From 99a0c2a18846bd7f8055ab81552456d10cd5c383 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Jun 2018 19:58:28 +0100 Subject: [PATCH 0001/3224] Block: Make recalculation of BB non-dependent on block position This now computes BBs relative to 0,0,0 and then offsets them as appropriate. This requires less boilerplate code and also furthers the goal of separating block types from instances. --- src/pocketmine/block/Anvil.php | 18 +--- src/pocketmine/block/Bed.php | 9 +- src/pocketmine/block/Block.php | 15 ++- src/pocketmine/block/Cactus.php | 11 +-- src/pocketmine/block/Cake.php | 13 ++- src/pocketmine/block/Carpet.php | 10 +- src/pocketmine/block/Chest.php | 9 +- src/pocketmine/block/CobblestoneWall.php | 12 +-- src/pocketmine/block/Door.php | 118 +++-------------------- src/pocketmine/block/EndPortalFrame.php | 12 +-- src/pocketmine/block/EndRod.php | 36 +++---- src/pocketmine/block/Farmland.php | 10 +- src/pocketmine/block/Fence.php | 48 ++++----- src/pocketmine/block/FenceGate.php | 25 +++-- src/pocketmine/block/FlowerPot.php | 10 +- src/pocketmine/block/GrassPath.php | 9 +- src/pocketmine/block/Ladder.php | 12 +-- src/pocketmine/block/Skull.php | 10 +- src/pocketmine/block/Slab.php | 18 +--- src/pocketmine/block/SoulSand.php | 10 +- src/pocketmine/block/Stair.php | 18 +--- src/pocketmine/block/Thin.php | 48 ++++----- src/pocketmine/block/Trapdoor.php | 54 ++--------- src/pocketmine/block/Vine.php | 10 +- src/pocketmine/block/WaterLily.php | 11 +-- 25 files changed, 149 insertions(+), 407 deletions(-) diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index d4b09eae69..8729925ab9 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -76,23 +76,9 @@ class Anvil extends Fallable{ $inset = 0.125; if($this->meta & 0x01){ //east/west - return new AxisAlignedBB( - $this->x, - $this->y, - $this->z + $inset, - $this->x + 1, - $this->y + 1, - $this->z + 1 - $inset - ); + return new AxisAlignedBB(0, 0, $inset, 1, 1, 1 - $inset); }else{ - return new AxisAlignedBB( - $this->x + $inset, - $this->y, - $this->z, - $this->x + 1 - $inset, - $this->y + 1, - $this->z + 1 - ); + return new AxisAlignedBB($inset, 0, 0, 1 - $inset, 1, 1); } } diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 8a31316168..b4024b238a 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -55,14 +55,7 @@ class Bed extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return new AxisAlignedBB( - $this->x, - $this->y, - $this->z, - $this->x + 1, - $this->y + 0.5625, - $this->z + 1 - ); + return new AxisAlignedBB(0, 0, 0, 1, 0.5625, 1); } public function isHeadPart() : bool{ diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 42d77663b7..74e1dd05fc 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -657,6 +657,9 @@ class Block extends Position implements BlockIds, Metadatable{ public function getCollisionBoxes() : array{ if($this->collisionBoxes === null){ $this->collisionBoxes = $this->recalculateCollisionBoxes(); + foreach($this->collisionBoxes as $bb){ + $bb->offset($this->x, $this->y, $this->z); + } } return $this->collisionBoxes; @@ -679,6 +682,9 @@ class Block extends Position implements BlockIds, Metadatable{ public function getBoundingBox() : ?AxisAlignedBB{ if($this->boundingBox === null){ $this->boundingBox = $this->recalculateBoundingBox(); + if($this->boundingBox !== null){ + $this->boundingBox->offset($this->x, $this->y, $this->z); + } } return $this->boundingBox; } @@ -687,14 +693,7 @@ class Block extends Position implements BlockIds, Metadatable{ * @return AxisAlignedBB|null */ protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return new AxisAlignedBB( - $this->x, - $this->y, - $this->z, - $this->x + 1, - $this->y + 1, - $this->z + 1 - ); + return new AxisAlignedBB(0, 0, 0, 1, 1, 1); } /** diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index 02118d898e..bd980f588f 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -54,15 +54,8 @@ class Cactus extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - - return new AxisAlignedBB( - $this->x + 0.0625, - $this->y + 0.0625, - $this->z + 0.0625, - $this->x + 0.9375, - $this->y + 0.9375, - $this->z + 0.9375 - ); + static $shrinkSize = 0.0625; + return new AxisAlignedBB($shrinkSize, $shrinkSize, $shrinkSize, 1 - $shrinkSize, 1 - $shrinkSize, 1 - $shrinkSize); } public function onEntityCollide(Entity $entity) : void{ diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index f67fa4e7d8..d4c46d520b 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -48,16 +48,15 @@ class Cake extends Transparent implements FoodSource{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - $f = $this->getDamage() * 0.125; //1 slice width return new AxisAlignedBB( - $this->x + 0.0625 + $f, - $this->y, - $this->z + 0.0625, - $this->x + 1 - 0.0625, - $this->y + 0.5, - $this->z + 1 - 0.0625 + 0.0625 + $f, + 0, + 0.0625, + 1 - 0.0625, + 0.5, + 1 - 0.0625 ); } diff --git a/src/pocketmine/block/Carpet.php b/src/pocketmine/block/Carpet.php index 3631248f34..6c0189a508 100644 --- a/src/pocketmine/block/Carpet.php +++ b/src/pocketmine/block/Carpet.php @@ -50,15 +50,7 @@ class Carpet extends Flowable{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - - return new AxisAlignedBB( - $this->x, - $this->y, - $this->z, - $this->x + 1, - $this->y + 0.0625, - $this->z + 1 - ); + return new AxisAlignedBB(0, 0, 0, 1, 0.0625, 1); } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index b11809ef29..a0b8d1a61f 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -52,14 +52,7 @@ class Chest extends Transparent{ protected function recalculateBoundingBox() : ?AxisAlignedBB{ //these are slightly bigger than in PC - return new AxisAlignedBB( - $this->x + 0.025, - $this->y, - $this->z + 0.025, - $this->x + 0.975, - $this->y + 0.95, - $this->z + 0.975 - ); + return new AxisAlignedBB(0.025, 0, 0.025, 0.975, 0.95, 0.975); } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ diff --git a/src/pocketmine/block/CobblestoneWall.php b/src/pocketmine/block/CobblestoneWall.php index 1e9e611ee7..34bd9a8b1a 100644 --- a/src/pocketmine/block/CobblestoneWall.php +++ b/src/pocketmine/block/CobblestoneWall.php @@ -78,12 +78,12 @@ class CobblestoneWall extends Transparent{ } return new AxisAlignedBB( - $this->x + ($west ? 0 : $inset), - $this->y, - $this->z + ($north ? 0 : $inset), - $this->x + 1 - ($east ? 0 : $inset), - $this->y + 1.5, - $this->z + 1 - ($south ? 0 : $inset) + ($west ? 0 : $inset), + 0, + ($north ? 0 : $inset), + 1 - ($east ? 0 : $inset), + 1.5, + 1 - ($south ? 0 : $inset) ); } diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index a23df95f0b..3b4f54af74 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -54,18 +54,10 @@ abstract class Door extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - $f = 0.1875; $damage = $this->getFullDamage(); - $bb = new AxisAlignedBB( - $this->x, - $this->y, - $this->z, - $this->x + 1, - $this->y + 2, - $this->z + 1 - ); + $bb = new AxisAlignedBB(0, 0, 0, 1, 2, 1); $j = $damage & 0x03; $isOpen = (($damage & 0x04) > 0); @@ -74,126 +66,42 @@ abstract class Door extends Transparent{ if($j === 0){ if($isOpen){ if(!$isRight){ - $bb->setBounds( - $this->x, - $this->y, - $this->z, - $this->x + 1, - $this->y + 1, - $this->z + $f - ); + $bb->setBounds(0, 0, 0, 1, 1, $f); }else{ - $bb->setBounds( - $this->x, - $this->y, - $this->z + 1 - $f, - $this->x + 1, - $this->y + 1, - $this->z + 1 - ); + $bb->setBounds(0, 0, 1 - $f, 1, 1, 1); } }else{ - $bb->setBounds( - $this->x, - $this->y, - $this->z, - $this->x + $f, - $this->y + 1, - $this->z + 1 - ); + $bb->setBounds(0, 0, 0, $f, 1, 1); } }elseif($j === 1){ if($isOpen){ if(!$isRight){ - $bb->setBounds( - $this->x + 1 - $f, - $this->y, - $this->z, - $this->x + 1, - $this->y + 1, - $this->z + 1 - ); + $bb->setBounds(1 - $f, 0, 0, 1, 1, 1); }else{ - $bb->setBounds( - $this->x, - $this->y, - $this->z, - $this->x + $f, - $this->y + 1, - $this->z + 1 - ); + $bb->setBounds(0, 0, 0, $f, 1, 1); } }else{ - $bb->setBounds( - $this->x, - $this->y, - $this->z, - $this->x + 1, - $this->y + 1, - $this->z + $f - ); + $bb->setBounds(0, 0, 0, 1, 1, $f); } }elseif($j === 2){ if($isOpen){ if(!$isRight){ - $bb->setBounds( - $this->x, - $this->y, - $this->z + 1 - $f, - $this->x + 1, - $this->y + 1, - $this->z + 1 - ); + $bb->setBounds(0, 0, 1 - $f, 1, 1, 1); }else{ - $bb->setBounds( - $this->x, - $this->y, - $this->z, - $this->x + 1, - $this->y + 1, - $this->z + $f - ); + $bb->setBounds(0, 0, 0, 1, 1, $f); } }else{ - $bb->setBounds( - $this->x + 1 - $f, - $this->y, - $this->z, - $this->x + 1, - $this->y + 1, - $this->z + 1 - ); + $bb->setBounds(1 - $f, 0, 0, 1, 1, 1); } }elseif($j === 3){ if($isOpen){ if(!$isRight){ - $bb->setBounds( - $this->x, - $this->y, - $this->z, - $this->x + $f, - $this->y + 1, - $this->z + 1 - ); + $bb->setBounds(0, 0, 0, $f, 1, 1); }else{ - $bb->setBounds( - $this->x + 1 - $f, - $this->y, - $this->z, - $this->x + 1, - $this->y + 1, - $this->z + 1 - ); + $bb->setBounds(1 - $f, 0, 0, 1, 1, 1); } }else{ - $bb->setBounds( - $this->x, - $this->y, - $this->z + 1 - $f, - $this->x + 1, - $this->y + 1, - $this->z + 1 - ); + $bb->setBounds(0, 0, 1 - $f, 1, 1, 1); } } diff --git a/src/pocketmine/block/EndPortalFrame.php b/src/pocketmine/block/EndPortalFrame.php index 5ecf295560..1e51399b61 100644 --- a/src/pocketmine/block/EndPortalFrame.php +++ b/src/pocketmine/block/EndPortalFrame.php @@ -57,12 +57,12 @@ class EndPortalFrame extends Solid{ protected function recalculateBoundingBox() : ?AxisAlignedBB{ return new AxisAlignedBB( - $this->x, - $this->y, - $this->z, - $this->x + 1, - $this->y + (($this->getDamage() & 0x04) > 0 ? 1 : 0.8125), - $this->z + 1 + 0, + 0, + 0, + 1, + (($this->getDamage() & 0x04) > 0 ? 1 : 0.8125), + 1 ); } } diff --git a/src/pocketmine/block/EndRod.php b/src/pocketmine/block/EndRod.php index 91251ab759..da64cc5680 100644 --- a/src/pocketmine/block/EndRod.php +++ b/src/pocketmine/block/EndRod.php @@ -68,30 +68,30 @@ class EndRod extends Flowable{ switch($m){ case 0x00: //up/down return new AxisAlignedBB( - $this->x + $width, - $this->y, - $this->z + $width, - $this->x + 1 - $width, - $this->y + 1, - $this->z + 1 - $width + $width, + 0, + $width, + 1 - $width, + 1, + 1 - $width ); case 0x02: //north/south return new AxisAlignedBB( - $this->x, - $this->y + $width, - $this->z + $width, - $this->x + 1, - $this->y + 1 - $width, - $this->z + 1 - $width + 0, + $width, + $width, + 1, + 1 - $width, + 1 - $width ); case 0x04: //east/west return new AxisAlignedBB( - $this->x + $width, - $this->y + $width, - $this->z, - $this->x + 1 - $width, - $this->y + 1 - $width, - $this->z + 1 + $width, + $width, + 0, + 1 - $width, + 1 - $width, + 1 ); } diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index 1da290a606..9c473a512b 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -48,16 +48,8 @@ class Farmland extends Transparent{ return BlockToolType::TYPE_SHOVEL; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return new AxisAlignedBB( - $this->x, - $this->y, - $this->z, - $this->x + 1, - $this->y + 1, //TODO: this should be 0.9375, but MCPE currently treats them as a full block (https://bugs.mojang.com/browse/MCPE-12109) - $this->z + 1 - ); + return new AxisAlignedBB(0, 0, 0, 1, 1, 1); //TODO: y max should be 0.9375, but MCPE currently treats them as a full block (https://bugs.mojang.com/browse/MCPE-12109) } public function onNearbyBlockChange() : void{ diff --git a/src/pocketmine/block/Fence.php b/src/pocketmine/block/Fence.php index 1e579c1eb4..aa9cdd00f4 100644 --- a/src/pocketmine/block/Fence.php +++ b/src/pocketmine/block/Fence.php @@ -40,12 +40,12 @@ abstract class Fence extends Transparent{ $width = 0.5 - $this->getThickness() / 2; return new AxisAlignedBB( - $this->x + ($this->canConnect($this->getSide(Vector3::SIDE_WEST)) ? 0 : $width), - $this->y, - $this->z + ($this->canConnect($this->getSide(Vector3::SIDE_NORTH)) ? 0 : $width), - $this->x + 1 - ($this->canConnect($this->getSide(Vector3::SIDE_EAST)) ? 0 : $width), - $this->y + 1.5, - $this->z + 1 - ($this->canConnect($this->getSide(Vector3::SIDE_SOUTH)) ? 0 : $width) + ($this->canConnect($this->getSide(Vector3::SIDE_WEST)) ? 0 : $width), + 0, + ($this->canConnect($this->getSide(Vector3::SIDE_NORTH)) ? 0 : $width), + 1 - ($this->canConnect($this->getSide(Vector3::SIDE_EAST)) ? 0 : $width), + 1.5, + 1 - ($this->canConnect($this->getSide(Vector3::SIDE_SOUTH)) ? 0 : $width) ); } @@ -61,12 +61,12 @@ abstract class Fence extends Transparent{ if($connectWest or $connectEast){ //X axis (west/east) $bbs[] = new AxisAlignedBB( - $this->x + ($connectWest ? 0 : $inset), - $this->y, - $this->z + $inset, - $this->x + 1 - ($connectEast ? 0 : $inset), - $this->y + 1.5, - $this->z + 1 - $inset + ($connectWest ? 0 : $inset), + 0, + $inset, + 1 - ($connectEast ? 0 : $inset), + 1.5, + 1 - $inset ); } @@ -76,12 +76,12 @@ abstract class Fence extends Transparent{ if($connectNorth or $connectSouth){ //Z axis (north/south) $bbs[] = new AxisAlignedBB( - $this->x + $inset, - $this->y, - $this->z + ($connectNorth ? 0 : $inset), - $this->x + 1 - $inset, - $this->y + 1.5, - $this->z + 1 - ($connectSouth ? 0 : $inset) + $inset, + 0, + ($connectNorth ? 0 : $inset), + 1 - $inset, + 1.5, + 1 - ($connectSouth ? 0 : $inset) ); } @@ -89,12 +89,12 @@ abstract class Fence extends Transparent{ //centre post AABB (only needed if not connected on any axis - other BBs overlapping will do this if any connections are made) return [ new AxisAlignedBB( - $this->x + $inset, - $this->y, - $this->z + $inset, - $this->x + 1 - $inset, - $this->y + 1.5, - $this->z + 1 - $inset + $inset, + 0, + $inset, + 1 - $inset, + 1.5, + 1 - $inset ) ]; } diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index 8f08a10c91..1d7a93b9cd 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -41,7 +41,6 @@ class FenceGate extends Transparent{ protected function recalculateBoundingBox() : ?AxisAlignedBB{ - if(($this->getDamage() & 0x04) > 0){ return null; } @@ -49,21 +48,21 @@ class FenceGate extends Transparent{ $i = ($this->getDamage() & 0x03); if($i === 2 or $i === 0){ return new AxisAlignedBB( - $this->x, - $this->y, - $this->z + 0.375, - $this->x + 1, - $this->y + 1.5, - $this->z + 0.625 + 0, + 0, + 0.375, + 1, + 1.5, + 0.625 ); }else{ return new AxisAlignedBB( - $this->x + 0.375, - $this->y, - $this->z, - $this->x + 0.625, - $this->y + 1.5, - $this->z + 1 + 0.375, + 0, + 0, + 0.625, + 1.5, + 1 ); } } diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index cc5d3b9ed1..3f92b7cc01 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -47,14 +47,8 @@ class FlowerPot extends Flowable{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return new AxisAlignedBB( - $this->x + 0.3125, - $this->y, - $this->z + 0.3125, - $this->x + 0.6875, - $this->y + 0.375, - $this->z + 0.6875 - ); + static $f = 0.3125; + return new AxisAlignedBB($f, 0, $f, 1 - $f, 0.375, 1 - $f); } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ diff --git a/src/pocketmine/block/GrassPath.php b/src/pocketmine/block/GrassPath.php index 712f3e5473..e58c402241 100644 --- a/src/pocketmine/block/GrassPath.php +++ b/src/pocketmine/block/GrassPath.php @@ -45,14 +45,7 @@ class GrassPath extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return new AxisAlignedBB( - $this->x, - $this->y, - $this->z, - $this->x + 1, - $this->y + 1, //TODO: this should be 0.9375, but MCPE currently treats them as a full block (https://bugs.mojang.com/browse/MCPE-12109) - $this->z + 1 - ); + return new AxisAlignedBB(0, 0, 0, 1, 1, 1); //TODO: y max should be 0.9375, but MCPE currently treats them as a full block (https://bugs.mojang.com/browse/MCPE-12109) } public function getHardness() : float{ diff --git a/src/pocketmine/block/Ladder.php b/src/pocketmine/block/Ladder.php index 062b972d54..49729cac2a 100644 --- a/src/pocketmine/block/Ladder.php +++ b/src/pocketmine/block/Ladder.php @@ -79,12 +79,12 @@ class Ladder extends Transparent{ } return new AxisAlignedBB( - $this->x + $minX, - $this->y, - $this->z + $minZ, - $this->x + $maxX, - $this->y + 1, - $this->z + $maxZ + $minX, + 0, + $minZ, + $maxX, + 1, + $maxZ ); } diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index 9e4c6c425c..dc74b96eb6 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -49,14 +49,8 @@ class Skull extends Flowable{ protected function recalculateBoundingBox() : ?AxisAlignedBB{ //TODO: different bounds depending on attached face (meta) - return new AxisAlignedBB( - $this->x + 0.25, - $this->y, - $this->z + 0.25, - $this->x + 0.75, - $this->y + 0.5, - $this->z + 0.75 - ); + static $f = 0.25; + return new AxisAlignedBB($f, 0, $f, 1 - $f, 0.5, 1 - $f); } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index 8444479b6f..319d039985 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -107,23 +107,9 @@ abstract class Slab extends Transparent{ protected function recalculateBoundingBox() : ?AxisAlignedBB{ if(($this->meta & 0x08) > 0){ - return new AxisAlignedBB( - $this->x, - $this->y + 0.5, - $this->z, - $this->x + 1, - $this->y + 1, - $this->z + 1 - ); + return new AxisAlignedBB(0, 0.5, 0, 1, 1, 1); }else{ - return new AxisAlignedBB( - $this->x, - $this->y, - $this->z, - $this->x + 1, - $this->y + 0.5, - $this->z + 1 - ); + return new AxisAlignedBB(0, 0, 0, 1, 0.5, 1); } } } diff --git a/src/pocketmine/block/SoulSand.php b/src/pocketmine/block/SoulSand.php index dbe6deadc7..5e402678ed 100644 --- a/src/pocketmine/block/SoulSand.php +++ b/src/pocketmine/block/SoulSand.php @@ -46,14 +46,6 @@ class SoulSand extends Solid{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - - return new AxisAlignedBB( - $this->x, - $this->y, - $this->z, - $this->x + 1, - $this->y + 1 - 0.125, - $this->z + 1 - ); + return new AxisAlignedBB(0, 0, 0, 1, 1 - 0.125, 1); } } diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index e45e25482a..27e66a24ec 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -37,14 +37,7 @@ abstract class Stair extends Transparent{ $maxYSlab = $minYSlab + 0.5; $bbs = [ - new AxisAlignedBB( - $this->x, - $this->y + $minYSlab, - $this->z, - $this->x + 1, - $this->y + $maxYSlab, - $this->z + 1 - ) + new AxisAlignedBB(0, $minYSlab, 0, 1, $maxYSlab, 1) ]; $minY = ($this->meta & 0x04) === 0 ? 0.5 : 0; @@ -70,14 +63,7 @@ abstract class Stair extends Transparent{ break; } - $bbs[] = new AxisAlignedBB( - $this->x + $minX, - $this->y + $minY, - $this->z + $minZ, - $this->x + $maxX, - $this->y + $maxY, - $this->z + $maxZ - ); + $bbs[] = new AxisAlignedBB($minX, $minY, $minZ, $maxX, $maxY, $maxZ); return $bbs; } diff --git a/src/pocketmine/block/Thin.php b/src/pocketmine/block/Thin.php index 108e8728d7..fb6b5f91cc 100644 --- a/src/pocketmine/block/Thin.php +++ b/src/pocketmine/block/Thin.php @@ -32,12 +32,12 @@ abstract class Thin extends Transparent{ $width = 0.5 - 0.125 / 2; return new AxisAlignedBB( - $this->x + ($this->canConnect($this->getSide(Vector3::SIDE_WEST)) ? 0 : $width), - $this->y, - $this->z + ($this->canConnect($this->getSide(Vector3::SIDE_NORTH)) ? 0 : $width), - $this->x + 1 - ($this->canConnect($this->getSide(Vector3::SIDE_EAST)) ? 0 : $width), - $this->y + 1, - $this->z + 1 - ($this->canConnect($this->getSide(Vector3::SIDE_SOUTH)) ? 0 : $width) + ($this->canConnect($this->getSide(Vector3::SIDE_WEST)) ? 0 : $width), + 0, + ($this->canConnect($this->getSide(Vector3::SIDE_NORTH)) ? 0 : $width), + 1 - ($this->canConnect($this->getSide(Vector3::SIDE_EAST)) ? 0 : $width), + 1, + 1 - ($this->canConnect($this->getSide(Vector3::SIDE_SOUTH)) ? 0 : $width) ); } @@ -53,12 +53,12 @@ abstract class Thin extends Transparent{ if($connectWest or $connectEast){ //X axis (west/east) $bbs[] = new AxisAlignedBB( - $this->x + ($connectWest ? 0 : $inset), - $this->y, - $this->z + $inset, - $this->x + 1 - ($connectEast ? 0 : $inset), - $this->y + 1, - $this->z + 1 - $inset + ($connectWest ? 0 : $inset), + 0, + $inset, + 1 - ($connectEast ? 0 : $inset), + 1, + 1 - $inset ); } @@ -68,12 +68,12 @@ abstract class Thin extends Transparent{ if($connectNorth or $connectSouth){ //Z axis (north/south) $bbs[] = new AxisAlignedBB( - $this->x + $inset, - $this->y, - $this->z + ($connectNorth ? 0 : $inset), - $this->x + 1 - $inset, - $this->y + 1, - $this->z + 1 - ($connectSouth ? 0 : $inset) + $inset, + 0, + ($connectNorth ? 0 : $inset), + 1 - $inset, + 1, + 1 - ($connectSouth ? 0 : $inset) ); } @@ -81,12 +81,12 @@ abstract class Thin extends Transparent{ //centre post AABB (only needed if not connected on any axis - other BBs overlapping will do this if any connections are made) return [ new AxisAlignedBB( - $this->x + $inset, - $this->y, - $this->z + $inset, - $this->x + 1 - $inset, - $this->y + 1, - $this->z + 1 - $inset + $inset, + 0, + $inset, + 1 - $inset, + 1, + 1 - $inset ) ]; } diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index 25c747cbdc..1dfde7d445 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -59,64 +59,22 @@ class Trapdoor extends Transparent{ $f = 0.1875; if(($damage & self::MASK_UPPER) > 0){ - $bb = new AxisAlignedBB( - $this->x, - $this->y + 1 - $f, - $this->z, - $this->x + 1, - $this->y + 1, - $this->z + 1 - ); + $bb = new AxisAlignedBB(0, 1 - $f, 0, 1, 1, 1); }else{ - $bb = new AxisAlignedBB( - $this->x, - $this->y, - $this->z, - $this->x + 1, - $this->y + $f, - $this->z + 1 - ); + $bb = new AxisAlignedBB(0, 0, 0, 1, $f, 1); } if(($damage & self::MASK_OPENED) > 0){ if(($damage & 0x03) === self::MASK_SIDE_NORTH){ - $bb->setBounds( - $this->x, - $this->y, - $this->z + 1 - $f, - $this->x + 1, - $this->y + 1, - $this->z + 1 - ); + $bb->setBounds(0, 0, 1 - $f, 1, 1, 1); }elseif(($damage & 0x03) === self::MASK_SIDE_SOUTH){ - $bb->setBounds( - $this->x, - $this->y, - $this->z, - $this->x + 1, - $this->y + 1, - $this->z + $f - ); + $bb->setBounds(0, 0, 0, 1, 1, $f); } if(($damage & 0x03) === self::MASK_SIDE_WEST){ - $bb->setBounds( - $this->x + 1 - $f, - $this->y, - $this->z, - $this->x + 1, - $this->y + 1, - $this->z + 1 - ); + $bb->setBounds(1 - $f, 0, 0, 1, 1, 1); } if(($damage & 0x03) === self::MASK_SIDE_EAST){ - $bb->setBounds( - $this->x, - $this->y, - $this->z, - $this->x + $f, - $this->y + 1, - $this->z + 1 - ); + $bb->setBounds(0, 0, 0, $f, 1, 1); } } diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index f589d7d21f..f9c27a65e7 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -70,7 +70,6 @@ class Vine extends Flowable{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - $minX = 1; $minY = 1; $minZ = 1; @@ -121,14 +120,7 @@ class Vine extends Flowable{ $maxZ = 1; } - return new AxisAlignedBB( - $this->x + $minX, - $this->y + $minY, - $this->z + $minZ, - $this->x + $maxX, - $this->y + $maxY, - $this->z + $maxZ - ); + return new AxisAlignedBB($minX, $minY, $minZ, $maxX, $maxY, $maxZ); } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ diff --git a/src/pocketmine/block/WaterLily.php b/src/pocketmine/block/WaterLily.php index 5327857d54..78eb3cd333 100644 --- a/src/pocketmine/block/WaterLily.php +++ b/src/pocketmine/block/WaterLily.php @@ -45,17 +45,10 @@ class WaterLily extends Flowable{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return new AxisAlignedBB( - $this->x + 0.0625, - $this->y, - $this->z + 0.0625, - $this->x + 0.9375, - $this->y + 0.015625, - $this->z + 0.9375 - ); + static $f = 0.0625; + return new AxisAlignedBB($f, 0, $f, 1 - $f, 0.015625, 1 - $f); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($blockClicked instanceof Water){ $up = $blockClicked->getSide(Vector3::SIDE_UP); From 8a659414899e5ed7e64c80e92ecd0a4c9d475296 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Jun 2018 20:01:27 +0100 Subject: [PATCH 0002/3224] reeeeee --- src/pocketmine/PocketMine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index 07d1c0f15c..1efdd0a327 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -38,7 +38,7 @@ namespace pocketmine { const NAME = "PocketMine-MP"; const BASE_VERSION = "3.0.2"; - const IS_DEVELOPMENT_BUILD = false; + const IS_DEVELOPMENT_BUILD = true; const BUILD_NUMBER = 0; const MIN_PHP_VERSION = "7.2.0"; From eddd626461240d08d21ad7411d5df0f87ca9fc2d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Jun 2018 20:13:26 +0100 Subject: [PATCH 0003/3224] Trapdoor: fixed condition for side checking --- src/pocketmine/block/Trapdoor.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index 1dfde7d445..63277f66c1 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -65,15 +65,14 @@ class Trapdoor extends Transparent{ } if(($damage & self::MASK_OPENED) > 0){ - if(($damage & 0x03) === self::MASK_SIDE_NORTH){ + $side = $damage & 0x03; + if($side === self::MASK_SIDE_NORTH){ $bb->setBounds(0, 0, 1 - $f, 1, 1, 1); - }elseif(($damage & 0x03) === self::MASK_SIDE_SOUTH){ + }elseif($side === self::MASK_SIDE_SOUTH){ $bb->setBounds(0, 0, 0, 1, 1, $f); - } - if(($damage & 0x03) === self::MASK_SIDE_WEST){ + }elseif($side === self::MASK_SIDE_WEST){ $bb->setBounds(1 - $f, 0, 0, 1, 1, 1); - } - if(($damage & 0x03) === self::MASK_SIDE_EAST){ + }elseif($side === self::MASK_SIDE_EAST){ $bb->setBounds(0, 0, 0, $f, 1, 1); } } From 2308eadf53f259d0ae9b5223076159cee828f0ef Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Jun 2018 22:15:50 +0100 Subject: [PATCH 0004/3224] Add ExamplePlugin to README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 42fcfbcd91..59ef84bf66 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,8 @@ There are a very wide range of already-written plugins available which you can u ### For developers * [Latest API documentation](https://jenkins.pmmp.io/job/PocketMine-MP-doc/doxygen/) - Doxygen documentation generated from development - * [DevTools](https://github.com/pmmp/PocketMine-DevTools/) - A development tools plugin for creating plugins. + * [DevTools](https://github.com/pmmp/PocketMine-DevTools/) - Development tools plugin for creating plugins + * [ExamplePlugin](https://github.com/pmmp/ExamplePlugin/) - Example plugin demonstrating some basic API features ### Can I contribute? Yes you can! Contributions are welcomed provided that they comply with our [Contributing Guidelines](CONTRIBUTING.md). Please ensure you read the relevant sections of the guidelines carefully before making a Pull Request or opening an Issue. From 9a6a5e2088f7c7d3974eae1e6df68a31d715e33b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 22 Jun 2018 09:36:07 +0100 Subject: [PATCH 0005/3224] submodule updates --- tests/plugins/PocketMine-DevTools | 2 +- tests/plugins/PocketMine-TesterPlugin | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/plugins/PocketMine-DevTools b/tests/plugins/PocketMine-DevTools index 638e44519a..2491457a82 160000 --- a/tests/plugins/PocketMine-DevTools +++ b/tests/plugins/PocketMine-DevTools @@ -1 +1 @@ -Subproject commit 638e44519a921f969c59365220fd46011aba51a1 +Subproject commit 2491457a82fe4b759a6a899bbe57fc62053dcc06 diff --git a/tests/plugins/PocketMine-TesterPlugin b/tests/plugins/PocketMine-TesterPlugin index 5fd76d5718..9c78e03f13 160000 --- a/tests/plugins/PocketMine-TesterPlugin +++ b/tests/plugins/PocketMine-TesterPlugin @@ -1 +1 @@ -Subproject commit 5fd76d57187baa0e80325f268ec2fd3ead405ce2 +Subproject commit 9c78e03f13c55e241ca37a9a165dec191fa2cb56 From f60b0e5cc75ae0aa17ae6fed4b5739185dcf8bc8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 22 Jun 2018 09:40:33 +0100 Subject: [PATCH 0006/3224] Server: more dev build warnings --- src/pocketmine/Server.php | 23 ++++++++++++++++------- src/pocketmine/lang/locale | 2 +- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 94b4305f1e..d8c2fff8e3 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1453,13 +1453,22 @@ class Server{ $this->baseLang = new BaseLang($this->getProperty("settings.language", BaseLang::FALLBACK_LANGUAGE)); $this->logger->info($this->getLanguage()->translateString("language.selected", [$this->getLanguage()->getName(), $this->getLanguage()->getLang()])); - if(\pocketmine\IS_DEVELOPMENT_BUILD and !((bool) $this->getProperty("settings.enable-dev-builds", false))){ - $this->logger->emergency($this->baseLang->translateString("pocketmine.server.devBuild.error1", [\pocketmine\NAME])); - $this->logger->emergency($this->baseLang->translateString("pocketmine.server.devBuild.error2")); - $this->logger->emergency($this->baseLang->translateString("pocketmine.server.devBuild.error3")); - $this->logger->emergency($this->baseLang->translateString("pocketmine.server.devBuild.error4", ["settings.enable-dev-builds"])); - $this->forceShutdown(); - return; + if(\pocketmine\IS_DEVELOPMENT_BUILD){ + if(!((bool) $this->getProperty("settings.enable-dev-builds", false))){ + $this->logger->emergency($this->baseLang->translateString("pocketmine.server.devBuild.error1", [\pocketmine\NAME])); + $this->logger->emergency($this->baseLang->translateString("pocketmine.server.devBuild.error2")); + $this->logger->emergency($this->baseLang->translateString("pocketmine.server.devBuild.error3")); + $this->logger->emergency($this->baseLang->translateString("pocketmine.server.devBuild.error4", ["settings.enable-dev-builds"])); + $this->forceShutdown(); + + return; + } + + $this->logger->warning(str_repeat("-", 40)); + $this->logger->warning($this->baseLang->translateString("pocketmine.server.devBuild.warning1", [\pocketmine\NAME])); + $this->logger->warning($this->baseLang->translateString("pocketmine.server.devBuild.warning2")); + $this->logger->warning($this->baseLang->translateString("pocketmine.server.devBuild.warning3")); + $this->logger->warning(str_repeat("-", 40)); } if(((int) ini_get('zend.assertions')) > 0 and ((bool) $this->getProperty("debug.assertions.warn-if-enabled", true)) !== false){ diff --git a/src/pocketmine/lang/locale b/src/pocketmine/lang/locale index 638dc473ca..91e77ffbce 160000 --- a/src/pocketmine/lang/locale +++ b/src/pocketmine/lang/locale @@ -1 +1 @@ -Subproject commit 638dc473cafa32542bc5c940482f59140bab1333 +Subproject commit 91e77ffbce10b0c56ae019655a3e803856b93a74 From 3846ee3d1d90e3539c90ecaf63dcf08cbf51aab0 Mon Sep 17 00:00:00 2001 From: David Schwartz Date: Fri, 29 Jun 2018 09:48:29 -0400 Subject: [PATCH 0007/3224] reorganize and optimize start.sh (#2267) --- start.sh | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/start.sh b/start.sh index 7546c5db51..48865b4c83 100755 --- a/start.sh +++ b/start.sh @@ -2,8 +2,6 @@ DIR="$(cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd)" cd "$DIR" -DO_LOOP="no" - while getopts "p:f:l" OPTION 2> /dev/null; do case ${OPTION} in p) @@ -47,19 +45,18 @@ fi LOOPS=0 set +e -while [ "$LOOPS" -eq 0 ] || [ "$DO_LOOP" == "yes" ]; do - if [ "$DO_LOOP" == "yes" ]; then - "$PHP_BINARY" "$POCKETMINE_FILE" $@ - else - exec "$PHP_BINARY" "$POCKETMINE_FILE" $@ - fi - if [ "$DO_LOOP" == "yes" ]; then + +if [ "$DO_LOOP" == "yes" ]; then + while true; do if [ ${LOOPS} -gt 0 ]; then echo "Restarted $LOOPS times" fi + "$PHP_BINARY" "$POCKETMINE_FILE" $@ echo "To escape the loop, press CTRL+C now. Otherwise, wait 5 seconds for the server to restart." echo "" sleep 5 ((LOOPS++)) - fi -done + done +else + exec "$PHP_BINARY" "$POCKETMINE_FILE" $@ +fi From 49bca0d5a1d18ab4adeee4c01276adf15e47600f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 29 Jun 2018 20:04:10 +0100 Subject: [PATCH 0008/3224] Remove a whole bunch of crap from the `Plugin` public interface (#2268) - remove onLoad(), onEnable(), onDisable() - remove Config related methods - remove getResource(), saveResource(), getResources() did I troll any readers so far? On a more serious note, these methods do not need to be declared in this interface because they are either hooks (`onLoad()`, `onEnable()`, `onDisable()`) or methods only used from within `PluginBase` and its children. They are not intended to be public API, and for this reason they don't need to be exposed in the interface. --- src/pocketmine/plugin/Plugin.php | 58 ------------------------- src/pocketmine/plugin/PluginBase.php | 17 ++++++-- src/pocketmine/plugin/PluginManager.php | 1 - 3 files changed, 14 insertions(+), 62 deletions(-) diff --git a/src/pocketmine/plugin/Plugin.php b/src/pocketmine/plugin/Plugin.php index 77d5dd9643..cba8b6f168 100644 --- a/src/pocketmine/plugin/Plugin.php +++ b/src/pocketmine/plugin/Plugin.php @@ -29,8 +29,6 @@ namespace pocketmine\plugin; use pocketmine\command\CommandExecutor; use pocketmine\scheduler\TaskScheduler; use pocketmine\Server; -use pocketmine\utils\Config; - /** * It is recommended to use PluginBase for the actual plugin @@ -39,16 +37,6 @@ interface Plugin extends CommandExecutor{ public function __construct(PluginLoader $loader, Server $server, PluginDescription $description, string $dataFolder, string $file); - /** - * Called when the plugin is loaded, before calling onEnable() - */ - public function onLoad(); - - /** - * Called when the plugin is enabled - */ - public function onEnable(); - /** * @return bool */ @@ -59,12 +47,6 @@ interface Plugin extends CommandExecutor{ */ public function setEnabled(bool $enabled = true) : void; - /** - * Called when the plugin is disabled - * Use this to free open things and finish actions - */ - public function onDisable(); - /** * @return bool */ @@ -83,46 +65,6 @@ interface Plugin extends CommandExecutor{ */ public function getDescription() : PluginDescription; - /** - * Gets an embedded resource in the plugin file. - * - * @param string $filename - * - * @return null|resource Resource data, or null - */ - public function getResource(string $filename); - - /** - * Saves an embedded resource to its relative location in the data folder - * - * @param string $filename - * @param bool $replace - * - * @return bool - */ - public function saveResource(string $filename, bool $replace = false) : bool; - - /** - * Returns all the resources packaged with the plugin - * - * @return \SplFileInfo[] - */ - public function getResources() : array; - - /** - * @return Config - */ - public function getConfig() : Config; - - public function saveConfig(); - - /** - * @return bool - */ - public function saveDefaultConfig() : bool; - - public function reloadConfig(); - /** * @return Server */ diff --git a/src/pocketmine/plugin/PluginBase.php b/src/pocketmine/plugin/PluginBase.php index 3001b0a426..923db119bc 100644 --- a/src/pocketmine/plugin/PluginBase.php +++ b/src/pocketmine/plugin/PluginBase.php @@ -68,20 +68,29 @@ abstract class PluginBase implements Plugin{ $this->configFile = $this->dataFolder . "config.yml"; $this->logger = new PluginLogger($this); $this->scheduler = new TaskScheduler($this->logger, $this->getFullName()); + + $this->onLoad(); } /** * Called when the plugin is loaded, before calling onEnable() */ - public function onLoad(){ + protected function onLoad()/* : void /* TODO: uncomment this for next major version */{ } - public function onEnable(){ + /** + * Called when the plugin is enabled + */ + protected function onEnable()/* : void /* TODO: uncomment this for next major version */{ } - public function onDisable(){ + /** + * Called when the plugin is disabled + * Use this to free open things and finish actions + */ + protected function onDisable()/* : void /* TODO: uncomment this for next major version */{ } @@ -183,6 +192,8 @@ abstract class PluginBase implements Plugin{ } /** + * Saves an embedded resource to its relative location in the data folder + * * @param string $filename * @param bool $replace * diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index 861ea2e1a7..f254c12a3a 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -201,7 +201,6 @@ class PluginManager{ * @see Plugin::__construct() */ $plugin = new $mainClass($loader, $this->server, $description, $dataFolder, $prefixed); - $plugin->onLoad(); $this->plugins[$plugin->getDescription()->getName()] = $plugin; $pluginCommands = $this->parseYamlCommands($plugin); From 5dc4e17a96aea269c78248ffd70d9e76424abf49 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 29 Jun 2018 20:11:32 +0100 Subject: [PATCH 0009/3224] Updated TesterPlugin submodule --- tests/plugins/PocketMine-TesterPlugin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/plugins/PocketMine-TesterPlugin b/tests/plugins/PocketMine-TesterPlugin index 9c78e03f13..5b8dd72abb 160000 --- a/tests/plugins/PocketMine-TesterPlugin +++ b/tests/plugins/PocketMine-TesterPlugin @@ -1 +1 @@ -Subproject commit 9c78e03f13c55e241ca37a9a165dec191fa2cb56 +Subproject commit 5b8dd72abbb9da0f38c603134e76586652909f96 From 2bba3a0805a5361e546732c02b593e669dfe207e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 5 Jul 2018 13:19:15 +0100 Subject: [PATCH 0010/3224] Apply typehints to pocketmine\network\mcpe\protocol namespace this is pulled from network-nuke in order to reduce the size of the diff. --- .../mcpe/protocol/AddBehaviorTreePacket.php | 4 ++-- .../network/mcpe/protocol/AddEntityPacket.php | 4 ++-- .../mcpe/protocol/AddHangingEntityPacket.php | 4 ++-- .../mcpe/protocol/AddItemEntityPacket.php | 4 ++-- .../network/mcpe/protocol/AddPaintingPacket.php | 4 ++-- .../network/mcpe/protocol/AddPlayerPacket.php | 4 ++-- .../mcpe/protocol/AdventureSettingsPacket.php | 6 +++--- .../network/mcpe/protocol/AnimatePacket.php | 4 ++-- .../mcpe/protocol/AvailableCommandsPacket.php | 10 +++++----- .../network/mcpe/protocol/BatchPacket.php | 14 +++++++------- .../mcpe/protocol/BlockEntityDataPacket.php | 4 ++-- .../network/mcpe/protocol/BlockEventPacket.php | 4 ++-- .../mcpe/protocol/BlockPickRequestPacket.php | 4 ++-- .../network/mcpe/protocol/BookEditPacket.php | 4 ++-- .../network/mcpe/protocol/BossEventPacket.php | 4 ++-- .../network/mcpe/protocol/CameraPacket.php | 4 ++-- .../mcpe/protocol/ChangeDimensionPacket.php | 4 ++-- .../mcpe/protocol/ChunkRadiusUpdatedPacket.php | 4 ++-- .../protocol/ClientToServerHandshakePacket.php | 4 ++-- .../protocol/ClientboundMapItemDataPacket.php | 4 ++-- .../mcpe/protocol/CommandBlockUpdatePacket.php | 4 ++-- .../mcpe/protocol/CommandOutputPacket.php | 6 +++--- .../mcpe/protocol/CommandRequestPacket.php | 4 ++-- .../mcpe/protocol/ContainerClosePacket.php | 4 ++-- .../mcpe/protocol/ContainerOpenPacket.php | 4 ++-- .../mcpe/protocol/ContainerSetDataPacket.php | 4 ++-- .../network/mcpe/protocol/CraftingDataPacket.php | 16 ++++++++-------- .../mcpe/protocol/CraftingEventPacket.php | 4 ++-- .../network/mcpe/protocol/DataPacket.php | 14 +++++++------- .../network/mcpe/protocol/DisconnectPacket.php | 4 ++-- .../network/mcpe/protocol/EntityEventPacket.php | 4 ++-- .../network/mcpe/protocol/EntityFallPacket.php | 4 ++-- .../mcpe/protocol/EntityPickRequestPacket.php | 4 ++-- .../network/mcpe/protocol/EventPacket.php | 4 ++-- .../network/mcpe/protocol/ExplodePacket.php | 4 ++-- .../mcpe/protocol/FullChunkDataPacket.php | 4 ++-- .../mcpe/protocol/GameRulesChangedPacket.php | 4 ++-- .../mcpe/protocol/GuiDataPickItemPacket.php | 4 ++-- .../network/mcpe/protocol/HurtArmorPacket.php | 4 ++-- .../network/mcpe/protocol/InteractPacket.php | 4 ++-- .../mcpe/protocol/InventoryContentPacket.php | 4 ++-- .../mcpe/protocol/InventorySlotPacket.php | 4 ++-- .../mcpe/protocol/InventoryTransactionPacket.php | 4 ++-- .../mcpe/protocol/ItemFrameDropItemPacket.php | 4 ++-- .../network/mcpe/protocol/LabTablePacket.php | 4 ++-- .../network/mcpe/protocol/LevelEventPacket.php | 4 ++-- .../mcpe/protocol/LevelSoundEventPacket.php | 4 ++-- .../network/mcpe/protocol/LoginPacket.php | 4 ++-- .../mcpe/protocol/MapInfoRequestPacket.php | 4 ++-- .../mcpe/protocol/MobArmorEquipmentPacket.php | 4 ++-- .../network/mcpe/protocol/MobEffectPacket.php | 4 ++-- .../network/mcpe/protocol/MobEquipmentPacket.php | 4 ++-- .../mcpe/protocol/ModalFormRequestPacket.php | 4 ++-- .../mcpe/protocol/ModalFormResponsePacket.php | 4 ++-- .../network/mcpe/protocol/MoveEntityPacket.php | 4 ++-- .../network/mcpe/protocol/MovePlayerPacket.php | 4 ++-- .../network/mcpe/protocol/NpcRequestPacket.php | 4 ++-- .../network/mcpe/protocol/PacketPool.php | 4 ++-- .../mcpe/protocol/PhotoTransferPacket.php | 4 ++-- .../network/mcpe/protocol/PlaySoundPacket.php | 4 ++-- .../network/mcpe/protocol/PlayStatusPacket.php | 6 +++--- .../network/mcpe/protocol/PlayerActionPacket.php | 4 ++-- .../network/mcpe/protocol/PlayerHotbarPacket.php | 4 ++-- .../network/mcpe/protocol/PlayerInputPacket.php | 4 ++-- .../network/mcpe/protocol/PlayerListPacket.php | 4 ++-- .../network/mcpe/protocol/PlayerSkinPacket.php | 4 ++-- .../mcpe/protocol/PurchaseReceiptPacket.php | 4 ++-- .../network/mcpe/protocol/RemoveEntityPacket.php | 4 ++-- .../mcpe/protocol/RemoveObjectivePacket.php | 4 ++-- .../mcpe/protocol/RequestChunkRadiusPacket.php | 4 ++-- .../protocol/ResourcePackChunkDataPacket.php | 4 ++-- .../protocol/ResourcePackChunkRequestPacket.php | 4 ++-- .../ResourcePackClientResponsePacket.php | 4 ++-- .../mcpe/protocol/ResourcePackDataInfoPacket.php | 4 ++-- .../mcpe/protocol/ResourcePackStackPacket.php | 4 ++-- .../mcpe/protocol/ResourcePacksInfoPacket.php | 4 ++-- .../network/mcpe/protocol/RespawnPacket.php | 4 ++-- .../network/mcpe/protocol/RiderJumpPacket.php | 4 ++-- .../protocol/ServerSettingsRequestPacket.php | 4 ++-- .../protocol/ServerSettingsResponsePacket.php | 4 ++-- .../protocol/ServerToClientHandshakePacket.php | 4 ++-- .../mcpe/protocol/SetCommandsEnabledPacket.php | 4 ++-- .../mcpe/protocol/SetDefaultGameTypePacket.php | 4 ++-- .../mcpe/protocol/SetDifficultyPacket.php | 4 ++-- .../mcpe/protocol/SetDisplayObjectivePacket.php | 4 ++-- .../mcpe/protocol/SetEntityDataPacket.php | 4 ++-- .../mcpe/protocol/SetEntityLinkPacket.php | 4 ++-- .../mcpe/protocol/SetEntityMotionPacket.php | 4 ++-- .../network/mcpe/protocol/SetHealthPacket.php | 4 ++-- .../mcpe/protocol/SetLastHurtByPacket.php | 4 ++-- .../mcpe/protocol/SetPlayerGameTypePacket.php | 4 ++-- .../network/mcpe/protocol/SetScorePacket.php | 4 ++-- .../mcpe/protocol/SetSpawnPositionPacket.php | 4 ++-- .../network/mcpe/protocol/SetTimePacket.php | 4 ++-- .../network/mcpe/protocol/SetTitlePacket.php | 4 ++-- .../network/mcpe/protocol/ShowCreditsPacket.php | 4 ++-- .../network/mcpe/protocol/ShowProfilePacket.php | 4 ++-- .../mcpe/protocol/ShowStoreOfferPacket.php | 4 ++-- .../network/mcpe/protocol/SimpleEventPacket.php | 4 ++-- .../mcpe/protocol/SpawnExperienceOrbPacket.php | 4 ++-- .../network/mcpe/protocol/StartGamePacket.php | 4 ++-- .../network/mcpe/protocol/StopSoundPacket.php | 4 ++-- .../mcpe/protocol/StructureBlockUpdatePacket.php | 4 ++-- .../mcpe/protocol/SubClientLoginPacket.php | 4 ++-- .../mcpe/protocol/TakeItemEntityPacket.php | 4 ++-- .../network/mcpe/protocol/TextPacket.php | 4 ++-- .../network/mcpe/protocol/TransferPacket.php | 4 ++-- .../network/mcpe/protocol/UnknownPacket.php | 6 +++--- .../mcpe/protocol/UpdateAttributesPacket.php | 4 ++-- .../network/mcpe/protocol/UpdateBlockPacket.php | 4 ++-- .../mcpe/protocol/UpdateBlockSyncedPacket.php | 4 ++-- .../network/mcpe/protocol/UpdateEquipPacket.php | 4 ++-- .../network/mcpe/protocol/UpdateTradePacket.php | 4 ++-- .../network/mcpe/protocol/WSConnectPacket.php | 4 ++-- .../network/mcpe/protocol/types/EntityLink.php | 2 +- .../protocol/types/NetworkInventoryAction.php | 6 +++--- 116 files changed, 255 insertions(+), 255 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php b/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php index 135b80a66b..545e7988db 100644 --- a/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php @@ -33,11 +33,11 @@ class AddBehaviorTreePacket extends DataPacket{ /** @var string */ public $behaviorTreeJson; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->behaviorTreeJson = $this->getString(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putString($this->behaviorTreeJson); } diff --git a/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php b/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php index fb93f307cf..edd46870a0 100644 --- a/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php @@ -55,7 +55,7 @@ class AddEntityPacket extends DataPacket{ /** @var EntityLink[] */ public $links = []; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->entityUniqueId = $this->getEntityUniqueId(); $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->type = $this->getUnsignedVarInt(); @@ -89,7 +89,7 @@ class AddEntityPacket extends DataPacket{ } } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); $this->putEntityRuntimeId($this->entityRuntimeId); $this->putUnsignedVarInt($this->type); diff --git a/src/pocketmine/network/mcpe/protocol/AddHangingEntityPacket.php b/src/pocketmine/network/mcpe/protocol/AddHangingEntityPacket.php index 931bfde4cb..871dd6a796 100644 --- a/src/pocketmine/network/mcpe/protocol/AddHangingEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddHangingEntityPacket.php @@ -43,14 +43,14 @@ class AddHangingEntityPacket extends DataPacket{ /** @var int */ public $direction; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->entityUniqueId = $this->getEntityUniqueId(); $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->getBlockPosition($this->x, $this->y, $this->z); $this->direction = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); $this->putEntityRuntimeId($this->entityRuntimeId); $this->putBlockPosition($this->x, $this->y, $this->z); diff --git a/src/pocketmine/network/mcpe/protocol/AddItemEntityPacket.php b/src/pocketmine/network/mcpe/protocol/AddItemEntityPacket.php index 9e2772e4ef..f3d24b052b 100644 --- a/src/pocketmine/network/mcpe/protocol/AddItemEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddItemEntityPacket.php @@ -47,7 +47,7 @@ class AddItemEntityPacket extends DataPacket{ /** @var bool */ public $isFromFishing = false; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->entityUniqueId = $this->getEntityUniqueId(); $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->item = $this->getSlot(); @@ -57,7 +57,7 @@ class AddItemEntityPacket extends DataPacket{ $this->isFromFishing = $this->getBool(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); $this->putEntityRuntimeId($this->entityRuntimeId); $this->putSlot($this->item); diff --git a/src/pocketmine/network/mcpe/protocol/AddPaintingPacket.php b/src/pocketmine/network/mcpe/protocol/AddPaintingPacket.php index faee720aa7..a69560ce66 100644 --- a/src/pocketmine/network/mcpe/protocol/AddPaintingPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddPaintingPacket.php @@ -34,12 +34,12 @@ class AddPaintingPacket extends AddHangingEntityPacket{ /** @var string */ public $title; - protected function decodePayload(){ + protected function decodePayload() : void{ parent::decodePayload(); $this->title = $this->getString(); } - protected function encodePayload(){ + protected function encodePayload() : void{ parent::encodePayload(); $this->putString($this->title); } diff --git a/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php b/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php index 2394bbd6b9..675f6c3cda 100644 --- a/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php @@ -75,7 +75,7 @@ class AddPlayerPacket extends DataPacket{ /** @var EntityLink[] */ public $links = []; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->uuid = $this->getUUID(); $this->username = $this->getString(); $this->thirdPartyName = $this->getString(); @@ -105,7 +105,7 @@ class AddPlayerPacket extends DataPacket{ } } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putUUID($this->uuid); $this->putString($this->username); $this->putString($this->thirdPartyName); diff --git a/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php b/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php index 8196f6d3aa..ff084a0187 100644 --- a/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php @@ -76,7 +76,7 @@ class AdventureSettingsPacket extends DataPacket{ /** @var int */ public $entityUniqueId; //This is a little-endian long, NOT a var-long. (WTF Mojang) - protected function decodePayload(){ + protected function decodePayload() : void{ $this->flags = $this->getUnsignedVarInt(); $this->commandPermission = $this->getUnsignedVarInt(); $this->flags2 = $this->getUnsignedVarInt(); @@ -85,7 +85,7 @@ class AdventureSettingsPacket extends DataPacket{ $this->entityUniqueId = $this->getLLong(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putUnsignedVarInt($this->flags); $this->putUnsignedVarInt($this->commandPermission); $this->putUnsignedVarInt($this->flags2); @@ -102,7 +102,7 @@ class AdventureSettingsPacket extends DataPacket{ return ($this->flags & $flag) !== 0; } - public function setFlag(int $flag, bool $value){ + public function setFlag(int $flag, bool $value) : void{ if($flag & self::BITFLAG_SECOND_SET){ $flagSet =& $this->flags2; }else{ diff --git a/src/pocketmine/network/mcpe/protocol/AnimatePacket.php b/src/pocketmine/network/mcpe/protocol/AnimatePacket.php index 16dcc620ca..cabc2889c9 100644 --- a/src/pocketmine/network/mcpe/protocol/AnimatePacket.php +++ b/src/pocketmine/network/mcpe/protocol/AnimatePacket.php @@ -43,7 +43,7 @@ class AnimatePacket extends DataPacket{ /** @var float */ public $float = 0.0; //TODO (Boat rowing time?) - protected function decodePayload(){ + protected function decodePayload() : void{ $this->action = $this->getVarInt(); $this->entityRuntimeId = $this->getEntityRuntimeId(); if($this->action & 0x80){ @@ -51,7 +51,7 @@ class AnimatePacket extends DataPacket{ } } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putVarInt($this->action); $this->putEntityRuntimeId($this->entityRuntimeId); if($this->action & 0x80){ diff --git a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php index 6592afe670..8806360b1a 100644 --- a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php @@ -103,7 +103,7 @@ class AvailableCommandsPacket extends DataPacket{ */ public $commandData = []; - protected function decodePayload(){ + protected function decodePayload() : void{ for($i = 0, $this->enumValuesCount = $this->getUnsignedVarInt(); $i < $this->enumValuesCount; ++$i){ $this->enumValues[] = $this->getString(); } @@ -133,7 +133,7 @@ class AvailableCommandsPacket extends DataPacket{ return $retval; } - protected function putEnum(CommandEnum $enum){ + protected function putEnum(CommandEnum $enum) : void{ $this->putString($enum->enumName); $this->putUnsignedVarInt(count($enum->enumValues)); @@ -157,7 +157,7 @@ class AvailableCommandsPacket extends DataPacket{ } } - protected function putEnumValueIndex(int $index){ + protected function putEnumValueIndex(int $index) : void{ if($this->enumValuesCount < 256){ $this->putByte($index); }elseif($this->enumValuesCount < 65536){ @@ -201,7 +201,7 @@ class AvailableCommandsPacket extends DataPacket{ return $retval; } - protected function putCommandData(CommandData $data){ + protected function putCommandData(CommandData $data) : void{ $this->putString($data->commandName); $this->putString($data->commandDescription); $this->putByte($data->flags); @@ -278,7 +278,7 @@ class AvailableCommandsPacket extends DataPacket{ return "unknown ($argtype)"; } - protected function encodePayload(){ + protected function encodePayload() : void{ $enumValuesMap = []; $postfixesMap = []; $enumMap = []; diff --git a/src/pocketmine/network/mcpe/protocol/BatchPacket.php b/src/pocketmine/network/mcpe/protocol/BatchPacket.php index 48ee3e600a..657ecb0c2f 100644 --- a/src/pocketmine/network/mcpe/protocol/BatchPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BatchPacket.php @@ -48,12 +48,12 @@ class BatchPacket extends DataPacket{ return true; } - protected function decodeHeader(){ + protected function decodeHeader() : void{ $pid = $this->getByte(); assert($pid === static::NETWORK_ID); } - protected function decodePayload(){ + protected function decodePayload() : void{ $data = $this->getRemaining(); try{ $this->payload = zlib_decode($data, 1024 * 1024 * 64); //Max 64MB @@ -62,18 +62,18 @@ class BatchPacket extends DataPacket{ } } - protected function encodeHeader(){ + protected function encodeHeader() : void{ $this->putByte(static::NETWORK_ID); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->put(zlib_encode($this->payload, ZLIB_ENCODING_DEFLATE, $this->compressionLevel)); } /** * @param DataPacket $packet */ - public function addPacket(DataPacket $packet){ + public function addPacket(DataPacket $packet) : void{ if(!$packet->canBeBatched()){ throw new \InvalidArgumentException(get_class($packet) . " cannot be put inside a BatchPacket"); } @@ -87,7 +87,7 @@ class BatchPacket extends DataPacket{ /** * @return \Generator */ - public function getPackets(){ + public function getPackets() : \Generator{ $stream = new NetworkBinaryStream($this->payload); while(!$stream->feof()){ yield $stream->getString(); @@ -98,7 +98,7 @@ class BatchPacket extends DataPacket{ return $this->compressionLevel; } - public function setCompressionLevel(int $level){ + public function setCompressionLevel(int $level) : void{ $this->compressionLevel = $level; } diff --git a/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php b/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php index e936f01e50..e5938f94c2 100644 --- a/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php @@ -40,12 +40,12 @@ class BlockEntityDataPacket extends DataPacket{ /** @var string */ public $namedtag; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->getBlockPosition($this->x, $this->y, $this->z); $this->namedtag = $this->getRemaining(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putBlockPosition($this->x, $this->y, $this->z); $this->put($this->namedtag); } diff --git a/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php b/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php index 12e7fc0c74..1ec8f6b4ce 100644 --- a/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php @@ -42,13 +42,13 @@ class BlockEventPacket extends DataPacket{ /** @var int */ public $eventData; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->getBlockPosition($this->x, $this->y, $this->z); $this->eventType = $this->getVarInt(); $this->eventData = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putBlockPosition($this->x, $this->y, $this->z); $this->putVarInt($this->eventType); $this->putVarInt($this->eventData); diff --git a/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php b/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php index 8e36475658..b3a7da89ad 100644 --- a/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php @@ -43,13 +43,13 @@ class BlockPickRequestPacket extends DataPacket{ /** @var int */ public $hotbarSlot; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->getSignedBlockPosition($this->blockX, $this->blockY, $this->blockZ); $this->addUserData = $this->getBool(); $this->hotbarSlot = $this->getByte(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putSignedBlockPosition($this->blockX, $this->blockY, $this->blockZ); $this->putBool($this->addUserData); $this->putByte($this->hotbarSlot); diff --git a/src/pocketmine/network/mcpe/protocol/BookEditPacket.php b/src/pocketmine/network/mcpe/protocol/BookEditPacket.php index d211b7f15e..0163b181a7 100644 --- a/src/pocketmine/network/mcpe/protocol/BookEditPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BookEditPacket.php @@ -57,7 +57,7 @@ class BookEditPacket extends DataPacket{ /** @var string */ public $xuid; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->type = $this->getByte(); $this->inventorySlot = $this->getByte(); @@ -85,7 +85,7 @@ class BookEditPacket extends DataPacket{ } } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putByte($this->type); $this->putByte($this->inventorySlot); diff --git a/src/pocketmine/network/mcpe/protocol/BossEventPacket.php b/src/pocketmine/network/mcpe/protocol/BossEventPacket.php index 30d07d6580..49739532c8 100644 --- a/src/pocketmine/network/mcpe/protocol/BossEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BossEventPacket.php @@ -66,7 +66,7 @@ class BossEventPacket extends DataPacket{ /** @var int */ public $overlay; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->bossEid = $this->getEntityUniqueId(); $this->eventType = $this->getUnsignedVarInt(); switch($this->eventType){ @@ -96,7 +96,7 @@ class BossEventPacket extends DataPacket{ } } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityUniqueId($this->bossEid); $this->putUnsignedVarInt($this->eventType); switch($this->eventType){ diff --git a/src/pocketmine/network/mcpe/protocol/CameraPacket.php b/src/pocketmine/network/mcpe/protocol/CameraPacket.php index ebee825cfb..e022fb1da3 100644 --- a/src/pocketmine/network/mcpe/protocol/CameraPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CameraPacket.php @@ -35,12 +35,12 @@ class CameraPacket extends DataPacket{ /** @var int */ public $playerUniqueId; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->cameraUniqueId = $this->getEntityUniqueId(); $this->playerUniqueId = $this->getEntityUniqueId(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityUniqueId($this->cameraUniqueId); $this->putEntityUniqueId($this->playerUniqueId); } diff --git a/src/pocketmine/network/mcpe/protocol/ChangeDimensionPacket.php b/src/pocketmine/network/mcpe/protocol/ChangeDimensionPacket.php index 485748f6d5..2177bf6c1a 100644 --- a/src/pocketmine/network/mcpe/protocol/ChangeDimensionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ChangeDimensionPacket.php @@ -39,13 +39,13 @@ class ChangeDimensionPacket extends DataPacket{ /** @var bool */ public $respawn = false; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->dimension = $this->getVarInt(); $this->position = $this->getVector3(); $this->respawn = $this->getBool(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putVarInt($this->dimension); $this->putVector3($this->position); $this->putBool($this->respawn); diff --git a/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php b/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php index 684de5f33e..231028525f 100644 --- a/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php @@ -34,11 +34,11 @@ class ChunkRadiusUpdatedPacket extends DataPacket{ /** @var int */ public $radius; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->radius = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putVarInt($this->radius); } diff --git a/src/pocketmine/network/mcpe/protocol/ClientToServerHandshakePacket.php b/src/pocketmine/network/mcpe/protocol/ClientToServerHandshakePacket.php index a4a564109a..c6a386ae12 100644 --- a/src/pocketmine/network/mcpe/protocol/ClientToServerHandshakePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ClientToServerHandshakePacket.php @@ -35,11 +35,11 @@ class ClientToServerHandshakePacket extends DataPacket{ return true; } - protected function decodePayload(){ + protected function decodePayload() : void{ //No payload } - protected function encodePayload(){ + protected function encodePayload() : void{ //No payload } diff --git a/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php b/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php index df6b1dcbc7..ab365e0f36 100644 --- a/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php @@ -65,7 +65,7 @@ class ClientboundMapItemDataPacket extends DataPacket{ /** @var Color[][] */ public $colors = []; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->mapId = $this->getEntityUniqueId(); $this->type = $this->getUnsignedVarInt(); $this->dimensionId = $this->getByte(); @@ -114,7 +114,7 @@ class ClientboundMapItemDataPacket extends DataPacket{ } } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityUniqueId($this->mapId); $type = 0; diff --git a/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php b/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php index be810fbc12..a0d8de69b0 100644 --- a/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php +++ b/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php @@ -60,7 +60,7 @@ class CommandBlockUpdatePacket extends DataPacket{ /** @var bool */ public $shouldTrackOutput; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->isBlock = $this->getBool(); if($this->isBlock){ @@ -80,7 +80,7 @@ class CommandBlockUpdatePacket extends DataPacket{ $this->shouldTrackOutput = $this->getBool(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putBool($this->isBlock); if($this->isBlock){ diff --git a/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php b/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php index 8a61d4587a..5d4cbb99a9 100644 --- a/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php @@ -43,7 +43,7 @@ class CommandOutputPacket extends DataPacket{ /** @var string */ public $unknownString; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->originData = $this->getCommandOriginData(); $this->outputType = $this->getByte(); $this->successCount = $this->getUnsignedVarInt(); @@ -70,7 +70,7 @@ class CommandOutputPacket extends DataPacket{ return $message; } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putCommandOriginData($this->originData); $this->putByte($this->outputType); $this->putUnsignedVarInt($this->successCount); @@ -85,7 +85,7 @@ class CommandOutputPacket extends DataPacket{ } } - protected function putCommandMessage(CommandOutputMessage $message){ + protected function putCommandMessage(CommandOutputMessage $message) : void{ $this->putBool($message->isInternal); $this->putString($message->messageId); diff --git a/src/pocketmine/network/mcpe/protocol/CommandRequestPacket.php b/src/pocketmine/network/mcpe/protocol/CommandRequestPacket.php index 2159086776..f15414f120 100644 --- a/src/pocketmine/network/mcpe/protocol/CommandRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CommandRequestPacket.php @@ -38,13 +38,13 @@ class CommandRequestPacket extends DataPacket{ /** @var bool */ public $isInternal; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->command = $this->getString(); $this->originData = $this->getCommandOriginData(); $this->isInternal = $this->getBool(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putString($this->command); $this->putCommandOriginData($this->originData); $this->putBool($this->isInternal); diff --git a/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php b/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php index 105de06ea2..f50e0a29fd 100644 --- a/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php @@ -34,11 +34,11 @@ class ContainerClosePacket extends DataPacket{ /** @var int */ public $windowId; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->windowId = $this->getByte(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putByte($this->windowId); } diff --git a/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php b/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php index 9b1b07c41e..0b9f8da0ca 100644 --- a/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php @@ -44,14 +44,14 @@ class ContainerOpenPacket extends DataPacket{ /** @var int */ public $entityUniqueId = -1; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->windowId = $this->getByte(); $this->type = $this->getByte(); $this->getBlockPosition($this->x, $this->y, $this->z); $this->entityUniqueId = $this->getEntityUniqueId(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putByte($this->windowId); $this->putByte($this->type); $this->putBlockPosition($this->x, $this->y, $this->z); diff --git a/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php b/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php index a3d57195f8..1242de2d5b 100644 --- a/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php @@ -48,13 +48,13 @@ class ContainerSetDataPacket extends DataPacket{ /** @var int */ public $value; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->windowId = $this->getByte(); $this->property = $this->getVarInt(); $this->value = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putByte($this->windowId); $this->putVarInt($this->property); $this->putVarInt($this->value); diff --git a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php b/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php index cf4afce99b..06ae1feab1 100644 --- a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php @@ -58,7 +58,7 @@ class CraftingDataPacket extends DataPacket{ return parent::clean(); } - protected function decodePayload(){ + protected function decodePayload() : void{ $this->decodedEntries = []; $recipeCount = $this->getUnsignedVarInt(); for($i = 0; $i < $recipeCount; ++$i){ @@ -131,7 +131,7 @@ class CraftingDataPacket extends DataPacket{ return -1; } - private static function writeShapelessRecipe(ShapelessRecipe $recipe, NetworkBinaryStream $stream){ + private static function writeShapelessRecipe(ShapelessRecipe $recipe, NetworkBinaryStream $stream) : int{ $stream->putUnsignedVarInt($recipe->getIngredientCount()); foreach($recipe->getIngredientList() as $item){ $stream->putSlot($item); @@ -148,7 +148,7 @@ class CraftingDataPacket extends DataPacket{ return CraftingDataPacket::ENTRY_SHAPELESS; } - private static function writeShapedRecipe(ShapedRecipe $recipe, NetworkBinaryStream $stream){ + private static function writeShapedRecipe(ShapedRecipe $recipe, NetworkBinaryStream $stream) : int{ $stream->putVarInt($recipe->getWidth()); $stream->putVarInt($recipe->getHeight()); @@ -169,7 +169,7 @@ class CraftingDataPacket extends DataPacket{ return CraftingDataPacket::ENTRY_SHAPED; } - private static function writeFurnaceRecipe(FurnaceRecipe $recipe, NetworkBinaryStream $stream){ + private static function writeFurnaceRecipe(FurnaceRecipe $recipe, NetworkBinaryStream $stream) : int{ if(!$recipe->getInput()->hasAnyDamageValue()){ //Data recipe $stream->putVarInt($recipe->getInput()->getId()); $stream->putVarInt($recipe->getInput()->getDamage()); @@ -184,19 +184,19 @@ class CraftingDataPacket extends DataPacket{ } } - public function addShapelessRecipe(ShapelessRecipe $recipe){ + public function addShapelessRecipe(ShapelessRecipe $recipe) : void{ $this->entries[] = $recipe; } - public function addShapedRecipe(ShapedRecipe $recipe){ + public function addShapedRecipe(ShapedRecipe $recipe) : void{ $this->entries[] = $recipe; } - public function addFurnaceRecipe(FurnaceRecipe $recipe){ + public function addFurnaceRecipe(FurnaceRecipe $recipe) : void{ $this->entries[] = $recipe; } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putUnsignedVarInt(count($this->entries)); $writer = new NetworkBinaryStream(); diff --git a/src/pocketmine/network/mcpe/protocol/CraftingEventPacket.php b/src/pocketmine/network/mcpe/protocol/CraftingEventPacket.php index 7be78b254a..cc48a21fd0 100644 --- a/src/pocketmine/network/mcpe/protocol/CraftingEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CraftingEventPacket.php @@ -49,7 +49,7 @@ class CraftingEventPacket extends DataPacket{ return parent::clean(); } - protected function decodePayload(){ + protected function decodePayload() : void{ $this->windowId = $this->getByte(); $this->type = $this->getVarInt(); $this->id = $this->getUUID(); @@ -65,7 +65,7 @@ class CraftingEventPacket extends DataPacket{ } } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putByte($this->windowId); $this->putVarInt($this->type); $this->putUUID($this->id); diff --git a/src/pocketmine/network/mcpe/protocol/DataPacket.php b/src/pocketmine/network/mcpe/protocol/DataPacket.php index c1b9831776..1201971d13 100644 --- a/src/pocketmine/network/mcpe/protocol/DataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/DataPacket.php @@ -41,7 +41,7 @@ abstract class DataPacket extends NetworkBinaryStream{ /** @var int */ public $recipientSubId = 0; - public function pid(){ + public function pid() : int{ return $this::NETWORK_ID; } @@ -65,13 +65,13 @@ abstract class DataPacket extends NetworkBinaryStream{ return false; } - public function decode(){ + public function decode() : void{ $this->offset = 0; $this->decodeHeader(); $this->decodePayload(); } - protected function decodeHeader(){ + protected function decodeHeader() : void{ $pid = $this->getUnsignedVarInt(); assert($pid === static::NETWORK_ID); @@ -83,18 +83,18 @@ abstract class DataPacket extends NetworkBinaryStream{ /** * Note for plugin developers: If you're adding your own packets, you should perform decoding in here. */ - protected function decodePayload(){ + protected function decodePayload() : void{ } - public function encode(){ + public function encode() : void{ $this->reset(); $this->encodeHeader(); $this->encodePayload(); $this->isEncoded = true; } - protected function encodeHeader(){ + protected function encodeHeader() : void{ $this->putUnsignedVarInt(static::NETWORK_ID); $this->putByte($this->senderSubId); @@ -104,7 +104,7 @@ abstract class DataPacket extends NetworkBinaryStream{ /** * Note for plugin developers: If you're adding your own packets, you should perform encoding in here. */ - protected function encodePayload(){ + protected function encodePayload() : void{ } diff --git a/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php b/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php index e9047df259..e8207306f3 100644 --- a/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php +++ b/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php @@ -40,14 +40,14 @@ class DisconnectPacket extends DataPacket{ return true; } - protected function decodePayload(){ + protected function decodePayload() : void{ $this->hideDisconnectionScreen = $this->getBool(); if(!$this->hideDisconnectionScreen){ $this->message = $this->getString(); } } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putBool($this->hideDisconnectionScreen); if(!$this->hideDisconnectionScreen){ $this->putString($this->message); diff --git a/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php b/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php index 19e5fbd190..5d6344b4b1 100644 --- a/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php @@ -90,13 +90,13 @@ class EntityEventPacket extends DataPacket{ /** @var int */ public $data = 0; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->event = $this->getByte(); $this->data = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityRuntimeId($this->entityRuntimeId); $this->putByte($this->event); $this->putVarInt($this->data); diff --git a/src/pocketmine/network/mcpe/protocol/EntityFallPacket.php b/src/pocketmine/network/mcpe/protocol/EntityFallPacket.php index 4c3c5cd6c2..490d6fd6db 100644 --- a/src/pocketmine/network/mcpe/protocol/EntityFallPacket.php +++ b/src/pocketmine/network/mcpe/protocol/EntityFallPacket.php @@ -38,13 +38,13 @@ class EntityFallPacket extends DataPacket{ /** @var bool */ public $isInVoid; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->fallDistance = $this->getLFloat(); $this->isInVoid = $this->getBool(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityRuntimeId($this->entityRuntimeId); $this->putLFloat($this->fallDistance); $this->putBool($this->isInVoid); diff --git a/src/pocketmine/network/mcpe/protocol/EntityPickRequestPacket.php b/src/pocketmine/network/mcpe/protocol/EntityPickRequestPacket.php index 96b6c7b2e7..8bb6b156da 100644 --- a/src/pocketmine/network/mcpe/protocol/EntityPickRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/EntityPickRequestPacket.php @@ -35,12 +35,12 @@ class EntityPickRequestPacket extends DataPacket{ /** @var int */ public $hotbarSlot; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->entityUniqueId = $this->getLLong(); $this->hotbarSlot = $this->getByte(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putLLong($this->entityUniqueId); $this->putByte($this->hotbarSlot); } diff --git a/src/pocketmine/network/mcpe/protocol/EventPacket.php b/src/pocketmine/network/mcpe/protocol/EventPacket.php index 612f5ded71..d5ce93c832 100644 --- a/src/pocketmine/network/mcpe/protocol/EventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/EventPacket.php @@ -48,7 +48,7 @@ class EventPacket extends DataPacket{ /** @var int */ public $type; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->playerRuntimeId = $this->getEntityRuntimeId(); $this->eventData = $this->getVarInt(); $this->type = $this->getByte(); @@ -56,7 +56,7 @@ class EventPacket extends DataPacket{ //TODO: nice confusing mess } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityRuntimeId($this->playerRuntimeId); $this->putVarInt($this->eventData); $this->putByte($this->type); diff --git a/src/pocketmine/network/mcpe/protocol/ExplodePacket.php b/src/pocketmine/network/mcpe/protocol/ExplodePacket.php index 5e2f0855d0..8740d28961 100644 --- a/src/pocketmine/network/mcpe/protocol/ExplodePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ExplodePacket.php @@ -44,7 +44,7 @@ class ExplodePacket extends DataPacket{ return parent::clean(); } - protected function decodePayload(){ + protected function decodePayload() : void{ $this->position = $this->getVector3(); $this->radius = (float) ($this->getVarInt() / 32); $count = $this->getUnsignedVarInt(); @@ -55,7 +55,7 @@ class ExplodePacket extends DataPacket{ } } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putVector3($this->position); $this->putVarInt((int) ($this->radius * 32)); $this->putUnsignedVarInt(count($this->records)); diff --git a/src/pocketmine/network/mcpe/protocol/FullChunkDataPacket.php b/src/pocketmine/network/mcpe/protocol/FullChunkDataPacket.php index c3c0a42158..5497267940 100644 --- a/src/pocketmine/network/mcpe/protocol/FullChunkDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/FullChunkDataPacket.php @@ -38,13 +38,13 @@ class FullChunkDataPacket extends DataPacket{ /** @var string */ public $data; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->chunkX = $this->getVarInt(); $this->chunkZ = $this->getVarInt(); $this->data = $this->getString(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putVarInt($this->chunkX); $this->putVarInt($this->chunkZ); $this->putString($this->data); diff --git a/src/pocketmine/network/mcpe/protocol/GameRulesChangedPacket.php b/src/pocketmine/network/mcpe/protocol/GameRulesChangedPacket.php index 1a45daa911..c7865588eb 100644 --- a/src/pocketmine/network/mcpe/protocol/GameRulesChangedPacket.php +++ b/src/pocketmine/network/mcpe/protocol/GameRulesChangedPacket.php @@ -33,11 +33,11 @@ class GameRulesChangedPacket extends DataPacket{ /** @var array */ public $gameRules = []; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->gameRules = $this->getGameRules(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putGameRules($this->gameRules); } diff --git a/src/pocketmine/network/mcpe/protocol/GuiDataPickItemPacket.php b/src/pocketmine/network/mcpe/protocol/GuiDataPickItemPacket.php index d9c1cf20ee..8341595525 100644 --- a/src/pocketmine/network/mcpe/protocol/GuiDataPickItemPacket.php +++ b/src/pocketmine/network/mcpe/protocol/GuiDataPickItemPacket.php @@ -33,11 +33,11 @@ class GuiDataPickItemPacket extends DataPacket{ /** @var int */ public $hotbarSlot; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->hotbarSlot = $this->getLInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putLInt($this->hotbarSlot); } diff --git a/src/pocketmine/network/mcpe/protocol/HurtArmorPacket.php b/src/pocketmine/network/mcpe/protocol/HurtArmorPacket.php index 805d0f1af6..ba557a2b24 100644 --- a/src/pocketmine/network/mcpe/protocol/HurtArmorPacket.php +++ b/src/pocketmine/network/mcpe/protocol/HurtArmorPacket.php @@ -34,11 +34,11 @@ class HurtArmorPacket extends DataPacket{ /** @var int */ public $health; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->health = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putVarInt($this->health); } diff --git a/src/pocketmine/network/mcpe/protocol/InteractPacket.php b/src/pocketmine/network/mcpe/protocol/InteractPacket.php index 7373962799..eea2d30f14 100644 --- a/src/pocketmine/network/mcpe/protocol/InteractPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InteractPacket.php @@ -48,7 +48,7 @@ class InteractPacket extends DataPacket{ /** @var float */ public $z; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->action = $this->getByte(); $this->target = $this->getEntityRuntimeId(); @@ -60,7 +60,7 @@ class InteractPacket extends DataPacket{ } } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putByte($this->action); $this->putEntityRuntimeId($this->target); diff --git a/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php b/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php index 76ba225fa9..bb6e6eebc5 100644 --- a/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php @@ -36,7 +36,7 @@ class InventoryContentPacket extends DataPacket{ /** @var Item[] */ public $items = []; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->windowId = $this->getUnsignedVarInt(); $count = $this->getUnsignedVarInt(); for($i = 0; $i < $count; ++$i){ @@ -44,7 +44,7 @@ class InventoryContentPacket extends DataPacket{ } } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putUnsignedVarInt($this->windowId); $this->putUnsignedVarInt(count($this->items)); foreach($this->items as $item){ diff --git a/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php b/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php index 1973e690bb..2eff470d40 100644 --- a/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php @@ -38,13 +38,13 @@ class InventorySlotPacket extends DataPacket{ /** @var Item */ public $item; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->windowId = $this->getUnsignedVarInt(); $this->inventorySlot = $this->getUnsignedVarInt(); $this->item = $this->getSlot(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putUnsignedVarInt($this->windowId); $this->putUnsignedVarInt($this->inventorySlot); $this->putSlot($this->item); diff --git a/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php b/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php index 7a3556b702..90d09bc323 100644 --- a/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php @@ -69,7 +69,7 @@ class InventoryTransactionPacket extends DataPacket{ /** @var \stdClass */ public $trData; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->transactionType = $this->getUnsignedVarInt(); for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ @@ -111,7 +111,7 @@ class InventoryTransactionPacket extends DataPacket{ } } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putUnsignedVarInt($this->transactionType); $this->putUnsignedVarInt(count($this->actions)); diff --git a/src/pocketmine/network/mcpe/protocol/ItemFrameDropItemPacket.php b/src/pocketmine/network/mcpe/protocol/ItemFrameDropItemPacket.php index 200bb5824d..989c490800 100644 --- a/src/pocketmine/network/mcpe/protocol/ItemFrameDropItemPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ItemFrameDropItemPacket.php @@ -38,11 +38,11 @@ class ItemFrameDropItemPacket extends DataPacket{ /** @var int */ public $z; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->getBlockPosition($this->x, $this->y, $this->z); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putBlockPosition($this->x, $this->y, $this->z); } diff --git a/src/pocketmine/network/mcpe/protocol/LabTablePacket.php b/src/pocketmine/network/mcpe/protocol/LabTablePacket.php index 8f45bcc566..f5d6f4f930 100644 --- a/src/pocketmine/network/mcpe/protocol/LabTablePacket.php +++ b/src/pocketmine/network/mcpe/protocol/LabTablePacket.php @@ -43,13 +43,13 @@ class LabTablePacket extends DataPacket{ /** @var int */ public $reactionType; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->uselessByte = $this->getByte(); $this->getSignedBlockPosition($this->x, $this->y, $this->z); $this->reactionType = $this->getByte(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putByte($this->uselessByte); $this->putSignedBlockPosition($this->x, $this->y, $this->z); $this->putByte($this->reactionType); diff --git a/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php b/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php index c400651159..a0f9fd92ed 100644 --- a/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php @@ -118,13 +118,13 @@ class LevelEventPacket extends DataPacket{ /** @var int */ public $data; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->evid = $this->getVarInt(); $this->position = $this->getVector3(); $this->data = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putVarInt($this->evid); $this->putVector3Nullable($this->position); $this->putVarInt($this->data); diff --git a/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacket.php b/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacket.php index 0afa420759..f9e330dd09 100644 --- a/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacket.php @@ -257,7 +257,7 @@ class LevelSoundEventPacket extends DataPacket{ /** @var bool */ public $disableRelativeVolume = false; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->sound = $this->getByte(); $this->position = $this->getVector3(); $this->extraData = $this->getVarInt(); @@ -266,7 +266,7 @@ class LevelSoundEventPacket extends DataPacket{ $this->disableRelativeVolume = $this->getBool(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putByte($this->sound); $this->putVector3($this->position); $this->putVarInt($this->extraData); diff --git a/src/pocketmine/network/mcpe/protocol/LoginPacket.php b/src/pocketmine/network/mcpe/protocol/LoginPacket.php index 24f9c520d0..554061aadd 100644 --- a/src/pocketmine/network/mcpe/protocol/LoginPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LoginPacket.php @@ -76,7 +76,7 @@ class LoginPacket extends DataPacket{ return $this->protocol !== null and $this->protocol !== ProtocolInfo::CURRENT_PROTOCOL; } - protected function decodePayload(){ + protected function decodePayload() : void{ $this->protocol = $this->getInt(); if($this->protocol !== ProtocolInfo::CURRENT_PROTOCOL){ @@ -133,7 +133,7 @@ class LoginPacket extends DataPacket{ $this->locale = $this->clientData["LanguageCode"] ?? null; } - protected function encodePayload(){ + protected function encodePayload() : void{ //TODO } diff --git a/src/pocketmine/network/mcpe/protocol/MapInfoRequestPacket.php b/src/pocketmine/network/mcpe/protocol/MapInfoRequestPacket.php index 4590aac25d..68b2a5d649 100644 --- a/src/pocketmine/network/mcpe/protocol/MapInfoRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MapInfoRequestPacket.php @@ -35,11 +35,11 @@ class MapInfoRequestPacket extends DataPacket{ /** @var int */ public $mapId; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->mapId = $this->getEntityUniqueId(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityUniqueId($this->mapId); } diff --git a/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php b/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php index f0e8335ee8..53131172df 100644 --- a/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php @@ -37,14 +37,14 @@ class MobArmorEquipmentPacket extends DataPacket{ /** @var Item[] */ public $slots = []; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); for($i = 0; $i < 4; ++$i){ $this->slots[$i] = $this->getSlot(); } } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityRuntimeId($this->entityRuntimeId); for($i = 0; $i < 4; ++$i){ $this->putSlot($this->slots[$i]); diff --git a/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php b/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php index e14bf73578..ccb43c5354 100644 --- a/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php @@ -48,7 +48,7 @@ class MobEffectPacket extends DataPacket{ /** @var int */ public $duration = 0; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->eventId = $this->getByte(); $this->effectId = $this->getVarInt(); @@ -57,7 +57,7 @@ class MobEffectPacket extends DataPacket{ $this->duration = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityRuntimeId($this->entityRuntimeId); $this->putByte($this->eventId); $this->putVarInt($this->effectId); diff --git a/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php b/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php index 49025bb27a..428f25b4bf 100644 --- a/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php @@ -43,7 +43,7 @@ class MobEquipmentPacket extends DataPacket{ /** @var int */ public $windowId = 0; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->item = $this->getSlot(); $this->inventorySlot = $this->getByte(); @@ -51,7 +51,7 @@ class MobEquipmentPacket extends DataPacket{ $this->windowId = $this->getByte(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityRuntimeId($this->entityRuntimeId); $this->putSlot($this->item); $this->putByte($this->inventorySlot); diff --git a/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php b/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php index 4a0bd2cb9e..bc6fc0b240 100644 --- a/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php @@ -35,12 +35,12 @@ class ModalFormRequestPacket extends DataPacket{ /** @var string */ public $formData; //json - protected function decodePayload(){ + protected function decodePayload() : void{ $this->formId = $this->getUnsignedVarInt(); $this->formData = $this->getString(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putUnsignedVarInt($this->formId); $this->putString($this->formData); } diff --git a/src/pocketmine/network/mcpe/protocol/ModalFormResponsePacket.php b/src/pocketmine/network/mcpe/protocol/ModalFormResponsePacket.php index 9303ec17dd..ca888ee969 100644 --- a/src/pocketmine/network/mcpe/protocol/ModalFormResponsePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ModalFormResponsePacket.php @@ -35,12 +35,12 @@ class ModalFormResponsePacket extends DataPacket{ /** @var string */ public $formData; //json - protected function decodePayload(){ + protected function decodePayload() : void{ $this->formId = $this->getUnsignedVarInt(); $this->formData = $this->getString(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putUnsignedVarInt($this->formId); $this->putString($this->formData); } diff --git a/src/pocketmine/network/mcpe/protocol/MoveEntityPacket.php b/src/pocketmine/network/mcpe/protocol/MoveEntityPacket.php index a17e4de3e8..cd5d60c275 100644 --- a/src/pocketmine/network/mcpe/protocol/MoveEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MoveEntityPacket.php @@ -47,7 +47,7 @@ class MoveEntityPacket extends DataPacket{ /** @var bool */ public $teleported = false; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->position = $this->getVector3(); $this->pitch = $this->getByteRotation(); @@ -57,7 +57,7 @@ class MoveEntityPacket extends DataPacket{ $this->teleported = $this->getBool(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityRuntimeId($this->entityRuntimeId); $this->putVector3($this->position); $this->putByteRotation($this->pitch); diff --git a/src/pocketmine/network/mcpe/protocol/MovePlayerPacket.php b/src/pocketmine/network/mcpe/protocol/MovePlayerPacket.php index cb85b447e5..cf1447011c 100644 --- a/src/pocketmine/network/mcpe/protocol/MovePlayerPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MovePlayerPacket.php @@ -58,7 +58,7 @@ class MovePlayerPacket extends DataPacket{ /** @var int */ public $teleportItem = 0; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->position = $this->getVector3(); $this->pitch = $this->getLFloat(); @@ -73,7 +73,7 @@ class MovePlayerPacket extends DataPacket{ } } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityRuntimeId($this->entityRuntimeId); $this->putVector3($this->position); $this->putLFloat($this->pitch); diff --git a/src/pocketmine/network/mcpe/protocol/NpcRequestPacket.php b/src/pocketmine/network/mcpe/protocol/NpcRequestPacket.php index 479221c014..3a61b55415 100644 --- a/src/pocketmine/network/mcpe/protocol/NpcRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/NpcRequestPacket.php @@ -39,14 +39,14 @@ class NpcRequestPacket extends DataPacket{ /** @var int */ public $actionType; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->requestType = $this->getByte(); $this->commandString = $this->getString(); $this->actionType = $this->getByte(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityRuntimeId($this->entityRuntimeId); $this->putByte($this->requestType); $this->putString($this->commandString); diff --git a/src/pocketmine/network/mcpe/protocol/PacketPool.php b/src/pocketmine/network/mcpe/protocol/PacketPool.php index af1f8b1848..46819b685f 100644 --- a/src/pocketmine/network/mcpe/protocol/PacketPool.php +++ b/src/pocketmine/network/mcpe/protocol/PacketPool.php @@ -27,7 +27,7 @@ class PacketPool{ /** @var \SplFixedArray */ protected static $pool = null; - public static function init(){ + public static function init() : void{ static::$pool = new \SplFixedArray(256); //Normal packets @@ -148,7 +148,7 @@ class PacketPool{ /** * @param DataPacket $packet */ - public static function registerPacket(DataPacket $packet){ + public static function registerPacket(DataPacket $packet) : void{ static::$pool[$packet->pid()] = clone $packet; } diff --git a/src/pocketmine/network/mcpe/protocol/PhotoTransferPacket.php b/src/pocketmine/network/mcpe/protocol/PhotoTransferPacket.php index 8d42c38372..75b6f89f7e 100644 --- a/src/pocketmine/network/mcpe/protocol/PhotoTransferPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PhotoTransferPacket.php @@ -37,13 +37,13 @@ class PhotoTransferPacket extends DataPacket{ /** @var string */ public $bookId; //photos are stored in a sibling directory to the games folder (screenshots/(some UUID)/bookID/example.png) - protected function decodePayload(){ + protected function decodePayload() : void{ $this->photoName = $this->getString(); $this->photoData = $this->getString(); $this->bookId = $this->getString(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putString($this->photoName); $this->putString($this->photoData); $this->putString($this->bookId); diff --git a/src/pocketmine/network/mcpe/protocol/PlaySoundPacket.php b/src/pocketmine/network/mcpe/protocol/PlaySoundPacket.php index b9ddb193e3..0460a3efca 100644 --- a/src/pocketmine/network/mcpe/protocol/PlaySoundPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlaySoundPacket.php @@ -45,7 +45,7 @@ class PlaySoundPacket extends DataPacket{ /** @var float */ public $pitch; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->soundName = $this->getString(); $this->getBlockPosition($this->x, $this->y, $this->z); $this->x /= 8; @@ -55,7 +55,7 @@ class PlaySoundPacket extends DataPacket{ $this->pitch = $this->getLFloat(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putString($this->soundName); $this->putBlockPosition((int) ($this->x * 8), (int) ($this->y * 8), (int) ($this->z * 8)); $this->putLFloat($this->volume); diff --git a/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php b/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php index ed04089721..fe01183f28 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php @@ -49,7 +49,7 @@ class PlayStatusPacket extends DataPacket{ */ public $protocol; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->status = $this->getInt(); } @@ -57,7 +57,7 @@ class PlayStatusPacket extends DataPacket{ return true; } - protected function encodeHeader(){ + protected function encodeHeader() : void{ if($this->protocol < 130){ //MCPE <= 1.1 $this->putByte(static::NETWORK_ID); }else{ @@ -65,7 +65,7 @@ class PlayStatusPacket extends DataPacket{ } } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putInt($this->status); } diff --git a/src/pocketmine/network/mcpe/protocol/PlayerActionPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerActionPacket.php index 5d45b27d37..3a16a783bc 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerActionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerActionPacket.php @@ -70,14 +70,14 @@ class PlayerActionPacket extends DataPacket{ /** @var int */ public $face; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->action = $this->getVarInt(); $this->getBlockPosition($this->x, $this->y, $this->z); $this->face = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityRuntimeId($this->entityRuntimeId); $this->putVarInt($this->action); $this->putBlockPosition($this->x, $this->y, $this->z); diff --git a/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php index 82269f7503..b541128beb 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php @@ -41,13 +41,13 @@ class PlayerHotbarPacket extends DataPacket{ /** @var bool */ public $selectHotbarSlot = true; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->selectedHotbarSlot = $this->getUnsignedVarInt(); $this->windowId = $this->getByte(); $this->selectHotbarSlot = $this->getBool(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putUnsignedVarInt($this->selectedHotbarSlot); $this->putByte($this->windowId); $this->putBool($this->selectHotbarSlot); diff --git a/src/pocketmine/network/mcpe/protocol/PlayerInputPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerInputPacket.php index 9835e832ab..8664e92ebe 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerInputPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerInputPacket.php @@ -40,14 +40,14 @@ class PlayerInputPacket extends DataPacket{ /** @var bool */ public $sneaking; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->motionX = $this->getLFloat(); $this->motionY = $this->getLFloat(); $this->jumping = $this->getBool(); $this->sneaking = $this->getBool(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putLFloat($this->motionX); $this->putLFloat($this->motionY); $this->putBool($this->jumping); diff --git a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php index 6e756982dc..ba854d8b98 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php @@ -46,7 +46,7 @@ class PlayerListPacket extends DataPacket{ return parent::clean(); } - protected function decodePayload(){ + protected function decodePayload() : void{ $this->type = $this->getByte(); $count = $this->getUnsignedVarInt(); for($i = 0; $i < $count; ++$i){ @@ -82,7 +82,7 @@ class PlayerListPacket extends DataPacket{ } } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putByte($this->type); $this->putUnsignedVarInt(count($this->entries)); foreach($this->entries as $entry){ diff --git a/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php index 2fa5314197..64a9b67c5e 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php @@ -42,7 +42,7 @@ class PlayerSkinPacket extends DataPacket{ public $skin; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->uuid = $this->getUUID(); $skinId = $this->getString(); @@ -56,7 +56,7 @@ class PlayerSkinPacket extends DataPacket{ $this->skin = new Skin($skinId, $skinData, $capeData, $geometryModel, $geometryData); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putUUID($this->uuid); $this->putString($this->skin->getSkinId()); diff --git a/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php b/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php index bc989f0d5b..e841fed934 100644 --- a/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php @@ -33,14 +33,14 @@ class PurchaseReceiptPacket extends DataPacket{ /** @var string[] */ public $entries = []; - protected function decodePayload(){ + protected function decodePayload() : void{ $count = $this->getUnsignedVarInt(); for($i = 0; $i < $count; ++$i){ $this->entries[] = $this->getString(); } } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putUnsignedVarInt(count($this->entries)); foreach($this->entries as $entry){ $this->putString($entry); diff --git a/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php b/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php index b4ef71361f..856b9b2118 100644 --- a/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php @@ -34,11 +34,11 @@ class RemoveEntityPacket extends DataPacket{ /** @var int */ public $entityUniqueId; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->entityUniqueId = $this->getEntityUniqueId(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityUniqueId($this->entityUniqueId); } diff --git a/src/pocketmine/network/mcpe/protocol/RemoveObjectivePacket.php b/src/pocketmine/network/mcpe/protocol/RemoveObjectivePacket.php index 6216c43ead..25dd8298be 100644 --- a/src/pocketmine/network/mcpe/protocol/RemoveObjectivePacket.php +++ b/src/pocketmine/network/mcpe/protocol/RemoveObjectivePacket.php @@ -33,11 +33,11 @@ class RemoveObjectivePacket extends DataPacket{ /** @var string */ public $objectiveName; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->objectiveName = $this->getString(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putString($this->objectiveName); } diff --git a/src/pocketmine/network/mcpe/protocol/RequestChunkRadiusPacket.php b/src/pocketmine/network/mcpe/protocol/RequestChunkRadiusPacket.php index 4c296c7574..3cb552b6bb 100644 --- a/src/pocketmine/network/mcpe/protocol/RequestChunkRadiusPacket.php +++ b/src/pocketmine/network/mcpe/protocol/RequestChunkRadiusPacket.php @@ -34,11 +34,11 @@ class RequestChunkRadiusPacket extends DataPacket{ /** @var int */ public $radius; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->radius = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putVarInt($this->radius); } diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php index c55f0a4734..6f51d6adf5 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php @@ -41,14 +41,14 @@ class ResourcePackChunkDataPacket extends DataPacket{ /** @var string */ public $data; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->packId = $this->getString(); $this->chunkIndex = $this->getLInt(); $this->progress = $this->getLLong(); $this->data = $this->get($this->getLInt()); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putString($this->packId); $this->putLInt($this->chunkIndex); $this->putLLong($this->progress); diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackChunkRequestPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackChunkRequestPacket.php index e095057969..4d17634ed9 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackChunkRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackChunkRequestPacket.php @@ -37,12 +37,12 @@ class ResourcePackChunkRequestPacket extends DataPacket{ /** @var int */ public $chunkIndex; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->packId = $this->getString(); $this->chunkIndex = $this->getLInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putString($this->packId); $this->putLInt($this->chunkIndex); } diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackClientResponsePacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackClientResponsePacket.php index a4dfba666f..1d1b2c3fa6 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackClientResponsePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackClientResponsePacket.php @@ -41,7 +41,7 @@ class ResourcePackClientResponsePacket extends DataPacket{ /** @var string[] */ public $packIds = []; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->status = $this->getByte(); $entryCount = $this->getLShort(); while($entryCount-- > 0){ @@ -49,7 +49,7 @@ class ResourcePackClientResponsePacket extends DataPacket{ } } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putByte($this->status); $this->putLShort(count($this->packIds)); foreach($this->packIds as $id){ diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php index a16bd9980a..777cc8e770 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php @@ -43,7 +43,7 @@ class ResourcePackDataInfoPacket extends DataPacket{ /** @var string */ public $sha256; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->packId = $this->getString(); $this->maxChunkSize = $this->getLInt(); $this->chunkCount = $this->getLInt(); @@ -51,7 +51,7 @@ class ResourcePackDataInfoPacket extends DataPacket{ $this->sha256 = $this->getString(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putString($this->packId); $this->putLInt($this->maxChunkSize); $this->putLInt($this->chunkCount); diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php index e8c1830daa..319528e441 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php @@ -41,7 +41,7 @@ class ResourcePackStackPacket extends DataPacket{ /** @var ResourcePack[] */ public $resourcePackStack = []; - protected function decodePayload(){ + protected function decodePayload() : void{ /*$this->mustAccept = $this->getBool(); $behaviorPackCount = $this->getUnsignedVarInt(); while($behaviorPackCount-- > 0){ @@ -58,7 +58,7 @@ class ResourcePackStackPacket extends DataPacket{ }*/ } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putBool($this->mustAccept); $this->putUnsignedVarInt(count($this->behaviorPackStack)); diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php index a01cb63844..e6af50106e 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php @@ -39,7 +39,7 @@ class ResourcePacksInfoPacket extends DataPacket{ /** @var ResourcePack[] */ public $resourcePackEntries = []; - protected function decodePayload(){ + protected function decodePayload() : void{ /*$this->mustAccept = $this->getBool(); $behaviorPackCount = $this->getLShort(); while($behaviorPackCount-- > 0){ @@ -60,7 +60,7 @@ class ResourcePacksInfoPacket extends DataPacket{ }*/ } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putBool($this->mustAccept); $this->putLShort(count($this->behaviorPackEntries)); diff --git a/src/pocketmine/network/mcpe/protocol/RespawnPacket.php b/src/pocketmine/network/mcpe/protocol/RespawnPacket.php index b13e7bcb7c..d6c088ba6d 100644 --- a/src/pocketmine/network/mcpe/protocol/RespawnPacket.php +++ b/src/pocketmine/network/mcpe/protocol/RespawnPacket.php @@ -35,11 +35,11 @@ class RespawnPacket extends DataPacket{ /** @var Vector3 */ public $position; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->position = $this->getVector3(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putVector3($this->position); } diff --git a/src/pocketmine/network/mcpe/protocol/RiderJumpPacket.php b/src/pocketmine/network/mcpe/protocol/RiderJumpPacket.php index 3ee83a606f..ca3e8df0f9 100644 --- a/src/pocketmine/network/mcpe/protocol/RiderJumpPacket.php +++ b/src/pocketmine/network/mcpe/protocol/RiderJumpPacket.php @@ -35,11 +35,11 @@ class RiderJumpPacket extends DataPacket{ /** @var int */ public $jumpStrength; //percentage - protected function decodePayload(){ + protected function decodePayload() : void{ $this->jumpStrength = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putVarInt($this->jumpStrength); } diff --git a/src/pocketmine/network/mcpe/protocol/ServerSettingsRequestPacket.php b/src/pocketmine/network/mcpe/protocol/ServerSettingsRequestPacket.php index 5404151cba..bccf9ed164 100644 --- a/src/pocketmine/network/mcpe/protocol/ServerSettingsRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ServerSettingsRequestPacket.php @@ -30,11 +30,11 @@ use pocketmine\network\mcpe\NetworkSession; class ServerSettingsRequestPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SERVER_SETTINGS_REQUEST_PACKET; - protected function decodePayload(){ + protected function decodePayload() : void{ //No payload } - protected function encodePayload(){ + protected function encodePayload() : void{ //No payload } diff --git a/src/pocketmine/network/mcpe/protocol/ServerSettingsResponsePacket.php b/src/pocketmine/network/mcpe/protocol/ServerSettingsResponsePacket.php index e8f997901d..c3a5b3fb20 100644 --- a/src/pocketmine/network/mcpe/protocol/ServerSettingsResponsePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ServerSettingsResponsePacket.php @@ -35,12 +35,12 @@ class ServerSettingsResponsePacket extends DataPacket{ /** @var string */ public $formData; //json - protected function decodePayload(){ + protected function decodePayload() : void{ $this->formId = $this->getUnsignedVarInt(); $this->formData = $this->getString(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putUnsignedVarInt($this->formId); $this->putString($this->formData); } diff --git a/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php b/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php index ee1f401522..b5a5defd94 100644 --- a/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php @@ -41,11 +41,11 @@ class ServerToClientHandshakePacket extends DataPacket{ return true; } - protected function decodePayload(){ + protected function decodePayload() : void{ $this->jwt = $this->getString(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putString($this->jwt); } diff --git a/src/pocketmine/network/mcpe/protocol/SetCommandsEnabledPacket.php b/src/pocketmine/network/mcpe/protocol/SetCommandsEnabledPacket.php index 0f3c87ce9c..82f28fc88a 100644 --- a/src/pocketmine/network/mcpe/protocol/SetCommandsEnabledPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetCommandsEnabledPacket.php @@ -34,11 +34,11 @@ class SetCommandsEnabledPacket extends DataPacket{ /** @var bool */ public $enabled; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->enabled = $this->getBool(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putBool($this->enabled); } diff --git a/src/pocketmine/network/mcpe/protocol/SetDefaultGameTypePacket.php b/src/pocketmine/network/mcpe/protocol/SetDefaultGameTypePacket.php index 3284704b78..a3adaa43fa 100644 --- a/src/pocketmine/network/mcpe/protocol/SetDefaultGameTypePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetDefaultGameTypePacket.php @@ -33,11 +33,11 @@ class SetDefaultGameTypePacket extends DataPacket{ /** @var int */ public $gamemode; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->gamemode = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putUnsignedVarInt($this->gamemode); } diff --git a/src/pocketmine/network/mcpe/protocol/SetDifficultyPacket.php b/src/pocketmine/network/mcpe/protocol/SetDifficultyPacket.php index c960e79507..a3f75035e5 100644 --- a/src/pocketmine/network/mcpe/protocol/SetDifficultyPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetDifficultyPacket.php @@ -34,11 +34,11 @@ class SetDifficultyPacket extends DataPacket{ /** @var int */ public $difficulty; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->difficulty = $this->getUnsignedVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putUnsignedVarInt($this->difficulty); } diff --git a/src/pocketmine/network/mcpe/protocol/SetDisplayObjectivePacket.php b/src/pocketmine/network/mcpe/protocol/SetDisplayObjectivePacket.php index a4b1aa54a0..534c66b01a 100644 --- a/src/pocketmine/network/mcpe/protocol/SetDisplayObjectivePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetDisplayObjectivePacket.php @@ -41,7 +41,7 @@ class SetDisplayObjectivePacket extends DataPacket{ /** @var int */ public $sortOrder; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->displaySlot = $this->getString(); $this->objectiveName = $this->getString(); $this->displayName = $this->getString(); @@ -49,7 +49,7 @@ class SetDisplayObjectivePacket extends DataPacket{ $this->sortOrder = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putString($this->displaySlot); $this->putString($this->objectiveName); $this->putString($this->displayName); diff --git a/src/pocketmine/network/mcpe/protocol/SetEntityDataPacket.php b/src/pocketmine/network/mcpe/protocol/SetEntityDataPacket.php index 678cfda618..48c483953f 100644 --- a/src/pocketmine/network/mcpe/protocol/SetEntityDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetEntityDataPacket.php @@ -36,12 +36,12 @@ class SetEntityDataPacket extends DataPacket{ /** @var array */ public $metadata; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->metadata = $this->getEntityMetadata(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityRuntimeId($this->entityRuntimeId); $this->putEntityMetadata($this->metadata); } diff --git a/src/pocketmine/network/mcpe/protocol/SetEntityLinkPacket.php b/src/pocketmine/network/mcpe/protocol/SetEntityLinkPacket.php index 63928b9b1d..4d695948ea 100644 --- a/src/pocketmine/network/mcpe/protocol/SetEntityLinkPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetEntityLinkPacket.php @@ -35,11 +35,11 @@ class SetEntityLinkPacket extends DataPacket{ /** @var EntityLink */ public $link; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->link = $this->getEntityLink(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityLink($this->link); } diff --git a/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php b/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php index 66b217552c..acecb51236 100644 --- a/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php @@ -37,12 +37,12 @@ class SetEntityMotionPacket extends DataPacket{ /** @var Vector3 */ public $motion; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->motion = $this->getVector3(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityRuntimeId($this->entityRuntimeId); $this->putVector3($this->motion); } diff --git a/src/pocketmine/network/mcpe/protocol/SetHealthPacket.php b/src/pocketmine/network/mcpe/protocol/SetHealthPacket.php index b87a0e9fb6..736f9deca1 100644 --- a/src/pocketmine/network/mcpe/protocol/SetHealthPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetHealthPacket.php @@ -34,11 +34,11 @@ class SetHealthPacket extends DataPacket{ /** @var int */ public $health; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->health = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putVarInt($this->health); } diff --git a/src/pocketmine/network/mcpe/protocol/SetLastHurtByPacket.php b/src/pocketmine/network/mcpe/protocol/SetLastHurtByPacket.php index b29b9ac2d9..25cc3d9f4d 100644 --- a/src/pocketmine/network/mcpe/protocol/SetLastHurtByPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetLastHurtByPacket.php @@ -33,11 +33,11 @@ class SetLastHurtByPacket extends DataPacket{ /** @var int */ public $entityTypeId; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->entityTypeId = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putVarInt($this->entityTypeId); } diff --git a/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php b/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php index 81a019eb5c..22e88ab1d9 100644 --- a/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php @@ -34,11 +34,11 @@ class SetPlayerGameTypePacket extends DataPacket{ /** @var int */ public $gamemode; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->gamemode = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putVarInt($this->gamemode); } diff --git a/src/pocketmine/network/mcpe/protocol/SetScorePacket.php b/src/pocketmine/network/mcpe/protocol/SetScorePacket.php index f1efb6579f..aa36a19f53 100644 --- a/src/pocketmine/network/mcpe/protocol/SetScorePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetScorePacket.php @@ -39,7 +39,7 @@ class SetScorePacket extends DataPacket{ /** @var ScorePacketEntry[] */ public $entries = []; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->type = $this->getByte(); for($i = 0, $i2 = $this->getUnsignedVarInt(); $i < $i2; ++$i){ $entry = new ScorePacketEntry(); @@ -49,7 +49,7 @@ class SetScorePacket extends DataPacket{ } } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putByte($this->type); $this->putUnsignedVarInt(count($this->entries)); foreach($this->entries as $entry){ diff --git a/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php b/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php index 5ba33933e6..1788ca16c0 100644 --- a/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php @@ -45,13 +45,13 @@ class SetSpawnPositionPacket extends DataPacket{ /** @var bool */ public $spawnForced; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->spawnType = $this->getVarInt(); $this->getBlockPosition($this->x, $this->y, $this->z); $this->spawnForced = $this->getBool(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putVarInt($this->spawnType); $this->putBlockPosition($this->x, $this->y, $this->z); $this->putBool($this->spawnForced); diff --git a/src/pocketmine/network/mcpe/protocol/SetTimePacket.php b/src/pocketmine/network/mcpe/protocol/SetTimePacket.php index 66a97fba82..4f72115e93 100644 --- a/src/pocketmine/network/mcpe/protocol/SetTimePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetTimePacket.php @@ -33,11 +33,11 @@ class SetTimePacket extends DataPacket{ /** @var int */ public $time; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->time = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putVarInt($this->time); } diff --git a/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php b/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php index 6065eacdc4..a819d03647 100644 --- a/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php @@ -50,7 +50,7 @@ class SetTitlePacket extends DataPacket{ /** @var int */ public $fadeOutTime = 0; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->type = $this->getVarInt(); $this->text = $this->getString(); $this->fadeInTime = $this->getVarInt(); @@ -58,7 +58,7 @@ class SetTitlePacket extends DataPacket{ $this->fadeOutTime = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putVarInt($this->type); $this->putString($this->text); $this->putVarInt($this->fadeInTime); diff --git a/src/pocketmine/network/mcpe/protocol/ShowCreditsPacket.php b/src/pocketmine/network/mcpe/protocol/ShowCreditsPacket.php index 6cc5a74439..15715e5b24 100644 --- a/src/pocketmine/network/mcpe/protocol/ShowCreditsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ShowCreditsPacket.php @@ -40,12 +40,12 @@ class ShowCreditsPacket extends DataPacket{ /** @var int */ public $status; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->playerEid = $this->getEntityRuntimeId(); $this->status = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityRuntimeId($this->playerEid); $this->putVarInt($this->status); } diff --git a/src/pocketmine/network/mcpe/protocol/ShowProfilePacket.php b/src/pocketmine/network/mcpe/protocol/ShowProfilePacket.php index 54f8cc1de8..4a7eaee19a 100644 --- a/src/pocketmine/network/mcpe/protocol/ShowProfilePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ShowProfilePacket.php @@ -33,11 +33,11 @@ class ShowProfilePacket extends DataPacket{ /** @var string */ public $xuid; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->xuid = $this->getString(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putString($this->xuid); } diff --git a/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php b/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php index a3f5a22c30..23ee620381 100644 --- a/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php @@ -35,12 +35,12 @@ class ShowStoreOfferPacket extends DataPacket{ /** @var bool */ public $showAll; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->offerId = $this->getString(); $this->showAll = $this->getBool(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putString($this->offerId); $this->putBool($this->showAll); } diff --git a/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php b/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php index 0792f199b1..b56e136954 100644 --- a/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php @@ -36,11 +36,11 @@ class SimpleEventPacket extends DataPacket{ /** @var int */ public $eventType; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->eventType = $this->getLShort(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putLShort($this->eventType); } diff --git a/src/pocketmine/network/mcpe/protocol/SpawnExperienceOrbPacket.php b/src/pocketmine/network/mcpe/protocol/SpawnExperienceOrbPacket.php index cacfc0dd69..628ef4a970 100644 --- a/src/pocketmine/network/mcpe/protocol/SpawnExperienceOrbPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SpawnExperienceOrbPacket.php @@ -37,12 +37,12 @@ class SpawnExperienceOrbPacket extends DataPacket{ /** @var int */ public $amount; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->position = $this->getVector3(); $this->amount = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putVector3($this->position); $this->putVarInt($this->amount); } diff --git a/src/pocketmine/network/mcpe/protocol/StartGamePacket.php b/src/pocketmine/network/mcpe/protocol/StartGamePacket.php index 0cea9e24e8..11d834f2c1 100644 --- a/src/pocketmine/network/mcpe/protocol/StartGamePacket.php +++ b/src/pocketmine/network/mcpe/protocol/StartGamePacket.php @@ -126,7 +126,7 @@ class StartGamePacket extends DataPacket{ /** @var int */ public $enchantmentSeed = 0; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->entityUniqueId = $this->getEntityUniqueId(); $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->playerGamemode = $this->getVarInt(); @@ -177,7 +177,7 @@ class StartGamePacket extends DataPacket{ $this->enchantmentSeed = $this->getVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityUniqueId($this->entityUniqueId); $this->putEntityRuntimeId($this->entityRuntimeId); $this->putVarInt($this->playerGamemode); diff --git a/src/pocketmine/network/mcpe/protocol/StopSoundPacket.php b/src/pocketmine/network/mcpe/protocol/StopSoundPacket.php index fc6dc5f3be..d48d4b96f8 100644 --- a/src/pocketmine/network/mcpe/protocol/StopSoundPacket.php +++ b/src/pocketmine/network/mcpe/protocol/StopSoundPacket.php @@ -37,12 +37,12 @@ class StopSoundPacket extends DataPacket{ /** @var bool */ public $stopAll; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->soundName = $this->getString(); $this->stopAll = $this->getBool(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putString($this->soundName); $this->putBool($this->stopAll); } diff --git a/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php b/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php index ef4febf1fc..cc409bfb34 100644 --- a/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php +++ b/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php @@ -30,11 +30,11 @@ use pocketmine\network\mcpe\NetworkSession; class StructureBlockUpdatePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::STRUCTURE_BLOCK_UPDATE_PACKET; - protected function decodePayload(){ + protected function decodePayload() : void{ //TODO } - protected function encodePayload(){ + protected function encodePayload() : void{ //TODO } diff --git a/src/pocketmine/network/mcpe/protocol/SubClientLoginPacket.php b/src/pocketmine/network/mcpe/protocol/SubClientLoginPacket.php index f699e0c6c2..5d1d72ab0f 100644 --- a/src/pocketmine/network/mcpe/protocol/SubClientLoginPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SubClientLoginPacket.php @@ -33,11 +33,11 @@ class SubClientLoginPacket extends DataPacket{ /** @var string */ public $connectionRequestData; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->connectionRequestData = $this->getString(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putString($this->connectionRequestData); } diff --git a/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php b/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php index 5fbe7a6be1..c0e66fa7d5 100644 --- a/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php @@ -36,11 +36,11 @@ class TakeItemEntityPacket extends DataPacket{ /** @var int */ public $eid; - protected function decodePayload(){ + protected function decodePayload() : void{ } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityRuntimeId($this->target); $this->putEntityRuntimeId($this->eid); } diff --git a/src/pocketmine/network/mcpe/protocol/TextPacket.php b/src/pocketmine/network/mcpe/protocol/TextPacket.php index cb69902758..532fd28e10 100644 --- a/src/pocketmine/network/mcpe/protocol/TextPacket.php +++ b/src/pocketmine/network/mcpe/protocol/TextPacket.php @@ -60,7 +60,7 @@ class TextPacket extends DataPacket{ /** @var string */ public $platformChatId = ""; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->type = $this->getByte(); $this->needsTranslation = $this->getBool(); switch($this->type){ @@ -92,7 +92,7 @@ class TextPacket extends DataPacket{ $this->platformChatId = $this->getString(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putByte($this->type); $this->putBool($this->needsTranslation); switch($this->type){ diff --git a/src/pocketmine/network/mcpe/protocol/TransferPacket.php b/src/pocketmine/network/mcpe/protocol/TransferPacket.php index e5729d1daf..1bf5270c22 100644 --- a/src/pocketmine/network/mcpe/protocol/TransferPacket.php +++ b/src/pocketmine/network/mcpe/protocol/TransferPacket.php @@ -35,12 +35,12 @@ class TransferPacket extends DataPacket{ /** @var int */ public $port = 19132; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->address = $this->getString(); $this->port = $this->getLShort(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putString($this->address); $this->putLShort($this->port); } diff --git a/src/pocketmine/network/mcpe/protocol/UnknownPacket.php b/src/pocketmine/network/mcpe/protocol/UnknownPacket.php index f27ef616e6..3acec2287d 100644 --- a/src/pocketmine/network/mcpe/protocol/UnknownPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UnknownPacket.php @@ -33,7 +33,7 @@ class UnknownPacket extends DataPacket{ /** @var string */ public $payload; - public function pid(){ + public function pid() : int{ if(strlen($this->payload ?? "") > 0){ return ord($this->payload{0}); } @@ -44,11 +44,11 @@ class UnknownPacket extends DataPacket{ return "unknown packet"; } - public function decode(){ + public function decode() : void{ $this->payload = $this->getRemaining(); } - public function encode(){ + public function encode() : void{ //Do not reset the buffer, this class does not have a valid NETWORK_ID constant. $this->put($this->payload); } diff --git a/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php index 5bf84a49c0..d8b6095575 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php @@ -37,12 +37,12 @@ class UpdateAttributesPacket extends DataPacket{ /** @var Attribute[] */ public $entries = []; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->entries = $this->getAttributeList(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityRuntimeId($this->entityRuntimeId); $this->putAttributeList(...$this->entries); } diff --git a/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php index e6e99cac74..ff27e23cf7 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php @@ -56,14 +56,14 @@ class UpdateBlockPacket extends DataPacket{ /** @var int */ public $dataLayerId = self::DATA_LAYER_NORMAL; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->getBlockPosition($this->x, $this->y, $this->z); $this->blockRuntimeId = $this->getUnsignedVarInt(); $this->flags = $this->getUnsignedVarInt(); $this->dataLayerId = $this->getUnsignedVarInt(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putBlockPosition($this->x, $this->y, $this->z); $this->putUnsignedVarInt($this->blockRuntimeId); $this->putUnsignedVarInt($this->flags); diff --git a/src/pocketmine/network/mcpe/protocol/UpdateBlockSyncedPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateBlockSyncedPacket.php index 5fce02e5c9..f99bb5731e 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateBlockSyncedPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateBlockSyncedPacket.php @@ -35,13 +35,13 @@ class UpdateBlockSyncedPacket extends UpdateBlockPacket{ /** @var int */ public $uvarint64_2 = 0; - protected function decodePayload(){ + protected function decodePayload() : void{ parent::decodePayload(); $this->entityUniqueId = $this->getUnsignedVarLong(); $this->uvarint64_2 = $this->getUnsignedVarLong(); } - protected function encodePayload(){ + protected function encodePayload() : void{ parent::encodePayload(); $this->putUnsignedVarLong($this->entityUniqueId); $this->putUnsignedVarLong($this->uvarint64_2); diff --git a/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php index b32d3eca71..7a79089186 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php @@ -41,7 +41,7 @@ class UpdateEquipPacket extends DataPacket{ /** @var string */ public $namedtag; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->windowId = $this->getByte(); $this->windowType = $this->getByte(); $this->unknownVarint = $this->getVarInt(); @@ -49,7 +49,7 @@ class UpdateEquipPacket extends DataPacket{ $this->namedtag = $this->getRemaining(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putByte($this->windowId); $this->putByte($this->windowType); $this->putVarInt($this->unknownVarint); diff --git a/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php b/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php index 08b5de26ee..a1c38553e7 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php @@ -54,7 +54,7 @@ class UpdateTradePacket extends DataPacket{ /** @var string */ public $offers; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->windowId = $this->getByte(); $this->windowType = $this->getByte(); $this->varint1 = $this->getVarInt(); @@ -66,7 +66,7 @@ class UpdateTradePacket extends DataPacket{ $this->offers = $this->getRemaining(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putByte($this->windowId); $this->putByte($this->windowType); $this->putVarInt($this->varint1); diff --git a/src/pocketmine/network/mcpe/protocol/WSConnectPacket.php b/src/pocketmine/network/mcpe/protocol/WSConnectPacket.php index 6489c0cba9..2514074717 100644 --- a/src/pocketmine/network/mcpe/protocol/WSConnectPacket.php +++ b/src/pocketmine/network/mcpe/protocol/WSConnectPacket.php @@ -33,11 +33,11 @@ class WSConnectPacket extends DataPacket{ /** @var string */ public $serverUri; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->serverUri = $this->getString(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putString($this->serverUri); } diff --git a/src/pocketmine/network/mcpe/protocol/types/EntityLink.php b/src/pocketmine/network/mcpe/protocol/types/EntityLink.php index 9a220fab15..c5386e682d 100644 --- a/src/pocketmine/network/mcpe/protocol/types/EntityLink.php +++ b/src/pocketmine/network/mcpe/protocol/types/EntityLink.php @@ -38,7 +38,7 @@ class EntityLink{ /** @var bool */ public $immediate; //for dismounting on mount death - public function __construct(int $fromEntityUniqueId = null, int $toEntityUniqueId = null, int $type = null, bool $immediate = false){ + public function __construct(?int $fromEntityUniqueId = null, ?int $toEntityUniqueId = null, ?int $type = null, bool $immediate = false){ $this->fromEntityUniqueId = $fromEntityUniqueId; $this->toEntityUniqueId = $toEntityUniqueId; $this->type = $type; diff --git a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php index c800c19fdc..027bd6e62a 100644 --- a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php +++ b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php @@ -94,7 +94,7 @@ class NetworkInventoryAction{ * @param InventoryTransactionPacket $packet * @return $this */ - public function read(InventoryTransactionPacket $packet){ + public function read(InventoryTransactionPacket $packet) : NetworkInventoryAction{ $this->sourceType = $packet->getUnsignedVarInt(); switch($this->sourceType){ @@ -129,7 +129,7 @@ class NetworkInventoryAction{ /** * @param InventoryTransactionPacket $packet */ - public function write(InventoryTransactionPacket $packet){ + public function write(InventoryTransactionPacket $packet) : void{ $packet->putUnsignedVarInt($this->sourceType); switch($this->sourceType){ @@ -156,7 +156,7 @@ class NetworkInventoryAction{ * * @return InventoryAction|null */ - public function createInventoryAction(Player $player){ + public function createInventoryAction(Player $player) : ?InventoryAction{ switch($this->sourceType){ case self::SOURCE_CONTAINER: $window = $player->getWindow($this->windowId); From 950465d283a219988c3358ded966b4b84bec6d31 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 5 Jul 2018 13:35:04 +0100 Subject: [PATCH 0011/3224] as always, missed one - I blame PhpStorm --- src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php b/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php index 06ae1feab1..94dc2e12be 100644 --- a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php @@ -118,7 +118,7 @@ class CraftingDataPacket extends DataPacket{ $this->getBool(); //cleanRecipes } - private static function writeEntry($entry, NetworkBinaryStream $stream){ + private static function writeEntry($entry, NetworkBinaryStream $stream) : int{ if($entry instanceof ShapelessRecipe){ return self::writeShapelessRecipe($entry, $stream); }elseif($entry instanceof ShapedRecipe){ From 2907de81ad3f329dd6fb2e0821b20683bde0aab4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 5 Jul 2018 13:36:23 +0100 Subject: [PATCH 0012/3224] Apply typehints to more general pocketmine\network namespace --- .../network/AdvancedSourceInterface.php | 8 +++---- .../network/CompressBatchedTask.php | 4 ++-- src/pocketmine/network/Network.php | 24 +++++++++---------- src/pocketmine/network/SourceInterface.php | 12 +++++----- .../mcpe/PlayerNetworkSessionAdapter.php | 2 +- .../network/mcpe/RakLibInterface.php | 24 +++++++++---------- .../network/mcpe/VerifyLoginTask.php | 4 ++-- src/pocketmine/network/query/QueryHandler.php | 6 ++--- src/pocketmine/network/rcon/RCON.php | 4 ++-- src/pocketmine/network/rcon/RCONInstance.php | 4 ++-- 10 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/pocketmine/network/AdvancedSourceInterface.php b/src/pocketmine/network/AdvancedSourceInterface.php index 3e58140f22..2ba728c317 100644 --- a/src/pocketmine/network/AdvancedSourceInterface.php +++ b/src/pocketmine/network/AdvancedSourceInterface.php @@ -32,23 +32,23 @@ interface AdvancedSourceInterface extends SourceInterface{ * @param string $address * @param int $timeout Seconds */ - public function blockAddress(string $address, int $timeout = 300); + public function blockAddress(string $address, int $timeout = 300) : void; /** * @param string $address */ - public function unblockAddress(string $address); + public function unblockAddress(string $address) : void; /** * @param Network $network */ - public function setNetwork(Network $network); + public function setNetwork(Network $network) : void; /** * @param string $address * @param int $port * @param string $payload */ - public function sendRawPacket(string $address, int $port, string $payload); + public function sendRawPacket(string $address, int $port, string $payload) : void; } diff --git a/src/pocketmine/network/CompressBatchedTask.php b/src/pocketmine/network/CompressBatchedTask.php index 9ddd7baaee..a8aa24a6b0 100644 --- a/src/pocketmine/network/CompressBatchedTask.php +++ b/src/pocketmine/network/CompressBatchedTask.php @@ -43,7 +43,7 @@ class CompressBatchedTask extends AsyncTask{ $this->storeLocal($targets); } - public function onRun(){ + public function onRun() : void{ $batch = new BatchPacket(); $batch->payload = $this->data; $this->data = null; @@ -54,7 +54,7 @@ class CompressBatchedTask extends AsyncTask{ $this->setResult($batch->buffer, false); } - public function onCompletion(Server $server){ + public function onCompletion(Server $server) : void{ $pk = new BatchPacket($this->getResult()); $pk->isEncoded = true; diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index 6edb9977fb..af907d77cd 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -58,20 +58,20 @@ class Network{ } - public function addStatistics($upload, $download){ + public function addStatistics(float $upload, float $download) : void{ $this->upload += $upload; $this->download += $download; } - public function getUpload(){ + public function getUpload() : float{ return $this->upload; } - public function getDownload(){ + public function getDownload() : float{ return $this->download; } - public function resetStatistics(){ + public function resetStatistics() : void{ $this->upload = 0; $this->download = 0; } @@ -83,7 +83,7 @@ class Network{ return $this->interfaces; } - public function processInterfaces(){ + public function processInterfaces() : void{ foreach($this->interfaces as $interface){ $this->processInterface($interface); } @@ -109,7 +109,7 @@ class Network{ /** * @param SourceInterface $interface */ - public function registerInterface(SourceInterface $interface){ + public function registerInterface(SourceInterface $interface) : void{ $this->server->getPluginManager()->callEvent($ev = new NetworkInterfaceRegisterEvent($interface)); if(!$ev->isCancelled()){ $interface->start(); @@ -125,7 +125,7 @@ class Network{ /** * @param SourceInterface $interface */ - public function unregisterInterface(SourceInterface $interface){ + public function unregisterInterface(SourceInterface $interface) : void{ $this->server->getPluginManager()->callEvent(new NetworkInterfaceUnregisterEvent($interface)); unset($this->interfaces[$hash = spl_object_hash($interface)], $this->advancedInterfaces[$hash]); } @@ -135,7 +135,7 @@ class Network{ * * @param string $name */ - public function setName(string $name){ + public function setName(string $name) : void{ $this->name = $name; foreach($this->interfaces as $interface){ $interface->setName($this->name); @@ -149,7 +149,7 @@ class Network{ return $this->name; } - public function updateName(){ + public function updateName() : void{ foreach($this->interfaces as $interface){ $interface->setName($this->name); } @@ -167,7 +167,7 @@ class Network{ * @param int $port * @param string $payload */ - public function sendPacket(string $address, int $port, string $payload){ + public function sendPacket(string $address, int $port, string $payload) : void{ foreach($this->advancedInterfaces as $interface){ $interface->sendRawPacket($address, $port, $payload); } @@ -179,13 +179,13 @@ class Network{ * @param string $address * @param int $timeout */ - public function blockAddress(string $address, int $timeout = 300){ + public function blockAddress(string $address, int $timeout = 300) : void{ foreach($this->advancedInterfaces as $interface){ $interface->blockAddress($address, $timeout); } } - public function unblockAddress(string $address){ + public function unblockAddress(string $address) : void{ foreach($this->advancedInterfaces as $interface){ $interface->unblockAddress($address); } diff --git a/src/pocketmine/network/SourceInterface.php b/src/pocketmine/network/SourceInterface.php index e5a6b679a9..e6676470cd 100644 --- a/src/pocketmine/network/SourceInterface.php +++ b/src/pocketmine/network/SourceInterface.php @@ -37,7 +37,7 @@ interface SourceInterface{ /** * Performs actions needed to start the interface after it is registered. */ - public function start(); + public function start() : void; /** * Sends a DataPacket to the interface, returns an unique identifier for the packet if $needACK is true @@ -49,7 +49,7 @@ interface SourceInterface{ * * @return int|null */ - public function putPacket(Player $player, DataPacket $packet, bool $needACK = false, bool $immediate = true); + public function putPacket(Player $player, DataPacket $packet, bool $needACK = false, bool $immediate = true) : ?int; /** * Terminates the connection @@ -57,20 +57,20 @@ interface SourceInterface{ * @param Player $player * @param string $reason */ - public function close(Player $player, string $reason = "unknown reason"); + public function close(Player $player, string $reason = "unknown reason") : void; /** * @param string $name */ - public function setName(string $name); + public function setName(string $name) : void; /** * Called every tick to process events on the interface. */ public function process() : void; - public function shutdown(); + public function shutdown() : void; - public function emergencyShutdown(); + public function emergencyShutdown() : void; } diff --git a/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php b/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php index 385a645403..2f651a583a 100644 --- a/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php +++ b/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php @@ -78,7 +78,7 @@ class PlayerNetworkSessionAdapter extends NetworkSession{ $this->player = $player; } - public function handleDataPacket(DataPacket $packet){ + public function handleDataPacket(DataPacket $packet) : void{ $timings = Timings::getReceiveDataPacketTimings($packet); $timings->startTiming(); diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index bd39983792..2f180ddf28 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -91,11 +91,11 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{ $this->interface = new ServerHandler($this->rakLib, $this); } - public function start(){ + public function start() : void{ $this->rakLib->start(PTHREADS_INHERIT_CONSTANTS | PTHREADS_INHERIT_INI); //HACK: MainLogger needs INI and constants } - public function setNetwork(Network $network){ + public function setNetwork(Network $network) : void{ $this->network = $network; } @@ -117,7 +117,7 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{ } } - public function close(Player $player, string $reason = "unknown reason"){ + public function close(Player $player, string $reason = "unknown reason") : void{ if(isset($this->identifiers[$h = spl_object_hash($player)])){ unset($this->players[$this->identifiers[$h]]); unset($this->identifiersACK[$this->identifiers[$h]]); @@ -126,12 +126,12 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{ } } - public function shutdown(){ + public function shutdown() : void{ $this->server->getTickSleeper()->removeNotifier($this->sleeper); $this->interface->shutdown(); } - public function emergencyShutdown(){ + public function emergencyShutdown() : void{ $this->server->getTickSleeper()->removeNotifier($this->sleeper); $this->interface->emergencyShutdown(); } @@ -167,11 +167,11 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{ } } - public function blockAddress(string $address, int $timeout = 300){ + public function blockAddress(string $address, int $timeout = 300) : void{ $this->interface->blockAddress($address, $timeout); } - public function unblockAddress(string $address){ + public function unblockAddress(string $address) : void{ $this->interface->unblockAddress($address); } @@ -179,7 +179,7 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{ $this->server->handlePacket($this, $address, $port, $payload); } - public function sendRawPacket(string $address, int $port, string $payload){ + public function sendRawPacket(string $address, int $port, string $payload) : void{ $this->interface->sendRaw($address, $port, $payload); } @@ -187,7 +187,7 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{ } - public function setName(string $name){ + public function setName(string $name) : void{ $info = $this->server->getQueryInformation(); $this->interface->sendOption("name", implode(";", @@ -205,8 +205,8 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{ ); } - public function setPortCheck($name){ - $this->interface->sendOption("portChecking", (bool) $name); + public function setPortCheck(bool $name) : void{ + $this->interface->sendOption("portChecking", $name); } public function handleOption(string $option, string $value) : void{ @@ -216,7 +216,7 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{ } } - public function putPacket(Player $player, DataPacket $packet, bool $needACK = false, bool $immediate = true){ + public function putPacket(Player $player, DataPacket $packet, bool $needACK = false, bool $immediate = true) : ?int{ if(isset($this->identifiers[$h = spl_object_hash($player)])){ $identifier = $this->identifiers[$h]; if(!$packet->isEncoded){ diff --git a/src/pocketmine/network/mcpe/VerifyLoginTask.php b/src/pocketmine/network/mcpe/VerifyLoginTask.php index cf4f5d3746..a509e35ef3 100644 --- a/src/pocketmine/network/mcpe/VerifyLoginTask.php +++ b/src/pocketmine/network/mcpe/VerifyLoginTask.php @@ -55,7 +55,7 @@ class VerifyLoginTask extends AsyncTask{ $this->packet = $packet; } - public function onRun(){ + public function onRun() : void{ $packet = $this->packet; //Get it in a local variable to make sure it stays unserialized try{ @@ -142,7 +142,7 @@ class VerifyLoginTask extends AsyncTask{ $currentPublicKey = $claims["identityPublicKey"] ?? null; //if there are further links, the next link should be signed with this } - public function onCompletion(Server $server){ + public function onCompletion(Server $server) : void{ /** @var Player $player */ $player = $this->fetchLocal(); if($player->isClosed()){ diff --git a/src/pocketmine/network/query/QueryHandler.php b/src/pocketmine/network/query/QueryHandler.php index 7c67700971..1f238962a9 100644 --- a/src/pocketmine/network/query/QueryHandler.php +++ b/src/pocketmine/network/query/QueryHandler.php @@ -58,14 +58,14 @@ class QueryHandler{ $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.server.query.running", [$addr, $port])); } - public function regenerateInfo(){ + public function regenerateInfo() : void{ $ev = $this->server->getQueryInformation(); $this->longData = $ev->getLongQuery(); $this->shortData = $ev->getShortQuery(); $this->timeout = microtime(true) + $ev->getTimeout(); } - public function regenerateToken(){ + public function regenerateToken() : void{ $this->lastToken = $this->token; $this->token = random_bytes(16); } @@ -74,7 +74,7 @@ class QueryHandler{ return Binary::readInt(substr(hash("sha512", $salt . ":" . $token, true), 7, 4)); } - public function handle(AdvancedSourceInterface $interface, string $address, int $port, string $packet){ + public function handle(AdvancedSourceInterface $interface, string $address, int $port, string $packet) : void{ $offset = 2; $packetType = ord($packet{$offset++}); $sessionID = Binary::readInt(substr($packet, $offset, 4)); diff --git a/src/pocketmine/network/rcon/RCON.php b/src/pocketmine/network/rcon/RCON.php index 6240457898..cf57cd1067 100644 --- a/src/pocketmine/network/rcon/RCON.php +++ b/src/pocketmine/network/rcon/RCON.php @@ -82,7 +82,7 @@ class RCON{ $this->server->getLogger()->info("RCON running on $addr:$port"); } - public function stop(){ + public function stop() : void{ $this->instance->close(); socket_write($this->ipcMainSocket, "\x00"); //make select() return Server::microSleep(50000); @@ -93,7 +93,7 @@ class RCON{ @socket_close($this->ipcThreadSocket); } - public function check(){ + public function check() : void{ $response = new RemoteConsoleCommandSender(); $command = $this->instance->cmd; diff --git a/src/pocketmine/network/rcon/RCONInstance.php b/src/pocketmine/network/rcon/RCONInstance.php index d1e98da2ef..47790e4e6e 100644 --- a/src/pocketmine/network/rcon/RCONInstance.php +++ b/src/pocketmine/network/rcon/RCONInstance.php @@ -102,11 +102,11 @@ class RCONInstance extends Thread{ return true; } - public function close(){ + public function close() : void{ $this->stop = true; } - public function run(){ + public function run() : void{ $this->registerClassLoader(); /** @var resource[] $clients */ From 120eb8e362d7e0a28922dcb4d3520117f15188c5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 5 Jul 2018 13:38:33 +0100 Subject: [PATCH 0013/3224] CompressBatchedTask: move to pocketmine\network\mcpe namespace --- src/pocketmine/Server.php | 2 +- src/pocketmine/network/{ => mcpe}/CompressBatchedTask.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/pocketmine/network/{ => mcpe}/CompressBatchedTask.php (97%) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index d8c2fff8e3..f49701089d 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -69,7 +69,7 @@ use pocketmine\nbt\tag\LongTag; use pocketmine\nbt\tag\ShortTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\AdvancedSourceInterface; -use pocketmine\network\CompressBatchedTask; +use pocketmine\network\mcpe\CompressBatchedTask; use pocketmine\network\mcpe\protocol\BatchPacket; use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket; diff --git a/src/pocketmine/network/CompressBatchedTask.php b/src/pocketmine/network/mcpe/CompressBatchedTask.php similarity index 97% rename from src/pocketmine/network/CompressBatchedTask.php rename to src/pocketmine/network/mcpe/CompressBatchedTask.php index a8aa24a6b0..420b3fc67f 100644 --- a/src/pocketmine/network/CompressBatchedTask.php +++ b/src/pocketmine/network/mcpe/CompressBatchedTask.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network; +namespace pocketmine\network\mcpe; use pocketmine\network\mcpe\protocol\BatchPacket; use pocketmine\Player; From 78d27dc3e4f8f075a2581483b3c0c2d03fa351de Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 7 Jul 2018 19:34:11 +0100 Subject: [PATCH 0014/3224] Move ChunkRequestTask to pocketmine\network\mcpe namespace it has a lot to do with network and little to do with world I/O (load/save). --- src/pocketmine/level/Level.php | 2 +- .../{level/format/io => network/mcpe}/ChunkRequestTask.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/pocketmine/{level/format/io => network/mcpe}/ChunkRequestTask.php (98%) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 05d0ac8ef9..15536b5ef5 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -48,7 +48,6 @@ use pocketmine\level\format\Chunk; use pocketmine\level\format\ChunkException; use pocketmine\level\format\EmptySubChunk; use pocketmine\level\format\io\BaseLevelProvider; -use pocketmine\level\format\io\ChunkRequestTask; use pocketmine\level\format\io\LevelProvider; use pocketmine\level\generator\Generator; use pocketmine\level\generator\GeneratorManager; @@ -69,6 +68,7 @@ use pocketmine\metadata\Metadatable; use pocketmine\metadata\MetadataValue; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; +use pocketmine\network\mcpe\ChunkRequestTask; use pocketmine\network\mcpe\protocol\BatchPacket; use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/format/io/ChunkRequestTask.php b/src/pocketmine/network/mcpe/ChunkRequestTask.php similarity index 98% rename from src/pocketmine/level/format/io/ChunkRequestTask.php rename to src/pocketmine/network/mcpe/ChunkRequestTask.php index ef451e4b59..6fb064b940 100644 --- a/src/pocketmine/level/format/io/ChunkRequestTask.php +++ b/src/pocketmine/network/mcpe/ChunkRequestTask.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\format\io; +namespace pocketmine\network\mcpe; use pocketmine\level\format\Chunk; use pocketmine\level\Level; From 258b4f9dde3431366320940d4aeb3d1dca692912 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 7 Jul 2018 19:35:40 +0100 Subject: [PATCH 0015/3224] ChunkRequestTask: add docs and typehints --- src/pocketmine/network/mcpe/ChunkRequestTask.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/network/mcpe/ChunkRequestTask.php b/src/pocketmine/network/mcpe/ChunkRequestTask.php index 6fb064b940..f28dc22f9e 100644 --- a/src/pocketmine/network/mcpe/ChunkRequestTask.php +++ b/src/pocketmine/network/mcpe/ChunkRequestTask.php @@ -32,15 +32,17 @@ use pocketmine\Server; use pocketmine\tile\Spawnable; class ChunkRequestTask extends AsyncTask{ - + /** @var int */ protected $levelId; - + /** @var string */ protected $chunk; + /** @var int */ protected $chunkX; + /** @var int */ protected $chunkZ; - + /** @var string */ protected $tiles; - + /** @var int */ protected $compressionLevel; public function __construct(Level $level, int $chunkX, int $chunkZ, Chunk $chunk){ @@ -62,7 +64,7 @@ class ChunkRequestTask extends AsyncTask{ $this->tiles = $tiles; } - public function onRun(){ + public function onRun() : void{ $chunk = Chunk::fastDeserialize($this->chunk); $pk = new FullChunkDataPacket(); @@ -78,7 +80,7 @@ class ChunkRequestTask extends AsyncTask{ $this->setResult($batch->buffer, false); } - public function onCompletion(Server $server){ + public function onCompletion(Server $server) : void{ $level = $server->getLevel($this->levelId); if($level instanceof Level){ if($this->hasResult()){ From bc9a387b0ba74687a9932a9ba00a44e36bb06630 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 17 Jul 2018 18:46:27 +0100 Subject: [PATCH 0016/3224] Fixed merge error --- .../network/mcpe/protocol/MoveEntityDeltaPacket.php | 4 ++-- .../mcpe/protocol/SetLocalPlayerAsInitializedPacket.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/MoveEntityDeltaPacket.php b/src/pocketmine/network/mcpe/protocol/MoveEntityDeltaPacket.php index 53fc8f77c5..134fb82c5e 100644 --- a/src/pocketmine/network/mcpe/protocol/MoveEntityDeltaPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MoveEntityDeltaPacket.php @@ -66,7 +66,7 @@ class MoveEntityDeltaPacket extends DataPacket{ return 0.0; } - protected function decodePayload(){ + protected function decodePayload() : void{ $this->flags = $this->getByte(); $this->xDiff = $this->maybeReadCoord(self::FLAG_HAS_X); $this->yDiff = $this->maybeReadCoord(self::FLAG_HAS_Y); @@ -88,7 +88,7 @@ class MoveEntityDeltaPacket extends DataPacket{ } } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putByte($this->flags); $this->maybeWriteCoord(self::FLAG_HAS_X, $this->xDiff); $this->maybeWriteCoord(self::FLAG_HAS_Y, $this->yDiff); diff --git a/src/pocketmine/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php b/src/pocketmine/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php index 12918f114c..46f4a00bc4 100644 --- a/src/pocketmine/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php @@ -33,11 +33,11 @@ class SetLocalPlayerAsInitializedPacket extends DataPacket{ /** @var int */ public $entityRuntimeId; - protected function decodePayload(){ + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); } - protected function encodePayload(){ + protected function encodePayload() : void{ $this->putEntityRuntimeId($this->entityRuntimeId); } From 965f0d670d425b30a83231ad858d0cf2df7911fe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 18 Jul 2018 11:01:16 +0100 Subject: [PATCH 0017/3224] Improve documentation of SourceInterface and AdvancedSourceInterface --- src/pocketmine/network/AdvancedSourceInterface.php | 10 ++++++++++ src/pocketmine/network/SourceInterface.php | 8 +++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/network/AdvancedSourceInterface.php b/src/pocketmine/network/AdvancedSourceInterface.php index 2ba728c317..94b3c6e5d5 100644 --- a/src/pocketmine/network/AdvancedSourceInterface.php +++ b/src/pocketmine/network/AdvancedSourceInterface.php @@ -26,15 +26,23 @@ declare(strict_types=1); */ namespace pocketmine\network; +/** + * Advanced network interfaces have some additional capabilities, such as being able to ban addresses and process raw + * packets. + */ interface AdvancedSourceInterface extends SourceInterface{ /** + * Prevents packets received from the IP address getting processed for the given timeout. + * * @param string $address * @param int $timeout Seconds */ public function blockAddress(string $address, int $timeout = 300) : void; /** + * Unblocks a previously-blocked address. + * * @param string $address */ public function unblockAddress(string $address) : void; @@ -45,6 +53,8 @@ interface AdvancedSourceInterface extends SourceInterface{ public function setNetwork(Network $network) : void; /** + * Sends a raw payload to the network interface, bypassing any sessions. + * * @param string $address * @param int $port * @param string $payload diff --git a/src/pocketmine/network/SourceInterface.php b/src/pocketmine/network/SourceInterface.php index e6676470cd..5db9c9f17b 100644 --- a/src/pocketmine/network/SourceInterface.php +++ b/src/pocketmine/network/SourceInterface.php @@ -30,7 +30,7 @@ use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\Player; /** - * Classes that implement this interface will be able to be attached to players + * Network interfaces are transport layers which can be used to transmit packets between the server and clients. */ interface SourceInterface{ @@ -69,8 +69,14 @@ interface SourceInterface{ */ public function process() : void; + /** + * Gracefully shuts down the network interface. + */ public function shutdown() : void; + /** + * Shuts down the network interface in an emergency situation, such as due to a crash. + */ public function emergencyShutdown() : void; } From 4d1e2d1b3a52dc70cd78404b332bf59bfdcdbbd5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 18 Jul 2018 11:03:21 +0100 Subject: [PATCH 0018/3224] Rename SourceInterface -> NetworkInterface SourceInterface doesn't make sense really... --- src/pocketmine/Player.php | 12 +++++------ src/pocketmine/Server.php | 12 +++++------ .../event/player/PlayerCreationEvent.php | 20 +++++++++---------- .../server/NetworkInterfaceCrashEvent.php | 4 ++-- .../event/server/NetworkInterfaceEvent.php | 12 +++++------ ...rface.php => AdvancedNetworkInterface.php} | 2 +- src/pocketmine/network/Network.php | 18 ++++++++--------- ...urceInterface.php => NetworkInterface.php} | 2 +- .../network/mcpe/RakLibInterface.php | 4 ++-- src/pocketmine/network/query/QueryHandler.php | 4 ++-- 10 files changed, 45 insertions(+), 45 deletions(-) rename src/pocketmine/network/{AdvancedSourceInterface.php => AdvancedNetworkInterface.php} (96%) rename src/pocketmine/network/{SourceInterface.php => NetworkInterface.php} (98%) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 58f03b5f21..4c6c49ca46 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -144,7 +144,7 @@ use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; use pocketmine\network\mcpe\VerifyLoginTask; -use pocketmine\network\SourceInterface; +use pocketmine\network\NetworkInterface; use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissionAttachment; use pocketmine\permission\PermissionAttachmentInfo; @@ -186,7 +186,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } - /** @var SourceInterface */ + /** @var NetworkInterface */ protected $interface; /** @@ -705,11 +705,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } /** - * @param SourceInterface $interface - * @param string $ip - * @param int $port + * @param NetworkInterface $interface + * @param string $ip + * @param int $port */ - public function __construct(SourceInterface $interface, string $ip, int $port){ + public function __construct(NetworkInterface $interface, string $ip, int $port){ $this->interface = $interface; $this->perm = new PermissibleBase($this); $this->namedtag = new CompoundTag(); diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index cee185ba24..3e7a46c644 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -68,7 +68,7 @@ use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\LongTag; use pocketmine\nbt\tag\ShortTag; use pocketmine\nbt\tag\StringTag; -use pocketmine\network\AdvancedSourceInterface; +use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\mcpe\CompressBatchedTask; use pocketmine\network\mcpe\protocol\BatchPacket; use pocketmine\network\mcpe\protocol\DataPacket; @@ -2459,14 +2459,14 @@ class Server{ } /** - * @param AdvancedSourceInterface $interface - * @param string $address - * @param int $port - * @param string $payload + * @param AdvancedNetworkInterface $interface + * @param string $address + * @param int $port + * @param string $payload * * TODO: move this to Network */ - public function handlePacket(AdvancedSourceInterface $interface, string $address, int $port, string $payload){ + public function handlePacket(AdvancedNetworkInterface $interface, string $address, int $port, string $payload){ try{ if(strlen($payload) > 2 and substr($payload, 0, 2) === "\xfe\xfd" and $this->queryHandler instanceof QueryHandler){ $this->queryHandler->handle($interface, $address, $port, $payload); diff --git a/src/pocketmine/event/player/PlayerCreationEvent.php b/src/pocketmine/event/player/PlayerCreationEvent.php index 1f3c406f16..a7485a21b4 100644 --- a/src/pocketmine/event/player/PlayerCreationEvent.php +++ b/src/pocketmine/event/player/PlayerCreationEvent.php @@ -24,14 +24,14 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Event; -use pocketmine\network\SourceInterface; +use pocketmine\network\NetworkInterface; use pocketmine\Player; /** * Allows the creation of players overriding the base Player class */ class PlayerCreationEvent extends Event{ - /** @var SourceInterface */ + /** @var NetworkInterface */ private $interface; /** @var string */ private $address; @@ -44,13 +44,13 @@ class PlayerCreationEvent extends Event{ private $playerClass; /** - * @param SourceInterface $interface - * @param Player::class $baseClass - * @param Player::class $playerClass - * @param string $address - * @param int $port + * @param NetworkInterface $interface + * @param Player::class $baseClass + * @param Player::class $playerClass + * @param string $address + * @param int $port */ - public function __construct(SourceInterface $interface, $baseClass, $playerClass, string $address, int $port){ + public function __construct(NetworkInterface $interface, $baseClass, $playerClass, string $address, int $port){ $this->interface = $interface; $this->address = $address; $this->port = $port; @@ -69,9 +69,9 @@ class PlayerCreationEvent extends Event{ } /** - * @return SourceInterface + * @return NetworkInterface */ - public function getInterface() : SourceInterface{ + public function getInterface() : NetworkInterface{ return $this->interface; } diff --git a/src/pocketmine/event/server/NetworkInterfaceCrashEvent.php b/src/pocketmine/event/server/NetworkInterfaceCrashEvent.php index 4d83965799..f0d109427a 100644 --- a/src/pocketmine/event/server/NetworkInterfaceCrashEvent.php +++ b/src/pocketmine/event/server/NetworkInterfaceCrashEvent.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\event\server; -use pocketmine\network\SourceInterface; +use pocketmine\network\NetworkInterface; /** * Called when a network interface crashes, with relevant crash information. @@ -34,7 +34,7 @@ class NetworkInterfaceCrashEvent extends NetworkInterfaceEvent{ */ private $exception; - public function __construct(SourceInterface $interface, \Throwable $throwable){ + public function __construct(NetworkInterface $interface, \Throwable $throwable){ parent::__construct($interface); $this->exception = $throwable; } diff --git a/src/pocketmine/event/server/NetworkInterfaceEvent.php b/src/pocketmine/event/server/NetworkInterfaceEvent.php index 6269394c0f..f6ed969c64 100644 --- a/src/pocketmine/event/server/NetworkInterfaceEvent.php +++ b/src/pocketmine/event/server/NetworkInterfaceEvent.php @@ -23,23 +23,23 @@ declare(strict_types=1); namespace pocketmine\event\server; -use pocketmine\network\SourceInterface; +use pocketmine\network\NetworkInterface; class NetworkInterfaceEvent extends ServerEvent{ - /** @var SourceInterface */ + /** @var NetworkInterface */ protected $interface; /** - * @param SourceInterface $interface + * @param NetworkInterface $interface */ - public function __construct(SourceInterface $interface){ + public function __construct(NetworkInterface $interface){ $this->interface = $interface; } /** - * @return SourceInterface + * @return NetworkInterface */ - public function getInterface() : SourceInterface{ + public function getInterface() : NetworkInterface{ return $this->interface; } } diff --git a/src/pocketmine/network/AdvancedSourceInterface.php b/src/pocketmine/network/AdvancedNetworkInterface.php similarity index 96% rename from src/pocketmine/network/AdvancedSourceInterface.php rename to src/pocketmine/network/AdvancedNetworkInterface.php index 94b3c6e5d5..85afc739e5 100644 --- a/src/pocketmine/network/AdvancedSourceInterface.php +++ b/src/pocketmine/network/AdvancedNetworkInterface.php @@ -30,7 +30,7 @@ namespace pocketmine\network; * Advanced network interfaces have some additional capabilities, such as being able to ban addresses and process raw * packets. */ -interface AdvancedSourceInterface extends SourceInterface{ +interface AdvancedNetworkInterface extends NetworkInterface{ /** * Prevents packets received from the IP address getting processed for the given timeout. diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index af907d77cd..0b315faab3 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -39,10 +39,10 @@ class Network{ /** @var Server */ private $server; - /** @var SourceInterface[] */ + /** @var NetworkInterface[] */ private $interfaces = []; - /** @var AdvancedSourceInterface[] */ + /** @var AdvancedNetworkInterface[] */ private $advancedInterfaces = []; private $upload = 0; @@ -77,7 +77,7 @@ class Network{ } /** - * @return SourceInterface[] + * @return NetworkInterface[] */ public function getInterfaces() : array{ return $this->interfaces; @@ -89,7 +89,7 @@ class Network{ } } - public function processInterface(SourceInterface $interface) : void{ + public function processInterface(NetworkInterface $interface) : void{ try{ $interface->process(); }catch(\Throwable $e){ @@ -107,14 +107,14 @@ class Network{ } /** - * @param SourceInterface $interface + * @param NetworkInterface $interface */ - public function registerInterface(SourceInterface $interface) : void{ + public function registerInterface(NetworkInterface $interface) : void{ $this->server->getPluginManager()->callEvent($ev = new NetworkInterfaceRegisterEvent($interface)); if(!$ev->isCancelled()){ $interface->start(); $this->interfaces[$hash = spl_object_hash($interface)] = $interface; - if($interface instanceof AdvancedSourceInterface){ + if($interface instanceof AdvancedNetworkInterface){ $this->advancedInterfaces[$hash] = $interface; $interface->setNetwork($this); } @@ -123,9 +123,9 @@ class Network{ } /** - * @param SourceInterface $interface + * @param NetworkInterface $interface */ - public function unregisterInterface(SourceInterface $interface) : void{ + public function unregisterInterface(NetworkInterface $interface) : void{ $this->server->getPluginManager()->callEvent(new NetworkInterfaceUnregisterEvent($interface)); unset($this->interfaces[$hash = spl_object_hash($interface)], $this->advancedInterfaces[$hash]); } diff --git a/src/pocketmine/network/SourceInterface.php b/src/pocketmine/network/NetworkInterface.php similarity index 98% rename from src/pocketmine/network/SourceInterface.php rename to src/pocketmine/network/NetworkInterface.php index 5db9c9f17b..0818234fcb 100644 --- a/src/pocketmine/network/SourceInterface.php +++ b/src/pocketmine/network/NetworkInterface.php @@ -32,7 +32,7 @@ use pocketmine\Player; /** * Network interfaces are transport layers which can be used to transmit packets between the server and clients. */ -interface SourceInterface{ +interface NetworkInterface{ /** * Performs actions needed to start the interface after it is registered. diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 2f180ddf28..08c46ee85d 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; use pocketmine\event\player\PlayerCreationEvent; -use pocketmine\network\AdvancedSourceInterface; +use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\mcpe\protocol\BatchPacket; use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\PacketPool; @@ -41,7 +41,7 @@ use raklib\server\ServerHandler; use raklib\server\ServerInstance; use raklib\utils\InternetAddress; -class RakLibInterface implements ServerInstance, AdvancedSourceInterface{ +class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ /** * Sometimes this gets changed when the MCPE-layer protocol gets broken to the point where old and new can't * communicate. It's important that we check this to avoid catastrophes. diff --git a/src/pocketmine/network/query/QueryHandler.php b/src/pocketmine/network/query/QueryHandler.php index 4279529941..2a64c5804d 100644 --- a/src/pocketmine/network/query/QueryHandler.php +++ b/src/pocketmine/network/query/QueryHandler.php @@ -27,7 +27,7 @@ declare(strict_types=1); */ namespace pocketmine\network\query; -use pocketmine\network\AdvancedSourceInterface; +use pocketmine\network\AdvancedNetworkInterface; use pocketmine\Server; use pocketmine\utils\Binary; @@ -79,7 +79,7 @@ class QueryHandler{ return Binary::readInt(substr(hash("sha512", $salt . ":" . $token, true), 7, 4)); } - public function handle(AdvancedSourceInterface $interface, string $address, int $port, string $packet) : void{ + public function handle(AdvancedNetworkInterface $interface, string $address, int $port, string $packet) : void{ $offset = 2; $packetType = ord($packet{$offset++}); $sessionID = Binary::readInt(substr($packet, $offset, 4)); From 36e197e2a9a515f7f353426e168327e4c563a1cc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 18 Jul 2018 12:48:58 +0100 Subject: [PATCH 0019/3224] Move more session logic out of Player --- src/pocketmine/Player.php | 72 +------------------ .../mcpe/PlayerNetworkSessionAdapter.php | 35 ++++++++- 2 files changed, 37 insertions(+), 70 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 4c6c49ca46..3b1f615722 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -67,7 +67,6 @@ use pocketmine\event\player\PlayerToggleFlightEvent; use pocketmine\event\player\PlayerToggleSneakEvent; use pocketmine\event\player\PlayerToggleSprintEvent; use pocketmine\event\player\PlayerTransferEvent; -use pocketmine\event\server\DataPacketSendEvent; use pocketmine\inventory\CraftingGrid; use pocketmine\inventory\Inventory; use pocketmine\inventory\PlayerCursorInventory; @@ -108,7 +107,6 @@ use pocketmine\network\mcpe\protocol\BookEditPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; use pocketmine\network\mcpe\protocol\ContainerClosePacket; use pocketmine\network\mcpe\protocol\DataPacket; -use pocketmine\network\mcpe\protocol\DisconnectPacket; use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\InteractPacket; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; @@ -185,10 +183,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return $lname !== "rcon" and $lname !== "console" and $len >= 1 and $len <= 16 and preg_match("/[^A-Za-z0-9_ ]/", $name) === 0; } - - /** @var NetworkInterface */ - protected $interface; - /** * @var PlayerNetworkSessionAdapter * TODO: remove this once player and network are divorced properly @@ -203,12 +197,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ /** @var int */ protected $port; - /** @var bool[] */ - private $needACK = []; - - /** @var DataPacket[] */ - private $batchedPackets = []; - /** * @var int * Last measurement of player's latency in milliseconds. @@ -710,7 +698,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ * @param int $port */ public function __construct(NetworkInterface $interface, string $ip, int $port){ - $this->interface = $interface; $this->perm = new PermissibleBase($this); $this->namedtag = new CompoundTag(); $this->server = Server::getInstance(); @@ -727,7 +714,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->allowMovementCheats = (bool) $this->server->getProperty("player.anti-cheat.allow-movement-cheats", false); - $this->sessionAdapter = new PlayerNetworkSessionAdapter($this->server, $this); + $this->sessionAdapter = new PlayerNetworkSessionAdapter($this->server, $this, $interface); } /** @@ -1802,11 +1789,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ if(count($this->loadQueue) > 0){ $this->sendNextChunk(); } - - if(count($this->batchedPackets) > 0){ - $this->server->batchPackets([$this], $this->batchedPackets, false); - $this->batchedPackets = []; - } } /** @@ -3058,31 +3040,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } } - /** - * Batch a Data packet into the channel list to send at the end of the tick - * - * @param DataPacket $packet - * - * @return bool - */ - public function batchDataPacket(DataPacket $packet) : bool{ - if(!$this->isConnected()){ - return false; - } - - $timings = Timings::getSendDataPacketTimings($packet); - $timings->startTiming(); - $this->server->getPluginManager()->callEvent($ev = new DataPacketSendEvent($this, $packet)); - if($ev->isCancelled()){ - $timings->stopTiming(); - return false; - } - - $this->batchedPackets[] = clone $packet; - $timings->stopTiming(); - return true; - } - /** * @param DataPacket $packet * @param bool $needACK @@ -3100,25 +3057,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ throw new \InvalidArgumentException("Attempted to send " . get_class($packet) . " to " . $this->getName() . " too early"); } - $timings = Timings::getSendDataPacketTimings($packet); - $timings->startTiming(); - try{ - $this->server->getPluginManager()->callEvent($ev = new DataPacketSendEvent($this, $packet)); - if($ev->isCancelled()){ - return false; - } - - $identifier = $this->interface->putPacket($this, $packet, $needACK, $immediate); - - if($needACK and $identifier !== null){ - $this->needACK[$identifier] = false; - return $identifier; - } - - return true; - }finally{ - $timings->stopTiming(); - } + return $this->sessionAdapter->sendDataPacket($packet, $immediate); } /** @@ -3368,12 +3307,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ if($this->isConnected() and !$this->closed){ try{ - if($notify and strlen($reason) > 0){ - $pk = new DisconnectPacket(); - $pk->message = $reason; - $this->directDataPacket($pk); - } - $this->interface->close($this, $notify ? $reason : ""); + $this->sessionAdapter->serverDisconnect($reason, $notify); $this->sessionAdapter = null; $this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this); diff --git a/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php b/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php index 2f651a583a..bc4895bf98 100644 --- a/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php +++ b/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe; use pocketmine\event\server\DataPacketReceiveEvent; +use pocketmine\event\server\DataPacketSendEvent; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; @@ -37,6 +38,7 @@ use pocketmine\network\mcpe\protocol\CommandRequestPacket; use pocketmine\network\mcpe\protocol\ContainerClosePacket; use pocketmine\network\mcpe\protocol\CraftingEventPacket; use pocketmine\network\mcpe\protocol\DataPacket; +use pocketmine\network\mcpe\protocol\DisconnectPacket; use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\EntityFallPacket; use pocketmine\network\mcpe\protocol\EntityPickRequestPacket; @@ -62,6 +64,7 @@ use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; use pocketmine\network\mcpe\protocol\ShowCreditsPacket; use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket; use pocketmine\network\mcpe\protocol\TextPacket; +use pocketmine\network\NetworkInterface; use pocketmine\Player; use pocketmine\Server; use pocketmine\timings\Timings; @@ -72,10 +75,13 @@ class PlayerNetworkSessionAdapter extends NetworkSession{ private $server; /** @var Player */ private $player; + /** @var NetworkInterface */ + private $interface; - public function __construct(Server $server, Player $player){ + public function __construct(Server $server, Player $player, NetworkInterface $interface){ $this->server = $server; $this->player = $player; + $this->interface = $interface; } public function handleDataPacket(DataPacket $packet) : void{ @@ -96,6 +102,33 @@ class PlayerNetworkSessionAdapter extends NetworkSession{ $timings->stopTiming(); } + public function sendDataPacket(DataPacket $packet, bool $immediate = false) : bool{ + $timings = Timings::getSendDataPacketTimings($packet); + $timings->startTiming(); + try{ + $this->server->getPluginManager()->callEvent($ev = new DataPacketSendEvent($this->player, $packet)); + if($ev->isCancelled()){ + return false; + } + + $this->interface->putPacket($this->player, $packet, false, $immediate); + + return true; + }finally{ + $timings->stopTiming(); + } + } + + public function serverDisconnect(string $reason, bool $notify = true) : void{ + if($notify){ + $pk = new DisconnectPacket(); + $pk->message = $reason; + $pk->hideDisconnectionScreen = $reason === ""; + $this->sendDataPacket($pk, true); + } + $this->interface->close($this->player, $notify ? $reason : ""); + } + public function handleLogin(LoginPacket $packet) : bool{ return $this->player->handleLogin($packet); } From 1144620f2b1a52710be3f7ee4117ace392e3fc56 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 18 Jul 2018 16:48:53 +0100 Subject: [PATCH 0020/3224] Level: minor de-spaghettification of chunk requesting Now the Level tells the player to request chunks on tick, instead of the server doing it. --- src/pocketmine/Player.php | 28 ++++++++++++++-------------- src/pocketmine/Server.php | 4 ---- src/pocketmine/level/Level.php | 7 +++++-- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index d645505165..8a8e5732c2 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1140,6 +1140,20 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ Timings::$playerChunkOrderTimer->stopTiming(); } + public function doChunkRequests(){ + if(!$this->isOnline()){ + return; + } + + if($this->nextChunkOrderRun-- <= 0){ + $this->orderChunks(); + } + + if(count($this->loadQueue) > 0){ + $this->sendNextChunk(); + } + } + /** * @return Position */ @@ -1774,20 +1788,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->dataPacket($pk); } - public function checkNetwork(){ - if(!$this->isOnline()){ - return; - } - - if($this->nextChunkOrderRun-- <= 0){ - $this->orderChunks(); - } - - if(count($this->loadQueue) > 0){ - $this->sendNextChunk(); - } - } - /** * Returns whether the player can interact with the specified position. This checks distance and direction. * diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 3e7a46c644..e0b920ad16 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -2511,10 +2511,6 @@ class Server{ $this->checkTickUpdates($this->tickCounter, $tickTime); - foreach($this->players as $player){ - $player->checkNetwork(); - } - if(($this->tickCounter % 20) === 0){ if($this->doTitleTick){ $this->titleTick(); diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 0678230ff8..4cd1281ce9 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -787,7 +787,10 @@ class Level implements ChunkManager, Metadatable{ } - $this->processChunkRequest(); + foreach($this->players as $p){ + $p->doChunkRequests(); + } + $this->processChunkRequests(); if($this->sleepTicks > 0 and --$this->sleepTicks <= 0){ $this->checkSleep(); @@ -2464,7 +2467,7 @@ class Level implements ChunkManager, Metadatable{ } } - private function processChunkRequest(){ + private function processChunkRequests(){ if(count($this->chunkSendQueue) > 0){ $this->timings->syncChunkSendTimer->startTiming(); From f969f3b77fe51d4e3bb5a5cfcd6cc132fbf2a4f9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 18 Jul 2018 17:23:49 +0100 Subject: [PATCH 0021/3224] Flatten NetworkSession hierarchy in preparation for refactor --- src/pocketmine/Player.php | 23 +- .../network/mcpe/NetworkSession.php | 143 ++++++--- .../mcpe/PlayerNetworkSessionAdapter.php | 281 ------------------ 3 files changed, 116 insertions(+), 331 deletions(-) delete mode 100644 src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 8a8e5732c2..ef90720f7d 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -96,7 +96,7 @@ use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\ListTag; -use pocketmine\network\mcpe\PlayerNetworkSessionAdapter; +use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; @@ -183,11 +183,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return $lname !== "rcon" and $lname !== "console" and $len >= 1 and $len <= 16 and preg_match("/[^A-Za-z0-9_ ]/", $name) === 0; } - /** - * @var PlayerNetworkSessionAdapter - * TODO: remove this once player and network are divorced properly - */ - protected $sessionAdapter; + /** @var NetworkSession */ + protected $networkSession; /** @var int */ protected $protocol = -1; @@ -714,14 +711,14 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->allowMovementCheats = (bool) $this->server->getProperty("player.anti-cheat.allow-movement-cheats", false); - $this->sessionAdapter = new PlayerNetworkSessionAdapter($this->server, $this, $interface); + $this->networkSession = new NetworkSession($this->server, $this, $interface); } /** * @return bool */ public function isConnected() : bool{ - return $this->sessionAdapter !== null; + return $this->networkSession !== null; } /** @@ -3032,8 +3029,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ * @param DataPacket $packet */ public function handleDataPacket(DataPacket $packet){ - if($this->sessionAdapter !== null){ - $this->sessionAdapter->handleDataPacket($packet); + if($this->networkSession !== null){ + $this->networkSession->handleDataPacket($packet); } } @@ -3054,7 +3051,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ throw new \InvalidArgumentException("Attempted to send " . get_class($packet) . " to " . $this->getName() . " too early"); } - return $this->sessionAdapter->sendDataPacket($packet, $immediate); + return $this->networkSession->sendDataPacket($packet, $immediate); } /** @@ -3304,8 +3301,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ if($this->isConnected() and !$this->closed){ try{ - $this->sessionAdapter->serverDisconnect($reason, $notify); - $this->sessionAdapter = null; + $this->networkSession->serverDisconnect($reason, $notify); + $this->networkSession = null; $this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this); $this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this); diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 67265e9476..d306133953 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; +use pocketmine\event\server\DataPacketReceiveEvent; +use pocketmine\event\server\DataPacketSendEvent; use pocketmine\network\mcpe\protocol\AddBehaviorTreePacket; use pocketmine\network\mcpe\protocol\AddEntityPacket; use pocketmine\network\mcpe\protocol\AddHangingEntityPacket; @@ -136,13 +138,74 @@ use pocketmine\network\mcpe\protocol\UpdateBlockSyncedPacket; use pocketmine\network\mcpe\protocol\UpdateEquipPacket; use pocketmine\network\mcpe\protocol\UpdateTradePacket; use pocketmine\network\mcpe\protocol\WSConnectPacket; +use pocketmine\network\NetworkInterface; +use pocketmine\Player; +use pocketmine\Server; +use pocketmine\timings\Timings; -abstract class NetworkSession{ +class NetworkSession{ - abstract public function handleDataPacket(DataPacket $packet); + + /** @var Server */ + private $server; + /** @var Player */ + private $player; + /** @var NetworkInterface */ + private $interface; + + public function __construct(Server $server, Player $player, NetworkInterface $interface){ + $this->server = $server; + $this->player = $player; + $this->interface = $interface; + } + + public function handleDataPacket(DataPacket $packet) : void{ + $timings = Timings::getReceiveDataPacketTimings($packet); + $timings->startTiming(); + + $packet->decode(); + if(!$packet->feof() and !$packet->mayHaveUnreadBytes()){ + $remains = substr($packet->buffer, $packet->offset); + $this->server->getLogger()->debug("Still " . strlen($remains) . " bytes unread in " . $packet->getName() . ": 0x" . bin2hex($remains)); + } + + $this->server->getPluginManager()->callEvent($ev = new DataPacketReceiveEvent($this->player, $packet)); + if(!$ev->isCancelled() and !$packet->handle($this)){ + $this->server->getLogger()->debug("Unhandled " . $packet->getName() . " received from " . $this->player->getName() . ": 0x" . bin2hex($packet->buffer)); + } + + $timings->stopTiming(); + } + + public function sendDataPacket(DataPacket $packet, bool $immediate = false) : bool{ + $timings = Timings::getSendDataPacketTimings($packet); + $timings->startTiming(); + try{ + $this->server->getPluginManager()->callEvent($ev = new DataPacketSendEvent($this->player, $packet)); + if($ev->isCancelled()){ + return false; + } + + $this->interface->putPacket($this->player, $packet, false, $immediate); + + return true; + }finally{ + $timings->stopTiming(); + } + } + + public function serverDisconnect(string $reason, bool $notify = true) : void{ + if($notify){ + $pk = new DisconnectPacket(); + $pk->message = $reason; + $pk->hideDisconnectionScreen = $reason === ""; + $this->sendDataPacket($pk, true); + } + $this->interface->close($this->player, $notify ? $reason : ""); + } public function handleLogin(LoginPacket $packet) : bool{ - return false; + return $this->player->handleLogin($packet); } public function handlePlayStatus(PlayStatusPacket $packet) : bool{ @@ -154,7 +217,7 @@ abstract class NetworkSession{ } public function handleClientToServerHandshake(ClientToServerHandshakePacket $packet) : bool{ - return false; + return false; //TODO } public function handleDisconnect(DisconnectPacket $packet) : bool{ @@ -170,10 +233,14 @@ abstract class NetworkSession{ } public function handleResourcePackClientResponse(ResourcePackClientResponsePacket $packet) : bool{ - return false; + return $this->player->handleResourcePackClientResponse($packet); } public function handleText(TextPacket $packet) : bool{ + if($packet->type === TextPacket::TYPE_CHAT){ + return $this->player->chat($packet->message); + } + return false; } @@ -214,7 +281,7 @@ abstract class NetworkSession{ } public function handleMovePlayer(MovePlayerPacket $packet) : bool{ - return false; + return $this->player->handleMovePlayer($packet); } public function handleRiderJump(RiderJumpPacket $packet) : bool{ @@ -234,7 +301,7 @@ abstract class NetworkSession{ } public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{ - return false; + return $this->player->handleLevelSoundEvent($packet); } public function handleLevelEvent(LevelEventPacket $packet) : bool{ @@ -246,7 +313,7 @@ abstract class NetworkSession{ } public function handleEntityEvent(EntityEventPacket $packet) : bool{ - return false; + return $this->player->handleEntityEvent($packet); } public function handleMobEffect(MobEffectPacket $packet) : bool{ @@ -258,35 +325,35 @@ abstract class NetworkSession{ } public function handleInventoryTransaction(InventoryTransactionPacket $packet) : bool{ - return false; + return $this->player->handleInventoryTransaction($packet); } public function handleMobEquipment(MobEquipmentPacket $packet) : bool{ - return false; + return $this->player->handleMobEquipment($packet); } public function handleMobArmorEquipment(MobArmorEquipmentPacket $packet) : bool{ - return false; + return true; //Not used } public function handleInteract(InteractPacket $packet) : bool{ - return false; + return $this->player->handleInteract($packet); } public function handleBlockPickRequest(BlockPickRequestPacket $packet) : bool{ - return false; + return $this->player->handleBlockPickRequest($packet); } public function handleEntityPickRequest(EntityPickRequestPacket $packet) : bool{ - return false; + return false; //TODO } public function handlePlayerAction(PlayerActionPacket $packet) : bool{ - return false; + return $this->player->handlePlayerAction($packet); } public function handleEntityFall(EntityFallPacket $packet) : bool{ - return false; + return true; //Not used } public function handleHurtArmor(HurtArmorPacket $packet) : bool{ @@ -314,7 +381,7 @@ abstract class NetworkSession{ } public function handleAnimate(AnimatePacket $packet) : bool{ - return false; + return $this->player->handleAnimate($packet); } public function handleRespawn(RespawnPacket $packet) : bool{ @@ -326,11 +393,11 @@ abstract class NetworkSession{ } public function handleContainerClose(ContainerClosePacket $packet) : bool{ - return false; + return $this->player->handleContainerClose($packet); } public function handlePlayerHotbar(PlayerHotbarPacket $packet) : bool{ - return false; + return true; //this packet is useless } public function handleInventoryContent(InventoryContentPacket $packet) : bool{ @@ -350,7 +417,7 @@ abstract class NetworkSession{ } public function handleCraftingEvent(CraftingEventPacket $packet) : bool{ - return false; + return true; //this is a broken useless packet, so we don't use it } public function handleGuiDataPickItem(GuiDataPickItemPacket $packet) : bool{ @@ -358,15 +425,15 @@ abstract class NetworkSession{ } public function handleAdventureSettings(AdventureSettingsPacket $packet) : bool{ - return false; + return $this->player->handleAdventureSettings($packet); } public function handleBlockEntityData(BlockEntityDataPacket $packet) : bool{ - return false; + return $this->player->handleBlockEntityData($packet); } public function handlePlayerInput(PlayerInputPacket $packet) : bool{ - return false; + return false; //TODO } public function handleFullChunkData(FullChunkDataPacket $packet) : bool{ @@ -386,7 +453,7 @@ abstract class NetworkSession{ } public function handleSetPlayerGameType(SetPlayerGameTypePacket $packet) : bool{ - return false; + return $this->player->handleSetPlayerGameType($packet); } public function handlePlayerList(PlayerListPacket $packet) : bool{ @@ -402,7 +469,7 @@ abstract class NetworkSession{ } public function handleSpawnExperienceOrb(SpawnExperienceOrbPacket $packet) : bool{ - return false; + return false; //TODO } public function handleClientboundMapItemData(ClientboundMapItemDataPacket $packet) : bool{ @@ -410,11 +477,13 @@ abstract class NetworkSession{ } public function handleMapInfoRequest(MapInfoRequestPacket $packet) : bool{ - return false; + return false; //TODO } public function handleRequestChunkRadius(RequestChunkRadiusPacket $packet) : bool{ - return false; + $this->player->setViewDistance($packet->radius); + + return true; } public function handleChunkRadiusUpdated(ChunkRadiusUpdatedPacket $packet) : bool{ @@ -422,7 +491,7 @@ abstract class NetworkSession{ } public function handleItemFrameDropItem(ItemFrameDropItemPacket $packet) : bool{ - return false; + return $this->player->handleItemFrameDropItem($packet); } public function handleGameRulesChanged(GameRulesChangedPacket $packet) : bool{ @@ -434,11 +503,11 @@ abstract class NetworkSession{ } public function handleBossEvent(BossEventPacket $packet) : bool{ - return false; + return false; //TODO } public function handleShowCredits(ShowCreditsPacket $packet) : bool{ - return false; + return false; //TODO: handle resume } public function handleAvailableCommands(AvailableCommandsPacket $packet) : bool{ @@ -446,11 +515,11 @@ abstract class NetworkSession{ } public function handleCommandRequest(CommandRequestPacket $packet) : bool{ - return false; + return $this->player->chat($packet->command); } public function handleCommandBlockUpdate(CommandBlockUpdatePacket $packet) : bool{ - return false; + return false; //TODO } public function handleCommandOutput(CommandOutputPacket $packet) : bool{ @@ -474,7 +543,7 @@ abstract class NetworkSession{ } public function handleResourcePackChunkRequest(ResourcePackChunkRequestPacket $packet) : bool{ - return false; + return $this->player->handleResourcePackChunkRequest($packet); } public function handleTransfer(TransferPacket $packet) : bool{ @@ -510,7 +579,7 @@ abstract class NetworkSession{ } public function handlePlayerSkin(PlayerSkinPacket $packet) : bool{ - return false; + return $this->player->changeSkin($packet->skin, $packet->newSkinName, $packet->oldSkinName); } public function handleSubClientLogin(SubClientLoginPacket $packet) : bool{ @@ -526,7 +595,7 @@ abstract class NetworkSession{ } public function handleBookEdit(BookEditPacket $packet) : bool{ - return false; + return $this->player->handleBookEdit($packet); } public function handleNpcRequest(NpcRequestPacket $packet) : bool{ @@ -542,11 +611,11 @@ abstract class NetworkSession{ } public function handleModalFormResponse(ModalFormResponsePacket $packet) : bool{ - return false; + return false; //TODO: GUI stuff } public function handleServerSettingsRequest(ServerSettingsRequestPacket $packet) : bool{ - return false; + return false; //TODO: GUI stuff } public function handleServerSettingsResponse(ServerSettingsResponsePacket $packet) : bool{ diff --git a/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php b/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php deleted file mode 100644 index bc4895bf98..0000000000 --- a/src/pocketmine/network/mcpe/PlayerNetworkSessionAdapter.php +++ /dev/null @@ -1,281 +0,0 @@ -server = $server; - $this->player = $player; - $this->interface = $interface; - } - - public function handleDataPacket(DataPacket $packet) : void{ - $timings = Timings::getReceiveDataPacketTimings($packet); - $timings->startTiming(); - - $packet->decode(); - if(!$packet->feof() and !$packet->mayHaveUnreadBytes()){ - $remains = substr($packet->buffer, $packet->offset); - $this->server->getLogger()->debug("Still " . strlen($remains) . " bytes unread in " . $packet->getName() . ": 0x" . bin2hex($remains)); - } - - $this->server->getPluginManager()->callEvent($ev = new DataPacketReceiveEvent($this->player, $packet)); - if(!$ev->isCancelled() and !$packet->handle($this)){ - $this->server->getLogger()->debug("Unhandled " . $packet->getName() . " received from " . $this->player->getName() . ": 0x" . bin2hex($packet->buffer)); - } - - $timings->stopTiming(); - } - - public function sendDataPacket(DataPacket $packet, bool $immediate = false) : bool{ - $timings = Timings::getSendDataPacketTimings($packet); - $timings->startTiming(); - try{ - $this->server->getPluginManager()->callEvent($ev = new DataPacketSendEvent($this->player, $packet)); - if($ev->isCancelled()){ - return false; - } - - $this->interface->putPacket($this->player, $packet, false, $immediate); - - return true; - }finally{ - $timings->stopTiming(); - } - } - - public function serverDisconnect(string $reason, bool $notify = true) : void{ - if($notify){ - $pk = new DisconnectPacket(); - $pk->message = $reason; - $pk->hideDisconnectionScreen = $reason === ""; - $this->sendDataPacket($pk, true); - } - $this->interface->close($this->player, $notify ? $reason : ""); - } - - public function handleLogin(LoginPacket $packet) : bool{ - return $this->player->handleLogin($packet); - } - - public function handleClientToServerHandshake(ClientToServerHandshakePacket $packet) : bool{ - return false; //TODO - } - - public function handleResourcePackClientResponse(ResourcePackClientResponsePacket $packet) : bool{ - return $this->player->handleResourcePackClientResponse($packet); - } - - public function handleText(TextPacket $packet) : bool{ - if($packet->type === TextPacket::TYPE_CHAT){ - return $this->player->chat($packet->message); - } - - return false; - } - - public function handleMovePlayer(MovePlayerPacket $packet) : bool{ - return $this->player->handleMovePlayer($packet); - } - - public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{ - return $this->player->handleLevelSoundEvent($packet); - } - - public function handleEntityEvent(EntityEventPacket $packet) : bool{ - return $this->player->handleEntityEvent($packet); - } - - public function handleInventoryTransaction(InventoryTransactionPacket $packet) : bool{ - return $this->player->handleInventoryTransaction($packet); - } - - public function handleMobEquipment(MobEquipmentPacket $packet) : bool{ - return $this->player->handleMobEquipment($packet); - } - - public function handleMobArmorEquipment(MobArmorEquipmentPacket $packet) : bool{ - return true; //Not used - } - - public function handleInteract(InteractPacket $packet) : bool{ - return $this->player->handleInteract($packet); - } - - public function handleBlockPickRequest(BlockPickRequestPacket $packet) : bool{ - return $this->player->handleBlockPickRequest($packet); - } - - public function handleEntityPickRequest(EntityPickRequestPacket $packet) : bool{ - return false; //TODO - } - - public function handlePlayerAction(PlayerActionPacket $packet) : bool{ - return $this->player->handlePlayerAction($packet); - } - - public function handleEntityFall(EntityFallPacket $packet) : bool{ - return true; //Not used - } - - public function handleAnimate(AnimatePacket $packet) : bool{ - return $this->player->handleAnimate($packet); - } - - public function handleContainerClose(ContainerClosePacket $packet) : bool{ - return $this->player->handleContainerClose($packet); - } - - public function handlePlayerHotbar(PlayerHotbarPacket $packet) : bool{ - return true; //this packet is useless - } - - public function handleCraftingEvent(CraftingEventPacket $packet) : bool{ - return true; //this is a broken useless packet, so we don't use it - } - - public function handleAdventureSettings(AdventureSettingsPacket $packet) : bool{ - return $this->player->handleAdventureSettings($packet); - } - - public function handleBlockEntityData(BlockEntityDataPacket $packet) : bool{ - return $this->player->handleBlockEntityData($packet); - } - - public function handlePlayerInput(PlayerInputPacket $packet) : bool{ - return false; //TODO - } - - public function handleSetPlayerGameType(SetPlayerGameTypePacket $packet) : bool{ - return $this->player->handleSetPlayerGameType($packet); - } - - public function handleSpawnExperienceOrb(SpawnExperienceOrbPacket $packet) : bool{ - return false; //TODO - } - - public function handleMapInfoRequest(MapInfoRequestPacket $packet) : bool{ - return false; //TODO - } - - public function handleRequestChunkRadius(RequestChunkRadiusPacket $packet) : bool{ - $this->player->setViewDistance($packet->radius); - - return true; - } - - public function handleItemFrameDropItem(ItemFrameDropItemPacket $packet) : bool{ - return $this->player->handleItemFrameDropItem($packet); - } - - public function handleBossEvent(BossEventPacket $packet) : bool{ - return false; //TODO - } - - public function handleShowCredits(ShowCreditsPacket $packet) : bool{ - return false; //TODO: handle resume - } - - public function handleCommandRequest(CommandRequestPacket $packet) : bool{ - return $this->player->chat($packet->command); - } - - public function handleCommandBlockUpdate(CommandBlockUpdatePacket $packet) : bool{ - return false; //TODO - } - - public function handleResourcePackChunkRequest(ResourcePackChunkRequestPacket $packet) : bool{ - return $this->player->handleResourcePackChunkRequest($packet); - } - - public function handlePlayerSkin(PlayerSkinPacket $packet) : bool{ - return $this->player->changeSkin($packet->skin, $packet->newSkinName, $packet->oldSkinName); - } - - public function handleBookEdit(BookEditPacket $packet) : bool{ - return $this->player->handleBookEdit($packet); - } - - public function handleModalFormResponse(ModalFormResponsePacket $packet) : bool{ - return false; //TODO: GUI stuff - } - - public function handleServerSettingsRequest(ServerSettingsRequestPacket $packet) : bool{ - return false; //TODO: GUI stuff - } -} From 85647c03bf2a90409ccba999779878b72bb07ee2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 18 Jul 2018 17:47:28 +0100 Subject: [PATCH 0022/3224] Move IP/port to NetworkSession --- src/pocketmine/Player.php | 23 ++++++++----------- .../network/mcpe/NetworkSession.php | 23 ++++++++++++++++++- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index ef90720f7d..440869eaee 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -189,11 +189,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ /** @var int */ protected $protocol = -1; - /** @var string */ - protected $ip; - /** @var int */ - protected $port; - /** * @var int * Last measurement of player's latency in milliseconds. @@ -698,8 +693,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->perm = new PermissibleBase($this); $this->namedtag = new CompoundTag(); $this->server = Server::getInstance(); - $this->ip = $ip; - $this->port = $port; $this->loaderId = Level::generateChunkLoaderId($this); $this->chunksPerTick = (int) $this->server->getProperty("chunk-sending.per-tick", 4); $this->spawnThreshold = (int) (($this->server->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); @@ -711,7 +704,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->allowMovementCheats = (bool) $this->server->getProperty("player.anti-cheat.allow-movement-cheats", false); - $this->networkSession = new NetworkSession($this->server, $this, $interface); + $this->networkSession = new NetworkSession($this->server, $this, $interface, $ip, $port); } /** @@ -806,14 +799,14 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ * @return string */ public function getAddress() : string{ - return $this->ip; + return $this->networkSession->getIp(); } /** * @return int */ public function getPort() : int{ - return $this->port; + return $this->networkSession->getPort(); } /** @@ -2106,8 +2099,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logIn", [ TextFormat::AQUA . $this->username . TextFormat::WHITE, - $this->ip, - $this->port, + $this->networkSession->getIp(), + $this->networkSession->getPort(), $this->id, $this->level->getName(), round($this->x, 4), @@ -3301,6 +3294,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ if($this->isConnected() and !$this->closed){ try{ + $ip = $this->networkSession->getIp(); + $port = $this->networkSession->getPort(); $this->networkSession->serverDisconnect($reason, $notify); $this->networkSession = null; @@ -3364,8 +3359,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logOut", [ TextFormat::AQUA . $this->getName() . TextFormat::WHITE, - $this->ip, - $this->port, + $ip, + $port, $this->getServer()->getLanguage()->translateString($reason) ])); diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index d306133953..b540415751 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -152,11 +152,32 @@ class NetworkSession{ private $player; /** @var NetworkInterface */ private $interface; + /** @var string */ + private $ip; + /** @var int */ + private $port; - public function __construct(Server $server, Player $player, NetworkInterface $interface){ + public function __construct(Server $server, Player $player, NetworkInterface $interface, string $ip, int $port){ $this->server = $server; $this->player = $player; $this->interface = $interface; + + $this->ip = $ip; + $this->port = $port; + } + + /** + * @return string + */ + public function getIp() : string{ + return $this->ip; + } + + /** + * @return int + */ + public function getPort() : int{ + return $this->port; } public function handleDataPacket(DataPacket $packet) : void{ From bdd9a7eb52cfbeca58295d2b86bf732ed1de43ba Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 19 Jul 2018 14:52:34 +0100 Subject: [PATCH 0023/3224] Kill BatchPacket, clean up batching related things DataPacketSendEvent and DataPacketReceiveEvent will no longer capture BatchPackets In most places strings are now used instead of DataPackets, to remove limitations on what data can be sent to a network interface Removed CraftingManager's cyclic dependency on Server There is a lot more work to do aside from this, but this commit is intended to clean up what is necessary to fix the handling of BatchPacket. --- src/pocketmine/Player.php | 14 +- src/pocketmine/Server.php | 46 +++---- src/pocketmine/inventory/CraftingManager.php | 18 ++- src/pocketmine/level/Level.php | 5 +- src/pocketmine/network/Network.php | 3 - src/pocketmine/network/NetworkInterface.php | 11 +- .../network/mcpe/ChunkRequestTask.php | 16 +-- .../network/mcpe/CompressBatchedTask.php | 30 ++--- .../network/mcpe/NetworkCompression.php | 47 +++++++ .../network/mcpe/NetworkSession.php | 25 +++- ...ncapsulatedPacket.php => PacketStream.php} | 18 ++- .../network/mcpe/RakLibInterface.php | 47 ++----- .../network/mcpe/protocol/BatchPacket.php | 122 ------------------ .../network/mcpe/protocol/DataPacket.php | 4 - .../network/mcpe/protocol/PacketPool.php | 2 - 15 files changed, 152 insertions(+), 256 deletions(-) create mode 100644 src/pocketmine/network/mcpe/NetworkCompression.php rename src/pocketmine/network/mcpe/{CachedEncapsulatedPacket.php => PacketStream.php} (66%) delete mode 100644 src/pocketmine/network/mcpe/protocol/BatchPacket.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 440869eaee..836545e7fd 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -100,7 +100,6 @@ use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; -use pocketmine\network\mcpe\protocol\BatchPacket; use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\network\mcpe\protocol\BlockPickRequestPacket; use pocketmine\network\mcpe\protocol\BookEditPacket; @@ -714,6 +713,13 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return $this->networkSession !== null; } + /** + * @return NetworkSession + */ + public function getNetworkSession() : NetworkSession{ + return $this->networkSession; + } + /** * Gets the username * @return string @@ -934,7 +940,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ unset($this->loadQueue[$index]); } - public function sendChunk(int $x, int $z, BatchPacket $payload){ + public function sendChunk(int $x, int $z, string $payload){ if(!$this->isConnected()){ return; } @@ -942,7 +948,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->usedChunks[Level::chunkHash($x, $z)] = true; $this->chunkLoadCount++; - $this->dataPacket($payload); + $this->networkSession->getInterface()->putPacket($this, $payload); if($this->spawned){ foreach($this->level->getChunkEntities($x, $z) as $entity){ @@ -2120,7 +2126,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->sendAllInventories(); $this->inventory->sendCreativeContents(); $this->inventory->sendHeldItem($this); - $this->dataPacket($this->server->getCraftingManager()->getCraftingDataPacket()); + $this->networkSession->getInterface()->putPacket($this, $this->server->getCraftingManager()->getCraftingDataPacket()); $this->server->addOnlinePlayer($this); $this->server->sendFullPlayerListData($this); diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index e0b920ad16..b7f1a0cc7b 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -70,7 +70,8 @@ use pocketmine\nbt\tag\ShortTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\mcpe\CompressBatchedTask; -use pocketmine\network\mcpe\protocol\BatchPacket; +use pocketmine\network\mcpe\NetworkCompression; +use pocketmine\network\mcpe\PacketStream; use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\ProtocolInfo; @@ -223,8 +224,6 @@ class Server{ private $network; /** @var bool */ private $networkCompressionAsync = true; - /** @var int */ - public $networkCompressionLevel = 7; /** @var bool */ private $autoTickRate = true; @@ -1517,15 +1516,15 @@ class Server{ $this->asyncPool = new AsyncPool($this, $poolSize, (int) max(-1, (int) $this->getProperty("memory.async-worker-hard-limit", 256)), $this->autoloader, $this->logger); if($this->getProperty("network.batch-threshold", 256) >= 0){ - Network::$BATCH_THRESHOLD = (int) $this->getProperty("network.batch-threshold", 256); + NetworkCompression::$THRESHOLD = (int) $this->getProperty("network.batch-threshold", 256); }else{ - Network::$BATCH_THRESHOLD = -1; + NetworkCompression::$THRESHOLD = -1; } - $this->networkCompressionLevel = $this->getProperty("network.compression-level", 7); - if($this->networkCompressionLevel < 1 or $this->networkCompressionLevel > 9){ - $this->logger->warning("Invalid network compression level $this->networkCompressionLevel set, setting to default 7"); - $this->networkCompressionLevel = 7; + NetworkCompression::$LEVEL = $this->getProperty("network.compression-level", 7); + if(NetworkCompression::$LEVEL < 1 or NetworkCompression::$LEVEL > 9){ + $this->logger->warning("Invalid network compression level " . NetworkCompression::$LEVEL . " set, setting to default 7"); + NetworkCompression::$LEVEL = 7; } $this->networkCompressionAsync = (bool) $this->getProperty("network.async-compression", true); @@ -1864,24 +1863,23 @@ class Server{ $targets = array_filter($players, function(Player $player) : bool{ return $player->isConnected(); }); if(!empty($targets)){ - $pk = new BatchPacket(); + $stream = new PacketStream(); foreach($packets as $p){ - $pk->addPacket($p); + $stream->putPacket($p); } - if(Network::$BATCH_THRESHOLD >= 0 and strlen($pk->payload) >= Network::$BATCH_THRESHOLD){ - $pk->setCompressionLevel($this->networkCompressionLevel); - }else{ - $pk->setCompressionLevel(0); //Do not compress packets under the threshold + $compressionLevel = NetworkCompression::$LEVEL; + if(NetworkCompression::$THRESHOLD < 0 or strlen($stream->buffer) < NetworkCompression::$THRESHOLD){ + $compressionLevel = 0; //Do not compress packets under the threshold $forceSync = true; } if(!$forceSync and !$immediate and $this->networkCompressionAsync){ - $task = new CompressBatchedTask($pk, $targets); + $task = new CompressBatchedTask($stream, $targets, $compressionLevel); $this->asyncPool->submitTask($task); }else{ - $this->broadcastPacketsCallback($pk, $targets, $immediate); + $this->broadcastPacketsCallback(NetworkCompression::compress($stream->buffer), $targets, $immediate); } } @@ -1889,17 +1887,13 @@ class Server{ } /** - * @param BatchPacket $pk - * @param Player[] $players - * @param bool $immediate + * @param string $payload + * @param Player[] $players + * @param bool $immediate */ - public function broadcastPacketsCallback(BatchPacket $pk, array $players, bool $immediate = false){ - if(!$pk->isEncoded){ - $pk->encode(); - } - + public function broadcastPacketsCallback(string $payload, array $players, bool $immediate = false){ foreach($players as $i){ - $i->sendDataPacket($pk, false, $immediate); + $i->getNetworkSession()->getInterface()->putPacket($i, $payload, false, $immediate); } } diff --git a/src/pocketmine/inventory/CraftingManager.php b/src/pocketmine/inventory/CraftingManager.php index 567e3e1b02..414294d91a 100644 --- a/src/pocketmine/inventory/CraftingManager.php +++ b/src/pocketmine/inventory/CraftingManager.php @@ -25,9 +25,9 @@ namespace pocketmine\inventory; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\network\mcpe\protocol\BatchPacket; +use pocketmine\network\mcpe\NetworkCompression; +use pocketmine\network\mcpe\PacketStream; use pocketmine\network\mcpe\protocol\CraftingDataPacket; -use pocketmine\Server; use pocketmine\timings\Timings; class CraftingManager{ @@ -38,7 +38,7 @@ class CraftingManager{ /** @var FurnaceRecipe[] */ protected $furnaceRecipes = []; - /** @var BatchPacket */ + /** @var string */ private $craftingDataCache; public function __construct(){ @@ -102,21 +102,19 @@ class CraftingManager{ $pk->encode(); - $batch = new BatchPacket(); - $batch->addPacket($pk); - $batch->setCompressionLevel(Server::getInstance()->networkCompressionLevel); - $batch->encode(); + $batch = new PacketStream(); + $batch->putPacket($pk); - $this->craftingDataCache = $batch; + $this->craftingDataCache = NetworkCompression::compress($batch->buffer); Timings::$craftingDataCacheRebuildTimer->stopTiming(); } /** * Returns a pre-compressed CraftingDataPacket for sending to players. Rebuilds the cache if it is not found. * - * @return BatchPacket + * @return string */ - public function getCraftingDataPacket() : BatchPacket{ + public function getCraftingDataPacket() : string{ if($this->craftingDataCache === null){ $this->buildCraftingDataCache(); } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 4cd1281ce9..e6011ef63f 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -69,7 +69,6 @@ use pocketmine\metadata\MetadataValue; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\ChunkRequestTask; -use pocketmine\network\mcpe\protocol\BatchPacket; use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; @@ -123,7 +122,7 @@ class Level implements ChunkManager, Metadatable{ /** @var Block[][] */ private $blockCache = []; - /** @var BatchPacket[] */ + /** @var string[] */ private $chunkCache = []; /** @var int */ @@ -2498,7 +2497,7 @@ class Level implements ChunkManager, Metadatable{ } } - public function chunkRequestCallback(int $x, int $z, BatchPacket $payload){ + public function chunkRequestCallback(int $x, int $z, string $payload){ $this->timings->syncChunkSendTimer->startTiming(); $index = Level::chunkHash($x, $z); diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index 0b315faab3..48252a03d1 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -33,9 +33,6 @@ use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\Server; class Network{ - - public static $BATCH_THRESHOLD = 512; - /** @var Server */ private $server; diff --git a/src/pocketmine/network/NetworkInterface.php b/src/pocketmine/network/NetworkInterface.php index 0818234fcb..461bc74401 100644 --- a/src/pocketmine/network/NetworkInterface.php +++ b/src/pocketmine/network/NetworkInterface.php @@ -26,7 +26,6 @@ declare(strict_types=1); */ namespace pocketmine\network; -use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\Player; /** @@ -42,14 +41,14 @@ interface NetworkInterface{ /** * Sends a DataPacket to the interface, returns an unique identifier for the packet if $needACK is true * - * @param Player $player - * @param DataPacket $packet - * @param bool $needACK - * @param bool $immediate + * @param Player $player + * @param string $payload + * @param bool $needACK + * @param bool $immediate * * @return int|null */ - public function putPacket(Player $player, DataPacket $packet, bool $needACK = false, bool $immediate = true) : ?int; + public function putPacket(Player $player, string $payload, bool $needACK = false, bool $immediate = true) : ?int; /** * Terminates the connection diff --git a/src/pocketmine/network/mcpe/ChunkRequestTask.php b/src/pocketmine/network/mcpe/ChunkRequestTask.php index f28dc22f9e..c904f517a7 100644 --- a/src/pocketmine/network/mcpe/ChunkRequestTask.php +++ b/src/pocketmine/network/mcpe/ChunkRequestTask.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe; use pocketmine\level\format\Chunk; use pocketmine\level\Level; -use pocketmine\network\mcpe\protocol\BatchPacket; use pocketmine\network\mcpe\protocol\FullChunkDataPacket; use pocketmine\scheduler\AsyncTask; use pocketmine\Server; @@ -47,7 +46,7 @@ class ChunkRequestTask extends AsyncTask{ public function __construct(Level $level, int $chunkX, int $chunkZ, Chunk $chunk){ $this->levelId = $level->getId(); - $this->compressionLevel = $level->getServer()->networkCompressionLevel; + $this->compressionLevel = NetworkCompression::$LEVEL; $this->chunk = $chunk->fastSerialize(); $this->chunkX = $chunkX; @@ -72,22 +71,17 @@ class ChunkRequestTask extends AsyncTask{ $pk->chunkZ = $this->chunkZ; $pk->data = $chunk->networkSerialize() . $this->tiles; - $batch = new BatchPacket(); - $batch->addPacket($pk); - $batch->setCompressionLevel($this->compressionLevel); - $batch->encode(); + $stream = new PacketStream(); + $stream->putPacket($pk); - $this->setResult($batch->buffer, false); + $this->setResult(NetworkCompression::compress($stream->buffer, $this->compressionLevel), false); } public function onCompletion(Server $server) : void{ $level = $server->getLevel($this->levelId); if($level instanceof Level){ if($this->hasResult()){ - $batch = new BatchPacket($this->getResult()); - assert(strlen($batch->buffer) > 0); - $batch->isEncoded = true; - $level->chunkRequestCallback($this->chunkX, $this->chunkZ, $batch); + $level->chunkRequestCallback($this->chunkX, $this->chunkZ, $this->getResult()); }else{ $server->getLogger()->error("Chunk request for level #" . $this->levelId . ", x=" . $this->chunkX . ", z=" . $this->chunkZ . " doesn't have any result data"); } diff --git a/src/pocketmine/network/mcpe/CompressBatchedTask.php b/src/pocketmine/network/mcpe/CompressBatchedTask.php index 420b3fc67f..77e4a089f0 100644 --- a/src/pocketmine/network/mcpe/CompressBatchedTask.php +++ b/src/pocketmine/network/mcpe/CompressBatchedTask.php @@ -23,44 +23,34 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; -use pocketmine\network\mcpe\protocol\BatchPacket; use pocketmine\Player; use pocketmine\scheduler\AsyncTask; use pocketmine\Server; class CompressBatchedTask extends AsyncTask{ - public $level = 7; - public $data; + private $level; + private $data; /** - * @param BatchPacket $batch - * @param string[] $targets + * @param PacketStream $stream + * @param string[] $targets + * @param int $compressionLevel */ - public function __construct(BatchPacket $batch, array $targets){ - $this->data = $batch->payload; - $this->level = $batch->getCompressionLevel(); + public function __construct(PacketStream $stream, array $targets, int $compressionLevel){ + $this->data = $stream->buffer; + $this->level = $compressionLevel; $this->storeLocal($targets); } public function onRun() : void{ - $batch = new BatchPacket(); - $batch->payload = $this->data; - $this->data = null; - - $batch->setCompressionLevel($this->level); - $batch->encode(); - - $this->setResult($batch->buffer, false); + $this->setResult(NetworkCompression::compress($this->data, $this->level), false); } public function onCompletion(Server $server) : void{ - $pk = new BatchPacket($this->getResult()); - $pk->isEncoded = true; - /** @var Player[] $targets */ $targets = $this->fetchLocal(); - $server->broadcastPacketsCallback($pk, $targets); + $server->broadcastPacketsCallback($this->getResult(), $targets); } } diff --git a/src/pocketmine/network/mcpe/NetworkCompression.php b/src/pocketmine/network/mcpe/NetworkCompression.php new file mode 100644 index 0000000000..b7c608f6a7 --- /dev/null +++ b/src/pocketmine/network/mcpe/NetworkCompression.php @@ -0,0 +1,47 @@ +port = $port; } + public function getInterface() : NetworkInterface{ + return $this->interface; + } + /** * @return string */ @@ -180,6 +185,15 @@ class NetworkSession{ return $this->port; } + public function handleEncoded(string $payload) : void{ + //TODO: decryption if enabled + + $stream = new PacketStream(NetworkCompression::decompress($payload)); + while(!$stream->feof()){ + $this->handleDataPacket(PacketPool::getPacket($stream->getString())); + } + } + public function handleDataPacket(DataPacket $packet) : void{ $timings = Timings::getReceiveDataPacketTimings($packet); $timings->startTiming(); @@ -207,7 +221,8 @@ class NetworkSession{ return false; } - $this->interface->putPacket($this->player, $packet, false, $immediate); + //TODO: implement buffering (this is just a quick fix) + $this->server->batchPackets([$this->player], [$packet], true, $immediate); return true; }finally{ diff --git a/src/pocketmine/network/mcpe/CachedEncapsulatedPacket.php b/src/pocketmine/network/mcpe/PacketStream.php similarity index 66% rename from src/pocketmine/network/mcpe/CachedEncapsulatedPacket.php rename to src/pocketmine/network/mcpe/PacketStream.php index 74bf3d4640..9a0f4e9778 100644 --- a/src/pocketmine/network/mcpe/CachedEncapsulatedPacket.php +++ b/src/pocketmine/network/mcpe/PacketStream.php @@ -23,13 +23,19 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; -use raklib\protocol\EncapsulatedPacket; +use pocketmine\network\mcpe\protocol\DataPacket; +use pocketmine\network\mcpe\protocol\PacketPool; -class CachedEncapsulatedPacket extends EncapsulatedPacket{ - /** @var string|null */ - private $internalData = null; +class PacketStream extends NetworkBinaryStream{ - public function toInternalBinary() : string{ - return $this->internalData ?? ($this->internalData = parent::toInternalBinary()); + public function putPacket(DataPacket $packet) : void{ + if(!$packet->isEncoded){ + $packet->encode(); + } + $this->putString($packet->buffer); + } + + public function getPacket() : DataPacket{ + return PacketPool::getPacket($this->getString()); } } diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 08c46ee85d..aca42af676 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -25,9 +25,6 @@ namespace pocketmine\network\mcpe; use pocketmine\event\player\PlayerCreationEvent; use pocketmine\network\AdvancedNetworkInterface; -use pocketmine\network\mcpe\protocol\BatchPacket; -use pocketmine\network\mcpe\protocol\DataPacket; -use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\Network; use pocketmine\Player; @@ -48,6 +45,8 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ */ private const MCPE_RAKNET_PROTOCOL_VERSION = 8; + private const MCPE_RAKNET_PACKET_ID = "\xfe"; + /** @var Server */ private $server; @@ -153,13 +152,12 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ //get this now for blocking in case the player was closed before the exception was raised $address = $this->players[$identifier]->getAddress(); try{ - if($packet->buffer !== ""){ - $pk = PacketPool::getPacket($packet->buffer); - $this->players[$identifier]->handleDataPacket($pk); + if($packet->buffer !== "" and $packet->buffer{0} === self::MCPE_RAKNET_PACKET_ID){ //Batch + $this->players[$identifier]->getNetworkSession()->handleEncoded(substr($packet->buffer, 1)); } }catch(\Throwable $e){ $logger = $this->server->getLogger(); - $logger->debug("Packet " . (isset($pk) ? get_class($pk) : "unknown") . " 0x" . bin2hex($packet->buffer)); + $logger->debug("EncapsulatedPacket 0x" . bin2hex($packet->buffer)); $logger->logException($e); $this->interface->blockAddress($address, 5); @@ -216,37 +214,18 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ } } - public function putPacket(Player $player, DataPacket $packet, bool $needACK = false, bool $immediate = true) : ?int{ + public function putPacket(Player $player, string $payload, bool $needACK = false, bool $immediate = true) : ?int{ if(isset($this->identifiers[$h = spl_object_hash($player)])){ $identifier = $this->identifiers[$h]; - if(!$packet->isEncoded){ - $packet->encode(); - } - if($packet instanceof BatchPacket){ - if($needACK){ - $pk = new EncapsulatedPacket(); - $pk->identifierACK = $this->identifiersACK[$identifier]++; - $pk->buffer = $packet->buffer; - $pk->reliability = PacketReliability::RELIABLE_ORDERED; - $pk->orderChannel = 0; - }else{ - if(!isset($packet->__encapsulatedPacket)){ - $packet->__encapsulatedPacket = new CachedEncapsulatedPacket; - $packet->__encapsulatedPacket->identifierACK = null; - $packet->__encapsulatedPacket->buffer = $packet->buffer; - $packet->__encapsulatedPacket->reliability = PacketReliability::RELIABLE_ORDERED; - $packet->__encapsulatedPacket->orderChannel = 0; - } - $pk = $packet->__encapsulatedPacket; - } + $pk = new EncapsulatedPacket(); + $pk->identifierACK = $this->identifiersACK[$identifier]++; + $pk->buffer = self::MCPE_RAKNET_PACKET_ID . $payload; + $pk->reliability = PacketReliability::RELIABLE_ORDERED; + $pk->orderChannel = 0; - $this->interface->sendEncapsulated($identifier, $pk, ($needACK ? RakLib::FLAG_NEED_ACK : 0) | ($immediate ? RakLib::PRIORITY_IMMEDIATE : RakLib::PRIORITY_NORMAL)); - return $pk->identifierACK; - }else{ - $this->server->batchPackets([$player], [$packet], true, $immediate); - return null; - } + $this->interface->sendEncapsulated($identifier, $pk, ($needACK ? RakLib::FLAG_NEED_ACK : 0) | ($immediate ? RakLib::PRIORITY_IMMEDIATE : RakLib::PRIORITY_NORMAL)); + return $pk->identifierACK; } return null; diff --git a/src/pocketmine/network/mcpe/protocol/BatchPacket.php b/src/pocketmine/network/mcpe/protocol/BatchPacket.php deleted file mode 100644 index 657ecb0c2f..0000000000 --- a/src/pocketmine/network/mcpe/protocol/BatchPacket.php +++ /dev/null @@ -1,122 +0,0 @@ - - - -use pocketmine\network\mcpe\NetworkBinaryStream; -use pocketmine\network\mcpe\NetworkSession; -#ifndef COMPILE -use pocketmine\utils\Binary; -#endif - -class BatchPacket extends DataPacket{ - public const NETWORK_ID = 0xfe; - - /** @var string */ - public $payload = ""; - /** @var int */ - protected $compressionLevel = 7; - - public function canBeBatched() : bool{ - return false; - } - - public function canBeSentBeforeLogin() : bool{ - return true; - } - - protected function decodeHeader() : void{ - $pid = $this->getByte(); - assert($pid === static::NETWORK_ID); - } - - protected function decodePayload() : void{ - $data = $this->getRemaining(); - try{ - $this->payload = zlib_decode($data, 1024 * 1024 * 64); //Max 64MB - }catch(\ErrorException $e){ //zlib decode error - $this->payload = ""; - } - } - - protected function encodeHeader() : void{ - $this->putByte(static::NETWORK_ID); - } - - protected function encodePayload() : void{ - $this->put(zlib_encode($this->payload, ZLIB_ENCODING_DEFLATE, $this->compressionLevel)); - } - - /** - * @param DataPacket $packet - */ - public function addPacket(DataPacket $packet) : void{ - if(!$packet->canBeBatched()){ - throw new \InvalidArgumentException(get_class($packet) . " cannot be put inside a BatchPacket"); - } - if(!$packet->isEncoded){ - $packet->encode(); - } - - $this->payload .= Binary::writeUnsignedVarInt(strlen($packet->buffer)) . $packet->buffer; - } - - /** - * @return \Generator - */ - public function getPackets() : \Generator{ - $stream = new NetworkBinaryStream($this->payload); - while(!$stream->feof()){ - yield $stream->getString(); - } - } - - public function getCompressionLevel() : int{ - return $this->compressionLevel; - } - - public function setCompressionLevel(int $level) : void{ - $this->compressionLevel = $level; - } - - public function handle(NetworkSession $session) : bool{ - if($this->payload === ""){ - return false; - } - - foreach($this->getPackets() as $buf){ - $pk = PacketPool::getPacket($buf); - - if(!$pk->canBeBatched()){ - throw new \InvalidArgumentException("Received invalid " . get_class($pk) . " inside BatchPacket"); - } - - $session->handleDataPacket($pk); - } - - return true; - } -} diff --git a/src/pocketmine/network/mcpe/protocol/DataPacket.php b/src/pocketmine/network/mcpe/protocol/DataPacket.php index 1201971d13..9e05043dbe 100644 --- a/src/pocketmine/network/mcpe/protocol/DataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/DataPacket.php @@ -49,10 +49,6 @@ abstract class DataPacket extends NetworkBinaryStream{ return (new \ReflectionClass($this))->getShortName(); } - public function canBeBatched() : bool{ - return true; - } - public function canBeSentBeforeLogin() : bool{ return false; } diff --git a/src/pocketmine/network/mcpe/protocol/PacketPool.php b/src/pocketmine/network/mcpe/protocol/PacketPool.php index 962932f1ad..d27545f7c1 100644 --- a/src/pocketmine/network/mcpe/protocol/PacketPool.php +++ b/src/pocketmine/network/mcpe/protocol/PacketPool.php @@ -143,8 +143,6 @@ class PacketPool{ static::registerPacket(new UpdateBlockSyncedPacket()); static::registerPacket(new MoveEntityDeltaPacket()); static::registerPacket(new SetLocalPlayerAsInitializedPacket()); - - static::registerPacket(new BatchPacket()); } /** From 64ecc373be17ec47a43f188075a2571184374050 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 19 Jul 2018 15:12:40 +0100 Subject: [PATCH 0024/3224] Split up session base logic and packet handling this will allow for mutable packet handlers which can be used to cleanly implement multi-stage game sessions. --- .../network/mcpe/NetworkSession.php | 574 +---------------- .../network/mcpe/handler/SessionHandler.php | 598 ++++++++++++++++++ .../mcpe/handler/SimpleSessionHandler.php | 241 +++++++ .../mcpe/protocol/AddBehaviorTreePacket.php | 6 +- .../network/mcpe/protocol/AddEntityPacket.php | 6 +- .../mcpe/protocol/AddHangingEntityPacket.php | 6 +- .../mcpe/protocol/AddItemEntityPacket.php | 6 +- .../mcpe/protocol/AddPaintingPacket.php | 6 +- .../network/mcpe/protocol/AddPlayerPacket.php | 6 +- .../mcpe/protocol/AdventureSettingsPacket.php | 6 +- .../network/mcpe/protocol/AnimatePacket.php | 6 +- .../mcpe/protocol/AvailableCommandsPacket.php | 6 +- .../mcpe/protocol/BlockEntityDataPacket.php | 6 +- .../mcpe/protocol/BlockEventPacket.php | 6 +- .../mcpe/protocol/BlockPickRequestPacket.php | 6 +- .../network/mcpe/protocol/BookEditPacket.php | 6 +- .../network/mcpe/protocol/BossEventPacket.php | 6 +- .../network/mcpe/protocol/CameraPacket.php | 6 +- .../mcpe/protocol/ChangeDimensionPacket.php | 6 +- .../protocol/ChunkRadiusUpdatedPacket.php | 6 +- .../ClientToServerHandshakePacket.php | 6 +- .../protocol/ClientboundMapItemDataPacket.php | 6 +- .../protocol/CommandBlockUpdatePacket.php | 6 +- .../mcpe/protocol/CommandOutputPacket.php | 6 +- .../mcpe/protocol/CommandRequestPacket.php | 6 +- .../mcpe/protocol/ContainerClosePacket.php | 6 +- .../mcpe/protocol/ContainerOpenPacket.php | 6 +- .../mcpe/protocol/ContainerSetDataPacket.php | 6 +- .../mcpe/protocol/CraftingDataPacket.php | 6 +- .../mcpe/protocol/CraftingEventPacket.php | 6 +- .../network/mcpe/protocol/DataPacket.php | 16 +- .../mcpe/protocol/DisconnectPacket.php | 6 +- .../mcpe/protocol/EntityEventPacket.php | 6 +- .../mcpe/protocol/EntityFallPacket.php | 6 +- .../mcpe/protocol/EntityPickRequestPacket.php | 6 +- .../network/mcpe/protocol/EventPacket.php | 6 +- .../network/mcpe/protocol/ExplodePacket.php | 6 +- .../mcpe/protocol/FullChunkDataPacket.php | 6 +- .../mcpe/protocol/GameRulesChangedPacket.php | 6 +- .../mcpe/protocol/GuiDataPickItemPacket.php | 6 +- .../network/mcpe/protocol/HurtArmorPacket.php | 6 +- .../network/mcpe/protocol/InteractPacket.php | 6 +- .../mcpe/protocol/InventoryContentPacket.php | 6 +- .../mcpe/protocol/InventorySlotPacket.php | 6 +- .../protocol/InventoryTransactionPacket.php | 6 +- .../mcpe/protocol/ItemFrameDropItemPacket.php | 6 +- .../network/mcpe/protocol/LabTablePacket.php | 6 +- .../mcpe/protocol/LevelEventPacket.php | 6 +- .../mcpe/protocol/LevelSoundEventPacket.php | 6 +- .../network/mcpe/protocol/LoginPacket.php | 6 +- .../mcpe/protocol/MapInfoRequestPacket.php | 6 +- .../mcpe/protocol/MobArmorEquipmentPacket.php | 6 +- .../network/mcpe/protocol/MobEffectPacket.php | 6 +- .../mcpe/protocol/MobEquipmentPacket.php | 6 +- .../mcpe/protocol/ModalFormRequestPacket.php | 6 +- .../mcpe/protocol/ModalFormResponsePacket.php | 6 +- .../protocol/MoveEntityAbsolutePacket.php | 6 +- .../mcpe/protocol/MoveEntityDeltaPacket.php | 6 +- .../mcpe/protocol/MovePlayerPacket.php | 6 +- .../mcpe/protocol/NpcRequestPacket.php | 6 +- .../mcpe/protocol/PhotoTransferPacket.php | 6 +- .../network/mcpe/protocol/PlaySoundPacket.php | 6 +- .../mcpe/protocol/PlayStatusPacket.php | 6 +- .../mcpe/protocol/PlayerActionPacket.php | 6 +- .../mcpe/protocol/PlayerHotbarPacket.php | 6 +- .../mcpe/protocol/PlayerInputPacket.php | 6 +- .../mcpe/protocol/PlayerListPacket.php | 6 +- .../mcpe/protocol/PlayerSkinPacket.php | 6 +- .../mcpe/protocol/PurchaseReceiptPacket.php | 6 +- .../mcpe/protocol/RemoveEntityPacket.php | 6 +- .../mcpe/protocol/RemoveObjectivePacket.php | 6 +- .../protocol/RequestChunkRadiusPacket.php | 6 +- .../protocol/ResourcePackChunkDataPacket.php | 6 +- .../ResourcePackChunkRequestPacket.php | 6 +- .../ResourcePackClientResponsePacket.php | 6 +- .../protocol/ResourcePackDataInfoPacket.php | 6 +- .../mcpe/protocol/ResourcePackStackPacket.php | 6 +- .../mcpe/protocol/ResourcePacksInfoPacket.php | 6 +- .../network/mcpe/protocol/RespawnPacket.php | 6 +- .../network/mcpe/protocol/RiderJumpPacket.php | 6 +- .../protocol/ServerSettingsRequestPacket.php | 6 +- .../protocol/ServerSettingsResponsePacket.php | 6 +- .../ServerToClientHandshakePacket.php | 6 +- .../protocol/SetCommandsEnabledPacket.php | 6 +- .../protocol/SetDefaultGameTypePacket.php | 6 +- .../mcpe/protocol/SetDifficultyPacket.php | 6 +- .../protocol/SetDisplayObjectivePacket.php | 6 +- .../mcpe/protocol/SetEntityDataPacket.php | 6 +- .../mcpe/protocol/SetEntityLinkPacket.php | 6 +- .../mcpe/protocol/SetEntityMotionPacket.php | 6 +- .../network/mcpe/protocol/SetHealthPacket.php | 6 +- .../mcpe/protocol/SetLastHurtByPacket.php | 6 +- .../SetLocalPlayerAsInitializedPacket.php | 6 +- .../mcpe/protocol/SetPlayerGameTypePacket.php | 6 +- .../network/mcpe/protocol/SetScorePacket.php | 6 +- .../mcpe/protocol/SetSpawnPositionPacket.php | 6 +- .../network/mcpe/protocol/SetTimePacket.php | 6 +- .../network/mcpe/protocol/SetTitlePacket.php | 6 +- .../mcpe/protocol/ShowCreditsPacket.php | 6 +- .../mcpe/protocol/ShowProfilePacket.php | 6 +- .../mcpe/protocol/ShowStoreOfferPacket.php | 6 +- .../mcpe/protocol/SimpleEventPacket.php | 6 +- .../protocol/SpawnExperienceOrbPacket.php | 6 +- .../network/mcpe/protocol/StartGamePacket.php | 6 +- .../network/mcpe/protocol/StopSoundPacket.php | 6 +- .../protocol/StructureBlockUpdatePacket.php | 6 +- .../mcpe/protocol/SubClientLoginPacket.php | 6 +- .../mcpe/protocol/TakeItemEntityPacket.php | 6 +- .../network/mcpe/protocol/TextPacket.php | 6 +- .../network/mcpe/protocol/TransferPacket.php | 6 +- .../network/mcpe/protocol/UnknownPacket.php | 4 +- .../mcpe/protocol/UpdateAttributesPacket.php | 6 +- .../mcpe/protocol/UpdateBlockPacket.php | 6 +- .../mcpe/protocol/UpdateBlockSyncedPacket.php | 6 +- .../mcpe/protocol/UpdateEquipPacket.php | 6 +- .../mcpe/protocol/UpdateTradePacket.php | 6 +- .../network/mcpe/protocol/WSConnectPacket.php | 6 +- 117 files changed, 1195 insertions(+), 910 deletions(-) create mode 100644 src/pocketmine/network/mcpe/handler/SessionHandler.php create mode 100644 src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 6d72ea00d2..e23e1d31ba 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -25,120 +25,11 @@ namespace pocketmine\network\mcpe; use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\event\server\DataPacketSendEvent; -use pocketmine\network\mcpe\protocol\AddBehaviorTreePacket; -use pocketmine\network\mcpe\protocol\AddEntityPacket; -use pocketmine\network\mcpe\protocol\AddHangingEntityPacket; -use pocketmine\network\mcpe\protocol\AddItemEntityPacket; -use pocketmine\network\mcpe\protocol\AddPaintingPacket; -use pocketmine\network\mcpe\protocol\AddPlayerPacket; -use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; -use pocketmine\network\mcpe\protocol\AnimatePacket; -use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; -use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; -use pocketmine\network\mcpe\protocol\BlockEventPacket; -use pocketmine\network\mcpe\protocol\BlockPickRequestPacket; -use pocketmine\network\mcpe\protocol\BookEditPacket; -use pocketmine\network\mcpe\protocol\BossEventPacket; -use pocketmine\network\mcpe\protocol\CameraPacket; -use pocketmine\network\mcpe\protocol\ChangeDimensionPacket; -use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; -use pocketmine\network\mcpe\protocol\ClientboundMapItemDataPacket; -use pocketmine\network\mcpe\protocol\ClientToServerHandshakePacket; -use pocketmine\network\mcpe\protocol\CommandBlockUpdatePacket; -use pocketmine\network\mcpe\protocol\CommandOutputPacket; -use pocketmine\network\mcpe\protocol\CommandRequestPacket; -use pocketmine\network\mcpe\protocol\ContainerClosePacket; -use pocketmine\network\mcpe\protocol\ContainerOpenPacket; -use pocketmine\network\mcpe\protocol\ContainerSetDataPacket; -use pocketmine\network\mcpe\protocol\CraftingDataPacket; -use pocketmine\network\mcpe\protocol\CraftingEventPacket; +use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\SimpleSessionHandler; use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\DisconnectPacket; -use pocketmine\network\mcpe\protocol\EntityEventPacket; -use pocketmine\network\mcpe\protocol\EntityFallPacket; -use pocketmine\network\mcpe\protocol\EntityPickRequestPacket; -use pocketmine\network\mcpe\protocol\EventPacket; -use pocketmine\network\mcpe\protocol\ExplodePacket; -use pocketmine\network\mcpe\protocol\FullChunkDataPacket; -use pocketmine\network\mcpe\protocol\GameRulesChangedPacket; -use pocketmine\network\mcpe\protocol\GuiDataPickItemPacket; -use pocketmine\network\mcpe\protocol\HurtArmorPacket; -use pocketmine\network\mcpe\protocol\InteractPacket; -use pocketmine\network\mcpe\protocol\InventoryContentPacket; -use pocketmine\network\mcpe\protocol\InventorySlotPacket; -use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; -use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket; -use pocketmine\network\mcpe\protocol\LabTablePacket; -use pocketmine\network\mcpe\protocol\LevelEventPacket; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; -use pocketmine\network\mcpe\protocol\LoginPacket; -use pocketmine\network\mcpe\protocol\MapInfoRequestPacket; -use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket; -use pocketmine\network\mcpe\protocol\MobEffectPacket; -use pocketmine\network\mcpe\protocol\MobEquipmentPacket; -use pocketmine\network\mcpe\protocol\ModalFormRequestPacket; -use pocketmine\network\mcpe\protocol\ModalFormResponsePacket; -use pocketmine\network\mcpe\protocol\MoveEntityAbsolutePacket; -use pocketmine\network\mcpe\protocol\MoveEntityDeltaPacket; -use pocketmine\network\mcpe\protocol\MovePlayerPacket; -use pocketmine\network\mcpe\protocol\NpcRequestPacket; use pocketmine\network\mcpe\protocol\PacketPool; -use pocketmine\network\mcpe\protocol\PhotoTransferPacket; -use pocketmine\network\mcpe\protocol\PlayerActionPacket; -use pocketmine\network\mcpe\protocol\PlayerHotbarPacket; -use pocketmine\network\mcpe\protocol\PlayerInputPacket; -use pocketmine\network\mcpe\protocol\PlayerListPacket; -use pocketmine\network\mcpe\protocol\PlayerSkinPacket; -use pocketmine\network\mcpe\protocol\PlaySoundPacket; -use pocketmine\network\mcpe\protocol\PlayStatusPacket; -use pocketmine\network\mcpe\protocol\PurchaseReceiptPacket; -use pocketmine\network\mcpe\protocol\RemoveEntityPacket; -use pocketmine\network\mcpe\protocol\RemoveObjectivePacket; -use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; -use pocketmine\network\mcpe\protocol\ResourcePackChunkDataPacket; -use pocketmine\network\mcpe\protocol\ResourcePackChunkRequestPacket; -use pocketmine\network\mcpe\protocol\ResourcePackClientResponsePacket; -use pocketmine\network\mcpe\protocol\ResourcePackDataInfoPacket; -use pocketmine\network\mcpe\protocol\ResourcePacksInfoPacket; -use pocketmine\network\mcpe\protocol\ResourcePackStackPacket; -use pocketmine\network\mcpe\protocol\RespawnPacket; -use pocketmine\network\mcpe\protocol\RiderJumpPacket; -use pocketmine\network\mcpe\protocol\ServerSettingsRequestPacket; -use pocketmine\network\mcpe\protocol\ServerSettingsResponsePacket; -use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket; -use pocketmine\network\mcpe\protocol\SetCommandsEnabledPacket; -use pocketmine\network\mcpe\protocol\SetDefaultGameTypePacket; -use pocketmine\network\mcpe\protocol\SetDifficultyPacket; -use pocketmine\network\mcpe\protocol\SetDisplayObjectivePacket; -use pocketmine\network\mcpe\protocol\SetEntityDataPacket; -use pocketmine\network\mcpe\protocol\SetEntityLinkPacket; -use pocketmine\network\mcpe\protocol\SetEntityMotionPacket; -use pocketmine\network\mcpe\protocol\SetHealthPacket; -use pocketmine\network\mcpe\protocol\SetLastHurtByPacket; -use pocketmine\network\mcpe\protocol\SetLocalPlayerAsInitializedPacket; -use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; -use pocketmine\network\mcpe\protocol\SetScorePacket; -use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket; -use pocketmine\network\mcpe\protocol\SetTimePacket; -use pocketmine\network\mcpe\protocol\SetTitlePacket; -use pocketmine\network\mcpe\protocol\ShowCreditsPacket; -use pocketmine\network\mcpe\protocol\ShowProfilePacket; -use pocketmine\network\mcpe\protocol\ShowStoreOfferPacket; -use pocketmine\network\mcpe\protocol\SimpleEventPacket; -use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket; -use pocketmine\network\mcpe\protocol\StartGamePacket; -use pocketmine\network\mcpe\protocol\StopSoundPacket; -use pocketmine\network\mcpe\protocol\StructureBlockUpdatePacket; -use pocketmine\network\mcpe\protocol\SubClientLoginPacket; -use pocketmine\network\mcpe\protocol\TakeItemEntityPacket; -use pocketmine\network\mcpe\protocol\TextPacket; -use pocketmine\network\mcpe\protocol\TransferPacket; -use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; -use pocketmine\network\mcpe\protocol\UpdateBlockPacket; -use pocketmine\network\mcpe\protocol\UpdateBlockSyncedPacket; -use pocketmine\network\mcpe\protocol\UpdateEquipPacket; -use pocketmine\network\mcpe\protocol\UpdateTradePacket; -use pocketmine\network\mcpe\protocol\WSConnectPacket; use pocketmine\network\NetworkInterface; use pocketmine\Player; use pocketmine\Server; @@ -158,6 +49,9 @@ class NetworkSession{ /** @var int */ private $port; + /** @var SessionHandler */ + private $handler; + public function __construct(Server $server, Player $player, NetworkInterface $interface, string $ip, int $port){ $this->server = $server; $this->player = $player; @@ -165,6 +59,8 @@ class NetworkSession{ $this->ip = $ip; $this->port = $port; + + $this->handler = new SimpleSessionHandler($player); } public function getInterface() : NetworkInterface{ @@ -205,7 +101,7 @@ class NetworkSession{ } $this->server->getPluginManager()->callEvent($ev = new DataPacketReceiveEvent($this->player, $packet)); - if(!$ev->isCancelled() and !$packet->handle($this)){ + if(!$ev->isCancelled() and !$packet->handle($this->handler)){ $this->server->getLogger()->debug("Unhandled " . $packet->getName() . " received from " . $this->player->getName() . ": 0x" . bin2hex($packet->buffer)); } @@ -239,458 +135,4 @@ class NetworkSession{ } $this->interface->close($this->player, $notify ? $reason : ""); } - - public function handleLogin(LoginPacket $packet) : bool{ - return $this->player->handleLogin($packet); - } - - public function handlePlayStatus(PlayStatusPacket $packet) : bool{ - return false; - } - - public function handleServerToClientHandshake(ServerToClientHandshakePacket $packet) : bool{ - return false; - } - - public function handleClientToServerHandshake(ClientToServerHandshakePacket $packet) : bool{ - return false; //TODO - } - - public function handleDisconnect(DisconnectPacket $packet) : bool{ - return false; - } - - public function handleResourcePacksInfo(ResourcePacksInfoPacket $packet) : bool{ - return false; - } - - public function handleResourcePackStack(ResourcePackStackPacket $packet) : bool{ - return false; - } - - public function handleResourcePackClientResponse(ResourcePackClientResponsePacket $packet) : bool{ - return $this->player->handleResourcePackClientResponse($packet); - } - - public function handleText(TextPacket $packet) : bool{ - if($packet->type === TextPacket::TYPE_CHAT){ - return $this->player->chat($packet->message); - } - - return false; - } - - public function handleSetTime(SetTimePacket $packet) : bool{ - return false; - } - - public function handleStartGame(StartGamePacket $packet) : bool{ - return false; - } - - public function handleAddPlayer(AddPlayerPacket $packet) : bool{ - return false; - } - - public function handleAddEntity(AddEntityPacket $packet) : bool{ - return false; - } - - public function handleRemoveEntity(RemoveEntityPacket $packet) : bool{ - return false; - } - - public function handleAddItemEntity(AddItemEntityPacket $packet) : bool{ - return false; - } - - public function handleAddHangingEntity(AddHangingEntityPacket $packet) : bool{ - return false; - } - - public function handleTakeItemEntity(TakeItemEntityPacket $packet) : bool{ - return false; - } - - public function handleMoveEntityAbsolute(MoveEntityAbsolutePacket $packet) : bool{ - return false; - } - - public function handleMovePlayer(MovePlayerPacket $packet) : bool{ - return $this->player->handleMovePlayer($packet); - } - - public function handleRiderJump(RiderJumpPacket $packet) : bool{ - return false; - } - - public function handleUpdateBlock(UpdateBlockPacket $packet) : bool{ - return false; - } - - public function handleAddPainting(AddPaintingPacket $packet) : bool{ - return false; - } - - public function handleExplode(ExplodePacket $packet) : bool{ - return false; - } - - public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{ - return $this->player->handleLevelSoundEvent($packet); - } - - public function handleLevelEvent(LevelEventPacket $packet) : bool{ - return false; - } - - public function handleBlockEvent(BlockEventPacket $packet) : bool{ - return false; - } - - public function handleEntityEvent(EntityEventPacket $packet) : bool{ - return $this->player->handleEntityEvent($packet); - } - - public function handleMobEffect(MobEffectPacket $packet) : bool{ - return false; - } - - public function handleUpdateAttributes(UpdateAttributesPacket $packet) : bool{ - return false; - } - - public function handleInventoryTransaction(InventoryTransactionPacket $packet) : bool{ - return $this->player->handleInventoryTransaction($packet); - } - - public function handleMobEquipment(MobEquipmentPacket $packet) : bool{ - return $this->player->handleMobEquipment($packet); - } - - public function handleMobArmorEquipment(MobArmorEquipmentPacket $packet) : bool{ - return true; //Not used - } - - public function handleInteract(InteractPacket $packet) : bool{ - return $this->player->handleInteract($packet); - } - - public function handleBlockPickRequest(BlockPickRequestPacket $packet) : bool{ - return $this->player->handleBlockPickRequest($packet); - } - - public function handleEntityPickRequest(EntityPickRequestPacket $packet) : bool{ - return false; //TODO - } - - public function handlePlayerAction(PlayerActionPacket $packet) : bool{ - return $this->player->handlePlayerAction($packet); - } - - public function handleEntityFall(EntityFallPacket $packet) : bool{ - return true; //Not used - } - - public function handleHurtArmor(HurtArmorPacket $packet) : bool{ - return false; - } - - public function handleSetEntityData(SetEntityDataPacket $packet) : bool{ - return false; - } - - public function handleSetEntityMotion(SetEntityMotionPacket $packet) : bool{ - return false; - } - - public function handleSetEntityLink(SetEntityLinkPacket $packet) : bool{ - return false; - } - - public function handleSetHealth(SetHealthPacket $packet) : bool{ - return false; - } - - public function handleSetSpawnPosition(SetSpawnPositionPacket $packet) : bool{ - return false; - } - - public function handleAnimate(AnimatePacket $packet) : bool{ - return $this->player->handleAnimate($packet); - } - - public function handleRespawn(RespawnPacket $packet) : bool{ - return false; - } - - public function handleContainerOpen(ContainerOpenPacket $packet) : bool{ - return false; - } - - public function handleContainerClose(ContainerClosePacket $packet) : bool{ - return $this->player->handleContainerClose($packet); - } - - public function handlePlayerHotbar(PlayerHotbarPacket $packet) : bool{ - return true; //this packet is useless - } - - public function handleInventoryContent(InventoryContentPacket $packet) : bool{ - return false; - } - - public function handleInventorySlot(InventorySlotPacket $packet) : bool{ - return false; - } - - public function handleContainerSetData(ContainerSetDataPacket $packet) : bool{ - return false; - } - - public function handleCraftingData(CraftingDataPacket $packet) : bool{ - return false; - } - - public function handleCraftingEvent(CraftingEventPacket $packet) : bool{ - return true; //this is a broken useless packet, so we don't use it - } - - public function handleGuiDataPickItem(GuiDataPickItemPacket $packet) : bool{ - return false; - } - - public function handleAdventureSettings(AdventureSettingsPacket $packet) : bool{ - return $this->player->handleAdventureSettings($packet); - } - - public function handleBlockEntityData(BlockEntityDataPacket $packet) : bool{ - return $this->player->handleBlockEntityData($packet); - } - - public function handlePlayerInput(PlayerInputPacket $packet) : bool{ - return false; //TODO - } - - public function handleFullChunkData(FullChunkDataPacket $packet) : bool{ - return false; - } - - public function handleSetCommandsEnabled(SetCommandsEnabledPacket $packet) : bool{ - return false; - } - - public function handleSetDifficulty(SetDifficultyPacket $packet) : bool{ - return false; - } - - public function handleChangeDimension(ChangeDimensionPacket $packet) : bool{ - return false; - } - - public function handleSetPlayerGameType(SetPlayerGameTypePacket $packet) : bool{ - return $this->player->handleSetPlayerGameType($packet); - } - - public function handlePlayerList(PlayerListPacket $packet) : bool{ - return false; - } - - public function handleSimpleEvent(SimpleEventPacket $packet) : bool{ - return false; - } - - public function handleEvent(EventPacket $packet) : bool{ - return false; - } - - public function handleSpawnExperienceOrb(SpawnExperienceOrbPacket $packet) : bool{ - return false; //TODO - } - - public function handleClientboundMapItemData(ClientboundMapItemDataPacket $packet) : bool{ - return false; - } - - public function handleMapInfoRequest(MapInfoRequestPacket $packet) : bool{ - return false; //TODO - } - - public function handleRequestChunkRadius(RequestChunkRadiusPacket $packet) : bool{ - $this->player->setViewDistance($packet->radius); - - return true; - } - - public function handleChunkRadiusUpdated(ChunkRadiusUpdatedPacket $packet) : bool{ - return false; - } - - public function handleItemFrameDropItem(ItemFrameDropItemPacket $packet) : bool{ - return $this->player->handleItemFrameDropItem($packet); - } - - public function handleGameRulesChanged(GameRulesChangedPacket $packet) : bool{ - return false; - } - - public function handleCamera(CameraPacket $packet) : bool{ - return false; - } - - public function handleBossEvent(BossEventPacket $packet) : bool{ - return false; //TODO - } - - public function handleShowCredits(ShowCreditsPacket $packet) : bool{ - return false; //TODO: handle resume - } - - public function handleAvailableCommands(AvailableCommandsPacket $packet) : bool{ - return false; - } - - public function handleCommandRequest(CommandRequestPacket $packet) : bool{ - return $this->player->chat($packet->command); - } - - public function handleCommandBlockUpdate(CommandBlockUpdatePacket $packet) : bool{ - return false; //TODO - } - - public function handleCommandOutput(CommandOutputPacket $packet) : bool{ - return false; - } - - public function handleUpdateTrade(UpdateTradePacket $packet) : bool{ - return false; - } - - public function handleUpdateEquip(UpdateEquipPacket $packet) : bool{ - return false; - } - - public function handleResourcePackDataInfo(ResourcePackDataInfoPacket $packet) : bool{ - return false; - } - - public function handleResourcePackChunkData(ResourcePackChunkDataPacket $packet) : bool{ - return false; - } - - public function handleResourcePackChunkRequest(ResourcePackChunkRequestPacket $packet) : bool{ - return $this->player->handleResourcePackChunkRequest($packet); - } - - public function handleTransfer(TransferPacket $packet) : bool{ - return false; - } - - public function handlePlaySound(PlaySoundPacket $packet) : bool{ - return false; - } - - public function handleStopSound(StopSoundPacket $packet) : bool{ - return false; - } - - public function handleSetTitle(SetTitlePacket $packet) : bool{ - return false; - } - - public function handleAddBehaviorTree(AddBehaviorTreePacket $packet) : bool{ - return false; - } - - public function handleStructureBlockUpdate(StructureBlockUpdatePacket $packet) : bool{ - return false; - } - - public function handleShowStoreOffer(ShowStoreOfferPacket $packet) : bool{ - return false; - } - - public function handlePurchaseReceipt(PurchaseReceiptPacket $packet) : bool{ - return false; - } - - public function handlePlayerSkin(PlayerSkinPacket $packet) : bool{ - return $this->player->changeSkin($packet->skin, $packet->newSkinName, $packet->oldSkinName); - } - - public function handleSubClientLogin(SubClientLoginPacket $packet) : bool{ - return false; - } - - public function handleWSConnect(WSConnectPacket $packet) : bool{ - return false; - } - - public function handleSetLastHurtBy(SetLastHurtByPacket $packet) : bool{ - return false; - } - - public function handleBookEdit(BookEditPacket $packet) : bool{ - return $this->player->handleBookEdit($packet); - } - - public function handleNpcRequest(NpcRequestPacket $packet) : bool{ - return false; - } - - public function handlePhotoTransfer(PhotoTransferPacket $packet) : bool{ - return false; - } - - public function handleModalFormRequest(ModalFormRequestPacket $packet) : bool{ - return false; - } - - public function handleModalFormResponse(ModalFormResponsePacket $packet) : bool{ - return false; //TODO: GUI stuff - } - - public function handleServerSettingsRequest(ServerSettingsRequestPacket $packet) : bool{ - return false; //TODO: GUI stuff - } - - public function handleServerSettingsResponse(ServerSettingsResponsePacket $packet) : bool{ - return false; - } - - public function handleShowProfile(ShowProfilePacket $packet) : bool{ - return false; - } - - public function handleSetDefaultGameType(SetDefaultGameTypePacket $packet) : bool{ - return false; - } - - public function handleRemoveObjective(RemoveObjectivePacket $packet) : bool{ - return false; - } - - public function handleSetDisplayObjective(SetDisplayObjectivePacket $packet) : bool{ - return false; - } - - public function handleSetScore(SetScorePacket $packet) : bool{ - return false; - } - - public function handleLabTable(LabTablePacket $packet) : bool{ - return false; - } - - public function handleUpdateBlockSynced(UpdateBlockSyncedPacket $packet) : bool{ - return false; - } - - public function handleMoveEntityDelta(MoveEntityDeltaPacket $packet) : bool{ - return false; - } - - public function handleSetLocalPlayerAsInitialized(SetLocalPlayerAsInitializedPacket $packet) : bool{ - return false; - } } diff --git a/src/pocketmine/network/mcpe/handler/SessionHandler.php b/src/pocketmine/network/mcpe/handler/SessionHandler.php new file mode 100644 index 0000000000..5ebc11b436 --- /dev/null +++ b/src/pocketmine/network/mcpe/handler/SessionHandler.php @@ -0,0 +1,598 @@ +player = $player; + } + + public function handleLogin(LoginPacket $packet) : bool{ + return $this->player->handleLogin($packet); + } + + public function handleClientToServerHandshake(ClientToServerHandshakePacket $packet) : bool{ + return false; //TODO + } + + public function handleResourcePackClientResponse(ResourcePackClientResponsePacket $packet) : bool{ + return $this->player->handleResourcePackClientResponse($packet); + } + + public function handleText(TextPacket $packet) : bool{ + if($packet->type === TextPacket::TYPE_CHAT){ + return $this->player->chat($packet->message); + } + + return false; + } + + public function handleMovePlayer(MovePlayerPacket $packet) : bool{ + return $this->player->handleMovePlayer($packet); + } + + public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{ + return $this->player->handleLevelSoundEvent($packet); + } + + public function handleEntityEvent(EntityEventPacket $packet) : bool{ + return $this->player->handleEntityEvent($packet); + } + + public function handleInventoryTransaction(InventoryTransactionPacket $packet) : bool{ + return $this->player->handleInventoryTransaction($packet); + } + + public function handleMobEquipment(MobEquipmentPacket $packet) : bool{ + return $this->player->handleMobEquipment($packet); + } + + public function handleMobArmorEquipment(MobArmorEquipmentPacket $packet) : bool{ + return true; //Not used + } + + public function handleInteract(InteractPacket $packet) : bool{ + return $this->player->handleInteract($packet); + } + + public function handleBlockPickRequest(BlockPickRequestPacket $packet) : bool{ + return $this->player->handleBlockPickRequest($packet); + } + + public function handleEntityPickRequest(EntityPickRequestPacket $packet) : bool{ + return false; //TODO + } + + public function handlePlayerAction(PlayerActionPacket $packet) : bool{ + return $this->player->handlePlayerAction($packet); + } + + public function handleEntityFall(EntityFallPacket $packet) : bool{ + return true; //Not used + } + + public function handleAnimate(AnimatePacket $packet) : bool{ + return $this->player->handleAnimate($packet); + } + + public function handleContainerClose(ContainerClosePacket $packet) : bool{ + return $this->player->handleContainerClose($packet); + } + + public function handlePlayerHotbar(PlayerHotbarPacket $packet) : bool{ + return true; //this packet is useless + } + + public function handleCraftingEvent(CraftingEventPacket $packet) : bool{ + return true; //this is a broken useless packet, so we don't use it + } + + public function handleAdventureSettings(AdventureSettingsPacket $packet) : bool{ + return $this->player->handleAdventureSettings($packet); + } + + public function handleBlockEntityData(BlockEntityDataPacket $packet) : bool{ + return $this->player->handleBlockEntityData($packet); + } + + public function handlePlayerInput(PlayerInputPacket $packet) : bool{ + return false; //TODO + } + + public function handleSetPlayerGameType(SetPlayerGameTypePacket $packet) : bool{ + return $this->player->handleSetPlayerGameType($packet); + } + + public function handleSpawnExperienceOrb(SpawnExperienceOrbPacket $packet) : bool{ + return false; //TODO + } + + public function handleMapInfoRequest(MapInfoRequestPacket $packet) : bool{ + return false; //TODO + } + + public function handleRequestChunkRadius(RequestChunkRadiusPacket $packet) : bool{ + $this->player->setViewDistance($packet->radius); + + return true; + } + + public function handleItemFrameDropItem(ItemFrameDropItemPacket $packet) : bool{ + return $this->player->handleItemFrameDropItem($packet); + } + + public function handleBossEvent(BossEventPacket $packet) : bool{ + return false; //TODO + } + + public function handleShowCredits(ShowCreditsPacket $packet) : bool{ + return false; //TODO: handle resume + } + + public function handleCommandRequest(CommandRequestPacket $packet) : bool{ + return $this->player->chat($packet->command); + } + + public function handleCommandBlockUpdate(CommandBlockUpdatePacket $packet) : bool{ + return false; //TODO + } + + public function handleResourcePackChunkRequest(ResourcePackChunkRequestPacket $packet) : bool{ + return $this->player->handleResourcePackChunkRequest($packet); + } + + public function handlePlayerSkin(PlayerSkinPacket $packet) : bool{ + return $this->player->changeSkin($packet->skin, $packet->newSkinName, $packet->oldSkinName); + } + + public function handleSubClientLogin(SubClientLoginPacket $packet) : bool{ + return false; //TODO + } + + public function handleBookEdit(BookEditPacket $packet) : bool{ + return $this->player->handleBookEdit($packet); + } + + public function handleModalFormResponse(ModalFormResponsePacket $packet) : bool{ + return false; //TODO: GUI stuff + } + + public function handleServerSettingsRequest(ServerSettingsRequestPacket $packet) : bool{ + return false; //TODO: GUI stuff + } + + public function handleLabTable(LabTablePacket $packet) : bool{ + return false; //TODO + } + + public function handleSetLocalPlayerAsInitialized(SetLocalPlayerAsInitializedPacket $packet) : bool{ + return false; //TODO + } +} diff --git a/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php b/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php index 545e7988db..8472b1b450 100644 --- a/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class AddBehaviorTreePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::ADD_BEHAVIOR_TREE_PACKET; @@ -41,7 +41,7 @@ class AddBehaviorTreePacket extends DataPacket{ $this->putString($this->behaviorTreeJson); } - public function handle(NetworkSession $session) : bool{ - return $session->handleAddBehaviorTree($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleAddBehaviorTree($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php b/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php index 3c8398364a..5ea109c7f2 100644 --- a/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\entity\Attribute; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\EntityLink; class AddEntityPacket extends DataPacket{ @@ -117,7 +117,7 @@ class AddEntityPacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleAddEntity($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleAddEntity($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/AddHangingEntityPacket.php b/src/pocketmine/network/mcpe/protocol/AddHangingEntityPacket.php index 871dd6a796..032de9f55d 100644 --- a/src/pocketmine/network/mcpe/protocol/AddHangingEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddHangingEntityPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class AddHangingEntityPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::ADD_HANGING_ENTITY_PACKET; @@ -57,7 +57,7 @@ class AddHangingEntityPacket extends DataPacket{ $this->putVarInt($this->direction); } - public function handle(NetworkSession $session) : bool{ - return $session->handleAddHangingEntity($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleAddHangingEntity($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/AddItemEntityPacket.php b/src/pocketmine/network/mcpe/protocol/AddItemEntityPacket.php index f3d24b052b..ff1a32dbd1 100644 --- a/src/pocketmine/network/mcpe/protocol/AddItemEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddItemEntityPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\item\Item; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class AddItemEntityPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::ADD_ITEM_ENTITY_PACKET; @@ -67,7 +67,7 @@ class AddItemEntityPacket extends DataPacket{ $this->putBool($this->isFromFishing); } - public function handle(NetworkSession $session) : bool{ - return $session->handleAddItemEntity($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleAddItemEntity($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/AddPaintingPacket.php b/src/pocketmine/network/mcpe/protocol/AddPaintingPacket.php index a69560ce66..a1997e3383 100644 --- a/src/pocketmine/network/mcpe/protocol/AddPaintingPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddPaintingPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class AddPaintingPacket extends AddHangingEntityPacket{ public const NETWORK_ID = ProtocolInfo::ADD_PAINTING_PACKET; @@ -44,7 +44,7 @@ class AddPaintingPacket extends AddHangingEntityPacket{ $this->putString($this->title); } - public function handle(NetworkSession $session) : bool{ - return $session->handleAddPainting($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleAddPainting($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php b/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php index 675f6c3cda..1550119923 100644 --- a/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\item\Item; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\EntityLink; use pocketmine\utils\UUID; @@ -135,7 +135,7 @@ class AddPlayerPacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleAddPlayer($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleAddPlayer($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php b/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php index ff084a0187..b98739fde7 100644 --- a/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; class AdventureSettingsPacket extends DataPacket{ @@ -116,7 +116,7 @@ class AdventureSettingsPacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleAdventureSettings($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleAdventureSettings($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/AnimatePacket.php b/src/pocketmine/network/mcpe/protocol/AnimatePacket.php index cabc2889c9..22ec0ccd05 100644 --- a/src/pocketmine/network/mcpe/protocol/AnimatePacket.php +++ b/src/pocketmine/network/mcpe/protocol/AnimatePacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class AnimatePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::ANIMATE_PACKET; @@ -59,7 +59,7 @@ class AnimatePacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleAnimate($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleAnimate($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php index 8806360b1a..b0ccbae047 100644 --- a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\CommandData; use pocketmine\network\mcpe\protocol\types\CommandEnum; use pocketmine\network\mcpe\protocol\types\CommandParameter; @@ -336,7 +336,7 @@ class AvailableCommandsPacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleAvailableCommands($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleAvailableCommands($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php b/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php index e5938f94c2..6e06e38b2d 100644 --- a/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class BlockEntityDataPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::BLOCK_ENTITY_DATA_PACKET; @@ -50,7 +50,7 @@ class BlockEntityDataPacket extends DataPacket{ $this->put($this->namedtag); } - public function handle(NetworkSession $session) : bool{ - return $session->handleBlockEntityData($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleBlockEntityData($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php b/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php index 1ec8f6b4ce..462e4d9e59 100644 --- a/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class BlockEventPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::BLOCK_EVENT_PACKET; @@ -54,7 +54,7 @@ class BlockEventPacket extends DataPacket{ $this->putVarInt($this->eventData); } - public function handle(NetworkSession $session) : bool{ - return $session->handleBlockEvent($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleBlockEvent($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php b/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php index b3a7da89ad..1bc27cef1a 100644 --- a/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class BlockPickRequestPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::BLOCK_PICK_REQUEST_PACKET; @@ -55,7 +55,7 @@ class BlockPickRequestPacket extends DataPacket{ $this->putByte($this->hotbarSlot); } - public function handle(NetworkSession $session) : bool{ - return $session->handleBlockPickRequest($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleBlockPickRequest($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/BookEditPacket.php b/src/pocketmine/network/mcpe/protocol/BookEditPacket.php index 0163b181a7..961ee1a815 100644 --- a/src/pocketmine/network/mcpe/protocol/BookEditPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BookEditPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class BookEditPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::BOOK_EDIT_PACKET; @@ -113,7 +113,7 @@ class BookEditPacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleBookEdit($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleBookEdit($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/BossEventPacket.php b/src/pocketmine/network/mcpe/protocol/BossEventPacket.php index 49739532c8..89a9be3541 100644 --- a/src/pocketmine/network/mcpe/protocol/BossEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BossEventPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class BossEventPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::BOSS_EVENT_PACKET; @@ -126,7 +126,7 @@ class BossEventPacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleBossEvent($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleBossEvent($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/CameraPacket.php b/src/pocketmine/network/mcpe/protocol/CameraPacket.php index e022fb1da3..6e211d5166 100644 --- a/src/pocketmine/network/mcpe/protocol/CameraPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CameraPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class CameraPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::CAMERA_PACKET; @@ -45,7 +45,7 @@ class CameraPacket extends DataPacket{ $this->putEntityUniqueId($this->playerUniqueId); } - public function handle(NetworkSession $session) : bool{ - return $session->handleCamera($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleCamera($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ChangeDimensionPacket.php b/src/pocketmine/network/mcpe/protocol/ChangeDimensionPacket.php index 2177bf6c1a..90f4870003 100644 --- a/src/pocketmine/network/mcpe/protocol/ChangeDimensionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ChangeDimensionPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class ChangeDimensionPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::CHANGE_DIMENSION_PACKET; @@ -51,7 +51,7 @@ class ChangeDimensionPacket extends DataPacket{ $this->putBool($this->respawn); } - public function handle(NetworkSession $session) : bool{ - return $session->handleChangeDimension($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleChangeDimension($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php b/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php index 231028525f..cf6ec6ef88 100644 --- a/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class ChunkRadiusUpdatedPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::CHUNK_RADIUS_UPDATED_PACKET; @@ -42,7 +42,7 @@ class ChunkRadiusUpdatedPacket extends DataPacket{ $this->putVarInt($this->radius); } - public function handle(NetworkSession $session) : bool{ - return $session->handleChunkRadiusUpdated($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleChunkRadiusUpdated($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ClientToServerHandshakePacket.php b/src/pocketmine/network/mcpe/protocol/ClientToServerHandshakePacket.php index c6a386ae12..0e42af7bb6 100644 --- a/src/pocketmine/network/mcpe/protocol/ClientToServerHandshakePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ClientToServerHandshakePacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class ClientToServerHandshakePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::CLIENT_TO_SERVER_HANDSHAKE_PACKET; @@ -43,7 +43,7 @@ class ClientToServerHandshakePacket extends DataPacket{ //No payload } - public function handle(NetworkSession $session) : bool{ - return $session->handleClientToServerHandshake($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleClientToServerHandshake($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php b/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php index fb20e9dea6..48b1695dd7 100644 --- a/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\protocol\types\MapTrackedObject; use pocketmine\utils\Color; @@ -194,7 +194,7 @@ class ClientboundMapItemDataPacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleClientboundMapItemData($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleClientboundMapItemData($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php b/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php index a0d8de69b0..d3c5a607d9 100644 --- a/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php +++ b/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class CommandBlockUpdatePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::COMMAND_BLOCK_UPDATE_PACKET; @@ -99,7 +99,7 @@ class CommandBlockUpdatePacket extends DataPacket{ $this->putBool($this->shouldTrackOutput); } - public function handle(NetworkSession $session) : bool{ - return $session->handleCommandBlockUpdate($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleCommandBlockUpdate($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php b/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php index 5d4cbb99a9..e60914b13e 100644 --- a/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\CommandOriginData; use pocketmine\network\mcpe\protocol\types\CommandOutputMessage; @@ -95,7 +95,7 @@ class CommandOutputPacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleCommandOutput($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleCommandOutput($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/CommandRequestPacket.php b/src/pocketmine/network/mcpe/protocol/CommandRequestPacket.php index f15414f120..11312d8150 100644 --- a/src/pocketmine/network/mcpe/protocol/CommandRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CommandRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\CommandOriginData; class CommandRequestPacket extends DataPacket{ @@ -50,7 +50,7 @@ class CommandRequestPacket extends DataPacket{ $this->putBool($this->isInternal); } - public function handle(NetworkSession $session) : bool{ - return $session->handleCommandRequest($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleCommandRequest($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php b/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php index f50e0a29fd..679b9f92f6 100644 --- a/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class ContainerClosePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::CONTAINER_CLOSE_PACKET; @@ -42,7 +42,7 @@ class ContainerClosePacket extends DataPacket{ $this->putByte($this->windowId); } - public function handle(NetworkSession $session) : bool{ - return $session->handleContainerClose($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleContainerClose($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php b/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php index 0b9f8da0ca..82fd3a18f7 100644 --- a/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class ContainerOpenPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::CONTAINER_OPEN_PACKET; @@ -58,7 +58,7 @@ class ContainerOpenPacket extends DataPacket{ $this->putEntityUniqueId($this->entityUniqueId); } - public function handle(NetworkSession $session) : bool{ - return $session->handleContainerOpen($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleContainerOpen($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php b/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php index 1242de2d5b..08a83861f3 100644 --- a/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class ContainerSetDataPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::CONTAINER_SET_DATA_PACKET; @@ -60,7 +60,7 @@ class ContainerSetDataPacket extends DataPacket{ $this->putVarInt($this->value); } - public function handle(NetworkSession $session) : bool{ - return $session->handleContainerSetData($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleContainerSetData($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php b/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php index 94dc2e12be..08fac729fe 100644 --- a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php @@ -30,8 +30,8 @@ use pocketmine\inventory\FurnaceRecipe; use pocketmine\inventory\ShapedRecipe; use pocketmine\inventory\ShapelessRecipe; use pocketmine\item\Item; +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\NetworkBinaryStream; -use pocketmine\network\mcpe\NetworkSession; class CraftingDataPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::CRAFTING_DATA_PACKET; @@ -215,7 +215,7 @@ class CraftingDataPacket extends DataPacket{ $this->putBool($this->cleanRecipes); } - public function handle(NetworkSession $session) : bool{ - return $session->handleCraftingData($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleCraftingData($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/CraftingEventPacket.php b/src/pocketmine/network/mcpe/protocol/CraftingEventPacket.php index cc48a21fd0..7b6332f15f 100644 --- a/src/pocketmine/network/mcpe/protocol/CraftingEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CraftingEventPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\item\Item; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\utils\UUID; class CraftingEventPacket extends DataPacket{ @@ -81,7 +81,7 @@ class CraftingEventPacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleCraftingEvent($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleCraftingEvent($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/DataPacket.php b/src/pocketmine/network/mcpe/protocol/DataPacket.php index 9e05043dbe..b30e066afb 100644 --- a/src/pocketmine/network/mcpe/protocol/DataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/DataPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\NetworkBinaryStream; -use pocketmine\network\mcpe\NetworkSession; use pocketmine\utils\Utils; abstract class DataPacket extends NetworkBinaryStream{ @@ -105,16 +105,20 @@ abstract class DataPacket extends NetworkBinaryStream{ } /** - * Performs handling for this packet. Usually you'll want an appropriately named method in the NetworkSession for this. + * Performs handling for this packet. Usually you'll want an appropriately named method in the session handler for + * this. * - * This method returns a bool to indicate whether the packet was handled or not. If the packet was unhandled, a debug message will be logged with a hexdump of the packet. - * Typically this method returns the return value of the handler in the supplied NetworkSession. See other packets for examples how to implement this. + * This method returns a bool to indicate whether the packet was handled or not. If the packet was unhandled, a + * debug message will be logged with a hexdump of the packet. * - * @param NetworkSession $session + * Typically this method returns the return value of the handler in the supplied SessionHandler. See other packets + * for examples how to implement this. + * + * @param SessionHandler $handler * * @return bool true if the packet was handled successfully, false if not. */ - abstract public function handle(NetworkSession $session) : bool; + abstract public function handle(SessionHandler $handler) : bool; public function clean(){ $this->buffer = null; diff --git a/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php b/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php index e8207306f3..722efbe2dd 100644 --- a/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php +++ b/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class DisconnectPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::DISCONNECT_PACKET; @@ -54,7 +54,7 @@ class DisconnectPacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleDisconnect($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleDisconnect($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php b/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php index 5d6344b4b1..b6ff4173a7 100644 --- a/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class EntityEventPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::ENTITY_EVENT_PACKET; @@ -102,7 +102,7 @@ class EntityEventPacket extends DataPacket{ $this->putVarInt($this->data); } - public function handle(NetworkSession $session) : bool{ - return $session->handleEntityEvent($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleEntityEvent($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/EntityFallPacket.php b/src/pocketmine/network/mcpe/protocol/EntityFallPacket.php index 490d6fd6db..4c0001df84 100644 --- a/src/pocketmine/network/mcpe/protocol/EntityFallPacket.php +++ b/src/pocketmine/network/mcpe/protocol/EntityFallPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class EntityFallPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::ENTITY_FALL_PACKET; @@ -50,7 +50,7 @@ class EntityFallPacket extends DataPacket{ $this->putBool($this->isInVoid); } - public function handle(NetworkSession $session) : bool{ - return $session->handleEntityFall($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleEntityFall($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/EntityPickRequestPacket.php b/src/pocketmine/network/mcpe/protocol/EntityPickRequestPacket.php index 8bb6b156da..f2d1a89aa4 100644 --- a/src/pocketmine/network/mcpe/protocol/EntityPickRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/EntityPickRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class EntityPickRequestPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::ENTITY_PICK_REQUEST_PACKET; @@ -45,7 +45,7 @@ class EntityPickRequestPacket extends DataPacket{ $this->putByte($this->hotbarSlot); } - public function handle(NetworkSession $session) : bool{ - return $session->handleEntityPickRequest($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleEntityPickRequest($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/EventPacket.php b/src/pocketmine/network/mcpe/protocol/EventPacket.php index d5ce93c832..bcf4f71e5d 100644 --- a/src/pocketmine/network/mcpe/protocol/EventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/EventPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class EventPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::EVENT_PACKET; @@ -64,7 +64,7 @@ class EventPacket extends DataPacket{ //TODO: also nice confusing mess } - public function handle(NetworkSession $session) : bool{ - return $session->handleEvent($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleEvent($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ExplodePacket.php b/src/pocketmine/network/mcpe/protocol/ExplodePacket.php index 8740d28961..3ac3cbbd7b 100644 --- a/src/pocketmine/network/mcpe/protocol/ExplodePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ExplodePacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class ExplodePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::EXPLODE_PACKET; @@ -66,7 +66,7 @@ class ExplodePacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleExplode($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleExplode($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/FullChunkDataPacket.php b/src/pocketmine/network/mcpe/protocol/FullChunkDataPacket.php index 5497267940..f1528d1616 100644 --- a/src/pocketmine/network/mcpe/protocol/FullChunkDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/FullChunkDataPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class FullChunkDataPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::FULL_CHUNK_DATA_PACKET; @@ -50,7 +50,7 @@ class FullChunkDataPacket extends DataPacket{ $this->putString($this->data); } - public function handle(NetworkSession $session) : bool{ - return $session->handleFullChunkData($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleFullChunkData($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/GameRulesChangedPacket.php b/src/pocketmine/network/mcpe/protocol/GameRulesChangedPacket.php index c7865588eb..a807e5cae5 100644 --- a/src/pocketmine/network/mcpe/protocol/GameRulesChangedPacket.php +++ b/src/pocketmine/network/mcpe/protocol/GameRulesChangedPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class GameRulesChangedPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::GAME_RULES_CHANGED_PACKET; @@ -41,7 +41,7 @@ class GameRulesChangedPacket extends DataPacket{ $this->putGameRules($this->gameRules); } - public function handle(NetworkSession $session) : bool{ - return $session->handleGameRulesChanged($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleGameRulesChanged($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/GuiDataPickItemPacket.php b/src/pocketmine/network/mcpe/protocol/GuiDataPickItemPacket.php index 8341595525..4b2034bd45 100644 --- a/src/pocketmine/network/mcpe/protocol/GuiDataPickItemPacket.php +++ b/src/pocketmine/network/mcpe/protocol/GuiDataPickItemPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class GuiDataPickItemPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::GUI_DATA_PICK_ITEM_PACKET; @@ -41,7 +41,7 @@ class GuiDataPickItemPacket extends DataPacket{ $this->putLInt($this->hotbarSlot); } - public function handle(NetworkSession $session) : bool{ - return $session->handleGuiDataPickItem($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleGuiDataPickItem($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/HurtArmorPacket.php b/src/pocketmine/network/mcpe/protocol/HurtArmorPacket.php index ba557a2b24..e55a7638dd 100644 --- a/src/pocketmine/network/mcpe/protocol/HurtArmorPacket.php +++ b/src/pocketmine/network/mcpe/protocol/HurtArmorPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class HurtArmorPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::HURT_ARMOR_PACKET; @@ -42,7 +42,7 @@ class HurtArmorPacket extends DataPacket{ $this->putVarInt($this->health); } - public function handle(NetworkSession $session) : bool{ - return $session->handleHurtArmor($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleHurtArmor($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/InteractPacket.php b/src/pocketmine/network/mcpe/protocol/InteractPacket.php index eea2d30f14..184b583b80 100644 --- a/src/pocketmine/network/mcpe/protocol/InteractPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InteractPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class InteractPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::INTERACT_PACKET; @@ -71,7 +71,7 @@ class InteractPacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleInteract($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleInteract($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php b/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php index bb6e6eebc5..bf37bf9643 100644 --- a/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\item\Item; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class InventoryContentPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::INVENTORY_CONTENT_PACKET; @@ -52,7 +52,7 @@ class InventoryContentPacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleInventoryContent($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleInventoryContent($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php b/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php index 2eff470d40..f6bf664357 100644 --- a/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\item\Item; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class InventorySlotPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::INVENTORY_SLOT_PACKET; @@ -50,7 +50,7 @@ class InventorySlotPacket extends DataPacket{ $this->putSlot($this->item); } - public function handle(NetworkSession $session) : bool{ - return $session->handleInventorySlot($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleInventorySlot($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php b/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php index 90d09bc323..e6f57ac27d 100644 --- a/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\NetworkInventoryAction; class InventoryTransactionPacket extends DataPacket{ @@ -151,7 +151,7 @@ class InventoryTransactionPacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleInventoryTransaction($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleInventoryTransaction($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ItemFrameDropItemPacket.php b/src/pocketmine/network/mcpe/protocol/ItemFrameDropItemPacket.php index 989c490800..2b16febee4 100644 --- a/src/pocketmine/network/mcpe/protocol/ItemFrameDropItemPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ItemFrameDropItemPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class ItemFrameDropItemPacket extends DataPacket{ @@ -46,7 +46,7 @@ class ItemFrameDropItemPacket extends DataPacket{ $this->putBlockPosition($this->x, $this->y, $this->z); } - public function handle(NetworkSession $session) : bool{ - return $session->handleItemFrameDropItem($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleItemFrameDropItem($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/LabTablePacket.php b/src/pocketmine/network/mcpe/protocol/LabTablePacket.php index f5d6f4f930..3291a7dae0 100644 --- a/src/pocketmine/network/mcpe/protocol/LabTablePacket.php +++ b/src/pocketmine/network/mcpe/protocol/LabTablePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class LabTablePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::LAB_TABLE_PACKET; @@ -55,7 +55,7 @@ class LabTablePacket extends DataPacket{ $this->putByte($this->reactionType); } - public function handle(NetworkSession $session) : bool{ - return $session->handleLabTable($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleLabTable($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php b/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php index a0f9fd92ed..01f422f81a 100644 --- a/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class LevelEventPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::LEVEL_EVENT_PACKET; @@ -130,7 +130,7 @@ class LevelEventPacket extends DataPacket{ $this->putVarInt($this->data); } - public function handle(NetworkSession $session) : bool{ - return $session->handleLevelEvent($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleLevelEvent($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacket.php b/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacket.php index f9e330dd09..c98dbf2d0b 100644 --- a/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class LevelSoundEventPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::LEVEL_SOUND_EVENT_PACKET; @@ -275,7 +275,7 @@ class LevelSoundEventPacket extends DataPacket{ $this->putBool($this->disableRelativeVolume); } - public function handle(NetworkSession $session) : bool{ - return $session->handleLevelSoundEvent($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleLevelSoundEvent($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/LoginPacket.php b/src/pocketmine/network/mcpe/protocol/LoginPacket.php index 60d28dbac1..af971f9522 100644 --- a/src/pocketmine/network/mcpe/protocol/LoginPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LoginPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\utils\BinaryStream; use pocketmine\utils\MainLogger; use pocketmine\utils\Utils; @@ -143,7 +143,7 @@ class LoginPacket extends DataPacket{ //TODO } - public function handle(NetworkSession $session) : bool{ - return $session->handleLogin($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleLogin($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/MapInfoRequestPacket.php b/src/pocketmine/network/mcpe/protocol/MapInfoRequestPacket.php index 68b2a5d649..04199d698a 100644 --- a/src/pocketmine/network/mcpe/protocol/MapInfoRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MapInfoRequestPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class MapInfoRequestPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::MAP_INFO_REQUEST_PACKET; @@ -43,7 +43,7 @@ class MapInfoRequestPacket extends DataPacket{ $this->putEntityUniqueId($this->mapId); } - public function handle(NetworkSession $session) : bool{ - return $session->handleMapInfoRequest($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleMapInfoRequest($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php b/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php index 53131172df..214b73f83f 100644 --- a/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\item\Item; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class MobArmorEquipmentPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::MOB_ARMOR_EQUIPMENT_PACKET; @@ -51,7 +51,7 @@ class MobArmorEquipmentPacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleMobArmorEquipment($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleMobArmorEquipment($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php b/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php index ccb43c5354..f95c5a0989 100644 --- a/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class MobEffectPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::MOB_EFFECT_PACKET; @@ -66,7 +66,7 @@ class MobEffectPacket extends DataPacket{ $this->putVarInt($this->duration); } - public function handle(NetworkSession $session) : bool{ - return $session->handleMobEffect($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleMobEffect($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php b/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php index 428f25b4bf..21661c6c47 100644 --- a/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\item\Item; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class MobEquipmentPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::MOB_EQUIPMENT_PACKET; @@ -59,7 +59,7 @@ class MobEquipmentPacket extends DataPacket{ $this->putByte($this->windowId); } - public function handle(NetworkSession $session) : bool{ - return $session->handleMobEquipment($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleMobEquipment($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php b/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php index bc6fc0b240..92cc5d8712 100644 --- a/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class ModalFormRequestPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::MODAL_FORM_REQUEST_PACKET; @@ -45,7 +45,7 @@ class ModalFormRequestPacket extends DataPacket{ $this->putString($this->formData); } - public function handle(NetworkSession $session) : bool{ - return $session->handleModalFormRequest($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleModalFormRequest($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ModalFormResponsePacket.php b/src/pocketmine/network/mcpe/protocol/ModalFormResponsePacket.php index ca888ee969..9300507c64 100644 --- a/src/pocketmine/network/mcpe/protocol/ModalFormResponsePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ModalFormResponsePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class ModalFormResponsePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::MODAL_FORM_RESPONSE_PACKET; @@ -45,7 +45,7 @@ class ModalFormResponsePacket extends DataPacket{ $this->putString($this->formData); } - public function handle(NetworkSession $session) : bool{ - return $session->handleModalFormResponse($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleModalFormResponse($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/MoveEntityAbsolutePacket.php b/src/pocketmine/network/mcpe/protocol/MoveEntityAbsolutePacket.php index 0d02d2dc22..34c1d1eab5 100644 --- a/src/pocketmine/network/mcpe/protocol/MoveEntityAbsolutePacket.php +++ b/src/pocketmine/network/mcpe/protocol/MoveEntityAbsolutePacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class MoveEntityAbsolutePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::MOVE_ENTITY_ABSOLUTE_PACKET; @@ -66,7 +66,7 @@ class MoveEntityAbsolutePacket extends DataPacket{ $this->putByteRotation($this->zRot); } - public function handle(NetworkSession $session) : bool{ - return $session->handleMoveEntityAbsolute($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleMoveEntityAbsolute($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/MoveEntityDeltaPacket.php b/src/pocketmine/network/mcpe/protocol/MoveEntityDeltaPacket.php index 134fb82c5e..906cd66698 100644 --- a/src/pocketmine/network/mcpe/protocol/MoveEntityDeltaPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MoveEntityDeltaPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class MoveEntityDeltaPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::MOVE_ENTITY_DELTA_PACKET; @@ -98,7 +98,7 @@ class MoveEntityDeltaPacket extends DataPacket{ $this->maybeWriteRotation(self::FLAG_HAS_ROT_Z, $this->zRot); } - public function handle(NetworkSession $session) : bool{ - return $session->handleMoveEntityDelta($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleMoveEntityDelta($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/MovePlayerPacket.php b/src/pocketmine/network/mcpe/protocol/MovePlayerPacket.php index cf1447011c..24e9983908 100644 --- a/src/pocketmine/network/mcpe/protocol/MovePlayerPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MovePlayerPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class MovePlayerPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::MOVE_PLAYER_PACKET; @@ -88,7 +88,7 @@ class MovePlayerPacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleMovePlayer($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleMovePlayer($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/NpcRequestPacket.php b/src/pocketmine/network/mcpe/protocol/NpcRequestPacket.php index 3a61b55415..babe74f6d0 100644 --- a/src/pocketmine/network/mcpe/protocol/NpcRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/NpcRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class NpcRequestPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::NPC_REQUEST_PACKET; @@ -53,7 +53,7 @@ class NpcRequestPacket extends DataPacket{ $this->putByte($this->actionType); } - public function handle(NetworkSession $session) : bool{ - return $session->handleNpcRequest($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleNpcRequest($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/PhotoTransferPacket.php b/src/pocketmine/network/mcpe/protocol/PhotoTransferPacket.php index 75b6f89f7e..ce4f0d7c5b 100644 --- a/src/pocketmine/network/mcpe/protocol/PhotoTransferPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PhotoTransferPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class PhotoTransferPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::PHOTO_TRANSFER_PACKET; @@ -49,7 +49,7 @@ class PhotoTransferPacket extends DataPacket{ $this->putString($this->bookId); } - public function handle(NetworkSession $session) : bool{ - return $session->handlePhotoTransfer($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handlePhotoTransfer($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/PlaySoundPacket.php b/src/pocketmine/network/mcpe/protocol/PlaySoundPacket.php index 0460a3efca..27aa677b2e 100644 --- a/src/pocketmine/network/mcpe/protocol/PlaySoundPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlaySoundPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class PlaySoundPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::PLAY_SOUND_PACKET; @@ -62,7 +62,7 @@ class PlaySoundPacket extends DataPacket{ $this->putLFloat($this->pitch); } - public function handle(NetworkSession $session) : bool{ - return $session->handlePlaySound($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handlePlaySound($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php b/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php index 7a89018c0b..839e66b3a4 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class PlayStatusPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::PLAY_STATUS_PACKET; @@ -69,7 +69,7 @@ class PlayStatusPacket extends DataPacket{ $this->putInt($this->status); } - public function handle(NetworkSession $session) : bool{ - return $session->handlePlayStatus($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handlePlayStatus($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/PlayerActionPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerActionPacket.php index 3a16a783bc..92254d75bf 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerActionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerActionPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class PlayerActionPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::PLAYER_ACTION_PACKET; @@ -84,7 +84,7 @@ class PlayerActionPacket extends DataPacket{ $this->putVarInt($this->face); } - public function handle(NetworkSession $session) : bool{ - return $session->handlePlayerAction($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handlePlayerAction($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php index b541128beb..ffcacbb662 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\ContainerIds; /** @@ -53,7 +53,7 @@ class PlayerHotbarPacket extends DataPacket{ $this->putBool($this->selectHotbarSlot); } - public function handle(NetworkSession $session) : bool{ - return $session->handlePlayerHotbar($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handlePlayerHotbar($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/PlayerInputPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerInputPacket.php index 8664e92ebe..a08eae9b8d 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerInputPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerInputPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class PlayerInputPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::PLAYER_INPUT_PACKET; @@ -54,7 +54,7 @@ class PlayerInputPacket extends DataPacket{ $this->putBool($this->sneaking); } - public function handle(NetworkSession $session) : bool{ - return $session->handlePlayerInput($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handlePlayerInput($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php index ba854d8b98..2027068faf 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\entity\Skin; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; class PlayerListPacket extends DataPacket{ @@ -105,7 +105,7 @@ class PlayerListPacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handlePlayerList($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handlePlayerList($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php index 64a9b67c5e..7a2fb964f9 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\entity\Skin; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\utils\UUID; class PlayerSkinPacket extends DataPacket{ @@ -68,7 +68,7 @@ class PlayerSkinPacket extends DataPacket{ $this->putString($this->skin->getGeometryData()); } - public function handle(NetworkSession $session) : bool{ - return $session->handlePlayerSkin($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handlePlayerSkin($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php b/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php index e841fed934..071468a376 100644 --- a/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class PurchaseReceiptPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::PURCHASE_RECEIPT_PACKET; @@ -47,7 +47,7 @@ class PurchaseReceiptPacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handlePurchaseReceipt($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handlePurchaseReceipt($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php b/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php index 856b9b2118..9925679e52 100644 --- a/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class RemoveEntityPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::REMOVE_ENTITY_PACKET; @@ -42,7 +42,7 @@ class RemoveEntityPacket extends DataPacket{ $this->putEntityUniqueId($this->entityUniqueId); } - public function handle(NetworkSession $session) : bool{ - return $session->handleRemoveEntity($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleRemoveEntity($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/RemoveObjectivePacket.php b/src/pocketmine/network/mcpe/protocol/RemoveObjectivePacket.php index 25dd8298be..3889f3b797 100644 --- a/src/pocketmine/network/mcpe/protocol/RemoveObjectivePacket.php +++ b/src/pocketmine/network/mcpe/protocol/RemoveObjectivePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class RemoveObjectivePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::REMOVE_OBJECTIVE_PACKET; @@ -41,7 +41,7 @@ class RemoveObjectivePacket extends DataPacket{ $this->putString($this->objectiveName); } - public function handle(NetworkSession $session) : bool{ - return $session->handleRemoveObjective($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleRemoveObjective($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/RequestChunkRadiusPacket.php b/src/pocketmine/network/mcpe/protocol/RequestChunkRadiusPacket.php index 3cb552b6bb..37cc96ee9f 100644 --- a/src/pocketmine/network/mcpe/protocol/RequestChunkRadiusPacket.php +++ b/src/pocketmine/network/mcpe/protocol/RequestChunkRadiusPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class RequestChunkRadiusPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::REQUEST_CHUNK_RADIUS_PACKET; @@ -42,7 +42,7 @@ class RequestChunkRadiusPacket extends DataPacket{ $this->putVarInt($this->radius); } - public function handle(NetworkSession $session) : bool{ - return $session->handleRequestChunkRadius($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleRequestChunkRadius($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php index 6f51d6adf5..529d81f11b 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class ResourcePackChunkDataPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_CHUNK_DATA_PACKET; @@ -56,7 +56,7 @@ class ResourcePackChunkDataPacket extends DataPacket{ $this->put($this->data); } - public function handle(NetworkSession $session) : bool{ - return $session->handleResourcePackChunkData($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleResourcePackChunkData($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackChunkRequestPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackChunkRequestPacket.php index 4d17634ed9..8d6d0188e0 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackChunkRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackChunkRequestPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class ResourcePackChunkRequestPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_CHUNK_REQUEST_PACKET; @@ -47,7 +47,7 @@ class ResourcePackChunkRequestPacket extends DataPacket{ $this->putLInt($this->chunkIndex); } - public function handle(NetworkSession $session) : bool{ - return $session->handleResourcePackChunkRequest($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleResourcePackChunkRequest($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackClientResponsePacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackClientResponsePacket.php index 1d1b2c3fa6..5b560e1e88 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackClientResponsePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackClientResponsePacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class ResourcePackClientResponsePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_CLIENT_RESPONSE_PACKET; @@ -57,7 +57,7 @@ class ResourcePackClientResponsePacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleResourcePackClientResponse($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleResourcePackClientResponse($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php index 777cc8e770..ba3d4a290a 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class ResourcePackDataInfoPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_DATA_INFO_PACKET; @@ -59,7 +59,7 @@ class ResourcePackDataInfoPacket extends DataPacket{ $this->putString($this->sha256); } - public function handle(NetworkSession $session) : bool{ - return $session->handleResourcePackDataInfo($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleResourcePackDataInfo($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php index 319528e441..58493fd76e 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\resourcepacks\ResourcePack; class ResourcePackStackPacket extends DataPacket{ @@ -76,7 +76,7 @@ class ResourcePackStackPacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleResourcePackStack($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleResourcePackStack($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php index e6af50106e..8b75355918 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\resourcepacks\ResourcePack; class ResourcePacksInfoPacket extends DataPacket{ @@ -81,7 +81,7 @@ class ResourcePacksInfoPacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleResourcePacksInfo($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleResourcePacksInfo($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/RespawnPacket.php b/src/pocketmine/network/mcpe/protocol/RespawnPacket.php index d6c088ba6d..7fb40ac2d4 100644 --- a/src/pocketmine/network/mcpe/protocol/RespawnPacket.php +++ b/src/pocketmine/network/mcpe/protocol/RespawnPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class RespawnPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::RESPAWN_PACKET; @@ -43,7 +43,7 @@ class RespawnPacket extends DataPacket{ $this->putVector3($this->position); } - public function handle(NetworkSession $session) : bool{ - return $session->handleRespawn($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleRespawn($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/RiderJumpPacket.php b/src/pocketmine/network/mcpe/protocol/RiderJumpPacket.php index ca3e8df0f9..f1eb66e627 100644 --- a/src/pocketmine/network/mcpe/protocol/RiderJumpPacket.php +++ b/src/pocketmine/network/mcpe/protocol/RiderJumpPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class RiderJumpPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::RIDER_JUMP_PACKET; @@ -43,7 +43,7 @@ class RiderJumpPacket extends DataPacket{ $this->putVarInt($this->jumpStrength); } - public function handle(NetworkSession $session) : bool{ - return $session->handleRiderJump($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleRiderJump($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ServerSettingsRequestPacket.php b/src/pocketmine/network/mcpe/protocol/ServerSettingsRequestPacket.php index bccf9ed164..c8513b3d0b 100644 --- a/src/pocketmine/network/mcpe/protocol/ServerSettingsRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ServerSettingsRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class ServerSettingsRequestPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SERVER_SETTINGS_REQUEST_PACKET; @@ -38,7 +38,7 @@ class ServerSettingsRequestPacket extends DataPacket{ //No payload } - public function handle(NetworkSession $session) : bool{ - return $session->handleServerSettingsRequest($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleServerSettingsRequest($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ServerSettingsResponsePacket.php b/src/pocketmine/network/mcpe/protocol/ServerSettingsResponsePacket.php index c3a5b3fb20..a1d3744949 100644 --- a/src/pocketmine/network/mcpe/protocol/ServerSettingsResponsePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ServerSettingsResponsePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class ServerSettingsResponsePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SERVER_SETTINGS_RESPONSE_PACKET; @@ -45,7 +45,7 @@ class ServerSettingsResponsePacket extends DataPacket{ $this->putString($this->formData); } - public function handle(NetworkSession $session) : bool{ - return $session->handleServerSettingsResponse($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleServerSettingsResponse($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php b/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php index b5a5defd94..c3fd0d9e6e 100644 --- a/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class ServerToClientHandshakePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SERVER_TO_CLIENT_HANDSHAKE_PACKET; @@ -49,7 +49,7 @@ class ServerToClientHandshakePacket extends DataPacket{ $this->putString($this->jwt); } - public function handle(NetworkSession $session) : bool{ - return $session->handleServerToClientHandshake($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleServerToClientHandshake($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetCommandsEnabledPacket.php b/src/pocketmine/network/mcpe/protocol/SetCommandsEnabledPacket.php index 82f28fc88a..1b4dcd1e94 100644 --- a/src/pocketmine/network/mcpe/protocol/SetCommandsEnabledPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetCommandsEnabledPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class SetCommandsEnabledPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SET_COMMANDS_ENABLED_PACKET; @@ -42,7 +42,7 @@ class SetCommandsEnabledPacket extends DataPacket{ $this->putBool($this->enabled); } - public function handle(NetworkSession $session) : bool{ - return $session->handleSetCommandsEnabled($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleSetCommandsEnabled($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetDefaultGameTypePacket.php b/src/pocketmine/network/mcpe/protocol/SetDefaultGameTypePacket.php index a3adaa43fa..a52f2a26b2 100644 --- a/src/pocketmine/network/mcpe/protocol/SetDefaultGameTypePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetDefaultGameTypePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class SetDefaultGameTypePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SET_DEFAULT_GAME_TYPE_PACKET; @@ -41,7 +41,7 @@ class SetDefaultGameTypePacket extends DataPacket{ $this->putUnsignedVarInt($this->gamemode); } - public function handle(NetworkSession $session) : bool{ - return $session->handleSetDefaultGameType($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleSetDefaultGameType($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetDifficultyPacket.php b/src/pocketmine/network/mcpe/protocol/SetDifficultyPacket.php index a3f75035e5..e4becdd5f6 100644 --- a/src/pocketmine/network/mcpe/protocol/SetDifficultyPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetDifficultyPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class SetDifficultyPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SET_DIFFICULTY_PACKET; @@ -42,7 +42,7 @@ class SetDifficultyPacket extends DataPacket{ $this->putUnsignedVarInt($this->difficulty); } - public function handle(NetworkSession $session) : bool{ - return $session->handleSetDifficulty($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleSetDifficulty($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetDisplayObjectivePacket.php b/src/pocketmine/network/mcpe/protocol/SetDisplayObjectivePacket.php index 534c66b01a..3eb7b4a299 100644 --- a/src/pocketmine/network/mcpe/protocol/SetDisplayObjectivePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetDisplayObjectivePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class SetDisplayObjectivePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SET_DISPLAY_OBJECTIVE_PACKET; @@ -57,7 +57,7 @@ class SetDisplayObjectivePacket extends DataPacket{ $this->putVarInt($this->sortOrder); } - public function handle(NetworkSession $session) : bool{ - return $session->handleSetDisplayObjective($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleSetDisplayObjective($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetEntityDataPacket.php b/src/pocketmine/network/mcpe/protocol/SetEntityDataPacket.php index 48c483953f..aa0206c967 100644 --- a/src/pocketmine/network/mcpe/protocol/SetEntityDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetEntityDataPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class SetEntityDataPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SET_ENTITY_DATA_PACKET; @@ -46,7 +46,7 @@ class SetEntityDataPacket extends DataPacket{ $this->putEntityMetadata($this->metadata); } - public function handle(NetworkSession $session) : bool{ - return $session->handleSetEntityData($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleSetEntityData($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetEntityLinkPacket.php b/src/pocketmine/network/mcpe/protocol/SetEntityLinkPacket.php index 4d695948ea..577b2d1d7b 100644 --- a/src/pocketmine/network/mcpe/protocol/SetEntityLinkPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetEntityLinkPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\EntityLink; class SetEntityLinkPacket extends DataPacket{ @@ -43,7 +43,7 @@ class SetEntityLinkPacket extends DataPacket{ $this->putEntityLink($this->link); } - public function handle(NetworkSession $session) : bool{ - return $session->handleSetEntityLink($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleSetEntityLink($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php b/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php index acecb51236..4d4eafe14c 100644 --- a/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class SetEntityMotionPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SET_ENTITY_MOTION_PACKET; @@ -47,7 +47,7 @@ class SetEntityMotionPacket extends DataPacket{ $this->putVector3($this->motion); } - public function handle(NetworkSession $session) : bool{ - return $session->handleSetEntityMotion($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleSetEntityMotion($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetHealthPacket.php b/src/pocketmine/network/mcpe/protocol/SetHealthPacket.php index 736f9deca1..c25f228d41 100644 --- a/src/pocketmine/network/mcpe/protocol/SetHealthPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetHealthPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class SetHealthPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SET_HEALTH_PACKET; @@ -42,7 +42,7 @@ class SetHealthPacket extends DataPacket{ $this->putVarInt($this->health); } - public function handle(NetworkSession $session) : bool{ - return $session->handleSetHealth($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleSetHealth($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetLastHurtByPacket.php b/src/pocketmine/network/mcpe/protocol/SetLastHurtByPacket.php index 25cc3d9f4d..5591b867a7 100644 --- a/src/pocketmine/network/mcpe/protocol/SetLastHurtByPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetLastHurtByPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class SetLastHurtByPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SET_LAST_HURT_BY_PACKET; @@ -41,7 +41,7 @@ class SetLastHurtByPacket extends DataPacket{ $this->putVarInt($this->entityTypeId); } - public function handle(NetworkSession $session) : bool{ - return $session->handleSetLastHurtBy($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleSetLastHurtBy($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php b/src/pocketmine/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php index 46f4a00bc4..9d8652a69d 100644 --- a/src/pocketmine/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class SetLocalPlayerAsInitializedPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SET_LOCAL_PLAYER_AS_INITIALIZED_PACKET; @@ -41,7 +41,7 @@ class SetLocalPlayerAsInitializedPacket extends DataPacket{ $this->putEntityRuntimeId($this->entityRuntimeId); } - public function handle(NetworkSession $session) : bool{ - return $session->handleSetLocalPlayerAsInitialized($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleSetLocalPlayerAsInitialized($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php b/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php index 22e88ab1d9..5c8ecb914a 100644 --- a/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class SetPlayerGameTypePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SET_PLAYER_GAME_TYPE_PACKET; @@ -42,7 +42,7 @@ class SetPlayerGameTypePacket extends DataPacket{ $this->putVarInt($this->gamemode); } - public function handle(NetworkSession $session) : bool{ - return $session->handleSetPlayerGameType($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleSetPlayerGameType($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetScorePacket.php b/src/pocketmine/network/mcpe/protocol/SetScorePacket.php index aa36a19f53..c65fa38abc 100644 --- a/src/pocketmine/network/mcpe/protocol/SetScorePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetScorePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\ScorePacketEntry; class SetScorePacket extends DataPacket{ @@ -59,7 +59,7 @@ class SetScorePacket extends DataPacket{ } } - public function handle(NetworkSession $session) : bool{ - return $session->handleSetScore($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleSetScore($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php b/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php index 1788ca16c0..4ebb0edebf 100644 --- a/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class SetSpawnPositionPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SET_SPAWN_POSITION_PACKET; @@ -57,7 +57,7 @@ class SetSpawnPositionPacket extends DataPacket{ $this->putBool($this->spawnForced); } - public function handle(NetworkSession $session) : bool{ - return $session->handleSetSpawnPosition($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleSetSpawnPosition($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetTimePacket.php b/src/pocketmine/network/mcpe/protocol/SetTimePacket.php index 4f72115e93..bbda124917 100644 --- a/src/pocketmine/network/mcpe/protocol/SetTimePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetTimePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class SetTimePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SET_TIME_PACKET; @@ -41,7 +41,7 @@ class SetTimePacket extends DataPacket{ $this->putVarInt($this->time); } - public function handle(NetworkSession $session) : bool{ - return $session->handleSetTime($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleSetTime($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php b/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php index a819d03647..c793dbb32a 100644 --- a/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class SetTitlePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SET_TITLE_PACKET; @@ -66,7 +66,7 @@ class SetTitlePacket extends DataPacket{ $this->putVarInt($this->fadeOutTime); } - public function handle(NetworkSession $session) : bool{ - return $session->handleSetTitle($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleSetTitle($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ShowCreditsPacket.php b/src/pocketmine/network/mcpe/protocol/ShowCreditsPacket.php index 15715e5b24..d8b325480c 100644 --- a/src/pocketmine/network/mcpe/protocol/ShowCreditsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ShowCreditsPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class ShowCreditsPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SHOW_CREDITS_PACKET; @@ -50,7 +50,7 @@ class ShowCreditsPacket extends DataPacket{ $this->putVarInt($this->status); } - public function handle(NetworkSession $session) : bool{ - return $session->handleShowCredits($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleShowCredits($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ShowProfilePacket.php b/src/pocketmine/network/mcpe/protocol/ShowProfilePacket.php index 4a7eaee19a..afb00dcb9f 100644 --- a/src/pocketmine/network/mcpe/protocol/ShowProfilePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ShowProfilePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class ShowProfilePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SHOW_PROFILE_PACKET; @@ -41,7 +41,7 @@ class ShowProfilePacket extends DataPacket{ $this->putString($this->xuid); } - public function handle(NetworkSession $session) : bool{ - return $session->handleShowProfile($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleShowProfile($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php b/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php index 23ee620381..0cc39362c1 100644 --- a/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class ShowStoreOfferPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SHOW_STORE_OFFER_PACKET; @@ -45,7 +45,7 @@ class ShowStoreOfferPacket extends DataPacket{ $this->putBool($this->showAll); } - public function handle(NetworkSession $session) : bool{ - return $session->handleShowStoreOffer($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleShowStoreOffer($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php b/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php index b56e136954..58d57c185b 100644 --- a/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class SimpleEventPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SIMPLE_EVENT_PACKET; @@ -44,7 +44,7 @@ class SimpleEventPacket extends DataPacket{ $this->putLShort($this->eventType); } - public function handle(NetworkSession $session) : bool{ - return $session->handleSimpleEvent($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleSimpleEvent($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SpawnExperienceOrbPacket.php b/src/pocketmine/network/mcpe/protocol/SpawnExperienceOrbPacket.php index 628ef4a970..a727f066de 100644 --- a/src/pocketmine/network/mcpe/protocol/SpawnExperienceOrbPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SpawnExperienceOrbPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class SpawnExperienceOrbPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SPAWN_EXPERIENCE_ORB_PACKET; @@ -47,7 +47,7 @@ class SpawnExperienceOrbPacket extends DataPacket{ $this->putVarInt($this->amount); } - public function handle(NetworkSession $session) : bool{ - return $session->handleSpawnExperienceOrb($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleSpawnExperienceOrb($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/StartGamePacket.php b/src/pocketmine/network/mcpe/protocol/StartGamePacket.php index 11d834f2c1..8e958bd391 100644 --- a/src/pocketmine/network/mcpe/protocol/StartGamePacket.php +++ b/src/pocketmine/network/mcpe/protocol/StartGamePacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; class StartGamePacket extends DataPacket{ @@ -228,7 +228,7 @@ class StartGamePacket extends DataPacket{ $this->putVarInt($this->enchantmentSeed); } - public function handle(NetworkSession $session) : bool{ - return $session->handleStartGame($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleStartGame($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/StopSoundPacket.php b/src/pocketmine/network/mcpe/protocol/StopSoundPacket.php index d48d4b96f8..74cdbb2214 100644 --- a/src/pocketmine/network/mcpe/protocol/StopSoundPacket.php +++ b/src/pocketmine/network/mcpe/protocol/StopSoundPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class StopSoundPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::STOP_SOUND_PACKET; @@ -47,7 +47,7 @@ class StopSoundPacket extends DataPacket{ $this->putBool($this->stopAll); } - public function handle(NetworkSession $session) : bool{ - return $session->handleStopSound($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleStopSound($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php b/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php index cc409bfb34..4bbad7173d 100644 --- a/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php +++ b/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class StructureBlockUpdatePacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::STRUCTURE_BLOCK_UPDATE_PACKET; @@ -38,7 +38,7 @@ class StructureBlockUpdatePacket extends DataPacket{ //TODO } - public function handle(NetworkSession $session) : bool{ - return $session->handleStructureBlockUpdate($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleStructureBlockUpdate($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SubClientLoginPacket.php b/src/pocketmine/network/mcpe/protocol/SubClientLoginPacket.php index 5d1d72ab0f..e29a96e774 100644 --- a/src/pocketmine/network/mcpe/protocol/SubClientLoginPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SubClientLoginPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class SubClientLoginPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::SUB_CLIENT_LOGIN_PACKET; @@ -41,7 +41,7 @@ class SubClientLoginPacket extends DataPacket{ $this->putString($this->connectionRequestData); } - public function handle(NetworkSession $session) : bool{ - return $session->handleSubClientLogin($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleSubClientLogin($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php b/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php index c0e66fa7d5..b5706530f6 100644 --- a/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class TakeItemEntityPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::TAKE_ITEM_ENTITY_PACKET; @@ -45,7 +45,7 @@ class TakeItemEntityPacket extends DataPacket{ $this->putEntityRuntimeId($this->eid); } - public function handle(NetworkSession $session) : bool{ - return $session->handleTakeItemEntity($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleTakeItemEntity($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/TextPacket.php b/src/pocketmine/network/mcpe/protocol/TextPacket.php index 532fd28e10..4604c922cd 100644 --- a/src/pocketmine/network/mcpe/protocol/TextPacket.php +++ b/src/pocketmine/network/mcpe/protocol/TextPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class TextPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::TEXT_PACKET; @@ -124,7 +124,7 @@ class TextPacket extends DataPacket{ $this->putString($this->platformChatId); } - public function handle(NetworkSession $session) : bool{ - return $session->handleText($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleText($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/TransferPacket.php b/src/pocketmine/network/mcpe/protocol/TransferPacket.php index 1bf5270c22..6e841ac0d2 100644 --- a/src/pocketmine/network/mcpe/protocol/TransferPacket.php +++ b/src/pocketmine/network/mcpe/protocol/TransferPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class TransferPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::TRANSFER_PACKET; @@ -45,7 +45,7 @@ class TransferPacket extends DataPacket{ $this->putLShort($this->port); } - public function handle(NetworkSession $session) : bool{ - return $session->handleTransfer($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleTransfer($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/UnknownPacket.php b/src/pocketmine/network/mcpe/protocol/UnknownPacket.php index 3acec2287d..6daf12bfb5 100644 --- a/src/pocketmine/network/mcpe/protocol/UnknownPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UnknownPacket.php @@ -25,7 +25,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class UnknownPacket extends DataPacket{ public const NETWORK_ID = -1; //Invalid, do not try to write this @@ -53,7 +53,7 @@ class UnknownPacket extends DataPacket{ $this->put($this->payload); } - public function handle(NetworkSession $session) : bool{ + public function handle(SessionHandler $handler) : bool{ return false; } } diff --git a/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php index d8b6095575..77e1b97184 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\entity\Attribute; -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class UpdateAttributesPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_ATTRIBUTES_PACKET; @@ -47,7 +47,7 @@ class UpdateAttributesPacket extends DataPacket{ $this->putAttributeList(...$this->entries); } - public function handle(NetworkSession $session) : bool{ - return $session->handleUpdateAttributes($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleUpdateAttributes($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php index ff27e23cf7..db70663289 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class UpdateBlockPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_BLOCK_PACKET; @@ -70,7 +70,7 @@ class UpdateBlockPacket extends DataPacket{ $this->putUnsignedVarInt($this->dataLayerId); } - public function handle(NetworkSession $session) : bool{ - return $session->handleUpdateBlock($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleUpdateBlock($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/UpdateBlockSyncedPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateBlockSyncedPacket.php index f99bb5731e..0ac93c3bff 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateBlockSyncedPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateBlockSyncedPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class UpdateBlockSyncedPacket extends UpdateBlockPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_BLOCK_SYNCED_PACKET; @@ -47,7 +47,7 @@ class UpdateBlockSyncedPacket extends UpdateBlockPacket{ $this->putUnsignedVarLong($this->uvarint64_2); } - public function handle(NetworkSession $session) : bool{ - return $session->handleUpdateBlockSynced($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleUpdateBlockSynced($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php index 7a79089186..fc5ba6934c 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class UpdateEquipPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_EQUIP_PACKET; @@ -57,7 +57,7 @@ class UpdateEquipPacket extends DataPacket{ $this->put($this->namedtag); } - public function handle(NetworkSession $session) : bool{ - return $session->handleUpdateEquip($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleUpdateEquip($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php b/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php index a1c38553e7..291d745ba0 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\WindowTypes; class UpdateTradePacket extends DataPacket{ @@ -78,7 +78,7 @@ class UpdateTradePacket extends DataPacket{ $this->put($this->offers); } - public function handle(NetworkSession $session) : bool{ - return $session->handleUpdateTrade($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleUpdateTrade($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/WSConnectPacket.php b/src/pocketmine/network/mcpe/protocol/WSConnectPacket.php index 2514074717..8619b15c89 100644 --- a/src/pocketmine/network/mcpe/protocol/WSConnectPacket.php +++ b/src/pocketmine/network/mcpe/protocol/WSConnectPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\handler\SessionHandler; class WSConnectPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::W_S_CONNECT_PACKET; @@ -41,7 +41,7 @@ class WSConnectPacket extends DataPacket{ $this->putString($this->serverUri); } - public function handle(NetworkSession $session) : bool{ - return $session->handleWSConnect($this); + public function handle(SessionHandler $handler) : bool{ + return $handler->handleWSConnect($this); } } From cdcafb1e75edfc1c771104297e94cccfb86f7174 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 19 Jul 2018 15:19:33 +0100 Subject: [PATCH 0025/3224] PacketPool: Properly deal with varint packet IDs now that BatchPacket is gone --- src/pocketmine/network/mcpe/protocol/PacketPool.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/PacketPool.php b/src/pocketmine/network/mcpe/protocol/PacketPool.php index d27545f7c1..d7facb48a5 100644 --- a/src/pocketmine/network/mcpe/protocol/PacketPool.php +++ b/src/pocketmine/network/mcpe/protocol/PacketPool.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; +use pocketmine\utils\Binary; + class PacketPool{ /** @var \SplFixedArray */ protected static $pool = null; @@ -165,8 +167,9 @@ class PacketPool{ * @return DataPacket */ public static function getPacket(string $buffer) : DataPacket{ - $pk = static::getPacketById(ord($buffer{0})); - $pk->setBuffer($buffer); + $offset = 0; + $pk = static::getPacketById(Binary::readUnsignedVarInt($buffer, $offset)); + $pk->setBuffer($buffer, $offset); return $pk; } From 08621604cd90c25553e8c6ce8190c372efe82c64 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 19 Jul 2018 15:43:38 +0100 Subject: [PATCH 0026/3224] PacketPool: remove redundant comment this was added to signify that these were normal, while BatchPacket was a hack. Since this has now been corrected, there's no need for the comment. --- src/pocketmine/network/mcpe/protocol/PacketPool.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/protocol/PacketPool.php b/src/pocketmine/network/mcpe/protocol/PacketPool.php index d7facb48a5..88f6b0c0a1 100644 --- a/src/pocketmine/network/mcpe/protocol/PacketPool.php +++ b/src/pocketmine/network/mcpe/protocol/PacketPool.php @@ -32,7 +32,6 @@ class PacketPool{ public static function init() : void{ static::$pool = new \SplFixedArray(256); - //Normal packets static::registerPacket(new LoginPacket()); static::registerPacket(new PlayStatusPacket()); static::registerPacket(new ServerToClientHandshakePacket()); From e16f20affaf790d7de96820a362e59e4f2f5cc87 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 19 Jul 2018 16:40:00 +0100 Subject: [PATCH 0027/3224] NetworkSession: added getHandler() and setHandler(), SessionHandler->setUp() now not useless --- src/pocketmine/network/mcpe/NetworkSession.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index e23e1d31ba..6cd32b6834 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -60,7 +60,7 @@ class NetworkSession{ $this->ip = $ip; $this->port = $port; - $this->handler = new SimpleSessionHandler($player); + $this->setHandler(new SimpleSessionHandler($player)); } public function getInterface() : NetworkInterface{ @@ -81,6 +81,15 @@ class NetworkSession{ return $this->port; } + public function getHandler() : SessionHandler{ + return $this->handler; + } + + public function setHandler(SessionHandler $handler) : void{ + $this->handler = $handler; + $this->handler->setUp(); + } + public function handleEncoded(string $payload) : void{ //TODO: decryption if enabled From 25cfcada262c2b2017d3f9058a83172c36f29489 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 20 Jul 2018 11:36:56 +0100 Subject: [PATCH 0028/3224] Player: clean up container close handling --- src/pocketmine/Player.php | 51 +++++++++++-------- .../mcpe/handler/SimpleSessionHandler.php | 2 +- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 836545e7fd..986faf486b 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -104,7 +104,6 @@ use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\network\mcpe\protocol\BlockPickRequestPacket; use pocketmine\network\mcpe\protocol\BookEditPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; -use pocketmine\network\mcpe\protocol\ContainerClosePacket; use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\InteractPacket; @@ -2840,25 +2839,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return true; } - public function handleContainerClose(ContainerClosePacket $packet) : bool{ - if(!$this->spawned or $packet->windowId === 0){ - return true; - } - - $this->doCloseInventory(); - - if(isset($this->windowIndex[$packet->windowId])){ - $this->server->getPluginManager()->callEvent(new InventoryCloseEvent($this->windowIndex[$packet->windowId], $this)); - $this->removeWindow($this->windowIndex[$packet->windowId]); - return true; - }elseif($packet->windowId === 255){ - //Closed a fake window - return true; - } - - return false; - } - public function handleAdventureSettings(AdventureSettingsPacket $packet) : bool{ if($packet->entityUniqueId !== $this->getId()){ return false; //TODO @@ -3752,6 +3732,10 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->craftingGrid = $grid; } + /** + * @internal Called to clean up crafting grid and cursor inventory when it is detected that the player closed their + * inventory. + */ public function doCloseInventory() : void{ /** @var Inventory[] $inventories */ $inventories = [$this->craftingGrid, $this->cursorInventory]; @@ -3772,6 +3756,33 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } } + /** + * @internal Called by the network session when a player closes a window. + * + * @param int $windowId + * + * @return bool + */ + public function doCloseWindow(int $windowId) : bool{ + if(!$this->spawned or $windowId === 0){ + return false; + } + + $this->doCloseInventory(); + + if(isset($this->windowIndex[$windowId])){ + $this->server->getPluginManager()->callEvent(new InventoryCloseEvent($this->windowIndex[$windowId], $this)); + $this->removeWindow($this->windowIndex[$windowId]); + return true; + } + if($windowId === 255){ + //Closed a fake window + return true; + } + + return false; + } + /** * Returns the window ID which the inventory has for this player, or -1 if the window is not open to the player. * diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index 8fe0e05337..1e8ede1603 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -146,7 +146,7 @@ class SimpleSessionHandler extends SessionHandler{ } public function handleContainerClose(ContainerClosePacket $packet) : bool{ - return $this->player->handleContainerClose($packet); + return $this->player->doCloseWindow($packet->windowId); } public function handlePlayerHotbar(PlayerHotbarPacket $packet) : bool{ From 57a86d9ed7ed9cfa0a785e536b6c28c1a259ff8c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 20 Jul 2018 12:39:48 +0100 Subject: [PATCH 0029/3224] Player: remove useless InteractPacket handler all the things we cared about in here don't exist anymore, so there's no sense in the handler still existing. It can be restored when we want to use the things it still does. --- src/pocketmine/Player.php | 26 ------------------- .../mcpe/handler/SimpleSessionHandler.php | 2 +- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 986faf486b..5910c3f2e9 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -106,7 +106,6 @@ use pocketmine\network\mcpe\protocol\BookEditPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\EntityEventPacket; -use pocketmine\network\mcpe\protocol\InteractPacket; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; @@ -2625,31 +2624,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return true; } - public function handleInteract(InteractPacket $packet) : bool{ - if(!$this->spawned or !$this->isAlive()){ - return true; - } - - $this->doCloseInventory(); - - $target = $this->level->getEntity($packet->target); - if($target === null){ - return false; - } - - switch($packet->action){ - case InteractPacket::ACTION_LEAVE_VEHICLE: - case InteractPacket::ACTION_MOUSEOVER: - break; //TODO: handle these - default: - $this->server->getLogger()->debug("Unhandled/unknown interaction type " . $packet->action . "received from " . $this->getName()); - - return false; - } - - return true; - } - public function handleBlockPickRequest(BlockPickRequestPacket $packet) : bool{ $block = $this->level->getBlockAt($packet->blockX, $packet->blockY, $packet->blockZ); diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index 1e8ede1603..b640192bb0 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -122,7 +122,7 @@ class SimpleSessionHandler extends SessionHandler{ } public function handleInteract(InteractPacket $packet) : bool{ - return $this->player->handleInteract($packet); + return false; //TODO } public function handleBlockPickRequest(BlockPickRequestPacket $packet) : bool{ From aae19d45b739377190b484721d576f4bf016364d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 20 Jul 2018 12:41:16 +0100 Subject: [PATCH 0030/3224] Player: remove useless handleDataPacket() leftover --- src/pocketmine/Player.php | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 5910c3f2e9..b20da0b71f 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2976,17 +2976,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return true; } - /** - * Called when a packet is received from the client. This method will call DataPacketReceiveEvent. - * - * @param DataPacket $packet - */ - public function handleDataPacket(DataPacket $packet){ - if($this->networkSession !== null){ - $this->networkSession->handleDataPacket($packet); - } - } - /** * @param DataPacket $packet * @param bool $needACK From 0fecb79addb08db9b08189496033d061d2dd1374 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 20 Jul 2018 13:02:36 +0100 Subject: [PATCH 0031/3224] Player: separate some PlayerActionPacket handling logic out into their own functions these are public, because later on the session handler will be calling these instead of the player itself. --- src/pocketmine/Player.php | 87 ++++++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 34 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index b20da0b71f..ae250fcc1f 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2664,42 +2664,13 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ switch($packet->action){ case PlayerActionPacket::ACTION_START_BREAK: - if($pos->distanceSquared($this) > 10000){ - break; - } - - $target = $this->level->getBlock($pos); - - $ev = new PlayerInteractEvent($this, $this->inventory->getItemInHand(), $target, null, $packet->face, $target->getId() === 0 ? PlayerInteractEvent::LEFT_CLICK_AIR : PlayerInteractEvent::LEFT_CLICK_BLOCK); - if($this->level->checkSpawnProtection($this, $target)){ - $ev->setCancelled(); - } - - $this->getServer()->getPluginManager()->callEvent($ev); - if($ev->isCancelled()){ - $this->inventory->sendHeldItem($this); - break; - } - - $block = $target->getSide($packet->face); - if($block->getId() === Block::FIRE){ - $this->level->setBlock($block, BlockFactory::get(Block::AIR)); - break; - } - - if(!$this->isCreative()){ - //TODO: improve this to take stuff like swimming, ladders, enchanted tools into account, fix wrong tool break time calculations for bad tools (pmmp/PocketMine-MP#211) - $breakTime = ceil($target->getBreakTime($this->inventory->getItemInHand()) * 20); - if($breakTime > 0){ - $this->level->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_START_BREAK, (int) (65535 / $breakTime)); - } - } + $this->startBreakBlock($pos, $packet->face); break; case PlayerActionPacket::ACTION_ABORT_BREAK: case PlayerActionPacket::ACTION_STOP_BREAK: - $this->level->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_STOP_BREAK); + $this->stopBreakBlock($pos); break; case PlayerActionPacket::ACTION_START_SLEEPING: //unused @@ -2733,9 +2704,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ case PlayerActionPacket::ACTION_STOP_GLIDE: break; //TODO case PlayerActionPacket::ACTION_CONTINUE_BREAK: - $block = $this->level->getBlock($pos); - $this->level->broadcastLevelEvent($pos, LevelEventPacket::EVENT_PARTICLE_PUNCH_BLOCK, BlockFactory::toStaticRuntimeId($block->getId(), $block->getDamage()) | ($packet->face << 24)); - //TODO: destroy-progress level event + $this->continueBreakBlock($pos, $packet->face); break; case PlayerActionPacket::ACTION_START_SWIMMING: break; //TODO @@ -2752,6 +2721,56 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return true; } + public function startBreakBlock(Vector3 $pos, int $face) : bool{ + if($pos->distanceSquared($this) > 10000){ + return false; //TODO: maybe this should throw an exception instead? + } + + $target = $this->level->getBlock($pos); + + $ev = new PlayerInteractEvent($this, $this->inventory->getItemInHand(), $target, null, $face, $target->getId() === 0 ? PlayerInteractEvent::LEFT_CLICK_AIR : PlayerInteractEvent::LEFT_CLICK_BLOCK); + if($this->level->checkSpawnProtection($this, $target)){ + $ev->setCancelled(); + } + + $this->getServer()->getPluginManager()->callEvent($ev); + if($ev->isCancelled()){ + $this->inventory->sendHeldItem($this); + return true; + } + + $block = $target->getSide($face); + if($block->getId() === Block::FIRE){ + $this->level->setBlock($block, BlockFactory::get(Block::AIR)); + return true; + } + + if(!$this->isCreative()){ + //TODO: improve this to take stuff like swimming, ladders, enchanted tools into account, fix wrong tool break time calculations for bad tools (pmmp/PocketMine-MP#211) + $breakTime = ceil($target->getBreakTime($this->inventory->getItemInHand()) * 20); + if($breakTime > 0){ + $this->level->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_START_BREAK, (int) (65535 / $breakTime)); + } + } + + return true; + } + + public function continueBreakBlock(Vector3 $pos, int $face) : void{ + $block = $this->level->getBlock($pos); + $this->level->broadcastLevelEvent( + $pos, + LevelEventPacket::EVENT_PARTICLE_PUNCH_BLOCK, + BlockFactory::toStaticRuntimeId($block->getId(), $block->getDamage()) | ($face << 24) + ); + + //TODO: destroy-progress level event + } + + public function stopBreakBlock(Vector3 $pos) : void{ + $this->level->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_STOP_BREAK); + } + public function toggleSprint(bool $sprint) : void{ $ev = new PlayerToggleSprintEvent($this, $sprint); $this->server->getPluginManager()->callEvent($ev); From 3cd105ff33be54bf5d8b4cda45ea9e88fff23184 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 20 Jul 2018 13:07:06 +0100 Subject: [PATCH 0032/3224] Remove remnants of needACK functionality this has been broken for a long time and hasn't been used for even longer. --- src/pocketmine/Player.php | 21 ++++++++----------- src/pocketmine/Server.php | 2 +- src/pocketmine/network/NetworkInterface.php | 5 +---- .../network/mcpe/RakLibInterface.php | 14 ++----------- 4 files changed, 13 insertions(+), 29 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index ae250fcc1f..17997d025d 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1902,7 +1902,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $pk = new PlayStatusPacket(); $pk->status = $status; $pk->protocol = $this->protocol; - $this->sendDataPacket($pk, false, $immediate); + $this->sendDataPacket($pk, $immediate); } public function onVerifyCompleted(LoginPacket $packet, ?string $error, bool $signedByMojang) : void{ @@ -2997,12 +2997,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ /** * @param DataPacket $packet - * @param bool $needACK * @param bool $immediate * - * @return bool|int + * @return bool */ - public function sendDataPacket(DataPacket $packet, bool $needACK = false, bool $immediate = false){ + public function sendDataPacket(DataPacket $packet, bool $immediate = false) : bool{ if(!$this->isConnected()){ return false; } @@ -3017,22 +3016,20 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ /** * @param DataPacket $packet - * @param bool $needACK * - * @return bool|int + * @return bool */ - public function dataPacket(DataPacket $packet, bool $needACK = false){ - return $this->sendDataPacket($packet, $needACK, false); + public function dataPacket(DataPacket $packet) : bool{ + return $this->sendDataPacket($packet, false); } /** * @param DataPacket $packet - * @param bool $needACK * - * @return bool|int + * @return bool */ - public function directDataPacket(DataPacket $packet, bool $needACK = false){ - return $this->sendDataPacket($packet, $needACK, true); + public function directDataPacket(DataPacket $packet) : bool{ + return $this->sendDataPacket($packet, true); } /** diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index b7f1a0cc7b..0d4a6f1dfb 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1893,7 +1893,7 @@ class Server{ */ public function broadcastPacketsCallback(string $payload, array $players, bool $immediate = false){ foreach($players as $i){ - $i->getNetworkSession()->getInterface()->putPacket($i, $payload, false, $immediate); + $i->getNetworkSession()->getInterface()->putPacket($i, $payload, $immediate); } } diff --git a/src/pocketmine/network/NetworkInterface.php b/src/pocketmine/network/NetworkInterface.php index 461bc74401..f065268736 100644 --- a/src/pocketmine/network/NetworkInterface.php +++ b/src/pocketmine/network/NetworkInterface.php @@ -43,12 +43,9 @@ interface NetworkInterface{ * * @param Player $player * @param string $payload - * @param bool $needACK * @param bool $immediate - * - * @return int|null */ - public function putPacket(Player $player, string $payload, bool $needACK = false, bool $immediate = true) : ?int; + public function putPacket(Player $player, string $payload, bool $immediate = true) : void; /** * Terminates the connection diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index aca42af676..9aaeeda9f6 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -62,9 +62,6 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ /** @var string[] */ private $identifiers = []; - /** @var int[] */ - private $identifiersACK = []; - /** @var ServerHandler */ private $interface; @@ -111,7 +108,6 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $player = $this->players[$identifier]; unset($this->identifiers[spl_object_hash($player)]); unset($this->players[$identifier]); - unset($this->identifiersACK[$identifier]); $player->close($player->getLeaveMessage(), $reason); } } @@ -119,7 +115,6 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ public function close(Player $player, string $reason = "unknown reason") : void{ if(isset($this->identifiers[$h = spl_object_hash($player)])){ unset($this->players[$this->identifiers[$h]]); - unset($this->identifiersACK[$this->identifiers[$h]]); $this->interface->closeSession($this->identifiers[$h], $reason); unset($this->identifiers[$h]); } @@ -142,7 +137,6 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $player = new $class($this, $ev->getAddress(), $ev->getPort()); $this->players[$identifier] = $player; - $this->identifiersACK[$identifier] = 0; $this->identifiers[spl_object_hash($player)] = $identifier; $this->server->addPlayer($player); } @@ -214,21 +208,17 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ } } - public function putPacket(Player $player, string $payload, bool $needACK = false, bool $immediate = true) : ?int{ + public function putPacket(Player $player, string $payload, bool $immediate = true) : void{ if(isset($this->identifiers[$h = spl_object_hash($player)])){ $identifier = $this->identifiers[$h]; $pk = new EncapsulatedPacket(); - $pk->identifierACK = $this->identifiersACK[$identifier]++; $pk->buffer = self::MCPE_RAKNET_PACKET_ID . $payload; $pk->reliability = PacketReliability::RELIABLE_ORDERED; $pk->orderChannel = 0; - $this->interface->sendEncapsulated($identifier, $pk, ($needACK ? RakLib::FLAG_NEED_ACK : 0) | ($immediate ? RakLib::PRIORITY_IMMEDIATE : RakLib::PRIORITY_NORMAL)); - return $pk->identifierACK; + $this->interface->sendEncapsulated($identifier, $pk, ($immediate ? RakLib::PRIORITY_IMMEDIATE : RakLib::PRIORITY_NORMAL)); } - - return null; } public function updatePing(string $identifier, int $pingMS) : void{ From 7633136a86235eec507581fb6e6e4230f170e5e5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 20 Jul 2018 13:22:08 +0100 Subject: [PATCH 0033/3224] Player: move max players check to somewhere that makes sense --- src/pocketmine/Player.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 17997d025d..493c70bca3 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1846,10 +1846,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->locale = $packet->locale; } - if(count($this->server->getOnlinePlayers()) >= $this->server->getMaxPlayers() and $this->kick("disconnectionScreen.serverFull", false)){ - return true; - } - $this->randomClientId = $packet->clientId; $this->uuid = UUID::fromString($packet->clientUUID); @@ -1878,6 +1874,10 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return true; } + if(count($this->server->getOnlinePlayers()) >= $this->server->getMaxPlayers() and $this->kick("disconnectionScreen.serverFull", false)){ + return true; + } + if(!$this->server->isWhitelisted($this->iusername) and $this->kick("Server is white-listed", false)){ return true; } From a4939b6bf11e3da6f3ffc569540fafd8eba84545 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 20 Jul 2018 15:34:47 +0100 Subject: [PATCH 0034/3224] Player: re-structure a whole bunch of construction mess This consolidates the Player entity construction and makes it more organized and consistent. There is of course a lot more work to do apart from this on player construction. --- src/pocketmine/Player.php | 156 ++++++++++++++++++-------------------- 1 file changed, 75 insertions(+), 81 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 493c70bca3..53f928e4fc 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1803,15 +1803,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return ($targetDot - $eyeDot) >= -$maxDiff; } - protected function initHumanData() : void{ - $this->setNameTag($this->username); - } - - protected function initEntity() : void{ - parent::initEntity(); - $this->addDefaultWindows(); - } - public function handleLogin(LoginPacket $packet) : bool{ if($this->loggedIn){ return false; @@ -1939,10 +1930,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ //TODO: encryption - $this->processLogin(); - } - - protected function processLogin(){ foreach($this->server->getLoggedInPlayers() as $p){ if($p !== $this and ($p->iusername === $this->iusername or $this->getUniqueId()->equals($p->getUniqueId()))){ if(!$p->kick("logged in from another location")){ @@ -1953,41 +1940,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } } - $this->namedtag = $this->server->getOfflinePlayerData($this->username); - - $this->playedBefore = ($this->getLastPlayed() - $this->getFirstPlayed()) > 1; // microtime(true) - microtime(true) may have less than one millisecond difference - $this->namedtag->setString("NameTag", $this->username); - - $this->gamemode = $this->namedtag->getInt("playerGameType", self::SURVIVAL) & 0x03; - if($this->server->getForceGamemode()){ - $this->gamemode = $this->server->getGamemode(); - $this->namedtag->setInt("playerGameType", $this->gamemode); - } - - $this->allowFlight = $this->isCreative(); - $this->keepMovement = $this->isSpectator() || $this->allowMovementCheats(); - - if(($level = $this->server->getLevelByName($this->namedtag->getString("Level", "", true))) === null){ - $this->setLevel($this->server->getDefaultLevel()); - $this->namedtag->setString("Level", $this->level->getFolderName()); - $spawnLocation = $this->level->getSafeSpawn(); - $this->namedtag->setTag(new ListTag("Pos", [ - new DoubleTag("", $spawnLocation->x), - new DoubleTag("", $spawnLocation->y), - new DoubleTag("", $spawnLocation->z) - ])); - }else{ - $this->setLevel($level); - } - - $this->achievements = []; - - $achievements = $this->namedtag->getCompoundTag("Achievements") ?? []; - /** @var ByteTag $achievement */ - foreach($achievements as $achievement){ - $this->achievements[$achievement->getName()] = $achievement->getValue() !== 0; - } - $this->sendPlayStatus(PlayStatusPacket::LOGIN_SUCCESS); $this->loggedIn = true; @@ -2036,7 +1988,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->dataPacket($pk); break; case ResourcePackClientResponsePacket::STATUS_COMPLETED: - $this->completeLoginSequence(); + $this->_actuallyConstruct(); break; default: return false; @@ -2045,12 +1997,28 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return true; } - protected function completeLoginSequence(){ - /** @var float[] $pos */ - $pos = $this->namedtag->getListTag("Pos")->getAllValues(); - $this->level->registerChunkLoader($this, ((int) floor($pos[0])) >> 4, ((int) floor($pos[2])) >> 4, true); + protected function _actuallyConstruct(){ + $namedtag = $this->server->getOfflinePlayerData($this->username); //TODO: make this async + + if(($level = $this->server->getLevelByName($namedtag->getString("Level", "", true))) === null){ + /** @var Level $level */ + $level = $this->server->getDefaultLevel(); //TODO: default level may be null + + $namedtag->setString("Level", $level->getFolderName()); + $spawnLocation = $level->getSafeSpawn(); + $namedtag->setTag(new ListTag("Pos", [ + new DoubleTag("", $spawnLocation->x), + new DoubleTag("", $spawnLocation->y), + new DoubleTag("", $spawnLocation->z) + ])); + } + + /** @var float[] $pos */ + $pos = $namedtag->getListTag("Pos")->getAllValues(); + $level->registerChunkLoader($this, ((int) floor($pos[0])) >> 4, ((int) floor($pos[2])) >> 4, true); + + parent::__construct($level, $namedtag); - parent::__construct($this->level, $this->namedtag); $this->server->getPluginManager()->callEvent($ev = new PlayerLoginEvent($this, "Plugin reason")); if($ev->isCancelled()){ $this->close($this->getLeaveMessage(), $ev->getKickMessage()); @@ -2058,14 +2026,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return; } - if(!$this->hasValidSpawnPosition()){ - if(($level = $this->server->getLevelByName($this->namedtag->getString("SpawnLevel", ""))) instanceof Level){ - $this->spawnPosition = new Position($this->namedtag->getInt("SpawnX"), $this->namedtag->getInt("SpawnY"), $this->namedtag->getInt("SpawnZ"), $level); - }else{ - $this->spawnPosition = $this->level->getSafeSpawn(); - } - } - $spawnPosition = $this->getSpawn(); $pk = new StartGamePacket(); @@ -2097,25 +2057,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->level->sendTime($this); $this->sendAttributes(true); - $this->setNameTagVisible(); - $this->setNameTagAlwaysVisible(); - $this->setCanClimb(); - - $this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logIn", [ - TextFormat::AQUA . $this->username . TextFormat::WHITE, - $this->networkSession->getIp(), - $this->networkSession->getPort(), - $this->id, - $this->level->getName(), - round($this->x, 4), - round($this->y, 4), - round($this->z, 4) - ])); - - if($this->isOp()){ - $this->setRemoveFormat(false); - } - $this->sendCommandData(); $this->sendSettings(); $this->sendPotionEffects($this); @@ -2128,6 +2069,59 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->server->addOnlinePlayer($this); $this->server->sendFullPlayerListData($this); + + $this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logIn", [ + TextFormat::AQUA . $this->username . TextFormat::WHITE, + $this->networkSession->getIp(), + $this->networkSession->getPort(), + $this->id, + $this->level->getName(), + round($this->x, 4), + round($this->y, 4), + round($this->z, 4) + ])); + } + + protected function initHumanData() : void{ + $this->setNameTag($this->username); + } + + protected function initEntity() : void{ + parent::initEntity(); + $this->addDefaultWindows(); + + $this->playedBefore = ($this->getLastPlayed() - $this->getFirstPlayed()) > 1; // microtime(true) - microtime(true) may have less than one millisecond difference + + $this->gamemode = $this->namedtag->getInt("playerGameType", self::SURVIVAL) & 0x03; + if($this->server->getForceGamemode()){ + $this->gamemode = $this->server->getGamemode(); + $this->namedtag->setInt("playerGameType", $this->gamemode); + } + + $this->setAllowFlight($this->isCreative()); + $this->keepMovement = $this->isSpectator() || $this->allowMovementCheats(); + if($this->isOp()){ + $this->setRemoveFormat(false); + } + + $this->setNameTagVisible(); + $this->setNameTagAlwaysVisible(); + $this->setCanClimb(); + + $this->achievements = []; + $achievements = $this->namedtag->getCompoundTag("Achievements") ?? []; + /** @var ByteTag $achievement */ + foreach($achievements as $achievement){ + $this->achievements[$achievement->getName()] = $achievement->getValue() !== 0; + } + + if(!$this->hasValidSpawnPosition()){ + if(($level = $this->server->getLevelByName($this->namedtag->getString("SpawnLevel", ""))) instanceof Level){ + $this->spawnPosition = new Position($this->namedtag->getInt("SpawnX"), $this->namedtag->getInt("SpawnY"), $this->namedtag->getInt("SpawnZ"), $level); + }else{ + $this->spawnPosition = $this->level->getSafeSpawn(); + } + } } /** From 97a1483f758cf13215f548f2227f279db020abb7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 20 Jul 2018 15:38:53 +0100 Subject: [PATCH 0035/3224] Player: remove useless crap from "constructor" 1. this isn't really the player constructor 2. this shit isn't needed until we start using the player as an actual player --- src/pocketmine/Player.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 53f928e4fc..c71033b7cb 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -88,7 +88,6 @@ use pocketmine\level\format\Chunk; use pocketmine\level\Level; use pocketmine\level\Location; use pocketmine\level\Position; -use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; use pocketmine\metadata\MetadataValue; use pocketmine\nbt\NetworkLittleEndianNBTStream; @@ -688,14 +687,10 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ */ public function __construct(NetworkInterface $interface, string $ip, int $port){ $this->perm = new PermissibleBase($this); - $this->namedtag = new CompoundTag(); $this->server = Server::getInstance(); $this->loaderId = Level::generateChunkLoaderId($this); $this->chunksPerTick = (int) $this->server->getProperty("chunk-sending.per-tick", 4); $this->spawnThreshold = (int) (($this->server->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); - $this->gamemode = $this->server->getGamemode(); - $this->setLevel($this->server->getDefaultLevel()); - $this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0); $this->creationTime = microtime(true); From f626b9e8a079cfa2d12f9daaeea8d59e223841e6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 20 Jul 2018 17:09:04 +0100 Subject: [PATCH 0036/3224] Initial mass migration to session handlers This introduces several new session handlers, splitting up session handling into several new states: - Login: Only allows handling the LoginPacket. This is the only time LoginPacket can be sent, and it'll be discarded when sent at any other time. - Resource packs: Handles only the resource packs sequence (downloading packs and such). This is the only time ResourcePackClientResponse and ResourcePackChunkRequest will be handled. - Pre-spawn: Only chunk radius requests are accepted during this state. SimpleNetworkHandler handles all the "rest" of the logic that hasn't yet been separated out into their own dedicated handlers. There's also a NullNetworkHandler which discards all packets while it's active. This solves a large number of issues with the security of the login sequence. It solves a range of possible DoS attacks and crashes, while also allowing great code simplification and cleanup. --- src/pocketmine/Player.php | 216 ++---------------- .../network/mcpe/NetworkSession.php | 31 ++- .../mcpe/handler/LoginSessionHandler.php | 89 ++++++++ .../mcpe/handler/NullSessionHandler.php | 31 +++ .../mcpe/handler/PreSpawnSessionHandler.php | 99 ++++++++ .../handler/ResourcePacksSessionHandler.php | 128 +++++++++++ .../mcpe/handler/SimpleSessionHandler.php | 15 -- .../network/mcpe/protocol/LoginPacket.php | 13 +- 8 files changed, 409 insertions(+), 213 deletions(-) create mode 100644 src/pocketmine/network/mcpe/handler/LoginSessionHandler.php create mode 100644 src/pocketmine/network/mcpe/handler/NullSessionHandler.php create mode 100644 src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php create mode 100644 src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index c71033b7cb..f5cf359986 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -114,26 +114,16 @@ use pocketmine\network\mcpe\protocol\MobEffectPacket; use pocketmine\network\mcpe\protocol\MobEquipmentPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\PlayerActionPacket; -use pocketmine\network\mcpe\protocol\PlayStatusPacket; -use pocketmine\network\mcpe\protocol\ProtocolInfo; -use pocketmine\network\mcpe\protocol\ResourcePackChunkDataPacket; -use pocketmine\network\mcpe\protocol\ResourcePackChunkRequestPacket; -use pocketmine\network\mcpe\protocol\ResourcePackClientResponsePacket; -use pocketmine\network\mcpe\protocol\ResourcePackDataInfoPacket; -use pocketmine\network\mcpe\protocol\ResourcePacksInfoPacket; -use pocketmine\network\mcpe\protocol\ResourcePackStackPacket; use pocketmine\network\mcpe\protocol\RespawnPacket; use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket; use pocketmine\network\mcpe\protocol\SetTitlePacket; -use pocketmine\network\mcpe\protocol\StartGamePacket; use pocketmine\network\mcpe\protocol\TextPacket; use pocketmine\network\mcpe\protocol\TransferPacket; use pocketmine\network\mcpe\protocol\types\CommandData; use pocketmine\network\mcpe\protocol\types\CommandEnum; use pocketmine\network\mcpe\protocol\types\CommandParameter; use pocketmine\network\mcpe\protocol\types\ContainerIds; -use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; @@ -143,7 +133,6 @@ use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissionAttachment; use pocketmine\permission\PermissionAttachmentInfo; use pocketmine\plugin\Plugin; -use pocketmine\resourcepacks\ResourcePack; use pocketmine\tile\ItemFrame; use pocketmine\tile\Spawnable; use pocketmine\tile\Tile; @@ -182,9 +171,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ /** @var NetworkSession */ protected $networkSession; - /** @var int */ - protected $protocol = -1; - /** * @var int * Last measurement of player's latency in milliseconds. @@ -993,7 +979,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ protected function doFirstSpawn(){ $this->spawned = true; - $this->sendPlayStatus(PlayStatusPacket::PLAYER_SPAWN); + $this->networkSession->onSpawn(); if($this->hasPermission(Server::BROADCAST_CHANNEL_USERS)){ $this->server->getPluginManager()->subscribeToPermission(Server::BROADCAST_CHANNEL_USERS, $this); @@ -1799,59 +1785,17 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } public function handleLogin(LoginPacket $packet) : bool{ - if($this->loggedIn){ - return false; - } - - $this->protocol = $packet->protocol; - - if($packet->protocol !== ProtocolInfo::CURRENT_PROTOCOL){ - if($packet->protocol < ProtocolInfo::CURRENT_PROTOCOL){ - $this->sendPlayStatus(PlayStatusPacket::LOGIN_FAILED_CLIENT, true); - }else{ - $this->sendPlayStatus(PlayStatusPacket::LOGIN_FAILED_SERVER, true); - } - - //This pocketmine disconnect message will only be seen by the console (PlayStatusPacket causes the messages to be shown for the client) - $this->close("", $this->server->getLanguage()->translateString("pocketmine.disconnect.incompatibleProtocol", [$packet->protocol ?? "unknown"]), false); - - return true; - } - - if(!self::isValidUserName($packet->username)){ - $this->close("", "disconnectionScreen.invalidName"); - - return true; - } - $this->username = TextFormat::clean($packet->username); $this->displayName = $this->username; $this->iusername = strtolower($this->username); - - if($packet->locale !== null){ - $this->locale = $packet->locale; - } - + $this->locale = $packet->locale; $this->randomClientId = $packet->clientId; $this->uuid = UUID::fromString($packet->clientUUID); $this->rawUUID = $this->uuid->toBinary(); - $skin = new Skin( - $packet->clientData["SkinId"], - base64_decode($packet->clientData["SkinData"] ?? ""), - base64_decode($packet->clientData["CapeData"] ?? ""), - $packet->clientData["SkinGeometryName"] ?? "", - base64_decode($packet->clientData["SkinGeometry"] ?? "") - ); + $this->setSkin($packet->skin); - if(!$skin->isValid()){ - $this->close("", "disconnectionScreen.invalidSkin"); - - return true; - } - - $this->setSkin($skin); $this->server->getPluginManager()->callEvent($ev = new PlayerPreLoginEvent($this, "Plugin reason")); if($ev->isCancelled()){ @@ -1884,13 +1828,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return true; } - public function sendPlayStatus(int $status, bool $immediate = false){ - $pk = new PlayStatusPacket(); - $pk->status = $status; - $pk->protocol = $this->protocol; - $this->sendDataPacket($pk, $immediate); - } - public function onVerifyCompleted(LoginPacket $packet, ?string $error, bool $signedByMojang) : void{ if($this->closed){ return; @@ -1935,64 +1872,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } } - $this->sendPlayStatus(PlayStatusPacket::LOGIN_SUCCESS); - $this->loggedIn = true; $this->server->onPlayerLogin($this); - - $pk = new ResourcePacksInfoPacket(); - $manager = $this->server->getResourcePackManager(); - $pk->resourcePackEntries = $manager->getResourceStack(); - $pk->mustAccept = $manager->resourcePacksRequired(); - $this->dataPacket($pk); + $this->networkSession->onLoginSuccess(); } - public function handleResourcePackClientResponse(ResourcePackClientResponsePacket $packet) : bool{ - switch($packet->status){ - case ResourcePackClientResponsePacket::STATUS_REFUSED: - //TODO: add lang strings for this - $this->close("", "You must accept resource packs to join this server.", true); - break; - case ResourcePackClientResponsePacket::STATUS_SEND_PACKS: - $manager = $this->server->getResourcePackManager(); - foreach($packet->packIds as $uuid){ - $pack = $manager->getPackById($uuid); - if(!($pack instanceof ResourcePack)){ - //Client requested a resource pack but we don't have it available on the server - $this->close("", "disconnectionScreen.resourcePack", true); - $this->server->getLogger()->debug("Got a resource pack request for unknown pack with UUID " . $uuid . ", available packs: " . implode(", ", $manager->getPackIdList())); - - return false; - } - - $pk = new ResourcePackDataInfoPacket(); - $pk->packId = $pack->getPackId(); - $pk->maxChunkSize = 1048576; //1MB - $pk->chunkCount = (int) ceil($pack->getPackSize() / $pk->maxChunkSize); - $pk->compressedPackSize = $pack->getPackSize(); - $pk->sha256 = $pack->getSha256(); - $this->dataPacket($pk); - } - - break; - case ResourcePackClientResponsePacket::STATUS_HAVE_ALL_PACKS: - $pk = new ResourcePackStackPacket(); - $manager = $this->server->getResourcePackManager(); - $pk->resourcePackStack = $manager->getResourceStack(); - $pk->mustAccept = $manager->resourcePacksRequired(); - $this->dataPacket($pk); - break; - case ResourcePackClientResponsePacket::STATUS_COMPLETED: - $this->_actuallyConstruct(); - break; - default: - return false; - } - - return true; - } - - protected function _actuallyConstruct(){ + public function _actuallyConstruct(){ $namedtag = $this->server->getOfflinePlayerData($this->username); //TODO: make this async if(($level = $this->server->getLevelByName($namedtag->getString("Level", "", true))) === null){ @@ -2021,50 +1906,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return; } - $spawnPosition = $this->getSpawn(); - - $pk = new StartGamePacket(); - $pk->entityUniqueId = $this->id; - $pk->entityRuntimeId = $this->id; - $pk->playerGamemode = Player::getClientFriendlyGamemode($this->gamemode); - - $pk->playerPosition = $this->getOffsetPosition($this); - - $pk->pitch = $this->pitch; - $pk->yaw = $this->yaw; - $pk->seed = -1; - $pk->dimension = DimensionIds::OVERWORLD; //TODO: implement this properly - $pk->worldGamemode = Player::getClientFriendlyGamemode($this->server->getGamemode()); - $pk->difficulty = $this->level->getDifficulty(); - $pk->spawnX = $spawnPosition->getFloorX(); - $pk->spawnY = $spawnPosition->getFloorY(); - $pk->spawnZ = $spawnPosition->getFloorZ(); - $pk->hasAchievementsDisabled = true; - $pk->time = $this->level->getTime(); - $pk->eduMode = false; - $pk->rainLevel = 0; //TODO: implement these properly - $pk->lightningLevel = 0; - $pk->commandsEnabled = true; - $pk->levelId = ""; - $pk->worldName = $this->server->getMotd(); - $this->dataPacket($pk); - - $this->level->sendTime($this); - - $this->sendAttributes(true); - $this->sendCommandData(); - $this->sendSettings(); - $this->sendPotionEffects($this); - $this->sendData($this); - - $this->sendAllInventories(); - $this->inventory->sendCreativeContents(); - $this->inventory->sendHeldItem($this); - $this->networkSession->getInterface()->putPacket($this, $this->server->getCraftingManager()->getCraftingDataPacket()); - - $this->server->addOnlinePlayer($this); - $this->server->sendFullPlayerListData($this); - $this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logIn", [ TextFormat::AQUA . $this->username . TextFormat::WHITE, $this->networkSession->getIp(), @@ -2075,6 +1916,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ round($this->y, 4), round($this->z, 4) ])); + + $this->server->addOnlinePlayer($this); } protected function initHumanData() : void{ @@ -2128,7 +1971,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ * @return bool */ public function chat(string $message) : bool{ - if(!$this->spawned or !$this->isAlive()){ + if(!$this->isAlive()){ return false; } @@ -2172,7 +2015,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->sendPosition($this, null, null, MovePlayerPacket::MODE_RESET); $this->server->getLogger()->debug("Got outdated pre-teleport movement from " . $this->getName() . ", received " . $newPos . ", expected " . $this->asVector3()); //Still getting movements from before teleport, ignore them - }elseif((!$this->isAlive() or !$this->spawned) and $newPos->distanceSquared($this) > 0.01){ + }elseif((!$this->isAlive()) and $newPos->distanceSquared($this) > 0.01){ $this->sendPosition($this, null, null, MovePlayerPacket::MODE_RESET); $this->server->getLogger()->debug("Reverted movement of " . $this->getName() . " due to not alive or not spawned, received " . $newPos . ", locked at " . $this->asVector3()); }else{ @@ -2204,7 +2047,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } public function handleEntityEvent(EntityEventPacket $packet) : bool{ - if(!$this->spawned or !$this->isAlive()){ + if(!$this->isAlive()){ return true; } $this->doCloseInventory(); @@ -2232,7 +2075,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ * @return bool */ public function handleInventoryTransaction(InventoryTransactionPacket $packet) : bool{ - if(!$this->spawned or !$this->isAlive()){ + if(!$this->isAlive()){ return false; } @@ -2594,7 +2437,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } public function handleMobEquipment(MobEquipmentPacket $packet) : bool{ - if(!$this->spawned or !$this->isAlive()){ + if(!$this->isAlive()){ return true; } @@ -2644,7 +2487,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } public function handlePlayerAction(PlayerActionPacket $packet) : bool{ - if(!$this->spawned or (!$this->isAlive() and $packet->action !== PlayerActionPacket::ACTION_RESPAWN and $packet->action !== PlayerActionPacket::ACTION_DIMENSION_CHANGE_REQUEST)){ + if(!$this->isAlive() and $packet->action !== PlayerActionPacket::ACTION_RESPAWN and $packet->action !== PlayerActionPacket::ACTION_DIMENSION_CHANGE_REQUEST){ return true; } @@ -2668,7 +2511,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->stopSleep(); break; case PlayerActionPacket::ACTION_RESPAWN: - if(!$this->spawned or $this->isAlive() or !$this->isOnline()){ + if($this->isAlive() or !$this->isOnline()){ break; } @@ -2781,7 +2624,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } public function handleAnimate(AnimatePacket $packet) : bool{ - if(!$this->spawned or !$this->isAlive()){ + if(!$this->isAlive()){ return true; } @@ -2805,7 +2648,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ * @return bool if the item was dropped or if the item was null */ public function dropItem(Item $item) : bool{ - if(!$this->spawned or !$this->isAlive()){ + if(!$this->isAlive()){ return false; } @@ -2854,7 +2697,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } public function handleBlockEntityData(BlockEntityDataPacket $packet) : bool{ - if(!$this->spawned or !$this->isAlive()){ + if(!$this->isAlive()){ return true; } $this->doCloseInventory(); @@ -2890,7 +2733,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } public function handleItemFrameDropItem(ItemFrameDropItemPacket $packet) : bool{ - if(!$this->spawned or !$this->isAlive()){ + if(!$this->isAlive()){ return true; } @@ -2917,25 +2760,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return true; } - public function handleResourcePackChunkRequest(ResourcePackChunkRequestPacket $packet) : bool{ - $manager = $this->server->getResourcePackManager(); - $pack = $manager->getPackById($packet->packId); - if(!($pack instanceof ResourcePack)){ - $this->close("", "disconnectionScreen.resourcePack", true); - $this->server->getLogger()->debug("Got a resource pack chunk request for unknown pack with UUID " . $packet->packId . ", available packs: " . implode(", ", $manager->getPackIdList())); - - return false; - } - - $pk = new ResourcePackChunkDataPacket(); - $pk->packId = $pack->getPackId(); - $pk->chunkIndex = $packet->chunkIndex; - $pk->data = $pack->getPackChunk(1048576 * $packet->chunkIndex, 1048576); - $pk->progress = (1048576 * $packet->chunkIndex); - $this->dataPacket($pk); - return true; - } - public function handleBookEdit(BookEditPacket $packet) : bool{ /** @var WritableBook $oldBook */ $oldBook = $this->inventory->getItem($packet->inventorySlot); @@ -3732,7 +3556,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ * @return bool */ public function doCloseWindow(int $windowId) : bool{ - if(!$this->spawned or $windowId === 0){ + if($windowId === 0){ return false; } @@ -3844,7 +3668,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } } - protected function sendAllInventories(){ + public function sendAllInventories(){ foreach($this->windowIndex as $id => $inventory){ $inventory->sendContents($this); } diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 6cd32b6834..a0ec1bf97d 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -25,11 +25,15 @@ namespace pocketmine\network\mcpe; use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\event\server\DataPacketSendEvent; +use pocketmine\network\mcpe\handler\LoginSessionHandler; +use pocketmine\network\mcpe\handler\PreSpawnSessionHandler; +use pocketmine\network\mcpe\handler\ResourcePacksSessionHandler; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\handler\SimpleSessionHandler; use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\DisconnectPacket; use pocketmine\network\mcpe\protocol\PacketPool; +use pocketmine\network\mcpe\protocol\PlayStatusPacket; use pocketmine\network\NetworkInterface; use pocketmine\Player; use pocketmine\Server; @@ -60,7 +64,7 @@ class NetworkSession{ $this->ip = $ip; $this->port = $port; - $this->setHandler(new SimpleSessionHandler($player)); + $this->setHandler(new LoginSessionHandler($player, $this)); } public function getInterface() : NetworkInterface{ @@ -144,4 +148,29 @@ class NetworkSession{ } $this->interface->close($this->player, $notify ? $reason : ""); } + + //TODO: onEnableEncryption() step + + public function onLoginSuccess() : void{ + $pk = new PlayStatusPacket(); + $pk->status = PlayStatusPacket::LOGIN_SUCCESS; + $this->sendDataPacket($pk); + + $this->setHandler(new ResourcePacksSessionHandler($this->server, $this->player, $this)); + } + + public function onResourcePacksDone() : void{ + $this->player->_actuallyConstruct(); + + $this->setHandler(new PreSpawnSessionHandler($this->server, $this->player, $this)); + } + + public function onSpawn() : void{ + $pk = new PlayStatusPacket(); + $pk->status = PlayStatusPacket::PLAYER_SPAWN; + $this->sendDataPacket($pk); + + //TODO: split this up even further + $this->setHandler(new SimpleSessionHandler($this->player)); + } } diff --git a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php new file mode 100644 index 0000000000..a65854f49d --- /dev/null +++ b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php @@ -0,0 +1,89 @@ +player = $player; + $this->session = $session; + } + + public function handleLogin(LoginPacket $packet) : bool{ + if(!$this->isCompatibleProtocol($packet->protocol)){ + $pk = new PlayStatusPacket(); + $pk->status = $packet->protocol < ProtocolInfo::CURRENT_PROTOCOL ? + PlayStatusPacket::LOGIN_FAILED_CLIENT : PlayStatusPacket::LOGIN_FAILED_SERVER; + $pk->protocol = $packet->protocol; + $this->session->sendDataPacket($pk, true); + + //This pocketmine disconnect message will only be seen by the console (PlayStatusPacket causes the messages to be shown for the client) + $this->player->close( + "", + $this->player->getServer()->getLanguage()->translateString("pocketmine.disconnect.incompatibleProtocol", [$packet->protocol]), + false + ); + + return true; + } + + if(!Player::isValidUserName($packet->username)){ + $this->player->close("", "disconnectionScreen.invalidName"); + + return true; + } + + if($packet->skin === null or !$packet->skin->isValid()){ + $this->player->close("", "disconnectionScreen.invalidSkin"); + + return true; + } + + if($this->player->handleLogin($packet)){ + if($this->session->getHandler() === $this){ //when login verification is disabled, the handler will already have been replaced + $this->session->setHandler(new NullSessionHandler()); //drop packets received during login verification + } + return true; + } + return false; + } + + protected function isCompatibleProtocol(int $protocolVersion) : bool{ + return $protocolVersion === ProtocolInfo::CURRENT_PROTOCOL; + } +} diff --git a/src/pocketmine/network/mcpe/handler/NullSessionHandler.php b/src/pocketmine/network/mcpe/handler/NullSessionHandler.php new file mode 100644 index 0000000000..a36a3989db --- /dev/null +++ b/src/pocketmine/network/mcpe/handler/NullSessionHandler.php @@ -0,0 +1,31 @@ +player = $player; + $this->server = $server; + $this->session = $session; + } + + public function setUp() : void{ + $spawnPosition = $this->player->getSpawn(); + + $pk = new StartGamePacket(); + $pk->entityUniqueId = $this->player->getId(); + $pk->entityRuntimeId = $this->player->getId(); + $pk->playerGamemode = Player::getClientFriendlyGamemode($this->player->getGamemode()); + $pk->playerPosition = $this->player->getOffsetPosition($this->player); + $pk->pitch = $this->player->pitch; + $pk->yaw = $this->player->yaw; + $pk->seed = -1; + $pk->dimension = DimensionIds::OVERWORLD; //TODO: implement this properly + $pk->worldGamemode = Player::getClientFriendlyGamemode($this->server->getGamemode()); + $pk->difficulty = $this->player->getLevel()->getDifficulty(); + $pk->spawnX = $spawnPosition->getFloorX(); + $pk->spawnY = $spawnPosition->getFloorY(); + $pk->spawnZ = $spawnPosition->getFloorZ(); + $pk->hasAchievementsDisabled = true; + $pk->time = $this->player->getLevel()->getTime(); + $pk->eduMode = false; + $pk->rainLevel = 0; //TODO: implement these properly + $pk->lightningLevel = 0; + $pk->commandsEnabled = true; + $pk->levelId = ""; + $pk->worldName = $this->server->getMotd(); + $this->session->sendDataPacket($pk); + + $this->player->getLevel()->sendTime($this->player); + + $this->player->sendAttributes(true); + $this->player->sendCommandData(); + $this->player->sendSettings(); + $this->player->sendPotionEffects($this->player); + $this->player->sendData($this->player); + + $this->player->sendAllInventories(); + $this->player->getInventory()->sendCreativeContents(); + $this->player->getInventory()->sendHeldItem($this->player); + $this->session->getInterface()->putPacket($this->player, $this->server->getCraftingManager()->getCraftingDataPacket()); + + $this->server->sendFullPlayerListData($this->player); + } + + public function handleRequestChunkRadius(RequestChunkRadiusPacket $packet) : bool{ + $this->player->setViewDistance($packet->radius); + + return true; + } +} diff --git a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php new file mode 100644 index 0000000000..cfb50ed9d8 --- /dev/null +++ b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php @@ -0,0 +1,128 @@ +server = $server; + $this->player = $player; + $this->session = $session; + } + + public function setUp() : void{ + $pk = new ResourcePacksInfoPacket(); + $manager = $this->server->getResourcePackManager(); + $pk->resourcePackEntries = $manager->getResourceStack(); + $pk->mustAccept = $manager->resourcePacksRequired(); + $this->session->sendDataPacket($pk); + } + + public function handleResourcePackClientResponse(ResourcePackClientResponsePacket $packet) : bool{ + switch($packet->status){ + case ResourcePackClientResponsePacket::STATUS_REFUSED: + //TODO: add lang strings for this + $this->player->close("", "You must accept resource packs to join this server.", true); + break; + case ResourcePackClientResponsePacket::STATUS_SEND_PACKS: + $manager = $this->server->getResourcePackManager(); + foreach($packet->packIds as $uuid){ + $pack = $manager->getPackById($uuid); + if(!($pack instanceof ResourcePack)){ + //Client requested a resource pack but we don't have it available on the server + $this->player->close("", "disconnectionScreen.resourcePack", true); + $this->server->getLogger()->debug("Got a resource pack request for unknown pack with UUID " . $uuid . ", available packs: " . implode(", ", $manager->getPackIdList())); + + return false; + } + + $pk = new ResourcePackDataInfoPacket(); + $pk->packId = $pack->getPackId(); + $pk->maxChunkSize = 1048576; //1MB + $pk->chunkCount = (int) ceil($pack->getPackSize() / $pk->maxChunkSize); + $pk->compressedPackSize = $pack->getPackSize(); + $pk->sha256 = $pack->getSha256(); + $this->session->sendDataPacket($pk); + } + + break; + case ResourcePackClientResponsePacket::STATUS_HAVE_ALL_PACKS: + $pk = new ResourcePackStackPacket(); + $manager = $this->server->getResourcePackManager(); + $pk->resourcePackStack = $manager->getResourceStack(); + $pk->mustAccept = $manager->resourcePacksRequired(); + $this->session->sendDataPacket($pk); + break; + case ResourcePackClientResponsePacket::STATUS_COMPLETED: + $this->session->onResourcePacksDone(); + break; + default: + return false; + } + + return true; + } + + public function handleResourcePackChunkRequest(ResourcePackChunkRequestPacket $packet) : bool{ + $manager = $this->server->getResourcePackManager(); + $pack = $manager->getPackById($packet->packId); + if(!($pack instanceof ResourcePack)){ + $this->player->close("", "disconnectionScreen.resourcePack", true); + $this->server->getLogger()->debug("Got a resource pack chunk request for unknown pack with UUID " . $packet->packId . ", available packs: " . implode(", ", $manager->getPackIdList())); + + return false; + } + + $pk = new ResourcePackChunkDataPacket(); + $pk->packId = $pack->getPackId(); + $pk->chunkIndex = $packet->chunkIndex; + $pk->data = $pack->getPackChunk(1048576 * $packet->chunkIndex, 1048576); + $pk->progress = (1048576 * $packet->chunkIndex); + $this->session->sendDataPacket($pk); + + return true; + } +} diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index b640192bb0..7bad4b51e2 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -42,7 +42,6 @@ use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket; use pocketmine\network\mcpe\protocol\LabTablePacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; -use pocketmine\network\mcpe\protocol\LoginPacket; use pocketmine\network\mcpe\protocol\MapInfoRequestPacket; use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket; use pocketmine\network\mcpe\protocol\MobEquipmentPacket; @@ -53,8 +52,6 @@ use pocketmine\network\mcpe\protocol\PlayerHotbarPacket; use pocketmine\network\mcpe\protocol\PlayerInputPacket; use pocketmine\network\mcpe\protocol\PlayerSkinPacket; use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; -use pocketmine\network\mcpe\protocol\ResourcePackChunkRequestPacket; -use pocketmine\network\mcpe\protocol\ResourcePackClientResponsePacket; use pocketmine\network\mcpe\protocol\ServerSettingsRequestPacket; use pocketmine\network\mcpe\protocol\SetLocalPlayerAsInitializedPacket; use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; @@ -77,18 +74,10 @@ class SimpleSessionHandler extends SessionHandler{ $this->player = $player; } - public function handleLogin(LoginPacket $packet) : bool{ - return $this->player->handleLogin($packet); - } - public function handleClientToServerHandshake(ClientToServerHandshakePacket $packet) : bool{ return false; //TODO } - public function handleResourcePackClientResponse(ResourcePackClientResponsePacket $packet) : bool{ - return $this->player->handleResourcePackClientResponse($packet); - } - public function handleText(TextPacket $packet) : bool{ if($packet->type === TextPacket::TYPE_CHAT){ return $this->player->chat($packet->message); @@ -207,10 +196,6 @@ class SimpleSessionHandler extends SessionHandler{ return false; //TODO } - public function handleResourcePackChunkRequest(ResourcePackChunkRequestPacket $packet) : bool{ - return $this->player->handleResourcePackChunkRequest($packet); - } - public function handlePlayerSkin(PlayerSkinPacket $packet) : bool{ return $this->player->changeSkin($packet->skin, $packet->newSkinName, $packet->oldSkinName); } diff --git a/src/pocketmine/network/mcpe/protocol/LoginPacket.php b/src/pocketmine/network/mcpe/protocol/LoginPacket.php index af971f9522..d6aaff9eb8 100644 --- a/src/pocketmine/network/mcpe/protocol/LoginPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LoginPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\entity\Skin; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\utils\BinaryStream; use pocketmine\utils\MainLogger; @@ -52,6 +53,8 @@ class LoginPacket extends DataPacket{ public $serverAddress; /** @var string */ public $locale; + /** @var Skin|null */ + public $skin; /** @var array (the "chain" index contains one or more JWTs) */ public $chainData = []; @@ -136,7 +139,15 @@ class LoginPacket extends DataPacket{ $this->clientId = $this->clientData["ClientRandomId"] ?? null; $this->serverAddress = $this->clientData["ServerAddress"] ?? null; - $this->locale = $this->clientData["LanguageCode"] ?? null; + $this->locale = $this->clientData["LanguageCode"] ?? "en_US"; + + $this->skin = new Skin( + $this->clientData["SkinId"] ?? "", + base64_decode($this->clientData["SkinData"] ?? ""), + base64_decode($this->clientData["CapeData"] ?? ""), + $this->clientData["SkinGeometryName"] ?? "", + base64_decode($this->clientData["SkinGeometry"] ?? "") + ); } protected function encodePayload() : void{ From 015ee90571263c3514ec45d8dca4799341bf00d0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 20 Jul 2018 18:11:29 +0100 Subject: [PATCH 0037/3224] Split PlayerActionPacket handling into two classes, death is now a session state --- src/pocketmine/Player.php | 117 +----------------- .../network/mcpe/NetworkSession.php | 9 ++ .../mcpe/handler/DeathSessionHandler.php | 61 +++++++++ .../mcpe/handler/SimpleSessionHandler.php | 54 +++++++- 4 files changed, 128 insertions(+), 113 deletions(-) create mode 100644 src/pocketmine/network/mcpe/handler/DeathSessionHandler.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index f5cf359986..5f3b5a03d1 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -113,8 +113,6 @@ use pocketmine\network\mcpe\protocol\LoginPacket; use pocketmine\network\mcpe\protocol\MobEffectPacket; use pocketmine\network\mcpe\protocol\MobEquipmentPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; -use pocketmine\network\mcpe\protocol\PlayerActionPacket; -use pocketmine\network\mcpe\protocol\RespawnPacket; use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket; use pocketmine\network\mcpe\protocol\SetTitlePacket; @@ -1019,13 +1017,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } } - protected function sendRespawnPacket(Vector3 $pos){ - $pk = new RespawnPacket(); - $pk->position = $pos->add(0, $this->baseOffset, 0); - - $this->dataPacket($pk); - } - protected function orderChunks() : void{ if(!$this->isConnected() or $this->viewDistance === -1){ return; @@ -1489,7 +1480,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } protected function processMovement(int $tickDiff){ - if(!$this->isAlive() or !$this->spawned or $this->newPosition === null or $this->isSleeping()){ + if($this->newPosition === null or $this->isSleeping()){ return; } @@ -1971,10 +1962,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ * @return bool */ public function chat(string $message) : bool{ - if(!$this->isAlive()){ - return false; - } - $this->doCloseInventory(); $message = TextFormat::clean($message, $this->removeFormat); @@ -2015,9 +2002,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->sendPosition($this, null, null, MovePlayerPacket::MODE_RESET); $this->server->getLogger()->debug("Got outdated pre-teleport movement from " . $this->getName() . ", received " . $newPos . ", expected " . $this->asVector3()); //Still getting movements from before teleport, ignore them - }elseif((!$this->isAlive()) and $newPos->distanceSquared($this) > 0.01){ - $this->sendPosition($this, null, null, MovePlayerPacket::MODE_RESET); - $this->server->getLogger()->debug("Reverted movement of " . $this->getName() . " due to not alive or not spawned, received " . $newPos . ", locked at " . $this->asVector3()); }else{ // Once we get a movement within a reasonable distance, treat it as a teleport ACK and remove position lock if($this->isTeleporting){ @@ -2047,9 +2031,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } public function handleEntityEvent(EntityEventPacket $packet) : bool{ - if(!$this->isAlive()){ - return true; - } $this->doCloseInventory(); switch($packet->event){ @@ -2075,10 +2056,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ * @return bool */ public function handleInventoryTransaction(InventoryTransactionPacket $packet) : bool{ - if(!$this->isAlive()){ - return false; - } - if($this->isSpectator()){ $this->sendAllInventories(); return true; @@ -2437,10 +2414,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } public function handleMobEquipment(MobEquipmentPacket $packet) : bool{ - if(!$this->isAlive()){ - return true; - } - $item = $this->inventory->getItem($packet->hotbarSlot); if(!$item->equals($packet->item)){ @@ -2486,73 +2459,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } - public function handlePlayerAction(PlayerActionPacket $packet) : bool{ - if(!$this->isAlive() and $packet->action !== PlayerActionPacket::ACTION_RESPAWN and $packet->action !== PlayerActionPacket::ACTION_DIMENSION_CHANGE_REQUEST){ - return true; - } - - $packet->entityRuntimeId = $this->id; - $pos = new Vector3($packet->x, $packet->y, $packet->z); - - switch($packet->action){ - case PlayerActionPacket::ACTION_START_BREAK: - $this->startBreakBlock($pos, $packet->face); - - break; - - case PlayerActionPacket::ACTION_ABORT_BREAK: - case PlayerActionPacket::ACTION_STOP_BREAK: - $this->stopBreakBlock($pos); - break; - case PlayerActionPacket::ACTION_START_SLEEPING: - //unused - break; - case PlayerActionPacket::ACTION_STOP_SLEEPING: - $this->stopSleep(); - break; - case PlayerActionPacket::ACTION_RESPAWN: - if($this->isAlive() or !$this->isOnline()){ - break; - } - - $this->respawn(); - break; - case PlayerActionPacket::ACTION_JUMP: - $this->jump(); - return true; - case PlayerActionPacket::ACTION_START_SPRINT: - $this->toggleSprint(true); - return true; - case PlayerActionPacket::ACTION_STOP_SPRINT: - $this->toggleSprint(false); - return true; - case PlayerActionPacket::ACTION_START_SNEAK: - $this->toggleSneak(true); - return true; - case PlayerActionPacket::ACTION_STOP_SNEAK: - $this->toggleSneak(false); - return true; - case PlayerActionPacket::ACTION_START_GLIDE: - case PlayerActionPacket::ACTION_STOP_GLIDE: - break; //TODO - case PlayerActionPacket::ACTION_CONTINUE_BREAK: - $this->continueBreakBlock($pos, $packet->face); - break; - case PlayerActionPacket::ACTION_START_SWIMMING: - break; //TODO - case PlayerActionPacket::ACTION_STOP_SWIMMING: - //TODO: handle this when it doesn't spam every damn tick (yet another spam bug!!) - break; - default: - $this->server->getLogger()->debug("Unhandled/unknown player action type " . $packet->action . " from " . $this->getName()); - return false; - } - - $this->setUsingItem(false); - - return true; - } - public function startBreakBlock(Vector3 $pos, int $face) : bool{ if($pos->distanceSquared($this) > 10000){ return false; //TODO: maybe this should throw an exception instead? @@ -2624,10 +2530,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } public function handleAnimate(AnimatePacket $packet) : bool{ - if(!$this->isAlive()){ - return true; - } - $this->server->getPluginManager()->callEvent($ev = new PlayerAnimationEvent($this, $packet->action)); if($ev->isCancelled()){ return true; @@ -2648,10 +2550,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ * @return bool if the item was dropped or if the item was null */ public function dropItem(Item $item) : bool{ - if(!$this->isAlive()){ - return false; - } - if($item->isNull()){ $this->server->getLogger()->debug($this->getName() . " attempted to drop a null item (" . $item . ")"); return true; @@ -2697,9 +2595,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } public function handleBlockEntityData(BlockEntityDataPacket $packet) : bool{ - if(!$this->isAlive()){ - return true; - } $this->doCloseInventory(); $pos = new Vector3($packet->x, $packet->y, $packet->z); @@ -2733,10 +2628,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } public function handleItemFrameDropItem(ItemFrameDropItemPacket $packet) : bool{ - if(!$this->isAlive()){ - return true; - } - $tile = $this->level->getTileAt($packet->x, $packet->y, $packet->z); if($tile instanceof ItemFrame){ $ev = new PlayerInteractEvent($this, $this->inventory->getItemInHand(), $tile->getBlock(), null, 5 - $tile->getBlock()->getDamage(), PlayerInteractEvent::LEFT_CLICK_BLOCK); @@ -3223,7 +3114,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ parent::kill(); - $this->sendRespawnPacket($this->getSpawn()); + $this->networkSession->onDeath(); } protected function onDeath() : void{ @@ -3372,7 +3263,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return false; //never flag players for despawn } - protected function respawn() : void{ + public function respawn() : void{ if($this->server->isHardcore()){ $this->setBanned(true); return; @@ -3406,6 +3297,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->spawnToAll(); $this->scheduleUpdate(); + + $this->networkSession->onRespawn(); } protected function applyPostDamageEffects(EntityDamageEvent $source) : void{ diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index a0ec1bf97d..c7f19f646b 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe; use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\event\server\DataPacketSendEvent; +use pocketmine\network\mcpe\handler\DeathSessionHandler; use pocketmine\network\mcpe\handler\LoginSessionHandler; use pocketmine\network\mcpe\handler\PreSpawnSessionHandler; use pocketmine\network\mcpe\handler\ResourcePacksSessionHandler; @@ -173,4 +174,12 @@ class NetworkSession{ //TODO: split this up even further $this->setHandler(new SimpleSessionHandler($this->player)); } + + public function onDeath() : void{ + $this->setHandler(new DeathSessionHandler($this->player, $this)); + } + + public function onRespawn() : void{ + $this->setHandler(new SimpleSessionHandler($this->player)); + } } diff --git a/src/pocketmine/network/mcpe/handler/DeathSessionHandler.php b/src/pocketmine/network/mcpe/handler/DeathSessionHandler.php new file mode 100644 index 0000000000..0333fb7f17 --- /dev/null +++ b/src/pocketmine/network/mcpe/handler/DeathSessionHandler.php @@ -0,0 +1,61 @@ +player = $player; + $this->session = $session; + } + + public function setUp() : void{ + $pk = new RespawnPacket(); + $pk->position = $this->player->getOffsetPosition($this->player->getSpawn()); + $this->session->sendDataPacket($pk); + } + + public function handlePlayerAction(PlayerActionPacket $packet) : bool{ + switch($packet->action){ + case PlayerActionPacket::ACTION_RESPAWN: + $this->player->respawn(); + return true; + case PlayerActionPacket::ACTION_DIMENSION_CHANGE_REQUEST: + //TODO: players send this when they die in another dimension + break; + } + + return false; + } +} diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index 7bad4b51e2..a408d85308 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; +use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; @@ -123,7 +124,58 @@ class SimpleSessionHandler extends SessionHandler{ } public function handlePlayerAction(PlayerActionPacket $packet) : bool{ - return $this->player->handlePlayerAction($packet); + $pos = new Vector3($packet->x, $packet->y, $packet->z); + + switch($packet->action){ + case PlayerActionPacket::ACTION_START_BREAK: + $this->player->startBreakBlock($pos, $packet->face); + + break; + + case PlayerActionPacket::ACTION_ABORT_BREAK: + case PlayerActionPacket::ACTION_STOP_BREAK: + $this->player->stopBreakBlock($pos); + break; + case PlayerActionPacket::ACTION_START_SLEEPING: + //unused + break; + case PlayerActionPacket::ACTION_STOP_SLEEPING: + $this->player->stopSleep(); + break; + case PlayerActionPacket::ACTION_JUMP: + $this->player->jump(); + return true; + case PlayerActionPacket::ACTION_START_SPRINT: + $this->player->toggleSprint(true); + return true; + case PlayerActionPacket::ACTION_STOP_SPRINT: + $this->player->toggleSprint(false); + return true; + case PlayerActionPacket::ACTION_START_SNEAK: + $this->player->toggleSneak(true); + return true; + case PlayerActionPacket::ACTION_STOP_SNEAK: + $this->player->toggleSneak(false); + return true; + case PlayerActionPacket::ACTION_START_GLIDE: + case PlayerActionPacket::ACTION_STOP_GLIDE: + break; //TODO + case PlayerActionPacket::ACTION_CONTINUE_BREAK: + $this->player->continueBreakBlock($pos, $packet->face); + break; + case PlayerActionPacket::ACTION_START_SWIMMING: + break; //TODO + case PlayerActionPacket::ACTION_STOP_SWIMMING: + //TODO: handle this when it doesn't spam every damn tick (yet another spam bug!!) + break; + default: + $this->player->getServer()->getLogger()->debug("Unhandled/unknown player action type " . $packet->action . " from " . $this->player->getName()); + return false; + } + + $this->player->setUsingItem(false); + + return true; } public function handleEntityFall(EntityFallPacket $packet) : bool{ From 30c044f0283370e7ef4b6e6e1aad12f8666d7a3b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 20 Jul 2018 18:48:46 +0100 Subject: [PATCH 0038/3224] Unwrap more code from packet handlers --- src/pocketmine/Player.php | 37 +++++++------------ src/pocketmine/inventory/PlayerInventory.php | 29 +-------------- .../mcpe/handler/SimpleSessionHandler.php | 13 +++++-- 3 files changed, 24 insertions(+), 55 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 5f3b5a03d1..1fd99d08e4 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -55,6 +55,7 @@ use pocketmine\event\player\PlayerExhaustEvent; use pocketmine\event\player\PlayerGameModeChangeEvent; use pocketmine\event\player\PlayerInteractEvent; use pocketmine\event\player\PlayerItemConsumeEvent; +use pocketmine\event\player\PlayerItemHeldEvent; use pocketmine\event\player\PlayerJoinEvent; use pocketmine\event\player\PlayerJumpEvent; use pocketmine\event\player\PlayerKickEvent; @@ -100,7 +101,6 @@ use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; -use pocketmine\network\mcpe\protocol\BlockPickRequestPacket; use pocketmine\network\mcpe\protocol\BookEditPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; use pocketmine\network\mcpe\protocol\DataPacket; @@ -111,7 +111,6 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\LoginPacket; use pocketmine\network\mcpe\protocol\MobEffectPacket; -use pocketmine\network\mcpe\protocol\MobEquipmentPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket; @@ -2413,27 +2412,29 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return false; //TODO } - public function handleMobEquipment(MobEquipmentPacket $packet) : bool{ - $item = $this->inventory->getItem($packet->hotbarSlot); - - if(!$item->equals($packet->item)){ - $this->server->getLogger()->debug("Tried to equip " . $packet->item . " but have " . $item . " in target slot"); + public function equipItem(int $hotbarSlot) : bool{ + if(!$this->inventory->isHotbarSlot($hotbarSlot)){ $this->inventory->sendContents($this); return false; } - $this->inventory->equipItem($packet->hotbarSlot); + $this->server->getPluginManager()->callEvent($ev = new PlayerItemHeldEvent($this, $this->inventory->getItem($hotbarSlot), $hotbarSlot)); + if($ev->isCancelled()){ + $this->inventory->sendHeldItem($this); + return false; + } + $this->inventory->setHeldItemIndex($hotbarSlot, false); $this->setUsingItem(false); return true; } - public function handleBlockPickRequest(BlockPickRequestPacket $packet) : bool{ - $block = $this->level->getBlockAt($packet->blockX, $packet->blockY, $packet->blockZ); + public function pickBlock(Vector3 $pos, bool $addTileNBT) : bool{ + $block = $this->level->getBlock($pos); $item = $block->getPickedItem(); - if($packet->addUserData){ + if($addTileNBT){ $tile = $this->getLevel()->getTile($block); if($tile instanceof Tile){ $nbt = $tile->getCleanedNBT(); @@ -2456,7 +2457,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } return true; - } public function startBreakBlock(Vector3 $pos, int $face) : bool{ @@ -2529,8 +2529,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } } - public function handleAnimate(AnimatePacket $packet) : bool{ - $this->server->getPluginManager()->callEvent($ev = new PlayerAnimationEvent($this, $packet->action)); + public function animate(int $action) : bool{ + $this->server->getPluginManager()->callEvent($ev = new PlayerAnimationEvent($this, $action)); if($ev->isCancelled()){ return true; } @@ -2618,15 +2618,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return true; } - public function handleSetPlayerGameType(SetPlayerGameTypePacket $packet) : bool{ - if($packet->gamemode !== $this->gamemode){ - //Set this back to default. TODO: handle this properly - $this->sendGamemode(); - $this->sendSettings(); - } - return true; - } - public function handleItemFrameDropItem(ItemFrameDropItemPacket $packet) : bool{ $tile = $this->level->getTileAt($packet->x, $packet->y, $packet->z); if($tile instanceof ItemFrame){ diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index 97ed33c424..b701afca05 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\inventory; use pocketmine\entity\Human; -use pocketmine\event\player\PlayerItemHeldEvent; use pocketmine\item\Item; use pocketmine\network\mcpe\protocol\InventoryContentPacket; use pocketmine\network\mcpe\protocol\MobEquipmentPacket; @@ -55,33 +54,7 @@ class PlayerInventory extends BaseInventory{ return 36; } - /** - * Called when a client equips a hotbar slot. This method should not be used by plugins. - * This method will call PlayerItemHeldEvent. - * - * @param int $hotbarSlot Number of the hotbar slot to equip. - * - * @return bool if the equipment change was successful, false if not. - */ - public function equipItem(int $hotbarSlot) : bool{ - if(!$this->isHotbarSlot($hotbarSlot)){ - $this->sendContents($this->getHolder()); - return false; - } - - $this->getHolder()->getLevel()->getServer()->getPluginManager()->callEvent($ev = new PlayerItemHeldEvent($this->getHolder(), $this->getItem($hotbarSlot), $hotbarSlot)); - - if($ev->isCancelled()){ - $this->sendHeldItem($this->getHolder()); - return false; - } - - $this->setHeldItemIndex($hotbarSlot, false); - - return true; - } - - private function isHotbarSlot(int $slot) : bool{ + public function isHotbarSlot(int $slot) : bool{ return $slot >= 0 and $slot <= $this->getHotbarSize(); } diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index a408d85308..ca080fd29c 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -104,7 +104,7 @@ class SimpleSessionHandler extends SessionHandler{ } public function handleMobEquipment(MobEquipmentPacket $packet) : bool{ - return $this->player->handleMobEquipment($packet); + return $this->player->equipItem($packet->hotbarSlot); } public function handleMobArmorEquipment(MobArmorEquipmentPacket $packet) : bool{ @@ -116,7 +116,7 @@ class SimpleSessionHandler extends SessionHandler{ } public function handleBlockPickRequest(BlockPickRequestPacket $packet) : bool{ - return $this->player->handleBlockPickRequest($packet); + return $this->player->pickBlock(new Vector3($packet->blockX, $packet->blockY, $packet->blockZ), $packet->addUserData); } public function handleEntityPickRequest(EntityPickRequestPacket $packet) : bool{ @@ -183,7 +183,7 @@ class SimpleSessionHandler extends SessionHandler{ } public function handleAnimate(AnimatePacket $packet) : bool{ - return $this->player->handleAnimate($packet); + return $this->player->animate($packet->action); } public function handleContainerClose(ContainerClosePacket $packet) : bool{ @@ -211,7 +211,12 @@ class SimpleSessionHandler extends SessionHandler{ } public function handleSetPlayerGameType(SetPlayerGameTypePacket $packet) : bool{ - return $this->player->handleSetPlayerGameType($packet); + if($packet->gamemode !== $this->player->getGamemode()){ + //Set this back to default. TODO: handle this properly + $this->player->sendGamemode(); + $this->player->sendSettings(); + } + return true; } public function handleSpawnExperienceOrb(SpawnExperienceOrbPacket $packet) : bool{ From 59f6821c29be07c4904e4dfdb6cdeb16da3f4373 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 20 Jul 2018 20:08:12 +0100 Subject: [PATCH 0039/3224] Allow parameterizing ResourcePackManager to session handler this will open the way (in the future) for custom managers to be used, instead of a global thing. --- .../network/mcpe/NetworkSession.php | 2 +- .../handler/ResourcePacksSessionHandler.php | 30 ++++++++----------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index c7f19f646b..ba4b14e520 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -157,7 +157,7 @@ class NetworkSession{ $pk->status = PlayStatusPacket::LOGIN_SUCCESS; $this->sendDataPacket($pk); - $this->setHandler(new ResourcePacksSessionHandler($this->server, $this->player, $this)); + $this->setHandler(new ResourcePacksSessionHandler($this->player, $this, $this->server->getResourcePackManager())); } public function onResourcePacksDone() : void{ diff --git a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php index cfb50ed9d8..c64d7bd47f 100644 --- a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php @@ -32,7 +32,7 @@ use pocketmine\network\mcpe\protocol\ResourcePacksInfoPacket; use pocketmine\network\mcpe\protocol\ResourcePackStackPacket; use pocketmine\Player; use pocketmine\resourcepacks\ResourcePack; -use pocketmine\Server; +use pocketmine\resourcepacks\ResourcePackManager; /** * Handler used for the resource packs sequence phase of the session. This handler takes care of downloading resource @@ -40,24 +40,23 @@ use pocketmine\Server; */ class ResourcePacksSessionHandler extends SessionHandler{ - /** @var Server */ - private $server; /** @var Player */ private $player; /** @var NetworkSession */ private $session; + /** @var ResourcePackManager */ + private $resourcePackManager; - public function __construct(Server $server, Player $player, NetworkSession $session){ - $this->server = $server; + public function __construct(Player $player, NetworkSession $session, ResourcePackManager $resourcePackManager){ $this->player = $player; $this->session = $session; + $this->resourcePackManager = $resourcePackManager; } public function setUp() : void{ $pk = new ResourcePacksInfoPacket(); - $manager = $this->server->getResourcePackManager(); - $pk->resourcePackEntries = $manager->getResourceStack(); - $pk->mustAccept = $manager->resourcePacksRequired(); + $pk->resourcePackEntries = $this->resourcePackManager->getResourceStack(); + $pk->mustAccept = $this->resourcePackManager->resourcePacksRequired(); $this->session->sendDataPacket($pk); } @@ -68,13 +67,12 @@ class ResourcePacksSessionHandler extends SessionHandler{ $this->player->close("", "You must accept resource packs to join this server.", true); break; case ResourcePackClientResponsePacket::STATUS_SEND_PACKS: - $manager = $this->server->getResourcePackManager(); foreach($packet->packIds as $uuid){ - $pack = $manager->getPackById($uuid); + $pack = $this->resourcePackManager->getPackById($uuid); if(!($pack instanceof ResourcePack)){ //Client requested a resource pack but we don't have it available on the server $this->player->close("", "disconnectionScreen.resourcePack", true); - $this->server->getLogger()->debug("Got a resource pack request for unknown pack with UUID " . $uuid . ", available packs: " . implode(", ", $manager->getPackIdList())); + $this->player->getServer()->getLogger()->debug("Got a resource pack request for unknown pack with UUID " . $uuid . ", available packs: " . implode(", ", $this->resourcePackManager->getPackIdList())); return false; } @@ -91,9 +89,8 @@ class ResourcePacksSessionHandler extends SessionHandler{ break; case ResourcePackClientResponsePacket::STATUS_HAVE_ALL_PACKS: $pk = new ResourcePackStackPacket(); - $manager = $this->server->getResourcePackManager(); - $pk->resourcePackStack = $manager->getResourceStack(); - $pk->mustAccept = $manager->resourcePacksRequired(); + $pk->resourcePackStack = $this->resourcePackManager->getResourceStack(); + $pk->mustAccept = $this->resourcePackManager->resourcePacksRequired(); $this->session->sendDataPacket($pk); break; case ResourcePackClientResponsePacket::STATUS_COMPLETED: @@ -107,11 +104,10 @@ class ResourcePacksSessionHandler extends SessionHandler{ } public function handleResourcePackChunkRequest(ResourcePackChunkRequestPacket $packet) : bool{ - $manager = $this->server->getResourcePackManager(); - $pack = $manager->getPackById($packet->packId); + $pack = $this->resourcePackManager->getPackById($packet->packId); if(!($pack instanceof ResourcePack)){ $this->player->close("", "disconnectionScreen.resourcePack", true); - $this->server->getLogger()->debug("Got a resource pack chunk request for unknown pack with UUID " . $packet->packId . ", available packs: " . implode(", ", $manager->getPackIdList())); + $this->player->getServer()->getLogger()->debug("Got a resource pack chunk request for unknown pack with UUID " . $packet->packId . ", available packs: " . implode(", ", $this->resourcePackManager->getPackIdList())); return false; } From c257a791e16a4edc1b3c1c2c3f5e053553b7fdc4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Jul 2018 09:33:21 +0100 Subject: [PATCH 0040/3224] ResourcePacksSessionHandler: move max pack chunk size to const --- .../network/mcpe/handler/ResourcePacksSessionHandler.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php index c64d7bd47f..da51a41ca3 100644 --- a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php @@ -39,6 +39,7 @@ use pocketmine\resourcepacks\ResourcePackManager; * packs to the client. */ class ResourcePacksSessionHandler extends SessionHandler{ + private const PACK_CHUNK_SIZE = 1048576; //1MB /** @var Player */ private $player; @@ -79,8 +80,8 @@ class ResourcePacksSessionHandler extends SessionHandler{ $pk = new ResourcePackDataInfoPacket(); $pk->packId = $pack->getPackId(); - $pk->maxChunkSize = 1048576; //1MB - $pk->chunkCount = (int) ceil($pack->getPackSize() / $pk->maxChunkSize); + $pk->maxChunkSize = self::PACK_CHUNK_SIZE; //1MB + $pk->chunkCount = (int) ceil($pack->getPackSize() / self::PACK_CHUNK_SIZE); $pk->compressedPackSize = $pack->getPackSize(); $pk->sha256 = $pack->getSha256(); $this->session->sendDataPacket($pk); @@ -115,8 +116,8 @@ class ResourcePacksSessionHandler extends SessionHandler{ $pk = new ResourcePackChunkDataPacket(); $pk->packId = $pack->getPackId(); $pk->chunkIndex = $packet->chunkIndex; - $pk->data = $pack->getPackChunk(1048576 * $packet->chunkIndex, 1048576); - $pk->progress = (1048576 * $packet->chunkIndex); + $pk->data = $pack->getPackChunk(self::PACK_CHUNK_SIZE * $packet->chunkIndex, self::PACK_CHUNK_SIZE); + $pk->progress = (self::PACK_CHUNK_SIZE * $packet->chunkIndex); $this->session->sendDataPacket($pk); return true; From b9cd96f6e092fccb8f800b03164ca958aa6b4880 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Jul 2018 13:36:20 +0100 Subject: [PATCH 0041/3224] ResourcePacksSessionHandler: remove useless brackets --- .../network/mcpe/handler/ResourcePacksSessionHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php index da51a41ca3..e0209afe21 100644 --- a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php @@ -117,7 +117,7 @@ class ResourcePacksSessionHandler extends SessionHandler{ $pk->packId = $pack->getPackId(); $pk->chunkIndex = $packet->chunkIndex; $pk->data = $pack->getPackChunk(self::PACK_CHUNK_SIZE * $packet->chunkIndex, self::PACK_CHUNK_SIZE); - $pk->progress = (self::PACK_CHUNK_SIZE * $packet->chunkIndex); + $pk->progress = self::PACK_CHUNK_SIZE * $packet->chunkIndex; $this->session->sendDataPacket($pk); return true; From d6e61e3e0016dc819fee862ae71887994eb6f491 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Jul 2018 14:19:24 +0100 Subject: [PATCH 0042/3224] ResourcePacksSessionHandler: Account for out-of-bounds chunk requests --- .../mcpe/handler/ResourcePacksSessionHandler.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php index e0209afe21..105a1829bd 100644 --- a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php @@ -113,11 +113,19 @@ class ResourcePacksSessionHandler extends SessionHandler{ return false; } + $offset = $packet->chunkIndex * self::PACK_CHUNK_SIZE; + if($offset < 0 or $offset >= $pack->getPackSize()){ + $this->player->close("", "disconnectionScreen.resourcePack", true); + $this->player->getServer()->getLogger()->debug("Got a resource pack chunk request with invalid start offset $offset, file size is " . $pack->getPackSize()); + + return false; + } + $pk = new ResourcePackChunkDataPacket(); $pk->packId = $pack->getPackId(); $pk->chunkIndex = $packet->chunkIndex; - $pk->data = $pack->getPackChunk(self::PACK_CHUNK_SIZE * $packet->chunkIndex, self::PACK_CHUNK_SIZE); - $pk->progress = self::PACK_CHUNK_SIZE * $packet->chunkIndex; + $pk->data = $pack->getPackChunk($offset, self::PACK_CHUNK_SIZE); + $pk->progress = $offset; $this->session->sendDataPacket($pk); return true; From da876cc8f3c5aaca4c19d6d34f9ce12af61604b4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Jul 2018 14:31:34 +0100 Subject: [PATCH 0043/3224] ResourcePacksSessionHandler: Prevent clients requesting the same chunk more than once Currently this can be used to attack the server by spamming requests for the same chunks forever. This commit prevents that by disconnecting the client if a chunk is requested more than 1 time. It is not necessary to allow more than 1 request per chunk, since RakNet should ensure that these are always delivered correctly. --- .../handler/ResourcePacksSessionHandler.php | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php index 105a1829bd..8d22d04d6f 100644 --- a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php @@ -48,6 +48,9 @@ class ResourcePacksSessionHandler extends SessionHandler{ /** @var ResourcePackManager */ private $resourcePackManager; + /** @var bool[][] uuid => [chunk index => hasSent] */ + private $downloadedChunks = []; + public function __construct(Player $player, NetworkSession $session, ResourcePackManager $resourcePackManager){ $this->player = $player; $this->session = $session; @@ -113,6 +116,15 @@ class ResourcePacksSessionHandler extends SessionHandler{ return false; } + $packId = $pack->getPackId(); //use this because case may be different + + if(isset($this->downloadedChunks[$packId][$packet->chunkIndex])){ + $this->player->close("", "disconnectionScreen.resourcePack", true); + $this->player->getServer()->getLogger()->debug("Got a duplicate resource pack chunk request for pack " . $packet->packId . " chunk $packet->chunkIndex"); + + return false; + } + $offset = $packet->chunkIndex * self::PACK_CHUNK_SIZE; if($offset < 0 or $offset >= $pack->getPackSize()){ $this->player->close("", "disconnectionScreen.resourcePack", true); @@ -121,8 +133,14 @@ class ResourcePacksSessionHandler extends SessionHandler{ return false; } + if(!isset($this->downloadedChunks[$packId])){ + $this->downloadedChunks[$packId] = [$packet->chunkIndex => true]; + }else{ + $this->downloadedChunks[$packId][$packet->chunkIndex] = true; + } + $pk = new ResourcePackChunkDataPacket(); - $pk->packId = $pack->getPackId(); + $pk->packId = $packId; $pk->chunkIndex = $packet->chunkIndex; $pk->data = $pack->getPackChunk($offset, self::PACK_CHUNK_SIZE); $pk->progress = $offset; From 7d8624b12f551a27bd8618ff8f98983e09015a09 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Jul 2018 14:44:54 +0100 Subject: [PATCH 0044/3224] ResourcePacksSessionHandler: clean up error reporting --- .../handler/ResourcePacksSessionHandler.php | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php index 8d22d04d6f..48959afca9 100644 --- a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php @@ -64,6 +64,11 @@ class ResourcePacksSessionHandler extends SessionHandler{ $this->session->sendDataPacket($pk); } + private function disconnectWithError(string $error) : void{ + $this->player->getServer()->getLogger()->error("Error while downloading resource packs for " . $this->player->getName() . ": " . $error); + $this->player->close("", "%disconnectionScreen.resourcePack", true); + } + public function handleResourcePackClientResponse(ResourcePackClientResponsePacket $packet) : bool{ switch($packet->status){ case ResourcePackClientResponsePacket::STATUS_REFUSED: @@ -75,9 +80,7 @@ class ResourcePacksSessionHandler extends SessionHandler{ $pack = $this->resourcePackManager->getPackById($uuid); if(!($pack instanceof ResourcePack)){ //Client requested a resource pack but we don't have it available on the server - $this->player->close("", "disconnectionScreen.resourcePack", true); - $this->player->getServer()->getLogger()->debug("Got a resource pack request for unknown pack with UUID " . $uuid . ", available packs: " . implode(", ", $this->resourcePackManager->getPackIdList())); - + $this->disconnectWithError("Unknown pack $uuid requested, available packs: " . implode(", ", $this->resourcePackManager->getPackIdList())); return false; } @@ -110,26 +113,20 @@ class ResourcePacksSessionHandler extends SessionHandler{ public function handleResourcePackChunkRequest(ResourcePackChunkRequestPacket $packet) : bool{ $pack = $this->resourcePackManager->getPackById($packet->packId); if(!($pack instanceof ResourcePack)){ - $this->player->close("", "disconnectionScreen.resourcePack", true); - $this->player->getServer()->getLogger()->debug("Got a resource pack chunk request for unknown pack with UUID " . $packet->packId . ", available packs: " . implode(", ", $this->resourcePackManager->getPackIdList())); - + $this->disconnectWithError("Invalid request for chunk $packet->chunkIndex of unknown pack $packet->packId, available packs: " . implode(", ", $this->resourcePackManager->getPackIdList())); return false; } $packId = $pack->getPackId(); //use this because case may be different if(isset($this->downloadedChunks[$packId][$packet->chunkIndex])){ - $this->player->close("", "disconnectionScreen.resourcePack", true); - $this->player->getServer()->getLogger()->debug("Got a duplicate resource pack chunk request for pack " . $packet->packId . " chunk $packet->chunkIndex"); - + $this->disconnectWithError("Duplicate request for chunk $packet->chunkIndex of pack $packet->packId"); return false; } $offset = $packet->chunkIndex * self::PACK_CHUNK_SIZE; if($offset < 0 or $offset >= $pack->getPackSize()){ - $this->player->close("", "disconnectionScreen.resourcePack", true); - $this->player->getServer()->getLogger()->debug("Got a resource pack chunk request with invalid start offset $offset, file size is " . $pack->getPackSize()); - + $this->disconnectWithError("Invalid out-of-bounds request for chunk $packet->chunkIndex of $packet->packId: offset $offset, file size " . $pack->getPackSize()); return false; } From c5bf746e4c0116ac0b9623c9a520dc2b11e1594d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Jul 2018 14:45:22 +0100 Subject: [PATCH 0045/3224] typo --- .../network/mcpe/handler/ResourcePacksSessionHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php index 48959afca9..c7c24d937d 100644 --- a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php @@ -66,7 +66,7 @@ class ResourcePacksSessionHandler extends SessionHandler{ private function disconnectWithError(string $error) : void{ $this->player->getServer()->getLogger()->error("Error while downloading resource packs for " . $this->player->getName() . ": " . $error); - $this->player->close("", "%disconnectionScreen.resourcePack", true); + $this->player->close("", "disconnectionScreen.resourcePack", true); } public function handleResourcePackClientResponse(ResourcePackClientResponsePacket $packet) : bool{ From 01a9e53394f1c12e7d2d1cb2e5497a3fb98f4c25 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Jul 2018 15:50:58 +0100 Subject: [PATCH 0046/3224] Config: Clean up error handling, throw exceptions instead of returning false (#2314) This also has the happy side effect of removing a cyclic dependency between Config and Server. There's only the dependency on MainLogger left to get rid of now. --- src/pocketmine/utils/Config.php | 163 +++++++++++++------------------- 1 file changed, 65 insertions(+), 98 deletions(-) diff --git a/src/pocketmine/utils/Config.php b/src/pocketmine/utils/Config.php index de8b65eb93..98e9aa2a43 100644 --- a/src/pocketmine/utils/Config.php +++ b/src/pocketmine/utils/Config.php @@ -23,9 +23,6 @@ declare(strict_types=1); namespace pocketmine\utils; -use pocketmine\Server; - - /** * Config Class for simple config manipulation of multiple formats. */ @@ -76,14 +73,12 @@ class Config{ ]; /** - * @param string $file Path of the file to be loaded - * @param int $type Config type to load, -1 by default (detect) - * @param array $default Array with the default values that will be written to the file if it did not exist - * @param null &$correct Sets correct to true if everything has been loaded correctly + * @param string $file Path of the file to be loaded + * @param int $type Config type to load, -1 by default (detect) + * @param array $default Array with the default values that will be written to the file if it did not exist */ - public function __construct(string $file, int $type = Config::DETECT, array $default = [], &$correct = null){ + public function __construct(string $file, int $type = Config::DETECT, array $default = []){ $this->load($file, $type, $default); - $correct = $this->correct; } /** @@ -92,7 +87,6 @@ class Config{ public function reload(){ $this->config = []; $this->nestedCache = []; - $this->correct = false; $this->load($this->file, $this->type); } @@ -114,14 +108,14 @@ class Config{ } /** - * @param $file - * @param int $type - * @param array $default + * @param string $file + * @param int $type + * @param array $default * - * @return bool + * @throws \InvalidArgumentException if config type could not be auto-detected + * @throws \InvalidStateException if config type is invalid */ - public function load(string $file, int $type = Config::DETECT, array $default = []) : bool{ - $this->correct = true; + public function load(string $file, int $type = Config::DETECT, array $default = []) : void{ $this->file = $file; $this->type = $type; @@ -131,7 +125,7 @@ class Config{ if(isset(Config::$formats[$extension])){ $this->type = Config::$formats[$extension]; }else{ - $this->correct = false; + throw new \InvalidArgumentException("Cannot detect config type of " . $this->file); } } @@ -139,93 +133,66 @@ class Config{ $this->config = $default; $this->save(); }else{ - if($this->correct){ - $content = file_get_contents($this->file); - switch($this->type){ - case Config::PROPERTIES: - $this->parseProperties($content); - break; - case Config::JSON: - $this->config = json_decode($content, true); - break; - case Config::YAML: - $content = self::fixYAMLIndexes($content); - $this->config = yaml_parse($content); - break; - case Config::SERIALIZED: - $this->config = unserialize($content); - break; - case Config::ENUM: - $this->parseList($content); - break; - default: - $this->correct = false; - - return false; - } - if(!is_array($this->config)){ - $this->config = $default; - } - if($this->fillDefaults($default, $this->config) > 0){ - $this->save(); - } - }else{ - return false; + $content = file_get_contents($this->file); + switch($this->type){ + case Config::PROPERTIES: + $this->parseProperties($content); + break; + case Config::JSON: + $this->config = json_decode($content, true); + break; + case Config::YAML: + $content = self::fixYAMLIndexes($content); + $this->config = yaml_parse($content); + break; + case Config::SERIALIZED: + $this->config = unserialize($content); + break; + case Config::ENUM: + $this->parseList($content); + break; + default: + throw new \InvalidStateException("Config type is unknown"); + } + if(!is_array($this->config)){ + $this->config = $default; + } + if($this->fillDefaults($default, $this->config) > 0){ + $this->save(); } } - - return true; } /** - * @return bool + * Flushes the config to disk in the appropriate format. + * + * @throws \InvalidStateException if config type is not valid */ - public function check() : bool{ - return $this->correct; - } - - /** - * @return bool - */ - public function save() : bool{ - if($this->correct){ - try{ - $content = null; - switch($this->type){ - case Config::PROPERTIES: - $content = $this->writeProperties(); - break; - case Config::JSON: - $content = json_encode($this->config, $this->jsonOptions); - break; - case Config::YAML: - $content = yaml_emit($this->config, YAML_UTF8_ENCODING); - break; - case Config::SERIALIZED: - $content = serialize($this->config); - break; - case Config::ENUM: - $content = implode("\r\n", array_keys($this->config)); - break; - default: - throw new \InvalidStateException("Config type is unknown, has not been set or not detected"); - } - - file_put_contents($this->file, $content); - }catch(\Throwable $e){ - $logger = Server::getInstance()->getLogger(); - $logger->critical("Could not save Config " . $this->file . ": " . $e->getMessage()); - if(\pocketmine\DEBUG > 1){ - $logger->logException($e); - } - } - - $this->changed = false; - - return true; - }else{ - return false; + public function save() : void{ + $content = null; + switch($this->type){ + case Config::PROPERTIES: + $content = $this->writeProperties(); + break; + case Config::JSON: + $content = json_encode($this->config, $this->jsonOptions); + break; + case Config::YAML: + $content = yaml_emit($this->config, YAML_UTF8_ENCODING); + break; + case Config::SERIALIZED: + $content = serialize($this->config); + break; + case Config::ENUM: + $content = implode("\r\n", array_keys($this->config)); + break; + default: + throw new \InvalidStateException("Config type is unknown, has not been set or not detected"); } + + file_put_contents($this->file, $content); + + $this->changed = false; } /** @@ -415,7 +382,7 @@ class Config{ * @return bool|mixed */ public function get($k, $default = false){ - return ($this->correct and isset($this->config[$k])) ? $this->config[$k] : $default; + return $this->config[$k] ?? $default; } /** From 34d64be42753c353409af147b546c9e652acfb9f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Jul 2018 16:10:25 +0100 Subject: [PATCH 0047/3224] CompressBatchedTask: players aren't strings --- src/pocketmine/network/mcpe/CompressBatchedTask.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/CompressBatchedTask.php b/src/pocketmine/network/mcpe/CompressBatchedTask.php index 77e4a089f0..6afb58f589 100644 --- a/src/pocketmine/network/mcpe/CompressBatchedTask.php +++ b/src/pocketmine/network/mcpe/CompressBatchedTask.php @@ -34,7 +34,7 @@ class CompressBatchedTask extends AsyncTask{ /** * @param PacketStream $stream - * @param string[] $targets + * @param Player[] $targets * @param int $compressionLevel */ public function __construct(PacketStream $stream, array $targets, int $compressionLevel){ From 57e5b1309d80a053cced4e0973d82c21d3c2c2bc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Jul 2018 16:27:30 +0100 Subject: [PATCH 0048/3224] NetworkSession: Stop processing batch if player gets disconnected during handling --- src/pocketmine/network/mcpe/NetworkSession.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index ba4b14e520..dfae1e39ed 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -99,7 +99,7 @@ class NetworkSession{ //TODO: decryption if enabled $stream = new PacketStream(NetworkCompression::decompress($payload)); - while(!$stream->feof()){ + while(!$stream->feof() and $this->player->isConnected()){ $this->handleDataPacket(PacketPool::getPacket($stream->getString())); } } From ca1a0c86433b68b0815c07aa8a6840e53bda8aca Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Jul 2018 16:33:12 +0100 Subject: [PATCH 0049/3224] Move responsibility for ping handling to NetworkSession --- src/pocketmine/Player.php | 20 +------------------ .../network/mcpe/NetworkSession.php | 20 +++++++++++++++++++ .../network/mcpe/RakLibInterface.php | 2 +- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 1fd99d08e4..3434e664ba 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -168,13 +168,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ /** @var NetworkSession */ protected $networkSession; - /** - * @var int - * Last measurement of player's latency in milliseconds. - */ - protected $lastPingMeasure = 1; - - /** @var float */ public $creationTime = 0; @@ -798,18 +791,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ * @return int */ public function getPing() : int{ - return $this->lastPingMeasure; - } - - /** - * Updates the player's last ping measurement. - * - * @internal Plugins should not use this method. - * - * @param int $pingMS - */ - public function updatePing(int $pingMS){ - $this->lastPingMeasure = $pingMS; + return $this->networkSession->getPing(); } /** diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index dfae1e39ed..df31805e6b 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -53,6 +53,8 @@ class NetworkSession{ private $ip; /** @var int */ private $port; + /** @var int */ + private $ping; /** @var SessionHandler */ private $handler; @@ -86,6 +88,24 @@ class NetworkSession{ return $this->port; } + /** + * Returns the last recorded ping measurement for this session, in milliseconds. + * + * @return int + */ + public function getPing() : int{ + return $this->ping; + } + + /** + * @internal Called by the network interface to update last recorded ping measurements. + * + * @param int $ping + */ + public function updatePing(int $ping) : void{ + $this->ping = $ping; + } + public function getHandler() : SessionHandler{ return $this->handler; } diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 9aaeeda9f6..dd13e320d0 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -223,7 +223,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ public function updatePing(string $identifier, int $pingMS) : void{ if(isset($this->players[$identifier])){ - $this->players[$identifier]->updatePing($pingMS); + $this->players[$identifier]->getNetworkSession()->updatePing($pingMS); } } } From b93318b2cf6c3d23746f9cf59c4a938d289193fe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Jul 2018 18:41:11 +0100 Subject: [PATCH 0050/3224] RakLibInterface: Use NetworkSession API for getting IP instead of Player soon the network interfaces won't be dealing with Players at all. --- src/pocketmine/network/mcpe/RakLibInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index dd13e320d0..4e0abca793 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -144,7 +144,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ public function handleEncapsulated(string $identifier, EncapsulatedPacket $packet, int $flags) : void{ if(isset($this->players[$identifier])){ //get this now for blocking in case the player was closed before the exception was raised - $address = $this->players[$identifier]->getAddress(); + $address = $this->players[$identifier]->getNetworkSession()->getIp(); try{ if($packet->buffer !== "" and $packet->buffer{0} === self::MCPE_RAKNET_PACKET_ID){ //Batch $this->players[$identifier]->getNetworkSession()->handleEncoded(substr($packet->buffer, 1)); From a86d3fe071605e238bcec0e7bebc8087185b5a6f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Jul 2018 18:42:18 +0100 Subject: [PATCH 0051/3224] PlayerCreationEvent: Remove useless crap from constructor --- .../event/player/PlayerCreationEvent.php | 20 +++---------------- .../network/mcpe/RakLibInterface.php | 2 +- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/src/pocketmine/event/player/PlayerCreationEvent.php b/src/pocketmine/event/player/PlayerCreationEvent.php index a7485a21b4..38c061a2ef 100644 --- a/src/pocketmine/event/player/PlayerCreationEvent.php +++ b/src/pocketmine/event/player/PlayerCreationEvent.php @@ -39,33 +39,19 @@ class PlayerCreationEvent extends Event{ private $port; /** @var Player::class */ - private $baseClass; + private $baseClass = Player::class; /** @var Player::class */ - private $playerClass; + private $playerClass = Player::class; /** * @param NetworkInterface $interface - * @param Player::class $baseClass - * @param Player::class $playerClass * @param string $address * @param int $port */ - public function __construct(NetworkInterface $interface, $baseClass, $playerClass, string $address, int $port){ + public function __construct(NetworkInterface $interface, string $address, int $port){ $this->interface = $interface; $this->address = $address; $this->port = $port; - - if(!is_a($baseClass, Player::class, true)){ - throw new \RuntimeException("Base class $baseClass must extend " . Player::class); - } - - $this->baseClass = $baseClass; - - if(!is_a($playerClass, Player::class, true)){ - throw new \RuntimeException("Class $playerClass must extend " . Player::class); - } - - $this->playerClass = $playerClass; } /** diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 4e0abca793..d3dc8b79d9 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -131,7 +131,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ } public function openSession(string $identifier, string $address, int $port, int $clientID) : void{ - $ev = new PlayerCreationEvent($this, Player::class, Player::class, $address, $port); + $ev = new PlayerCreationEvent($this, $address, $port); $this->server->getPluginManager()->callEvent($ev); $class = $ev->getPlayerClass(); From 85105ed0666b86cc64d254092106342863c06168 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Jul 2018 20:03:05 +0100 Subject: [PATCH 0052/3224] Inseparable set of network changes - these all need each other to work - Separated player handling and creation from network interfaces - Rewire disconnects to make them not be recursive - Batching now uses sessions instead of players - Fixed DisconnectPacket getting sent to players who disconnect of their own accord --- src/pocketmine/Player.php | 18 ++-- src/pocketmine/Server.php | 22 +++-- .../event/player/PlayerCreationEvent.php | 34 +++---- src/pocketmine/network/NetworkInterface.php | 16 ++-- .../network/mcpe/CompressBatchedTask.php | 9 +- .../network/mcpe/NetworkSession.php | 89 +++++++++++++++++-- .../network/mcpe/RakLibInterface.php | 47 +++++----- .../mcpe/handler/LoginSessionHandler.php | 7 +- .../mcpe/handler/PreSpawnSessionHandler.php | 2 +- .../handler/ResourcePacksSessionHandler.php | 4 +- 10 files changed, 160 insertions(+), 88 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 3434e664ba..f780677b94 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -125,7 +125,6 @@ use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; use pocketmine\network\mcpe\VerifyLoginTask; -use pocketmine\network\NetworkInterface; use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissionAttachment; use pocketmine\permission\PermissionAttachmentInfo; @@ -657,13 +656,14 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } /** - * @param NetworkInterface $interface - * @param string $ip - * @param int $port + * @param Server $server + * @param NetworkSession $session */ - public function __construct(NetworkInterface $interface, string $ip, int $port){ + public function __construct(Server $server, NetworkSession $session){ + $this->server = $server; + $this->networkSession = $session; + $this->perm = new PermissibleBase($this); - $this->server = Server::getInstance(); $this->loaderId = Level::generateChunkLoaderId($this); $this->chunksPerTick = (int) $this->server->getProperty("chunk-sending.per-tick", 4); $this->spawnThreshold = (int) (($this->server->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); @@ -671,8 +671,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->creationTime = microtime(true); $this->allowMovementCheats = (bool) $this->server->getProperty("player.anti-cheat.allow-movement-cheats", false); - - $this->networkSession = new NetworkSession($this->server, $this, $interface, $ip, $port); } /** @@ -906,7 +904,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->usedChunks[Level::chunkHash($x, $z)] = true; $this->chunkLoadCount++; - $this->networkSession->getInterface()->putPacket($this, $payload); + $this->networkSession->getInterface()->putPacket($this->networkSession, $payload); if($this->spawned){ foreach($this->level->getChunkEntities($x, $z) as $entity){ @@ -2938,7 +2936,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ try{ $ip = $this->networkSession->getIp(); $port = $this->networkSession->getPort(); - $this->networkSession->serverDisconnect($reason, $notify); + $this->networkSession->onPlayerDestroyed($reason, $notify); $this->networkSession = null; $this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this); diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 0d4a6f1dfb..b462287c76 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -71,6 +71,7 @@ use pocketmine\nbt\tag\StringTag; use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\mcpe\CompressBatchedTask; use pocketmine\network\mcpe\NetworkCompression; +use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\PacketStream; use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket; @@ -1860,7 +1861,13 @@ class Server{ } Timings::$playerNetworkTimer->startTiming(); - $targets = array_filter($players, function(Player $player) : bool{ return $player->isConnected(); }); + /** @var NetworkSession[] $targets */ + $targets = []; + foreach($players as $player){ + if($player->isConnected()){ + $targets[] = $player->getNetworkSession(); + } + } if(!empty($targets)){ $stream = new PacketStream(); @@ -1887,13 +1894,14 @@ class Server{ } /** - * @param string $payload - * @param Player[] $players - * @param bool $immediate + * @param string $payload + * @param NetworkSession[] $sessions + * @param bool $immediate */ - public function broadcastPacketsCallback(string $payload, array $players, bool $immediate = false){ - foreach($players as $i){ - $i->getNetworkSession()->getInterface()->putPacket($i, $payload, $immediate); + public function broadcastPacketsCallback(string $payload, array $sessions, bool $immediate = false){ + /** @var NetworkSession $session */ + foreach($sessions as $session){ + $session->getInterface()->putPacket($session, $payload, $immediate); } } diff --git a/src/pocketmine/event/player/PlayerCreationEvent.php b/src/pocketmine/event/player/PlayerCreationEvent.php index 38c061a2ef..daae0c3d1d 100644 --- a/src/pocketmine/event/player/PlayerCreationEvent.php +++ b/src/pocketmine/event/player/PlayerCreationEvent.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Event; +use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\NetworkInterface; use pocketmine\Player; @@ -31,48 +32,49 @@ use pocketmine\Player; * Allows the creation of players overriding the base Player class */ class PlayerCreationEvent extends Event{ - /** @var NetworkInterface */ - private $interface; - /** @var string */ - private $address; - /** @var int */ - private $port; + + /** @var NetworkSession */ + private $session; /** @var Player::class */ private $baseClass = Player::class; /** @var Player::class */ private $playerClass = Player::class; + /** - * @param NetworkInterface $interface - * @param string $address - * @param int $port + * @param NetworkSession $session */ - public function __construct(NetworkInterface $interface, string $address, int $port){ - $this->interface = $interface; - $this->address = $address; - $this->port = $port; + public function __construct(NetworkSession $session){ + $this->session = $session; } /** * @return NetworkInterface */ public function getInterface() : NetworkInterface{ - return $this->interface; + return $this->session->getInterface(); + } + + /** + * @return NetworkSession + */ + public function getNetworkSession() : NetworkSession{ + return $this->session; } /** * @return string */ public function getAddress() : string{ - return $this->address; + return $this->session->getIp(); } /** * @return int */ public function getPort() : int{ - return $this->port; + return $this->session->getPort(); } /** diff --git a/src/pocketmine/network/NetworkInterface.php b/src/pocketmine/network/NetworkInterface.php index f065268736..60001a74f5 100644 --- a/src/pocketmine/network/NetworkInterface.php +++ b/src/pocketmine/network/NetworkInterface.php @@ -26,7 +26,7 @@ declare(strict_types=1); */ namespace pocketmine\network; -use pocketmine\Player; +use pocketmine\network\mcpe\NetworkSession; /** * Network interfaces are transport layers which can be used to transmit packets between the server and clients. @@ -41,19 +41,19 @@ interface NetworkInterface{ /** * Sends a DataPacket to the interface, returns an unique identifier for the packet if $needACK is true * - * @param Player $player - * @param string $payload - * @param bool $immediate + * @param NetworkSession $session + * @param string $payload + * @param bool $immediate */ - public function putPacket(Player $player, string $payload, bool $immediate = true) : void; + public function putPacket(NetworkSession $session, string $payload, bool $immediate = true) : void; /** * Terminates the connection * - * @param Player $player - * @param string $reason + * @param NetworkSession $session + * @param string $reason */ - public function close(Player $player, string $reason = "unknown reason") : void; + public function close(NetworkSession $session, string $reason = "unknown reason") : void; /** * @param string $name diff --git a/src/pocketmine/network/mcpe/CompressBatchedTask.php b/src/pocketmine/network/mcpe/CompressBatchedTask.php index 6afb58f589..c9366b22a0 100644 --- a/src/pocketmine/network/mcpe/CompressBatchedTask.php +++ b/src/pocketmine/network/mcpe/CompressBatchedTask.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; -use pocketmine\Player; use pocketmine\scheduler\AsyncTask; use pocketmine\Server; @@ -33,9 +32,9 @@ class CompressBatchedTask extends AsyncTask{ private $data; /** - * @param PacketStream $stream - * @param Player[] $targets - * @param int $compressionLevel + * @param PacketStream $stream + * @param NetworkSession[] $targets + * @param int $compressionLevel */ public function __construct(PacketStream $stream, array $targets, int $compressionLevel){ $this->data = $stream->buffer; @@ -48,7 +47,7 @@ class CompressBatchedTask extends AsyncTask{ } public function onCompletion(Server $server) : void{ - /** @var Player[] $targets */ + /** @var NetworkSession[] $targets */ $targets = $this->fetchLocal(); $server->broadcastPacketsCallback($this->getResult(), $targets); diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index df31805e6b..494d62def6 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; +use pocketmine\event\player\PlayerCreationEvent; use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\event\server\DataPacketSendEvent; use pocketmine\network\mcpe\handler\DeathSessionHandler; @@ -59,15 +60,36 @@ class NetworkSession{ /** @var SessionHandler */ private $handler; - public function __construct(Server $server, Player $player, NetworkInterface $interface, string $ip, int $port){ - $this->server = $server; - $this->player = $player; - $this->interface = $interface; + /** @var bool */ + private $connected = true; + public function __construct(Server $server, NetworkInterface $interface, string $ip, int $port){ + $this->server = $server; + $this->interface = $interface; $this->ip = $ip; $this->port = $port; - $this->setHandler(new LoginSessionHandler($player, $this)); + //TODO: this should happen later in the login sequence + $this->createPlayer(); + + $this->setHandler(new LoginSessionHandler($this->player, $this)); + } + + protected function createPlayer() : void{ + $this->server->getPluginManager()->callEvent($ev = new PlayerCreationEvent($this)); + $class = $ev->getPlayerClass(); + + /** + * @var Player $player + * @see Player::__construct() + */ + $this->player = new $class($this->server, $this); + + $this->server->addPlayer($this->player); + } + + public function isConnected() : bool{ + return $this->connected; } public function getInterface() : NetworkInterface{ @@ -116,10 +138,14 @@ class NetworkSession{ } public function handleEncoded(string $payload) : void{ + if(!$this->connected){ + return; + } + //TODO: decryption if enabled $stream = new PacketStream(NetworkCompression::decompress($payload)); - while(!$stream->feof() and $this->player->isConnected()){ + while(!$stream->feof() and $this->connected){ $this->handleDataPacket(PacketPool::getPacket($stream->getString())); } } @@ -160,14 +186,61 @@ class NetworkSession{ } } - public function serverDisconnect(string $reason, bool $notify = true) : void{ + /** + * Disconnects the session, destroying the associated player (if it exists). + * + * @param string $reason + * @param bool $notify + */ + public function disconnect(string $reason, bool $notify = true) : void{ + if($this->connected){ + $this->connected = false; + $this->player->close($this->player->getLeaveMessage(), $reason); + $this->doServerDisconnect($reason, $notify); + } + } + + /** + * Called by the Player when it is closed (for example due to getting kicked). + * + * @param string $reason + * @param bool $notify + */ + public function onPlayerDestroyed(string $reason, bool $notify = true) : void{ + if($this->connected){ + $this->connected = false; + $this->doServerDisconnect($reason, $notify); + } + } + + /** + * Internal helper function used to handle server disconnections. + * + * @param string $reason + * @param bool $notify + */ + private function doServerDisconnect(string $reason, bool $notify = true) : void{ if($notify){ $pk = new DisconnectPacket(); $pk->message = $reason; $pk->hideDisconnectionScreen = $reason === ""; $this->sendDataPacket($pk, true); } - $this->interface->close($this->player, $notify ? $reason : ""); + + $this->interface->close($this, $notify ? $reason : ""); + } + + /** + * Called by the network interface to close the session when the client disconnects without server input, for + * example in a timeout condition or voluntary client disconnect. + * + * @param string $reason + */ + public function onClientDisconnect(string $reason) : void{ + if($this->connected){ + $this->connected = false; + $this->player->close($this->player->getLeaveMessage(), $reason); + } } //TODO: onEnableEncryption() step diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index d3dc8b79d9..314e41c643 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -23,11 +23,9 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; -use pocketmine\event\player\PlayerCreationEvent; use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\Network; -use pocketmine\Player; use pocketmine\Server; use pocketmine\snooze\SleeperNotifier; use raklib\protocol\EncapsulatedPacket; @@ -56,8 +54,8 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ /** @var RakLibServer */ private $rakLib; - /** @var Player[] */ - private $players = []; + /** @var NetworkSession[] */ + private $sessions = []; /** @var string[] */ private $identifiers = []; @@ -104,17 +102,17 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ } public function closeSession(string $identifier, string $reason) : void{ - if(isset($this->players[$identifier])){ - $player = $this->players[$identifier]; - unset($this->identifiers[spl_object_hash($player)]); - unset($this->players[$identifier]); - $player->close($player->getLeaveMessage(), $reason); + if(isset($this->sessions[$identifier])){ + $session = $this->sessions[$identifier]; + unset($this->identifiers[spl_object_hash($session)]); + unset($this->sessions[$identifier]); + $session->onClientDisconnect($reason); } } - public function close(Player $player, string $reason = "unknown reason") : void{ - if(isset($this->identifiers[$h = spl_object_hash($player)])){ - unset($this->players[$this->identifiers[$h]]); + public function close(NetworkSession $session, string $reason = "unknown reason") : void{ + if(isset($this->identifiers[$h = spl_object_hash($session)])){ + unset($this->sessions[$this->identifiers[$h]]); $this->interface->closeSession($this->identifiers[$h], $reason); unset($this->identifiers[$h]); } @@ -131,23 +129,18 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ } public function openSession(string $identifier, string $address, int $port, int $clientID) : void{ - $ev = new PlayerCreationEvent($this, $address, $port); - $this->server->getPluginManager()->callEvent($ev); - $class = $ev->getPlayerClass(); - - $player = new $class($this, $ev->getAddress(), $ev->getPort()); - $this->players[$identifier] = $player; - $this->identifiers[spl_object_hash($player)] = $identifier; - $this->server->addPlayer($player); + $session = new NetworkSession($this->server, $this, $address, $port); + $this->sessions[$identifier] = $session; + $this->identifiers[spl_object_hash($session)] = $identifier; } public function handleEncapsulated(string $identifier, EncapsulatedPacket $packet, int $flags) : void{ - if(isset($this->players[$identifier])){ + if(isset($this->sessions[$identifier])){ //get this now for blocking in case the player was closed before the exception was raised - $address = $this->players[$identifier]->getNetworkSession()->getIp(); + $address = $this->sessions[$identifier]->getIp(); try{ if($packet->buffer !== "" and $packet->buffer{0} === self::MCPE_RAKNET_PACKET_ID){ //Batch - $this->players[$identifier]->getNetworkSession()->handleEncoded(substr($packet->buffer, 1)); + $this->sessions[$identifier]->handleEncoded(substr($packet->buffer, 1)); } }catch(\Throwable $e){ $logger = $this->server->getLogger(); @@ -208,8 +201,8 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ } } - public function putPacket(Player $player, string $payload, bool $immediate = true) : void{ - if(isset($this->identifiers[$h = spl_object_hash($player)])){ + public function putPacket(NetworkSession $session, string $payload, bool $immediate = true) : void{ + if(isset($this->identifiers[$h = spl_object_hash($session)])){ $identifier = $this->identifiers[$h]; $pk = new EncapsulatedPacket(); @@ -222,8 +215,8 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ } public function updatePing(string $identifier, int $pingMS) : void{ - if(isset($this->players[$identifier])){ - $this->players[$identifier]->getNetworkSession()->updatePing($pingMS); + if(isset($this->sessions[$identifier])){ + $this->sessions[$identifier]->updatePing($pingMS); } } } diff --git a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php index a65854f49d..0c65896d4c 100644 --- a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php @@ -53,8 +53,7 @@ class LoginSessionHandler extends SessionHandler{ $this->session->sendDataPacket($pk, true); //This pocketmine disconnect message will only be seen by the console (PlayStatusPacket causes the messages to be shown for the client) - $this->player->close( - "", + $this->session->disconnect( $this->player->getServer()->getLanguage()->translateString("pocketmine.disconnect.incompatibleProtocol", [$packet->protocol]), false ); @@ -63,13 +62,13 @@ class LoginSessionHandler extends SessionHandler{ } if(!Player::isValidUserName($packet->username)){ - $this->player->close("", "disconnectionScreen.invalidName"); + $this->session->disconnect("disconnectionScreen.invalidName"); return true; } if($packet->skin === null or !$packet->skin->isValid()){ - $this->player->close("", "disconnectionScreen.invalidSkin"); + $this->session->disconnect("disconnectionScreen.invalidSkin"); return true; } diff --git a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php index 5553625383..00d72b9917 100644 --- a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php @@ -86,7 +86,7 @@ class PreSpawnSessionHandler extends SessionHandler{ $this->player->sendAllInventories(); $this->player->getInventory()->sendCreativeContents(); $this->player->getInventory()->sendHeldItem($this->player); - $this->session->getInterface()->putPacket($this->player, $this->server->getCraftingManager()->getCraftingDataPacket()); + $this->session->getInterface()->putPacket($this->session, $this->server->getCraftingManager()->getCraftingDataPacket()); $this->server->sendFullPlayerListData($this->player); } diff --git a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php index c7c24d937d..9b5499119c 100644 --- a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php @@ -66,14 +66,14 @@ class ResourcePacksSessionHandler extends SessionHandler{ private function disconnectWithError(string $error) : void{ $this->player->getServer()->getLogger()->error("Error while downloading resource packs for " . $this->player->getName() . ": " . $error); - $this->player->close("", "disconnectionScreen.resourcePack", true); + $this->session->disconnect("disconnectionScreen.resourcePack"); } public function handleResourcePackClientResponse(ResourcePackClientResponsePacket $packet) : bool{ switch($packet->status){ case ResourcePackClientResponsePacket::STATUS_REFUSED: //TODO: add lang strings for this - $this->player->close("", "You must accept resource packs to join this server.", true); + $this->session->disconnect("You must accept resource packs to join this server.", true); break; case ResourcePackClientResponsePacket::STATUS_SEND_PACKS: foreach($packet->packIds as $uuid){ From c1843ac2d4f66e9a76873cbe2b1ea3e71c0d85a7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 22 Jul 2018 12:04:53 +0100 Subject: [PATCH 0053/3224] Player: remove dataPacket() and directDataPacket() I considered renaming sendDataPacket() to dataPacket() to reduce the BC breaks, but the parameter set has changed, which might cause astonishing behaviour, so it's better to break it in a loud way. Also, this has a clearer name. --- src/pocketmine/Player.php | 62 +++++++------------ src/pocketmine/Server.php | 2 +- src/pocketmine/entity/Entity.php | 8 +-- src/pocketmine/entity/Human.php | 6 +- src/pocketmine/entity/Living.php | 2 +- src/pocketmine/entity/object/ItemEntity.php | 2 +- src/pocketmine/entity/object/Painting.php | 2 +- src/pocketmine/inventory/ArmorInventory.php | 2 +- src/pocketmine/inventory/BaseInventory.php | 4 +- .../inventory/ContainerInventory.php | 4 +- src/pocketmine/inventory/PlayerInventory.php | 4 +- .../transaction/CraftingTransaction.php | 2 +- src/pocketmine/tile/Furnace.php | 2 +- src/pocketmine/tile/Spawnable.php | 2 +- 14 files changed, 43 insertions(+), 61 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index f780677b94..567c82c7c1 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -512,7 +512,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $pk = new ChunkRadiusUpdatedPacket(); $pk->radius = $this->viewDistance; - $this->dataPacket($pk); + $this->sendDataPacket($pk); $this->server->getLogger()->debug("Setting view distance for " . $this->getName() . " to " . $this->viewDistance . " (requested " . $distance . ")"); } @@ -651,7 +651,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $pk->commandData[$command->getName()] = $data; } - $this->dataPacket($pk); + $this->sendDataPacket($pk); } @@ -1138,7 +1138,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $pk->z = $this->spawnPosition->getFloorZ(); $pk->spawnType = SetSpawnPositionPacket::TYPE_PLAYER_SPAWN; $pk->spawnForced = false; - $this->dataPacket($pk); + $this->sendDataPacket($pk); } /** @@ -1199,7 +1199,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $pk = new AnimatePacket(); $pk->entityRuntimeId = $this->id; $pk->action = AnimatePacket::ACTION_STOP_SLEEP; - $this->dataPacket($pk); + $this->sendDataPacket($pk); } } @@ -1336,7 +1336,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ public function sendGamemode(){ $pk = new SetPlayerGameTypePacket(); $pk->gamemode = Player::getClientFriendlyGamemode($this->gamemode); - $this->dataPacket($pk); + $this->sendDataPacket($pk); } /** @@ -1356,7 +1356,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $pk->playerPermission = ($this->isOp() ? PlayerPermissions::OPERATOR : PlayerPermissions::MEMBER); $pk->entityUniqueId = $this->getId(); - $this->dataPacket($pk); + $this->sendDataPacket($pk); } /** @@ -1613,7 +1613,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $pk = new UpdateAttributesPacket(); $pk->entityRuntimeId = $this->id; $pk->entries = $entries; - $this->dataPacket($pk); + $this->sendDataPacket($pk); foreach($entries as $entry){ $entry->markSynchronized(); } @@ -1721,7 +1721,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $pk->particles = $effect->isVisible(); $pk->duration = $effect->getDuration(); - $this->dataPacket($pk); + $this->sendDataPacket($pk); } protected function sendEffectRemove(EffectInstance $effect) : void{ @@ -1730,7 +1730,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $pk->eventId = MobEffectPacket::EVENT_REMOVE; $pk->effectId = $effect->getId(); - $this->dataPacket($pk); + $this->sendDataPacket($pk); } /** @@ -2018,7 +2018,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return false; } - $this->dataPacket($packet); + $this->sendDataPacket($packet); $this->server->broadcastPacket($this->getViewers(), $packet); break; default: @@ -2301,7 +2301,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $pk->entityRuntimeId = $target->getId(); $this->server->broadcastPacket($target->getViewers(), $pk); if($target instanceof Player){ - $target->dataPacket($pk); + $target->sendDataPacket($pk); } } @@ -2689,24 +2689,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return $this->networkSession->sendDataPacket($packet, $immediate); } - /** - * @param DataPacket $packet - * - * @return bool - */ - public function dataPacket(DataPacket $packet) : bool{ - return $this->sendDataPacket($packet, false); - } - - /** - * @param DataPacket $packet - * - * @return bool - */ - public function directDataPacket(DataPacket $packet) : bool{ - return $this->sendDataPacket($packet, true); - } - /** * Transfers a player to another server. * @@ -2723,7 +2705,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $pk = new TransferPacket(); $pk->address = $ev->getAddress(); $pk->port = $ev->getPort(); - $this->directDataPacket($pk); + $this->sendDataPacket($pk, true); $this->close("", $ev->getMessage(), false); return true; @@ -2804,7 +2786,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ public function removeTitles(){ $pk = new SetTitlePacket(); $pk->type = SetTitlePacket::TYPE_CLEAR_TITLE; - $this->dataPacket($pk); + $this->sendDataPacket($pk); } /** @@ -2813,7 +2795,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ public function resetTitles(){ $pk = new SetTitlePacket(); $pk->type = SetTitlePacket::TYPE_RESET_TITLE; - $this->dataPacket($pk); + $this->sendDataPacket($pk); } /** @@ -2830,7 +2812,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $pk->fadeInTime = $fadeIn; $pk->stayTime = $stay; $pk->fadeOutTime = $fadeOut; - $this->dataPacket($pk); + $this->sendDataPacket($pk); } } @@ -2844,7 +2826,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $pk = new SetTitlePacket(); $pk->type = $type; $pk->text = $title; - $this->dataPacket($pk); + $this->sendDataPacket($pk); } /** @@ -2864,7 +2846,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $pk = new TextPacket(); $pk->type = TextPacket::TYPE_RAW; $pk->message = $this->server->getLanguage()->translateString($message); - $this->dataPacket($pk); + $this->sendDataPacket($pk); } /** @@ -2885,7 +2867,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $pk->type = TextPacket::TYPE_RAW; $pk->message = $this->server->getLanguage()->translateString($message, $parameters); } - $this->dataPacket($pk); + $this->sendDataPacket($pk); } /** @@ -2900,14 +2882,14 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $pk = new TextPacket(); $pk->type = TextPacket::TYPE_POPUP; $pk->message = $message; - $this->dataPacket($pk); + $this->sendDataPacket($pk); } public function sendTip(string $message){ $pk = new TextPacket(); $pk->type = TextPacket::TYPE_TIP; $pk->message = $message; - $this->dataPacket($pk); + $this->sendDataPacket($pk); } /** @@ -2919,7 +2901,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $pk->type = TextPacket::TYPE_WHISPER; $pk->sourceName = $sender; $pk->message = $message; - $this->dataPacket($pk); + $this->sendDataPacket($pk); } /** @@ -3324,7 +3306,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ if($targets !== null){ $this->server->broadcastPacket($targets, $pk); }else{ - $this->dataPacket($pk); + $this->sendDataPacket($pk); } $this->newPosition = null; diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index b462287c76..87a2a6a5c2 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -2335,7 +2335,7 @@ class Server{ $pk->entries[] = PlayerListEntry::createAdditionEntry($player->getUniqueId(), $player->getId(), $player->getDisplayName(), "", 0, $player->getSkin(), $player->getXuid()); } - $p->dataPacket($pk); + $p->sendDataPacket($pk); } private function checkTickUpdates(int $currentTick, float $tickTime) : void{ diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 80e699274a..e51364e6ad 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -1930,7 +1930,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $pk->attributes = $this->attributeMap->getAll(); $pk->metadata = $this->propertyManager->getAll(); - $player->dataPacket($pk); + $player->sendDataPacket($pk); } /** @@ -1971,7 +1971,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ if($send){ $pk = new RemoveEntityPacket(); $pk->entityUniqueId = $this->id; - $player->dataPacket($pk); + $player->sendDataPacket($pk); } unset($this->hasSpawned[$player->getLoaderId()]); } @@ -2092,11 +2092,11 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ if($p === $this){ continue; } - $p->dataPacket(clone $pk); + $p->sendDataPacket(clone $pk); } if($this instanceof Player){ - $this->dataPacket($pk); + $this->sendDataPacket($pk); } } diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index da5a7220bb..7aa322ad2b 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -842,7 +842,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $pk = new PlayerListPacket(); $pk->type = PlayerListPacket::TYPE_ADD; $pk->entries = [PlayerListEntry::createAdditionEntry($this->uuid, $this->id, $this->getName(), $this->getName(), 0, $this->skin)]; - $player->dataPacket($pk); + $player->sendDataPacket($pk); } $pk = new AddPlayerPacket(); @@ -855,7 +855,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $pk->pitch = $this->pitch; $pk->item = $this->getInventory()->getItemInHand(); $pk->metadata = $this->propertyManager->getAll(); - $player->dataPacket($pk); + $player->sendDataPacket($pk); //TODO: Hack for MCPE 1.2.13: DATA_NAMETAG is useless in AddPlayerPacket, so it has to be sent separately $this->sendData($player, [self::DATA_NAMETAG => [self::DATA_TYPE_STRING, $this->getNameTag()]]); @@ -866,7 +866,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $pk = new PlayerListPacket(); $pk->type = PlayerListPacket::TYPE_REMOVE; $pk->entries = [PlayerListEntry::createRemovalEntry($this->uuid)]; - $player->dataPacket($pk); + $player->sendDataPacket($pk); } } diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 1c70235af0..e78fa834a1 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -341,7 +341,7 @@ abstract class Living extends Entity implements Damageable{ $pk->duration = $effect->getDuration(); $pk->eventId = MobEffectPacket::EVENT_ADD; - $player->dataPacket($pk); + $player->sendDataPacket($pk); } } diff --git a/src/pocketmine/entity/object/ItemEntity.php b/src/pocketmine/entity/object/ItemEntity.php index 2e38a386a7..708087e7e5 100644 --- a/src/pocketmine/entity/object/ItemEntity.php +++ b/src/pocketmine/entity/object/ItemEntity.php @@ -193,7 +193,7 @@ class ItemEntity extends Entity{ $pk->item = $this->getItem(); $pk->metadata = $this->propertyManager->getAll(); - $player->dataPacket($pk); + $player->sendDataPacket($pk); } public function onCollideWithPlayer(Player $player) : void{ diff --git a/src/pocketmine/entity/object/Painting.php b/src/pocketmine/entity/object/Painting.php index 6279f0dd72..4dfa7ddcd3 100644 --- a/src/pocketmine/entity/object/Painting.php +++ b/src/pocketmine/entity/object/Painting.php @@ -155,7 +155,7 @@ class Painting extends Entity{ $pk->direction = $this->direction; $pk->title = $this->motive; - $player->dataPacket($pk); + $player->sendDataPacket($pk); } /** diff --git a/src/pocketmine/inventory/ArmorInventory.php b/src/pocketmine/inventory/ArmorInventory.php index e894de67dd..5d19a8a7c2 100644 --- a/src/pocketmine/inventory/ArmorInventory.php +++ b/src/pocketmine/inventory/ArmorInventory.php @@ -108,7 +108,7 @@ class ArmorInventory extends BaseInventory{ $pk2->windowId = $player->getWindowId($this); $pk2->inventorySlot = $index; $pk2->item = $this->getItem($index); - $player->dataPacket($pk2); + $player->sendDataPacket($pk2); }else{ $player->dataPacket($pk); } diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index 337b3b80a3..6a7650dc4f 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -443,7 +443,7 @@ abstract class BaseInventory implements Inventory{ continue; } $pk->windowId = $id; - $player->dataPacket($pk); + $player->sendDataPacket($pk); } } @@ -466,7 +466,7 @@ abstract class BaseInventory implements Inventory{ continue; } $pk->windowId = $id; - $player->dataPacket($pk); + $player->sendDataPacket($pk); } } diff --git a/src/pocketmine/inventory/ContainerInventory.php b/src/pocketmine/inventory/ContainerInventory.php index 1a2c4c4eae..4ede6d8263 100644 --- a/src/pocketmine/inventory/ContainerInventory.php +++ b/src/pocketmine/inventory/ContainerInventory.php @@ -56,7 +56,7 @@ abstract class ContainerInventory extends BaseInventory{ $pk->z = $holder->getFloorZ(); } - $who->dataPacket($pk); + $who->sendDataPacket($pk); $this->sendContents($who); } @@ -64,7 +64,7 @@ abstract class ContainerInventory extends BaseInventory{ public function onClose(Player $who) : void{ $pk = new ContainerClosePacket(); $pk->windowId = $who->getWindowId($this); - $who->dataPacket($pk); + $who->sendDataPacket($pk); parent::onClose($who); } diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index b701afca05..6d43f5286d 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -144,7 +144,7 @@ class PlayerInventory extends BaseInventory{ $pk->windowId = ContainerIds::INVENTORY; if(!is_array($target)){ - $target->dataPacket($pk); + $target->sendDataPacket($pk); if($target === $this->getHolder()){ $this->sendSlot($this->getHeldItemIndex(), $target); } @@ -174,7 +174,7 @@ class PlayerInventory extends BaseInventory{ } } - $this->getHolder()->dataPacket($pk); + $this->getHolder()->sendDataPacket($pk); } /** diff --git a/src/pocketmine/inventory/transaction/CraftingTransaction.php b/src/pocketmine/inventory/transaction/CraftingTransaction.php index 6de3a4b522..d69b0d5ace 100644 --- a/src/pocketmine/inventory/transaction/CraftingTransaction.php +++ b/src/pocketmine/inventory/transaction/CraftingTransaction.php @@ -149,7 +149,7 @@ class CraftingTransaction extends InventoryTransaction{ */ $pk = new ContainerClosePacket(); $pk->windowId = ContainerIds::NONE; - $this->source->dataPacket($pk); + $this->source->sendDataPacket($pk); } public function execute() : bool{ diff --git a/src/pocketmine/tile/Furnace.php b/src/pocketmine/tile/Furnace.php index 2790f52d2c..848d5fba2b 100644 --- a/src/pocketmine/tile/Furnace.php +++ b/src/pocketmine/tile/Furnace.php @@ -235,7 +235,7 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ if($windowId > 0){ foreach($packets as $pk){ $pk->windowId = $windowId; - $player->dataPacket(clone $pk); + $player->sendDataPacket(clone $pk); } } } diff --git a/src/pocketmine/tile/Spawnable.php b/src/pocketmine/tile/Spawnable.php index 76c3f3c640..98e385a533 100644 --- a/src/pocketmine/tile/Spawnable.php +++ b/src/pocketmine/tile/Spawnable.php @@ -52,7 +52,7 @@ abstract class Spawnable extends Tile{ return false; } - $player->dataPacket($this->createSpawnPacket()); + $player->sendDataPacket($this->createSpawnPacket()); return true; } From fe1df7092394d86d063808276b60929c11912f09 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 22 Jul 2018 12:20:13 +0100 Subject: [PATCH 0054/3224] Player: be less horrible and leave a deprecated proxy for dataPacket() --- src/pocketmine/Player.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 567c82c7c1..f539a7b7a4 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2689,6 +2689,18 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return $this->networkSession->sendDataPacket($packet, $immediate); } + /** + * @deprecated This is a proxy for sendDataPacket() and will be removed in the next major release. + * @see Player::sendDataPacket() + * + * @param DataPacket $packet + * + * @return bool + */ + public function dataPacket(DataPacket $packet) : bool{ + return $this->sendDataPacket($packet, false); + } + /** * Transfers a player to another server. * From cc84ec8629f9889f504ea2f6f99f7f5b2f261ff7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 22 Jul 2018 13:41:06 +0100 Subject: [PATCH 0055/3224] Fixed Player/NetworkSession/SessionHandler cycle memory leak NetworkSession and some SessionHandlers hold cyclic refs to each other, stopping them getting destroyed. Unfortunately, these also reference the player, stopping that getting destroyed too. The cycle garbage collector will deal with this, but it's best to get rid of the cyclic refs for immediate collection. --- src/pocketmine/network/mcpe/NetworkSession.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 494d62def6..333dace3bb 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -228,6 +228,7 @@ class NetworkSession{ } $this->interface->close($this, $notify ? $reason : ""); + $this->disconnectCleanup(); } /** @@ -240,9 +241,16 @@ class NetworkSession{ if($this->connected){ $this->connected = false; $this->player->close($this->player->getLeaveMessage(), $reason); + $this->disconnectCleanup(); } } + private function disconnectCleanup() : void{ + $this->handler = null; + $this->interface = null; + $this->player = null; + } + //TODO: onEnableEncryption() step public function onLoginSuccess() : void{ From 622fe9998200c7894241468167d8f49d4934f814 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 23 Jul 2018 14:38:46 +0100 Subject: [PATCH 0056/3224] NetworkSession: Don't crash on failure to decode compressed batches this could be an outdated version (pre-1.1 for example). --- src/pocketmine/network/mcpe/NetworkSession.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 333dace3bb..7e409cca01 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -144,7 +144,13 @@ class NetworkSession{ //TODO: decryption if enabled - $stream = new PacketStream(NetworkCompression::decompress($payload)); + try{ + $stream = new PacketStream(NetworkCompression::decompress($payload)); + }catch(\ErrorException $e){ + $this->server->getLogger()->debug("Failed to decompress packet from " . $this->ip . " " . $this->port . ": " . bin2hex($payload)); + $this->disconnect("Compressed packet batch decode error (incompatible game version?)", false); + return; + } while(!$stream->feof() and $this->connected){ $this->handleDataPacket(PacketPool::getPacket($stream->getString())); } From 522f0f5c25cd9a69b2a707e6ffb1924f56236001 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 26 Jul 2018 14:05:38 +0100 Subject: [PATCH 0057/3224] Config: remove dead field --- src/pocketmine/utils/Config.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pocketmine/utils/Config.php b/src/pocketmine/utils/Config.php index 98e9aa2a43..211412c2f6 100644 --- a/src/pocketmine/utils/Config.php +++ b/src/pocketmine/utils/Config.php @@ -44,8 +44,6 @@ class Config{ /** @var string */ private $file; - /** @var bool */ - private $correct = false; /** @var int */ private $type = Config::DETECT; /** @var int */ From d305a1342fcd84755c8e90da43e1cc64d23581c3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 26 Jul 2018 14:55:55 +0100 Subject: [PATCH 0058/3224] Make Tile::registerTile() and Entity::registerEntity() throw exceptions instead of returning false --- src/pocketmine/entity/Entity.php | 51 ++++++++++++++++++-------------- src/pocketmine/tile/Tile.php | 45 ++++++++++++++-------------- 2 files changed, 51 insertions(+), 45 deletions(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 0af2ed268c..480d38cbfa 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -301,34 +301,39 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ * NOTE: The first save name in the $saveNames array will be used when saving the entity to disk. The reflection * name of the class will be appended to the end and only used if no other save names are specified. * - * @return bool + * @throws \InvalidArgumentException */ - public static function registerEntity(string $className, bool $force = false, array $saveNames = []) : bool{ + public static function registerEntity(string $className, bool $force = false, array $saveNames = []) : void{ /** @var Entity $className */ - $class = new \ReflectionClass($className); - if(is_a($className, Entity::class, true) and !$class->isAbstract()){ - if($className::NETWORK_ID !== -1){ - self::$knownEntities[$className::NETWORK_ID] = $className; - }elseif(!$force){ - return false; - } - - $shortName = $class->getShortName(); - if(!in_array($shortName, $saveNames, true)){ - $saveNames[] = $shortName; - } - - foreach($saveNames as $name){ - self::$knownEntities[$name] = $className; - } - - self::$saveNames[$className] = $saveNames; - - return true; + try{ + $class = new \ReflectionClass($className); + }catch(\ReflectionException $e){ + throw new \InvalidArgumentException("Class $className does not exist"); + } + if(!$class->isSubclassOf(Entity::class)){ + throw new \InvalidArgumentException("Class $className does not extend " . Entity::class); + } + if(!$class->isInstantiable()){ + throw new \InvalidArgumentException("Class $className cannot be constructed"); } - return false; + if($className::NETWORK_ID !== -1){ + self::$knownEntities[$className::NETWORK_ID] = $className; + }elseif(!$force){ + throw new \InvalidArgumentException("Class $className does not declare a valid NETWORK_ID and not force-registering"); + } + + $shortName = $class->getShortName(); + if(!in_array($shortName, $saveNames, true)){ + $saveNames[] = $shortName; + } + + foreach($saveNames as $name){ + self::$knownEntities[$name] = $className; + } + + self::$saveNames[$className] = $saveNames; } /** diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/tile/Tile.php index 0bda6abd78..78cda5fed4 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/tile/Tile.php @@ -110,31 +110,32 @@ abstract class Tile extends Position{ } /** - * @param string $className - * @param array $saveNames - * - * @return bool - * @throws \ReflectionException + * @param string $className + * @param string[] $saveNames */ - public static function registerTile(string $className, array $saveNames = []) : bool{ - $class = new \ReflectionClass($className); - if(is_a($className, Tile::class, true) and !$class->isAbstract()){ - $shortName = $class->getShortName(); - if(!in_array($shortName, $saveNames, true)){ - $saveNames[] = $shortName; - } - - foreach($saveNames as $name){ - self::$knownTiles[$name] = $className; - } - - self::$saveNames[$className] = $saveNames; - - - return true; + public static function registerTile(string $className, array $saveNames = []) : void{ + try{ + $class = new \ReflectionClass($className); + }catch(\ReflectionException $e){ + throw new \InvalidArgumentException("Class $className does not exist"); + } + if(!$class->isSubclassOf(Tile::class)){ + throw new \InvalidArgumentException("Class $className does not extend " . Tile::class); + } + if(!$class->isInstantiable()){ + throw new \InvalidArgumentException("Class $className cannot be constructed"); } - return false; + $shortName = $class->getShortName(); + if(!in_array($shortName, $saveNames, true)){ + $saveNames[] = $shortName; + } + + foreach($saveNames as $name){ + self::$knownTiles[$name] = $className; + } + + self::$saveNames[$className] = $saveNames; } /** From e0166937795dd2cc779bdb04765a14245b19f4a7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 26 Jul 2018 15:17:16 +0100 Subject: [PATCH 0059/3224] Test one extra case for LevelProviderManager --- tests/phpunit/level/format/io/LevelProviderManagerTest.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/phpunit/level/format/io/LevelProviderManagerTest.php b/tests/phpunit/level/format/io/LevelProviderManagerTest.php index 7661de234b..64b6206225 100644 --- a/tests/phpunit/level/format/io/LevelProviderManagerTest.php +++ b/tests/phpunit/level/format/io/LevelProviderManagerTest.php @@ -44,4 +44,10 @@ class LevelProviderManagerTest extends TestCase{ LevelProviderManager::addProvider(InterfaceLevelProvider::class); } + + public function testAddWrongClassProvider() : void{ + $this->expectException(\InvalidArgumentException::class); + + LevelProviderManager::addProvider(LevelProviderManagerTest::class); + } } From be37236c7660e1f204a0c6c5dbccb3620c3d48a1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 26 Jul 2018 15:21:03 +0100 Subject: [PATCH 0060/3224] Deduplicate code for general classpath registries --- src/pocketmine/entity/Entity.php | 18 ++++------------ .../level/format/io/LevelProviderManager.php | 13 ++---------- src/pocketmine/tile/Tile.php | 15 +++---------- src/pocketmine/utils/Utils.php | 21 +++++++++++++++++++ 4 files changed, 30 insertions(+), 37 deletions(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 480d38cbfa..e2ea69f1a2 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -73,6 +73,7 @@ use pocketmine\plugin\Plugin; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; +use pocketmine\utils\Utils; abstract class Entity extends Location implements Metadatable, EntityIds{ @@ -304,27 +305,16 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ * @throws \InvalidArgumentException */ public static function registerEntity(string $className, bool $force = false, array $saveNames = []) : void{ + Utils::testValidInstance($className, Entity::class); + /** @var Entity $className */ - - try{ - $class = new \ReflectionClass($className); - }catch(\ReflectionException $e){ - throw new \InvalidArgumentException("Class $className does not exist"); - } - if(!$class->isSubclassOf(Entity::class)){ - throw new \InvalidArgumentException("Class $className does not extend " . Entity::class); - } - if(!$class->isInstantiable()){ - throw new \InvalidArgumentException("Class $className cannot be constructed"); - } - if($className::NETWORK_ID !== -1){ self::$knownEntities[$className::NETWORK_ID] = $className; }elseif(!$force){ throw new \InvalidArgumentException("Class $className does not declare a valid NETWORK_ID and not force-registering"); } - $shortName = $class->getShortName(); + $shortName = (new \ReflectionClass($className))->getShortName(); if(!in_array($shortName, $saveNames, true)){ $saveNames[] = $shortName; } diff --git a/src/pocketmine/level/format/io/LevelProviderManager.php b/src/pocketmine/level/format/io/LevelProviderManager.php index 1b42a5eda5..04f30f168b 100644 --- a/src/pocketmine/level/format/io/LevelProviderManager.php +++ b/src/pocketmine/level/format/io/LevelProviderManager.php @@ -27,6 +27,7 @@ use pocketmine\level\format\io\leveldb\LevelDB; use pocketmine\level\format\io\region\Anvil; use pocketmine\level\format\io\region\McRegion; use pocketmine\level\format\io\region\PMAnvil; +use pocketmine\utils\Utils; abstract class LevelProviderManager{ protected static $providers = []; @@ -44,17 +45,7 @@ abstract class LevelProviderManager{ * @throws \InvalidArgumentException */ public static function addProvider(string $class){ - try{ - $reflection = new \ReflectionClass($class); - }catch(\ReflectionException $e){ - throw new \InvalidArgumentException("Class $class does not exist"); - } - if(!$reflection->implementsInterface(LevelProvider::class)){ - throw new \InvalidArgumentException("Class $class does not implement " . LevelProvider::class); - } - if(!$reflection->isInstantiable()){ - throw new \InvalidArgumentException("Class $class cannot be constructed"); - } + Utils::testValidInstance($class, LevelProvider::class); /** @var LevelProvider $class */ self::$providers[strtolower($class::getProviderName())] = $class; diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/tile/Tile.php index 78cda5fed4..d268496496 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/tile/Tile.php @@ -39,6 +39,7 @@ use pocketmine\Player; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; +use pocketmine\utils\Utils; abstract class Tile extends Position{ @@ -114,19 +115,9 @@ abstract class Tile extends Position{ * @param string[] $saveNames */ public static function registerTile(string $className, array $saveNames = []) : void{ - try{ - $class = new \ReflectionClass($className); - }catch(\ReflectionException $e){ - throw new \InvalidArgumentException("Class $className does not exist"); - } - if(!$class->isSubclassOf(Tile::class)){ - throw new \InvalidArgumentException("Class $className does not extend " . Tile::class); - } - if(!$class->isInstantiable()){ - throw new \InvalidArgumentException("Class $className cannot be constructed"); - } + Utils::testValidInstance($className, Tile::class); - $shortName = $class->getShortName(); + $shortName = (new \ReflectionClass($className))->getShortName(); if(!in_array($shortName, $saveNames, true)){ $saveNames[] = $shortName; } diff --git a/src/pocketmine/utils/Utils.php b/src/pocketmine/utils/Utils.php index fa80a13ac3..08552626a2 100644 --- a/src/pocketmine/utils/Utils.php +++ b/src/pocketmine/utils/Utils.php @@ -547,4 +547,25 @@ class Utils{ return true; //stfu operator } + + public static function testValidInstance(string $className, string $baseName) : void{ + try{ + $base = new \ReflectionClass($baseName); + }catch(\ReflectionException $e){ + throw new \InvalidArgumentException("Base class $baseName does not exist"); + } + + try{ + $class = new \ReflectionClass($className); + }catch(\ReflectionException $e){ + throw new \InvalidArgumentException("Class $className does not exist"); + } + + if(!$class->isSubclassOf($baseName)){ + throw new \InvalidArgumentException("Class $className does not " . ($base->isInterface() ? "implement" : "extend") . " " . $baseName); + } + if(!$class->isInstantiable()){ + throw new \InvalidArgumentException("Class $className cannot be constructed"); + } + } } From 20a5b756223564b756acbeefec53d0433a8bc4b7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 26 Jul 2018 19:14:16 +0100 Subject: [PATCH 0061/3224] PluginBase: fixed error always being emitted on saveConfig() This now throws exceptions... let's let the caller deal with this instead, it makes more sense anyway --- src/pocketmine/plugin/PluginBase.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pocketmine/plugin/PluginBase.php b/src/pocketmine/plugin/PluginBase.php index 6127a1f5c3..5cfdd08cc3 100644 --- a/src/pocketmine/plugin/PluginBase.php +++ b/src/pocketmine/plugin/PluginBase.php @@ -254,9 +254,7 @@ abstract class PluginBase implements Plugin{ } public function saveConfig(){ - if(!$this->getConfig()->save()){ - $this->getLogger()->critical("Could not save config to " . $this->configFile); - } + $this->getConfig()->save(); } public function saveDefaultConfig() : bool{ From edb03e8a9b31ae1bd01aa79ce4c59d78f927b483 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 26 Jul 2018 19:21:38 +0100 Subject: [PATCH 0062/3224] Remove more dead code from the generator this stuff is useless broken crap that just makes noise in inspections for no good reason... bye --- .../level/generator/object/BigTree.php | 85 ------------------- .../level/generator/object/Pond.php | 47 ---------- .../generator/object/PopulatorObject.php | 32 ------- .../level/generator/populator/Pond.php | 60 ------------- 4 files changed, 224 deletions(-) delete mode 100644 src/pocketmine/level/generator/object/BigTree.php delete mode 100644 src/pocketmine/level/generator/object/Pond.php delete mode 100644 src/pocketmine/level/generator/object/PopulatorObject.php delete mode 100644 src/pocketmine/level/generator/populator/Pond.php diff --git a/src/pocketmine/level/generator/object/BigTree.php b/src/pocketmine/level/generator/object/BigTree.php deleted file mode 100644 index 0306c6b726..0000000000 --- a/src/pocketmine/level/generator/object/BigTree.php +++ /dev/null @@ -1,85 +0,0 @@ -trunkHeight = (int) ($this->totalHeight * $this->trunkHeightMultiplier); - $leaves = $this->getLeafGroupPoints($level, $pos); - foreach($leaves as $leafGroup){ - $groupX = $leafGroup->getBlockX(); - $groupY = $leafGroup->getBlockY(); - $groupZ = $leafGroup->getBlockZ(); - for($yy = $groupY; $yy < $groupY + $this->leafDistanceLimit; ++$yy){ - $this->generateGroupLayer($level, $groupX, $yy, $groupZ, $this->getLeafGroupLayerSize($yy - $groupY)); - } - } - final BlockIterator trunk = new BlockIterator(new Point(w, x, y - 1, z), new Point(w, x, y + trunkHeight, z)); - while (trunk.hasNext()) { - trunk.next().setMaterial(VanillaMaterials.LOG, logMetadata); - } - generateBranches(w, x, y, z, leaves); - - $level->setBlock($x, $pos->y - 1, $z, 3, 0); - $this->totalHeight += $random->nextRange(0, 2); - $this->leavesHeight += mt_rand(0, 1); - for($yy = ($this->totalHeight - $this->leavesHeight); $yy < ($this->totalHeight + 1); ++$yy){ - $yRadius = ($yy - $this->totalHeight); - $xzRadius = (int) (($this->radiusIncrease + 1) - $yRadius / 2); - for($xx = -$xzRadius; $xx < ($xzRadius + 1); ++$xx){ - for($zz = -$xzRadius; $zz < ($xzRadius + 1); ++$zz){ - if((abs($xx) != $xzRadius or abs($zz) != $xzRadius) and $yRadius != 0){ - $level->setBlock($pos->x + $xx, $pos->y + $yy, $pos->z + $zz, 18, $this->type); - } - } - } - } - for($yy = 0; $yy < ($this->totalHeight - 1); ++$yy){ - $level->setBlock($x, $pos->y + $yy, $z, 17, $this->type); - } - */ - } -} diff --git a/src/pocketmine/level/generator/object/Pond.php b/src/pocketmine/level/generator/object/Pond.php deleted file mode 100644 index 560d644648..0000000000 --- a/src/pocketmine/level/generator/object/Pond.php +++ /dev/null @@ -1,47 +0,0 @@ -type = $type; - $this->random = $random; - } - - public function canPlaceObject(ChunkManager $level, Vector3 $pos) : bool{ - return false; - } - - public function placeObject(ChunkManager $level, Vector3 $pos){ - - } -} diff --git a/src/pocketmine/level/generator/object/PopulatorObject.php b/src/pocketmine/level/generator/object/PopulatorObject.php deleted file mode 100644 index 0b7b0def64..0000000000 --- a/src/pocketmine/level/generator/object/PopulatorObject.php +++ /dev/null @@ -1,32 +0,0 @@ -nextRange(0, $this->waterOdd) === 0){ - $x = $random->nextRange($chunkX << 4, ($chunkX << 4) + 16); - $y = $random->nextBoundedInt(128); - $z = $random->nextRange($chunkZ << 4, ($chunkZ << 4) + 16); - $pond = new \pocketmine\level\generator\object\Pond($random, BlockFactory::get(Block::WATER)); - if($pond->canPlaceObject($level, $v = new Vector3($x, $y, $z))){ - $pond->placeObject($level, $v); - } - } - } - - public function setWaterOdd(int $waterOdd){ - $this->waterOdd = $waterOdd; - } - - public function setLavaOdd(int $lavaOdd){ - $this->lavaOdd = $lavaOdd; - } - - public function setLavaSurfaceOdd(int $lavaSurfaceOdd){ - $this->lavaSurfaceOdd = $lavaSurfaceOdd; - } -} From eb738d1d724fcac46119ab9d5989a7db95dd00f6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 26 Jul 2018 19:31:18 +0100 Subject: [PATCH 0063/3224] Apply more typehints to generator namespace --- .../level/generator/GeneratorRegisterTask.php | 2 +- .../level/generator/GeneratorUnregisterTask.php | 2 +- src/pocketmine/level/generator/PopulationTask.php | 4 ++-- src/pocketmine/level/generator/biome/BiomeSelector.php | 2 +- src/pocketmine/level/generator/object/BirchTree.php | 2 +- src/pocketmine/level/generator/object/OakTree.php | 2 +- src/pocketmine/level/generator/object/Ore.php | 2 +- src/pocketmine/level/generator/object/SpruceTree.php | 2 +- src/pocketmine/level/generator/object/TallGrass.php | 2 +- src/pocketmine/level/generator/object/Tree.php | 7 +++---- .../level/generator/populator/GroundCover.php | 2 +- src/pocketmine/level/generator/populator/Ore.php | 4 ++-- src/pocketmine/level/generator/populator/Populator.php | 10 ++++------ src/pocketmine/level/generator/populator/TallGrass.php | 6 +++--- src/pocketmine/level/generator/populator/Tree.php | 8 ++++---- 15 files changed, 27 insertions(+), 30 deletions(-) diff --git a/src/pocketmine/level/generator/GeneratorRegisterTask.php b/src/pocketmine/level/generator/GeneratorRegisterTask.php index 1c608a7e18..c1c0f6a8e4 100644 --- a/src/pocketmine/level/generator/GeneratorRegisterTask.php +++ b/src/pocketmine/level/generator/GeneratorRegisterTask.php @@ -46,7 +46,7 @@ class GeneratorRegisterTask extends AsyncTask{ $this->worldHeight = $level->getWorldHeight(); } - public function onRun(){ + public function onRun() : void{ BlockFactory::init(); Biome::init(); $manager = new SimpleChunkManager($this->seed, $this->worldHeight); diff --git a/src/pocketmine/level/generator/GeneratorUnregisterTask.php b/src/pocketmine/level/generator/GeneratorUnregisterTask.php index 780268cac2..54aa2fb481 100644 --- a/src/pocketmine/level/generator/GeneratorUnregisterTask.php +++ b/src/pocketmine/level/generator/GeneratorUnregisterTask.php @@ -34,7 +34,7 @@ class GeneratorUnregisterTask extends AsyncTask{ $this->levelId = $level->getId(); } - public function onRun(){ + public function onRun() : void{ $this->removeFromThreadStore("generation.level{$this->levelId}.manager"); $this->removeFromThreadStore("generation.level{$this->levelId}.generator"); } diff --git a/src/pocketmine/level/generator/PopulationTask.php b/src/pocketmine/level/generator/PopulationTask.php index 007a6f87f5..af94ffd8e0 100644 --- a/src/pocketmine/level/generator/PopulationTask.php +++ b/src/pocketmine/level/generator/PopulationTask.php @@ -55,7 +55,7 @@ class PopulationTask extends AsyncTask{ } } - public function onRun(){ + public function onRun() : void{ /** @var SimpleChunkManager $manager */ $manager = $this->getFromThreadStore("generation.level{$this->levelId}.manager"); /** @var Generator $generator */ @@ -135,7 +135,7 @@ class PopulationTask extends AsyncTask{ } } - public function onCompletion(Server $server){ + public function onCompletion(Server $server) : void{ $level = $server->getLevel($this->levelId); if($level !== null){ if(!$this->state){ diff --git a/src/pocketmine/level/generator/biome/BiomeSelector.php b/src/pocketmine/level/generator/biome/BiomeSelector.php index 5d80d607e1..0af35246e0 100644 --- a/src/pocketmine/level/generator/biome/BiomeSelector.php +++ b/src/pocketmine/level/generator/biome/BiomeSelector.php @@ -52,7 +52,7 @@ abstract class BiomeSelector{ */ abstract protected function lookup(float $temperature, float $rainfall) : int; - public function recalculate(){ + public function recalculate() : void{ $this->map = new \SplFixedArray(64 * 64); for($i = 0; $i < 64; ++$i){ diff --git a/src/pocketmine/level/generator/object/BirchTree.php b/src/pocketmine/level/generator/object/BirchTree.php index 18a3cc9f56..1dedf230d1 100644 --- a/src/pocketmine/level/generator/object/BirchTree.php +++ b/src/pocketmine/level/generator/object/BirchTree.php @@ -39,7 +39,7 @@ class BirchTree extends Tree{ $this->superBirch = $superBirch; } - public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random){ + public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ $this->treeHeight = $random->nextBoundedInt(3) + 5; if($this->superBirch){ $this->treeHeight += 5; diff --git a/src/pocketmine/level/generator/object/OakTree.php b/src/pocketmine/level/generator/object/OakTree.php index 47865de7ee..27d24326d1 100644 --- a/src/pocketmine/level/generator/object/OakTree.php +++ b/src/pocketmine/level/generator/object/OakTree.php @@ -36,7 +36,7 @@ class OakTree extends Tree{ $this->type = Wood::OAK; } - public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random){ + public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ $this->treeHeight = $random->nextBoundedInt(3) + 4; parent::placeObject($level, $x, $y, $z, $random); } diff --git a/src/pocketmine/level/generator/object/Ore.php b/src/pocketmine/level/generator/object/Ore.php index c8b2ea33dd..27e7a15f9e 100644 --- a/src/pocketmine/level/generator/object/Ore.php +++ b/src/pocketmine/level/generator/object/Ore.php @@ -47,7 +47,7 @@ class Ore{ return $level->getBlockIdAt($x, $y, $z) === Block::STONE; } - public function placeObject(ChunkManager $level, int $x, int $y, int $z){ + public function placeObject(ChunkManager $level, int $x, int $y, int $z) : void{ $clusterSize = $this->type->clusterSize; $angle = $this->random->nextFloat() * M_PI; $offset = VectorMath::getDirection2D($angle)->multiply($clusterSize / 8); diff --git a/src/pocketmine/level/generator/object/SpruceTree.php b/src/pocketmine/level/generator/object/SpruceTree.php index 30ac7315e9..eb09978c55 100644 --- a/src/pocketmine/level/generator/object/SpruceTree.php +++ b/src/pocketmine/level/generator/object/SpruceTree.php @@ -38,7 +38,7 @@ class SpruceTree extends Tree{ $this->treeHeight = 10; } - public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random){ + public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ $this->treeHeight = $random->nextBoundedInt(4) + 6; $topSize = $this->treeHeight - (1 + $random->nextBoundedInt(2)); diff --git a/src/pocketmine/level/generator/object/TallGrass.php b/src/pocketmine/level/generator/object/TallGrass.php index bb60682a37..cfa8098b12 100644 --- a/src/pocketmine/level/generator/object/TallGrass.php +++ b/src/pocketmine/level/generator/object/TallGrass.php @@ -30,7 +30,7 @@ use pocketmine\utils\Random; class TallGrass{ - public static function growGrass(ChunkManager $level, Vector3 $pos, Random $random, int $count = 15, int $radius = 10){ + public static function growGrass(ChunkManager $level, Vector3 $pos, Random $random, int $count = 15, int $radius = 10) : void{ $arr = [ [Block::DANDELION, 0], [Block::POPPY, 0], diff --git a/src/pocketmine/level/generator/object/Tree.php b/src/pocketmine/level/generator/object/Tree.php index 27b8107297..e79dd6cb98 100644 --- a/src/pocketmine/level/generator/object/Tree.php +++ b/src/pocketmine/level/generator/object/Tree.php @@ -45,7 +45,7 @@ abstract class Tree{ public $leafBlock = Block::LEAVES; public $treeHeight = 7; - public static function growTree(ChunkManager $level, int $x, int $y, int $z, Random $random, int $type = 0){ + public static function growTree(ChunkManager $level, int $x, int $y, int $z, Random $random, int $type = Sapling::OAK) : void{ switch($type){ case Sapling::SPRUCE: $tree = new SpruceTree(); @@ -96,8 +96,7 @@ abstract class Tree{ return true; } - public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random){ - + public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ $this->placeTrunk($level, $x, $y, $z, $random, $this->treeHeight - 1); for($yy = $y - 3 + $this->treeHeight; $yy <= $y + $this->treeHeight; ++$yy){ @@ -119,7 +118,7 @@ abstract class Tree{ } } - protected function placeTrunk(ChunkManager $level, int $x, int $y, int $z, Random $random, int $trunkHeight){ + protected function placeTrunk(ChunkManager $level, int $x, int $y, int $z, Random $random, int $trunkHeight) : void{ // The base dirt block $level->setBlockIdAt($x, $y - 1, $z, Block::DIRT); diff --git a/src/pocketmine/level/generator/populator/GroundCover.php b/src/pocketmine/level/generator/populator/GroundCover.php index 70e7e09456..1410beb0ae 100644 --- a/src/pocketmine/level/generator/populator/GroundCover.php +++ b/src/pocketmine/level/generator/populator/GroundCover.php @@ -31,7 +31,7 @@ use pocketmine\utils\Random; class GroundCover extends Populator{ - public function populate(ChunkManager $level, int $chunkX, int $chunkZ, Random $random){ + public function populate(ChunkManager $level, int $chunkX, int $chunkZ, Random $random) : void{ $chunk = $level->getChunk($chunkX, $chunkZ); for($x = 0; $x < 16; ++$x){ for($z = 0; $z < 16; ++$z){ diff --git a/src/pocketmine/level/generator/populator/Ore.php b/src/pocketmine/level/generator/populator/Ore.php index a5b472fa51..0b7f982e81 100644 --- a/src/pocketmine/level/generator/populator/Ore.php +++ b/src/pocketmine/level/generator/populator/Ore.php @@ -32,7 +32,7 @@ class Ore extends Populator{ /** @var OreType[] */ private $oreTypes = []; - public function populate(ChunkManager $level, int $chunkX, int $chunkZ, Random $random){ + public function populate(ChunkManager $level, int $chunkX, int $chunkZ, Random $random) : void{ foreach($this->oreTypes as $type){ $ore = new ObjectOre($random, $type); for($i = 0; $i < $ore->type->clusterCount; ++$i){ @@ -49,7 +49,7 @@ class Ore extends Populator{ /** * @param OreType[] $types */ - public function setOreTypes(array $types){ + public function setOreTypes(array $types) : void{ $this->oreTypes = $types; } } diff --git a/src/pocketmine/level/generator/populator/Populator.php b/src/pocketmine/level/generator/populator/Populator.php index 50fb359195..c913e7a618 100644 --- a/src/pocketmine/level/generator/populator/Populator.php +++ b/src/pocketmine/level/generator/populator/Populator.php @@ -33,11 +33,9 @@ abstract class Populator{ /** * @param ChunkManager $level - * @param int $chunkX - * @param int $chunkZ - * @param Random $random - * - * @return mixed + * @param int $chunkX + * @param int $chunkZ + * @param Random $random */ - abstract public function populate(ChunkManager $level, int $chunkX, int $chunkZ, Random $random); + abstract public function populate(ChunkManager $level, int $chunkX, int $chunkZ, Random $random) : void; } diff --git a/src/pocketmine/level/generator/populator/TallGrass.php b/src/pocketmine/level/generator/populator/TallGrass.php index a601799466..3532bc568b 100644 --- a/src/pocketmine/level/generator/populator/TallGrass.php +++ b/src/pocketmine/level/generator/populator/TallGrass.php @@ -33,15 +33,15 @@ class TallGrass extends Populator{ private $randomAmount; private $baseAmount; - public function setRandomAmount($amount){ + public function setRandomAmount(int $amount) : void{ $this->randomAmount = $amount; } - public function setBaseAmount($amount){ + public function setBaseAmount(int $amount) : void{ $this->baseAmount = $amount; } - public function populate(ChunkManager $level, int $chunkX, int $chunkZ, Random $random){ + public function populate(ChunkManager $level, int $chunkX, int $chunkZ, Random $random) : void{ $this->level = $level; $amount = $random->nextRange(0, $this->randomAmount + 1) + $this->baseAmount; for($i = 0; $i < $amount; ++$i){ diff --git a/src/pocketmine/level/generator/populator/Tree.php b/src/pocketmine/level/generator/populator/Tree.php index cbe8e6bcee..6250aa41ad 100644 --- a/src/pocketmine/level/generator/populator/Tree.php +++ b/src/pocketmine/level/generator/populator/Tree.php @@ -37,19 +37,19 @@ class Tree extends Populator{ private $type; - public function __construct($type = Sapling::OAK){ + public function __construct(int $type = Sapling::OAK){ $this->type = $type; } - public function setRandomAmount($amount){ + public function setRandomAmount(int $amount) : void{ $this->randomAmount = $amount; } - public function setBaseAmount($amount){ + public function setBaseAmount(int $amount) : void{ $this->baseAmount = $amount; } - public function populate(ChunkManager $level, int $chunkX, int $chunkZ, Random $random){ + public function populate(ChunkManager $level, int $chunkX, int $chunkZ, Random $random) : void{ $this->level = $level; $amount = $random->nextRange(0, $this->randomAmount + 1) + $this->baseAmount; for($i = 0; $i < $amount; ++$i){ From f3cf64c2cf24a9a7b99301e4f8091c315423e05d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Jul 2018 12:27:29 +0100 Subject: [PATCH 0064/3224] Security vulnerability reporting for dummies --- .github/ISSUE_TEMPLATE.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index e23b3d3afd..09d826a78a 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -4,6 +4,9 @@ THIS ISSUE TRACKER IS FOR BUG REPORTING, NOT FOR HELP & SUPPORT. If you need hel - http://pmmp.readthedocs.io/en/rtfd/ - Documentation - https://forums.pmmp.io - PMMP Forums +PLEASE DO NOT REPORT ATTACK VECTORS ON THIS ISSUE TRACKER. +Send an email to team@pmmp.io if you have a vulnerability to report. + Any issues requesting updates to new versions of MCPE will be treated as spam. Please do not create issues for missing/un-implemented gameplay features - they will be closed. --> From 7541a6070fdda8d3f3a5e6a3e844aba15bff392f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Jul 2018 18:04:13 +0100 Subject: [PATCH 0065/3224] Player: clean up handling of authentication --- src/pocketmine/Player.php | 31 ++++++++++--------- .../network/mcpe/VerifyLoginTask.php | 2 +- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 391ecc8811..eb52c3e654 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -187,6 +187,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ protected $randomClientId; /** @var string */ protected $xuid = ""; + /** @var bool */ + protected $authenticated = false; protected $windowCnt = 2; /** @var int[] */ @@ -325,7 +327,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } public function isAuthenticated() : bool{ - return $this->xuid !== ""; + return $this->authenticated; } /** @@ -1765,6 +1767,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->uuid = UUID::fromString($packet->clientUUID); $this->rawUUID = $this->uuid->toBinary(); + $this->xuid = $packet->xuid; $this->setSkin($packet->skin); @@ -1794,42 +1797,40 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ if(!$packet->skipVerification){ $this->server->getAsyncPool()->submitTask(new VerifyLoginTask($this, $packet)); }else{ - $this->onVerifyCompleted($packet, null, true); + $this->onVerifyCompleted(true, null); } return true; } - public function onVerifyCompleted(LoginPacket $packet, ?string $error, bool $signedByMojang) : void{ + public function onVerifyCompleted(bool $authenticated, ?string $error) : void{ if($this->closed){ return; } + if($authenticated and $this->xuid === ""){ + $error = "Expected XUID but none found"; + } + if($error !== null){ $this->close("", $this->server->getLanguage()->translateString("pocketmine.disconnect.invalidSession", [$error])); return; } - $xuid = $packet->xuid; - - if(!$signedByMojang and $xuid !== ""){ - $this->server->getLogger()->warning($this->getName() . " has an XUID, but their login keychain is not signed by Mojang"); - $xuid = ""; - } - - if($xuid === "" or !is_string($xuid)){ - if($signedByMojang){ - $this->server->getLogger()->error($this->getName() . " should have an XUID, but none found"); - } + $this->authenticated = $authenticated; + if(!$this->authenticated){ if($this->server->requiresAuthentication() and $this->kick("disconnectionScreen.notAuthenticated", false)){ //use kick to allow plugins to cancel this return; } $this->server->getLogger()->debug($this->getName() . " is NOT logged into Xbox Live"); + if($this->xuid !== ""){ + $this->server->getLogger()->warning($this->getName() . " has an XUID, but their login keychain is not signed by Mojang"); + $this->xuid = ""; + } }else{ $this->server->getLogger()->debug($this->getName() . " is logged into Xbox Live"); - $this->xuid = $xuid; } //TODO: encryption diff --git a/src/pocketmine/network/mcpe/VerifyLoginTask.php b/src/pocketmine/network/mcpe/VerifyLoginTask.php index a509e35ef3..06cf93594e 100644 --- a/src/pocketmine/network/mcpe/VerifyLoginTask.php +++ b/src/pocketmine/network/mcpe/VerifyLoginTask.php @@ -148,7 +148,7 @@ class VerifyLoginTask extends AsyncTask{ if($player->isClosed()){ $server->getLogger()->error("Player " . $player->getName() . " was disconnected before their login could be verified"); }else{ - $player->onVerifyCompleted($this->packet, $this->error, $this->authenticated); + $player->onVerifyCompleted($this->authenticated, $this->error); } } } From 2647b3f40462338574eb01345330682783968752 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Jul 2018 18:33:10 +0100 Subject: [PATCH 0066/3224] VerifyLoginTask: remove unnecessary wordwrap() I don't recall why this was needed, but it's not. --- src/pocketmine/network/mcpe/VerifyLoginTask.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/VerifyLoginTask.php b/src/pocketmine/network/mcpe/VerifyLoginTask.php index 06cf93594e..c151fda0f0 100644 --- a/src/pocketmine/network/mcpe/VerifyLoginTask.php +++ b/src/pocketmine/network/mcpe/VerifyLoginTask.php @@ -119,7 +119,7 @@ class VerifyLoginTask extends AsyncTask{ //0x30 = Sequence ASN.1 tag $derSignature = "\x30" . chr(strlen($sequence)) . $sequence; - $v = openssl_verify("$headB64.$payloadB64", $derSignature, "-----BEGIN PUBLIC KEY-----\n" . wordwrap($currentPublicKey, 64, "\n", true) . "\n-----END PUBLIC KEY-----\n", OPENSSL_ALGO_SHA384); + $v = openssl_verify("$headB64.$payloadB64", $derSignature, "-----BEGIN PUBLIC KEY-----\n" . $currentPublicKey . "\n-----END PUBLIC KEY-----\n", OPENSSL_ALGO_SHA384); if($v !== 1){ throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.badSignature"); } From bdd42d6a783a3c38ffb4ab31cc13225b7dfb94e9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Jul 2018 18:39:14 +0100 Subject: [PATCH 0067/3224] Added NetworkSession->sendEncoded(), clean up some code --- src/pocketmine/Player.php | 2 +- src/pocketmine/Server.php | 2 +- src/pocketmine/network/mcpe/NetworkSession.php | 5 +++++ .../network/mcpe/handler/PreSpawnSessionHandler.php | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index eb52c3e654..1be619e4f8 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -908,7 +908,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->usedChunks[Level::chunkHash($x, $z)] = true; $this->chunkLoadCount++; - $this->networkSession->getInterface()->putPacket($this->networkSession, $payload); + $this->networkSession->sendEncoded($payload); if($this->spawned){ foreach($this->level->getChunkEntities($x, $z) as $entity){ diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 4ff4fe2605..5d562145c9 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1903,7 +1903,7 @@ class Server{ public function broadcastPacketsCallback(string $payload, array $sessions, bool $immediate = false){ /** @var NetworkSession $session */ foreach($sessions as $session){ - $session->getInterface()->putPacket($session, $payload, $immediate); + $session->sendEncoded($payload, $immediate); } } diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 7e409cca01..acad83e3e0 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -192,6 +192,11 @@ class NetworkSession{ } } + public function sendEncoded(string $payload, bool $immediate = false) : void{ + //TODO: encryption + $this->interface->putPacket($this, $payload, $immediate); + } + /** * Disconnects the session, destroying the associated player (if it exists). * diff --git a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php index 00d72b9917..f3edfe9872 100644 --- a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php @@ -86,7 +86,7 @@ class PreSpawnSessionHandler extends SessionHandler{ $this->player->sendAllInventories(); $this->player->getInventory()->sendCreativeContents(); $this->player->getInventory()->sendHeldItem($this->player); - $this->session->getInterface()->putPacket($this->session, $this->server->getCraftingManager()->getCraftingDataPacket()); + $this->session->sendEncoded($this->server->getCraftingManager()->getCraftingDataPacket()); $this->server->sendFullPlayerListData($this->player); } From d26631d8e0cc5b9d83408a4ef1e44c460548b80e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 30 Jul 2018 17:00:52 +0100 Subject: [PATCH 0068/3224] Clean up BaseLang error handling, throw exceptions instead --- src/pocketmine/Server.php | 15 ++++++- src/pocketmine/lang/BaseLang.php | 44 +++++++++++-------- .../lang/LanguageNotFoundException.php | 28 ++++++++++++ src/pocketmine/wizard/SetupWizard.php | 6 ++- 4 files changed, 71 insertions(+), 22 deletions(-) create mode 100644 src/pocketmine/lang/LanguageNotFoundException.php diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 5d562145c9..c6db4953e1 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -46,6 +46,7 @@ use pocketmine\item\enchantment\Enchantment; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\lang\BaseLang; +use pocketmine\lang\LanguageNotFoundException; use pocketmine\lang\TextContainer; use pocketmine\level\biome\Biome; use pocketmine\level\format\io\LevelProvider; @@ -1442,7 +1443,19 @@ class Server{ define('pocketmine\DEBUG', (int) $this->getProperty("debug.level", 1)); $this->forceLanguage = (bool) $this->getProperty("settings.force-language", false); - $this->baseLang = new BaseLang($this->getProperty("settings.language", BaseLang::FALLBACK_LANGUAGE)); + $selectedLang = $this->getProperty("settings.language", BaseLang::FALLBACK_LANGUAGE); + try{ + $this->baseLang = new BaseLang($selectedLang); + }catch(LanguageNotFoundException $e){ + $this->logger->error($e->getMessage()); + try{ + $this->baseLang = new BaseLang(BaseLang::FALLBACK_LANGUAGE); + }catch(LanguageNotFoundException $e){ + $this->logger->emergency("Fallback language \"" . BaseLang::FALLBACK_LANGUAGE . "\" not found"); + return; + } + } + $this->logger->info($this->getLanguage()->translateString("language.selected", [$this->getLanguage()->getName(), $this->getLanguage()->getLang()])); if(\pocketmine\IS_DEVELOPMENT_BUILD){ diff --git a/src/pocketmine/lang/BaseLang.php b/src/pocketmine/lang/BaseLang.php index e573a0f732..628e38951f 100644 --- a/src/pocketmine/lang/BaseLang.php +++ b/src/pocketmine/lang/BaseLang.php @@ -23,12 +23,16 @@ declare(strict_types=1); namespace pocketmine\lang; -use pocketmine\utils\MainLogger; - class BaseLang{ public const FALLBACK_LANGUAGE = "eng"; + /** + * @param string $path + * + * @return array + * @throws LanguageNotFoundException + */ public static function getLanguageList(string $path = "") : array{ if($path === ""){ $path = \pocketmine\PATH . "src/pocketmine/lang/locale/"; @@ -45,10 +49,10 @@ class BaseLang{ $result = []; foreach($files as $file){ - $strings = []; - self::loadLang($path . $file, $strings); + $code = explode(".", $file)[0]; + $strings = self::loadLang($path, $code); if(isset($strings["language.name"])){ - $result[substr($file, 0, -4)] = $strings["language.name"]; + $result[$code] = $strings["language.name"]; } } @@ -56,7 +60,7 @@ class BaseLang{ } } - return []; + throw new LanguageNotFoundException("Language directory $path does not exist or is not a directory"); } /** @var string */ @@ -67,20 +71,22 @@ class BaseLang{ /** @var string[] */ protected $fallbackLang = []; + /** + * @param string $lang + * @param string|null $path + * @param string $fallback + * + * @throws LanguageNotFoundException + */ public function __construct(string $lang, string $path = null, string $fallback = self::FALLBACK_LANGUAGE){ - $this->langName = strtolower($lang); if($path === null){ $path = \pocketmine\PATH . "src/pocketmine/lang/locale/"; } - if(!self::loadLang($file = $path . $this->langName . ".ini", $this->lang)){ - MainLogger::getLogger()->error("Missing required language file $file"); - } - if(!self::loadLang($file = $path . $fallback . ".ini", $this->fallbackLang)){ - MainLogger::getLogger()->error("Missing required language file $file"); - } + $this->lang = self::loadLang($path, $this->langName); + $this->fallbackLang = self::loadLang($path, $fallback); } public function getName() : string{ @@ -91,13 +97,13 @@ class BaseLang{ return $this->langName; } - protected static function loadLang(string $path, array &$d){ - if(file_exists($path)){ - $d = array_map('stripcslashes', parse_ini_file($path, false, INI_SCANNER_RAW)); - return true; - }else{ - return false; + protected static function loadLang(string $path, string $languageCode) : array{ + $file = $path . $languageCode . ".ini"; + if(file_exists($file)){ + return array_map('stripcslashes', parse_ini_file($file, false, INI_SCANNER_RAW)); } + + throw new LanguageNotFoundException("Language \"$languageCode\" not found"); } /** diff --git a/src/pocketmine/lang/LanguageNotFoundException.php b/src/pocketmine/lang/LanguageNotFoundException.php new file mode 100644 index 0000000000..8d8b39b5b2 --- /dev/null +++ b/src/pocketmine/lang/LanguageNotFoundException.php @@ -0,0 +1,28 @@ +message(\pocketmine\NAME . " set-up wizard"); - $langs = BaseLang::getLanguageList(); - if(empty($langs)){ + try{ + $langs = BaseLang::getLanguageList(); + }catch(LanguageNotFoundException $e){ $this->error("No language files found, please use provided builds or clone the repository recursively."); return false; } From 0d9952d53eb5b1210d834d0940c9ba5950b298a3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 30 Jul 2018 17:07:19 +0100 Subject: [PATCH 0069/3224] Rename BaseLang -> Language --- src/pocketmine/Server.php | 32 +++++++++---------- .../lang/{BaseLang.php => Language.php} | 2 +- src/pocketmine/wizard/SetupWizard.php | 8 ++--- 3 files changed, 21 insertions(+), 21 deletions(-) rename src/pocketmine/lang/{BaseLang.php => Language.php} (99%) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index c6db4953e1..d900c99cb9 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -45,7 +45,7 @@ use pocketmine\inventory\CraftingManager; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\lang\BaseLang; +use pocketmine\lang\Language; use pocketmine\lang\LanguageNotFoundException; use pocketmine\lang\TextContainer; use pocketmine\level\biome\Biome; @@ -243,8 +243,8 @@ class Server{ /** @var int */ private $autoSaveTicks = 6000; - /** @var BaseLang */ - private $baseLang; + /** @var Language */ + private $language; /** @var bool */ private $forceLanguage = false; @@ -1443,15 +1443,15 @@ class Server{ define('pocketmine\DEBUG', (int) $this->getProperty("debug.level", 1)); $this->forceLanguage = (bool) $this->getProperty("settings.force-language", false); - $selectedLang = $this->getProperty("settings.language", BaseLang::FALLBACK_LANGUAGE); + $selectedLang = $this->getProperty("settings.language", Language::FALLBACK_LANGUAGE); try{ - $this->baseLang = new BaseLang($selectedLang); + $this->language = new Language($selectedLang); }catch(LanguageNotFoundException $e){ $this->logger->error($e->getMessage()); try{ - $this->baseLang = new BaseLang(BaseLang::FALLBACK_LANGUAGE); + $this->language = new Language(Language::FALLBACK_LANGUAGE); }catch(LanguageNotFoundException $e){ - $this->logger->emergency("Fallback language \"" . BaseLang::FALLBACK_LANGUAGE . "\" not found"); + $this->logger->emergency("Fallback language \"" . Language::FALLBACK_LANGUAGE . "\" not found"); return; } } @@ -1460,19 +1460,19 @@ class Server{ if(\pocketmine\IS_DEVELOPMENT_BUILD){ if(!((bool) $this->getProperty("settings.enable-dev-builds", false))){ - $this->logger->emergency($this->baseLang->translateString("pocketmine.server.devBuild.error1", [\pocketmine\NAME])); - $this->logger->emergency($this->baseLang->translateString("pocketmine.server.devBuild.error2")); - $this->logger->emergency($this->baseLang->translateString("pocketmine.server.devBuild.error3")); - $this->logger->emergency($this->baseLang->translateString("pocketmine.server.devBuild.error4", ["settings.enable-dev-builds"])); + $this->logger->emergency($this->language->translateString("pocketmine.server.devBuild.error1", [\pocketmine\NAME])); + $this->logger->emergency($this->language->translateString("pocketmine.server.devBuild.error2")); + $this->logger->emergency($this->language->translateString("pocketmine.server.devBuild.error3")); + $this->logger->emergency($this->language->translateString("pocketmine.server.devBuild.error4", ["settings.enable-dev-builds"])); $this->forceShutdown(); return; } $this->logger->warning(str_repeat("-", 40)); - $this->logger->warning($this->baseLang->translateString("pocketmine.server.devBuild.warning1", [\pocketmine\NAME])); - $this->logger->warning($this->baseLang->translateString("pocketmine.server.devBuild.warning2")); - $this->logger->warning($this->baseLang->translateString("pocketmine.server.devBuild.warning3")); + $this->logger->warning($this->language->translateString("pocketmine.server.devBuild.warning1", [\pocketmine\NAME])); + $this->logger->warning($this->language->translateString("pocketmine.server.devBuild.warning2")); + $this->logger->warning($this->language->translateString("pocketmine.server.devBuild.warning3")); $this->logger->warning(str_repeat("-", 40)); } @@ -2430,10 +2430,10 @@ class Server{ /** - * @return BaseLang + * @return Language */ public function getLanguage(){ - return $this->baseLang; + return $this->language; } /** diff --git a/src/pocketmine/lang/BaseLang.php b/src/pocketmine/lang/Language.php similarity index 99% rename from src/pocketmine/lang/BaseLang.php rename to src/pocketmine/lang/Language.php index 628e38951f..f3a2643235 100644 --- a/src/pocketmine/lang/BaseLang.php +++ b/src/pocketmine/lang/Language.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\lang; -class BaseLang{ +class Language{ public const FALLBACK_LANGUAGE = "eng"; diff --git a/src/pocketmine/wizard/SetupWizard.php b/src/pocketmine/wizard/SetupWizard.php index 31567b5388..24930cfed7 100644 --- a/src/pocketmine/wizard/SetupWizard.php +++ b/src/pocketmine/wizard/SetupWizard.php @@ -27,7 +27,7 @@ declare(strict_types=1); */ namespace pocketmine\wizard; -use pocketmine\lang\BaseLang; +use pocketmine\lang\Language; use pocketmine\lang\LanguageNotFoundException; use pocketmine\utils\Config; use pocketmine\utils\Internet; @@ -38,7 +38,7 @@ class SetupWizard{ public const DEFAULT_PLAYERS = 20; public const DEFAULT_GAMEMODE = 0; - /** @var BaseLang */ + /** @var Language */ private $lang; public function __construct(){ @@ -49,7 +49,7 @@ class SetupWizard{ $this->message(\pocketmine\NAME . " set-up wizard"); try{ - $langs = BaseLang::getLanguageList(); + $langs = Language::getLanguageList(); }catch(LanguageNotFoundException $e){ $this->error("No language files found, please use provided builds or clone the repository recursively."); return false; @@ -68,7 +68,7 @@ class SetupWizard{ } }while($lang === null); - $this->lang = new BaseLang($lang); + $this->lang = new Language($lang); $this->message($this->lang->get("language_has_been_selected")); From 58b46179f94e62acadbfd1e3ddb0f7d4eec2b2d2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 30 Jul 2018 17:27:48 +0100 Subject: [PATCH 0070/3224] Language: make internal function not public this is only used within the Language class anyway. --- src/pocketmine/lang/Language.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/lang/Language.php b/src/pocketmine/lang/Language.php index f3a2643235..aebaba599f 100644 --- a/src/pocketmine/lang/Language.php +++ b/src/pocketmine/lang/Language.php @@ -144,7 +144,7 @@ class Language{ * * @return string|null */ - public function internalGet(string $id){ + protected function internalGet(string $id){ if(isset($this->lang[$id])){ return $this->lang[$id]; }elseif(isset($this->fallbackLang[$id])){ From 4e8a256a536205561c8073bb8059e21a524d1360 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 30 Jul 2018 17:29:13 +0100 Subject: [PATCH 0071/3224] Language: use null coalesce for get() and internalGet() --- src/pocketmine/lang/Language.php | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/pocketmine/lang/Language.php b/src/pocketmine/lang/Language.php index aebaba599f..cdcd02905b 100644 --- a/src/pocketmine/lang/Language.php +++ b/src/pocketmine/lang/Language.php @@ -145,13 +145,7 @@ class Language{ * @return string|null */ protected function internalGet(string $id){ - if(isset($this->lang[$id])){ - return $this->lang[$id]; - }elseif(isset($this->fallbackLang[$id])){ - return $this->fallbackLang[$id]; - } - - return null; + return $this->lang[$id] ?? $this->fallbackLang[$id] ?? null; } /** @@ -160,13 +154,7 @@ class Language{ * @return string */ public function get(string $id) : string{ - if(isset($this->lang[$id])){ - return $this->lang[$id]; - }elseif(isset($this->fallbackLang[$id])){ - return $this->fallbackLang[$id]; - } - - return $id; + return $this->internalGet($id) ?? $id; } /** From 62cb7963dcd4a8f1adbb2ee99bad565523404b59 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 31 Jul 2018 14:37:54 +0100 Subject: [PATCH 0072/3224] Remove deprecated functions for 4.0.0 If any moron starts complaining that their plugins broke, tell them to use 3.x... thanks --- src/pocketmine/plugin/PluginManager.php | 136 ------------------------ src/pocketmine/utils/Utils.php | 65 ----------- 2 files changed, 201 deletions(-) diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index fae48e193a..357f53c8ec 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -32,8 +32,6 @@ use pocketmine\event\Listener; use pocketmine\event\plugin\PluginDisableEvent; use pocketmine\event\plugin\PluginEnableEvent; use pocketmine\network\mcpe\protocol\ProtocolInfo; -use pocketmine\permission\Permissible; -use pocketmine\permission\Permission; use pocketmine\permission\PermissionManager; use pocketmine\Server; use pocketmine\timings\TimingsHandler; @@ -396,140 +394,6 @@ class PluginManager{ return false; } - /** - * @deprecated - * @see PermissionManager::getPermission() - * - * @param string $name - * - * @return null|Permission - */ - public function getPermission(string $name){ - return PermissionManager::getInstance()->getPermission($name); - } - - /** - * @deprecated - * @see PermissionManager::addPermission() - * - * @param Permission $permission - * - * @return bool - */ - public function addPermission(Permission $permission) : bool{ - return PermissionManager::getInstance()->addPermission($permission); - } - - /** - * @deprecated - * @see PermissionManager::removePermission() - * - * @param string|Permission $permission - */ - public function removePermission($permission){ - PermissionManager::getInstance()->removePermission($permission); - } - - /** - * @deprecated - * @see PermissionManager::getDefaultPermissions() - * - * @param bool $op - * - * @return Permission[] - */ - public function getDefaultPermissions(bool $op) : array{ - return PermissionManager::getInstance()->getDefaultPermissions($op); - } - - /** - * @deprecated - * @see PermissionManager::recalculatePermissionDefaults() - * - * @param Permission $permission - */ - public function recalculatePermissionDefaults(Permission $permission){ - PermissionManager::getInstance()->recalculatePermissionDefaults($permission); - } - - /** - * @deprecated - * @see PermissionManager::subscribeToPermission() - * - * @param string $permission - * @param Permissible $permissible - */ - public function subscribeToPermission(string $permission, Permissible $permissible){ - PermissionManager::getInstance()->subscribeToPermission($permission, $permissible); - } - - /** - * @deprecated - * @see PermissionManager::unsubscribeFromPermission() - * - * @param string $permission - * @param Permissible $permissible - */ - public function unsubscribeFromPermission(string $permission, Permissible $permissible){ - PermissionManager::getInstance()->unsubscribeFromPermission($permission, $permissible); - } - - /** - * @deprecated - * @see PermissionManager::getPermissionSubscriptions() - * - * @param string $permission - * - * @return array|Permissible[] - */ - public function getPermissionSubscriptions(string $permission) : array{ - return PermissionManager::getInstance()->getPermissionSubscriptions($permission); - } - - /** - * @deprecated - * @see PermissionManager::subscribeToDefaultPerms() - * - * @param bool $op - * @param Permissible $permissible - */ - public function subscribeToDefaultPerms(bool $op, Permissible $permissible){ - PermissionManager::getInstance()->subscribeToDefaultPerms($op, $permissible); - } - - /** - * @deprecated - * @see PermissionManager::unsubscribeFromDefaultPerms() - * - * @param bool $op - * @param Permissible $permissible - */ - public function unsubscribeFromDefaultPerms(bool $op, Permissible $permissible){ - PermissionManager::getInstance()->unsubscribeFromDefaultPerms($op, $permissible); - } - - /** - * @deprecated - * @see PermissionManager::getDefaultPermSubscriptions() - * - * @param bool $op - * - * @return Permissible[] - */ - public function getDefaultPermSubscriptions(bool $op) : array{ - return PermissionManager::getInstance()->getDefaultPermSubscriptions($op); - } - - /** - * @deprecated - * @see PermissionManager::getPermissions() - * - * @return Permission[] - */ - public function getPermissions() : array{ - return PermissionManager::getInstance()->getPermissions(); - } - /** * @param Plugin $plugin * diff --git a/src/pocketmine/utils/Utils.php b/src/pocketmine/utils/Utils.php index 08552626a2..3459ade898 100644 --- a/src/pocketmine/utils/Utils.php +++ b/src/pocketmine/utils/Utils.php @@ -120,18 +120,6 @@ class Utils{ return $uuid; } - /** - * @deprecated - * @see Internet::getIP() - * - * @param bool $force default false, force IP check even when cached - * - * @return string|bool - */ - public static function getIP(bool $force = false){ - return Internet::getIP($force); - } - /** * Returns the current Operating System * Windows => win @@ -330,59 +318,6 @@ class Utils{ return array("yaw" => $hAngle, "pitch" => $vAngle); }*/ - /** - * @deprecated - * @see Internet::getURL() - * - * @param string $page - * @param int $timeout default 10 - * @param array $extraHeaders - * @param string &$err Will be set to the output of curl_error(). Use this to retrieve errors that occured during the operation. - * @param array[] &$headers - * @param int &$httpCode - * - * @return bool|mixed false if an error occurred, mixed data if successful. - */ - public static function getURL(string $page, int $timeout = 10, array $extraHeaders = [], &$err = null, &$headers = null, &$httpCode = null){ - return Internet::getURL($page, $timeout, $extraHeaders, $err, $headers, $httpCode); - } - - /** - * @deprecated - * @see Internet::postURL() - * - * @param string $page - * @param array|string $args - * @param int $timeout - * @param array $extraHeaders - * @param string &$err Will be set to the output of curl_error(). Use this to retrieve errors that occured during the operation. - * @param array[] &$headers - * @param int &$httpCode - * - * @return bool|mixed false if an error occurred, mixed data if successful. - */ - public static function postURL(string $page, $args, int $timeout = 10, array $extraHeaders = [], &$err = null, &$headers = null, &$httpCode = null){ - return Internet::postURL($page, $args, $timeout, $extraHeaders, $err, $headers, $httpCode); - } - - /** - * @deprecated - * @see Internet::simpleCurl() - * - * @param string $page - * @param float|int $timeout The maximum connect timeout and timeout in seconds, correct to ms. - * @param string[] $extraHeaders extra headers to send as a plain string array - * @param array $extraOpts extra CURLOPT_* to set as an [opt => value] map - * @param callable|null $onSuccess function to be called if there is no error. Accepts a resource argument as the cURL handle. - * - * @return array a plain array of three [result body : string, headers : array[], HTTP response code : int]. Headers are grouped by requests with strtolower(header name) as keys and header value as values - * - * @throws \RuntimeException if a cURL error occurs - */ - public static function simpleCurl(string $page, $timeout = 10, array $extraHeaders = [], array $extraOpts = [], callable $onSuccess = null){ - return Internet::simpleCurl($page, $timeout, $extraHeaders, $extraOpts, $onSuccess); - } - public static function javaStringHash(string $string) : int{ $hash = 0; for($i = 0, $len = strlen($string); $i < $len; $i++){ From 2bf676411247c35ae89c3070b7dee449939c2bd4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 31 Jul 2018 15:54:18 +0100 Subject: [PATCH 0073/3224] Implemented network encryption (#2343) For those who fuss about performance, you can disable the `network.enable-encryption` option to use sessions without encryption. --- .travis.yml | 1 + composer.json | 3 + composer.lock | 145 ++++++++++- src/pocketmine/Player.php | 25 +- src/pocketmine/PocketMine.php | 2 + src/pocketmine/Server.php | 3 + src/pocketmine/network/mcpe/NetworkCipher.php | 83 +++++++ .../network/mcpe/NetworkSession.php | 34 ++- .../network/mcpe/ProcessLoginTask.php | 229 ++++++++++++++++++ .../network/mcpe/VerifyLoginTask.php | 154 ------------ .../mcpe/handler/HandshakeSessionHandler.php | 45 ++++ .../mcpe/handler/SimpleSessionHandler.php | 5 - src/pocketmine/resources/pocketmine.yml | 3 + 13 files changed, 556 insertions(+), 176 deletions(-) create mode 100644 src/pocketmine/network/mcpe/NetworkCipher.php create mode 100644 src/pocketmine/network/mcpe/ProcessLoginTask.php delete mode 100644 src/pocketmine/network/mcpe/VerifyLoginTask.php create mode 100644 src/pocketmine/network/mcpe/handler/HandshakeSessionHandler.php diff --git a/.travis.yml b/.travis.yml index 4196f2c2e6..c4b30098e1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ php: before_script: # - pecl install channel://pecl.php.net/pthreads-3.1.6 - echo | pecl install channel://pecl.php.net/yaml-2.0.2 + - pecl install channel://pecl.php.net/crypto-0.3.1 - git clone https://github.com/pmmp/pthreads.git - cd pthreads - git checkout c8cfacda84f21032d6014b53e72bf345ac901dac diff --git a/composer.json b/composer.json index 205b60ee87..f4aa2af785 100644 --- a/composer.json +++ b/composer.json @@ -9,8 +9,10 @@ "php-64bit": "*", "ext-bcmath": "*", "ext-curl": "*", + "ext-crypto": "^0.3.1", "ext-ctype": "*", "ext-date": "*", + "ext-gmp": "*", "ext-hash": "*", "ext-json": "*", "ext-mbstring": "*", @@ -24,6 +26,7 @@ "ext-yaml": ">=2.0.0", "ext-zip": "*", "ext-zlib": ">=1.2.11", + "mdanter/ecc": "^0.5.0", "pocketmine/raklib": "^0.12.0", "pocketmine/spl": "^0.3.0", "pocketmine/binaryutils": "^0.1.0", diff --git a/composer.lock b/composer.lock index 4809e8a227..70f70ee978 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,149 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2670b9e2a730ff758909be8b9e9d609a", + "content-hash": "85fe0f9aca77848b0f753dbc28815c79", "packages": [ + { + "name": "fgrosse/phpasn1", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/fgrosse/PHPASN1.git", + "reference": "0e27e71e3d0a8d5c3f1471d727fd9574d920f33c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/0e27e71e3d0a8d5c3f1471d727fd9574d920f33c", + "reference": "0e27e71e3d0a8d5c3f1471d727fd9574d920f33c", + "shasum": "" + }, + "require": { + "ext-gmp": "*", + "php": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~6.3", + "satooshi/php-coveralls": "dev-master" + }, + "suggest": { + "php-curl": "For loading OID information from the web if they have not bee defined statically" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "FG\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Friedrich Große", + "email": "friedrich.grosse@gmail.com", + "homepage": "https://github.com/FGrosse", + "role": "Author" + }, + { + "name": "All contributors", + "homepage": "https://github.com/FGrosse/PHPASN1/contributors" + } + ], + "description": "A PHP Framework that allows you to encode and decode arbitrary ASN.1 structures using the ITU-T X.690 Encoding Rules.", + "homepage": "https://github.com/FGrosse/PHPASN1", + "keywords": [ + "DER", + "asn.1", + "asn1", + "ber", + "binary", + "decoding", + "encoding", + "x.509", + "x.690", + "x509", + "x690" + ], + "time": "2017-12-17T10:21:51+00:00" + }, + { + "name": "mdanter/ecc", + "version": "v0.5.0", + "source": { + "type": "git", + "url": "https://github.com/phpecc/phpecc.git", + "reference": "ed5c6d496f5310de1b7071b8375fafa3559a1344" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpecc/phpecc/zipball/ed5c6d496f5310de1b7071b8375fafa3559a1344", + "reference": "ed5c6d496f5310de1b7071b8375fafa3559a1344", + "shasum": "" + }, + "require": { + "ext-gmp": "*", + "fgrosse/phpasn1": "v2.0.x", + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0", + "squizlabs/php_codesniffer": "~2", + "symfony/yaml": "~2.6|~3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Mdanter\\Ecc\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matyas Danter", + "homepage": "http://matejdanter.com/", + "role": "Author" + }, + { + "name": "Thibaud Fabre", + "email": "thibaud@aztech.io", + "homepage": "http://aztech.io", + "role": "Maintainer" + }, + { + "name": "Thomas Kerin", + "email": "afk11@users.noreply.github.com", + "role": "Maintainer" + } + ], + "description": "PHP Elliptic Curve Cryptography library", + "homepage": "https://github.com/phpecc/phpecc", + "keywords": [ + "Diffie", + "ECDSA", + "Hellman", + "curve", + "ecdh", + "elliptic", + "nistp192", + "nistp224", + "nistp256", + "nistp384", + "nistp521", + "phpecc", + "secp256k1", + "secp256r1" + ], + "time": "2017-10-09T16:05:37+00:00" + }, { "name": "pocketmine/binaryutils", "version": "0.1.0", @@ -235,8 +376,10 @@ "php-64bit": "*", "ext-bcmath": "*", "ext-curl": "*", + "ext-crypto": "^0.3.1", "ext-ctype": "*", "ext-date": "*", + "ext-gmp": "*", "ext-hash": "*", "ext-json": "*", "ext-mbstring": "*", diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 1be619e4f8..ff3ee37a74 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -124,7 +124,7 @@ use pocketmine\network\mcpe\protocol\types\ContainerIds; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; -use pocketmine\network\mcpe\VerifyLoginTask; +use pocketmine\network\mcpe\ProcessLoginTask; use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissionAttachment; use pocketmine\permission\PermissionAttachmentInfo; @@ -1795,17 +1795,18 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } if(!$packet->skipVerification){ - $this->server->getAsyncPool()->submitTask(new VerifyLoginTask($this, $packet)); + $this->server->getAsyncPool()->submitTask(new ProcessLoginTask($this, $packet)); }else{ - $this->onVerifyCompleted(true, null); + $this->setAuthenticationStatus(true, null); + $this->networkSession->onLoginSuccess(); } return true; } - public function onVerifyCompleted(bool $authenticated, ?string $error) : void{ + public function setAuthenticationStatus(bool $authenticated, ?string $error) : bool{ if($this->closed){ - return; + return false; } if($authenticated and $this->xuid === ""){ @@ -1814,14 +1815,15 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ if($error !== null){ $this->close("", $this->server->getLanguage()->translateString("pocketmine.disconnect.invalidSession", [$error])); - return; + + return false; } $this->authenticated = $authenticated; if(!$this->authenticated){ if($this->server->requiresAuthentication() and $this->kick("disconnectionScreen.notAuthenticated", false)){ //use kick to allow plugins to cancel this - return; + return false; } $this->server->getLogger()->debug($this->getName() . " is NOT logged into Xbox Live"); @@ -1833,21 +1835,22 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->server->getLogger()->debug($this->getName() . " is logged into Xbox Live"); } - //TODO: encryption - foreach($this->server->getLoggedInPlayers() as $p){ if($p !== $this and ($p->iusername === $this->iusername or $this->getUniqueId()->equals($p->getUniqueId()))){ if(!$p->kick("logged in from another location")){ $this->close($this->getLeaveMessage(), "Logged in from another location"); - return; + return false; } } } + return true; + } + + public function onLoginSuccess() : void{ $this->loggedIn = true; $this->server->onPlayerLogin($this); - $this->networkSession->onLoginSuccess(); } public function _actuallyConstruct(){ diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index 0afd772f6f..dd99a3fa16 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -77,8 +77,10 @@ namespace pocketmine { $extensions = [ "bcmath" => "BC Math", "curl" => "cURL", + "crypto" => "php-crypto", "ctype" => "ctype", "date" => "Date", + "gmp" => "GMP", "hash" => "Hash", "json" => "JSON", "mbstring" => "Multibyte String", diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index d900c99cb9..17c2309c63 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -71,6 +71,7 @@ use pocketmine\nbt\tag\ShortTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\mcpe\CompressBatchedTask; +use pocketmine\network\mcpe\NetworkCipher; use pocketmine\network\mcpe\NetworkCompression; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\PacketStream; @@ -1544,6 +1545,8 @@ class Server{ } $this->networkCompressionAsync = (bool) $this->getProperty("network.async-compression", true); + NetworkCipher::$ENABLED = (bool) $this->getProperty("network.enable-encryption", true); + $this->autoTickRate = (bool) $this->getProperty("level-settings.auto-tick-rate", true); $this->autoTickRateLimit = (int) $this->getProperty("level-settings.auto-tick-rate-limit", 20); $this->alwaysTickPlayers = (bool) $this->getProperty("level-settings.always-tick-players", false); diff --git a/src/pocketmine/network/mcpe/NetworkCipher.php b/src/pocketmine/network/mcpe/NetworkCipher.php new file mode 100644 index 0000000000..eb4c5f1aa9 --- /dev/null +++ b/src/pocketmine/network/mcpe/NetworkCipher.php @@ -0,0 +1,83 @@ +key = $encryptionKey; + $iv = substr($this->key, 0, 16); + + $this->decryptCipher = new Cipher(self::ENCRYPTION_SCHEME); + $this->decryptCipher->decryptInit($this->key, $iv); + + $this->encryptCipher = new Cipher(self::ENCRYPTION_SCHEME); + $this->encryptCipher->encryptInit($this->key, $iv); + } + + public function decrypt($encrypted){ + if(strlen($encrypted) < 9){ + throw new \InvalidArgumentException("Payload is too short"); + } + $decrypted = $this->decryptCipher->decryptUpdate($encrypted); + $payload = substr($decrypted, 0, -8); + + if(($expected = $this->calculateChecksum($this->decryptCounter++, $payload)) !== ($actual = substr($decrypted, -8))){ + throw new \InvalidArgumentException("Encrypted payload has invalid checksum (expected " . bin2hex($expected) . ", got " . bin2hex($actual) . ")"); + } + + return $payload; + } + + public function encrypt(string $payload) : string{ + return $this->encryptCipher->encryptUpdate($payload . $this->calculateChecksum($this->encryptCounter++, $payload)); + } + + private function calculateChecksum(int $counter, string $payload) : string{ + return substr(hash(self::CHECKSUM_ALGO, Binary::writeLLong($counter) . $payload . $this->key, true), 0, 8); + } +} diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index acad83e3e0..993749b299 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -27,6 +27,7 @@ use pocketmine\event\player\PlayerCreationEvent; use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\event\server\DataPacketSendEvent; use pocketmine\network\mcpe\handler\DeathSessionHandler; +use pocketmine\network\mcpe\handler\HandshakeSessionHandler; use pocketmine\network\mcpe\handler\LoginSessionHandler; use pocketmine\network\mcpe\handler\PreSpawnSessionHandler; use pocketmine\network\mcpe\handler\ResourcePacksSessionHandler; @@ -36,14 +37,13 @@ use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\DisconnectPacket; use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\network\mcpe\protocol\PlayStatusPacket; +use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket; use pocketmine\network\NetworkInterface; use pocketmine\Player; use pocketmine\Server; use pocketmine\timings\Timings; class NetworkSession{ - - /** @var Server */ private $server; /** @var Player */ @@ -63,6 +63,9 @@ class NetworkSession{ /** @var bool */ private $connected = true; + /** @var NetworkCipher */ + private $cipher; + public function __construct(Server $server, NetworkInterface $interface, string $ip, int $port){ $this->server = $server; $this->interface = $interface; @@ -142,7 +145,15 @@ class NetworkSession{ return; } - //TODO: decryption if enabled + if($this->cipher !== null){ + try{ + $payload = $this->cipher->decrypt($payload); + }catch(\InvalidArgumentException $e){ + $this->server->getLogger()->debug("Encrypted packet from " . $this->ip . " " . $this->port . ": " . bin2hex($payload)); + $this->disconnect("Packet decryption error: " . $e->getMessage()); + return; + } + } try{ $stream = new PacketStream(NetworkCompression::decompress($payload)); @@ -151,6 +162,7 @@ class NetworkSession{ $this->disconnect("Compressed packet batch decode error (incompatible game version?)", false); return; } + while(!$stream->feof() and $this->connected){ $this->handleDataPacket(PacketPool::getPacket($stream->getString())); } @@ -193,7 +205,9 @@ class NetworkSession{ } public function sendEncoded(string $payload, bool $immediate = false) : void{ - //TODO: encryption + if($this->cipher !== null){ + $payload = $this->cipher->encrypt($payload); + } $this->interface->putPacket($this, $payload, $immediate); } @@ -262,13 +276,23 @@ class NetworkSession{ $this->player = null; } - //TODO: onEnableEncryption() step + public function enableEncryption(string $encryptionKey, string $handshakeJwt) : void{ + $pk = new ServerToClientHandshakePacket(); + $pk->jwt = $handshakeJwt; + $this->sendDataPacket($pk, true); //make sure this gets sent before encryption is enabled + + $this->cipher = new NetworkCipher($encryptionKey); + + $this->setHandler(new HandshakeSessionHandler($this)); + $this->server->getLogger()->debug("Enabled encryption for $this->ip $this->port"); + } public function onLoginSuccess() : void{ $pk = new PlayStatusPacket(); $pk->status = PlayStatusPacket::LOGIN_SUCCESS; $this->sendDataPacket($pk); + $this->player->onLoginSuccess(); $this->setHandler(new ResourcePacksSessionHandler($this->player, $this, $this->server->getResourcePackManager())); } diff --git a/src/pocketmine/network/mcpe/ProcessLoginTask.php b/src/pocketmine/network/mcpe/ProcessLoginTask.php new file mode 100644 index 0000000000..75f19cb819 --- /dev/null +++ b/src/pocketmine/network/mcpe/ProcessLoginTask.php @@ -0,0 +1,229 @@ +storeLocal($player); + $this->packet = $packet; + $this->useEncryption = $useEncryption; + if($useEncryption){ + if(self::$SERVER_PRIVATE_KEY === null){ + self::$SERVER_PRIVATE_KEY = EccFactory::getNistCurves()->generator384()->createPrivateKey(); + } + + $this->serverPrivateKey = self::$SERVER_PRIVATE_KEY; + } + } + + public function onRun() : void{ + try{ + $clientPub = $this->validateChain(); + }catch(VerifyLoginException $e){ + $this->error = $e->getMessage(); + return; + } + + if($this->useEncryption){ + $serverPriv = $this->serverPrivateKey; + $salt = random_bytes(16); + $sharedSecret = $serverPriv->createExchange($clientPub)->calculateSharedKey(); + + $this->aesKey = hash('sha256', $salt . hex2bin(str_pad(gmp_strval($sharedSecret, 16), 96, "0", STR_PAD_LEFT)), true); + $this->handshakeJwt = $this->generateServerHandshakeJwt($serverPriv, $salt); + } + + $this->error = null; + } + + private function validateChain() : PublicKeyInterface{ + $packet = $this->packet; + + $currentKey = null; + $first = true; + + foreach($packet->chainData["chain"] as $jwt){ + $this->validateToken($jwt, $currentKey, $first); + if($first){ + $first = false; + } + } + + /** @var string $clientKey */ + $clientKey = $currentKey; + + $this->validateToken($packet->clientDataJwt, $currentKey); + + return (new DerPublicKeySerializer())->parse(base64_decode($clientKey, true)); + } + + /** + * @param string $jwt + * @param null|string $currentPublicKey + * @param bool $first + * + * @throws VerifyLoginException if errors are encountered + */ + private function validateToken(string $jwt, ?string &$currentPublicKey, bool $first = false) : void{ + [$headB64, $payloadB64, $sigB64] = explode('.', $jwt); + + if($currentPublicKey === null){ + if(!$first){ + throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.missingKey"); + } + + //First link, check that it is self-signed + $headers = json_decode(self::b64UrlDecode($headB64), true); + $currentPublicKey = $headers["x5u"]; + } + + $plainSignature = self::b64UrlDecode($sigB64); + assert(strlen($plainSignature) === 96); + [$rString, $sString] = str_split($plainSignature, 48); + $sig = new Signature(gmp_init(bin2hex($rString), 16), gmp_init(bin2hex($sString), 16)); + + $derSerializer = new DerPublicKeySerializer(); + $v = openssl_verify( + "$headB64.$payloadB64", + (new DerSignatureSerializer())->serialize($sig), + (new PemPublicKeySerializer($derSerializer))->serialize($derSerializer->parse(base64_decode($currentPublicKey))), + OPENSSL_ALGO_SHA384 + ); + + if($v !== 1){ + throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.badSignature"); + } + + if($currentPublicKey === self::MOJANG_ROOT_PUBLIC_KEY){ + $this->authenticated = true; //we're signed into xbox live + } + + $claims = json_decode(self::b64UrlDecode($payloadB64), true); + + $time = time(); + if(isset($claims["nbf"]) and $claims["nbf"] > $time){ + throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.tooEarly"); + } + + if(isset($claims["exp"]) and $claims["exp"] < $time){ + throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.tooLate"); + } + + $currentPublicKey = $claims["identityPublicKey"] ?? null; //if there are further links, the next link should be signed with this + } + + private function generateServerHandshakeJwt(PrivateKeyInterface $serverPriv, string $salt) : string{ + $jwtBody = self::b64UrlEncode(json_encode([ + "x5u" => base64_encode((new DerPublicKeySerializer())->serialize($serverPriv->getPublicKey())), + "alg" => "ES384" + ]) + ) . "." . self::b64UrlEncode(json_encode([ + "salt" => base64_encode($salt) + ]) + ); + + openssl_sign($jwtBody, $sig, (new PemPrivateKeySerializer(new DerPrivateKeySerializer()))->serialize($serverPriv), OPENSSL_ALGO_SHA384); + + $decodedSig = (new DerSignatureSerializer())->parse($sig); + $jwtSig = self::b64UrlEncode( + hex2bin(str_pad(gmp_strval($decodedSig->getR(), 16), 96, "0", STR_PAD_LEFT)) . + hex2bin(str_pad(gmp_strval($decodedSig->getS(), 16), 96, "0", STR_PAD_LEFT)) + ); + + return "$jwtBody.$jwtSig"; + } + + private static function b64UrlDecode(string $str) : string{ + return base64_decode(strtr($str, '-_', '+/'), true); + } + + private static function b64UrlEncode(string $str) : string{ + return strtr(base64_encode($str), '+/', '-_'); + } + + public function onCompletion(Server $server) : void{ + /** @var Player $player */ + $player = $this->fetchLocal(); + if($player->isClosed()){ + $server->getLogger()->error("Player " . $player->getName() . " was disconnected before their login could be verified"); + }elseif($player->setAuthenticationStatus($this->authenticated, $this->error)){ + if(!$this->useEncryption){ + $player->getNetworkSession()->onLoginSuccess(); + }else{ + $player->getNetworkSession()->enableEncryption($this->aesKey, $this->handshakeJwt); + } + } + } +} diff --git a/src/pocketmine/network/mcpe/VerifyLoginTask.php b/src/pocketmine/network/mcpe/VerifyLoginTask.php deleted file mode 100644 index c151fda0f0..0000000000 --- a/src/pocketmine/network/mcpe/VerifyLoginTask.php +++ /dev/null @@ -1,154 +0,0 @@ -storeLocal($player); - $this->packet = $packet; - } - - public function onRun() : void{ - $packet = $this->packet; //Get it in a local variable to make sure it stays unserialized - - try{ - $currentKey = null; - $first = true; - - foreach($packet->chainData["chain"] as $jwt){ - $this->validateToken($jwt, $currentKey, $first); - $first = false; - } - - $this->validateToken($packet->clientDataJwt, $currentKey); - - $this->error = null; - }catch(VerifyLoginException $e){ - $this->error = $e->getMessage(); - } - } - - /** - * @param string $jwt - * @param null|string $currentPublicKey - * @param bool $first - * - * @throws VerifyLoginException if errors are encountered - */ - private function validateToken(string $jwt, ?string &$currentPublicKey, bool $first = false) : void{ - [$headB64, $payloadB64, $sigB64] = explode('.', $jwt); - - $headers = json_decode(base64_decode(strtr($headB64, '-_', '+/'), true), true); - - if($currentPublicKey === null){ - if(!$first){ - throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.missingKey"); - } - - //First link, check that it is self-signed - $currentPublicKey = $headers["x5u"]; - } - - $plainSignature = base64_decode(strtr($sigB64, '-_', '+/'), true); - - //OpenSSL wants a DER-encoded signature, so we extract R and S from the plain signature and crudely serialize it. - - assert(strlen($plainSignature) === 96); - - [$rString, $sString] = str_split($plainSignature, 48); - - $rString = ltrim($rString, "\x00"); - if(ord($rString{0}) >= 128){ //Would be considered signed, pad it with an extra zero - $rString = "\x00" . $rString; - } - - $sString = ltrim($sString, "\x00"); - if(ord($sString{0}) >= 128){ //Would be considered signed, pad it with an extra zero - $sString = "\x00" . $sString; - } - - //0x02 = Integer ASN.1 tag - $sequence = "\x02" . chr(strlen($rString)) . $rString . "\x02" . chr(strlen($sString)) . $sString; - //0x30 = Sequence ASN.1 tag - $derSignature = "\x30" . chr(strlen($sequence)) . $sequence; - - $v = openssl_verify("$headB64.$payloadB64", $derSignature, "-----BEGIN PUBLIC KEY-----\n" . $currentPublicKey . "\n-----END PUBLIC KEY-----\n", OPENSSL_ALGO_SHA384); - if($v !== 1){ - throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.badSignature"); - } - - if($currentPublicKey === self::MOJANG_ROOT_PUBLIC_KEY){ - $this->authenticated = true; //we're signed into xbox live - } - - $claims = json_decode(base64_decode(strtr($payloadB64, '-_', '+/'), true), true); - - $time = time(); - if(isset($claims["nbf"]) and $claims["nbf"] > $time){ - throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.tooEarly"); - } - - if(isset($claims["exp"]) and $claims["exp"] < $time){ - throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.tooLate"); - } - - $currentPublicKey = $claims["identityPublicKey"] ?? null; //if there are further links, the next link should be signed with this - } - - public function onCompletion(Server $server) : void{ - /** @var Player $player */ - $player = $this->fetchLocal(); - if($player->isClosed()){ - $server->getLogger()->error("Player " . $player->getName() . " was disconnected before their login could be verified"); - }else{ - $player->onVerifyCompleted($this->authenticated, $this->error); - } - } -} diff --git a/src/pocketmine/network/mcpe/handler/HandshakeSessionHandler.php b/src/pocketmine/network/mcpe/handler/HandshakeSessionHandler.php new file mode 100644 index 0000000000..50a39557b4 --- /dev/null +++ b/src/pocketmine/network/mcpe/handler/HandshakeSessionHandler.php @@ -0,0 +1,45 @@ +session = $session; + } + + public function handleClientToServerHandshake(ClientToServerHandshakePacket $packet) : bool{ + $this->session->onLoginSuccess(); + return true; + } +} diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index ca080fd29c..a30f247a98 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -30,7 +30,6 @@ use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\network\mcpe\protocol\BlockPickRequestPacket; use pocketmine\network\mcpe\protocol\BookEditPacket; use pocketmine\network\mcpe\protocol\BossEventPacket; -use pocketmine\network\mcpe\protocol\ClientToServerHandshakePacket; use pocketmine\network\mcpe\protocol\CommandBlockUpdatePacket; use pocketmine\network\mcpe\protocol\CommandRequestPacket; use pocketmine\network\mcpe\protocol\ContainerClosePacket; @@ -75,10 +74,6 @@ class SimpleSessionHandler extends SessionHandler{ $this->player = $player; } - public function handleClientToServerHandshake(ClientToServerHandshakePacket $packet) : bool{ - return false; //TODO - } - public function handleText(TextPacket $packet) : bool{ if($packet->type === TextPacket::TYPE_CHAT){ return $this->player->chat($packet->message); diff --git a/src/pocketmine/resources/pocketmine.yml b/src/pocketmine/resources/pocketmine.yml index 739f5194d9..efb943c2d8 100644 --- a/src/pocketmine/resources/pocketmine.yml +++ b/src/pocketmine/resources/pocketmine.yml @@ -97,6 +97,9 @@ network: #Maximum size in bytes of packets sent over the network (default 1492 bytes). Packets larger than this will be #fragmented or split into smaller parts. Clients can request MTU sizes up to but not more than this number. max-mtu-size: 1492 + #Enable encryption of Minecraft network traffic. This has an impact on performance, but prevents hackers from stealing sessions and pretending to be other players. + #DO NOT DISABLE THIS unless you understand the risks involved. + enable-encryption: true debug: #To enable assertion execution, set zend.assertions in your php.ini to 1 From 488c03c2002f8f6705a3130bbc7956a6b901b139 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 31 Jul 2018 16:34:15 +0100 Subject: [PATCH 0074/3224] Make timings for player network more detailed --- src/pocketmine/Server.php | 4 ++-- .../network/mcpe/NetworkSession.php | 8 +++++++ src/pocketmine/timings/Timings.php | 21 ++++++++++++++++--- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 17c2309c63..5c0692abc2 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1877,7 +1877,7 @@ class Server{ if(empty($packets)){ throw new \InvalidArgumentException("Cannot send empty batch"); } - Timings::$playerNetworkTimer->startTiming(); + Timings::$playerNetworkSendCompressTimer->startTiming(); /** @var NetworkSession[] $targets */ $targets = []; @@ -1908,7 +1908,7 @@ class Server{ } } - Timings::$playerNetworkTimer->stopTiming(); + Timings::$playerNetworkSendCompressTimer->stopTiming(); } /** diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 993749b299..18fc3dfb96 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -146,21 +146,27 @@ class NetworkSession{ } if($this->cipher !== null){ + Timings::$playerNetworkReceiveDecryptTimer->startTiming(); try{ $payload = $this->cipher->decrypt($payload); }catch(\InvalidArgumentException $e){ $this->server->getLogger()->debug("Encrypted packet from " . $this->ip . " " . $this->port . ": " . bin2hex($payload)); $this->disconnect("Packet decryption error: " . $e->getMessage()); return; + }finally{ + Timings::$playerNetworkReceiveDecryptTimer->stopTiming(); } } + Timings::$playerNetworkReceiveDecompressTimer->startTiming(); try{ $stream = new PacketStream(NetworkCompression::decompress($payload)); }catch(\ErrorException $e){ $this->server->getLogger()->debug("Failed to decompress packet from " . $this->ip . " " . $this->port . ": " . bin2hex($payload)); $this->disconnect("Compressed packet batch decode error (incompatible game version?)", false); return; + }finally{ + Timings::$playerNetworkReceiveDecompressTimer->stopTiming(); } while(!$stream->feof() and $this->connected){ @@ -206,7 +212,9 @@ class NetworkSession{ public function sendEncoded(string $payload, bool $immediate = false) : void{ if($this->cipher !== null){ + Timings::$playerNetworkSendEncryptTimer->startTiming(); $payload = $this->cipher->encrypt($payload); + Timings::$playerNetworkSendEncryptTimer->stopTiming(); } $this->interface->putPacket($this, $payload, $immediate); } diff --git a/src/pocketmine/timings/Timings.php b/src/pocketmine/timings/Timings.php index 91df09a924..86e7f793fa 100644 --- a/src/pocketmine/timings/Timings.php +++ b/src/pocketmine/timings/Timings.php @@ -42,10 +42,18 @@ abstract class Timings{ /** @var TimingsHandler */ public static $titleTickTimer; /** @var TimingsHandler */ - public static $playerNetworkTimer; + public static $playerNetworkSendTimer; + /** @var TimingsHandler */ + public static $playerNetworkSendCompressTimer; + /** @var TimingsHandler */ + public static $playerNetworkSendEncryptTimer; /** @var TimingsHandler */ public static $playerNetworkReceiveTimer; /** @var TimingsHandler */ + public static $playerNetworkReceiveDecompressTimer; + /** @var TimingsHandler */ + public static $playerNetworkReceiveDecryptTimer; + /** @var TimingsHandler */ public static $playerChunkOrderTimer; /** @var TimingsHandler */ public static $playerChunkSendTimer; @@ -112,8 +120,15 @@ abstract class Timings{ self::$memoryManagerTimer = new TimingsHandler("Memory Manager"); self::$garbageCollectorTimer = new TimingsHandler("Garbage Collector", self::$memoryManagerTimer); self::$titleTickTimer = new TimingsHandler("Console Title Tick"); - self::$playerNetworkTimer = new TimingsHandler("Player Network Send"); + + self::$playerNetworkSendTimer = new TimingsHandler("Player Network Send"); + self::$playerNetworkSendCompressTimer = new TimingsHandler("** Player Network Send - Compression", self::$playerNetworkSendTimer); + self::$playerNetworkSendEncryptTimer = new TimingsHandler("** Player Network Send - Encryption", self::$playerNetworkSendTimer); + self::$playerNetworkReceiveTimer = new TimingsHandler("Player Network Receive"); + self::$playerNetworkReceiveDecompressTimer = new TimingsHandler("** Player Network Receive - Decompression", self::$playerNetworkReceiveTimer); + self::$playerNetworkReceiveDecryptTimer = new TimingsHandler("** Player Network Receive - Decryption", self::$playerNetworkReceiveTimer); + self::$playerChunkOrderTimer = new TimingsHandler("Player Order Chunks"); self::$playerChunkSendTimer = new TimingsHandler("Player Send Chunks"); self::$connectionTimer = new TimingsHandler("Connection Handler"); @@ -218,7 +233,7 @@ abstract class Timings{ public static function getSendDataPacketTimings(DataPacket $pk) : TimingsHandler{ if(!isset(self::$packetSendTimingMap[$pk::NETWORK_ID])){ $pkName = (new \ReflectionClass($pk))->getShortName(); - self::$packetSendTimingMap[$pk::NETWORK_ID] = new TimingsHandler("** sendPacket - " . $pkName . " [0x" . dechex($pk::NETWORK_ID) . "]", self::$playerNetworkTimer); + self::$packetSendTimingMap[$pk::NETWORK_ID] = new TimingsHandler("** sendPacket - " . $pkName . " [0x" . dechex($pk::NETWORK_ID) . "]", self::$playerNetworkSendTimer); } return self::$packetSendTimingMap[$pk::NETWORK_ID]; From 32a78e679a1481d8610c3f87beb6093e3117bb27 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 31 Jul 2018 18:36:36 +0100 Subject: [PATCH 0075/3224] Fixed JWT padding --- src/pocketmine/network/mcpe/ProcessLoginTask.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/ProcessLoginTask.php b/src/pocketmine/network/mcpe/ProcessLoginTask.php index 75f19cb819..29d5823fa8 100644 --- a/src/pocketmine/network/mcpe/ProcessLoginTask.php +++ b/src/pocketmine/network/mcpe/ProcessLoginTask.php @@ -206,11 +206,14 @@ class ProcessLoginTask extends AsyncTask{ } private static function b64UrlDecode(string $str) : string{ + if(($len = strlen($str) % 4) !== 0){ + $str .= str_repeat('=', 4 - $len); + } return base64_decode(strtr($str, '-_', '+/'), true); } private static function b64UrlEncode(string $str) : string{ - return strtr(base64_encode($str), '+/', '-_'); + return rtrim(strtr(base64_encode($str), '+/', '-_'), '='); } public function onCompletion(Server $server) : void{ From 47cf6e4833bba052775d7c816fa3e0c42ac18d7b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 31 Jul 2018 18:51:57 +0100 Subject: [PATCH 0076/3224] Fixed not being able to disable encryption --- src/pocketmine/Player.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index ff3ee37a74..876fea6afa 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -96,6 +96,7 @@ use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\ListTag; +use pocketmine\network\mcpe\NetworkCipher; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; @@ -1795,7 +1796,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } if(!$packet->skipVerification){ - $this->server->getAsyncPool()->submitTask(new ProcessLoginTask($this, $packet)); + $this->server->getAsyncPool()->submitTask(new ProcessLoginTask($this, $packet, NetworkCipher::$ENABLED)); }else{ $this->setAuthenticationStatus(true, null); $this->networkSession->onLoginSuccess(); From 1ef538b69e1ea2f1dcff43b4a29e6c6d48fbe3dc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 31 Jul 2018 19:40:24 +0100 Subject: [PATCH 0077/3224] LoginSessionHandler: fix crash when disconnected during login handling --- src/pocketmine/network/mcpe/handler/LoginSessionHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php index 0c65896d4c..877d1baf80 100644 --- a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php @@ -74,7 +74,7 @@ class LoginSessionHandler extends SessionHandler{ } if($this->player->handleLogin($packet)){ - if($this->session->getHandler() === $this){ //when login verification is disabled, the handler will already have been replaced + if($this->session->isConnected() and $this->session->getHandler() === $this){ //when login verification is disabled, the handler will already have been replaced $this->session->setHandler(new NullSessionHandler()); //drop packets received during login verification } return true; From 809b33033e2b4ae126de4103b144cd3ce6973c72 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 1 Aug 2018 17:27:32 +0100 Subject: [PATCH 0078/3224] Player: Use connected status instead of Entity->closed flag --- src/pocketmine/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 876fea6afa..f8afe7a6cf 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1806,7 +1806,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } public function setAuthenticationStatus(bool $authenticated, ?string $error) : bool{ - if($this->closed){ + if($this->networkSession === null){ return false; } From af6b279e54b74e3e5bc3d5a615fc474313463e82 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 1 Aug 2018 17:28:30 +0100 Subject: [PATCH 0079/3224] Player: Ensure we always get flagged as closed when parent constructor was never called This was causing unexpected bugs when players got disconnected during the login sequence. --- src/pocketmine/Player.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index f8afe7a6cf..1724394c3a 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2990,6 +2990,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ if($this->constructed){ parent::close(); + }else{ + $this->closed = true; } $this->spawned = false; From 7560880168f5b731b3707dd55818a353a47ca06b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 2 Aug 2018 15:54:30 +0100 Subject: [PATCH 0080/3224] Added DataPacketBroadcastEvent, refactor broadcast handling, close #1521 batchPackets() is now considered internal and shouldn't be used by plugins. Added Server->broadcastPackets(Player[], DataPacket[]) : bool --- src/pocketmine/Server.php | 72 +++++++++++------- .../event/server/DataPacketBroadcastEvent.php | 75 +++++++++++++++++++ src/pocketmine/level/Level.php | 26 ++++--- .../network/mcpe/NetworkSession.php | 4 +- 4 files changed, 140 insertions(+), 37 deletions(-) create mode 100644 src/pocketmine/event/server/DataPacketBroadcastEvent.php diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 6880f1167d..e140c23764 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -39,6 +39,7 @@ use pocketmine\event\HandlerList; use pocketmine\event\level\LevelInitEvent; use pocketmine\event\level\LevelLoadEvent; use pocketmine\event\player\PlayerDataSaveEvent; +use pocketmine\event\server\DataPacketBroadcastEvent; use pocketmine\event\server\QueryRegenerateEvent; use pocketmine\event\server\ServerCommandEvent; use pocketmine\inventory\CraftingManager; @@ -1859,41 +1860,62 @@ class Server{ * * @param Player[] $players * @param DataPacket $packet + * + * @return bool */ - public function broadcastPacket(array $players, DataPacket $packet){ - $packet->encode(); - $this->batchPackets($players, [$packet], false); + public function broadcastPacket(array $players, DataPacket $packet) : bool{ + return $this->broadcastPackets($players, [$packet]); + } + + /** + * @param Player[] $players + * @param DataPacket[] $packets + * + * @return bool + */ + public function broadcastPackets(array $players, array $packets) : bool{ + if(empty($packets)){ + throw new \InvalidArgumentException("Cannot broadcast empty list of packets"); + } + + $this->pluginManager->callEvent($ev = new DataPacketBroadcastEvent($players, $packets)); + if($ev->isCancelled()){ + return false; + } + + /** @var NetworkSession[] $targets */ + $targets = []; + foreach($ev->getPlayers() as $player){ + if($player->isConnected()){ + $targets[] = $player->getNetworkSession(); + } + } + if(empty($targets)){ + return false; + } + + $stream = new PacketStream(); + foreach($ev->getPackets() as $packet){ + $stream->putPacket($packet); + } + + //TODO: if under the compression threshold, add to session buffers instead of batching (first we need to implement buffering!) + $this->batchPackets($targets, $stream); + return true; } /** * Broadcasts a list of packets in a batch to a list of players * - * @param Player[] $players - * @param DataPacket[] $packets - * @param bool $forceSync - * @param bool $immediate + * @param NetworkSession[] $targets + * @param PacketStream $stream + * @param bool $forceSync + * @param bool $immediate */ - public function batchPackets(array $players, array $packets, bool $forceSync = false, bool $immediate = false){ - if(empty($packets)){ - throw new \InvalidArgumentException("Cannot send empty batch"); - } + public function batchPackets(array $targets, PacketStream $stream, bool $forceSync = false, bool $immediate = false){ Timings::$playerNetworkSendCompressTimer->startTiming(); - /** @var NetworkSession[] $targets */ - $targets = []; - foreach($players as $player){ - if($player->isConnected()){ - $targets[] = $player->getNetworkSession(); - } - } - if(!empty($targets)){ - $stream = new PacketStream(); - - foreach($packets as $p){ - $stream->putPacket($p); - } - $compressionLevel = NetworkCompression::$LEVEL; if(NetworkCompression::$THRESHOLD < 0 or strlen($stream->buffer) < NetworkCompression::$THRESHOLD){ $compressionLevel = 0; //Do not compress packets under the threshold diff --git a/src/pocketmine/event/server/DataPacketBroadcastEvent.php b/src/pocketmine/event/server/DataPacketBroadcastEvent.php new file mode 100644 index 0000000000..7b818ff377 --- /dev/null +++ b/src/pocketmine/event/server/DataPacketBroadcastEvent.php @@ -0,0 +1,75 @@ +players = $players; + $this->packets = $packets; + } + + /** + * @return Player[] + */ + public function getPlayers() : array{ + return $this->players; + } + + /** + * @param Player[] $players + */ + public function setPlayers(array $players) : void{ + $this->players = $players; + } + + /** + * @return DataPacket[] + */ + public function getPackets() : array{ + return $this->packets; + } + + /** + * @param DataPacket[] $packets + */ + public function setPackets(array $packets) : void{ + $this->packets = $packets; + } +} diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index dc939395a7..5373abe7b3 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -446,7 +446,7 @@ class Level implements ChunkManager, Metadatable{ $this->addChunkPacket($sound->getFloorX() >> 4, $sound->getFloorZ() >> 4, $e); } }else{ - $this->server->batchPackets($players, $pk, false); + $this->server->broadcastPackets($players, $pk); } } @@ -461,7 +461,7 @@ class Level implements ChunkManager, Metadatable{ $this->addChunkPacket($particle->getFloorX() >> 4, $particle->getFloorZ() >> 4, $e); } }else{ - $this->server->batchPackets($players, $pk, false); + $this->server->broadcastPackets($players, $pk); } } @@ -675,7 +675,11 @@ class Level implements ChunkManager, Metadatable{ $pk = new SetTimePacket(); $pk->time = $this->time; - $this->server->broadcastPacket(count($targets) > 0 ? $targets : $this->players, $pk); + if(empty($targets)){ + $this->addGlobalPacket($pk); + }else{ + $this->server->broadcastPacket($targets, $pk); + } } /** @@ -798,7 +802,7 @@ class Level implements ChunkManager, Metadatable{ } if(!empty($this->players) and !empty($this->globalPackets)){ - $this->server->batchPackets($this->players, $this->globalPackets); + $this->server->broadcastPackets($this->players, $this->globalPackets); $this->globalPackets = []; } @@ -806,7 +810,7 @@ class Level implements ChunkManager, Metadatable{ Level::getXZ($index, $chunkX, $chunkZ); $chunkPlayers = $this->getChunkPlayers($chunkX, $chunkZ); if(count($chunkPlayers) > 0){ - $this->server->batchPackets($chunkPlayers, $entries, false, false); + $this->server->broadcastPackets($chunkPlayers, $entries); } } @@ -914,7 +918,7 @@ class Level implements ChunkManager, Metadatable{ } } - $this->server->batchPackets($target, $packets, false, false); + $this->server->broadcastPackets($target, $packets); } public function clearCache(bool $force = false){ @@ -2919,13 +2923,13 @@ class Level implements ChunkManager, Metadatable{ * @param Player ...$targets */ public function sendDifficulty(Player ...$targets){ - if(count($targets) === 0){ - $targets = $this->getPlayers(); - } - $pk = new SetDifficultyPacket(); $pk->difficulty = $this->getDifficulty(); - $this->server->broadcastPacket($targets, $pk); + if(empty($targets)){ + $this->addGlobalPacket($pk); + }else{ + $this->server->broadcastPacket($targets, $pk); + } } public function populateChunk(int $x, int $z, bool $force = false) : bool{ diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 18fc3dfb96..8f75577498 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -202,7 +202,9 @@ class NetworkSession{ } //TODO: implement buffering (this is just a quick fix) - $this->server->batchPackets([$this->player], [$packet], true, $immediate); + $stream = new PacketStream(); + $stream->putPacket($packet); + $this->server->batchPackets([$this], $stream, true, $immediate); return true; }finally{ From e43496e7e41388aa4c4d0859e4b56123969ec7f0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 2 Aug 2018 17:13:34 +0100 Subject: [PATCH 0081/3224] Network: clean up ticking handling, RakLib only processes on Snooze notification --- src/pocketmine/Server.php | 2 +- src/pocketmine/network/Network.php | 30 ++++++++----------- src/pocketmine/network/NetworkInterface.php | 2 +- .../network/mcpe/RakLibInterface.php | 7 ++--- 4 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index e140c23764..4187057f8a 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -2537,7 +2537,7 @@ class Server{ ++$this->tickCounter; Timings::$connectionTimer->startTiming(); - $this->network->processInterfaces(); + $this->network->tickInterfaces(); Timings::$connectionTimer->stopTiming(); Timings::$schedulerTimer->startTiming(); diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index 48252a03d1..a1e022c6e9 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -80,26 +80,22 @@ class Network{ return $this->interfaces; } - public function processInterfaces() : void{ + public function tickInterfaces() : void{ foreach($this->interfaces as $interface){ - $this->processInterface($interface); - } - } + try{ + $interface->tick(); + }catch(\Exception $e){ + $logger = $this->server->getLogger(); + if(\pocketmine\DEBUG > 1){ + $logger->logException($e); + } - public function processInterface(NetworkInterface $interface) : void{ - try{ - $interface->process(); - }catch(\Throwable $e){ - $logger = $this->server->getLogger(); - if(\pocketmine\DEBUG > 1){ - $logger->logException($e); + $this->server->getPluginManager()->callEvent(new NetworkInterfaceCrashEvent($interface, $e)); + + $interface->emergencyShutdown(); + $this->unregisterInterface($interface); + $logger->critical($this->server->getLanguage()->translateString("pocketmine.server.networkError", [get_class($interface), $e->getMessage()])); } - - $this->server->getPluginManager()->callEvent(new NetworkInterfaceCrashEvent($interface, $e)); - - $interface->emergencyShutdown(); - $this->unregisterInterface($interface); - $logger->critical($this->server->getLanguage()->translateString("pocketmine.server.networkError", [get_class($interface), $e->getMessage()])); } } diff --git a/src/pocketmine/network/NetworkInterface.php b/src/pocketmine/network/NetworkInterface.php index 60001a74f5..8bf17e4224 100644 --- a/src/pocketmine/network/NetworkInterface.php +++ b/src/pocketmine/network/NetworkInterface.php @@ -63,7 +63,7 @@ interface NetworkInterface{ /** * Called every tick to process events on the interface. */ - public function process() : void; + public function tick() : void; /** * Gracefully shuts down the network interface. diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 314e41c643..d5ee7d3e5f 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -71,7 +71,8 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $this->sleeper = new SleeperNotifier(); $server->getTickSleeper()->addNotifier($this->sleeper, function() : void{ - $this->server->getNetwork()->processInterface($this); + //this should not throw any exception. If it does, this should crash the server since it's a fault condition. + while($this->interface->handlePacket()); }); $this->rakLib = new RakLibServer( @@ -93,9 +94,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $this->network = $network; } - public function process() : void{ - while($this->interface->handlePacket()){} - + public function tick() : void{ if(!$this->rakLib->isRunning() and !$this->rakLib->isShutdown()){ throw new \Exception("RakLib Thread crashed"); } From 10ba3d635958620fa4e98bcce1f3cbb4b2458b15 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 2 Aug 2018 17:39:09 +0100 Subject: [PATCH 0082/3224] Network: add ability to tick sessions moved responsibility for login timeout checks to NetworkSession instead of Server --- src/pocketmine/Server.php | 16 ++++++++-------- src/pocketmine/network/Network.php | 16 +++++++++++++++- .../network/mcpe/NetworkSession.php | 19 +++++++++++++++++++ 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 4187057f8a..3e56fdd839 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -2375,12 +2375,12 @@ class Server{ $p->sendDataPacket($pk); } - private function checkTickUpdates(int $currentTick, float $tickTime) : void{ - foreach($this->players as $p){ - if(!$p->loggedIn and ($tickTime - $p->creationTime) >= 10){ - $p->close("", "Login timeout"); - }elseif($this->alwaysTickPlayers and $p->spawned){ - $p->onUpdate($currentTick); + private function checkTickUpdates(int $currentTick) : void{ + if($this->alwaysTickPlayers){ + foreach($this->players as $p){ + if($p->spawned){ + $p->onUpdate($currentTick); + } } } @@ -2537,7 +2537,7 @@ class Server{ ++$this->tickCounter; Timings::$connectionTimer->startTiming(); - $this->network->tickInterfaces(); + $this->network->tick(); Timings::$connectionTimer->stopTiming(); Timings::$schedulerTimer->startTiming(); @@ -2548,7 +2548,7 @@ class Server{ $this->asyncPool->collectTasks(); Timings::$schedulerAsyncTimer->stopTiming(); - $this->checkTickUpdates($this->tickCounter, $tickTime); + $this->checkTickUpdates($this->tickCounter); if(($this->tickCounter % 20) === 0){ if($this->doTitleTick){ diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index a1e022c6e9..7cc580ffcc 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -29,6 +29,7 @@ namespace pocketmine\network; use pocketmine\event\server\NetworkInterfaceCrashEvent; use pocketmine\event\server\NetworkInterfaceRegisterEvent; use pocketmine\event\server\NetworkInterfaceUnregisterEvent; +use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\Server; @@ -48,6 +49,9 @@ class Network{ /** @var string */ private $name; + /** @var NetworkSession[] */ + private $updateSessions = []; + public function __construct(Server $server){ PacketPool::init(); @@ -80,7 +84,7 @@ class Network{ return $this->interfaces; } - public function tickInterfaces() : void{ + public function tick() : void{ foreach($this->interfaces as $interface){ try{ $interface->tick(); @@ -97,6 +101,12 @@ class Network{ $logger->critical($this->server->getLanguage()->translateString("pocketmine.server.networkError", [get_class($interface), $e->getMessage()])); } } + + foreach($this->updateSessions as $k => $session){ + if(!$session->isConnected() or !$session->tick()){ + unset($this->updateSessions[$k]); + } + } } /** @@ -183,4 +193,8 @@ class Network{ $interface->unblockAddress($address); } } + + public function scheduleSessionTick(NetworkSession $session) : void{ + $this->updateSessions[spl_object_hash($session)] = $session; + } } diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 8f75577498..a00916c71a 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -62,6 +62,8 @@ class NetworkSession{ /** @var bool */ private $connected = true; + /** @var int */ + private $connectTime; /** @var NetworkCipher */ private $cipher; @@ -72,6 +74,9 @@ class NetworkSession{ $this->ip = $ip; $this->port = $port; + $this->connectTime = time(); + $this->server->getNetwork()->scheduleSessionTick($this); + //TODO: this should happen later in the login sequence $this->createPlayer(); @@ -328,4 +333,18 @@ class NetworkSession{ public function onRespawn() : void{ $this->setHandler(new SimpleSessionHandler($this->player)); } + + public function tick() : bool{ + if($this->handler instanceof LoginSessionHandler){ + if(time() >= $this->connectTime + 10){ + $this->disconnect("Login timeout"); + return false; + } + + return true; //keep ticking until timeout + } + + //TODO: more stuff on tick + return false; + } } From 0e44e5b6815f96b1224461f284b98ccc8f9925b3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 3 Aug 2018 09:02:53 +0100 Subject: [PATCH 0083/3224] Update ISSUE_TEMPLATE.md --- .github/ISSUE_TEMPLATE.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 09d826a78a..b2d513eae3 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -8,6 +8,8 @@ PLEASE DO NOT REPORT ATTACK VECTORS ON THIS ISSUE TRACKER. Send an email to team@pmmp.io if you have a vulnerability to report. Any issues requesting updates to new versions of MCPE will be treated as spam. + +Missing gameplay features are to be expected. Please do not create issues for missing/un-implemented gameplay features - they will be closed. --> From 779d92c656bac3ff8a7e351991afc79cbb91f4e4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 4 Aug 2018 14:44:20 +0100 Subject: [PATCH 0084/3224] BulkCurlTask: Remove complexData parameter (BC break) This is a leftover from when it was necessary to pass complex data to the AsyncTask constructor in order to have it locally-stored. Since this has now been superseded by storeLocal(), it doesn't make sense for this parameter to exist anymore. --- src/pocketmine/command/defaults/TimingsCommand.php | 3 ++- src/pocketmine/scheduler/BulkCurlTask.php | 6 ++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/command/defaults/TimingsCommand.php b/src/pocketmine/command/defaults/TimingsCommand.php index 8b2846e81a..f4105cb7d6 100644 --- a/src/pocketmine/command/defaults/TimingsCommand.php +++ b/src/pocketmine/command/defaults/TimingsCommand.php @@ -121,8 +121,9 @@ class TimingsCommand extends VanillaCommand{ CURLOPT_AUTOREFERER => false, CURLOPT_FOLLOWLOCATION => false ]] - ], $sender); + ]); $this->host = $host; + $this->storeLocal($sender); } public function onCompletion(Server $server){ diff --git a/src/pocketmine/scheduler/BulkCurlTask.php b/src/pocketmine/scheduler/BulkCurlTask.php index d7a0e4b39a..b181dc33b6 100644 --- a/src/pocketmine/scheduler/BulkCurlTask.php +++ b/src/pocketmine/scheduler/BulkCurlTask.php @@ -42,11 +42,9 @@ class BulkCurlTask extends AsyncTask{ * "timeout", "extraHeaders" and "extraOpts". Documentation of these options are same as those in * {@link Utils::simpleCurl}. * - * @param array $operations - * @param mixed|null $complexData + * @param array $operations */ - public function __construct(array $operations, $complexData = null){ - $this->storeLocal($complexData); + public function __construct(array $operations){ $this->operations = serialize($operations); } From 20f3b82d52ba04b7fe5d986195ee02f611f8a407 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 4 Aug 2018 15:56:14 +0100 Subject: [PATCH 0085/3224] Be less dependent on AsyncTask->onCompletion() Server parameter this is going to get removed soon. --- .../command/defaults/TimingsCommand.php | 2 +- .../level/generator/PopulationTask.php | 7 +++++-- .../level/light/LightPopulationTask.php | 8 ++++---- .../network/mcpe/ChunkRequestTask.php | 13 +++++-------- src/pocketmine/updater/AutoUpdater.php | 6 +++++- src/pocketmine/updater/UpdateCheckTask.php | 17 +++++++---------- 6 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/pocketmine/command/defaults/TimingsCommand.php b/src/pocketmine/command/defaults/TimingsCommand.php index f4105cb7d6..98c91b8317 100644 --- a/src/pocketmine/command/defaults/TimingsCommand.php +++ b/src/pocketmine/command/defaults/TimingsCommand.php @@ -133,7 +133,7 @@ class TimingsCommand extends VanillaCommand{ } $result = $this->getResult()[0]; if($result instanceof \RuntimeException){ - $server->getLogger()->logException($result); + $sender->getServer()->getLogger()->logException($result); return; } if(isset($result[0]) && is_array($response = json_decode($result[0], true)) && isset($response["id"])){ diff --git a/src/pocketmine/level/generator/PopulationTask.php b/src/pocketmine/level/generator/PopulationTask.php index af94ffd8e0..7c469dc086 100644 --- a/src/pocketmine/level/generator/PopulationTask.php +++ b/src/pocketmine/level/generator/PopulationTask.php @@ -53,6 +53,8 @@ class PopulationTask extends AsyncTask{ foreach($level->getAdjacentChunks($chunk->getX(), $chunk->getZ()) as $i => $c){ $this->{"chunk$i"} = $c !== null ? $c->fastSerialize() : null; } + + $this->storeLocal($level); } public function onRun() : void{ @@ -136,8 +138,9 @@ class PopulationTask extends AsyncTask{ } public function onCompletion(Server $server) : void{ - $level = $server->getLevel($this->levelId); - if($level !== null){ + /** @var Level $level */ + $level = $this->fetchLocal(); + if(!$level->isClosed()){ if(!$this->state){ $level->registerGeneratorToWorker($this->worker->getAsyncWorkerId()); } diff --git a/src/pocketmine/level/light/LightPopulationTask.php b/src/pocketmine/level/light/LightPopulationTask.php index 201d52d413..1e6c9f7eb5 100644 --- a/src/pocketmine/level/light/LightPopulationTask.php +++ b/src/pocketmine/level/light/LightPopulationTask.php @@ -30,11 +30,10 @@ use pocketmine\Server; class LightPopulationTask extends AsyncTask{ - public $levelId; public $chunk; public function __construct(Level $level, Chunk $chunk){ - $this->levelId = $level->getId(); + $this->storeLocal($level); $this->chunk = $chunk->fastSerialize(); } @@ -50,8 +49,9 @@ class LightPopulationTask extends AsyncTask{ } public function onCompletion(Server $server){ - $level = $server->getLevel($this->levelId); - if($level !== null){ + /** @var Level $level */ + $level = $this->fetchLocal(); + if(!$level->isClosed()){ /** @var Chunk $chunk */ $chunk = Chunk::fastDeserialize($this->chunk); $level->generateChunkCallback($chunk->getX(), $chunk->getZ(), $chunk); diff --git a/src/pocketmine/network/mcpe/ChunkRequestTask.php b/src/pocketmine/network/mcpe/ChunkRequestTask.php index c904f517a7..b12d31db11 100644 --- a/src/pocketmine/network/mcpe/ChunkRequestTask.php +++ b/src/pocketmine/network/mcpe/ChunkRequestTask.php @@ -31,8 +31,6 @@ use pocketmine\Server; use pocketmine\tile\Spawnable; class ChunkRequestTask extends AsyncTask{ - /** @var int */ - protected $levelId; /** @var string */ protected $chunk; /** @var int */ @@ -45,7 +43,7 @@ class ChunkRequestTask extends AsyncTask{ protected $compressionLevel; public function __construct(Level $level, int $chunkX, int $chunkZ, Chunk $chunk){ - $this->levelId = $level->getId(); + $this->storeLocal($level); $this->compressionLevel = NetworkCompression::$LEVEL; $this->chunk = $chunk->fastSerialize(); @@ -78,15 +76,14 @@ class ChunkRequestTask extends AsyncTask{ } public function onCompletion(Server $server) : void{ - $level = $server->getLevel($this->levelId); - if($level instanceof Level){ + /** @var Level $level */ + $level = $this->fetchLocal(); + if(!$level->isClosed()){ if($this->hasResult()){ $level->chunkRequestCallback($this->chunkX, $this->chunkZ, $this->getResult()); }else{ - $server->getLogger()->error("Chunk request for level #" . $this->levelId . ", x=" . $this->chunkX . ", z=" . $this->chunkZ . " doesn't have any result data"); + $level->getServer()->getLogger()->error("Chunk request for level " . $level->getName() . ", x=" . $this->chunkX . ", z=" . $this->chunkZ . " doesn't have any result data"); } - }else{ - $server->getLogger()->debug("Dropped chunk task due to level not loaded"); } } } diff --git a/src/pocketmine/updater/AutoUpdater.php b/src/pocketmine/updater/AutoUpdater.php index 087b7f8a69..19925c1873 100644 --- a/src/pocketmine/updater/AutoUpdater.php +++ b/src/pocketmine/updater/AutoUpdater.php @@ -53,6 +53,10 @@ class AutoUpdater{ } } + public function checkUpdateError(string $error) : void{ + $this->server->getLogger()->debug("[AutoUpdater] Async update check failed due to \"$error\""); + } + /** * Callback used at the end of the update checking task * @@ -146,7 +150,7 @@ class AutoUpdater{ * Schedules an AsyncTask to check for an update. */ public function doCheck(){ - $this->server->getAsyncPool()->submitTask(new UpdateCheckTask($this->endpoint, $this->getChannel())); + $this->server->getAsyncPool()->submitTask(new UpdateCheckTask($this, $this->endpoint, $this->getChannel())); } /** diff --git a/src/pocketmine/updater/UpdateCheckTask.php b/src/pocketmine/updater/UpdateCheckTask.php index e71b8f2c83..1044f9b5c3 100644 --- a/src/pocketmine/updater/UpdateCheckTask.php +++ b/src/pocketmine/updater/UpdateCheckTask.php @@ -38,7 +38,8 @@ class UpdateCheckTask extends AsyncTask{ /** @var string */ private $error = "Unknown error"; - public function __construct(string $endpoint, string $channel){ + public function __construct(AutoUpdater $updater, string $endpoint, string $channel){ + $this->storeLocal($updater); $this->endpoint = $endpoint; $this->channel = $channel; } @@ -72,16 +73,12 @@ class UpdateCheckTask extends AsyncTask{ } public function onCompletion(Server $server){ - if($this->error !== ""){ - $server->getLogger()->debug("[AutoUpdater] Async update check failed due to \"$this->error\""); + /** @var AutoUpdater $updater */ + $updater = $this->fetchLocal(); + if($this->hasResult()){ + $updater->checkUpdateCallback($this->getResult()); }else{ - $updateInfo = $this->getResult(); - if(is_array($updateInfo)){ - $server->getUpdater()->checkUpdateCallback($updateInfo); - }else{ - $server->getLogger()->debug("[AutoUpdater] Update info error"); - } - + $updater->checkUpdateError($this->error); } } } From 25660843c5887284def59efdcd8f0cf95db314b1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 4 Aug 2018 20:01:32 +0100 Subject: [PATCH 0086/3224] Player: Obliterate InventoryTransactionPacket handler, add some new methods --- src/pocketmine/Player.php | 640 ++++++++---------- .../mcpe/handler/SimpleSessionHandler.php | 133 +++- 2 files changed, 401 insertions(+), 372 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 1724394c3a..7c77c978da 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -71,10 +71,6 @@ use pocketmine\event\player\PlayerTransferEvent; use pocketmine\inventory\CraftingGrid; use pocketmine\inventory\Inventory; use pocketmine\inventory\PlayerCursorInventory; -use pocketmine\inventory\transaction\action\InventoryAction; -use pocketmine\inventory\transaction\CraftingTransaction; -use pocketmine\inventory\transaction\InventoryTransaction; -use pocketmine\inventory\transaction\TransactionValidationException; use pocketmine\item\Consumable; use pocketmine\item\Durable; use pocketmine\item\enchantment\EnchantmentInstance; @@ -106,7 +102,6 @@ use pocketmine\network\mcpe\protocol\BookEditPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\EntityEventPacket; -use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; @@ -202,8 +197,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ protected $cursorInventory; /** @var CraftingGrid */ protected $craftingGrid = null; - /** @var CraftingTransaction|null */ - protected $craftingTransaction = null; /** @var int */ protected $messageCounter = 2; @@ -2035,370 +2028,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return true; } - /** - * Don't expect much from this handler. Most of it is roughly hacked and duct-taped together. - * - * @param InventoryTransactionPacket $packet - * @return bool - */ - public function handleInventoryTransaction(InventoryTransactionPacket $packet) : bool{ - if($this->isSpectator()){ - $this->sendAllInventories(); - return true; - } - - /** @var InventoryAction[] $actions */ - $actions = []; - foreach($packet->actions as $networkInventoryAction){ - try{ - $action = $networkInventoryAction->createInventoryAction($this); - if($action !== null){ - $actions[] = $action; - } - }catch(\Exception $e){ - $this->server->getLogger()->debug("Unhandled inventory action from " . $this->getName() . ": " . $e->getMessage()); - $this->sendAllInventories(); - return false; - } - } - - if($packet->isCraftingPart){ - if($this->craftingTransaction === null){ - $this->craftingTransaction = new CraftingTransaction($this, $actions); - }else{ - foreach($actions as $action){ - $this->craftingTransaction->addAction($action); - } - } - - if($packet->isFinalCraftingPart){ - //we get the actions for this in several packets, so we need to wait until we have all the pieces before - //trying to execute it - - $ret = true; - try{ - $this->craftingTransaction->execute(); - }catch(TransactionValidationException $e){ - $this->server->getLogger()->debug("Failed to execute crafting transaction for " . $this->getName() . ": " . $e->getMessage()); - $ret = false; - } - - $this->craftingTransaction = null; - return $ret; - } - - return true; - }elseif($this->craftingTransaction !== null){ - $this->server->getLogger()->debug("Got unexpected normal inventory action with incomplete crafting transaction from " . $this->getName() . ", refusing to execute crafting"); - $this->craftingTransaction = null; - } - - switch($packet->transactionType){ - case InventoryTransactionPacket::TYPE_NORMAL: - $this->setUsingItem(false); - $transaction = new InventoryTransaction($this, $actions); - - try{ - $transaction->execute(); - }catch(TransactionValidationException $e){ - $this->server->getLogger()->debug("Failed to execute inventory transaction from " . $this->getName() . ": " . $e->getMessage()); - $this->server->getLogger()->debug("Actions: " . json_encode($packet->actions)); - - return false; - } - - //TODO: fix achievement for getting iron from furnace - - return true; - case InventoryTransactionPacket::TYPE_MISMATCH: - if(count($packet->actions) > 0){ - $this->server->getLogger()->debug("Expected 0 actions for mismatch, got " . count($packet->actions) . ", " . json_encode($packet->actions)); - } - $this->setUsingItem(false); - $this->sendAllInventories(); - - return true; - case InventoryTransactionPacket::TYPE_USE_ITEM: - $blockVector = new Vector3($packet->trData->x, $packet->trData->y, $packet->trData->z); - $face = $packet->trData->face; - - $type = $packet->trData->actionType; - switch($type){ - case InventoryTransactionPacket::USE_ITEM_ACTION_CLICK_BLOCK: - $this->setUsingItem(false); - - if(!$this->canInteract($blockVector->add(0.5, 0.5, 0.5), 13) or $this->isSpectator()){ - }elseif($this->isCreative()){ - $item = $this->inventory->getItemInHand(); - if($this->level->useItemOn($blockVector, $item, $face, $packet->trData->clickPos, $this, true)){ - return true; - } - }elseif(!$this->inventory->getItemInHand()->equals($packet->trData->itemInHand)){ - $this->inventory->sendHeldItem($this); - }else{ - $item = $this->inventory->getItemInHand(); - $oldItem = clone $item; - if($this->level->useItemOn($blockVector, $item, $face, $packet->trData->clickPos, $this, true)){ - if(!$item->equalsExact($oldItem)){ - $this->inventory->setItemInHand($item); - $this->inventory->sendHeldItem($this->hasSpawned); - } - - return true; - } - } - - $this->inventory->sendHeldItem($this); - - if($blockVector->distanceSquared($this) > 10000){ - return true; - } - - $target = $this->level->getBlock($blockVector); - $block = $target->getSide($face); - - /** @var Block[] $blocks */ - $blocks = array_merge($target->getAllSides(), $block->getAllSides()); //getAllSides() on each of these will include $target and $block because they are next to each other - - $this->level->sendBlocks([$this], $blocks, UpdateBlockPacket::FLAG_ALL_PRIORITY); - - return true; - case InventoryTransactionPacket::USE_ITEM_ACTION_BREAK_BLOCK: - $this->doCloseInventory(); - - $item = $this->inventory->getItemInHand(); - $oldItem = clone $item; - - if($this->canInteract($blockVector->add(0.5, 0.5, 0.5), $this->isCreative() ? 13 : 7) and $this->level->useBreakOn($blockVector, $item, $this, true)){ - if($this->isSurvival()){ - if(!$item->equalsExact($oldItem)){ - $this->inventory->setItemInHand($item); - $this->inventory->sendHeldItem($this->hasSpawned); - } - - $this->exhaust(0.025, PlayerExhaustEvent::CAUSE_MINING); - } - return true; - } - - $this->inventory->sendContents($this); - $this->inventory->sendHeldItem($this); - - $target = $this->level->getBlock($blockVector); - /** @var Block[] $blocks */ - $blocks = $target->getAllSides(); - $blocks[] = $target; - - $this->level->sendBlocks([$this], $blocks, UpdateBlockPacket::FLAG_ALL_PRIORITY); - - foreach($blocks as $b){ - $tile = $this->level->getTile($b); - if($tile instanceof Spawnable){ - $tile->spawnTo($this); - } - } - - return true; - case InventoryTransactionPacket::USE_ITEM_ACTION_CLICK_AIR: - $directionVector = $this->getDirectionVector(); - - if($this->isCreative()){ - $item = $this->inventory->getItemInHand(); - }elseif(!$this->inventory->getItemInHand()->equals($packet->trData->itemInHand)){ - $this->inventory->sendHeldItem($this); - return true; - }else{ - $item = $this->inventory->getItemInHand(); - } - - $ev = new PlayerInteractEvent($this, $item, null, $directionVector, $face, PlayerInteractEvent::RIGHT_CLICK_AIR); - if($this->hasItemCooldown($item)){ - $ev->setCancelled(); - } - - $this->server->getPluginManager()->callEvent($ev); - - if($ev->isCancelled()){ - $this->inventory->sendHeldItem($this); - return true; - } - - if($item->onClickAir($this, $directionVector)){ - $this->resetItemCooldown($item); - if($this->isSurvival()){ - $this->inventory->setItemInHand($item); - } - } - - $this->setUsingItem(true); - - return true; - default: - //unknown - break; - } - break; - case InventoryTransactionPacket::TYPE_USE_ITEM_ON_ENTITY: - $target = $this->level->getEntity($packet->trData->entityRuntimeId); - if($target === null){ - return false; - } - - $type = $packet->trData->actionType; - - switch($type){ - case InventoryTransactionPacket::USE_ITEM_ON_ENTITY_ACTION_INTERACT: - break; //TODO - case InventoryTransactionPacket::USE_ITEM_ON_ENTITY_ACTION_ATTACK: - if(!$target->isAlive()){ - return true; - } - if($target instanceof ItemEntity or $target instanceof Arrow){ - $this->kick("Attempting to attack an invalid entity"); - $this->server->getLogger()->warning($this->getServer()->getLanguage()->translateString("pocketmine.player.invalidEntity", [$this->getName()])); - return false; - } - - $cancelled = false; - - $heldItem = $this->inventory->getItemInHand(); - - if(!$this->canInteract($target, 8)){ - $cancelled = true; - }elseif($target instanceof Player){ - if(!$this->server->getConfigBool("pvp")){ - $cancelled = true; - } - } - - $ev = new EntityDamageByEntityEvent($this, $target, EntityDamageEvent::CAUSE_ENTITY_ATTACK, $heldItem->getAttackPoints()); - - $meleeEnchantmentDamage = 0; - /** @var EnchantmentInstance[] $meleeEnchantments */ - $meleeEnchantments = []; - foreach($heldItem->getEnchantments() as $enchantment){ - $type = $enchantment->getType(); - if($type instanceof MeleeWeaponEnchantment and $type->isApplicableTo($target)){ - $meleeEnchantmentDamage += $type->getDamageBonus($enchantment->getLevel()); - $meleeEnchantments[] = $enchantment; - } - } - $ev->setModifier($meleeEnchantmentDamage, EntityDamageEvent::MODIFIER_WEAPON_ENCHANTMENTS); - - if($cancelled){ - $ev->setCancelled(); - } - - if(!$this->isSprinting() and !$this->isFlying() and $this->fallDistance > 0 and !$this->hasEffect(Effect::BLINDNESS) and !$this->isUnderwater()){ - $ev->setModifier($ev->getFinalDamage() / 2, EntityDamageEvent::MODIFIER_CRITICAL); - } - - $target->attack($ev); - - if($ev->isCancelled()){ - if($heldItem instanceof Durable and $this->isSurvival()){ - $this->inventory->sendContents($this); - } - return true; - } - - if($ev->getModifier(EntityDamageEvent::MODIFIER_CRITICAL) > 0){ - $pk = new AnimatePacket(); - $pk->action = AnimatePacket::ACTION_CRITICAL_HIT; - $pk->entityRuntimeId = $target->getId(); - $this->server->broadcastPacket($target->getViewers(), $pk); - if($target instanceof Player){ - $target->sendDataPacket($pk); - } - } - - foreach($meleeEnchantments as $enchantment){ - $type = $enchantment->getType(); - assert($type instanceof MeleeWeaponEnchantment); - $type->onPostAttack($this, $target, $enchantment->getLevel()); - } - - if($this->isAlive()){ - //reactive damage like thorns might cause us to be killed by attacking another mob, which - //would mean we'd already have dropped the inventory by the time we reached here - if($heldItem->onAttackEntity($target) and $this->isSurvival()){ //always fire the hook, even if we are survival - $this->inventory->setItemInHand($heldItem); - } - - $this->exhaust(0.3, PlayerExhaustEvent::CAUSE_ATTACK); - } - - return true; - default: - break; //unknown - } - - break; - case InventoryTransactionPacket::TYPE_RELEASE_ITEM: - try{ - $type = $packet->trData->actionType; - switch($type){ - case InventoryTransactionPacket::RELEASE_ITEM_ACTION_RELEASE: - if($this->isUsingItem()){ - $item = $this->inventory->getItemInHand(); - if($this->hasItemCooldown($item)){ - $this->inventory->sendContents($this); - return false; - } - if($item->onReleaseUsing($this)){ - $this->resetItemCooldown($item); - $this->inventory->setItemInHand($item); - } - }else{ - break; - } - - return true; - case InventoryTransactionPacket::RELEASE_ITEM_ACTION_CONSUME: - $slot = $this->inventory->getItemInHand(); - - if($slot instanceof Consumable){ - $ev = new PlayerItemConsumeEvent($this, $slot); - if($this->hasItemCooldown($slot)){ - $ev->setCancelled(); - } - $this->server->getPluginManager()->callEvent($ev); - - if($ev->isCancelled() or !$this->consumeObject($slot)){ - $this->inventory->sendContents($this); - return true; - } - - $this->resetItemCooldown($slot); - - if($this->isSurvival()){ - $slot->pop(); - $this->inventory->setItemInHand($slot); - $this->inventory->addItem($slot->getResidue()); - } - - return true; - } - - break; - default: - break; - } - }finally{ - $this->setUsingItem(false); - } - - $this->inventory->sendContents($this); - break; - default: - $this->inventory->sendContents($this); - break; - - } - - return false; //TODO - } - public function equipItem(int $hotbarSlot) : bool{ if(!$this->inventory->isHotbarSlot($hotbarSlot)){ $this->inventory->sendContents($this); @@ -2417,6 +2046,99 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return true; } + /** + * Activates the item in hand, for example throwing a projectile. + * + * @return bool if it did something + */ + public function useHeldItem() : bool{ + $directionVector = $this->getDirectionVector(); + $item = $this->inventory->getItemInHand(); + + $ev = new PlayerInteractEvent($this, $item, null, $directionVector, 0, PlayerInteractEvent::RIGHT_CLICK_AIR); + if($this->hasItemCooldown($item)){ + $ev->setCancelled(); + } + + $this->server->getPluginManager()->callEvent($ev); + + if($ev->isCancelled()){ + $this->inventory->sendHeldItem($this); + return false; + } + + if($item->onClickAir($this, $directionVector)){ + $this->resetItemCooldown($item); + if($this->isSurvival()){ + $this->inventory->setItemInHand($item); + } + } + + //TODO: check if item has a release action - if it doesn't, this shouldn't be set + $this->setUsingItem(true); + + return true; + } + + /** + * Consumes the currently-held item. + * + * @return bool + */ + public function consumeHeldItem() : bool{ + $slot = $this->inventory->getItemInHand(); + if($slot instanceof Consumable){ + $ev = new PlayerItemConsumeEvent($this, $slot); + if($this->hasItemCooldown($slot)){ + $ev->setCancelled(); + } + $this->server->getPluginManager()->callEvent($ev); + + if($ev->isCancelled() or !$this->consumeObject($slot)){ + $this->inventory->sendContents($this); + return true; + } + + $this->resetItemCooldown($slot); + + if($this->isSurvival()){ + $slot->pop(); + $this->inventory->setItemInHand($slot); + $this->inventory->addItem($slot->getResidue()); + } + + return true; + } + + return false; + } + + /** + * Releases the held item, for example to fire a bow. This should be preceded by a call to useHeldItem(). + * + * @return bool if it did something. + */ + public function releaseHeldItem() : bool{ + try{ + if($this->isUsingItem()){ + $item = $this->inventory->getItemInHand(); + if($this->hasItemCooldown($item)){ + $this->inventory->sendContents($this); + return false; + } + if($item->onReleaseUsing($this)){ + $this->resetItemCooldown($item); + $this->inventory->setItemInHand($item); + return true; + } + } + + return false; + }finally{ + $this->setUsingItem(false); + } + } + public function pickBlock(Vector3 $pos, bool $addTileNBT) : bool{ $block = $this->level->getBlock($pos); @@ -2496,6 +2218,182 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->level->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_STOP_BREAK); } + /** + * Breaks the block at the given position using the currently-held item. + * + * @param Vector3 $pos + * + * @return bool if the block was successfully broken. + */ + public function breakBlock(Vector3 $pos) : bool{ + $this->doCloseInventory(); + + if($this->canInteract($pos->add(0.5, 0.5, 0.5), $this->isCreative() ? 13 : 7) and !$this->isSpectator()){ + $item = $this->inventory->getItemInHand(); + if($this->level->useBreakOn($pos, $item, $this, true)){ + if($this->isSurvival()){ + if(!$item->equalsExact($this->inventory->getItemInHand())){ + $this->inventory->setItemInHand($item); + $this->inventory->sendHeldItem($this->hasSpawned); + } + $this->exhaust(0.025, PlayerExhaustEvent::CAUSE_MINING); + } + return true; + } + } + + $this->inventory->sendContents($this); + $this->inventory->sendHeldItem($this); + + $target = $this->level->getBlock($pos); + /** @var Block[] $blocks */ + $blocks = $target->getAllSides(); + $blocks[] = $target; + + $this->level->sendBlocks([$this], $blocks, UpdateBlockPacket::FLAG_ALL_PRIORITY); + + foreach($blocks as $b){ + $tile = $this->level->getTile($b); + if($tile instanceof Spawnable){ + $tile->spawnTo($this); + } + } + + return false; + } + + /** + * Touches the block at the given position with the currently-held item. + * + * @param Vector3 $pos + * @param int $face + * @param Vector3 $clickOffset + * + * @return bool if it did something + */ + public function interactBlock(Vector3 $pos, int $face, Vector3 $clickOffset) : bool{ + $this->setUsingItem(false); + + if($this->canInteract($pos->add(0.5, 0.5, 0.5), 13) and !$this->isSpectator()){ + $item = $this->inventory->getItemInHand(); //this is a copy of the real item + if($this->level->useItemOn($pos, $item, $face, $clickOffset, $this, true)){ + if($this->isSurvival() and !$item->equalsExact($this->inventory->getItemInHand())){ + $this->inventory->setItemInHand($item); + $this->inventory->sendHeldItem($this->hasSpawned); + } + return true; + } + } + + $this->inventory->sendHeldItem($this); + + if($pos->distanceSquared($this) > 10000){ + return true; + } + + $target = $this->level->getBlock($pos); + $block = $target->getSide($face); + + /** @var Block[] $blocks */ + $blocks = array_merge($target->getAllSides(), $block->getAllSides()); //getAllSides() on each of these will include $target and $block because they are next to each other + + $this->level->sendBlocks([$this], $blocks, UpdateBlockPacket::FLAG_ALL_PRIORITY); + + return false; + } + + /** + * Attacks the given entity with the currently-held item. + * TODO: move this up the class hierarchy + * + * @param Entity $entity + * + * @return bool if the entity was dealt damage + */ + public function attackEntity(Entity $entity) : bool{ + if(!$entity->isAlive()){ + return false; + } + if($entity instanceof ItemEntity or $entity instanceof Arrow){ + $this->kick("Attempting to attack an invalid entity"); + $this->server->getLogger()->warning($this->getServer()->getLanguage()->translateString("pocketmine.player.invalidEntity", [$this->getName()])); + return false; + } + + $heldItem = $this->inventory->getItemInHand(); + + $ev = new EntityDamageByEntityEvent($this, $entity, EntityDamageEvent::CAUSE_ENTITY_ATTACK, $heldItem->getAttackPoints()); + if(!$this->canInteract($entity, 8) or ($entity instanceof Player and !$this->server->getConfigBool("pvp"))){ + $ev->setCancelled(); + } + + $meleeEnchantmentDamage = 0; + /** @var EnchantmentInstance[] $meleeEnchantments */ + $meleeEnchantments = []; + foreach($heldItem->getEnchantments() as $enchantment){ + $type = $enchantment->getType(); + if($type instanceof MeleeWeaponEnchantment and $type->isApplicableTo($entity)){ + $meleeEnchantmentDamage += $type->getDamageBonus($enchantment->getLevel()); + $meleeEnchantments[] = $enchantment; + } + } + $ev->setModifier($meleeEnchantmentDamage, EntityDamageEvent::MODIFIER_WEAPON_ENCHANTMENTS); + + if(!$this->isSprinting() and !$this->isFlying() and $this->fallDistance > 0 and !$this->hasEffect(Effect::BLINDNESS) and !$this->isUnderwater()){ + $ev->setModifier($ev->getFinalDamage() / 2, EntityDamageEvent::MODIFIER_CRITICAL); + } + + $entity->attack($ev); + + if($ev->isCancelled()){ + if($heldItem instanceof Durable and $this->isSurvival()){ + $this->inventory->sendContents($this); + } + return false; + } + + if($ev->getModifier(EntityDamageEvent::MODIFIER_CRITICAL) > 0){ + $pk = new AnimatePacket(); + $pk->action = AnimatePacket::ACTION_CRITICAL_HIT; + $pk->entityRuntimeId = $entity->getId(); + $this->server->broadcastPacket($entity->getViewers(), $pk); + if($entity instanceof Player){ + $entity->sendDataPacket($pk); + } + } + + foreach($meleeEnchantments as $enchantment){ + $type = $enchantment->getType(); + assert($type instanceof MeleeWeaponEnchantment); + $type->onPostAttack($this, $entity, $enchantment->getLevel()); + } + + if($this->isAlive()){ + //reactive damage like thorns might cause us to be killed by attacking another mob, which + //would mean we'd already have dropped the inventory by the time we reached here + if($heldItem->onAttackEntity($entity) and $this->isSurvival()){ //always fire the hook, even if we are survival + $this->inventory->setItemInHand($heldItem); + } + + $this->exhaust(0.3, PlayerExhaustEvent::CAUSE_ATTACK); + } + + return true; + } + + /** + * Interacts with the given entity using the currently-held item. + * + * @param Entity $entity + * @param Vector3 $clickPos + * + * @return bool + */ + public function interactEntity(Entity $entity, Vector3 $clickPos) : bool{ + //TODO + return false; + } + public function toggleSprint(bool $sprint) : void{ $ev = new PlayerToggleSprintEvent($this, $sprint); $this->server->getPluginManager()->callEvent($ev); diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index a30f247a98..ecdaef7adc 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -23,6 +23,10 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; +use pocketmine\inventory\transaction\action\InventoryAction; +use pocketmine\inventory\transaction\CraftingTransaction; +use pocketmine\inventory\transaction\InventoryTransaction; +use pocketmine\inventory\transaction\TransactionValidationException; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; @@ -70,6 +74,9 @@ class SimpleSessionHandler extends SessionHandler{ /** @var Player */ private $player; + /** @var CraftingTransaction|null */ + protected $craftingTransaction = null; + public function __construct(Player $player){ $this->player = $player; } @@ -95,7 +102,131 @@ class SimpleSessionHandler extends SessionHandler{ } public function handleInventoryTransaction(InventoryTransactionPacket $packet) : bool{ - return $this->player->handleInventoryTransaction($packet); + if($this->player->isSpectator()){ + $this->player->sendAllInventories(); + return true; + } + + /** @var InventoryAction[] $actions */ + $actions = []; + foreach($packet->actions as $networkInventoryAction){ + try{ + $action = $networkInventoryAction->createInventoryAction($this->player); + if($action !== null){ + $actions[] = $action; + } + }catch(\Exception $e){ + $this->player->getServer()->getLogger()->debug("Unhandled inventory action from " . $this->player->getName() . ": " . $e->getMessage()); + $this->player->sendAllInventories(); + return false; + } + } + + if($packet->isCraftingPart){ + if($this->craftingTransaction === null){ + $this->craftingTransaction = new CraftingTransaction($this->player, $actions); + }else{ + foreach($actions as $action){ + $this->craftingTransaction->addAction($action); + } + } + + if($packet->isFinalCraftingPart){ + //we get the actions for this in several packets, so we need to wait until we have all the pieces before + //trying to execute it + + $ret = true; + try{ + $this->craftingTransaction->execute(); + }catch(TransactionValidationException $e){ + $this->player->getServer()->getLogger()->debug("Failed to execute crafting transaction for " . $this->player->getName() . ": " . $e->getMessage()); + $ret = false; + } + + $this->craftingTransaction = null; + return $ret; + } + + return true; + } + if($this->craftingTransaction !== null){ + $this->player->getServer()->getLogger()->debug("Got unexpected normal inventory action with incomplete crafting transaction from " . $this->player->getName() . ", refusing to execute crafting"); + $this->craftingTransaction = null; + } + + switch($packet->transactionType){ + case InventoryTransactionPacket::TYPE_NORMAL: + $transaction = new InventoryTransaction($this->player, $actions); + + try{ + $transaction->execute(); + }catch(TransactionValidationException $e){ + $this->player->getServer()->getLogger()->debug("Failed to execute inventory transaction from " . $this->player->getName() . ": " . $e->getMessage()); + $this->player->getServer()->getLogger()->debug("Actions: " . json_encode($packet->actions)); + + return false; + } + + //TODO: fix achievement for getting iron from furnace + + return true; + case InventoryTransactionPacket::TYPE_MISMATCH: + if(count($packet->actions) > 0){ + $this->player->getServer()->getLogger()->debug("Expected 0 actions for mismatch, got " . count($packet->actions) . ", " . json_encode($packet->actions)); + } + $this->player->sendAllInventories(); + + return true; + case InventoryTransactionPacket::TYPE_USE_ITEM: + $blockVector = new Vector3($packet->trData->x, $packet->trData->y, $packet->trData->z); + $face = $packet->trData->face; + + $type = $packet->trData->actionType; + switch($type){ + case InventoryTransactionPacket::USE_ITEM_ACTION_CLICK_BLOCK: + $this->player->interactBlock($blockVector, $face, $packet->trData->clickPos); + return true; + case InventoryTransactionPacket::USE_ITEM_ACTION_BREAK_BLOCK: + $this->player->breakBlock($blockVector); + return true; + case InventoryTransactionPacket::USE_ITEM_ACTION_CLICK_AIR: + $this->player->useHeldItem(); + return true; + } + break; + case InventoryTransactionPacket::TYPE_USE_ITEM_ON_ENTITY: + $target = $this->player->getLevel()->getEntity($packet->trData->entityRuntimeId); + if($target === null){ + return false; + } + + switch($packet->trData->actionType){ + case InventoryTransactionPacket::USE_ITEM_ON_ENTITY_ACTION_INTERACT: + $this->player->interactEntity($target, $packet->trData->clickPos); + return true; + case InventoryTransactionPacket::USE_ITEM_ON_ENTITY_ACTION_ATTACK: + $this->player->attackEntity($target); + return true; + } + + break; + case InventoryTransactionPacket::TYPE_RELEASE_ITEM: + switch($packet->trData->actionType){ + case InventoryTransactionPacket::RELEASE_ITEM_ACTION_RELEASE: + $this->player->releaseHeldItem(); + return true; + case InventoryTransactionPacket::RELEASE_ITEM_ACTION_CONSUME: + $this->player->consumeHeldItem(); + return true; + } + break; + default: + break; + + } + + $this->player->sendAllInventories(); + return false; } public function handleMobEquipment(MobEquipmentPacket $packet) : bool{ From a5383b4a82ebe2c1d144c8fba3e7db7adf154a6e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Aug 2018 10:45:41 +0100 Subject: [PATCH 0087/3224] Use SetLocalPlayerAsInitializedPacket for spawning, fixed a bunch of bugs this should fix forms not working during PlayerJoinEvent, and also removes the spurious PlayerItemHeldEvent firing on spawn bug. The player MUST now send this packet. Bots take note. --- src/pocketmine/Player.php | 28 +++++++++---------- .../network/mcpe/NetworkSession.php | 5 ++-- .../mcpe/handler/PreSpawnSessionHandler.php | 7 +++++ .../mcpe/handler/SimpleSessionHandler.php | 5 ---- 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 7c77c978da..cf9c99a852 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -910,10 +910,19 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $entity->spawnTo($this); } } - } + }elseif($this->chunkLoadCount >= $this->spawnThreshold){ + $this->spawned = true; - if($this->chunkLoadCount >= $this->spawnThreshold and !$this->spawned){ - $this->doFirstSpawn(); + foreach($this->usedChunks as $index => $c){ + Level::getXZ($index, $chunkX, $chunkZ); + foreach($this->level->getChunkEntities($chunkX, $chunkZ) as $entity){ + if($entity !== $this and !$entity->isClosed() and $entity->isAlive() and !$entity->isFlaggedForDespawn()){ + $entity->spawnTo($this); + } + } + } + + $this->networkSession->onTerrainReady(); } } @@ -951,9 +960,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ Timings::$playerChunkSendTimer->stopTiming(); } - protected function doFirstSpawn(){ - $this->spawned = true; - + public function doFirstSpawn(){ $this->networkSession->onSpawn(); if($this->hasPermission(Server::BROADCAST_CHANNEL_USERS)){ @@ -974,15 +981,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->noDamageTicks = 60; - foreach($this->usedChunks as $index => $c){ - Level::getXZ($index, $chunkX, $chunkZ); - foreach($this->level->getChunkEntities($chunkX, $chunkZ) as $entity){ - if($entity !== $this and !$entity->isClosed() and $entity->isAlive() and !$entity->isFlaggedForDespawn()){ - $entity->spawnTo($this); - } - } - } - $this->spawnToAll(); if($this->server->getUpdater()->hasUpdate() and $this->hasPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE) and $this->server->getProperty("auto-updater.on-update.warn-ops", true)){ diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index a00916c71a..f4d38224a3 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -317,12 +317,13 @@ class NetworkSession{ $this->setHandler(new PreSpawnSessionHandler($this->server, $this->player, $this)); } - public function onSpawn() : void{ + public function onTerrainReady() : void{ $pk = new PlayStatusPacket(); $pk->status = PlayStatusPacket::PLAYER_SPAWN; $this->sendDataPacket($pk); + } - //TODO: split this up even further + public function onSpawn() : void{ $this->setHandler(new SimpleSessionHandler($this->player)); } diff --git a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php index f3edfe9872..1c18c8aa95 100644 --- a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe\handler; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; +use pocketmine\network\mcpe\protocol\SetLocalPlayerAsInitializedPacket; use pocketmine\network\mcpe\protocol\StartGamePacket; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\Player; @@ -96,4 +97,10 @@ class PreSpawnSessionHandler extends SessionHandler{ return true; } + + public function handleSetLocalPlayerAsInitialized(SetLocalPlayerAsInitializedPacket $packet) : bool{ + $this->player->doFirstSpawn(); + + return true; + } } diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index ecdaef7adc..c479f0ca40 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -57,7 +57,6 @@ use pocketmine\network\mcpe\protocol\PlayerInputPacket; use pocketmine\network\mcpe\protocol\PlayerSkinPacket; use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; use pocketmine\network\mcpe\protocol\ServerSettingsRequestPacket; -use pocketmine\network\mcpe\protocol\SetLocalPlayerAsInitializedPacket; use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; use pocketmine\network\mcpe\protocol\ShowCreditsPacket; use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket; @@ -402,8 +401,4 @@ class SimpleSessionHandler extends SessionHandler{ public function handleLabTable(LabTablePacket $packet) : bool{ return false; //TODO } - - public function handleSetLocalPlayerAsInitialized(SetLocalPlayerAsInitializedPacket $packet) : bool{ - return false; //TODO - } } From 5df56a1baca6c8daa2679e0f9467865e8e35039c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Aug 2018 12:39:36 +0100 Subject: [PATCH 0088/3224] Clean up some AnimatePacket boilerplate code --- src/pocketmine/Player.php | 27 +++++++++++---------------- src/pocketmine/entity/Entity.php | 8 ++++++++ 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 7f8887907d..03346f1c4e 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1190,10 +1190,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->level->setSleepTicks(0); - $pk = new AnimatePacket(); - $pk->entityRuntimeId = $this->id; - $pk->action = AnimatePacket::ACTION_STOP_SLEEP; - $this->sendDataPacket($pk); + $this->broadcastAnimation([$this], AnimatePacket::ACTION_STOP_SLEEP); } } @@ -2349,13 +2346,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } if($ev->getModifier(EntityDamageEvent::MODIFIER_CRITICAL) > 0){ - $pk = new AnimatePacket(); - $pk->action = AnimatePacket::ACTION_CRITICAL_HIT; - $pk->entityRuntimeId = $entity->getId(); - $this->server->broadcastPacket($entity->getViewers(), $pk); - if($entity instanceof Player){ - $entity->sendDataPacket($pk); - } + $entity->broadcastAnimation(null, AnimatePacket::ACTION_CRITICAL_HIT); } foreach($meleeEnchantments as $enchantment){ @@ -2416,11 +2407,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return true; } - $pk = new AnimatePacket(); - $pk->entityRuntimeId = $this->getId(); - $pk->action = $ev->getAnimationType(); - $this->server->broadcastPacket($this->getViewers(), $pk); - + $this->broadcastAnimation($this->getViewers(), $ev->getAnimationType()); return true; } @@ -3088,6 +3075,14 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ parent::broadcastEntityEvent($eventId, $eventData, $players); } + public function broadcastAnimation(?array $players, int $animationId) : void{ + if($this->spawned and $players === null){ + $players = $this->getViewers(); + $players[] = $this; + } + parent::broadcastAnimation($players, $animationId); + } + public function getOffsetPosition(Vector3 $vector3) : Vector3{ $result = parent::getOffsetPosition($vector3); $result->y += 0.001; //Hack for MCPE falling underground for no good reason (TODO: find out why it's doing this) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 16ea367953..847182cc5a 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -63,6 +63,7 @@ use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\protocol\AddEntityPacket; +use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\MoveEntityAbsolutePacket; use pocketmine\network\mcpe\protocol\RemoveEntityPacket; @@ -2118,6 +2119,13 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->server->broadcastPacket($players ?? $this->getViewers(), $pk); } + public function broadcastAnimation(?array $players, int $animationId) : void{ + $pk = new AnimatePacket(); + $pk->entityRuntimeId = $this->id; + $pk->action = $animationId; + $this->server->broadcastPacket($players ?? $this->getViewers(), $pk); + } + public function __destruct(){ $this->close(); } From ea9415961b0c9e19bb813eb5fed50cc29d6994e0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Aug 2018 12:53:31 +0100 Subject: [PATCH 0089/3224] Player: remove useless check from dropItem() the transaction system will deal with this now, and if a plugin wants to make a player drop a null item, they are free to do so. --- src/pocketmine/Player.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 03346f1c4e..fa7b463247 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2418,11 +2418,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ * @return bool if the item was dropped or if the item was null */ public function dropItem(Item $item) : bool{ - if($item->isNull()){ - $this->server->getLogger()->debug($this->getName() . " attempted to drop a null item (" . $item . ")"); - return true; - } - $motion = $this->getDirectionVector()->multiply(0.4); $this->level->dropItem($this->add(0, 1.3, 0), $item, $motion, 40); From 90f80782d43bcfc18836531b19abd15632992de6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Aug 2018 12:55:12 +0100 Subject: [PATCH 0090/3224] Player: remove useless return value from dropItem() --- src/pocketmine/Player.php | 11 +++-------- .../inventory/transaction/action/DropItemAction.php | 3 ++- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index fa7b463247..f475deef5c 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2412,17 +2412,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } /** - * Drops an item on the ground in front of the player. Returns if the item drop was successful. + * Drops an item on the ground in front of the player. * * @param Item $item - * @return bool if the item was dropped or if the item was null */ - public function dropItem(Item $item) : bool{ - $motion = $this->getDirectionVector()->multiply(0.4); - - $this->level->dropItem($this->add(0, 1.3, 0), $item, $motion, 40); - - return true; + public function dropItem(Item $item) : void{ + $this->level->dropItem($this->add(0, 1.3, 0), $item, $this->getDirectionVector()->multiply(0.4), 40); } public function handleAdventureSettings(AdventureSettingsPacket $packet) : bool{ diff --git a/src/pocketmine/inventory/transaction/action/DropItemAction.php b/src/pocketmine/inventory/transaction/action/DropItemAction.php index 6605b5a39a..0753e93fdf 100644 --- a/src/pocketmine/inventory/transaction/action/DropItemAction.php +++ b/src/pocketmine/inventory/transaction/action/DropItemAction.php @@ -57,7 +57,8 @@ class DropItemAction extends InventoryAction{ * @return bool */ public function execute(Player $source) : bool{ - return $source->dropItem($this->targetItem); + $source->dropItem($this->targetItem); + return true; } public function onExecuteSuccess(Player $source) : void{ From 6fcb2214530c0078eaf650a1363fd287132991e7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Aug 2018 18:38:51 +0100 Subject: [PATCH 0091/3224] Remove useless crap from ChunkLoader interface these methods are not used anywhere and are unnecessary extra baggage for any implementation. --- src/pocketmine/Player.php | 4 ---- src/pocketmine/level/ChunkLoader.php | 17 ----------------- 2 files changed, 21 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index f475deef5c..fce29e750a 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -3352,8 +3352,4 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ public function getLoaderId() : int{ return $this->loaderId; } - - public function isLoaderActive() : bool{ - return $this->isConnected(); - } } diff --git a/src/pocketmine/level/ChunkLoader.php b/src/pocketmine/level/ChunkLoader.php index 144b551927..9f10e8ac10 100644 --- a/src/pocketmine/level/ChunkLoader.php +++ b/src/pocketmine/level/ChunkLoader.php @@ -47,18 +47,6 @@ interface ChunkLoader{ */ public function getLoaderId() : int; - /** - * Returns if the chunk loader is currently active - * - * @return bool - */ - public function isLoaderActive() : bool; - - /** - * @return Position - */ - public function getPosition(); - /** * @return float */ @@ -69,11 +57,6 @@ interface ChunkLoader{ */ public function getZ(); - /** - * @return Level - */ - public function getLevel(); - /** * This method will be called when a Chunk is replaced by a new one * From c90e3e351d254012d5c66bce6b5db8c083ccf58d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Aug 2018 19:07:23 +0100 Subject: [PATCH 0092/3224] PlayerBlockPickEvent: remove setResultItem() the same behaviour can be achieved by cancelling the event and setting the held item manually. Allowing this to be changed increases the complexity of dealing with survival block picking. --- src/pocketmine/Player.php | 2 +- src/pocketmine/event/player/PlayerBlockPickEvent.php | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index fce29e750a..965e462c8e 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2155,7 +2155,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->server->getPluginManager()->callEvent($ev); if(!$ev->isCancelled()){ - $this->inventory->setItemInHand($ev->getResultItem()); + $this->inventory->setItemInHand($item); } return true; diff --git a/src/pocketmine/event/player/PlayerBlockPickEvent.php b/src/pocketmine/event/player/PlayerBlockPickEvent.php index f4b1b5d821..d4a9f7f058 100644 --- a/src/pocketmine/event/player/PlayerBlockPickEvent.php +++ b/src/pocketmine/event/player/PlayerBlockPickEvent.php @@ -50,8 +50,4 @@ class PlayerBlockPickEvent extends PlayerEvent implements Cancellable{ public function getResultItem() : Item{ return $this->resultItem; } - - public function setResultItem(Item $item) : void{ - $this->resultItem = clone $item; - } } From ff6d590d0c7f0086224ac512101b7bb60ec3a28e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Aug 2018 19:31:21 +0100 Subject: [PATCH 0093/3224] PlayerInventory: Send updates to viewers automatically on setItemInHand() --- src/pocketmine/Player.php | 2 -- src/pocketmine/inventory/PlayerInventory.php | 7 ++++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 965e462c8e..222da34b58 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2227,7 +2227,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ if($this->isSurvival()){ if(!$item->equalsExact($this->inventory->getItemInHand())){ $this->inventory->setItemInHand($item); - $this->inventory->sendHeldItem($this->hasSpawned); } $this->exhaust(0.025, PlayerExhaustEvent::CAUSE_MINING); } @@ -2272,7 +2271,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ if($this->level->useItemOn($pos, $item, $face, $clickOffset, $this, true)){ if($this->isSurvival() and !$item->equalsExact($this->inventory->getItemInHand())){ $this->inventory->setItemInHand($item); - $this->inventory->sendHeldItem($this->hasSpawned); } return true; } diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index 6d43f5286d..aa915b2ca6 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -127,7 +127,12 @@ class PlayerInventory extends BaseInventory{ * @return bool */ public function setItemInHand(Item $item) : bool{ - return $this->setItem($this->getHeldItemIndex(), $item); + if($this->setItem($this->getHeldItemIndex(), $item)){ + $this->sendHeldItem($this->holder->getViewers()); + return true; + } + + return false; } /** From 4142666df89aed1a8b1eb8ce04069e2e735d367d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 6 Aug 2018 19:00:00 +0100 Subject: [PATCH 0094/3224] Level: clean up and remove checkTime() --- src/pocketmine/command/defaults/TimeCommand.php | 8 -------- src/pocketmine/level/Level.php | 16 +++------------- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/src/pocketmine/command/defaults/TimeCommand.php b/src/pocketmine/command/defaults/TimeCommand.php index c0c9ec4d70..e988e0fe92 100644 --- a/src/pocketmine/command/defaults/TimeCommand.php +++ b/src/pocketmine/command/defaults/TimeCommand.php @@ -54,9 +54,7 @@ class TimeCommand extends VanillaCommand{ return true; } foreach($sender->getServer()->getLevels() as $level){ - $level->checkTime(); $level->startTime(); - $level->checkTime(); } Command::broadcastCommandMessage($sender, "Restarted the time"); return true; @@ -67,9 +65,7 @@ class TimeCommand extends VanillaCommand{ return true; } foreach($sender->getServer()->getLevels() as $level){ - $level->checkTime(); $level->stopTime(); - $level->checkTime(); } Command::broadcastCommandMessage($sender, "Stopped the time"); return true; @@ -109,9 +105,7 @@ class TimeCommand extends VanillaCommand{ } foreach($sender->getServer()->getLevels() as $level){ - $level->checkTime(); $level->setTime($value); - $level->checkTime(); } Command::broadcastCommandMessage($sender, new TranslationContainer("commands.time.set", [$value])); }elseif($args[0] === "add"){ @@ -123,9 +117,7 @@ class TimeCommand extends VanillaCommand{ $value = $this->getInteger($sender, $args[1], 0); foreach($sender->getServer()->getLevels() as $level){ - $level->checkTime(); $level->setTime($level->getTime() + $value); - $level->checkTime(); } Command::broadcastCommandMessage($sender, new TranslationContainer("commands.time.added", [$value])); }else{ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 80b1cd38a8..b8231d979b 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -653,18 +653,6 @@ class Level implements ChunkManager, Metadatable{ } } - /** - * WARNING: Do not use this, it's only for internal use. - * Changes to this function won't be recorded on the version. - */ - public function checkTime(){ - if($this->stopTime){ - return; - }else{ - ++$this->time; - } - } - /** * WARNING: Do not use this, it's only for internal use. * Changes to this function won't be recorded on the version. @@ -696,7 +684,9 @@ class Level implements ChunkManager, Metadatable{ $this->timings->doTick->startTiming(); - $this->checkTime(); + if(!$this->stopTime){ + $this->time++; + } $this->sunAnglePercentage = $this->computeSunAnglePercentage(); //Sun angle depends on the current time $this->skyLightReduction = $this->computeSkyLightReduction(); //Sky light reduction depends on the sun angle From 55ac1c80c995fbe634034f92da67fb3064cb4e7b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Aug 2018 17:33:57 +0100 Subject: [PATCH 0095/3224] Player: replace redundant usage of Server->broadcast() --- src/pocketmine/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 222da34b58..bb493742da 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2982,7 +2982,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } if($ev->getDeathMessage() != ""){ - $this->server->broadcast($ev->getDeathMessage(), Server::BROADCAST_CHANNEL_USERS); + $this->server->broadcastMessage($ev->getDeathMessage()); } } From 16b789a52871579c14a1032af72e22f2a75d014a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Aug 2018 17:37:55 +0100 Subject: [PATCH 0096/3224] Player: remove useless checks from save() this should never be called for a player with an empty username (because data isn't saved unless the player was spawned) and the instanceof is laughable. --- src/pocketmine/Player.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index bb493742da..6ac2a80ac2 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2945,9 +2945,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->namedtag->setInt("playerGameType", $this->gamemode); $this->namedtag->setLong("lastPlayed", (int) floor(microtime(true) * 1000)); - if($this->username != "" and $this->namedtag instanceof CompoundTag){ - $this->server->saveOfflinePlayerData($this->username, $this->namedtag, $async); - } + $this->server->saveOfflinePlayerData($this->username, $this->namedtag, $async); } public function kill() : void{ From ec9ef891ee6ce4e6d676e899cbda5284c67c17cb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Aug 2018 18:27:22 +0100 Subject: [PATCH 0097/3224] Player: clean up some runtime usages of NBT the goal is to get rid of this completely, but that's slightly complicated by the mess that is player creation right now. --- src/pocketmine/Player.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 6ac2a80ac2..3cf8aff790 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -203,8 +203,10 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ /** @var bool[] name of achievement => bool */ protected $achievements = []; - /** @var bool */ - protected $playedBefore; + /** @var int */ + protected $firstPlayed; + /** @var int */ + protected $lastPlayed; /** @var int */ protected $gamemode; @@ -358,15 +360,15 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } public function getFirstPlayed(){ - return $this->namedtag instanceof CompoundTag ? $this->namedtag->getLong("firstPlayed", 0, true) : null; + return $this->firstPlayed; } public function getLastPlayed(){ - return $this->namedtag instanceof CompoundTag ? $this->namedtag->getLong("lastPlayed", 0, true) : null; + return $this->lastPlayed; } public function hasPlayedBefore() : bool{ - return $this->playedBefore; + return $this->lastPlayed - $this->firstPlayed > 1; // microtime(true) - microtime(true) may have less than one millisecond difference } public function setAllowFlight(bool $value){ @@ -1307,7 +1309,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->resetFallDistance(); - $this->namedtag->setInt("playerGameType", $this->gamemode); if(!$client){ //Gamemode changed by server, do not send for client changes $this->sendGamemode(); }else{ @@ -1891,12 +1892,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ parent::initEntity(); $this->addDefaultWindows(); - $this->playedBefore = ($this->getLastPlayed() - $this->getFirstPlayed()) > 1; // microtime(true) - microtime(true) may have less than one millisecond difference + $this->firstPlayed = $this->namedtag->getLong("firstPlayed", $now = (int) (microtime(true) * 1000)); + $this->lastPlayed = $this->namedtag->getLong("lastPlayed", $now); $this->gamemode = $this->namedtag->getInt("playerGameType", self::SURVIVAL) & 0x03; if($this->server->getForceGamemode()){ $this->gamemode = $this->server->getGamemode(); - $this->namedtag->setInt("playerGameType", $this->gamemode); } $this->setAllowFlight($this->isCreative()); @@ -2943,6 +2944,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->namedtag->setTag($achievements); $this->namedtag->setInt("playerGameType", $this->gamemode); + $this->namedtag->setLong("firstPlayed", $this->firstPlayed); $this->namedtag->setLong("lastPlayed", (int) floor(microtime(true) * 1000)); $this->server->saveOfflinePlayerData($this->username, $this->namedtag, $async); From 9c94ebcf82a0bda6fd5ee64defa56f7a97c39410 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 8 Aug 2018 16:58:13 +0100 Subject: [PATCH 0098/3224] Updated DevTools submodule to get bloat fixes --- tests/plugins/PocketMine-DevTools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/plugins/PocketMine-DevTools b/tests/plugins/PocketMine-DevTools index 2491457a82..3318ac4c0e 160000 --- a/tests/plugins/PocketMine-DevTools +++ b/tests/plugins/PocketMine-DevTools @@ -1 +1 @@ -Subproject commit 2491457a82fe4b759a6a899bbe57fc62053dcc06 +Subproject commit 3318ac4c0e6c0ea1bc7eb2d0f4e66a038ae581a9 From 0d9968f305ff902d0ff57722f3f444ba5188d9d4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 11 Aug 2018 15:22:58 +0100 Subject: [PATCH 0099/3224] Added donation methods --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 59ef84bf66..15e616927d 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,12 @@ Yes you can! Contributions are welcomed provided that they comply with our [Cont **Note: Please avoid development builds unless there is no other alternative for what you need.** Development builds are subject to changes at any time without notice, and it is likely that your server or plugins might break without warning. +### Donate +Donations help support the development of the project and pay for our expenses. +- Bitcoin Cash (BCH): `qz9p8dqkv0r7aahdatu5uewqfkvstrglv58f8yle07` +- Bitcoin (BTC): `1PVAyDJ2g7kcjCxAC3C89oxpV2ZYcLad8T` +- [Patreon](https://www.patreon.com/pocketminemp) + ## Licensing information This program is free software: you can redistribute it and/or modify From 10f14beb4b5b640cfdc89b4953f2f13c652913dc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 11 Aug 2018 19:12:04 +0100 Subject: [PATCH 0100/3224] Fixed intermittent crash on player disconnect when async compression is enabled --- src/pocketmine/Server.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 42fb57521c..2c9e5d0f6f 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1941,7 +1941,9 @@ class Server{ public function broadcastPacketsCallback(string $payload, array $sessions, bool $immediate = false){ /** @var NetworkSession $session */ foreach($sessions as $session){ - $session->sendEncoded($payload, $immediate); + if($session->isConnected()){ + $session->sendEncoded($payload, $immediate); + } } } From 15bac8c58adff26c66c5119829af89db83ef8621 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 13 Aug 2018 14:37:18 +0100 Subject: [PATCH 0101/3224] Implement send buffering and queuing for network sessions (#2358) Async compression and broadcasts are now reliable and don't have race condition bugs. This features improved performance and significantly reduced bandwidth wastage. Reduce Level broadcast latency by ticking network after levels. This ensures that session buffers get flushed as soon as possible after level tick, if level broadcasts were done. --- src/pocketmine/Player.php | 5 +- src/pocketmine/Server.php | 66 +++++++-------- src/pocketmine/inventory/CraftingManager.php | 11 ++- src/pocketmine/level/Level.php | 49 +++++++----- .../network/mcpe/ChunkRequestTask.php | 18 ++--- .../network/mcpe/CompressBatchPromise.php | 62 ++++++++++++++ ...sBatchedTask.php => CompressBatchTask.php} | 19 +++-- .../network/mcpe/NetworkSession.php | 80 +++++++++++++++++-- .../mcpe/handler/PreSpawnSessionHandler.php | 2 +- 9 files changed, 225 insertions(+), 87 deletions(-) create mode 100644 src/pocketmine/network/mcpe/CompressBatchPromise.php rename src/pocketmine/network/mcpe/{CompressBatchedTask.php => CompressBatchTask.php} (72%) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 3cf8aff790..7aa78cb65d 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -90,6 +90,7 @@ use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\ListTag; +use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\NetworkCipher; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; @@ -894,7 +895,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ unset($this->loadQueue[$index]); } - public function sendChunk(int $x, int $z, string $payload){ + public function sendChunk(int $x, int $z, CompressBatchPromise $promise){ if(!$this->isConnected()){ return; } @@ -902,7 +903,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->usedChunks[Level::chunkHash($x, $z)] = true; $this->chunkLoadCount++; - $this->networkSession->sendEncoded($payload); + $this->networkSession->queueCompressed($promise); if($this->spawned){ foreach($this->level->getChunkEntities($x, $z) as $entity){ diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 2c9e5d0f6f..528e1743b8 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -71,7 +71,8 @@ use pocketmine\nbt\tag\LongTag; use pocketmine\nbt\tag\ShortTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\AdvancedNetworkInterface; -use pocketmine\network\mcpe\CompressBatchedTask; +use pocketmine\network\mcpe\CompressBatchPromise; +use pocketmine\network\mcpe\CompressBatchTask; use pocketmine\network\mcpe\NetworkCipher; use pocketmine\network\mcpe\NetworkCompression; use pocketmine\network\mcpe\NetworkSession; @@ -1899,55 +1900,54 @@ class Server{ $stream->putPacket($packet); } - //TODO: if under the compression threshold, add to session buffers instead of batching (first we need to implement buffering!) - $this->batchPackets($targets, $stream); + if(NetworkCompression::$THRESHOLD < 0 or strlen($stream->buffer) < NetworkCompression::$THRESHOLD){ + foreach($targets as $target){ + foreach($ev->getPackets() as $pk){ + $target->addToSendBuffer($pk); + } + } + }else{ + $promise = $this->prepareBatch($stream); + foreach($targets as $target){ + $target->queueCompressed($promise); + } + } + return true; } /** * Broadcasts a list of packets in a batch to a list of players * - * @param NetworkSession[] $targets - * @param PacketStream $stream - * @param bool $forceSync - * @param bool $immediate + * @param PacketStream $stream + * @param bool $forceSync + * + * @return CompressBatchPromise */ - public function batchPackets(array $targets, PacketStream $stream, bool $forceSync = false, bool $immediate = false){ - Timings::$playerNetworkSendCompressTimer->startTiming(); + public function prepareBatch(PacketStream $stream, bool $forceSync = false) : CompressBatchPromise{ + try{ + Timings::$playerNetworkSendCompressTimer->startTiming(); - if(!empty($targets)){ $compressionLevel = NetworkCompression::$LEVEL; if(NetworkCompression::$THRESHOLD < 0 or strlen($stream->buffer) < NetworkCompression::$THRESHOLD){ $compressionLevel = 0; //Do not compress packets under the threshold $forceSync = true; } - if(!$forceSync and !$immediate and $this->networkCompressionAsync){ - $task = new CompressBatchedTask($stream, $targets, $compressionLevel); + $promise = new CompressBatchPromise(); + if(!$forceSync and $this->networkCompressionAsync){ + $task = new CompressBatchTask($stream, $compressionLevel, $promise); $this->asyncPool->submitTask($task); }else{ - $this->broadcastPacketsCallback(NetworkCompression::compress($stream->buffer), $targets, $immediate); + $promise->resolve(NetworkCompression::compress($stream->buffer)); } - } - Timings::$playerNetworkSendCompressTimer->stopTiming(); - } - - /** - * @param string $payload - * @param NetworkSession[] $sessions - * @param bool $immediate - */ - public function broadcastPacketsCallback(string $payload, array $sessions, bool $immediate = false){ - /** @var NetworkSession $session */ - foreach($sessions as $session){ - if($session->isConnected()){ - $session->sendEncoded($payload, $immediate); - } + return $promise; + }finally{ + Timings::$playerNetworkSendCompressTimer->stopTiming(); } } - /** * @param int $type */ @@ -2542,10 +2542,6 @@ class Server{ ++$this->tickCounter; - Timings::$connectionTimer->startTiming(); - $this->network->tick(); - Timings::$connectionTimer->stopTiming(); - Timings::$schedulerTimer->startTiming(); $this->pluginManager->tickSchedulers($this->tickCounter); Timings::$schedulerTimer->stopTiming(); @@ -2556,6 +2552,10 @@ class Server{ $this->checkTickUpdates($this->tickCounter); + Timings::$connectionTimer->startTiming(); + $this->network->tick(); + Timings::$connectionTimer->stopTiming(); + if(($this->tickCounter % 20) === 0){ if($this->doTitleTick){ $this->titleTick(); diff --git a/src/pocketmine/inventory/CraftingManager.php b/src/pocketmine/inventory/CraftingManager.php index 414294d91a..0b51e998ab 100644 --- a/src/pocketmine/inventory/CraftingManager.php +++ b/src/pocketmine/inventory/CraftingManager.php @@ -25,6 +25,7 @@ namespace pocketmine\inventory; use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\NetworkCompression; use pocketmine\network\mcpe\PacketStream; use pocketmine\network\mcpe\protocol\CraftingDataPacket; @@ -38,7 +39,7 @@ class CraftingManager{ /** @var FurnaceRecipe[] */ protected $furnaceRecipes = []; - /** @var string */ + /** @var CompressBatchPromise */ private $craftingDataCache; public function __construct(){ @@ -105,16 +106,18 @@ class CraftingManager{ $batch = new PacketStream(); $batch->putPacket($pk); - $this->craftingDataCache = NetworkCompression::compress($batch->buffer); + $this->craftingDataCache = new CompressBatchPromise(); + $this->craftingDataCache->resolve(NetworkCompression::compress($batch->buffer)); + Timings::$craftingDataCacheRebuildTimer->stopTiming(); } /** * Returns a pre-compressed CraftingDataPacket for sending to players. Rebuilds the cache if it is not found. * - * @return string + * @return CompressBatchPromise */ - public function getCraftingDataPacket() : string{ + public function getCraftingDataPacket() : CompressBatchPromise{ if($this->craftingDataCache === null){ $this->buildCraftingDataCache(); } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index b8231d979b..a7c0613fff 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -69,6 +69,7 @@ use pocketmine\metadata\MetadataValue; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\ChunkRequestTask; +use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; @@ -122,7 +123,7 @@ class Level implements ChunkManager, Metadatable{ /** @var Block[][] */ private $blockCache = []; - /** @var string[] */ + /** @var CompressBatchPromise[] */ private $chunkCache = []; /** @var int */ @@ -2451,7 +2452,7 @@ class Level implements ChunkManager, Metadatable{ $this->chunkSendQueue[$index][$player->getLoaderId()] = $player; } - private function sendChunkFromCache(int $x, int $z){ + private function sendCachedChunk(int $x, int $z){ if(isset($this->chunkSendQueue[$index = Level::chunkHash($x, $z)])){ foreach($this->chunkSendQueue[$index] as $player){ /** @var Player $player */ @@ -2479,10 +2480,12 @@ class Level implements ChunkManager, Metadatable{ continue; } } + if(isset($this->chunkCache[$index])){ - $this->sendChunkFromCache($x, $z); + $this->sendCachedChunk($x, $z); continue; } + $this->timings->syncChunkSendPrepareTimer->startTiming(); $chunk = $this->chunks[$index] ?? null; @@ -2491,7 +2494,30 @@ class Level implements ChunkManager, Metadatable{ } assert($chunk->getX() === $x and $chunk->getZ() === $z, "Chunk coordinate mismatch: expected $x $z, but chunk has coordinates " . $chunk->getX() . " " . $chunk->getZ() . ", did you forget to clone a chunk before setting?"); - $this->server->getAsyncPool()->submitTask($task = new ChunkRequestTask($this, $x, $z, $chunk)); + /* + * we don't send promises directly to the players here because unresolved promises of chunk sending + * would slow down the sending of other packets, especially if a chunk takes a long time to prepare. + */ + + $promise = new CompressBatchPromise(); + $promise->onResolve(function(CompressBatchPromise $promise) use ($x, $z, $index): void{ + if(!$this->closed){ + $this->timings->syncChunkSendTimer->startTiming(); + + unset($this->chunkSendTasks[$index]); + + $this->chunkCache[$index] = $promise; + $this->sendCachedChunk($x, $z); + if(!$this->server->getMemoryManager()->canUseChunkCache()){ + unset($this->chunkCache[$index]); + } + + $this->timings->syncChunkSendTimer->stopTiming(); + }else{ + $this->server->getLogger()->debug("Dropped prepared chunk $x $z due to level not loaded"); + } + }); + $this->server->getAsyncPool()->submitTask($task = new ChunkRequestTask($x, $z, $chunk, $promise)); $this->chunkSendTasks[$index] = $task; $this->timings->syncChunkSendPrepareTimer->stopTiming(); @@ -2501,21 +2527,6 @@ class Level implements ChunkManager, Metadatable{ } } - public function chunkRequestCallback(int $x, int $z, string $payload){ - $this->timings->syncChunkSendTimer->startTiming(); - - $index = Level::chunkHash($x, $z); - unset($this->chunkSendTasks[$index]); - - $this->chunkCache[$index] = $payload; - $this->sendChunkFromCache($x, $z); - if(!$this->server->getMemoryManager()->canUseChunkCache()){ - unset($this->chunkCache[$index]); - } - - $this->timings->syncChunkSendTimer->stopTiming(); - } - /** * @param Entity $entity * diff --git a/src/pocketmine/network/mcpe/ChunkRequestTask.php b/src/pocketmine/network/mcpe/ChunkRequestTask.php index b12d31db11..885bb44f4f 100644 --- a/src/pocketmine/network/mcpe/ChunkRequestTask.php +++ b/src/pocketmine/network/mcpe/ChunkRequestTask.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; use pocketmine\level\format\Chunk; -use pocketmine\level\Level; use pocketmine\network\mcpe\protocol\FullChunkDataPacket; use pocketmine\scheduler\AsyncTask; use pocketmine\Server; @@ -42,8 +41,7 @@ class ChunkRequestTask extends AsyncTask{ /** @var int */ protected $compressionLevel; - public function __construct(Level $level, int $chunkX, int $chunkZ, Chunk $chunk){ - $this->storeLocal($level); + public function __construct(int $chunkX, int $chunkZ, Chunk $chunk, CompressBatchPromise $promise){ $this->compressionLevel = NetworkCompression::$LEVEL; $this->chunk = $chunk->fastSerialize(); @@ -59,6 +57,8 @@ class ChunkRequestTask extends AsyncTask{ } $this->tiles = $tiles; + + $this->storeLocal($promise); } public function onRun() : void{ @@ -76,14 +76,8 @@ class ChunkRequestTask extends AsyncTask{ } public function onCompletion(Server $server) : void{ - /** @var Level $level */ - $level = $this->fetchLocal(); - if(!$level->isClosed()){ - if($this->hasResult()){ - $level->chunkRequestCallback($this->chunkX, $this->chunkZ, $this->getResult()); - }else{ - $level->getServer()->getLogger()->error("Chunk request for level " . $level->getName() . ", x=" . $this->chunkX . ", z=" . $this->chunkZ . " doesn't have any result data"); - } - } + /** @var CompressBatchPromise $promise */ + $promise = $this->fetchLocal(); + $promise->resolve($this->getResult()); } } diff --git a/src/pocketmine/network/mcpe/CompressBatchPromise.php b/src/pocketmine/network/mcpe/CompressBatchPromise.php new file mode 100644 index 0000000000..6707c08c28 --- /dev/null +++ b/src/pocketmine/network/mcpe/CompressBatchPromise.php @@ -0,0 +1,62 @@ +result !== null){ + $callback($this); + }else{ + $this->callbacks[] = $callback; + } + } + + public function resolve(string $result) : void{ + if($this->result !== null){ + throw new \InvalidStateException("Cannot resolve promise more than once"); + } + $this->result = $result; + foreach($this->callbacks as $callback){ + $callback($this); + } + $this->callbacks = []; + } + + public function getResult() : string{ + if($this->result === null){ + throw new \InvalidStateException("Promise has not yet been resolved"); + } + return $this->result; + } + + public function hasResult() : bool{ + return $this->result !== null; + } +} diff --git a/src/pocketmine/network/mcpe/CompressBatchedTask.php b/src/pocketmine/network/mcpe/CompressBatchTask.php similarity index 72% rename from src/pocketmine/network/mcpe/CompressBatchedTask.php rename to src/pocketmine/network/mcpe/CompressBatchTask.php index c9366b22a0..8604603157 100644 --- a/src/pocketmine/network/mcpe/CompressBatchedTask.php +++ b/src/pocketmine/network/mcpe/CompressBatchTask.php @@ -26,20 +26,20 @@ namespace pocketmine\network\mcpe; use pocketmine\scheduler\AsyncTask; use pocketmine\Server; -class CompressBatchedTask extends AsyncTask{ +class CompressBatchTask extends AsyncTask{ private $level; private $data; /** - * @param PacketStream $stream - * @param NetworkSession[] $targets - * @param int $compressionLevel + * @param PacketStream $stream + * @param int $compressionLevel + * @param CompressBatchPromise $promise */ - public function __construct(PacketStream $stream, array $targets, int $compressionLevel){ + public function __construct(PacketStream $stream, int $compressionLevel, CompressBatchPromise $promise){ $this->data = $stream->buffer; $this->level = $compressionLevel; - $this->storeLocal($targets); + $this->storeLocal($promise); } public function onRun() : void{ @@ -47,9 +47,8 @@ class CompressBatchedTask extends AsyncTask{ } public function onCompletion(Server $server) : void{ - /** @var NetworkSession[] $targets */ - $targets = $this->fetchLocal(); - - $server->broadcastPacketsCallback($this->getResult(), $targets); + /** @var CompressBatchPromise $promise */ + $promise = $this->fetchLocal(); + $promise->resolve($this->getResult()); } } diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index f4d38224a3..eff34d2020 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -68,12 +68,20 @@ class NetworkSession{ /** @var NetworkCipher */ private $cipher; + /** @var PacketStream|null */ + private $sendBuffer; + + /** @var \SplQueue|CompressBatchPromise[] */ + private $compressedQueue; + public function __construct(Server $server, NetworkInterface $interface, string $ip, int $port){ $this->server = $server; $this->interface = $interface; $this->ip = $ip; $this->port = $port; + $this->compressedQueue = new \SplQueue(); + $this->connectTime = time(); $this->server->getNetwork()->scheduleSessionTick($this); @@ -206,10 +214,10 @@ class NetworkSession{ return false; } - //TODO: implement buffering (this is just a quick fix) - $stream = new PacketStream(); - $stream->putPacket($packet); - $this->server->batchPackets([$this], $stream, true, $immediate); + $this->addToSendBuffer($packet); + if($immediate){ + $this->flushSendBuffer(true); + } return true; }finally{ @@ -217,7 +225,62 @@ class NetworkSession{ } } - public function sendEncoded(string $payload, bool $immediate = false) : void{ + /** + * @internal + * @param DataPacket $packet + */ + public function addToSendBuffer(DataPacket $packet) : void{ + $timings = Timings::getSendDataPacketTimings($packet); + $timings->startTiming(); + try{ + if($this->sendBuffer === null){ + $this->sendBuffer = new PacketStream(); + } + $this->sendBuffer->putPacket($packet); + $this->server->getNetwork()->scheduleSessionTick($this); + }finally{ + $timings->stopTiming(); + } + } + + private function flushSendBuffer(bool $immediate = false) : void{ + if($this->sendBuffer !== null){ + $promise = $this->server->prepareBatch($this->sendBuffer, $immediate); + $this->sendBuffer = null; + $this->queueCompressed($promise, $immediate); + } + } + + public function queueCompressed(CompressBatchPromise $payload, bool $immediate = false) : void{ + $this->flushSendBuffer($immediate); //Maintain ordering if possible + if($immediate){ + //Skips all queues + $this->sendEncoded($payload->getResult(), true); + }else{ + $this->compressedQueue->enqueue($payload); + $payload->onResolve(function(CompressBatchPromise $payload) : void{ + if($this->connected and $this->compressedQueue->bottom() === $payload){ + $this->compressedQueue->dequeue(); //result unused + $this->sendEncoded($payload->getResult()); + + while(!$this->compressedQueue->isEmpty()){ + /** @var CompressBatchPromise $current */ + $current = $this->compressedQueue->bottom(); + if($current->hasResult()){ + $this->compressedQueue->dequeue(); + + $this->sendEncoded($current->getResult()); + }else{ + //can't send any more queued until this one is ready + break; + } + } + } + }); + } + } + + private function sendEncoded(string $payload, bool $immediate = false) : void{ if($this->cipher !== null){ Timings::$playerNetworkSendEncryptTimer->startTiming(); $payload = $this->cipher->encrypt($payload); @@ -289,6 +352,8 @@ class NetworkSession{ $this->handler = null; $this->interface = null; $this->player = null; + $this->sendBuffer = null; + $this->compressedQueue = null; } public function enableEncryption(string $encryptionKey, string $handshakeJwt) : void{ @@ -345,7 +410,10 @@ class NetworkSession{ return true; //keep ticking until timeout } - //TODO: more stuff on tick + if($this->sendBuffer !== null){ + $this->flushSendBuffer(); + } + return false; } } diff --git a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php index 1c18c8aa95..69083f0147 100644 --- a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php @@ -87,7 +87,7 @@ class PreSpawnSessionHandler extends SessionHandler{ $this->player->sendAllInventories(); $this->player->getInventory()->sendCreativeContents(); $this->player->getInventory()->sendHeldItem($this->player); - $this->session->sendEncoded($this->server->getCraftingManager()->getCraftingDataPacket()); + $this->session->queueCompressed($this->server->getCraftingManager()->getCraftingDataPacket()); $this->server->sendFullPlayerListData($this->player); } From 78671bafe39a44dba606355e14881d15dc9a2b95 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 13 Aug 2018 15:52:55 +0100 Subject: [PATCH 0102/3224] Remove unnecessary DataPacket->encode() calls --- src/pocketmine/inventory/ArmorInventory.php | 2 -- src/pocketmine/inventory/CraftingManager.php | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/pocketmine/inventory/ArmorInventory.php b/src/pocketmine/inventory/ArmorInventory.php index 5d19a8a7c2..d0fed611f3 100644 --- a/src/pocketmine/inventory/ArmorInventory.php +++ b/src/pocketmine/inventory/ArmorInventory.php @@ -98,7 +98,6 @@ class ArmorInventory extends BaseInventory{ $pk = new MobArmorEquipmentPacket(); $pk->entityRuntimeId = $this->getHolder()->getId(); $pk->slots = $armor; - $pk->encode(); foreach($target as $player){ if($player === $this->getHolder()){ @@ -125,7 +124,6 @@ class ArmorInventory extends BaseInventory{ $pk = new MobArmorEquipmentPacket(); $pk->entityRuntimeId = $this->getHolder()->getId(); $pk->slots = $armor; - $pk->encode(); foreach($target as $player){ if($player === $this->getHolder()){ diff --git a/src/pocketmine/inventory/CraftingManager.php b/src/pocketmine/inventory/CraftingManager.php index 0b51e998ab..b378af8ef7 100644 --- a/src/pocketmine/inventory/CraftingManager.php +++ b/src/pocketmine/inventory/CraftingManager.php @@ -101,8 +101,6 @@ class CraftingManager{ $pk->addFurnaceRecipe($recipe); } - $pk->encode(); - $batch = new PacketStream(); $batch->putPacket($pk); From f2fd505baee55dd6f3a25f445e2c2f784b433a60 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 13 Aug 2018 15:57:59 +0100 Subject: [PATCH 0103/3224] ArmorInventory: fixed missed usages of dataPacket() these were missed because PhpStorm couldn't infer the variable types in foreach, and there were no type docs to help it out. --- src/pocketmine/inventory/ArmorInventory.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/inventory/ArmorInventory.php b/src/pocketmine/inventory/ArmorInventory.php index d0fed611f3..e9e2815f45 100644 --- a/src/pocketmine/inventory/ArmorInventory.php +++ b/src/pocketmine/inventory/ArmorInventory.php @@ -100,16 +100,15 @@ class ArmorInventory extends BaseInventory{ $pk->slots = $armor; foreach($target as $player){ + /** @var Player $player */ if($player === $this->getHolder()){ - /** @var Player $player */ - $pk2 = new InventorySlotPacket(); $pk2->windowId = $player->getWindowId($this); $pk2->inventorySlot = $index; $pk2->item = $this->getItem($index); $player->sendDataPacket($pk2); }else{ - $player->dataPacket($pk); + $player->sendDataPacket($pk); } } } @@ -126,13 +125,14 @@ class ArmorInventory extends BaseInventory{ $pk->slots = $armor; foreach($target as $player){ + /** @var Player $player */ if($player === $this->getHolder()){ $pk2 = new InventoryContentPacket(); $pk2->windowId = $player->getWindowId($this); $pk2->items = $armor; - $player->dataPacket($pk2); + $player->sendDataPacket($pk2); }else{ - $player->dataPacket($pk); + $player->sendDataPacket($pk); } } } From 59a51a6c75344ded91218ed4918286694edb708e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 13 Aug 2018 16:12:25 +0100 Subject: [PATCH 0104/3224] ArmorInventory: use broadcast for sending armour updates --- src/pocketmine/inventory/ArmorInventory.php | 56 ++++++++++----------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/src/pocketmine/inventory/ArmorInventory.php b/src/pocketmine/inventory/ArmorInventory.php index e9e2815f45..8c279faabe 100644 --- a/src/pocketmine/inventory/ArmorInventory.php +++ b/src/pocketmine/inventory/ArmorInventory.php @@ -93,23 +93,21 @@ class ArmorInventory extends BaseInventory{ $target = [$target]; } - $armor = $this->getContents(true); + /** @var Player[] $target */ - $pk = new MobArmorEquipmentPacket(); - $pk->entityRuntimeId = $this->getHolder()->getId(); - $pk->slots = $armor; - - foreach($target as $player){ - /** @var Player $player */ - if($player === $this->getHolder()){ - $pk2 = new InventorySlotPacket(); - $pk2->windowId = $player->getWindowId($this); - $pk2->inventorySlot = $index; - $pk2->item = $this->getItem($index); - $player->sendDataPacket($pk2); - }else{ - $player->sendDataPacket($pk); - } + if(($k = array_search($this->holder, $target, true)) !== false){ + $pk = new InventorySlotPacket(); + $pk->windowId = $target[$k]->getWindowId($this); + $pk->inventorySlot = $index; + $pk->item = $this->getItem($index); + $target[$k]->sendDataPacket($pk); + unset($target[$k]); + } + if(!empty($target)){ + $pk = new MobArmorEquipmentPacket(); + $pk->entityRuntimeId = $this->getHolder()->getId(); + $pk->slots = $this->getContents(true); + $this->holder->getLevel()->getServer()->broadcastPacket($target, $pk); } } @@ -120,20 +118,18 @@ class ArmorInventory extends BaseInventory{ $armor = $this->getContents(true); - $pk = new MobArmorEquipmentPacket(); - $pk->entityRuntimeId = $this->getHolder()->getId(); - $pk->slots = $armor; - - foreach($target as $player){ - /** @var Player $player */ - if($player === $this->getHolder()){ - $pk2 = new InventoryContentPacket(); - $pk2->windowId = $player->getWindowId($this); - $pk2->items = $armor; - $player->sendDataPacket($pk2); - }else{ - $player->sendDataPacket($pk); - } + if(($k = array_search($this->holder, $target, true)) !== false){ + $pk = new InventoryContentPacket(); + $pk->windowId = $target[$k]->getWindowId($this); + $pk->items = $armor; + $target[$k]->sendDataPacket($pk); + unset($target[$k]); + } + if(!empty($target)){ + $pk = new MobArmorEquipmentPacket(); + $pk->entityRuntimeId = $this->getHolder()->getId(); + $pk->slots = $armor; + $this->holder->getLevel()->getServer()->broadcastPacket($target, $pk); } } From 4b7300de8d54930e6d22859487d67fbb034e8ca5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 13 Aug 2018 19:56:20 +0100 Subject: [PATCH 0105/3224] Use openssl_digest() instead of hash() in network hot code openssl_digest() is TWICE as fast as hash() on my machine for the same data and same algorithm. I can only guess that OpenSSL is more optimized than PHP ext/standard :) --- src/pocketmine/network/mcpe/NetworkCipher.php | 2 +- src/pocketmine/network/mcpe/ProcessLoginTask.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/NetworkCipher.php b/src/pocketmine/network/mcpe/NetworkCipher.php index eb4c5f1aa9..7e3bd07217 100644 --- a/src/pocketmine/network/mcpe/NetworkCipher.php +++ b/src/pocketmine/network/mcpe/NetworkCipher.php @@ -78,6 +78,6 @@ class NetworkCipher{ } private function calculateChecksum(int $counter, string $payload) : string{ - return substr(hash(self::CHECKSUM_ALGO, Binary::writeLLong($counter) . $payload . $this->key, true), 0, 8); + return substr(openssl_digest(Binary::writeLLong($counter) . $payload . $this->key, self::CHECKSUM_ALGO, true), 0, 8); } } diff --git a/src/pocketmine/network/mcpe/ProcessLoginTask.php b/src/pocketmine/network/mcpe/ProcessLoginTask.php index 29d5823fa8..0ca99783f9 100644 --- a/src/pocketmine/network/mcpe/ProcessLoginTask.php +++ b/src/pocketmine/network/mcpe/ProcessLoginTask.php @@ -101,7 +101,7 @@ class ProcessLoginTask extends AsyncTask{ $salt = random_bytes(16); $sharedSecret = $serverPriv->createExchange($clientPub)->calculateSharedKey(); - $this->aesKey = hash('sha256', $salt . hex2bin(str_pad(gmp_strval($sharedSecret, 16), 96, "0", STR_PAD_LEFT)), true); + $this->aesKey = openssl_digest($salt . hex2bin(str_pad(gmp_strval($sharedSecret, 16), 96, "0", STR_PAD_LEFT)), 'sha256', true); $this->handshakeJwt = $this->generateServerHandshakeJwt($serverPriv, $salt); } From 0273e2484e157df64df7e3299be3f9247b71a5be Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 14 Aug 2018 13:33:02 +0100 Subject: [PATCH 0106/3224] Kill entity runtime NBT (#2361) --- src/pocketmine/Player.php | 42 +++++------ src/pocketmine/entity/Entity.php | 68 ++++++++---------- src/pocketmine/entity/Human.php | 70 ++++++++++--------- src/pocketmine/entity/Living.php | 30 ++++---- src/pocketmine/entity/Squid.php | 5 +- src/pocketmine/entity/Villager.php | 16 +++-- .../entity/object/ExperienceOrb.php | 27 +++---- src/pocketmine/entity/object/FallingBlock.php | 26 +++---- src/pocketmine/entity/object/ItemEntity.php | 35 +++++----- src/pocketmine/entity/object/Painting.php | 20 +++--- src/pocketmine/entity/object/PrimedTNT.php | 17 +++-- src/pocketmine/entity/projectile/Arrow.php | 14 ++-- .../entity/projectile/Projectile.php | 40 ++++++----- .../entity/projectile/SplashPotion.php | 15 ++-- .../level/format/io/leveldb/LevelDB.php | 3 +- .../level/format/io/region/Anvil.php | 3 +- .../level/format/io/region/McRegion.php | 3 +- 17 files changed, 224 insertions(+), 210 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 7aa78cb65d..50b00cfb77 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1885,18 +1885,18 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->server->addOnlinePlayer($this); } - protected function initHumanData() : void{ + protected function initHumanData(CompoundTag $nbt) : void{ $this->setNameTag($this->username); } - protected function initEntity() : void{ - parent::initEntity(); + protected function initEntity(CompoundTag $nbt) : void{ + parent::initEntity($nbt); $this->addDefaultWindows(); - $this->firstPlayed = $this->namedtag->getLong("firstPlayed", $now = (int) (microtime(true) * 1000)); - $this->lastPlayed = $this->namedtag->getLong("lastPlayed", $now); + $this->firstPlayed = $nbt->getLong("firstPlayed", $now = (int) (microtime(true) * 1000)); + $this->lastPlayed = $nbt->getLong("lastPlayed", $now); - $this->gamemode = $this->namedtag->getInt("playerGameType", self::SURVIVAL) & 0x03; + $this->gamemode = $nbt->getInt("playerGameType", self::SURVIVAL) & 0x03; if($this->server->getForceGamemode()){ $this->gamemode = $this->server->getGamemode(); } @@ -1912,15 +1912,15 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->setCanClimb(); $this->achievements = []; - $achievements = $this->namedtag->getCompoundTag("Achievements") ?? []; + $achievements = $nbt->getCompoundTag("Achievements") ?? []; /** @var ByteTag $achievement */ foreach($achievements as $achievement){ $this->achievements[$achievement->getName()] = $achievement->getValue() !== 0; } if(!$this->hasValidSpawnPosition()){ - if(($level = $this->server->getLevelByName($this->namedtag->getString("SpawnLevel", ""))) instanceof Level){ - $this->spawnPosition = new Position($this->namedtag->getInt("SpawnX"), $this->namedtag->getInt("SpawnY"), $this->namedtag->getInt("SpawnZ"), $level); + if(($level = $this->server->getLevelByName($nbt->getString("SpawnLevel", ""))) instanceof Level){ + $this->spawnPosition = new Position($nbt->getInt("SpawnX"), $nbt->getInt("SpawnY"), $nbt->getInt("SpawnZ"), $level); }else{ $this->spawnPosition = $this->level->getSafeSpawn(); } @@ -2916,21 +2916,21 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ throw new \InvalidStateException("Tried to save closed player"); } - parent::saveNBT(); + $nbt = $this->saveNBT(); if($this->isValid()){ - $this->namedtag->setString("Level", $this->level->getFolderName()); + $nbt->setString("Level", $this->level->getFolderName()); } if($this->hasValidSpawnPosition()){ - $this->namedtag->setString("SpawnLevel", $this->spawnPosition->getLevel()->getFolderName()); - $this->namedtag->setInt("SpawnX", $this->spawnPosition->getFloorX()); - $this->namedtag->setInt("SpawnY", $this->spawnPosition->getFloorY()); - $this->namedtag->setInt("SpawnZ", $this->spawnPosition->getFloorZ()); + $nbt->setString("SpawnLevel", $this->spawnPosition->getLevel()->getFolderName()); + $nbt->setInt("SpawnX", $this->spawnPosition->getFloorX()); + $nbt->setInt("SpawnY", $this->spawnPosition->getFloorY()); + $nbt->setInt("SpawnZ", $this->spawnPosition->getFloorZ()); if(!$this->isAlive()){ //hack for respawn after quit - $this->namedtag->setTag(new ListTag("Pos", [ + $nbt->setTag(new ListTag("Pos", [ new DoubleTag("", $this->spawnPosition->x), new DoubleTag("", $this->spawnPosition->y), new DoubleTag("", $this->spawnPosition->z) @@ -2942,13 +2942,13 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ foreach($this->achievements as $achievement => $status){ $achievements->setByte($achievement, $status ? 1 : 0); } - $this->namedtag->setTag($achievements); + $nbt->setTag($achievements); - $this->namedtag->setInt("playerGameType", $this->gamemode); - $this->namedtag->setLong("firstPlayed", $this->firstPlayed); - $this->namedtag->setLong("lastPlayed", (int) floor(microtime(true) * 1000)); + $nbt->setInt("playerGameType", $this->gamemode); + $nbt->setLong("firstPlayed", $this->firstPlayed); + $nbt->setLong("lastPlayed", (int) floor(microtime(true) * 1000)); - $this->server->saveOfflinePlayerData($this->username, $this->namedtag, $async); + $this->server->saveOfflinePlayerData($this->username, $nbt, $async); } public function kill() : void{ diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 847182cc5a..1a909f0fea 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -436,8 +436,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ public $lastUpdate; /** @var int */ public $fireTicks = 0; - /** @var CompoundTag */ - public $namedtag; /** @var bool */ public $canCollide = true; @@ -495,13 +493,12 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } $this->id = Entity::$entityCount++; - $this->namedtag = $nbt; $this->server = $level->getServer(); /** @var float[] $pos */ - $pos = $this->namedtag->getListTag("Pos")->getAllValues(); + $pos = $nbt->getListTag("Pos")->getAllValues(); /** @var float[] $rotation */ - $rotation = $this->namedtag->getListTag("Rotation")->getAllValues(); + $rotation = $nbt->getListTag("Rotation")->getAllValues(); parent::__construct($pos[0], $pos[1], $pos[2], $rotation[0], $rotation[1], $level); assert(!is_nan($this->x) and !is_infinite($this->x) and !is_nan($this->y) and !is_infinite($this->y) and !is_nan($this->z) and !is_infinite($this->z)); @@ -514,15 +511,15 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ throw new \InvalidStateException("Cannot create entities in unloaded chunks"); } - if($this->namedtag->hasTag("Motion", ListTag::class)){ + if($nbt->hasTag("Motion", ListTag::class)){ /** @var float[] $motion */ - $motion = $this->namedtag->getListTag("Motion")->getAllValues(); + $motion = $nbt->getListTag("Motion")->getAllValues(); $this->setMotion($this->temporalVector->setComponents(...$motion)); } $this->resetLastMovements(); - $this->fallDistance = $this->namedtag->getFloat("FallDistance", 0.0); + $this->fallDistance = $nbt->getFloat("FallDistance", 0.0); $this->propertyManager = new DataPropertyManager(); @@ -534,14 +531,14 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->propertyManager->setFloat(self::DATA_BOUNDING_BOX_WIDTH, $this->width); $this->propertyManager->setFloat(self::DATA_BOUNDING_BOX_HEIGHT, $this->height); - $this->fireTicks = $this->namedtag->getShort("Fire", 0); + $this->fireTicks = $nbt->getShort("Fire", 0); if($this->isOnFire()){ $this->setGenericFlag(self::DATA_FLAG_ONFIRE); } - $this->propertyManager->setShort(self::DATA_AIR, $this->namedtag->getShort("Air", 300)); - $this->onGround = $this->namedtag->getByte("OnGround", 0) !== 0; - $this->invulnerable = $this->namedtag->getByte("Invulnerable", 0) !== 0; + $this->propertyManager->setShort(self::DATA_AIR, $nbt->getShort("Air", 300)); + $this->onGround = $nbt->getByte("OnGround", 0) !== 0; + $this->invulnerable = $nbt->getByte("Invulnerable", 0) !== 0; $this->attributeMap = new AttributeMap(); $this->addAttributes(); @@ -549,7 +546,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->setGenericFlag(self::DATA_FLAG_AFFECTED_BY_GRAVITY, true); $this->setGenericFlag(self::DATA_FLAG_HAS_COLLISION, true); - $this->initEntity(); + $this->initEntity($nbt); $this->propertyManager->clearDirtyProperties(); //Prevents resending properties that were set during construction $this->chunk->addEntity($this); @@ -838,54 +835,52 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ return current(self::$saveNames[static::class]); } - public function saveNBT() : void{ + public function saveNBT() : CompoundTag{ + $nbt = new CompoundTag(); if(!($this instanceof Player)){ - $this->namedtag->setString("id", $this->getSaveId(), true); + $nbt->setString("id", $this->getSaveId(), true); if($this->getNameTag() !== ""){ - $this->namedtag->setString("CustomName", $this->getNameTag()); - $this->namedtag->setByte("CustomNameVisible", $this->isNameTagVisible() ? 1 : 0); - }else{ - $this->namedtag->removeTag("CustomName", "CustomNameVisible"); + $nbt->setString("CustomName", $this->getNameTag()); + $nbt->setByte("CustomNameVisible", $this->isNameTagVisible() ? 1 : 0); } } - $this->namedtag->setTag(new ListTag("Pos", [ + $nbt->setTag(new ListTag("Pos", [ new DoubleTag("", $this->x), new DoubleTag("", $this->y), new DoubleTag("", $this->z) ])); - $this->namedtag->setTag(new ListTag("Motion", [ + $nbt->setTag(new ListTag("Motion", [ new DoubleTag("", $this->motion->x), new DoubleTag("", $this->motion->y), new DoubleTag("", $this->motion->z) ])); - $this->namedtag->setTag(new ListTag("Rotation", [ + $nbt->setTag(new ListTag("Rotation", [ new FloatTag("", $this->yaw), new FloatTag("", $this->pitch) ])); - $this->namedtag->setFloat("FallDistance", $this->fallDistance); - $this->namedtag->setShort("Fire", $this->fireTicks); - $this->namedtag->setShort("Air", $this->propertyManager->getShort(self::DATA_AIR)); - $this->namedtag->setByte("OnGround", $this->onGround ? 1 : 0); - $this->namedtag->setByte("Invulnerable", $this->invulnerable ? 1 : 0); + $nbt->setFloat("FallDistance", $this->fallDistance); + $nbt->setShort("Fire", $this->fireTicks); + $nbt->setShort("Air", $this->propertyManager->getShort(self::DATA_AIR)); + $nbt->setByte("OnGround", $this->onGround ? 1 : 0); + $nbt->setByte("Invulnerable", $this->invulnerable ? 1 : 0); + + return $nbt; } - protected function initEntity() : void{ - assert($this->namedtag instanceof CompoundTag); + protected function initEntity(CompoundTag $nbt) : void{ + if($nbt->hasTag("CustomName", StringTag::class)){ + $this->setNameTag($nbt->getString("CustomName")); - if($this->namedtag->hasTag("CustomName", StringTag::class)){ - $this->setNameTag($this->namedtag->getString("CustomName")); - - if($this->namedtag->hasTag("CustomNameVisible", StringTag::class)){ + if($nbt->hasTag("CustomNameVisible", StringTag::class)){ //Older versions incorrectly saved this as a string (see 890f72dbf23a77f294169b79590770470041adc4) - $this->setNameTagVisible($this->namedtag->getString("CustomNameVisible") !== ""); - $this->namedtag->removeTag("CustomNameVisible"); + $this->setNameTagVisible($nbt->getString("CustomNameVisible") !== ""); }else{ - $this->setNameTagVisible($this->namedtag->getByte("CustomNameVisible", 1) !== 0); + $this->setNameTagVisible($nbt->getByte("CustomNameVisible", 1) !== 0); } } } @@ -2036,7 +2031,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->setLevel(null); } - $this->namedtag = null; $this->lastDamageCause = null; } } diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 7aa322ad2b..68d99d7e01 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -578,13 +578,15 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ /** * For Human entities which are not players, sets their properties such as nametag, skin and UUID from NBT. + * + * @param CompoundTag $nbt */ - protected function initHumanData() : void{ - if($this->namedtag->hasTag("NameTag", StringTag::class)){ - $this->setNameTag($this->namedtag->getString("NameTag")); + protected function initHumanData(CompoundTag $nbt) : void{ + if($nbt->hasTag("NameTag", StringTag::class)){ + $this->setNameTag($nbt->getString("NameTag")); } - $skin = $this->namedtag->getCompoundTag("Skin"); + $skin = $nbt->getCompoundTag("Skin"); if($skin !== null){ $this->setSkin(new Skin( $skin->getString("Name"), @@ -598,17 +600,17 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $this->uuid = UUID::fromData((string) $this->getId(), $this->skin->getSkinData(), $this->getNameTag()); } - protected function initEntity() : void{ - parent::initEntity(); + protected function initEntity(CompoundTag $nbt) : void{ + parent::initEntity($nbt); $this->setPlayerFlag(self::DATA_PLAYER_FLAG_SLEEP, false); $this->propertyManager->setBlockPos(self::DATA_PLAYER_BED_POSITION, null); $this->inventory = new PlayerInventory($this); $this->enderChestInventory = new EnderChestInventory(); - $this->initHumanData(); + $this->initHumanData($nbt); - $inventoryTag = $this->namedtag->getListTag("Inventory"); + $inventoryTag = $nbt->getListTag("Inventory"); if($inventoryTag !== null){ $armorListener = $this->armorInventory->getEventProcessor(); $this->armorInventory->setEventProcessor(null); @@ -628,7 +630,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $this->armorInventory->setEventProcessor($armorListener); } - $enderChestInventoryTag = $this->namedtag->getListTag("EnderChestInventory"); + $enderChestInventoryTag = $nbt->getListTag("EnderChestInventory"); if($enderChestInventoryTag !== null){ /** @var CompoundTag $item */ foreach($enderChestInventoryTag as $i => $item){ @@ -636,21 +638,21 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ } } - $this->inventory->setHeldItemIndex($this->namedtag->getInt("SelectedInventorySlot", 0), false); + $this->inventory->setHeldItemIndex($nbt->getInt("SelectedInventorySlot", 0), false); $this->inventory->setEventProcessor(new EntityInventoryEventProcessor($this)); - $this->setFood((float) $this->namedtag->getInt("foodLevel", (int) $this->getFood(), true)); - $this->setExhaustion($this->namedtag->getFloat("foodExhaustionLevel", $this->getExhaustion(), true)); - $this->setSaturation($this->namedtag->getFloat("foodSaturationLevel", $this->getSaturation(), true)); - $this->foodTickTimer = $this->namedtag->getInt("foodTickTimer", $this->foodTickTimer, true); + $this->setFood((float) $nbt->getInt("foodLevel", (int) $this->getFood(), true)); + $this->setExhaustion($nbt->getFloat("foodExhaustionLevel", $this->getExhaustion(), true)); + $this->setSaturation($nbt->getFloat("foodSaturationLevel", $this->getSaturation(), true)); + $this->foodTickTimer = $nbt->getInt("foodTickTimer", $this->foodTickTimer, true); - $this->setXpLevel($this->namedtag->getInt("XpLevel", $this->getXpLevel(), true)); - $this->setXpProgress($this->namedtag->getFloat("XpP", $this->getXpProgress(), true)); - $this->totalXp = $this->namedtag->getInt("XpTotal", $this->totalXp, true); + $this->setXpLevel($nbt->getInt("XpLevel", $this->getXpLevel(), true)); + $this->setXpProgress($nbt->getFloat("XpP", $this->getXpProgress(), true)); + $this->totalXp = $nbt->getInt("XpTotal", $this->totalXp, true); - if($this->namedtag->hasTag("XpSeed", IntTag::class)){ - $this->xpSeed = $this->namedtag->getInt("XpSeed"); + if($nbt->hasTag("XpSeed", IntTag::class)){ + $this->xpSeed = $nbt->getInt("XpSeed"); }else{ $this->xpSeed = random_int(INT32_MIN, INT32_MAX); } @@ -764,21 +766,21 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ ), function(Item $item) : bool{ return !$item->hasEnchantment(Enchantment::VANISHING); }); } - public function saveNBT() : void{ - parent::saveNBT(); + public function saveNBT() : CompoundTag{ + $nbt = parent::saveNBT(); - $this->namedtag->setInt("foodLevel", (int) $this->getFood(), true); - $this->namedtag->setFloat("foodExhaustionLevel", $this->getExhaustion(), true); - $this->namedtag->setFloat("foodSaturationLevel", $this->getSaturation(), true); - $this->namedtag->setInt("foodTickTimer", $this->foodTickTimer); + $nbt->setInt("foodLevel", (int) $this->getFood(), true); + $nbt->setFloat("foodExhaustionLevel", $this->getExhaustion(), true); + $nbt->setFloat("foodSaturationLevel", $this->getSaturation(), true); + $nbt->setInt("foodTickTimer", $this->foodTickTimer); - $this->namedtag->setInt("XpLevel", $this->getXpLevel()); - $this->namedtag->setFloat("XpP", $this->getXpProgress()); - $this->namedtag->setInt("XpTotal", $this->totalXp); - $this->namedtag->setInt("XpSeed", $this->xpSeed); + $nbt->setInt("XpLevel", $this->getXpLevel()); + $nbt->setFloat("XpP", $this->getXpProgress()); + $nbt->setInt("XpTotal", $this->totalXp); + $nbt->setInt("XpSeed", $this->xpSeed); $inventoryTag = new ListTag("Inventory", [], NBT::TAG_Compound); - $this->namedtag->setTag($inventoryTag); + $nbt->setTag($inventoryTag); if($this->inventory !== null){ //Normal inventory $slotCount = $this->inventory->getSize() + $this->inventory->getHotbarSize(); @@ -797,7 +799,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ } } - $this->namedtag->setInt("SelectedInventorySlot", $this->inventory->getHeldItemIndex()); + $nbt->setInt("SelectedInventorySlot", $this->inventory->getHeldItemIndex()); } if($this->enderChestInventory !== null){ @@ -812,11 +814,11 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ } } - $this->namedtag->setTag(new ListTag("EnderChestInventory", $items, NBT::TAG_Compound)); + $nbt->setTag(new ListTag("EnderChestInventory", $items, NBT::TAG_Compound)); } if($this->skin !== null){ - $this->namedtag->setTag(new CompoundTag("Skin", [ + $nbt->setTag(new CompoundTag("Skin", [ new StringTag("Name", $this->skin->getSkinId()), new ByteArrayTag("Data", $this->skin->getSkinData()), new ByteArrayTag("CapeData", $this->skin->getCapeData()), @@ -824,6 +826,8 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ new ByteArrayTag("GeometryData", $this->skin->getGeometryData()) ])); } + + return $nbt; } public function spawnTo(Player $player) : void{ diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 1ebea73b68..1c0e12b47d 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -74,8 +74,8 @@ abstract class Living extends Entity implements Damageable{ abstract public function getName() : string; - protected function initEntity() : void{ - parent::initEntity(); + protected function initEntity(CompoundTag $nbt) : void{ + parent::initEntity($nbt); $this->armorInventory = new ArmorInventory($this); //TODO: load/save armor inventory contents @@ -83,21 +83,17 @@ abstract class Living extends Entity implements Damageable{ $health = $this->getMaxHealth(); - if($this->namedtag->hasTag("HealF", FloatTag::class)){ - $health = $this->namedtag->getFloat("HealF"); - $this->namedtag->removeTag("HealF"); - }elseif($this->namedtag->hasTag("Health")){ - $healthTag = $this->namedtag->getTag("Health"); + if($nbt->hasTag("HealF", FloatTag::class)){ + $health = $nbt->getFloat("HealF"); + }elseif($nbt->hasTag("Health")){ + $healthTag = $nbt->getTag("Health"); $health = (float) $healthTag->getValue(); //Older versions of PocketMine-MP incorrectly saved this as a short instead of a float - if(!($healthTag instanceof FloatTag)){ - $this->namedtag->removeTag("Health"); - } } $this->setHealth($health); /** @var CompoundTag[]|ListTag $activeEffectsTag */ - $activeEffectsTag = $this->namedtag->getListTag("ActiveEffects"); + $activeEffectsTag = $nbt->getListTag("ActiveEffects"); if($activeEffectsTag !== null){ foreach($activeEffectsTag as $e){ $effect = Effect::getEffect($e->getByte("Id")); @@ -150,9 +146,9 @@ abstract class Living extends Entity implements Damageable{ $this->attributeMap->getAttribute(Attribute::ABSORPTION)->setValue($absorption); } - public function saveNBT() : void{ - parent::saveNBT(); - $this->namedtag->setFloat("Health", $this->getHealth(), true); + public function saveNBT() : CompoundTag{ + $nbt = parent::saveNBT(); + $nbt->setFloat("Health", $this->getHealth(), true); if(count($this->effects) > 0){ $effects = []; @@ -166,10 +162,10 @@ abstract class Living extends Entity implements Damageable{ ]); } - $this->namedtag->setTag(new ListTag("ActiveEffects", $effects)); - }else{ - $this->namedtag->removeTag("ActiveEffects"); + $nbt->setTag(new ListTag("ActiveEffects", $effects)); } + + return $nbt; } diff --git a/src/pocketmine/entity/Squid.php b/src/pocketmine/entity/Squid.php index 2d2c08e26f..24d97340b4 100644 --- a/src/pocketmine/entity/Squid.php +++ b/src/pocketmine/entity/Squid.php @@ -28,6 +28,7 @@ use pocketmine\event\entity\EntityDamageEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\Vector3; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\EntityEventPacket; class Squid extends WaterAnimal{ @@ -42,9 +43,9 @@ class Squid extends WaterAnimal{ private $switchDirectionTicker = 0; - public function initEntity() : void{ + public function initEntity(CompoundTag $nbt) : void{ $this->setMaxHealth(10); - parent::initEntity(); + parent::initEntity($nbt); } public function getName() : string{ diff --git a/src/pocketmine/entity/Villager.php b/src/pocketmine/entity/Villager.php index 233690ca9c..52b0d1bdd4 100644 --- a/src/pocketmine/entity/Villager.php +++ b/src/pocketmine/entity/Villager.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\entity; +use pocketmine\nbt\tag\CompoundTag; + class Villager extends Creature implements NPC, Ageable{ public const PROFESSION_FARMER = 0; public const PROFESSION_LIBRARIAN = 1; @@ -39,11 +41,11 @@ class Villager extends Creature implements NPC, Ageable{ return "Villager"; } - protected function initEntity() : void{ - parent::initEntity(); + protected function initEntity(CompoundTag $nbt) : void{ + parent::initEntity($nbt); /** @var int $profession */ - $profession = $this->namedtag->getInt("Profession", self::PROFESSION_FARMER); + $profession = $nbt->getInt("Profession", self::PROFESSION_FARMER); if($profession > 4 or $profession < 0){ $profession = self::PROFESSION_FARMER; @@ -52,9 +54,11 @@ class Villager extends Creature implements NPC, Ageable{ $this->setProfession($profession); } - public function saveNBT() : void{ - parent::saveNBT(); - $this->namedtag->setInt("Profession", $this->getProfession()); + public function saveNBT() : CompoundTag{ + $nbt = parent::saveNBT(); + $nbt->setInt("Profession", $this->getProfession()); + + return $nbt; } /** diff --git a/src/pocketmine/entity/object/ExperienceOrb.php b/src/pocketmine/entity/object/ExperienceOrb.php index 93cd692569..44d30ee76d 100644 --- a/src/pocketmine/entity/object/ExperienceOrb.php +++ b/src/pocketmine/entity/object/ExperienceOrb.php @@ -25,6 +25,7 @@ namespace pocketmine\entity\object; use pocketmine\entity\Entity; use pocketmine\entity\Human; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ShortTag; use pocketmine\Player; @@ -100,28 +101,30 @@ class ExperienceOrb extends Entity{ */ protected $targetPlayerRuntimeId = null; - protected function initEntity() : void{ - parent::initEntity(); + protected function initEntity(CompoundTag $nbt) : void{ + parent::initEntity($nbt); - $this->age = $this->namedtag->getShort("Age", 0); + $this->age = $nbt->getShort("Age", 0); $value = 0; - if($this->namedtag->hasTag(self::TAG_VALUE_PC, ShortTag::class)){ //PC - $value = $this->namedtag->getShort(self::TAG_VALUE_PC); - }elseif($this->namedtag->hasTag(self::TAG_VALUE_PE, IntTag::class)){ //PE save format - $value = $this->namedtag->getInt(self::TAG_VALUE_PE); + if($nbt->hasTag(self::TAG_VALUE_PC, ShortTag::class)){ //PC + $value = $nbt->getShort(self::TAG_VALUE_PC); + }elseif($nbt->hasTag(self::TAG_VALUE_PE, IntTag::class)){ //PE save format + $value = $nbt->getInt(self::TAG_VALUE_PE); } $this->setXpValue($value); } - public function saveNBT() : void{ - parent::saveNBT(); + public function saveNBT() : CompoundTag{ + $nbt = parent::saveNBT(); - $this->namedtag->setShort("Age", $this->age); + $nbt->setShort("Age", $this->age); - $this->namedtag->setShort(self::TAG_VALUE_PC, $this->getXpValue()); - $this->namedtag->setInt(self::TAG_VALUE_PE, $this->getXpValue()); + $nbt->setShort(self::TAG_VALUE_PC, $this->getXpValue()); + $nbt->setInt(self::TAG_VALUE_PE, $this->getXpValue()); + + return $nbt; } public function getXpValue() : int{ diff --git a/src/pocketmine/entity/object/FallingBlock.php b/src/pocketmine/entity/object/FallingBlock.php index a2dfa4ad44..4db9c18dcf 100644 --- a/src/pocketmine/entity/object/FallingBlock.php +++ b/src/pocketmine/entity/object/FallingBlock.php @@ -32,6 +32,7 @@ use pocketmine\event\entity\EntityDamageEvent; use pocketmine\item\ItemFactory; use pocketmine\level\Position; use pocketmine\nbt\tag\ByteTag; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; class FallingBlock extends Entity{ @@ -50,24 +51,23 @@ class FallingBlock extends Entity{ public $canCollide = false; - protected function initEntity() : void{ - parent::initEntity(); + protected function initEntity(CompoundTag $nbt) : void{ + parent::initEntity($nbt); $blockId = 0; //TODO: 1.8+ save format - if($this->namedtag->hasTag("TileID", IntTag::class)){ - $blockId = $this->namedtag->getInt("TileID"); - }elseif($this->namedtag->hasTag("Tile", ByteTag::class)){ - $blockId = $this->namedtag->getByte("Tile"); - $this->namedtag->removeTag("Tile"); + if($nbt->hasTag("TileID", IntTag::class)){ + $blockId = $nbt->getInt("TileID"); + }elseif($nbt->hasTag("Tile", ByteTag::class)){ + $blockId = $nbt->getByte("Tile"); } if($blockId === 0){ throw new \UnexpectedValueException("Invalid " . get_class($this) . " entity: block ID is 0 or missing"); } - $damage = $this->namedtag->getByte("Data", 0); + $damage = $nbt->getByte("Data", 0); $this->block = BlockFactory::get($blockId, $damage); @@ -133,9 +133,11 @@ class FallingBlock extends Entity{ return $this->block->getDamage(); } - public function saveNBT() : void{ - parent::saveNBT(); - $this->namedtag->setInt("TileID", $this->block->getId(), true); - $this->namedtag->setByte("Data", $this->block->getDamage()); + public function saveNBT() : CompoundTag{ + $nbt = parent::saveNBT(); + $nbt->setInt("TileID", $this->block->getId(), true); + $nbt->setByte("Data", $this->block->getDamage()); + + return $nbt; } } diff --git a/src/pocketmine/entity/object/ItemEntity.php b/src/pocketmine/entity/object/ItemEntity.php index 708087e7e5..103f9a45f4 100644 --- a/src/pocketmine/entity/object/ItemEntity.php +++ b/src/pocketmine/entity/object/ItemEntity.php @@ -28,6 +28,7 @@ use pocketmine\event\entity\ItemDespawnEvent; use pocketmine\event\entity\ItemSpawnEvent; use pocketmine\event\inventory\InventoryPickupItemEvent; use pocketmine\item\Item; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\AddItemEntityPacket; use pocketmine\network\mcpe\protocol\TakeItemEntityPacket; use pocketmine\Player; @@ -53,18 +54,18 @@ class ItemEntity extends Entity{ public $canCollide = false; - protected function initEntity() : void{ - parent::initEntity(); + protected function initEntity(CompoundTag $nbt) : void{ + parent::initEntity($nbt); $this->setMaxHealth(5); - $this->setHealth($this->namedtag->getShort("Health", (int) $this->getHealth())); - $this->age = $this->namedtag->getShort("Age", $this->age); - $this->pickupDelay = $this->namedtag->getShort("PickupDelay", $this->pickupDelay); - $this->owner = $this->namedtag->getString("Owner", $this->owner); - $this->thrower = $this->namedtag->getString("Thrower", $this->thrower); + $this->setHealth($nbt->getShort("Health", (int) $this->getHealth())); + $this->age = $nbt->getShort("Age", $this->age); + $this->pickupDelay = $nbt->getShort("PickupDelay", $this->pickupDelay); + $this->owner = $nbt->getString("Owner", $this->owner); + $this->thrower = $nbt->getString("Thrower", $this->thrower); - $itemTag = $this->namedtag->getCompoundTag("Item"); + $itemTag = $nbt->getCompoundTag("Item"); if($itemTag === null){ throw new \UnexpectedValueException("Invalid " . get_class($this) . " entity: expected \"Item\" NBT tag not found"); } @@ -114,18 +115,20 @@ class ItemEntity extends Entity{ return true; } - public function saveNBT() : void{ - parent::saveNBT(); - $this->namedtag->setTag($this->item->nbtSerialize(-1, "Item")); - $this->namedtag->setShort("Health", (int) $this->getHealth()); - $this->namedtag->setShort("Age", $this->age); - $this->namedtag->setShort("PickupDelay", $this->pickupDelay); + public function saveNBT() : CompoundTag{ + $nbt = parent::saveNBT(); + $nbt->setTag($this->item->nbtSerialize(-1, "Item")); + $nbt->setShort("Health", (int) $this->getHealth()); + $nbt->setShort("Age", $this->age); + $nbt->setShort("PickupDelay", $this->pickupDelay); if($this->owner !== null){ - $this->namedtag->setString("Owner", $this->owner); + $nbt->setString("Owner", $this->owner); } if($this->thrower !== null){ - $this->namedtag->setString("Thrower", $this->thrower); + $nbt->setString("Thrower", $this->thrower); } + + return $nbt; } /** diff --git a/src/pocketmine/entity/object/Painting.php b/src/pocketmine/entity/object/Painting.php index 4dfa7ddcd3..6faafac8d4 100644 --- a/src/pocketmine/entity/object/Painting.php +++ b/src/pocketmine/entity/object/Painting.php @@ -70,20 +70,22 @@ class Painting extends Entity{ parent::__construct($level, $nbt); } - protected function initEntity() : void{ + protected function initEntity(CompoundTag $nbt) : void{ $this->setMaxHealth(1); $this->setHealth(1); - parent::initEntity(); + parent::initEntity($nbt); } - public function saveNBT() : void{ - parent::saveNBT(); - $this->namedtag->setInt("TileX", (int) $this->blockIn->x); - $this->namedtag->setInt("TileY", (int) $this->blockIn->y); - $this->namedtag->setInt("TileZ", (int) $this->blockIn->z); + public function saveNBT() : CompoundTag{ + $nbt = parent::saveNBT(); + $nbt->setInt("TileX", (int) $this->blockIn->x); + $nbt->setInt("TileY", (int) $this->blockIn->y); + $nbt->setInt("TileZ", (int) $this->blockIn->z); - $this->namedtag->setByte("Facing", (int) $this->direction); - $this->namedtag->setByte("Direction", (int) $this->direction); //Save both for full compatibility + $nbt->setByte("Facing", (int) $this->direction); + $nbt->setByte("Direction", (int) $this->direction); //Save both for full compatibility + + return $nbt; } public function kill() : void{ diff --git a/src/pocketmine/entity/object/PrimedTNT.php b/src/pocketmine/entity/object/PrimedTNT.php index b7839c2b3e..5db3438fae 100644 --- a/src/pocketmine/entity/object/PrimedTNT.php +++ b/src/pocketmine/entity/object/PrimedTNT.php @@ -28,6 +28,7 @@ use pocketmine\entity\Explosive; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\ExplosionPrimeEvent; use pocketmine\level\Explosion; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ShortTag; use pocketmine\network\mcpe\protocol\LevelEventPacket; @@ -53,11 +54,11 @@ class PrimedTNT extends Entity implements Explosive{ } } - protected function initEntity() : void{ - parent::initEntity(); + protected function initEntity(CompoundTag $nbt) : void{ + parent::initEntity($nbt); - if($this->namedtag->hasTag("Fuse", ShortTag::class)){ - $this->fuse = $this->namedtag->getShort("Fuse"); + if($nbt->hasTag("Fuse", ShortTag::class)){ + $this->fuse = $nbt->getShort("Fuse"); }else{ $this->fuse = 80; } @@ -73,9 +74,11 @@ class PrimedTNT extends Entity implements Explosive{ return false; } - public function saveNBT() : void{ - parent::saveNBT(); - $this->namedtag->setShort("Fuse", $this->fuse, true); //older versions incorrectly saved this as a byte + public function saveNBT() : CompoundTag{ + $nbt = parent::saveNBT(); + $nbt->setShort("Fuse", $this->fuse, true); //older versions incorrectly saved this as a byte + + return $nbt; } public function entityBaseTick(int $tickDiff = 1) : bool{ diff --git a/src/pocketmine/entity/projectile/Arrow.php b/src/pocketmine/entity/projectile/Arrow.php index ee2716e5af..92409071e9 100644 --- a/src/pocketmine/entity/projectile/Arrow.php +++ b/src/pocketmine/entity/projectile/Arrow.php @@ -66,16 +66,16 @@ class Arrow extends Projectile{ $this->setCritical($critical); } - protected function initEntity() : void{ - parent::initEntity(); + protected function initEntity(CompoundTag $nbt) : void{ + parent::initEntity($nbt); - $this->pickupMode = $this->namedtag->getByte(self::TAG_PICKUP, self::PICKUP_ANY, true); + $this->pickupMode = $nbt->getByte(self::TAG_PICKUP, self::PICKUP_ANY, true); } - public function saveNBT() : void{ - parent::saveNBT(); - - $this->namedtag->setByte(self::TAG_PICKUP, $this->pickupMode, true); + public function saveNBT() : CompoundTag{ + $nbt = parent::saveNBT(); + $nbt->setByte(self::TAG_PICKUP, $this->pickupMode); + return $nbt; } public function isCritical() : bool{ diff --git a/src/pocketmine/entity/projectile/Projectile.php b/src/pocketmine/entity/projectile/Projectile.php index 66c0a14337..d6553cacd7 100644 --- a/src/pocketmine/entity/projectile/Projectile.php +++ b/src/pocketmine/entity/projectile/Projectile.php @@ -69,33 +69,33 @@ abstract class Projectile extends Entity{ } } - protected function initEntity() : void{ - parent::initEntity(); + protected function initEntity(CompoundTag $nbt) : void{ + parent::initEntity($nbt); $this->setMaxHealth(1); $this->setHealth(1); - $this->age = $this->namedtag->getShort("Age", $this->age); - $this->damage = $this->namedtag->getDouble("damage", $this->damage); + $this->age = $nbt->getShort("Age", $this->age); + $this->damage = $nbt->getDouble("damage", $this->damage); do{ $blockHit = null; $blockId = null; $blockData = null; - if($this->namedtag->hasTag("tileX", IntTag::class) and $this->namedtag->hasTag("tileY", IntTag::class) and $this->namedtag->hasTag("tileZ", IntTag::class)){ - $blockHit = new Vector3($this->namedtag->getInt("tileX"), $this->namedtag->getInt("tileY"), $this->namedtag->getInt("tileZ")); + if($nbt->hasTag("tileX", IntTag::class) and $nbt->hasTag("tileY", IntTag::class) and $nbt->hasTag("tileZ", IntTag::class)){ + $blockHit = new Vector3($nbt->getInt("tileX"), $nbt->getInt("tileY"), $nbt->getInt("tileZ")); }else{ break; } - if($this->namedtag->hasTag("blockId", IntTag::class)){ - $blockId = $this->namedtag->getInt("blockId"); + if($nbt->hasTag("blockId", IntTag::class)){ + $blockId = $nbt->getInt("blockId"); }else{ break; } - if($this->namedtag->hasTag("blockData", ByteTag::class)){ - $blockData = $this->namedtag->getByte("blockData"); + if($nbt->hasTag("blockData", ByteTag::class)){ + $blockData = $nbt->getByte("blockData"); }else{ break; } @@ -141,21 +141,23 @@ abstract class Projectile extends Entity{ return (int) ceil($this->motion->length() * $this->damage); } - public function saveNBT() : void{ - parent::saveNBT(); + public function saveNBT() : CompoundTag{ + $nbt = parent::saveNBT(); - $this->namedtag->setShort("Age", $this->age); - $this->namedtag->setDouble("damage", $this->damage); + $nbt->setShort("Age", $this->age); + $nbt->setDouble("damage", $this->damage); if($this->blockHit !== null){ - $this->namedtag->setInt("tileX", $this->blockHit->x); - $this->namedtag->setInt("tileY", $this->blockHit->y); - $this->namedtag->setInt("tileZ", $this->blockHit->z); + $nbt->setInt("tileX", $this->blockHit->x); + $nbt->setInt("tileY", $this->blockHit->y); + $nbt->setInt("tileZ", $this->blockHit->z); //we intentionally use different ones to PC because we don't have stringy IDs - $this->namedtag->setInt("blockId", $this->blockHitId); - $this->namedtag->setByte("blockData", $this->blockHitData); + $nbt->setInt("blockId", $this->blockHitId); + $nbt->setByte("blockData", $this->blockHitData); } + + return $nbt; } protected function applyDragBeforeGravity() : bool{ diff --git a/src/pocketmine/entity/projectile/SplashPotion.php b/src/pocketmine/entity/projectile/SplashPotion.php index 4720a5c28d..7ad93b639f 100644 --- a/src/pocketmine/entity/projectile/SplashPotion.php +++ b/src/pocketmine/entity/projectile/SplashPotion.php @@ -31,6 +31,7 @@ use pocketmine\event\entity\ProjectileHitEntityEvent; use pocketmine\event\entity\ProjectileHitBlockEvent; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\item\Potion; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\utils\Color; @@ -42,15 +43,17 @@ class SplashPotion extends Throwable{ protected $gravity = 0.05; protected $drag = 0.01; - protected function initEntity() : void{ - parent::initEntity(); + protected function initEntity(CompoundTag $nbt) : void{ + parent::initEntity($nbt); - $this->setPotionId($this->namedtag->getShort("PotionId", 0)); + $this->setPotionId($nbt->getShort("PotionId", 0)); } - public function saveNBT() : void{ - parent::saveNBT(); - $this->namedtag->setShort("PotionId", $this->getPotionId()); + public function saveNBT() : CompoundTag{ + $nbt = parent::saveNBT(); + $nbt->setShort("PotionId", $this->getPotionId()); + + return $nbt; } public function getResultDamage() : int{ diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index 5b94d0f4ce..71dbcb94f4 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -464,8 +464,7 @@ class LevelDB extends BaseLevelProvider{ /** @var CompoundTag[] $entities */ $entities = []; foreach($chunk->getSavableEntities() as $entity){ - $entity->saveNBT(); - $entities[] = $entity->namedtag; + $entities[] = $entity->saveNBT(); } $this->writeTags($entities, $index . self::TAG_ENTITY); diff --git a/src/pocketmine/level/format/io/region/Anvil.php b/src/pocketmine/level/format/io/region/Anvil.php index 9cd69599f7..5864d30f71 100644 --- a/src/pocketmine/level/format/io/region/Anvil.php +++ b/src/pocketmine/level/format/io/region/Anvil.php @@ -67,8 +67,7 @@ class Anvil extends McRegion{ $entities = []; foreach($chunk->getSavableEntities() as $entity){ - $entity->saveNBT(); - $entities[] = $entity->namedtag; + $entities[] = $entity->saveNBT(); } $nbt->setTag(new ListTag("Entities", $entities, NBT::TAG_Compound)); diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index c080b79a47..1f3f77bfc2 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -86,8 +86,7 @@ class McRegion extends BaseLevelProvider{ $entities = []; foreach($chunk->getSavableEntities() as $entity){ - $entity->saveNBT(); - $entities[] = $entity->namedtag; + $entities[] = $entity->saveNBT(); } $nbt->setTag(new ListTag("Entities", $entities, NBT::TAG_Compound)); From ce5829430563bab5d5808f8b1bb10a12c860bd17 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 14 Aug 2018 14:39:01 +0100 Subject: [PATCH 0107/3224] ProcessLoginTask: check connected status instead of closed status connected is what we're looking for here, as opposed to an entity being marked as garbage. --- src/pocketmine/network/mcpe/ProcessLoginTask.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/ProcessLoginTask.php b/src/pocketmine/network/mcpe/ProcessLoginTask.php index 0ca99783f9..256a7a55d4 100644 --- a/src/pocketmine/network/mcpe/ProcessLoginTask.php +++ b/src/pocketmine/network/mcpe/ProcessLoginTask.php @@ -219,7 +219,7 @@ class ProcessLoginTask extends AsyncTask{ public function onCompletion(Server $server) : void{ /** @var Player $player */ $player = $this->fetchLocal(); - if($player->isClosed()){ + if(!$player->isConnected()){ $server->getLogger()->error("Player " . $player->getName() . " was disconnected before their login could be verified"); }elseif($player->setAuthenticationStatus($this->authenticated, $this->error)){ if(!$this->useEncryption){ From d8198d81301c55aab5ee9cb75d2f97310e627682 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 14 Aug 2018 16:44:14 +0100 Subject: [PATCH 0108/3224] Fixed setItemInHand() regressions when placing or breaking blocks this was causing any items set into the hand during these events _at all_ to get overwritten, rather than just tools. That's a bit of a problem for buckets because buckets rely on a bad hack to handle the modified items. This doesn't fix the tools bug, but that's a job for another time. --- src/pocketmine/Player.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 7431086ec5..7c1edd21dc 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2233,9 +2233,10 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ if($this->canInteract($pos->add(0.5, 0.5, 0.5), $this->isCreative() ? 13 : 7) and !$this->isSpectator()){ $item = $this->inventory->getItemInHand(); + $oldItem = clone $item; if($this->level->useBreakOn($pos, $item, $this, true)){ if($this->isSurvival()){ - if(!$item->equalsExact($this->inventory->getItemInHand())){ + if(!$item->equalsExact($oldItem)){ $this->inventory->setItemInHand($item); } $this->exhaust(0.025, PlayerExhaustEvent::CAUSE_MINING); @@ -2278,8 +2279,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ if($this->canInteract($pos->add(0.5, 0.5, 0.5), 13) and !$this->isSpectator()){ $item = $this->inventory->getItemInHand(); //this is a copy of the real item + $oldItem = clone $item; if($this->level->useItemOn($pos, $item, $face, $clickOffset, $this, true)){ - if($this->isSurvival() and !$item->equalsExact($this->inventory->getItemInHand())){ + if($this->isSurvival() and !$item->equalsExact($oldItem)){ $this->inventory->setItemInHand($item); } return true; From b3d8d10bec8f592f2534b0735939559c96cc7c43 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 14 Aug 2018 19:21:13 +0100 Subject: [PATCH 0109/3224] Player: move flight toggling to its own method --- src/pocketmine/Player.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 7c1edd21dc..65ced448a5 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2411,6 +2411,16 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } } + public function toggleFlight(bool $fly) : void{ + $ev = new PlayerToggleFlightEvent($this, $fly); + $this->server->getPluginManager()->callEvent($ev); + if($ev->isCancelled()){ + $this->sendSettings(); + }else{ + $this->setFlying($fly); + } + } + public function animate(int $action) : bool{ $this->server->getPluginManager()->callEvent($ev = new PlayerAnimationEvent($this, $action)); if($ev->isCancelled()){ @@ -2442,13 +2452,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->kick($this->server->getLanguage()->translateString("kick.reason.cheat", ["%ability.flight"])); return true; }elseif($isFlying !== $this->isFlying()){ - $this->server->getPluginManager()->callEvent($ev = new PlayerToggleFlightEvent($this, $isFlying)); - if($ev->isCancelled()){ - $this->sendSettings(); - }else{ - $this->flying = $ev->isFlying(); - } - + $this->toggleFlight($isFlying); $handled = true; } From 728142b1131d14e99bbccff5019280da4c2eed5f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 14 Aug 2018 19:39:06 +0100 Subject: [PATCH 0110/3224] Level: remove useless check for RIGHT_CLICK_AIR it's impossible for this to fire because of the condition immediately above, and makes no sense anyway... --- src/pocketmine/level/Level.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index a7c0613fff..768dd0920c 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1773,7 +1773,7 @@ class Level implements ChunkManager, Metadatable{ } if($player !== null){ - $ev = new PlayerInteractEvent($player, $item, $blockClicked, $clickVector, $face, $blockClicked->getId() === 0 ? PlayerInteractEvent::RIGHT_CLICK_AIR : PlayerInteractEvent::RIGHT_CLICK_BLOCK); + $ev = new PlayerInteractEvent($player, $item, $blockClicked, $clickVector, $face, PlayerInteractEvent::RIGHT_CLICK_BLOCK); if($this->checkSpawnProtection($player, $blockClicked)){ $ev->setCancelled(); //set it to cancelled so plugins can bypass this } From 2ee0436f46f5b7402a519640bb2ef7de70263aa4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 15 Aug 2018 14:50:58 +0100 Subject: [PATCH 0111/3224] Continued cleanup of runtime entity NBT removal it's no longer necessary to force-write these, since the NBT is now ephemeral. Any tag type mismatches should be dealt with on read, after which the original tag will be discarded anyway. --- src/pocketmine/entity/Entity.php | 2 +- src/pocketmine/entity/Human.php | 6 +++--- src/pocketmine/entity/Living.php | 2 +- src/pocketmine/entity/object/FallingBlock.php | 2 +- src/pocketmine/entity/object/PrimedTNT.php | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 1a909f0fea..ce456e9ed9 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -838,7 +838,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ public function saveNBT() : CompoundTag{ $nbt = new CompoundTag(); if(!($this instanceof Player)){ - $nbt->setString("id", $this->getSaveId(), true); + $nbt->setString("id", $this->getSaveId()); if($this->getNameTag() !== ""){ $nbt->setString("CustomName", $this->getNameTag()); diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 68d99d7e01..db82118d13 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -769,9 +769,9 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ public function saveNBT() : CompoundTag{ $nbt = parent::saveNBT(); - $nbt->setInt("foodLevel", (int) $this->getFood(), true); - $nbt->setFloat("foodExhaustionLevel", $this->getExhaustion(), true); - $nbt->setFloat("foodSaturationLevel", $this->getSaturation(), true); + $nbt->setInt("foodLevel", (int) $this->getFood()); + $nbt->setFloat("foodExhaustionLevel", $this->getExhaustion()); + $nbt->setFloat("foodSaturationLevel", $this->getSaturation()); $nbt->setInt("foodTickTimer", $this->foodTickTimer); $nbt->setInt("XpLevel", $this->getXpLevel()); diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 1c0e12b47d..c9b18f91c0 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -148,7 +148,7 @@ abstract class Living extends Entity implements Damageable{ public function saveNBT() : CompoundTag{ $nbt = parent::saveNBT(); - $nbt->setFloat("Health", $this->getHealth(), true); + $nbt->setFloat("Health", $this->getHealth()); if(count($this->effects) > 0){ $effects = []; diff --git a/src/pocketmine/entity/object/FallingBlock.php b/src/pocketmine/entity/object/FallingBlock.php index 4db9c18dcf..7aa93469a0 100644 --- a/src/pocketmine/entity/object/FallingBlock.php +++ b/src/pocketmine/entity/object/FallingBlock.php @@ -135,7 +135,7 @@ class FallingBlock extends Entity{ public function saveNBT() : CompoundTag{ $nbt = parent::saveNBT(); - $nbt->setInt("TileID", $this->block->getId(), true); + $nbt->setInt("TileID", $this->block->getId()); $nbt->setByte("Data", $this->block->getDamage()); return $nbt; diff --git a/src/pocketmine/entity/object/PrimedTNT.php b/src/pocketmine/entity/object/PrimedTNT.php index 5db3438fae..495299c8dd 100644 --- a/src/pocketmine/entity/object/PrimedTNT.php +++ b/src/pocketmine/entity/object/PrimedTNT.php @@ -76,7 +76,7 @@ class PrimedTNT extends Entity implements Explosive{ public function saveNBT() : CompoundTag{ $nbt = parent::saveNBT(); - $nbt->setShort("Fuse", $this->fuse, true); //older versions incorrectly saved this as a byte + $nbt->setShort("Fuse", $this->fuse); return $nbt; } From d32b9ec5dc843c9985a1c215211a7a54dd1e4d1b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 15 Aug 2018 14:56:02 +0100 Subject: [PATCH 0112/3224] Player: remove useless write to NBT the parent constructor doesn't care about this tag, and the tag is discarded afterwards. --- src/pocketmine/Player.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 65ced448a5..6f3503e218 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1857,7 +1857,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ /** @var Level $level */ $level = $this->server->getDefaultLevel(); //TODO: default level may be null - $namedtag->setString("Level", $level->getFolderName()); $spawnLocation = $level->getSafeSpawn(); $namedtag->setTag(new ListTag("Pos", [ new DoubleTag("", $spawnLocation->x), From 2438d20971e1bbeb3e34e7ecd77100b00a41a0ef Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 16 Aug 2018 22:23:09 +0100 Subject: [PATCH 0113/3224] Fixed zero-compression being ignored for small packets --- src/pocketmine/Server.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 528e1743b8..7343854b0d 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1939,7 +1939,7 @@ class Server{ $task = new CompressBatchTask($stream, $compressionLevel, $promise); $this->asyncPool->submitTask($task); }else{ - $promise->resolve(NetworkCompression::compress($stream->buffer)); + $promise->resolve(NetworkCompression::compress($stream->buffer, $compressionLevel)); } return $promise; From f8e3b0b16b531fbdc812e2b079109931b414b74e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 Aug 2018 13:22:53 +0100 Subject: [PATCH 0114/3224] Support bot: Be a little less rude --- .github/support.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/support.yml b/.github/support.yml index cb869d76e6..1fab0ebccd 100644 --- a/.github/support.yml +++ b/.github/support.yml @@ -5,7 +5,8 @@ supportLabel: "Support request" # Comment to post on issues marked as support requests. Add a link # to a support page, or set to `false` to disable supportComment: > - This issue tracker is not a support forum. Please use the [forums](https://forums.pmmp.io) for support. + Thanks, but this issue tracker is intended for bugs reports only, not for support requests. Please use the [forums](https://forums.pmmp.io) for support requests. + Please read the guidelines on [submitting an issue](https://github.com/pmmp/PocketMine-MP/blob/master/CONTRIBUTING.md#creating-an-issue) before opening any further issues. # Whether to close issues marked as support requests close: true # Whether to lock issues marked as support requests From a306421737cd795980f6ed787813d4b4350c9cc0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 Aug 2018 13:38:19 +0100 Subject: [PATCH 0115/3224] Entity: remove lastX lastY lastZ lastYaw lastPitch, replace with lastLocation object field --- src/pocketmine/Player.php | 25 +++++++------------------ src/pocketmine/entity/Entity.php | 29 ++++++----------------------- 2 files changed, 13 insertions(+), 41 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 6f3503e218..bf9919c812 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1506,7 +1506,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $diff = $this->distanceSquared($newPos) / $tickDiff ** 2; if($this->isSurvival() and !$revert and $diff > 0.0625){ - $ev = new PlayerIllegalMoveEvent($this, $newPos, new Vector3($this->lastX, $this->lastY, $this->lastZ)); + $ev = new PlayerIllegalMoveEvent($this, $newPos, $this->lastLocation->asVector3()); $ev->setCancelled($this->allowMovementCheats); $this->server->getPluginManager()->callEvent($ev); @@ -1523,19 +1523,14 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } } - $from = new Location($this->lastX, $this->lastY, $this->lastZ, $this->lastYaw, $this->lastPitch, $this->level); - $to = $this->getLocation(); + $from = clone $this->lastLocation; + $to = $this->asLocation(); - $delta = (($this->lastX - $to->x) ** 2) + (($this->lastY - $to->y) ** 2) + (($this->lastZ - $to->z) ** 2); - $deltaAngle = abs($this->lastYaw - $to->yaw) + abs($this->lastPitch - $to->pitch); + $delta = $to->distanceSquared($from); + $deltaAngle = abs($this->lastLocation->yaw - $to->yaw) + abs($this->lastLocation->pitch - $to->pitch); if(!$revert and ($delta > 0.0001 or $deltaAngle > 1.0)){ - $this->lastX = $to->x; - $this->lastY = $to->y; - $this->lastZ = $to->z; - - $this->lastYaw = $to->yaw; - $this->lastPitch = $to->pitch; + $this->lastLocation = clone $to; //avoid PlayerMoveEvent modifying this $ev = new PlayerMoveEvent($this, $from, $to); @@ -1563,13 +1558,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } if($revert){ - - $this->lastX = $from->x; - $this->lastY = $from->y; - $this->lastZ = $from->z; - - $this->lastYaw = $from->yaw; - $this->lastPitch = $from->pitch; + $this->lastLocation = $from; $this->setPosition($from); $this->sendPosition($from, $from->yaw, $from->pitch, MovePlayerPacket::MODE_RESET); diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index ce456e9ed9..a2a694abc2 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -376,13 +376,8 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ /** @var Block[] */ protected $blocksAround = []; - /** @var float|null */ - public $lastX = null; - /** @var float|null */ - public $lastY = null; - /** @var float|null */ - public $lastZ = null; - + /** @var Location */ + protected $lastLocation; /** @var Vector3 */ protected $motion; /** @var Vector3 */ @@ -393,12 +388,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ /** @var Vector3 */ public $temporalVector; - - /** @var float */ - public $lastYaw; - /** @var float */ - public $lastPitch; - /** @var AxisAlignedBB */ public $boundingBox; /** @var bool */ @@ -1110,18 +1099,13 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } protected function updateMovement(bool $teleport = false) : void{ - $diffPosition = ($this->x - $this->lastX) ** 2 + ($this->y - $this->lastY) ** 2 + ($this->z - $this->lastZ) ** 2; - $diffRotation = ($this->yaw - $this->lastYaw) ** 2 + ($this->pitch - $this->lastPitch) ** 2; + $diffPosition = $this->distanceSquared($this->lastLocation); + $diffRotation = ($this->yaw - $this->lastLocation->yaw) ** 2 + ($this->pitch - $this->lastLocation->pitch) ** 2; $diffMotion = $this->motion->subtract($this->lastMotion)->lengthSquared(); if($teleport or $diffPosition > 0.0001 or $diffRotation > 1.0){ - $this->lastX = $this->x; - $this->lastY = $this->y; - $this->lastZ = $this->z; - - $this->lastYaw = $this->yaw; - $this->lastPitch = $this->pitch; + $this->lastLocation = $this->asLocation(); $this->broadcastMovement($teleport); } @@ -1819,8 +1803,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } protected function resetLastMovements() : void{ - list($this->lastX, $this->lastY, $this->lastZ) = [$this->x, $this->y, $this->z]; - list($this->lastYaw, $this->lastPitch) = [$this->yaw, $this->pitch]; + $this->lastLocation = $this->asLocation(); $this->lastMotion = clone $this->motion; } From 06d7ee283d8ac37491f1bdcb936020d14fee8af0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 Aug 2018 13:42:00 +0100 Subject: [PATCH 0116/3224] Player: Don't use iusername in cases where it's useless these calls all do strtolower() anyway, so having iusername here just makes it confusing. --- src/pocketmine/Player.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index bf9919c812..743a965d6f 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -305,7 +305,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } public function isBanned() : bool{ - return $this->server->getNameBans()->isBanned($this->iusername); + return $this->server->getNameBans()->isBanned($this->username); } public function setBanned(bool $value){ @@ -318,14 +318,14 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } public function isWhitelisted() : bool{ - return $this->server->isWhitelisted($this->iusername); + return $this->server->isWhitelisted($this->username); } public function setWhitelisted(bool $value){ if($value){ - $this->server->addWhitelist($this->iusername); + $this->server->addWhitelist($this->username); }else{ - $this->server->removeWhitelist($this->iusername); + $this->server->removeWhitelist($this->username); } } @@ -1769,7 +1769,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return true; } - if(!$this->server->isWhitelisted($this->iusername) and $this->kick("Server is white-listed", false)){ + if(!$this->server->isWhitelisted($this->username) and $this->kick("Server is white-listed", false)){ return true; } From 475ec413e5fd0dc4bdb0422d6b7aff67828068d3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 19 Aug 2018 14:23:41 +0100 Subject: [PATCH 0117/3224] Removed deprecated ServerCommandEvent and RemoteServerCommandEvent if you get rekt by these changes... USE A RELEASE like we've been telling you for so long! --- src/pocketmine/Server.php | 6 +- .../event/server/RemoteServerCommandEvent.php | 42 ----------- .../event/server/ServerCommandEvent.php | 75 ------------------- src/pocketmine/network/rcon/RCON.php | 9 +-- 4 files changed, 2 insertions(+), 130 deletions(-) delete mode 100644 src/pocketmine/event/server/RemoteServerCommandEvent.php delete mode 100644 src/pocketmine/event/server/ServerCommandEvent.php diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 18cd70b4e4..a6dc52962a 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -42,7 +42,6 @@ use pocketmine\event\player\PlayerDataSaveEvent; use pocketmine\event\server\CommandEvent; use pocketmine\event\server\DataPacketBroadcastEvent; use pocketmine\event\server\QueryRegenerateEvent; -use pocketmine\event\server\ServerCommandEvent; use pocketmine\inventory\CraftingManager; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\Item; @@ -1979,10 +1978,7 @@ class Server{ public function checkConsole(){ Timings::$serverCommandTimer->startTiming(); while(($line = $this->console->getLine()) !== null){ - $this->pluginManager->callEvent($ev = new ServerCommandEvent($this->consoleSender, $line)); - if(!$ev->isCancelled()){ - $this->dispatchCommand($ev->getSender(), $ev->getCommand()); - } + $this->dispatchCommand($this->consoleSender, $line); } Timings::$serverCommandTimer->stopTiming(); } diff --git a/src/pocketmine/event/server/RemoteServerCommandEvent.php b/src/pocketmine/event/server/RemoteServerCommandEvent.php deleted file mode 100644 index 9b1039104c..0000000000 --- a/src/pocketmine/event/server/RemoteServerCommandEvent.php +++ /dev/null @@ -1,42 +0,0 @@ -sender = $sender; - $this->command = $command; - } - - /** - * @return CommandSender - */ - public function getSender() : CommandSender{ - return $this->sender; - } - - /** - * @return string - */ - public function getCommand() : string{ - return $this->command; - } - - /** - * @param string $command - */ - public function setCommand(string $command) : void{ - $this->command = $command; - } -} diff --git a/src/pocketmine/network/rcon/RCON.php b/src/pocketmine/network/rcon/RCON.php index cf57cd1067..919f8bfe9f 100644 --- a/src/pocketmine/network/rcon/RCON.php +++ b/src/pocketmine/network/rcon/RCON.php @@ -28,7 +28,6 @@ declare(strict_types=1); namespace pocketmine\network\rcon; use pocketmine\command\RemoteConsoleCommandSender; -use pocketmine\event\server\RemoteServerCommandEvent; use pocketmine\Server; use pocketmine\snooze\SleeperNotifier; use pocketmine\utils\TextFormat; @@ -95,13 +94,7 @@ class RCON{ public function check() : void{ $response = new RemoteConsoleCommandSender(); - $command = $this->instance->cmd; - - $this->server->getPluginManager()->callEvent($ev = new RemoteServerCommandEvent($response, $command)); - - if(!$ev->isCancelled()){ - $this->server->dispatchCommand($ev->getSender(), $ev->getCommand()); - } + $this->server->dispatchCommand($response, $this->instance->cmd); $this->instance->response = TextFormat::clean($response->getMessage()); $this->instance->synchronized(function(RCONInstance $thread){ From 7c41bfcdf3f2157f68d28832fa83f8ccfb76c2aa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 19 Aug 2018 16:37:04 +0100 Subject: [PATCH 0118/3224] Removed Tile numeric runtime IDs, use block hashes instead Tiles are level-local and are not indexed globally like entities. There is pretty much zero point to them having numeric runtime IDs. --- src/pocketmine/level/Level.php | 25 +++++-------------------- src/pocketmine/level/format/Chunk.php | 15 ++++++--------- src/pocketmine/tile/Tile.php | 12 +----------- 3 files changed, 12 insertions(+), 40 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 768dd0920c..9e9514fa9b 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -746,9 +746,9 @@ class Level implements ChunkManager, Metadatable{ $this->timings->tileEntityTick->startTiming(); Timings::$tickTileEntityTimer->startTiming(); //Update tiles that need update - foreach($this->updateTiles as $id => $tile){ + foreach($this->updateTiles as $blockHash => $tile){ if(!$tile->onUpdate()){ - unset($this->updateTiles[$id]); + unset($this->updateTiles[$blockHash]); } } Timings::$tickTileEntityTimer->stopTiming(); @@ -1999,15 +1999,6 @@ class Level implements ChunkManager, Metadatable{ return $this->tiles; } - /** - * @param $tileId - * - * @return Tile|null - */ - public function getTileById(int $tileId){ - return $this->tiles[$tileId] ?? null; - } - /** * Returns a list of the players in this level * @@ -2048,13 +2039,7 @@ class Level implements ChunkManager, Metadatable{ * @return Tile|null */ public function getTileAt(int $x, int $y, int $z) : ?Tile{ - $chunk = $this->getChunk($x >> 4, $z >> 4); - - if($chunk !== null){ - return $chunk->getTile($x & 0x0f, $y, $z & 0x0f); - } - - return null; + return $this->tiles[Level::blockHash($x, $y, $z)] ?? null; } /** @@ -2589,7 +2574,7 @@ class Level implements ChunkManager, Metadatable{ throw new \InvalidStateException("Attempted to create tile " . get_class($tile) . " in unloaded chunk $chunkX $chunkZ"); } - $this->tiles[$tile->getId()] = $tile; + $this->tiles[Level::blockHash($tile->x, $tile->y, $tile->z)] = $tile; $this->clearChunkCache($chunkX, $chunkZ); } @@ -2603,7 +2588,7 @@ class Level implements ChunkManager, Metadatable{ throw new LevelException("Invalid Tile level"); } - unset($this->tiles[$tile->getId()], $this->updateTiles[$tile->getId()]); + unset($this->tiles[$blockHash = Level::blockHash($tile->x, $tile->y, $tile->z)], $this->updateTiles[$blockHash]); $chunkX = $tile->getFloorX() >> 4; $chunkZ = $tile->getFloorZ() >> 4; diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index a373a2cd0a..88d8d5e1d1 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -69,8 +69,6 @@ class Chunk{ /** @var Tile[] */ protected $tiles = []; - /** @var Tile[] */ - protected $tileList = []; /** @var Entity[] */ protected $entities = []; @@ -595,11 +593,11 @@ class Chunk{ if($tile->isClosed()){ throw new \InvalidArgumentException("Attempted to add a garbage closed Tile to a chunk"); } - $this->tiles[$tile->getId()] = $tile; - if(isset($this->tileList[$index = (($tile->x & 0x0f) << 12) | (($tile->z & 0x0f) << 8) | ($tile->y & 0xff)]) and $this->tileList[$index] !== $tile){ - $this->tileList[$index]->close(); + + if(isset($this->tiles[$index = (($tile->x & 0x0f) << 12) | (($tile->z & 0x0f) << 8) | ($tile->y & 0xff)]) and $this->tiles[$index] !== $tile){ + $this->tiles[$index]->close(); } - $this->tileList[$index] = $tile; + $this->tiles[$index] = $tile; if($this->isInit){ $this->hasChanged = true; } @@ -609,8 +607,7 @@ class Chunk{ * @param Tile $tile */ public function removeTile(Tile $tile){ - unset($this->tiles[$tile->getId()]); - unset($this->tileList[(($tile->x & 0x0f) << 12) | (($tile->z & 0x0f) << 8) | ($tile->y & 0xff)]); + unset($this->tiles[(($tile->x & 0x0f) << 12) | (($tile->z & 0x0f) << 8) | ($tile->y & 0xff)]); if($this->isInit){ $this->hasChanged = true; } @@ -650,7 +647,7 @@ class Chunk{ */ public function getTile(int $x, int $y, int $z){ $index = ($x << 12) | ($z << 8) | $y; - return $this->tileList[$index] ?? null; + return $this->tiles[$index] ?? null; } /** diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/tile/Tile.php index 19c16df75f..2443e49b73 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/tile/Tile.php @@ -61,9 +61,6 @@ abstract class Tile extends Position{ public const SIGN = "Sign"; public const SKULL = "Skull"; - /** @var int */ - public static $tileCount = 1; - /** @var string[] classes that extend Tile */ private static $knownTiles = []; /** @var string[][] */ @@ -71,8 +68,6 @@ abstract class Tile extends Position{ /** @var string */ public $name; - /** @var int */ - public $id; /** @var bool */ public $closed = false; /** @var Server */ @@ -148,7 +143,6 @@ abstract class Tile extends Position{ $this->server = $level->getServer(); $this->name = ""; - $this->id = Tile::$tileCount++; parent::__construct($nbt->getInt(self::TAG_X), $nbt->getInt(self::TAG_Y), $nbt->getInt(self::TAG_Z), $level); $this->readSaveData($nbt); @@ -156,10 +150,6 @@ abstract class Tile extends Position{ $this->getLevel()->addTile($this); } - public function getId() : int{ - return $this->id; - } - /** * Reads additional data from the CompoundTag on tile creation. * @@ -253,7 +243,7 @@ abstract class Tile extends Position{ if($this->closed){ throw new \InvalidStateException("Cannot schedule update on garbage tile " . get_class($this)); } - $this->level->updateTiles[$this->id] = $this; + $this->level->updateTiles[Level::blockHash($this->x, $this->y, $this->z)] = $this; } public function isClosed() : bool{ From 848bce193c5560dc245d1cdac5afcb961b85e482 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 19 Aug 2018 16:56:50 +0100 Subject: [PATCH 0119/3224] Chunk: change tile storage hash function to unbind Y coordinate this isn't strictly needed but it is more scalable in the case of future build height limit lifts. --- src/pocketmine/level/format/Chunk.php | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index 88d8d5e1d1..1cdd005616 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -594,7 +594,7 @@ class Chunk{ throw new \InvalidArgumentException("Attempted to add a garbage closed Tile to a chunk"); } - if(isset($this->tiles[$index = (($tile->x & 0x0f) << 12) | (($tile->z & 0x0f) << 8) | ($tile->y & 0xff)]) and $this->tiles[$index] !== $tile){ + if(isset($this->tiles[$index = Chunk::blockHash($tile->x, $tile->y, $tile->z)]) and $this->tiles[$index] !== $tile){ $this->tiles[$index]->close(); } $this->tiles[$index] = $tile; @@ -607,7 +607,7 @@ class Chunk{ * @param Tile $tile */ public function removeTile(Tile $tile){ - unset($this->tiles[(($tile->x & 0x0f) << 12) | (($tile->z & 0x0f) << 8) | ($tile->y & 0xff)]); + unset($this->tiles[Chunk::blockHash($tile->x, $tile->y, $tile->z)]); if($this->isInit){ $this->hasChanged = true; } @@ -646,8 +646,7 @@ class Chunk{ * @return Tile|null */ public function getTile(int $x, int $y, int $z){ - $index = ($x << 12) | ($z << 8) | $y; - return $this->tiles[$index] ?? null; + return $this->tiles[Chunk::blockHash($x, $y, $z)] ?? null; } /** @@ -922,4 +921,17 @@ class Chunk{ $chunk->terrainGenerated = (bool) ($flags & 1); return $chunk; } + + /** + * Hashes the given chunk block coordinates into a single integer. + * + * @param int $x 0-15 + * @param int $y + * @param int $z 0-15 + * + * @return int + */ + public static function blockHash(int $x, int $y, int $z) : int{ + return ($y << 8) | (($z & 0x0f) << 4) | ($x & 0x0f); + } } From d6376a236d7dd71ad83ecd17795703610fea6b47 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 22 Aug 2018 19:20:21 +0100 Subject: [PATCH 0120/3224] Player: assign allowFlight directly instead of using setter fixes #2397 This was changed by a4939b6bf11e3da6f3ffc569540fafd8eba84545 without apparent reason. It causes AdventureSettings to be sent too early. --- src/pocketmine/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 06a72d3a5d..c5e46ff37b 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1897,7 +1897,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->gamemode = $this->server->getGamemode(); } - $this->setAllowFlight($this->isCreative()); + $this->allowFlight = $this->isCreative(); $this->keepMovement = $this->isSpectator() || $this->allowMovementCheats(); if($this->isOp()){ $this->setRemoveFormat(false); From 5d1ec1ad49f6e93faedbcda57fe7077432f3c045 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 25 Aug 2018 18:38:10 +0100 Subject: [PATCH 0121/3224] Server: remove deprecated parameter from findEntity() --- src/pocketmine/Server.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 0818f64832..a2f8d92c66 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1140,12 +1140,11 @@ class Server{ * Searches all levels for the entity with the specified ID. * Useful for tracking entities across multiple worlds without needing strong references. * - * @param int $entityId - * @param Level|null $expectedLevel @deprecated Level to look in first for the target + * @param int $entityId * * @return Entity|null */ - public function findEntity(int $entityId, Level $expectedLevel = null){ + public function findEntity(int $entityId){ foreach($this->levels as $level){ assert(!$level->isClosed()); if(($entity = $level->getEntity($entityId)) instanceof Entity){ From 66e46e1c0751a59ed134d1a1acf044209d5d98aa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 26 Aug 2018 18:57:08 +0100 Subject: [PATCH 0122/3224] Level: use chunk records for tile reading in getTileAt() the previous revision caused a crash when clicking on the bottom of the world due to a block hash being out of bounds. --- src/pocketmine/level/Level.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 9e9514fa9b..533febadf2 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -2039,7 +2039,7 @@ class Level implements ChunkManager, Metadatable{ * @return Tile|null */ public function getTileAt(int $x, int $y, int $z) : ?Tile{ - return $this->tiles[Level::blockHash($x, $y, $z)] ?? null; + return ($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null ? $chunk->getTile($x & 0x0f, $y, $z & 0x0f) : null; } /** From 9b49d0971481288abb8172fbb9616c5bb0b40355 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jan 2018 16:48:19 +0000 Subject: [PATCH 0123/3224] LevelProvider: Added methods to get and set rain/lightning level and times --- .../level/format/io/LevelProvider.php | 44 +++++++++++++++++++ .../level/format/io/leveldb/LevelDB.php | 32 ++++++++++++++ .../level/format/io/region/McRegion.php | 44 ++++++++++++++++++- 3 files changed, 119 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/level/format/io/LevelProvider.php b/src/pocketmine/level/format/io/LevelProvider.php index 3c07f3023e..bf7ce85899 100644 --- a/src/pocketmine/level/format/io/LevelProvider.php +++ b/src/pocketmine/level/format/io/LevelProvider.php @@ -152,6 +152,50 @@ interface LevelProvider{ */ public function setDifficulty(int $difficulty); + /** + * Returns the time in ticks to the next rain level change. + * @return int + */ + public function getRainTime() : int; + + /** + * Sets the time in ticks to the next rain level change. + * @param int $ticks + */ + public function setRainTime(int $ticks) : void; + + /** + * @return float 0.0 - 1.0 + */ + public function getRainLevel() : float; + + /** + * @param float $level 0.0 - 1.0 + */ + public function setRainLevel(float $level) : void; + + /** + * Returns the time in ticks to the next lightning level change. + * @return int + */ + public function getLightningTime() : int; + + /** + * Sets the time in ticks to the next lightning level change. + * @param int $ticks + */ + public function setLightningTime(int $ticks) : void; + + /** + * @return float 0.0 - 1.0 + */ + public function getLightningLevel() : float; + + /** + * @param float $level 0.0 - 1.0 + */ + public function setLightningLevel(float $level) : void; + /** * Performs garbage collection in the level provider, such as cleaning up regions in Region-based worlds. */ diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index 6c50ac9fce..d82c5a8332 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -266,6 +266,38 @@ class LevelDB extends BaseLevelProvider{ $this->levelData->setInt("Difficulty", $difficulty); //yes, this is intended! (in PE: int, PC: byte) } + public function getRainTime() : int{ + return $this->levelData->getInt("rainTime", 0); + } + + public function setRainTime(int $ticks) : void{ + $this->levelData->setInt("rainTime", $ticks); + } + + public function getRainLevel() : float{ + return $this->levelData->getFloat("rainLevel", 0.0); + } + + public function setRainLevel(float $level) : void{ + $this->levelData->setFloat("rainLevel", $level); + } + + public function getLightningTime() : int{ + return $this->levelData->getInt("lightningTime", 0); + } + + public function setLightningTime(int $ticks) : void{ + $this->levelData->setInt("lightningTime", $ticks); + } + + public function getLightningLevel() : float{ + return $this->levelData->getFloat("lightningLevel", 0.0); + } + + public function setLightningLevel(float $level) : void{ + $this->levelData->setFloat("lightningLevel", $level); + } + /** * @param int $chunkX * @param int $chunkZ diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index 1f3f77bfc2..35bf7f1afd 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -33,7 +33,7 @@ use pocketmine\level\Level; use pocketmine\nbt\BigEndianNBTStream; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\{ - ByteArrayTag, ByteTag, CompoundTag, IntArrayTag, IntTag, ListTag, LongTag, StringTag + ByteArrayTag, ByteTag, CompoundTag, FloatTag, IntArrayTag, IntTag, ListTag, LongTag, StringTag }; use pocketmine\utils\MainLogger; @@ -268,6 +268,48 @@ class McRegion extends BaseLevelProvider{ $this->levelData->setByte("Difficulty", $difficulty); } + public function getRainTime() : int{ + return $this->levelData->getInt("rainTime", 0); + } + + public function setRainTime(int $ticks) : void{ + $this->levelData->setInt("rainTime", $ticks); + } + + public function getRainLevel() : float{ + if($this->levelData->hasTag("rainLevel", FloatTag::class)){ //PocketMine/MCPE + return $this->levelData->getFloat("rainLevel"); + } + + return (float) $this->levelData->getByte("raining", 0); //PC vanilla + } + + public function setRainLevel(float $level) : void{ + $this->levelData->setFloat("rainLevel", $level); //PocketMine/MCPE + $this->levelData->setByte("raining", (int) ceil($level)); //PC vanilla + } + + public function getLightningTime() : int{ + return $this->levelData->getInt("thunderTime", 0); + } + + public function setLightningTime(int $ticks) : void{ + $this->levelData->setInt("thunderTime", $ticks); + } + + public function getLightningLevel() : float{ + if($this->levelData->hasTag("lightningLevel", FloatTag::class)){ //PocketMine/MCPE + return $this->levelData->getFloat("lightningLevel"); + } + + return (float) $this->levelData->getByte("thundering", 0); //PC vanilla + } + + public function setLightningLevel(float $level) : void{ + $this->levelData->setFloat("lightningLevel", $level); //PocketMine/MCPE + $this->levelData->setByte("thundering", (int) ceil($level)); //PC vanilla + } + public function doGarbageCollection(){ $limit = time() - 300; foreach($this->regions as $index => $region){ From cf7071de3d22b7c6767869c5cc0ceac539822715 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Aug 2018 17:25:31 +0100 Subject: [PATCH 0124/3224] 3.2.1 is next --- src/pocketmine/PocketMine.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index 99611972d8..a1192ddd30 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -37,8 +37,8 @@ namespace pocketmine { use pocketmine\wizard\SetupWizard; const NAME = "PocketMine-MP"; - const BASE_VERSION = "3.2.0"; - const IS_DEVELOPMENT_BUILD = false; + const BASE_VERSION = "3.2.1"; + const IS_DEVELOPMENT_BUILD = true; const BUILD_NUMBER = 0; const MIN_PHP_VERSION = "7.2.0"; From f2188683381671e803e580ce7770c8c01c1371b4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Sep 2018 19:56:14 +0100 Subject: [PATCH 0125/3224] Separate facing/bearing handling from Vector3, deobfusticate a ton of @shoghicp old code --- composer.json | 2 +- composer.lock | 17 +++--- src/pocketmine/block/Anvil.php | 3 +- src/pocketmine/block/Bed.php | 29 +++------- src/pocketmine/block/Block.php | 13 ++--- src/pocketmine/block/BurningFurnace.php | 11 ++-- src/pocketmine/block/Cactus.php | 15 +++--- src/pocketmine/block/Cake.php | 5 +- src/pocketmine/block/Carpet.php | 5 +- src/pocketmine/block/Chest.php | 27 ++++------ src/pocketmine/block/CobblestoneWall.php | 12 ++--- src/pocketmine/block/Crops.php | 5 +- src/pocketmine/block/Dandelion.php | 5 +- src/pocketmine/block/DeadBush.php | 5 +- src/pocketmine/block/Door.php | 41 +++++++------- src/pocketmine/block/DoublePlant.php | 15 +++--- src/pocketmine/block/EndRod.php | 11 ++-- src/pocketmine/block/EnderChest.php | 15 +++--- src/pocketmine/block/Fallable.php | 4 +- src/pocketmine/block/Farmland.php | 4 +- src/pocketmine/block/Fence.php | 18 +++---- src/pocketmine/block/FenceGate.php | 7 ++- src/pocketmine/block/Fire.php | 10 ++-- src/pocketmine/block/Flower.php | 5 +- src/pocketmine/block/FlowerPot.php | 5 +- src/pocketmine/block/GlazedTerracotta.php | 10 +--- src/pocketmine/block/Grass.php | 4 +- src/pocketmine/block/GrassPath.php | 4 +- src/pocketmine/block/ItemFrame.php | 19 +++---- src/pocketmine/block/Leaves.php | 27 +++++----- src/pocketmine/block/Lever.php | 29 +++++----- src/pocketmine/block/MelonStem.php | 4 +- src/pocketmine/block/Mycelium.php | 4 +- src/pocketmine/block/NetherWartPlant.php | 5 +- src/pocketmine/block/Pumpkin.php | 13 ----- src/pocketmine/block/PumpkinStem.php | 4 +- src/pocketmine/block/Rail.php | 5 +- src/pocketmine/block/RedMushroom.php | 5 +- src/pocketmine/block/Sapling.php | 5 +- src/pocketmine/block/SignPost.php | 7 +-- src/pocketmine/block/Skull.php | 3 +- src/pocketmine/block/Slab.php | 9 ++-- src/pocketmine/block/SnowLayer.php | 5 +- src/pocketmine/block/Stair.php | 18 ++++--- src/pocketmine/block/StandingBanner.php | 7 +-- src/pocketmine/block/Sugarcane.php | 17 +++--- src/pocketmine/block/TallGrass.php | 5 +- src/pocketmine/block/Thin.php | 18 +++---- src/pocketmine/block/Torch.php | 35 ++++++------ src/pocketmine/block/Trapdoor.php | 16 +++--- src/pocketmine/block/Vine.php | 25 ++++----- src/pocketmine/block/WaterLily.php | 5 +- .../block/utils/PillarRotationHelper.php | 12 ++--- src/pocketmine/entity/Entity.php | 47 ++++++---------- src/pocketmine/entity/object/Painting.php | 54 +++++-------------- src/pocketmine/item/PaintingItem.php | 9 ++-- src/pocketmine/tile/Skull.php | 3 +- 57 files changed, 338 insertions(+), 384 deletions(-) diff --git a/composer.json b/composer.json index 86bf002ec9..916c15babb 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "pocketmine/spl": "^0.3.0", "pocketmine/binaryutils": "^0.1.0", "pocketmine/nbt": "^0.2.1", - "pocketmine/math": "^0.2.0", + "pocketmine/math": "dev-master", "pocketmine/snooze": "^0.1.0" }, "autoload": { diff --git a/composer.lock b/composer.lock index a35c199342..6b30e4c312 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9ff16274822f181c2ed533797d2e22f7", + "content-hash": "cef68cbc2596130f6b20e6f2ecdfd58d", "packages": [ { "name": "fgrosse/phpasn1", @@ -183,16 +183,16 @@ }, { "name": "pocketmine/math", - "version": "0.2.1", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "ee299f5c9c444ca526c9c691b920f321458cf0b6" + "reference": "ec66eaa959b86ec3d3d22084a534ae466910aabe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/ee299f5c9c444ca526c9c691b920f321458cf0b6", - "reference": "ee299f5c9c444ca526c9c691b920f321458cf0b6", + "url": "https://api.github.com/repos/pmmp/Math/zipball/ec66eaa959b86ec3d3d22084a534ae466910aabe", + "reference": "ec66eaa959b86ec3d3d22084a534ae466910aabe", "shasum": "" }, "require": { @@ -210,10 +210,10 @@ ], "description": "PHP library containing math related code used in PocketMine-MP", "support": { - "source": "https://github.com/pmmp/Math/tree/0.2.1", + "source": "https://github.com/pmmp/Math/tree/master", "issues": "https://github.com/pmmp/Math/issues" }, - "time": "2018-08-15T15:43:27+00:00" + "time": "2018-09-05T18:50:26+00:00" }, { "name": "pocketmine/nbt", @@ -367,7 +367,8 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "ext-pthreads": 20 + "ext-pthreads": 20, + "pocketmine/math": 20 }, "prefer-stable": false, "prefer-lowest": false, diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index 1f4ed8b7ca..7279fc8c3c 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -27,6 +27,7 @@ use pocketmine\inventory\AnvilInventory; use pocketmine\item\Item; use pocketmine\item\TieredTool; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Bearing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -94,7 +95,7 @@ class Anvil extends Fallable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $direction = ($player !== null ? $player->getDirection() : 0) & 0x03; + $direction = $player !== null ? Bearing::rotate($player->getDirection(), -1) : 0; $this->meta = $this->getVariant() | $direction; return $this->getLevel()->setBlock($blockReplace, $this, true, true); } diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index b4024b238a..229fbedad0 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -28,6 +28,8 @@ use pocketmine\item\ItemFactory; use pocketmine\lang\TranslationContainer; use pocketmine\level\Level; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Bearing; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Bed as TileBed; @@ -90,26 +92,9 @@ class Bed extends Transparent{ * @return int */ public static function getOtherHalfSide(int $meta, bool $isHead = false) : int{ - $rotation = $meta & 0x03; - $side = -1; - - switch($rotation){ - case 0x00: //South - $side = Vector3::SIDE_SOUTH; - break; - case 0x01: //West - $side = Vector3::SIDE_WEST; - break; - case 0x02: //North - $side = Vector3::SIDE_NORTH; - break; - case 0x03: //East - $side = Vector3::SIDE_EAST; - break; - } - + $side = Bearing::toFacing($meta & 0x03); if($isHead){ - $side = Vector3::getOppositeSide($side); + $side = Facing::opposite($side); } return $side; @@ -165,11 +150,11 @@ class Bed extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $down = $this->getSide(Vector3::SIDE_DOWN); + $down = $this->getSide(Facing::DOWN); if(!$down->isTransparent()){ - $meta = (($player instanceof Player ? $player->getDirection() : 0) - 1) & 0x03; + $meta = $player instanceof Player ? Bearing::rotate($player->getDirection(), 2) : 0; //rotate 180 degrees $next = $this->getSide(self::getOtherHalfSide($meta)); - if($next->canBeReplaced() and !$next->getSide(Vector3::SIDE_DOWN)->isTransparent()){ + if($next->canBeReplaced() and !$next->getSide(Facing::DOWN)->isTransparent()){ $this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->id, $meta), true, true); $this->getLevel()->setBlock($next, BlockFactory::get($this->id, $meta | self::BITFLAG_HEAD), true, true); diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 74e1dd05fc..777c9311a6 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -32,6 +32,7 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\level\Position; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\RayTraceResult; use pocketmine\math\Vector3; use pocketmine\metadata\Metadatable; @@ -588,10 +589,10 @@ class Block extends Position implements BlockIds, Metadatable{ */ public function getHorizontalSides() : array{ return [ - $this->getSide(Vector3::SIDE_NORTH), - $this->getSide(Vector3::SIDE_SOUTH), - $this->getSide(Vector3::SIDE_WEST), - $this->getSide(Vector3::SIDE_EAST) + $this->getSide(Facing::NORTH), + $this->getSide(Facing::SOUTH), + $this->getSide(Facing::WEST), + $this->getSide(Facing::EAST) ]; } @@ -603,8 +604,8 @@ class Block extends Position implements BlockIds, Metadatable{ public function getAllSides() : array{ return array_merge( [ - $this->getSide(Vector3::SIDE_DOWN), - $this->getSide(Vector3::SIDE_UP) + $this->getSide(Facing::DOWN), + $this->getSide(Facing::UP) ], $this->getHorizontalSides() ); diff --git a/src/pocketmine/block/BurningFurnace.php b/src/pocketmine/block/BurningFurnace.php index 01bbd67798..98d0c135dd 100644 --- a/src/pocketmine/block/BurningFurnace.php +++ b/src/pocketmine/block/BurningFurnace.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\item\TieredTool; +use pocketmine\math\Bearing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Furnace as TileFurnace; @@ -61,13 +62,9 @@ class BurningFurnace extends Solid{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $faces = [ - 0 => 4, - 1 => 2, - 2 => 5, - 3 => 3 - ]; - $this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0]; + if($player !== null){ + $this->meta = Bearing::toFacing($player->getDirection()); + } $this->getLevel()->setBlock($blockReplace, $this, true, true); Tile::createTile(Tile::FURNACE, $this->getLevel(), TileFurnace::createNBT($this, $face, $item, $player)); diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index 105e2ab1c4..8964cd2485 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -29,6 +29,7 @@ use pocketmine\event\entity\EntityDamageByBlockEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\Server; @@ -64,7 +65,7 @@ class Cactus extends Transparent{ } public function onNearbyBlockChange() : void{ - $down = $this->getSide(Vector3::SIDE_DOWN); + $down = $this->getSide(Facing::DOWN); if($down->getId() !== self::SAND and $down->getId() !== self::CACTUS){ $this->getLevel()->useBreakOn($this); }else{ @@ -83,7 +84,7 @@ class Cactus extends Transparent{ } public function onRandomTick() : void{ - if($this->getSide(Vector3::SIDE_DOWN)->getId() !== self::CACTUS){ + if($this->getSide(Facing::DOWN)->getId() !== self::CACTUS){ if($this->meta === 0x0f){ for($y = 1; $y < 3; ++$y){ $b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z); @@ -104,12 +105,12 @@ class Cactus extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $down = $this->getSide(Vector3::SIDE_DOWN); + $down = $this->getSide(Facing::DOWN); if($down->getId() === self::SAND or $down->getId() === self::CACTUS){ - $block0 = $this->getSide(Vector3::SIDE_NORTH); - $block1 = $this->getSide(Vector3::SIDE_SOUTH); - $block2 = $this->getSide(Vector3::SIDE_WEST); - $block3 = $this->getSide(Vector3::SIDE_EAST); + $block0 = $this->getSide(Facing::NORTH); + $block1 = $this->getSide(Facing::SOUTH); + $block2 = $this->getSide(Facing::WEST); + $block3 = $this->getSide(Facing::EAST); if(!$block0->isSolid() and !$block1->isSolid() and !$block2->isSolid() and !$block3->isSolid()){ $this->getLevel()->setBlock($this, $this, true); diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index d4c46d520b..83d2b61c12 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -28,6 +28,7 @@ use pocketmine\entity\Living; use pocketmine\item\FoodSource; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -61,7 +62,7 @@ class Cake extends Transparent implements FoodSource{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $down = $this->getSide(Vector3::SIDE_DOWN); + $down = $this->getSide(Facing::DOWN); if($down->getId() !== self::AIR){ $this->getLevel()->setBlock($blockReplace, $this, true, true); @@ -72,7 +73,7 @@ class Cake extends Transparent implements FoodSource{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){ //Replace with common break method + if($this->getSide(Facing::DOWN)->getId() === self::AIR){ //Replace with common break method $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true); } } diff --git a/src/pocketmine/block/Carpet.php b/src/pocketmine/block/Carpet.php index 6c0189a508..a3cbc8c550 100644 --- a/src/pocketmine/block/Carpet.php +++ b/src/pocketmine/block/Carpet.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\block\utils\ColorBlockMetaHelper; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -54,7 +55,7 @@ class Carpet extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $down = $this->getSide(Vector3::SIDE_DOWN); + $down = $this->getSide(Facing::DOWN); if($down->getId() !== self::AIR){ $this->getLevel()->setBlock($blockReplace, $this, true, true); @@ -65,7 +66,7 @@ class Carpet extends Flowable{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){ + if($this->getSide(Facing::DOWN)->getId() === self::AIR){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index a0b8d1a61f..2e1f1e91b9 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -25,6 +25,8 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Bearing; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Chest as TileChest; @@ -56,22 +58,15 @@ class Chest extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $faces = [ - 0 => 4, - 1 => 2, - 2 => 5, - 3 => 3 - ]; - $chest = null; - $this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0]; + if($player !== null){ + $this->meta = Bearing::toFacing($player->getDirection()); + } - for($side = 2; $side <= 5; ++$side){ - if(($this->meta === 4 or $this->meta === 5) and ($side === 4 or $side === 5)){ - continue; - }elseif(($this->meta === 3 or $this->meta === 2) and ($side === 2 or $side === 3)){ - continue; - } + foreach([ + Bearing::toFacing(Bearing::rotate($player->getDirection(), -1)), + Bearing::toFacing(Bearing::rotate($player->getDirection(), 1)) + ] as $side){ $c = $this->getSide($side); if($c->getId() === $this->id and $c->getDamage() === $this->meta){ $tile = $this->getLevel()->getTile($c); @@ -105,8 +100,8 @@ class Chest extends Transparent{ } if( - !$this->getSide(Vector3::SIDE_UP)->isTransparent() or - ($chest->isPaired() and !$chest->getPair()->getBlock()->getSide(Vector3::SIDE_UP)->isTransparent()) or + !$this->getSide(Facing::UP)->isTransparent() or + ($chest->isPaired() and !$chest->getPair()->getBlock()->getSide(Facing::UP)->isTransparent()) or !$chest->canOpenWith($item->getCustomName()) ){ return true; diff --git a/src/pocketmine/block/CobblestoneWall.php b/src/pocketmine/block/CobblestoneWall.php index 34bd9a8b1a..86c2d977d4 100644 --- a/src/pocketmine/block/CobblestoneWall.php +++ b/src/pocketmine/block/CobblestoneWall.php @@ -25,7 +25,7 @@ namespace pocketmine\block; use pocketmine\item\TieredTool; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Vector3; +use pocketmine\math\Facing; class CobblestoneWall extends Transparent{ public const NONE_MOSSY_WALL = 0; @@ -60,14 +60,14 @@ class CobblestoneWall extends Transparent{ protected function recalculateBoundingBox() : ?AxisAlignedBB{ //walls don't have any special collision boxes like fences do - $north = $this->canConnect($this->getSide(Vector3::SIDE_NORTH)); - $south = $this->canConnect($this->getSide(Vector3::SIDE_SOUTH)); - $west = $this->canConnect($this->getSide(Vector3::SIDE_WEST)); - $east = $this->canConnect($this->getSide(Vector3::SIDE_EAST)); + $north = $this->canConnect($this->getSide(Facing::NORTH)); + $south = $this->canConnect($this->getSide(Facing::SOUTH)); + $west = $this->canConnect($this->getSide(Facing::WEST)); + $east = $this->canConnect($this->getSide(Facing::EAST)); $inset = 0.25; if( - $this->getSide(Vector3::SIDE_UP)->getId() === Block::AIR and //if there is a block on top, it stays as a post + $this->getSide(Facing::UP)->getId() === Block::AIR and //if there is a block on top, it stays as a post ( ($north and $south and !$west and !$east) or (!$north and !$south and $west and $east) diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index 43be767320..476c8d5ce2 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Item; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\Server; @@ -32,7 +33,7 @@ use pocketmine\Server; abstract class Crops extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if($blockReplace->getSide(Vector3::SIDE_DOWN)->getId() === Block::FARMLAND){ + if($blockReplace->getSide(Facing::DOWN)->getId() === Block::FARMLAND){ $this->getLevel()->setBlock($blockReplace, $this, true, true); return true; @@ -65,7 +66,7 @@ abstract class Crops extends Flowable{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Vector3::SIDE_DOWN)->getId() !== Block::FARMLAND){ + if($this->getSide(Facing::DOWN)->getId() !== Block::FARMLAND){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/Dandelion.php b/src/pocketmine/block/Dandelion.php index bf9f16b8ec..443ba08110 100644 --- a/src/pocketmine/block/Dandelion.php +++ b/src/pocketmine/block/Dandelion.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -41,7 +42,7 @@ class Dandelion extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $down = $this->getSide(Vector3::SIDE_DOWN); + $down = $this->getSide(Facing::DOWN); if($down->getId() === Block::GRASS or $down->getId() === Block::DIRT or $down->getId() === Block::FARMLAND){ $this->getLevel()->setBlock($blockReplace, $this, true, true); @@ -52,7 +53,7 @@ class Dandelion extends Flowable{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){ + if($this->getSide(Facing::DOWN)->isTransparent()){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/DeadBush.php b/src/pocketmine/block/DeadBush.php index 2ea91e6e2d..8f3c5c3547 100644 --- a/src/pocketmine/block/DeadBush.php +++ b/src/pocketmine/block/DeadBush.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -41,7 +42,7 @@ class DeadBush extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if(!$this->getSide(Vector3::SIDE_DOWN)->isTransparent()){ + if(!$this->getSide(Facing::DOWN)->isTransparent()){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -49,7 +50,7 @@ class DeadBush extends Flowable{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){ + if($this->getSide(Facing::DOWN)->isTransparent()){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 3b4f54af74..c95947725a 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -26,6 +26,8 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\level\sound\DoorSound; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Bearing; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -41,11 +43,11 @@ abstract class Door extends Transparent{ $isUp = ($damage & 0x08) > 0; if($isUp){ - $down = $this->getSide(Vector3::SIDE_DOWN)->getDamage(); + $down = $this->getSide(Facing::DOWN)->getDamage(); $up = $damage; }else{ $down = $damage; - $up = $this->getSide(Vector3::SIDE_UP)->getDamage(); + $up = $this->getSide(Facing::UP)->getDamage(); } $isRight = ($up & 0x01) > 0; @@ -109,36 +111,33 @@ abstract class Door extends Transparent{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){ //Replace with common break method + if($this->getSide(Facing::DOWN)->getId() === self::AIR){ //Replace with common break method $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), false); - if($this->getSide(Vector3::SIDE_UP) instanceof Door){ - $this->getLevel()->setBlock($this->getSide(Vector3::SIDE_UP), BlockFactory::get(Block::AIR), false); + if($this->getSide(Facing::UP) instanceof Door){ + $this->getLevel()->setBlock($this->getSide(Facing::UP), BlockFactory::get(Block::AIR), false); } } } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if($face === Vector3::SIDE_UP){ - $blockUp = $this->getSide(Vector3::SIDE_UP); - $blockDown = $this->getSide(Vector3::SIDE_DOWN); + if($face === Facing::UP){ + $blockUp = $this->getSide(Facing::UP); + $blockDown = $this->getSide(Facing::DOWN); if(!$blockUp->canBeReplaced() or $blockDown->isTransparent()){ return false; } - $direction = $player instanceof Player ? $player->getDirection() : 0; - $faces = [ - 0 => 3, - 1 => 4, - 2 => 2, - 3 => 5 - ]; - $next = $this->getSide($faces[($direction + 2) % 4]); - $next2 = $this->getSide($faces[$direction]); + + $ccw = Bearing::toFacing($player instanceof Player ? Bearing::rotate($player->getDirection(), -1) : Facing::EAST); + + $next = $this->getSide(Facing::opposite($ccw)); + $next2 = $this->getSide($ccw); + $metaUp = 0x08; if($next->getId() === $this->getId() or (!$next2->isTransparent() and $next->isTransparent())){ //Door hinge $metaUp |= 0x01; } - $this->setDamage($player->getDirection() & 0x03); + $this->setDamage(Bearing::rotate($player->getDirection(), -1)); $this->getLevel()->setBlock($blockReplace, $this, true, true); //Bottom $this->getLevel()->setBlock($blockUp, BlockFactory::get($this->getId(), $metaUp), true); //Top return true; @@ -149,7 +148,7 @@ abstract class Door extends Transparent{ public function onActivate(Item $item, Player $player = null) : bool{ if(($this->getDamage() & 0x08) === 0x08){ //Top - $down = $this->getSide(Vector3::SIDE_DOWN); + $down = $this->getSide(Facing::DOWN); if($down->getId() === $this->getId()){ $meta = $down->getDamage() ^ 0x04; $this->level->setBlock($down, BlockFactory::get($this->getId(), $meta), true); @@ -185,12 +184,12 @@ abstract class Door extends Transparent{ public function getAffectedBlocks() : array{ if(($this->getDamage() & 0x08) === 0x08){ - $down = $this->getSide(Vector3::SIDE_DOWN); + $down = $this->getSide(Facing::DOWN); if($down->getId() === $this->getId()){ return [$this, $down]; } }else{ - $up = $this->getSide(Vector3::SIDE_UP); + $up = $this->getSide(Facing::UP); if($up->getId() === $this->getId()){ return [$this, $up]; } diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index b1d38fff1f..f1d477675c 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -54,10 +55,10 @@ class DoublePlant extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $id = $blockReplace->getSide(Vector3::SIDE_DOWN)->getId(); - if(($id === Block::GRASS or $id === Block::DIRT) and $blockReplace->getSide(Vector3::SIDE_UP)->canBeReplaced()){ + $id = $blockReplace->getSide(Facing::DOWN)->getId(); + if(($id === Block::GRASS or $id === Block::DIRT) and $blockReplace->getSide(Facing::UP)->canBeReplaced()){ $this->getLevel()->setBlock($blockReplace, $this, false, false); - $this->getLevel()->setBlock($blockReplace->getSide(Vector3::SIDE_UP), BlockFactory::get($this->id, $this->meta | self::BITFLAG_TOP), false, false); + $this->getLevel()->setBlock($blockReplace->getSide(Facing::UP), BlockFactory::get($this->id, $this->meta | self::BITFLAG_TOP), false, false); return true; } @@ -71,9 +72,9 @@ class DoublePlant extends Flowable{ */ public function isValidHalfPlant() : bool{ if($this->meta & self::BITFLAG_TOP){ - $other = $this->getSide(Vector3::SIDE_DOWN); + $other = $this->getSide(Facing::DOWN); }else{ - $other = $this->getSide(Vector3::SIDE_UP); + $other = $this->getSide(Facing::UP); } return ( @@ -84,7 +85,7 @@ class DoublePlant extends Flowable{ } public function onNearbyBlockChange() : void{ - if(!$this->isValidHalfPlant() or (($this->meta & self::BITFLAG_TOP) === 0 and $this->getSide(Vector3::SIDE_DOWN)->isTransparent())){ + if(!$this->isValidHalfPlant() or (($this->meta & self::BITFLAG_TOP) === 0 and $this->getSide(Facing::DOWN)->isTransparent())){ $this->getLevel()->useBreakOn($this); } } @@ -119,7 +120,7 @@ class DoublePlant extends Flowable{ public function getAffectedBlocks() : array{ if($this->isValidHalfPlant()){ - return [$this, $this->getSide(($this->meta & self::BITFLAG_TOP) !== 0 ? Vector3::SIDE_DOWN : Vector3::SIDE_UP)]; + return [$this, $this->getSide(($this->meta & self::BITFLAG_TOP) !== 0 ? Facing::DOWN : Facing::UP)]; } return parent::getAffectedBlocks(); diff --git a/src/pocketmine/block/EndRod.php b/src/pocketmine/block/EndRod.php index da64cc5680..e652707403 100644 --- a/src/pocketmine/block/EndRod.php +++ b/src/pocketmine/block/EndRod.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -41,7 +42,7 @@ class EndRod extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if($face === Vector3::SIDE_UP or $face === Vector3::SIDE_DOWN){ + if(Facing::axis($face) === Facing::AXIS_Y){ $this->meta = $face; }else{ $this->meta = $face ^ 0x01; @@ -62,11 +63,11 @@ class EndRod extends Flowable{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - $m = $this->meta & ~0x01; + $m = $this->meta >> 1; //everything except up/down are inverted, but we can still use this for axis $width = 0.375; switch($m){ - case 0x00: //up/down + case Facing::AXIS_Y: return new AxisAlignedBB( $width, 0, @@ -75,7 +76,7 @@ class EndRod extends Flowable{ 1, 1 - $width ); - case 0x02: //north/south + case Facing::AXIS_Z: return new AxisAlignedBB( 0, $width, @@ -84,7 +85,7 @@ class EndRod extends Flowable{ 1 - $width, 1 - $width ); - case 0x04: //east/west + case Facing::AXIS_X: return new AxisAlignedBB( $width, $width, diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index ea5afb2577..015f909480 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -26,6 +26,8 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; +use pocketmine\math\Bearing; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\EnderChest as TileEnderChest; @@ -60,14 +62,9 @@ class EnderChest extends Chest{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $faces = [ - 0 => 4, - 1 => 2, - 2 => 5, - 3 => 3 - ]; - - $this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0]; + if($player !== null){ + $this->meta = Bearing::toFacing($player->getDirection()); + } $this->getLevel()->setBlock($blockReplace, $this, true, true); Tile::createTile(Tile::ENDER_CHEST, $this->getLevel(), TileEnderChest::createNBT($this, $face, $item, $player)); @@ -86,7 +83,7 @@ class EnderChest extends Chest{ $enderChest = Tile::createTile(Tile::ENDER_CHEST, $this->getLevel(), TileEnderChest::createNBT($this)); } - if(!$this->getSide(Vector3::SIDE_UP)->isTransparent()){ + if(!$this->getSide(Facing::UP)->isTransparent()){ return true; } diff --git a/src/pocketmine/block/Fallable.php b/src/pocketmine/block/Fallable.php index d3fe4dec51..990a13ebe9 100644 --- a/src/pocketmine/block/Fallable.php +++ b/src/pocketmine/block/Fallable.php @@ -24,12 +24,12 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\entity\Entity; -use pocketmine\math\Vector3; +use pocketmine\math\Facing; abstract class Fallable extends Solid{ public function onNearbyBlockChange() : void{ - $down = $this->getSide(Vector3::SIDE_DOWN); + $down = $this->getSide(Facing::DOWN); if($down->getId() === self::AIR or $down instanceof Liquid or $down instanceof Fire){ $this->level->setBlock($this, BlockFactory::get(Block::AIR), true); diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index 9c473a512b..b8a32a7539 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Vector3; +use pocketmine\math\Facing; class Farmland extends Transparent{ @@ -53,7 +53,7 @@ class Farmland extends Transparent{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Vector3::SIDE_UP)->isSolid()){ + if($this->getSide(Facing::UP)->isSolid()){ $this->level->setBlock($this, BlockFactory::get(Block::DIRT), true); } } diff --git a/src/pocketmine/block/Fence.php b/src/pocketmine/block/Fence.php index aa9cdd00f4..f7981e207b 100644 --- a/src/pocketmine/block/Fence.php +++ b/src/pocketmine/block/Fence.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Vector3; +use pocketmine\math\Facing; abstract class Fence extends Transparent{ @@ -40,12 +40,12 @@ abstract class Fence extends Transparent{ $width = 0.5 - $this->getThickness() / 2; return new AxisAlignedBB( - ($this->canConnect($this->getSide(Vector3::SIDE_WEST)) ? 0 : $width), + ($this->canConnect($this->getSide(Facing::WEST)) ? 0 : $width), 0, - ($this->canConnect($this->getSide(Vector3::SIDE_NORTH)) ? 0 : $width), - 1 - ($this->canConnect($this->getSide(Vector3::SIDE_EAST)) ? 0 : $width), + ($this->canConnect($this->getSide(Facing::NORTH)) ? 0 : $width), + 1 - ($this->canConnect($this->getSide(Facing::EAST)) ? 0 : $width), 1.5, - 1 - ($this->canConnect($this->getSide(Vector3::SIDE_SOUTH)) ? 0 : $width) + 1 - ($this->canConnect($this->getSide(Facing::SOUTH)) ? 0 : $width) ); } @@ -55,8 +55,8 @@ abstract class Fence extends Transparent{ /** @var AxisAlignedBB[] $bbs */ $bbs = []; - $connectWest = $this->canConnect($this->getSide(Vector3::SIDE_WEST)); - $connectEast = $this->canConnect($this->getSide(Vector3::SIDE_EAST)); + $connectWest = $this->canConnect($this->getSide(Facing::WEST)); + $connectEast = $this->canConnect($this->getSide(Facing::EAST)); if($connectWest or $connectEast){ //X axis (west/east) @@ -70,8 +70,8 @@ abstract class Fence extends Transparent{ ); } - $connectNorth = $this->canConnect($this->getSide(Vector3::SIDE_NORTH)); - $connectSouth = $this->canConnect($this->getSide(Vector3::SIDE_SOUTH)); + $connectNorth = $this->canConnect($this->getSide(Facing::NORTH)); + $connectSouth = $this->canConnect($this->getSide(Facing::SOUTH)); if($connectNorth or $connectSouth){ //Z axis (north/south) diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index 1d7a93b9cd..1aacbbf846 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\level\sound\DoorSound; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Bearing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -68,7 +69,9 @@ class FenceGate extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $this->meta = ($player instanceof Player ? ($player->getDirection() - 1) & 0x03 : 0); + if($player !== null){ + $this->meta = Bearing::rotate($player->getDirection(), 2); + } $this->getLevel()->setBlock($blockReplace, $this, true, true); return true; @@ -82,7 +85,7 @@ class FenceGate extends Transparent{ $this->meta = (($this->meta ^ 0x04) & ~0x02); if($player !== null){ - $this->meta |= (($player->getDirection() - 1) & 0x02); + $this->meta |= (Bearing::rotate($player->getDirection(), 2) & 0x02); //open towards the player, retaining axis } $this->getLevel()->setBlock($this, $this, true); diff --git a/src/pocketmine/block/Fire.php b/src/pocketmine/block/Fire.php index ace4a385d0..33e971fd39 100644 --- a/src/pocketmine/block/Fire.php +++ b/src/pocketmine/block/Fire.php @@ -30,7 +30,7 @@ use pocketmine\event\entity\EntityCombustByBlockEvent; use pocketmine\event\entity\EntityDamageByBlockEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\item\Item; -use pocketmine\math\Vector3; +use pocketmine\math\Facing; use pocketmine\Server; class Fire extends Flowable{ @@ -80,7 +80,7 @@ class Fire extends Flowable{ } public function onNearbyBlockChange() : void{ - if(!$this->getSide(Vector3::SIDE_DOWN)->isSolid() and !$this->hasAdjacentFlammableBlocks()){ + if(!$this->getSide(Facing::DOWN)->isSolid() and !$this->hasAdjacentFlammableBlocks()){ $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true); }else{ $this->level->scheduleDelayedBlockUpdate($this, mt_rand(30, 40)); @@ -92,7 +92,7 @@ class Fire extends Flowable{ } public function onRandomTick() : void{ - $down = $this->getSide(Vector3::SIDE_DOWN); + $down = $this->getSide(Facing::DOWN); $result = null; if($this->meta < 15 and mt_rand(0, 2) === 0){ @@ -130,8 +130,8 @@ class Fire extends Flowable{ } //vanilla uses a 250 upper bound here, but I don't think they intended to increase the chance of incineration - $this->burnBlock($this->getSide(Vector3::SIDE_UP), 350); - $this->burnBlock($this->getSide(Vector3::SIDE_DOWN), 350); + $this->burnBlock($this->getSide(Facing::UP), 350); + $this->burnBlock($this->getSide(Facing::DOWN), 350); //TODO: fire spread } diff --git a/src/pocketmine/block/Flower.php b/src/pocketmine/block/Flower.php index 2946b3cbed..ac7a063a8d 100644 --- a/src/pocketmine/block/Flower.php +++ b/src/pocketmine/block/Flower.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -60,7 +61,7 @@ class Flower extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $down = $this->getSide(Vector3::SIDE_DOWN); + $down = $this->getSide(Facing::DOWN); if($down->getId() === Block::GRASS or $down->getId() === Block::DIRT or $down->getId() === Block::FARMLAND){ $this->getLevel()->setBlock($blockReplace, $this, true); @@ -71,7 +72,7 @@ class Flower extends Flowable{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){ + if($this->getSide(Facing::DOWN)->isTransparent()){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 3f92b7cc01..8dd7f9db2f 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\FlowerPot as TileFlowerPot; @@ -52,7 +53,7 @@ class FlowerPot extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){ + if($this->getSide(Facing::DOWN)->isTransparent()){ return false; } @@ -62,7 +63,7 @@ class FlowerPot extends Flowable{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){ + if($this->getSide(Facing::DOWN)->isTransparent()){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/GlazedTerracotta.php b/src/pocketmine/block/GlazedTerracotta.php index 336b513257..d4c3e30639 100644 --- a/src/pocketmine/block/GlazedTerracotta.php +++ b/src/pocketmine/block/GlazedTerracotta.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\item\TieredTool; +use pocketmine\math\Bearing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -45,15 +46,8 @@ class GlazedTerracotta extends Solid{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ - $faces = [ - 0 => 4, - 1 => 3, - 2 => 5, - 3 => 2 - ]; - $this->meta = $faces[(~($player->getDirection() - 1)) & 0x03]; + $this->meta = Bearing::toFacing($player->getDirection()); } - return $this->getLevel()->setBlock($blockReplace, $this, true, true); } diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index a2887e0fdf..43045355e0 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -29,7 +29,7 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\Shovel; use pocketmine\level\generator\object\TallGrass as TallGrassObject; -use pocketmine\math\Vector3; +use pocketmine\math\Facing; use pocketmine\Player; use pocketmine\utils\Random; @@ -105,7 +105,7 @@ class Grass extends Solid{ $this->getLevel()->setBlock($this, BlockFactory::get(Block::FARMLAND)); return true; - }elseif($item instanceof Shovel and $this->getSide(Vector3::SIDE_UP)->getId() === Block::AIR){ + }elseif($item instanceof Shovel and $this->getSide(Facing::UP)->getId() === Block::AIR){ $item->applyDamage(1); $this->getLevel()->setBlock($this, BlockFactory::get(Block::GRASS_PATH)); diff --git a/src/pocketmine/block/GrassPath.php b/src/pocketmine/block/GrassPath.php index e58c402241..dbe08ca782 100644 --- a/src/pocketmine/block/GrassPath.php +++ b/src/pocketmine/block/GrassPath.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Vector3; +use pocketmine\math\Facing; class GrassPath extends Transparent{ @@ -53,7 +53,7 @@ class GrassPath extends Transparent{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Vector3::SIDE_UP)->isSolid()){ + if($this->getSide(Facing::UP)->isSolid()){ $this->level->setBlock($this, BlockFactory::get(Block::DIRT), true); } } diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 9b44104e13..e01fcc9385 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\ItemFrame as TileItemFrame; @@ -59,10 +60,10 @@ class ItemFrame extends Flowable{ public function onNearbyBlockChange() : void{ $sides = [ - 0 => Vector3::SIDE_WEST, - 1 => Vector3::SIDE_EAST, - 2 => Vector3::SIDE_NORTH, - 3 => Vector3::SIDE_SOUTH + 0 => Facing::WEST, + 1 => Facing::EAST, + 2 => Facing::NORTH, + 3 => Facing::SOUTH ]; if(!$this->getSide($sides[$this->meta])->isSolid()){ $this->level->useBreakOn($this); @@ -70,15 +71,15 @@ class ItemFrame extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if($face === Vector3::SIDE_DOWN or $face === Vector3::SIDE_UP or !$blockClicked->isSolid()){ + if($face === Facing::DOWN or $face === Facing::UP or !$blockClicked->isSolid()){ return false; } $faces = [ - Vector3::SIDE_NORTH => 3, - Vector3::SIDE_SOUTH => 2, - Vector3::SIDE_WEST => 1, - Vector3::SIDE_EAST => 0 + Facing::NORTH => 3, + Facing::SOUTH => 2, + Facing::WEST => 1, + Facing::EAST => 0 ]; $this->meta = $faces[$face]; diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 05ef8a8829..212354682e 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\event\block\LeavesDecayEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -76,7 +77,7 @@ class Leaves extends Transparent{ return true; }elseif($pos->getId() === $this->id and $distance < 3){ $visited[$index] = true; - $down = $pos->getSide(Vector3::SIDE_DOWN)->getId(); + $down = $pos->getSide(Facing::DOWN)->getId(); if($down === $this->woodType){ return true; } @@ -89,38 +90,38 @@ class Leaves extends Transparent{ }else{ //No more loops switch($fromSide){ case 2: - if($this->findLog($pos->getSide(Vector3::SIDE_NORTH), $visited, $distance + 1, $fromSide)){ + if($this->findLog($pos->getSide(Facing::NORTH), $visited, $distance + 1, $fromSide)){ return true; - }elseif($this->findLog($pos->getSide(Vector3::SIDE_WEST), $visited, $distance + 1, $fromSide)){ + }elseif($this->findLog($pos->getSide(Facing::WEST), $visited, $distance + 1, $fromSide)){ return true; - }elseif($this->findLog($pos->getSide(Vector3::SIDE_EAST), $visited, $distance + 1, $fromSide)){ + }elseif($this->findLog($pos->getSide(Facing::EAST), $visited, $distance + 1, $fromSide)){ return true; } break; case 3: - if($this->findLog($pos->getSide(Vector3::SIDE_SOUTH), $visited, $distance + 1, $fromSide)){ + if($this->findLog($pos->getSide(Facing::SOUTH), $visited, $distance + 1, $fromSide)){ return true; - }elseif($this->findLog($pos->getSide(Vector3::SIDE_WEST), $visited, $distance + 1, $fromSide)){ + }elseif($this->findLog($pos->getSide(Facing::WEST), $visited, $distance + 1, $fromSide)){ return true; - }elseif($this->findLog($pos->getSide(Vector3::SIDE_EAST), $visited, $distance + 1, $fromSide)){ + }elseif($this->findLog($pos->getSide(Facing::EAST), $visited, $distance + 1, $fromSide)){ return true; } break; case 4: - if($this->findLog($pos->getSide(Vector3::SIDE_NORTH), $visited, $distance + 1, $fromSide)){ + if($this->findLog($pos->getSide(Facing::NORTH), $visited, $distance + 1, $fromSide)){ return true; - }elseif($this->findLog($pos->getSide(Vector3::SIDE_SOUTH), $visited, $distance + 1, $fromSide)){ + }elseif($this->findLog($pos->getSide(Facing::SOUTH), $visited, $distance + 1, $fromSide)){ return true; - }elseif($this->findLog($pos->getSide(Vector3::SIDE_WEST), $visited, $distance + 1, $fromSide)){ + }elseif($this->findLog($pos->getSide(Facing::WEST), $visited, $distance + 1, $fromSide)){ return true; } break; case 5: - if($this->findLog($pos->getSide(Vector3::SIDE_NORTH), $visited, $distance + 1, $fromSide)){ + if($this->findLog($pos->getSide(Facing::NORTH), $visited, $distance + 1, $fromSide)){ return true; - }elseif($this->findLog($pos->getSide(Vector3::SIDE_SOUTH), $visited, $distance + 1, $fromSide)){ + }elseif($this->findLog($pos->getSide(Facing::SOUTH), $visited, $distance + 1, $fromSide)){ return true; - }elseif($this->findLog($pos->getSide(Vector3::SIDE_EAST), $visited, $distance + 1, $fromSide)){ + }elseif($this->findLog($pos->getSide(Facing::EAST), $visited, $distance + 1, $fromSide)){ return true; } break; diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index 10b6f3042f..7b622af4a7 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -24,6 +24,8 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; +use pocketmine\math\Bearing; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -52,19 +54,20 @@ class Lever extends Flowable{ return false; } - if($face === Vector3::SIDE_DOWN){ + if($face === Facing::DOWN){ $this->meta = 0; }else{ $this->meta = 6 - $face; } if($player !== null){ - if(($player->getDirection() & 0x01) === 0){ - if($face === Vector3::SIDE_UP){ + $bearing = $player->getDirection(); + if($bearing === Bearing::EAST or $bearing === Bearing::WEST){ + if($face === Facing::UP){ $this->meta = 6; } }else{ - if($face === Vector3::SIDE_DOWN){ + if($face === Facing::DOWN){ $this->meta = 7; } } @@ -74,15 +77,15 @@ class Lever extends Flowable{ } public function onNearbyBlockChange() : void{ - $faces = [ - 0 => Vector3::SIDE_UP, - 1 => Vector3::SIDE_WEST, - 2 => Vector3::SIDE_EAST, - 3 => Vector3::SIDE_NORTH, - 4 => Vector3::SIDE_SOUTH, - 5 => Vector3::SIDE_DOWN, - 6 => Vector3::SIDE_DOWN, - 7 => Vector3::SIDE_UP + static $faces = [ + 0 => Facing::UP, + 1 => Facing::WEST, + 2 => Facing::EAST, + 3 => Facing::NORTH, + 4 => Facing::SOUTH, + 5 => Facing::DOWN, + 6 => Facing::DOWN, + 7 => Facing::UP ]; if(!$this->getSide($faces[$this->meta & 0x07])->isSolid()){ $this->level->useBreakOn($this); diff --git a/src/pocketmine/block/MelonStem.php b/src/pocketmine/block/MelonStem.php index eb4c6d0ee7..48e4f19ecb 100644 --- a/src/pocketmine/block/MelonStem.php +++ b/src/pocketmine/block/MelonStem.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\math\Vector3; +use pocketmine\math\Facing; use pocketmine\Server; class MelonStem extends Crops{ @@ -58,7 +58,7 @@ class MelonStem extends Crops{ } } $side = $this->getSide(mt_rand(2, 5)); - $d = $side->getSide(Vector3::SIDE_DOWN); + $d = $side->getSide(Facing::DOWN); if($side->getId() === self::AIR and ($d->getId() === self::FARMLAND or $d->getId() === self::GRASS or $d->getId() === self::DIRT)){ Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($side, BlockFactory::get(Block::MELON_BLOCK))); if(!$ev->isCancelled()){ diff --git a/src/pocketmine/block/Mycelium.php b/src/pocketmine/block/Mycelium.php index 36439e0e84..331d4ddc7f 100644 --- a/src/pocketmine/block/Mycelium.php +++ b/src/pocketmine/block/Mycelium.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\event\block\BlockSpreadEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\math\Vector3; +use pocketmine\math\Facing; use pocketmine\Server; class Mycelium extends Solid{ @@ -66,7 +66,7 @@ class Mycelium extends Solid{ $z = mt_rand($this->z - 1, $this->z + 1); $block = $this->getLevel()->getBlockAt($x, $y, $z); if($block->getId() === Block::DIRT){ - if($block->getSide(Vector3::SIDE_UP) instanceof Transparent){ + if($block->getSide(Facing::UP) instanceof Transparent){ Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, BlockFactory::get(Block::MYCELIUM))); if(!$ev->isCancelled()){ $this->getLevel()->setBlock($block, $ev->getNewState()); diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index 14e82f5480..9071ca29e3 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -27,6 +27,7 @@ namespace pocketmine\block; use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -44,7 +45,7 @@ class NetherWartPlant extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $down = $this->getSide(Vector3::SIDE_DOWN); + $down = $this->getSide(Facing::DOWN); if($down->getId() === Block::SOUL_SAND){ $this->getLevel()->setBlock($blockReplace, $this, false, true); @@ -55,7 +56,7 @@ class NetherWartPlant extends Flowable{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Vector3::SIDE_DOWN)->getId() !== Block::SOUL_SAND){ + if($this->getSide(Facing::DOWN)->getId() !== Block::SOUL_SAND){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/Pumpkin.php b/src/pocketmine/block/Pumpkin.php index 811dd06e5a..3c63bae356 100644 --- a/src/pocketmine/block/Pumpkin.php +++ b/src/pocketmine/block/Pumpkin.php @@ -23,10 +23,6 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\Item; -use pocketmine\math\Vector3; -use pocketmine\Player; - class Pumpkin extends Solid{ protected $id = self::PUMPKIN; @@ -47,15 +43,6 @@ class Pumpkin extends Solid{ return "Pumpkin"; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if($player instanceof Player){ - $this->meta = ((int) $player->getDirection() + 1) % 4; - } - $this->getLevel()->setBlock($blockReplace, $this, true, true); - - return true; - } - public function getVariantBitmask() : int{ return 0; } diff --git a/src/pocketmine/block/PumpkinStem.php b/src/pocketmine/block/PumpkinStem.php index 33d83470f6..7cc4da6422 100644 --- a/src/pocketmine/block/PumpkinStem.php +++ b/src/pocketmine/block/PumpkinStem.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\math\Vector3; +use pocketmine\math\Facing; use pocketmine\Server; class PumpkinStem extends Crops{ @@ -58,7 +58,7 @@ class PumpkinStem extends Crops{ } } $side = $this->getSide(mt_rand(2, 5)); - $d = $side->getSide(Vector3::SIDE_DOWN); + $d = $side->getSide(Facing::DOWN); if($side->getId() === self::AIR and ($d->getId() === self::FARMLAND or $d->getId() === self::GRASS or $d->getId() === self::DIRT)){ Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($side, BlockFactory::get(Block::PUMPKIN))); if(!$ev->isCancelled()){ diff --git a/src/pocketmine/block/Rail.php b/src/pocketmine/block/Rail.php index 8ac173cd31..7e5e36f971 100644 --- a/src/pocketmine/block/Rail.php +++ b/src/pocketmine/block/Rail.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -55,7 +56,7 @@ class Rail extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if(!$blockReplace->getSide(Vector3::SIDE_DOWN)->isTransparent()){ + if(!$blockReplace->getSide(Facing::DOWN)->isTransparent()){ return $this->getLevel()->setBlock($blockReplace, $this, true, true); } @@ -63,7 +64,7 @@ class Rail extends Flowable{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){ + if($this->getSide(Facing::DOWN)->isTransparent()){ $this->getLevel()->useBreakOn($this); }else{ //TODO: Update rail connectivity diff --git a/src/pocketmine/block/RedMushroom.php b/src/pocketmine/block/RedMushroom.php index 5c4d5296bb..d5f25a60b0 100644 --- a/src/pocketmine/block/RedMushroom.php +++ b/src/pocketmine/block/RedMushroom.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -44,13 +45,13 @@ class RedMushroom extends Flowable{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){ + if($this->getSide(Facing::DOWN)->isTransparent()){ $this->getLevel()->useBreakOn($this); } } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $down = $this->getSide(Vector3::SIDE_DOWN); + $down = $this->getSide(Facing::DOWN); if(!$down->isTransparent()){ $this->getLevel()->setBlock($blockReplace, $this, true, true); diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index a6c65bba92..5d6d51c0fa 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\level\generator\object\Tree; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\utils\Random; @@ -56,7 +57,7 @@ class Sapling extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $down = $this->getSide(Vector3::SIDE_DOWN); + $down = $this->getSide(Facing::DOWN); if($down->getId() === self::GRASS or $down->getId() === self::DIRT or $down->getId() === self::FARMLAND){ $this->getLevel()->setBlock($blockReplace, $this, true, true); @@ -80,7 +81,7 @@ class Sapling extends Flowable{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){ + if($this->getSide(Facing::DOWN)->isTransparent()){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/SignPost.php b/src/pocketmine/block/SignPost.php index fdd4a0e1a0..c1b820f667 100644 --- a/src/pocketmine/block/SignPost.php +++ b/src/pocketmine/block/SignPost.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Sign as TileSign; @@ -58,9 +59,9 @@ class SignPost extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if($face !== Vector3::SIDE_DOWN){ + if($face !== Facing::DOWN){ - if($face === Vector3::SIDE_UP){ + if($face === Facing::UP){ $this->meta = $player !== null ? (floor((($player->yaw + 180) * 16 / 360) + 0.5) & 0x0f) : 0; $this->getLevel()->setBlock($blockReplace, $this, true); }else{ @@ -77,7 +78,7 @@ class SignPost extends Transparent{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){ + if($this->getSide(Facing::DOWN)->getId() === self::AIR){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index dc74b96eb6..34c6077d75 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Skull as TileSkull; @@ -54,7 +55,7 @@ class Skull extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if($face === Vector3::SIDE_DOWN){ + if($face === Facing::DOWN){ return false; } diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index 319d039985..66bb2940fb 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -43,9 +44,9 @@ abstract class Slab extends Transparent{ if($blockReplace->getId() === $this->getId() and $blockReplace->getVariant() === $this->getVariant()){ if(($blockReplace->getDamage() & 0x08) !== 0){ //Trying to combine with top slab - return $clickVector->y <= 0.5 or (!$isClickedBlock and $face === Vector3::SIDE_UP); + return $clickVector->y <= 0.5 or (!$isClickedBlock and $face === Facing::UP); }else{ - return $clickVector->y >= 0.5 or (!$isClickedBlock and $face === Vector3::SIDE_DOWN); + return $clickVector->y >= 0.5 or (!$isClickedBlock and $face === Facing::DOWN); } } @@ -54,7 +55,7 @@ abstract class Slab extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $this->meta &= 0x07; - if($face === Vector3::SIDE_DOWN){ + if($face === Facing::DOWN){ if($blockClicked->getId() === $this->id and ($blockClicked->getDamage() & 0x08) === 0x08 and $blockClicked->getVariant() === $this->getVariant()){ $this->getLevel()->setBlock($blockClicked, BlockFactory::get($this->getDoubleSlabId(), $this->getVariant()), true); @@ -66,7 +67,7 @@ abstract class Slab extends Transparent{ }else{ $this->meta |= 0x08; } - }elseif($face === Vector3::SIDE_UP){ + }elseif($face === Facing::UP){ if($blockClicked->getId() === $this->id and ($blockClicked->getDamage() & 0x08) === 0 and $blockClicked->getVariant() === $this->getVariant()){ $this->getLevel()->setBlock($blockClicked, BlockFactory::get($this->getDoubleSlabId(), $this->getVariant()), true); diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index ab8168e823..b7c730b9df 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -58,7 +59,7 @@ class SnowLayer extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if($blockReplace->getSide(Vector3::SIDE_DOWN)->isSolid()){ + if($blockReplace->getSide(Facing::DOWN)->isSolid()){ //TODO: fix placement $this->getLevel()->setBlock($blockReplace, $this, true); @@ -69,7 +70,7 @@ class SnowLayer extends Flowable{ } public function onNearbyBlockChange() : void{ - if(!$this->getSide(Vector3::SIDE_DOWN)->isSolid()){ + if(!$this->getSide(Facing::DOWN)->isSolid()){ $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), false, false); } } diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index 27e66a24ec..a7a7a425a4 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -25,6 +25,8 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Bearing; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -69,14 +71,16 @@ abstract class Stair extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $faces = [ - 0 => 0, - 1 => 2, - 2 => 1, - 3 => 3 + static $faces = [ + Bearing::SOUTH => 3, //north + Bearing::WEST => 0, //east + Bearing::NORTH => 2, //south + Bearing::EAST => 1 //west ]; - $this->meta = $faces[$player->getDirection()] & 0x03; - if(($clickVector->y > 0.5 and $face !== Vector3::SIDE_UP) or $face === Vector3::SIDE_DOWN){ + if($player !== null){ + $this->meta = $faces[$player->getDirection()]; + } + if(($clickVector->y > 0.5 and $face !== Facing::UP) or $face === Facing::DOWN){ $this->meta |= 0x04; //Upside-down stairs } $this->getLevel()->setBlock($blockReplace, $this, true, true); diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index 88520deb23..352bbd1700 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Banner as TileBanner; @@ -58,8 +59,8 @@ class StandingBanner extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if($face !== Vector3::SIDE_DOWN){ - if($face === Vector3::SIDE_UP and $player !== null){ + if($face !== Facing::DOWN){ + if($face === Facing::UP and $player !== null){ $this->meta = floor((($player->yaw + 180) * 16 / 360) + 0.5) & 0x0f; $this->getLevel()->setBlock($blockReplace, $this, true); }else{ @@ -75,7 +76,7 @@ class StandingBanner extends Transparent{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){ + if($this->getSide(Facing::DOWN)->getId() === self::AIR){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index bddd9ec1c1..f2ddab7213 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Item; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\Server; @@ -45,7 +46,7 @@ class Sugarcane extends Flowable{ public function onActivate(Item $item, Player $player = null) : bool{ if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal - if($this->getSide(Vector3::SIDE_DOWN)->getId() !== self::SUGARCANE_BLOCK){ + if($this->getSide(Facing::DOWN)->getId() !== self::SUGARCANE_BLOCK){ for($y = 1; $y < 3; ++$y){ $b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z); if($b->getId() === self::AIR){ @@ -69,7 +70,7 @@ class Sugarcane extends Flowable{ } public function onNearbyBlockChange() : void{ - $down = $this->getSide(Vector3::SIDE_DOWN); + $down = $this->getSide(Facing::DOWN); if($down->isTransparent() and $down->getId() !== self::SUGARCANE_BLOCK){ $this->getLevel()->useBreakOn($this); } @@ -80,7 +81,7 @@ class Sugarcane extends Flowable{ } public function onRandomTick() : void{ - if($this->getSide(Vector3::SIDE_DOWN)->getId() !== self::SUGARCANE_BLOCK){ + if($this->getSide(Facing::DOWN)->getId() !== self::SUGARCANE_BLOCK){ if($this->meta === 0x0F){ for($y = 1; $y < 3; ++$y){ $b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z); @@ -99,16 +100,16 @@ class Sugarcane extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $down = $this->getSide(Vector3::SIDE_DOWN); + $down = $this->getSide(Facing::DOWN); if($down->getId() === self::SUGARCANE_BLOCK){ $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::SUGARCANE_BLOCK), true); return true; }elseif($down->getId() === self::GRASS or $down->getId() === self::DIRT or $down->getId() === self::SAND){ - $block0 = $down->getSide(Vector3::SIDE_NORTH); - $block1 = $down->getSide(Vector3::SIDE_SOUTH); - $block2 = $down->getSide(Vector3::SIDE_WEST); - $block3 = $down->getSide(Vector3::SIDE_EAST); + $block0 = $down->getSide(Facing::NORTH); + $block1 = $down->getSide(Facing::SOUTH); + $block2 = $down->getSide(Facing::WEST); + $block3 = $down->getSide(Facing::EAST); if(($block0 instanceof Water) or ($block1 instanceof Water) or ($block2 instanceof Water) or ($block3 instanceof Water)){ $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::SUGARCANE_BLOCK), true); diff --git a/src/pocketmine/block/TallGrass.php b/src/pocketmine/block/TallGrass.php index fe3c133c4f..310398f539 100644 --- a/src/pocketmine/block/TallGrass.php +++ b/src/pocketmine/block/TallGrass.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -50,7 +51,7 @@ class TallGrass extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $down = $this->getSide(Vector3::SIDE_DOWN); + $down = $this->getSide(Facing::DOWN); if($down->getId() === self::GRASS){ $this->getLevel()->setBlock($blockReplace, $this, true); @@ -61,7 +62,7 @@ class TallGrass extends Flowable{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){ //Replace with common break method + if($this->getSide(Facing::DOWN)->isTransparent()){ //Replace with common break method $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true, true); } } diff --git a/src/pocketmine/block/Thin.php b/src/pocketmine/block/Thin.php index fb6b5f91cc..3c33da2cfe 100644 --- a/src/pocketmine/block/Thin.php +++ b/src/pocketmine/block/Thin.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Vector3; +use pocketmine\math\Facing; abstract class Thin extends Transparent{ @@ -32,12 +32,12 @@ abstract class Thin extends Transparent{ $width = 0.5 - 0.125 / 2; return new AxisAlignedBB( - ($this->canConnect($this->getSide(Vector3::SIDE_WEST)) ? 0 : $width), + ($this->canConnect($this->getSide(Facing::WEST)) ? 0 : $width), 0, - ($this->canConnect($this->getSide(Vector3::SIDE_NORTH)) ? 0 : $width), - 1 - ($this->canConnect($this->getSide(Vector3::SIDE_EAST)) ? 0 : $width), + ($this->canConnect($this->getSide(Facing::NORTH)) ? 0 : $width), + 1 - ($this->canConnect($this->getSide(Facing::EAST)) ? 0 : $width), 1, - 1 - ($this->canConnect($this->getSide(Vector3::SIDE_SOUTH)) ? 0 : $width) + 1 - ($this->canConnect($this->getSide(Facing::SOUTH)) ? 0 : $width) ); } @@ -47,8 +47,8 @@ abstract class Thin extends Transparent{ /** @var AxisAlignedBB[] $bbs */ $bbs = []; - $connectWest = $this->canConnect($this->getSide(Vector3::SIDE_WEST)); - $connectEast = $this->canConnect($this->getSide(Vector3::SIDE_EAST)); + $connectWest = $this->canConnect($this->getSide(Facing::WEST)); + $connectEast = $this->canConnect($this->getSide(Facing::EAST)); if($connectWest or $connectEast){ //X axis (west/east) @@ -62,8 +62,8 @@ abstract class Thin extends Transparent{ ); } - $connectNorth = $this->canConnect($this->getSide(Vector3::SIDE_NORTH)); - $connectSouth = $this->canConnect($this->getSide(Vector3::SIDE_SOUTH)); + $connectNorth = $this->canConnect($this->getSide(Facing::NORTH)); + $connectSouth = $this->canConnect($this->getSide(Facing::SOUTH)); if($connectNorth or $connectSouth){ //Z axis (north/south) diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index 3c310a68ad..b553bfd8c3 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -44,32 +45,32 @@ class Torch extends Flowable{ } public function onNearbyBlockChange() : void{ - $below = $this->getSide(Vector3::SIDE_DOWN); + $below = $this->getSide(Facing::DOWN); $side = $this->getDamage(); - $faces = [ - 0 => Vector3::SIDE_DOWN, - 1 => Vector3::SIDE_WEST, - 2 => Vector3::SIDE_EAST, - 3 => Vector3::SIDE_NORTH, - 4 => Vector3::SIDE_SOUTH, - 5 => Vector3::SIDE_DOWN + static $faces = [ + 0 => Facing::DOWN, + 1 => Facing::WEST, + 2 => Facing::EAST, + 3 => Facing::NORTH, + 4 => Facing::SOUTH, + 5 => Facing::DOWN ]; - if($this->getSide($faces[$side])->isTransparent() and !($side === Vector3::SIDE_DOWN and ($below->getId() === self::FENCE or $below->getId() === self::COBBLESTONE_WALL))){ + if($this->getSide($faces[$side])->isTransparent() and !($side === Facing::DOWN and ($below->getId() === self::FENCE or $below->getId() === self::COBBLESTONE_WALL))){ $this->getLevel()->useBreakOn($this); } } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $below = $this->getSide(Vector3::SIDE_DOWN); + $below = $this->getSide(Facing::DOWN); - if(!$blockClicked->isTransparent() and $face !== Vector3::SIDE_DOWN){ - $faces = [ - Vector3::SIDE_UP => 5, - Vector3::SIDE_NORTH => 4, - Vector3::SIDE_SOUTH => 3, - Vector3::SIDE_WEST => 2, - Vector3::SIDE_EAST => 1 + if(!$blockClicked->isTransparent() and $face !== Facing::DOWN){ + static $faces = [ + Facing::UP => 5, + Facing::NORTH => 4, + Facing::SOUTH => 3, + Facing::WEST => 2, + Facing::EAST => 1 ]; $this->meta = $faces[$face]; $this->getLevel()->setBlock($blockReplace, $this, true, true); diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index 63277f66c1..1d01dcd027 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -26,6 +26,8 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\level\sound\DoorSound; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Bearing; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -81,16 +83,16 @@ class Trapdoor extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $directions = [ - 0 => 1, - 1 => 3, - 2 => 0, - 3 => 2 + static $directions = [ + Bearing::SOUTH => 2, + Bearing::WEST => 1, + Bearing::NORTH => 3, + Bearing::EAST => 0 ]; if($player !== null){ - $this->meta = $directions[$player->getDirection() & 0x03]; + $this->meta = $directions[$player->getDirection()]; } - if(($clickVector->y > 0.5 and $face !== self::SIDE_UP) or $face === self::SIDE_DOWN){ + if(($clickVector->y > 0.5 and $face !== Facing::UP) or $face === Facing::DOWN){ $this->meta |= self::MASK_UPPER; //top half of block } $this->getLevel()->setBlock($blockReplace, $this, true, true); diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index f9c27a65e7..72bc36fc59 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\entity\Entity; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -111,7 +112,7 @@ class Vine extends Flowable{ //TODO: Missing NORTH check - if(!$flag and $this->getSide(Vector3::SIDE_UP)->isSolid()){ + if(!$flag and $this->getSide(Facing::UP)->isSolid()){ $minY = min($minY, 0.9375); $maxY = 1; $minX = 0; @@ -124,15 +125,15 @@ class Vine extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if(!$blockClicked->isSolid() or $face === Vector3::SIDE_UP or $face === Vector3::SIDE_DOWN){ + if(!$blockClicked->isSolid() or $face === Facing::UP or $face === Facing::DOWN){ return false; } - $faces = [ - Vector3::SIDE_NORTH => self::FLAG_SOUTH, - Vector3::SIDE_SOUTH => self::FLAG_NORTH, - Vector3::SIDE_WEST => self::FLAG_EAST, - Vector3::SIDE_EAST => self::FLAG_WEST + static $faces = [ + Facing::NORTH => self::FLAG_SOUTH, + Facing::SOUTH => self::FLAG_NORTH, + Facing::WEST => self::FLAG_EAST, + Facing::EAST => self::FLAG_WEST ]; $this->meta = $faces[$face] ?? 0; @@ -145,11 +146,11 @@ class Vine extends Flowable{ } public function onNearbyBlockChange() : void{ - $sides = [ - self::FLAG_SOUTH => Vector3::SIDE_SOUTH, - self::FLAG_WEST => Vector3::SIDE_WEST, - self::FLAG_NORTH => Vector3::SIDE_NORTH, - self::FLAG_EAST => Vector3::SIDE_EAST + static $sides = [ + self::FLAG_SOUTH => Facing::SOUTH, + self::FLAG_WEST => Facing::WEST, + self::FLAG_NORTH => Facing::NORTH, + self::FLAG_EAST => Facing::EAST ]; $meta = $this->meta; diff --git a/src/pocketmine/block/WaterLily.php b/src/pocketmine/block/WaterLily.php index 78eb3cd333..59f999960f 100644 --- a/src/pocketmine/block/WaterLily.php +++ b/src/pocketmine/block/WaterLily.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -51,7 +52,7 @@ class WaterLily extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($blockClicked instanceof Water){ - $up = $blockClicked->getSide(Vector3::SIDE_UP); + $up = $blockClicked->getSide(Facing::UP); if($up->getId() === Block::AIR){ $this->getLevel()->setBlock($up, $this, true, true); return true; @@ -62,7 +63,7 @@ class WaterLily extends Flowable{ } public function onNearbyBlockChange() : void{ - if(!($this->getSide(Vector3::SIDE_DOWN) instanceof Water)){ + if(!($this->getSide(Facing::DOWN) instanceof Water)){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/utils/PillarRotationHelper.php b/src/pocketmine/block/utils/PillarRotationHelper.php index 8a633c11f4..8e64afd92f 100644 --- a/src/pocketmine/block/utils/PillarRotationHelper.php +++ b/src/pocketmine/block/utils/PillarRotationHelper.php @@ -23,17 +23,17 @@ declare(strict_types=1); namespace pocketmine\block\utils; -use pocketmine\math\Vector3; +use pocketmine\math\Facing; class PillarRotationHelper{ public static function getMetaFromFace(int $meta, int $face) : int{ - $faces = [ - Vector3::SIDE_DOWN => 0, - Vector3::SIDE_NORTH => 0x08, - Vector3::SIDE_WEST => 0x04 + static $bits = [ + Facing::AXIS_Y => 0, + Facing::AXIS_Z => 0x08, + Facing::AXIS_X => 0x04 ]; - return ($meta & 0x03) | $faces[$face & ~0x01]; + return ($meta & 0x03) | $bits[Facing::axis($face)]; } } diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index eb8aa1171c..25f68b0c98 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -53,6 +53,8 @@ use pocketmine\level\Level; use pocketmine\level\Location; use pocketmine\level\Position; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Bearing; +use pocketmine\math\Facing; use pocketmine\math\Vector2; use pocketmine\math\Vector3; use pocketmine\metadata\Metadatable; @@ -1208,66 +1210,66 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ if($westNonSolid){ $limit = $diffX; - $direction = Vector3::SIDE_WEST; + $direction = Facing::WEST; } if($eastNonSolid and 1 - $diffX < $limit){ $limit = 1 - $diffX; - $direction = Vector3::SIDE_EAST; + $direction = Facing::EAST; } if($downNonSolid and $diffY < $limit){ $limit = $diffY; - $direction = Vector3::SIDE_DOWN; + $direction = Facing::DOWN; } if($upNonSolid and 1 - $diffY < $limit){ $limit = 1 - $diffY; - $direction = Vector3::SIDE_UP; + $direction = Facing::UP; } if($northNonSolid and $diffZ < $limit){ $limit = $diffZ; - $direction = Vector3::SIDE_NORTH; + $direction = Facing::NORTH; } if($southNonSolid and 1 - $diffZ < $limit){ - $direction = Vector3::SIDE_SOUTH; + $direction = Facing::SOUTH; } $force = lcg_value() * 0.2 + 0.1; - if($direction === Vector3::SIDE_WEST){ + if($direction === Facing::WEST){ $this->motion->x = -$force; return true; } - if($direction === Vector3::SIDE_EAST){ + if($direction === Facing::EAST){ $this->motion->x = $force; return true; } - if($direction === Vector3::SIDE_DOWN){ + if($direction === Facing::DOWN){ $this->motion->y = -$force; return true; } - if($direction === Vector3::SIDE_UP){ + if($direction === Facing::UP){ $this->motion->y = $force; return true; } - if($direction === Vector3::SIDE_NORTH){ + if($direction === Facing::NORTH){ $this->motion->z = -$force; return true; } - if($direction === Vector3::SIDE_SOUTH){ + if($direction === Facing::SOUTH){ $this->motion->z = $force; return true; @@ -1277,25 +1279,8 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ return false; } - /** - * @return int|null - */ - public function getDirection() : ?int{ - $rotation = ($this->yaw - 90) % 360; - if($rotation < 0){ - $rotation += 360.0; - } - if((0 <= $rotation and $rotation < 45) or (315 <= $rotation and $rotation < 360)){ - return 2; //North - }elseif(45 <= $rotation and $rotation < 135){ - return 3; //East - }elseif(135 <= $rotation and $rotation < 225){ - return 0; //South - }elseif(225 <= $rotation and $rotation < 315){ - return 1; //West - }else{ - return null; - } + public function getDirection() : int{ + return Bearing::fromAngle($this->yaw); } /** diff --git a/src/pocketmine/entity/object/Painting.php b/src/pocketmine/entity/object/Painting.php index 5b5db672d6..7699db77ac 100644 --- a/src/pocketmine/entity/object/Painting.php +++ b/src/pocketmine/entity/object/Painting.php @@ -32,6 +32,8 @@ use pocketmine\item\ItemFactory; use pocketmine\level\Level; use pocketmine\level\particle\DestroyBlockParticle; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Bearing; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; @@ -110,29 +112,14 @@ class Painting extends Entity{ } protected function recalculateBoundingBox() : void{ - static $directions = [ - 0 => Vector3::SIDE_SOUTH, - 1 => Vector3::SIDE_WEST, - 2 => Vector3::SIDE_NORTH, - 3 => Vector3::SIDE_EAST - ]; - - $facing = $directions[$this->direction]; - + $facing = Bearing::toFacing($this->direction); $this->boundingBox->setBB(self::getPaintingBB($this->blockIn->getSide($facing), $facing, $this->getMotive())); } public function onNearbyBlockChange() : void{ parent::onNearbyBlockChange(); - static $directions = [ - 0 => Vector3::SIDE_SOUTH, - 1 => Vector3::SIDE_WEST, - 2 => Vector3::SIDE_NORTH, - 3 => Vector3::SIDE_EAST - ]; - - $face = $directions[$this->direction]; + $face = Bearing::toFacing($this->direction); if(!self::canFit($this->level, $this->blockIn->getSide($face), $face, false, $this->getMotive())){ $this->kill(); } @@ -170,7 +157,7 @@ class Painting extends Entity{ return PaintingMotive::getMotiveByName($this->motive); } - public function getDirection() : ?int{ + public function getDirection() : int{ return $this->direction; } @@ -199,25 +186,25 @@ class Painting extends Entity{ $maxY = $minY + $height; switch($facing){ - case Vector3::SIDE_NORTH: + case Facing::NORTH: $minZ = 1 - $thickness; $maxZ = 1; $maxX = $horizontalStart + 1; $minX = $maxX - $width; break; - case Vector3::SIDE_SOUTH: + case Facing::SOUTH: $minZ = 0; $maxZ = $thickness; $minX = -$horizontalStart; $maxX = $minX + $width; break; - case Vector3::SIDE_WEST: + case Facing::WEST: $minX = 1 - $thickness; $maxX = 1; $minZ = -$horizontalStart; $maxZ = $minZ + $width; break; - case Vector3::SIDE_EAST: + case Facing::EAST: $minX = 0; $maxX = $thickness; $maxZ = $horizontalStart + 1; @@ -253,30 +240,15 @@ class Painting extends Entity{ $horizontalStart = (int) (ceil($width / 2) - 1); $verticalStart = (int) (ceil($height / 2) - 1); - switch($facing){ - case Vector3::SIDE_NORTH: - $rotatedFace = Vector3::SIDE_WEST; - break; - case Vector3::SIDE_WEST: - $rotatedFace = Vector3::SIDE_SOUTH; - break; - case Vector3::SIDE_SOUTH: - $rotatedFace = Vector3::SIDE_EAST; - break; - case Vector3::SIDE_EAST: - $rotatedFace = Vector3::SIDE_NORTH; - break; - default: - return false; - } + $rotatedFace = Bearing::toFacing(Bearing::rotate(Bearing::fromFacing($facing), -1)); - $oppositeSide = Vector3::getOppositeSide($facing); + $oppositeSide = Facing::opposite($facing); - $startPos = $blockIn->asVector3()->getSide(Vector3::getOppositeSide($rotatedFace), $horizontalStart)->getSide(Vector3::SIDE_DOWN, $verticalStart); + $startPos = $blockIn->asVector3()->getSide(Facing::opposite($rotatedFace), $horizontalStart)->getSide(Facing::DOWN, $verticalStart); for($w = 0; $w < $width; ++$w){ for($h = 0; $h < $height; ++$h){ - $pos = $startPos->getSide($rotatedFace, $w)->getSide(Vector3::SIDE_UP, $h); + $pos = $startPos->getSide($rotatedFace, $w)->getSide(Facing::UP, $h); $block = $level->getBlockAt($pos->x, $pos->y, $pos->z); if($block->isSolid() or !$block->getSide($oppositeSide)->isSolid()){ diff --git a/src/pocketmine/item/PaintingItem.php b/src/pocketmine/item/PaintingItem.php index c342502a33..0ee2542fe8 100644 --- a/src/pocketmine/item/PaintingItem.php +++ b/src/pocketmine/item/PaintingItem.php @@ -27,6 +27,7 @@ use pocketmine\block\Block; use pocketmine\entity\Entity; use pocketmine\entity\object\Painting; use pocketmine\entity\object\PaintingMotive; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\Player; @@ -71,10 +72,10 @@ class PaintingItem extends Item{ $motive = $motives[array_rand($motives)]; static $directions = [ - Vector3::SIDE_SOUTH => 0, - Vector3::SIDE_WEST => 1, - Vector3::SIDE_NORTH => 2, - Vector3::SIDE_EAST => 3 + Facing::SOUTH => 0, + Facing::WEST => 1, + Facing::NORTH => 2, + Facing::EAST => 3 ]; $direction = $directions[$face] ?? -1; diff --git a/src/pocketmine/tile/Skull.php b/src/pocketmine/tile/Skull.php index 4367991a65..bfe0df385f 100644 --- a/src/pocketmine/tile/Skull.php +++ b/src/pocketmine/tile/Skull.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\tile; use pocketmine\item\Item; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\Player; @@ -74,7 +75,7 @@ class Skull extends Spawnable{ $nbt->setByte(self::TAG_SKULL_TYPE, $item !== null ? $item->getDamage() : self::TYPE_SKELETON); $rot = 0; - if($face === Vector3::SIDE_UP and $player !== null){ + if($face === Facing::UP and $player !== null){ $rot = floor(($player->yaw * 16 / 360) + 0.5) & 0x0F; } $nbt->setByte(self::TAG_ROT, $rot); From 5ce2d5e072e8659190d1111cd394ebb8f78db4dc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 10 Sep 2018 13:28:15 +0100 Subject: [PATCH 0126/3224] Clean up to Generator creation, remove getSeed() from ChunkManager interface it's the generator's responsibility to know about the seed, not the chunkmanager's. This now reduces the complexity of implementing and using a chunkmanager. --- src/pocketmine/level/ChunkManager.php | 7 -- src/pocketmine/level/SimpleChunkManager.php | 14 +-- src/pocketmine/level/generator/Flat.php | 20 ++--- src/pocketmine/level/generator/Generator.php | 18 ++-- .../level/generator/GeneratorRegisterTask.php | 5 +- .../level/generator/hell/Nether.php | 28 +++--- .../level/generator/normal/Normal.php | 90 +++++++++---------- 7 files changed, 73 insertions(+), 109 deletions(-) diff --git a/src/pocketmine/level/ChunkManager.php b/src/pocketmine/level/ChunkManager.php index ce17eec12e..373b6cbef3 100644 --- a/src/pocketmine/level/ChunkManager.php +++ b/src/pocketmine/level/ChunkManager.php @@ -125,13 +125,6 @@ interface ChunkManager{ */ public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk = null); - /** - * Gets the level seed - * - * @return int - */ - public function getSeed() : int; - /** * Returns the height of the world * @return int diff --git a/src/pocketmine/level/SimpleChunkManager.php b/src/pocketmine/level/SimpleChunkManager.php index 051176d148..e240e23ee6 100644 --- a/src/pocketmine/level/SimpleChunkManager.php +++ b/src/pocketmine/level/SimpleChunkManager.php @@ -30,17 +30,14 @@ class SimpleChunkManager implements ChunkManager{ /** @var Chunk[] */ protected $chunks = []; - protected $seed; protected $worldHeight; /** * SimpleChunkManager constructor. * - * @param int $seed * @param int $worldHeight */ - public function __construct(int $seed, int $worldHeight = Level::Y_MAX){ - $this->seed = $seed; + public function __construct(int $worldHeight = Level::Y_MAX){ $this->worldHeight = $worldHeight; } @@ -159,15 +156,6 @@ class SimpleChunkManager implements ChunkManager{ $this->chunks = []; } - /** - * Gets the level seed - * - * @return int - */ - public function getSeed() : int{ - return $this->seed; - } - public function getWorldHeight() : int{ return $this->worldHeight; } diff --git a/src/pocketmine/level/generator/Flat.php b/src/pocketmine/level/generator/Flat.php index fe4f0e0fd4..e525cafbea 100644 --- a/src/pocketmine/level/generator/Flat.php +++ b/src/pocketmine/level/generator/Flat.php @@ -45,21 +45,16 @@ class Flat extends Generator{ private $floorLevel; /** @var int */ private $biome; - /** @var mixed[] */ - private $options; /** @var string */ private $preset; - public function getSettings() : array{ - return $this->options; - } - public function getName() : string{ return "flat"; } - public function __construct(array $options = []){ - $this->options = $options; + public function __construct(ChunkManager $level, int $seed, array $options = []){ + parent::__construct($level, $seed, $options); + if(isset($this->options["preset"]) and $this->options["preset"] != ""){ $this->preset = $this->options["preset"]; }else{ @@ -83,6 +78,8 @@ class Flat extends Generator{ ]); $this->populators[] = $ores; } + + $this->generateBaseChunk(); } public static function parseLayers(string $layers) : array{ @@ -151,11 +148,6 @@ class Flat extends Generator{ } } - public function init(ChunkManager $level, Random $random) : void{ - parent::init($level, $random); - $this->generateBaseChunk(); - } - public function generateChunk(int $chunkX, int $chunkZ) : void{ $chunk = clone $this->chunk; $chunk->setX($chunkX); @@ -164,7 +156,7 @@ class Flat extends Generator{ } public function populateChunk(int $chunkX, int $chunkZ) : void{ - $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed()); + $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed); foreach($this->populators as $populator){ $populator->populate($this->level, $chunkX, $chunkZ, $this->random); } diff --git a/src/pocketmine/level/generator/Generator.php b/src/pocketmine/level/generator/Generator.php index 44b47d90d0..b844301ce6 100644 --- a/src/pocketmine/level/generator/Generator.php +++ b/src/pocketmine/level/generator/Generator.php @@ -54,22 +54,28 @@ abstract class Generator{ /** @var ChunkManager */ protected $level; + /** @var int */ + protected $seed; + /** @var array */ + protected $options; + /** @var Random */ protected $random; - abstract public function __construct(array $settings = []); - - - public function init(ChunkManager $level, Random $random) : void{ + public function __construct(ChunkManager $level, int $seed, array $options = []){ $this->level = $level; - $this->random = $random; + $this->seed = $seed; + $this->options = $options; + $this->random = new Random($seed); } abstract public function generateChunk(int $chunkX, int $chunkZ) : void; abstract public function populateChunk(int $chunkX, int $chunkZ) : void; - abstract public function getSettings() : array; + public function getSettings() : array{ + return $this->options; + } abstract public function getName() : string; diff --git a/src/pocketmine/level/generator/GeneratorRegisterTask.php b/src/pocketmine/level/generator/GeneratorRegisterTask.php index 4a2aef9788..ce0b47d81b 100644 --- a/src/pocketmine/level/generator/GeneratorRegisterTask.php +++ b/src/pocketmine/level/generator/GeneratorRegisterTask.php @@ -49,15 +49,14 @@ class GeneratorRegisterTask extends AsyncTask{ public function onRun() : void{ BlockFactory::init(); Biome::init(); - $manager = new SimpleChunkManager($this->seed, $this->worldHeight); + $manager = new SimpleChunkManager($this->worldHeight); $this->saveToThreadStore("generation.level{$this->levelId}.manager", $manager); /** * @var Generator $generator * @see Generator::__construct() */ - $generator = new $this->generatorClass(unserialize($this->settings)); - $generator->init($manager, new Random($manager->getSeed())); + $generator = new $this->generatorClass($manager, $this->seed, unserialize($this->settings)); $this->saveToThreadStore("generation.level{$this->levelId}.generator", $generator); } } diff --git a/src/pocketmine/level/generator/hell/Nether.php b/src/pocketmine/level/generator/hell/Nether.php index 1638702675..a51e2f6a5d 100644 --- a/src/pocketmine/level/generator/hell/Nether.php +++ b/src/pocketmine/level/generator/hell/Nether.php @@ -50,28 +50,16 @@ class Nether extends Generator{ /** @var Simplex */ private $noiseBase; - public function __construct(array $options = []){ + public function __construct(ChunkManager $level, int $seed, array $options = []){ + parent::__construct($level, $seed, $options); - } - - public function getName() : string{ - return "nether"; - } - - public function getSettings() : array{ - return []; - } - - public function init(ChunkManager $level, Random $random) : void{ - parent::init($level, $random); - $this->random->setSeed($this->level->getSeed()); $this->noiseBase = new Simplex($this->random, 4, 1 / 4, 1 / 64); - $this->random->setSeed($this->level->getSeed()); + $this->random->setSeed($this->seed); /*$ores = new Ore(); $ores->setOreTypes([ new OreType(new CoalOre(), 20, 16, 0, 128), - new OreType(New IronOre(), 20, 8, 0, 64), + new OreType(new IronOre(), 20, 8, 0, 64), new OreType(new RedstoneOre(), 8, 7, 0, 16), new OreType(new LapisOre(), 1, 6, 0, 32), new OreType(new GoldOre(), 2, 8, 0, 32), @@ -82,8 +70,12 @@ class Nether extends Generator{ $this->populators[] = $ores;*/ } + public function getName() : string{ + return "nether"; + } + public function generateChunk(int $chunkX, int $chunkZ) : void{ - $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed()); + $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed); $noise = $this->noiseBase->getFastNoise3D(16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16); @@ -118,7 +110,7 @@ class Nether extends Generator{ } public function populateChunk(int $chunkX, int $chunkZ) : void{ - $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed()); + $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed); foreach($this->populators as $populator){ $populator->populate($this->level, $chunkX, $chunkZ, $this->random); } diff --git a/src/pocketmine/level/generator/normal/Normal.php b/src/pocketmine/level/generator/normal/Normal.php index 0c1ca5dab2..b34631199a 100644 --- a/src/pocketmine/level/generator/normal/Normal.php +++ b/src/pocketmine/level/generator/normal/Normal.php @@ -56,57 +56,15 @@ class Normal extends Generator{ private static $GAUSSIAN_KERNEL = null; private static $SMOOTH_SIZE = 2; - public function __construct(array $options = []){ + public function __construct(ChunkManager $level, int $seed, array $options = []){ + parent::__construct($level, $seed, $options); if(self::$GAUSSIAN_KERNEL === null){ self::generateKernel(); } - } - private static function generateKernel() : void{ - self::$GAUSSIAN_KERNEL = []; - - $bellSize = 1 / self::$SMOOTH_SIZE; - $bellHeight = 2 * self::$SMOOTH_SIZE; - - for($sx = -self::$SMOOTH_SIZE; $sx <= self::$SMOOTH_SIZE; ++$sx){ - self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE] = []; - - for($sz = -self::$SMOOTH_SIZE; $sz <= self::$SMOOTH_SIZE; ++$sz){ - $bx = $bellSize * $sx; - $bz = $bellSize * $sz; - self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE][$sz + self::$SMOOTH_SIZE] = $bellHeight * exp(-($bx * $bx + $bz * $bz) / 2); - } - } - } - - public function getName() : string{ - return "normal"; - } - - public function getSettings() : array{ - return []; - } - - private function pickBiome(int $x, int $z) : Biome{ - $hash = $x * 2345803 ^ $z * 9236449 ^ $this->level->getSeed(); - $hash *= $hash + 223; - $xNoise = $hash >> 20 & 3; - $zNoise = $hash >> 22 & 3; - if($xNoise == 3){ - $xNoise = 1; - } - if($zNoise == 3){ - $zNoise = 1; - } - - return $this->selector->pickBiome($x + $xNoise - 1, $z + $zNoise - 1); - } - - public function init(ChunkManager $level, Random $random) : void{ - parent::init($level, $random); - $this->random->setSeed($this->level->getSeed()); $this->noiseBase = new Simplex($this->random, 4, 1 / 4, 1 / 32); - $this->random->setSeed($this->level->getSeed()); + $this->random->setSeed($this->seed); + $this->selector = new class($this->random) extends BiomeSelector{ protected function lookup(float $temperature, float $rainfall) : int{ if($rainfall < 0.25){ @@ -167,8 +125,44 @@ class Normal extends Generator{ $this->populators[] = $ores; } + private static function generateKernel() : void{ + self::$GAUSSIAN_KERNEL = []; + + $bellSize = 1 / self::$SMOOTH_SIZE; + $bellHeight = 2 * self::$SMOOTH_SIZE; + + for($sx = -self::$SMOOTH_SIZE; $sx <= self::$SMOOTH_SIZE; ++$sx){ + self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE] = []; + + for($sz = -self::$SMOOTH_SIZE; $sz <= self::$SMOOTH_SIZE; ++$sz){ + $bx = $bellSize * $sx; + $bz = $bellSize * $sz; + self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE][$sz + self::$SMOOTH_SIZE] = $bellHeight * exp(-($bx * $bx + $bz * $bz) / 2); + } + } + } + + public function getName() : string{ + return "normal"; + } + + private function pickBiome(int $x, int $z) : Biome{ + $hash = $x * 2345803 ^ $z * 9236449 ^ $this->seed; + $hash *= $hash + 223; + $xNoise = $hash >> 20 & 3; + $zNoise = $hash >> 22 & 3; + if($xNoise == 3){ + $xNoise = 1; + } + if($zNoise == 3){ + $zNoise = 1; + } + + return $this->selector->pickBiome($x + $xNoise - 1, $z + $zNoise - 1); + } + public function generateChunk(int $chunkX, int $chunkZ) : void{ - $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed()); + $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed); $noise = $this->noiseBase->getFastNoise3D(16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16); @@ -235,7 +229,7 @@ class Normal extends Generator{ } public function populateChunk(int $chunkX, int $chunkZ) : void{ - $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed()); + $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed); foreach($this->populators as $populator){ $populator->populate($this->level, $chunkX, $chunkZ, $this->random); } From d62e00cc74f2a62b1c4dc98a5fb2056d9b184d7b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 10 Sep 2018 15:47:12 +0100 Subject: [PATCH 0127/3224] AsyncPool: Remove Server dependency (API breaks included) This brings two plugin-breaking changes: AsyncTask->onCompletion() and AsyncTask->onProgressUpdate() no longer accept Server parameters. This now allows for the functionality of AsyncPool and AsyncTask to be tested outside of a Server. --- src/pocketmine/Server.php | 2 +- .../command/defaults/TimingsCommand.php | 3 +-- .../level/generator/PopulationTask.php | 3 +-- .../level/light/LightPopulationTask.php | 3 +-- src/pocketmine/network/mcpe/ChunkRequestTask.php | 3 +-- .../network/mcpe/CompressBatchTask.php | 3 +-- src/pocketmine/network/mcpe/ProcessLoginTask.php | 5 ++--- src/pocketmine/scheduler/AsyncPool.php | 14 ++++---------- src/pocketmine/scheduler/AsyncTask.php | 16 +++++----------- src/pocketmine/updater/UpdateCheckTask.php | 4 +--- .../tests/AsyncTaskMainLoggerTest.php | 3 +-- 11 files changed, 19 insertions(+), 40 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 561446996b..1af22c6a12 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1528,7 +1528,7 @@ class Server{ $poolSize = max(1, (int) $poolSize); } - $this->asyncPool = new AsyncPool($this, $poolSize, (int) max(-1, (int) $this->getProperty("memory.async-worker-hard-limit", 256)), $this->autoloader, $this->logger); + $this->asyncPool = new AsyncPool($poolSize, (int) max(-1, (int) $this->getProperty("memory.async-worker-hard-limit", 256)), $this->autoloader, $this->logger); if($this->getProperty("network.batch-threshold", 256) >= 0){ NetworkCompression::$THRESHOLD = (int) $this->getProperty("network.batch-threshold", 256); diff --git a/src/pocketmine/command/defaults/TimingsCommand.php b/src/pocketmine/command/defaults/TimingsCommand.php index 50ff20046c..cff8e22987 100644 --- a/src/pocketmine/command/defaults/TimingsCommand.php +++ b/src/pocketmine/command/defaults/TimingsCommand.php @@ -28,7 +28,6 @@ use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; use pocketmine\Player; use pocketmine\scheduler\BulkCurlTask; -use pocketmine\Server; use pocketmine\timings\TimingsHandler; use pocketmine\utils\InternetException; @@ -127,7 +126,7 @@ class TimingsCommand extends VanillaCommand{ $this->storeLocal($sender); } - public function onCompletion(Server $server){ + public function onCompletion(){ $sender = $this->fetchLocal(); if($sender instanceof Player and !$sender->isOnline()){ // TODO replace with a more generic API method for checking availability of CommandSender return; diff --git a/src/pocketmine/level/generator/PopulationTask.php b/src/pocketmine/level/generator/PopulationTask.php index 7c469dc086..165bc9ca77 100644 --- a/src/pocketmine/level/generator/PopulationTask.php +++ b/src/pocketmine/level/generator/PopulationTask.php @@ -27,7 +27,6 @@ use pocketmine\level\format\Chunk; use pocketmine\level\Level; use pocketmine\level\SimpleChunkManager; use pocketmine\scheduler\AsyncTask; -use pocketmine\Server; class PopulationTask extends AsyncTask{ @@ -137,7 +136,7 @@ class PopulationTask extends AsyncTask{ } } - public function onCompletion(Server $server) : void{ + public function onCompletion() : void{ /** @var Level $level */ $level = $this->fetchLocal(); if(!$level->isClosed()){ diff --git a/src/pocketmine/level/light/LightPopulationTask.php b/src/pocketmine/level/light/LightPopulationTask.php index 1e6c9f7eb5..4902c7d59a 100644 --- a/src/pocketmine/level/light/LightPopulationTask.php +++ b/src/pocketmine/level/light/LightPopulationTask.php @@ -26,7 +26,6 @@ namespace pocketmine\level\light; use pocketmine\level\format\Chunk; use pocketmine\level\Level; use pocketmine\scheduler\AsyncTask; -use pocketmine\Server; class LightPopulationTask extends AsyncTask{ @@ -48,7 +47,7 @@ class LightPopulationTask extends AsyncTask{ $this->chunk = $chunk->fastSerialize(); } - public function onCompletion(Server $server){ + public function onCompletion() : void{ /** @var Level $level */ $level = $this->fetchLocal(); if(!$level->isClosed()){ diff --git a/src/pocketmine/network/mcpe/ChunkRequestTask.php b/src/pocketmine/network/mcpe/ChunkRequestTask.php index 885bb44f4f..7ea3b5e0d4 100644 --- a/src/pocketmine/network/mcpe/ChunkRequestTask.php +++ b/src/pocketmine/network/mcpe/ChunkRequestTask.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe; use pocketmine\level\format\Chunk; use pocketmine\network\mcpe\protocol\FullChunkDataPacket; use pocketmine\scheduler\AsyncTask; -use pocketmine\Server; use pocketmine\tile\Spawnable; class ChunkRequestTask extends AsyncTask{ @@ -75,7 +74,7 @@ class ChunkRequestTask extends AsyncTask{ $this->setResult(NetworkCompression::compress($stream->buffer, $this->compressionLevel), false); } - public function onCompletion(Server $server) : void{ + public function onCompletion() : void{ /** @var CompressBatchPromise $promise */ $promise = $this->fetchLocal(); $promise->resolve($this->getResult()); diff --git a/src/pocketmine/network/mcpe/CompressBatchTask.php b/src/pocketmine/network/mcpe/CompressBatchTask.php index 8604603157..a0d1c96de1 100644 --- a/src/pocketmine/network/mcpe/CompressBatchTask.php +++ b/src/pocketmine/network/mcpe/CompressBatchTask.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; use pocketmine\scheduler\AsyncTask; -use pocketmine\Server; class CompressBatchTask extends AsyncTask{ @@ -46,7 +45,7 @@ class CompressBatchTask extends AsyncTask{ $this->setResult(NetworkCompression::compress($this->data, $this->level), false); } - public function onCompletion(Server $server) : void{ + public function onCompletion() : void{ /** @var CompressBatchPromise $promise */ $promise = $this->fetchLocal(); $promise->resolve($this->getResult()); diff --git a/src/pocketmine/network/mcpe/ProcessLoginTask.php b/src/pocketmine/network/mcpe/ProcessLoginTask.php index 256a7a55d4..c130e93c07 100644 --- a/src/pocketmine/network/mcpe/ProcessLoginTask.php +++ b/src/pocketmine/network/mcpe/ProcessLoginTask.php @@ -35,7 +35,6 @@ use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer; use pocketmine\network\mcpe\protocol\LoginPacket; use pocketmine\Player; use pocketmine\scheduler\AsyncTask; -use pocketmine\Server; class ProcessLoginTask extends AsyncTask{ @@ -216,11 +215,11 @@ class ProcessLoginTask extends AsyncTask{ return rtrim(strtr(base64_encode($str), '+/', '-_'), '='); } - public function onCompletion(Server $server) : void{ + public function onCompletion() : void{ /** @var Player $player */ $player = $this->fetchLocal(); if(!$player->isConnected()){ - $server->getLogger()->error("Player " . $player->getName() . " was disconnected before their login could be verified"); + $this->worker->getLogger()->error("Player " . $player->getName() . " was disconnected before their login could be verified"); }elseif($player->setAuthenticationStatus($this->authenticated, $this->error)){ if(!$this->useEncryption){ $player->getNetworkSession()->onLoginSuccess(); diff --git a/src/pocketmine/scheduler/AsyncPool.php b/src/pocketmine/scheduler/AsyncPool.php index 5588a83009..e720e7e85f 100644 --- a/src/pocketmine/scheduler/AsyncPool.php +++ b/src/pocketmine/scheduler/AsyncPool.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\scheduler; -use pocketmine\Server; - /** * Manages general-purpose worker threads used for processing asynchronous tasks, and the tasks submitted to those * workers. @@ -32,9 +30,6 @@ use pocketmine\Server; class AsyncPool{ private const WORKER_START_OPTIONS = PTHREADS_INHERIT_INI | PTHREADS_INHERIT_CONSTANTS; - /** @var Server */ - private $server; - /** @var \ClassLoader */ private $classLoader; /** @var \ThreadedLogger */ @@ -59,8 +54,7 @@ class AsyncPool{ /** @var \Closure[] */ private $workerStartHooks = []; - public function __construct(Server $server, int $size, int $workerMemoryLimit, \ClassLoader $classLoader, \ThreadedLogger $logger){ - $this->server = $server; + public function __construct(int $size, int $workerMemoryLimit, \ClassLoader $classLoader, \ThreadedLogger $logger){ $this->size = $size; $this->workerMemoryLimit = $workerMemoryLimit; $this->classLoader = $classLoader; @@ -259,7 +253,7 @@ class AsyncPool{ } if(count($this->tasks) > 0){ - Server::microSleep(25000); + usleep(25000); } }while(count($this->tasks) > 0); @@ -290,12 +284,12 @@ class AsyncPool{ public function collectTasks() : void{ foreach($this->tasks as $task){ if(!$task->isGarbage()){ - $task->checkProgressUpdates($this->server); + $task->checkProgressUpdates(); } if($task->isGarbage() and !$task->isRunning() and !$task->isCrashed()){ if(!$task->hasCancelledRun()){ try{ - $task->onCompletion($this->server); + $task->onCompletion(); if($task->removeDanglingStoredObjects()){ $this->logger->notice("AsyncTask " . get_class($task) . " stored local complex data but did not remove them after completion"); } diff --git a/src/pocketmine/scheduler/AsyncTask.php b/src/pocketmine/scheduler/AsyncTask.php index 6e4a517d51..021f6cb948 100644 --- a/src/pocketmine/scheduler/AsyncTask.php +++ b/src/pocketmine/scheduler/AsyncTask.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\scheduler; use pocketmine\Collectable; -use pocketmine\Server; /** * Class used to run async tasks in other threads. @@ -174,11 +173,9 @@ abstract class AsyncTask extends Collectable{ * Actions to execute when completed (on main thread) * Implement this if you want to handle the data in your AsyncTask after it has been processed * - * @param Server $server - * * @return void */ - public function onCompletion(Server $server){ + public function onCompletion(){ } @@ -194,13 +191,11 @@ abstract class AsyncTask extends Collectable{ /** * @internal Only call from AsyncPool.php on the main thread - * - * @param Server $server */ - public function checkProgressUpdates(Server $server){ + public function checkProgressUpdates(){ while($this->progressUpdates->count() !== 0){ $progress = $this->progressUpdates->shift(); - $this->onProgressUpdate($server, unserialize($progress)); + $this->onProgressUpdate(unserialize($progress)); } } @@ -209,11 +204,10 @@ abstract class AsyncTask extends Collectable{ * All {@link AsyncTask#publishProgress} calls should result in {@link AsyncTask#onProgressUpdate} calls before * {@link AsyncTask#onCompletion} is called. * - * @param Server $server - * @param mixed $progress The parameter passed to {@link AsyncTask#publishProgress}. It is serialize()'ed + * @param mixed $progress The parameter passed to {@link AsyncTask#publishProgress}. It is serialize()'ed * and then unserialize()'ed, as if it has been cloned. */ - public function onProgressUpdate(Server $server, $progress){ + public function onProgressUpdate($progress){ } diff --git a/src/pocketmine/updater/UpdateCheckTask.php b/src/pocketmine/updater/UpdateCheckTask.php index 1044f9b5c3..5c70e4a026 100644 --- a/src/pocketmine/updater/UpdateCheckTask.php +++ b/src/pocketmine/updater/UpdateCheckTask.php @@ -24,9 +24,7 @@ declare(strict_types=1); namespace pocketmine\updater; - use pocketmine\scheduler\AsyncTask; -use pocketmine\Server; use pocketmine\utils\Internet; class UpdateCheckTask extends AsyncTask{ @@ -72,7 +70,7 @@ class UpdateCheckTask extends AsyncTask{ } } - public function onCompletion(Server $server){ + public function onCompletion(){ /** @var AutoUpdater $updater */ $updater = $this->fetchLocal(); if($this->hasResult()){ diff --git a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMainLoggerTest.php b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMainLoggerTest.php index 27d3bdc49c..11d087f94d 100644 --- a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMainLoggerTest.php +++ b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMainLoggerTest.php @@ -25,7 +25,6 @@ namespace pmmp\TesterPlugin\tests; use pmmp\TesterPlugin\Test; use pocketmine\scheduler\AsyncTask; -use pocketmine\Server; use pocketmine\utils\MainLogger; class AsyncTaskMainLoggerTest extends Test{ @@ -49,7 +48,7 @@ class AsyncTaskMainLoggerTest extends Test{ ob_end_flush(); } - public function onCompletion(Server $server){ + public function onCompletion(){ /** @var AsyncTaskMainLoggerTest $test */ $test = $this->fetchLocal(); $test->setResult($this->success ? Test::RESULT_OK : Test::RESULT_FAILED); From 37190c9a65643efccc515d5687374f30fcf26b96 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 10 Sep 2018 15:54:01 +0100 Subject: [PATCH 0128/3224] Apply typehints to all AsyncTask methods Since we're breaking API here anyway, no point in holding back on this. --- .../command/defaults/TimingsCommand.php | 2 +- .../level/light/LightPopulationTask.php | 2 +- src/pocketmine/scheduler/AsyncTask.php | 27 ++++++++----------- src/pocketmine/scheduler/BulkCurlTask.php | 2 +- .../scheduler/DumpWorkerMemoryTask.php | 2 +- src/pocketmine/scheduler/FileWriteTask.php | 2 +- .../scheduler/GarbageCollectionTask.php | 2 +- src/pocketmine/scheduler/SendUsageTask.php | 2 +- src/pocketmine/updater/UpdateCheckTask.php | 4 +-- .../tests/AsyncTaskMainLoggerTest.php | 4 +-- .../tests/AsyncTaskMemoryLeakTest.php | 2 +- 11 files changed, 23 insertions(+), 28 deletions(-) diff --git a/src/pocketmine/command/defaults/TimingsCommand.php b/src/pocketmine/command/defaults/TimingsCommand.php index cff8e22987..a7503860d4 100644 --- a/src/pocketmine/command/defaults/TimingsCommand.php +++ b/src/pocketmine/command/defaults/TimingsCommand.php @@ -126,7 +126,7 @@ class TimingsCommand extends VanillaCommand{ $this->storeLocal($sender); } - public function onCompletion(){ + public function onCompletion() : void{ $sender = $this->fetchLocal(); if($sender instanceof Player and !$sender->isOnline()){ // TODO replace with a more generic API method for checking availability of CommandSender return; diff --git a/src/pocketmine/level/light/LightPopulationTask.php b/src/pocketmine/level/light/LightPopulationTask.php index 4902c7d59a..ced91dc3da 100644 --- a/src/pocketmine/level/light/LightPopulationTask.php +++ b/src/pocketmine/level/light/LightPopulationTask.php @@ -36,7 +36,7 @@ class LightPopulationTask extends AsyncTask{ $this->chunk = $chunk->fastSerialize(); } - public function onRun(){ + public function onRun() : void{ /** @var Chunk $chunk */ $chunk = Chunk::fastDeserialize($this->chunk); diff --git a/src/pocketmine/scheduler/AsyncTask.php b/src/pocketmine/scheduler/AsyncTask.php index 021f6cb948..d3045c2b82 100644 --- a/src/pocketmine/scheduler/AsyncTask.php +++ b/src/pocketmine/scheduler/AsyncTask.php @@ -63,7 +63,7 @@ abstract class AsyncTask extends Collectable{ private $crashed = false; - public function run(){ + public function run() : void{ $this->result = null; if(!$this->cancelRun){ @@ -89,7 +89,7 @@ abstract class AsyncTask extends Collectable{ return $this->serialized ? unserialize($this->result) : $this->result; } - public function cancelRun(){ + public function cancelRun() : void{ $this->cancelRun = true; } @@ -108,19 +108,19 @@ abstract class AsyncTask extends Collectable{ * @param mixed $result * @param bool $serialize */ - public function setResult($result, bool $serialize = true){ + public function setResult($result, bool $serialize = true) : void{ $this->result = $serialize ? serialize($result) : $result; $this->serialized = $serialize; } - public function setTaskId(int $taskId){ + public function setTaskId(int $taskId) : void{ $this->taskId = $taskId; } /** * @return int|null */ - public function getTaskId(){ + public function getTaskId() : ?int{ return $this->taskId; } @@ -143,7 +143,7 @@ abstract class AsyncTask extends Collectable{ * @param string $identifier * @param mixed $value */ - public function saveToThreadStore(string $identifier, $value){ + public function saveToThreadStore(string $identifier, $value) : void{ if($this->worker === null or $this->isGarbage()){ throw new \BadMethodCallException("Objects can only be added to AsyncWorker thread-local storage during task execution"); } @@ -164,18 +164,14 @@ abstract class AsyncTask extends Collectable{ /** * Actions to execute when run - * - * @return void */ - abstract public function onRun(); + abstract public function onRun() : void; /** * Actions to execute when completed (on main thread) * Implement this if you want to handle the data in your AsyncTask after it has been processed - * - * @return void */ - public function onCompletion(){ + public function onCompletion() : void{ } @@ -192,7 +188,7 @@ abstract class AsyncTask extends Collectable{ /** * @internal Only call from AsyncPool.php on the main thread */ - public function checkProgressUpdates(){ + public function checkProgressUpdates() : void{ while($this->progressUpdates->count() !== 0){ $progress = $this->progressUpdates->shift(); $this->onProgressUpdate(unserialize($progress)); @@ -207,7 +203,7 @@ abstract class AsyncTask extends Collectable{ * @param mixed $progress The parameter passed to {@link AsyncTask#publishProgress}. It is serialize()'ed * and then unserialize()'ed, as if it has been cloned. */ - public function onProgressUpdate($progress){ + public function onProgressUpdate($progress) : void{ } @@ -232,9 +228,8 @@ abstract class AsyncTask extends Collectable{ * * @param mixed $complexData the data to store * - * @throws \BadMethodCallException if called from any thread except the main thread */ - protected function storeLocal($complexData){ + protected function storeLocal($complexData) : void{ if($this->worker !== null and $this->worker === \Thread::getCurrentThread()){ throw new \BadMethodCallException("Objects can only be stored from the parent thread"); } diff --git a/src/pocketmine/scheduler/BulkCurlTask.php b/src/pocketmine/scheduler/BulkCurlTask.php index 51682efcfa..0a1c4566ec 100644 --- a/src/pocketmine/scheduler/BulkCurlTask.php +++ b/src/pocketmine/scheduler/BulkCurlTask.php @@ -49,7 +49,7 @@ class BulkCurlTask extends AsyncTask{ $this->operations = serialize($operations); } - public function onRun(){ + public function onRun() : void{ $operations = unserialize($this->operations); $results = []; foreach($operations as $op){ diff --git a/src/pocketmine/scheduler/DumpWorkerMemoryTask.php b/src/pocketmine/scheduler/DumpWorkerMemoryTask.php index ac3525e577..b36529b19d 100644 --- a/src/pocketmine/scheduler/DumpWorkerMemoryTask.php +++ b/src/pocketmine/scheduler/DumpWorkerMemoryTask.php @@ -47,7 +47,7 @@ class DumpWorkerMemoryTask extends AsyncTask{ $this->maxStringSize = $maxStringSize; } - public function onRun(){ + public function onRun() : void{ MemoryManager::dumpMemory( $this->worker, $this->outputFolder . DIRECTORY_SEPARATOR . "AsyncWorker#" . $this->worker->getAsyncWorkerId(), diff --git a/src/pocketmine/scheduler/FileWriteTask.php b/src/pocketmine/scheduler/FileWriteTask.php index ab926f5956..fedb158c00 100644 --- a/src/pocketmine/scheduler/FileWriteTask.php +++ b/src/pocketmine/scheduler/FileWriteTask.php @@ -43,7 +43,7 @@ class FileWriteTask extends AsyncTask{ $this->flags = $flags; } - public function onRun(){ + public function onRun() : void{ try{ file_put_contents($this->path, $this->contents, $this->flags); }catch(\Throwable $e){ diff --git a/src/pocketmine/scheduler/GarbageCollectionTask.php b/src/pocketmine/scheduler/GarbageCollectionTask.php index 25c1f98458..b24ceb3190 100644 --- a/src/pocketmine/scheduler/GarbageCollectionTask.php +++ b/src/pocketmine/scheduler/GarbageCollectionTask.php @@ -25,7 +25,7 @@ namespace pocketmine\scheduler; class GarbageCollectionTask extends AsyncTask{ - public function onRun(){ + public function onRun() : void{ gc_enable(); gc_collect_cycles(); } diff --git a/src/pocketmine/scheduler/SendUsageTask.php b/src/pocketmine/scheduler/SendUsageTask.php index b618f33dda..3d55493914 100644 --- a/src/pocketmine/scheduler/SendUsageTask.php +++ b/src/pocketmine/scheduler/SendUsageTask.php @@ -146,7 +146,7 @@ class SendUsageTask extends AsyncTask{ $this->data = json_encode($data/*, JSON_PRETTY_PRINT*/); } - public function onRun(){ + public function onRun() : void{ try{ Internet::postURL($this->endpoint, $this->data, 5, [ "Content-Type: application/json", diff --git a/src/pocketmine/updater/UpdateCheckTask.php b/src/pocketmine/updater/UpdateCheckTask.php index 5c70e4a026..0cb0d586f2 100644 --- a/src/pocketmine/updater/UpdateCheckTask.php +++ b/src/pocketmine/updater/UpdateCheckTask.php @@ -42,7 +42,7 @@ class UpdateCheckTask extends AsyncTask{ $this->channel = $channel; } - public function onRun(){ + public function onRun() : void{ $error = ""; $response = Internet::getURL($this->endpoint . "?channel=" . $this->channel, 4, [], $error); $this->error = $error; @@ -70,7 +70,7 @@ class UpdateCheckTask extends AsyncTask{ } } - public function onCompletion(){ + public function onCompletion() : void{ /** @var AutoUpdater $updater */ $updater = $this->fetchLocal(); if($this->hasResult()){ diff --git a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMainLoggerTest.php b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMainLoggerTest.php index 11d087f94d..4972ec2866 100644 --- a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMainLoggerTest.php +++ b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMainLoggerTest.php @@ -39,7 +39,7 @@ class AsyncTaskMainLoggerTest extends Test{ $this->storeLocal($testObject); } - public function onRun(){ + public function onRun() : void{ ob_start(); MainLogger::getLogger()->info("Testing"); if(strpos(ob_get_contents(), "Testing") !== false){ @@ -48,7 +48,7 @@ class AsyncTaskMainLoggerTest extends Test{ ob_end_flush(); } - public function onCompletion(){ + public function onCompletion() : void{ /** @var AsyncTaskMainLoggerTest $test */ $test = $this->fetchLocal(); $test->setResult($this->success ? Test::RESULT_OK : Test::RESULT_FAILED); diff --git a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMemoryLeakTest.php b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMemoryLeakTest.php index 2b7fd4eab9..686ad9628e 100644 --- a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMemoryLeakTest.php +++ b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMemoryLeakTest.php @@ -50,7 +50,7 @@ class AsyncTaskMemoryLeakTest extends Test{ class TestAsyncTask extends AsyncTask{ public static $destroyed = false; - public function onRun(){ + public function onRun() : void{ usleep(50 * 1000); //1 server tick } From f03ab76c83ed4c8aabbac893579e857b9a833a7c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 10 Sep 2018 17:51:13 +0100 Subject: [PATCH 0129/3224] Remove imports left over from 5ce2d5e072e8659190d1111cd394ebb8f78db4dc --- src/pocketmine/level/generator/Flat.php | 1 - src/pocketmine/level/generator/GeneratorRegisterTask.php | 1 - src/pocketmine/level/generator/hell/Nether.php | 1 - src/pocketmine/level/generator/normal/Normal.php | 1 - 4 files changed, 4 deletions(-) diff --git a/src/pocketmine/level/generator/Flat.php b/src/pocketmine/level/generator/Flat.php index e525cafbea..2595b8cdeb 100644 --- a/src/pocketmine/level/generator/Flat.php +++ b/src/pocketmine/level/generator/Flat.php @@ -32,7 +32,6 @@ use pocketmine\level\generator\object\OreType; use pocketmine\level\generator\populator\Ore; use pocketmine\level\generator\populator\Populator; use pocketmine\math\Vector3; -use pocketmine\utils\Random; class Flat extends Generator{ /** @var Chunk */ diff --git a/src/pocketmine/level/generator/GeneratorRegisterTask.php b/src/pocketmine/level/generator/GeneratorRegisterTask.php index ce0b47d81b..629db1badb 100644 --- a/src/pocketmine/level/generator/GeneratorRegisterTask.php +++ b/src/pocketmine/level/generator/GeneratorRegisterTask.php @@ -28,7 +28,6 @@ use pocketmine\level\biome\Biome; use pocketmine\level\Level; use pocketmine\level\SimpleChunkManager; use pocketmine\scheduler\AsyncTask; -use pocketmine\utils\Random; class GeneratorRegisterTask extends AsyncTask{ diff --git a/src/pocketmine/level/generator/hell/Nether.php b/src/pocketmine/level/generator/hell/Nether.php index a51e2f6a5d..1215226911 100644 --- a/src/pocketmine/level/generator/hell/Nether.php +++ b/src/pocketmine/level/generator/hell/Nether.php @@ -30,7 +30,6 @@ use pocketmine\level\generator\Generator; use pocketmine\level\generator\noise\Simplex; use pocketmine\level\generator\populator\Populator; use pocketmine\math\Vector3; -use pocketmine\utils\Random; class Nether extends Generator{ diff --git a/src/pocketmine/level/generator/normal/Normal.php b/src/pocketmine/level/generator/normal/Normal.php index b34631199a..79e3a6e1f6 100644 --- a/src/pocketmine/level/generator/normal/Normal.php +++ b/src/pocketmine/level/generator/normal/Normal.php @@ -36,7 +36,6 @@ use pocketmine\level\generator\populator\Ore; use pocketmine\level\generator\populator\Populator; use pocketmine\level\Level; use pocketmine\math\Vector3; -use pocketmine\utils\Random; class Normal extends Generator{ From 535d4e2c9b4501e037bd2a39a6755988b5f6610b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 Sep 2018 10:51:37 +0100 Subject: [PATCH 0130/3224] Added NetworkSession->getPlayer() --- src/pocketmine/network/mcpe/NetworkSession.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index eff34d2020..5e6823b462 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -104,6 +104,10 @@ class NetworkSession{ $this->server->addPlayer($this->player); } + public function getPlayer() : ?Player{ + return $this->player; + } + public function isConnected() : bool{ return $this->connected; } From 653fa1213e504aab847d2c5ed9e964b4143f0a00 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 Sep 2018 11:23:48 +0100 Subject: [PATCH 0131/3224] Added an event for handling duplicate logins (#2430) --- src/pocketmine/Player.php | 9 ++- .../player/PlayerDuplicateLoginEvent.php | 71 +++++++++++++++++++ 2 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 src/pocketmine/event/player/PlayerDuplicateLoginEvent.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 25abc7afc9..8ec5bc25c4 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -58,6 +58,7 @@ use pocketmine\event\player\PlayerJoinEvent; use pocketmine\event\player\PlayerJumpEvent; use pocketmine\event\player\PlayerKickEvent; use pocketmine\event\player\PlayerLoginEvent; +use pocketmine\event\player\PlayerDuplicateLoginEvent; use pocketmine\event\player\PlayerMoveEvent; use pocketmine\event\player\PlayerPreLoginEvent; use pocketmine\event\player\PlayerQuitEvent; @@ -1787,11 +1788,13 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ foreach($this->server->getLoggedInPlayers() as $p){ if($p !== $this and ($p->iusername === $this->iusername or $this->getUniqueId()->equals($p->getUniqueId()))){ - if(!$p->kick("logged in from another location")){ - $this->close($this->getLeaveMessage(), "Logged in from another location"); - + $this->server->getPluginManager()->callEvent($ev = new PlayerDuplicateLoginEvent($this->networkSession, $p->networkSession)); + if($ev->isCancelled()){ + $this->networkSession->disconnect($ev->getDisconnectMessage()); return false; } + + $p->networkSession->disconnect($ev->getDisconnectMessage()); } } diff --git a/src/pocketmine/event/player/PlayerDuplicateLoginEvent.php b/src/pocketmine/event/player/PlayerDuplicateLoginEvent.php new file mode 100644 index 0000000000..9ef7accf48 --- /dev/null +++ b/src/pocketmine/event/player/PlayerDuplicateLoginEvent.php @@ -0,0 +1,71 @@ +connectingSession = $connectingSession; + $this->existingSession = $existingSession; + } + + public function getConnectingSession() : NetworkSession{ + return $this->connectingSession; + } + + public function getExistingSession() : NetworkSession{ + return $this->existingSession; + } + + /** + * Returns the message shown to the session which gets disconnected. + * + * @return string + */ + public function getDisconnectMessage() : string{ + return $this->disconnectMessage; + } + + /** + * @param string $message + */ + public function setDisconnectMessage(string $message) : void{ + $this->disconnectMessage = $message; + } +} From e0574008b4223a9d4bf505f6dc8cedbda42f06b4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 Sep 2018 18:08:12 +0100 Subject: [PATCH 0132/3224] AsyncPool: Move removeTasks() functionality inside shutdown() there's no need for a loop if we just have the workers shutdown directly, because they'll block until all tasks are done anyway. --- src/pocketmine/scheduler/AsyncPool.php | 55 +++++++++----------------- 1 file changed, 19 insertions(+), 36 deletions(-) diff --git a/src/pocketmine/scheduler/AsyncPool.php b/src/pocketmine/scheduler/AsyncPool.php index e720e7e85f..5f06c9f646 100644 --- a/src/pocketmine/scheduler/AsyncPool.php +++ b/src/pocketmine/scheduler/AsyncPool.php @@ -232,41 +232,6 @@ class AsyncPool{ unset($this->taskWorkers[$task->getTaskId()]); } - /** - * Removes all tasks from the pool, cancelling where possible. This will block until all tasks have been - * successfully deleted. - */ - public function removeTasks() : void{ - foreach($this->workers as $worker){ - /** @var AsyncTask $task */ - while(($task = $worker->unstack()) !== null){ - //cancelRun() is not strictly necessary here, but it might be used to inform plugins of the task state - //(i.e. it never executed). - $task->cancelRun(); - $this->removeTask($task, true); - } - } - do{ - foreach($this->tasks as $task){ - $task->cancelRun(); - $this->removeTask($task); - } - - if(count($this->tasks) > 0){ - usleep(25000); - } - }while(count($this->tasks) > 0); - - for($i = 0; $i < $this->size; ++$i){ - $this->workerUsage[$i] = 0; - } - - $this->taskWorkers = []; - $this->tasks = []; - - $this->collectWorkers(); - } - /** * Collects garbage from running workers. */ @@ -329,10 +294,28 @@ class AsyncPool{ */ public function shutdown() : void{ $this->collectTasks(); - $this->removeTasks(); + + foreach($this->workers as $worker){ + /** @var AsyncTask $task */ + while(($task = $worker->unstack()) !== null){ + //cancelRun() is not strictly necessary here, but it might be used to inform plugins of the task state + //(i.e. it never executed). + $task->cancelRun(); + $this->removeTask($task, true); + } + } + foreach($this->tasks as $task){ + $task->cancelRun(); + $this->removeTask($task, true); + } + + $this->taskWorkers = []; + $this->tasks = []; + foreach($this->workers as $worker){ $worker->quit(); } $this->workers = []; + $this->workerUsage = []; } } From 778eb5fb33f1826b05b3d1228aaa6c56530b24fb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 Sep 2018 19:40:19 +0100 Subject: [PATCH 0133/3224] Block: Make getId(), getDamage(), setDamage() non-final In the future, these methods will be used to derive ID/meta on the fly from properties instead of using them internally. --- src/pocketmine/block/Block.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 777c9311a6..023c92dd8c 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -96,7 +96,7 @@ class Block extends Position implements BlockIds, Metadatable{ /** * @return int */ - final public function getId() : int{ + public function getId() : int{ return $this->id; } @@ -113,14 +113,14 @@ class Block extends Position implements BlockIds, Metadatable{ /** * @return int */ - final public function getDamage() : int{ + public function getDamage() : int{ return $this->meta; } /** * @param int $meta */ - final public function setDamage(int $meta) : void{ + public function setDamage(int $meta) : void{ if($meta < 0 or $meta > 0xf){ throw new \InvalidArgumentException("Block damage values must be 0-15, not $meta"); } From 54342ab0ce0b5cd9c72a521cdb6c031b4d7a39c8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 Sep 2018 19:56:17 +0100 Subject: [PATCH 0134/3224] Remove ridiculous code in Ladder --- src/pocketmine/block/Ladder.php | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/pocketmine/block/Ladder.php b/src/pocketmine/block/Ladder.php index 49729cac2a..f1b73cf803 100644 --- a/src/pocketmine/block/Ladder.php +++ b/src/pocketmine/block/Ladder.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\entity\Entity; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -90,19 +91,11 @@ class Ladder extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if(!$blockClicked->isTransparent()){ - $faces = [ - 2 => 2, - 3 => 3, - 4 => 4, - 5 => 5 - ]; - if(isset($faces[$face])){ - $this->meta = $faces[$face]; - $this->getLevel()->setBlock($blockReplace, $this, true, true); + if(!$blockClicked->isTransparent() and Facing::axis($face) !== Facing::AXIS_Y){ + $this->meta = $face; + $this->getLevel()->setBlock($blockReplace, $this, true, true); - return true; - } + return true; } return false; From c0962a47be1e65155ae7ac9a3f351f33914a232c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 Sep 2018 20:07:39 +0100 Subject: [PATCH 0135/3224] Block: Use parent::place() instead of setBlock() directly --- src/pocketmine/block/Anvil.php | 2 +- src/pocketmine/block/BaseRail.php | 2 +- src/pocketmine/block/Bed.php | 8 ++++---- src/pocketmine/block/Block.php | 2 +- src/pocketmine/block/BoneBlock.php | 2 +- src/pocketmine/block/BurningFurnace.php | 9 +++++---- src/pocketmine/block/Button.php | 3 +-- src/pocketmine/block/Cactus.php | 4 +--- src/pocketmine/block/Cake.php | 4 +--- src/pocketmine/block/Carpet.php | 4 +--- src/pocketmine/block/Chest.php | 15 +++++++++------ src/pocketmine/block/Crops.php | 4 +--- src/pocketmine/block/Dandelion.php | 4 +--- src/pocketmine/block/Door.php | 2 +- src/pocketmine/block/EnchantingTable.php | 9 +++++---- src/pocketmine/block/EndRod.php | 2 +- src/pocketmine/block/EnderChest.php | 8 +++++--- src/pocketmine/block/FenceGate.php | 3 +-- src/pocketmine/block/Flower.php | 4 +--- src/pocketmine/block/FlowerPot.php | 9 ++++++--- src/pocketmine/block/GlazedTerracotta.php | 3 ++- src/pocketmine/block/HayBale.php | 4 +--- src/pocketmine/block/ItemFrame.php | 8 +++++--- src/pocketmine/block/Ladder.php | 4 +--- src/pocketmine/block/Lava.php | 10 ---------- src/pocketmine/block/Leaves.php | 2 +- src/pocketmine/block/Lever.php | 2 +- src/pocketmine/block/NetherWartPlant.php | 4 +--- src/pocketmine/block/Quartz.php | 2 +- src/pocketmine/block/RedMushroom.php | 4 +--- src/pocketmine/block/Sapling.php | 4 +--- src/pocketmine/block/SignPost.php | 11 ++++++----- src/pocketmine/block/Skull.php | 8 +++++--- src/pocketmine/block/Slab.php | 3 +-- src/pocketmine/block/SnowLayer.php | 4 +--- src/pocketmine/block/Stair.php | 3 +-- src/pocketmine/block/StandingBanner.php | 10 ++++++---- src/pocketmine/block/Sugarcane.php | 8 ++------ src/pocketmine/block/TallGrass.php | 4 +--- src/pocketmine/block/Torch.php | 7 ++----- src/pocketmine/block/Trapdoor.php | 4 ++-- src/pocketmine/block/Vine.php | 3 +-- src/pocketmine/block/Water.php | 10 ---------- src/pocketmine/block/WaterLily.php | 3 +-- src/pocketmine/block/Wood.php | 2 +- 45 files changed, 93 insertions(+), 134 deletions(-) diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index 7279fc8c3c..fb9019f96a 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -97,6 +97,6 @@ class Anvil extends Fallable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $direction = $player !== null ? Bearing::rotate($player->getDirection(), -1) : 0; $this->meta = $this->getVariant() | $direction; - return $this->getLevel()->setBlock($blockReplace, $this, true, true); + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } } diff --git a/src/pocketmine/block/BaseRail.php b/src/pocketmine/block/BaseRail.php index 69f555d3c6..bfcdf32ca5 100644 --- a/src/pocketmine/block/BaseRail.php +++ b/src/pocketmine/block/BaseRail.php @@ -85,7 +85,7 @@ abstract class BaseRail extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if(!$blockReplace->getSide(Facing::DOWN)->isTransparent() and $this->getLevel()->setBlock($blockReplace, $this, true, true)){ + if(!$blockReplace->getSide(Facing::DOWN)->isTransparent() and parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ $this->tryReconnect(); return true; } diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 229fbedad0..525734547c 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -152,11 +152,11 @@ class Bed extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if(!$down->isTransparent()){ - $meta = $player instanceof Player ? Bearing::rotate($player->getDirection(), 2) : 0; //rotate 180 degrees - $next = $this->getSide(self::getOtherHalfSide($meta)); + $this->meta = $player instanceof Player ? Bearing::rotate($player->getDirection(), 2) : 0; //rotate 180 degrees + $next = $this->getSide(self::getOtherHalfSide($this->meta)); if($next->canBeReplaced() and !$next->getSide(Facing::DOWN)->isTransparent()){ - $this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->id, $meta), true, true); - $this->getLevel()->setBlock($next, BlockFactory::get($this->id, $meta | self::BITFLAG_HEAD), true, true); + parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + $this->getLevel()->setBlock($next, BlockFactory::get($this->id, $this->meta | self::BITFLAG_HEAD), true, true); Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($this, $face, $item, $player)); Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($next, $face, $item, $player)); diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 023c92dd8c..07215efa7e 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -181,7 +181,7 @@ class Block extends Position implements BlockIds, Metadatable{ * @return bool */ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - return $this->getLevel()->setBlock($this, $this, true, true); + return $this->getLevel()->setBlock($blockReplace, $this, true, true); } /** diff --git a/src/pocketmine/block/BoneBlock.php b/src/pocketmine/block/BoneBlock.php index 696565faeb..7d9efaceb8 100644 --- a/src/pocketmine/block/BoneBlock.php +++ b/src/pocketmine/block/BoneBlock.php @@ -55,7 +55,7 @@ class BoneBlock extends Solid{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $this->meta = PillarRotationHelper::getMetaFromFace($this->meta, $face); - return $this->getLevel()->setBlock($blockReplace, $this, true, true); + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function getVariantBitmask() : int{ diff --git a/src/pocketmine/block/BurningFurnace.php b/src/pocketmine/block/BurningFurnace.php index 98d0c135dd..7440d0f28c 100644 --- a/src/pocketmine/block/BurningFurnace.php +++ b/src/pocketmine/block/BurningFurnace.php @@ -65,11 +65,12 @@ class BurningFurnace extends Solid{ if($player !== null){ $this->meta = Bearing::toFacing($player->getDirection()); } - $this->getLevel()->setBlock($blockReplace, $this, true, true); + if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ + Tile::createTile(Tile::FURNACE, $this->getLevel(), TileFurnace::createNBT($this, $face, $item, $player)); + return true; + } - Tile::createTile(Tile::FURNACE, $this->getLevel(), TileFurnace::createNBT($this, $face, $item, $player)); - - return true; + return false; } public function onActivate(Item $item, Player $player = null) : bool{ diff --git a/src/pocketmine/block/Button.php b/src/pocketmine/block/Button.php index 2745fdd586..d8b333e825 100644 --- a/src/pocketmine/block/Button.php +++ b/src/pocketmine/block/Button.php @@ -40,8 +40,7 @@ abstract class Button extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ //TODO: check valid target block $this->meta = $face; - - return $this->level->setBlock($this, $this, true, true); + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onActivate(Item $item, Player $player = null) : bool{ diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index 8964cd2485..a8fdd1c3b6 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -112,9 +112,7 @@ class Cactus extends Transparent{ $block2 = $this->getSide(Facing::WEST); $block3 = $this->getSide(Facing::EAST); if(!$block0->isSolid() and !$block1->isSolid() and !$block2->isSolid() and !$block3->isSolid()){ - $this->getLevel()->setBlock($this, $this, true); - - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } } diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index 83d2b61c12..dd31ec231f 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -64,9 +64,7 @@ class Cake extends Transparent implements FoodSource{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() !== self::AIR){ - $this->getLevel()->setBlock($blockReplace, $this, true, true); - - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Carpet.php b/src/pocketmine/block/Carpet.php index a3cbc8c550..a79dac0926 100644 --- a/src/pocketmine/block/Carpet.php +++ b/src/pocketmine/block/Carpet.php @@ -57,9 +57,7 @@ class Carpet extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() !== self::AIR){ - $this->getLevel()->setBlock($blockReplace, $this, true, true); - - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index 2e1f1e91b9..2ca3536ee2 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -77,15 +77,18 @@ class Chest extends Transparent{ } } - $this->getLevel()->setBlock($blockReplace, $this, true, true); - $tile = Tile::createTile(Tile::CHEST, $this->getLevel(), TileChest::createNBT($this, $face, $item, $player)); + if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ + $tile = Tile::createTile(Tile::CHEST, $this->getLevel(), TileChest::createNBT($this, $face, $item, $player)); - if($chest instanceof TileChest and $tile instanceof TileChest){ - $chest->pairWith($tile); - $tile->pairWith($chest); + if($chest instanceof TileChest and $tile instanceof TileChest){ + $chest->pairWith($tile); + $tile->pairWith($chest); + } + + return true; } - return true; + return false; } public function onActivate(Item $item, Player $player = null) : bool{ diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index 476c8d5ce2..f92f94add5 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -34,9 +34,7 @@ abstract class Crops extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($blockReplace->getSide(Facing::DOWN)->getId() === Block::FARMLAND){ - $this->getLevel()->setBlock($blockReplace, $this, true, true); - - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Dandelion.php b/src/pocketmine/block/Dandelion.php index 443ba08110..474054e723 100644 --- a/src/pocketmine/block/Dandelion.php +++ b/src/pocketmine/block/Dandelion.php @@ -44,9 +44,7 @@ class Dandelion extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === Block::GRASS or $down->getId() === Block::DIRT or $down->getId() === Block::FARMLAND){ - $this->getLevel()->setBlock($blockReplace, $this, true, true); - - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index c95947725a..e5acf3708f 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -138,7 +138,7 @@ abstract class Door extends Transparent{ } $this->setDamage(Bearing::rotate($player->getDirection(), -1)); - $this->getLevel()->setBlock($blockReplace, $this, true, true); //Bottom + parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); $this->getLevel()->setBlock($blockUp, BlockFactory::get($this->getId(), $metaUp), true); //Top return true; } diff --git a/src/pocketmine/block/EnchantingTable.php b/src/pocketmine/block/EnchantingTable.php index 5574677c48..f86616beef 100644 --- a/src/pocketmine/block/EnchantingTable.php +++ b/src/pocketmine/block/EnchantingTable.php @@ -40,11 +40,12 @@ class EnchantingTable extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $this->getLevel()->setBlock($blockReplace, $this, true, true); + if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ + Tile::createTile(Tile::ENCHANT_TABLE, $this->getLevel(), TileEnchantTable::createNBT($this, $face, $item, $player)); + return true; + } - Tile::createTile(Tile::ENCHANT_TABLE, $this->getLevel(), TileEnchantTable::createNBT($this, $face, $item, $player)); - - return true; + return false; } public function getHardness() : float{ diff --git a/src/pocketmine/block/EndRod.php b/src/pocketmine/block/EndRod.php index e652707403..9aa1576700 100644 --- a/src/pocketmine/block/EndRod.php +++ b/src/pocketmine/block/EndRod.php @@ -51,7 +51,7 @@ class EndRod extends Flowable{ $this->meta ^= 0x01; } - return $this->level->setBlock($blockReplace, $this, true, true); + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function isSolid() : bool{ diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index 015f909480..c619a3fefb 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -66,10 +66,12 @@ class EnderChest extends Chest{ $this->meta = Bearing::toFacing($player->getDirection()); } - $this->getLevel()->setBlock($blockReplace, $this, true, true); - Tile::createTile(Tile::ENDER_CHEST, $this->getLevel(), TileEnderChest::createNBT($this, $face, $item, $player)); + if(Block::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ + Tile::createTile(Tile::ENDER_CHEST, $this->getLevel(), TileEnderChest::createNBT($this, $face, $item, $player)); + return true; + } - return true; + return false; } public function onActivate(Item $item, Player $player = null) : bool{ diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index 1aacbbf846..5a1942f8df 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -72,9 +72,8 @@ class FenceGate extends Transparent{ if($player !== null){ $this->meta = Bearing::rotate($player->getDirection(), 2); } - $this->getLevel()->setBlock($blockReplace, $this, true, true); - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function getVariantBitmask() : int{ diff --git a/src/pocketmine/block/Flower.php b/src/pocketmine/block/Flower.php index ac7a063a8d..d19bfa3a2a 100644 --- a/src/pocketmine/block/Flower.php +++ b/src/pocketmine/block/Flower.php @@ -63,9 +63,7 @@ class Flower extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === Block::GRASS or $down->getId() === Block::DIRT or $down->getId() === Block::FARMLAND){ - $this->getLevel()->setBlock($blockReplace, $this, true); - - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 8dd7f9db2f..8e50621cd0 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -57,9 +57,12 @@ class FlowerPot extends Flowable{ return false; } - $this->getLevel()->setBlock($blockReplace, $this, true, true); - Tile::createTile(Tile::FLOWER_POT, $this->getLevel(), TileFlowerPot::createNBT($this, $face, $item, $player)); - return true; + if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ + Tile::createTile(Tile::FLOWER_POT, $this->getLevel(), TileFlowerPot::createNBT($this, $face, $item, $player)); + return true; + } + + return false; } public function onNearbyBlockChange() : void{ diff --git a/src/pocketmine/block/GlazedTerracotta.php b/src/pocketmine/block/GlazedTerracotta.php index d4c3e30639..d8276666bd 100644 --- a/src/pocketmine/block/GlazedTerracotta.php +++ b/src/pocketmine/block/GlazedTerracotta.php @@ -48,7 +48,8 @@ class GlazedTerracotta extends Solid{ if($player !== null){ $this->meta = Bearing::toFacing($player->getDirection()); } - return $this->getLevel()->setBlock($blockReplace, $this, true, true); + + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function getVariantBitmask() : int{ diff --git a/src/pocketmine/block/HayBale.php b/src/pocketmine/block/HayBale.php index 7dd2989dab..112f9f788c 100644 --- a/src/pocketmine/block/HayBale.php +++ b/src/pocketmine/block/HayBale.php @@ -46,9 +46,7 @@ class HayBale extends Solid{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $this->meta = PillarRotationHelper::getMetaFromFace($this->meta, $face); - $this->getLevel()->setBlock($blockReplace, $this, true, true); - - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function getVariantBitmask() : int{ diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index e01fcc9385..f744d05f33 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -83,11 +83,13 @@ class ItemFrame extends Flowable{ ]; $this->meta = $faces[$face]; - $this->level->setBlock($blockReplace, $this, true, true); - Tile::createTile(Tile::ITEM_FRAME, $this->getLevel(), TileItemFrame::createNBT($this, $face, $item, $player)); + if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ + Tile::createTile(Tile::ITEM_FRAME, $this->getLevel(), TileItemFrame::createNBT($this, $face, $item, $player)); + return true; + } - return true; + return false; } diff --git a/src/pocketmine/block/Ladder.php b/src/pocketmine/block/Ladder.php index f1b73cf803..0fcbe82175 100644 --- a/src/pocketmine/block/Ladder.php +++ b/src/pocketmine/block/Ladder.php @@ -93,9 +93,7 @@ class Ladder extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if(!$blockClicked->isTransparent() and Facing::axis($face) !== Facing::AXIS_Y){ $this->meta = $face; - $this->getLevel()->setBlock($blockReplace, $this, true, true); - - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Lava.php b/src/pocketmine/block/Lava.php index 057ad42f47..04ab07fae8 100644 --- a/src/pocketmine/block/Lava.php +++ b/src/pocketmine/block/Lava.php @@ -27,10 +27,7 @@ use pocketmine\entity\Entity; use pocketmine\event\entity\EntityCombustByBlockEvent; use pocketmine\event\entity\EntityDamageByBlockEvent; use pocketmine\event\entity\EntityDamageEvent; -use pocketmine\item\Item; -use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; -use pocketmine\Player; use pocketmine\Server; class Lava extends Liquid{ @@ -114,11 +111,4 @@ class Lava extends Liquid{ $entity->resetFallDistance(); } - - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $ret = $this->getLevel()->setBlock($this, $this, true, false); - $this->getLevel()->scheduleDelayedBlockUpdate($this, $this->tickRate()); - - return $ret; - } } diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 212354682e..7eea230521 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -160,7 +160,7 @@ class Leaves extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $this->meta |= 0x04; - return $this->getLevel()->setBlock($this, $this, true); + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function getVariantBitmask() : int{ diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index 7b622af4a7..a57fc1c665 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -73,7 +73,7 @@ class Lever extends Flowable{ } } - return $this->level->setBlock($blockReplace, $this, true, true); + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onNearbyBlockChange() : void{ diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index 9071ca29e3..5c5e256949 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -47,9 +47,7 @@ class NetherWartPlant extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === Block::SOUL_SAND){ - $this->getLevel()->setBlock($blockReplace, $this, false, true); - - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Quartz.php b/src/pocketmine/block/Quartz.php index e0813022c9..dbda5ca3c5 100644 --- a/src/pocketmine/block/Quartz.php +++ b/src/pocketmine/block/Quartz.php @@ -58,7 +58,7 @@ class Quartz extends Solid{ if($this->meta !== self::NORMAL){ $this->meta = PillarRotationHelper::getMetaFromFace($this->meta, $face); } - return $this->getLevel()->setBlock($blockReplace, $this, true, true); + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function getToolType() : int{ diff --git a/src/pocketmine/block/RedMushroom.php b/src/pocketmine/block/RedMushroom.php index d5f25a60b0..6a4b9118fe 100644 --- a/src/pocketmine/block/RedMushroom.php +++ b/src/pocketmine/block/RedMushroom.php @@ -53,9 +53,7 @@ class RedMushroom extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if(!$down->isTransparent()){ - $this->getLevel()->setBlock($blockReplace, $this, true, true); - - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index 5d6d51c0fa..1573f63219 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -59,9 +59,7 @@ class Sapling extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === self::GRASS or $down->getId() === self::DIRT or $down->getId() === self::FARMLAND){ - $this->getLevel()->setBlock($blockReplace, $this, true, true); - - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/SignPost.php b/src/pocketmine/block/SignPost.php index c1b820f667..948c77ed12 100644 --- a/src/pocketmine/block/SignPost.php +++ b/src/pocketmine/block/SignPost.php @@ -63,15 +63,16 @@ class SignPost extends Transparent{ if($face === Facing::UP){ $this->meta = $player !== null ? (floor((($player->yaw + 180) * 16 / 360) + 0.5) & 0x0f) : 0; - $this->getLevel()->setBlock($blockReplace, $this, true); + $ret = parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); }else{ $this->meta = $face; - $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::WALL_SIGN, $this->meta), true); + $ret = $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::WALL_SIGN, $this->meta), true); } - Tile::createTile(Tile::SIGN, $this->getLevel(), TileSign::createNBT($this, $face, $item, $player)); - - return true; + if($ret){ + Tile::createTile(Tile::SIGN, $this->getLevel(), TileSign::createNBT($this, $face, $item, $player)); + return true; + } } return false; diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index 34c6077d75..fe7c63a1cb 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -60,10 +60,12 @@ class Skull extends Flowable{ } $this->meta = $face; - $this->getLevel()->setBlock($blockReplace, $this, true); - Tile::createTile(Tile::SKULL, $this->getLevel(), TileSkull::createNBT($this, $face, $item, $player)); + if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ + Tile::createTile(Tile::SKULL, $this->getLevel(), TileSkull::createNBT($this, $face, $item, $player)); + return true; + } - return true; + return false; } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index 66bb2940fb..96fec3e314 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -96,9 +96,8 @@ abstract class Slab extends Transparent{ if($blockReplace->getId() === $this->id and $blockClicked->getVariant() !== $this->getVariant()){ return false; } - $this->getLevel()->setBlock($blockReplace, $this, true, true); - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function getVariantBitmask() : int{ diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index b7c730b9df..9c4106f31c 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -61,9 +61,7 @@ class SnowLayer extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($blockReplace->getSide(Facing::DOWN)->isSolid()){ //TODO: fix placement - $this->getLevel()->setBlock($blockReplace, $this, true); - - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index a7a7a425a4..db0bcdaa41 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -83,9 +83,8 @@ abstract class Stair extends Transparent{ if(($clickVector->y > 0.5 and $face !== Facing::UP) or $face === Facing::DOWN){ $this->meta |= 0x04; //Upside-down stairs } - $this->getLevel()->setBlock($blockReplace, $this, true, true); - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function getVariantBitmask() : int{ diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index 352bbd1700..9d6675914b 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -62,14 +62,16 @@ class StandingBanner extends Transparent{ if($face !== Facing::DOWN){ if($face === Facing::UP and $player !== null){ $this->meta = floor((($player->yaw + 180) * 16 / 360) + 0.5) & 0x0f; - $this->getLevel()->setBlock($blockReplace, $this, true); + $ret = parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); }else{ $this->meta = $face; - $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::WALL_BANNER, $this->meta), true); + $ret = $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::WALL_BANNER, $this->meta), true); } - Tile::createTile(Tile::BANNER, $this->getLevel(), TileBanner::createNBT($this, $face, $item, $player)); - return true; + if($ret){ + Tile::createTile(Tile::BANNER, $this->getLevel(), TileBanner::createNBT($this, $face, $item, $player)); + return true; + } } return false; diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index f2ddab7213..69eda68143 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -102,18 +102,14 @@ class Sugarcane extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === self::SUGARCANE_BLOCK){ - $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::SUGARCANE_BLOCK), true); - - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); }elseif($down->getId() === self::GRASS or $down->getId() === self::DIRT or $down->getId() === self::SAND){ $block0 = $down->getSide(Facing::NORTH); $block1 = $down->getSide(Facing::SOUTH); $block2 = $down->getSide(Facing::WEST); $block3 = $down->getSide(Facing::EAST); if(($block0 instanceof Water) or ($block1 instanceof Water) or ($block2 instanceof Water) or ($block3 instanceof Water)){ - $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::SUGARCANE_BLOCK), true); - - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } } diff --git a/src/pocketmine/block/TallGrass.php b/src/pocketmine/block/TallGrass.php index 310398f539..5d15a10e87 100644 --- a/src/pocketmine/block/TallGrass.php +++ b/src/pocketmine/block/TallGrass.php @@ -53,9 +53,7 @@ class TallGrass extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === self::GRASS){ - $this->getLevel()->setBlock($blockReplace, $this, true); - - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index b553bfd8c3..98473c92d3 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -73,14 +73,11 @@ class Torch extends Flowable{ Facing::EAST => 1 ]; $this->meta = $faces[$face]; - $this->getLevel()->setBlock($blockReplace, $this, true, true); - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); }elseif(!$below->isTransparent() or $below->getId() === self::FENCE or $below->getId() === self::COBBLESTONE_WALL){ $this->meta = 0; - $this->getLevel()->setBlock($blockReplace, $this, true, true); - - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index 1d01dcd027..437ca730e6 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -95,8 +95,8 @@ class Trapdoor extends Transparent{ if(($clickVector->y > 0.5 and $face !== Facing::UP) or $face === Facing::DOWN){ $this->meta |= self::MASK_UPPER; //top half of block } - $this->getLevel()->setBlock($blockReplace, $this, true, true); - return true; + + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function getVariantBitmask() : int{ diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index 72bc36fc59..b4adf98c65 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -141,8 +141,7 @@ class Vine extends Flowable{ $this->meta |= $blockReplace->meta; } - $this->getLevel()->setBlock($blockReplace, $this, true, true); - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onNearbyBlockChange() : void{ diff --git a/src/pocketmine/block/Water.php b/src/pocketmine/block/Water.php index 00eeb3a9d8..a4c96bdab1 100644 --- a/src/pocketmine/block/Water.php +++ b/src/pocketmine/block/Water.php @@ -24,10 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\entity\Entity; -use pocketmine\item\Item; -use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; -use pocketmine\Player; class Water extends Liquid{ @@ -73,11 +70,4 @@ class Water extends Liquid{ $entity->resetFallDistance(); } - - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $ret = $this->getLevel()->setBlock($this, $this, true, false); - $this->getLevel()->scheduleDelayedBlockUpdate($this, $this->tickRate()); - - return $ret; - } } diff --git a/src/pocketmine/block/WaterLily.php b/src/pocketmine/block/WaterLily.php index 59f999960f..4260a8a3e4 100644 --- a/src/pocketmine/block/WaterLily.php +++ b/src/pocketmine/block/WaterLily.php @@ -54,8 +54,7 @@ class WaterLily extends Flowable{ if($blockClicked instanceof Water){ $up = $blockClicked->getSide(Facing::UP); if($up->getId() === Block::AIR){ - $this->getLevel()->setBlock($up, $this, true, true); - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } } diff --git a/src/pocketmine/block/Wood.php b/src/pocketmine/block/Wood.php index 2c309aed6f..f50cdea3e1 100644 --- a/src/pocketmine/block/Wood.php +++ b/src/pocketmine/block/Wood.php @@ -56,7 +56,7 @@ class Wood extends Solid{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $this->meta = PillarRotationHelper::getMetaFromFace($this->meta, $face); - return $this->getLevel()->setBlock($blockReplace, $this, true, true); + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function getVariantBitmask() : int{ From fee42e9f34d4007721048d0d270500e68c9e7568 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Sep 2018 16:36:10 +0100 Subject: [PATCH 0136/3224] Leaves: Replace a big mess of code with something nice and simple (#2432) --- src/pocketmine/block/Leaves.php | 53 ++++++--------------------------- 1 file changed, 9 insertions(+), 44 deletions(-) diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 7eea230521..b7c1fa9e86 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -81,50 +81,15 @@ class Leaves extends Transparent{ if($down === $this->woodType){ return true; } - if($fromSide === null){ - for($side = 2; $side <= 5; ++$side){ - if($this->findLog($pos->getSide($side), $visited, $distance + 1, $side)){ - return true; - } - } - }else{ //No more loops - switch($fromSide){ - case 2: - if($this->findLog($pos->getSide(Facing::NORTH), $visited, $distance + 1, $fromSide)){ - return true; - }elseif($this->findLog($pos->getSide(Facing::WEST), $visited, $distance + 1, $fromSide)){ - return true; - }elseif($this->findLog($pos->getSide(Facing::EAST), $visited, $distance + 1, $fromSide)){ - return true; - } - break; - case 3: - if($this->findLog($pos->getSide(Facing::SOUTH), $visited, $distance + 1, $fromSide)){ - return true; - }elseif($this->findLog($pos->getSide(Facing::WEST), $visited, $distance + 1, $fromSide)){ - return true; - }elseif($this->findLog($pos->getSide(Facing::EAST), $visited, $distance + 1, $fromSide)){ - return true; - } - break; - case 4: - if($this->findLog($pos->getSide(Facing::NORTH), $visited, $distance + 1, $fromSide)){ - return true; - }elseif($this->findLog($pos->getSide(Facing::SOUTH), $visited, $distance + 1, $fromSide)){ - return true; - }elseif($this->findLog($pos->getSide(Facing::WEST), $visited, $distance + 1, $fromSide)){ - return true; - } - break; - case 5: - if($this->findLog($pos->getSide(Facing::NORTH), $visited, $distance + 1, $fromSide)){ - return true; - }elseif($this->findLog($pos->getSide(Facing::SOUTH), $visited, $distance + 1, $fromSide)){ - return true; - }elseif($this->findLog($pos->getSide(Facing::EAST), $visited, $distance + 1, $fromSide)){ - return true; - } - break; + + foreach([ + Facing::NORTH, + Facing::SOUTH, + Facing::WEST, + Facing::EAST + ] as $side){ + if($side !== $fromSide and $this->findLog($pos->getSide($side), $visited, $distance + 1, Facing::opposite($side))){ + return true; } } } From 3b772f54e94fcfd5db6be4852caaef87af49a723 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Sep 2018 16:49:22 +0100 Subject: [PATCH 0137/3224] Leaves: make more findLog() params optional --- src/pocketmine/block/Leaves.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index b7c1fa9e86..aadc9b7ab6 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -68,7 +68,7 @@ class Leaves extends Transparent{ } - protected function findLog(Block $pos, array $visited, int $distance, ?int $fromSide = null) : bool{ + protected function findLog(Block $pos, array $visited = [], int $distance = 0, ?int $fromSide = null) : bool{ $index = $pos->x . "." . $pos->y . "." . $pos->z; if(isset($visited[$index])){ return false; @@ -111,11 +111,10 @@ class Leaves extends Transparent{ public function onRandomTick() : void{ if(($this->meta & 0b00001100) === 0x08){ $this->meta &= 0x03; - $visited = []; $this->getLevel()->getServer()->getPluginManager()->callEvent($ev = new LeavesDecayEvent($this)); - if($ev->isCancelled() or $this->findLog($this, $visited, 0)){ + if($ev->isCancelled() or $this->findLog($this)){ $this->getLevel()->setBlock($this, $this, false, false); }else{ $this->getLevel()->useBreakOn($this); From 0406c49ba99dd93a619bb76e09d7a29d5a9aaad2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Sep 2018 17:30:02 +0100 Subject: [PATCH 0138/3224] Leaves: improve log search algorithm to fix vanilla inconsistencies --- src/pocketmine/block/Leaves.php | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index aadc9b7ab6..9257ca84c0 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\event\block\LeavesDecayEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\level\Level; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -68,27 +69,20 @@ class Leaves extends Transparent{ } - protected function findLog(Block $pos, array $visited = [], int $distance = 0, ?int $fromSide = null) : bool{ - $index = $pos->x . "." . $pos->y . "." . $pos->z; + protected function findLog(Block $pos, array &$visited = [], int $distance = 0) : bool{ + $index = Level::blockHash($pos->x, $pos->y, $pos->z); if(isset($visited[$index])){ return false; } + $visited[$index] = true; + if($pos->getId() === $this->woodType){ return true; - }elseif($pos->getId() === $this->id and $distance < 3){ - $visited[$index] = true; - $down = $pos->getSide(Facing::DOWN)->getId(); - if($down === $this->woodType){ - return true; - } + } - foreach([ - Facing::NORTH, - Facing::SOUTH, - Facing::WEST, - Facing::EAST - ] as $side){ - if($side !== $fromSide and $this->findLog($pos->getSide($side), $visited, $distance + 1, Facing::opposite($side))){ + if($pos->getId() === $this->id and $distance <= 4){ + foreach(Facing::ALL as $side){ + if($this->findLog($pos->getSide($side), $visited, $distance + 1)){ return true; } } From 65684eec9914eab39a4e46a2ce7045d3834b42f9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Sep 2018 18:36:50 +0100 Subject: [PATCH 0139/3224] Door: fixed bad rotation when no player is specified --- src/pocketmine/block/Door.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index e5acf3708f..be43b8ae40 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -127,7 +127,7 @@ abstract class Door extends Transparent{ return false; } - $ccw = Bearing::toFacing($player instanceof Player ? Bearing::rotate($player->getDirection(), -1) : Facing::EAST); + $ccw = Bearing::toFacing($player instanceof Player ? Bearing::rotate($player->getDirection(), -1) : Bearing::EAST); $next = $this->getSide(Facing::opposite($ccw)); $next2 = $this->getSide($ccw); From f488e594f6bf7ef7cadf8452bebd33232e21b585 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Sep 2018 19:34:27 +0100 Subject: [PATCH 0140/3224] Remove hardcoded facing literals in for loops --- composer.lock | 13 +++++++++---- src/pocketmine/block/Cactus.php | 14 +++++++------- src/pocketmine/block/ConcretePowder.php | 6 +++++- src/pocketmine/block/Fire.php | 4 ++-- src/pocketmine/block/Lava.php | 6 +++++- src/pocketmine/block/MelonStem.php | 4 ++-- src/pocketmine/block/PumpkinStem.php | 4 ++-- src/pocketmine/level/Explosion.php | 3 ++- src/pocketmine/level/Level.php | 5 +++-- 9 files changed, 37 insertions(+), 22 deletions(-) diff --git a/composer.lock b/composer.lock index 6b30e4c312..1ea1b675c6 100644 --- a/composer.lock +++ b/composer.lock @@ -187,12 +187,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "ec66eaa959b86ec3d3d22084a534ae466910aabe" + "reference": "6511fb0dcfeb60705d4169cc0422258b325af5c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/ec66eaa959b86ec3d3d22084a534ae466910aabe", - "reference": "ec66eaa959b86ec3d3d22084a534ae466910aabe", + "url": "https://api.github.com/repos/pmmp/Math/zipball/6511fb0dcfeb60705d4169cc0422258b325af5c6", + "reference": "6511fb0dcfeb60705d4169cc0422258b325af5c6", "shasum": "" }, "require": { @@ -205,6 +205,11 @@ "pocketmine\\math\\": "src/" } }, + "autoload-dev": { + "psr-4": { + "pocketmine\\math\\": "tests/phpunit/" + } + }, "license": [ "LGPL-3.0" ], @@ -213,7 +218,7 @@ "source": "https://github.com/pmmp/Math/tree/master", "issues": "https://github.com/pmmp/Math/issues" }, - "time": "2018-09-05T18:50:26+00:00" + "time": "2018-09-13T18:32:31+00:00" }, { "name": "pocketmine/nbt", diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index a8fdd1c3b6..19fbff9043 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -69,7 +69,7 @@ class Cactus extends Transparent{ if($down->getId() !== self::SAND and $down->getId() !== self::CACTUS){ $this->getLevel()->useBreakOn($this); }else{ - for($side = 2; $side <= 5; ++$side){ + foreach(Facing::HORIZONTAL as $side){ $b = $this->getSide($side); if($b->isSolid()){ $this->getLevel()->useBreakOn($this); @@ -107,13 +107,13 @@ class Cactus extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === self::SAND or $down->getId() === self::CACTUS){ - $block0 = $this->getSide(Facing::NORTH); - $block1 = $this->getSide(Facing::SOUTH); - $block2 = $this->getSide(Facing::WEST); - $block3 = $this->getSide(Facing::EAST); - if(!$block0->isSolid() and !$block1->isSolid() and !$block2->isSolid() and !$block3->isSolid()){ - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + foreach(Facing::HORIZONTAL as $side){ + if($this->getSide($side)->isSolid()){ + return false; + } } + + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/ConcretePowder.php b/src/pocketmine/block/ConcretePowder.php index 2ce84145d5..71df537872 100644 --- a/src/pocketmine/block/ConcretePowder.php +++ b/src/pocketmine/block/ConcretePowder.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\ColorBlockMetaHelper; +use pocketmine\math\Facing; class ConcretePowder extends Fallable{ @@ -64,7 +65,10 @@ class ConcretePowder extends Fallable{ * @return null|Block */ private function checkAdjacentWater() : ?Block{ - for($i = 1; $i < 6; ++$i){ //Do not check underneath + foreach(Facing::ALL as $i){ + if($i === Facing::DOWN){ + continue; + } if($this->getSide($i) instanceof Water){ return BlockFactory::get(Block::CONCRETE, $this->meta); } diff --git a/src/pocketmine/block/Fire.php b/src/pocketmine/block/Fire.php index 33e971fd39..b8ccc1cf70 100644 --- a/src/pocketmine/block/Fire.php +++ b/src/pocketmine/block/Fire.php @@ -142,8 +142,8 @@ class Fire extends Flowable{ } private function hasAdjacentFlammableBlocks() : bool{ - for($i = 0; $i <= 5; ++$i){ - if($this->getSide($i)->isFlammable()){ + foreach(Facing::ALL as $face){ + if($this->getSide($face)->isFlammable()){ return true; } } diff --git a/src/pocketmine/block/Lava.php b/src/pocketmine/block/Lava.php index 04ab07fae8..044bc1d9f6 100644 --- a/src/pocketmine/block/Lava.php +++ b/src/pocketmine/block/Lava.php @@ -27,6 +27,7 @@ use pocketmine\entity\Entity; use pocketmine\event\entity\EntityCombustByBlockEvent; use pocketmine\event\entity\EntityDamageByBlockEvent; use pocketmine\event\entity\EntityDamageEvent; +use pocketmine\math\Facing; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\Server; @@ -72,7 +73,10 @@ class Lava extends Liquid{ protected function checkForHarden(){ $colliding = null; - for($side = 1; $side <= 5; ++$side){ //don't check downwards side + foreach(Facing::ALL as $side){ + if($side === Facing::DOWN){ + continue; + } $blockSide = $this->getSide($side); if($blockSide instanceof Water){ $colliding = $blockSide; diff --git a/src/pocketmine/block/MelonStem.php b/src/pocketmine/block/MelonStem.php index 48e4f19ecb..0af36721dd 100644 --- a/src/pocketmine/block/MelonStem.php +++ b/src/pocketmine/block/MelonStem.php @@ -51,13 +51,13 @@ class MelonStem extends Crops{ $this->getLevel()->setBlock($this, $ev->getNewState(), true); } }else{ - for($side = 2; $side <= 5; ++$side){ + foreach(Facing::HORIZONTAL as $side){ $b = $this->getSide($side); if($b->getId() === self::MELON_BLOCK){ return; } } - $side = $this->getSide(mt_rand(2, 5)); + $side = $this->getSide(Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)]); $d = $side->getSide(Facing::DOWN); if($side->getId() === self::AIR and ($d->getId() === self::FARMLAND or $d->getId() === self::GRASS or $d->getId() === self::DIRT)){ Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($side, BlockFactory::get(Block::MELON_BLOCK))); diff --git a/src/pocketmine/block/PumpkinStem.php b/src/pocketmine/block/PumpkinStem.php index 7cc4da6422..de5b480ba8 100644 --- a/src/pocketmine/block/PumpkinStem.php +++ b/src/pocketmine/block/PumpkinStem.php @@ -51,13 +51,13 @@ class PumpkinStem extends Crops{ $this->getLevel()->setBlock($this, $ev->getNewState(), true); } }else{ - for($side = 2; $side <= 5; ++$side){ + foreach(Facing::HORIZONTAL as $side){ $b = $this->getSide($side); if($b->getId() === self::PUMPKIN){ return; } } - $side = $this->getSide(mt_rand(2, 5)); + $side = $this->getSide(Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)]); $d = $side->getSide(Facing::DOWN); if($side->getId() === self::AIR and ($d->getId() === self::FARMLAND or $d->getId() === self::GRASS or $d->getId() === self::DIRT)){ Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($side, BlockFactory::get(Block::PUMPKIN))); diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index cc45e20820..d56abb21d1 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -37,6 +37,7 @@ use pocketmine\item\ItemFactory; use pocketmine\level\particle\HugeExplodeSeedParticle; use pocketmine\level\utils\SubChunkIteratorManager; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\ExplodePacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; @@ -228,7 +229,7 @@ class Explosion{ $pos = new Vector3($block->x, $block->y, $block->z); - for($side = 0; $side <= 5; $side++){ + foreach(Facing::ALL as $side){ $sideBlock = $pos->getSide($side); if(!$this->level->isInWorld($sideBlock->x, $sideBlock->y, $sideBlock->z)){ continue; diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 4871adf69a..3e27ab4986 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -61,6 +61,7 @@ use pocketmine\level\particle\DestroyBlockParticle; use pocketmine\level\particle\Particle; use pocketmine\level\sound\Sound; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\Vector2; use pocketmine\math\Vector3; use pocketmine\metadata\BlockMetadataStore; @@ -1087,8 +1088,8 @@ class Level implements ChunkManager, Metadatable{ public function scheduleNeighbourBlockUpdates(Vector3 $pos){ $pos = $pos->floor(); - for($i = 0; $i <= 5; ++$i){ - $side = $pos->getSide($i); + foreach(Facing::ALL as $face){ + $side = $pos->getSide($face); if($this->isInWorld($side->x, $side->y, $side->z)){ $this->neighbourBlockUpdateQueue->enqueue(Level::blockHash($side->x, $side->y, $side->z)); } From 2b8405e6eeba6ad664937d9455f814aa824fbdaf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Sep 2018 19:35:47 +0100 Subject: [PATCH 0141/3224] Make use of Bearing::opposite() --- src/pocketmine/block/Bed.php | 2 +- src/pocketmine/block/FenceGate.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 525734547c..e802482ebe 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -152,7 +152,7 @@ class Bed extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if(!$down->isTransparent()){ - $this->meta = $player instanceof Player ? Bearing::rotate($player->getDirection(), 2) : 0; //rotate 180 degrees + $this->meta = $player instanceof Player ? Bearing::opposite($player->getDirection()) : 0; //rotate 180 degrees $next = $this->getSide(self::getOtherHalfSide($this->meta)); if($next->canBeReplaced() and !$next->getSide(Facing::DOWN)->isTransparent()){ parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index 5a1942f8df..69fda88143 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -70,7 +70,7 @@ class FenceGate extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ - $this->meta = Bearing::rotate($player->getDirection(), 2); + $this->meta = Bearing::opposite($player->getDirection()); } return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); @@ -84,7 +84,7 @@ class FenceGate extends Transparent{ $this->meta = (($this->meta ^ 0x04) & ~0x02); if($player !== null){ - $this->meta |= (Bearing::rotate($player->getDirection(), 2) & 0x02); //open towards the player, retaining axis + $this->meta |= (Bearing::opposite($player->getDirection()) & 0x02); //open towards the player, retaining axis } $this->getLevel()->setBlock($this, $this, true); From 8ad57f7ca08e5c9f0475409948864ca6b839e5c2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Sep 2018 19:36:03 +0100 Subject: [PATCH 0142/3224] Painting: use Facing::rotate() --- src/pocketmine/entity/object/Painting.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/entity/object/Painting.php b/src/pocketmine/entity/object/Painting.php index 7699db77ac..66602ab4fd 100644 --- a/src/pocketmine/entity/object/Painting.php +++ b/src/pocketmine/entity/object/Painting.php @@ -240,7 +240,7 @@ class Painting extends Entity{ $horizontalStart = (int) (ceil($width / 2) - 1); $verticalStart = (int) (ceil($height / 2) - 1); - $rotatedFace = Bearing::toFacing(Bearing::rotate(Bearing::fromFacing($facing), -1)); + $rotatedFace = Facing::rotate($facing, Facing::AXIS_Y, false); $oppositeSide = Facing::opposite($facing); From d4580fa683466717927fc3c1ea897e637f57c670 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Sep 2018 19:49:55 +0100 Subject: [PATCH 0143/3224] Cleanup Sugarcane placement code --- src/pocketmine/block/Sugarcane.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index 69eda68143..2a2e8266ef 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -104,12 +104,10 @@ class Sugarcane extends Flowable{ if($down->getId() === self::SUGARCANE_BLOCK){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); }elseif($down->getId() === self::GRASS or $down->getId() === self::DIRT or $down->getId() === self::SAND){ - $block0 = $down->getSide(Facing::NORTH); - $block1 = $down->getSide(Facing::SOUTH); - $block2 = $down->getSide(Facing::WEST); - $block3 = $down->getSide(Facing::EAST); - if(($block0 instanceof Water) or ($block1 instanceof Water) or ($block2 instanceof Water) or ($block3 instanceof Water)){ - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + foreach(Facing::HORIZONTAL as $side){ + if($down->getSide($side) instanceof Water){ + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } } } From db2567f96524baeb1d8955cd6de87d809f5967ac Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 14 Sep 2018 16:23:57 +0100 Subject: [PATCH 0144/3224] Separate use-item action from PlayerInteractEvent This solves the age-old issue of PlayerInteractEvent firing twice when a player clicks a block with an item in the hand. API changes: - Removed PlayerInteractEvent constants LEFT_CLICK_AIR, RIGHT_CLICK_AIR and PHYSICAL. - PlayerInteractEvent no longer fires when the player right-clicks the air. - Added new event PlayerItemUseEvent. --- src/pocketmine/Player.php | 3 +- .../event/player/PlayerInteractEvent.php | 3 - .../event/player/PlayerItemUseEvent.php | 69 +++++++++++++++++++ 3 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 src/pocketmine/event/player/PlayerItemUseEvent.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 910f122c0a..0eda7fac1d 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -54,6 +54,7 @@ use pocketmine\event\player\PlayerGameModeChangeEvent; use pocketmine\event\player\PlayerInteractEvent; use pocketmine\event\player\PlayerItemConsumeEvent; use pocketmine\event\player\PlayerItemHeldEvent; +use pocketmine\event\player\PlayerItemUseEvent; use pocketmine\event\player\PlayerJoinEvent; use pocketmine\event\player\PlayerJumpEvent; use pocketmine\event\player\PlayerKickEvent; @@ -2013,7 +2014,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $directionVector = $this->getDirectionVector(); $item = $this->inventory->getItemInHand(); - $ev = new PlayerInteractEvent($this, $item, null, $directionVector, 0, PlayerInteractEvent::RIGHT_CLICK_AIR); + $ev = new PlayerItemUseEvent($this, $item, $directionVector); if($this->hasItemCooldown($item)){ $ev->setCancelled(); } diff --git a/src/pocketmine/event/player/PlayerInteractEvent.php b/src/pocketmine/event/player/PlayerInteractEvent.php index 2c8890cc18..7ca0e59ac5 100644 --- a/src/pocketmine/event/player/PlayerInteractEvent.php +++ b/src/pocketmine/event/player/PlayerInteractEvent.php @@ -37,9 +37,6 @@ use pocketmine\Player; class PlayerInteractEvent extends PlayerEvent implements Cancellable{ public const LEFT_CLICK_BLOCK = 0; public const RIGHT_CLICK_BLOCK = 1; - public const LEFT_CLICK_AIR = 2; - public const RIGHT_CLICK_AIR = 3; - public const PHYSICAL = 4; /** @var Block */ protected $blockTouched; diff --git a/src/pocketmine/event/player/PlayerItemUseEvent.php b/src/pocketmine/event/player/PlayerItemUseEvent.php new file mode 100644 index 0000000000..743e78ca1d --- /dev/null +++ b/src/pocketmine/event/player/PlayerItemUseEvent.php @@ -0,0 +1,69 @@ +player = $player; + $this->item = $item; + $this->directionVector = $directionVector; + } + + /** + * Returns the item used. + * + * @return Item + */ + public function getItem() : Item{ + return $this->item; + } + + /** + * Returns the direction the player is aiming when activating this item. Used for projectile direction. + * + * @return Vector3 + */ + public function getDirectionVector() : Vector3{ + return $this->directionVector; + } +} From 0e5cbca9834908f980a2c42ea12329caa939b837 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 14 Sep 2018 16:30:22 +0100 Subject: [PATCH 0145/3224] PlayerInteractEvent: cleanup constructor now that block isn't optional anymore --- src/pocketmine/event/player/PlayerInteractEvent.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/event/player/PlayerInteractEvent.php b/src/pocketmine/event/player/PlayerInteractEvent.php index 7ca0e59ac5..04f7cd2294 100644 --- a/src/pocketmine/event/player/PlayerInteractEvent.php +++ b/src/pocketmine/event/player/PlayerInteractEvent.php @@ -61,11 +61,10 @@ class PlayerInteractEvent extends PlayerEvent implements Cancellable{ * @param int $face * @param int $action */ - public function __construct(Player $player, Item $item, ?Block $block, ?Vector3 $touchVector, int $face, int $action = PlayerInteractEvent::RIGHT_CLICK_BLOCK){ - assert($block !== null or $touchVector !== null); + public function __construct(Player $player, Item $item, Block $block, ?Vector3 $touchVector, int $face, int $action = PlayerInteractEvent::RIGHT_CLICK_BLOCK){ $this->player = $player; $this->item = $item; - $this->blockTouched = $block ?? BlockFactory::get(0, 0, new Position(0, 0, 0, $player->level)); + $this->blockTouched = $block; $this->touchVector = $touchVector ?? new Vector3(0, 0, 0); $this->blockFace = $face; $this->action = $action; From 54e19a6d2fffdb4d5ad0777352ab9d64e64f7f29 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 15 Sep 2018 17:10:57 +0100 Subject: [PATCH 0146/3224] Vine: fixed north check being missing --- src/pocketmine/block/Vine.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index b4adf98c65..957b081c5e 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -110,7 +110,15 @@ class Vine extends Flowable{ $flag = true; } - //TODO: Missing NORTH check + if(($this->meta & self::FLAG_NORTH) > 0){ + $maxZ = max($maxZ, 0.0625); + $minZ = 0; + $minX = 0; + $maxX = 1; + $minY = 0; + $maxY = 1; + $flag = true; + } if(!$flag and $this->getSide(Facing::UP)->isSolid()){ $minY = min($minY, 0.9375); From ed8b8a13a34fdc532988d054920204f73befb7fa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 16 Sep 2018 12:20:10 +0100 Subject: [PATCH 0147/3224] Vine: cleanup BB calculation --- src/pocketmine/block/Vine.php | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index 957b081c5e..de7e9e18fb 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -72,32 +72,27 @@ class Vine extends Flowable{ protected function recalculateBoundingBox() : ?AxisAlignedBB{ $minX = 1; - $minY = 1; $minZ = 1; $maxX = 0; - $maxY = 0; $maxZ = 0; - $flag = $this->meta > 0; + $minY = 0; + $hasSide = false; if(($this->meta & self::FLAG_WEST) > 0){ $maxX = max($maxX, 0.0625); $minX = 0; - $minY = 0; - $maxY = 1; $minZ = 0; $maxZ = 1; - $flag = true; + $hasSide = true; } if(($this->meta & self::FLAG_EAST) > 0){ $minX = min($minX, 0.9375); $maxX = 1; - $minY = 0; - $maxY = 1; $minZ = 0; $maxZ = 1; - $flag = true; + $hasSide = true; } if(($this->meta & self::FLAG_SOUTH) > 0){ @@ -105,9 +100,7 @@ class Vine extends Flowable{ $maxZ = 1; $minX = 0; $maxX = 1; - $minY = 0; - $maxY = 1; - $flag = true; + $hasSide = true; } if(($this->meta & self::FLAG_NORTH) > 0){ @@ -115,21 +108,18 @@ class Vine extends Flowable{ $minZ = 0; $minX = 0; $maxX = 1; - $minY = 0; - $maxY = 1; - $flag = true; + $hasSide = true; } - if(!$flag and $this->getSide(Facing::UP)->isSolid()){ - $minY = min($minY, 0.9375); - $maxY = 1; + if(!$hasSide){ + $minY = 0.9375; $minX = 0; $maxX = 1; $minZ = 0; $maxZ = 1; } - return new AxisAlignedBB($minX, $minY, $minZ, $maxX, $maxY, $maxZ); + return new AxisAlignedBB($minX, $minY, $minZ, $maxX, 1, $maxZ); } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ From f7f06c993d908b714feb3b10dd92a1f5b0bcad2b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 16 Sep 2018 14:10:40 +0100 Subject: [PATCH 0148/3224] Make block constructors not write to this->meta directly --- src/pocketmine/block/Air.php | 2 +- src/pocketmine/block/Anvil.php | 2 +- src/pocketmine/block/BaseRail.php | 2 +- src/pocketmine/block/Bed.php | 2 +- src/pocketmine/block/Bedrock.php | 2 +- src/pocketmine/block/Beetroot.php | 2 +- src/pocketmine/block/BoneBlock.php | 2 +- src/pocketmine/block/Bookshelf.php | 2 +- src/pocketmine/block/BrewingStand.php | 2 +- src/pocketmine/block/BrickStairs.php | 2 +- src/pocketmine/block/Bricks.php | 2 +- src/pocketmine/block/BurningFurnace.php | 2 +- src/pocketmine/block/Button.php | 2 +- src/pocketmine/block/Cactus.php | 2 +- src/pocketmine/block/Cake.php | 2 +- src/pocketmine/block/Carpet.php | 2 +- src/pocketmine/block/Carrot.php | 2 +- src/pocketmine/block/Chest.php | 2 +- src/pocketmine/block/Clay.php | 2 +- src/pocketmine/block/Coal.php | 2 +- src/pocketmine/block/CoalOre.php | 2 +- src/pocketmine/block/Cobblestone.php | 2 +- src/pocketmine/block/CobblestoneStairs.php | 2 +- src/pocketmine/block/CobblestoneWall.php | 2 +- src/pocketmine/block/Cobweb.php | 2 +- src/pocketmine/block/CocoaBlock.php | 2 +- src/pocketmine/block/Concrete.php | 2 +- src/pocketmine/block/ConcretePowder.php | 2 +- src/pocketmine/block/CraftingTable.php | 2 +- src/pocketmine/block/Dandelion.php | 2 +- src/pocketmine/block/DaylightSensor.php | 2 +- src/pocketmine/block/DeadBush.php | 2 +- src/pocketmine/block/Diamond.php | 2 +- src/pocketmine/block/DiamondOre.php | 2 +- src/pocketmine/block/Dirt.php | 2 +- src/pocketmine/block/DoublePlant.php | 2 +- src/pocketmine/block/DoubleSlab.php | 2 +- src/pocketmine/block/Emerald.php | 2 +- src/pocketmine/block/EmeraldOre.php | 2 +- src/pocketmine/block/EnchantingTable.php | 2 +- src/pocketmine/block/EndPortalFrame.php | 2 +- src/pocketmine/block/EndRod.php | 2 +- src/pocketmine/block/EndStone.php | 2 +- src/pocketmine/block/EndStoneBricks.php | 2 +- src/pocketmine/block/Farmland.php | 2 +- src/pocketmine/block/Fence.php | 2 +- src/pocketmine/block/Fire.php | 2 +- src/pocketmine/block/Flower.php | 2 +- src/pocketmine/block/FlowerPot.php | 2 +- src/pocketmine/block/Glass.php | 2 +- src/pocketmine/block/GlassPane.php | 2 +- src/pocketmine/block/GlowingObsidian.php | 2 +- src/pocketmine/block/Glowstone.php | 2 +- src/pocketmine/block/Gold.php | 2 +- src/pocketmine/block/GoldOre.php | 2 +- src/pocketmine/block/Grass.php | 2 +- src/pocketmine/block/GrassPath.php | 2 +- src/pocketmine/block/Gravel.php | 2 +- src/pocketmine/block/HardenedClay.php | 2 +- src/pocketmine/block/HayBale.php | 2 +- src/pocketmine/block/Ice.php | 2 +- src/pocketmine/block/Iron.php | 2 +- src/pocketmine/block/IronBars.php | 2 +- src/pocketmine/block/IronDoor.php | 2 +- src/pocketmine/block/IronOre.php | 2 +- src/pocketmine/block/ItemFrame.php | 2 +- src/pocketmine/block/Ladder.php | 2 +- src/pocketmine/block/Lapis.php | 2 +- src/pocketmine/block/LapisOre.php | 2 +- src/pocketmine/block/Lava.php | 2 +- src/pocketmine/block/Leaves.php | 2 +- src/pocketmine/block/Lever.php | 2 +- src/pocketmine/block/Magma.php | 2 +- src/pocketmine/block/Melon.php | 2 +- src/pocketmine/block/MelonStem.php | 2 +- src/pocketmine/block/MonsterSpawner.php | 2 +- src/pocketmine/block/Mycelium.php | 2 +- src/pocketmine/block/NetherBrickStairs.php | 2 +- src/pocketmine/block/NetherQuartzOre.php | 2 +- src/pocketmine/block/NetherReactor.php | 2 +- src/pocketmine/block/NetherWartBlock.php | 2 +- src/pocketmine/block/NetherWartPlant.php | 2 +- src/pocketmine/block/Netherrack.php | 2 +- src/pocketmine/block/NoteBlock.php | 2 +- src/pocketmine/block/Obsidian.php | 2 +- src/pocketmine/block/PackedIce.php | 2 +- src/pocketmine/block/Planks.php | 2 +- src/pocketmine/block/Podzol.php | 2 +- src/pocketmine/block/Potato.php | 2 +- src/pocketmine/block/Prismarine.php | 2 +- src/pocketmine/block/Pumpkin.php | 2 +- src/pocketmine/block/PumpkinStem.php | 2 +- src/pocketmine/block/PurpurStairs.php | 2 +- src/pocketmine/block/Quartz.php | 2 +- src/pocketmine/block/QuartzStairs.php | 2 +- src/pocketmine/block/RedMushroom.php | 2 +- src/pocketmine/block/RedMushroomBlock.php | 2 +- src/pocketmine/block/Redstone.php | 2 +- src/pocketmine/block/RedstoneLamp.php | 2 +- src/pocketmine/block/RedstoneOre.php | 2 +- src/pocketmine/block/Sand.php | 2 +- src/pocketmine/block/Sandstone.php | 2 +- src/pocketmine/block/SandstoneStairs.php | 2 +- src/pocketmine/block/Sapling.php | 2 +- src/pocketmine/block/SeaLantern.php | 2 +- src/pocketmine/block/SignPost.php | 2 +- src/pocketmine/block/Skull.php | 2 +- src/pocketmine/block/Slab.php | 2 +- src/pocketmine/block/Snow.php | 2 +- src/pocketmine/block/SnowLayer.php | 2 +- src/pocketmine/block/SoulSand.php | 2 +- src/pocketmine/block/Sponge.php | 2 +- src/pocketmine/block/StandingBanner.php | 2 +- src/pocketmine/block/Stone.php | 2 +- src/pocketmine/block/StoneBrickStairs.php | 2 +- src/pocketmine/block/StoneBricks.php | 2 +- src/pocketmine/block/StonePressurePlate.php | 2 +- src/pocketmine/block/Stonecutter.php | 2 +- src/pocketmine/block/Sugarcane.php | 2 +- src/pocketmine/block/TNT.php | 2 +- src/pocketmine/block/TallGrass.php | 2 +- src/pocketmine/block/Torch.php | 2 +- src/pocketmine/block/Trapdoor.php | 2 +- src/pocketmine/block/Tripwire.php | 2 +- src/pocketmine/block/TripwireHook.php | 2 +- src/pocketmine/block/Vine.php | 2 +- src/pocketmine/block/Water.php | 2 +- src/pocketmine/block/WaterLily.php | 2 +- src/pocketmine/block/WeightedPressurePlateLight.php | 2 +- src/pocketmine/block/Wheat.php | 2 +- src/pocketmine/block/Wood.php | 2 +- src/pocketmine/block/Wool.php | 2 +- 132 files changed, 132 insertions(+), 132 deletions(-) diff --git a/src/pocketmine/block/Air.php b/src/pocketmine/block/Air.php index b953eb9060..9984e3fe25 100644 --- a/src/pocketmine/block/Air.php +++ b/src/pocketmine/block/Air.php @@ -35,7 +35,7 @@ class Air extends Transparent{ protected $id = self::AIR; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index fb9019f96a..7f8bf54fac 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -40,7 +40,7 @@ class Anvil extends Fallable{ protected $id = self::ANVIL; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function isTransparent() : bool{ diff --git a/src/pocketmine/block/BaseRail.php b/src/pocketmine/block/BaseRail.php index bfcdf32ca5..d7a2096b99 100644 --- a/src/pocketmine/block/BaseRail.php +++ b/src/pocketmine/block/BaseRail.php @@ -77,7 +77,7 @@ abstract class BaseRail extends Flowable{ ]; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index e802482ebe..f6ee877c50 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -45,7 +45,7 @@ class Bed extends Transparent{ protected $itemId = Item::BED; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Bedrock.php b/src/pocketmine/block/Bedrock.php index beb5ceac1e..403fc495d5 100644 --- a/src/pocketmine/block/Bedrock.php +++ b/src/pocketmine/block/Bedrock.php @@ -30,7 +30,7 @@ class Bedrock extends Solid{ protected $id = self::BEDROCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Beetroot.php b/src/pocketmine/block/Beetroot.php index a6cc047525..783fe6e09a 100644 --- a/src/pocketmine/block/Beetroot.php +++ b/src/pocketmine/block/Beetroot.php @@ -31,7 +31,7 @@ class Beetroot extends Crops{ protected $id = self::BEETROOT_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/BoneBlock.php b/src/pocketmine/block/BoneBlock.php index 7d9efaceb8..1eb7e11f5c 100644 --- a/src/pocketmine/block/BoneBlock.php +++ b/src/pocketmine/block/BoneBlock.php @@ -34,7 +34,7 @@ class BoneBlock extends Solid{ protected $id = Block::BONE_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Bookshelf.php b/src/pocketmine/block/Bookshelf.php index 601f396101..3ae90a3ed2 100644 --- a/src/pocketmine/block/Bookshelf.php +++ b/src/pocketmine/block/Bookshelf.php @@ -31,7 +31,7 @@ class Bookshelf extends Solid{ protected $id = self::BOOKSHELF; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/BrewingStand.php b/src/pocketmine/block/BrewingStand.php index c2ad6f9482..b5443a8775 100644 --- a/src/pocketmine/block/BrewingStand.php +++ b/src/pocketmine/block/BrewingStand.php @@ -30,7 +30,7 @@ class BrewingStand extends Transparent{ protected $id = self::BREWING_STAND_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/BrickStairs.php b/src/pocketmine/block/BrickStairs.php index 4e305e9552..490c2697fe 100644 --- a/src/pocketmine/block/BrickStairs.php +++ b/src/pocketmine/block/BrickStairs.php @@ -30,7 +30,7 @@ class BrickStairs extends Stair{ protected $id = self::BRICK_STAIRS; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Bricks.php b/src/pocketmine/block/Bricks.php index 22f0c1fc7c..f18963ca14 100644 --- a/src/pocketmine/block/Bricks.php +++ b/src/pocketmine/block/Bricks.php @@ -30,7 +30,7 @@ class Bricks extends Solid{ protected $id = self::BRICK_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/BurningFurnace.php b/src/pocketmine/block/BurningFurnace.php index 7440d0f28c..3cc32970f6 100644 --- a/src/pocketmine/block/BurningFurnace.php +++ b/src/pocketmine/block/BurningFurnace.php @@ -38,7 +38,7 @@ class BurningFurnace extends Solid{ protected $itemId = self::FURNACE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Button.php b/src/pocketmine/block/Button.php index d8b333e825..2c1dbaf588 100644 --- a/src/pocketmine/block/Button.php +++ b/src/pocketmine/block/Button.php @@ -30,7 +30,7 @@ use pocketmine\Player; abstract class Button extends Flowable{ public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getVariantBitmask() : int{ diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index 19fbff9043..fcf5c4a562 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -39,7 +39,7 @@ class Cactus extends Transparent{ protected $id = self::CACTUS; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index dd31ec231f..970a073ef2 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -37,7 +37,7 @@ class Cake extends Transparent implements FoodSource{ protected $id = self::CAKE_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Carpet.php b/src/pocketmine/block/Carpet.php index a79dac0926..92310cc338 100644 --- a/src/pocketmine/block/Carpet.php +++ b/src/pocketmine/block/Carpet.php @@ -35,7 +35,7 @@ class Carpet extends Flowable{ protected $id = self::CARPET; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Carrot.php b/src/pocketmine/block/Carrot.php index 42f6133f25..9ca50c2246 100644 --- a/src/pocketmine/block/Carrot.php +++ b/src/pocketmine/block/Carrot.php @@ -31,7 +31,7 @@ class Carrot extends Crops{ protected $id = self::CARROT_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index 2ca3536ee2..942503bfc9 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -37,7 +37,7 @@ class Chest extends Transparent{ protected $id = self::CHEST; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Clay.php b/src/pocketmine/block/Clay.php index 12758b8020..2fb26fd99a 100644 --- a/src/pocketmine/block/Clay.php +++ b/src/pocketmine/block/Clay.php @@ -31,7 +31,7 @@ class Clay extends Solid{ protected $id = self::CLAY_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Coal.php b/src/pocketmine/block/Coal.php index 68ccfe2396..eb6f609a1e 100644 --- a/src/pocketmine/block/Coal.php +++ b/src/pocketmine/block/Coal.php @@ -30,7 +30,7 @@ class Coal extends Solid{ protected $id = self::COAL_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/CoalOre.php b/src/pocketmine/block/CoalOre.php index 520c2ff712..f440fa2c37 100644 --- a/src/pocketmine/block/CoalOre.php +++ b/src/pocketmine/block/CoalOre.php @@ -32,7 +32,7 @@ class CoalOre extends Solid{ protected $id = self::COAL_ORE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Cobblestone.php b/src/pocketmine/block/Cobblestone.php index 87169fc63b..dd9cce576f 100644 --- a/src/pocketmine/block/Cobblestone.php +++ b/src/pocketmine/block/Cobblestone.php @@ -30,7 +30,7 @@ class Cobblestone extends Solid{ protected $id = self::COBBLESTONE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getToolType() : int{ diff --git a/src/pocketmine/block/CobblestoneStairs.php b/src/pocketmine/block/CobblestoneStairs.php index 06357dea1d..4670b4957f 100644 --- a/src/pocketmine/block/CobblestoneStairs.php +++ b/src/pocketmine/block/CobblestoneStairs.php @@ -30,7 +30,7 @@ class CobblestoneStairs extends Stair{ protected $id = self::COBBLESTONE_STAIRS; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/CobblestoneWall.php b/src/pocketmine/block/CobblestoneWall.php index 86c2d977d4..0e2ee42f50 100644 --- a/src/pocketmine/block/CobblestoneWall.php +++ b/src/pocketmine/block/CobblestoneWall.php @@ -34,7 +34,7 @@ class CobblestoneWall extends Transparent{ protected $id = self::COBBLESTONE_WALL; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getToolType() : int{ diff --git a/src/pocketmine/block/Cobweb.php b/src/pocketmine/block/Cobweb.php index c20cc35f57..d75ee1cfea 100644 --- a/src/pocketmine/block/Cobweb.php +++ b/src/pocketmine/block/Cobweb.php @@ -32,7 +32,7 @@ class Cobweb extends Flowable{ protected $id = self::COBWEB; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function hasEntityCollision() : bool{ diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index fca535a99c..663e8f42c6 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -28,7 +28,7 @@ class CocoaBlock extends Transparent{ protected $id = self::COCOA_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Concrete.php b/src/pocketmine/block/Concrete.php index 9148d9f503..42d427a1b3 100644 --- a/src/pocketmine/block/Concrete.php +++ b/src/pocketmine/block/Concrete.php @@ -31,7 +31,7 @@ class Concrete extends Solid{ protected $id = Block::CONCRETE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/ConcretePowder.php b/src/pocketmine/block/ConcretePowder.php index 71df537872..a43f688a3c 100644 --- a/src/pocketmine/block/ConcretePowder.php +++ b/src/pocketmine/block/ConcretePowder.php @@ -31,7 +31,7 @@ class ConcretePowder extends Fallable{ protected $id = self::CONCRETE_POWDER; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/CraftingTable.php b/src/pocketmine/block/CraftingTable.php index 05b52fd6ad..a0ce8ce3bf 100644 --- a/src/pocketmine/block/CraftingTable.php +++ b/src/pocketmine/block/CraftingTable.php @@ -32,7 +32,7 @@ class CraftingTable extends Solid{ protected $id = self::CRAFTING_TABLE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Dandelion.php b/src/pocketmine/block/Dandelion.php index 474054e723..50b887d93b 100644 --- a/src/pocketmine/block/Dandelion.php +++ b/src/pocketmine/block/Dandelion.php @@ -33,7 +33,7 @@ class Dandelion extends Flowable{ protected $id = self::DANDELION; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/DaylightSensor.php b/src/pocketmine/block/DaylightSensor.php index b5381b41a8..708667600f 100644 --- a/src/pocketmine/block/DaylightSensor.php +++ b/src/pocketmine/block/DaylightSensor.php @@ -28,7 +28,7 @@ class DaylightSensor extends Transparent{ protected $id = self::DAYLIGHT_SENSOR; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/DeadBush.php b/src/pocketmine/block/DeadBush.php index 8f3c5c3547..d32afc18c0 100644 --- a/src/pocketmine/block/DeadBush.php +++ b/src/pocketmine/block/DeadBush.php @@ -34,7 +34,7 @@ class DeadBush extends Flowable{ protected $id = self::DEAD_BUSH; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Diamond.php b/src/pocketmine/block/Diamond.php index 8deea0468b..3a6f66aa70 100644 --- a/src/pocketmine/block/Diamond.php +++ b/src/pocketmine/block/Diamond.php @@ -30,7 +30,7 @@ class Diamond extends Solid{ protected $id = self::DIAMOND_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/DiamondOre.php b/src/pocketmine/block/DiamondOre.php index cde4604e32..a789d9d45a 100644 --- a/src/pocketmine/block/DiamondOre.php +++ b/src/pocketmine/block/DiamondOre.php @@ -32,7 +32,7 @@ class DiamondOre extends Solid{ protected $id = self::DIAMOND_ORE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Dirt.php b/src/pocketmine/block/Dirt.php index 96f8da27c4..89a4e519d1 100644 --- a/src/pocketmine/block/Dirt.php +++ b/src/pocketmine/block/Dirt.php @@ -32,7 +32,7 @@ class Dirt extends Solid{ protected $id = self::DIRT; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index f1d477675c..1c9317de58 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -35,7 +35,7 @@ class DoublePlant extends Flowable{ protected $id = self::DOUBLE_PLANT; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function canBeReplaced() : bool{ diff --git a/src/pocketmine/block/DoubleSlab.php b/src/pocketmine/block/DoubleSlab.php index 31a2ffdcfa..668e56615b 100644 --- a/src/pocketmine/block/DoubleSlab.php +++ b/src/pocketmine/block/DoubleSlab.php @@ -29,7 +29,7 @@ use pocketmine\item\ItemFactory; abstract class DoubleSlab extends Solid{ public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } abstract public function getSlabId() : int; diff --git a/src/pocketmine/block/Emerald.php b/src/pocketmine/block/Emerald.php index 7c5051051f..778d7e8176 100644 --- a/src/pocketmine/block/Emerald.php +++ b/src/pocketmine/block/Emerald.php @@ -30,7 +30,7 @@ class Emerald extends Solid{ protected $id = self::EMERALD_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/EmeraldOre.php b/src/pocketmine/block/EmeraldOre.php index 7dcbcde65a..31c2a3f809 100644 --- a/src/pocketmine/block/EmeraldOre.php +++ b/src/pocketmine/block/EmeraldOre.php @@ -32,7 +32,7 @@ class EmeraldOre extends Solid{ protected $id = self::EMERALD_ORE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/EnchantingTable.php b/src/pocketmine/block/EnchantingTable.php index f86616beef..4a23b3ab16 100644 --- a/src/pocketmine/block/EnchantingTable.php +++ b/src/pocketmine/block/EnchantingTable.php @@ -36,7 +36,7 @@ class EnchantingTable extends Transparent{ protected $id = self::ENCHANTING_TABLE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ diff --git a/src/pocketmine/block/EndPortalFrame.php b/src/pocketmine/block/EndPortalFrame.php index 1e51399b61..193788054b 100644 --- a/src/pocketmine/block/EndPortalFrame.php +++ b/src/pocketmine/block/EndPortalFrame.php @@ -31,7 +31,7 @@ class EndPortalFrame extends Solid{ protected $id = self::END_PORTAL_FRAME; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getLightLevel() : int{ diff --git a/src/pocketmine/block/EndRod.php b/src/pocketmine/block/EndRod.php index 9aa1576700..306cdd2669 100644 --- a/src/pocketmine/block/EndRod.php +++ b/src/pocketmine/block/EndRod.php @@ -34,7 +34,7 @@ class EndRod extends Flowable{ protected $id = Block::END_ROD; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/EndStone.php b/src/pocketmine/block/EndStone.php index d7147f8de5..cd4f40c7d5 100644 --- a/src/pocketmine/block/EndStone.php +++ b/src/pocketmine/block/EndStone.php @@ -30,7 +30,7 @@ class EndStone extends Solid{ protected $id = self::END_STONE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/EndStoneBricks.php b/src/pocketmine/block/EndStoneBricks.php index 87ba1cb29d..a925f952c2 100644 --- a/src/pocketmine/block/EndStoneBricks.php +++ b/src/pocketmine/block/EndStoneBricks.php @@ -30,7 +30,7 @@ class EndStoneBricks extends Solid{ protected $id = self::END_BRICKS; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index b8a32a7539..f1895e947b 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -33,7 +33,7 @@ class Farmland extends Transparent{ protected $id = self::FARMLAND; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Fence.php b/src/pocketmine/block/Fence.php index f7981e207b..effd3b8249 100644 --- a/src/pocketmine/block/Fence.php +++ b/src/pocketmine/block/Fence.php @@ -29,7 +29,7 @@ use pocketmine\math\Facing; abstract class Fence extends Transparent{ public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getThickness() : float{ diff --git a/src/pocketmine/block/Fire.php b/src/pocketmine/block/Fire.php index b8ccc1cf70..a6bd4c1e70 100644 --- a/src/pocketmine/block/Fire.php +++ b/src/pocketmine/block/Fire.php @@ -38,7 +38,7 @@ class Fire extends Flowable{ protected $id = self::FIRE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function hasEntityCollision() : bool{ diff --git a/src/pocketmine/block/Flower.php b/src/pocketmine/block/Flower.php index d19bfa3a2a..fb85cbefb9 100644 --- a/src/pocketmine/block/Flower.php +++ b/src/pocketmine/block/Flower.php @@ -42,7 +42,7 @@ class Flower extends Flowable{ protected $id = self::RED_FLOWER; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 8e50621cd0..40555546c1 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -40,7 +40,7 @@ class FlowerPot extends Flowable{ protected $itemId = Item::FLOWER_POT; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Glass.php b/src/pocketmine/block/Glass.php index 42bd5cdd9b..65ab80b572 100644 --- a/src/pocketmine/block/Glass.php +++ b/src/pocketmine/block/Glass.php @@ -30,7 +30,7 @@ class Glass extends Transparent{ protected $id = self::GLASS; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/GlassPane.php b/src/pocketmine/block/GlassPane.php index c009460af8..cc19440671 100644 --- a/src/pocketmine/block/GlassPane.php +++ b/src/pocketmine/block/GlassPane.php @@ -30,7 +30,7 @@ class GlassPane extends Thin{ protected $id = self::GLASS_PANE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/GlowingObsidian.php b/src/pocketmine/block/GlowingObsidian.php index 74c129c217..e8e62a76db 100644 --- a/src/pocketmine/block/GlowingObsidian.php +++ b/src/pocketmine/block/GlowingObsidian.php @@ -31,7 +31,7 @@ class GlowingObsidian extends Solid{ protected $id = self::GLOWING_OBSIDIAN; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Glowstone.php b/src/pocketmine/block/Glowstone.php index caf15beb93..02f5a31bab 100644 --- a/src/pocketmine/block/Glowstone.php +++ b/src/pocketmine/block/Glowstone.php @@ -31,7 +31,7 @@ class Glowstone extends Transparent{ protected $id = self::GLOWSTONE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Gold.php b/src/pocketmine/block/Gold.php index d9b7457953..99e82324a9 100644 --- a/src/pocketmine/block/Gold.php +++ b/src/pocketmine/block/Gold.php @@ -30,7 +30,7 @@ class Gold extends Solid{ protected $id = self::GOLD_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/GoldOre.php b/src/pocketmine/block/GoldOre.php index a776e01fd7..a6b280ccfb 100644 --- a/src/pocketmine/block/GoldOre.php +++ b/src/pocketmine/block/GoldOre.php @@ -30,7 +30,7 @@ class GoldOre extends Solid{ protected $id = self::GOLD_ORE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index 43045355e0..641f3118e6 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -38,7 +38,7 @@ class Grass extends Solid{ protected $id = self::GRASS; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/GrassPath.php b/src/pocketmine/block/GrassPath.php index dbe08ca782..18818277f1 100644 --- a/src/pocketmine/block/GrassPath.php +++ b/src/pocketmine/block/GrassPath.php @@ -33,7 +33,7 @@ class GrassPath extends Transparent{ protected $id = self::GRASS_PATH; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Gravel.php b/src/pocketmine/block/Gravel.php index 5aced70ce6..d2492729b2 100644 --- a/src/pocketmine/block/Gravel.php +++ b/src/pocketmine/block/Gravel.php @@ -31,7 +31,7 @@ class Gravel extends Fallable{ protected $id = self::GRAVEL; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/HardenedClay.php b/src/pocketmine/block/HardenedClay.php index 3a3e6896e6..7918c2c32a 100644 --- a/src/pocketmine/block/HardenedClay.php +++ b/src/pocketmine/block/HardenedClay.php @@ -30,7 +30,7 @@ class HardenedClay extends Solid{ protected $id = self::HARDENED_CLAY; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/HayBale.php b/src/pocketmine/block/HayBale.php index 112f9f788c..696c8c8f96 100644 --- a/src/pocketmine/block/HayBale.php +++ b/src/pocketmine/block/HayBale.php @@ -33,7 +33,7 @@ class HayBale extends Solid{ protected $id = self::HAY_BALE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Ice.php b/src/pocketmine/block/Ice.php index b3e33af14f..071de1fd44 100644 --- a/src/pocketmine/block/Ice.php +++ b/src/pocketmine/block/Ice.php @@ -32,7 +32,7 @@ class Ice extends Transparent{ protected $id = self::ICE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Iron.php b/src/pocketmine/block/Iron.php index 3f0a0786f3..772a8d664b 100644 --- a/src/pocketmine/block/Iron.php +++ b/src/pocketmine/block/Iron.php @@ -30,7 +30,7 @@ class Iron extends Solid{ protected $id = self::IRON_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/IronBars.php b/src/pocketmine/block/IronBars.php index 52b4869ce2..7e6030f092 100644 --- a/src/pocketmine/block/IronBars.php +++ b/src/pocketmine/block/IronBars.php @@ -30,7 +30,7 @@ class IronBars extends Thin{ protected $id = self::IRON_BARS; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/IronDoor.php b/src/pocketmine/block/IronDoor.php index 2d263faed5..b097d4d26e 100644 --- a/src/pocketmine/block/IronDoor.php +++ b/src/pocketmine/block/IronDoor.php @@ -33,7 +33,7 @@ class IronDoor extends Door{ protected $itemId = Item::IRON_DOOR; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/IronOre.php b/src/pocketmine/block/IronOre.php index 003e8384d0..bda7572dab 100644 --- a/src/pocketmine/block/IronOre.php +++ b/src/pocketmine/block/IronOre.php @@ -30,7 +30,7 @@ class IronOre extends Solid{ protected $id = self::IRON_ORE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index f744d05f33..f8414aed30 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -36,7 +36,7 @@ class ItemFrame extends Flowable{ protected $itemId = Item::ITEM_FRAME; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Ladder.php b/src/pocketmine/block/Ladder.php index 0fcbe82175..0f29bcb0cc 100644 --- a/src/pocketmine/block/Ladder.php +++ b/src/pocketmine/block/Ladder.php @@ -35,7 +35,7 @@ class Ladder extends Transparent{ protected $id = self::LADDER; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Lapis.php b/src/pocketmine/block/Lapis.php index 664a4a4db9..3ca5c31b11 100644 --- a/src/pocketmine/block/Lapis.php +++ b/src/pocketmine/block/Lapis.php @@ -30,7 +30,7 @@ class Lapis extends Solid{ protected $id = self::LAPIS_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/LapisOre.php b/src/pocketmine/block/LapisOre.php index c13181cdcf..18bccaf98a 100644 --- a/src/pocketmine/block/LapisOre.php +++ b/src/pocketmine/block/LapisOre.php @@ -32,7 +32,7 @@ class LapisOre extends Solid{ protected $id = self::LAPIS_ORE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Lava.php b/src/pocketmine/block/Lava.php index 044bc1d9f6..7757cd36d5 100644 --- a/src/pocketmine/block/Lava.php +++ b/src/pocketmine/block/Lava.php @@ -36,7 +36,7 @@ class Lava extends Liquid{ protected $id = self::FLOWING_LAVA; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getLightLevel() : int{ diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 9257ca84c0..8ad5ae402a 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -43,7 +43,7 @@ class Leaves extends Transparent{ protected $woodType = self::WOOD; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index a57fc1c665..6cd6b84801 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -34,7 +34,7 @@ class Lever extends Flowable{ protected $id = self::LEVER; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Magma.php b/src/pocketmine/block/Magma.php index 6fae86ae80..725bdfeb8a 100644 --- a/src/pocketmine/block/Magma.php +++ b/src/pocketmine/block/Magma.php @@ -33,7 +33,7 @@ class Magma extends Solid{ protected $id = Block::MAGMA; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Melon.php b/src/pocketmine/block/Melon.php index e5023d3923..649f839d21 100644 --- a/src/pocketmine/block/Melon.php +++ b/src/pocketmine/block/Melon.php @@ -31,7 +31,7 @@ class Melon extends Transparent{ protected $id = self::MELON_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/MelonStem.php b/src/pocketmine/block/MelonStem.php index 0af36721dd..e8763cb2d5 100644 --- a/src/pocketmine/block/MelonStem.php +++ b/src/pocketmine/block/MelonStem.php @@ -38,7 +38,7 @@ class MelonStem extends Crops{ } public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function onRandomTick() : void{ diff --git a/src/pocketmine/block/MonsterSpawner.php b/src/pocketmine/block/MonsterSpawner.php index dda5895435..4829fd4f86 100644 --- a/src/pocketmine/block/MonsterSpawner.php +++ b/src/pocketmine/block/MonsterSpawner.php @@ -31,7 +31,7 @@ class MonsterSpawner extends Transparent{ protected $id = self::MONSTER_SPAWNER; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Mycelium.php b/src/pocketmine/block/Mycelium.php index 331d4ddc7f..1c5692a52a 100644 --- a/src/pocketmine/block/Mycelium.php +++ b/src/pocketmine/block/Mycelium.php @@ -34,7 +34,7 @@ class Mycelium extends Solid{ protected $id = self::MYCELIUM; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/NetherBrickStairs.php b/src/pocketmine/block/NetherBrickStairs.php index 270256929f..190a66e3c3 100644 --- a/src/pocketmine/block/NetherBrickStairs.php +++ b/src/pocketmine/block/NetherBrickStairs.php @@ -30,7 +30,7 @@ class NetherBrickStairs extends Stair{ protected $id = self::NETHER_BRICK_STAIRS; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/NetherQuartzOre.php b/src/pocketmine/block/NetherQuartzOre.php index 3726abc02e..7280203a53 100644 --- a/src/pocketmine/block/NetherQuartzOre.php +++ b/src/pocketmine/block/NetherQuartzOre.php @@ -32,7 +32,7 @@ class NetherQuartzOre extends Solid{ protected $id = Block::NETHER_QUARTZ_ORE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/NetherReactor.php b/src/pocketmine/block/NetherReactor.php index bf3f924fb7..fdaa0cb86a 100644 --- a/src/pocketmine/block/NetherReactor.php +++ b/src/pocketmine/block/NetherReactor.php @@ -31,7 +31,7 @@ class NetherReactor extends Solid{ protected $id = Block::NETHER_REACTOR; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/NetherWartBlock.php b/src/pocketmine/block/NetherWartBlock.php index 2758f4ff49..ac960d9206 100644 --- a/src/pocketmine/block/NetherWartBlock.php +++ b/src/pocketmine/block/NetherWartBlock.php @@ -28,7 +28,7 @@ class NetherWartBlock extends Solid{ protected $id = Block::NETHER_WART_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index 5c5e256949..50dd5dbbef 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -37,7 +37,7 @@ class NetherWartPlant extends Flowable{ protected $itemId = Item::NETHER_WART; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Netherrack.php b/src/pocketmine/block/Netherrack.php index e89d12f7a1..823a6b30c5 100644 --- a/src/pocketmine/block/Netherrack.php +++ b/src/pocketmine/block/Netherrack.php @@ -30,7 +30,7 @@ class Netherrack extends Solid{ protected $id = self::NETHERRACK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/NoteBlock.php b/src/pocketmine/block/NoteBlock.php index ca0d3c661c..4dc4fe9d49 100644 --- a/src/pocketmine/block/NoteBlock.php +++ b/src/pocketmine/block/NoteBlock.php @@ -28,7 +28,7 @@ class NoteBlock extends Solid{ protected $id = self::NOTE_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Obsidian.php b/src/pocketmine/block/Obsidian.php index 1363b490fe..f37298483b 100644 --- a/src/pocketmine/block/Obsidian.php +++ b/src/pocketmine/block/Obsidian.php @@ -30,7 +30,7 @@ class Obsidian extends Solid{ protected $id = self::OBSIDIAN; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/PackedIce.php b/src/pocketmine/block/PackedIce.php index 48eb086677..d80c91839c 100644 --- a/src/pocketmine/block/PackedIce.php +++ b/src/pocketmine/block/PackedIce.php @@ -28,7 +28,7 @@ class PackedIce extends Solid{ protected $id = self::PACKED_ICE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Planks.php b/src/pocketmine/block/Planks.php index 85de56ea77..9e5efe7056 100644 --- a/src/pocketmine/block/Planks.php +++ b/src/pocketmine/block/Planks.php @@ -34,7 +34,7 @@ class Planks extends Solid{ protected $id = self::WOODEN_PLANKS; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Podzol.php b/src/pocketmine/block/Podzol.php index 1ad8406cf3..470c8fabd7 100644 --- a/src/pocketmine/block/Podzol.php +++ b/src/pocketmine/block/Podzol.php @@ -28,7 +28,7 @@ class Podzol extends Solid{ protected $id = self::PODZOL; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getToolType() : int{ diff --git a/src/pocketmine/block/Potato.php b/src/pocketmine/block/Potato.php index 6df545d302..87d0efa2de 100644 --- a/src/pocketmine/block/Potato.php +++ b/src/pocketmine/block/Potato.php @@ -31,7 +31,7 @@ class Potato extends Crops{ protected $id = self::POTATO_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Prismarine.php b/src/pocketmine/block/Prismarine.php index 61de1b3b37..42a3fad713 100644 --- a/src/pocketmine/block/Prismarine.php +++ b/src/pocketmine/block/Prismarine.php @@ -34,7 +34,7 @@ class Prismarine extends Solid{ protected $id = self::PRISMARINE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Pumpkin.php b/src/pocketmine/block/Pumpkin.php index 3c63bae356..598114b1e2 100644 --- a/src/pocketmine/block/Pumpkin.php +++ b/src/pocketmine/block/Pumpkin.php @@ -28,7 +28,7 @@ class Pumpkin extends Solid{ protected $id = self::PUMPKIN; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/PumpkinStem.php b/src/pocketmine/block/PumpkinStem.php index de5b480ba8..dba366297b 100644 --- a/src/pocketmine/block/PumpkinStem.php +++ b/src/pocketmine/block/PumpkinStem.php @@ -34,7 +34,7 @@ class PumpkinStem extends Crops{ protected $id = self::PUMPKIN_STEM; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/PurpurStairs.php b/src/pocketmine/block/PurpurStairs.php index 39b3ace269..4e21183c57 100644 --- a/src/pocketmine/block/PurpurStairs.php +++ b/src/pocketmine/block/PurpurStairs.php @@ -30,7 +30,7 @@ class PurpurStairs extends Stair{ protected $id = self::PURPUR_STAIRS; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Quartz.php b/src/pocketmine/block/Quartz.php index dbda5ca3c5..162191d9e8 100644 --- a/src/pocketmine/block/Quartz.php +++ b/src/pocketmine/block/Quartz.php @@ -38,7 +38,7 @@ class Quartz extends Solid{ protected $id = self::QUARTZ_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/QuartzStairs.php b/src/pocketmine/block/QuartzStairs.php index 9ef08373d8..e748ca3856 100644 --- a/src/pocketmine/block/QuartzStairs.php +++ b/src/pocketmine/block/QuartzStairs.php @@ -30,7 +30,7 @@ class QuartzStairs extends Stair{ protected $id = self::QUARTZ_STAIRS; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/RedMushroom.php b/src/pocketmine/block/RedMushroom.php index 6a4b9118fe..1ed6076970 100644 --- a/src/pocketmine/block/RedMushroom.php +++ b/src/pocketmine/block/RedMushroom.php @@ -33,7 +33,7 @@ class RedMushroom extends Flowable{ protected $id = self::RED_MUSHROOM; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/RedMushroomBlock.php b/src/pocketmine/block/RedMushroomBlock.php index 94e1f45f3a..f892138670 100644 --- a/src/pocketmine/block/RedMushroomBlock.php +++ b/src/pocketmine/block/RedMushroomBlock.php @@ -30,7 +30,7 @@ class RedMushroomBlock extends Solid{ protected $id = Block::RED_MUSHROOM_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Redstone.php b/src/pocketmine/block/Redstone.php index cdeb98fe71..7430138c94 100644 --- a/src/pocketmine/block/Redstone.php +++ b/src/pocketmine/block/Redstone.php @@ -30,7 +30,7 @@ class Redstone extends Solid{ protected $id = self::REDSTONE_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/RedstoneLamp.php b/src/pocketmine/block/RedstoneLamp.php index a90e944f9a..8a33c6e946 100644 --- a/src/pocketmine/block/RedstoneLamp.php +++ b/src/pocketmine/block/RedstoneLamp.php @@ -28,7 +28,7 @@ class RedstoneLamp extends Solid{ protected $id = self::REDSTONE_LAMP; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/RedstoneOre.php b/src/pocketmine/block/RedstoneOre.php index 22b8aa7395..a16e48cd45 100644 --- a/src/pocketmine/block/RedstoneOre.php +++ b/src/pocketmine/block/RedstoneOre.php @@ -34,7 +34,7 @@ class RedstoneOre extends Solid{ protected $id = self::REDSTONE_ORE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Sand.php b/src/pocketmine/block/Sand.php index bd98b47b17..3bd4294ff2 100644 --- a/src/pocketmine/block/Sand.php +++ b/src/pocketmine/block/Sand.php @@ -28,7 +28,7 @@ class Sand extends Fallable{ protected $id = self::SAND; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Sandstone.php b/src/pocketmine/block/Sandstone.php index 5c941c319a..d7b829801d 100644 --- a/src/pocketmine/block/Sandstone.php +++ b/src/pocketmine/block/Sandstone.php @@ -34,7 +34,7 @@ class Sandstone extends Solid{ protected $id = self::SANDSTONE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/SandstoneStairs.php b/src/pocketmine/block/SandstoneStairs.php index 7c73e6147e..4bdc87b7f5 100644 --- a/src/pocketmine/block/SandstoneStairs.php +++ b/src/pocketmine/block/SandstoneStairs.php @@ -30,7 +30,7 @@ class SandstoneStairs extends Stair{ protected $id = self::SANDSTONE_STAIRS; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index 1573f63219..8c9db99e95 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -41,7 +41,7 @@ class Sapling extends Flowable{ protected $id = self::SAPLING; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/SeaLantern.php b/src/pocketmine/block/SeaLantern.php index 86af6679d6..5fcaa87f05 100644 --- a/src/pocketmine/block/SeaLantern.php +++ b/src/pocketmine/block/SeaLantern.php @@ -31,7 +31,7 @@ class SeaLantern extends Transparent{ protected $id = self::SEA_LANTERN; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/SignPost.php b/src/pocketmine/block/SignPost.php index 948c77ed12..87e47aea79 100644 --- a/src/pocketmine/block/SignPost.php +++ b/src/pocketmine/block/SignPost.php @@ -38,7 +38,7 @@ class SignPost extends Transparent{ protected $itemId = Item::SIGN; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index fe7c63a1cb..3f4dc71c29 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -37,7 +37,7 @@ class Skull extends Flowable{ protected $id = self::SKULL_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index 96fec3e314..26ea65ca37 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -32,7 +32,7 @@ use pocketmine\Player; abstract class Slab extends Transparent{ public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } abstract public function getDoubleSlabId() : int; diff --git a/src/pocketmine/block/Snow.php b/src/pocketmine/block/Snow.php index b6e00b3bd0..20e9919c10 100644 --- a/src/pocketmine/block/Snow.php +++ b/src/pocketmine/block/Snow.php @@ -32,7 +32,7 @@ class Snow extends Solid{ protected $id = self::SNOW_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index 9c4106f31c..0a709d45b8 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -35,7 +35,7 @@ class SnowLayer extends Flowable{ protected $id = self::SNOW_LAYER; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/SoulSand.php b/src/pocketmine/block/SoulSand.php index 5e402678ed..44e9900fde 100644 --- a/src/pocketmine/block/SoulSand.php +++ b/src/pocketmine/block/SoulSand.php @@ -30,7 +30,7 @@ class SoulSand extends Solid{ protected $id = self::SOUL_SAND; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Sponge.php b/src/pocketmine/block/Sponge.php index 4553f6fc57..1f9289e203 100644 --- a/src/pocketmine/block/Sponge.php +++ b/src/pocketmine/block/Sponge.php @@ -29,7 +29,7 @@ class Sponge extends Solid{ protected $id = self::SPONGE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index 9d6675914b..388ae5e6d8 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -39,7 +39,7 @@ class StandingBanner extends Transparent{ protected $itemId = Item::BANNER; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Stone.php b/src/pocketmine/block/Stone.php index c3a6d8c211..47b0962353 100644 --- a/src/pocketmine/block/Stone.php +++ b/src/pocketmine/block/Stone.php @@ -39,7 +39,7 @@ class Stone extends Solid{ protected $id = self::STONE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/StoneBrickStairs.php b/src/pocketmine/block/StoneBrickStairs.php index dc12203001..ec397251aa 100644 --- a/src/pocketmine/block/StoneBrickStairs.php +++ b/src/pocketmine/block/StoneBrickStairs.php @@ -30,7 +30,7 @@ class StoneBrickStairs extends Stair{ protected $id = self::STONE_BRICK_STAIRS; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getToolType() : int{ diff --git a/src/pocketmine/block/StoneBricks.php b/src/pocketmine/block/StoneBricks.php index 3b17797ba3..34518a8232 100644 --- a/src/pocketmine/block/StoneBricks.php +++ b/src/pocketmine/block/StoneBricks.php @@ -34,7 +34,7 @@ class StoneBricks extends Solid{ protected $id = self::STONE_BRICKS; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/StonePressurePlate.php b/src/pocketmine/block/StonePressurePlate.php index dc72f72a53..f11f7aebcf 100644 --- a/src/pocketmine/block/StonePressurePlate.php +++ b/src/pocketmine/block/StonePressurePlate.php @@ -30,7 +30,7 @@ class StonePressurePlate extends Transparent{ protected $id = self::STONE_PRESSURE_PLATE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Stonecutter.php b/src/pocketmine/block/Stonecutter.php index e8a6a40d42..1532b23383 100644 --- a/src/pocketmine/block/Stonecutter.php +++ b/src/pocketmine/block/Stonecutter.php @@ -30,7 +30,7 @@ class Stonecutter extends Solid{ protected $id = self::STONECUTTER; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index 2a2e8266ef..f3e25880ca 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -37,7 +37,7 @@ class Sugarcane extends Flowable{ protected $itemId = Item::SUGARCANE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index 5ebae29cde..7fa63d9d0f 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -36,7 +36,7 @@ class TNT extends Solid{ protected $id = self::TNT; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/TallGrass.php b/src/pocketmine/block/TallGrass.php index 5d15a10e87..d7e0b45f59 100644 --- a/src/pocketmine/block/TallGrass.php +++ b/src/pocketmine/block/TallGrass.php @@ -34,7 +34,7 @@ class TallGrass extends Flowable{ protected $id = self::TALL_GRASS; public function __construct(int $meta = 1){ - $this->meta = $meta; + $this->setDamage($meta); } public function canBeReplaced() : bool{ diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index 98473c92d3..c56f86ba85 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -33,7 +33,7 @@ class Torch extends Flowable{ protected $id = self::TORCH; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getLightLevel() : int{ diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index 437ca730e6..b5eb3d9d83 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -43,7 +43,7 @@ class Trapdoor extends Transparent{ protected $id = self::TRAPDOOR; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Tripwire.php b/src/pocketmine/block/Tripwire.php index 9a1f718ee8..e916fcb69c 100644 --- a/src/pocketmine/block/Tripwire.php +++ b/src/pocketmine/block/Tripwire.php @@ -31,7 +31,7 @@ class Tripwire extends Flowable{ protected $id = self::TRIPWIRE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/TripwireHook.php b/src/pocketmine/block/TripwireHook.php index 8bf328573a..f505dd92aa 100644 --- a/src/pocketmine/block/TripwireHook.php +++ b/src/pocketmine/block/TripwireHook.php @@ -28,7 +28,7 @@ class TripwireHook extends Flowable{ protected $id = self::TRIPWIRE_HOOK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index de7e9e18fb..300c120b21 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -39,7 +39,7 @@ class Vine extends Flowable{ protected $id = self::VINE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Water.php b/src/pocketmine/block/Water.php index a4c96bdab1..777696ff3b 100644 --- a/src/pocketmine/block/Water.php +++ b/src/pocketmine/block/Water.php @@ -31,7 +31,7 @@ class Water extends Liquid{ protected $id = self::FLOWING_WATER; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/WaterLily.php b/src/pocketmine/block/WaterLily.php index 4260a8a3e4..edee10a13d 100644 --- a/src/pocketmine/block/WaterLily.php +++ b/src/pocketmine/block/WaterLily.php @@ -34,7 +34,7 @@ class WaterLily extends Flowable{ protected $id = self::WATER_LILY; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/WeightedPressurePlateLight.php b/src/pocketmine/block/WeightedPressurePlateLight.php index c36d107f6b..5633173c86 100644 --- a/src/pocketmine/block/WeightedPressurePlateLight.php +++ b/src/pocketmine/block/WeightedPressurePlateLight.php @@ -30,7 +30,7 @@ class WeightedPressurePlateLight extends Transparent{ protected $id = self::LIGHT_WEIGHTED_PRESSURE_PLATE; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Wheat.php b/src/pocketmine/block/Wheat.php index 61ac91e115..c0d455a083 100644 --- a/src/pocketmine/block/Wheat.php +++ b/src/pocketmine/block/Wheat.php @@ -31,7 +31,7 @@ class Wheat extends Crops{ protected $id = self::WHEAT_BLOCK; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getName() : string{ diff --git a/src/pocketmine/block/Wood.php b/src/pocketmine/block/Wood.php index f50cdea3e1..375cd15df6 100644 --- a/src/pocketmine/block/Wood.php +++ b/src/pocketmine/block/Wood.php @@ -37,7 +37,7 @@ class Wood extends Solid{ protected $id = self::WOOD; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Wool.php b/src/pocketmine/block/Wool.php index 3c6fa7d78e..7963a13f93 100644 --- a/src/pocketmine/block/Wool.php +++ b/src/pocketmine/block/Wool.php @@ -31,7 +31,7 @@ class Wool extends Solid{ protected $id = self::WOOL; public function __construct(int $meta = 0){ - $this->meta = $meta; + $this->setDamage($meta); } public function getHardness() : float{ From 1bb4daa7d1f52691e0f3fa7f73ecf4b0c9850094 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 16 Sep 2018 17:37:36 +0100 Subject: [PATCH 0149/3224] Fixed mess of rotations being inverted --- composer.lock | 8 ++++---- src/pocketmine/block/Anvil.php | 2 +- src/pocketmine/block/Bed.php | 2 +- src/pocketmine/block/BurningFurnace.php | 2 +- src/pocketmine/block/Chest.php | 2 +- src/pocketmine/block/Door.php | 10 ++++++---- src/pocketmine/block/EnderChest.php | 2 +- src/pocketmine/block/FenceGate.php | 5 ++--- src/pocketmine/block/GlazedTerracotta.php | 2 +- src/pocketmine/block/Stair.php | 8 +------- src/pocketmine/block/Trapdoor.php | 9 ++------- 11 files changed, 21 insertions(+), 31 deletions(-) diff --git a/composer.lock b/composer.lock index 1ea1b675c6..4bfccbac99 100644 --- a/composer.lock +++ b/composer.lock @@ -187,12 +187,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "6511fb0dcfeb60705d4169cc0422258b325af5c6" + "reference": "e5fd6cf9e71c285ff24bb3a3cbc22a15a8e73ac7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/6511fb0dcfeb60705d4169cc0422258b325af5c6", - "reference": "6511fb0dcfeb60705d4169cc0422258b325af5c6", + "url": "https://api.github.com/repos/pmmp/Math/zipball/e5fd6cf9e71c285ff24bb3a3cbc22a15a8e73ac7", + "reference": "e5fd6cf9e71c285ff24bb3a3cbc22a15a8e73ac7", "shasum": "" }, "require": { @@ -218,7 +218,7 @@ "source": "https://github.com/pmmp/Math/tree/master", "issues": "https://github.com/pmmp/Math/issues" }, - "time": "2018-09-13T18:32:31+00:00" + "time": "2018-09-16T16:36:04+00:00" }, { "name": "pocketmine/nbt", diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index 7f8bf54fac..aa468082cd 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -95,7 +95,7 @@ class Anvil extends Fallable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $direction = $player !== null ? Bearing::rotate($player->getDirection(), -1) : 0; + $direction = $player !== null ? Bearing::rotate($player->getDirection(), 1) : 0; $this->meta = $this->getVariant() | $direction; return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index f6ee877c50..d8961d94ab 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -152,7 +152,7 @@ class Bed extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if(!$down->isTransparent()){ - $this->meta = $player instanceof Player ? Bearing::opposite($player->getDirection()) : 0; //rotate 180 degrees + $this->meta = $player instanceof Player ? $player->getDirection() : 0; $next = $this->getSide(self::getOtherHalfSide($this->meta)); if($next->canBeReplaced() and !$next->getSide(Facing::DOWN)->isTransparent()){ parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/BurningFurnace.php b/src/pocketmine/block/BurningFurnace.php index 3cc32970f6..2371b1ad2a 100644 --- a/src/pocketmine/block/BurningFurnace.php +++ b/src/pocketmine/block/BurningFurnace.php @@ -63,7 +63,7 @@ class BurningFurnace extends Solid{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ - $this->meta = Bearing::toFacing($player->getDirection()); + $this->meta = Bearing::toFacing(Bearing::opposite($player->getDirection())); } if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ Tile::createTile(Tile::FURNACE, $this->getLevel(), TileFurnace::createNBT($this, $face, $item, $player)); diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index 942503bfc9..ddec85663e 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -60,7 +60,7 @@ class Chest extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $chest = null; if($player !== null){ - $this->meta = Bearing::toFacing($player->getDirection()); + $this->meta = Bearing::toFacing(Bearing::opposite($player->getDirection())); } foreach([ diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index be43b8ae40..a0371f49eb 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -127,17 +127,19 @@ abstract class Door extends Transparent{ return false; } - $ccw = Bearing::toFacing($player instanceof Player ? Bearing::rotate($player->getDirection(), -1) : Bearing::EAST); + //door faces this way when opened (unless it's right, in which case it's the opposite) + $direction = $player !== null ? Bearing::rotate($player->getDirection(), 1) : Bearing::NORTH; - $next = $this->getSide(Facing::opposite($ccw)); - $next2 = $this->getSide($ccw); + $facing = Bearing::toFacing($direction); + $next = $this->getSide(Facing::opposite($facing)); + $next2 = $this->getSide($facing); $metaUp = 0x08; if($next->getId() === $this->getId() or (!$next2->isTransparent() and $next->isTransparent())){ //Door hinge $metaUp |= 0x01; } - $this->setDamage(Bearing::rotate($player->getDirection(), -1)); + $this->setDamage($direction); parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); $this->getLevel()->setBlock($blockUp, BlockFactory::get($this->getId(), $metaUp), true); //Top return true; diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index c619a3fefb..348c5c701e 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -63,7 +63,7 @@ class EnderChest extends Chest{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ - $this->meta = Bearing::toFacing($player->getDirection()); + $this->meta = Bearing::toFacing(Bearing::opposite($player->getDirection())); } if(Block::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index 69fda88143..e3e3191b9f 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -26,7 +26,6 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\level\sound\DoorSound; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Bearing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -70,7 +69,7 @@ class FenceGate extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ - $this->meta = Bearing::opposite($player->getDirection()); + $this->meta = $player->getDirection(); } return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); @@ -84,7 +83,7 @@ class FenceGate extends Transparent{ $this->meta = (($this->meta ^ 0x04) & ~0x02); if($player !== null){ - $this->meta |= (Bearing::opposite($player->getDirection()) & 0x02); //open towards the player, retaining axis + $this->meta |= ($player->getDirection() & 0x02); //open towards the player, retaining axis } $this->getLevel()->setBlock($this, $this, true); diff --git a/src/pocketmine/block/GlazedTerracotta.php b/src/pocketmine/block/GlazedTerracotta.php index d8276666bd..8035274756 100644 --- a/src/pocketmine/block/GlazedTerracotta.php +++ b/src/pocketmine/block/GlazedTerracotta.php @@ -46,7 +46,7 @@ class GlazedTerracotta extends Solid{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ - $this->meta = Bearing::toFacing($player->getDirection()); + $this->meta = Bearing::toFacing(Bearing::opposite($player->getDirection())); } return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index db0bcdaa41..1026b2fd3b 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -71,14 +71,8 @@ abstract class Stair extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - static $faces = [ - Bearing::SOUTH => 3, //north - Bearing::WEST => 0, //east - Bearing::NORTH => 2, //south - Bearing::EAST => 1 //west - ]; if($player !== null){ - $this->meta = $faces[$player->getDirection()]; + $this->meta = 5 - Bearing::toFacing($player->getDirection()); } if(($clickVector->y > 0.5 and $face !== Facing::UP) or $face === Facing::DOWN){ $this->meta |= 0x04; //Upside-down stairs diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index b5eb3d9d83..0b5278582c 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -83,14 +83,9 @@ class Trapdoor extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - static $directions = [ - Bearing::SOUTH => 2, - Bearing::WEST => 1, - Bearing::NORTH => 3, - Bearing::EAST => 0 - ]; if($player !== null){ - $this->meta = $directions[$player->getDirection()]; + //TODO: in PC the values are reversed (3 - (5 - facing)) + $this->meta = 5 - Bearing::toFacing(Bearing::opposite($player->getDirection())); } if(($clickVector->y > 0.5 and $face !== Facing::UP) or $face === Facing::DOWN){ $this->meta |= self::MASK_UPPER; //top half of block From 31e409388276c335e4d8eb91857f1656c9860a4b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 16 Sep 2018 18:00:16 +0100 Subject: [PATCH 0150/3224] Remove some remaining hardcoded meta maps --- src/pocketmine/block/ItemFrame.php | 17 ++--------------- src/pocketmine/block/Torch.php | 23 ++++------------------- 2 files changed, 6 insertions(+), 34 deletions(-) diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index f8414aed30..0c9f43e647 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -59,13 +59,7 @@ class ItemFrame extends Flowable{ } public function onNearbyBlockChange() : void{ - $sides = [ - 0 => Facing::WEST, - 1 => Facing::EAST, - 2 => Facing::NORTH, - 3 => Facing::SOUTH - ]; - if(!$this->getSide($sides[$this->meta])->isSolid()){ + if(!$this->getSide(Facing::opposite(5 - $this->meta))->isSolid()){ $this->level->useBreakOn($this); } } @@ -75,14 +69,7 @@ class ItemFrame extends Flowable{ return false; } - $faces = [ - Facing::NORTH => 3, - Facing::SOUTH => 2, - Facing::WEST => 1, - Facing::EAST => 0 - ]; - - $this->meta = $faces[$face]; + $this->meta = 5 - $face; if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ Tile::createTile(Tile::ITEM_FRAME, $this->getLevel(), TileItemFrame::createNBT($this, $face, $item, $player)); diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index bb41a87c7b..a4269ac6af 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -46,17 +46,9 @@ class Torch extends Flowable{ public function onNearbyBlockChange() : void{ $below = $this->getSide(Facing::DOWN); - $side = $this->getDamage(); - static $faces = [ - 0 => Facing::DOWN, - 1 => Facing::WEST, - 2 => Facing::EAST, - 3 => Facing::NORTH, - 4 => Facing::SOUTH, - 5 => Facing::DOWN - ]; + $face = $this->meta === 0 ? Facing::DOWN : Facing::opposite(6 - $this->meta); - if($this->getSide($faces[$side])->isTransparent() and !($faces[$side] === Facing::DOWN and ($below->getId() === self::FENCE or $below->getId() === self::COBBLESTONE_WALL))){ + if($this->getSide($face)->isTransparent() and !($face === Facing::DOWN and ($below->getId() === self::FENCE or $below->getId() === self::COBBLESTONE_WALL))){ $this->getLevel()->useBreakOn($this); } } @@ -65,18 +57,11 @@ class Torch extends Flowable{ $below = $this->getSide(Facing::DOWN); if(!$blockClicked->isTransparent() and $face !== Facing::DOWN){ - static $faces = [ - Facing::UP => 5, - Facing::NORTH => 4, - Facing::SOUTH => 3, - Facing::WEST => 2, - Facing::EAST => 1 - ]; - $this->meta = $faces[$face]; + $this->meta = 6 - $face; return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); }elseif(!$below->isTransparent() or $below->getId() === self::FENCE or $below->getId() === self::COBBLESTONE_WALL){ - $this->meta = 0; + $this->meta = 5; //attached to block below return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } From a80d5bb6a87ca88df3eaf0fc64a7c73ca50aa946 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Sep 2018 08:47:03 +0100 Subject: [PATCH 0151/3224] Leaf log search is type agnostic any wood type will do --- src/pocketmine/block/Leaves.php | 4 ++-- src/pocketmine/block/Leaves2.php | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 8ad5ae402a..5d32a721d1 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -40,7 +40,6 @@ class Leaves extends Transparent{ public const DARK_OAK = 1; protected $id = self::LEAVES; - protected $woodType = self::WOOD; public function __construct(int $meta = 0){ $this->setDamage($meta); @@ -76,7 +75,8 @@ class Leaves extends Transparent{ } $visited[$index] = true; - if($pos->getId() === $this->woodType){ + $id = $pos->getId(); + if($id === Block::WOOD or $id === Block::WOOD2){ return true; } diff --git a/src/pocketmine/block/Leaves2.php b/src/pocketmine/block/Leaves2.php index bd18ec7c26..3038e3319e 100644 --- a/src/pocketmine/block/Leaves2.php +++ b/src/pocketmine/block/Leaves2.php @@ -29,7 +29,6 @@ use pocketmine\item\ItemFactory; class Leaves2 extends Leaves{ protected $id = self::LEAVES2; - protected $woodType = self::WOOD2; public function getName() : string{ static $names = [ From 48a5eeb3a459cb90b302990d3f243a34b0bb7da0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Sep 2018 15:06:58 +0100 Subject: [PATCH 0152/3224] BlockFactory: remove some useless static arrays --- src/pocketmine/block/BlockFactory.php | 12 ------------ src/pocketmine/level/Level.php | 4 ++-- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index b5dee4f42f..6874db58ee 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -35,12 +35,6 @@ class BlockFactory{ /** @var \SplFixedArray */ public static $solid = null; - /** @var \SplFixedArray */ - public static $transparent = null; - /** @var \SplFixedArray */ - public static $hardness = null; - /** @var \SplFixedArray */ - public static $light = null; /** @var \SplFixedArray */ public static $lightFilter = null; /** @var \SplFixedArray */ @@ -64,11 +58,8 @@ class BlockFactory{ public static function init() : void{ self::$fullList = new \SplFixedArray(4096); - self::$light = new \SplFixedArray(256); self::$lightFilter = new \SplFixedArray(256); self::$solid = new \SplFixedArray(256); - self::$hardness = new \SplFixedArray(256); - self::$transparent = new \SplFixedArray(256); self::$diffusesSkyLight = new \SplFixedArray(256); self::$blastResistance = new \SplFixedArray(256); @@ -357,9 +348,6 @@ class BlockFactory{ } self::$solid[$id] = $block->isSolid(); - self::$transparent[$id] = $block->isTransparent(); - self::$hardness[$id] = $block->getHardness(); - self::$light[$id] = $block->getLightLevel(); self::$lightFilter[$id] = min(15, $block->getLightFilter() + 1); //opacity plus 1 standard light filter self::$diffusesSkyLight[$id] = $block->diffusesSkyLight(); self::$blastResistance[$id] = $block->getBlastResistance(); diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 3e27ab4986..6bee970082 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1463,8 +1463,8 @@ class Level implements ChunkManager, Metadatable{ public function updateBlockLight(int $x, int $y, int $z){ $this->timings->doBlockLightUpdates->startTiming(); - $id = $this->getBlockIdAt($x, $y, $z); - $newLevel = max(BlockFactory::$light[$id], $this->getHighestAdjacentBlockLight($x, $y, $z) - BlockFactory::$lightFilter[$id]); + $block = $this->getBlockAt($x, $y, $z); + $newLevel = max($block->getLightLevel(), $this->getHighestAdjacentBlockLight($x, $y, $z) - $block->getLightFilter()); if($this->blockLightUpdate === null){ $this->blockLightUpdate = new BlockLightUpdate($this); From ef038d962567122e6e5af8fda842f0f23a313da2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Sep 2018 15:07:24 +0100 Subject: [PATCH 0153/3224] Level: use block directly in updateBlockSkyLight() --- src/pocketmine/level/Level.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 6bee970082..8c025b4f85 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1404,14 +1404,14 @@ class Level implements ChunkManager, Metadatable{ $this->timings->doBlockSkyLightUpdates->startTiming(); $oldHeightMap = $this->getHeightMap($x, $z); - $sourceId = $this->getBlockIdAt($x, $y, $z); + $source = $this->getBlockAt($x, $y, $z); $yPlusOne = $y + 1; if($yPlusOne === $oldHeightMap){ //Block changed directly beneath the heightmap. Check if a block was removed or changed to a different light-filter. $newHeightMap = $this->getChunk($x >> 4, $z >> 4)->recalculateHeightMapColumn($x & 0x0f, $z & 0x0f); }elseif($yPlusOne > $oldHeightMap){ //Block changed above the heightmap. - if(BlockFactory::$lightFilter[$sourceId] > 1 or BlockFactory::$diffusesSkyLight[$sourceId]){ + if($source->getLightFilter() > 0 or $source->diffusesSkyLight()){ $this->setHeightMap($x, $z, $yPlusOne); $newHeightMap = $yPlusOne; }else{ //Block changed which has no effect on direct sky light, for example placing or removing glass. From dbe0ee2d44697de8370e4fae01778ca70c5a094e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Sep 2018 15:17:39 +0100 Subject: [PATCH 0154/3224] BlockFactory: don't pre-populate gaps with UnknownBlock objects this produces a minor reduction in memory usage. --- src/pocketmine/block/BlockFactory.php | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 6874db58ee..bdce2f63fc 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -58,10 +58,10 @@ class BlockFactory{ public static function init() : void{ self::$fullList = new \SplFixedArray(4096); - self::$lightFilter = new \SplFixedArray(256); - self::$solid = new \SplFixedArray(256); - self::$diffusesSkyLight = new \SplFixedArray(256); - self::$blastResistance = new \SplFixedArray(256); + self::$lightFilter = \SplFixedArray::fromArray(array_fill(0, 256, 1)); + self::$solid = \SplFixedArray::fromArray(array_fill(0, 256, false)); + self::$diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 256, false)); + self::$blastResistance = \SplFixedArray::fromArray(array_fill(0, 256, 0)); self::registerBlock(new Air()); self::registerBlock(new Stone()); @@ -313,12 +313,6 @@ class BlockFactory{ //TODO: STRUCTURE_BLOCK //TODO: RESERVED6 - - for($id = 0, $size = self::$fullList->getSize() >> 4; $id < $size; ++$id){ - if(self::$fullList[$id << 4] === null){ - self::registerBlock(new UnknownBlock($id)); - } - } } /** @@ -368,7 +362,7 @@ class BlockFactory{ } try{ - if(self::$fullList !== null){ + if(self::$fullList[($id << 4) | $meta] !== null){ $block = clone self::$fullList[($id << 4) | $meta]; }else{ $block = new UnknownBlock($id, $meta); From d291345ed7c5cc9112ac4bfbf99f2add2bf43aac Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Sep 2018 16:20:16 +0100 Subject: [PATCH 0155/3224] Clean up some unused imports --- src/pocketmine/Player.php | 1 - src/pocketmine/event/player/PlayerInteractEvent.php | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 7d6ee0bba3..471523998e 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -85,7 +85,6 @@ use pocketmine\lang\TranslationContainer; use pocketmine\level\ChunkLoader; use pocketmine\level\format\Chunk; use pocketmine\level\Level; -use pocketmine\level\Location; use pocketmine\level\Position; use pocketmine\math\Vector3; use pocketmine\metadata\MetadataValue; diff --git a/src/pocketmine/event/player/PlayerInteractEvent.php b/src/pocketmine/event/player/PlayerInteractEvent.php index 04f7cd2294..96b37937f7 100644 --- a/src/pocketmine/event/player/PlayerInteractEvent.php +++ b/src/pocketmine/event/player/PlayerInteractEvent.php @@ -24,10 +24,8 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\block\Block; -use pocketmine\block\BlockFactory; use pocketmine\event\Cancellable; use pocketmine\item\Item; -use pocketmine\level\Position; use pocketmine\math\Vector3; use pocketmine\Player; From 0f33459632394db8062b46c50f1b060a6f8dc090 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Sep 2018 16:20:54 +0100 Subject: [PATCH 0156/3224] missed this because it was too far to the right of the screen... --- src/pocketmine/level/Level.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 1c1b221cdf..a98a075810 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1426,7 +1426,7 @@ class Level implements ChunkManager, Metadatable{ $this->skyLightUpdate->setAndUpdateLight($x, $i, $z, 15); } }else{ //No heightmap change, block changed "underground" - $this->skyLightUpdate->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentBlockSkyLight($x, $y, $z) - BlockFactory::$lightFilter[$sourceId])); + $this->skyLightUpdate->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentBlockSkyLight($x, $y, $z) - BlockFactory::$lightFilter[$source->getId()])); } $this->timings->doBlockSkyLightUpdates->stopTiming(); From d92e79ba54de646a3e5822736d5e1d6d86e1a218 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Sep 2018 17:39:31 +0100 Subject: [PATCH 0157/3224] Level: fix crashdump #754691 --- src/pocketmine/level/Level.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index a98a075810..26b4ea743c 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -28,6 +28,7 @@ namespace pocketmine\level; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\UnknownBlock; use pocketmine\entity\Entity; use pocketmine\entity\object\ExperienceOrb; use pocketmine\entity\object\ItemEntity; @@ -1353,7 +1354,12 @@ class Level implements ChunkManager, Metadatable{ } } - $block = clone $this->blockStates[$fullState & 0xfff]; + $block = $this->blockStates[$fullState & 0xfff]; + if($block !== null){ + $block = clone $block; + }else{ + $block = new UnknownBlock($fullState >> 4, $fullState & 0xf); + } $block->x = $x; $block->y = $y; From 7da51ae97e93bb6220e814381bd38eb27b43a63b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 Sep 2018 17:51:28 +0100 Subject: [PATCH 0158/3224] Fixed ItemBlocks passing the wrong block name to their constructors --- src/pocketmine/item/ItemBlock.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/pocketmine/item/ItemBlock.php b/src/pocketmine/item/ItemBlock.php index 865c0470d4..4fa540b14d 100644 --- a/src/pocketmine/item/ItemBlock.php +++ b/src/pocketmine/item/ItemBlock.php @@ -40,6 +40,7 @@ class ItemBlock extends Item{ */ public function __construct(int $blockId, int $meta = 0, int $itemId = null){ $this->blockId = $blockId; + $this->setDamage($meta); parent::__construct($itemId ?? $blockId, $meta, $this->getBlock()->getName()); } @@ -47,10 +48,6 @@ class ItemBlock extends Item{ return BlockFactory::get($this->blockId, $this->meta === -1 ? 0 : $this->meta & 0xf); } - public function getVanillaName() : string{ - return $this->getBlock()->getName(); - } - public function getFuelTime() : int{ return $this->getBlock()->getFuelTime(); } From 668da0772a36354003847e1e5668f7773d8d2234 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 20 Sep 2018 12:49:36 +0100 Subject: [PATCH 0159/3224] WaterLily: fixed broken placement logic --- src/pocketmine/block/WaterLily.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/block/WaterLily.php b/src/pocketmine/block/WaterLily.php index edee10a13d..bd372c4f35 100644 --- a/src/pocketmine/block/WaterLily.php +++ b/src/pocketmine/block/WaterLily.php @@ -53,8 +53,8 @@ class WaterLily extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($blockClicked instanceof Water){ $up = $blockClicked->getSide(Facing::UP); - if($up->getId() === Block::AIR){ - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + if($up->canBeReplaced()){ + return parent::place($item, $up, $blockClicked, $face, $clickVector, $player); } } From 19e68f98a707536866c33bb1e9fad9f7c280447d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 20 Sep 2018 16:16:28 +0100 Subject: [PATCH 0160/3224] Level: Remove unnecessary BlockFactory::$lightFilter usage --- src/pocketmine/level/Level.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 26b4ea743c..14e7add6c1 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1432,7 +1432,7 @@ class Level implements ChunkManager, Metadatable{ $this->skyLightUpdate->setAndUpdateLight($x, $i, $z, 15); } }else{ //No heightmap change, block changed "underground" - $this->skyLightUpdate->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentBlockSkyLight($x, $y, $z) - BlockFactory::$lightFilter[$source->getId()])); + $this->skyLightUpdate->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentBlockSkyLight($x, $y, $z) - $source->getLightFilter())); } $this->timings->doBlockSkyLightUpdates->stopTiming(); From 9b4d82630b9b063e3bac87d89f95ebb20ba2bffd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 20 Sep 2018 16:26:15 +0100 Subject: [PATCH 0161/3224] BlockFactory: remove $solid this is premature optimization and will run into problems once we enter the flattening. --- src/pocketmine/block/BlockFactory.php | 4 ---- src/pocketmine/entity/Entity.php | 14 +++++++------- .../level/generator/object/SpruceTree.php | 2 +- src/pocketmine/level/generator/object/Tree.php | 2 +- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index bdce2f63fc..6089234ac5 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -33,8 +33,6 @@ class BlockFactory{ /** @var \SplFixedArray */ private static $fullList = null; - /** @var \SplFixedArray */ - public static $solid = null; /** @var \SplFixedArray */ public static $lightFilter = null; /** @var \SplFixedArray */ @@ -59,7 +57,6 @@ class BlockFactory{ self::$fullList = new \SplFixedArray(4096); self::$lightFilter = \SplFixedArray::fromArray(array_fill(0, 256, 1)); - self::$solid = \SplFixedArray::fromArray(array_fill(0, 256, false)); self::$diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 256, false)); self::$blastResistance = \SplFixedArray::fromArray(array_fill(0, 256, 0)); @@ -341,7 +338,6 @@ class BlockFactory{ self::$fullList[($id << 4) | $meta] = $variant; } - self::$solid[$id] = $block->isSolid(); self::$lightFilter[$id] = min(15, $block->getLightFilter() + 1); //opacity plus 1 standard light filter self::$diffusesSkyLight[$id] = $block->diffusesSkyLight(); self::$blastResistance[$id] = $block->getBlastResistance(); diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index bc4e5fc36b..bfeb108ab6 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -1194,13 +1194,13 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $diffY = $y - $floorY; $diffZ = $z - $floorZ; - if(BlockFactory::$solid[$this->level->getBlockIdAt($floorX, $floorY, $floorZ)]){ - $westNonSolid = !BlockFactory::$solid[$this->level->getBlockIdAt($floorX - 1, $floorY, $floorZ)]; - $eastNonSolid = !BlockFactory::$solid[$this->level->getBlockIdAt($floorX + 1, $floorY, $floorZ)]; - $downNonSolid = !BlockFactory::$solid[$this->level->getBlockIdAt($floorX, $floorY - 1, $floorZ)]; - $upNonSolid = !BlockFactory::$solid[$this->level->getBlockIdAt($floorX, $floorY + 1, $floorZ)]; - $northNonSolid = !BlockFactory::$solid[$this->level->getBlockIdAt($floorX, $floorY, $floorZ - 1)]; - $southNonSolid = !BlockFactory::$solid[$this->level->getBlockIdAt($floorX, $floorY, $floorZ + 1)]; + if($this->level->getBlockAt($floorX, $floorY, $floorZ)->isSolid()){ + $westNonSolid = !$this->level->getBlockAt($floorX - 1, $floorY, $floorZ)->isSolid(); + $eastNonSolid = !$this->level->getBlockAt($floorX + 1, $floorY, $floorZ)->isSolid(); + $downNonSolid = !$this->level->getBlockAt($floorX, $floorY - 1, $floorZ)->isSolid(); + $upNonSolid = !$this->level->getBlockAt($floorX, $floorY + 1, $floorZ)->isSolid(); + $northNonSolid = !$this->level->getBlockAt($floorX, $floorY, $floorZ - 1)->isSolid(); + $southNonSolid = !$this->level->getBlockAt($floorX, $floorY, $floorZ + 1)->isSolid(); $direction = -1; $limit = 9999; diff --git a/src/pocketmine/level/generator/object/SpruceTree.php b/src/pocketmine/level/generator/object/SpruceTree.php index eb09978c55..8201e20b41 100644 --- a/src/pocketmine/level/generator/object/SpruceTree.php +++ b/src/pocketmine/level/generator/object/SpruceTree.php @@ -61,7 +61,7 @@ class SpruceTree extends Tree{ continue; } - if(!BlockFactory::$solid[$level->getBlockIdAt($xx, $yyy, $zz)]){ + if(!BlockFactory::get($level->getBlockIdAt($xx, $yyy, $zz))->isSolid()){ $level->setBlockIdAt($xx, $yyy, $zz, $this->leafBlock); $level->setBlockDataAt($xx, $yyy, $zz, $this->type); } diff --git a/src/pocketmine/level/generator/object/Tree.php b/src/pocketmine/level/generator/object/Tree.php index e79dd6cb98..f25bcf4bc4 100644 --- a/src/pocketmine/level/generator/object/Tree.php +++ b/src/pocketmine/level/generator/object/Tree.php @@ -109,7 +109,7 @@ abstract class Tree{ if($xOff === $mid and $zOff === $mid and ($yOff === 0 or $random->nextBoundedInt(2) === 0)){ continue; } - if(!BlockFactory::$solid[$level->getBlockIdAt($xx, $yy, $zz)]){ + if(!BlockFactory::get($level->getBlockIdAt($xx, $yy, $zz))->isSolid()){ $level->setBlockIdAt($xx, $yy, $zz, $this->leafBlock); $level->setBlockDataAt($xx, $yy, $zz, $this->type); } From 56d9943b0d10832c6416b3a5983ec7038fb0efd2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 21 Sep 2018 19:28:10 +0100 Subject: [PATCH 0162/3224] Nuke Block->meta, split into variant and state properties, lots of cleanup This is a major change to the way block metadata is handled within the PM core. This separates variant metadata (which really ought to be part of the ID) from state metadata, and in a couple of cases flattens separate states of blocks together. The result of this is that invalid variants can be much more easily detected, and additionally state handling is much cleaner since meta is only needed at the serialize layer instead of throughout the code. --- src/pocketmine/Player.php | 1 + src/pocketmine/block/Air.php | 4 +- src/pocketmine/block/Anvil.php | 36 +-- src/pocketmine/block/BaseRail.php | 59 ++-- src/pocketmine/block/Bed.php | 74 +++-- src/pocketmine/block/Bedrock.php | 4 +- src/pocketmine/block/Beetroot.php | 6 +- src/pocketmine/block/Block.php | 53 ++-- src/pocketmine/block/BlockFactory.php | 296 ++++++++++++++---- src/pocketmine/block/BoneBlock.php | 14 +- src/pocketmine/block/Bookshelf.php | 4 +- src/pocketmine/block/BrewingStand.php | 29 +- src/pocketmine/block/BrickStairs.php | 4 +- src/pocketmine/block/Bricks.php | 4 +- src/pocketmine/block/BurningFurnace.php | 96 ------ src/pocketmine/block/Button.php | 26 +- src/pocketmine/block/Cactus.php | 29 +- src/pocketmine/block/Cake.php | 25 +- src/pocketmine/block/Carpet.php | 11 - src/pocketmine/block/Carrot.php | 6 +- src/pocketmine/block/Chest.php | 27 +- src/pocketmine/block/Clay.php | 4 +- src/pocketmine/block/Coal.php | 4 +- src/pocketmine/block/CoalOre.php | 4 +- src/pocketmine/block/Cobblestone.php | 4 +- src/pocketmine/block/CobblestoneStairs.php | 4 +- src/pocketmine/block/CobblestoneWall.php | 14 - src/pocketmine/block/Cobweb.php | 4 +- src/pocketmine/block/CocoaBlock.php | 30 +- src/pocketmine/block/Concrete.php | 11 - src/pocketmine/block/ConcretePowder.php | 13 +- src/pocketmine/block/CraftingTable.php | 4 +- src/pocketmine/block/Crops.php | 28 +- src/pocketmine/block/Dandelion.php | 4 +- src/pocketmine/block/DaylightSensor.php | 36 ++- src/pocketmine/block/DeadBush.php | 4 +- src/pocketmine/block/Diamond.php | 4 +- src/pocketmine/block/DiamondOre.php | 4 +- src/pocketmine/block/Dirt.php | 17 +- src/pocketmine/block/Door.php | 166 +++++----- src/pocketmine/block/DoublePlant.php | 60 ++-- src/pocketmine/block/DoubleSlab.php | 37 ++- src/pocketmine/block/DoubleStoneSlab.php | 47 --- src/pocketmine/block/DoubleStoneSlab2.php | 33 -- src/pocketmine/block/DoubleWoodenSlab.php | 49 --- src/pocketmine/block/Emerald.php | 4 +- src/pocketmine/block/EmeraldOre.php | 4 +- src/pocketmine/block/EnchantingTable.php | 4 +- src/pocketmine/block/EndPortalFrame.php | 36 ++- src/pocketmine/block/EndRod.php | 42 ++- src/pocketmine/block/EndStone.php | 4 +- src/pocketmine/block/EndStoneBricks.php | 4 +- src/pocketmine/block/EnderChest.php | 4 +- src/pocketmine/block/Farmland.php | 27 +- src/pocketmine/block/Fence.php | 4 - src/pocketmine/block/FenceGate.php | 40 ++- src/pocketmine/block/Fire.php | 33 +- src/pocketmine/block/Flower.php | 21 -- src/pocketmine/block/FlowerPot.php | 28 +- src/pocketmine/block/Furnace.php | 88 +++++- src/pocketmine/block/Glass.php | 10 - src/pocketmine/block/GlassPane.php | 10 - src/pocketmine/block/GlazedTerracotta.php | 22 +- src/pocketmine/block/GlowingObsidian.php | 4 +- src/pocketmine/block/GlowingRedstoneOre.php | 58 ---- src/pocketmine/block/Glowstone.php | 4 +- src/pocketmine/block/Gold.php | 4 +- src/pocketmine/block/GoldOre.php | 4 +- src/pocketmine/block/Grass.php | 4 +- src/pocketmine/block/GrassPath.php | 4 +- src/pocketmine/block/Gravel.php | 4 +- src/pocketmine/block/HardenedClay.php | 10 - src/pocketmine/block/HayBale.php | 14 +- src/pocketmine/block/Ice.php | 4 +- src/pocketmine/block/Iron.php | 4 +- src/pocketmine/block/IronBars.php | 8 +- src/pocketmine/block/IronDoor.php | 4 +- src/pocketmine/block/IronOre.php | 4 +- src/pocketmine/block/ItemFrame.php | 27 +- src/pocketmine/block/Ladder.php | 35 ++- src/pocketmine/block/Lapis.php | 4 +- src/pocketmine/block/LapisOre.php | 4 +- src/pocketmine/block/Lava.php | 16 +- src/pocketmine/block/Leaves.php | 70 ++--- src/pocketmine/block/Leaves2.php | 48 --- src/pocketmine/block/Lever.php | 92 ++++-- src/pocketmine/block/Liquid.php | 163 +++++----- src/pocketmine/block/LitRedstoneLamp.php | 37 --- src/pocketmine/block/Magma.php | 4 +- src/pocketmine/block/Melon.php | 4 +- src/pocketmine/block/MelonStem.php | 8 +- src/pocketmine/block/MonsterSpawner.php | 4 +- src/pocketmine/block/Mycelium.php | 4 +- src/pocketmine/block/NetherBrickFence.php | 4 + src/pocketmine/block/NetherBrickStairs.php | 4 +- src/pocketmine/block/NetherQuartzOre.php | 4 +- src/pocketmine/block/NetherReactor.php | 30 +- src/pocketmine/block/NetherWartBlock.php | 4 +- src/pocketmine/block/NetherWartPlant.php | 25 +- src/pocketmine/block/Netherrack.php | 4 +- src/pocketmine/block/NoteBlock.php | 4 +- src/pocketmine/block/Obsidian.php | 4 +- src/pocketmine/block/PackedIce.php | 4 +- src/pocketmine/block/Planks.php | 24 -- src/pocketmine/block/Podzol.php | 4 +- src/pocketmine/block/Potato.php | 6 +- src/pocketmine/block/Prismarine.php | 19 -- src/pocketmine/block/Pumpkin.php | 8 +- src/pocketmine/block/PumpkinStem.php | 8 +- src/pocketmine/block/Purpur.php | 12 - src/pocketmine/block/PurpurStairs.php | 4 +- src/pocketmine/block/Quartz.php | 27 +- src/pocketmine/block/QuartzStairs.php | 4 +- src/pocketmine/block/Rail.php | 4 +- src/pocketmine/block/RedMushroom.php | 4 +- src/pocketmine/block/RedMushroomBlock.php | 25 +- src/pocketmine/block/RedSandstone.php | 37 --- src/pocketmine/block/Redstone.php | 4 +- src/pocketmine/block/RedstoneLamp.php | 25 +- src/pocketmine/block/RedstoneOre.php | 48 ++- src/pocketmine/block/RedstoneRail.php | 20 +- src/pocketmine/block/RedstoneTorch.php | 19 +- src/pocketmine/block/RedstoneTorchUnlit.php | 37 --- src/pocketmine/block/Sand.php | 14 - src/pocketmine/block/Sandstone.php | 19 -- src/pocketmine/block/SandstoneStairs.php | 4 +- src/pocketmine/block/Sapling.php | 37 +-- src/pocketmine/block/SeaLantern.php | 4 +- src/pocketmine/block/SignPost.php | 29 +- src/pocketmine/block/Skull.php | 23 +- src/pocketmine/block/Slab.php | 66 ++-- src/pocketmine/block/Snow.php | 4 +- src/pocketmine/block/SnowLayer.php | 19 +- src/pocketmine/block/SoulSand.php | 4 +- src/pocketmine/block/Sponge.php | 19 +- src/pocketmine/block/StainedClay.php | 35 --- src/pocketmine/block/StainedGlass.php | 35 --- src/pocketmine/block/StainedGlassPane.php | 35 --- src/pocketmine/block/Stair.php | 49 +-- src/pocketmine/block/StandingBanner.php | 28 +- src/pocketmine/block/Stone.php | 23 +- src/pocketmine/block/StoneBrickStairs.php | 4 +- src/pocketmine/block/StoneBricks.php | 16 - src/pocketmine/block/StonePressurePlate.php | 23 +- src/pocketmine/block/StoneSlab.php | 28 -- src/pocketmine/block/StoneSlab2.php | 44 --- src/pocketmine/block/Stonecutter.php | 4 +- src/pocketmine/block/Sugarcane.php | 31 +- src/pocketmine/block/TNT.php | 4 +- src/pocketmine/block/TallGrass.php | 15 - src/pocketmine/block/Torch.php | 34 +- src/pocketmine/block/Trapdoor.php | 56 ++-- src/pocketmine/block/Tripwire.php | 25 +- src/pocketmine/block/TripwireHook.php | 40 ++- src/pocketmine/block/UnknownBlock.php | 9 + src/pocketmine/block/Vine.php | 85 ++--- src/pocketmine/block/WallBanner.php | 19 +- src/pocketmine/block/WallSign.php | 19 +- src/pocketmine/block/Water.php | 8 +- src/pocketmine/block/WaterLily.php | 8 +- .../block/WeightedPressurePlateLight.php | 23 +- src/pocketmine/block/Wheat.php | 6 +- src/pocketmine/block/Wood.php | 27 +- src/pocketmine/block/Wood2.php | 41 --- src/pocketmine/block/WoodenFence.php | 20 -- src/pocketmine/block/WoodenSlab.php | 18 +- src/pocketmine/block/Wool.php | 11 - .../block/utils/ColorBlockMetaHelper.php | 50 --- .../block/utils/PillarRotationHelper.php | 39 --- src/pocketmine/item/Bucket.php | 2 +- src/pocketmine/item/Dye.php | 10 + src/pocketmine/level/Level.php | 51 +-- src/pocketmine/level/biome/ForestBiome.php | 4 +- src/pocketmine/level/biome/TaigaBiome.php | 4 +- .../level/generator/object/Tree.php | 14 +- .../level/generator/populator/Tree.php | 4 +- src/pocketmine/tile/Furnace.php | 15 +- tests/phpunit/block/BlockTest.php | 16 +- 178 files changed, 2012 insertions(+), 2120 deletions(-) delete mode 100644 src/pocketmine/block/BurningFurnace.php delete mode 100644 src/pocketmine/block/DoubleStoneSlab.php delete mode 100644 src/pocketmine/block/DoubleStoneSlab2.php delete mode 100644 src/pocketmine/block/DoubleWoodenSlab.php delete mode 100644 src/pocketmine/block/GlowingRedstoneOre.php delete mode 100644 src/pocketmine/block/Leaves2.php delete mode 100644 src/pocketmine/block/LitRedstoneLamp.php delete mode 100644 src/pocketmine/block/RedSandstone.php delete mode 100644 src/pocketmine/block/RedstoneTorchUnlit.php delete mode 100644 src/pocketmine/block/StainedClay.php delete mode 100644 src/pocketmine/block/StainedGlass.php delete mode 100644 src/pocketmine/block/StainedGlassPane.php delete mode 100644 src/pocketmine/block/StoneSlab2.php delete mode 100644 src/pocketmine/block/Wood2.php delete mode 100644 src/pocketmine/block/utils/ColorBlockMetaHelper.php delete mode 100644 src/pocketmine/block/utils/PillarRotationHelper.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 471523998e..1489fd7812 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2448,6 +2448,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ public function handleItemFrameDropItem(ItemFrameDropItemPacket $packet) : bool{ $tile = $this->level->getTileAt($packet->x, $packet->y, $packet->z); if($tile instanceof ItemFrame){ + //TODO: use facing blockstate property instead of damage value $ev = new PlayerInteractEvent($this, $this->inventory->getItemInHand(), $tile->getBlock(), null, 5 - $tile->getBlock()->getDamage(), PlayerInteractEvent::LEFT_CLICK_BLOCK); if($this->isSpectator() or $this->level->checkSpawnProtection($this, $tile)){ $ev->setCancelled(); diff --git a/src/pocketmine/block/Air.php b/src/pocketmine/block/Air.php index 9984e3fe25..8451e5a19b 100644 --- a/src/pocketmine/block/Air.php +++ b/src/pocketmine/block/Air.php @@ -34,8 +34,8 @@ class Air extends Transparent{ protected $id = self::AIR; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index aa468082cd..d3212e03b3 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -28,6 +28,7 @@ use pocketmine\item\Item; use pocketmine\item\TieredTool; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -37,10 +38,19 @@ class Anvil extends Fallable{ public const TYPE_SLIGHTLY_DAMAGED = 4; public const TYPE_VERY_DAMAGED = 8; - protected $id = self::ANVIL; + /** @var int */ + protected $facing = Facing::NORTH; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + protected function writeStateToMeta() : int{ + return Bearing::fromFacing($this->facing); + } + + public function readStateFromMeta(int $meta) : void{ + $this->facing = Bearing::toFacing($meta); + } + + public function getStateBitmask() : int{ + return 0b11; } public function isTransparent() : bool{ @@ -55,19 +65,6 @@ class Anvil extends Fallable{ return 6000; } - public function getVariantBitmask() : int{ - return 0x0c; - } - - public function getName() : string{ - static $names = [ - self::TYPE_NORMAL => "Anvil", - self::TYPE_SLIGHTLY_DAMAGED => "Slightly Damaged Anvil", - self::TYPE_VERY_DAMAGED => "Very Damaged Anvil" - ]; - return $names[$this->getVariant()] ?? "Anvil"; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } @@ -79,7 +76,7 @@ class Anvil extends Fallable{ public function recalculateBoundingBox() : ?AxisAlignedBB{ $inset = 0.125; - if($this->meta & 0x01){ //east/west + if(Facing::axis($this->facing) === Facing::AXIS_X){ return new AxisAlignedBB(0, 0, $inset, 1, 1, 1 - $inset); }else{ return new AxisAlignedBB($inset, 0, 0, 1 - $inset, 1, 1); @@ -95,8 +92,9 @@ class Anvil extends Fallable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $direction = $player !== null ? Bearing::rotate($player->getDirection(), 1) : 0; - $this->meta = $this->getVariant() | $direction; + if($player !== null){ + $this->facing = Bearing::toFacing(Bearing::rotate($player->getDirection(), 1)); + } return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } } diff --git a/src/pocketmine/block/BaseRail.php b/src/pocketmine/block/BaseRail.php index d7a2096b99..b7a0d96b6a 100644 --- a/src/pocketmine/block/BaseRail.php +++ b/src/pocketmine/block/BaseRail.php @@ -37,13 +37,6 @@ abstract class BaseRail extends Flowable{ public const ASCENDING_NORTH = 4; public const ASCENDING_SOUTH = 5; - private const ASCENDING_SIDES = [ - self::ASCENDING_NORTH => Facing::NORTH, - self::ASCENDING_EAST => Facing::EAST, - self::ASCENDING_SOUTH => Facing::SOUTH, - self::ASCENDING_WEST => Facing::WEST - ]; - protected const FLAG_ASCEND = 1 << 24; //used to indicate direction-up protected const CONNECTIONS = [ @@ -76,8 +69,28 @@ abstract class BaseRail extends Flowable{ ] ]; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int[] */ + protected $connections = []; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + if(empty($this->connections)){ + return self::STRAIGHT_NORTH_SOUTH; + } + return $this->getMetaForState($this->connections); + } + + public function readStateFromMeta(int $meta) : void{ + //on invalid states, this will return an empty array, allowing this rail to transform into any other state + //TODO: should this throw instead? + $this->connections = $this->getConnectionsFromMeta($meta); + } + + public function getStateBitmask() : int{ + return 0b111; } public function getHardness() : float{ @@ -121,9 +134,11 @@ abstract class BaseRail extends Flowable{ /** * Returns the connection directions of this rail (depending on the current block state) * + * @param int $meta + * * @return int[] */ - abstract protected function getConnectionsForState() : array; + abstract protected function getConnectionsFromMeta(int $meta) : array; /** * Returns all the directions this rail is already connected in. @@ -135,7 +150,7 @@ abstract class BaseRail extends Flowable{ $connections = []; /** @var int $connection */ - foreach($this->getConnectionsForState() as $connection){ + foreach($this->connections as $connection){ $other = $this->getSide($connection & ~self::FLAG_ASCEND); $otherConnection = Facing::opposite($connection & ~self::FLAG_ASCEND); @@ -149,7 +164,7 @@ abstract class BaseRail extends Flowable{ if( $other instanceof BaseRail and - in_array($otherConnection, $other->getConnectionsForState(), true) + in_array($otherConnection, $other->connections, true) ){ $connections[] = $connection; } @@ -248,20 +263,20 @@ abstract class BaseRail extends Flowable{ throw new \InvalidArgumentException("Expected exactly 2 connections, got " . count($connections)); } - $this->meta = $this->getMetaForState($connections); + $this->connections = $connections; $this->level->setBlock($this, $this, false, false); //avoid recursion } public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::DOWN)->isTransparent() or ( - isset(self::ASCENDING_SIDES[$this->meta & 0x07]) and - $this->getSide(self::ASCENDING_SIDES[$this->meta & 0x07])->isTransparent() - )){ - $this->getLevel()->useBreakOn($this); + if($this->getSide(Facing::DOWN)->isTransparent()){ + $this->level->useBreakOn($this); + }else{ + foreach($this->connections as $connection){ + if(($connection & self::FLAG_ASCEND) !== 0 and $this->getSide($connection & ~self::FLAG_ASCEND)->isTransparent()){ + $this->level->useBreakOn($this); + break; + } + } } } - - public function getVariantBitmask() : int{ - return 0; - } } diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index d0dfb28fd7..0e98356f1f 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -37,15 +37,38 @@ use pocketmine\tile\Tile; use pocketmine\utils\TextFormat; class Bed extends Transparent{ - public const BITFLAG_OCCUPIED = 0x04; - public const BITFLAG_HEAD = 0x08; + private const BITFLAG_OCCUPIED = 0x04; + private const BITFLAG_HEAD = 0x08; protected $id = self::BED_BLOCK; protected $itemId = Item::BED; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $facing = Facing::NORTH; + /** @var bool */ + protected $occupied = false; + /** @var bool */ + protected $head = false; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return Bearing::fromFacing($this->facing) | + ($this->occupied ? self::BITFLAG_OCCUPIED : 0) | + ($this->head ? self::BITFLAG_HEAD : 0); + } + + public function readStateFromMeta(int $meta) : void{ + $this->facing = Bearing::toFacing($meta & 0x03); + $this->occupied = ($meta & self::BITFLAG_OCCUPIED) !== 0; + $this->head = ($meta & self::BITFLAG_HEAD) !== 0; + } + + public function getStateBitmask() : int{ + return 0b1111; } public function getHardness() : float{ @@ -61,51 +84,39 @@ class Bed extends Transparent{ } public function isHeadPart() : bool{ - return ($this->meta & self::BITFLAG_HEAD) !== 0; + return $this->head; } /** * @return bool */ public function isOccupied() : bool{ - return ($this->meta & self::BITFLAG_OCCUPIED) !== 0; + return $this->occupied; } public function setOccupied(bool $occupied = true){ - if($occupied){ - $this->meta |= self::BITFLAG_OCCUPIED; - }else{ - $this->meta &= ~self::BITFLAG_OCCUPIED; - } + $this->occupied = $occupied; + $this->level->setBlock($this, $this, false, false); - $this->getLevel()->setBlock($this, $this, false, false); - - if(($other = $this->getOtherHalf()) !== null and $other->isOccupied() !== $occupied){ - $other->setOccupied($occupied); + if(($other = $this->getOtherHalf()) !== null){ + $other->occupied = $occupied; + $this->level->setBlock($other, $other, false, false); } } /** - * @param int $meta - * @param bool $isHead - * * @return int */ - public static function getOtherHalfSide(int $meta, bool $isHead = false) : int{ - $side = Bearing::toFacing($meta & 0x03); - if($isHead){ - $side = Facing::opposite($side); - } - - return $side; + private function getOtherHalfSide() : int{ + return $this->head ? Facing::opposite($this->facing) : $this->facing; } /** * @return Bed|null */ public function getOtherHalf() : ?Bed{ - $other = $this->getSide(self::getOtherHalfSide($this->meta, $this->isHeadPart())); - if($other instanceof Bed and $other->getId() === $this->getId() and $other->isHeadPart() !== $this->isHeadPart() and (($other->getDamage() & 0x03) === ($this->getDamage() & 0x03))){ + $other = $this->getSide($this->getOtherHalfSide()); + if($other instanceof Bed and $other->head !== $this->head and $other->facing === $this->facing){ return $other; } @@ -152,11 +163,14 @@ class Bed extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if(!$down->isTransparent()){ - $this->meta = $player instanceof Player ? $player->getDirection() : 0; - $next = $this->getSide(self::getOtherHalfSide($this->meta)); + $this->facing = $player !== null ? Bearing::toFacing($player->getDirection()) : Facing::NORTH; + + $next = $this->getSide($this->getOtherHalfSide()); if($next->canBeReplaced() and !$next->getSide(Facing::DOWN)->isTransparent()){ parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); - $this->getLevel()->setBlock($next, BlockFactory::get($this->id, $this->meta | self::BITFLAG_HEAD), true, true); + $nextState = clone $this; + $nextState->head = true; + $this->getLevel()->setBlock($next, $nextState, true, true); Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($this, $face, $item, $player)); Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($next, $face, $item, $player)); diff --git a/src/pocketmine/block/Bedrock.php b/src/pocketmine/block/Bedrock.php index 403fc495d5..c17173855f 100644 --- a/src/pocketmine/block/Bedrock.php +++ b/src/pocketmine/block/Bedrock.php @@ -29,8 +29,8 @@ class Bedrock extends Solid{ protected $id = self::BEDROCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/Beetroot.php b/src/pocketmine/block/Beetroot.php index 783fe6e09a..c63d3f86fc 100644 --- a/src/pocketmine/block/Beetroot.php +++ b/src/pocketmine/block/Beetroot.php @@ -30,16 +30,12 @@ class Beetroot extends Crops{ protected $id = self::BEETROOT_BLOCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - public function getName() : string{ return "Beetroot Block"; } public function getDropsForCompatibleTool(Item $item) : array{ - if($this->meta >= 0x07){ + if($this->age >= 7){ return [ ItemFactory::get(Item::BEETROOT), ItemFactory::get(Item::BEETROOT_SEEDS, 0, mt_rand(0, 3)) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 20d195dfa2..bdb8871d73 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -60,7 +60,7 @@ class Block extends Position implements BlockIds, Metadatable{ /** @var int */ protected $id; /** @var int */ - protected $meta = 0; + protected $variant = 0; /** @var string|null */ protected $fallbackName; /** @var int|null */ @@ -74,14 +74,18 @@ class Block extends Position implements BlockIds, Metadatable{ protected $collisionBoxes = null; /** - * @param int $id The block type's ID, 0-255 - * @param int $meta Meta value of the block type - * @param string|null $name English name of the block type (TODO: implement translations) - * @param int $itemId The item ID of the block type, used for block picking and dropping items. + * @param int $id The block type's ID, 0-255 + * @param int $variant Meta value of the block type + * @param string|null $name English name of the block type (TODO: implement translations) + * @param int $itemId The item ID of the block type, used for block picking and dropping items. */ - public function __construct(int $id, int $meta = 0, string $name = null, int $itemId = null){ + public function __construct(int $id, int $variant = 0, string $name = null, int $itemId = null){ $this->id = $id; - $this->meta = $meta; + + if(($variant & $this->getStateBitmask()) !== 0){ + throw new \InvalidArgumentException("Variant 0x" . dechex($variant) . " collides with state bitmask 0x" . dechex($this->getStateBitmask())); + } + $this->variant = $variant; $this->fallbackName = $name; $this->itemId = $itemId; } @@ -122,30 +126,26 @@ class Block extends Position implements BlockIds, Metadatable{ * @return int */ public function getDamage() : int{ - return $this->meta; + $stateMeta = $this->writeStateToMeta(); + assert(($stateMeta & ~$this->getStateBitmask()) === 0); + return $this->variant | $stateMeta; + } + + protected function writeStateToMeta() : int{ + return 0; + } + + public function readStateFromMeta(int $meta) : void{ + //NOOP } /** - * @param int $meta - */ - public function setDamage(int $meta) : void{ - if($meta < 0 or $meta > 0xf){ - throw new \InvalidArgumentException("Block damage values must be 0-15, not $meta"); - } - $this->meta = $meta; - } - - /** - * Bitmask to use to remove superfluous information from block meta when getting its item form or name. - * This defaults to -1 (don't remove any data). Used to remove rotation data and bitflags from block drops. - * - * If your block should not have any meta value when it's dropped as an item, override this to return 0 in - * descendent classes. + * Returns a bitmask used to extract state bits from block metadata. * * @return int */ - public function getVariantBitmask() : int{ - return -1; + public function getStateBitmask() : int{ + return 0; } /** @@ -153,10 +153,9 @@ class Block extends Position implements BlockIds, Metadatable{ * @return int */ public function getVariant() : int{ - return $this->meta & $this->getVariantBitmask(); + return $this->variant; } - /** * AKA: Block->isPlaceable * @return bool diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 6089234ac5..f8a091ce7f 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\Color; +use pocketmine\block\utils\WoodType; use pocketmine\item\Item; use pocketmine\level\Position; @@ -32,6 +34,8 @@ use pocketmine\level\Position; class BlockFactory{ /** @var \SplFixedArray */ private static $fullList = null; + /** @var \SplFixedArray|\Closure[] */ + private static $getInterceptors = null; /** @var \SplFixedArray */ public static $lightFilter = null; @@ -40,6 +44,9 @@ class BlockFactory{ /** @var \SplFixedArray */ public static $blastResistance = null; + /** @var \SplFixedArray|int[] */ + public static $stateMasks = null; + /** @var int[] */ public static $staticRuntimeIdMap = []; @@ -55,56 +62,138 @@ class BlockFactory{ */ public static function init() : void{ self::$fullList = new \SplFixedArray(4096); + self::$getInterceptors = new \SplFixedArray(4096); self::$lightFilter = \SplFixedArray::fromArray(array_fill(0, 256, 1)); self::$diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 256, false)); self::$blastResistance = \SplFixedArray::fromArray(array_fill(0, 256, 0)); + self::$stateMasks = \SplFixedArray::fromArray(array_fill(0, 256, 0)); + self::registerBlock(new Air()); - self::registerBlock(new Stone()); + + //TODO: give smooth stone its own class (different drops) + self::registerBlock(new Stone(Block::STONE, Stone::NORMAL, "Stone")); + self::registerBlock(new Stone(Block::STONE, Stone::GRANITE, "Granite")); + self::registerBlock(new Stone(Block::STONE, Stone::POLISHED_GRANITE, "Polished Granite")); + self::registerBlock(new Stone(Block::STONE, Stone::DIORITE, "Diorite")); + self::registerBlock(new Stone(Block::STONE, Stone::POLISHED_DIORITE, "Polished Diorite")); + self::registerBlock(new Stone(Block::STONE, Stone::ANDESITE, "Andesite")); + self::registerBlock(new Stone(Block::STONE, Stone::POLISHED_ANDESITE, "Polished Andesite")); + self::registerBlock(new Grass()); - self::registerBlock(new Dirt()); + + //TODO: split these into separate classes + self::registerBlock(new Dirt(Block::DIRT, Dirt::NORMAL, "Dirt")); + self::registerBlock(new Dirt(Block::DIRT, Dirt::COARSE, "Coarse Dirt")); + self::registerBlock(new Cobblestone()); - self::registerBlock(new Planks()); - self::registerBlock(new Sapling()); + + foreach(WoodType::ALL as $type){ + self::registerBlock(new Planks(Block::PLANKS, $type, WoodType::NAMES[$type] . " Planks")); + self::registerBlock(new Sapling(Block::SAPLING, $type, WoodType::NAMES[$type] . " Sapling")); + self::registerBlock(new WoodenFence(Block::FENCE, $type, WoodType::NAMES[$type] . " Fence")); + } + + foreach(WoodType::ALL as $type){ + //TODO: find a better way to deal with this split + self::registerBlock(new Wood($type >= 4 ? Block::WOOD2 : Block::WOOD, $type & 0x03, WoodType::NAMES[$type] . " Wood")); + self::registerBlock(new Leaves($type >= 4 ? Block::LEAVES2 : Block::LEAVES, $type & 0x03, $type, WoodType::NAMES[$type] . " Leaves")); + } + self::registerBlock(new Bedrock()); self::registerBlock(new Water()); self::registerBlock(new StillWater()); self::registerBlock(new Lava()); self::registerBlock(new StillLava()); - self::registerBlock(new Sand()); + + self::registerBlock(new Sand(Block::SAND, 0, "Sand")); + self::registerBlock(new Sand(Block::SAND, 1, "Red Sand")); + self::registerBlock(new Gravel()); self::registerBlock(new GoldOre()); self::registerBlock(new IronOre()); self::registerBlock(new CoalOre()); - self::registerBlock(new Wood()); - self::registerBlock(new Leaves()); self::registerBlock(new Sponge()); - self::registerBlock(new Glass()); + self::registerBlock(new Glass(Block::GLASS, 0, "Glass")); self::registerBlock(new LapisOre()); self::registerBlock(new Lapis()); //TODO: DISPENSER - self::registerBlock(new Sandstone()); + + static $sandstoneTypes = [ + Sandstone::NORMAL => "", + Sandstone::CHISELED => "Chiseled ", + Sandstone::SMOOTH => "Smooth " + ]; + foreach($sandstoneTypes as $variant => $prefix){ + self::registerBlock(new Sandstone(Block::SANDSTONE, $variant, $prefix . "Sandstone")); + self::registerBlock(new Sandstone(Block::RED_SANDSTONE, $variant, $prefix . "Red Sandstone")); + } + self::registerBlock(new NoteBlock()); self::registerBlock(new Bed()); self::registerBlock(new PoweredRail()); self::registerBlock(new DetectorRail()); //TODO: STICKY_PISTON self::registerBlock(new Cobweb()); - self::registerBlock(new TallGrass()); + + self::registerBlock(new TallGrass(Block::TALL_GRASS, 0, "Fern")); + self::registerBlock(new TallGrass(Block::TALL_GRASS, 1, "Tall Grass")); + self::registerBlock(new TallGrass(Block::TALL_GRASS, 2, "Fern")); + self::registerBlock(new TallGrass(Block::TALL_GRASS, 3, "Fern")); + self::registerBlock(new DeadBush()); //TODO: PISTON //TODO: PISTONARMCOLLISION - self::registerBlock(new Wool()); + + foreach(Color::ALL as $color){ + self::registerBlock(new Wool(Block::WOOL, $color, Color::NAMES[$color] . " Wool")); + self::registerBlock(new HardenedClay(Block::STAINED_CLAY, $color, Color::NAMES[$color] . " Stained Clay")); + self::registerBlock(new Glass(Block::STAINED_GLASS, $color, Color::NAMES[$color] . " Stained Glass")); + self::registerBlock(new GlassPane(Block::STAINED_GLASS_PANE, $color, Color::NAMES[$color] . " Stained Glass Pane")); + self::registerBlock(new Carpet(Block::CARPET, $color, Color::NAMES[$color] . " Carpet")); + self::registerBlock(new Concrete(Block::CONCRETE, $color, Color::NAMES[$color] . " Concrete")); + self::registerBlock(new ConcretePowder(Block::CONCRETE_POWDER, $color, Color::NAMES[$color] . " Concrete Powder")); + } self::registerBlock(new Dandelion()); - self::registerBlock(new Flower()); + + self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_POPPY, "Poppy")); + self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_BLUE_ORCHID, "Blue Orchid")); + self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_ALLIUM, "Allium")); + self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_AZURE_BLUET, "Azure Bluet")); + self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_RED_TULIP, "Red Tulip")); + self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_ORANGE_TULIP, "Orange Tulip")); + self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_WHITE_TULIP, "White Tulip")); + self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_PINK_TULIP, "Pink Tulip")); + self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_OXEYE_DAISY, "Oxeye Daisy")); + self::registerBlock(new BrownMushroom()); self::registerBlock(new RedMushroom()); self::registerBlock(new Gold()); self::registerBlock(new Iron()); - self::registerBlock(new DoubleStoneSlab()); - self::registerBlock(new StoneSlab()); + + /** @var Slab[] $slabTypes */ + $slabTypes = [ + new StoneSlab(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 0, "Stone"), + new StoneSlab(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 1, "Sandstone"), + new StoneSlab(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 2, "Fake Wooden"), + new StoneSlab(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 3, "Cobblestone"), + new StoneSlab(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 4, "Brick"), + new StoneSlab(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 5, "Stone Brick"), + new StoneSlab(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 6, "Quartz"), + new StoneSlab(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 7, "Nether Brick"), + new StoneSlab(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 0, "Red Sandstone"), + new StoneSlab(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 1, "Purpur") + ]; + foreach(WoodType::ALL as $woodType){ + $slabTypes[] = new WoodenSlab($woodType); + } + foreach($slabTypes as $type){ + self::registerBlock($type); + self::registerBlock(new DoubleSlab($type->getDoubleSlabId(), $type->getId(), $type->getVariant())); + } + self::registerBlock(new Bricks()); self::registerBlock(new TNT()); self::registerBlock(new Bookshelf()); @@ -121,8 +210,16 @@ class BlockFactory{ self::registerBlock(new CraftingTable()); self::registerBlock(new Wheat()); self::registerBlock(new Farmland()); + self::registerBlock(new Furnace()); - self::registerBlock(new BurningFurnace()); + self::addGetInterceptor(Block::BURNING_FURNACE, 0, function() : Block{ + $block = self::get(Block::FURNACE); + if($block instanceof Furnace){ + $block->setLit(); + } + return $block; + }); + self::registerBlock(new SignPost()); self::registerBlock(new WoodenDoor(Block::OAK_DOOR_BLOCK, 0, "Oak Door", Item::OAK_DOOR)); self::registerBlock(new Ladder()); @@ -134,9 +231,23 @@ class BlockFactory{ self::registerBlock(new IronDoor()); self::registerBlock(new WoodenPressurePlate()); self::registerBlock(new RedstoneOre()); - self::registerBlock(new GlowingRedstoneOre()); - self::registerBlock(new RedstoneTorchUnlit()); + self::addGetInterceptor(Block::GLOWING_REDSTONE_ORE, 0, function() : Block{ + $block = self::get(Block::REDSTONE_ORE); + if($block instanceof RedstoneOre){ + $block->setLit(); + } + return $block; + }); + self::registerBlock(new RedstoneTorch()); + self::addGetInterceptor(Block::UNLIT_REDSTONE_TORCH, 0, function() : Block{ + $block = self::get(Block::REDSTONE_TORCH); + if($block instanceof RedstoneTorch){ + $block->setLit(false); //default state is lit + } + return $block; + }); + self::registerBlock(new StoneButton()); self::registerBlock(new SnowLayer()); self::registerBlock(new Ice()); @@ -145,7 +256,7 @@ class BlockFactory{ self::registerBlock(new Clay()); self::registerBlock(new Sugarcane()); //TODO: JUKEBOX - self::registerBlock(new WoodenFence()); + self::registerBlock(new Pumpkin()); self::registerBlock(new Netherrack()); self::registerBlock(new SoulSand()); @@ -158,11 +269,16 @@ class BlockFactory{ //TODO: INVISIBLEBEDROCK self::registerBlock(new Trapdoor()); //TODO: MONSTER_EGG - self::registerBlock(new StoneBricks()); + + self::registerBlock(new StoneBricks(Block::STONE_BRICKS, StoneBricks::NORMAL, "Stone Bricks")); + self::registerBlock(new StoneBricks(Block::STONE_BRICKS, StoneBricks::MOSSY, "Mossy Stone Bricks")); + self::registerBlock(new StoneBricks(Block::STONE_BRICKS, StoneBricks::CRACKED, "Cracked Stone Bricks")); + self::registerBlock(new StoneBricks(Block::STONE_BRICKS, StoneBricks::CHISELED, "Chiseled Stone Bricks")); + self::registerBlock(new BrownMushroomBlock()); self::registerBlock(new RedMushroomBlock()); self::registerBlock(new IronBars()); - self::registerBlock(new GlassPane()); + self::registerBlock(new GlassPane(Block::GLASS_PANE, 0, "Glass Pane")); self::registerBlock(new Melon()); self::registerBlock(new PumpkinStem()); self::registerBlock(new MelonStem()); @@ -184,7 +300,14 @@ class BlockFactory{ self::registerBlock(new EndStone()); //TODO: DRAGON_EGG self::registerBlock(new RedstoneLamp()); - self::registerBlock(new LitRedstoneLamp()); + self::addGetInterceptor(Block::LIT_REDSTONE_LAMP, 0, function() : Block{ + $block = self::get(Block::REDSTONE_LAMP); + if($block instanceof RedstoneLamp){ + $block->setLit(); + } + return $block; + }); + //TODO: DROPPER self::registerBlock(new ActivatorRail()); self::registerBlock(new CocoaBlock()); @@ -199,50 +322,76 @@ class BlockFactory{ self::registerBlock(new WoodenStairs(Block::JUNGLE_STAIRS, 0, "Jungle Stairs")); //TODO: COMMAND_BLOCK //TODO: BEACON - self::registerBlock(new CobblestoneWall()); + + self::registerBlock(new CobblestoneWall(Block::COBBLESTONE_WALL, CobblestoneWall::NONE_MOSSY_WALL, "Cobblestone Wall")); + self::registerBlock(new CobblestoneWall(Block::COBBLESTONE_WALL, CobblestoneWall::MOSSY_WALL, "Mossy Cobblestone Wall")); + self::registerBlock(new FlowerPot()); self::registerBlock(new Carrot()); self::registerBlock(new Potato()); self::registerBlock(new WoodenButton()); self::registerBlock(new Skull()); - self::registerBlock(new Anvil()); + + self::registerBlock(new Anvil(Block::ANVIL, Anvil::TYPE_NORMAL, "Anvil")); + self::registerBlock(new Anvil(Block::ANVIL, Anvil::TYPE_SLIGHTLY_DAMAGED, "Slightly Damaged Anvil")); + self::registerBlock(new Anvil(Block::ANVIL, Anvil::TYPE_VERY_DAMAGED, "Very Damaged Anvil")); + self::registerBlock(new TrappedChest()); self::registerBlock(new WeightedPressurePlateLight()); self::registerBlock(new WeightedPressurePlateHeavy()); //TODO: COMPARATOR_BLOCK //TODO: POWERED_COMPARATOR self::registerBlock(new DaylightSensor()); + self::addGetInterceptor(Block::DAYLIGHT_SENSOR_INVERTED, 0, function() : Block{ + $block = self::get(Block::DAYLIGHT_SENSOR); + if($block instanceof DaylightSensor){ + $block->setInverted(); + } + return $block; + }); + self::registerBlock(new Redstone()); self::registerBlock(new NetherQuartzOre()); //TODO: HOPPER_BLOCK - self::registerBlock(new Quartz()); + + self::registerBlock(new Quartz(Block::QUARTZ_BLOCK, Quartz::NORMAL, "Quartz Block")); + self::registerBlock(new Quartz(Block::QUARTZ_BLOCK, Quartz::CHISELED, "Chiseled Quartz Block")); + self::registerBlock(new Quartz(Block::QUARTZ_BLOCK, Quartz::PILLAR, "Quartz Pillar")); + + self::registerBlock(new Purpur(Block::PURPUR_BLOCK, Purpur::NORMAL, "Purpur Block")); + self::registerBlock(new Purpur(Block::PURPUR_BLOCK, Purpur::PILLAR, "Purpur Pillar")); + self::registerBlock(new QuartzStairs()); - self::registerBlock(new DoubleWoodenSlab()); - self::registerBlock(new WoodenSlab()); - self::registerBlock(new StainedClay()); - self::registerBlock(new StainedGlassPane()); - self::registerBlock(new Leaves2()); - self::registerBlock(new Wood2()); + self::registerBlock(new WoodenStairs(Block::ACACIA_STAIRS, 0, "Acacia Stairs")); self::registerBlock(new WoodenStairs(Block::DARK_OAK_STAIRS, 0, "Dark Oak Stairs")); //TODO: SLIME self::registerBlock(new IronTrapdoor()); - self::registerBlock(new Prismarine()); + + self::registerBlock(new Prismarine(Block::PRISMARINE, Prismarine::NORMAL, "Prismarine")); + self::registerBlock(new Prismarine(Block::PRISMARINE, Prismarine::DARK, "Dark Prismarine")); + self::registerBlock(new Prismarine(Block::PRISMARINE, Prismarine::BRICKS, "Prismarine Bricks")); + self::registerBlock(new SeaLantern()); self::registerBlock(new HayBale()); - self::registerBlock(new Carpet()); - self::registerBlock(new HardenedClay()); + + self::registerBlock(new HardenedClay(Block::HARDENED_CLAY, 0, "Hardened Clay")); self::registerBlock(new Coal()); self::registerBlock(new PackedIce()); - self::registerBlock(new DoublePlant()); + + self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 0, "Sunflower")); + self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 1, "Lilac")); + //TODO: double tallgrass and large fern have different behaviour than the others, so they should get their own classes + self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 2, "Double Tallgrass")); + self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 3, "Large Fern")); + self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 4, "Rose Bush")); + self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 5, "Peony")); + self::registerBlock(new StandingBanner()); self::registerBlock(new WallBanner()); - //TODO: DAYLIGHT_DETECTOR_INVERTED - self::registerBlock(new RedSandstone()); + self::registerBlock(new RedSandstoneStairs()); - self::registerBlock(new DoubleStoneSlab2()); - self::registerBlock(new StoneSlab2()); self::registerBlock(new FenceGate(Block::SPRUCE_FENCE_GATE, 0, "Spruce Fence Gate")); self::registerBlock(new FenceGate(Block::BIRCH_FENCE_GATE, 0, "Birch Fence Gate")); self::registerBlock(new FenceGate(Block::JUNGLE_FENCE_GATE, 0, "Jungle Fence Gate")); @@ -259,7 +408,6 @@ class BlockFactory{ self::registerBlock(new GrassPath()); self::registerBlock(new ItemFrame()); //TODO: CHORUS_FLOWER - self::registerBlock(new Purpur()); self::registerBlock(new PurpurStairs()); @@ -292,11 +440,8 @@ class BlockFactory{ self::registerBlock(new GlazedTerracotta(Block::GREEN_GLAZED_TERRACOTTA, 0, "Green Glazed Terracotta")); self::registerBlock(new GlazedTerracotta(Block::RED_GLAZED_TERRACOTTA, 0, "Red Glazed Terracotta")); self::registerBlock(new GlazedTerracotta(Block::BLACK_GLAZED_TERRACOTTA, 0, "Black Glazed Terracotta")); - self::registerBlock(new Concrete()); - self::registerBlock(new ConcretePowder()); //TODO: CHORUS_PLANT - self::registerBlock(new StainedGlass()); self::registerBlock(new Podzol()); self::registerBlock(new Beetroot()); @@ -327,20 +472,17 @@ class BlockFactory{ */ public static function registerBlock(Block $block, bool $override = false) : void{ $id = $block->getId(); + $variant = $block->getVariant(); - if(!$override and self::isRegistered($id)){ + if(!$override and self::isRegistered($id, $variant)){ throw new \RuntimeException("Trying to overwrite an already registered block"); } - for($meta = 0; $meta < 16; ++$meta){ - $variant = clone $block; - $variant->setDamage($meta); - self::$fullList[($id << 4) | $meta] = $variant; + self::$fullList[($id << 4) | $variant] = clone $block; + if($variant === 0){ + //TODO: allow these to differ for different variants + self::fillStaticArrays($id, $block); } - - self::$lightFilter[$id] = min(15, $block->getLightFilter() + 1); //opacity plus 1 standard light filter - self::$diffusesSkyLight[$id] = $block->diffusesSkyLight(); - self::$blastResistance[$id] = $block->getBlastResistance(); } /** @@ -357,16 +499,34 @@ class BlockFactory{ throw new \InvalidArgumentException("Block meta value $meta is out of bounds"); } + if(self::$stateMasks[$id] === null){ + $variant = 0; + $state = $meta; + }else{ + $variant = $meta & ~self::$stateMasks[$id]; + $state = $meta & self::$stateMasks[$id]; + } + + $index = ($id << 4) | $variant; + + /** @var Block|null $block */ + $block = null; try{ - if(self::$fullList[($id << 4) | $meta] !== null){ - $block = clone self::$fullList[($id << 4) | $meta]; - }else{ - $block = new UnknownBlock($id, $meta); + if(self::$getInterceptors[$index] !== null){ + $block = (self::$getInterceptors[$index])(); + }elseif(self::$fullList[$index] !== null){ + $block = clone self::$fullList[$index]; } }catch(\RuntimeException $e){ throw new \InvalidArgumentException("Block ID $id is out of bounds"); } + if($block !== null){ + $block->readStateFromMeta($state); + }else{ + $block = new UnknownBlock($id, $meta); + } + if($pos !== null){ $block->x = $pos->getFloorX(); $block->y = $pos->getFloorY(); @@ -377,22 +537,32 @@ class BlockFactory{ return $block; } - /** - * @internal - * @return \SplFixedArray - */ - public static function getBlockStatesArray() : \SplFixedArray{ - return self::$fullList; + public static function addGetInterceptor(int $id, int $variant, \Closure $interceptor) : void{ + $block = $interceptor(); + if(!($block instanceof Block)){ + throw new \InvalidArgumentException("Interceptor must return an instance of " . Block::class); + } + self::$getInterceptors[($id << 4) | $variant] = $interceptor; + self::fillStaticArrays($id, $block); + } + + private static function fillStaticArrays(int $id, Block $block) : void{ + self::$lightFilter[$id] = min(15, $block->getLightFilter() + 1); //opacity plus 1 standard light filter + self::$diffusesSkyLight[$id] = $block->diffusesSkyLight(); + self::$blastResistance[$id] = $block->getBlastResistance(); + self::$stateMasks[$id] = $block->getStateBitmask(); } /** * Returns whether a specified block ID is already registered in the block factory. * * @param int $id + * @param int $variant + * * @return bool */ - public static function isRegistered(int $id) : bool{ - $b = self::$fullList[$id << 4]; + public static function isRegistered(int $id, int $variant = 0) : bool{ + $b = self::$fullList[($id << 4) | $variant]; return $b !== null and !($b instanceof UnknownBlock); } diff --git a/src/pocketmine/block/BoneBlock.php b/src/pocketmine/block/BoneBlock.php index 1eb7e11f5c..f632cfcc23 100644 --- a/src/pocketmine/block/BoneBlock.php +++ b/src/pocketmine/block/BoneBlock.php @@ -23,18 +23,20 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\PillarRotationHelper; +use pocketmine\block\utils\PillarRotationTrait; use pocketmine\item\Item; use pocketmine\item\TieredTool; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; class BoneBlock extends Solid{ + use PillarRotationTrait; protected $id = Block::BONE_BLOCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ @@ -54,11 +56,7 @@ class BoneBlock extends Solid{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $this->meta = PillarRotationHelper::getMetaFromFace($this->meta, $face); + $this->axis = Facing::axis($face); return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - - public function getVariantBitmask() : int{ - return 0x03; - } } diff --git a/src/pocketmine/block/Bookshelf.php b/src/pocketmine/block/Bookshelf.php index 3ae90a3ed2..417109f648 100644 --- a/src/pocketmine/block/Bookshelf.php +++ b/src/pocketmine/block/Bookshelf.php @@ -30,8 +30,8 @@ class Bookshelf extends Solid{ protected $id = self::BOOKSHELF; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/BrewingStand.php b/src/pocketmine/block/BrewingStand.php index 4d9cc18833..21bbfed483 100644 --- a/src/pocketmine/block/BrewingStand.php +++ b/src/pocketmine/block/BrewingStand.php @@ -32,8 +32,29 @@ class BrewingStand extends Transparent{ protected $itemId = Item::BREWING_STAND; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var bool */ + protected $eastSlot = false; + /** @var bool */ + protected $northwestSlot = false; + /** @var bool */ + protected $southwestSlot = false; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return ($this->eastSlot ? 0x01 : 0) | ($this->southwestSlot ? 0x02 : 0) | ($this->northwestSlot ? 0x04 : 0); + } + + public function readStateFromMeta(int $meta) : void{ + $this->eastSlot = ($meta & 0x01) !== 0; + $this->southwestSlot = ($meta & 0x02) !== 0; + $this->northwestSlot = ($meta & 0x04) !== 0; + } + + public function getStateBitmask() : int{ + return 0b111; } public function getName() : string{ @@ -52,9 +73,5 @@ class BrewingStand extends Transparent{ return TieredTool::TIER_WOODEN; } - public function getVariantBitmask() : int{ - return 0; - } - //TODO } diff --git a/src/pocketmine/block/BrickStairs.php b/src/pocketmine/block/BrickStairs.php index 490c2697fe..d8fd303935 100644 --- a/src/pocketmine/block/BrickStairs.php +++ b/src/pocketmine/block/BrickStairs.php @@ -29,8 +29,8 @@ class BrickStairs extends Stair{ protected $id = self::BRICK_STAIRS; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getHardness() : float{ diff --git a/src/pocketmine/block/Bricks.php b/src/pocketmine/block/Bricks.php index f18963ca14..ee50e8d6a6 100644 --- a/src/pocketmine/block/Bricks.php +++ b/src/pocketmine/block/Bricks.php @@ -29,8 +29,8 @@ class Bricks extends Solid{ protected $id = self::BRICK_BLOCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getHardness() : float{ diff --git a/src/pocketmine/block/BurningFurnace.php b/src/pocketmine/block/BurningFurnace.php deleted file mode 100644 index 2371b1ad2a..0000000000 --- a/src/pocketmine/block/BurningFurnace.php +++ /dev/null @@ -1,96 +0,0 @@ -setDamage($meta); - } - - public function getName() : string{ - return "Burning Furnace"; - } - - public function getHardness() : float{ - return 3.5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; - } - - public function getLightLevel() : int{ - return 13; - } - - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if($player !== null){ - $this->meta = Bearing::toFacing(Bearing::opposite($player->getDirection())); - } - if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - Tile::createTile(Tile::FURNACE, $this->getLevel(), TileFurnace::createNBT($this, $face, $item, $player)); - return true; - } - - return false; - } - - public function onActivate(Item $item, Player $player = null) : bool{ - if($player instanceof Player){ - $furnace = $this->getLevel()->getTile($this); - if(!($furnace instanceof TileFurnace)){ - $furnace = Tile::createTile(Tile::FURNACE, $this->getLevel(), TileFurnace::createNBT($this)); - } - - if(!$furnace->canOpenWith($item->getCustomName())){ - return true; - } - - $player->addWindow($furnace->getInventory()); - } - - return true; - } - - public function getVariantBitmask() : int{ - return 0; - } -} diff --git a/src/pocketmine/block/Button.php b/src/pocketmine/block/Button.php index 2c1dbaf588..9dc3291599 100644 --- a/src/pocketmine/block/Button.php +++ b/src/pocketmine/block/Button.php @@ -24,22 +24,38 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; abstract class Button extends Flowable{ - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $facing = Facing::DOWN; + /** @var bool */ + protected $powered = false; + + public function __construct(){ + } - public function getVariantBitmask() : int{ - return 0; + protected function writeStateToMeta() : int{ + return $this->facing | ($this->powered ? 0x08 : 0); + } + + public function readStateFromMeta(int $meta) : void{ + //TODO: in PC it's (6 - facing) for every meta except 0 (down) + $this->facing = $meta & 0x07; + $this->powered = ($meta & 0x08) !== 0; + } + + public function getStateBitmask() : int{ + return 0b1111; } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ //TODO: check valid target block - $this->meta = $face; + $this->facing = $face; return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index fcf5c4a562..97c10529db 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -38,8 +38,23 @@ class Cactus extends Transparent{ protected $id = self::CACTUS; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $age = 0; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return $this->age; + } + + public function readStateFromMeta(int $meta) : void{ + $this->age = $meta; + } + + public function getStateBitmask() : int{ + return 0b1111; } public function getHardness() : float{ @@ -85,7 +100,7 @@ class Cactus extends Transparent{ public function onRandomTick() : void{ if($this->getSide(Facing::DOWN)->getId() !== self::CACTUS){ - if($this->meta === 0x0f){ + if($this->age === 15){ for($y = 1; $y < 3; ++$y){ $b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z); if($b->getId() === self::AIR){ @@ -95,10 +110,10 @@ class Cactus extends Transparent{ } } } - $this->meta = 0; + $this->age = 0; $this->getLevel()->setBlock($this, $this); }else{ - ++$this->meta; + ++$this->age; $this->getLevel()->setBlock($this, $this); } } @@ -118,8 +133,4 @@ class Cactus extends Transparent{ return false; } - - public function getVariantBitmask() : int{ - return 0; - } } diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index 07de3fc467..f082ba2bd7 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -38,8 +38,23 @@ class Cake extends Transparent implements FoodSource{ protected $itemId = Item::CAKE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $bites = 0; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return $this->bites; + } + + public function readStateFromMeta(int $meta) : void{ + $this->bites = $meta; + } + + public function getStateBitmask() : int{ + return 0b111; } public function getHardness() : float{ @@ -51,7 +66,7 @@ class Cake extends Transparent implements FoodSource{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - $f = $this->getDamage() * 0.125; //1 slice width + $f = $this->bites * 0.125; //1 slice width return new AxisAlignedBB( 0.0625 + $f, @@ -112,8 +127,8 @@ class Cake extends Transparent implements FoodSource{ */ public function getResidue(){ $clone = clone $this; - $clone->meta++; - if($clone->meta > 0x06){ + $clone->bites++; + if($clone->bites > 6){ $clone = BlockFactory::get(Block::AIR); } return $clone; diff --git a/src/pocketmine/block/Carpet.php b/src/pocketmine/block/Carpet.php index 92310cc338..b9ca2d13d4 100644 --- a/src/pocketmine/block/Carpet.php +++ b/src/pocketmine/block/Carpet.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\ColorBlockMetaHelper; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -32,12 +31,6 @@ use pocketmine\Player; class Carpet extends Flowable{ - protected $id = self::CARPET; - - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - public function getHardness() : float{ return 0.1; } @@ -46,10 +39,6 @@ class Carpet extends Flowable{ return true; } - public function getName() : string{ - return ColorBlockMetaHelper::getColorFromMeta($this->meta) . " Carpet"; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ return new AxisAlignedBB(0, 0, 0, 1, 0.0625, 1); } diff --git a/src/pocketmine/block/Carrot.php b/src/pocketmine/block/Carrot.php index 9ca50c2246..20af72d1da 100644 --- a/src/pocketmine/block/Carrot.php +++ b/src/pocketmine/block/Carrot.php @@ -30,17 +30,13 @@ class Carrot extends Crops{ protected $id = self::CARROT_BLOCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - public function getName() : string{ return "Carrot Block"; } public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::CARROT, 0, $this->meta >= 0x07 ? mt_rand(1, 4) : 1) + ItemFactory::get(Item::CARROT, 0, $this->age >= 7 ? mt_rand(1, 4) : 1) ]; } diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index ddec85663e..a4ccd0522f 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -36,8 +36,23 @@ class Chest extends Transparent{ protected $id = self::CHEST; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $facing = Facing::NORTH; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return $this->facing; + } + + public function readStateFromMeta(int $meta) : void{ + $this->facing = $meta; + } + + public function getStateBitmask() : int{ + return 0b111; } public function getHardness() : float{ @@ -60,7 +75,7 @@ class Chest extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $chest = null; if($player !== null){ - $this->meta = Bearing::toFacing(Bearing::opposite($player->getDirection())); + $this->facing = Bearing::toFacing(Bearing::opposite($player->getDirection())); } foreach([ @@ -68,7 +83,7 @@ class Chest extends Transparent{ Bearing::toFacing(Bearing::rotate($player->getDirection(), 1)) ] as $side){ $c = $this->getSide($side); - if($c->getId() === $this->id and $c->getDamage() === $this->meta){ + if($c instanceof Chest and $c->getId() === $this->getId() and $c->facing === $this->facing){ $tile = $this->getLevel()->getTile($c); if($tile instanceof TileChest and !$tile->isPaired()){ $chest = $tile; @@ -116,10 +131,6 @@ class Chest extends Transparent{ return true; } - public function getVariantBitmask() : int{ - return 0; - } - public function getFuelTime() : int{ return 300; } diff --git a/src/pocketmine/block/Clay.php b/src/pocketmine/block/Clay.php index 2fb26fd99a..cc279b2be4 100644 --- a/src/pocketmine/block/Clay.php +++ b/src/pocketmine/block/Clay.php @@ -30,8 +30,8 @@ class Clay extends Solid{ protected $id = self::CLAY_BLOCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getHardness() : float{ diff --git a/src/pocketmine/block/Coal.php b/src/pocketmine/block/Coal.php index eb6f609a1e..36686bee76 100644 --- a/src/pocketmine/block/Coal.php +++ b/src/pocketmine/block/Coal.php @@ -29,8 +29,8 @@ class Coal extends Solid{ protected $id = self::COAL_BLOCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getHardness() : float{ diff --git a/src/pocketmine/block/CoalOre.php b/src/pocketmine/block/CoalOre.php index f440fa2c37..065c391b9a 100644 --- a/src/pocketmine/block/CoalOre.php +++ b/src/pocketmine/block/CoalOre.php @@ -31,8 +31,8 @@ class CoalOre extends Solid{ protected $id = self::COAL_ORE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getHardness() : float{ diff --git a/src/pocketmine/block/Cobblestone.php b/src/pocketmine/block/Cobblestone.php index dd9cce576f..212a858753 100644 --- a/src/pocketmine/block/Cobblestone.php +++ b/src/pocketmine/block/Cobblestone.php @@ -29,8 +29,8 @@ class Cobblestone extends Solid{ protected $id = self::COBBLESTONE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getToolType() : int{ diff --git a/src/pocketmine/block/CobblestoneStairs.php b/src/pocketmine/block/CobblestoneStairs.php index 4670b4957f..b67c1a75de 100644 --- a/src/pocketmine/block/CobblestoneStairs.php +++ b/src/pocketmine/block/CobblestoneStairs.php @@ -29,8 +29,8 @@ class CobblestoneStairs extends Stair{ protected $id = self::COBBLESTONE_STAIRS; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getHardness() : float{ diff --git a/src/pocketmine/block/CobblestoneWall.php b/src/pocketmine/block/CobblestoneWall.php index 0e2ee42f50..85a2dab8fc 100644 --- a/src/pocketmine/block/CobblestoneWall.php +++ b/src/pocketmine/block/CobblestoneWall.php @@ -31,12 +31,6 @@ class CobblestoneWall extends Transparent{ public const NONE_MOSSY_WALL = 0; public const MOSSY_WALL = 1; - protected $id = self::COBBLESTONE_WALL; - - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } @@ -49,14 +43,6 @@ class CobblestoneWall extends Transparent{ return 2; } - public function getName() : string{ - if($this->meta === 0x01){ - return "Mossy Cobblestone Wall"; - } - - return "Cobblestone Wall"; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ //walls don't have any special collision boxes like fences do diff --git a/src/pocketmine/block/Cobweb.php b/src/pocketmine/block/Cobweb.php index d75ee1cfea..cdffe07da2 100644 --- a/src/pocketmine/block/Cobweb.php +++ b/src/pocketmine/block/Cobweb.php @@ -31,8 +31,8 @@ class Cobweb extends Flowable{ protected $id = self::COBWEB; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function hasEntityCollision() : bool{ diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index 663e8f42c6..554533ef87 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -23,12 +23,38 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\item\Item; +use pocketmine\item\ItemFactory; +use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Bearing; +use pocketmine\math\Facing; +use pocketmine\math\Vector3; +use pocketmine\Player; + class CocoaBlock extends Transparent{ protected $id = self::COCOA_BLOCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $facing = Facing::NORTH; + /** @var int */ + protected $age = 0; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return Bearing::fromFacing(Facing::opposite($this->facing)) | ($this->age << 2); + } + + public function readStateFromMeta(int $meta) : void{ + $this->facing = Facing::opposite(Bearing::toFacing($meta & 0x03)); + $this->age = $meta >> 2; + } + + public function getStateBitmask() : int{ + return 0b1111; } public function getName() : string{ diff --git a/src/pocketmine/block/Concrete.php b/src/pocketmine/block/Concrete.php index 42d427a1b3..0b8673ab6f 100644 --- a/src/pocketmine/block/Concrete.php +++ b/src/pocketmine/block/Concrete.php @@ -23,21 +23,10 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\ColorBlockMetaHelper; use pocketmine\item\TieredTool; class Concrete extends Solid{ - protected $id = Block::CONCRETE; - - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - - public function getName() : string{ - return ColorBlockMetaHelper::getColorFromMeta($this->meta) . " Concrete"; - } - public function getHardness() : float{ return 1.8; } diff --git a/src/pocketmine/block/ConcretePowder.php b/src/pocketmine/block/ConcretePowder.php index a43f688a3c..5eff4ef028 100644 --- a/src/pocketmine/block/ConcretePowder.php +++ b/src/pocketmine/block/ConcretePowder.php @@ -23,21 +23,10 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\ColorBlockMetaHelper; use pocketmine\math\Facing; class ConcretePowder extends Fallable{ - protected $id = self::CONCRETE_POWDER; - - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - - public function getName() : string{ - return ColorBlockMetaHelper::getColorFromMeta($this->meta) . " Concrete Powder"; - } - public function getHardness() : float{ return 0.5; } @@ -70,7 +59,7 @@ class ConcretePowder extends Fallable{ continue; } if($this->getSide($i) instanceof Water){ - return BlockFactory::get(Block::CONCRETE, $this->meta); + return BlockFactory::get(Block::CONCRETE, $this->variant); } } diff --git a/src/pocketmine/block/CraftingTable.php b/src/pocketmine/block/CraftingTable.php index a0ce8ce3bf..1576e389d2 100644 --- a/src/pocketmine/block/CraftingTable.php +++ b/src/pocketmine/block/CraftingTable.php @@ -31,8 +31,8 @@ class CraftingTable extends Solid{ protected $id = self::CRAFTING_TABLE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getHardness() : float{ diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index f92f94add5..e890fa3dd4 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -31,6 +31,24 @@ use pocketmine\Player; use pocketmine\Server; abstract class Crops extends Flowable{ + /** @var int */ + protected $age = 0; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return $this->age; + } + + public function readStateFromMeta(int $meta) : void{ + $this->age = $meta; + } + + public function getStateBitmask() : int{ + return 0b111; + } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($blockReplace->getSide(Facing::DOWN)->getId() === Block::FARMLAND){ @@ -44,9 +62,9 @@ abstract class Crops extends Flowable{ public function onActivate(Item $item, Player $player = null) : bool{ if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal $block = clone $this; - $block->meta += mt_rand(2, 5); - if($block->meta > 7){ - $block->meta = 7; + $block->age += mt_rand(2, 5); + if($block->age > 7){ + $block->age = 7; } Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block)); @@ -75,9 +93,9 @@ abstract class Crops extends Flowable{ public function onRandomTick() : void{ if(mt_rand(0, 2) === 1){ - if($this->meta < 0x07){ + if($this->age < 7){ $block = clone $this; - ++$block->meta; + ++$block->age; Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block)); if(!$ev->isCancelled()){ diff --git a/src/pocketmine/block/Dandelion.php b/src/pocketmine/block/Dandelion.php index 50b887d93b..15be4a8711 100644 --- a/src/pocketmine/block/Dandelion.php +++ b/src/pocketmine/block/Dandelion.php @@ -32,8 +32,8 @@ class Dandelion extends Flowable{ protected $id = self::DANDELION; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/DaylightSensor.php b/src/pocketmine/block/DaylightSensor.php index 708667600f..7ffe1377ea 100644 --- a/src/pocketmine/block/DaylightSensor.php +++ b/src/pocketmine/block/DaylightSensor.php @@ -25,10 +25,40 @@ namespace pocketmine\block; class DaylightSensor extends Transparent{ - protected $id = self::DAYLIGHT_SENSOR; + protected $itemId = self::DAYLIGHT_SENSOR; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $power = 0; + + /** @var bool */ + protected $inverted = false; + + public function __construct(){ + + } + + public function getId() : int{ + return $this->inverted ? self::DAYLIGHT_SENSOR_INVERTED : self::DAYLIGHT_SENSOR; + } + + protected function writeStateToMeta() : int{ + return $this->power; + } + + public function readStateFromMeta(int $meta) : void{ + $this->power = $meta; + } + + public function getStateBitmask() : int{ + return 0b1111; + } + + public function isInverted() : bool{ + return $this->inverted; + } + + public function setInverted(bool $inverted = true) : void{ + $this->inverted = $inverted; } public function getName() : string{ diff --git a/src/pocketmine/block/DeadBush.php b/src/pocketmine/block/DeadBush.php index d32afc18c0..9cfd5a51d1 100644 --- a/src/pocketmine/block/DeadBush.php +++ b/src/pocketmine/block/DeadBush.php @@ -33,8 +33,8 @@ class DeadBush extends Flowable{ protected $id = self::DEAD_BUSH; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/Diamond.php b/src/pocketmine/block/Diamond.php index 3a6f66aa70..83a7935b64 100644 --- a/src/pocketmine/block/Diamond.php +++ b/src/pocketmine/block/Diamond.php @@ -29,8 +29,8 @@ class Diamond extends Solid{ protected $id = self::DIAMOND_BLOCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getHardness() : float{ diff --git a/src/pocketmine/block/DiamondOre.php b/src/pocketmine/block/DiamondOre.php index a789d9d45a..a6a0576076 100644 --- a/src/pocketmine/block/DiamondOre.php +++ b/src/pocketmine/block/DiamondOre.php @@ -31,8 +31,8 @@ class DiamondOre extends Solid{ protected $id = self::DIAMOND_ORE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getHardness() : float{ diff --git a/src/pocketmine/block/Dirt.php b/src/pocketmine/block/Dirt.php index 89a4e519d1..fea10f3e20 100644 --- a/src/pocketmine/block/Dirt.php +++ b/src/pocketmine/block/Dirt.php @@ -28,12 +28,8 @@ use pocketmine\item\Item; use pocketmine\Player; class Dirt extends Solid{ - - protected $id = self::DIRT; - - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } + public const NORMAL = 0; + public const COARSE = 1; public function getHardness() : float{ return 0.5; @@ -43,17 +39,10 @@ class Dirt extends Solid{ return BlockToolType::TYPE_SHOVEL; } - public function getName() : string{ - if($this->meta === 1){ - return "Coarse Dirt"; - } - return "Dirt"; - } - public function onActivate(Item $item, Player $player = null) : bool{ if($item instanceof Hoe){ $item->applyDamage(1); - if($this->meta === 1){ + if($this->variant === self::COARSE){ $this->getLevel()->setBlock($this, BlockFactory::get(Block::DIRT), true); }else{ $this->getLevel()->setBlock($this, BlockFactory::get(Block::FARMLAND), true); diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index a0371f49eb..31edd423d3 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -33,41 +33,72 @@ use pocketmine\Player; abstract class Door extends Transparent{ + /** @var int */ + protected $facing = Facing::NORTH; + /** @var bool */ + protected $top = false; + /** @var bool */ + protected $hingeRight = false; + + /** @var bool */ + protected $open = false; + /** @var bool */ + protected $powered = false; + + + protected function writeStateToMeta() : int{ + if($this->top){ + return 0x08 | ($this->hingeRight ? 0x01 : 0) | ($this->powered ? 0x02 : 0); + } + + return Bearing::rotate(Bearing::fromFacing($this->facing), 1) | ($this->open ? 0x04 : 0); + } + + public function readStateFromMeta(int $meta) : void{ + $this->top = $meta & 0x08; + if($this->top){ + $this->hingeRight = ($meta & 0x01) !== 0; + $this->powered = ($meta & 0x02) !== 0; + }else{ + $this->facing = Bearing::toFacing(Bearing::rotate($meta & 0x03, -1)); + $this->open = ($meta & 0x04) !== 0; + } + } + + public function getStateBitmask() : int{ + return 0b1111; + } + + /** + * Copies door properties from the other half of the door, since metadata is split between the two halves. + * TODO: the blockstate should be updated directly on creation so these properties can be detected in advance. + */ + private function updateStateFromOtherHalf() : void{ + $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); + if($other instanceof Door and $other->getId() === $this->getId()){ + if($this->top){ + $this->facing = $other->facing; + $this->open = $other->open; + }else{ + $this->hingeRight = $other->hingeRight; + $this->powered = $other->powered; + } + } + } public function isSolid() : bool{ return false; } - private function getFullDamage(){ - $damage = $this->getDamage(); - $isUp = ($damage & 0x08) > 0; - - if($isUp){ - $down = $this->getSide(Facing::DOWN)->getDamage(); - $up = $damage; - }else{ - $down = $damage; - $up = $this->getSide(Facing::UP)->getDamage(); - } - - $isRight = ($up & 0x01) > 0; - - return $down & 0x07 | ($isUp ? 8 : 0) | ($isRight ? 0x10 : 0); - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ $f = 0.1875; - $damage = $this->getFullDamage(); + $this->updateStateFromOtherHalf(); $bb = new AxisAlignedBB(0, 0, 0, 1, 2, 1); - $j = $damage & 0x03; - $isOpen = (($damage & 0x04) > 0); - $isRight = (($damage & 0x10) > 0); - - if($j === 0){ - if($isOpen){ - if(!$isRight){ + if($this->facing === Facing::EAST){ + if($this->open){ + if(!$this->hingeRight){ $bb->setBounds(0, 0, 0, 1, 1, $f); }else{ $bb->setBounds(0, 0, 1 - $f, 1, 1, 1); @@ -75,9 +106,9 @@ abstract class Door extends Transparent{ }else{ $bb->setBounds(0, 0, 0, $f, 1, 1); } - }elseif($j === 1){ - if($isOpen){ - if(!$isRight){ + }elseif($this->facing === Facing::SOUTH){ + if($this->open){ + if(!$this->hingeRight){ $bb->setBounds(1 - $f, 0, 0, 1, 1, 1); }else{ $bb->setBounds(0, 0, 0, $f, 1, 1); @@ -85,9 +116,9 @@ abstract class Door extends Transparent{ }else{ $bb->setBounds(0, 0, 0, 1, 1, $f); } - }elseif($j === 2){ - if($isOpen){ - if(!$isRight){ + }elseif($this->facing === Facing::WEST){ + if($this->open){ + if(!$this->hingeRight){ $bb->setBounds(0, 0, 1 - $f, 1, 1, 1); }else{ $bb->setBounds(0, 0, 0, 1, 1, $f); @@ -95,9 +126,9 @@ abstract class Door extends Transparent{ }else{ $bb->setBounds(1 - $f, 0, 0, 1, 1, 1); } - }elseif($j === 3){ - if($isOpen){ - if(!$isRight){ + }elseif($this->facing === Facing::NORTH){ + if($this->open){ + if(!$this->hingeRight){ $bb->setBounds(0, 0, 0, $f, 1, 1); }else{ $bb->setBounds(1 - $f, 0, 0, 1, 1, 1); @@ -127,21 +158,22 @@ abstract class Door extends Transparent{ return false; } - //door faces this way when opened (unless it's right, in which case it's the opposite) - $direction = $player !== null ? Bearing::rotate($player->getDirection(), 1) : Bearing::NORTH; - - $facing = Bearing::toFacing($direction); - $next = $this->getSide(Facing::opposite($facing)); - $next2 = $this->getSide($facing); - - $metaUp = 0x08; - if($next->getId() === $this->getId() or (!$next2->isTransparent() and $next->isTransparent())){ //Door hinge - $metaUp |= 0x01; + if($player !== null){ + $this->facing = Bearing::toFacing($player->getDirection()); } - $this->setDamage($direction); + $next = $this->getSide(Facing::rotate($this->facing, Facing::AXIS_Y, false)); + $next2 = $this->getSide(Facing::rotate($this->facing, Facing::AXIS_Y, true)); + + if($next->getId() === $this->getId() or (!$next2->isTransparent() and $next->isTransparent())){ //Door hinge + $this->hingeRight = true; + } + + $topHalf = clone $this; + $topHalf->top = true; + parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); - $this->getLevel()->setBlock($blockUp, BlockFactory::get($this->getId(), $metaUp), true); //Top + $this->level->setBlock($blockUp, $topHalf, true); //Top return true; } @@ -149,31 +181,23 @@ abstract class Door extends Transparent{ } public function onActivate(Item $item, Player $player = null) : bool{ - if(($this->getDamage() & 0x08) === 0x08){ //Top - $down = $this->getSide(Facing::DOWN); - if($down->getId() === $this->getId()){ - $meta = $down->getDamage() ^ 0x04; - $this->level->setBlock($down, BlockFactory::get($this->getId(), $meta), true); - $this->level->addSound(new DoorSound($this)); - return true; - } + $this->updateStateFromOtherHalf(); + $this->open = !$this->open; - return false; - }else{ - $this->meta ^= 0x04; - $this->level->setBlock($this, $this, true); - $this->level->addSound(new DoorSound($this)); + $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); + if($other instanceof Door and $this->getId() === $other->getId()){ + $other->open = $this->open; + $this->level->setBlock($other, $other, true, true); } + $this->level->setBlock($this, $this, true, true); + $this->level->addSound(new DoorSound($this)); + return true; } - public function getVariantBitmask() : int{ - return 0; - } - public function getDropsForCompatibleTool(Item $item) : array{ - if(($this->meta & 0x08) === 0){ //bottom half only + if(!$this->top){ //bottom half only return parent::getDropsForCompatibleTool($item); } @@ -185,18 +209,10 @@ abstract class Door extends Transparent{ } public function getAffectedBlocks() : array{ - if(($this->getDamage() & 0x08) === 0x08){ - $down = $this->getSide(Facing::DOWN); - if($down->getId() === $this->getId()){ - return [$this, $down]; - } - }else{ - $up = $this->getSide(Facing::UP); - if($up->getId() === $this->getId()){ - return [$this, $up]; - } + $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); + if($other->getId() === $this->getId()){ + return [$this, $other]; } - return parent::getAffectedBlocks(); } } diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index 1c9317de58..8f11b1e9c8 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -30,35 +30,34 @@ use pocketmine\math\Vector3; use pocketmine\Player; class DoublePlant extends Flowable{ - public const BITFLAG_TOP = 0x08; + private const BITFLAG_TOP = 0x08; - protected $id = self::DOUBLE_PLANT; + /** @var bool */ + protected $top = false; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + protected function writeStateToMeta() : int{ + return ($this->top ? self::BITFLAG_TOP : 0); + } + + public function readStateFromMeta(int $meta) : void{ + $this->top = ($meta & self::BITFLAG_TOP) !== 0; + } + + public function getStateBitmask() : int{ + return 0b1000; } public function canBeReplaced() : bool{ - return $this->meta === 2 or $this->meta === 3; //grass or fern - } - - public function getName() : string{ - static $names = [ - 0 => "Sunflower", - 1 => "Lilac", - 2 => "Double Tallgrass", - 3 => "Large Fern", - 4 => "Rose Bush", - 5 => "Peony" - ]; - return $names[$this->getVariant()] ?? ""; + return $this->variant === 2 or $this->variant === 3; //grass or fern } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $id = $blockReplace->getSide(Facing::DOWN)->getId(); if(($id === Block::GRASS or $id === Block::DIRT) and $blockReplace->getSide(Facing::UP)->canBeReplaced()){ $this->getLevel()->setBlock($blockReplace, $this, false, false); - $this->getLevel()->setBlock($blockReplace->getSide(Facing::UP), BlockFactory::get($this->id, $this->meta | self::BITFLAG_TOP), false, false); + $top = clone $this; + $top->top = true; + $this->getLevel()->setBlock($blockReplace->getSide(Facing::UP), $top, false, false); return true; } @@ -71,39 +70,32 @@ class DoublePlant extends Flowable{ * @return bool */ public function isValidHalfPlant() : bool{ - if($this->meta & self::BITFLAG_TOP){ - $other = $this->getSide(Facing::DOWN); - }else{ - $other = $this->getSide(Facing::UP); - } + $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); return ( + $other instanceof DoublePlant and $other->getId() === $this->getId() and - $other->getVariant() === $this->getVariant() and - ($other->getDamage() & self::BITFLAG_TOP) !== ($this->getDamage() & self::BITFLAG_TOP) + $other->getVariant() === $this->variant and + $other->top !== $this->top ); } public function onNearbyBlockChange() : void{ - if(!$this->isValidHalfPlant() or (($this->meta & self::BITFLAG_TOP) === 0 and $this->getSide(Facing::DOWN)->isTransparent())){ + if(!$this->isValidHalfPlant() or (!$this->top and $this->getSide(Facing::DOWN)->isTransparent())){ $this->getLevel()->useBreakOn($this); } } - public function getVariantBitmask() : int{ - return 0x07; - } - public function getToolType() : int{ - return ($this->meta === 2 or $this->meta === 3) ? BlockToolType::TYPE_SHEARS : BlockToolType::TYPE_NONE; + return ($this->variant === 2 or $this->variant === 3) ? BlockToolType::TYPE_SHEARS : BlockToolType::TYPE_NONE; } public function getToolHarvestLevel() : int{ - return ($this->meta === 2 or $this->meta === 3) ? 1 : 0; //only grass or fern require shears + return ($this->variant === 2 or $this->variant === 3) ? 1 : 0; //only grass or fern require shears } public function getDrops(Item $item) : array{ - if($this->meta & self::BITFLAG_TOP){ + if($this->top){ if($this->isCompatibleWithTool($item)){ return parent::getDrops($item); } @@ -120,7 +112,7 @@ class DoublePlant extends Flowable{ public function getAffectedBlocks() : array{ if($this->isValidHalfPlant()){ - return [$this, $this->getSide(($this->meta & self::BITFLAG_TOP) !== 0 ? Facing::DOWN : Facing::UP)]; + return [$this, $this->getSide($this->top ? Facing::DOWN : Facing::UP)]; } return parent::getAffectedBlocks(); diff --git a/src/pocketmine/block/DoubleSlab.php b/src/pocketmine/block/DoubleSlab.php index 02006099b8..acdbb887ca 100644 --- a/src/pocketmine/block/DoubleSlab.php +++ b/src/pocketmine/block/DoubleSlab.php @@ -26,21 +26,46 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -abstract class DoubleSlab extends Solid{ +class DoubleSlab extends Solid{ + /** @var int */ + protected $singleId; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(int $id, int $singleId, int $variant = 0){ + parent::__construct($id, $variant); + $this->singleId = $singleId; } - abstract public function getSlabId() : int; + protected function getSingle() : Block{ + return BlockFactory::get($this->singleId, $this->variant); + } + + public function getHardness() : float{ + return $this->getSingle()->getHardness(); + } + + public function getToolType() : int{ + return $this->getSingle()->getToolType(); + } + + public function getToolHarvestLevel() : int{ + return $this->getSingle()->getToolHarvestLevel(); + } + + public function getFlameEncouragement() : int{ + return $this->getSingle()->getFlameEncouragement(); + } + + public function getFlammability() : int{ + return $this->getSingle()->getFlammability(); + } public function getName() : string{ - return "Double " . BlockFactory::get($this->getSlabId(), $this->getVariant())->getName(); + return "Double " . $this->getSingle()->getName(); } public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get($this->getSlabId(), $this->getVariant(), 2) + ItemFactory::get($this->singleId, $this->variant, 2) ]; } diff --git a/src/pocketmine/block/DoubleStoneSlab.php b/src/pocketmine/block/DoubleStoneSlab.php deleted file mode 100644 index 1466828ea3..0000000000 --- a/src/pocketmine/block/DoubleStoneSlab.php +++ /dev/null @@ -1,47 +0,0 @@ -setDamage($meta); + public function __construct(){ + } public function getHardness() : float{ diff --git a/src/pocketmine/block/EmeraldOre.php b/src/pocketmine/block/EmeraldOre.php index 31c2a3f809..7c94475eac 100644 --- a/src/pocketmine/block/EmeraldOre.php +++ b/src/pocketmine/block/EmeraldOre.php @@ -31,8 +31,8 @@ class EmeraldOre extends Solid{ protected $id = self::EMERALD_ORE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/EnchantingTable.php b/src/pocketmine/block/EnchantingTable.php index 4a23b3ab16..0b0d066c21 100644 --- a/src/pocketmine/block/EnchantingTable.php +++ b/src/pocketmine/block/EnchantingTable.php @@ -35,8 +35,8 @@ class EnchantingTable extends Transparent{ protected $id = self::ENCHANTING_TABLE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ diff --git a/src/pocketmine/block/EndPortalFrame.php b/src/pocketmine/block/EndPortalFrame.php index 193788054b..5c002b71fb 100644 --- a/src/pocketmine/block/EndPortalFrame.php +++ b/src/pocketmine/block/EndPortalFrame.php @@ -25,13 +25,35 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Bearing; +use pocketmine\math\Facing; +use pocketmine\math\Vector3; +use pocketmine\Player; class EndPortalFrame extends Solid{ protected $id = self::END_PORTAL_FRAME; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $facing = Facing::NORTH; + /** @var bool */ + protected $eye = false; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return Bearing::fromFacing($this->facing) | ($this->eye ? 0x04 : 0); + } + + public function readStateFromMeta(int $meta) : void{ + $this->facing = Bearing::toFacing($meta & 0x03); + $this->eye = ($meta & 0x04) !== 0; + } + + public function getStateBitmask() : int{ + return 0b111; } public function getLightLevel() : int{ @@ -55,14 +77,20 @@ class EndPortalFrame extends Solid{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return new AxisAlignedBB( 0, 0, 0, 1, - (($this->getDamage() & 0x04) > 0 ? 1 : 0.8125), + $this->eye ? 1 : 0.8125, 1 ); } + + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + if($player !== null){ + $this->facing = Bearing::toFacing(Bearing::opposite($player->getDirection())); + } + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } } diff --git a/src/pocketmine/block/EndRod.php b/src/pocketmine/block/EndRod.php index 306cdd2669..25391667bc 100644 --- a/src/pocketmine/block/EndRod.php +++ b/src/pocketmine/block/EndRod.php @@ -33,8 +33,30 @@ class EndRod extends Flowable{ protected $id = Block::END_ROD; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $facing = Facing::DOWN; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + if(Facing::axis($this->facing) === Facing::AXIS_Y){ + return $this->facing; + } + return $this->facing ^ 1; //TODO: in PC this is always the same as facing, just PE is stupid + } + + public function readStateFromMeta(int $meta) : void{ + if($meta === 0 or $meta === 1){ + $this->facing = $meta; + }else{ + $this->facing = $meta ^ 1; //TODO: see above + } + } + + public function getStateBitmask() : int{ + return 0b111; } public function getName() : string{ @@ -42,13 +64,9 @@ class EndRod extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if(Facing::axis($face) === Facing::AXIS_Y){ - $this->meta = $face; - }else{ - $this->meta = $face ^ 0x01; - } - if($blockClicked instanceof EndRod and $blockClicked->getDamage() === $this->meta){ - $this->meta ^= 0x01; + $this->facing = $face; + if($blockClicked instanceof EndRod and $blockClicked->facing === $this->facing){ + $this->facing = Facing::opposite($face); } return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); @@ -63,7 +81,7 @@ class EndRod extends Flowable{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - $m = $this->meta >> 1; //everything except up/down are inverted, but we can still use this for axis + $m = Facing::axis($this->facing); $width = 0.375; switch($m){ @@ -98,8 +116,4 @@ class EndRod extends Flowable{ return null; } - - public function getVariantBitmask() : int{ - return 0; - } } diff --git a/src/pocketmine/block/EndStone.php b/src/pocketmine/block/EndStone.php index cd4f40c7d5..17953f776e 100644 --- a/src/pocketmine/block/EndStone.php +++ b/src/pocketmine/block/EndStone.php @@ -29,8 +29,8 @@ class EndStone extends Solid{ protected $id = self::END_STONE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/EndStoneBricks.php b/src/pocketmine/block/EndStoneBricks.php index a925f952c2..0808f18b15 100644 --- a/src/pocketmine/block/EndStoneBricks.php +++ b/src/pocketmine/block/EndStoneBricks.php @@ -29,8 +29,8 @@ class EndStoneBricks extends Solid{ protected $id = self::END_BRICKS; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index 348c5c701e..8bf91e201d 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -62,8 +62,8 @@ class EnderChest extends Chest{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if($player !== null){ - $this->meta = Bearing::toFacing(Bearing::opposite($player->getDirection())); + if($player !== null){ //same as normal chest - TODO: clean up inheritance here + $this->facing = Bearing::toFacing(Bearing::opposite($player->getDirection())); } if(Block::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index 0b435b1145..0db8a649ae 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -32,8 +32,23 @@ class Farmland extends Transparent{ protected $id = self::FARMLAND; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $wetness = 0; //"moisture" blockstate property in PC + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return $this->wetness; + } + + public function readStateFromMeta(int $meta) : void{ + $this->wetness = $meta; + } + + public function getStateBitmask() : int{ + return 0b111; } public function getName() : string{ @@ -64,14 +79,14 @@ class Farmland extends Transparent{ public function onRandomTick() : void{ if(!$this->canHydrate()){ - if($this->meta > 0){ - $this->meta--; + if($this->wetness > 0){ + $this->wetness--; $this->level->setBlock($this, $this, false, false); }else{ $this->level->setBlock($this, BlockFactory::get(Block::DIRT), false, true); } - }elseif($this->meta < 7){ - $this->meta = 7; + }elseif($this->wetness < 7){ + $this->wetness = 7; $this->level->setBlock($this, $this, false, false); } } diff --git a/src/pocketmine/block/Fence.php b/src/pocketmine/block/Fence.php index effd3b8249..b207619c6c 100644 --- a/src/pocketmine/block/Fence.php +++ b/src/pocketmine/block/Fence.php @@ -28,10 +28,6 @@ use pocketmine\math\Facing; abstract class Fence extends Transparent{ - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - public function getThickness() : float{ return 0.25; } diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index e3e3191b9f..5f14cdcd74 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -26,10 +26,29 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\level\sound\DoorSound; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Bearing; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; class FenceGate extends Transparent{ + /** @var bool */ + protected $open = false; + /** @var int */ + protected $facing = Facing::NORTH; + + protected function writeStateToMeta() : int{ + return Bearing::fromFacing($this->facing) | ($this->open ? 0x04 : 0); + } + + public function readStateFromMeta(int $meta) : void{ + $this->facing = Bearing::toFacing($meta & 0x03); + $this->open = ($meta & 0x04) !== 0; + } + + public function getStateBitmask() : int{ + return 0b111; + } public function getHardness() : float{ return 2; @@ -41,12 +60,11 @@ class FenceGate extends Transparent{ protected function recalculateBoundingBox() : ?AxisAlignedBB{ - if(($this->getDamage() & 0x04) > 0){ + if($this->open){ return null; } - $i = ($this->getDamage() & 0x03); - if($i === 2 or $i === 0){ + if(Facing::axis($this->facing) === Facing::AXIS_Z){ return new AxisAlignedBB( 0, 0, @@ -69,21 +87,19 @@ class FenceGate extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ - $this->meta = $player->getDirection(); + $this->facing = Bearing::toFacing($player->getDirection()); } return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - public function getVariantBitmask() : int{ - return 0; - } - public function onActivate(Item $item, Player $player = null) : bool{ - $this->meta = (($this->meta ^ 0x04) & ~0x02); - - if($player !== null){ - $this->meta |= ($player->getDirection() & 0x02); //open towards the player, retaining axis + $this->open = !$this->open; + if($this->open and $player !== null){ + $playerFacing = Bearing::toFacing($player->getDirection()); + if($playerFacing === Facing::opposite($this->facing)){ + $this->facing = $playerFacing; + } } $this->getLevel()->setBlock($this, $this, true); diff --git a/src/pocketmine/block/Fire.php b/src/pocketmine/block/Fire.php index a6bd4c1e70..7aa4abd1f8 100644 --- a/src/pocketmine/block/Fire.php +++ b/src/pocketmine/block/Fire.php @@ -37,8 +37,23 @@ class Fire extends Flowable{ protected $id = self::FIRE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $age = 0; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return $this->age; + } + + public function readStateFromMeta(int $meta) : void{ + $this->age = $meta; + } + + public function getStateBitmask() : int{ + return 0b1111; } public function hasEntityCollision() : bool{ @@ -95,22 +110,22 @@ class Fire extends Flowable{ $down = $this->getSide(Facing::DOWN); $result = null; - if($this->meta < 15 and mt_rand(0, 2) === 0){ - $this->meta++; + if($this->age < 15 and mt_rand(0, 2) === 0){ + $this->age++; $result = $this; } $canSpread = true; if(!$down->burnsForever()){ //TODO: check rain - if($this->meta === 15){ + if($this->age === 15){ if(!$down->isFlammable() and mt_rand(0, 3) === 3){ //1/4 chance to extinguish $canSpread = false; $result = BlockFactory::get(Block::AIR); } }elseif(!$this->hasAdjacentFlammableBlocks()){ $canSpread = false; - if(!$down->isSolid() or $this->meta > 3){ //fire older than 3, or without a solid block below + if(!$down->isSolid() or $this->age > 3){ $result = BlockFactory::get(Block::AIR); } } @@ -157,8 +172,10 @@ class Fire extends Flowable{ if(!$ev->isCancelled()){ $block->onIncinerate(); - if(mt_rand(0, $this->meta + 9) < 5){ //TODO: check rain - $this->level->setBlock($block, BlockFactory::get(Block::FIRE, min(15, $this->meta + (mt_rand(0, 4) >> 2)))); + if(mt_rand(0, $this->age + 9) < 5){ //TODO: check rain + $fire = clone $this; + $fire->age = min(15, $fire->age + (mt_rand(0, 4) >> 2)); + $this->level->setBlock($block, $fire); }else{ $this->level->setBlock($block, BlockFactory::get(Block::AIR)); } diff --git a/src/pocketmine/block/Flower.php b/src/pocketmine/block/Flower.php index fb85cbefb9..4ae18ae68a 100644 --- a/src/pocketmine/block/Flower.php +++ b/src/pocketmine/block/Flower.php @@ -39,27 +39,6 @@ class Flower extends Flowable{ public const TYPE_PINK_TULIP = 7; public const TYPE_OXEYE_DAISY = 8; - protected $id = self::RED_FLOWER; - - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - - public function getName() : string{ - static $names = [ - self::TYPE_POPPY => "Poppy", - self::TYPE_BLUE_ORCHID => "Blue Orchid", - self::TYPE_ALLIUM => "Allium", - self::TYPE_AZURE_BLUET => "Azure Bluet", - self::TYPE_RED_TULIP => "Red Tulip", - self::TYPE_ORANGE_TULIP => "Orange Tulip", - self::TYPE_WHITE_TULIP => "White Tulip", - self::TYPE_PINK_TULIP => "Pink Tulip", - self::TYPE_OXEYE_DAISY => "Oxeye Daisy" - ]; - return $names[$this->meta] ?? "Unknown"; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === Block::GRASS or $down->getId() === Block::DIRT or $down->getId() === Block::FARMLAND){ diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 40555546c1..2a07fd07dc 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -33,14 +33,26 @@ use pocketmine\tile\Tile; class FlowerPot extends Flowable{ - public const STATE_EMPTY = 0; - public const STATE_FULL = 1; - protected $id = self::FLOWER_POT_BLOCK; protected $itemId = Item::FLOWER_POT; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var bool */ + protected $occupied = false; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return $this->occupied ? 1 : 0; + } + + public function readStateFromMeta(int $meta) : void{ + $this->occupied = $meta !== 0; + } + + public function getStateBitmask() : int{ + return 0b1111; //vanilla uses various values, we only care about 1 and 0 for PE } public function getName() : string{ @@ -80,17 +92,13 @@ class FlowerPot extends Flowable{ return true; } - $this->setDamage(self::STATE_FULL); //specific damage value is unnecessary, it just needs to be non-zero to show an item. + $this->occupied = true; $this->getLevel()->setBlock($this, $this, true, false); $pot->setItem($item->pop()); return true; } - public function getVariantBitmask() : int{ - return 0; - } - public function getDropsForCompatibleTool(Item $item) : array{ $items = parent::getDropsForCompatibleTool($item); diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index eb8acd9ed5..a311355790 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -23,16 +23,98 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\item\Item; +use pocketmine\item\TieredTool; +use pocketmine\math\Bearing; +use pocketmine\math\Facing; +use pocketmine\math\Vector3; +use pocketmine\Player; +use pocketmine\tile\Furnace as TileFurnace; +use pocketmine\tile\Tile; -class Furnace extends BurningFurnace{ +class Furnace extends Solid{ - protected $id = self::FURNACE; + protected $itemId = self::FURNACE; + + /** @var int */ + protected $facing = Facing::NORTH; + /** @var bool */ + protected $lit = false; //this is set based on the blockID + + public function __construct(){ + + } + + public function getId() : int{ + return $this->lit ? Block::BURNING_FURNACE : Block::FURNACE; + } + + protected function writeStateToMeta() : int{ + return $this->facing; + } + + public function readStateFromMeta(int $meta) : void{ + $this->facing = $meta; + } + + public function getStateBitmask() : int{ + return 0b111; + } public function getName() : string{ return "Furnace"; } + public function getHardness() : float{ + return 3.5; + } + + public function getToolType() : int{ + return BlockToolType::TYPE_PICKAXE; + } + + public function getToolHarvestLevel() : int{ + return TieredTool::TIER_WOODEN; + } + public function getLightLevel() : int{ - return 0; + return $this->lit ? 13 : 0; + } + + public function isLit() : bool{ + return $this->lit; + } + + public function setLit(bool $lit = true) : void{ + $this->lit = $lit; + } + + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + if($player !== null){ + $this->facing = Bearing::toFacing(Bearing::opposite($player->getDirection())); + } + if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ + Tile::createTile(Tile::FURNACE, $this->getLevel(), TileFurnace::createNBT($this, $face, $item, $player)); + return true; + } + + return false; + } + + public function onActivate(Item $item, Player $player = null) : bool{ + if($player instanceof Player){ + $furnace = $this->getLevel()->getTile($this); + if(!($furnace instanceof TileFurnace)){ + $furnace = Tile::createTile(Tile::FURNACE, $this->getLevel(), TileFurnace::createNBT($this)); + } + + if(!$furnace->canOpenWith($item->getCustomName())){ + return true; + } + + $player->addWindow($furnace->getInventory()); + } + + return true; } } diff --git a/src/pocketmine/block/Glass.php b/src/pocketmine/block/Glass.php index 65ab80b572..dd25ea7423 100644 --- a/src/pocketmine/block/Glass.php +++ b/src/pocketmine/block/Glass.php @@ -27,16 +27,6 @@ use pocketmine\item\Item; class Glass extends Transparent{ - protected $id = self::GLASS; - - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - - public function getName() : string{ - return "Glass"; - } - public function getHardness() : float{ return 0.3; } diff --git a/src/pocketmine/block/GlassPane.php b/src/pocketmine/block/GlassPane.php index cc19440671..7f2e02fd60 100644 --- a/src/pocketmine/block/GlassPane.php +++ b/src/pocketmine/block/GlassPane.php @@ -27,16 +27,6 @@ use pocketmine\item\Item; class GlassPane extends Thin{ - protected $id = self::GLASS_PANE; - - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - - public function getName() : string{ - return "Glass Pane"; - } - public function getHardness() : float{ return 0.3; } diff --git a/src/pocketmine/block/GlazedTerracotta.php b/src/pocketmine/block/GlazedTerracotta.php index 8035274756..f3b5e72c5e 100644 --- a/src/pocketmine/block/GlazedTerracotta.php +++ b/src/pocketmine/block/GlazedTerracotta.php @@ -27,11 +27,27 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\item\TieredTool; use pocketmine\math\Bearing; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; class GlazedTerracotta extends Solid{ + /** @var int */ + protected $facing = Facing::NORTH; + + protected function writeStateToMeta() : int{ + return $this->facing; + } + + public function readStateFromMeta(int $meta) : void{ + $this->facing = $meta; + } + + public function getStateBitmask() : int{ + return 0b111; + } + public function getHardness() : float{ return 1.4; } @@ -46,13 +62,9 @@ class GlazedTerracotta extends Solid{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ - $this->meta = Bearing::toFacing(Bearing::opposite($player->getDirection())); + $this->facing = Bearing::toFacing(Bearing::opposite($player->getDirection())); } return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - - public function getVariantBitmask() : int{ - return 0; - } } diff --git a/src/pocketmine/block/GlowingObsidian.php b/src/pocketmine/block/GlowingObsidian.php index e8e62a76db..51e81c4502 100644 --- a/src/pocketmine/block/GlowingObsidian.php +++ b/src/pocketmine/block/GlowingObsidian.php @@ -30,8 +30,8 @@ class GlowingObsidian extends Solid{ protected $id = self::GLOWING_OBSIDIAN; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/GlowingRedstoneOre.php b/src/pocketmine/block/GlowingRedstoneOre.php deleted file mode 100644 index 0825bf5464..0000000000 --- a/src/pocketmine/block/GlowingRedstoneOre.php +++ /dev/null @@ -1,58 +0,0 @@ -getLevel()->setBlock($this, BlockFactory::get(Block::REDSTONE_ORE, $this->meta), false, false); - } -} diff --git a/src/pocketmine/block/Glowstone.php b/src/pocketmine/block/Glowstone.php index 02f5a31bab..c4ab959fe7 100644 --- a/src/pocketmine/block/Glowstone.php +++ b/src/pocketmine/block/Glowstone.php @@ -30,8 +30,8 @@ class Glowstone extends Transparent{ protected $id = self::GLOWSTONE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/Gold.php b/src/pocketmine/block/Gold.php index 99e82324a9..8e6aa97c25 100644 --- a/src/pocketmine/block/Gold.php +++ b/src/pocketmine/block/Gold.php @@ -29,8 +29,8 @@ class Gold extends Solid{ protected $id = self::GOLD_BLOCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/GoldOre.php b/src/pocketmine/block/GoldOre.php index a6b280ccfb..9ef07f4cce 100644 --- a/src/pocketmine/block/GoldOre.php +++ b/src/pocketmine/block/GoldOre.php @@ -29,8 +29,8 @@ class GoldOre extends Solid{ protected $id = self::GOLD_ORE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index 641f3118e6..954c5f9ba0 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -37,8 +37,8 @@ class Grass extends Solid{ protected $id = self::GRASS; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/GrassPath.php b/src/pocketmine/block/GrassPath.php index 18818277f1..9ec3737afc 100644 --- a/src/pocketmine/block/GrassPath.php +++ b/src/pocketmine/block/GrassPath.php @@ -32,8 +32,8 @@ class GrassPath extends Transparent{ protected $id = self::GRASS_PATH; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/Gravel.php b/src/pocketmine/block/Gravel.php index d2492729b2..a5ee8d07d1 100644 --- a/src/pocketmine/block/Gravel.php +++ b/src/pocketmine/block/Gravel.php @@ -30,8 +30,8 @@ class Gravel extends Fallable{ protected $id = self::GRAVEL; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/HardenedClay.php b/src/pocketmine/block/HardenedClay.php index 7918c2c32a..77b06e2a3c 100644 --- a/src/pocketmine/block/HardenedClay.php +++ b/src/pocketmine/block/HardenedClay.php @@ -27,16 +27,6 @@ use pocketmine\item\TieredTool; class HardenedClay extends Solid{ - protected $id = self::HARDENED_CLAY; - - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - - public function getName() : string{ - return "Hardened Clay"; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } diff --git a/src/pocketmine/block/HayBale.php b/src/pocketmine/block/HayBale.php index 696c8c8f96..e39f200030 100644 --- a/src/pocketmine/block/HayBale.php +++ b/src/pocketmine/block/HayBale.php @@ -23,17 +23,19 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\PillarRotationHelper; +use pocketmine\block\utils\PillarRotationTrait; use pocketmine\item\Item; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; class HayBale extends Solid{ + use PillarRotationTrait; protected $id = self::HAY_BALE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ @@ -45,14 +47,10 @@ class HayBale extends Solid{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $this->meta = PillarRotationHelper::getMetaFromFace($this->meta, $face); + $this->axis = Facing::axis($face); return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - public function getVariantBitmask() : int{ - return 0x03; - } - public function getFlameEncouragement() : int{ return 60; } diff --git a/src/pocketmine/block/Ice.php b/src/pocketmine/block/Ice.php index 071de1fd44..fb100a4f7e 100644 --- a/src/pocketmine/block/Ice.php +++ b/src/pocketmine/block/Ice.php @@ -31,8 +31,8 @@ class Ice extends Transparent{ protected $id = self::ICE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/Iron.php b/src/pocketmine/block/Iron.php index 772a8d664b..0246fe5364 100644 --- a/src/pocketmine/block/Iron.php +++ b/src/pocketmine/block/Iron.php @@ -29,8 +29,8 @@ class Iron extends Solid{ protected $id = self::IRON_BLOCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/IronBars.php b/src/pocketmine/block/IronBars.php index 7e6030f092..755c0d12c5 100644 --- a/src/pocketmine/block/IronBars.php +++ b/src/pocketmine/block/IronBars.php @@ -29,8 +29,8 @@ class IronBars extends Thin{ protected $id = self::IRON_BARS; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ @@ -48,8 +48,4 @@ class IronBars extends Thin{ public function getToolHarvestLevel() : int{ return TieredTool::TIER_WOODEN; } - - public function getVariantBitmask() : int{ - return 0; - } } diff --git a/src/pocketmine/block/IronDoor.php b/src/pocketmine/block/IronDoor.php index b097d4d26e..c9da8160a7 100644 --- a/src/pocketmine/block/IronDoor.php +++ b/src/pocketmine/block/IronDoor.php @@ -32,8 +32,8 @@ class IronDoor extends Door{ protected $itemId = Item::IRON_DOOR; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/IronOre.php b/src/pocketmine/block/IronOre.php index bda7572dab..c41c7518ee 100644 --- a/src/pocketmine/block/IronOre.php +++ b/src/pocketmine/block/IronOre.php @@ -29,8 +29,8 @@ class IronOre extends Solid{ protected $id = self::IRON_ORE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 0c9f43e647..8e33153904 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -35,8 +35,23 @@ class ItemFrame extends Flowable{ protected $itemId = Item::ITEM_FRAME; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $facing = Facing::NORTH; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return 5 - $this->facing; + } + + public function readStateFromMeta(int $meta) : void{ + $this->facing = 5 - $meta; + } + + public function getStateBitmask() : int{ + return 0b11; } public function getName() : string{ @@ -59,7 +74,7 @@ class ItemFrame extends Flowable{ } public function onNearbyBlockChange() : void{ - if(!$this->getSide(Facing::opposite(5 - $this->meta))->isSolid()){ + if(!$this->getSide(Facing::opposite($this->facing))->isSolid()){ $this->level->useBreakOn($this); } } @@ -69,7 +84,7 @@ class ItemFrame extends Flowable{ return false; } - $this->meta = 5 - $face; + $this->facing = $face; if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ Tile::createTile(Tile::ITEM_FRAME, $this->getLevel(), TileItemFrame::createNBT($this, $face, $item, $player)); @@ -80,10 +95,6 @@ class ItemFrame extends Flowable{ } - public function getVariantBitmask() : int{ - return 0; - } - public function getDropsForCompatibleTool(Item $item) : array{ $drops = parent::getDropsForCompatibleTool($item); diff --git a/src/pocketmine/block/Ladder.php b/src/pocketmine/block/Ladder.php index 0f29bcb0cc..b309fa18ac 100644 --- a/src/pocketmine/block/Ladder.php +++ b/src/pocketmine/block/Ladder.php @@ -34,8 +34,23 @@ class Ladder extends Transparent{ protected $id = self::LADDER; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $facing = Facing::NORTH; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return $this->facing; + } + + public function readStateFromMeta(int $meta) : void{ + $this->facing = $meta; + } + + public function getStateBitmask() : int{ + return 0b111; } public function getName() : string{ @@ -69,13 +84,13 @@ class Ladder extends Transparent{ $minX = $minZ = 0; $maxX = $maxZ = 1; - if($this->meta === 2){ + if($this->facing === Facing::NORTH){ $minZ = 1 - $f; - }elseif($this->meta === 3){ + }elseif($this->facing === Facing::SOUTH){ $maxZ = $f; - }elseif($this->meta === 4){ + }elseif($this->facing === Facing::WEST){ $minX = 1 - $f; - }elseif($this->meta === 5){ + }elseif($this->facing === Facing::EAST){ $maxX = $f; } @@ -92,7 +107,7 @@ class Ladder extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if(!$blockClicked->isTransparent() and Facing::axis($face) !== Facing::AXIS_Y){ - $this->meta = $face; + $this->facing = $face; return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -100,7 +115,7 @@ class Ladder extends Transparent{ } public function onNearbyBlockChange() : void{ - if(!$this->getSide($this->meta ^ 0x01)->isSolid()){ //Replace with common break method + if(!$this->getSide(Facing::opposite($this->facing))->isSolid()){ //Replace with common break method $this->level->useBreakOn($this); } } @@ -108,8 +123,4 @@ class Ladder extends Transparent{ public function getToolType() : int{ return BlockToolType::TYPE_AXE; } - - public function getVariantBitmask() : int{ - return 0; - } } diff --git a/src/pocketmine/block/Lapis.php b/src/pocketmine/block/Lapis.php index 3ca5c31b11..9af975e22e 100644 --- a/src/pocketmine/block/Lapis.php +++ b/src/pocketmine/block/Lapis.php @@ -29,8 +29,8 @@ class Lapis extends Solid{ protected $id = self::LAPIS_BLOCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/LapisOre.php b/src/pocketmine/block/LapisOre.php index 18bccaf98a..171cf0dd4a 100644 --- a/src/pocketmine/block/LapisOre.php +++ b/src/pocketmine/block/LapisOre.php @@ -31,8 +31,8 @@ class LapisOre extends Solid{ protected $id = self::LAPIS_ORE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getHardness() : float{ diff --git a/src/pocketmine/block/Lava.php b/src/pocketmine/block/Lava.php index 7757cd36d5..c653c0d3ad 100644 --- a/src/pocketmine/block/Lava.php +++ b/src/pocketmine/block/Lava.php @@ -35,8 +35,8 @@ class Lava extends Liquid{ protected $id = self::FLOWING_LAVA; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getLightLevel() : int{ @@ -48,11 +48,11 @@ class Lava extends Liquid{ } public function getStillForm() : Block{ - return BlockFactory::get(Block::STILL_LAVA, $this->meta); + return BlockFactory::get(Block::STILL_LAVA, $this->getDamage()); } public function getFlowingForm() : Block{ - return BlockFactory::get(Block::FLOWING_LAVA, $this->meta); + return BlockFactory::get(Block::FLOWING_LAVA, $this->getDamage()); } public function getBucketFillSound() : int{ @@ -85,19 +85,19 @@ class Lava extends Liquid{ } if($colliding !== null){ - if($this->getDamage() === 0){ + if($this->decay === 0){ $this->liquidCollide($colliding, BlockFactory::get(Block::OBSIDIAN)); - }elseif($this->getDamage() <= 4){ + }elseif($this->decay <= 4){ $this->liquidCollide($colliding, BlockFactory::get(Block::COBBLESTONE)); } } } - protected function flowIntoBlock(Block $block, int $newFlowDecay) : void{ + protected function flowIntoBlock(Block $block, int $newFlowDecay, bool $falling) : void{ if($block instanceof Water){ $block->liquidCollide($this, BlockFactory::get(Block::STONE)); }else{ - parent::flowIntoBlock($block, $newFlowDecay); + parent::flowIntoBlock($block, $newFlowDecay, $falling); } } diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 5d32a721d1..11dd7fc4b9 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\WoodType; use pocketmine\event\block\LeavesDecayEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; @@ -32,17 +33,30 @@ use pocketmine\math\Vector3; use pocketmine\Player; class Leaves extends Transparent{ - public const OAK = 0; - public const SPRUCE = 1; - public const BIRCH = 2; - public const JUNGLE = 3; - public const ACACIA = 0; - public const DARK_OAK = 1; + /** @var int */ + protected $woodType; - protected $id = self::LEAVES; + /** @var bool */ + protected $noDecay = false; + /** @var bool */ + protected $checkDecay = false; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(int $id, int $variant, int $woodType, ?string $name = null){ + parent::__construct($id, $variant, $name); + $this->woodType = $woodType; + } + + protected function writeStateToMeta() : int{ + return ($this->noDecay ? 0x04 : 0) | ($this->checkDecay ? 0x08 : 0); + } + + public function readStateFromMeta(int $meta) : void{ + $this->noDecay = ($meta & 0x04) !== 0; + $this->checkDecay = ($meta & 0x08) !== 0; + } + + public function getStateBitmask() : int{ + return 0b1100; } public function getHardness() : float{ @@ -53,16 +67,6 @@ class Leaves extends Transparent{ return BlockToolType::TYPE_SHEARS; } - public function getName() : string{ - static $names = [ - self::OAK => "Oak Leaves", - self::SPRUCE => "Spruce Leaves", - self::BIRCH => "Birch Leaves", - self::JUNGLE => "Jungle Leaves" - ]; - return $names[$this->getVariant()]; - } - public function diffusesSkyLight() : bool{ return true; } @@ -80,7 +84,7 @@ class Leaves extends Transparent{ return true; } - if($pos->getId() === $this->id and $distance <= 4){ + if($pos->getId() === $this->getId() and $distance <= 4){ foreach(Facing::ALL as $side){ if($this->findLog($pos->getSide($side), $visited, $distance + 1)){ return true; @@ -92,8 +96,8 @@ class Leaves extends Transparent{ } public function onNearbyBlockChange() : void{ - if(($this->meta & 0b00001100) === 0){ - $this->meta |= 0x08; + if(!$this->noDecay and !$this->checkDecay){ + $this->checkDecay = true; $this->getLevel()->setBlock($this, $this, true, false); } } @@ -103,9 +107,7 @@ class Leaves extends Transparent{ } public function onRandomTick() : void{ - if(($this->meta & 0b00001100) === 0x08){ - $this->meta &= 0x03; - + if(!$this->noDecay and $this->checkDecay){ $this->getLevel()->getServer()->getPluginManager()->callEvent($ev = new LeavesDecayEvent($this)); if($ev->isCancelled() or $this->findLog($this)){ @@ -117,14 +119,10 @@ class Leaves extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $this->meta |= 0x04; + $this->noDecay = true; //artificial leaves don't decay return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - public function getVariantBitmask() : int{ - return 0x03; - } - public function getDrops(Item $item) : array{ if($item->getBlockToolType() & BlockToolType::TYPE_SHEARS){ return $this->getDropsForCompatibleTool($item); @@ -132,23 +130,15 @@ class Leaves extends Transparent{ $drops = []; if(mt_rand(1, 20) === 1){ //Saplings - $drops[] = $this->getSaplingItem(); + $drops[] = ItemFactory::get(Item::SAPLING, $this->woodType); } - if($this->canDropApples() and mt_rand(1, 200) === 1){ //Apples + if(($this->woodType === WoodType::OAK or $this->woodType === WoodType::DARK_OAK) and mt_rand(1, 200) === 1){ //Apples $drops[] = ItemFactory::get(Item::APPLE); } return $drops; } - public function getSaplingItem() : Item{ - return ItemFactory::get(Item::SAPLING, $this->getVariant()); - } - - public function canDropApples() : bool{ - return $this->meta === self::OAK; - } - public function getFlameEncouragement() : int{ return 30; } diff --git a/src/pocketmine/block/Leaves2.php b/src/pocketmine/block/Leaves2.php deleted file mode 100644 index 3038e3319e..0000000000 --- a/src/pocketmine/block/Leaves2.php +++ /dev/null @@ -1,48 +0,0 @@ - "Acacia Leaves", - self::DARK_OAK => "Dark Oak Leaves" - ]; - return $names[$this->getVariant()] ?? "Unknown"; - } - - public function getSaplingItem() : Item{ - return ItemFactory::get(Item::SAPLING, $this->getVariant() + 4); - } - - public function canDropApples() : bool{ - return $this->meta === self::DARK_OAK; - } -} diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index 6cd6b84801..a44ef16f20 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -30,11 +30,52 @@ use pocketmine\math\Vector3; use pocketmine\Player; class Lever extends Flowable{ + protected const BOTTOM = 0; + protected const SIDE = 1; + protected const TOP = 2; protected $id = self::LEVER; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $position = self::BOTTOM; + /** @var int */ + protected $facing = Facing::NORTH; + /** @var bool */ + protected $powered = false; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + if($this->position === self::BOTTOM){ + $rotationMeta = Facing::axis($this->facing) === Facing::AXIS_Z ? 7 : 0; + }elseif($this->position === self::TOP){ + $rotationMeta = Facing::axis($this->facing) === Facing::AXIS_Z ? 5 : 6; + }else{ + $rotationMeta = 6 - $this->facing; + } + return $rotationMeta | ($this->powered ? 0x08 : 0); + } + + public function readStateFromMeta(int $meta) : void{ + $rotationMeta = $meta & 0x07; + if($rotationMeta === 5 or $rotationMeta === 6){ + $this->position = self::TOP; + $this->facing = $rotationMeta === 5 ? Facing::SOUTH : Facing::EAST; + }elseif($rotationMeta === 7 or $rotationMeta === 0){ + $this->position = self::BOTTOM; + $this->facing = $rotationMeta === 7 ? Facing::SOUTH : Facing::EAST; + }else{ + $this->position = self::SIDE; + $this->facing = 6 - $rotationMeta; + } + + $this->powered = ($meta & 0x08) !== 0; + } + + public function getStateBitmask() : int{ + return 0b1111; } public function getName() : string{ @@ -45,49 +86,34 @@ class Lever extends Flowable{ return 0.5; } - public function getVariantBitmask() : int{ - return 0; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if(!$blockClicked->isSolid()){ return false; } - if($face === Facing::DOWN){ - $this->meta = 0; - }else{ - $this->meta = 6 - $face; - } - - if($player !== null){ - $bearing = $player->getDirection(); - if($bearing === Bearing::EAST or $bearing === Bearing::WEST){ - if($face === Facing::UP){ - $this->meta = 6; - } - }else{ - if($face === Facing::DOWN){ - $this->meta = 7; - } + if(Facing::axis($face) === Facing::AXIS_Y){ + if($player !== null){ + $this->facing = Bearing::toFacing(Bearing::opposite($player->getDirection())); } + $this->position = $face === Facing::DOWN ? self::BOTTOM : self::TOP; + }else{ + $this->facing = $face; + $this->position = self::SIDE; } return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onNearbyBlockChange() : void{ - static $faces = [ - 0 => Facing::UP, - 1 => Facing::WEST, - 2 => Facing::EAST, - 3 => Facing::NORTH, - 4 => Facing::SOUTH, - 5 => Facing::DOWN, - 6 => Facing::DOWN, - 7 => Facing::UP - ]; - if(!$this->getSide($faces[$this->meta & 0x07])->isSolid()){ + if($this->position === self::BOTTOM){ + $face = Facing::UP; + }elseif($this->position === self::TOP){ + $face = Facing::DOWN; + }else{ + $face = Facing::opposite($this->facing); + } + + if(!$this->getSide($face)->isSolid()){ $this->level->useBreakOn($this); } } diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index 16cfc16334..978d3c520b 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -44,6 +44,24 @@ abstract class Liquid extends Transparent{ private const CAN_FLOW = 0; private const BLOCKED = -1; + /** @var bool */ + protected $falling = false; + /** @var int */ + protected $decay = 0; //PC "level" property + + protected function writeStateToMeta() : int{ + return $this->decay | ($this->falling ? 0x08 : 0); + } + + public function readStateFromMeta(int $meta) : void{ + $this->decay = $meta & 0x07; + $this->falling = ($meta & 0x08) !== 0; + } + + public function getStateBitmask() : int{ + return 0b1111; + } + public function hasEntityCollision() : bool{ return true; } @@ -84,35 +102,20 @@ abstract class Liquid extends Transparent{ abstract public function getBucketEmptySound() : int; - public function getFluidHeightPercent(){ - $d = $this->meta; - if($d >= 8){ - $d = 0; - } - - return ($d + 1) / 9; + public function isSource() : bool{ + return !$this->falling and $this->decay === 0; } - protected function getFlowDecay(Block $block) : int{ - if($block->getId() !== $this->getId()){ - return -1; - } - - return $block->getDamage(); + public function getFluidHeightPercent(){ + return (($this->falling ? 0 : $this->decay) + 1) / 9; } protected function getEffectiveFlowDecay(Block $block) : int{ - if($block->getId() !== $this->getId()){ + if(!($block instanceof Liquid) or $block->getId() !== $this->getId()){ return -1; } - $decay = $block->getDamage(); - - if($decay >= 8){ - $decay = 0; - } - - return $decay; + return $block->falling ? 0 : $block->decay; } public function clearCaches() : void{ @@ -170,7 +173,7 @@ abstract class Liquid extends Transparent{ } } - if($this->getDamage() >= 8){ + if($this->falling){ if( !$this->canFlowInto($this->level->getBlockAt($this->x, $this->y, $this->z - 1)) or !$this->canFlowInto($this->level->getBlockAt($this->x, $this->y, $this->z + 1)) or @@ -214,10 +217,9 @@ abstract class Liquid extends Transparent{ } public function onScheduledUpdate() : void{ - $decay = $this->getFlowDecay($this); $multiplier = $this->getFlowDecayPerBlock(); - if($decay > 0){ + if(!$this->isSource()){ $smallestFlowDecay = -100; $this->adjacentSources = 0; $smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlockAt($this->x, $this->y, $this->z - 1), $smallestFlowDecay); @@ -226,80 +228,81 @@ abstract class Liquid extends Transparent{ $smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlockAt($this->x + 1, $this->y, $this->z), $smallestFlowDecay); $newDecay = $smallestFlowDecay + $multiplier; + $falling = false; if($newDecay >= 8 or $smallestFlowDecay < 0){ $newDecay = -1; } - if(($topFlowDecay = $this->getFlowDecay($this->level->getBlockAt($this->x, $this->y + 1, $this->z))) >= 0){ - $newDecay = $topFlowDecay | 0x08; + if($this->getEffectiveFlowDecay($this->level->getBlockAt($this->x, $this->y + 1, $this->z)) >= 0){ + $falling = true; } if($this->adjacentSources >= 2 and $this instanceof Water){ $bottomBlock = $this->level->getBlockAt($this->x, $this->y - 1, $this->z); - if($bottomBlock->isSolid()){ - $newDecay = 0; - }elseif($bottomBlock instanceof Water and $bottomBlock->getDamage() === 0){ + if($bottomBlock->isSolid() or ($bottomBlock instanceof Water and $bottomBlock->isSource())){ $newDecay = 0; + $falling = false; } } - if($newDecay !== $decay){ - $decay = $newDecay; - if($decay < 0){ + if($newDecay !== $this->decay or $falling !== $this->falling){ + if(!$falling and $newDecay < 0){ $this->level->setBlock($this, BlockFactory::get(Block::AIR), true, true); - }else{ - $this->level->setBlock($this, BlockFactory::get($this->id, $decay), true, true); - $this->level->scheduleDelayedBlockUpdate($this, $this->tickRate()); + return; + } + + $this->falling = $falling; + $this->decay = $falling ? 0 : $newDecay; + $this->level->setBlock($this, $this, true, true); //local block update will cause an update to be scheduled + } + } + + $bottomBlock = $this->level->getBlockAt($this->x, $this->y - 1, $this->z); + + $this->flowIntoBlock($bottomBlock, 0, true); + + if($this->isSource() or !$bottomBlock->canBeFlowedInto()){ + if($this->falling){ + $adjacentDecay = 1; //falling liquid behaves like source block + }else{ + $adjacentDecay = $this->decay + $multiplier; + } + + if($adjacentDecay < 8){ + $flags = $this->getOptimalFlowDirections(); + + if($flags[0]){ + $this->flowIntoBlock($this->level->getBlockAt($this->x - 1, $this->y, $this->z), $adjacentDecay, false); + } + + if($flags[1]){ + $this->flowIntoBlock($this->level->getBlockAt($this->x + 1, $this->y, $this->z), $adjacentDecay, false); + } + + if($flags[2]){ + $this->flowIntoBlock($this->level->getBlockAt($this->x, $this->y, $this->z - 1), $adjacentDecay, false); + } + + if($flags[3]){ + $this->flowIntoBlock($this->level->getBlockAt($this->x, $this->y, $this->z + 1), $adjacentDecay, false); } } } - if($decay >= 0){ - $bottomBlock = $this->level->getBlockAt($this->x, $this->y - 1, $this->z); - - $this->flowIntoBlock($bottomBlock, $decay | 0x08); - - if($decay === 0 or !$bottomBlock->canBeFlowedInto()){ - if($decay >= 8){ - $adjacentDecay = 1; - }else{ - $adjacentDecay = $decay + $multiplier; - } - - if($adjacentDecay < 8){ - $flags = $this->getOptimalFlowDirections(); - - if($flags[0]){ - $this->flowIntoBlock($this->level->getBlockAt($this->x - 1, $this->y, $this->z), $adjacentDecay); - } - - if($flags[1]){ - $this->flowIntoBlock($this->level->getBlockAt($this->x + 1, $this->y, $this->z), $adjacentDecay); - } - - if($flags[2]){ - $this->flowIntoBlock($this->level->getBlockAt($this->x, $this->y, $this->z - 1), $adjacentDecay); - } - - if($flags[3]){ - $this->flowIntoBlock($this->level->getBlockAt($this->x, $this->y, $this->z + 1), $adjacentDecay); - } - } - } - - $this->checkForHarden(); - } + $this->checkForHarden(); } - protected function flowIntoBlock(Block $block, int $newFlowDecay) : void{ + protected function flowIntoBlock(Block $block, int $newFlowDecay, bool $falling) : void{ if($this->canFlowInto($block) and !($block instanceof Liquid)){ if($block->getId() > 0){ $this->level->useBreakOn($block); } - $this->level->setBlock($block, BlockFactory::get($this->getId(), $newFlowDecay), true, true); - $this->level->scheduleDelayedBlockUpdate($block, $this->tickRate()); + $new = clone $this; + $new->falling = $falling; + $new->decay = $falling ? 0 : $newFlowDecay; + $this->level->setBlock($block, $new, true, true); } } @@ -407,13 +410,15 @@ abstract class Liquid extends Transparent{ } private function getSmallestFlowDecay(Block $block, int $decay) : int{ - $blockDecay = $this->getFlowDecay($block); - - if($blockDecay < 0){ + if(!($block instanceof Liquid) or $block->getId() !== $this->getId()){ return $decay; - }elseif($blockDecay === 0){ + } + + $blockDecay = $block->decay; + + if($block->isSource()){ ++$this->adjacentSources; - }elseif($blockDecay >= 8){ + }elseif($block->falling){ $blockDecay = 0; } @@ -433,6 +438,6 @@ abstract class Liquid extends Transparent{ } protected function canFlowInto(Block $block) : bool{ - return $block->canBeFlowedInto() and !($block instanceof Liquid and $block->meta === 0); //TODO: I think this should only be liquids of the same type + return $block->canBeFlowedInto() and !($block instanceof Liquid and $block->isSource()); //TODO: I think this should only be liquids of the same type } } diff --git a/src/pocketmine/block/LitRedstoneLamp.php b/src/pocketmine/block/LitRedstoneLamp.php deleted file mode 100644 index ecc8128f0c..0000000000 --- a/src/pocketmine/block/LitRedstoneLamp.php +++ /dev/null @@ -1,37 +0,0 @@ -setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/Melon.php b/src/pocketmine/block/Melon.php index 649f839d21..c21cff0c63 100644 --- a/src/pocketmine/block/Melon.php +++ b/src/pocketmine/block/Melon.php @@ -30,8 +30,8 @@ class Melon extends Transparent{ protected $id = self::MELON_BLOCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/MelonStem.php b/src/pocketmine/block/MelonStem.php index e8763cb2d5..aeb6eabc7d 100644 --- a/src/pocketmine/block/MelonStem.php +++ b/src/pocketmine/block/MelonStem.php @@ -37,15 +37,11 @@ class MelonStem extends Crops{ return "Melon Stem"; } - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - public function onRandomTick() : void{ if(mt_rand(0, 2) === 1){ - if($this->meta < 0x07){ + if($this->age < 7){ $block = clone $this; - ++$block->meta; + ++$block->age; Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block)); if(!$ev->isCancelled()){ $this->getLevel()->setBlock($this, $ev->getNewState(), true); diff --git a/src/pocketmine/block/MonsterSpawner.php b/src/pocketmine/block/MonsterSpawner.php index 4829fd4f86..d4fc111978 100644 --- a/src/pocketmine/block/MonsterSpawner.php +++ b/src/pocketmine/block/MonsterSpawner.php @@ -30,8 +30,8 @@ class MonsterSpawner extends Transparent{ protected $id = self::MONSTER_SPAWNER; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getHardness() : float{ diff --git a/src/pocketmine/block/Mycelium.php b/src/pocketmine/block/Mycelium.php index 1c5692a52a..b56edf7556 100644 --- a/src/pocketmine/block/Mycelium.php +++ b/src/pocketmine/block/Mycelium.php @@ -33,8 +33,8 @@ class Mycelium extends Solid{ protected $id = self::MYCELIUM; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/NetherBrickFence.php b/src/pocketmine/block/NetherBrickFence.php index 099518fd25..b8cd98afb1 100644 --- a/src/pocketmine/block/NetherBrickFence.php +++ b/src/pocketmine/block/NetherBrickFence.php @@ -29,6 +29,10 @@ class NetherBrickFence extends Fence{ protected $id = self::NETHER_BRICK_FENCE; + public function __construct(){ + + } + public function getHardness() : float{ return 2; } diff --git a/src/pocketmine/block/NetherBrickStairs.php b/src/pocketmine/block/NetherBrickStairs.php index 190a66e3c3..f67c877950 100644 --- a/src/pocketmine/block/NetherBrickStairs.php +++ b/src/pocketmine/block/NetherBrickStairs.php @@ -29,8 +29,8 @@ class NetherBrickStairs extends Stair{ protected $id = self::NETHER_BRICK_STAIRS; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/NetherQuartzOre.php b/src/pocketmine/block/NetherQuartzOre.php index 7280203a53..7405acf63e 100644 --- a/src/pocketmine/block/NetherQuartzOre.php +++ b/src/pocketmine/block/NetherQuartzOre.php @@ -31,8 +31,8 @@ class NetherQuartzOre extends Solid{ protected $id = Block::NETHER_QUARTZ_ORE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/NetherReactor.php b/src/pocketmine/block/NetherReactor.php index fdaa0cb86a..1ea1a3332f 100644 --- a/src/pocketmine/block/NetherReactor.php +++ b/src/pocketmine/block/NetherReactor.php @@ -28,19 +28,33 @@ use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; class NetherReactor extends Solid{ + protected const STATE_INACTIVE = 0; + protected const STATE_ACTIVE = 1; + protected const STATE_USED = 2; + protected $id = Block::NETHER_REACTOR; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $state = self::STATE_INACTIVE; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return $this->state; + } + + public function readStateFromMeta(int $meta) : void{ + $this->state = $meta; + } + + public function getStateBitmask() : int{ + return 0b11; } public function getName() : string{ - static $prefixes = [ - "", - "Active ", - "Used " - ]; - return ($prefixes[$this->meta] ?? "") . "Nether Reactor Core"; + return "Nether Reactor Core"; } public function getToolType() : int{ diff --git a/src/pocketmine/block/NetherWartBlock.php b/src/pocketmine/block/NetherWartBlock.php index ac960d9206..21cdc6f50c 100644 --- a/src/pocketmine/block/NetherWartBlock.php +++ b/src/pocketmine/block/NetherWartBlock.php @@ -27,8 +27,8 @@ class NetherWartBlock extends Solid{ protected $id = Block::NETHER_WART_BLOCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index 50dd5dbbef..eb68dd3e7c 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -36,8 +36,23 @@ class NetherWartPlant extends Flowable{ protected $itemId = Item::NETHER_WART; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $age = 0; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return $this->age; + } + + public function readStateFromMeta(int $meta) : void{ + $this->age = $meta; + } + + public function getStateBitmask() : int{ + return 0b11; } public function getName() : string{ @@ -64,9 +79,9 @@ class NetherWartPlant extends Flowable{ } public function onRandomTick() : void{ - if($this->meta < 3 and mt_rand(0, 10) === 0){ //Still growing + if($this->age < 3 and mt_rand(0, 10) === 0){ //Still growing $block = clone $this; - $block->meta++; + $block->age++; $this->getLevel()->getServer()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block)); if(!$ev->isCancelled()){ @@ -77,7 +92,7 @@ class NetherWartPlant extends Flowable{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get($this->getItemId(), 0, ($this->getDamage() === 3 ? mt_rand(2, 4) : 1)) + ItemFactory::get($this->getItemId(), 0, ($this->age === 3 ? mt_rand(2, 4) : 1)) ]; } diff --git a/src/pocketmine/block/Netherrack.php b/src/pocketmine/block/Netherrack.php index 823a6b30c5..1a79ea9f9e 100644 --- a/src/pocketmine/block/Netherrack.php +++ b/src/pocketmine/block/Netherrack.php @@ -29,8 +29,8 @@ class Netherrack extends Solid{ protected $id = self::NETHERRACK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/NoteBlock.php b/src/pocketmine/block/NoteBlock.php index 4dc4fe9d49..4c30cb60fe 100644 --- a/src/pocketmine/block/NoteBlock.php +++ b/src/pocketmine/block/NoteBlock.php @@ -27,8 +27,8 @@ class NoteBlock extends Solid{ protected $id = self::NOTE_BLOCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/Obsidian.php b/src/pocketmine/block/Obsidian.php index f37298483b..ba821ec1bc 100644 --- a/src/pocketmine/block/Obsidian.php +++ b/src/pocketmine/block/Obsidian.php @@ -29,8 +29,8 @@ class Obsidian extends Solid{ protected $id = self::OBSIDIAN; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/PackedIce.php b/src/pocketmine/block/PackedIce.php index d80c91839c..6ca48c390f 100644 --- a/src/pocketmine/block/PackedIce.php +++ b/src/pocketmine/block/PackedIce.php @@ -27,8 +27,8 @@ class PackedIce extends Solid{ protected $id = self::PACKED_ICE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/Planks.php b/src/pocketmine/block/Planks.php index 9e5efe7056..2acf2c0719 100644 --- a/src/pocketmine/block/Planks.php +++ b/src/pocketmine/block/Planks.php @@ -24,18 +24,6 @@ declare(strict_types=1); namespace pocketmine\block; class Planks extends Solid{ - public const OAK = 0; - public const SPRUCE = 1; - public const BIRCH = 2; - public const JUNGLE = 3; - public const ACACIA = 4; - public const DARK_OAK = 5; - - protected $id = self::WOODEN_PLANKS; - - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } public function getHardness() : float{ return 2; @@ -45,18 +33,6 @@ class Planks extends Solid{ return BlockToolType::TYPE_AXE; } - public function getName() : string{ - static $names = [ - self::OAK => "Oak Wood Planks", - self::SPRUCE => "Spruce Wood Planks", - self::BIRCH => "Birch Wood Planks", - self::JUNGLE => "Jungle Wood Planks", - self::ACACIA => "Acacia Wood Planks", - self::DARK_OAK => "Dark Oak Wood Planks" - ]; - return $names[$this->getVariant()] ?? "Unknown"; - } - public function getFuelTime() : int{ return 300; } diff --git a/src/pocketmine/block/Podzol.php b/src/pocketmine/block/Podzol.php index 470c8fabd7..be44cf1b42 100644 --- a/src/pocketmine/block/Podzol.php +++ b/src/pocketmine/block/Podzol.php @@ -27,8 +27,8 @@ class Podzol extends Solid{ protected $id = self::PODZOL; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getToolType() : int{ diff --git a/src/pocketmine/block/Potato.php b/src/pocketmine/block/Potato.php index 87d0efa2de..9c00722fa0 100644 --- a/src/pocketmine/block/Potato.php +++ b/src/pocketmine/block/Potato.php @@ -30,17 +30,13 @@ class Potato extends Crops{ protected $id = self::POTATO_BLOCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - public function getName() : string{ return "Potato Block"; } public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::POTATO, 0, $this->getDamage() >= 0x07 ? mt_rand(1, 4) : 1) + ItemFactory::get(Item::POTATO, 0, $this->age >= 7 ? mt_rand(1, 4) : 1) ]; } diff --git a/src/pocketmine/block/Prismarine.php b/src/pocketmine/block/Prismarine.php index 42a3fad713..c850bfaaf6 100644 --- a/src/pocketmine/block/Prismarine.php +++ b/src/pocketmine/block/Prismarine.php @@ -31,25 +31,10 @@ class Prismarine extends Solid{ public const DARK = 1; public const BRICKS = 2; - protected $id = self::PRISMARINE; - - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - public function getHardness() : float{ return 1.5; } - public function getName() : string{ - static $names = [ - self::NORMAL => "Prismarine", - self::DARK => "Dark Prismarine", - self::BRICKS => "Prismarine Bricks" - ]; - return $names[$this->getVariant()] ?? "Unknown"; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } @@ -57,8 +42,4 @@ class Prismarine extends Solid{ public function getToolHarvestLevel() : int{ return TieredTool::TIER_WOODEN; } - - public function getVariantBitmask() : int{ - return 0x03; - } } diff --git a/src/pocketmine/block/Pumpkin.php b/src/pocketmine/block/Pumpkin.php index 598114b1e2..245996a717 100644 --- a/src/pocketmine/block/Pumpkin.php +++ b/src/pocketmine/block/Pumpkin.php @@ -27,8 +27,8 @@ class Pumpkin extends Solid{ protected $id = self::PUMPKIN; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getHardness() : float{ @@ -42,8 +42,4 @@ class Pumpkin extends Solid{ public function getName() : string{ return "Pumpkin"; } - - public function getVariantBitmask() : int{ - return 0; - } } diff --git a/src/pocketmine/block/PumpkinStem.php b/src/pocketmine/block/PumpkinStem.php index dba366297b..1c916606b2 100644 --- a/src/pocketmine/block/PumpkinStem.php +++ b/src/pocketmine/block/PumpkinStem.php @@ -33,19 +33,15 @@ class PumpkinStem extends Crops{ protected $id = self::PUMPKIN_STEM; - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - public function getName() : string{ return "Pumpkin Stem"; } public function onRandomTick() : void{ if(mt_rand(0, 2) === 1){ - if($this->meta < 0x07){ + if($this->age < 7){ $block = clone $this; - ++$block->meta; + ++$block->age; Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block)); if(!$ev->isCancelled()){ $this->getLevel()->setBlock($this, $ev->getNewState(), true); diff --git a/src/pocketmine/block/Purpur.php b/src/pocketmine/block/Purpur.php index 30854b62bb..a2e3c49f6b 100644 --- a/src/pocketmine/block/Purpur.php +++ b/src/pocketmine/block/Purpur.php @@ -25,18 +25,6 @@ namespace pocketmine\block; class Purpur extends Quartz{ - protected $id = self::PURPUR_BLOCK; - - public function getName() : string{ - static $names = [ - self::NORMAL => "Purpur Block", - self::CHISELED => "Chiseled Purpur", //wtf? - self::PILLAR => "Purpur Pillar" - ]; - - return $names[$this->getVariant()] ?? "Unknown"; - } - public function getHardness() : float{ return 1.5; } diff --git a/src/pocketmine/block/PurpurStairs.php b/src/pocketmine/block/PurpurStairs.php index 4e21183c57..49409be4fa 100644 --- a/src/pocketmine/block/PurpurStairs.php +++ b/src/pocketmine/block/PurpurStairs.php @@ -29,8 +29,8 @@ class PurpurStairs extends Stair{ protected $id = self::PURPUR_STAIRS; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/Quartz.php b/src/pocketmine/block/Quartz.php index 162191d9e8..eb66aaff9c 100644 --- a/src/pocketmine/block/Quartz.php +++ b/src/pocketmine/block/Quartz.php @@ -23,40 +23,27 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\PillarRotationHelper; +use pocketmine\block\utils\PillarRotationTrait; use pocketmine\item\Item; use pocketmine\item\TieredTool; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; class Quartz extends Solid{ + use PillarRotationTrait; public const NORMAL = 0; public const CHISELED = 1; public const PILLAR = 2; - protected $id = self::QUARTZ_BLOCK; - - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - public function getHardness() : float{ return 0.8; } - public function getName() : string{ - static $names = [ - self::NORMAL => "Quartz Block", - self::CHISELED => "Chiseled Quartz Block", - self::PILLAR => "Quartz Pillar" - ]; - return $names[$this->getVariant()] ?? "Unknown"; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if($this->meta !== self::NORMAL){ - $this->meta = PillarRotationHelper::getMetaFromFace($this->meta, $face); + if($this->variant !== self::NORMAL){ + $this->axis = Facing::axis($face); } return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -68,8 +55,4 @@ class Quartz extends Solid{ public function getToolHarvestLevel() : int{ return TieredTool::TIER_WOODEN; } - - public function getVariantBitmask() : int{ - return 0x03; - } } diff --git a/src/pocketmine/block/QuartzStairs.php b/src/pocketmine/block/QuartzStairs.php index e748ca3856..56b93156d9 100644 --- a/src/pocketmine/block/QuartzStairs.php +++ b/src/pocketmine/block/QuartzStairs.php @@ -29,8 +29,8 @@ class QuartzStairs extends Stair{ protected $id = self::QUARTZ_STAIRS; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getHardness() : float{ diff --git a/src/pocketmine/block/Rail.php b/src/pocketmine/block/Rail.php index 643e61ff00..b7d5ab8a9f 100644 --- a/src/pocketmine/block/Rail.php +++ b/src/pocketmine/block/Rail.php @@ -66,8 +66,8 @@ class Rail extends BaseRail{ } } - protected function getConnectionsForState() : array{ - return self::CURVE_CONNECTIONS[$this->meta] ?? self::CONNECTIONS[$this->meta]; + protected function getConnectionsFromMeta(int $meta) : array{ + return self::CURVE_CONNECTIONS[$meta] ?? self::CONNECTIONS[$meta] ?? []; } protected function getPossibleConnectionDirectionsOneConstraint(int $constraint) : array{ diff --git a/src/pocketmine/block/RedMushroom.php b/src/pocketmine/block/RedMushroom.php index 1ed6076970..be4d6e1bbb 100644 --- a/src/pocketmine/block/RedMushroom.php +++ b/src/pocketmine/block/RedMushroom.php @@ -32,8 +32,8 @@ class RedMushroom extends Flowable{ protected $id = self::RED_MUSHROOM; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/RedMushroomBlock.php b/src/pocketmine/block/RedMushroomBlock.php index f892138670..3281b8d46b 100644 --- a/src/pocketmine/block/RedMushroomBlock.php +++ b/src/pocketmine/block/RedMushroomBlock.php @@ -29,8 +29,29 @@ class RedMushroomBlock extends Solid{ protected $id = Block::RED_MUSHROOM_BLOCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** + * @var int + * In PC they have blockstate properties for each of the sides (pores/not pores). Unfortunately, we can't support + * that because we can't serialize 2^6 combinations into a 4-bit metadata value, so this has to stick with storing + * the legacy crap for now. + * TODO: change this once proper blockstates are implemented + */ + protected $rotationData = 0; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return $this->rotationData; + } + + public function readStateFromMeta(int $meta) : void{ + $this->rotationData = $meta; + } + + public function getStateBitmask() : int{ + return 0b1111; } public function getName() : string{ diff --git a/src/pocketmine/block/RedSandstone.php b/src/pocketmine/block/RedSandstone.php deleted file mode 100644 index 8c2372ccc5..0000000000 --- a/src/pocketmine/block/RedSandstone.php +++ /dev/null @@ -1,37 +0,0 @@ - "Red Sandstone", - self::CHISELED => "Chiseled Red Sandstone", - self::SMOOTH => "Smooth Red Sandstone" - ]; - return $names[$this->getVariant()] ?? "Unknown"; - } -} diff --git a/src/pocketmine/block/Redstone.php b/src/pocketmine/block/Redstone.php index 7430138c94..f88c571a0a 100644 --- a/src/pocketmine/block/Redstone.php +++ b/src/pocketmine/block/Redstone.php @@ -29,8 +29,8 @@ class Redstone extends Solid{ protected $id = self::REDSTONE_BLOCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getHardness() : float{ diff --git a/src/pocketmine/block/RedstoneLamp.php b/src/pocketmine/block/RedstoneLamp.php index 8a33c6e946..421268d7e6 100644 --- a/src/pocketmine/block/RedstoneLamp.php +++ b/src/pocketmine/block/RedstoneLamp.php @@ -25,10 +25,29 @@ namespace pocketmine\block; class RedstoneLamp extends Solid{ - protected $id = self::REDSTONE_LAMP; + protected $itemId = self::REDSTONE_LAMP; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var bool */ + protected $lit = false; + + public function __construct(){ + + } + + public function getId() : int{ + return $this->lit ? self::LIT_REDSTONE_LAMP : self::REDSTONE_LAMP; + } + + public function isLit() : bool{ + return $this->lit; + } + + public function setLit(bool $lit = true) : void{ + $this->lit = $lit; + } + + public function getLightLevel() : int{ + return $this->lit ? 15 : 0; } public function getName() : string{ diff --git a/src/pocketmine/block/RedstoneOre.php b/src/pocketmine/block/RedstoneOre.php index b0900799e8..495634a3bf 100644 --- a/src/pocketmine/block/RedstoneOre.php +++ b/src/pocketmine/block/RedstoneOre.php @@ -31,10 +31,17 @@ use pocketmine\Player; class RedstoneOre extends Solid{ - protected $id = self::REDSTONE_ORE; + protected $itemId = self::REDSTONE_ORE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var bool */ + protected $lit = false; + + public function __construct(){ + + } + + public function getId() : int{ + return $this->lit ? self::GLOWING_REDSTONE_ORE : self::REDSTONE_ORE; } public function getName() : string{ @@ -45,17 +52,46 @@ class RedstoneOre extends Solid{ return 3; } + public function isLit() : bool{ + return $this->lit; + } + + public function setLit(bool $lit = true) : void{ + $this->lit = $lit; + } + + public function getLightLevel() : int{ + return $this->lit ? 9 : 0; + } + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ return $this->getLevel()->setBlock($this, $this, true, false); } public function onActivate(Item $item, Player $player = null) : bool{ - $this->getLevel()->setBlock($this, BlockFactory::get(Block::GLOWING_REDSTONE_ORE, $this->meta)); - return false; //this shouldn't prevent block placement + if(!$this->lit){ + $this->lit = true; + $this->getLevel()->setBlock($this, $this); //no return here - this shouldn't prevent block placement + } + return false; } public function onNearbyBlockChange() : void{ - $this->getLevel()->setBlock($this, BlockFactory::get(Block::GLOWING_REDSTONE_ORE, $this->meta)); + if(!$this->lit){ + $this->lit = true; + $this->getLevel()->setBlock($this, $this); + } + } + + public function ticksRandomly() : bool{ + return true; + } + + public function onRandomTick() : void{ + if($this->lit){ + $this->lit = false; + $this->level->setBlock($this, $this); + } } public function getToolType() : int{ diff --git a/src/pocketmine/block/RedstoneRail.php b/src/pocketmine/block/RedstoneRail.php index 7d3b9cd4c0..a02f11635d 100644 --- a/src/pocketmine/block/RedstoneRail.php +++ b/src/pocketmine/block/RedstoneRail.php @@ -26,7 +26,23 @@ namespace pocketmine\block; class RedstoneRail extends BaseRail{ protected const FLAG_POWERED = 0x08; - protected function getConnectionsForState() : array{ - return self::CONNECTIONS[$this->meta & ~self::FLAG_POWERED]; + /** @var bool */ + protected $powered = false; + + protected function writeStateToMeta() : int{ + return parent::writeStateToMeta() | ($this->powered ? self::FLAG_POWERED : 0); + } + + public function readStateFromMeta(int $meta) : void{ + parent::readStateFromMeta($meta); + $this->powered = ($meta & self::FLAG_POWERED) !== 0; + } + + public function getStateBitmask() : int{ + return 0b1111; + } + + protected function getConnectionsFromMeta(int $meta) : array{ + return self::CONNECTIONS[$meta & ~self::FLAG_POWERED] ?? []; } } diff --git a/src/pocketmine/block/RedstoneTorch.php b/src/pocketmine/block/RedstoneTorch.php index 4d0770d1dd..c8b9ab9a5b 100644 --- a/src/pocketmine/block/RedstoneTorch.php +++ b/src/pocketmine/block/RedstoneTorch.php @@ -25,13 +25,28 @@ namespace pocketmine\block; class RedstoneTorch extends Torch{ - protected $id = self::LIT_REDSTONE_TORCH; + protected $itemId = self::REDSTONE_TORCH; + + /** @var bool */ + protected $lit = true; + + public function getId() : int{ + return $this->lit ? self::REDSTONE_TORCH : self::UNLIT_REDSTONE_TORCH; + } public function getName() : string{ return "Redstone Torch"; } + public function isLit() : bool{ + return $this->lit; + } + + public function setLit(bool $lit = true) : void{ + $this->lit = $lit; + } + public function getLightLevel() : int{ - return 7; + return $this->lit ? 7 : 0; } } diff --git a/src/pocketmine/block/RedstoneTorchUnlit.php b/src/pocketmine/block/RedstoneTorchUnlit.php deleted file mode 100644 index f074d0f666..0000000000 --- a/src/pocketmine/block/RedstoneTorchUnlit.php +++ /dev/null @@ -1,37 +0,0 @@ -setDamage($meta); - } - public function getHardness() : float{ return 0.5; } @@ -38,12 +32,4 @@ class Sand extends Fallable{ public function getToolType() : int{ return BlockToolType::TYPE_SHOVEL; } - - public function getName() : string{ - if($this->meta === 0x01){ - return "Red Sand"; - } - - return "Sand"; - } } diff --git a/src/pocketmine/block/Sandstone.php b/src/pocketmine/block/Sandstone.php index d7b829801d..17571564a8 100644 --- a/src/pocketmine/block/Sandstone.php +++ b/src/pocketmine/block/Sandstone.php @@ -31,25 +31,10 @@ class Sandstone extends Solid{ public const CHISELED = 1; public const SMOOTH = 2; - protected $id = self::SANDSTONE; - - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - public function getHardness() : float{ return 0.8; } - public function getName() : string{ - static $names = [ - self::NORMAL => "Sandstone", - self::CHISELED => "Chiseled Sandstone", - self::SMOOTH => "Smooth Sandstone" - ]; - return $names[$this->getVariant()] ?? "Unknown"; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } @@ -57,8 +42,4 @@ class Sandstone extends Solid{ public function getToolHarvestLevel() : int{ return TieredTool::TIER_WOODEN; } - - public function getVariantBitmask() : int{ - return 0x03; - } } diff --git a/src/pocketmine/block/SandstoneStairs.php b/src/pocketmine/block/SandstoneStairs.php index 4bdc87b7f5..aeeb0152e3 100644 --- a/src/pocketmine/block/SandstoneStairs.php +++ b/src/pocketmine/block/SandstoneStairs.php @@ -29,8 +29,8 @@ class SandstoneStairs extends Stair{ protected $id = self::SANDSTONE_STAIRS; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getHardness() : float{ diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index 8c9db99e95..3ec18bf9ff 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -31,29 +31,20 @@ use pocketmine\Player; use pocketmine\utils\Random; class Sapling extends Flowable{ - public const OAK = 0; - public const SPRUCE = 1; - public const BIRCH = 2; - public const JUNGLE = 3; - public const ACACIA = 4; - public const DARK_OAK = 5; - protected $id = self::SAPLING; + /** @var bool */ + protected $ready = false; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + protected function writeStateToMeta() : int{ + return ($this->ready ? 0x08 : 0); } - public function getName() : string{ - static $names = [ - 0 => "Oak Sapling", - 1 => "Spruce Sapling", - 2 => "Birch Sapling", - 3 => "Jungle Sapling", - 4 => "Acacia Sapling", - 5 => "Dark Oak Sapling" - ]; - return $names[$this->getVariant()] ?? "Unknown"; + public function readStateFromMeta(int $meta) : void{ + $this->ready = ($meta & 0x08) !== 0; + } + + public function getStateBitmask() : int{ + return 0b1000; } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ @@ -90,19 +81,15 @@ class Sapling extends Flowable{ public function onRandomTick() : void{ if($this->level->getFullLightAt($this->x, $this->y, $this->z) >= 8 and mt_rand(1, 7) === 1){ - if(($this->meta & 0x08) === 0x08){ + if($this->ready){ Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->getVariant()); }else{ - $this->meta |= 0x08; + $this->ready = true; $this->getLevel()->setBlock($this, $this, true); } } } - public function getVariantBitmask() : int{ - return 0x07; - } - public function getFuelTime() : int{ return 100; } diff --git a/src/pocketmine/block/SeaLantern.php b/src/pocketmine/block/SeaLantern.php index 5fcaa87f05..3d0e3009fc 100644 --- a/src/pocketmine/block/SeaLantern.php +++ b/src/pocketmine/block/SeaLantern.php @@ -30,8 +30,8 @@ class SeaLantern extends Transparent{ protected $id = self::SEA_LANTERN; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/SignPost.php b/src/pocketmine/block/SignPost.php index 87e47aea79..b37ec9e842 100644 --- a/src/pocketmine/block/SignPost.php +++ b/src/pocketmine/block/SignPost.php @@ -37,8 +37,23 @@ class SignPost extends Transparent{ protected $itemId = Item::SIGN; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $rotation = 0; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return $this->rotation; + } + + public function readStateFromMeta(int $meta) : void{ + $this->rotation = $meta; + } + + public function getStateBitmask() : int{ + return 0b1111; } public function getHardness() : float{ @@ -57,16 +72,14 @@ class SignPost extends Transparent{ return null; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($face !== Facing::DOWN){ if($face === Facing::UP){ - $this->meta = $player !== null ? (floor((($player->yaw + 180) * 16 / 360) + 0.5) & 0x0f) : 0; + $this->rotation = $player !== null ? ((int) floor((($player->yaw + 180) * 16 / 360) + 0.5)) & 0x0f : 0; $ret = parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); }else{ - $this->meta = $face; - $ret = $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::WALL_SIGN, $this->meta), true); + $ret = $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::WALL_SIGN, $face), true); } if($ret){ @@ -87,8 +100,4 @@ class SignPost extends Transparent{ public function getToolType() : int{ return BlockToolType::TYPE_AXE; } - - public function getVariantBitmask() : int{ - return 0; - } } diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index bdfaef4a16..8eb9677e95 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -36,8 +36,23 @@ class Skull extends Flowable{ protected $id = self::SKULL_BLOCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $facing = Facing::NORTH; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return $this->facing; + } + + public function readStateFromMeta(int $meta) : void{ + $this->facing = $meta; + } + + public function getStateBitmask() : int{ + return 0b111; } public function getHardness() : float{ @@ -49,7 +64,7 @@ class Skull extends Flowable{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - //TODO: different bounds depending on attached face (meta) + //TODO: different bounds depending on attached face static $f = 0.25; return new AxisAlignedBB($f, 0, $f, 1 - $f, 0.5, 1 - $f); } @@ -59,7 +74,7 @@ class Skull extends Flowable{ return false; } - $this->meta = $face; + $this->facing = $face; if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ Tile::createTile(Tile::SKULL, $this->getLevel(), TileSkull::createNBT($this, $face, $item, $player)); return true; diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index 26ea65ca37..abe6561fc1 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -30,20 +30,40 @@ use pocketmine\math\Vector3; use pocketmine\Player; abstract class Slab extends Transparent{ + /** @var int */ + protected $doubleId; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var bool */ + protected $top = false; + + public function __construct(int $id, int $doubleId, int $variant = 0, ?string $name = null){ + parent::__construct($id, $variant, $name . " Slab"); + $this->doubleId = $doubleId; } - abstract public function getDoubleSlabId() : int; + protected function writeStateToMeta() : int{ + return ($this->top ? 0x08 : 0); + } + + public function readStateFromMeta(int $meta) : void{ + $this->top = ($meta & 0x08) !== 0; + } + + public function getStateBitmask() : int{ + return 0b1000; + } + + public function getDoubleSlabId() : int{ + return $this->doubleId; + } public function canBePlacedAt(Block $blockReplace, Vector3 $clickVector, int $face, bool $isClickedBlock) : bool{ if(parent::canBePlacedAt($blockReplace, $clickVector, $face, $isClickedBlock)){ return true; } - if($blockReplace->getId() === $this->getId() and $blockReplace->getVariant() === $this->getVariant()){ - if(($blockReplace->getDamage() & 0x08) !== 0){ //Trying to combine with top slab + if($blockReplace instanceof Slab and $blockReplace->getId() === $this->getId() and $blockReplace->getVariant() === $this->variant){ + if($blockReplace->top){ //Trying to combine with top slab return $clickVector->y <= 0.5 or (!$isClickedBlock and $face === Facing::UP); }else{ return $clickVector->y >= 0.5 or (!$isClickedBlock and $face === Facing::DOWN); @@ -54,33 +74,32 @@ abstract class Slab extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $this->meta &= 0x07; if($face === Facing::DOWN){ - if($blockClicked->getId() === $this->id and ($blockClicked->getDamage() & 0x08) === 0x08 and $blockClicked->getVariant() === $this->getVariant()){ - $this->getLevel()->setBlock($blockClicked, BlockFactory::get($this->getDoubleSlabId(), $this->getVariant()), true); + if($blockClicked instanceof Slab and $blockClicked->getId() === $this->getId() and $blockClicked->top and $blockClicked->getVariant() === $this->variant){ + $this->getLevel()->setBlock($blockClicked, BlockFactory::get($this->getDoubleSlabId(), $this->variant), true); return true; - }elseif($blockReplace->getId() === $this->id and $blockReplace->getVariant() === $this->getVariant()){ - $this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->getVariant()), true); + }elseif($blockReplace->getId() === $this->getId() and $blockReplace->getVariant() === $this->variant){ + $this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->variant), true); return true; }else{ - $this->meta |= 0x08; + $this->top = true; } }elseif($face === Facing::UP){ - if($blockClicked->getId() === $this->id and ($blockClicked->getDamage() & 0x08) === 0 and $blockClicked->getVariant() === $this->getVariant()){ - $this->getLevel()->setBlock($blockClicked, BlockFactory::get($this->getDoubleSlabId(), $this->getVariant()), true); + if($blockClicked instanceof Slab and $blockClicked->getId() === $this->getId() and !$blockClicked->top and $blockClicked->getVariant() === $this->variant){ + $this->getLevel()->setBlock($blockClicked, BlockFactory::get($this->getDoubleSlabId(), $this->variant), true); return true; - }elseif($blockReplace->getId() === $this->id and $blockReplace->getVariant() === $this->getVariant()){ - $this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->getVariant()), true); + }elseif($blockReplace->getId() === $this->getId() and $blockReplace->getVariant() === $this->variant){ + $this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->variant), true); return true; } }else{ //TODO: collision - if($blockReplace->getId() === $this->id){ - if($blockReplace->getVariant() === $this->meta){ - $this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->getVariant()), true); + if($blockReplace->getId() === $this->getId()){ + if($blockReplace->getVariant() === $this->variant){ + $this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->variant), true); return true; } @@ -88,25 +107,20 @@ abstract class Slab extends Transparent{ return false; }else{ if($clickVector->y > 0.5){ - $this->meta |= 0x08; + $this->top = true; } } } - if($blockReplace->getId() === $this->id and $blockClicked->getVariant() !== $this->getVariant()){ + if($blockReplace->getId() === $this->getId() and $blockClicked->getVariant() !== $this->variant){ return false; } return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - public function getVariantBitmask() : int{ - return 0x07; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - - if(($this->meta & 0x08) > 0){ + if($this->top){ return new AxisAlignedBB(0, 0.5, 0, 1, 1, 1); }else{ return new AxisAlignedBB(0, 0, 0, 1, 0.5, 1); diff --git a/src/pocketmine/block/Snow.php b/src/pocketmine/block/Snow.php index 20e9919c10..707a72af23 100644 --- a/src/pocketmine/block/Snow.php +++ b/src/pocketmine/block/Snow.php @@ -31,8 +31,8 @@ class Snow extends Solid{ protected $id = self::SNOW_BLOCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getHardness() : float{ diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index 0a709d45b8..faa73bab16 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -34,8 +34,23 @@ class SnowLayer extends Flowable{ protected $id = self::SNOW_LAYER; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $layers = 1; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return $this->layers - 1; + } + + public function readStateFromMeta(int $meta) : void{ + $this->layers = $meta + 1; + } + + public function getStateBitmask() : int{ + return 0b111; } public function getName() : string{ diff --git a/src/pocketmine/block/SoulSand.php b/src/pocketmine/block/SoulSand.php index 44e9900fde..9df0ac22bb 100644 --- a/src/pocketmine/block/SoulSand.php +++ b/src/pocketmine/block/SoulSand.php @@ -29,8 +29,8 @@ class SoulSand extends Solid{ protected $id = self::SOUL_SAND; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/Sponge.php b/src/pocketmine/block/Sponge.php index 1f9289e203..d84c352f61 100644 --- a/src/pocketmine/block/Sponge.php +++ b/src/pocketmine/block/Sponge.php @@ -28,8 +28,23 @@ class Sponge extends Solid{ protected $id = self::SPONGE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var bool */ + protected $wet = false; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return $this->wet ? 1 : 0; + } + + public function readStateFromMeta(int $meta) : void{ + $this->wet = $meta !== 0; + } + + public function getStateBitmask() : int{ + return 0b1; } public function getHardness() : float{ diff --git a/src/pocketmine/block/StainedClay.php b/src/pocketmine/block/StainedClay.php deleted file mode 100644 index 3807dab668..0000000000 --- a/src/pocketmine/block/StainedClay.php +++ /dev/null @@ -1,35 +0,0 @@ -meta) . " Stained Clay"; - } -} diff --git a/src/pocketmine/block/StainedGlass.php b/src/pocketmine/block/StainedGlass.php deleted file mode 100644 index 76aa65d2d3..0000000000 --- a/src/pocketmine/block/StainedGlass.php +++ /dev/null @@ -1,35 +0,0 @@ -meta) . " Stained Glass"; - } -} diff --git a/src/pocketmine/block/StainedGlassPane.php b/src/pocketmine/block/StainedGlassPane.php deleted file mode 100644 index 01a9d35dfa..0000000000 --- a/src/pocketmine/block/StainedGlassPane.php +++ /dev/null @@ -1,35 +0,0 @@ -meta) . " Stained Glass Pane"; - } -} diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index 1026b2fd3b..23bc452404 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -31,57 +31,64 @@ use pocketmine\math\Vector3; use pocketmine\Player; abstract class Stair extends Transparent{ + /** @var int */ + protected $facing = Facing::NORTH; + /** @var bool */ + protected $upsideDown = false; + + protected function writeStateToMeta() : int{ + return (5 - $this->facing) | ($this->upsideDown ? 0x04 : 0); + } + + public function readStateFromMeta(int $meta) : void{ + $this->facing = 5 - ($meta & 0x03); + $this->upsideDown = ($meta & 0x04) !== 0; + } + + public function getStateBitmask() : int{ + return 0b111; + } protected function recalculateCollisionBoxes() : array{ //TODO: handle corners - $minYSlab = ($this->meta & 0x04) === 0 ? 0 : 0.5; - $maxYSlab = $minYSlab + 0.5; + $minYSlab = $this->upsideDown ? 0.5 : 0; $bbs = [ - new AxisAlignedBB(0, $minYSlab, 0, 1, $maxYSlab, 1) + new AxisAlignedBB(0, $minYSlab, 0, 1, $minYSlab + 0.5, 1) ]; - $minY = ($this->meta & 0x04) === 0 ? 0.5 : 0; - $maxY = $minY + 0.5; - - $rotationMeta = $this->meta & 0x03; + $minY = $this->upsideDown ? 0 : 0.5; $minX = $minZ = 0; $maxX = $maxZ = 1; - switch($rotationMeta){ - case 0: + switch($this->facing){ + case Facing::EAST: $minX = 0.5; break; - case 1: + case Facing::WEST: $maxX = 0.5; break; - case 2: + case Facing::SOUTH: $minZ = 0.5; break; - case 3: + case Facing::NORTH: $maxZ = 0.5; break; } - $bbs[] = new AxisAlignedBB($minX, $minY, $minZ, $maxX, $maxY, $maxZ); + $bbs[] = new AxisAlignedBB($minX, $minY, $minZ, $maxX, $minY + 0.5, $maxZ); return $bbs; } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ - $this->meta = 5 - Bearing::toFacing($player->getDirection()); - } - if(($clickVector->y > 0.5 and $face !== Facing::UP) or $face === Facing::DOWN){ - $this->meta |= 0x04; //Upside-down stairs + $this->facing = Bearing::toFacing($player->getDirection()); } + $this->upsideDown = (($clickVector->y > 0.5 and $face !== Facing::UP) or $face === Facing::DOWN); return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - - public function getVariantBitmask() : int{ - return 0; - } } diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index 388ae5e6d8..5dc4b43daa 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -38,8 +38,23 @@ class StandingBanner extends Transparent{ protected $itemId = Item::BANNER; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $rotation = 0; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return $this->rotation; + } + + public function readStateFromMeta(int $meta) : void{ + $this->rotation = $meta; + } + + public function getStateBitmask() : int{ + return 0b1111; } public function getHardness() : float{ @@ -61,11 +76,10 @@ class StandingBanner extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($face !== Facing::DOWN){ if($face === Facing::UP and $player !== null){ - $this->meta = floor((($player->yaw + 180) * 16 / 360) + 0.5) & 0x0f; + $this->rotation = ((int) floor((($player->yaw + 180) * 16 / 360) + 0.5)) & 0x0f; $ret = parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); }else{ - $this->meta = $face; - $ret = $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::WALL_BANNER, $this->meta), true); + $ret = $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::WALL_BANNER, $face), true); } if($ret){ @@ -87,10 +101,6 @@ class StandingBanner extends Transparent{ return BlockToolType::TYPE_AXE; } - public function getVariantBitmask() : int{ - return 0; - } - public function getDropsForCompatibleTool(Item $item) : array{ $tile = $this->level->getTile($this); diff --git a/src/pocketmine/block/Stone.php b/src/pocketmine/block/Stone.php index 47b0962353..0878abec35 100644 --- a/src/pocketmine/block/Stone.php +++ b/src/pocketmine/block/Stone.php @@ -36,12 +36,6 @@ class Stone extends Solid{ public const ANDESITE = 5; public const POLISHED_ANDESITE = 6; - protected $id = self::STONE; - - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - public function getHardness() : float{ return 1.5; } @@ -54,23 +48,10 @@ class Stone extends Solid{ return TieredTool::TIER_WOODEN; } - public function getName() : string{ - static $names = [ - self::NORMAL => "Stone", - self::GRANITE => "Granite", - self::POLISHED_GRANITE => "Polished Granite", - self::DIORITE => "Diorite", - self::POLISHED_DIORITE => "Polished Diorite", - self::ANDESITE => "Andesite", - self::POLISHED_ANDESITE => "Polished Andesite" - ]; - return $names[$this->getVariant()] ?? "Unknown"; - } - public function getDropsForCompatibleTool(Item $item) : array{ - if($this->getDamage() === self::NORMAL){ + if($this->variant === self::NORMAL){ return [ - ItemFactory::get(Item::COBBLESTONE, $this->getDamage()) + ItemFactory::get(Item::COBBLESTONE) ]; } diff --git a/src/pocketmine/block/StoneBrickStairs.php b/src/pocketmine/block/StoneBrickStairs.php index ec397251aa..c0cb53059e 100644 --- a/src/pocketmine/block/StoneBrickStairs.php +++ b/src/pocketmine/block/StoneBrickStairs.php @@ -29,8 +29,8 @@ class StoneBrickStairs extends Stair{ protected $id = self::STONE_BRICK_STAIRS; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getToolType() : int{ diff --git a/src/pocketmine/block/StoneBricks.php b/src/pocketmine/block/StoneBricks.php index 34518a8232..fca2d99374 100644 --- a/src/pocketmine/block/StoneBricks.php +++ b/src/pocketmine/block/StoneBricks.php @@ -31,12 +31,6 @@ class StoneBricks extends Solid{ public const CRACKED = 2; public const CHISELED = 3; - protected $id = self::STONE_BRICKS; - - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - public function getHardness() : float{ return 1.5; } @@ -48,14 +42,4 @@ class StoneBricks extends Solid{ public function getToolHarvestLevel() : int{ return TieredTool::TIER_WOODEN; } - - public function getName() : string{ - static $names = [ - self::NORMAL => "Stone Bricks", - self::MOSSY => "Mossy Stone Bricks", - self::CRACKED => "Cracked Stone Bricks", - self::CHISELED => "Chiseled Stone Bricks" - ]; - return $names[$this->getVariant()] ?? "Unknown"; - } } diff --git a/src/pocketmine/block/StonePressurePlate.php b/src/pocketmine/block/StonePressurePlate.php index f11f7aebcf..027d10ae3c 100644 --- a/src/pocketmine/block/StonePressurePlate.php +++ b/src/pocketmine/block/StonePressurePlate.php @@ -29,8 +29,23 @@ class StonePressurePlate extends Transparent{ protected $id = self::STONE_PRESSURE_PLATE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var bool */ + protected $powered = false; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return $this->powered ? 1 : 0; + } + + public function readStateFromMeta(int $meta) : void{ + $this->powered = $meta !== 0; + } + + public function getStateBitmask() : int{ + return 0b1; } public function getName() : string{ @@ -45,10 +60,6 @@ class StonePressurePlate extends Transparent{ return 0.5; } - public function getVariantBitmask() : int{ - return 0; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } diff --git a/src/pocketmine/block/StoneSlab.php b/src/pocketmine/block/StoneSlab.php index 19d3dbe5cc..56ae176d98 100644 --- a/src/pocketmine/block/StoneSlab.php +++ b/src/pocketmine/block/StoneSlab.php @@ -26,39 +26,11 @@ namespace pocketmine\block; use pocketmine\item\TieredTool; class StoneSlab extends Slab{ - public const STONE = 0; - public const SANDSTONE = 1; - public const WOODEN = 2; - public const COBBLESTONE = 3; - public const BRICK = 4; - public const STONE_BRICK = 5; - public const QUARTZ = 6; - public const NETHER_BRICK = 7; - - protected $id = self::STONE_SLAB; - - public function getDoubleSlabId() : int{ - return self::DOUBLE_STONE_SLAB; - } public function getHardness() : float{ return 2; } - public function getName() : string{ - static $names = [ - self::STONE => "Stone", - self::SANDSTONE => "Sandstone", - self::WOODEN => "Wooden", - self::COBBLESTONE => "Cobblestone", - self::BRICK => "Brick", - self::STONE_BRICK => "Stone Brick", - self::QUARTZ => "Quartz", - self::NETHER_BRICK => "Nether Brick" - ]; - return (($this->meta & 0x08) > 0 ? "Upper " : "") . ($names[$this->getVariant()] ?? "") . " Slab"; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } diff --git a/src/pocketmine/block/StoneSlab2.php b/src/pocketmine/block/StoneSlab2.php deleted file mode 100644 index 1f3a9c44ef..0000000000 --- a/src/pocketmine/block/StoneSlab2.php +++ /dev/null @@ -1,44 +0,0 @@ - "Red Sandstone", - self::TYPE_PURPUR => "Purpur" - ]; - - return (($this->meta & 0x08) > 0 ? "Upper " : "") . ($names[$this->getVariant()] ?? "") . " Slab"; - } -} diff --git a/src/pocketmine/block/Stonecutter.php b/src/pocketmine/block/Stonecutter.php index 1532b23383..daaf02d853 100644 --- a/src/pocketmine/block/Stonecutter.php +++ b/src/pocketmine/block/Stonecutter.php @@ -29,8 +29,8 @@ class Stonecutter extends Solid{ protected $id = self::STONECUTTER; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index f3e25880ca..70381022a6 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -36,8 +36,23 @@ class Sugarcane extends Flowable{ protected $itemId = Item::SUGARCANE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $age = 0; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return $this->age; + } + + public function readStateFromMeta(int $meta) : void{ + $this->age = $meta; + } + + public function getStateBitmask() : int{ + return 0b1111; } public function getName() : string{ @@ -57,7 +72,7 @@ class Sugarcane extends Flowable{ break; } } - $this->meta = 0; + $this->age = 0; $this->getLevel()->setBlock($this, $this, true); } @@ -82,7 +97,7 @@ class Sugarcane extends Flowable{ public function onRandomTick() : void{ if($this->getSide(Facing::DOWN)->getId() !== self::SUGARCANE_BLOCK){ - if($this->meta === 0x0F){ + if($this->age === 15){ for($y = 1; $y < 3; ++$y){ $b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z); if($b->getId() === self::AIR){ @@ -90,10 +105,10 @@ class Sugarcane extends Flowable{ break; } } - $this->meta = 0; + $this->age = 0; $this->getLevel()->setBlock($this, $this, true); }else{ - ++$this->meta; + ++$this->age; $this->getLevel()->setBlock($this, $this, true); } } @@ -113,8 +128,4 @@ class Sugarcane extends Flowable{ return false; } - - public function getVariantBitmask() : int{ - return 0; - } } diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index 7fa63d9d0f..2a13c18aff 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -35,8 +35,8 @@ class TNT extends Solid{ protected $id = self::TNT; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ diff --git a/src/pocketmine/block/TallGrass.php b/src/pocketmine/block/TallGrass.php index d7e0b45f59..f439a22040 100644 --- a/src/pocketmine/block/TallGrass.php +++ b/src/pocketmine/block/TallGrass.php @@ -31,25 +31,10 @@ use pocketmine\Player; class TallGrass extends Flowable{ - protected $id = self::TALL_GRASS; - - public function __construct(int $meta = 1){ - $this->setDamage($meta); - } - public function canBeReplaced() : bool{ return true; } - public function getName() : string{ - static $names = [ - 0 => "Dead Shrub", - 1 => "Tall Grass", - 2 => "Fern" - ]; - return $names[$this->getVariant()] ?? "Unknown"; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === self::GRASS){ diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index a4269ac6af..6524faa55b 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -32,8 +32,27 @@ class Torch extends Flowable{ protected $id = self::TORCH; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $facing = Facing::UP; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return $this->facing === Facing::DOWN ? 0 : 6 - $this->facing; + } + + public function readStateFromMeta(int $meta) : void{ + if($meta === 0){ + $this->facing = Facing::DOWN; + }else{ + $this->facing = 6 - $meta; + } + } + + public function getStateBitmask() : int{ + return 0b111; } public function getLightLevel() : int{ @@ -46,7 +65,7 @@ class Torch extends Flowable{ public function onNearbyBlockChange() : void{ $below = $this->getSide(Facing::DOWN); - $face = $this->meta === 0 ? Facing::DOWN : Facing::opposite(6 - $this->meta); + $face = Facing::opposite($this->facing); if($this->getSide($face)->isTransparent() and !($face === Facing::DOWN and ($below->getId() === self::FENCE or $below->getId() === self::COBBLESTONE_WALL))){ $this->getLevel()->useBreakOn($this); @@ -57,18 +76,13 @@ class Torch extends Flowable{ $below = $this->getSide(Facing::DOWN); if(!$blockClicked->isTransparent() and $face !== Facing::DOWN){ - $this->meta = 6 - $face; - + $this->facing = $face; return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); }elseif(!$below->isTransparent() or $below->getId() === self::FENCE or $below->getId() === self::COBBLESTONE_WALL){ - $this->meta = 5; //attached to block below + $this->facing = Facing::UP; return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; } - - public function getVariantBitmask() : int{ - return 0; - } } diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index 0b5278582c..641f82e960 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -42,8 +42,31 @@ class Trapdoor extends Transparent{ protected $id = self::TRAPDOOR; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $facing = Facing::NORTH; + /** @var bool */ + protected $open = false; + /** @var bool */ + protected $top = false; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return (5 - $this->facing) | ($this->top ? self::MASK_UPPER : 0) | ($this->open ? self::MASK_OPENED : 0); + } + + public function readStateFromMeta(int $meta) : void{ + //TODO: in PC the values are reversed (3 - (5 - facing)) + + $this->facing = 5 - ($meta & 0x03); + $this->top = ($meta & self::MASK_UPPER) !== 0; + $this->open = ($meta & self::MASK_OPENED) !== 0; + } + + public function getStateBitmask() : int{ + return 0b1111; } public function getName() : string{ @@ -55,26 +78,22 @@ class Trapdoor extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - - $damage = $this->getDamage(); - $f = 0.1875; - if(($damage & self::MASK_UPPER) > 0){ + if($this->top){ $bb = new AxisAlignedBB(0, 1 - $f, 0, 1, 1, 1); }else{ $bb = new AxisAlignedBB(0, 0, 0, 1, $f, 1); } - if(($damage & self::MASK_OPENED) > 0){ - $side = $damage & 0x03; - if($side === self::MASK_SIDE_NORTH){ + if($this->open){ + if($this->facing === Facing::NORTH){ $bb->setBounds(0, 0, 1 - $f, 1, 1, 1); - }elseif($side === self::MASK_SIDE_SOUTH){ + }elseif($this->facing === Facing::SOUTH){ $bb->setBounds(0, 0, 0, 1, 1, $f); - }elseif($side === self::MASK_SIDE_WEST){ + }elseif($this->facing === Facing::WEST){ $bb->setBounds(1 - $f, 0, 0, 1, 1, 1); - }elseif($side === self::MASK_SIDE_EAST){ + }elseif($this->facing === Facing::EAST){ $bb->setBounds(0, 0, 0, $f, 1, 1); } } @@ -84,23 +103,18 @@ class Trapdoor extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ - //TODO: in PC the values are reversed (3 - (5 - facing)) - $this->meta = 5 - Bearing::toFacing(Bearing::opposite($player->getDirection())); + $this->facing = Bearing::toFacing(Bearing::opposite($player->getDirection())); } if(($clickVector->y > 0.5 and $face !== Facing::UP) or $face === Facing::DOWN){ - $this->meta |= self::MASK_UPPER; //top half of block + $this->top = true; } return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - public function getVariantBitmask() : int{ - return 0; - } - public function onActivate(Item $item, Player $player = null) : bool{ - $this->meta ^= self::MASK_OPENED; - $this->getLevel()->setBlock($this, $this, true); + $this->open = !$this->open; + $this->level->setBlock($this, $this, true); $this->level->addSound(new DoorSound($this)); return true; } diff --git a/src/pocketmine/block/Tripwire.php b/src/pocketmine/block/Tripwire.php index e916fcb69c..397a5f40d0 100644 --- a/src/pocketmine/block/Tripwire.php +++ b/src/pocketmine/block/Tripwire.php @@ -30,8 +30,29 @@ class Tripwire extends Flowable{ protected $id = self::TRIPWIRE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var bool */ + protected $triggered = false; + /** @var bool */ + protected $connected = false; + /** @var bool */ + protected $disarmed = false; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return ($this->triggered ? 0x01 : 0) | ($this->connected ? 0x04 : 0) | ($this->disarmed ? 0x08 : 0); + } + + public function readStateFromMeta(int $meta) : void{ + $this->triggered = ($meta & 0x01) !== 0; + $this->connected = ($meta & 0x04) !== 0; + $this->disarmed = ($meta & 0x08) !== 0; + } + + public function getStateBitmask() : int{ + return 0b1111; } public function getName() : string{ diff --git a/src/pocketmine/block/TripwireHook.php b/src/pocketmine/block/TripwireHook.php index f505dd92aa..ef56ce8475 100644 --- a/src/pocketmine/block/TripwireHook.php +++ b/src/pocketmine/block/TripwireHook.php @@ -23,20 +23,52 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\item\Item; +use pocketmine\math\Bearing; +use pocketmine\math\Facing; +use pocketmine\math\Vector3; +use pocketmine\Player; + class TripwireHook extends Flowable{ protected $id = self::TRIPWIRE_HOOK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $facing = Facing::NORTH; + /** @var bool */ + protected $connected = false; + /** @var bool */ + protected $powered = false; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return Bearing::fromFacing($this->facing) | ($this->connected ? 0x04 : 0) | ($this->powered ? 0x08 : 0); + } + + public function readStateFromMeta(int $meta) : void{ + $this->facing = Bearing::toFacing($meta & 0x03); + $this->connected = ($meta & 0x04) !== 0; + $this->powered = ($meta & 0x08) !== 0; + } + + public function getStateBitmask() : int{ + return 0b1111; } public function getName() : string{ return "Tripwire Hook"; } - public function getVariantBitmask() : int{ - return 0; + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + if(Facing::axis($face) !== Facing::AXIS_Y){ + //TODO: check face is valid + $this->facing = $face; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + return false; } //TODO diff --git a/src/pocketmine/block/UnknownBlock.php b/src/pocketmine/block/UnknownBlock.php index e12420710c..37ea74af98 100644 --- a/src/pocketmine/block/UnknownBlock.php +++ b/src/pocketmine/block/UnknownBlock.php @@ -27,6 +27,15 @@ use pocketmine\item\Item; class UnknownBlock extends Transparent{ + public function __construct(int $id, int $meta = 0){ + $this->id = $id; + $this->variant = $meta; + } + + public function canBePlaced() : bool{ + return false; + } + public function getHardness() : float{ return 0; } diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index 300c120b21..1f00611571 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -38,8 +38,36 @@ class Vine extends Flowable{ protected $id = self::VINE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var bool[] */ + protected $faces = []; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return + (isset($this->faces[Facing::SOUTH]) ? self::FLAG_SOUTH : 0) | + (isset($this->faces[Facing::WEST]) ? self::FLAG_WEST : 0) | + (isset($this->faces[Facing::NORTH]) ? self::FLAG_NORTH : 0) | + (isset($this->faces[Facing::EAST]) ? self::FLAG_EAST : 0); + } + + public function readStateFromMeta(int $meta) : void{ + $this->setFaceFromMeta($meta, self::FLAG_SOUTH, Facing::SOUTH); + $this->setFaceFromMeta($meta, self::FLAG_WEST, Facing::WEST); + $this->setFaceFromMeta($meta, self::FLAG_NORTH, Facing::NORTH); + $this->setFaceFromMeta($meta, self::FLAG_EAST, Facing::EAST); + } + + public function getStateBitmask() : int{ + return 0b1111; + } + + private function setFaceFromMeta(int $meta, int $flag, int $face) : void{ + if(($meta & $flag) !== 0){ + $this->faces[$face] = true; + } } public function getName() : string{ @@ -79,7 +107,7 @@ class Vine extends Flowable{ $minY = 0; $hasSide = false; - if(($this->meta & self::FLAG_WEST) > 0){ + if(isset($this->faces[Facing::WEST])){ $maxX = max($maxX, 0.0625); $minX = 0; $minZ = 0; @@ -87,7 +115,7 @@ class Vine extends Flowable{ $hasSide = true; } - if(($this->meta & self::FLAG_EAST) > 0){ + if(isset($this->faces[Facing::EAST])){ $minX = min($minX, 0.9375); $maxX = 1; $minZ = 0; @@ -95,7 +123,7 @@ class Vine extends Flowable{ $hasSide = true; } - if(($this->meta & self::FLAG_SOUTH) > 0){ + if(isset($this->faces[Facing::SOUTH])){ $minZ = min($minZ, 0.9375); $maxZ = 1; $minX = 0; @@ -103,7 +131,7 @@ class Vine extends Flowable{ $hasSide = true; } - if(($this->meta & self::FLAG_NORTH) > 0){ + if(isset($this->faces[Facing::NORTH])){ $maxZ = max($maxZ, 0.0625); $minZ = 0; $minX = 0; @@ -123,50 +151,29 @@ class Vine extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if(!$blockClicked->isSolid() or $face === Facing::UP or $face === Facing::DOWN){ + if(!$blockClicked->isSolid() or Facing::axis($face) === Facing::AXIS_Y){ return false; } - static $faces = [ - Facing::NORTH => self::FLAG_SOUTH, - Facing::SOUTH => self::FLAG_NORTH, - Facing::WEST => self::FLAG_EAST, - Facing::EAST => self::FLAG_WEST - ]; - - $this->meta = $faces[$face] ?? 0; - if($blockReplace->getId() === $this->getId()){ - $this->meta |= $blockReplace->meta; - } + $this->faces = $blockReplace instanceof Vine ? $blockReplace->faces : []; + $this->faces[Facing::opposite($face)] = true; return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onNearbyBlockChange() : void{ - static $sides = [ - self::FLAG_SOUTH => Facing::SOUTH, - self::FLAG_WEST => Facing::WEST, - self::FLAG_NORTH => Facing::NORTH, - self::FLAG_EAST => Facing::EAST - ]; - - $meta = $this->meta; - - foreach($sides as $flag => $side){ - if(($meta & $flag) === 0){ - continue; - } - - if(!$this->getSide($side)->isSolid()){ - $meta &= ~$flag; + $changed = false; + foreach($this->faces as $face => $bool){ + if(!$this->getSide($face)->isSolid()){ + unset($this->faces[$face]); + $changed = true; } } - if($meta !== $this->meta){ - if($meta === 0){ + if($changed){ + if(empty($this->faces)){ $this->level->useBreakOn($this); }else{ - $this->meta = $meta; $this->level->setBlock($this, $this); } } @@ -180,10 +187,6 @@ class Vine extends Flowable{ //TODO: vine growth } - public function getVariantBitmask() : int{ - return 0; - } - public function getDrops(Item $item) : array{ if($item->getBlockToolType() & BlockToolType::TYPE_SHEARS){ return $this->getDropsForCompatibleTool($item); diff --git a/src/pocketmine/block/WallBanner.php b/src/pocketmine/block/WallBanner.php index a0a16ea446..a161ce8475 100644 --- a/src/pocketmine/block/WallBanner.php +++ b/src/pocketmine/block/WallBanner.php @@ -23,16 +23,33 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\math\Facing; + class WallBanner extends StandingBanner{ protected $id = self::WALL_BANNER; + /** @var int */ + protected $facing = Facing::NORTH; + + protected function writeStateToMeta() : int{ + return $this->facing; + } + + public function readStateFromMeta(int $meta) : void{ + $this->facing = $meta; + } + + public function getStateBitmask() : int{ + return 0b111; + } + public function getName() : string{ return "Wall Banner"; } public function onNearbyBlockChange() : void{ - if($this->getSide($this->meta ^ 0x01)->getId() === self::AIR){ + if($this->getSide(Facing::opposite($this->facing))->getId() === self::AIR){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/WallSign.php b/src/pocketmine/block/WallSign.php index 58b0d8a821..e416e27eb5 100644 --- a/src/pocketmine/block/WallSign.php +++ b/src/pocketmine/block/WallSign.php @@ -23,16 +23,33 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\math\Facing; + class WallSign extends SignPost{ protected $id = self::WALL_SIGN; + /** @var int */ + protected $facing = Facing::NORTH; + + protected function writeStateToMeta() : int{ + return $this->facing; + } + + public function readStateFromMeta(int $meta) : void{ + $this->facing = $meta; + } + + public function getStateBitmask() : int{ + return 0b111; + } + public function getName() : string{ return "Wall Sign"; } public function onNearbyBlockChange() : void{ - if($this->getSide($this->meta ^ 0x01)->getId() === self::AIR){ + if($this->getSide(Facing::opposite($this->facing))->getId() === self::AIR){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/Water.php b/src/pocketmine/block/Water.php index 777696ff3b..2256f202c8 100644 --- a/src/pocketmine/block/Water.php +++ b/src/pocketmine/block/Water.php @@ -30,8 +30,8 @@ class Water extends Liquid{ protected $id = self::FLOWING_WATER; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ @@ -43,11 +43,11 @@ class Water extends Liquid{ } public function getStillForm() : Block{ - return BlockFactory::get(Block::STILL_WATER, $this->meta); + return BlockFactory::get(Block::STILL_WATER, $this->getDamage()); } public function getFlowingForm() : Block{ - return BlockFactory::get(Block::FLOWING_WATER, $this->meta); + return BlockFactory::get(Block::FLOWING_WATER, $this->getDamage()); } public function getBucketFillSound() : int{ diff --git a/src/pocketmine/block/WaterLily.php b/src/pocketmine/block/WaterLily.php index bd372c4f35..faf1316fa0 100644 --- a/src/pocketmine/block/WaterLily.php +++ b/src/pocketmine/block/WaterLily.php @@ -33,8 +33,8 @@ class WaterLily extends Flowable{ protected $id = self::WATER_LILY; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + public function __construct(){ + } public function getName() : string{ @@ -66,8 +66,4 @@ class WaterLily extends Flowable{ $this->getLevel()->useBreakOn($this); } } - - public function getVariantBitmask() : int{ - return 0; - } } diff --git a/src/pocketmine/block/WeightedPressurePlateLight.php b/src/pocketmine/block/WeightedPressurePlateLight.php index 5633173c86..baea3a0bfa 100644 --- a/src/pocketmine/block/WeightedPressurePlateLight.php +++ b/src/pocketmine/block/WeightedPressurePlateLight.php @@ -29,8 +29,23 @@ class WeightedPressurePlateLight extends Transparent{ protected $id = self::LIGHT_WEIGHTED_PRESSURE_PLATE; - public function __construct(int $meta = 0){ - $this->setDamage($meta); + /** @var int */ + protected $power = 0; + + public function __construct(){ + + } + + protected function writeStateToMeta() : int{ + return $this->power; + } + + public function readStateFromMeta(int $meta) : void{ + $this->power = $meta; + } + + public function getStateBitmask() : int{ + return 0b1111; } public function getName() : string{ @@ -45,10 +60,6 @@ class WeightedPressurePlateLight extends Transparent{ return 0.5; } - public function getVariantBitmask() : int{ - return 0; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } diff --git a/src/pocketmine/block/Wheat.php b/src/pocketmine/block/Wheat.php index c0d455a083..ac3f0775b5 100644 --- a/src/pocketmine/block/Wheat.php +++ b/src/pocketmine/block/Wheat.php @@ -30,16 +30,12 @@ class Wheat extends Crops{ protected $id = self::WHEAT_BLOCK; - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - public function getName() : string{ return "Wheat Block"; } public function getDropsForCompatibleTool(Item $item) : array{ - if($this->meta >= 0x07){ + if($this->age >= 7){ return [ ItemFactory::get(Item::WHEAT), ItemFactory::get(Item::WHEAT_SEEDS, 0, mt_rand(0, 3)) diff --git a/src/pocketmine/block/Wood.php b/src/pocketmine/block/Wood.php index 375cd15df6..9f66ef3183 100644 --- a/src/pocketmine/block/Wood.php +++ b/src/pocketmine/block/Wood.php @@ -23,46 +23,29 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\PillarRotationHelper; +use pocketmine\block\utils\PillarRotationTrait; use pocketmine\item\Item; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; class Wood extends Solid{ + use PillarRotationTrait; + public const OAK = 0; public const SPRUCE = 1; public const BIRCH = 2; public const JUNGLE = 3; - protected $id = self::WOOD; - - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - public function getHardness() : float{ return 2; } - public function getName() : string{ - static $names = [ - self::OAK => "Oak Wood", - self::SPRUCE => "Spruce Wood", - self::BIRCH => "Birch Wood", - self::JUNGLE => "Jungle Wood" - ]; - return $names[$this->getVariant()] ?? "Unknown"; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $this->meta = PillarRotationHelper::getMetaFromFace($this->meta, $face); + $this->axis = Facing::axis($face); return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - public function getVariantBitmask() : int{ - return 0x03; - } - public function getToolType() : int{ return BlockToolType::TYPE_AXE; } diff --git a/src/pocketmine/block/Wood2.php b/src/pocketmine/block/Wood2.php deleted file mode 100644 index f452aaef8b..0000000000 --- a/src/pocketmine/block/Wood2.php +++ /dev/null @@ -1,41 +0,0 @@ - "Acacia Wood", - 1 => "Dark Oak Wood" - ]; - return $names[$this->getVariant()] ?? "Unknown"; - } -} diff --git a/src/pocketmine/block/WoodenFence.php b/src/pocketmine/block/WoodenFence.php index f0df471f64..3190e9d877 100644 --- a/src/pocketmine/block/WoodenFence.php +++ b/src/pocketmine/block/WoodenFence.php @@ -24,14 +24,6 @@ declare(strict_types=1); namespace pocketmine\block; class WoodenFence extends Fence{ - public const FENCE_OAK = 0; - public const FENCE_SPRUCE = 1; - public const FENCE_BIRCH = 2; - public const FENCE_JUNGLE = 3; - public const FENCE_ACACIA = 4; - public const FENCE_DARKOAK = 5; - - protected $id = self::FENCE; public function getHardness() : float{ return 2; @@ -41,18 +33,6 @@ class WoodenFence extends Fence{ return BlockToolType::TYPE_AXE; } - public function getName() : string{ - static $names = [ - self::FENCE_OAK => "Oak Fence", - self::FENCE_SPRUCE => "Spruce Fence", - self::FENCE_BIRCH => "Birch Fence", - self::FENCE_JUNGLE => "Jungle Fence", - self::FENCE_ACACIA => "Acacia Fence", - self::FENCE_DARKOAK => "Dark Oak Fence" - ]; - return $names[$this->getVariant()] ?? "Unknown"; - } - public function getFuelTime() : int{ return 300; } diff --git a/src/pocketmine/block/WoodenSlab.php b/src/pocketmine/block/WoodenSlab.php index f1b8f4611e..36528d695d 100644 --- a/src/pocketmine/block/WoodenSlab.php +++ b/src/pocketmine/block/WoodenSlab.php @@ -23,30 +23,20 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\WoodType; + class WoodenSlab extends Slab{ protected $id = self::WOODEN_SLAB; - public function getDoubleSlabId() : int{ - return self::DOUBLE_WOODEN_SLAB; + public function __construct(int $variant = 0){ + parent::__construct(self::WOODEN_SLAB, self::DOUBLE_WOODEN_SLAB, $variant, WoodType::NAMES[$variant]); } public function getHardness() : float{ return 2; } - public function getName() : string{ - static $names = [ - 0 => "Oak", - 1 => "Spruce", - 2 => "Birch", - 3 => "Jungle", - 4 => "Acacia", - 5 => "Dark Oak" - ]; - return (($this->meta & 0x08) === 0x08 ? "Upper " : "") . ($names[$this->getVariant()] ?? "") . " Wooden Slab"; - } - public function getToolType() : int{ return BlockToolType::TYPE_AXE; } diff --git a/src/pocketmine/block/Wool.php b/src/pocketmine/block/Wool.php index 7963a13f93..0a7b107f53 100644 --- a/src/pocketmine/block/Wool.php +++ b/src/pocketmine/block/Wool.php @@ -23,17 +23,10 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\ColorBlockMetaHelper; use pocketmine\item\Item; class Wool extends Solid{ - protected $id = self::WOOL; - - public function __construct(int $meta = 0){ - $this->setDamage($meta); - } - public function getHardness() : float{ return 0.8; } @@ -42,10 +35,6 @@ class Wool extends Solid{ return BlockToolType::TYPE_SHEARS; } - public function getName() : string{ - return ColorBlockMetaHelper::getColorFromMeta($this->meta) . " Wool"; - } - public function getBreakTime(Item $item) : float{ $time = parent::getBreakTime($item); if($item->getBlockToolType() === BlockToolType::TYPE_SHEARS){ diff --git a/src/pocketmine/block/utils/ColorBlockMetaHelper.php b/src/pocketmine/block/utils/ColorBlockMetaHelper.php deleted file mode 100644 index 6fe8bf15e8..0000000000 --- a/src/pocketmine/block/utils/ColorBlockMetaHelper.php +++ /dev/null @@ -1,50 +0,0 @@ - "White", - 1 => "Orange", - 2 => "Magenta", - 3 => "Light Blue", - 4 => "Yellow", - 5 => "Lime", - 6 => "Pink", - 7 => "Gray", - 8 => "Light Gray", - 9 => "Cyan", - 10 => "Purple", - 11 => "Blue", - 12 => "Brown", - 13 => "Green", - 14 => "Red", - 15 => "Black" - ]; - - return $names[$meta] ?? "Unknown"; - } -} diff --git a/src/pocketmine/block/utils/PillarRotationHelper.php b/src/pocketmine/block/utils/PillarRotationHelper.php deleted file mode 100644 index 8e64afd92f..0000000000 --- a/src/pocketmine/block/utils/PillarRotationHelper.php +++ /dev/null @@ -1,39 +0,0 @@ - 0, - Facing::AXIS_Z => 0x08, - Facing::AXIS_X => 0x04 - ]; - - return ($meta & 0x03) | $bits[Facing::axis($face)]; - } -} diff --git a/src/pocketmine/item/Bucket.php b/src/pocketmine/item/Bucket.php index ce9365d82b..133ccbb370 100644 --- a/src/pocketmine/item/Bucket.php +++ b/src/pocketmine/item/Bucket.php @@ -54,7 +54,7 @@ class Bucket extends Item implements Consumable{ $resultBlock = BlockFactory::get($this->meta); if($resultBlock instanceof Air){ - if($blockClicked instanceof Liquid and $blockClicked->getDamage() === 0){ + if($blockClicked instanceof Liquid and $blockClicked->isSource()){ $stack = clone $this; $stack->pop(); diff --git a/src/pocketmine/item/Dye.php b/src/pocketmine/item/Dye.php index 9443e900d4..87aaa184cc 100644 --- a/src/pocketmine/item/Dye.php +++ b/src/pocketmine/item/Dye.php @@ -23,10 +23,20 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\block\Block; +use pocketmine\block\BlockFactory; + class Dye extends Item{ public function __construct(int $meta = 0){ parent::__construct(self::DYE, $meta, "Dye"); } + public function getBlock() : Block{ + if($this->meta === 3){ //cocoa beans + return BlockFactory::get(Block::COCOA); + } + return parent::getBlock(); + } + //TODO: names } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 14e7add6c1..79068d5f05 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -216,9 +216,6 @@ class Level implements ChunkManager, Metadatable{ /** @var Vector3 */ private $temporalVector; - /** @var \SplFixedArray */ - private $blockStates; - /** @var int */ private $sleepTicks = 0; @@ -230,7 +227,7 @@ class Level implements ChunkManager, Metadatable{ private $chunksPerTick; /** @var bool */ private $clearChunksOnTick; - /** @var \SplFixedArray */ + /** @var \SplFixedArray */ private $randomTickBlocks = null; /** @var LevelTimings */ @@ -327,7 +324,6 @@ class Level implements ChunkManager, Metadatable{ * @param LevelProvider $provider */ public function __construct(Server $server, string $name, LevelProvider $provider){ - $this->blockStates = BlockFactory::getBlockStatesArray(); $this->levelId = static::$levelIdCounter++; $this->blockMetadata = new BlockMetadataStore($this); $this->server = $server; @@ -357,11 +353,17 @@ class Level implements ChunkManager, Metadatable{ $dontTickBlocks = array_fill_keys($this->server->getProperty("chunk-ticking.disable-block-ticking", []), true); - $this->randomTickBlocks = new \SplFixedArray(256); - foreach($this->randomTickBlocks as $id => $null){ - $block = BlockFactory::get($id); //Make sure it's a copy + $this->randomTickBlocks = new \SplFixedArray(4096); + foreach($this->randomTickBlocks as $i => $null){ + $id = $i >> 4; + $meta = $i & 0xf; + try{ + $block = BlockFactory::get($id, $meta); //Make sure it's a copy + }catch(\InvalidArgumentException $e){ + continue; + } if(!isset($dontTickBlocks[$id]) and $block->ticksRandomly()){ - $this->randomTickBlocks[$id] = $block; + $this->randomTickBlocks[($id << 4) | $meta] = true; } } @@ -939,12 +941,16 @@ class Level implements ChunkManager, Metadatable{ return $this->randomTickBlocks; } - public function addRandomTickedBlock(int $id){ - $this->randomTickBlocks[$id] = BlockFactory::get($id); + public function addRandomTickedBlock(int $id, int $variant = 0){ + $block = BlockFactory::get($id, $variant); + if($block instanceof UnknownBlock){ + throw new \InvalidArgumentException("ID $id variant $variant is unknown, cannot do random-tick"); + } + $this->randomTickBlocks[($id << 4) | $variant] = true; } - public function removeRandomTickedBlock(int $id){ - $this->randomTickBlocks[$id] = null; + public function removeRandomTickedBlock(int $id, int $variant = 0){ + $this->randomTickBlocks[($id << 4) | $variant] = null; } private function tickChunks(){ @@ -998,10 +1004,11 @@ class Level implements ChunkManager, Metadatable{ $z = ($k >> 8) & 0x0f; $blockId = $subChunk->getBlockId($x, $y, $z); - if($this->randomTickBlocks[$blockId] !== null){ + $meta = $subChunk->getBlockData($x, $y, $z); + + if($this->randomTickBlocks[($blockId << 4) | ($meta & ~BlockFactory::$stateMasks[$blockId])]){ /** @var Block $block */ - $block = clone $this->randomTickBlocks[$blockId]; - $block->setDamage($subChunk->getBlockData($x, $y, $z)); + $block = BlockFactory::get($blockId, $meta); $block->x = $chunkX * 16 + $x; $block->y = ($Y << 4) + $y; @@ -1335,7 +1342,8 @@ class Level implements ChunkManager, Metadatable{ * @return Block */ public function getBlockAt(int $x, int $y, int $z, bool $cached = true, bool $addToCache = true) : Block{ - $fullState = 0; + $id = 0; + $meta = 0; $blockHash = null; $chunkHash = Level::chunkHash($x >> 4, $z >> 4); @@ -1349,17 +1357,14 @@ class Level implements ChunkManager, Metadatable{ $chunk = $this->chunks[$chunkHash] ?? null; if($chunk !== null){ $fullState = $chunk->getFullBlock($x & 0x0f, $y, $z & 0x0f); + $id = $fullState >> 4; + $meta = $fullState & 0xf; }else{ $addToCache = false; } } - $block = $this->blockStates[$fullState & 0xfff]; - if($block !== null){ - $block = clone $block; - }else{ - $block = new UnknownBlock($fullState >> 4, $fullState & 0xf); - } + $block = BlockFactory::get($id, $meta); $block->x = $x; $block->y = $y; diff --git a/src/pocketmine/level/biome/ForestBiome.php b/src/pocketmine/level/biome/ForestBiome.php index 30ec1475f7..0c4699c405 100644 --- a/src/pocketmine/level/biome/ForestBiome.php +++ b/src/pocketmine/level/biome/ForestBiome.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\level\biome; -use pocketmine\block\Sapling; +use pocketmine\block\utils\WoodType; use pocketmine\level\generator\populator\TallGrass; use pocketmine\level\generator\populator\Tree; @@ -39,7 +39,7 @@ class ForestBiome extends GrassyBiome{ $this->type = $type; - $trees = new Tree($type === self::TYPE_BIRCH ? Sapling::BIRCH : Sapling::OAK); + $trees = new Tree($type === self::TYPE_BIRCH ? WoodType::BIRCH : WoodType::OAK); $trees->setBaseAmount(5); $this->addPopulator($trees); diff --git a/src/pocketmine/level/biome/TaigaBiome.php b/src/pocketmine/level/biome/TaigaBiome.php index 90ac60b610..2404c59368 100644 --- a/src/pocketmine/level/biome/TaigaBiome.php +++ b/src/pocketmine/level/biome/TaigaBiome.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\level\biome; -use pocketmine\block\Sapling; +use pocketmine\block\utils\WoodType; use pocketmine\level\generator\populator\TallGrass; use pocketmine\level\generator\populator\Tree; @@ -32,7 +32,7 @@ class TaigaBiome extends SnowyBiome{ public function __construct(){ parent::__construct(); - $trees = new Tree(Sapling::SPRUCE); + $trees = new Tree(WoodType::SPRUCE); $trees->setBaseAmount(10); $this->addPopulator($trees); diff --git a/src/pocketmine/level/generator/object/Tree.php b/src/pocketmine/level/generator/object/Tree.php index f25bcf4bc4..5b9110f9e1 100644 --- a/src/pocketmine/level/generator/object/Tree.php +++ b/src/pocketmine/level/generator/object/Tree.php @@ -25,7 +25,7 @@ namespace pocketmine\level\generator\object; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\Sapling; +use pocketmine\block\utils\WoodType; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; @@ -45,23 +45,23 @@ abstract class Tree{ public $leafBlock = Block::LEAVES; public $treeHeight = 7; - public static function growTree(ChunkManager $level, int $x, int $y, int $z, Random $random, int $type = Sapling::OAK) : void{ + public static function growTree(ChunkManager $level, int $x, int $y, int $z, Random $random, int $type = WoodType::OAK) : void{ switch($type){ - case Sapling::SPRUCE: + case WoodType::SPRUCE: $tree = new SpruceTree(); break; - case Sapling::BIRCH: + case WoodType::BIRCH: if($random->nextBoundedInt(39) === 0){ $tree = new BirchTree(true); }else{ $tree = new BirchTree(); } break; - case Sapling::JUNGLE: + case WoodType::JUNGLE: $tree = new JungleTree(); break; - case Sapling::ACACIA: - case Sapling::DARK_OAK: + case WoodType::ACACIA: + case WoodType::DARK_OAK: return; //TODO default: $tree = new OakTree(); diff --git a/src/pocketmine/level/generator/populator/Tree.php b/src/pocketmine/level/generator/populator/Tree.php index 6250aa41ad..d63b311ea7 100644 --- a/src/pocketmine/level/generator/populator/Tree.php +++ b/src/pocketmine/level/generator/populator/Tree.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\level\generator\populator; use pocketmine\block\Block; -use pocketmine\block\Sapling; +use pocketmine\block\utils\WoodType; use pocketmine\level\ChunkManager; use pocketmine\level\generator\object\Tree as ObjectTree; use pocketmine\utils\Random; @@ -37,7 +37,7 @@ class Tree extends Populator{ private $type; - public function __construct(int $type = Sapling::OAK){ + public function __construct(int $type = WoodType::OAK){ $this->type = $type; } diff --git a/src/pocketmine/tile/Furnace.php b/src/pocketmine/tile/Furnace.php index 848d5fba2b..2e4dbe79e7 100644 --- a/src/pocketmine/tile/Furnace.php +++ b/src/pocketmine/tile/Furnace.php @@ -23,8 +23,7 @@ declare(strict_types=1); namespace pocketmine\tile; -use pocketmine\block\Block; -use pocketmine\block\BlockFactory; +use pocketmine\block\Furnace as BlockFurnace; use pocketmine\event\inventory\FurnaceBurnEvent; use pocketmine\event\inventory\FurnaceSmeltEvent; use pocketmine\inventory\FurnaceInventory; @@ -144,8 +143,10 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ $this->maxTime = $this->burnTime = $ev->getBurnTime(); - if($this->getBlock()->getId() === Block::FURNACE){ - $this->getLevel()->setBlock($this, BlockFactory::get(Block::BURNING_FURNACE, $this->getBlock()->getDamage()), true); + $block = $this->getBlock(); + if($block instanceof BlockFurnace and !$block->isLit()){ + $block->setLit(true); + $this->getLevel()->setBlock($block, $block, true); } if($this->burnTime > 0 and $ev->isBurning()){ @@ -206,8 +207,10 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ } $ret = true; }else{ - if($this->getBlock()->getId() === Block::BURNING_FURNACE){ - $this->getLevel()->setBlock($this, BlockFactory::get(Block::FURNACE, $this->getBlock()->getDamage()), true); + $block = $this->getBlock(); + if($block instanceof BlockFurnace and $block->isLit()){ + $block->setLit(false); + $this->getLevel()->setBlock($block, $block, true); } $this->burnTime = $this->cookTime = $this->maxTime = 0; } diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index 222a4cc6c7..2fae84449b 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -99,11 +99,12 @@ class BlockTest extends TestCase{ */ public function blockGetProvider() : array{ return [ - [Block::STONE, Stone::ANDESITE], + [Block::STONE, 5], [Block::STONE, 15], - [Block::GOLD_BLOCK, 5], - [Block::WOODEN_PLANKS, Planks::DARK_OAK], - [Block::SAND, 0] + [Block::GOLD_BLOCK, 0], + [Block::WOODEN_PLANKS, 5], + [Block::SAND, 0], + [Block::GOLD_BLOCK, 0] ]; } @@ -119,6 +120,13 @@ class BlockTest extends TestCase{ self::assertEquals($meta, $block->getDamage()); } + public function testBlockIds() : void{ + for($i = 0; $i < 256; ++$i){ + $b = BlockFactory::get($i); + self::assertEquals($i, $b->getId()); + } + } + /** * Test that all blocks have correctly set names */ From 4a7f8fd9d93d1c18bc1795df41d022eb0076af44 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 21 Sep 2018 19:28:31 +0100 Subject: [PATCH 0163/3224] Implemented behaviour for cocoa pods --- src/pocketmine/block/CocoaBlock.php | 80 ++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index 554533ef87..f306cccc8b 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -69,9 +69,85 @@ class CocoaBlock extends Transparent{ return BlockToolType::TYPE_AXE; } - //TODO - public function isAffectedBySilkTouch() : bool{ return false; } + + protected function recalculateBoundingBox() : ?AxisAlignedBB{ + static $logDistance = 1 / 16; + + $widthInset = (6 - $this->age) / 16; + $faceDistance = (5 + $this->age * 2) / 16; + + $minY = (7 - $this->age * 2) / 16; + + if(Facing::isPositive($this->facing)){ + $minFacing = $logDistance; + $maxFacing = $faceDistance; + }else{ + $minFacing = 1 - $faceDistance; + $maxFacing = 1 - $logDistance; + } + + if(Facing::axis($this->facing) === Facing::AXIS_Z){ + $minX = $widthInset; + $maxX = 1 - $widthInset; + + $minZ = $minFacing; + $maxZ = $maxFacing; + }else{ + $minX = $minFacing; + $maxX = $maxFacing; + + $minZ = $widthInset; + $maxZ = 1 - $widthInset; + } + + return new AxisAlignedBB($minX, $minY, $minZ, $maxX, 0.75, $maxZ); + } + + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + if(Facing::axis($face) !== Facing::AXIS_Y and $blockClicked->getId() === Block::LOG and $blockClicked->getVariant() === Wood::JUNGLE){ + $this->facing = $face; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + + return false; + } + + public function onActivate(Item $item, Player $player = null) : bool{ + if($this->age < 2 and $item->getId() === Item::DYE and $item->getDamage() === 15){ //bone meal + $this->age++; + $this->level->setBlock($this, $this); + } + return false; + } + + public function onNearbyBlockChange() : void{ + $side = $this->getSide(Facing::opposite($this->facing)); + if($side->getId() !== Block::LOG or $side->getVariant() !== Wood::JUNGLE){ + $this->level->useBreakOn($this); + } + } + + public function ticksRandomly() : bool{ + return true; + } + + public function onRandomTick() : void{ + if($this->age < 2 and mt_rand(1, 5) === 1){ + $this->age++; + $this->level->setBlock($this, $this); + } + } + + public function getDropsForCompatibleTool(Item $item) : array{ + return [ + ItemFactory::get(Item::DYE, 3, $this->age === 2 ? mt_rand(2, 3) : 1) + ]; + } + + public function getPickedItem() : Item{ + return ItemFactory::get(Item::DYE, 3); //cocoa beans + } } From a093ba3ed9987701af3f4ed660ba4fb55dea3591 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 21 Sep 2018 19:30:04 +0100 Subject: [PATCH 0164/3224] thanks git --- src/pocketmine/block/utils/Color.php | 81 +++++++++++++++++++ .../block/utils/PillarRotationTrait.php | 76 +++++++++++++++++ src/pocketmine/block/utils/WoodType.php | 51 ++++++++++++ 3 files changed, 208 insertions(+) create mode 100644 src/pocketmine/block/utils/Color.php create mode 100644 src/pocketmine/block/utils/PillarRotationTrait.php create mode 100644 src/pocketmine/block/utils/WoodType.php diff --git a/src/pocketmine/block/utils/Color.php b/src/pocketmine/block/utils/Color.php new file mode 100644 index 0000000000..2b89fad1f3 --- /dev/null +++ b/src/pocketmine/block/utils/Color.php @@ -0,0 +1,81 @@ + "White", + self::ORANGE => "Orange", + self::MAGENTA => "Magenta", + self::LIGHT_BLUE => "Light Blue", + self::YELLOW => "Yellow", + self::LIME => "Lime", + self::PINK => "Pink", + self::GRAY => "Gray", + self::LIGHT_GRAY => "Light Gray", + self::CYAN => "Cyan", + self::PURPLE => "Purple", + self::BLUE => "Blue", + self::BROWN => "Brown", + self::GREEN => "Green", + self::RED => "Red", + self::BLACK => "Black" + ]; +} diff --git a/src/pocketmine/block/utils/PillarRotationTrait.php b/src/pocketmine/block/utils/PillarRotationTrait.php new file mode 100644 index 0000000000..a7531e77f5 --- /dev/null +++ b/src/pocketmine/block/utils/PillarRotationTrait.php @@ -0,0 +1,76 @@ +writeAxisToMeta(); + } + + /** + * @see Block::readStateFromMeta() + * @param int $meta + */ + public function readStateFromMeta(int $meta) : void{ + $this->readAxisFromMeta($meta); + } + + /** + * @see Block::getStateBitmask() + * @return int + */ + public function getStateBitmask() : int{ + return 0b1100; + } + + protected function readAxisFromMeta(int $meta) : void{ + static $map = [ + 0 => Facing::AXIS_Y, + 1 => Facing::AXIS_X, + 2 => Facing::AXIS_Z, + 3 => Facing::AXIS_Y //TODO: how to deal with all-bark logs? + ]; + $this->axis = $map[$meta >> 2]; + } + + protected function writeAxisToMeta() : int{ + static $bits = [ + Facing::AXIS_Y => 0, + Facing::AXIS_Z => 2, + Facing::AXIS_X => 1 + ]; + return $bits[$this->axis] << 2; + } +} diff --git a/src/pocketmine/block/utils/WoodType.php b/src/pocketmine/block/utils/WoodType.php new file mode 100644 index 0000000000..8963b5e5a7 --- /dev/null +++ b/src/pocketmine/block/utils/WoodType.php @@ -0,0 +1,51 @@ + "Oak", + self::SPRUCE => "Spruce", + self::BIRCH => "Birch", + self::JUNGLE => "Jungle", + self::ACACIA => "Acacia", + self::DARK_OAK => "Dark Oak" + ]; +} From 02d5f4da85fc151404ddc1958a6deca87534498c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 21 Sep 2018 19:32:59 +0100 Subject: [PATCH 0165/3224] fix merge error --- src/pocketmine/block/DoubleSlab.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/DoubleSlab.php b/src/pocketmine/block/DoubleSlab.php index acdbb887ca..41ad6a0d70 100644 --- a/src/pocketmine/block/DoubleSlab.php +++ b/src/pocketmine/block/DoubleSlab.php @@ -74,6 +74,6 @@ class DoubleSlab extends Solid{ } public function getPickedItem() : Item{ - return ItemFactory::get($this->getSlabId(), $this->getVariant()); + return ItemFactory::get($this->singleId, $this->getVariant()); } } From 3edf3a3a8029de9ff05850a1b8f43cad0c363725 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 21 Sep 2018 19:34:18 +0100 Subject: [PATCH 0166/3224] Entity: remove unused import --- src/pocketmine/entity/Entity.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index bfeb108ab6..83f76d2064 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -27,7 +27,6 @@ declare(strict_types=1); namespace pocketmine\entity; use pocketmine\block\Block; -use pocketmine\block\BlockFactory; use pocketmine\block\Water; use pocketmine\entity\object\ExperienceOrb; use pocketmine\entity\object\FallingBlock; From 9d2e9e1663997b78bf0cf70f9eb311b6d8f2bfb1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 21 Sep 2018 19:45:52 +0100 Subject: [PATCH 0167/3224] Fixed torch facing bug with wrong metadata torches cannot face down --- src/pocketmine/block/Torch.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index 6524faa55b..8e889bfe58 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -40,12 +40,12 @@ class Torch extends Flowable{ } protected function writeStateToMeta() : int{ - return $this->facing === Facing::DOWN ? 0 : 6 - $this->facing; + return 6 - $this->facing; } public function readStateFromMeta(int $meta) : void{ if($meta === 0){ - $this->facing = Facing::DOWN; + $this->facing = Facing::UP; }else{ $this->facing = 6 - $meta; } From ed1c511c3c13fea478130bdf3906b5ed6a7e9e2e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 23 Sep 2018 14:14:58 +0100 Subject: [PATCH 0168/3224] Hacks for dealing with negative item IDs... --- src/pocketmine/block/Block.php | 8 +++++++- src/pocketmine/block/BlockFactory.php | 12 ++++++------ src/pocketmine/item/ItemBlock.php | 7 +++++++ 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index bdb8871d73..1cfcf5ce17 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -111,7 +111,13 @@ class Block extends Position implements BlockIds, Metadatable{ * @return int */ public function getItemId() : int{ - return $this->itemId ?? $this->getId(); + if($this->itemId !== null){ + return $this->itemId; + } + if($this->id > 255){ + return 255 - $this->id; + } + return $this->id; } /** diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index f8a091ce7f..7fc4af2aef 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -61,14 +61,14 @@ class BlockFactory{ * this if you need to reset the block factory back to its original defaults for whatever reason. */ public static function init() : void{ - self::$fullList = new \SplFixedArray(4096); - self::$getInterceptors = new \SplFixedArray(4096); + self::$fullList = new \SplFixedArray(8192); + self::$getInterceptors = new \SplFixedArray(8192); - self::$lightFilter = \SplFixedArray::fromArray(array_fill(0, 256, 1)); - self::$diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 256, false)); - self::$blastResistance = \SplFixedArray::fromArray(array_fill(0, 256, 0)); + self::$lightFilter = \SplFixedArray::fromArray(array_fill(0, 512, 1)); + self::$diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 512, false)); + self::$blastResistance = \SplFixedArray::fromArray(array_fill(0, 512, 0)); - self::$stateMasks = \SplFixedArray::fromArray(array_fill(0, 256, 0)); + self::$stateMasks = \SplFixedArray::fromArray(array_fill(0, 512, 0)); self::registerBlock(new Air()); diff --git a/src/pocketmine/item/ItemBlock.php b/src/pocketmine/item/ItemBlock.php index 4fa540b14d..da455e517d 100644 --- a/src/pocketmine/item/ItemBlock.php +++ b/src/pocketmine/item/ItemBlock.php @@ -39,8 +39,15 @@ class ItemBlock extends Item{ * @param int|null $itemId */ public function __construct(int $blockId, int $meta = 0, int $itemId = null){ + if($blockId < 0){ //extended blocks + if($itemId === null){ + $itemId = $blockId; + } + $blockId = 255 - $blockId; + } $this->blockId = $blockId; $this->setDamage($meta); + parent::__construct($itemId ?? $blockId, $meta, $this->getBlock()->getName()); } From 1427da0aeba210843f6214e42e4ea00e0ebab849 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 23 Sep 2018 14:21:37 +0100 Subject: [PATCH 0169/3224] Clean up item handling of blocks --- src/pocketmine/block/Bed.php | 8 ++------ src/pocketmine/block/Block.php | 15 +++++++-------- src/pocketmine/block/Skull.php | 10 +--------- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 0e98356f1f..658433ab11 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -184,17 +184,13 @@ class Bed extends Transparent{ public function getDropsForCompatibleTool(Item $item) : array{ if($this->isHeadPart()){ - return [$this->getItem()]; + return parent::getDropsForCompatibleTool($item); } return []; } - public function getPickedItem() : Item{ - return $this->getItem(); - } - - private function getItem() : Item{ + public function getItem() : Item{ $tile = $this->getLevel()->getTile($this); if($tile instanceof TileBed){ return ItemFactory::get($this->getItemId(), $tile->getColor()); diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 1cfcf5ce17..95973a8c2b 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -120,6 +120,10 @@ class Block extends Position implements BlockIds, Metadatable{ return $this->id; } + public function getItem() : Item{ + return ItemFactory::get($this->getItemId(), $this->getVariant()); + } + /** * @internal * @return int @@ -127,7 +131,6 @@ class Block extends Position implements BlockIds, Metadatable{ public function getRuntimeId() : int{ return BlockFactory::toStaticRuntimeId($this->getId(), $this->getDamage()); } - /** * @return int */ @@ -467,9 +470,7 @@ class Block extends Position implements BlockIds, Metadatable{ * @return Item[] */ public function getDropsForCompatibleTool(Item $item) : array{ - return [ - ItemFactory::get($this->getItemId(), $this->getVariant()) - ]; + return [$this->getItem()]; } /** @@ -480,9 +481,7 @@ class Block extends Position implements BlockIds, Metadatable{ * @return Item[] */ public function getSilkTouchDrops(Item $item) : array{ - return [ - ItemFactory::get($this->getItemId(), $this->getVariant()) - ]; + return [$this->getItem()]; } /** @@ -524,7 +523,7 @@ class Block extends Position implements BlockIds, Metadatable{ * @return Item */ public function getPickedItem() : Item{ - return ItemFactory::get($this->getItemId(), $this->getVariant()); + return $this->getItem(); } /** diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index 8eb9677e95..e676b57abe 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -83,20 +83,12 @@ class Skull extends Flowable{ return false; } - private function getItem() : Item{ + public function getItem() : Item{ $tile = $this->level->getTile($this); return ItemFactory::get(Item::SKULL, $tile instanceof TileSkull ? $tile->getType() : 0); } - public function getDropsForCompatibleTool(Item $item) : array{ - return [$this->getItem()]; - } - public function isAffectedBySilkTouch() : bool{ return false; } - - public function getPickedItem() : Item{ - return $this->getItem(); - } } From 8873efc303297ea183ebd356d71c4ca2c2787411 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 23 Sep 2018 15:53:16 +0100 Subject: [PATCH 0170/3224] Duplicate block IDs into ItemIds to allow for split this will be necessary to deal with negative IDs (if I choose to do that), and it'll also be necessary if I decide to do any shift hacks to merge ID/variant for block IDs, because we don't want such things to affect items before we're ready to deal with that. --- src/pocketmine/item/ItemIds.php | 252 +++++++++++++++++++++++++++++++- 1 file changed, 250 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/item/ItemIds.php b/src/pocketmine/item/ItemIds.php index 6b0b6cc678..4e250d1927 100644 --- a/src/pocketmine/item/ItemIds.php +++ b/src/pocketmine/item/ItemIds.php @@ -23,10 +23,258 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\block\BlockIds; +interface ItemIds{ -interface ItemIds extends BlockIds{ + public const AIR = 0; + public const STONE = 1; + public const GRASS = 2; + public const DIRT = 3; + public const COBBLESTONE = 4; + public const PLANKS = 5, WOODEN_PLANKS = 5; + public const SAPLING = 6; + public const BEDROCK = 7; + public const FLOWING_WATER = 8; + public const STILL_WATER = 9, WATER = 9; + public const FLOWING_LAVA = 10; + public const LAVA = 11, STILL_LAVA = 11; + public const SAND = 12; + public const GRAVEL = 13; + public const GOLD_ORE = 14; + public const IRON_ORE = 15; + public const COAL_ORE = 16; + public const LOG = 17, WOOD = 17; + public const LEAVES = 18; + public const SPONGE = 19; + public const GLASS = 20; + public const LAPIS_ORE = 21; + public const LAPIS_BLOCK = 22; + public const DISPENSER = 23; + public const SANDSTONE = 24; + public const NOTEBLOCK = 25, NOTE_BLOCK = 25; + public const BED_BLOCK = 26; + public const GOLDEN_RAIL = 27, POWERED_RAIL = 27; + public const DETECTOR_RAIL = 28; + public const STICKY_PISTON = 29; + public const COBWEB = 30, WEB = 30; + public const TALLGRASS = 31, TALL_GRASS = 31; + public const DEADBUSH = 32, DEAD_BUSH = 32; + public const PISTON = 33; + public const PISTONARMCOLLISION = 34, PISTON_ARM_COLLISION = 34; + public const WOOL = 35; + public const DANDELION = 37, YELLOW_FLOWER = 37; + public const POPPY = 38, RED_FLOWER = 38; + public const BROWN_MUSHROOM = 39; + public const RED_MUSHROOM = 40; + public const GOLD_BLOCK = 41; + public const IRON_BLOCK = 42; + public const DOUBLE_STONE_SLAB = 43; + public const STONE_SLAB = 44; + public const BRICK_BLOCK = 45; + public const TNT = 46; + public const BOOKSHELF = 47; + public const MOSSY_COBBLESTONE = 48, MOSS_STONE = 48; + public const OBSIDIAN = 49; + public const TORCH = 50; + public const FIRE = 51; + public const MOB_SPAWNER = 52, MONSTER_SPAWNER = 52; + public const OAK_STAIRS = 53, WOODEN_STAIRS = 53; + public const CHEST = 54; + public const REDSTONE_WIRE = 55; + public const DIAMOND_ORE = 56; + public const DIAMOND_BLOCK = 57; + public const CRAFTING_TABLE = 58, WORKBENCH = 58; + public const WHEAT_BLOCK = 59; + public const FARMLAND = 60; + public const FURNACE = 61; + public const BURNING_FURNACE = 62, LIT_FURNACE = 62; + public const SIGN_POST = 63, STANDING_SIGN = 63; + public const OAK_DOOR_BLOCK = 64, WOODEN_DOOR_BLOCK = 64; + public const LADDER = 65; + public const RAIL = 66; + public const COBBLESTONE_STAIRS = 67, STONE_STAIRS = 67; + public const WALL_SIGN = 68; + public const LEVER = 69; + public const STONE_PRESSURE_PLATE = 70; + public const IRON_DOOR_BLOCK = 71; + public const WOODEN_PRESSURE_PLATE = 72; + public const REDSTONE_ORE = 73; + public const GLOWING_REDSTONE_ORE = 74, LIT_REDSTONE_ORE = 74; + public const UNLIT_REDSTONE_TORCH = 75; + public const LIT_REDSTONE_TORCH = 76, REDSTONE_TORCH = 76; + public const STONE_BUTTON = 77; + public const SNOW_LAYER = 78; + public const ICE = 79; + public const SNOW = 80, SNOW_BLOCK = 80; + public const CACTUS = 81; + public const CLAY_BLOCK = 82; + public const REEDS_BLOCK = 83, SUGARCANE_BLOCK = 83; + public const JUKEBOX = 84; + public const FENCE = 85; + public const PUMPKIN = 86; + public const NETHERRACK = 87; + public const SOUL_SAND = 88; + public const GLOWSTONE = 89; + public const PORTAL = 90; + public const JACK_O_LANTERN = 91, LIT_PUMPKIN = 91; + public const CAKE_BLOCK = 92; + public const REPEATER_BLOCK = 93, UNPOWERED_REPEATER = 93; + public const POWERED_REPEATER = 94; + public const INVISIBLEBEDROCK = 95, INVISIBLE_BEDROCK = 95; + public const TRAPDOOR = 96, WOODEN_TRAPDOOR = 96; + public const MONSTER_EGG = 97; + public const STONEBRICK = 98, STONE_BRICK = 98, STONE_BRICKS = 98; + public const BROWN_MUSHROOM_BLOCK = 99; + public const RED_MUSHROOM_BLOCK = 100; + public const IRON_BARS = 101; + public const GLASS_PANE = 102; + public const MELON_BLOCK = 103; + public const PUMPKIN_STEM = 104; + public const MELON_STEM = 105; + public const VINE = 106, VINES = 106; + public const FENCE_GATE = 107, OAK_FENCE_GATE = 107; + public const BRICK_STAIRS = 108; + public const STONE_BRICK_STAIRS = 109; + public const MYCELIUM = 110; + public const LILY_PAD = 111, WATERLILY = 111, WATER_LILY = 111; + public const NETHER_BRICK_BLOCK = 112; + public const NETHER_BRICK_FENCE = 113; + public const NETHER_BRICK_STAIRS = 114; + public const NETHER_WART_PLANT = 115; + public const ENCHANTING_TABLE = 116, ENCHANTMENT_TABLE = 116; + public const BREWING_STAND_BLOCK = 117; + public const CAULDRON_BLOCK = 118; + public const END_PORTAL = 119; + public const END_PORTAL_FRAME = 120; + public const END_STONE = 121; + public const DRAGON_EGG = 122; + public const REDSTONE_LAMP = 123; + public const LIT_REDSTONE_LAMP = 124; + public const DROPPER = 125; + public const ACTIVATOR_RAIL = 126; + public const COCOA = 127, COCOA_BLOCK = 127; + public const SANDSTONE_STAIRS = 128; + public const EMERALD_ORE = 129; + public const ENDER_CHEST = 130; + public const TRIPWIRE_HOOK = 131; + public const TRIPWIRE = 132, TRIP_WIRE = 132; + public const EMERALD_BLOCK = 133; + public const SPRUCE_STAIRS = 134; + public const BIRCH_STAIRS = 135; + public const JUNGLE_STAIRS = 136; + public const COMMAND_BLOCK = 137; + public const BEACON = 138; + public const COBBLESTONE_WALL = 139, STONE_WALL = 139; + public const FLOWER_POT_BLOCK = 140; + public const CARROTS = 141, CARROT_BLOCK = 141; + public const POTATOES = 142, POTATO_BLOCK = 142; + public const WOODEN_BUTTON = 143; + public const MOB_HEAD_BLOCK = 144, SKULL_BLOCK = 144; + public const ANVIL = 145; + public const TRAPPED_CHEST = 146; + public const LIGHT_WEIGHTED_PRESSURE_PLATE = 147; + public const HEAVY_WEIGHTED_PRESSURE_PLATE = 148; + public const COMPARATOR_BLOCK = 149, UNPOWERED_COMPARATOR = 149; + public const POWERED_COMPARATOR = 150; + public const DAYLIGHT_DETECTOR = 151, DAYLIGHT_SENSOR = 151; + public const REDSTONE_BLOCK = 152; + public const NETHER_QUARTZ_ORE = 153, QUARTZ_ORE = 153; + public const HOPPER_BLOCK = 154; + public const QUARTZ_BLOCK = 155; + public const QUARTZ_STAIRS = 156; + public const DOUBLE_WOODEN_SLAB = 157; + public const WOODEN_SLAB = 158; + public const STAINED_CLAY = 159, STAINED_HARDENED_CLAY = 159, TERRACOTTA = 159; + public const STAINED_GLASS_PANE = 160; + public const LEAVES2 = 161; + public const LOG2 = 162, WOOD2 = 162; + public const ACACIA_STAIRS = 163; + public const DARK_OAK_STAIRS = 164; + public const SLIME = 165, SLIME_BLOCK = 165; + + public const IRON_TRAPDOOR = 167; + public const PRISMARINE = 168; + public const SEALANTERN = 169, SEA_LANTERN = 169; + public const HAY_BALE = 170, HAY_BLOCK = 170; + public const CARPET = 171; + public const HARDENED_CLAY = 172; + public const COAL_BLOCK = 173; + public const PACKED_ICE = 174; + public const DOUBLE_PLANT = 175; + public const STANDING_BANNER = 176; + public const WALL_BANNER = 177; + public const DAYLIGHT_DETECTOR_INVERTED = 178, DAYLIGHT_SENSOR_INVERTED = 178; + public const RED_SANDSTONE = 179; + public const RED_SANDSTONE_STAIRS = 180; + public const DOUBLE_STONE_SLAB2 = 181; + public const STONE_SLAB2 = 182; + public const SPRUCE_FENCE_GATE = 183; + public const BIRCH_FENCE_GATE = 184; + public const JUNGLE_FENCE_GATE = 185; + public const DARK_OAK_FENCE_GATE = 186; + public const ACACIA_FENCE_GATE = 187; + public const REPEATING_COMMAND_BLOCK = 188; + public const CHAIN_COMMAND_BLOCK = 189; + + public const SPRUCE_DOOR_BLOCK = 193; + public const BIRCH_DOOR_BLOCK = 194; + public const JUNGLE_DOOR_BLOCK = 195; + public const ACACIA_DOOR_BLOCK = 196; + public const DARK_OAK_DOOR_BLOCK = 197; + public const GRASS_PATH = 198; + public const FRAME_BLOCK = 199, ITEM_FRAME_BLOCK = 199; + public const CHORUS_FLOWER = 200; + public const PURPUR_BLOCK = 201; + + public const PURPUR_STAIRS = 203; + + public const UNDYED_SHULKER_BOX = 205; + public const END_BRICKS = 206; + public const FROSTED_ICE = 207; + public const END_ROD = 208; + public const END_GATEWAY = 209; + + public const MAGMA = 213; + public const NETHER_WART_BLOCK = 214; + public const RED_NETHER_BRICK = 215; + public const BONE_BLOCK = 216; + + public const SHULKER_BOX = 218; + public const PURPLE_GLAZED_TERRACOTTA = 219; + public const WHITE_GLAZED_TERRACOTTA = 220; + public const ORANGE_GLAZED_TERRACOTTA = 221; + public const MAGENTA_GLAZED_TERRACOTTA = 222; + public const LIGHT_BLUE_GLAZED_TERRACOTTA = 223; + public const YELLOW_GLAZED_TERRACOTTA = 224; + public const LIME_GLAZED_TERRACOTTA = 225; + public const PINK_GLAZED_TERRACOTTA = 226; + public const GRAY_GLAZED_TERRACOTTA = 227; + public const SILVER_GLAZED_TERRACOTTA = 228; + public const CYAN_GLAZED_TERRACOTTA = 229; + + public const BLUE_GLAZED_TERRACOTTA = 231; + public const BROWN_GLAZED_TERRACOTTA = 232; + public const GREEN_GLAZED_TERRACOTTA = 233; + public const RED_GLAZED_TERRACOTTA = 234; + public const BLACK_GLAZED_TERRACOTTA = 235; + public const CONCRETE = 236; + public const CONCRETEPOWDER = 237, CONCRETE_POWDER = 237; + + public const CHORUS_PLANT = 240; + public const STAINED_GLASS = 241; + + public const PODZOL = 243; + public const BEETROOT_BLOCK = 244; + public const STONECUTTER = 245; + public const GLOWINGOBSIDIAN = 246, GLOWING_OBSIDIAN = 246; + public const NETHERREACTOR = 247, NETHER_REACTOR = 247; + public const INFO_UPDATE = 248; + public const INFO_UPDATE2 = 249; + public const MOVINGBLOCK = 250, MOVING_BLOCK = 250; + public const OBSERVER = 251; + public const STRUCTURE_BLOCK = 252; + + public const RESERVED6 = 255; public const IRON_SHOVEL = 256; public const IRON_PICKAXE = 257; public const IRON_AXE = 258; From c501c740a11c0b3f19c9caec0222efb9e88799c2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 23 Sep 2018 17:05:03 +0100 Subject: [PATCH 0171/3224] Get rid of Block->canPassThrough() This is only implemented in 1 place where the collision box should just be zero anyway, so there's no point this existing. There's a lot of other blocks which should have bounding boxes without collision boxes as well, but that's outside the scope of this commit. --- src/pocketmine/block/Block.php | 4 ---- src/pocketmine/block/Vine.php | 8 ++++---- src/pocketmine/level/Level.php | 12 +++++------- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 95973a8c2b..35e868efc7 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -413,10 +413,6 @@ class Block extends Position implements BlockIds, Metadatable{ return false; } - public function canPassThrough() : bool{ - return false; - } - /** * Returns whether entities can climb up this block. * @return bool diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index 1f00611571..fdfd7cb0cd 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -78,10 +78,6 @@ class Vine extends Flowable{ return 0.2; } - public function canPassThrough() : bool{ - return true; - } - public function hasEntityCollision() : bool{ return true; } @@ -150,6 +146,10 @@ class Vine extends Flowable{ return new AxisAlignedBB($minX, $minY, $minZ, $maxX, 1, $maxZ); } + protected function recalculateCollisionBoxes() : array{ + return []; + } + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if(!$blockClicked->isSolid() or Facing::axis($face) === Facing::AXIS_Y){ return false; diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 571f14cefb..8d46999651 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1131,7 +1131,7 @@ class Level implements ChunkManager, Metadatable{ for($x = $minX; $x <= $maxX; ++$x){ for($y = $minY; $y <= $maxY; ++$y){ $block = $this->getBlockAt($x, $y, $z); - if(!$block->canPassThrough() and $block->collidesWithBB($bb)){ + if($block->collidesWithBB($bb)){ return [$block]; } } @@ -1142,7 +1142,7 @@ class Level implements ChunkManager, Metadatable{ for($x = $minX; $x <= $maxX; ++$x){ for($y = $minY; $y <= $maxY; ++$y){ $block = $this->getBlockAt($x, $y, $z); - if(!$block->canPassThrough() and $block->collidesWithBB($bb)){ + if($block->collidesWithBB($bb)){ $collides[] = $block; } } @@ -1193,11 +1193,9 @@ class Level implements ChunkManager, Metadatable{ for($x = $minX; $x <= $maxX; ++$x){ for($y = $minY; $y <= $maxY; ++$y){ $block = $this->getBlockAt($x, $y, $z); - if(!$block->canPassThrough()){ - foreach($block->getCollisionBoxes() as $blockBB){ - if($blockBB->intersectsWith($bb)){ - $collides[] = $blockBB; - } + foreach($block->getCollisionBoxes() as $blockBB){ + if($blockBB->intersectsWith($bb)){ + $collides[] = $blockBB; } } } From 0b989925d708f239eac62d905952b6b9b44fbc18 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 23 Sep 2018 18:41:57 +0100 Subject: [PATCH 0172/3224] whitespace --- src/pocketmine/block/Block.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 35e868efc7..364e6be11e 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -131,6 +131,7 @@ class Block extends Position implements BlockIds, Metadatable{ public function getRuntimeId() : int{ return BlockFactory::toStaticRuntimeId($this->getId(), $this->getDamage()); } + /** * @return int */ From a77e05f875ac645557cd2c15c0e64b694946cf7b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 24 Sep 2018 16:25:17 +0100 Subject: [PATCH 0173/3224] Implement corner stair BB handling --- src/pocketmine/block/Stair.php | 60 ++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index 23bc452404..dcdaf1ac0f 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -50,8 +50,6 @@ abstract class Stair extends Transparent{ } protected function recalculateCollisionBoxes() : array{ - //TODO: handle corners - $minYSlab = $this->upsideDown ? 0.5 : 0; $bbs = [ @@ -60,29 +58,55 @@ abstract class Stair extends Transparent{ $minY = $this->upsideDown ? 0 : 0.5; - $minX = $minZ = 0; - $maxX = $maxZ = 1; + $topStep = new AxisAlignedBB(0, $minY, 0, 1, $minY + 0.5, 1); + self::setBoundsForFacing($topStep, $this->facing); - switch($this->facing){ - case Facing::EAST: - $minX = 0.5; - break; - case Facing::WEST: - $maxX = 0.5; - break; - case Facing::SOUTH: - $minZ = 0.5; - break; - case Facing::NORTH: - $maxZ = 0.5; - break; + /** @var Stair $corner */ + if(($backFacing = $this->getPossibleCornerFacing(false)) !== null){ + self::setBoundsForFacing($topStep, $backFacing); + }elseif(($frontFacing = $this->getPossibleCornerFacing(true)) !== null){ + //add an extra cube + $extraCube = new AxisAlignedBB(0, $minY, 0, 1, $minY + 0.5, 1); + self::setBoundsForFacing($extraCube, Facing::opposite($this->facing)); + self::setBoundsForFacing($extraCube, $frontFacing); + $bbs[] = $extraCube; } - $bbs[] = new AxisAlignedBB($minX, $minY, $minZ, $maxX, $minY + 0.5, $maxZ); + $bbs[] = $topStep; return $bbs; } + private function getPossibleCornerFacing(bool $oppositeFacing) : ?int{ + $side = $this->getSide($oppositeFacing ? Facing::opposite($this->facing) : $this->facing); + if($side instanceof Stair and $side->upsideDown === $this->upsideDown and ( + $side->facing === Facing::rotate($this->facing, Facing::AXIS_Y, true) or + $side->facing === Facing::rotate($this->facing, Facing::AXIS_Y, false)) + ){ + return $side->facing; + } + return null; + } + + private static function setBoundsForFacing(AxisAlignedBB $bb, int $facing) : void{ + switch($facing){ + case Facing::EAST: + $bb->minX = 0.5; + break; + case Facing::WEST: + $bb->maxX = 0.5; + break; + case Facing::SOUTH: + $bb->minZ = 0.5; + break; + case Facing::NORTH: + $bb->maxZ = 0.5; + break; + default: + throw new \InvalidArgumentException("Facing must be horizontal"); + } + } + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ $this->facing = Bearing::toFacing($player->getDirection()); From a195e940db5587d66d122f37df870f8811e73969 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 24 Sep 2018 16:37:18 +0100 Subject: [PATCH 0174/3224] Fixed BB and right-click action for daylight sensor --- src/pocketmine/block/DaylightSensor.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/pocketmine/block/DaylightSensor.php b/src/pocketmine/block/DaylightSensor.php index 7ffe1377ea..faa2acc236 100644 --- a/src/pocketmine/block/DaylightSensor.php +++ b/src/pocketmine/block/DaylightSensor.php @@ -23,6 +23,10 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\item\Item; +use pocketmine\math\AxisAlignedBB; +use pocketmine\Player; + class DaylightSensor extends Transparent{ protected $itemId = self::DAYLIGHT_SENSOR; @@ -77,5 +81,15 @@ class DaylightSensor extends Transparent{ return BlockToolType::TYPE_AXE; } + protected function recalculateBoundingBox() : ?AxisAlignedBB{ + return new AxisAlignedBB(0, 0, 0, 1, 0.5, 1); + } + + public function onActivate(Item $item, Player $player = null) : bool{ + $this->inverted = !$this->inverted; + $this->level->setBlock($this, $this); + return true; + } + //TODO } From 9651b3f470920cbc312f57ca669b80c9ffad30de Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 24 Sep 2018 16:48:19 +0100 Subject: [PATCH 0175/3224] Crops: micro optimization - check age before generating random number (faster) I don't have any idea how much benefit this will provide in real terms, but it may be significant. --- src/pocketmine/block/Crops.php | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index e890fa3dd4..66866180f5 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -92,15 +92,13 @@ abstract class Crops extends Flowable{ } public function onRandomTick() : void{ - if(mt_rand(0, 2) === 1){ - if($this->age < 7){ - $block = clone $this; - ++$block->age; - Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block)); + if($this->age < 7 and mt_rand(0, 2) === 1){ + $block = clone $this; + ++$block->age; + Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block)); - if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($this, $ev->getNewState(), true, true); - } + if(!$ev->isCancelled()){ + $this->getLevel()->setBlock($this, $ev->getNewState(), true, true); } } } From f2c960cfd8571679983ef5b2fc6658b7aef25b0f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 26 Sep 2018 19:19:35 +0100 Subject: [PATCH 0176/3224] Added on/off handling for buttons and levers --- src/pocketmine/block/Button.php | 19 ++++++++++++++++++- src/pocketmine/block/Lever.php | 11 +++++++++++ src/pocketmine/block/StoneButton.php | 4 ++++ src/pocketmine/block/WoodenButton.php | 8 ++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/block/Button.php b/src/pocketmine/block/Button.php index 9dc3291599..8baa3af126 100644 --- a/src/pocketmine/block/Button.php +++ b/src/pocketmine/block/Button.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\Player; abstract class Button extends Flowable{ @@ -59,8 +60,24 @@ abstract class Button extends Flowable{ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } + abstract protected function getActivationTime() : int; + public function onActivate(Item $item, Player $player = null) : bool{ - //TODO + if(!$this->powered){ + $this->powered = true; + $this->level->setBlock($this, $this); + $this->level->scheduleDelayedBlockUpdate($this, $this->getActivationTime()); + $this->level->broadcastLevelSoundEvent($this->add(0.5, 0.5, 0.5), LevelSoundEventPacket::SOUND_POWER_ON); + } + return true; } + + public function onScheduledUpdate() : void{ + if($this->powered){ + $this->powered = false; + $this->level->setBlock($this, $this); + $this->level->broadcastLevelSoundEvent($this->add(0.5, 0.5, 0.5), LevelSoundEventPacket::SOUND_POWER_OFF); + } + } } diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index a44ef16f20..410ef6ff91 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -27,6 +27,7 @@ use pocketmine\item\Item; use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\Player; class Lever extends Flowable{ @@ -118,5 +119,15 @@ class Lever extends Flowable{ } } + public function onActivate(Item $item, Player $player = null) : bool{ + $this->powered = !$this->powered; + $this->level->setBlock($this, $this); + $this->level->broadcastLevelSoundEvent( + $this->add(0.5, 0.5, 0.5), + $this->powered ? LevelSoundEventPacket::SOUND_POWER_ON : LevelSoundEventPacket::SOUND_POWER_OFF + ); + return true; + } + //TODO } diff --git a/src/pocketmine/block/StoneButton.php b/src/pocketmine/block/StoneButton.php index a677e0f305..9471b1b78e 100644 --- a/src/pocketmine/block/StoneButton.php +++ b/src/pocketmine/block/StoneButton.php @@ -38,4 +38,8 @@ class StoneButton extends Button{ public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } + + protected function getActivationTime() : int{ + return 20; + } } diff --git a/src/pocketmine/block/WoodenButton.php b/src/pocketmine/block/WoodenButton.php index a62225cc2e..85f7b978c4 100644 --- a/src/pocketmine/block/WoodenButton.php +++ b/src/pocketmine/block/WoodenButton.php @@ -38,4 +38,12 @@ class WoodenButton extends Button{ public function getToolType() : int{ return BlockToolType::TYPE_AXE; } + + protected function getActivationTime() : int{ + return 30; + } + + public function hasEntityCollision() : bool{ + return false; //TODO: arrows activate wooden buttons + } } From ac3509aa3db808adeeceff26c9e3be6b38ad5a2a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 26 Sep 2018 19:58:03 +0100 Subject: [PATCH 0177/3224] Updated BedrockData submodule this change won't be backported to other branches due to technical limitations that can't be easily solved without API breaks. --- src/pocketmine/resources/vanilla | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/resources/vanilla b/src/pocketmine/resources/vanilla index 0c00c4f3b9..4b0bcd0e52 160000 --- a/src/pocketmine/resources/vanilla +++ b/src/pocketmine/resources/vanilla @@ -1 +1 @@ -Subproject commit 0c00c4f3b9de1b6b0866cab79a66a91182ae5405 +Subproject commit 4b0bcd0e52d8802d8692d6c3ade7c2351ddb11b7 From e6a13989924be150fed7bdef37ac296db3164110 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Sep 2018 02:36:39 -0400 Subject: [PATCH 0178/3224] EndRod: fix BB rotation on X/Z axes this was very apparent with the new code, less so with the magic meta values... --- src/pocketmine/block/EndRod.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/pocketmine/block/EndRod.php b/src/pocketmine/block/EndRod.php index 25391667bc..c639fc495e 100644 --- a/src/pocketmine/block/EndRod.php +++ b/src/pocketmine/block/EndRod.php @@ -95,15 +95,6 @@ class EndRod extends Flowable{ 1 - $width ); case Facing::AXIS_Z: - return new AxisAlignedBB( - 0, - $width, - $width, - 1, - 1 - $width, - 1 - $width - ); - case Facing::AXIS_X: return new AxisAlignedBB( $width, $width, @@ -112,6 +103,16 @@ class EndRod extends Flowable{ 1 - $width, 1 ); + + case Facing::AXIS_X: + return new AxisAlignedBB( + 0, + $width, + $width, + 1, + 1 - $width, + 1 - $width + ); } return null; From 8a8f1d84ff5ca40339281f36cf969d3a5ba5cac9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Sep 2018 11:29:17 +0100 Subject: [PATCH 0179/3224] EnchantingTable: fix BB --- src/pocketmine/block/EnchantingTable.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pocketmine/block/EnchantingTable.php b/src/pocketmine/block/EnchantingTable.php index 0b0d066c21..c608d394e7 100644 --- a/src/pocketmine/block/EnchantingTable.php +++ b/src/pocketmine/block/EnchantingTable.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\inventory\EnchantInventory; use pocketmine\item\Item; use pocketmine\item\TieredTool; +use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\EnchantTable as TileEnchantTable; @@ -68,6 +69,10 @@ class EnchantingTable extends Transparent{ return TieredTool::TIER_WOODEN; } + protected function recalculateBoundingBox() : ?AxisAlignedBB{ + return new AxisAlignedBB(0, 0, 0, 1, 0.75, 1); + } + public function onActivate(Item $item, Player $player = null) : bool{ if($player instanceof Player){ //TODO lock From 16f2ac14b3630896368dfb04f763d8f4728c85ec Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Sep 2018 15:56:08 +0100 Subject: [PATCH 0180/3224] Clean up block update sending, remove UpdateBlockPacket flag constants These flags are not intended for network use, instead they are supposed to be used internally by the game. For network, we only need to care about the 0x02 flag (send to players) because that's necessary for the client to render the block. --- src/pocketmine/Player.php | 5 +- src/pocketmine/level/Level.php | 68 +++++-------------- .../mcpe/protocol/UpdateBlockPacket.php | 17 ++--- 3 files changed, 25 insertions(+), 65 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 1489fd7812..801083f140 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -122,7 +122,6 @@ use pocketmine\network\mcpe\protocol\types\CommandParameter; use pocketmine\network\mcpe\protocol\types\ContainerIds; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; -use pocketmine\network\mcpe\protocol\UpdateBlockPacket; use pocketmine\network\mcpe\ProcessLoginTask; use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissionAttachment; @@ -2208,7 +2207,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $blocks = $target->getAllSides(); $blocks[] = $target; - $this->level->sendBlocks([$this], $blocks, UpdateBlockPacket::FLAG_ALL_PRIORITY); + $this->level->sendBlocks([$this], $blocks); foreach($blocks as $b){ $tile = $this->level->getTile($b); @@ -2255,7 +2254,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ /** @var Block[] $blocks */ $blocks = array_merge($target->getAllSides(), $block->getAllSides()); //getAllSides() on each of these will include $target and $block because they are next to each other - $this->level->sendBlocks([$this], $blocks, UpdateBlockPacket::FLAG_ALL_PRIORITY); + $this->level->sendBlocks([$this], $blocks); return false; } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 8d46999651..13cbbb65a2 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -799,7 +799,7 @@ class Level implements ChunkManager, Metadatable{ $p->onChunkChanged($chunk); } }else{ - $this->sendBlocks($this->getChunkPlayers($chunkX, $chunkZ), $blocks, UpdateBlockPacket::FLAG_ALL); + $this->sendBlocks($this->getChunkPlayers($chunkX, $chunkZ), $blocks); } } }else{ @@ -870,62 +870,28 @@ class Level implements ChunkManager, Metadatable{ /** * @param Player[] $target * @param Vector3[] $blocks - * @param int $flags - * @param bool $optimizeRebuilds */ - public function sendBlocks(array $target, array $blocks, int $flags = UpdateBlockPacket::FLAG_NONE, bool $optimizeRebuilds = false){ + public function sendBlocks(array $target, array $blocks){ $packets = []; - if($optimizeRebuilds){ - $chunks = []; - foreach($blocks as $b){ - if(!($b instanceof Vector3)){ - throw new \TypeError("Expected Vector3 in blocks array, got " . (is_object($b) ? get_class($b) : gettype($b))); - } - $pk = new UpdateBlockPacket(); - $first = false; - if(!isset($chunks[$index = Level::chunkHash($b->x >> 4, $b->z >> 4)])){ - $chunks[$index] = true; - $first = true; - } - - $pk->x = $b->x; - $pk->y = $b->y; - $pk->z = $b->z; - - if($b instanceof Block){ - $pk->blockRuntimeId = $b->getRuntimeId(); - }else{ - $fullBlock = $this->getFullBlock($b->x, $b->y, $b->z); - $pk->blockRuntimeId = BlockFactory::toStaticRuntimeId($fullBlock >> 4, $fullBlock & 0xf); - } - - $pk->flags = $first ? $flags : UpdateBlockPacket::FLAG_NONE; - - $packets[] = $pk; + foreach($blocks as $b){ + if(!($b instanceof Vector3)){ + throw new \TypeError("Expected Vector3 in blocks array, got " . (is_object($b) ? get_class($b) : gettype($b))); } - }else{ - foreach($blocks as $b){ - if(!($b instanceof Vector3)){ - throw new \TypeError("Expected Vector3 in blocks array, got " . (is_object($b) ? get_class($b) : gettype($b))); - } - $pk = new UpdateBlockPacket(); + $pk = new UpdateBlockPacket(); - $pk->x = $b->x; - $pk->y = $b->y; - $pk->z = $b->z; + $pk->x = $b->x; + $pk->y = $b->y; + $pk->z = $b->z; - if($b instanceof Block){ - $pk->blockRuntimeId = $b->getRuntimeId(); - }else{ - $fullBlock = $this->getFullBlock($b->x, $b->y, $b->z); - $pk->blockRuntimeId = BlockFactory::toStaticRuntimeId($fullBlock >> 4, $fullBlock & 0xf); - } - - $pk->flags = $flags; - - $packets[] = $pk; + if($b instanceof Block){ + $pk->blockRuntimeId = $b->getRuntimeId(); + }else{ + $fullBlock = $this->getFullBlock($b->x, $b->y, $b->z); + $pk->blockRuntimeId = BlockFactory::toStaticRuntimeId($fullBlock >> 4, $fullBlock & 0xf); } + + $packets[] = $pk; } $this->server->broadcastPackets($target, $packets); @@ -1547,7 +1513,7 @@ class Level implements ChunkManager, Metadatable{ unset($this->blockCache[$chunkHash][$blockHash]); if($direct){ - $this->sendBlocks($this->getChunkPlayers($pos->x >> 4, $pos->z >> 4), [$block], UpdateBlockPacket::FLAG_ALL_PRIORITY); + $this->sendBlocks($this->getChunkPlayers($pos->x >> 4, $pos->z >> 4), [$block]); unset($this->chunkCache[$chunkHash], $this->changedBlocks[$chunkHash][$blockHash]); }else{ if(!isset($this->changedBlocks[$chunkHash])){ diff --git a/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php index db70663289..254f54bd04 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php @@ -31,15 +31,6 @@ use pocketmine\network\mcpe\handler\SessionHandler; class UpdateBlockPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_BLOCK_PACKET; - public const FLAG_NONE = 0b0000; - public const FLAG_NEIGHBORS = 0b0001; - public const FLAG_NETWORK = 0b0010; - public const FLAG_NOGRAPHIC = 0b0100; - public const FLAG_PRIORITY = 0b1000; - - public const FLAG_ALL = self::FLAG_NEIGHBORS | self::FLAG_NETWORK; - public const FLAG_ALL_PRIORITY = self::FLAG_ALL | self::FLAG_PRIORITY; - public const DATA_LAYER_NORMAL = 0; public const DATA_LAYER_LIQUID = 1; @@ -51,8 +42,12 @@ class UpdateBlockPacket extends DataPacket{ public $y; /** @var int */ public $blockRuntimeId; - /** @var int */ - public $flags; + /** + * @var int + * Flags are used by MCPE internally for block setting, but only flag 2 (network flag) is relevant for network. + * This field is pointless really. + */ + public $flags = 0x02; /** @var int */ public $dataLayerId = self::DATA_LAYER_NORMAL; From 75f364fcf2ff951b8e35070516352a2d82f3c130 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Sep 2018 16:15:07 +0100 Subject: [PATCH 0181/3224] Level: Remove obsolete \$direct parameter from setBlock() this parameter was previously used to send blocks with a different set of flags, immediately, to players. However, the flags have been demonstrated useless and the direct sending is pointless now since packets are buffered now per session, so we might as well take advantage of the batched block update sending. --- src/pocketmine/block/BaseRail.php | 2 +- src/pocketmine/block/Bed.php | 6 +++--- src/pocketmine/block/Block.php | 4 ++-- src/pocketmine/block/Cactus.php | 2 +- src/pocketmine/block/Cake.php | 2 +- src/pocketmine/block/Crops.php | 4 ++-- src/pocketmine/block/Dirt.php | 4 ++-- src/pocketmine/block/Door.php | 10 +++++----- src/pocketmine/block/DoublePlant.php | 4 ++-- src/pocketmine/block/Fallable.php | 2 +- src/pocketmine/block/Farmland.php | 8 ++++---- src/pocketmine/block/FenceGate.php | 2 +- src/pocketmine/block/Fire.php | 2 +- src/pocketmine/block/FlowerPot.php | 2 +- src/pocketmine/block/Grass.php | 4 ++-- src/pocketmine/block/GrassPath.php | 2 +- src/pocketmine/block/Ice.php | 2 +- src/pocketmine/block/Leaves.php | 4 ++-- src/pocketmine/block/Liquid.php | 8 ++++---- src/pocketmine/block/MelonStem.php | 4 ++-- src/pocketmine/block/NetherWartPlant.php | 2 +- src/pocketmine/block/PumpkinStem.php | 4 ++-- src/pocketmine/block/RedstoneOre.php | 2 +- src/pocketmine/block/Sapling.php | 2 +- src/pocketmine/block/SignPost.php | 2 +- src/pocketmine/block/Slab.php | 10 +++++----- src/pocketmine/block/SnowLayer.php | 4 ++-- src/pocketmine/block/StandingBanner.php | 2 +- src/pocketmine/block/Sugarcane.php | 10 +++++----- src/pocketmine/block/TNT.php | 2 +- src/pocketmine/block/TallGrass.php | 2 +- src/pocketmine/block/Trapdoor.php | 2 +- src/pocketmine/entity/object/FallingBlock.php | 2 +- src/pocketmine/item/Bucket.php | 4 ++-- src/pocketmine/item/FlintSteel.php | 2 +- src/pocketmine/level/Level.php | 19 ++++--------------- src/pocketmine/tile/Furnace.php | 4 ++-- 37 files changed, 71 insertions(+), 82 deletions(-) diff --git a/src/pocketmine/block/BaseRail.php b/src/pocketmine/block/BaseRail.php index b7a0d96b6a..682404a0e5 100644 --- a/src/pocketmine/block/BaseRail.php +++ b/src/pocketmine/block/BaseRail.php @@ -264,7 +264,7 @@ abstract class BaseRail extends Flowable{ } $this->connections = $connections; - $this->level->setBlock($this, $this, false, false); //avoid recursion + $this->level->setBlock($this, $this, false); //avoid recursion } public function onNearbyBlockChange() : void{ diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 658433ab11..9586015a05 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -96,11 +96,11 @@ class Bed extends Transparent{ public function setOccupied(bool $occupied = true){ $this->occupied = $occupied; - $this->level->setBlock($this, $this, false, false); + $this->level->setBlock($this, $this, false); if(($other = $this->getOtherHalf()) !== null){ $other->occupied = $occupied; - $this->level->setBlock($other, $other, false, false); + $this->level->setBlock($other, $other, false); } } @@ -170,7 +170,7 @@ class Bed extends Transparent{ parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); $nextState = clone $this; $nextState->head = true; - $this->getLevel()->setBlock($next, $nextState, true, true); + $this->getLevel()->setBlock($next, $nextState); Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($this, $face, $item, $player)); Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($next, $face, $item, $player)); diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 364e6be11e..60c2920450 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -198,7 +198,7 @@ class Block extends Position implements BlockIds, Metadatable{ * @return bool */ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - return $this->getLevel()->setBlock($blockReplace, $this, true, true); + return $this->getLevel()->setBlock($blockReplace, $this); } /** @@ -266,7 +266,7 @@ class Block extends Position implements BlockIds, Metadatable{ * @return bool */ public function onBreak(Item $item, Player $player = null) : bool{ - return $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true, true); + return $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR)); } diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index 97c10529db..6e452d0b07 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -106,7 +106,7 @@ class Cactus extends Transparent{ if($b->getId() === self::AIR){ Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($b, BlockFactory::get(Block::CACTUS))); if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($b, $ev->getNewState(), true); + $this->getLevel()->setBlock($b, $ev->getNewState()); } } } diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index f082ba2bd7..35862bacaf 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -89,7 +89,7 @@ class Cake extends Transparent implements FoodSource{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() === self::AIR){ //Replace with common break method - $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true); + $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR)); } } diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index 66866180f5..5ce339e245 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -70,7 +70,7 @@ abstract class Crops extends Flowable{ Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block)); if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($this, $ev->getNewState(), true, true); + $this->getLevel()->setBlock($this, $ev->getNewState()); } $item->count--; @@ -98,7 +98,7 @@ abstract class Crops extends Flowable{ Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block)); if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($this, $ev->getNewState(), true, true); + $this->getLevel()->setBlock($this, $ev->getNewState()); } } } diff --git a/src/pocketmine/block/Dirt.php b/src/pocketmine/block/Dirt.php index fea10f3e20..2bc32e343c 100644 --- a/src/pocketmine/block/Dirt.php +++ b/src/pocketmine/block/Dirt.php @@ -43,9 +43,9 @@ class Dirt extends Solid{ if($item instanceof Hoe){ $item->applyDamage(1); if($this->variant === self::COARSE){ - $this->getLevel()->setBlock($this, BlockFactory::get(Block::DIRT), true); + $this->getLevel()->setBlock($this, BlockFactory::get(Block::DIRT)); }else{ - $this->getLevel()->setBlock($this, BlockFactory::get(Block::FARMLAND), true); + $this->getLevel()->setBlock($this, BlockFactory::get(Block::FARMLAND)); } return true; diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 31edd423d3..1d081680fa 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -143,9 +143,9 @@ abstract class Door extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() === self::AIR){ //Replace with common break method - $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), false); + $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR)); if($this->getSide(Facing::UP) instanceof Door){ - $this->getLevel()->setBlock($this->getSide(Facing::UP), BlockFactory::get(Block::AIR), false); + $this->getLevel()->setBlock($this->getSide(Facing::UP), BlockFactory::get(Block::AIR)); } } } @@ -173,7 +173,7 @@ abstract class Door extends Transparent{ $topHalf->top = true; parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); - $this->level->setBlock($blockUp, $topHalf, true); //Top + $this->level->setBlock($blockUp, $topHalf); //Top return true; } @@ -187,10 +187,10 @@ abstract class Door extends Transparent{ $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); if($other instanceof Door and $this->getId() === $other->getId()){ $other->open = $this->open; - $this->level->setBlock($other, $other, true, true); + $this->level->setBlock($other, $other); } - $this->level->setBlock($this, $this, true, true); + $this->level->setBlock($this, $this); $this->level->addSound(new DoorSound($this)); return true; diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index 8f11b1e9c8..caecc5c0a2 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -54,10 +54,10 @@ class DoublePlant extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $id = $blockReplace->getSide(Facing::DOWN)->getId(); if(($id === Block::GRASS or $id === Block::DIRT) and $blockReplace->getSide(Facing::UP)->canBeReplaced()){ - $this->getLevel()->setBlock($blockReplace, $this, false, false); + $this->getLevel()->setBlock($blockReplace, $this, false); $top = clone $this; $top->top = true; - $this->getLevel()->setBlock($blockReplace->getSide(Facing::UP), $top, false, false); + $this->getLevel()->setBlock($blockReplace->getSide(Facing::UP), $top, false); return true; } diff --git a/src/pocketmine/block/Fallable.php b/src/pocketmine/block/Fallable.php index 990a13ebe9..b9bc89571b 100644 --- a/src/pocketmine/block/Fallable.php +++ b/src/pocketmine/block/Fallable.php @@ -31,7 +31,7 @@ abstract class Fallable extends Solid{ public function onNearbyBlockChange() : void{ $down = $this->getSide(Facing::DOWN); if($down->getId() === self::AIR or $down instanceof Liquid or $down instanceof Fire){ - $this->level->setBlock($this, BlockFactory::get(Block::AIR), true); + $this->level->setBlock($this, BlockFactory::get(Block::AIR)); $nbt = Entity::createBaseNBT($this->add(0.5, 0, 0.5)); $nbt->setInt("TileID", $this->getId()); diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index 0db8a649ae..89c50a41cc 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -69,7 +69,7 @@ class Farmland extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::UP)->isSolid()){ - $this->level->setBlock($this, BlockFactory::get(Block::DIRT), true); + $this->level->setBlock($this, BlockFactory::get(Block::DIRT)); } } @@ -81,13 +81,13 @@ class Farmland extends Transparent{ if(!$this->canHydrate()){ if($this->wetness > 0){ $this->wetness--; - $this->level->setBlock($this, $this, false, false); + $this->level->setBlock($this, $this, false); }else{ - $this->level->setBlock($this, BlockFactory::get(Block::DIRT), false, true); + $this->level->setBlock($this, BlockFactory::get(Block::DIRT)); } }elseif($this->wetness < 7){ $this->wetness = 7; - $this->level->setBlock($this, $this, false, false); + $this->level->setBlock($this, $this, false); } } diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index 5f14cdcd74..cd8878a450 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -102,7 +102,7 @@ class FenceGate extends Transparent{ } } - $this->getLevel()->setBlock($this, $this, true); + $this->getLevel()->setBlock($this, $this); $this->level->addSound(new DoorSound($this)); return true; } diff --git a/src/pocketmine/block/Fire.php b/src/pocketmine/block/Fire.php index 7aa4abd1f8..f0757c87ee 100644 --- a/src/pocketmine/block/Fire.php +++ b/src/pocketmine/block/Fire.php @@ -96,7 +96,7 @@ class Fire extends Flowable{ public function onNearbyBlockChange() : void{ if(!$this->getSide(Facing::DOWN)->isSolid() and !$this->hasAdjacentFlammableBlocks()){ - $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true); + $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR)); }else{ $this->level->scheduleDelayedBlockUpdate($this, mt_rand(30, 40)); } diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 2a07fd07dc..e8b2eb8b3f 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -93,7 +93,7 @@ class FlowerPot extends Flowable{ } $this->occupied = true; - $this->getLevel()->setBlock($this, $this, true, false); + $this->getLevel()->setBlock($this, $this, false); $pot->setItem($item->pop()); return true; diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index 954c5f9ba0..b7c57158e4 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -69,7 +69,7 @@ class Grass extends Solid{ //grass dies $this->level->getServer()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($this, $this, BlockFactory::get(Block::DIRT))); if(!$ev->isCancelled()){ - $this->level->setBlock($this, $ev->getNewState(), false, false); + $this->level->setBlock($this, $ev->getNewState(), false); } }elseif($lightAbove >= 9){ //try grass spread @@ -88,7 +88,7 @@ class Grass extends Solid{ $this->level->getServer()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($b = $this->level->getBlockAt($x, $y, $z), $this, BlockFactory::get(Block::GRASS))); if(!$ev->isCancelled()){ - $this->level->setBlock($b, $ev->getNewState(), false, false); + $this->level->setBlock($b, $ev->getNewState(), false); } } } diff --git a/src/pocketmine/block/GrassPath.php b/src/pocketmine/block/GrassPath.php index 9ec3737afc..389d5ee58e 100644 --- a/src/pocketmine/block/GrassPath.php +++ b/src/pocketmine/block/GrassPath.php @@ -54,7 +54,7 @@ class GrassPath extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::UP)->isSolid()){ - $this->level->setBlock($this, BlockFactory::get(Block::DIRT), true); + $this->level->setBlock($this, BlockFactory::get(Block::DIRT)); } } diff --git a/src/pocketmine/block/Ice.php b/src/pocketmine/block/Ice.php index fb100a4f7e..f0b243a859 100644 --- a/src/pocketmine/block/Ice.php +++ b/src/pocketmine/block/Ice.php @@ -57,7 +57,7 @@ class Ice extends Transparent{ public function onBreak(Item $item, Player $player = null) : bool{ if(!$item->hasEnchantment(Enchantment::SILK_TOUCH)){ - return $this->getLevel()->setBlock($this, BlockFactory::get(Block::WATER), true); + return $this->getLevel()->setBlock($this, BlockFactory::get(Block::WATER)); } return parent::onBreak($item, $player); } diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 11dd7fc4b9..52e70d532a 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -98,7 +98,7 @@ class Leaves extends Transparent{ public function onNearbyBlockChange() : void{ if(!$this->noDecay and !$this->checkDecay){ $this->checkDecay = true; - $this->getLevel()->setBlock($this, $this, true, false); + $this->getLevel()->setBlock($this, $this, false); } } @@ -111,7 +111,7 @@ class Leaves extends Transparent{ $this->getLevel()->getServer()->getPluginManager()->callEvent($ev = new LeavesDecayEvent($this)); if($ev->isCancelled() or $this->findLog($this)){ - $this->getLevel()->setBlock($this, $this, false, false); + $this->getLevel()->setBlock($this, $this, false); }else{ $this->getLevel()->useBreakOn($this); } diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index 978d3c520b..ff8d20587a 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -248,13 +248,13 @@ abstract class Liquid extends Transparent{ if($newDecay !== $this->decay or $falling !== $this->falling){ if(!$falling and $newDecay < 0){ - $this->level->setBlock($this, BlockFactory::get(Block::AIR), true, true); + $this->level->setBlock($this, BlockFactory::get(Block::AIR)); return; } $this->falling = $falling; $this->decay = $falling ? 0 : $newDecay; - $this->level->setBlock($this, $this, true, true); //local block update will cause an update to be scheduled + $this->level->setBlock($this, $this); //local block update will cause an update to be scheduled } } @@ -302,7 +302,7 @@ abstract class Liquid extends Transparent{ $new = clone $this; $new->falling = $falling; $new->decay = $falling ? 0 : $newFlowDecay; - $this->level->setBlock($block, $new, true, true); + $this->level->setBlock($block, $new); } } @@ -432,7 +432,7 @@ abstract class Liquid extends Transparent{ protected function liquidCollide(Block $cause, Block $result) : bool{ //TODO: add events - $this->level->setBlock($this, $result, true, true); + $this->level->setBlock($this, $result); $this->level->broadcastLevelSoundEvent($this->add(0.5, 0.5, 0.5), LevelSoundEventPacket::SOUND_FIZZ, (int) ((2.6 + (lcg_value() - lcg_value()) * 0.8) * 1000)); return true; } diff --git a/src/pocketmine/block/MelonStem.php b/src/pocketmine/block/MelonStem.php index aeb6eabc7d..553230a3ef 100644 --- a/src/pocketmine/block/MelonStem.php +++ b/src/pocketmine/block/MelonStem.php @@ -44,7 +44,7 @@ class MelonStem extends Crops{ ++$block->age; Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block)); if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($this, $ev->getNewState(), true); + $this->getLevel()->setBlock($this, $ev->getNewState()); } }else{ foreach(Facing::HORIZONTAL as $side){ @@ -58,7 +58,7 @@ class MelonStem extends Crops{ if($side->getId() === self::AIR and ($d->getId() === self::FARMLAND or $d->getId() === self::GRASS or $d->getId() === self::DIRT)){ Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($side, BlockFactory::get(Block::MELON_BLOCK))); if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($side, $ev->getNewState(), true); + $this->getLevel()->setBlock($side, $ev->getNewState()); } } } diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index eb68dd3e7c..e56dd19c5a 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -85,7 +85,7 @@ class NetherWartPlant extends Flowable{ $this->getLevel()->getServer()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block)); if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($this, $ev->getNewState(), false, true); + $this->getLevel()->setBlock($this, $ev->getNewState()); } } } diff --git a/src/pocketmine/block/PumpkinStem.php b/src/pocketmine/block/PumpkinStem.php index 1c916606b2..13f8f93eca 100644 --- a/src/pocketmine/block/PumpkinStem.php +++ b/src/pocketmine/block/PumpkinStem.php @@ -44,7 +44,7 @@ class PumpkinStem extends Crops{ ++$block->age; Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block)); if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($this, $ev->getNewState(), true); + $this->getLevel()->setBlock($this, $ev->getNewState()); } }else{ foreach(Facing::HORIZONTAL as $side){ @@ -58,7 +58,7 @@ class PumpkinStem extends Crops{ if($side->getId() === self::AIR and ($d->getId() === self::FARMLAND or $d->getId() === self::GRASS or $d->getId() === self::DIRT)){ Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($side, BlockFactory::get(Block::PUMPKIN))); if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($side, $ev->getNewState(), true); + $this->getLevel()->setBlock($side, $ev->getNewState()); } } } diff --git a/src/pocketmine/block/RedstoneOre.php b/src/pocketmine/block/RedstoneOre.php index 495634a3bf..ffcef7ba1b 100644 --- a/src/pocketmine/block/RedstoneOre.php +++ b/src/pocketmine/block/RedstoneOre.php @@ -65,7 +65,7 @@ class RedstoneOre extends Solid{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - return $this->getLevel()->setBlock($this, $this, true, false); + return $this->getLevel()->setBlock($this, $this, false); } public function onActivate(Item $item, Player $player = null) : bool{ diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index 3ec18bf9ff..73e315ab6e 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -85,7 +85,7 @@ class Sapling extends Flowable{ Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->getVariant()); }else{ $this->ready = true; - $this->getLevel()->setBlock($this, $this, true); + $this->getLevel()->setBlock($this, $this); } } } diff --git a/src/pocketmine/block/SignPost.php b/src/pocketmine/block/SignPost.php index b37ec9e842..c55f70662b 100644 --- a/src/pocketmine/block/SignPost.php +++ b/src/pocketmine/block/SignPost.php @@ -79,7 +79,7 @@ class SignPost extends Transparent{ $this->rotation = $player !== null ? ((int) floor((($player->yaw + 180) * 16 / 360) + 0.5)) & 0x0f : 0; $ret = parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); }else{ - $ret = $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::WALL_SIGN, $face), true); + $ret = $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::WALL_SIGN, $face)); } if($ret){ diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index abe6561fc1..5a09e6495e 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -76,11 +76,11 @@ abstract class Slab extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($face === Facing::DOWN){ if($blockClicked instanceof Slab and $blockClicked->getId() === $this->getId() and $blockClicked->top and $blockClicked->getVariant() === $this->variant){ - $this->getLevel()->setBlock($blockClicked, BlockFactory::get($this->getDoubleSlabId(), $this->variant), true); + $this->getLevel()->setBlock($blockClicked, BlockFactory::get($this->getDoubleSlabId(), $this->variant)); return true; }elseif($blockReplace->getId() === $this->getId() and $blockReplace->getVariant() === $this->variant){ - $this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->variant), true); + $this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->variant)); return true; }else{ @@ -88,18 +88,18 @@ abstract class Slab extends Transparent{ } }elseif($face === Facing::UP){ if($blockClicked instanceof Slab and $blockClicked->getId() === $this->getId() and !$blockClicked->top and $blockClicked->getVariant() === $this->variant){ - $this->getLevel()->setBlock($blockClicked, BlockFactory::get($this->getDoubleSlabId(), $this->variant), true); + $this->getLevel()->setBlock($blockClicked, BlockFactory::get($this->getDoubleSlabId(), $this->variant)); return true; }elseif($blockReplace->getId() === $this->getId() and $blockReplace->getVariant() === $this->variant){ - $this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->variant), true); + $this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->variant)); return true; } }else{ //TODO: collision if($blockReplace->getId() === $this->getId()){ if($blockReplace->getVariant() === $this->variant){ - $this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->variant), true); + $this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->variant)); return true; } diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index faa73bab16..03759ef33b 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -84,7 +84,7 @@ class SnowLayer extends Flowable{ public function onNearbyBlockChange() : void{ if(!$this->getSide(Facing::DOWN)->isSolid()){ - $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), false, false); + $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), false); } } @@ -94,7 +94,7 @@ class SnowLayer extends Flowable{ public function onRandomTick() : void{ if($this->level->getBlockLightAt($this->x, $this->y, $this->z) >= 12){ - $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), false, false); + $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), false); } } diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index 5dc4b43daa..e4b3ecc3d9 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -79,7 +79,7 @@ class StandingBanner extends Transparent{ $this->rotation = ((int) floor((($player->yaw + 180) * 16 / 360) + 0.5)) & 0x0f; $ret = parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); }else{ - $ret = $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::WALL_BANNER, $face), true); + $ret = $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::WALL_BANNER, $face)); } if($ret){ diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index 70381022a6..17b6323501 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -67,13 +67,13 @@ class Sugarcane extends Flowable{ if($b->getId() === self::AIR){ Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($b, BlockFactory::get(Block::SUGARCANE_BLOCK))); if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($b, $ev->getNewState(), true); + $this->getLevel()->setBlock($b, $ev->getNewState()); } break; } } $this->age = 0; - $this->getLevel()->setBlock($this, $this, true); + $this->getLevel()->setBlock($this, $this); } $item->count--; @@ -101,15 +101,15 @@ class Sugarcane extends Flowable{ for($y = 1; $y < 3; ++$y){ $b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z); if($b->getId() === self::AIR){ - $this->getLevel()->setBlock($b, BlockFactory::get(Block::SUGARCANE_BLOCK), true); + $this->getLevel()->setBlock($b, BlockFactory::get(Block::SUGARCANE_BLOCK)); break; } } $this->age = 0; - $this->getLevel()->setBlock($this, $this, true); + $this->getLevel()->setBlock($this, $this); }else{ ++$this->age; - $this->getLevel()->setBlock($this, $this, true); + $this->getLevel()->setBlock($this, $this); } } } diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index 2a13c18aff..57038bab3e 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -68,7 +68,7 @@ class TNT extends Solid{ } public function ignite(int $fuse = 80){ - $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true); + $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR)); $mot = (new Random())->nextSignedFloat() * M_PI * 2; $nbt = Entity::createBaseNBT($this->add(0.5, 0, 0.5), new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02)); diff --git a/src/pocketmine/block/TallGrass.php b/src/pocketmine/block/TallGrass.php index f439a22040..0eab87c62d 100644 --- a/src/pocketmine/block/TallGrass.php +++ b/src/pocketmine/block/TallGrass.php @@ -46,7 +46,7 @@ class TallGrass extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ //Replace with common break method - $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true, true); + $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR)); } } diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index 641f82e960..ba056ac7c8 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -114,7 +114,7 @@ class Trapdoor extends Transparent{ public function onActivate(Item $item, Player $player = null) : bool{ $this->open = !$this->open; - $this->level->setBlock($this, $this, true); + $this->level->setBlock($this, $this); $this->level->addSound(new DoorSound($this)); return true; } diff --git a/src/pocketmine/entity/object/FallingBlock.php b/src/pocketmine/entity/object/FallingBlock.php index eb023b77c9..9dc7b3e9e8 100644 --- a/src/pocketmine/entity/object/FallingBlock.php +++ b/src/pocketmine/entity/object/FallingBlock.php @@ -115,7 +115,7 @@ class FallingBlock extends Entity{ }else{ $this->server->getPluginManager()->callEvent($ev = new EntityBlockChangeEvent($this, $block, $blockTarget ?? $this->block)); if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($pos, $ev->getTo(), true); + $this->getLevel()->setBlock($pos, $ev->getTo()); } } $hasUpdate = true; diff --git a/src/pocketmine/item/Bucket.php b/src/pocketmine/item/Bucket.php index 133ccbb370..b7731ea1a2 100644 --- a/src/pocketmine/item/Bucket.php +++ b/src/pocketmine/item/Bucket.php @@ -61,7 +61,7 @@ class Bucket extends Item implements Consumable{ $resultItem = ItemFactory::get(Item::BUCKET, $blockClicked->getFlowingForm()->getId()); $player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketFillEvent($player, $blockReplace, $face, $this, $resultItem)); if(!$ev->isCancelled()){ - $player->getLevel()->setBlock($blockClicked, BlockFactory::get(Block::AIR), true, true); + $player->getLevel()->setBlock($blockClicked, BlockFactory::get(Block::AIR)); $player->getLevel()->broadcastLevelSoundEvent($blockClicked->add(0.5, 0.5, 0.5), $blockClicked->getBucketFillSound()); if($player->isSurvival()){ if($stack->getCount() === 0){ @@ -82,7 +82,7 @@ class Bucket extends Item implements Consumable{ }elseif($resultBlock instanceof Liquid and $blockReplace->canBeReplaced()){ $player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketEmptyEvent($player, $blockReplace, $face, $this, ItemFactory::get(Item::BUCKET))); if(!$ev->isCancelled()){ - $player->getLevel()->setBlock($blockReplace, $resultBlock->getFlowingForm(), true, true); + $player->getLevel()->setBlock($blockReplace, $resultBlock->getFlowingForm()); $player->getLevel()->broadcastLevelSoundEvent($blockClicked->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound()); if($player->isSurvival()){ diff --git a/src/pocketmine/item/FlintSteel.php b/src/pocketmine/item/FlintSteel.php index 94b0098d7d..ac9cb1456e 100644 --- a/src/pocketmine/item/FlintSteel.php +++ b/src/pocketmine/item/FlintSteel.php @@ -38,7 +38,7 @@ class FlintSteel extends Tool{ if($blockReplace->getId() === self::AIR){ $level = $player->getLevel(); assert($level !== null); - $level->setBlock($blockReplace, BlockFactory::get(Block::FIRE), true); + $level->setBlock($blockReplace, BlockFactory::get(Block::FIRE)); $level->broadcastLevelSoundEvent($blockReplace->add(0.5, 0.5, 0.5), LevelSoundEventPacket::SOUND_IGNITE); $this->applyDamage(1); diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 13cbbb65a2..9209100dc4 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1475,21 +1475,16 @@ class Level implements ChunkManager, Metadatable{ * Sets on Vector3 the data from a Block object, * does block updates and puts the changes to the send queue. * - * If $direct is true, it'll send changes directly to players. if false, it'll be queued - * and the best way to send queued changes will be done in the next tick. - * This way big changes can be sent on a single chunk update packet instead of thousands of packets. - * * If $update is true, it'll get the neighbour blocks (6 sides) and update them. * If you are doing big changes, you might want to set this to false, then update manually. * * @param Vector3 $pos * @param Block $block - * @param bool $direct @deprecated * @param bool $update * * @return bool Whether the block has been updated or not */ - public function setBlock(Vector3 $pos, Block $block, bool $direct = false, bool $update = true) : bool{ + public function setBlock(Vector3 $pos, Block $block, bool $update = true) : bool{ $pos = $pos->floor(); if(!$this->isInWorld($pos->x, $pos->y, $pos->z)){ return false; @@ -1512,16 +1507,10 @@ class Level implements ChunkManager, Metadatable{ unset($this->blockCache[$chunkHash][$blockHash]); - if($direct){ - $this->sendBlocks($this->getChunkPlayers($pos->x >> 4, $pos->z >> 4), [$block]); - unset($this->chunkCache[$chunkHash], $this->changedBlocks[$chunkHash][$blockHash]); - }else{ - if(!isset($this->changedBlocks[$chunkHash])){ - $this->changedBlocks[$chunkHash] = []; - } - - $this->changedBlocks[$chunkHash][$blockHash] = $block; + if(!isset($this->changedBlocks[$chunkHash])){ + $this->changedBlocks[$chunkHash] = []; } + $this->changedBlocks[$chunkHash][$blockHash] = $block; foreach($this->getChunkLoaders($pos->x >> 4, $pos->z >> 4) as $loader){ $loader->onBlockChanged($block); diff --git a/src/pocketmine/tile/Furnace.php b/src/pocketmine/tile/Furnace.php index 2e4dbe79e7..48369108e3 100644 --- a/src/pocketmine/tile/Furnace.php +++ b/src/pocketmine/tile/Furnace.php @@ -146,7 +146,7 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ $block = $this->getBlock(); if($block instanceof BlockFurnace and !$block->isLit()){ $block->setLit(true); - $this->getLevel()->setBlock($block, $block, true); + $this->getLevel()->setBlock($block, $block); } if($this->burnTime > 0 and $ev->isBurning()){ @@ -210,7 +210,7 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ $block = $this->getBlock(); if($block instanceof BlockFurnace and $block->isLit()){ $block->setLit(false); - $this->getLevel()->setBlock($block, $block, true); + $this->getLevel()->setBlock($block, $block); } $this->burnTime = $this->cookTime = $this->maxTime = 0; } From 0b49ec46c612a9f37763aa206cc0cfbd43953cfb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Sep 2018 16:24:35 +0100 Subject: [PATCH 0182/3224] Deduplicate Pumpkin/Melon stem code --- src/pocketmine/block/MelonStem.php | 46 ++---------------- src/pocketmine/block/PumpkinStem.php | 46 ++---------------- src/pocketmine/block/Stem.php | 71 ++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 82 deletions(-) create mode 100644 src/pocketmine/block/Stem.php diff --git a/src/pocketmine/block/MelonStem.php b/src/pocketmine/block/MelonStem.php index 553230a3ef..49646981d3 100644 --- a/src/pocketmine/block/MelonStem.php +++ b/src/pocketmine/block/MelonStem.php @@ -23,55 +23,19 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; -use pocketmine\math\Facing; -use pocketmine\Server; -class MelonStem extends Crops{ +class MelonStem extends Stem{ protected $id = self::MELON_STEM; + protected $itemId = Item::MELON_SEEDS; + public function getName() : string{ return "Melon Stem"; } - public function onRandomTick() : void{ - if(mt_rand(0, 2) === 1){ - if($this->age < 7){ - $block = clone $this; - ++$block->age; - Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block)); - if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($this, $ev->getNewState()); - } - }else{ - foreach(Facing::HORIZONTAL as $side){ - $b = $this->getSide($side); - if($b->getId() === self::MELON_BLOCK){ - return; - } - } - $side = $this->getSide(Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)]); - $d = $side->getSide(Facing::DOWN); - if($side->getId() === self::AIR and ($d->getId() === self::FARMLAND or $d->getId() === self::GRASS or $d->getId() === self::DIRT)){ - Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($side, BlockFactory::get(Block::MELON_BLOCK))); - if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($side, $ev->getNewState()); - } - } - } - } - } - - public function getDropsForCompatibleTool(Item $item) : array{ - return [ - ItemFactory::get(Item::MELON_SEEDS, 0, mt_rand(0, 2)) - ]; - } - - public function getPickedItem() : Item{ - return ItemFactory::get(Item::MELON_SEEDS); + protected function getPlant() : Block{ + return BlockFactory::get(Block::MELON_BLOCK); } } diff --git a/src/pocketmine/block/PumpkinStem.php b/src/pocketmine/block/PumpkinStem.php index 13f8f93eca..fa13fcc410 100644 --- a/src/pocketmine/block/PumpkinStem.php +++ b/src/pocketmine/block/PumpkinStem.php @@ -23,55 +23,19 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; -use pocketmine\math\Facing; -use pocketmine\Server; -class PumpkinStem extends Crops{ +class PumpkinStem extends Stem{ protected $id = self::PUMPKIN_STEM; + protected $itemId = Item::PUMPKIN_SEEDS; + public function getName() : string{ return "Pumpkin Stem"; } - public function onRandomTick() : void{ - if(mt_rand(0, 2) === 1){ - if($this->age < 7){ - $block = clone $this; - ++$block->age; - Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block)); - if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($this, $ev->getNewState()); - } - }else{ - foreach(Facing::HORIZONTAL as $side){ - $b = $this->getSide($side); - if($b->getId() === self::PUMPKIN){ - return; - } - } - $side = $this->getSide(Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)]); - $d = $side->getSide(Facing::DOWN); - if($side->getId() === self::AIR and ($d->getId() === self::FARMLAND or $d->getId() === self::GRASS or $d->getId() === self::DIRT)){ - Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($side, BlockFactory::get(Block::PUMPKIN))); - if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($side, $ev->getNewState()); - } - } - } - } - } - - public function getDropsForCompatibleTool(Item $item) : array{ - return [ - ItemFactory::get(Item::PUMPKIN_SEEDS, 0, mt_rand(0, 2)) - ]; - } - - public function getPickedItem() : Item{ - return ItemFactory::get(Item::PUMPKIN_SEEDS); + protected function getPlant() : Block{ + return BlockFactory::get(Block::PUMPKIN); } } diff --git a/src/pocketmine/block/Stem.php b/src/pocketmine/block/Stem.php new file mode 100644 index 0000000000..9d105380fe --- /dev/null +++ b/src/pocketmine/block/Stem.php @@ -0,0 +1,71 @@ +age < 7){ + $block = clone $this; + ++$block->age; + Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block)); + if(!$ev->isCancelled()){ + $this->getLevel()->setBlock($this, $ev->getNewState()); + } + }else{ + $grow = $this->getPlant(); + foreach(Facing::HORIZONTAL as $side){ + $b = $this->getSide($side); + if($b->getId() === $grow->getId()){ + return; + } + } + + $side = $this->getSide(Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)]); + $d = $side->getSide(Facing::DOWN); + if($side->getId() === self::AIR and ($d->getId() === self::FARMLAND or $d->getId() === self::GRASS or $d->getId() === self::DIRT)){ + Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($side, $grow)); + if(!$ev->isCancelled()){ + $this->getLevel()->setBlock($side, $ev->getNewState()); + } + } + } + } + } + + public function getDropsForCompatibleTool(Item $item) : array{ + return [ + ItemFactory::get($this->getItemId(), 0, mt_rand(0, 2)) + ]; + } +} From 8910c93de1b4978ac09dc6e28ca587a9a9ece37c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Sep 2018 16:45:06 +0100 Subject: [PATCH 0183/3224] Slab: slight reduction of code repetition --- src/pocketmine/block/Slab.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index 5a09e6495e..8c52eb20dc 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -57,6 +57,10 @@ abstract class Slab extends Transparent{ return $this->doubleId; } + protected function getDouble() : Block{ + return BlockFactory::get($this->doubleId, $this->variant); + } + public function canBePlacedAt(Block $blockReplace, Vector3 $clickVector, int $face, bool $isClickedBlock) : bool{ if(parent::canBePlacedAt($blockReplace, $clickVector, $face, $isClickedBlock)){ return true; @@ -76,11 +80,11 @@ abstract class Slab extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($face === Facing::DOWN){ if($blockClicked instanceof Slab and $blockClicked->getId() === $this->getId() and $blockClicked->top and $blockClicked->getVariant() === $this->variant){ - $this->getLevel()->setBlock($blockClicked, BlockFactory::get($this->getDoubleSlabId(), $this->variant)); + $this->getLevel()->setBlock($blockClicked, $this->getDouble()); return true; }elseif($blockReplace->getId() === $this->getId() and $blockReplace->getVariant() === $this->variant){ - $this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->variant)); + $this->getLevel()->setBlock($blockReplace, $this->getDouble()); return true; }else{ @@ -88,18 +92,18 @@ abstract class Slab extends Transparent{ } }elseif($face === Facing::UP){ if($blockClicked instanceof Slab and $blockClicked->getId() === $this->getId() and !$blockClicked->top and $blockClicked->getVariant() === $this->variant){ - $this->getLevel()->setBlock($blockClicked, BlockFactory::get($this->getDoubleSlabId(), $this->variant)); + $this->getLevel()->setBlock($blockClicked, $this->getDouble()); return true; }elseif($blockReplace->getId() === $this->getId() and $blockReplace->getVariant() === $this->variant){ - $this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->variant)); + $this->getLevel()->setBlock($blockReplace, $this->getDouble()); return true; } }else{ //TODO: collision if($blockReplace->getId() === $this->getId()){ if($blockReplace->getVariant() === $this->variant){ - $this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->variant)); + $this->getLevel()->setBlock($blockReplace, $this->getDouble()); return true; } From 35d51570becbae4b5d707d102724fe34be6c82d1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Sep 2018 17:59:06 +0100 Subject: [PATCH 0184/3224] Add and make use of Block->isSameType() --- src/pocketmine/block/Block.php | 11 +++++++++++ src/pocketmine/block/Chest.php | 2 +- src/pocketmine/block/Door.php | 8 ++++---- src/pocketmine/block/DoublePlant.php | 3 +-- src/pocketmine/block/Liquid.php | 4 ++-- src/pocketmine/block/Slab.php | 10 +++++----- src/pocketmine/block/Stem.php | 3 +-- src/pocketmine/level/Level.php | 4 ++-- 8 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 60c2920450..75167523e8 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -166,6 +166,17 @@ class Block extends Position implements BlockIds, Metadatable{ return $this->variant; } + /** + * Returns whether the given block has an equivalent type to this one. + * + * @param Block $other + * + * @return bool + */ + public function isSameType(Block $other) : bool{ + return $this->getId() === $other->getId() and $this->getVariant() === $other->getVariant(); + } + /** * AKA: Block->isPlaceable * @return bool diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index a4ccd0522f..323f9f5445 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -83,7 +83,7 @@ class Chest extends Transparent{ Bearing::toFacing(Bearing::rotate($player->getDirection(), 1)) ] as $side){ $c = $this->getSide($side); - if($c instanceof Chest and $c->getId() === $this->getId() and $c->facing === $this->facing){ + if($c instanceof Chest and $c->isSameType($this) and $c->facing === $this->facing){ $tile = $this->getLevel()->getTile($c); if($tile instanceof TileChest and !$tile->isPaired()){ $chest = $tile; diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 1d081680fa..68456e4e45 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -75,7 +75,7 @@ abstract class Door extends Transparent{ */ private function updateStateFromOtherHalf() : void{ $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); - if($other instanceof Door and $other->getId() === $this->getId()){ + if($other instanceof Door and $other->isSameType($this)){ if($this->top){ $this->facing = $other->facing; $this->open = $other->open; @@ -165,7 +165,7 @@ abstract class Door extends Transparent{ $next = $this->getSide(Facing::rotate($this->facing, Facing::AXIS_Y, false)); $next2 = $this->getSide(Facing::rotate($this->facing, Facing::AXIS_Y, true)); - if($next->getId() === $this->getId() or (!$next2->isTransparent() and $next->isTransparent())){ //Door hinge + if($next->isSameType($this) or (!$next2->isTransparent() and $next->isTransparent())){ //Door hinge $this->hingeRight = true; } @@ -185,7 +185,7 @@ abstract class Door extends Transparent{ $this->open = !$this->open; $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); - if($other instanceof Door and $this->getId() === $other->getId()){ + if($other instanceof Door and $other->isSameType($this)){ $other->open = $this->open; $this->level->setBlock($other, $other); } @@ -210,7 +210,7 @@ abstract class Door extends Transparent{ public function getAffectedBlocks() : array{ $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); - if($other->getId() === $this->getId()){ + if($other->isSameType($this)){ return [$this, $other]; } return parent::getAffectedBlocks(); diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index caecc5c0a2..fb4266c174 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -74,8 +74,7 @@ class DoublePlant extends Flowable{ return ( $other instanceof DoublePlant and - $other->getId() === $this->getId() and - $other->getVariant() === $this->variant and + $other->isSameType($this) and $other->top !== $this->top ); } diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index ff8d20587a..caa43e6925 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -111,7 +111,7 @@ abstract class Liquid extends Transparent{ } protected function getEffectiveFlowDecay(Block $block) : int{ - if(!($block instanceof Liquid) or $block->getId() !== $this->getId()){ + if(!($block instanceof Liquid) or !$block->isSameType($this)){ return -1; } @@ -410,7 +410,7 @@ abstract class Liquid extends Transparent{ } private function getSmallestFlowDecay(Block $block, int $decay) : int{ - if(!($block instanceof Liquid) or $block->getId() !== $this->getId()){ + if(!($block instanceof Liquid) or !$block->isSameType($this)){ return $decay; } diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index 8c52eb20dc..f138d1c972 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -66,7 +66,7 @@ abstract class Slab extends Transparent{ return true; } - if($blockReplace instanceof Slab and $blockReplace->getId() === $this->getId() and $blockReplace->getVariant() === $this->variant){ + if($blockReplace instanceof Slab and $blockReplace->isSameType($this)){ if($blockReplace->top){ //Trying to combine with top slab return $clickVector->y <= 0.5 or (!$isClickedBlock and $face === Facing::UP); }else{ @@ -79,11 +79,11 @@ abstract class Slab extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($face === Facing::DOWN){ - if($blockClicked instanceof Slab and $blockClicked->getId() === $this->getId() and $blockClicked->top and $blockClicked->getVariant() === $this->variant){ + if($blockClicked instanceof Slab and $blockClicked->isSameType($this) and $blockClicked->top){ $this->getLevel()->setBlock($blockClicked, $this->getDouble()); return true; - }elseif($blockReplace->getId() === $this->getId() and $blockReplace->getVariant() === $this->variant){ + }elseif($blockReplace->isSameType($this)){ $this->getLevel()->setBlock($blockReplace, $this->getDouble()); return true; @@ -91,11 +91,11 @@ abstract class Slab extends Transparent{ $this->top = true; } }elseif($face === Facing::UP){ - if($blockClicked instanceof Slab and $blockClicked->getId() === $this->getId() and !$blockClicked->top and $blockClicked->getVariant() === $this->variant){ + if($blockClicked instanceof Slab and $blockClicked->isSameType($this) and !$blockClicked->top){ $this->getLevel()->setBlock($blockClicked, $this->getDouble()); return true; - }elseif($blockReplace->getId() === $this->getId() and $blockReplace->getVariant() === $this->variant){ + }elseif($blockReplace->isSameType($this)){ $this->getLevel()->setBlock($blockReplace, $this->getDouble()); return true; diff --git a/src/pocketmine/block/Stem.php b/src/pocketmine/block/Stem.php index 9d105380fe..2722e6c834 100644 --- a/src/pocketmine/block/Stem.php +++ b/src/pocketmine/block/Stem.php @@ -45,8 +45,7 @@ abstract class Stem extends Crops{ }else{ $grow = $this->getPlant(); foreach(Facing::HORIZONTAL as $side){ - $b = $this->getSide($side); - if($b->getId() === $grow->getId()){ + if($this->getSide($side)->isSameType($grow)){ return; } } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 9209100dc4..2ab1cc9a63 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1671,7 +1671,7 @@ class Level implements ChunkManager, Metadatable{ foreach($tag as $v){ if($v instanceof StringTag){ $entry = ItemFactory::fromString($v->getValue()); - if($entry->getId() > 0 and $entry->getBlock()->getId() === $target->getId()){ + if($entry->getId() > 0 and $entry->getBlock()->isSameType($target)){ $canBreak = true; break; } @@ -1833,7 +1833,7 @@ class Level implements ChunkManager, Metadatable{ foreach($tag as $v){ if($v instanceof StringTag){ $entry = ItemFactory::fromString($v->getValue()); - if($entry->getId() > 0 and $entry->getBlock()->getId() === $blockClicked->getId()){ + if($entry->getId() > 0 and $entry->getBlock()->isSameType($blockClicked)){ $canPlace = true; break; } From e038c4295d50c31883066e886c03187684247eff Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Sep 2018 18:46:01 +0100 Subject: [PATCH 0185/3224] Clean up abhorrent mess of Slab placement code --- src/pocketmine/block/Slab.php | 51 ++++++++++------------------------- 1 file changed, 14 insertions(+), 37 deletions(-) diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index f138d1c972..d6b8fb63fa 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -78,48 +78,25 @@ abstract class Slab extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if($face === Facing::DOWN){ - if($blockClicked instanceof Slab and $blockClicked->isSameType($this) and $blockClicked->top){ - $this->getLevel()->setBlock($blockClicked, $this->getDouble()); + /* note these conditions can't be merged, since one targets clicked and the other replace */ - return true; - }elseif($blockReplace->isSameType($this)){ - $this->getLevel()->setBlock($blockReplace, $this->getDouble()); - - return true; - }else{ - $this->top = true; - } - }elseif($face === Facing::UP){ - if($blockClicked instanceof Slab and $blockClicked->isSameType($this) and !$blockClicked->top){ - $this->getLevel()->setBlock($blockClicked, $this->getDouble()); - - return true; - }elseif($blockReplace->isSameType($this)){ - $this->getLevel()->setBlock($blockReplace, $this->getDouble()); - - return true; - } - }else{ //TODO: collision - if($blockReplace->getId() === $this->getId()){ - if($blockReplace->getVariant() === $this->variant){ - $this->getLevel()->setBlock($blockReplace, $this->getDouble()); - - return true; - } - - return false; - }else{ - if($clickVector->y > 0.5){ - $this->top = true; - } - } + if($blockClicked instanceof Slab and $blockClicked->isSameType($this) and ( + ($face === Facing::DOWN and $blockClicked->top) or //Bottom face of top slab + ($face === Facing::UP and !$blockClicked->top) //Top face of bottom slab + )){ + return $this->level->setBlock($blockClicked, $this->getDouble()); } - if($blockReplace->getId() === $this->getId() and $blockClicked->getVariant() !== $this->variant){ - return false; + if($blockReplace instanceof Slab and $blockReplace->isSameType($this) and ( + ($blockReplace->top and $clickVector->y <= 0.5) or + (!$blockReplace->top and $clickVector->y >= 0.5) + )){ + //Clicked in empty half of existing slab + return $this->level->setBlock($blockReplace, $this->getDouble()); } + $this->top = ($face !== Facing::UP && $clickVector->y > 0.5) || $face === Facing::DOWN; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } From 2600cf5977487ee7622590faf165737ecb8da1fe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 28 Sep 2018 16:21:03 +0100 Subject: [PATCH 0186/3224] Split some block variants into their own classes where behaviour differs --- src/pocketmine/block/BlockFactory.php | 49 ++++++++++-------- src/pocketmine/block/BoneBlock.php | 9 ---- src/pocketmine/block/CoarseDirt.php | 41 +++++++++++++++ src/pocketmine/block/Dirt.php | 6 +-- src/pocketmine/block/DoublePlant.php | 26 +--------- src/pocketmine/block/DoubleTallGrass.php | 51 +++++++++++++++++++ src/pocketmine/block/HayBale.php | 9 ---- src/pocketmine/block/Purpur.php | 16 +++++- src/pocketmine/block/Quartz.php | 17 ++----- src/pocketmine/block/SmoothStone.php | 36 +++++++++++++ src/pocketmine/block/Stone.php | 10 ---- src/pocketmine/block/Wood.php | 9 ---- .../block/utils/PillarRotationTrait.php | 21 ++++++++ src/pocketmine/level/Level.php | 2 +- 14 files changed, 200 insertions(+), 102 deletions(-) create mode 100644 src/pocketmine/block/CoarseDirt.php create mode 100644 src/pocketmine/block/DoubleTallGrass.php create mode 100644 src/pocketmine/block/SmoothStone.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 7fc4af2aef..b105d4315c 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\Color; +use pocketmine\block\utils\PillarRotationTrait; use pocketmine\block\utils\WoodType; use pocketmine\item\Item; use pocketmine\level\Position; @@ -45,7 +46,7 @@ class BlockFactory{ public static $blastResistance = null; /** @var \SplFixedArray|int[] */ - public static $stateMasks = null; + private static $stateMasks = null; /** @var int[] */ public static $staticRuntimeIdMap = []; @@ -68,12 +69,12 @@ class BlockFactory{ self::$diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 512, false)); self::$blastResistance = \SplFixedArray::fromArray(array_fill(0, 512, 0)); - self::$stateMasks = \SplFixedArray::fromArray(array_fill(0, 512, 0)); + self::$stateMasks = new \SplFixedArray(512); self::registerBlock(new Air()); - //TODO: give smooth stone its own class (different drops) - self::registerBlock(new Stone(Block::STONE, Stone::NORMAL, "Stone")); + self::registerBlock(new SmoothStone(Block::STONE, Stone::NORMAL, "Stone")); + self::registerBlock(new Stone(Block::STONE, Stone::GRANITE, "Granite")); self::registerBlock(new Stone(Block::STONE, Stone::POLISHED_GRANITE, "Polished Granite")); self::registerBlock(new Stone(Block::STONE, Stone::DIORITE, "Diorite")); @@ -83,9 +84,8 @@ class BlockFactory{ self::registerBlock(new Grass()); - //TODO: split these into separate classes self::registerBlock(new Dirt(Block::DIRT, Dirt::NORMAL, "Dirt")); - self::registerBlock(new Dirt(Block::DIRT, Dirt::COARSE, "Coarse Dirt")); + self::registerBlock(new CoarseDirt(Block::DIRT, Dirt::COARSE, "Coarse Dirt")); self::registerBlock(new Cobblestone()); @@ -355,11 +355,17 @@ class BlockFactory{ //TODO: HOPPER_BLOCK self::registerBlock(new Quartz(Block::QUARTZ_BLOCK, Quartz::NORMAL, "Quartz Block")); - self::registerBlock(new Quartz(Block::QUARTZ_BLOCK, Quartz::CHISELED, "Chiseled Quartz Block")); - self::registerBlock(new Quartz(Block::QUARTZ_BLOCK, Quartz::PILLAR, "Quartz Pillar")); + self::registerBlock(new class(Block::QUARTZ_BLOCK, Quartz::CHISELED, "Chiseled Quartz Block") extends Quartz{ + use PillarRotationTrait; + }); + self::registerBlock(new class(Block::QUARTZ_BLOCK, Quartz::PILLAR, "Quartz Pillar") extends Quartz{ + use PillarRotationTrait; + }); - self::registerBlock(new Purpur(Block::PURPUR_BLOCK, Purpur::NORMAL, "Purpur Block")); - self::registerBlock(new Purpur(Block::PURPUR_BLOCK, Purpur::PILLAR, "Purpur Pillar")); + self::registerBlock(new Purpur(Block::PURPUR_BLOCK, 0, "Purpur Block")); + self::registerBlock(new class(Block::PURPUR_BLOCK, 2, "Purpur Pillar") extends Purpur{ + use PillarRotationTrait; + }); self::registerBlock(new QuartzStairs()); @@ -382,9 +388,8 @@ class BlockFactory{ self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 0, "Sunflower")); self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 1, "Lilac")); - //TODO: double tallgrass and large fern have different behaviour than the others, so they should get their own classes - self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 2, "Double Tallgrass")); - self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 3, "Large Fern")); + self::registerBlock(new DoubleTallGrass(Block::DOUBLE_PLANT, 2, "Double Tallgrass")); + self::registerBlock(new DoubleTallGrass(Block::DOUBLE_PLANT, 3, "Large Fern")); self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 4, "Rose Bush")); self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 5, "Peony")); @@ -478,6 +483,10 @@ class BlockFactory{ throw new \RuntimeException("Trying to overwrite an already registered block"); } + if(self::$stateMasks[$id] !== null and self::$stateMasks[$id] !== $block->getStateBitmask()){ + throw new \InvalidArgumentException("Blocks with the same ID must have the same state bitmask"); + } + self::$fullList[($id << 4) | $variant] = clone $block; if($variant === 0){ //TODO: allow these to differ for different variants @@ -499,13 +508,9 @@ class BlockFactory{ throw new \InvalidArgumentException("Block meta value $meta is out of bounds"); } - if(self::$stateMasks[$id] === null){ - $variant = 0; - $state = $meta; - }else{ - $variant = $meta & ~self::$stateMasks[$id]; - $state = $meta & self::$stateMasks[$id]; - } + $stateMask = self::getStateMask($id); + $variant = $meta & ~$stateMask; + $state = $meta & $stateMask; $index = ($id << 4) | $variant; @@ -553,6 +558,10 @@ class BlockFactory{ self::$stateMasks[$id] = $block->getStateBitmask(); } + public static function getStateMask(int $id) : int{ + return self::$stateMasks[$id] ?? 0; + } + /** * Returns whether a specified block ID is already registered in the block factory. * diff --git a/src/pocketmine/block/BoneBlock.php b/src/pocketmine/block/BoneBlock.php index f632cfcc23..b8a183a1c5 100644 --- a/src/pocketmine/block/BoneBlock.php +++ b/src/pocketmine/block/BoneBlock.php @@ -24,11 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\PillarRotationTrait; -use pocketmine\item\Item; use pocketmine\item\TieredTool; -use pocketmine\math\Facing; -use pocketmine\math\Vector3; -use pocketmine\Player; class BoneBlock extends Solid{ use PillarRotationTrait; @@ -54,9 +50,4 @@ class BoneBlock extends Solid{ public function getToolHarvestLevel() : int{ return TieredTool::TIER_WOODEN; } - - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $this->axis = Facing::axis($face); - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); - } } diff --git a/src/pocketmine/block/CoarseDirt.php b/src/pocketmine/block/CoarseDirt.php new file mode 100644 index 0000000000..2f3a3eb253 --- /dev/null +++ b/src/pocketmine/block/CoarseDirt.php @@ -0,0 +1,41 @@ +applyDamage(1); + $this->getLevel()->setBlock($this, BlockFactory::get(Block::DIRT)); + return true; + } + + return false; + } +} diff --git a/src/pocketmine/block/Dirt.php b/src/pocketmine/block/Dirt.php index 2bc32e343c..e810b0ab58 100644 --- a/src/pocketmine/block/Dirt.php +++ b/src/pocketmine/block/Dirt.php @@ -42,11 +42,7 @@ class Dirt extends Solid{ public function onActivate(Item $item, Player $player = null) : bool{ if($item instanceof Hoe){ $item->applyDamage(1); - if($this->variant === self::COARSE){ - $this->getLevel()->setBlock($this, BlockFactory::get(Block::DIRT)); - }else{ - $this->getLevel()->setBlock($this, BlockFactory::get(Block::FARMLAND)); - } + $this->getLevel()->setBlock($this, BlockFactory::get(Block::FARMLAND)); return true; } diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index fb4266c174..f9ab9bf4e2 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -47,10 +47,6 @@ class DoublePlant extends Flowable{ return 0b1000; } - public function canBeReplaced() : bool{ - return $this->variant === 2 or $this->variant === 3; //grass or fern - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $id = $blockReplace->getSide(Facing::DOWN)->getId(); if(($id === Block::GRASS or $id === Block::DIRT) and $blockReplace->getSide(Facing::UP)->canBeReplaced()){ @@ -85,28 +81,8 @@ class DoublePlant extends Flowable{ } } - public function getToolType() : int{ - return ($this->variant === 2 or $this->variant === 3) ? BlockToolType::TYPE_SHEARS : BlockToolType::TYPE_NONE; - } - - public function getToolHarvestLevel() : int{ - return ($this->variant === 2 or $this->variant === 3) ? 1 : 0; //only grass or fern require shears - } - public function getDrops(Item $item) : array{ - if($this->top){ - if($this->isCompatibleWithTool($item)){ - return parent::getDrops($item); - } - - if(mt_rand(0, 24) === 0){ - return [ - ItemFactory::get(Item::SEEDS) - ]; - } - } - - return []; + return $this->top ? parent::getDrops($item) : []; } public function getAffectedBlocks() : array{ diff --git a/src/pocketmine/block/DoubleTallGrass.php b/src/pocketmine/block/DoubleTallGrass.php new file mode 100644 index 0000000000..374d8136a5 --- /dev/null +++ b/src/pocketmine/block/DoubleTallGrass.php @@ -0,0 +1,51 @@ +top and !$this->isCompatibleWithTool($item) and mt_rand(0, 7) === 0){ + return [ + ItemFactory::get(Item::SEEDS) + ]; + } + return parent::getDrops($item); + } +} diff --git a/src/pocketmine/block/HayBale.php b/src/pocketmine/block/HayBale.php index e39f200030..e1bb4e19b9 100644 --- a/src/pocketmine/block/HayBale.php +++ b/src/pocketmine/block/HayBale.php @@ -24,10 +24,6 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\PillarRotationTrait; -use pocketmine\item\Item; -use pocketmine\math\Facing; -use pocketmine\math\Vector3; -use pocketmine\Player; class HayBale extends Solid{ use PillarRotationTrait; @@ -46,11 +42,6 @@ class HayBale extends Solid{ return 0.5; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $this->axis = Facing::axis($face); - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); - } - public function getFlameEncouragement() : int{ return 60; } diff --git a/src/pocketmine/block/Purpur.php b/src/pocketmine/block/Purpur.php index a2e3c49f6b..5c6687aed4 100644 --- a/src/pocketmine/block/Purpur.php +++ b/src/pocketmine/block/Purpur.php @@ -23,7 +23,17 @@ declare(strict_types=1); namespace pocketmine\block; -class Purpur extends Quartz{ +use pocketmine\item\TieredTool; + +class Purpur extends Solid{ + + public function getToolType() : int{ + return BlockToolType::TYPE_PICKAXE; + } + + public function getToolHarvestLevel() : int{ + return TieredTool::TIER_WOODEN; + } public function getHardness() : float{ return 1.5; @@ -32,4 +42,8 @@ class Purpur extends Quartz{ public function getBlastResistance() : float{ return 30; } + + public function getStateBitmask() : int{ + return 0b1100; //HACK: needs to be consistent for blocks with the same ID :( + } } diff --git a/src/pocketmine/block/Quartz.php b/src/pocketmine/block/Quartz.php index eb66aaff9c..7c5e3c4e58 100644 --- a/src/pocketmine/block/Quartz.php +++ b/src/pocketmine/block/Quartz.php @@ -23,15 +23,9 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\PillarRotationTrait; -use pocketmine\item\Item; use pocketmine\item\TieredTool; -use pocketmine\math\Facing; -use pocketmine\math\Vector3; -use pocketmine\Player; class Quartz extends Solid{ - use PillarRotationTrait; public const NORMAL = 0; public const CHISELED = 1; @@ -41,13 +35,6 @@ class Quartz extends Solid{ return 0.8; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if($this->variant !== self::NORMAL){ - $this->axis = Facing::axis($face); - } - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } @@ -55,4 +42,8 @@ class Quartz extends Solid{ public function getToolHarvestLevel() : int{ return TieredTool::TIER_WOODEN; } + + public function getStateBitmask() : int{ + return 0b1100; //HACK: needs to be consistent for blocks with the same ID :( + } } diff --git a/src/pocketmine/block/SmoothStone.php b/src/pocketmine/block/SmoothStone.php new file mode 100644 index 0000000000..764ee79a9e --- /dev/null +++ b/src/pocketmine/block/SmoothStone.php @@ -0,0 +1,36 @@ +variant === self::NORMAL){ - return [ - ItemFactory::get(Item::COBBLESTONE) - ]; - } - - return parent::getDropsForCompatibleTool($item); - } } diff --git a/src/pocketmine/block/Wood.php b/src/pocketmine/block/Wood.php index 9f66ef3183..43e0eec294 100644 --- a/src/pocketmine/block/Wood.php +++ b/src/pocketmine/block/Wood.php @@ -24,10 +24,6 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\PillarRotationTrait; -use pocketmine\item\Item; -use pocketmine\math\Facing; -use pocketmine\math\Vector3; -use pocketmine\Player; class Wood extends Solid{ use PillarRotationTrait; @@ -41,11 +37,6 @@ class Wood extends Solid{ return 2; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $this->axis = Facing::axis($face); - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); - } - public function getToolType() : int{ return BlockToolType::TYPE_AXE; } diff --git a/src/pocketmine/block/utils/PillarRotationTrait.php b/src/pocketmine/block/utils/PillarRotationTrait.php index a7531e77f5..156fae1ee8 100644 --- a/src/pocketmine/block/utils/PillarRotationTrait.php +++ b/src/pocketmine/block/utils/PillarRotationTrait.php @@ -24,7 +24,10 @@ declare(strict_types=1); namespace pocketmine\block\utils; use pocketmine\block\Block; +use pocketmine\item\Item; use pocketmine\math\Facing; +use pocketmine\math\Vector3; +use pocketmine\Player; trait PillarRotationTrait{ @@ -73,4 +76,22 @@ trait PillarRotationTrait{ ]; return $bits[$this->axis] << 2; } + + /** + * @see Block::place() + * + * @param Item $item + * @param Block $blockReplace + * @param Block $blockClicked + * @param int $face + * @param Vector3 $clickVector + * @param Player|null $player + * + * @return bool + */ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + $this->axis = Facing::axis($face); + /** @see Block::place() */ + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 2ab1cc9a63..cf05d19710 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -986,7 +986,7 @@ class Level implements ChunkManager, Metadatable{ $blockId = $subChunk->getBlockId($x, $y, $z); $meta = $subChunk->getBlockData($x, $y, $z); - if($this->randomTickBlocks[($blockId << 4) | ($meta & ~BlockFactory::$stateMasks[$blockId])]){ + if($this->randomTickBlocks[($blockId << 4) | ($meta & ~BlockFactory::getStateMask($blockId))]){ /** @var Block $block */ $block = BlockFactory::get($blockId, $meta); From 594a2041b699f0c8fdea93a52f77bfde1685f95e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 28 Sep 2018 16:44:30 +0100 Subject: [PATCH 0187/3224] Trapdoor: fix bad meth in comment --- src/pocketmine/block/Trapdoor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index ba056ac7c8..fb49f6fe25 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -58,7 +58,7 @@ class Trapdoor extends Transparent{ } public function readStateFromMeta(int $meta) : void{ - //TODO: in PC the values are reversed (3 - (5 - facing)) + //TODO: in PC the values are reversed (facing - 2) $this->facing = 5 - ($meta & 0x03); $this->top = ($meta & self::MASK_UPPER) !== 0; From 8e6a5813eaa88ba24b5b8176943259c5f755203d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 28 Sep 2018 20:12:41 +0100 Subject: [PATCH 0188/3224] Don't auto-create tiles on activate this complicates the code unnecessarily and doesn't produce the desired effect in most cases anyway. --- src/pocketmine/block/Chest.php | 25 ++++++++++--------------- src/pocketmine/block/EnderChest.php | 18 ++++-------------- src/pocketmine/block/Furnace.php | 10 ++-------- src/pocketmine/block/ItemFrame.php | 14 ++++++-------- 4 files changed, 22 insertions(+), 45 deletions(-) diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index 323f9f5445..c5f22ebed5 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -109,23 +109,18 @@ class Chest extends Transparent{ public function onActivate(Item $item, Player $player = null) : bool{ if($player instanceof Player){ - $t = $this->getLevel()->getTile($this); - $chest = null; - if($t instanceof TileChest){ - $chest = $t; - }else{ - $chest = Tile::createTile(Tile::CHEST, $this->getLevel(), TileChest::createNBT($this)); - } + $chest = $this->getLevel()->getTile($this); + if($chest instanceof TileChest){ + if( + !$this->getSide(Facing::UP)->isTransparent() or + ($chest->isPaired() and !$chest->getPair()->getBlock()->getSide(Facing::UP)->isTransparent()) or + !$chest->canOpenWith($item->getCustomName()) + ){ + return true; + } - if( - !$this->getSide(Facing::UP)->isTransparent() or - ($chest->isPaired() and !$chest->getPair()->getBlock()->getSide(Facing::UP)->isTransparent()) or - !$chest->canOpenWith($item->getCustomName()) - ){ - return true; + $player->addWindow($chest->getInventory()); } - - $player->addWindow($chest->getInventory()); } return true; diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index 8bf91e201d..e2d273d4a7 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -76,21 +76,11 @@ class EnderChest extends Chest{ public function onActivate(Item $item, Player $player = null) : bool{ if($player instanceof Player){ - - $t = $this->getLevel()->getTile($this); - $enderChest = null; - if($t instanceof TileEnderChest){ - $enderChest = $t; - }else{ - $enderChest = Tile::createTile(Tile::ENDER_CHEST, $this->getLevel(), TileEnderChest::createNBT($this)); + $enderChest = $this->getLevel()->getTile($this); + if($enderChest instanceof TileEnderChest and $this->getSide(Facing::UP)->isTransparent()){ + $player->getEnderChestInventory()->setHolderPosition($enderChest); + $player->addWindow($player->getEnderChestInventory()); } - - if(!$this->getSide(Facing::UP)->isTransparent()){ - return true; - } - - $player->getEnderChestInventory()->setHolderPosition($enderChest); - $player->addWindow($player->getEnderChestInventory()); } return true; diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index a311355790..820195d6e6 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -104,15 +104,9 @@ class Furnace extends Solid{ public function onActivate(Item $item, Player $player = null) : bool{ if($player instanceof Player){ $furnace = $this->getLevel()->getTile($this); - if(!($furnace instanceof TileFurnace)){ - $furnace = Tile::createTile(Tile::FURNACE, $this->getLevel(), TileFurnace::createNBT($this)); + if($furnace instanceof TileFurnace and $furnace->canOpenWith($item->getCustomName())){ + $player->addWindow($furnace->getInventory()); } - - if(!$furnace->canOpenWith($item->getCustomName())){ - return true; - } - - $player->addWindow($furnace->getInventory()); } return true; diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 8e33153904..ca9dab19f3 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -60,14 +60,12 @@ class ItemFrame extends Flowable{ public function onActivate(Item $item, Player $player = null) : bool{ $tile = $this->level->getTile($this); - if(!($tile instanceof TileItemFrame)){ - $tile = Tile::createTile(Tile::ITEM_FRAME, $this->getLevel(), TileItemFrame::createNBT($this)); - } - - if($tile->hasItem()){ - $tile->setItemRotation(($tile->getItemRotation() + 1) % 8); - }elseif(!$item->isNull()){ - $tile->setItem($item->pop()); + if($tile instanceof TileItemFrame){ + if($tile->hasItem()){ + $tile->setItemRotation(($tile->getItemRotation() + 1) % 8); + }elseif(!$item->isNull()){ + $tile->setItem($item->pop()); + } } return true; From 1a2312418bf7171fcd69d2e277bcb961c3ea1e5a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 30 Sep 2018 14:17:30 +0100 Subject: [PATCH 0189/3224] Fixed assert failure when placing northeast/northwest powered rails --- src/pocketmine/block/BaseRail.php | 2 +- src/pocketmine/block/RedstoneRail.php | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/pocketmine/block/BaseRail.php b/src/pocketmine/block/BaseRail.php index 682404a0e5..55c944b6c8 100644 --- a/src/pocketmine/block/BaseRail.php +++ b/src/pocketmine/block/BaseRail.php @@ -90,7 +90,7 @@ abstract class BaseRail extends Flowable{ } public function getStateBitmask() : int{ - return 0b111; + return 0b1111; } public function getHardness() : float{ diff --git a/src/pocketmine/block/RedstoneRail.php b/src/pocketmine/block/RedstoneRail.php index a02f11635d..0ea1ab7ad8 100644 --- a/src/pocketmine/block/RedstoneRail.php +++ b/src/pocketmine/block/RedstoneRail.php @@ -38,10 +38,6 @@ class RedstoneRail extends BaseRail{ $this->powered = ($meta & self::FLAG_POWERED) !== 0; } - public function getStateBitmask() : int{ - return 0b1111; - } - protected function getConnectionsFromMeta(int $meta) : array{ return self::CONNECTIONS[$meta & ~self::FLAG_POWERED] ?? []; } From 274a4d892fdeb9bcae9d481a46cb06f7fdf9e417 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 30 Sep 2018 14:35:57 +0100 Subject: [PATCH 0190/3224] Rail: detect state and then place, not vice versa --- src/pocketmine/block/BaseRail.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/block/BaseRail.php b/src/pocketmine/block/BaseRail.php index 55c944b6c8..187f6b2222 100644 --- a/src/pocketmine/block/BaseRail.php +++ b/src/pocketmine/block/BaseRail.php @@ -98,9 +98,9 @@ abstract class BaseRail extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if(!$blockReplace->getSide(Facing::DOWN)->isTransparent() and parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ + if(!$blockReplace->getSide(Facing::DOWN)->isTransparent()){ $this->tryReconnect(); - return true; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; @@ -240,7 +240,8 @@ abstract class BaseRail extends Flowable{ if(isset($otherPossible[$otherSide])){ $otherConnections[] = $otherSide; - $other->updateState($otherConnections); + $other->setConnections($otherConnections); + $other->level->setBlock($other, $other); $changed = true; $thisConnections[] = $thisSide; @@ -252,11 +253,11 @@ abstract class BaseRail extends Flowable{ }while($continue); if($changed){ - $this->updateState($thisConnections); + $this->setConnections($thisConnections); } } - private function updateState(array $connections) : void{ + private function setConnections(array $connections) : void{ if(count($connections) === 1){ $connections[] = Facing::opposite($connections[0] & ~self::FLAG_ASCEND); }elseif(count($connections) !== 2){ @@ -264,7 +265,6 @@ abstract class BaseRail extends Flowable{ } $this->connections = $connections; - $this->level->setBlock($this, $this, false); //avoid recursion } public function onNearbyBlockChange() : void{ From 74486d68803a27bfb0ab2c38adca5ef711e7b88e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 30 Sep 2018 14:43:55 +0100 Subject: [PATCH 0191/3224] Remove some state meta constants from API visibility --- src/pocketmine/block/Trapdoor.php | 9 ++------- src/pocketmine/block/Vine.php | 8 ++++---- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index fb49f6fe25..b9a5dbdaea 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -32,13 +32,8 @@ use pocketmine\math\Vector3; use pocketmine\Player; class Trapdoor extends Transparent{ - public const MASK_UPPER = 0x04; - public const MASK_OPENED = 0x08; - public const MASK_SIDE = 0x03; - public const MASK_SIDE_SOUTH = 2; - public const MASK_SIDE_NORTH = 3; - public const MASK_SIDE_EAST = 0; - public const MASK_SIDE_WEST = 1; + private const MASK_UPPER = 0x04; + private const MASK_OPENED = 0x08; protected $id = self::TRAPDOOR; diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index fdfd7cb0cd..4ffe880082 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -31,10 +31,10 @@ use pocketmine\math\Vector3; use pocketmine\Player; class Vine extends Flowable{ - public const FLAG_SOUTH = 0x01; - public const FLAG_WEST = 0x02; - public const FLAG_NORTH = 0x04; - public const FLAG_EAST = 0x08; + private const FLAG_SOUTH = 0x01; + private const FLAG_WEST = 0x02; + private const FLAG_NORTH = 0x04; + private const FLAG_EAST = 0x08; protected $id = self::VINE; From 94936d0f6b433629a6193f4fd11193f94bcdb5bc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 1 Oct 2018 16:15:49 -0400 Subject: [PATCH 0192/3224] Fixed CPU leak in falling water block updating The cause of this was the flow decay of falling water changing, but the flow decay is ignored for falling water. This caused the block to be repeatedly set to itself, triggering local block updates, causing the disease to spread in large falling water bodies and cause immense amounts of lag. --- src/pocketmine/block/Liquid.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index caa43e6925..e819288431 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -246,7 +246,7 @@ abstract class Liquid extends Transparent{ } } - if($newDecay !== $this->decay or $falling !== $this->falling){ +*/ if($falling !== $this->falling or (!$falling and $newDecay !== $this->decay)){ if(!$falling and $newDecay < 0){ $this->level->setBlock($this, BlockFactory::get(Block::AIR)); return; From 77fd57e11a936f1afbad8805aaf2139bec1af979 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 1 Oct 2018 16:20:35 -0400 Subject: [PATCH 0193/3224] Removed wtf from Liquid --- src/pocketmine/block/Liquid.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index e819288431..4837278d43 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -246,7 +246,7 @@ abstract class Liquid extends Transparent{ } } -*/ if($falling !== $this->falling or (!$falling and $newDecay !== $this->decay)){ + if($falling !== $this->falling or (!$falling and $newDecay !== $this->decay)){ if(!$falling and $newDecay < 0){ $this->level->setBlock($this, BlockFactory::get(Block::AIR)); return; From 8a062f440df4cb70b59b774f1ada07f76bd3534e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 3 Oct 2018 18:35:39 +0100 Subject: [PATCH 0194/3224] Chunk: remove column methods these were (mostly) unused, and the places they were used breaks the interface definitions. It also exposes internals that are sensitive to change. --- src/pocketmine/level/format/Chunk.php | 60 ------------------- .../level/generator/populator/GroundCover.php | 10 ++-- 2 files changed, 6 insertions(+), 64 deletions(-) diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index 1cdd005616..01835e32d5 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -461,66 +461,6 @@ class Chunk{ $this->biomeIds{($z << 4) | $x} = chr($biomeId & 0xff); } - /** - * Returns a column of block IDs from bottom to top at the specified X/Z chunk block coordinates. - * @param int $x 0-15 - * @param int $z 0-15 - * - * @return string - */ - public function getBlockIdColumn(int $x, int $z) : string{ - $result = ""; - foreach($this->subChunks as $subChunk){ - $result .= $subChunk->getBlockIdColumn($x, $z); - } - return $result; - } - - /** - * Returns a column of block meta values from bottom to top at the specified X/Z chunk block coordinates. - * @param int $x 0-15 - * @param int $z 0-15 - * - * @return string - */ - public function getBlockDataColumn(int $x, int $z) : string{ - $result = ""; - foreach($this->subChunks as $subChunk){ - $result .= $subChunk->getBlockDataColumn($x, $z); - } - return $result; - } - - /** - * Returns a column of sky light values from bottom to top at the specified X/Z chunk block coordinates. - * @param int $x 0-15 - * @param int $z 0-15 - * - * @return string - */ - public function getBlockSkyLightColumn(int $x, int $z) : string{ - $result = ""; - foreach($this->subChunks as $subChunk){ - $result .= $subChunk->getBlockSkyLightColumn($x, $z); - } - return $result; - } - - /** - * Returns a column of block light values from bottom to top at the specified X/Z chunk block coordinates. - * @param int $x 0-15 - * @param int $z 0-15 - * - * @return string - */ - public function getBlockLightColumn(int $x, int $z) : string{ - $result = ""; - foreach($this->subChunks as $subChunk){ - $result .= $subChunk->getBlockLightColumn($x, $z); - } - return $result; - } - /** * @return bool */ diff --git a/src/pocketmine/level/generator/populator/GroundCover.php b/src/pocketmine/level/generator/populator/GroundCover.php index 1410beb0ae..1218b449ab 100644 --- a/src/pocketmine/level/generator/populator/GroundCover.php +++ b/src/pocketmine/level/generator/populator/GroundCover.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\level\generator\populator; +use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\Liquid; use pocketmine\level\biome\Biome; @@ -43,9 +44,9 @@ class GroundCover extends Populator{ $diffY = 1; } - $column = $chunk->getBlockIdColumn($x, $z); for($y = 127; $y > 0; --$y){ - if($column{$y} !== "\x00" and !BlockFactory::get(ord($column{$y}))->isTransparent()){ + $id = $chunk->getBlockId($x, $y, $z); + if($id !== Block::AIR and !BlockFactory::get($id)->isTransparent()){ break; } } @@ -53,10 +54,11 @@ class GroundCover extends Populator{ $endY = $startY - count($cover); for($y = $startY; $y > $endY and $y >= 0; --$y){ $b = $cover[$startY - $y]; - if($column{$y} === "\x00" and $b->isSolid()){ + $id = $chunk->getBlockId($x, $y, $z); + if($id === Block::AIR and $b->isSolid()){ break; } - if($b->canBeFlowedInto() and BlockFactory::get(ord($column{$y})) instanceof Liquid){ + if($b->canBeFlowedInto() and BlockFactory::get($id) instanceof Liquid){ continue; } if($b->getDamage() === 0){ From 23132b899cd791dab3832af00d41292fcb096f01 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 3 Oct 2018 19:43:16 +0100 Subject: [PATCH 0195/3224] Added LevelProvider->getAllChunks() method this returns a generator which yields known chunks. This will be used in the future for world format conversions. --- .../level/format/io/LevelProvider.php | 7 ++++++ .../level/format/io/leveldb/LevelDB.php | 12 +++++++++ .../level/format/io/region/McRegion.php | 25 +++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/src/pocketmine/level/format/io/LevelProvider.php b/src/pocketmine/level/format/io/LevelProvider.php index bf7ce85899..93c6c9a2ac 100644 --- a/src/pocketmine/level/format/io/LevelProvider.php +++ b/src/pocketmine/level/format/io/LevelProvider.php @@ -206,4 +206,11 @@ interface LevelProvider{ */ public function close(); + /** + * Returns a generator which yields all the chunks in this level. + * + * @return \Generator|Chunk[] + */ + public function getAllChunks() : \Generator; + } diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index d82c5a8332..34017d2f84 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -535,4 +535,16 @@ class LevelDB extends BaseLevelProvider{ public function close(){ $this->db->close(); } + + public function getAllChunks() : \Generator{ + foreach($this->db->getIterator() as $key => $_){ + if(strlen($key) === 9 and substr($key, -1) === self::TAG_VERSION){ + $chunkX = Binary::readLInt(substr($key, 0, 4)); + $chunkZ = Binary::readLInt(substr($key, 4, 4)); + if(($chunk = $this->loadChunk($chunkX, $chunkZ)) !== null){ + yield $chunk; + } + } + } + } } diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index 35bf7f1afd..4cb8df9cad 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -413,4 +413,29 @@ class McRegion extends BaseLevelProvider{ $this->getRegion($regionX, $regionZ)->writeChunk($chunkX & 0x1f, $chunkZ & 0x1f, $this->nbtSerialize($chunk)); } + + public function getAllChunks() : \Generator{ + $iterator = new \RegexIterator( + new \FilesystemIterator( + $this->path . '/region/', + \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS + ), + '/\/r\.(-?\d+)\.(-?\d+)\.' . static::REGION_FILE_EXTENSION . '$/', + \RegexIterator::GET_MATCH + ); + + foreach($iterator as $region){ + $rX = ((int) $region[1]) << 5; + $rZ = ((int) $region[2]) << 5; + + for($chunkX = $rX; $chunkX < $rX + 32; ++$chunkX){ + for($chunkZ = $rZ; $chunkZ < $rZ + 32; ++$chunkZ){ + $chunk = $this->loadChunk($chunkX, $chunkZ); + if($chunk !== null){ + yield $chunk; + } + } + } + } + } } From 050e972adda31208991f8df008e42d96146eda15 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Oct 2018 12:49:46 +0100 Subject: [PATCH 0196/3224] Clean up default level provider management --- src/pocketmine/Server.php | 13 +++++----- .../level/format/io/LevelProviderManager.php | 26 +++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 3af550ed27..f52f5199cf 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1080,12 +1080,7 @@ class Server{ $generator = GeneratorManager::getGenerator($this->getLevelType()); } - if(($providerClass = LevelProviderManager::getProviderByName($this->getProperty("level-settings.default-format", "pmanvil"))) === null){ - $providerClass = LevelProviderManager::getProviderByName("pmanvil"); - if($providerClass === null){ - throw new \InvalidStateException("Default level provider has not been registered"); - } - } + $providerClass = LevelProviderManager::getDefault(); $path = $this->getDataPath() . "worlds/" . $name . "/"; /** @var LevelProvider $providerClass */ @@ -1677,6 +1672,12 @@ class Server{ $this->network->registerInterface(new RakLibInterface($this)); LevelProviderManager::init(); + if(($format = LevelProviderManager::getProviderByName($formatName = (string) $this->getProperty("level-settings.default-format"))) !== null){ + LevelProviderManager::setDefault($format); + }elseif($formatName !== ""){ + $this->logger->warning($this->language->translateString("pocketmine.level.badDefaultFormat", [$formatName])); + } + if(extension_loaded("leveldb")){ $this->logger->debug($this->getLanguage()->translateString("pocketmine.debug.enable")); } diff --git a/src/pocketmine/level/format/io/LevelProviderManager.php b/src/pocketmine/level/format/io/LevelProviderManager.php index 04f30f168b..437721816e 100644 --- a/src/pocketmine/level/format/io/LevelProviderManager.php +++ b/src/pocketmine/level/format/io/LevelProviderManager.php @@ -32,6 +32,9 @@ use pocketmine\utils\Utils; abstract class LevelProviderManager{ protected static $providers = []; + /** @var string|LevelProvider */ + private static $default = PMAnvil::class; + public static function init() : void{ self::addProvider(Anvil::class); self::addProvider(McRegion::class); @@ -39,6 +42,29 @@ abstract class LevelProviderManager{ self::addProvider(LevelDB::class); } + /** + * Returns the default format used to generate new levels. + * + * @return string + */ + public static function getDefault() : string{ + return self::$default; + } + + /** + * Sets the default format. + * + * @param string $class Class extending LevelProvider + * + * @throws \InvalidArgumentException + */ + public static function setDefault(string $class) : void{ + Utils::testValidInstance($class, LevelProvider::class); + + self::addProvider($class); + self::$default = $class; + } + /** * @param string $class * From eaf6b316c74d0a53b0e59f1187a5db30e5c9e7dd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Oct 2018 12:52:09 +0100 Subject: [PATCH 0197/3224] I always commit this submodule when I don't want it, and not when I do --- src/pocketmine/lang/locale | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/lang/locale b/src/pocketmine/lang/locale index 0cd3f8ef30..7f12f293bf 160000 --- a/src/pocketmine/lang/locale +++ b/src/pocketmine/lang/locale @@ -1 +1 @@ -Subproject commit 0cd3f8ef307a695eb0c4352db79a26bf7a077b8f +Subproject commit 7f12f293bfad76e5c07b929c893e848728064977 From 65b49dec713d554e68b7e9bc21226d6e960a6db8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Oct 2018 14:19:19 +0100 Subject: [PATCH 0198/3224] Refactor hierarchy of Region-based world formats In the future, McRegion and PMAnvil will become deprecated legacy formats which we won't support for writing anymore. However, this brings complications because Anvil (which would not be deprecated) would be sandwiched between its deprecated base (McRegion) and its deprecated child (PMAnvil), complicating the implementation (particularly for PMAnvil). This abstracts away the generic Region-based world functionality into a separate class, making McRegion, Anvil and PMAnvil all inherit from it directly. Since only the chunk formats are different, they are more accurately siblings rather than parent-child (although Anvil and PMAnvil are cousins, ish). --- .../level/format/io/region/Anvil.php | 104 +----- .../io/region/LegacyAnvilChunkTrait.php | 138 ++++++++ .../level/format/io/region/McRegion.php | 276 +--------------- .../level/format/io/region/PMAnvil.php | 15 +- .../format/io/region/RegionLevelProvider.php | 303 ++++++++++++++++++ 5 files changed, 473 insertions(+), 363 deletions(-) create mode 100644 src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php create mode 100644 src/pocketmine/level/format/io/region/RegionLevelProvider.php diff --git a/src/pocketmine/level/format/io/region/Anvil.php b/src/pocketmine/level/format/io/region/Anvil.php index 5864d30f71..a00455c053 100644 --- a/src/pocketmine/level/format/io/region/Anvil.php +++ b/src/pocketmine/level/format/io/region/Anvil.php @@ -23,67 +23,13 @@ declare(strict_types=1); namespace pocketmine\level\format\io\region; -use pocketmine\level\format\Chunk; -use pocketmine\level\format\ChunkException; use pocketmine\level\format\io\ChunkUtils; use pocketmine\level\format\SubChunk; -use pocketmine\nbt\BigEndianNBTStream; -use pocketmine\nbt\NBT; use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\IntArrayTag; -use pocketmine\nbt\tag\ListTag; -class Anvil extends McRegion{ - - public const REGION_FILE_EXTENSION = "mca"; - - protected function nbtSerialize(Chunk $chunk) : string{ - $nbt = new CompoundTag("Level", []); - $nbt->setInt("xPos", $chunk->getX()); - $nbt->setInt("zPos", $chunk->getZ()); - - $nbt->setByte("V", 1); - $nbt->setLong("LastUpdate", 0); //TODO - $nbt->setLong("InhabitedTime", 0); //TODO - $nbt->setByte("TerrainPopulated", $chunk->isPopulated() ? 1 : 0); - $nbt->setByte("LightPopulated", $chunk->isLightPopulated() ? 1 : 0); - - $subChunks = []; - foreach($chunk->getSubChunks() as $y => $subChunk){ - if($subChunk->isEmpty()){ - continue; - } - - $tag = $this->serializeSubChunk($subChunk); - $tag->setByte("Y", $y); - $subChunks[] = $tag; - } - $nbt->setTag(new ListTag("Sections", $subChunks, NBT::TAG_Compound)); - - $nbt->setByteArray("Biomes", $chunk->getBiomeIdArray()); - $nbt->setIntArray("HeightMap", $chunk->getHeightMapArray()); - - $entities = []; - - foreach($chunk->getSavableEntities() as $entity){ - $entities[] = $entity->saveNBT(); - } - - $nbt->setTag(new ListTag("Entities", $entities, NBT::TAG_Compound)); - - $tiles = []; - foreach($chunk->getTiles() as $tile){ - $tiles[] = $tile->saveNBT(); - } - - $nbt->setTag(new ListTag("TileEntities", $tiles, NBT::TAG_Compound)); - - //TODO: TileTicks - - $writer = new BigEndianNBTStream(); - return $writer->writeCompressed(new CompoundTag("", [$nbt]), ZLIB_ENCODING_DEFLATE, RegionLoader::$COMPRESSION_LEVEL); - } +class Anvil extends RegionLevelProvider{ + use LegacyAnvilChunkTrait; protected function serializeSubChunk(SubChunk $subChunk) : CompoundTag{ return new CompoundTag("", [ @@ -94,44 +40,6 @@ class Anvil extends McRegion{ ]); } - protected function nbtDeserialize(string $data) : Chunk{ - $nbt = new BigEndianNBTStream(); - $chunk = $nbt->readCompressed($data); - if(!($chunk instanceof CompoundTag) or !$chunk->hasTag("Level")){ - throw new ChunkException("Invalid NBT format"); - } - - $chunk = $chunk->getCompoundTag("Level"); - - $subChunks = []; - $subChunksTag = $chunk->getListTag("Sections") ?? []; - foreach($subChunksTag as $subChunk){ - if($subChunk instanceof CompoundTag){ - $subChunks[$subChunk->getByte("Y")] = $this->deserializeSubChunk($subChunk); - } - } - - if($chunk->hasTag("BiomeColors", IntArrayTag::class)){ - $biomeIds = ChunkUtils::convertBiomeColors($chunk->getIntArray("BiomeColors")); //Convert back to original format - }else{ - $biomeIds = $chunk->getByteArray("Biomes", "", true); - } - - $result = new Chunk( - $chunk->getInt("xPos"), - $chunk->getInt("zPos"), - $subChunks, - $chunk->hasTag("Entities", ListTag::class) ? $chunk->getListTag("Entities")->getValue() : [], - $chunk->hasTag("TileEntities", ListTag::class) ? $chunk->getListTag("TileEntities")->getValue() : [], - $biomeIds, - $chunk->getIntArray("HeightMap", []) - ); - $result->setLightPopulated($chunk->getByte("LightPopulated", 0) !== 0); - $result->setPopulated($chunk->getByte("TerrainPopulated", 0) !== 0); - $result->setGenerated(); - return $result; - } - protected function deserializeSubChunk(CompoundTag $subChunk) : SubChunk{ return new SubChunk( ChunkUtils::reorderByteArray($subChunk->getByteArray("Blocks")), @@ -145,8 +53,12 @@ class Anvil extends McRegion{ return "anvil"; } - public static function getPcWorldFormatVersion() : int{ - return 19133; //anvil + protected static function getRegionFileExtension() : string{ + return "mca"; + } + + protected static function getPcWorldFormatVersion() : int{ + return 19133; } public function getWorldHeight() : int{ diff --git a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php b/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php new file mode 100644 index 0000000000..b467df5066 --- /dev/null +++ b/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php @@ -0,0 +1,138 @@ +setInt("xPos", $chunk->getX()); + $nbt->setInt("zPos", $chunk->getZ()); + + $nbt->setByte("V", 1); + $nbt->setLong("LastUpdate", 0); //TODO + $nbt->setLong("InhabitedTime", 0); //TODO + $nbt->setByte("TerrainPopulated", $chunk->isPopulated() ? 1 : 0); + $nbt->setByte("LightPopulated", $chunk->isLightPopulated() ? 1 : 0); + + $subChunks = []; + foreach($chunk->getSubChunks() as $y => $subChunk){ + if($subChunk->isEmpty()){ + continue; + } + + $tag = $this->serializeSubChunk($subChunk); + $tag->setByte("Y", $y); + $subChunks[] = $tag; + } + $nbt->setTag(new ListTag("Sections", $subChunks, NBT::TAG_Compound)); + + $nbt->setByteArray("Biomes", $chunk->getBiomeIdArray()); + $nbt->setIntArray("HeightMap", $chunk->getHeightMapArray()); + + $entities = []; + + foreach($chunk->getSavableEntities() as $entity){ + $entities[] = $entity->saveNBT(); + } + + $nbt->setTag(new ListTag("Entities", $entities, NBT::TAG_Compound)); + + $tiles = []; + foreach($chunk->getTiles() as $tile){ + $tiles[] = $tile->saveNBT(); + } + + $nbt->setTag(new ListTag("TileEntities", $tiles, NBT::TAG_Compound)); + + //TODO: TileTicks + + $writer = new BigEndianNBTStream(); + return $writer->writeCompressed(new CompoundTag("", [$nbt]), ZLIB_ENCODING_DEFLATE, RegionLoader::$COMPRESSION_LEVEL); + } + + abstract protected function serializeSubChunk(SubChunk $subChunk) : CompoundTag; + + protected function deserializeChunk(string $data) : Chunk{ + $nbt = new BigEndianNBTStream(); + $chunk = $nbt->readCompressed($data); + if(!($chunk instanceof CompoundTag) or !$chunk->hasTag("Level")){ + throw new ChunkException("Invalid NBT format"); + } + + $chunk = $chunk->getCompoundTag("Level"); + + $subChunks = []; + $subChunksTag = $chunk->getListTag("Sections") ?? []; + foreach($subChunksTag as $subChunk){ + if($subChunk instanceof CompoundTag){ + $subChunks[$subChunk->getByte("Y")] = $this->deserializeSubChunk($subChunk); + } + } + + if($chunk->hasTag("BiomeColors", IntArrayTag::class)){ + $biomeIds = ChunkUtils::convertBiomeColors($chunk->getIntArray("BiomeColors")); //Convert back to original format + }else{ + $biomeIds = $chunk->getByteArray("Biomes", "", true); + } + + $result = new Chunk( + $chunk->getInt("xPos"), + $chunk->getInt("zPos"), + $subChunks, + $chunk->hasTag("Entities", ListTag::class) ? $chunk->getListTag("Entities")->getValue() : [], + $chunk->hasTag("TileEntities", ListTag::class) ? $chunk->getListTag("TileEntities")->getValue() : [], + $biomeIds, + $chunk->getIntArray("HeightMap", []) + ); + $result->setLightPopulated($chunk->getByte("LightPopulated", 0) !== 0); + $result->setPopulated($chunk->getByte("TerrainPopulated", 0) !== 0); + $result->setGenerated(); + return $result; + } + + abstract protected function deserializeSubChunk(CompoundTag $subChunk) : SubChunk; + +} diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index 4cb8df9cad..890de55c15 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -25,31 +25,23 @@ namespace pocketmine\level\format\io\region; use pocketmine\level\format\Chunk; use pocketmine\level\format\ChunkException; -use pocketmine\level\format\io\BaseLevelProvider; use pocketmine\level\format\io\ChunkUtils; use pocketmine\level\format\SubChunk; -use pocketmine\level\generator\GeneratorManager; -use pocketmine\level\Level; use pocketmine\nbt\BigEndianNBTStream; use pocketmine\nbt\NBT; -use pocketmine\nbt\tag\{ - ByteArrayTag, ByteTag, CompoundTag, FloatTag, IntArrayTag, IntTag, ListTag, LongTag, StringTag -}; -use pocketmine\utils\MainLogger; +use pocketmine\nbt\tag\ByteArrayTag; +use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\tag\IntArrayTag; +use pocketmine\nbt\tag\ListTag; -class McRegion extends BaseLevelProvider{ - - public const REGION_FILE_EXTENSION = "mcr"; - - /** @var RegionLoader[] */ - protected $regions = []; +class McRegion extends RegionLevelProvider{ /** * @param Chunk $chunk * * @return string */ - protected function nbtSerialize(Chunk $chunk) : string{ + protected function serializeChunk(Chunk $chunk) : string{ $nbt = new CompoundTag("Level", []); $nbt->setInt("xPos", $chunk->getX()); $nbt->setInt("zPos", $chunk->getZ()); @@ -107,7 +99,7 @@ class McRegion extends BaseLevelProvider{ * * @return Chunk */ - protected function nbtDeserialize(string $data) : Chunk{ + protected function deserializeChunk(string $data) : Chunk{ $nbt = new BigEndianNBTStream(); $chunk = $nbt->readCompressed($data); if(!($chunk instanceof CompoundTag) or !$chunk->hasTag("Level")){ @@ -184,258 +176,16 @@ class McRegion extends BaseLevelProvider{ return "mcregion"; } - /** - * Returns the storage version as per Minecraft PC world formats. - * @return int - */ - public static function getPcWorldFormatVersion() : int{ - return 19132; //mcregion + protected static function getRegionFileExtension() : string{ + return "mcr"; + } + + protected static function getPcWorldFormatVersion() : int{ + return 19132; } public function getWorldHeight() : int{ //TODO: add world height options return 128; } - - public static function isValid(string $path) : bool{ - $isValid = (file_exists($path . "/level.dat") and is_dir($path . "/region/")); - - if($isValid){ - $files = array_filter(scandir($path . "/region/", SCANDIR_SORT_NONE), function($file){ - return substr($file, strrpos($file, ".") + 1, 2) === "mc"; //region file - }); - - foreach($files as $f){ - if(substr($f, strrpos($f, ".") + 1) !== static::REGION_FILE_EXTENSION){ - $isValid = false; - break; - } - } - } - - return $isValid; - } - - public static function generate(string $path, string $name, int $seed, string $generator, array $options = []){ - if(!file_exists($path)){ - mkdir($path, 0777, true); - } - - if(!file_exists($path . "/region")){ - mkdir($path . "/region", 0777); - } - //TODO, add extra details - $levelData = new CompoundTag("Data", [ - new ByteTag("hardcore", ($options["hardcore"] ?? false) === true ? 1 : 0), - new ByteTag("Difficulty", Level::getDifficultyFromString((string) ($options["difficulty"] ?? "normal"))), - new ByteTag("initialized", 1), - new IntTag("GameType", 0), - new IntTag("generatorVersion", 1), //2 in MCPE - new IntTag("SpawnX", 256), - new IntTag("SpawnY", 70), - new IntTag("SpawnZ", 256), - new IntTag("version", static::getPcWorldFormatVersion()), - new IntTag("DayTime", 0), - new LongTag("LastPlayed", (int) (microtime(true) * 1000)), - new LongTag("RandomSeed", $seed), - new LongTag("SizeOnDisk", 0), - new LongTag("Time", 0), - new StringTag("generatorName", GeneratorManager::getGeneratorName($generator)), - new StringTag("generatorOptions", $options["preset"] ?? ""), - new StringTag("LevelName", $name), - new CompoundTag("GameRules", []) - ]); - $nbt = new BigEndianNBTStream(); - $buffer = $nbt->writeCompressed(new CompoundTag("", [ - $levelData - ])); - file_put_contents($path . "level.dat", $buffer); - } - - public function getGenerator() : string{ - return $this->levelData->getString("generatorName", "DEFAULT"); - } - - public function getGeneratorOptions() : array{ - return ["preset" => $this->levelData->getString("generatorOptions", "")]; - } - - public function getDifficulty() : int{ - return $this->levelData->getByte("Difficulty", Level::DIFFICULTY_NORMAL); - } - - public function setDifficulty(int $difficulty){ - $this->levelData->setByte("Difficulty", $difficulty); - } - - public function getRainTime() : int{ - return $this->levelData->getInt("rainTime", 0); - } - - public function setRainTime(int $ticks) : void{ - $this->levelData->setInt("rainTime", $ticks); - } - - public function getRainLevel() : float{ - if($this->levelData->hasTag("rainLevel", FloatTag::class)){ //PocketMine/MCPE - return $this->levelData->getFloat("rainLevel"); - } - - return (float) $this->levelData->getByte("raining", 0); //PC vanilla - } - - public function setRainLevel(float $level) : void{ - $this->levelData->setFloat("rainLevel", $level); //PocketMine/MCPE - $this->levelData->setByte("raining", (int) ceil($level)); //PC vanilla - } - - public function getLightningTime() : int{ - return $this->levelData->getInt("thunderTime", 0); - } - - public function setLightningTime(int $ticks) : void{ - $this->levelData->setInt("thunderTime", $ticks); - } - - public function getLightningLevel() : float{ - if($this->levelData->hasTag("lightningLevel", FloatTag::class)){ //PocketMine/MCPE - return $this->levelData->getFloat("lightningLevel"); - } - - return (float) $this->levelData->getByte("thundering", 0); //PC vanilla - } - - public function setLightningLevel(float $level) : void{ - $this->levelData->setFloat("lightningLevel", $level); //PocketMine/MCPE - $this->levelData->setByte("thundering", (int) ceil($level)); //PC vanilla - } - - public function doGarbageCollection(){ - $limit = time() - 300; - foreach($this->regions as $index => $region){ - if($region->lastUsed <= $limit){ - $region->close(); - unset($this->regions[$index]); - } - } - } - - /** - * @param int $chunkX - * @param int $chunkZ - * @param int &$regionX - * @param int &$regionZ - */ - public static function getRegionIndex(int $chunkX, int $chunkZ, &$regionX, &$regionZ){ - $regionX = $chunkX >> 5; - $regionZ = $chunkZ >> 5; - } - - /** - * @param int $regionX - * @param int $regionZ - * - * @return RegionLoader|null - */ - protected function getRegion(int $regionX, int $regionZ){ - return $this->regions[Level::chunkHash($regionX, $regionZ)] ?? null; - } - - /** - * Returns the path to a specific region file based on its X/Z coordinates - * - * @param int $regionX - * @param int $regionZ - * - * @return string - */ - protected function pathToRegion(int $regionX, int $regionZ) : string{ - return $this->path . "region/r.$regionX.$regionZ." . static::REGION_FILE_EXTENSION; - } - - /** - * @param int $regionX - * @param int $regionZ - */ - protected function loadRegion(int $regionX, int $regionZ){ - if(!isset($this->regions[$index = Level::chunkHash($regionX, $regionZ)])){ - $path = $this->pathToRegion($regionX, $regionZ); - - $region = new RegionLoader($path, $regionX, $regionZ); - try{ - $region->open(); - }catch(CorruptedRegionException $e){ - $logger = MainLogger::getLogger(); - $logger->error("Corrupted region file detected: " . $e->getMessage()); - - $region->close(false); //Do not write anything to the file - - $backupPath = $path . ".bak." . time(); - rename($path, $backupPath); - $logger->error("Corrupted region file has been backed up to " . $backupPath); - - $region = new RegionLoader($path, $regionX, $regionZ); - $region->open(); //this will create a new empty region to replace the corrupted one - } - - $this->regions[$index] = $region; - } - } - - public function close(){ - foreach($this->regions as $index => $region){ - $region->close(); - unset($this->regions[$index]); - } - } - - protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk{ - $regionX = $regionZ = null; - self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ); - assert(is_int($regionX) and is_int($regionZ)); - - $this->loadRegion($regionX, $regionZ); - - $chunkData = $this->getRegion($regionX, $regionZ)->readChunk($chunkX & 0x1f, $chunkZ & 0x1f); - if($chunkData !== null){ - return $this->nbtDeserialize($chunkData); - } - - return null; - } - - protected function writeChunk(Chunk $chunk) : void{ - $chunkX = $chunk->getX(); - $chunkZ = $chunk->getZ(); - - self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ); - $this->loadRegion($regionX, $regionZ); - - $this->getRegion($regionX, $regionZ)->writeChunk($chunkX & 0x1f, $chunkZ & 0x1f, $this->nbtSerialize($chunk)); - } - - public function getAllChunks() : \Generator{ - $iterator = new \RegexIterator( - new \FilesystemIterator( - $this->path . '/region/', - \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS - ), - '/\/r\.(-?\d+)\.(-?\d+)\.' . static::REGION_FILE_EXTENSION . '$/', - \RegexIterator::GET_MATCH - ); - - foreach($iterator as $region){ - $rX = ((int) $region[1]) << 5; - $rZ = ((int) $region[2]) << 5; - - for($chunkX = $rX; $chunkX < $rX + 32; ++$chunkX){ - for($chunkZ = $rZ; $chunkZ < $rZ + 32; ++$chunkZ){ - $chunk = $this->loadChunk($chunkX, $chunkZ); - if($chunk !== null){ - yield $chunk; - } - } - } - } - } } diff --git a/src/pocketmine/level/format/io/region/PMAnvil.php b/src/pocketmine/level/format/io/region/PMAnvil.php index 5ef0d665c4..472fa93973 100644 --- a/src/pocketmine/level/format/io/region/PMAnvil.php +++ b/src/pocketmine/level/format/io/region/PMAnvil.php @@ -31,9 +31,8 @@ use pocketmine\nbt\tag\CompoundTag; * This format is exactly the same as the PC Anvil format, with the only difference being that the stored data order * is XZY instead of YZX for more performance loading and saving worlds. */ -class PMAnvil extends Anvil{ - - public const REGION_FILE_EXTENSION = "mcapm"; +class PMAnvil extends RegionLevelProvider{ + use LegacyAnvilChunkTrait; protected function serializeSubChunk(SubChunk $subChunk) : CompoundTag{ return new CompoundTag("", [ @@ -57,7 +56,15 @@ class PMAnvil extends Anvil{ return "pmanvil"; } - public static function getPcWorldFormatVersion() : int{ + protected static function getRegionFileExtension() : string{ + return "mcapm"; + } + + protected static function getPcWorldFormatVersion() : int{ return -1; //Not a PC format, only PocketMine-MP } + + public function getWorldHeight() : int{ + return 256; + } } diff --git a/src/pocketmine/level/format/io/region/RegionLevelProvider.php b/src/pocketmine/level/format/io/region/RegionLevelProvider.php new file mode 100644 index 0000000000..e5c5a82b8e --- /dev/null +++ b/src/pocketmine/level/format/io/region/RegionLevelProvider.php @@ -0,0 +1,303 @@ +writeCompressed(new CompoundTag("", [ + $levelData + ])); + file_put_contents($path . "level.dat", $buffer); + } + + /** @var RegionLoader[] */ + protected $regions = []; + + + public function getGenerator() : string{ + return $this->levelData->getString("generatorName", "DEFAULT"); + } + + public function getGeneratorOptions() : array{ + return ["preset" => $this->levelData->getString("generatorOptions", "")]; + } + + public function getDifficulty() : int{ + return $this->levelData->getByte("Difficulty", Level::DIFFICULTY_NORMAL); + } + + public function setDifficulty(int $difficulty){ + $this->levelData->setByte("Difficulty", $difficulty); + } + + public function getRainTime() : int{ + return $this->levelData->getInt("rainTime", 0); + } + + public function setRainTime(int $ticks) : void{ + $this->levelData->setInt("rainTime", $ticks); + } + + public function getRainLevel() : float{ + if($this->levelData->hasTag("rainLevel", FloatTag::class)){ //PocketMine/MCPE + return $this->levelData->getFloat("rainLevel"); + } + + return (float) $this->levelData->getByte("raining", 0); //PC vanilla + } + + public function setRainLevel(float $level) : void{ + $this->levelData->setFloat("rainLevel", $level); //PocketMine/MCPE + $this->levelData->setByte("raining", (int) ceil($level)); //PC vanilla + } + + public function getLightningTime() : int{ + return $this->levelData->getInt("thunderTime", 0); + } + + public function setLightningTime(int $ticks) : void{ + $this->levelData->setInt("thunderTime", $ticks); + } + + public function getLightningLevel() : float{ + if($this->levelData->hasTag("lightningLevel", FloatTag::class)){ //PocketMine/MCPE + return $this->levelData->getFloat("lightningLevel"); + } + + return (float) $this->levelData->getByte("thundering", 0); //PC vanilla + } + + public function setLightningLevel(float $level) : void{ + $this->levelData->setFloat("lightningLevel", $level); //PocketMine/MCPE + $this->levelData->setByte("thundering", (int) ceil($level)); //PC vanilla + } + + public function doGarbageCollection(){ + $limit = time() - 300; + foreach($this->regions as $index => $region){ + if($region->lastUsed <= $limit){ + $region->close(); + unset($this->regions[$index]); + } + } + } + + /** + * @param int $chunkX + * @param int $chunkZ + * @param int &$regionX + * @param int &$regionZ + */ + public static function getRegionIndex(int $chunkX, int $chunkZ, &$regionX, &$regionZ){ + $regionX = $chunkX >> 5; + $regionZ = $chunkZ >> 5; + } + + /** + * @param int $regionX + * @param int $regionZ + * + * @return RegionLoader|null + */ + protected function getRegion(int $regionX, int $regionZ){ + return $this->regions[Level::chunkHash($regionX, $regionZ)] ?? null; + } + + /** + * Returns the path to a specific region file based on its X/Z coordinates + * + * @param int $regionX + * @param int $regionZ + * + * @return string + */ + protected function pathToRegion(int $regionX, int $regionZ) : string{ + return $this->path . "region/r.$regionX.$regionZ." . static::getRegionFileExtension(); + } + + /** + * @param int $regionX + * @param int $regionZ + */ + protected function loadRegion(int $regionX, int $regionZ){ + if(!isset($this->regions[$index = Level::chunkHash($regionX, $regionZ)])){ + $path = $this->pathToRegion($regionX, $regionZ); + + $region = new RegionLoader($path, $regionX, $regionZ); + try{ + $region->open(); + }catch(CorruptedRegionException $e){ + $logger = MainLogger::getLogger(); + $logger->error("Corrupted region file detected: " . $e->getMessage()); + + $region->close(false); //Do not write anything to the file + + $backupPath = $path . ".bak." . time(); + rename($path, $backupPath); + $logger->error("Corrupted region file has been backed up to " . $backupPath); + + $region = new RegionLoader($path, $regionX, $regionZ); + $region->open(); //this will create a new empty region to replace the corrupted one + } + + $this->regions[$index] = $region; + } + } + + public function close(){ + foreach($this->regions as $index => $region){ + $region->close(); + unset($this->regions[$index]); + } + } + + abstract protected function serializeChunk(Chunk $chunk) : string; + + abstract protected function deserializeChunk(string $data) : Chunk; + + protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk{ + $regionX = $regionZ = null; + self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ); + assert(is_int($regionX) and is_int($regionZ)); + + $this->loadRegion($regionX, $regionZ); + + $chunkData = $this->getRegion($regionX, $regionZ)->readChunk($chunkX & 0x1f, $chunkZ & 0x1f); + if($chunkData !== null){ + return $this->deserializeChunk($chunkData); + } + + return null; + } + + protected function writeChunk(Chunk $chunk) : void{ + $chunkX = $chunk->getX(); + $chunkZ = $chunk->getZ(); + + self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ); + $this->loadRegion($regionX, $regionZ); + + $this->getRegion($regionX, $regionZ)->writeChunk($chunkX & 0x1f, $chunkZ & 0x1f, $this->serializeChunk($chunk)); + } + + public function getAllChunks() : \Generator{ + $iterator = new \RegexIterator( + new \FilesystemIterator( + $this->path . '/region/', + \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS + ), + '/\/r\.(-?\d+)\.(-?\d+)\.' . static::getRegionFileExtension() . '$/', + \RegexIterator::GET_MATCH + ); + + foreach($iterator as $region){ + $rX = ((int) $region[1]) << 5; + $rZ = ((int) $region[2]) << 5; + + for($chunkX = $rX; $chunkX < $rX + 32; ++$chunkX){ + for($chunkZ = $rZ; $chunkZ < $rZ + 32; ++$chunkZ){ + $chunk = $this->loadChunk($chunkX, $chunkZ); + if($chunk !== null){ + yield $chunk; + } + } + } + } + } +} From f787552e97cc4d2c4a1197924cedce476313abaa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Oct 2018 14:56:42 +0100 Subject: [PATCH 0199/3224] Remove LevelProvider::getProviderName() This is problematic because child level providers can forget to override the provider name of their parents, and then override them by error. Instead, they should be used in a mapping fashion to make sure they are unique and not inherited. Also, the old method did not permit registering multiple aliases for the same provider. This now makes that possible. --- .../level/format/io/LevelProvider.php | 7 ------- .../level/format/io/LevelProviderManager.php | 21 ++++++++++++------- .../level/format/io/leveldb/LevelDB.php | 4 ---- .../level/format/io/region/Anvil.php | 4 ---- .../level/format/io/region/McRegion.php | 4 ---- .../level/format/io/region/PMAnvil.php | 4 ---- .../format/io/LevelProviderManagerTest.php | 8 +++---- 7 files changed, 17 insertions(+), 35 deletions(-) diff --git a/src/pocketmine/level/format/io/LevelProvider.php b/src/pocketmine/level/format/io/LevelProvider.php index 93c6c9a2ac..ab30ddfbbb 100644 --- a/src/pocketmine/level/format/io/LevelProvider.php +++ b/src/pocketmine/level/format/io/LevelProvider.php @@ -33,13 +33,6 @@ interface LevelProvider{ */ public function __construct(string $path); - /** - * Returns the full provider name, like "anvil" or "mcregion", will be used to find the correct format. - * - * @return string - */ - public static function getProviderName() : string; - /** * Gets the build height limit of this world * diff --git a/src/pocketmine/level/format/io/LevelProviderManager.php b/src/pocketmine/level/format/io/LevelProviderManager.php index 437721816e..75291a75ab 100644 --- a/src/pocketmine/level/format/io/LevelProviderManager.php +++ b/src/pocketmine/level/format/io/LevelProviderManager.php @@ -36,10 +36,10 @@ abstract class LevelProviderManager{ private static $default = PMAnvil::class; public static function init() : void{ - self::addProvider(Anvil::class); - self::addProvider(McRegion::class); - self::addProvider(PMAnvil::class); - self::addProvider(LevelDB::class); + self::addProvider(Anvil::class, "anvil"); + self::addProvider(McRegion::class, "mcregion"); + self::addProvider(PMAnvil::class, "pmanvil"); + self::addProvider(LevelDB::class, "leveldb"); } /** @@ -61,20 +61,25 @@ abstract class LevelProviderManager{ public static function setDefault(string $class) : void{ Utils::testValidInstance($class, LevelProvider::class); - self::addProvider($class); self::$default = $class; } /** * @param string $class * - * @throws \InvalidArgumentException + * @param string $name + * @param bool $overwrite */ - public static function addProvider(string $class){ + public static function addProvider(string $class, string $name, bool $overwrite = false) : void{ Utils::testValidInstance($class, LevelProvider::class); + $name = strtolower($name); + if(!$overwrite and isset(self::$providers[$name])){ + throw new \InvalidArgumentException("Alias \"$name\" is already assigned"); + } + /** @var LevelProvider $class */ - self::$providers[strtolower($class::getProviderName())] = $class; + self::$providers[$name] = $class; } /** diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index 34017d2f84..14199abbb4 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -153,10 +153,6 @@ class LevelDB extends BaseLevelProvider{ $db->close(); } - public static function getProviderName() : string{ - return "leveldb"; - } - public function getWorldHeight() : int{ return 256; } diff --git a/src/pocketmine/level/format/io/region/Anvil.php b/src/pocketmine/level/format/io/region/Anvil.php index a00455c053..b5fc667188 100644 --- a/src/pocketmine/level/format/io/region/Anvil.php +++ b/src/pocketmine/level/format/io/region/Anvil.php @@ -49,10 +49,6 @@ class Anvil extends RegionLevelProvider{ ); } - public static function getProviderName() : string{ - return "anvil"; - } - protected static function getRegionFileExtension() : string{ return "mca"; } diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index 890de55c15..36e903f91e 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -172,10 +172,6 @@ class McRegion extends RegionLevelProvider{ return $result; } - public static function getProviderName() : string{ - return "mcregion"; - } - protected static function getRegionFileExtension() : string{ return "mcr"; } diff --git a/src/pocketmine/level/format/io/region/PMAnvil.php b/src/pocketmine/level/format/io/region/PMAnvil.php index 472fa93973..84ab25ac79 100644 --- a/src/pocketmine/level/format/io/region/PMAnvil.php +++ b/src/pocketmine/level/format/io/region/PMAnvil.php @@ -52,10 +52,6 @@ class PMAnvil extends RegionLevelProvider{ ); } - public static function getProviderName() : string{ - return "pmanvil"; - } - protected static function getRegionFileExtension() : string{ return "mcapm"; } diff --git a/tests/phpunit/level/format/io/LevelProviderManagerTest.php b/tests/phpunit/level/format/io/LevelProviderManagerTest.php index 64b6206225..10c484a76d 100644 --- a/tests/phpunit/level/format/io/LevelProviderManagerTest.php +++ b/tests/phpunit/level/format/io/LevelProviderManagerTest.php @@ -30,24 +30,24 @@ class LevelProviderManagerTest extends TestCase{ public function testAddNonClassProvider() : void{ $this->expectException(\InvalidArgumentException::class); - LevelProviderManager::addProvider("lol"); + LevelProviderManager::addProvider("lol", "nope"); } public function testAddAbstractClassProvider() : void{ $this->expectException(\InvalidArgumentException::class); - LevelProviderManager::addProvider(AbstractLevelProvider::class); + LevelProviderManager::addProvider(AbstractLevelProvider::class, "abstract"); } public function testAddInterfaceProvider() : void{ $this->expectException(\InvalidArgumentException::class); - LevelProviderManager::addProvider(InterfaceLevelProvider::class); + LevelProviderManager::addProvider(InterfaceLevelProvider::class, "interface"); } public function testAddWrongClassProvider() : void{ $this->expectException(\InvalidArgumentException::class); - LevelProviderManager::addProvider(LevelProviderManagerTest::class); + LevelProviderManager::addProvider(LevelProviderManagerTest::class, "bad_class"); } } From 4f421d561c5c381ee1d444012e67546d216eb559 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Oct 2018 15:41:18 +0100 Subject: [PATCH 0200/3224] BaseLevelProvider: clean up not-exists error handling disaster It checks for the existence of (and creates) the world directory if it doesn't exist. But what sense does this make when the world obviously doesn't exist in this case and must be generated first? --- src/pocketmine/level/format/io/BaseLevelProvider.php | 12 ++++++++---- src/pocketmine/level/format/io/leveldb/LevelDB.php | 6 +++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/level/format/io/BaseLevelProvider.php b/src/pocketmine/level/format/io/BaseLevelProvider.php index 574c519a64..99bb35de2d 100644 --- a/src/pocketmine/level/format/io/BaseLevelProvider.php +++ b/src/pocketmine/level/format/io/BaseLevelProvider.php @@ -37,18 +37,22 @@ abstract class BaseLevelProvider implements LevelProvider{ protected $levelData; public function __construct(string $path){ - $this->path = $path; - if(!file_exists($this->path)){ - mkdir($this->path, 0777, true); + if(!file_exists($path)){ + throw new LevelException("Level does not exist"); } + $this->path = $path; $this->loadLevelData(); $this->fixLevelData(); } protected function loadLevelData() : void{ + $levelDatPath = $this->getPath() . "level.dat"; + if(!file_exists($levelDatPath)){ + throw new LevelException("level.dat not found"); + } $nbt = new BigEndianNBTStream(); - $levelData = $nbt->readCompressed(file_get_contents($this->getPath() . "level.dat")); + $levelData = $nbt->readCompressed(file_get_contents($levelDatPath)); if(!($levelData instanceof CompoundTag) or !$levelData->hasTag("Data", CompoundTag::class)){ throw new LevelException("Invalid level.dat"); diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index 14199abbb4..6272a292e2 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -100,8 +100,12 @@ class LevelDB extends BaseLevelProvider{ } protected function loadLevelData() : void{ + $levelDatPath = $this->getPath() . "level.dat"; + if(!file_exists($levelDatPath)){ + throw new LevelException("level.dat not found"); + } $nbt = new LittleEndianNBTStream(); - $levelData = $nbt->read(substr(file_get_contents($this->getPath() . "level.dat"), 8)); + $levelData = $nbt->read(substr(file_get_contents($levelDatPath), 8)); if($levelData instanceof CompoundTag){ $this->levelData = $levelData; }else{ From 4d9d4d7c60f83aee91e6525bea7d2e373856257e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Oct 2018 16:02:55 +0100 Subject: [PATCH 0201/3224] More cleanups to level provider hierarchy, move more garbage out of BaseLevelProvider --- src/pocketmine/level/Level.php | 5 +-- .../level/format/io/BaseLevelProvider.php | 41 +------------------ .../level/format/io/LevelProvider.php | 5 +++ .../level/format/io/leveldb/LevelDB.php | 4 ++ .../format/io/region/RegionLevelProvider.php | 35 ++++++++++++++++ 5 files changed, 47 insertions(+), 43 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index cf05d19710..d82bc9cf6d 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -48,7 +48,6 @@ use pocketmine\level\biome\Biome; use pocketmine\level\format\Chunk; use pocketmine\level\format\ChunkException; use pocketmine\level\format\EmptySubChunk; -use pocketmine\level\format\io\BaseLevelProvider; use pocketmine\level\format\io\LevelProvider; use pocketmine\level\generator\Generator; use pocketmine\level\generator\GeneratorManager; @@ -1025,9 +1024,7 @@ class Level implements ChunkManager, Metadatable{ $this->provider->setTime($this->time); $this->saveChunks(); - if($this->provider instanceof BaseLevelProvider){ - $this->provider->saveLevelData(); - } + $this->provider->saveLevelData(); return true; } diff --git a/src/pocketmine/level/format/io/BaseLevelProvider.php b/src/pocketmine/level/format/io/BaseLevelProvider.php index 99bb35de2d..5ecbe032ab 100644 --- a/src/pocketmine/level/format/io/BaseLevelProvider.php +++ b/src/pocketmine/level/format/io/BaseLevelProvider.php @@ -26,9 +26,7 @@ namespace pocketmine\level\format\io; use pocketmine\level\format\Chunk; use pocketmine\level\LevelException; use pocketmine\math\Vector3; -use pocketmine\nbt\BigEndianNBTStream; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\StringTag; abstract class BaseLevelProvider implements LevelProvider{ /** @var string */ @@ -46,32 +44,9 @@ abstract class BaseLevelProvider implements LevelProvider{ $this->fixLevelData(); } - protected function loadLevelData() : void{ - $levelDatPath = $this->getPath() . "level.dat"; - if(!file_exists($levelDatPath)){ - throw new LevelException("level.dat not found"); - } - $nbt = new BigEndianNBTStream(); - $levelData = $nbt->readCompressed(file_get_contents($levelDatPath)); + abstract protected function loadLevelData() : void; - if(!($levelData instanceof CompoundTag) or !$levelData->hasTag("Data", CompoundTag::class)){ - throw new LevelException("Invalid level.dat"); - } - - $this->levelData = $levelData->getCompoundTag("Data"); - } - - protected function fixLevelData() : void{ - if(!$this->levelData->hasTag("generatorName", StringTag::class)){ - $this->levelData->setString("generatorName", "default", true); - }elseif(($generatorName = self::hackyFixForGeneratorClasspathInLevelDat($this->levelData->getString("generatorName"))) !== null){ - $this->levelData->setString("generatorName", $generatorName); - } - - if(!$this->levelData->hasTag("generatorOptions", StringTag::class)){ - $this->levelData->setString("generatorOptions", ""); - } - } + abstract protected function fixLevelData() : void; /** * Hack to fix worlds broken previously by older versions of PocketMine-MP which incorrectly saved classpaths of @@ -137,10 +112,6 @@ abstract class BaseLevelProvider implements LevelProvider{ $this->levelData->setInt("SpawnZ", $pos->getFloorZ()); } - public function doGarbageCollection(){ - - } - /** * @return CompoundTag */ @@ -148,14 +119,6 @@ abstract class BaseLevelProvider implements LevelProvider{ return $this->levelData; } - public function saveLevelData(){ - $nbt = new BigEndianNBTStream(); - $buffer = $nbt->writeCompressed(new CompoundTag("", [ - $this->levelData - ])); - file_put_contents($this->getPath() . "level.dat", $buffer); - } - public function loadChunk(int $chunkX, int $chunkZ) : ?Chunk{ return $this->readChunk($chunkX, $chunkZ); } diff --git a/src/pocketmine/level/format/io/LevelProvider.php b/src/pocketmine/level/format/io/LevelProvider.php index ab30ddfbbb..412cfd90df 100644 --- a/src/pocketmine/level/format/io/LevelProvider.php +++ b/src/pocketmine/level/format/io/LevelProvider.php @@ -194,6 +194,11 @@ interface LevelProvider{ */ public function doGarbageCollection(); + /** + * Saves information about the level state, such as weather, time, etc. + */ + public function saveLevelData(); + /** * Performs cleanups necessary when the level provider is closed and no longer needed. */ diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index 6272a292e2..86625291f4 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -532,6 +532,10 @@ class LevelDB extends BaseLevelProvider{ return $this->db->get(LevelDB::chunkIndex($chunkX, $chunkZ) . self::TAG_VERSION) !== false; } + public function doGarbageCollection(){ + + } + public function close(){ $this->db->close(); } diff --git a/src/pocketmine/level/format/io/region/RegionLevelProvider.php b/src/pocketmine/level/format/io/region/RegionLevelProvider.php index e5c5a82b8e..705ddd0cbb 100644 --- a/src/pocketmine/level/format/io/region/RegionLevelProvider.php +++ b/src/pocketmine/level/format/io/region/RegionLevelProvider.php @@ -27,6 +27,7 @@ use pocketmine\level\format\Chunk; use pocketmine\level\format\io\BaseLevelProvider; use pocketmine\level\generator\GeneratorManager; use pocketmine\level\Level; +use pocketmine\level\LevelException; use pocketmine\nbt\BigEndianNBTStream; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; @@ -109,6 +110,40 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ /** @var RegionLoader[] */ protected $regions = []; + protected function loadLevelData() : void{ + $levelDatPath = $this->getPath() . "level.dat"; + if(!file_exists($levelDatPath)){ + throw new LevelException("level.dat not found"); + } + $nbt = new BigEndianNBTStream(); + $levelData = $nbt->readCompressed(file_get_contents($levelDatPath)); + + if(!($levelData instanceof CompoundTag) or !$levelData->hasTag("Data", CompoundTag::class)){ + throw new LevelException("Invalid level.dat"); + } + + $this->levelData = $levelData->getCompoundTag("Data"); + } + + protected function fixLevelData() : void{ + if(!$this->levelData->hasTag("generatorName", StringTag::class)){ + $this->levelData->setString("generatorName", "default", true); + }elseif(($generatorName = self::hackyFixForGeneratorClasspathInLevelDat($this->levelData->getString("generatorName"))) !== null){ + $this->levelData->setString("generatorName", $generatorName); + } + + if(!$this->levelData->hasTag("generatorOptions", StringTag::class)){ + $this->levelData->setString("generatorOptions", ""); + } + } + + public function saveLevelData(){ + $nbt = new BigEndianNBTStream(); + $buffer = $nbt->writeCompressed(new CompoundTag("", [ + $this->levelData + ])); + file_put_contents($this->getPath() . "level.dat", $buffer); + } public function getGenerator() : string{ return $this->levelData->getString("generatorName", "DEFAULT"); From 41f335e7d9b61df0aab68227821a464aea4bb5de Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Oct 2018 16:24:07 +0100 Subject: [PATCH 0202/3224] Level: Remove setSeed() Seed is immutable information about the world, like its generator type, generator options, name, etc. We don't allow changing any of those things, so why the fuck would we allow changing the seed? This makes no sense at all. I'm removing this because a) its existence makes no sense, and b) it will not produce the behaviour expected from such a function (what even is the expected behaviour???) --- src/pocketmine/level/Level.php | 9 --------- src/pocketmine/level/format/io/BaseLevelProvider.php | 4 ---- src/pocketmine/level/format/io/LevelProvider.php | 5 ----- 3 files changed, 18 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index d82bc9cf6d..d71d7efb07 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -2864,15 +2864,6 @@ class Level implements ChunkManager, Metadatable{ return $this->provider->getSeed(); } - /** - * Sets the seed for the level - * - * @param int $seed - */ - public function setSeed(int $seed){ - $this->provider->setSeed($seed); - } - public function getWorldHeight() : int{ return $this->worldHeight; } diff --git a/src/pocketmine/level/format/io/BaseLevelProvider.php b/src/pocketmine/level/format/io/BaseLevelProvider.php index 5ecbe032ab..c300b71fc4 100644 --- a/src/pocketmine/level/format/io/BaseLevelProvider.php +++ b/src/pocketmine/level/format/io/BaseLevelProvider.php @@ -98,10 +98,6 @@ abstract class BaseLevelProvider implements LevelProvider{ return $this->levelData->getLong("RandomSeed"); } - public function setSeed(int $value){ - $this->levelData->setLong("RandomSeed", $value); - } - public function getSpawn() : Vector3{ return new Vector3($this->levelData->getInt("SpawnX"), $this->levelData->getInt("SpawnY"), $this->levelData->getInt("SpawnZ")); } diff --git a/src/pocketmine/level/format/io/LevelProvider.php b/src/pocketmine/level/format/io/LevelProvider.php index 412cfd90df..54c9d9f448 100644 --- a/src/pocketmine/level/format/io/LevelProvider.php +++ b/src/pocketmine/level/format/io/LevelProvider.php @@ -118,11 +118,6 @@ interface LevelProvider{ */ public function getSeed() : int; - /** - * @param int - */ - public function setSeed(int $value); - /** * @return Vector3 */ From b0f1863c4f73f112e112605696e68740d6b782b4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Oct 2018 16:37:19 +0100 Subject: [PATCH 0203/3224] Region loaders don't need to know their own coordinates --- .../format/io/region/RegionLevelProvider.php | 4 ++-- .../level/format/io/region/RegionLoader.php | 16 +--------------- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/src/pocketmine/level/format/io/region/RegionLevelProvider.php b/src/pocketmine/level/format/io/region/RegionLevelProvider.php index 705ddd0cbb..8b3701a7be 100644 --- a/src/pocketmine/level/format/io/region/RegionLevelProvider.php +++ b/src/pocketmine/level/format/io/region/RegionLevelProvider.php @@ -254,7 +254,7 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ if(!isset($this->regions[$index = Level::chunkHash($regionX, $regionZ)])){ $path = $this->pathToRegion($regionX, $regionZ); - $region = new RegionLoader($path, $regionX, $regionZ); + $region = new RegionLoader($path); try{ $region->open(); }catch(CorruptedRegionException $e){ @@ -267,7 +267,7 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ rename($path, $backupPath); $logger->error("Corrupted region file has been backed up to " . $backupPath); - $region = new RegionLoader($path, $regionX, $regionZ); + $region = new RegionLoader($path); $region->open(); //this will create a new empty region to replace the corrupted one } diff --git a/src/pocketmine/level/format/io/region/RegionLoader.php b/src/pocketmine/level/format/io/region/RegionLoader.php index feb35844d1..9b5d1ac14b 100644 --- a/src/pocketmine/level/format/io/region/RegionLoader.php +++ b/src/pocketmine/level/format/io/region/RegionLoader.php @@ -39,10 +39,6 @@ class RegionLoader{ public static $COMPRESSION_LEVEL = 7; - /** @var int */ - protected $x; - /** @var int */ - protected $z; /** @var string */ protected $filePath; /** @var resource */ @@ -54,9 +50,7 @@ class RegionLoader{ /** @var int */ public $lastUsed = 0; - public function __construct(string $filePath, int $regionX, int $regionZ){ - $this->x = $regionX; - $this->z = $regionZ; + public function __construct(string $filePath){ $this->filePath = $filePath; } @@ -340,14 +334,6 @@ class RegionLoader{ $this->locationTable = array_fill(0, 1024, [0, 0, 0]); } - public function getX() : int{ - return $this->x; - } - - public function getZ() : int{ - return $this->z; - } - public function getFilePath() : string{ return $this->filePath; } From 49e47edcf5f2bc3842369d8ac964bb11a83e8e2a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Oct 2018 18:45:02 +0100 Subject: [PATCH 0204/3224] Separate level data handling from the main LevelProvider --- src/pocketmine/level/Level.php | 24 +-- .../level/format/io/BaseLevelProvider.php | 43 +--- src/pocketmine/level/format/io/LevelData.php | 136 ++++++++++++ .../level/format/io/LevelProvider.php | 105 +-------- .../level/format/io/data/BaseNbtLevelData.php | 100 +++++++++ .../level/format/io/data/BedrockLevelData.php | 193 +++++++++++++++++ .../level/format/io/data/JavaLevelData.php | 148 +++++++++++++ .../level/format/io/leveldb/LevelDB.php | 199 +----------------- .../format/io/region/RegionLevelProvider.php | 132 +----------- 9 files changed, 612 insertions(+), 468 deletions(-) create mode 100644 src/pocketmine/level/format/io/LevelData.php create mode 100644 src/pocketmine/level/format/io/data/BaseNbtLevelData.php create mode 100644 src/pocketmine/level/format/io/data/BedrockLevelData.php create mode 100644 src/pocketmine/level/format/io/data/JavaLevelData.php diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index d71d7efb07..8a99561c16 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -333,11 +333,11 @@ class Level implements ChunkManager, Metadatable{ $this->provider = $provider; - $this->displayName = $this->provider->getName(); + $this->displayName = $this->provider->getLevelData()->getName(); $this->worldHeight = $this->provider->getWorldHeight(); $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.level.preparing", [$this->displayName])); - $this->generator = GeneratorManager::getGenerator($this->provider->getGenerator()); + $this->generator = GeneratorManager::getGenerator($this->provider->getLevelData()->getGenerator()); $this->folderName = $name; @@ -346,7 +346,7 @@ class Level implements ChunkManager, Metadatable{ $this->neighbourBlockUpdateQueue = new \SplQueue(); - $this->time = $this->provider->getTime(); + $this->time = $this->provider->getLevelData()->getTime(); $this->chunkTickRadius = min($this->server->getViewDistance(), max(1, (int) $this->server->getProperty("chunk-ticking.tick-radius", 4))); $this->chunksPerTick = (int) $this->server->getProperty("chunk-ticking.per-tick", 40); @@ -389,7 +389,7 @@ class Level implements ChunkManager, Metadatable{ public function registerGeneratorToWorker(int $worker) : void{ $this->generatorRegisteredWorkers[$worker] = true; - $this->server->getAsyncPool()->submitTaskToWorker(new GeneratorRegisterTask($this, $this->generator, $this->provider->getGeneratorOptions()), $worker); + $this->server->getAsyncPool()->submitTaskToWorker(new GeneratorRegisterTask($this, $this->generator, $this->provider->getLevelData()->getGeneratorOptions()), $worker); } public function unregisterGenerator(){ @@ -1022,9 +1022,9 @@ class Level implements ChunkManager, Metadatable{ $this->server->getPluginManager()->callEvent(new LevelSaveEvent($this)); - $this->provider->setTime($this->time); + $this->provider->getLevelData()->setTime($this->time); $this->saveChunks(); - $this->provider->saveLevelData(); + $this->provider->getLevelData()->save(); return true; } @@ -2405,7 +2405,7 @@ class Level implements ChunkManager, Metadatable{ * @return Position */ public function getSpawnLocation() : Position{ - return Position::fromObject($this->provider->getSpawn(), $this); + return Position::fromObject($this->provider->getLevelData()->getSpawn(), $this); } /** @@ -2415,7 +2415,7 @@ class Level implements ChunkManager, Metadatable{ */ public function setSpawnLocation(Vector3 $pos){ $previousSpawn = $this->getSpawnLocation(); - $this->provider->setSpawn($pos); + $this->provider->getLevelData()->setSpawn($pos); $this->server->getPluginManager()->callEvent(new SpawnChangeEvent($this, $previousSpawn)); } @@ -2750,7 +2750,7 @@ class Level implements ChunkManager, Metadatable{ * @return bool */ public function isSpawnChunk(int $X, int $Z) : bool{ - $spawn = $this->provider->getSpawn(); + $spawn = $this->getSpawnLocation(); $spawnX = $spawn->x >> 4; $spawnZ = $spawn->z >> 4; @@ -2861,7 +2861,7 @@ class Level implements ChunkManager, Metadatable{ * @return int */ public function getSeed() : int{ - return $this->provider->getSeed(); + return $this->provider->getLevelData()->getSeed(); } public function getWorldHeight() : int{ @@ -2872,7 +2872,7 @@ class Level implements ChunkManager, Metadatable{ * @return int */ public function getDifficulty() : int{ - return $this->provider->getDifficulty(); + return $this->provider->getLevelData()->getDifficulty(); } /** @@ -2882,7 +2882,7 @@ class Level implements ChunkManager, Metadatable{ if($difficulty < 0 or $difficulty > 3){ throw new \InvalidArgumentException("Invalid difficulty level $difficulty"); } - $this->provider->setDifficulty($difficulty); + $this->provider->getLevelData()->setDifficulty($difficulty); $this->sendDifficulty(); } diff --git a/src/pocketmine/level/format/io/BaseLevelProvider.php b/src/pocketmine/level/format/io/BaseLevelProvider.php index c300b71fc4..6c29574b37 100644 --- a/src/pocketmine/level/format/io/BaseLevelProvider.php +++ b/src/pocketmine/level/format/io/BaseLevelProvider.php @@ -25,13 +25,11 @@ namespace pocketmine\level\format\io; use pocketmine\level\format\Chunk; use pocketmine\level\LevelException; -use pocketmine\math\Vector3; -use pocketmine\nbt\tag\CompoundTag; abstract class BaseLevelProvider implements LevelProvider{ /** @var string */ protected $path; - /** @var CompoundTag */ + /** @var LevelData */ protected $levelData; public function __construct(string $path){ @@ -40,13 +38,10 @@ abstract class BaseLevelProvider implements LevelProvider{ } $this->path = $path; - $this->loadLevelData(); - $this->fixLevelData(); + $this->levelData = $this->loadLevelData(); } - abstract protected function loadLevelData() : void; - - abstract protected function fixLevelData() : void; + abstract protected function loadLevelData() : LevelData; /** * Hack to fix worlds broken previously by older versions of PocketMine-MP which incorrectly saved classpaths of @@ -66,7 +61,7 @@ abstract class BaseLevelProvider implements LevelProvider{ * * @return null|string Name of the correct generator to replace the broken value */ - protected static function hackyFixForGeneratorClasspathInLevelDat(string $className) : ?string{ + public static function hackyFixForGeneratorClasspathInLevelDat(string $className) : ?string{ //THESE ARE DELIBERATELY HARDCODED, DO NOT CHANGE! switch($className){ case 'pocketmine\level\generator\normal\Normal': @@ -82,36 +77,10 @@ abstract class BaseLevelProvider implements LevelProvider{ return $this->path; } - public function getName() : string{ - return $this->levelData->getString("LevelName"); - } - - public function getTime() : int{ - return $this->levelData->getLong("Time", 0, true); - } - - public function setTime(int $value){ - $this->levelData->setLong("Time", $value, true); //some older PM worlds had this in the wrong format - } - - public function getSeed() : int{ - return $this->levelData->getLong("RandomSeed"); - } - - public function getSpawn() : Vector3{ - return new Vector3($this->levelData->getInt("SpawnX"), $this->levelData->getInt("SpawnY"), $this->levelData->getInt("SpawnZ")); - } - - public function setSpawn(Vector3 $pos){ - $this->levelData->setInt("SpawnX", $pos->getFloorX()); - $this->levelData->setInt("SpawnY", $pos->getFloorY()); - $this->levelData->setInt("SpawnZ", $pos->getFloorZ()); - } - /** - * @return CompoundTag + * @return LevelData */ - public function getLevelData() : CompoundTag{ + public function getLevelData() : LevelData{ return $this->levelData; } diff --git a/src/pocketmine/level/format/io/LevelData.php b/src/pocketmine/level/format/io/LevelData.php new file mode 100644 index 0000000000..ea08a2c0f0 --- /dev/null +++ b/src/pocketmine/level/format/io/LevelData.php @@ -0,0 +1,136 @@ +dataPath = $dataPath; + + if(!file_exists($this->dataPath)){ + throw new LevelException("Level data not found at $dataPath"); + } + + $this->compoundTag = $this->load(); + if($this->compoundTag === null){ + throw new LevelException("Invalid level data"); + } + } + + /** + * @return CompoundTag + */ + abstract protected function load() : ?CompoundTag; + + abstract protected function fix() : void; + + public function getCompoundTag() : CompoundTag{ + return $this->compoundTag; + } + + + /* The below are common between PC and PE */ + + public function getName() : string{ + return $this->compoundTag->getString("LevelName"); + } + + public function getGenerator() : string{ + return $this->compoundTag->getString("generatorName", "DEFAULT"); + } + + public function getGeneratorOptions() : array{ + return ["preset" => $this->compoundTag->getString("generatorOptions", "")]; + } + + public function getSeed() : int{ + return $this->compoundTag->getLong("RandomSeed"); + } + + public function getTime() : int{ + return $this->compoundTag->getLong("Time", 0, true); + } + + public function setTime(int $value) : void{ + $this->compoundTag->setLong("Time", $value, true); //some older PM worlds had this in the wrong format + } + + public function getSpawn() : Vector3{ + return new Vector3($this->compoundTag->getInt("SpawnX"), $this->compoundTag->getInt("SpawnY"), $this->compoundTag->getInt("SpawnZ")); + } + + public function setSpawn(Vector3 $pos) : void{ + $this->compoundTag->setInt("SpawnX", $pos->getFloorX()); + $this->compoundTag->setInt("SpawnY", $pos->getFloorY()); + $this->compoundTag->setInt("SpawnZ", $pos->getFloorZ()); + } + +} diff --git a/src/pocketmine/level/format/io/data/BedrockLevelData.php b/src/pocketmine/level/format/io/data/BedrockLevelData.php new file mode 100644 index 0000000000..6fcf8c19fa --- /dev/null +++ b/src/pocketmine/level/format/io/data/BedrockLevelData.php @@ -0,0 +1,193 @@ +write($levelData); + file_put_contents($path . "level.dat", Binary::writeLInt(self::CURRENT_STORAGE_VERSION) . Binary::writeLInt(strlen($buffer)) . $buffer); + } + + protected function load() : ?CompoundTag{ + $nbt = new LittleEndianNBTStream(); + $levelData = $nbt->read(substr(file_get_contents($this->dataPath), 8)); + if($levelData instanceof CompoundTag){ + $version = $levelData->getInt("StorageVersion", INT32_MAX, true); + if($version > self::CURRENT_STORAGE_VERSION){ + throw new LevelException("Specified LevelDB world format version ($version) is not supported by " . \pocketmine\NAME); + } + + return $levelData; + } + return null; + } + + protected function fix() : void{ + if(!$this->compoundTag->hasTag("generatorName", StringTag::class)){ + if($this->compoundTag->hasTag("Generator", IntTag::class)){ + switch($this->compoundTag->getInt("Generator")){ //Detect correct generator from MCPE data + case self::GENERATOR_FLAT: + $this->compoundTag->setString("generatorName", "flat"); + $this->compoundTag->setString("generatorOptions", "2;7,3,3,2;1"); + break; + case self::GENERATOR_INFINITE: + //TODO: add a null generator which does not generate missing chunks (to allow importing back to MCPE and generating more normal terrain without PocketMine messing things up) + $this->compoundTag->setString("generatorName", "default"); + $this->compoundTag->setString("generatorOptions", ""); + break; + case self::GENERATOR_LIMITED: + throw new LevelException("Limited worlds are not currently supported"); + default: + throw new LevelException("Unknown LevelDB world format type, this level cannot be loaded"); + } + }else{ + $this->compoundTag->setString("generatorName", "default"); + } + }elseif(($generatorName = BaseLevelProvider::hackyFixForGeneratorClasspathInLevelDat($this->compoundTag->getString("generatorName"))) !== null){ + $this->compoundTag->setString("generatorName", $generatorName); + } + + if(!$this->compoundTag->hasTag("generatorOptions", StringTag::class)){ + $this->compoundTag->setString("generatorOptions", ""); + } + } + + public function save() : void{ + $this->compoundTag->setInt("NetworkVersion", ProtocolInfo::CURRENT_PROTOCOL); + $this->compoundTag->setInt("StorageVersion", self::CURRENT_STORAGE_VERSION); + + $nbt = new LittleEndianNBTStream(); + $buffer = $nbt->write($this->compoundTag); + file_put_contents($this->dataPath, Binary::writeLInt(self::CURRENT_STORAGE_VERSION) . Binary::writeLInt(strlen($buffer)) . $buffer); + } + + public function getDifficulty() : int{ + return $this->compoundTag->getInt("Difficulty", Level::DIFFICULTY_NORMAL); + } + + public function setDifficulty(int $difficulty) : void{ + $this->compoundTag->setInt("Difficulty", $difficulty); //yes, this is intended! (in PE: int, PC: byte) + } + + public function getRainTime() : int{ + return $this->compoundTag->getInt("rainTime", 0); + } + + public function setRainTime(int $ticks) : void{ + $this->compoundTag->setInt("rainTime", $ticks); + } + + public function getRainLevel() : float{ + return $this->compoundTag->getFloat("rainLevel", 0.0); + } + + public function setRainLevel(float $level) : void{ + $this->compoundTag->setFloat("rainLevel", $level); + } + + public function getLightningTime() : int{ + return $this->compoundTag->getInt("lightningTime", 0); + } + + public function setLightningTime(int $ticks) : void{ + $this->compoundTag->setInt("lightningTime", $ticks); + } + + public function getLightningLevel() : float{ + return $this->compoundTag->getFloat("lightningLevel", 0.0); + } + + public function setLightningLevel(float $level) : void{ + $this->compoundTag->setFloat("lightningLevel", $level); + } +} diff --git a/src/pocketmine/level/format/io/data/JavaLevelData.php b/src/pocketmine/level/format/io/data/JavaLevelData.php new file mode 100644 index 0000000000..8580c6478f --- /dev/null +++ b/src/pocketmine/level/format/io/data/JavaLevelData.php @@ -0,0 +1,148 @@ +writeCompressed(new CompoundTag("", [ + $levelData + ])); + file_put_contents($path . "level.dat", $buffer); + } + + protected function load() : ?CompoundTag{ + $nbt = new BigEndianNBTStream(); + $levelData = $nbt->readCompressed(file_get_contents($this->dataPath)); + if($levelData instanceof CompoundTag and $levelData->hasTag("Data", CompoundTag::class)){ + return $levelData->getCompoundTag("Data"); + } + return null; + } + + protected function fix() : void{ + if(!$this->compoundTag->hasTag("generatorName", StringTag::class)){ + $this->compoundTag->setString("generatorName", "default", true); + }elseif(($generatorName = BaseLevelProvider::hackyFixForGeneratorClasspathInLevelDat($this->compoundTag->getString("generatorName"))) !== null){ + $this->compoundTag->setString("generatorName", $generatorName); + } + + if(!$this->compoundTag->hasTag("generatorOptions", StringTag::class)){ + $this->compoundTag->setString("generatorOptions", ""); + } + } + + public function save() : void{ + $nbt = new BigEndianNBTStream(); + $this->compoundTag->setName("Data"); + $buffer = $nbt->writeCompressed(new CompoundTag("", [ + $this->compoundTag + ])); + file_put_contents($this->dataPath, $buffer); + } + + + public function getDifficulty() : int{ + return $this->compoundTag->getByte("Difficulty", Level::DIFFICULTY_NORMAL); + } + + public function setDifficulty(int $difficulty) : void{ + $this->compoundTag->setByte("Difficulty", $difficulty); + } + + public function getRainTime() : int{ + return $this->compoundTag->getInt("rainTime", 0); + } + + public function setRainTime(int $ticks) : void{ + $this->compoundTag->setInt("rainTime", $ticks); + } + + public function getRainLevel() : float{ + if($this->compoundTag->hasTag("rainLevel", FloatTag::class)){ //PocketMine/MCPE + return $this->compoundTag->getFloat("rainLevel"); + } + + return (float) $this->compoundTag->getByte("raining", 0); //PC vanilla + } + + public function setRainLevel(float $level) : void{ + $this->compoundTag->setFloat("rainLevel", $level); //PocketMine/MCPE + $this->compoundTag->setByte("raining", (int) ceil($level)); //PC vanilla + } + + public function getLightningTime() : int{ + return $this->compoundTag->getInt("thunderTime", 0); + } + + public function setLightningTime(int $ticks) : void{ + $this->compoundTag->setInt("thunderTime", $ticks); + } + + public function getLightningLevel() : float{ + if($this->compoundTag->hasTag("lightningLevel", FloatTag::class)){ //PocketMine/MCPE + return $this->compoundTag->getFloat("lightningLevel"); + } + + return (float) $this->compoundTag->getByte("thundering", 0); //PC vanilla + } + + public function setLightningLevel(float $level) : void{ + $this->compoundTag->setFloat("lightningLevel", $level); //PocketMine/MCPE + $this->compoundTag->setByte("thundering", (int) ceil($level)); //PC vanilla + } +} diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index 86625291f4..f721f97b2f 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -26,17 +26,14 @@ namespace pocketmine\level\format\io\leveldb; use pocketmine\level\format\Chunk; use pocketmine\level\format\io\BaseLevelProvider; use pocketmine\level\format\io\ChunkUtils; +use pocketmine\level\format\io\data\BedrockLevelData; use pocketmine\level\format\io\exception\UnsupportedChunkFormatException; +use pocketmine\level\format\io\LevelData; use pocketmine\level\format\SubChunk; -use pocketmine\level\generator\Flat; -use pocketmine\level\generator\GeneratorManager; -use pocketmine\level\Level; use pocketmine\level\LevelException; use pocketmine\nbt\LittleEndianNBTStream; -use pocketmine\nbt\tag\{ - ByteTag, CompoundTag, FloatTag, IntTag, LongTag, StringTag -}; -use pocketmine\network\mcpe\protocol\ProtocolInfo; +use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\tag\IntTag; use pocketmine\utils\Binary; use pocketmine\utils\BinaryStream; @@ -65,11 +62,6 @@ class LevelDB extends BaseLevelProvider{ public const ENTRY_FLAT_WORLD_LAYERS = "game_flatworldlayers"; - public const GENERATOR_LIMITED = 0; - public const GENERATOR_INFINITE = 1; - public const GENERATOR_FLAT = 2; - - public const CURRENT_STORAGE_VERSION = 6; //Current MCPE level format version public const CURRENT_LEVEL_CHUNK_VERSION = 7; public const CURRENT_LEVEL_SUBCHUNK_VERSION = 0; @@ -99,62 +91,8 @@ class LevelDB extends BaseLevelProvider{ $this->db = self::createDB($path); } - protected function loadLevelData() : void{ - $levelDatPath = $this->getPath() . "level.dat"; - if(!file_exists($levelDatPath)){ - throw new LevelException("level.dat not found"); - } - $nbt = new LittleEndianNBTStream(); - $levelData = $nbt->read(substr(file_get_contents($levelDatPath), 8)); - if($levelData instanceof CompoundTag){ - $this->levelData = $levelData; - }else{ - throw new LevelException("Invalid level.dat"); - } - - $version = $this->levelData->getInt("StorageVersion", INT32_MAX, true); - if($version > self::CURRENT_STORAGE_VERSION){ - throw new LevelException("Specified LevelDB world format version ($version) is not supported by " . \pocketmine\NAME); - } - } - - protected function fixLevelData() : void{ - $db = self::createDB($this->path); - - if(!$this->levelData->hasTag("generatorName", StringTag::class)){ - if($this->levelData->hasTag("Generator", IntTag::class)){ - switch($this->levelData->getInt("Generator")){ //Detect correct generator from MCPE data - case self::GENERATOR_FLAT: - $this->levelData->setString("generatorName", "flat"); - if(($layers = $db->get(self::ENTRY_FLAT_WORLD_LAYERS)) !== false){ //Detect existing custom flat layers - $layers = trim($layers, "[]"); - }else{ - $layers = "7,3,3,2"; - } - $this->levelData->setString("generatorOptions", "2;" . $layers . ";1"); - break; - case self::GENERATOR_INFINITE: - //TODO: add a null generator which does not generate missing chunks (to allow importing back to MCPE and generating more normal terrain without PocketMine messing things up) - $this->levelData->setString("generatorName", "default"); - $this->levelData->setString("generatorOptions", ""); - break; - case self::GENERATOR_LIMITED: - throw new LevelException("Limited worlds are not currently supported"); - default: - throw new LevelException("Unknown LevelDB world format type, this level cannot be loaded"); - } - }else{ - $this->levelData->setString("generatorName", "default"); - } - }elseif(($generatorName = self::hackyFixForGeneratorClasspathInLevelDat($this->levelData->getString("generatorName"))) !== null){ - $this->levelData->setString("generatorName", $generatorName); - } - - if(!$this->levelData->hasTag("generatorOptions", StringTag::class)){ - $this->levelData->setString("generatorOptions", ""); - } - - $db->close(); + protected function loadLevelData() : LevelData{ + return new BedrockLevelData($this->getPath() . "level.dat"); } public function getWorldHeight() : int{ @@ -172,130 +110,7 @@ class LevelDB extends BaseLevelProvider{ mkdir($path . "/db", 0777, true); } - switch($generator){ - case Flat::class: - $generatorType = self::GENERATOR_FLAT; - break; - default: - $generatorType = self::GENERATOR_INFINITE; - //TODO: add support for limited worlds - } - - $levelData = new CompoundTag("", [ - //Vanilla fields - new IntTag("DayCycleStopTime", -1), - new IntTag("Difficulty", Level::getDifficultyFromString((string) ($options["difficulty"] ?? "normal"))), - new ByteTag("ForceGameType", 0), - new IntTag("GameType", 0), - new IntTag("Generator", $generatorType), - new LongTag("LastPlayed", time()), - new StringTag("LevelName", $name), - new IntTag("NetworkVersion", ProtocolInfo::CURRENT_PROTOCOL), - //new IntTag("Platform", 2), //TODO: find out what the possible values are for - new LongTag("RandomSeed", $seed), - new IntTag("SpawnX", 0), - new IntTag("SpawnY", 32767), - new IntTag("SpawnZ", 0), - new IntTag("StorageVersion", self::CURRENT_STORAGE_VERSION), - new LongTag("Time", 0), - new ByteTag("eduLevel", 0), - new ByteTag("falldamage", 1), - new ByteTag("firedamage", 1), - new ByteTag("hasBeenLoadedInCreative", 1), //badly named, this actually determines whether achievements can be earned in this world... - new ByteTag("immutableWorld", 0), - new FloatTag("lightningLevel", 0.0), - new IntTag("lightningTime", 0), - new ByteTag("pvp", 1), - new FloatTag("rainLevel", 0.0), - new IntTag("rainTime", 0), - new ByteTag("spawnMobs", 1), - new ByteTag("texturePacksRequired", 0), //TODO - - //Additional PocketMine-MP fields - new CompoundTag("GameRules", []), - new ByteTag("hardcore", ($options["hardcore"] ?? false) === true ? 1 : 0), - new StringTag("generatorName", GeneratorManager::getGeneratorName($generator)), - new StringTag("generatorOptions", $options["preset"] ?? "") - ]); - - $nbt = new LittleEndianNBTStream(); - $buffer = $nbt->write($levelData); - file_put_contents($path . "level.dat", Binary::writeLInt(self::CURRENT_STORAGE_VERSION) . Binary::writeLInt(strlen($buffer)) . $buffer); - - - $db = self::createDB($path); - - if($generatorType === self::GENERATOR_FLAT and isset($options["preset"])){ - $layers = explode(";", $options["preset"])[1] ?? ""; - if($layers !== ""){ - $out = "["; - foreach(Flat::parseLayers($layers) as $result){ - $out .= $result[0] . ","; //only id, meta will unfortunately not survive :( - } - $out = rtrim($out, ",") . "]"; //remove trailing comma - $db->put(self::ENTRY_FLAT_WORLD_LAYERS, $out); //Add vanilla flatworld layers to allow terrain generation by MCPE to continue seamlessly - } - } - - $db->close(); - - } - - public function saveLevelData(){ - $this->levelData->setInt("NetworkVersion", ProtocolInfo::CURRENT_PROTOCOL); - $this->levelData->setInt("StorageVersion", self::CURRENT_STORAGE_VERSION); - - $nbt = new LittleEndianNBTStream(); - $buffer = $nbt->write($this->levelData); - file_put_contents($this->getPath() . "level.dat", Binary::writeLInt(self::CURRENT_STORAGE_VERSION) . Binary::writeLInt(strlen($buffer)) . $buffer); - } - - public function getGenerator() : string{ - return $this->levelData->getString("generatorName", ""); - } - - public function getGeneratorOptions() : array{ - return ["preset" => $this->levelData->getString("generatorOptions", "")]; - } - - public function getDifficulty() : int{ - return $this->levelData->getInt("Difficulty", Level::DIFFICULTY_NORMAL); - } - - public function setDifficulty(int $difficulty){ - $this->levelData->setInt("Difficulty", $difficulty); //yes, this is intended! (in PE: int, PC: byte) - } - - public function getRainTime() : int{ - return $this->levelData->getInt("rainTime", 0); - } - - public function setRainTime(int $ticks) : void{ - $this->levelData->setInt("rainTime", $ticks); - } - - public function getRainLevel() : float{ - return $this->levelData->getFloat("rainLevel", 0.0); - } - - public function setRainLevel(float $level) : void{ - $this->levelData->setFloat("rainLevel", $level); - } - - public function getLightningTime() : int{ - return $this->levelData->getInt("lightningTime", 0); - } - - public function setLightningTime(int $ticks) : void{ - $this->levelData->setInt("lightningTime", $ticks); - } - - public function getLightningLevel() : float{ - return $this->levelData->getFloat("lightningLevel", 0.0); - } - - public function setLightningLevel(float $level) : void{ - $this->levelData->setFloat("lightningLevel", $level); + BedrockLevelData::generate($path, $name, $seed, $generator, $options); } /** diff --git a/src/pocketmine/level/format/io/region/RegionLevelProvider.php b/src/pocketmine/level/format/io/region/RegionLevelProvider.php index 8b3701a7be..43751c0693 100644 --- a/src/pocketmine/level/format/io/region/RegionLevelProvider.php +++ b/src/pocketmine/level/format/io/region/RegionLevelProvider.php @@ -25,16 +25,9 @@ namespace pocketmine\level\format\io\region; use pocketmine\level\format\Chunk; use pocketmine\level\format\io\BaseLevelProvider; -use pocketmine\level\generator\GeneratorManager; +use pocketmine\level\format\io\data\JavaLevelData; +use pocketmine\level\format\io\LevelData; use pocketmine\level\Level; -use pocketmine\level\LevelException; -use pocketmine\nbt\BigEndianNBTStream; -use pocketmine\nbt\tag\ByteTag; -use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\FloatTag; -use pocketmine\nbt\tag\IntTag; -use pocketmine\nbt\tag\LongTag; -use pocketmine\nbt\tag\StringTag; use pocketmine\utils\MainLogger; abstract class RegionLevelProvider extends BaseLevelProvider{ @@ -79,128 +72,15 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ if(!file_exists($path . "/region")){ mkdir($path . "/region", 0777); } - //TODO, add extra details - $levelData = new CompoundTag("Data", [ - new ByteTag("hardcore", ($options["hardcore"] ?? false) === true ? 1 : 0), - new ByteTag("Difficulty", Level::getDifficultyFromString((string) ($options["difficulty"] ?? "normal"))), - new ByteTag("initialized", 1), - new IntTag("GameType", 0), - new IntTag("generatorVersion", 1), //2 in MCPE - new IntTag("SpawnX", 256), - new IntTag("SpawnY", 70), - new IntTag("SpawnZ", 256), - new IntTag("version", static::getPcWorldFormatVersion()), - new IntTag("DayTime", 0), - new LongTag("LastPlayed", (int) (microtime(true) * 1000)), - new LongTag("RandomSeed", $seed), - new LongTag("SizeOnDisk", 0), - new LongTag("Time", 0), - new StringTag("generatorName", GeneratorManager::getGeneratorName($generator)), - new StringTag("generatorOptions", $options["preset"] ?? ""), - new StringTag("LevelName", $name), - new CompoundTag("GameRules", []) - ]); - $nbt = new BigEndianNBTStream(); - $buffer = $nbt->writeCompressed(new CompoundTag("", [ - $levelData - ])); - file_put_contents($path . "level.dat", $buffer); + + JavaLevelData::generate($path, $name, $seed, $generator, $options, static::getPcWorldFormatVersion()); } /** @var RegionLoader[] */ protected $regions = []; - protected function loadLevelData() : void{ - $levelDatPath = $this->getPath() . "level.dat"; - if(!file_exists($levelDatPath)){ - throw new LevelException("level.dat not found"); - } - $nbt = new BigEndianNBTStream(); - $levelData = $nbt->readCompressed(file_get_contents($levelDatPath)); - - if(!($levelData instanceof CompoundTag) or !$levelData->hasTag("Data", CompoundTag::class)){ - throw new LevelException("Invalid level.dat"); - } - - $this->levelData = $levelData->getCompoundTag("Data"); - } - - protected function fixLevelData() : void{ - if(!$this->levelData->hasTag("generatorName", StringTag::class)){ - $this->levelData->setString("generatorName", "default", true); - }elseif(($generatorName = self::hackyFixForGeneratorClasspathInLevelDat($this->levelData->getString("generatorName"))) !== null){ - $this->levelData->setString("generatorName", $generatorName); - } - - if(!$this->levelData->hasTag("generatorOptions", StringTag::class)){ - $this->levelData->setString("generatorOptions", ""); - } - } - - public function saveLevelData(){ - $nbt = new BigEndianNBTStream(); - $buffer = $nbt->writeCompressed(new CompoundTag("", [ - $this->levelData - ])); - file_put_contents($this->getPath() . "level.dat", $buffer); - } - - public function getGenerator() : string{ - return $this->levelData->getString("generatorName", "DEFAULT"); - } - - public function getGeneratorOptions() : array{ - return ["preset" => $this->levelData->getString("generatorOptions", "")]; - } - - public function getDifficulty() : int{ - return $this->levelData->getByte("Difficulty", Level::DIFFICULTY_NORMAL); - } - - public function setDifficulty(int $difficulty){ - $this->levelData->setByte("Difficulty", $difficulty); - } - - public function getRainTime() : int{ - return $this->levelData->getInt("rainTime", 0); - } - - public function setRainTime(int $ticks) : void{ - $this->levelData->setInt("rainTime", $ticks); - } - - public function getRainLevel() : float{ - if($this->levelData->hasTag("rainLevel", FloatTag::class)){ //PocketMine/MCPE - return $this->levelData->getFloat("rainLevel"); - } - - return (float) $this->levelData->getByte("raining", 0); //PC vanilla - } - - public function setRainLevel(float $level) : void{ - $this->levelData->setFloat("rainLevel", $level); //PocketMine/MCPE - $this->levelData->setByte("raining", (int) ceil($level)); //PC vanilla - } - - public function getLightningTime() : int{ - return $this->levelData->getInt("thunderTime", 0); - } - - public function setLightningTime(int $ticks) : void{ - $this->levelData->setInt("thunderTime", $ticks); - } - - public function getLightningLevel() : float{ - if($this->levelData->hasTag("lightningLevel", FloatTag::class)){ //PocketMine/MCPE - return $this->levelData->getFloat("lightningLevel"); - } - - return (float) $this->levelData->getByte("thundering", 0); //PC vanilla - } - - public function setLightningLevel(float $level) : void{ - $this->levelData->setFloat("lightningLevel", $level); //PocketMine/MCPE - $this->levelData->setByte("thundering", (int) ceil($level)); //PC vanilla + protected function loadLevelData() : LevelData{ + return new JavaLevelData($this->getPath() . "level.dat"); } public function doGarbageCollection(){ From 0cc4bc48cc9de831711bb287a459726f4d398e45 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Oct 2018 18:55:20 +0100 Subject: [PATCH 0205/3224] Move generator classpath hack out of BaseLevelProvider --- .../level/format/io/BaseLevelProvider.php | 30 ------------------ .../level/format/io/data/BaseNbtLevelData.php | 31 +++++++++++++++++++ .../level/format/io/data/BedrockLevelData.php | 3 +- .../level/format/io/data/JavaLevelData.php | 3 +- 4 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/pocketmine/level/format/io/BaseLevelProvider.php b/src/pocketmine/level/format/io/BaseLevelProvider.php index 6c29574b37..e74038d252 100644 --- a/src/pocketmine/level/format/io/BaseLevelProvider.php +++ b/src/pocketmine/level/format/io/BaseLevelProvider.php @@ -43,36 +43,6 @@ abstract class BaseLevelProvider implements LevelProvider{ abstract protected function loadLevelData() : LevelData; - /** - * Hack to fix worlds broken previously by older versions of PocketMine-MP which incorrectly saved classpaths of - * generators into level.dat on imported (not generated) worlds. - * - * This should only have affected leveldb worlds as far as I know, because PC format worlds include the - * generatorName tag by default. However, MCPE leveldb ones didn't, and so they would get filled in with something - * broken. - * - * This bug took a long time to get found because previously the generator manager would just return the default - * generator silently on failure to identify the correct generator, which caused lots of unexpected bugs. - * - * Only classnames which were written into the level.dat from "fixing" the level data are included here. These are - * hardcoded to avoid problems fixing broken worlds in the future if these classes get moved, renamed or removed. - * - * @param string $className Classname saved in level.dat - * - * @return null|string Name of the correct generator to replace the broken value - */ - public static function hackyFixForGeneratorClasspathInLevelDat(string $className) : ?string{ - //THESE ARE DELIBERATELY HARDCODED, DO NOT CHANGE! - switch($className){ - case 'pocketmine\level\generator\normal\Normal': - return "normal"; - case 'pocketmine\level\generator\Flat': - return "flat"; - } - - return null; - } - public function getPath() : string{ return $this->path; } diff --git a/src/pocketmine/level/format/io/data/BaseNbtLevelData.php b/src/pocketmine/level/format/io/data/BaseNbtLevelData.php index d2ae70385c..5c8c6a6997 100644 --- a/src/pocketmine/level/format/io/data/BaseNbtLevelData.php +++ b/src/pocketmine/level/format/io/data/BaseNbtLevelData.php @@ -54,8 +54,39 @@ abstract class BaseNbtLevelData implements LevelData{ */ abstract protected function load() : ?CompoundTag; + abstract protected function fix() : void; + /** + * Hack to fix worlds broken previously by older versions of PocketMine-MP which incorrectly saved classpaths of + * generators into level.dat on imported (not generated) worlds. + * + * This should only have affected leveldb worlds as far as I know, because PC format worlds include the + * generatorName tag by default. However, MCPE leveldb ones didn't, and so they would get filled in with something + * broken. + * + * This bug took a long time to get found because previously the generator manager would just return the default + * generator silently on failure to identify the correct generator, which caused lots of unexpected bugs. + * + * Only classnames which were written into the level.dat from "fixing" the level data are included here. These are + * hardcoded to avoid problems fixing broken worlds in the future if these classes get moved, renamed or removed. + * + * @param string $className Classname saved in level.dat + * + * @return null|string Name of the correct generator to replace the broken value + */ + protected static function hackyFixForGeneratorClasspathInLevelDat(string $className) : ?string{ + //THESE ARE DELIBERATELY HARDCODED, DO NOT CHANGE! + switch($className){ + case 'pocketmine\level\generator\normal\Normal': + return "normal"; + case 'pocketmine\level\generator\Flat': + return "flat"; + } + + return null; + } + public function getCompoundTag() : CompoundTag{ return $this->compoundTag; } diff --git a/src/pocketmine/level/format/io/data/BedrockLevelData.php b/src/pocketmine/level/format/io/data/BedrockLevelData.php index 6fcf8c19fa..dcc98ffceb 100644 --- a/src/pocketmine/level/format/io/data/BedrockLevelData.php +++ b/src/pocketmine/level/format/io/data/BedrockLevelData.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\level\format\io\data; -use pocketmine\level\format\io\BaseLevelProvider; use pocketmine\level\generator\Flat; use pocketmine\level\generator\GeneratorManager; use pocketmine\level\Level; @@ -133,7 +132,7 @@ class BedrockLevelData extends BaseNbtLevelData{ }else{ $this->compoundTag->setString("generatorName", "default"); } - }elseif(($generatorName = BaseLevelProvider::hackyFixForGeneratorClasspathInLevelDat($this->compoundTag->getString("generatorName"))) !== null){ + }elseif(($generatorName = self::hackyFixForGeneratorClasspathInLevelDat($this->compoundTag->getString("generatorName"))) !== null){ $this->compoundTag->setString("generatorName", $generatorName); } diff --git a/src/pocketmine/level/format/io/data/JavaLevelData.php b/src/pocketmine/level/format/io/data/JavaLevelData.php index 8580c6478f..a8ecf9beb3 100644 --- a/src/pocketmine/level/format/io/data/JavaLevelData.php +++ b/src/pocketmine/level/format/io/data/JavaLevelData.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\level\format\io\data; -use pocketmine\level\format\io\BaseLevelProvider; use pocketmine\level\generator\GeneratorManager; use pocketmine\level\Level; use pocketmine\nbt\BigEndianNBTStream; @@ -77,7 +76,7 @@ class JavaLevelData extends BaseNbtLevelData{ protected function fix() : void{ if(!$this->compoundTag->hasTag("generatorName", StringTag::class)){ $this->compoundTag->setString("generatorName", "default", true); - }elseif(($generatorName = BaseLevelProvider::hackyFixForGeneratorClasspathInLevelDat($this->compoundTag->getString("generatorName"))) !== null){ + }elseif(($generatorName = self::hackyFixForGeneratorClasspathInLevelDat($this->compoundTag->getString("generatorName"))) !== null){ $this->compoundTag->setString("generatorName", $generatorName); } From a273a0c8a9b90f7415de982424245758501abb91 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Oct 2018 19:43:31 +0100 Subject: [PATCH 0206/3224] Fixed remaining cases of undefined behaviour on ambiguous world format It was still possible to produce undefined behaviour by creating a db folder in a region-based world, or adding regions to a leveldb world. This now solves the problem completely by refusing to load the world if multiple formats match the world. --- src/pocketmine/Server.php | 14 +++++++++----- src/pocketmine/lang/locale | 2 +- .../level/format/io/LevelProviderManager.php | 14 +++++++------- .../format/io/region/RegionLevelProvider.php | 19 ++++++------------- 4 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index f52f5199cf..0afe2eecb2 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1035,13 +1035,17 @@ class Server{ $path = $this->getDataPath() . "worlds/" . $name . "/"; - $providerClass = LevelProviderManager::getProvider($path); - - if($providerClass === null){ - $this->logger->error($this->getLanguage()->translateString("pocketmine.level.loadError", [$name, "Cannot identify format of world"])); - + $providers = LevelProviderManager::getMatchingProviders($path); + if(count($providers) !== 1){ + $this->logger->error($this->language->translateString("pocketmine.level.loadError", [ + $name, + empty($providers) ? + $this->language->translateString("pocketmine.level.unknownFormat") : + $this->language->translateString("pocketmine.level.ambiguousFormat", [implode(", ", array_keys($providers))]) + ])); return false; } + $providerClass = array_shift($providers); /** @see LevelProvider::__construct() */ $level = new Level($this, $name, new $providerClass($path)); diff --git a/src/pocketmine/lang/locale b/src/pocketmine/lang/locale index 7f12f293bf..e738dc7ca0 160000 --- a/src/pocketmine/lang/locale +++ b/src/pocketmine/lang/locale @@ -1 +1 @@ -Subproject commit 7f12f293bfad76e5c07b929c893e848728064977 +Subproject commit e738dc7ca0171a1a16e3682fc2a7619c059988b9 diff --git a/src/pocketmine/level/format/io/LevelProviderManager.php b/src/pocketmine/level/format/io/LevelProviderManager.php index 75291a75ab..0d3a3b3d94 100644 --- a/src/pocketmine/level/format/io/LevelProviderManager.php +++ b/src/pocketmine/level/format/io/LevelProviderManager.php @@ -87,17 +87,17 @@ abstract class LevelProviderManager{ * * @param string $path * - * @return string|null + * @return string[]|LevelProvider[] */ - public static function getProvider(string $path){ - foreach(self::$providers as $provider){ - /** @var $provider LevelProvider */ + public static function getMatchingProviders(string $path) : array{ + $result = []; + foreach(self::$providers as $alias => $provider){ + /** @var LevelProvider|string $provider */ if($provider::isValid($path)){ - return $provider; + $result[$alias] = $provider; } } - - return null; + return $result; } /** diff --git a/src/pocketmine/level/format/io/region/RegionLevelProvider.php b/src/pocketmine/level/format/io/region/RegionLevelProvider.php index 43751c0693..fad5ff3ebe 100644 --- a/src/pocketmine/level/format/io/region/RegionLevelProvider.php +++ b/src/pocketmine/level/format/io/region/RegionLevelProvider.php @@ -45,23 +45,16 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ abstract protected static function getPcWorldFormatVersion() : int; public static function isValid(string $path) : bool{ - $isValid = (file_exists($path . "/level.dat") and is_dir($path . "/region/")); - - if($isValid){ - $files = array_filter(scandir($path . "/region/", SCANDIR_SORT_NONE), function($file){ - return substr($file, strrpos($file, ".") + 1, 2) === "mc"; //region file - }); - - $ext = static::getRegionFileExtension(); - foreach($files as $f){ - if(substr($f, strrpos($f, ".") + 1) !== $ext){ - $isValid = false; - break; + if(file_exists($path . "/level.dat") and is_dir($path . "/region/")){ + foreach(scandir($path . "/region/", SCANDIR_SORT_NONE) as $file){ + if(substr($file, strrpos($file, ".") + 1) === static::getRegionFileExtension()){ + //we don't care if other region types exist, we only care if this format is possible + return true; } } } - return $isValid; + return false; } public static function generate(string $path, string $name, int $seed, string $generator, array $options = []){ From b214601a827bd4e56a8202a8f0b9b82fc26eea20 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Oct 2018 19:58:39 +0100 Subject: [PATCH 0207/3224] Silence PhpStorm complaining about hardcoded classpaths --- src/pocketmine/level/format/io/data/BaseNbtLevelData.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pocketmine/level/format/io/data/BaseNbtLevelData.php b/src/pocketmine/level/format/io/data/BaseNbtLevelData.php index 5c8c6a6997..532e7b22f3 100644 --- a/src/pocketmine/level/format/io/data/BaseNbtLevelData.php +++ b/src/pocketmine/level/format/io/data/BaseNbtLevelData.php @@ -78,8 +78,10 @@ abstract class BaseNbtLevelData implements LevelData{ protected static function hackyFixForGeneratorClasspathInLevelDat(string $className) : ?string{ //THESE ARE DELIBERATELY HARDCODED, DO NOT CHANGE! switch($className){ + /** @noinspection ClassConstantCanBeUsedInspection */ case 'pocketmine\level\generator\normal\Normal': return "normal"; + /** @noinspection ClassConstantCanBeUsedInspection */ case 'pocketmine\level\generator\Flat': return "flat"; } From b407eba1a3f6f33c2adbf246d8d7ecf33643e330 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Oct 2018 19:59:26 +0100 Subject: [PATCH 0208/3224] Apply typehints to level\format\io namespace --- src/pocketmine/level/format/io/LevelProvider.php | 6 +++--- .../level/format/io/data/BedrockLevelData.php | 2 +- .../level/format/io/data/JavaLevelData.php | 2 +- .../level/format/io/leveldb/LevelDB.php | 10 +++++----- .../format/io/region/RegionLevelProvider.php | 12 ++++++------ .../level/format/io/region/RegionLoader.php | 16 ++++++++-------- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/pocketmine/level/format/io/LevelProvider.php b/src/pocketmine/level/format/io/LevelProvider.php index ea09f633ee..cb5838b01e 100644 --- a/src/pocketmine/level/format/io/LevelProvider.php +++ b/src/pocketmine/level/format/io/LevelProvider.php @@ -63,7 +63,7 @@ interface LevelProvider{ * @param string $generator * @param array[] $options */ - public static function generate(string $path, string $name, int $seed, string $generator, array $options = []); + public static function generate(string $path, string $name, int $seed, string $generator, array $options = []) : void; /** * Saves a chunk (usually to disk). @@ -88,7 +88,7 @@ interface LevelProvider{ /** * Performs garbage collection in the level provider, such as cleaning up regions in Region-based worlds. */ - public function doGarbageCollection(); + public function doGarbageCollection() : void; /** * Returns information about the world @@ -100,7 +100,7 @@ interface LevelProvider{ /** * Performs cleanups necessary when the level provider is closed and no longer needed. */ - public function close(); + public function close() : void; /** * Returns a generator which yields all the chunks in this level. diff --git a/src/pocketmine/level/format/io/data/BedrockLevelData.php b/src/pocketmine/level/format/io/data/BedrockLevelData.php index dcc98ffceb..320d101a58 100644 --- a/src/pocketmine/level/format/io/data/BedrockLevelData.php +++ b/src/pocketmine/level/format/io/data/BedrockLevelData.php @@ -45,7 +45,7 @@ class BedrockLevelData extends BaseNbtLevelData{ public const GENERATOR_INFINITE = 1; public const GENERATOR_FLAT = 2; - public static function generate(string $path, string $name, int $seed, string $generator, array $options = []){ + public static function generate(string $path, string $name, int $seed, string $generator, array $options = []) : void{ switch($generator){ case Flat::class: $generatorType = self::GENERATOR_FLAT; diff --git a/src/pocketmine/level/format/io/data/JavaLevelData.php b/src/pocketmine/level/format/io/data/JavaLevelData.php index a8ecf9beb3..2847a46c64 100644 --- a/src/pocketmine/level/format/io/data/JavaLevelData.php +++ b/src/pocketmine/level/format/io/data/JavaLevelData.php @@ -35,7 +35,7 @@ use pocketmine\nbt\tag\StringTag; class JavaLevelData extends BaseNbtLevelData{ - public static function generate(string $path, string $name, int $seed, string $generator, array $options = [], int $version = 19133){ + public static function generate(string $path, string $name, int $seed, string $generator, array $options = [], int $version = 19133) : void{ //TODO, add extra details $levelData = new CompoundTag("Data", [ new ByteTag("hardcore", ($options["hardcore"] ?? false) === true ? 1 : 0), diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index f721f97b2f..2cabde6577 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -68,7 +68,7 @@ class LevelDB extends BaseLevelProvider{ /** @var \LevelDB */ protected $db; - private static function checkForLevelDBExtension(){ + private static function checkForLevelDBExtension() : void{ if(!extension_loaded('leveldb')){ throw new LevelException("The leveldb PHP extension is required to use this world format"); } @@ -103,7 +103,7 @@ class LevelDB extends BaseLevelProvider{ return file_exists($path . "/level.dat") and is_dir($path . "/db/"); } - public static function generate(string $path, string $name, int $seed, string $generator, array $options = []){ + public static function generate(string $path, string $name, int $seed, string $generator, array $options = []) : void{ self::checkForLevelDBExtension(); if(!file_exists($path . "/db")){ @@ -323,7 +323,7 @@ class LevelDB extends BaseLevelProvider{ * @param CompoundTag[] $targets * @param string $index */ - private function writeTags(array $targets, string $index){ + private function writeTags(array $targets, string $index) : void{ if(!empty($targets)){ $nbt = new LittleEndianNBTStream(); $this->db->put($index, $nbt->write($targets)); @@ -347,11 +347,11 @@ class LevelDB extends BaseLevelProvider{ return $this->db->get(LevelDB::chunkIndex($chunkX, $chunkZ) . self::TAG_VERSION) !== false; } - public function doGarbageCollection(){ + public function doGarbageCollection() : void{ } - public function close(){ + public function close() : void{ $this->db->close(); } diff --git a/src/pocketmine/level/format/io/region/RegionLevelProvider.php b/src/pocketmine/level/format/io/region/RegionLevelProvider.php index fad5ff3ebe..6c9e637f5e 100644 --- a/src/pocketmine/level/format/io/region/RegionLevelProvider.php +++ b/src/pocketmine/level/format/io/region/RegionLevelProvider.php @@ -57,7 +57,7 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ return false; } - public static function generate(string $path, string $name, int $seed, string $generator, array $options = []){ + public static function generate(string $path, string $name, int $seed, string $generator, array $options = []) : void{ if(!file_exists($path)){ mkdir($path, 0777, true); } @@ -76,7 +76,7 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ return new JavaLevelData($this->getPath() . "level.dat"); } - public function doGarbageCollection(){ + public function doGarbageCollection() : void{ $limit = time() - 300; foreach($this->regions as $index => $region){ if($region->lastUsed <= $limit){ @@ -92,7 +92,7 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ * @param int &$regionX * @param int &$regionZ */ - public static function getRegionIndex(int $chunkX, int $chunkZ, &$regionX, &$regionZ){ + public static function getRegionIndex(int $chunkX, int $chunkZ, &$regionX, &$regionZ) : void{ $regionX = $chunkX >> 5; $regionZ = $chunkZ >> 5; } @@ -103,7 +103,7 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ * * @return RegionLoader|null */ - protected function getRegion(int $regionX, int $regionZ){ + protected function getRegion(int $regionX, int $regionZ) : ?RegionLoader{ return $this->regions[Level::chunkHash($regionX, $regionZ)] ?? null; } @@ -123,7 +123,7 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ * @param int $regionX * @param int $regionZ */ - protected function loadRegion(int $regionX, int $regionZ){ + protected function loadRegion(int $regionX, int $regionZ) : void{ if(!isset($this->regions[$index = Level::chunkHash($regionX, $regionZ)])){ $path = $this->pathToRegion($regionX, $regionZ); @@ -148,7 +148,7 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ } } - public function close(){ + public function close() : void{ foreach($this->regions as $index => $region){ $region->close(); unset($this->regions[$index]); diff --git a/src/pocketmine/level/format/io/region/RegionLoader.php b/src/pocketmine/level/format/io/region/RegionLoader.php index dc6ee97c73..baa84cfe0e 100644 --- a/src/pocketmine/level/format/io/region/RegionLoader.php +++ b/src/pocketmine/level/format/io/region/RegionLoader.php @@ -53,7 +53,7 @@ class RegionLoader{ $this->filePath = $filePath; } - public function open(){ + public function open() : void{ $exists = file_exists($this->filePath); if(!$exists){ touch($this->filePath); @@ -138,7 +138,7 @@ class RegionLoader{ return $this->isChunkGenerated(self::getChunkOffset($x, $z)); } - public function writeChunk(int $x, int $z, string $chunkData){ + public function writeChunk(int $x, int $z, string $chunkData) : void{ $this->lastUsed = time(); $length = strlen($chunkData) + 1; @@ -167,7 +167,7 @@ class RegionLoader{ } } - public function removeChunk(int $x, int $z){ + public function removeChunk(int $x, int $z) : void{ $index = self::getChunkOffset($x, $z); $this->locationTable[$index][0] = 0; $this->locationTable[$index][1] = 0; @@ -182,7 +182,7 @@ class RegionLoader{ * * @param bool $writeHeader */ - public function close(bool $writeHeader = true){ + public function close(bool $writeHeader = true) : void{ if(is_resource($this->filePointer)){ if($writeHeader){ $this->writeLocationTable(); @@ -267,7 +267,7 @@ class RegionLoader{ return $shift; } - protected function loadLocationTable(){ + protected function loadLocationTable() : void{ fseek($this->filePointer, 0); $this->lastSector = 1; @@ -301,7 +301,7 @@ class RegionLoader{ fseek($this->filePointer, 0); } - private function writeLocationTable(){ + private function writeLocationTable() : void{ $write = []; for($i = 0; $i < 1024; ++$i){ @@ -314,14 +314,14 @@ class RegionLoader{ fwrite($this->filePointer, pack("N*", ...$write), 4096 * 2); } - protected function writeLocationIndex($index){ + protected function writeLocationIndex(int $index) : void{ fseek($this->filePointer, $index << 2); fwrite($this->filePointer, Binary::writeInt(($this->locationTable[$index][0] << 8) | $this->locationTable[$index][1]), 4); fseek($this->filePointer, 4096 + ($index << 2)); fwrite($this->filePointer, Binary::writeInt($this->locationTable[$index][2]), 4); } - protected function createBlank(){ + protected function createBlank() : void{ fseek($this->filePointer, 0); ftruncate($this->filePointer, 8192); // this fills the file with the null byte $this->lastSector = 1; From 47f43c5e6b7a8e570c5071c2cfc9d44c90b82b86 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Oct 2018 20:03:11 +0100 Subject: [PATCH 0209/3224] Remove some internal constants from public API --- .../level/format/io/leveldb/LevelDB.php | 38 +++++++++---------- .../level/format/io/region/RegionLoader.php | 4 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index 2cabde6577..97049b393d 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -40,30 +40,30 @@ use pocketmine\utils\BinaryStream; class LevelDB extends BaseLevelProvider{ //According to Tomasso, these aren't supposed to be readable anymore. Thankfully he didn't change the readable ones... - public const TAG_DATA_2D = "\x2d"; - public const TAG_DATA_2D_LEGACY = "\x2e"; - public const TAG_SUBCHUNK_PREFIX = "\x2f"; - public const TAG_LEGACY_TERRAIN = "0"; - public const TAG_BLOCK_ENTITY = "1"; - public const TAG_ENTITY = "2"; - public const TAG_PENDING_TICK = "3"; - public const TAG_BLOCK_EXTRA_DATA = "4"; - public const TAG_BIOME_STATE = "5"; - public const TAG_STATE_FINALISATION = "6"; + protected const TAG_DATA_2D = "\x2d"; + protected const TAG_DATA_2D_LEGACY = "\x2e"; + protected const TAG_SUBCHUNK_PREFIX = "\x2f"; + protected const TAG_LEGACY_TERRAIN = "0"; + protected const TAG_BLOCK_ENTITY = "1"; + protected const TAG_ENTITY = "2"; + protected const TAG_PENDING_TICK = "3"; + protected const TAG_BLOCK_EXTRA_DATA = "4"; + protected const TAG_BIOME_STATE = "5"; + protected const TAG_STATE_FINALISATION = "6"; - public const TAG_BORDER_BLOCKS = "8"; - public const TAG_HARDCODED_SPAWNERS = "9"; + protected const TAG_BORDER_BLOCKS = "8"; + protected const TAG_HARDCODED_SPAWNERS = "9"; - public const FINALISATION_NEEDS_INSTATICKING = 0; - public const FINALISATION_NEEDS_POPULATION = 1; - public const FINALISATION_DONE = 2; + protected const FINALISATION_NEEDS_INSTATICKING = 0; + protected const FINALISATION_NEEDS_POPULATION = 1; + protected const FINALISATION_DONE = 2; - public const TAG_VERSION = "v"; + protected const TAG_VERSION = "v"; - public const ENTRY_FLAT_WORLD_LAYERS = "game_flatworldlayers"; + protected const ENTRY_FLAT_WORLD_LAYERS = "game_flatworldlayers"; - public const CURRENT_LEVEL_CHUNK_VERSION = 7; - public const CURRENT_LEVEL_SUBCHUNK_VERSION = 0; + protected const CURRENT_LEVEL_CHUNK_VERSION = 7; + protected const CURRENT_LEVEL_SUBCHUNK_VERSION = 0; /** @var \LevelDB */ protected $db; diff --git a/src/pocketmine/level/format/io/region/RegionLoader.php b/src/pocketmine/level/format/io/region/RegionLoader.php index baa84cfe0e..50ad077488 100644 --- a/src/pocketmine/level/format/io/region/RegionLoader.php +++ b/src/pocketmine/level/format/io/region/RegionLoader.php @@ -33,8 +33,8 @@ class RegionLoader{ public const COMPRESSION_GZIP = 1; public const COMPRESSION_ZLIB = 2; - public const MAX_SECTOR_LENGTH = 256 << 12; //256 sectors, (1 MiB) - public const REGION_HEADER_LENGTH = 8192; //4096 location table + 4096 timestamps + private const MAX_SECTOR_LENGTH = 256 << 12; //256 sectors, (1 MiB) + private const REGION_HEADER_LENGTH = 8192; //4096 location table + 4096 timestamps public static $COMPRESSION_LEVEL = 7; From 78bb0145aa6f56a10dea6b143dee980d45fe0de2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 5 Oct 2018 18:31:06 +0100 Subject: [PATCH 0210/3224] Remove unused imports from Block namespace --- src/pocketmine/block/DoublePlant.php | 1 - src/pocketmine/block/Stone.php | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index f9ab9bf4e2..594e901ea2 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; diff --git a/src/pocketmine/block/Stone.php b/src/pocketmine/block/Stone.php index 2492c0d60e..47272c2f86 100644 --- a/src/pocketmine/block/Stone.php +++ b/src/pocketmine/block/Stone.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; class Stone extends Solid{ From 785df3789d4b2f65056a23f27240d0d281784b68 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Oct 2018 14:46:38 +0100 Subject: [PATCH 0211/3224] Remove now-unused internal function --- src/pocketmine/Server.php | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 65adaa4a6b..e4cdb7450e 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -123,9 +123,6 @@ class Server{ /** @var Server */ private static $instance = null; - /** @var \Threaded */ - private static $sleeper = null; - /** @var SleeperHandler */ private $tickSleeper; @@ -1402,12 +1399,6 @@ class Server{ return self::$instance; } - public static function microSleep(int $microseconds){ - Server::$sleeper->synchronized(function(int $ms){ - Server::$sleeper->wait($ms); - }, $microseconds); - } - /** * @param \ClassLoader $autoloader * @param \AttachableThreadedLogger $logger @@ -1419,7 +1410,7 @@ class Server{ throw new \InvalidStateException("Only one server instance can exist at once"); } self::$instance = $this; - self::$sleeper = new \Threaded; + $this->tickSleeper = new SleeperHandler(); $this->autoloader = $autoloader; $this->logger = $logger; From 933806139062e954a37a54a6d8ee658e440d0394 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Oct 2018 15:10:43 +0100 Subject: [PATCH 0212/3224] Update composer lock dependencies --- composer.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/composer.lock b/composer.lock index 4bfccbac99..5a9baaa316 100644 --- a/composer.lock +++ b/composer.lock @@ -187,12 +187,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "e5fd6cf9e71c285ff24bb3a3cbc22a15a8e73ac7" + "reference": "115700a493fc38fe8886739c20c4303eeb1cd182" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/e5fd6cf9e71c285ff24bb3a3cbc22a15a8e73ac7", - "reference": "e5fd6cf9e71c285ff24bb3a3cbc22a15a8e73ac7", + "url": "https://api.github.com/repos/pmmp/Math/zipball/115700a493fc38fe8886739c20c4303eeb1cd182", + "reference": "115700a493fc38fe8886739c20c4303eeb1cd182", "shasum": "" }, "require": { @@ -218,7 +218,7 @@ "source": "https://github.com/pmmp/Math/tree/master", "issues": "https://github.com/pmmp/Math/issues" }, - "time": "2018-09-16T16:36:04+00:00" + "time": "2018-09-23T17:50:23+00:00" }, { "name": "pocketmine/nbt", @@ -337,16 +337,16 @@ }, { "name": "pocketmine/spl", - "version": "0.3.1", + "version": "0.3.2", "source": { "type": "git", "url": "https://github.com/pmmp/SPL.git", - "reference": "ca3912099543ddc4b4b14f40e258d84ca547dfa5" + "reference": "7fd53857cd000491ba69e8db865792a024dd2c49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/SPL/zipball/ca3912099543ddc4b4b14f40e258d84ca547dfa5", - "reference": "ca3912099543ddc4b4b14f40e258d84ca547dfa5", + "url": "https://api.github.com/repos/pmmp/SPL/zipball/7fd53857cd000491ba69e8db865792a024dd2c49", + "reference": "7fd53857cd000491ba69e8db865792a024dd2c49", "shasum": "" }, "type": "library", @@ -365,7 +365,7 @@ "support": { "source": "https://github.com/pmmp/SPL/tree/master" }, - "time": "2018-06-09T17:30:36+00:00" + "time": "2018-08-12T15:17:39+00:00" } ], "packages-dev": [], From a430f7f4f71e58dfcb0377137bbecea0b3904f98 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Oct 2018 17:33:28 +0100 Subject: [PATCH 0213/3224] Allow static properties and state masks to vary based on variant --- src/pocketmine/block/BlockFactory.php | 133 ++++++++------------- src/pocketmine/block/Grass.php | 4 +- src/pocketmine/block/Purpur.php | 4 - src/pocketmine/block/Quartz.php | 4 - src/pocketmine/level/Explosion.php | 8 +- src/pocketmine/level/Level.php | 7 +- src/pocketmine/level/format/Chunk.php | 4 +- src/pocketmine/level/light/LightUpdate.php | 2 +- 8 files changed, 64 insertions(+), 102 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index b105d4315c..28aa85cf09 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -35,8 +35,6 @@ use pocketmine\level\Position; class BlockFactory{ /** @var \SplFixedArray */ private static $fullList = null; - /** @var \SplFixedArray|\Closure[] */ - private static $getInterceptors = null; /** @var \SplFixedArray */ public static $lightFilter = null; @@ -63,13 +61,12 @@ class BlockFactory{ */ public static function init() : void{ self::$fullList = new \SplFixedArray(8192); - self::$getInterceptors = new \SplFixedArray(8192); - self::$lightFilter = \SplFixedArray::fromArray(array_fill(0, 512, 1)); - self::$diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 512, false)); - self::$blastResistance = \SplFixedArray::fromArray(array_fill(0, 512, 0)); + self::$lightFilter = \SplFixedArray::fromArray(array_fill(0, 8192, 1)); + self::$diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 8192, false)); + self::$blastResistance = \SplFixedArray::fromArray(array_fill(0, 8192, 0)); - self::$stateMasks = new \SplFixedArray(512); + self::$stateMasks = new \SplFixedArray(8192); self::registerBlock(new Air()); @@ -212,13 +209,10 @@ class BlockFactory{ self::registerBlock(new Farmland()); self::registerBlock(new Furnace()); - self::addGetInterceptor(Block::BURNING_FURNACE, 0, function() : Block{ - $block = self::get(Block::FURNACE); - if($block instanceof Furnace){ - $block->setLit(); - } - return $block; - }); + + $furnace = new Furnace(); + $furnace->setLit(); + self::registerBlock($furnace); //flattening hack self::registerBlock(new SignPost()); self::registerBlock(new WoodenDoor(Block::OAK_DOOR_BLOCK, 0, "Oak Door", Item::OAK_DOOR)); @@ -231,22 +225,15 @@ class BlockFactory{ self::registerBlock(new IronDoor()); self::registerBlock(new WoodenPressurePlate()); self::registerBlock(new RedstoneOre()); - self::addGetInterceptor(Block::GLOWING_REDSTONE_ORE, 0, function() : Block{ - $block = self::get(Block::REDSTONE_ORE); - if($block instanceof RedstoneOre){ - $block->setLit(); - } - return $block; - }); + + $litRedstone = new RedstoneOre(); + $litRedstone->setLit(); + self::registerBlock($litRedstone); //flattening hack self::registerBlock(new RedstoneTorch()); - self::addGetInterceptor(Block::UNLIT_REDSTONE_TORCH, 0, function() : Block{ - $block = self::get(Block::REDSTONE_TORCH); - if($block instanceof RedstoneTorch){ - $block->setLit(false); //default state is lit - } - return $block; - }); + $unlitRedstoneTorch = new RedstoneTorch(); + $unlitRedstoneTorch->setLit(false); + self::registerBlock($unlitRedstoneTorch); //flattening hack self::registerBlock(new StoneButton()); self::registerBlock(new SnowLayer()); @@ -300,13 +287,9 @@ class BlockFactory{ self::registerBlock(new EndStone()); //TODO: DRAGON_EGG self::registerBlock(new RedstoneLamp()); - self::addGetInterceptor(Block::LIT_REDSTONE_LAMP, 0, function() : Block{ - $block = self::get(Block::REDSTONE_LAMP); - if($block instanceof RedstoneLamp){ - $block->setLit(); - } - return $block; - }); + $litLamp = new RedstoneLamp(); + $litLamp->setLit(); + self::registerBlock($litLamp); //flattening hack //TODO: DROPPER self::registerBlock(new ActivatorRail()); @@ -342,13 +325,9 @@ class BlockFactory{ //TODO: COMPARATOR_BLOCK //TODO: POWERED_COMPARATOR self::registerBlock(new DaylightSensor()); - self::addGetInterceptor(Block::DAYLIGHT_SENSOR_INVERTED, 0, function() : Block{ - $block = self::get(Block::DAYLIGHT_SENSOR); - if($block instanceof DaylightSensor){ - $block->setInverted(); - } - return $block; - }); + $invertedSensor = new DaylightSensor(); + $invertedSensor->setInverted(); + self::registerBlock($invertedSensor); //flattening hack self::registerBlock(new Redstone()); self::registerBlock(new NetherQuartzOre()); @@ -479,18 +458,31 @@ class BlockFactory{ $id = $block->getId(); $variant = $block->getVariant(); - if(!$override and self::isRegistered($id, $variant)){ - throw new \RuntimeException("Trying to overwrite an already registered block"); + + $stateMask = $block->getStateBitmask(); + if(($variant & $stateMask) !== 0){ + throw new \InvalidArgumentException("Block variant collides with state bitmask"); } - if(self::$stateMasks[$id] !== null and self::$stateMasks[$id] !== $block->getStateBitmask()){ - throw new \InvalidArgumentException("Blocks with the same ID must have the same state bitmask"); - } + for($m = $variant; $m <= ($variant | $stateMask); ++$m){ + if(($m & ~$stateMask) !== $variant){ + continue; + } - self::$fullList[($id << 4) | $variant] = clone $block; - if($variant === 0){ - //TODO: allow these to differ for different variants - self::fillStaticArrays($id, $block); + if(!$override and self::isRegistered($id, $m)){ + throw new \InvalidArgumentException("Block registration " . get_class($block) . " has states which conflict with other blocks"); + } + + $index = ($id << 4) | $m; + + $v = clone $block; + $v->readStateFromMeta($m & $stateMask); + + self::$fullList[$index] = $v; + self::$stateMasks[$index] = $stateMask; + self::$lightFilter[$index] = min(15, $v->getLightFilter() + 1); //opacity plus 1 standard light filter + self::$diffusesSkyLight[$index] = $v->diffusesSkyLight(); + self::$blastResistance[$index] = $v->getBlastResistance(); } } @@ -508,27 +500,18 @@ class BlockFactory{ throw new \InvalidArgumentException("Block meta value $meta is out of bounds"); } - $stateMask = self::getStateMask($id); - $variant = $meta & ~$stateMask; - $state = $meta & $stateMask; - - $index = ($id << 4) | $variant; - /** @var Block|null $block */ $block = null; try{ - if(self::$getInterceptors[$index] !== null){ - $block = (self::$getInterceptors[$index])(); - }elseif(self::$fullList[$index] !== null){ + $index = ($id << 4) | $meta; + if(self::$fullList[$index] !== null){ $block = clone self::$fullList[$index]; } }catch(\RuntimeException $e){ throw new \InvalidArgumentException("Block ID $id is out of bounds"); } - if($block !== null){ - $block->readStateFromMeta($state); - }else{ + if($block === null){ $block = new UnknownBlock($id, $meta); } @@ -542,20 +525,8 @@ class BlockFactory{ return $block; } - public static function addGetInterceptor(int $id, int $variant, \Closure $interceptor) : void{ - $block = $interceptor(); - if(!($block instanceof Block)){ - throw new \InvalidArgumentException("Interceptor must return an instance of " . Block::class); - } - self::$getInterceptors[($id << 4) | $variant] = $interceptor; - self::fillStaticArrays($id, $block); - } - - private static function fillStaticArrays(int $id, Block $block) : void{ - self::$lightFilter[$id] = min(15, $block->getLightFilter() + 1); //opacity plus 1 standard light filter - self::$diffusesSkyLight[$id] = $block->diffusesSkyLight(); - self::$blastResistance[$id] = $block->getBlastResistance(); - self::$stateMasks[$id] = $block->getStateBitmask(); + public static function fromFullBlock(int $fullState, ?Position $pos = null) : Block{ + return self::get($fullState >> 4, $fullState & 0xf, $pos); } public static function getStateMask(int $id) : int{ @@ -563,15 +534,15 @@ class BlockFactory{ } /** - * Returns whether a specified block ID is already registered in the block factory. + * Returns whether a specified block state is already registered in the block factory. * * @param int $id - * @param int $variant + * @param int $meta * * @return bool */ - public static function isRegistered(int $id, int $variant = 0) : bool{ - $b = self::$fullList[($id << 4) | $variant]; + public static function isRegistered(int $id, int $meta = 0) : bool{ + $b = self::$fullList[($id << 4) | $meta]; return $b !== null and !($b instanceof UnknownBlock); } diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index 4332cc0d55..fd1f47b9e7 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -65,7 +65,7 @@ class Grass extends Solid{ public function onRandomTick() : void{ $lightAbove = $this->level->getFullLightAt($this->x, $this->y + 1, $this->z); - if($lightAbove < 4 and BlockFactory::$lightFilter[$this->level->getBlockIdAt($this->x, $this->y + 1, $this->z)] >= 3){ //2 plus 1 standard filter amount + if($lightAbove < 4 and BlockFactory::$lightFilter[$this->level->getFullBlock($this->x, $this->y + 1, $this->z)] >= 3){ //2 plus 1 standard filter amount //grass dies $ev = new BlockSpreadEvent($this, $this, BlockFactory::get(Block::DIRT)); $ev->call(); @@ -82,7 +82,7 @@ class Grass extends Solid{ $this->level->getBlockIdAt($x, $y, $z) !== Block::DIRT or $this->level->getBlockDataAt($x, $y, $z) === 1 or $this->level->getFullLightAt($x, $y + 1, $z) < 4 or - BlockFactory::$lightFilter[$this->level->getBlockIdAt($x, $y + 1, $z)] >= 3 + BlockFactory::$lightFilter[$this->level->getFullBlock($x, $y + 1, $z)] >= 3 ){ continue; } diff --git a/src/pocketmine/block/Purpur.php b/src/pocketmine/block/Purpur.php index 5c6687aed4..43db8c9aa1 100644 --- a/src/pocketmine/block/Purpur.php +++ b/src/pocketmine/block/Purpur.php @@ -42,8 +42,4 @@ class Purpur extends Solid{ public function getBlastResistance() : float{ return 30; } - - public function getStateBitmask() : int{ - return 0b1100; //HACK: needs to be consistent for blocks with the same ID :( - } } diff --git a/src/pocketmine/block/Quartz.php b/src/pocketmine/block/Quartz.php index 7c5e3c4e58..926a20a357 100644 --- a/src/pocketmine/block/Quartz.php +++ b/src/pocketmine/block/Quartz.php @@ -42,8 +42,4 @@ class Quartz extends Solid{ public function getToolHarvestLevel() : int{ return TieredTool::TIER_WOODEN; } - - public function getStateBitmask() : int{ - return 0b1100; //HACK: needs to be consistent for blocks with the same ID :( - } } diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index 3eef24d07c..5c83389869 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -123,13 +123,13 @@ class Explosion{ continue; } - $blockId = $this->subChunkHandler->currentSubChunk->getBlockId($vBlock->x & 0x0f, $vBlock->y & 0x0f, $vBlock->z & 0x0f); + $state = $this->subChunkHandler->currentSubChunk->getFullBlock($vBlock->x & 0x0f, $vBlock->y & 0x0f, $vBlock->z & 0x0f); - if($blockId !== 0){ - $blastForce -= (BlockFactory::$blastResistance[$blockId] / 5 + 0.3) * $this->stepLen; + if($state !== 0){ + $blastForce -= (BlockFactory::$blastResistance[$state] / 5 + 0.3) * $this->stepLen; if($blastForce > 0){ if(!isset($this->affectedBlocks[$index = Level::blockHash($vBlock->x, $vBlock->y, $vBlock->z)])){ - $this->affectedBlocks[$index] = BlockFactory::get($blockId, $this->subChunkHandler->currentSubChunk->getBlockData($vBlock->x & 0x0f, $vBlock->y & 0x0f, $vBlock->z & 0x0f), $vBlock); + $this->affectedBlocks[$index] = BlockFactory::get($state >> 4, $state & 0xf, $vBlock); } } } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 2dd638d9fa..d040eba907 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -983,12 +983,11 @@ class Level implements ChunkManager, Metadatable{ $y = ($k >> 4) & 0x0f; $z = ($k >> 8) & 0x0f; - $blockId = $subChunk->getBlockId($x, $y, $z); - $meta = $subChunk->getBlockData($x, $y, $z); + $state = $subChunk->getFullBlock($x, $y, $z); - if($this->randomTickBlocks[($blockId << 4) | ($meta & ~BlockFactory::getStateMask($blockId))]){ + if($this->randomTickBlocks[$state & ~BlockFactory::getStateMask($state >> 4)]){ /** @var Block $block */ - $block = BlockFactory::get($blockId, $meta); + $block = BlockFactory::fromFullBlock($state); $block->x = $chunkX * 16 + $x; $block->y = ($Y << 4) + $y; diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index 01835e32d5..398229cf6c 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -394,7 +394,7 @@ class Chunk{ public function recalculateHeightMapColumn(int $x, int $z) : int{ $max = $this->getHighestBlockAt($x, $z); for($y = $max; $y >= 0; --$y){ - if(BlockFactory::$lightFilter[$id = $this->getBlockId($x, $y, $z)] > 1 or BlockFactory::$diffusesSkyLight[$id]){ + if(BlockFactory::$lightFilter[$state = $this->getFullBlock($x, $y, $z)] > 1 or BlockFactory::$diffusesSkyLight[$state]){ break; } } @@ -426,7 +426,7 @@ class Chunk{ $light = 15; for(; $y >= 0; --$y){ if($light > 0){ - $light -= BlockFactory::$lightFilter[$this->getBlockId($x, $y, $z)]; + $light -= BlockFactory::$lightFilter[$this->getFullBlock($x, $y, $z)]; if($light <= 0){ break; } diff --git a/src/pocketmine/level/light/LightUpdate.php b/src/pocketmine/level/light/LightUpdate.php index 2ee6d3479d..7dec14ccd5 100644 --- a/src/pocketmine/level/light/LightUpdate.php +++ b/src/pocketmine/level/light/LightUpdate.php @@ -157,7 +157,7 @@ abstract class LightUpdate{ protected function computeSpreadLight(int $x, int $y, int $z, int $newAdjacentLevel){ $current = $this->getLight($x, $y, $z); - $potentialLight = $newAdjacentLevel - BlockFactory::$lightFilter[$this->subChunkHandler->currentSubChunk->getBlockId($x & 0x0f, $y & 0x0f, $z & 0x0f)]; + $potentialLight = $newAdjacentLevel - BlockFactory::$lightFilter[$this->subChunkHandler->currentSubChunk->getFullBlock($x & 0x0f, $y & 0x0f, $z & 0x0f)]; if($current < $potentialLight){ $this->setLight($x, $y, $z, $potentialLight); From cdb17b1ceed41fae74be405c138c691f5fe09b9d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Oct 2018 17:39:11 +0100 Subject: [PATCH 0214/3224] Fixed broken test --- tests/phpunit/block/BlockTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index 2fae84449b..d092023708 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -36,7 +36,7 @@ class BlockTest extends TestCase{ */ public function testAccidentalOverrideBlock() : void{ $block = new MyCustomBlock(); - $this->expectException(\RuntimeException::class); + $this->expectException(\InvalidArgumentException::class); BlockFactory::registerBlock($block); } From 14ef4558c22d0ab0af9c8ca1aeb5de88e94e1334 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Oct 2018 19:06:49 +0100 Subject: [PATCH 0215/3224] Allow BlockFactory to handle position setting of newly created blocks --- src/pocketmine/level/Level.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index d040eba907..c0d448749c 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -987,12 +987,11 @@ class Level implements ChunkManager, Metadatable{ if($this->randomTickBlocks[$state & ~BlockFactory::getStateMask($state >> 4)]){ /** @var Block $block */ - $block = BlockFactory::fromFullBlock($state); - - $block->x = $chunkX * 16 + $x; - $block->y = ($Y << 4) + $y; - $block->z = $chunkZ * 16 + $z; - $block->level = $this; + $block = BlockFactory::fromFullBlock($state, $this->temporalPosition->setComponents( + $chunkX * 16 + $x, + ($Y << 4) + $y, + $chunkZ * 16 + $z + )); $block->onRandomTick(); } } From 5fb782548516316475fd286c48ea2a34c52903ed Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Oct 2018 20:09:11 +0100 Subject: [PATCH 0216/3224] Flatten Item variants, remove Item->setDamage() --- src/pocketmine/entity/Entity.php | 9 ++++ src/pocketmine/item/Bucket.php | 19 +++++--- src/pocketmine/item/Coal.php | 6 --- src/pocketmine/item/Durable.php | 19 +++++++- src/pocketmine/item/Item.php | 21 +++------ src/pocketmine/item/ItemBlock.php | 2 +- src/pocketmine/item/ItemFactory.php | 68 ++++++++++++++++++++++------- src/pocketmine/item/Potion.php | 40 +++++++++++++++++ src/pocketmine/item/SpawnEgg.php | 3 -- 9 files changed, 138 insertions(+), 49 deletions(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 7bf12c7236..b1820ca529 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -329,6 +329,15 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ self::$saveNames[$className] = $saveNames; } + /** + * Returns an array of all registered entity classpaths. + * + * @return string[] + */ + public static function getKnownEntityTypes() : array{ + return array_unique(self::$knownEntities); + } + /** * Helper function which creates minimal NBT needed to spawn an entity. * diff --git a/src/pocketmine/item/Bucket.php b/src/pocketmine/item/Bucket.php index ca3551d95d..254c4af60b 100644 --- a/src/pocketmine/item/Bucket.php +++ b/src/pocketmine/item/Bucket.php @@ -34,16 +34,20 @@ use pocketmine\math\Vector3; use pocketmine\Player; class Bucket extends Item implements Consumable{ - public function __construct(int $meta = 0){ - parent::__construct(self::BUCKET, $meta, "Bucket"); + /** @var int|null */ + protected $blockId; + + public function __construct(int $id, int $meta, string $name, ?int $blockId){ + parent::__construct($id, $meta, $name); + $this->blockId = $blockId; } public function getMaxStackSize() : int{ - return $this->meta === Block::AIR ? 16 : 1; //empty buckets stack to 16 + return $this->blockId === Block::AIR ? 16 : 1; //empty buckets stack to 16 } public function getFuelTime() : int{ - if($this->meta === Block::LAVA or $this->meta === Block::FLOWING_LAVA){ + if($this->blockId === Block::LAVA or $this->blockId === Block::FLOWING_LAVA){ return 20000; } @@ -51,7 +55,10 @@ class Bucket extends Item implements Consumable{ } public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : bool{ - $resultBlock = BlockFactory::get($this->meta); + if($this->blockId === null){ + return false; + } + $resultBlock = BlockFactory::get($this->blockId); if($resultBlock instanceof Air){ if($blockClicked instanceof Liquid and $blockClicked->isSource()){ @@ -108,7 +115,7 @@ class Bucket extends Item implements Consumable{ } public function canBeConsumed() : bool{ - return $this->meta === 1; //Milk + return $this->blockId === null; //Milk } public function onConsume(Living $consumer){ diff --git a/src/pocketmine/item/Coal.php b/src/pocketmine/item/Coal.php index 89c214b3bd..ebdb65ee37 100644 --- a/src/pocketmine/item/Coal.php +++ b/src/pocketmine/item/Coal.php @@ -25,12 +25,6 @@ namespace pocketmine\item; class Coal extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::COAL, $meta, "Coal"); - if($this->meta === 1){ - $this->name = "Charcoal"; - } - } public function getFuelTime() : int{ return 1600; diff --git a/src/pocketmine/item/Durable.php b/src/pocketmine/item/Durable.php index 76e6927b39..e0e1d00e67 100644 --- a/src/pocketmine/item/Durable.php +++ b/src/pocketmine/item/Durable.php @@ -28,6 +28,9 @@ use pocketmine\nbt\tag\ByteTag; abstract class Durable extends Item{ + /** @var int */ + protected $damage = 0; + /** * Returns whether this item will take damage when used. * @return bool @@ -57,7 +60,7 @@ abstract class Durable extends Item{ $amount -= $this->getUnbreakingDamageReduction($amount); - $this->meta = min($this->meta + $amount, $this->getMaxDurability()); + $this->damage = min($this->damage + $amount, $this->getMaxDurability()); if($this->isBroken()){ $this->onBroken(); } @@ -65,6 +68,18 @@ abstract class Durable extends Item{ return true; } + public function getDamage() : int{ + return $this->damage; + } + + public function setDamage(int $meta) : Item{ + if($meta < 0 or $meta > $this->getMaxDurability()){ + throw new \InvalidArgumentException("Damage must be in range 0 - " , $this->getMaxDurability()); + } + $this->damage = $meta; + return $this; + } + protected function getUnbreakingDamageReduction(int $amount) : int{ if(($unbreakingLevel = $this->getEnchantmentLevel(Enchantment::UNBREAKING)) > 0){ $negated = 0; @@ -101,6 +116,6 @@ abstract class Durable extends Item{ * @return bool */ public function isBroken() : bool{ - return $this->meta >= $this->getMaxDurability(); + return $this->damage >= $this->getMaxDurability(); } } diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 7e71829141..2440bf97e0 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -200,7 +200,7 @@ class Item implements ItemIds, \JsonSerializable{ throw new \InvalidArgumentException("ID must be in range " . -0x8000 . " - " . 0x7fff); } $this->id = $id; - $this->setDamage($meta); + $this->meta = $meta !== -1 ? $meta & 0x7FFF : -1; $this->name = $name; } @@ -663,20 +663,10 @@ class Item implements ItemIds, \JsonSerializable{ /** * @return int */ - final public function getDamage() : int{ + public function getDamage() : int{ return $this->meta; } - /** - * @param int $meta - * @return Item - */ - public function setDamage(int $meta) : Item{ - $this->meta = $meta !== -1 ? $meta & 0x7FFF : -1; - - return $this; - } - /** * Returns whether this item can match any item with an equivalent ID with any meta value. * Used in crafting recipes which accept multiple variants of the same item, for example crafting tables recipes. @@ -856,7 +846,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return string */ final public function __toString() : string{ - return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->meta) . ")x" . $this->count . ($this->hasCompoundTag() ? " tags:0x" . bin2hex($this->getCompoundTag()) : ""); + return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->getDamage()) . ")x" . $this->count . ($this->hasCompoundTag() ? " tags:0x" . bin2hex($this->getCompoundTag()) : ""); } /** @@ -921,7 +911,7 @@ class Item implements ItemIds, \JsonSerializable{ $result = new CompoundTag($tagName, [ new ShortTag("id", $this->id), new ByteTag("Count", Binary::signByte($this->count)), - new ShortTag("Damage", $this->meta) + new ShortTag("Damage", $this->getDamage()) ]); if($this->hasCompoundTag()){ @@ -957,12 +947,11 @@ class Item implements ItemIds, \JsonSerializable{ $item = ItemFactory::get($idTag->getValue(), $meta, $count); }elseif($idTag instanceof StringTag){ //PC item save format try{ - $item = ItemFactory::fromString($idTag->getValue()); + $item = ItemFactory::fromString($idTag->getValue() . ":$meta"); }catch(\InvalidArgumentException $e){ //TODO: improve error handling return ItemFactory::get(Item::AIR, 0, 0); } - $item->setDamage($meta); $item->setCount($count); }else{ throw new \InvalidArgumentException("Item CompoundTag ID must be an instance of StringTag or ShortTag, " . get_class($idTag) . " given"); diff --git a/src/pocketmine/item/ItemBlock.php b/src/pocketmine/item/ItemBlock.php index da455e517d..a0c4375f58 100644 --- a/src/pocketmine/item/ItemBlock.php +++ b/src/pocketmine/item/ItemBlock.php @@ -46,7 +46,7 @@ class ItemBlock extends Item{ $blockId = 255 - $blockId; } $this->blockId = $blockId; - $this->setDamage($meta); + $this->meta = $meta; parent::__construct($itemId ?? $blockId, $meta, $this->getBlock()->getName()); } diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 8a0c24e46e..89730fa96f 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -25,6 +25,8 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\entity\Entity; +use pocketmine\entity\Living; use pocketmine\nbt\tag\CompoundTag; /** @@ -45,7 +47,8 @@ class ItemFactory{ self::registerItem(new Apple()); self::registerItem(new Bow()); self::registerItem(new Arrow()); - self::registerItem(new Coal()); + self::registerItem(new Coal(Item::COAL, 0, "Coal")); + self::registerItem(new Coal(Item::COAL, 1, "Charcoal")); self::registerItem(new Item(Item::DIAMOND, 0, "Diamond")); self::registerItem(new Item(Item::IRON_INGOT, 0, "Iron Ingot")); self::registerItem(new Item(Item::GOLD_INGOT, 0, "Gold Ingot")); @@ -107,13 +110,19 @@ class ItemFactory{ self::registerItem(new GoldenApple()); self::registerItem(new Sign()); self::registerItem(new ItemBlock(Block::OAK_DOOR_BLOCK, 0, Item::OAK_DOOR)); - self::registerItem(new Bucket()); + self::registerItem(new Bucket(Item::BUCKET, 0, "Bucket", Block::AIR)); + self::registerItem(new Bucket(Item::BUCKET, 1, "Milk Bucket", null)); //TODO: this ought to get its own class, it has completely different behaviour + //TODO: fix metadata for buckets with still liquid in them + //the meta values are intentionally hardcoded because block IDs will change in the future + self::registerItem(new Bucket(Item::BUCKET, 8, "Water Bucket", Block::FLOWING_WATER)); + self::registerItem(new Bucket(Item::BUCKET, 10, "Lava Bucket", Block::FLOWING_LAVA)); self::registerItem(new Minecart()); //TODO: SADDLE self::registerItem(new ItemBlock(Block::IRON_DOOR_BLOCK, 0, Item::IRON_DOOR)); self::registerItem(new Redstone()); self::registerItem(new Snowball()); + self::registerItem(new Boat()); self::registerItem(new Item(Item::LEATHER, 0, "Leather")); //TODO: KELP @@ -132,7 +141,10 @@ class ItemFactory{ self::registerItem(new Item(Item::GLOWSTONE_DUST, 0, "Glowstone Dust")); self::registerItem(new RawFish()); self::registerItem(new CookedFish()); - self::registerItem(new Dye()); + for($i = 0; $i < 16; ++$i){ + //TODO: add colour constants (this is messy) + self::registerItem(new Dye($i)); + } self::registerItem(new Item(Item::BONE, 0, "Bone")); self::registerItem(new Item(Item::SUGAR, 0, "Sugar")); self::registerItem(new ItemBlock(Block::CAKE_BLOCK, 0, Item::CAKE)); @@ -154,7 +166,12 @@ class ItemFactory{ self::registerItem(new Item(Item::GHAST_TEAR, 0, "Ghast Tear")); self::registerItem(new Item(Item::GOLD_NUGGET, 0, "Gold Nugget")); self::registerItem(new ItemBlock(Block::NETHER_WART_PLANT, 0, Item::NETHER_WART)); - self::registerItem(new Potion()); + + foreach(Potion::ALL as $type){ + self::registerItem(new Potion($type)); + self::registerItem(new SplashPotion($type)); + //TODO: LINGERING_POTION + } self::registerItem(new GlassBottle()); self::registerItem(new SpiderEye()); self::registerItem(new Item(Item::FERMENTED_SPIDER_EYE, 0, "Fermented Spider Eye")); @@ -164,7 +181,14 @@ class ItemFactory{ self::registerItem(new ItemBlock(Block::CAULDRON_BLOCK, 0, Item::CAULDRON)); //TODO: ENDER_EYE self::registerItem(new Item(Item::GLISTERING_MELON, 0, "Glistering Melon")); - self::registerItem(new SpawnEgg()); + + foreach(Entity::getKnownEntityTypes() as $className){ + /** @var Living $className */ + if(is_a($className, Living::class, true) and $className::NETWORK_ID !== -1){ + self::registerItem(new SpawnEgg(Item::SPAWN_EGG, $className::NETWORK_ID, "Spawn Egg")); + } + } + self::registerItem(new ExperienceBottle()); //TODO: FIREBALL self::registerItem(new WritableBook()); @@ -217,9 +241,7 @@ class ItemFactory{ self::registerItem(new Item(Item::CHORUS_FRUIT_POPPED, 0, "Popped Chorus Fruit")); self::registerItem(new Item(Item::DRAGON_BREATH, 0, "Dragon's Breath")); - self::registerItem(new SplashPotion()); - //TODO: LINGERING_POTION //TODO: SPARKLER //TODO: COMMAND_BLOCK_MINECART //TODO: ELYTRA @@ -279,11 +301,19 @@ class ItemFactory{ */ public static function registerItem(Item $item, bool $override = false){ $id = $item->getId(); - if(!$override and self::isRegistered($id)){ + $variant = $item->getDamage(); + + if(!$override and self::isRegistered($id, $variant)){ throw new \RuntimeException("Trying to overwrite an already registered item"); } - self::$list[self::getListOffset($id)] = clone $item; + $offset = self::getListOffset($id); + $sublist = self::$list[$offset] ?? new \SplFixedArray(); + if($sublist->getSize() < $variant + 1){ + $sublist->setSize($variant + 1); + } + $sublist[$variant] = clone $item; + self::$list[$offset] = $sublist; } /** @@ -303,24 +333,28 @@ class ItemFactory{ } try{ + $sublist = self::$list[self::getListOffset($id)]; + /** @var Item|null $listed */ - $listed = self::$list[self::getListOffset($id)]; - if($listed !== null){ - $item = clone $listed; + if($sublist !== null and isset($sublist[$meta])){ + $item = clone $sublist[$meta]; }elseif($id < 256){ //intentionally includes negatives, for extended block IDs /* Blocks must have a damage value 0-15, but items can have damage value -1 to indicate that they are * crafting ingredients with any-damage. */ $item = new ItemBlock($id, $meta); }else{ + //negative damage values will fallthru to here, to avoid crazy shit with crafting wildcard hacks $item = new Item($id, $meta); } }catch(\RuntimeException $e){ throw new \InvalidArgumentException("Item ID $id is invalid or out of bounds"); } - $item->setDamage($meta); $item->setCount($count); $item->setCompoundTag($tags); + if($item instanceof Durable){ //nasty, but necessary for BC reasons + $item->setDamage($meta); + } return $item; } @@ -376,13 +410,17 @@ class ItemFactory{ * Returns whether the specified item ID is already registered in the item factory. * * @param int $id + * @param int $variant + * * @return bool */ - public static function isRegistered(int $id) : bool{ + public static function isRegistered(int $id, int $variant = 0) : bool{ if($id < 256){ return BlockFactory::isRegistered($id); } - return self::$list[self::getListOffset($id)] !== null; + + $sublist = self::$list[self::getListOffset($id)]; + return $sublist !== null and isset($sublist[$variant]); } private static function getListOffset(int $id) : int{ diff --git a/src/pocketmine/item/Potion.php b/src/pocketmine/item/Potion.php index 6a04fe73c1..7df7eafe23 100644 --- a/src/pocketmine/item/Potion.php +++ b/src/pocketmine/item/Potion.php @@ -67,6 +67,46 @@ class Potion extends Item implements Consumable{ public const LONG_WEAKNESS = 35; public const WITHER = 36; + public const ALL = [ + self::WATER, + self::MUNDANE, + self::LONG_MUNDANE, + self::THICK, + self::AWKWARD, + self::NIGHT_VISION, + self::LONG_NIGHT_VISION, + self::INVISIBILITY, + self::LONG_INVISIBILITY, + self::LEAPING, + self::LONG_LEAPING, + self::STRONG_LEAPING, + self::FIRE_RESISTANCE, + self::LONG_FIRE_RESISTANCE, + self::SWIFTNESS, + self::LONG_SWIFTNESS, + self::STRONG_SWIFTNESS, + self::SLOWNESS, + self::LONG_SLOWNESS, + self::WATER_BREATHING, + self::LONG_WATER_BREATHING, + self::HEALING, + self::STRONG_HEALING, + self::HARMING, + self::STRONG_HARMING, + self::POISON, + self::LONG_POISON, + self::STRONG_POISON, + self::REGENERATION, + self::LONG_REGENERATION, + self::STRONG_REGENERATION, + self::STRENGTH, + self::LONG_STRENGTH, + self::STRONG_STRENGTH, + self::WEAKNESS, + self::LONG_WEAKNESS, + self::WITHER + ]; + /** * Returns a list of effects applied by potions with the specified ID. * diff --git a/src/pocketmine/item/SpawnEgg.php b/src/pocketmine/item/SpawnEgg.php index 46acc47dea..4eca401f9f 100644 --- a/src/pocketmine/item/SpawnEgg.php +++ b/src/pocketmine/item/SpawnEgg.php @@ -29,9 +29,6 @@ use pocketmine\math\Vector3; use pocketmine\Player; class SpawnEgg extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::SPAWN_EGG, $meta, "Spawn Egg"); - } public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : bool{ $nbt = Entity::createBaseNBT($blockReplace->add(0.5, 0, 0.5), null, lcg_value() * 360, 0); From 36548a335c4c703998ef22a81f81e6d81080b504 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Oct 2018 21:30:21 +0100 Subject: [PATCH 0217/3224] Fixed some items disappeared after 5fb782548516316475fd286c48ea2a34c52903ed --- src/pocketmine/item/ItemFactory.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 89730fa96f..615890ca04 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -28,6 +28,7 @@ use pocketmine\block\BlockFactory; use pocketmine\entity\Entity; use pocketmine\entity\Living; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\tile\Skull; /** * Manages Item instance creation and registration @@ -144,11 +145,13 @@ class ItemFactory{ for($i = 0; $i < 16; ++$i){ //TODO: add colour constants (this is messy) self::registerItem(new Dye($i)); + self::registerItem(new Bed($i)); + self::registerItem(new Banner($i)); } self::registerItem(new Item(Item::BONE, 0, "Bone")); self::registerItem(new Item(Item::SUGAR, 0, "Sugar")); self::registerItem(new ItemBlock(Block::CAKE_BLOCK, 0, Item::CAKE)); - self::registerItem(new Bed()); + self::registerItem(new ItemBlock(Block::REPEATER_BLOCK, 0, Item::REPEATER)); self::registerItem(new Cookie()); //TODO: FILLED_MAP @@ -202,7 +205,14 @@ class ItemFactory{ self::registerItem(new PoisonousPotato()); //TODO: EMPTYMAP self::registerItem(new GoldenCarrot()); - self::registerItem(new ItemBlock(Block::SKULL_BLOCK, 0, Item::SKULL)); + + self::registerItem(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_SKELETON, Item::SKULL)); + self::registerItem(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_WITHER, Item::SKULL)); + self::registerItem(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_ZOMBIE, Item::SKULL)); + self::registerItem(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_HUMAN, Item::SKULL)); + self::registerItem(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_CREEPER, Item::SKULL)); + self::registerItem(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_DRAGON, Item::SKULL)); + //TODO: CARROTONASTICK self::registerItem(new Item(Item::NETHER_STAR, 0, "Nether Star")); self::registerItem(new PumpkinPie()); @@ -246,7 +256,7 @@ class ItemFactory{ //TODO: COMMAND_BLOCK_MINECART //TODO: ELYTRA self::registerItem(new Item(Item::SHULKER_SHELL, 0, "Shulker Shell")); - self::registerItem(new Banner()); + //TODO: MEDICINE //TODO: BALLOON //TODO: RAPID_FERTILIZER From 706082deb1c73727bdefc6d07c5f069fa93b213a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 7 Oct 2018 12:01:43 +0100 Subject: [PATCH 0218/3224] Fixed Flat generator using item ID/damage to build block layers --- src/pocketmine/level/generator/Flat.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/level/generator/Flat.php b/src/pocketmine/level/generator/Flat.php index 2595b8cdeb..145a7bd503 100644 --- a/src/pocketmine/level/generator/Flat.php +++ b/src/pocketmine/level/generator/Flat.php @@ -86,7 +86,7 @@ class Flat extends Generator{ preg_match_all('#^(([0-9]*x|)([0-9]{1,3})(|:[0-9]{0,2}))$#m', str_replace(",", "\n", $layers), $matches); $y = 0; foreach($matches[3] as $i => $b){ - $b = ItemFactory::fromString($b . $matches[4][$i]); + $b = ItemFactory::fromString($b . $matches[4][$i])->getBlock(); $cnt = $matches[2][$i] === "" ? 1 : (int) $matches[2][$i]; for($cY = $y, $y += $cnt; $cY < $y; ++$cY){ $result[$cY] = [$b->getId(), $b->getDamage()]; From 82c718cff0b1eebcb97ec3099c82da18f9183d44 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 7 Oct 2018 14:03:13 +0100 Subject: [PATCH 0219/3224] Split Bucket into multiple classes --- src/pocketmine/item/Bucket.php | 94 ++++++---------------------- src/pocketmine/item/ItemFactory.php | 9 +-- src/pocketmine/item/LiquidBucket.php | 81 ++++++++++++++++++++++++ src/pocketmine/item/MilkBucket.php | 45 +++++++++++++ 4 files changed, 151 insertions(+), 78 deletions(-) create mode 100644 src/pocketmine/item/LiquidBucket.php create mode 100644 src/pocketmine/item/MilkBucket.php diff --git a/src/pocketmine/item/Bucket.php b/src/pocketmine/item/Bucket.php index 254c4af60b..3650e45f3a 100644 --- a/src/pocketmine/item/Bucket.php +++ b/src/pocketmine/item/Bucket.php @@ -23,102 +23,48 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\block\Air; use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\Liquid; -use pocketmine\entity\Living; -use pocketmine\event\player\PlayerBucketEmptyEvent; use pocketmine\event\player\PlayerBucketFillEvent; use pocketmine\math\Vector3; use pocketmine\Player; -class Bucket extends Item implements Consumable{ - /** @var int|null */ - protected $blockId; - - public function __construct(int $id, int $meta, string $name, ?int $blockId){ - parent::__construct($id, $meta, $name); - $this->blockId = $blockId; - } +class Bucket extends Item{ public function getMaxStackSize() : int{ - return $this->blockId === Block::AIR ? 16 : 1; //empty buckets stack to 16 - } - - public function getFuelTime() : int{ - if($this->blockId === Block::LAVA or $this->blockId === Block::FLOWING_LAVA){ - return 20000; - } - - return 0; + return 16; } public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : bool{ - if($this->blockId === null){ - return false; - } - $resultBlock = BlockFactory::get($this->blockId); + //TODO: move this to generic placement logic + if($blockClicked instanceof Liquid and $blockClicked->isSource()){ + $stack = clone $this; + $stack->pop(); - if($resultBlock instanceof Air){ - if($blockClicked instanceof Liquid and $blockClicked->isSource()){ - $stack = clone $this; - - $stack->pop(); - $resultItem = ItemFactory::get(Item::BUCKET, $blockClicked->getFlowingForm()->getId()); - $ev = new PlayerBucketFillEvent($player, $blockReplace, $face, $this, $resultItem); - $ev->call(); - if(!$ev->isCancelled()){ - $player->getLevel()->setBlock($blockClicked, BlockFactory::get(Block::AIR)); - $player->getLevel()->broadcastLevelSoundEvent($blockClicked->add(0.5, 0.5, 0.5), $blockClicked->getBucketFillSound()); - if($player->isSurvival()){ - if($stack->getCount() === 0){ - $player->getInventory()->setItemInHand($ev->getItem()); - }else{ - $player->getInventory()->setItemInHand($stack); - $player->getInventory()->addItem($ev->getItem()); - } - }else{ - $player->getInventory()->addItem($ev->getItem()); - } - - return true; - }else{ - $player->getInventory()->sendContents($player); - } - } - }elseif($resultBlock instanceof Liquid and $blockReplace->canBeReplaced()){ - $ev = new PlayerBucketEmptyEvent($player, $blockReplace, $face, $this, ItemFactory::get(Item::BUCKET)); + $resultItem = ItemFactory::get(Item::BUCKET, $blockClicked->getFlowingForm()->getId()); + $ev = new PlayerBucketFillEvent($player, $blockReplace, $face, $this, $resultItem); $ev->call(); if(!$ev->isCancelled()){ - $player->getLevel()->setBlock($blockReplace, $resultBlock->getFlowingForm()); - $player->getLevel()->broadcastLevelSoundEvent($blockClicked->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound()); - + $player->getLevel()->setBlock($blockClicked, BlockFactory::get(Block::AIR)); + $player->getLevel()->broadcastLevelSoundEvent($blockClicked->add(0.5, 0.5, 0.5), $blockClicked->getBucketFillSound()); if($player->isSurvival()){ - $player->getInventory()->setItemInHand($ev->getItem()); + if($stack->getCount() === 0){ + $player->getInventory()->setItemInHand($ev->getItem()); + }else{ + $player->getInventory()->setItemInHand($stack); + $player->getInventory()->addItem($ev->getItem()); + } + }else{ + $player->getInventory()->addItem($ev->getItem()); } - return true; }else{ $player->getInventory()->sendContents($player); } + + return true; } return false; } - - public function getResidue(){ - return ItemFactory::get(Item::BUCKET, 0, 1); - } - - public function getAdditionalEffects() : array{ - return []; - } - - public function canBeConsumed() : bool{ - return $this->blockId === null; //Milk - } - - public function onConsume(Living $consumer){ - $consumer->removeAllEffects(); - } } diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 615890ca04..a796eaf36c 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -111,12 +111,13 @@ class ItemFactory{ self::registerItem(new GoldenApple()); self::registerItem(new Sign()); self::registerItem(new ItemBlock(Block::OAK_DOOR_BLOCK, 0, Item::OAK_DOOR)); - self::registerItem(new Bucket(Item::BUCKET, 0, "Bucket", Block::AIR)); - self::registerItem(new Bucket(Item::BUCKET, 1, "Milk Bucket", null)); //TODO: this ought to get its own class, it has completely different behaviour + //TODO: fix metadata for buckets with still liquid in them //the meta values are intentionally hardcoded because block IDs will change in the future - self::registerItem(new Bucket(Item::BUCKET, 8, "Water Bucket", Block::FLOWING_WATER)); - self::registerItem(new Bucket(Item::BUCKET, 10, "Lava Bucket", Block::FLOWING_LAVA)); + self::registerItem(new Bucket(Item::BUCKET, 0, "Bucket")); + self::registerItem(new MilkBucket(Item::BUCKET, 1, "Milk Bucket")); + self::registerItem(new LiquidBucket(Item::BUCKET, 8, "Water Bucket", Block::FLOWING_WATER)); + self::registerItem(new LiquidBucket(Item::BUCKET, 10, "Lava Bucket", Block::FLOWING_LAVA)); self::registerItem(new Minecart()); //TODO: SADDLE diff --git a/src/pocketmine/item/LiquidBucket.php b/src/pocketmine/item/LiquidBucket.php new file mode 100644 index 0000000000..943d9f63eb --- /dev/null +++ b/src/pocketmine/item/LiquidBucket.php @@ -0,0 +1,81 @@ +liquidId = $liquidId; + } + + public function getMaxStackSize() : int{ + return 1; + } + + public function getFuelTime() : int{ + if(BlockFactory::get($this->liquidId) instanceof Lava){ + return 20000; + } + + return 0; + } + + public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : bool{ + if(!$blockReplace->canBeReplaced()){ + return false; + } + + //TODO: move this to generic placement logic + $resultBlock = BlockFactory::get($this->liquidId); + if($resultBlock instanceof Liquid){ + $ev = new PlayerBucketEmptyEvent($player, $blockReplace, $face, $this, ItemFactory::get(Item::BUCKET)); + $ev->call(); + if(!$ev->isCancelled()){ + $player->getLevel()->setBlock($blockReplace, $resultBlock->getFlowingForm()); + $player->getLevel()->broadcastLevelSoundEvent($blockClicked->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound()); + + if($player->isSurvival()){ + $player->getInventory()->setItemInHand($ev->getItem()); + } + }else{ + $player->getInventory()->sendContents($player); + } + + return true; + } + + return false; + } +} diff --git a/src/pocketmine/item/MilkBucket.php b/src/pocketmine/item/MilkBucket.php new file mode 100644 index 0000000000..628be6033f --- /dev/null +++ b/src/pocketmine/item/MilkBucket.php @@ -0,0 +1,45 @@ +removeAllEffects(); + } +} From 139aaa5577d5811716c24aefc99baad910fc388e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 7 Oct 2018 14:34:04 +0100 Subject: [PATCH 0220/3224] Protect Item->count --- src/pocketmine/block/Crops.php | 2 +- src/pocketmine/block/Grass.php | 2 +- src/pocketmine/block/Sapling.php | 2 +- src/pocketmine/block/Sugarcane.php | 2 +- src/pocketmine/item/Item.php | 2 +- src/pocketmine/item/PaintingItem.php | 2 +- src/pocketmine/item/ProjectileItem.php | 2 +- src/pocketmine/item/SpawnEgg.php | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index e4bd5d2cf5..42f1bcbf26 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -72,7 +72,7 @@ abstract class Crops extends Flowable{ $this->getLevel()->setBlock($this, $ev->getNewState()); } - $item->count--; + $item->pop(); return true; } diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index fd1f47b9e7..b640de8542 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -98,7 +98,7 @@ class Grass extends Solid{ public function onActivate(Item $item, Player $player = null) : bool{ if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ - $item->count--; + $item->pop(); TallGrassObject::growGrass($this->getLevel(), $this, new Random(mt_rand()), 8, 2); return true; diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index 73e315ab6e..e8db5dd752 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -61,7 +61,7 @@ class Sapling extends Flowable{ //TODO: change log type Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->getVariant()); - $item->count--; + $item->pop(); return true; } diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index a75023f2de..4dc97d84d1 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -76,7 +76,7 @@ class Sugarcane extends Flowable{ $this->getLevel()->setBlock($this, $this); } - $item->count--; + $item->pop(); return true; } diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 2440bf97e0..562fe2675c 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -180,7 +180,7 @@ class Item implements ItemIds, \JsonSerializable{ /** @var CompoundTag|null */ private $cachedNBT = null; /** @var int */ - public $count = 1; + protected $count = 1; /** @var string */ protected $name; diff --git a/src/pocketmine/item/PaintingItem.php b/src/pocketmine/item/PaintingItem.php index 0ee2542fe8..1c7085b411 100644 --- a/src/pocketmine/item/PaintingItem.php +++ b/src/pocketmine/item/PaintingItem.php @@ -93,7 +93,7 @@ class PaintingItem extends Item{ $entity = Entity::createEntity("Painting", $blockReplace->getLevel(), $nbt); if($entity instanceof Entity){ - --$this->count; + $this->pop(); $entity->spawnToAll(); $player->getLevel()->broadcastLevelEvent($blockReplace->add(0.5, 0.5, 0.5), LevelEventPacket::EVENT_SOUND_ITEMFRAME_PLACE); //item frame and painting have the same sound diff --git a/src/pocketmine/item/ProjectileItem.php b/src/pocketmine/item/ProjectileItem.php index e06cd398e1..db9b16ca7f 100644 --- a/src/pocketmine/item/ProjectileItem.php +++ b/src/pocketmine/item/ProjectileItem.php @@ -55,7 +55,7 @@ abstract class ProjectileItem extends Item{ $projectile->setMotion($projectile->getMotion()->multiply($this->getThrowForce())); } - $this->count--; + $this->pop(); if($projectile instanceof Projectile){ $projectileEv = new ProjectileLaunchEvent($projectile); diff --git a/src/pocketmine/item/SpawnEgg.php b/src/pocketmine/item/SpawnEgg.php index 4eca401f9f..1c2be92a59 100644 --- a/src/pocketmine/item/SpawnEgg.php +++ b/src/pocketmine/item/SpawnEgg.php @@ -40,7 +40,7 @@ class SpawnEgg extends Item{ $entity = Entity::createEntity($this->meta, $player->getLevel(), $nbt); if($entity instanceof Entity){ - --$this->count; + $this->pop(); $entity->spawnToAll(); return true; } From 7c1432526f6ffa0c271913c522f14542e3663c84 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 7 Oct 2018 15:28:10 +0100 Subject: [PATCH 0221/3224] Remove pointless ID maths from Level --- src/pocketmine/level/Level.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index c0d448749c..2ef63effc7 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1668,7 +1668,7 @@ class Level implements ChunkManager, Metadatable{ foreach($tag as $v){ if($v instanceof StringTag){ $entry = ItemFactory::fromString($v->getValue()); - if($entry->getId() > 0 and $entry->getBlock()->isSameType($target)){ + if($entry->getBlock()->isSameType($target)){ $canBreak = true; break; } @@ -1830,7 +1830,7 @@ class Level implements ChunkManager, Metadatable{ foreach($tag as $v){ if($v instanceof StringTag){ $entry = ItemFactory::fromString($v->getValue()); - if($entry->getId() > 0 and $entry->getBlock()->isSameType($blockClicked)){ + if($entry->getBlock()->isSameType($blockClicked)){ $canPlace = true; break; } From 8d1400115e653075edae54989816a6047c0b528f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 7 Oct 2018 15:42:59 +0100 Subject: [PATCH 0222/3224] fixed unsupported leveldb format versions crashing the server --- src/pocketmine/Server.php | 10 +++++-- .../level/format/io/data/BedrockLevelData.php | 8 +++--- .../UnsupportedLevelFormatException.php | 28 +++++++++++++++++++ .../level/format/io/leveldb/LevelDB.php | 6 ++-- 4 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 src/pocketmine/level/format/io/exception/UnsupportedLevelFormatException.php diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index e4cdb7450e..f2ab9819b4 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -50,6 +50,7 @@ use pocketmine\lang\Language; use pocketmine\lang\LanguageNotFoundException; use pocketmine\lang\TextContainer; use pocketmine\level\biome\Biome; +use pocketmine\level\format\io\exception\UnsupportedLevelFormatException; use pocketmine\level\format\io\LevelProvider; use pocketmine\level\format\io\LevelProviderManager; use pocketmine\level\generator\Generator; @@ -1044,8 +1045,13 @@ class Server{ } $providerClass = array_shift($providers); - /** @see LevelProvider::__construct() */ - $level = new Level($this, $name, new $providerClass($path)); + try{ + /** @see LevelProvider::__construct() */ + $level = new Level($this, $name, new $providerClass($path)); + }catch(UnsupportedLevelFormatException $e){ + $this->logger->error($this->language->translateString("pocketmine.level.loadError", [$name, $e->getMessage()])); + return false; + } $this->levels[$level->getId()] = $level; diff --git a/src/pocketmine/level/format/io/data/BedrockLevelData.php b/src/pocketmine/level/format/io/data/BedrockLevelData.php index 320d101a58..175aafe788 100644 --- a/src/pocketmine/level/format/io/data/BedrockLevelData.php +++ b/src/pocketmine/level/format/io/data/BedrockLevelData.php @@ -23,10 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\format\io\data; +use pocketmine\level\format\io\exception\UnsupportedLevelFormatException; use pocketmine\level\generator\Flat; use pocketmine\level\generator\GeneratorManager; use pocketmine\level\Level; -use pocketmine\level\LevelException; use pocketmine\nbt\LittleEndianNBTStream; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; @@ -103,7 +103,7 @@ class BedrockLevelData extends BaseNbtLevelData{ if($levelData instanceof CompoundTag){ $version = $levelData->getInt("StorageVersion", INT32_MAX, true); if($version > self::CURRENT_STORAGE_VERSION){ - throw new LevelException("Specified LevelDB world format version ($version) is not supported by " . \pocketmine\NAME); + throw new UnsupportedLevelFormatException("Specified LevelDB world format version ($version) is not supported by " . \pocketmine\NAME); } return $levelData; @@ -125,9 +125,9 @@ class BedrockLevelData extends BaseNbtLevelData{ $this->compoundTag->setString("generatorOptions", ""); break; case self::GENERATOR_LIMITED: - throw new LevelException("Limited worlds are not currently supported"); + throw new UnsupportedLevelFormatException("Limited worlds are not currently supported"); default: - throw new LevelException("Unknown LevelDB world format type, this level cannot be loaded"); + throw new UnsupportedLevelFormatException("Unknown LevelDB world format type, this level cannot be loaded"); } }else{ $this->compoundTag->setString("generatorName", "default"); diff --git a/src/pocketmine/level/format/io/exception/UnsupportedLevelFormatException.php b/src/pocketmine/level/format/io/exception/UnsupportedLevelFormatException.php new file mode 100644 index 0000000000..4e0dc310c4 --- /dev/null +++ b/src/pocketmine/level/format/io/exception/UnsupportedLevelFormatException.php @@ -0,0 +1,28 @@ + Date: Mon, 8 Oct 2018 12:48:44 +0100 Subject: [PATCH 0223/3224] Improve and simplify AsyncTask thread-local storage This is now self-maintaining and doesn't rely on the async pool to wipe its ass on task completion. Instead, the garbage collector will cause thread-local data to be automatically released when the async task is garbage-collected on the main thread. --- src/pocketmine/scheduler/AsyncPool.php | 5 - src/pocketmine/scheduler/AsyncTask.php | 127 +++++++----------- .../tests/AsyncTaskMemoryLeakTest.php | 2 +- 3 files changed, 48 insertions(+), 86 deletions(-) diff --git a/src/pocketmine/scheduler/AsyncPool.php b/src/pocketmine/scheduler/AsyncPool.php index 5f06c9f646..04461df9e6 100644 --- a/src/pocketmine/scheduler/AsyncPool.php +++ b/src/pocketmine/scheduler/AsyncPool.php @@ -255,14 +255,9 @@ class AsyncPool{ if(!$task->hasCancelledRun()){ try{ $task->onCompletion(); - if($task->removeDanglingStoredObjects()){ - $this->logger->notice("AsyncTask " . get_class($task) . " stored local complex data but did not remove them after completion"); - } }catch(\Throwable $e){ $this->logger->critical("Could not execute completion of asynchronous task " . (new \ReflectionClass($task))->getShortName() . ": " . $e->getMessage()); $this->logger->logException($e); - - $task->removeDanglingStoredObjects(); //silent } } diff --git a/src/pocketmine/scheduler/AsyncTask.php b/src/pocketmine/scheduler/AsyncTask.php index d3045c2b82..c3a7619d58 100644 --- a/src/pocketmine/scheduler/AsyncTask.php +++ b/src/pocketmine/scheduler/AsyncTask.php @@ -44,10 +44,11 @@ use pocketmine\Collectable; */ abstract class AsyncTask extends Collectable{ /** - * @var \SplObjectStorage|null - * Used to store objects on the main thread which should not be serialized. + * @var \ArrayObject|mixed[] object hash => mixed data + * + * Used to store objects which are only needed on one thread and should not be serialized. */ - private static $localObjectStorage; + private static $threadLocalStorage = null; /** @var AsyncWorker $worker */ public $worker = null; @@ -208,108 +209,74 @@ abstract class AsyncTask extends Collectable{ } /** - * Saves mixed data in thread-local storage on the parent thread. You may use this to retain references to objects - * or arrays which you need to access in {@link AsyncTask#onCompletion} which cannot be stored as a property of - * your task (due to them becoming serialized). + * Saves mixed data in thread-local storage. Data stored using this storage is **only accessible from the thread it + * was stored on**. Data stored using this method will **not** be serialized. + * This can be used to store references to variables which you need later on on the same thread, but not others. + * + * For example, plugin references could be stored in the constructor of the async task (which is called on the main + * thread) using this, and then fetched in onCompletion() (which is also called on the main thread), without them + * becoming serialized. * * Scalar types can be stored directly in class properties instead of using this storage. * - * Objects stored in this storage MUST be retrieved through {@link #fetchLocal} when {@link #onCompletion} is called. - * Otherwise, a NOTICE level message will be raised and the reference will be removed after onCompletion exits. + * Objects stored in this storage can be retrieved using fetchLocal() on the same thread that this method was called + * from. * - * WARNING: Use this method carefully. It might take a long time before an AsyncTask is completed. PocketMine will - * keep a strong reference to objects passed in this method. This may result in a light memory leak. Usually this - * does not cause memory failure, but be aware that the object may be no longer usable when the AsyncTask completes. + * WARNING: Use this method carefully. It might take a long time before an AsyncTask is completed. The thread this + * is called on will keep a strong reference to variables stored using method. This may result in a light memory + * leak. Usually this does not cause memory failure, but be aware that the object may be no longer usable when the + * AsyncTask completes. Since a strong reference is retained, the objects still exist, but the implementation is + * responsible for checking whether these objects are still usable. * (E.g. a {@link \pocketmine\Level} object is no longer usable because it is unloaded while the AsyncTask is - * executing, or even a plugin might be unloaded). Since PocketMine keeps a strong reference, the objects are still - * valid, but the implementation is responsible for checking whether these objects are still usable. - * - * WARNING: THIS METHOD SHOULD ONLY BE CALLED FROM THE MAIN THREAD! + * executing, or even a plugin might be unloaded). * * @param mixed $complexData the data to store - * */ protected function storeLocal($complexData) : void{ - if($this->worker !== null and $this->worker === \Thread::getCurrentThread()){ - throw new \BadMethodCallException("Objects can only be stored from the parent thread"); + if(self::$threadLocalStorage === null){ + /* + * It's necessary to use an object (not array) here because pthreads is stupid. Non-default array statics + * will be inherited when task classes are copied to the worker thread, which would cause unwanted + * inheritance of primitive thread-locals, which we really don't want for various reasons. + * It won't try to inherit objects though, so this is the easiest solution. + */ + self::$threadLocalStorage = new \ArrayObject(); } - - if(self::$localObjectStorage === null){ - self::$localObjectStorage = new \SplObjectStorage(); //lazy init - } - - if(isset(self::$localObjectStorage[$this])){ - throw new \InvalidStateException("Already storing complex data for this async task"); - } - self::$localObjectStorage[$this] = $complexData; + self::$threadLocalStorage[spl_object_hash($this)] = $complexData; } /** - * Returns and removes mixed data in thread-local storage on the parent thread. Call this method from - * {@link AsyncTask#onCompletion} to fetch the data stored in the object store, if any. + * Retrieves data stored in thread-local storage. * - * If no data was stored in the local store, or if the data was already retrieved by a previous call to fetchLocal, - * do NOT call this method, or an exception will be thrown. - * - * Do not call this method from {@link AsyncTask#onProgressUpdate}, because this method deletes stored data, which - * means that you will not be able to retrieve it again afterwards. Use {@link AsyncTask#peekLocal} instead to - * retrieve stored data without removing it from the store. - * - * WARNING: THIS METHOD SHOULD ONLY BE CALLED FROM THE MAIN THREAD! + * If you used storeLocal(), you can use this on the same thread to fetch data stored. This should be used during + * onProgressUpdate() and onCompletion() to fetch thread-local data stored on the parent thread. * * @return mixed * - * @throws \RuntimeException if no data were stored by this AsyncTask instance. - * @throws \BadMethodCallException if called from any thread except the main thread + * @throws \InvalidArgumentException if no data were stored by this AsyncTask instance. */ protected function fetchLocal(){ - try{ - return $this->peekLocal(); - }finally{ - if(self::$localObjectStorage !== null){ - unset(self::$localObjectStorage[$this]); + if(self::$threadLocalStorage === null or !isset(self::$threadLocalStorage[spl_object_hash($this)])){ + throw new \InvalidArgumentException("No matching thread-local data found on this thread"); + } + + return self::$threadLocalStorage[spl_object_hash($this)]; + } + + final public function __destruct(){ + $this->reallyDestruct(); + if(self::$threadLocalStorage !== null){ + unset(self::$threadLocalStorage[spl_object_hash($this)]); + if(self::$threadLocalStorage->count() === 0){ + self::$threadLocalStorage = null; } } } /** - * Returns mixed data in thread-local storage on the parent thread **without clearing** it. Call this method from - * {@link AsyncTask#onProgressUpdate} to fetch the data stored if you need to be able to access the data later on, - * such as in another progress update. - * - * Use {@link AsyncTask#fetchLocal} instead from {@link AsyncTask#onCompletion}, because this method does not delete - * the data, and not clearing the data will result in a warning for memory leak after {@link AsyncTask#onCompletion} - * finished executing. - * - * WARNING: THIS METHOD SHOULD ONLY BE CALLED FROM THE MAIN THREAD! - * - * @return mixed - * - * @throws \RuntimeException if no data were stored by this AsyncTask instance - * @throws \BadMethodCallException if called from any thread except the main thread + * Override this to do normal __destruct() cleanup from a child class. */ - protected function peekLocal(){ - if($this->worker !== null and $this->worker === \Thread::getCurrentThread()){ - throw new \BadMethodCallException("Objects can only be retrieved from the parent thread"); - } + protected function reallyDestruct() : void{ - if(self::$localObjectStorage === null or !isset(self::$localObjectStorage[$this])){ - throw new \InvalidStateException("No complex data stored for this async task"); - } - - return self::$localObjectStorage[$this]; - } - - /** - * @internal Called by the AsyncPool to destroy any leftover stored objects that this task failed to retrieve. - * @return bool - */ - public function removeDanglingStoredObjects() : bool{ - if(self::$localObjectStorage !== null and isset(self::$localObjectStorage[$this])){ - unset(self::$localObjectStorage[$this]); - return true; - } - - return false; } } diff --git a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMemoryLeakTest.php b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMemoryLeakTest.php index 686ad9628e..eba13c43ca 100644 --- a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMemoryLeakTest.php +++ b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMemoryLeakTest.php @@ -54,7 +54,7 @@ class TestAsyncTask extends AsyncTask{ usleep(50 * 1000); //1 server tick } - public function __destruct(){ + protected function reallyDestruct() : void{ self::$destroyed = true; } } From a0f3c03b50b61c1c0432a13c6167ca8cade65769 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Oct 2018 12:59:47 +0100 Subject: [PATCH 0224/3224] oopsie woopsie I made a fucky wucky! a wittle fucko boingo! --- src/pocketmine/scheduler/AsyncTask.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/scheduler/AsyncTask.php b/src/pocketmine/scheduler/AsyncTask.php index c3a7619d58..1272c961ac 100644 --- a/src/pocketmine/scheduler/AsyncTask.php +++ b/src/pocketmine/scheduler/AsyncTask.php @@ -265,8 +265,8 @@ abstract class AsyncTask extends Collectable{ final public function __destruct(){ $this->reallyDestruct(); - if(self::$threadLocalStorage !== null){ - unset(self::$threadLocalStorage[spl_object_hash($this)]); + if(self::$threadLocalStorage !== null and isset(self::$threadLocalStorage[$h = spl_object_hash($this)])){ + unset(self::$threadLocalStorage[$h]); if(self::$threadLocalStorage->count() === 0){ self::$threadLocalStorage = null; } From 24677e1d793868a8ea8068df710f433736510bfe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Oct 2018 13:01:12 +0100 Subject: [PATCH 0225/3224] Prevent undefined behaviour when accessing async worker thread-store from outside the worker itself --- src/pocketmine/scheduler/AsyncWorker.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/pocketmine/scheduler/AsyncWorker.php b/src/pocketmine/scheduler/AsyncWorker.php index 221d4aa5d9..8222e46d5f 100644 --- a/src/pocketmine/scheduler/AsyncWorker.php +++ b/src/pocketmine/scheduler/AsyncWorker.php @@ -90,6 +90,9 @@ class AsyncWorker extends Worker{ * @param mixed $value */ public function saveToThreadStore(string $identifier, $value) : void{ + if(\Thread::getCurrentThread() !== $this){ + throw new \InvalidStateException("Thread-local data can only be stored in the thread context"); + } self::$store[$identifier] = $value; } @@ -105,6 +108,9 @@ class AsyncWorker extends Worker{ * @return mixed */ public function getFromThreadStore(string $identifier){ + if(\Thread::getCurrentThread() !== $this){ + throw new \InvalidStateException("Thread-local data can only be fetched in the thread context"); + } return self::$store[$identifier] ?? null; } @@ -114,6 +120,9 @@ class AsyncWorker extends Worker{ * @param string $identifier */ public function removeFromThreadStore(string $identifier) : void{ + if(\Thread::getCurrentThread() !== $this){ + throw new \InvalidStateException("Thread-local data can only be removed in the thread context"); + } unset(self::$store[$identifier]); } } From a653289c404cd02320ecc9c3f73a23ceb8a76841 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Oct 2018 13:06:51 +0100 Subject: [PATCH 0226/3224] Rename Plugin->setEnabled() with a more clear name This is intended to break API in order to jerk the rug out from underneath plugin developers who have been misusing this without noticing the side effects. --- src/pocketmine/plugin/Plugin.php | 2 +- src/pocketmine/plugin/PluginBase.php | 2 +- src/pocketmine/plugin/PluginManager.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/plugin/Plugin.php b/src/pocketmine/plugin/Plugin.php index f6df54b8e0..1a6146a6bb 100644 --- a/src/pocketmine/plugin/Plugin.php +++ b/src/pocketmine/plugin/Plugin.php @@ -51,7 +51,7 @@ interface Plugin extends CommandExecutor{ * * @param bool $enabled */ - public function setEnabled(bool $enabled = true) : void; + public function onEnableStateChange(bool $enabled) : void; /** * @return bool diff --git a/src/pocketmine/plugin/PluginBase.php b/src/pocketmine/plugin/PluginBase.php index fd4a913744..b76ffa2c2a 100644 --- a/src/pocketmine/plugin/PluginBase.php +++ b/src/pocketmine/plugin/PluginBase.php @@ -110,7 +110,7 @@ abstract class PluginBase implements Plugin{ * * @param bool $enabled */ - final public function setEnabled(bool $enabled = true) : void{ + final public function onEnableStateChange(bool $enabled) : void{ if($this->isEnabled !== $enabled){ $this->isEnabled = $enabled; if($this->isEnabled){ diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index 847bf9f298..98f1dd960d 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -412,7 +412,7 @@ class PluginManager{ $permManager->addPermission($perm); } $plugin->getScheduler()->setEnabled(true); - $plugin->setEnabled(true); + $plugin->onEnableStateChange(true); $this->enabledPlugins[$plugin->getDescription()->getName()] = $plugin; @@ -498,7 +498,7 @@ class PluginManager{ unset($this->enabledPlugins[$plugin->getDescription()->getName()]); try{ - $plugin->setEnabled(false); + $plugin->onEnableStateChange(false); }catch(\Throwable $e){ $this->server->getLogger()->logException($e); } From 3bb450244fda8c2e7050e44e8a392960ef63f02f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 9 Oct 2018 16:32:34 +0100 Subject: [PATCH 0227/3224] Level: Identify chunk loaders by their object ID chunkloader ID is completely unnecessary extra complication. spl_object_hash() would be fine for this as well, but a number is better. Since it's unique for the object lifetime (and the Level keeps a ref to loaders) this system should work just fine. --- src/pocketmine/Player.php | 7 ------- src/pocketmine/level/ChunkLoader.php | 8 -------- src/pocketmine/level/Level.php | 13 ++----------- 3 files changed, 2 insertions(+), 26 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 09c88a8c38..a86a11b3dd 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -214,8 +214,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ /** @var int */ protected $gamemode; - /** @var int */ - private $loaderId = 0; /** @var bool[] chunkHash => bool (true = sent, false = needs sending) */ public $usedChunks = []; /** @var bool[] chunkHash => dummy */ @@ -664,7 +662,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->networkSession = $session; $this->perm = new PermissibleBase($this); - $this->loaderId = Level::generateChunkLoaderId($this); $this->chunksPerTick = (int) $this->server->getProperty("chunk-sending.per-tick", 4); $this->spawnThreshold = (int) (($this->server->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); @@ -3382,8 +3379,4 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ public function onBlockChanged(Vector3 $block){ } - - public function getLoaderId() : int{ - return $this->loaderId; - } } diff --git a/src/pocketmine/level/ChunkLoader.php b/src/pocketmine/level/ChunkLoader.php index 9f10e8ac10..9d36150759 100644 --- a/src/pocketmine/level/ChunkLoader.php +++ b/src/pocketmine/level/ChunkLoader.php @@ -39,14 +39,6 @@ use pocketmine\math\Vector3; */ interface ChunkLoader{ - /** - * Returns the ChunkLoader id. - * Call Level::generateChunkLoaderId($this) to generate and save it - * - * @return int - */ - public function getLoaderId() : int; - /** * @return float */ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 2ef63effc7..f8dc009c9a 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -91,7 +91,6 @@ use pocketmine\utils\ReversePriorityQueue; class Level implements ChunkManager, Metadatable{ private static $levelIdCounter = 1; - private static $chunkLoaderCounter = 1; public const Y_MASK = 0xFF; public const Y_MAX = 0x100; //256 @@ -280,14 +279,6 @@ class Level implements ChunkManager, Metadatable{ $z = ($hash & 0xFFFFFFFF) << 32 >> 32; } - public static function generateChunkLoaderId(ChunkLoader $loader) : int{ - if($loader->getLoaderId() === 0){ - return self::$chunkLoaderCounter++; - }else{ - throw new \InvalidStateException("ChunkLoader has a loader id already assigned: " . $loader->getLoaderId()); - } - } - /** * @param string $str * @return int @@ -624,7 +615,7 @@ class Level implements ChunkManager, Metadatable{ } public function registerChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ, bool $autoLoad = true){ - $hash = $loader->getLoaderId(); + $hash = spl_object_id($loader); if(!isset($this->chunkLoaders[$index = Level::chunkHash($chunkX, $chunkZ)])){ $this->chunkLoaders[$index] = []; @@ -653,7 +644,7 @@ class Level implements ChunkManager, Metadatable{ } public function unregisterChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ){ - if(isset($this->chunkLoaders[$index = Level::chunkHash($chunkX, $chunkZ)][$hash = $loader->getLoaderId()])){ + if(isset($this->chunkLoaders[$index = Level::chunkHash($chunkX, $chunkZ)][$hash = spl_object_id($loader)])){ unset($this->chunkLoaders[$index][$hash]); unset($this->playerLoaders[$index][$hash]); if(count($this->chunkLoaders[$index]) === 0){ From e2af394c8108e3f03476908da802122e59521e99 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 10 Oct 2018 03:59:07 -0400 Subject: [PATCH 0228/3224] Revert "Level: Identify chunk loaders by their object ID" This reverts commit 3bb450244fda8c2e7050e44e8a392960ef63f02f. PhpStorm you lying piece of shit... you only showed me the usages in Level! This change should be revised and redone later. --- src/pocketmine/Player.php | 7 +++++++ src/pocketmine/level/ChunkLoader.php | 8 ++++++++ src/pocketmine/level/Level.php | 13 +++++++++++-- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 23c031433c..438d55efc2 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -214,6 +214,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ /** @var int */ protected $gamemode; + /** @var int */ + private $loaderId = 0; /** @var bool[] chunkHash => bool (true = sent, false = needs sending) */ public $usedChunks = []; /** @var bool[] chunkHash => dummy */ @@ -662,6 +664,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->networkSession = $session; $this->perm = new PermissibleBase($this); + $this->loaderId = Level::generateChunkLoaderId($this); $this->chunksPerTick = (int) $this->server->getProperty("chunk-sending.per-tick", 4); $this->spawnThreshold = (int) (($this->server->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); @@ -3382,4 +3385,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ public function onBlockChanged(Vector3 $block){ } + + public function getLoaderId() : int{ + return $this->loaderId; + } } diff --git a/src/pocketmine/level/ChunkLoader.php b/src/pocketmine/level/ChunkLoader.php index 9d36150759..9f10e8ac10 100644 --- a/src/pocketmine/level/ChunkLoader.php +++ b/src/pocketmine/level/ChunkLoader.php @@ -39,6 +39,14 @@ use pocketmine\math\Vector3; */ interface ChunkLoader{ + /** + * Returns the ChunkLoader id. + * Call Level::generateChunkLoaderId($this) to generate and save it + * + * @return int + */ + public function getLoaderId() : int; + /** * @return float */ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index f8dc009c9a..2ef63effc7 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -91,6 +91,7 @@ use pocketmine\utils\ReversePriorityQueue; class Level implements ChunkManager, Metadatable{ private static $levelIdCounter = 1; + private static $chunkLoaderCounter = 1; public const Y_MASK = 0xFF; public const Y_MAX = 0x100; //256 @@ -279,6 +280,14 @@ class Level implements ChunkManager, Metadatable{ $z = ($hash & 0xFFFFFFFF) << 32 >> 32; } + public static function generateChunkLoaderId(ChunkLoader $loader) : int{ + if($loader->getLoaderId() === 0){ + return self::$chunkLoaderCounter++; + }else{ + throw new \InvalidStateException("ChunkLoader has a loader id already assigned: " . $loader->getLoaderId()); + } + } + /** * @param string $str * @return int @@ -615,7 +624,7 @@ class Level implements ChunkManager, Metadatable{ } public function registerChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ, bool $autoLoad = true){ - $hash = spl_object_id($loader); + $hash = $loader->getLoaderId(); if(!isset($this->chunkLoaders[$index = Level::chunkHash($chunkX, $chunkZ)])){ $this->chunkLoaders[$index] = []; @@ -644,7 +653,7 @@ class Level implements ChunkManager, Metadatable{ } public function unregisterChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ){ - if(isset($this->chunkLoaders[$index = Level::chunkHash($chunkX, $chunkZ)][$hash = spl_object_id($loader)])){ + if(isset($this->chunkLoaders[$index = Level::chunkHash($chunkX, $chunkZ)][$hash = $loader->getLoaderId()])){ unset($this->chunkLoaders[$index][$hash]); unset($this->playerLoaders[$index][$hash]); if(count($this->chunkLoaders[$index]) === 0){ From 2e265423c7d74f5d1e38a96812851223b2e0890a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 10 Oct 2018 04:44:45 -0400 Subject: [PATCH 0229/3224] Fixed NBT leveldata fixer never getting called --- src/pocketmine/level/format/io/data/BaseNbtLevelData.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pocketmine/level/format/io/data/BaseNbtLevelData.php b/src/pocketmine/level/format/io/data/BaseNbtLevelData.php index 532e7b22f3..4045d0cd2b 100644 --- a/src/pocketmine/level/format/io/data/BaseNbtLevelData.php +++ b/src/pocketmine/level/format/io/data/BaseNbtLevelData.php @@ -47,6 +47,7 @@ abstract class BaseNbtLevelData implements LevelData{ if($this->compoundTag === null){ throw new LevelException("Invalid level data"); } + $this->fix(); } /** From a944641509f6f6f9c9172f9a452d53614d712bec Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 12 Oct 2018 12:26:44 +0100 Subject: [PATCH 0230/3224] Torch: Fix placement issues when clicking the bottom of a block, closes #2453 (#2474) --- src/pocketmine/block/Torch.php | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index 8e889bfe58..1238fe110a 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -73,16 +73,28 @@ class Torch extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $below = $this->getSide(Facing::DOWN); - - if(!$blockClicked->isTransparent() and $face !== Facing::DOWN){ - $this->facing = $face; - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); - }elseif(!$below->isTransparent() or $below->getId() === self::FENCE or $below->getId() === self::COBBLESTONE_WALL){ + if($blockClicked->canBeReplaced() and !$blockClicked->getSide(Facing::DOWN)->isTransparent()){ $this->facing = Facing::UP; return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + }elseif($face !== Facing::DOWN and (!$blockClicked->isTransparent() or ($face === Facing::UP and ($blockClicked->getId() === self::FENCE or $blockClicked->getId() === self::COBBLESTONE_WALL)))){ + $this->facing = $face; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + }else{ + static $faces = [ + Facing::SOUTH, + Facing::WEST, + Facing::NORTH, + Facing::EAST, + Facing::DOWN, + ]; + foreach($faces as $side){ + $block = $this->getSide($side); + if(!$block->isTransparent()){ + $this->facing = Facing::opposite($side); + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + } } - return false; } } From 97c836f199f536e4596ecf8cc1945b7f06d30ea6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 12 Oct 2018 16:31:17 +0100 Subject: [PATCH 0231/3224] Remove nasty network crap from API --- src/pocketmine/event/entity/EntityDespawnEvent.php | 10 ---------- src/pocketmine/event/entity/EntitySpawnEvent.php | 10 ---------- 2 files changed, 20 deletions(-) diff --git a/src/pocketmine/event/entity/EntityDespawnEvent.php b/src/pocketmine/event/entity/EntityDespawnEvent.php index 0f456e3600..3831041e6c 100644 --- a/src/pocketmine/event/entity/EntityDespawnEvent.php +++ b/src/pocketmine/event/entity/EntityDespawnEvent.php @@ -34,22 +34,12 @@ use pocketmine\entity\Vehicle; * Called when a entity is despawned */ class EntityDespawnEvent extends EntityEvent{ - /** @var int */ - private $entityType; /** * @param Entity $entity */ public function __construct(Entity $entity){ $this->entity = $entity; - $this->entityType = $entity::NETWORK_ID; - } - - /** - * @return int - */ - public function getType() : int{ - return $this->entityType; } /** diff --git a/src/pocketmine/event/entity/EntitySpawnEvent.php b/src/pocketmine/event/entity/EntitySpawnEvent.php index 20a068b879..8a8f1484fa 100644 --- a/src/pocketmine/event/entity/EntitySpawnEvent.php +++ b/src/pocketmine/event/entity/EntitySpawnEvent.php @@ -35,15 +35,12 @@ use pocketmine\level\Position; * Called when a entity is spawned */ class EntitySpawnEvent extends EntityEvent{ - /** @var int */ - private $entityType; /** * @param Entity $entity */ public function __construct(Entity $entity){ $this->entity = $entity; - $this->entityType = $entity::NETWORK_ID; } /** @@ -53,13 +50,6 @@ class EntitySpawnEvent extends EntityEvent{ return $this->entity->getPosition(); } - /** - * @return int - */ - public function getType() : int{ - return $this->entityType; - } - /** * @return bool */ From acb794e7281e6127640510da90e7d3f680a91a7d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 12 Oct 2018 16:35:51 +0100 Subject: [PATCH 0232/3224] Remove garbage from Entity(De)SpawnEvent These methods: a) add concrete dependencies b) are pointless (event->getEntity() instanceof Creature, anyone? an IDE can better understand this as well...) c) encourage bad code (they don't enforce type contracts the same way an instanceof check does - oh, and why not let's add an is*() for every new mob that gets added ever? --- .../event/entity/EntityDespawnEvent.php | 40 ---------------- .../event/entity/EntitySpawnEvent.php | 48 ------------------- 2 files changed, 88 deletions(-) diff --git a/src/pocketmine/event/entity/EntityDespawnEvent.php b/src/pocketmine/event/entity/EntityDespawnEvent.php index 3831041e6c..1978f60797 100644 --- a/src/pocketmine/event/entity/EntityDespawnEvent.php +++ b/src/pocketmine/event/entity/EntityDespawnEvent.php @@ -23,12 +23,7 @@ declare(strict_types=1); namespace pocketmine\event\entity; -use pocketmine\entity\Creature; use pocketmine\entity\Entity; -use pocketmine\entity\Human; -use pocketmine\entity\object\ItemEntity; -use pocketmine\entity\projectile\Projectile; -use pocketmine\entity\Vehicle; /** * Called when a entity is despawned @@ -41,39 +36,4 @@ class EntityDespawnEvent extends EntityEvent{ public function __construct(Entity $entity){ $this->entity = $entity; } - - /** - * @return bool - */ - public function isCreature() : bool{ - return $this->entity instanceof Creature; - } - - /** - * @return bool - */ - public function isHuman() : bool{ - return $this->entity instanceof Human; - } - - /** - * @return bool - */ - public function isProjectile() : bool{ - return $this->entity instanceof Projectile; - } - - /** - * @return bool - */ - public function isVehicle() : bool{ - return $this->entity instanceof Vehicle; - } - - /** - * @return bool - */ - public function isItem() : bool{ - return $this->entity instanceof ItemEntity; - } } diff --git a/src/pocketmine/event/entity/EntitySpawnEvent.php b/src/pocketmine/event/entity/EntitySpawnEvent.php index 8a8f1484fa..e20b98dbc1 100644 --- a/src/pocketmine/event/entity/EntitySpawnEvent.php +++ b/src/pocketmine/event/entity/EntitySpawnEvent.php @@ -23,13 +23,7 @@ declare(strict_types=1); namespace pocketmine\event\entity; -use pocketmine\entity\Creature; use pocketmine\entity\Entity; -use pocketmine\entity\Human; -use pocketmine\entity\object\ItemEntity; -use pocketmine\entity\projectile\Projectile; -use pocketmine\entity\Vehicle; -use pocketmine\level\Position; /** * Called when a entity is spawned @@ -42,46 +36,4 @@ class EntitySpawnEvent extends EntityEvent{ public function __construct(Entity $entity){ $this->entity = $entity; } - - /** - * @return Position - */ - public function getPosition() : Position{ - return $this->entity->getPosition(); - } - - /** - * @return bool - */ - public function isCreature() : bool{ - return $this->entity instanceof Creature; - } - - /** - * @return bool - */ - public function isHuman() : bool{ - return $this->entity instanceof Human; - } - - /** - * @return bool - */ - public function isProjectile() : bool{ - return $this->entity instanceof Projectile; - } - - /** - * @return bool - */ - public function isVehicle() : bool{ - return $this->entity instanceof Vehicle; - } - - /** - * @return bool - */ - public function isItem() : bool{ - return $this->entity instanceof ItemEntity; - } } From c96203b5284ca44d09a8b5c133ad58bb65429841 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 12 Oct 2018 17:08:22 +0100 Subject: [PATCH 0233/3224] Set immobile flag on player pre-spawn The client likes to fall involuntarily as soon as PLAYER_SPAWN PlayStatus is sent, which causes debug spam on the PM side and then movement reversions if falling far enough. This now prevents the client moving until the server knows the client has spawned. --- .../network/mcpe/handler/PreSpawnSessionHandler.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php index 69083f0147..66d8cf0b45 100644 --- a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php @@ -76,6 +76,8 @@ class PreSpawnSessionHandler extends SessionHandler{ $pk->worldName = $this->server->getMotd(); $this->session->sendDataPacket($pk); + $this->player->setImmobile(); //HACK: fix client-side falling pre-spawn + $this->player->getLevel()->sendTime($this->player); $this->player->sendAttributes(true); @@ -99,6 +101,8 @@ class PreSpawnSessionHandler extends SessionHandler{ } public function handleSetLocalPlayerAsInitialized(SetLocalPlayerAsInitializedPacket $packet) : bool{ + $this->player->setImmobile(false); //HACK: this is set to prevent client-side falling before spawn + $this->player->doFirstSpawn(); return true; From d151a89037715841c6776df48b42e3bfb6f5a566 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 12 Oct 2018 18:38:52 +0100 Subject: [PATCH 0234/3224] Vine: don't break when a supported vine is above, closes #2452 --- src/pocketmine/block/Vine.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index 4ffe880082..81d7d928bf 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -163,8 +163,13 @@ class Vine extends Flowable{ public function onNearbyBlockChange() : void{ $changed = false; + + $up = $this->getSide(Facing::UP); + //check which faces have corresponding vines in the block above + $supportedFaces = $up instanceof Vine ? array_intersect_key($this->faces, $up->faces) : []; + foreach($this->faces as $face => $bool){ - if(!$this->getSide($face)->isSolid()){ + if(!isset($supportedFaces[$face]) and !$this->getSide($face)->isSolid()){ unset($this->faces[$face]); $changed = true; } From 873b64259d334022c95c990ff2c05ed7c700ae2d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 12 Oct 2018 19:07:43 +0100 Subject: [PATCH 0235/3224] Torch: remove trailing comma --- src/pocketmine/block/Torch.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index 1238fe110a..e3fc2af253 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -85,7 +85,7 @@ class Torch extends Flowable{ Facing::WEST, Facing::NORTH, Facing::EAST, - Facing::DOWN, + Facing::DOWN ]; foreach($faces as $side){ $block = $this->getSide($side); From 05205985840b7cefe0f5a5314c5226e1e2fd03b3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 12 Oct 2018 19:49:26 +0100 Subject: [PATCH 0236/3224] BlockFactory: skip blockstates which corrupt the metadata if the metadata doesn't match what was inputted when reading back, it's an invalid state and should not be registered. --- src/pocketmine/block/BlockFactory.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 28aa85cf09..b14259a82d 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -477,12 +477,13 @@ class BlockFactory{ $v = clone $block; $v->readStateFromMeta($m & $stateMask); - - self::$fullList[$index] = $v; - self::$stateMasks[$index] = $stateMask; - self::$lightFilter[$index] = min(15, $v->getLightFilter() + 1); //opacity plus 1 standard light filter - self::$diffusesSkyLight[$index] = $v->diffusesSkyLight(); - self::$blastResistance[$index] = $v->getBlastResistance(); + if($v->getDamage() === $m){ //don't register anything that isn't the same when we read it back again + self::$fullList[$index] = $v; + self::$stateMasks[$index] = $stateMask; + self::$lightFilter[$index] = min(15, $v->getLightFilter() + 1); //opacity plus 1 standard light filter + self::$diffusesSkyLight[$index] = $v->diffusesSkyLight(); + self::$blastResistance[$index] = $v->getBlastResistance(); + } } } From 7af7783cc8ef288e776756a283aaa1a9c8cca5c6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 12 Oct 2018 20:05:44 +0100 Subject: [PATCH 0237/3224] BlockFactory: Register block to id|variant without setting state to allow non-zero default states This will be needed to deal with things like chest/furnace which don't use 0 as a valid state (these both use facing horizontal for rotation, and vertical is invalid, so 0 would mean downwards facing which is invalid. --- src/pocketmine/block/BlockFactory.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index b14259a82d..539f4de08f 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -464,7 +464,9 @@ class BlockFactory{ throw new \InvalidArgumentException("Block variant collides with state bitmask"); } - for($m = $variant; $m <= ($variant | $stateMask); ++$m){ + self::fillStaticArrays(($id << 4) | $variant, $block); //register default state mapped to variant, for blocks which don't use 0 as valid state + + for($m = $variant + 1; $m <= ($variant | $stateMask); ++$m){ if(($m & ~$stateMask) !== $variant){ continue; } @@ -478,15 +480,19 @@ class BlockFactory{ $v = clone $block; $v->readStateFromMeta($m & $stateMask); if($v->getDamage() === $m){ //don't register anything that isn't the same when we read it back again - self::$fullList[$index] = $v; - self::$stateMasks[$index] = $stateMask; - self::$lightFilter[$index] = min(15, $v->getLightFilter() + 1); //opacity plus 1 standard light filter - self::$diffusesSkyLight[$index] = $v->diffusesSkyLight(); - self::$blastResistance[$index] = $v->getBlastResistance(); + self::fillStaticArrays($index, $v); } } } + private static function fillStaticArrays(int $index, Block $block) : void{ + self::$fullList[$index] = $block; + self::$stateMasks[$index] = $block->getStateBitmask(); + self::$lightFilter[$index] = min(15, $block->getLightFilter() + 1); //opacity plus 1 standard light filter + self::$diffusesSkyLight[$index] = $block->diffusesSkyLight(); + self::$blastResistance[$index] = $block->getBlastResistance(); + } + /** * Returns a new Block instance with the specified ID, meta and position. * From f671da99a626b9f50b8fe38339c1a32752136671 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 12 Oct 2018 21:40:45 +0100 Subject: [PATCH 0238/3224] BlockFactory: fix failing test --- src/pocketmine/block/BlockFactory.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 539f4de08f..9fd5c8625f 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -464,6 +464,9 @@ class BlockFactory{ throw new \InvalidArgumentException("Block variant collides with state bitmask"); } + if(!$override and self::isRegistered($id, $variant)){ + throw new \InvalidArgumentException("Block registration conflicts with an existing block"); + } self::fillStaticArrays(($id << 4) | $variant, $block); //register default state mapped to variant, for blocks which don't use 0 as valid state for($m = $variant + 1; $m <= ($variant | $stateMask); ++$m){ From 39d1196e4ccdae51d2a19feb9f732c7cca7f191c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 13 Oct 2018 12:28:33 +0100 Subject: [PATCH 0239/3224] Leaves: fix performance issue introduced by block meta nuke --- src/pocketmine/block/Leaves.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 118d8e47a6..aa290ddadc 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -111,6 +111,7 @@ class Leaves extends Transparent{ $ev = new LeavesDecayEvent($this); $ev->call(); if($ev->isCancelled() or $this->findLog($this)){ + $this->checkDecay = false; $this->getLevel()->setBlock($this, $this, false); }else{ $this->getLevel()->useBreakOn($this); From bb286dea9184e0a8537cabef7bda44e700cde5a8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 13 Oct 2018 15:37:26 +0100 Subject: [PATCH 0240/3224] Server: more elegant isLevelGenerated() check --- src/pocketmine/Server.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index f2ab9819b4..2f1f5b818b 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1142,9 +1142,7 @@ class Server{ } $path = $this->getDataPath() . "worlds/" . $name . "/"; if(!($this->getLevelByName($name) instanceof Level)){ - return is_dir($path) and !empty(array_filter(scandir($path, SCANDIR_SORT_NONE), function($v){ - return $v !== ".." and $v !== "."; - })); + return !empty(LevelProviderManager::getMatchingProviders($path)); } return true; From 1b572d3e404d30001fcc52570250f822b3097b33 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 13 Oct 2018 15:43:43 +0100 Subject: [PATCH 0241/3224] Level: rename unload to onUnload() again, this is an intentional rug-jerk, along with a clearer naming. --- src/pocketmine/Server.php | 2 +- src/pocketmine/level/Level.php | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 2f1f5b818b..2dedebf33b 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -999,7 +999,7 @@ class Server{ throw new \InvalidStateException("The default level cannot be unloaded while running, please switch levels."); } - return $level->unload($forceUnload); + return $level->onUnload($forceUnload); } /** diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 2ef63effc7..eb1356983f 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -529,14 +529,12 @@ class Level implements ChunkManager, Metadatable{ /** * @internal DO NOT use this from plugins, it's for internal use only. Use Server->unloadLevel() instead. * - * Unloads the current level from memory safely - * * @param bool $force default false, force unload of default level * * @return bool * @throws \InvalidStateException if trying to unload a level during level tick */ - public function unload(bool $force = false) : bool{ + public function onUnload(bool $force = false) : bool{ if($this->doingTick and !$force){ throw new \InvalidStateException("Cannot unload a level during level tick"); } From 70054de5759025d8f67d3e27a334da808f965694 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 15 Oct 2018 18:08:07 +0100 Subject: [PATCH 0242/3224] Clean up garbage in Tree populators --- .../level/generator/object/BirchTree.php | 6 +-- .../level/generator/object/JungleTree.php | 5 +-- .../level/generator/object/OakTree.php | 4 +- .../level/generator/object/SpruceTree.php | 7 +-- .../level/generator/object/Tree.php | 43 +++++++++++-------- 5 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/pocketmine/level/generator/object/BirchTree.php b/src/pocketmine/level/generator/object/BirchTree.php index 1dedf230d1..be6046fb50 100644 --- a/src/pocketmine/level/generator/object/BirchTree.php +++ b/src/pocketmine/level/generator/object/BirchTree.php @@ -29,13 +29,11 @@ use pocketmine\level\ChunkManager; use pocketmine\utils\Random; class BirchTree extends Tree{ - + /** @var bool */ protected $superBirch = false; public function __construct(bool $superBirch = false){ - $this->trunkBlock = Block::LOG; - $this->leafBlock = Block::LEAVES; - $this->type = Wood::BIRCH; + parent::__construct(Block::LOG, Block::LEAVES, Wood::BIRCH); $this->superBirch = $superBirch; } diff --git a/src/pocketmine/level/generator/object/JungleTree.php b/src/pocketmine/level/generator/object/JungleTree.php index a237e5303a..ae749f0dfe 100644 --- a/src/pocketmine/level/generator/object/JungleTree.php +++ b/src/pocketmine/level/generator/object/JungleTree.php @@ -29,9 +29,6 @@ use pocketmine\block\Wood; class JungleTree extends Tree{ public function __construct(){ - $this->trunkBlock = Block::LOG; - $this->leafBlock = Block::LEAVES; - $this->type = Wood::JUNGLE; - $this->treeHeight = 8; + parent::__construct(Block::LOG, Block::LEAVES, Wood::JUNGLE, 8); } } diff --git a/src/pocketmine/level/generator/object/OakTree.php b/src/pocketmine/level/generator/object/OakTree.php index 27d24326d1..66e7f81d78 100644 --- a/src/pocketmine/level/generator/object/OakTree.php +++ b/src/pocketmine/level/generator/object/OakTree.php @@ -31,9 +31,7 @@ use pocketmine\utils\Random; class OakTree extends Tree{ public function __construct(){ - $this->trunkBlock = Block::LOG; - $this->leafBlock = Block::LEAVES; - $this->type = Wood::OAK; + parent::__construct(Block::LOG, Block::LEAVES, Wood::OAK); } public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ diff --git a/src/pocketmine/level/generator/object/SpruceTree.php b/src/pocketmine/level/generator/object/SpruceTree.php index 8201e20b41..2ff0304ac7 100644 --- a/src/pocketmine/level/generator/object/SpruceTree.php +++ b/src/pocketmine/level/generator/object/SpruceTree.php @@ -32,10 +32,7 @@ use pocketmine\utils\Random; class SpruceTree extends Tree{ public function __construct(){ - $this->trunkBlock = Block::LOG; - $this->leafBlock = Block::LEAVES; - $this->type = Wood::SPRUCE; - $this->treeHeight = 10; + parent::__construct(Block::LOG, Block::LEAVES, Wood::SPRUCE, 10); } public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ @@ -63,7 +60,7 @@ class SpruceTree extends Tree{ if(!BlockFactory::get($level->getBlockIdAt($xx, $yyy, $zz))->isSolid()){ $level->setBlockIdAt($xx, $yyy, $zz, $this->leafBlock); - $level->setBlockDataAt($xx, $yyy, $zz, $this->type); + $level->setBlockDataAt($xx, $yyy, $zz, $this->blockMeta); } } } diff --git a/src/pocketmine/level/generator/object/Tree.php b/src/pocketmine/level/generator/object/Tree.php index 5b9110f9e1..5d3367bdbb 100644 --- a/src/pocketmine/level/generator/object/Tree.php +++ b/src/pocketmine/level/generator/object/Tree.php @@ -25,25 +25,30 @@ namespace pocketmine\level\generator\object; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\Leaves; +use pocketmine\block\Sapling; use pocketmine\block\utils\WoodType; +use pocketmine\block\Wood; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; abstract class Tree{ - public $overridable = [ - Block::AIR => true, - Block::SAPLING => true, - Block::LOG => true, - Block::LEAVES => true, - Block::SNOW_LAYER => true, - Block::LOG2 => true, - Block::LEAVES2 => true - ]; - public $type = 0; - public $trunkBlock = Block::LOG; - public $leafBlock = Block::LEAVES; - public $treeHeight = 7; + /** @var int */ + protected $blockMeta; + /** @var int */ + protected $trunkBlock; + /** @var int */ + protected $leafBlock; + /** @var int */ + protected $treeHeight; + + public function __construct(int $trunkBlock, int $leafBlock, int $blockMeta, int $treeHeight = 7){ + $this->trunkBlock = $trunkBlock; + $this->leafBlock = $leafBlock; + $this->blockMeta = $blockMeta; + $this->treeHeight = $treeHeight; + } public static function growTree(ChunkManager $level, int $x, int $y, int $z, Random $random, int $type = WoodType::OAK) : void{ switch($type){ @@ -86,7 +91,7 @@ abstract class Tree{ } for($xx = -$radiusToCheck; $xx < ($radiusToCheck + 1); ++$xx){ for($zz = -$radiusToCheck; $zz < ($radiusToCheck + 1); ++$zz){ - if(!isset($this->overridable[$level->getBlockIdAt($x + $xx, $y + $yy, $z + $zz)])){ + if(!$this->canOverride(BlockFactory::get($level->getBlockIdAt($x + $xx, $y + $yy, $z + $zz)))){ return false; } } @@ -111,7 +116,7 @@ abstract class Tree{ } if(!BlockFactory::get($level->getBlockIdAt($xx, $yy, $zz))->isSolid()){ $level->setBlockIdAt($xx, $yy, $zz, $this->leafBlock); - $level->setBlockDataAt($xx, $yy, $zz, $this->type); + $level->setBlockDataAt($xx, $yy, $zz, $this->blockMeta); } } } @@ -124,10 +129,14 @@ abstract class Tree{ for($yy = 0; $yy < $trunkHeight; ++$yy){ $blockId = $level->getBlockIdAt($x, $y + $yy, $z); - if(isset($this->overridable[$blockId])){ + if($this->canOverride(BlockFactory::get($blockId))){ $level->setBlockIdAt($x, $y + $yy, $z, $this->trunkBlock); - $level->setBlockDataAt($x, $y + $yy, $z, $this->type); + $level->setBlockDataAt($x, $y + $yy, $z, $this->blockMeta); } } } + + protected function canOverride(Block $block) : bool{ + return $block->canBeReplaced() or $block instanceof Wood or $block instanceof Sapling or $block instanceof Leaves; + } } From ec5af0398e68bb22f5e29ed2106cb2922c02c5d4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 16 Oct 2018 16:46:27 +0100 Subject: [PATCH 0243/3224] VersionString: use appropriate regex for number matching --- src/pocketmine/utils/VersionString.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/utils/VersionString.php b/src/pocketmine/utils/VersionString.php index 4c512f47d1..51757a872c 100644 --- a/src/pocketmine/utils/VersionString.php +++ b/src/pocketmine/utils/VersionString.php @@ -55,7 +55,7 @@ class VersionString{ $this->development = $isDevBuild; $this->build = $buildNumber; - preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)(?:-(.*))?$/', $this->baseVersion, $matches); + preg_match('/(\d+)\.(\d+)\.(\d+)(?:-(.*))?$/', $this->baseVersion, $matches); if(count($matches) < 4){ throw new \InvalidArgumentException("Invalid base version \"$baseVersion\", should contain at least 3 version digits"); } From 9284e53f9eb522c9bf335229de44148ae0824f09 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Oct 2018 14:58:57 +0100 Subject: [PATCH 0244/3224] Added failing test case for #2483 --- tests/phpunit/item/ItemTest.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/phpunit/item/ItemTest.php b/tests/phpunit/item/ItemTest.php index f1be994f38..de3103167d 100644 --- a/tests/phpunit/item/ItemTest.php +++ b/tests/phpunit/item/ItemTest.php @@ -76,4 +76,12 @@ class ItemTest extends TestCase{ self::assertEquals($id, $item->getId()); self::assertEquals($meta, $item->getDamage()); } + + /** + * Test that durable items are correctly created by the item factory + */ + public function testGetDurableItem() : void{ + self::assertInstanceOf(Sword::class, ItemFactory::get(Item::WOODEN_SWORD)); + self::assertInstanceOf(Sword::class, ItemFactory::get(Item::WOODEN_SWORD, 1)); + } } From f81849e55062538d81f4b89162c70c735b9c0def Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Oct 2018 15:02:52 +0100 Subject: [PATCH 0245/3224] ItemFactory: fix special case handling for durable items, close #2483 --- src/pocketmine/item/ItemFactory.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index a796eaf36c..d3bfb0c3fc 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -347,8 +347,16 @@ class ItemFactory{ $sublist = self::$list[self::getListOffset($id)]; /** @var Item|null $listed */ - if($sublist !== null and isset($sublist[$meta])){ - $item = clone $sublist[$meta]; + if($sublist !== null){ + if(isset($sublist[$meta])){ + $item = clone $sublist[$meta]; + }elseif(isset($sublist[0]) and $sublist[0] instanceof Durable){ + /** @var Durable $item */ + $item = clone $sublist[0]; + $item->setDamage($meta); + }else{ + throw new \InvalidArgumentException("Unknown variant $meta of item ID $id"); + } }elseif($id < 256){ //intentionally includes negatives, for extended block IDs /* Blocks must have a damage value 0-15, but items can have damage value -1 to indicate that they are * crafting ingredients with any-damage. */ @@ -363,9 +371,6 @@ class ItemFactory{ $item->setCount($count); $item->setCompoundTag($tags); - if($item instanceof Durable){ //nasty, but necessary for BC reasons - $item->setDamage($meta); - } return $item; } From e7494fff962324283660068fbda32e8c8237b365 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Oct 2018 15:08:08 +0100 Subject: [PATCH 0246/3224] - the fix didn't fix this is a mess it would be nice not to have to start the server to find these kinds of bugs >.< --- src/pocketmine/item/ItemFactory.php | 46 ++++++++++++++++------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index d3bfb0c3fc..d5a291fa41 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -343,30 +343,34 @@ class ItemFactory{ throw new \TypeError("`tags` argument must be a string or CompoundTag instance, " . (is_object($tags) ? "instance of " . get_class($tags) : gettype($tags)) . " given"); } - try{ - $sublist = self::$list[self::getListOffset($id)]; + /** @var Item $item */ + $item = null; + if($meta !== -1){ + try{ + $sublist = self::$list[self::getListOffset($id)]; - /** @var Item|null $listed */ - if($sublist !== null){ - if(isset($sublist[$meta])){ - $item = clone $sublist[$meta]; - }elseif(isset($sublist[0]) and $sublist[0] instanceof Durable){ - /** @var Durable $item */ - $item = clone $sublist[0]; - $item->setDamage($meta); - }else{ - throw new \InvalidArgumentException("Unknown variant $meta of item ID $id"); + /** @var Item|null $listed */ + if($sublist !== null){ + if(isset($sublist[$meta])){ + $item = clone $sublist[$meta]; + }elseif(isset($sublist[0]) and $sublist[0] instanceof Durable){ + /** @var Durable $item */ + $item = clone $sublist[0]; + $item->setDamage($meta); + } + }elseif($id < 256){ //intentionally includes negatives, for extended block IDs + /* Blocks must have a damage value 0-15, but items can have damage value -1 to indicate that they are + * crafting ingredients with any-damage. */ + $item = new ItemBlock($id, $meta); } - }elseif($id < 256){ //intentionally includes negatives, for extended block IDs - /* Blocks must have a damage value 0-15, but items can have damage value -1 to indicate that they are - * crafting ingredients with any-damage. */ - $item = new ItemBlock($id, $meta); - }else{ - //negative damage values will fallthru to here, to avoid crazy shit with crafting wildcard hacks - $item = new Item($id, $meta); + }catch(\RuntimeException $e){ + throw new \InvalidArgumentException("Item ID $id is invalid or out of bounds"); } - }catch(\RuntimeException $e){ - throw new \InvalidArgumentException("Item ID $id is invalid or out of bounds"); + } + + if($item === null){ + //negative damage values will fallthru to here, to avoid crazy shit with crafting wildcard hacks + $item = new Item($id, $meta); } $item->setCount($count); From a2a6286e1c51c8d5617120f1ab07400aa0f4edf4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Oct 2018 17:12:53 +0100 Subject: [PATCH 0247/3224] ItemFactory: clean up some unnecessary code this try/catch isn't needed because the list offset derivation function will deal with invalid IDs anyway. --- src/pocketmine/item/ItemFactory.php | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index d5a291fa41..4493b88a75 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -346,25 +346,19 @@ class ItemFactory{ /** @var Item $item */ $item = null; if($meta !== -1){ - try{ - $sublist = self::$list[self::getListOffset($id)]; + $sublist = self::$list[self::getListOffset($id)]; - /** @var Item|null $listed */ - if($sublist !== null){ - if(isset($sublist[$meta])){ - $item = clone $sublist[$meta]; - }elseif(isset($sublist[0]) and $sublist[0] instanceof Durable){ - /** @var Durable $item */ - $item = clone $sublist[0]; - $item->setDamage($meta); - } - }elseif($id < 256){ //intentionally includes negatives, for extended block IDs - /* Blocks must have a damage value 0-15, but items can have damage value -1 to indicate that they are - * crafting ingredients with any-damage. */ - $item = new ItemBlock($id, $meta); + /** @var Item|null $listed */ + if($sublist !== null){ + if(isset($sublist[$meta])){ + $item = clone $sublist[$meta]; + }elseif(isset($sublist[0]) and $sublist[0] instanceof Durable){ + /** @var Durable $item */ + $item = clone $sublist[0]; + $item->setDamage($meta); } - }catch(\RuntimeException $e){ - throw new \InvalidArgumentException("Item ID $id is invalid or out of bounds"); + }elseif($id < 256){ //intentionally includes negatives, for extended block IDs + $item = new ItemBlock($id, $meta); } } From 20b87b7875441983b6e7dd6dd201860170dcb2f1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Oct 2018 15:43:17 +0100 Subject: [PATCH 0248/3224] Level: reduce complexity of populateChunk() --- src/pocketmine/level/Level.php | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index eb1356983f..355f94f79f 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -2903,35 +2903,31 @@ class Level implements ChunkManager, Metadatable{ if(isset($this->chunkPopulationQueue[$index = Level::chunkHash($x, $z)]) or (count($this->chunkPopulationQueue) >= $this->chunkPopulationQueueSize and !$force)){ return false; } + for($xx = -1; $xx <= 1; ++$xx){ + for($zz = -1; $zz <= 1; ++$zz){ + if(isset($this->chunkPopulationLock[Level::chunkHash($x + $xx, $z + $zz)])){ + return false; + } + } + } $chunk = $this->getChunk($x, $z, true); if(!$chunk->isPopulated()){ Timings::$populationTimer->startTiming(); - $populate = true; + + $this->chunkPopulationQueue[$index] = true; for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ - if(isset($this->chunkPopulationLock[Level::chunkHash($x + $xx, $z + $zz)])){ - $populate = false; - break; - } + $this->chunkPopulationLock[Level::chunkHash($x + $xx, $z + $zz)] = true; } } - if($populate){ - $this->chunkPopulationQueue[$index] = true; - for($xx = -1; $xx <= 1; ++$xx){ - for($zz = -1; $zz <= 1; ++$zz){ - $this->chunkPopulationLock[Level::chunkHash($x + $xx, $z + $zz)] = true; - } - } - - $task = new PopulationTask($this, $chunk); - $workerId = $this->server->getAsyncPool()->selectWorker(); - if(!isset($this->generatorRegisteredWorkers[$workerId])){ - $this->registerGeneratorToWorker($workerId); - } - $this->server->getAsyncPool()->submitTaskToWorker($task, $workerId); + $task = new PopulationTask($this, $chunk); + $workerId = $this->server->getAsyncPool()->selectWorker(); + if(!isset($this->generatorRegisteredWorkers[$workerId])){ + $this->registerGeneratorToWorker($workerId); } + $this->server->getAsyncPool()->submitTaskToWorker($task, $workerId); Timings::$populationTimer->stopTiming(); return false; From d88b32da91392c68eeca3c5b621fae3362ec9945 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Oct 2018 13:43:01 +0100 Subject: [PATCH 0249/3224] Drop useless numeric IDs for attributes, use strings instead --- src/pocketmine/entity/Attribute.php | 85 +++++++------------ src/pocketmine/entity/AttributeMap.php | 10 +-- .../network/mcpe/NetworkBinaryStream.php | 8 +- .../network/mcpe/protocol/AddEntityPacket.php | 8 +- .../mcpe/protocol/UpdateAttributesPacket.php | 2 +- 5 files changed, 46 insertions(+), 67 deletions(-) diff --git a/src/pocketmine/entity/Attribute.php b/src/pocketmine/entity/Attribute.php index 835a2debea..c4dd3477b5 100644 --- a/src/pocketmine/entity/Attribute.php +++ b/src/pocketmine/entity/Attribute.php @@ -24,26 +24,26 @@ declare(strict_types=1); namespace pocketmine\entity; class Attribute{ + public const MC_PREFIX = "minecraft:"; - public const ABSORPTION = 0; - public const SATURATION = 1; - public const EXHAUSTION = 2; - public const KNOCKBACK_RESISTANCE = 3; - public const HEALTH = 4; - public const MOVEMENT_SPEED = 5; - public const FOLLOW_RANGE = 6; - public const HUNGER = 7; - public const FOOD = 7; - public const ATTACK_DAMAGE = 8; - public const EXPERIENCE_LEVEL = 9; - public const EXPERIENCE = 10; + public const ABSORPTION = self::MC_PREFIX . "absorption"; + public const SATURATION = self::MC_PREFIX . "player.saturation"; + public const EXHAUSTION = self::MC_PREFIX . "player.exhaustion"; + public const KNOCKBACK_RESISTANCE = self::MC_PREFIX . "knockback_resistance"; + public const HEALTH = self::MC_PREFIX . "health"; + public const MOVEMENT_SPEED = self::MC_PREFIX . "movement"; + public const FOLLOW_RANGE = self::MC_PREFIX . "follow_range"; + public const HUNGER = self::MC_PREFIX . "player.hunger"; + public const FOOD = self::HUNGER; + public const ATTACK_DAMAGE = self::MC_PREFIX . "attack_damage"; + public const EXPERIENCE_LEVEL = self::MC_PREFIX . "player.level"; + public const EXPERIENCE = self::MC_PREFIX . "player.experience"; - private $id; + protected $id; protected $minValue; protected $maxValue; protected $defaultValue; protected $currentValue; - protected $name; protected $shouldSend; protected $desynchronized = true; @@ -52,24 +52,23 @@ class Attribute{ protected static $attributes = []; public static function init() : void{ - self::addAttribute(self::ABSORPTION, "minecraft:absorption", 0.00, 340282346638528859811704183484516925440.00, 0.00); - self::addAttribute(self::SATURATION, "minecraft:player.saturation", 0.00, 20.00, 20.00); - self::addAttribute(self::EXHAUSTION, "minecraft:player.exhaustion", 0.00, 5.00, 0.0); - self::addAttribute(self::KNOCKBACK_RESISTANCE, "minecraft:knockback_resistance", 0.00, 1.00, 0.00); - self::addAttribute(self::HEALTH, "minecraft:health", 0.00, 20.00, 20.00); - self::addAttribute(self::MOVEMENT_SPEED, "minecraft:movement", 0.00, 340282346638528859811704183484516925440.00, 0.10); - self::addAttribute(self::FOLLOW_RANGE, "minecraft:follow_range", 0.00, 2048.00, 16.00, false); - self::addAttribute(self::HUNGER, "minecraft:player.hunger", 0.00, 20.00, 20.00); - self::addAttribute(self::ATTACK_DAMAGE, "minecraft:attack_damage", 0.00, 340282346638528859811704183484516925440.00, 1.00, false); - self::addAttribute(self::EXPERIENCE_LEVEL, "minecraft:player.level", 0.00, 24791.00, 0.00); - self::addAttribute(self::EXPERIENCE, "minecraft:player.experience", 0.00, 1.00, 0.00); + self::addAttribute(self::ABSORPTION, 0.00, 340282346638528859811704183484516925440.00, 0.00); + self::addAttribute(self::SATURATION, 0.00, 20.00, 20.00); + self::addAttribute(self::EXHAUSTION, 0.00, 5.00, 0.0); + self::addAttribute(self::KNOCKBACK_RESISTANCE, 0.00, 1.00, 0.00); + self::addAttribute(self::HEALTH, 0.00, 20.00, 20.00); + self::addAttribute(self::MOVEMENT_SPEED, 0.00, 340282346638528859811704183484516925440.00, 0.10); + self::addAttribute(self::FOLLOW_RANGE, 0.00, 2048.00, 16.00, false); + self::addAttribute(self::HUNGER, 0.00, 20.00, 20.00); + self::addAttribute(self::ATTACK_DAMAGE, 0.00, 340282346638528859811704183484516925440.00, 1.00, false); + self::addAttribute(self::EXPERIENCE_LEVEL, 0.00, 24791.00, 0.00); + self::addAttribute(self::EXPERIENCE, 0.00, 1.00, 0.00); //TODO: minecraft:luck (for fishing?) //TODO: minecraft:fall_damage } /** - * @param int $id - * @param string $name + * @param string $id * @param float $minValue * @param float $maxValue * @param float $defaultValue @@ -79,41 +78,25 @@ class Attribute{ * * @throws \InvalidArgumentException */ - public static function addAttribute(int $id, string $name, float $minValue, float $maxValue, float $defaultValue, bool $shouldSend = true) : Attribute{ + public static function addAttribute(string $id, float $minValue, float $maxValue, float $defaultValue, bool $shouldSend = true) : Attribute{ if($minValue > $maxValue or $defaultValue > $maxValue or $defaultValue < $minValue){ throw new \InvalidArgumentException("Invalid ranges: min value: $minValue, max value: $maxValue, $defaultValue: $defaultValue"); } - return self::$attributes[$id] = new Attribute($id, $name, $minValue, $maxValue, $defaultValue, $shouldSend); + return self::$attributes[$id] = new Attribute($id, $minValue, $maxValue, $defaultValue, $shouldSend); } /** - * @param int $id + * @param string $id * * @return Attribute|null */ - public static function getAttribute(int $id) : ?Attribute{ + public static function getAttribute(string $id) : ?Attribute{ return isset(self::$attributes[$id]) ? clone self::$attributes[$id] : null; } - /** - * @param string $name - * - * @return Attribute|null - */ - public static function getAttributeByName(string $name) : ?Attribute{ - foreach(self::$attributes as $a){ - if($a->getName() === $name){ - return clone $a; - } - } - - return null; - } - - private function __construct(int $id, string $name, float $minValue, float $maxValue, float $defaultValue, bool $shouldSend = true){ + private function __construct(string $id, float $minValue, float $maxValue, float $defaultValue, bool $shouldSend = true){ $this->id = $id; - $this->name = $name; $this->minValue = $minValue; $this->maxValue = $maxValue; $this->defaultValue = $defaultValue; @@ -203,11 +186,7 @@ class Attribute{ return $this; } - public function getName() : string{ - return $this->name; - } - - public function getId() : int{ + public function getId() : string{ return $this->id; } diff --git a/src/pocketmine/entity/AttributeMap.php b/src/pocketmine/entity/AttributeMap.php index dd07a8619a..5ff7e3392a 100644 --- a/src/pocketmine/entity/AttributeMap.php +++ b/src/pocketmine/entity/AttributeMap.php @@ -32,11 +32,11 @@ class AttributeMap implements \ArrayAccess{ } /** - * @param int $id + * @param string $id * * @return Attribute|null */ - public function getAttribute(int $id) : ?Attribute{ + public function getAttribute(string $id) : ?Attribute{ return $this->attributes[$id] ?? null; } @@ -61,7 +61,7 @@ class AttributeMap implements \ArrayAccess{ } /** - * @param int $offset + * @param string $offset * * @return float */ @@ -70,8 +70,8 @@ class AttributeMap implements \ArrayAccess{ } /** - * @param int $offset - * @param float $value + * @param string $offset + * @param float $value */ public function offsetSet($offset, $value) : void{ $this->attributes[$offset]->setValue($value); diff --git a/src/pocketmine/network/mcpe/NetworkBinaryStream.php b/src/pocketmine/network/mcpe/NetworkBinaryStream.php index bb6101491d..75139ad273 100644 --- a/src/pocketmine/network/mcpe/NetworkBinaryStream.php +++ b/src/pocketmine/network/mcpe/NetworkBinaryStream.php @@ -236,9 +236,9 @@ class NetworkBinaryStream extends BinaryStream{ $max = $this->getLFloat(); $current = $this->getLFloat(); $default = $this->getLFloat(); - $name = $this->getString(); + $id = $this->getString(); - $attr = Attribute::getAttributeByName($name); + $attr = Attribute::getAttribute($id); if($attr !== null){ $attr->setMinValue($min); $attr->setMaxValue($max); @@ -247,7 +247,7 @@ class NetworkBinaryStream extends BinaryStream{ $list[] = $attr; }else{ - throw new \UnexpectedValueException("Unknown attribute type \"$name\""); + throw new \UnexpectedValueException("Unknown attribute type \"$id\""); } } @@ -266,7 +266,7 @@ class NetworkBinaryStream extends BinaryStream{ $this->putLFloat($attribute->getMaxValue()); $this->putLFloat($attribute->getValue()); $this->putLFloat($attribute->getDefaultValue()); - $this->putString($attribute->getName()); + $this->putString($attribute->getId()); } } diff --git a/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php b/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php index 5ea109c7f2..68d8df9bc4 100644 --- a/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php @@ -69,11 +69,11 @@ class AddEntityPacket extends DataPacket{ $attrCount = $this->getUnsignedVarInt(); for($i = 0; $i < $attrCount; ++$i){ - $name = $this->getString(); + $id = $this->getString(); $min = $this->getLFloat(); $current = $this->getLFloat(); $max = $this->getLFloat(); - $attr = Attribute::getAttributeByName($name); + $attr = Attribute::getAttribute($id); if($attr !== null){ $attr->setMinValue($min); @@ -81,7 +81,7 @@ class AddEntityPacket extends DataPacket{ $attr->setValue($current); $this->attributes[] = $attr; }else{ - throw new \UnexpectedValueException("Unknown attribute type \"$name\""); + throw new \UnexpectedValueException("Unknown attribute type \"$id\""); } } @@ -104,7 +104,7 @@ class AddEntityPacket extends DataPacket{ $this->putUnsignedVarInt(count($this->attributes)); foreach($this->attributes as $attribute){ - $this->putString($attribute->getName()); + $this->putString($attribute->getId()); $this->putLFloat($attribute->getMinValue()); $this->putLFloat($attribute->getValue()); $this->putLFloat($attribute->getMaxValue()); diff --git a/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php index 77e1b97184..7d3277cd91 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php @@ -44,7 +44,7 @@ class UpdateAttributesPacket extends DataPacket{ protected function encodePayload() : void{ $this->putEntityRuntimeId($this->entityRuntimeId); - $this->putAttributeList(...$this->entries); + $this->putAttributeList(...array_values($this->entries)); } public function handle(SessionHandler $handler) : bool{ From 93b8a6c44a8a38d26cd48d98c3ceb83644dfbfa2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Oct 2018 18:52:42 +0100 Subject: [PATCH 0250/3224] Level: fix light removal bugs caused by 48a5eeb3a459cb90b302990d3f243a34b0bb7da0 and 19e68f98a707536866c33bb1e9fad9f7c280447d BlockFactory::\$lightFilter and Block->getLightFilter() are not equivalent. --- src/pocketmine/level/Level.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index d5ffaf30eb..537b1caf1d 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1418,7 +1418,7 @@ class Level implements ChunkManager, Metadatable{ $this->skyLightUpdate->setAndUpdateLight($x, $i, $z, 15); } }else{ //No heightmap change, block changed "underground" - $this->skyLightUpdate->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentBlockSkyLight($x, $y, $z) - $source->getLightFilter())); + $this->skyLightUpdate->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentBlockSkyLight($x, $y, $z) - BlockFactory::$lightFilter[($source->getId() << 4) | $source->getDamage()])); } $this->timings->doBlockSkyLightUpdates->stopTiming(); @@ -1448,7 +1448,7 @@ class Level implements ChunkManager, Metadatable{ $this->timings->doBlockLightUpdates->startTiming(); $block = $this->getBlockAt($x, $y, $z); - $newLevel = max($block->getLightLevel(), $this->getHighestAdjacentBlockLight($x, $y, $z) - $block->getLightFilter()); + $newLevel = max($block->getLightLevel(), $this->getHighestAdjacentBlockLight($x, $y, $z) - BlockFactory::$lightFilter[($block->getId() << 4) | $block->getDamage()]); if($this->blockLightUpdate === null){ $this->blockLightUpdate = new BlockLightUpdate($this); From 517a21c418df50e8336885d4ac9eae76d71f7795 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Oct 2018 14:19:27 +0100 Subject: [PATCH 0251/3224] RegionLoader: remove unused constant --- src/pocketmine/level/format/io/region/RegionLoader.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pocketmine/level/format/io/region/RegionLoader.php b/src/pocketmine/level/format/io/region/RegionLoader.php index 50ad077488..1412f759d8 100644 --- a/src/pocketmine/level/format/io/region/RegionLoader.php +++ b/src/pocketmine/level/format/io/region/RegionLoader.php @@ -29,7 +29,6 @@ use pocketmine\utils\Binary; use pocketmine\utils\MainLogger; class RegionLoader{ - public const VERSION = 1; public const COMPRESSION_GZIP = 1; public const COMPRESSION_ZLIB = 2; From e035be8498f4510bb487da51aa6eeee132eae84c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Oct 2018 15:27:08 +0100 Subject: [PATCH 0252/3224] Remove some master-only usages of addGlobalPacket() --- src/pocketmine/level/Level.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 33a1f7a291..bf316bcde0 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -698,7 +698,7 @@ class Level implements ChunkManager, Metadatable{ $pk->time = $this->time; if(empty($targets)){ - $this->addGlobalPacket($pk); + $this->broadcastGlobalPacket($pk); }else{ $this->server->broadcastPacket($targets, $pk); } @@ -2922,7 +2922,7 @@ class Level implements ChunkManager, Metadatable{ $pk = new SetDifficultyPacket(); $pk->difficulty = $this->getDifficulty(); if(empty($targets)){ - $this->addGlobalPacket($pk); + $this->broadcastGlobalPacket($pk); }else{ $this->server->broadcastPacket($targets, $pk); } From 605e7e08ed716b589edddaca96821595c4589c34 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Oct 2018 15:29:43 +0100 Subject: [PATCH 0253/3224] Remove some deprecated methods --- src/pocketmine/Server.php | 8 -------- src/pocketmine/level/Level.php | 10 ---------- src/pocketmine/plugin/PluginManager.php | 12 ------------ 3 files changed, 30 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index f9e3704506..29f541ce97 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -556,14 +556,6 @@ class Server{ return $this->getConfigInt("spawn-protection", 16); } - /** - * @deprecated - * @return bool - */ - public function getAllowFlight() : bool{ - return true; - } - /** * @return bool */ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index bf316bcde0..5ae154e178 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -631,16 +631,6 @@ class Level implements ChunkManager, Metadatable{ $this->globalPackets[] = $packet; } - /** - * @deprecated - * @see Level::broadcastGlobalPacket() - * - * @param DataPacket $packet - */ - public function addGlobalPacket(DataPacket $packet) : void{ - $this->globalPackets[] = $packet; - } - public function registerChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ, bool $autoLoad = true){ $hash = $loader->getLoaderId(); diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index 98f1dd960d..188c4c7e9f 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -524,18 +524,6 @@ class PluginManager{ $this->fileAssociations = []; } - /** - * Calls an event - * - * @deprecated - * @see Event::call() - * - * @param Event $event - */ - public function callEvent(Event $event){ - $event->call(); - } - /** * Registers all the events in the given Listener class * From bae140dc028364b273c643b0d8064c4f46a30bb5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Oct 2018 19:05:39 +0100 Subject: [PATCH 0254/3224] Entity: remove dead code --- src/pocketmine/entity/Entity.php | 41 -------------------------------- 1 file changed, 41 deletions(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 7364654d70..7fcd7f8ec6 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -1461,47 +1461,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ return $block->isSolid() and !$block->isTransparent() and $block->collidesWithBB($this->getBoundingBox()); } - public function fastMove(float $dx, float $dy, float $dz) : bool{ - $this->blocksAround = null; - - if($dx == 0 and $dz == 0 and $dy == 0){ - return true; - } - - Timings::$entityMoveTimer->startTiming(); - - $newBB = $this->boundingBox->offsetCopy($dx, $dy, $dz); - - $list = $this->level->getCollisionCubes($this, $newBB, false); - - if(count($list) === 0){ - $this->boundingBox = $newBB; - } - - $this->x = ($this->boundingBox->minX + $this->boundingBox->maxX) / 2; - $this->y = $this->boundingBox->minY - $this->ySize; - $this->z = ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2; - - $this->checkChunks(); - - if(!$this->onGround or $dy != 0){ - $bb = clone $this->boundingBox; - $bb->minY -= 0.75; - $this->onGround = false; - - if(count($this->level->getCollisionBlocks($bb)) > 0){ - $this->onGround = true; - } - } - $this->isCollided = $this->onGround; - $this->updateFallState($dy, $this->onGround); - - - Timings::$entityMoveTimer->stopTiming(); - - return true; - } - public function move(float $dx, float $dy, float $dz) : void{ $this->blocksAround = null; From 742fbc25c3104ca1f4855b030339accbeb911c6a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Oct 2018 21:42:34 +0100 Subject: [PATCH 0255/3224] BlockFactory: fixed 0 being assumed to be default if used this defeated the whole point of adding this code ... --- src/pocketmine/block/BlockFactory.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 9fd5c8625f..c793caae6e 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -467,9 +467,8 @@ class BlockFactory{ if(!$override and self::isRegistered($id, $variant)){ throw new \InvalidArgumentException("Block registration conflicts with an existing block"); } - self::fillStaticArrays(($id << 4) | $variant, $block); //register default state mapped to variant, for blocks which don't use 0 as valid state - for($m = $variant + 1; $m <= ($variant | $stateMask); ++$m){ + for($m = $variant; $m <= ($variant | $stateMask); ++$m){ if(($m & ~$stateMask) !== $variant){ continue; } @@ -486,6 +485,10 @@ class BlockFactory{ self::fillStaticArrays($index, $v); } } + + if(!self::isRegistered($id, $variant)){ + self::fillStaticArrays(($id << 4) | $variant, $block); //register default state mapped to variant, for blocks which don't use 0 as valid state + } } private static function fillStaticArrays(int $index, Block $block) : void{ From 08cf7e489fe2957cf4b0831a0ab4dbe2f11d32db Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 21 Oct 2018 15:23:06 +0100 Subject: [PATCH 0256/3224] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 59 ++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000000..d3f95d40bc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,59 @@ +--- +name: Bug report +about: Report a bug in PocketMine-MP (not plugins) + +--- + +### Issue description + + + + + +- Expected result: What were you expecting to happen? +- Actual result: What actually happened? + +### Steps to reproduce the issue + +1. ... +2. ... + +### OS and versions + +* PocketMine-MP: +* PHP: +* Server OS: +* Game version: PE/Win10 (delete as appropriate) + +### Plugins +- Test on a clean server without plugins: is the issue reproducible without any plugins loaded? + +If the issue is **not** reproducible without plugins: +- Have you asked for help on our forums before creating an issue? +- Can you provide sample, *minimal* reproducing code for the issue? If so, paste it in the bottom section +- Paste your list of plugins here (use the 'plugins' command in PocketMine-MP) + +### Crashdump, backtrace or other files +- Do not paste crashdumps into an issue - please use our Crash Archive at https://crash.pmmp.io for submitting crash reports to not spam the issue tracker. Add links to your reports in the Crash Archive here. +- Please use gist or anything else to add other files and add links here + +* ... From 62db7727c042cece8a79cfdca57c5c5d860a1ed0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 21 Oct 2018 15:23:46 +0100 Subject: [PATCH 0257/3224] Remove legacy issue template --- .github/ISSUE_TEMPLATE.md | 53 --------------------------------------- 1 file changed, 53 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index b2d513eae3..0000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,53 +0,0 @@ -### Issue description - - - - - -- Expected result: What were you expecting to happen? -- Actual result: What actually happened? - -### Steps to reproduce the issue - -1. ... -2. ... - -### OS and versions - -* PocketMine-MP: -* PHP: -* Server OS: -* Game version: PE/Win10 (delete as appropriate) - -### Plugins -- Test on a clean server without plugins: is the issue reproducible without any plugins loaded? - -If the issue is **not** reproducible without plugins: -- Have you asked for help on our forums before creating an issue? -- Can you provide sample, *minimal* reproducing code for the issue? If so, paste it in the bottom section -- Paste your list of plugins here (use the 'plugins' command in PocketMine-MP) - -### Crashdump, backtrace or other files -- Do not paste crashdumps into an issue - please use our Crash Archive at https://crash.pmmp.io for submitting crash reports to not spam the issue tracker. Add links to your reports in the Crash Archive here. -- Please use gist or anything else to add other files and add links here - -* ... From 011b9ae159e9d1e97fa304e4da598a81b1806759 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 23 Oct 2018 16:47:00 +0100 Subject: [PATCH 0258/3224] Update to latest NBT lib version --- composer.json | 2 +- composer.lock | 15 ++++++++------- src/pocketmine/Player.php | 4 ---- src/pocketmine/Server.php | 7 +------ src/pocketmine/item/Item.php | 7 +------ .../level/format/io/data/BedrockLevelData.php | 12 +++++------- .../level/format/io/data/JavaLevelData.php | 2 +- .../level/format/io/leveldb/LevelDB.php | 13 ++++--------- .../format/io/region/LegacyAnvilChunkTrait.php | 2 +- .../level/format/io/region/McRegion.php | 2 +- 10 files changed, 23 insertions(+), 43 deletions(-) diff --git a/composer.json b/composer.json index 916c15babb..3379374fe0 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,7 @@ "pocketmine/raklib": "^0.12.0", "pocketmine/spl": "^0.3.0", "pocketmine/binaryutils": "^0.1.0", - "pocketmine/nbt": "^0.2.1", + "pocketmine/nbt": "dev-master", "pocketmine/math": "dev-master", "pocketmine/snooze": "^0.1.0" }, diff --git a/composer.lock b/composer.lock index 13a9d7565f..458b80b1de 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "cef68cbc2596130f6b20e6f2ecdfd58d", + "content-hash": "28f054aefede2c0dc4f220d5c4a918a0", "packages": [ { "name": "fgrosse/phpasn1", @@ -222,16 +222,16 @@ }, { "name": "pocketmine/nbt", - "version": "0.2.2", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "474f0cf0a47656d0122b4f3f71302e694ed6977b" + "reference": "db491f3309231e56f2640a047f665a0131c23538" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/474f0cf0a47656d0122b4f3f71302e694ed6977b", - "reference": "474f0cf0a47656d0122b4f3f71302e694ed6977b", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/db491f3309231e56f2640a047f665a0131c23538", + "reference": "db491f3309231e56f2640a047f665a0131c23538", "shasum": "" }, "require": { @@ -255,10 +255,10 @@ ], "description": "PHP library for working with Named Binary Tags", "support": { - "source": "https://github.com/pmmp/NBT/tree/0.2.2", + "source": "https://github.com/pmmp/NBT/tree/master", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2018-10-12T08:26:44+00:00" + "time": "2018-10-23T15:23:36+00:00" }, { "name": "pocketmine/raklib", @@ -373,6 +373,7 @@ "minimum-stability": "stable", "stability-flags": { "ext-pthreads": 20, + "pocketmine/nbt": 20, "pocketmine/math": 20 }, "prefer-stable": false, diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 64f1272f34..03a1f98585 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2435,10 +2435,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ if($t instanceof Spawnable){ $nbt = new NetworkLittleEndianNBTStream(); $compound = $nbt->read($packet->namedtag); - - if(!($compound instanceof CompoundTag)){ - throw new \InvalidArgumentException("Expected " . CompoundTag::class . " in block entity NBT, got " . (is_object($compound) ? get_class($compound) : gettype($compound))); - } if(!$t->updateCompoundTag($compound, $this)){ $t->spawnTo($this); } diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index bb949830f9..1e4eea9959 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -751,12 +751,7 @@ class Server{ if(file_exists($path . "$name.dat")){ try{ $nbt = new BigEndianNBTStream(); - $compound = $nbt->readCompressed(file_get_contents($path . "$name.dat")); - if(!($compound instanceof CompoundTag)){ - throw new \RuntimeException("Invalid data found in \"$name.dat\", expected " . CompoundTag::class . ", got " . (is_object($compound) ? get_class($compound) : gettype($compound))); - } - - return $compound; + return $nbt->readCompressed(file_get_contents($path . "$name.dat")); }catch(\Throwable $e){ //zlib decode error / corrupt data rename($path . "$name.dat", $path . "$name.dat.bak"); $this->logger->notice($this->getLanguage()->translateString("pocketmine.data.playerCorrupted", [$name])); diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index ce3cca7082..91a1aa06b8 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -65,12 +65,7 @@ class Item implements ItemIds, \JsonSerializable{ self::$cachedParser = new LittleEndianNBTStream(); } - $data = self::$cachedParser->read($tag); - if(!($data instanceof CompoundTag)){ - throw new \InvalidArgumentException("Invalid item NBT string given, it could not be deserialized"); - } - - return $data; + return self::$cachedParser->read($tag); } private static function writeCompoundTag(CompoundTag $tag) : string{ diff --git a/src/pocketmine/level/format/io/data/BedrockLevelData.php b/src/pocketmine/level/format/io/data/BedrockLevelData.php index 175aafe788..1d3886001c 100644 --- a/src/pocketmine/level/format/io/data/BedrockLevelData.php +++ b/src/pocketmine/level/format/io/data/BedrockLevelData.php @@ -100,15 +100,13 @@ class BedrockLevelData extends BaseNbtLevelData{ protected function load() : ?CompoundTag{ $nbt = new LittleEndianNBTStream(); $levelData = $nbt->read(substr(file_get_contents($this->dataPath), 8)); - if($levelData instanceof CompoundTag){ - $version = $levelData->getInt("StorageVersion", INT32_MAX, true); - if($version > self::CURRENT_STORAGE_VERSION){ - throw new UnsupportedLevelFormatException("Specified LevelDB world format version ($version) is not supported by " . \pocketmine\NAME); - } - return $levelData; + $version = $levelData->getInt("StorageVersion", INT32_MAX, true); + if($version > self::CURRENT_STORAGE_VERSION){ + throw new UnsupportedLevelFormatException("Specified LevelDB world format version ($version) is not supported by " . \pocketmine\NAME); } - return null; + + return $levelData; } protected function fix() : void{ diff --git a/src/pocketmine/level/format/io/data/JavaLevelData.php b/src/pocketmine/level/format/io/data/JavaLevelData.php index 2847a46c64..45e9133a6b 100644 --- a/src/pocketmine/level/format/io/data/JavaLevelData.php +++ b/src/pocketmine/level/format/io/data/JavaLevelData.php @@ -67,7 +67,7 @@ class JavaLevelData extends BaseNbtLevelData{ protected function load() : ?CompoundTag{ $nbt = new BigEndianNBTStream(); $levelData = $nbt->readCompressed(file_get_contents($this->dataPath)); - if($levelData instanceof CompoundTag and $levelData->hasTag("Data", CompoundTag::class)){ + if($levelData->hasTag("Data", CompoundTag::class)){ return $levelData->getCompoundTag("Data"); } return null; diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index fe34680d73..6ae328434a 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -225,10 +225,7 @@ class LevelDB extends BaseLevelProvider{ /** @var CompoundTag[] $entities */ $entities = []; if(($entityData = $this->db->get($index . self::TAG_ENTITY)) !== false and $entityData !== ""){ - $entities = $nbt->read($entityData, true); - if(!is_array($entities)){ - $entities = [$entities]; - } + $entities = $nbt->readMultiple($entityData); } /** @var CompoundTag $entityNBT */ @@ -238,12 +235,10 @@ class LevelDB extends BaseLevelProvider{ } } + /** @var CompoundTag[] $tiles */ $tiles = []; if(($tileData = $this->db->get($index . self::TAG_BLOCK_ENTITY)) !== false and $tileData !== ""){ - $tiles = $nbt->read($tileData, true); - if(!is_array($tiles)){ - $tiles = [$tiles]; - } + $tiles = $nbt->readMultiple($tileData); } //TODO: extra data should be converted into blockstorage layers (first they need to be implemented!) @@ -326,7 +321,7 @@ class LevelDB extends BaseLevelProvider{ private function writeTags(array $targets, string $index) : void{ if(!empty($targets)){ $nbt = new LittleEndianNBTStream(); - $this->db->put($index, $nbt->write($targets)); + $this->db->put($index, $nbt->writeMultiple($targets)); }else{ $this->db->delete($index); } diff --git a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php b/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php index b467df5066..eca17c88ce 100644 --- a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php @@ -98,7 +98,7 @@ trait LegacyAnvilChunkTrait{ protected function deserializeChunk(string $data) : Chunk{ $nbt = new BigEndianNBTStream(); $chunk = $nbt->readCompressed($data); - if(!($chunk instanceof CompoundTag) or !$chunk->hasTag("Level")){ + if(!$chunk->hasTag("Level")){ throw new ChunkException("Invalid NBT format"); } diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index 36e903f91e..abae6c7f2e 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -102,7 +102,7 @@ class McRegion extends RegionLevelProvider{ protected function deserializeChunk(string $data) : Chunk{ $nbt = new BigEndianNBTStream(); $chunk = $nbt->readCompressed($data); - if(!($chunk instanceof CompoundTag) or !$chunk->hasTag("Level")){ + if(!$chunk->hasTag("Level")){ throw new ChunkException("Invalid NBT format"); } From 212d72657abb0ceadd68f30ce58ccf7a3a06c786 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 25 Oct 2018 15:36:38 +0100 Subject: [PATCH 0259/3224] AsyncPool: Switch to a more efficient collection algorithm, revamp internals (#2493) This greatly improves GC performance by being more intelligent about how it collects garbage tasks. It knows that if X task in the queue is not finished, none of the tasks behind it can be finished either, so there's no point checking them. This also presents the opportunity to cleanup a lot of async pool internals, so I've taken it and torched a lot of garbage. --- src/pocketmine/scheduler/AsyncPool.php | 143 ++++++++++--------------- src/pocketmine/scheduler/AsyncTask.php | 14 +-- 2 files changed, 64 insertions(+), 93 deletions(-) diff --git a/src/pocketmine/scheduler/AsyncPool.php b/src/pocketmine/scheduler/AsyncPool.php index 70e71a5c10..b5633b57c5 100644 --- a/src/pocketmine/scheduler/AsyncPool.php +++ b/src/pocketmine/scheduler/AsyncPool.php @@ -39,17 +39,11 @@ class AsyncPool{ /** @var int */ private $workerMemoryLimit; - /** @var AsyncTask[] */ - private $tasks = []; - /** @var int[] */ - private $taskWorkers = []; - /** @var int */ - private $nextTaskId = 1; + /** @var \SplQueue[]|AsyncTask[][] */ + private $taskQueues = []; /** @var AsyncWorker[] */ private $workers = []; - /** @var int[] */ - private $workerUsage = []; /** @var \Closure[] */ private $workerStartHooks = []; @@ -124,11 +118,13 @@ class AsyncPool{ */ private function getWorker(int $worker) : AsyncWorker{ if(!isset($this->workers[$worker])){ - $this->workerUsage[$worker] = 0; + $this->workers[$worker] = new AsyncWorker($this->logger, $worker, $this->workerMemoryLimit); $this->workers[$worker]->setClassLoader($this->classLoader); $this->workers[$worker]->start(self::WORKER_START_OPTIONS); + $this->taskQueues[$worker] = new \SplQueue(); + foreach($this->workerStartHooks as $hook){ $hook($worker); } @@ -147,18 +143,15 @@ class AsyncPool{ if($worker < 0 or $worker >= $this->size){ throw new \InvalidArgumentException("Invalid worker $worker"); } - if($task->getTaskId() !== null){ + if($task->isSubmitted()){ throw new \InvalidArgumentException("Cannot submit the same AsyncTask instance more than once"); } $task->progressUpdates = new \Threaded; - $task->setTaskId($this->nextTaskId++); - - $this->tasks[$task->getTaskId()] = $task; + $task->setSubmitted(); $this->getWorker($worker)->stack($task); - $this->workerUsage[$worker]++; - $this->taskWorkers[$task->getTaskId()] = $worker; + $this->taskQueues[$worker]->enqueue($task); } /** @@ -173,8 +166,8 @@ class AsyncPool{ public function selectWorker() : int{ $worker = null; $minUsage = PHP_INT_MAX; - foreach($this->workerUsage as $i => $usage){ - if($usage < $minUsage){ + foreach($this->taskQueues as $i => $queue){ + if(($usage = $queue->count()) < $minUsage){ $worker = $i; $minUsage = $usage; if($usage === 0){ @@ -205,7 +198,7 @@ class AsyncPool{ * @return int */ public function submitTask(AsyncTask $task) : int{ - if($task->getTaskId() !== null){ + if($task->isSubmitted()){ throw new \InvalidArgumentException("Cannot submit the same AsyncTask instance more than once"); } @@ -214,77 +207,58 @@ class AsyncPool{ return $worker; } - /** - * Removes a completed or crashed task from the pool. - * - * @param AsyncTask $task - * @param bool $force - */ - private function removeTask(AsyncTask $task, bool $force = false) : void{ - if(isset($this->taskWorkers[$task->getTaskId()])){ - if(!$force and ($task->isRunning() or !$task->isGarbage())){ - return; - } - $this->workerUsage[$this->taskWorkers[$task->getTaskId()]]--; - } - - unset($this->tasks[$task->getTaskId()]); - unset($this->taskWorkers[$task->getTaskId()]); - } - - /** - * Collects garbage from running workers. - */ - private function collectWorkers() : void{ - foreach($this->workers as $worker){ - $worker->collect(); - } - } - /** * Collects finished and/or crashed tasks from the workers, firing their on-completion hooks where appropriate. * * @throws \ReflectionException */ public function collectTasks() : void{ - foreach($this->tasks as $task){ - $task->checkProgressUpdates(); - if($task->isGarbage() and !$task->isRunning() and !$task->isCrashed()){ - if(!$task->hasCancelledRun()){ - try{ - /* - * It's possible for a task to submit a progress update and then finish before the progress - * update is detected by the parent thread, so here we consume any missed updates. - * - * When this happens, it's possible for a progress update to arrive between the previous - * checkProgressUpdates() call and the next isGarbage() call, causing progress updates to be - * lost. Thus, it's necessary to do one last check here to make sure all progress updates have - * been consumed before completing. - */ - $task->checkProgressUpdates(); - $task->onCompletion(); - }catch(\Throwable $e){ - $this->logger->critical("Could not execute completion of asynchronous task " . (new \ReflectionClass($task))->getShortName() . ": " . $e->getMessage()); - $this->logger->logException($e); - } - } + foreach($this->taskQueues as $worker => $queue){ + $doGC = false; + while(!$queue->isEmpty()){ + /** @var AsyncTask $task */ + $task = $queue->bottom(); + $task->checkProgressUpdates(); + if(!$task->isRunning() and $task->isGarbage()){ //make sure the task actually executed before trying to collect + $doGC = true; + $queue->dequeue(); - $this->removeTask($task); - }elseif($task->isCrashed()){ - $this->logger->critical("Could not execute asynchronous task " . (new \ReflectionClass($task))->getShortName() . ": Task crashed"); - $this->removeTask($task, true); + if($task->isCrashed()){ + $this->logger->critical("Could not execute asynchronous task " . (new \ReflectionClass($task))->getShortName() . ": Task crashed"); + }elseif(!$task->hasCancelledRun()){ + try{ + /* + * It's possible for a task to submit a progress update and then finish before the progress + * update is detected by the parent thread, so here we consume any missed updates. + * + * When this happens, it's possible for a progress update to arrive between the previous + * checkProgressUpdates() call and the next isGarbage() call, causing progress updates to be + * lost. Thus, it's necessary to do one last check here to make sure all progress updates have + * been consumed before completing. + */ + $task->checkProgressUpdates(); + $task->onCompletion(); + }catch(\Throwable $e){ + $this->logger->critical("Could not execute completion of asynchronous task " . (new \ReflectionClass($task))->getShortName() . ": " . $e->getMessage()); + $this->logger->logException($e); + } + } + }else{ + break; //current task is still running, skip to next worker + } + } + if($doGC){ + $this->workers[$worker]->collect(); } } - - $this->collectWorkers(); } public function shutdownUnusedWorkers() : int{ $ret = 0; - foreach($this->workerUsage as $i => $usage){ - if($usage === 0){ + foreach($this->taskQueues as $i => $queue){ + if($queue->isEmpty()){ $this->workers[$i]->quit(); - unset($this->workers[$i], $this->workerUsage[$i]); + unset($this->workers[$i], $this->taskQueues[$i]); $ret++; } } @@ -301,24 +275,21 @@ class AsyncPool{ foreach($this->workers as $worker){ /** @var AsyncTask $task */ while(($task = $worker->unstack()) !== null){ - //cancelRun() is not strictly necessary here, but it might be used to inform plugins of the task state - //(i.e. it never executed). - $task->cancelRun(); - $this->removeTask($task, true); + //NOOP: the below loop will deal with marking tasks as garbage } } - foreach($this->tasks as $task){ - $task->cancelRun(); - $this->removeTask($task, true); + foreach($this->taskQueues as $queue){ + while(!$queue->isEmpty()){ + /** @var AsyncTask $task */ + $task = $queue->dequeue(); + $task->cancelRun(); + } } - $this->taskWorkers = []; - $this->tasks = []; - foreach($this->workers as $worker){ $worker->quit(); } $this->workers = []; - $this->workerUsage = []; + $this->taskQueues = []; } } diff --git a/src/pocketmine/scheduler/AsyncTask.php b/src/pocketmine/scheduler/AsyncTask.php index 8360fd312f..36231235a5 100644 --- a/src/pocketmine/scheduler/AsyncTask.php +++ b/src/pocketmine/scheduler/AsyncTask.php @@ -59,8 +59,8 @@ abstract class AsyncTask extends Collectable{ private $result = null; private $serialized = false; private $cancelRun = false; - /** @var int|null */ - private $taskId = null; + /** @var bool */ + private $submitted = false; private $crashed = false; @@ -114,15 +114,15 @@ abstract class AsyncTask extends Collectable{ $this->serialized = $serialize; } - public function setTaskId(int $taskId) : void{ - $this->taskId = $taskId; + public function setSubmitted() : void{ + $this->submitted = true; } /** - * @return int|null + * @return bool */ - public function getTaskId() : ?int{ - return $this->taskId; + public function isSubmitted() : bool{ + return $this->submitted; } /** From 712cafa0cc612bd1788f6c352a2c0cd7915f27fd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Oct 2018 16:29:14 +0100 Subject: [PATCH 0260/3224] Item: remove redundant meta constructor params these ctor params should only be used for variants in the ItemFactory registration, but all of these items have no non-zero variants anyway. --- src/pocketmine/item/Apple.php | 4 ++-- src/pocketmine/item/Arrow.php | 4 ++-- src/pocketmine/item/BakedPotato.php | 4 ++-- src/pocketmine/item/Beetroot.php | 4 ++-- src/pocketmine/item/BeetrootSeeds.php | 4 ++-- src/pocketmine/item/BeetrootSoup.php | 4 ++-- src/pocketmine/item/BlazeRod.php | 4 ++-- src/pocketmine/item/Boat.php | 4 ++-- src/pocketmine/item/Book.php | 4 ++-- src/pocketmine/item/Bow.php | 4 ++-- src/pocketmine/item/Bowl.php | 4 ++-- src/pocketmine/item/Bread.php | 4 ++-- src/pocketmine/item/Carrot.php | 4 ++-- src/pocketmine/item/ChainBoots.php | 4 ++-- src/pocketmine/item/ChainChestplate.php | 4 ++-- src/pocketmine/item/ChainHelmet.php | 4 ++-- src/pocketmine/item/ChainLeggings.php | 4 ++-- src/pocketmine/item/ChorusFruit.php | 4 ++-- src/pocketmine/item/Clock.php | 4 ++-- src/pocketmine/item/Clownfish.php | 4 ++-- src/pocketmine/item/Compass.php | 4 ++-- src/pocketmine/item/CookedChicken.php | 4 ++-- src/pocketmine/item/CookedFish.php | 4 ++-- src/pocketmine/item/CookedMutton.php | 4 ++-- src/pocketmine/item/CookedPorkchop.php | 4 ++-- src/pocketmine/item/CookedRabbit.php | 4 ++-- src/pocketmine/item/CookedSalmon.php | 4 ++-- src/pocketmine/item/Cookie.php | 4 ++-- src/pocketmine/item/DiamondBoots.php | 4 ++-- src/pocketmine/item/DiamondChestplate.php | 4 ++-- src/pocketmine/item/DiamondHelmet.php | 4 ++-- src/pocketmine/item/DiamondLeggings.php | 4 ++-- src/pocketmine/item/DriedKelp.php | 4 ++-- src/pocketmine/item/EnderPearl.php | 4 ++-- src/pocketmine/item/ExperienceBottle.php | 4 ++-- src/pocketmine/item/FishingRod.php | 4 ++-- src/pocketmine/item/FlintSteel.php | 4 ++-- src/pocketmine/item/GlassBottle.php | 4 ++-- src/pocketmine/item/GoldBoots.php | 4 ++-- src/pocketmine/item/GoldChestplate.php | 4 ++-- src/pocketmine/item/GoldHelmet.php | 4 ++-- src/pocketmine/item/GoldLeggings.php | 4 ++-- src/pocketmine/item/GoldenApple.php | 4 ++-- src/pocketmine/item/GoldenAppleEnchanted.php | 4 ++-- src/pocketmine/item/GoldenCarrot.php | 4 ++-- src/pocketmine/item/IronBoots.php | 4 ++-- src/pocketmine/item/IronChestplate.php | 4 ++-- src/pocketmine/item/IronHelmet.php | 4 ++-- src/pocketmine/item/IronLeggings.php | 4 ++-- src/pocketmine/item/LeatherBoots.php | 4 ++-- src/pocketmine/item/LeatherCap.php | 4 ++-- src/pocketmine/item/LeatherPants.php | 4 ++-- src/pocketmine/item/LeatherTunic.php | 4 ++-- src/pocketmine/item/Melon.php | 4 ++-- src/pocketmine/item/MelonSeeds.php | 4 ++-- src/pocketmine/item/Minecart.php | 4 ++-- src/pocketmine/item/MushroomStew.php | 4 ++-- src/pocketmine/item/PaintingItem.php | 4 ++-- src/pocketmine/item/PoisonousPotato.php | 4 ++-- src/pocketmine/item/Potato.php | 4 ++-- src/pocketmine/item/Pufferfish.php | 4 ++-- src/pocketmine/item/PumpkinPie.php | 4 ++-- src/pocketmine/item/PumpkinSeeds.php | 4 ++-- src/pocketmine/item/RabbitStew.php | 4 ++-- src/pocketmine/item/RawBeef.php | 4 ++-- src/pocketmine/item/RawChicken.php | 4 ++-- src/pocketmine/item/RawFish.php | 4 ++-- src/pocketmine/item/RawMutton.php | 4 ++-- src/pocketmine/item/RawPorkchop.php | 4 ++-- src/pocketmine/item/RawRabbit.php | 4 ++-- src/pocketmine/item/RawSalmon.php | 4 ++-- src/pocketmine/item/Redstone.php | 4 ++-- src/pocketmine/item/RottenFlesh.php | 4 ++-- src/pocketmine/item/Shears.php | 4 ++-- src/pocketmine/item/Sign.php | 4 ++-- src/pocketmine/item/Snowball.php | 4 ++-- src/pocketmine/item/SpiderEye.php | 4 ++-- src/pocketmine/item/Steak.php | 4 ++-- src/pocketmine/item/Stick.php | 4 ++-- src/pocketmine/item/StringItem.php | 4 ++-- src/pocketmine/item/Totem.php | 4 ++-- src/pocketmine/item/WheatSeeds.php | 4 ++-- src/pocketmine/item/WritableBook.php | 4 ++-- src/pocketmine/item/WrittenBook.php | 4 ++-- 84 files changed, 168 insertions(+), 168 deletions(-) diff --git a/src/pocketmine/item/Apple.php b/src/pocketmine/item/Apple.php index b0c4ccd125..eea93a02fd 100644 --- a/src/pocketmine/item/Apple.php +++ b/src/pocketmine/item/Apple.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class Apple extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::APPLE, $meta, "Apple"); + public function __construct(){ + parent::__construct(self::APPLE, 0, "Apple"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/Arrow.php b/src/pocketmine/item/Arrow.php index 31b73b7254..dab935e877 100644 --- a/src/pocketmine/item/Arrow.php +++ b/src/pocketmine/item/Arrow.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\item; class Arrow extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::ARROW, $meta, "Arrow"); + public function __construct(){ + parent::__construct(self::ARROW, 0, "Arrow"); } } diff --git a/src/pocketmine/item/BakedPotato.php b/src/pocketmine/item/BakedPotato.php index 5c3147137e..95b45e682b 100644 --- a/src/pocketmine/item/BakedPotato.php +++ b/src/pocketmine/item/BakedPotato.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class BakedPotato extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::BAKED_POTATO, $meta, "Baked Potato"); + public function __construct(){ + parent::__construct(self::BAKED_POTATO, 0, "Baked Potato"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/Beetroot.php b/src/pocketmine/item/Beetroot.php index 21f95a3d36..aa6d2e7a36 100644 --- a/src/pocketmine/item/Beetroot.php +++ b/src/pocketmine/item/Beetroot.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class Beetroot extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::BEETROOT, $meta, "Beetroot"); + public function __construct(){ + parent::__construct(self::BEETROOT, 0, "Beetroot"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/BeetrootSeeds.php b/src/pocketmine/item/BeetrootSeeds.php index 3e3c091a7d..0243fd6d65 100644 --- a/src/pocketmine/item/BeetrootSeeds.php +++ b/src/pocketmine/item/BeetrootSeeds.php @@ -27,8 +27,8 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; class BeetrootSeeds extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::BEETROOT_SEEDS, $meta, "Beetroot Seeds"); + public function __construct(){ + parent::__construct(self::BEETROOT_SEEDS, 0, "Beetroot Seeds"); } public function getBlock() : Block{ diff --git a/src/pocketmine/item/BeetrootSoup.php b/src/pocketmine/item/BeetrootSoup.php index 294698d266..0f805fb565 100644 --- a/src/pocketmine/item/BeetrootSoup.php +++ b/src/pocketmine/item/BeetrootSoup.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class BeetrootSoup extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::BEETROOT_SOUP, $meta, "Beetroot Soup"); + public function __construct(){ + parent::__construct(self::BEETROOT_SOUP, 0, "Beetroot Soup"); } public function getMaxStackSize() : int{ diff --git a/src/pocketmine/item/BlazeRod.php b/src/pocketmine/item/BlazeRod.php index c9276ea682..98e55369b9 100644 --- a/src/pocketmine/item/BlazeRod.php +++ b/src/pocketmine/item/BlazeRod.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class BlazeRod extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::BLAZE_ROD, $meta, "Blaze Rod"); + public function __construct(){ + parent::__construct(self::BLAZE_ROD, 0, "Blaze Rod"); } public function getFuelTime() : int{ diff --git a/src/pocketmine/item/Boat.php b/src/pocketmine/item/Boat.php index 35c05d997e..cfff0224a0 100644 --- a/src/pocketmine/item/Boat.php +++ b/src/pocketmine/item/Boat.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class Boat extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::BOAT, $meta, "Boat"); + public function __construct(){ + parent::__construct(self::BOAT, 0, "Boat"); } public function getFuelTime() : int{ diff --git a/src/pocketmine/item/Book.php b/src/pocketmine/item/Book.php index 8aec5186e5..002fb5c84d 100644 --- a/src/pocketmine/item/Book.php +++ b/src/pocketmine/item/Book.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\item; class Book extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::BOOK, $meta, "Book"); + public function __construct(){ + parent::__construct(self::BOOK, 0, "Book"); } } diff --git a/src/pocketmine/item/Bow.php b/src/pocketmine/item/Bow.php index 60aed426d8..faf7f4995f 100644 --- a/src/pocketmine/item/Bow.php +++ b/src/pocketmine/item/Bow.php @@ -33,8 +33,8 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\Player; class Bow extends Tool{ - public function __construct(int $meta = 0){ - parent::__construct(self::BOW, $meta, "Bow"); + public function __construct(){ + parent::__construct(self::BOW, 0, "Bow"); } public function getFuelTime() : int{ diff --git a/src/pocketmine/item/Bowl.php b/src/pocketmine/item/Bowl.php index 67a81ae406..e2b4a6bf5f 100644 --- a/src/pocketmine/item/Bowl.php +++ b/src/pocketmine/item/Bowl.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class Bowl extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::BOWL, $meta, "Bowl"); + public function __construct(){ + parent::__construct(self::BOWL, 0, "Bowl"); } //TODO: check fuel diff --git a/src/pocketmine/item/Bread.php b/src/pocketmine/item/Bread.php index 5e70816d33..ad6bd73c16 100644 --- a/src/pocketmine/item/Bread.php +++ b/src/pocketmine/item/Bread.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class Bread extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::BREAD, $meta, "Bread"); + public function __construct(){ + parent::__construct(self::BREAD, 0, "Bread"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/Carrot.php b/src/pocketmine/item/Carrot.php index 24b525fdba..fb70484ed0 100644 --- a/src/pocketmine/item/Carrot.php +++ b/src/pocketmine/item/Carrot.php @@ -27,8 +27,8 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; class Carrot extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::CARROT, $meta, "Carrot"); + public function __construct(){ + parent::__construct(self::CARROT, 0, "Carrot"); } public function getBlock() : Block{ diff --git a/src/pocketmine/item/ChainBoots.php b/src/pocketmine/item/ChainBoots.php index 141aefc8cb..9048917733 100644 --- a/src/pocketmine/item/ChainBoots.php +++ b/src/pocketmine/item/ChainBoots.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class ChainBoots extends Armor{ - public function __construct(int $meta = 0){ - parent::__construct(self::CHAIN_BOOTS, $meta, "Chainmail Boots"); + public function __construct(){ + parent::__construct(self::CHAIN_BOOTS, 0, "Chainmail Boots"); } public function getDefensePoints() : int{ diff --git a/src/pocketmine/item/ChainChestplate.php b/src/pocketmine/item/ChainChestplate.php index 2f1453fc97..0e1f90a1b3 100644 --- a/src/pocketmine/item/ChainChestplate.php +++ b/src/pocketmine/item/ChainChestplate.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class ChainChestplate extends Armor{ - public function __construct(int $meta = 0){ - parent::__construct(self::CHAIN_CHESTPLATE, $meta, "Chain Chestplate"); + public function __construct(){ + parent::__construct(self::CHAIN_CHESTPLATE, 0, "Chain Chestplate"); } public function getDefensePoints() : int{ diff --git a/src/pocketmine/item/ChainHelmet.php b/src/pocketmine/item/ChainHelmet.php index b949a72ffd..8714f2e31c 100644 --- a/src/pocketmine/item/ChainHelmet.php +++ b/src/pocketmine/item/ChainHelmet.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class ChainHelmet extends Armor{ - public function __construct(int $meta = 0){ - parent::__construct(self::CHAIN_HELMET, $meta, "Chainmail Helmet"); + public function __construct(){ + parent::__construct(self::CHAIN_HELMET, 0, "Chainmail Helmet"); } public function getDefensePoints() : int{ diff --git a/src/pocketmine/item/ChainLeggings.php b/src/pocketmine/item/ChainLeggings.php index e4882f06b6..f3daf37109 100644 --- a/src/pocketmine/item/ChainLeggings.php +++ b/src/pocketmine/item/ChainLeggings.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class ChainLeggings extends Armor{ - public function __construct(int $meta = 0){ - parent::__construct(self::CHAIN_LEGGINGS, $meta, "Chain Leggings"); + public function __construct(){ + parent::__construct(self::CHAIN_LEGGINGS, 0, "Chain Leggings"); } public function getDefensePoints() : int{ diff --git a/src/pocketmine/item/ChorusFruit.php b/src/pocketmine/item/ChorusFruit.php index 1e91ea0524..7c9b34ed43 100644 --- a/src/pocketmine/item/ChorusFruit.php +++ b/src/pocketmine/item/ChorusFruit.php @@ -30,8 +30,8 @@ use pocketmine\math\Vector3; class ChorusFruit extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::CHORUS_FRUIT, $meta, "Chorus Fruit"); + public function __construct(){ + parent::__construct(self::CHORUS_FRUIT, 0, "Chorus Fruit"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/Clock.php b/src/pocketmine/item/Clock.php index d2769167e7..0c32657282 100644 --- a/src/pocketmine/item/Clock.php +++ b/src/pocketmine/item/Clock.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\item; class Clock extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::CLOCK, $meta, "Clock"); + public function __construct(){ + parent::__construct(self::CLOCK, 0, "Clock"); } } diff --git a/src/pocketmine/item/Clownfish.php b/src/pocketmine/item/Clownfish.php index 4cd83e1001..e776dbcdfd 100644 --- a/src/pocketmine/item/Clownfish.php +++ b/src/pocketmine/item/Clownfish.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class Clownfish extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::CLOWNFISH, $meta, "Clownfish"); + public function __construct(){ + parent::__construct(self::CLOWNFISH, 0, "Clownfish"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/Compass.php b/src/pocketmine/item/Compass.php index 1469e71b44..5eccdbfc47 100644 --- a/src/pocketmine/item/Compass.php +++ b/src/pocketmine/item/Compass.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\item; class Compass extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::COMPASS, $meta, "Compass"); + public function __construct(){ + parent::__construct(self::COMPASS, 0, "Compass"); } } diff --git a/src/pocketmine/item/CookedChicken.php b/src/pocketmine/item/CookedChicken.php index 69ee857cfd..d72fd01923 100644 --- a/src/pocketmine/item/CookedChicken.php +++ b/src/pocketmine/item/CookedChicken.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class CookedChicken extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::COOKED_CHICKEN, $meta, "Cooked Chicken"); + public function __construct(){ + parent::__construct(self::COOKED_CHICKEN, 0, "Cooked Chicken"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/CookedFish.php b/src/pocketmine/item/CookedFish.php index ec5e30ef6d..bd28be171e 100644 --- a/src/pocketmine/item/CookedFish.php +++ b/src/pocketmine/item/CookedFish.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class CookedFish extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::COOKED_FISH, $meta, "Cooked Fish"); + public function __construct(){ + parent::__construct(self::COOKED_FISH, 0, "Cooked Fish"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/CookedMutton.php b/src/pocketmine/item/CookedMutton.php index 889c57d32e..152cb75c6b 100644 --- a/src/pocketmine/item/CookedMutton.php +++ b/src/pocketmine/item/CookedMutton.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class CookedMutton extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::COOKED_MUTTON, $meta, "Cooked Mutton"); + public function __construct(){ + parent::__construct(self::COOKED_MUTTON, 0, "Cooked Mutton"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/CookedPorkchop.php b/src/pocketmine/item/CookedPorkchop.php index fcf2af3269..649551c8df 100644 --- a/src/pocketmine/item/CookedPorkchop.php +++ b/src/pocketmine/item/CookedPorkchop.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class CookedPorkchop extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::COOKED_PORKCHOP, $meta, "Cooked Porkchop"); + public function __construct(){ + parent::__construct(self::COOKED_PORKCHOP, 0, "Cooked Porkchop"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/CookedRabbit.php b/src/pocketmine/item/CookedRabbit.php index c94543fc3c..03e5077fb7 100644 --- a/src/pocketmine/item/CookedRabbit.php +++ b/src/pocketmine/item/CookedRabbit.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class CookedRabbit extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::COOKED_RABBIT, $meta, "Cooked Rabbit"); + public function __construct(){ + parent::__construct(self::COOKED_RABBIT, 0, "Cooked Rabbit"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/CookedSalmon.php b/src/pocketmine/item/CookedSalmon.php index 6b32e667b3..f1e7013988 100644 --- a/src/pocketmine/item/CookedSalmon.php +++ b/src/pocketmine/item/CookedSalmon.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class CookedSalmon extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::COOKED_SALMON, $meta, "Cooked Salmon"); + public function __construct(){ + parent::__construct(self::COOKED_SALMON, 0, "Cooked Salmon"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/Cookie.php b/src/pocketmine/item/Cookie.php index f8c0bd4686..6dc546870b 100644 --- a/src/pocketmine/item/Cookie.php +++ b/src/pocketmine/item/Cookie.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class Cookie extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::COOKIE, $meta, "Cookie"); + public function __construct(){ + parent::__construct(self::COOKIE, 0, "Cookie"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/DiamondBoots.php b/src/pocketmine/item/DiamondBoots.php index 25b79761da..4cb849d602 100644 --- a/src/pocketmine/item/DiamondBoots.php +++ b/src/pocketmine/item/DiamondBoots.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class DiamondBoots extends Armor{ - public function __construct(int $meta = 0){ - parent::__construct(self::DIAMOND_BOOTS, $meta, "Diamond Boots"); + public function __construct(){ + parent::__construct(self::DIAMOND_BOOTS, 0, "Diamond Boots"); } public function getDefensePoints() : int{ diff --git a/src/pocketmine/item/DiamondChestplate.php b/src/pocketmine/item/DiamondChestplate.php index 778aa6ba92..8a1ce917b9 100644 --- a/src/pocketmine/item/DiamondChestplate.php +++ b/src/pocketmine/item/DiamondChestplate.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class DiamondChestplate extends Armor{ - public function __construct(int $meta = 0){ - parent::__construct(self::DIAMOND_CHESTPLATE, $meta, "Diamond Chestplate"); + public function __construct(){ + parent::__construct(self::DIAMOND_CHESTPLATE, 0, "Diamond Chestplate"); } public function getDefensePoints() : int{ diff --git a/src/pocketmine/item/DiamondHelmet.php b/src/pocketmine/item/DiamondHelmet.php index c5f652cc68..662aef6a97 100644 --- a/src/pocketmine/item/DiamondHelmet.php +++ b/src/pocketmine/item/DiamondHelmet.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class DiamondHelmet extends Armor{ - public function __construct(int $meta = 0){ - parent::__construct(self::DIAMOND_HELMET, $meta, "Diamond Helmet"); + public function __construct(){ + parent::__construct(self::DIAMOND_HELMET, 0, "Diamond Helmet"); } public function getDefensePoints() : int{ diff --git a/src/pocketmine/item/DiamondLeggings.php b/src/pocketmine/item/DiamondLeggings.php index 6f7613c6fb..e1662a7104 100644 --- a/src/pocketmine/item/DiamondLeggings.php +++ b/src/pocketmine/item/DiamondLeggings.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class DiamondLeggings extends Armor{ - public function __construct(int $meta = 0){ - parent::__construct(self::DIAMOND_LEGGINGS, $meta, "Diamond Leggings"); + public function __construct(){ + parent::__construct(self::DIAMOND_LEGGINGS, 0, "Diamond Leggings"); } public function getDefensePoints() : int{ diff --git a/src/pocketmine/item/DriedKelp.php b/src/pocketmine/item/DriedKelp.php index ae4fe87240..24b914db5d 100644 --- a/src/pocketmine/item/DriedKelp.php +++ b/src/pocketmine/item/DriedKelp.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class DriedKelp extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::DRIED_KELP, $meta, "Dried Kelp"); + public function __construct(){ + parent::__construct(self::DRIED_KELP, 0, "Dried Kelp"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/EnderPearl.php b/src/pocketmine/item/EnderPearl.php index ec0e9d788b..5b375a3915 100644 --- a/src/pocketmine/item/EnderPearl.php +++ b/src/pocketmine/item/EnderPearl.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class EnderPearl extends ProjectileItem{ - public function __construct(int $meta = 0){ - parent::__construct(self::ENDER_PEARL, $meta, "Ender Pearl"); + public function __construct(){ + parent::__construct(self::ENDER_PEARL, 0, "Ender Pearl"); } public function getMaxStackSize() : int{ diff --git a/src/pocketmine/item/ExperienceBottle.php b/src/pocketmine/item/ExperienceBottle.php index 5158cd06b4..277957ec64 100644 --- a/src/pocketmine/item/ExperienceBottle.php +++ b/src/pocketmine/item/ExperienceBottle.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class ExperienceBottle extends ProjectileItem{ - public function __construct(int $meta = 0){ - parent::__construct(self::EXPERIENCE_BOTTLE, $meta, "Bottle o' Enchanting"); + public function __construct(){ + parent::__construct(self::EXPERIENCE_BOTTLE, 0, "Bottle o' Enchanting"); } public function getProjectileEntityType() : string{ diff --git a/src/pocketmine/item/FishingRod.php b/src/pocketmine/item/FishingRod.php index 85991e5e98..8909de54ed 100644 --- a/src/pocketmine/item/FishingRod.php +++ b/src/pocketmine/item/FishingRod.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class FishingRod extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::FISHING_ROD, $meta, "Fishing Rod"); + public function __construct(){ + parent::__construct(self::FISHING_ROD, 0, "Fishing Rod"); } //TODO diff --git a/src/pocketmine/item/FlintSteel.php b/src/pocketmine/item/FlintSteel.php index ac9cb1456e..946a480885 100644 --- a/src/pocketmine/item/FlintSteel.php +++ b/src/pocketmine/item/FlintSteel.php @@ -30,8 +30,8 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\Player; class FlintSteel extends Tool{ - public function __construct(int $meta = 0){ - parent::__construct(self::FLINT_STEEL, $meta, "Flint and Steel"); + public function __construct(){ + parent::__construct(self::FLINT_STEEL, 0, "Flint and Steel"); } public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : bool{ diff --git a/src/pocketmine/item/GlassBottle.php b/src/pocketmine/item/GlassBottle.php index 682eecacf7..8957531426 100644 --- a/src/pocketmine/item/GlassBottle.php +++ b/src/pocketmine/item/GlassBottle.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\item; class GlassBottle extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::GLASS_BOTTLE, $meta, "Glass Bottle"); + public function __construct(){ + parent::__construct(self::GLASS_BOTTLE, 0, "Glass Bottle"); } } diff --git a/src/pocketmine/item/GoldBoots.php b/src/pocketmine/item/GoldBoots.php index cb039b52df..038639fa3a 100644 --- a/src/pocketmine/item/GoldBoots.php +++ b/src/pocketmine/item/GoldBoots.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class GoldBoots extends Armor{ - public function __construct(int $meta = 0){ - parent::__construct(self::GOLD_BOOTS, $meta, "Gold Boots"); + public function __construct(){ + parent::__construct(self::GOLD_BOOTS, 0, "Gold Boots"); } public function getDefensePoints() : int{ diff --git a/src/pocketmine/item/GoldChestplate.php b/src/pocketmine/item/GoldChestplate.php index 74bed00ac7..449b1df15a 100644 --- a/src/pocketmine/item/GoldChestplate.php +++ b/src/pocketmine/item/GoldChestplate.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class GoldChestplate extends Armor{ - public function __construct(int $meta = 0){ - parent::__construct(self::GOLD_CHESTPLATE, $meta, "Gold Chestplate"); + public function __construct(){ + parent::__construct(self::GOLD_CHESTPLATE, 0, "Gold Chestplate"); } public function getDefensePoints() : int{ diff --git a/src/pocketmine/item/GoldHelmet.php b/src/pocketmine/item/GoldHelmet.php index 043c363a2f..3533be19f6 100644 --- a/src/pocketmine/item/GoldHelmet.php +++ b/src/pocketmine/item/GoldHelmet.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class GoldHelmet extends Armor{ - public function __construct(int $meta = 0){ - parent::__construct(self::GOLD_HELMET, $meta, "Gold Helmet"); + public function __construct(){ + parent::__construct(self::GOLD_HELMET, 0, "Gold Helmet"); } public function getDefensePoints() : int{ diff --git a/src/pocketmine/item/GoldLeggings.php b/src/pocketmine/item/GoldLeggings.php index 47b675259b..2a54f7b023 100644 --- a/src/pocketmine/item/GoldLeggings.php +++ b/src/pocketmine/item/GoldLeggings.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class GoldLeggings extends Armor{ - public function __construct(int $meta = 0){ - parent::__construct(self::GOLD_LEGGINGS, $meta, "Gold Leggings"); + public function __construct(){ + parent::__construct(self::GOLD_LEGGINGS, 0, "Gold Leggings"); } public function getDefensePoints() : int{ diff --git a/src/pocketmine/item/GoldenApple.php b/src/pocketmine/item/GoldenApple.php index dbd3550d23..4bd1c3fb90 100644 --- a/src/pocketmine/item/GoldenApple.php +++ b/src/pocketmine/item/GoldenApple.php @@ -28,8 +28,8 @@ use pocketmine\entity\EffectInstance; class GoldenApple extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::GOLDEN_APPLE, $meta, "Golden Apple"); + public function __construct(){ + parent::__construct(self::GOLDEN_APPLE, 0, "Golden Apple"); } public function requiresHunger() : bool{ diff --git a/src/pocketmine/item/GoldenAppleEnchanted.php b/src/pocketmine/item/GoldenAppleEnchanted.php index 4961d8498e..b5d8bc3055 100644 --- a/src/pocketmine/item/GoldenAppleEnchanted.php +++ b/src/pocketmine/item/GoldenAppleEnchanted.php @@ -28,8 +28,8 @@ use pocketmine\entity\EffectInstance; class GoldenAppleEnchanted extends GoldenApple{ - public function __construct(int $meta = 0){ - Food::__construct(self::ENCHANTED_GOLDEN_APPLE, $meta, "Enchanted Golden Apple"); //skip parent constructor + public function __construct(){ + Food::__construct(self::ENCHANTED_GOLDEN_APPLE, 0, "Enchanted Golden Apple"); //skip parent constructor } public function getAdditionalEffects() : array{ diff --git a/src/pocketmine/item/GoldenCarrot.php b/src/pocketmine/item/GoldenCarrot.php index 78b99ab74b..06d327bca4 100644 --- a/src/pocketmine/item/GoldenCarrot.php +++ b/src/pocketmine/item/GoldenCarrot.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class GoldenCarrot extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::GOLDEN_CARROT, $meta, "Golden Carrot"); + public function __construct(){ + parent::__construct(self::GOLDEN_CARROT, 0, "Golden Carrot"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/IronBoots.php b/src/pocketmine/item/IronBoots.php index a116394684..322da7869c 100644 --- a/src/pocketmine/item/IronBoots.php +++ b/src/pocketmine/item/IronBoots.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class IronBoots extends Armor{ - public function __construct(int $meta = 0){ - parent::__construct(self::IRON_BOOTS, $meta, "Iron Boots"); + public function __construct(){ + parent::__construct(self::IRON_BOOTS, 0, "Iron Boots"); } public function getDefensePoints() : int{ diff --git a/src/pocketmine/item/IronChestplate.php b/src/pocketmine/item/IronChestplate.php index 2cb8814788..8879b71f23 100644 --- a/src/pocketmine/item/IronChestplate.php +++ b/src/pocketmine/item/IronChestplate.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class IronChestplate extends Armor{ - public function __construct(int $meta = 0){ - parent::__construct(self::IRON_CHESTPLATE, $meta, "Iron Chestplate"); + public function __construct(){ + parent::__construct(self::IRON_CHESTPLATE, 0, "Iron Chestplate"); } public function getDefensePoints() : int{ diff --git a/src/pocketmine/item/IronHelmet.php b/src/pocketmine/item/IronHelmet.php index 74875d29e2..187daed0be 100644 --- a/src/pocketmine/item/IronHelmet.php +++ b/src/pocketmine/item/IronHelmet.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class IronHelmet extends Armor{ - public function __construct(int $meta = 0){ - parent::__construct(self::IRON_HELMET, $meta, "Iron Helmet"); + public function __construct(){ + parent::__construct(self::IRON_HELMET, 0, "Iron Helmet"); } public function getDefensePoints() : int{ diff --git a/src/pocketmine/item/IronLeggings.php b/src/pocketmine/item/IronLeggings.php index 655248f99d..8ab4c5d2d3 100644 --- a/src/pocketmine/item/IronLeggings.php +++ b/src/pocketmine/item/IronLeggings.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class IronLeggings extends Armor{ - public function __construct(int $meta = 0){ - parent::__construct(self::IRON_LEGGINGS, $meta, "Iron Leggings"); + public function __construct(){ + parent::__construct(self::IRON_LEGGINGS, 0, "Iron Leggings"); } public function getDefensePoints() : int{ diff --git a/src/pocketmine/item/LeatherBoots.php b/src/pocketmine/item/LeatherBoots.php index 4c93de806d..1fc036d9fb 100644 --- a/src/pocketmine/item/LeatherBoots.php +++ b/src/pocketmine/item/LeatherBoots.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class LeatherBoots extends Armor{ - public function __construct(int $meta = 0){ - parent::__construct(self::LEATHER_BOOTS, $meta, "Leather Boots"); + public function __construct(){ + parent::__construct(self::LEATHER_BOOTS, 0, "Leather Boots"); } public function getDefensePoints() : int{ diff --git a/src/pocketmine/item/LeatherCap.php b/src/pocketmine/item/LeatherCap.php index 3b2c0653dd..37805e80ee 100644 --- a/src/pocketmine/item/LeatherCap.php +++ b/src/pocketmine/item/LeatherCap.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class LeatherCap extends Armor{ - public function __construct(int $meta = 0){ - parent::__construct(self::LEATHER_CAP, $meta, "Leather Cap"); + public function __construct(){ + parent::__construct(self::LEATHER_CAP, 0, "Leather Cap"); } public function getDefensePoints() : int{ diff --git a/src/pocketmine/item/LeatherPants.php b/src/pocketmine/item/LeatherPants.php index 05ee76ca74..5ef56c79a7 100644 --- a/src/pocketmine/item/LeatherPants.php +++ b/src/pocketmine/item/LeatherPants.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class LeatherPants extends Armor{ - public function __construct(int $meta = 0){ - parent::__construct(self::LEATHER_PANTS, $meta, "Leather Pants"); + public function __construct(){ + parent::__construct(self::LEATHER_PANTS, 0, "Leather Pants"); } public function getDefensePoints() : int{ diff --git a/src/pocketmine/item/LeatherTunic.php b/src/pocketmine/item/LeatherTunic.php index d587f2eaa2..c57707c4c2 100644 --- a/src/pocketmine/item/LeatherTunic.php +++ b/src/pocketmine/item/LeatherTunic.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class LeatherTunic extends Armor{ - public function __construct(int $meta = 0){ - parent::__construct(self::LEATHER_TUNIC, $meta, "Leather Tunic"); + public function __construct(){ + parent::__construct(self::LEATHER_TUNIC, 0, "Leather Tunic"); } public function getDefensePoints() : int{ diff --git a/src/pocketmine/item/Melon.php b/src/pocketmine/item/Melon.php index 104fa10d62..0a4c5cedc9 100644 --- a/src/pocketmine/item/Melon.php +++ b/src/pocketmine/item/Melon.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class Melon extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::MELON, $meta, "Melon"); + public function __construct(){ + parent::__construct(self::MELON, 0, "Melon"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/MelonSeeds.php b/src/pocketmine/item/MelonSeeds.php index a536f93969..0f359b9db7 100644 --- a/src/pocketmine/item/MelonSeeds.php +++ b/src/pocketmine/item/MelonSeeds.php @@ -27,8 +27,8 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; class MelonSeeds extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::MELON_SEEDS, $meta, "Melon Seeds"); + public function __construct(){ + parent::__construct(self::MELON_SEEDS, 0, "Melon Seeds"); } public function getBlock() : Block{ diff --git a/src/pocketmine/item/Minecart.php b/src/pocketmine/item/Minecart.php index bba2b997d6..ec9bbcbe99 100644 --- a/src/pocketmine/item/Minecart.php +++ b/src/pocketmine/item/Minecart.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class Minecart extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::MINECART, $meta, "Minecart"); + public function __construct(){ + parent::__construct(self::MINECART, 0, "Minecart"); } //TODO diff --git a/src/pocketmine/item/MushroomStew.php b/src/pocketmine/item/MushroomStew.php index a3776393d2..abba737a54 100644 --- a/src/pocketmine/item/MushroomStew.php +++ b/src/pocketmine/item/MushroomStew.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class MushroomStew extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::MUSHROOM_STEW, $meta, "Mushroom Stew"); + public function __construct(){ + parent::__construct(self::MUSHROOM_STEW, 0, "Mushroom Stew"); } public function getMaxStackSize() : int{ diff --git a/src/pocketmine/item/PaintingItem.php b/src/pocketmine/item/PaintingItem.php index 1c7085b411..a642c41de3 100644 --- a/src/pocketmine/item/PaintingItem.php +++ b/src/pocketmine/item/PaintingItem.php @@ -33,8 +33,8 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\Player; class PaintingItem extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::PAINTING, $meta, "Painting"); + public function __construct(){ + parent::__construct(self::PAINTING, 0, "Painting"); } public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : bool{ diff --git a/src/pocketmine/item/PoisonousPotato.php b/src/pocketmine/item/PoisonousPotato.php index e98703e5b2..82ebf64fa6 100644 --- a/src/pocketmine/item/PoisonousPotato.php +++ b/src/pocketmine/item/PoisonousPotato.php @@ -27,8 +27,8 @@ use pocketmine\entity\Effect; use pocketmine\entity\EffectInstance; class PoisonousPotato extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::POISONOUS_POTATO, $meta, "Poisonous Potato"); + public function __construct(){ + parent::__construct(self::POISONOUS_POTATO, 0, "Poisonous Potato"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/Potato.php b/src/pocketmine/item/Potato.php index b2531bb7d5..f7278e93ea 100644 --- a/src/pocketmine/item/Potato.php +++ b/src/pocketmine/item/Potato.php @@ -27,8 +27,8 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; class Potato extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::POTATO, $meta, "Potato"); + public function __construct(){ + parent::__construct(self::POTATO, 0, "Potato"); } public function getBlock() : Block{ diff --git a/src/pocketmine/item/Pufferfish.php b/src/pocketmine/item/Pufferfish.php index cef122f938..12d3a4c986 100644 --- a/src/pocketmine/item/Pufferfish.php +++ b/src/pocketmine/item/Pufferfish.php @@ -27,8 +27,8 @@ use pocketmine\entity\Effect; use pocketmine\entity\EffectInstance; class Pufferfish extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::PUFFERFISH, $meta, "Pufferfish"); + public function __construct(){ + parent::__construct(self::PUFFERFISH, 0, "Pufferfish"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/PumpkinPie.php b/src/pocketmine/item/PumpkinPie.php index 69a1f74862..90628dd68a 100644 --- a/src/pocketmine/item/PumpkinPie.php +++ b/src/pocketmine/item/PumpkinPie.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class PumpkinPie extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::PUMPKIN_PIE, $meta, "Pumpkin Pie"); + public function __construct(){ + parent::__construct(self::PUMPKIN_PIE, 0, "Pumpkin Pie"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/PumpkinSeeds.php b/src/pocketmine/item/PumpkinSeeds.php index ec8e840bd8..01ec1a6e1e 100644 --- a/src/pocketmine/item/PumpkinSeeds.php +++ b/src/pocketmine/item/PumpkinSeeds.php @@ -27,8 +27,8 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; class PumpkinSeeds extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::PUMPKIN_SEEDS, $meta, "Pumpkin Seeds"); + public function __construct(){ + parent::__construct(self::PUMPKIN_SEEDS, 0, "Pumpkin Seeds"); } public function getBlock() : Block{ diff --git a/src/pocketmine/item/RabbitStew.php b/src/pocketmine/item/RabbitStew.php index acdf635ff4..9161d888a6 100644 --- a/src/pocketmine/item/RabbitStew.php +++ b/src/pocketmine/item/RabbitStew.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class RabbitStew extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::RABBIT_STEW, $meta, "Rabbit Stew"); + public function __construct(){ + parent::__construct(self::RABBIT_STEW, 0, "Rabbit Stew"); } public function getMaxStackSize() : int{ diff --git a/src/pocketmine/item/RawBeef.php b/src/pocketmine/item/RawBeef.php index 0e1a3a8b7e..59aa7e9c32 100644 --- a/src/pocketmine/item/RawBeef.php +++ b/src/pocketmine/item/RawBeef.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class RawBeef extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::RAW_BEEF, $meta, "Raw Beef"); + public function __construct(){ + parent::__construct(self::RAW_BEEF, 0, "Raw Beef"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/RawChicken.php b/src/pocketmine/item/RawChicken.php index df430e2efa..79b57e1e75 100644 --- a/src/pocketmine/item/RawChicken.php +++ b/src/pocketmine/item/RawChicken.php @@ -27,8 +27,8 @@ use pocketmine\entity\Effect; use pocketmine\entity\EffectInstance; class RawChicken extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::RAW_CHICKEN, $meta, "Raw Chicken"); + public function __construct(){ + parent::__construct(self::RAW_CHICKEN, 0, "Raw Chicken"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/RawFish.php b/src/pocketmine/item/RawFish.php index 0ecfe970e1..54da485c19 100644 --- a/src/pocketmine/item/RawFish.php +++ b/src/pocketmine/item/RawFish.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class RawFish extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::RAW_FISH, $meta, "Raw Fish"); + public function __construct(){ + parent::__construct(self::RAW_FISH, 0, "Raw Fish"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/RawMutton.php b/src/pocketmine/item/RawMutton.php index 7812bfe5f3..125f901a53 100644 --- a/src/pocketmine/item/RawMutton.php +++ b/src/pocketmine/item/RawMutton.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class RawMutton extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::RAW_MUTTON, $meta, "Raw Mutton"); + public function __construct(){ + parent::__construct(self::RAW_MUTTON, 0, "Raw Mutton"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/RawPorkchop.php b/src/pocketmine/item/RawPorkchop.php index 85ccd69d6b..fa28f59298 100644 --- a/src/pocketmine/item/RawPorkchop.php +++ b/src/pocketmine/item/RawPorkchop.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class RawPorkchop extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::RAW_PORKCHOP, $meta, "Raw Porkchop"); + public function __construct(){ + parent::__construct(self::RAW_PORKCHOP, 0, "Raw Porkchop"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/RawRabbit.php b/src/pocketmine/item/RawRabbit.php index f3b9380fb1..2234c60a2c 100644 --- a/src/pocketmine/item/RawRabbit.php +++ b/src/pocketmine/item/RawRabbit.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class RawRabbit extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::RAW_RABBIT, $meta, "Raw Rabbit"); + public function __construct(){ + parent::__construct(self::RAW_RABBIT, 0, "Raw Rabbit"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/RawSalmon.php b/src/pocketmine/item/RawSalmon.php index c702d3869b..d8b2375f92 100644 --- a/src/pocketmine/item/RawSalmon.php +++ b/src/pocketmine/item/RawSalmon.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class RawSalmon extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::RAW_SALMON, $meta, "Raw Salmon"); + public function __construct(){ + parent::__construct(self::RAW_SALMON, 0, "Raw Salmon"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/Redstone.php b/src/pocketmine/item/Redstone.php index 9826b4e670..a67f8365a9 100644 --- a/src/pocketmine/item/Redstone.php +++ b/src/pocketmine/item/Redstone.php @@ -27,8 +27,8 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; class Redstone extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::REDSTONE, $meta, "Redstone"); + public function __construct(){ + parent::__construct(self::REDSTONE, 0, "Redstone"); } public function getBlock() : Block{ diff --git a/src/pocketmine/item/RottenFlesh.php b/src/pocketmine/item/RottenFlesh.php index 223f7452e4..9a928edaf8 100644 --- a/src/pocketmine/item/RottenFlesh.php +++ b/src/pocketmine/item/RottenFlesh.php @@ -28,8 +28,8 @@ use pocketmine\entity\EffectInstance; class RottenFlesh extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::ROTTEN_FLESH, $meta, "Rotten Flesh"); + public function __construct(){ + parent::__construct(self::ROTTEN_FLESH, 0, "Rotten Flesh"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/Shears.php b/src/pocketmine/item/Shears.php index 04a5b9d550..4bd563e8e7 100644 --- a/src/pocketmine/item/Shears.php +++ b/src/pocketmine/item/Shears.php @@ -27,8 +27,8 @@ use pocketmine\block\Block; use pocketmine\block\BlockToolType; class Shears extends Tool{ - public function __construct(int $meta = 0){ - parent::__construct(self::SHEARS, $meta, "Shears"); + public function __construct(){ + parent::__construct(self::SHEARS, 0, "Shears"); } public function getMaxDurability() : int{ diff --git a/src/pocketmine/item/Sign.php b/src/pocketmine/item/Sign.php index 56a06749d7..723c460b6e 100644 --- a/src/pocketmine/item/Sign.php +++ b/src/pocketmine/item/Sign.php @@ -27,8 +27,8 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; class Sign extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::SIGN, $meta, "Sign"); + public function __construct(){ + parent::__construct(self::SIGN, 0, "Sign"); } public function getBlock() : Block{ diff --git a/src/pocketmine/item/Snowball.php b/src/pocketmine/item/Snowball.php index 1e2fc00d14..c13f9abd73 100644 --- a/src/pocketmine/item/Snowball.php +++ b/src/pocketmine/item/Snowball.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class Snowball extends ProjectileItem{ - public function __construct(int $meta = 0){ - parent::__construct(self::SNOWBALL, $meta, "Snowball"); + public function __construct(){ + parent::__construct(self::SNOWBALL, 0, "Snowball"); } public function getMaxStackSize() : int{ diff --git a/src/pocketmine/item/SpiderEye.php b/src/pocketmine/item/SpiderEye.php index 4feea931b2..2e386afb5b 100644 --- a/src/pocketmine/item/SpiderEye.php +++ b/src/pocketmine/item/SpiderEye.php @@ -27,8 +27,8 @@ use pocketmine\entity\Effect; use pocketmine\entity\EffectInstance; class SpiderEye extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::SPIDER_EYE, $meta, "Spider Eye"); + public function __construct(){ + parent::__construct(self::SPIDER_EYE, 0, "Spider Eye"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/Steak.php b/src/pocketmine/item/Steak.php index 57ec814a1c..1e5ed99f05 100644 --- a/src/pocketmine/item/Steak.php +++ b/src/pocketmine/item/Steak.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class Steak extends Food{ - public function __construct(int $meta = 0){ - parent::__construct(self::STEAK, $meta, "Steak"); + public function __construct(){ + parent::__construct(self::STEAK, 0, "Steak"); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/Stick.php b/src/pocketmine/item/Stick.php index b3dd1c92c1..4bbb63bf26 100644 --- a/src/pocketmine/item/Stick.php +++ b/src/pocketmine/item/Stick.php @@ -25,8 +25,8 @@ namespace pocketmine\item; class Stick extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::STICK, $meta, "Stick"); + public function __construct(){ + parent::__construct(self::STICK, 0, "Stick"); } public function getFuelTime() : int{ diff --git a/src/pocketmine/item/StringItem.php b/src/pocketmine/item/StringItem.php index eb5868a21c..c3023b82c1 100644 --- a/src/pocketmine/item/StringItem.php +++ b/src/pocketmine/item/StringItem.php @@ -27,8 +27,8 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; class StringItem extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::STRING, $meta, "String"); + public function __construct(){ + parent::__construct(self::STRING, 0, "String"); } public function getBlock() : Block{ diff --git a/src/pocketmine/item/Totem.php b/src/pocketmine/item/Totem.php index f64ced723b..e322de7f1f 100644 --- a/src/pocketmine/item/Totem.php +++ b/src/pocketmine/item/Totem.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class Totem extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::TOTEM, $meta, "Totem of Undying"); + public function __construct(){ + parent::__construct(self::TOTEM, 0, "Totem of Undying"); } public function getMaxStackSize() : int{ diff --git a/src/pocketmine/item/WheatSeeds.php b/src/pocketmine/item/WheatSeeds.php index 5bf2dccdd8..538d56368f 100644 --- a/src/pocketmine/item/WheatSeeds.php +++ b/src/pocketmine/item/WheatSeeds.php @@ -27,8 +27,8 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; class WheatSeeds extends Item{ - public function __construct(int $meta = 0){ - parent::__construct(self::WHEAT_SEEDS, $meta, "Wheat Seeds"); + public function __construct(){ + parent::__construct(self::WHEAT_SEEDS, 0, "Wheat Seeds"); } public function getBlock() : Block{ diff --git a/src/pocketmine/item/WritableBook.php b/src/pocketmine/item/WritableBook.php index cc73eec18c..2bd083e83a 100644 --- a/src/pocketmine/item/WritableBook.php +++ b/src/pocketmine/item/WritableBook.php @@ -34,8 +34,8 @@ class WritableBook extends Item{ public const TAG_PAGE_TEXT = "text"; //TAG_String public const TAG_PAGE_PHOTONAME = "photoname"; //TAG_String - TODO - public function __construct(int $meta = 0){ - parent::__construct(self::WRITABLE_BOOK, $meta, "Book & Quill"); + public function __construct(){ + parent::__construct(self::WRITABLE_BOOK, 0, "Book & Quill"); } /** diff --git a/src/pocketmine/item/WrittenBook.php b/src/pocketmine/item/WrittenBook.php index 5666e6c6be..1be3b5025f 100644 --- a/src/pocketmine/item/WrittenBook.php +++ b/src/pocketmine/item/WrittenBook.php @@ -34,8 +34,8 @@ class WrittenBook extends WritableBook{ public const TAG_AUTHOR = "author"; //TAG_String public const TAG_TITLE = "title"; //TAG_String - public function __construct(int $meta = 0){ - Item::__construct(self::WRITTEN_BOOK, $meta, "Written Book"); + public function __construct(){ + Item::__construct(self::WRITTEN_BOOK, 0, "Written Book"); } public function getMaxStackSize() : int{ From 51e13104dc4cbbe9880c7069436009b13799e704 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Oct 2018 16:49:25 +0100 Subject: [PATCH 0261/3224] oops, missed one --- src/pocketmine/item/Egg.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/item/Egg.php b/src/pocketmine/item/Egg.php index fa2716b9d8..9276342d4a 100644 --- a/src/pocketmine/item/Egg.php +++ b/src/pocketmine/item/Egg.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; class Egg extends ProjectileItem{ - public function __construct(int $meta = 0){ - parent::__construct(self::EGG, $meta, "Egg"); + public function __construct(){ + parent::__construct(self::EGG, 0, "Egg"); } public function getMaxStackSize() : int{ From f438736af5652c273727825292c5fb96291db6d1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Oct 2018 16:51:02 +0100 Subject: [PATCH 0262/3224] Make some item constructor variant parameters mandatory --- src/pocketmine/item/Banner.php | 2 +- src/pocketmine/item/Bed.php | 2 +- src/pocketmine/item/Dye.php | 2 +- src/pocketmine/item/Potion.php | 2 +- src/pocketmine/item/SplashPotion.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/item/Banner.php b/src/pocketmine/item/Banner.php index d4f160e33d..2fdf48daa9 100644 --- a/src/pocketmine/item/Banner.php +++ b/src/pocketmine/item/Banner.php @@ -37,7 +37,7 @@ class Banner extends Item{ public const TAG_PATTERN_COLOR = TileBanner::TAG_PATTERN_COLOR; public const TAG_PATTERN_NAME = TileBanner::TAG_PATTERN_NAME; - public function __construct(int $meta = 0){ + public function __construct(int $meta){ parent::__construct(self::BANNER, $meta, "Banner"); } diff --git a/src/pocketmine/item/Bed.php b/src/pocketmine/item/Bed.php index 6433b8f587..7fe88e3e33 100644 --- a/src/pocketmine/item/Bed.php +++ b/src/pocketmine/item/Bed.php @@ -27,7 +27,7 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; class Bed extends Item{ - public function __construct(int $meta = 0){ + public function __construct(int $meta){ parent::__construct(self::BED, $meta, "Bed"); } diff --git a/src/pocketmine/item/Dye.php b/src/pocketmine/item/Dye.php index 87aaa184cc..382c7a5836 100644 --- a/src/pocketmine/item/Dye.php +++ b/src/pocketmine/item/Dye.php @@ -27,7 +27,7 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; class Dye extends Item{ - public function __construct(int $meta = 0){ + public function __construct(int $meta){ parent::__construct(self::DYE, $meta, "Dye"); } diff --git a/src/pocketmine/item/Potion.php b/src/pocketmine/item/Potion.php index 2f56a87393..6c925543e9 100644 --- a/src/pocketmine/item/Potion.php +++ b/src/pocketmine/item/Potion.php @@ -255,7 +255,7 @@ class Potion extends Item implements Consumable{ return []; } - public function __construct(int $meta = 0){ + public function __construct(int $meta){ parent::__construct(self::POTION, $meta, "Potion"); } diff --git a/src/pocketmine/item/SplashPotion.php b/src/pocketmine/item/SplashPotion.php index fe1db43115..15293dd118 100644 --- a/src/pocketmine/item/SplashPotion.php +++ b/src/pocketmine/item/SplashPotion.php @@ -27,7 +27,7 @@ use pocketmine\nbt\tag\CompoundTag; class SplashPotion extends ProjectileItem{ - public function __construct(int $meta = 0){ + public function __construct(int $meta){ parent::__construct(self::SPLASH_POTION, $meta, "Splash Potion"); } From 327c8361bd3f1563bbb8e82f54fad86af376ba48 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Oct 2018 18:16:31 +0100 Subject: [PATCH 0263/3224] Remove variant parameters from TieredTool --- src/pocketmine/item/ItemFactory.php | 50 ++++++++++++++--------------- src/pocketmine/item/TieredTool.php | 4 +-- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 4493b88a75..c80199c62d 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -41,9 +41,9 @@ class ItemFactory{ public static function init(){ self::$list = new \SplFixedArray(65536); - self::registerItem(new Shovel(Item::IRON_SHOVEL, 0, "Iron Shovel", TieredTool::TIER_IRON)); - self::registerItem(new Pickaxe(Item::IRON_PICKAXE, 0, "Iron Pickaxe", TieredTool::TIER_IRON)); - self::registerItem(new Axe(Item::IRON_AXE, 0, "Iron Axe", TieredTool::TIER_IRON)); + self::registerItem(new Shovel(Item::IRON_SHOVEL, "Iron Shovel", TieredTool::TIER_IRON)); + self::registerItem(new Pickaxe(Item::IRON_PICKAXE, "Iron Pickaxe", TieredTool::TIER_IRON)); + self::registerItem(new Axe(Item::IRON_AXE, "Iron Axe", TieredTool::TIER_IRON)); self::registerItem(new FlintSteel()); self::registerItem(new Apple()); self::registerItem(new Bow()); @@ -53,34 +53,34 @@ class ItemFactory{ self::registerItem(new Item(Item::DIAMOND, 0, "Diamond")); self::registerItem(new Item(Item::IRON_INGOT, 0, "Iron Ingot")); self::registerItem(new Item(Item::GOLD_INGOT, 0, "Gold Ingot")); - self::registerItem(new Sword(Item::IRON_SWORD, 0, "Iron Sword", TieredTool::TIER_IRON)); - self::registerItem(new Sword(Item::WOODEN_SWORD, 0, "Wooden Sword", TieredTool::TIER_WOODEN)); - self::registerItem(new Shovel(Item::WOODEN_SHOVEL, 0, "Wooden Shovel", TieredTool::TIER_WOODEN)); - self::registerItem(new Pickaxe(Item::WOODEN_PICKAXE, 0, "Wooden Pickaxe", TieredTool::TIER_WOODEN)); - self::registerItem(new Axe(Item::WOODEN_AXE, 0, "Wooden Axe", TieredTool::TIER_WOODEN)); - self::registerItem(new Sword(Item::STONE_SWORD, 0, "Stone Sword", TieredTool::TIER_STONE)); - self::registerItem(new Shovel(Item::STONE_SHOVEL, 0, "Stone Shovel", TieredTool::TIER_STONE)); - self::registerItem(new Pickaxe(Item::STONE_PICKAXE, 0, "Stone Pickaxe", TieredTool::TIER_STONE)); - self::registerItem(new Axe(Item::STONE_AXE, 0, "Stone Axe", TieredTool::TIER_STONE)); - self::registerItem(new Sword(Item::DIAMOND_SWORD, 0, "Diamond Sword", TieredTool::TIER_DIAMOND)); - self::registerItem(new Shovel(Item::DIAMOND_SHOVEL, 0, "Diamond Shovel", TieredTool::TIER_DIAMOND)); - self::registerItem(new Pickaxe(Item::DIAMOND_PICKAXE, 0, "Diamond Pickaxe", TieredTool::TIER_DIAMOND)); - self::registerItem(new Axe(Item::DIAMOND_AXE, 0, "Diamond Axe", TieredTool::TIER_DIAMOND)); + self::registerItem(new Sword(Item::IRON_SWORD, "Iron Sword", TieredTool::TIER_IRON)); + self::registerItem(new Sword(Item::WOODEN_SWORD, "Wooden Sword", TieredTool::TIER_WOODEN)); + self::registerItem(new Shovel(Item::WOODEN_SHOVEL, "Wooden Shovel", TieredTool::TIER_WOODEN)); + self::registerItem(new Pickaxe(Item::WOODEN_PICKAXE, "Wooden Pickaxe", TieredTool::TIER_WOODEN)); + self::registerItem(new Axe(Item::WOODEN_AXE, "Wooden Axe", TieredTool::TIER_WOODEN)); + self::registerItem(new Sword(Item::STONE_SWORD, "Stone Sword", TieredTool::TIER_STONE)); + self::registerItem(new Shovel(Item::STONE_SHOVEL, "Stone Shovel", TieredTool::TIER_STONE)); + self::registerItem(new Pickaxe(Item::STONE_PICKAXE, "Stone Pickaxe", TieredTool::TIER_STONE)); + self::registerItem(new Axe(Item::STONE_AXE, "Stone Axe", TieredTool::TIER_STONE)); + self::registerItem(new Sword(Item::DIAMOND_SWORD, "Diamond Sword", TieredTool::TIER_DIAMOND)); + self::registerItem(new Shovel(Item::DIAMOND_SHOVEL, "Diamond Shovel", TieredTool::TIER_DIAMOND)); + self::registerItem(new Pickaxe(Item::DIAMOND_PICKAXE, "Diamond Pickaxe", TieredTool::TIER_DIAMOND)); + self::registerItem(new Axe(Item::DIAMOND_AXE, "Diamond Axe", TieredTool::TIER_DIAMOND)); self::registerItem(new Stick()); self::registerItem(new Bowl()); self::registerItem(new MushroomStew()); - self::registerItem(new Sword(Item::GOLDEN_SWORD, 0, "Gold Sword", TieredTool::TIER_GOLD)); - self::registerItem(new Shovel(Item::GOLDEN_SHOVEL, 0, "Gold Shovel", TieredTool::TIER_GOLD)); - self::registerItem(new Pickaxe(Item::GOLDEN_PICKAXE, 0, "Gold Pickaxe", TieredTool::TIER_GOLD)); - self::registerItem(new Axe(Item::GOLDEN_AXE, 0, "Gold Axe", TieredTool::TIER_GOLD)); + self::registerItem(new Sword(Item::GOLDEN_SWORD, "Gold Sword", TieredTool::TIER_GOLD)); + self::registerItem(new Shovel(Item::GOLDEN_SHOVEL, "Gold Shovel", TieredTool::TIER_GOLD)); + self::registerItem(new Pickaxe(Item::GOLDEN_PICKAXE, "Gold Pickaxe", TieredTool::TIER_GOLD)); + self::registerItem(new Axe(Item::GOLDEN_AXE, "Gold Axe", TieredTool::TIER_GOLD)); self::registerItem(new StringItem()); self::registerItem(new Item(Item::FEATHER, 0, "Feather")); self::registerItem(new Item(Item::GUNPOWDER, 0, "Gunpowder")); - self::registerItem(new Hoe(Item::WOODEN_HOE, 0, "Wooden Hoe", TieredTool::TIER_WOODEN)); - self::registerItem(new Hoe(Item::STONE_HOE, 0, "Stone Hoe", TieredTool::TIER_STONE)); - self::registerItem(new Hoe(Item::IRON_HOE, 0, "Iron Hoe", TieredTool::TIER_IRON)); - self::registerItem(new Hoe(Item::DIAMOND_HOE, 0, "Diamond Hoe", TieredTool::TIER_DIAMOND)); - self::registerItem(new Hoe(Item::GOLDEN_HOE, 0, "Golden Hoe", TieredTool::TIER_GOLD)); + self::registerItem(new Hoe(Item::WOODEN_HOE, "Wooden Hoe", TieredTool::TIER_WOODEN)); + self::registerItem(new Hoe(Item::STONE_HOE, "Stone Hoe", TieredTool::TIER_STONE)); + self::registerItem(new Hoe(Item::IRON_HOE, "Iron Hoe", TieredTool::TIER_IRON)); + self::registerItem(new Hoe(Item::DIAMOND_HOE, "Diamond Hoe", TieredTool::TIER_DIAMOND)); + self::registerItem(new Hoe(Item::GOLDEN_HOE, "Golden Hoe", TieredTool::TIER_GOLD)); self::registerItem(new WheatSeeds()); self::registerItem(new Item(Item::WHEAT, 0, "Wheat")); self::registerItem(new Bread()); diff --git a/src/pocketmine/item/TieredTool.php b/src/pocketmine/item/TieredTool.php index 7fa2898895..ac276f5e24 100644 --- a/src/pocketmine/item/TieredTool.php +++ b/src/pocketmine/item/TieredTool.php @@ -33,8 +33,8 @@ abstract class TieredTool extends Tool{ /** @var int */ protected $tier; - public function __construct(int $id, int $meta, string $name, int $tier){ - parent::__construct($id, $meta, $name); + public function __construct(int $id, string $name, int $tier){ + parent::__construct($id, 0, $name); $this->tier = $tier; } From 7dd3b5b996338813365ce18ca00c97ec9c6d88cb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Oct 2018 18:17:34 +0100 Subject: [PATCH 0264/3224] Durable: fixed leftover wtf from damage refactor --- src/pocketmine/item/Durable.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/item/Durable.php b/src/pocketmine/item/Durable.php index 37ac4244f7..22cabb9751 100644 --- a/src/pocketmine/item/Durable.php +++ b/src/pocketmine/item/Durable.php @@ -74,11 +74,11 @@ abstract class Durable extends Item{ return $this->damage; } - public function setDamage(int $meta) : Item{ - if($meta < 0 or $meta > $this->getMaxDurability()){ + public function setDamage(int $damage) : Item{ + if($damage < 0 or $damage > $this->getMaxDurability()){ throw new \InvalidArgumentException("Damage must be in range 0 - " , $this->getMaxDurability()); } - $this->damage = $meta; + $this->damage = $damage; return $this; } From 93131b4d925951750d9636f50d84dc9f84772e81 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Oct 2018 18:20:37 +0100 Subject: [PATCH 0265/3224] Rename some meta usages to variant --- src/pocketmine/item/Banner.php | 4 ++-- src/pocketmine/item/Bed.php | 4 ++-- src/pocketmine/item/Dye.php | 4 ++-- src/pocketmine/item/Item.php | 6 +++--- src/pocketmine/item/Potion.php | 4 ++-- src/pocketmine/item/SplashPotion.php | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/pocketmine/item/Banner.php b/src/pocketmine/item/Banner.php index 2fdf48daa9..9dabb9306a 100644 --- a/src/pocketmine/item/Banner.php +++ b/src/pocketmine/item/Banner.php @@ -37,8 +37,8 @@ class Banner extends Item{ public const TAG_PATTERN_COLOR = TileBanner::TAG_PATTERN_COLOR; public const TAG_PATTERN_NAME = TileBanner::TAG_PATTERN_NAME; - public function __construct(int $meta){ - parent::__construct(self::BANNER, $meta, "Banner"); + public function __construct(int $variant){ + parent::__construct(self::BANNER, $variant, "Banner"); } public function getBlock() : Block{ diff --git a/src/pocketmine/item/Bed.php b/src/pocketmine/item/Bed.php index 7fe88e3e33..c451a6acce 100644 --- a/src/pocketmine/item/Bed.php +++ b/src/pocketmine/item/Bed.php @@ -27,8 +27,8 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; class Bed extends Item{ - public function __construct(int $meta){ - parent::__construct(self::BED, $meta, "Bed"); + public function __construct(int $variant){ + parent::__construct(self::BED, $variant, "Bed"); } public function getBlock() : Block{ diff --git a/src/pocketmine/item/Dye.php b/src/pocketmine/item/Dye.php index 382c7a5836..fb91e3f3db 100644 --- a/src/pocketmine/item/Dye.php +++ b/src/pocketmine/item/Dye.php @@ -27,8 +27,8 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; class Dye extends Item{ - public function __construct(int $meta){ - parent::__construct(self::DYE, $meta, "Dye"); + public function __construct(int $variant){ + parent::__construct(self::DYE, $variant, "Dye"); } public function getBlock() : Block{ diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 91a1aa06b8..e92da31946 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -187,15 +187,15 @@ class Item implements ItemIds, \JsonSerializable{ * purpose. * * @param int $id - * @param int $meta + * @param int $variant * @param string $name */ - public function __construct(int $id, int $meta = 0, string $name = "Unknown"){ + public function __construct(int $id, int $variant = 0, string $name = "Unknown"){ if($id < -0x8000 or $id > 0x7fff){ //signed short range throw new \InvalidArgumentException("ID must be in range " . -0x8000 . " - " . 0x7fff); } $this->id = $id; - $this->meta = $meta !== -1 ? $meta & 0x7FFF : -1; + $this->meta = $variant !== -1 ? $variant & 0x7FFF : -1; $this->name = $name; } diff --git a/src/pocketmine/item/Potion.php b/src/pocketmine/item/Potion.php index 6c925543e9..bddab81e9d 100644 --- a/src/pocketmine/item/Potion.php +++ b/src/pocketmine/item/Potion.php @@ -255,8 +255,8 @@ class Potion extends Item implements Consumable{ return []; } - public function __construct(int $meta){ - parent::__construct(self::POTION, $meta, "Potion"); + public function __construct(int $variant){ + parent::__construct(self::POTION, $variant, "Potion"); } public function getMaxStackSize() : int{ diff --git a/src/pocketmine/item/SplashPotion.php b/src/pocketmine/item/SplashPotion.php index 15293dd118..945b5f5e8f 100644 --- a/src/pocketmine/item/SplashPotion.php +++ b/src/pocketmine/item/SplashPotion.php @@ -27,8 +27,8 @@ use pocketmine\nbt\tag\CompoundTag; class SplashPotion extends ProjectileItem{ - public function __construct(int $meta){ - parent::__construct(self::SPLASH_POTION, $meta, "Splash Potion"); + public function __construct(int $variant){ + parent::__construct(self::SPLASH_POTION, $variant, "Splash Potion"); } public function getMaxStackSize() : int{ From 0ef81e701a28ab068e515b1c225d07745f795b75 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Oct 2018 18:38:24 +0100 Subject: [PATCH 0266/3224] ItemFactory: Use a simple hashmap for item types this is slower but yields less complicated code. Since this isn't in a hot path it's acceptable for this to slow down a little for the sake of sanity. --- src/pocketmine/item/ItemFactory.php | 36 ++++++++++------------------- 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index c80199c62d..67023c599e 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -36,10 +36,10 @@ use pocketmine\tile\Skull; class ItemFactory{ /** @var \SplFixedArray */ - private static $list = null; + private static $list = []; public static function init(){ - self::$list = new \SplFixedArray(65536); + self::$list = []; //in case of re-initializing self::registerItem(new Shovel(Item::IRON_SHOVEL, "Iron Shovel", TieredTool::TIER_IRON)); self::registerItem(new Pickaxe(Item::IRON_PICKAXE, "Iron Pickaxe", TieredTool::TIER_IRON)); @@ -318,13 +318,7 @@ class ItemFactory{ throw new \RuntimeException("Trying to overwrite an already registered item"); } - $offset = self::getListOffset($id); - $sublist = self::$list[$offset] ?? new \SplFixedArray(); - if($sublist->getSize() < $variant + 1){ - $sublist->setSize($variant + 1); - } - $sublist[$variant] = clone $item; - self::$list[$offset] = $sublist; + self::$list[self::getListOffset($id, $variant)] = clone $item; } /** @@ -346,17 +340,12 @@ class ItemFactory{ /** @var Item $item */ $item = null; if($meta !== -1){ - $sublist = self::$list[self::getListOffset($id)]; - - /** @var Item|null $listed */ - if($sublist !== null){ - if(isset($sublist[$meta])){ - $item = clone $sublist[$meta]; - }elseif(isset($sublist[0]) and $sublist[0] instanceof Durable){ - /** @var Durable $item */ - $item = clone $sublist[0]; - $item->setDamage($meta); - } + if(isset(self::$list[$offset = self::getListOffset($id, $meta)])){ + $item = clone self::$list[$offset]; + }elseif(isset(self::$list[$zero = self::getListOffset($id, 0)]) and self::$list[$zero] instanceof Durable){ + /** @var Durable $item */ + $item = clone self::$list[$zero]; + $item->setDamage($meta); }elseif($id < 256){ //intentionally includes negatives, for extended block IDs $item = new ItemBlock($id, $meta); } @@ -433,14 +422,13 @@ class ItemFactory{ return BlockFactory::isRegistered($id); } - $sublist = self::$list[self::getListOffset($id)]; - return $sublist !== null and isset($sublist[$variant]); + return isset(self::$list[self::getListOffset($id, $variant)]); } - private static function getListOffset(int $id) : int{ + private static function getListOffset(int $id, int $variant) : int{ if($id < -0x8000 or $id > 0x7fff){ throw new \InvalidArgumentException("ID must be in range " . -0x8000 . " - " . 0x7fff); } - return $id & 0xffff; + return (($id & 0xffff) << 16) | ($variant & 0xffff); } } From 9bb3c93285d8589cde855b08318e32514eff78c4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Oct 2018 15:26:01 +0100 Subject: [PATCH 0267/3224] Remove network-serialized item NBT from API layer, item NBT is now retained for the lifetime of the stack --- src/pocketmine/inventory/BaseInventory.php | 12 +-- src/pocketmine/inventory/ShapedRecipe.php | 2 +- src/pocketmine/inventory/ShapelessRecipe.php | 4 +- .../transaction/CraftingTransaction.php | 2 +- src/pocketmine/item/Item.php | 89 ++++++------------- src/pocketmine/item/ItemFactory.php | 20 ++--- .../network/mcpe/NetworkBinaryStream.php | 28 ++++-- 7 files changed, 66 insertions(+), 91 deletions(-) diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index 27c0fd6c97..cc335e6dec 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -181,7 +181,7 @@ abstract class BaseInventory implements Inventory{ public function contains(Item $item) : bool{ $count = max(1, $item->getCount()); $checkDamage = !$item->hasAnyDamageValue(); - $checkTags = $item->hasCompoundTag(); + $checkTags = $item->hasNamedTag(); foreach($this->getContents() as $i){ if($item->equals($i, $checkDamage, $checkTags)){ $count -= $i->getCount(); @@ -197,7 +197,7 @@ abstract class BaseInventory implements Inventory{ public function all(Item $item) : array{ $slots = []; $checkDamage = !$item->hasAnyDamageValue(); - $checkTags = $item->hasCompoundTag(); + $checkTags = $item->hasNamedTag(); foreach($this->getContents() as $index => $i){ if($item->equals($i, $checkDamage, $checkTags)){ $slots[$index] = $i; @@ -209,7 +209,7 @@ abstract class BaseInventory implements Inventory{ public function remove(Item $item) : void{ $checkDamage = !$item->hasAnyDamageValue(); - $checkTags = $item->hasCompoundTag(); + $checkTags = $item->hasNamedTag(); foreach($this->getContents() as $index => $i){ if($item->equals($i, $checkDamage, $checkTags)){ @@ -221,7 +221,7 @@ abstract class BaseInventory implements Inventory{ public function first(Item $item, bool $exact = false) : int{ $count = $exact ? $item->getCount() : max(1, $item->getCount()); $checkDamage = $exact || !$item->hasAnyDamageValue(); - $checkTags = $exact || $item->hasCompoundTag(); + $checkTags = $exact || $item->hasNamedTag(); foreach($this->getContents() as $index => $i){ if($item->equals($i, $checkDamage, $checkTags) and ($i->getCount() === $count or (!$exact and $i->getCount() > $count))){ @@ -249,7 +249,7 @@ abstract class BaseInventory implements Inventory{ public function canAddItem(Item $item) : bool{ $item = clone $item; $checkDamage = !$item->hasAnyDamageValue(); - $checkTags = $item->hasCompoundTag(); + $checkTags = $item->hasNamedTag(); for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ $slot = $this->getItem($i); if($item->equals($slot, $checkDamage, $checkTags)){ @@ -342,7 +342,7 @@ abstract class BaseInventory implements Inventory{ } foreach($itemSlots as $index => $slot){ - if($slot->equals($item, !$slot->hasAnyDamageValue(), $slot->hasCompoundTag())){ + if($slot->equals($item, !$slot->hasAnyDamageValue(), $slot->hasNamedTag())){ $amount = min($item->getCount(), $slot->getCount()); $slot->setCount($slot->getCount() - $amount); $item->setCount($item->getCount() - $amount); diff --git a/src/pocketmine/inventory/ShapedRecipe.php b/src/pocketmine/inventory/ShapedRecipe.php index b15778ea9f..ae787c0803 100644 --- a/src/pocketmine/inventory/ShapedRecipe.php +++ b/src/pocketmine/inventory/ShapedRecipe.php @@ -197,7 +197,7 @@ class ShapedRecipe implements CraftingRecipe{ $given = $grid->getIngredient($reverse ? $this->width - $x - 1 : $x, $y); $required = $this->getIngredient($x, $y); - if(!$required->equals($given, !$required->hasAnyDamageValue(), $required->hasCompoundTag()) or $required->getCount() > $given->getCount()){ + if(!$required->equals($given, !$required->hasAnyDamageValue(), $required->hasNamedTag()) or $required->getCount() > $given->getCount()){ return false; } } diff --git a/src/pocketmine/inventory/ShapelessRecipe.php b/src/pocketmine/inventory/ShapelessRecipe.php index a8dbcb007f..7db3d3c132 100644 --- a/src/pocketmine/inventory/ShapelessRecipe.php +++ b/src/pocketmine/inventory/ShapelessRecipe.php @@ -81,7 +81,7 @@ class ShapelessRecipe implements CraftingRecipe{ if($item->getCount() <= 0){ break; } - if($ingredient->equals($item, !$item->hasAnyDamageValue(), $item->hasCompoundTag())){ + if($ingredient->equals($item, !$item->hasAnyDamageValue(), $item->hasNamedTag())){ unset($this->ingredients[$index]); $item->pop(); } @@ -124,7 +124,7 @@ class ShapelessRecipe implements CraftingRecipe{ foreach($this->ingredients as $needItem){ foreach($input as $j => $haveItem){ - if($haveItem->equals($needItem, !$needItem->hasAnyDamageValue(), $needItem->hasCompoundTag()) and $haveItem->getCount() >= $needItem->getCount()){ + if($haveItem->equals($needItem, !$needItem->hasAnyDamageValue(), $needItem->hasNamedTag()) and $haveItem->getCount() >= $needItem->getCount()){ unset($input[$j]); continue 2; } diff --git a/src/pocketmine/inventory/transaction/CraftingTransaction.php b/src/pocketmine/inventory/transaction/CraftingTransaction.php index de7fec6faf..0ef31b3756 100644 --- a/src/pocketmine/inventory/transaction/CraftingTransaction.php +++ b/src/pocketmine/inventory/transaction/CraftingTransaction.php @@ -69,7 +69,7 @@ class CraftingTransaction extends InventoryTransaction{ $haveCount = 0; foreach($txItems as $j => $txItem){ - if($txItem->equals($recipeItem, !$wildcards or !$recipeItem->hasAnyDamageValue(), !$wildcards or $recipeItem->hasCompoundTag())){ + if($txItem->equals($recipeItem, !$wildcards or !$recipeItem->hasAnyDamageValue(), !$wildcards or $recipeItem->hasNamedTag())){ $haveCount += $txItem->getCount(); unset($txItems[$j]); } diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index e92da31946..2df5a4dd11 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -81,14 +81,14 @@ class Item implements ItemIds, \JsonSerializable{ * * This function redirects to {@link ItemFactory#get}. * - * @param int $id - * @param int $meta - * @param int $count - * @param CompoundTag|string $tags + * @param int $id + * @param int $meta + * @param int $count + * @param CompoundTag $tags * * @return Item */ - public static function get(int $id, int $meta = 0, int $count = 1, $tags = "") : Item{ + public static function get(int $id, int $meta = 0, int $count = 1, ?CompoundTag $tags = null) : Item{ return ItemFactory::get($id, $meta, $count, $tags); } @@ -170,10 +170,8 @@ class Item implements ItemIds, \JsonSerializable{ protected $id; /** @var int */ protected $meta; - /** @var string */ - private $tags = ""; /** @var CompoundTag|null */ - private $cachedNBT = null; + private $nbt = null; /** @var int */ protected $count = 1; /** @var string */ @@ -199,40 +197,6 @@ class Item implements ItemIds, \JsonSerializable{ $this->name = $name; } - /** - * Sets the Item's NBT - * - * @param CompoundTag|string $tags - * - * @return Item - */ - public function setCompoundTag($tags) : Item{ - if($tags instanceof CompoundTag){ - $this->setNamedTag($tags); - }else{ - $this->tags = (string) $tags; - $this->cachedNBT = null; - } - - return $this; - } - - /** - * Returns the serialized NBT of the Item - * @return string - */ - public function getCompoundTag() : string{ - return $this->tags; - } - - /** - * Returns whether this Item has a non-empty NBT. - * @return bool - */ - public function hasCompoundTag() : bool{ - return $this->tags !== ""; - } - /** * @return bool */ @@ -537,6 +501,14 @@ class Item implements ItemIds, \JsonSerializable{ $this->setNamedTag($tag); } + /** + * Returns whether this Item has a non-empty NBT. + * @return bool + */ + public function hasNamedTag() : bool{ + return $this->nbt !== null and $this->nbt->count() > 0; + } + /** * Returns a tree of Tag objects representing the Item's NBT. If the item does not have any NBT, an empty CompoundTag * object is returned to allow the caller to manipulate and apply back to the item. @@ -544,11 +516,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return CompoundTag */ public function getNamedTag() : CompoundTag{ - if(!$this->hasCompoundTag() and $this->cachedNBT === null){ - $this->cachedNBT = new CompoundTag(); - } - - return $this->cachedNBT ?? ($this->cachedNBT = self::parseCompoundTag($this->tags)); + return $this->nbt ?? ($this->nbt = new CompoundTag()); } /** @@ -563,8 +531,7 @@ class Item implements ItemIds, \JsonSerializable{ return $this->clearNamedTag(); } - $this->cachedNBT = $tag; - $this->tags = self::writeCompoundTag($tag); + $this->nbt = clone $tag; return $this; } @@ -574,7 +541,8 @@ class Item implements ItemIds, \JsonSerializable{ * @return Item */ public function clearNamedTag() : Item{ - return $this->setCompoundTag(""); + $this->nbt = null; + return $this; } /** @@ -817,9 +785,7 @@ class Item implements ItemIds, \JsonSerializable{ final public function equals(Item $item, bool $checkDamage = true, bool $checkCompound = true) : bool{ if($this->id === $item->getId() and (!$checkDamage or $this->getDamage() === $item->getDamage())){ if($checkCompound){ - if($item->getCompoundTag() === $this->getCompoundTag()){ - return true; - }elseif($this->hasCompoundTag() and $item->hasCompoundTag()){ + if($this->hasNamedTag() and $item->hasNamedTag()){ //Serialized NBT didn't match, check the cached object tree. return $this->getNamedTag()->equals($item->getNamedTag()); } @@ -846,7 +812,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return string */ final public function __toString() : string{ - return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->getDamage()) . ")x" . $this->count . ($this->hasCompoundTag() ? " tags:0x" . bin2hex($this->getCompoundTag()) : ""); + return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->getDamage()) . ")x" . $this->count . ($this->hasNamedTag() ? " tags:0x" . self::writeCompoundTag($this->nbt) : ""); } /** @@ -867,8 +833,8 @@ class Item implements ItemIds, \JsonSerializable{ $data["count"] = $this->getCount(); } - if($this->hasCompoundTag()){ - $data["nbt_b64"] = base64_encode($this->getCompoundTag()); + if($this->hasNamedTag()){ + $data["nbt_b64"] = base64_encode(self::writeCompoundTag($this->getNamedTag())); } return $data; @@ -893,10 +859,7 @@ class Item implements ItemIds, \JsonSerializable{ $nbt = base64_decode($data["nbt_b64"], true); } return ItemFactory::get( - (int) $data["id"], - (int) ($data["damage"] ?? 0), - (int) ($data["count"] ?? 1), - (string) $nbt + (int) $data["id"], (int) ($data["damage"] ?? 0), (int) ($data["count"] ?? 1), $nbt !== "" ? self::parseCompoundTag($nbt) : null ); } @@ -915,7 +878,7 @@ class Item implements ItemIds, \JsonSerializable{ new ShortTag("Damage", $this->getDamage()) ]); - if($this->hasCompoundTag()){ + if($this->hasNamedTag()){ $itemNBT = clone $this->getNamedTag(); $itemNBT->setName("tag"); $result->setTag($itemNBT); @@ -970,6 +933,8 @@ class Item implements ItemIds, \JsonSerializable{ } public function __clone(){ - $this->cachedNBT = null; + if($this->nbt !== null){ + $this->nbt = clone $this->nbt; + } } } diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 67023c599e..2c26229516 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -324,19 +324,15 @@ class ItemFactory{ /** * Returns an instance of the Item with the specified id, meta, count and NBT. * - * @param int $id - * @param int $meta - * @param int $count - * @param CompoundTag|string $tags + * @param int $id + * @param int $meta + * @param int $count + * @param CompoundTag $tags * * @return Item - * @throws \TypeError + * @throws \InvalidArgumentException */ - public static function get(int $id, int $meta = 0, int $count = 1, $tags = "") : Item{ - if(!is_string($tags) and !($tags instanceof CompoundTag)){ - throw new \TypeError("`tags` argument must be a string or CompoundTag instance, " . (is_object($tags) ? "instance of " . get_class($tags) : gettype($tags)) . " given"); - } - + public static function get(int $id, int $meta = 0, int $count = 1, ?CompoundTag $tags = null) : Item{ /** @var Item $item */ $item = null; if($meta !== -1){ @@ -357,7 +353,9 @@ class ItemFactory{ } $item->setCount($count); - $item->setCompoundTag($tags); + if($tags !== null){ + $item->setNamedTag($tags); + } return $item; } diff --git a/src/pocketmine/network/mcpe/NetworkBinaryStream.php b/src/pocketmine/network/mcpe/NetworkBinaryStream.php index 8cdfd68c97..d857d9720d 100644 --- a/src/pocketmine/network/mcpe/NetworkBinaryStream.php +++ b/src/pocketmine/network/mcpe/NetworkBinaryStream.php @@ -30,12 +30,15 @@ use pocketmine\entity\Entity; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\Vector3; +use pocketmine\nbt\LittleEndianNBTStream; use pocketmine\network\mcpe\protocol\types\CommandOriginData; use pocketmine\network\mcpe\protocol\types\EntityLink; use pocketmine\utils\BinaryStream; use pocketmine\utils\UUID; class NetworkBinaryStream extends BinaryStream{ + /** @var LittleEndianNBTStream */ + private static $itemNbtSerializer = null; public function getString() : string{ return $this->get($this->getUnsignedVarInt()); @@ -77,10 +80,12 @@ class NetworkBinaryStream extends BinaryStream{ $cnt = $auxValue & 0xff; $nbtLen = $this->getLShort(); - $nbt = ""; - + $compound = null; if($nbtLen > 0){ - $nbt = $this->get($nbtLen); + if(self::$itemNbtSerializer === null){ + self::$itemNbtSerializer = new LittleEndianNBTStream(); + } + $compound = self::$itemNbtSerializer->read($this->get($nbtLen)); } //TODO @@ -93,7 +98,7 @@ class NetworkBinaryStream extends BinaryStream{ $this->getString(); } - return ItemFactory::get($id, $data, $cnt, $nbt); + return ItemFactory::get($id, $data, $cnt, $compound); } @@ -108,10 +113,17 @@ class NetworkBinaryStream extends BinaryStream{ $auxValue = (($item->getDamage() & 0x7fff) << 8) | $item->getCount(); $this->putVarInt($auxValue); - $nbt = $item->getCompoundTag(); - $nbtLen = strlen($nbt); - if($nbtLen > 32767){ - throw new \InvalidArgumentException("NBT encoded length must be < 32768, got $nbtLen bytes"); + $nbt = ""; + $nbtLen = 0; + if($item->hasNamedTag()){ + if(self::$itemNbtSerializer === null){ + self::$itemNbtSerializer = new LittleEndianNBTStream(); + } + $nbt = self::$itemNbtSerializer->write($item->getNamedTag()); + $nbtLen = strlen($nbt); + if($nbtLen > 32767){ + throw new \InvalidArgumentException("NBT encoded length must be < 32768, got $nbtLen bytes"); + } } $this->putLShort($nbtLen); From ff28c982ac6aeb065e4f59ce0b43a7099559bf88 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Oct 2018 16:33:58 +0100 Subject: [PATCH 0268/3224] Kick out unnecessary Perlin class the code in here isn't used anywhere except as a base for Simplex, so it makes more sense to flatten it and get rid of the crap. --- .../level/generator/noise/Perlin.php | 150 ------------------ .../level/generator/noise/Simplex.php | 34 +++- 2 files changed, 32 insertions(+), 152 deletions(-) delete mode 100644 src/pocketmine/level/generator/noise/Perlin.php diff --git a/src/pocketmine/level/generator/noise/Perlin.php b/src/pocketmine/level/generator/noise/Perlin.php deleted file mode 100644 index 84b2ab2c2e..0000000000 --- a/src/pocketmine/level/generator/noise/Perlin.php +++ /dev/null @@ -1,150 +0,0 @@ -octaves = $octaves; - $this->persistence = $persistence; - $this->expansion = $expansion; - $this->offsetX = $random->nextFloat() * 256; - $this->offsetY = $random->nextFloat() * 256; - $this->offsetZ = $random->nextFloat() * 256; - - for($i = 0; $i < 512; ++$i){ - $this->perm[$i] = 0; - } - - for($i = 0; $i < 256; ++$i){ - $this->perm[$i] = $random->nextBoundedInt(256); - } - - for($i = 0; $i < 256; ++$i){ - $pos = $random->nextBoundedInt(256 - $i) + $i; - $old = $this->perm[$i]; - - $this->perm[$i] = $this->perm[$pos]; - $this->perm[$pos] = $old; - $this->perm[$i + 256] = $this->perm[$i]; - } - - } - - public function getNoise3D($x, $y, $z){ - $x += $this->offsetX; - $y += $this->offsetY; - $z += $this->offsetZ; - - $floorX = (int) $x; - $floorY = (int) $y; - $floorZ = (int) $z; - - $X = $floorX & 0xFF; - $Y = $floorY & 0xFF; - $Z = $floorZ & 0xFF; - - $x -= $floorX; - $y -= $floorY; - $z -= $floorZ; - - //Fade curves - //$fX = self::fade($x); - //$fY = self::fade($y); - //$fZ = self::fade($z); - $fX = $x * $x * $x * ($x * ($x * 6 - 15) + 10); - $fY = $y * $y * $y * ($y * ($y * 6 - 15) + 10); - $fZ = $z * $z * $z * ($z * ($z * 6 - 15) + 10); - - //Cube corners - $A = $this->perm[$X] + $Y; - $B = $this->perm[$X + 1] + $Y; - - $AA = $this->perm[$A] + $Z; - $AB = $this->perm[$A + 1] + $Z; - $BA = $this->perm[$B] + $Z; - $BB = $this->perm[$B + 1] + $Z; - - $AA1 = self::grad($this->perm[$AA], $x, $y, $z); - $BA1 = self::grad($this->perm[$BA], $x - 1, $y, $z); - $AB1 = self::grad($this->perm[$AB], $x, $y - 1, $z); - $BB1 = self::grad($this->perm[$BB], $x - 1, $y - 1, $z); - $AA2 = self::grad($this->perm[$AA + 1], $x, $y, $z - 1); - $BA2 = self::grad($this->perm[$BA + 1], $x - 1, $y, $z - 1); - $AB2 = self::grad($this->perm[$AB + 1], $x, $y - 1, $z - 1); - $BB2 = self::grad($this->perm[$BB + 1], $x - 1, $y - 1, $z - 1); - - $xLerp11 = $AA1 + $fX * ($BA1 - $AA1); - - $zLerp1 = $xLerp11 + $fY * ($AB1 + $fX * ($BB1 - $AB1) - $xLerp11); - - $xLerp21 = $AA2 + $fX * ($BA2 - $AA2); - - return $zLerp1 + $fZ * ($xLerp21 + $fY * ($AB2 + $fX * ($BB2 - $AB2) - $xLerp21) - $zLerp1); - - /* - return self::lerp( - $fZ, - self::lerp( - $fY, - self::lerp( - $fX, - self::grad($this->perm[$AA], $x, $y, $z), - self::grad($this->perm[$BA], $x - 1, $y, $z) - ), - self::lerp( - $fX, - self::grad($this->perm[$AB], $x, $y - 1, $z), - self::grad($this->perm[$BB], $x - 1, $y - 1, $z) - ) - ), - self::lerp( - $fY, - self::lerp( - $fX, - self::grad($this->perm[$AA + 1], $x, $y, $z - 1), - self::grad($this->perm[$BA + 1], $x - 1, $y, $z - 1) - ), - self::lerp( - $fX, - self::grad($this->perm[$AB + 1], $x, $y - 1, $z - 1), - self::grad($this->perm[$BB + 1], $x - 1, $y - 1, $z - 1) - ) - ) - ); - */ - } - - public function getNoise2D($x, $y){ - return $this->getNoise3D($x, $y, 0); - } -} diff --git a/src/pocketmine/level/generator/noise/Simplex.php b/src/pocketmine/level/generator/noise/Simplex.php index d29546f7e0..3e009f288a 100644 --- a/src/pocketmine/level/generator/noise/Simplex.php +++ b/src/pocketmine/level/generator/noise/Simplex.php @@ -32,7 +32,13 @@ use pocketmine\utils\Random; * Stefan Gustavson at * http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf */ -class Simplex extends Perlin{ +class Simplex extends Noise{ + public static $grad3 = [ + [1, 1, 0], [-1, 1, 0], [1, -1, 0], [-1, -1, 0], + [1, 0, 1], [-1, 0, 1], [1, 0, -1], [-1, 0, -1], + [0, 1, 1], [0, -1, 1], [0, 1, -1], [0, -1, -1] + ]; + protected static $SQRT_3; protected static $SQRT_5; protected static $F2; @@ -66,8 +72,32 @@ class Simplex extends Perlin{ public function __construct(Random $random, $octaves, $persistence, $expansion = 1){ - parent::__construct($random, $octaves, $persistence, $expansion); + $this->octaves = $octaves; + $this->persistence = $persistence; + $this->expansion = $expansion; + $this->offsetX = $random->nextFloat() * 256; + $this->offsetY = $random->nextFloat() * 256; + $this->offsetZ = $random->nextFloat() * 256; $this->offsetW = $random->nextFloat() * 256; + + for($i = 0; $i < 512; ++$i){ + $this->perm[$i] = 0; + } + + for($i = 0; $i < 256; ++$i){ + $this->perm[$i] = $random->nextBoundedInt(256); + } + + for($i = 0; $i < 256; ++$i){ + $pos = $random->nextBoundedInt(256 - $i) + $i; + $old = $this->perm[$i]; + + $this->perm[$i] = $this->perm[$pos]; + $this->perm[$pos] = $old; + $this->perm[$i + 256] = $this->perm[$i]; + } + + self::$SQRT_3 = sqrt(3); self::$SQRT_5 = sqrt(5); self::$F2 = 0.5 * (self::$SQRT_3 - 1); From f4105fd91a6c9cb9b5c59a18d9511dcf4219a78c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Oct 2018 17:04:53 +0100 Subject: [PATCH 0269/3224] Noise: remove a ton of dead code --- .../level/generator/noise/Noise.php | 30 +- .../level/generator/noise/Simplex.php | 270 ++---------------- 2 files changed, 34 insertions(+), 266 deletions(-) diff --git a/src/pocketmine/level/generator/noise/Noise.php b/src/pocketmine/level/generator/noise/Noise.php index b16b05aabb..78b7903203 100644 --- a/src/pocketmine/level/generator/noise/Noise.php +++ b/src/pocketmine/level/generator/noise/Noise.php @@ -36,18 +36,6 @@ abstract class Noise{ protected $persistence; protected $expansion; - public static function floor($x) : int{ - return $x >= 0 ? (int) $x : (int) ($x - 1); - } - - public static function fade($x){ - return $x * $x * $x * ($x * ($x * 6 - 15) + 10); - } - - public static function lerp($x, $y, $z){ - return $y + $x * ($z - $y); - } - public static function linearLerp($x, $x1, $x2, $q0, $q1){ return (($x2 - $x) / ($x2 - $x1)) * $q0 + (($x - $x1) / ($x2 - $x1)) * $q1; } @@ -84,14 +72,6 @@ abstract class Noise{ ); } - public static function grad($hash, $x, $y, $z){ - $hash &= 15; - $u = $hash < 8 ? $x : $y; - $v = $hash < 4 ? $y : (($hash === 12 or $hash === 14) ? $x : $z); - - return (($hash & 1) === 0 ? $u : -$u) + (($hash & 2) === 0 ? $v : -$v); - } - abstract public function getNoise2D($x, $z); abstract public function getNoise3D($x, $y, $z); @@ -268,6 +248,10 @@ abstract class Noise{ $nny = $ny + $ySamplingRate; $nnz = $nz + $zSamplingRate; + /** + * This code has been manually inlined. + * @see Noise::trilinearLerp() + */ $dx1 = (($nnx - $xx) / ($nnx - $nx)); $dx2 = (($xx - $nx) / ($nnx - $nx)); $dy1 = (($nny - $yy) / ($nny - $ny)); @@ -293,10 +277,4 @@ abstract class Noise{ return $noiseArray; } - - public function setOffset($x, $y, $z){ - $this->offsetX = $x; - $this->offsetY = $y; - $this->offsetZ = $z; - } } diff --git a/src/pocketmine/level/generator/noise/Simplex.php b/src/pocketmine/level/generator/noise/Simplex.php index 3e009f288a..d96070bb91 100644 --- a/src/pocketmine/level/generator/noise/Simplex.php +++ b/src/pocketmine/level/generator/noise/Simplex.php @@ -33,43 +33,17 @@ use pocketmine\utils\Random; * http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf */ class Simplex extends Noise{ - public static $grad3 = [ + protected const grad3 = [ [1, 1, 0], [-1, 1, 0], [1, -1, 0], [-1, -1, 0], [1, 0, 1], [-1, 0, 1], [1, 0, -1], [-1, 0, -1], [0, 1, 1], [0, -1, 1], [0, 1, -1], [0, -1, -1] ]; - protected static $SQRT_3; - protected static $SQRT_5; - protected static $F2; - protected static $G2; - protected static $G22; - protected static $F3; - protected static $G3; - protected static $F4; - protected static $G4; - protected static $G42; - protected static $G43; - protected static $G44; - protected static $grad4 = [[0, 1, 1, 1], [0, 1, 1, -1], [0, 1, -1, 1], [0, 1, -1, -1], - [0, -1, 1, 1], [0, -1, 1, -1], [0, -1, -1, 1], [0, -1, -1, -1], - [1, 0, 1, 1], [1, 0, 1, -1], [1, 0, -1, 1], [1, 0, -1, -1], - [-1, 0, 1, 1], [-1, 0, 1, -1], [-1, 0, -1, 1], [-1, 0, -1, -1], - [1, 1, 0, 1], [1, 1, 0, -1], [1, -1, 0, 1], [1, -1, 0, -1], - [-1, 1, 0, 1], [-1, 1, 0, -1], [-1, -1, 0, 1], [-1, -1, 0, -1], - [1, 1, 1, 0], [1, 1, -1, 0], [1, -1, 1, 0], [1, -1, -1, 0], - [-1, 1, 1, 0], [-1, 1, -1, 0], [-1, -1, 1, 0], [-1, -1, -1, 0]]; - protected static $simplex = [ - [0, 1, 2, 3], [0, 1, 3, 2], [0, 0, 0, 0], [0, 2, 3, 1], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1, 2, 3, 0], - [0, 2, 1, 3], [0, 0, 0, 0], [0, 3, 1, 2], [0, 3, 2, 1], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1, 3, 2, 0], - [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], - [1, 2, 0, 3], [0, 0, 0, 0], [1, 3, 0, 2], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [2, 3, 0, 1], [2, 3, 1, 0], - [1, 0, 2, 3], [1, 0, 3, 2], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [2, 0, 3, 1], [0, 0, 0, 0], [2, 1, 3, 0], - [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], - [2, 0, 1, 3], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [3, 0, 1, 2], [3, 0, 2, 1], [0, 0, 0, 0], [3, 1, 2, 0], - [2, 1, 0, 3], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [3, 1, 0, 2], [0, 0, 0, 0], [3, 2, 0, 1], [3, 2, 1, 0]]; - protected $offsetW; - + protected const F2 = 0.5 * (M_SQRT3 - 1); + protected const G2 = (3 - M_SQRT3) / 6; + protected const G22 = self::G2 * 2.0 - 1; + protected const F3 = 1.0 / 3.0; + protected const G3 = 1.0 / 6.0; public function __construct(Random $random, $octaves, $persistence, $expansion = 1){ $this->octaves = $octaves; @@ -78,7 +52,6 @@ class Simplex extends Noise{ $this->offsetX = $random->nextFloat() * 256; $this->offsetY = $random->nextFloat() * 256; $this->offsetZ = $random->nextFloat() * 256; - $this->offsetW = $random->nextFloat() * 256; for($i = 0; $i < 512; ++$i){ $this->perm[$i] = 0; @@ -96,32 +69,6 @@ class Simplex extends Noise{ $this->perm[$pos] = $old; $this->perm[$i + 256] = $this->perm[$i]; } - - - self::$SQRT_3 = sqrt(3); - self::$SQRT_5 = sqrt(5); - self::$F2 = 0.5 * (self::$SQRT_3 - 1); - self::$G2 = (3 - self::$SQRT_3) / 6; - self::$G22 = self::$G2 * 2.0 - 1; - self::$F3 = 1.0 / 3.0; - self::$G3 = 1.0 / 6.0; - self::$F4 = (self::$SQRT_5 - 1.0) / 4.0; - self::$G4 = (5.0 - self::$SQRT_5) / 20.0; - self::$G42 = self::$G4 * 2.0; - self::$G43 = self::$G4 * 3.0; - self::$G44 = self::$G4 * 4.0 - 1.0; - } - - protected static function dot2D($g, $x, $y){ - return $g[0] * $x + $g[1] * $y; - } - - protected static function dot3D($g, $x, $y, $z){ - return $g[0] * $x + $g[1] * $y + $g[2] * $z; - } - - protected static function dot4D($g, $x, $y, $z, $w){ - return $g[0] * $x + $g[1] * $y + $g[2] * $z + $g[3] * $w; } public function getNoise3D($x, $y, $z){ @@ -130,11 +77,11 @@ class Simplex extends Noise{ $z += $this->offsetZ; // Skew the input space to determine which simplex cell we're in - $s = ($x + $y + $z) * self::$F3; // Very nice and simple skew factor for 3D + $s = ($x + $y + $z) * self::F3; // Very nice and simple skew factor for 3D $i = (int) ($x + $s); $j = (int) ($y + $s); $k = (int) ($z + $s); - $t = ($i + $j + $k) * self::$G3; + $t = ($i + $j + $k) * self::G3; // Unskew the cell origin back to (x,y,z) space $x0 = $x - ($i - $t); // The x,y,z distances from the cell origin $y0 = $y - ($j - $t); @@ -201,15 +148,15 @@ class Simplex extends Noise{ // a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and // a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where // c = 1/6. - $x1 = $x0 - $i1 + self::$G3; // Offsets for second corner in (x,y,z) coords - $y1 = $y0 - $j1 + self::$G3; - $z1 = $z0 - $k1 + self::$G3; - $x2 = $x0 - $i2 + 2.0 * self::$G3; // Offsets for third corner in (x,y,z) coords - $y2 = $y0 - $j2 + 2.0 * self::$G3; - $z2 = $z0 - $k2 + 2.0 * self::$G3; - $x3 = $x0 - 1.0 + 3.0 * self::$G3; // Offsets for last corner in (x,y,z) coords - $y3 = $y0 - 1.0 + 3.0 * self::$G3; - $z3 = $z0 - 1.0 + 3.0 * self::$G3; + $x1 = $x0 - $i1 + self::G3; // Offsets for second corner in (x,y,z) coords + $y1 = $y0 - $j1 + self::G3; + $z1 = $z0 - $k1 + self::G3; + $x2 = $x0 - $i2 + 2.0 * self::G3; // Offsets for third corner in (x,y,z) coords + $y2 = $y0 - $j2 + 2.0 * self::G3; + $z2 = $z0 - $k2 + 2.0 * self::G3; + $x3 = $x0 - 1.0 + 3.0 * self::G3; // Offsets for last corner in (x,y,z) coords + $y3 = $y0 - 1.0 + 3.0 * self::G3; + $z3 = $z0 - 1.0 + 3.0 * self::G3; // Work out the hashed gradient indices of the four simplex corners $ii = $i & 255; @@ -221,25 +168,25 @@ class Simplex extends Noise{ // Calculate the contribution from the four corners $t0 = 0.6 - $x0 * $x0 - $y0 * $y0 - $z0 * $z0; if($t0 > 0){ - $gi0 = self::$grad3[$this->perm[$ii + $this->perm[$jj + $this->perm[$kk]]] % 12]; + $gi0 = self::grad3[$this->perm[$ii + $this->perm[$jj + $this->perm[$kk]]] % 12]; $n += $t0 * $t0 * $t0 * $t0 * ($gi0[0] * $x0 + $gi0[1] * $y0 + $gi0[2] * $z0); } $t1 = 0.6 - $x1 * $x1 - $y1 * $y1 - $z1 * $z1; if($t1 > 0){ - $gi1 = self::$grad3[$this->perm[$ii + $i1 + $this->perm[$jj + $j1 + $this->perm[$kk + $k1]]] % 12]; + $gi1 = self::grad3[$this->perm[$ii + $i1 + $this->perm[$jj + $j1 + $this->perm[$kk + $k1]]] % 12]; $n += $t1 * $t1 * $t1 * $t1 * ($gi1[0] * $x1 + $gi1[1] * $y1 + $gi1[2] * $z1); } $t2 = 0.6 - $x2 * $x2 - $y2 * $y2 - $z2 * $z2; if($t2 > 0){ - $gi2 = self::$grad3[$this->perm[$ii + $i2 + $this->perm[$jj + $j2 + $this->perm[$kk + $k2]]] % 12]; + $gi2 = self::grad3[$this->perm[$ii + $i2 + $this->perm[$jj + $j2 + $this->perm[$kk + $k2]]] % 12]; $n += $t2 * $t2 * $t2 * $t2 * ($gi2[0] * $x2 + $gi2[1] * $y2 + $gi2[2] * $z2); } $t3 = 0.6 - $x3 * $x3 - $y3 * $y3 - $z3 * $z3; if($t3 > 0){ - $gi3 = self::$grad3[$this->perm[$ii + 1 + $this->perm[$jj + 1 + $this->perm[$kk + 1]]] % 12]; + $gi3 = self::grad3[$this->perm[$ii + 1 + $this->perm[$jj + 1 + $this->perm[$kk + 1]]] % 12]; $n += $t3 * $t3 * $t3 * $t3 * ($gi3[0] * $x3 + $gi3[1] * $y3 + $gi3[2] * $z3); } @@ -253,10 +200,10 @@ class Simplex extends Noise{ $y += $this->offsetY; // Skew the input space to determine which simplex cell we're in - $s = ($x + $y) * self::$F2; // Hairy factor for 2D + $s = ($x + $y) * self::F2; // Hairy factor for 2D $i = (int) ($x + $s); $j = (int) ($y + $s); - $t = ($i + $j) * self::$G2; + $t = ($i + $j) * self::G2; // Unskew the cell origin back to (x,y) space $x0 = $x - ($i - $t); // The x,y distances from the cell origin $y0 = $y - ($j - $t); @@ -278,10 +225,10 @@ class Simplex extends Noise{ // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where // c = (3-sqrt(3))/6 - $x1 = $x0 - $i1 + self::$G2; // Offsets for middle corner in (x,y) unskewed coords - $y1 = $y0 - $j1 + self::$G2; - $x2 = $x0 + self::$G22; // Offsets for last corner in (x,y) unskewed coords - $y2 = $y0 + self::$G22; + $x1 = $x0 - $i1 + self::G2; // Offsets for middle corner in (x,y) unskewed coords + $y1 = $y0 - $j1 + self::G2; + $x2 = $x0 + self::G22; // Offsets for last corner in (x,y) unskewed coords + $y2 = $y0 + self::G22; // Work out the hashed gradient indices of the three simplex corners $ii = $i & 255; @@ -292,19 +239,19 @@ class Simplex extends Noise{ // Calculate the contribution from the three corners $t0 = 0.5 - $x0 * $x0 - $y0 * $y0; if($t0 > 0){ - $gi0 = self::$grad3[$this->perm[$ii + $this->perm[$jj]] % 12]; + $gi0 = self::grad3[$this->perm[$ii + $this->perm[$jj]] % 12]; $n += $t0 * $t0 * $t0 * $t0 * ($gi0[0] * $x0 + $gi0[1] * $y0); // (x,y) of grad3 used for 2D gradient } $t1 = 0.5 - $x1 * $x1 - $y1 * $y1; if($t1 > 0){ - $gi1 = self::$grad3[$this->perm[$ii + $i1 + $this->perm[$jj + $j1]] % 12]; + $gi1 = self::grad3[$this->perm[$ii + $i1 + $this->perm[$jj + $j1]] % 12]; $n += $t1 * $t1 * $t1 * $t1 * ($gi1[0] * $x1 + $gi1[1] * $y1); } $t2 = 0.5 - $x2 * $x2 - $y2 * $y2; if($t2 > 0){ - $gi2 = self::$grad3[$this->perm[$ii + 1 + $this->perm[$jj + 1]] % 12]; + $gi2 = self::grad3[$this->perm[$ii + 1 + $this->perm[$jj + 1]] % 12]; $n += $t2 * $t2 * $t2 * $t2 * ($gi2[0] * $x2 + $gi2[1] * $y2); } @@ -312,161 +259,4 @@ class Simplex extends Noise{ // The result is scaled to return values in the interval [-1,1]. return 70.0 * $n; } - - /** - * Computes and returns the 4D simplex noise for the given coordinates in - * 4D space - * - * @param float $x X coordinate - * @param float $y Y coordinate - * @param float $z Z coordinate - * @param float $w W coordinate - * - * @return float Noise at given location, from range -1 to 1 - */ - /*public function getNoise4D($x, $y, $z, $w){ - x += offsetX; - y += offsetY; - z += offsetZ; - w += offsetW; - - n0, n1, n2, n3, n4; // Noise contributions from the five corners - - // Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in - s = (x + y + z + w) * self::$F4; // Factor for 4D skewing - i = floor(x + s); - j = floor(y + s); - k = floor(z + s); - l = floor(w + s); - - t = (i + j + k + l) * self::$G4; // Factor for 4D unskewing - X0 = i - t; // Unskew the cell origin back to (x,y,z,w) space - Y0 = j - t; - Z0 = k - t; - W0 = l - t; - x0 = x - X0; // The x,y,z,w distances from the cell origin - y0 = y - Y0; - z0 = z - Z0; - w0 = w - W0; - - // For the 4D case, the simplex is a 4D shape I won't even try to describe. - // To find out which of the 24 possible simplices we're in, we need to - // determine the magnitude ordering of x0, y0, z0 and w0. - // The method below is a good way of finding the ordering of x,y,z,w and - // then find the correct traversal order for the simplex we’re in. - // First, six pair-wise comparisons are performed between each possible pair - // of the four coordinates, and the results are used to add up binary bits - // for an integer index. - c1 = (x0 > y0) ? 32 : 0; - c2 = (x0 > z0) ? 16 : 0; - c3 = (y0 > z0) ? 8 : 0; - c4 = (x0 > w0) ? 4 : 0; - c5 = (y0 > w0) ? 2 : 0; - c6 = (z0 > w0) ? 1 : 0; - c = c1 + c2 + c3 + c4 + c5 + c6; - i1, j1, k1, l1; // The integer offsets for the second simplex corner - i2, j2, k2, l2; // The integer offsets for the third simplex corner - i3, j3, k3, l3; // The integer offsets for the fourth simplex corner - - // simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order. - // Many values of c will never occur, since e.g. x>y>z>w makes x= 3 ? 1 : 0; - j1 = simplex[c][1] >= 3 ? 1 : 0; - k1 = simplex[c][2] >= 3 ? 1 : 0; - l1 = simplex[c][3] >= 3 ? 1 : 0; - - // The number 2 in the "simplex" array is at the second largest coordinate. - i2 = simplex[c][0] >= 2 ? 1 : 0; - j2 = simplex[c][1] >= 2 ? 1 : 0; - k2 = simplex[c][2] >= 2 ? 1 : 0; - l2 = simplex[c][3] >= 2 ? 1 : 0; - - // The number 1 in the "simplex" array is at the second smallest coordinate. - i3 = simplex[c][0] >= 1 ? 1 : 0; - j3 = simplex[c][1] >= 1 ? 1 : 0; - k3 = simplex[c][2] >= 1 ? 1 : 0; - l3 = simplex[c][3] >= 1 ? 1 : 0; - - // The fifth corner has all coordinate offsets = 1, so no need to look that up. - - x1 = x0 - i1 + self::$G4; // Offsets for second corner in (x,y,z,w) coords - y1 = y0 - j1 + self::$G4; - z1 = z0 - k1 + self::$G4; - w1 = w0 - l1 + self::$G4; - - x2 = x0 - i2 + self::$G42; // Offsets for third corner in (x,y,z,w) coords - y2 = y0 - j2 + self::$G42; - z2 = z0 - k2 + self::$G42; - w2 = w0 - l2 + self::$G42; - - x3 = x0 - i3 + self::$G43; // Offsets for fourth corner in (x,y,z,w) coords - y3 = y0 - j3 + self::$G43; - z3 = z0 - k3 + self::$G43; - w3 = w0 - l3 + self::$G43; - - x4 = x0 + self::$G44; // Offsets for last corner in (x,y,z,w) coords - y4 = y0 + self::$G44; - z4 = z0 + self::$G44; - w4 = w0 + self::$G44; - - // Work out the hashed gradient indices of the five simplex corners - ii = i & 255; - jj = j & 255; - kk = k & 255; - ll = l & 255; - - gi0 = $this->perm[ii + $this->perm[jj + $this->perm[kk + $this->perm[ll]]]] % 32; - gi1 = $this->perm[ii + i1 + $this->perm[jj + j1 + $this->perm[kk + k1 + $this->perm[ll + l1]]]] % 32; - gi2 = $this->perm[ii + i2 + $this->perm[jj + j2 + $this->perm[kk + k2 + $this->perm[ll + l2]]]] % 32; - gi3 = $this->perm[ii + i3 + $this->perm[jj + j3 + $this->perm[kk + k3 + $this->perm[ll + l3]]]] % 32; - gi4 = $this->perm[ii + 1 + $this->perm[jj + 1 + $this->perm[kk + 1 + $this->perm[ll + 1]]]] % 32; - - // Calculate the contribution from the five corners - t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0; - if(t0 < 0){ - n0 = 0.0; - }else{ - t0 *= t0; - n0 = t0 * t0 * dot(grad4[gi0], x0, y0, z0, w0); - } - - t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1; - if(t1 < 0){ - n1 = 0.0; - }else{ - t1 *= t1; - n1 = t1 * t1 * dot(grad4[gi1], x1, y1, z1, w1); - } - - t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2; - if(t2 < 0){ - n2 = 0.0; - }else{ - t2 *= t2; - n2 = t2 * t2 * dot(grad4[gi2], x2, y2, z2, w2); - } - - t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3; - if(t3 < 0){ - n3 = 0.0; - }else{ - t3 *= t3; - n3 = t3 * t3 * dot(grad4[gi3], x3, y3, z3, w3); - } - - t4 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4; - if(t4 < 0){ - n4 = 0.0; - }else{ - t4 *= t4; - n4 = t4 * t4 * dot(grad4[gi4], x4, y4, z4, w4); - } - - // Sum up and scale the result to cover the range [-1,1] - return 27.0 * (n0 + n1 + n2 + n3 + n4); - }*/ } From e1795dfd4978e22770e0d08e569bfca89eb5d284 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Oct 2018 21:50:14 +0100 Subject: [PATCH 0270/3224] Fixed wtf in Durable->setDamage() exception throw --- src/pocketmine/item/Durable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/item/Durable.php b/src/pocketmine/item/Durable.php index 22cabb9751..f25004797c 100644 --- a/src/pocketmine/item/Durable.php +++ b/src/pocketmine/item/Durable.php @@ -76,7 +76,7 @@ abstract class Durable extends Item{ public function setDamage(int $damage) : Item{ if($damage < 0 or $damage > $this->getMaxDurability()){ - throw new \InvalidArgumentException("Damage must be in range 0 - " , $this->getMaxDurability()); + throw new \InvalidArgumentException("Damage must be in range 0 - " . $this->getMaxDurability()); } $this->damage = $damage; return $this; From 1e8b153662047e2fe0e970c84a69d2dbe978abe9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 28 Oct 2018 16:19:20 +0000 Subject: [PATCH 0271/3224] Further cleanup to Simplex/Noise hierarchy --- .../level/generator/noise/Noise.php | 21 ++++++++++++------- .../level/generator/noise/Simplex.php | 16 ++++++++++---- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/pocketmine/level/generator/noise/Noise.php b/src/pocketmine/level/generator/noise/Noise.php index 78b7903203..4b51180b24 100644 --- a/src/pocketmine/level/generator/noise/Noise.php +++ b/src/pocketmine/level/generator/noise/Noise.php @@ -28,13 +28,7 @@ namespace pocketmine\level\generator\noise; abstract class Noise{ - protected $perm = []; - protected $offsetX = 0; - protected $offsetY = 0; - protected $offsetZ = 0; - protected $octaves = 8; - protected $persistence; - protected $expansion; + public static function linearLerp($x, $x1, $x2, $q0, $q1){ return (($x2 - $x) / ($x2 - $x1)) * $q0 + (($x - $x1) / ($x2 - $x1)) * $q1; @@ -72,6 +66,19 @@ abstract class Noise{ ); } + /** @var float */ + protected $persistence; + /** @var float */ + protected $expansion; + /** @var int */ + protected $octaves; + + public function __construct(int $octaves, float $persistence, float $expansion){ + $this->octaves = $octaves; + $this->persistence = $persistence; + $this->expansion = $expansion; + } + abstract public function getNoise2D($x, $z); abstract public function getNoise3D($x, $y, $z); diff --git a/src/pocketmine/level/generator/noise/Simplex.php b/src/pocketmine/level/generator/noise/Simplex.php index d96070bb91..846d45566a 100644 --- a/src/pocketmine/level/generator/noise/Simplex.php +++ b/src/pocketmine/level/generator/noise/Simplex.php @@ -45,10 +45,18 @@ class Simplex extends Noise{ protected const F3 = 1.0 / 3.0; protected const G3 = 1.0 / 6.0; - public function __construct(Random $random, $octaves, $persistence, $expansion = 1){ - $this->octaves = $octaves; - $this->persistence = $persistence; - $this->expansion = $expansion; + /** @var float */ + protected $offsetX; + /** @var float */ + protected $offsetZ; + /** @var float */ + protected $offsetY; + /** @var int[] */ + protected $perm = []; + + public function __construct(Random $random, int $octaves, float $persistence, float $expansion){ + parent::__construct($octaves, $persistence, $expansion); + $this->offsetX = $random->nextFloat() * 256; $this->offsetY = $random->nextFloat() * 256; $this->offsetZ = $random->nextFloat() * 256; From 7607e484dd74a7ba28b657f6f7fbf948537f8de9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 28 Oct 2018 16:32:56 +0000 Subject: [PATCH 0272/3224] Expose chunk locking to the API --- src/pocketmine/level/Level.php | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index df9fc51cd4..626081965e 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -198,7 +198,7 @@ class Level implements ChunkManager, Metadatable{ /** @var bool[] */ private $chunkPopulationQueue = []; /** @var bool[] */ - private $chunkPopulationLock = []; + private $chunkLock = []; /** @var int */ private $chunkPopulationQueueSize = 2; /** @var bool[] */ @@ -2314,12 +2314,28 @@ class Level implements ChunkManager, Metadatable{ return $result; } + public function lockChunk(int $chunkX, int $chunkZ) : void{ + $chunkHash = Level::chunkHash($chunkX, $chunkZ); + if(isset($this->chunkLock[$chunkHash])){ + throw new \InvalidArgumentException("Chunk $chunkX $chunkZ is already locked"); + } + $this->chunkLock[$chunkHash] = true; + } + + public function unlockChunk(int $chunkX, int $chunkZ) : void{ + unset($this->chunkLock[Level::chunkHash($chunkX, $chunkZ)]); + } + + public function isChunkLocked(int $chunkX, int $chunkZ) : bool{ + return isset($this->chunkLock[Level::chunkHash($chunkX, $chunkZ)]); + } + public function generateChunkCallback(int $x, int $z, ?Chunk $chunk){ Timings::$generationCallbackTimer->startTiming(); if(isset($this->chunkPopulationQueue[$index = Level::chunkHash($x, $z)])){ for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ - unset($this->chunkPopulationLock[Level::chunkHash($x + $xx, $z + $zz)]); + $this->unlockChunk($x + $xx, $z + $zz); } } unset($this->chunkPopulationQueue[$index]); @@ -2335,8 +2351,8 @@ class Level implements ChunkManager, Metadatable{ } } } - }elseif(isset($this->chunkPopulationLock[$index])){ - unset($this->chunkPopulationLock[$index]); + }elseif($this->isChunkLocked($x, $z)){ + $this->unlockChunk($x, $z); if($chunk !== null){ $this->setChunk($x, $z, $chunk, false); } @@ -2958,7 +2974,7 @@ class Level implements ChunkManager, Metadatable{ } for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ - if(isset($this->chunkPopulationLock[Level::chunkHash($x + $xx, $z + $zz)])){ + if($this->isChunkLocked($x + $xx, $z + $zz)){ return false; } } @@ -2971,7 +2987,7 @@ class Level implements ChunkManager, Metadatable{ $this->chunkPopulationQueue[$index] = true; for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ - $this->chunkPopulationLock[Level::chunkHash($x + $xx, $z + $zz)] = true; + $this->lockChunk($x + $xx, $z + $zz); } } From a6c31b72aeabab112d0044f5c71282152345209f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 28 Oct 2018 16:42:16 +0000 Subject: [PATCH 0273/3224] Level: throw exceptions on bad positions in setBlock() --- src/pocketmine/level/Level.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 626081965e..d40bc59cf9 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1511,7 +1511,7 @@ class Level implements ChunkManager, Metadatable{ public function setBlock(Vector3 $pos, Block $block, bool $update = true) : bool{ $pos = $pos->floor(); if(!$this->isInWorld($pos->x, $pos->y, $pos->z)){ - return false; + throw new \InvalidArgumentException("Pos x=$pos->x,y=$pos->y,z=$pos->z is outside of the world bounds"); } $this->timings->setBlock->startTiming(); From 95be571481a8f9ab09a06c9fe6bc0ff97084cb65 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Oct 2018 12:45:39 +0000 Subject: [PATCH 0274/3224] Fixed Item->equals() not working for no-NBT items since 9bb3c93285d8589cde855b08318e32514eff78c4 --- src/pocketmine/item/Item.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 2df5a4dd11..eb6f564278 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -785,10 +785,11 @@ class Item implements ItemIds, \JsonSerializable{ final public function equals(Item $item, bool $checkDamage = true, bool $checkCompound = true) : bool{ if($this->id === $item->getId() and (!$checkDamage or $this->getDamage() === $item->getDamage())){ if($checkCompound){ - if($this->hasNamedTag() and $item->hasNamedTag()){ - //Serialized NBT didn't match, check the cached object tree. + if($this->hasNamedTag() and $item->hasNamedTag()){ //both items have NBT return $this->getNamedTag()->equals($item->getNamedTag()); } + + return (!$this->hasNamedTag() and !$item->hasNamedTag()); //both items must have no NBT }else{ return true; } From d011fc518ecf16c8f5526dc2c774006a542d5305 Mon Sep 17 00:00:00 2001 From: Daniktheboss Date: Mon, 29 Oct 2018 09:16:57 -0700 Subject: [PATCH 0275/3224] Fixed wooden doors not dropping when removing supporting block, closes #2436 (#2496) --- src/pocketmine/block/Door.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 68456e4e45..a99638ef3e 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -143,10 +143,7 @@ abstract class Door extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() === self::AIR){ //Replace with common break method - $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR)); - if($this->getSide(Facing::UP) instanceof Door){ - $this->getLevel()->setBlock($this->getSide(Facing::UP), BlockFactory::get(Block::AIR)); - } + $this->getLevel()->useBreakOn($this); //this will delete both halves if they exist } } From 38d419fb29783a7c73dd746e612f6674a425b3dc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 4 Nov 2018 12:59:34 +0000 Subject: [PATCH 0276/3224] Level: use isInWorld() where appropriate --- src/pocketmine/level/Level.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index d40bc59cf9..181a50b6f0 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1782,7 +1782,7 @@ class Level implements ChunkManager, Metadatable{ $clickVector = new Vector3(0.0, 0.0, 0.0); } - if($blockReplace->y >= $this->worldHeight or $blockReplace->y < 0){ + if(!$this->isInWorld($blockReplace->x, $blockReplace->y, $blockReplace->z)){ //TODO: build height limit messages for custom world heights and mcregion cap return false; } From 6437078c8bcb55143cae98e81e44a889cff24213 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 4 Nov 2018 23:30:04 +0000 Subject: [PATCH 0277/3224] TaskScheduler: remove deprecated constructor parameter --- src/pocketmine/plugin/PluginBase.php | 2 +- src/pocketmine/scheduler/TaskScheduler.php | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/plugin/PluginBase.php b/src/pocketmine/plugin/PluginBase.php index a824b8daf7..102d98ed40 100644 --- a/src/pocketmine/plugin/PluginBase.php +++ b/src/pocketmine/plugin/PluginBase.php @@ -67,7 +67,7 @@ abstract class PluginBase implements Plugin{ $this->file = rtrim($file, "\\/") . "/"; $this->configFile = $this->dataFolder . "config.yml"; $this->logger = new PluginLogger($this); - $this->scheduler = new TaskScheduler($this->logger, $this->getFullName()); + $this->scheduler = new TaskScheduler($this->getFullName()); $this->onLoad(); } diff --git a/src/pocketmine/scheduler/TaskScheduler.php b/src/pocketmine/scheduler/TaskScheduler.php index 857074b4c2..8174edbbef 100644 --- a/src/pocketmine/scheduler/TaskScheduler.php +++ b/src/pocketmine/scheduler/TaskScheduler.php @@ -53,10 +53,9 @@ class TaskScheduler{ protected $currentTick = 0; /** - * @param \Logger $logger @deprecated * @param null|string $owner */ - public function __construct(\Logger $logger, ?string $owner = null){ + public function __construct(?string $owner = null){ $this->owner = $owner; $this->queue = new ReversePriorityQueue(); } From ce7718f0d180f2ff3c0ef05a3c6985225d6f9736 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 5 Nov 2018 09:39:49 +0000 Subject: [PATCH 0278/3224] Move resources/ directory out of src/ this isn't source code and as such doesn't belong in here. --- .gitmodules | 2 +- {src/pocketmine/resources => resources}/pocketmine.yml | 0 {src/pocketmine/resources => resources}/resource_packs.yml | 0 {src/pocketmine/resources => resources}/runtimeid_table.json | 0 {src/pocketmine/resources => resources}/vanilla | 0 src/pocketmine/PocketMine.php | 2 +- tests/plugins/PocketMine-DevTools | 2 +- tests/travis.sh | 2 +- 8 files changed, 4 insertions(+), 4 deletions(-) rename {src/pocketmine/resources => resources}/pocketmine.yml (100%) rename {src/pocketmine/resources => resources}/resource_packs.yml (100%) rename {src/pocketmine/resources => resources}/runtimeid_table.json (100%) rename {src/pocketmine/resources => resources}/vanilla (100%) diff --git a/.gitmodules b/.gitmodules index cf20af141b..21adfef04b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -8,5 +8,5 @@ path = tests/plugins/PocketMine-DevTools url = https://github.com/pmmp/PocketMine-DevTools.git [submodule "src/pocketmine/resources/vanilla"] - path = src/pocketmine/resources/vanilla + path = resources/vanilla url = https://github.com/pmmp/BedrockData.git diff --git a/src/pocketmine/resources/pocketmine.yml b/resources/pocketmine.yml similarity index 100% rename from src/pocketmine/resources/pocketmine.yml rename to resources/pocketmine.yml diff --git a/src/pocketmine/resources/resource_packs.yml b/resources/resource_packs.yml similarity index 100% rename from src/pocketmine/resources/resource_packs.yml rename to resources/resource_packs.yml diff --git a/src/pocketmine/resources/runtimeid_table.json b/resources/runtimeid_table.json similarity index 100% rename from src/pocketmine/resources/runtimeid_table.json rename to resources/runtimeid_table.json diff --git a/src/pocketmine/resources/vanilla b/resources/vanilla similarity index 100% rename from src/pocketmine/resources/vanilla rename to resources/vanilla diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index a865e32bc4..9023c2e193 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -181,7 +181,7 @@ namespace pocketmine { ini_set("memory_limit", '-1'); define('pocketmine\START_TIME', microtime(true)); - define('pocketmine\RESOURCE_PATH', \pocketmine\PATH . 'src' . DIRECTORY_SEPARATOR . 'pocketmine' . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR); + define('pocketmine\RESOURCE_PATH', \pocketmine\PATH . 'resources' . DIRECTORY_SEPARATOR); $opts = getopt("", ["data:", "plugins:", "no-wizard"]); diff --git a/tests/plugins/PocketMine-DevTools b/tests/plugins/PocketMine-DevTools index 3318ac4c0e..cc6a5b5aa7 160000 --- a/tests/plugins/PocketMine-DevTools +++ b/tests/plugins/PocketMine-DevTools @@ -1 +1 @@ -Subproject commit 3318ac4c0e6c0ea1bc7eb2d0f4e66a038ae581a9 +Subproject commit cc6a5b5aa79fddb0a03715a503bae6f78add721c diff --git a/tests/travis.sh b/tests/travis.sh index d975014a15..6cfeac161b 100755 --- a/tests/travis.sh +++ b/tests/travis.sh @@ -36,7 +36,7 @@ cd tests/plugins/PocketMine-DevTools "$PHP_BINARY" -dphar.readonly=0 ./src/DevTools/ConsoleScript.php --make ./ --relative ./ --out ../../../DevTools.phar cd ../../.. -"$PHP_BINARY" -dphar.readonly=0 DevTools.phar --make src,vendor --relative ./ --entry src/pocketmine/PocketMine.php --out PocketMine-MP.phar +"$PHP_BINARY" -dphar.readonly=0 DevTools.phar --make src,vendor,resources --relative ./ --entry src/pocketmine/PocketMine.php --out PocketMine-MP.phar if [ -f PocketMine-MP.phar ]; then echo Server phar created successfully. else From c201a0e909d9e8212657c7b072d6c620895e3013 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 5 Nov 2018 09:49:21 +0000 Subject: [PATCH 0279/3224] Move language submodule to resources/ again, this isn't source code. --- .gitmodules | 2 +- {src/pocketmine/lang => resources}/locale | 0 src/pocketmine/lang/Language.php | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) rename {src/pocketmine/lang => resources}/locale (100%) diff --git a/.gitmodules b/.gitmodules index 21adfef04b..ffdd6fb4f1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,5 +1,5 @@ [submodule "src/pocketmine/lang/locale"] - path = src/pocketmine/lang/locale + path = resources/locale url = https://github.com/pmmp/PocketMine-Language.git [submodule "tests/preprocessor"] path = tests/preprocessor diff --git a/src/pocketmine/lang/locale b/resources/locale similarity index 100% rename from src/pocketmine/lang/locale rename to resources/locale diff --git a/src/pocketmine/lang/Language.php b/src/pocketmine/lang/Language.php index cdcd02905b..2774641487 100644 --- a/src/pocketmine/lang/Language.php +++ b/src/pocketmine/lang/Language.php @@ -35,7 +35,7 @@ class Language{ */ public static function getLanguageList(string $path = "") : array{ if($path === ""){ - $path = \pocketmine\PATH . "src/pocketmine/lang/locale/"; + $path = \pocketmine\RESOURCE_PATH . "locale/"; } if(is_dir($path)){ @@ -82,7 +82,7 @@ class Language{ $this->langName = strtolower($lang); if($path === null){ - $path = \pocketmine\PATH . "src/pocketmine/lang/locale/"; + $path = \pocketmine\RESOURCE_PATH . "locale/"; } $this->lang = self::loadLang($path, $this->langName); From ed8569a3f4da1c457442db873eff85402a2a5e7a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 5 Nov 2018 17:26:22 +0000 Subject: [PATCH 0280/3224] Remove Collectable class, fix memory leak on AsyncTask fatal error --- src/pocketmine/Collectable.php | 37 -------------------------- src/pocketmine/scheduler/AsyncPool.php | 2 +- src/pocketmine/scheduler/AsyncTask.php | 24 ++++++++++++----- 3 files changed, 18 insertions(+), 45 deletions(-) delete mode 100644 src/pocketmine/Collectable.php diff --git a/src/pocketmine/Collectable.php b/src/pocketmine/Collectable.php deleted file mode 100644 index 4dde44cb50..0000000000 --- a/src/pocketmine/Collectable.php +++ /dev/null @@ -1,37 +0,0 @@ -isGarbage; - } - - public function setGarbage(){ - $this->isGarbage = true; - } -} diff --git a/src/pocketmine/scheduler/AsyncPool.php b/src/pocketmine/scheduler/AsyncPool.php index cd8df7ea19..efbb0b5b06 100644 --- a/src/pocketmine/scheduler/AsyncPool.php +++ b/src/pocketmine/scheduler/AsyncPool.php @@ -219,7 +219,7 @@ class AsyncPool{ /** @var AsyncTask $task */ $task = $queue->bottom(); $task->checkProgressUpdates(); - if(!$task->isRunning() and $task->isGarbage()){ //make sure the task actually executed before trying to collect + if($task->isFinished()){ //make sure the task actually executed before trying to collect $doGC = true; $queue->dequeue(); diff --git a/src/pocketmine/scheduler/AsyncTask.php b/src/pocketmine/scheduler/AsyncTask.php index b6e927b6dd..3812074935 100644 --- a/src/pocketmine/scheduler/AsyncTask.php +++ b/src/pocketmine/scheduler/AsyncTask.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\scheduler; -use pocketmine\Collectable; - /** * Class used to run async tasks in other threads. * @@ -42,7 +40,7 @@ use pocketmine\Collectable; * * WARNING: Do not call PocketMine-MP API methods from other Threads!! */ -abstract class AsyncTask extends Collectable{ +abstract class AsyncTask extends \Threaded{ /** * @var \ArrayObject|mixed[] object hash => mixed data * @@ -63,6 +61,8 @@ abstract class AsyncTask extends Collectable{ private $submitted = false; private $crashed = false; + /** @var bool */ + private $finished = false; public function run() : void{ $this->result = null; @@ -76,13 +76,23 @@ abstract class AsyncTask extends Collectable{ } } - $this->setGarbage(); + $this->finished = true; } public function isCrashed() : bool{ return $this->crashed or $this->isTerminated(); } + /** + * Returns whether this task has finished executing, whether successfully or not. This differs from isRunning() + * because it is not true prior to task execution. + * + * @return bool + */ + public function isFinished() : bool{ + return $this->finished or $this->isCrashed(); + } + /** * @return mixed */ @@ -131,7 +141,7 @@ abstract class AsyncTask extends Collectable{ * @return mixed */ public function getFromThreadStore(string $identifier){ - if($this->worker === null or $this->isGarbage()){ + if($this->worker === null or $this->isFinished()){ throw new \BadMethodCallException("Objects stored in AsyncWorker thread-local storage can only be retrieved during task execution"); } return $this->worker->getFromThreadStore($identifier); @@ -144,7 +154,7 @@ abstract class AsyncTask extends Collectable{ * @param mixed $value */ public function saveToThreadStore(string $identifier, $value) : void{ - if($this->worker === null or $this->isGarbage()){ + if($this->worker === null or $this->isFinished()){ throw new \BadMethodCallException("Objects can only be added to AsyncWorker thread-local storage during task execution"); } $this->worker->saveToThreadStore($identifier, $value); @@ -156,7 +166,7 @@ abstract class AsyncTask extends Collectable{ * @param string $identifier */ public function removeFromThreadStore(string $identifier) : void{ - if($this->worker === null or $this->isGarbage()){ + if($this->worker === null or $this->isFinished()){ throw new \BadMethodCallException("Objects can only be removed from AsyncWorker thread-local storage during task execution"); } $this->worker->removeFromThreadStore($identifier); From 67a5f3f5572a8058f3e1804273ecf21c6ea068c4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 5 Nov 2018 19:01:59 +0000 Subject: [PATCH 0281/3224] Register MainLogger as SPL global, remove hard MainLogger dependency from many areas, break a bunch of cyclic dependencies --- src/pocketmine/PocketMine.php | 8 +- src/pocketmine/ThreadManager.php | 4 +- src/pocketmine/level/Position.php | 3 +- .../format/io/region/RegionLevelProvider.php | 3 +- .../level/format/io/region/RegionLoader.php | 3 +- .../network/mcpe/protocol/LoginPacket.php | 3 +- src/pocketmine/permission/BanList.php | 7 +- src/pocketmine/utils/Config.php | 2 +- src/pocketmine/utils/Timezone.php | 81 +++++++++---------- src/pocketmine/utils/Utils.php | 5 +- .../src/pmmp/TesterPlugin/Main.php | 1 - .../tests/AsyncTaskMainLoggerTest.php | 68 ---------------- 12 files changed, 52 insertions(+), 136 deletions(-) delete mode 100644 tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMainLoggerTest.php diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index 9023c2e193..dabc0c8356 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -193,15 +193,11 @@ namespace pocketmine { } //Logger has a dependency on timezone - $tzError = Timezone::init(); + Timezone::init(); $logger = new MainLogger(\pocketmine\DATA . "server.log"); $logger->registerStatic(); - - foreach($tzError as $e){ - $logger->warning($e); - } - unset($tzError); + \GlobalLogger::set($logger); if(extension_loaded("xdebug")){ $logger->warning(PHP_EOL . PHP_EOL . PHP_EOL . "\tYou are running " . \pocketmine\NAME . " with xdebug enabled. This has a major impact on performance." . PHP_EOL . PHP_EOL); diff --git a/src/pocketmine/ThreadManager.php b/src/pocketmine/ThreadManager.php index 0691a3b89d..980515eda7 100644 --- a/src/pocketmine/ThreadManager.php +++ b/src/pocketmine/ThreadManager.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine; -use pocketmine\utils\MainLogger; - class ThreadManager extends \Volatile{ /** @var ThreadManager */ @@ -72,7 +70,7 @@ class ThreadManager extends \Volatile{ } public function stopAll() : int{ - $logger = MainLogger::getLogger(); + $logger = \GlobalLogger::get(); $erroredThreads = 0; diff --git a/src/pocketmine/level/Position.php b/src/pocketmine/level/Position.php index b2e31bb4c9..a693ccda57 100644 --- a/src/pocketmine/level/Position.php +++ b/src/pocketmine/level/Position.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\level; use pocketmine\math\Vector3; -use pocketmine\utils\MainLogger; class Position extends Vector3{ @@ -63,7 +62,7 @@ class Position extends Vector3{ */ public function getLevel(){ if($this->level !== null and $this->level->isClosed()){ - MainLogger::getLogger()->debug("Position was holding a reference to an unloaded Level"); + \GlobalLogger::get()->debug("Position was holding a reference to an unloaded Level"); $this->level = null; } diff --git a/src/pocketmine/level/format/io/region/RegionLevelProvider.php b/src/pocketmine/level/format/io/region/RegionLevelProvider.php index 6c9e637f5e..8e58ce2f5e 100644 --- a/src/pocketmine/level/format/io/region/RegionLevelProvider.php +++ b/src/pocketmine/level/format/io/region/RegionLevelProvider.php @@ -28,7 +28,6 @@ use pocketmine\level\format\io\BaseLevelProvider; use pocketmine\level\format\io\data\JavaLevelData; use pocketmine\level\format\io\LevelData; use pocketmine\level\Level; -use pocketmine\utils\MainLogger; abstract class RegionLevelProvider extends BaseLevelProvider{ @@ -131,7 +130,7 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ try{ $region->open(); }catch(CorruptedRegionException $e){ - $logger = MainLogger::getLogger(); + $logger = \GlobalLogger::get(); $logger->error("Corrupted region file detected: " . $e->getMessage()); $region->close(false); //Do not write anything to the file diff --git a/src/pocketmine/level/format/io/region/RegionLoader.php b/src/pocketmine/level/format/io/region/RegionLoader.php index 1412f759d8..08b680a183 100644 --- a/src/pocketmine/level/format/io/region/RegionLoader.php +++ b/src/pocketmine/level/format/io/region/RegionLoader.php @@ -26,7 +26,6 @@ namespace pocketmine\level\format\io\region; use pocketmine\level\format\ChunkException; use pocketmine\level\format\io\exception\CorruptedChunkException; use pocketmine\utils\Binary; -use pocketmine\utils\MainLogger; class RegionLoader{ public const COMPRESSION_GZIP = 1; @@ -117,7 +116,7 @@ class RegionLoader{ } if($length > ($this->locationTable[$index][1] << 12)){ //Invalid chunk, bigger than defined number of sectors - MainLogger::getLogger()->error("Corrupted bigger chunk detected (bigger than number of sectors given in header)"); + \GlobalLogger::get()->error("Corrupted bigger chunk detected (bigger than number of sectors given in header)"); $this->locationTable[$index][1] = $length >> 12; $this->writeLocationIndex($index); }elseif($compression !== self::COMPRESSION_ZLIB and $compression !== self::COMPRESSION_GZIP){ diff --git a/src/pocketmine/network/mcpe/protocol/LoginPacket.php b/src/pocketmine/network/mcpe/protocol/LoginPacket.php index a2f7f2c7c5..3a801b8e97 100644 --- a/src/pocketmine/network/mcpe/protocol/LoginPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LoginPacket.php @@ -29,7 +29,6 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\entity\Skin; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\utils\BinaryStream; -use pocketmine\utils\MainLogger; use pocketmine\utils\Utils; class LoginPacket extends DataPacket{ @@ -89,7 +88,7 @@ class LoginPacket extends DataPacket{ throw $e; } - $logger = MainLogger::getLogger(); + $logger = \GlobalLogger::get(); $logger->debug(get_class($e) . " was thrown while decoding connection request in login (protocol version " . ($this->protocol ?? "unknown") . "): " . $e->getMessage()); foreach(Utils::getTrace(0, $e->getTrace()) as $line){ $logger->debug($line); diff --git a/src/pocketmine/permission/BanList.php b/src/pocketmine/permission/BanList.php index 7970f88484..681dc23d56 100644 --- a/src/pocketmine/permission/BanList.php +++ b/src/pocketmine/permission/BanList.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\permission; use pocketmine\Server; -use pocketmine\utils\MainLogger; class BanList{ @@ -153,7 +152,7 @@ class BanList{ $this->list[$entry->getName()] = $entry; } }catch(\Throwable $e){ - $logger = MainLogger::getLogger(); + $logger = \GlobalLogger::get(); $logger->critical("Failed to parse ban entry from string \"$line\": " . $e->getMessage()); $logger->logException($e); } @@ -161,7 +160,7 @@ class BanList{ } fclose($fp); }else{ - MainLogger::getLogger()->error("Could not load ban list"); + \GlobalLogger::get()->error("Could not load ban list"); } } @@ -182,7 +181,7 @@ class BanList{ } fclose($fp); }else{ - MainLogger::getLogger()->error("Could not save ban list"); + \GlobalLogger::get()->error("Could not save ban list"); } } } diff --git a/src/pocketmine/utils/Config.php b/src/pocketmine/utils/Config.php index e09c86cfbf..353ca1e436 100644 --- a/src/pocketmine/utils/Config.php +++ b/src/pocketmine/utils/Config.php @@ -525,7 +525,7 @@ class Config{ break; } if(isset($this->config[$k])){ - MainLogger::getLogger()->debug("[Config] Repeated property " . $k . " on file " . $this->file); + \GlobalLogger::get()->debug("[Config] Repeated property " . $k . " on file " . $this->file); } $this->config[$k] = $v; } diff --git a/src/pocketmine/utils/Timezone.php b/src/pocketmine/utils/Timezone.php index 1138f66a7a..a1169ddfa7 100644 --- a/src/pocketmine/utils/Timezone.php +++ b/src/pocketmine/utils/Timezone.php @@ -29,54 +29,49 @@ abstract class Timezone{ return ini_get('date.timezone'); } - public static function init() : array{ - $messages = []; - do{ - $timezone = ini_get("date.timezone"); - if($timezone !== ""){ - /* - * This is here so that people don't come to us complaining and fill up the issue tracker when they put - * an incorrect timezone abbreviation in php.ini apparently. - */ - if(strpos($timezone, "/") === false){ - $default_timezone = timezone_name_from_abbr($timezone); - if($default_timezone !== false){ - ini_set("date.timezone", $default_timezone); - date_default_timezone_set($default_timezone); - break; - }else{ - //Bad php.ini value, try another method to detect timezone - $messages[] = "Timezone \"$timezone\" could not be parsed as a valid timezone from php.ini, falling back to auto-detection"; - } - }else{ - date_default_timezone_set($timezone); - break; + public static function init() : void{ + $timezone = ini_get("date.timezone"); + if($timezone !== ""){ + /* + * This is here so that people don't come to us complaining and fill up the issue tracker when they put + * an incorrect timezone abbreviation in php.ini apparently. + */ + if(strpos($timezone, "/") === false){ + $default_timezone = timezone_name_from_abbr($timezone); + if($default_timezone !== false){ + ini_set("date.timezone", $default_timezone); + date_default_timezone_set($default_timezone); + return; } + + //Bad php.ini value, try another method to detect timezone + \GlobalLogger::get()->warning("Timezone \"$timezone\" could not be parsed as a valid timezone from php.ini, falling back to auto-detection"); + }else{ + date_default_timezone_set($timezone); + return; } + } - if(($timezone = self::detectSystemTimezone()) and date_default_timezone_set($timezone)){ - //Success! Timezone has already been set and validated in the if statement. - //This here is just for redundancy just in case some program wants to read timezone data from the ini. - ini_set("date.timezone", $timezone); - break; - } + if(($timezone = self::detectSystemTimezone()) and date_default_timezone_set($timezone)){ + //Success! Timezone has already been set and validated in the if statement. + //This here is just for redundancy just in case some program wants to read timezone data from the ini. + ini_set("date.timezone", $timezone); + return; + } - if($response = Internet::getURL("http://ip-api.com/json") //If system timezone detection fails or timezone is an invalid value. - and $ip_geolocation_data = json_decode($response, true) - and $ip_geolocation_data['status'] !== 'fail' - and date_default_timezone_set($ip_geolocation_data['timezone']) - ){ - //Again, for redundancy. - ini_set("date.timezone", $ip_geolocation_data['timezone']); - break; - } + if($response = Internet::getURL("http://ip-api.com/json") //If system timezone detection fails or timezone is an invalid value. + and $ip_geolocation_data = json_decode($response, true) + and $ip_geolocation_data['status'] !== 'fail' + and date_default_timezone_set($ip_geolocation_data['timezone']) + ){ + //Again, for redundancy. + ini_set("date.timezone", $ip_geolocation_data['timezone']); + return; + } - ini_set("date.timezone", "UTC"); - date_default_timezone_set("UTC"); - $messages[] = "Timezone could not be automatically determined or was set to an invalid value. An incorrect timezone will result in incorrect timestamps on console logs. It has been set to \"UTC\" by default. You can change it on the php.ini file."; - }while(false); - - return $messages; + ini_set("date.timezone", "UTC"); + date_default_timezone_set("UTC"); + \GlobalLogger::get()->warning("Timezone could not be automatically determined or was set to an invalid value. An incorrect timezone will result in incorrect timestamps on console logs. It has been set to \"UTC\" by default. You can change it on the php.ini file."); } public static function detectSystemTimezone(){ diff --git a/src/pocketmine/utils/Utils.php b/src/pocketmine/utils/Utils.php index 33e409a904..f2eeeb26cf 100644 --- a/src/pocketmine/utils/Utils.php +++ b/src/pocketmine/utils/Utils.php @@ -407,8 +407,9 @@ class Utils{ } public static function kill($pid) : void{ - if(MainLogger::isRegisteredStatic()){ - MainLogger::getLogger()->syncFlushBuffer(); + $logger = \GlobalLogger::get(); + if($logger instanceof MainLogger){ + $logger->syncFlushBuffer(); } switch(Utils::getOS()){ case "win": diff --git a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/Main.php b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/Main.php index c008b14980..7b40795b82 100644 --- a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/Main.php +++ b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/Main.php @@ -44,7 +44,6 @@ class Main extends PluginBase implements Listener{ $this->waitingTests = [ new tests\AsyncTaskMemoryLeakTest($this), - new tests\AsyncTaskMainLoggerTest($this), new tests\AsyncTaskPublishProgressRaceTest($this) ]; } diff --git a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMainLoggerTest.php b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMainLoggerTest.php deleted file mode 100644 index 4972ec2866..0000000000 --- a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMainLoggerTest.php +++ /dev/null @@ -1,68 +0,0 @@ -getPlugin()->getServer()->getAsyncPool()->submitTask(new class($this) extends AsyncTask{ - - /** @var bool */ - protected $success = false; - - public function __construct(AsyncTaskMainLoggerTest $testObject){ - $this->storeLocal($testObject); - } - - public function onRun() : void{ - ob_start(); - MainLogger::getLogger()->info("Testing"); - if(strpos(ob_get_contents(), "Testing") !== false){ - $this->success = true; - } - ob_end_flush(); - } - - public function onCompletion() : void{ - /** @var AsyncTaskMainLoggerTest $test */ - $test = $this->fetchLocal(); - $test->setResult($this->success ? Test::RESULT_OK : Test::RESULT_FAILED); - } - }); - } - - public function getName() : string{ - return "MainLogger::getLogger() works in AsyncTasks"; - } - - public function getDescription() : string{ - return "Verifies that the MainLogger is accessible by MainLogger::getLogger() in an AsyncTask"; - } - - -} From 0b03e3c95be45a1a83e0608ec937c4df7bb164a7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 5 Nov 2018 21:20:42 +0000 Subject: [PATCH 0282/3224] Update dependencies, fix travis failure --- composer.json | 4 ++-- composer.lock | 28 +++++++++++++++------------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/composer.json b/composer.json index 3379374fe0..3056ffa823 100644 --- a/composer.json +++ b/composer.json @@ -27,8 +27,8 @@ "ext-zip": "*", "ext-zlib": ">=1.2.11", "mdanter/ecc": "^0.5.0", - "pocketmine/raklib": "^0.12.0", - "pocketmine/spl": "^0.3.0", + "pocketmine/raklib": "dev-master", + "pocketmine/spl": "dev-master", "pocketmine/binaryutils": "^0.1.0", "pocketmine/nbt": "dev-master", "pocketmine/math": "dev-master", diff --git a/composer.lock b/composer.lock index 458b80b1de..72dd12b7ac 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "28f054aefede2c0dc4f220d5c4a918a0", + "content-hash": "d6cbb4a2c58dae0906bf9c13ef4a1f2c", "packages": [ { "name": "fgrosse/phpasn1", @@ -262,16 +262,16 @@ }, { "name": "pocketmine/raklib", - "version": "0.12.0", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "922da28efd828e2af6c19db1676ea9b6a267071c" + "reference": "a92e0508b13386e938a8092201ddfd3da17b8dd0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/922da28efd828e2af6c19db1676ea9b6a267071c", - "reference": "922da28efd828e2af6c19db1676ea9b6a267071c", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/a92e0508b13386e938a8092201ddfd3da17b8dd0", + "reference": "a92e0508b13386e938a8092201ddfd3da17b8dd0", "shasum": "" }, "require": { @@ -283,7 +283,7 @@ "php-ipv6": "*", "pocketmine/binaryutils": "^0.1.0", "pocketmine/snooze": "^0.1.0", - "pocketmine/spl": "^0.3.0" + "pocketmine/spl": "dev-master" }, "type": "library", "autoload": { @@ -296,10 +296,10 @@ ], "description": "A RakNet server implementation written in PHP", "support": { - "source": "https://github.com/pmmp/RakLib/tree/0.12.0", + "source": "https://github.com/pmmp/RakLib/tree/master", "issues": "https://github.com/pmmp/RakLib/issues" }, - "time": "2018-06-13T10:06:14+00:00" + "time": "2018-11-05T21:18:34+00:00" }, { "name": "pocketmine/snooze", @@ -337,16 +337,16 @@ }, { "name": "pocketmine/spl", - "version": "0.3.2", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/pmmp/SPL.git", - "reference": "7fd53857cd000491ba69e8db865792a024dd2c49" + "reference": "985e212ac528412ec00ddd3b88c5fc11549a2fe0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/SPL/zipball/7fd53857cd000491ba69e8db865792a024dd2c49", - "reference": "7fd53857cd000491ba69e8db865792a024dd2c49", + "url": "https://api.github.com/repos/pmmp/SPL/zipball/985e212ac528412ec00ddd3b88c5fc11549a2fe0", + "reference": "985e212ac528412ec00ddd3b88c5fc11549a2fe0", "shasum": "" }, "type": "library", @@ -365,7 +365,7 @@ "support": { "source": "https://github.com/pmmp/SPL/tree/master" }, - "time": "2018-08-12T15:17:39+00:00" + "time": "2018-10-21T17:32:00+00:00" } ], "packages-dev": [], @@ -373,6 +373,8 @@ "minimum-stability": "stable", "stability-flags": { "ext-pthreads": 20, + "pocketmine/raklib": 20, + "pocketmine/spl": 20, "pocketmine/nbt": 20, "pocketmine/math": 20 }, From 3a6af3327f65e8e2f87c2cbf9f9e38b8f355fb33 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 9 Nov 2018 19:50:52 +0000 Subject: [PATCH 0283/3224] Encapsulate plugin.yml commands handling inside PluginBase, removed CommandExecutor requirement from Plugin interface This removes the need for custom Plugin implementations to implement onCommand(). In the future it's planned to remove plugin.yml commands completely and have them registered similarly to how events are handled. --- src/pocketmine/Server.php | 2 +- src/pocketmine/plugin/Plugin.php | 3 +- src/pocketmine/plugin/PluginBase.php | 63 +++++++++++++++++++- src/pocketmine/plugin/PluginManager.php | 76 +------------------------ 4 files changed, 67 insertions(+), 77 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 379b150d27..af6979a525 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1644,7 +1644,7 @@ class Server{ $this->resourceManager = new ResourcePackManager($this->getDataPath() . "resource_packs" . DIRECTORY_SEPARATOR, $this->logger); - $this->pluginManager = new PluginManager($this, $this->commandMap, ((bool) $this->getProperty("plugins.legacy-data-dir", true)) ? null : $this->getDataPath() . "plugin_data" . DIRECTORY_SEPARATOR); + $this->pluginManager = new PluginManager($this, ((bool) $this->getProperty("plugins.legacy-data-dir", true)) ? null : $this->getDataPath() . "plugin_data" . DIRECTORY_SEPARATOR); $this->profilingTickRate = (float) $this->getProperty("settings.profile-report-trigger", 20); $this->pluginManager->registerInterface(new PharPluginLoader($this->autoloader)); $this->pluginManager->registerInterface(new ScriptPluginLoader()); diff --git a/src/pocketmine/plugin/Plugin.php b/src/pocketmine/plugin/Plugin.php index 1a6146a6bb..9a33b4920d 100644 --- a/src/pocketmine/plugin/Plugin.php +++ b/src/pocketmine/plugin/Plugin.php @@ -26,14 +26,13 @@ declare(strict_types=1); */ namespace pocketmine\plugin; -use pocketmine\command\CommandExecutor; use pocketmine\scheduler\TaskScheduler; use pocketmine\Server; /** * It is recommended to use PluginBase for the actual plugin */ -interface Plugin extends CommandExecutor{ +interface Plugin{ public function __construct(PluginLoader $loader, Server $server, PluginDescription $description, string $dataFolder, string $file); diff --git a/src/pocketmine/plugin/PluginBase.php b/src/pocketmine/plugin/PluginBase.php index 102d98ed40..21f91cfa83 100644 --- a/src/pocketmine/plugin/PluginBase.php +++ b/src/pocketmine/plugin/PluginBase.php @@ -24,13 +24,15 @@ declare(strict_types=1); namespace pocketmine\plugin; use pocketmine\command\Command; +use pocketmine\command\CommandExecutor; use pocketmine\command\CommandSender; +use pocketmine\command\PluginCommand; use pocketmine\command\PluginIdentifiableCommand; use pocketmine\scheduler\TaskScheduler; use pocketmine\Server; use pocketmine\utils\Config; -abstract class PluginBase implements Plugin{ +abstract class PluginBase implements Plugin, CommandExecutor{ /** @var PluginLoader */ private $loader; @@ -70,6 +72,8 @@ abstract class PluginBase implements Plugin{ $this->scheduler = new TaskScheduler($this->getFullName()); $this->onLoad(); + + $this->registerYamlCommands(); } /** @@ -143,6 +147,63 @@ abstract class PluginBase implements Plugin{ return $this->logger; } + /** + * Registers commands declared in the plugin manifest + */ + private function registerYamlCommands() : void{ + $pluginCmds = []; + + foreach($this->getDescription()->getCommands() as $key => $data){ + if(strpos($key, ":") !== false){ + $this->logger->error($this->server->getLanguage()->translateString("pocketmine.plugin.commandError", [$key, $this->getDescription()->getFullName()])); + continue; + } + if(is_array($data)){ //TODO: error out if it isn't + $newCmd = new PluginCommand($key, $this); + if(isset($data["description"])){ + $newCmd->setDescription($data["description"]); + } + + if(isset($data["usage"])){ + $newCmd->setUsage($data["usage"]); + } + + if(isset($data["aliases"]) and is_array($data["aliases"])){ + $aliasList = []; + foreach($data["aliases"] as $alias){ + if(strpos($alias, ":") !== false){ + $this->logger->error($this->server->getLanguage()->translateString("pocketmine.plugin.aliasError", [$alias, $this->getDescription()->getFullName()])); + continue; + } + $aliasList[] = $alias; + } + + $newCmd->setAliases($aliasList); + } + + if(isset($data["permission"])){ + if(is_bool($data["permission"])){ + $newCmd->setPermission($data["permission"] ? "true" : "false"); + }elseif(is_string($data["permission"])){ + $newCmd->setPermission($data["permission"]); + }else{ + $this->logger->error("Permission must be a string, " . gettype($data["permission"]) . " given for command $key"); + } + } + + if(isset($data["permission-message"])){ + $newCmd->setPermissionMessage($data["permission-message"]); + } + + $pluginCmds[] = $newCmd; + } + } + + if(count($pluginCmds) > 0){ + $this->server->getCommandMap()->registerAll($this->getDescription()->getName(), $pluginCmds); + } + } + /** * @param string $name * diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index e31cb0889d..d7fe182016 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\plugin; -use pocketmine\command\PluginCommand; -use pocketmine\command\SimpleCommandMap; use pocketmine\event\Event; use pocketmine\event\EventPriority; use pocketmine\event\HandlerList; @@ -45,9 +43,6 @@ class PluginManager{ /** @var Server */ private $server; - /** @var SimpleCommandMap */ - private $commandMap; - /** * @var Plugin[] */ @@ -67,13 +62,11 @@ class PluginManager{ private $pluginDataDirectory; /** - * @param Server $server - * @param SimpleCommandMap $commandMap - * @param null|string $pluginDataDirectory + * @param Server $server + * @param null|string $pluginDataDirectory */ - public function __construct(Server $server, SimpleCommandMap $commandMap, ?string $pluginDataDirectory){ + public function __construct(Server $server, ?string $pluginDataDirectory){ $this->server = $server; - $this->commandMap = $commandMap; $this->pluginDataDirectory = $pluginDataDirectory; if($this->pluginDataDirectory !== null){ if(!file_exists($this->pluginDataDirectory)){ @@ -167,12 +160,6 @@ class PluginManager{ $plugin = new $mainClass($loader, $this->server, $description, $dataFolder, $prefixed); $this->plugins[$plugin->getDescription()->getName()] = $plugin; - $pluginCommands = $this->parseYamlCommands($plugin); - - if(count($pluginCommands) > 0){ - $this->commandMap->registerAll($plugin->getDescription()->getName(), $pluginCommands); - } - return $plugin; }catch(\Throwable $e){ $this->server->getLogger()->logException($e); @@ -425,63 +412,6 @@ class PluginManager{ } } - /** - * @param Plugin $plugin - * - * @return PluginCommand[] - */ - protected function parseYamlCommands(Plugin $plugin) : array{ - $pluginCmds = []; - - foreach($plugin->getDescription()->getCommands() as $key => $data){ - if(strpos($key, ":") !== false){ - $this->server->getLogger()->critical($this->server->getLanguage()->translateString("pocketmine.plugin.commandError", [$key, $plugin->getDescription()->getFullName()])); - continue; - } - if(is_array($data)){ - $newCmd = new PluginCommand($key, $plugin); - if(isset($data["description"])){ - $newCmd->setDescription($data["description"]); - } - - if(isset($data["usage"])){ - $newCmd->setUsage($data["usage"]); - } - - if(isset($data["aliases"]) and is_array($data["aliases"])){ - $aliasList = []; - foreach($data["aliases"] as $alias){ - if(strpos($alias, ":") !== false){ - $this->server->getLogger()->critical($this->server->getLanguage()->translateString("pocketmine.plugin.aliasError", [$alias, $plugin->getDescription()->getFullName()])); - continue; - } - $aliasList[] = $alias; - } - - $newCmd->setAliases($aliasList); - } - - if(isset($data["permission"])){ - if(is_bool($data["permission"])){ - $newCmd->setPermission($data["permission"] ? "true" : "false"); - }elseif(is_string($data["permission"])){ - $newCmd->setPermission($data["permission"]); - }else{ - throw new \InvalidArgumentException("Permission must be a string or boolean, " . gettype($data["permission"]) . " given"); - } - } - - if(isset($data["permission-message"])){ - $newCmd->setPermissionMessage($data["permission-message"]); - } - - $pluginCmds[] = $newCmd; - } - } - - return $pluginCmds; - } - public function disablePlugins(){ foreach($this->getPlugins() as $plugin){ $this->disablePlugin($plugin); From 3c86944a7ca0407596665af7a62bcb457cc25781 Mon Sep 17 00:00:00 2001 From: Twisted Date: Tue, 13 Nov 2018 16:48:13 +0000 Subject: [PATCH 0284/3224] Item: make addEnchantment(), removeEnchantment() and removeEnchantments() fluent (#2523) --- src/pocketmine/item/Item.php | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index eb6f564278..e3e30d5378 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -286,11 +286,13 @@ class Item implements ItemIds, \JsonSerializable{ /** * @param int $id * @param int $level + * + * @return Item */ - public function removeEnchantment(int $id, int $level = -1) : void{ + public function removeEnchantment(int $id, int $level = -1) : Item{ $ench = $this->getNamedTagEntry(self::TAG_ENCH); if(!($ench instanceof ListTag)){ - return; + return $this; } /** @var CompoundTag $entry */ @@ -302,16 +304,25 @@ class Item implements ItemIds, \JsonSerializable{ } $this->setNamedTagEntry($ench); + + return $this; } - public function removeEnchantments() : void{ + /** + * @return Item + */ + public function removeEnchantments() : Item{ $this->removeNamedTagEntry(self::TAG_ENCH); + + return $this; } /** * @param EnchantmentInstance $enchantment + * + * @return Item */ - public function addEnchantment(EnchantmentInstance $enchantment) : void{ + public function addEnchantment(EnchantmentInstance $enchantment) : Item{ $found = false; $ench = $this->getNamedTagEntry(self::TAG_ENCH); @@ -339,6 +350,8 @@ class Item implements ItemIds, \JsonSerializable{ } $this->setNamedTagEntry($ench); + + return $this; } /** From 5d7feaaf2118c4474945ca6ccf90f594d6ff5510 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Tue, 13 Nov 2018 21:04:47 +0000 Subject: [PATCH 0285/3224] Remove EventExecutor, event handlers now use closures (#2525) This cleans up some cargo-cult code poorly copied from Bukkit, which has negative performance effects and also makes internal event handling more complex than necessary. ## API changes - Removed `EventExecutor` and `MethodEventExecutor`. - A listener is no longer required for an event handler to be registered. Closure objects can now be used directly provided that they meet the conditions for registration. - `PluginManager->registerEvent()` signature has changed: the `Listener` and `EventExecutor` parameters have been removed and a `\Closure $handler` has been added in its place. - `RegisteredListener` now requires a `Closure` parameter instead of `Listener, EventExecutor`. ## Behavioural changes These changes reduce the execution complexity involved with calling an event handler. Since event calls can happen in hot paths, this may have visible positive effects on performance. Initial testing reveals a performance improvement of ~15% per event handler call compared to the old method. --- src/pocketmine/event/HandlerList.php | 2 +- src/pocketmine/plugin/EventExecutor.php | 38 ---------------- src/pocketmine/plugin/MethodEventExecutor.php | 44 ------------------- src/pocketmine/plugin/PluginManager.php | 27 ++++++------ src/pocketmine/plugin/RegisteredListener.php | 25 ++++------- 5 files changed, 23 insertions(+), 113 deletions(-) delete mode 100644 src/pocketmine/plugin/EventExecutor.php delete mode 100644 src/pocketmine/plugin/MethodEventExecutor.php diff --git a/src/pocketmine/event/HandlerList.php b/src/pocketmine/event/HandlerList.php index 9b27787057..833f0bb2a7 100644 --- a/src/pocketmine/event/HandlerList.php +++ b/src/pocketmine/event/HandlerList.php @@ -140,7 +140,7 @@ class HandlerList{ foreach($this->handlerSlots as $priority => $list){ foreach($list as $hash => $listener){ if(($object instanceof Plugin and $listener->getPlugin() === $object) - or ($object instanceof Listener and $listener->getListener() === $object) + or ($object instanceof Listener and (new \ReflectionFunction($listener->getHandler()))->getClosureThis() === $object) //this doesn't even need to be a listener :D ){ unset($this->handlerSlots[$priority][$hash]); } diff --git a/src/pocketmine/plugin/EventExecutor.php b/src/pocketmine/plugin/EventExecutor.php deleted file mode 100644 index f7697a3009..0000000000 --- a/src/pocketmine/plugin/EventExecutor.php +++ /dev/null @@ -1,38 +0,0 @@ -method = $method; - } - - public function execute(Listener $listener, Event $event){ - $listener->{$this->getMethod()}($event); - } - - public function getMethod(){ - return $this->method; - } -} diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index 767bc71343..66a8dbce29 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -519,43 +519,44 @@ class PluginManager{ } } - $this->registerEvent($eventClass->getName(), $listener, $priority, new MethodEventExecutor($method->getName()), $plugin, $ignoreCancelled); + $this->registerEvent($eventClass->getName(), $handlerClosure, $priority, $plugin, $ignoreCancelled); } } } /** - * @param string $event Class name that extends Event - * @param Listener $listener - * @param int $priority - * @param EventExecutor $executor - * @param Plugin $plugin - * @param bool $ignoreCancelled + * @param string $event Class name that extends Event + * @param \Closure $handler + * @param int $priority + * @param Plugin $plugin + * @param bool $ignoreCancelled * - * @throws PluginException + * @throws \ReflectionException */ - public function registerEvent(string $event, Listener $listener, int $priority, EventExecutor $executor, Plugin $plugin, bool $ignoreCancelled = false) : void{ + public function registerEvent(string $event, \Closure $handler, int $priority, Plugin $plugin, bool $ignoreCancelled = false) : void{ if(!is_subclass_of($event, Event::class)){ throw new PluginException($event . " is not an Event"); } + $handlerName = Utils::getNiceClosureName($handler); + $tags = Utils::parseDocComment((string) (new \ReflectionClass($event))->getDocComment()); if(isset($tags["deprecated"]) and $this->server->getProperty("settings.deprecated-verbose", true)){ $this->server->getLogger()->warning($this->server->getLanguage()->translateString("pocketmine.plugin.deprecatedEvent", [ $plugin->getName(), $event, - get_class($listener) . "->" . ($executor instanceof MethodEventExecutor ? $executor->getMethod() : "") + $handlerName ])); } if(!$plugin->isEnabled()){ - throw new PluginException("Plugin attempted to register " . $event . " while not enabled"); + throw new PluginException("Plugin attempted to register event handler " . $handlerName . "() to event " . $event . " while not enabled"); } - $timings = new TimingsHandler("Plugin: " . $plugin->getDescription()->getFullName() . " Event: " . get_class($listener) . "::" . ($executor instanceof MethodEventExecutor ? $executor->getMethod() : "???") . "(" . (new \ReflectionClass($event))->getShortName() . ")"); + $timings = new TimingsHandler("Plugin: " . $plugin->getDescription()->getFullName() . " Event: " . $handlerName . "(" . (new \ReflectionClass($event))->getShortName() . ")"); - $this->getEventListeners($event)->register(new RegisteredListener($listener, $executor, $priority, $plugin, $ignoreCancelled, $timings)); + $this->getEventListeners($event)->register(new RegisteredListener($handler, $priority, $plugin, $ignoreCancelled, $timings)); } /** diff --git a/src/pocketmine/plugin/RegisteredListener.php b/src/pocketmine/plugin/RegisteredListener.php index 7db4cadea6..0af6b197c7 100644 --- a/src/pocketmine/plugin/RegisteredListener.php +++ b/src/pocketmine/plugin/RegisteredListener.php @@ -25,13 +25,12 @@ namespace pocketmine\plugin; use pocketmine\event\Cancellable; use pocketmine\event\Event; -use pocketmine\event\Listener; use pocketmine\timings\TimingsHandler; class RegisteredListener{ - /** @var Listener */ - private $listener; + /** @var \Closure */ + private $handler; /** @var int */ private $priority; @@ -39,9 +38,6 @@ class RegisteredListener{ /** @var Plugin */ private $plugin; - /** @var EventExecutor */ - private $executor; - /** @var bool */ private $ignoreCancelled; @@ -50,27 +46,22 @@ class RegisteredListener{ /** - * @param Listener $listener - * @param EventExecutor $executor + * @param \Closure $handler * @param int $priority * @param Plugin $plugin * @param bool $ignoreCancelled * @param TimingsHandler $timings */ - public function __construct(Listener $listener, EventExecutor $executor, int $priority, Plugin $plugin, bool $ignoreCancelled, TimingsHandler $timings){ - $this->listener = $listener; + public function __construct(\Closure $handler, int $priority, Plugin $plugin, bool $ignoreCancelled, TimingsHandler $timings){ + $this->handler = $handler; $this->priority = $priority; $this->plugin = $plugin; - $this->executor = $executor; $this->ignoreCancelled = $ignoreCancelled; $this->timings = $timings; } - /** - * @return Listener - */ - public function getListener() : Listener{ - return $this->listener; + public function getHandler() : \Closure{ + return $this->handler; } /** @@ -95,7 +86,7 @@ class RegisteredListener{ return; } $this->timings->startTiming(); - $this->executor->execute($this->listener, $event); + ($this->handler)($event); $this->timings->stopTiming(); } From 20dad957554778b8676a145995cf5a9f8ee7c09e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 14 Nov 2018 17:48:14 +0000 Subject: [PATCH 0286/3224] Liquid: don't try to flow out of the world, close #2510 this fix is only required for master, although it could be backported. --- src/pocketmine/block/Liquid.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index 4837278d43..6ce560c0cb 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -438,6 +438,6 @@ abstract class Liquid extends Transparent{ } protected function canFlowInto(Block $block) : bool{ - return $block->canBeFlowedInto() and !($block instanceof Liquid and $block->isSource()); //TODO: I think this should only be liquids of the same type + return $this->level->isInWorld($block->x, $block->y, $block->z) and $block->canBeFlowedInto() and !($block instanceof Liquid and $block->isSource()); //TODO: I think this should only be liquids of the same type } } From 98efd275432f74f010af48649b2dd8839cc558ff Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 22 Nov 2018 16:53:22 +0000 Subject: [PATCH 0287/3224] Remove ability to set blockID and blockdata independently This was the cause of many inconsistency and broken world bugs. In the future (once we switch to paletted chunks) this won't be possible anyway. For now, some temporary API is provided to allow modifying chunkdata directly, but it is required that **both** must be provided. --- src/pocketmine/level/ChunkManager.php | 20 +-------- src/pocketmine/level/Explosion.php | 3 +- src/pocketmine/level/Level.php | 33 +------------- src/pocketmine/level/SimpleChunkManager.php | 28 ++---------- src/pocketmine/level/format/Chunk.php | 32 +------------- src/pocketmine/level/format/EmptySubChunk.php | 10 +---- src/pocketmine/level/format/SubChunk.php | 44 +++++-------------- .../level/format/SubChunkInterface.php | 32 +++----------- .../level/generator/hell/Nether.php | 6 +-- .../level/generator/normal/Normal.php | 6 +-- src/pocketmine/level/generator/object/Ore.php | 5 +-- .../level/generator/object/SpruceTree.php | 3 +- .../level/generator/object/TallGrass.php | 3 +- .../level/generator/object/Tree.php | 8 ++-- .../level/generator/populator/GroundCover.php | 7 +-- .../level/generator/populator/TallGrass.php | 3 +- 16 files changed, 43 insertions(+), 200 deletions(-) diff --git a/src/pocketmine/level/ChunkManager.php b/src/pocketmine/level/ChunkManager.php index 373b6cbef3..dd9fa341f8 100644 --- a/src/pocketmine/level/ChunkManager.php +++ b/src/pocketmine/level/ChunkManager.php @@ -37,16 +37,6 @@ interface ChunkManager{ */ public function getBlockIdAt(int $x, int $y, int $z) : int; - /** - * Sets the raw block id. - * - * @param int $x - * @param int $y - * @param int $z - * @param int $id 0-255 - */ - public function setBlockIdAt(int $x, int $y, int $z, int $id); - /** * Gets the raw block metadata * @@ -58,15 +48,7 @@ interface ChunkManager{ */ public function getBlockDataAt(int $x, int $y, int $z) : int; - /** - * Sets the raw block metadata. - * - * @param int $x - * @param int $y - * @param int $z - * @param int $data 0-15 - */ - public function setBlockDataAt(int $x, int $y, int $z, int $data); + public function setBlockIdAndDataAt(int $x, int $y, int $z, int $id, int $data) : void; /** * Returns the raw block light level diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index e0dd865089..3d1a963916 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -212,8 +212,7 @@ class Explosion{ } } - $this->level->setBlockIdAt($block->x, $block->y, $block->z, 0); - $this->level->setBlockDataAt($block->x, $block->y, $block->z, 0); + $this->level->setBlockIdAndDataAt($block->x, $block->y, $block->z, 0, 0); $t = $this->level->getTileAt($block->x, $block->y, $block->z); if($t instanceof Tile){ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 1493093425..65610a0254 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -2098,27 +2098,6 @@ class Level implements ChunkManager, Metadatable{ return $this->getChunk($x >> 4, $z >> 4, true)->getBlockId($x & 0x0f, $y, $z & 0x0f); } - /** - * Sets the raw block id. - * - * @param int $x - * @param int $y - * @param int $z - * @param int $id 0-255 - */ - public function setBlockIdAt(int $x, int $y, int $z, int $id){ - unset($this->blockCache[$chunkHash = Level::chunkHash($x >> 4, $z >> 4)][$blockHash = Level::blockHash($x, $y, $z)]); - $this->getChunk($x >> 4, $z >> 4, true)->setBlockId($x & 0x0f, $y, $z & 0x0f, $id & 0xff); - - if(!isset($this->changedBlocks[$chunkHash])){ - $this->changedBlocks[$chunkHash] = []; - } - $this->changedBlocks[$chunkHash][$blockHash] = $v = new Vector3($x, $y, $z); - foreach($this->getChunkLoaders($x >> 4, $z >> 4) as $loader){ - $loader->onBlockChanged($v); - } - } - /** * Gets the raw block metadata * @@ -2132,18 +2111,10 @@ class Level implements ChunkManager, Metadatable{ return $this->getChunk($x >> 4, $z >> 4, true)->getBlockData($x & 0x0f, $y, $z & 0x0f); } - /** - * Sets the raw block metadata. - * - * @param int $x - * @param int $y - * @param int $z - * @param int $data 0-15 - */ - public function setBlockDataAt(int $x, int $y, int $z, int $data){ + public function setBlockIdAndDataAt(int $x, int $y, int $z, int $id, int $data) : void{ unset($this->blockCache[$chunkHash = Level::chunkHash($x >> 4, $z >> 4)][$blockHash = Level::blockHash($x, $y, $z)]); - $this->getChunk($x >> 4, $z >> 4, true)->setBlockData($x & 0x0f, $y, $z & 0x0f, $data & 0x0f); + $this->getChunk($x >> 4, $z >> 4, true)->setBlock($x & 0x0f, $y, $z & 0x0f, $id, $data); if(!isset($this->changedBlocks[$chunkHash])){ $this->changedBlocks[$chunkHash] = []; diff --git a/src/pocketmine/level/SimpleChunkManager.php b/src/pocketmine/level/SimpleChunkManager.php index e240e23ee6..7243881786 100644 --- a/src/pocketmine/level/SimpleChunkManager.php +++ b/src/pocketmine/level/SimpleChunkManager.php @@ -57,20 +57,6 @@ class SimpleChunkManager implements ChunkManager{ return 0; } - /** - * Sets the raw block id. - * - * @param int $x - * @param int $y - * @param int $z - * @param int $id 0-255 - */ - public function setBlockIdAt(int $x, int $y, int $z, int $id){ - if($chunk = $this->getChunk($x >> 4, $z >> 4)){ - $chunk->setBlockId($x & 0xf, $y, $z & 0xf, $id); - } - } - /** * Gets the raw block metadata * @@ -87,17 +73,9 @@ class SimpleChunkManager implements ChunkManager{ return 0; } - /** - * Sets the raw block metadata. - * - * @param int $x - * @param int $y - * @param int $z - * @param int $data 0-15 - */ - public function setBlockDataAt(int $x, int $y, int $z, int $data){ - if($chunk = $this->getChunk($x >> 4, $z >> 4)){ - $chunk->setBlockData($x & 0xf, $y, $z & 0xf, $data); + public function setBlockIdAndDataAt(int $x, int $y, int $z, int $id, int $data) : void{ + if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ + $chunk->setBlock($x & 0xf, $y & 0xf, $z & 0xf, $id, $data); } } diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index 927149cd3a..e66d7e3de1 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -184,8 +184,8 @@ class Chunk{ * * @return bool */ - public function setBlock(int $x, int $y, int $z, ?int $blockId = null, ?int $meta = null) : bool{ - if($this->getSubChunk($y >> 4, true)->setBlock($x, $y & 0x0f, $z, $blockId !== null ? ($blockId & 0xff) : null, $meta !== null ? ($meta & 0x0f) : null)){ + public function setBlock(int $x, int $y, int $z, int $blockId, int $meta) : bool{ + if($this->getSubChunk($y >> 4, true)->setBlock($x, $y & 0x0f, $z, $blockId & 0xff, $meta & 0x0f)){ $this->hasChanged = true; return true; } @@ -205,20 +205,6 @@ class Chunk{ return $this->getSubChunk($y >> 4)->getBlockId($x, $y & 0x0f, $z); } - /** - * Sets the block ID at the specified chunk block coordinates - * - * @param int $x 0-15 - * @param int $y - * @param int $z 0-15 - * @param int $id 0-255 - */ - public function setBlockId(int $x, int $y, int $z, int $id){ - if($this->getSubChunk($y >> 4, true)->setBlockId($x, $y & 0x0f, $z, $id)){ - $this->hasChanged = true; - } - } - /** * Returns the block meta value at the specified chunk block coordinates * @@ -232,20 +218,6 @@ class Chunk{ return $this->getSubChunk($y >> 4)->getBlockData($x, $y & 0x0f, $z); } - /** - * Sets the block meta value at the specified chunk block coordinates - * - * @param int $x 0-15 - * @param int $y - * @param int $z 0-15 - * @param int $data 0-15 - */ - public function setBlockData(int $x, int $y, int $z, int $data){ - if($this->getSubChunk($y >> 4, true)->setBlockData($x, $y & 0x0f, $z, $data)){ - $this->hasChanged = true; - } - } - /** * Returns the sky light level at the specified chunk block coordinates * diff --git a/src/pocketmine/level/format/EmptySubChunk.php b/src/pocketmine/level/format/EmptySubChunk.php index 1e137ae058..6fb4d8d116 100644 --- a/src/pocketmine/level/format/EmptySubChunk.php +++ b/src/pocketmine/level/format/EmptySubChunk.php @@ -43,23 +43,15 @@ class EmptySubChunk implements SubChunkInterface{ return 0; } - public function setBlockId(int $x, int $y, int $z, int $id) : bool{ - return false; - } - public function getBlockData(int $x, int $y, int $z) : int{ return 0; } - public function setBlockData(int $x, int $y, int $z, int $data) : bool{ - return false; - } - public function getFullBlock(int $x, int $y, int $z) : int{ return 0; } - public function setBlock(int $x, int $y, int $z, ?int $id = null, ?int $data = null) : bool{ + public function setBlock(int $x, int $y, int $z, int $id, int $data) : bool{ return false; } diff --git a/src/pocketmine/level/format/SubChunk.php b/src/pocketmine/level/format/SubChunk.php index af63436842..32b62e4724 100644 --- a/src/pocketmine/level/format/SubChunk.php +++ b/src/pocketmine/level/format/SubChunk.php @@ -64,51 +64,31 @@ class SubChunk implements SubChunkInterface{ return ord($this->ids{($x << 8) | ($z << 4) | $y}); } - public function setBlockId(int $x, int $y, int $z, int $id) : bool{ - $this->ids{($x << 8) | ($z << 4) | $y} = chr($id); - return true; - } - public function getBlockData(int $x, int $y, int $z) : int{ return (ord($this->data{($x << 7) | ($z << 3) | ($y >> 1)}) >> (($y & 1) << 2)) & 0xf; } - public function setBlockData(int $x, int $y, int $z, int $data) : bool{ - $i = ($x << 7) | ($z << 3) | ($y >> 1); - - $shift = ($y & 1) << 2; - $byte = ord($this->data{$i}); - $this->data{$i} = chr(($byte & ~(0xf << $shift)) | (($data & 0xf) << $shift)); - - return true; - } - public function getFullBlock(int $x, int $y, int $z) : int{ $i = ($x << 8) | ($z << 4) | $y; return (ord($this->ids{$i}) << 4) | ((ord($this->data{$i >> 1}) >> (($y & 1) << 2)) & 0xf); } - public function setBlock(int $x, int $y, int $z, ?int $id = null, ?int $data = null) : bool{ + public function setBlock(int $x, int $y, int $z, int $id, int $data) : bool{ $i = ($x << 8) | ($z << 4) | $y; $changed = false; - if($id !== null){ - $block = chr($id); - if($this->ids{$i} !== $block){ - $this->ids{$i} = $block; - $changed = true; - } + + $block = chr($id); + if($this->ids{$i} !== $block){ + $this->ids{$i} = $block; + $changed = true; } - if($data !== null){ - $i >>= 1; - - $shift = ($y & 1) << 2; - $oldPair = ord($this->data{$i}); - $newPair = ($oldPair & ~(0xf << $shift)) | (($data & 0xf) << $shift); - if($newPair !== $oldPair){ - $this->data{$i} = chr($newPair); - $changed = true; - } + $shift = ($y & 1) << 2; + $oldPair = ord($this->data{$i}); + $newPair = ($oldPair & ~(0xf << $shift)) | (($data & 0xf) << $shift); + if($newPair !== $oldPair){ + $this->data{$i} = chr($newPair); + $changed = true; } return $changed; diff --git a/src/pocketmine/level/format/SubChunkInterface.php b/src/pocketmine/level/format/SubChunkInterface.php index e7d4cde8b1..71226db908 100644 --- a/src/pocketmine/level/format/SubChunkInterface.php +++ b/src/pocketmine/level/format/SubChunkInterface.php @@ -41,16 +41,6 @@ interface SubChunkInterface{ */ public function getBlockId(int $x, int $y, int $z) : int; - /** - * @param int $x - * @param int $y - * @param int $z - * @param int $id - * - * @return bool - */ - public function setBlockId(int $x, int $y, int $z, int $id) : bool; - /** * @param int $x * @param int $y @@ -60,16 +50,6 @@ interface SubChunkInterface{ */ public function getBlockData(int $x, int $y, int $z) : int; - /** - * @param int $x - * @param int $y - * @param int $z - * @param int $data - * - * @return bool - */ - public function setBlockData(int $x, int $y, int $z, int $data) : bool; - /** * @param int $x * @param int $y @@ -80,15 +60,15 @@ interface SubChunkInterface{ public function getFullBlock(int $x, int $y, int $z) : int; /** - * @param int $x - * @param int $y - * @param int $z - * @param int|null $id - * @param int|null $data + * @param int $x + * @param int $y + * @param int $z + * @param int $id + * @param int $data * * @return bool */ - public function setBlock(int $x, int $y, int $z, ?int $id = null, ?int $data = null) : bool; + public function setBlock(int $x, int $y, int $z, int $id, int $data) : bool; /** * @param int $x diff --git a/src/pocketmine/level/generator/hell/Nether.php b/src/pocketmine/level/generator/hell/Nether.php index 1215226911..838fa4db29 100644 --- a/src/pocketmine/level/generator/hell/Nether.php +++ b/src/pocketmine/level/generator/hell/Nether.php @@ -88,16 +88,16 @@ class Nether extends Generator{ for($y = 0; $y < 128; ++$y){ if($y === 0 or $y === 127){ - $chunk->setBlockId($x, $y, $z, Block::BEDROCK); + $chunk->setBlock($x, $y, $z, Block::BEDROCK, 0); continue; } $noiseValue = (abs($this->emptyHeight - $y) / $this->emptyHeight) * $this->emptyAmplitude - $noise[$x][$z][$y]; $noiseValue -= 1 - $this->density; if($noiseValue > 0){ - $chunk->setBlockId($x, $y, $z, Block::NETHERRACK); + $chunk->setBlock($x, $y, $z, Block::NETHERRACK, 0); }elseif($y <= $this->waterHeight){ - $chunk->setBlockId($x, $y, $z, Block::STILL_LAVA); + $chunk->setBlock($x, $y, $z, Block::STILL_LAVA, 0); } } } diff --git a/src/pocketmine/level/generator/normal/Normal.php b/src/pocketmine/level/generator/normal/Normal.php index 79e3a6e1f6..14c52e412f 100644 --- a/src/pocketmine/level/generator/normal/Normal.php +++ b/src/pocketmine/level/generator/normal/Normal.php @@ -208,15 +208,15 @@ class Normal extends Generator{ for($y = 0; $y < 128; ++$y){ if($y === 0){ - $chunk->setBlockId($x, $y, $z, Block::BEDROCK); + $chunk->setBlock($x, $y, $z, Block::BEDROCK, 0); continue; } $noiseValue = $noise[$x][$z][$y] - 1 / $smoothHeight * ($y - $smoothHeight - $minSum); if($noiseValue > 0){ - $chunk->setBlockId($x, $y, $z, Block::STONE); + $chunk->setBlock($x, $y, $z, Block::STONE, 0); }elseif($y <= $this->waterHeight){ - $chunk->setBlockId($x, $y, $z, Block::STILL_WATER); + $chunk->setBlock($x, $y, $z, Block::STILL_WATER, 0); } } } diff --git a/src/pocketmine/level/generator/object/Ore.php b/src/pocketmine/level/generator/object/Ore.php index 27e7a15f9e..048bd212ed 100644 --- a/src/pocketmine/level/generator/object/Ore.php +++ b/src/pocketmine/level/generator/object/Ore.php @@ -85,10 +85,7 @@ class Ore{ $sizeZ *= $sizeZ; if(($sizeX + $sizeY + $sizeZ) < 1 and $level->getBlockIdAt($x, $y, $z) === Block::STONE){ - $level->setBlockIdAt($x, $y, $z, $this->type->material->getId()); - if($this->type->material->getDamage() !== 0){ - $level->setBlockDataAt($x, $y, $z, $this->type->material->getDamage()); - } + $level->setBlockIdAndDataAt($x, $y, $z, $this->type->material->getId(), $this->type->material->getDamage()); } } } diff --git a/src/pocketmine/level/generator/object/SpruceTree.php b/src/pocketmine/level/generator/object/SpruceTree.php index 2ff0304ac7..cb7346cb7a 100644 --- a/src/pocketmine/level/generator/object/SpruceTree.php +++ b/src/pocketmine/level/generator/object/SpruceTree.php @@ -59,8 +59,7 @@ class SpruceTree extends Tree{ } if(!BlockFactory::get($level->getBlockIdAt($xx, $yyy, $zz))->isSolid()){ - $level->setBlockIdAt($xx, $yyy, $zz, $this->leafBlock); - $level->setBlockDataAt($xx, $yyy, $zz, $this->blockMeta); + $level->setBlockIdAndDataAt($xx, $yyy, $zz, $this->leafBlock, $this->blockMeta); } } } diff --git a/src/pocketmine/level/generator/object/TallGrass.php b/src/pocketmine/level/generator/object/TallGrass.php index cfa8098b12..ce1aee00f2 100644 --- a/src/pocketmine/level/generator/object/TallGrass.php +++ b/src/pocketmine/level/generator/object/TallGrass.php @@ -45,8 +45,7 @@ class TallGrass{ $z = $random->nextRange($pos->z - $radius, $pos->z + $radius); if($level->getBlockIdAt($x, $pos->y + 1, $z) === Block::AIR and $level->getBlockIdAt($x, $pos->y, $z) === Block::GRASS){ $t = $arr[$random->nextRange(0, $arrC)]; - $level->setBlockIdAt($x, $pos->y + 1, $z, $t[0]); - $level->setBlockDataAt($x, $pos->y + 1, $z, $t[1]); + $level->setBlockIdAndDataAt($x, $pos->y + 1, $z, $t[0], $t[1]); } } } diff --git a/src/pocketmine/level/generator/object/Tree.php b/src/pocketmine/level/generator/object/Tree.php index 5d3367bdbb..f0dced5a60 100644 --- a/src/pocketmine/level/generator/object/Tree.php +++ b/src/pocketmine/level/generator/object/Tree.php @@ -115,8 +115,7 @@ abstract class Tree{ continue; } if(!BlockFactory::get($level->getBlockIdAt($xx, $yy, $zz))->isSolid()){ - $level->setBlockIdAt($xx, $yy, $zz, $this->leafBlock); - $level->setBlockDataAt($xx, $yy, $zz, $this->blockMeta); + $level->setBlockIdAndDataAt($xx, $yy, $zz, $this->leafBlock, $this->blockMeta); } } } @@ -125,13 +124,12 @@ abstract class Tree{ protected function placeTrunk(ChunkManager $level, int $x, int $y, int $z, Random $random, int $trunkHeight) : void{ // The base dirt block - $level->setBlockIdAt($x, $y - 1, $z, Block::DIRT); + $level->setBlockIdAndDataAt($x, $y - 1, $z, Block::DIRT, 0); for($yy = 0; $yy < $trunkHeight; ++$yy){ $blockId = $level->getBlockIdAt($x, $y + $yy, $z); if($this->canOverride(BlockFactory::get($blockId))){ - $level->setBlockIdAt($x, $y + $yy, $z, $this->trunkBlock); - $level->setBlockDataAt($x, $y + $yy, $z, $this->blockMeta); + $level->setBlockIdAndDataAt($x, $y + $yy, $z, $this->trunkBlock, $this->blockMeta); } } } diff --git a/src/pocketmine/level/generator/populator/GroundCover.php b/src/pocketmine/level/generator/populator/GroundCover.php index 1218b449ab..2dd9109fc1 100644 --- a/src/pocketmine/level/generator/populator/GroundCover.php +++ b/src/pocketmine/level/generator/populator/GroundCover.php @@ -61,11 +61,8 @@ class GroundCover extends Populator{ if($b->canBeFlowedInto() and BlockFactory::get($id) instanceof Liquid){ continue; } - if($b->getDamage() === 0){ - $chunk->setBlockId($x, $y, $z, $b->getId()); - }else{ - $chunk->setBlock($x, $y, $z, $b->getId(), $b->getDamage()); - } + + $chunk->setBlock($x, $y, $z, $b->getId(), $b->getDamage()); } } } diff --git a/src/pocketmine/level/generator/populator/TallGrass.php b/src/pocketmine/level/generator/populator/TallGrass.php index 3532bc568b..6a16870a63 100644 --- a/src/pocketmine/level/generator/populator/TallGrass.php +++ b/src/pocketmine/level/generator/populator/TallGrass.php @@ -50,8 +50,7 @@ class TallGrass extends Populator{ $y = $this->getHighestWorkableBlock($x, $z); if($y !== -1 and $this->canTallGrassStay($x, $y, $z)){ - $this->level->setBlockIdAt($x, $y, $z, Block::TALL_GRASS); - $this->level->setBlockDataAt($x, $y, $z, 1); + $this->level->setBlockIdAndDataAt($x, $y, $z, Block::TALL_GRASS, 1); } } } From 8b350808efeb95768e2761b7fcfe3912c312d525 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 22 Nov 2018 16:56:44 +0000 Subject: [PATCH 0288/3224] Fixed merge error --- src/pocketmine/level/format/SubChunk.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pocketmine/level/format/SubChunk.php b/src/pocketmine/level/format/SubChunk.php index 32b62e4724..a8b1deadb8 100644 --- a/src/pocketmine/level/format/SubChunk.php +++ b/src/pocketmine/level/format/SubChunk.php @@ -83,6 +83,7 @@ class SubChunk implements SubChunkInterface{ $changed = true; } + $i >>= 1; $shift = ($y & 1) << 2; $oldPair = ord($this->data{$i}); $newPair = ($oldPair & ~(0xf << $shift)) | (($data & 0xf) << $shift); From 4c848bb4c179a2a1b31f457259bc4d43b8b32c38 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 22 Nov 2018 17:07:36 +0000 Subject: [PATCH 0289/3224] docs fixes --- src/pocketmine/level/format/Chunk.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index e66d7e3de1..a457aeb0ba 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -176,11 +176,11 @@ class Chunk{ /** * Sets block ID and meta in one call at the specified chunk block coordinates * - * @param int $x 0-15 - * @param int $y - * @param int $z 0-15 - * @param int|null $blockId 0-255 if null, does not change - * @param int|null $meta 0-15 if null, does not change + * @param int $x 0-15 + * @param int $y + * @param int $z 0-15 + * @param int $blockId 0-255 + * @param int $meta 0-15 * * @return bool */ From 101de7adda76dd750082e7e2b9ae0b22c288bc89 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 23 Nov 2018 19:41:52 +0000 Subject: [PATCH 0290/3224] Update Math dependency, obliterate some nasty code from Block --- composer.lock | 8 ++--- src/pocketmine/block/Anvil.php | 7 ++--- src/pocketmine/block/CocoaBlock.php | 34 ++++----------------- src/pocketmine/block/Door.php | 46 +---------------------------- src/pocketmine/block/EndRod.php | 41 +++++-------------------- src/pocketmine/block/FenceGate.php | 21 ++----------- src/pocketmine/block/Ladder.php | 25 ++-------------- src/pocketmine/block/Stair.php | 29 ++++-------------- src/pocketmine/block/Trapdoor.php | 23 ++------------- 9 files changed, 31 insertions(+), 203 deletions(-) diff --git a/composer.lock b/composer.lock index 72dd12b7ac..5ea2d220a8 100644 --- a/composer.lock +++ b/composer.lock @@ -187,12 +187,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "115700a493fc38fe8886739c20c4303eeb1cd182" + "reference": "93a430a089da009b44b710cca0c4fd4c2f06e702" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/115700a493fc38fe8886739c20c4303eeb1cd182", - "reference": "115700a493fc38fe8886739c20c4303eeb1cd182", + "url": "https://api.github.com/repos/pmmp/Math/zipball/93a430a089da009b44b710cca0c4fd4c2f06e702", + "reference": "93a430a089da009b44b710cca0c4fd4c2f06e702", "shasum": "" }, "require": { @@ -218,7 +218,7 @@ "source": "https://github.com/pmmp/Math/tree/master", "issues": "https://github.com/pmmp/Math/issues" }, - "time": "2018-09-23T17:50:23+00:00" + "time": "2018-11-23T19:38:18+00:00" }, { "name": "pocketmine/nbt", diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index d3212e03b3..065c8b8ac9 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -76,11 +76,8 @@ class Anvil extends Fallable{ public function recalculateBoundingBox() : ?AxisAlignedBB{ $inset = 0.125; - if(Facing::axis($this->facing) === Facing::AXIS_X){ - return new AxisAlignedBB(0, 0, $inset, 1, 1, 1 - $inset); - }else{ - return new AxisAlignedBB($inset, 0, 0, 1 - $inset, 1, 1); - } + $bb = new AxisAlignedBB(0, 0, 0, 1, 1, 1); + return $bb->squash(Facing::axis(Facing::rotate($this->facing, Facing::AXIS_Y, false)), $inset); } public function onActivate(Item $item, Player $player = null) : bool{ diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index f306cccc8b..15523b53c6 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -74,36 +74,12 @@ class CocoaBlock extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - static $logDistance = 1 / 16; + $bb = new AxisAlignedBB(0, (7 - $this->age * 2) / 16, 0, 1, 0.75, 1); - $widthInset = (6 - $this->age) / 16; - $faceDistance = (5 + $this->age * 2) / 16; - - $minY = (7 - $this->age * 2) / 16; - - if(Facing::isPositive($this->facing)){ - $minFacing = $logDistance; - $maxFacing = $faceDistance; - }else{ - $minFacing = 1 - $faceDistance; - $maxFacing = 1 - $logDistance; - } - - if(Facing::axis($this->facing) === Facing::AXIS_Z){ - $minX = $widthInset; - $maxX = 1 - $widthInset; - - $minZ = $minFacing; - $maxZ = $maxFacing; - }else{ - $minX = $minFacing; - $maxX = $maxFacing; - - $minZ = $widthInset; - $maxZ = 1 - $widthInset; - } - - return new AxisAlignedBB($minX, $minY, $minZ, $maxX, 0.75, $maxZ); + return $bb + ->squash(Facing::axis(Facing::rotate($this->facing, Facing::AXIS_Y, true)), (6 - $this->age) / 16) //sides + ->trim(Facing::opposite($this->facing), 1 / 16) //gap between log and pod + ->trim($this->facing, (11 - $this->age * 2) / 16); //outward face } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index a99638ef3e..5aea3c1ec7 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -91,54 +91,10 @@ abstract class Door extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - $f = 0.1875; $this->updateStateFromOtherHalf(); $bb = new AxisAlignedBB(0, 0, 0, 1, 2, 1); - - if($this->facing === Facing::EAST){ - if($this->open){ - if(!$this->hingeRight){ - $bb->setBounds(0, 0, 0, 1, 1, $f); - }else{ - $bb->setBounds(0, 0, 1 - $f, 1, 1, 1); - } - }else{ - $bb->setBounds(0, 0, 0, $f, 1, 1); - } - }elseif($this->facing === Facing::SOUTH){ - if($this->open){ - if(!$this->hingeRight){ - $bb->setBounds(1 - $f, 0, 0, 1, 1, 1); - }else{ - $bb->setBounds(0, 0, 0, $f, 1, 1); - } - }else{ - $bb->setBounds(0, 0, 0, 1, 1, $f); - } - }elseif($this->facing === Facing::WEST){ - if($this->open){ - if(!$this->hingeRight){ - $bb->setBounds(0, 0, 1 - $f, 1, 1, 1); - }else{ - $bb->setBounds(0, 0, 0, 1, 1, $f); - } - }else{ - $bb->setBounds(1 - $f, 0, 0, 1, 1, 1); - } - }elseif($this->facing === Facing::NORTH){ - if($this->open){ - if(!$this->hingeRight){ - $bb->setBounds(0, 0, 0, $f, 1, 1); - }else{ - $bb->setBounds(1 - $f, 0, 0, 1, 1, 1); - } - }else{ - $bb->setBounds(0, 0, 1 - $f, 1, 1, 1); - } - } - - return $bb; + return $bb->trim($this->open ? Facing::rotate($this->facing, Facing::AXIS_Y, !$this->hingeRight) : $this->facing, 13 / 16); } public function onNearbyBlockChange() : void{ diff --git a/src/pocketmine/block/EndRod.php b/src/pocketmine/block/EndRod.php index c639fc495e..d4caf3bc4e 100644 --- a/src/pocketmine/block/EndRod.php +++ b/src/pocketmine/block/EndRod.php @@ -81,40 +81,15 @@ class EndRod extends Flowable{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - $m = Facing::axis($this->facing); - $width = 0.375; + $myAxis = Facing::axis($this->facing); - switch($m){ - case Facing::AXIS_Y: - return new AxisAlignedBB( - $width, - 0, - $width, - 1 - $width, - 1, - 1 - $width - ); - case Facing::AXIS_Z: - return new AxisAlignedBB( - $width, - $width, - 0, - 1 - $width, - 1 - $width, - 1 - ); - - case Facing::AXIS_X: - return new AxisAlignedBB( - 0, - $width, - $width, - 1, - 1 - $width, - 1 - $width - ); + $bb = new AxisAlignedBB(0, 0, 0, 1, 1, 1); + foreach([Facing::AXIS_Y, Facing::AXIS_Z, Facing::AXIS_X] as $axis){ + if($axis === $myAxis){ + continue; + } + $bb->squash($axis, 6 / 16); } - - return null; + return $bb; } } diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index cd8878a450..6da2499154 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -64,25 +64,8 @@ class FenceGate extends Transparent{ return null; } - if(Facing::axis($this->facing) === Facing::AXIS_Z){ - return new AxisAlignedBB( - 0, - 0, - 0.375, - 1, - 1.5, - 0.625 - ); - }else{ - return new AxisAlignedBB( - 0.375, - 0, - 0, - 0.625, - 1.5, - 1 - ); - } + $bb = new AxisAlignedBB(0, 0, 0, 1, 1.5, 1); + return $bb->squash(Facing::axis($this->facing), 6 / 16); } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ diff --git a/src/pocketmine/block/Ladder.php b/src/pocketmine/block/Ladder.php index b309fa18ac..f6f2218b02 100644 --- a/src/pocketmine/block/Ladder.php +++ b/src/pocketmine/block/Ladder.php @@ -79,29 +79,8 @@ class Ladder extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - $f = 0.1875; - - $minX = $minZ = 0; - $maxX = $maxZ = 1; - - if($this->facing === Facing::NORTH){ - $minZ = 1 - $f; - }elseif($this->facing === Facing::SOUTH){ - $maxZ = $f; - }elseif($this->facing === Facing::WEST){ - $minX = 1 - $f; - }elseif($this->facing === Facing::EAST){ - $maxX = $f; - } - - return new AxisAlignedBB( - $minX, - 0, - $minZ, - $maxX, - 1, - $maxZ - ); + $bb = new AxisAlignedBB(0, 0, 0, 1, 1, 1); + return $bb->trim($this->facing, 13 / 16); } diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index dcdaf1ac0f..cdf4019cae 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -59,17 +59,17 @@ abstract class Stair extends Transparent{ $minY = $this->upsideDown ? 0 : 0.5; $topStep = new AxisAlignedBB(0, $minY, 0, 1, $minY + 0.5, 1); - self::setBoundsForFacing($topStep, $this->facing); + $topStep->trim(Facing::opposite($this->facing), 0.5); /** @var Stair $corner */ if(($backFacing = $this->getPossibleCornerFacing(false)) !== null){ - self::setBoundsForFacing($topStep, $backFacing); + $topStep->trim(Facing::opposite($backFacing), 0.5); }elseif(($frontFacing = $this->getPossibleCornerFacing(true)) !== null){ //add an extra cube $extraCube = new AxisAlignedBB(0, $minY, 0, 1, $minY + 0.5, 1); - self::setBoundsForFacing($extraCube, Facing::opposite($this->facing)); - self::setBoundsForFacing($extraCube, $frontFacing); - $bbs[] = $extraCube; + $bbs[] = $extraCube + ->trim($this->facing, 0.5) + ->trim(Facing::opposite($frontFacing), 0.5); } $bbs[] = $topStep; @@ -88,25 +88,6 @@ abstract class Stair extends Transparent{ return null; } - private static function setBoundsForFacing(AxisAlignedBB $bb, int $facing) : void{ - switch($facing){ - case Facing::EAST: - $bb->minX = 0.5; - break; - case Facing::WEST: - $bb->maxX = 0.5; - break; - case Facing::SOUTH: - $bb->minZ = 0.5; - break; - case Facing::NORTH: - $bb->maxZ = 0.5; - break; - default: - throw new \InvalidArgumentException("Facing must be horizontal"); - } - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ $this->facing = Bearing::toFacing($player->getDirection()); diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index b9a5dbdaea..42cb728b99 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -73,27 +73,8 @@ class Trapdoor extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - $f = 0.1875; - - if($this->top){ - $bb = new AxisAlignedBB(0, 1 - $f, 0, 1, 1, 1); - }else{ - $bb = new AxisAlignedBB(0, 0, 0, 1, $f, 1); - } - - if($this->open){ - if($this->facing === Facing::NORTH){ - $bb->setBounds(0, 0, 1 - $f, 1, 1, 1); - }elseif($this->facing === Facing::SOUTH){ - $bb->setBounds(0, 0, 0, 1, 1, $f); - }elseif($this->facing === Facing::WEST){ - $bb->setBounds(1 - $f, 0, 0, 1, 1, 1); - }elseif($this->facing === Facing::EAST){ - $bb->setBounds(0, 0, 0, $f, 1, 1); - } - } - - return $bb; + $bb = new AxisAlignedBB(0, 0, 0, 1, 1, 1); + return $bb->trim($this->open ? $this->facing : ($this->top ? Facing::DOWN : Facing::UP), 13 / 16); } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ From d5ae4ad141b17e42f628af4288428d49d801182c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 24 Nov 2018 18:34:49 +0000 Subject: [PATCH 0291/3224] Sync Math dependency --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 5ea2d220a8..e89e1658cf 100644 --- a/composer.lock +++ b/composer.lock @@ -187,12 +187,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "93a430a089da009b44b710cca0c4fd4c2f06e702" + "reference": "82401b6c79404fa2e102596dfc3e59a0e4449158" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/93a430a089da009b44b710cca0c4fd4c2f06e702", - "reference": "93a430a089da009b44b710cca0c4fd4c2f06e702", + "url": "https://api.github.com/repos/pmmp/Math/zipball/82401b6c79404fa2e102596dfc3e59a0e4449158", + "reference": "82401b6c79404fa2e102596dfc3e59a0e4449158", "shasum": "" }, "require": { @@ -218,7 +218,7 @@ "source": "https://github.com/pmmp/Math/tree/master", "issues": "https://github.com/pmmp/Math/issues" }, - "time": "2018-11-23T19:38:18+00:00" + "time": "2018-11-24T14:16:58+00:00" }, { "name": "pocketmine/nbt", From b2201c8c59600cf1f8db76c0d0b6be211b0dbf04 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 24 Nov 2018 19:17:03 +0000 Subject: [PATCH 0292/3224] Further cleanup to general AABB handling --- src/pocketmine/block/Anvil.php | 5 +---- src/pocketmine/block/Bed.php | 2 +- src/pocketmine/block/Block.php | 2 +- src/pocketmine/block/Cactus.php | 4 ++-- src/pocketmine/block/Cake.php | 14 ++++---------- src/pocketmine/block/Carpet.php | 2 +- src/pocketmine/block/Chest.php | 2 +- src/pocketmine/block/CocoaBlock.php | 6 +++--- src/pocketmine/block/DaylightSensor.php | 3 ++- src/pocketmine/block/Door.php | 5 +++-- src/pocketmine/block/EnchantingTable.php | 3 ++- src/pocketmine/block/EndPortalFrame.php | 9 +-------- src/pocketmine/block/EndRod.php | 2 +- src/pocketmine/block/Farmland.php | 2 +- src/pocketmine/block/FenceGate.php | 3 +-- src/pocketmine/block/FlowerPot.php | 3 +-- src/pocketmine/block/GrassPath.php | 2 +- src/pocketmine/block/Ladder.php | 3 +-- src/pocketmine/block/Skull.php | 3 +-- src/pocketmine/block/Slab.php | 6 +----- src/pocketmine/block/SoulSand.php | 3 ++- src/pocketmine/block/Trapdoor.php | 3 +-- src/pocketmine/block/WaterLily.php | 3 +-- src/pocketmine/level/Explosion.php | 2 +- src/pocketmine/level/Level.php | 2 +- 25 files changed, 36 insertions(+), 58 deletions(-) diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index 065c8b8ac9..78909e6662 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -74,10 +74,7 @@ class Anvil extends Fallable{ } public function recalculateBoundingBox() : ?AxisAlignedBB{ - $inset = 0.125; - - $bb = new AxisAlignedBB(0, 0, 0, 1, 1, 1); - return $bb->squash(Facing::axis(Facing::rotate($this->facing, Facing::AXIS_Y, false)), $inset); + return AxisAlignedBB::one()->squash(Facing::axis(Facing::rotate($this->facing, Facing::AXIS_Y, false)), 1 / 8); } public function onActivate(Item $item, Player $player = null) : bool{ diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 9586015a05..0ddceb3c78 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -80,7 +80,7 @@ class Bed extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return new AxisAlignedBB(0, 0, 0, 1, 0.5625, 1); + return AxisAlignedBB::one()->trim(Facing::UP, 7 / 16); } public function isHeadPart() : bool{ diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 75167523e8..5fd0d27aee 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -714,7 +714,7 @@ class Block extends Position implements BlockIds, Metadatable{ * @return AxisAlignedBB|null */ protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return new AxisAlignedBB(0, 0, 0, 1, 1, 1); + return AxisAlignedBB::one(); } /** diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index b0a0d65924..19faaa0da1 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -69,8 +69,8 @@ class Cactus extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - static $shrinkSize = 0.0625; - return new AxisAlignedBB($shrinkSize, $shrinkSize, $shrinkSize, 1 - $shrinkSize, 1 - $shrinkSize, 1 - $shrinkSize); + static $shrinkSize = 1 / 16; + return AxisAlignedBB::one()->contract($shrinkSize, 0, $shrinkSize)->trim(Facing::UP, $shrinkSize); } public function onEntityCollide(Entity $entity) : void{ diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index 35862bacaf..ffa436c57d 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -66,16 +66,10 @@ class Cake extends Transparent implements FoodSource{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - $f = $this->bites * 0.125; //1 slice width - - return new AxisAlignedBB( - 0.0625 + $f, - 0, - 0.0625, - 1 - 0.0625, - 0.5, - 1 - 0.0625 - ); + return AxisAlignedBB::one() + ->contract(1 / 16, 0, 1 / 16) + ->trim(Facing::UP, 0.5) + ->trim(Facing::WEST, $this->bites / 8); } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ diff --git a/src/pocketmine/block/Carpet.php b/src/pocketmine/block/Carpet.php index b9ca2d13d4..bc8efe52c0 100644 --- a/src/pocketmine/block/Carpet.php +++ b/src/pocketmine/block/Carpet.php @@ -40,7 +40,7 @@ class Carpet extends Flowable{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return new AxisAlignedBB(0, 0, 0, 1, 0.0625, 1); + return AxisAlignedBB::one()->trim(Facing::UP, 15 / 16); } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index c5f22ebed5..ce41b7a7bf 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -69,7 +69,7 @@ class Chest extends Transparent{ protected function recalculateBoundingBox() : ?AxisAlignedBB{ //these are slightly bigger than in PC - return new AxisAlignedBB(0.025, 0, 0.025, 0.975, 0.95, 0.975); + return AxisAlignedBB::one()->contract(0.025, 0, 0.025)->trim(Facing::UP, 0.05); } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index 15523b53c6..b2225bf738 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -74,10 +74,10 @@ class CocoaBlock extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - $bb = new AxisAlignedBB(0, (7 - $this->age * 2) / 16, 0, 1, 0.75, 1); - - return $bb + return AxisAlignedBB::one() ->squash(Facing::axis(Facing::rotate($this->facing, Facing::AXIS_Y, true)), (6 - $this->age) / 16) //sides + ->trim(Facing::DOWN, (7 - $this->age * 2) / 16) + ->trim(Facing::UP, 0.25) ->trim(Facing::opposite($this->facing), 1 / 16) //gap between log and pod ->trim($this->facing, (11 - $this->age * 2) / 16); //outward face } diff --git a/src/pocketmine/block/DaylightSensor.php b/src/pocketmine/block/DaylightSensor.php index faa2acc236..ee64b39d85 100644 --- a/src/pocketmine/block/DaylightSensor.php +++ b/src/pocketmine/block/DaylightSensor.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\Player; class DaylightSensor extends Transparent{ @@ -82,7 +83,7 @@ class DaylightSensor extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return new AxisAlignedBB(0, 0, 0, 1, 0.5, 1); + return AxisAlignedBB::one()->trim(Facing::UP, 0.5); } public function onActivate(Item $item, Player $player = null) : bool{ diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 5aea3c1ec7..dcb6c65d9c 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -93,8 +93,9 @@ abstract class Door extends Transparent{ protected function recalculateBoundingBox() : ?AxisAlignedBB{ $this->updateStateFromOtherHalf(); - $bb = new AxisAlignedBB(0, 0, 0, 1, 2, 1); - return $bb->trim($this->open ? Facing::rotate($this->facing, Facing::AXIS_Y, !$this->hingeRight) : $this->facing, 13 / 16); + return AxisAlignedBB::one() + ->extend(Facing::UP, 1) + ->trim($this->open ? Facing::rotate($this->facing, Facing::AXIS_Y, !$this->hingeRight) : $this->facing, 13 / 16); } public function onNearbyBlockChange() : void{ diff --git a/src/pocketmine/block/EnchantingTable.php b/src/pocketmine/block/EnchantingTable.php index c608d394e7..6a8b68d907 100644 --- a/src/pocketmine/block/EnchantingTable.php +++ b/src/pocketmine/block/EnchantingTable.php @@ -27,6 +27,7 @@ use pocketmine\inventory\EnchantInventory; use pocketmine\item\Item; use pocketmine\item\TieredTool; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\EnchantTable as TileEnchantTable; @@ -70,7 +71,7 @@ class EnchantingTable extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return new AxisAlignedBB(0, 0, 0, 1, 0.75, 1); + return AxisAlignedBB::one()->trim(Facing::UP, 0.25); } public function onActivate(Item $item, Player $player = null) : bool{ diff --git a/src/pocketmine/block/EndPortalFrame.php b/src/pocketmine/block/EndPortalFrame.php index 5c002b71fb..438d0a2c2c 100644 --- a/src/pocketmine/block/EndPortalFrame.php +++ b/src/pocketmine/block/EndPortalFrame.php @@ -77,14 +77,7 @@ class EndPortalFrame extends Solid{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return new AxisAlignedBB( - 0, - 0, - 0, - 1, - $this->eye ? 1 : 0.8125, - 1 - ); + return AxisAlignedBB::one()->trim(Facing::UP, 3 / 16); } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ diff --git a/src/pocketmine/block/EndRod.php b/src/pocketmine/block/EndRod.php index d4caf3bc4e..eeebbd200c 100644 --- a/src/pocketmine/block/EndRod.php +++ b/src/pocketmine/block/EndRod.php @@ -83,7 +83,7 @@ class EndRod extends Flowable{ protected function recalculateBoundingBox() : ?AxisAlignedBB{ $myAxis = Facing::axis($this->facing); - $bb = new AxisAlignedBB(0, 0, 0, 1, 1, 1); + $bb = AxisAlignedBB::one(); foreach([Facing::AXIS_Y, Facing::AXIS_Z, Facing::AXIS_X] as $axis){ if($axis === $myAxis){ continue; diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index 89c50a41cc..3303bc4d67 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -64,7 +64,7 @@ class Farmland extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return new AxisAlignedBB(0, 0, 0, 1, 1, 1); //TODO: y max should be 0.9375, but MCPE currently treats them as a full block (https://bugs.mojang.com/browse/MCPE-12109) + return AxisAlignedBB::one(); //TODO: this should be trimmed at the top by 1/16, but MCPE currently treats them as a full block (https://bugs.mojang.com/browse/MCPE-12109) } public function onNearbyBlockChange() : void{ diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index 6da2499154..5dcb60ded6 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -64,8 +64,7 @@ class FenceGate extends Transparent{ return null; } - $bb = new AxisAlignedBB(0, 0, 0, 1, 1.5, 1); - return $bb->squash(Facing::axis($this->facing), 6 / 16); + return AxisAlignedBB::one()->extend(Facing::UP, 0.5)->squash(Facing::axis($this->facing), 6 / 16); } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index e8b2eb8b3f..0399fd26e2 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -60,8 +60,7 @@ class FlowerPot extends Flowable{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - static $f = 0.3125; - return new AxisAlignedBB($f, 0, $f, 1 - $f, 0.375, 1 - $f); + return AxisAlignedBB::one()->contract(3 / 16, 0, 3 / 16)->trim(Facing::UP, 5 / 8); } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ diff --git a/src/pocketmine/block/GrassPath.php b/src/pocketmine/block/GrassPath.php index 389d5ee58e..459ff721d0 100644 --- a/src/pocketmine/block/GrassPath.php +++ b/src/pocketmine/block/GrassPath.php @@ -45,7 +45,7 @@ class GrassPath extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return new AxisAlignedBB(0, 0, 0, 1, 1, 1); //TODO: y max should be 0.9375, but MCPE currently treats them as a full block (https://bugs.mojang.com/browse/MCPE-12109) + return AxisAlignedBB::one(); //TODO: this should be trimmed at the top by 1/16, but MCPE currently treats them as a full block (https://bugs.mojang.com/browse/MCPE-12109) } public function getHardness() : float{ diff --git a/src/pocketmine/block/Ladder.php b/src/pocketmine/block/Ladder.php index f6f2218b02..1b834204ec 100644 --- a/src/pocketmine/block/Ladder.php +++ b/src/pocketmine/block/Ladder.php @@ -79,8 +79,7 @@ class Ladder extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - $bb = new AxisAlignedBB(0, 0, 0, 1, 1, 1); - return $bb->trim($this->facing, 13 / 16); + return AxisAlignedBB::one()->trim($this->facing, 13 / 16); } diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index e676b57abe..d19815f4db 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -65,8 +65,7 @@ class Skull extends Flowable{ protected function recalculateBoundingBox() : ?AxisAlignedBB{ //TODO: different bounds depending on attached face - static $f = 0.25; - return new AxisAlignedBB($f, 0, $f, 1 - $f, 0.5, 1 - $f); + return AxisAlignedBB::one()->contract(0.25, 0, 0.25)->trim(Facing::UP, 0.5); } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index d6b8fb63fa..ef7950e2f5 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -101,10 +101,6 @@ abstract class Slab extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - if($this->top){ - return new AxisAlignedBB(0, 0.5, 0, 1, 1, 1); - }else{ - return new AxisAlignedBB(0, 0, 0, 1, 0.5, 1); - } + return AxisAlignedBB::one()->trim($this->top ? Facing::DOWN : Facing::UP, 0.5); } } diff --git a/src/pocketmine/block/SoulSand.php b/src/pocketmine/block/SoulSand.php index 9df0ac22bb..8dc21f87c9 100644 --- a/src/pocketmine/block/SoulSand.php +++ b/src/pocketmine/block/SoulSand.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; class SoulSand extends Solid{ @@ -46,6 +47,6 @@ class SoulSand extends Solid{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return new AxisAlignedBB(0, 0, 0, 1, 1 - 0.125, 1); + return AxisAlignedBB::one()->trim(Facing::UP, 1 / 8); } } diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index 42cb728b99..625824409d 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -73,8 +73,7 @@ class Trapdoor extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - $bb = new AxisAlignedBB(0, 0, 0, 1, 1, 1); - return $bb->trim($this->open ? $this->facing : ($this->top ? Facing::DOWN : Facing::UP), 13 / 16); + return AxisAlignedBB::one()->trim($this->open ? $this->facing : ($this->top ? Facing::DOWN : Facing::UP), 13 / 16); } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ diff --git a/src/pocketmine/block/WaterLily.php b/src/pocketmine/block/WaterLily.php index faf1316fa0..0c4c05ff11 100644 --- a/src/pocketmine/block/WaterLily.php +++ b/src/pocketmine/block/WaterLily.php @@ -46,8 +46,7 @@ class WaterLily extends Flowable{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - static $f = 0.0625; - return new AxisAlignedBB($f, 0, $f, 1 - $f, 0.015625, 1 - $f); + return AxisAlignedBB::one()->contract(1 / 16, 0, 1 / 16)->trim(Facing::UP, 63 / 64); } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index 3d1a963916..3f2b0e7343 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -238,7 +238,7 @@ class Explosion{ $ev = new BlockUpdateEvent($this->level->getBlockAt($sideBlock->x, $sideBlock->y, $sideBlock->z)); $ev->call(); if(!$ev->isCancelled()){ - foreach($this->level->getNearbyEntities(new AxisAlignedBB($sideBlock->x - 1, $sideBlock->y - 1, $sideBlock->z - 1, $sideBlock->x + 2, $sideBlock->y + 2, $sideBlock->z + 2)) as $entity){ + foreach($this->level->getNearbyEntities(AxisAlignedBB::one()->offset($sideBlock->x, $sideBlock->y, $sideBlock->z)->expand(1, 1, 1)) as $entity){ $entity->onNearbyBlockChange(); } $ev->getBlock()->onNearbyBlockChange(); diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 65610a0254..3914e9133a 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1546,7 +1546,7 @@ class Level implements ChunkManager, Metadatable{ $ev = new BlockUpdateEvent($block); $ev->call(); if(!$ev->isCancelled()){ - foreach($this->getNearbyEntities(new AxisAlignedBB($block->x - 1, $block->y - 1, $block->z - 1, $block->x + 2, $block->y + 2, $block->z + 2)) as $entity){ + foreach($this->getNearbyEntities(AxisAlignedBB::one()->offset($block->x, $block->y, $block->z)->expand(1, 1, 1)) as $entity){ $entity->onNearbyBlockChange(); } $ev->getBlock()->onNearbyBlockChange(); From 3af293f024fcf6a384341264bc5aef16827a419a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Oct 2018 15:57:32 +0100 Subject: [PATCH 0293/3224] Added a mechanism for blocks to detect dynamic state properties from surroundings --- src/pocketmine/block/Block.php | 11 +++++--- src/pocketmine/block/CobblestoneWall.php | 34 +++++++++++++++++------ src/pocketmine/block/Door.php | 12 +++----- src/pocketmine/block/Fence.php | 35 ++++++++++++++++-------- src/pocketmine/block/Liquid.php | 4 +-- src/pocketmine/level/Level.php | 4 +-- 6 files changed, 63 insertions(+), 37 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 5fd0d27aee..cc6ac4b86d 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -448,7 +448,7 @@ class Block extends Position implements BlockIds, Metadatable{ $this->y = (int) $v->y; $this->z = (int) $v->z; $this->level = $v->level; - $this->boundingBox = null; + $this->updateState(); } /** @@ -718,10 +718,13 @@ class Block extends Position implements BlockIds, Metadatable{ } /** - * Clears any cached precomputed objects, such as bounding boxes. This is called on block neighbour update and when - * the block is set into the world to remove any outdated precomputed things such as AABBs and force recalculation. + * Called when this block is created, set, or has a neighbouring block update, to re-detect dynamic properties which + * are not saved on the world. + * + * Clears any cached precomputed objects, such as bounding boxes. Remove any outdated precomputed things such as + * AABBs and force recalculation. */ - public function clearCaches() : void{ + public function updateState() : void{ $this->boundingBox = null; $this->collisionBoxes = null; } diff --git a/src/pocketmine/block/CobblestoneWall.php b/src/pocketmine/block/CobblestoneWall.php index 85a2dab8fc..a944dc20d2 100644 --- a/src/pocketmine/block/CobblestoneWall.php +++ b/src/pocketmine/block/CobblestoneWall.php @@ -31,6 +31,11 @@ class CobblestoneWall extends Transparent{ public const NONE_MOSSY_WALL = 0; public const MOSSY_WALL = 1; + /** @var bool[] facing => dummy */ + protected $connections = []; + /** @var bool */ + protected $up = false; + public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } @@ -43,17 +48,32 @@ class CobblestoneWall extends Transparent{ return 2; } + public function updateState() : void{ + parent::updateState(); + + foreach(Facing::HORIZONTAL as $facing){ + $block = $this->getSide($facing); + if($block instanceof static or $block instanceof FenceGate or ($block->isSolid() and !$block->isTransparent())){ + $this->connections[$facing] = true; + }else{ + unset($this->connections[$facing]); + } + } + + $this->up = $this->getSide(Facing::UP)->getId() !== Block::AIR; + } + protected function recalculateBoundingBox() : ?AxisAlignedBB{ //walls don't have any special collision boxes like fences do - $north = $this->canConnect($this->getSide(Facing::NORTH)); - $south = $this->canConnect($this->getSide(Facing::SOUTH)); - $west = $this->canConnect($this->getSide(Facing::WEST)); - $east = $this->canConnect($this->getSide(Facing::EAST)); + $north = isset($this->connections[Facing::NORTH]); + $south = isset($this->connections[Facing::SOUTH]); + $west = isset($this->connections[Facing::WEST]); + $east = isset($this->connections[Facing::EAST]); $inset = 0.25; if( - $this->getSide(Facing::UP)->getId() === Block::AIR and //if there is a block on top, it stays as a post + !$this->up and //if there is a block on top, it stays as a post ( ($north and $south and !$west and !$east) or (!$north and !$south and $west and $east) @@ -72,8 +92,4 @@ class CobblestoneWall extends Transparent{ 1 - ($south ? 0 : $inset) ); } - - public function canConnect(Block $block){ - return $block instanceof static or $block instanceof FenceGate or ($block->isSolid() and !$block->isTransparent()); - } } diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index dcb6c65d9c..7191d80a4e 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -69,11 +69,10 @@ abstract class Door extends Transparent{ return 0b1111; } - /** - * Copies door properties from the other half of the door, since metadata is split between the two halves. - * TODO: the blockstate should be updated directly on creation so these properties can be detected in advance. - */ - private function updateStateFromOtherHalf() : void{ + public function updateState() : void{ + parent::updateState(); + + //copy door properties from other half $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); if($other instanceof Door and $other->isSameType($this)){ if($this->top){ @@ -91,8 +90,6 @@ abstract class Door extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - $this->updateStateFromOtherHalf(); - return AxisAlignedBB::one() ->extend(Facing::UP, 1) ->trim($this->open ? Facing::rotate($this->facing, Facing::AXIS_Y, !$this->hingeRight) : $this->facing, 13 / 16); @@ -135,7 +132,6 @@ abstract class Door extends Transparent{ } public function onActivate(Item $item, Player $player = null) : bool{ - $this->updateStateFromOtherHalf(); $this->open = !$this->open; $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); diff --git a/src/pocketmine/block/Fence.php b/src/pocketmine/block/Fence.php index b207619c6c..44847f58d9 100644 --- a/src/pocketmine/block/Fence.php +++ b/src/pocketmine/block/Fence.php @@ -27,21 +27,36 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; abstract class Fence extends Transparent{ + /** @var bool[] facing => dummy */ + protected $connections = []; public function getThickness() : float{ return 0.25; } + public function updateState() : void{ + parent::updateState(); + + foreach(Facing::HORIZONTAL as $facing){ + $block = $this->getSide($facing); + if($block instanceof static or $block instanceof FenceGate or ($block->isSolid() and !$block->isTransparent())){ + $this->connections[$facing] = true; + }else{ + unset($this->connections[$facing]); + } + } + } + protected function recalculateBoundingBox() : ?AxisAlignedBB{ $width = 0.5 - $this->getThickness() / 2; return new AxisAlignedBB( - ($this->canConnect($this->getSide(Facing::WEST)) ? 0 : $width), + (isset($this->connections[Facing::WEST]) ? 0 : $width), 0, - ($this->canConnect($this->getSide(Facing::NORTH)) ? 0 : $width), - 1 - ($this->canConnect($this->getSide(Facing::EAST)) ? 0 : $width), + (isset($this->connections[Facing::NORTH]) ? 0 : $width), + 1 - (isset($this->connections[Facing::EAST]) ? 0 : $width), 1.5, - 1 - ($this->canConnect($this->getSide(Facing::SOUTH)) ? 0 : $width) + 1 - (isset($this->connections[Facing::WEST]) ? 0 : $width) ); } @@ -51,8 +66,8 @@ abstract class Fence extends Transparent{ /** @var AxisAlignedBB[] $bbs */ $bbs = []; - $connectWest = $this->canConnect($this->getSide(Facing::WEST)); - $connectEast = $this->canConnect($this->getSide(Facing::EAST)); + $connectWest = isset($this->connections[Facing::WEST]); + $connectEast = isset($this->connections[Facing::EAST]); if($connectWest or $connectEast){ //X axis (west/east) @@ -66,8 +81,8 @@ abstract class Fence extends Transparent{ ); } - $connectNorth = $this->canConnect($this->getSide(Facing::NORTH)); - $connectSouth = $this->canConnect($this->getSide(Facing::SOUTH)); + $connectNorth = isset($this->connections[Facing::NORTH]); + $connectSouth = isset($this->connections[Facing::SOUTH]); if($connectNorth or $connectSouth){ //Z axis (north/south) @@ -97,8 +112,4 @@ abstract class Fence extends Transparent{ return $bbs; } - - public function canConnect(Block $block){ - return $block instanceof static or $block instanceof FenceGate or ($block->isSolid() and !$block->isTransparent()); - } } diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index 6ce560c0cb..2ea31779eb 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -118,8 +118,8 @@ abstract class Liquid extends Transparent{ return $block->falling ? 0 : $block->decay; } - public function clearCaches() : void{ - parent::clearCaches(); + public function updateState() : void{ + parent::updateState(); $this->flowVector = null; } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 3914e9133a..85c5396894 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -762,7 +762,7 @@ class Level implements ChunkManager, Metadatable{ Level::getBlockXYZ($index, $x, $y, $z); $block = $this->getBlockAt($x, $y, $z); - $block->clearCaches(); //for blocks like fences, force recalculation of connected AABBs + $block->updateState(); //for blocks like fences, force recalculation of connected AABBs $ev = new BlockUpdateEvent($block); $ev->call(); @@ -1372,6 +1372,7 @@ class Level implements ChunkManager, Metadatable{ $block->y = $y; $block->z = $z; $block->level = $this; + $block->updateState(); if($addToCache and $blockHash !== null){ $this->blockCache[$chunkHash][$blockHash] = $block; @@ -1524,7 +1525,6 @@ class Level implements ChunkManager, Metadatable{ $block = clone $block; $block->position($pos); - $block->clearCaches(); $chunkHash = Level::chunkHash($pos->x >> 4, $pos->z >> 4); $blockHash = Level::blockHash($pos->x, $pos->y, $pos->z); From 3f3bdaeba529677a891a64c3679c3214f08c309f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 28 Oct 2018 20:00:43 +0000 Subject: [PATCH 0294/3224] Use dynamic state detection to localize stateinfo stored in tiles (hack) --- src/pocketmine/block/Bed.php | 32 ++++++++++++++++++------ src/pocketmine/block/Chest.php | 2 +- src/pocketmine/block/EnchantingTable.php | 2 +- src/pocketmine/block/EnderChest.php | 2 +- src/pocketmine/block/FlowerPot.php | 2 +- src/pocketmine/block/Furnace.php | 2 +- src/pocketmine/block/ItemFrame.php | 2 +- src/pocketmine/block/SignPost.php | 2 +- src/pocketmine/block/Skull.php | 27 +++++++++++++++++--- src/pocketmine/block/StandingBanner.php | 2 +- src/pocketmine/tile/Banner.php | 12 ++++----- src/pocketmine/tile/Bed.php | 10 -------- src/pocketmine/tile/NameableTrait.php | 4 +-- src/pocketmine/tile/Skull.php | 23 +++++++---------- src/pocketmine/tile/Tile.php | 20 +++++++-------- 15 files changed, 81 insertions(+), 63 deletions(-) diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 0ddceb3c78..420b19496a 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\Color; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\lang\TranslationContainer; @@ -50,6 +51,8 @@ class Bed extends Transparent{ protected $occupied = false; /** @var bool */ protected $head = false; + /** @var int */ + protected $color = Color::RED; public function __construct(){ @@ -71,6 +74,16 @@ class Bed extends Transparent{ return 0b1111; } + public function updateState() : void{ + parent::updateState(); + //read extra state information from the tile - this is an ugly hack + //TODO: extend this hack to setting block as well so we don't have to deal with tile hacks in the main code + $tile = $this->level->getTile($this); + if($tile instanceof TileBed){ + $this->color = $tile->getColor(); + } + } + public function getHardness() : float{ return 0.2; } @@ -161,6 +174,7 @@ class Bed extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + $this->color = $item->getDamage(); //TODO: replace this with a proper colour getter $down = $this->getSide(Facing::DOWN); if(!$down->isTransparent()){ $this->facing = $player !== null ? Bearing::toFacing($player->getDirection()) : Facing::NORTH; @@ -172,8 +186,15 @@ class Bed extends Transparent{ $nextState->head = true; $this->getLevel()->setBlock($next, $nextState); - Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($this, $face, $item, $player)); - Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($next, $face, $item, $player)); + //TODO: make this happen automatically on block set + $tile1 = Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($this)); + if($tile1 instanceof TileBed){ + $tile1->setColor($this->color); + } + $tile2 = Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($next)); + if($tile2 instanceof TileBed){ + $tile2->setColor($this->color); + } return true; } @@ -191,12 +212,7 @@ class Bed extends Transparent{ } public function getItem() : Item{ - $tile = $this->getLevel()->getTile($this); - if($tile instanceof TileBed){ - return ItemFactory::get($this->getItemId(), $tile->getColor()); - } - - return ItemFactory::get($this->getItemId(), 14); //Red + return ItemFactory::get($this->getItemId(), $this->color); } public function isAffectedBySilkTouch() : bool{ diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index ce41b7a7bf..8b4fea601c 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -93,7 +93,7 @@ class Chest extends Transparent{ } if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - $tile = Tile::createTile(Tile::CHEST, $this->getLevel(), TileChest::createNBT($this, $face, $item, $player)); + $tile = Tile::createTile(Tile::CHEST, $this->getLevel(), TileChest::createNBT($this, $item)); if($chest instanceof TileChest and $tile instanceof TileChest){ $chest->pairWith($tile); diff --git a/src/pocketmine/block/EnchantingTable.php b/src/pocketmine/block/EnchantingTable.php index 6a8b68d907..416ec54594 100644 --- a/src/pocketmine/block/EnchantingTable.php +++ b/src/pocketmine/block/EnchantingTable.php @@ -43,7 +43,7 @@ class EnchantingTable extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - Tile::createTile(Tile::ENCHANT_TABLE, $this->getLevel(), TileEnchantTable::createNBT($this, $face, $item, $player)); + Tile::createTile(Tile::ENCHANT_TABLE, $this->getLevel(), TileEnchantTable::createNBT($this, $item)); return true; } diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index e2d273d4a7..eab6beaffe 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -67,7 +67,7 @@ class EnderChest extends Chest{ } if(Block::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - Tile::createTile(Tile::ENDER_CHEST, $this->getLevel(), TileEnderChest::createNBT($this, $face, $item, $player)); + Tile::createTile(Tile::ENDER_CHEST, $this->getLevel(), TileEnderChest::createNBT($this, $item)); return true; } diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 0399fd26e2..14e48dec40 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -69,7 +69,7 @@ class FlowerPot extends Flowable{ } if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - Tile::createTile(Tile::FLOWER_POT, $this->getLevel(), TileFlowerPot::createNBT($this, $face, $item, $player)); + Tile::createTile(Tile::FLOWER_POT, $this->getLevel(), TileFlowerPot::createNBT($this, $item)); return true; } diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index 820195d6e6..0a7295515e 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -94,7 +94,7 @@ class Furnace extends Solid{ $this->facing = Bearing::toFacing(Bearing::opposite($player->getDirection())); } if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - Tile::createTile(Tile::FURNACE, $this->getLevel(), TileFurnace::createNBT($this, $face, $item, $player)); + Tile::createTile(Tile::FURNACE, $this->getLevel(), TileFurnace::createNBT($this, $item)); return true; } diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index ca9dab19f3..772665c60d 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -85,7 +85,7 @@ class ItemFrame extends Flowable{ $this->facing = $face; if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - Tile::createTile(Tile::ITEM_FRAME, $this->getLevel(), TileItemFrame::createNBT($this, $face, $item, $player)); + Tile::createTile(Tile::ITEM_FRAME, $this->getLevel(), TileItemFrame::createNBT($this, $item)); return true; } diff --git a/src/pocketmine/block/SignPost.php b/src/pocketmine/block/SignPost.php index c55f70662b..8dd99035e5 100644 --- a/src/pocketmine/block/SignPost.php +++ b/src/pocketmine/block/SignPost.php @@ -83,7 +83,7 @@ class SignPost extends Transparent{ } if($ret){ - Tile::createTile(Tile::SIGN, $this->getLevel(), TileSign::createNBT($this, $face, $item, $player)); + Tile::createTile(Tile::SIGN, $this->getLevel(), TileSign::createNBT($this, $item)); return true; } } diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index d19815f4db..c0e42bc9c7 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -39,6 +39,10 @@ class Skull extends Flowable{ /** @var int */ protected $facing = Facing::NORTH; + protected $type = TileSkull::TYPE_SKELETON; + /** @var int */ + protected $rotation = 0; //TODO: split this into floor skull and wall skull handling + public function __construct(){ } @@ -55,6 +59,15 @@ class Skull extends Flowable{ return 0b111; } + public function updateState() : void{ + parent::updateState(); + $tile = $this->level->getTile($this); + if($tile instanceof TileSkull){ + $this->type = $tile->getType(); + $this->rotation = $tile->getRotation(); + } + } + public function getHardness() : float{ return 1; } @@ -74,8 +87,17 @@ class Skull extends Flowable{ } $this->facing = $face; + $this->type = $item->getDamage(); //TODO: replace this with a proper variant getter + if($player !== null and $face === Facing::UP){ + $this->rotation = ((int) floor(($player->yaw * 16 / 360) + 0.5)) & 0xf; + } if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - Tile::createTile(Tile::SKULL, $this->getLevel(), TileSkull::createNBT($this, $face, $item, $player)); + //TODO: make this automatic on block set + $tile = Tile::createTile(Tile::SKULL, $this->getLevel(), TileSkull::createNBT($this)); + if($tile instanceof TileSkull){ + $tile->setRotation($this->rotation); + $tile->setType($this->type); + } return true; } @@ -83,8 +105,7 @@ class Skull extends Flowable{ } public function getItem() : Item{ - $tile = $this->level->getTile($this); - return ItemFactory::get(Item::SKULL, $tile instanceof TileSkull ? $tile->getType() : 0); + return ItemFactory::get(Item::SKULL, $this->type); } public function isAffectedBySilkTouch() : bool{ diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index e4b3ecc3d9..28898faa45 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -83,7 +83,7 @@ class StandingBanner extends Transparent{ } if($ret){ - Tile::createTile(Tile::BANNER, $this->getLevel(), TileBanner::createNBT($this, $face, $item, $player)); + Tile::createTile(Tile::BANNER, $this->getLevel(), TileBanner::createNBT($this, $item)); return true; } } diff --git a/src/pocketmine/tile/Banner.php b/src/pocketmine/tile/Banner.php index e538f58194..6227446193 100644 --- a/src/pocketmine/tile/Banner.php +++ b/src/pocketmine/tile/Banner.php @@ -23,13 +23,12 @@ declare(strict_types=1); namespace pocketmine\tile; +use pocketmine\item\Banner as ItemBanner; use pocketmine\item\Item; -use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; -use pocketmine\Player; class Banner extends Spawnable implements Nameable{ use NameableTrait { @@ -268,15 +267,16 @@ class Banner extends Spawnable implements Nameable{ return $this->patterns; } - protected static function createAdditionalNBT(CompoundTag $nbt, Vector3 $pos, ?int $face = null, ?Item $item = null, ?Player $player = null) : void{ - $nbt->setInt(self::TAG_BASE, $item !== null ? $item->getDamage() & 0x0f : 0); + protected static function createAdditionalNBT(CompoundTag $nbt, ?Item $item = null) : void{ + if($item instanceof ItemBanner){ + $nbt->setInt(self::TAG_BASE, $item->getBaseColor()); - if($item !== null){ + //TODO: clean this mess up if($item->getNamedTag()->hasTag(self::TAG_PATTERNS, ListTag::class)){ $nbt->setTag($item->getNamedTag()->getListTag(self::TAG_PATTERNS)); } - self::createNameNBT($nbt, $pos, $face, $item, $player); + self::createNameNBT($nbt, $item); } } diff --git a/src/pocketmine/tile/Bed.php b/src/pocketmine/tile/Bed.php index b53c3de271..ebcd291f70 100644 --- a/src/pocketmine/tile/Bed.php +++ b/src/pocketmine/tile/Bed.php @@ -23,11 +23,7 @@ declare(strict_types=1); namespace pocketmine\tile; - -use pocketmine\item\Item; -use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\Player; class Bed extends Spawnable{ public const TAG_COLOR = "color"; @@ -54,10 +50,4 @@ class Bed extends Spawnable{ protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ $nbt->setByte(self::TAG_COLOR, $this->color); } - - protected static function createAdditionalNBT(CompoundTag $nbt, Vector3 $pos, ?int $face = null, ?Item $item = null, ?Player $player = null) : void{ - if($item !== null){ - $nbt->setByte(self::TAG_COLOR, $item->getDamage()); - } - } } diff --git a/src/pocketmine/tile/NameableTrait.php b/src/pocketmine/tile/NameableTrait.php index d1a62593c1..b623df8db8 100644 --- a/src/pocketmine/tile/NameableTrait.php +++ b/src/pocketmine/tile/NameableTrait.php @@ -24,10 +24,8 @@ declare(strict_types=1); namespace pocketmine\tile; use pocketmine\item\Item; -use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\StringTag; -use pocketmine\Player; /** * This trait implements most methods in the {@link Nameable} interface. It should only be used by Tiles. @@ -66,7 +64,7 @@ trait NameableTrait{ return $this->customName !== null; } - protected static function createAdditionalNBT(CompoundTag $nbt, Vector3 $pos, ?int $face = null, ?Item $item = null, ?Player $player = null) : void{ + protected static function createAdditionalNBT(CompoundTag $nbt, ?Item $item = null) : void{ if($item !== null and $item->hasCustomName()){ $nbt->setString(Nameable::TAG_CUSTOM_NAME, $item->getCustomName()); } diff --git a/src/pocketmine/tile/Skull.php b/src/pocketmine/tile/Skull.php index bfe0df385f..e49460bdf2 100644 --- a/src/pocketmine/tile/Skull.php +++ b/src/pocketmine/tile/Skull.php @@ -23,11 +23,7 @@ declare(strict_types=1); namespace pocketmine\tile; -use pocketmine\item\Item; -use pocketmine\math\Facing; -use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\Player; class Skull extends Spawnable{ public const TYPE_SKELETON = 0; @@ -66,18 +62,17 @@ class Skull extends Spawnable{ return $this->skullType; } + public function getRotation() : int{ + return $this->skullRotation; + } + + public function setRotation(int $rotation) : void{ + $this->skullRotation = $rotation; + $this->onChanged(); + } + protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ $nbt->setByte(self::TAG_SKULL_TYPE, $this->skullType); $nbt->setByte(self::TAG_ROT, $this->skullRotation); } - - protected static function createAdditionalNBT(CompoundTag $nbt, Vector3 $pos, ?int $face = null, ?Item $item = null, ?Player $player = null) : void{ - $nbt->setByte(self::TAG_SKULL_TYPE, $item !== null ? $item->getDamage() : self::TYPE_SKELETON); - - $rot = 0; - if($face === Facing::UP and $player !== null){ - $rot = floor(($player->yaw * 16 / 360) + 0.5) & 0x0F; - } - $nbt->setByte(self::TAG_ROT, $rot); - } } diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/tile/Tile.php index 2964c8c76c..abe5df44f7 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/tile/Tile.php @@ -35,7 +35,6 @@ use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\StringTag; -use pocketmine\Player; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; @@ -183,14 +182,15 @@ abstract class Tile extends Position{ /** * Creates and returns a CompoundTag containing the necessary information to spawn a tile of this type. * - * @param Vector3 $pos - * @param int|null $face - * @param Item|null $item - * @param Player|null $player + * @param Vector3 $pos + * @param Item|null $item * * @return CompoundTag + * @throws \BadMethodCallException + * @throws \InvalidArgumentException + * @throws \InvalidStateException */ - public static function createNBT(Vector3 $pos, ?int $face = null, ?Item $item = null, ?Player $player = null) : CompoundTag{ + public static function createNBT(Vector3 $pos, ?Item $item = null) : CompoundTag{ if(static::class === self::class){ throw new \BadMethodCallException(__METHOD__ . " must be called from the scope of a child class"); } @@ -201,7 +201,7 @@ abstract class Tile extends Position{ new IntTag(self::TAG_Z, (int) $pos->z) ]); - static::createAdditionalNBT($nbt, $pos, $face, $item, $player); + static::createAdditionalNBT($nbt, $item); if($item !== null){ $customBlockData = $item->getCustomBlockData(); @@ -217,14 +217,12 @@ abstract class Tile extends Position{ /** * Called by createNBT() to allow descendent classes to add their own base NBT using the parameters provided. + * TODO: remove this and add a hook for setting data from items post-place * * @param CompoundTag $nbt - * @param Vector3 $pos - * @param int|null $face * @param Item|null $item - * @param Player|null $player */ - protected static function createAdditionalNBT(CompoundTag $nbt, Vector3 $pos, ?int $face = null, ?Item $item = null, ?Player $player = null) : void{ + protected static function createAdditionalNBT(CompoundTag $nbt, ?Item $item = null) : void{ } From 1170b66fd520f8bcbb6e8335ce65dbf3766c4b35 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Oct 2018 18:20:05 +0000 Subject: [PATCH 0295/3224] Automate creation of tiles when they are used to store block properties --- src/pocketmine/block/Bed.php | 24 +++++----- src/pocketmine/block/Block.php | 30 +++++++----- src/pocketmine/block/CobblestoneWall.php | 4 +- src/pocketmine/block/Door.php | 4 +- src/pocketmine/block/Fence.php | 4 +- src/pocketmine/block/Liquid.php | 4 +- src/pocketmine/block/Skull.php | 25 +++++----- src/pocketmine/level/Level.php | 61 +++++++++++------------- 8 files changed, 76 insertions(+), 80 deletions(-) diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 420b19496a..fcbcbe202a 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -74,16 +74,24 @@ class Bed extends Transparent{ return 0b1111; } - public function updateState() : void{ - parent::updateState(); + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); //read extra state information from the tile - this is an ugly hack - //TODO: extend this hack to setting block as well so we don't have to deal with tile hacks in the main code $tile = $this->level->getTile($this); if($tile instanceof TileBed){ $this->color = $tile->getColor(); } } + public function writeStateToWorld() : void{ + parent::writeStateToWorld(); + //extra block properties storage hack + $tile = Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($this)); + if($tile instanceof TileBed){ + $tile->setColor($this->color); + } + } + public function getHardness() : float{ return 0.2; } @@ -186,16 +194,6 @@ class Bed extends Transparent{ $nextState->head = true; $this->getLevel()->setBlock($next, $nextState); - //TODO: make this happen automatically on block set - $tile1 = Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($this)); - if($tile1 instanceof TileBed){ - $tile1->setColor($this->color); - } - $tile2 = Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($next)); - if($tile2 instanceof TileBed){ - $tile2->setColor($this->color); - } - return true; } } diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index cc6ac4b86d..17bdaaa615 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -149,6 +149,22 @@ class Block extends Position implements BlockIds, Metadatable{ //NOOP } + /** + * Called when this block is created, set, or has a neighbouring block update, to re-detect dynamic properties which + * are not saved on the world. + * + * Clears any cached precomputed objects, such as bounding boxes. Remove any outdated precomputed things such as + * AABBs and force recalculation. + */ + public function readStateFromWorld() : void{ + $this->boundingBox = null; + $this->collisionBoxes = null; + } + + public function writeStateToWorld() : void{ + $this->level->getChunkAtPosition($this)->setBlock($this->x & 0xf, $this->y, $this->z & 0xf, $this->getId(), $this->getDamage()); + } + /** * Returns a bitmask used to extract state bits from block metadata. * @@ -448,7 +464,7 @@ class Block extends Position implements BlockIds, Metadatable{ $this->y = (int) $v->y; $this->z = (int) $v->z; $this->level = $v->level; - $this->updateState(); + $this->readStateFromWorld(); } /** @@ -717,18 +733,6 @@ class Block extends Position implements BlockIds, Metadatable{ return AxisAlignedBB::one(); } - /** - * Called when this block is created, set, or has a neighbouring block update, to re-detect dynamic properties which - * are not saved on the world. - * - * Clears any cached precomputed objects, such as bounding boxes. Remove any outdated precomputed things such as - * AABBs and force recalculation. - */ - public function updateState() : void{ - $this->boundingBox = null; - $this->collisionBoxes = null; - } - /** * @param Vector3 $pos1 * @param Vector3 $pos2 diff --git a/src/pocketmine/block/CobblestoneWall.php b/src/pocketmine/block/CobblestoneWall.php index a944dc20d2..21b0a1f37d 100644 --- a/src/pocketmine/block/CobblestoneWall.php +++ b/src/pocketmine/block/CobblestoneWall.php @@ -48,8 +48,8 @@ class CobblestoneWall extends Transparent{ return 2; } - public function updateState() : void{ - parent::updateState(); + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); foreach(Facing::HORIZONTAL as $facing){ $block = $this->getSide($facing); diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 7191d80a4e..76a67c7fa5 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -69,8 +69,8 @@ abstract class Door extends Transparent{ return 0b1111; } - public function updateState() : void{ - parent::updateState(); + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); //copy door properties from other half $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); diff --git a/src/pocketmine/block/Fence.php b/src/pocketmine/block/Fence.php index 44847f58d9..caad4df8e6 100644 --- a/src/pocketmine/block/Fence.php +++ b/src/pocketmine/block/Fence.php @@ -34,8 +34,8 @@ abstract class Fence extends Transparent{ return 0.25; } - public function updateState() : void{ - parent::updateState(); + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); foreach(Facing::HORIZONTAL as $facing){ $block = $this->getSide($facing); diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index 2ea31779eb..01e369ee31 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -118,8 +118,8 @@ abstract class Liquid extends Transparent{ return $block->falling ? 0 : $block->decay; } - public function updateState() : void{ - parent::updateState(); + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); $this->flowVector = null; } diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index c0e42bc9c7..b49017bb5d 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -59,8 +59,8 @@ class Skull extends Flowable{ return 0b111; } - public function updateState() : void{ - parent::updateState(); + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); $tile = $this->level->getTile($this); if($tile instanceof TileSkull){ $this->type = $tile->getType(); @@ -68,6 +68,15 @@ class Skull extends Flowable{ } } + public function writeStateToWorld() : void{ + parent::writeStateToWorld(); + $tile = Tile::createTile(Tile::SKULL, $this->getLevel(), TileSkull::createNBT($this)); + if($tile instanceof TileSkull){ + $tile->setRotation($this->rotation); + $tile->setType($this->type); + } + } + public function getHardness() : float{ return 1; } @@ -91,17 +100,7 @@ class Skull extends Flowable{ if($player !== null and $face === Facing::UP){ $this->rotation = ((int) floor(($player->yaw * 16 / 360) + 0.5)) & 0xf; } - if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - //TODO: make this automatic on block set - $tile = Tile::createTile(Tile::SKULL, $this->getLevel(), TileSkull::createNBT($this)); - if($tile instanceof TileSkull){ - $tile->setRotation($this->rotation); - $tile->setType($this->type); - } - return true; - } - - return false; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function getItem() : Item{ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 85c5396894..89b666f8dd 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -762,7 +762,7 @@ class Level implements ChunkManager, Metadatable{ Level::getBlockXYZ($index, $x, $y, $z); $block = $this->getBlockAt($x, $y, $z); - $block->updateState(); //for blocks like fences, force recalculation of connected AABBs + $block->readStateFromWorld(); //for blocks like fences, force recalculation of connected AABBs $ev = new BlockUpdateEvent($block); $ev->call(); @@ -1372,7 +1372,7 @@ class Level implements ChunkManager, Metadatable{ $block->y = $y; $block->z = $z; $block->level = $this; - $block->updateState(); + $block->readStateFromWorld(); if($addToCache and $blockHash !== null){ $this->blockCache[$chunkHash][$blockHash] = $block; @@ -1517,51 +1517,46 @@ class Level implements ChunkManager, Metadatable{ $this->timings->setBlock->startTiming(); - if($this->getChunkAtPosition($pos, true)->setBlock($pos->x & 0x0f, $pos->y, $pos->z & 0x0f, $block->getId(), $block->getDamage())){ - if(!($pos instanceof Position)){ - $pos = $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z); - } + if(!($pos instanceof Position)){ + $pos = $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z); + } - $block = clone $block; + $block = clone $block; - $block->position($pos); + $block->position($pos); + $block->writeStateToWorld(); - $chunkHash = Level::chunkHash($pos->x >> 4, $pos->z >> 4); - $blockHash = Level::blockHash($pos->x, $pos->y, $pos->z); + $chunkHash = Level::chunkHash($pos->x >> 4, $pos->z >> 4); + $blockHash = Level::blockHash($pos->x, $pos->y, $pos->z); - unset($this->blockCache[$chunkHash][$blockHash]); + unset($this->blockCache[$chunkHash][$blockHash]); - if(!isset($this->changedBlocks[$chunkHash])){ - $this->changedBlocks[$chunkHash] = []; - } - $this->changedBlocks[$chunkHash][$blockHash] = $block; + if(!isset($this->changedBlocks[$chunkHash])){ + $this->changedBlocks[$chunkHash] = []; + } + $this->changedBlocks[$chunkHash][$blockHash] = $block; - foreach($this->getChunkLoaders($pos->x >> 4, $pos->z >> 4) as $loader){ - $loader->onBlockChanged($block); - } + foreach($this->getChunkLoaders($pos->x >> 4, $pos->z >> 4) as $loader){ + $loader->onBlockChanged($block); + } - if($update){ - $this->updateAllLight($block); + if($update){ + $this->updateAllLight($block); - $ev = new BlockUpdateEvent($block); - $ev->call(); - if(!$ev->isCancelled()){ - foreach($this->getNearbyEntities(AxisAlignedBB::one()->offset($block->x, $block->y, $block->z)->expand(1, 1, 1)) as $entity){ - $entity->onNearbyBlockChange(); - } - $ev->getBlock()->onNearbyBlockChange(); - $this->scheduleNeighbourBlockUpdates($pos); + $ev = new BlockUpdateEvent($block); + $ev->call(); + if(!$ev->isCancelled()){ + foreach($this->getNearbyEntities(AxisAlignedBB::one()->offset($block->x, $block->y, $block->z)->expand(1, 1, 1)) as $entity){ + $entity->onNearbyBlockChange(); } + $ev->getBlock()->onNearbyBlockChange(); + $this->scheduleNeighbourBlockUpdates($pos); } - - $this->timings->setBlock->stopTiming(); - - return true; } $this->timings->setBlock->stopTiming(); - return false; + return true; } /** From d426d18b77d81d83b6b95141b71ef183bda38ace Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 23 Nov 2018 16:14:39 +0000 Subject: [PATCH 0296/3224] Add dynamic shape property for stairs --- src/pocketmine/block/Stair.php | 44 ++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index cdf4019cae..2b24031305 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -31,10 +31,18 @@ use pocketmine\math\Vector3; use pocketmine\Player; abstract class Stair extends Transparent{ + private const SHAPE_STRAIGHT = "straight"; + private const SHAPE_INNER_LEFT = "inner_left"; + private const SHAPE_INNER_RIGHT = "inner_right"; + private const SHAPE_OUTER_LEFT = "outer_left"; + private const SHAPE_OUTER_RIGHT = "outer_right"; + /** @var int */ protected $facing = Facing::NORTH; /** @var bool */ protected $upsideDown = false; + /** @var string */ + protected $shape = self::SHAPE_STRAIGHT; protected function writeStateToMeta() : int{ return (5 - $this->facing) | ($this->upsideDown ? 0x04 : 0); @@ -49,6 +57,19 @@ abstract class Stair extends Transparent{ return 0b111; } + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); + + $clockwise = Facing::rotate($this->facing, Facing::AXIS_Y, true); + if(($backFacing = $this->getPossibleCornerFacing(false)) !== null){ + $this->shape = $backFacing === $clockwise ? self::SHAPE_OUTER_RIGHT : self::SHAPE_OUTER_LEFT; + }elseif(($frontFacing = $this->getPossibleCornerFacing(true)) !== null){ + $this->shape = $frontFacing === $clockwise ? self::SHAPE_INNER_RIGHT : self::SHAPE_INNER_LEFT; + }else{ + $this->shape = self::SHAPE_STRAIGHT; + } + } + protected function recalculateCollisionBoxes() : array{ $minYSlab = $this->upsideDown ? 0.5 : 0; @@ -61,15 +82,14 @@ abstract class Stair extends Transparent{ $topStep = new AxisAlignedBB(0, $minY, 0, 1, $minY + 0.5, 1); $topStep->trim(Facing::opposite($this->facing), 0.5); - /** @var Stair $corner */ - if(($backFacing = $this->getPossibleCornerFacing(false)) !== null){ - $topStep->trim(Facing::opposite($backFacing), 0.5); - }elseif(($frontFacing = $this->getPossibleCornerFacing(true)) !== null){ + if($this->shape === self::SHAPE_OUTER_LEFT or $this->shape === self::SHAPE_OUTER_RIGHT){ + $topStep->trim(Facing::rotate($this->facing, Facing::AXIS_Y, $this->shape === self::SHAPE_OUTER_LEFT), 0.5); + }elseif($this->shape === self::SHAPE_INNER_LEFT or $this->shape === self::SHAPE_INNER_RIGHT){ //add an extra cube $extraCube = new AxisAlignedBB(0, $minY, 0, 1, $minY + 0.5, 1); $bbs[] = $extraCube - ->trim($this->facing, 0.5) - ->trim(Facing::opposite($frontFacing), 0.5); + ->trim($this->facing, 0.5) //avoid overlapping with main step + ->trim(Facing::rotate($this->facing, Facing::AXIS_Y, $this->shape === self::SHAPE_INNER_LEFT), 0.5); } $bbs[] = $topStep; @@ -79,13 +99,11 @@ abstract class Stair extends Transparent{ private function getPossibleCornerFacing(bool $oppositeFacing) : ?int{ $side = $this->getSide($oppositeFacing ? Facing::opposite($this->facing) : $this->facing); - if($side instanceof Stair and $side->upsideDown === $this->upsideDown and ( - $side->facing === Facing::rotate($this->facing, Facing::AXIS_Y, true) or - $side->facing === Facing::rotate($this->facing, Facing::AXIS_Y, false)) - ){ - return $side->facing; - } - return null; + return ( + $side instanceof Stair and + $side->upsideDown === $this->upsideDown and + Facing::axis($side->facing) !== Facing::axis($this->facing) //perpendicular + ) ? $side->facing : null; } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ From 0fec58730b82aeeb1c5bf7d30e611fa564cc17a7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 24 Nov 2018 17:35:56 +0000 Subject: [PATCH 0297/3224] Level: fixed recursion bug when reading dynamic states calculating dynamic states in some cases requires getting properties from neighbouring blocks, but getting these blocks also causes their dynamic states to be calculated, leading to a bouncing recursion. This change allows retrieving blocks without calculating dynamic state information, if the call was generated by calculating dynamic state information. Since these blocks are incomplete, they should not be cached and are only used to allow another adjacent block to complete its state. It is therefore not possible for a block's dynamic states to depend on another block's dynamic states. This recursion bug was observable by running /gc and walking into a door, which would cause the server to freeze and crash. --- src/pocketmine/level/Level.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 89b666f8dd..67617f40c8 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1372,7 +1372,19 @@ class Level implements ChunkManager, Metadatable{ $block->y = $y; $block->z = $z; $block->level = $this; - $block->readStateFromWorld(); + + static $dynamicStateRead = false; + + if($dynamicStateRead){ + //this call was generated by a parent getBlock() call calculating dynamic stateinfo + //don't calculate dynamic state and don't add to block cache (since it won't have dynamic state calculated). + //this ensures that it's impossible for dynamic state properties to recursively depend on each other. + $addToCache = false; + }else{ + $dynamicStateRead = true; + $block->readStateFromWorld(); + $dynamicStateRead = false; + } if($addToCache and $blockHash !== null){ $this->blockCache[$chunkHash][$blockHash] = $block; From fcd81ada04ec3d0920b58ed2b0e8dcf5165f2527 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 24 Nov 2018 17:48:40 +0000 Subject: [PATCH 0298/3224] Make Thin use dynamic state properties --- src/pocketmine/block/Thin.php | 97 ++++++++++++++++------------------- 1 file changed, 44 insertions(+), 53 deletions(-) diff --git a/src/pocketmine/block/Thin.php b/src/pocketmine/block/Thin.php index 92f3e31b5c..fbdf658158 100644 --- a/src/pocketmine/block/Thin.php +++ b/src/pocketmine/block/Thin.php @@ -27,80 +27,71 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; abstract class Thin extends Transparent{ + /** @var bool[] facing => dummy */ + protected $connections = []; + + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); + + foreach(Facing::HORIZONTAL as $facing){ + $side = $this->getSide($facing); + //FIXME: currently there's no proper way to tell if a block is a full-block, so we check the bounding box size + if($side instanceof Thin or ($bb = $side->getBoundingBox()) !== null and $bb->getAverageEdgeLength() >= 1){ + $this->connections[$facing] = true; + }else{ + unset($this->connections[$facing]); + } + } + } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - $width = 0.5 - 0.125 / 2; - - return new AxisAlignedBB( - ($this->canConnect($this->getSide(Facing::WEST)) ? 0 : $width), - 0, - ($this->canConnect($this->getSide(Facing::NORTH)) ? 0 : $width), - 1 - ($this->canConnect($this->getSide(Facing::EAST)) ? 0 : $width), - 1, - 1 - ($this->canConnect($this->getSide(Facing::SOUTH)) ? 0 : $width) - ); + $bb = new AxisAlignedBB(0, 0, 0, 1, 1, 1); + foreach(Facing::HORIZONTAL as $facing){ + if(!isset($this->connections[$facing])){ + $bb->trim($facing, 7 / 16); + } + } + return $bb; } protected function recalculateCollisionBoxes() : array{ - $inset = 0.5 - 0.125 / 2; + $inset = 7 / 16; /** @var AxisAlignedBB[] $bbs */ $bbs = []; - $connectWest = $this->canConnect($this->getSide(Facing::WEST)); - $connectEast = $this->canConnect($this->getSide(Facing::EAST)); + if(isset($this->connections[Facing::WEST]) or isset($this->connections[Facing::EAST])){ + $bb = new AxisAlignedBB(0, 0, 0, 1, 1, 1); + $bb->squash(Facing::AXIS_Z, $inset); - if($connectWest or $connectEast){ - //X axis (west/east) - $bbs[] = new AxisAlignedBB( - ($connectWest ? 0 : $inset), - 0, - $inset, - 1 - ($connectEast ? 0 : $inset), - 1, - 1 - $inset - ); + if(!isset($this->connections[Facing::WEST])){ + $bb->trim(Facing::WEST, $inset); + }elseif(!isset($this->connections[Facing::EAST])){ + $bb->trim(Facing::EAST, $inset); + } + $bbs[] = $bb; } - $connectNorth = $this->canConnect($this->getSide(Facing::NORTH)); - $connectSouth = $this->canConnect($this->getSide(Facing::SOUTH)); + if(isset($this->connections[Facing::NORTH]) or isset($this->connections[Facing::SOUTH])){ + $bb = new AxisAlignedBB(0, 0, 0, 1, 1, 1); + $bb->squash(Facing::AXIS_X, $inset); - if($connectNorth or $connectSouth){ - //Z axis (north/south) - $bbs[] = new AxisAlignedBB( - $inset, - 0, - ($connectNorth ? 0 : $inset), - 1 - $inset, - 1, - 1 - ($connectSouth ? 0 : $inset) - ); + if(!isset($this->connections[Facing::NORTH])){ + $bb->trim(Facing::NORTH, $inset); + }elseif(!isset($this->connections[Facing::SOUTH])){ + $bb->trim(Facing::SOUTH, $inset); + } + $bbs[] = $bb; } if(empty($bbs)){ //centre post AABB (only needed if not connected on any axis - other BBs overlapping will do this if any connections are made) + $bb = new AxisAlignedBB(0, 0, 0, 1, 1, 1); return [ - new AxisAlignedBB( - $inset, - 0, - $inset, - 1 - $inset, - 1, - 1 - $inset - ) + $bb->contract($inset, 0, $inset) ]; } return $bbs; } - - public function canConnect(Block $block) : bool{ - if($block instanceof Thin){ - return true; - } - - //FIXME: currently there's no proper way to tell if a block is a full-block, so we check the bounding box size - $bb = $block->getBoundingBox(); - return $bb !== null and $bb->getAverageEdgeLength() >= 1; - } } From 7ddcd2941b14661c140bfc96d7b1194c0e3de10e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 24 Nov 2018 19:49:15 +0000 Subject: [PATCH 0299/3224] More AxisAlignedBB::one() usages --- src/pocketmine/block/Thin.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/block/Thin.php b/src/pocketmine/block/Thin.php index fbdf658158..fe048415d9 100644 --- a/src/pocketmine/block/Thin.php +++ b/src/pocketmine/block/Thin.php @@ -45,7 +45,7 @@ abstract class Thin extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - $bb = new AxisAlignedBB(0, 0, 0, 1, 1, 1); + $bb = AxisAlignedBB::one(); foreach(Facing::HORIZONTAL as $facing){ if(!isset($this->connections[$facing])){ $bb->trim($facing, 7 / 16); @@ -61,8 +61,7 @@ abstract class Thin extends Transparent{ $bbs = []; if(isset($this->connections[Facing::WEST]) or isset($this->connections[Facing::EAST])){ - $bb = new AxisAlignedBB(0, 0, 0, 1, 1, 1); - $bb->squash(Facing::AXIS_Z, $inset); + $bb = AxisAlignedBB::one()->squash(Facing::AXIS_Z, $inset); if(!isset($this->connections[Facing::WEST])){ $bb->trim(Facing::WEST, $inset); @@ -73,8 +72,7 @@ abstract class Thin extends Transparent{ } if(isset($this->connections[Facing::NORTH]) or isset($this->connections[Facing::SOUTH])){ - $bb = new AxisAlignedBB(0, 0, 0, 1, 1, 1); - $bb->squash(Facing::AXIS_X, $inset); + $bb = AxisAlignedBB::one()->squash(Facing::AXIS_X, $inset); if(!isset($this->connections[Facing::NORTH])){ $bb->trim(Facing::NORTH, $inset); @@ -86,9 +84,8 @@ abstract class Thin extends Transparent{ if(empty($bbs)){ //centre post AABB (only needed if not connected on any axis - other BBs overlapping will do this if any connections are made) - $bb = new AxisAlignedBB(0, 0, 0, 1, 1, 1); return [ - $bb->contract($inset, 0, $inset) + AxisAlignedBB::one()->contract($inset, 0, $inset) ]; } From 7399e9036af7cdcbbb346ea50bcb599640e76a67 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Nov 2018 14:53:57 +0000 Subject: [PATCH 0300/3224] Block: add method isSameState() to allow black-box comparison of blockstates --- src/pocketmine/block/Block.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 17bdaaa615..0c1fd4d43b 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -193,6 +193,17 @@ class Block extends Position implements BlockIds, Metadatable{ return $this->getId() === $other->getId() and $this->getVariant() === $other->getVariant(); } + /** + * Returns whether the given block has the same type and properties as this block. + * + * @param Block $other + * + * @return bool + */ + public function isSameState(Block $other) : bool{ + return $this->isSameType($other) and $this->writeStateToMeta() === $other->writeStateToMeta(); + } + /** * AKA: Block->isPlaceable * @return bool From d8ea8fa0f07f19a266ab5713427d06206435b279 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Nov 2018 14:55:12 +0000 Subject: [PATCH 0301/3224] Use Block objects more instead of legacy ID/meta crap --- src/pocketmine/entity/object/FallingBlock.php | 11 ++----- .../entity/projectile/Projectile.php | 33 +++++++------------ 2 files changed, 15 insertions(+), 29 deletions(-) diff --git a/src/pocketmine/entity/object/FallingBlock.php b/src/pocketmine/entity/object/FallingBlock.php index a73d68eb18..f03ff9e719 100644 --- a/src/pocketmine/entity/object/FallingBlock.php +++ b/src/pocketmine/entity/object/FallingBlock.php @@ -29,7 +29,6 @@ use pocketmine\block\Fallable; use pocketmine\entity\Entity; use pocketmine\event\entity\EntityBlockChangeEvent; use pocketmine\event\entity\EntityDamageEvent; -use pocketmine\item\ItemFactory; use pocketmine\level\Position; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; @@ -111,7 +110,7 @@ class FallingBlock extends Entity{ $block = $this->level->getBlock($pos); if($block->getId() > 0 and $block->isTransparent() and !$block->canBeReplaced()){ //FIXME: anvils are supposed to destroy torches - $this->getLevel()->dropItem($this, ItemFactory::get($this->getBlock(), $this->getDamage())); + $this->getLevel()->dropItem($this, $this->block->getItem()); }else{ $ev = new EntityBlockChangeEvent($this, $block, $blockTarget ?? $this->block); $ev->call(); @@ -126,12 +125,8 @@ class FallingBlock extends Entity{ return $hasUpdate; } - public function getBlock() : int{ - return $this->block->getId(); - } - - public function getDamage() : int{ - return $this->block->getDamage(); + public function getBlock() : Block{ + return $this->block; } public function saveNBT() : CompoundTag{ diff --git a/src/pocketmine/entity/projectile/Projectile.php b/src/pocketmine/entity/projectile/Projectile.php index b7fcfbb8a6..1acb87e9db 100644 --- a/src/pocketmine/entity/projectile/Projectile.php +++ b/src/pocketmine/entity/projectile/Projectile.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity\projectile; use pocketmine\block\Block; +use pocketmine\block\BlockFactory; use pocketmine\entity\Entity; use pocketmine\entity\Living; use pocketmine\event\entity\EntityCombustByEntityEvent; @@ -34,6 +35,7 @@ use pocketmine\event\entity\ProjectileHitBlockEvent; use pocketmine\event\entity\ProjectileHitEntityEvent; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\level\Level; +use pocketmine\level\Position; use pocketmine\math\RayTraceResult; use pocketmine\math\Vector3; use pocketmine\math\VoxelRayTrace; @@ -49,12 +51,8 @@ abstract class Projectile extends Entity{ /** @var float */ protected $damage = 0.0; - /** @var Vector3|null */ + /** @var Block|null */ protected $blockHit; - /** @var int|null */ - protected $blockHitId; - /** @var int|null */ - protected $blockHitData; public function __construct(Level $level, CompoundTag $nbt, ?Entity $shootingEntity = null){ parent::__construct($level, $nbt); @@ -77,12 +75,12 @@ abstract class Projectile extends Entity{ $this->damage = $nbt->getDouble("damage", $this->damage); do{ - $blockHit = null; + $blockPos = null; $blockId = null; $blockData = null; if($nbt->hasTag("tileX", IntTag::class) and $nbt->hasTag("tileY", IntTag::class) and $nbt->hasTag("tileZ", IntTag::class)){ - $blockHit = new Vector3($nbt->getInt("tileX"), $nbt->getInt("tileY"), $nbt->getInt("tileZ")); + $blockPos = new Position($nbt->getInt("tileX"), $nbt->getInt("tileY"), $nbt->getInt("tileZ"), $this->level); }else{ break; } @@ -99,9 +97,7 @@ abstract class Projectile extends Entity{ break; } - $this->blockHit = $blockHit; - $this->blockHitId = $blockId; - $this->blockHitData = $blockData; + $this->blockHit = BlockFactory::get($blockId, $blockData, $blockPos); }while(false); } @@ -151,8 +147,8 @@ abstract class Projectile extends Entity{ $nbt->setInt("tileZ", $this->blockHit->z); //we intentionally use different ones to PC because we don't have stringy IDs - $nbt->setInt("blockId", $this->blockHitId); - $nbt->setByte("blockData", $this->blockHitData); + $nbt->setInt("blockId", $this->blockHit->getId()); + $nbt->setByte("blockData", $this->blockHit->getDamage()); } return $nbt; @@ -163,11 +159,8 @@ abstract class Projectile extends Entity{ } public function onNearbyBlockChange() : void{ - if($this->blockHit !== null){ - $blockIn = $this->level->getBlockAt($this->blockHit->x, $this->blockHit->y, $this->blockHit->z); - if($blockIn->getId() !== $this->blockHitId or $blockIn->getDamage() !== $this->blockHitData){ - $this->blockHit = $this->blockHitId = $this->blockHitData = null; - } + if($this->blockHit !== null and !$this->blockHit->isSameState($this->level->getBlock($this->blockHit))){ + $this->blockHit = null; } parent::onNearbyBlockChange(); @@ -257,7 +250,7 @@ abstract class Projectile extends Entity{ $this->motion->x = $this->motion->y = $this->motion->z = 0; }else{ $this->isCollided = $this->onGround = false; - $this->blockHit = $this->blockHitId = $this->blockHitData = null; + $this->blockHit = null; //recompute angles... $f = sqrt(($this->motion->x ** 2) + ($this->motion->z ** 2)); @@ -334,8 +327,6 @@ abstract class Projectile extends Entity{ * @param RayTraceResult $hitResult */ protected function onHitBlock(Block $blockHit, RayTraceResult $hitResult) : void{ - $this->blockHit = $blockHit->asVector3(); - $this->blockHitId = $blockHit->getId(); - $this->blockHitData = $blockHit->getDamage(); + $this->blockHit = clone $blockHit; } } From d0e2cdb54ce85627af53c5b21f5ee22fbe137153 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Nov 2018 15:58:24 +0000 Subject: [PATCH 0302/3224] Tile: remove server field it would be nice to get rid of the server dependency entirely... perhaps craftingmanager should be a singleton? it's contextless after all... --- src/pocketmine/tile/Furnace.php | 2 +- src/pocketmine/tile/Tile.php | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/pocketmine/tile/Furnace.php b/src/pocketmine/tile/Furnace.php index c276d326af..aef45ecb0e 100644 --- a/src/pocketmine/tile/Furnace.php +++ b/src/pocketmine/tile/Furnace.php @@ -174,7 +174,7 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ $fuel = $this->inventory->getFuel(); $raw = $this->inventory->getSmelting(); $product = $this->inventory->getResult(); - $smelt = $this->server->getCraftingManager()->matchFurnaceRecipe($raw); + $smelt = $this->level->getServer()->getCraftingManager()->matchFurnaceRecipe($raw); $canSmelt = ($smelt instanceof FurnaceRecipe and $raw->getCount() > 0 and (($smelt->getResult()->equals($product) and $product->getCount() < $product->getMaxStackSize()) or $product->isNull())); if($this->burnTime <= 0 and $canSmelt and $fuel->getFuelTime() > 0 and $fuel->getCount() > 0){ diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/tile/Tile.php index abe5df44f7..3d629a978e 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/tile/Tile.php @@ -69,8 +69,6 @@ abstract class Tile extends Position{ public $name; /** @var bool */ public $closed = false; - /** @var Server */ - protected $server; /** @var TimingsHandler */ protected $timings; @@ -140,7 +138,6 @@ abstract class Tile extends Position{ public function __construct(Level $level, CompoundTag $nbt){ $this->timings = Timings::getTileEntityTimings($this); - $this->server = $level->getServer(); $this->name = ""; parent::__construct($nbt->getInt(self::TAG_X), $nbt->getInt(self::TAG_Y), $nbt->getInt(self::TAG_Z), $level); From a9a647855b7097a3f0756cb904e13f08a5b02766 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Nov 2018 17:08:09 +0000 Subject: [PATCH 0303/3224] Remove useless Recipe interface --- src/pocketmine/inventory/CraftingManager.php | 13 ++------- src/pocketmine/inventory/CraftingRecipe.php | 2 +- src/pocketmine/inventory/FurnaceRecipe.php | 6 +--- src/pocketmine/inventory/Recipe.php | 29 -------------------- src/pocketmine/inventory/ShapedRecipe.php | 4 --- src/pocketmine/inventory/ShapelessRecipe.php | 4 --- 6 files changed, 5 insertions(+), 53 deletions(-) delete mode 100644 src/pocketmine/inventory/Recipe.php diff --git a/src/pocketmine/inventory/CraftingManager.php b/src/pocketmine/inventory/CraftingManager.php index b378af8ef7..f8aa119c4a 100644 --- a/src/pocketmine/inventory/CraftingManager.php +++ b/src/pocketmine/inventory/CraftingManager.php @@ -52,13 +52,13 @@ class CraftingManager{ foreach($recipes as $recipe){ switch($recipe["type"]){ case 0: - $this->registerRecipe(new ShapelessRecipe( + $this->registerShapelessRecipe(new ShapelessRecipe( array_map(function(array $data) : Item{ return Item::jsonDeserialize($data); }, $recipe["input"]), array_map(function(array $data) : Item{ return Item::jsonDeserialize($data); }, $recipe["output"]) )); break; case 1: - $this->registerRecipe(new ShapedRecipe( + $this->registerShapedRecipe(new ShapedRecipe( $recipe["shape"], array_map(function(array $data) : Item{ return Item::jsonDeserialize($data); }, $recipe["input"]), array_map(function(array $data) : Item{ return Item::jsonDeserialize($data); }, $recipe["output"]) @@ -68,7 +68,7 @@ class CraftingManager{ case 3: $result = $recipe["output"]; $resultItem = Item::jsonDeserialize($result); - $this->registerRecipe(new FurnaceRecipe($resultItem, ItemFactory::get($recipe["inputId"], $recipe["inputDamage"] ?? -1, 1))); + $this->registerFurnaceRecipe(new FurnaceRecipe($resultItem, ItemFactory::get($recipe["inputId"], $recipe["inputDamage"] ?? -1, 1))); break; default: break; @@ -282,11 +282,4 @@ class CraftingManager{ public function matchFurnaceRecipe(Item $input) : ?FurnaceRecipe{ return $this->furnaceRecipes[$input->getId() . ":" . $input->getDamage()] ?? $this->furnaceRecipes[$input->getId() . ":?"] ?? null; } - - /** - * @param Recipe $recipe - */ - public function registerRecipe(Recipe $recipe) : void{ - $recipe->registerToCraftingManager($this); - } } diff --git a/src/pocketmine/inventory/CraftingRecipe.php b/src/pocketmine/inventory/CraftingRecipe.php index df37ca6e64..1ea9d71e74 100644 --- a/src/pocketmine/inventory/CraftingRecipe.php +++ b/src/pocketmine/inventory/CraftingRecipe.php @@ -25,7 +25,7 @@ namespace pocketmine\inventory; use pocketmine\item\Item; -interface CraftingRecipe extends Recipe{ +interface CraftingRecipe{ /** * Returns a list of items needed to craft this recipe. This MUST NOT include Air items or items with a zero count. * diff --git a/src/pocketmine/inventory/FurnaceRecipe.php b/src/pocketmine/inventory/FurnaceRecipe.php index c8ed4be613..bcd333f8a0 100644 --- a/src/pocketmine/inventory/FurnaceRecipe.php +++ b/src/pocketmine/inventory/FurnaceRecipe.php @@ -25,7 +25,7 @@ namespace pocketmine\inventory; use pocketmine\item\Item; -class FurnaceRecipe implements Recipe{ +class FurnaceRecipe{ /** @var Item */ private $output; @@ -62,8 +62,4 @@ class FurnaceRecipe implements Recipe{ public function getResult() : Item{ return clone $this->output; } - - public function registerToCraftingManager(CraftingManager $manager) : void{ - $manager->registerFurnaceRecipe($this); - } } diff --git a/src/pocketmine/inventory/Recipe.php b/src/pocketmine/inventory/Recipe.php deleted file mode 100644 index 883eea6d94..0000000000 --- a/src/pocketmine/inventory/Recipe.php +++ /dev/null @@ -1,29 +0,0 @@ -shape; } - public function registerToCraftingManager(CraftingManager $manager) : void{ - $manager->registerShapedRecipe($this); - } - /** * @param CraftingGrid $grid * @param bool $reverse diff --git a/src/pocketmine/inventory/ShapelessRecipe.php b/src/pocketmine/inventory/ShapelessRecipe.php index 7db3d3c132..01fd17d727 100644 --- a/src/pocketmine/inventory/ShapelessRecipe.php +++ b/src/pocketmine/inventory/ShapelessRecipe.php @@ -109,10 +109,6 @@ class ShapelessRecipe implements CraftingRecipe{ return $count; } - public function registerToCraftingManager(CraftingManager $manager) : void{ - $manager->registerShapelessRecipe($this); - } - /** * @param CraftingGrid $grid * From 8fe3f6ef1b8af15e48b74c3484f56dbf75fd078a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Nov 2018 17:13:35 +0000 Subject: [PATCH 0304/3224] Player now drops the contents of temporary inventories these inventories are just glorified crafting tables. --- src/pocketmine/inventory/AnvilInventory.php | 5 ++++- src/pocketmine/inventory/EnchantInventory.php | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/inventory/AnvilInventory.php b/src/pocketmine/inventory/AnvilInventory.php index 7d74fdc01e..c13d872513 100644 --- a/src/pocketmine/inventory/AnvilInventory.php +++ b/src/pocketmine/inventory/AnvilInventory.php @@ -59,6 +59,9 @@ class AnvilInventory extends ContainerInventory{ public function onClose(Player $who) : void{ parent::onClose($who); - $this->dropContents($this->holder->getLevel(), $this->holder->add(0.5, 0.5, 0.5)); + foreach($this->getContents() as $item){ + $who->dropItem($item); + } + $this->clearAll(); } } diff --git a/src/pocketmine/inventory/EnchantInventory.php b/src/pocketmine/inventory/EnchantInventory.php index e6f9cf1182..059b229b64 100644 --- a/src/pocketmine/inventory/EnchantInventory.php +++ b/src/pocketmine/inventory/EnchantInventory.php @@ -59,6 +59,9 @@ class EnchantInventory extends ContainerInventory{ public function onClose(Player $who) : void{ parent::onClose($who); - $this->dropContents($this->holder->getLevel(), $this->holder->add(0.5, 0.5, 0.5)); + foreach($this->getContents() as $item){ + $who->dropItem($item); + } + $this->clearAll(); } } From c809365c39060724e0e58ade49dfb8afd8c78579 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Nov 2018 19:22:00 +0000 Subject: [PATCH 0305/3224] Make RedstoneRail class abstract --- src/pocketmine/block/RedstoneRail.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/RedstoneRail.php b/src/pocketmine/block/RedstoneRail.php index 0ea1ab7ad8..4592bb1c69 100644 --- a/src/pocketmine/block/RedstoneRail.php +++ b/src/pocketmine/block/RedstoneRail.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -class RedstoneRail extends BaseRail{ +abstract class RedstoneRail extends BaseRail{ protected const FLAG_POWERED = 0x08; /** @var bool */ From 328ee40d5dd2c279abf8d63dc67e6e0522006148 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Nov 2018 19:52:45 +0000 Subject: [PATCH 0306/3224] Bring back support for all-sided logs, properly this time --- src/pocketmine/block/BlockFactory.php | 3 ++- src/pocketmine/block/Log.php | 30 +++++++++++++++++++++++++++ src/pocketmine/block/Wood.php | 4 ---- 3 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 src/pocketmine/block/Log.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 7b04d3a78d..b6c1a9efde 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -94,7 +94,8 @@ class BlockFactory{ foreach(WoodType::ALL as $type){ //TODO: find a better way to deal with this split - self::registerBlock(new Wood($type >= 4 ? Block::WOOD2 : Block::WOOD, $type & 0x03, WoodType::NAMES[$type] . " Wood")); + self::registerBlock(new Log($type >= 4 ? Block::WOOD2 : Block::WOOD, $type & 0x03, WoodType::NAMES[$type] . " Log")); + self::registerBlock(new Wood($type >= 4 ? Block::WOOD2 : Block::WOOD, ($type & 0x03) | 0b1100, WoodType::NAMES[$type] . " Wood")); self::registerBlock(new Leaves($type >= 4 ? Block::LEAVES2 : Block::LEAVES, $type & 0x03, $type, WoodType::NAMES[$type] . " Leaves")); } diff --git a/src/pocketmine/block/Log.php b/src/pocketmine/block/Log.php new file mode 100644 index 0000000000..ca9346cab9 --- /dev/null +++ b/src/pocketmine/block/Log.php @@ -0,0 +1,30 @@ + Date: Mon, 26 Nov 2018 14:29:06 +0000 Subject: [PATCH 0307/3224] Fixed population artifacts always generating in the bottom subchunk, closes #2538 --- src/pocketmine/level/SimpleChunkManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/level/SimpleChunkManager.php b/src/pocketmine/level/SimpleChunkManager.php index 7243881786..74d071a2f8 100644 --- a/src/pocketmine/level/SimpleChunkManager.php +++ b/src/pocketmine/level/SimpleChunkManager.php @@ -75,7 +75,7 @@ class SimpleChunkManager implements ChunkManager{ public function setBlockIdAndDataAt(int $x, int $y, int $z, int $id, int $data) : void{ if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ - $chunk->setBlock($x & 0xf, $y & 0xf, $z & 0xf, $id, $data); + $chunk->setBlock($x & 0xf, $y, $z & 0xf, $id, $data); } } From 650a2eee4b3049b60b46d0021b84f43cb2f7d6e5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 27 Nov 2018 20:04:47 +0000 Subject: [PATCH 0308/3224] Tile: remove unused import --- src/pocketmine/tile/Tile.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/tile/Tile.php index 3d629a978e..fd48c30b23 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/tile/Tile.php @@ -35,7 +35,6 @@ use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\StringTag; -use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; use pocketmine\utils\Utils; From c3063ccc446e0493ccfe602798883be5aabdd951 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 29 Nov 2018 14:40:15 +0000 Subject: [PATCH 0309/3224] Remove useless CustomInventory class --- src/pocketmine/inventory/CustomInventory.php | 31 -------------------- 1 file changed, 31 deletions(-) delete mode 100644 src/pocketmine/inventory/CustomInventory.php diff --git a/src/pocketmine/inventory/CustomInventory.php b/src/pocketmine/inventory/CustomInventory.php deleted file mode 100644 index 4fb2eff480..0000000000 --- a/src/pocketmine/inventory/CustomInventory.php +++ /dev/null @@ -1,31 +0,0 @@ - Date: Fri, 30 Nov 2018 16:06:35 +0000 Subject: [PATCH 0310/3224] Flatten still liquid blocks into a liquid block property --- src/pocketmine/block/BlockFactory.php | 8 +++++-- src/pocketmine/block/Lava.php | 16 +------------ src/pocketmine/block/Liquid.php | 33 +++++++++++++++++++++++++-- src/pocketmine/block/StillLava.php | 33 --------------------------- src/pocketmine/block/StillWater.php | 33 --------------------------- src/pocketmine/block/Water.php | 16 +------------ 6 files changed, 39 insertions(+), 100 deletions(-) delete mode 100644 src/pocketmine/block/StillLava.php delete mode 100644 src/pocketmine/block/StillWater.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index b6c1a9efde..d72db93e28 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -101,9 +101,13 @@ class BlockFactory{ self::registerBlock(new Bedrock()); self::registerBlock(new Water()); - self::registerBlock(new StillWater()); + $b = new Water(); + $b->setStill(); + self::registerBlock($b); //flattening hack self::registerBlock(new Lava()); - self::registerBlock(new StillLava()); + $b = new Lava(); + $b->setStill(); + self::registerBlock($b); //flattening hack self::registerBlock(new Sand(Block::SAND, 0, "Sand")); self::registerBlock(new Sand(Block::SAND, 1, "Red Sand")); diff --git a/src/pocketmine/block/Lava.php b/src/pocketmine/block/Lava.php index 5e6c6e2f7d..7e57418d11 100644 --- a/src/pocketmine/block/Lava.php +++ b/src/pocketmine/block/Lava.php @@ -32,28 +32,14 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class Lava extends Liquid{ - protected $id = self::FLOWING_LAVA; - public function __construct(){ - + parent::__construct(self::FLOWING_LAVA, self::STILL_LAVA, "Lava"); } public function getLightLevel() : int{ return 15; } - public function getName() : string{ - return "Lava"; - } - - public function getStillForm() : Block{ - return BlockFactory::get(Block::STILL_LAVA, $this->getDamage()); - } - - public function getFlowingForm() : Block{ - return BlockFactory::get(Block::FLOWING_LAVA, $this->getDamage()); - } - public function getBucketFillSound() : int{ return LevelSoundEventPacket::SOUND_BUCKET_FILL_LAVA; } diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index 01e369ee31..af8dde96e3 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -31,6 +31,8 @@ use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; abstract class Liquid extends Transparent{ + /** @var int */ + private $stillId; public $adjacentSources = 0; @@ -48,6 +50,17 @@ abstract class Liquid extends Transparent{ protected $falling = false; /** @var int */ protected $decay = 0; //PC "level" property + /** @var bool */ + protected $still = false; + + public function __construct(int $id, int $stillId, string $name){ + parent::__construct($id, 0, $name); + $this->stillId = $stillId; + } + + public function getId() : int{ + return $this->still ? $this->stillId : parent::getId(); + } protected function writeStateToMeta() : int{ return $this->decay | ($this->falling ? 0x08 : 0); @@ -94,9 +107,17 @@ abstract class Liquid extends Transparent{ return []; } - abstract public function getStillForm() : Block; + public function getStillForm() : Block{ + $b = clone $this; + $b->still = true; + return $b; + } - abstract public function getFlowingForm() : Block; + public function getFlowingForm() : Block{ + $b = clone $this; + $b->still = false; + return $b; + } abstract public function getBucketFillSound() : int; @@ -110,6 +131,14 @@ abstract class Liquid extends Transparent{ return (($this->falling ? 0 : $this->decay) + 1) / 9; } + public function isStill() : bool{ + return $this->still; + } + + public function setStill(bool $still = true) : void{ + $this->still = $still; + } + protected function getEffectiveFlowDecay(Block $block) : int{ if(!($block instanceof Liquid) or !$block->isSameType($this)){ return -1; diff --git a/src/pocketmine/block/StillLava.php b/src/pocketmine/block/StillLava.php deleted file mode 100644 index b4130a7394..0000000000 --- a/src/pocketmine/block/StillLava.php +++ /dev/null @@ -1,33 +0,0 @@ -getDamage()); - } - - public function getFlowingForm() : Block{ - return BlockFactory::get(Block::FLOWING_WATER, $this->getDamage()); - } - public function getBucketFillSound() : int{ return LevelSoundEventPacket::SOUND_BUCKET_FILL_WATER; } From 16006f9175c82c12d770c2dad6e797172ff7cb61 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 30 Nov 2018 17:05:36 +0000 Subject: [PATCH 0311/3224] Make Tile constructors non-dependent on NBT --- src/pocketmine/level/Level.php | 7 ++++++- src/pocketmine/tile/Furnace.php | 8 -------- src/pocketmine/tile/Spawnable.php | 6 ------ src/pocketmine/tile/Tile.php | 23 ++++++++++++----------- 4 files changed, 18 insertions(+), 26 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 67617f40c8..b36d68233e 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -82,6 +82,7 @@ use pocketmine\plugin\Plugin; use pocketmine\Server; use pocketmine\tile\Chest; use pocketmine\tile\Container; +use pocketmine\tile\Spawnable; use pocketmine\tile\Tile; use pocketmine\timings\Timings; use pocketmine\utils\ReversePriorityQueue; @@ -2611,7 +2612,11 @@ class Level implements ChunkManager, Metadatable{ } $this->tiles[Level::blockHash($tile->x, $tile->y, $tile->z)] = $tile; - $this->clearChunkCache($chunkX, $chunkZ); + $tile->scheduleUpdate(); + if($tile instanceof Spawnable){ + $this->clearChunkCache($chunkX, $chunkZ); + $tile->spawnToAll(); + } } /** diff --git a/src/pocketmine/tile/Furnace.php b/src/pocketmine/tile/Furnace.php index aef45ecb0e..8e4846b14d 100644 --- a/src/pocketmine/tile/Furnace.php +++ b/src/pocketmine/tile/Furnace.php @@ -33,7 +33,6 @@ use pocketmine\inventory\InventoryEventProcessor; use pocketmine\inventory\InventoryHolder; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\level\Level; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\ContainerSetDataPacket; @@ -56,13 +55,6 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ /** @var int */ private $maxTime; - public function __construct(Level $level, CompoundTag $nbt){ - parent::__construct($level, $nbt); - if($this->burnTime > 0){ - $this->scheduleUpdate(); - } - } - protected function readSaveData(CompoundTag $nbt) : void{ $this->burnTime = max(0, $nbt->getShort(self::TAG_BURN_TIME, 0, true)); diff --git a/src/pocketmine/tile/Spawnable.php b/src/pocketmine/tile/Spawnable.php index 2d4710f5e8..3b7f95e576 100644 --- a/src/pocketmine/tile/Spawnable.php +++ b/src/pocketmine/tile/Spawnable.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\tile; -use pocketmine\level\Level; use pocketmine\nbt\NetworkLittleEndianNBTStream; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; @@ -57,11 +56,6 @@ abstract class Spawnable extends Tile{ return true; } - public function __construct(Level $level, CompoundTag $nbt){ - parent::__construct($level, $nbt); - $this->spawnToAll(); - } - public function spawnToAll(){ if($this->closed){ return; diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/tile/Tile.php index fd48c30b23..5cfcc52dda 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/tile/Tile.php @@ -65,7 +65,7 @@ abstract class Tile extends Position{ private static $saveNames = []; /** @var string */ - public $name; + public $name = ""; /** @var bool */ public $closed = false; /** @var TimingsHandler */ @@ -94,9 +94,16 @@ abstract class Tile extends Position{ */ public static function createTile($type, Level $level, CompoundTag $nbt, ...$args) : ?Tile{ if(isset(self::$knownTiles[$type])){ + $pos = new Vector3($nbt->getInt(self::TAG_X), $nbt->getInt(self::TAG_Y), $nbt->getInt(self::TAG_Z)); $class = self::$knownTiles[$type]; - /** @see Tile::__construct() */ - return new $class($level, $nbt, ...$args); + /** + * @var Tile $tile + * @see Tile::__construct() + */ + $tile = new $class($level, $pos); + $tile->readSaveData($nbt); + $level->addTile($tile); + return $tile; } return null; @@ -134,15 +141,9 @@ abstract class Tile extends Position{ return current(self::$saveNames[static::class]); } - public function __construct(Level $level, CompoundTag $nbt){ + public function __construct(Level $level, Vector3 $pos){ $this->timings = Timings::getTileEntityTimings($this); - - $this->name = ""; - - parent::__construct($nbt->getInt(self::TAG_X), $nbt->getInt(self::TAG_Y), $nbt->getInt(self::TAG_Z), $level); - $this->readSaveData($nbt); - - $this->getLevel()->addTile($this); + parent::__construct($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ(), $level); } /** From 9fb365306a0b22183f5aa69dd5367dcb15190250 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 3 Dec 2018 21:18:22 +0000 Subject: [PATCH 0312/3224] Make Block->position() accept Level,x,y,z instead of Position since this is an internal method, it doesn't make sense to force a single parameter that requires potentially constructing a separate object just for the parameters, so we pass primitives instead, which are also easier to typehint against. --- src/pocketmine/block/Block.php | 18 +++++++++++------- src/pocketmine/entity/object/FallingBlock.php | 5 ++--- src/pocketmine/level/Level.php | 10 +++------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 0c1fd4d43b..d9795e9650 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -30,6 +30,7 @@ use pocketmine\entity\Entity; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\level\Level; use pocketmine\level\Position; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -466,15 +467,18 @@ class Block extends Position implements BlockIds, Metadatable{ } /** - * Sets the block position to a new Position object + * @internal * - * @param Position $v + * @param Level $level + * @param int $x + * @param int $y + * @param int $z */ - final public function position(Position $v) : void{ - $this->x = (int) $v->x; - $this->y = (int) $v->y; - $this->z = (int) $v->z; - $this->level = $v->level; + final public function position(Level $level, int $x, int $y, int $z) : void{ + $this->x = $x; + $this->y = $y; + $this->z = $z; + $this->level = $level; $this->readStateFromWorld(); } diff --git a/src/pocketmine/entity/object/FallingBlock.php b/src/pocketmine/entity/object/FallingBlock.php index f03ff9e719..9e21809f6c 100644 --- a/src/pocketmine/entity/object/FallingBlock.php +++ b/src/pocketmine/entity/object/FallingBlock.php @@ -29,7 +29,6 @@ use pocketmine\block\Fallable; use pocketmine\entity\Entity; use pocketmine\event\entity\EntityBlockChangeEvent; use pocketmine\event\entity\EntityDamageEvent; -use pocketmine\level\Position; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; @@ -95,9 +94,9 @@ class FallingBlock extends Entity{ $hasUpdate = parent::entityBaseTick($tickDiff); if(!$this->isFlaggedForDespawn()){ - $pos = Position::fromObject($this->add(-$this->width / 2, $this->height, -$this->width / 2)->floor(), $this->getLevel()); + $pos = $this->add(-$this->width / 2, $this->height, -$this->width / 2)->floor(); - $this->block->position($pos); + $this->block->position($this->level, $pos->x, $pos->y, $pos->z); $blockTarget = null; if($this->block instanceof Fallable){ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 1bb06aed99..ff1370e1bd 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1530,13 +1530,9 @@ class Level implements ChunkManager, Metadatable{ $this->timings->setBlock->startTiming(); - if(!($pos instanceof Position)){ - $pos = $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z); - } - $block = clone $block; - $block->position($pos); + $block->position($this, $pos->x, $pos->y, $pos->z); $block->writeStateToWorld(); $chunkHash = Level::chunkHash($pos->x >> 4, $pos->z >> 4); @@ -1823,14 +1819,14 @@ class Level implements ChunkManager, Metadatable{ if($item->canBePlaced()){ $hand = $item->getBlock(); - $hand->position($blockReplace); + $hand->position($this, $blockReplace->x, $blockReplace->y, $blockReplace->z); }else{ return false; } if($hand->canBePlacedAt($blockClicked, $clickVector, $face, true)){ $blockReplace = $blockClicked; - $hand->position($blockReplace); + $hand->position($this, $blockReplace->x, $blockReplace->y, $blockReplace->z); }elseif(!$hand->canBePlacedAt($blockReplace, $clickVector, $face, false)){ return false; } From 8051fa4f6d4cb235b6ed3bf207b672c899b08158 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 3 Dec 2018 21:39:17 +0000 Subject: [PATCH 0313/3224] Remove some direct Position->level accesses --- src/pocketmine/block/BlockFactory.php | 5 +---- src/pocketmine/item/PaintingItem.php | 2 +- src/pocketmine/level/Level.php | 6 +----- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index d72db93e28..7251e6523d 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -538,10 +538,7 @@ class BlockFactory{ } if($pos !== null){ - $block->x = $pos->getFloorX(); - $block->y = $pos->getFloorY(); - $block->z = $pos->getFloorZ(); - $block->level = $pos->level; + $block->position($pos->getLevel(), $pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ()); } return $block; diff --git a/src/pocketmine/item/PaintingItem.php b/src/pocketmine/item/PaintingItem.php index fe09a4454a..b8cf24bfd5 100644 --- a/src/pocketmine/item/PaintingItem.php +++ b/src/pocketmine/item/PaintingItem.php @@ -51,7 +51,7 @@ class PaintingItem extends Item{ continue; } - if(Painting::canFit($player->level, $blockReplace, $face, true, $motive)){ + if(Painting::canFit($player->getLevel(), $blockReplace, $face, true, $motive)){ if($currentTotalDimension > $totalDimension){ $totalDimension = $currentTotalDimension; /* diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index ff1370e1bd..c3f41d6a13 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1368,11 +1368,7 @@ class Level implements ChunkManager, Metadatable{ } $block = BlockFactory::get($id, $meta); - - $block->x = $x; - $block->y = $y; - $block->z = $z; - $block->level = $this; + $block->position($this, $x, $y, $z); static $dynamicStateRead = false; From bfe766e626e9b625a47137ad944af24cd601e358 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 4 Dec 2018 13:22:29 +0000 Subject: [PATCH 0314/3224] oops, a merge error --- src/pocketmine/block/Liquid.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index 17093fa145..4665f23737 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -326,17 +326,18 @@ abstract class Liquid extends Transparent{ protected function flowIntoBlock(Block $block, int $newFlowDecay, bool $falling) : void{ if($this->canFlowInto($block) and !($block instanceof Liquid)){ - $ev = new BlockSpreadEvent($block, $this, BlockFactory::get($this->getId(), $newFlowDecay)); + $new = clone $this; + $new->falling = $falling; + $new->decay = $falling ? 0 : $newFlowDecay; + + $ev = new BlockSpreadEvent($block, $this, $new); $ev->call(); if(!$ev->isCancelled()){ if($block->getId() > 0){ $this->level->useBreakOn($block); } - $new = clone $this; - $new->falling = $falling; - $new->decay = $falling ? 0 : $newFlowDecay; - $this->level->setBlock($block, $new); + $this->level->setBlock($block, $ev->getNewState()); } } } From b50e29085e3830ca8002007eef3d9be095072e89 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 4 Dec 2018 19:02:26 +0000 Subject: [PATCH 0315/3224] Remove InventoryEventProcessor, use closures instead --- src/pocketmine/entity/Human.php | 19 ++++++-- src/pocketmine/entity/Living.php | 13 ++++- .../ArmorInventoryEventProcessor.php | 47 ------------------ src/pocketmine/inventory/BaseInventory.php | 20 ++++---- .../EntityInventoryEventProcessor.php | 47 ------------------ src/pocketmine/inventory/Inventory.php | 8 ++-- .../inventory/InventoryEventProcessor.php | 48 ------------------- src/pocketmine/tile/Furnace.php | 16 ++----- 8 files changed, 44 insertions(+), 174 deletions(-) delete mode 100644 src/pocketmine/inventory/ArmorInventoryEventProcessor.php delete mode 100644 src/pocketmine/inventory/EntityInventoryEventProcessor.php delete mode 100644 src/pocketmine/inventory/InventoryEventProcessor.php diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index bdc657a2ae..bd0fde33d1 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -26,11 +26,12 @@ namespace pocketmine\entity; use pocketmine\entity\projectile\ProjectileSource; use pocketmine\entity\utils\ExperienceUtils; use pocketmine\event\entity\EntityDamageEvent; +use pocketmine\event\entity\EntityInventoryChangeEvent; use pocketmine\event\entity\EntityRegainHealthEvent; use pocketmine\event\player\PlayerExhaustEvent; use pocketmine\event\player\PlayerExperienceChangeEvent; use pocketmine\inventory\EnderChestInventory; -use pocketmine\inventory\EntityInventoryEventProcessor; +use pocketmine\inventory\Inventory; use pocketmine\inventory\InventoryHolder; use pocketmine\inventory\PlayerInventory; use pocketmine\item\Consumable; @@ -613,8 +614,8 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $inventoryTag = $nbt->getListTag("Inventory"); if($inventoryTag !== null){ - $armorListener = $this->armorInventory->getEventProcessor(); - $this->armorInventory->setEventProcessor(null); + $armorListener = $this->armorInventory->getSlotChangeListener(); + $this->armorInventory->setSlotChangeListener(null); /** @var CompoundTag $item */ foreach($inventoryTag as $i => $item){ @@ -628,7 +629,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ } } - $this->armorInventory->setEventProcessor($armorListener); + $this->armorInventory->setSlotChangeListener($armorListener); } $enderChestInventoryTag = $nbt->getListTag("EnderChestInventory"); @@ -641,7 +642,15 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $this->inventory->setHeldItemIndex($nbt->getInt("SelectedInventorySlot", 0), false); - $this->inventory->setEventProcessor(new EntityInventoryEventProcessor($this)); + $this->inventory->setSlotChangeListener(function(Inventory $inventory, int $slot, Item $oldItem, Item $newItem) : ?Item{ + $ev = new EntityInventoryChangeEvent($this, $oldItem, $newItem, $slot); + $ev->call(); + if($ev->isCancelled()){ + return null; + } + + return $ev->getNewItem(); + }); $this->setFood((float) $nbt->getInt("foodLevel", (int) $this->getFood(), true)); $this->setExhaustion($nbt->getFloat("foodExhaustionLevel", $this->getExhaustion(), true)); diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 8f8846ef32..e279bd4188 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity; use pocketmine\block\Block; +use pocketmine\event\entity\EntityArmorChangeEvent; use pocketmine\event\entity\EntityDamageByChildEntityEvent; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; @@ -31,7 +32,7 @@ use pocketmine\event\entity\EntityDeathEvent; use pocketmine\event\entity\EntityEffectAddEvent; use pocketmine\event\entity\EntityEffectRemoveEvent; use pocketmine\inventory\ArmorInventory; -use pocketmine\inventory\ArmorInventoryEventProcessor; +use pocketmine\inventory\Inventory; use pocketmine\item\Armor; use pocketmine\item\Consumable; use pocketmine\item\Durable; @@ -79,7 +80,15 @@ abstract class Living extends Entity implements Damageable{ $this->armorInventory = new ArmorInventory($this); //TODO: load/save armor inventory contents - $this->armorInventory->setEventProcessor(new ArmorInventoryEventProcessor($this)); + $this->armorInventory->setSlotChangeListener(function(Inventory $inventory, int $slot, Item $oldItem, Item $newItem) : ?Item{ + $ev = new EntityArmorChangeEvent($this, $oldItem, $newItem, $slot); + $ev->call(); + if($ev->isCancelled()){ + return null; + } + + return $ev->getNewItem(); + }); $health = $this->getMaxHealth(); diff --git a/src/pocketmine/inventory/ArmorInventoryEventProcessor.php b/src/pocketmine/inventory/ArmorInventoryEventProcessor.php deleted file mode 100644 index f0866571e7..0000000000 --- a/src/pocketmine/inventory/ArmorInventoryEventProcessor.php +++ /dev/null @@ -1,47 +0,0 @@ -entity = $entity; - } - - public function onSlotChange(Inventory $inventory, int $slot, Item $oldItem, Item $newItem) : ?Item{ - $ev = new EntityArmorChangeEvent($this->entity, $oldItem, $newItem, $slot); - $ev->call(); - if($ev->isCancelled()){ - return null; - } - - return $ev->getNewItem(); - } -} diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index cc335e6dec..fdbe0a2e03 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -32,6 +32,7 @@ use pocketmine\network\mcpe\protocol\InventoryContentPacket; use pocketmine\network\mcpe\protocol\InventorySlotPacket; use pocketmine\network\mcpe\protocol\types\ContainerIds; use pocketmine\Player; +use pocketmine\utils\Utils; abstract class BaseInventory implements Inventory{ @@ -45,8 +46,8 @@ abstract class BaseInventory implements Inventory{ protected $slots = []; /** @var Player[] */ protected $viewers = []; - /** @var InventoryEventProcessor */ - protected $eventProcessor; + /** @var \Closure */ + protected $slotChangeListener; /** * @param Item[] $items @@ -163,8 +164,8 @@ abstract class BaseInventory implements Inventory{ } $oldItem = $this->getItem($index); - if($this->eventProcessor !== null){ - $newItem = $this->eventProcessor->onSlotChange($this, $index, $oldItem, $item); + if($this->slotChangeListener !== null){ + $newItem = ($this->slotChangeListener)($this, $index, $oldItem, $item); if($newItem === null){ return false; } @@ -476,11 +477,14 @@ abstract class BaseInventory implements Inventory{ return $slot >= 0 and $slot < $this->slots->getSize(); } - public function getEventProcessor() : ?InventoryEventProcessor{ - return $this->eventProcessor; + public function getSlotChangeListener() : ?\Closure{ + return $this->slotChangeListener; } - public function setEventProcessor(?InventoryEventProcessor $eventProcessor) : void{ - $this->eventProcessor = $eventProcessor; + public function setSlotChangeListener(?\Closure $eventProcessor) : void{ + if($eventProcessor !== null){ + Utils::validateCallableSignature(function(Inventory $inventory, int $slot, Item $oldItem, Item $newItem) : ?Item{}, $eventProcessor); + } + $this->slotChangeListener = $eventProcessor; } } diff --git a/src/pocketmine/inventory/EntityInventoryEventProcessor.php b/src/pocketmine/inventory/EntityInventoryEventProcessor.php deleted file mode 100644 index 1b4fbf0eb0..0000000000 --- a/src/pocketmine/inventory/EntityInventoryEventProcessor.php +++ /dev/null @@ -1,47 +0,0 @@ -entity = $entity; - } - - public function onSlotChange(Inventory $inventory, int $slot, Item $oldItem, Item $newItem) : ?Item{ - $ev = new EntityInventoryChangeEvent($this->entity, $oldItem, $newItem, $slot); - $ev->call(); - if($ev->isCancelled()){ - return null; - } - - return $ev->getNewItem(); - } -} diff --git a/src/pocketmine/inventory/Inventory.php b/src/pocketmine/inventory/Inventory.php index 7e5f5d40a0..cf251d03ea 100644 --- a/src/pocketmine/inventory/Inventory.php +++ b/src/pocketmine/inventory/Inventory.php @@ -250,12 +250,12 @@ interface Inventory{ public function slotExists(int $slot) : bool; /** - * @return null|InventoryEventProcessor + * @return null|\Closure */ - public function getEventProcessor() : ?InventoryEventProcessor; + public function getSlotChangeListener() : ?\Closure; /** - * @param null|InventoryEventProcessor $eventProcessor + * @param \Closure|null $eventProcessor */ - public function setEventProcessor(?InventoryEventProcessor $eventProcessor) : void; + public function setSlotChangeListener(?\Closure $eventProcessor) : void; } diff --git a/src/pocketmine/inventory/InventoryEventProcessor.php b/src/pocketmine/inventory/InventoryEventProcessor.php deleted file mode 100644 index 0ecafec3c2..0000000000 --- a/src/pocketmine/inventory/InventoryEventProcessor.php +++ /dev/null @@ -1,48 +0,0 @@ -inventory = new FurnaceInventory($this); $this->loadItems($nbt); - $this->inventory->setEventProcessor(new class($this) implements InventoryEventProcessor{ - /** @var Furnace */ - private $furnace; - - public function __construct(Furnace $furnace){ - $this->furnace = $furnace; - } - - public function onSlotChange(Inventory $inventory, int $slot, Item $oldItem, Item $newItem) : ?Item{ - $this->furnace->scheduleUpdate(); - return $newItem; - } + $this->inventory->setSlotChangeListener(function(Inventory $inventory, int $slot, Item $oldItem, Item $newItem) : ?Item{ + $this->scheduleUpdate(); + return $newItem; }); } From 47e62b1b38dcfa23d8ebd40774653deed15d9496 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 4 Dec 2018 21:59:58 +0000 Subject: [PATCH 0316/3224] Level: Add setBlockAt() which accepts integers instead of Vector3 --- src/pocketmine/level/Level.php | 44 ++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index c3f41d6a13..94d41d5907 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1506,33 +1506,51 @@ class Level implements ChunkManager, Metadatable{ } /** - * Sets on Vector3 the data from a Block object, - * does block updates and puts the changes to the send queue. - * - * If $update is true, it'll get the neighbour blocks (6 sides) and update them. - * If you are doing big changes, you might want to set this to false, then update manually. + * Sets the block at the given Vector3 coordinates. + * @see Level::setBlockAt() * * @param Vector3 $pos * @param Block $block * @param bool $update * * @return bool Whether the block has been updated or not + * + * @throws \InvalidArgumentException if the position is out of the world bounds */ public function setBlock(Vector3 $pos, Block $block, bool $update = true) : bool{ - $pos = $pos->floor(); - if(!$this->isInWorld($pos->x, $pos->y, $pos->z)){ - throw new \InvalidArgumentException("Pos x=$pos->x,y=$pos->y,z=$pos->z is outside of the world bounds"); + return $this->setBlockAt((int) floor($pos->x), (int) floor($pos->y), (int) floor($pos->z), $block, $update); + } + + /** + * Sets the block at the given coordinates. + * + * If $update is true, it'll get the neighbour blocks (6 sides) and update them, and also update local lighting. + * If you are doing big changes, you might want to set this to false, then update manually. + * + * @param int $x + * @param int $y + * @param int $z + * @param Block $block + * @param bool $update + * + * @return bool Whether the block has been updated or not + * + * @throws \InvalidArgumentException if the position is out of the world bounds + */ + public function setBlockAt(int $x, int $y, int $z, Block $block, bool $update = true) : bool{ + if(!$this->isInWorld($x, $y, $z)){ + throw new \InvalidArgumentException("Pos x=$x,y=$y,z=$z is outside of the world bounds"); } $this->timings->setBlock->startTiming(); $block = clone $block; - $block->position($this, $pos->x, $pos->y, $pos->z); + $block->position($this, $x, $y, $z); $block->writeStateToWorld(); - $chunkHash = Level::chunkHash($pos->x >> 4, $pos->z >> 4); - $blockHash = Level::blockHash($pos->x, $pos->y, $pos->z); + $chunkHash = Level::chunkHash($x >> 4, $z >> 4); + $blockHash = Level::blockHash($x, $y, $z); unset($this->blockCache[$chunkHash][$blockHash]); @@ -1541,7 +1559,7 @@ class Level implements ChunkManager, Metadatable{ } $this->changedBlocks[$chunkHash][$blockHash] = $block; - foreach($this->getChunkLoaders($pos->x >> 4, $pos->z >> 4) as $loader){ + foreach($this->getChunkLoaders($x >> 4, $z >> 4) as $loader){ $loader->onBlockChanged($block); } @@ -1555,7 +1573,7 @@ class Level implements ChunkManager, Metadatable{ $entity->onNearbyBlockChange(); } $ev->getBlock()->onNearbyBlockChange(); - $this->scheduleNeighbourBlockUpdates($pos); + $this->scheduleNeighbourBlockUpdates($block); } } From 8dd2ea22b84c1cae5354b2f015238fa7c4321af7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 4 Dec 2018 22:05:00 +0000 Subject: [PATCH 0317/3224] Level: make use of fromFullState() in getBlockAt() --- src/pocketmine/level/Level.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 94d41d5907..31b0aa2ff2 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1345,8 +1345,7 @@ class Level implements ChunkManager, Metadatable{ * @return Block */ public function getBlockAt(int $x, int $y, int $z, bool $cached = true, bool $addToCache = true) : Block{ - $id = 0; - $meta = 0; + $fullState = 0; $blockHash = null; $chunkHash = Level::chunkHash($x >> 4, $z >> 4); @@ -1360,14 +1359,12 @@ class Level implements ChunkManager, Metadatable{ $chunk = $this->chunks[$chunkHash] ?? null; if($chunk !== null){ $fullState = $chunk->getFullBlock($x & 0x0f, $y, $z & 0x0f); - $id = $fullState >> 4; - $meta = $fullState & 0xf; }else{ $addToCache = false; } } - $block = BlockFactory::get($id, $meta); + $block = BlockFactory::fromFullBlock($fullState); $block->position($this, $x, $y, $z); static $dynamicStateRead = false; From cd5b81bdb9365da940179197222bbc0eec1e6d6c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 4 Dec 2018 22:27:00 +0000 Subject: [PATCH 0318/3224] ChunkManager: Remove getBlockIdAt()/setBlockIdAt()/getBlockDataAt()/setBlockDataAt(), add getBlockAt() and setBlockAt() --- src/pocketmine/block/Farmland.php | 3 +- src/pocketmine/block/Grass.php | 8 ++-- src/pocketmine/level/ChunkManager.php | 23 +++++----- src/pocketmine/level/Explosion.php | 3 +- src/pocketmine/level/Level.php | 43 ------------------- src/pocketmine/level/SimpleChunkManager.php | 38 ++++------------ .../level/generator/object/BirchTree.php | 3 +- .../level/generator/object/JungleTree.php | 3 +- .../level/generator/object/OakTree.php | 3 +- src/pocketmine/level/generator/object/Ore.php | 6 +-- .../level/generator/object/SpruceTree.php | 6 +-- .../level/generator/object/TallGrass.php | 19 ++++---- .../level/generator/object/Tree.php | 25 +++++------ .../level/generator/populator/TallGrass.php | 11 +++-- .../level/generator/populator/Tree.php | 2 +- 15 files changed, 69 insertions(+), 127 deletions(-) diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index 3303bc4d67..c1e25eaeec 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -98,8 +98,7 @@ class Farmland extends Transparent{ for($y = $start->y; $y <= $end->y; ++$y){ for($z = $start->z; $z <= $end->z; ++$z){ for($x = $start->x; $x <= $end->x; ++$x){ - $id = $this->level->getBlockIdAt($x, $y, $z); - if($id === Block::STILL_WATER or $id === Block::FLOWING_WATER){ + if($this->level->getBlockAt($x, $y, $z) instanceof Water){ return true; } } diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index b640de8542..fa9e9d71ff 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -78,16 +78,18 @@ class Grass extends Solid{ $x = mt_rand($this->x - 1, $this->x + 1); $y = mt_rand($this->y - 3, $this->y + 1); $z = mt_rand($this->z - 1, $this->z + 1); + + $b = $this->level->getBlockAt($x, $y, $z); if( - $this->level->getBlockIdAt($x, $y, $z) !== Block::DIRT or - $this->level->getBlockDataAt($x, $y, $z) === 1 or + $b->getId() !== Block::DIRT or + $b->getDamage() === 1 or //coarse dirt $this->level->getFullLightAt($x, $y + 1, $z) < 4 or BlockFactory::$lightFilter[$this->level->getFullBlock($x, $y + 1, $z)] >= 3 ){ continue; } - $ev = new BlockSpreadEvent($b = $this->level->getBlockAt($x, $y, $z), $this, BlockFactory::get(Block::GRASS)); + $ev = new BlockSpreadEvent($b, $this, BlockFactory::get(Block::GRASS)); $ev->call(); if(!$ev->isCancelled()){ $this->level->setBlock($b, $ev->getNewState(), false); diff --git a/src/pocketmine/level/ChunkManager.php b/src/pocketmine/level/ChunkManager.php index dd9fa341f8..2e669253b4 100644 --- a/src/pocketmine/level/ChunkManager.php +++ b/src/pocketmine/level/ChunkManager.php @@ -23,32 +23,33 @@ declare(strict_types=1); namespace pocketmine\level; +use pocketmine\block\Block; use pocketmine\level\format\Chunk; interface ChunkManager{ + /** - * Gets the raw block id. + * Returns a Block object representing the block state at the given coordinates. * * @param int $x * @param int $y * @param int $z * - * @return int 0-255 + * @return Block */ - public function getBlockIdAt(int $x, int $y, int $z) : int; + public function getBlockAt(int $x, int $y, int $z) : Block; /** - * Gets the raw block metadata + * Sets the block at the given coordinates to the block state specified. * - * @param int $x - * @param int $y - * @param int $z + * @param int $x + * @param int $y + * @param int $z + * @param Block $block * - * @return int 0-15 + * @return bool TODO: remove */ - public function getBlockDataAt(int $x, int $y, int $z) : int; - - public function setBlockIdAndDataAt(int $x, int $y, int $z, int $id, int $data) : void; + public function setBlockAt(int $x, int $y, int $z, Block $block) : bool; /** * Returns the raw block light level diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index 3f2b0e7343..3aaf290099 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -200,6 +200,7 @@ class Explosion{ $air = ItemFactory::get(Item::AIR); + $airBlock = BlockFactory::get(Block::AIR); foreach($this->affectedBlocks as $block){ $yieldDrops = false; @@ -212,7 +213,7 @@ class Explosion{ } } - $this->level->setBlockIdAndDataAt($block->x, $block->y, $block->z, 0, 0); + $this->level->setBlockAt($block->x, $block->y, $block->z, $airBlock, false); //TODO: should updating really be disabled here? $t = $this->level->getTileAt($block->x, $block->y, $block->z); if($t instanceof Tile){ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 31b0aa2ff2..859b013c72 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -2100,49 +2100,6 @@ class Level implements ChunkManager, Metadatable{ return ($chunk = $this->getChunk($X, $Z)) !== null ? $chunk->getTiles() : []; } - /** - * Gets the raw block id. - * - * @param int $x - * @param int $y - * @param int $z - * - * @return int 0-255 - */ - public function getBlockIdAt(int $x, int $y, int $z) : int{ - return $this->getChunk($x >> 4, $z >> 4, true)->getBlockId($x & 0x0f, $y, $z & 0x0f); - } - - /** - * Gets the raw block metadata - * - * @param int $x - * @param int $y - * @param int $z - * - * @return int 0-15 - */ - public function getBlockDataAt(int $x, int $y, int $z) : int{ - return $this->getChunk($x >> 4, $z >> 4, true)->getBlockData($x & 0x0f, $y, $z & 0x0f); - } - - public function setBlockIdAndDataAt(int $x, int $y, int $z, int $id, int $data) : void{ - if(!$this->isInWorld($x, $y, $z)){ //TODO: bad hack but fixing this requires BC breaks to do properly :( - return; - } - unset($this->blockCache[$chunkHash = Level::chunkHash($x >> 4, $z >> 4)][$blockHash = Level::blockHash($x, $y, $z)]); - - $this->getChunk($x >> 4, $z >> 4, true)->setBlock($x & 0x0f, $y, $z & 0x0f, $id, $data); - - if(!isset($this->changedBlocks[$chunkHash])){ - $this->changedBlocks[$chunkHash] = []; - } - $this->changedBlocks[$chunkHash][$blockHash] = $v = new Vector3($x, $y, $z); - foreach($this->getChunkLoaders($x >> 4, $z >> 4) as $loader){ - $loader->onBlockChanged($v); - } - } - /** * Gets the raw block skylight level * diff --git a/src/pocketmine/level/SimpleChunkManager.php b/src/pocketmine/level/SimpleChunkManager.php index 74d071a2f8..d290058b64 100644 --- a/src/pocketmine/level/SimpleChunkManager.php +++ b/src/pocketmine/level/SimpleChunkManager.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\level; +use pocketmine\block\Block; +use pocketmine\block\BlockFactory; use pocketmine\level\format\Chunk; class SimpleChunkManager implements ChunkManager{ @@ -41,42 +43,18 @@ class SimpleChunkManager implements ChunkManager{ $this->worldHeight = $worldHeight; } - /** - * Gets the raw block id. - * - * @param int $x - * @param int $y - * @param int $z - * - * @return int 0-255 - */ - public function getBlockIdAt(int $x, int $y, int $z) : int{ + public function getBlockAt(int $x, int $y, int $z) : Block{ if($chunk = $this->getChunk($x >> 4, $z >> 4)){ - return $chunk->getBlockId($x & 0xf, $y, $z & 0xf); + return BlockFactory::fromFullBlock($chunk->getFullBlock($x & 0xf, $y, $z & 0xf)); } - return 0; + return BlockFactory::get(Block::AIR); } - /** - * Gets the raw block metadata - * - * @param int $x - * @param int $y - * @param int $z - * - * @return int 0-15 - */ - public function getBlockDataAt(int $x, int $y, int $z) : int{ - if($chunk = $this->getChunk($x >> 4, $z >> 4)){ - return $chunk->getBlockData($x & 0xf, $y, $z & 0xf); - } - return 0; - } - - public function setBlockIdAndDataAt(int $x, int $y, int $z, int $id, int $data) : void{ + public function setBlockAt(int $x, int $y, int $z, Block $block) : bool{ if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ - $chunk->setBlock($x & 0xf, $y, $z & 0xf, $id, $data); + return $chunk->setBlock($x & 0xf, $y, $z & 0xf, $block->getId(), $block->getDamage()); } + return false; } public function getBlockLightAt(int $x, int $y, int $z) : int{ diff --git a/src/pocketmine/level/generator/object/BirchTree.php b/src/pocketmine/level/generator/object/BirchTree.php index be6046fb50..eea3f37f63 100644 --- a/src/pocketmine/level/generator/object/BirchTree.php +++ b/src/pocketmine/level/generator/object/BirchTree.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\level\generator\object; use pocketmine\block\Block; +use pocketmine\block\BlockFactory; use pocketmine\block\Wood; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; @@ -33,7 +34,7 @@ class BirchTree extends Tree{ protected $superBirch = false; public function __construct(bool $superBirch = false){ - parent::__construct(Block::LOG, Block::LEAVES, Wood::BIRCH); + parent::__construct(BlockFactory::get(Block::LOG, Wood::BIRCH), BlockFactory::get(Block::LEAVES, Wood::BIRCH)); $this->superBirch = $superBirch; } diff --git a/src/pocketmine/level/generator/object/JungleTree.php b/src/pocketmine/level/generator/object/JungleTree.php index ae749f0dfe..10a01d2837 100644 --- a/src/pocketmine/level/generator/object/JungleTree.php +++ b/src/pocketmine/level/generator/object/JungleTree.php @@ -24,11 +24,12 @@ declare(strict_types=1); namespace pocketmine\level\generator\object; use pocketmine\block\Block; +use pocketmine\block\BlockFactory; use pocketmine\block\Wood; class JungleTree extends Tree{ public function __construct(){ - parent::__construct(Block::LOG, Block::LEAVES, Wood::JUNGLE, 8); + parent::__construct(BlockFactory::get(Block::LOG, Wood::JUNGLE), BlockFactory::get(Block::LEAVES, Wood::JUNGLE), 8); } } diff --git a/src/pocketmine/level/generator/object/OakTree.php b/src/pocketmine/level/generator/object/OakTree.php index 66e7f81d78..ade1b6da4a 100644 --- a/src/pocketmine/level/generator/object/OakTree.php +++ b/src/pocketmine/level/generator/object/OakTree.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\level\generator\object; use pocketmine\block\Block; +use pocketmine\block\BlockFactory; use pocketmine\block\Wood; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; @@ -31,7 +32,7 @@ use pocketmine\utils\Random; class OakTree extends Tree{ public function __construct(){ - parent::__construct(Block::LOG, Block::LEAVES, Wood::OAK); + parent::__construct(BlockFactory::get(Block::LOG, Wood::OAK), BlockFactory::get(Block::LEAVES, Wood::OAK)); } public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ diff --git a/src/pocketmine/level/generator/object/Ore.php b/src/pocketmine/level/generator/object/Ore.php index 048bd212ed..2fa098f02c 100644 --- a/src/pocketmine/level/generator/object/Ore.php +++ b/src/pocketmine/level/generator/object/Ore.php @@ -44,7 +44,7 @@ class Ore{ } public function canPlaceObject(ChunkManager $level, int $x, int $y, int $z) : bool{ - return $level->getBlockIdAt($x, $y, $z) === Block::STONE; + return $level->getBlockAt($x, $y, $z)->getId() === Block::STONE; } public function placeObject(ChunkManager $level, int $x, int $y, int $z) : void{ @@ -84,8 +84,8 @@ class Ore{ $sizeZ = ($z + 0.5 - $seedZ) / $size; $sizeZ *= $sizeZ; - if(($sizeX + $sizeY + $sizeZ) < 1 and $level->getBlockIdAt($x, $y, $z) === Block::STONE){ - $level->setBlockIdAndDataAt($x, $y, $z, $this->type->material->getId(), $this->type->material->getDamage()); + if(($sizeX + $sizeY + $sizeZ) < 1 and $level->getBlockAt($x, $y, $z)->getId() === Block::STONE){ + $level->setBlockAt($x, $y, $z, $this->type->material); } } } diff --git a/src/pocketmine/level/generator/object/SpruceTree.php b/src/pocketmine/level/generator/object/SpruceTree.php index cb7346cb7a..7333a59238 100644 --- a/src/pocketmine/level/generator/object/SpruceTree.php +++ b/src/pocketmine/level/generator/object/SpruceTree.php @@ -32,7 +32,7 @@ use pocketmine\utils\Random; class SpruceTree extends Tree{ public function __construct(){ - parent::__construct(Block::LOG, Block::LEAVES, Wood::SPRUCE, 10); + parent::__construct(BlockFactory::get(Block::LOG, Wood::SPRUCE), BlockFactory::get(Block::LEAVES, Wood::SPRUCE), 10); } public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ @@ -58,8 +58,8 @@ class SpruceTree extends Tree{ continue; } - if(!BlockFactory::get($level->getBlockIdAt($xx, $yyy, $zz))->isSolid()){ - $level->setBlockIdAndDataAt($xx, $yyy, $zz, $this->leafBlock, $this->blockMeta); + if(!$level->getBlockAt($xx, $yyy, $zz)->isSolid()){ + $level->setBlockAt($xx, $yyy, $zz, $this->leafBlock); } } } diff --git a/src/pocketmine/level/generator/object/TallGrass.php b/src/pocketmine/level/generator/object/TallGrass.php index ce1aee00f2..12dbfec9e7 100644 --- a/src/pocketmine/level/generator/object/TallGrass.php +++ b/src/pocketmine/level/generator/object/TallGrass.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\level\generator\object; use pocketmine\block\Block; +use pocketmine\block\BlockFactory; use pocketmine\level\ChunkManager; use pocketmine\math\Vector3; use pocketmine\utils\Random; @@ -31,21 +32,21 @@ use pocketmine\utils\Random; class TallGrass{ public static function growGrass(ChunkManager $level, Vector3 $pos, Random $random, int $count = 15, int $radius = 10) : void{ + /** @var Block[] $arr */ $arr = [ - [Block::DANDELION, 0], - [Block::POPPY, 0], - [Block::TALL_GRASS, 1], - [Block::TALL_GRASS, 1], - [Block::TALL_GRASS, 1], - [Block::TALL_GRASS, 1] + BlockFactory::get(Block::DANDELION), + BlockFactory::get(Block::POPPY), + $tallGrass = BlockFactory::get(Block::TALL_GRASS, 1), + $tallGrass, + $tallGrass, + $tallGrass ]; $arrC = count($arr) - 1; for($c = 0; $c < $count; ++$c){ $x = $random->nextRange($pos->x - $radius, $pos->x + $radius); $z = $random->nextRange($pos->z - $radius, $pos->z + $radius); - if($level->getBlockIdAt($x, $pos->y + 1, $z) === Block::AIR and $level->getBlockIdAt($x, $pos->y, $z) === Block::GRASS){ - $t = $arr[$random->nextRange(0, $arrC)]; - $level->setBlockIdAndDataAt($x, $pos->y + 1, $z, $t[0], $t[1]); + if($level->getBlockAt($x, $pos->y + 1, $z)->getId() === Block::AIR and $level->getBlockAt($x, $pos->y, $z)->getId() === Block::GRASS){ + $level->setBlockAt($x, $pos->y + 1, $z, $arr[$random->nextRange(0, $arrC)]); } } } diff --git a/src/pocketmine/level/generator/object/Tree.php b/src/pocketmine/level/generator/object/Tree.php index f0dced5a60..4fcd1d6fe5 100644 --- a/src/pocketmine/level/generator/object/Tree.php +++ b/src/pocketmine/level/generator/object/Tree.php @@ -33,20 +33,18 @@ use pocketmine\level\ChunkManager; use pocketmine\utils\Random; abstract class Tree{ - - /** @var int */ - protected $blockMeta; - /** @var int */ + /** @var Block */ protected $trunkBlock; - /** @var int */ + /** @var Block */ protected $leafBlock; + /** @var int */ protected $treeHeight; - public function __construct(int $trunkBlock, int $leafBlock, int $blockMeta, int $treeHeight = 7){ + public function __construct(Block $trunkBlock, Block $leafBlock, int $treeHeight = 7){ $this->trunkBlock = $trunkBlock; $this->leafBlock = $leafBlock; - $this->blockMeta = $blockMeta; + $this->treeHeight = $treeHeight; } @@ -91,7 +89,7 @@ abstract class Tree{ } for($xx = -$radiusToCheck; $xx < ($radiusToCheck + 1); ++$xx){ for($zz = -$radiusToCheck; $zz < ($radiusToCheck + 1); ++$zz){ - if(!$this->canOverride(BlockFactory::get($level->getBlockIdAt($x + $xx, $y + $yy, $z + $zz)))){ + if(!$this->canOverride($level->getBlockAt($x + $xx, $y + $yy, $z + $zz))){ return false; } } @@ -114,8 +112,8 @@ abstract class Tree{ if($xOff === $mid and $zOff === $mid and ($yOff === 0 or $random->nextBoundedInt(2) === 0)){ continue; } - if(!BlockFactory::get($level->getBlockIdAt($xx, $yy, $zz))->isSolid()){ - $level->setBlockIdAndDataAt($xx, $yy, $zz, $this->leafBlock, $this->blockMeta); + if(!$level->getBlockAt($xx, $yy, $zz)->isSolid()){ + $level->setBlockAt($xx, $yy, $zz, $this->leafBlock); } } } @@ -124,12 +122,11 @@ abstract class Tree{ protected function placeTrunk(ChunkManager $level, int $x, int $y, int $z, Random $random, int $trunkHeight) : void{ // The base dirt block - $level->setBlockIdAndDataAt($x, $y - 1, $z, Block::DIRT, 0); + $level->setBlockAt($x, $y - 1, $z, BlockFactory::get(Block::DIRT)); for($yy = 0; $yy < $trunkHeight; ++$yy){ - $blockId = $level->getBlockIdAt($x, $y + $yy, $z); - if($this->canOverride(BlockFactory::get($blockId))){ - $level->setBlockIdAndDataAt($x, $y + $yy, $z, $this->trunkBlock, $this->blockMeta); + if($this->canOverride($level->getBlockAt($x, $y + $yy, $z))){ + $level->setBlockAt($x, $y + $yy, $z, $this->trunkBlock); } } } diff --git a/src/pocketmine/level/generator/populator/TallGrass.php b/src/pocketmine/level/generator/populator/TallGrass.php index 6a16870a63..353a67e184 100644 --- a/src/pocketmine/level/generator/populator/TallGrass.php +++ b/src/pocketmine/level/generator/populator/TallGrass.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\level\generator\populator; use pocketmine\block\Block; +use pocketmine\block\BlockFactory; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; @@ -44,25 +45,27 @@ class TallGrass extends Populator{ public function populate(ChunkManager $level, int $chunkX, int $chunkZ, Random $random) : void{ $this->level = $level; $amount = $random->nextRange(0, $this->randomAmount + 1) + $this->baseAmount; + + $block = BlockFactory::get(Block::TALL_GRASS, 1); for($i = 0; $i < $amount; ++$i){ $x = $random->nextRange($chunkX * 16, $chunkX * 16 + 15); $z = $random->nextRange($chunkZ * 16, $chunkZ * 16 + 15); $y = $this->getHighestWorkableBlock($x, $z); if($y !== -1 and $this->canTallGrassStay($x, $y, $z)){ - $this->level->setBlockIdAndDataAt($x, $y, $z, Block::TALL_GRASS, 1); + $this->level->setBlockAt($x, $y, $z, $block); } } } private function canTallGrassStay(int $x, int $y, int $z) : bool{ - $b = $this->level->getBlockIdAt($x, $y, $z); - return ($b === Block::AIR or $b === Block::SNOW_LAYER) and $this->level->getBlockIdAt($x, $y - 1, $z) === Block::GRASS; + $b = $this->level->getBlockAt($x, $y, $z)->getId(); + return ($b === Block::AIR or $b === Block::SNOW_LAYER) and $this->level->getBlockAt($x, $y - 1, $z)->getId() === Block::GRASS; } private function getHighestWorkableBlock(int $x, int $z) : int{ for($y = 127; $y >= 0; --$y){ - $b = $this->level->getBlockIdAt($x, $y, $z); + $b = $this->level->getBlockAt($x, $y, $z)->getId(); if($b !== Block::AIR and $b !== Block::LEAVES and $b !== Block::LEAVES2 and $b !== Block::SNOW_LAYER){ break; } diff --git a/src/pocketmine/level/generator/populator/Tree.php b/src/pocketmine/level/generator/populator/Tree.php index d63b311ea7..17102fc448 100644 --- a/src/pocketmine/level/generator/populator/Tree.php +++ b/src/pocketmine/level/generator/populator/Tree.php @@ -65,7 +65,7 @@ class Tree extends Populator{ private function getHighestWorkableBlock(int $x, int $z) : int{ for($y = 127; $y > 0; --$y){ - $b = $this->level->getBlockIdAt($x, $y, $z); + $b = $this->level->getBlockAt($x, $y, $z)->getId(); if($b === Block::DIRT or $b === Block::GRASS){ break; }elseif($b !== Block::AIR and $b !== Block::SNOW_LAYER){ From ceef3110d7b086d4cff7739426a39d3ef2ea534c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Dec 2018 14:09:19 +0000 Subject: [PATCH 0319/3224] Remove dead function --- src/pocketmine/block/Air.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/pocketmine/block/Air.php b/src/pocketmine/block/Air.php index 8451e5a19b..e7a11e0ea7 100644 --- a/src/pocketmine/block/Air.php +++ b/src/pocketmine/block/Air.php @@ -42,10 +42,6 @@ class Air extends Transparent{ return "Air"; } - public function canPassThrough() : bool{ - return true; - } - public function isBreakable(Item $item) : bool{ return false; } From 2014ebccd81796380c37edc315b03cae58382c5e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Dec 2018 15:03:59 +0000 Subject: [PATCH 0320/3224] Make state setters fluent, clean up some BlockFactory noise --- src/pocketmine/block/BlockFactory.php | 33 ++++++------------------- src/pocketmine/block/DaylightSensor.php | 8 +++++- src/pocketmine/block/Furnace.php | 8 +++++- src/pocketmine/block/Liquid.php | 8 +++++- src/pocketmine/block/RedstoneLamp.php | 8 +++++- src/pocketmine/block/RedstoneOre.php | 8 +++++- src/pocketmine/block/RedstoneTorch.php | 8 +++++- 7 files changed, 49 insertions(+), 32 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 7251e6523d..5ad7538ee7 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -101,13 +101,9 @@ class BlockFactory{ self::registerBlock(new Bedrock()); self::registerBlock(new Water()); - $b = new Water(); - $b->setStill(); - self::registerBlock($b); //flattening hack + self::registerBlock((new Water())->setStill()); //flattening hack self::registerBlock(new Lava()); - $b = new Lava(); - $b->setStill(); - self::registerBlock($b); //flattening hack + self::registerBlock((new Lava())->setStill()); //flattening hack self::registerBlock(new Sand(Block::SAND, 0, "Sand")); self::registerBlock(new Sand(Block::SAND, 1, "Red Sand")); @@ -214,10 +210,7 @@ class BlockFactory{ self::registerBlock(new Farmland()); self::registerBlock(new Furnace()); - - $furnace = new Furnace(); - $furnace->setLit(); - self::registerBlock($furnace); //flattening hack + self::registerBlock((new Furnace())->setLit()); //flattening hack self::registerBlock(new SignPost()); self::registerBlock(new WoodenDoor(Block::OAK_DOOR_BLOCK, 0, "Oak Door", Item::OAK_DOOR)); @@ -230,16 +223,9 @@ class BlockFactory{ self::registerBlock(new IronDoor()); self::registerBlock(new WoodenPressurePlate()); self::registerBlock(new RedstoneOre()); - - $litRedstone = new RedstoneOre(); - $litRedstone->setLit(); - self::registerBlock($litRedstone); //flattening hack - + self::registerBlock((new RedstoneOre())->setLit()); //flattening hack self::registerBlock(new RedstoneTorch()); - $unlitRedstoneTorch = new RedstoneTorch(); - $unlitRedstoneTorch->setLit(false); - self::registerBlock($unlitRedstoneTorch); //flattening hack - + self::registerBlock((new RedstoneTorch())->setLit()); //flattening hack self::registerBlock(new StoneButton()); self::registerBlock(new SnowLayer()); self::registerBlock(new Ice()); @@ -292,10 +278,7 @@ class BlockFactory{ self::registerBlock(new EndStone()); //TODO: DRAGON_EGG self::registerBlock(new RedstoneLamp()); - $litLamp = new RedstoneLamp(); - $litLamp->setLit(); - self::registerBlock($litLamp); //flattening hack - + self::registerBlock((new RedstoneLamp())->setLit()); //flattening hack //TODO: DROPPER self::registerBlock(new ActivatorRail()); self::registerBlock(new CocoaBlock()); @@ -330,9 +313,7 @@ class BlockFactory{ //TODO: COMPARATOR_BLOCK //TODO: POWERED_COMPARATOR self::registerBlock(new DaylightSensor()); - $invertedSensor = new DaylightSensor(); - $invertedSensor->setInverted(); - self::registerBlock($invertedSensor); //flattening hack + self::registerBlock((new DaylightSensor())->setInverted()); //flattening hack self::registerBlock(new Redstone()); self::registerBlock(new NetherQuartzOre()); diff --git a/src/pocketmine/block/DaylightSensor.php b/src/pocketmine/block/DaylightSensor.php index ee64b39d85..7afda00e3f 100644 --- a/src/pocketmine/block/DaylightSensor.php +++ b/src/pocketmine/block/DaylightSensor.php @@ -62,8 +62,14 @@ class DaylightSensor extends Transparent{ return $this->inverted; } - public function setInverted(bool $inverted = true) : void{ + /** + * @param bool $inverted + * + * @return $this + */ + public function setInverted(bool $inverted = true) : self{ $this->inverted = $inverted; + return $this; } public function getName() : string{ diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index 0a7295515e..06473a53a0 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -85,8 +85,14 @@ class Furnace extends Solid{ return $this->lit; } - public function setLit(bool $lit = true) : void{ + /** + * @param bool $lit + * + * @return $this + */ + public function setLit(bool $lit = true) : self{ $this->lit = $lit; + return $this; } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index 4665f23737..d365ca2d4a 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -137,8 +137,14 @@ abstract class Liquid extends Transparent{ return $this->still; } - public function setStill(bool $still = true) : void{ + /** + * @param bool $still + * + * @return $this + */ + public function setStill(bool $still = true) : self{ $this->still = $still; + return $this; } protected function getEffectiveFlowDecay(Block $block) : int{ diff --git a/src/pocketmine/block/RedstoneLamp.php b/src/pocketmine/block/RedstoneLamp.php index 421268d7e6..34b97a212d 100644 --- a/src/pocketmine/block/RedstoneLamp.php +++ b/src/pocketmine/block/RedstoneLamp.php @@ -42,8 +42,14 @@ class RedstoneLamp extends Solid{ return $this->lit; } - public function setLit(bool $lit = true) : void{ + /** + * @param bool $lit + * + * @return $this + */ + public function setLit(bool $lit = true) : self{ $this->lit = $lit; + return $this; } public function getLightLevel() : int{ diff --git a/src/pocketmine/block/RedstoneOre.php b/src/pocketmine/block/RedstoneOre.php index ffcef7ba1b..592b5f0bb3 100644 --- a/src/pocketmine/block/RedstoneOre.php +++ b/src/pocketmine/block/RedstoneOre.php @@ -56,8 +56,14 @@ class RedstoneOre extends Solid{ return $this->lit; } - public function setLit(bool $lit = true) : void{ + /** + * @param bool $lit + * + * @return $this + */ + public function setLit(bool $lit = true) : self{ $this->lit = $lit; + return $this; } public function getLightLevel() : int{ diff --git a/src/pocketmine/block/RedstoneTorch.php b/src/pocketmine/block/RedstoneTorch.php index c8b9ab9a5b..51b03843ff 100644 --- a/src/pocketmine/block/RedstoneTorch.php +++ b/src/pocketmine/block/RedstoneTorch.php @@ -42,8 +42,14 @@ class RedstoneTorch extends Torch{ return $this->lit; } - public function setLit(bool $lit = true) : void{ + /** + * @param bool $lit + * + * @return $this + */ + public function setLit(bool $lit = true) : self{ $this->lit = $lit; + return $this; } public function getLightLevel() : int{ From 281d8fd813c0c7ad20d8d097e3b7f442785f7276 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Dec 2018 15:07:18 +0000 Subject: [PATCH 0321/3224] Redstone torch is lit by default --- src/pocketmine/block/BlockFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 5ad7538ee7..ad57b94243 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -225,7 +225,7 @@ class BlockFactory{ self::registerBlock(new RedstoneOre()); self::registerBlock((new RedstoneOre())->setLit()); //flattening hack self::registerBlock(new RedstoneTorch()); - self::registerBlock((new RedstoneTorch())->setLit()); //flattening hack + self::registerBlock((new RedstoneTorch())->setLit(false)); //flattening hack self::registerBlock(new StoneButton()); self::registerBlock(new SnowLayer()); self::registerBlock(new Ice()); From c53d3c28fbdb5f1395eee271aa3621c62b9eb2c2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Dec 2018 19:11:54 +0000 Subject: [PATCH 0322/3224] Register a couple of simple missing redstone blocks --- src/pocketmine/block/BlockFactory.php | 6 +- src/pocketmine/block/RedstoneRepeater.php | 114 ++++++++++++++++++++++ src/pocketmine/block/RedstoneWire.php | 61 ++++++++++++ 3 files changed, 178 insertions(+), 3 deletions(-) create mode 100644 src/pocketmine/block/RedstoneRepeater.php create mode 100644 src/pocketmine/block/RedstoneWire.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index ad57b94243..676e6fa7fb 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -202,7 +202,7 @@ class BlockFactory{ self::registerBlock(new MonsterSpawner()); self::registerBlock(new WoodenStairs(Block::OAK_STAIRS, 0, "Oak Stairs")); self::registerBlock(new Chest()); - //TODO: REDSTONE_WIRE + self::registerBlock(new RedstoneWire()); self::registerBlock(new DiamondOre()); self::registerBlock(new Diamond()); self::registerBlock(new CraftingTable()); @@ -242,8 +242,8 @@ class BlockFactory{ //TODO: PORTAL self::registerBlock(new LitPumpkin()); self::registerBlock(new Cake()); - //TODO: REPEATER_BLOCK - //TODO: POWERED_REPEATER + self::registerBlock(new RedstoneRepeater()); + self::registerBlock((new RedstoneRepeater())->setPowered()); //TODO: INVISIBLEBEDROCK self::registerBlock(new Trapdoor()); //TODO: MONSTER_EGG diff --git a/src/pocketmine/block/RedstoneRepeater.php b/src/pocketmine/block/RedstoneRepeater.php new file mode 100644 index 0000000000..43f8b0b9a7 --- /dev/null +++ b/src/pocketmine/block/RedstoneRepeater.php @@ -0,0 +1,114 @@ +powered ? Block::POWERED_REPEATER : Block::UNPOWERED_REPEATER; + } + + public function readStateFromMeta(int $meta) : void{ + $this->facing = Bearing::toFacing($meta & 0x03); + $this->delay = ($meta >> 2) + 1; + } + + public function writeStateToMeta() : int{ + return Bearing::fromFacing($this->facing) | (($this->delay - 1) << 2); + } + + public function getStateBitmask() : int{ + return 0b1111; + } + + public function getName() : string{ + return "Redstone Repeater"; + } + + protected function recalculateBoundingBox() : ?AxisAlignedBB{ + return AxisAlignedBB::one()->trim(Facing::UP, 7 / 8); + } + + public function isPowered() : bool{ + return $this->powered; + } + + /** + * @param bool $powered + * + * @return $this + */ + public function setPowered(bool $powered = true) : self{ + $this->powered = $powered; + return $this; + } + + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + if(!$blockReplace->getSide(Facing::DOWN)->isTransparent()){ + if($player !== null){ + $this->facing = Facing::opposite(Bearing::toFacing($player->getDirection())); + } + + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + + return false; + } + + public function onActivate(Item $item, Player $player = null) : bool{ + if(++$this->delay > 4){ + $this->delay = 1; + } + $this->level->setBlock($this, $this); + return true; + } + + public function onNearbyBlockChange() : void{ + if($this->getSide(Facing::DOWN)->isTransparent()){ + $this->level->useBreakOn($this); + } + } + + //TODO: redstone functionality +} diff --git a/src/pocketmine/block/RedstoneWire.php b/src/pocketmine/block/RedstoneWire.php new file mode 100644 index 0000000000..f9dc52266c --- /dev/null +++ b/src/pocketmine/block/RedstoneWire.php @@ -0,0 +1,61 @@ +power = $meta; + } + + protected function writeStateToMeta() : int{ + return $this->power; + } + + public function getStateBitmask() : int{ + return 0b1111; + } + + public function getName() : string{ + return "Redstone"; + } + + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); + //TODO: check connections to nearby redstone components + } +} From f60d13548e3e8a6c8ae7b23fc14ea114ba2ca8a4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Dec 2018 20:10:00 +0000 Subject: [PATCH 0323/3224] Fix another stupid recursion bug --- src/pocketmine/block/Block.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index d9795e9650..67adef400b 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -479,7 +479,6 @@ class Block extends Position implements BlockIds, Metadatable{ $this->y = $y; $this->z = $z; $this->level = $level; - $this->readStateFromWorld(); } /** From 39e383a17589e3041754842b09d603002d10a2b9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Dec 2018 20:27:43 +0000 Subject: [PATCH 0324/3224] Entity: add getHorizontalFacing(), clean up some boilerplate code --- src/pocketmine/block/Anvil.php | 2 +- src/pocketmine/block/Bed.php | 2 +- src/pocketmine/block/Chest.php | 7 +++---- src/pocketmine/block/Door.php | 2 +- src/pocketmine/block/EndPortalFrame.php | 2 +- src/pocketmine/block/EnderChest.php | 3 +-- src/pocketmine/block/FenceGate.php | 4 ++-- src/pocketmine/block/Furnace.php | 3 +-- src/pocketmine/block/GlazedTerracotta.php | 3 +-- src/pocketmine/block/Lever.php | 3 +-- src/pocketmine/block/RedstoneRepeater.php | 2 +- src/pocketmine/block/Stair.php | 3 +-- src/pocketmine/block/Trapdoor.php | 3 +-- src/pocketmine/entity/Entity.php | 4 ++++ 14 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index 78909e6662..5f48df0f1f 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -87,7 +87,7 @@ class Anvil extends Fallable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ - $this->facing = Bearing::toFacing(Bearing::rotate($player->getDirection(), 1)); + $this->facing = Facing::rotate($player->getHorizontalFacing(), Facing::AXIS_Y, true); } return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index fcbcbe202a..8291967042 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -185,7 +185,7 @@ class Bed extends Transparent{ $this->color = $item->getDamage(); //TODO: replace this with a proper colour getter $down = $this->getSide(Facing::DOWN); if(!$down->isTransparent()){ - $this->facing = $player !== null ? Bearing::toFacing($player->getDirection()) : Facing::NORTH; + $this->facing = $player !== null ? $player->getHorizontalFacing() : Facing::NORTH; $next = $this->getSide($this->getOtherHalfSide()); if($next->canBeReplaced() and !$next->getSide(Facing::DOWN)->isTransparent()){ diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index 8b4fea601c..c83ef3eac4 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -25,7 +25,6 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -75,12 +74,12 @@ class Chest extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $chest = null; if($player !== null){ - $this->facing = Bearing::toFacing(Bearing::opposite($player->getDirection())); + $this->facing = Facing::opposite($player->getHorizontalFacing()); } foreach([ - Bearing::toFacing(Bearing::rotate($player->getDirection(), -1)), - Bearing::toFacing(Bearing::rotate($player->getDirection(), 1)) + Facing::rotate($player->getHorizontalFacing(), Facing::AXIS_Y, false), + Facing::rotate($player->getHorizontalFacing(), Facing::AXIS_Y, true) ] as $side){ $c = $this->getSide($side); if($c instanceof Chest and $c->isSameType($this) and $c->facing === $this->facing){ diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 76a67c7fa5..fcf9573e61 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -110,7 +110,7 @@ abstract class Door extends Transparent{ } if($player !== null){ - $this->facing = Bearing::toFacing($player->getDirection()); + $this->facing = $player->getHorizontalFacing(); } $next = $this->getSide(Facing::rotate($this->facing, Facing::AXIS_Y, false)); diff --git a/src/pocketmine/block/EndPortalFrame.php b/src/pocketmine/block/EndPortalFrame.php index 438d0a2c2c..d981ae9138 100644 --- a/src/pocketmine/block/EndPortalFrame.php +++ b/src/pocketmine/block/EndPortalFrame.php @@ -82,7 +82,7 @@ class EndPortalFrame extends Solid{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ - $this->facing = Bearing::toFacing(Bearing::opposite($player->getDirection())); + $this->facing = Facing::opposite($player->getHorizontalFacing()); } return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index eab6beaffe..f58ce88b0b 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -26,7 +26,6 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; -use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -63,7 +62,7 @@ class EnderChest extends Chest{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ //same as normal chest - TODO: clean up inheritance here - $this->facing = Bearing::toFacing(Bearing::opposite($player->getDirection())); + $this->facing = Facing::opposite($player->getHorizontalFacing()); } if(Block::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index 5dcb60ded6..fdf1a060e6 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -69,7 +69,7 @@ class FenceGate extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ - $this->facing = Bearing::toFacing($player->getDirection()); + $this->facing = $player->getHorizontalFacing(); } return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); @@ -78,7 +78,7 @@ class FenceGate extends Transparent{ public function onActivate(Item $item, Player $player = null) : bool{ $this->open = !$this->open; if($this->open and $player !== null){ - $playerFacing = Bearing::toFacing($player->getDirection()); + $playerFacing = $player->getHorizontalFacing(); if($playerFacing === Facing::opposite($this->facing)){ $this->facing = $playerFacing; } diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index 06473a53a0..38e8d91b17 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -25,7 +25,6 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\item\TieredTool; -use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -97,7 +96,7 @@ class Furnace extends Solid{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ - $this->facing = Bearing::toFacing(Bearing::opposite($player->getDirection())); + $this->facing = Facing::opposite($player->getHorizontalFacing()); } if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ Tile::createTile(Tile::FURNACE, $this->getLevel(), TileFurnace::createNBT($this, $item)); diff --git a/src/pocketmine/block/GlazedTerracotta.php b/src/pocketmine/block/GlazedTerracotta.php index f3b5e72c5e..940ee38249 100644 --- a/src/pocketmine/block/GlazedTerracotta.php +++ b/src/pocketmine/block/GlazedTerracotta.php @@ -26,7 +26,6 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\item\TieredTool; -use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -62,7 +61,7 @@ class GlazedTerracotta extends Solid{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ - $this->facing = Bearing::toFacing(Bearing::opposite($player->getDirection())); + $this->facing = Facing::opposite($player->getHorizontalFacing()); } return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index 410ef6ff91..f813a78313 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; @@ -94,7 +93,7 @@ class Lever extends Flowable{ if(Facing::axis($face) === Facing::AXIS_Y){ if($player !== null){ - $this->facing = Bearing::toFacing(Bearing::opposite($player->getDirection())); + $this->facing = Facing::opposite($player->getHorizontalFacing()); } $this->position = $face === Facing::DOWN ? self::BOTTOM : self::TOP; }else{ diff --git a/src/pocketmine/block/RedstoneRepeater.php b/src/pocketmine/block/RedstoneRepeater.php index 43f8b0b9a7..d64fe598fb 100644 --- a/src/pocketmine/block/RedstoneRepeater.php +++ b/src/pocketmine/block/RedstoneRepeater.php @@ -87,7 +87,7 @@ class RedstoneRepeater extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if(!$blockReplace->getSide(Facing::DOWN)->isTransparent()){ if($player !== null){ - $this->facing = Facing::opposite(Bearing::toFacing($player->getDirection())); + $this->facing = Facing::opposite($player->getHorizontalFacing()); } return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index 2b24031305..4a26c4ca28 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -25,7 +25,6 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -108,7 +107,7 @@ abstract class Stair extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ - $this->facing = Bearing::toFacing($player->getDirection()); + $this->facing = $player->getHorizontalFacing(); } $this->upsideDown = (($clickVector->y > 0.5 and $face !== Facing::UP) or $face === Facing::DOWN); diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index 625824409d..9466ebeff1 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -26,7 +26,6 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\level\sound\DoorSound; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -78,7 +77,7 @@ class Trapdoor extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ - $this->facing = Bearing::toFacing(Bearing::opposite($player->getDirection())); + $this->facing = Facing::opposite($player->getHorizontalFacing()); } if(($clickVector->y > 0.5 and $face !== Facing::UP) or $face === Facing::DOWN){ $this->top = true; diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 6085f4ae1d..f5239bf36f 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -1289,6 +1289,10 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ return Bearing::fromAngle($this->yaw); } + public function getHorizontalFacing() : int{ + return Bearing::toFacing($this->getDirection()); + } + /** * @return Vector3 */ From 8dbeda69a71c4f970e4489166b3d265ae1fd9908 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Dec 2018 10:49:12 +0000 Subject: [PATCH 0325/3224] Make use of Facing::rotateY() to reduce boilerplate --- composer.lock | 18 +++++++++--------- src/pocketmine/block/Anvil.php | 4 ++-- src/pocketmine/block/Chest.php | 4 ++-- src/pocketmine/block/CocoaBlock.php | 2 +- src/pocketmine/block/Door.php | 6 +++--- src/pocketmine/block/Stair.php | 6 +++--- src/pocketmine/entity/object/Painting.php | 2 +- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/composer.lock b/composer.lock index 8269f9a20c..d56dea85a2 100644 --- a/composer.lock +++ b/composer.lock @@ -117,16 +117,16 @@ }, { "name": "mdanter/ecc", - "version": "v0.5.1", + "version": "v0.5.2", "source": { "type": "git", "url": "https://github.com/phpecc/phpecc.git", - "reference": "9a3aca17c6dfc04bdaad2e7ddab3b8df656ffc5b" + "reference": "b95f25cc1bacc83a9f0ccd375900b7cfd343029e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpecc/phpecc/zipball/9a3aca17c6dfc04bdaad2e7ddab3b8df656ffc5b", - "reference": "9a3aca17c6dfc04bdaad2e7ddab3b8df656ffc5b", + "url": "https://api.github.com/repos/phpecc/phpecc/zipball/b95f25cc1bacc83a9f0ccd375900b7cfd343029e", + "reference": "b95f25cc1bacc83a9f0ccd375900b7cfd343029e", "shasum": "" }, "require": { @@ -185,7 +185,7 @@ "secp256k1", "secp256r1" ], - "time": "2018-12-01T23:35:23+00:00" + "time": "2018-12-03T18:17:01+00:00" }, { "name": "pocketmine/binaryutils", @@ -227,12 +227,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "5bb6facf8c46212bdb78d6bb1be6fbd2891b200d" + "reference": "a162c02be87fd49abd195a7330e61be9d4b8e766" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/5bb6facf8c46212bdb78d6bb1be6fbd2891b200d", - "reference": "5bb6facf8c46212bdb78d6bb1be6fbd2891b200d", + "url": "https://api.github.com/repos/pmmp/Math/zipball/a162c02be87fd49abd195a7330e61be9d4b8e766", + "reference": "a162c02be87fd49abd195a7330e61be9d4b8e766", "shasum": "" }, "require": { @@ -258,7 +258,7 @@ "source": "https://github.com/pmmp/Math/tree/master", "issues": "https://github.com/pmmp/Math/issues" }, - "time": "2018-12-02T11:40:31+00:00" + "time": "2018-12-07T10:47:16+00:00" }, { "name": "pocketmine/nbt", diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index 5f48df0f1f..8dd96332f9 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -74,7 +74,7 @@ class Anvil extends Fallable{ } public function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one()->squash(Facing::axis(Facing::rotate($this->facing, Facing::AXIS_Y, false)), 1 / 8); + return AxisAlignedBB::one()->squash(Facing::axis(Facing::rotateY($this->facing, false)), 1 / 8); } public function onActivate(Item $item, Player $player = null) : bool{ @@ -87,7 +87,7 @@ class Anvil extends Fallable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ - $this->facing = Facing::rotate($player->getHorizontalFacing(), Facing::AXIS_Y, true); + $this->facing = Facing::rotateY($player->getHorizontalFacing(), true); } return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index c83ef3eac4..2a6de15a7e 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -78,8 +78,8 @@ class Chest extends Transparent{ } foreach([ - Facing::rotate($player->getHorizontalFacing(), Facing::AXIS_Y, false), - Facing::rotate($player->getHorizontalFacing(), Facing::AXIS_Y, true) + Facing::rotateY($player->getHorizontalFacing(), false), + Facing::rotateY($player->getHorizontalFacing(), true) ] as $side){ $c = $this->getSide($side); if($c instanceof Chest and $c->isSameType($this) and $c->facing === $this->facing){ diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index b2225bf738..3c58587c54 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -75,7 +75,7 @@ class CocoaBlock extends Transparent{ protected function recalculateBoundingBox() : ?AxisAlignedBB{ return AxisAlignedBB::one() - ->squash(Facing::axis(Facing::rotate($this->facing, Facing::AXIS_Y, true)), (6 - $this->age) / 16) //sides + ->squash(Facing::axis(Facing::rotateY($this->facing, true)), (6 - $this->age) / 16) //sides ->trim(Facing::DOWN, (7 - $this->age * 2) / 16) ->trim(Facing::UP, 0.25) ->trim(Facing::opposite($this->facing), 1 / 16) //gap between log and pod diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index fcf9573e61..f1221e1b65 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -92,7 +92,7 @@ abstract class Door extends Transparent{ protected function recalculateBoundingBox() : ?AxisAlignedBB{ return AxisAlignedBB::one() ->extend(Facing::UP, 1) - ->trim($this->open ? Facing::rotate($this->facing, Facing::AXIS_Y, !$this->hingeRight) : $this->facing, 13 / 16); + ->trim($this->open ? Facing::rotateY($this->facing, !$this->hingeRight) : $this->facing, 13 / 16); } public function onNearbyBlockChange() : void{ @@ -113,8 +113,8 @@ abstract class Door extends Transparent{ $this->facing = $player->getHorizontalFacing(); } - $next = $this->getSide(Facing::rotate($this->facing, Facing::AXIS_Y, false)); - $next2 = $this->getSide(Facing::rotate($this->facing, Facing::AXIS_Y, true)); + $next = $this->getSide(Facing::rotateY($this->facing, false)); + $next2 = $this->getSide(Facing::rotateY($this->facing, true)); if($next->isSameType($this) or (!$next2->isTransparent() and $next->isTransparent())){ //Door hinge $this->hingeRight = true; diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index 4a26c4ca28..6ef67b32d5 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -59,7 +59,7 @@ abstract class Stair extends Transparent{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $clockwise = Facing::rotate($this->facing, Facing::AXIS_Y, true); + $clockwise = Facing::rotateY($this->facing, true); if(($backFacing = $this->getPossibleCornerFacing(false)) !== null){ $this->shape = $backFacing === $clockwise ? self::SHAPE_OUTER_RIGHT : self::SHAPE_OUTER_LEFT; }elseif(($frontFacing = $this->getPossibleCornerFacing(true)) !== null){ @@ -82,13 +82,13 @@ abstract class Stair extends Transparent{ $topStep->trim(Facing::opposite($this->facing), 0.5); if($this->shape === self::SHAPE_OUTER_LEFT or $this->shape === self::SHAPE_OUTER_RIGHT){ - $topStep->trim(Facing::rotate($this->facing, Facing::AXIS_Y, $this->shape === self::SHAPE_OUTER_LEFT), 0.5); + $topStep->trim(Facing::rotateY($this->facing, $this->shape === self::SHAPE_OUTER_LEFT), 0.5); }elseif($this->shape === self::SHAPE_INNER_LEFT or $this->shape === self::SHAPE_INNER_RIGHT){ //add an extra cube $extraCube = new AxisAlignedBB(0, $minY, 0, 1, $minY + 0.5, 1); $bbs[] = $extraCube ->trim($this->facing, 0.5) //avoid overlapping with main step - ->trim(Facing::rotate($this->facing, Facing::AXIS_Y, $this->shape === self::SHAPE_INNER_LEFT), 0.5); + ->trim(Facing::rotateY($this->facing, $this->shape === self::SHAPE_INNER_LEFT), 0.5); } $bbs[] = $topStep; diff --git a/src/pocketmine/entity/object/Painting.php b/src/pocketmine/entity/object/Painting.php index 66602ab4fd..072f70ef17 100644 --- a/src/pocketmine/entity/object/Painting.php +++ b/src/pocketmine/entity/object/Painting.php @@ -240,7 +240,7 @@ class Painting extends Entity{ $horizontalStart = (int) (ceil($width / 2) - 1); $verticalStart = (int) (ceil($height / 2) - 1); - $rotatedFace = Facing::rotate($facing, Facing::AXIS_Y, false); + $rotatedFace = Facing::rotateY($facing, false); $oppositeSide = Facing::opposite($facing); From 6dbceda3e854004df6bc76e396753d3ffd9ad3f3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 10 Dec 2018 18:35:26 +0000 Subject: [PATCH 0326/3224] Tile: Fill defaults and move code to constructors where appropriate this is leftovers from when NBT was required to construct a tile. --- src/pocketmine/tile/Banner.php | 13 ++++++++--- src/pocketmine/tile/Chest.php | 8 +++++-- src/pocketmine/tile/ContainerTrait.php | 6 ++++- src/pocketmine/tile/FlowerPot.php | 13 ++++++++++- src/pocketmine/tile/Furnace.php | 31 +++++++++++++++----------- src/pocketmine/tile/ItemFrame.php | 17 +++++++++----- src/pocketmine/tile/NameableTrait.php | 2 +- src/pocketmine/tile/Skull.php | 8 +++---- 8 files changed, 67 insertions(+), 31 deletions(-) diff --git a/src/pocketmine/tile/Banner.php b/src/pocketmine/tile/Banner.php index 6227446193..af14afad00 100644 --- a/src/pocketmine/tile/Banner.php +++ b/src/pocketmine/tile/Banner.php @@ -25,6 +25,8 @@ namespace pocketmine\tile; use pocketmine\item\Banner as ItemBanner; use pocketmine\item\Item; +use pocketmine\level\Level; +use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; @@ -98,16 +100,21 @@ class Banner extends Spawnable implements Nameable{ public const COLOR_WHITE = 15; /** @var int */ - private $baseColor; + private $baseColor = self::COLOR_BLACK; /** * @var ListTag * TODO: break this down further and remove runtime NBT from here entirely */ private $patterns; + public function __construct(Level $level, Vector3 $pos){ + $this->patterns = new ListTag(self::TAG_PATTERNS); + parent::__construct($level, $pos); + } + protected function readSaveData(CompoundTag $nbt) : void{ - $this->baseColor = $nbt->getInt(self::TAG_BASE, self::COLOR_BLACK, true); - $this->patterns = $nbt->getListTag(self::TAG_PATTERNS) ?? new ListTag(self::TAG_PATTERNS); + $this->baseColor = $nbt->getInt(self::TAG_BASE, $this->baseColor, true); + $this->patterns = $nbt->getListTag(self::TAG_PATTERNS) ?? $this->patterns; $this->loadName($nbt); } diff --git a/src/pocketmine/tile/Chest.php b/src/pocketmine/tile/Chest.php index 2a7a16faa4..9ce0fe09e5 100644 --- a/src/pocketmine/tile/Chest.php +++ b/src/pocketmine/tile/Chest.php @@ -26,6 +26,7 @@ namespace pocketmine\tile; use pocketmine\inventory\ChestInventory; use pocketmine\inventory\DoubleChestInventory; use pocketmine\inventory\InventoryHolder; +use pocketmine\level\Level; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; @@ -50,14 +51,17 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ /** @var int|null */ private $pairZ; + public function __construct(Level $level, Vector3 $pos){ + $this->inventory = new ChestInventory($this); + parent::__construct($level, $pos); + } + protected function readSaveData(CompoundTag $nbt) : void{ if($nbt->hasTag(self::TAG_PAIRX, IntTag::class) and $nbt->hasTag(self::TAG_PAIRZ, IntTag::class)){ $this->pairX = $nbt->getInt(self::TAG_PAIRX); $this->pairZ = $nbt->getInt(self::TAG_PAIRZ); } $this->loadName($nbt); - - $this->inventory = new ChestInventory($this); $this->loadItems($nbt); } diff --git a/src/pocketmine/tile/ContainerTrait.php b/src/pocketmine/tile/ContainerTrait.php index 3300924605..71fe631521 100644 --- a/src/pocketmine/tile/ContainerTrait.php +++ b/src/pocketmine/tile/ContainerTrait.php @@ -35,7 +35,7 @@ use pocketmine\nbt\tag\StringTag; */ trait ContainerTrait{ /** @var string|null */ - private $lock; + private $lock = null; /** * @return Inventory @@ -47,10 +47,14 @@ trait ContainerTrait{ $inventoryTag = $tag->getListTag(Container::TAG_ITEMS); $inventory = $this->getRealInventory(); + $slotChangeListener = $inventory->getSlotChangeListener(); + $inventory->setSlotChangeListener(null); //prevent any events being fired by initialization + $inventory->clearAll(); /** @var CompoundTag $itemNBT */ foreach($inventoryTag as $itemNBT){ $inventory->setItem($itemNBT->getByte("Slot"), Item::nbtDeserialize($itemNBT)); } + $inventory->setSlotChangeListener($slotChangeListener); } if($tag->hasTag(Container::TAG_LOCK, StringTag::class)){ diff --git a/src/pocketmine/tile/FlowerPot.php b/src/pocketmine/tile/FlowerPot.php index 7b69d69afd..7ee5c7e681 100644 --- a/src/pocketmine/tile/FlowerPot.php +++ b/src/pocketmine/tile/FlowerPot.php @@ -25,7 +25,11 @@ namespace pocketmine\tile; use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\level\Level; +use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\tag\IntTag; +use pocketmine\nbt\tag\ShortTag; class FlowerPot extends Spawnable{ public const TAG_ITEM = "item"; @@ -34,8 +38,15 @@ class FlowerPot extends Spawnable{ /** @var Item */ private $item; + public function __construct(Level $level, Vector3 $pos){ + $this->item = ItemFactory::get(Item::AIR, 0, 0); + parent::__construct($level, $pos); + } + protected function readSaveData(CompoundTag $nbt) : void{ - $this->item = ItemFactory::get($nbt->getShort(self::TAG_ITEM, 0, true), $nbt->getInt(self::TAG_ITEM_DATA, 0, true), 1); + if($nbt->hasTag(self::TAG_ITEM, ShortTag::class) and $nbt->hasTag(self::TAG_ITEM_DATA, IntTag::class)){ + $this->item = ItemFactory::get($nbt->getShort(self::TAG_ITEM, 0), $nbt->getInt(self::TAG_ITEM_DATA, 0), 1); + } } protected function writeSaveData(CompoundTag $nbt) : void{ diff --git a/src/pocketmine/tile/Furnace.php b/src/pocketmine/tile/Furnace.php index ad03f97348..8cbee9aa1d 100644 --- a/src/pocketmine/tile/Furnace.php +++ b/src/pocketmine/tile/Furnace.php @@ -32,6 +32,8 @@ use pocketmine\inventory\Inventory; use pocketmine\inventory\InventoryHolder; use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\level\Level; +use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\ContainerSetDataPacket; @@ -48,34 +50,37 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ /** @var FurnaceInventory */ protected $inventory; /** @var int */ - private $burnTime; + private $burnTime = 0; /** @var int */ - private $cookTime; + private $cookTime = 0; /** @var int */ - private $maxTime; + private $maxTime = 0; + + public function __construct(Level $level, Vector3 $pos){ + $this->inventory = new FurnaceInventory($this); + $this->inventory->setSlotChangeListener(function(Inventory $inventory, int $slot, Item $oldItem, Item $newItem) : ?Item{ + $this->scheduleUpdate(); + return $newItem; + }); + + parent::__construct($level, $pos); + } protected function readSaveData(CompoundTag $nbt) : void{ - $this->burnTime = max(0, $nbt->getShort(self::TAG_BURN_TIME, 0, true)); + $this->burnTime = max(0, $nbt->getShort(self::TAG_BURN_TIME, $this->burnTime, true)); - $this->cookTime = $nbt->getShort(self::TAG_COOK_TIME, 0, true); + $this->cookTime = $nbt->getShort(self::TAG_COOK_TIME, $this->cookTime, true); if($this->burnTime === 0){ $this->cookTime = 0; } - $this->maxTime = $nbt->getShort(self::TAG_MAX_TIME, 0, true); + $this->maxTime = $nbt->getShort(self::TAG_MAX_TIME, $this->maxTime, true); if($this->maxTime === 0){ $this->maxTime = $this->burnTime; } $this->loadName($nbt); - - $this->inventory = new FurnaceInventory($this); $this->loadItems($nbt); - - $this->inventory->setSlotChangeListener(function(Inventory $inventory, int $slot, Item $oldItem, Item $newItem) : ?Item{ - $this->scheduleUpdate(); - return $newItem; - }); } protected function writeSaveData(CompoundTag $nbt) : void{ diff --git a/src/pocketmine/tile/ItemFrame.php b/src/pocketmine/tile/ItemFrame.php index 4b573395fb..2fbb1f4b5c 100644 --- a/src/pocketmine/tile/ItemFrame.php +++ b/src/pocketmine/tile/ItemFrame.php @@ -25,6 +25,8 @@ namespace pocketmine\tile; use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\level\Level; +use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; class ItemFrame extends Spawnable{ @@ -35,18 +37,21 @@ class ItemFrame extends Spawnable{ /** @var Item */ private $item; /** @var int */ - private $itemRotation; + private $itemRotation = 0; /** @var float */ - private $itemDropChance; + private $itemDropChance = 1.0; + + public function __construct(Level $level, Vector3 $pos){ + $this->item = ItemFactory::get(Item::AIR, 0, 0); + parent::__construct($level, $pos); + } protected function readSaveData(CompoundTag $nbt) : void{ if(($itemTag = $nbt->getCompoundTag(self::TAG_ITEM)) !== null){ $this->item = Item::nbtDeserialize($itemTag); - }else{ - $this->item = ItemFactory::get(Item::AIR, 0, 0); } - $this->itemRotation = $nbt->getByte(self::TAG_ITEM_ROTATION, 0, true); - $this->itemDropChance = $nbt->getFloat(self::TAG_ITEM_DROP_CHANCE, 1.0, true); + $this->itemRotation = $nbt->getByte(self::TAG_ITEM_ROTATION, $this->itemRotation, true); + $this->itemDropChance = $nbt->getFloat(self::TAG_ITEM_DROP_CHANCE, $this->itemDropChance, true); } protected function writeSaveData(CompoundTag $nbt) : void{ diff --git a/src/pocketmine/tile/NameableTrait.php b/src/pocketmine/tile/NameableTrait.php index b623df8db8..c65a679fd2 100644 --- a/src/pocketmine/tile/NameableTrait.php +++ b/src/pocketmine/tile/NameableTrait.php @@ -32,7 +32,7 @@ use pocketmine\nbt\tag\StringTag; */ trait NameableTrait{ /** @var string|null */ - private $customName; + private $customName = null; /** * @return string diff --git a/src/pocketmine/tile/Skull.php b/src/pocketmine/tile/Skull.php index e49460bdf2..1421fe5db2 100644 --- a/src/pocketmine/tile/Skull.php +++ b/src/pocketmine/tile/Skull.php @@ -39,13 +39,13 @@ class Skull extends Spawnable{ public const TAG_MOUTH_TICK_COUNT = "MouthTickCount"; //TAG_Int /** @var int */ - private $skullType; + private $skullType = self::TYPE_SKELETON; /** @var int */ - private $skullRotation; + private $skullRotation = 0; protected function readSaveData(CompoundTag $nbt) : void{ - $this->skullType = $nbt->getByte(self::TAG_SKULL_TYPE, self::TYPE_SKELETON, true); - $this->skullRotation = $nbt->getByte(self::TAG_ROT, 0, true); + $this->skullType = $nbt->getByte(self::TAG_SKULL_TYPE, $this->skullType, true); + $this->skullRotation = $nbt->getByte(self::TAG_ROT, $this->skullRotation, true); } protected function writeSaveData(CompoundTag $nbt) : void{ From d72e4cb9a142560efae68a324e3c1a625839350b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 10 Dec 2018 19:40:37 +0000 Subject: [PATCH 0327/3224] Tile: remove createNBT(), add create(), createFromData(), createFromItem() --- src/pocketmine/block/Bed.php | 9 ++- src/pocketmine/block/Chest.php | 5 +- src/pocketmine/block/EnchantingTable.php | 5 +- src/pocketmine/block/EnderChest.php | 4 +- src/pocketmine/block/FlowerPot.php | 4 +- src/pocketmine/block/Furnace.php | 4 +- src/pocketmine/block/ItemFrame.php | 4 +- src/pocketmine/block/SignPost.php | 5 +- src/pocketmine/block/Skull.php | 11 +-- src/pocketmine/block/StandingBanner.php | 17 ++++- src/pocketmine/item/Banner.php | 14 ++++ src/pocketmine/level/format/Chunk.php | 4 +- src/pocketmine/tile/Banner.php | 17 +---- src/pocketmine/tile/NameableTrait.php | 7 -- src/pocketmine/tile/Tile.php | 90 ++++++++++-------------- 15 files changed, 105 insertions(+), 95 deletions(-) diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 8291967042..28aaa8b5dd 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -86,9 +86,12 @@ class Bed extends Transparent{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); //extra block properties storage hack - $tile = Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($this)); - if($tile instanceof TileBed){ - $tile->setColor($this->color); + $tile = Tile::create(Tile::BED, $this->getLevel(), $this->asVector3()); + if($tile !== null){ + if($tile instanceof TileBed){ + $tile->setColor($this->color); + } + $this->level->addTile($tile); } } diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index 2a6de15a7e..b577ff66ba 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -92,7 +92,10 @@ class Chest extends Transparent{ } if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - $tile = Tile::createTile(Tile::CHEST, $this->getLevel(), TileChest::createNBT($this, $item)); + $tile = Tile::createFromItem(Tile::CHEST, $this->getLevel(), $this->asVector3(), $item); + if($tile !== null){ + $this->level->addTile($tile); + } if($chest instanceof TileChest and $tile instanceof TileChest){ $chest->pairWith($tile); diff --git a/src/pocketmine/block/EnchantingTable.php b/src/pocketmine/block/EnchantingTable.php index 416ec54594..02c3059b18 100644 --- a/src/pocketmine/block/EnchantingTable.php +++ b/src/pocketmine/block/EnchantingTable.php @@ -30,7 +30,6 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; -use pocketmine\tile\EnchantTable as TileEnchantTable; use pocketmine\tile\Tile; class EnchantingTable extends Transparent{ @@ -43,7 +42,9 @@ class EnchantingTable extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - Tile::createTile(Tile::ENCHANT_TABLE, $this->getLevel(), TileEnchantTable::createNBT($this, $item)); + if(($tile = Tile::createFromItem(Tile::ENCHANT_TABLE, $this->getLevel(), $this->asVector3(), $item)) !== null){ + $this->level->addTile($tile); + } return true; } diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index f58ce88b0b..c810263a65 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -66,7 +66,9 @@ class EnderChest extends Chest{ } if(Block::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - Tile::createTile(Tile::ENDER_CHEST, $this->getLevel(), TileEnderChest::createNBT($this, $item)); + if(($tile = Tile::createFromItem(Tile::ENDER_CHEST, $this->getLevel(), $this->asVector3(), $item)) !== null){ + $this->level->addTile($tile); + } return true; } diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 14e48dec40..1c0350dd01 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -69,7 +69,9 @@ class FlowerPot extends Flowable{ } if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - Tile::createTile(Tile::FLOWER_POT, $this->getLevel(), TileFlowerPot::createNBT($this, $item)); + if(($tile = Tile::createFromItem(Tile::FLOWER_POT, $this->getLevel(), $this->asVector3(), $item)) !== null){ + $this->level->addTile($tile); + } return true; } diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index 38e8d91b17..b4a91ccf58 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -99,7 +99,9 @@ class Furnace extends Solid{ $this->facing = Facing::opposite($player->getHorizontalFacing()); } if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - Tile::createTile(Tile::FURNACE, $this->getLevel(), TileFurnace::createNBT($this, $item)); + if(($tile = Tile::createFromItem(Tile::FURNACE, $this->getLevel(), $this->asVector3(), $item)) !== null){ + $this->level->addTile($tile); + } return true; } diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 772665c60d..adbc93d079 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -85,7 +85,9 @@ class ItemFrame extends Flowable{ $this->facing = $face; if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - Tile::createTile(Tile::ITEM_FRAME, $this->getLevel(), TileItemFrame::createNBT($this, $item)); + if(($tile = Tile::createFromItem(Tile::ITEM_FRAME, $this->getLevel(), $this->asVector3(), $item)) !== null){ + $this->level->addTile($tile); + } return true; } diff --git a/src/pocketmine/block/SignPost.php b/src/pocketmine/block/SignPost.php index 8dd99035e5..8f6e027d2e 100644 --- a/src/pocketmine/block/SignPost.php +++ b/src/pocketmine/block/SignPost.php @@ -28,7 +28,6 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; -use pocketmine\tile\Sign as TileSign; use pocketmine\tile\Tile; class SignPost extends Transparent{ @@ -83,7 +82,9 @@ class SignPost extends Transparent{ } if($ret){ - Tile::createTile(Tile::SIGN, $this->getLevel(), TileSign::createNBT($this, $item)); + if(($tile = Tile::createFromItem(Tile::SIGN, $this->getLevel(), $this->asVector3(), $item)) !== null){ + $this->level->addTile($tile); + } return true; } } diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index b49017bb5d..7e54d629f5 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -70,10 +70,13 @@ class Skull extends Flowable{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = Tile::createTile(Tile::SKULL, $this->getLevel(), TileSkull::createNBT($this)); - if($tile instanceof TileSkull){ - $tile->setRotation($this->rotation); - $tile->setType($this->type); + $tile = Tile::create(Tile::SKULL, $this->getLevel(), $this->asVector3()); + if($tile !== null){ + if($tile instanceof TileSkull){ + $tile->setRotation($this->rotation); + $tile->setType($this->type); + } + $this->level->addTile($tile); } } diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index 28898faa45..55745c29d1 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\item\Banner as ItemBanner; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\AxisAlignedBB; @@ -83,7 +84,17 @@ class StandingBanner extends Transparent{ } if($ret){ - Tile::createTile(Tile::BANNER, $this->getLevel(), TileBanner::createNBT($this, $item)); + $tile = Tile::createFromItem(Tile::BANNER, $this->getLevel(), $this->asVector3(), $item); + if($tile !== null){ + if($tile instanceof TileBanner and $item instanceof ItemBanner){ + $tile->setBaseColor($item->getBaseColor()); + if(($patterns = $item->getPatterns()) !== null){ + $tile->setPatterns($patterns); + } + } + + $this->level->addTile($tile); + } return true; } } @@ -105,8 +116,8 @@ class StandingBanner extends Transparent{ $tile = $this->level->getTile($this); $drop = ItemFactory::get(Item::BANNER, ($tile instanceof TileBanner ? $tile->getBaseColor() : 0)); - if($tile instanceof TileBanner and !($patterns = $tile->getPatterns())->empty()){ - $drop->setNamedTagEntry(clone $patterns); + if($tile instanceof TileBanner and $drop instanceof ItemBanner and !($patterns = $tile->getPatterns())->empty()){ + $drop->setPatterns($patterns); } return [$drop]; diff --git a/src/pocketmine/item/Banner.php b/src/pocketmine/item/Banner.php index 9dabb9306a..d5ddb5e39c 100644 --- a/src/pocketmine/item/Banner.php +++ b/src/pocketmine/item/Banner.php @@ -206,6 +206,20 @@ class Banner extends Item{ return $this->getNamedTag()->getListTag(self::TAG_PATTERNS)->count(); } + /** + * @return ListTag|null + */ + public function getPatterns() : ?ListTag{ + return $this->getNamedTag()->getListTag(self::TAG_PATTERNS); + } + + /** + * @param ListTag $patterns + */ + public function setPatterns(ListTag $patterns) : void{ + $this->setNamedTagEntry(clone $patterns); + } + public function correctNBT() : void{ $tag = $this->getNamedTag(); if(!$tag->hasTag(self::TAG_BASE, IntTag::class)){ diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index a457aeb0ba..05ad16c4c9 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -618,7 +618,9 @@ class Chunk{ continue; } - if(Tile::createTile($nbt->getString(Tile::TAG_ID), $level, $nbt) === null){ + if(($tile = Tile::createFromData($nbt->getString(Tile::TAG_ID), $level, $nbt)) !== null){ + $level->addTile($tile); + }else{ $changed = true; continue; } diff --git a/src/pocketmine/tile/Banner.php b/src/pocketmine/tile/Banner.php index af14afad00..c1ed28e693 100644 --- a/src/pocketmine/tile/Banner.php +++ b/src/pocketmine/tile/Banner.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\tile; -use pocketmine\item\Banner as ItemBanner; -use pocketmine\item\Item; use pocketmine\level\Level; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; @@ -35,7 +33,6 @@ use pocketmine\nbt\tag\StringTag; class Banner extends Spawnable implements Nameable{ use NameableTrait { addAdditionalSpawnData as addNameSpawnData; - createAdditionalNBT as createNameNBT; } public const TAG_BASE = "Base"; @@ -274,17 +271,9 @@ class Banner extends Spawnable implements Nameable{ return $this->patterns; } - protected static function createAdditionalNBT(CompoundTag $nbt, ?Item $item = null) : void{ - if($item instanceof ItemBanner){ - $nbt->setInt(self::TAG_BASE, $item->getBaseColor()); - - //TODO: clean this mess up - if($item->getNamedTag()->hasTag(self::TAG_PATTERNS, ListTag::class)){ - $nbt->setTag($item->getNamedTag()->getListTag(self::TAG_PATTERNS)); - } - - self::createNameNBT($nbt, $item); - } + public function setPatterns(ListTag $patterns) : void{ + $this->patterns = clone $patterns; + $this->onChanged(); } public function getDefaultName() : string{ diff --git a/src/pocketmine/tile/NameableTrait.php b/src/pocketmine/tile/NameableTrait.php index c65a679fd2..90dd3d778f 100644 --- a/src/pocketmine/tile/NameableTrait.php +++ b/src/pocketmine/tile/NameableTrait.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\tile; -use pocketmine\item\Item; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\StringTag; @@ -64,12 +63,6 @@ trait NameableTrait{ return $this->customName !== null; } - protected static function createAdditionalNBT(CompoundTag $nbt, ?Item $item = null) : void{ - if($item !== null and $item->hasCustomName()){ - $nbt->setString(Nameable::TAG_CUSTOM_NAME, $item->getCustomName()); - } - } - public function addAdditionalSpawnData(CompoundTag $nbt) : void{ if($this->customName !== null){ $nbt->setString(Nameable::TAG_CUSTOM_NAME, $this->customName); diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/tile/Tile.php index 5cfcc52dda..f60f572a99 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/tile/Tile.php @@ -33,8 +33,6 @@ use pocketmine\level\Level; use pocketmine\level\Position; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\IntTag; -use pocketmine\nbt\tag\StringTag; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; use pocketmine\utils\Utils; @@ -88,21 +86,52 @@ abstract class Tile extends Position{ * @param string $type * @param Level $level * @param CompoundTag $nbt - * @param $args * * @return Tile|null */ - public static function createTile($type, Level $level, CompoundTag $nbt, ...$args) : ?Tile{ + public static function createFromData($type, Level $level, CompoundTag $nbt) : ?Tile{ + $tile = self::create($type, $level, new Vector3($nbt->getInt(self::TAG_X), $nbt->getInt(self::TAG_Y), $nbt->getInt(self::TAG_Z))); + if($tile !== null){ + $tile->readSaveData($nbt); + } + return $tile; + } + + /** + * @param string $type + * @param Level $level + * @param Vector3 $pos + * @param Item $item + * + * @return Tile|null + */ + public static function createFromItem(string $type, Level $level, Vector3 $pos, Item $item) : ?Tile{ + $tile = self::create($type, $level, $pos); + if($tile !== null and $item->hasCustomBlockData()){ + $tile->readSaveData($item->getCustomBlockData()); + } + if($tile instanceof Nameable and $item->hasCustomName()){ //this should take precedence over saved NBT + $tile->setName($item->getCustomName()); + } + + return $tile; + } + + /** + * @param string $type + * @param Level $level + * @param Vector3 $pos + * + * @return Tile|null + */ + public static function create(string $type, Level $level, Vector3 $pos) : ?Tile{ if(isset(self::$knownTiles[$type])){ - $pos = new Vector3($nbt->getInt(self::TAG_X), $nbt->getInt(self::TAG_Y), $nbt->getInt(self::TAG_Z)); $class = self::$knownTiles[$type]; /** * @var Tile $tile * @see Tile::__construct() */ $tile = new $class($level, $pos); - $tile->readSaveData($nbt); - $level->addTile($tile); return $tile; } @@ -176,53 +205,6 @@ abstract class Tile extends Position{ return $tag->getCount() > 0 ? $tag : null; } - /** - * Creates and returns a CompoundTag containing the necessary information to spawn a tile of this type. - * - * @param Vector3 $pos - * @param Item|null $item - * - * @return CompoundTag - * @throws \BadMethodCallException - * @throws \InvalidArgumentException - * @throws \InvalidStateException - */ - public static function createNBT(Vector3 $pos, ?Item $item = null) : CompoundTag{ - if(static::class === self::class){ - throw new \BadMethodCallException(__METHOD__ . " must be called from the scope of a child class"); - } - $nbt = new CompoundTag("", [ - new StringTag(self::TAG_ID, static::getSaveId()), - new IntTag(self::TAG_X, (int) $pos->x), - new IntTag(self::TAG_Y, (int) $pos->y), - new IntTag(self::TAG_Z, (int) $pos->z) - ]); - - static::createAdditionalNBT($nbt, $item); - - if($item !== null){ - $customBlockData = $item->getCustomBlockData(); - if($customBlockData !== null){ - foreach($customBlockData as $customBlockDataTag){ - $nbt->setTag(clone $customBlockDataTag); - } - } - } - - return $nbt; - } - - /** - * Called by createNBT() to allow descendent classes to add their own base NBT using the parameters provided. - * TODO: remove this and add a hook for setting data from items post-place - * - * @param CompoundTag $nbt - * @param Item|null $item - */ - protected static function createAdditionalNBT(CompoundTag $nbt, ?Item $item = null) : void{ - - } - /** * @return Block */ From a9dc447f8f0acf5dd3bdd2a05384b3ceca9eaff6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 11 Dec 2018 14:56:25 +0000 Subject: [PATCH 0328/3224] Tile: make createFromData() retrieve the ID by itself --- src/pocketmine/level/format/Chunk.php | 8 +------- src/pocketmine/tile/Tile.php | 7 +++++-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index 05ad16c4c9..3fc1461a3e 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -30,7 +30,6 @@ use pocketmine\block\BlockFactory; use pocketmine\entity\Entity; use pocketmine\level\Level; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\StringTag; use pocketmine\Player; use pocketmine\tile\Spawnable; use pocketmine\tile\Tile; @@ -613,12 +612,7 @@ class Chunk{ $level->timings->syncChunkLoadTileEntitiesTimer->startTiming(); foreach($this->NBTtiles as $nbt){ if($nbt instanceof CompoundTag){ - if(!$nbt->hasTag(Tile::TAG_ID, StringTag::class)){ - $changed = true; - continue; - } - - if(($tile = Tile::createFromData($nbt->getString(Tile::TAG_ID), $level, $nbt)) !== null){ + if(($tile = Tile::createFromData($level, $nbt)) !== null){ $level->addTile($tile); }else{ $changed = true; diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/tile/Tile.php index f60f572a99..f6808cc1fa 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/tile/Tile.php @@ -83,13 +83,16 @@ abstract class Tile extends Position{ } /** - * @param string $type * @param Level $level * @param CompoundTag $nbt * * @return Tile|null */ - public static function createFromData($type, Level $level, CompoundTag $nbt) : ?Tile{ + public static function createFromData(Level $level, CompoundTag $nbt) : ?Tile{ + $type = $nbt->getString(self::TAG_ID, "", true); + if($type === ""){ + return null; + } $tile = self::create($type, $level, new Vector3($nbt->getInt(self::TAG_X), $nbt->getInt(self::TAG_Y), $nbt->getInt(self::TAG_Z))); if($tile !== null){ $tile->readSaveData($nbt); From 19edacbea9982e867fe783c88ddc30beb602d470 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 15 Dec 2018 13:59:10 +0000 Subject: [PATCH 0329/3224] BanIpCommand: fix crash when banning by playername, closes #2578 --- src/pocketmine/command/defaults/BanIpCommand.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/command/defaults/BanIpCommand.php b/src/pocketmine/command/defaults/BanIpCommand.php index af35f7f7c7..5c513171bf 100644 --- a/src/pocketmine/command/defaults/BanIpCommand.php +++ b/src/pocketmine/command/defaults/BanIpCommand.php @@ -58,9 +58,10 @@ class BanIpCommand extends VanillaCommand{ Command::broadcastCommandMessage($sender, new TranslationContainer("commands.banip.success", [$value])); }else{ if(($player = $sender->getServer()->getPlayer($value)) instanceof Player){ - $this->processIPBan($player->getAddress(), $sender, $reason); + $ip = $player->getAddress(); + $this->processIPBan($ip, $sender, $reason); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.banip.success.players", [$player->getAddress(), $player->getName()])); + Command::broadcastCommandMessage($sender, new TranslationContainer("commands.banip.success.players", [$ip, $player->getName()])); }else{ $sender->sendMessage(new TranslationContainer("commands.banip.invalid")); From 3c520aa7863a62442171dd498b8b45a48b44b99d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 16 Dec 2018 14:15:41 +0000 Subject: [PATCH 0330/3224] Particle no longer extends Vector3 --- .../command/defaults/ParticleCommand.php | 81 +++++++++---------- src/pocketmine/entity/object/Painting.php | 2 +- src/pocketmine/entity/projectile/Egg.php | 2 +- src/pocketmine/entity/projectile/Snowball.php | 2 +- src/pocketmine/level/Explosion.php | 2 +- src/pocketmine/level/Level.php | 8 +- .../level/particle/AngryVillagerParticle.php | 6 +- .../particle/BlockForceFieldParticle.php | 6 +- .../level/particle/BubbleParticle.php | 6 +- .../level/particle/CriticalParticle.php | 6 +- .../level/particle/DestroyBlockParticle.php | 7 +- .../level/particle/DustParticle.php | 6 +- .../level/particle/EnchantParticle.php | 6 +- .../particle/EnchantmentTableParticle.php | 6 +- .../level/particle/EntityFlameParticle.php | 6 +- .../level/particle/ExplodeParticle.php | 6 +- .../level/particle/FlameParticle.php | 6 +- .../level/particle/FloatingTextParticle.php | 12 ++- .../level/particle/GenericParticle.php | 7 +- .../level/particle/HappyVillagerParticle.php | 6 +- .../level/particle/HeartParticle.php | 6 +- .../level/particle/HugeExplodeParticle.php | 6 +- .../particle/HugeExplodeSeedParticle.php | 6 +- src/pocketmine/level/particle/InkParticle.php | 6 +- .../level/particle/InstantEnchantParticle.php | 6 +- .../level/particle/ItemBreakParticle.php | 5 +- .../level/particle/LavaDripParticle.php | 6 +- .../level/particle/LavaParticle.php | 6 +- .../level/particle/MobSpawnParticle.php | 7 +- src/pocketmine/level/particle/Particle.php | 6 +- .../level/particle/PortalParticle.php | 6 +- .../level/particle/RainSplashParticle.php | 6 +- .../level/particle/RedstoneParticle.php | 6 +- .../level/particle/SmokeParticle.php | 6 +- .../level/particle/SnowballPoofParticle.php | 6 +- .../level/particle/SplashParticle.php | 6 +- .../level/particle/SporeParticle.php | 6 +- .../level/particle/TerrainParticle.php | 5 +- .../level/particle/WaterDripParticle.php | 6 +- .../level/particle/WaterParticle.php | 6 +- 40 files changed, 122 insertions(+), 186 deletions(-) diff --git a/src/pocketmine/command/defaults/ParticleCommand.php b/src/pocketmine/command/defaults/ParticleCommand.php index d9c67aef28..d875e77016 100644 --- a/src/pocketmine/command/defaults/ParticleCommand.php +++ b/src/pocketmine/command/defaults/ParticleCommand.php @@ -105,7 +105,7 @@ class ParticleCommand extends VanillaCommand{ $data = isset($args[8]) ? (int) $args[8] : null; - $particle = $this->getParticle($name, $pos, $xd, $yd, $zd, $data); + $particle = $this->getParticle($name, $data); if($particle === null){ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.particle.notFound", [$name])); @@ -118,12 +118,11 @@ class ParticleCommand extends VanillaCommand{ $random = new Random((int) (microtime(true) * 1000) + mt_rand()); for($i = 0; $i < $count; ++$i){ - $particle->setComponents( - $pos->x + $random->nextSignedFloat() * $xd, - $pos->y + $random->nextSignedFloat() * $yd, - $pos->z + $random->nextSignedFloat() * $zd - ); - $level->addParticle($particle); + $level->addParticle($pos->add( + $random->nextSignedFloat() * $xd, + $random->nextSignedFloat() * $yd, + $random->nextSignedFloat() * $zd + ), $particle); } return true; @@ -131,97 +130,93 @@ class ParticleCommand extends VanillaCommand{ /** * @param string $name - * @param Vector3 $pos - * @param float $xd - * @param float $yd - * @param float $zd * @param int|null $data * * @return Particle|null */ - private function getParticle(string $name, Vector3 $pos, float $xd, float $yd, float $zd, int $data = null){ + private function getParticle(string $name, int $data = null){ switch($name){ case "explode": - return new ExplodeParticle($pos); + return new ExplodeParticle(); case "hugeexplosion": - return new HugeExplodeParticle($pos); + return new HugeExplodeParticle(); case "hugeexplosionseed": - return new HugeExplodeSeedParticle($pos); + return new HugeExplodeSeedParticle(); case "bubble": - return new BubbleParticle($pos); + return new BubbleParticle(); case "splash": - return new SplashParticle($pos); + return new SplashParticle(); case "wake": case "water": - return new WaterParticle($pos); + return new WaterParticle(); case "crit": - return new CriticalParticle($pos); + return new CriticalParticle(); case "smoke": - return new SmokeParticle($pos, $data ?? 0); + return new SmokeParticle($data ?? 0); case "spell": - return new EnchantParticle($pos); + return new EnchantParticle(); case "instantspell": - return new InstantEnchantParticle($pos); + return new InstantEnchantParticle(); case "dripwater": - return new WaterDripParticle($pos); + return new WaterDripParticle(); case "driplava": - return new LavaDripParticle($pos); + return new LavaDripParticle(); case "townaura": case "spore": - return new SporeParticle($pos); + return new SporeParticle(); case "portal": - return new PortalParticle($pos); + return new PortalParticle(); case "flame": - return new FlameParticle($pos); + return new FlameParticle(); case "lava": - return new LavaParticle($pos); + return new LavaParticle(); case "reddust": - return new RedstoneParticle($pos, $data ?? 1); + return new RedstoneParticle($data ?? 1); case "snowballpoof": - return new ItemBreakParticle($pos, ItemFactory::get(Item::SNOWBALL)); + return new ItemBreakParticle(ItemFactory::get(Item::SNOWBALL)); case "slime": - return new ItemBreakParticle($pos, ItemFactory::get(Item::SLIMEBALL)); + return new ItemBreakParticle(ItemFactory::get(Item::SLIMEBALL)); case "itembreak": if($data !== null and $data !== 0){ - return new ItemBreakParticle($pos, ItemFactory::get($data)); + return new ItemBreakParticle(ItemFactory::get($data)); } break; case "terrain": if($data !== null and $data !== 0){ - return new TerrainParticle($pos, BlockFactory::get($data)); + return new TerrainParticle(BlockFactory::get($data)); } break; case "heart": - return new HeartParticle($pos, $data ?? 0); + return new HeartParticle($data ?? 0); case "ink": - return new InkParticle($pos, $data ?? 0); + return new InkParticle($data ?? 0); case "droplet": - return new RainSplashParticle($pos); + return new RainSplashParticle(); case "enchantmenttable": - return new EnchantmentTableParticle($pos); + return new EnchantmentTableParticle(); case "happyvillager": - return new HappyVillagerParticle($pos); + return new HappyVillagerParticle(); case "angryvillager": - return new AngryVillagerParticle($pos); + return new AngryVillagerParticle(); case "forcefield": - return new BlockForceFieldParticle($pos, $data ?? 0); + return new BlockForceFieldParticle($data ?? 0); } if(strpos($name, "iconcrack_") === 0){ $d = explode("_", $name); if(count($d) === 3){ - return new ItemBreakParticle($pos, ItemFactory::get((int) $d[1], (int) $d[2])); + return new ItemBreakParticle(ItemFactory::get((int) $d[1], (int) $d[2])); } }elseif(strpos($name, "blockcrack_") === 0){ $d = explode("_", $name); if(count($d) === 2){ - return new TerrainParticle($pos, BlockFactory::get($d[1] & 0xff, $d[1] >> 12)); + return new TerrainParticle(BlockFactory::get($d[1] & 0xff, $d[1] >> 12)); } }elseif(strpos($name, "blockdust_") === 0){ $d = explode("_", $name); if(count($d) >= 4){ - return new DustParticle($pos, $d[1] & 0xff, $d[2] & 0xff, $d[3] & 0xff, isset($d[4]) ? $d[4] & 0xff : 255); + return new DustParticle($d[1] & 0xff, $d[2] & 0xff, $d[3] & 0xff, isset($d[4]) ? $d[4] & 0xff : 255); } } diff --git a/src/pocketmine/entity/object/Painting.php b/src/pocketmine/entity/object/Painting.php index 072f70ef17..c69ab5cf5a 100644 --- a/src/pocketmine/entity/object/Painting.php +++ b/src/pocketmine/entity/object/Painting.php @@ -108,7 +108,7 @@ class Painting extends Entity{ //non-living entities don't have a way to create drops generically yet $this->level->dropItem($this, ItemFactory::get(Item::PAINTING)); } - $this->level->addParticle(new DestroyBlockParticle($this->add(0.5, 0.5, 0.5), BlockFactory::get(Block::PLANKS))); + $this->level->addParticle($this->add(0.5, 0.5, 0.5), new DestroyBlockParticle(BlockFactory::get(Block::PLANKS))); } protected function recalculateBoundingBox() : void{ diff --git a/src/pocketmine/entity/projectile/Egg.php b/src/pocketmine/entity/projectile/Egg.php index 21cfb5a732..70a1605544 100644 --- a/src/pocketmine/entity/projectile/Egg.php +++ b/src/pocketmine/entity/projectile/Egg.php @@ -35,7 +35,7 @@ class Egg extends Throwable{ protected function onHit(ProjectileHitEvent $event) : void{ for($i = 0; $i < 6; ++$i){ - $this->level->addParticle(new ItemBreakParticle($this, ItemFactory::get(Item::EGG))); + $this->level->addParticle($this, new ItemBreakParticle(ItemFactory::get(Item::EGG))); } } } diff --git a/src/pocketmine/entity/projectile/Snowball.php b/src/pocketmine/entity/projectile/Snowball.php index 93304822bd..587d980488 100644 --- a/src/pocketmine/entity/projectile/Snowball.php +++ b/src/pocketmine/entity/projectile/Snowball.php @@ -31,7 +31,7 @@ class Snowball extends Throwable{ protected function onHit(ProjectileHitEvent $event) : void{ for($i = 0; $i < 6; ++$i){ - $this->level->addParticle(new SnowballPoofParticle($this)); + $this->level->addParticle($this, new SnowballPoofParticle()); } } } diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index 3aaf290099..0cc56081ec 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -256,7 +256,7 @@ class Explosion{ $pk->records = $send; $this->level->broadcastPacketToViewers($source, $pk); - $this->level->addParticle(new HugeExplodeSeedParticle($source)); + $this->level->addParticle($source, new HugeExplodeSeedParticle()); $this->level->broadcastLevelSoundEvent($source, LevelSoundEventPacket::SOUND_EXPLODE); return true; diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 0d6f05f453..7513497bfb 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -466,15 +466,15 @@ class Level implements ChunkManager, Metadatable{ } } - public function addParticle(Particle $particle, array $players = null){ - $pk = $particle->encode(); + public function addParticle(Vector3 $pos, Particle $particle, array $players = null){ + $pk = $particle->encode($pos); if(!is_array($pk)){ $pk = [$pk]; } if(!empty($pk)){ if($players === null){ foreach($pk as $e){ - $this->broadcastPacketToViewers($particle, $e); + $this->broadcastPacketToViewers($pos, $e); } }else{ $this->server->broadcastPackets($players, $pk); @@ -1761,7 +1761,7 @@ class Level implements ChunkManager, Metadatable{ private function destroyBlockInternal(Block $target, Item $item, ?Player $player = null, bool $createParticles = false) : void{ if($createParticles){ - $this->addParticle(new DestroyBlockParticle($target->add(0.5, 0.5, 0.5), $target)); + $this->addParticle($target->add(0.5, 0.5, 0.5), new DestroyBlockParticle($target)); } $target->onBreak($item, $player); diff --git a/src/pocketmine/level/particle/AngryVillagerParticle.php b/src/pocketmine/level/particle/AngryVillagerParticle.php index 52c8e67629..acde51b426 100644 --- a/src/pocketmine/level/particle/AngryVillagerParticle.php +++ b/src/pocketmine/level/particle/AngryVillagerParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class AngryVillagerParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, Particle::TYPE_VILLAGER_ANGRY); + public function __construct(){ + parent::__construct(Particle::TYPE_VILLAGER_ANGRY); } } diff --git a/src/pocketmine/level/particle/BlockForceFieldParticle.php b/src/pocketmine/level/particle/BlockForceFieldParticle.php index 4ad56cb77a..312ff5c753 100644 --- a/src/pocketmine/level/particle/BlockForceFieldParticle.php +++ b/src/pocketmine/level/particle/BlockForceFieldParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class BlockForceFieldParticle extends GenericParticle{ - public function __construct(Vector3 $pos, int $data = 0){ - parent::__construct($pos, Particle::TYPE_BLOCK_FORCE_FIELD, $data); //TODO: proper encode/decode of data + public function __construct(int $data = 0){ + parent::__construct(Particle::TYPE_BLOCK_FORCE_FIELD, $data); //TODO: proper encode/decode of data } } diff --git a/src/pocketmine/level/particle/BubbleParticle.php b/src/pocketmine/level/particle/BubbleParticle.php index edc50afdae..6bf00072a2 100644 --- a/src/pocketmine/level/particle/BubbleParticle.php +++ b/src/pocketmine/level/particle/BubbleParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class BubbleParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, Particle::TYPE_BUBBLE); + public function __construct(){ + parent::__construct(Particle::TYPE_BUBBLE); } } diff --git a/src/pocketmine/level/particle/CriticalParticle.php b/src/pocketmine/level/particle/CriticalParticle.php index 9ecfff529c..4943527c25 100644 --- a/src/pocketmine/level/particle/CriticalParticle.php +++ b/src/pocketmine/level/particle/CriticalParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class CriticalParticle extends GenericParticle{ - public function __construct(Vector3 $pos, int $scale = 2){ - parent::__construct($pos, Particle::TYPE_CRITICAL, $scale); + public function __construct(int $scale = 2){ + parent::__construct(Particle::TYPE_CRITICAL, $scale); } } diff --git a/src/pocketmine/level/particle/DestroyBlockParticle.php b/src/pocketmine/level/particle/DestroyBlockParticle.php index 3bec46f60d..d7d98548c9 100644 --- a/src/pocketmine/level/particle/DestroyBlockParticle.php +++ b/src/pocketmine/level/particle/DestroyBlockParticle.php @@ -32,15 +32,14 @@ class DestroyBlockParticle extends Particle{ /** @var int */ protected $data; - public function __construct(Vector3 $pos, Block $b){ - parent::__construct($pos->x, $pos->y, $pos->z); + public function __construct(Block $b){ $this->data = $b->getRuntimeId(); } - public function encode(){ + public function encode(Vector3 $pos){ $pk = new LevelEventPacket; $pk->evid = LevelEventPacket::EVENT_PARTICLE_DESTROY; - $pk->position = $this->asVector3(); + $pk->position = $pos; $pk->data = $this->data; return $pk; diff --git a/src/pocketmine/level/particle/DustParticle.php b/src/pocketmine/level/particle/DustParticle.php index e1cb56742e..dda464285a 100644 --- a/src/pocketmine/level/particle/DustParticle.php +++ b/src/pocketmine/level/particle/DustParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class DustParticle extends GenericParticle{ - public function __construct(Vector3 $pos, int $r, int $g, int $b, int $a = 255){ - parent::__construct($pos, Particle::TYPE_DUST, (($a & 0xff) << 24) | (($r & 0xff) << 16) | (($g & 0xff) << 8) | ($b & 0xff)); + public function __construct(int $r, int $g, int $b, int $a = 255){ + parent::__construct(Particle::TYPE_DUST, (($a & 0xff) << 24) | (($r & 0xff) << 16) | (($g & 0xff) << 8) | ($b & 0xff)); } } diff --git a/src/pocketmine/level/particle/EnchantParticle.php b/src/pocketmine/level/particle/EnchantParticle.php index ca2e599ce0..4fc625cd41 100644 --- a/src/pocketmine/level/particle/EnchantParticle.php +++ b/src/pocketmine/level/particle/EnchantParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class EnchantParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, Particle::TYPE_MOB_SPELL); + public function __construct(){ + parent::__construct(Particle::TYPE_MOB_SPELL); } } diff --git a/src/pocketmine/level/particle/EnchantmentTableParticle.php b/src/pocketmine/level/particle/EnchantmentTableParticle.php index 00cd11dc2d..a0756e2ad0 100644 --- a/src/pocketmine/level/particle/EnchantmentTableParticle.php +++ b/src/pocketmine/level/particle/EnchantmentTableParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class EnchantmentTableParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, Particle::TYPE_ENCHANTMENT_TABLE); + public function __construct(){ + parent::__construct(Particle::TYPE_ENCHANTMENT_TABLE); } } diff --git a/src/pocketmine/level/particle/EntityFlameParticle.php b/src/pocketmine/level/particle/EntityFlameParticle.php index 41e688f38e..234da00523 100644 --- a/src/pocketmine/level/particle/EntityFlameParticle.php +++ b/src/pocketmine/level/particle/EntityFlameParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class EntityFlameParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, Particle::TYPE_MOB_FLAME); + public function __construct(){ + parent::__construct(Particle::TYPE_MOB_FLAME); } } diff --git a/src/pocketmine/level/particle/ExplodeParticle.php b/src/pocketmine/level/particle/ExplodeParticle.php index c4c8ce0026..86ef3bb25a 100644 --- a/src/pocketmine/level/particle/ExplodeParticle.php +++ b/src/pocketmine/level/particle/ExplodeParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class ExplodeParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, Particle::TYPE_EXPLODE); + public function __construct(){ + parent::__construct(Particle::TYPE_EXPLODE); } } diff --git a/src/pocketmine/level/particle/FlameParticle.php b/src/pocketmine/level/particle/FlameParticle.php index 89f61c39a2..aa69de17b1 100644 --- a/src/pocketmine/level/particle/FlameParticle.php +++ b/src/pocketmine/level/particle/FlameParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class FlameParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, Particle::TYPE_FLAME); + public function __construct(){ + parent::__construct(Particle::TYPE_FLAME); } } diff --git a/src/pocketmine/level/particle/FloatingTextParticle.php b/src/pocketmine/level/particle/FloatingTextParticle.php index 4c4b511f70..521562e587 100644 --- a/src/pocketmine/level/particle/FloatingTextParticle.php +++ b/src/pocketmine/level/particle/FloatingTextParticle.php @@ -43,12 +43,10 @@ class FloatingTextParticle extends Particle{ protected $invisible = false; /** - * @param Vector3 $pos - * @param string $text - * @param string $title + * @param string $text + * @param string $title */ - public function __construct(Vector3 $pos, string $text, string $title = ""){ - parent::__construct($pos->x, $pos->y, $pos->z); + public function __construct(string $text, string $title = ""){ $this->text = $text; $this->title = $title; } @@ -77,7 +75,7 @@ class FloatingTextParticle extends Particle{ $this->invisible = $value; } - public function encode(){ + public function encode(Vector3 $pos){ $p = []; if($this->entityId === null){ @@ -102,7 +100,7 @@ class FloatingTextParticle extends Particle{ $pk->uuid = $uuid; $pk->username = $name; $pk->entityRuntimeId = $this->entityId; - $pk->position = $this->asVector3(); //TODO: check offset + $pk->position = $pos; //TODO: check offset $pk->item = ItemFactory::get(Item::AIR, 0, 0); $flags = ( diff --git a/src/pocketmine/level/particle/GenericParticle.php b/src/pocketmine/level/particle/GenericParticle.php index b14afa1493..ad9ee2f28c 100644 --- a/src/pocketmine/level/particle/GenericParticle.php +++ b/src/pocketmine/level/particle/GenericParticle.php @@ -32,16 +32,15 @@ class GenericParticle extends Particle{ /** @var int */ protected $data; - public function __construct(Vector3 $pos, int $id, int $data = 0){ - parent::__construct($pos->x, $pos->y, $pos->z); + public function __construct(int $id, int $data = 0){ $this->id = $id & 0xFFF; $this->data = $data; } - public function encode(){ + public function encode(Vector3 $pos){ $pk = new LevelEventPacket; $pk->evid = LevelEventPacket::EVENT_ADD_PARTICLE_MASK | $this->id; - $pk->position = $this->asVector3(); + $pk->position = $pos; $pk->data = $this->data; return $pk; diff --git a/src/pocketmine/level/particle/HappyVillagerParticle.php b/src/pocketmine/level/particle/HappyVillagerParticle.php index d4afcda09f..007478e6e5 100644 --- a/src/pocketmine/level/particle/HappyVillagerParticle.php +++ b/src/pocketmine/level/particle/HappyVillagerParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class HappyVillagerParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, Particle::TYPE_VILLAGER_HAPPY); + public function __construct(){ + parent::__construct(Particle::TYPE_VILLAGER_HAPPY); } } diff --git a/src/pocketmine/level/particle/HeartParticle.php b/src/pocketmine/level/particle/HeartParticle.php index c25271b1da..66d6bb0a00 100644 --- a/src/pocketmine/level/particle/HeartParticle.php +++ b/src/pocketmine/level/particle/HeartParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class HeartParticle extends GenericParticle{ - public function __construct(Vector3 $pos, int $scale = 0){ - parent::__construct($pos, Particle::TYPE_HEART, $scale); + public function __construct(int $scale = 0){ + parent::__construct(Particle::TYPE_HEART, $scale); } } diff --git a/src/pocketmine/level/particle/HugeExplodeParticle.php b/src/pocketmine/level/particle/HugeExplodeParticle.php index bab01f517f..4cb5915175 100644 --- a/src/pocketmine/level/particle/HugeExplodeParticle.php +++ b/src/pocketmine/level/particle/HugeExplodeParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class HugeExplodeParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, Particle::TYPE_HUGE_EXPLODE); + public function __construct(){ + parent::__construct(Particle::TYPE_HUGE_EXPLODE); } } diff --git a/src/pocketmine/level/particle/HugeExplodeSeedParticle.php b/src/pocketmine/level/particle/HugeExplodeSeedParticle.php index 13adce1896..c8a495f750 100644 --- a/src/pocketmine/level/particle/HugeExplodeSeedParticle.php +++ b/src/pocketmine/level/particle/HugeExplodeSeedParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class HugeExplodeSeedParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, Particle::TYPE_HUGE_EXPLODE_SEED); + public function __construct(){ + parent::__construct(Particle::TYPE_HUGE_EXPLODE_SEED); } } diff --git a/src/pocketmine/level/particle/InkParticle.php b/src/pocketmine/level/particle/InkParticle.php index 80fed048f4..37aa82682f 100644 --- a/src/pocketmine/level/particle/InkParticle.php +++ b/src/pocketmine/level/particle/InkParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class InkParticle extends GenericParticle{ - public function __construct(Vector3 $pos, int $scale = 0){ - parent::__construct($pos, Particle::TYPE_INK, $scale); + public function __construct(int $scale = 0){ + parent::__construct(Particle::TYPE_INK, $scale); } } diff --git a/src/pocketmine/level/particle/InstantEnchantParticle.php b/src/pocketmine/level/particle/InstantEnchantParticle.php index 337a89ff38..ed69f3c4b8 100644 --- a/src/pocketmine/level/particle/InstantEnchantParticle.php +++ b/src/pocketmine/level/particle/InstantEnchantParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class InstantEnchantParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, Particle::TYPE_MOB_SPELL_INSTANTANEOUS); + public function __construct(){ + parent::__construct(Particle::TYPE_MOB_SPELL_INSTANTANEOUS); } } diff --git a/src/pocketmine/level/particle/ItemBreakParticle.php b/src/pocketmine/level/particle/ItemBreakParticle.php index 8a5e655a08..1d4146741c 100644 --- a/src/pocketmine/level/particle/ItemBreakParticle.php +++ b/src/pocketmine/level/particle/ItemBreakParticle.php @@ -24,10 +24,9 @@ declare(strict_types=1); namespace pocketmine\level\particle; use pocketmine\item\Item; -use pocketmine\math\Vector3; class ItemBreakParticle extends GenericParticle{ - public function __construct(Vector3 $pos, Item $item){ - parent::__construct($pos, Particle::TYPE_ITEM_BREAK, ($item->getId() << 16) | $item->getDamage()); + public function __construct(Item $item){ + parent::__construct(Particle::TYPE_ITEM_BREAK, ($item->getId() << 16) | $item->getDamage()); } } diff --git a/src/pocketmine/level/particle/LavaDripParticle.php b/src/pocketmine/level/particle/LavaDripParticle.php index 9d71da477e..738a01da5d 100644 --- a/src/pocketmine/level/particle/LavaDripParticle.php +++ b/src/pocketmine/level/particle/LavaDripParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class LavaDripParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, Particle::TYPE_DRIP_LAVA); + public function __construct(){ + parent::__construct(Particle::TYPE_DRIP_LAVA); } } diff --git a/src/pocketmine/level/particle/LavaParticle.php b/src/pocketmine/level/particle/LavaParticle.php index 4d088d31d0..f59210c986 100644 --- a/src/pocketmine/level/particle/LavaParticle.php +++ b/src/pocketmine/level/particle/LavaParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class LavaParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, Particle::TYPE_LAVA); + public function __construct(){ + parent::__construct(Particle::TYPE_LAVA); } } diff --git a/src/pocketmine/level/particle/MobSpawnParticle.php b/src/pocketmine/level/particle/MobSpawnParticle.php index 754e59710b..42a7596275 100644 --- a/src/pocketmine/level/particle/MobSpawnParticle.php +++ b/src/pocketmine/level/particle/MobSpawnParticle.php @@ -32,16 +32,15 @@ class MobSpawnParticle extends Particle{ /** @var int */ protected $height; - public function __construct(Vector3 $pos, int $width = 0, int $height = 0){ - parent::__construct($pos->x, $pos->y, $pos->z); + public function __construct(int $width = 0, int $height = 0){ $this->width = $width; $this->height = $height; } - public function encode(){ + public function encode(Vector3 $pos){ $pk = new LevelEventPacket; $pk->evid = LevelEventPacket::EVENT_PARTICLE_SPAWN; - $pk->position = $this->asVector3(); + $pk->position = $pos; $pk->data = ($this->width & 0xff) + (($this->height & 0xff) << 8); return $pk; diff --git a/src/pocketmine/level/particle/Particle.php b/src/pocketmine/level/particle/Particle.php index 576e924f9a..2f7aa566d7 100644 --- a/src/pocketmine/level/particle/Particle.php +++ b/src/pocketmine/level/particle/Particle.php @@ -26,7 +26,7 @@ namespace pocketmine\level\particle; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\DataPacket; -abstract class Particle extends Vector3{ +abstract class Particle{ public const TYPE_BUBBLE = 1; public const TYPE_CRITICAL = 2; @@ -74,8 +74,10 @@ abstract class Particle extends Vector3{ public const TYPE_FOOD = 44; /** + * @param Vector3 $pos + * * @return DataPacket|DataPacket[] */ - abstract public function encode(); + abstract public function encode(Vector3 $pos); } diff --git a/src/pocketmine/level/particle/PortalParticle.php b/src/pocketmine/level/particle/PortalParticle.php index 66edf03c49..e04898146a 100644 --- a/src/pocketmine/level/particle/PortalParticle.php +++ b/src/pocketmine/level/particle/PortalParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class PortalParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, Particle::TYPE_PORTAL); + public function __construct(){ + parent::__construct(Particle::TYPE_PORTAL); } } diff --git a/src/pocketmine/level/particle/RainSplashParticle.php b/src/pocketmine/level/particle/RainSplashParticle.php index 159ba73c55..67e7977ae1 100644 --- a/src/pocketmine/level/particle/RainSplashParticle.php +++ b/src/pocketmine/level/particle/RainSplashParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class RainSplashParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, Particle::TYPE_RAIN_SPLASH); + public function __construct(){ + parent::__construct(Particle::TYPE_RAIN_SPLASH); } } diff --git a/src/pocketmine/level/particle/RedstoneParticle.php b/src/pocketmine/level/particle/RedstoneParticle.php index 7fa524115c..7516e77b6d 100644 --- a/src/pocketmine/level/particle/RedstoneParticle.php +++ b/src/pocketmine/level/particle/RedstoneParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class RedstoneParticle extends GenericParticle{ - public function __construct(Vector3 $pos, int $lifetime = 1){ - parent::__construct($pos, Particle::TYPE_REDSTONE, $lifetime); + public function __construct(int $lifetime = 1){ + parent::__construct(Particle::TYPE_REDSTONE, $lifetime); } } diff --git a/src/pocketmine/level/particle/SmokeParticle.php b/src/pocketmine/level/particle/SmokeParticle.php index 3653551f9e..6092255b5d 100644 --- a/src/pocketmine/level/particle/SmokeParticle.php +++ b/src/pocketmine/level/particle/SmokeParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class SmokeParticle extends GenericParticle{ - public function __construct(Vector3 $pos, int $scale = 0){ - parent::__construct($pos, Particle::TYPE_SMOKE, $scale); + public function __construct(int $scale = 0){ + parent::__construct(Particle::TYPE_SMOKE, $scale); } } diff --git a/src/pocketmine/level/particle/SnowballPoofParticle.php b/src/pocketmine/level/particle/SnowballPoofParticle.php index 83156d96dc..6e79fa1518 100644 --- a/src/pocketmine/level/particle/SnowballPoofParticle.php +++ b/src/pocketmine/level/particle/SnowballPoofParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class SnowballPoofParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, self::TYPE_SNOWBALL_POOF, 0); + public function __construct(){ + parent::__construct(self::TYPE_SNOWBALL_POOF, 0); } } diff --git a/src/pocketmine/level/particle/SplashParticle.php b/src/pocketmine/level/particle/SplashParticle.php index 8c0eea703a..1001076c79 100644 --- a/src/pocketmine/level/particle/SplashParticle.php +++ b/src/pocketmine/level/particle/SplashParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class SplashParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, Particle::TYPE_WATER_SPLASH); + public function __construct(){ + parent::__construct(Particle::TYPE_WATER_SPLASH); } } diff --git a/src/pocketmine/level/particle/SporeParticle.php b/src/pocketmine/level/particle/SporeParticle.php index 31328aa2a9..883cc24eec 100644 --- a/src/pocketmine/level/particle/SporeParticle.php +++ b/src/pocketmine/level/particle/SporeParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class SporeParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, Particle::TYPE_TOWN_AURA); + public function __construct(){ + parent::__construct(Particle::TYPE_TOWN_AURA); } } diff --git a/src/pocketmine/level/particle/TerrainParticle.php b/src/pocketmine/level/particle/TerrainParticle.php index 8295f3d1d4..c602a82ac3 100644 --- a/src/pocketmine/level/particle/TerrainParticle.php +++ b/src/pocketmine/level/particle/TerrainParticle.php @@ -24,10 +24,9 @@ declare(strict_types=1); namespace pocketmine\level\particle; use pocketmine\block\Block; -use pocketmine\math\Vector3; class TerrainParticle extends GenericParticle{ - public function __construct(Vector3 $pos, Block $b){ - parent::__construct($pos, Particle::TYPE_TERRAIN, $b->getRuntimeId()); + public function __construct(Block $b){ + parent::__construct(Particle::TYPE_TERRAIN, $b->getRuntimeId()); } } diff --git a/src/pocketmine/level/particle/WaterDripParticle.php b/src/pocketmine/level/particle/WaterDripParticle.php index 171937598f..0aa04d79fa 100644 --- a/src/pocketmine/level/particle/WaterDripParticle.php +++ b/src/pocketmine/level/particle/WaterDripParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class WaterDripParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, Particle::TYPE_DRIP_WATER); + public function __construct(){ + parent::__construct(Particle::TYPE_DRIP_WATER); } } diff --git a/src/pocketmine/level/particle/WaterParticle.php b/src/pocketmine/level/particle/WaterParticle.php index 8b1feb1d6e..906bbe29a2 100644 --- a/src/pocketmine/level/particle/WaterParticle.php +++ b/src/pocketmine/level/particle/WaterParticle.php @@ -23,10 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\math\Vector3; - class WaterParticle extends GenericParticle{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, Particle::TYPE_WATER_WAKE); + public function __construct(){ + parent::__construct(Particle::TYPE_WATER_WAKE); } } From 20aaa8373a1b37b2f5e12875411a6ec96819a629 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 16 Dec 2018 14:26:42 +0000 Subject: [PATCH 0331/3224] Sound no longer extends Vector3 --- src/pocketmine/block/Door.php | 2 +- src/pocketmine/block/FenceGate.php | 2 +- src/pocketmine/block/Liquid.php | 2 +- src/pocketmine/block/Trapdoor.php | 2 +- src/pocketmine/entity/projectile/EnderPearl.php | 6 +++--- src/pocketmine/item/ChorusFruit.php | 6 +++--- src/pocketmine/level/Level.php | 6 +++--- src/pocketmine/level/sound/AnvilBreakSound.php | 5 ++--- src/pocketmine/level/sound/AnvilFallSound.php | 5 ++--- src/pocketmine/level/sound/AnvilUseSound.php | 5 ++--- src/pocketmine/level/sound/BlazeShootSound.php | 5 ++--- src/pocketmine/level/sound/ClickSound.php | 5 ++--- src/pocketmine/level/sound/DoorBumpSound.php | 5 ++--- src/pocketmine/level/sound/DoorCrashSound.php | 5 ++--- src/pocketmine/level/sound/DoorSound.php | 5 ++--- src/pocketmine/level/sound/EndermanTeleportSound.php | 5 ++--- src/pocketmine/level/sound/FizzSound.php | 5 ++--- src/pocketmine/level/sound/GenericSound.php | 7 +++---- src/pocketmine/level/sound/GhastShootSound.php | 5 ++--- src/pocketmine/level/sound/GhastSound.php | 5 ++--- src/pocketmine/level/sound/LaunchSound.php | 5 ++--- src/pocketmine/level/sound/PopSound.php | 5 ++--- src/pocketmine/level/sound/Sound.php | 6 ++++-- 23 files changed, 48 insertions(+), 61 deletions(-) diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index f1221e1b65..5f7dc498d3 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -141,7 +141,7 @@ abstract class Door extends Transparent{ } $this->level->setBlock($this, $this); - $this->level->addSound(new DoorSound($this)); + $this->level->addSound($this, new DoorSound()); return true; } diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index fdf1a060e6..d17c9e82e5 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -85,7 +85,7 @@ class FenceGate extends Transparent{ } $this->getLevel()->setBlock($this, $this); - $this->level->addSound(new DoorSound($this)); + $this->level->addSound($this, new DoorSound()); return true; } diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index d8c3ea9c49..f5de8b964e 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -476,7 +476,7 @@ abstract class Liquid extends Transparent{ $ev->call(); if(!$ev->isCancelled()){ $this->level->setBlock($this, $ev->getNewState()); - $this->level->addSound(new FizzSound($this->add(0.5, 0.5, 0.5), 2.6 + (lcg_value() - lcg_value()) * 0.8)); + $this->level->addSound($this->add(0.5, 0.5, 0.5), new FizzSound(2.6 + (lcg_value() - lcg_value()) * 0.8)); } return true; } diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index 9466ebeff1..ac6844d286 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -89,7 +89,7 @@ class Trapdoor extends Transparent{ public function onActivate(Item $item, Player $player = null) : bool{ $this->open = !$this->open; $this->level->setBlock($this, $this); - $this->level->addSound(new DoorSound($this)); + $this->level->addSound($this, new DoorSound()); return true; } diff --git a/src/pocketmine/entity/projectile/EnderPearl.php b/src/pocketmine/entity/projectile/EnderPearl.php index 2bbdfab5e8..2191a71eed 100644 --- a/src/pocketmine/entity/projectile/EnderPearl.php +++ b/src/pocketmine/entity/projectile/EnderPearl.php @@ -60,9 +60,9 @@ class EnderPearl extends Throwable{ //TODO: spawn endermites at origin $this->level->broadcastLevelEvent($owner, LevelEventPacket::EVENT_PARTICLE_ENDERMAN_TELEPORT); - $this->level->addSound(new EndermanTeleportSound($owner)); - $owner->teleport($event->getRayTraceResult()->getHitVector()); - $this->level->addSound(new EndermanTeleportSound($owner)); + $this->level->addSound($owner, new EndermanTeleportSound()); + $owner->teleport($target = $event->getRayTraceResult()->getHitVector()); + $this->level->addSound($target, new EndermanTeleportSound()); $owner->attack(new EntityDamageEvent($owner, EntityDamageEvent::CAUSE_FALL, 5)); } diff --git a/src/pocketmine/item/ChorusFruit.php b/src/pocketmine/item/ChorusFruit.php index 7c9b34ed43..91f7131a9a 100644 --- a/src/pocketmine/item/ChorusFruit.php +++ b/src/pocketmine/item/ChorusFruit.php @@ -77,9 +77,9 @@ class ChorusFruit extends Food{ } //Sounds are broadcasted at both source and destination - $level->addSound(new EndermanTeleportSound($consumer->asVector3())); - $consumer->teleport(new Vector3($x + 0.5, $y + 1, $z + 0.5)); - $level->addSound(new EndermanTeleportSound($consumer->asVector3())); + $level->addSound($consumer->asVector3(), new EndermanTeleportSound()); + $consumer->teleport($target = new Vector3($x + 0.5, $y + 1, $z + 0.5)); + $level->addSound($target, new EndermanTeleportSound()); break; } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 7513497bfb..52743230c3 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -450,15 +450,15 @@ class Level implements ChunkManager, Metadatable{ $this->closed = true; } - public function addSound(Sound $sound, array $players = null){ - $pk = $sound->encode(); + public function addSound(Vector3 $pos, Sound $sound, array $players = null){ + $pk = $sound->encode($pos); if(!is_array($pk)){ $pk = [$pk]; } if(!empty($pk)){ if($players === null){ foreach($pk as $e){ - $this->broadcastPacketToViewers($sound, $e); + $this->broadcastPacketToViewers($pos, $e); } }else{ $this->server->broadcastPackets($players, $pk); diff --git a/src/pocketmine/level/sound/AnvilBreakSound.php b/src/pocketmine/level/sound/AnvilBreakSound.php index c144d8833a..fe8560e752 100644 --- a/src/pocketmine/level/sound/AnvilBreakSound.php +++ b/src/pocketmine/level/sound/AnvilBreakSound.php @@ -23,11 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\sound; -use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; class AnvilBreakSound extends GenericSound{ - public function __construct(Vector3 $pos, float $pitch = 0){ - parent::__construct($pos, LevelEventPacket::EVENT_SOUND_ANVIL_BREAK, $pitch); + public function __construct(float $pitch = 0){ + parent::__construct(LevelEventPacket::EVENT_SOUND_ANVIL_BREAK, $pitch); } } diff --git a/src/pocketmine/level/sound/AnvilFallSound.php b/src/pocketmine/level/sound/AnvilFallSound.php index a1bb8ce174..910603afcf 100644 --- a/src/pocketmine/level/sound/AnvilFallSound.php +++ b/src/pocketmine/level/sound/AnvilFallSound.php @@ -23,11 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\sound; -use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; class AnvilFallSound extends GenericSound{ - public function __construct(Vector3 $pos, float $pitch = 0){ - parent::__construct($pos, LevelEventPacket::EVENT_SOUND_ANVIL_FALL, $pitch); + public function __construct(float $pitch = 0){ + parent::__construct(LevelEventPacket::EVENT_SOUND_ANVIL_FALL, $pitch); } } diff --git a/src/pocketmine/level/sound/AnvilUseSound.php b/src/pocketmine/level/sound/AnvilUseSound.php index 7036e7113b..b9902edcc2 100644 --- a/src/pocketmine/level/sound/AnvilUseSound.php +++ b/src/pocketmine/level/sound/AnvilUseSound.php @@ -23,11 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\sound; -use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; class AnvilUseSound extends GenericSound{ - public function __construct(Vector3 $pos, float $pitch = 0){ - parent::__construct($pos, LevelEventPacket::EVENT_SOUND_ANVIL_USE, $pitch); + public function __construct(float $pitch = 0){ + parent::__construct(LevelEventPacket::EVENT_SOUND_ANVIL_USE, $pitch); } } diff --git a/src/pocketmine/level/sound/BlazeShootSound.php b/src/pocketmine/level/sound/BlazeShootSound.php index 2da36d25bf..7050bb82a9 100644 --- a/src/pocketmine/level/sound/BlazeShootSound.php +++ b/src/pocketmine/level/sound/BlazeShootSound.php @@ -23,11 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\sound; -use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; class BlazeShootSound extends GenericSound{ - public function __construct(Vector3 $pos, float $pitch = 0){ - parent::__construct($pos, LevelEventPacket::EVENT_SOUND_BLAZE_SHOOT, $pitch); + public function __construct(float $pitch = 0){ + parent::__construct(LevelEventPacket::EVENT_SOUND_BLAZE_SHOOT, $pitch); } } diff --git a/src/pocketmine/level/sound/ClickSound.php b/src/pocketmine/level/sound/ClickSound.php index 9ca035309a..24d920b0d0 100644 --- a/src/pocketmine/level/sound/ClickSound.php +++ b/src/pocketmine/level/sound/ClickSound.php @@ -23,11 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\sound; -use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; class ClickSound extends GenericSound{ - public function __construct(Vector3 $pos, float $pitch = 0){ - parent::__construct($pos, LevelEventPacket::EVENT_SOUND_CLICK, $pitch); + public function __construct(float $pitch = 0){ + parent::__construct(LevelEventPacket::EVENT_SOUND_CLICK, $pitch); } } diff --git a/src/pocketmine/level/sound/DoorBumpSound.php b/src/pocketmine/level/sound/DoorBumpSound.php index 0035b1ef77..84f4a18c56 100644 --- a/src/pocketmine/level/sound/DoorBumpSound.php +++ b/src/pocketmine/level/sound/DoorBumpSound.php @@ -23,11 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\sound; -use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; class DoorBumpSound extends GenericSound{ - public function __construct(Vector3 $pos, float $pitch = 0){ - parent::__construct($pos, LevelEventPacket::EVENT_SOUND_DOOR_BUMP, $pitch); + public function __construct(float $pitch = 0){ + parent::__construct(LevelEventPacket::EVENT_SOUND_DOOR_BUMP, $pitch); } } diff --git a/src/pocketmine/level/sound/DoorCrashSound.php b/src/pocketmine/level/sound/DoorCrashSound.php index e9e817b4b4..bd8ab139ee 100644 --- a/src/pocketmine/level/sound/DoorCrashSound.php +++ b/src/pocketmine/level/sound/DoorCrashSound.php @@ -23,11 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\sound; -use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; class DoorCrashSound extends GenericSound{ - public function __construct(Vector3 $pos, float $pitch = 0){ - parent::__construct($pos, LevelEventPacket::EVENT_SOUND_DOOR_CRASH, $pitch); + public function __construct(float $pitch = 0){ + parent::__construct(LevelEventPacket::EVENT_SOUND_DOOR_CRASH, $pitch); } } diff --git a/src/pocketmine/level/sound/DoorSound.php b/src/pocketmine/level/sound/DoorSound.php index 2da8ed9190..623b682d79 100644 --- a/src/pocketmine/level/sound/DoorSound.php +++ b/src/pocketmine/level/sound/DoorSound.php @@ -23,11 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\sound; -use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; class DoorSound extends GenericSound{ - public function __construct(Vector3 $pos, float $pitch = 0){ - parent::__construct($pos, LevelEventPacket::EVENT_SOUND_DOOR, $pitch); + public function __construct(float $pitch = 0){ + parent::__construct(LevelEventPacket::EVENT_SOUND_DOOR, $pitch); } } diff --git a/src/pocketmine/level/sound/EndermanTeleportSound.php b/src/pocketmine/level/sound/EndermanTeleportSound.php index 587a520e8d..4f3230f331 100644 --- a/src/pocketmine/level/sound/EndermanTeleportSound.php +++ b/src/pocketmine/level/sound/EndermanTeleportSound.php @@ -23,11 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\sound; -use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; class EndermanTeleportSound extends GenericSound{ - public function __construct(Vector3 $pos){ - parent::__construct($pos, LevelEventPacket::EVENT_SOUND_ENDERMAN_TELEPORT); + public function __construct(){ + parent::__construct(LevelEventPacket::EVENT_SOUND_ENDERMAN_TELEPORT); } } diff --git a/src/pocketmine/level/sound/FizzSound.php b/src/pocketmine/level/sound/FizzSound.php index 944f9b7462..325cdac707 100644 --- a/src/pocketmine/level/sound/FizzSound.php +++ b/src/pocketmine/level/sound/FizzSound.php @@ -23,11 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\sound; -use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; class FizzSound extends GenericSound{ - public function __construct(Vector3 $pos, float $pitch = 0){ - parent::__construct($pos, LevelEventPacket::EVENT_SOUND_FIZZ, $pitch); + public function __construct(float $pitch = 0){ + parent::__construct(LevelEventPacket::EVENT_SOUND_FIZZ, $pitch); } } diff --git a/src/pocketmine/level/sound/GenericSound.php b/src/pocketmine/level/sound/GenericSound.php index 1aba871a3d..be8262636a 100644 --- a/src/pocketmine/level/sound/GenericSound.php +++ b/src/pocketmine/level/sound/GenericSound.php @@ -33,8 +33,7 @@ class GenericSound extends Sound{ /** @var float */ protected $pitch = 0; - public function __construct(Vector3 $pos, int $id, float $pitch = 0){ - parent::__construct($pos->x, $pos->y, $pos->z); + public function __construct(int $id, float $pitch = 0){ $this->id = $id; $this->pitch = $pitch * 1000; } @@ -47,10 +46,10 @@ class GenericSound extends Sound{ $this->pitch = $pitch * 1000; } - public function encode(){ + public function encode(Vector3 $pos){ $pk = new LevelEventPacket; $pk->evid = $this->id; - $pk->position = $this->asVector3(); + $pk->position = $pos; $pk->data = (int) $this->pitch; return $pk; diff --git a/src/pocketmine/level/sound/GhastShootSound.php b/src/pocketmine/level/sound/GhastShootSound.php index 09000042ee..3e4320942b 100644 --- a/src/pocketmine/level/sound/GhastShootSound.php +++ b/src/pocketmine/level/sound/GhastShootSound.php @@ -23,11 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\sound; -use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; class GhastShootSound extends GenericSound{ - public function __construct(Vector3 $pos, float $pitch = 0){ - parent::__construct($pos, LevelEventPacket::EVENT_SOUND_GHAST_SHOOT, $pitch); + public function __construct(float $pitch = 0){ + parent::__construct(LevelEventPacket::EVENT_SOUND_GHAST_SHOOT, $pitch); } } diff --git a/src/pocketmine/level/sound/GhastSound.php b/src/pocketmine/level/sound/GhastSound.php index cef339b382..568f221586 100644 --- a/src/pocketmine/level/sound/GhastSound.php +++ b/src/pocketmine/level/sound/GhastSound.php @@ -23,11 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\sound; -use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; class GhastSound extends GenericSound{ - public function __construct(Vector3 $pos, float $pitch = 0){ - parent::__construct($pos, LevelEventPacket::EVENT_SOUND_GHAST, $pitch); + public function __construct(float $pitch = 0){ + parent::__construct(LevelEventPacket::EVENT_SOUND_GHAST, $pitch); } } diff --git a/src/pocketmine/level/sound/LaunchSound.php b/src/pocketmine/level/sound/LaunchSound.php index 2ad2e3bfdd..e7f28072f2 100644 --- a/src/pocketmine/level/sound/LaunchSound.php +++ b/src/pocketmine/level/sound/LaunchSound.php @@ -23,11 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\sound; -use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; class LaunchSound extends GenericSound{ - public function __construct(Vector3 $pos, float $pitch = 0){ - parent::__construct($pos, LevelEventPacket::EVENT_SOUND_SHOOT, $pitch); + public function __construct(float $pitch = 0){ + parent::__construct(LevelEventPacket::EVENT_SOUND_SHOOT, $pitch); } } diff --git a/src/pocketmine/level/sound/PopSound.php b/src/pocketmine/level/sound/PopSound.php index adb768ac65..bfc56ee3eb 100644 --- a/src/pocketmine/level/sound/PopSound.php +++ b/src/pocketmine/level/sound/PopSound.php @@ -23,11 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\sound; -use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; class PopSound extends GenericSound{ - public function __construct(Vector3 $pos, float $pitch = 0){ - parent::__construct($pos, LevelEventPacket::EVENT_SOUND_POP, $pitch); + public function __construct(float $pitch = 0){ + parent::__construct(LevelEventPacket::EVENT_SOUND_POP, $pitch); } } diff --git a/src/pocketmine/level/sound/Sound.php b/src/pocketmine/level/sound/Sound.php index 641739e899..0c488d14bb 100644 --- a/src/pocketmine/level/sound/Sound.php +++ b/src/pocketmine/level/sound/Sound.php @@ -26,11 +26,13 @@ namespace pocketmine\level\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\DataPacket; -abstract class Sound extends Vector3{ +abstract class Sound{ /** + * @param Vector3 $pos + * * @return DataPacket|DataPacket[] */ - abstract public function encode(); + abstract public function encode(Vector3 $pos); } From 17e5f604103c656715db2067edd9d9b583c6a0df Mon Sep 17 00:00:00 2001 From: Dylan T Date: Sat, 22 Dec 2018 11:24:04 +0000 Subject: [PATCH 0332/3224] Add community Discord to Discussion section --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 15e616927d..c350247370 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ If you don't find what you're looking for there, [talk to a human](#discussion). ### Discussion - [Forums](https://forums.pmmp.io/) +- [Community Discord](https://discord.gg/bge7dYQ) ### Plugins There are a very wide range of already-written plugins available which you can use to customise your server. Check out [Poggit](https://poggit.pmmp.io), or just search GitHub. From 02efa93e3a8927738c7e668e805841f0131362d4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 23 Dec 2018 18:24:33 +0000 Subject: [PATCH 0333/3224] PlayerPreLoginEvent: New, more elegant way to control authentication requirement Previously the only way to deal with this was to cancel the PlayerKickEvent generated by lack of authentication. Now, plugins can decide whether auth should be required for a specific player. The default is whatever xbox-auth is set to in server.properties. cc @Johnmacrocraft --- src/pocketmine/Player.php | 11 +++++----- .../event/player/PlayerPreLoginEvent.php | 20 ++++++++++++++++++- .../network/mcpe/ProcessLoginTask.php | 7 +++++-- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 56b8d49721..d00f4e2c62 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1732,7 +1732,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->setSkin($packet->skin); - $ev = new PlayerPreLoginEvent($this, "Plugin reason"); + $ev = new PlayerPreLoginEvent($this, "Plugin reason", $this->server->requiresAuthentication()); $ev->call(); if($ev->isCancelled()){ $this->close("", $ev->getKickMessage()); @@ -1756,16 +1756,16 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } if(!$packet->skipVerification){ - $this->server->getAsyncPool()->submitTask(new ProcessLoginTask($this, $packet, NetworkCipher::$ENABLED)); + $this->server->getAsyncPool()->submitTask(new ProcessLoginTask($this, $packet, $ev->isAuthRequired(), NetworkCipher::$ENABLED)); }else{ - $this->setAuthenticationStatus(true, null); + $this->setAuthenticationStatus(false, false, null); $this->networkSession->onLoginSuccess(); } return true; } - public function setAuthenticationStatus(bool $authenticated, ?string $error) : bool{ + public function setAuthenticationStatus(bool $authenticated, bool $authRequired, ?string $error) : bool{ if($this->networkSession === null){ return false; } @@ -1783,7 +1783,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->authenticated = $authenticated; if(!$this->authenticated){ - if($this->server->requiresAuthentication() and $this->kick("disconnectionScreen.notAuthenticated", false)){ //use kick to allow plugins to cancel this + if($authRequired){ + $this->close("", "disconnectionScreen.notAuthenticated"); return false; } diff --git a/src/pocketmine/event/player/PlayerPreLoginEvent.php b/src/pocketmine/event/player/PlayerPreLoginEvent.php index 6ad2ce22fc..3ea25fb4d0 100644 --- a/src/pocketmine/event/player/PlayerPreLoginEvent.php +++ b/src/pocketmine/event/player/PlayerPreLoginEvent.php @@ -42,14 +42,18 @@ use pocketmine\Player; class PlayerPreLoginEvent extends PlayerEvent implements Cancellable{ /** @var string */ protected $kickMessage; + /** @var bool */ + protected $authRequired; /** * @param Player $player * @param string $kickMessage + * @param bool $authRequired */ - public function __construct(Player $player, string $kickMessage){ + public function __construct(Player $player, string $kickMessage, bool $authRequired){ $this->player = $player; $this->kickMessage = $kickMessage; + $this->authRequired = $authRequired; } /** @@ -65,4 +69,18 @@ class PlayerPreLoginEvent extends PlayerEvent implements Cancellable{ public function getKickMessage() : string{ return $this->kickMessage; } + + /** + * @return bool + */ + public function isAuthRequired() : bool{ + return $this->authRequired; + } + + /** + * @param bool $v + */ + public function setAuthRequired(bool $v) : void{ + $this->authRequired = $v; + } } diff --git a/src/pocketmine/network/mcpe/ProcessLoginTask.php b/src/pocketmine/network/mcpe/ProcessLoginTask.php index c130e93c07..89460145d3 100644 --- a/src/pocketmine/network/mcpe/ProcessLoginTask.php +++ b/src/pocketmine/network/mcpe/ProcessLoginTask.php @@ -59,6 +59,8 @@ class ProcessLoginTask extends AsyncTask{ * root public key. */ private $authenticated = false; + /** @var bool */ + private $authRequired; /** * @var bool @@ -74,9 +76,10 @@ class ProcessLoginTask extends AsyncTask{ /** @var string|null */ private $handshakeJwt = null; - public function __construct(Player $player, LoginPacket $packet, bool $useEncryption = true){ + public function __construct(Player $player, LoginPacket $packet, bool $authRequired, bool $useEncryption = true){ $this->storeLocal($player); $this->packet = $packet; + $this->authRequired = $authRequired; $this->useEncryption = $useEncryption; if($useEncryption){ if(self::$SERVER_PRIVATE_KEY === null){ @@ -220,7 +223,7 @@ class ProcessLoginTask extends AsyncTask{ $player = $this->fetchLocal(); if(!$player->isConnected()){ $this->worker->getLogger()->error("Player " . $player->getName() . " was disconnected before their login could be verified"); - }elseif($player->setAuthenticationStatus($this->authenticated, $this->error)){ + }elseif($player->setAuthenticationStatus($this->authenticated, $this->authRequired, $this->error)){ if(!$this->useEncryption){ $player->getNetworkSession()->onLoginSuccess(); }else{ From 9f4bb440bdd9b821bd167fa31b387c54c9c8e45a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 26 Dec 2018 13:46:44 +0000 Subject: [PATCH 0334/3224] Move server-full/banned/whitelisted controls into PlayerPreLoginEvent This allows plugins to more easily control the behaviour of server-full, whitelisting and banning. A message can be assigned for each, with a plugin custom reason taking the final priority if set. This system solves several edge case problems in the Bukkit version by allowing kick reasons to be combined, so that removing one kick reason will roll back the final reason to the next highest, instead of just allowing the player through completely. Only one message will be shown at point of disconnection, for consistency with the old behaviour. The message priority is as follows (for all cases, only if set): - Plugin reason - Server full - Whitelist enabled - Player is banned This also brings us one step closer to separating Player and NetworkSession. --- src/pocketmine/Player.php | 32 ++--- .../event/player/PlayerPreLoginEvent.php | 126 +++++++++++++++--- 2 files changed, 118 insertions(+), 40 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index d00f4e2c62..8ca984e421 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1732,26 +1732,20 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->setSkin($packet->skin); - $ev = new PlayerPreLoginEvent($this, "Plugin reason", $this->server->requiresAuthentication()); + $ev = new PlayerPreLoginEvent($this, $this->server->requiresAuthentication()); + if(count($this->server->getOnlinePlayers()) >= $this->server->getMaxPlayers()){ + $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_SERVER_FULL, "disconnectionScreen.serverFull"); + } + if(!$this->server->isWhitelisted($this->username)){ + $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_SERVER_WHITELISTED, "Server is whitelisted"); + } + if($this->isBanned() or $this->server->getIPBans()->isBanned($this->getAddress())){ + $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_BANNED, "You are banned"); + } + $ev->call(); - if($ev->isCancelled()){ - $this->close("", $ev->getKickMessage()); - - return true; - } - - if(count($this->server->getOnlinePlayers()) >= $this->server->getMaxPlayers() and $this->kick("disconnectionScreen.serverFull", false)){ - return true; - } - - if(!$this->server->isWhitelisted($this->username) and $this->kick("Server is white-listed", false)){ - return true; - } - - if( - ($this->isBanned() or $this->server->getIPBans()->isBanned($this->getAddress())) and - $this->kick("You are banned", false) - ){ + if(!$ev->isAllowed()){ + $this->close("", $ev->getFinalKickMessage()); return true; } diff --git a/src/pocketmine/event/player/PlayerPreLoginEvent.php b/src/pocketmine/event/player/PlayerPreLoginEvent.php index 3ea25fb4d0..5d4d566e44 100644 --- a/src/pocketmine/event/player/PlayerPreLoginEvent.php +++ b/src/pocketmine/event/player/PlayerPreLoginEvent.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\event\player; -use pocketmine\event\Cancellable; use pocketmine\Player; /** @@ -39,37 +38,34 @@ use pocketmine\Player; * WARNING: Due to internal bad architecture, the player is not fully constructed at this stage, and errors might occur * when calling API methods on the player. Tread with caution. */ -class PlayerPreLoginEvent extends PlayerEvent implements Cancellable{ - /** @var string */ - protected $kickMessage; +class PlayerPreLoginEvent extends PlayerEvent{ + public const KICK_REASON_PLUGIN = 0; + public const KICK_REASON_SERVER_FULL = 1; + public const KICK_REASON_SERVER_WHITELISTED = 2; + public const KICK_REASON_BANNED = 3; + + public const KICK_REASON_PRIORITY = [ + self::KICK_REASON_PLUGIN, //Plugin reason should always take priority over anything else + self::KICK_REASON_SERVER_FULL, + self::KICK_REASON_SERVER_WHITELISTED, + self::KICK_REASON_BANNED + ]; + /** @var bool */ protected $authRequired; + /** @var string[] reason const => associated message */ + protected $kickReasons = []; + /** * @param Player $player - * @param string $kickMessage * @param bool $authRequired */ - public function __construct(Player $player, string $kickMessage, bool $authRequired){ + public function __construct(Player $player, bool $authRequired){ $this->player = $player; - $this->kickMessage = $kickMessage; $this->authRequired = $authRequired; } - /** - * @param string $kickMessage - */ - public function setKickMessage(string $kickMessage) : void{ - $this->kickMessage = $kickMessage; - } - - /** - * @return string - */ - public function getKickMessage() : string{ - return $this->kickMessage; - } - /** * @return bool */ @@ -83,4 +79,92 @@ class PlayerPreLoginEvent extends PlayerEvent implements Cancellable{ public function setAuthRequired(bool $v) : void{ $this->authRequired = $v; } + + /** + * Returns an array of kick reasons currently assigned. + * + * @return int[] + */ + public function getKickReasons() : array{ + return array_keys($this->kickReasons); + } + + /** + * Returns whether the given kick reason is set for this event. + * + * @param int $flag + * + * @return bool + */ + public function isKickReasonSet(int $flag) : bool{ + return isset($this->kickReasons[$flag]); + } + + /** + * Sets a reason to disallow the player to continue continue authenticating, with a message. + * This can also be used to change kick messages for already-set flags. + * + * @param int $flag + * @param string $message + */ + public function setKickReason(int $flag, string $message) : void{ + $this->kickReasons[$flag] = $message; + } + + /** + * Clears a specific kick flag if it was set. This allows fine-tuned kick reason removal without impacting other + * reasons (for example, a ban can be bypassed without accidentally allowing a player to join a full server). + * + * @param int $flag Specific flag to clear. + */ + public function clearKickReason(int $flag) : void{ + unset($this->kickReasons[$flag]); + } + + /** + * Clears all pre-assigned kick reasons, allowing the player to continue logging in. + */ + public function clearAllKickReasons() : void{ + $this->kickReasons = []; + } + + /** + * Returns whether the player is allowed to continue logging in. + * + * @return bool + */ + public function isAllowed() : bool{ + return empty($this->kickReasons); + } + + /** + * Returns the kick message provided for the given kick flag, or null if not set. + * + * @param int $flag + * + * @return string|null + */ + public function getKickMessage(int $flag) : ?string{ + return $this->kickReasons[$flag] ?? null; + } + + /** + * Returns the final kick message which will be shown on the disconnect screen. + * + * Note: Only one message (the highest priority one) will be shown. See priority order to decide how to set your + * messages. + * + * @see PlayerPreLoginEvent::KICK_REASON_PRIORITY + * + * @return string + */ + public function getFinalKickMessage() : string{ + foreach(self::KICK_REASON_PRIORITY as $p){ + if(isset($this->kickReasons[$p])){ + return $this->kickReasons[$p]; + } + } + + return ""; + } } From f6983efec12b939b3b6f77914b4ad69a46dc656a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 26 Dec 2018 19:21:37 +0000 Subject: [PATCH 0335/3224] Revamp Tile creation (again) This breaks down the handling of tile creation even further. - Introduced a static Tile::override() method to allow overriding the construction class for a specific type of chest. This applies to classes as opposed to save IDs, so you can override Chest::class with MyCustomChest::class and it will take effect for any Chest save ID. - Removed MCPE stringy save ID constants from public Tile interface. These are now only used for creating saved tiles from a stored chunk, and saving them. - Renamed Tile::registerTile() to register() - Tile::create() and Tile::createFromItem() now accept a class parameter instead of a stringy save ID. - Tile::create() and Tile::createFromItem() were changed to throw \InvalidArgumentException on unknown/unregistered tile types. They also now never return null, but always (except in exception cases) return an object which is an instanceof the base class specified. --- src/pocketmine/block/Bed.php | 11 +- src/pocketmine/block/Chest.php | 18 ++-- src/pocketmine/block/EnchantingTable.php | 5 +- src/pocketmine/block/EnderChest.php | 4 +- src/pocketmine/block/FlowerPot.php | 4 +- src/pocketmine/block/Furnace.php | 4 +- src/pocketmine/block/ItemFrame.php | 4 +- src/pocketmine/block/SignPost.php | 5 +- src/pocketmine/block/Skull.php | 13 +-- src/pocketmine/block/StandingBanner.php | 17 ++-- src/pocketmine/tile/Sign.php | 4 - src/pocketmine/tile/Tile.php | 124 +++++++++++++---------- 12 files changed, 103 insertions(+), 110 deletions(-) diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 28aaa8b5dd..74474e049e 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -86,13 +86,10 @@ class Bed extends Transparent{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); //extra block properties storage hack - $tile = Tile::create(Tile::BED, $this->getLevel(), $this->asVector3()); - if($tile !== null){ - if($tile instanceof TileBed){ - $tile->setColor($this->color); - } - $this->level->addTile($tile); - } + /** @var TileBed $tile */ + $tile = Tile::create(TileBed::class, $this->getLevel(), $this->asVector3()); + $tile->setColor($this->color); + $this->level->addTile($tile); } public function getHardness() : float{ diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index b577ff66ba..f64fe4bb10 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -72,7 +72,8 @@ class Chest extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $chest = null; + /** @var TileChest|null $pair */ + $pair = null; if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } @@ -85,21 +86,20 @@ class Chest extends Transparent{ if($c instanceof Chest and $c->isSameType($this) and $c->facing === $this->facing){ $tile = $this->getLevel()->getTile($c); if($tile instanceof TileChest and !$tile->isPaired()){ - $chest = $tile; + $pair = $tile; break; } } } if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - $tile = Tile::createFromItem(Tile::CHEST, $this->getLevel(), $this->asVector3(), $item); - if($tile !== null){ - $this->level->addTile($tile); - } + /** @var TileChest $tile */ + $tile = Tile::createFromItem(TileChest::class, $this->getLevel(), $this->asVector3(), $item); + $this->level->addTile($tile); - if($chest instanceof TileChest and $tile instanceof TileChest){ - $chest->pairWith($tile); - $tile->pairWith($chest); + if($pair instanceof TileChest){ + $pair->pairWith($tile); + $tile->pairWith($pair); } return true; diff --git a/src/pocketmine/block/EnchantingTable.php b/src/pocketmine/block/EnchantingTable.php index 02c3059b18..86a88a8c31 100644 --- a/src/pocketmine/block/EnchantingTable.php +++ b/src/pocketmine/block/EnchantingTable.php @@ -30,6 +30,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\tile\EnchantTable as TileEnchantingTable; use pocketmine\tile\Tile; class EnchantingTable extends Transparent{ @@ -42,9 +43,7 @@ class EnchantingTable extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - if(($tile = Tile::createFromItem(Tile::ENCHANT_TABLE, $this->getLevel(), $this->asVector3(), $item)) !== null){ - $this->level->addTile($tile); - } + $this->level->addTile(Tile::createFromItem(TileEnchantingTable::class, $this->getLevel(), $this->asVector3(), $item)); return true; } diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index c810263a65..e8026a5aff 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -66,9 +66,7 @@ class EnderChest extends Chest{ } if(Block::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - if(($tile = Tile::createFromItem(Tile::ENDER_CHEST, $this->getLevel(), $this->asVector3(), $item)) !== null){ - $this->level->addTile($tile); - } + $this->level->addTile(Tile::createFromItem(TileEnderChest::class, $this->getLevel(), $this->asVector3(), $item)); return true; } diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 1c0350dd01..f9ac6eb609 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -69,9 +69,7 @@ class FlowerPot extends Flowable{ } if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - if(($tile = Tile::createFromItem(Tile::FLOWER_POT, $this->getLevel(), $this->asVector3(), $item)) !== null){ - $this->level->addTile($tile); - } + $this->level->addTile(Tile::createFromItem(TileFlowerPot::class, $this->getLevel(), $this->asVector3(), $item)); return true; } diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index b4a91ccf58..96293cd209 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -99,9 +99,7 @@ class Furnace extends Solid{ $this->facing = Facing::opposite($player->getHorizontalFacing()); } if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - if(($tile = Tile::createFromItem(Tile::FURNACE, $this->getLevel(), $this->asVector3(), $item)) !== null){ - $this->level->addTile($tile); - } + $this->level->addTile(Tile::createFromItem(TileFurnace::class, $this->getLevel(), $this->asVector3(), $item)); return true; } diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index adbc93d079..7c6a92abcf 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -85,9 +85,7 @@ class ItemFrame extends Flowable{ $this->facing = $face; if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - if(($tile = Tile::createFromItem(Tile::ITEM_FRAME, $this->getLevel(), $this->asVector3(), $item)) !== null){ - $this->level->addTile($tile); - } + $this->level->addTile(Tile::createFromItem(TileItemFrame::class, $this->getLevel(), $this->asVector3(), $item)); return true; } diff --git a/src/pocketmine/block/SignPost.php b/src/pocketmine/block/SignPost.php index 8f6e027d2e..9a420519ae 100644 --- a/src/pocketmine/block/SignPost.php +++ b/src/pocketmine/block/SignPost.php @@ -28,6 +28,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\tile\Sign as TileSign; use pocketmine\tile\Tile; class SignPost extends Transparent{ @@ -82,9 +83,7 @@ class SignPost extends Transparent{ } if($ret){ - if(($tile = Tile::createFromItem(Tile::SIGN, $this->getLevel(), $this->asVector3(), $item)) !== null){ - $this->level->addTile($tile); - } + $this->level->addTile(Tile::createFromItem(TileSign::class, $this->getLevel(), $this->asVector3(), $item)); return true; } } diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index 7e54d629f5..d1fd2955bb 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -70,14 +70,11 @@ class Skull extends Flowable{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = Tile::create(Tile::SKULL, $this->getLevel(), $this->asVector3()); - if($tile !== null){ - if($tile instanceof TileSkull){ - $tile->setRotation($this->rotation); - $tile->setType($this->type); - } - $this->level->addTile($tile); - } + /** @var TileSkull $tile */ + $tile = Tile::create(TileSkull::class, $this->getLevel(), $this->asVector3()); + $tile->setRotation($this->rotation); + $tile->setType($this->type); + $this->level->addTile($tile); } public function getHardness() : float{ diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index 55745c29d1..3954b35f96 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -84,17 +84,16 @@ class StandingBanner extends Transparent{ } if($ret){ - $tile = Tile::createFromItem(Tile::BANNER, $this->getLevel(), $this->asVector3(), $item); - if($tile !== null){ - if($tile instanceof TileBanner and $item instanceof ItemBanner){ - $tile->setBaseColor($item->getBaseColor()); - if(($patterns = $item->getPatterns()) !== null){ - $tile->setPatterns($patterns); - } + /** @var TileBanner $tile */ + $tile = Tile::createFromItem(TileBanner::class, $this->getLevel(), $this->asVector3(), $item); + if($item instanceof ItemBanner){ + $tile->setBaseColor($item->getBaseColor()); + if(($patterns = $item->getPatterns()) !== null){ + $tile->setPatterns($patterns); } - - $this->level->addTile($tile); } + + $this->level->addTile($tile); return true; } } diff --git a/src/pocketmine/tile/Sign.php b/src/pocketmine/tile/Sign.php index 8d63d7a654..aea189a4f9 100644 --- a/src/pocketmine/tile/Sign.php +++ b/src/pocketmine/tile/Sign.php @@ -125,10 +125,6 @@ class Sign extends Spawnable{ } public function updateCompoundTag(CompoundTag $nbt, Player $player) : bool{ - if($nbt->getString("id") !== Tile::SIGN){ - return false; - } - if($nbt->hasTag(self::TAG_TEXT_BLOB, StringTag::class)){ $lines = array_pad(explode("\n", $nbt->getString(self::TAG_TEXT_BLOB)), 4, ""); }else{ diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/tile/Tile.php index f6808cc1fa..8708ce6ba4 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/tile/Tile.php @@ -44,24 +44,14 @@ abstract class Tile extends Position{ public const TAG_Y = "y"; public const TAG_Z = "z"; - public const BANNER = "Banner"; - public const BED = "Bed"; - public const BREWING_STAND = "BrewingStand"; - public const CHEST = "Chest"; - public const ENCHANT_TABLE = "EnchantTable"; - public const ENDER_CHEST = "EnderChest"; - public const FLOWER_POT = "FlowerPot"; - public const FURNACE = "Furnace"; - public const ITEM_FRAME = "ItemFrame"; - public const MOB_SPAWNER = "MobSpawner"; - public const SIGN = "Sign"; - public const SKULL = "Skull"; - /** @var string[] classes that extend Tile */ private static $knownTiles = []; /** @var string[][] */ private static $saveNames = []; + /** @var string[] base class => overridden class */ + private static $classMapping = []; + /** @var string */ public $name = ""; /** @var bool */ @@ -70,16 +60,16 @@ abstract class Tile extends Position{ protected $timings; public static function init(){ - self::registerTile(Banner::class, [self::BANNER, "minecraft:banner"]); - self::registerTile(Bed::class, [self::BED, "minecraft:bed"]); - self::registerTile(Chest::class, [self::CHEST, "minecraft:chest"]); - self::registerTile(EnchantTable::class, [self::ENCHANT_TABLE, "minecraft:enchanting_table"]); - self::registerTile(EnderChest::class, [self::ENDER_CHEST, "minecraft:ender_chest"]); - self::registerTile(FlowerPot::class, [self::FLOWER_POT, "minecraft:flower_pot"]); - self::registerTile(Furnace::class, [self::FURNACE, "minecraft:furnace"]); - self::registerTile(ItemFrame::class, [self::ITEM_FRAME]); //this is an entity in PC - self::registerTile(Sign::class, [self::SIGN, "minecraft:sign"]); - self::registerTile(Skull::class, [self::SKULL, "minecraft:skull"]); + self::register(Banner::class, ["Banner", "minecraft:banner"]); + self::register(Bed::class, ["Bed", "minecraft:bed"]); + self::register(Chest::class, ["Chest", "minecraft:chest"]); + self::register(EnchantTable::class, ["EnchantTable", "minecraft:enchanting_table"]); + self::register(EnderChest::class, ["EnderChest", "minecraft:ender_chest"]); + self::register(FlowerPot::class, ["FlowerPot", "minecraft:flower_pot"]); + self::register(Furnace::class, ["Furnace", "minecraft:furnace"]); + self::register(ItemFrame::class, ["ItemFrame"]); //this is an entity in PC + self::register(Sign::class, ["Sign", "minecraft:sign"]); + self::register(Skull::class, ["Skull", "minecraft:skull"]); } /** @@ -90,27 +80,32 @@ abstract class Tile extends Position{ */ public static function createFromData(Level $level, CompoundTag $nbt) : ?Tile{ $type = $nbt->getString(self::TAG_ID, "", true); - if($type === ""){ + if(!isset(self::$knownTiles[$type])){ return null; } - $tile = self::create($type, $level, new Vector3($nbt->getInt(self::TAG_X), $nbt->getInt(self::TAG_Y), $nbt->getInt(self::TAG_Z))); - if($tile !== null){ - $tile->readSaveData($nbt); - } + $class = self::$knownTiles[$type]; + assert(is_a($class, Tile::class, true)); + /** + * @var Tile $tile + * @see Tile::__construct() + */ + $tile = new $class($level, new Vector3($nbt->getInt(self::TAG_X), $nbt->getInt(self::TAG_Y), $nbt->getInt(self::TAG_Z))); + $tile->readSaveData($nbt); return $tile; } /** - * @param string $type + * @param string $baseClass * @param Level $level * @param Vector3 $pos * @param Item $item * - * @return Tile|null + * @return Tile (instanceof $baseClass) + * @throws \InvalidArgumentException if the base class is not a registered tile */ - public static function createFromItem(string $type, Level $level, Vector3 $pos, Item $item) : ?Tile{ - $tile = self::create($type, $level, $pos); - if($tile !== null and $item->hasCustomBlockData()){ + public static function createFromItem(string $baseClass, Level $level, Vector3 $pos, Item $item) : Tile{ + $tile = self::create($baseClass, $level, $pos); + if($item->hasCustomBlockData()){ $tile->readSaveData($item->getCustomBlockData()); } if($tile instanceof Nameable and $item->hasCustomName()){ //this should take precedence over saved NBT @@ -120,34 +115,15 @@ abstract class Tile extends Position{ return $tile; } - /** - * @param string $type - * @param Level $level - * @param Vector3 $pos - * - * @return Tile|null - */ - public static function create(string $type, Level $level, Vector3 $pos) : ?Tile{ - if(isset(self::$knownTiles[$type])){ - $class = self::$knownTiles[$type]; - /** - * @var Tile $tile - * @see Tile::__construct() - */ - $tile = new $class($level, $pos); - return $tile; - } - - return null; - } - /** * @param string $className * @param string[] $saveNames */ - public static function registerTile(string $className, array $saveNames = []) : void{ + public static function register(string $className, array $saveNames = []) : void{ Utils::testValidInstance($className, Tile::class); + self::$classMapping[$className] = $className; + $shortName = (new \ReflectionClass($className))->getShortName(); if(!in_array($shortName, $saveNames, true)){ $saveNames[] = $shortName; @@ -160,6 +136,44 @@ abstract class Tile extends Position{ self::$saveNames[$className] = $saveNames; } + /** + * @param string $baseClass Already-registered tile class to override + * @param string $newClass Class which extends the base class + * + * @throws \InvalidArgumentException if the base class is not a registered tile + */ + public static function override(string $baseClass, string $newClass) : void{ + if(!isset(self::$classMapping[$baseClass])){ + throw new \InvalidArgumentException("Class $baseClass is not a registered tile"); + } + + Utils::testValidInstance($newClass, $baseClass); + self::$classMapping[$baseClass] = $newClass; + } + + /** + * @param string $baseClass + * @param Level $level + * @param Vector3 $pos + * + * @return Tile (will be an instanceof $baseClass) + * @throws \InvalidArgumentException if the specified class is not a registered tile + */ + public static function create(string $baseClass, Level $level, Vector3 $pos) : Tile{ + if(isset(self::$classMapping[$baseClass])){ + $class = self::$classMapping[$baseClass]; + assert(is_a($class, $baseClass, true)); + /** + * @var Tile $tile + * @see Tile::__construct() + */ + $tile = new $class($level, $pos); + return $tile; + } + + throw new \InvalidArgumentException("Class $baseClass is not a registered tile"); + } + /** * Returns the short save name * @return string From 2c6381632cb0f6dbe7608711fe8267756aa1bef3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 26 Dec 2018 20:01:14 +0000 Subject: [PATCH 0336/3224] Allow Tiles to decide how to copy data from an item --- src/pocketmine/block/StandingBanner.php | 11 +---------- src/pocketmine/tile/Banner.php | 14 ++++++++++++++ src/pocketmine/tile/NameableTrait.php | 12 ++++++++++++ src/pocketmine/tile/Tile.php | 13 +++++++------ 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index 3954b35f96..c640b451a3 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -84,16 +84,7 @@ class StandingBanner extends Transparent{ } if($ret){ - /** @var TileBanner $tile */ - $tile = Tile::createFromItem(TileBanner::class, $this->getLevel(), $this->asVector3(), $item); - if($item instanceof ItemBanner){ - $tile->setBaseColor($item->getBaseColor()); - if(($patterns = $item->getPatterns()) !== null){ - $tile->setPatterns($patterns); - } - } - - $this->level->addTile($tile); + $this->level->addTile(Tile::createFromItem(TileBanner::class, $this->getLevel(), $this->asVector3(), $item)); return true; } } diff --git a/src/pocketmine/tile/Banner.php b/src/pocketmine/tile/Banner.php index c1ed28e693..68140c4e2a 100644 --- a/src/pocketmine/tile/Banner.php +++ b/src/pocketmine/tile/Banner.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\tile; +use pocketmine\item\Banner as ItemBanner; +use pocketmine\item\Item; use pocketmine\level\Level; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; @@ -33,6 +35,7 @@ use pocketmine\nbt\tag\StringTag; class Banner extends Spawnable implements Nameable{ use NameableTrait { addAdditionalSpawnData as addNameSpawnData; + copyDataFromItem as copyNameFromItem; } public const TAG_BASE = "Base"; @@ -127,6 +130,17 @@ class Banner extends Spawnable implements Nameable{ $this->addNameSpawnData($nbt); } + protected function copyDataFromItem(Item $item) : void{ + parent::copyDataFromItem($item); + $this->copyNameFromItem($item); + if($item instanceof ItemBanner){ + $this->setBaseColor($item->getBaseColor()); + if(($patterns = $item->getPatterns()) !== null){ + $this->setPatterns($patterns); + } + } + } + /** * Returns the color of the banner base. * diff --git a/src/pocketmine/tile/NameableTrait.php b/src/pocketmine/tile/NameableTrait.php index 90dd3d778f..4b159df422 100644 --- a/src/pocketmine/tile/NameableTrait.php +++ b/src/pocketmine/tile/NameableTrait.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\tile; +use pocketmine\item\Item; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\StringTag; @@ -80,4 +81,15 @@ trait NameableTrait{ $tag->setString(Nameable::TAG_CUSTOM_NAME, $this->customName); } } + + /** + * @param Item $item + * @see Tile::copyDataFromItem() + */ + protected function copyDataFromItem(Item $item) : void{ + parent::copyDataFromItem($item); + if($item->hasCustomName()){ //this should take precedence over saved NBT + $this->setName($item->getCustomName()); + } + } } diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/tile/Tile.php index 8708ce6ba4..3f1d8b6a05 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/tile/Tile.php @@ -105,12 +105,7 @@ abstract class Tile extends Position{ */ public static function createFromItem(string $baseClass, Level $level, Vector3 $pos, Item $item) : Tile{ $tile = self::create($baseClass, $level, $pos); - if($item->hasCustomBlockData()){ - $tile->readSaveData($item->getCustomBlockData()); - } - if($tile instanceof Nameable and $item->hasCustomName()){ //this should take precedence over saved NBT - $tile->setName($item->getCustomName()); - } + $tile->copyDataFromItem($item); return $tile; } @@ -222,6 +217,12 @@ abstract class Tile extends Position{ return $tag->getCount() > 0 ? $tag : null; } + protected function copyDataFromItem(Item $item) : void{ + if($item->hasCustomBlockData()){ //TODO: check item root tag (MCPE doesn't use BlockEntityTag) + $this->readSaveData($item->getCustomBlockData()); + } + } + /** * @return Block */ From a6cd9ae029acf15ac760bd6bca8653ceebba395d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 26 Dec 2018 22:18:47 +0000 Subject: [PATCH 0337/3224] Implemented #2556: don't send tile NBT updates until the end of tick this eliminates spam when tile spawn NBT changes a lot during a tick, for example the lines of a sign being updated. closes #2556 --- src/pocketmine/level/Level.php | 10 +++++---- src/pocketmine/tile/Sign.php | 7 ++----- src/pocketmine/tile/Spawnable.php | 34 ++++++++++++++++++++----------- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 97738ca77f..b627f88eff 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -798,6 +798,12 @@ class Level implements ChunkManager, Metadatable{ if(!$tile->onUpdate()){ unset($this->updateTiles[$blockHash]); } + if(!$tile->isClosed() and $tile instanceof Spawnable and $tile->isDirty()){ + $this->clearChunkCache($tile->getFloorX() >> 4, $tile->getFloorZ() >> 4); + //TODO: merge this with block-updating (it'll send useless data if a full-chunk resend happens) + $this->broadcastPacketToViewers($tile, $tile->createSpawnPacket()); + $tile->setDirty(false); + } } Timings::$tickTileEntityTimer->stopTiming(); $this->timings->tileEntityTick->stopTiming(); @@ -2587,10 +2593,6 @@ class Level implements ChunkManager, Metadatable{ $this->tiles[Level::blockHash($tile->x, $tile->y, $tile->z)] = $tile; $tile->scheduleUpdate(); - if($tile instanceof Spawnable){ - $this->clearChunkCache($chunkX, $chunkZ); - $tile->spawnToAll(); - } } /** diff --git a/src/pocketmine/tile/Sign.php b/src/pocketmine/tile/Sign.php index aea189a4f9..c566fe6511 100644 --- a/src/pocketmine/tile/Sign.php +++ b/src/pocketmine/tile/Sign.php @@ -88,17 +88,14 @@ class Sign extends Spawnable{ /** * @param int $index 0-3 * @param string $line - * @param bool $update */ - public function setLine(int $index, string $line, bool $update = true) : void{ + public function setLine(int $index, string $line) : void{ if($index < 0 or $index > 3){ throw new \InvalidArgumentException("Index must be in the range 0-3!"); } $this->text[$index] = $line; - if($update){ - $this->onChanged(); - } + $this->onChanged(); } /** diff --git a/src/pocketmine/tile/Spawnable.php b/src/pocketmine/tile/Spawnable.php index 3b7f95e576..fe9818d396 100644 --- a/src/pocketmine/tile/Spawnable.php +++ b/src/pocketmine/tile/Spawnable.php @@ -33,6 +33,9 @@ use pocketmine\Player; abstract class Spawnable extends Tile{ /** @var string|null */ private $spawnCompoundCache = null; + /** @var bool */ + private $dirty = true; //default dirty, until it's been spawned appropriately on the level + /** @var NetworkLittleEndianNBTStream|null */ private static $nbtWriter = null; @@ -56,23 +59,30 @@ abstract class Spawnable extends Tile{ return true; } - public function spawnToAll(){ - if($this->closed){ - return; - } - - $this->level->broadcastPacketToViewers($this, $this->createSpawnPacket()); - } - /** - * Performs actions needed when the tile is modified, such as clearing caches and respawning the tile to players. - * WARNING: This MUST be called to clear spawn-compound and chunk caches when the tile's spawn compound has changed! + * Flags the tile as modified, so that updates will be broadcasted at the next available opportunity. + * This MUST be called any time a change is made that players must be able to see. */ protected function onChanged() : void{ $this->spawnCompoundCache = null; - $this->spawnToAll(); + $this->dirty = true; + $this->scheduleUpdate(); + } - $this->level->clearChunkCache($this->getFloorX() >> 4, $this->getFloorZ() >> 4); + /** + * Returns whether the tile needs to be respawned to viewers. + * + * @return bool + */ + public function isDirty() : bool{ + return $this->dirty; + } + + /** + * @param bool $dirty + */ + public function setDirty(bool $dirty = true) : void{ + $this->dirty = $dirty; } /** From 8564efc011d3ed8fddb9445a6813ede57e1269dd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Dec 2018 15:02:14 +0000 Subject: [PATCH 0338/3224] Sync item and block legacy IDs --- src/pocketmine/block/BlockIds.php | 62 ++++++++++++++++++++++++++---- src/pocketmine/item/ItemIds.php | 64 +++++++++++++++++++++++++++---- 2 files changed, 112 insertions(+), 14 deletions(-) diff --git a/src/pocketmine/block/BlockIds.php b/src/pocketmine/block/BlockIds.php index 7edaca892a..3cebed295a 100644 --- a/src/pocketmine/block/BlockIds.php +++ b/src/pocketmine/block/BlockIds.php @@ -61,7 +61,7 @@ interface BlockIds{ public const PISTON = 33; public const PISTONARMCOLLISION = 34, PISTON_ARM_COLLISION = 34; public const WOOL = 35; - + public const ELEMENT_0 = 36; public const DANDELION = 37, YELLOW_FLOWER = 37; public const POPPY = 38, RED_FLOWER = 38; public const BROWN_MUSHROOM = 39; @@ -191,7 +191,7 @@ interface BlockIds{ public const ACACIA_STAIRS = 163; public const DARK_OAK_STAIRS = 164; public const SLIME = 165, SLIME_BLOCK = 165; - + public const GLOW_STICK = 166; public const IRON_TRAPDOOR = 167; public const PRISMARINE = 168; public const SEALANTERN = 169, SEA_LANTERN = 169; @@ -215,7 +215,9 @@ interface BlockIds{ public const ACACIA_FENCE_GATE = 187; public const REPEATING_COMMAND_BLOCK = 188; public const CHAIN_COMMAND_BLOCK = 189; - + public const HARD_GLASS_PANE = 190; + public const HARD_STAINED_GLASS_PANE = 191; + public const CHEMICAL_HEAT = 192; public const SPRUCE_DOOR_BLOCK = 193; public const BIRCH_DOOR_BLOCK = 194; public const JUNGLE_DOOR_BLOCK = 195; @@ -225,9 +227,9 @@ interface BlockIds{ public const FRAME_BLOCK = 199, ITEM_FRAME_BLOCK = 199; public const CHORUS_FLOWER = 200; public const PURPUR_BLOCK = 201; - + public const COLORED_TORCH_RG = 202; public const PURPUR_STAIRS = 203; - + public const COLORED_TORCH_BP = 204; public const UNDYED_SHULKER_BOX = 205; public const END_BRICKS = 206; public const FROSTED_ICE = 207; @@ -259,7 +261,8 @@ interface BlockIds{ public const BLACK_GLAZED_TERRACOTTA = 235; public const CONCRETE = 236; public const CONCRETEPOWDER = 237, CONCRETE_POWDER = 237; - + public const CHEMISTRY_TABLE = 238; + public const UNDERWATER_TORCH = 239; public const CHORUS_PLANT = 240; public const STAINED_GLASS = 241; @@ -273,7 +276,52 @@ interface BlockIds{ public const MOVINGBLOCK = 250, MOVING_BLOCK = 250; public const OBSERVER = 251; public const STRUCTURE_BLOCK = 252; - + public const HARD_GLASS = 253; + public const HARD_STAINED_GLASS = 254; public const RESERVED6 = 255; + public const PRISMARINE_STAIRS = 257; + public const DARK_PRISMARINE_STAIRS = 258; + public const PRISMARINE_BRICKS_STAIRS = 259; + public const STRIPPED_SPRUCE_LOG = 260; + public const STRIPPED_BIRCH_LOG = 261; + public const STRIPPED_JUNGLE_LOG = 262; + public const STRIPPED_ACACIA_LOG = 263; + public const STRIPPED_DARK_OAK_LOG = 264; + public const STRIPPED_OAK_LOG = 265; + public const BLUE_ICE = 266; + + public const SEAGRASS = 385; + public const CORAL = 386; + public const CORAL_BLOCK = 387; + public const CORAL_FAN = 388; + public const CORAL_FAN_DEAD = 389; + public const CORAL_FAN_HANG = 390; + public const CORAL_FAN_HANG2 = 391; + public const CORAL_FAN_HANG3 = 392; + public const KELP = 393; + public const DRIED_KELP_BLOCK = 394; + public const ACACIA_BUTTON = 395; + public const BIRCH_BUTTON = 396; + public const DARK_OAK_BUTTON = 397; + public const JUNGLE_BUTTON = 398; + public const SPRUCE_BUTTON = 399; + public const ACACIA_TRAPDOOR = 400; + public const BIRCH_TRAPDOOR = 401; + public const DARK_OAK_TRAPDOOR = 402; + public const JUNGLE_TRAPDOOR = 403; + public const SPRUCE_TRAPDOOR = 404; + public const ACACIA_PRESSURE_PLATE = 405; + public const BIRCH_PRESSURE_PLATE = 406; + public const DARK_OAK_PRESSURE_PLATE = 407; + public const JUNGLE_PRESSURE_PLATE = 408; + public const SPRUCE_PRESSURE_PLATE = 409; + public const CARVED_PUMPKIN = 410; + public const SEA_PICKLE = 411; + public const CONDUIT = 412; + + public const TURTLE_EGG = 414; + public const BUBBLE_COLUMN = 415; + public const BARRIER = 416; + } diff --git a/src/pocketmine/item/ItemIds.php b/src/pocketmine/item/ItemIds.php index 4e250d1927..7f33791411 100644 --- a/src/pocketmine/item/ItemIds.php +++ b/src/pocketmine/item/ItemIds.php @@ -25,6 +25,50 @@ namespace pocketmine\item; interface ItemIds{ + public const BARRIER = -161; + public const BUBBLE_COLUMN = -160; + public const TURTLE_EGG = -159; + + public const CONDUIT = -157; + public const SEA_PICKLE = -156; + public const CARVED_PUMPKIN = -155; + public const SPRUCE_PRESSURE_PLATE = -154; + public const JUNGLE_PRESSURE_PLATE = -153; + public const DARK_OAK_PRESSURE_PLATE = -152; + public const BIRCH_PRESSURE_PLATE = -151; + public const ACACIA_PRESSURE_PLATE = -150; + public const SPRUCE_TRAPDOOR = -149; + public const JUNGLE_TRAPDOOR = -148; + public const DARK_OAK_TRAPDOOR = -147; + public const BIRCH_TRAPDOOR = -146; + public const ACACIA_TRAPDOOR = -145; + public const SPRUCE_BUTTON = -144; + public const JUNGLE_BUTTON = -143; + public const DARK_OAK_BUTTON = -142; + public const BIRCH_BUTTON = -141; + public const ACACIA_BUTTON = -140; + public const DRIED_KELP_BLOCK = -139; + public const KELP_BLOCK = -138; + public const CORAL_FAN_HANG3 = -137; + public const CORAL_FAN_HANG2 = -136; + public const CORAL_FAN_HANG = -135; + public const CORAL_FAN_DEAD = -134; + public const CORAL_FAN = -133; + public const CORAL_BLOCK = -132; + public const CORAL = -131; + public const SEAGRASS = -130; + + public const BLUE_ICE = -11; + public const STRIPPED_OAK_LOG = -10; + public const STRIPPED_DARK_OAK_LOG = -9; + public const STRIPPED_ACACIA_LOG = -8; + public const STRIPPED_JUNGLE_LOG = -7; + public const STRIPPED_BIRCH_LOG = -6; + public const STRIPPED_SPRUCE_LOG = -5; + public const PRISMARINE_BRICKS_STAIRS = -4; + public const DARK_PRISMARINE_STAIRS = -3; + public const PRISMARINE_STAIRS = -2; + public const AIR = 0; public const STONE = 1; public const GRASS = 2; @@ -61,7 +105,7 @@ interface ItemIds{ public const PISTON = 33; public const PISTONARMCOLLISION = 34, PISTON_ARM_COLLISION = 34; public const WOOL = 35; - + public const ELEMENT_0 = 36; public const DANDELION = 37, YELLOW_FLOWER = 37; public const POPPY = 38, RED_FLOWER = 38; public const BROWN_MUSHROOM = 39; @@ -191,7 +235,7 @@ interface ItemIds{ public const ACACIA_STAIRS = 163; public const DARK_OAK_STAIRS = 164; public const SLIME = 165, SLIME_BLOCK = 165; - + public const GLOW_STICK = 166; public const IRON_TRAPDOOR = 167; public const PRISMARINE = 168; public const SEALANTERN = 169, SEA_LANTERN = 169; @@ -215,7 +259,9 @@ interface ItemIds{ public const ACACIA_FENCE_GATE = 187; public const REPEATING_COMMAND_BLOCK = 188; public const CHAIN_COMMAND_BLOCK = 189; - + public const HARD_GLASS_PANE = 190; + public const HARD_STAINED_GLASS_PANE = 191; + public const CHEMICAL_HEAT = 192; public const SPRUCE_DOOR_BLOCK = 193; public const BIRCH_DOOR_BLOCK = 194; public const JUNGLE_DOOR_BLOCK = 195; @@ -225,9 +271,9 @@ interface ItemIds{ public const FRAME_BLOCK = 199, ITEM_FRAME_BLOCK = 199; public const CHORUS_FLOWER = 200; public const PURPUR_BLOCK = 201; - + public const COLORED_TORCH_RG = 202; public const PURPUR_STAIRS = 203; - + public const COLORED_TORCH_BP = 204; public const UNDYED_SHULKER_BOX = 205; public const END_BRICKS = 206; public const FROSTED_ICE = 207; @@ -259,7 +305,8 @@ interface ItemIds{ public const BLACK_GLAZED_TERRACOTTA = 235; public const CONCRETE = 236; public const CONCRETEPOWDER = 237, CONCRETE_POWDER = 237; - + public const CHEMISTRY_TABLE = 238; + public const UNDERWATER_TORCH = 239; public const CHORUS_PLANT = 240; public const STAINED_GLASS = 241; @@ -273,7 +320,8 @@ interface ItemIds{ public const MOVINGBLOCK = 250, MOVING_BLOCK = 250; public const OBSERVER = 251; public const STRUCTURE_BLOCK = 252; - + public const HARD_GLASS = 253; + public const HARD_STAINED_GLASS = 254; public const RESERVED6 = 255; public const IRON_SHOVEL = 256; public const IRON_PICKAXE = 257; @@ -485,6 +533,8 @@ interface ItemIds{ public const HEART_OF_THE_SEA = 467; public const TURTLE_SHELL_PIECE = 468; public const TURTLE_HELMET = 469; + public const PHANTOM_MEMBRANE = 470; + public const CROSSBOW = 471; public const COMPOUND = 499; public const RECORD_13 = 500; From ab75e89d95993e172eeb6d5e31d457228975f164 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Dec 2018 17:36:41 -0500 Subject: [PATCH 0339/3224] Fixed generation changes in recent builds compared to 3.x this was caused by improper RNG sanitization and a recent cleanup refactor. --- src/pocketmine/level/generator/noise/Simplex.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pocketmine/level/generator/noise/Simplex.php b/src/pocketmine/level/generator/noise/Simplex.php index 846d45566a..27494d51c4 100644 --- a/src/pocketmine/level/generator/noise/Simplex.php +++ b/src/pocketmine/level/generator/noise/Simplex.php @@ -77,6 +77,11 @@ class Simplex extends Noise{ $this->perm[$pos] = $old; $this->perm[$i + 256] = $this->perm[$i]; } + + //this dummy call is necessary to produce the same RNG state as before latest refactors to this file + //previously this value would be used for offsetW + //TODO: this really needs to reset the RNG seed to avoid future RNG contamination + $random->nextSignedInt(); } public function getNoise3D($x, $y, $z){ From f64cef7eb689823244832ff071bb10b73f6fd101 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 28 Dec 2018 11:55:52 +0000 Subject: [PATCH 0340/3224] ItemFactory: Get rid of $multiple crap this is required in a specialized format, which doesn't make any sense. Plugins with multiple packed item formats should parse them themselves. --- src/pocketmine/item/Item.php | 10 +++--- src/pocketmine/item/ItemFactory.php | 51 +++++++++++------------------ 2 files changed, 24 insertions(+), 37 deletions(-) diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index e3e30d5378..82c04b35df 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -93,17 +93,17 @@ class Item implements ItemIds, \JsonSerializable{ } /** - * Tries to parse the specified string into Item ID/meta identifiers, and returns Item instances it created. + * Tries to parse the specified string into Item types. * * This function redirects to {@link ItemFactory#fromString}. * * @param string $str - * @param bool $multiple * - * @return Item[]|Item + * @return Item + * @throws \InvalidArgumentException */ - public static function fromString(string $str, bool $multiple = false){ - return ItemFactory::fromString($str, $multiple); + public static function fromString(string $str) : Item{ + return ItemFactory::fromString($str); } diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 2c26229516..575d6b789d 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -360,51 +360,38 @@ class ItemFactory{ } /** - * Tries to parse the specified string into Item ID/meta identifiers, and returns Item instances it created. + * Tries to parse the specified string into Item types. * * Example accepted formats: * - `diamond_pickaxe:5` * - `minecraft:string` * - `351:4 (lapis lazuli ID:meta)` * - * If multiple item instances are to be created, their identifiers must be comma-separated, for example: - * `diamond_pickaxe,wooden_shovel:18,iron_ingot` - * * @param string $str - * @param bool $multiple * - * @return Item[]|Item + * @return Item * * @throws \InvalidArgumentException if the given string cannot be parsed as an item identifier */ - public static function fromString(string $str, bool $multiple = false){ - if($multiple){ - $blocks = []; - foreach(explode(",", $str) as $b){ - $blocks[] = self::fromString($b, false); - } - - return $blocks; + public static function fromString(string $str) : Item{ + $b = explode(":", str_replace([" ", "minecraft:"], ["_", ""], trim($str))); + if(!isset($b[1])){ + $meta = 0; + }elseif(is_numeric($b[1])){ + $meta = (int) $b[1]; }else{ - $b = explode(":", str_replace([" ", "minecraft:"], ["_", ""], trim($str))); - if(!isset($b[1])){ - $meta = 0; - }elseif(is_numeric($b[1])){ - $meta = (int) $b[1]; - }else{ - throw new \InvalidArgumentException("Unable to parse \"" . $b[1] . "\" from \"" . $str . "\" as a valid meta value"); - } - - if(is_numeric($b[0])){ - $item = self::get((int) $b[0], $meta); - }elseif(defined(ItemIds::class . "::" . strtoupper($b[0]))){ - $item = self::get(constant(ItemIds::class . "::" . strtoupper($b[0])), $meta); - }else{ - throw new \InvalidArgumentException("Unable to resolve \"" . $str . "\" to a valid item"); - } - - return $item; + throw new \InvalidArgumentException("Unable to parse \"" . $b[1] . "\" from \"" . $str . "\" as a valid meta value"); } + + if(is_numeric($b[0])){ + $item = self::get((int) $b[0], $meta); + }elseif(defined(ItemIds::class . "::" . strtoupper($b[0]))){ + $item = self::get(constant(ItemIds::class . "::" . strtoupper($b[0])), $meta); + }else{ + throw new \InvalidArgumentException("Unable to resolve \"" . $str . "\" to a valid item"); + } + + return $item; } /** From e9d43aa44fa3c39abbb5a32a138db1d7fab509b8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 28 Dec 2018 12:55:49 +0000 Subject: [PATCH 0341/3224] Fixed MainLogger not being assigned as global on async workers --- src/pocketmine/scheduler/AsyncWorker.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pocketmine/scheduler/AsyncWorker.php b/src/pocketmine/scheduler/AsyncWorker.php index 64c853196e..06476feef2 100644 --- a/src/pocketmine/scheduler/AsyncWorker.php +++ b/src/pocketmine/scheduler/AsyncWorker.php @@ -51,6 +51,7 @@ class AsyncWorker extends Worker{ //set this after the autoloader is registered set_error_handler([Utils::class, 'errorExceptionHandler']); + \GlobalLogger::set($this->logger); if($this->logger instanceof MainLogger){ $this->logger->registerStatic(); } From 78a80a69588cf4a08d71c374a49e19038b59aa4a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 28 Dec 2018 14:33:09 +0000 Subject: [PATCH 0342/3224] Tighten validity checks for block metadata This filters out over 200 invalid states which were previously considered just fine, including zero-width cakes, buttons with broken facing values, furnace/chest with crazy values, and more. --- src/pocketmine/block/Anvil.php | 3 +- src/pocketmine/block/BaseRail.php | 11 ++- src/pocketmine/block/Bed.php | 3 +- src/pocketmine/block/Block.php | 5 ++ src/pocketmine/block/BlockFactory.php | 13 ++- src/pocketmine/block/Button.php | 3 +- src/pocketmine/block/Cactus.php | 3 +- src/pocketmine/block/Cake.php | 3 +- src/pocketmine/block/Chest.php | 3 +- src/pocketmine/block/CocoaBlock.php | 5 +- src/pocketmine/block/Crops.php | 3 +- src/pocketmine/block/DaylightSensor.php | 3 +- src/pocketmine/block/Door.php | 5 +- src/pocketmine/block/EndPortalFrame.php | 3 +- src/pocketmine/block/EndRod.php | 9 +- src/pocketmine/block/Farmland.php | 3 +- src/pocketmine/block/FenceGate.php | 3 +- src/pocketmine/block/Fire.php | 3 +- src/pocketmine/block/Furnace.php | 3 +- src/pocketmine/block/GlazedTerracotta.php | 3 +- src/pocketmine/block/ItemFrame.php | 3 +- src/pocketmine/block/Ladder.php | 3 +- src/pocketmine/block/Lever.php | 3 +- src/pocketmine/block/Liquid.php | 3 +- src/pocketmine/block/NetherReactor.php | 3 +- src/pocketmine/block/NetherWartPlant.php | 3 +- src/pocketmine/block/Rail.php | 5 +- src/pocketmine/block/RedstoneRail.php | 4 +- src/pocketmine/block/RedstoneRepeater.php | 5 +- src/pocketmine/block/RedstoneWire.php | 3 +- src/pocketmine/block/Skull.php | 3 +- src/pocketmine/block/SnowLayer.php | 3 +- src/pocketmine/block/Stair.php | 3 +- src/pocketmine/block/Sugarcane.php | 3 +- src/pocketmine/block/Torch.php | 7 +- src/pocketmine/block/Trapdoor.php | 3 +- src/pocketmine/block/TripwireHook.php | 3 +- src/pocketmine/block/WallBanner.php | 3 +- src/pocketmine/block/WallSign.php | 3 +- .../block/WeightedPressurePlateLight.php | 3 +- .../block/utils/BlockDataValidator.php | 85 +++++++++++++++++++ .../utils/InvalidBlockStateException.php | 28 ++++++ .../block/utils/PillarRotationTrait.php | 9 +- 43 files changed, 222 insertions(+), 59 deletions(-) create mode 100644 src/pocketmine/block/utils/BlockDataValidator.php create mode 100644 src/pocketmine/block/utils/InvalidBlockStateException.php diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index 8dd96332f9..0c0c0b0aea 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\inventory\AnvilInventory; use pocketmine\item\Item; use pocketmine\item\TieredTool; @@ -46,7 +47,7 @@ class Anvil extends Fallable{ } public function readStateFromMeta(int $meta) : void{ - $this->facing = Bearing::toFacing($meta); + $this->facing = BlockDataValidator::readLegacyHorizontalFacing($meta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/BaseRail.php b/src/pocketmine/block/BaseRail.php index 187f6b2222..2e546577b4 100644 --- a/src/pocketmine/block/BaseRail.php +++ b/src/pocketmine/block/BaseRail.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -84,9 +85,11 @@ abstract class BaseRail extends Flowable{ } public function readStateFromMeta(int $meta) : void{ - //on invalid states, this will return an empty array, allowing this rail to transform into any other state - //TODO: should this throw instead? - $this->connections = $this->getConnectionsFromMeta($meta); + $connections = $this->getConnectionsFromMeta($meta); + if($connections === null){ + throw new InvalidBlockStateException("Invalid rail type meta $meta"); + } + $this->connections = $connections; } public function getStateBitmask() : int{ @@ -138,7 +141,7 @@ abstract class BaseRail extends Flowable{ * * @return int[] */ - abstract protected function getConnectionsFromMeta(int $meta) : array; + abstract protected function getConnectionsFromMeta(int $meta) : ?array; /** * Returns all the directions this rail is already connected in. diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 74474e049e..edfc72ed85 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\block\utils\Color; use pocketmine\item\Item; use pocketmine\item\ItemFactory; @@ -65,7 +66,7 @@ class Bed extends Transparent{ } public function readStateFromMeta(int $meta) : void{ - $this->facing = Bearing::toFacing($meta & 0x03); + $this->facing = BlockDataValidator::readLegacyHorizontalFacing($meta & 0x03); $this->occupied = ($meta & self::BITFLAG_OCCUPIED) !== 0; $this->head = ($meta & self::BITFLAG_HEAD) !== 0; } diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 67adef400b..747b8137b8 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -26,6 +26,7 @@ declare(strict_types=1); */ namespace pocketmine\block; +use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\entity\Entity; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\Item; @@ -146,6 +147,10 @@ class Block extends Position implements BlockIds, Metadatable{ return 0; } + /** + * @param int $meta + * @throws InvalidBlockStateException + */ public function readStateFromMeta(int $meta) : void{ //NOOP } diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 676e6fa7fb..8c3fa4005b 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\Color; +use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\block\utils\PillarRotationTrait; use pocketmine\block\utils\WoodType; use pocketmine\item\Item; @@ -470,10 +471,16 @@ class BlockFactory{ $index = ($id << 4) | $m; $v = clone $block; - $v->readStateFromMeta($m & $stateMask); - if($v->getDamage() === $m){ //don't register anything that isn't the same when we read it back again - self::fillStaticArrays($index, $v); + try{ + $v->readStateFromMeta($m & $stateMask); + if($v->getDamage() !== $m){ + throw new InvalidBlockStateException("Corrupted meta"); //don't register anything that isn't the same when we read it back again + } + }catch(InvalidBlockStateException $e){ //invalid property combination + continue; } + + self::fillStaticArrays($index, $v); } if(!self::isRegistered($id, $variant)){ diff --git a/src/pocketmine/block/Button.php b/src/pocketmine/block/Button.php index 8baa3af126..54d16b337a 100644 --- a/src/pocketmine/block/Button.php +++ b/src/pocketmine/block/Button.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -46,7 +47,7 @@ abstract class Button extends Flowable{ public function readStateFromMeta(int $meta) : void{ //TODO: in PC it's (6 - facing) for every meta except 0 (down) - $this->facing = $meta & 0x07; + $this->facing = BlockDataValidator::readFacing($meta & 0x07); $this->powered = ($meta & 0x08) !== 0; } diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index 19faaa0da1..d7338b9f6a 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\entity\Entity; use pocketmine\event\block\BlockGrowEvent; use pocketmine\event\entity\EntityDamageByBlockEvent; @@ -49,7 +50,7 @@ class Cactus extends Transparent{ } public function readStateFromMeta(int $meta) : void{ - $this->age = $meta; + $this->age = BlockDataValidator::readBoundedInt("age", $meta, 0, 15); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index ffa436c57d..f50b09dc15 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\entity\EffectInstance; use pocketmine\entity\Living; use pocketmine\item\FoodSource; @@ -50,7 +51,7 @@ class Cake extends Transparent implements FoodSource{ } public function readStateFromMeta(int $meta) : void{ - $this->bites = $meta; + $this->bites = BlockDataValidator::readBoundedInt("bites", $meta, 0, 6); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index f64fe4bb10..9e0beb7e26 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -47,7 +48,7 @@ class Chest extends Transparent{ } public function readStateFromMeta(int $meta) : void{ - $this->facing = $meta; + $this->facing = BlockDataValidator::readHorizontalFacing($meta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index 3c58587c54..8e31ee2ba4 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\AxisAlignedBB; @@ -49,8 +50,8 @@ class CocoaBlock extends Transparent{ } public function readStateFromMeta(int $meta) : void{ - $this->facing = Facing::opposite(Bearing::toFacing($meta & 0x03)); - $this->age = $meta >> 2; + $this->facing = Facing::opposite(BlockDataValidator::readLegacyHorizontalFacing($meta & 0x03)); + $this->age = BlockDataValidator::readBoundedInt("age", $meta >> 2, 0, 2); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index 42f1bcbf26..5e6ad21f02 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Item; use pocketmine\math\Facing; @@ -42,7 +43,7 @@ abstract class Crops extends Flowable{ } public function readStateFromMeta(int $meta) : void{ - $this->age = $meta; + $this->age = BlockDataValidator::readBoundedInt("age", $meta, 0, 7); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/DaylightSensor.php b/src/pocketmine/block/DaylightSensor.php index 7afda00e3f..9fdbd267c2 100644 --- a/src/pocketmine/block/DaylightSensor.php +++ b/src/pocketmine/block/DaylightSensor.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -51,7 +52,7 @@ class DaylightSensor extends Transparent{ } public function readStateFromMeta(int $meta) : void{ - $this->power = $meta; + $this->power = BlockDataValidator::readBoundedInt("power", $meta, 0, 15); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 5f7dc498d3..f927860b14 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\level\sound\DoorSound; use pocketmine\math\AxisAlignedBB; @@ -51,7 +52,7 @@ abstract class Door extends Transparent{ return 0x08 | ($this->hingeRight ? 0x01 : 0) | ($this->powered ? 0x02 : 0); } - return Bearing::rotate(Bearing::fromFacing($this->facing), 1) | ($this->open ? 0x04 : 0); + return Bearing::fromFacing(Facing::rotateY($this->facing, true)) | ($this->open ? 0x04 : 0); } public function readStateFromMeta(int $meta) : void{ @@ -60,7 +61,7 @@ abstract class Door extends Transparent{ $this->hingeRight = ($meta & 0x01) !== 0; $this->powered = ($meta & 0x02) !== 0; }else{ - $this->facing = Bearing::toFacing(Bearing::rotate($meta & 0x03, -1)); + $this->facing = Facing::rotateY(BlockDataValidator::readLegacyHorizontalFacing($meta & 0x03), false); $this->open = ($meta & 0x04) !== 0; } } diff --git a/src/pocketmine/block/EndPortalFrame.php b/src/pocketmine/block/EndPortalFrame.php index d981ae9138..e15b55dc55 100644 --- a/src/pocketmine/block/EndPortalFrame.php +++ b/src/pocketmine/block/EndPortalFrame.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; @@ -48,7 +49,7 @@ class EndPortalFrame extends Solid{ } public function readStateFromMeta(int $meta) : void{ - $this->facing = Bearing::toFacing($meta & 0x03); + $this->facing = BlockDataValidator::readLegacyHorizontalFacing($meta & 0x03); $this->eye = ($meta & 0x04) !== 0; } diff --git a/src/pocketmine/block/EndRod.php b/src/pocketmine/block/EndRod.php index eeebbd200c..aedfb03d5a 100644 --- a/src/pocketmine/block/EndRod.php +++ b/src/pocketmine/block/EndRod.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -48,11 +49,11 @@ class EndRod extends Flowable{ } public function readStateFromMeta(int $meta) : void{ - if($meta === 0 or $meta === 1){ - $this->facing = $meta; - }else{ - $this->facing = $meta ^ 1; //TODO: see above + if($meta !== 0 and $meta !== 1){ + $meta ^= 1; } + + $this->facing = BlockDataValidator::readFacing($meta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index c1e25eaeec..2e862559e6 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\AxisAlignedBB; @@ -44,7 +45,7 @@ class Farmland extends Transparent{ } public function readStateFromMeta(int $meta) : void{ - $this->wetness = $meta; + $this->wetness = BlockDataValidator::readBoundedInt("wetness", $meta, 0, 7); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index d17c9e82e5..4be8fd463d 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\level\sound\DoorSound; use pocketmine\math\AxisAlignedBB; @@ -42,7 +43,7 @@ class FenceGate extends Transparent{ } public function readStateFromMeta(int $meta) : void{ - $this->facing = Bearing::toFacing($meta & 0x03); + $this->facing = BlockDataValidator::readLegacyHorizontalFacing($meta & 0x03); $this->open = ($meta & 0x04) !== 0; } diff --git a/src/pocketmine/block/Fire.php b/src/pocketmine/block/Fire.php index 7a5da3ff3f..08ab3c9d24 100644 --- a/src/pocketmine/block/Fire.php +++ b/src/pocketmine/block/Fire.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\entity\Entity; use pocketmine\entity\projectile\Arrow; use pocketmine\event\block\BlockBurnEvent; @@ -48,7 +49,7 @@ class Fire extends Flowable{ } public function readStateFromMeta(int $meta) : void{ - $this->age = $meta; + $this->age = BlockDataValidator::readBoundedInt("age", $meta, 0, 15); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index 96293cd209..0e2dc49e97 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\item\TieredTool; use pocketmine\math\Facing; @@ -53,7 +54,7 @@ class Furnace extends Solid{ } public function readStateFromMeta(int $meta) : void{ - $this->facing = $meta; + $this->facing = BlockDataValidator::readHorizontalFacing($meta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/GlazedTerracotta.php b/src/pocketmine/block/GlazedTerracotta.php index 940ee38249..0fb27de73f 100644 --- a/src/pocketmine/block/GlazedTerracotta.php +++ b/src/pocketmine/block/GlazedTerracotta.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\item\TieredTool; use pocketmine\math\Facing; @@ -40,7 +41,7 @@ class GlazedTerracotta extends Solid{ } public function readStateFromMeta(int $meta) : void{ - $this->facing = $meta; + $this->facing = BlockDataValidator::readHorizontalFacing($meta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 7c6a92abcf..0e26f8508e 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -47,7 +48,7 @@ class ItemFrame extends Flowable{ } public function readStateFromMeta(int $meta) : void{ - $this->facing = 5 - $meta; + $this->facing = BlockDataValidator::readHorizontalFacing(5 - $meta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Ladder.php b/src/pocketmine/block/Ladder.php index 1b834204ec..0579b7e3c2 100644 --- a/src/pocketmine/block/Ladder.php +++ b/src/pocketmine/block/Ladder.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\entity\Entity; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; @@ -46,7 +47,7 @@ class Ladder extends Transparent{ } public function readStateFromMeta(int $meta) : void{ - $this->facing = $meta; + $this->facing = BlockDataValidator::readHorizontalFacing($meta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index f813a78313..11a8f4efe4 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -68,7 +69,7 @@ class Lever extends Flowable{ $this->facing = $rotationMeta === 7 ? Facing::SOUTH : Facing::EAST; }else{ $this->position = self::SIDE; - $this->facing = 6 - $rotationMeta; + $this->facing = BlockDataValidator::readHorizontalFacing(6 - $rotationMeta); } $this->powered = ($meta & 0x08) !== 0; diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index f5de8b964e..af4b5c37be 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\entity\Entity; use pocketmine\event\block\BlockFormEvent; use pocketmine\event\block\BlockSpreadEvent; @@ -69,7 +70,7 @@ abstract class Liquid extends Transparent{ } public function readStateFromMeta(int $meta) : void{ - $this->decay = $meta & 0x07; + $this->decay = BlockDataValidator::readBoundedInt("decay", $meta & 0x07, 0, 7); $this->falling = ($meta & 0x08) !== 0; } diff --git a/src/pocketmine/block/NetherReactor.php b/src/pocketmine/block/NetherReactor.php index 1ea1a3332f..92c2c0bb2a 100644 --- a/src/pocketmine/block/NetherReactor.php +++ b/src/pocketmine/block/NetherReactor.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; @@ -46,7 +47,7 @@ class NetherReactor extends Solid{ } public function readStateFromMeta(int $meta) : void{ - $this->state = $meta; + $this->state = BlockDataValidator::readBoundedInt("state", $meta, 0, 2); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index 91d8eee7f0..2ef06b4ab3 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; @@ -48,7 +49,7 @@ class NetherWartPlant extends Flowable{ } public function readStateFromMeta(int $meta) : void{ - $this->age = $meta; + $this->age = BlockDataValidator::readBoundedInt("age", $meta, 0, 3); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Rail.php b/src/pocketmine/block/Rail.php index b7d5ab8a9f..2101cfaf68 100644 --- a/src/pocketmine/block/Rail.php +++ b/src/pocketmine/block/Rail.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\math\Facing; class Rail extends BaseRail{ @@ -66,8 +67,8 @@ class Rail extends BaseRail{ } } - protected function getConnectionsFromMeta(int $meta) : array{ - return self::CURVE_CONNECTIONS[$meta] ?? self::CONNECTIONS[$meta] ?? []; + protected function getConnectionsFromMeta(int $meta) : ?array{ + return self::CURVE_CONNECTIONS[$meta] ?? self::CONNECTIONS[$meta] ?? null; } protected function getPossibleConnectionDirectionsOneConstraint(int $constraint) : array{ diff --git a/src/pocketmine/block/RedstoneRail.php b/src/pocketmine/block/RedstoneRail.php index 4592bb1c69..01b1b10c98 100644 --- a/src/pocketmine/block/RedstoneRail.php +++ b/src/pocketmine/block/RedstoneRail.php @@ -38,7 +38,7 @@ abstract class RedstoneRail extends BaseRail{ $this->powered = ($meta & self::FLAG_POWERED) !== 0; } - protected function getConnectionsFromMeta(int $meta) : array{ - return self::CONNECTIONS[$meta & ~self::FLAG_POWERED] ?? []; + protected function getConnectionsFromMeta(int $meta) : ?array{ + return self::CONNECTIONS[$meta & ~self::FLAG_POWERED] ?? null; } } diff --git a/src/pocketmine/block/RedstoneRepeater.php b/src/pocketmine/block/RedstoneRepeater.php index d64fe598fb..a8b98836d7 100644 --- a/src/pocketmine/block/RedstoneRepeater.php +++ b/src/pocketmine/block/RedstoneRepeater.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; @@ -50,8 +51,8 @@ class RedstoneRepeater extends Flowable{ } public function readStateFromMeta(int $meta) : void{ - $this->facing = Bearing::toFacing($meta & 0x03); - $this->delay = ($meta >> 2) + 1; + $this->facing = BlockDataValidator::readLegacyHorizontalFacing($meta & 0x03); + $this->delay = BlockDataValidator::readBoundedInt("delay", ($meta >> 2) + 1, 1, 4); } public function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/RedstoneWire.php b/src/pocketmine/block/RedstoneWire.php index f9dc52266c..6ad98d589d 100644 --- a/src/pocketmine/block/RedstoneWire.php +++ b/src/pocketmine/block/RedstoneWire.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; class RedstoneWire extends Flowable{ @@ -39,7 +40,7 @@ class RedstoneWire extends Flowable{ } public function readStateFromMeta(int $meta) : void{ - $this->power = $meta; + $this->power = BlockDataValidator::readBoundedInt("power", $meta, 0, 15); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index d1fd2955bb..e586c10527 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\AxisAlignedBB; @@ -52,7 +53,7 @@ class Skull extends Flowable{ } public function readStateFromMeta(int $meta) : void{ - $this->facing = $meta; + $this->facing = $meta === 1 ? Facing::UP : BlockDataValidator::readHorizontalFacing($meta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index 03759ef33b..a998a78bc4 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; @@ -46,7 +47,7 @@ class SnowLayer extends Flowable{ } public function readStateFromMeta(int $meta) : void{ - $this->layers = $meta + 1; + $this->layers = BlockDataValidator::readBoundedInt("layers", $meta + 1, 1, 8); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index 6ef67b32d5..fba071a54f 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -48,7 +49,7 @@ abstract class Stair extends Transparent{ } public function readStateFromMeta(int $meta) : void{ - $this->facing = 5 - ($meta & 0x03); + $this->facing = BlockDataValidator::readHorizontalFacing(5 - ($meta & 0x03)); $this->upsideDown = ($meta & 0x04) !== 0; } diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index 4dc97d84d1..aa78a99a6f 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Item; use pocketmine\math\Facing; @@ -47,7 +48,7 @@ class Sugarcane extends Flowable{ } public function readStateFromMeta(int $meta) : void{ - $this->age = $meta; + $this->age = BlockDataValidator::readBoundedInt("age", $meta, 0, 15); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index e3fc2af253..b50ceee6f0 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -44,11 +45,7 @@ class Torch extends Flowable{ } public function readStateFromMeta(int $meta) : void{ - if($meta === 0){ - $this->facing = Facing::UP; - }else{ - $this->facing = 6 - $meta; - } + $this->facing = $meta === 5 ? Facing::UP : BlockDataValidator::readHorizontalFacing(6 - $meta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index ac6844d286..a943d6ad16 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\level\sound\DoorSound; use pocketmine\math\AxisAlignedBB; @@ -54,7 +55,7 @@ class Trapdoor extends Transparent{ public function readStateFromMeta(int $meta) : void{ //TODO: in PC the values are reversed (facing - 2) - $this->facing = 5 - ($meta & 0x03); + $this->facing = BlockDataValidator::readHorizontalFacing(5 - ($meta & 0x03)); $this->top = ($meta & self::MASK_UPPER) !== 0; $this->open = ($meta & self::MASK_OPENED) !== 0; } diff --git a/src/pocketmine/block/TripwireHook.php b/src/pocketmine/block/TripwireHook.php index ef56ce8475..cf79a4919f 100644 --- a/src/pocketmine/block/TripwireHook.php +++ b/src/pocketmine/block/TripwireHook.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\math\Bearing; use pocketmine\math\Facing; @@ -49,7 +50,7 @@ class TripwireHook extends Flowable{ } public function readStateFromMeta(int $meta) : void{ - $this->facing = Bearing::toFacing($meta & 0x03); + $this->facing = BlockDataValidator::readLegacyHorizontalFacing($meta & 0x03); $this->connected = ($meta & 0x04) !== 0; $this->powered = ($meta & 0x08) !== 0; } diff --git a/src/pocketmine/block/WallBanner.php b/src/pocketmine/block/WallBanner.php index a161ce8475..41aac1639c 100644 --- a/src/pocketmine/block/WallBanner.php +++ b/src/pocketmine/block/WallBanner.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\math\Facing; class WallBanner extends StandingBanner{ @@ -37,7 +38,7 @@ class WallBanner extends StandingBanner{ } public function readStateFromMeta(int $meta) : void{ - $this->facing = $meta; + $this->facing = BlockDataValidator::readHorizontalFacing($meta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/WallSign.php b/src/pocketmine/block/WallSign.php index e416e27eb5..bca6b62692 100644 --- a/src/pocketmine/block/WallSign.php +++ b/src/pocketmine/block/WallSign.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\math\Facing; class WallSign extends SignPost{ @@ -37,7 +38,7 @@ class WallSign extends SignPost{ } public function readStateFromMeta(int $meta) : void{ - $this->facing = $meta; + $this->facing = BlockDataValidator::readHorizontalFacing($meta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/WeightedPressurePlateLight.php b/src/pocketmine/block/WeightedPressurePlateLight.php index baea3a0bfa..7bd0b74e58 100644 --- a/src/pocketmine/block/WeightedPressurePlateLight.php +++ b/src/pocketmine/block/WeightedPressurePlateLight.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\TieredTool; class WeightedPressurePlateLight extends Transparent{ @@ -41,7 +42,7 @@ class WeightedPressurePlateLight extends Transparent{ } public function readStateFromMeta(int $meta) : void{ - $this->power = $meta; + $this->power = BlockDataValidator::readBoundedInt("power", $meta, 0, 15); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/utils/BlockDataValidator.php b/src/pocketmine/block/utils/BlockDataValidator.php new file mode 100644 index 0000000000..1e92c400e7 --- /dev/null +++ b/src/pocketmine/block/utils/BlockDataValidator.php @@ -0,0 +1,85 @@ + $max){ + throw new InvalidBlockStateException("$name should be in range $min - $max, got $v"); + } + return $v; + } +} diff --git a/src/pocketmine/block/utils/InvalidBlockStateException.php b/src/pocketmine/block/utils/InvalidBlockStateException.php new file mode 100644 index 0000000000..506b81dbb6 --- /dev/null +++ b/src/pocketmine/block/utils/InvalidBlockStateException.php @@ -0,0 +1,28 @@ + Facing::AXIS_Y, 1 => Facing::AXIS_X, - 2 => Facing::AXIS_Z, - 3 => Facing::AXIS_Y //TODO: how to deal with all-bark logs? + 2 => Facing::AXIS_Z ]; - $this->axis = $map[$meta >> 2]; + $axis = $meta >> 2; + if(!isset($map[$axis])){ + throw new InvalidBlockStateException("Invalid axis meta $axis"); + } + $this->axis = $map[$axis]; } protected function writeAxisToMeta() : int{ From f06e67a792a79b2a8085be9bbac6174dfa30ed81 Mon Sep 17 00:00:00 2001 From: Frago9876543210 Date: Fri, 28 Dec 2018 17:34:54 +0300 Subject: [PATCH 0343/3224] Allow plugins to disable background generation (#2613) --- src/pocketmine/Server.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 1de1a99a83..c15d80a4b2 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1048,10 +1048,11 @@ class Server{ * @param int|null $seed * @param string|null $generator Class name that extends pocketmine\level\generator\Generator * @param array $options + * @param bool $backgroundGeneration * * @return bool */ - public function generateLevel(string $name, int $seed = null, $generator = null, array $options = []) : bool{ + public function generateLevel(string $name, int $seed = null, $generator = null, array $options = [], bool $backgroundGeneration = true) : bool{ if(trim($name) === "" or $this->isLevelGenerated($name)){ return false; } @@ -1082,6 +1083,10 @@ class Server{ (new LevelLoadEvent($level))->call(); + if(!$backgroundGeneration){ + return true; + } + $this->getLogger()->notice($this->getLanguage()->translateString("pocketmine.level.backgroundGeneration", [$name])); $spawnLocation = $level->getSpawnLocation(); From 3ebd7e8ba696aee5b4eee0ba6dfccdd5b74ac7ca Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 28 Dec 2018 16:30:04 +0000 Subject: [PATCH 0344/3224] Add network-wide API to filter raw packets by regex, stricter validation for Query --- composer.lock | 8 ++++---- src/pocketmine/network/AdvancedNetworkInterface.php | 7 +++++++ src/pocketmine/network/Network.php | 6 ++++++ src/pocketmine/network/mcpe/RakLibInterface.php | 4 ++++ src/pocketmine/network/query/QueryHandler.php | 1 + 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 34d6c2f076..bcf26dbc2b 100644 --- a/composer.lock +++ b/composer.lock @@ -351,12 +351,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "a92e0508b13386e938a8092201ddfd3da17b8dd0" + "reference": "b447c7895b5672b7d2f6b92f0919ae814d6b13dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/a92e0508b13386e938a8092201ddfd3da17b8dd0", - "reference": "a92e0508b13386e938a8092201ddfd3da17b8dd0", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/b447c7895b5672b7d2f6b92f0919ae814d6b13dc", + "reference": "b447c7895b5672b7d2f6b92f0919ae814d6b13dc", "shasum": "" }, "require": { @@ -384,7 +384,7 @@ "source": "https://github.com/pmmp/RakLib/tree/master", "issues": "https://github.com/pmmp/RakLib/issues" }, - "time": "2018-11-05T21:18:34+00:00" + "time": "2018-12-28T16:10:25+00:00" }, { "name": "pocketmine/snooze", diff --git a/src/pocketmine/network/AdvancedNetworkInterface.php b/src/pocketmine/network/AdvancedNetworkInterface.php index 85afc739e5..42c1ef62d5 100644 --- a/src/pocketmine/network/AdvancedNetworkInterface.php +++ b/src/pocketmine/network/AdvancedNetworkInterface.php @@ -61,4 +61,11 @@ interface AdvancedNetworkInterface extends NetworkInterface{ */ public function sendRawPacket(string $address, int $port, string $payload) : void; + /** + * Adds a regex filter for raw packets to this network interface. This filter should be used to check validity of + * raw packets before relaying them to the main thread. + * + * @param string $regex + */ + public function addRawPacketFilter(string $regex) : void; } diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index cd65f68d6b..8a78a07f71 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -195,6 +195,12 @@ class Network{ } } + public function addRawPacketFilter(string $regex) : void{ + foreach($this->advancedInterfaces as $interface){ + $interface->addRawPacketFilter($regex); + } + } + public function scheduleSessionTick(NetworkSession $session) : void{ $this->updateSessions[spl_object_hash($session)] = $session; } diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 176be22b0f..30d1d2fdf3 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -169,6 +169,10 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $this->interface->sendRaw($address, $port, $payload); } + public function addRawPacketFilter(string $regex) : void{ + $this->interface->addRawPacketFilter($regex); + } + public function notifyACK(string $identifier, int $identifierACK) : void{ } diff --git a/src/pocketmine/network/query/QueryHandler.php b/src/pocketmine/network/query/QueryHandler.php index 2a64c5804d..e3cd45197f 100644 --- a/src/pocketmine/network/query/QueryHandler.php +++ b/src/pocketmine/network/query/QueryHandler.php @@ -39,6 +39,7 @@ class QueryHandler{ public function __construct(){ $this->server = Server::getInstance(); + $this->server->getNetwork()->addRawPacketFilter('/^\xfe\xfd.+$/s'); $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.server.query.start")); $addr = $this->server->getIp(); $port = $this->server->getPort(); From e6381297c73019fc8093263694a6d43959b65220 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 28 Dec 2018 17:35:37 +0000 Subject: [PATCH 0345/3224] NetworkCipher: fix some missing typehints --- src/pocketmine/network/mcpe/NetworkCipher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/NetworkCipher.php b/src/pocketmine/network/mcpe/NetworkCipher.php index 7e3bd07217..5e9fda64c8 100644 --- a/src/pocketmine/network/mcpe/NetworkCipher.php +++ b/src/pocketmine/network/mcpe/NetworkCipher.php @@ -59,7 +59,7 @@ class NetworkCipher{ $this->encryptCipher->encryptInit($this->key, $iv); } - public function decrypt($encrypted){ + public function decrypt(string $encrypted) : string{ if(strlen($encrypted) < 9){ throw new \InvalidArgumentException("Payload is too short"); } From 23954c4cda739190cb79295eeb78859c5c329be0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 28 Dec 2018 23:03:24 +0000 Subject: [PATCH 0346/3224] RegionLoader: Remove dead/broken code garbage collection does need to be implemented, but I was looking at this code and found so many fucking bugs I decided it wasn't worth the effort of fixing. --- .../level/format/io/region/RegionLoader.php | 75 ------------------- 1 file changed, 75 deletions(-) diff --git a/src/pocketmine/level/format/io/region/RegionLoader.php b/src/pocketmine/level/format/io/region/RegionLoader.php index 08b680a183..75443c67e5 100644 --- a/src/pocketmine/level/format/io/region/RegionLoader.php +++ b/src/pocketmine/level/format/io/region/RegionLoader.php @@ -190,81 +190,6 @@ class RegionLoader{ } } - public function doSlowCleanUp() : int{ - for($i = 0; $i < 1024; ++$i){ - if($this->locationTable[$i][0] === 0 or $this->locationTable[$i][1] === 0){ - continue; - } - fseek($this->filePointer, $this->locationTable[$i][0] << 12); - $chunk = fread($this->filePointer, $this->locationTable[$i][1] << 12); - $length = Binary::readInt(substr($chunk, 0, 4)); - if($length <= 1){ - $this->locationTable[$i] = [0, 0, 0]; //Non-generated chunk, remove it from index - } - - try{ - $chunk = zlib_decode(substr($chunk, 5)); - }catch(\Throwable $e){ - $this->locationTable[$i] = [0, 0, 0]; //Corrupted chunk, remove it - continue; - } - - $chunk = chr(self::COMPRESSION_ZLIB) . zlib_encode($chunk, ZLIB_ENCODING_DEFLATE, 9); - $chunk = Binary::writeInt(strlen($chunk)) . $chunk; - $sectors = (int) ceil(strlen($chunk) / 4096); - if($sectors > $this->locationTable[$i][1]){ - $this->locationTable[$i][0] = $this->lastSector + 1; - $this->lastSector += $sectors; - } - fseek($this->filePointer, $this->locationTable[$i][0] << 12); - fwrite($this->filePointer, str_pad($chunk, $sectors << 12, "\x00", STR_PAD_RIGHT)); - } - $this->writeLocationTable(); - $n = $this->cleanGarbage(); - $this->writeLocationTable(); - - return $n; - } - - private function cleanGarbage() : int{ - $sectors = []; - foreach($this->locationTable as $index => $data){ //Calculate file usage - if($data[0] === 0 or $data[1] === 0){ - $this->locationTable[$index] = [0, 0, 0]; - continue; - } - for($i = 0; $i < $data[1]; ++$i){ - $sectors[$data[0]] = $index; - } - } - - if(count($sectors) === ($this->lastSector - 2)){ //No collection needed - return 0; - } - - ksort($sectors); - $shift = 0; - $lastSector = 1; //First chunk - 1 - - fseek($this->filePointer, 8192); - $sector = 2; - foreach($sectors as $sector => $index){ - if(($sector - $lastSector) > 1){ - $shift += $sector - $lastSector - 1; - } - if($shift > 0){ - fseek($this->filePointer, $sector << 12); - $old = fread($this->filePointer, 4096); - fseek($this->filePointer, ($sector - $shift) << 12); - fwrite($this->filePointer, $old, 4096); - } - $this->locationTable[$index][0] -= $shift; - $lastSector = $sector; - } - ftruncate($this->filePointer, ($sector + 1) << 12); //Truncate to the end of file written - return $shift; - } - protected function loadLocationTable() : void{ fseek($this->filePointer, 0); $this->lastSector = 1; From 498bffb34f08a3ea155dad44746306118f54db5d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 29 Dec 2018 11:23:32 +0000 Subject: [PATCH 0347/3224] Fixed --enable-ansi and --disable-ansi not being respected on threads this causes some breakage to the behaviour of Terminal, and for that reason this is going on 4.0. Terminal::hasFormattingCodes() will no longer auto-detect whether colour codes are supported. --- src/pocketmine/PocketMine.php | 10 ++++++- src/pocketmine/utils/MainLogger.php | 14 ++++------ src/pocketmine/utils/Terminal.php | 43 +++++++++++++++-------------- 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index dabc0c8356..83e844f9d3 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -183,7 +183,7 @@ namespace pocketmine { define('pocketmine\RESOURCE_PATH', \pocketmine\PATH . 'resources' . DIRECTORY_SEPARATOR); - $opts = getopt("", ["data:", "plugins:", "no-wizard"]); + $opts = getopt("", ["data:", "plugins:", "no-wizard", "enable-ansi", "disable-ansi"]); define('pocketmine\DATA', isset($opts["data"]) ? $opts["data"] . DIRECTORY_SEPARATOR : realpath(getcwd()) . DIRECTORY_SEPARATOR); define('pocketmine\PLUGIN_PATH', isset($opts["plugins"]) ? $opts["plugins"] . DIRECTORY_SEPARATOR : realpath(getcwd()) . DIRECTORY_SEPARATOR . "plugins" . DIRECTORY_SEPARATOR); @@ -195,6 +195,14 @@ namespace pocketmine { //Logger has a dependency on timezone Timezone::init(); + if(isset($opts["enable-ansi"])){ + Terminal::init(true); + }elseif(isset($opts["disable-ansi"])){ + Terminal::init(false); + }else{ + Terminal::init(); + } + $logger = new MainLogger(\pocketmine\DATA . "server.log"); $logger->registerStatic(); \GlobalLogger::set($logger); diff --git a/src/pocketmine/utils/MainLogger.php b/src/pocketmine/utils/MainLogger.php index 3f5e0f3f6b..78562da779 100644 --- a/src/pocketmine/utils/MainLogger.php +++ b/src/pocketmine/utils/MainLogger.php @@ -275,20 +275,18 @@ class MainLogger extends \AttachableThreadedLogger{ $message = sprintf($this->format, $time->format("H:i:s"), $color, $threadName, $prefix, $message); - $this->synchronized(function() use ($message, $level, $time) : void{ - $cleanMessage = TextFormat::clean($message); + if(!Terminal::isInit()){ + Terminal::init($this->mainThreadHasFormattingCodes); //lazy-init colour codes because we don't know if they've been registered on this thread + } - if($this->mainThreadHasFormattingCodes and Terminal::hasFormattingCodes()){ //hasFormattingCodes() lazy-inits colour codes because we don't know if they've been registered on this thread - echo Terminal::toANSI($message) . PHP_EOL; - }else{ - echo $cleanMessage . PHP_EOL; - } + $this->synchronized(function() use ($message, $level, $time) : void{ + echo Terminal::toANSI($message) . PHP_EOL; foreach($this->attachments as $attachment){ $attachment->call($level, $message); } - $this->logStream[] = $time->format("Y-m-d") . " " . $cleanMessage . PHP_EOL; + $this->logStream[] = $time->format("Y-m-d") . " " . TextFormat::clean($message) . PHP_EOL; }); } diff --git a/src/pocketmine/utils/Terminal.php b/src/pocketmine/utils/Terminal.php index 5f4140e1e9..f7c52a974d 100644 --- a/src/pocketmine/utils/Terminal.php +++ b/src/pocketmine/utils/Terminal.php @@ -49,31 +49,29 @@ abstract class Terminal{ public static $COLOR_YELLOW = ""; public static $COLOR_WHITE = ""; + /** @var bool|null */ private static $formattingCodes = null; - public static function hasFormattingCodes(){ + public static function hasFormattingCodes() : bool{ if(self::$formattingCodes === null){ - $opts = getopt("", ["enable-ansi", "disable-ansi"]); - if(isset($opts["disable-ansi"])){ - self::$formattingCodes = false; - }else{ - $stdout = fopen("php://stdout", "w"); - self::$formattingCodes = (isset($opts["enable-ansi"]) or ( //user explicitly told us to enable ANSI - stream_isatty($stdout) and //STDOUT isn't being piped - ( - getenv('TERM') !== false or //Console says it supports colours - (function_exists('sapi_windows_vt100_support') and sapi_windows_vt100_support($stdout)) //we're on windows and have vt100 support - ) - )); - fclose($stdout); - } - - self::init(); + throw new \InvalidStateException("Formatting codes have not been initialized"); } - return self::$formattingCodes; } + private static function detectFormattingCodesSupport() : bool{ + $stdout = fopen("php://stdout", "w"); + $result = ( + stream_isatty($stdout) and //STDOUT isn't being piped + ( + getenv('TERM') !== false or //Console says it supports colours + (function_exists('sapi_windows_vt100_support') and sapi_windows_vt100_support($stdout)) //we're on windows and have vt100 support + ) + ); + fclose($stdout); + return $result; + } + protected static function getFallbackEscapeCodes(){ self::$FORMAT_BOLD = "\x1b[1m"; self::$FORMAT_OBFUSCATED = ""; @@ -140,8 +138,9 @@ abstract class Terminal{ } } - public static function init(){ - if(!self::hasFormattingCodes()){ + public static function init(?bool $enableFormatting = null) : void{ + self::$formattingCodes = $enableFormatting ?? self::detectFormattingCodesSupport(); + if(!self::$formattingCodes){ return; } @@ -161,6 +160,10 @@ abstract class Terminal{ //TODO: iOS } + public static function isInit() : bool{ + return self::$formattingCodes !== null; + } + /** * Returns a string with colorized ANSI Escape codes for the current terminal * Note that this is platform-dependent and might produce different results depending on the terminal type and/or OS. From d86107e22ad49dd75fa4c8a867253f73f0095691 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 29 Dec 2018 11:28:25 +0000 Subject: [PATCH 0348/3224] Terminal: Added write() and writeLine() to allow easily emitting Minecraft-formatted text to the console --- src/pocketmine/utils/MainLogger.php | 2 +- src/pocketmine/utils/Terminal.php | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/utils/MainLogger.php b/src/pocketmine/utils/MainLogger.php index 78562da779..df749f3c97 100644 --- a/src/pocketmine/utils/MainLogger.php +++ b/src/pocketmine/utils/MainLogger.php @@ -280,7 +280,7 @@ class MainLogger extends \AttachableThreadedLogger{ } $this->synchronized(function() use ($message, $level, $time) : void{ - echo Terminal::toANSI($message) . PHP_EOL; + Terminal::writeLine($message); foreach($this->attachments as $attachment){ $attachment->call($level, $message); diff --git a/src/pocketmine/utils/Terminal.php b/src/pocketmine/utils/Terminal.php index f7c52a974d..23c05be8a6 100644 --- a/src/pocketmine/utils/Terminal.php +++ b/src/pocketmine/utils/Terminal.php @@ -256,4 +256,23 @@ abstract class Terminal{ return $newString; } + + /** + * Emits a string containing Minecraft colour codes to the console formatted with native colours. + * + * @param string $line + */ + public static function write(string $line) : void{ + echo self::toANSI($line); + } + + /** + * Emits a string containing Minecraft colour codes to the console formatted with native colours, followed by a + * newline character. + * + * @param string $line + */ + public static function writeLine(string $line) : void{ + echo self::toANSI($line) . PHP_EOL; + } } From aaaddd1fd6f28a9e0f4dcc96b1d633f6f6131bd1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 29 Dec 2018 11:54:44 +0000 Subject: [PATCH 0349/3224] Terminal: stick a RESET on the end when writing a newline --- src/pocketmine/utils/Terminal.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/utils/Terminal.php b/src/pocketmine/utils/Terminal.php index 23c05be8a6..600f780312 100644 --- a/src/pocketmine/utils/Terminal.php +++ b/src/pocketmine/utils/Terminal.php @@ -273,6 +273,6 @@ abstract class Terminal{ * @param string $line */ public static function writeLine(string $line) : void{ - echo self::toANSI($line) . PHP_EOL; + echo self::toANSI($line) . self::$FORMAT_RESET . PHP_EOL; } } From ac87319aed4d556d85a8aeba0ea6da6667a5408f Mon Sep 17 00:00:00 2001 From: Dylan T Date: Sat, 29 Dec 2018 12:00:14 +0000 Subject: [PATCH 0350/3224] Introduce a "block write-batch" concept (#2555) Make use of writebatch to generate trees, doors and double plants safely - Fixes #2441 - Fixes #2548 - Closes #2498 --- src/pocketmine/block/Door.php | 8 +- src/pocketmine/block/DoublePlant.php | 7 +- src/pocketmine/level/BlockWriteBatch.php | 133 ++++++++++++++++++ .../level/generator/object/SpruceTree.php | 13 +- .../level/generator/object/Tree.php | 37 +++-- 5 files changed, 175 insertions(+), 23 deletions(-) create mode 100644 src/pocketmine/level/BlockWriteBatch.php diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index f927860b14..d2602c9522 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; +use pocketmine\level\BlockWriteBatch; use pocketmine\level\sound\DoorSound; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; @@ -124,9 +125,10 @@ abstract class Door extends Transparent{ $topHalf = clone $this; $topHalf->top = true; - parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); - $this->level->setBlock($blockUp, $topHalf); //Top - return true; + $write = new BlockWriteBatch(); + $write->addBlock($blockReplace, $this)->addBlock($blockUp, $topHalf); + + return $write->apply($this->level); } return false; diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index 594e901ea2..c730bf6962 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; +use pocketmine\level\BlockWriteBatch; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -49,12 +50,12 @@ class DoublePlant extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $id = $blockReplace->getSide(Facing::DOWN)->getId(); if(($id === Block::GRASS or $id === Block::DIRT) and $blockReplace->getSide(Facing::UP)->canBeReplaced()){ - $this->getLevel()->setBlock($blockReplace, $this, false); $top = clone $this; $top->top = true; - $this->getLevel()->setBlock($blockReplace->getSide(Facing::UP), $top, false); - return true; + $write = new BlockWriteBatch(); + $write->addBlock($blockReplace, $this)->addBlock($blockReplace->getSide(Facing::UP), $top); + return $write->apply($this->level); } return false; diff --git a/src/pocketmine/level/BlockWriteBatch.php b/src/pocketmine/level/BlockWriteBatch.php new file mode 100644 index 0000000000..8638930fd4 --- /dev/null +++ b/src/pocketmine/level/BlockWriteBatch.php @@ -0,0 +1,133 @@ +addValidator(function(ChunkManager $world, int $x, int $y, int $z) : bool{ + return $world->isInWorld($x, $y, $z); + }); + } + + /** + * Adds a block to the batch at the given position. + * + * @param Vector3 $pos + * @param Block $state + * + * @return $this + */ + public function addBlock(Vector3 $pos, Block $state) : self{ + return $this->addBlockAt($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ(), $state); + } + + /** + * Adds a block to the batch at the given coordinates. + * + * @param int $x + * @param int $y + * @param int $z + * @param Block $state + * + * @return $this + */ + public function addBlockAt(int $x, int $y, int $z, Block $state) : self{ + $this->blocks[$x][$y][$z] = $state; + return $this; + } + + /** + * Validates and attempts to apply the batch to the given world. If any part of the batch fails to validate, no + * changes will be made to the world. + * + * @param ChunkManager $world + * + * @return bool if the application was successful + */ + public function apply(ChunkManager $world) : bool{ + foreach($this->getBlocks() as [$x, $y, $z, $_]){ + foreach($this->validators as $validator){ + if(!$validator($world, $x, $y, $z)){ + return false; + } + } + } + foreach($this->getBlocks() as [$x, $y, $z, $block]){ + $world->setBlockAt($x, $y, $z, $block); + } + return true; + } + + /** + * @return \Generator|mixed[] [int $x, int $y, int $z, Block $block] + */ + public function getBlocks() : \Generator{ + foreach($this->blocks as $x => $yLine){ + foreach($yLine as $y => $zLine){ + foreach($zLine as $z => $block){ + yield [$x, $y, $z, $block]; + } + } + } + } + + /** + * Add a validation predicate which will be used to validate every block. + * The callable signature should be the same as the below dummy function. + * @see BlockWriteBatch::dummyValidator() + * + * @param callable $validator + */ + public function addValidator(callable $validator) : void{ + Utils::validateCallableSignature([$this, 'dummyValidator'], $validator); + $this->validators[] = $validator; + } + + /** + * Dummy function demonstrating the required closure signature for validators. + * @see BlockWriteBatch::addValidator() + * + * @dummy + * + * @param ChunkManager $world + * @param int $x + * @param int $y + * @param int $z + * + * @return bool + */ + public function dummyValidator(ChunkManager $world, int $x, int $y, int $z) : bool{ + return true; + } +} diff --git a/src/pocketmine/level/generator/object/SpruceTree.php b/src/pocketmine/level/generator/object/SpruceTree.php index 7333a59238..e757784883 100644 --- a/src/pocketmine/level/generator/object/SpruceTree.php +++ b/src/pocketmine/level/generator/object/SpruceTree.php @@ -26,6 +26,7 @@ namespace pocketmine\level\generator\object; use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\Wood; +use pocketmine\level\BlockWriteBatch; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; @@ -35,14 +36,18 @@ class SpruceTree extends Tree{ parent::__construct(BlockFactory::get(Block::LOG, Wood::SPRUCE), BlockFactory::get(Block::LEAVES, Wood::SPRUCE), 10); } + protected function generateChunkHeight(Random $random) : int{ + return $this->treeHeight - $random->nextBoundedInt(3); + } + public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ $this->treeHeight = $random->nextBoundedInt(4) + 6; + parent::placeObject($level, $x, $y, $z, $random); + } + protected function placeCanopy(ChunkManager $level, int $x, int $y, int $z, Random $random, BlockWriteBatch $write) : void{ $topSize = $this->treeHeight - (1 + $random->nextBoundedInt(2)); $lRadius = 2 + $random->nextBoundedInt(2); - - $this->placeTrunk($level, $x, $y, $z, $random, $this->treeHeight - $random->nextBoundedInt(3)); - $radius = $random->nextBoundedInt(2); $maxR = 1; $minR = 0; @@ -59,7 +64,7 @@ class SpruceTree extends Tree{ } if(!$level->getBlockAt($xx, $yyy, $zz)->isSolid()){ - $level->setBlockAt($xx, $yyy, $zz, $this->leafBlock); + $write->addBlockAt($xx, $yyy, $zz, $this->leafBlock); } } } diff --git a/src/pocketmine/level/generator/object/Tree.php b/src/pocketmine/level/generator/object/Tree.php index f3b3f5492e..0287f672a7 100644 --- a/src/pocketmine/level/generator/object/Tree.php +++ b/src/pocketmine/level/generator/object/Tree.php @@ -29,6 +29,7 @@ use pocketmine\block\Leaves; use pocketmine\block\Sapling; use pocketmine\block\utils\WoodType; use pocketmine\block\Wood; +use pocketmine\level\BlockWriteBatch; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; @@ -100,8 +101,29 @@ abstract class Tree{ } public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ - $this->placeTrunk($level, $x, $y, $z, $random, $this->treeHeight - 1); + $write = new BlockWriteBatch(); + $this->placeTrunk($level, $x, $y, $z, $random, $this->generateChunkHeight($random), $write); + $this->placeCanopy($level, $x, $y, $z, $random, $write); + $write->apply($level); //TODO: handle return value on failure + } + + protected function generateChunkHeight(Random $random) : int{ + return $this->treeHeight - 1; + } + + protected function placeTrunk(ChunkManager $level, int $x, int $y, int $z, Random $random, int $trunkHeight, BlockWriteBatch $write) : void{ + // The base dirt block + $write->addBlockAt($x, $y - 1, $z, BlockFactory::get(Block::DIRT)); + + for($yy = 0; $yy < $trunkHeight; ++$yy){ + if($this->canOverride($level->getBlockAt($x, $y + $yy, $z))){ + $write->addBlockAt($x, $y + $yy, $z, $this->trunkBlock); + } + } + } + + protected function placeCanopy(ChunkManager $level, int $x, int $y, int $z, Random $random, BlockWriteBatch $write) : void{ for($yy = $y - 3 + $this->treeHeight; $yy <= $y + $this->treeHeight; ++$yy){ $yOff = $yy - ($y + $this->treeHeight); $mid = (int) (1 - $yOff / 2); @@ -113,24 +135,13 @@ abstract class Tree{ continue; } if(!$level->getBlockAt($xx, $yy, $zz)->isSolid()){ - $level->setBlockAt($xx, $yy, $zz, $this->leafBlock); + $write->addBlockAt($xx, $yy, $zz, $this->leafBlock); } } } } } - protected function placeTrunk(ChunkManager $level, int $x, int $y, int $z, Random $random, int $trunkHeight) : void{ - // The base dirt block - $level->setBlockAt($x, $y - 1, $z, BlockFactory::get(Block::DIRT)); - - for($yy = 0; $yy < $trunkHeight; ++$yy){ - if($this->canOverride($level->getBlockAt($x, $y + $yy, $z))){ - $level->setBlockAt($x, $y + $yy, $z, $this->trunkBlock); - } - } - } - protected function canOverride(Block $block) : bool{ return $block->canBeReplaced() or $block instanceof Sapling or $block instanceof Leaves; } From 7b3115c00c4421bcc3a4d271a74d6be4692d02f2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 29 Dec 2018 20:12:00 +0000 Subject: [PATCH 0351/3224] Moved network NBT serializer into network namespace --- composer.lock | 8 +- src/pocketmine/Player.php | 2 +- .../mcpe/NetworkLittleEndianNBTStream.php | 79 +++++++++++++++++++ src/pocketmine/tile/Spawnable.php | 2 +- 4 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 src/pocketmine/network/mcpe/NetworkLittleEndianNBTStream.php diff --git a/composer.lock b/composer.lock index bcf26dbc2b..849587f243 100644 --- a/composer.lock +++ b/composer.lock @@ -310,12 +310,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "91b6a158d06032e9029b9a87be64a12c3b93aa14" + "reference": "a32760c1797280574c461e6c42502221de499d01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/91b6a158d06032e9029b9a87be64a12c3b93aa14", - "reference": "91b6a158d06032e9029b9a87be64a12c3b93aa14", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/a32760c1797280574c461e6c42502221de499d01", + "reference": "a32760c1797280574c461e6c42502221de499d01", "shasum": "" }, "require": { @@ -343,7 +343,7 @@ "source": "https://github.com/pmmp/NBT/tree/master", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2018-12-03T16:12:37+00:00" + "time": "2018-12-29T19:46:47+00:00" }, { "name": "pocketmine/raklib", diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index a8edf2a278..e6ebff89ff 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -88,13 +88,13 @@ use pocketmine\level\Level; use pocketmine\level\Position; use pocketmine\math\Vector3; use pocketmine\metadata\MetadataValue; -use pocketmine\nbt\NetworkLittleEndianNBTStream; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\NetworkCipher; +use pocketmine\network\mcpe\NetworkLittleEndianNBTStream; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; diff --git a/src/pocketmine/network/mcpe/NetworkLittleEndianNBTStream.php b/src/pocketmine/network/mcpe/NetworkLittleEndianNBTStream.php new file mode 100644 index 0000000000..7aabeda62f --- /dev/null +++ b/src/pocketmine/network/mcpe/NetworkLittleEndianNBTStream.php @@ -0,0 +1,79 @@ + + +class NetworkLittleEndianNBTStream extends LittleEndianNBTStream{ + + public function getInt() : int{ + return Binary::readVarInt($this->buffer, $this->offset); + } + + public function putInt(int $v) : void{ + $this->put(Binary::writeVarInt($v)); + } + + public function getLong() : int{ + return Binary::readVarLong($this->buffer, $this->offset); + } + + public function putLong(int $v) : void{ + $this->put(Binary::writeVarLong($v)); + } + + public function getString() : string{ + return $this->get(Binary::readUnsignedVarInt($this->buffer, $this->offset)); + } + + public function putString(string $v) : void{ + $len = strlen($v); + if($len > 32767){ + throw new \InvalidArgumentException("NBT strings cannot be longer than 32767 bytes, got $len bytes"); + } + $this->put(Binary::writeUnsignedVarInt($len) . $v); + } + + public function getIntArray() : array{ + $len = $this->getInt(); //varint + $ret = []; + for($i = 0; $i < $len; ++$i){ + $ret[] = $this->getInt(); //varint + } + + return $ret; + } + + public function putIntArray(array $array) : void{ + $this->putInt(count($array)); //varint + foreach($array as $v){ + $this->putInt($v); //varint + } + } +} diff --git a/src/pocketmine/tile/Spawnable.php b/src/pocketmine/tile/Spawnable.php index fe9818d396..0c8200241a 100644 --- a/src/pocketmine/tile/Spawnable.php +++ b/src/pocketmine/tile/Spawnable.php @@ -23,10 +23,10 @@ declare(strict_types=1); namespace pocketmine\tile; -use pocketmine\nbt\NetworkLittleEndianNBTStream; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\StringTag; +use pocketmine\network\mcpe\NetworkLittleEndianNBTStream; use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\Player; From 2e5465e3286d53868247e2556aa14c44e43e3b0b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 29 Dec 2018 20:13:28 +0000 Subject: [PATCH 0352/3224] Updated RakLib dependency --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 849587f243..842e19aa92 100644 --- a/composer.lock +++ b/composer.lock @@ -351,12 +351,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "b447c7895b5672b7d2f6b92f0919ae814d6b13dc" + "reference": "3665288c955c0dbbb40c11ee1c7b4f7e6d5199bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/b447c7895b5672b7d2f6b92f0919ae814d6b13dc", - "reference": "b447c7895b5672b7d2f6b92f0919ae814d6b13dc", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/3665288c955c0dbbb40c11ee1c7b4f7e6d5199bf", + "reference": "3665288c955c0dbbb40c11ee1c7b4f7e6d5199bf", "shasum": "" }, "require": { @@ -384,7 +384,7 @@ "source": "https://github.com/pmmp/RakLib/tree/master", "issues": "https://github.com/pmmp/RakLib/issues" }, - "time": "2018-12-28T16:10:25+00:00" + "time": "2018-12-28T17:22:34+00:00" }, { "name": "pocketmine/snooze", From 1e58144a38a2d940ad60428c88791f0c8bf3c2b1 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Sun, 30 Dec 2018 17:19:25 +0000 Subject: [PATCH 0353/3224] Add Discord link to issue template --- .github/ISSUE_TEMPLATE/bug_report.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index d3f95d40bc..590a70dace 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -9,6 +9,7 @@ about: Report a bug in PocketMine-MP (not plugins) THIS ISSUE TRACKER IS FOR BUG REPORTING, NOT FOR HELP & SUPPORT. If you need help, use the links below. - http://pmmp.readthedocs.io/en/rtfd/ - Documentation - https://forums.pmmp.io - PMMP Forums +- https://discord.gg/bge7dYQ - Community Discord PLEASE DO NOT REPORT ATTACK VECTORS ON THIS ISSUE TRACKER. Send an email to team@pmmp.io if you have a vulnerability to report. From ff3d2ba19e2b0e809f26bd87f77c485e3e03605b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 31 Dec 2018 22:04:08 +0000 Subject: [PATCH 0354/3224] Fixed no-NBT banner items always placing black banners, closes #2624 --- src/pocketmine/item/Banner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/item/Banner.php b/src/pocketmine/item/Banner.php index d5ddb5e39c..57a1c0d521 100644 --- a/src/pocketmine/item/Banner.php +++ b/src/pocketmine/item/Banner.php @@ -55,7 +55,7 @@ class Banner extends Item{ * @return int */ public function getBaseColor() : int{ - return $this->getNamedTag()->getInt(self::TAG_BASE, 0); + return $this->getNamedTag()->getInt(self::TAG_BASE, $this->getDamage()); } /** From 4a629e1a26a839f177940137efa0b85cc7f99d6b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 1 Jan 2019 15:43:05 +0000 Subject: [PATCH 0355/3224] DataPacket: remove dead function clean() --- .../network/mcpe/protocol/CraftingDataPacket.php | 6 ------ .../network/mcpe/protocol/CraftingEventPacket.php | 6 ------ src/pocketmine/network/mcpe/protocol/DataPacket.php | 7 ------- src/pocketmine/network/mcpe/protocol/ExplodePacket.php | 5 ----- src/pocketmine/network/mcpe/protocol/PlayerListPacket.php | 5 ----- 5 files changed, 29 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php b/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php index 08fac729fe..23b51838db 100644 --- a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php @@ -52,12 +52,6 @@ class CraftingDataPacket extends DataPacket{ public $decodedEntries = []; - public function clean(){ - $this->entries = []; - $this->decodedEntries = []; - return parent::clean(); - } - protected function decodePayload() : void{ $this->decodedEntries = []; $recipeCount = $this->getUnsignedVarInt(); diff --git a/src/pocketmine/network/mcpe/protocol/CraftingEventPacket.php b/src/pocketmine/network/mcpe/protocol/CraftingEventPacket.php index 7b6332f15f..acb196197c 100644 --- a/src/pocketmine/network/mcpe/protocol/CraftingEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CraftingEventPacket.php @@ -43,12 +43,6 @@ class CraftingEventPacket extends DataPacket{ /** @var Item[] */ public $output = []; - public function clean(){ - $this->input = []; - $this->output = []; - return parent::clean(); - } - protected function decodePayload() : void{ $this->windowId = $this->getByte(); $this->type = $this->getVarInt(); diff --git a/src/pocketmine/network/mcpe/protocol/DataPacket.php b/src/pocketmine/network/mcpe/protocol/DataPacket.php index 0482bb5a67..18c1e37156 100644 --- a/src/pocketmine/network/mcpe/protocol/DataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/DataPacket.php @@ -115,13 +115,6 @@ abstract class DataPacket extends NetworkBinaryStream{ */ abstract public function handle(SessionHandler $handler) : bool; - public function clean(){ - $this->buffer = null; - $this->isEncoded = false; - $this->offset = 0; - return $this; - } - public function __debugInfo(){ $data = []; foreach($this as $k => $v){ diff --git a/src/pocketmine/network/mcpe/protocol/ExplodePacket.php b/src/pocketmine/network/mcpe/protocol/ExplodePacket.php index 3ac3cbbd7b..b85268e266 100644 --- a/src/pocketmine/network/mcpe/protocol/ExplodePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ExplodePacket.php @@ -39,11 +39,6 @@ class ExplodePacket extends DataPacket{ /** @var Vector3[] */ public $records = []; - public function clean(){ - $this->records = []; - return parent::clean(); - } - protected function decodePayload() : void{ $this->position = $this->getVector3(); $this->radius = (float) ($this->getVarInt() / 32); diff --git a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php index bce69bf628..d44a5ec80a 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php @@ -41,11 +41,6 @@ class PlayerListPacket extends DataPacket{ /** @var int */ public $type; - public function clean(){ - $this->entries = []; - return parent::clean(); - } - protected function decodePayload() : void{ $this->type = $this->getByte(); $count = $this->getUnsignedVarInt(); From f81bbd60e8963bd2654a4f181158f403e063cf8c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 1 Jan 2019 16:42:14 +0000 Subject: [PATCH 0356/3224] Avoid use of internal fields in BinaryStream --- composer.lock | 12 ++++++------ src/pocketmine/Server.php | 9 +++++---- src/pocketmine/inventory/CraftingManager.php | 2 +- src/pocketmine/network/mcpe/ChunkRequestTask.php | 2 +- src/pocketmine/network/mcpe/CompressBatchTask.php | 6 +++--- src/pocketmine/network/mcpe/NetworkSession.php | 4 ++-- src/pocketmine/network/mcpe/PacketStream.php | 2 +- src/pocketmine/network/mcpe/protocol/DataPacket.php | 2 +- .../network/mcpe/protocol/StartGamePacket.php | 2 +- 9 files changed, 21 insertions(+), 20 deletions(-) diff --git a/composer.lock b/composer.lock index afd6b5d1f1..df46acfb49 100644 --- a/composer.lock +++ b/composer.lock @@ -233,16 +233,16 @@ }, { "name": "pocketmine/binaryutils", - "version": "0.1.3", + "version": "0.1.4", "source": { "type": "git", "url": "https://github.com/pmmp/BinaryUtils.git", - "reference": "925001c8eff97a36519b16bbd095964b0fc52772" + "reference": "8c559e8c437aa56143e1a9231debf734b4de481c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/925001c8eff97a36519b16bbd095964b0fc52772", - "reference": "925001c8eff97a36519b16bbd095964b0fc52772", + "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/8c559e8c437aa56143e1a9231debf734b4de481c", + "reference": "8c559e8c437aa56143e1a9231debf734b4de481c", "shasum": "" }, "require": { @@ -260,10 +260,10 @@ ], "description": "Classes and methods for conveniently handling binary data", "support": { - "source": "https://github.com/pmmp/BinaryUtils/tree/0.1.3", + "source": "https://github.com/pmmp/BinaryUtils/tree/master", "issues": "https://github.com/pmmp/BinaryUtils/issues" }, - "time": "2018-12-30T12:17:51+00:00" + "time": "2019-01-01T15:58:16+00:00" }, { "name": "pocketmine/math", diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 0e829841f9..a3e43be233 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1900,7 +1900,7 @@ class Server{ $stream->putPacket($packet); } - if(NetworkCompression::$THRESHOLD < 0 or strlen($stream->buffer) < NetworkCompression::$THRESHOLD){ + if(NetworkCompression::$THRESHOLD < 0 or strlen($stream->getBuffer()) < NetworkCompression::$THRESHOLD){ foreach($targets as $target){ foreach($ev->getPackets() as $pk){ $target->addToSendBuffer($pk); @@ -1929,17 +1929,18 @@ class Server{ Timings::$playerNetworkSendCompressTimer->startTiming(); $compressionLevel = NetworkCompression::$LEVEL; - if(NetworkCompression::$THRESHOLD < 0 or strlen($stream->buffer) < NetworkCompression::$THRESHOLD){ + $buffer = $stream->getBuffer(); + if(NetworkCompression::$THRESHOLD < 0 or strlen($buffer) < NetworkCompression::$THRESHOLD){ $compressionLevel = 0; //Do not compress packets under the threshold $forceSync = true; } $promise = new CompressBatchPromise(); if(!$forceSync and $this->networkCompressionAsync){ - $task = new CompressBatchTask($stream, $compressionLevel, $promise); + $task = new CompressBatchTask($buffer, $compressionLevel, $promise); $this->asyncPool->submitTask($task); }else{ - $promise->resolve(NetworkCompression::compress($stream->buffer, $compressionLevel)); + $promise->resolve(NetworkCompression::compress($buffer, $compressionLevel)); } return $promise; diff --git a/src/pocketmine/inventory/CraftingManager.php b/src/pocketmine/inventory/CraftingManager.php index f8aa119c4a..976b25ffea 100644 --- a/src/pocketmine/inventory/CraftingManager.php +++ b/src/pocketmine/inventory/CraftingManager.php @@ -105,7 +105,7 @@ class CraftingManager{ $batch->putPacket($pk); $this->craftingDataCache = new CompressBatchPromise(); - $this->craftingDataCache->resolve(NetworkCompression::compress($batch->buffer)); + $this->craftingDataCache->resolve(NetworkCompression::compress($batch->getBuffer())); Timings::$craftingDataCacheRebuildTimer->stopTiming(); } diff --git a/src/pocketmine/network/mcpe/ChunkRequestTask.php b/src/pocketmine/network/mcpe/ChunkRequestTask.php index 82141f4807..4053dd6c5a 100644 --- a/src/pocketmine/network/mcpe/ChunkRequestTask.php +++ b/src/pocketmine/network/mcpe/ChunkRequestTask.php @@ -56,7 +56,7 @@ class ChunkRequestTask extends AsyncTask{ $stream = new PacketStream(); $stream->putPacket($pk); - $this->setResult(NetworkCompression::compress($stream->buffer, $this->compressionLevel)); + $this->setResult(NetworkCompression::compress($stream->getBuffer(), $this->compressionLevel)); } public function onCompletion() : void{ diff --git a/src/pocketmine/network/mcpe/CompressBatchTask.php b/src/pocketmine/network/mcpe/CompressBatchTask.php index ffd8048a7e..41498ec9b6 100644 --- a/src/pocketmine/network/mcpe/CompressBatchTask.php +++ b/src/pocketmine/network/mcpe/CompressBatchTask.php @@ -31,12 +31,12 @@ class CompressBatchTask extends AsyncTask{ private $data; /** - * @param PacketStream $stream + * @param string $data * @param int $compressionLevel * @param CompressBatchPromise $promise */ - public function __construct(PacketStream $stream, int $compressionLevel, CompressBatchPromise $promise){ - $this->data = $stream->buffer; + public function __construct(string $data, int $compressionLevel, CompressBatchPromise $promise){ + $this->data = $data; $this->level = $compressionLevel; $this->storeLocal($promise); } diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index fd7a78a341..c0854520a3 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -198,14 +198,14 @@ class NetworkSession{ $packet->decode(); if(!$packet->feof() and !$packet->mayHaveUnreadBytes()){ - $remains = substr($packet->buffer, $packet->offset); + $remains = substr($packet->getBuffer(), $packet->getOffset()); $this->server->getLogger()->debug("Still " . strlen($remains) . " bytes unread in " . $packet->getName() . ": 0x" . bin2hex($remains)); } $ev = new DataPacketReceiveEvent($this->player, $packet); $ev->call(); if(!$ev->isCancelled() and !$packet->handle($this->handler)){ - $this->server->getLogger()->debug("Unhandled " . $packet->getName() . " received from " . $this->player->getName() . ": 0x" . bin2hex($packet->buffer)); + $this->server->getLogger()->debug("Unhandled " . $packet->getName() . " received from " . $this->player->getName() . ": 0x" . bin2hex($packet->getBuffer())); } $timings->stopTiming(); diff --git a/src/pocketmine/network/mcpe/PacketStream.php b/src/pocketmine/network/mcpe/PacketStream.php index 9a0f4e9778..f22dc6e200 100644 --- a/src/pocketmine/network/mcpe/PacketStream.php +++ b/src/pocketmine/network/mcpe/PacketStream.php @@ -32,7 +32,7 @@ class PacketStream extends NetworkBinaryStream{ if(!$packet->isEncoded){ $packet->encode(); } - $this->putString($packet->buffer); + $this->putString($packet->getBuffer()); } public function getPacket() : DataPacket{ diff --git a/src/pocketmine/network/mcpe/protocol/DataPacket.php b/src/pocketmine/network/mcpe/protocol/DataPacket.php index 18c1e37156..a21de3fb1c 100644 --- a/src/pocketmine/network/mcpe/protocol/DataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/DataPacket.php @@ -62,7 +62,7 @@ abstract class DataPacket extends NetworkBinaryStream{ } public function decode() : void{ - $this->offset = 0; + $this->rewind(); $this->decodeHeader(); $this->decodePayload(); } diff --git a/src/pocketmine/network/mcpe/protocol/StartGamePacket.php b/src/pocketmine/network/mcpe/protocol/StartGamePacket.php index 3a612e2543..1d438a2b5f 100644 --- a/src/pocketmine/network/mcpe/protocol/StartGamePacket.php +++ b/src/pocketmine/network/mcpe/protocol/StartGamePacket.php @@ -262,7 +262,7 @@ class StartGamePacket extends DataPacket{ $stream->putString($v["name"]); $stream->putLShort($v["data"]); } - self::$runtimeIdTable = $stream->buffer; + self::$runtimeIdTable = $stream->getBuffer(); } $this->put(self::$runtimeIdTable); From 171be946c64dedff096566cdc9dd9c70f8cff234 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 1 Jan 2019 20:53:33 +0000 Subject: [PATCH 0357/3224] Network: burn some deprecated stuff --- .../server/NetworkInterfaceCrashEvent.php | 49 ------------------- src/pocketmine/network/NetworkInterface.php | 7 --- .../network/mcpe/RakLibInterface.php | 5 -- 3 files changed, 61 deletions(-) delete mode 100644 src/pocketmine/event/server/NetworkInterfaceCrashEvent.php diff --git a/src/pocketmine/event/server/NetworkInterfaceCrashEvent.php b/src/pocketmine/event/server/NetworkInterfaceCrashEvent.php deleted file mode 100644 index ecbd9400e0..0000000000 --- a/src/pocketmine/event/server/NetworkInterfaceCrashEvent.php +++ /dev/null @@ -1,49 +0,0 @@ -exception = $throwable; - } - - /** - * @return \Throwable - */ - public function getCrashInformation() : \Throwable{ - return $this->exception; - } -} diff --git a/src/pocketmine/network/NetworkInterface.php b/src/pocketmine/network/NetworkInterface.php index c13b86636f..da64d6f572 100644 --- a/src/pocketmine/network/NetworkInterface.php +++ b/src/pocketmine/network/NetworkInterface.php @@ -69,11 +69,4 @@ interface NetworkInterface{ * Gracefully shuts down the network interface. */ public function shutdown() : void; - - /** - * @deprecated - * Shuts down the network interface in an emergency situation, such as due to a crash. - */ - public function emergencyShutdown() : void; - } diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index b1ff366362..1fd51b72e1 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -121,11 +121,6 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $this->interface->shutdown(); } - public function emergencyShutdown() : void{ - $this->server->getTickSleeper()->removeNotifier($this->sleeper); - $this->interface->emergencyShutdown(); - } - public function openSession(string $identifier, string $address, int $port, int $clientID) : void{ $session = new NetworkSession($this->server, $this, $address, $port); $this->sessions[$identifier] = $session; From 6ad405950a59e8651588f5930e0a3487548f5556 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Thu, 3 Jan 2019 00:01:20 +0000 Subject: [PATCH 0358/3224] Update support.yml --- .github/support.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/support.yml b/.github/support.yml index 1fab0ebccd..608966cb10 100644 --- a/.github/support.yml +++ b/.github/support.yml @@ -5,8 +5,11 @@ supportLabel: "Support request" # Comment to post on issues marked as support requests. Add a link # to a support page, or set to `false` to disable supportComment: > - Thanks, but this issue tracker is intended for bugs reports only, not for support requests. Please use the [forums](https://forums.pmmp.io) for support requests. - Please read the guidelines on [submitting an issue](https://github.com/pmmp/PocketMine-MP/blob/master/CONTRIBUTING.md#creating-an-issue) before opening any further issues. + Thanks, but this issue tracker not intended for support requests. Please read the guidelines on [submitting an issue](https://github.com/pmmp/PocketMine-MP/blob/master/CONTRIBUTING.md#creating-an-issue). + + + [Docs](https://pmmp.rtfd.io) | [Discord](https://discord.gg/bge7dYQ) | [Forums](https://forums.pmmp.io) + # Whether to close issues marked as support requests close: true # Whether to lock issues marked as support requests From 5806ce9205633e2a68c3c51cc0d57ededebc5b16 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Thu, 3 Jan 2019 16:32:21 +0000 Subject: [PATCH 0359/3224] add a Crash issue template valid crashdumps are usually self explanatory and include all required information like OS/version/etc, so there's no need to force reporters to rewrite a bunch of extra information that should already be in the crashdump. --- .github/ISSUE_TEMPLATE/bug_report.md | 3 +++ .github/ISSUE_TEMPLATE/crash.md | 15 +++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/crash.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 590a70dace..83b9270c87 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,6 +1,9 @@ --- name: Bug report about: Report a bug in PocketMine-MP (not plugins) +title: '' +labels: '' +assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/crash.md b/.github/ISSUE_TEMPLATE/crash.md new file mode 100644 index 0000000000..7bcf5f4c29 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/crash.md @@ -0,0 +1,15 @@ +--- +name: Crash +about: Report a crash in PocketMine-MP (not plugins) +title: Server crashed +labels: '' +assignees: '' + +--- + + + +Link to crashdump: + + +### Additional comments (optional) From 134956ac58f3fc3652d726c9f885c57cbecbaaee Mon Sep 17 00:00:00 2001 From: Dylan T Date: Thu, 3 Jan 2019 16:37:48 +0000 Subject: [PATCH 0360/3224] Add a Support issue template maybe this will guide people who don't read into shooting themselves in the foot automatically >:) --- .github/ISSUE_TEMPLATE/help---support.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/help---support.md diff --git a/.github/ISSUE_TEMPLATE/help---support.md b/.github/ISSUE_TEMPLATE/help---support.md new file mode 100644 index 0000000000..7c370b2d3a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/help---support.md @@ -0,0 +1,14 @@ +--- +name: Help & support +about: Help & support +title: '' +labels: Support request +assignees: '' + +--- + +We don't accept support requests on the issue tracker. Please try the following links instead: + +Documentation: http://pmmp.rtfd.io +Forums: https://forums.pmmp.io +Discord: https://discord.gg/bge7dYQ From 4d15eb3327c0e551940025fda332a474cb8d09f7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 3 Jan 2019 16:54:42 +0000 Subject: [PATCH 0361/3224] Cleaned up the InventoryTransactionPacket decoding clusterfuck @shoghicp, y u do dis... I almost created a sub-packet architecture to deal with this shit :( This mess really ought to be split into multiple packets. Perhaps the PacketPool can be extended to do that in the future. --- .../mcpe/handler/SimpleSessionHandler.php | 210 ++++++++++-------- .../protocol/InventoryTransactionPacket.php | 118 ++-------- .../types/MismatchTransactionData.php | 48 ++++ .../protocol/types/NetworkInventoryAction.php | 41 ++-- .../protocol/types/NormalTransactionData.php | 53 +++++ .../types/ReleaseItemTransactionData.php | 99 +++++++++ .../mcpe/protocol/types/TransactionData.php | 75 +++++++ .../types/UseItemOnEntityTransactionData.php | 123 ++++++++++ .../protocol/types/UseItemTransactionData.php | 137 ++++++++++++ 9 files changed, 699 insertions(+), 205 deletions(-) create mode 100644 src/pocketmine/network/mcpe/protocol/types/MismatchTransactionData.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/NormalTransactionData.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/ReleaseItemTransactionData.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/TransactionData.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/UseItemOnEntityTransactionData.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/UseItemTransactionData.php diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index 35b4636458..c86362a174 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -63,6 +63,11 @@ use pocketmine\network\mcpe\protocol\ShowCreditsPacket; use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket; use pocketmine\network\mcpe\protocol\SubClientLoginPacket; use pocketmine\network\mcpe\protocol\TextPacket; +use pocketmine\network\mcpe\protocol\types\MismatchTransactionData; +use pocketmine\network\mcpe\protocol\types\NormalTransactionData; +use pocketmine\network\mcpe\protocol\types\ReleaseItemTransactionData; +use pocketmine\network\mcpe\protocol\types\UseItemOnEntityTransactionData; +use pocketmine\network\mcpe\protocol\types\UseItemTransactionData; use pocketmine\Player; /** @@ -112,22 +117,52 @@ class SimpleSessionHandler extends SessionHandler{ return true; } + $result = true; + + if($packet->trData instanceof NormalTransactionData){ + $result = $this->handleNormalTransaction($packet->trData); + }elseif($packet->trData instanceof MismatchTransactionData){ + $this->player->sendAllInventories(); + $result = true; + }elseif($packet->trData instanceof UseItemTransactionData){ + $result = $this->handleUseItemTransaction($packet->trData); + }elseif($packet->trData instanceof UseItemOnEntityTransactionData){ + $result = $this->handleUseItemOnEntityTransaction($packet->trData); + }elseif($packet->trData instanceof ReleaseItemTransactionData){ + $result = $this->handleReleaseItemTransaction($packet->trData); + } + + if(!$result){ + $this->player->sendAllInventories(); + } + return $result; + } + + private function handleNormalTransaction(NormalTransactionData $data) : bool{ /** @var InventoryAction[] $actions */ $actions = []; - foreach($packet->actions as $networkInventoryAction){ + + $isCrafting = false; + $isFinalCraftingPart = false; + foreach($data->getActions() as $networkInventoryAction){ + $isCrafting = $isCrafting || $networkInventoryAction->isCraftingPart(); + $isFinalCraftingPart = $isFinalCraftingPart || $networkInventoryAction->isFinalCraftingPart(); + try{ $action = $networkInventoryAction->createInventoryAction($this->player); if($action !== null){ $actions[] = $action; } - }catch(\Exception $e){ + }catch(\UnexpectedValueException $e){ $this->player->getServer()->getLogger()->debug("Unhandled inventory action from " . $this->player->getName() . ": " . $e->getMessage()); - $this->player->sendAllInventories(); return false; } } - if($packet->isCraftingPart){ + if($isCrafting){ + //we get the actions for this in several packets, so we need to wait until we have all the pieces before + //trying to execute it + if($this->craftingTransaction === null){ $this->craftingTransaction = new CraftingTransaction($this->player, $actions); }else{ @@ -136,113 +171,98 @@ class SimpleSessionHandler extends SessionHandler{ } } - if($packet->isFinalCraftingPart){ - //we get the actions for this in several packets, so we need to wait until we have all the pieces before - //trying to execute it - - $ret = true; + if($isFinalCraftingPart){ try{ $this->craftingTransaction->execute(); }catch(TransactionValidationException $e){ $this->player->getServer()->getLogger()->debug("Failed to execute crafting transaction for " . $this->player->getName() . ": " . $e->getMessage()); - $ret = false; + return false; + }finally{ + $this->craftingTransaction = null; } - + } + }else{ + //normal transaction fallthru + if($this->craftingTransaction !== null){ + $this->player->getServer()->getLogger()->debug("Got unexpected normal inventory action with incomplete crafting transaction from " . $this->player->getName() . ", refusing to execute crafting"); $this->craftingTransaction = null; - return $ret; + return false; } - return true; - } - if($this->craftingTransaction !== null){ - $this->player->getServer()->getLogger()->debug("Got unexpected normal inventory action with incomplete crafting transaction from " . $this->player->getName() . ", refusing to execute crafting"); - $this->craftingTransaction = null; + $transaction = new InventoryTransaction($this->player, $actions); + try{ + $transaction->execute(); + }catch(TransactionValidationException $e){ + $logger = $this->player->getServer()->getLogger(); + $logger->debug("Failed to execute inventory transaction from " . $this->player->getName() . ": " . $e->getMessage()); + $logger->debug("Actions: " . json_encode($data->getActions())); + + return false; + } + + //TODO: fix achievement for getting iron from furnace } - switch($packet->transactionType){ - case InventoryTransactionPacket::TYPE_NORMAL: - $transaction = new InventoryTransaction($this->player, $actions); + return true; + } - try{ - $transaction->execute(); - }catch(TransactionValidationException $e){ - $this->player->getServer()->getLogger()->debug("Failed to execute inventory transaction from " . $this->player->getName() . ": " . $e->getMessage()); - $this->player->getServer()->getLogger()->debug("Actions: " . json_encode($packet->actions)); - - return false; + private function handleUseItemTransaction(UseItemTransactionData $data) : bool{ + switch($data->getActionType()){ + case UseItemTransactionData::ACTION_CLICK_BLOCK: + //TODO: start hack for client spam bug + $clickPos = $data->getClickPos(); + $spamBug = ($this->lastRightClickPos !== null and + microtime(true) - $this->lastRightClickTime < 0.1 and //100ms + $this->lastRightClickPos->distanceSquared($clickPos) < 0.00001 //signature spam bug has 0 distance, but allow some error + ); + //get rid of continued spam if the player clicks and holds right-click + $this->lastRightClickPos = clone $clickPos; + $this->lastRightClickTime = microtime(true); + if($spamBug){ + return true; } - - //TODO: fix achievement for getting iron from furnace - + //TODO: end hack for client spam bug + $this->player->interactBlock($data->getBlockPos(), $data->getFace(), $clickPos); return true; - case InventoryTransactionPacket::TYPE_MISMATCH: - if(count($packet->actions) > 0){ - $this->player->getServer()->getLogger()->debug("Expected 0 actions for mismatch, got " . count($packet->actions) . ", " . json_encode($packet->actions)); - } - $this->player->sendAllInventories(); - + case UseItemTransactionData::ACTION_BREAK_BLOCK: + $this->player->breakBlock($data->getBlockPos()); + return true; + case UseItemTransactionData::ACTION_CLICK_AIR: + $this->player->useHeldItem(); + return true; + } + + return false; + } + + private function handleUseItemOnEntityTransaction(UseItemOnEntityTransactionData $data) : bool{ + $target = $this->player->getLevel()->getEntity($data->getEntityRuntimeId()); + if($target === null){ + return false; + } + + switch($data->getActionType()){ + case UseItemOnEntityTransactionData::ACTION_INTERACT: + $this->player->interactEntity($target, $data->getClickPos()); + return true; + case UseItemOnEntityTransactionData::ACTION_ATTACK: + $this->player->attackEntity($target); + return true; + } + + return false; + } + + private function handleReleaseItemTransaction(ReleaseItemTransactionData $data) : bool{ + switch($data->getActionType()){ + case ReleaseItemTransactionData::ACTION_RELEASE: + $this->player->releaseHeldItem(); + return true; + case ReleaseItemTransactionData::ACTION_CONSUME: + $this->player->consumeHeldItem(); return true; - case InventoryTransactionPacket::TYPE_USE_ITEM: - $blockVector = new Vector3($packet->trData->x, $packet->trData->y, $packet->trData->z); - $face = $packet->trData->face; - - $type = $packet->trData->actionType; - switch($type){ - case InventoryTransactionPacket::USE_ITEM_ACTION_CLICK_BLOCK: - //TODO: start hack for client spam bug - $spamBug = ($this->lastRightClickPos !== null and - microtime(true) - $this->lastRightClickTime < 0.1 and //100ms - $this->lastRightClickPos->distanceSquared($packet->trData->clickPos) < 0.00001 //signature spam bug has 0 distance, but allow some error - ); - //get rid of continued spam if the player clicks and holds right-click - $this->lastRightClickPos = clone $packet->trData->clickPos; - $this->lastRightClickTime = microtime(true); - if($spamBug){ - return true; - } - //TODO: end hack for client spam bug - $this->player->interactBlock($blockVector, $face, $packet->trData->clickPos); - return true; - case InventoryTransactionPacket::USE_ITEM_ACTION_BREAK_BLOCK: - $this->player->breakBlock($blockVector); - return true; - case InventoryTransactionPacket::USE_ITEM_ACTION_CLICK_AIR: - $this->player->useHeldItem(); - return true; - } - break; - case InventoryTransactionPacket::TYPE_USE_ITEM_ON_ENTITY: - $target = $this->player->getLevel()->getEntity($packet->trData->entityRuntimeId); - if($target === null){ - return false; - } - - switch($packet->trData->actionType){ - case InventoryTransactionPacket::USE_ITEM_ON_ENTITY_ACTION_INTERACT: - $this->player->interactEntity($target, $packet->trData->clickPos); - return true; - case InventoryTransactionPacket::USE_ITEM_ON_ENTITY_ACTION_ATTACK: - $this->player->attackEntity($target); - return true; - } - - break; - case InventoryTransactionPacket::TYPE_RELEASE_ITEM: - switch($packet->trData->actionType){ - case InventoryTransactionPacket::RELEASE_ITEM_ACTION_RELEASE: - $this->player->releaseHeldItem(); - return true; - case InventoryTransactionPacket::RELEASE_ITEM_ACTION_CONSUME: - $this->player->consumeHeldItem(); - return true; - } - break; - default: - break; - } - $this->player->sendAllInventories(); return false; } diff --git a/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php b/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php index e6f57ac27d..6cdb4c3a30 100644 --- a/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php @@ -26,8 +26,16 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\SessionHandler; -use pocketmine\network\mcpe\protocol\types\NetworkInventoryAction; +use pocketmine\network\mcpe\protocol\types\MismatchTransactionData; +use pocketmine\network\mcpe\protocol\types\NormalTransactionData; +use pocketmine\network\mcpe\protocol\types\ReleaseItemTransactionData; +use pocketmine\network\mcpe\protocol\types\TransactionData; +use pocketmine\network\mcpe\protocol\types\UseItemOnEntityTransactionData; +use pocketmine\network\mcpe\protocol\types\UseItemTransactionData; +/** + * This packet effectively crams multiple packets into one. + */ class InventoryTransactionPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::INVENTORY_TRANSACTION_PACKET; @@ -37,118 +45,38 @@ class InventoryTransactionPacket extends DataPacket{ public const TYPE_USE_ITEM_ON_ENTITY = 3; public const TYPE_RELEASE_ITEM = 4; - public const USE_ITEM_ACTION_CLICK_BLOCK = 0; - public const USE_ITEM_ACTION_CLICK_AIR = 1; - public const USE_ITEM_ACTION_BREAK_BLOCK = 2; - - public const RELEASE_ITEM_ACTION_RELEASE = 0; //bow shoot - public const RELEASE_ITEM_ACTION_CONSUME = 1; //eat food, drink potion - - public const USE_ITEM_ON_ENTITY_ACTION_INTERACT = 0; - public const USE_ITEM_ON_ENTITY_ACTION_ATTACK = 1; - - /** @var int */ - public $transactionType; - - /** - * @var bool - * NOTE: THIS FIELD DOES NOT EXIST IN THE PROTOCOL, it's merely used for convenience for PocketMine-MP to easily - * determine whether we're doing a crafting transaction. - */ - public $isCraftingPart = false; - /** - * @var bool - * NOTE: THIS FIELD DOES NOT EXIST IN THE PROTOCOL, it's merely used for convenience for PocketMine-MP to easily - * determine whether we're doing a crafting transaction. - */ - public $isFinalCraftingPart = false; - - /** @var NetworkInventoryAction[] */ - public $actions = []; - - /** @var \stdClass */ + /** @var TransactionData */ public $trData; protected function decodePayload() : void{ - $this->transactionType = $this->getUnsignedVarInt(); + $transactionType = $this->getUnsignedVarInt(); - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ - $this->actions[] = (new NetworkInventoryAction())->read($this); - } - - $this->trData = new \stdClass(); - - switch($this->transactionType){ + switch($transactionType){ case self::TYPE_NORMAL: + $this->trData = new NormalTransactionData(); + break; case self::TYPE_MISMATCH: - //Regular ComplexInventoryTransaction doesn't read any extra data + $this->trData = new MismatchTransactionData(); break; case self::TYPE_USE_ITEM: - $this->trData->actionType = $this->getUnsignedVarInt(); - $this->getBlockPosition($this->trData->x, $this->trData->y, $this->trData->z); - $this->trData->face = $this->getVarInt(); - $this->trData->hotbarSlot = $this->getVarInt(); - $this->trData->itemInHand = $this->getSlot(); - $this->trData->playerPos = $this->getVector3(); - $this->trData->clickPos = $this->getVector3(); + $this->trData = new UseItemTransactionData(); break; case self::TYPE_USE_ITEM_ON_ENTITY: - $this->trData->entityRuntimeId = $this->getEntityRuntimeId(); - $this->trData->actionType = $this->getUnsignedVarInt(); - $this->trData->hotbarSlot = $this->getVarInt(); - $this->trData->itemInHand = $this->getSlot(); - $this->trData->playerPos = $this->getVector3(); - $this->trData->clickPos = $this->getVector3(); + $this->trData = new UseItemOnEntityTransactionData(); break; case self::TYPE_RELEASE_ITEM: - $this->trData->actionType = $this->getUnsignedVarInt(); - $this->trData->hotbarSlot = $this->getVarInt(); - $this->trData->itemInHand = $this->getSlot(); - $this->trData->headPos = $this->getVector3(); + $this->trData = new ReleaseItemTransactionData(); break; default: - throw new \UnexpectedValueException("Unknown transaction type $this->transactionType"); + throw new \UnexpectedValueException("Unknown transaction type $transactionType"); } + + $this->trData->decode($this); } protected function encodePayload() : void{ - $this->putUnsignedVarInt($this->transactionType); - - $this->putUnsignedVarInt(count($this->actions)); - foreach($this->actions as $action){ - $action->write($this); - } - - switch($this->transactionType){ - case self::TYPE_NORMAL: - case self::TYPE_MISMATCH: - break; - case self::TYPE_USE_ITEM: - $this->putUnsignedVarInt($this->trData->actionType); - $this->putBlockPosition($this->trData->x, $this->trData->y, $this->trData->z); - $this->putVarInt($this->trData->face); - $this->putVarInt($this->trData->hotbarSlot); - $this->putSlot($this->trData->itemInHand); - $this->putVector3($this->trData->playerPos); - $this->putVector3($this->trData->clickPos); - break; - case self::TYPE_USE_ITEM_ON_ENTITY: - $this->putEntityRuntimeId($this->trData->entityRuntimeId); - $this->putUnsignedVarInt($this->trData->actionType); - $this->putVarInt($this->trData->hotbarSlot); - $this->putSlot($this->trData->itemInHand); - $this->putVector3($this->trData->playerPos); - $this->putVector3($this->trData->clickPos); - break; - case self::TYPE_RELEASE_ITEM: - $this->putUnsignedVarInt($this->trData->actionType); - $this->putVarInt($this->trData->hotbarSlot); - $this->putSlot($this->trData->itemInHand); - $this->putVector3($this->trData->headPos); - break; - default: - throw new \UnexpectedValueException("Unknown transaction type $this->transactionType"); - } + $this->putUnsignedVarInt($this->trData->getTypeId()); + $this->trData->encode($this); } public function handle(SessionHandler $handler) : bool{ diff --git a/src/pocketmine/network/mcpe/protocol/types/MismatchTransactionData.php b/src/pocketmine/network/mcpe/protocol/types/MismatchTransactionData.php new file mode 100644 index 0000000000..ad4d039046 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/MismatchTransactionData.php @@ -0,0 +1,48 @@ +actions)){ + throw new \UnexpectedValueException("Mismatch transaction type should not have any actions associated with it, but got " . count($this->actions)); + } + } + + protected function encodeData(NetworkBinaryStream $stream) : void{ + + } + + public static function new() : self{ + return new self; //no arguments + } +} diff --git a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php index 738f6743e4..1c9bae16a1 100644 --- a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php +++ b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php @@ -28,7 +28,7 @@ use pocketmine\inventory\transaction\action\DropItemAction; use pocketmine\inventory\transaction\action\InventoryAction; use pocketmine\inventory\transaction\action\SlotChangeAction; use pocketmine\item\Item; -use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; +use pocketmine\network\mcpe\NetworkBinaryStream; use pocketmine\Player; class NetworkInventoryAction{ @@ -92,11 +92,13 @@ class NetworkInventoryAction{ public $newItem; /** - * @param InventoryTransactionPacket $packet + * @param NetworkBinaryStream $packet * * @return $this + * @throws \UnexpectedValueException + * @throws \OutOfBoundsException */ - public function read(InventoryTransactionPacket $packet) : NetworkInventoryAction{ + public function read(NetworkBinaryStream $packet) : NetworkInventoryAction{ $this->sourceType = $packet->getUnsignedVarInt(); switch($this->sourceType){ @@ -111,14 +113,6 @@ class NetworkInventoryAction{ case self::SOURCE_CRAFTING_GRID: case self::SOURCE_TODO: $this->windowId = $packet->getVarInt(); - switch($this->windowId){ - /** @noinspection PhpMissingBreakStatementInspection */ - case self::SOURCE_TYPE_CRAFTING_RESULT: - $packet->isFinalCraftingPart = true; - case self::SOURCE_TYPE_CRAFTING_USE_INGREDIENT: - $packet->isCraftingPart = true; - break; - } break; default: throw new \UnexpectedValueException("Unknown inventory action source type $this->sourceType"); @@ -132,9 +126,11 @@ class NetworkInventoryAction{ } /** - * @param InventoryTransactionPacket $packet + * @param NetworkBinaryStream $packet + * + * @throws \InvalidArgumentException */ - public function write(InventoryTransactionPacket $packet) : void{ + public function write(NetworkBinaryStream $packet) : void{ $packet->putUnsignedVarInt($this->sourceType); switch($this->sourceType){ @@ -151,7 +147,7 @@ class NetworkInventoryAction{ $packet->putVarInt($this->windowId); break; default: - throw new \UnexpectedValueException("Unknown inventory action source type $this->sourceType"); + throw new \InvalidArgumentException("Unknown inventory action source type $this->sourceType"); } $packet->putUnsignedVarInt($this->inventorySlot); @@ -163,6 +159,7 @@ class NetworkInventoryAction{ * @param Player $player * * @return InventoryAction|null + * @throws \UnexpectedValueException */ public function createInventoryAction(Player $player) : ?InventoryAction{ switch($this->sourceType){ @@ -172,7 +169,7 @@ class NetworkInventoryAction{ return new SlotChangeAction($window, $this->inventorySlot, $this->oldItem, $this->newItem); } - throw new \InvalidStateException("Player " . $player->getName() . " has no open container with window ID $this->windowId"); + throw new \UnexpectedValueException("Player " . $player->getName() . " has no open container with window ID $this->windowId"); case self::SOURCE_WORLD: if($this->inventorySlot !== self::ACTION_MAGIC_SLOT_DROP_ITEM){ throw new \UnexpectedValueException("Only expecting drop-item world actions from the client!"); @@ -212,4 +209,18 @@ class NetworkInventoryAction{ throw new \UnexpectedValueException("Unknown inventory source type $this->sourceType"); } } + + /** + * Hack to allow identifying crafting transaction parts. + * + * @return bool + */ + public function isCraftingPart() : bool{ + return ($this->sourceType === self::SOURCE_TODO or $this->sourceType === self::SOURCE_CRAFTING_GRID) and + ($this->windowId === self::SOURCE_TYPE_CRAFTING_RESULT or $this->windowId === self::SOURCE_TYPE_CRAFTING_USE_INGREDIENT); + } + + public function isFinalCraftingPart() : bool{ + return $this->isCraftingPart() and $this->windowId === self::SOURCE_TYPE_CRAFTING_RESULT; + } } diff --git a/src/pocketmine/network/mcpe/protocol/types/NormalTransactionData.php b/src/pocketmine/network/mcpe/protocol/types/NormalTransactionData.php new file mode 100644 index 0000000000..500c80d912 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/NormalTransactionData.php @@ -0,0 +1,53 @@ +actions = $actions; + return $result; + } +} diff --git a/src/pocketmine/network/mcpe/protocol/types/ReleaseItemTransactionData.php b/src/pocketmine/network/mcpe/protocol/types/ReleaseItemTransactionData.php new file mode 100644 index 0000000000..471801a839 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/ReleaseItemTransactionData.php @@ -0,0 +1,99 @@ +actionType; + } + + /** + * @return int + */ + public function getHotbarSlot() : int{ + return $this->hotbarSlot; + } + + /** + * @return Item + */ + public function getItemInHand() : Item{ + return $this->itemInHand; + } + + /** + * @return Vector3 + */ + public function getHeadPos() : Vector3{ + return $this->headPos; + } + + public function getTypeId() : int{ + return InventoryTransactionPacket::TYPE_RELEASE_ITEM; + } + + protected function decodeData(NetworkBinaryStream $stream) : void{ + $this->actionType = $stream->getUnsignedVarInt(); + $this->hotbarSlot = $stream->getVarInt(); + $this->itemInHand = $stream->getSlot(); + $this->headPos = $stream->getVector3(); + } + + protected function encodeData(NetworkBinaryStream $stream) : void{ + $stream->putUnsignedVarInt($this->actionType); + $stream->putVarInt($this->hotbarSlot); + $stream->putSlot($this->itemInHand); + $stream->putVector3($this->headPos); + } + + public static function new(array $actions, int $actionType, int $hotbarSlot, Item $itemInHand, Vector3 $headPos) : self{ + $result = new self; + $result->actions = $actions; + $result->actionType = $actionType; + $result->hotbarSlot = $hotbarSlot; + $result->itemInHand = $itemInHand; + $result->headPos = $headPos; + return $result; + } +} diff --git a/src/pocketmine/network/mcpe/protocol/types/TransactionData.php b/src/pocketmine/network/mcpe/protocol/types/TransactionData.php new file mode 100644 index 0000000000..115757d1ef --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/TransactionData.php @@ -0,0 +1,75 @@ +actions; + } + + /** + * @return int + */ + abstract public function getTypeId() : int; + + /** + * @param NetworkBinaryStream $stream + * + * @throws \OutOfBoundsException + * @throws \UnexpectedValueException + */ + final public function decode(NetworkBinaryStream $stream) : void{ + $actionCount = $stream->getUnsignedVarInt(); + for($i = 0; $i < $actionCount; ++$i){ + $this->actions[] = (new NetworkInventoryAction())->read($stream); + } + $this->decodeData($stream); + } + + /** + * @param NetworkBinaryStream $stream + * + * @throws \OutOfBoundsException + * @throws \UnexpectedValueException + */ + abstract protected function decodeData(NetworkBinaryStream $stream) : void; + + final public function encode(NetworkBinaryStream $stream) : void{ + $stream->putUnsignedVarInt(count($this->actions)); + foreach($this->actions as $action){ + $action->write($stream); + } + $this->encodeData($stream); + } + + abstract protected function encodeData(NetworkBinaryStream $stream) : void; +} diff --git a/src/pocketmine/network/mcpe/protocol/types/UseItemOnEntityTransactionData.php b/src/pocketmine/network/mcpe/protocol/types/UseItemOnEntityTransactionData.php new file mode 100644 index 0000000000..560a5eb5e2 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/UseItemOnEntityTransactionData.php @@ -0,0 +1,123 @@ +entityRuntimeId; + } + + /** + * @return int + */ + public function getActionType() : int{ + return $this->actionType; + } + + /** + * @return int + */ + public function getHotbarSlot() : int{ + return $this->hotbarSlot; + } + + /** + * @return Item + */ + public function getItemInHand() : Item{ + return $this->itemInHand; + } + + /** + * @return Vector3 + */ + public function getPlayerPos() : Vector3{ + return $this->playerPos; + } + + /** + * @return Vector3 + */ + public function getClickPos() : Vector3{ + return $this->clickPos; + } + + public function getTypeId() : int{ + return InventoryTransactionPacket::TYPE_USE_ITEM_ON_ENTITY; + } + + protected function decodeData(NetworkBinaryStream $stream) : void{ + $this->entityRuntimeId = $stream->getEntityRuntimeId(); + $this->actionType = $stream->getUnsignedVarInt(); + $this->hotbarSlot = $stream->getVarInt(); + $this->itemInHand = $stream->getSlot(); + $this->playerPos = $stream->getVector3(); + $this->clickPos = $stream->getVector3(); + } + + protected function encodeData(NetworkBinaryStream $stream) : void{ + $stream->putEntityRuntimeId($this->entityRuntimeId); + $stream->putUnsignedVarInt($this->actionType); + $stream->putVarInt($this->hotbarSlot); + $stream->putSlot($this->itemInHand); + $stream->putVector3($this->playerPos); + $stream->putVector3($this->clickPos); + } + + public static function new(array $actions, int $entityRuntimeId, int $actionType, int $hotbarSlot, Item $itemInHand, Vector3 $playerPos, Vector3 $clickPos) : self{ + $result = new self; + $result->actions = $actions; + $result->entityRuntimeId = $entityRuntimeId; + $result->actionType = $actionType; + $result->hotbarSlot = $hotbarSlot; + $result->itemInHand = $itemInHand; + $result->playerPos = $playerPos; + $result->clickPos = $clickPos; + return $result; + } +} diff --git a/src/pocketmine/network/mcpe/protocol/types/UseItemTransactionData.php b/src/pocketmine/network/mcpe/protocol/types/UseItemTransactionData.php new file mode 100644 index 0000000000..141b90a829 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/UseItemTransactionData.php @@ -0,0 +1,137 @@ +actionType; + } + + /** + * @return Vector3 + */ + public function getBlockPos() : Vector3{ + return $this->blockPos; + } + + /** + * @return int + */ + public function getFace() : int{ + return $this->face; + } + + /** + * @return int + */ + public function getHotbarSlot() : int{ + return $this->hotbarSlot; + } + + /** + * @return Item + */ + public function getItemInHand() : Item{ + return $this->itemInHand; + } + + /** + * @return Vector3 + */ + public function getPlayerPos() : Vector3{ + return $this->playerPos; + } + + /** + * @return Vector3 + */ + public function getClickPos() : Vector3{ + return $this->clickPos; + } + + public function getTypeId() : int{ + return InventoryTransactionPacket::TYPE_USE_ITEM; + } + + protected function decodeData(NetworkBinaryStream $stream) : void{ + $this->actionType = $stream->getUnsignedVarInt(); + $this->blockPos = new Vector3(); + $stream->getBlockPosition($this->blockPos->x, $this->blockPos->y, $this->blockPos->z); + $this->face = $stream->getVarInt(); + $this->hotbarSlot = $stream->getVarInt(); + $this->itemInHand = $stream->getSlot(); + $this->playerPos = $stream->getVector3(); + $this->clickPos = $stream->getVector3(); + } + + protected function encodeData(NetworkBinaryStream $stream) : void{ + $stream->putUnsignedVarInt($this->actionType); + $stream->putBlockPosition($this->blockPos->x, $this->blockPos->y, $this->blockPos->z); + $stream->putVarInt($this->face); + $stream->putVarInt($this->hotbarSlot); + $stream->putSlot($this->itemInHand); + $stream->putVector3($this->playerPos); + $stream->putVector3($this->clickPos); + } + + public static function new(array $actions, int $actionType, Vector3 $blockPos, int $face, int $hotbarSlot, Item $itemInHand, Vector3 $playerPos, Vector3 $clickPos) : self{ + $result = new self; + $result->actions = $actions; + $result->actionType = $actionType; + $result->blockPos = $blockPos; + $result->face = $face; + $result->hotbarSlot = $hotbarSlot; + $result->itemInHand = $itemInHand; + $result->playerPos = $playerPos; + $result->clickPos = $clickPos; + return $result; + } +} From c559dfccfefc60e35a0ed20683d38558df2c5c9e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 3 Jan 2019 21:14:54 +0000 Subject: [PATCH 0362/3224] DataPacket: encode() and decode() are now final, encodePayload() and decodePayload() are now abstract --- .../network/mcpe/protocol/DataPacket.php | 16 ++++++---------- .../network/mcpe/protocol/UnknownPacket.php | 13 ++++++++++--- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/DataPacket.php b/src/pocketmine/network/mcpe/protocol/DataPacket.php index 0eeb9abe8a..344ed5a5f0 100644 --- a/src/pocketmine/network/mcpe/protocol/DataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/DataPacket.php @@ -65,7 +65,7 @@ abstract class DataPacket extends NetworkBinaryStream{ * @throws \OutOfBoundsException * @throws \UnexpectedValueException */ - public function decode() : void{ + final public function decode() : void{ $this->rewind(); $this->decodeHeader(); $this->decodePayload(); @@ -83,16 +83,14 @@ abstract class DataPacket extends NetworkBinaryStream{ } /** - * Note for plugin developers: If you're adding your own packets, you should perform decoding in here. + * Decodes the packet body, without the packet ID or other generic header fields. * * @throws \OutOfBoundsException * @throws \UnexpectedValueException */ - protected function decodePayload() : void{ + abstract protected function decodePayload() : void; - } - - public function encode() : void{ + final public function encode() : void{ $this->reset(); $this->encodeHeader(); $this->encodePayload(); @@ -104,11 +102,9 @@ abstract class DataPacket extends NetworkBinaryStream{ } /** - * Note for plugin developers: If you're adding your own packets, you should perform encoding in here. + * Encodes the packet body, without the packet ID or other generic header fields. */ - protected function encodePayload() : void{ - - } + abstract protected function encodePayload() : void; /** * Performs handling for this packet. Usually you'll want an appropriately named method in the session handler for diff --git a/src/pocketmine/network/mcpe/protocol/UnknownPacket.php b/src/pocketmine/network/mcpe/protocol/UnknownPacket.php index 6daf12bfb5..f2e5986eb8 100644 --- a/src/pocketmine/network/mcpe/protocol/UnknownPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UnknownPacket.php @@ -44,12 +44,19 @@ class UnknownPacket extends DataPacket{ return "unknown packet"; } - public function decode() : void{ + protected function decodeHeader() : void{ + + } + + protected function decodePayload() : void{ $this->payload = $this->getRemaining(); } - public function encode() : void{ - //Do not reset the buffer, this class does not have a valid NETWORK_ID constant. + protected function encodeHeader() : void{ + + } + + protected function encodePayload() : void{ $this->put($this->payload); } From 8ef15d728a2b96954ed88791ca3681b61a6ced40 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 3 Jan 2019 22:36:31 +0000 Subject: [PATCH 0363/3224] HandshakeSessionHandler: fix a doc comment bug thank you PHPStan :heart: --- src/pocketmine/network/mcpe/handler/HandshakeSessionHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/handler/HandshakeSessionHandler.php b/src/pocketmine/network/mcpe/handler/HandshakeSessionHandler.php index 50a39557b4..8c2cb2be71 100644 --- a/src/pocketmine/network/mcpe/handler/HandshakeSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/HandshakeSessionHandler.php @@ -31,7 +31,7 @@ use pocketmine\network\mcpe\protocol\ClientToServerHandshakePacket; */ class HandshakeSessionHandler extends SessionHandler{ - /** @var string */ + /** @var NetworkSession */ private $session; public function __construct(NetworkSession $session){ From 7a4e2371e6d558458a70c2ef9eaf704bde49a096 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 4 Jan 2019 00:40:09 +0000 Subject: [PATCH 0364/3224] master-specific PHPStan nits --- src/pocketmine/event/player/PlayerInteractEvent.php | 2 +- src/pocketmine/level/format/io/LevelData.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/event/player/PlayerInteractEvent.php b/src/pocketmine/event/player/PlayerInteractEvent.php index 96b37937f7..1d82d124ab 100644 --- a/src/pocketmine/event/player/PlayerInteractEvent.php +++ b/src/pocketmine/event/player/PlayerInteractEvent.php @@ -54,7 +54,7 @@ class PlayerInteractEvent extends PlayerEvent implements Cancellable{ /** * @param Player $player * @param Item $item - * @param Block|null $block + * @param Block $block * @param Vector3|null $touchVector * @param int $face * @param int $action diff --git a/src/pocketmine/level/format/io/LevelData.php b/src/pocketmine/level/format/io/LevelData.php index ea08a2c0f0..15b2980e92 100644 --- a/src/pocketmine/level/format/io/LevelData.php +++ b/src/pocketmine/level/format/io/LevelData.php @@ -62,7 +62,7 @@ interface LevelData{ public function getTime() : int; /** - * @param int + * @param int $value */ public function setTime(int $value) : void; From d8d04aeb539516983717db34e7695cdd05a89327 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 4 Jan 2019 23:49:32 +0000 Subject: [PATCH 0365/3224] fixup some imports --- src/pocketmine/Player.php | 4 ++-- src/pocketmine/block/Rail.php | 1 - src/pocketmine/level/generator/object/Tree.php | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index e27b3b7793..c997a09878 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -48,6 +48,7 @@ use pocketmine\event\player\PlayerChangeSkinEvent; use pocketmine\event\player\PlayerChatEvent; use pocketmine\event\player\PlayerCommandPreprocessEvent; use pocketmine\event\player\PlayerDeathEvent; +use pocketmine\event\player\PlayerDuplicateLoginEvent; use pocketmine\event\player\PlayerEditBookEvent; use pocketmine\event\player\PlayerExhaustEvent; use pocketmine\event\player\PlayerGameModeChangeEvent; @@ -59,7 +60,6 @@ use pocketmine\event\player\PlayerJoinEvent; use pocketmine\event\player\PlayerJumpEvent; use pocketmine\event\player\PlayerKickEvent; use pocketmine\event\player\PlayerLoginEvent; -use pocketmine\event\player\PlayerDuplicateLoginEvent; use pocketmine\event\player\PlayerMoveEvent; use pocketmine\event\player\PlayerPreLoginEvent; use pocketmine\event\player\PlayerQuitEvent; @@ -96,6 +96,7 @@ use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\NetworkCipher; use pocketmine\network\mcpe\NetworkLittleEndianNBTStream; use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\ProcessLoginTask; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; @@ -123,7 +124,6 @@ use pocketmine\network\mcpe\protocol\types\CommandParameter; use pocketmine\network\mcpe\protocol\types\ContainerIds; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; -use pocketmine\network\mcpe\ProcessLoginTask; use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissionAttachment; use pocketmine\permission\PermissionAttachmentInfo; diff --git a/src/pocketmine/block/Rail.php b/src/pocketmine/block/Rail.php index 2101cfaf68..cc78c4c40a 100644 --- a/src/pocketmine/block/Rail.php +++ b/src/pocketmine/block/Rail.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\math\Facing; class Rail extends BaseRail{ diff --git a/src/pocketmine/level/generator/object/Tree.php b/src/pocketmine/level/generator/object/Tree.php index 4546fba944..aa6993017a 100644 --- a/src/pocketmine/level/generator/object/Tree.php +++ b/src/pocketmine/level/generator/object/Tree.php @@ -28,7 +28,6 @@ use pocketmine\block\BlockFactory; use pocketmine\block\Leaves; use pocketmine\block\Sapling; use pocketmine\block\utils\WoodType; -use pocketmine\block\Wood; use pocketmine\level\BlockWriteBatch; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; From b1cef8509ab09011de420319e171945018580abe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 6 Jan 2019 23:33:36 +0000 Subject: [PATCH 0366/3224] Revamp Entity construction This is a similar refactor to the one I recently did for tiles. - Entity::createEntity() is removed. In its place are Entity::create() (runtime creation, use where you'd use a constructor, accepts a ::class parameter, throws exceptions on unknown entities) and Entity::createFromData() (internal, used to restore entities from chunks, swallows unknown entities and returns null). - Entity::registerEntity() is renamed to Entity::register(). - Added Entity::override() to allow overriding factory classes without touching save IDs. This allows more cleanly extending & overriding entities. This method only allows overriding registered Entity classes with children of that class, which makes code using the factory much more sane and allows to provide safety guarantees which make the code less nasty. - Entity::getKnownEntityTypes() is renamed to Entity::getKnownTypes(). - ProjectileItem::getProjectileEntityType() now returns a ::class constant instead of a stringy ID. - Cleaned up a bunch of nasty code, particularly in Bow. --- src/pocketmine/block/Fallable.php | 9 +- src/pocketmine/block/TNT.php | 9 +- src/pocketmine/entity/Entity.php | 118 +++++++++++++----- src/pocketmine/item/Bow.php | 93 +++++++------- src/pocketmine/item/Egg.php | 6 +- src/pocketmine/item/EnderPearl.php | 6 +- src/pocketmine/item/ExperienceBottle.php | 6 +- src/pocketmine/item/ItemFactory.php | 6 +- src/pocketmine/item/PaintingItem.php | 16 +-- src/pocketmine/item/ProjectileItem.php | 44 +++---- src/pocketmine/item/Snowball.php | 6 +- src/pocketmine/item/SpawnEgg.php | 31 +++-- src/pocketmine/item/SplashPotion.php | 5 +- src/pocketmine/level/Level.php | 21 ++-- src/pocketmine/level/format/Chunk.php | 9 +- .../level/format/io/leveldb/LevelDB.php | 8 -- 16 files changed, 224 insertions(+), 169 deletions(-) diff --git a/src/pocketmine/block/Fallable.php b/src/pocketmine/block/Fallable.php index b9bc89571b..32dac2a970 100644 --- a/src/pocketmine/block/Fallable.php +++ b/src/pocketmine/block/Fallable.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\entity\Entity; +use pocketmine\entity\object\FallingBlock; use pocketmine\math\Facing; abstract class Fallable extends Solid{ @@ -37,11 +38,9 @@ abstract class Fallable extends Solid{ $nbt->setInt("TileID", $this->getId()); $nbt->setByte("Data", $this->getDamage()); - $fall = Entity::createEntity("FallingSand", $this->getLevel(), $nbt); - - if($fall !== null){ - $fall->spawnToAll(); - } + /** @var FallingBlock $fall */ + $fall = Entity::create(FallingBlock::class, $this->getLevel(), $nbt); + $fall->spawnToAll(); } } diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index e7ed6f6cc5..50b67f4173 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\entity\Entity; +use pocketmine\entity\object\PrimedTNT; use pocketmine\entity\projectile\Arrow; use pocketmine\item\FlintSteel; use pocketmine\item\Item; @@ -77,11 +78,9 @@ class TNT extends Solid{ $nbt = Entity::createBaseNBT($this->add(0.5, 0, 0.5), new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02)); $nbt->setShort("Fuse", $fuse); - $tnt = Entity::createEntity("PrimedTNT", $this->getLevel(), $nbt); - - if($tnt !== null){ - $tnt->spawnToAll(); - } + /** @var PrimedTNT $tnt */ + $tnt = Entity::create(PrimedTNT::class, $this->getLevel(), $nbt); + $tnt->spawnToAll(); } public function getFlameEncouragement() : int{ diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index c5b100779b..136b40bcb3 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -61,6 +61,7 @@ use pocketmine\metadata\MetadataValue; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\FloatTag; +use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\protocol\AddEntityPacket; @@ -77,7 +78,7 @@ use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; use pocketmine\utils\Utils; use function abs; -use function array_unique; +use function array_keys; use function assert; use function cos; use function count; @@ -86,6 +87,7 @@ use function deg2rad; use function floor; use function get_class; use function in_array; +use function is_a; use function is_array; use function is_infinite; use function is_nan; @@ -282,6 +284,8 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ private static $knownEntities = []; /** @var string[][] */ private static $saveNames = []; + /** @var string[] base class => currently used class for construction */ + private static $classMapping = []; /** * Called on server startup to register default entity types. @@ -290,22 +294,22 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ //define legacy save IDs first - use them for saving for maximum compatibility with Minecraft PC //TODO: index them by version to allow proper multi-save compatibility - Entity::registerEntity(Arrow::class, false, ['Arrow', 'minecraft:arrow']); - Entity::registerEntity(Egg::class, false, ['Egg', 'minecraft:egg']); - Entity::registerEntity(EnderPearl::class, false, ['ThrownEnderpearl', 'minecraft:ender_pearl']); - Entity::registerEntity(ExperienceBottle::class, false, ['ThrownExpBottle', 'minecraft:xp_bottle']); - Entity::registerEntity(ExperienceOrb::class, false, ['XPOrb', 'minecraft:xp_orb']); - Entity::registerEntity(FallingBlock::class, false, ['FallingSand', 'minecraft:falling_block']); - Entity::registerEntity(ItemEntity::class, false, ['Item', 'minecraft:item']); - Entity::registerEntity(Painting::class, false, ['Painting', 'minecraft:painting']); - Entity::registerEntity(PrimedTNT::class, false, ['PrimedTnt', 'PrimedTNT', 'minecraft:tnt']); - Entity::registerEntity(Snowball::class, false, ['Snowball', 'minecraft:snowball']); - Entity::registerEntity(SplashPotion::class, false, ['ThrownPotion', 'minecraft:potion', 'thrownpotion']); - Entity::registerEntity(Squid::class, false, ['Squid', 'minecraft:squid']); - Entity::registerEntity(Villager::class, false, ['Villager', 'minecraft:villager']); - Entity::registerEntity(Zombie::class, false, ['Zombie', 'minecraft:zombie']); + self::register(Arrow::class, false, ['Arrow', 'minecraft:arrow']); + self::register(Egg::class, false, ['Egg', 'minecraft:egg']); + self::register(EnderPearl::class, false, ['ThrownEnderpearl', 'minecraft:ender_pearl']); + self::register(ExperienceBottle::class, false, ['ThrownExpBottle', 'minecraft:xp_bottle']); + self::register(ExperienceOrb::class, false, ['XPOrb', 'minecraft:xp_orb']); + self::register(FallingBlock::class, false, ['FallingSand', 'minecraft:falling_block']); + self::register(ItemEntity::class, false, ['Item', 'minecraft:item']); + self::register(Painting::class, false, ['Painting', 'minecraft:painting']); + self::register(PrimedTNT::class, false, ['PrimedTnt', 'PrimedTNT', 'minecraft:tnt']); + self::register(Snowball::class, false, ['Snowball', 'minecraft:snowball']); + self::register(SplashPotion::class, false, ['ThrownPotion', 'minecraft:potion', 'thrownpotion']); + self::register(Squid::class, false, ['Squid', 'minecraft:squid']); + self::register(Villager::class, false, ['Villager', 'minecraft:villager']); + self::register(Zombie::class, false, ['Zombie', 'minecraft:zombie']); - Entity::registerEntity(Human::class, true); + self::register(Human::class, true); Attribute::init(); Effect::init(); @@ -315,23 +319,62 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ /** * Creates an entity with the specified type, level and NBT, with optional additional arguments to pass to the - * entity's constructor + * entity's constructor. * - * @param int|string $type + * TODO: make this NBT-independent + * + * @param string $baseClass * @param Level $level * @param CompoundTag $nbt * @param mixed ...$args * - * @return Entity|null + * @return Entity instanceof $baseClass + * @throws \InvalidArgumentException if the class doesn't exist or is not registered */ - public static function createEntity($type, Level $level, CompoundTag $nbt, ...$args) : ?Entity{ - if(isset(self::$knownEntities[$type])){ - $class = self::$knownEntities[$type]; - /** @see Entity::__construct() */ - return new $class($level, $nbt, ...$args); + public static function create(string $baseClass, Level $level, CompoundTag $nbt, ...$args) : Entity{ + if(isset(self::$classMapping[$baseClass])){ + $class = self::$classMapping[$baseClass]; + assert(is_a($class, $baseClass, true)); + /** + * @var Entity $entity + * @see Entity::__construct() + */ + $entity = new $class($level, $nbt, ...$args); + return $entity; } - return null; + throw new \InvalidArgumentException("Class $baseClass is not a registered entity"); + } + + /** + * Creates an entity from data stored on a chunk. + * @internal + * + * @param Level $level + * @param CompoundTag $nbt + * + * @return Entity|null + * @throws \RuntimeException + */ + public static function createFromData(Level $level, CompoundTag $nbt) : ?Entity{ + $saveId = $nbt->getTag("id"); + $baseClass = null; + if($saveId instanceof StringTag){ + $baseClass = self::$knownEntities[$saveId->getValue()] ?? null; + }elseif($saveId instanceof IntTag){ //legacy MCPE format + $baseClass = self::$knownEntities[$saveId->getValue() & 0xff] ?? null; + } + if($baseClass === null){ + return null; + } + $class = self::$classMapping[$baseClass]; + assert(is_a($class, $baseClass, true)); + /** + * @var Entity $entity + * @see Entity::__construct() + */ + $entity = new $class($level, $nbt); + return $entity; } /** @@ -346,7 +389,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ * * @throws \InvalidArgumentException */ - public static function registerEntity(string $className, bool $force = false, array $saveNames = []) : void{ + public static function register(string $className, bool $force = false, array $saveNames = []) : void{ Utils::testValidInstance($className, Entity::class); /** @var Entity $className */ @@ -355,6 +398,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ }elseif(!$force){ throw new \InvalidArgumentException("Class $className does not declare a valid NETWORK_ID and not force-registering"); } + self::$classMapping[$className] = $className; $shortName = (new \ReflectionClass($className))->getShortName(); if(!in_array($shortName, $saveNames, true)){ @@ -368,13 +412,31 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ self::$saveNames[$className] = $saveNames; } + /** + * Registers a class override for the given class. When a new entity is constructed using the factory, the new class + * will be used instead of the base class. + * + * @param string $baseClass Already-registered entity class to override + * @param string $newClass Class which extends the base class + * + * @throws \InvalidArgumentException + */ + public static function override(string $baseClass, string $newClass) : void{ + if(!isset(self::$classMapping[$baseClass])){ + throw new \InvalidArgumentException("Class $baseClass is not a registered entity"); + } + + Utils::testValidInstance($newClass, $baseClass); + self::$classMapping[$baseClass] = $newClass; + } + /** * Returns an array of all registered entity classpaths. * * @return string[] */ - public static function getKnownEntityTypes() : array{ - return array_unique(self::$knownEntities); + public static function getKnownTypes() : array{ + return array_keys(self::$classMapping); } /** diff --git a/src/pocketmine/item/Bow.php b/src/pocketmine/item/Bow.php index 1e28f60121..5105434a55 100644 --- a/src/pocketmine/item/Bow.php +++ b/src/pocketmine/item/Bow.php @@ -65,61 +65,56 @@ class Bow extends Tool{ $p = $diff / 20; $force = min((($p ** 2) + $p * 2) / 3, 1) * 2; + /** @var ArrowEntity $entity */ + $entity = Entity::create(ArrowEntity::class, $player->getLevel(), $nbt, $player, $force == 2); - $entity = Entity::createEntity("Arrow", $player->getLevel(), $nbt, $player, $force == 2); - if($entity instanceof Projectile){ - $infinity = $this->hasEnchantment(Enchantment::INFINITY); - if($entity instanceof ArrowEntity){ - if($infinity){ - $entity->setPickupMode(ArrowEntity::PICKUP_CREATIVE); - } - if(($punchLevel = $this->getEnchantmentLevel(Enchantment::PUNCH)) > 0){ - $entity->setPunchKnockback($punchLevel); - } - } - if(($powerLevel = $this->getEnchantmentLevel(Enchantment::POWER)) > 0){ - $entity->setBaseDamage($entity->getBaseDamage() + (($powerLevel + 1) / 2)); - } - if($this->hasEnchantment(Enchantment::FLAME)){ - $entity->setOnFire(intdiv($entity->getFireTicks(), 20) + 100); - } - $ev = new EntityShootBowEvent($player, $this, $entity, $force); + $infinity = $this->hasEnchantment(Enchantment::INFINITY); + if($infinity){ + $entity->setPickupMode(ArrowEntity::PICKUP_CREATIVE); + } + if(($punchLevel = $this->getEnchantmentLevel(Enchantment::PUNCH)) > 0){ + $entity->setPunchKnockback($punchLevel); + } + if(($powerLevel = $this->getEnchantmentLevel(Enchantment::POWER)) > 0){ + $entity->setBaseDamage($entity->getBaseDamage() + (($powerLevel + 1) / 2)); + } + if($this->hasEnchantment(Enchantment::FLAME)){ + $entity->setOnFire(intdiv($entity->getFireTicks(), 20) + 100); + } + $ev = new EntityShootBowEvent($player, $this, $entity, $force); - if($force < 0.1 or $diff < 5){ - $ev->setCancelled(); - } + if($force < 0.1 or $diff < 5){ + $ev->setCancelled(); + } - $ev->call(); + $ev->call(); - $entity = $ev->getProjectile(); //This might have been changed by plugins + $entity = $ev->getProjectile(); //This might have been changed by plugins - if($ev->isCancelled()){ - $entity->flagForDespawn(); - $player->getInventory()->sendContents($player); - }else{ - $entity->setMotion($entity->getMotion()->multiply($ev->getForce())); - if($player->isSurvival()){ - if(!$infinity){ //TODO: tipped arrows are still consumed when Infinity is applied - $player->getInventory()->removeItem(ItemFactory::get(Item::ARROW, 0, 1)); - } - $this->applyDamage(1); - } - - if($entity instanceof Projectile){ - $projectileEv = new ProjectileLaunchEvent($entity); - $projectileEv->call(); - if($projectileEv->isCancelled()){ - $ev->getProjectile()->flagForDespawn(); - }else{ - $ev->getProjectile()->spawnToAll(); - $player->getLevel()->broadcastLevelSoundEvent($player, LevelSoundEventPacket::SOUND_BOW); - } - }else{ - $entity->spawnToAll(); - } - } + if($ev->isCancelled()){ + $entity->flagForDespawn(); + $player->getInventory()->sendContents($player); }else{ - $entity->spawnToAll(); + $entity->setMotion($entity->getMotion()->multiply($ev->getForce())); + if($player->isSurvival()){ + if(!$infinity){ //TODO: tipped arrows are still consumed when Infinity is applied + $player->getInventory()->removeItem(ItemFactory::get(Item::ARROW, 0, 1)); + } + $this->applyDamage(1); + } + + if($entity instanceof Projectile){ + $projectileEv = new ProjectileLaunchEvent($entity); + $projectileEv->call(); + if($projectileEv->isCancelled()){ + $ev->getProjectile()->flagForDespawn(); + }else{ + $ev->getProjectile()->spawnToAll(); + $player->getLevel()->broadcastLevelSoundEvent($player, LevelSoundEventPacket::SOUND_BOW); + } + }else{ + $entity->spawnToAll(); + } } return true; diff --git a/src/pocketmine/item/Egg.php b/src/pocketmine/item/Egg.php index 9276342d4a..bf6d15482c 100644 --- a/src/pocketmine/item/Egg.php +++ b/src/pocketmine/item/Egg.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\entity\projectile\Egg as EggEntity; + class Egg extends ProjectileItem{ public function __construct(){ parent::__construct(self::EGG, 0, "Egg"); @@ -32,8 +34,8 @@ class Egg extends ProjectileItem{ return 16; } - public function getProjectileEntityType() : string{ - return "Egg"; + public function getProjectileEntityClass() : string{ + return EggEntity::class; } public function getThrowForce() : float{ diff --git a/src/pocketmine/item/EnderPearl.php b/src/pocketmine/item/EnderPearl.php index 5b375a3915..8417c58064 100644 --- a/src/pocketmine/item/EnderPearl.php +++ b/src/pocketmine/item/EnderPearl.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\entity\projectile\EnderPearl as EnderPearlEntity; + class EnderPearl extends ProjectileItem{ public function __construct(){ parent::__construct(self::ENDER_PEARL, 0, "Ender Pearl"); @@ -32,8 +34,8 @@ class EnderPearl extends ProjectileItem{ return 16; } - public function getProjectileEntityType() : string{ - return "ThrownEnderpearl"; + public function getProjectileEntityClass() : string{ + return EnderPearlEntity::class; } public function getThrowForce() : float{ diff --git a/src/pocketmine/item/ExperienceBottle.php b/src/pocketmine/item/ExperienceBottle.php index 277957ec64..21d07cb42b 100644 --- a/src/pocketmine/item/ExperienceBottle.php +++ b/src/pocketmine/item/ExperienceBottle.php @@ -23,13 +23,15 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\entity\projectile\ExperienceBottle as ExperienceBottleEntity; + class ExperienceBottle extends ProjectileItem{ public function __construct(){ parent::__construct(self::EXPERIENCE_BOTTLE, 0, "Bottle o' Enchanting"); } - public function getProjectileEntityType() : string{ - return "ThrownExpBottle"; + public function getProjectileEntityClass() : string{ + return ExperienceBottleEntity::class; } public function getThrowForce() : float{ diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 63e7134ce7..0fbafa9b77 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -194,10 +194,10 @@ class ItemFactory{ //TODO: ENDER_EYE self::registerItem(new Item(Item::GLISTERING_MELON, 0, "Glistering Melon")); - foreach(Entity::getKnownEntityTypes() as $className){ - /** @var Living $className */ + foreach(Entity::getKnownTypes() as $className){ + /** @var Living|string $className */ if(is_a($className, Living::class, true) and $className::NETWORK_ID !== -1){ - self::registerItem(new SpawnEgg(Item::SPAWN_EGG, $className::NETWORK_ID, "Spawn Egg")); + self::registerItem(new SpawnEgg(Item::SPAWN_EGG, $className::NETWORK_ID, $className, "Spawn Egg")); } } diff --git a/src/pocketmine/item/PaintingItem.php b/src/pocketmine/item/PaintingItem.php index 3224b4923a..69f833031b 100644 --- a/src/pocketmine/item/PaintingItem.php +++ b/src/pocketmine/item/PaintingItem.php @@ -93,16 +93,12 @@ class PaintingItem extends Item{ $nbt->setInt("TileY", $blockClicked->getFloorY()); $nbt->setInt("TileZ", $blockClicked->getFloorZ()); - $entity = Entity::createEntity("Painting", $blockReplace->getLevel(), $nbt); + /** @var Painting $entity */ + $entity = Entity::create(Painting::class, $blockReplace->getLevel(), $nbt); + $this->pop(); + $entity->spawnToAll(); - if($entity instanceof Entity){ - $this->pop(); - $entity->spawnToAll(); - - $player->getLevel()->broadcastLevelEvent($blockReplace->add(0.5, 0.5, 0.5), LevelEventPacket::EVENT_SOUND_ITEMFRAME_PLACE); //item frame and painting have the same sound - return true; - } - - return false; + $player->getLevel()->broadcastLevelEvent($blockReplace->add(0.5, 0.5, 0.5), LevelEventPacket::EVENT_SOUND_ITEMFRAME_PLACE); //item frame and painting have the same sound + return true; } } diff --git a/src/pocketmine/item/ProjectileItem.php b/src/pocketmine/item/ProjectileItem.php index 02092a9b22..3a6316a713 100644 --- a/src/pocketmine/item/ProjectileItem.php +++ b/src/pocketmine/item/ProjectileItem.php @@ -25,16 +25,22 @@ namespace pocketmine\item; use pocketmine\entity\Entity; use pocketmine\entity\EntityIds; -use pocketmine\entity\projectile\Projectile; +use pocketmine\entity\projectile\Throwable; use pocketmine\event\entity\ProjectileLaunchEvent; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\Player; +use pocketmine\utils\Utils; abstract class ProjectileItem extends Item{ - abstract public function getProjectileEntityType() : string; + /** + * Returns the entity type that this projectile creates. This should return a ::class extending Throwable. + * + * @return string class extends Throwable + */ + abstract public function getProjectileEntityClass() : string; abstract public function getThrowForce() : float; @@ -51,29 +57,25 @@ abstract class ProjectileItem extends Item{ $nbt = Entity::createBaseNBT($player->add(0, $player->getEyeHeight(), 0), $directionVector, $player->yaw, $player->pitch); $this->addExtraTags($nbt); - $projectile = Entity::createEntity($this->getProjectileEntityType(), $player->getLevel(), $nbt, $player); - if($projectile !== null){ - $projectile->setMotion($projectile->getMotion()->multiply($this->getThrowForce())); + $class = $this->getProjectileEntityClass(); + Utils::testValidInstance($class, Throwable::class); + + /** @var Throwable $projectile */ + $projectile = Entity::create($class, $player->getLevel(), $nbt, $player); + $projectile->setMotion($projectile->getMotion()->multiply($this->getThrowForce())); + + $projectileEv = new ProjectileLaunchEvent($projectile); + $projectileEv->call(); + if($projectileEv->isCancelled()){ + $projectile->flagForDespawn(); + }else{ + $projectile->spawnToAll(); + + $player->getLevel()->broadcastLevelSoundEvent($player, LevelSoundEventPacket::SOUND_THROW, 0, EntityIds::PLAYER); } $this->pop(); - if($projectile instanceof Projectile){ - $projectileEv = new ProjectileLaunchEvent($projectile); - $projectileEv->call(); - if($projectileEv->isCancelled()){ - $projectile->flagForDespawn(); - }else{ - $projectile->spawnToAll(); - - $player->getLevel()->broadcastLevelSoundEvent($player, LevelSoundEventPacket::SOUND_THROW, 0, EntityIds::PLAYER); - } - }elseif($projectile !== null){ - $projectile->spawnToAll(); - }else{ - return false; - } - return true; } } diff --git a/src/pocketmine/item/Snowball.php b/src/pocketmine/item/Snowball.php index c13f9abd73..6f46dfcb4d 100644 --- a/src/pocketmine/item/Snowball.php +++ b/src/pocketmine/item/Snowball.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\entity\projectile\Snowball as SnowballEntity; + class Snowball extends ProjectileItem{ public function __construct(){ parent::__construct(self::SNOWBALL, 0, "Snowball"); @@ -32,8 +34,8 @@ class Snowball extends ProjectileItem{ return 16; } - public function getProjectileEntityType() : string{ - return "Snowball"; + public function getProjectileEntityClass() : string{ + return SnowballEntity::class; } public function getThrowForce() : float{ diff --git a/src/pocketmine/item/SpawnEgg.php b/src/pocketmine/item/SpawnEgg.php index 5fa857d3ae..8b25b82445 100644 --- a/src/pocketmine/item/SpawnEgg.php +++ b/src/pocketmine/item/SpawnEgg.php @@ -27,10 +27,28 @@ use pocketmine\block\Block; use pocketmine\entity\Entity; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\utils\Utils; use function lcg_value; class SpawnEgg extends Item{ + /** @var string */ + private $entityClass; + + /** + * @param int $id + * @param int $variant + * @param string $entityClass instanceof Entity + * @param string $name + * + * @throws \InvalidArgumentException + */ + public function __construct(int $id, int $variant, string $entityClass, string $name = "Unknown"){ + parent::__construct($id, $variant, $name); + Utils::testValidInstance($entityClass, Entity::class); + $this->entityClass = $entityClass; + } + public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : bool{ $nbt = Entity::createBaseNBT($blockReplace->add(0.5, 0, 0.5), null, lcg_value() * 360, 0); @@ -38,14 +56,9 @@ class SpawnEgg extends Item{ $nbt->setString("CustomName", $this->getCustomName()); } - $entity = Entity::createEntity($this->meta, $player->getLevel(), $nbt); - - if($entity instanceof Entity){ - $this->pop(); - $entity->spawnToAll(); - return true; - } - - return false; + $entity = Entity::create($this->entityClass, $player->getLevel(), $nbt); + $this->pop(); + $entity->spawnToAll(); + return true; } } diff --git a/src/pocketmine/item/SplashPotion.php b/src/pocketmine/item/SplashPotion.php index 945b5f5e8f..3f12c7b840 100644 --- a/src/pocketmine/item/SplashPotion.php +++ b/src/pocketmine/item/SplashPotion.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\entity\projectile\SplashPotion as SplashPotionEntity; use pocketmine\nbt\tag\CompoundTag; class SplashPotion extends ProjectileItem{ @@ -35,8 +36,8 @@ class SplashPotion extends ProjectileItem{ return 1; } - public function getProjectileEntityType() : string{ - return "ThrownPotion"; + public function getProjectileEntityClass() : string{ + return SplashPotionEntity::class; } public function getThrowForce() : float{ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index d53ef82a72..0ba50b7947 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1634,13 +1634,11 @@ class Level implements ChunkManager, Metadatable{ $nbt->setShort("Health", 5); $nbt->setShort("PickupDelay", $delay); $nbt->setTag($itemTag); - $itemEntity = Entity::createEntity("Item", $this, $nbt); - if($itemEntity instanceof ItemEntity){ - $itemEntity->spawnToAll(); - - return $itemEntity; - } + /** @var ItemEntity $itemEntity */ + $itemEntity = Entity::create(ItemEntity::class, $this, $nbt); + $itemEntity->spawnToAll(); + return $itemEntity; } return null; } @@ -1666,15 +1664,10 @@ class Level implements ChunkManager, Metadatable{ ); $nbt->setShort(ExperienceOrb::TAG_VALUE_PC, $split); - $orb = Entity::createEntity("XPOrb", $this, $nbt); - if($orb === null){ - continue; - } - + /** @var ExperienceOrb $orb */ + $orb = Entity::create(ExperienceOrb::class, $this, $nbt); $orb->spawnToAll(); - if($orb instanceof ExperienceOrb){ - $orbs[] = $orb; - } + $orbs[] = $orb; } return $orbs; diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index 7cf6156225..2800d745d1 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -600,18 +600,13 @@ class Chunk{ $level->timings->syncChunkLoadEntitiesTimer->startTiming(); foreach($this->NBTentities as $nbt){ if($nbt instanceof CompoundTag){ - if(!$nbt->hasTag("id")){ //allow mixed types (because of leveldb) - $changed = true; - continue; - } - try{ - $entity = Entity::createEntity($nbt->getTag("id")->getValue(), $level, $nbt); + $entity = Entity::createFromData($level, $nbt); if(!($entity instanceof Entity)){ $changed = true; continue; } - }catch(\Throwable $t){ + }catch(\Exception $t){ //TODO: this shouldn't be here $level->getServer()->getLogger()->logException($t); $changed = true; continue; diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index 108b23682f..18fd3f5ec8 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -33,7 +33,6 @@ use pocketmine\level\format\io\LevelData; use pocketmine\level\format\SubChunk; use pocketmine\nbt\LittleEndianNBTStream; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\IntTag; use pocketmine\utils\Binary; use pocketmine\utils\BinaryStream; use function array_values; @@ -248,13 +247,6 @@ class LevelDB extends BaseLevelProvider{ $entities = $nbt->readMultiple($entityData); } - /** @var CompoundTag $entityNBT */ - foreach($entities as $entityNBT){ - if($entityNBT->hasTag("id", IntTag::class)){ - $entityNBT->setInt("id", $entityNBT->getInt("id") & 0xff); //remove type flags - TODO: use these instead of removing them) - } - } - /** @var CompoundTag[] $tiles */ $tiles = []; if(($tileData = $this->db->get($index . self::TAG_BLOCK_ENTITY)) !== false and $tileData !== ""){ From 7d827a1c65dc127800c58d3338894c1ead389a86 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 6 Jan 2019 23:54:29 +0000 Subject: [PATCH 0367/3224] Introduce EntityFactory This contains all of the static stuff that was previously embedded in the Entity static root. This solves a bunch of problems like circular dependencies between parent and child classes, encapsulating logic and reducing the size of the enormous Entity.php. --- src/pocketmine/Server.php | 3 +- src/pocketmine/block/Fallable.php | 6 +- src/pocketmine/block/TNT.php | 5 +- src/pocketmine/entity/Entity.php | 224 +-------------- src/pocketmine/entity/EntityFactory.php | 265 ++++++++++++++++++ src/pocketmine/item/Bow.php | 6 +- src/pocketmine/item/ItemFactory.php | 4 +- src/pocketmine/item/PaintingItem.php | 6 +- src/pocketmine/item/ProjectileItem.php | 6 +- src/pocketmine/item/SpawnEgg.php | 5 +- src/pocketmine/level/Level.php | 9 +- src/pocketmine/level/format/Chunk.php | 3 +- .../level/particle/FloatingTextParticle.php | 3 +- 13 files changed, 298 insertions(+), 247 deletions(-) create mode 100644 src/pocketmine/entity/EntityFactory.php diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index ece48518e8..9126a382cd 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -34,6 +34,7 @@ use pocketmine\command\ConsoleCommandSender; use pocketmine\command\PluginIdentifiableCommand; use pocketmine\command\SimpleCommandMap; use pocketmine\entity\Entity; +use pocketmine\entity\EntityFactory; use pocketmine\entity\Skin; use pocketmine\event\HandlerList; use pocketmine\event\level\LevelInitEvent; @@ -1695,7 +1696,7 @@ class Server{ $this->commandMap = new SimpleCommandMap($this); - Entity::init(); + EntityFactory::init(); Tile::init(); BlockFactory::init(); BlockFactory::registerStaticRuntimeIdMappings(); diff --git a/src/pocketmine/block/Fallable.php b/src/pocketmine/block/Fallable.php index 32dac2a970..1d8c693af7 100644 --- a/src/pocketmine/block/Fallable.php +++ b/src/pocketmine/block/Fallable.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\entity\Entity; +use pocketmine\entity\EntityFactory; use pocketmine\entity\object\FallingBlock; use pocketmine\math\Facing; @@ -34,12 +34,12 @@ abstract class Fallable extends Solid{ if($down->getId() === self::AIR or $down instanceof Liquid or $down instanceof Fire){ $this->level->setBlock($this, BlockFactory::get(Block::AIR)); - $nbt = Entity::createBaseNBT($this->add(0.5, 0, 0.5)); + $nbt = EntityFactory::createBaseNBT($this->add(0.5, 0, 0.5)); $nbt->setInt("TileID", $this->getId()); $nbt->setByte("Data", $this->getDamage()); /** @var FallingBlock $fall */ - $fall = Entity::create(FallingBlock::class, $this->getLevel(), $nbt); + $fall = EntityFactory::create(FallingBlock::class, $this->getLevel(), $nbt); $fall->spawnToAll(); } } diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index 50b67f4173..773592452e 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\entity\Entity; +use pocketmine\entity\EntityFactory; use pocketmine\entity\object\PrimedTNT; use pocketmine\entity\projectile\Arrow; use pocketmine\item\FlintSteel; @@ -75,11 +76,11 @@ class TNT extends Solid{ $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR)); $mot = (new Random())->nextSignedFloat() * M_PI * 2; - $nbt = Entity::createBaseNBT($this->add(0.5, 0, 0.5), new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02)); + $nbt = EntityFactory::createBaseNBT($this->add(0.5, 0, 0.5), new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02)); $nbt->setShort("Fuse", $fuse); /** @var PrimedTNT $tnt */ - $tnt = Entity::create(PrimedTNT::class, $this->getLevel(), $nbt); + $tnt = EntityFactory::create(PrimedTNT::class, $this->getLevel(), $nbt); $tnt->spawnToAll(); } diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 136b40bcb3..7c4e68d957 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -28,18 +28,6 @@ namespace pocketmine\entity; use pocketmine\block\Block; use pocketmine\block\Water; -use pocketmine\entity\object\ExperienceOrb; -use pocketmine\entity\object\FallingBlock; -use pocketmine\entity\object\ItemEntity; -use pocketmine\entity\object\Painting; -use pocketmine\entity\object\PaintingMotive; -use pocketmine\entity\object\PrimedTNT; -use pocketmine\entity\projectile\Arrow; -use pocketmine\entity\projectile\Egg; -use pocketmine\entity\projectile\EnderPearl; -use pocketmine\entity\projectile\ExperienceBottle; -use pocketmine\entity\projectile\Snowball; -use pocketmine\entity\projectile\SplashPotion; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDespawnEvent; use pocketmine\event\entity\EntityLevelChangeEvent; @@ -61,7 +49,6 @@ use pocketmine\metadata\MetadataValue; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\FloatTag; -use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\protocol\AddEntityPacket; @@ -76,23 +63,17 @@ use pocketmine\plugin\Plugin; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; -use pocketmine\utils\Utils; use function abs; -use function array_keys; use function assert; use function cos; use function count; -use function current; use function deg2rad; use function floor; use function get_class; -use function in_array; -use function is_a; use function is_array; use function is_infinite; use function is_nan; use function lcg_value; -use function reset; use function sin; use const M_PI_2; @@ -279,194 +260,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ public const DATA_FLAG_OVER_SCAFFOLDING = 69; public const DATA_FLAG_FALL_THROUGH_SCAFFOLDING = 70; - public static $entityCount = 1; - /** @var Entity[] */ - private static $knownEntities = []; - /** @var string[][] */ - private static $saveNames = []; - /** @var string[] base class => currently used class for construction */ - private static $classMapping = []; - - /** - * Called on server startup to register default entity types. - */ - public static function init() : void{ - //define legacy save IDs first - use them for saving for maximum compatibility with Minecraft PC - //TODO: index them by version to allow proper multi-save compatibility - - self::register(Arrow::class, false, ['Arrow', 'minecraft:arrow']); - self::register(Egg::class, false, ['Egg', 'minecraft:egg']); - self::register(EnderPearl::class, false, ['ThrownEnderpearl', 'minecraft:ender_pearl']); - self::register(ExperienceBottle::class, false, ['ThrownExpBottle', 'minecraft:xp_bottle']); - self::register(ExperienceOrb::class, false, ['XPOrb', 'minecraft:xp_orb']); - self::register(FallingBlock::class, false, ['FallingSand', 'minecraft:falling_block']); - self::register(ItemEntity::class, false, ['Item', 'minecraft:item']); - self::register(Painting::class, false, ['Painting', 'minecraft:painting']); - self::register(PrimedTNT::class, false, ['PrimedTnt', 'PrimedTNT', 'minecraft:tnt']); - self::register(Snowball::class, false, ['Snowball', 'minecraft:snowball']); - self::register(SplashPotion::class, false, ['ThrownPotion', 'minecraft:potion', 'thrownpotion']); - self::register(Squid::class, false, ['Squid', 'minecraft:squid']); - self::register(Villager::class, false, ['Villager', 'minecraft:villager']); - self::register(Zombie::class, false, ['Zombie', 'minecraft:zombie']); - - self::register(Human::class, true); - - Attribute::init(); - Effect::init(); - PaintingMotive::init(); - } - - - /** - * Creates an entity with the specified type, level and NBT, with optional additional arguments to pass to the - * entity's constructor. - * - * TODO: make this NBT-independent - * - * @param string $baseClass - * @param Level $level - * @param CompoundTag $nbt - * @param mixed ...$args - * - * @return Entity instanceof $baseClass - * @throws \InvalidArgumentException if the class doesn't exist or is not registered - */ - public static function create(string $baseClass, Level $level, CompoundTag $nbt, ...$args) : Entity{ - if(isset(self::$classMapping[$baseClass])){ - $class = self::$classMapping[$baseClass]; - assert(is_a($class, $baseClass, true)); - /** - * @var Entity $entity - * @see Entity::__construct() - */ - $entity = new $class($level, $nbt, ...$args); - return $entity; - } - - throw new \InvalidArgumentException("Class $baseClass is not a registered entity"); - } - - /** - * Creates an entity from data stored on a chunk. - * @internal - * - * @param Level $level - * @param CompoundTag $nbt - * - * @return Entity|null - * @throws \RuntimeException - */ - public static function createFromData(Level $level, CompoundTag $nbt) : ?Entity{ - $saveId = $nbt->getTag("id"); - $baseClass = null; - if($saveId instanceof StringTag){ - $baseClass = self::$knownEntities[$saveId->getValue()] ?? null; - }elseif($saveId instanceof IntTag){ //legacy MCPE format - $baseClass = self::$knownEntities[$saveId->getValue() & 0xff] ?? null; - } - if($baseClass === null){ - return null; - } - $class = self::$classMapping[$baseClass]; - assert(is_a($class, $baseClass, true)); - /** - * @var Entity $entity - * @see Entity::__construct() - */ - $entity = new $class($level, $nbt); - return $entity; - } - - /** - * Registers an entity type into the index. - * - * @param string $className Class that extends Entity - * @param bool $force Force registration even if the entity does not have a valid network ID - * @param string[] $saveNames An array of save names which this entity might be saved under. Defaults to the short name of the class itself if empty. - * - * NOTE: The first save name in the $saveNames array will be used when saving the entity to disk. The reflection - * name of the class will be appended to the end and only used if no other save names are specified. - * - * @throws \InvalidArgumentException - */ - public static function register(string $className, bool $force = false, array $saveNames = []) : void{ - Utils::testValidInstance($className, Entity::class); - - /** @var Entity $className */ - if($className::NETWORK_ID !== -1){ - self::$knownEntities[$className::NETWORK_ID] = $className; - }elseif(!$force){ - throw new \InvalidArgumentException("Class $className does not declare a valid NETWORK_ID and not force-registering"); - } - self::$classMapping[$className] = $className; - - $shortName = (new \ReflectionClass($className))->getShortName(); - if(!in_array($shortName, $saveNames, true)){ - $saveNames[] = $shortName; - } - - foreach($saveNames as $name){ - self::$knownEntities[$name] = $className; - } - - self::$saveNames[$className] = $saveNames; - } - - /** - * Registers a class override for the given class. When a new entity is constructed using the factory, the new class - * will be used instead of the base class. - * - * @param string $baseClass Already-registered entity class to override - * @param string $newClass Class which extends the base class - * - * @throws \InvalidArgumentException - */ - public static function override(string $baseClass, string $newClass) : void{ - if(!isset(self::$classMapping[$baseClass])){ - throw new \InvalidArgumentException("Class $baseClass is not a registered entity"); - } - - Utils::testValidInstance($newClass, $baseClass); - self::$classMapping[$baseClass] = $newClass; - } - - /** - * Returns an array of all registered entity classpaths. - * - * @return string[] - */ - public static function getKnownTypes() : array{ - return array_keys(self::$classMapping); - } - - /** - * Helper function which creates minimal NBT needed to spawn an entity. - * - * @param Vector3 $pos - * @param Vector3|null $motion - * @param float $yaw - * @param float $pitch - * - * @return CompoundTag - */ - public static function createBaseNBT(Vector3 $pos, ?Vector3 $motion = null, float $yaw = 0.0, float $pitch = 0.0) : CompoundTag{ - return new CompoundTag("", [ - new ListTag("Pos", [ - new DoubleTag("", $pos->x), - new DoubleTag("", $pos->y), - new DoubleTag("", $pos->z) - ]), - new ListTag("Motion", [ - new DoubleTag("", $motion ? $motion->x : 0.0), - new DoubleTag("", $motion ? $motion->y : 0.0), - new DoubleTag("", $motion ? $motion->z : 0.0) - ]), - new ListTag("Rotation", [ - new FloatTag("", $yaw), - new FloatTag("", $pitch) - ]) - ]); - } /** * @var Player[] @@ -591,7 +384,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->eyeHeight = $this->height / 2 + 0.1; } - $this->id = Entity::$entityCount++; + $this->id = EntityFactory::nextRuntimeId(); $this->server = $level->getServer(); /** @var float[] $pos */ @@ -924,23 +717,10 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->savedWithChunk = $value; } - /** - * Returns the short save name - * - * @return string - */ - public function getSaveId() : string{ - if(!isset(self::$saveNames[static::class])){ - throw new \InvalidStateException("Entity is not registered"); - } - reset(self::$saveNames[static::class]); - return current(self::$saveNames[static::class]); - } - public function saveNBT() : CompoundTag{ $nbt = new CompoundTag(); if(!($this instanceof Player)){ - $nbt->setString("id", $this->getSaveId()); + $nbt->setString("id", EntityFactory::getSaveId(get_class($this))); if($this->getNameTag() !== ""){ $nbt->setString("CustomName", $this->getNameTag()); diff --git a/src/pocketmine/entity/EntityFactory.php b/src/pocketmine/entity/EntityFactory.php new file mode 100644 index 0000000000..30f3f78ccc --- /dev/null +++ b/src/pocketmine/entity/EntityFactory.php @@ -0,0 +1,265 @@ + currently used class for construction */ + private static $classMapping = []; + /** @var Entity[] */ + private static $knownEntities = []; + /** @var string[][] */ + private static $saveNames = []; + + private function __construct(){ + //NOOP + } + + /** + * Called on server startup to register default entity types. + */ + public static function init() : void{ + //define legacy save IDs first - use them for saving for maximum compatibility with Minecraft PC + //TODO: index them by version to allow proper multi-save compatibility + + self::register(Arrow::class, false, ['Arrow', 'minecraft:arrow']); + self::register(Egg::class, false, ['Egg', 'minecraft:egg']); + self::register(EnderPearl::class, false, ['ThrownEnderpearl', 'minecraft:ender_pearl']); + self::register(ExperienceBottle::class, false, ['ThrownExpBottle', 'minecraft:xp_bottle']); + self::register(ExperienceOrb::class, false, ['XPOrb', 'minecraft:xp_orb']); + self::register(FallingBlock::class, false, ['FallingSand', 'minecraft:falling_block']); + self::register(ItemEntity::class, false, ['Item', 'minecraft:item']); + self::register(Painting::class, false, ['Painting', 'minecraft:painting']); + self::register(PrimedTNT::class, false, ['PrimedTnt', 'PrimedTNT', 'minecraft:tnt']); + self::register(Snowball::class, false, ['Snowball', 'minecraft:snowball']); + self::register(SplashPotion::class, false, ['ThrownPotion', 'minecraft:potion', 'thrownpotion']); + self::register(Squid::class, false, ['Squid', 'minecraft:squid']); + self::register(Villager::class, false, ['Villager', 'minecraft:villager']); + self::register(Zombie::class, false, ['Zombie', 'minecraft:zombie']); + + self::register(Human::class, true); + + Attribute::init(); + Effect::init(); + PaintingMotive::init(); + } + + /** + * Registers an entity type into the index. + * + * @param string $className Class that extends Entity + * @param bool $force Force registration even if the entity does not have a valid network ID + * @param string[] $saveNames An array of save names which this entity might be saved under. Defaults to the short name of the class itself if empty. + * + * NOTE: The first save name in the $saveNames array will be used when saving the entity to disk. The reflection + * name of the class will be appended to the end and only used if no other save names are specified. + * + * @throws \InvalidArgumentException + */ + public static function register(string $className, bool $force = false, array $saveNames = []) : void{ + Utils::testValidInstance($className, Entity::class); + + /** @var Entity $className */ + if($className::NETWORK_ID !== -1){ + self::$knownEntities[$className::NETWORK_ID] = $className; + }elseif(!$force){ + throw new \InvalidArgumentException("Class $className does not declare a valid NETWORK_ID and not force-registering"); + } + self::$classMapping[$className] = $className; + + $shortName = (new \ReflectionClass($className))->getShortName(); + if(!in_array($shortName, $saveNames, true)){ + $saveNames[] = $shortName; + } + + foreach($saveNames as $name){ + self::$knownEntities[$name] = $className; + } + + self::$saveNames[$className] = $saveNames; + } + + /** + * Registers a class override for the given class. When a new entity is constructed using the factory, the new class + * will be used instead of the base class. + * + * @param string $baseClass Already-registered entity class to override + * @param string $newClass Class which extends the base class + * + * @throws \InvalidArgumentException + */ + public static function override(string $baseClass, string $newClass) : void{ + if(!isset(self::$classMapping[$baseClass])){ + throw new \InvalidArgumentException("Class $baseClass is not a registered entity"); + } + + Utils::testValidInstance($newClass, $baseClass); + self::$classMapping[$baseClass] = $newClass; + } + + /** + * Returns an array of all registered entity classpaths. + * + * @return string[] + */ + public static function getKnownTypes() : array{ + return array_keys(self::$classMapping); + } + + /** + * Returns a new runtime entity ID for a new entity. + * + * @return int + */ + public static function nextRuntimeId() : int{ + return self::$entityCount++; + } + + /** + * Creates an entity with the specified type, level and NBT, with optional additional arguments to pass to the + * entity's constructor. + * + * TODO: make this NBT-independent + * + * @param string $baseClass + * @param Level $level + * @param CompoundTag $nbt + * @param mixed ...$args + * + * @return Entity instanceof $baseClass + * @throws \InvalidArgumentException if the class doesn't exist or is not registered + */ + public static function create(string $baseClass, Level $level, CompoundTag $nbt, ...$args) : Entity{ + if(isset(self::$classMapping[$baseClass])){ + $class = self::$classMapping[$baseClass]; + assert(is_a($class, $baseClass, true)); + /** + * @var Entity $entity + * @see Entity::__construct() + */ + $entity = new $class($level, $nbt, ...$args); + + return $entity; + } + + throw new \InvalidArgumentException("Class $baseClass is not a registered entity"); + } + + /** + * Creates an entity from data stored on a chunk. + * @internal + * + * @param Level $level + * @param CompoundTag $nbt + * + * @return Entity|null + * @throws \RuntimeException + */ + public static function createFromData(Level $level, CompoundTag $nbt) : ?Entity{ + $saveId = $nbt->getTag("id"); + $baseClass = null; + if($saveId instanceof StringTag){ + $baseClass = self::$knownEntities[$saveId->getValue()] ?? null; + }elseif($saveId instanceof IntTag){ //legacy MCPE format + $baseClass = self::$knownEntities[$saveId->getValue() & 0xff] ?? null; + } + if($baseClass === null){ + return null; + } + $class = self::$classMapping[$baseClass]; + assert(is_a($class, $baseClass, true)); + /** + * @var Entity $entity + * @see Entity::__construct() + */ + $entity = new $class($level, $nbt); + + return $entity; + } + + public static function getSaveId(string $class) : string{ + if(isset(self::$saveNames[$class])){ + return reset(self::$saveNames[$class]); + } + throw new \InvalidArgumentException("Entity $class is not registered"); + } + + + /** + * Helper function which creates minimal NBT needed to spawn an entity. + * + * @param Vector3 $pos + * @param Vector3|null $motion + * @param float $yaw + * @param float $pitch + * + * @return CompoundTag + */ + public static function createBaseNBT(Vector3 $pos, ?Vector3 $motion = null, float $yaw = 0.0, float $pitch = 0.0) : CompoundTag{ + return new CompoundTag("", [ + new ListTag("Pos", [ + new DoubleTag("", $pos->x), + new DoubleTag("", $pos->y), + new DoubleTag("", $pos->z) + ]), + new ListTag("Motion", [ + new DoubleTag("", $motion ? $motion->x : 0.0), + new DoubleTag("", $motion ? $motion->y : 0.0), + new DoubleTag("", $motion ? $motion->z : 0.0) + ]), + new ListTag("Rotation", [ + new FloatTag("", $yaw), + new FloatTag("", $pitch) + ]) + ]); + } +} diff --git a/src/pocketmine/item/Bow.php b/src/pocketmine/item/Bow.php index 5105434a55..9cc3cb44e0 100644 --- a/src/pocketmine/item/Bow.php +++ b/src/pocketmine/item/Bow.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\Entity; +use pocketmine\entity\EntityFactory; use pocketmine\entity\projectile\Arrow as ArrowEntity; use pocketmine\entity\projectile\Projectile; use pocketmine\event\entity\EntityShootBowEvent; @@ -53,7 +53,7 @@ class Bow extends Tool{ return false; } - $nbt = Entity::createBaseNBT( + $nbt = EntityFactory::createBaseNBT( $player->add(0, $player->getEyeHeight(), 0), $player->getDirectionVector(), ($player->yaw > 180 ? 360 : 0) - $player->yaw, @@ -66,7 +66,7 @@ class Bow extends Tool{ $force = min((($p ** 2) + $p * 2) / 3, 1) * 2; /** @var ArrowEntity $entity */ - $entity = Entity::create(ArrowEntity::class, $player->getLevel(), $nbt, $player, $force == 2); + $entity = EntityFactory::create(ArrowEntity::class, $player->getLevel(), $nbt, $player, $force == 2); $infinity = $this->hasEnchantment(Enchantment::INFINITY); if($infinity){ diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 0fbafa9b77..fadadbad1c 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -25,7 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\entity\Entity; +use pocketmine\entity\EntityFactory; use pocketmine\entity\Living; use pocketmine\nbt\tag\CompoundTag; use pocketmine\tile\Skull; @@ -194,7 +194,7 @@ class ItemFactory{ //TODO: ENDER_EYE self::registerItem(new Item(Item::GLISTERING_MELON, 0, "Glistering Melon")); - foreach(Entity::getKnownTypes() as $className){ + foreach(EntityFactory::getKnownTypes() as $className){ /** @var Living|string $className */ if(is_a($className, Living::class, true) and $className::NETWORK_ID !== -1){ self::registerItem(new SpawnEgg(Item::SPAWN_EGG, $className::NETWORK_ID, $className, "Spawn Egg")); diff --git a/src/pocketmine/item/PaintingItem.php b/src/pocketmine/item/PaintingItem.php index 69f833031b..2856b7f925 100644 --- a/src/pocketmine/item/PaintingItem.php +++ b/src/pocketmine/item/PaintingItem.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\Block; -use pocketmine\entity\Entity; +use pocketmine\entity\EntityFactory; use pocketmine\entity\object\Painting; use pocketmine\entity\object\PaintingMotive; use pocketmine\math\Facing; @@ -86,7 +86,7 @@ class PaintingItem extends Item{ return false; } - $nbt = Entity::createBaseNBT($blockReplace, null, $direction * 90, 0); + $nbt = EntityFactory::createBaseNBT($blockReplace, null, $direction * 90, 0); $nbt->setByte("Direction", $direction); $nbt->setString("Motive", $motive->getName()); $nbt->setInt("TileX", $blockClicked->getFloorX()); @@ -94,7 +94,7 @@ class PaintingItem extends Item{ $nbt->setInt("TileZ", $blockClicked->getFloorZ()); /** @var Painting $entity */ - $entity = Entity::create(Painting::class, $blockReplace->getLevel(), $nbt); + $entity = EntityFactory::create(Painting::class, $blockReplace->getLevel(), $nbt); $this->pop(); $entity->spawnToAll(); diff --git a/src/pocketmine/item/ProjectileItem.php b/src/pocketmine/item/ProjectileItem.php index 3a6316a713..14bb8e5875 100644 --- a/src/pocketmine/item/ProjectileItem.php +++ b/src/pocketmine/item/ProjectileItem.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\Entity; +use pocketmine\entity\EntityFactory; use pocketmine\entity\EntityIds; use pocketmine\entity\projectile\Throwable; use pocketmine\event\entity\ProjectileLaunchEvent; @@ -54,14 +54,14 @@ abstract class ProjectileItem extends Item{ } public function onClickAir(Player $player, Vector3 $directionVector) : bool{ - $nbt = Entity::createBaseNBT($player->add(0, $player->getEyeHeight(), 0), $directionVector, $player->yaw, $player->pitch); + $nbt = EntityFactory::createBaseNBT($player->add(0, $player->getEyeHeight(), 0), $directionVector, $player->yaw, $player->pitch); $this->addExtraTags($nbt); $class = $this->getProjectileEntityClass(); Utils::testValidInstance($class, Throwable::class); /** @var Throwable $projectile */ - $projectile = Entity::create($class, $player->getLevel(), $nbt, $player); + $projectile = EntityFactory::create($class, $player->getLevel(), $nbt, $player); $projectile->setMotion($projectile->getMotion()->multiply($this->getThrowForce())); $projectileEv = new ProjectileLaunchEvent($projectile); diff --git a/src/pocketmine/item/SpawnEgg.php b/src/pocketmine/item/SpawnEgg.php index 8b25b82445..7c7d86d288 100644 --- a/src/pocketmine/item/SpawnEgg.php +++ b/src/pocketmine/item/SpawnEgg.php @@ -25,6 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\entity\Entity; +use pocketmine\entity\EntityFactory; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\utils\Utils; @@ -50,13 +51,13 @@ class SpawnEgg extends Item{ } public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : bool{ - $nbt = Entity::createBaseNBT($blockReplace->add(0.5, 0, 0.5), null, lcg_value() * 360, 0); + $nbt = EntityFactory::createBaseNBT($blockReplace->add(0.5, 0, 0.5), null, lcg_value() * 360, 0); if($this->hasCustomName()){ $nbt->setString("CustomName", $this->getCustomName()); } - $entity = Entity::create($this->entityClass, $player->getLevel(), $nbt); + $entity = EntityFactory::create($this->entityClass, $player->getLevel(), $nbt); $this->pop(); $entity->spawnToAll(); return true; diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 0ba50b7947..374ece7d84 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -30,6 +30,7 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\UnknownBlock; use pocketmine\entity\Entity; +use pocketmine\entity\EntityFactory; use pocketmine\entity\object\ExperienceOrb; use pocketmine\entity\object\ItemEntity; use pocketmine\event\block\BlockBreakEvent; @@ -1630,13 +1631,13 @@ class Level implements ChunkManager, Metadatable{ $itemTag->setName("Item"); if(!$item->isNull()){ - $nbt = Entity::createBaseNBT($source, $motion, lcg_value() * 360, 0); + $nbt = EntityFactory::createBaseNBT($source, $motion, lcg_value() * 360, 0); $nbt->setShort("Health", 5); $nbt->setShort("PickupDelay", $delay); $nbt->setTag($itemTag); /** @var ItemEntity $itemEntity */ - $itemEntity = Entity::create(ItemEntity::class, $this, $nbt); + $itemEntity = EntityFactory::create(ItemEntity::class, $this, $nbt); $itemEntity->spawnToAll(); return $itemEntity; } @@ -1656,7 +1657,7 @@ class Level implements ChunkManager, Metadatable{ $orbs = []; foreach(ExperienceOrb::splitIntoOrbSizes($amount) as $split){ - $nbt = Entity::createBaseNBT( + $nbt = EntityFactory::createBaseNBT( $pos, $this->temporalVector->setComponents((lcg_value() * 0.2 - 0.1) * 2, lcg_value() * 0.4, (lcg_value() * 0.2 - 0.1) * 2), lcg_value() * 360, @@ -1665,7 +1666,7 @@ class Level implements ChunkManager, Metadatable{ $nbt->setShort(ExperienceOrb::TAG_VALUE_PC, $split); /** @var ExperienceOrb $orb */ - $orb = Entity::create(ExperienceOrb::class, $this, $nbt); + $orb = EntityFactory::create(ExperienceOrb::class, $this, $nbt); $orb->spawnToAll(); $orbs[] = $orb; } diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index 2800d745d1..bba26c00a1 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -28,6 +28,7 @@ namespace pocketmine\level\format; use pocketmine\block\BlockFactory; use pocketmine\entity\Entity; +use pocketmine\entity\EntityFactory; use pocketmine\level\Level; use pocketmine\nbt\tag\CompoundTag; use pocketmine\Player; @@ -601,7 +602,7 @@ class Chunk{ foreach($this->NBTentities as $nbt){ if($nbt instanceof CompoundTag){ try{ - $entity = Entity::createFromData($level, $nbt); + $entity = EntityFactory::createFromData($level, $nbt); if(!($entity instanceof Entity)){ $changed = true; continue; diff --git a/src/pocketmine/level/particle/FloatingTextParticle.php b/src/pocketmine/level/particle/FloatingTextParticle.php index 7423670484..727b75cc09 100644 --- a/src/pocketmine/level/particle/FloatingTextParticle.php +++ b/src/pocketmine/level/particle/FloatingTextParticle.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\level\particle; use pocketmine\entity\Entity; +use pocketmine\entity\EntityFactory; use pocketmine\entity\Skin; use pocketmine\item\Item; use pocketmine\item\ItemFactory; @@ -80,7 +81,7 @@ class FloatingTextParticle extends Particle{ $p = []; if($this->entityId === null){ - $this->entityId = Entity::$entityCount++; + $this->entityId = EntityFactory::nextRuntimeId(); }else{ $pk0 = new RemoveEntityPacket(); $pk0->entityUniqueId = $this->entityId; From 78cb6445a5502bada9c42887b74a6de7cb22f8a8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 7 Jan 2019 00:20:24 +0000 Subject: [PATCH 0368/3224] Introduce TileFactory --- src/pocketmine/Server.php | 4 +- src/pocketmine/block/Bed.php | 4 +- src/pocketmine/block/Chest.php | 4 +- src/pocketmine/block/EnchantingTable.php | 4 +- src/pocketmine/block/EnderChest.php | 4 +- src/pocketmine/block/FlowerPot.php | 4 +- src/pocketmine/block/Furnace.php | 4 +- src/pocketmine/block/ItemFrame.php | 4 +- src/pocketmine/block/SignPost.php | 4 +- src/pocketmine/block/Skull.php | 4 +- src/pocketmine/block/StandingBanner.php | 4 +- src/pocketmine/level/format/Chunk.php | 3 +- src/pocketmine/tile/Banner.php | 4 +- src/pocketmine/tile/Bed.php | 2 +- src/pocketmine/tile/Chest.php | 2 +- src/pocketmine/tile/EnchantTable.php | 2 +- src/pocketmine/tile/EnderChest.php | 2 +- src/pocketmine/tile/FlowerPot.php | 2 +- src/pocketmine/tile/Furnace.php | 2 +- src/pocketmine/tile/ItemFrame.php | 2 +- src/pocketmine/tile/NameableTrait.php | 2 +- src/pocketmine/tile/Sign.php | 2 +- src/pocketmine/tile/Skull.php | 2 +- src/pocketmine/tile/Spawnable.php | 3 +- src/pocketmine/tile/Tile.php | 151 ++------------------ src/pocketmine/tile/TileFactory.php | 171 +++++++++++++++++++++++ 26 files changed, 220 insertions(+), 176 deletions(-) create mode 100644 src/pocketmine/tile/TileFactory.php diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 9126a382cd..cd3b92920b 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -101,7 +101,7 @@ use pocketmine\scheduler\AsyncPool; use pocketmine\scheduler\SendUsageTask; use pocketmine\snooze\SleeperHandler; use pocketmine\snooze\SleeperNotifier; -use pocketmine\tile\Tile; +use pocketmine\tile\TileFactory; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; use pocketmine\updater\AutoUpdater; @@ -1697,7 +1697,7 @@ class Server{ $this->commandMap = new SimpleCommandMap($this); EntityFactory::init(); - Tile::init(); + TileFactory::init(); BlockFactory::init(); BlockFactory::registerStaticRuntimeIdMappings(); Enchantment::init(); diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index edfc72ed85..3a63b790c5 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -35,7 +35,7 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Bed as TileBed; -use pocketmine\tile\Tile; +use pocketmine\tile\TileFactory; use pocketmine\utils\TextFormat; class Bed extends Transparent{ @@ -88,7 +88,7 @@ class Bed extends Transparent{ parent::writeStateToWorld(); //extra block properties storage hack /** @var TileBed $tile */ - $tile = Tile::create(TileBed::class, $this->getLevel(), $this->asVector3()); + $tile = TileFactory::create(TileBed::class, $this->getLevel(), $this->asVector3()); $tile->setColor($this->color); $this->level->addTile($tile); } diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index 9e0beb7e26..a7bdc97509 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -30,7 +30,7 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Chest as TileChest; -use pocketmine\tile\Tile; +use pocketmine\tile\TileFactory; class Chest extends Transparent{ @@ -95,7 +95,7 @@ class Chest extends Transparent{ if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ /** @var TileChest $tile */ - $tile = Tile::createFromItem(TileChest::class, $this->getLevel(), $this->asVector3(), $item); + $tile = TileFactory::createFromItem(TileChest::class, $this->getLevel(), $this->asVector3(), $item); $this->level->addTile($tile); if($pair instanceof TileChest){ diff --git a/src/pocketmine/block/EnchantingTable.php b/src/pocketmine/block/EnchantingTable.php index 86a88a8c31..5a1a628634 100644 --- a/src/pocketmine/block/EnchantingTable.php +++ b/src/pocketmine/block/EnchantingTable.php @@ -31,7 +31,7 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\EnchantTable as TileEnchantingTable; -use pocketmine\tile\Tile; +use pocketmine\tile\TileFactory; class EnchantingTable extends Transparent{ @@ -43,7 +43,7 @@ class EnchantingTable extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - $this->level->addTile(Tile::createFromItem(TileEnchantingTable::class, $this->getLevel(), $this->asVector3(), $item)); + $this->level->addTile(TileFactory::createFromItem(TileEnchantingTable::class, $this->getLevel(), $this->asVector3(), $item)); return true; } diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index e8026a5aff..1bde46ab26 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -30,7 +30,7 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\EnderChest as TileEnderChest; -use pocketmine\tile\Tile; +use pocketmine\tile\TileFactory; class EnderChest extends Chest{ @@ -66,7 +66,7 @@ class EnderChest extends Chest{ } if(Block::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - $this->level->addTile(Tile::createFromItem(TileEnderChest::class, $this->getLevel(), $this->asVector3(), $item)); + $this->level->addTile(TileFactory::createFromItem(TileEnderChest::class, $this->getLevel(), $this->asVector3(), $item)); return true; } diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index f9ac6eb609..4b24d626a7 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -29,7 +29,7 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\FlowerPot as TileFlowerPot; -use pocketmine\tile\Tile; +use pocketmine\tile\TileFactory; class FlowerPot extends Flowable{ @@ -69,7 +69,7 @@ class FlowerPot extends Flowable{ } if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - $this->level->addTile(Tile::createFromItem(TileFlowerPot::class, $this->getLevel(), $this->asVector3(), $item)); + $this->level->addTile(TileFactory::createFromItem(TileFlowerPot::class, $this->getLevel(), $this->asVector3(), $item)); return true; } diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index 0e2dc49e97..031accfad4 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -30,7 +30,7 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Furnace as TileFurnace; -use pocketmine\tile\Tile; +use pocketmine\tile\TileFactory; class Furnace extends Solid{ @@ -100,7 +100,7 @@ class Furnace extends Solid{ $this->facing = Facing::opposite($player->getHorizontalFacing()); } if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - $this->level->addTile(Tile::createFromItem(TileFurnace::class, $this->getLevel(), $this->asVector3(), $item)); + $this->level->addTile(TileFactory::createFromItem(TileFurnace::class, $this->getLevel(), $this->asVector3(), $item)); return true; } diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 40b9930bad..827d7c2ba1 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -29,7 +29,7 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\ItemFrame as TileItemFrame; -use pocketmine\tile\Tile; +use pocketmine\tile\TileFactory; use function lcg_value; class ItemFrame extends Flowable{ @@ -87,7 +87,7 @@ class ItemFrame extends Flowable{ $this->facing = $face; if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - $this->level->addTile(Tile::createFromItem(TileItemFrame::class, $this->getLevel(), $this->asVector3(), $item)); + $this->level->addTile(TileFactory::createFromItem(TileItemFrame::class, $this->getLevel(), $this->asVector3(), $item)); return true; } diff --git a/src/pocketmine/block/SignPost.php b/src/pocketmine/block/SignPost.php index 4531b4f8c7..d9d05131b6 100644 --- a/src/pocketmine/block/SignPost.php +++ b/src/pocketmine/block/SignPost.php @@ -29,7 +29,7 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Sign as TileSign; -use pocketmine\tile\Tile; +use pocketmine\tile\TileFactory; use function floor; class SignPost extends Transparent{ @@ -84,7 +84,7 @@ class SignPost extends Transparent{ } if($ret){ - $this->level->addTile(Tile::createFromItem(TileSign::class, $this->getLevel(), $this->asVector3(), $item)); + $this->level->addTile(TileFactory::createFromItem(TileSign::class, $this->getLevel(), $this->asVector3(), $item)); return true; } } diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index 5208f7e0db..156ed0da7b 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -31,7 +31,7 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Skull as TileSkull; -use pocketmine\tile\Tile; +use pocketmine\tile\TileFactory; use function floor; class Skull extends Flowable{ @@ -73,7 +73,7 @@ class Skull extends Flowable{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); /** @var TileSkull $tile */ - $tile = Tile::create(TileSkull::class, $this->getLevel(), $this->asVector3()); + $tile = TileFactory::create(TileSkull::class, $this->getLevel(), $this->asVector3()); $tile->setRotation($this->rotation); $tile->setType($this->type); $this->level->addTile($tile); diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index 7a011c68fa..ff58a176e6 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -31,7 +31,7 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Banner as TileBanner; -use pocketmine\tile\Tile; +use pocketmine\tile\TileFactory; use function floor; class StandingBanner extends Transparent{ @@ -85,7 +85,7 @@ class StandingBanner extends Transparent{ } if($ret){ - $this->level->addTile(Tile::createFromItem(TileBanner::class, $this->getLevel(), $this->asVector3(), $item)); + $this->level->addTile(TileFactory::createFromItem(TileBanner::class, $this->getLevel(), $this->asVector3(), $item)); return true; } } diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index bba26c00a1..38799b0601 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -34,6 +34,7 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\Player; use pocketmine\tile\Spawnable; use pocketmine\tile\Tile; +use pocketmine\tile\TileFactory; use pocketmine\utils\BinaryStream; use function array_fill; use function array_filter; @@ -619,7 +620,7 @@ class Chunk{ $level->timings->syncChunkLoadTileEntitiesTimer->startTiming(); foreach($this->NBTtiles as $nbt){ if($nbt instanceof CompoundTag){ - if(($tile = Tile::createFromData($level, $nbt)) !== null){ + if(($tile = TileFactory::createFromData($level, $nbt)) !== null){ $level->addTile($tile); }else{ $changed = true; diff --git a/src/pocketmine/tile/Banner.php b/src/pocketmine/tile/Banner.php index f63110baac..3266236fb7 100644 --- a/src/pocketmine/tile/Banner.php +++ b/src/pocketmine/tile/Banner.php @@ -113,7 +113,7 @@ class Banner extends Spawnable implements Nameable{ parent::__construct($level, $pos); } - protected function readSaveData(CompoundTag $nbt) : void{ + public function readSaveData(CompoundTag $nbt) : void{ $this->baseColor = $nbt->getInt(self::TAG_BASE, $this->baseColor, true); $this->patterns = $nbt->getListTag(self::TAG_PATTERNS) ?? $this->patterns; $this->loadName($nbt); @@ -131,7 +131,7 @@ class Banner extends Spawnable implements Nameable{ $this->addNameSpawnData($nbt); } - protected function copyDataFromItem(Item $item) : void{ + public function copyDataFromItem(Item $item) : void{ parent::copyDataFromItem($item); $this->copyNameFromItem($item); if($item instanceof ItemBanner){ diff --git a/src/pocketmine/tile/Bed.php b/src/pocketmine/tile/Bed.php index ebcd291f70..42fe1c776f 100644 --- a/src/pocketmine/tile/Bed.php +++ b/src/pocketmine/tile/Bed.php @@ -39,7 +39,7 @@ class Bed extends Spawnable{ $this->onChanged(); } - protected function readSaveData(CompoundTag $nbt) : void{ + public function readSaveData(CompoundTag $nbt) : void{ $this->color = $nbt->getByte(self::TAG_COLOR, 14, true); } diff --git a/src/pocketmine/tile/Chest.php b/src/pocketmine/tile/Chest.php index e9734cabf5..a5aad2fdab 100644 --- a/src/pocketmine/tile/Chest.php +++ b/src/pocketmine/tile/Chest.php @@ -56,7 +56,7 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ parent::__construct($level, $pos); } - protected function readSaveData(CompoundTag $nbt) : void{ + public function readSaveData(CompoundTag $nbt) : void{ if($nbt->hasTag(self::TAG_PAIRX, IntTag::class) and $nbt->hasTag(self::TAG_PAIRZ, IntTag::class)){ $this->pairX = $nbt->getInt(self::TAG_PAIRX); $this->pairZ = $nbt->getInt(self::TAG_PAIRZ); diff --git a/src/pocketmine/tile/EnchantTable.php b/src/pocketmine/tile/EnchantTable.php index e2618a8ff8..d6dc08a20b 100644 --- a/src/pocketmine/tile/EnchantTable.php +++ b/src/pocketmine/tile/EnchantTable.php @@ -25,7 +25,7 @@ namespace pocketmine\tile; class EnchantTable extends Spawnable implements Nameable{ use NameableTrait{ - loadName as readSaveData; + loadName as public readSaveData; saveName as writeSaveData; } diff --git a/src/pocketmine/tile/EnderChest.php b/src/pocketmine/tile/EnderChest.php index 5faa2b2929..9493c924e6 100644 --- a/src/pocketmine/tile/EnderChest.php +++ b/src/pocketmine/tile/EnderChest.php @@ -27,7 +27,7 @@ use pocketmine\nbt\tag\CompoundTag; class EnderChest extends Spawnable{ - protected function readSaveData(CompoundTag $nbt) : void{ + public function readSaveData(CompoundTag $nbt) : void{ } diff --git a/src/pocketmine/tile/FlowerPot.php b/src/pocketmine/tile/FlowerPot.php index 7ee5c7e681..b8aefefc6c 100644 --- a/src/pocketmine/tile/FlowerPot.php +++ b/src/pocketmine/tile/FlowerPot.php @@ -43,7 +43,7 @@ class FlowerPot extends Spawnable{ parent::__construct($level, $pos); } - protected function readSaveData(CompoundTag $nbt) : void{ + public function readSaveData(CompoundTag $nbt) : void{ if($nbt->hasTag(self::TAG_ITEM, ShortTag::class) and $nbt->hasTag(self::TAG_ITEM_DATA, IntTag::class)){ $this->item = ItemFactory::get($nbt->getShort(self::TAG_ITEM, 0), $nbt->getInt(self::TAG_ITEM_DATA, 0), 1); } diff --git a/src/pocketmine/tile/Furnace.php b/src/pocketmine/tile/Furnace.php index 814543557c..b98dd5b551 100644 --- a/src/pocketmine/tile/Furnace.php +++ b/src/pocketmine/tile/Furnace.php @@ -68,7 +68,7 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ parent::__construct($level, $pos); } - protected function readSaveData(CompoundTag $nbt) : void{ + public function readSaveData(CompoundTag $nbt) : void{ $this->burnTime = max(0, $nbt->getShort(self::TAG_BURN_TIME, $this->burnTime, true)); $this->cookTime = $nbt->getShort(self::TAG_COOK_TIME, $this->cookTime, true); diff --git a/src/pocketmine/tile/ItemFrame.php b/src/pocketmine/tile/ItemFrame.php index 2fbb1f4b5c..a4c5108171 100644 --- a/src/pocketmine/tile/ItemFrame.php +++ b/src/pocketmine/tile/ItemFrame.php @@ -46,7 +46,7 @@ class ItemFrame extends Spawnable{ parent::__construct($level, $pos); } - protected function readSaveData(CompoundTag $nbt) : void{ + public function readSaveData(CompoundTag $nbt) : void{ if(($itemTag = $nbt->getCompoundTag(self::TAG_ITEM)) !== null){ $this->item = Item::nbtDeserialize($itemTag); } diff --git a/src/pocketmine/tile/NameableTrait.php b/src/pocketmine/tile/NameableTrait.php index 4b159df422..8f9ad1070b 100644 --- a/src/pocketmine/tile/NameableTrait.php +++ b/src/pocketmine/tile/NameableTrait.php @@ -86,7 +86,7 @@ trait NameableTrait{ * @param Item $item * @see Tile::copyDataFromItem() */ - protected function copyDataFromItem(Item $item) : void{ + public function copyDataFromItem(Item $item) : void{ parent::copyDataFromItem($item); if($item->hasCustomName()){ //this should take precedence over saved NBT $this->setName($item->getCustomName()); diff --git a/src/pocketmine/tile/Sign.php b/src/pocketmine/tile/Sign.php index 1f5ef98a2e..55d64f1c37 100644 --- a/src/pocketmine/tile/Sign.php +++ b/src/pocketmine/tile/Sign.php @@ -44,7 +44,7 @@ class Sign extends Spawnable{ /** @var string[] */ protected $text = ["", "", "", ""]; - protected function readSaveData(CompoundTag $nbt) : void{ + public function readSaveData(CompoundTag $nbt) : void{ if($nbt->hasTag(self::TAG_TEXT_BLOB, StringTag::class)){ //MCPE 1.2 save format $this->text = array_pad(explode("\n", $nbt->getString(self::TAG_TEXT_BLOB)), 4, ""); assert(count($this->text) === 4, "Too many lines!"); diff --git a/src/pocketmine/tile/Skull.php b/src/pocketmine/tile/Skull.php index 1421fe5db2..87876a76c7 100644 --- a/src/pocketmine/tile/Skull.php +++ b/src/pocketmine/tile/Skull.php @@ -43,7 +43,7 @@ class Skull extends Spawnable{ /** @var int */ private $skullRotation = 0; - protected function readSaveData(CompoundTag $nbt) : void{ + public function readSaveData(CompoundTag $nbt) : void{ $this->skullType = $nbt->getByte(self::TAG_SKULL_TYPE, $this->skullType, true); $this->skullRotation = $nbt->getByte(self::TAG_ROT, $this->skullRotation, true); } diff --git a/src/pocketmine/tile/Spawnable.php b/src/pocketmine/tile/Spawnable.php index 0c8200241a..b4954ffb1c 100644 --- a/src/pocketmine/tile/Spawnable.php +++ b/src/pocketmine/tile/Spawnable.php @@ -29,6 +29,7 @@ use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\NetworkLittleEndianNBTStream; use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\Player; +use function get_class; abstract class Spawnable extends Tile{ /** @var string|null */ @@ -108,7 +109,7 @@ abstract class Spawnable extends Tile{ */ final public function getSpawnCompound() : CompoundTag{ $nbt = new CompoundTag("", [ - new StringTag(self::TAG_ID, static::getSaveId()), + new StringTag(self::TAG_ID, TileFactory::getSaveId(get_class($this))), //TODO: disassociate network ID from save ID new IntTag(self::TAG_X, $this->x), new IntTag(self::TAG_Y, $this->y), new IntTag(self::TAG_Z, $this->z) diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/tile/Tile.php index 86a6e9dd1c..60bb22fff5 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/tile/Tile.php @@ -35,13 +35,7 @@ use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; -use pocketmine\utils\Utils; -use function assert; -use function current; use function get_class; -use function in_array; -use function is_a; -use function reset; abstract class Tile extends Position{ @@ -50,14 +44,6 @@ abstract class Tile extends Position{ public const TAG_Y = "y"; public const TAG_Z = "z"; - /** @var string[] classes that extend Tile */ - private static $knownTiles = []; - /** @var string[][] */ - private static $saveNames = []; - - /** @var string[] base class => overridden class */ - private static $classMapping = []; - /** @var string */ public $name = ""; /** @var bool */ @@ -65,140 +51,18 @@ abstract class Tile extends Position{ /** @var TimingsHandler */ protected $timings; - public static function init(){ - self::register(Banner::class, ["Banner", "minecraft:banner"]); - self::register(Bed::class, ["Bed", "minecraft:bed"]); - self::register(Chest::class, ["Chest", "minecraft:chest"]); - self::register(EnchantTable::class, ["EnchantTable", "minecraft:enchanting_table"]); - self::register(EnderChest::class, ["EnderChest", "minecraft:ender_chest"]); - self::register(FlowerPot::class, ["FlowerPot", "minecraft:flower_pot"]); - self::register(Furnace::class, ["Furnace", "minecraft:furnace"]); - self::register(ItemFrame::class, ["ItemFrame"]); //this is an entity in PC - self::register(Sign::class, ["Sign", "minecraft:sign"]); - self::register(Skull::class, ["Skull", "minecraft:skull"]); - } - - /** - * @param Level $level - * @param CompoundTag $nbt - * - * @return Tile|null - */ - public static function createFromData(Level $level, CompoundTag $nbt) : ?Tile{ - $type = $nbt->getString(self::TAG_ID, "", true); - if(!isset(self::$knownTiles[$type])){ - return null; - } - $class = self::$knownTiles[$type]; - assert(is_a($class, Tile::class, true)); - /** - * @var Tile $tile - * @see Tile::__construct() - */ - $tile = new $class($level, new Vector3($nbt->getInt(self::TAG_X), $nbt->getInt(self::TAG_Y), $nbt->getInt(self::TAG_Z))); - $tile->readSaveData($nbt); - return $tile; - } - - /** - * @param string $baseClass - * @param Level $level - * @param Vector3 $pos - * @param Item $item - * - * @return Tile (instanceof $baseClass) - * @throws \InvalidArgumentException if the base class is not a registered tile - */ - public static function createFromItem(string $baseClass, Level $level, Vector3 $pos, Item $item) : Tile{ - $tile = self::create($baseClass, $level, $pos); - $tile->copyDataFromItem($item); - - return $tile; - } - - /** - * @param string $className - * @param string[] $saveNames - */ - public static function register(string $className, array $saveNames = []) : void{ - Utils::testValidInstance($className, Tile::class); - - self::$classMapping[$className] = $className; - - $shortName = (new \ReflectionClass($className))->getShortName(); - if(!in_array($shortName, $saveNames, true)){ - $saveNames[] = $shortName; - } - - foreach($saveNames as $name){ - self::$knownTiles[$name] = $className; - } - - self::$saveNames[$className] = $saveNames; - } - - /** - * @param string $baseClass Already-registered tile class to override - * @param string $newClass Class which extends the base class - * - * @throws \InvalidArgumentException if the base class is not a registered tile - */ - public static function override(string $baseClass, string $newClass) : void{ - if(!isset(self::$classMapping[$baseClass])){ - throw new \InvalidArgumentException("Class $baseClass is not a registered tile"); - } - - Utils::testValidInstance($newClass, $baseClass); - self::$classMapping[$baseClass] = $newClass; - } - - /** - * @param string $baseClass - * @param Level $level - * @param Vector3 $pos - * - * @return Tile (will be an instanceof $baseClass) - * @throws \InvalidArgumentException if the specified class is not a registered tile - */ - public static function create(string $baseClass, Level $level, Vector3 $pos) : Tile{ - if(isset(self::$classMapping[$baseClass])){ - $class = self::$classMapping[$baseClass]; - assert(is_a($class, $baseClass, true)); - /** - * @var Tile $tile - * @see Tile::__construct() - */ - $tile = new $class($level, $pos); - return $tile; - } - - throw new \InvalidArgumentException("Class $baseClass is not a registered tile"); - } - - /** - * Returns the short save name - * @return string - */ - public static function getSaveId() : string{ - if(!isset(self::$saveNames[static::class])){ - throw new \InvalidStateException("Tile is not registered"); - } - - reset(self::$saveNames[static::class]); - return current(self::$saveNames[static::class]); - } - public function __construct(Level $level, Vector3 $pos){ $this->timings = Timings::getTileEntityTimings($this); parent::__construct($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ(), $level); } /** + * @internal * Reads additional data from the CompoundTag on tile creation. * * @param CompoundTag $nbt */ - abstract protected function readSaveData(CompoundTag $nbt) : void; + abstract public function readSaveData(CompoundTag $nbt) : void; /** * Writes additional save data to a CompoundTag, not including generic things like ID and coordinates. @@ -209,7 +73,7 @@ abstract class Tile extends Position{ public function saveNBT() : CompoundTag{ $nbt = new CompoundTag(); - $nbt->setString(self::TAG_ID, static::getSaveId()); + $nbt->setString(self::TAG_ID, TileFactory::getSaveId(get_class($this))); $nbt->setInt(self::TAG_X, $this->x); $nbt->setInt(self::TAG_Y, $this->y); $nbt->setInt(self::TAG_Z, $this->z); @@ -223,7 +87,14 @@ abstract class Tile extends Position{ return $tag->getCount() > 0 ? $tag : null; } - protected function copyDataFromItem(Item $item) : void{ + /** + * @internal + * + * @param Item $item + * + * @throws \RuntimeException + */ + public function copyDataFromItem(Item $item) : void{ if($item->hasCustomBlockData()){ //TODO: check item root tag (MCPE doesn't use BlockEntityTag) $this->readSaveData($item->getCustomBlockData()); } diff --git a/src/pocketmine/tile/TileFactory.php b/src/pocketmine/tile/TileFactory.php new file mode 100644 index 0000000000..7073b619af --- /dev/null +++ b/src/pocketmine/tile/TileFactory.php @@ -0,0 +1,171 @@ + overridden class */ + private static $classMapping = []; + + private function __construct(){ + //NOOP + } + + public static function init(){ + self::register(Banner::class, ["Banner", "minecraft:banner"]); + self::register(Bed::class, ["Bed", "minecraft:bed"]); + self::register(Chest::class, ["Chest", "minecraft:chest"]); + self::register(EnchantTable::class, ["EnchantTable", "minecraft:enchanting_table"]); + self::register(EnderChest::class, ["EnderChest", "minecraft:ender_chest"]); + self::register(FlowerPot::class, ["FlowerPot", "minecraft:flower_pot"]); + self::register(Furnace::class, ["Furnace", "minecraft:furnace"]); + self::register(ItemFrame::class, ["ItemFrame"]); //this is an entity in PC + self::register(Sign::class, ["Sign", "minecraft:sign"]); + self::register(Skull::class, ["Skull", "minecraft:skull"]); + } + + /** + * @param string $className + * @param string[] $saveNames + */ + public static function register(string $className, array $saveNames = []) : void{ + Utils::testValidInstance($className, Tile::class); + + self::$classMapping[$className] = $className; + + $shortName = (new \ReflectionClass($className))->getShortName(); + if(!in_array($shortName, $saveNames, true)){ + $saveNames[] = $shortName; + } + + foreach($saveNames as $name){ + self::$knownTiles[$name] = $className; + } + + self::$saveNames[$className] = $saveNames; + } + + /** + * @param string $baseClass Already-registered tile class to override + * @param string $newClass Class which extends the base class + * + * @throws \InvalidArgumentException if the base class is not a registered tile + */ + public static function override(string $baseClass, string $newClass) : void{ + if(!isset(self::$classMapping[$baseClass])){ + throw new \InvalidArgumentException("Class $baseClass is not a registered tile"); + } + + Utils::testValidInstance($newClass, $baseClass); + self::$classMapping[$baseClass] = $newClass; + } + + /** + * @param string $baseClass + * @param Level $level + * @param Vector3 $pos + * + * @return Tile (will be an instanceof $baseClass) + * @throws \InvalidArgumentException if the specified class is not a registered tile + */ + public static function create(string $baseClass, Level $level, Vector3 $pos) : Tile{ + if(isset(self::$classMapping[$baseClass])){ + $class = self::$classMapping[$baseClass]; + assert(is_a($class, $baseClass, true)); + /** + * @var Tile $tile + * @see Tile::__construct() + */ + $tile = new $class($level, $pos); + + return $tile; + } + + throw new \InvalidArgumentException("Class $baseClass is not a registered tile"); + } + + /** + * @internal + * + * @param string $baseClass + * @param Level $level + * @param Vector3 $pos + * @param Item $item + * + * @return Tile (instanceof $baseClass) + * @throws \InvalidArgumentException if the base class is not a registered tile + */ + public static function createFromItem(string $baseClass, Level $level, Vector3 $pos, Item $item) : Tile{ + $tile = self::create($baseClass, $level, $pos); + $tile->copyDataFromItem($item); + + return $tile; + } + + /** + * @internal + * + * @param Level $level + * @param CompoundTag $nbt + * + * @return Tile|null + */ + public static function createFromData(Level $level, CompoundTag $nbt) : ?Tile{ + $type = $nbt->getString(Tile::TAG_ID, "", true); + if(!isset(self::$knownTiles[$type])){ + return null; + } + $class = self::$knownTiles[$type]; + assert(is_a($class, Tile::class, true)); + /** + * @var Tile $tile + * @see Tile::__construct() + */ + $tile = new $class($level, new Vector3($nbt->getInt(Tile::TAG_X), $nbt->getInt(Tile::TAG_Y), $nbt->getInt(Tile::TAG_Z))); + $tile->readSaveData($nbt); + + return $tile; + } + + public static function getSaveId(string $class) : string{ + if(isset(self::$saveNames[$class])){ + return reset(self::$saveNames[$class]); + } + throw new \InvalidArgumentException("Tile $class is not registered"); + } +} From 8663be85043e70e2ebfa24589607f53422be41aa Mon Sep 17 00:00:00 2001 From: Dylan T Date: Mon, 7 Jan 2019 00:59:16 +0000 Subject: [PATCH 0369/3224] moar issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 47 ++++--------------- .github/ISSUE_TEMPLATE/help---support.md | 2 +- .../security-dos-vulnerability.md | 12 +++++ 3 files changed, 23 insertions(+), 38 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/security-dos-vulnerability.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 83b9270c87..99a016aefe 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,6 +1,6 @@ --- name: Bug report -about: Report a bug in PocketMine-MP (not plugins) +about: Unexpected non-crash behaviour (except missing gameplay features) title: '' labels: '' assignees: '' @@ -8,56 +8,29 @@ assignees: '' --- ### Issue description - - - - - - Expected result: What were you expecting to happen? - Actual result: What actually happened? ### Steps to reproduce the issue - 1. ... 2. ... ### OS and versions - -* PocketMine-MP: + +* PocketMine-MP: * PHP: * Server OS: * Game version: PE/Win10 (delete as appropriate) ### Plugins -- Test on a clean server without plugins: is the issue reproducible without any plugins loaded? + -If the issue is **not** reproducible without plugins: -- Have you asked for help on our forums before creating an issue? -- Can you provide sample, *minimal* reproducing code for the issue? If so, paste it in the bottom section -- Paste your list of plugins here (use the 'plugins' command in PocketMine-MP) +- If you remove all plugins, does the issue still occur? +- If the issue is **not** reproducible without plugins: + - Have you asked for help on our forums before creating an issue? + - Can you provide sample, *minimal* reproducing code for the issue? If so, paste it in the bottom section ### Crashdump, backtrace or other files -- Do not paste crashdumps into an issue - please use our Crash Archive at https://crash.pmmp.io for submitting crash reports to not spam the issue tracker. Add links to your reports in the Crash Archive here. -- Please use gist or anything else to add other files and add links here - -* ... + + diff --git a/.github/ISSUE_TEMPLATE/help---support.md b/.github/ISSUE_TEMPLATE/help---support.md index 7c370b2d3a..a724460a6a 100644 --- a/.github/ISSUE_TEMPLATE/help---support.md +++ b/.github/ISSUE_TEMPLATE/help---support.md @@ -1,6 +1,6 @@ --- name: Help & support -about: Help & support +about: We don't accept support requests here. Try the links on the README. title: '' labels: Support request assignees: '' diff --git a/.github/ISSUE_TEMPLATE/security-dos-vulnerability.md b/.github/ISSUE_TEMPLATE/security-dos-vulnerability.md new file mode 100644 index 0000000000..c39833685e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/security-dos-vulnerability.md @@ -0,0 +1,12 @@ +--- +name: Security/DoS vulnerability +about: 'Bug or exploit that can be used to attack servers (hint: don''t report it + on a public issue tracker)' +title: '' +labels: 'Auto: Spam' +assignees: '' + +--- + +Please DO NOT report security vulnerabilities here. +Instead, send an email to team@pmmp.io or contact a developer directly, IN PRIVATE. From 4f50119b745436dcb37e9a8cf490cbf5d15199c3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 7 Jan 2019 14:45:44 +0000 Subject: [PATCH 0370/3224] LoginPacket: Cater for more error cases This now doesn't crash unexpectedly at the first sign of broken data. --- composer.json | 3 +- composer.lock | 64 ++++++++- .../network/mcpe/ProcessLoginTask.php | 2 +- .../network/mcpe/protocol/LoginPacket.php | 129 ++++++++++++------ src/pocketmine/utils/Utils.php | 26 +++- 5 files changed, 178 insertions(+), 46 deletions(-) diff --git a/composer.json b/composer.json index 0cc178ebd3..ee23b9a700 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,8 @@ "pocketmine/math": "dev-master", "pocketmine/snooze": "^0.1.0", "daverandom/callback-validator": "dev-master", - "adhocore/json-comment": "^0.0.7" + "adhocore/json-comment": "^0.0.7", + "particle/validator": "^2.3" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index f7d13c0da4..6391d98f15 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "cdf1ae08bd2f3e13b0a766a835ed8cb8", + "content-hash": "a011d12545207848fb8fe0fccb1cf18c", "packages": [ { "name": "adhocore/json-comment", @@ -231,6 +231,68 @@ ], "time": "2018-12-03T18:17:01+00:00" }, + { + "name": "particle/validator", + "version": "v2.3.3", + "source": { + "type": "git", + "url": "https://github.com/particle-php/Validator.git", + "reference": "becaa89160fe220ebd9e9cd10addc62cf2adf3f0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/particle-php/Validator/zipball/becaa89160fe220ebd9e9cd10addc62cf2adf3f0", + "reference": "becaa89160fe220ebd9e9cd10addc62cf2adf3f0", + "shasum": "" + }, + "require": { + "php": ">=5.4" + }, + "require-dev": { + "byrokrat/checkdigit": "^1.0", + "giggsey/libphonenumber-for-php": "^7.2", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "2.*" + }, + "suggest": { + "byrokrat/checkdigit": "If you want to use CreditCard validation rule, this library must be installed.", + "giggsey/libphonenumber-for-php": "If you want to use Phone validation rule, this library must be installed." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Particle\\Validator\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Berry Langerak", + "email": "berry@berryllium.nl", + "role": "developer" + }, + { + "name": "Rick van der Staaij", + "homepage": "http://rickvanderstaaij.nl", + "role": "Developer" + } + ], + "description": "Flexible and highly usable validation library with no dependencies.", + "homepage": "http://github.com/particle-php/validator", + "keywords": [ + "validation", + "validator" + ], + "time": "2018-09-12T08:03:23+00:00" + }, { "name": "pocketmine/binaryutils", "version": "0.1.5", diff --git a/src/pocketmine/network/mcpe/ProcessLoginTask.php b/src/pocketmine/network/mcpe/ProcessLoginTask.php index 12c06cdfc5..ab7a054c1f 100644 --- a/src/pocketmine/network/mcpe/ProcessLoginTask.php +++ b/src/pocketmine/network/mcpe/ProcessLoginTask.php @@ -138,7 +138,7 @@ class ProcessLoginTask extends AsyncTask{ $currentKey = null; $first = true; - foreach($packet->chainData["chain"] as $jwt){ + foreach($packet->chainDataJwt as $jwt){ $this->validateToken($jwt, $currentKey, $first); if($first){ $first = false; diff --git a/src/pocketmine/network/mcpe/protocol/LoginPacket.php b/src/pocketmine/network/mcpe/protocol/LoginPacket.php index 7d763fad3b..e7d2edef5b 100644 --- a/src/pocketmine/network/mcpe/protocol/LoginPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LoginPacket.php @@ -26,19 +26,34 @@ namespace pocketmine\network\mcpe\protocol; #include +use Particle\Validator\Validator; use pocketmine\entity\Skin; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\utils\BinaryStream; use pocketmine\utils\Utils; +use function array_filter; use function base64_decode; -use function get_class; +use function count; +use function implode; +use function is_array; use function json_decode; +use function json_last_error_msg; class LoginPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::LOGIN_PACKET; public const EDITION_POCKET = 0; + public const I_CLIENT_RANDOM_ID = 'ClientRandomId'; + public const I_SERVER_ADDRESS = 'ServerAddress'; + public const I_LANGUAGE_CODE = 'LanguageCode'; + + public const I_SKIN_ID = 'SkinId'; + public const I_SKIN_DATA = 'SkinData'; + public const I_CAPE_DATA = 'CapeData'; + public const I_GEOMETRY_NAME = 'SkinGeometryName'; + public const I_GEOMETRY_DATA = 'SkinGeometry'; + /** @var string */ public $username; /** @var int */ @@ -58,8 +73,8 @@ class LoginPacket extends DataPacket{ /** @var Skin|null */ public $skin; - /** @var array (the "chain" index contains one or more JWTs) */ - public $chainData = []; + /** @var string[] array of encoded JWT */ + public $chainDataJwt = []; /** @var string */ public $clientDataJwt; /** @var array decoded payload of the clientData JWT */ @@ -83,65 +98,99 @@ class LoginPacket extends DataPacket{ protected function decodePayload() : void{ $this->protocol = $this->getInt(); + $this->decodeConnectionRequest(); + } - try{ - $this->decodeConnectionRequest(); - }catch(\Throwable $e){ - if($this->protocol === ProtocolInfo::CURRENT_PROTOCOL){ - throw $e; - } - - $logger = \GlobalLogger::get(); - $logger->debug(get_class($e) . " was thrown while decoding connection request in login (protocol version " . ($this->protocol ?? "unknown") . "): " . $e->getMessage()); - foreach(Utils::printableTrace($e->getTrace()) as $line){ - $logger->debug($line); + /** + * @param Validator $v + * @param string $name + * @param $data + * + * @throws \UnexpectedValueException + */ + private static function validate(Validator $v, string $name, $data) : void{ + $result = $v->validate($data); + if($result->isNotValid()){ + $messages = []; + foreach($result->getFailures() as $f){ + $messages[] = $f->format(); } + throw new \UnexpectedValueException("Failed to validate '$name': " . implode(", ", $messages)); } } + /** + * @throws \OutOfBoundsException + * @throws \UnexpectedValueException + */ protected function decodeConnectionRequest() : void{ $buffer = new BinaryStream($this->getString()); - $this->chainData = json_decode($buffer->get($buffer->getLInt()), true); + $chainData = json_decode($buffer->get($buffer->getLInt()), true); + if(!is_array($chainData)){ + throw new \UnexpectedValueException("Failed to decode chainData JSON: " . json_last_error_msg()); + } + + $vd = new Validator(); + $vd->required('chain')->isArray()->callback(function(array $data) : bool{ + return count($data) === 3 and count(array_filter($data, '\is_string')) === count($data); + }); + self::validate($vd, "chainData", $chainData); + + $this->chainDataJwt = $chainData['chain']; $hasExtraData = false; - foreach($this->chainData["chain"] as $chain){ - $webtoken = Utils::decodeJWT($chain); - if(isset($webtoken["extraData"])){ + foreach($this->chainDataJwt as $k => $chain){ + //validate every chain element + $claims = Utils::getJwtClaims($chain); + if(isset($claims["extraData"])){ + if(!is_array($claims["extraData"])){ + throw new \UnexpectedValueException("'extraData' key should be an array"); + } if($hasExtraData){ - throw new \RuntimeException("Found 'extraData' multiple times in key chain"); + throw new \UnexpectedValueException("Found 'extraData' more than once in chainData"); } $hasExtraData = true; - if(isset($webtoken["extraData"]["displayName"])){ - $this->username = $webtoken["extraData"]["displayName"]; - } - if(isset($webtoken["extraData"]["identity"])){ - $this->clientUUID = $webtoken["extraData"]["identity"]; - } - if(isset($webtoken["extraData"]["XUID"])){ - $this->xuid = $webtoken["extraData"]["XUID"]; - } - } - if(isset($webtoken["identityPublicKey"])){ - $this->identityPublicKey = $webtoken["identityPublicKey"]; + $extraV = new Validator(); + $extraV->required('displayName')->string(); + $extraV->required('identity')->uuid(); + $extraV->required('XUID')->string()->digits(); + self::validate($extraV, "chain.$k.extraData", $claims['extraData']); + + $this->username = $claims["extraData"]["displayName"]; + $this->clientUUID = $claims["extraData"]["identity"]; + $this->xuid = $claims["extraData"]["XUID"]; } } $this->clientDataJwt = $buffer->get($buffer->getLInt()); - $this->clientData = Utils::decodeJWT($this->clientDataJwt); + $clientData = Utils::getJwtClaims($this->clientDataJwt); - $this->clientId = $this->clientData["ClientRandomId"] ?? null; - $this->serverAddress = $this->clientData["ServerAddress"] ?? null; + $v = new Validator(); + $v->required(self::I_CLIENT_RANDOM_ID)->integer(); + $v->required(self::I_SERVER_ADDRESS)->string(); + $v->required(self::I_LANGUAGE_CODE)->string(); - $this->locale = $this->clientData["LanguageCode"] ?? "en_US"; + $v->required(self::I_SKIN_ID)->string(); + $v->required(self::I_SKIN_DATA)->string(); + $v->required(self::I_CAPE_DATA, null, true)->string(); + $v->required(self::I_GEOMETRY_NAME)->string(); + $v->required(self::I_GEOMETRY_DATA, null, true)->string(); + self::validate($v, 'clientData', $clientData); + + $this->clientData = $clientData; + + $this->clientId = $this->clientData[self::I_CLIENT_RANDOM_ID]; + $this->serverAddress = $this->clientData[self::I_SERVER_ADDRESS]; + $this->locale = $this->clientData[self::I_LANGUAGE_CODE]; $this->skin = new Skin( - $this->clientData["SkinId"] ?? "", - base64_decode($this->clientData["SkinData"] ?? ""), - base64_decode($this->clientData["CapeData"] ?? ""), - $this->clientData["SkinGeometryName"] ?? "", - base64_decode($this->clientData["SkinGeometry"] ?? "") + $this->clientData[self::I_SKIN_ID], + base64_decode($this->clientData[self::I_SKIN_DATA]), + base64_decode($this->clientData[self::I_CAPE_DATA]), + $this->clientData[self::I_GEOMETRY_NAME], + base64_decode($this->clientData[self::I_GEOMETRY_DATA]) ); } diff --git a/src/pocketmine/utils/Utils.php b/src/pocketmine/utils/Utils.php index 0780126c8a..58bfab4f72 100644 --- a/src/pocketmine/utils/Utils.php +++ b/src/pocketmine/utils/Utils.php @@ -59,6 +59,7 @@ use function is_object; use function is_readable; use function is_string; use function json_decode; +use function json_last_error_msg; use function memory_get_usage; use function ob_end_clean; use function ob_get_contents; @@ -480,10 +481,29 @@ class Utils{ return proc_close($process); } - public static function decodeJWT(string $token) : array{ - list($headB64, $payloadB64, $sigB64) = explode(".", $token); + /** + * @param string $token + * + * @return array of claims + * + * @throws \UnexpectedValueException + */ + public static function getJwtClaims(string $token) : array{ + $v = explode(".", $token); + if(count($v) !== 3){ + throw new \UnexpectedValueException("Expected exactly 3 JWT parts, got " . count($v)); + } + $payloadB64 = $v[1]; + $payloadJSON = base64_decode(strtr($payloadB64, '-_', '+/'), true); + if($payloadJSON === false){ + throw new \UnexpectedValueException("Invalid base64 JWT payload"); + } + $result = json_decode($payloadJSON, true); + if(!is_array($result)){ + throw new \UnexpectedValueException("Failed to decode JWT payload JSON: " . json_last_error_msg()); + } - return json_decode(base64_decode(strtr($payloadB64, '-_', '+/'), true), true); + return $result; } public static function kill($pid) : void{ From 9c16caf27ba869674e684de77b327b828c6d2bfc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 7 Jan 2019 22:23:51 +0000 Subject: [PATCH 0371/3224] Fixed an edge-case in AvailableCommandsPacket decoding --- .../network/mcpe/protocol/AvailableCommandsPacket.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php index f62bb0fe0d..037a9374b0 100644 --- a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php @@ -144,8 +144,12 @@ class AvailableCommandsPacket extends DataPacket{ $retval->enumName = $this->getString(); for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ + $index = $this->getEnumValueIndex(); + if(!isset($this->enumValues[$index])){ + throw new \UnexpectedValueException("Invalid enum value index $index"); + } //Get the enum value from the initial pile of mess - $retval->enumValues[] = $this->enumValues[$this->getEnumValueIndex()]; + $retval->enumValues[] = $this->enumValues[$index]; } return $retval; From 2924303169439f5d9347c66bbeab3143f6a06891 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 7 Jan 2019 22:26:22 +0000 Subject: [PATCH 0372/3224] Sync NBT dependency --- composer.lock | 30 ++++++------ src/pocketmine/Player.php | 4 +- src/pocketmine/Server.php | 6 +-- src/pocketmine/item/Item.php | 8 ++-- .../level/format/io/data/BedrockLevelData.php | 8 ++-- .../level/format/io/data/JavaLevelData.php | 8 ++-- .../level/format/io/leveldb/LevelDB.php | 6 +-- .../io/region/LegacyAnvilChunkTrait.php | 6 +-- .../level/format/io/region/McRegion.php | 6 +-- .../network/mcpe/NetworkBinaryStream.php | 8 ++-- ...NBTStream.php => NetworkNbtSerializer.php} | 46 +++++++++---------- src/pocketmine/tile/Spawnable.php | 6 +-- 12 files changed, 69 insertions(+), 73 deletions(-) rename src/pocketmine/network/mcpe/{NetworkLittleEndianNBTStream.php => NetworkNbtSerializer.php} (52%) diff --git a/composer.lock b/composer.lock index 6391d98f15..f38a63753e 100644 --- a/composer.lock +++ b/composer.lock @@ -233,16 +233,16 @@ }, { "name": "particle/validator", - "version": "v2.3.3", + "version": "v2.3.4", "source": { "type": "git", "url": "https://github.com/particle-php/Validator.git", - "reference": "becaa89160fe220ebd9e9cd10addc62cf2adf3f0" + "reference": "657c7543e51938dd9d114750e49d695129527a7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/particle-php/Validator/zipball/becaa89160fe220ebd9e9cd10addc62cf2adf3f0", - "reference": "becaa89160fe220ebd9e9cd10addc62cf2adf3f0", + "url": "https://api.github.com/repos/particle-php/Validator/zipball/657c7543e51938dd9d114750e49d695129527a7a", + "reference": "657c7543e51938dd9d114750e49d695129527a7a", "shasum": "" }, "require": { @@ -291,20 +291,20 @@ "validation", "validator" ], - "time": "2018-09-12T08:03:23+00:00" + "time": "2019-01-07T13:39:13+00:00" }, { "name": "pocketmine/binaryutils", - "version": "0.1.5", + "version": "0.1.6", "source": { "type": "git", "url": "https://github.com/pmmp/BinaryUtils.git", - "reference": "03361b0d78ef2b400a99e96406aa594a5bc1c4ed" + "reference": "53cbb5a958130a6c6b5a4c511e623f4d401c1476" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/03361b0d78ef2b400a99e96406aa594a5bc1c4ed", - "reference": "03361b0d78ef2b400a99e96406aa594a5bc1c4ed", + "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/53cbb5a958130a6c6b5a4c511e623f4d401c1476", + "reference": "53cbb5a958130a6c6b5a4c511e623f4d401c1476", "shasum": "" }, "require": { @@ -322,10 +322,10 @@ ], "description": "Classes and methods for conveniently handling binary data", "support": { - "source": "https://github.com/pmmp/BinaryUtils/tree/0.1.5", + "source": "https://github.com/pmmp/BinaryUtils/tree/0.1.6", "issues": "https://github.com/pmmp/BinaryUtils/issues" }, - "time": "2019-01-04T13:32:11+00:00" + "time": "2019-01-06T15:20:40+00:00" }, { "name": "pocketmine/math", @@ -372,12 +372,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "863b2e509485baffd4897cd6fa8e98e7e7e5ae14" + "reference": "ead8577bf3ff0eb8dd3c19c40a67a9ee6d06783a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/863b2e509485baffd4897cd6fa8e98e7e7e5ae14", - "reference": "863b2e509485baffd4897cd6fa8e98e7e7e5ae14", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/ead8577bf3ff0eb8dd3c19c40a67a9ee6d06783a", + "reference": "ead8577bf3ff0eb8dd3c19c40a67a9ee6d06783a", "shasum": "" }, "require": { @@ -405,7 +405,7 @@ "source": "https://github.com/pmmp/NBT/tree/master", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2019-01-04T15:32:10+00:00" + "time": "2019-01-07T21:01:32+00:00" }, { "name": "pocketmine/raklib", diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 41409e66f9..776bfd733f 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -94,7 +94,7 @@ use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\NetworkCipher; -use pocketmine\network\mcpe\NetworkLittleEndianNBTStream; +use pocketmine\network\mcpe\NetworkNbtSerializer; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\ProcessLoginTask; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; @@ -2465,7 +2465,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $t = $this->level->getTile($pos); if($t instanceof Spawnable){ - $nbt = new NetworkLittleEndianNBTStream(); + $nbt = new NetworkNbtSerializer(); $compound = $nbt->read($packet->namedtag); if(!$t->updateCompoundTag($compound, $this)){ $t->spawnTo($this); diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index cd3b92920b..2156ef3983 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -61,7 +61,7 @@ use pocketmine\level\LevelException; use pocketmine\metadata\EntityMetadataStore; use pocketmine\metadata\LevelMetadataStore; use pocketmine\metadata\PlayerMetadataStore; -use pocketmine\nbt\BigEndianNBTStream; +use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; @@ -812,7 +812,7 @@ class Server{ if($this->shouldSavePlayerData()){ if(file_exists($path . "$name.dat")){ try{ - $nbt = new BigEndianNBTStream(); + $nbt = new BigEndianNbtSerializer(); return $nbt->readCompressed(file_get_contents($path . "$name.dat")); }catch(\Throwable $e){ //zlib decode error / corrupt data rename($path . "$name.dat", $path . "$name.dat.bak"); @@ -875,7 +875,7 @@ class Server{ $ev->call(); if(!$ev->isCancelled()){ - $nbt = new BigEndianNBTStream(); + $nbt = new BigEndianNbtSerializer(); try{ file_put_contents($this->getDataPath() . "players/" . strtolower($name) . ".dat", $nbt->writeCompressed($ev->getSaveData())); }catch(\Throwable $e){ diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 1e7e640842..214efe1df0 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -33,7 +33,7 @@ use pocketmine\entity\Entity; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\EnchantmentInstance; use pocketmine\math\Vector3; -use pocketmine\nbt\LittleEndianNBTStream; +use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; @@ -61,7 +61,7 @@ class Item implements ItemIds, \JsonSerializable{ public const TAG_DISPLAY_LORE = "Lore"; - /** @var LittleEndianNBTStream */ + /** @var LittleEndianNbtSerializer */ private static $cachedParser = null; private static function parseCompoundTag(string $tag) : CompoundTag{ @@ -70,7 +70,7 @@ class Item implements ItemIds, \JsonSerializable{ } if(self::$cachedParser === null){ - self::$cachedParser = new LittleEndianNBTStream(); + self::$cachedParser = new LittleEndianNbtSerializer(); } return self::$cachedParser->read($tag); @@ -78,7 +78,7 @@ class Item implements ItemIds, \JsonSerializable{ private static function writeCompoundTag(CompoundTag $tag) : string{ if(self::$cachedParser === null){ - self::$cachedParser = new LittleEndianNBTStream(); + self::$cachedParser = new LittleEndianNbtSerializer(); } return self::$cachedParser->write($tag); diff --git a/src/pocketmine/level/format/io/data/BedrockLevelData.php b/src/pocketmine/level/format/io/data/BedrockLevelData.php index 1f4f9f0ba3..bfdfdf1112 100644 --- a/src/pocketmine/level/format/io/data/BedrockLevelData.php +++ b/src/pocketmine/level/format/io/data/BedrockLevelData.php @@ -27,7 +27,7 @@ use pocketmine\level\format\io\exception\UnsupportedLevelFormatException; use pocketmine\level\generator\Flat; use pocketmine\level\generator\GeneratorManager; use pocketmine\level\Level; -use pocketmine\nbt\LittleEndianNBTStream; +use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\FloatTag; @@ -97,13 +97,13 @@ class BedrockLevelData extends BaseNbtLevelData{ new StringTag("generatorOptions", $options["preset"] ?? "") ]); - $nbt = new LittleEndianNBTStream(); + $nbt = new LittleEndianNbtSerializer(); $buffer = $nbt->write($levelData); file_put_contents($path . "level.dat", Binary::writeLInt(self::CURRENT_STORAGE_VERSION) . Binary::writeLInt(strlen($buffer)) . $buffer); } protected function load() : ?CompoundTag{ - $nbt = new LittleEndianNBTStream(); + $nbt = new LittleEndianNbtSerializer(); $levelData = $nbt->read(substr(file_get_contents($this->dataPath), 8)); $version = $levelData->getInt("StorageVersion", INT32_MAX, true); @@ -148,7 +148,7 @@ class BedrockLevelData extends BaseNbtLevelData{ $this->compoundTag->setInt("NetworkVersion", ProtocolInfo::CURRENT_PROTOCOL); $this->compoundTag->setInt("StorageVersion", self::CURRENT_STORAGE_VERSION); - $nbt = new LittleEndianNBTStream(); + $nbt = new LittleEndianNbtSerializer(); $buffer = $nbt->write($this->compoundTag); file_put_contents($this->dataPath, Binary::writeLInt(self::CURRENT_STORAGE_VERSION) . Binary::writeLInt(strlen($buffer)) . $buffer); } diff --git a/src/pocketmine/level/format/io/data/JavaLevelData.php b/src/pocketmine/level/format/io/data/JavaLevelData.php index 76d7268435..893d7cef0a 100644 --- a/src/pocketmine/level/format/io/data/JavaLevelData.php +++ b/src/pocketmine/level/format/io/data/JavaLevelData.php @@ -25,7 +25,7 @@ namespace pocketmine\level\format\io\data; use pocketmine\level\generator\GeneratorManager; use pocketmine\level\Level; -use pocketmine\nbt\BigEndianNBTStream; +use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\FloatTag; @@ -61,7 +61,7 @@ class JavaLevelData extends BaseNbtLevelData{ new StringTag("LevelName", $name), new CompoundTag("GameRules", []) ]); - $nbt = new BigEndianNBTStream(); + $nbt = new BigEndianNbtSerializer(); $buffer = $nbt->writeCompressed(new CompoundTag("", [ $levelData ])); @@ -69,7 +69,7 @@ class JavaLevelData extends BaseNbtLevelData{ } protected function load() : ?CompoundTag{ - $nbt = new BigEndianNBTStream(); + $nbt = new BigEndianNbtSerializer(); $levelData = $nbt->readCompressed(file_get_contents($this->dataPath)); if($levelData->hasTag("Data", CompoundTag::class)){ return $levelData->getCompoundTag("Data"); @@ -90,7 +90,7 @@ class JavaLevelData extends BaseNbtLevelData{ } public function save() : void{ - $nbt = new BigEndianNBTStream(); + $nbt = new BigEndianNbtSerializer(); $this->compoundTag->setName("Data"); $buffer = $nbt->writeCompressed(new CompoundTag("", [ $this->compoundTag diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index 18fd3f5ec8..8badadf354 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -31,7 +31,7 @@ use pocketmine\level\format\io\exception\UnsupportedChunkFormatException; use pocketmine\level\format\io\exception\UnsupportedLevelFormatException; use pocketmine\level\format\io\LevelData; use pocketmine\level\format\SubChunk; -use pocketmine\nbt\LittleEndianNBTStream; +use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\tag\CompoundTag; use pocketmine\utils\Binary; use pocketmine\utils\BinaryStream; @@ -239,7 +239,7 @@ class LevelDB extends BaseLevelProvider{ throw new UnsupportedChunkFormatException("don't know how to decode chunk format version $chunkVersion"); } - $nbt = new LittleEndianNBTStream(); + $nbt = new LittleEndianNbtSerializer(); /** @var CompoundTag[] $entities */ $entities = []; @@ -332,7 +332,7 @@ class LevelDB extends BaseLevelProvider{ */ private function writeTags(array $targets, string $index) : void{ if(!empty($targets)){ - $nbt = new LittleEndianNBTStream(); + $nbt = new LittleEndianNbtSerializer(); $this->db->put($index, $nbt->writeMultiple($targets)); }else{ $this->db->delete($index); diff --git a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php b/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php index 759da6d9b8..86b69eedea 100644 --- a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php @@ -27,7 +27,7 @@ use pocketmine\level\format\Chunk; use pocketmine\level\format\io\ChunkUtils; use pocketmine\level\format\io\exception\CorruptedChunkException; use pocketmine\level\format\SubChunk; -use pocketmine\nbt\BigEndianNBTStream; +use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntArrayTag; @@ -89,14 +89,14 @@ trait LegacyAnvilChunkTrait{ //TODO: TileTicks - $writer = new BigEndianNBTStream(); + $writer = new BigEndianNbtSerializer(); return $writer->writeCompressed(new CompoundTag("", [$nbt]), ZLIB_ENCODING_DEFLATE, RegionLoader::$COMPRESSION_LEVEL); } abstract protected function serializeSubChunk(SubChunk $subChunk) : CompoundTag; protected function deserializeChunk(string $data) : Chunk{ - $nbt = new BigEndianNBTStream(); + $nbt = new BigEndianNbtSerializer(); $chunk = $nbt->readCompressed($data); if(!$chunk->hasTag("Level")){ throw new CorruptedChunkException("'Level' key is missing from chunk NBT"); diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index 165840d8fa..389c6e9398 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -27,7 +27,7 @@ use pocketmine\level\format\Chunk; use pocketmine\level\format\io\ChunkUtils; use pocketmine\level\format\io\exception\CorruptedChunkException; use pocketmine\level\format\SubChunk; -use pocketmine\nbt\BigEndianNBTStream; +use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\CompoundTag; @@ -95,7 +95,7 @@ class McRegion extends RegionLevelProvider{ $nbt->setTag(new ListTag("TileEntities", $tiles, NBT::TAG_Compound)); - $writer = new BigEndianNBTStream(); + $writer = new BigEndianNbtSerializer(); return $writer->writeCompressed(new CompoundTag("", [$nbt]), ZLIB_ENCODING_DEFLATE, RegionLoader::$COMPRESSION_LEVEL); } @@ -106,7 +106,7 @@ class McRegion extends RegionLevelProvider{ * @throws CorruptedChunkException */ protected function deserializeChunk(string $data) : Chunk{ - $nbt = new BigEndianNBTStream(); + $nbt = new BigEndianNbtSerializer(); $chunk = $nbt->readCompressed($data); if(!$chunk->hasTag("Level")){ throw new CorruptedChunkException("'Level' key is missing from chunk NBT"); diff --git a/src/pocketmine/network/mcpe/NetworkBinaryStream.php b/src/pocketmine/network/mcpe/NetworkBinaryStream.php index 565e5779a2..5b4a8523b4 100644 --- a/src/pocketmine/network/mcpe/NetworkBinaryStream.php +++ b/src/pocketmine/network/mcpe/NetworkBinaryStream.php @@ -30,7 +30,7 @@ use pocketmine\entity\Entity; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\Vector3; -use pocketmine\nbt\LittleEndianNBTStream; +use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\network\mcpe\protocol\types\CommandOriginData; use pocketmine\network\mcpe\protocol\types\EntityLink; use pocketmine\utils\BinaryStream; @@ -39,7 +39,7 @@ use function count; use function strlen; class NetworkBinaryStream extends BinaryStream{ - /** @var LittleEndianNBTStream */ + /** @var LittleEndianNbtSerializer */ private static $itemNbtSerializer = null; public function getString() : string{ @@ -85,7 +85,7 @@ class NetworkBinaryStream extends BinaryStream{ $compound = null; if($nbtLen > 0){ if(self::$itemNbtSerializer === null){ - self::$itemNbtSerializer = new LittleEndianNBTStream(); + self::$itemNbtSerializer = new LittleEndianNbtSerializer(); } $compound = self::$itemNbtSerializer->read($this->get($nbtLen)); } @@ -119,7 +119,7 @@ class NetworkBinaryStream extends BinaryStream{ $nbtLen = 0; if($item->hasNamedTag()){ if(self::$itemNbtSerializer === null){ - self::$itemNbtSerializer = new LittleEndianNBTStream(); + self::$itemNbtSerializer = new LittleEndianNbtSerializer(); } $nbt = self::$itemNbtSerializer->write($item->getNamedTag()); $nbtLen = strlen($nbt); diff --git a/src/pocketmine/network/mcpe/NetworkLittleEndianNBTStream.php b/src/pocketmine/network/mcpe/NetworkNbtSerializer.php similarity index 52% rename from src/pocketmine/network/mcpe/NetworkLittleEndianNBTStream.php rename to src/pocketmine/network/mcpe/NetworkNbtSerializer.php index 3f136463a5..689dcb7baf 100644 --- a/src/pocketmine/network/mcpe/NetworkLittleEndianNBTStream.php +++ b/src/pocketmine/network/mcpe/NetworkNbtSerializer.php @@ -23,59 +23,55 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; -use pocketmine\nbt\LittleEndianNBTStream; +use pocketmine\nbt\LittleEndianNbtSerializer; use function count; use function strlen; -#ifndef COMPILE -use pocketmine\utils\Binary; -#endif -#include +class NetworkNbtSerializer extends LittleEndianNbtSerializer{ -class NetworkLittleEndianNBTStream extends LittleEndianNBTStream{ - - public function getInt() : int{ - return Binary::readVarInt($this->buffer, $this->offset); + public function readInt() : int{ + return $this->buffer->getVarInt(); } - public function putInt(int $v) : void{ - $this->put(Binary::writeVarInt($v)); + public function writeInt(int $v) : void{ + $this->buffer->putVarInt($v); } - public function getLong() : int{ - return Binary::readVarLong($this->buffer, $this->offset); + public function readLong() : int{ + return $this->buffer->getVarLong(); } - public function putLong(int $v) : void{ - $this->put(Binary::writeVarLong($v)); + public function writeLong(int $v) : void{ + $this->buffer->putVarLong($v); } - public function getString() : string{ - return $this->get(Binary::readUnsignedVarInt($this->buffer, $this->offset)); + public function readString() : string{ + return $this->buffer->get($this->buffer->getUnsignedVarInt()); } - public function putString(string $v) : void{ + public function writeString(string $v) : void{ $len = strlen($v); if($len > 32767){ throw new \InvalidArgumentException("NBT strings cannot be longer than 32767 bytes, got $len bytes"); } - $this->put(Binary::writeUnsignedVarInt($len) . $v); + $this->buffer->putUnsignedVarInt($len); + $this->buffer->put($v); } - public function getIntArray() : array{ - $len = $this->getInt(); //varint + public function readIntArray() : array{ + $len = $this->readInt(); //varint $ret = []; for($i = 0; $i < $len; ++$i){ - $ret[] = $this->getInt(); //varint + $ret[] = $this->readInt(); //varint } return $ret; } - public function putIntArray(array $array) : void{ - $this->putInt(count($array)); //varint + public function writeIntArray(array $array) : void{ + $this->writeInt(count($array)); //varint foreach($array as $v){ - $this->putInt($v); //varint + $this->writeInt($v); //varint } } } diff --git a/src/pocketmine/tile/Spawnable.php b/src/pocketmine/tile/Spawnable.php index b4954ffb1c..10f2729018 100644 --- a/src/pocketmine/tile/Spawnable.php +++ b/src/pocketmine/tile/Spawnable.php @@ -26,7 +26,7 @@ namespace pocketmine\tile; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\StringTag; -use pocketmine\network\mcpe\NetworkLittleEndianNBTStream; +use pocketmine\network\mcpe\NetworkNbtSerializer; use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\Player; use function get_class; @@ -37,7 +37,7 @@ abstract class Spawnable extends Tile{ /** @var bool */ private $dirty = true; //default dirty, until it's been spawned appropriately on the level - /** @var NetworkLittleEndianNBTStream|null */ + /** @var NetworkNbtSerializer|null */ private static $nbtWriter = null; public function createSpawnPacket() : BlockEntityDataPacket{ @@ -95,7 +95,7 @@ abstract class Spawnable extends Tile{ final public function getSerializedSpawnCompound() : string{ if($this->spawnCompoundCache === null){ if(self::$nbtWriter === null){ - self::$nbtWriter = new NetworkLittleEndianNBTStream(); + self::$nbtWriter = new NetworkNbtSerializer(); } $this->spawnCompoundCache = self::$nbtWriter->write($this->getSpawnCompound()); From 8452c7bdbd771e0e9f630236825e037bda770aa8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 9 Jan 2019 00:18:55 +0000 Subject: [PATCH 0373/3224] Sync composer dependencies --- composer.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/composer.lock b/composer.lock index 7d409d8aa3..f43eb58736 100644 --- a/composer.lock +++ b/composer.lock @@ -92,16 +92,16 @@ }, { "name": "pocketmine/binaryutils", - "version": "0.1.5", + "version": "0.1.7", "source": { "type": "git", "url": "https://github.com/pmmp/BinaryUtils.git", - "reference": "03361b0d78ef2b400a99e96406aa594a5bc1c4ed" + "reference": "3403751da9d39853b43426085cd242173baadd2b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/03361b0d78ef2b400a99e96406aa594a5bc1c4ed", - "reference": "03361b0d78ef2b400a99e96406aa594a5bc1c4ed", + "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/3403751da9d39853b43426085cd242173baadd2b", + "reference": "3403751da9d39853b43426085cd242173baadd2b", "shasum": "" }, "require": { @@ -119,10 +119,10 @@ ], "description": "Classes and methods for conveniently handling binary data", "support": { - "source": "https://github.com/pmmp/BinaryUtils/tree/0.1.5", + "source": "https://github.com/pmmp/BinaryUtils/tree/0.1.7", "issues": "https://github.com/pmmp/BinaryUtils/issues" }, - "time": "2019-01-04T13:32:11+00:00" + "time": "2019-01-07T15:59:50+00:00" }, { "name": "pocketmine/math", @@ -160,16 +160,16 @@ }, { "name": "pocketmine/nbt", - "version": "0.2.4", + "version": "0.2.5", "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "05dddb51830fd8f3b6c93e553abe07643ec96fc5" + "reference": "0b290fa0f5b44835ebeea8146c9ac960cac833f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/05dddb51830fd8f3b6c93e553abe07643ec96fc5", - "reference": "05dddb51830fd8f3b6c93e553abe07643ec96fc5", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/0b290fa0f5b44835ebeea8146c9ac960cac833f5", + "reference": "0b290fa0f5b44835ebeea8146c9ac960cac833f5", "shasum": "" }, "require": { @@ -194,10 +194,10 @@ ], "description": "PHP library for working with Named Binary Tags", "support": { - "source": "https://github.com/pmmp/NBT/tree/0.2.4", + "source": "https://github.com/pmmp/NBT/tree/0.2.5", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2019-01-04T15:28:44+00:00" + "time": "2019-01-07T17:28:16+00:00" }, { "name": "pocketmine/raklib", From cc230034f9ea12e692a56f0d04d69c9a5d8dd5ee Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 9 Jan 2019 14:00:38 +0000 Subject: [PATCH 0374/3224] Fixed TransactionData->actions default value, closes #2652 --- src/pocketmine/network/mcpe/protocol/types/TransactionData.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/protocol/types/TransactionData.php b/src/pocketmine/network/mcpe/protocol/types/TransactionData.php index fc40262f0f..9c183a1b54 100644 --- a/src/pocketmine/network/mcpe/protocol/types/TransactionData.php +++ b/src/pocketmine/network/mcpe/protocol/types/TransactionData.php @@ -28,7 +28,7 @@ use function count; abstract class TransactionData{ /** @var NetworkInventoryAction[] */ - protected $actions; + protected $actions = []; /** * @return NetworkInventoryAction[] From 5d8fa2e126a92dae40fcb1aaab1aa22f21b44234 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 9 Jan 2019 19:04:12 +0000 Subject: [PATCH 0375/3224] Crash main server thread when RakLib dies this way we get crashdumps and find out what's actually wrong with RakLib in the wild. --- composer.lock | 8 ++++---- src/pocketmine/network/mcpe/RakLibInterface.php | 6 +++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/composer.lock b/composer.lock index b8a4d03989..9631541815 100644 --- a/composer.lock +++ b/composer.lock @@ -413,12 +413,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "8f189b687d39489e422bb30be984a33763f29662" + "reference": "2f5dfdaa28ff69d72cd1682faa521e18b17a15ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/8f189b687d39489e422bb30be984a33763f29662", - "reference": "8f189b687d39489e422bb30be984a33763f29662", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/2f5dfdaa28ff69d72cd1682faa521e18b17a15ef", + "reference": "2f5dfdaa28ff69d72cd1682faa521e18b17a15ef", "shasum": "" }, "require": { @@ -446,7 +446,7 @@ "source": "https://github.com/pmmp/RakLib/tree/master", "issues": "https://github.com/pmmp/RakLib/issues" }, - "time": "2019-01-04T15:05:24+00:00" + "time": "2019-01-09T18:42:21+00:00" }, { "name": "pocketmine/snooze", diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 26bec045d5..9bcea2896b 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -103,7 +103,11 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ public function tick() : void{ if(!$this->rakLib->isRunning() and !$this->rakLib->isShutdown()){ - throw new \Exception("RakLib Thread crashed"); + $e = $this->rakLib->getCrashInfo(); + if($e !== null){ + throw $e; + } + throw new \Exception("RakLib Thread crashed without crash information"); } } From 1f54760daedf10d15a9982d57f69cc19959cbe7c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 10 Jan 2019 18:03:15 +0000 Subject: [PATCH 0376/3224] Config: Make load() private --- src/pocketmine/utils/Config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/utils/Config.php b/src/pocketmine/utils/Config.php index 0484f0864b..e5617f0c56 100644 --- a/src/pocketmine/utils/Config.php +++ b/src/pocketmine/utils/Config.php @@ -144,7 +144,7 @@ class Config{ * @throws \InvalidArgumentException if config type could not be auto-detected * @throws \InvalidStateException if config type is invalid */ - public function load(string $file, int $type = Config::DETECT, array $default = []) : void{ + private function load(string $file, int $type = Config::DETECT, array $default = []) : void{ $this->file = $file; $this->type = $type; From 19614ed25e326d6573fb81035cc74d019e5d48ae Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 10 Jan 2019 21:01:19 +0000 Subject: [PATCH 0377/3224] Entity: move some NBT usages out of constructor, fix missing property defaults --- src/pocketmine/entity/Entity.php | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 7c4e68d957..617f9f4f2c 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -296,7 +296,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ /** @var AxisAlignedBB */ public $boundingBox; /** @var bool */ - public $onGround; + public $onGround = false; /** @var float */ public $eyeHeight = null; @@ -345,11 +345,11 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ public $isCollidedVertically = false; /** @var int */ - public $noDamageTicks; + public $noDamageTicks = 0; /** @var bool */ protected $justCreated = true; /** @var bool */ - private $invulnerable; + private $invulnerable = false; /** @var AttributeMap */ protected $attributeMap; @@ -411,8 +411,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->resetLastMovements(); - $this->fallDistance = $nbt->getFloat("FallDistance", 0.0); - $this->propertyManager = new DataPropertyManager(); $this->propertyManager->setLong(self::DATA_FLAGS, 0); @@ -423,15 +421,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->propertyManager->setFloat(self::DATA_BOUNDING_BOX_WIDTH, $this->width); $this->propertyManager->setFloat(self::DATA_BOUNDING_BOX_HEIGHT, $this->height); - $this->fireTicks = $nbt->getShort("Fire", 0); - if($this->isOnFire()){ - $this->setGenericFlag(self::DATA_FLAG_ONFIRE); - } - - $this->propertyManager->setShort(self::DATA_AIR, $nbt->getShort("Air", 300)); - $this->onGround = $nbt->getByte("OnGround", 0) !== 0; - $this->invulnerable = $nbt->getByte("Invulnerable", 0) !== 0; - $this->attributeMap = new AttributeMap(); $this->addAttributes(); @@ -755,6 +744,17 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } protected function initEntity(CompoundTag $nbt) : void{ + $this->fireTicks = $nbt->getShort("Fire", 0); + if($this->isOnFire()){ + $this->setGenericFlag(self::DATA_FLAG_ONFIRE); + } + + $this->propertyManager->setShort(self::DATA_AIR, $nbt->getShort("Air", 300)); + $this->onGround = $nbt->getByte("OnGround", 0) !== 0; + $this->invulnerable = $nbt->getByte("Invulnerable", 0) !== 0; + + $this->fallDistance = $nbt->getFloat("FallDistance", 0.0); + if($nbt->hasTag("CustomName", StringTag::class)){ $this->setNameTag($nbt->getString("CustomName")); From e9f023fe69282d1cf7f7a41e3d93c8d27f1322c2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 11 Jan 2019 17:55:58 +0000 Subject: [PATCH 0378/3224] LoginPacket: fix corruption false-positives in offline mode --- src/pocketmine/network/mcpe/protocol/LoginPacket.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/LoginPacket.php b/src/pocketmine/network/mcpe/protocol/LoginPacket.php index e7d2edef5b..28a09b742e 100644 --- a/src/pocketmine/network/mcpe/protocol/LoginPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LoginPacket.php @@ -133,7 +133,7 @@ class LoginPacket extends DataPacket{ $vd = new Validator(); $vd->required('chain')->isArray()->callback(function(array $data) : bool{ - return count($data) === 3 and count(array_filter($data, '\is_string')) === count($data); + return count($data) <= 3 and count(array_filter($data, '\is_string')) === count($data); }); self::validate($vd, "chainData", $chainData); @@ -155,7 +155,7 @@ class LoginPacket extends DataPacket{ $extraV = new Validator(); $extraV->required('displayName')->string(); $extraV->required('identity')->uuid(); - $extraV->required('XUID')->string()->digits(); + $extraV->required('XUID')->string()->digits()->allowEmpty(true); self::validate($extraV, "chain.$k.extraData", $claims['extraData']); $this->username = $claims["extraData"]["displayName"]; From 49bdd92faae6bc29c432f87141072e663e0dad87 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 11 Jan 2019 17:56:18 +0000 Subject: [PATCH 0379/3224] LoginPacket: Assert that extradata must exist --- src/pocketmine/network/mcpe/protocol/LoginPacket.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pocketmine/network/mcpe/protocol/LoginPacket.php b/src/pocketmine/network/mcpe/protocol/LoginPacket.php index 28a09b742e..bad35b06b8 100644 --- a/src/pocketmine/network/mcpe/protocol/LoginPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LoginPacket.php @@ -163,6 +163,9 @@ class LoginPacket extends DataPacket{ $this->xuid = $claims["extraData"]["XUID"]; } } + if(!$hasExtraData){ + throw new \UnexpectedValueException("'extraData' not found in chain data"); + } $this->clientDataJwt = $buffer->get($buffer->getLInt()); $clientData = Utils::getJwtClaims($this->clientDataJwt); From a756519e6bd0496cbcd36566e05591e4a68dee30 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 12 Jan 2019 16:10:14 +0000 Subject: [PATCH 0380/3224] Move gamemode constants & functions to their own class future enhancements: - make gamemode an object containing information about abilities that players have in this gamemode (gamemodes are just predefined ability sets) - get the magic numbers out of the API --- src/pocketmine/Gamemode.php | 109 ++++++++++++++++++ src/pocketmine/Player.php | 22 ++-- src/pocketmine/Server.php | 72 +----------- .../defaults/DefaultGamemodeCommand.php | 6 +- .../command/defaults/GamemodeCommand.php | 10 +- .../network/mcpe/RakLibInterface.php | 3 +- 6 files changed, 128 insertions(+), 94 deletions(-) create mode 100644 src/pocketmine/Gamemode.php diff --git a/src/pocketmine/Gamemode.php b/src/pocketmine/Gamemode.php new file mode 100644 index 0000000000..1eb494ed2a --- /dev/null +++ b/src/pocketmine/Gamemode.php @@ -0,0 +1,109 @@ +sendGamemode(); }else{ - Command::broadcastCommandMessage($this, new TranslationContainer("commands.gamemode.success.self", [Server::getGamemodeString($gm)])); + Command::broadcastCommandMessage($this, new TranslationContainer("commands.gamemode.success.self", [Gamemode::toTranslation($gm)])); } $this->sendSettings(); @@ -1406,7 +1400,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ */ public function isSurvival(bool $literal = false) : bool{ if($literal){ - return $this->gamemode === Player::SURVIVAL; + return $this->gamemode === Gamemode::SURVIVAL; }else{ return ($this->gamemode & 0x01) === 0; } @@ -1422,7 +1416,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ */ public function isCreative(bool $literal = false) : bool{ if($literal){ - return $this->gamemode === Player::CREATIVE; + return $this->gamemode === Gamemode::CREATIVE; }else{ return ($this->gamemode & 0x01) === 1; } @@ -1438,7 +1432,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ */ public function isAdventure(bool $literal = false) : bool{ if($literal){ - return $this->gamemode === Player::ADVENTURE; + return $this->gamemode === Gamemode::ADVENTURE; }else{ return ($this->gamemode & 0x02) > 0; } @@ -1448,7 +1442,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ * @return bool */ public function isSpectator() : bool{ - return $this->gamemode === Player::SPECTATOR; + return $this->gamemode === Gamemode::SPECTATOR; } public function isFireProof() : bool{ @@ -1893,7 +1887,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->firstPlayed = $nbt->getLong("firstPlayed", $now = (int) (microtime(true) * 1000)); $this->lastPlayed = $nbt->getLong("lastPlayed", $now); - $this->gamemode = $nbt->getInt("playerGameType", self::SURVIVAL) & 0x03; + $this->gamemode = $nbt->getInt("playerGameType", Gamemode::SURVIVAL) & 0x03; if($this->server->getForceGamemode()){ $this->gamemode = $this->server->getGamemode(); } diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index a0498e7a6f..b750e112ff 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -526,76 +526,6 @@ class Server{ return $this->getConfigBool("force-gamemode", false); } - /** - * Returns the gamemode text name - * - * @param int $mode - * - * @return string - */ - public static function getGamemodeString(int $mode) : string{ - switch($mode){ - case Player::SURVIVAL: - return "%gameMode.survival"; - case Player::CREATIVE: - return "%gameMode.creative"; - case Player::ADVENTURE: - return "%gameMode.adventure"; - case Player::SPECTATOR: - return "%gameMode.spectator"; - } - - return "UNKNOWN"; - } - - public static function getGamemodeName(int $mode) : string{ - switch($mode){ - case Player::SURVIVAL: - return "Survival"; - case Player::CREATIVE: - return "Creative"; - case Player::ADVENTURE: - return "Adventure"; - case Player::SPECTATOR: - return "Spectator"; - default: - throw new \InvalidArgumentException("Invalid gamemode $mode"); - } - } - - /** - * Parses a string and returns a gamemode integer, -1 if not found - * - * @param string $str - * - * @return int - */ - public static function getGamemodeFromString(string $str) : int{ - switch(strtolower(trim($str))){ - case (string) Player::SURVIVAL: - case "survival": - case "s": - return Player::SURVIVAL; - - case (string) Player::CREATIVE: - case "creative": - case "c": - return Player::CREATIVE; - - case (string) Player::ADVENTURE: - case "adventure": - case "a": - return Player::ADVENTURE; - - case (string) Player::SPECTATOR: - case "spectator": - case "view": - case "v": - return Player::SPECTATOR; - } - return -1; - } - /** * Returns Server global difficulty. Note that this may be overridden in individual Levels. * @return int @@ -2237,7 +2167,7 @@ class Server{ $this->dispatchSignals = true; } - $this->logger->info($this->getLanguage()->translateString("pocketmine.server.defaultGameMode", [self::getGamemodeString($this->getGamemode())])); + $this->logger->info($this->getLanguage()->translateString("pocketmine.server.defaultGameMode", [Gamemode::toTranslation($this->getGamemode())])); $this->logger->info($this->getLanguage()->translateString("pocketmine.server.startFinished", [round(microtime(true) - \pocketmine\START_TIME, 3)])); diff --git a/src/pocketmine/command/defaults/DefaultGamemodeCommand.php b/src/pocketmine/command/defaults/DefaultGamemodeCommand.php index 04c94d9903..d5bdc0f099 100644 --- a/src/pocketmine/command/defaults/DefaultGamemodeCommand.php +++ b/src/pocketmine/command/defaults/DefaultGamemodeCommand.php @@ -25,8 +25,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\Gamemode; use pocketmine\lang\TranslationContainer; -use pocketmine\Server; use function count; class DefaultGamemodeCommand extends VanillaCommand{ @@ -49,11 +49,11 @@ class DefaultGamemodeCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $gameMode = Server::getGamemodeFromString($args[0]); + $gameMode = Gamemode::fromString($args[0]); if($gameMode !== -1){ $sender->getServer()->setConfigInt("gamemode", $gameMode); - $sender->sendMessage(new TranslationContainer("commands.defaultgamemode.success", [Server::getGamemodeString($gameMode)])); + $sender->sendMessage(new TranslationContainer("commands.defaultgamemode.success", [Gamemode::toTranslation($gameMode)])); }else{ $sender->sendMessage("Unknown game mode"); } diff --git a/src/pocketmine/command/defaults/GamemodeCommand.php b/src/pocketmine/command/defaults/GamemodeCommand.php index 063993aee4..9199e74e68 100644 --- a/src/pocketmine/command/defaults/GamemodeCommand.php +++ b/src/pocketmine/command/defaults/GamemodeCommand.php @@ -26,9 +26,9 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\Gamemode; use pocketmine\lang\TranslationContainer; use pocketmine\Player; -use pocketmine\Server; use pocketmine\utils\TextFormat; use function count; @@ -52,7 +52,7 @@ class GamemodeCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $gameMode = Server::getGamemodeFromString($args[0]); + $gameMode = Gamemode::fromString($args[0]); if($gameMode === -1){ $sender->sendMessage("Unknown game mode"); @@ -77,10 +77,10 @@ class GamemodeCommand extends VanillaCommand{ $sender->sendMessage("Game mode change for " . $target->getName() . " failed!"); }else{ if($target === $sender){ - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.gamemode.success.self", [Server::getGamemodeString($gameMode)])); + Command::broadcastCommandMessage($sender, new TranslationContainer("commands.gamemode.success.self", [Gamemode::toTranslation($gameMode)])); }else{ - $target->sendMessage(new TranslationContainer("gameMode.changed", [Server::getGamemodeString($gameMode)])); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.gamemode.success.other", [Server::getGamemodeString($gameMode), $target->getName()])); + $target->sendMessage(new TranslationContainer("gameMode.changed", [Gamemode::toTranslation($gameMode)])); + Command::broadcastCommandMessage($sender, new TranslationContainer("commands.gamemode.success.other", [Gamemode::toTranslation($gameMode), $target->getName()])); } } diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 9bcea2896b..3a35296020 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; +use pocketmine\Gamemode; use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\Network; @@ -196,7 +197,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $info->getMaxPlayerCount(), $this->rakLib->getServerId(), $this->server->getName(), - Server::getGamemodeName($this->server->getGamemode()) + Gamemode::toString($this->server->getGamemode()) ]) . ";" ); } From 27761ac26e1d0234792f6bab0878cba767a66e5c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 12 Jan 2019 16:19:31 +0000 Subject: [PATCH 0381/3224] Fixed casing: Gamemode -> GameMode it's two words, not one. --- src/pocketmine/{Gamemode.php => GameMode.php} | 4 ++-- src/pocketmine/Player.php | 18 +++++++++--------- src/pocketmine/Server.php | 2 +- .../defaults/DefaultGamemodeCommand.php | 6 +++--- .../command/defaults/GamemodeCommand.php | 10 +++++----- .../network/mcpe/RakLibInterface.php | 4 ++-- 6 files changed, 22 insertions(+), 22 deletions(-) rename src/pocketmine/{Gamemode.php => GameMode.php} (97%) diff --git a/src/pocketmine/Gamemode.php b/src/pocketmine/GameMode.php similarity index 97% rename from src/pocketmine/Gamemode.php rename to src/pocketmine/GameMode.php index 1eb494ed2a..43271d5687 100644 --- a/src/pocketmine/Gamemode.php +++ b/src/pocketmine/GameMode.php @@ -23,12 +23,12 @@ declare(strict_types=1); namespace pocketmine; -final class Gamemode{ +final class GameMode{ public const SURVIVAL = 0; public const CREATIVE = 1; public const ADVENTURE = 2; public const SPECTATOR = 3; - public const VIEW = Gamemode::SPECTATOR; + public const VIEW = GameMode::SPECTATOR; private function __construct(){ //NOOP diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index fa45259e21..37604a4135 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1302,8 +1302,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ */ public static function getClientFriendlyGamemode(int $gamemode) : int{ $gamemode &= 0x03; - if($gamemode === Gamemode::SPECTATOR){ - return Gamemode::CREATIVE; + if($gamemode === GameMode::SPECTATOR){ + return GameMode::CREATIVE; } return $gamemode; @@ -1348,10 +1348,10 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->resetFallDistance(); - if(!$client){ //Gamemode changed by server, do not send for client changes + if(!$client){ //GameMode changed by server, do not send for client changes $this->sendGamemode(); }else{ - Command::broadcastCommandMessage($this, new TranslationContainer("commands.gamemode.success.self", [Gamemode::toTranslation($gm)])); + Command::broadcastCommandMessage($this, new TranslationContainer("commands.gamemode.success.self", [GameMode::toTranslation($gm)])); } $this->sendSettings(); @@ -1400,7 +1400,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ */ public function isSurvival(bool $literal = false) : bool{ if($literal){ - return $this->gamemode === Gamemode::SURVIVAL; + return $this->gamemode === GameMode::SURVIVAL; }else{ return ($this->gamemode & 0x01) === 0; } @@ -1416,7 +1416,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ */ public function isCreative(bool $literal = false) : bool{ if($literal){ - return $this->gamemode === Gamemode::CREATIVE; + return $this->gamemode === GameMode::CREATIVE; }else{ return ($this->gamemode & 0x01) === 1; } @@ -1432,7 +1432,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ */ public function isAdventure(bool $literal = false) : bool{ if($literal){ - return $this->gamemode === Gamemode::ADVENTURE; + return $this->gamemode === GameMode::ADVENTURE; }else{ return ($this->gamemode & 0x02) > 0; } @@ -1442,7 +1442,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ * @return bool */ public function isSpectator() : bool{ - return $this->gamemode === Gamemode::SPECTATOR; + return $this->gamemode === GameMode::SPECTATOR; } public function isFireProof() : bool{ @@ -1887,7 +1887,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->firstPlayed = $nbt->getLong("firstPlayed", $now = (int) (microtime(true) * 1000)); $this->lastPlayed = $nbt->getLong("lastPlayed", $now); - $this->gamemode = $nbt->getInt("playerGameType", Gamemode::SURVIVAL) & 0x03; + $this->gamemode = $nbt->getInt("playerGameType", GameMode::SURVIVAL) & 0x03; if($this->server->getForceGamemode()){ $this->gamemode = $this->server->getGamemode(); } diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index b750e112ff..059d243bd6 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -2167,7 +2167,7 @@ class Server{ $this->dispatchSignals = true; } - $this->logger->info($this->getLanguage()->translateString("pocketmine.server.defaultGameMode", [Gamemode::toTranslation($this->getGamemode())])); + $this->logger->info($this->getLanguage()->translateString("pocketmine.server.defaultGameMode", [GameMode::toTranslation($this->getGamemode())])); $this->logger->info($this->getLanguage()->translateString("pocketmine.server.startFinished", [round(microtime(true) - \pocketmine\START_TIME, 3)])); diff --git a/src/pocketmine/command/defaults/DefaultGamemodeCommand.php b/src/pocketmine/command/defaults/DefaultGamemodeCommand.php index d5bdc0f099..c8bede912a 100644 --- a/src/pocketmine/command/defaults/DefaultGamemodeCommand.php +++ b/src/pocketmine/command/defaults/DefaultGamemodeCommand.php @@ -25,7 +25,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; -use pocketmine\Gamemode; +use pocketmine\GameMode; use pocketmine\lang\TranslationContainer; use function count; @@ -49,11 +49,11 @@ class DefaultGamemodeCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $gameMode = Gamemode::fromString($args[0]); + $gameMode = GameMode::fromString($args[0]); if($gameMode !== -1){ $sender->getServer()->setConfigInt("gamemode", $gameMode); - $sender->sendMessage(new TranslationContainer("commands.defaultgamemode.success", [Gamemode::toTranslation($gameMode)])); + $sender->sendMessage(new TranslationContainer("commands.defaultgamemode.success", [GameMode::toTranslation($gameMode)])); }else{ $sender->sendMessage("Unknown game mode"); } diff --git a/src/pocketmine/command/defaults/GamemodeCommand.php b/src/pocketmine/command/defaults/GamemodeCommand.php index 9199e74e68..3439caa8aa 100644 --- a/src/pocketmine/command/defaults/GamemodeCommand.php +++ b/src/pocketmine/command/defaults/GamemodeCommand.php @@ -26,7 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; -use pocketmine\Gamemode; +use pocketmine\GameMode; use pocketmine\lang\TranslationContainer; use pocketmine\Player; use pocketmine\utils\TextFormat; @@ -52,7 +52,7 @@ class GamemodeCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $gameMode = Gamemode::fromString($args[0]); + $gameMode = GameMode::fromString($args[0]); if($gameMode === -1){ $sender->sendMessage("Unknown game mode"); @@ -77,10 +77,10 @@ class GamemodeCommand extends VanillaCommand{ $sender->sendMessage("Game mode change for " . $target->getName() . " failed!"); }else{ if($target === $sender){ - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.gamemode.success.self", [Gamemode::toTranslation($gameMode)])); + Command::broadcastCommandMessage($sender, new TranslationContainer("commands.gamemode.success.self", [GameMode::toTranslation($gameMode)])); }else{ - $target->sendMessage(new TranslationContainer("gameMode.changed", [Gamemode::toTranslation($gameMode)])); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.gamemode.success.other", [Gamemode::toTranslation($gameMode), $target->getName()])); + $target->sendMessage(new TranslationContainer("gameMode.changed", [GameMode::toTranslation($gameMode)])); + Command::broadcastCommandMessage($sender, new TranslationContainer("commands.gamemode.success.other", [GameMode::toTranslation($gameMode), $target->getName()])); } } diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 3a35296020..cfa0833038 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; -use pocketmine\Gamemode; +use pocketmine\GameMode; use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\Network; @@ -197,7 +197,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $info->getMaxPlayerCount(), $this->rakLib->getServerId(), $this->server->getName(), - Gamemode::toString($this->server->getGamemode()) + GameMode::toString($this->server->getGamemode()) ]) . ";" ); } From 5052b755659a5405cf5985813a756ffe9cf173be Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 12 Jan 2019 19:11:05 +0000 Subject: [PATCH 0382/3224] Separate Level management functionality from Server, clean up a bunch of mess --- src/pocketmine/MemoryManager.php | 4 +- src/pocketmine/Player.php | 8 +- src/pocketmine/Server.php | 482 ++---------------- .../command/defaults/DifficultyCommand.php | 2 +- .../defaults/GarbageCollectorCommand.php | 2 +- .../command/defaults/ParticleCommand.php | 2 +- .../command/defaults/SaveCommand.php | 2 +- .../command/defaults/SaveOffCommand.php | 2 +- .../command/defaults/SaveOnCommand.php | 2 +- .../command/defaults/SeedCommand.php | 2 +- .../command/defaults/SetWorldSpawnCommand.php | 2 +- .../command/defaults/StatusCommand.php | 2 +- .../command/defaults/TimeCommand.php | 10 +- src/pocketmine/entity/Entity.php | 4 +- .../entity/object/ExperienceOrb.php | 2 +- .../entity/EntityDamageByChildEntityEvent.php | 2 +- .../entity/EntityDamageByEntityEvent.php | 2 +- .../event/server/QueryRegenerateEvent.php | 3 +- src/pocketmine/level/Level.php | 55 +- src/pocketmine/level/LevelManager.php | 439 ++++++++++++++++ .../level/generator/GeneratorManager.php | 8 +- src/pocketmine/timings/TimingsHandler.php | 2 +- 22 files changed, 530 insertions(+), 509 deletions(-) create mode 100644 src/pocketmine/level/LevelManager.php diff --git a/src/pocketmine/MemoryManager.php b/src/pocketmine/MemoryManager.php index d6e03a393c..fcf29504af 100644 --- a/src/pocketmine/MemoryManager.php +++ b/src/pocketmine/MemoryManager.php @@ -206,13 +206,13 @@ class MemoryManager{ $this->server->getLogger()->debug(sprintf("[Memory Manager] %sLow memory triggered, limit %gMB, using %gMB", $global ? "Global " : "", round(($limit / 1024) / 1024, 2), round(($memory / 1024) / 1024, 2))); if($this->lowMemClearWorldCache){ - foreach($this->server->getLevels() as $level){ + foreach($this->server->getLevelManager()->getLevels() as $level){ $level->clearCache(true); } } if($this->lowMemChunkGC){ - foreach($this->server->getLevels() as $level){ + foreach($this->server->getLevelManager()->getLevels() as $level){ $level->doChunkGarbageCollection(); } } diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 37604a4135..1ddd2db4b0 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1137,7 +1137,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ if($this->hasValidSpawnPosition()){ return $this->spawnPosition; }else{ - $level = $this->server->getDefaultLevel(); + $level = $this->server->getLevelManager()->getDefaultLevel(); return $level->getSafeSpawn(); } @@ -1837,9 +1837,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ public function _actuallyConstruct(){ $namedtag = $this->server->getOfflinePlayerData($this->username); //TODO: make this async - if(($level = $this->server->getLevelByName($namedtag->getString("Level", "", true))) === null){ + if(($level = $this->server->getLevelManager()->getLevelByName($namedtag->getString("Level", "", true))) === null){ /** @var Level $level */ - $level = $this->server->getDefaultLevel(); //TODO: default level may be null + $level = $this->server->getLevelManager()->getDefaultLevel(); //TODO: default level may be null $spawnLocation = $level->getSafeSpawn(); $namedtag->setTag(new ListTag("Pos", [ @@ -1910,7 +1910,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } if(!$this->hasValidSpawnPosition()){ - if(($level = $this->server->getLevelByName($nbt->getString("SpawnLevel", ""))) instanceof Level){ + if(($level = $this->server->getLevelManager()->getLevelByName($nbt->getString("SpawnLevel", ""))) instanceof Level){ $this->spawnPosition = new Position($nbt->getInt("SpawnX"), $nbt->getInt("SpawnY"), $nbt->getInt("SpawnZ"), $level); }else{ $this->spawnPosition = $this->level->getSafeSpawn(); diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 059d243bd6..f8709ca67c 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -33,12 +33,9 @@ use pocketmine\command\CommandSender; use pocketmine\command\ConsoleCommandSender; use pocketmine\command\PluginIdentifiableCommand; use pocketmine\command\SimpleCommandMap; -use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; use pocketmine\entity\Skin; use pocketmine\event\HandlerList; -use pocketmine\event\level\LevelInitEvent; -use pocketmine\event\level\LevelLoadEvent; use pocketmine\event\player\PlayerDataSaveEvent; use pocketmine\event\server\CommandEvent; use pocketmine\event\server\DataPacketBroadcastEvent; @@ -51,13 +48,12 @@ use pocketmine\lang\Language; use pocketmine\lang\LanguageNotFoundException; use pocketmine\lang\TextContainer; use pocketmine\level\biome\Biome; -use pocketmine\level\format\io\exception\UnsupportedLevelFormatException; -use pocketmine\level\format\io\LevelProvider; use pocketmine\level\format\io\LevelProviderManager; use pocketmine\level\generator\Generator; use pocketmine\level\generator\GeneratorManager; +use pocketmine\level\generator\normal\Normal; use pocketmine\level\Level; -use pocketmine\level\LevelException; +use pocketmine\level\LevelManager; use pocketmine\metadata\EntityMetadataStore; use pocketmine\metadata\LevelMetadataStore; use pocketmine\metadata\PlayerMetadataStore; @@ -113,14 +109,10 @@ use pocketmine\utils\TextFormat; use pocketmine\utils\Utils; use pocketmine\utils\UUID; use function array_key_exists; -use function array_keys; use function array_shift; use function array_sum; -use function asort; -use function assert; use function base64_encode; use function bin2hex; -use function class_exists; use function count; use function define; use function explode; @@ -129,7 +121,6 @@ use function file_exists; use function file_get_contents; use function file_put_contents; use function filemtime; -use function floor; use function function_exists; use function gc_collect_cycles; use function get_class; @@ -141,7 +132,6 @@ use function ini_set; use function is_array; use function is_bool; use function is_string; -use function is_subclass_of; use function json_decode; use function max; use function microtime; @@ -151,7 +141,6 @@ use function pcntl_signal; use function pcntl_signal_dispatch; use function preg_replace; use function random_bytes; -use function random_int; use function realpath; use function register_shutdown_function; use function rename; @@ -170,8 +159,6 @@ use function time; use function touch; use function trim; use const DIRECTORY_SEPARATOR; -use const INT32_MAX; -use const INT32_MIN; use const PHP_EOL; use const PHP_INT_MAX; use const PTHREADS_INHERIT_NONE; @@ -266,15 +253,15 @@ class Server{ /** @var ResourcePackManager */ private $resourceManager; + /** @var LevelManager */ + private $levelManager; + /** @var int */ private $maxPlayers; /** @var bool */ private $onlineMode = true; - /** @var bool */ - private $autoSave; - /** @var RCON */ private $rcon; @@ -292,20 +279,6 @@ class Server{ /** @var bool */ private $networkCompressionAsync = true; - /** @var bool */ - private $autoTickRate = true; - /** @var int */ - private $autoTickRateLimit = 20; - /** @var bool */ - private $alwaysTickPlayers = false; - /** @var int */ - private $baseTickRate = 1; - - /** @var int */ - private $autoSaveTicker = 0; - /** @var int */ - private $autoSaveTicks = 6000; - /** @var Language */ private $language; /** @var bool */ @@ -347,12 +320,6 @@ class Server{ /** @var Player[] */ private $playerList = []; - /** @var Level[] */ - private $levels = []; - - /** @var Level */ - private $levelDefault = null; - /** * @return string */ @@ -481,37 +448,6 @@ class Server{ return $this->serverID; } - /** - * @return bool - */ - public function getAutoSave() : bool{ - return $this->autoSave; - } - - /** - * @param bool $value - */ - public function setAutoSave(bool $value){ - $this->autoSave = $value; - foreach($this->getLevels() as $level){ - $level->setAutoSave($this->autoSave); - } - } - - /** - * @return string - */ - public function getLevelType() : string{ - return $this->getConfigString("level-type", "DEFAULT"); - } - - /** - * @return bool - */ - public function getGenerateStructures() : bool{ - return $this->getConfigBool("generate-structures", true); - } - /** * @return int */ @@ -632,6 +568,13 @@ class Server{ return $this->resourceManager; } + /** + * @return LevelManager + */ + public function getLevelManager() : LevelManager{ + return $this->levelManager; + } + public function getAsyncPool() : AsyncPool{ return $this->asyncPool; } @@ -752,7 +695,7 @@ class Server{ $this->logger->notice($this->getLanguage()->translateString("pocketmine.data.playerNotFound", [$name])); } } - $spawn = $this->getDefaultLevel()->getSafeSpawn(); + $spawn = $this->levelManager->getDefaultLevel()->getSafeSpawn(); $currentTimeMillis = (int) (microtime(true) * 1000); $nbt = new CompoundTag("", [ @@ -763,7 +706,7 @@ class Server{ new DoubleTag("", $spawn->y), new DoubleTag("", $spawn->z) ], NBT::TAG_Double), - new StringTag("Level", $this->getDefaultLevel()->getFolderName()), + new StringTag("Level", $this->levelManager->getDefaultLevel()->getFolderName()), //new StringTag("SpawnLevel", $this->getDefaultLevel()->getFolderName()), //new IntTag("SpawnX", $spawn->getFloorX()), //new IntTag("SpawnY", $spawn->getFloorY()), @@ -898,255 +841,6 @@ class Server{ return $this->getPlayerByRawUUID($uuid->toBinary()); } - /** - * @return Level[] - */ - public function getLevels() : array{ - return $this->levels; - } - - /** - * @return Level|null - */ - public function getDefaultLevel() : ?Level{ - return $this->levelDefault; - } - - /** - * Sets the default level to a different level - * This won't change the level-name property, - * it only affects the server on runtime - * - * @param Level|null $level - */ - public function setDefaultLevel(?Level $level) : void{ - if($level === null or ($this->isLevelLoaded($level->getFolderName()) and $level !== $this->levelDefault)){ - $this->levelDefault = $level; - } - } - - /** - * @param string $name - * - * @return bool - */ - public function isLevelLoaded(string $name) : bool{ - return $this->getLevelByName($name) instanceof Level; - } - - /** - * @param int $levelId - * - * @return Level|null - */ - public function getLevel(int $levelId) : ?Level{ - return $this->levels[$levelId] ?? null; - } - - /** - * NOTE: This matches levels based on the FOLDER name, NOT the display name. - * - * @param string $name - * - * @return Level|null - */ - public function getLevelByName(string $name) : ?Level{ - foreach($this->getLevels() as $level){ - if($level->getFolderName() === $name){ - return $level; - } - } - - return null; - } - - /** - * @param Level $level - * @param bool $forceUnload - * - * @return bool - * - * @throws \InvalidStateException - */ - public function unloadLevel(Level $level, bool $forceUnload = false) : bool{ - if($level === $this->getDefaultLevel() and !$forceUnload){ - throw new \InvalidStateException("The default level cannot be unloaded while running, please switch levels."); - } - - return $level->onUnload($forceUnload); - } - - /** - * @internal - * - * @param Level $level - */ - public function removeLevel(Level $level) : void{ - unset($this->levels[$level->getId()]); - } - - /** - * Loads a level from the data directory - * - * @param string $name - * - * @return bool - * - * @throws LevelException - */ - public function loadLevel(string $name) : bool{ - if(trim($name) === ""){ - throw new LevelException("Invalid empty level name"); - } - if($this->isLevelLoaded($name)){ - return true; - }elseif(!$this->isLevelGenerated($name)){ - $this->logger->notice($this->getLanguage()->translateString("pocketmine.level.notFound", [$name])); - - return false; - } - - $path = $this->getDataPath() . "worlds/" . $name . "/"; - - $providers = LevelProviderManager::getMatchingProviders($path); - if(count($providers) !== 1){ - $this->logger->error($this->language->translateString("pocketmine.level.loadError", [ - $name, - empty($providers) ? - $this->language->translateString("pocketmine.level.unknownFormat") : - $this->language->translateString("pocketmine.level.ambiguousFormat", [implode(", ", array_keys($providers))]) - ])); - return false; - } - $providerClass = array_shift($providers); - - try{ - /** @see LevelProvider::__construct() */ - $level = new Level($this, $name, new $providerClass($path)); - }catch(UnsupportedLevelFormatException $e){ - $this->logger->error($this->language->translateString("pocketmine.level.loadError", [$name, $e->getMessage()])); - return false; - } - - $this->levels[$level->getId()] = $level; - - (new LevelLoadEvent($level))->call(); - - $level->setTickRate($this->baseTickRate); - - return true; - } - - /** - * Generates a new level if it does not exist - * - * @param string $name - * @param int|null $seed - * @param string|null $generator Class name that extends pocketmine\level\generator\Generator - * @param array $options - * @param bool $backgroundGeneration - * - * @return bool - */ - public function generateLevel(string $name, int $seed = null, $generator = null, array $options = [], bool $backgroundGeneration = true) : bool{ - if(trim($name) === "" or $this->isLevelGenerated($name)){ - return false; - } - - $seed = $seed ?? random_int(INT32_MIN, INT32_MAX); - - if(!isset($options["preset"])){ - $options["preset"] = $this->getConfigString("generator-settings", ""); - } - - if(!($generator !== null and class_exists($generator, true) and is_subclass_of($generator, Generator::class))){ - $generator = GeneratorManager::getGenerator($this->getLevelType()); - } - - $providerClass = LevelProviderManager::getDefault(); - - $path = $this->getDataPath() . "worlds/" . $name . "/"; - /** @var LevelProvider $providerClass */ - $providerClass::generate($path, $name, $seed, $generator, $options); - - /** @see LevelProvider::__construct() */ - $level = new Level($this, $name, new $providerClass($path)); - $this->levels[$level->getId()] = $level; - - $level->setTickRate($this->baseTickRate); - - (new LevelInitEvent($level))->call(); - - (new LevelLoadEvent($level))->call(); - - if(!$backgroundGeneration){ - return true; - } - - $this->getLogger()->notice($this->getLanguage()->translateString("pocketmine.level.backgroundGeneration", [$name])); - - $spawnLocation = $level->getSpawnLocation(); - $centerX = $spawnLocation->getFloorX() >> 4; - $centerZ = $spawnLocation->getFloorZ() >> 4; - - $order = []; - - for($X = -3; $X <= 3; ++$X){ - for($Z = -3; $Z <= 3; ++$Z){ - $distance = $X ** 2 + $Z ** 2; - $chunkX = $X + $centerX; - $chunkZ = $Z + $centerZ; - $index = Level::chunkHash($chunkX, $chunkZ); - $order[$index] = $distance; - } - } - - asort($order); - - foreach($order as $index => $distance){ - Level::getXZ($index, $chunkX, $chunkZ); - $level->populateChunk($chunkX, $chunkZ, true); - } - - return true; - } - - /** - * @param string $name - * - * @return bool - */ - public function isLevelGenerated(string $name) : bool{ - if(trim($name) === ""){ - return false; - } - $path = $this->getDataPath() . "worlds/" . $name . "/"; - if(!($this->getLevelByName($name) instanceof Level)){ - return !empty(LevelProviderManager::getMatchingProviders($path)); - } - - return true; - } - - /** - * Searches all levels for the entity with the specified ID. - * Useful for tracking entities across multiple worlds without needing strong references. - * - * @param int $entityId - * - * @return Entity|null - */ - public function findEntity(int $entityId){ - foreach($this->levels as $level){ - assert(!$level->isClosed()); - if(($entity = $level->getEntity($entityId)) instanceof Entity){ - return $entity; - } - } - - return null; - } - /** * @param string $variable * @param mixed $defaultValue @@ -1530,11 +1224,6 @@ class Server{ NetworkCipher::$ENABLED = (bool) $this->getProperty("network.enable-encryption", true); - $this->autoTickRate = (bool) $this->getProperty("level-settings.auto-tick-rate", true); - $this->autoTickRateLimit = (int) $this->getProperty("level-settings.auto-tick-rate-limit", 20); - $this->alwaysTickPlayers = (bool) $this->getProperty("level-settings.always-tick-players", false); - $this->baseTickRate = (int) $this->getProperty("level-settings.base-tick-rate", 1); - $this->doTitleTick = ((bool) $this->getProperty("console.title-tick", true)) && Terminal::hasFormattingCodes(); @@ -1583,7 +1272,6 @@ class Server{ $this->banByIP->load(); $this->maxPlayers = $this->getConfigInt("max-players", 20); - $this->setAutoSave($this->getConfigBool("auto-save", true)); $this->onlineMode = $this->getConfigBool("xbox-auth", true); if($this->onlineMode){ @@ -1644,6 +1332,20 @@ class Server{ $this->pluginManager->registerInterface(new PharPluginLoader($this->autoloader)); $this->pluginManager->registerInterface(new ScriptPluginLoader()); + LevelProviderManager::init(); + if(($format = LevelProviderManager::getProviderByName($formatName = (string) $this->getProperty("level-settings.default-format"))) !== null){ + LevelProviderManager::setDefault($format); + }elseif($formatName !== ""){ + $this->logger->warning($this->language->translateString("pocketmine.level.badDefaultFormat", [$formatName])); + } + if(extension_loaded("leveldb")){ + $this->logger->debug($this->getLanguage()->translateString("pocketmine.debug.enable")); + } + + $this->levelManager = new LevelManager($this); + + GeneratorManager::registerDefaultGenerators(); + register_shutdown_function([$this, "crashDump"]); $this->queryRegenerateTask = new QueryRegenerateEvent($this, 5); @@ -1656,26 +1358,13 @@ class Server{ $this->network->registerInterface(new RakLibInterface($this)); - LevelProviderManager::init(); - if(($format = LevelProviderManager::getProviderByName($formatName = (string) $this->getProperty("level-settings.default-format"))) !== null){ - LevelProviderManager::setDefault($format); - }elseif($formatName !== ""){ - $this->logger->warning($this->language->translateString("pocketmine.level.badDefaultFormat", [$formatName])); - } - - if(extension_loaded("leveldb")){ - $this->logger->debug($this->getLanguage()->translateString("pocketmine.debug.enable")); - } - - GeneratorManager::registerDefaultGenerators(); - foreach((array) $this->getProperty("worlds", []) as $name => $options){ if($options === null){ $options = []; }elseif(!is_array($options)){ continue; } - if(!$this->loadLevel($name)){ + if(!$this->levelManager->loadLevel($name)){ if(isset($options["generator"])){ $generatorOptions = explode(":", $options["generator"]); $generator = GeneratorManager::getGenerator(array_shift($generatorOptions)); @@ -1683,42 +1372,43 @@ class Server{ $options["preset"] = implode(":", $generatorOptions); } }else{ - $generator = GeneratorManager::getGenerator("default"); + $generator = Normal::class; } - $this->generateLevel($name, Generator::convertSeed((string) ($options["seed"] ?? "")), $generator, $options); + $this->levelManager->generateLevel($name, Generator::convertSeed((string) ($options["seed"] ?? "")), $generator, $options); } } - if($this->getDefaultLevel() === null){ + if($this->levelManager->getDefaultLevel() === null){ $default = $this->getConfigString("level-name", "world"); if(trim($default) == ""){ $this->getLogger()->warning("level-name cannot be null, using default"); $default = "world"; $this->setConfigString("level-name", "world"); } - if(!$this->loadLevel($default)){ - $this->generateLevel($default, Generator::convertSeed($this->getConfigString("level-seed"))); + if(!$this->levelManager->loadLevel($default)){ + $this->levelManager->generateLevel( + $default, + Generator::convertSeed($this->getConfigString("level-seed")), + GeneratorManager::getGenerator($this->getConfigString("level-type")), + ["preset" => $this->getConfigString("generator-settings")] + ); } - $this->setDefaultLevel($this->getLevelByName($default)); + $level = $this->levelManager->getLevelByName($default); + if($level === null){ + $this->getLogger()->emergency($this->getLanguage()->translateString("pocketmine.level.defaultError")); + $this->forceShutdown(); + + return; + } + $this->levelManager->setDefaultLevel($level); } if($this->properties->hasChanged()){ $this->properties->save(); } - if(!($this->getDefaultLevel() instanceof Level)){ - $this->getLogger()->emergency($this->getLanguage()->translateString("pocketmine.level.defaultError")); - $this->forceShutdown(); - - return; - } - - if($this->getProperty("ticks-per.autosave", 6000) > 0){ - $this->autoSaveTicks = (int) $this->getProperty("ticks-per.autosave", 6000); - } - $this->enablePlugins(PluginLoadOrder::POSTWORLD); $this->start(); @@ -2005,7 +1695,7 @@ class Server{ public function reload(){ $this->logger->info("Saving levels..."); - foreach($this->levels as $level){ + foreach($this->levelManager->getLevels() as $level){ $level->save(); } @@ -2082,8 +1772,8 @@ class Server{ } $this->getLogger()->debug("Unloading all levels"); - foreach($this->getLevels() as $level){ - $this->unloadLevel($level, true); + foreach($this->levelManager->getLevels() as $level){ + $this->levelManager->unloadLevel($level, true); } $this->getLogger()->debug("Removing event handlers"); @@ -2393,69 +2083,6 @@ class Server{ $p->sendDataPacket($pk); } - private function checkTickUpdates(int $currentTick) : void{ - if($this->alwaysTickPlayers){ - foreach($this->players as $p){ - if($p->spawned){ - $p->onUpdate($currentTick); - } - } - } - - //Do level ticks - foreach($this->levels as $k => $level){ - if(!isset($this->levels[$k])){ - // Level unloaded during the tick of a level earlier in this loop, perhaps by plugin - continue; - } - if($level->getTickRate() > $this->baseTickRate and --$level->tickRateCounter > 0){ - continue; - } - - $levelTime = microtime(true); - $level->doTick($currentTick); - $tickMs = (microtime(true) - $levelTime) * 1000; - $level->tickRateTime = $tickMs; - - if($this->autoTickRate){ - if($tickMs < 50 and $level->getTickRate() > $this->baseTickRate){ - $level->setTickRate($r = $level->getTickRate() - 1); - if($r > $this->baseTickRate){ - $level->tickRateCounter = $level->getTickRate(); - } - $this->getLogger()->debug("Raising level \"{$level->getName()}\" tick rate to {$level->getTickRate()} ticks"); - }elseif($tickMs >= 50){ - if($level->getTickRate() === $this->baseTickRate){ - $level->setTickRate(max($this->baseTickRate + 1, min($this->autoTickRateLimit, (int) floor($tickMs / 50)))); - $this->getLogger()->debug(sprintf("Level \"%s\" took %gms, setting tick rate to %d ticks", $level->getName(), (int) round($tickMs, 2), $level->getTickRate())); - }elseif(($tickMs / $level->getTickRate()) >= 50 and $level->getTickRate() < $this->autoTickRateLimit){ - $level->setTickRate($level->getTickRate() + 1); - $this->getLogger()->debug(sprintf("Level \"%s\" took %gms, setting tick rate to %d ticks", $level->getName(), (int) round($tickMs, 2), $level->getTickRate())); - } - $level->tickRateCounter = $level->getTickRate(); - } - } - } - } - - public function doAutoSave(){ - if($this->getAutoSave()){ - Timings::$worldSaveTimer->startTiming(); - foreach($this->players as $index => $player){ - if($player->spawned){ - $player->save(); - }elseif(!$player->isConnected()){ - $this->removePlayer($player); - } - } - - foreach($this->getLevels() as $level){ - $level->save(false); - } - Timings::$worldSaveTimer->stopTiming(); - } - } - public function sendUsage($type = SendUsageTask::TYPE_STATUS){ if((bool) $this->getProperty("anonymous-statistics.enabled", true)){ $this->asyncPool->submitTask(new SendUsageTask($this, $type, $this->uniquePlayers)); @@ -2556,7 +2183,7 @@ class Server{ $this->asyncPool->collectTasks(); Timings::$schedulerAsyncTimer->stopTiming(); - $this->checkTickUpdates($this->tickCounter); + $this->levelManager->tick($this->tickCounter); Timings::$connectionTimer->startTiming(); $this->network->tick(); @@ -2580,18 +2207,13 @@ class Server{ } } - if($this->autoSave and ++$this->autoSaveTicker >= $this->autoSaveTicks){ - $this->autoSaveTicker = 0; - $this->doAutoSave(); - } - if($this->sendUsageTicker > 0 and --$this->sendUsageTicker === 0){ $this->sendUsageTicker = 6000; $this->sendUsage(SendUsageTask::TYPE_STATUS); } if(($this->tickCounter % 100) === 0){ - foreach($this->levels as $level){ + foreach($this->levelManager->getLevels() as $level){ $level->clearCache(); } diff --git a/src/pocketmine/command/defaults/DifficultyCommand.php b/src/pocketmine/command/defaults/DifficultyCommand.php index a03f828ae6..8addfb0a87 100644 --- a/src/pocketmine/command/defaults/DifficultyCommand.php +++ b/src/pocketmine/command/defaults/DifficultyCommand.php @@ -60,7 +60,7 @@ class DifficultyCommand extends VanillaCommand{ $sender->getServer()->setConfigInt("difficulty", $difficulty); //TODO: add per-world support - foreach($sender->getServer()->getLevels() as $level){ + foreach($sender->getServer()->getLevelManager()->getLevels() as $level){ $level->setDifficulty($difficulty); } diff --git a/src/pocketmine/command/defaults/GarbageCollectorCommand.php b/src/pocketmine/command/defaults/GarbageCollectorCommand.php index f6cbc9af7e..7df2d16ed8 100644 --- a/src/pocketmine/command/defaults/GarbageCollectorCommand.php +++ b/src/pocketmine/command/defaults/GarbageCollectorCommand.php @@ -52,7 +52,7 @@ class GarbageCollectorCommand extends VanillaCommand{ $memory = memory_get_usage(); - foreach($sender->getServer()->getLevels() as $level){ + foreach($sender->getServer()->getLevelManager()->getLevels() as $level){ $diff = [count($level->getChunks()), count($level->getEntities()), count($level->getTiles())]; $level->doChunkGarbageCollection(); $level->unloadChunks(true); diff --git a/src/pocketmine/command/defaults/ParticleCommand.php b/src/pocketmine/command/defaults/ParticleCommand.php index 78c586943e..12b939eb39 100644 --- a/src/pocketmine/command/defaults/ParticleCommand.php +++ b/src/pocketmine/command/defaults/ParticleCommand.php @@ -98,7 +98,7 @@ class ParticleCommand extends VanillaCommand{ $this->getRelativeDouble($sender->getZ(), $sender, $args[3]) ); }else{ - $level = $sender->getServer()->getDefaultLevel(); + $level = $sender->getServer()->getLevelManager()->getDefaultLevel(); $pos = new Vector3((float) $args[1], (float) $args[2], (float) $args[3]); } diff --git a/src/pocketmine/command/defaults/SaveCommand.php b/src/pocketmine/command/defaults/SaveCommand.php index a52eabcfc8..d1f4882fbf 100644 --- a/src/pocketmine/command/defaults/SaveCommand.php +++ b/src/pocketmine/command/defaults/SaveCommand.php @@ -49,7 +49,7 @@ class SaveCommand extends VanillaCommand{ $player->save(); } - foreach($sender->getServer()->getLevels() as $level){ + foreach($sender->getServer()->getLevelManager()->getLevels() as $level){ $level->save(true); } diff --git a/src/pocketmine/command/defaults/SaveOffCommand.php b/src/pocketmine/command/defaults/SaveOffCommand.php index c81d169056..e5b8d79e31 100644 --- a/src/pocketmine/command/defaults/SaveOffCommand.php +++ b/src/pocketmine/command/defaults/SaveOffCommand.php @@ -43,7 +43,7 @@ class SaveOffCommand extends VanillaCommand{ return true; } - $sender->getServer()->setAutoSave(false); + $sender->getServer()->getLevelManager()->setAutoSave(false); Command::broadcastCommandMessage($sender, new TranslationContainer("commands.save.disabled")); diff --git a/src/pocketmine/command/defaults/SaveOnCommand.php b/src/pocketmine/command/defaults/SaveOnCommand.php index 8962baa2bb..d79f03be50 100644 --- a/src/pocketmine/command/defaults/SaveOnCommand.php +++ b/src/pocketmine/command/defaults/SaveOnCommand.php @@ -43,7 +43,7 @@ class SaveOnCommand extends VanillaCommand{ return true; } - $sender->getServer()->setAutoSave(true); + $sender->getServer()->getLevelManager()->setAutoSave(true); Command::broadcastCommandMessage($sender, new TranslationContainer("commands.save.enabled")); diff --git a/src/pocketmine/command/defaults/SeedCommand.php b/src/pocketmine/command/defaults/SeedCommand.php index 431c04d48a..5fdaa50b9e 100644 --- a/src/pocketmine/command/defaults/SeedCommand.php +++ b/src/pocketmine/command/defaults/SeedCommand.php @@ -46,7 +46,7 @@ class SeedCommand extends VanillaCommand{ if($sender instanceof Player){ $seed = $sender->getLevel()->getSeed(); }else{ - $seed = $sender->getServer()->getDefaultLevel()->getSeed(); + $seed = $sender->getServer()->getLevelManager()->getDefaultLevel()->getSeed(); } $sender->sendMessage(new TranslationContainer("commands.seed.success", [$seed])); diff --git a/src/pocketmine/command/defaults/SetWorldSpawnCommand.php b/src/pocketmine/command/defaults/SetWorldSpawnCommand.php index 054adc059f..fe50ec205e 100644 --- a/src/pocketmine/command/defaults/SetWorldSpawnCommand.php +++ b/src/pocketmine/command/defaults/SetWorldSpawnCommand.php @@ -59,7 +59,7 @@ class SetWorldSpawnCommand extends VanillaCommand{ return true; } }elseif(count($args) === 3){ - $level = $sender->getServer()->getDefaultLevel(); + $level = $sender->getServer()->getLevelManager()->getDefaultLevel(); $pos = new Vector3($this->getInteger($sender, $args[0]), $this->getInteger($sender, $args[1]), $this->getInteger($sender, $args[2])); }else{ throw new InvalidCommandSyntaxException(); diff --git a/src/pocketmine/command/defaults/StatusCommand.php b/src/pocketmine/command/defaults/StatusCommand.php index 9c258c3cc6..c580fda328 100644 --- a/src/pocketmine/command/defaults/StatusCommand.php +++ b/src/pocketmine/command/defaults/StatusCommand.php @@ -106,7 +106,7 @@ class StatusCommand extends VanillaCommand{ $sender->sendMessage(TextFormat::GOLD . "Maximum memory (manager): " . TextFormat::RED . number_format(round($server->getProperty("memory.global-limit"), 2), 2) . " MB."); } - foreach($server->getLevels() as $level){ + foreach($server->getLevelManager()->getLevels() as $level){ $levelName = $level->getFolderName() !== $level->getName() ? " (" . $level->getName() . ")" : ""; $timeColor = ($level->getTickRate() > 1 or $level->getTickRateTime() > 40) ? TextFormat::RED : TextFormat::YELLOW; $tickRate = $level->getTickRate() > 1 ? " (tick rate " . $level->getTickRate() . ")" : ""; diff --git a/src/pocketmine/command/defaults/TimeCommand.php b/src/pocketmine/command/defaults/TimeCommand.php index 61a9967e14..2289e3f716 100644 --- a/src/pocketmine/command/defaults/TimeCommand.php +++ b/src/pocketmine/command/defaults/TimeCommand.php @@ -54,7 +54,7 @@ class TimeCommand extends VanillaCommand{ return true; } - foreach($sender->getServer()->getLevels() as $level){ + foreach($sender->getServer()->getLevelManager()->getLevels() as $level){ $level->startTime(); } Command::broadcastCommandMessage($sender, "Restarted the time"); @@ -65,7 +65,7 @@ class TimeCommand extends VanillaCommand{ return true; } - foreach($sender->getServer()->getLevels() as $level){ + foreach($sender->getServer()->getLevelManager()->getLevels() as $level){ $level->stopTime(); } Command::broadcastCommandMessage($sender, "Stopped the time"); @@ -79,7 +79,7 @@ class TimeCommand extends VanillaCommand{ if($sender instanceof Player){ $level = $sender->getLevel(); }else{ - $level = $sender->getServer()->getDefaultLevel(); + $level = $sender->getServer()->getLevelManager()->getDefaultLevel(); } $sender->sendMessage(new TranslationContainer("commands.time.query", [$level->getTime()])); return true; @@ -105,7 +105,7 @@ class TimeCommand extends VanillaCommand{ $value = $this->getInteger($sender, $args[1], 0); } - foreach($sender->getServer()->getLevels() as $level){ + foreach($sender->getServer()->getLevelManager()->getLevels() as $level){ $level->setTime($value); } Command::broadcastCommandMessage($sender, new TranslationContainer("commands.time.set", [$value])); @@ -117,7 +117,7 @@ class TimeCommand extends VanillaCommand{ } $value = $this->getInteger($sender, $args[1], 0); - foreach($sender->getServer()->getLevels() as $level){ + foreach($sender->getServer()->getLevelManager()->getLevels() as $level){ $level->setTime($level->getTime() + $value); } Command::broadcastCommandMessage($sender, new TranslationContainer("commands.time.added", [$value])); diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 617f9f4f2c..56846fc478 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -625,7 +625,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ public function getOwningEntity() : ?Entity{ $eid = $this->getOwningEntityId(); if($eid !== null){ - return $this->server->findEntity($eid); + return $this->server->getLevelManager()->findEntity($eid); } return null; @@ -665,7 +665,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ public function getTargetEntity() : ?Entity{ $eid = $this->getTargetEntityId(); if($eid !== null){ - return $this->server->findEntity($eid); + return $this->server->getLevelManager()->findEntity($eid); } return null; diff --git a/src/pocketmine/entity/object/ExperienceOrb.php b/src/pocketmine/entity/object/ExperienceOrb.php index 96578acd0f..d962de77fc 100644 --- a/src/pocketmine/entity/object/ExperienceOrb.php +++ b/src/pocketmine/entity/object/ExperienceOrb.php @@ -150,7 +150,7 @@ class ExperienceOrb extends Entity{ return null; } - $entity = $this->server->findEntity($this->targetPlayerRuntimeId); + $entity = $this->server->getLevelManager()->findEntity($this->targetPlayerRuntimeId); if($entity instanceof Human){ return $entity; } diff --git a/src/pocketmine/event/entity/EntityDamageByChildEntityEvent.php b/src/pocketmine/event/entity/EntityDamageByChildEntityEvent.php index 879af9e684..e10e062ba9 100644 --- a/src/pocketmine/event/entity/EntityDamageByChildEntityEvent.php +++ b/src/pocketmine/event/entity/EntityDamageByChildEntityEvent.php @@ -51,6 +51,6 @@ class EntityDamageByChildEntityEvent extends EntityDamageByEntityEvent{ * @return Entity|null */ public function getChild() : ?Entity{ - return $this->getEntity()->getLevel()->getServer()->findEntity($this->childEntityEid); + return $this->getEntity()->getLevel()->getServer()->getLevelManager()->findEntity($this->childEntityEid); } } diff --git a/src/pocketmine/event/entity/EntityDamageByEntityEvent.php b/src/pocketmine/event/entity/EntityDamageByEntityEvent.php index 970818aa5b..a89a0dea71 100644 --- a/src/pocketmine/event/entity/EntityDamageByEntityEvent.php +++ b/src/pocketmine/event/entity/EntityDamageByEntityEvent.php @@ -69,7 +69,7 @@ class EntityDamageByEntityEvent extends EntityDamageEvent{ * @return Entity|null */ public function getDamager() : ?Entity{ - return $this->getEntity()->getLevel()->getServer()->findEntity($this->damagerEntityId); + return $this->getEntity()->getLevel()->getServer()->getLevelManager()->findEntity($this->damagerEntityId); } /** diff --git a/src/pocketmine/event/server/QueryRegenerateEvent.php b/src/pocketmine/event/server/QueryRegenerateEvent.php index beef6b987b..c54d51166b 100644 --- a/src/pocketmine/event/server/QueryRegenerateEvent.php +++ b/src/pocketmine/event/server/QueryRegenerateEvent.php @@ -88,7 +88,8 @@ class QueryRegenerateEvent extends ServerEvent{ $this->gametype = ($server->getGamemode() & 0x01) === 0 ? "SMP" : "CMP"; $this->version = $server->getVersion(); $this->server_engine = $server->getName() . " " . $server->getPocketMineVersion(); - $this->map = $server->getDefaultLevel() === null ? "unknown" : $server->getDefaultLevel()->getName(); + $level = $server->getLevelManager()->getDefaultLevel(); + $this->map = $level === null ? "unknown" : $level->getName(); $this->numPlayers = count($this->players); $this->maxPlayers = $server->getMaxPlayers(); $this->whitelist = $server->hasWhitelist() ? "on" : "off"; diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 374ece7d84..664bacca41 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -40,7 +40,6 @@ use pocketmine\event\level\ChunkLoadEvent; use pocketmine\event\level\ChunkPopulateEvent; use pocketmine\event\level\ChunkUnloadEvent; use pocketmine\event\level\LevelSaveEvent; -use pocketmine\event\level\LevelUnloadEvent; use pocketmine\event\level\SpawnChangeEvent; use pocketmine\event\player\PlayerInteractEvent; use pocketmine\item\Item; @@ -359,7 +358,6 @@ class Level implements ChunkManager, Metadatable{ $this->levelId = static::$levelIdCounter++; $this->blockMetadata = new BlockMetadataStore($this); $this->server = $server; - $this->autoSave = $server->getAutoSave(); $this->provider = $provider; @@ -455,6 +453,9 @@ class Level implements ChunkManager, Metadatable{ return $this->closed; } + /** + * @internal + */ public function close(){ if($this->closed){ throw new \InvalidStateException("Tried to close a level which is already closed"); @@ -558,52 +559,6 @@ class Level implements ChunkManager, Metadatable{ $this->autoSave = $value; } - /** - * @internal DO NOT use this from plugins, it's for internal use only. Use Server->unloadLevel() instead. - * - * @param bool $force default false, force unload of default level - * - * @return bool - * @throws \InvalidStateException if trying to unload a level during level tick - */ - public function onUnload(bool $force = false) : bool{ - if($this->doingTick and !$force){ - throw new \InvalidStateException("Cannot unload a level during level tick"); - } - - $ev = new LevelUnloadEvent($this); - - if($this === $this->server->getDefaultLevel() and !$force){ - $ev->setCancelled(true); - } - - $ev->call(); - - if(!$force and $ev->isCancelled()){ - return false; - } - - $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.level.unloading", [$this->getName()])); - $defaultLevel = $this->server->getDefaultLevel(); - foreach($this->getPlayers() as $player){ - if($this === $defaultLevel or $defaultLevel === null){ - $player->close($player->getLeaveMessage(), "Forced default level unload"); - }elseif($defaultLevel instanceof Level){ - $player->teleport($this->server->getDefaultLevel()->getSafeSpawn()); - } - } - - if($this === $defaultLevel){ - $this->server->setDefaultLevel(null); - } - - $this->server->removeLevel($this); - - $this->close(); - - return true; - } - /** * Gets the players being used in a specific chunk * @@ -738,6 +693,10 @@ class Level implements ChunkManager, Metadatable{ } } + public function isDoingTick() : bool{ + return $this->doingTick; + } + /** * WARNING: Do not use this, it's only for internal use. * Changes to this function won't be recorded on the version. diff --git a/src/pocketmine/level/LevelManager.php b/src/pocketmine/level/LevelManager.php new file mode 100644 index 0000000000..1631175a24 --- /dev/null +++ b/src/pocketmine/level/LevelManager.php @@ -0,0 +1,439 @@ +server = $server; + + $this->autoTickRate = (bool) $this->server->getProperty("level-settings.auto-tick-rate", $this->autoTickRate); + $this->autoTickRateLimit = (int) $this->server->getProperty("level-settings.auto-tick-rate-limit", $this->autoTickRateLimit); + $this->alwaysTickPlayers = (bool) $this->server->getProperty("level-settings.always-tick-players", $this->alwaysTickPlayers); + $this->baseTickRate = (int) $this->server->getProperty("level-settings.base-tick-rate", $this->baseTickRate); + + $this->autoSave = $this->server->getConfigBool("auto-save", $this->autoSave); + $this->autoSaveTicks = (int) $this->server->getProperty("ticks-per.autosave", 6000); + } + + /** + * @return Level[] + */ + public function getLevels() : array{ + return $this->levels; + } + + /** + * @return Level|null + */ + public function getDefaultLevel() : ?Level{ + return $this->levelDefault; + } + + /** + * Sets the default level to a different level + * This won't change the level-name property, + * it only affects the server on runtime + * + * @param Level|null $level + */ + public function setDefaultLevel(?Level $level) : void{ + if($level === null or ($this->isLevelLoaded($level->getFolderName()) and $level !== $this->levelDefault)){ + $this->levelDefault = $level; + } + } + + /** + * @param string $name + * + * @return bool + */ + public function isLevelLoaded(string $name) : bool{ + return $this->getLevelByName($name) instanceof Level; + } + + /** + * @param int $levelId + * + * @return Level|null + */ + public function getLevel(int $levelId) : ?Level{ + return $this->levels[$levelId] ?? null; + } + + /** + * NOTE: This matches levels based on the FOLDER name, NOT the display name. + * + * @param string $name + * + * @return Level|null + */ + public function getLevelByName(string $name) : ?Level{ + foreach($this->levels as $level){ + if($level->getFolderName() === $name){ + return $level; + } + } + + return null; + } + + /** + * @param Level $level + * @param bool $forceUnload + * + * @return bool + * + * @throws \InvalidArgumentException + */ + public function unloadLevel(Level $level, bool $forceUnload = false) : bool{ + if($level === $this->getDefaultLevel() and !$forceUnload){ + throw new \InvalidArgumentException("The default level cannot be unloaded while running, please switch levels."); + } + if($level->isDoingTick()){ + throw new \InvalidArgumentException("Cannot unload a level during level tick"); + } + + $ev = new LevelUnloadEvent($level); + if($level === $this->levelDefault and !$forceUnload){ + $ev->setCancelled(true); + } + + $ev->call(); + + if(!$forceUnload and $ev->isCancelled()){ + return false; + } + + $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.level.unloading", [$level->getName()])); + foreach($level->getPlayers() as $player){ + if($level === $this->levelDefault or $this->levelDefault === null){ + $player->close($player->getLeaveMessage(), "Forced default level unload"); + }elseif($this->levelDefault instanceof Level){ + $player->teleport($this->levelDefault->getSafeSpawn()); + } + } + + if($level === $this->levelDefault){ + $this->levelDefault = null; + } + unset($this->levels[$level->getId()]); + + $level->close(); + return true; + } + + /** + * Loads a level from the data directory + * + * @param string $name + * + * @return bool + * + * @throws LevelException + */ + public function loadLevel(string $name) : bool{ + if(trim($name) === ""){ + throw new LevelException("Invalid empty level name"); + } + if($this->isLevelLoaded($name)){ + return true; + }elseif(!$this->isLevelGenerated($name)){ + $this->server->getLogger()->notice($this->server->getLanguage()->translateString("pocketmine.level.notFound", [$name])); + + return false; + } + + $path = $this->server->getDataPath() . "worlds/" . $name . "/"; + + $providers = LevelProviderManager::getMatchingProviders($path); + if(count($providers) !== 1){ + $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.level.loadError", [ + $name, + empty($providers) ? + $this->server->getLanguage()->translateString("pocketmine.level.unknownFormat") : + $this->server->getLanguage()->translateString("pocketmine.level.ambiguousFormat", [implode(", ", array_keys($providers))]) + ])); + return false; + } + $providerClass = array_shift($providers); + + try{ + /** @see LevelProvider::__construct() */ + $level = new Level($this->server, $name, new $providerClass($path)); + }catch(UnsupportedLevelFormatException $e){ + $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.level.loadError", [$name, $e->getMessage()])); + return false; + } + + $this->levels[$level->getId()] = $level; + $level->setTickRate($this->baseTickRate); + $level->setAutoSave($this->autoSave); + + (new LevelLoadEvent($level))->call(); + + return true; + } + + /** + * Generates a new level if it does not exist + * + * @param string $name + * @param int|null $seed + * @param string $generator Class name that extends pocketmine\level\generator\Generator + * @param array $options + * @param bool $backgroundGeneration + * + * @return bool + * @throws \InvalidArgumentException + */ + public function generateLevel(string $name, int $seed = null, string $generator = Normal::class, array $options = [], bool $backgroundGeneration = true) : bool{ + if(trim($name) === "" or $this->isLevelGenerated($name)){ + return false; + } + + $seed = $seed ?? random_int(INT32_MIN, INT32_MAX); + + Utils::testValidInstance($generator, Generator::class); + + $providerClass = LevelProviderManager::getDefault(); + + $path = $this->server->getDataPath() . "worlds/" . $name . "/"; + /** @var LevelProvider $providerClass */ + $providerClass::generate($path, $name, $seed, $generator, $options); + + /** @see LevelProvider::__construct() */ + $level = new Level($this->server, $name, new $providerClass($path)); + $this->levels[$level->getId()] = $level; + + $level->setTickRate($this->baseTickRate); + $level->setAutoSave($this->autoSave); + + (new LevelInitEvent($level))->call(); + + (new LevelLoadEvent($level))->call(); + + if(!$backgroundGeneration){ + return true; + } + + $this->server->getLogger()->notice($this->server->getLanguage()->translateString("pocketmine.level.backgroundGeneration", [$name])); + + $spawnLocation = $level->getSpawnLocation(); + $centerX = $spawnLocation->getFloorX() >> 4; + $centerZ = $spawnLocation->getFloorZ() >> 4; + + $order = []; + + for($X = -3; $X <= 3; ++$X){ + for($Z = -3; $Z <= 3; ++$Z){ + $distance = $X ** 2 + $Z ** 2; + $chunkX = $X + $centerX; + $chunkZ = $Z + $centerZ; + $index = Level::chunkHash($chunkX, $chunkZ); + $order[$index] = $distance; + } + } + + asort($order); + + foreach($order as $index => $distance){ + Level::getXZ($index, $chunkX, $chunkZ); + $level->populateChunk($chunkX, $chunkZ, true); + } + + return true; + } + + /** + * @param string $name + * + * @return bool + */ + public function isLevelGenerated(string $name) : bool{ + if(trim($name) === ""){ + return false; + } + $path = $this->server->getDataPath() . "worlds/" . $name . "/"; + if(!($this->getLevelByName($name) instanceof Level)){ + return !empty(LevelProviderManager::getMatchingProviders($path)); + } + + return true; + } + + /** + * Searches all levels for the entity with the specified ID. + * Useful for tracking entities across multiple worlds without needing strong references. + * + * @param int $entityId + * + * @return Entity|null + */ + public function findEntity(int $entityId){ + foreach($this->levels as $level){ + assert(!$level->isClosed()); + if(($entity = $level->getEntity($entityId)) instanceof Entity){ + return $entity; + } + } + + return null; + } + + + public function tick(int $currentTick) : void{ + foreach($this->levels as $k => $level){ + if(!isset($this->levels[$k])){ + // Level unloaded during the tick of a level earlier in this loop, perhaps by plugin + continue; + } + if($level->getTickRate() > $this->baseTickRate and --$level->tickRateCounter > 0){ + if($this->alwaysTickPlayers){ + foreach($level->getPlayers() as $p){ + if($p->spawned){ + $p->onUpdate($currentTick); + } + } + } + continue; + } + + $levelTime = microtime(true); + $level->doTick($currentTick); + $tickMs = (microtime(true) - $levelTime) * 1000; + $level->tickRateTime = $tickMs; + + if($this->autoTickRate){ + if($tickMs < 50 and $level->getTickRate() > $this->baseTickRate){ + $level->setTickRate($r = $level->getTickRate() - 1); + if($r > $this->baseTickRate){ + $level->tickRateCounter = $level->getTickRate(); + } + $this->server->getLogger()->debug("Raising level \"{$level->getName()}\" tick rate to {$level->getTickRate()} ticks"); + }elseif($tickMs >= 50){ + if($level->getTickRate() === $this->baseTickRate){ + $level->setTickRate(max($this->baseTickRate + 1, min($this->autoTickRateLimit, (int) floor($tickMs / 50)))); + $this->server->getLogger()->debug(sprintf("Level \"%s\" took %gms, setting tick rate to %d ticks", $level->getName(), (int) round($tickMs, 2), $level->getTickRate())); + }elseif(($tickMs / $level->getTickRate()) >= 50 and $level->getTickRate() < $this->autoTickRateLimit){ + $level->setTickRate($level->getTickRate() + 1); + $this->server->getLogger()->debug(sprintf("Level \"%s\" took %gms, setting tick rate to %d ticks", $level->getName(), (int) round($tickMs, 2), $level->getTickRate())); + } + $level->tickRateCounter = $level->getTickRate(); + } + } + } + + if($this->autoSave and ++$this->autoSaveTicker >= $this->autoSaveTicks){ + $this->autoSaveTicker = 0; + $this->doAutoSave(); + } + } + + + /** + * @return bool + */ + public function getAutoSave() : bool{ + return $this->autoSave; + } + + /** + * @param bool $value + */ + public function setAutoSave(bool $value){ + $this->autoSave = $value; + foreach($this->levels as $level){ + $level->setAutoSave($this->autoSave); + } + } + + private function doAutoSave() : void{ + Timings::$worldSaveTimer->startTiming(); + foreach($this->levels as $level){ + foreach($level->getPlayers() as $player){ + if($player->spawned){ + $player->save(); + }elseif(!$player->isConnected()){ //TODO: check if this is ever possible + $this->server->removePlayer($player); + } + } + $level->save(false); + } + Timings::$worldSaveTimer->stopTiming(); + } +} diff --git a/src/pocketmine/level/generator/GeneratorManager.php b/src/pocketmine/level/generator/GeneratorManager.php index 5e24b1faaa..fbf8fb5327 100644 --- a/src/pocketmine/level/generator/GeneratorManager.php +++ b/src/pocketmine/level/generator/GeneratorManager.php @@ -25,8 +25,8 @@ namespace pocketmine\level\generator; use pocketmine\level\generator\hell\Nether; use pocketmine\level\generator\normal\Normal; +use pocketmine\utils\Utils; use function array_keys; -use function is_subclass_of; use function strtolower; final class GeneratorManager{ @@ -48,11 +48,11 @@ final class GeneratorManager{ * @param string $class Fully qualified name of class that extends \pocketmine\level\generator\Generator * @param string $name Alias for this generator type that can be written in configs * @param bool $overwrite Whether to force overwriting any existing registered generator with the same name + * + * @throws \InvalidArgumentException */ public static function addGenerator(string $class, string $name, bool $overwrite = false) : void{ - if(!is_subclass_of($class, Generator::class)){ - throw new \InvalidArgumentException("Class $class does not extend " . Generator::class); - } + Utils::testValidInstance($class, Generator::class); if(!$overwrite and isset(self::$list[$name = strtolower($name)])){ throw new \InvalidArgumentException("Alias \"$name\" is already assigned"); diff --git a/src/pocketmine/timings/TimingsHandler.php b/src/pocketmine/timings/TimingsHandler.php index 4018ee7302..4667cb2311 100644 --- a/src/pocketmine/timings/TimingsHandler.php +++ b/src/pocketmine/timings/TimingsHandler.php @@ -64,7 +64,7 @@ class TimingsHandler{ $entities = 0; $livingEntities = 0; - foreach(Server::getInstance()->getLevels() as $level){ + foreach(Server::getInstance()->getLevelManager()->getLevels() as $level){ $entities += count($level->getEntities()); foreach($level->getEntities() as $e){ if($e instanceof Living){ From d2768188e8d401ecea53702585d4d1f5ad1d9ad1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 12 Jan 2019 19:52:28 +0000 Subject: [PATCH 0383/3224] LevelManager: remove unnecessary message --- src/pocketmine/level/LevelManager.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pocketmine/level/LevelManager.php b/src/pocketmine/level/LevelManager.php index 1631175a24..b4f54ece2f 100644 --- a/src/pocketmine/level/LevelManager.php +++ b/src/pocketmine/level/LevelManager.php @@ -213,8 +213,6 @@ class LevelManager{ if($this->isLevelLoaded($name)){ return true; }elseif(!$this->isLevelGenerated($name)){ - $this->server->getLogger()->notice($this->server->getLanguage()->translateString("pocketmine.level.notFound", [$name])); - return false; } From 82788774b02136736ee428aac98df28a32e064c2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Jan 2019 13:24:02 +0000 Subject: [PATCH 0384/3224] Level: Queue all block updates until the end of tick this allows deduplicating block updates when lots of adjacent blocks are set on a tick, which has beneficial effects on performance. It also fixes #2659. Future scope: - Use this mechanism to deal with explosions properly. - Don't execute block updates for air blocks. --- src/pocketmine/level/Level.php | 38 ++++++++++++++-------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 664bacca41..ec9cf76f35 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -63,7 +63,6 @@ use pocketmine\level\particle\DestroyBlockParticle; use pocketmine\level\particle\Particle; use pocketmine\level\sound\Sound; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Facing; use pocketmine\math\Vector2; use pocketmine\math\Vector3; use pocketmine\metadata\BlockMetadataStore; @@ -217,6 +216,8 @@ class Level implements ChunkManager, Metadatable{ /** @var \SplQueue */ private $neighbourBlockUpdateQueue; + /** @var bool[] blockhash => dummy */ + private $neighbourBlockUpdateQueueIndex = []; /** @var Player[][] */ private $chunkSendQueue = []; @@ -759,8 +760,12 @@ class Level implements ChunkManager, Metadatable{ $ev = new BlockUpdateEvent($block); $ev->call(); if(!$ev->isCancelled()){ + foreach($this->getNearbyEntities(AxisAlignedBB::one()->offset($block->x, $block->y, $block->z)) as $entity){ + $entity->onNearbyBlockChange(); + } $block->onNearbyBlockChange(); } + unset($this->neighbourBlockUpdateQueueIndex[$index]); } $this->timings->doTickPending->stopTiming(); @@ -1081,19 +1086,12 @@ class Level implements ChunkManager, Metadatable{ $this->scheduledBlockUpdateQueue->insert(new Vector3((int) $pos->x, (int) $pos->y, (int) $pos->z), $delay + $this->server->getTick()); } - /** - * Schedules the blocks around the specified position to be updated at the end of this tick. - * Blocks will be updated with the normal update type. - * - * @param Vector3 $pos - */ - public function scheduleNeighbourBlockUpdates(Vector3 $pos){ - $pos = $pos->floor(); - - foreach(Facing::ALL as $face){ - $side = $pos->getSide($face); - if($this->isInWorld($side->x, $side->y, $side->z)){ - $this->neighbourBlockUpdateQueue->enqueue(Level::blockHash($side->x, $side->y, $side->z)); + private function tryAddToNeighbourUpdateQueue(Vector3 $pos) : void{ + if($this->isInWorld($pos->x, $pos->y, $pos->z)){ + $hash = Level::blockHash($pos->x, $pos->y, $pos->z); + if(!isset($this->neighbourBlockUpdateQueueIndex[$hash])){ + $this->neighbourBlockUpdateQueue->enqueue($hash); + $this->neighbourBlockUpdateQueueIndex[$hash] = true; } } } @@ -1559,15 +1557,9 @@ class Level implements ChunkManager, Metadatable{ if($update){ $this->updateAllLight($block); - - $ev = new BlockUpdateEvent($block); - $ev->call(); - if(!$ev->isCancelled()){ - foreach($this->getNearbyEntities(AxisAlignedBB::one()->offset($block->x, $block->y, $block->z)->expand(1, 1, 1)) as $entity){ - $entity->onNearbyBlockChange(); - } - $ev->getBlock()->onNearbyBlockChange(); - $this->scheduleNeighbourBlockUpdates($block); + $this->tryAddToNeighbourUpdateQueue($block); + foreach($block->sides() as $side){ + $this->tryAddToNeighbourUpdateQueue($side); } } From 1dca9074d5f087d15f8d30d2941150fe51617489 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Jan 2019 14:17:56 +0000 Subject: [PATCH 0385/3224] Remove hacks for triggering adjacent light refill --- src/pocketmine/level/Level.php | 8 +++----- src/pocketmine/level/light/LightUpdate.php | 14 +++++++------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index ec9cf76f35..9490a2d0b5 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1440,8 +1440,8 @@ class Level implements ChunkManager, Metadatable{ for($i = $y; $i >= $newHeightMap; --$i){ $this->skyLightUpdate->setAndUpdateLight($x, $i, $z, 15); } - }else{ //No heightmap change, block changed "underground" - $this->skyLightUpdate->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentBlockSkyLight($x, $y, $z) - BlockFactory::$lightFilter[($source->getId() << 4) | $source->getDamage()])); + }else{ //No heightmap change, block changed "underground" - trigger recalculation from surroundings + $this->skyLightUpdate->setAndUpdateLight($x, $y, $z, 0); } $this->timings->doBlockSkyLightUpdates->stopTiming(); @@ -1471,12 +1471,10 @@ class Level implements ChunkManager, Metadatable{ $this->timings->doBlockLightUpdates->startTiming(); $block = $this->getBlockAt($x, $y, $z); - $newLevel = max($block->getLightLevel(), $this->getHighestAdjacentBlockLight($x, $y, $z) - BlockFactory::$lightFilter[($block->getId() << 4) | $block->getDamage()]); - if($this->blockLightUpdate === null){ $this->blockLightUpdate = new BlockLightUpdate($this); } - $this->blockLightUpdate->setAndUpdateLight($x, $y, $z, $newLevel); + $this->blockLightUpdate->setAndUpdateLight($x, $y, $z, $block->getLightLevel()); $this->timings->doBlockLightUpdates->stopTiming(); } diff --git a/src/pocketmine/level/light/LightUpdate.php b/src/pocketmine/level/light/LightUpdate.php index 02b803cc01..567270a1eb 100644 --- a/src/pocketmine/level/light/LightUpdate.php +++ b/src/pocketmine/level/light/LightUpdate.php @@ -72,13 +72,13 @@ abstract class LightUpdate{ if($oldLevel !== $newLevel){ $this->setLight($x, $y, $z, $newLevel); - if($oldLevel < $newLevel){ //light increased - $this->spreadVisited[$blockHash] = true; - $this->spreadQueue->enqueue([$x, $y, $z]); - }else{ //light removed - $this->removalVisited[$blockHash] = true; - $this->removalQueue->enqueue([$x, $y, $z, $oldLevel]); - } + } + if($newLevel > $oldLevel){ //light increased + $this->spreadVisited[$blockHash] = true; + $this->spreadQueue->enqueue([$x, $y, $z]); + }elseif($newLevel < 15){ //light removed or stayed the same, force recheck nearby environment + $this->removalVisited[$blockHash] = true; + $this->removalQueue->enqueue([$x, $y, $z, $oldLevel]); } } } From d2082c0383ef204a58457133d304427ee0206568 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Jan 2019 14:22:35 +0000 Subject: [PATCH 0386/3224] Explosion: Recalculate light on destroyed blocks this has been a bug for a long long time. I think the reason it was never addressed is because of the performance impact associated with it. However, that performance impact is now gone thanks to light update batching. --- src/pocketmine/level/Explosion.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index bd37863f53..540b4e0fef 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -230,6 +230,7 @@ class Explosion{ $t->close(); } + $this->level->updateAllLight($block); $pos = new Vector3($block->x, $block->y, $block->z); From 9c53b4185118d61931faa753de9a20af7b22cd18 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Jan 2019 19:32:30 +0000 Subject: [PATCH 0387/3224] Added PlayerInfo, Player is no longer accessible during PlayerPreLoginEvent --- src/pocketmine/Player.php | 34 ++++--- src/pocketmine/PlayerInfo.php | 97 +++++++++++++++++++ src/pocketmine/entity/Human.php | 4 +- .../event/player/PlayerPreLoginEvent.php | 51 ++++++++-- .../mcpe/handler/LoginSessionHandler.php | 4 +- .../network/mcpe/protocol/LoginPacket.php | 67 ++++++------- 6 files changed, 191 insertions(+), 66 deletions(-) create mode 100644 src/pocketmine/PlayerInfo.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 1ddd2db4b0..b77400b5fd 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -191,11 +191,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ /** @var NetworkSession */ protected $networkSession; - /** @var float */ - public $creationTime = 0; - /** @var bool */ - public $loggedIn = false; + protected $loggedIn = false; /** @var bool */ public $spawned = false; @@ -212,6 +209,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ protected $xuid = ""; /** @var bool */ protected $authenticated = false; + /** @var PlayerInfo|null */ + protected $playerInfo = null; protected $windowCnt = 2; /** @var int[] */ @@ -379,9 +378,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ * as SimpleAuth for authentication. This is NOT SAFE anymore as this UUID is now what was given by the client, NOT * a server-computed UUID.) * - * @return UUID|null + * @return UUID */ - public function getUniqueId() : ?UUID{ + public function getUniqueId() : UUID{ return parent::getUniqueId(); } @@ -693,8 +692,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->chunksPerTick = (int) $this->server->getProperty("chunk-sending.per-tick", 4); $this->spawnThreshold = (int) (($this->server->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); - $this->creationTime = microtime(true); - $this->allowMovementCheats = (bool) $this->server->getProperty("player.anti-cheat.allow-movement-cheats", false); } @@ -1741,20 +1738,25 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } public function handleLogin(LoginPacket $packet) : bool{ - $this->username = TextFormat::clean($packet->username); + $this->playerInfo = $packet->playerInfo; + $this->username = TextFormat::clean($this->playerInfo->getUsername()); $this->displayName = $this->username; $this->iusername = strtolower($this->username); - $this->locale = $packet->locale; - $this->randomClientId = $packet->clientId; + $this->locale = $this->playerInfo->getLocale(); + $this->randomClientId = $this->playerInfo->getClientId(); - $this->uuid = UUID::fromString($packet->clientUUID); + $this->uuid = $this->playerInfo->getUuid(); $this->rawUUID = $this->uuid->toBinary(); - $this->xuid = $packet->xuid; + $this->xuid = $this->playerInfo->getXuid(); - $this->setSkin($packet->skin); + $this->setSkin($this->playerInfo->getSkin()); - - $ev = new PlayerPreLoginEvent($this, $this->server->requiresAuthentication()); + $ev = new PlayerPreLoginEvent( + $this->playerInfo, + $this->networkSession->getIp(), + $this->networkSession->getPort(), + $this->server->requiresAuthentication() + ); if(count($this->server->getOnlinePlayers()) >= $this->server->getMaxPlayers()){ $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_SERVER_FULL, "disconnectionScreen.serverFull"); } diff --git a/src/pocketmine/PlayerInfo.php b/src/pocketmine/PlayerInfo.php new file mode 100644 index 0000000000..cc54f5529d --- /dev/null +++ b/src/pocketmine/PlayerInfo.php @@ -0,0 +1,97 @@ +username = $username; + $this->uuid = $uuid; + $this->skin = $skin; + $this->locale = $locale; + $this->xuid = $xuid; + $this->clientId = $clientId; + } + + /** + * @return string + */ + public function getUsername() : string{ + return $this->username; + } + + /** + * @return UUID + */ + public function getUuid() : UUID{ + return $this->uuid; + } + + /** + * @return Skin + */ + public function getSkin() : Skin{ + return $this->skin; + } + + /** + * @return string + */ + public function getLocale() : string{ + return $this->locale; + } + + /** + * @return string + */ + public function getXuid() : string{ + return $this->xuid; + } + + /** + * @return int + */ + public function getClientId() : int{ + return $this->clientId; + } +} diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 0ab10733d0..a7b379471e 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -129,9 +129,9 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ } /** - * @return UUID|null + * @return UUID */ - public function getUniqueId() : ?UUID{ + public function getUniqueId() : UUID{ return $this->uuid; } diff --git a/src/pocketmine/event/player/PlayerPreLoginEvent.php b/src/pocketmine/event/player/PlayerPreLoginEvent.php index 18aa5f0813..fef54b7f9a 100644 --- a/src/pocketmine/event/player/PlayerPreLoginEvent.php +++ b/src/pocketmine/event/player/PlayerPreLoginEvent.php @@ -23,7 +23,8 @@ declare(strict_types=1); namespace pocketmine\event\player; -use pocketmine\Player; +use pocketmine\event\Event; +use pocketmine\PlayerInfo; use function array_keys; /** @@ -35,11 +36,8 @@ use function array_keys; * * WARNING: Any information about the player CANNOT be trusted at this stage, because they are not authenticated and * could be a hacker posing as another player. - * - * WARNING: Due to internal bad architecture, the player is not fully constructed at this stage, and errors might occur - * when calling API methods on the player. Tread with caution. */ -class PlayerPreLoginEvent extends PlayerEvent{ +class PlayerPreLoginEvent extends Event{ public const KICK_REASON_PLUGIN = 0; public const KICK_REASON_SERVER_FULL = 1; public const KICK_REASON_SERVER_WHITELISTED = 2; @@ -52,6 +50,12 @@ class PlayerPreLoginEvent extends PlayerEvent{ self::KICK_REASON_BANNED ]; + /** @var PlayerInfo */ + private $playerInfo; + /** @var string */ + private $ip; + /** @var int */ + private $port; /** @var bool */ protected $authRequired; @@ -59,14 +63,43 @@ class PlayerPreLoginEvent extends PlayerEvent{ protected $kickReasons = []; /** - * @param Player $player - * @param bool $authRequired + * @param PlayerInfo $playerInfo + * @param string $ip + * @param int $port + * @param bool $authRequired */ - public function __construct(Player $player, bool $authRequired){ - $this->player = $player; + public function __construct(PlayerInfo $playerInfo, string $ip, int $port, bool $authRequired){ + $this->playerInfo = $playerInfo; + $this->ip = $ip; + $this->port = $port; $this->authRequired = $authRequired; } + /** + * Returns an object containing self-proclaimed information about the connecting player. + * WARNING: THE PLAYER IS NOT VERIFIED DURING THIS EVENT. At this point, it's unknown if the player is real or a + * hacker. + * + * @return PlayerInfo + */ + public function getPlayerInfo() : PlayerInfo{ + return $this->playerInfo; + } + + /** + * @return string + */ + public function getIp() : string{ + return $this->ip; + } + + /** + * @return int + */ + public function getPort() : int{ + return $this->port; + } + /** * @return bool */ diff --git a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php index 6fd4d9a566..7db8565413 100644 --- a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php @@ -60,13 +60,13 @@ class LoginSessionHandler extends SessionHandler{ return true; } - if(!Player::isValidUserName($packet->username)){ + if(!Player::isValidUserName($packet->playerInfo->getUsername())){ $this->session->disconnect("disconnectionScreen.invalidName"); return true; } - if($packet->skin === null or !$packet->skin->isValid()){ + if(!$packet->playerInfo->getSkin()->isValid()){ $this->session->disconnect("disconnectionScreen.invalidSkin"); return true; diff --git a/src/pocketmine/network/mcpe/protocol/LoginPacket.php b/src/pocketmine/network/mcpe/protocol/LoginPacket.php index bad35b06b8..99d16930d2 100644 --- a/src/pocketmine/network/mcpe/protocol/LoginPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LoginPacket.php @@ -29,8 +29,10 @@ namespace pocketmine\network\mcpe\protocol; use Particle\Validator\Validator; use pocketmine\entity\Skin; use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\PlayerInfo; use pocketmine\utils\BinaryStream; use pocketmine\utils\Utils; +use pocketmine\utils\UUID; use function array_filter; use function base64_decode; use function count; @@ -44,6 +46,10 @@ class LoginPacket extends DataPacket{ public const EDITION_POCKET = 0; + public const I_USERNAME = 'displayName'; + public const I_UUID = 'identity'; + public const I_XUID = 'XUID'; + public const I_CLIENT_RANDOM_ID = 'ClientRandomId'; public const I_SERVER_ADDRESS = 'ServerAddress'; public const I_LANGUAGE_CODE = 'LanguageCode'; @@ -54,27 +60,16 @@ class LoginPacket extends DataPacket{ public const I_GEOMETRY_NAME = 'SkinGeometryName'; public const I_GEOMETRY_DATA = 'SkinGeometry'; - /** @var string */ - public $username; /** @var int */ public $protocol; - /** @var string */ - public $clientUUID; - /** @var int */ - public $clientId; - /** @var string */ - public $xuid; - /** @var string */ - public $identityPublicKey; - /** @var string */ - public $serverAddress; - /** @var string */ - public $locale; - /** @var Skin|null */ - public $skin; + + /** @var PlayerInfo */ + public $playerInfo; /** @var string[] array of encoded JWT */ public $chainDataJwt = []; + /** @var array|null extraData index of whichever JWT has it */ + public $extraData = null; /** @var string */ public $clientDataJwt; /** @var array decoded payload of the clientData JWT */ @@ -138,8 +133,6 @@ class LoginPacket extends DataPacket{ self::validate($vd, "chainData", $chainData); $this->chainDataJwt = $chainData['chain']; - - $hasExtraData = false; foreach($this->chainDataJwt as $k => $chain){ //validate every chain element $claims = Utils::getJwtClaims($chain); @@ -147,23 +140,20 @@ class LoginPacket extends DataPacket{ if(!is_array($claims["extraData"])){ throw new \UnexpectedValueException("'extraData' key should be an array"); } - if($hasExtraData){ + if($this->extraData !== null){ throw new \UnexpectedValueException("Found 'extraData' more than once in chainData"); } - $hasExtraData = true; $extraV = new Validator(); - $extraV->required('displayName')->string(); - $extraV->required('identity')->uuid(); - $extraV->required('XUID')->string()->digits()->allowEmpty(true); + $extraV->required(self::I_USERNAME)->string(); + $extraV->required(self::I_UUID)->uuid(); + $extraV->required(self::I_XUID)->string()->digits()->allowEmpty(true); self::validate($extraV, "chain.$k.extraData", $claims['extraData']); - $this->username = $claims["extraData"]["displayName"]; - $this->clientUUID = $claims["extraData"]["identity"]; - $this->xuid = $claims["extraData"]["XUID"]; + $this->extraData = $claims['extraData']; } } - if(!$hasExtraData){ + if($this->extraData === null){ throw new \UnexpectedValueException("'extraData' not found in chain data"); } @@ -184,16 +174,19 @@ class LoginPacket extends DataPacket{ $this->clientData = $clientData; - $this->clientId = $this->clientData[self::I_CLIENT_RANDOM_ID]; - $this->serverAddress = $this->clientData[self::I_SERVER_ADDRESS]; - $this->locale = $this->clientData[self::I_LANGUAGE_CODE]; - - $this->skin = new Skin( - $this->clientData[self::I_SKIN_ID], - base64_decode($this->clientData[self::I_SKIN_DATA]), - base64_decode($this->clientData[self::I_CAPE_DATA]), - $this->clientData[self::I_GEOMETRY_NAME], - base64_decode($this->clientData[self::I_GEOMETRY_DATA]) + $this->playerInfo = new PlayerInfo( + $this->extraData[self::I_USERNAME], + UUID::fromString($this->extraData[self::I_UUID]), + new Skin( + $this->clientData[self::I_SKIN_ID], + base64_decode($this->clientData[self::I_SKIN_DATA]), + base64_decode($this->clientData[self::I_CAPE_DATA]), + $this->clientData[self::I_GEOMETRY_NAME], + base64_decode($this->clientData[self::I_GEOMETRY_DATA]) + ), + $this->clientData[self::I_LANGUAGE_CODE], + $this->extraData[self::I_XUID], + $this->clientData[self::I_CLIENT_RANDOM_ID] ); } From 3e1aa3e2b4c9199fb79a9c3fa43559c03fb8b7b8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Jan 2019 20:41:17 +0000 Subject: [PATCH 0388/3224] Network: remove Server dependency --- src/pocketmine/network/Network.php | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index a745d2ea4c..e83952f484 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -30,13 +30,9 @@ use pocketmine\event\server\NetworkInterfaceRegisterEvent; use pocketmine\event\server\NetworkInterfaceUnregisterEvent; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\PacketPool; -use pocketmine\Server; use function spl_object_hash; class Network{ - /** @var Server */ - private $server; - /** @var NetworkInterface[] */ private $interfaces = []; @@ -52,11 +48,8 @@ class Network{ /** @var NetworkSession[] */ private $updateSessions = []; - public function __construct(Server $server){ + public function __construct(){ PacketPool::init(); - - $this->server = $server; - } public function addStatistics(float $upload, float $download) : void{ @@ -146,13 +139,6 @@ class Network{ } } - /** - * @return Server - */ - public function getServer() : Server{ - return $this->server; - } - /** * @param string $address * @param int $port From ff5cb84b810f1528ce9e35d2e06efbcade3c5dd1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Jan 2019 21:00:16 +0000 Subject: [PATCH 0389/3224] Server: fixed an oops --- src/pocketmine/Server.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index f8709ca67c..116f210597 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1298,7 +1298,7 @@ class Server{ $this->getLogger()->debug("Server unique id: " . $this->getServerUniqueId()); $this->getLogger()->debug("Machine unique id: " . Utils::getMachineUniqueId()); - $this->network = new Network($this); + $this->network = new Network(); $this->network->setName($this->getMotd()); From 797aabdf1502a0812a179380d5ae36dee5a22d91 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 14 Jan 2019 19:57:46 +0000 Subject: [PATCH 0390/3224] Entity: Protect move() to avoid stupidity --- src/pocketmine/entity/Entity.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 56846fc478..f8b67ce8cc 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -1345,7 +1345,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ return $block->isSolid() and !$block->isTransparent() and $block->collidesWithBB($this->getBoundingBox()); } - public function move(float $dx, float $dy, float $dz) : void{ + protected function move(float $dx, float $dy, float $dz) : void{ $this->blocksAround = null; Timings::$entityMoveTimer->startTiming(); From 242c7e3777201656a2866d04b39fea4fe91e239c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 14 Jan 2019 23:14:22 +0000 Subject: [PATCH 0391/3224] Grass: remove premature optimization this is reading full-block from the chunk every access, which is slower than accessing the level block-cache. --- src/pocketmine/block/Grass.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index 20b96ea3df..607d851b03 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -66,7 +66,7 @@ class Grass extends Solid{ public function onRandomTick() : void{ $lightAbove = $this->level->getFullLightAt($this->x, $this->y + 1, $this->z); - if($lightAbove < 4 and BlockFactory::$lightFilter[$this->level->getFullBlock($this->x, $this->y + 1, $this->z)] >= 3){ //2 plus 1 standard filter amount + if($lightAbove < 4 and $this->level->getBlockAt($this->x, $this->y + 1, $this->z)->getLightFilter() >= 2){ //grass dies $ev = new BlockSpreadEvent($this, $this, BlockFactory::get(Block::DIRT)); $ev->call(); @@ -85,7 +85,7 @@ class Grass extends Solid{ $b->getId() !== Block::DIRT or $b->getDamage() === 1 or //coarse dirt $this->level->getFullLightAt($x, $y + 1, $z) < 4 or - BlockFactory::$lightFilter[$this->level->getFullBlock($x, $y + 1, $z)] >= 3 + $this->level->getBlockAt($x, $y + 1, $z)->getLightFilter() >= 2 ){ continue; } From f647b1b7a5c6b18ddecd0222555ac864579f0522 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 15 Jan 2019 21:32:41 +0000 Subject: [PATCH 0392/3224] Some cleanup to internal sounds handling --- src/pocketmine/level/sound/AnvilBreakSound.php | 7 ++++--- src/pocketmine/level/sound/AnvilFallSound.php | 7 ++++--- src/pocketmine/level/sound/AnvilUseSound.php | 7 ++++--- src/pocketmine/level/sound/BlazeShootSound.php | 7 ++++--- src/pocketmine/level/sound/ClickSound.php | 7 ++++--- src/pocketmine/level/sound/DoorBumpSound.php | 7 ++++--- src/pocketmine/level/sound/DoorCrashSound.php | 7 ++++--- src/pocketmine/level/sound/DoorSound.php | 7 ++++--- .../level/sound/EndermanTeleportSound.php | 10 +++++++--- src/pocketmine/level/sound/FizzSound.php | 7 ++++--- src/pocketmine/level/sound/GhastShootSound.php | 7 ++++--- src/pocketmine/level/sound/GhastSound.php | 7 ++++--- src/pocketmine/level/sound/LaunchSound.php | 7 ++++--- .../{GenericSound.php => LevelEventSound.php} | 14 ++++++++------ src/pocketmine/level/sound/PopSound.php | 7 ++++--- 15 files changed, 67 insertions(+), 48 deletions(-) rename src/pocketmine/level/sound/{GenericSound.php => LevelEventSound.php} (85%) diff --git a/src/pocketmine/level/sound/AnvilBreakSound.php b/src/pocketmine/level/sound/AnvilBreakSound.php index fe8560e752..a7dc6a2a7f 100644 --- a/src/pocketmine/level/sound/AnvilBreakSound.php +++ b/src/pocketmine/level/sound/AnvilBreakSound.php @@ -25,8 +25,9 @@ namespace pocketmine\level\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class AnvilBreakSound extends GenericSound{ - public function __construct(float $pitch = 0){ - parent::__construct(LevelEventPacket::EVENT_SOUND_ANVIL_BREAK, $pitch); +class AnvilBreakSound extends LevelEventSound{ + + protected function getLevelEventId() : int{ + return LevelEventPacket::EVENT_SOUND_ANVIL_BREAK; } } diff --git a/src/pocketmine/level/sound/AnvilFallSound.php b/src/pocketmine/level/sound/AnvilFallSound.php index 910603afcf..82fa3c4801 100644 --- a/src/pocketmine/level/sound/AnvilFallSound.php +++ b/src/pocketmine/level/sound/AnvilFallSound.php @@ -25,8 +25,9 @@ namespace pocketmine\level\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class AnvilFallSound extends GenericSound{ - public function __construct(float $pitch = 0){ - parent::__construct(LevelEventPacket::EVENT_SOUND_ANVIL_FALL, $pitch); +class AnvilFallSound extends LevelEventSound{ + + protected function getLevelEventId() : int{ + return LevelEventPacket::EVENT_SOUND_ANVIL_FALL; } } diff --git a/src/pocketmine/level/sound/AnvilUseSound.php b/src/pocketmine/level/sound/AnvilUseSound.php index b9902edcc2..d3862c2d8e 100644 --- a/src/pocketmine/level/sound/AnvilUseSound.php +++ b/src/pocketmine/level/sound/AnvilUseSound.php @@ -25,8 +25,9 @@ namespace pocketmine\level\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class AnvilUseSound extends GenericSound{ - public function __construct(float $pitch = 0){ - parent::__construct(LevelEventPacket::EVENT_SOUND_ANVIL_USE, $pitch); +class AnvilUseSound extends LevelEventSound{ + + protected function getLevelEventId() : int{ + return LevelEventPacket::EVENT_SOUND_ANVIL_USE; } } diff --git a/src/pocketmine/level/sound/BlazeShootSound.php b/src/pocketmine/level/sound/BlazeShootSound.php index 7050bb82a9..c9d32f4bdc 100644 --- a/src/pocketmine/level/sound/BlazeShootSound.php +++ b/src/pocketmine/level/sound/BlazeShootSound.php @@ -25,8 +25,9 @@ namespace pocketmine\level\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class BlazeShootSound extends GenericSound{ - public function __construct(float $pitch = 0){ - parent::__construct(LevelEventPacket::EVENT_SOUND_BLAZE_SHOOT, $pitch); +class BlazeShootSound extends LevelEventSound{ + + protected function getLevelEventId() : int{ + return LevelEventPacket::EVENT_SOUND_BLAZE_SHOOT; } } diff --git a/src/pocketmine/level/sound/ClickSound.php b/src/pocketmine/level/sound/ClickSound.php index 24d920b0d0..79509bd8e3 100644 --- a/src/pocketmine/level/sound/ClickSound.php +++ b/src/pocketmine/level/sound/ClickSound.php @@ -25,8 +25,9 @@ namespace pocketmine\level\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class ClickSound extends GenericSound{ - public function __construct(float $pitch = 0){ - parent::__construct(LevelEventPacket::EVENT_SOUND_CLICK, $pitch); +class ClickSound extends LevelEventSound{ + + protected function getLevelEventId() : int{ + return LevelEventPacket::EVENT_SOUND_CLICK; } } diff --git a/src/pocketmine/level/sound/DoorBumpSound.php b/src/pocketmine/level/sound/DoorBumpSound.php index 84f4a18c56..88dac8efae 100644 --- a/src/pocketmine/level/sound/DoorBumpSound.php +++ b/src/pocketmine/level/sound/DoorBumpSound.php @@ -25,8 +25,9 @@ namespace pocketmine\level\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class DoorBumpSound extends GenericSound{ - public function __construct(float $pitch = 0){ - parent::__construct(LevelEventPacket::EVENT_SOUND_DOOR_BUMP, $pitch); +class DoorBumpSound extends LevelEventSound{ + + protected function getLevelEventId() : int{ + return LevelEventPacket::EVENT_SOUND_DOOR_BUMP; } } diff --git a/src/pocketmine/level/sound/DoorCrashSound.php b/src/pocketmine/level/sound/DoorCrashSound.php index bd8ab139ee..6946593ede 100644 --- a/src/pocketmine/level/sound/DoorCrashSound.php +++ b/src/pocketmine/level/sound/DoorCrashSound.php @@ -25,8 +25,9 @@ namespace pocketmine\level\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class DoorCrashSound extends GenericSound{ - public function __construct(float $pitch = 0){ - parent::__construct(LevelEventPacket::EVENT_SOUND_DOOR_CRASH, $pitch); +class DoorCrashSound extends LevelEventSound{ + + protected function getLevelEventId() : int{ + return LevelEventPacket::EVENT_SOUND_DOOR_CRASH; } } diff --git a/src/pocketmine/level/sound/DoorSound.php b/src/pocketmine/level/sound/DoorSound.php index 623b682d79..ee5a526747 100644 --- a/src/pocketmine/level/sound/DoorSound.php +++ b/src/pocketmine/level/sound/DoorSound.php @@ -25,8 +25,9 @@ namespace pocketmine\level\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class DoorSound extends GenericSound{ - public function __construct(float $pitch = 0){ - parent::__construct(LevelEventPacket::EVENT_SOUND_DOOR, $pitch); +class DoorSound extends LevelEventSound{ + + protected function getLevelEventId() : int{ + return LevelEventPacket::EVENT_SOUND_DOOR; } } diff --git a/src/pocketmine/level/sound/EndermanTeleportSound.php b/src/pocketmine/level/sound/EndermanTeleportSound.php index 4f3230f331..ab8801657f 100644 --- a/src/pocketmine/level/sound/EndermanTeleportSound.php +++ b/src/pocketmine/level/sound/EndermanTeleportSound.php @@ -25,8 +25,12 @@ namespace pocketmine\level\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class EndermanTeleportSound extends GenericSound{ - public function __construct(){ - parent::__construct(LevelEventPacket::EVENT_SOUND_ENDERMAN_TELEPORT); +class EndermanTeleportSound extends LevelEventSound{ + public function __construct(){ //don't allow specifying a pitch - TODO: remove pitch from sounds that don't have it + parent::__construct(); + } + + protected function getLevelEventId() : int{ + return LevelEventPacket::EVENT_SOUND_ENDERMAN_TELEPORT; } } diff --git a/src/pocketmine/level/sound/FizzSound.php b/src/pocketmine/level/sound/FizzSound.php index 325cdac707..09fb4b9af4 100644 --- a/src/pocketmine/level/sound/FizzSound.php +++ b/src/pocketmine/level/sound/FizzSound.php @@ -25,8 +25,9 @@ namespace pocketmine\level\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class FizzSound extends GenericSound{ - public function __construct(float $pitch = 0){ - parent::__construct(LevelEventPacket::EVENT_SOUND_FIZZ, $pitch); +class FizzSound extends LevelEventSound{ + + protected function getLevelEventId() : int{ + return LevelEventPacket::EVENT_SOUND_FIZZ; } } diff --git a/src/pocketmine/level/sound/GhastShootSound.php b/src/pocketmine/level/sound/GhastShootSound.php index 3e4320942b..0d2b3fe64f 100644 --- a/src/pocketmine/level/sound/GhastShootSound.php +++ b/src/pocketmine/level/sound/GhastShootSound.php @@ -25,8 +25,9 @@ namespace pocketmine\level\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class GhastShootSound extends GenericSound{ - public function __construct(float $pitch = 0){ - parent::__construct(LevelEventPacket::EVENT_SOUND_GHAST_SHOOT, $pitch); +class GhastShootSound extends LevelEventSound{ + + protected function getLevelEventId() : int{ + return LevelEventPacket::EVENT_SOUND_GHAST_SHOOT; } } diff --git a/src/pocketmine/level/sound/GhastSound.php b/src/pocketmine/level/sound/GhastSound.php index 568f221586..13cd6509fd 100644 --- a/src/pocketmine/level/sound/GhastSound.php +++ b/src/pocketmine/level/sound/GhastSound.php @@ -25,8 +25,9 @@ namespace pocketmine\level\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class GhastSound extends GenericSound{ - public function __construct(float $pitch = 0){ - parent::__construct(LevelEventPacket::EVENT_SOUND_GHAST, $pitch); +class GhastSound extends LevelEventSound{ + + protected function getLevelEventId() : int{ + return LevelEventPacket::EVENT_SOUND_GHAST; } } diff --git a/src/pocketmine/level/sound/LaunchSound.php b/src/pocketmine/level/sound/LaunchSound.php index e7f28072f2..243c5fc2e1 100644 --- a/src/pocketmine/level/sound/LaunchSound.php +++ b/src/pocketmine/level/sound/LaunchSound.php @@ -25,8 +25,9 @@ namespace pocketmine\level\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class LaunchSound extends GenericSound{ - public function __construct(float $pitch = 0){ - parent::__construct(LevelEventPacket::EVENT_SOUND_SHOOT, $pitch); +class LaunchSound extends LevelEventSound{ + + protected function getLevelEventId() : int{ + return LevelEventPacket::EVENT_SOUND_SHOOT; } } diff --git a/src/pocketmine/level/sound/GenericSound.php b/src/pocketmine/level/sound/LevelEventSound.php similarity index 85% rename from src/pocketmine/level/sound/GenericSound.php rename to src/pocketmine/level/sound/LevelEventSound.php index be8262636a..615c238ef0 100644 --- a/src/pocketmine/level/sound/GenericSound.php +++ b/src/pocketmine/level/sound/LevelEventSound.php @@ -26,18 +26,20 @@ namespace pocketmine\level\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class GenericSound extends Sound{ +/** + * @internal + */ +abstract class LevelEventSound extends Sound{ - /** @var int */ - protected $id; /** @var float */ protected $pitch = 0; - public function __construct(int $id, float $pitch = 0){ - $this->id = $id; + public function __construct(float $pitch = 0){ $this->pitch = $pitch * 1000; } + abstract protected function getLevelEventId() : int; + public function getPitch() : float{ return $this->pitch / 1000; } @@ -48,7 +50,7 @@ class GenericSound extends Sound{ public function encode(Vector3 $pos){ $pk = new LevelEventPacket; - $pk->evid = $this->id; + $pk->evid = $this->getLevelEventId(); $pk->position = $pos; $pk->data = (int) $this->pitch; diff --git a/src/pocketmine/level/sound/PopSound.php b/src/pocketmine/level/sound/PopSound.php index bfc56ee3eb..126ca9366f 100644 --- a/src/pocketmine/level/sound/PopSound.php +++ b/src/pocketmine/level/sound/PopSound.php @@ -25,8 +25,9 @@ namespace pocketmine\level\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class PopSound extends GenericSound{ - public function __construct(float $pitch = 0){ - parent::__construct(LevelEventPacket::EVENT_SOUND_POP, $pitch); +class PopSound extends LevelEventSound{ + + protected function getLevelEventId() : int{ + return LevelEventPacket::EVENT_SOUND_POP; } } From acdd0fec5f69a41fd8a99ffadd450983cfeb384f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 16 Jan 2019 16:19:39 +0000 Subject: [PATCH 0393/3224] NetworkSession: player may be null --- src/pocketmine/network/mcpe/NetworkSession.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 09146dd219..eda42eee17 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -50,7 +50,7 @@ use function time; class NetworkSession{ /** @var Server */ private $server; - /** @var Player */ + /** @var Player|null */ private $player; /** @var NetworkInterface */ private $interface; From 728bc95d73b7ce9bc15014d1cdaf8a0a9a1783d8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 16 Jan 2019 16:50:13 +0000 Subject: [PATCH 0394/3224] NetworkSession: remove premature GC optimization The only cyclic references here are both destroyed during normal collection directly (net interface removes from sessions array, player destroys its session reference), so there's no need to destroy them again here. This just causes a giant swathe of potential crashes for no real benefit. close #2669 --- src/pocketmine/network/mcpe/NetworkSession.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index eda42eee17..c87e7cb30a 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -342,7 +342,6 @@ class NetworkSession{ } $this->interface->close($this, $notify ? $reason : ""); - $this->disconnectCleanup(); } /** @@ -355,18 +354,9 @@ class NetworkSession{ if($this->connected){ $this->connected = false; $this->player->close($this->player->getLeaveMessage(), $reason); - $this->disconnectCleanup(); } } - private function disconnectCleanup() : void{ - $this->handler = null; - $this->interface = null; - $this->player = null; - $this->sendBuffer = null; - $this->compressedQueue = null; - } - public function enableEncryption(string $encryptionKey, string $handshakeJwt) : void{ $pk = new ServerToClientHandshakePacket(); $pk->jwt = $handshakeJwt; From 8bc33a849a20014b32bea417f2c2bc9e0d4a23ca Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 16 Jan 2019 15:44:14 +0000 Subject: [PATCH 0395/3224] Remove built-in pcntl support This is a bolt-on feature that can't be disabled and causes serious grief for Unix server users, because it prevents ctrl+c aborting the server the normal way. Instead, we prefer introducing a plugin to implement this functionality, so that users can opt-in or opt-out. --- src/pocketmine/Server.php | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 116f210597..14ff8661d5 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -121,7 +121,6 @@ use function file_exists; use function file_get_contents; use function file_put_contents; use function filemtime; -use function function_exists; use function gc_collect_cycles; use function get_class; use function getmypid; @@ -137,8 +136,6 @@ use function max; use function microtime; use function min; use function mkdir; -use function pcntl_signal; -use function pcntl_signal_dispatch; use function preg_replace; use function random_bytes; use function realpath; @@ -162,9 +159,6 @@ use const DIRECTORY_SEPARATOR; use const PHP_EOL; use const PHP_INT_MAX; use const PTHREADS_INHERIT_NONE; -use const SIGHUP; -use const SIGINT; -use const SIGTERM; /** * The class that manages everything @@ -232,9 +226,6 @@ class Server{ /** @var int */ private $sendUsageTicker = 0; - /** @var bool */ - private $dispatchSignals = false; - /** @var \AttachableThreadedLogger */ private $logger; @@ -1850,13 +1841,6 @@ class Server{ $this->tickCounter = 0; - if(function_exists("pcntl_signal")){ - pcntl_signal(SIGTERM, [$this, "handleSignal"]); - pcntl_signal(SIGINT, [$this, "handleSignal"]); - pcntl_signal(SIGHUP, [$this, "handleSignal"]); - $this->dispatchSignals = true; - } - $this->logger->info($this->getLanguage()->translateString("pocketmine.server.defaultGameMode", [GameMode::toTranslation($this->getGamemode())])); $this->logger->info($this->getLanguage()->translateString("pocketmine.server.startFinished", [round(microtime(true) - \pocketmine\START_TIME, 3)])); @@ -1865,12 +1849,6 @@ class Server{ $this->forceShutdown(); } - public function handleSignal($signo){ - if($signo === SIGTERM or $signo === SIGINT or $signo === SIGHUP){ - $this->shutdown(); - } - } - /** * @param \Throwable $e * @param array|null $trace @@ -2222,10 +2200,6 @@ class Server{ } } - if($this->dispatchSignals and $this->tickCounter % 5 === 0){ - pcntl_signal_dispatch(); - } - $this->getMemoryManager()->check(); Timings::$serverTickTimer->stopTiming(); From ddc2bed63f5f86fdb1608659fe37e888d7d2207c Mon Sep 17 00:00:00 2001 From: Dylan T Date: Wed, 16 Jan 2019 19:21:37 +0000 Subject: [PATCH 0396/3224] Add an API change request template --- .github/ISSUE_TEMPLATE/api-change-request.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/api-change-request.md diff --git a/.github/ISSUE_TEMPLATE/api-change-request.md b/.github/ISSUE_TEMPLATE/api-change-request.md new file mode 100644 index 0000000000..615ab12ef3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/api-change-request.md @@ -0,0 +1,19 @@ +--- +name: API change request +about: Suggest a change, addition or removal to the plugin API +title: '' +labels: '' +assignees: '' + +--- + + +## Description + + + +## Justification + + + +## Alternative methods From 23269da1a638f31b78fcb422dd5b0725efe5946c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 16 Jan 2019 19:52:41 +0000 Subject: [PATCH 0397/3224] Fixed the disaster of packet receive error handling --- composer.lock | 12 +++---- .../network/mcpe/NetworkBinaryStream.php | 17 ++++++--- src/pocketmine/network/mcpe/NetworkCipher.php | 4 +-- .../network/mcpe/NetworkCompression.php | 6 ++++ .../network/mcpe/NetworkSession.php | 36 +++++++++++++++---- .../network/mcpe/RakLibInterface.php | 24 ++++++++----- .../mcpe/handler/SimpleSessionHandler.php | 4 ++- .../network/mcpe/protocol/AddEntityPacket.php | 5 +-- .../mcpe/protocol/AvailableCommandsPacket.php | 9 ++--- .../network/mcpe/protocol/BookEditPacket.php | 3 +- .../protocol/ClientboundMapItemDataPacket.php | 5 +-- .../mcpe/protocol/CraftingDataPacket.php | 3 +- .../network/mcpe/protocol/DataPacket.php | 21 +++++++---- .../protocol/InventoryTransactionPacket.php | 3 +- .../network/mcpe/protocol/LoginPacket.php | 11 +++--- .../network/mcpe/protocol/PacketPool.php | 9 ++++- .../network/mcpe/protocol/SetScorePacket.php | 3 +- .../types/MismatchTransactionData.php | 3 +- .../protocol/types/NetworkInventoryAction.php | 3 +- 19 files changed, 126 insertions(+), 55 deletions(-) diff --git a/composer.lock b/composer.lock index 9631541815..070afe9dfa 100644 --- a/composer.lock +++ b/composer.lock @@ -295,16 +295,16 @@ }, { "name": "pocketmine/binaryutils", - "version": "0.1.7", + "version": "0.1.8", "source": { "type": "git", "url": "https://github.com/pmmp/BinaryUtils.git", - "reference": "3403751da9d39853b43426085cd242173baadd2b" + "reference": "33f511715d22418c03368b49b45a6c25d6b33806" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/3403751da9d39853b43426085cd242173baadd2b", - "reference": "3403751da9d39853b43426085cd242173baadd2b", + "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/33f511715d22418c03368b49b45a6c25d6b33806", + "reference": "33f511715d22418c03368b49b45a6c25d6b33806", "shasum": "" }, "require": { @@ -322,10 +322,10 @@ ], "description": "Classes and methods for conveniently handling binary data", "support": { - "source": "https://github.com/pmmp/BinaryUtils/tree/0.1.7", + "source": "https://github.com/pmmp/BinaryUtils/tree/0.1.8", "issues": "https://github.com/pmmp/BinaryUtils/issues" }, - "time": "2019-01-07T15:59:50+00:00" + "time": "2019-01-16T17:31:44+00:00" }, { "name": "pocketmine/math", diff --git a/src/pocketmine/network/mcpe/NetworkBinaryStream.php b/src/pocketmine/network/mcpe/NetworkBinaryStream.php index 5b4a8523b4..cf7e85ee76 100644 --- a/src/pocketmine/network/mcpe/NetworkBinaryStream.php +++ b/src/pocketmine/network/mcpe/NetworkBinaryStream.php @@ -33,6 +33,7 @@ use pocketmine\math\Vector3; use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\network\mcpe\protocol\types\CommandOriginData; use pocketmine\network\mcpe\protocol\types\EntityLink; +use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; use pocketmine\utils\UUID; use function count; @@ -100,7 +101,11 @@ class NetworkBinaryStream extends BinaryStream{ $this->getString(); } - return ItemFactory::get($id, $data, $cnt, $compound); + try{ + return ItemFactory::get($id, $data, $cnt, $compound); + }catch(\InvalidArgumentException $e){ + throw new BinaryDataException($e->getMessage(), 0, $e); + } } @@ -179,7 +184,7 @@ class NetworkBinaryStream extends BinaryStream{ $value = $this->getVector3(); break; default: - throw new \UnexpectedValueException("Invalid data type " . $type); + throw new BinaryDataException("Invalid data type " . $type); } if($types){ $data[$key] = [$type, $value]; @@ -235,7 +240,7 @@ class NetworkBinaryStream extends BinaryStream{ $this->putVector3Nullable($d[1]); break; default: - throw new \UnexpectedValueException("Invalid data type " . $d[0]); + throw new \InvalidArgumentException("Invalid data type " . $d[0]); } } } @@ -266,7 +271,7 @@ class NetworkBinaryStream extends BinaryStream{ $list[] = $attr; }else{ - throw new \UnexpectedValueException("Unknown attribute type \"$id\""); + throw new BinaryDataException("Unknown attribute type \"$id\""); } } @@ -450,6 +455,8 @@ class NetworkBinaryStream extends BinaryStream{ case 3: $value = $this->getLFloat(); break; + default: + throw new BinaryDataException("Unknown gamerule type $type"); } $rules[$name] = [$type, $value]; @@ -479,6 +486,8 @@ class NetworkBinaryStream extends BinaryStream{ case 3: $this->putLFloat($rule[1]); break; + default: + throw new \InvalidArgumentException("Invalid gamerule type " . $rule[0]); } } } diff --git a/src/pocketmine/network/mcpe/NetworkCipher.php b/src/pocketmine/network/mcpe/NetworkCipher.php index da01062607..79bdfaba4e 100644 --- a/src/pocketmine/network/mcpe/NetworkCipher.php +++ b/src/pocketmine/network/mcpe/NetworkCipher.php @@ -65,13 +65,13 @@ class NetworkCipher{ public function decrypt(string $encrypted) : string{ if(strlen($encrypted) < 9){ - throw new \InvalidArgumentException("Payload is too short"); + throw new \UnexpectedValueException("Payload is too short"); } $decrypted = $this->decryptCipher->decryptUpdate($encrypted); $payload = substr($decrypted, 0, -8); if(($expected = $this->calculateChecksum($this->decryptCounter++, $payload)) !== ($actual = substr($decrypted, -8))){ - throw new \InvalidArgumentException("Encrypted payload has invalid checksum (expected " . bin2hex($expected) . ", got " . bin2hex($actual) . ")"); + throw new \UnexpectedValueException("Encrypted payload has invalid checksum (expected " . bin2hex($expected) . ", got " . bin2hex($actual) . ")"); } return $payload; diff --git a/src/pocketmine/network/mcpe/NetworkCompression.php b/src/pocketmine/network/mcpe/NetworkCompression.php index b007254e38..3f27ea18a3 100644 --- a/src/pocketmine/network/mcpe/NetworkCompression.php +++ b/src/pocketmine/network/mcpe/NetworkCompression.php @@ -35,6 +35,12 @@ final class NetworkCompression{ } + /** + * @param string $payload + * + * @return string + * @throws \ErrorException + */ public static function decompress(string $payload) : string{ return zlib_decode($payload, 1024 * 1024 * 64); //Max 64MB } diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index c87e7cb30a..c6f7a02949 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe; use pocketmine\event\player\PlayerCreationEvent; use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\event\server\DataPacketSendEvent; +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\DeathSessionHandler; use pocketmine\network\mcpe\handler\HandshakeSessionHandler; use pocketmine\network\mcpe\handler\LoginSessionHandler; @@ -42,6 +43,7 @@ use pocketmine\network\NetworkInterface; use pocketmine\Player; use pocketmine\Server; use pocketmine\timings\Timings; +use pocketmine\utils\BinaryDataException; use function bin2hex; use function strlen; use function substr; @@ -162,6 +164,11 @@ class NetworkSession{ $this->handler->setUp(); } + /** + * @param string $payload + * + * @throws BadPacketException + */ public function handleEncoded(string $payload) : void{ if(!$this->connected){ return; @@ -171,10 +178,9 @@ class NetworkSession{ Timings::$playerNetworkReceiveDecryptTimer->startTiming(); try{ $payload = $this->cipher->decrypt($payload); - }catch(\InvalidArgumentException $e){ + }catch(\UnexpectedValueException $e){ $this->server->getLogger()->debug("Encrypted packet from " . $this->ip . " " . $this->port . ": " . bin2hex($payload)); - $this->disconnect("Packet decryption error: " . $e->getMessage()); - return; + throw new BadPacketException("Packet decryption error: " . $e->getMessage(), 0, $e); }finally{ Timings::$playerNetworkReceiveDecryptTimer->stopTiming(); } @@ -185,22 +191,38 @@ class NetworkSession{ $stream = new PacketStream(NetworkCompression::decompress($payload)); }catch(\ErrorException $e){ $this->server->getLogger()->debug("Failed to decompress packet from " . $this->ip . " " . $this->port . ": " . bin2hex($payload)); - $this->disconnect("Compressed packet batch decode error (incompatible game version?)", false); - return; + //TODO: this isn't incompatible game version if we already established protocol version + throw new BadPacketException("Compressed packet batch decode error (incompatible game version?)", 0, $e); }finally{ Timings::$playerNetworkReceiveDecompressTimer->stopTiming(); } while(!$stream->feof() and $this->connected){ - $this->handleDataPacket(PacketPool::getPacket($stream->getString())); + try{ + $buf = $stream->getString(); + }catch(BinaryDataException $e){ + $this->server->getLogger()->debug("Packet batch from " . $this->ip . " " . $this->port . ": " . bin2hex($stream->getBuffer())); + throw new BadPacketException("Packet batch decode error: " . $e->getMessage(), 0, $e); + } + $this->handleDataPacket(PacketPool::getPacket($buf)); } } + /** + * @param DataPacket $packet + * + * @throws BadPacketException + */ public function handleDataPacket(DataPacket $packet) : void{ $timings = Timings::getReceiveDataPacketTimings($packet); $timings->startTiming(); - $packet->decode(); + try{ + $packet->decode(); + }catch(BadPacketException $e){ + $this->server->getLogger()->debug($packet->getName() . " from " . $this->ip . " " . $this->port . ": " . bin2hex($packet->getBuffer())); + throw $e; + } if(!$packet->feof() and !$packet->mayHaveUnreadBytes()){ $remains = substr($packet->getBuffer(), $packet->getOffset()); $this->server->getLogger()->debug("Still " . strlen($remains) . " bytes unread in " . $packet->getName() . ": 0x" . bin2hex($remains)); diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index cfa0833038..1bd89f341f 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -25,10 +25,12 @@ namespace pocketmine\network\mcpe; use pocketmine\GameMode; use pocketmine\network\AdvancedNetworkInterface; +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\Network; use pocketmine\Server; use pocketmine\snooze\SleeperNotifier; +use pocketmine\utils\Utils; use raklib\protocol\EncapsulatedPacket; use raklib\protocol\PacketReliability; use raklib\RakLib; @@ -37,7 +39,6 @@ use raklib\server\ServerHandler; use raklib\server\ServerInstance; use raklib\utils\InternetAddress; use function addcslashes; -use function bin2hex; use function implode; use function rtrim; use function spl_object_hash; @@ -142,19 +143,26 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ public function handleEncapsulated(string $identifier, EncapsulatedPacket $packet, int $flags) : void{ if(isset($this->sessions[$identifier])){ + if($packet->buffer === "" or $packet->buffer{0} !== self::MCPE_RAKNET_PACKET_ID){ + return; + } //get this now for blocking in case the player was closed before the exception was raised $session = $this->sessions[$identifier]; $address = $session->getIp(); + $port = $session->getPort(); + $buf = substr($packet->buffer, 1); try{ - if($packet->buffer !== "" and $packet->buffer{0} === self::MCPE_RAKNET_PACKET_ID){ //Batch - $session->handleEncoded(substr($packet->buffer, 1)); - } - }catch(\Throwable $e){ + $session->handleEncoded($buf); + }catch(BadPacketException $e){ $logger = $this->server->getLogger(); - $logger->debug("EncapsulatedPacket 0x" . bin2hex($packet->buffer)); - $logger->logException($e); + $logger->error("Bad packet from $address $port: " . $e->getMessage()); - $session->disconnect("Internal server error"); + //intentionally doesn't use logException, we don't want spammy packet error traces to appear in release mode + $logger->debug("Origin: " . Utils::cleanPath($e->getFile()) . "(" . $e->getLine() . ")"); + foreach(Utils::printableTrace($e->getTrace()) as $frame){ + $logger->debug($frame); + } + $session->disconnect("Packet processing error"); $this->interface->blockAddress($address, 5); } } diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index fe2b5d3c0e..925eb334a2 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -28,6 +28,7 @@ use pocketmine\inventory\transaction\CraftingTransaction; use pocketmine\inventory\transaction\InventoryTransaction; use pocketmine\inventory\transaction\TransactionValidationException; use pocketmine\math\Vector3; +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; @@ -454,6 +455,7 @@ class SimpleSessionHandler extends SessionHandler{ * @param bool $assoc * * @return mixed + * @throws BadPacketException */ private static function stupid_json_decode(string $json, bool $assoc = false){ if(preg_match('/^\[(.+)\]$/s', $json, $matches) > 0){ @@ -468,7 +470,7 @@ class SimpleSessionHandler extends SessionHandler{ $fixed = "[" . implode(",", $parts) . "]"; if(($ret = json_decode($fixed, $assoc)) === null){ - throw new \InvalidArgumentException("Failed to fix JSON: " . json_last_error_msg() . "(original: $json, modified: $fixed)"); + throw new BadPacketException("Failed to fix JSON: " . json_last_error_msg() . "(original: $json, modified: $fixed)"); } return $ret; diff --git a/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php b/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php index e1f1db6907..6bd81c3331 100644 --- a/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php @@ -28,6 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\entity\Attribute; use pocketmine\entity\EntityIds; use pocketmine\math\Vector3; +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\EntityLink; use function array_search; @@ -173,7 +174,7 @@ class AddEntityPacket extends DataPacket{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->type = array_search($t = $this->getString(), self::LEGACY_ID_MAP_BC, true); if($this->type === false){ - throw new \UnexpectedValueException("Can't map ID $t to legacy ID"); + throw new BadPacketException("Can't map ID $t to legacy ID"); } $this->position = $this->getVector3(); $this->motion = $this->getVector3(); @@ -195,7 +196,7 @@ class AddEntityPacket extends DataPacket{ $attr->setValue($current); $this->attributes[] = $attr; }else{ - throw new \UnexpectedValueException("Unknown attribute type \"$id\""); + throw new BadPacketException("Unknown attribute type \"$id\""); } } diff --git a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php index 037a9374b0..e0c5c4873e 100644 --- a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\CommandData; use pocketmine\network\mcpe\protocol\types\CommandEnum; @@ -146,7 +147,7 @@ class AvailableCommandsPacket extends DataPacket{ for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ $index = $this->getEnumValueIndex(); if(!isset($this->enumValues[$index])){ - throw new \UnexpectedValueException("Invalid enum value index $index"); + throw new BadPacketException("Invalid enum value index $index"); } //Get the enum value from the initial pile of mess $retval->enumValues[] = $this->enumValues[$index]; @@ -229,16 +230,16 @@ class AvailableCommandsPacket extends DataPacket{ $index = ($parameter->paramType & 0xffff); $parameter->enum = $this->enums[$index] ?? null; if($parameter->enum === null){ - throw new \UnexpectedValueException("expected enum at $index, but got none"); + throw new BadPacketException("expected enum at $index, but got none"); } }elseif($parameter->paramType & self::ARG_FLAG_POSTFIX){ $index = ($parameter->paramType & 0xffff); $parameter->postfix = $this->postfixes[$index] ?? null; if($parameter->postfix === null){ - throw new \UnexpectedValueException("expected postfix at $index, but got none"); + throw new BadPacketException("expected postfix at $index, but got none"); } }elseif(($parameter->paramType & self::ARG_FLAG_VALID) === 0){ - throw new \UnexpectedValueException("Invalid parameter type 0x" . dechex($parameter->paramType)); + throw new BadPacketException("Invalid parameter type 0x" . dechex($parameter->paramType)); } $retval->overloads[$overloadIndex][$paramIndex] = $parameter; diff --git a/src/pocketmine/network/mcpe/protocol/BookEditPacket.php b/src/pocketmine/network/mcpe/protocol/BookEditPacket.php index 759ff57bed..f1b0a0851b 100644 --- a/src/pocketmine/network/mcpe/protocol/BookEditPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BookEditPacket.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\SessionHandler; class BookEditPacket extends DataPacket{ @@ -81,7 +82,7 @@ class BookEditPacket extends DataPacket{ $this->xuid = $this->getString(); break; default: - throw new \UnexpectedValueException("Unknown book edit type $this->type!"); + throw new BadPacketException("Unknown book edit type $this->type!"); } } diff --git a/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php b/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php index 38ba21462e..c068b50ef4 100644 --- a/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\protocol\types\MapTrackedObject; @@ -93,7 +94,7 @@ class ClientboundMapItemDataPacket extends DataPacket{ }elseif($object->type === MapTrackedObject::TYPE_ENTITY){ $object->entityUniqueId = $this->getEntityUniqueId(); }else{ - throw new \UnexpectedValueException("Unknown map object type $object->type"); + throw new BadPacketException("Unknown map object type $object->type"); } $this->trackedEntities[] = $object; } @@ -117,7 +118,7 @@ class ClientboundMapItemDataPacket extends DataPacket{ $count = $this->getUnsignedVarInt(); if($count !== $this->width * $this->height){ - throw new \UnexpectedValueException("Expected colour count of " . ($this->height * $this->width) . " (height $this->height * width $this->width), got $count"); + throw new BadPacketException("Expected colour count of " . ($this->height * $this->width) . " (height $this->height * width $this->width), got $count"); } for($y = 0; $y < $this->height; ++$y){ diff --git a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php b/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php index 8062836b37..490db90d96 100644 --- a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php @@ -30,6 +30,7 @@ use pocketmine\inventory\FurnaceRecipe; use pocketmine\inventory\ShapedRecipe; use pocketmine\inventory\ShapelessRecipe; use pocketmine\item\Item; +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\NetworkBinaryStream; use function count; @@ -107,7 +108,7 @@ class CraftingDataPacket extends DataPacket{ $entry["uuid"] = $this->getUUID()->toString(); break; default: - throw new \UnexpectedValueException("Unhandled recipe type $recipeType!"); //do not continue attempting to decode + throw new BadPacketException("Unhandled recipe type $recipeType!"); //do not continue attempting to decode } $this->decodedEntries[] = $entry; } diff --git a/src/pocketmine/network/mcpe/protocol/DataPacket.php b/src/pocketmine/network/mcpe/protocol/DataPacket.php index 9e05ab3b05..a93833ab98 100644 --- a/src/pocketmine/network/mcpe/protocol/DataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/DataPacket.php @@ -25,8 +25,10 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\NetworkBinaryStream; +use pocketmine\utils\BinaryDataException; use pocketmine\utils\Utils; use function bin2hex; use function get_class; @@ -67,22 +69,26 @@ abstract class DataPacket extends NetworkBinaryStream{ } /** - * @throws \OutOfBoundsException - * @throws \UnexpectedValueException + * @throws BadPacketException */ final public function decode() : void{ $this->rewind(); - $this->decodeHeader(); - $this->decodePayload(); + try{ + $this->decodeHeader(); + $this->decodePayload(); + }catch(BinaryDataException | BadPacketException $e){ + throw new BadPacketException($this->getName() . ": " . $e->getMessage(), 0, $e); + } } /** - * @throws \OutOfBoundsException + * @throws BinaryDataException * @throws \UnexpectedValueException */ protected function decodeHeader() : void{ $pid = $this->getUnsignedVarInt(); if($pid !== static::NETWORK_ID){ + //TODO: this means a logical error in the code, but how to prevent it from happening? throw new \UnexpectedValueException("Expected " . static::NETWORK_ID . " for packet ID, got $pid"); } } @@ -90,8 +96,8 @@ abstract class DataPacket extends NetworkBinaryStream{ /** * Decodes the packet body, without the packet ID or other generic header fields. * - * @throws \OutOfBoundsException - * @throws \UnexpectedValueException + * @throws BadPacketException + * @throws BinaryDataException */ abstract protected function decodePayload() : void; @@ -124,6 +130,7 @@ abstract class DataPacket extends NetworkBinaryStream{ * @param SessionHandler $handler * * @return bool true if the packet was handled successfully, false if not. + * @throws BadPacketException if broken data was found in the packet */ abstract public function handle(SessionHandler $handler) : bool; diff --git a/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php b/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php index 6cdb4c3a30..aad97a1d86 100644 --- a/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\MismatchTransactionData; use pocketmine\network\mcpe\protocol\types\NormalTransactionData; @@ -68,7 +69,7 @@ class InventoryTransactionPacket extends DataPacket{ $this->trData = new ReleaseItemTransactionData(); break; default: - throw new \UnexpectedValueException("Unknown transaction type $transactionType"); + throw new BadPacketException("Unknown transaction type $transactionType"); } $this->trData->decode($this); diff --git a/src/pocketmine/network/mcpe/protocol/LoginPacket.php b/src/pocketmine/network/mcpe/protocol/LoginPacket.php index 99d16930d2..f80b51618e 100644 --- a/src/pocketmine/network/mcpe/protocol/LoginPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LoginPacket.php @@ -28,6 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use Particle\Validator\Validator; use pocketmine\entity\Skin; +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\PlayerInfo; use pocketmine\utils\BinaryStream; @@ -110,7 +111,7 @@ class LoginPacket extends DataPacket{ foreach($result->getFailures() as $f){ $messages[] = $f->format(); } - throw new \UnexpectedValueException("Failed to validate '$name': " . implode(", ", $messages)); + throw new BadPacketException("Failed to validate '$name': " . implode(", ", $messages)); } } @@ -123,7 +124,7 @@ class LoginPacket extends DataPacket{ $chainData = json_decode($buffer->get($buffer->getLInt()), true); if(!is_array($chainData)){ - throw new \UnexpectedValueException("Failed to decode chainData JSON: " . json_last_error_msg()); + throw new BadPacketException("Failed to decode chainData JSON: " . json_last_error_msg()); } $vd = new Validator(); @@ -138,10 +139,10 @@ class LoginPacket extends DataPacket{ $claims = Utils::getJwtClaims($chain); if(isset($claims["extraData"])){ if(!is_array($claims["extraData"])){ - throw new \UnexpectedValueException("'extraData' key should be an array"); + throw new BadPacketException("'extraData' key should be an array"); } if($this->extraData !== null){ - throw new \UnexpectedValueException("Found 'extraData' more than once in chainData"); + throw new BadPacketException("Found 'extraData' more than once in chainData"); } $extraV = new Validator(); @@ -154,7 +155,7 @@ class LoginPacket extends DataPacket{ } } if($this->extraData === null){ - throw new \UnexpectedValueException("'extraData' not found in chain data"); + throw new BadPacketException("'extraData' not found in chain data"); } $this->clientDataJwt = $buffer->get($buffer->getLInt()); diff --git a/src/pocketmine/network/mcpe/protocol/PacketPool.php b/src/pocketmine/network/mcpe/protocol/PacketPool.php index cff34b94c6..9817db1b93 100644 --- a/src/pocketmine/network/mcpe/protocol/PacketPool.php +++ b/src/pocketmine/network/mcpe/protocol/PacketPool.php @@ -23,7 +23,9 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; +use pocketmine\network\BadPacketException; use pocketmine\utils\Binary; +use pocketmine\utils\BinaryDataException; class PacketPool{ /** @var \SplFixedArray */ @@ -175,10 +177,15 @@ class PacketPool{ * @param string $buffer * * @return DataPacket + * @throws BadPacketException */ public static function getPacket(string $buffer) : DataPacket{ $offset = 0; - $pk = static::getPacketById(Binary::readUnsignedVarInt($buffer, $offset)); + try{ + $pk = static::getPacketById(Binary::readUnsignedVarInt($buffer, $offset)); + }catch(BinaryDataException $e){ + throw new BadPacketException("Packet is too short"); + } $pk->setBuffer($buffer, $offset); return $pk; diff --git a/src/pocketmine/network/mcpe/protocol/SetScorePacket.php b/src/pocketmine/network/mcpe/protocol/SetScorePacket.php index 0e3365af6e..1e8daa3f66 100644 --- a/src/pocketmine/network/mcpe/protocol/SetScorePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetScorePacket.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\ScorePacketEntry; use function count; @@ -58,7 +59,7 @@ class SetScorePacket extends DataPacket{ $entry->customName = $this->getString(); break; default: - throw new \UnexpectedValueException("Unknown entry type $entry->type"); + throw new BadPacketException("Unknown entry type $entry->type"); } } } diff --git a/src/pocketmine/network/mcpe/protocol/types/MismatchTransactionData.php b/src/pocketmine/network/mcpe/protocol/types/MismatchTransactionData.php index 74571d02e6..52bac3b315 100644 --- a/src/pocketmine/network/mcpe/protocol/types/MismatchTransactionData.php +++ b/src/pocketmine/network/mcpe/protocol/types/MismatchTransactionData.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types; +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; use function count; @@ -35,7 +36,7 @@ class MismatchTransactionData extends TransactionData{ protected function decodeData(NetworkBinaryStream $stream) : void{ if(!empty($this->actions)){ - throw new \UnexpectedValueException("Mismatch transaction type should not have any actions associated with it, but got " . count($this->actions)); + throw new BadPacketException("Mismatch transaction type should not have any actions associated with it, but got " . count($this->actions)); } } diff --git a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php index 25f8c5b362..9e7b25aad9 100644 --- a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php +++ b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php @@ -28,6 +28,7 @@ use pocketmine\inventory\transaction\action\DropItemAction; use pocketmine\inventory\transaction\action\InventoryAction; use pocketmine\inventory\transaction\action\SlotChangeAction; use pocketmine\item\Item; +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\NetworkBinaryStream; use pocketmine\Player; @@ -115,7 +116,7 @@ class NetworkInventoryAction{ $this->windowId = $packet->getVarInt(); break; default: - throw new \UnexpectedValueException("Unknown inventory action source type $this->sourceType"); + throw new BadPacketException("Unknown inventory action source type $this->sourceType"); } $this->inventorySlot = $packet->getUnsignedVarInt(); From c9c6a5dc94bcaa95e9c690b1f73a36c72942b6e8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 16 Jan 2019 20:48:26 +0000 Subject: [PATCH 0398/3224] Fixed some doc comments --- src/pocketmine/network/mcpe/NetworkBinaryStream.php | 2 +- src/pocketmine/network/mcpe/protocol/LoginPacket.php | 4 ++-- .../network/mcpe/protocol/types/NetworkInventoryAction.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/network/mcpe/NetworkBinaryStream.php b/src/pocketmine/network/mcpe/NetworkBinaryStream.php index cf7e85ee76..918972e883 100644 --- a/src/pocketmine/network/mcpe/NetworkBinaryStream.php +++ b/src/pocketmine/network/mcpe/NetworkBinaryStream.php @@ -249,7 +249,7 @@ class NetworkBinaryStream extends BinaryStream{ * Reads a list of Attributes from the stream. * @return Attribute[] * - * @throws \UnexpectedValueException if reading an attribute with an unrecognized name + * @throws BinaryDataException if reading an attribute with an unrecognized name */ public function getAttributeList() : array{ $list = []; diff --git a/src/pocketmine/network/mcpe/protocol/LoginPacket.php b/src/pocketmine/network/mcpe/protocol/LoginPacket.php index f80b51618e..ea51cf32f8 100644 --- a/src/pocketmine/network/mcpe/protocol/LoginPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LoginPacket.php @@ -102,7 +102,7 @@ class LoginPacket extends DataPacket{ * @param string $name * @param $data * - * @throws \UnexpectedValueException + * @throws BadPacketException */ private static function validate(Validator $v, string $name, $data) : void{ $result = $v->validate($data); @@ -116,7 +116,7 @@ class LoginPacket extends DataPacket{ } /** - * @throws \OutOfBoundsException + * @throws BadPacketException * @throws \UnexpectedValueException */ protected function decodeConnectionRequest() : void{ diff --git a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php index 9e7b25aad9..56be858b25 100644 --- a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php +++ b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php @@ -97,7 +97,7 @@ class NetworkInventoryAction{ * * @return $this * @throws \UnexpectedValueException - * @throws \OutOfBoundsException + * @throws BadPacketException */ public function read(NetworkBinaryStream $packet) : NetworkInventoryAction{ $this->sourceType = $packet->getUnsignedVarInt(); From 44ef9fc5776804014104295eb3c852c9eab1a248 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 16 Jan 2019 21:00:28 +0000 Subject: [PATCH 0399/3224] LoginPacket: account for some missed error cases --- .../network/mcpe/protocol/LoginPacket.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/LoginPacket.php b/src/pocketmine/network/mcpe/protocol/LoginPacket.php index ea51cf32f8..abdb2a55a3 100644 --- a/src/pocketmine/network/mcpe/protocol/LoginPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LoginPacket.php @@ -31,6 +31,7 @@ use pocketmine\entity\Skin; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\PlayerInfo; +use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; use pocketmine\utils\Utils; use pocketmine\utils\UUID; @@ -117,7 +118,7 @@ class LoginPacket extends DataPacket{ /** * @throws BadPacketException - * @throws \UnexpectedValueException + * @throws BinaryDataException */ protected function decodeConnectionRequest() : void{ $buffer = new BinaryStream($this->getString()); @@ -136,7 +137,11 @@ class LoginPacket extends DataPacket{ $this->chainDataJwt = $chainData['chain']; foreach($this->chainDataJwt as $k => $chain){ //validate every chain element - $claims = Utils::getJwtClaims($chain); + try{ + $claims = Utils::getJwtClaims($chain); + }catch(\UnexpectedValueException $e){ + throw new BadPacketException($e->getMessage(), 0, $e); + } if(isset($claims["extraData"])){ if(!is_array($claims["extraData"])){ throw new BadPacketException("'extraData' key should be an array"); @@ -159,7 +164,11 @@ class LoginPacket extends DataPacket{ } $this->clientDataJwt = $buffer->get($buffer->getLInt()); - $clientData = Utils::getJwtClaims($this->clientDataJwt); + try{ + $clientData = Utils::getJwtClaims($this->clientDataJwt); + }catch(\UnexpectedValueException $e){ + throw new BadPacketException($e->getMessage(), 0, $e); + } $v = new Validator(); $v->required(self::I_CLIENT_RANDOM_ID)->integer(); From fc98f4c42b503b93c5edff91d7a26efd74ecfc62 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 16 Jan 2019 21:30:31 +0000 Subject: [PATCH 0400/3224] Address more error cases, some minor cleanup --- .../network/mcpe/NetworkBinaryStream.php | 58 +++++++++++++++++-- .../network/mcpe/protocol/AddEntityPacket.php | 10 +++- .../mcpe/protocol/AvailableCommandsPacket.php | 19 ++++++ .../mcpe/protocol/CommandOutputPacket.php | 5 ++ .../mcpe/protocol/MoveEntityDeltaPacket.php | 13 +++++ .../protocol/types/NetworkInventoryAction.php | 4 +- .../mcpe/protocol/types/TransactionData.php | 10 ++-- 7 files changed, 105 insertions(+), 14 deletions(-) diff --git a/src/pocketmine/network/mcpe/NetworkBinaryStream.php b/src/pocketmine/network/mcpe/NetworkBinaryStream.php index 918972e883..69f7cd9cec 100644 --- a/src/pocketmine/network/mcpe/NetworkBinaryStream.php +++ b/src/pocketmine/network/mcpe/NetworkBinaryStream.php @@ -31,6 +31,7 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\Vector3; use pocketmine\nbt\LittleEndianNbtSerializer; +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\types\CommandOriginData; use pocketmine\network\mcpe\protocol\types\EntityLink; use pocketmine\utils\BinaryDataException; @@ -43,6 +44,10 @@ class NetworkBinaryStream extends BinaryStream{ /** @var LittleEndianNbtSerializer */ private static $itemNbtSerializer = null; + /** + * @return string + * @throws BinaryDataException + */ public function getString() : string{ return $this->get($this->getUnsignedVarInt()); } @@ -52,6 +57,10 @@ class NetworkBinaryStream extends BinaryStream{ $this->put($v); } + /** + * @return UUID + * @throws BinaryDataException + */ public function getUUID() : UUID{ //This is actually two little-endian longs: UUID Most followed by UUID Least $part1 = $this->getLInt(); @@ -69,6 +78,12 @@ class NetworkBinaryStream extends BinaryStream{ $this->putLInt($uuid->getPart(2)); } + /** + * @return Item + * + * @throws BadPacketException + * @throws BinaryDataException + */ public function getSlot() : Item{ $id = $this->getVarInt(); if($id === 0){ @@ -88,7 +103,11 @@ class NetworkBinaryStream extends BinaryStream{ if(self::$itemNbtSerializer === null){ self::$itemNbtSerializer = new LittleEndianNbtSerializer(); } - $compound = self::$itemNbtSerializer->read($this->get($nbtLen)); + try{ + $compound = self::$itemNbtSerializer->read($this->get($nbtLen)); + }catch(\UnexpectedValueException $e){ + throw new BadPacketException($e->getMessage(), 0, $e); + } } //TODO @@ -104,7 +123,7 @@ class NetworkBinaryStream extends BinaryStream{ try{ return ItemFactory::get($id, $data, $cnt, $compound); }catch(\InvalidArgumentException $e){ - throw new BinaryDataException($e->getMessage(), 0, $e); + throw new BadPacketException($e->getMessage(), 0, $e); } } @@ -146,6 +165,9 @@ class NetworkBinaryStream extends BinaryStream{ * @param bool $types Whether to include metadata types along with values in the returned array * * @return array + * + * @throws BadPacketException + * @throws BinaryDataException */ public function getEntityMetadata(bool $types = true) : array{ $count = $this->getUnsignedVarInt(); @@ -184,7 +206,7 @@ class NetworkBinaryStream extends BinaryStream{ $value = $this->getVector3(); break; default: - throw new BinaryDataException("Invalid data type " . $type); + throw new BadPacketException("Unknown entity metadata type " . $type); } if($types){ $data[$key] = [$type, $value]; @@ -249,7 +271,8 @@ class NetworkBinaryStream extends BinaryStream{ * Reads a list of Attributes from the stream. * @return Attribute[] * - * @throws BinaryDataException if reading an attribute with an unrecognized name + * @throws BadPacketException if reading an attribute with an unrecognized name + * @throws BinaryDataException */ public function getAttributeList() : array{ $list = []; @@ -271,7 +294,7 @@ class NetworkBinaryStream extends BinaryStream{ $list[] = $attr; }else{ - throw new BinaryDataException("Unknown attribute type \"$id\""); + throw new BadPacketException("Unknown attribute type \"$id\""); } } @@ -297,6 +320,8 @@ class NetworkBinaryStream extends BinaryStream{ /** * Reads and returns an EntityUniqueID * @return int + * + * @throws BinaryDataException */ public function getEntityUniqueId() : int{ return $this->getVarLong(); @@ -314,6 +339,8 @@ class NetworkBinaryStream extends BinaryStream{ /** * Reads and returns an EntityRuntimeID * @return int + * + * @throws BinaryDataException */ public function getEntityRuntimeId() : int{ return $this->getUnsignedVarLong(); @@ -334,6 +361,8 @@ class NetworkBinaryStream extends BinaryStream{ * @param int &$x * @param int &$y * @param int &$z + * + * @throws BinaryDataException */ public function getBlockPosition(&$x, &$y, &$z) : void{ $x = $this->getVarInt(); @@ -360,6 +389,8 @@ class NetworkBinaryStream extends BinaryStream{ * @param int &$x * @param int &$y * @param int &$z + * + * @throws BinaryDataException */ public function getSignedBlockPosition(&$x, &$y, &$z) : void{ $x = $this->getVarInt(); @@ -384,6 +415,8 @@ class NetworkBinaryStream extends BinaryStream{ * Reads a floating-point Vector3 object with coordinates rounded to 4 decimal places. * * @return Vector3 + * + * @throws BinaryDataException */ public function getVector3() : Vector3{ return new Vector3( @@ -424,6 +457,10 @@ class NetworkBinaryStream extends BinaryStream{ $this->putLFloat($vector->z); } + /** + * @return float + * @throws BinaryDataException + */ public function getByteRotation() : float{ return (float) ($this->getByte() * (360 / 256)); } @@ -437,6 +474,9 @@ class NetworkBinaryStream extends BinaryStream{ * TODO: implement this properly * * @return array, members are in the structure [name => [type, value]] + * + * @throws BadPacketException + * @throws BinaryDataException */ public function getGameRules() : array{ $count = $this->getUnsignedVarInt(); @@ -456,7 +496,7 @@ class NetworkBinaryStream extends BinaryStream{ $value = $this->getLFloat(); break; default: - throw new BinaryDataException("Unknown gamerule type $type"); + throw new BadPacketException("Unknown gamerule type $type"); } $rules[$name] = [$type, $value]; @@ -494,6 +534,8 @@ class NetworkBinaryStream extends BinaryStream{ /** * @return EntityLink + * + * @throws BinaryDataException */ protected function getEntityLink() : EntityLink{ $link = new EntityLink(); @@ -516,6 +558,10 @@ class NetworkBinaryStream extends BinaryStream{ $this->putBool($link->immediate); } + /** + * @return CommandOriginData + * @throws BinaryDataException + */ protected function getCommandOriginData() : CommandOriginData{ $result = new CommandOriginData(); diff --git a/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php b/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php index 6bd81c3331..6a417a5871 100644 --- a/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php @@ -191,9 +191,13 @@ class AddEntityPacket extends DataPacket{ $attr = Attribute::getAttribute($id); if($attr !== null){ - $attr->setMinValue($min); - $attr->setMaxValue($max); - $attr->setValue($current); + try{ + $attr->setMinValue($min); + $attr->setMaxValue($max); + $attr->setValue($current); + }catch(\InvalidArgumentException $e){ + throw new BadPacketException($e->getMessage(), 0, $e); //TODO: address this properly + } $this->attributes[] = $attr; }else{ throw new BadPacketException("Unknown attribute type \"$id\""); diff --git a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php index e0c5c4873e..e2458df497 100644 --- a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php @@ -30,6 +30,7 @@ use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\CommandData; use pocketmine\network\mcpe\protocol\types\CommandEnum; use pocketmine\network\mcpe\protocol\types\CommandParameter; +use pocketmine\utils\BinaryDataException; use function array_flip; use function array_keys; use function array_map; @@ -140,6 +141,11 @@ class AvailableCommandsPacket extends DataPacket{ } } + /** + * @return CommandEnum + * @throws BadPacketException + * @throws BinaryDataException + */ protected function getEnum() : CommandEnum{ $retval = new CommandEnum(); $retval->enumName = $this->getString(); @@ -156,6 +162,10 @@ class AvailableCommandsPacket extends DataPacket{ return $retval; } + /** + * @return CommandEnum + * @throws BinaryDataException + */ protected function getSoftEnum() : CommandEnum{ $retval = new CommandEnum(); $retval->enumName = $this->getString(); @@ -191,6 +201,10 @@ class AvailableCommandsPacket extends DataPacket{ } } + /** + * @return int + * @throws BinaryDataException + */ protected function getEnumValueIndex() : int{ if($this->enumValuesCount < 256){ return $this->getByte(); @@ -211,6 +225,11 @@ class AvailableCommandsPacket extends DataPacket{ } } + /** + * @return CommandData + * @throws BadPacketException + * @throws BinaryDataException + */ protected function getCommandData() : CommandData{ $retval = new CommandData(); $retval->commandName = $this->getString(); diff --git a/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php b/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php index 4cc25c1bc1..c4afe4ca6f 100644 --- a/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php @@ -28,6 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\CommandOriginData; use pocketmine\network\mcpe\protocol\types\CommandOutputMessage; +use pocketmine\utils\BinaryDataException; use function count; class CommandOutputPacket extends DataPacket{ @@ -58,6 +59,10 @@ class CommandOutputPacket extends DataPacket{ } } + /** + * @return CommandOutputMessage + * @throws BinaryDataException + */ protected function getCommandMessage() : CommandOutputMessage{ $message = new CommandOutputMessage(); diff --git a/src/pocketmine/network/mcpe/protocol/MoveEntityDeltaPacket.php b/src/pocketmine/network/mcpe/protocol/MoveEntityDeltaPacket.php index e5ff93cd27..f799b60bd0 100644 --- a/src/pocketmine/network/mcpe/protocol/MoveEntityDeltaPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MoveEntityDeltaPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\utils\BinaryDataException; class MoveEntityDeltaPacket extends DataPacket{ public const NETWORK_ID = ProtocolInfo::MOVE_ENTITY_DELTA_PACKET; @@ -54,6 +55,12 @@ class MoveEntityDeltaPacket extends DataPacket{ /** @var float */ public $zRot = 0.0; + /** + * @param int $flag + * + * @return int + * @throws BinaryDataException + */ private function maybeReadCoord(int $flag) : int{ if($this->flags & $flag){ return $this->getVarInt(); @@ -61,6 +68,12 @@ class MoveEntityDeltaPacket extends DataPacket{ return 0; } + /** + * @param int $flag + * + * @return float + * @throws BinaryDataException + */ private function maybeReadRotation(int $flag) : float{ if($this->flags & $flag){ return $this->getByteRotation(); diff --git a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php index 56be858b25..c88b046e7f 100644 --- a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php +++ b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php @@ -31,6 +31,7 @@ use pocketmine\item\Item; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\NetworkBinaryStream; use pocketmine\Player; +use pocketmine\utils\BinaryDataException; class NetworkInventoryAction{ public const SOURCE_CONTAINER = 0; @@ -96,7 +97,8 @@ class NetworkInventoryAction{ * @param NetworkBinaryStream $packet * * @return $this - * @throws \UnexpectedValueException + * + * @throws BinaryDataException * @throws BadPacketException */ public function read(NetworkBinaryStream $packet) : NetworkInventoryAction{ diff --git a/src/pocketmine/network/mcpe/protocol/types/TransactionData.php b/src/pocketmine/network/mcpe/protocol/types/TransactionData.php index 9c183a1b54..8cb0688e2d 100644 --- a/src/pocketmine/network/mcpe/protocol/types/TransactionData.php +++ b/src/pocketmine/network/mcpe/protocol/types/TransactionData.php @@ -23,7 +23,9 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types; +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\NetworkBinaryStream; +use pocketmine\utils\BinaryDataException; use function count; abstract class TransactionData{ @@ -45,8 +47,8 @@ abstract class TransactionData{ /** * @param NetworkBinaryStream $stream * - * @throws \OutOfBoundsException - * @throws \UnexpectedValueException + * @throws BinaryDataException + * @throws BadPacketException */ final public function decode(NetworkBinaryStream $stream) : void{ $actionCount = $stream->getUnsignedVarInt(); @@ -59,8 +61,8 @@ abstract class TransactionData{ /** * @param NetworkBinaryStream $stream * - * @throws \OutOfBoundsException - * @throws \UnexpectedValueException + * @throws BinaryDataException + * @throws BadPacketException */ abstract protected function decodeData(NetworkBinaryStream $stream) : void; From 2656993223389f8711f4c936ee50932a264f3f94 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 16 Jan 2019 21:31:17 +0000 Subject: [PATCH 0401/3224] AAAAAAAAAAAAAAAAAAAAAAAAAAAAA --- src/pocketmine/network/BadPacketException.php | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/pocketmine/network/BadPacketException.php diff --git a/src/pocketmine/network/BadPacketException.php b/src/pocketmine/network/BadPacketException.php new file mode 100644 index 0000000000..179110a65c --- /dev/null +++ b/src/pocketmine/network/BadPacketException.php @@ -0,0 +1,28 @@ + Date: Wed, 16 Jan 2019 22:14:25 +0000 Subject: [PATCH 0402/3224] Move Event cancellable parts to trait --- src/pocketmine/event/CancellableTrait.php | 47 +++++++++++++++++++ src/pocketmine/event/Event.php | 30 ------------ .../event/block/BlockBreakEvent.php | 3 ++ src/pocketmine/event/block/BlockBurnEvent.php | 3 ++ src/pocketmine/event/block/BlockGrowEvent.php | 3 ++ .../event/block/BlockPlaceEvent.php | 3 ++ .../event/block/BlockUpdateEvent.php | 3 +- .../event/block/LeavesDecayEvent.php | 3 +- .../event/block/SignChangeEvent.php | 3 ++ .../event/entity/EntityBlockChangeEvent.php | 3 ++ .../event/entity/EntityCombustEvent.php | 3 ++ .../event/entity/EntityDamageEvent.php | 3 ++ .../event/entity/EntityEffectEvent.php | 3 ++ .../event/entity/EntityExplodeEvent.php | 3 ++ .../entity/EntityInventoryChangeEvent.php | 3 ++ .../event/entity/EntityLevelChangeEvent.php | 3 ++ .../event/entity/EntityMotionEvent.php | 3 ++ .../event/entity/EntityRegainHealthEvent.php | 3 ++ .../event/entity/EntityShootBowEvent.php | 3 ++ .../event/entity/EntityTeleportEvent.php | 3 ++ .../event/entity/ExplosionPrimeEvent.php | 3 ++ .../event/entity/ItemDespawnEvent.php | 2 + .../event/entity/ProjectileLaunchEvent.php | 3 ++ .../event/inventory/CraftItemEvent.php | 3 ++ .../event/inventory/FurnaceBurnEvent.php | 3 ++ .../event/inventory/FurnaceSmeltEvent.php | 3 ++ .../event/inventory/InventoryOpenEvent.php | 3 ++ .../inventory/InventoryPickupArrowEvent.php | 3 ++ .../inventory/InventoryPickupItemEvent.php | 3 ++ .../inventory/InventoryTransactionEvent.php | 3 ++ .../event/level/ChunkUnloadEvent.php | 3 +- .../event/level/LevelUnloadEvent.php | 3 +- .../player/PlayerAchievementAwardedEvent.php | 3 ++ .../event/player/PlayerAnimationEvent.php | 3 ++ .../event/player/PlayerBedEnterEvent.php | 3 ++ .../event/player/PlayerBlockPickEvent.php | 3 ++ .../event/player/PlayerBucketEvent.php | 3 ++ .../event/player/PlayerChangeSkinEvent.php | 3 ++ .../event/player/PlayerChatEvent.php | 3 ++ .../player/PlayerCommandPreprocessEvent.php | 3 ++ .../event/player/PlayerDataSaveEvent.php | 3 ++ .../event/player/PlayerDropItemEvent.php | 3 ++ .../player/PlayerDuplicateLoginEvent.php | 2 + .../event/player/PlayerEditBookEvent.php | 3 ++ .../event/player/PlayerExhaustEvent.php | 3 ++ .../player/PlayerExperienceChangeEvent.php | 3 ++ .../player/PlayerGameModeChangeEvent.php | 3 ++ .../event/player/PlayerInteractEvent.php | 3 ++ .../event/player/PlayerItemConsumeEvent.php | 3 ++ .../event/player/PlayerItemHeldEvent.php | 3 ++ .../event/player/PlayerItemUseEvent.php | 2 + .../event/player/PlayerKickEvent.php | 3 ++ .../event/player/PlayerLoginEvent.php | 3 ++ .../event/player/PlayerMoveEvent.php | 3 ++ .../event/player/PlayerToggleFlightEvent.php | 3 ++ .../event/player/PlayerToggleSneakEvent.php | 3 ++ .../event/player/PlayerToggleSprintEvent.php | 3 ++ .../event/player/PlayerTransferEvent.php | 3 ++ .../player/cheat/PlayerIllegalMoveEvent.php | 3 ++ src/pocketmine/event/server/CommandEvent.php | 3 ++ .../event/server/DataPacketBroadcastEvent.php | 3 ++ .../event/server/DataPacketReceiveEvent.php | 3 ++ .../event/server/DataPacketSendEvent.php | 3 ++ .../server/NetworkInterfaceRegisterEvent.php | 3 +- 64 files changed, 225 insertions(+), 35 deletions(-) create mode 100644 src/pocketmine/event/CancellableTrait.php diff --git a/src/pocketmine/event/CancellableTrait.php b/src/pocketmine/event/CancellableTrait.php new file mode 100644 index 0000000000..740f24a4e2 --- /dev/null +++ b/src/pocketmine/event/CancellableTrait.php @@ -0,0 +1,47 @@ +isCancelled; + } + + /** + * @param bool $value + */ + public function setCancelled(bool $value = true) : void{ + $this->isCancelled = $value; + } +} diff --git a/src/pocketmine/event/Event.php b/src/pocketmine/event/Event.php index e3bcf871f1..6123806812 100644 --- a/src/pocketmine/event/Event.php +++ b/src/pocketmine/event/Event.php @@ -36,8 +36,6 @@ abstract class Event{ /** @var string|null */ protected $eventName = null; - /** @var bool */ - private $isCancelled = false; /** * @return string @@ -46,34 +44,6 @@ abstract class Event{ return $this->eventName ?? get_class($this); } - /** - * @return bool - * - * @throws \BadMethodCallException - */ - public function isCancelled() : bool{ - if(!($this instanceof Cancellable)){ - throw new \BadMethodCallException(get_class($this) . " is not Cancellable"); - } - - /** @var Event $this */ - return $this->isCancelled; - } - - /** - * @param bool $value - * - * @throws \BadMethodCallException - */ - public function setCancelled(bool $value = true) : void{ - if(!($this instanceof Cancellable)){ - throw new \BadMethodCallException(get_class($this) . " is not Cancellable"); - } - - /** @var Event $this */ - $this->isCancelled = $value; - } - /** * Calls event handlers registered for this event. * diff --git a/src/pocketmine/event/block/BlockBreakEvent.php b/src/pocketmine/event/block/BlockBreakEvent.php index f294757993..16d97b7133 100644 --- a/src/pocketmine/event/block/BlockBreakEvent.php +++ b/src/pocketmine/event/block/BlockBreakEvent.php @@ -25,6 +25,7 @@ namespace pocketmine\event\block; use pocketmine\block\Block; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\item\Item; use pocketmine\Player; @@ -32,6 +33,8 @@ use pocketmine\Player; * Called when a player destroys a block somewhere in the world. */ class BlockBreakEvent extends BlockEvent implements Cancellable{ + use CancellableTrait; + /** @var Player */ protected $player; diff --git a/src/pocketmine/event/block/BlockBurnEvent.php b/src/pocketmine/event/block/BlockBurnEvent.php index 1764199d51..d50f96953f 100644 --- a/src/pocketmine/event/block/BlockBurnEvent.php +++ b/src/pocketmine/event/block/BlockBurnEvent.php @@ -25,11 +25,14 @@ namespace pocketmine\event\block; use pocketmine\block\Block; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; /** * Called when a block is burned away by fire. */ class BlockBurnEvent extends BlockEvent implements Cancellable{ + use CancellableTrait; + /** @var Block */ private $causingBlock; diff --git a/src/pocketmine/event/block/BlockGrowEvent.php b/src/pocketmine/event/block/BlockGrowEvent.php index c2caff64fc..49cac65d7c 100644 --- a/src/pocketmine/event/block/BlockGrowEvent.php +++ b/src/pocketmine/event/block/BlockGrowEvent.php @@ -25,11 +25,14 @@ namespace pocketmine\event\block; use pocketmine\block\Block; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; /** * Called when plants or crops grow. */ class BlockGrowEvent extends BlockEvent implements Cancellable{ + use CancellableTrait; + /** @var Block */ private $newState; diff --git a/src/pocketmine/event/block/BlockPlaceEvent.php b/src/pocketmine/event/block/BlockPlaceEvent.php index 44e3b9e6d3..d7c51cf671 100644 --- a/src/pocketmine/event/block/BlockPlaceEvent.php +++ b/src/pocketmine/event/block/BlockPlaceEvent.php @@ -25,6 +25,7 @@ namespace pocketmine\event\block; use pocketmine\block\Block; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\item\Item; use pocketmine\Player; @@ -32,6 +33,8 @@ use pocketmine\Player; * Called when a player places a block */ class BlockPlaceEvent extends BlockEvent implements Cancellable{ + use CancellableTrait; + /** @var Player */ protected $player; diff --git a/src/pocketmine/event/block/BlockUpdateEvent.php b/src/pocketmine/event/block/BlockUpdateEvent.php index 8e31251537..0944afd9e4 100644 --- a/src/pocketmine/event/block/BlockUpdateEvent.php +++ b/src/pocketmine/event/block/BlockUpdateEvent.php @@ -24,10 +24,11 @@ declare(strict_types=1); namespace pocketmine\event\block; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; /** * Called when a block tries to be updated due to a neighbor change */ class BlockUpdateEvent extends BlockEvent implements Cancellable{ - + use CancellableTrait; } diff --git a/src/pocketmine/event/block/LeavesDecayEvent.php b/src/pocketmine/event/block/LeavesDecayEvent.php index 9fe15234a6..c68461b6f4 100644 --- a/src/pocketmine/event/block/LeavesDecayEvent.php +++ b/src/pocketmine/event/block/LeavesDecayEvent.php @@ -24,10 +24,11 @@ declare(strict_types=1); namespace pocketmine\event\block; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; /** * Called when leaves decay due to not being attached to wood. */ class LeavesDecayEvent extends BlockEvent implements Cancellable{ - + use CancellableTrait; } diff --git a/src/pocketmine/event/block/SignChangeEvent.php b/src/pocketmine/event/block/SignChangeEvent.php index ff1e1f0564..267f002247 100644 --- a/src/pocketmine/event/block/SignChangeEvent.php +++ b/src/pocketmine/event/block/SignChangeEvent.php @@ -25,6 +25,7 @@ namespace pocketmine\event\block; use pocketmine\block\Block; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\Player; use function count; @@ -32,6 +33,8 @@ use function count; * Called when a sign is changed by a player. */ class SignChangeEvent extends BlockEvent implements Cancellable{ + use CancellableTrait; + /** @var Player */ private $player; /** @var string[] */ diff --git a/src/pocketmine/event/entity/EntityBlockChangeEvent.php b/src/pocketmine/event/entity/EntityBlockChangeEvent.php index 4ac9a86244..1655dc8d77 100644 --- a/src/pocketmine/event/entity/EntityBlockChangeEvent.php +++ b/src/pocketmine/event/entity/EntityBlockChangeEvent.php @@ -26,11 +26,14 @@ namespace pocketmine\event\entity; use pocketmine\block\Block; use pocketmine\entity\Entity; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; /** * Called when an Entity, excluding players, changes a block directly */ class EntityBlockChangeEvent extends EntityEvent implements Cancellable{ + use CancellableTrait; + /** @var Block */ private $from; /** @var Block */ diff --git a/src/pocketmine/event/entity/EntityCombustEvent.php b/src/pocketmine/event/entity/EntityCombustEvent.php index 17f7634910..e205390c91 100644 --- a/src/pocketmine/event/entity/EntityCombustEvent.php +++ b/src/pocketmine/event/entity/EntityCombustEvent.php @@ -25,8 +25,11 @@ namespace pocketmine\event\entity; use pocketmine\entity\Entity; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; class EntityCombustEvent extends EntityEvent implements Cancellable{ + use CancellableTrait; + protected $duration; /** diff --git a/src/pocketmine/event/entity/EntityDamageEvent.php b/src/pocketmine/event/entity/EntityDamageEvent.php index 9792a7d2e1..2fc305977c 100644 --- a/src/pocketmine/event/entity/EntityDamageEvent.php +++ b/src/pocketmine/event/entity/EntityDamageEvent.php @@ -25,12 +25,15 @@ namespace pocketmine\event\entity; use pocketmine\entity\Entity; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use function array_sum; /** * Called when an entity takes damage. */ class EntityDamageEvent extends EntityEvent implements Cancellable{ + use CancellableTrait; + public const MODIFIER_ARMOR = 1; public const MODIFIER_STRENGTH = 2; public const MODIFIER_WEAKNESS = 3; diff --git a/src/pocketmine/event/entity/EntityEffectEvent.php b/src/pocketmine/event/entity/EntityEffectEvent.php index 072144bdd3..01bdb47c7f 100644 --- a/src/pocketmine/event/entity/EntityEffectEvent.php +++ b/src/pocketmine/event/entity/EntityEffectEvent.php @@ -26,8 +26,11 @@ namespace pocketmine\event\entity; use pocketmine\entity\EffectInstance; use pocketmine\entity\Entity; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; class EntityEffectEvent extends EntityEvent implements Cancellable{ + use CancellableTrait; + /** @var EffectInstance */ private $effect; diff --git a/src/pocketmine/event/entity/EntityExplodeEvent.php b/src/pocketmine/event/entity/EntityExplodeEvent.php index 3a7256f310..f3aa1c98fb 100644 --- a/src/pocketmine/event/entity/EntityExplodeEvent.php +++ b/src/pocketmine/event/entity/EntityExplodeEvent.php @@ -26,12 +26,15 @@ namespace pocketmine\event\entity; use pocketmine\block\Block; use pocketmine\entity\Entity; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\level\Position; /** * Called when a entity explodes */ class EntityExplodeEvent extends EntityEvent implements Cancellable{ + use CancellableTrait; + /** @var Position */ protected $position; diff --git a/src/pocketmine/event/entity/EntityInventoryChangeEvent.php b/src/pocketmine/event/entity/EntityInventoryChangeEvent.php index 0e7c12538e..fc3fc17a51 100644 --- a/src/pocketmine/event/entity/EntityInventoryChangeEvent.php +++ b/src/pocketmine/event/entity/EntityInventoryChangeEvent.php @@ -25,12 +25,15 @@ namespace pocketmine\event\entity; use pocketmine\entity\Entity; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\item\Item; /** * Called before a slot in an entity's inventory changes. */ class EntityInventoryChangeEvent extends EntityEvent implements Cancellable{ + use CancellableTrait; + /** @var Item */ private $oldItem; /** @var Item */ diff --git a/src/pocketmine/event/entity/EntityLevelChangeEvent.php b/src/pocketmine/event/entity/EntityLevelChangeEvent.php index c9118665b5..cb792115ef 100644 --- a/src/pocketmine/event/entity/EntityLevelChangeEvent.php +++ b/src/pocketmine/event/entity/EntityLevelChangeEvent.php @@ -25,9 +25,12 @@ namespace pocketmine\event\entity; use pocketmine\entity\Entity; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\level\Level; class EntityLevelChangeEvent extends EntityEvent implements Cancellable{ + use CancellableTrait; + /** @var Level */ private $originLevel; /** @var Level */ diff --git a/src/pocketmine/event/entity/EntityMotionEvent.php b/src/pocketmine/event/entity/EntityMotionEvent.php index 36b9a2d1c0..c917e0cac7 100644 --- a/src/pocketmine/event/entity/EntityMotionEvent.php +++ b/src/pocketmine/event/entity/EntityMotionEvent.php @@ -25,9 +25,12 @@ namespace pocketmine\event\entity; use pocketmine\entity\Entity; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\math\Vector3; class EntityMotionEvent extends EntityEvent implements Cancellable{ + use CancellableTrait; + /** @var Vector3 */ private $mot; diff --git a/src/pocketmine/event/entity/EntityRegainHealthEvent.php b/src/pocketmine/event/entity/EntityRegainHealthEvent.php index da8a24b18d..153b0fd8aa 100644 --- a/src/pocketmine/event/entity/EntityRegainHealthEvent.php +++ b/src/pocketmine/event/entity/EntityRegainHealthEvent.php @@ -25,8 +25,11 @@ namespace pocketmine\event\entity; use pocketmine\entity\Entity; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; class EntityRegainHealthEvent extends EntityEvent implements Cancellable{ + use CancellableTrait; + public const CAUSE_REGEN = 0; public const CAUSE_EATING = 1; public const CAUSE_MAGIC = 2; diff --git a/src/pocketmine/event/entity/EntityShootBowEvent.php b/src/pocketmine/event/entity/EntityShootBowEvent.php index cafede44c0..eeded96159 100644 --- a/src/pocketmine/event/entity/EntityShootBowEvent.php +++ b/src/pocketmine/event/entity/EntityShootBowEvent.php @@ -27,10 +27,13 @@ use pocketmine\entity\Entity; use pocketmine\entity\Living; use pocketmine\entity\projectile\Projectile; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\item\Item; use function count; class EntityShootBowEvent extends EntityEvent implements Cancellable{ + use CancellableTrait; + /** @var Item */ private $bow; /** @var Projectile */ diff --git a/src/pocketmine/event/entity/EntityTeleportEvent.php b/src/pocketmine/event/entity/EntityTeleportEvent.php index 7b467461a3..3c5c5dc573 100644 --- a/src/pocketmine/event/entity/EntityTeleportEvent.php +++ b/src/pocketmine/event/entity/EntityTeleportEvent.php @@ -25,9 +25,12 @@ namespace pocketmine\event\entity; use pocketmine\entity\Entity; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\level\Position; class EntityTeleportEvent extends EntityEvent implements Cancellable{ + use CancellableTrait; + /** @var Position */ private $from; /** @var Position */ diff --git a/src/pocketmine/event/entity/ExplosionPrimeEvent.php b/src/pocketmine/event/entity/ExplosionPrimeEvent.php index db6c734470..c2ecb2cf80 100644 --- a/src/pocketmine/event/entity/ExplosionPrimeEvent.php +++ b/src/pocketmine/event/entity/ExplosionPrimeEvent.php @@ -25,11 +25,14 @@ namespace pocketmine\event\entity; use pocketmine\entity\Entity; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; /** * Called when a entity decides to explode */ class ExplosionPrimeEvent extends EntityEvent implements Cancellable{ + use CancellableTrait; + /** @var float */ protected $force; /** @var bool */ diff --git a/src/pocketmine/event/entity/ItemDespawnEvent.php b/src/pocketmine/event/entity/ItemDespawnEvent.php index c934dd5653..2a34ccca4a 100644 --- a/src/pocketmine/event/entity/ItemDespawnEvent.php +++ b/src/pocketmine/event/entity/ItemDespawnEvent.php @@ -25,8 +25,10 @@ namespace pocketmine\event\entity; use pocketmine\entity\object\ItemEntity; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; class ItemDespawnEvent extends EntityEvent implements Cancellable{ + use CancellableTrait; /** * @param ItemEntity $item diff --git a/src/pocketmine/event/entity/ProjectileLaunchEvent.php b/src/pocketmine/event/entity/ProjectileLaunchEvent.php index 6aafb585c3..b66c5e3d59 100644 --- a/src/pocketmine/event/entity/ProjectileLaunchEvent.php +++ b/src/pocketmine/event/entity/ProjectileLaunchEvent.php @@ -25,8 +25,11 @@ namespace pocketmine\event\entity; use pocketmine\entity\projectile\Projectile; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; class ProjectileLaunchEvent extends EntityEvent implements Cancellable{ + use CancellableTrait; + /** * @param Projectile $entity */ diff --git a/src/pocketmine/event/inventory/CraftItemEvent.php b/src/pocketmine/event/inventory/CraftItemEvent.php index 3aaaacede9..8630331b49 100644 --- a/src/pocketmine/event/inventory/CraftItemEvent.php +++ b/src/pocketmine/event/inventory/CraftItemEvent.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\event\inventory; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\event\Event; use pocketmine\inventory\CraftingRecipe; use pocketmine\inventory\transaction\CraftingTransaction; @@ -31,6 +32,8 @@ use pocketmine\item\Item; use pocketmine\Player; class CraftItemEvent extends Event implements Cancellable{ + use CancellableTrait; + /** @var CraftingTransaction */ private $transaction; /** @var CraftingRecipe */ diff --git a/src/pocketmine/event/inventory/FurnaceBurnEvent.php b/src/pocketmine/event/inventory/FurnaceBurnEvent.php index b0637ccc08..1ace733297 100644 --- a/src/pocketmine/event/inventory/FurnaceBurnEvent.php +++ b/src/pocketmine/event/inventory/FurnaceBurnEvent.php @@ -25,10 +25,13 @@ namespace pocketmine\event\inventory; use pocketmine\event\block\BlockEvent; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\item\Item; use pocketmine\tile\Furnace; class FurnaceBurnEvent extends BlockEvent implements Cancellable{ + use CancellableTrait; + /** @var Furnace */ private $furnace; /** @var Item */ diff --git a/src/pocketmine/event/inventory/FurnaceSmeltEvent.php b/src/pocketmine/event/inventory/FurnaceSmeltEvent.php index 5b487d1c30..b69f0115ae 100644 --- a/src/pocketmine/event/inventory/FurnaceSmeltEvent.php +++ b/src/pocketmine/event/inventory/FurnaceSmeltEvent.php @@ -25,10 +25,13 @@ namespace pocketmine\event\inventory; use pocketmine\event\block\BlockEvent; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\item\Item; use pocketmine\tile\Furnace; class FurnaceSmeltEvent extends BlockEvent implements Cancellable{ + use CancellableTrait; + /** @var Furnace */ private $furnace; /** @var Item */ diff --git a/src/pocketmine/event/inventory/InventoryOpenEvent.php b/src/pocketmine/event/inventory/InventoryOpenEvent.php index 0b26c9bfb0..79ccb8ec26 100644 --- a/src/pocketmine/event/inventory/InventoryOpenEvent.php +++ b/src/pocketmine/event/inventory/InventoryOpenEvent.php @@ -24,10 +24,13 @@ declare(strict_types=1); namespace pocketmine\event\inventory; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\inventory\Inventory; use pocketmine\Player; class InventoryOpenEvent extends InventoryEvent implements Cancellable{ + use CancellableTrait; + /** @var Player */ private $who; diff --git a/src/pocketmine/event/inventory/InventoryPickupArrowEvent.php b/src/pocketmine/event/inventory/InventoryPickupArrowEvent.php index 0efa7af7b3..058c6be929 100644 --- a/src/pocketmine/event/inventory/InventoryPickupArrowEvent.php +++ b/src/pocketmine/event/inventory/InventoryPickupArrowEvent.php @@ -25,9 +25,12 @@ namespace pocketmine\event\inventory; use pocketmine\entity\projectile\Arrow; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\inventory\Inventory; class InventoryPickupArrowEvent extends InventoryEvent implements Cancellable{ + use CancellableTrait; + /** @var Arrow */ private $arrow; diff --git a/src/pocketmine/event/inventory/InventoryPickupItemEvent.php b/src/pocketmine/event/inventory/InventoryPickupItemEvent.php index f94e6dfeb5..60ead87c74 100644 --- a/src/pocketmine/event/inventory/InventoryPickupItemEvent.php +++ b/src/pocketmine/event/inventory/InventoryPickupItemEvent.php @@ -25,9 +25,12 @@ namespace pocketmine\event\inventory; use pocketmine\entity\object\ItemEntity; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\inventory\Inventory; class InventoryPickupItemEvent extends InventoryEvent implements Cancellable{ + use CancellableTrait; + /** @var ItemEntity */ private $item; diff --git a/src/pocketmine/event/inventory/InventoryTransactionEvent.php b/src/pocketmine/event/inventory/InventoryTransactionEvent.php index 50d7671aea..34f02ee242 100644 --- a/src/pocketmine/event/inventory/InventoryTransactionEvent.php +++ b/src/pocketmine/event/inventory/InventoryTransactionEvent.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\event\inventory; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\event\Event; use pocketmine\inventory\transaction\InventoryTransaction; @@ -32,6 +33,8 @@ use pocketmine\inventory\transaction\InventoryTransaction; * The source of this can be a Player, entities, mobs, or even hoppers in the future! */ class InventoryTransactionEvent extends Event implements Cancellable{ + use CancellableTrait; + /** @var InventoryTransaction */ private $transaction; diff --git a/src/pocketmine/event/level/ChunkUnloadEvent.php b/src/pocketmine/event/level/ChunkUnloadEvent.php index 288325864d..e37df56cd1 100644 --- a/src/pocketmine/event/level/ChunkUnloadEvent.php +++ b/src/pocketmine/event/level/ChunkUnloadEvent.php @@ -24,10 +24,11 @@ declare(strict_types=1); namespace pocketmine\event\level; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; /** * Called when a Chunk is unloaded */ class ChunkUnloadEvent extends ChunkEvent implements Cancellable{ - + use CancellableTrait; } diff --git a/src/pocketmine/event/level/LevelUnloadEvent.php b/src/pocketmine/event/level/LevelUnloadEvent.php index e5cc36e8af..14b950396b 100644 --- a/src/pocketmine/event/level/LevelUnloadEvent.php +++ b/src/pocketmine/event/level/LevelUnloadEvent.php @@ -24,10 +24,11 @@ declare(strict_types=1); namespace pocketmine\event\level; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; /** * Called when a Level is unloaded */ class LevelUnloadEvent extends LevelEvent implements Cancellable{ - + use CancellableTrait; } diff --git a/src/pocketmine/event/player/PlayerAchievementAwardedEvent.php b/src/pocketmine/event/player/PlayerAchievementAwardedEvent.php index 7b2231a9ab..da9ebea5de 100644 --- a/src/pocketmine/event/player/PlayerAchievementAwardedEvent.php +++ b/src/pocketmine/event/player/PlayerAchievementAwardedEvent.php @@ -24,12 +24,15 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\Player; /** * Called when a player is awarded an achievement */ class PlayerAchievementAwardedEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + /** @var string */ protected $achievement; diff --git a/src/pocketmine/event/player/PlayerAnimationEvent.php b/src/pocketmine/event/player/PlayerAnimationEvent.php index b0650446bf..af6ad556fc 100644 --- a/src/pocketmine/event/player/PlayerAnimationEvent.php +++ b/src/pocketmine/event/player/PlayerAnimationEvent.php @@ -24,12 +24,15 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\Player; /** * Called when a player does an animation */ class PlayerAnimationEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + /** @var int */ private $animationType; diff --git a/src/pocketmine/event/player/PlayerBedEnterEvent.php b/src/pocketmine/event/player/PlayerBedEnterEvent.php index e25ac35a73..be2ee766c8 100644 --- a/src/pocketmine/event/player/PlayerBedEnterEvent.php +++ b/src/pocketmine/event/player/PlayerBedEnterEvent.php @@ -25,9 +25,12 @@ namespace pocketmine\event\player; use pocketmine\block\Block; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\Player; class PlayerBedEnterEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + /** @var Block */ private $bed; diff --git a/src/pocketmine/event/player/PlayerBlockPickEvent.php b/src/pocketmine/event/player/PlayerBlockPickEvent.php index d4a9f7f058..9cbb092219 100644 --- a/src/pocketmine/event/player/PlayerBlockPickEvent.php +++ b/src/pocketmine/event/player/PlayerBlockPickEvent.php @@ -25,6 +25,7 @@ namespace pocketmine\event\player; use pocketmine\block\Block; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\item\Item; use pocketmine\Player; @@ -32,6 +33,8 @@ use pocketmine\Player; * Called when a player middle-clicks on a block to get an item in creative mode. */ class PlayerBlockPickEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + /** @var Block */ private $blockClicked; /** @var Item */ diff --git a/src/pocketmine/event/player/PlayerBucketEvent.php b/src/pocketmine/event/player/PlayerBucketEvent.php index f207aeef98..8aba82ae52 100644 --- a/src/pocketmine/event/player/PlayerBucketEvent.php +++ b/src/pocketmine/event/player/PlayerBucketEvent.php @@ -25,6 +25,7 @@ namespace pocketmine\event\player; use pocketmine\block\Block; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\item\Item; use pocketmine\Player; @@ -32,6 +33,8 @@ use pocketmine\Player; * @allowHandle */ abstract class PlayerBucketEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + /** @var Block */ private $blockClicked; /** @var int */ diff --git a/src/pocketmine/event/player/PlayerChangeSkinEvent.php b/src/pocketmine/event/player/PlayerChangeSkinEvent.php index bfb854b721..60070218b6 100644 --- a/src/pocketmine/event/player/PlayerChangeSkinEvent.php +++ b/src/pocketmine/event/player/PlayerChangeSkinEvent.php @@ -25,12 +25,15 @@ namespace pocketmine\event\player; use pocketmine\entity\Skin; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\Player; /** * Called when a player changes their skin in-game. */ class PlayerChangeSkinEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + /** @var Skin */ private $oldSkin; /** @var Skin */ diff --git a/src/pocketmine/event/player/PlayerChatEvent.php b/src/pocketmine/event/player/PlayerChatEvent.php index 4ebddecdd7..b12fa0858a 100644 --- a/src/pocketmine/event/player/PlayerChatEvent.php +++ b/src/pocketmine/event/player/PlayerChatEvent.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\permission\PermissionManager; use pocketmine\Player; use pocketmine\Server; @@ -32,6 +33,8 @@ use pocketmine\Server; * Called when a player chats something */ class PlayerChatEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + /** @var string */ protected $message; diff --git a/src/pocketmine/event/player/PlayerCommandPreprocessEvent.php b/src/pocketmine/event/player/PlayerCommandPreprocessEvent.php index edeaa847d5..2c8951c6fa 100644 --- a/src/pocketmine/event/player/PlayerCommandPreprocessEvent.php +++ b/src/pocketmine/event/player/PlayerCommandPreprocessEvent.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\Player; /** @@ -35,6 +36,8 @@ use pocketmine\Player; * The message contains a slash at the start */ class PlayerCommandPreprocessEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + /** @var string */ protected $message; diff --git a/src/pocketmine/event/player/PlayerDataSaveEvent.php b/src/pocketmine/event/player/PlayerDataSaveEvent.php index c3296bdce3..cb23ad01dd 100644 --- a/src/pocketmine/event/player/PlayerDataSaveEvent.php +++ b/src/pocketmine/event/player/PlayerDataSaveEvent.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\event\Event; use pocketmine\IPlayer; use pocketmine\nbt\tag\CompoundTag; @@ -33,6 +34,8 @@ use pocketmine\Server; * Called when a player's data is about to be saved to disk. */ class PlayerDataSaveEvent extends Event implements Cancellable{ + use CancellableTrait; + /** @var CompoundTag */ protected $data; /** @var string */ diff --git a/src/pocketmine/event/player/PlayerDropItemEvent.php b/src/pocketmine/event/player/PlayerDropItemEvent.php index 5a16af15e6..0cf50d995e 100644 --- a/src/pocketmine/event/player/PlayerDropItemEvent.php +++ b/src/pocketmine/event/player/PlayerDropItemEvent.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\item\Item; use pocketmine\Player; @@ -31,6 +32,8 @@ use pocketmine\Player; * Called when a player tries to drop an item from its hotbar */ class PlayerDropItemEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + /** @var Item */ private $drop; diff --git a/src/pocketmine/event/player/PlayerDuplicateLoginEvent.php b/src/pocketmine/event/player/PlayerDuplicateLoginEvent.php index 9ef7accf48..d77f6fc4cc 100644 --- a/src/pocketmine/event/player/PlayerDuplicateLoginEvent.php +++ b/src/pocketmine/event/player/PlayerDuplicateLoginEvent.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\event\Event; use pocketmine\network\mcpe\NetworkSession; @@ -32,6 +33,7 @@ use pocketmine\network\mcpe\NetworkSession; * If cancelled, the newly connecting session will be disconnected; otherwise, the existing player will be disconnected. */ class PlayerDuplicateLoginEvent extends Event implements Cancellable{ + use CancellableTrait; /** @var NetworkSession */ private $connectingSession; diff --git a/src/pocketmine/event/player/PlayerEditBookEvent.php b/src/pocketmine/event/player/PlayerEditBookEvent.php index c0b7c6ad30..6aac41d9e3 100644 --- a/src/pocketmine/event/player/PlayerEditBookEvent.php +++ b/src/pocketmine/event/player/PlayerEditBookEvent.php @@ -24,10 +24,13 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\item\WritableBook; use pocketmine\Player; class PlayerEditBookEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + public const ACTION_REPLACE_PAGE = 0; public const ACTION_ADD_PAGE = 1; public const ACTION_DELETE_PAGE = 2; diff --git a/src/pocketmine/event/player/PlayerExhaustEvent.php b/src/pocketmine/event/player/PlayerExhaustEvent.php index 1e765bdbb9..91ab4caea3 100644 --- a/src/pocketmine/event/player/PlayerExhaustEvent.php +++ b/src/pocketmine/event/player/PlayerExhaustEvent.php @@ -25,9 +25,12 @@ namespace pocketmine\event\player; use pocketmine\entity\Human; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\event\entity\EntityEvent; class PlayerExhaustEvent extends EntityEvent implements Cancellable{ + use CancellableTrait; + public const CAUSE_ATTACK = 1; public const CAUSE_DAMAGE = 2; public const CAUSE_MINING = 3; diff --git a/src/pocketmine/event/player/PlayerExperienceChangeEvent.php b/src/pocketmine/event/player/PlayerExperienceChangeEvent.php index dc72f43714..56197678c3 100644 --- a/src/pocketmine/event/player/PlayerExperienceChangeEvent.php +++ b/src/pocketmine/event/player/PlayerExperienceChangeEvent.php @@ -25,12 +25,15 @@ namespace pocketmine\event\player; use pocketmine\entity\Human; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\event\entity\EntityEvent; /** * Called when a player gains or loses XP levels and/or progress. */ class PlayerExperienceChangeEvent extends EntityEvent implements Cancellable{ + use CancellableTrait; + /** @var Human */ protected $entity; /** @var int */ diff --git a/src/pocketmine/event/player/PlayerGameModeChangeEvent.php b/src/pocketmine/event/player/PlayerGameModeChangeEvent.php index 9697c9f72c..0a399e0bc3 100644 --- a/src/pocketmine/event/player/PlayerGameModeChangeEvent.php +++ b/src/pocketmine/event/player/PlayerGameModeChangeEvent.php @@ -24,12 +24,15 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\Player; /** * Called when a player has its gamemode changed */ class PlayerGameModeChangeEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + /** @var int */ protected $gamemode; diff --git a/src/pocketmine/event/player/PlayerInteractEvent.php b/src/pocketmine/event/player/PlayerInteractEvent.php index 1d82d124ab..5b4a86cd38 100644 --- a/src/pocketmine/event/player/PlayerInteractEvent.php +++ b/src/pocketmine/event/player/PlayerInteractEvent.php @@ -25,6 +25,7 @@ namespace pocketmine\event\player; use pocketmine\block\Block; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\Player; @@ -33,6 +34,8 @@ use pocketmine\Player; * Called when a player interacts or touches a block (including air?) */ class PlayerInteractEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + public const LEFT_CLICK_BLOCK = 0; public const RIGHT_CLICK_BLOCK = 1; diff --git a/src/pocketmine/event/player/PlayerItemConsumeEvent.php b/src/pocketmine/event/player/PlayerItemConsumeEvent.php index 54a4eecae9..aac350fd01 100644 --- a/src/pocketmine/event/player/PlayerItemConsumeEvent.php +++ b/src/pocketmine/event/player/PlayerItemConsumeEvent.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\item\Item; use pocketmine\Player; @@ -31,6 +32,8 @@ use pocketmine\Player; * Called when a player eats something */ class PlayerItemConsumeEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + /** @var Item */ private $item; diff --git a/src/pocketmine/event/player/PlayerItemHeldEvent.php b/src/pocketmine/event/player/PlayerItemHeldEvent.php index 9b56f1cbd4..6f81004178 100644 --- a/src/pocketmine/event/player/PlayerItemHeldEvent.php +++ b/src/pocketmine/event/player/PlayerItemHeldEvent.php @@ -24,10 +24,13 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\item\Item; use pocketmine\Player; class PlayerItemHeldEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + /** @var Item */ private $item; /** @var int */ diff --git a/src/pocketmine/event/player/PlayerItemUseEvent.php b/src/pocketmine/event/player/PlayerItemUseEvent.php index 743e78ca1d..c7aafd61ba 100644 --- a/src/pocketmine/event/player/PlayerItemUseEvent.php +++ b/src/pocketmine/event/player/PlayerItemUseEvent.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\Player; @@ -32,6 +33,7 @@ use pocketmine\Player; * Called when a player uses its held item, for example when throwing a projectile. */ class PlayerItemUseEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; /** @var Item */ private $item; diff --git a/src/pocketmine/event/player/PlayerKickEvent.php b/src/pocketmine/event/player/PlayerKickEvent.php index d696825c89..b199a9410c 100644 --- a/src/pocketmine/event/player/PlayerKickEvent.php +++ b/src/pocketmine/event/player/PlayerKickEvent.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\lang\TextContainer; use pocketmine\Player; @@ -31,6 +32,8 @@ use pocketmine\Player; * Called when a player leaves the server */ class PlayerKickEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + /** @var TextContainer|string */ protected $quitMessage; diff --git a/src/pocketmine/event/player/PlayerLoginEvent.php b/src/pocketmine/event/player/PlayerLoginEvent.php index 5afbaa061b..298f2a1b2e 100644 --- a/src/pocketmine/event/player/PlayerLoginEvent.php +++ b/src/pocketmine/event/player/PlayerLoginEvent.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\Player; /** @@ -32,6 +33,8 @@ use pocketmine\Player; * Cancelling this event will cause the player to be disconnected with the kick message set. */ class PlayerLoginEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + /** @var string */ protected $kickMessage; diff --git a/src/pocketmine/event/player/PlayerMoveEvent.php b/src/pocketmine/event/player/PlayerMoveEvent.php index 0725faf62c..720a98b95b 100644 --- a/src/pocketmine/event/player/PlayerMoveEvent.php +++ b/src/pocketmine/event/player/PlayerMoveEvent.php @@ -24,10 +24,13 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\level\Location; use pocketmine\Player; class PlayerMoveEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + /** @var Location */ private $from; /** @var Location */ diff --git a/src/pocketmine/event/player/PlayerToggleFlightEvent.php b/src/pocketmine/event/player/PlayerToggleFlightEvent.php index de0511e9dc..298947c423 100644 --- a/src/pocketmine/event/player/PlayerToggleFlightEvent.php +++ b/src/pocketmine/event/player/PlayerToggleFlightEvent.php @@ -24,9 +24,12 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\Player; class PlayerToggleFlightEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + /** @var bool */ protected $isFlying; diff --git a/src/pocketmine/event/player/PlayerToggleSneakEvent.php b/src/pocketmine/event/player/PlayerToggleSneakEvent.php index 902f5b9c61..8ba0ac5990 100644 --- a/src/pocketmine/event/player/PlayerToggleSneakEvent.php +++ b/src/pocketmine/event/player/PlayerToggleSneakEvent.php @@ -24,9 +24,12 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\Player; class PlayerToggleSneakEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + /** @var bool */ protected $isSneaking; diff --git a/src/pocketmine/event/player/PlayerToggleSprintEvent.php b/src/pocketmine/event/player/PlayerToggleSprintEvent.php index 96f8c1c0a8..323df0120a 100644 --- a/src/pocketmine/event/player/PlayerToggleSprintEvent.php +++ b/src/pocketmine/event/player/PlayerToggleSprintEvent.php @@ -24,9 +24,12 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\Player; class PlayerToggleSprintEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + /** @var bool */ protected $isSprinting; diff --git a/src/pocketmine/event/player/PlayerTransferEvent.php b/src/pocketmine/event/player/PlayerTransferEvent.php index 146e08b718..31baa90dc2 100644 --- a/src/pocketmine/event/player/PlayerTransferEvent.php +++ b/src/pocketmine/event/player/PlayerTransferEvent.php @@ -24,9 +24,12 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\Player; class PlayerTransferEvent extends PlayerEvent implements Cancellable{ + use CancellableTrait; + /** @var string */ protected $address; /** @var int */ diff --git a/src/pocketmine/event/player/cheat/PlayerIllegalMoveEvent.php b/src/pocketmine/event/player/cheat/PlayerIllegalMoveEvent.php index 5beae2a4ab..454cb7f385 100644 --- a/src/pocketmine/event/player/cheat/PlayerIllegalMoveEvent.php +++ b/src/pocketmine/event/player/cheat/PlayerIllegalMoveEvent.php @@ -25,6 +25,7 @@ declare(strict_types=1); namespace pocketmine\event\player\cheat; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\math\Vector3; use pocketmine\Player; @@ -32,6 +33,8 @@ use pocketmine\Player; * Called when a player attempts to perform movement cheats such as clipping through blocks. */ class PlayerIllegalMoveEvent extends PlayerCheatEvent implements Cancellable{ + use CancellableTrait; + /** @var Vector3 */ private $attemptedPosition; diff --git a/src/pocketmine/event/server/CommandEvent.php b/src/pocketmine/event/server/CommandEvent.php index d5dd422a3e..95f1cca6a5 100644 --- a/src/pocketmine/event/server/CommandEvent.php +++ b/src/pocketmine/event/server/CommandEvent.php @@ -25,6 +25,7 @@ namespace pocketmine\event\server; use pocketmine\command\CommandSender; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; /** * Called when any CommandSender runs a command, early in the process @@ -35,6 +36,8 @@ use pocketmine\event\Cancellable; * The message DOES NOT contain a slash at the start */ class CommandEvent extends ServerEvent implements Cancellable{ + use CancellableTrait; + /** @var string */ protected $command; diff --git a/src/pocketmine/event/server/DataPacketBroadcastEvent.php b/src/pocketmine/event/server/DataPacketBroadcastEvent.php index 7b818ff377..57f2564c3e 100644 --- a/src/pocketmine/event/server/DataPacketBroadcastEvent.php +++ b/src/pocketmine/event/server/DataPacketBroadcastEvent.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\event\server; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\Player; @@ -31,6 +32,8 @@ use pocketmine\Player; * Called when a list of packets is broadcasted to 1 or more players. */ class DataPacketBroadcastEvent extends ServerEvent implements Cancellable{ + use CancellableTrait; + /** @var Player[] */ private $players; /** @var DataPacket[] */ diff --git a/src/pocketmine/event/server/DataPacketReceiveEvent.php b/src/pocketmine/event/server/DataPacketReceiveEvent.php index 1766c0d7f4..733927f054 100644 --- a/src/pocketmine/event/server/DataPacketReceiveEvent.php +++ b/src/pocketmine/event/server/DataPacketReceiveEvent.php @@ -24,10 +24,13 @@ declare(strict_types=1); namespace pocketmine\event\server; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\Player; class DataPacketReceiveEvent extends ServerEvent implements Cancellable{ + use CancellableTrait; + /** @var DataPacket */ private $packet; /** @var Player */ diff --git a/src/pocketmine/event/server/DataPacketSendEvent.php b/src/pocketmine/event/server/DataPacketSendEvent.php index fbbef6362f..0d2e699343 100644 --- a/src/pocketmine/event/server/DataPacketSendEvent.php +++ b/src/pocketmine/event/server/DataPacketSendEvent.php @@ -24,10 +24,13 @@ declare(strict_types=1); namespace pocketmine\event\server; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\Player; class DataPacketSendEvent extends ServerEvent implements Cancellable{ + use CancellableTrait; + /** @var DataPacket */ private $packet; /** @var Player */ diff --git a/src/pocketmine/event/server/NetworkInterfaceRegisterEvent.php b/src/pocketmine/event/server/NetworkInterfaceRegisterEvent.php index b2dafb82ea..a2ee78af65 100644 --- a/src/pocketmine/event/server/NetworkInterfaceRegisterEvent.php +++ b/src/pocketmine/event/server/NetworkInterfaceRegisterEvent.php @@ -24,10 +24,11 @@ declare(strict_types=1); namespace pocketmine\event\server; use pocketmine\event\Cancellable; +use pocketmine\event\CancellableTrait; /** * Called when a network interface is registered into the network, for example the RakLib interface. */ class NetworkInterfaceRegisterEvent extends NetworkInterfaceEvent implements Cancellable{ - + use CancellableTrait; } From 9c0ebb6350e9f8d0a09459469cfcee6daf241114 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 16 Jan 2019 22:14:40 +0000 Subject: [PATCH 0403/3224] Minor formatting fixes --- src/pocketmine/event/entity/ItemDespawnEvent.php | 1 - src/pocketmine/event/entity/ProjectileLaunchEvent.php | 1 - 2 files changed, 2 deletions(-) diff --git a/src/pocketmine/event/entity/ItemDespawnEvent.php b/src/pocketmine/event/entity/ItemDespawnEvent.php index 2a34ccca4a..628c56cc86 100644 --- a/src/pocketmine/event/entity/ItemDespawnEvent.php +++ b/src/pocketmine/event/entity/ItemDespawnEvent.php @@ -35,7 +35,6 @@ class ItemDespawnEvent extends EntityEvent implements Cancellable{ */ public function __construct(ItemEntity $item){ $this->entity = $item; - } /** diff --git a/src/pocketmine/event/entity/ProjectileLaunchEvent.php b/src/pocketmine/event/entity/ProjectileLaunchEvent.php index b66c5e3d59..f7355131db 100644 --- a/src/pocketmine/event/entity/ProjectileLaunchEvent.php +++ b/src/pocketmine/event/entity/ProjectileLaunchEvent.php @@ -35,7 +35,6 @@ class ProjectileLaunchEvent extends EntityEvent implements Cancellable{ */ public function __construct(Projectile $entity){ $this->entity = $entity; - } /** From b82e00ffdfc5ea22a78bb2075bd7fc6dad02943b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 17 Jan 2019 12:21:56 +0000 Subject: [PATCH 0404/3224] Extract a Packet interface from DataPacket this is in preparation for clientbound/serverbound packet separation. I did this already on another branch, but the changeset was dependent on a massive refactor to split apart packets and binarystream which i'm still not fully happy with. --- src/pocketmine/Player.php | 12 +-- src/pocketmine/Server.php | 10 +-- .../event/server/DataPacketBroadcastEvent.php | 12 +-- .../event/server/DataPacketReceiveEvent.php | 14 ++-- .../event/server/DataPacketSendEvent.php | 14 ++-- src/pocketmine/level/Level.php | 26 +++--- src/pocketmine/level/particle/Particle.php | 4 +- src/pocketmine/level/sound/Sound.php | 4 +- src/pocketmine/network/NetworkInterface.php | 2 +- .../network/mcpe/NetworkSession.php | 12 +-- src/pocketmine/network/mcpe/PacketStream.php | 8 +- .../network/mcpe/protocol/DataPacket.php | 8 +- .../network/mcpe/protocol/Packet.php | 82 +++++++++++++++++++ .../network/mcpe/protocol/PacketPool.php | 14 ++-- src/pocketmine/timings/Timings.php | 24 +++--- 15 files changed, 167 insertions(+), 79 deletions(-) create mode 100644 src/pocketmine/network/mcpe/protocol/Packet.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index b77400b5fd..8ed1746f42 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -103,7 +103,6 @@ use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\network\mcpe\protocol\BookEditPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; -use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; @@ -113,6 +112,7 @@ use pocketmine\network\mcpe\protocol\MobEffectPacket; use pocketmine\network\mcpe\protocol\ModalFormRequestPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\NetworkChunkPublisherUpdatePacket; +use pocketmine\network\mcpe\protocol\Packet; use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket; use pocketmine\network\mcpe\protocol\SetTitlePacket; @@ -2546,12 +2546,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } /** - * @param DataPacket $packet - * @param bool $immediate + * @param Packet $packet + * @param bool $immediate * * @return bool */ - public function sendDataPacket(DataPacket $packet, bool $immediate = false) : bool{ + public function sendDataPacket(Packet $packet, bool $immediate = false) : bool{ if(!$this->isConnected()){ return false; } @@ -2568,11 +2568,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ * @deprecated This is a proxy for sendDataPacket() and will be removed in the next major release. * @see Player::sendDataPacket() * - * @param DataPacket $packet + * @param Packet $packet * * @return bool */ - public function dataPacket(DataPacket $packet) : bool{ + public function dataPacket(Packet $packet) : bool{ return $this->sendDataPacket($packet, false); } diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 14ff8661d5..f79d470a15 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -75,7 +75,7 @@ use pocketmine\network\mcpe\NetworkCipher; use pocketmine\network\mcpe\NetworkCompression; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\PacketStream; -use pocketmine\network\mcpe\protocol\DataPacket; +use pocketmine\network\mcpe\protocol\Packet; use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; @@ -1535,18 +1535,18 @@ class Server{ /** * Broadcasts a Minecraft packet to a list of players * - * @param Player[] $players - * @param DataPacket $packet + * @param Player[] $players + * @param Packet $packet * * @return bool */ - public function broadcastPacket(array $players, DataPacket $packet) : bool{ + public function broadcastPacket(array $players, Packet $packet) : bool{ return $this->broadcastPackets($players, [$packet]); } /** * @param Player[] $players - * @param DataPacket[] $packets + * @param Packet[] $packets * * @return bool */ diff --git a/src/pocketmine/event/server/DataPacketBroadcastEvent.php b/src/pocketmine/event/server/DataPacketBroadcastEvent.php index 57f2564c3e..364b45c552 100644 --- a/src/pocketmine/event/server/DataPacketBroadcastEvent.php +++ b/src/pocketmine/event/server/DataPacketBroadcastEvent.php @@ -25,7 +25,7 @@ namespace pocketmine\event\server; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\network\mcpe\protocol\DataPacket; +use pocketmine\network\mcpe\protocol\Packet; use pocketmine\Player; /** @@ -36,12 +36,12 @@ class DataPacketBroadcastEvent extends ServerEvent implements Cancellable{ /** @var Player[] */ private $players; - /** @var DataPacket[] */ + /** @var Packet[] */ private $packets; /** - * @param Player[] $players - * @param DataPacket[] $packets + * @param Player[] $players + * @param Packet[] $packets */ public function __construct(array $players, array $packets){ $this->players = $players; @@ -63,14 +63,14 @@ class DataPacketBroadcastEvent extends ServerEvent implements Cancellable{ } /** - * @return DataPacket[] + * @return Packet[] */ public function getPackets() : array{ return $this->packets; } /** - * @param DataPacket[] $packets + * @param Packet[] $packets */ public function setPackets(array $packets) : void{ $this->packets = $packets; diff --git a/src/pocketmine/event/server/DataPacketReceiveEvent.php b/src/pocketmine/event/server/DataPacketReceiveEvent.php index 733927f054..8ed8e2de09 100644 --- a/src/pocketmine/event/server/DataPacketReceiveEvent.php +++ b/src/pocketmine/event/server/DataPacketReceiveEvent.php @@ -25,30 +25,30 @@ namespace pocketmine\event\server; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\network\mcpe\protocol\DataPacket; +use pocketmine\network\mcpe\protocol\Packet; use pocketmine\Player; class DataPacketReceiveEvent extends ServerEvent implements Cancellable{ use CancellableTrait; - /** @var DataPacket */ + /** @var Packet */ private $packet; /** @var Player */ private $player; /** - * @param Player $player - * @param DataPacket $packet + * @param Player $player + * @param Packet $packet */ - public function __construct(Player $player, DataPacket $packet){ + public function __construct(Player $player, Packet $packet){ $this->packet = $packet; $this->player = $player; } /** - * @return DataPacket + * @return Packet */ - public function getPacket() : DataPacket{ + public function getPacket() : Packet{ return $this->packet; } diff --git a/src/pocketmine/event/server/DataPacketSendEvent.php b/src/pocketmine/event/server/DataPacketSendEvent.php index 0d2e699343..32c8399006 100644 --- a/src/pocketmine/event/server/DataPacketSendEvent.php +++ b/src/pocketmine/event/server/DataPacketSendEvent.php @@ -25,30 +25,30 @@ namespace pocketmine\event\server; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\network\mcpe\protocol\DataPacket; +use pocketmine\network\mcpe\protocol\Packet; use pocketmine\Player; class DataPacketSendEvent extends ServerEvent implements Cancellable{ use CancellableTrait; - /** @var DataPacket */ + /** @var Packet */ private $packet; /** @var Player */ private $player; /** - * @param Player $player - * @param DataPacket $packet + * @param Player $player + * @param Packet $packet */ - public function __construct(Player $player, DataPacket $packet){ + public function __construct(Player $player, Packet $packet){ $this->packet = $packet; $this->player = $player; } /** - * @return DataPacket + * @return Packet */ - public function getPacket() : DataPacket{ + public function getPacket() : Packet{ return $this->packet; } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 9490a2d0b5..94ba6eb213 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -73,9 +73,9 @@ use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\ChunkRequestTask; use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\protocol\AddEntityPacket; -use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\Packet; use pocketmine\network\mcpe\protocol\SetDifficultyPacket; use pocketmine\network\mcpe\protocol\SetTimePacket; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; @@ -180,9 +180,9 @@ class Level implements ChunkManager, Metadatable{ /** @var Player[][] */ private $playerLoaders = []; - /** @var DataPacket[][] */ + /** @var Packet[][] */ private $chunkPackets = []; - /** @var DataPacket[] */ + /** @var Packet[] */ private $globalPackets = []; /** @var float[] */ @@ -595,14 +595,14 @@ class Level implements ChunkManager, Metadatable{ } /** - * Queues a DataPacket to be sent to all players using the chunk at the specified X/Z coordinates at the end of the + * Queues a packet to be sent to all players using the chunk at the specified X/Z coordinates at the end of the * current tick. * - * @param int $chunkX - * @param int $chunkZ - * @param DataPacket $packet + * @param int $chunkX + * @param int $chunkZ + * @param Packet $packet */ - public function addChunkPacket(int $chunkX, int $chunkZ, DataPacket $packet){ + public function addChunkPacket(int $chunkX, int $chunkZ, Packet $packet){ if(!isset($this->chunkPackets[$index = Level::chunkHash($chunkX, $chunkZ)])){ $this->chunkPackets[$index] = [$packet]; }else{ @@ -613,19 +613,19 @@ class Level implements ChunkManager, Metadatable{ /** * Broadcasts a packet to every player who has the target position within their view distance. * - * @param Vector3 $pos - * @param DataPacket $packet + * @param Vector3 $pos + * @param Packet $packet */ - public function broadcastPacketToViewers(Vector3 $pos, DataPacket $packet) : void{ + public function broadcastPacketToViewers(Vector3 $pos, Packet $packet) : void{ $this->addChunkPacket($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4, $packet); } /** * Broadcasts a packet to every player in the level. * - * @param DataPacket $packet + * @param Packet $packet */ - public function broadcastGlobalPacket(DataPacket $packet) : void{ + public function broadcastGlobalPacket(Packet $packet) : void{ $this->globalPackets[] = $packet; } diff --git a/src/pocketmine/level/particle/Particle.php b/src/pocketmine/level/particle/Particle.php index b48fff7431..cef6dbcc8a 100644 --- a/src/pocketmine/level/particle/Particle.php +++ b/src/pocketmine/level/particle/Particle.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\level\particle; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\DataPacket; +use pocketmine\network\mcpe\protocol\Packet; abstract class Particle{ @@ -86,7 +86,7 @@ abstract class Particle{ /** * @param Vector3 $pos * - * @return DataPacket|DataPacket[] + * @return Packet|Packet[] */ abstract public function encode(Vector3 $pos); diff --git a/src/pocketmine/level/sound/Sound.php b/src/pocketmine/level/sound/Sound.php index 0c488d14bb..8cf77770d1 100644 --- a/src/pocketmine/level/sound/Sound.php +++ b/src/pocketmine/level/sound/Sound.php @@ -24,14 +24,14 @@ declare(strict_types=1); namespace pocketmine\level\sound; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\DataPacket; +use pocketmine\network\mcpe\protocol\Packet; abstract class Sound{ /** * @param Vector3 $pos * - * @return DataPacket|DataPacket[] + * @return Packet|Packet[] */ abstract public function encode(Vector3 $pos); diff --git a/src/pocketmine/network/NetworkInterface.php b/src/pocketmine/network/NetworkInterface.php index da64d6f572..8ef8484637 100644 --- a/src/pocketmine/network/NetworkInterface.php +++ b/src/pocketmine/network/NetworkInterface.php @@ -39,7 +39,7 @@ interface NetworkInterface{ public function start() : void; /** - * Sends a DataPacket to the interface, returns an unique identifier for the packet if $needACK is true + * Sends a packet to the interface, returns an unique identifier for the packet if $needACK is true * * @param NetworkSession $session * @param string $payload diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index c6f7a02949..f91e327e25 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -34,8 +34,8 @@ use pocketmine\network\mcpe\handler\PreSpawnSessionHandler; use pocketmine\network\mcpe\handler\ResourcePacksSessionHandler; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\handler\SimpleSessionHandler; -use pocketmine\network\mcpe\protocol\DataPacket; use pocketmine\network\mcpe\protocol\DisconnectPacket; +use pocketmine\network\mcpe\protocol\Packet; use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\network\mcpe\protocol\PlayStatusPacket; use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket; @@ -209,11 +209,11 @@ class NetworkSession{ } /** - * @param DataPacket $packet + * @param Packet $packet * * @throws BadPacketException */ - public function handleDataPacket(DataPacket $packet) : void{ + public function handleDataPacket(Packet $packet) : void{ $timings = Timings::getReceiveDataPacketTimings($packet); $timings->startTiming(); @@ -237,7 +237,7 @@ class NetworkSession{ $timings->stopTiming(); } - public function sendDataPacket(DataPacket $packet, bool $immediate = false) : bool{ + public function sendDataPacket(Packet $packet, bool $immediate = false) : bool{ $timings = Timings::getSendDataPacketTimings($packet); $timings->startTiming(); try{ @@ -260,9 +260,9 @@ class NetworkSession{ /** * @internal - * @param DataPacket $packet + * @param Packet $packet */ - public function addToSendBuffer(DataPacket $packet) : void{ + public function addToSendBuffer(Packet $packet) : void{ $timings = Timings::getSendDataPacketTimings($packet); $timings->startTiming(); try{ diff --git a/src/pocketmine/network/mcpe/PacketStream.php b/src/pocketmine/network/mcpe/PacketStream.php index f22dc6e200..dd79f9704b 100644 --- a/src/pocketmine/network/mcpe/PacketStream.php +++ b/src/pocketmine/network/mcpe/PacketStream.php @@ -23,19 +23,19 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; -use pocketmine\network\mcpe\protocol\DataPacket; +use pocketmine\network\mcpe\protocol\Packet; use pocketmine\network\mcpe\protocol\PacketPool; class PacketStream extends NetworkBinaryStream{ - public function putPacket(DataPacket $packet) : void{ - if(!$packet->isEncoded){ + public function putPacket(Packet $packet) : void{ + if(!$packet->isEncoded()){ $packet->encode(); } $this->putString($packet->getBuffer()); } - public function getPacket() : DataPacket{ + public function getPacket() : Packet{ return PacketPool::getPacket($this->getString()); } } diff --git a/src/pocketmine/network/mcpe/protocol/DataPacket.php b/src/pocketmine/network/mcpe/protocol/DataPacket.php index a93833ab98..3d683ee990 100644 --- a/src/pocketmine/network/mcpe/protocol/DataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/DataPacket.php @@ -36,12 +36,12 @@ use function is_object; use function is_string; use function method_exists; -abstract class DataPacket extends NetworkBinaryStream{ +abstract class DataPacket extends NetworkBinaryStream implements Packet{ public const NETWORK_ID = 0; /** @var bool */ - public $isEncoded = false; + private $isEncoded = false; /** @var int */ public $senderSubId = 0; @@ -108,6 +108,10 @@ abstract class DataPacket extends NetworkBinaryStream{ $this->isEncoded = true; } + final public function isEncoded() : bool{ + return $this->isEncoded; + } + protected function encodeHeader() : void{ $this->putUnsignedVarInt(static::NETWORK_ID); } diff --git a/src/pocketmine/network/mcpe/protocol/Packet.php b/src/pocketmine/network/mcpe/protocol/Packet.php new file mode 100644 index 0000000000..959103fbca --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/Packet.php @@ -0,0 +1,82 @@ + */ + /** @var \SplFixedArray */ protected static $pool = null; public static function init() : void{ @@ -158,28 +158,28 @@ class PacketPool{ } /** - * @param DataPacket $packet + * @param Packet $packet */ - public static function registerPacket(DataPacket $packet) : void{ + public static function registerPacket(Packet $packet) : void{ static::$pool[$packet->pid()] = clone $packet; } /** * @param int $pid * - * @return DataPacket + * @return Packet */ - public static function getPacketById(int $pid) : DataPacket{ + public static function getPacketById(int $pid) : Packet{ return isset(static::$pool[$pid]) ? clone static::$pool[$pid] : new UnknownPacket(); } /** * @param string $buffer * - * @return DataPacket + * @return Packet * @throws BadPacketException */ - public static function getPacket(string $buffer) : DataPacket{ + public static function getPacket(string $buffer) : Packet{ $offset = 0; try{ $pk = static::getPacketById(Binary::readUnsignedVarInt($buffer, $offset)); diff --git a/src/pocketmine/timings/Timings.php b/src/pocketmine/timings/Timings.php index 928751ebeb..8a6185c4ab 100644 --- a/src/pocketmine/timings/Timings.php +++ b/src/pocketmine/timings/Timings.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\timings; use pocketmine\entity\Entity; -use pocketmine\network\mcpe\protocol\DataPacket; +use pocketmine\network\mcpe\protocol\Packet; use pocketmine\Player; use pocketmine\scheduler\TaskHandler; use pocketmine\tile\Tile; @@ -212,31 +212,33 @@ abstract class Timings{ } /** - * @param DataPacket $pk + * @param Packet $pk * * @return TimingsHandler */ - public static function getReceiveDataPacketTimings(DataPacket $pk) : TimingsHandler{ - if(!isset(self::$packetReceiveTimingMap[$pk::NETWORK_ID])){ + public static function getReceiveDataPacketTimings(Packet $pk) : TimingsHandler{ + $pid = $pk->pid(); + if(!isset(self::$packetReceiveTimingMap[$pid])){ $pkName = (new \ReflectionClass($pk))->getShortName(); - self::$packetReceiveTimingMap[$pk::NETWORK_ID] = new TimingsHandler("** receivePacket - " . $pkName . " [0x" . dechex($pk::NETWORK_ID) . "]", self::$playerNetworkReceiveTimer); + self::$packetReceiveTimingMap[$pid] = new TimingsHandler("** receivePacket - " . $pkName . " [0x" . dechex($pid) . "]", self::$playerNetworkReceiveTimer); } - return self::$packetReceiveTimingMap[$pk::NETWORK_ID]; + return self::$packetReceiveTimingMap[$pid]; } /** - * @param DataPacket $pk + * @param Packet $pk * * @return TimingsHandler */ - public static function getSendDataPacketTimings(DataPacket $pk) : TimingsHandler{ - if(!isset(self::$packetSendTimingMap[$pk::NETWORK_ID])){ + public static function getSendDataPacketTimings(Packet $pk) : TimingsHandler{ + $pid = $pk->pid(); + if(!isset(self::$packetSendTimingMap[$pid])){ $pkName = (new \ReflectionClass($pk))->getShortName(); - self::$packetSendTimingMap[$pk::NETWORK_ID] = new TimingsHandler("** sendPacket - " . $pkName . " [0x" . dechex($pk::NETWORK_ID) . "]", self::$playerNetworkSendTimer); + self::$packetSendTimingMap[$pid] = new TimingsHandler("** sendPacket - " . $pkName . " [0x" . dechex($pid) . "]", self::$playerNetworkSendTimer); } - return self::$packetSendTimingMap[$pk::NETWORK_ID]; + return self::$packetSendTimingMap[$pid]; } } From 76f1ee18274c9fbe20b04eb944ee307f0af532d8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 4 Jan 2019 03:19:47 +0000 Subject: [PATCH 0405/3224] Add restrictions on packet send directions with interfaces This prevents plugins sending wrong packets at the compiler level (or would, if we had a compiler). It's more robust than a getter for client/server and throwing an exception since a static analysis tool can detect faults created by sending wrong packets from the server. This is also used to deny service to dodgy clients which send wrong packets to the server to attack it. --- src/pocketmine/Player.php | 12 ++++---- src/pocketmine/Server.php | 12 ++++---- .../event/server/DataPacketBroadcastEvent.php | 12 ++++---- .../event/server/DataPacketReceiveEvent.php | 14 +++++----- .../event/server/DataPacketSendEvent.php | 14 +++++----- src/pocketmine/level/Level.php | 24 ++++++++-------- src/pocketmine/level/particle/Particle.php | 4 +-- src/pocketmine/level/sound/Sound.php | 4 +-- .../network/mcpe/NetworkSession.php | 12 ++++++-- .../mcpe/protocol/AddBehaviorTreePacket.php | 2 +- .../network/mcpe/protocol/AddEntityPacket.php | 2 +- .../mcpe/protocol/AddHangingEntityPacket.php | 2 +- .../mcpe/protocol/AddItemEntityPacket.php | 2 +- .../network/mcpe/protocol/AddPlayerPacket.php | 2 +- .../mcpe/protocol/AdventureSettingsPacket.php | 2 +- .../network/mcpe/protocol/AnimatePacket.php | 2 +- .../mcpe/protocol/AvailableCommandsPacket.php | 2 +- .../AvailableEntityIdentifiersPacket.php | 2 +- .../protocol/BiomeDefinitionListPacket.php | 2 +- .../mcpe/protocol/BlockEntityDataPacket.php | 2 +- .../mcpe/protocol/BlockEventPacket.php | 2 +- .../mcpe/protocol/BlockPickRequestPacket.php | 2 +- .../network/mcpe/protocol/BookEditPacket.php | 2 +- .../network/mcpe/protocol/BossEventPacket.php | 2 +- .../network/mcpe/protocol/CameraPacket.php | 2 +- .../mcpe/protocol/ChangeDimensionPacket.php | 2 +- .../protocol/ChunkRadiusUpdatedPacket.php | 2 +- .../ClientToServerHandshakePacket.php | 2 +- .../protocol/ClientboundMapItemDataPacket.php | 2 +- .../mcpe/protocol/ClientboundPacket.php | 28 +++++++++++++++++++ .../protocol/CommandBlockUpdatePacket.php | 2 +- .../mcpe/protocol/CommandOutputPacket.php | 2 +- .../mcpe/protocol/CommandRequestPacket.php | 2 +- .../mcpe/protocol/ContainerClosePacket.php | 2 +- .../mcpe/protocol/ContainerOpenPacket.php | 2 +- .../mcpe/protocol/ContainerSetDataPacket.php | 2 +- .../mcpe/protocol/CraftingDataPacket.php | 2 +- .../mcpe/protocol/CraftingEventPacket.php | 2 +- .../mcpe/protocol/DisconnectPacket.php | 2 +- .../mcpe/protocol/EntityEventPacket.php | 2 +- .../mcpe/protocol/EntityFallPacket.php | 2 +- .../mcpe/protocol/EntityPickRequestPacket.php | 2 +- .../network/mcpe/protocol/EventPacket.php | 2 +- .../network/mcpe/protocol/ExplodePacket.php | 2 +- .../mcpe/protocol/FullChunkDataPacket.php | 2 +- .../mcpe/protocol/GameRulesChangedPacket.php | 2 +- .../mcpe/protocol/GuiDataPickItemPacket.php | 2 +- .../network/mcpe/protocol/HurtArmorPacket.php | 2 +- .../network/mcpe/protocol/InteractPacket.php | 2 +- .../mcpe/protocol/InventoryContentPacket.php | 2 +- .../mcpe/protocol/InventorySlotPacket.php | 2 +- .../protocol/InventoryTransactionPacket.php | 2 +- .../mcpe/protocol/ItemFrameDropItemPacket.php | 2 +- .../network/mcpe/protocol/LabTablePacket.php | 2 +- .../mcpe/protocol/LevelEventPacket.php | 2 +- .../mcpe/protocol/LevelSoundEventPacket.php | 2 +- .../network/mcpe/protocol/LoginPacket.php | 2 +- .../mcpe/protocol/MapInfoRequestPacket.php | 2 +- .../mcpe/protocol/MobArmorEquipmentPacket.php | 2 +- .../network/mcpe/protocol/MobEffectPacket.php | 2 +- .../mcpe/protocol/MobEquipmentPacket.php | 2 +- .../mcpe/protocol/ModalFormRequestPacket.php | 2 +- .../mcpe/protocol/ModalFormResponsePacket.php | 2 +- .../protocol/MoveEntityAbsolutePacket.php | 2 +- .../mcpe/protocol/MoveEntityDeltaPacket.php | 2 +- .../mcpe/protocol/MovePlayerPacket.php | 2 +- .../NetworkChunkPublisherUpdatePacket.php | 2 +- .../protocol/NetworkStackLatencyPacket.php | 2 +- .../mcpe/protocol/NpcRequestPacket.php | 2 +- .../mcpe/protocol/PhotoTransferPacket.php | 2 +- .../network/mcpe/protocol/PlaySoundPacket.php | 2 +- .../mcpe/protocol/PlayStatusPacket.php | 2 +- .../mcpe/protocol/PlayerActionPacket.php | 2 +- .../mcpe/protocol/PlayerHotbarPacket.php | 2 +- .../mcpe/protocol/PlayerInputPacket.php | 2 +- .../mcpe/protocol/PlayerListPacket.php | 2 +- .../mcpe/protocol/PlayerSkinPacket.php | 2 +- .../mcpe/protocol/PurchaseReceiptPacket.php | 2 +- .../mcpe/protocol/RemoveEntityPacket.php | 2 +- .../mcpe/protocol/RemoveObjectivePacket.php | 2 +- .../protocol/RequestChunkRadiusPacket.php | 2 +- .../protocol/ResourcePackChunkDataPacket.php | 2 +- .../ResourcePackChunkRequestPacket.php | 2 +- .../ResourcePackClientResponsePacket.php | 2 +- .../protocol/ResourcePackDataInfoPacket.php | 2 +- .../mcpe/protocol/ResourcePackStackPacket.php | 2 +- .../mcpe/protocol/ResourcePacksInfoPacket.php | 2 +- .../network/mcpe/protocol/RespawnPacket.php | 2 +- .../network/mcpe/protocol/RiderJumpPacket.php | 2 +- .../mcpe/protocol/ScriptCustomEventPacket.php | 2 +- .../protocol/ServerSettingsRequestPacket.php | 2 +- .../protocol/ServerSettingsResponsePacket.php | 2 +- .../ServerToClientHandshakePacket.php | 2 +- .../mcpe/protocol/ServerboundPacket.php | 28 +++++++++++++++++++ .../protocol/SetCommandsEnabledPacket.php | 2 +- .../protocol/SetDefaultGameTypePacket.php | 2 +- .../mcpe/protocol/SetDifficultyPacket.php | 2 +- .../protocol/SetDisplayObjectivePacket.php | 2 +- .../mcpe/protocol/SetEntityDataPacket.php | 2 +- .../mcpe/protocol/SetEntityLinkPacket.php | 2 +- .../mcpe/protocol/SetEntityMotionPacket.php | 2 +- .../network/mcpe/protocol/SetHealthPacket.php | 2 +- .../mcpe/protocol/SetLastHurtByPacket.php | 2 +- .../SetLocalPlayerAsInitializedPacket.php | 2 +- .../mcpe/protocol/SetPlayerGameTypePacket.php | 2 +- .../network/mcpe/protocol/SetScorePacket.php | 2 +- .../protocol/SetScoreboardIdentityPacket.php | 2 +- .../mcpe/protocol/SetSpawnPositionPacket.php | 2 +- .../network/mcpe/protocol/SetTimePacket.php | 2 +- .../network/mcpe/protocol/SetTitlePacket.php | 2 +- .../mcpe/protocol/ShowCreditsPacket.php | 2 +- .../mcpe/protocol/ShowProfilePacket.php | 2 +- .../mcpe/protocol/ShowStoreOfferPacket.php | 2 +- .../mcpe/protocol/SimpleEventPacket.php | 2 +- .../protocol/SpawnExperienceOrbPacket.php | 2 +- .../protocol/SpawnParticleEffectPacket.php | 2 +- .../network/mcpe/protocol/StartGamePacket.php | 2 +- .../network/mcpe/protocol/StopSoundPacket.php | 2 +- .../protocol/StructureBlockUpdatePacket.php | 2 +- .../mcpe/protocol/SubClientLoginPacket.php | 2 +- .../mcpe/protocol/TakeItemEntityPacket.php | 2 +- .../network/mcpe/protocol/TextPacket.php | 2 +- .../network/mcpe/protocol/TransferPacket.php | 2 +- .../mcpe/protocol/UpdateAttributesPacket.php | 2 +- .../mcpe/protocol/UpdateBlockPacket.php | 2 +- .../mcpe/protocol/UpdateEquipPacket.php | 2 +- .../mcpe/protocol/UpdateSoftEnumPacket.php | 2 +- .../mcpe/protocol/UpdateTradePacket.php | 2 +- .../network/mcpe/protocol/WSConnectPacket.php | 2 +- src/pocketmine/timings/Timings.php | 11 ++++---- 130 files changed, 237 insertions(+), 174 deletions(-) create mode 100644 src/pocketmine/network/mcpe/protocol/ClientboundPacket.php create mode 100644 src/pocketmine/network/mcpe/protocol/ServerboundPacket.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 8ed1746f42..4d4915ba26 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -103,6 +103,7 @@ use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\network\mcpe\protocol\BookEditPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; +use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; @@ -112,7 +113,6 @@ use pocketmine\network\mcpe\protocol\MobEffectPacket; use pocketmine\network\mcpe\protocol\ModalFormRequestPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\NetworkChunkPublisherUpdatePacket; -use pocketmine\network\mcpe\protocol\Packet; use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket; use pocketmine\network\mcpe\protocol\SetTitlePacket; @@ -2546,12 +2546,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } /** - * @param Packet $packet - * @param bool $immediate + * @param ClientboundPacket $packet + * @param bool $immediate * * @return bool */ - public function sendDataPacket(Packet $packet, bool $immediate = false) : bool{ + public function sendDataPacket(ClientboundPacket $packet, bool $immediate = false) : bool{ if(!$this->isConnected()){ return false; } @@ -2568,11 +2568,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ * @deprecated This is a proxy for sendDataPacket() and will be removed in the next major release. * @see Player::sendDataPacket() * - * @param Packet $packet + * @param ClientboundPacket $packet * * @return bool */ - public function dataPacket(Packet $packet) : bool{ + public function dataPacket(ClientboundPacket $packet) : bool{ return $this->sendDataPacket($packet, false); } diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index f79d470a15..b838ff9068 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -75,7 +75,7 @@ use pocketmine\network\mcpe\NetworkCipher; use pocketmine\network\mcpe\NetworkCompression; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\PacketStream; -use pocketmine\network\mcpe\protocol\Packet; +use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; @@ -1535,18 +1535,18 @@ class Server{ /** * Broadcasts a Minecraft packet to a list of players * - * @param Player[] $players - * @param Packet $packet + * @param Player[] $players + * @param ClientboundPacket $packet * * @return bool */ - public function broadcastPacket(array $players, Packet $packet) : bool{ + public function broadcastPacket(array $players, ClientboundPacket $packet) : bool{ return $this->broadcastPackets($players, [$packet]); } /** - * @param Player[] $players - * @param Packet[] $packets + * @param Player[] $players + * @param ClientboundPacket[] $packets * * @return bool */ diff --git a/src/pocketmine/event/server/DataPacketBroadcastEvent.php b/src/pocketmine/event/server/DataPacketBroadcastEvent.php index 364b45c552..d42d6ea3f9 100644 --- a/src/pocketmine/event/server/DataPacketBroadcastEvent.php +++ b/src/pocketmine/event/server/DataPacketBroadcastEvent.php @@ -25,7 +25,7 @@ namespace pocketmine\event\server; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\network\mcpe\protocol\Packet; +use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\Player; /** @@ -36,12 +36,12 @@ class DataPacketBroadcastEvent extends ServerEvent implements Cancellable{ /** @var Player[] */ private $players; - /** @var Packet[] */ + /** @var ClientboundPacket[] */ private $packets; /** - * @param Player[] $players - * @param Packet[] $packets + * @param Player[] $players + * @param ClientboundPacket[] $packets */ public function __construct(array $players, array $packets){ $this->players = $players; @@ -63,14 +63,14 @@ class DataPacketBroadcastEvent extends ServerEvent implements Cancellable{ } /** - * @return Packet[] + * @return ClientboundPacket[] */ public function getPackets() : array{ return $this->packets; } /** - * @param Packet[] $packets + * @param ClientboundPacket[] $packets */ public function setPackets(array $packets) : void{ $this->packets = $packets; diff --git a/src/pocketmine/event/server/DataPacketReceiveEvent.php b/src/pocketmine/event/server/DataPacketReceiveEvent.php index 8ed8e2de09..946cd7ee90 100644 --- a/src/pocketmine/event/server/DataPacketReceiveEvent.php +++ b/src/pocketmine/event/server/DataPacketReceiveEvent.php @@ -25,30 +25,30 @@ namespace pocketmine\event\server; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\network\mcpe\protocol\Packet; +use pocketmine\network\mcpe\protocol\ServerboundPacket; use pocketmine\Player; class DataPacketReceiveEvent extends ServerEvent implements Cancellable{ use CancellableTrait; - /** @var Packet */ + /** @var ServerboundPacket */ private $packet; /** @var Player */ private $player; /** - * @param Player $player - * @param Packet $packet + * @param Player $player + * @param ServerboundPacket $packet */ - public function __construct(Player $player, Packet $packet){ + public function __construct(Player $player, ServerboundPacket $packet){ $this->packet = $packet; $this->player = $player; } /** - * @return Packet + * @return ServerboundPacket */ - public function getPacket() : Packet{ + public function getPacket() : ServerboundPacket{ return $this->packet; } diff --git a/src/pocketmine/event/server/DataPacketSendEvent.php b/src/pocketmine/event/server/DataPacketSendEvent.php index 32c8399006..c14b16037e 100644 --- a/src/pocketmine/event/server/DataPacketSendEvent.php +++ b/src/pocketmine/event/server/DataPacketSendEvent.php @@ -25,30 +25,30 @@ namespace pocketmine\event\server; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\network\mcpe\protocol\Packet; +use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\Player; class DataPacketSendEvent extends ServerEvent implements Cancellable{ use CancellableTrait; - /** @var Packet */ + /** @var ClientboundPacket */ private $packet; /** @var Player */ private $player; /** - * @param Player $player - * @param Packet $packet + * @param Player $player + * @param ClientboundPacket $packet */ - public function __construct(Player $player, Packet $packet){ + public function __construct(Player $player, ClientboundPacket $packet){ $this->packet = $packet; $this->player = $player; } /** - * @return Packet + * @return ClientboundPacket */ - public function getPacket() : Packet{ + public function getPacket() : ClientboundPacket{ return $this->packet; } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 94ba6eb213..47d9dd04ae 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -73,9 +73,9 @@ use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\ChunkRequestTask; use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\protocol\AddEntityPacket; +use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; -use pocketmine\network\mcpe\protocol\Packet; use pocketmine\network\mcpe\protocol\SetDifficultyPacket; use pocketmine\network\mcpe\protocol\SetTimePacket; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; @@ -180,9 +180,9 @@ class Level implements ChunkManager, Metadatable{ /** @var Player[][] */ private $playerLoaders = []; - /** @var Packet[][] */ + /** @var ClientboundPacket[][] */ private $chunkPackets = []; - /** @var Packet[] */ + /** @var ClientboundPacket[] */ private $globalPackets = []; /** @var float[] */ @@ -598,11 +598,11 @@ class Level implements ChunkManager, Metadatable{ * Queues a packet to be sent to all players using the chunk at the specified X/Z coordinates at the end of the * current tick. * - * @param int $chunkX - * @param int $chunkZ - * @param Packet $packet + * @param int $chunkX + * @param int $chunkZ + * @param ClientboundPacket $packet */ - public function addChunkPacket(int $chunkX, int $chunkZ, Packet $packet){ + public function addChunkPacket(int $chunkX, int $chunkZ, ClientboundPacket $packet){ if(!isset($this->chunkPackets[$index = Level::chunkHash($chunkX, $chunkZ)])){ $this->chunkPackets[$index] = [$packet]; }else{ @@ -613,19 +613,19 @@ class Level implements ChunkManager, Metadatable{ /** * Broadcasts a packet to every player who has the target position within their view distance. * - * @param Vector3 $pos - * @param Packet $packet + * @param Vector3 $pos + * @param ClientboundPacket $packet */ - public function broadcastPacketToViewers(Vector3 $pos, Packet $packet) : void{ + public function broadcastPacketToViewers(Vector3 $pos, ClientboundPacket $packet) : void{ $this->addChunkPacket($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4, $packet); } /** * Broadcasts a packet to every player in the level. * - * @param Packet $packet + * @param ClientboundPacket $packet */ - public function broadcastGlobalPacket(Packet $packet) : void{ + public function broadcastGlobalPacket(ClientboundPacket $packet) : void{ $this->globalPackets[] = $packet; } diff --git a/src/pocketmine/level/particle/Particle.php b/src/pocketmine/level/particle/Particle.php index cef6dbcc8a..ccf97d35bf 100644 --- a/src/pocketmine/level/particle/Particle.php +++ b/src/pocketmine/level/particle/Particle.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\level\particle; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\Packet; +use pocketmine\network\mcpe\protocol\ClientboundPacket; abstract class Particle{ @@ -86,7 +86,7 @@ abstract class Particle{ /** * @param Vector3 $pos * - * @return Packet|Packet[] + * @return ClientboundPacket|ClientboundPacket[] */ abstract public function encode(Vector3 $pos); diff --git a/src/pocketmine/level/sound/Sound.php b/src/pocketmine/level/sound/Sound.php index 8cf77770d1..20b7533ae3 100644 --- a/src/pocketmine/level/sound/Sound.php +++ b/src/pocketmine/level/sound/Sound.php @@ -24,14 +24,14 @@ declare(strict_types=1); namespace pocketmine\level\sound; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\Packet; +use pocketmine\network\mcpe\protocol\ClientboundPacket; abstract class Sound{ /** * @param Vector3 $pos * - * @return Packet|Packet[] + * @return ClientboundPacket|ClientboundPacket[] */ abstract public function encode(Vector3 $pos); diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index f91e327e25..0d4a9e4046 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -34,10 +34,12 @@ use pocketmine\network\mcpe\handler\PreSpawnSessionHandler; use pocketmine\network\mcpe\handler\ResourcePacksSessionHandler; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\handler\SimpleSessionHandler; +use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\DisconnectPacket; use pocketmine\network\mcpe\protocol\Packet; use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\network\mcpe\protocol\PlayStatusPacket; +use pocketmine\network\mcpe\protocol\ServerboundPacket; use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket; use pocketmine\network\NetworkInterface; use pocketmine\Player; @@ -214,6 +216,10 @@ class NetworkSession{ * @throws BadPacketException */ public function handleDataPacket(Packet $packet) : void{ + if(!($packet instanceof ServerboundPacket)){ + throw new BadPacketException("Unexpected non-serverbound packet " . $packet->getName()); + } + $timings = Timings::getReceiveDataPacketTimings($packet); $timings->startTiming(); @@ -237,7 +243,7 @@ class NetworkSession{ $timings->stopTiming(); } - public function sendDataPacket(Packet $packet, bool $immediate = false) : bool{ + public function sendDataPacket(ClientboundPacket $packet, bool $immediate = false) : bool{ $timings = Timings::getSendDataPacketTimings($packet); $timings->startTiming(); try{ @@ -260,9 +266,9 @@ class NetworkSession{ /** * @internal - * @param Packet $packet + * @param ClientboundPacket $packet */ - public function addToSendBuffer(Packet $packet) : void{ + public function addToSendBuffer(ClientboundPacket $packet) : void{ $timings = Timings::getSendDataPacketTimings($packet); $timings->startTiming(); try{ diff --git a/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php b/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php index 8472b1b450..863880befa 100644 --- a/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\SessionHandler; -class AddBehaviorTreePacket extends DataPacket{ +class AddBehaviorTreePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_BEHAVIOR_TREE_PACKET; /** @var string */ diff --git a/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php b/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php index 6a417a5871..56b95fcb23 100644 --- a/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php @@ -34,7 +34,7 @@ use pocketmine\network\mcpe\protocol\types\EntityLink; use function array_search; use function count; -class AddEntityPacket extends DataPacket{ +class AddEntityPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_ENTITY_PACKET; /* diff --git a/src/pocketmine/network/mcpe/protocol/AddHangingEntityPacket.php b/src/pocketmine/network/mcpe/protocol/AddHangingEntityPacket.php index 032de9f55d..07f575ace2 100644 --- a/src/pocketmine/network/mcpe/protocol/AddHangingEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddHangingEntityPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\SessionHandler; -class AddHangingEntityPacket extends DataPacket{ +class AddHangingEntityPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_HANGING_ENTITY_PACKET; /** @var int|null */ diff --git a/src/pocketmine/network/mcpe/protocol/AddItemEntityPacket.php b/src/pocketmine/network/mcpe/protocol/AddItemEntityPacket.php index ff1a32dbd1..9ee9a2d10f 100644 --- a/src/pocketmine/network/mcpe/protocol/AddItemEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddItemEntityPacket.php @@ -29,7 +29,7 @@ use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\SessionHandler; -class AddItemEntityPacket extends DataPacket{ +class AddItemEntityPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_ITEM_ENTITY_PACKET; /** @var int|null */ diff --git a/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php b/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php index cb80125c7c..693009353f 100644 --- a/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php @@ -32,7 +32,7 @@ use pocketmine\network\mcpe\protocol\types\EntityLink; use pocketmine\utils\UUID; use function count; -class AddPlayerPacket extends DataPacket{ +class AddPlayerPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_PLAYER_PACKET; /** @var UUID */ diff --git a/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php b/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php index b98739fde7..43eaa4e9f5 100644 --- a/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php @@ -29,7 +29,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; -class AdventureSettingsPacket extends DataPacket{ +class AdventureSettingsPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ADVENTURE_SETTINGS_PACKET; public const PERMISSION_NORMAL = 0; diff --git a/src/pocketmine/network/mcpe/protocol/AnimatePacket.php b/src/pocketmine/network/mcpe/protocol/AnimatePacket.php index 22ec0ccd05..49f9c59bcd 100644 --- a/src/pocketmine/network/mcpe/protocol/AnimatePacket.php +++ b/src/pocketmine/network/mcpe/protocol/AnimatePacket.php @@ -28,7 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\SessionHandler; -class AnimatePacket extends DataPacket{ +class AnimatePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ANIMATE_PACKET; public const ACTION_SWING_ARM = 1; diff --git a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php index e2458df497..c67601e2f3 100644 --- a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php @@ -39,7 +39,7 @@ use function array_values; use function count; use function dechex; -class AvailableCommandsPacket extends DataPacket{ +class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::AVAILABLE_COMMANDS_PACKET; diff --git a/src/pocketmine/network/mcpe/protocol/AvailableEntityIdentifiersPacket.php b/src/pocketmine/network/mcpe/protocol/AvailableEntityIdentifiersPacket.php index 194094f258..e5ba51e19d 100644 --- a/src/pocketmine/network/mcpe/protocol/AvailableEntityIdentifiersPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AvailableEntityIdentifiersPacket.php @@ -28,7 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\SessionHandler; use function base64_decode; -class AvailableEntityIdentifiersPacket extends DataPacket{ +class AvailableEntityIdentifiersPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::AVAILABLE_ENTITY_IDENTIFIERS_PACKET; /** diff --git a/src/pocketmine/network/mcpe/protocol/BiomeDefinitionListPacket.php b/src/pocketmine/network/mcpe/protocol/BiomeDefinitionListPacket.php index e518a148fa..018afab65b 100644 --- a/src/pocketmine/network/mcpe/protocol/BiomeDefinitionListPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BiomeDefinitionListPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\SessionHandler; -class BiomeDefinitionListPacket extends DataPacket{ +class BiomeDefinitionListPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::BIOME_DEFINITION_LIST_PACKET; /** @var string */ diff --git a/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php b/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php index 6e06e38b2d..663c242270 100644 --- a/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php @@ -28,7 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\SessionHandler; -class BlockEntityDataPacket extends DataPacket{ +class BlockEntityDataPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::BLOCK_ENTITY_DATA_PACKET; /** @var int */ diff --git a/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php b/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php index 462e4d9e59..755b971e21 100644 --- a/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php @@ -28,7 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\SessionHandler; -class BlockEventPacket extends DataPacket{ +class BlockEventPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::BLOCK_EVENT_PACKET; /** @var int */ diff --git a/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php b/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php index 1bc27cef1a..8bd44a7259 100644 --- a/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php @@ -29,7 +29,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\SessionHandler; -class BlockPickRequestPacket extends DataPacket{ +class BlockPickRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::BLOCK_PICK_REQUEST_PACKET; /** @var int */ diff --git a/src/pocketmine/network/mcpe/protocol/BookEditPacket.php b/src/pocketmine/network/mcpe/protocol/BookEditPacket.php index f1b0a0851b..38eed556a9 100644 --- a/src/pocketmine/network/mcpe/protocol/BookEditPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BookEditPacket.php @@ -28,7 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\SessionHandler; -class BookEditPacket extends DataPacket{ +class BookEditPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::BOOK_EDIT_PACKET; public const TYPE_REPLACE_PAGE = 0; diff --git a/src/pocketmine/network/mcpe/protocol/BossEventPacket.php b/src/pocketmine/network/mcpe/protocol/BossEventPacket.php index 89a9be3541..4a3c50eab1 100644 --- a/src/pocketmine/network/mcpe/protocol/BossEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BossEventPacket.php @@ -28,7 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\SessionHandler; -class BossEventPacket extends DataPacket{ +class BossEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::BOSS_EVENT_PACKET; /* S2C: Shows the boss-bar to the player. */ diff --git a/src/pocketmine/network/mcpe/protocol/CameraPacket.php b/src/pocketmine/network/mcpe/protocol/CameraPacket.php index 6e211d5166..ddca6dd15c 100644 --- a/src/pocketmine/network/mcpe/protocol/CameraPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CameraPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\SessionHandler; -class CameraPacket extends DataPacket{ +class CameraPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CAMERA_PACKET; /** @var int */ diff --git a/src/pocketmine/network/mcpe/protocol/ChangeDimensionPacket.php b/src/pocketmine/network/mcpe/protocol/ChangeDimensionPacket.php index 90f4870003..6e13a72967 100644 --- a/src/pocketmine/network/mcpe/protocol/ChangeDimensionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ChangeDimensionPacket.php @@ -29,7 +29,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\SessionHandler; -class ChangeDimensionPacket extends DataPacket{ +class ChangeDimensionPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CHANGE_DIMENSION_PACKET; /** @var int */ diff --git a/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php b/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php index cf6ec6ef88..7fe8c056b7 100644 --- a/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php @@ -28,7 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\SessionHandler; -class ChunkRadiusUpdatedPacket extends DataPacket{ +class ChunkRadiusUpdatedPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CHUNK_RADIUS_UPDATED_PACKET; /** @var int */ diff --git a/src/pocketmine/network/mcpe/protocol/ClientToServerHandshakePacket.php b/src/pocketmine/network/mcpe/protocol/ClientToServerHandshakePacket.php index 0e42af7bb6..e744ff0ff5 100644 --- a/src/pocketmine/network/mcpe/protocol/ClientToServerHandshakePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ClientToServerHandshakePacket.php @@ -28,7 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\SessionHandler; -class ClientToServerHandshakePacket extends DataPacket{ +class ClientToServerHandshakePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::CLIENT_TO_SERVER_HANDSHAKE_PACKET; public function canBeSentBeforeLogin() : bool{ diff --git a/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php b/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php index c068b50ef4..6c716ffaa3 100644 --- a/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php @@ -35,7 +35,7 @@ use pocketmine\utils\Color; use function assert; use function count; -class ClientboundMapItemDataPacket extends DataPacket{ +class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CLIENTBOUND_MAP_ITEM_DATA_PACKET; public const BITFLAG_TEXTURE_UPDATE = 0x02; diff --git a/src/pocketmine/network/mcpe/protocol/ClientboundPacket.php b/src/pocketmine/network/mcpe/protocol/ClientboundPacket.php new file mode 100644 index 0000000000..edd22bf0e9 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/ClientboundPacket.php @@ -0,0 +1,28 @@ +pid(); if(!isset(self::$packetReceiveTimingMap[$pid])){ $pkName = (new \ReflectionClass($pk))->getShortName(); @@ -228,11 +229,11 @@ abstract class Timings{ /** - * @param Packet $pk + * @param ClientboundPacket $pk * * @return TimingsHandler */ - public static function getSendDataPacketTimings(Packet $pk) : TimingsHandler{ + public static function getSendDataPacketTimings(ClientboundPacket $pk) : TimingsHandler{ $pid = $pk->pid(); if(!isset(self::$packetSendTimingMap[$pid])){ $pkName = (new \ReflectionClass($pk))->getShortName(); From e341f3dce233c60a7e5715bc0ec6f857675d4c73 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 17 Jan 2019 16:46:56 +0000 Subject: [PATCH 0406/3224] Level: rename getName() to getDisplayName() --- src/pocketmine/Player.php | 2 +- src/pocketmine/command/defaults/StatusCommand.php | 2 +- src/pocketmine/event/server/QueryRegenerateEvent.php | 2 +- src/pocketmine/level/Level.php | 7 ++++--- src/pocketmine/level/LevelManager.php | 8 ++++---- src/pocketmine/level/Location.php | 2 +- src/pocketmine/level/Position.php | 2 +- src/pocketmine/metadata/BlockMetadataStore.php | 2 +- src/pocketmine/metadata/LevelMetadataStore.php | 2 +- 9 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 4d4915ba26..9bfa1d1a1e 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1869,7 +1869,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->networkSession->getIp(), $this->networkSession->getPort(), $this->id, - $this->level->getName(), + $this->level->getDisplayName(), round($this->x, 4), round($this->y, 4), round($this->z, 4) diff --git a/src/pocketmine/command/defaults/StatusCommand.php b/src/pocketmine/command/defaults/StatusCommand.php index c580fda328..d83f380192 100644 --- a/src/pocketmine/command/defaults/StatusCommand.php +++ b/src/pocketmine/command/defaults/StatusCommand.php @@ -107,7 +107,7 @@ class StatusCommand extends VanillaCommand{ } foreach($server->getLevelManager()->getLevels() as $level){ - $levelName = $level->getFolderName() !== $level->getName() ? " (" . $level->getName() . ")" : ""; + $levelName = $level->getFolderName() !== $level->getDisplayName() ? " (" . $level->getDisplayName() . ")" : ""; $timeColor = ($level->getTickRate() > 1 or $level->getTickRateTime() > 40) ? TextFormat::RED : TextFormat::YELLOW; $tickRate = $level->getTickRate() > 1 ? " (tick rate " . $level->getTickRate() . ")" : ""; $sender->sendMessage(TextFormat::GOLD . "World \"{$level->getFolderName()}\"$levelName: " . diff --git a/src/pocketmine/event/server/QueryRegenerateEvent.php b/src/pocketmine/event/server/QueryRegenerateEvent.php index c54d51166b..a9393a1c6a 100644 --- a/src/pocketmine/event/server/QueryRegenerateEvent.php +++ b/src/pocketmine/event/server/QueryRegenerateEvent.php @@ -89,7 +89,7 @@ class QueryRegenerateEvent extends ServerEvent{ $this->version = $server->getVersion(); $this->server_engine = $server->getName() . " " . $server->getPocketMineVersion(); $level = $server->getLevelManager()->getDefaultLevel(); - $this->map = $level === null ? "unknown" : $level->getName(); + $this->map = $level === null ? "unknown" : $level->getDisplayName(); $this->numPlayers = count($this->players); $this->maxPlayers = $server->getMaxPlayers(); $this->whitelist = $server->hasWhitelist() ? "on" : "off"; diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 47d9dd04ae..aaa14426ee 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -2803,16 +2803,17 @@ class Level implements ChunkManager, Metadatable{ } /** - * Returns the Level name + * Returns the Level display name. + * WARNING: This is NOT guaranteed to be unique. Multiple levels at runtime may share the same display name. * * @return string */ - public function getName() : string{ + public function getDisplayName() : string{ return $this->displayName; } /** - * Returns the Level folder name + * Returns the Level folder name. This will not change at runtime and will be unique to a level per runtime. * * @return string */ diff --git a/src/pocketmine/level/LevelManager.php b/src/pocketmine/level/LevelManager.php index b4f54ece2f..56cb8b6c85 100644 --- a/src/pocketmine/level/LevelManager.php +++ b/src/pocketmine/level/LevelManager.php @@ -179,7 +179,7 @@ class LevelManager{ return false; } - $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.level.unloading", [$level->getName()])); + $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.level.unloading", [$level->getDisplayName()])); foreach($level->getPlayers() as $player){ if($level === $this->levelDefault or $this->levelDefault === null){ $player->close($player->getLeaveMessage(), "Forced default level unload"); @@ -382,14 +382,14 @@ class LevelManager{ if($r > $this->baseTickRate){ $level->tickRateCounter = $level->getTickRate(); } - $this->server->getLogger()->debug("Raising level \"{$level->getName()}\" tick rate to {$level->getTickRate()} ticks"); + $this->server->getLogger()->debug("Raising level \"{$level->getDisplayName()}\" tick rate to {$level->getTickRate()} ticks"); }elseif($tickMs >= 50){ if($level->getTickRate() === $this->baseTickRate){ $level->setTickRate(max($this->baseTickRate + 1, min($this->autoTickRateLimit, (int) floor($tickMs / 50)))); - $this->server->getLogger()->debug(sprintf("Level \"%s\" took %gms, setting tick rate to %d ticks", $level->getName(), (int) round($tickMs, 2), $level->getTickRate())); + $this->server->getLogger()->debug(sprintf("Level \"%s\" took %gms, setting tick rate to %d ticks", $level->getDisplayName(), (int) round($tickMs, 2), $level->getTickRate())); }elseif(($tickMs / $level->getTickRate()) >= 50 and $level->getTickRate() < $this->autoTickRateLimit){ $level->setTickRate($level->getTickRate() + 1); - $this->server->getLogger()->debug(sprintf("Level \"%s\" took %gms, setting tick rate to %d ticks", $level->getName(), (int) round($tickMs, 2), $level->getTickRate())); + $this->server->getLogger()->debug(sprintf("Level \"%s\" took %gms, setting tick rate to %d ticks", $level->getDisplayName(), (int) round($tickMs, 2), $level->getTickRate())); } $level->tickRateCounter = $level->getTickRate(); } diff --git a/src/pocketmine/level/Location.php b/src/pocketmine/level/Location.php index d29f8b26ce..b24d902421 100644 --- a/src/pocketmine/level/Location.php +++ b/src/pocketmine/level/Location.php @@ -76,7 +76,7 @@ class Location extends Position{ } public function __toString(){ - return "Location (level=" . ($this->isValid() ? $this->getLevel()->getName() : "null") . ", x=$this->x, y=$this->y, z=$this->z, yaw=$this->yaw, pitch=$this->pitch)"; + return "Location (level=" . ($this->isValid() ? $this->getLevel()->getDisplayName() : "null") . ", x=$this->x, y=$this->y, z=$this->z, yaw=$this->yaw, pitch=$this->pitch)"; } public function equals(Vector3 $v) : bool{ diff --git a/src/pocketmine/level/Position.php b/src/pocketmine/level/Position.php index 313f24e019..9f3898b097 100644 --- a/src/pocketmine/level/Position.php +++ b/src/pocketmine/level/Position.php @@ -118,7 +118,7 @@ class Position extends Vector3{ } public function __toString(){ - return "Position(level=" . ($this->isValid() ? $this->getLevel()->getName() : "null") . ",x=" . $this->x . ",y=" . $this->y . ",z=" . $this->z . ")"; + return "Position(level=" . ($this->isValid() ? $this->getLevel()->getDisplayName() : "null") . ",x=" . $this->x . ",y=" . $this->y . ",z=" . $this->z . ")"; } public function equals(Vector3 $v) : bool{ diff --git a/src/pocketmine/metadata/BlockMetadataStore.php b/src/pocketmine/metadata/BlockMetadataStore.php index 58adf2e54a..dd16447ba2 100644 --- a/src/pocketmine/metadata/BlockMetadataStore.php +++ b/src/pocketmine/metadata/BlockMetadataStore.php @@ -37,7 +37,7 @@ class BlockMetadataStore extends MetadataStore{ private function disambiguate(Block $block, string $metadataKey) : string{ if($block->getLevel() !== $this->owningLevel){ - throw new \InvalidStateException("Block does not belong to world " . $this->owningLevel->getName()); + throw new \InvalidStateException("Block does not belong to world " . $this->owningLevel->getDisplayName()); } return $block->x . ":" . $block->y . ":" . $block->z . ":" . $metadataKey; } diff --git a/src/pocketmine/metadata/LevelMetadataStore.php b/src/pocketmine/metadata/LevelMetadataStore.php index 790c5221ca..b31099f414 100644 --- a/src/pocketmine/metadata/LevelMetadataStore.php +++ b/src/pocketmine/metadata/LevelMetadataStore.php @@ -30,7 +30,7 @@ use function strtolower; class LevelMetadataStore extends MetadataStore{ private function disambiguate(Level $level, string $metadataKey) : string{ - return strtolower($level->getName()) . ":" . $metadataKey; + return strtolower($level->getFolderName()) . ":" . $metadataKey; } public function getMetadata(Level $subject, string $metadataKey){ From bbc8bc4df53280225f8d6b9d489f20e5fb5f13d3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 17 Jan 2019 19:16:03 +0000 Subject: [PATCH 0407/3224] Move some error handling stuff to SPL --- composer.lock | 16 +++++----- src/pocketmine/CrashDump.php | 38 ++++-------------------- src/pocketmine/PocketMine.php | 2 +- src/pocketmine/scheduler/AsyncWorker.php | 4 +-- src/pocketmine/utils/MainLogger.php | 35 ++++------------------ src/pocketmine/utils/Utils.php | 18 ----------- 6 files changed, 20 insertions(+), 93 deletions(-) diff --git a/composer.lock b/composer.lock index 070afe9dfa..e9501da4f8 100644 --- a/composer.lock +++ b/composer.lock @@ -413,12 +413,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "2f5dfdaa28ff69d72cd1682faa521e18b17a15ef" + "reference": "caffc9bcce765c78d4464b4f6852e3981b81b752" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/2f5dfdaa28ff69d72cd1682faa521e18b17a15ef", - "reference": "2f5dfdaa28ff69d72cd1682faa521e18b17a15ef", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/caffc9bcce765c78d4464b4f6852e3981b81b752", + "reference": "caffc9bcce765c78d4464b4f6852e3981b81b752", "shasum": "" }, "require": { @@ -446,7 +446,7 @@ "source": "https://github.com/pmmp/RakLib/tree/master", "issues": "https://github.com/pmmp/RakLib/issues" }, - "time": "2019-01-09T18:42:21+00:00" + "time": "2019-01-17T19:13:53+00:00" }, { "name": "pocketmine/snooze", @@ -488,12 +488,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/SPL.git", - "reference": "985e212ac528412ec00ddd3b88c5fc11549a2fe0" + "reference": "d7bd7b8cb10c264ca6e6b5c3ef9b52e48a6f29d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/SPL/zipball/985e212ac528412ec00ddd3b88c5fc11549a2fe0", - "reference": "985e212ac528412ec00ddd3b88c5fc11549a2fe0", + "url": "https://api.github.com/repos/pmmp/SPL/zipball/d7bd7b8cb10c264ca6e6b5c3ef9b52e48a6f29d8", + "reference": "d7bd7b8cb10c264ca6e6b5c3ef9b52e48a6f29d8", "shasum": "" }, "type": "library", @@ -512,7 +512,7 @@ "support": { "source": "https://github.com/pmmp/SPL/tree/master" }, - "time": "2018-10-21T17:32:00+00:00" + "time": "2019-01-17T18:54:01+00:00" } ], "packages-dev": [], diff --git a/src/pocketmine/CrashDump.php b/src/pocketmine/CrashDump.php index 4b01bcf174..4131a60231 100644 --- a/src/pocketmine/CrashDump.php +++ b/src/pocketmine/CrashDump.php @@ -60,21 +60,6 @@ use function substr; use function time; use function zend_version; use function zlib_encode; -use const E_COMPILE_ERROR; -use const E_COMPILE_WARNING; -use const E_CORE_ERROR; -use const E_CORE_WARNING; -use const E_DEPRECATED; -use const E_ERROR; -use const E_NOTICE; -use const E_PARSE; -use const E_RECOVERABLE_ERROR; -use const E_STRICT; -use const E_USER_DEPRECATED; -use const E_USER_ERROR; -use const E_USER_NOTICE; -use const E_USER_WARNING; -use const E_WARNING; use const FILE_IGNORE_NEW_LINES; use const JSON_UNESCAPED_SLASHES; use const PHP_EOL; @@ -217,26 +202,13 @@ class CrashDump{ }else{ $error = (array) error_get_last(); $error["trace"] = Utils::currentTrace(3); //Skipping CrashDump->baseCrash, CrashDump->construct, Server->crashDump - $errorConversion = [ - E_ERROR => "E_ERROR", - E_WARNING => "E_WARNING", - E_PARSE => "E_PARSE", - E_NOTICE => "E_NOTICE", - E_CORE_ERROR => "E_CORE_ERROR", - E_CORE_WARNING => "E_CORE_WARNING", - E_COMPILE_ERROR => "E_COMPILE_ERROR", - E_COMPILE_WARNING => "E_COMPILE_WARNING", - E_USER_ERROR => "E_USER_ERROR", - E_USER_WARNING => "E_USER_WARNING", - E_USER_NOTICE => "E_USER_NOTICE", - E_STRICT => "E_STRICT", - E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", - E_DEPRECATED => "E_DEPRECATED", - E_USER_DEPRECATED => "E_USER_DEPRECATED" - ]; $error["fullFile"] = $error["file"]; $error["file"] = Utils::cleanPath($error["file"]); - $error["type"] = $errorConversion[$error["type"]] ?? $error["type"]; + try{ + $error["type"] = \ErrorUtils::errorTypeToString($error["type"]); + }catch(\InvalidArgumentException $e){ + //pass + } if(($pos = strpos($error["message"], "\n")) !== false){ $error["message"] = substr($error["message"], 0, $pos); } diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index 83e844f9d3..c63c3a9cfd 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -163,7 +163,7 @@ namespace pocketmine { exit(1); } - set_error_handler([Utils::class, 'errorExceptionHandler']); + \ErrorUtils::setErrorExceptionHandler(); /* * We now use the Composer autoloader, but this autoloader is still for loading plugins. diff --git a/src/pocketmine/scheduler/AsyncWorker.php b/src/pocketmine/scheduler/AsyncWorker.php index 3f6bf6c4da..67bf176bb8 100644 --- a/src/pocketmine/scheduler/AsyncWorker.php +++ b/src/pocketmine/scheduler/AsyncWorker.php @@ -24,12 +24,10 @@ declare(strict_types=1); namespace pocketmine\scheduler; use pocketmine\utils\MainLogger; -use pocketmine\utils\Utils; use pocketmine\Worker; use function error_reporting; use function gc_enable; use function ini_set; -use function set_error_handler; class AsyncWorker extends Worker{ /** @var mixed[] */ @@ -53,7 +51,7 @@ class AsyncWorker extends Worker{ $this->registerClassLoader(); //set this after the autoloader is registered - set_error_handler([Utils::class, 'errorExceptionHandler']); + \ErrorUtils::setErrorExceptionHandler(); \GlobalLogger::set($this->logger); if($this->logger instanceof MainLogger){ diff --git a/src/pocketmine/utils/MainLogger.php b/src/pocketmine/utils/MainLogger.php index 06d11da641..f942249c9e 100644 --- a/src/pocketmine/utils/MainLogger.php +++ b/src/pocketmine/utils/MainLogger.php @@ -36,19 +36,8 @@ use function sprintf; use function time; use function touch; use function trim; -use const E_COMPILE_ERROR; -use const E_COMPILE_WARNING; -use const E_CORE_ERROR; -use const E_CORE_WARNING; -use const E_DEPRECATED; use const E_ERROR; -use const E_NOTICE; -use const E_PARSE; -use const E_RECOVERABLE_ERROR; -use const E_STRICT; -use const E_USER_DEPRECATED; use const E_USER_ERROR; -use const E_USER_NOTICE; use const E_USER_WARNING; use const E_WARNING; use const PHP_EOL; @@ -209,30 +198,16 @@ class MainLogger extends \AttachableThreadedLogger{ $errno = $e->getCode(); $errline = $e->getLine(); - $errorConversion = [ - 0 => "EXCEPTION", - E_ERROR => "E_ERROR", - E_WARNING => "E_WARNING", - E_PARSE => "E_PARSE", - E_NOTICE => "E_NOTICE", - E_CORE_ERROR => "E_CORE_ERROR", - E_CORE_WARNING => "E_CORE_WARNING", - E_COMPILE_ERROR => "E_COMPILE_ERROR", - E_COMPILE_WARNING => "E_COMPILE_WARNING", - E_USER_ERROR => "E_USER_ERROR", - E_USER_WARNING => "E_USER_WARNING", - E_USER_NOTICE => "E_USER_NOTICE", - E_STRICT => "E_STRICT", - E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", - E_DEPRECATED => "E_DEPRECATED", - E_USER_DEPRECATED => "E_USER_DEPRECATED" - ]; if($errno === 0){ $type = LogLevel::CRITICAL; }else{ $type = ($errno === E_ERROR or $errno === E_USER_ERROR) ? LogLevel::ERROR : (($errno === E_USER_WARNING or $errno === E_WARNING) ? LogLevel::WARNING : LogLevel::NOTICE); } - $errno = $errorConversion[$errno] ?? $errno; + try{ + $errno = \ErrorUtils::errorTypeToString($errno); + }catch(\InvalidArgumentException $e){ + //pass + } $errstr = preg_replace('/\s+/', ' ', trim($errstr)); $errfile = Utils::cleanPath($errfile); diff --git a/src/pocketmine/utils/Utils.php b/src/pocketmine/utils/Utils.php index 58bfab4f72..bfca817580 100644 --- a/src/pocketmine/utils/Utils.php +++ b/src/pocketmine/utils/Utils.php @@ -39,7 +39,6 @@ use function chunk_split; use function count; use function debug_zval_dump; use function dechex; -use function error_reporting; use function exec; use function explode; use function fclose; @@ -628,23 +627,6 @@ class Utils{ return array_combine($matches[1], $matches[2]); } - /** - * @param int $severity - * @param string $message - * @param string $file - * @param int $line - * - * @return bool - * @throws \ErrorException - */ - public static function errorExceptionHandler(int $severity, string $message, string $file, int $line) : bool{ - if(error_reporting() & $severity){ - throw new \ErrorException($message, 0, $severity, $file, $line); - } - - return true; //stfu operator - } - public static function testValidInstance(string $className, string $baseName) : void{ try{ $base = new \ReflectionClass($baseName); From 41676cb4d47a6a6b71e3b14ca6342e3035af983a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 17 Jan 2019 21:01:31 +0000 Subject: [PATCH 0408/3224] Server: remove some useless methods --- src/pocketmine/Server.php | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index b838ff9068..15d509c074 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1632,7 +1632,7 @@ class Server{ public function enablePlugins(int $type){ foreach($this->pluginManager->getPlugins() as $plugin){ if(!$plugin->isEnabled() and $plugin->getDescription()->getOrder() === $type){ - $this->enablePlugin($plugin); + $this->pluginManager->enablePlugin($plugin); } } @@ -1642,17 +1642,6 @@ class Server{ } } - /** - * @param Plugin $plugin - */ - public function enablePlugin(Plugin $plugin){ - $this->pluginManager->enablePlugin($plugin); - } - - public function disablePlugins(){ - $this->pluginManager->disablePlugins(); - } - /** * Executes a command from a CommandSender * From 38cf8d157dd1fb46f8b29f0898c4bdd7731b57b5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 17 Jan 2019 21:40:10 +0000 Subject: [PATCH 0409/3224] Max players check now works properly This now includes all connected sessions, whether they are considered online or not. --- src/pocketmine/Player.php | 2 +- src/pocketmine/Server.php | 6 +++++- src/pocketmine/network/Network.php | 8 ++++++++ src/pocketmine/network/NetworkInterface.php | 7 +++++++ src/pocketmine/network/mcpe/RakLibInterface.php | 5 +++++ 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 9bfa1d1a1e..1856887ca6 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1757,7 +1757,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->networkSession->getPort(), $this->server->requiresAuthentication() ); - if(count($this->server->getOnlinePlayers()) >= $this->server->getMaxPlayers()){ + if($this->server->getNetwork()->getConnectionCount() > $this->server->getMaxPlayers()){ $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_SERVER_FULL, "disconnectionScreen.serverFull"); } if(!$this->server->isWhitelisted($this->username)){ diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 15d509c074..4fdcaf089d 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -2093,9 +2093,13 @@ class Server{ $u = Utils::getMemoryUsage(true); $usage = sprintf("%g/%g/%g/%g MB @ %d threads", round(($u[0] / 1024) / 1024, 2), round(($d[0] / 1024) / 1024, 2), round(($u[1] / 1024) / 1024, 2), round(($u[2] / 1024) / 1024, 2), Utils::getThreadCount()); + $online = count($this->playerList); + $connecting = $this->network->getConnectionCount() - $online; + echo "\x1b]0;" . $this->getName() . " " . $this->getPocketMineVersion() . - " | Online " . count($this->players) . "/" . $this->getMaxPlayers() . + " | Online $online/" . $this->getMaxPlayers() . + ($connecting > 0 ? " (+$connecting connecting)" : "") . " | Memory " . $usage . " | U " . round($this->network->getUpload() / 1024, 2) . " D " . round($this->network->getDownload() / 1024, 2) . diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index e83952f484..a975caf250 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -77,6 +77,14 @@ class Network{ return $this->interfaces; } + public function getConnectionCount() : int{ + $count = 0; + foreach($this->interfaces as $interface){ + $count += $interface->getConnectionCount(); + } + return $count; + } + public function tick() : void{ foreach($this->interfaces as $interface){ $interface->tick(); diff --git a/src/pocketmine/network/NetworkInterface.php b/src/pocketmine/network/NetworkInterface.php index 8ef8484637..96207498cd 100644 --- a/src/pocketmine/network/NetworkInterface.php +++ b/src/pocketmine/network/NetworkInterface.php @@ -38,6 +38,13 @@ interface NetworkInterface{ */ public function start() : void; + /** + * Returns the number of connections on this interface. + * + * @return int + */ + public function getConnectionCount() : int; + /** * Sends a packet to the interface, returns an unique identifier for the packet if $needACK is true * diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 1bd89f341f..962c3643c9 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -39,6 +39,7 @@ use raklib\server\ServerHandler; use raklib\server\ServerInstance; use raklib\utils\InternetAddress; use function addcslashes; +use function count; use function implode; use function rtrim; use function spl_object_hash; @@ -99,6 +100,10 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $this->rakLib->start(PTHREADS_INHERIT_CONSTANTS); //HACK: MainLogger needs constants for exception logging } + public function getConnectionCount() : int{ + return count($this->sessions); + } + public function setNetwork(Network $network) : void{ $this->network = $network; } From 2dee7e9e0f2a12fac997de977a12a26d778a3477 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 17 Jan 2019 22:22:53 +0000 Subject: [PATCH 0410/3224] Properly handle Query packet errors --- src/pocketmine/Server.php | 12 +-- src/pocketmine/network/query/QueryHandler.php | 90 +++++++++++-------- 2 files changed, 56 insertions(+), 46 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 4fdcaf089d..e96250cfe4 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -2118,16 +2118,8 @@ class Server{ * TODO: move this to Network */ public function handlePacket(AdvancedNetworkInterface $interface, string $address, int $port, string $payload){ - try{ - if(strlen($payload) > 2 and substr($payload, 0, 2) === "\xfe\xfd" and $this->queryHandler instanceof QueryHandler){ - $this->queryHandler->handle($interface, $address, $port, $payload); - }else{ - $this->logger->debug("Unhandled raw packet from $address $port: " . bin2hex($payload)); - } - }catch(\Throwable $e){ - $this->logger->logException($e); - - $this->getNetwork()->blockAddress($address, 600); + if($this->queryHandler === null or !$this->queryHandler->handle($interface, $address, $port, $payload)){ + $this->logger->debug("Unhandled raw packet from $address $port: " . bin2hex($payload)); } //TODO: add raw packet events } diff --git a/src/pocketmine/network/query/QueryHandler.php b/src/pocketmine/network/query/QueryHandler.php index 541f95e0b6..feb7928c06 100644 --- a/src/pocketmine/network/query/QueryHandler.php +++ b/src/pocketmine/network/query/QueryHandler.php @@ -30,11 +30,11 @@ namespace pocketmine\network\query; use pocketmine\network\AdvancedNetworkInterface; use pocketmine\Server; use pocketmine\utils\Binary; -use function bin2hex; +use pocketmine\utils\BinaryDataException; +use pocketmine\utils\BinaryStream; use function chr; use function hash; use function microtime; -use function ord; use function random_bytes; use function strlen; use function substr; @@ -88,44 +88,62 @@ class QueryHandler{ return Binary::readInt(substr(hash("sha512", $salt . ":" . $token, true), 7, 4)); } - public function handle(AdvancedNetworkInterface $interface, string $address, int $port, string $packet) : void{ - $offset = 2; - $packetType = ord($packet{$offset++}); - $sessionID = Binary::readInt(substr($packet, $offset, 4)); - $offset += 4; - $payload = substr($packet, $offset); + /** + * @param AdvancedNetworkInterface $interface + * @param string $address + * @param int $port + * @param string $packet + * + * @return bool + */ + public function handle(AdvancedNetworkInterface $interface, string $address, int $port, string $packet) : bool{ + try{ + $stream = new BinaryStream($packet); + $header = $stream->get(2); + if($header !== "\xfe\xfd"){ //TODO: have this filtered by the regex filter we installed above + return false; + } + $packetType = $stream->getByte(); + $sessionID = $stream->getInt(); - switch($packetType){ - case self::HANDSHAKE: //Handshake - $reply = chr(self::HANDSHAKE); - $reply .= Binary::writeInt($sessionID); - $reply .= self::getTokenString($this->token, $address) . "\x00"; + switch($packetType){ + case self::HANDSHAKE: //Handshake + $reply = chr(self::HANDSHAKE); + $reply .= Binary::writeInt($sessionID); + $reply .= self::getTokenString($this->token, $address) . "\x00"; - $interface->sendRawPacket($address, $port, $reply); - break; - case self::STATISTICS: //Stat - $token = Binary::readInt(substr($payload, 0, 4)); - if($token !== ($t1 = self::getTokenString($this->token, $address)) and $token !== ($t2 = self::getTokenString($this->lastToken, $address))){ - $this->debug("Bad token $token from $address $port, expected $t1 or $t2"); - break; - } - $reply = chr(self::STATISTICS); - $reply .= Binary::writeInt($sessionID); + $interface->sendRawPacket($address, $port, $reply); - if($this->timeout < microtime(true)){ - $this->regenerateInfo(); - } + return true; + case self::STATISTICS: //Stat + $token = $stream->getInt(); + if($token !== ($t1 = self::getTokenString($this->token, $address)) and $token !== ($t2 = self::getTokenString($this->lastToken, $address))){ + $this->debug("Bad token $token from $address $port, expected $t1 or $t2"); - if(strlen($payload) === 8){ - $reply .= $this->longData; - }else{ - $reply .= $this->shortData; - } - $interface->sendRawPacket($address, $port, $reply); - break; - default: - $this->debug("Unhandled packet from $address $port: 0x" . bin2hex($packet)); - break; + return true; + } + $reply = chr(self::STATISTICS); + $reply .= Binary::writeInt($sessionID); + + if($this->timeout < microtime(true)){ + $this->regenerateInfo(); + } + + $remaining = $stream->getRemaining(); + if(strlen($remaining) === 4){ //TODO: check this! according to the spec, this should always be here and always be FF FF FF 01 + $reply .= $this->longData; + }else{ + $reply .= $this->shortData; + } + $interface->sendRawPacket($address, $port, $reply); + + return true; + default: + return false; + } + }catch(BinaryDataException $e){ + $this->debug("Bad packet from $address $port: " . $e->getMessage()); + return false; } } } From c5df2f6f0d538c0d4cc22c044fc9634104b99732 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 17 Jan 2019 22:43:52 +0000 Subject: [PATCH 0411/3224] Remove another Throwable abuse --- src/pocketmine/permission/BanEntry.php | 68 +++++++++++++------------- src/pocketmine/permission/BanList.php | 9 ++-- 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/src/pocketmine/permission/BanEntry.php b/src/pocketmine/permission/BanEntry.php index 7c8cbf3abb..80aae0c6e2 100644 --- a/src/pocketmine/permission/BanEntry.php +++ b/src/pocketmine/permission/BanEntry.php @@ -49,6 +49,7 @@ class BanEntry{ public function __construct(string $name){ $this->name = strtolower($name); + /** @noinspection PhpUnhandledExceptionInspection */ $this->creationDate = new \DateTime(); } @@ -60,6 +61,11 @@ class BanEntry{ return $this->creationDate; } + /** + * @param \DateTime $date + * + * @throws \InvalidArgumentException + */ public function setCreated(\DateTime $date){ self::validateDate($date); $this->creationDate = $date; @@ -82,6 +88,7 @@ class BanEntry{ /** * @param \DateTime|null $date + * @throws \InvalidArgumentException */ public function setExpires(\DateTime $date = null){ if($date !== null){ @@ -91,6 +98,7 @@ class BanEntry{ } public function hasExpired() : bool{ + /** @noinspection PhpUnhandledExceptionInspection */ $now = new \DateTime(); return $this->expirationDate === null ? false : $this->expirationDate < $now; @@ -127,10 +135,14 @@ class BanEntry{ * * @param \DateTime $dateTime * - * @throws \RuntimeException if the argument can't be parsed from a formatted date string + * @throws \InvalidArgumentException if the argument can't be parsed from a formatted date string */ private static function validateDate(\DateTime $dateTime) : void{ - self::parseDate($dateTime->format(self::$format)); + try{ + self::parseDate($dateTime->format(self::$format)); + }catch(\RuntimeException $e){ + throw new \InvalidArgumentException($e->getMessage(), 0, $e); + } } /** @@ -142,7 +154,7 @@ class BanEntry{ private static function parseDate(string $date) : ?\DateTime{ $datetime = \DateTime::createFromFormat(self::$format, $date); if(!($datetime instanceof \DateTime)){ - throw new \RuntimeException("Error parsing date for BanEntry: " . implode(", ", \DateTime::getLastErrors()["errors"])); + throw new \RuntimeException("Corrupted date/time: " . implode(", ", \DateTime::getLastErrors()["errors"])); } return $datetime; @@ -157,36 +169,26 @@ class BanEntry{ public static function fromString(string $str) : ?BanEntry{ if(strlen($str) < 2){ return null; - }else{ - $str = explode("|", trim($str)); - $entry = new BanEntry(trim(array_shift($str))); - do{ - if(empty($str)){ - break; - } - - $entry->setCreated(self::parseDate(array_shift($str))); - if(empty($str)){ - break; - } - - $entry->setSource(trim(array_shift($str))); - if(empty($str)){ - break; - } - - $expire = trim(array_shift($str)); - if($expire !== "" and strtolower($expire) !== "forever"){ - $entry->setExpires(self::parseDate($expire)); - } - if(empty($str)){ - break; - } - - $entry->setReason(trim(array_shift($str))); - }while(false); - - return $entry; } + + $parts = explode("|", trim($str)); + $entry = new BanEntry(trim(array_shift($parts))); + if(!empty($parts)){ + $entry->setCreated(self::parseDate(array_shift($parts))); + } + if(!empty($parts)){ + $entry->setSource(trim(array_shift($parts))); + } + if(!empty($parts)){ + $expire = trim(array_shift($parts)); + if($expire !== "" and strtolower($expire) !== "forever"){ + $entry->setExpires(self::parseDate($expire)); + } + } + if(!empty($parts)){ + $entry->setReason(trim(array_shift($parts))); + } + + return $entry; } } diff --git a/src/pocketmine/permission/BanList.php b/src/pocketmine/permission/BanList.php index 0eb3c71f92..df849c1c90 100644 --- a/src/pocketmine/permission/BanList.php +++ b/src/pocketmine/permission/BanList.php @@ -32,6 +32,7 @@ use function is_resource; use function strftime; use function strtolower; use function time; +use function trim; class BanList{ @@ -156,14 +157,14 @@ class BanList{ if($line{0} !== "#"){ try{ $entry = BanEntry::fromString($line); - if($entry instanceof BanEntry){ + if($entry !== null){ $this->list[$entry->getName()] = $entry; } - }catch(\Throwable $e){ + }catch(\RuntimeException $e){ $logger = \GlobalLogger::get(); - $logger->critical("Failed to parse ban entry from string \"$line\": " . $e->getMessage()); - $logger->logException($e); + $logger->critical("Failed to parse ban entry from string \"" . trim($line) . "\": " . $e->getMessage()); } + } } fclose($fp); From c5998a92a8cbdb1dfc3697dec502e69135eff2fe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 17 Jan 2019 23:34:59 +0000 Subject: [PATCH 0412/3224] PluginManager: clean up some Throwable abuse --- src/pocketmine/plugin/PluginManager.php | 134 +++++++++++------------- 1 file changed, 61 insertions(+), 73 deletions(-) diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index a83017e456..3e7e1270f5 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -172,19 +172,14 @@ class PluginManager{ return null; } - try{ - /** - * @var Plugin $plugin - * @see Plugin::__construct() - */ - $plugin = new $mainClass($loader, $this->server, $description, $dataFolder, $prefixed); - $this->plugins[$plugin->getDescription()->getName()] = $plugin; + /** + * @var Plugin $plugin + * @see Plugin::__construct() + */ + $plugin = new $mainClass($loader, $this->server, $description, $dataFolder, $prefixed); + $this->plugins[$plugin->getDescription()->getName()] = $plugin; - return $plugin; - }catch(\Throwable $e){ - $this->server->getLogger()->logException($e); - return null; - } + return $plugin; } } } @@ -228,57 +223,59 @@ class PluginManager{ } try{ $description = $loader->getPluginDescription($file); - if($description === null){ - continue; - } + }catch(\RuntimeException $e){ //TODO: more specific exception handling + $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.fileError", [$file, $directory, $e->getMessage()])); + $this->server->getLogger()->logException($e); + continue; + } + if($description === null){ + continue; + } - $name = $description->getName(); - if(stripos($name, "pocketmine") !== false or stripos($name, "minecraft") !== false or stripos($name, "mojang") !== false){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.loadError", [$name, "%pocketmine.plugin.restrictedName"])); - continue; - }elseif(strpos($name, " ") !== false){ - $this->server->getLogger()->warning($this->server->getLanguage()->translateString("pocketmine.plugin.spacesDiscouraged", [$name])); - } + $name = $description->getName(); + if(stripos($name, "pocketmine") !== false or stripos($name, "minecraft") !== false or stripos($name, "mojang") !== false){ + $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.loadError", [$name, "%pocketmine.plugin.restrictedName"])); + continue; + } + if(strpos($name, " ") !== false){ + $this->server->getLogger()->warning($this->server->getLanguage()->translateString("pocketmine.plugin.spacesDiscouraged", [$name])); + } - if(isset($plugins[$name]) or $this->getPlugin($name) instanceof Plugin){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.duplicateError", [$name])); - continue; - } + if(isset($plugins[$name]) or $this->getPlugin($name) instanceof Plugin){ + $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.duplicateError", [$name])); + continue; + } - if(!$this->isCompatibleApi(...$description->getCompatibleApis())){ + if(!$this->isCompatibleApi(...$description->getCompatibleApis())){ + $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.loadError", [ + $name, + $this->server->getLanguage()->translateString("%pocketmine.plugin.incompatibleAPI", [implode(", ", $description->getCompatibleApis())]) + ])); + continue; + } + + if(count($pluginMcpeProtocols = $description->getCompatibleMcpeProtocols()) > 0){ + $serverMcpeProtocols = [ProtocolInfo::CURRENT_PROTOCOL]; + if(count(array_intersect($pluginMcpeProtocols, $serverMcpeProtocols)) === 0){ $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.loadError", [ $name, - $this->server->getLanguage()->translateString("%pocketmine.plugin.incompatibleAPI", [implode(", ", $description->getCompatibleApis())]) + $this->server->getLanguage()->translateString("%pocketmine.plugin.incompatibleProtocol", [implode(", ", $pluginMcpeProtocols)]) ])); continue; } + } - if(count($pluginMcpeProtocols = $description->getCompatibleMcpeProtocols()) > 0){ - $serverMcpeProtocols = [ProtocolInfo::CURRENT_PROTOCOL]; - if(count(array_intersect($pluginMcpeProtocols, $serverMcpeProtocols)) === 0){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.loadError", [ - $name, - $this->server->getLanguage()->translateString("%pocketmine.plugin.incompatibleProtocol", [implode(", ", $pluginMcpeProtocols)]) - ])); - continue; - } + $plugins[$name] = $file; + + $softDependencies[$name] = $description->getSoftDepend(); + $dependencies[$name] = $description->getDepend(); + + foreach($description->getLoadBefore() as $before){ + if(isset($softDependencies[$before])){ + $softDependencies[$before][] = $name; + }else{ + $softDependencies[$before] = [$name]; } - - $plugins[$name] = $file; - - $softDependencies[$name] = $description->getSoftDepend(); - $dependencies[$name] = $description->getDepend(); - - foreach($description->getLoadBefore() as $before){ - if(isset($softDependencies[$before])){ - $softDependencies[$before][] = $name; - }else{ - $softDependencies[$before] = [$name]; - } - } - }catch(\Throwable $e){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.fileError", [$file, $directory, $e->getMessage()])); - $this->server->getLogger()->logException($e); } } } @@ -413,23 +410,18 @@ class PluginManager{ */ public function enablePlugin(Plugin $plugin){ if(!$plugin->isEnabled()){ - try{ - $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.plugin.enable", [$plugin->getDescription()->getFullName()])); + $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.plugin.enable", [$plugin->getDescription()->getFullName()])); - $permManager = PermissionManager::getInstance(); - foreach($plugin->getDescription()->getPermissions() as $perm){ - $permManager->addPermission($perm); - } - $plugin->getScheduler()->setEnabled(true); - $plugin->onEnableStateChange(true); - - $this->enabledPlugins[$plugin->getDescription()->getName()] = $plugin; - - (new PluginEnableEvent($plugin))->call(); - }catch(\Throwable $e){ - $this->server->getLogger()->logException($e); - $this->disablePlugin($plugin); + $permManager = PermissionManager::getInstance(); + foreach($plugin->getDescription()->getPermissions() as $perm){ + $permManager->addPermission($perm); } + $plugin->getScheduler()->setEnabled(true); + $plugin->onEnableStateChange(true); + + $this->enabledPlugins[$plugin->getDescription()->getName()] = $plugin; + + (new PluginEnableEvent($plugin))->call(); } } @@ -449,11 +441,7 @@ class PluginManager{ unset($this->enabledPlugins[$plugin->getDescription()->getName()]); - try{ - $plugin->onEnableStateChange(false); - }catch(\Throwable $e){ - $this->server->getLogger()->logException($e); - } + $plugin->onEnableStateChange(false); $plugin->getScheduler()->shutdown(); HandlerList::unregisterAll($plugin); $permManager = PermissionManager::getInstance(); From 6b7710e62bc91bf1058b480bab05ce18b939bc73 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 19 Jan 2019 12:43:47 +0000 Subject: [PATCH 0413/3224] Introduce dedicated NBT data exceptions, fix up some corrupted chunk handling --- composer.lock | 8 +- src/pocketmine/Player.php | 14 +++- src/pocketmine/Server.php | 11 ++- .../command/defaults/GiveCommand.php | 11 +-- src/pocketmine/item/Item.php | 11 ++- .../level/format/io/leveldb/LevelDB.php | 81 +++++++++++++------ .../io/region/LegacyAnvilChunkTrait.php | 13 ++- .../level/format/io/region/McRegion.php | 7 +- .../format/io/region/RegionLevelProvider.php | 7 ++ .../network/mcpe/NetworkBinaryStream.php | 3 +- 10 files changed, 117 insertions(+), 49 deletions(-) diff --git a/composer.lock b/composer.lock index e9501da4f8..32dade4095 100644 --- a/composer.lock +++ b/composer.lock @@ -372,12 +372,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "8b211471159b4aca329c665bdbd9149046ca6550" + "reference": "6736e85ec7600309d7ef1dc5b965ff7e4b1c5357" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/8b211471159b4aca329c665bdbd9149046ca6550", - "reference": "8b211471159b4aca329c665bdbd9149046ca6550", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/6736e85ec7600309d7ef1dc5b965ff7e4b1c5357", + "reference": "6736e85ec7600309d7ef1dc5b965ff7e4b1c5357", "shasum": "" }, "require": { @@ -405,7 +405,7 @@ "source": "https://github.com/pmmp/NBT/tree/master", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2019-01-09T00:12:13+00:00" + "time": "2019-01-18T15:28:20+00:00" }, { "name": "pocketmine/raklib", diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 1856887ca6..fae95601a4 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -88,10 +88,12 @@ use pocketmine\level\Level; use pocketmine\level\Position; use pocketmine\math\Vector3; use pocketmine\metadata\MetadataValue; +use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\ListTag; +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\NetworkCipher; use pocketmine\network\mcpe\NetworkNbtSerializer; @@ -2451,6 +2453,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return $handled; } + /** + * @param BlockEntityDataPacket $packet + * + * @return bool + * @throws BadPacketException + */ public function handleBlockEntityData(BlockEntityDataPacket $packet) : bool{ $this->doCloseInventory(); @@ -2462,7 +2470,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $t = $this->level->getTile($pos); if($t instanceof Spawnable){ $nbt = new NetworkNbtSerializer(); - $compound = $nbt->read($packet->namedtag); + try{ + $compound = $nbt->read($packet->namedtag); + }catch(NbtDataException $e){ + throw new BadPacketException($e->getMessage(), 0, $e); + } if(!$t->updateCompoundTag($compound, $this)){ $t->spawnTo($this); } diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index e96250cfe4..8b0568381d 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -59,6 +59,7 @@ use pocketmine\metadata\LevelMetadataStore; use pocketmine\metadata\PlayerMetadataStore; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NBT; +use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\DoubleTag; @@ -676,15 +677,13 @@ class Server{ if($this->shouldSavePlayerData()){ if(file_exists($path . "$name.dat")){ try{ - $nbt = new BigEndianNbtSerializer(); - return $nbt->readCompressed(file_get_contents($path . "$name.dat")); - }catch(\Throwable $e){ //zlib decode error / corrupt data + return (new BigEndianNbtSerializer())->readCompressed(file_get_contents($path . "$name.dat")); + }catch(NbtDataException $e){ //zlib decode error / corrupt data rename($path . "$name.dat", $path . "$name.dat.bak"); - $this->logger->notice($this->getLanguage()->translateString("pocketmine.data.playerCorrupted", [$name])); + $this->logger->error($this->getLanguage()->translateString("pocketmine.data.playerCorrupted", [$name])); } - }else{ - $this->logger->notice($this->getLanguage()->translateString("pocketmine.data.playerNotFound", [$name])); } + $this->logger->notice($this->getLanguage()->translateString("pocketmine.data.playerNotFound", [$name])); } $spawn = $this->levelManager->getDefaultLevel()->getSafeSpawn(); $currentTimeMillis = (int) (microtime(true) * 1000); diff --git a/src/pocketmine/command/defaults/GiveCommand.php b/src/pocketmine/command/defaults/GiveCommand.php index 8e2138aa05..0e43bcac1a 100644 --- a/src/pocketmine/command/defaults/GiveCommand.php +++ b/src/pocketmine/command/defaults/GiveCommand.php @@ -29,7 +29,7 @@ use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\ItemFactory; use pocketmine\lang\TranslationContainer; use pocketmine\nbt\JsonNbtParser; -use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\NbtDataException; use pocketmine\utils\TextFormat; use function array_slice; use function count; @@ -75,16 +75,11 @@ class GiveCommand extends VanillaCommand{ } if(isset($args[3])){ - $tags = $exception = null; $data = implode(" ", array_slice($args, 3)); try{ $tags = JsonNbtParser::parseJson($data); - }catch(\Exception $ex){ - $exception = $ex; - } - - if(!($tags instanceof CompoundTag) or $exception !== null){ - $sender->sendMessage(new TranslationContainer("commands.give.tagError", [$exception !== null ? $exception->getMessage() : "Invalid tag conversion"])); + }catch(NbtDataException $e){ + $sender->sendMessage(new TranslationContainer("commands.give.tagError", [$e->getMessage()])); return true; } diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 214efe1df0..60296abf76 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -35,6 +35,7 @@ use pocketmine\item\enchantment\EnchantmentInstance; use pocketmine\math\Vector3; use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\NBT; +use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; @@ -64,11 +65,13 @@ class Item implements ItemIds, \JsonSerializable{ /** @var LittleEndianNbtSerializer */ private static $cachedParser = null; + /** + * @param string $tag + * + * @return CompoundTag + * @throws NbtDataException + */ private static function parseCompoundTag(string $tag) : CompoundTag{ - if($tag === ""){ - throw new \InvalidArgumentException("No NBT data found in supplied string"); - } - if(self::$cachedParser === null){ self::$cachedParser = new LittleEndianNbtSerializer(); } diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index 8badadf354..069692c7cf 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -27,13 +27,16 @@ use pocketmine\level\format\Chunk; use pocketmine\level\format\io\BaseLevelProvider; use pocketmine\level\format\io\ChunkUtils; use pocketmine\level\format\io\data\BedrockLevelData; +use pocketmine\level\format\io\exception\CorruptedChunkException; use pocketmine\level\format\io\exception\UnsupportedChunkFormatException; use pocketmine\level\format\io\exception\UnsupportedLevelFormatException; use pocketmine\level\format\io\LevelData; use pocketmine\level\format\SubChunk; use pocketmine\nbt\LittleEndianNbtSerializer; +use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\utils\Binary; +use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; use function array_values; use function chr; @@ -130,6 +133,7 @@ class LevelDB extends BaseLevelProvider{ * @param int $chunkZ * * @return Chunk|null + * @throws CorruptedChunkException * @throws UnsupportedChunkFormatException */ protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk{ @@ -164,21 +168,28 @@ class LevelDB extends BaseLevelProvider{ continue; } - $binaryStream->setBuffer($data, 0); + $binaryStream->setBuffer($data); + if($binaryStream->feof()){ + throw new CorruptedChunkException("Unexpected empty data for subchunk $y"); + } $subChunkVersion = $binaryStream->getByte(); switch($subChunkVersion){ case 0: - $blocks = $binaryStream->get(4096); - $blockData = $binaryStream->get(2048); - if($chunkVersion < 4){ - $blockSkyLight = $binaryStream->get(2048); - $blockLight = $binaryStream->get(2048); - }else{ - //Mojang didn't bother changing the subchunk version when they stopped saving sky light -_- - $blockSkyLight = ""; - $blockLight = ""; - $lightPopulated = false; + try{ + $blocks = $binaryStream->get(4096); + $blockData = $binaryStream->get(2048); + if($chunkVersion < 4){ + $blockSkyLight = $binaryStream->get(2048); + $blockLight = $binaryStream->get(2048); + }else{ + //Mojang didn't bother changing the subchunk version when they stopped saving sky light -_- + $blockSkyLight = ""; + $blockLight = ""; + $lightPopulated = false; + } + }catch(BinaryDataException $e){ + throw new CorruptedChunkException($e->getMessage(), 0, $e); } $subChunks[$y] = new SubChunk($blocks, $blockData, $blockSkyLight, $blockLight); @@ -190,18 +201,30 @@ class LevelDB extends BaseLevelProvider{ } if(($maps2d = $this->db->get($index . self::TAG_DATA_2D)) !== false){ - $binaryStream->setBuffer($maps2d, 0); + $binaryStream->setBuffer($maps2d); - $heightMap = array_values(unpack("v*", $binaryStream->get(512))); - $biomeIds = $binaryStream->get(256); + try{ + $heightMap = array_values(unpack("v*", $binaryStream->get(512))); + $biomeIds = $binaryStream->get(256); + }catch(BinaryDataException $e){ + throw new CorruptedChunkException($e->getMessage(), 0, $e); + } } break; case 2: // < MCPE 1.0 - $binaryStream->setBuffer($this->db->get($index . self::TAG_LEGACY_TERRAIN)); - $fullIds = $binaryStream->get(32768); - $fullData = $binaryStream->get(16384); - $fullSkyLight = $binaryStream->get(16384); - $fullBlockLight = $binaryStream->get(16384); + $legacyTerrain = $this->db->get($index . self::TAG_LEGACY_TERRAIN); + if($legacyTerrain === false){ + throw new CorruptedChunkException("Missing expected LEGACY_TERRAIN tag for format version $chunkVersion"); + } + $binaryStream->setBuffer($legacyTerrain); + try{ + $fullIds = $binaryStream->get(32768); + $fullData = $binaryStream->get(16384); + $fullSkyLight = $binaryStream->get(16384); + $fullBlockLight = $binaryStream->get(16384); + }catch(BinaryDataException $e){ + throw new CorruptedChunkException($e->getMessage(), 0, $e); + } for($yy = 0; $yy < 8; ++$yy){ $subOffset = ($yy << 4); @@ -231,8 +254,12 @@ class LevelDB extends BaseLevelProvider{ $subChunks[$yy] = new SubChunk($ids, $data, $skyLight, $blockLight); } - $heightMap = array_values(unpack("C*", $binaryStream->get(256))); - $biomeIds = ChunkUtils::convertBiomeColors(array_values(unpack("N*", $binaryStream->get(1024)))); + try{ + $heightMap = array_values(unpack("C*", $binaryStream->get(256))); + $biomeIds = ChunkUtils::convertBiomeColors(array_values(unpack("N*", $binaryStream->get(1024)))); + }catch(BinaryDataException $e){ + throw new CorruptedChunkException($e->getMessage(), 0, $e); + } break; default: //TODO: set chunks read-only so the version on disk doesn't get overwritten @@ -244,13 +271,21 @@ class LevelDB extends BaseLevelProvider{ /** @var CompoundTag[] $entities */ $entities = []; if(($entityData = $this->db->get($index . self::TAG_ENTITY)) !== false and $entityData !== ""){ - $entities = $nbt->readMultiple($entityData); + try{ + $entities = $nbt->readMultiple($entityData); + }catch(NbtDataException $e){ + throw new CorruptedChunkException($e->getMessage(), 0, $e); + } } /** @var CompoundTag[] $tiles */ $tiles = []; if(($tileData = $this->db->get($index . self::TAG_BLOCK_ENTITY)) !== false and $tileData !== ""){ - $tiles = $nbt->readMultiple($tileData); + try{ + $tiles = $nbt->readMultiple($tileData); + }catch(NbtDataException $e){ + throw new CorruptedChunkException($e->getMessage(), 0, $e); + } } //TODO: extra data should be converted into blockstorage layers (first they need to be implemented!) diff --git a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php b/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php index 86b69eedea..3d68f5f6c2 100644 --- a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php @@ -29,6 +29,7 @@ use pocketmine\level\format\io\exception\CorruptedChunkException; use pocketmine\level\format\SubChunk; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NBT; +use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntArrayTag; use pocketmine\nbt\tag\ListTag; @@ -95,9 +96,19 @@ trait LegacyAnvilChunkTrait{ abstract protected function serializeSubChunk(SubChunk $subChunk) : CompoundTag; + /** + * @param string $data + * + * @return Chunk + * @throws CorruptedChunkException + */ protected function deserializeChunk(string $data) : Chunk{ $nbt = new BigEndianNbtSerializer(); - $chunk = $nbt->readCompressed($data); + try{ + $chunk = $nbt->readCompressed($data); + }catch(NbtDataException $e){ + throw new CorruptedChunkException($e->getMessage(), 0, $e); + } if(!$chunk->hasTag("Level")){ throw new CorruptedChunkException("'Level' key is missing from chunk NBT"); } diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index 389c6e9398..56f1e0326b 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -29,6 +29,7 @@ use pocketmine\level\format\io\exception\CorruptedChunkException; use pocketmine\level\format\SubChunk; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NBT; +use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntArrayTag; @@ -107,7 +108,11 @@ class McRegion extends RegionLevelProvider{ */ protected function deserializeChunk(string $data) : Chunk{ $nbt = new BigEndianNbtSerializer(); - $chunk = $nbt->readCompressed($data); + try{ + $chunk = $nbt->readCompressed($data); + }catch(NbtDataException $e){ + throw new CorruptedChunkException($e->getMessage(), 0, $e); + } if(!$chunk->hasTag("Level")){ throw new CorruptedChunkException("'Level' key is missing from chunk NBT"); } diff --git a/src/pocketmine/level/format/io/region/RegionLevelProvider.php b/src/pocketmine/level/format/io/region/RegionLevelProvider.php index 5d0dc4ebba..3874e960f7 100644 --- a/src/pocketmine/level/format/io/region/RegionLevelProvider.php +++ b/src/pocketmine/level/format/io/region/RegionLevelProvider.php @@ -176,6 +176,13 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ */ abstract protected function deserializeChunk(string $data) : Chunk; + /** + * @param int $chunkX + * @param int $chunkZ + * + * @return Chunk|null + * @throws CorruptedChunkException + */ protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk{ $regionX = $regionZ = null; self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ); diff --git a/src/pocketmine/network/mcpe/NetworkBinaryStream.php b/src/pocketmine/network/mcpe/NetworkBinaryStream.php index ca1dd40623..ae1399873c 100644 --- a/src/pocketmine/network/mcpe/NetworkBinaryStream.php +++ b/src/pocketmine/network/mcpe/NetworkBinaryStream.php @@ -31,6 +31,7 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\Vector3; use pocketmine\nbt\LittleEndianNbtSerializer; +use pocketmine\nbt\NbtDataException; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\types\CommandOriginData; use pocketmine\network\mcpe\protocol\types\EntityLink; @@ -105,7 +106,7 @@ class NetworkBinaryStream extends BinaryStream{ } try{ $compound = self::$itemNbtSerializer->read($this->get($nbtLen)); - }catch(\UnexpectedValueException $e){ + }catch(NbtDataException $e){ throw new BadPacketException($e->getMessage(), 0, $e); } } From 179fb9c7cb19e7a3221492a156f0c25684121172 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 19 Jan 2019 13:41:28 +0000 Subject: [PATCH 0414/3224] Fixed tree trunk generation bug introduced by ac87319aed4d556d85a8aeba0ea6da6667a5408f Blocks were being overwritten in the writebatch which hadn't yet been set, so reading them from the world yielded air blocks instead of trunk, allowing the generation to overwrite blocks which should have been logs. --- src/pocketmine/level/BlockWriteBatch.php | 27 +++++++++++++++++++ .../level/generator/object/Tree.php | 4 +-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/level/BlockWriteBatch.php b/src/pocketmine/level/BlockWriteBatch.php index 8638930fd4..11faaa2bc6 100644 --- a/src/pocketmine/level/BlockWriteBatch.php +++ b/src/pocketmine/level/BlockWriteBatch.php @@ -67,6 +67,33 @@ class BlockWriteBatch{ return $this; } + /** + * Reads a block from the given world, masked by the blocks in this writebatch. This can be useful if you want to + * add blocks to the batch that depend on previous blocks should they exist. + * + * @param ChunkManager $world + * @param Vector3 $pos + * + * @return Block + */ + public function fetchBlock(ChunkManager $world, Vector3 $pos) : Block{ + return $this->fetchBlockAt($world, $pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ()); + } + + /** + * @see BlockWriteBatch::fetchBlock() + * + * @param ChunkManager $world + * @param int $x + * @param int $y + * @param int $z + * + * @return Block + */ + public function fetchBlockAt(ChunkManager $world, int $x, int $y, int $z) : Block{ + return $this->blocks[$x][$y][$z] ?? $world->getBlockAt($x, $y, $z); + } + /** * Validates and attempts to apply the batch to the given world. If any part of the batch fails to validate, no * changes will be made to the world. diff --git a/src/pocketmine/level/generator/object/Tree.php b/src/pocketmine/level/generator/object/Tree.php index aa6993017a..7a795e20ad 100644 --- a/src/pocketmine/level/generator/object/Tree.php +++ b/src/pocketmine/level/generator/object/Tree.php @@ -117,7 +117,7 @@ abstract class Tree{ $write->addBlockAt($x, $y - 1, $z, BlockFactory::get(Block::DIRT)); for($yy = 0; $yy < $trunkHeight; ++$yy){ - if($this->canOverride($level->getBlockAt($x, $y + $yy, $z))){ + if($this->canOverride($write->fetchBlockAt($level, $x, $y + $yy, $z))){ $write->addBlockAt($x, $y + $yy, $z, $this->trunkBlock); } } @@ -134,7 +134,7 @@ abstract class Tree{ if($xOff === $mid and $zOff === $mid and ($yOff === 0 or $random->nextBoundedInt(2) === 0)){ continue; } - if(!$level->getBlockAt($xx, $yy, $zz)->isSolid()){ + if(!$write->fetchBlockAt($level, $xx, $yy, $zz)->isSolid()){ $write->addBlockAt($xx, $yy, $zz, $this->leafBlock); } } From 65927e69651652917c928990fb8643cfa33f0096 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 19 Jan 2019 14:32:20 +0000 Subject: [PATCH 0415/3224] Minor cleanup to Player NBT creation garbage --- src/pocketmine/OfflinePlayer.php | 7 +++-- src/pocketmine/Player.php | 15 +++++----- src/pocketmine/Server.php | 50 ++++---------------------------- 3 files changed, 16 insertions(+), 56 deletions(-) diff --git a/src/pocketmine/OfflinePlayer.php b/src/pocketmine/OfflinePlayer.php index 0e631ee626..2b1d87a85b 100644 --- a/src/pocketmine/OfflinePlayer.php +++ b/src/pocketmine/OfflinePlayer.php @@ -26,6 +26,7 @@ namespace pocketmine; use pocketmine\metadata\Metadatable; use pocketmine\metadata\MetadataValue; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\tag\LongTag; use pocketmine\plugin\Plugin; class OfflinePlayer implements IPlayer, Metadatable{ @@ -106,15 +107,15 @@ class OfflinePlayer implements IPlayer, Metadatable{ } public function getFirstPlayed(){ - return $this->namedtag instanceof CompoundTag ? $this->namedtag->getLong("firstPlayed", 0, true) : null; + return ($this->namedtag !== null and $this->namedtag->hasTag("firstPlayed", LongTag::class)) ? $this->namedtag->getInt("firstPlayed") : null; } public function getLastPlayed(){ - return $this->namedtag instanceof CompoundTag ? $this->namedtag->getLong("lastPlayed", 0, true) : null; + return ($this->namedtag !== null and $this->namedtag->hasTag("lastPlayed", LongTag::class)) ? $this->namedtag->getLong("lastPlayed") : null; } public function hasPlayedBefore() : bool{ - return $this->namedtag instanceof CompoundTag; + return $this->namedtag !== null; } public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue){ diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index fae95601a4..ac06b7123b 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1891,10 +1891,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->firstPlayed = $nbt->getLong("firstPlayed", $now = (int) (microtime(true) * 1000)); $this->lastPlayed = $nbt->getLong("lastPlayed", $now); - $this->gamemode = $nbt->getInt("playerGameType", GameMode::SURVIVAL) & 0x03; - if($this->server->getForceGamemode()){ - $this->gamemode = $this->server->getGamemode(); - } + $this->gamemode = $this->server->getForceGamemode() ? $this->server->getGamemode() : $nbt->getInt("playerGameType", $this->server->getGamemode()) & 0x03; $this->allowFlight = $this->isCreative(); $this->keepMovement = $this->isSpectator() || $this->allowMovementCheats(); @@ -1907,10 +1904,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->setCanClimb(); $this->achievements = []; - $achievements = $nbt->getCompoundTag("Achievements") ?? []; - /** @var ByteTag $achievement */ - foreach($achievements as $achievement){ - $this->achievements[$achievement->getName()] = $achievement->getValue() !== 0; + $achievements = $nbt->getCompoundTag("Achievements"); + if($achievements !== null){ + /** @var ByteTag $achievement */ + foreach($achievements as $achievement){ + $this->achievements[$achievement->getName()] = $achievement->getValue() !== 0; + } } if(!$this->hasValidSpawnPosition()){ diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 8b0568381d..235b276bfc 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -58,17 +58,8 @@ use pocketmine\metadata\EntityMetadataStore; use pocketmine\metadata\LevelMetadataStore; use pocketmine\metadata\PlayerMetadataStore; use pocketmine\nbt\BigEndianNbtSerializer; -use pocketmine\nbt\NBT; use pocketmine\nbt\NbtDataException; -use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\DoubleTag; -use pocketmine\nbt\tag\FloatTag; -use pocketmine\nbt\tag\IntTag; -use pocketmine\nbt\tag\ListTag; -use pocketmine\nbt\tag\LongTag; -use pocketmine\nbt\tag\ShortTag; -use pocketmine\nbt\tag\StringTag; use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\CompressBatchTask; @@ -686,45 +677,14 @@ class Server{ $this->logger->notice($this->getLanguage()->translateString("pocketmine.data.playerNotFound", [$name])); } $spawn = $this->levelManager->getDefaultLevel()->getSafeSpawn(); - $currentTimeMillis = (int) (microtime(true) * 1000); - $nbt = new CompoundTag("", [ - new LongTag("firstPlayed", $currentTimeMillis), - new LongTag("lastPlayed", $currentTimeMillis), - new ListTag("Pos", [ - new DoubleTag("", $spawn->x), - new DoubleTag("", $spawn->y), - new DoubleTag("", $spawn->z) - ], NBT::TAG_Double), - new StringTag("Level", $this->levelManager->getDefaultLevel()->getFolderName()), - //new StringTag("SpawnLevel", $this->getDefaultLevel()->getFolderName()), - //new IntTag("SpawnX", $spawn->getFloorX()), - //new IntTag("SpawnY", $spawn->getFloorY()), - //new IntTag("SpawnZ", $spawn->getFloorZ()), - //new ByteTag("SpawnForced", 1), //TODO - new ListTag("Inventory", [], NBT::TAG_Compound), - new ListTag("EnderChestInventory", [], NBT::TAG_Compound), - new CompoundTag("Achievements", []), - new IntTag("playerGameType", $this->getGamemode()), - new ListTag("Motion", [ - new DoubleTag("", 0.0), - new DoubleTag("", 0.0), - new DoubleTag("", 0.0) - ], NBT::TAG_Double), - new ListTag("Rotation", [ - new FloatTag("", 0.0), - new FloatTag("", 0.0) - ], NBT::TAG_Float), - new FloatTag("FallDistance", 0.0), - new ShortTag("Fire", 0), - new ShortTag("Air", 300), - new ByteTag("OnGround", 1), - new ByteTag("Invulnerable", 0), - new StringTag("NameTag", $name) - ]); + $nbt = EntityFactory::createBaseNBT($spawn); + + $nbt->setString("Level", $this->levelManager->getDefaultLevel()->getFolderName()); + $nbt->setByte("OnGround", 1); //TODO: this hack is needed for new players in-air ticks - they don't get detected as on-ground until they move + //TODO: old code had a TODO for SpawnForced return $nbt; - } /** From 9d8a70d5cf782d546113be69c97a5ce19761f7dc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 19 Jan 2019 14:55:09 +0000 Subject: [PATCH 0416/3224] Level: use appropriate exceptions --- src/pocketmine/level/Level.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index aaa14426ee..37876bb680 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -2503,14 +2503,14 @@ class Level implements ChunkManager, Metadatable{ /** * @param Entity $entity * - * @throws LevelException + * @throws \InvalidArgumentException */ public function addEntity(Entity $entity){ if($entity->isClosed()){ throw new \InvalidArgumentException("Attempted to add a garbage closed Entity to Level"); } if($entity->getLevel() !== $this){ - throw new LevelException("Invalid Entity level"); + throw new \InvalidArgumentException("Invalid Entity level"); } if($entity instanceof Player){ @@ -2524,11 +2524,11 @@ class Level implements ChunkManager, Metadatable{ * * @param Entity $entity * - * @throws LevelException + * @throws \InvalidArgumentException */ public function removeEntity(Entity $entity){ if($entity->getLevel() !== $this){ - throw new LevelException("Invalid Entity level"); + throw new \InvalidArgumentException("Invalid Entity level"); } if($entity instanceof Player){ @@ -2543,14 +2543,14 @@ class Level implements ChunkManager, Metadatable{ /** * @param Tile $tile * - * @throws LevelException + * @throws \InvalidArgumentException */ public function addTile(Tile $tile){ if($tile->isClosed()){ throw new \InvalidArgumentException("Attempted to add a garbage closed Tile to Level"); } if($tile->getLevel() !== $this){ - throw new LevelException("Invalid Tile level"); + throw new \InvalidArgumentException("Invalid Tile level"); } $chunkX = $tile->getFloorX() >> 4; @@ -2569,11 +2569,11 @@ class Level implements ChunkManager, Metadatable{ /** * @param Tile $tile * - * @throws LevelException + * @throws \InvalidArgumentException */ public function removeTile(Tile $tile){ if($tile->getLevel() !== $this){ - throw new LevelException("Invalid Tile level"); + throw new \InvalidArgumentException("Invalid Tile level"); } unset($this->tiles[$blockHash = Level::blockHash($tile->x, $tile->y, $tile->z)], $this->updateTiles[$blockHash]); From 5d8568b1a4492cf10294cbc2419c1d372f32074f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 20 Jan 2019 11:05:12 +0000 Subject: [PATCH 0417/3224] Add NetworkSession->getDisplayName(), clean up ip/port ad-hoc usages --- src/pocketmine/network/mcpe/NetworkSession.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 0d4a9e4046..026e16c876 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -139,6 +139,10 @@ class NetworkSession{ return $this->port; } + public function getDisplayName() : string{ + return ($this->player !== null and $this->player->getName() !== "") ? $this->player->getName() : $this->ip . " " . $this->port; + } + /** * Returns the last recorded ping measurement for this session, in milliseconds. * @@ -181,7 +185,7 @@ class NetworkSession{ try{ $payload = $this->cipher->decrypt($payload); }catch(\UnexpectedValueException $e){ - $this->server->getLogger()->debug("Encrypted packet from " . $this->ip . " " . $this->port . ": " . bin2hex($payload)); + $this->server->getLogger()->debug("Encrypted packet from " . $this->getDisplayName() . ": " . bin2hex($payload)); throw new BadPacketException("Packet decryption error: " . $e->getMessage(), 0, $e); }finally{ Timings::$playerNetworkReceiveDecryptTimer->stopTiming(); @@ -192,7 +196,7 @@ class NetworkSession{ try{ $stream = new PacketStream(NetworkCompression::decompress($payload)); }catch(\ErrorException $e){ - $this->server->getLogger()->debug("Failed to decompress packet from " . $this->ip . " " . $this->port . ": " . bin2hex($payload)); + $this->server->getLogger()->debug("Failed to decompress packet from " . $this->getDisplayName() . ": " . bin2hex($payload)); //TODO: this isn't incompatible game version if we already established protocol version throw new BadPacketException("Compressed packet batch decode error (incompatible game version?)", 0, $e); }finally{ @@ -203,7 +207,7 @@ class NetworkSession{ try{ $buf = $stream->getString(); }catch(BinaryDataException $e){ - $this->server->getLogger()->debug("Packet batch from " . $this->ip . " " . $this->port . ": " . bin2hex($stream->getBuffer())); + $this->server->getLogger()->debug("Packet batch from " . $this->getDisplayName() . ": " . bin2hex($stream->getBuffer())); throw new BadPacketException("Packet batch decode error: " . $e->getMessage(), 0, $e); } $this->handleDataPacket(PacketPool::getPacket($buf)); @@ -226,7 +230,7 @@ class NetworkSession{ try{ $packet->decode(); }catch(BadPacketException $e){ - $this->server->getLogger()->debug($packet->getName() . " from " . $this->ip . " " . $this->port . ": " . bin2hex($packet->getBuffer())); + $this->server->getLogger()->debug($packet->getName() . " from " . $this->getDisplayName() . ": " . bin2hex($packet->getBuffer())); throw $e; } if(!$packet->feof() and !$packet->mayHaveUnreadBytes()){ @@ -237,7 +241,7 @@ class NetworkSession{ $ev = new DataPacketReceiveEvent($this->player, $packet); $ev->call(); if(!$ev->isCancelled() and !$packet->handle($this->handler)){ - $this->server->getLogger()->debug("Unhandled " . $packet->getName() . " received from " . $this->player->getName() . ": 0x" . bin2hex($packet->getBuffer())); + $this->server->getLogger()->debug("Unhandled " . $packet->getName() . " received from " . $this->getDisplayName() . ": 0x" . bin2hex($packet->getBuffer())); } $timings->stopTiming(); @@ -393,7 +397,7 @@ class NetworkSession{ $this->cipher = new NetworkCipher($encryptionKey); $this->setHandler(new HandshakeSessionHandler($this)); - $this->server->getLogger()->debug("Enabled encryption for $this->ip $this->port"); + $this->server->getLogger()->debug("Enabled encryption for " . $this->getDisplayName()); } public function onLoginSuccess() : void{ From 467caf347da921c9864ab3931a625b86cfac4f39 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 20 Jan 2019 11:06:47 +0000 Subject: [PATCH 0418/3224] NetworkSession: Consistently don't use 0x prefix --- src/pocketmine/network/mcpe/NetworkSession.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 026e16c876..7ec01b79b7 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -235,13 +235,13 @@ class NetworkSession{ } if(!$packet->feof() and !$packet->mayHaveUnreadBytes()){ $remains = substr($packet->getBuffer(), $packet->getOffset()); - $this->server->getLogger()->debug("Still " . strlen($remains) . " bytes unread in " . $packet->getName() . ": 0x" . bin2hex($remains)); + $this->server->getLogger()->debug("Still " . strlen($remains) . " bytes unread in " . $packet->getName() . ": " . bin2hex($remains)); } $ev = new DataPacketReceiveEvent($this->player, $packet); $ev->call(); if(!$ev->isCancelled() and !$packet->handle($this->handler)){ - $this->server->getLogger()->debug("Unhandled " . $packet->getName() . " received from " . $this->getDisplayName() . ": 0x" . bin2hex($packet->getBuffer())); + $this->server->getLogger()->debug("Unhandled " . $packet->getName() . " received from " . $this->getDisplayName() . ": " . bin2hex($packet->getBuffer())); } $timings->stopTiming(); From d586a18a16cf4bbcd330d3ba72a7acae86ba90f3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 20 Jan 2019 16:57:25 +0000 Subject: [PATCH 0419/3224] Updated BedrockData submodule --- resources/vanilla | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/vanilla b/resources/vanilla index 4b0bcd0e52..b9247957da 160000 --- a/resources/vanilla +++ b/resources/vanilla @@ -1 +1 @@ -Subproject commit 4b0bcd0e52d8802d8692d6c3ade7c2351ddb11b7 +Subproject commit b9247957dad663760f22842836844cfcd4b0c03e From 425ad6101f6761f6f43685ce35e702dbb19be46c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 20 Jan 2019 18:09:47 +0000 Subject: [PATCH 0420/3224] Block: rename onEntityCollide() -> onEntityInside() this better describes what the hook is for. --- src/pocketmine/block/Block.php | 5 ++++- src/pocketmine/block/Cactus.php | 2 +- src/pocketmine/block/Cobweb.php | 2 +- src/pocketmine/block/Fire.php | 2 +- src/pocketmine/block/Ladder.php | 2 +- src/pocketmine/block/Lava.php | 2 +- src/pocketmine/block/Magma.php | 2 +- src/pocketmine/block/TNT.php | 2 +- src/pocketmine/block/Vine.php | 2 +- src/pocketmine/block/Water.php | 2 +- src/pocketmine/entity/Entity.php | 2 +- 11 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index d02b7b6238..faf41bda6d 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -705,9 +705,12 @@ class Block extends Position implements BlockIds, Metadatable{ } /** + * Called when an entity's bounding box clips inside this block's cell. Note that the entity may not be intersecting + * with the collision box or bounding box. + * * @param Entity $entity */ - public function onEntityCollide(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : void{ } diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index d7338b9f6a..059129e019 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -74,7 +74,7 @@ class Cactus extends Transparent{ return AxisAlignedBB::one()->contract($shrinkSize, 0, $shrinkSize)->trim(Facing::UP, $shrinkSize); } - public function onEntityCollide(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : void{ $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_CONTACT, 1); $entity->attack($ev); } diff --git a/src/pocketmine/block/Cobweb.php b/src/pocketmine/block/Cobweb.php index cdffe07da2..4f424b3485 100644 --- a/src/pocketmine/block/Cobweb.php +++ b/src/pocketmine/block/Cobweb.php @@ -55,7 +55,7 @@ class Cobweb extends Flowable{ return 1; } - public function onEntityCollide(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : void{ $entity->resetFallDistance(); } diff --git a/src/pocketmine/block/Fire.php b/src/pocketmine/block/Fire.php index 3b66814965..cae80261ae 100644 --- a/src/pocketmine/block/Fire.php +++ b/src/pocketmine/block/Fire.php @@ -78,7 +78,7 @@ class Fire extends Flowable{ return true; } - public function onEntityCollide(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : void{ $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1); $entity->attack($ev); diff --git a/src/pocketmine/block/Ladder.php b/src/pocketmine/block/Ladder.php index 0579b7e3c2..ab6fb62689 100644 --- a/src/pocketmine/block/Ladder.php +++ b/src/pocketmine/block/Ladder.php @@ -74,7 +74,7 @@ class Ladder extends Transparent{ return true; } - public function onEntityCollide(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : void{ $entity->resetFallDistance(); $entity->onGround = true; } diff --git a/src/pocketmine/block/Lava.php b/src/pocketmine/block/Lava.php index 7e57418d11..2221d87cb2 100644 --- a/src/pocketmine/block/Lava.php +++ b/src/pocketmine/block/Lava.php @@ -86,7 +86,7 @@ class Lava extends Liquid{ } } - public function onEntityCollide(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : void{ $entity->fallDistance *= 0.5; $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_LAVA, 4); diff --git a/src/pocketmine/block/Magma.php b/src/pocketmine/block/Magma.php index 4a83750a68..d246a4969c 100644 --- a/src/pocketmine/block/Magma.php +++ b/src/pocketmine/block/Magma.php @@ -60,7 +60,7 @@ class Magma extends Solid{ return true; } - public function onEntityCollide(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : void{ if(!$entity->isSneaking()){ $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1); $entity->attack($ev); diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index 773592452e..76421375b8 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -66,7 +66,7 @@ class TNT extends Solid{ return true; } - public function onEntityCollide(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : void{ if($entity instanceof Arrow and $entity->isOnFire()){ $this->ignite(); } diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index d40a768247..7247264464 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -93,7 +93,7 @@ class Vine extends Flowable{ return true; } - public function onEntityCollide(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : void{ $entity->resetFallDistance(); } diff --git a/src/pocketmine/block/Water.php b/src/pocketmine/block/Water.php index 948386c371..961adb482c 100644 --- a/src/pocketmine/block/Water.php +++ b/src/pocketmine/block/Water.php @@ -48,7 +48,7 @@ class Water extends Liquid{ return 5; } - public function onEntityCollide(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : void{ $entity->resetFallDistance(); if($entity->isOnFire()){ $entity->extinguish(); diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 2b0977652e..340af4f303 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -1548,7 +1548,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $vector = $this->temporalVector->setComponents(0, 0, 0); foreach($this->getBlocksAround() as $block){ - $block->onEntityCollide($this); + $block->onEntityInside($this); $block->addVelocityToEntity($this, $vector); } From 4ae6428641b7c6172947246fbc62510253131b8b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 20 Jan 2019 18:11:20 +0000 Subject: [PATCH 0421/3224] Level: rename getCollisionCubes() -> getCollisionBoxes() these aren't cubes! shoghi, please read the dictionary. --- src/pocketmine/entity/Entity.php | 6 +++--- src/pocketmine/level/Level.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 340af4f303..1c77a10a75 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -1075,7 +1075,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } protected function checkObstruction(float $x, float $y, float $z) : bool{ - if(count($this->level->getCollisionCubes($this, $this->getBoundingBox(), false)) === 0){ + if(count($this->level->getCollisionBoxes($this, $this->getBoundingBox(), false)) === 0){ return false; } @@ -1405,7 +1405,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ assert(abs($dx) <= 20 and abs($dy) <= 20 and abs($dz) <= 20, "Movement distance is excessive: dx=$dx, dy=$dy, dz=$dz"); - $list = $this->level->getCollisionCubes($this, $this->level->getTickRate() > 1 ? $this->boundingBox->offsetCopy($dx, $dy, $dz) : $this->boundingBox->addCoord($dx, $dy, $dz), false); + $list = $this->level->getCollisionBoxes($this, $this->level->getTickRate() > 1 ? $this->boundingBox->offsetCopy($dx, $dy, $dz) : $this->boundingBox->addCoord($dx, $dy, $dz), false); foreach($list as $bb){ $dy = $bb->calculateYOffset($this->boundingBox, $dy); @@ -1440,7 +1440,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->boundingBox->setBB($axisalignedbb); - $list = $this->level->getCollisionCubes($this, $this->boundingBox->addCoord($dx, $dy, $dz), false); + $list = $this->level->getCollisionBoxes($this, $this->boundingBox->addCoord($dx, $dy, $dz), false); foreach($list as $bb){ $dy = $bb->calculateYOffset($this->boundingBox, $dy); diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 37876bb680..74104039bd 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1165,7 +1165,7 @@ class Level implements ChunkManager, Metadatable{ * * @return AxisAlignedBB[] */ - public function getCollisionCubes(Entity $entity, AxisAlignedBB $bb, bool $entities = true) : array{ + public function getCollisionBoxes(Entity $entity, AxisAlignedBB $bb, bool $entities = true) : array{ $minX = (int) floor($bb->minX - 1); $minY = (int) floor($bb->minY - 1); $minZ = (int) floor($bb->minZ - 1); From 053defb7dc4dc3f15f6076258516c395d1ff0481 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 21 Jan 2019 14:19:15 +0000 Subject: [PATCH 0422/3224] Updated RakLib dependency --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 32dade4095..5fa1e59ecf 100644 --- a/composer.lock +++ b/composer.lock @@ -413,12 +413,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "caffc9bcce765c78d4464b4f6852e3981b81b752" + "reference": "ceee20a6755e33132621fba4e5f21fccb317f73e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/caffc9bcce765c78d4464b4f6852e3981b81b752", - "reference": "caffc9bcce765c78d4464b4f6852e3981b81b752", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/ceee20a6755e33132621fba4e5f21fccb317f73e", + "reference": "ceee20a6755e33132621fba4e5f21fccb317f73e", "shasum": "" }, "require": { @@ -446,7 +446,7 @@ "source": "https://github.com/pmmp/RakLib/tree/master", "issues": "https://github.com/pmmp/RakLib/issues" }, - "time": "2019-01-17T19:13:53+00:00" + "time": "2019-01-21T14:17:51+00:00" }, { "name": "pocketmine/snooze", From 48a99937b9556d0b04121d58ea45dce994d88633 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 22 Jan 2019 13:37:46 +0000 Subject: [PATCH 0423/3224] more exception handling cleanup --- src/pocketmine/Server.php | 6 +++--- src/pocketmine/network/rcon/RCON.php | 11 ++++++++++- src/pocketmine/network/upnp/UPnP.php | 29 +++++++++++++++++++--------- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 235b276bfc..d8d6ddc366 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -701,7 +701,7 @@ class Server{ $nbt = new BigEndianNbtSerializer(); try{ file_put_contents($this->getDataPath() . "players/" . strtolower($name) . ".dat", $nbt->writeCompressed($ev->getSaveData())); - }catch(\Throwable $e){ + }catch(\ErrorException $e){ $this->logger->critical($this->getLanguage()->translateString("pocketmine.data.saveError", [$name, $e->getMessage()])); $this->logger->logException($e); } @@ -1200,7 +1200,7 @@ class Server{ $this->getIp(), $this->getConfigInt("rcon.max-clients", 50) ); - }catch(\Exception $e){ + }catch(\RuntimeException $e){ $this->getLogger()->critical("RCON can't be started: " . $e->getMessage()); } } @@ -1782,7 +1782,7 @@ class Server{ $this->logger->info("[UPnP] Trying to port forward..."); try{ UPnP::PortForward($this->getPort()); - }catch(\Exception $e){ + }catch(\RuntimeException $e){ $this->logger->alert("UPnP portforward failed: " . $e->getMessage()); } } diff --git a/src/pocketmine/network/rcon/RCON.php b/src/pocketmine/network/rcon/RCON.php index ffcf1214b5..09aa4be249 100644 --- a/src/pocketmine/network/rcon/RCON.php +++ b/src/pocketmine/network/rcon/RCON.php @@ -64,11 +64,20 @@ class RCON{ /** @var resource */ private $ipcThreadSocket; + /** + * @param Server $server + * @param string $password + * @param int $port + * @param string $interface + * @param int $maxClients + * + * @throws \RuntimeException + */ public function __construct(Server $server, string $password, int $port = 19132, string $interface = "0.0.0.0", int $maxClients = 50){ $this->server = $server; $this->server->getLogger()->info("Starting remote control listener"); if($password === ""){ - throw new \InvalidArgumentException("Empty password"); + throw new \RuntimeException("Empty password"); } $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); diff --git a/src/pocketmine/network/upnp/UPnP.php b/src/pocketmine/network/upnp/UPnP.php index aa9c3a7334..35b19a0337 100644 --- a/src/pocketmine/network/upnp/UPnP.php +++ b/src/pocketmine/network/upnp/UPnP.php @@ -35,6 +35,11 @@ use function trim; abstract class UPnP{ + /** + * @param int $port + * + * @throws \RuntimeException + */ public static function PortForward(int $port) : void{ if(!Internet::$online){ throw new \RuntimeException("Server is offline"); @@ -56,8 +61,12 @@ abstract class UPnP{ throw new \RuntimeException("Failed to portforward using UPnP. Ensure that network discovery is enabled in Control Panel."); } - /** @noinspection PhpUndefinedFieldInspection */ - $com->StaticPortMappingCollection->Add($port, "UDP", $port, $myLocalIP, true, "PocketMine-MP"); + try{ + /** @noinspection PhpUndefinedFieldInspection */ + $com->StaticPortMappingCollection->Add($port, "UDP", $port, $myLocalIP, true, "PocketMine-MP"); + }catch(\com_exception $e){ + throw new \RuntimeException($e->getMessage(), 0, $e); + } } public static function RemovePortForward(int $port) : bool{ @@ -68,16 +77,18 @@ abstract class UPnP{ return false; } + /** @noinspection PhpUndefinedClassInspection */ + $com = new \COM("HNetCfg.NATUPnP"); + /** @noinspection PhpUndefinedFieldInspection */ + if($com === false or !is_object($com->StaticPortMappingCollection)){ + return false; + } + try{ - /** @noinspection PhpUndefinedClassInspection */ - $com = new \COM("HNetCfg.NATUPnP"); - /** @noinspection PhpUndefinedFieldInspection */ - if($com === false or !is_object($com->StaticPortMappingCollection)){ - return false; - } /** @noinspection PhpUndefinedFieldInspection */ $com->StaticPortMappingCollection->Remove($port, "UDP"); - }catch(\Throwable $e){ + }catch(\com_exception $e){ + //TODO: should this really be silenced? return false; } From 1ebc101ded143fbdeb3bdf1e87351b1a8f420eb8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 22 Jan 2019 13:38:50 +0000 Subject: [PATCH 0424/3224] fixed crash on dev build self-shutdown --- src/pocketmine/Server.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index d8d6ddc366..ba197174cc 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1710,9 +1710,11 @@ class Server{ $player->close($player->getLeaveMessage(), $this->getProperty("settings.shutdown-message", "Server closed")); } - $this->getLogger()->debug("Unloading all levels"); - foreach($this->levelManager->getLevels() as $level){ - $this->levelManager->unloadLevel($level, true); + if($this->levelManager instanceof LevelManager){ + $this->getLogger()->debug("Unloading all levels"); + foreach($this->levelManager->getLevels() as $level){ + $this->levelManager->unloadLevel($level, true); + } } $this->getLogger()->debug("Removing event handlers"); From 17fee801e6acd8cf7fbbda24a54819a54553e050 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 22 Jan 2019 13:43:55 +0000 Subject: [PATCH 0425/3224] RCON: remove unnecessary function --- src/pocketmine/network/rcon/RCON.php | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/pocketmine/network/rcon/RCON.php b/src/pocketmine/network/rcon/RCON.php index 09aa4be249..d911aad458 100644 --- a/src/pocketmine/network/rcon/RCON.php +++ b/src/pocketmine/network/rcon/RCON.php @@ -100,7 +100,13 @@ class RCON{ $notifier = new SleeperNotifier(); $this->server->getTickSleeper()->addNotifier($notifier, function() : void{ - $this->check(); + $response = new RemoteConsoleCommandSender(); + $this->server->dispatchCommand($response, $this->instance->cmd); + + $this->instance->response = TextFormat::clean($response->getMessage()); + $this->instance->synchronized(function(RCONInstance $thread){ + $thread->notify(); + }, $this->instance); }); $this->instance = new RCONInstance($this->socket, $password, (int) max(1, $maxClients), $this->server->getLogger(), $this->ipcThreadSocket, $notifier); @@ -117,14 +123,4 @@ class RCON{ @socket_close($this->ipcMainSocket); @socket_close($this->ipcThreadSocket); } - - public function check() : void{ - $response = new RemoteConsoleCommandSender(); - $this->server->dispatchCommand($response, $this->instance->cmd); - - $this->instance->response = TextFormat::clean($response->getMessage()); - $this->instance->synchronized(function(RCONInstance $thread){ - $thread->notify(); - }, $this->instance); - } } From 23a18a8eb60a1a71984f04bcc27113b69e08610e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 23 Jan 2019 12:10:24 +0000 Subject: [PATCH 0426/3224] Convert Sound into interface --- src/pocketmine/level/sound/LevelEventSound.php | 2 +- src/pocketmine/level/sound/Sound.php | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/level/sound/LevelEventSound.php b/src/pocketmine/level/sound/LevelEventSound.php index 615c238ef0..710567fa40 100644 --- a/src/pocketmine/level/sound/LevelEventSound.php +++ b/src/pocketmine/level/sound/LevelEventSound.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; /** * @internal */ -abstract class LevelEventSound extends Sound{ +abstract class LevelEventSound implements Sound{ /** @var float */ protected $pitch = 0; diff --git a/src/pocketmine/level/sound/Sound.php b/src/pocketmine/level/sound/Sound.php index 20b7533ae3..83f1ff4435 100644 --- a/src/pocketmine/level/sound/Sound.php +++ b/src/pocketmine/level/sound/Sound.php @@ -26,13 +26,12 @@ namespace pocketmine\level\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\ClientboundPacket; -abstract class Sound{ +interface Sound{ /** * @param Vector3 $pos * * @return ClientboundPacket|ClientboundPacket[] */ - abstract public function encode(Vector3 $pos); - + public function encode(Vector3 $pos); } From d2284d5c47926a2ab831dee7ef4c6256e8043476 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 23 Jan 2019 12:16:01 +0000 Subject: [PATCH 0427/3224] Move Particle IDs to protocol namespace --- .../level/particle/AngryVillagerParticle.php | 4 +- .../particle/BlockForceFieldParticle.php | 4 +- .../level/particle/BubbleParticle.php | 4 +- .../level/particle/CriticalParticle.php | 4 +- .../level/particle/DustParticle.php | 4 +- .../level/particle/EnchantParticle.php | 4 +- .../particle/EnchantmentTableParticle.php | 4 +- .../level/particle/EntityFlameParticle.php | 4 +- .../level/particle/ExplodeParticle.php | 4 +- .../level/particle/FlameParticle.php | 4 +- .../level/particle/HappyVillagerParticle.php | 4 +- .../level/particle/HeartParticle.php | 4 +- .../level/particle/HugeExplodeParticle.php | 4 +- .../particle/HugeExplodeSeedParticle.php | 4 +- src/pocketmine/level/particle/InkParticle.php | 4 +- .../level/particle/InstantEnchantParticle.php | 4 +- .../level/particle/ItemBreakParticle.php | 3 +- .../level/particle/LavaDripParticle.php | 4 +- .../level/particle/LavaParticle.php | 4 +- src/pocketmine/level/particle/Particle.php | 55 ------------- .../level/particle/PortalParticle.php | 4 +- .../level/particle/RainSplashParticle.php | 4 +- .../level/particle/RedstoneParticle.php | 4 +- .../level/particle/SmokeParticle.php | 4 +- .../level/particle/SnowballPoofParticle.php | 4 +- .../level/particle/SplashParticle.php | 4 +- .../level/particle/SporeParticle.php | 4 +- .../level/particle/TerrainParticle.php | 3 +- .../level/particle/WaterDripParticle.php | 4 +- .../level/particle/WaterParticle.php | 4 +- .../mcpe/protocol/types/ParticleIds.php | 81 +++++++++++++++++++ 31 files changed, 166 insertions(+), 84 deletions(-) create mode 100644 src/pocketmine/network/mcpe/protocol/types/ParticleIds.php diff --git a/src/pocketmine/level/particle/AngryVillagerParticle.php b/src/pocketmine/level/particle/AngryVillagerParticle.php index acde51b426..5841170c89 100644 --- a/src/pocketmine/level/particle/AngryVillagerParticle.php +++ b/src/pocketmine/level/particle/AngryVillagerParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class AngryVillagerParticle extends GenericParticle{ public function __construct(){ - parent::__construct(Particle::TYPE_VILLAGER_ANGRY); + parent::__construct(ParticleIds::VILLAGER_ANGRY); } } diff --git a/src/pocketmine/level/particle/BlockForceFieldParticle.php b/src/pocketmine/level/particle/BlockForceFieldParticle.php index 312ff5c753..2da0a9aa60 100644 --- a/src/pocketmine/level/particle/BlockForceFieldParticle.php +++ b/src/pocketmine/level/particle/BlockForceFieldParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class BlockForceFieldParticle extends GenericParticle{ public function __construct(int $data = 0){ - parent::__construct(Particle::TYPE_BLOCK_FORCE_FIELD, $data); //TODO: proper encode/decode of data + parent::__construct(ParticleIds::BLOCK_FORCE_FIELD, $data); //TODO: proper encode/decode of data } } diff --git a/src/pocketmine/level/particle/BubbleParticle.php b/src/pocketmine/level/particle/BubbleParticle.php index 6bf00072a2..777eade96a 100644 --- a/src/pocketmine/level/particle/BubbleParticle.php +++ b/src/pocketmine/level/particle/BubbleParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class BubbleParticle extends GenericParticle{ public function __construct(){ - parent::__construct(Particle::TYPE_BUBBLE); + parent::__construct(ParticleIds::BUBBLE); } } diff --git a/src/pocketmine/level/particle/CriticalParticle.php b/src/pocketmine/level/particle/CriticalParticle.php index 4943527c25..17e7ca1284 100644 --- a/src/pocketmine/level/particle/CriticalParticle.php +++ b/src/pocketmine/level/particle/CriticalParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class CriticalParticle extends GenericParticle{ public function __construct(int $scale = 2){ - parent::__construct(Particle::TYPE_CRITICAL, $scale); + parent::__construct(ParticleIds::CRITICAL, $scale); } } diff --git a/src/pocketmine/level/particle/DustParticle.php b/src/pocketmine/level/particle/DustParticle.php index dda464285a..bd3b40d142 100644 --- a/src/pocketmine/level/particle/DustParticle.php +++ b/src/pocketmine/level/particle/DustParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class DustParticle extends GenericParticle{ public function __construct(int $r, int $g, int $b, int $a = 255){ - parent::__construct(Particle::TYPE_DUST, (($a & 0xff) << 24) | (($r & 0xff) << 16) | (($g & 0xff) << 8) | ($b & 0xff)); + parent::__construct(ParticleIds::DUST, (($a & 0xff) << 24) | (($r & 0xff) << 16) | (($g & 0xff) << 8) | ($b & 0xff)); } } diff --git a/src/pocketmine/level/particle/EnchantParticle.php b/src/pocketmine/level/particle/EnchantParticle.php index 4fc625cd41..5be274b692 100644 --- a/src/pocketmine/level/particle/EnchantParticle.php +++ b/src/pocketmine/level/particle/EnchantParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class EnchantParticle extends GenericParticle{ public function __construct(){ - parent::__construct(Particle::TYPE_MOB_SPELL); + parent::__construct(ParticleIds::MOB_SPELL); } } diff --git a/src/pocketmine/level/particle/EnchantmentTableParticle.php b/src/pocketmine/level/particle/EnchantmentTableParticle.php index a0756e2ad0..bd6e288dbf 100644 --- a/src/pocketmine/level/particle/EnchantmentTableParticle.php +++ b/src/pocketmine/level/particle/EnchantmentTableParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class EnchantmentTableParticle extends GenericParticle{ public function __construct(){ - parent::__construct(Particle::TYPE_ENCHANTMENT_TABLE); + parent::__construct(ParticleIds::ENCHANTMENT_TABLE); } } diff --git a/src/pocketmine/level/particle/EntityFlameParticle.php b/src/pocketmine/level/particle/EntityFlameParticle.php index 234da00523..e3a94c53c8 100644 --- a/src/pocketmine/level/particle/EntityFlameParticle.php +++ b/src/pocketmine/level/particle/EntityFlameParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class EntityFlameParticle extends GenericParticle{ public function __construct(){ - parent::__construct(Particle::TYPE_MOB_FLAME); + parent::__construct(ParticleIds::MOB_FLAME); } } diff --git a/src/pocketmine/level/particle/ExplodeParticle.php b/src/pocketmine/level/particle/ExplodeParticle.php index 86ef3bb25a..962f576550 100644 --- a/src/pocketmine/level/particle/ExplodeParticle.php +++ b/src/pocketmine/level/particle/ExplodeParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class ExplodeParticle extends GenericParticle{ public function __construct(){ - parent::__construct(Particle::TYPE_EXPLODE); + parent::__construct(ParticleIds::EXPLODE); } } diff --git a/src/pocketmine/level/particle/FlameParticle.php b/src/pocketmine/level/particle/FlameParticle.php index aa69de17b1..41a6433192 100644 --- a/src/pocketmine/level/particle/FlameParticle.php +++ b/src/pocketmine/level/particle/FlameParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class FlameParticle extends GenericParticle{ public function __construct(){ - parent::__construct(Particle::TYPE_FLAME); + parent::__construct(ParticleIds::FLAME); } } diff --git a/src/pocketmine/level/particle/HappyVillagerParticle.php b/src/pocketmine/level/particle/HappyVillagerParticle.php index 007478e6e5..71ce2d6b67 100644 --- a/src/pocketmine/level/particle/HappyVillagerParticle.php +++ b/src/pocketmine/level/particle/HappyVillagerParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class HappyVillagerParticle extends GenericParticle{ public function __construct(){ - parent::__construct(Particle::TYPE_VILLAGER_HAPPY); + parent::__construct(ParticleIds::VILLAGER_HAPPY); } } diff --git a/src/pocketmine/level/particle/HeartParticle.php b/src/pocketmine/level/particle/HeartParticle.php index 66d6bb0a00..dc196ca3b4 100644 --- a/src/pocketmine/level/particle/HeartParticle.php +++ b/src/pocketmine/level/particle/HeartParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class HeartParticle extends GenericParticle{ public function __construct(int $scale = 0){ - parent::__construct(Particle::TYPE_HEART, $scale); + parent::__construct(ParticleIds::HEART, $scale); } } diff --git a/src/pocketmine/level/particle/HugeExplodeParticle.php b/src/pocketmine/level/particle/HugeExplodeParticle.php index 4cb5915175..26f80fc759 100644 --- a/src/pocketmine/level/particle/HugeExplodeParticle.php +++ b/src/pocketmine/level/particle/HugeExplodeParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class HugeExplodeParticle extends GenericParticle{ public function __construct(){ - parent::__construct(Particle::TYPE_HUGE_EXPLODE); + parent::__construct(ParticleIds::HUGE_EXPLODE); } } diff --git a/src/pocketmine/level/particle/HugeExplodeSeedParticle.php b/src/pocketmine/level/particle/HugeExplodeSeedParticle.php index c8a495f750..409d08a2ec 100644 --- a/src/pocketmine/level/particle/HugeExplodeSeedParticle.php +++ b/src/pocketmine/level/particle/HugeExplodeSeedParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class HugeExplodeSeedParticle extends GenericParticle{ public function __construct(){ - parent::__construct(Particle::TYPE_HUGE_EXPLODE_SEED); + parent::__construct(ParticleIds::HUGE_EXPLODE_SEED); } } diff --git a/src/pocketmine/level/particle/InkParticle.php b/src/pocketmine/level/particle/InkParticle.php index 37aa82682f..7a6e8d6af7 100644 --- a/src/pocketmine/level/particle/InkParticle.php +++ b/src/pocketmine/level/particle/InkParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class InkParticle extends GenericParticle{ public function __construct(int $scale = 0){ - parent::__construct(Particle::TYPE_INK, $scale); + parent::__construct(ParticleIds::INK, $scale); } } diff --git a/src/pocketmine/level/particle/InstantEnchantParticle.php b/src/pocketmine/level/particle/InstantEnchantParticle.php index ed69f3c4b8..da58d16960 100644 --- a/src/pocketmine/level/particle/InstantEnchantParticle.php +++ b/src/pocketmine/level/particle/InstantEnchantParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class InstantEnchantParticle extends GenericParticle{ public function __construct(){ - parent::__construct(Particle::TYPE_MOB_SPELL_INSTANTANEOUS); + parent::__construct(ParticleIds::MOB_SPELL_INSTANTANEOUS); } } diff --git a/src/pocketmine/level/particle/ItemBreakParticle.php b/src/pocketmine/level/particle/ItemBreakParticle.php index 1d4146741c..0baffed371 100644 --- a/src/pocketmine/level/particle/ItemBreakParticle.php +++ b/src/pocketmine/level/particle/ItemBreakParticle.php @@ -24,9 +24,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; use pocketmine\item\Item; +use pocketmine\network\mcpe\protocol\types\ParticleIds; class ItemBreakParticle extends GenericParticle{ public function __construct(Item $item){ - parent::__construct(Particle::TYPE_ITEM_BREAK, ($item->getId() << 16) | $item->getDamage()); + parent::__construct(ParticleIds::ITEM_BREAK, ($item->getId() << 16) | $item->getDamage()); } } diff --git a/src/pocketmine/level/particle/LavaDripParticle.php b/src/pocketmine/level/particle/LavaDripParticle.php index 738a01da5d..6ca209e0b8 100644 --- a/src/pocketmine/level/particle/LavaDripParticle.php +++ b/src/pocketmine/level/particle/LavaDripParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class LavaDripParticle extends GenericParticle{ public function __construct(){ - parent::__construct(Particle::TYPE_DRIP_LAVA); + parent::__construct(ParticleIds::DRIP_LAVA); } } diff --git a/src/pocketmine/level/particle/LavaParticle.php b/src/pocketmine/level/particle/LavaParticle.php index f59210c986..9a3e65e66f 100644 --- a/src/pocketmine/level/particle/LavaParticle.php +++ b/src/pocketmine/level/particle/LavaParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class LavaParticle extends GenericParticle{ public function __construct(){ - parent::__construct(Particle::TYPE_LAVA); + parent::__construct(ParticleIds::LAVA); } } diff --git a/src/pocketmine/level/particle/Particle.php b/src/pocketmine/level/particle/Particle.php index ccf97d35bf..91c3c32532 100644 --- a/src/pocketmine/level/particle/Particle.php +++ b/src/pocketmine/level/particle/Particle.php @@ -28,61 +28,6 @@ use pocketmine\network\mcpe\protocol\ClientboundPacket; abstract class Particle{ - public const TYPE_BUBBLE = 1; - public const TYPE_CRITICAL = 2; - public const TYPE_BLOCK_FORCE_FIELD = 3; - public const TYPE_SMOKE = 4; - public const TYPE_EXPLODE = 5; - public const TYPE_EVAPORATION = 6; - public const TYPE_FLAME = 7; - public const TYPE_LAVA = 8; - public const TYPE_LARGE_SMOKE = 9; - public const TYPE_REDSTONE = 10; - public const TYPE_RISING_RED_DUST = 11; - public const TYPE_ITEM_BREAK = 12; - public const TYPE_SNOWBALL_POOF = 13; - public const TYPE_HUGE_EXPLODE = 14; - public const TYPE_HUGE_EXPLODE_SEED = 15; - public const TYPE_MOB_FLAME = 16; - public const TYPE_HEART = 17; - public const TYPE_TERRAIN = 18; - public const TYPE_SUSPENDED_TOWN = 19, TYPE_TOWN_AURA = 19; - public const TYPE_PORTAL = 20; - public const TYPE_SPLASH = 21, TYPE_WATER_SPLASH = 21; - public const TYPE_WATER_WAKE = 22; - public const TYPE_DRIP_WATER = 23; - public const TYPE_DRIP_LAVA = 24; - public const TYPE_FALLING_DUST = 25, TYPE_DUST = 25; - public const TYPE_MOB_SPELL = 26; - public const TYPE_MOB_SPELL_AMBIENT = 27; - public const TYPE_MOB_SPELL_INSTANTANEOUS = 28; - public const TYPE_INK = 29; - public const TYPE_SLIME = 30; - public const TYPE_RAIN_SPLASH = 31; - public const TYPE_VILLAGER_ANGRY = 32; - public const TYPE_VILLAGER_HAPPY = 33; - public const TYPE_ENCHANTMENT_TABLE = 34; - public const TYPE_TRACKING_EMITTER = 35; - public const TYPE_NOTE = 36; - public const TYPE_WITCH_SPELL = 37; - public const TYPE_CARROT = 38; - //39 unknown - public const TYPE_END_ROD = 40; - public const TYPE_DRAGONS_BREATH = 41; - public const TYPE_SPIT = 42; - public const TYPE_TOTEM = 43; - public const TYPE_FOOD = 44; - public const TYPE_FIREWORKS_STARTER = 45; - public const TYPE_FIREWORKS_SPARK = 46; - public const TYPE_FIREWORKS_OVERLAY = 47; - public const TYPE_BALLOON_GAS = 48; - public const TYPE_COLORED_FLAME = 49; - public const TYPE_SPARKLER = 50; - public const TYPE_CONDUIT = 51; - public const TYPE_BUBBLE_COLUMN_UP = 52; - public const TYPE_BUBBLE_COLUMN_DOWN = 53; - public const TYPE_SNEEZE = 54; - /** * @param Vector3 $pos * diff --git a/src/pocketmine/level/particle/PortalParticle.php b/src/pocketmine/level/particle/PortalParticle.php index e04898146a..9175d3a6ba 100644 --- a/src/pocketmine/level/particle/PortalParticle.php +++ b/src/pocketmine/level/particle/PortalParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class PortalParticle extends GenericParticle{ public function __construct(){ - parent::__construct(Particle::TYPE_PORTAL); + parent::__construct(ParticleIds::PORTAL); } } diff --git a/src/pocketmine/level/particle/RainSplashParticle.php b/src/pocketmine/level/particle/RainSplashParticle.php index 67e7977ae1..20ca50ec0f 100644 --- a/src/pocketmine/level/particle/RainSplashParticle.php +++ b/src/pocketmine/level/particle/RainSplashParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class RainSplashParticle extends GenericParticle{ public function __construct(){ - parent::__construct(Particle::TYPE_RAIN_SPLASH); + parent::__construct(ParticleIds::RAIN_SPLASH); } } diff --git a/src/pocketmine/level/particle/RedstoneParticle.php b/src/pocketmine/level/particle/RedstoneParticle.php index 7516e77b6d..15b464e4bf 100644 --- a/src/pocketmine/level/particle/RedstoneParticle.php +++ b/src/pocketmine/level/particle/RedstoneParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class RedstoneParticle extends GenericParticle{ public function __construct(int $lifetime = 1){ - parent::__construct(Particle::TYPE_REDSTONE, $lifetime); + parent::__construct(ParticleIds::REDSTONE, $lifetime); } } diff --git a/src/pocketmine/level/particle/SmokeParticle.php b/src/pocketmine/level/particle/SmokeParticle.php index 6092255b5d..f057c5ed5d 100644 --- a/src/pocketmine/level/particle/SmokeParticle.php +++ b/src/pocketmine/level/particle/SmokeParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class SmokeParticle extends GenericParticle{ public function __construct(int $scale = 0){ - parent::__construct(Particle::TYPE_SMOKE, $scale); + parent::__construct(ParticleIds::SMOKE, $scale); } } diff --git a/src/pocketmine/level/particle/SnowballPoofParticle.php b/src/pocketmine/level/particle/SnowballPoofParticle.php index 6e79fa1518..24e8d14c12 100644 --- a/src/pocketmine/level/particle/SnowballPoofParticle.php +++ b/src/pocketmine/level/particle/SnowballPoofParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class SnowballPoofParticle extends GenericParticle{ public function __construct(){ - parent::__construct(self::TYPE_SNOWBALL_POOF, 0); + parent::__construct(ParticleIds::SNOWBALL_POOF, 0); } } diff --git a/src/pocketmine/level/particle/SplashParticle.php b/src/pocketmine/level/particle/SplashParticle.php index 1001076c79..b79e8ee07b 100644 --- a/src/pocketmine/level/particle/SplashParticle.php +++ b/src/pocketmine/level/particle/SplashParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class SplashParticle extends GenericParticle{ public function __construct(){ - parent::__construct(Particle::TYPE_WATER_SPLASH); + parent::__construct(ParticleIds::WATER_SPLASH); } } diff --git a/src/pocketmine/level/particle/SporeParticle.php b/src/pocketmine/level/particle/SporeParticle.php index 883cc24eec..846c7149ef 100644 --- a/src/pocketmine/level/particle/SporeParticle.php +++ b/src/pocketmine/level/particle/SporeParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class SporeParticle extends GenericParticle{ public function __construct(){ - parent::__construct(Particle::TYPE_TOWN_AURA); + parent::__construct(ParticleIds::TOWN_AURA); } } diff --git a/src/pocketmine/level/particle/TerrainParticle.php b/src/pocketmine/level/particle/TerrainParticle.php index c602a82ac3..296934af87 100644 --- a/src/pocketmine/level/particle/TerrainParticle.php +++ b/src/pocketmine/level/particle/TerrainParticle.php @@ -24,9 +24,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; use pocketmine\block\Block; +use pocketmine\network\mcpe\protocol\types\ParticleIds; class TerrainParticle extends GenericParticle{ public function __construct(Block $b){ - parent::__construct(Particle::TYPE_TERRAIN, $b->getRuntimeId()); + parent::__construct(ParticleIds::TERRAIN, $b->getRuntimeId()); } } diff --git a/src/pocketmine/level/particle/WaterDripParticle.php b/src/pocketmine/level/particle/WaterDripParticle.php index 0aa04d79fa..6a8431fa28 100644 --- a/src/pocketmine/level/particle/WaterDripParticle.php +++ b/src/pocketmine/level/particle/WaterDripParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class WaterDripParticle extends GenericParticle{ public function __construct(){ - parent::__construct(Particle::TYPE_DRIP_WATER); + parent::__construct(ParticleIds::DRIP_WATER); } } diff --git a/src/pocketmine/level/particle/WaterParticle.php b/src/pocketmine/level/particle/WaterParticle.php index 906bbe29a2..fb85ff9d62 100644 --- a/src/pocketmine/level/particle/WaterParticle.php +++ b/src/pocketmine/level/particle/WaterParticle.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\level\particle; +use pocketmine\network\mcpe\protocol\types\ParticleIds; + class WaterParticle extends GenericParticle{ public function __construct(){ - parent::__construct(Particle::TYPE_WATER_WAKE); + parent::__construct(ParticleIds::WATER_WAKE); } } diff --git a/src/pocketmine/network/mcpe/protocol/types/ParticleIds.php b/src/pocketmine/network/mcpe/protocol/types/ParticleIds.php new file mode 100644 index 0000000000..271ddd3a0f --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/ParticleIds.php @@ -0,0 +1,81 @@ + Date: Wed, 23 Jan 2019 12:18:24 +0000 Subject: [PATCH 0428/3224] Convert Particle to interface --- src/pocketmine/level/particle/DestroyBlockParticle.php | 2 +- src/pocketmine/level/particle/FloatingTextParticle.php | 2 +- src/pocketmine/level/particle/GenericParticle.php | 2 +- src/pocketmine/level/particle/MobSpawnParticle.php | 2 +- src/pocketmine/level/particle/Particle.php | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/level/particle/DestroyBlockParticle.php b/src/pocketmine/level/particle/DestroyBlockParticle.php index d7d98548c9..cb278a4ede 100644 --- a/src/pocketmine/level/particle/DestroyBlockParticle.php +++ b/src/pocketmine/level/particle/DestroyBlockParticle.php @@ -27,7 +27,7 @@ use pocketmine\block\Block; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class DestroyBlockParticle extends Particle{ +class DestroyBlockParticle implements Particle{ /** @var int */ protected $data; diff --git a/src/pocketmine/level/particle/FloatingTextParticle.php b/src/pocketmine/level/particle/FloatingTextParticle.php index 727b75cc09..043e4435ca 100644 --- a/src/pocketmine/level/particle/FloatingTextParticle.php +++ b/src/pocketmine/level/particle/FloatingTextParticle.php @@ -36,7 +36,7 @@ use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\utils\UUID; use function str_repeat; -class FloatingTextParticle extends Particle{ +class FloatingTextParticle implements Particle{ //TODO: HACK! protected $text; diff --git a/src/pocketmine/level/particle/GenericParticle.php b/src/pocketmine/level/particle/GenericParticle.php index ad9ee2f28c..2731eaba7a 100644 --- a/src/pocketmine/level/particle/GenericParticle.php +++ b/src/pocketmine/level/particle/GenericParticle.php @@ -26,7 +26,7 @@ namespace pocketmine\level\particle; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class GenericParticle extends Particle{ +class GenericParticle implements Particle{ /** @var int */ protected $id; /** @var int */ diff --git a/src/pocketmine/level/particle/MobSpawnParticle.php b/src/pocketmine/level/particle/MobSpawnParticle.php index 42a7596275..87c971aa5a 100644 --- a/src/pocketmine/level/particle/MobSpawnParticle.php +++ b/src/pocketmine/level/particle/MobSpawnParticle.php @@ -26,7 +26,7 @@ namespace pocketmine\level\particle; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class MobSpawnParticle extends Particle{ +class MobSpawnParticle implements Particle{ /** @var int */ protected $width; /** @var int */ diff --git a/src/pocketmine/level/particle/Particle.php b/src/pocketmine/level/particle/Particle.php index 91c3c32532..ab393ecfd0 100644 --- a/src/pocketmine/level/particle/Particle.php +++ b/src/pocketmine/level/particle/Particle.php @@ -26,13 +26,13 @@ namespace pocketmine\level\particle; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\ClientboundPacket; -abstract class Particle{ +interface Particle{ /** * @param Vector3 $pos * * @return ClientboundPacket|ClientboundPacket[] */ - abstract public function encode(Vector3 $pos); + public function encode(Vector3 $pos); } From 738e310798f5a4742b2dc81a926bd0989e543ee5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 23 Jan 2019 20:39:16 +0000 Subject: [PATCH 0429/3224] Strip out RCON, closes #2686 Users should move to the new RconServer plugin instead. --- src/pocketmine/CrashDump.php | 2 - src/pocketmine/Server.php | 24 -- .../command/RemoteConsoleCommandSender.php | 51 ---- src/pocketmine/network/rcon/RCON.php | 126 --------- src/pocketmine/network/rcon/RCONInstance.php | 267 ------------------ src/pocketmine/wizard/SetupWizard.php | 13 - 6 files changed, 483 deletions(-) delete mode 100644 src/pocketmine/command/RemoteConsoleCommandSender.php delete mode 100644 src/pocketmine/network/rcon/RCON.php delete mode 100644 src/pocketmine/network/rcon/RCONInstance.php diff --git a/src/pocketmine/CrashDump.php b/src/pocketmine/CrashDump.php index 4131a60231..7c9cfeb808 100644 --- a/src/pocketmine/CrashDump.php +++ b/src/pocketmine/CrashDump.php @@ -53,7 +53,6 @@ use function ob_start; use function php_uname; use function phpinfo; use function phpversion; -use function preg_replace; use function str_split; use function strpos; use function substr; @@ -173,7 +172,6 @@ class CrashDump{ if($this->server->getProperty("auto-report.send-settings", true) !== false){ $this->data["parameters"] = (array) $argv; $this->data["server.properties"] = @file_get_contents($this->server->getDataPath() . "server.properties"); - $this->data["server.properties"] = preg_replace("#^rcon\\.password=(.*)$#m", "rcon.password=******", $this->data["server.properties"]); $this->data["pocketmine.yml"] = @file_get_contents($this->server->getDataPath() . "pocketmine.yml"); }else{ $this->data["pocketmine.yml"] = ""; diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index ba197174cc..2ba02af186 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -74,7 +74,6 @@ use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\network\mcpe\RakLibInterface; use pocketmine\network\Network; use pocketmine\network\query\QueryHandler; -use pocketmine\network\rcon\RCON; use pocketmine\network\upnp\UPnP; use pocketmine\permission\BanList; use pocketmine\permission\DefaultPermissions; @@ -143,7 +142,6 @@ use function stripos; use function strlen; use function strrpos; use function strtolower; -use function substr; use function time; use function touch; use function trim; @@ -245,9 +243,6 @@ class Server{ /** @var bool */ private $onlineMode = true; - /** @var RCON */ - private $rcon; - /** @var EntityMetadataStore */ private $entityMetadata; @@ -1087,8 +1082,6 @@ class Server{ "level-seed" => "", "level-type" => "DEFAULT", "enable-query" => true, - "enable-rcon" => false, - "rcon.password" => substr(base64_encode(random_bytes(20)), 3, 10), "auto-save" => true, "view-distance" => 8, "xbox-auth" => true, @@ -1191,20 +1184,6 @@ class Server{ }); $this->console->start(PTHREADS_INHERIT_NONE); - if($this->getConfigBool("enable-rcon", false)){ - try{ - $this->rcon = new RCON( - $this, - $this->getConfigString("rcon.password", ""), - $this->getConfigInt("rcon.port", $this->getPort()), - $this->getIp(), - $this->getConfigInt("rcon.max-clients", 50) - ); - }catch(\RuntimeException $e){ - $this->getLogger()->critical("RCON can't be started: " . $e->getMessage()); - } - } - $this->entityMetadata = new EntityMetadataStore(); $this->playerMetadata = new PlayerMetadataStore(); $this->levelMetadata = new LevelMetadataStore(); @@ -1692,9 +1671,6 @@ class Server{ $this->hasStopped = true; $this->shutdown(); - if($this->rcon instanceof RCON){ - $this->rcon->stop(); - } if($this->getProperty("network.upnp-forwarding", false)){ $this->logger->info("[UPnP] Removing port forward..."); diff --git a/src/pocketmine/command/RemoteConsoleCommandSender.php b/src/pocketmine/command/RemoteConsoleCommandSender.php deleted file mode 100644 index 054d7ad881..0000000000 --- a/src/pocketmine/command/RemoteConsoleCommandSender.php +++ /dev/null @@ -1,51 +0,0 @@ -getServer()->getLanguage()->translate($message); - }else{ - $message = $this->getServer()->getLanguage()->translateString($message); - } - - $this->messages .= trim($message, "\r\n") . "\n"; - } - - public function getMessage(){ - return $this->messages; - } - - public function getName() : string{ - return "Rcon"; - } -} diff --git a/src/pocketmine/network/rcon/RCON.php b/src/pocketmine/network/rcon/RCON.php deleted file mode 100644 index 19aae8c600..0000000000 --- a/src/pocketmine/network/rcon/RCON.php +++ /dev/null @@ -1,126 +0,0 @@ -server = $server; - $this->server->getLogger()->info("Starting remote control listener"); - if($password === ""){ - throw new \RuntimeException("Empty password"); - } - - $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); - - if($this->socket === false or !@socket_bind($this->socket, $interface, $port) or !@socket_listen($this->socket, 5)){ - throw new \RuntimeException(trim(socket_strerror(socket_last_error()))); - } - - socket_set_block($this->socket); - - $ret = @socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $ipc); - if(!$ret){ - $err = socket_last_error(); - if(($err !== SOCKET_EPROTONOSUPPORT and $err !== SOCKET_ENOPROTOOPT) or !@socket_create_pair(AF_INET, SOCK_STREAM, 0, $ipc)){ - throw new \RuntimeException(trim(socket_strerror(socket_last_error()))); - } - } - - [$this->ipcMainSocket, $this->ipcThreadSocket] = $ipc; - - $notifier = new SleeperNotifier(); - $this->server->getTickSleeper()->addNotifier($notifier, function() : void{ - $response = new RemoteConsoleCommandSender(); - $this->server->dispatchCommand($response, $this->instance->cmd); - - $this->instance->response = TextFormat::clean($response->getMessage()); - $this->instance->synchronized(function(RCONInstance $thread){ - $thread->notify(); - }, $this->instance); - }); - $this->instance = new RCONInstance($this->socket, $password, (int) max(1, $maxClients), $this->server->getLogger(), $this->ipcThreadSocket, $notifier); - - socket_getsockname($this->socket, $addr, $port); - $this->server->getLogger()->info("RCON running on $addr:$port"); - } - - public function stop() : void{ - $this->instance->close(); - socket_write($this->ipcMainSocket, "\x00"); //make select() return - $this->instance->quit(); - - @socket_close($this->socket); - @socket_close($this->ipcMainSocket); - @socket_close($this->ipcThreadSocket); - } -} diff --git a/src/pocketmine/network/rcon/RCONInstance.php b/src/pocketmine/network/rcon/RCONInstance.php deleted file mode 100644 index 9b852d1145..0000000000 --- a/src/pocketmine/network/rcon/RCONInstance.php +++ /dev/null @@ -1,267 +0,0 @@ -stop = false; - $this->cmd = ""; - $this->response = ""; - $this->socket = $socket; - $this->password = $password; - $this->maxClients = $maxClients; - $this->logger = $logger; - $this->ipcSocket = $ipcSocket; - $this->notifier = $notifier; - - $this->start(PTHREADS_INHERIT_NONE); - } - - private function writePacket($client, int $requestID, int $packetType, string $payload){ - $pk = Binary::writeLInt($requestID) - . Binary::writeLInt($packetType) - . $payload - . "\x00\x00"; //Terminate payload and packet - return socket_write($client, Binary::writeLInt(strlen($pk)) . $pk); - } - - private function readPacket($client, ?int &$requestID, ?int &$packetType, ?string &$payload){ - $d = @socket_read($client, 4); - - socket_getpeername($client, $ip, $port); - if($d === false){ - $err = socket_last_error($client); - if($err !== SOCKET_ECONNRESET){ - $this->logger->debug("Connection error with $ip $port: " . trim(socket_strerror($err))); - } - return false; - } - if(strlen($d) !== 4){ - if($d !== ""){ //empty data is returned on disconnection - $this->logger->debug("Truncated packet from $ip $port (want 4 bytes, have " . strlen($d) . "), disconnecting"); - } - return false; - } - $size = Binary::readLInt($d); - if($size < 0 or $size > 65535){ - $this->logger->debug("Packet with too-large length header $size from $ip $port, disconnecting"); - return false; - } - $buf = @socket_read($client, $size); - if($buf === false){ - $err = socket_last_error($client); - if($err !== SOCKET_ECONNRESET){ - $this->logger->debug("Connection error with $ip $port: " . trim(socket_strerror($err))); - } - return false; - } - if(strlen($buf) !== $size){ - $this->logger->debug("Truncated packet from $ip $port (want $size bytes, have " . strlen($buf) . "), disconnecting"); - return false; - } - $requestID = Binary::readLInt(substr($buf, 0, 4)); - $packetType = Binary::readLInt(substr($buf, 4, 4)); - $payload = substr($buf, 8, -2); //Strip two null bytes - return true; - } - - public function close() : void{ - $this->stop = true; - } - - public function run() : void{ - $this->registerClassLoader(); - - /** @var resource[] $clients */ - $clients = []; - /** @var int[] $authenticated */ - $authenticated = []; - /** @var float[] $timeouts */ - $timeouts = []; - - /** @var int $nextClientId */ - $nextClientId = 0; - - while(!$this->stop){ - $r = $clients; - $r["main"] = $this->socket; //this is ugly, but we need to be able to mass-select() - $r["ipc"] = $this->ipcSocket; - $w = null; - $e = null; - - $disconnect = []; - - if(socket_select($r, $w, $e, 5, 0) > 0){ - foreach($r as $id => $sock){ - if($sock === $this->socket){ - if(($client = socket_accept($this->socket)) !== false){ - if(count($clients) >= $this->maxClients){ - @socket_close($client); - }else{ - socket_set_nonblock($client); - socket_set_option($client, SOL_SOCKET, SO_KEEPALIVE, 1); - - $id = $nextClientId++; - $clients[$id] = $client; - $authenticated[$id] = false; - $timeouts[$id] = microtime(true) + 5; - } - } - }elseif($sock === $this->ipcSocket){ - //read dummy data - socket_read($sock, 65535); - }else{ - $p = $this->readPacket($sock, $requestID, $packetType, $payload); - if($p === false){ - $disconnect[$id] = $sock; - continue; - }elseif($p === null){ - continue; - } - - switch($packetType){ - case 3: //Login - if($authenticated[$id]){ - $disconnect[$id] = $sock; - break; - } - if($payload === $this->password){ - socket_getpeername($sock, $addr, $port); - $this->logger->info("Successful Rcon connection from: /$addr:$port"); - $this->writePacket($sock, $requestID, 2, ""); - $authenticated[$id] = true; - }else{ - $disconnect[$id] = $sock; - $this->writePacket($sock, -1, 2, ""); - } - break; - case 2: //Command - if(!$authenticated[$id]){ - $disconnect[$id] = $sock; - break; - } - if($payload !== ""){ - $this->cmd = ltrim($payload); - $this->synchronized(function(){ - $this->notifier->wakeupSleeper(); - $this->wait(); - }); - $this->writePacket($sock, $requestID, 0, str_replace("\n", "\r\n", trim($this->response))); - $this->response = ""; - $this->cmd = ""; - } - break; - } - } - } - } - - foreach($authenticated as $id => $status){ - if(!isset($disconnect[$id]) and !$authenticated[$id] and $timeouts[$id] < microtime(true)){ //Timeout - $disconnect[$id] = $clients[$id]; - } - } - - foreach($disconnect as $id => $client){ - $this->disconnectClient($client); - unset($clients[$id], $authenticated[$id], $timeouts[$id]); - } - } - - foreach($clients as $client){ - $this->disconnectClient($client); - } - } - - private function disconnectClient($client) : void{ - socket_getpeername($client, $ip, $port); - @socket_set_option($client, SOL_SOCKET, SO_LINGER, ["l_onoff" => 1, "l_linger" => 1]); - @socket_shutdown($client, 2); - @socket_set_block($client); - @socket_read($client, 1); - @socket_close($client); - $this->logger->info("Disconnected client: /$ip:$port"); - } - - public function getThreadName() : string{ - return "RCON"; - } -} diff --git a/src/pocketmine/wizard/SetupWizard.php b/src/pocketmine/wizard/SetupWizard.php index 548ff372c0..af2356aa89 100644 --- a/src/pocketmine/wizard/SetupWizard.php +++ b/src/pocketmine/wizard/SetupWizard.php @@ -31,13 +31,10 @@ use pocketmine\lang\Language; use pocketmine\lang\LanguageNotFoundException; use pocketmine\utils\Config; use pocketmine\utils\Internet; -use function base64_encode; use function fgets; use function gethostbyname; -use function random_bytes; use function sleep; use function strtolower; -use function substr; use function trim; use const PHP_EOL; use const STDIN; @@ -206,16 +203,6 @@ LICENSE; $config->set("enable-query", true); } - $this->message($this->lang->get("rcon_info")); - if(strtolower($this->getInput($this->lang->get("rcon_enable"), "n", "y/N")) === "y"){ - $config->set("enable-rcon", true); - $password = substr(base64_encode(random_bytes(20)), 3, 10); - $config->set("rcon.password", $password); - $this->message($this->lang->get("rcon_password") . ": " . $password); - }else{ - $config->set("enable-rcon", false); - } - $config->save(); From 469b24b0a541e838cef8d9c03fb900e3fe1f693c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 24 Jan 2019 16:56:15 +0000 Subject: [PATCH 0430/3224] Remove built-in spawn protection Users should use the new BasicSpawnProtection plugin instead. --- src/pocketmine/Player.php | 8 ++--- src/pocketmine/Server.php | 8 ----- src/pocketmine/level/Level.php | 34 ------------------- .../permission/DefaultPermissions.php | 3 -- src/pocketmine/wizard/SetupWizard.php | 8 ----- 5 files changed, 2 insertions(+), 59 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 5ef2da305d..78b091cc7c 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2164,10 +2164,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $target = $this->level->getBlock($pos); $ev = new PlayerInteractEvent($this, $this->inventory->getItemInHand(), $target, null, $face, PlayerInteractEvent::LEFT_CLICK_BLOCK); - if($this->level->checkSpawnProtection($this, $target)){ - $ev->setCancelled(); - } - $ev->call(); if($ev->isCancelled()){ $this->inventory->sendHeldItem($this); @@ -2462,7 +2458,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->doCloseInventory(); $pos = new Vector3($packet->x, $packet->y, $packet->z); - if($pos->distanceSquared($this) > 10000 or $this->level->checkSpawnProtection($this, $pos)){ + if($pos->distanceSquared($this) > 10000){ return true; } @@ -2487,7 +2483,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ if($tile instanceof ItemFrame){ //TODO: use facing blockstate property instead of damage value $ev = new PlayerInteractEvent($this, $this->inventory->getItemInHand(), $tile->getBlock(), null, 5 - $tile->getBlock()->getDamage(), PlayerInteractEvent::LEFT_CLICK_BLOCK); - if($this->isSpectator() or $this->level->checkSpawnProtection($this, $tile)){ + if($this->isSpectator()){ $ev->setCancelled(); } diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 2ba02af186..2104298ea7 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -455,13 +455,6 @@ class Server{ return $this->getConfigBool("white-list", false); } - /** - * @return int - */ - public function getSpawnRadius() : int{ - return $this->getConfigInt("spawn-protection", 16); - } - /** * @return bool */ @@ -1070,7 +1063,6 @@ class Server{ "server-port" => 19132, "white-list" => false, "announce-player-achievements" => true, - "spawn-protection" => 16, "max-players" => 20, "gamemode" => 0, "force-gamemode" => false, diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 74104039bd..beb1c68e3e 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -63,7 +63,6 @@ use pocketmine\level\particle\DestroyBlockParticle; use pocketmine\level\particle\Particle; use pocketmine\level\sound\Sound; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Vector2; use pocketmine\math\Vector3; use pocketmine\metadata\BlockMetadataStore; use pocketmine\metadata\Metadatable; @@ -1623,29 +1622,6 @@ class Level implements ChunkManager, Metadatable{ return $orbs; } - /** - * Checks if the level spawn protection radius will prevent the player from using items or building at the specified - * Vector3 position. - * - * @param Player $player - * @param Vector3 $vector - * - * @return bool true if spawn protection cancelled the action, false if not. - */ - public function checkSpawnProtection(Player $player, Vector3 $vector) : bool{ - if(!$player->hasPermission("pocketmine.spawnprotect.bypass") and ($distance = $this->server->getSpawnRadius()) > -1){ - $t = new Vector2($vector->x, $vector->z); - - $spawnLocation = $this->getSpawnLocation(); - $s = new Vector2($spawnLocation->x, $spawnLocation->z); - if($t->distance($s) <= $distance){ - return true; - } - } - - return false; - } - /** * Tries to break a block using a item, including Player time checks if available * It'll try to lower the durability if Item is a tool, and set it to Air if broken. @@ -1680,8 +1656,6 @@ class Level implements ChunkManager, Metadatable{ if(($player->isSurvival() and !$target->isBreakable($item)) or $player->isSpectator()){ $ev->setCancelled(); - }elseif($this->checkSpawnProtection($player, $target)){ - $ev->setCancelled(); //set it to cancelled so plugins can bypass this } if($player->isAdventure(true) and !$ev->isCancelled()){ @@ -1788,10 +1762,6 @@ class Level implements ChunkManager, Metadatable{ if($player !== null){ $ev = new PlayerInteractEvent($player, $item, $blockClicked, $clickVector, $face, PlayerInteractEvent::RIGHT_CLICK_BLOCK); - if($this->checkSpawnProtection($player, $blockClicked)){ - $ev->setCancelled(); //set it to cancelled so plugins can bypass this - } - $ev->call(); if(!$ev->isCancelled()){ if(!$player->isSneaking() and $blockClicked->onActivate($item, $player)){ @@ -1842,10 +1812,6 @@ class Level implements ChunkManager, Metadatable{ if($player !== null){ $ev = new BlockPlaceEvent($player, $hand, $blockReplace, $blockClicked, $item); - if($this->checkSpawnProtection($player, $blockClicked)){ - $ev->setCancelled(); - } - if($player->isAdventure(true) and !$ev->isCancelled()){ $canPlace = false; $tag = $item->getNamedTagEntry("CanPlaceOn"); diff --git a/src/pocketmine/permission/DefaultPermissions.php b/src/pocketmine/permission/DefaultPermissions.php index 5529d5adf8..08a795de13 100644 --- a/src/pocketmine/permission/DefaultPermissions.php +++ b/src/pocketmine/permission/DefaultPermissions.php @@ -51,9 +51,6 @@ abstract class DefaultPermissions{ self::registerPermission(new Permission(self::ROOT . ".broadcast.user", "Allows the user to receive user broadcasts", Permission::DEFAULT_TRUE), $broadcasts); $broadcasts->recalculatePermissibles(); - $spawnprotect = self::registerPermission(new Permission(self::ROOT . ".spawnprotect.bypass", "Allows the user to edit blocks within the protected spawn radius", Permission::DEFAULT_OP), $parent); - $spawnprotect->recalculatePermissibles(); - $commands = self::registerPermission(new Permission(self::ROOT . ".command", "Allows using all PocketMine commands"), $parent); $whitelist = self::registerPermission(new Permission(self::ROOT . ".command.whitelist", "Allows the user to modify the server whitelist", Permission::DEFAULT_OP), $commands); diff --git a/src/pocketmine/wizard/SetupWizard.php b/src/pocketmine/wizard/SetupWizard.php index af2356aa89..c80b09ce48 100644 --- a/src/pocketmine/wizard/SetupWizard.php +++ b/src/pocketmine/wizard/SetupWizard.php @@ -158,14 +158,6 @@ LICENSE; $config->set("max-players", (int) $this->getInput($this->lang->get("max_players"), (string) self::DEFAULT_PLAYERS)); - $this->message($this->lang->get("spawn_protection_info")); - - if(strtolower($this->getInput($this->lang->get("spawn_protection"), "y", "Y/n")) === "n"){ - $config->set("spawn-protection", -1); - }else{ - $config->set("spawn-protection", 16); - } - $config->save(); } From 6ee484e401ce6a75f810a28dce7221e814380b7d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 25 Jan 2019 18:58:01 +0000 Subject: [PATCH 0431/3224] ChunkLoader: remove getLoaderId() (take 2) --- src/pocketmine/Player.php | 7 ------- src/pocketmine/entity/Entity.php | 15 +++++++++------ src/pocketmine/level/ChunkLoader.php | 8 -------- src/pocketmine/level/Level.php | 16 ++++------------ 4 files changed, 13 insertions(+), 33 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 78b091cc7c..abace213da 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -240,8 +240,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ /** @var int */ protected $gamemode; - /** @var int */ - private $loaderId = 0; /** @var bool[] chunkHash => bool (true = sent, false = needs sending) */ public $usedChunks = []; /** @var bool[] chunkHash => dummy */ @@ -690,7 +688,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->networkSession = $session; $this->perm = new PermissibleBase($this); - $this->loaderId = Level::generateChunkLoaderId($this); $this->chunksPerTick = (int) $this->server->getProperty("chunk-sending.per-tick", 4); $this->spawnThreshold = (int) (($this->server->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); @@ -3393,8 +3390,4 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ public function onBlockChanged(Vector3 $block){ } - - public function getLoaderId() : int{ - return $this->loaderId; - } } diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 1c77a10a75..eecb2a8ad9 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -75,6 +75,7 @@ use function is_infinite; use function is_nan; use function lcg_value; use function sin; +use function spl_object_id; use const M_PI_2; abstract class Entity extends Location implements Metadatable, EntityIds{ @@ -1621,10 +1622,10 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ if(!$this->justCreated){ $newChunk = $this->level->getViewersForPosition($this); foreach($this->hasSpawned as $player){ - if(!isset($newChunk[$player->getLoaderId()])){ + if(!isset($newChunk[spl_object_id($player)])){ $this->despawnFrom($player); }else{ - unset($newChunk[$player->getLoaderId()]); + unset($newChunk[spl_object_id($player)]); } } foreach($newChunk as $player){ @@ -1767,8 +1768,9 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ * @param Player $player */ public function spawnTo(Player $player) : void{ - if(!isset($this->hasSpawned[$player->getLoaderId()])){ - $this->hasSpawned[$player->getLoaderId()] = $player; + $id = spl_object_id($player); + if(!isset($this->hasSpawned[$id])){ + $this->hasSpawned[$id] = $player; $this->sendSpawnPacket($player); } @@ -1797,13 +1799,14 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ * @param bool $send */ public function despawnFrom(Player $player, bool $send = true) : void{ - if(isset($this->hasSpawned[$player->getLoaderId()])){ + $id = spl_object_id($player); + if(isset($this->hasSpawned[$id])){ if($send){ $pk = new RemoveEntityPacket(); $pk->entityUniqueId = $this->id; $player->sendDataPacket($pk); } - unset($this->hasSpawned[$player->getLoaderId()]); + unset($this->hasSpawned[$id]); } } diff --git a/src/pocketmine/level/ChunkLoader.php b/src/pocketmine/level/ChunkLoader.php index 9f10e8ac10..9d36150759 100644 --- a/src/pocketmine/level/ChunkLoader.php +++ b/src/pocketmine/level/ChunkLoader.php @@ -39,14 +39,6 @@ use pocketmine\math\Vector3; */ interface ChunkLoader{ - /** - * Returns the ChunkLoader id. - * Call Level::generateChunkLoaderId($this) to generate and save it - * - * @return int - */ - public function getLoaderId() : int; - /** * @return float */ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 7a80ed831b..128e2c47ae 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -106,6 +106,7 @@ use function max; use function microtime; use function min; use function mt_rand; +use function spl_object_id; use function strtolower; use function trim; use const INT32_MAX; @@ -117,7 +118,6 @@ use const M_PI; class Level implements ChunkManager, Metadatable{ private static $levelIdCounter = 1; - private static $chunkLoaderCounter = 1; public const Y_MASK = 0xFF; public const Y_MAX = 0x100; //256 @@ -321,14 +321,6 @@ class Level implements ChunkManager, Metadatable{ $z = ($hash & 0xFFFFFFFF) << 32 >> 32; } - public static function generateChunkLoaderId(ChunkLoader $loader) : int{ - if($loader->getLoaderId() === 0){ - return self::$chunkLoaderCounter++; - }else{ - throw new \InvalidStateException("ChunkLoader has a loader id already assigned: " . $loader->getLoaderId()); - } - } - /** * @param string $str * @@ -642,7 +634,7 @@ class Level implements ChunkManager, Metadatable{ } public function registerChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ, bool $autoLoad = true){ - $loaderId = $loader->getLoaderId(); + $loaderId = spl_object_id($loader); if(!isset($this->chunkLoaders[$chunkHash = Level::chunkHash($chunkX, $chunkZ)])){ $this->chunkLoaders[$chunkHash] = []; @@ -672,7 +664,7 @@ class Level implements ChunkManager, Metadatable{ public function unregisterChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ){ $chunkHash = Level::chunkHash($chunkX, $chunkZ); - $loaderId = $loader->getLoaderId(); + $loaderId = spl_object_id($loader); if(isset($this->chunkLoaders[$chunkHash][$loaderId])){ unset($this->chunkLoaders[$chunkHash][$loaderId]); unset($this->playerLoaders[$chunkHash][$loaderId]); @@ -2401,7 +2393,7 @@ class Level implements ChunkManager, Metadatable{ $this->chunkSendQueue[$index] = []; } - $this->chunkSendQueue[$index][$player->getLoaderId()] = $player; + $this->chunkSendQueue[$index][spl_object_id($player)] = $player; } private function sendCachedChunk(int $x, int $z){ From eac8f639a7d5e236fdca564530a8392730f6bbb9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Jan 2019 13:48:43 +0000 Subject: [PATCH 0432/3224] Level: Simplify internal chunk ticking handling --- resources/pocketmine.yml | 1 - src/pocketmine/level/Level.php | 47 +++++++++++----------------------- 2 files changed, 15 insertions(+), 33 deletions(-) diff --git a/resources/pocketmine.yml b/resources/pocketmine.yml index 75af040671..342beb6429 100644 --- a/resources/pocketmine.yml +++ b/resources/pocketmine.yml @@ -133,7 +133,6 @@ chunk-ticking: #Radius of chunks around a player to tick tick-radius: 3 light-updates: false - clear-tick-list: true #IDs of blocks not to perform random ticking on. disable-block-ticking: #- 2 # grass diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 41a3427b31..ed056a9fd0 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -248,12 +248,8 @@ class Level implements ChunkManager, Metadatable{ /** @var int */ private $chunkTickRadius; - /** @var int[] */ - private $chunkTickList = []; /** @var int */ private $chunksPerTick; - /** @var bool */ - private $clearChunksOnTick; /** @var \SplFixedArray */ private $randomTickBlocks = null; @@ -384,7 +380,6 @@ class Level implements ChunkManager, Metadatable{ $this->chunkTickRadius = min($this->server->getViewDistance(), max(1, (int) $this->server->getProperty("chunk-ticking.tick-radius", 4))); $this->chunksPerTick = (int) $this->server->getProperty("chunk-ticking.per-tick", 40); $this->chunkPopulationQueueSize = (int) $this->server->getProperty("chunk-generation.population-queue-size", 2); - $this->clearChunksOnTick = (bool) $this->server->getProperty("chunk-ticking.clear-tick-list", true); $dontTickBlocks = array_fill_keys($this->server->getProperty("chunk-ticking.disable-block-ticking", []), true); @@ -961,10 +956,12 @@ class Level implements ChunkManager, Metadatable{ private function tickChunks(){ if($this->chunksPerTick <= 0 or count($this->loaders) === 0){ - $this->chunkTickList = []; return; } + /** @var bool[] $chunkTickList chunkhash => dummy */ + $chunkTickList = []; + $chunksPerLoader = min(200, max(1, (int) ((($this->chunksPerTick - count($this->loaders)) / count($this->loaders)) + 0.5))); $randRange = 3 + $chunksPerLoader / 30; $randRange = (int) ($randRange > $this->chunkTickRadius ? $this->chunkTickRadius : $randRange); @@ -974,34 +971,28 @@ class Level implements ChunkManager, Metadatable{ $chunkZ = (int) floor($loader->getZ()) >> 4; $index = Level::chunkHash($chunkX, $chunkZ); - $existingLoaders = max(0, $this->chunkTickList[$index] ?? 0); - $this->chunkTickList[$index] = $existingLoaders + 1; + $chunkTickList[$index] = true; for($chunk = 0; $chunk < $chunksPerLoader; ++$chunk){ $dx = mt_rand(-$randRange, $randRange); $dz = mt_rand(-$randRange, $randRange); $hash = Level::chunkHash($dx + $chunkX, $dz + $chunkZ); - if(!isset($this->chunkTickList[$hash]) and isset($this->chunks[$hash])){ - $this->chunkTickList[$hash] = -1; + if(!isset($chunkTickList[$hash]) and isset($this->chunks[$hash])){ + //check adjacent chunks are loaded + for($cx = -1; $cx <= 1; ++$cx){ + for($cz = -1; $cz <= 1; ++$cz){ + if(!isset($this->chunks[Level::chunkHash($chunkX + $cx, $chunkZ + $cz)])){ + continue 3; + } + } + } + $chunkTickList[$hash] = true; } } } - foreach($this->chunkTickList as $index => $loaders){ + foreach($chunkTickList as $index => $_){ Level::getXZ($index, $chunkX, $chunkZ); - for($cx = -1; $cx <= 1; ++$cx){ - for($cz = -1; $cz <= 1; ++$cz){ - if(!isset($this->chunks[Level::chunkHash($chunkX + $cx, $chunkZ + $cz)])){ - unset($this->chunkTickList[$index]); - goto skip_to_next; //no "continue 3" thanks! - } - } - } - - if($loaders <= 0){ - unset($this->chunkTickList[$index]); - } - $chunk = $this->chunks[$index]; foreach($chunk->getEntities() as $entity){ $entity->scheduleUpdate(); @@ -1031,12 +1022,6 @@ class Level implements ChunkManager, Metadatable{ } } } - - skip_to_next: //dummy label to break out of nested loops - } - - if($this->clearChunksOnTick){ - $this->chunkTickList = []; } } @@ -2637,7 +2622,6 @@ class Level implements ChunkManager, Metadatable{ private function queueUnloadChunk(int $x, int $z){ $this->unloadQueue[$index = Level::chunkHash($x, $z)] = microtime(true); - unset($this->chunkTickList[$index]); } public function unloadChunkRequest(int $x, int $z, bool $safe = true){ @@ -2692,7 +2676,6 @@ class Level implements ChunkManager, Metadatable{ } unset($this->chunks[$chunkHash]); - unset($this->chunkTickList[$chunkHash]); unset($this->chunkCache[$chunkHash]); unset($this->blockCache[$chunkHash]); unset($this->changedBlocks[$chunkHash]); From d6e44c7475185451e034b095357636b45e589400 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Jan 2019 14:11:45 +0000 Subject: [PATCH 0433/3224] Sync composer dependencies --- composer.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.lock b/composer.lock index 5fa1e59ecf..2d76023ffc 100644 --- a/composer.lock +++ b/composer.lock @@ -372,12 +372,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "6736e85ec7600309d7ef1dc5b965ff7e4b1c5357" + "reference": "6f00e4f6c31d69bb9b7c19467dd70462616a45a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/6736e85ec7600309d7ef1dc5b965ff7e4b1c5357", - "reference": "6736e85ec7600309d7ef1dc5b965ff7e4b1c5357", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/6f00e4f6c31d69bb9b7c19467dd70462616a45a2", + "reference": "6f00e4f6c31d69bb9b7c19467dd70462616a45a2", "shasum": "" }, "require": { @@ -405,7 +405,7 @@ "source": "https://github.com/pmmp/NBT/tree/master", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2019-01-18T15:28:20+00:00" + "time": "2019-01-21T20:39:55+00:00" }, { "name": "pocketmine/raklib", @@ -413,12 +413,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "ceee20a6755e33132621fba4e5f21fccb317f73e" + "reference": "7fd825ad208b0d7d622c55583cae9a8e21eaa3eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/ceee20a6755e33132621fba4e5f21fccb317f73e", - "reference": "ceee20a6755e33132621fba4e5f21fccb317f73e", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/7fd825ad208b0d7d622c55583cae9a8e21eaa3eb", + "reference": "7fd825ad208b0d7d622c55583cae9a8e21eaa3eb", "shasum": "" }, "require": { @@ -446,7 +446,7 @@ "source": "https://github.com/pmmp/RakLib/tree/master", "issues": "https://github.com/pmmp/RakLib/issues" }, - "time": "2019-01-21T14:17:51+00:00" + "time": "2019-01-21T19:44:18+00:00" }, { "name": "pocketmine/snooze", From d052b1a45f7f652e675cf3def93058a1666904e0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Jan 2019 15:02:07 +0000 Subject: [PATCH 0434/3224] Server: reduce code duplication in broadcast handling --- src/pocketmine/Server.php | 44 +++++++++++++-------------------------- 1 file changed, 15 insertions(+), 29 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 2104298ea7..74cda4db66 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -135,6 +135,7 @@ use function rename; use function round; use function sleep; use function spl_object_hash; +use function spl_object_id; use function sprintf; use function str_repeat; use function str_replace; @@ -1357,6 +1358,17 @@ class Server{ return count($recipients); } + private function selectPermittedPlayers(string $permission) : array{ + /** @var Player[] $players */ + $players = []; + foreach(PermissionManager::getInstance()->getPermissionSubscriptions($permission) as $permissible){ + if($permissible instanceof Player and $permissible->hasPermission($permission)){ + $players[spl_object_id($permissible)] = $permissible; //prevent duplication + } + } + return $players; + } + /** * @param string $tip * @param Player[] $recipients @@ -1364,15 +1376,7 @@ class Server{ * @return int */ public function broadcastTip(string $tip, array $recipients = null) : int{ - if(!is_array($recipients)){ - /** @var Player[] $recipients */ - $recipients = []; - foreach(PermissionManager::getInstance()->getPermissionSubscriptions(self::BROADCAST_CHANNEL_USERS) as $permissible){ - if($permissible instanceof Player and $permissible->hasPermission(self::BROADCAST_CHANNEL_USERS)){ - $recipients[spl_object_hash($permissible)] = $permissible; // do not send messages directly, or some might be repeated - } - } - } + $recipients = $recipients ?? $this->selectPermittedPlayers(self::BROADCAST_CHANNEL_USERS); /** @var Player[] $recipients */ foreach($recipients as $recipient){ @@ -1389,16 +1393,7 @@ class Server{ * @return int */ public function broadcastPopup(string $popup, array $recipients = null) : int{ - if(!is_array($recipients)){ - /** @var Player[] $recipients */ - $recipients = []; - - foreach(PermissionManager::getInstance()->getPermissionSubscriptions(self::BROADCAST_CHANNEL_USERS) as $permissible){ - if($permissible instanceof Player and $permissible->hasPermission(self::BROADCAST_CHANNEL_USERS)){ - $recipients[spl_object_hash($permissible)] = $permissible; // do not send messages directly, or some might be repeated - } - } - } + $recipients = $recipients ?? $this->selectPermittedPlayers(self::BROADCAST_CHANNEL_USERS); /** @var Player[] $recipients */ foreach($recipients as $recipient){ @@ -1419,16 +1414,7 @@ class Server{ * @return int */ public function broadcastTitle(string $title, string $subtitle = "", int $fadeIn = -1, int $stay = -1, int $fadeOut = -1, array $recipients = null) : int{ - if(!is_array($recipients)){ - /** @var Player[] $recipients */ - $recipients = []; - - foreach(PermissionManager::getInstance()->getPermissionSubscriptions(self::BROADCAST_CHANNEL_USERS) as $permissible){ - if($permissible instanceof Player and $permissible->hasPermission(self::BROADCAST_CHANNEL_USERS)){ - $recipients[spl_object_hash($permissible)] = $permissible; // do not send messages directly, or some might be repeated - } - } - } + $recipients = $recipients ?? $this->selectPermittedPlayers(self::BROADCAST_CHANNEL_USERS); /** @var Player[] $recipients */ foreach($recipients as $recipient){ From 1e708db26c5ff6a6ac3758c38576ddd4b181e07f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Jan 2019 15:03:15 +0000 Subject: [PATCH 0435/3224] Server: fixed wrong doc type on broadcastMessage() --- src/pocketmine/Server.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 74cda4db66..d60c05f06f 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1341,7 +1341,7 @@ class Server{ /** * @param TextContainer|string $message - * @param Player[] $recipients + * @param CommandSender[] $recipients * * @return int */ From d378371cc86171f63c1f98718cee94feb5a4d1a5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Jan 2019 15:06:38 +0000 Subject: [PATCH 0436/3224] Transition to spl_object_id() --- src/pocketmine/Player.php | 8 ++++---- src/pocketmine/Server.php | 7 +++---- src/pocketmine/ThreadManager.php | 6 +++--- src/pocketmine/event/HandlerList.php | 10 +++++----- src/pocketmine/inventory/BaseInventory.php | 6 +++--- .../transaction/InventoryTransaction.php | 7 ++++--- .../transaction/action/SlotChangeAction.php | 4 ++-- src/pocketmine/network/Network.php | 8 ++++---- src/pocketmine/network/mcpe/RakLibInterface.php | 10 +++++----- src/pocketmine/permission/PermissibleBase.php | 8 ++++---- src/pocketmine/permission/PermissionManager.php | 16 ++++++++-------- src/pocketmine/plugin/PluginLogger.php | 6 +++--- src/pocketmine/scheduler/AsyncPool.php | 6 +++--- src/pocketmine/scheduler/AsyncTask.php | 10 +++++----- src/pocketmine/timings/TimingsHandler.php | 6 +++--- 15 files changed, 59 insertions(+), 59 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index abace213da..4543e9c0aa 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -156,7 +156,7 @@ use function microtime; use function min; use function preg_match; use function round; -use function spl_object_hash; +use function spl_object_id; use function strlen; use function strpos; use function strtolower; @@ -3247,7 +3247,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ * @return int */ public function getWindowId(Inventory $inventory) : int{ - return $this->windows[spl_object_hash($inventory)] ?? ContainerIds::NONE; + return $this->windows[spl_object_id($inventory)] ?? ContainerIds::NONE; } /** @@ -3297,7 +3297,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } $this->windowIndex[$cnt] = $inventory; - $this->windows[spl_object_hash($inventory)] = $cnt; + $this->windows[spl_object_id($inventory)] = $cnt; if($inventory->open($this)){ if($isPermanent){ $this->permanentWindows[$cnt] = true; @@ -3319,7 +3319,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ * @throws \InvalidArgumentException if trying to remove a fixed inventory window without the `force` parameter as true */ public function removeWindow(Inventory $inventory, bool $force = false){ - $id = $this->windows[$hash = spl_object_hash($inventory)] ?? null; + $id = $this->windows[$hash = spl_object_id($inventory)] ?? null; if($id !== null and !$force and isset($this->permanentWindows[$id])){ throw new \InvalidArgumentException("Cannot remove fixed window $id (" . get_class($inventory) . ") from " . $this->getName()); diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index d60c05f06f..071606e289 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -134,7 +134,6 @@ use function register_shutdown_function; use function rename; use function round; use function sleep; -use function spl_object_hash; use function spl_object_id; use function sprintf; use function str_repeat; @@ -1436,7 +1435,7 @@ class Server{ foreach(explode(";", $permissions) as $permission){ foreach(PermissionManager::getInstance()->getPermissionSubscriptions($permission) as $permissible){ if($permissible instanceof CommandSender and $permissible->hasPermission($permission)){ - $recipients[spl_object_hash($permissible)] = $permissible; // do not send messages directly, or some might be repeated + $recipients[spl_object_id($permissible)] = $permissible; // do not send messages directly, or some might be repeated } } } @@ -1900,14 +1899,14 @@ class Server{ } public function addPlayer(Player $player){ - $this->players[spl_object_hash($player)] = $player; + $this->players[spl_object_id($player)] = $player; } /** * @param Player $player */ public function removePlayer(Player $player){ - unset($this->players[spl_object_hash($player)]); + unset($this->players[spl_object_id($player)]); } public function addOnlinePlayer(Player $player){ diff --git a/src/pocketmine/ThreadManager.php b/src/pocketmine/ThreadManager.php index 3694d6c989..a4bbe2a57a 100644 --- a/src/pocketmine/ThreadManager.php +++ b/src/pocketmine/ThreadManager.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine; -use function spl_object_hash; +use function spl_object_id; class ThreadManager extends \Volatile{ @@ -46,7 +46,7 @@ class ThreadManager extends \Volatile{ */ public function add($thread){ if($thread instanceof Thread or $thread instanceof Worker){ - $this->{spl_object_hash($thread)} = $thread; + $this->{spl_object_id($thread)} = $thread; } } @@ -55,7 +55,7 @@ class ThreadManager extends \Volatile{ */ public function remove($thread){ if($thread instanceof Thread or $thread instanceof Worker){ - unset($this->{spl_object_hash($thread)}); + unset($this->{spl_object_id($thread)}); } } diff --git a/src/pocketmine/event/HandlerList.php b/src/pocketmine/event/HandlerList.php index 8b833a4c30..60b3d4bac6 100644 --- a/src/pocketmine/event/HandlerList.php +++ b/src/pocketmine/event/HandlerList.php @@ -28,7 +28,7 @@ use pocketmine\plugin\RegisteredListener; use pocketmine\utils\Utils; use function array_fill_keys; use function in_array; -use function spl_object_hash; +use function spl_object_id; class HandlerList{ /** @@ -120,10 +120,10 @@ class HandlerList{ if(!in_array($listener->getPriority(), EventPriority::ALL, true)){ return; } - if(isset($this->handlerSlots[$listener->getPriority()][spl_object_hash($listener)])){ + if(isset($this->handlerSlots[$listener->getPriority()][spl_object_id($listener)])){ throw new \InvalidStateException("This listener is already registered to priority {$listener->getPriority()} of event {$this->class}"); } - $this->handlerSlots[$listener->getPriority()][spl_object_hash($listener)] = $listener; + $this->handlerSlots[$listener->getPriority()][spl_object_id($listener)] = $listener; } /** @@ -150,8 +150,8 @@ class HandlerList{ } } }elseif($object instanceof RegisteredListener){ - if(isset($this->handlerSlots[$object->getPriority()][spl_object_hash($object)])){ - unset($this->handlerSlots[$object->getPriority()][spl_object_hash($object)]); + if(isset($this->handlerSlots[$object->getPriority()][spl_object_id($object)])){ + unset($this->handlerSlots[$object->getPriority()][spl_object_id($object)]); } } } diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index ce015b3e2e..2be0a0ef1e 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -37,7 +37,7 @@ use function array_slice; use function count; use function max; use function min; -use function spl_object_hash; +use function spl_object_id; abstract class BaseInventory implements Inventory{ @@ -420,11 +420,11 @@ abstract class BaseInventory implements Inventory{ } public function onOpen(Player $who) : void{ - $this->viewers[spl_object_hash($who)] = $who; + $this->viewers[spl_object_id($who)] = $who; } public function onClose(Player $who) : void{ - unset($this->viewers[spl_object_hash($who)]); + unset($this->viewers[spl_object_id($who)]); } public function onSlotChange(int $index, Item $before, bool $send) : void{ diff --git a/src/pocketmine/inventory/transaction/InventoryTransaction.php b/src/pocketmine/inventory/transaction/InventoryTransaction.php index 55219fac67..e74bfa6030 100644 --- a/src/pocketmine/inventory/transaction/InventoryTransaction.php +++ b/src/pocketmine/inventory/transaction/InventoryTransaction.php @@ -34,6 +34,7 @@ use function count; use function get_class; use function min; use function spl_object_hash; +use function spl_object_id; /** * This InventoryTransaction only allows doing Transaction between one / two inventories @@ -85,7 +86,7 @@ class InventoryTransaction{ * @param InventoryAction $action */ public function addAction(InventoryAction $action) : void{ - if(!isset($this->actions[$hash = spl_object_hash($action)])){ + if(!isset($this->actions[$hash = spl_object_id($action)])){ $this->actions[$hash] = $action; $action->onAddToTransaction($this); }else{ @@ -100,7 +101,7 @@ class InventoryTransaction{ * @param Inventory $inventory */ public function addInventory(Inventory $inventory) : void{ - if(!isset($this->inventories[$hash = spl_object_hash($inventory)])){ + if(!isset($this->inventories[$hash = spl_object_id($inventory)])){ $this->inventories[$hash] = $inventory; } } @@ -188,7 +189,7 @@ class InventoryTransaction{ } foreach($list as $action){ - unset($this->actions[spl_object_hash($action)]); + unset($this->actions[spl_object_id($action)]); } if(!$targetItem->equalsExact($sourceItem)){ diff --git a/src/pocketmine/inventory/transaction/action/SlotChangeAction.php b/src/pocketmine/inventory/transaction/action/SlotChangeAction.php index 8b2a1812c8..3bc8265484 100644 --- a/src/pocketmine/inventory/transaction/action/SlotChangeAction.php +++ b/src/pocketmine/inventory/transaction/action/SlotChangeAction.php @@ -27,7 +27,7 @@ use pocketmine\inventory\Inventory; use pocketmine\inventory\transaction\InventoryTransaction; use pocketmine\item\Item; use pocketmine\Player; -use function spl_object_hash; +use function spl_object_id; /** * Represents an action causing a change in an inventory slot. @@ -110,7 +110,7 @@ class SlotChangeAction extends InventoryAction{ */ public function onExecuteSuccess(Player $source) : void{ $viewers = $this->inventory->getViewers(); - unset($viewers[spl_object_hash($source)]); + unset($viewers[spl_object_id($source)]); $this->inventory->sendSlot($this->inventorySlot, $viewers); } diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index a975caf250..60d0961ba7 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -30,7 +30,7 @@ use pocketmine\event\server\NetworkInterfaceRegisterEvent; use pocketmine\event\server\NetworkInterfaceUnregisterEvent; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\PacketPool; -use function spl_object_hash; +use function spl_object_id; class Network{ /** @var NetworkInterface[] */ @@ -105,7 +105,7 @@ class Network{ $ev->call(); if(!$ev->isCancelled()){ $interface->start(); - $this->interfaces[$hash = spl_object_hash($interface)] = $interface; + $this->interfaces[$hash = spl_object_id($interface)] = $interface; if($interface instanceof AdvancedNetworkInterface){ $this->advancedInterfaces[$hash] = $interface; $interface->setNetwork($this); @@ -119,7 +119,7 @@ class Network{ */ public function unregisterInterface(NetworkInterface $interface) : void{ (new NetworkInterfaceUnregisterEvent($interface))->call(); - unset($this->interfaces[$hash = spl_object_hash($interface)], $this->advancedInterfaces[$hash]); + unset($this->interfaces[$hash = spl_object_id($interface)], $this->advancedInterfaces[$hash]); } /** @@ -183,6 +183,6 @@ class Network{ } public function scheduleSessionTick(NetworkSession $session) : void{ - $this->updateSessions[spl_object_hash($session)] = $session; + $this->updateSessions[spl_object_id($session)] = $session; } } diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 962c3643c9..17d073b84b 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -42,7 +42,7 @@ use function addcslashes; use function count; use function implode; use function rtrim; -use function spl_object_hash; +use function spl_object_id; use function substr; use function unserialize; use const PTHREADS_INHERIT_CONSTANTS; @@ -121,14 +121,14 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ public function closeSession(string $identifier, string $reason) : void{ if(isset($this->sessions[$identifier])){ $session = $this->sessions[$identifier]; - unset($this->identifiers[spl_object_hash($session)]); + unset($this->identifiers[spl_object_id($session)]); unset($this->sessions[$identifier]); $session->onClientDisconnect($reason); } } public function close(NetworkSession $session, string $reason = "unknown reason") : void{ - if(isset($this->identifiers[$h = spl_object_hash($session)])){ + if(isset($this->identifiers[$h = spl_object_id($session)])){ unset($this->sessions[$this->identifiers[$h]]); $this->interface->closeSession($this->identifiers[$h], $reason); unset($this->identifiers[$h]); @@ -143,7 +143,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ public function openSession(string $identifier, string $address, int $port, int $clientID) : void{ $session = new NetworkSession($this->server, $this, $address, $port); $this->sessions[$identifier] = $session; - $this->identifiers[spl_object_hash($session)] = $identifier; + $this->identifiers[spl_object_id($session)] = $identifier; } public function handleEncapsulated(string $identifier, EncapsulatedPacket $packet, int $flags) : void{ @@ -227,7 +227,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ } public function putPacket(NetworkSession $session, string $payload, bool $immediate = true) : void{ - if(isset($this->identifiers[$h = spl_object_hash($session)])){ + if(isset($this->identifiers[$h = spl_object_id($session)])){ $identifier = $this->identifiers[$h]; $pk = new EncapsulatedPacket(); diff --git a/src/pocketmine/permission/PermissibleBase.php b/src/pocketmine/permission/PermissibleBase.php index 32fd74d82a..809d62c756 100644 --- a/src/pocketmine/permission/PermissibleBase.php +++ b/src/pocketmine/permission/PermissibleBase.php @@ -26,7 +26,7 @@ namespace pocketmine\permission; use pocketmine\plugin\Plugin; use pocketmine\plugin\PluginException; use pocketmine\timings\Timings; -use function spl_object_hash; +use function spl_object_id; class PermissibleBase implements Permissible{ /** @var ServerOperator */ @@ -117,7 +117,7 @@ class PermissibleBase implements Permissible{ } $result = new PermissionAttachment($plugin, $this->parent ?? $this); - $this->attachments[spl_object_hash($result)] = $result; + $this->attachments[spl_object_id($result)] = $result; if($name !== null and $value !== null){ $result->setPermission($name, $value); } @@ -131,8 +131,8 @@ class PermissibleBase implements Permissible{ * @param PermissionAttachment $attachment */ public function removeAttachment(PermissionAttachment $attachment){ - if(isset($this->attachments[spl_object_hash($attachment)])){ - unset($this->attachments[spl_object_hash($attachment)]); + if(isset($this->attachments[spl_object_id($attachment)])){ + unset($this->attachments[spl_object_id($attachment)]); if(($ex = $attachment->getRemovalCallback()) !== null){ $ex->attachmentRemoved($attachment); } diff --git a/src/pocketmine/permission/PermissionManager.php b/src/pocketmine/permission/PermissionManager.php index 02d7d96648..6cd1d8ab18 100644 --- a/src/pocketmine/permission/PermissionManager.php +++ b/src/pocketmine/permission/PermissionManager.php @@ -25,7 +25,7 @@ namespace pocketmine\permission; use pocketmine\timings\Timings; use function count; -use function spl_object_hash; +use function spl_object_id; class PermissionManager{ /** @var PermissionManager|null */ @@ -146,7 +146,7 @@ class PermissionManager{ if(!isset($this->permSubs[$permission])){ $this->permSubs[$permission] = []; } - $this->permSubs[$permission][spl_object_hash($permissible)] = $permissible; + $this->permSubs[$permission][spl_object_id($permissible)] = $permissible; } /** @@ -155,7 +155,7 @@ class PermissionManager{ */ public function unsubscribeFromPermission(string $permission, Permissible $permissible){ if(isset($this->permSubs[$permission])){ - unset($this->permSubs[$permission][spl_object_hash($permissible)]); + unset($this->permSubs[$permission][spl_object_id($permissible)]); if(count($this->permSubs[$permission]) === 0){ unset($this->permSubs[$permission]); } @@ -167,7 +167,7 @@ class PermissionManager{ */ public function unsubscribeFromAllPermissions(Permissible $permissible) : void{ foreach($this->permSubs as $permission => &$subs){ - unset($subs[spl_object_hash($permissible)]); + unset($subs[spl_object_id($permissible)]); if(empty($subs)){ unset($this->permSubs[$permission]); } @@ -189,9 +189,9 @@ class PermissionManager{ */ public function subscribeToDefaultPerms(bool $op, Permissible $permissible){ if($op){ - $this->defSubsOp[spl_object_hash($permissible)] = $permissible; + $this->defSubsOp[spl_object_id($permissible)] = $permissible; }else{ - $this->defSubs[spl_object_hash($permissible)] = $permissible; + $this->defSubs[spl_object_id($permissible)] = $permissible; } } @@ -201,9 +201,9 @@ class PermissionManager{ */ public function unsubscribeFromDefaultPerms(bool $op, Permissible $permissible){ if($op){ - unset($this->defSubsOp[spl_object_hash($permissible)]); + unset($this->defSubsOp[spl_object_id($permissible)]); }else{ - unset($this->defSubs[spl_object_hash($permissible)]); + unset($this->defSubs[spl_object_id($permissible)]); } } diff --git a/src/pocketmine/plugin/PluginLogger.php b/src/pocketmine/plugin/PluginLogger.php index 585d9da397..944533dcd7 100644 --- a/src/pocketmine/plugin/PluginLogger.php +++ b/src/pocketmine/plugin/PluginLogger.php @@ -25,7 +25,7 @@ namespace pocketmine\plugin; use LogLevel; use pocketmine\Server; -use function spl_object_hash; +use function spl_object_id; class PluginLogger implements \AttachableLogger{ @@ -35,11 +35,11 @@ class PluginLogger implements \AttachableLogger{ private $attachments = []; public function addAttachment(\LoggerAttachment $attachment){ - $this->attachments[spl_object_hash($attachment)] = $attachment; + $this->attachments[spl_object_id($attachment)] = $attachment; } public function removeAttachment(\LoggerAttachment $attachment){ - unset($this->attachments[spl_object_hash($attachment)]); + unset($this->attachments[spl_object_id($attachment)]); } public function removeAttachments(){ diff --git a/src/pocketmine/scheduler/AsyncPool.php b/src/pocketmine/scheduler/AsyncPool.php index f6eec52e71..60e1bcac55 100644 --- a/src/pocketmine/scheduler/AsyncPool.php +++ b/src/pocketmine/scheduler/AsyncPool.php @@ -27,7 +27,7 @@ use pocketmine\utils\Utils; use function array_keys; use function assert; use function count; -use function spl_object_hash; +use function spl_object_id; use function time; use const PHP_INT_MAX; use const PTHREADS_INHERIT_CONSTANTS; @@ -97,7 +97,7 @@ class AsyncPool{ */ public function addWorkerStartHook(\Closure $hook) : void{ Utils::validateCallableSignature(function(int $worker) : void{}, $hook); - $this->workerStartHooks[spl_object_hash($hook)] = $hook; + $this->workerStartHooks[spl_object_id($hook)] = $hook; foreach($this->workers as $i => $worker){ $hook($i); } @@ -109,7 +109,7 @@ class AsyncPool{ * @param \Closure $hook */ public function removeWorkerStartHook(\Closure $hook) : void{ - unset($this->workerStartHooks[spl_object_hash($hook)]); + unset($this->workerStartHooks[spl_object_id($hook)]); } /** diff --git a/src/pocketmine/scheduler/AsyncTask.php b/src/pocketmine/scheduler/AsyncTask.php index af78f29bb1..38f6429c68 100644 --- a/src/pocketmine/scheduler/AsyncTask.php +++ b/src/pocketmine/scheduler/AsyncTask.php @@ -25,7 +25,7 @@ namespace pocketmine\scheduler; use function is_scalar; use function serialize; -use function spl_object_hash; +use function spl_object_id; use function unserialize; /** @@ -256,7 +256,7 @@ abstract class AsyncTask extends \Threaded{ */ self::$threadLocalStorage = new \ArrayObject(); } - self::$threadLocalStorage[spl_object_hash($this)] = $complexData; + self::$threadLocalStorage[spl_object_id($this)] = $complexData; } /** @@ -270,16 +270,16 @@ abstract class AsyncTask extends \Threaded{ * @throws \InvalidArgumentException if no data were stored by this AsyncTask instance. */ protected function fetchLocal(){ - if(self::$threadLocalStorage === null or !isset(self::$threadLocalStorage[spl_object_hash($this)])){ + if(self::$threadLocalStorage === null or !isset(self::$threadLocalStorage[spl_object_id($this)])){ throw new \InvalidArgumentException("No matching thread-local data found on this thread"); } - return self::$threadLocalStorage[spl_object_hash($this)]; + return self::$threadLocalStorage[spl_object_id($this)]; } final public function __destruct(){ $this->reallyDestruct(); - if(self::$threadLocalStorage !== null and isset(self::$threadLocalStorage[$h = spl_object_hash($this)])){ + if(self::$threadLocalStorage !== null and isset(self::$threadLocalStorage[$h = spl_object_id($this)])){ unset(self::$threadLocalStorage[$h]); if(self::$threadLocalStorage->count() === 0){ self::$threadLocalStorage = null; diff --git a/src/pocketmine/timings/TimingsHandler.php b/src/pocketmine/timings/TimingsHandler.php index 4667cb2311..102f5466cc 100644 --- a/src/pocketmine/timings/TimingsHandler.php +++ b/src/pocketmine/timings/TimingsHandler.php @@ -29,7 +29,7 @@ use function count; use function fwrite; use function microtime; use function round; -use function spl_object_hash; +use function spl_object_id; use const PHP_EOL; class TimingsHandler{ @@ -154,7 +154,7 @@ class TimingsHandler{ $this->name = $name; $this->parent = $parent; - self::$HANDLERS[spl_object_hash($this)] = $this; + self::$HANDLERS[spl_object_id($this)] = $this; } public function startTiming(){ @@ -195,6 +195,6 @@ class TimingsHandler{ } public function remove(){ - unset(self::$HANDLERS[spl_object_hash($this)]); + unset(self::$HANDLERS[spl_object_id($this)]); } } From 0b1bdec3ac099e3b00e89188293baa093e831023 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Jan 2019 17:09:54 +0000 Subject: [PATCH 0437/3224] GameMode::fromString() now throws InvalidArgumentException --- src/pocketmine/GameMode.php | 4 +++- .../command/defaults/DefaultGamemodeCommand.php | 13 +++++++------ src/pocketmine/command/defaults/GamemodeCommand.php | 7 +++---- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/pocketmine/GameMode.php b/src/pocketmine/GameMode.php index 43271d5687..99e0bd4c92 100644 --- a/src/pocketmine/GameMode.php +++ b/src/pocketmine/GameMode.php @@ -40,6 +40,8 @@ final class GameMode{ * @param string $str * * @return int + * + * @throws \InvalidArgumentException */ public static function fromString(string $str) : int{ switch(strtolower(trim($str))){ @@ -65,7 +67,7 @@ final class GameMode{ return self::SPECTATOR; } - return -1; + throw new \InvalidArgumentException("Unknown gamemode string \"$str\""); } /** diff --git a/src/pocketmine/command/defaults/DefaultGamemodeCommand.php b/src/pocketmine/command/defaults/DefaultGamemodeCommand.php index c8bede912a..294ba3a276 100644 --- a/src/pocketmine/command/defaults/DefaultGamemodeCommand.php +++ b/src/pocketmine/command/defaults/DefaultGamemodeCommand.php @@ -49,15 +49,16 @@ class DefaultGamemodeCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $gameMode = GameMode::fromString($args[0]); - - if($gameMode !== -1){ - $sender->getServer()->setConfigInt("gamemode", $gameMode); - $sender->sendMessage(new TranslationContainer("commands.defaultgamemode.success", [GameMode::toTranslation($gameMode)])); - }else{ + try{ + $gameMode = GameMode::fromString($args[0]); + }catch(\InvalidArgumentException $e){ $sender->sendMessage("Unknown game mode"); + return true; } + $sender->getServer()->setConfigInt("gamemode", $gameMode); + $sender->sendMessage(new TranslationContainer("commands.defaultgamemode.success", [GameMode::toTranslation($gameMode)])); + return true; } } diff --git a/src/pocketmine/command/defaults/GamemodeCommand.php b/src/pocketmine/command/defaults/GamemodeCommand.php index 3439caa8aa..d8db3fcca8 100644 --- a/src/pocketmine/command/defaults/GamemodeCommand.php +++ b/src/pocketmine/command/defaults/GamemodeCommand.php @@ -52,11 +52,10 @@ class GamemodeCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $gameMode = GameMode::fromString($args[0]); - - if($gameMode === -1){ + try{ + $gameMode = GameMode::fromString($args[0]); + }catch(\InvalidArgumentException $e){ $sender->sendMessage("Unknown game mode"); - return true; } From bccc07633cf42b1c7108f739536135dc6cb9bef2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 27 Jan 2019 15:42:46 +0000 Subject: [PATCH 0438/3224] Entity: Allow disabling gravity for a mob --- src/pocketmine/entity/Entity.php | 14 +++++++++++++- src/pocketmine/entity/Squid.php | 7 +------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index eecb2a8ad9..2069c97f7c 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -359,6 +359,8 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ protected $gravity; /** @var float */ protected $drag; + /** @var bool */ + protected $gravityEnabled = true; /** @var Server */ protected $server; @@ -1046,6 +1048,14 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->level->broadcastPacketToViewers($this, $pk); } + public function hasGravity() : bool{ + return $this->gravityEnabled; + } + + public function setHasGravity(bool $v = true) : void{ + $this->gravityEnabled = $v; + } + protected function applyDragBeforeGravity() : bool{ return false; } @@ -1061,7 +1071,9 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->motion->y *= $friction; } - $this->applyGravity(); + if($this->gravityEnabled){ + $this->applyGravity(); + } if(!$this->applyDragBeforeGravity()){ $this->motion->y *= $friction; diff --git a/src/pocketmine/entity/Squid.php b/src/pocketmine/entity/Squid.php index 352a4d8d0d..9a2cf896b6 100644 --- a/src/pocketmine/entity/Squid.php +++ b/src/pocketmine/entity/Squid.php @@ -99,6 +99,7 @@ class Squid extends WaterAnimal{ } $inWater = $this->isUnderwater(); + $this->setHasGravity(!$inWater); if(!$inWater){ $this->swimDirection = null; }elseif($this->swimDirection !== null){ @@ -118,12 +119,6 @@ class Squid extends WaterAnimal{ return $hasUpdate; } - protected function applyGravity() : void{ - if(!$this->isUnderwater()){ - parent::applyGravity(); - } - } - public function getDrops() : array{ return [ ItemFactory::get(Item::DYE, 0, mt_rand(1, 3)) From ac551cf2482420fa79b4b31b5b73380184b20e1a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 27 Jan 2019 15:43:57 +0000 Subject: [PATCH 0439/3224] Entity: add addMotion() to allow updating motion vector this allows updating motion without needing to create new objects for the task. --- src/pocketmine/entity/Entity.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 2069c97f7c..015ae9f9b5 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -1680,6 +1680,19 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ return true; } + /** + * Adds the given values to the entity's motion vector. + * + * @param float $x + * @param float $y + * @param float $z + */ + public function addMotion(float $x, float $y, float $z) : void{ + $this->motion->x += $x; + $this->motion->y += $y; + $this->motion->z += $z; + } + public function isOnGround() : bool{ return $this->onGround; } From 729ae8bab730e01e9fc9f8dee9ba1a9a330ecb90 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 27 Jan 2019 16:20:25 +0000 Subject: [PATCH 0440/3224] Level: fixed adjacent chunk loading check --- src/pocketmine/level/Level.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index ed056a9fd0..579569202c 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -980,7 +980,7 @@ class Level implements ChunkManager, Metadatable{ //check adjacent chunks are loaded for($cx = -1; $cx <= 1; ++$cx){ for($cz = -1; $cz <= 1; ++$cz){ - if(!isset($this->chunks[Level::chunkHash($chunkX + $cx, $chunkZ + $cz)])){ + if(!isset($this->chunks[Level::chunkHash($chunkX + $dx + $cx, $chunkZ + $dz + $cz)])){ continue 3; } } From 9ec40c421fad00ec6c77bfd71816712ddb33452c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 27 Jan 2019 19:45:15 +0000 Subject: [PATCH 0441/3224] Split up Effects into a bunch of classes Server-side levitation now works too. --- src/pocketmine/entity/Effect.php | 187 +++--------------- .../entity/effect/AbsorptionEffect.php | 42 ++++ .../entity/effect/HealthBoostEffect.php | 39 ++++ src/pocketmine/entity/effect/HungerEffect.php | 44 +++++ .../entity/effect/InstantDamageEffect.php | 50 +++++ .../entity/effect/InstantEffect.php | 38 ++++ .../entity/effect/InstantHealthEffect.php | 39 ++++ .../entity/effect/InvisibilityEffect.php | 41 ++++ .../entity/effect/LevitationEffect.php | 51 +++++ src/pocketmine/entity/effect/PoisonEffect.php | 56 ++++++ .../entity/effect/RegenerationEffect.php | 47 +++++ .../entity/effect/SaturationEffect.php | 39 ++++ .../entity/effect/SlownessEffect.php | 42 ++++ src/pocketmine/entity/effect/SpeedEffect.php | 42 ++++ src/pocketmine/entity/effect/WitherEffect.php | 45 +++++ .../entity/projectile/SplashPotion.php | 5 +- 16 files changed, 649 insertions(+), 158 deletions(-) create mode 100644 src/pocketmine/entity/effect/AbsorptionEffect.php create mode 100644 src/pocketmine/entity/effect/HealthBoostEffect.php create mode 100644 src/pocketmine/entity/effect/HungerEffect.php create mode 100644 src/pocketmine/entity/effect/InstantDamageEffect.php create mode 100644 src/pocketmine/entity/effect/InstantEffect.php create mode 100644 src/pocketmine/entity/effect/InstantHealthEffect.php create mode 100644 src/pocketmine/entity/effect/InvisibilityEffect.php create mode 100644 src/pocketmine/entity/effect/LevitationEffect.php create mode 100644 src/pocketmine/entity/effect/PoisonEffect.php create mode 100644 src/pocketmine/entity/effect/RegenerationEffect.php create mode 100644 src/pocketmine/entity/effect/SaturationEffect.php create mode 100644 src/pocketmine/entity/effect/SlownessEffect.php create mode 100644 src/pocketmine/entity/effect/SpeedEffect.php create mode 100644 src/pocketmine/entity/effect/WitherEffect.php diff --git a/src/pocketmine/entity/Effect.php b/src/pocketmine/entity/Effect.php index 96299d3ca2..f35b4dc961 100644 --- a/src/pocketmine/entity/Effect.php +++ b/src/pocketmine/entity/Effect.php @@ -23,11 +23,19 @@ declare(strict_types=1); namespace pocketmine\entity; -use pocketmine\event\entity\EntityDamageByChildEntityEvent; -use pocketmine\event\entity\EntityDamageByEntityEvent; -use pocketmine\event\entity\EntityDamageEvent; -use pocketmine\event\entity\EntityRegainHealthEvent; -use pocketmine\event\player\PlayerExhaustEvent; +use pocketmine\entity\effect\AbsorptionEffect; +use pocketmine\entity\effect\HealthBoostEffect; +use pocketmine\entity\effect\HungerEffect; +use pocketmine\entity\effect\InstantDamageEffect; +use pocketmine\entity\effect\InstantHealthEffect; +use pocketmine\entity\effect\InvisibilityEffect; +use pocketmine\entity\effect\LevitationEffect; +use pocketmine\entity\effect\PoisonEffect; +use pocketmine\entity\effect\RegenerationEffect; +use pocketmine\entity\effect\SaturationEffect; +use pocketmine\entity\effect\SlownessEffect; +use pocketmine\entity\effect\SpeedEffect; +use pocketmine\entity\effect\WitherEffect; use pocketmine\utils\Color; use function constant; use function defined; @@ -65,31 +73,31 @@ class Effect{ protected static $effects = []; public static function init() : void{ - self::registerEffect(new Effect(Effect::SPEED, "%potion.moveSpeed", new Color(0x7c, 0xaf, 0xc6))); - self::registerEffect(new Effect(Effect::SLOWNESS, "%potion.moveSlowdown", new Color(0x5a, 0x6c, 0x81), true)); + self::registerEffect(new SpeedEffect(Effect::SPEED, "%potion.moveSpeed", new Color(0x7c, 0xaf, 0xc6))); + self::registerEffect(new SlownessEffect(Effect::SLOWNESS, "%potion.moveSlowdown", new Color(0x5a, 0x6c, 0x81), true)); self::registerEffect(new Effect(Effect::HASTE, "%potion.digSpeed", new Color(0xd9, 0xc0, 0x43))); self::registerEffect(new Effect(Effect::MINING_FATIGUE, "%potion.digSlowDown", new Color(0x4a, 0x42, 0x17), true)); self::registerEffect(new Effect(Effect::STRENGTH, "%potion.damageBoost", new Color(0x93, 0x24, 0x23))); - self::registerEffect(new Effect(Effect::INSTANT_HEALTH, "%potion.heal", new Color(0xf8, 0x24, 0x23), false, 1, false)); - self::registerEffect(new Effect(Effect::INSTANT_DAMAGE, "%potion.harm", new Color(0x43, 0x0a, 0x09), true, 1, false)); + self::registerEffect(new InstantHealthEffect(Effect::INSTANT_HEALTH, "%potion.heal", new Color(0xf8, 0x24, 0x23), false, false)); + self::registerEffect(new InstantDamageEffect(Effect::INSTANT_DAMAGE, "%potion.harm", new Color(0x43, 0x0a, 0x09), true, false)); self::registerEffect(new Effect(Effect::JUMP_BOOST, "%potion.jump", new Color(0x22, 0xff, 0x4c))); self::registerEffect(new Effect(Effect::NAUSEA, "%potion.confusion", new Color(0x55, 0x1d, 0x4a), true)); - self::registerEffect(new Effect(Effect::REGENERATION, "%potion.regeneration", new Color(0xcd, 0x5c, 0xab))); + self::registerEffect(new RegenerationEffect(Effect::REGENERATION, "%potion.regeneration", new Color(0xcd, 0x5c, 0xab))); self::registerEffect(new Effect(Effect::RESISTANCE, "%potion.resistance", new Color(0x99, 0x45, 0x3a))); self::registerEffect(new Effect(Effect::FIRE_RESISTANCE, "%potion.fireResistance", new Color(0xe4, 0x9a, 0x3a))); self::registerEffect(new Effect(Effect::WATER_BREATHING, "%potion.waterBreathing", new Color(0x2e, 0x52, 0x99))); - self::registerEffect(new Effect(Effect::INVISIBILITY, "%potion.invisibility", new Color(0x7f, 0x83, 0x92))); + self::registerEffect(new InvisibilityEffect(Effect::INVISIBILITY, "%potion.invisibility", new Color(0x7f, 0x83, 0x92))); self::registerEffect(new Effect(Effect::BLINDNESS, "%potion.blindness", new Color(0x1f, 0x1f, 0x23), true)); self::registerEffect(new Effect(Effect::NIGHT_VISION, "%potion.nightVision", new Color(0x1f, 0x1f, 0xa1))); - self::registerEffect(new Effect(Effect::HUNGER, "%potion.hunger", new Color(0x58, 0x76, 0x53), true)); + self::registerEffect(new HungerEffect(Effect::HUNGER, "%potion.hunger", new Color(0x58, 0x76, 0x53), true)); self::registerEffect(new Effect(Effect::WEAKNESS, "%potion.weakness", new Color(0x48, 0x4d, 0x48), true)); - self::registerEffect(new Effect(Effect::POISON, "%potion.poison", new Color(0x4e, 0x93, 0x31), true)); - self::registerEffect(new Effect(Effect::WITHER, "%potion.wither", new Color(0x35, 0x2a, 0x27), true)); - self::registerEffect(new Effect(Effect::HEALTH_BOOST, "%potion.healthBoost", new Color(0xf8, 0x7d, 0x23))); - self::registerEffect(new Effect(Effect::ABSORPTION, "%potion.absorption", new Color(0x25, 0x52, 0xa5))); - self::registerEffect(new Effect(Effect::SATURATION, "%potion.saturation", new Color(0xf8, 0x24, 0x23), false, 1)); - self::registerEffect(new Effect(Effect::LEVITATION, "%potion.levitation", new Color(0xce, 0xff, 0xff))); - self::registerEffect(new Effect(Effect::FATAL_POISON, "%potion.poison", new Color(0x4e, 0x93, 0x31), true)); + self::registerEffect(new PoisonEffect(Effect::POISON, "%potion.poison", new Color(0x4e, 0x93, 0x31), true)); + self::registerEffect(new WitherEffect(Effect::WITHER, "%potion.wither", new Color(0x35, 0x2a, 0x27), true)); + self::registerEffect(new HealthBoostEffect(Effect::HEALTH_BOOST, "%potion.healthBoost", new Color(0xf8, 0x7d, 0x23))); + self::registerEffect(new AbsorptionEffect(Effect::ABSORPTION, "%potion.absorption", new Color(0x25, 0x52, 0xa5))); + self::registerEffect(new SaturationEffect(Effect::SATURATION, "%potion.saturation", new Color(0xf8, 0x24, 0x23), false)); + self::registerEffect(new LevitationEffect(Effect::LEVITATION, "%potion.levitation", new Color(0xce, 0xff, 0xff))); + self::registerEffect(new PoisonEffect(Effect::FATAL_POISON, "%potion.poison", new Color(0x4e, 0x93, 0x31), true, true, true)); self::registerEffect(new Effect(Effect::CONDUIT_POWER, "%potion.conduitPower", new Color(0x1d, 0xc2, 0xd1))); } @@ -130,8 +138,6 @@ class Effect{ protected $color; /** @var bool */ protected $bad; - /** @var int */ - protected $defaultDuration; /** @var bool */ protected $hasBubbles; @@ -140,15 +146,13 @@ class Effect{ * @param string $name Translation key used for effect name * @param Color $color * @param bool $isBad Whether the effect is harmful - * @param int $defaultDuration Duration in ticks the effect will last for by default if applied without a duration. * @param bool $hasBubbles Whether the effect has potion bubbles. Some do not (e.g. Instant Damage has its own particles instead of bubbles) */ - public function __construct(int $id, string $name, Color $color, bool $isBad = false, int $defaultDuration = 300 * 20, bool $hasBubbles = true){ + public function __construct(int $id, string $name, Color $color, bool $isBad = false, bool $hasBubbles = true){ $this->id = $id; $this->name = $name; $this->color = $color; $this->bad = $isBad; - $this->defaultDuration = $defaultDuration; $this->hasBubbles = $hasBubbles; } @@ -186,20 +190,12 @@ class Effect{ return $this->bad; } - /** - * Returns whether the effect is by default an instant effect. - * @return bool - */ - public function isInstantEffect() : bool{ - return $this->defaultDuration <= 1; - } - /** * Returns the default duration this effect will apply for if a duration is not specified. * @return int */ public function getDefaultDuration() : int{ - return $this->defaultDuration; + return 600; } /** @@ -218,31 +214,6 @@ class Effect{ * @return bool */ public function canTick(EffectInstance $instance) : bool{ - switch($this->id){ - case Effect::POISON: - case Effect::FATAL_POISON: - if(($interval = (25 >> $instance->getAmplifier())) > 0){ - return ($instance->getDuration() % $interval) === 0; - } - return true; - case Effect::WITHER: - if(($interval = (50 >> $instance->getAmplifier())) > 0){ - return ($instance->getDuration() % $interval) === 0; - } - return true; - case Effect::REGENERATION: - if(($interval = (40 >> $instance->getAmplifier())) > 0){ - return ($instance->getDuration() % $interval) === 0; - } - return true; - case Effect::HUNGER: - return true; - case Effect::INSTANT_DAMAGE: - case Effect::INSTANT_HEALTH: - case Effect::SATURATION: - //If forced to last longer than 1 tick, these apply every tick. - return true; - } return false; } @@ -253,63 +224,9 @@ class Effect{ * @param EffectInstance $instance * @param float $potency * @param null|Entity $source - * @param null|Entity $sourceOwner */ - public function applyEffect(Living $entity, EffectInstance $instance, float $potency = 1.0, ?Entity $source = null, ?Entity $sourceOwner = null) : void{ - switch($this->id){ - /** @noinspection PhpMissingBreakStatementInspection */ - case Effect::POISON: - if($entity->getHealth() <= 1){ - break; - } - case Effect::FATAL_POISON: - $ev = new EntityDamageEvent($entity, EntityDamageEvent::CAUSE_MAGIC, 1); - $entity->attack($ev); - break; + public function applyEffect(Living $entity, EffectInstance $instance, float $potency = 1.0, ?Entity $source = null) : void{ - case Effect::WITHER: - $ev = new EntityDamageEvent($entity, EntityDamageEvent::CAUSE_MAGIC, 1); - $entity->attack($ev); - break; - - case Effect::REGENERATION: - if($entity->getHealth() < $entity->getMaxHealth()){ - $ev = new EntityRegainHealthEvent($entity, 1, EntityRegainHealthEvent::CAUSE_MAGIC); - $entity->heal($ev); - } - break; - - case Effect::HUNGER: - if($entity instanceof Human){ - $entity->exhaust(0.025 * $instance->getEffectLevel(), PlayerExhaustEvent::CAUSE_POTION); - } - break; - case Effect::INSTANT_HEALTH: - //TODO: add particles (witch spell) - if($entity->getHealth() < $entity->getMaxHealth()){ - $entity->heal(new EntityRegainHealthEvent($entity, (4 << $instance->getAmplifier()) * $potency, EntityRegainHealthEvent::CAUSE_MAGIC)); - } - break; - case Effect::INSTANT_DAMAGE: - //TODO: add particles (witch spell) - $damage = (4 << $instance->getAmplifier()) * $potency; - if($source !== null and $sourceOwner !== null){ - $ev = new EntityDamageByChildEntityEvent($sourceOwner, $source, $entity, EntityDamageEvent::CAUSE_MAGIC, $damage); - }elseif($source !== null){ - $ev = new EntityDamageByEntityEvent($source, $entity, EntityDamageEvent::CAUSE_MAGIC, $damage); - }else{ - $ev = new EntityDamageEvent($entity, EntityDamageEvent::CAUSE_MAGIC, $damage); - } - $entity->attack($ev); - - break; - case Effect::SATURATION: - if($entity instanceof Human){ - $entity->addFood($instance->getEffectLevel()); - $entity->addSaturation($instance->getEffectLevel() * 2); - } - break; - } } /** @@ -319,30 +236,7 @@ class Effect{ * @param EffectInstance $instance */ public function add(Living $entity, EffectInstance $instance) : void{ - switch($this->id){ - case Effect::INVISIBILITY: - $entity->setInvisible(); - $entity->setNameTagVisible(false); - break; - case Effect::SPEED: - $attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED); - $attr->setValue($attr->getValue() * (1 + 0.2 * $instance->getEffectLevel())); - break; - case Effect::SLOWNESS: - $attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED); - $attr->setValue($attr->getValue() * (1 - 0.15 * $instance->getEffectLevel()), true); - break; - case Effect::HEALTH_BOOST: - $entity->setMaxHealth($entity->getMaxHealth() + 4 * $instance->getEffectLevel()); - break; - case Effect::ABSORPTION: - $new = (4 * $instance->getEffectLevel()); - if($new > $entity->getAbsorption()){ - $entity->setAbsorption($new); - } - break; - } } /** @@ -352,26 +246,7 @@ class Effect{ * @param EffectInstance $instance */ public function remove(Living $entity, EffectInstance $instance) : void{ - switch($this->id){ - case Effect::INVISIBILITY: - $entity->setInvisible(false); - $entity->setNameTagVisible(true); - break; - case Effect::SPEED: - $attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED); - $attr->setValue($attr->getValue() / (1 + 0.2 * $instance->getEffectLevel())); - break; - case Effect::SLOWNESS: - $attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED); - $attr->setValue($attr->getValue() / (1 - 0.15 * $instance->getEffectLevel())); - break; - case Effect::HEALTH_BOOST: - $entity->setMaxHealth($entity->getMaxHealth() - 4 * $instance->getEffectLevel()); - break; - case Effect::ABSORPTION: - $entity->setAbsorption(0); - break; - } + } public function __clone(){ diff --git a/src/pocketmine/entity/effect/AbsorptionEffect.php b/src/pocketmine/entity/effect/AbsorptionEffect.php new file mode 100644 index 0000000000..75aeff4e40 --- /dev/null +++ b/src/pocketmine/entity/effect/AbsorptionEffect.php @@ -0,0 +1,42 @@ +getEffectLevel()); + if($new > $entity->getAbsorption()){ + $entity->setAbsorption($new); + } + } + + public function remove(Living $entity, EffectInstance $instance) : void{ + $entity->setAbsorption(0); + } +} diff --git a/src/pocketmine/entity/effect/HealthBoostEffect.php b/src/pocketmine/entity/effect/HealthBoostEffect.php new file mode 100644 index 0000000000..86f92924d9 --- /dev/null +++ b/src/pocketmine/entity/effect/HealthBoostEffect.php @@ -0,0 +1,39 @@ +setMaxHealth($entity->getMaxHealth() + 4 * $instance->getEffectLevel()); + } + + public function remove(Living $entity, EffectInstance $instance) : void{ + $entity->setMaxHealth($entity->getMaxHealth() - 4 * $instance->getEffectLevel()); + } +} diff --git a/src/pocketmine/entity/effect/HungerEffect.php b/src/pocketmine/entity/effect/HungerEffect.php new file mode 100644 index 0000000000..c7f8c66921 --- /dev/null +++ b/src/pocketmine/entity/effect/HungerEffect.php @@ -0,0 +1,44 @@ +exhaust(0.025 * $instance->getEffectLevel(), PlayerExhaustEvent::CAUSE_POTION); + } + } +} diff --git a/src/pocketmine/entity/effect/InstantDamageEffect.php b/src/pocketmine/entity/effect/InstantDamageEffect.php new file mode 100644 index 0000000000..ffd8e007ad --- /dev/null +++ b/src/pocketmine/entity/effect/InstantDamageEffect.php @@ -0,0 +1,50 @@ +getAmplifier()) * $potency; + if($source !== null){ + $sourceOwner = $source->getOwningEntity(); + if($sourceOwner !== null){ + $ev = new EntityDamageByChildEntityEvent($sourceOwner, $source, $entity, EntityDamageEvent::CAUSE_MAGIC, $damage); + }else{ + $ev = new EntityDamageByEntityEvent($source, $entity, EntityDamageEvent::CAUSE_MAGIC, $damage); + } + }else{ + $ev = new EntityDamageEvent($entity, EntityDamageEvent::CAUSE_MAGIC, $damage); + } + $entity->attack($ev); + } +} diff --git a/src/pocketmine/entity/effect/InstantEffect.php b/src/pocketmine/entity/effect/InstantEffect.php new file mode 100644 index 0000000000..5ed863cb72 --- /dev/null +++ b/src/pocketmine/entity/effect/InstantEffect.php @@ -0,0 +1,38 @@ +getHealth() < $entity->getMaxHealth()){ + $entity->heal(new EntityRegainHealthEvent($entity, (4 << $instance->getAmplifier()) * $potency, EntityRegainHealthEvent::CAUSE_MAGIC)); + } + } + +} diff --git a/src/pocketmine/entity/effect/InvisibilityEffect.php b/src/pocketmine/entity/effect/InvisibilityEffect.php new file mode 100644 index 0000000000..6cd552c479 --- /dev/null +++ b/src/pocketmine/entity/effect/InvisibilityEffect.php @@ -0,0 +1,41 @@ +setInvisible(); + $entity->setNameTagVisible(false); + } + + public function remove(Living $entity, EffectInstance $instance) : void{ + $entity->setInvisible(false); + $entity->setNameTagVisible(); + } +} diff --git a/src/pocketmine/entity/effect/LevitationEffect.php b/src/pocketmine/entity/effect/LevitationEffect.php new file mode 100644 index 0000000000..b75b0bd0c2 --- /dev/null +++ b/src/pocketmine/entity/effect/LevitationEffect.php @@ -0,0 +1,51 @@ +addMotion(0, ($instance->getEffectLevel() / 20 - $entity->getMotion()->y) / 5, 0); + } + } + + public function add(Living $entity, EffectInstance $instance) : void{ + $entity->setHasGravity(false); + } + + public function remove(Living $entity, EffectInstance $instance) : void{ + $entity->setHasGravity(); + } +} diff --git a/src/pocketmine/entity/effect/PoisonEffect.php b/src/pocketmine/entity/effect/PoisonEffect.php new file mode 100644 index 0000000000..1f2da37d53 --- /dev/null +++ b/src/pocketmine/entity/effect/PoisonEffect.php @@ -0,0 +1,56 @@ +fatal = $fatal; + } + + public function canTick(EffectInstance $instance) : bool{ + if(($interval = (25 >> $instance->getAmplifier())) > 0){ + return ($instance->getDuration() % $interval) === 0; + } + return true; + } + + public function applyEffect(Living $entity, EffectInstance $instance, float $potency = 1.0, ?Entity $source = null) : void{ + if($entity->getHealth() > 1 or $this->fatal){ + $ev = new EntityDamageEvent($entity, EntityDamageEvent::CAUSE_MAGIC, 1); + $entity->attack($ev); + } + } +} diff --git a/src/pocketmine/entity/effect/RegenerationEffect.php b/src/pocketmine/entity/effect/RegenerationEffect.php new file mode 100644 index 0000000000..02d353ca7f --- /dev/null +++ b/src/pocketmine/entity/effect/RegenerationEffect.php @@ -0,0 +1,47 @@ +> $instance->getAmplifier())) > 0){ + return ($instance->getDuration() % $interval) === 0; + } + return true; + } + + public function applyEffect(Living $entity, EffectInstance $instance, float $potency = 1.0, ?Entity $source = null) : void{ + if($entity->getHealth() < $entity->getMaxHealth()){ + $ev = new EntityRegainHealthEvent($entity, 1, EntityRegainHealthEvent::CAUSE_MAGIC); + $entity->heal($ev); + } + } +} diff --git a/src/pocketmine/entity/effect/SaturationEffect.php b/src/pocketmine/entity/effect/SaturationEffect.php new file mode 100644 index 0000000000..aea9ce762d --- /dev/null +++ b/src/pocketmine/entity/effect/SaturationEffect.php @@ -0,0 +1,39 @@ +addFood($instance->getEffectLevel()); + $entity->addSaturation($instance->getEffectLevel() * 2); + } + } +} diff --git a/src/pocketmine/entity/effect/SlownessEffect.php b/src/pocketmine/entity/effect/SlownessEffect.php new file mode 100644 index 0000000000..59bfe4f8f1 --- /dev/null +++ b/src/pocketmine/entity/effect/SlownessEffect.php @@ -0,0 +1,42 @@ +getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED); + $attr->setValue($attr->getValue() * (1 - 0.15 * $instance->getEffectLevel()), true); + } + + public function remove(Living $entity, EffectInstance $instance) : void{ + $attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED); + $attr->setValue($attr->getValue() / (1 - 0.15 * $instance->getEffectLevel())); + } +} diff --git a/src/pocketmine/entity/effect/SpeedEffect.php b/src/pocketmine/entity/effect/SpeedEffect.php new file mode 100644 index 0000000000..dbd1b4d216 --- /dev/null +++ b/src/pocketmine/entity/effect/SpeedEffect.php @@ -0,0 +1,42 @@ +getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED); + $attr->setValue($attr->getValue() * (1 + 0.2 * $instance->getEffectLevel())); + } + + public function remove(Living $entity, EffectInstance $instance) : void{ + $attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED); + $attr->setValue($attr->getValue() / (1 + 0.2 * $instance->getEffectLevel())); + } +} diff --git a/src/pocketmine/entity/effect/WitherEffect.php b/src/pocketmine/entity/effect/WitherEffect.php new file mode 100644 index 0000000000..89f53b1e3b --- /dev/null +++ b/src/pocketmine/entity/effect/WitherEffect.php @@ -0,0 +1,45 @@ +> $instance->getAmplifier())) > 0){ + return ($instance->getDuration() % $interval) === 0; + } + return true; + } + + public function applyEffect(Living $entity, EffectInstance $instance, float $potency = 1.0, ?Entity $source = null) : void{ + $ev = new EntityDamageEvent($entity, EntityDamageEvent::CAUSE_MAGIC, 1); + $entity->attack($ev); + } +} diff --git a/src/pocketmine/entity/projectile/SplashPotion.php b/src/pocketmine/entity/projectile/SplashPotion.php index e135eafc53..4484d7eefc 100644 --- a/src/pocketmine/entity/projectile/SplashPotion.php +++ b/src/pocketmine/entity/projectile/SplashPotion.php @@ -25,6 +25,7 @@ namespace pocketmine\entity\projectile; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\entity\effect\InstantEffect; use pocketmine\entity\EffectInstance; use pocketmine\entity\Living; use pocketmine\event\entity\ProjectileHitBlockEvent; @@ -101,7 +102,7 @@ class SplashPotion extends Throwable{ foreach($this->getPotionEffects() as $effect){ //getPotionEffects() is used to get COPIES to avoid accidentally modifying the same effect instance already applied to another entity - if(!$effect->getType()->isInstantEffect()){ + if(!($effect->getType() instanceof InstantEffect)){ $newDuration = (int) round($effect->getDuration() * 0.75 * $distanceMultiplier); if($newDuration < 20){ continue; @@ -109,7 +110,7 @@ class SplashPotion extends Throwable{ $effect->setDuration($newDuration); $entity->addEffect($effect); }else{ - $effect->getType()->applyEffect($entity, $effect, $distanceMultiplier, $this, $this->getOwningEntity()); + $effect->getType()->applyEffect($entity, $effect, $distanceMultiplier, $this); } } } From a6237958e82e7df1d6fa7b3295cf100965067d2b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 27 Jan 2019 20:41:47 +0000 Subject: [PATCH 0442/3224] Level: fix another crashy edge case in chunk ticking this also removes a bias towards the chunk that the player is on, because this makes such chunks tick faster than adjacent chunks. --- src/pocketmine/level/Level.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 579569202c..ea0f18e0f3 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -970,8 +970,6 @@ class Level implements ChunkManager, Metadatable{ $chunkX = (int) floor($loader->getX()) >> 4; $chunkZ = (int) floor($loader->getZ()) >> 4; - $index = Level::chunkHash($chunkX, $chunkZ); - $chunkTickList[$index] = true; for($chunk = 0; $chunk < $chunksPerLoader; ++$chunk){ $dx = mt_rand(-$randRange, $randRange); $dz = mt_rand(-$randRange, $randRange); From 78dfcc5f2df10a1e572256e3a9af243a40cbfe5c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 28 Jan 2019 15:40:39 +0000 Subject: [PATCH 0443/3224] Move Effect and EffectInstance to entity\effect namespace --- src/pocketmine/Player.php | 4 ++-- src/pocketmine/block/Cake.php | 2 +- .../command/defaults/EffectCommand.php | 4 ++-- src/pocketmine/entity/EntityFactory.php | 1 + src/pocketmine/entity/Human.php | 2 ++ src/pocketmine/entity/Living.php | 2 ++ .../entity/effect/AbsorptionEffect.php | 2 -- src/pocketmine/entity/{ => effect}/Effect.php | 17 +++-------------- .../entity/{ => effect}/EffectInstance.php | 2 +- .../entity/effect/HealthBoostEffect.php | 2 -- src/pocketmine/entity/effect/HungerEffect.php | 2 -- .../entity/effect/InstantDamageEffect.php | 1 - src/pocketmine/entity/effect/InstantEffect.php | 3 --- .../entity/effect/InstantHealthEffect.php | 1 - .../entity/effect/InvisibilityEffect.php | 2 -- .../entity/effect/LevitationEffect.php | 2 -- src/pocketmine/entity/effect/PoisonEffect.php | 2 -- .../entity/effect/RegenerationEffect.php | 2 -- .../entity/effect/SaturationEffect.php | 1 - src/pocketmine/entity/effect/SlownessEffect.php | 2 -- src/pocketmine/entity/effect/SpeedEffect.php | 2 -- src/pocketmine/entity/effect/WitherEffect.php | 2 -- .../entity/projectile/SplashPotion.php | 2 +- .../event/entity/EntityDamageByEntityEvent.php | 2 +- .../event/entity/EntityEffectAddEvent.php | 2 +- .../event/entity/EntityEffectEvent.php | 2 +- src/pocketmine/item/Consumable.php | 2 +- src/pocketmine/item/GoldenApple.php | 4 ++-- src/pocketmine/item/GoldenAppleEnchanted.php | 4 ++-- src/pocketmine/item/PoisonousPotato.php | 4 ++-- src/pocketmine/item/Potion.php | 4 ++-- src/pocketmine/item/Pufferfish.php | 4 ++-- src/pocketmine/item/RawChicken.php | 4 ++-- src/pocketmine/item/RottenFlesh.php | 4 ++-- src/pocketmine/item/SpiderEye.php | 4 ++-- 35 files changed, 35 insertions(+), 67 deletions(-) rename src/pocketmine/entity/{ => effect}/Effect.php (92%) rename src/pocketmine/entity/{ => effect}/EffectInstance.php (99%) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 3d26f3a251..19b30bc2ca 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -28,8 +28,8 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\command\Command; use pocketmine\command\CommandSender; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; +use pocketmine\entity\effect\Effect; +use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\Entity; use pocketmine\entity\Human; use pocketmine\entity\object\ItemEntity; diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index f50b09dc15..5518c467ec 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; -use pocketmine\entity\EffectInstance; +use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\Living; use pocketmine\item\FoodSource; use pocketmine\item\Item; diff --git a/src/pocketmine/command/defaults/EffectCommand.php b/src/pocketmine/command/defaults/EffectCommand.php index a13967bd1d..34dffb8be2 100644 --- a/src/pocketmine/command/defaults/EffectCommand.php +++ b/src/pocketmine/command/defaults/EffectCommand.php @@ -25,8 +25,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; +use pocketmine\entity\effect\Effect; +use pocketmine\entity\effect\EffectInstance; use pocketmine\lang\TranslationContainer; use pocketmine\utils\TextFormat; use function count; diff --git a/src/pocketmine/entity/EntityFactory.php b/src/pocketmine/entity/EntityFactory.php index 30f3f78ccc..75bd41e19d 100644 --- a/src/pocketmine/entity/EntityFactory.php +++ b/src/pocketmine/entity/EntityFactory.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\entity; +use pocketmine\entity\effect\Effect; use pocketmine\entity\object\ExperienceOrb; use pocketmine\entity\object\FallingBlock; use pocketmine\entity\object\ItemEntity; diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index e9b38dc1c9..266ea5aaa9 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\entity; +use pocketmine\entity\effect\Effect; +use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\projectile\ProjectileSource; use pocketmine\entity\utils\ExperienceUtils; use pocketmine\event\entity\EntityDamageEvent; diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 2446808e3d..409184983a 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -24,6 +24,8 @@ declare(strict_types=1); namespace pocketmine\entity; use pocketmine\block\Block; +use pocketmine\entity\effect\Effect; +use pocketmine\entity\effect\EffectInstance; use pocketmine\event\entity\EntityArmorChangeEvent; use pocketmine\event\entity\EntityDamageByChildEntityEvent; use pocketmine\event\entity\EntityDamageByEntityEvent; diff --git a/src/pocketmine/entity/effect/AbsorptionEffect.php b/src/pocketmine/entity/effect/AbsorptionEffect.php index 75aeff4e40..0d7f60513c 100644 --- a/src/pocketmine/entity/effect/AbsorptionEffect.php +++ b/src/pocketmine/entity/effect/AbsorptionEffect.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\entity\effect; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; use pocketmine\entity\Living; class AbsorptionEffect extends Effect{ diff --git a/src/pocketmine/entity/Effect.php b/src/pocketmine/entity/effect/Effect.php similarity index 92% rename from src/pocketmine/entity/Effect.php rename to src/pocketmine/entity/effect/Effect.php index f35b4dc961..f6d7466f34 100644 --- a/src/pocketmine/entity/Effect.php +++ b/src/pocketmine/entity/effect/Effect.php @@ -21,21 +21,10 @@ declare(strict_types=1); -namespace pocketmine\entity; +namespace pocketmine\entity\effect; -use pocketmine\entity\effect\AbsorptionEffect; -use pocketmine\entity\effect\HealthBoostEffect; -use pocketmine\entity\effect\HungerEffect; -use pocketmine\entity\effect\InstantDamageEffect; -use pocketmine\entity\effect\InstantHealthEffect; -use pocketmine\entity\effect\InvisibilityEffect; -use pocketmine\entity\effect\LevitationEffect; -use pocketmine\entity\effect\PoisonEffect; -use pocketmine\entity\effect\RegenerationEffect; -use pocketmine\entity\effect\SaturationEffect; -use pocketmine\entity\effect\SlownessEffect; -use pocketmine\entity\effect\SpeedEffect; -use pocketmine\entity\effect\WitherEffect; +use pocketmine\entity\Entity; +use pocketmine\entity\Living; use pocketmine\utils\Color; use function constant; use function defined; diff --git a/src/pocketmine/entity/EffectInstance.php b/src/pocketmine/entity/effect/EffectInstance.php similarity index 99% rename from src/pocketmine/entity/EffectInstance.php rename to src/pocketmine/entity/effect/EffectInstance.php index c66341926a..f3707f6725 100644 --- a/src/pocketmine/entity/EffectInstance.php +++ b/src/pocketmine/entity/effect/EffectInstance.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\entity; +namespace pocketmine\entity\effect; use pocketmine\utils\Color; use function max; diff --git a/src/pocketmine/entity/effect/HealthBoostEffect.php b/src/pocketmine/entity/effect/HealthBoostEffect.php index 86f92924d9..c1d2439da0 100644 --- a/src/pocketmine/entity/effect/HealthBoostEffect.php +++ b/src/pocketmine/entity/effect/HealthBoostEffect.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\entity\effect; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; use pocketmine\entity\Living; class HealthBoostEffect extends Effect{ diff --git a/src/pocketmine/entity/effect/HungerEffect.php b/src/pocketmine/entity/effect/HungerEffect.php index c7f8c66921..25599c6b9e 100644 --- a/src/pocketmine/entity/effect/HungerEffect.php +++ b/src/pocketmine/entity/effect/HungerEffect.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\entity\effect; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; use pocketmine\entity\Entity; use pocketmine\entity\Human; use pocketmine\entity\Living; diff --git a/src/pocketmine/entity/effect/InstantDamageEffect.php b/src/pocketmine/entity/effect/InstantDamageEffect.php index ffd8e007ad..88a22b8040 100644 --- a/src/pocketmine/entity/effect/InstantDamageEffect.php +++ b/src/pocketmine/entity/effect/InstantDamageEffect.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\entity\effect; -use pocketmine\entity\EffectInstance; use pocketmine\entity\Entity; use pocketmine\entity\Living; use pocketmine\event\entity\EntityDamageByChildEntityEvent; diff --git a/src/pocketmine/entity/effect/InstantEffect.php b/src/pocketmine/entity/effect/InstantEffect.php index 5ed863cb72..6539259188 100644 --- a/src/pocketmine/entity/effect/InstantEffect.php +++ b/src/pocketmine/entity/effect/InstantEffect.php @@ -23,9 +23,6 @@ declare(strict_types=1); namespace pocketmine\entity\effect; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; - abstract class InstantEffect extends Effect{ public function getDefaultDuration() : int{ diff --git a/src/pocketmine/entity/effect/InstantHealthEffect.php b/src/pocketmine/entity/effect/InstantHealthEffect.php index 9195b6b53c..a591f237f4 100644 --- a/src/pocketmine/entity/effect/InstantHealthEffect.php +++ b/src/pocketmine/entity/effect/InstantHealthEffect.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\entity\effect; -use pocketmine\entity\EffectInstance; use pocketmine\entity\Entity; use pocketmine\entity\Living; use pocketmine\event\entity\EntityRegainHealthEvent; diff --git a/src/pocketmine/entity/effect/InvisibilityEffect.php b/src/pocketmine/entity/effect/InvisibilityEffect.php index 6cd552c479..e170630679 100644 --- a/src/pocketmine/entity/effect/InvisibilityEffect.php +++ b/src/pocketmine/entity/effect/InvisibilityEffect.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\entity\effect; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; use pocketmine\entity\Living; class InvisibilityEffect extends Effect{ diff --git a/src/pocketmine/entity/effect/LevitationEffect.php b/src/pocketmine/entity/effect/LevitationEffect.php index b75b0bd0c2..746ad49adf 100644 --- a/src/pocketmine/entity/effect/LevitationEffect.php +++ b/src/pocketmine/entity/effect/LevitationEffect.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\entity\effect; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; use pocketmine\entity\Entity; use pocketmine\entity\Living; use pocketmine\Player; diff --git a/src/pocketmine/entity/effect/PoisonEffect.php b/src/pocketmine/entity/effect/PoisonEffect.php index 1f2da37d53..2c351981a2 100644 --- a/src/pocketmine/entity/effect/PoisonEffect.php +++ b/src/pocketmine/entity/effect/PoisonEffect.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\entity\effect; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; use pocketmine\entity\Entity; use pocketmine\entity\Living; use pocketmine\event\entity\EntityDamageEvent; diff --git a/src/pocketmine/entity/effect/RegenerationEffect.php b/src/pocketmine/entity/effect/RegenerationEffect.php index 02d353ca7f..ed5ca0f5f8 100644 --- a/src/pocketmine/entity/effect/RegenerationEffect.php +++ b/src/pocketmine/entity/effect/RegenerationEffect.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\entity\effect; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; use pocketmine\entity\Entity; use pocketmine\entity\Living; use pocketmine\event\entity\EntityRegainHealthEvent; diff --git a/src/pocketmine/entity/effect/SaturationEffect.php b/src/pocketmine/entity/effect/SaturationEffect.php index aea9ce762d..e20eeec83a 100644 --- a/src/pocketmine/entity/effect/SaturationEffect.php +++ b/src/pocketmine/entity/effect/SaturationEffect.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\entity\effect; -use pocketmine\entity\EffectInstance; use pocketmine\entity\Entity; use pocketmine\entity\Human; use pocketmine\entity\Living; diff --git a/src/pocketmine/entity/effect/SlownessEffect.php b/src/pocketmine/entity/effect/SlownessEffect.php index 59bfe4f8f1..8fbbc9912b 100644 --- a/src/pocketmine/entity/effect/SlownessEffect.php +++ b/src/pocketmine/entity/effect/SlownessEffect.php @@ -24,8 +24,6 @@ declare(strict_types=1); namespace pocketmine\entity\effect; use pocketmine\entity\Attribute; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; use pocketmine\entity\Living; class SlownessEffect extends Effect{ diff --git a/src/pocketmine/entity/effect/SpeedEffect.php b/src/pocketmine/entity/effect/SpeedEffect.php index dbd1b4d216..5f0cc29f52 100644 --- a/src/pocketmine/entity/effect/SpeedEffect.php +++ b/src/pocketmine/entity/effect/SpeedEffect.php @@ -24,8 +24,6 @@ declare(strict_types=1); namespace pocketmine\entity\effect; use pocketmine\entity\Attribute; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; use pocketmine\entity\Living; class SpeedEffect extends Effect{ diff --git a/src/pocketmine/entity/effect/WitherEffect.php b/src/pocketmine/entity/effect/WitherEffect.php index 89f53b1e3b..5c8d6d4631 100644 --- a/src/pocketmine/entity/effect/WitherEffect.php +++ b/src/pocketmine/entity/effect/WitherEffect.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\entity\effect; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; use pocketmine\entity\Entity; use pocketmine\entity\Living; use pocketmine\event\entity\EntityDamageEvent; diff --git a/src/pocketmine/entity/projectile/SplashPotion.php b/src/pocketmine/entity/projectile/SplashPotion.php index 4484d7eefc..c718bcecb2 100644 --- a/src/pocketmine/entity/projectile/SplashPotion.php +++ b/src/pocketmine/entity/projectile/SplashPotion.php @@ -25,8 +25,8 @@ namespace pocketmine\entity\projectile; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\InstantEffect; -use pocketmine\entity\EffectInstance; use pocketmine\entity\Living; use pocketmine\event\entity\ProjectileHitBlockEvent; use pocketmine\event\entity\ProjectileHitEntityEvent; diff --git a/src/pocketmine/event/entity/EntityDamageByEntityEvent.php b/src/pocketmine/event/entity/EntityDamageByEntityEvent.php index a89a0dea71..d8f0212021 100644 --- a/src/pocketmine/event/entity/EntityDamageByEntityEvent.php +++ b/src/pocketmine/event/entity/EntityDamageByEntityEvent.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\event\entity; -use pocketmine\entity\Effect; +use pocketmine\entity\effect\Effect; use pocketmine\entity\Entity; use pocketmine\entity\Living; diff --git a/src/pocketmine/event/entity/EntityEffectAddEvent.php b/src/pocketmine/event/entity/EntityEffectAddEvent.php index d1a84c03b8..a42747f75f 100644 --- a/src/pocketmine/event/entity/EntityEffectAddEvent.php +++ b/src/pocketmine/event/entity/EntityEffectAddEvent.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\event\entity; -use pocketmine\entity\EffectInstance; +use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\Entity; /** diff --git a/src/pocketmine/event/entity/EntityEffectEvent.php b/src/pocketmine/event/entity/EntityEffectEvent.php index 01bdb47c7f..724944335d 100644 --- a/src/pocketmine/event/entity/EntityEffectEvent.php +++ b/src/pocketmine/event/entity/EntityEffectEvent.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\event\entity; -use pocketmine\entity\EffectInstance; +use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\Entity; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; diff --git a/src/pocketmine/item/Consumable.php b/src/pocketmine/item/Consumable.php index 5977c37f44..eac296fc8f 100644 --- a/src/pocketmine/item/Consumable.php +++ b/src/pocketmine/item/Consumable.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\Block; -use pocketmine\entity\EffectInstance; +use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\Living; /** diff --git a/src/pocketmine/item/GoldenApple.php b/src/pocketmine/item/GoldenApple.php index 4bd1c3fb90..edec3b2b3e 100644 --- a/src/pocketmine/item/GoldenApple.php +++ b/src/pocketmine/item/GoldenApple.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; +use pocketmine\entity\effect\Effect; +use pocketmine\entity\effect\EffectInstance; class GoldenApple extends Food{ diff --git a/src/pocketmine/item/GoldenAppleEnchanted.php b/src/pocketmine/item/GoldenAppleEnchanted.php index b5d8bc3055..120d67871d 100644 --- a/src/pocketmine/item/GoldenAppleEnchanted.php +++ b/src/pocketmine/item/GoldenAppleEnchanted.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; +use pocketmine\entity\effect\Effect; +use pocketmine\entity\effect\EffectInstance; class GoldenAppleEnchanted extends GoldenApple{ diff --git a/src/pocketmine/item/PoisonousPotato.php b/src/pocketmine/item/PoisonousPotato.php index 56ebe7032c..7f6e1203dd 100644 --- a/src/pocketmine/item/PoisonousPotato.php +++ b/src/pocketmine/item/PoisonousPotato.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; +use pocketmine\entity\effect\Effect; +use pocketmine\entity\effect\EffectInstance; use function mt_rand; class PoisonousPotato extends Food{ diff --git a/src/pocketmine/item/Potion.php b/src/pocketmine/item/Potion.php index bddab81e9d..40b8293e37 100644 --- a/src/pocketmine/item/Potion.php +++ b/src/pocketmine/item/Potion.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; +use pocketmine\entity\effect\Effect; +use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\Living; class Potion extends Item implements Consumable{ diff --git a/src/pocketmine/item/Pufferfish.php b/src/pocketmine/item/Pufferfish.php index 12d3a4c986..78b3958065 100644 --- a/src/pocketmine/item/Pufferfish.php +++ b/src/pocketmine/item/Pufferfish.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; +use pocketmine\entity\effect\Effect; +use pocketmine\entity\effect\EffectInstance; class Pufferfish extends Food{ public function __construct(){ diff --git a/src/pocketmine/item/RawChicken.php b/src/pocketmine/item/RawChicken.php index 746937e1c6..36e59357b5 100644 --- a/src/pocketmine/item/RawChicken.php +++ b/src/pocketmine/item/RawChicken.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; +use pocketmine\entity\effect\Effect; +use pocketmine\entity\effect\EffectInstance; use function mt_rand; class RawChicken extends Food{ diff --git a/src/pocketmine/item/RottenFlesh.php b/src/pocketmine/item/RottenFlesh.php index 3eebcba6b8..03045f76a5 100644 --- a/src/pocketmine/item/RottenFlesh.php +++ b/src/pocketmine/item/RottenFlesh.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; +use pocketmine\entity\effect\Effect; +use pocketmine\entity\effect\EffectInstance; use function lcg_value; class RottenFlesh extends Food{ diff --git a/src/pocketmine/item/SpiderEye.php b/src/pocketmine/item/SpiderEye.php index 2e386afb5b..97b6ff10d9 100644 --- a/src/pocketmine/item/SpiderEye.php +++ b/src/pocketmine/item/SpiderEye.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\Effect; -use pocketmine\entity\EffectInstance; +use pocketmine\entity\effect\Effect; +use pocketmine\entity\effect\EffectInstance; class SpiderEye extends Food{ public function __construct(){ From c3bbb8905c7eae81da24a69d863b030dcba1457e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 28 Jan 2019 17:33:58 +0000 Subject: [PATCH 0444/3224] Human: simplify setFood() --- src/pocketmine/entity/Human.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 266ea5aaa9..45573edbd5 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -206,18 +206,13 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $old = $attr->getValue(); $attr->setValue($new); - $reset = false; // ranges: 18-20 (regen), 7-17 (none), 1-6 (no sprint), 0 (health depletion) foreach([17, 6, 0] as $bound){ if(($old > $bound) !== ($new > $bound)){ - $reset = true; + $this->foodTickTimer = 0; break; } } - if($reset){ - $this->foodTickTimer = 0; - } - } public function getMaxFood() : float{ From 8387c08db2ee498772722c6d68b271af526b8cf3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 30 Jan 2019 16:53:12 +0000 Subject: [PATCH 0445/3224] Level: remove unused variable --- src/pocketmine/level/Level.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index e17922e4a5..96d77defd3 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -2631,7 +2631,7 @@ class Level implements ChunkManager, Metadatable{ } private function queueUnloadChunk(int $x, int $z){ - $this->unloadQueue[$index = Level::chunkHash($x, $z)] = microtime(true); + $this->unloadQueue[Level::chunkHash($x, $z)] = microtime(true); } public function unloadChunkRequest(int $x, int $z, bool $safe = true){ From 3e58708130d9a77c261b3a1355fa2e0163a5c7c6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 30 Jan 2019 19:41:20 +0000 Subject: [PATCH 0446/3224] Add some missing @throws annotations --- src/pocketmine/command/Command.php | 2 ++ src/pocketmine/event/Event.php | 2 -- .../inventory/transaction/CraftingTransaction.php | 1 + src/pocketmine/level/format/io/region/RegionLoader.php | 6 ++++++ src/pocketmine/network/mcpe/NetworkCipher.php | 6 ++++++ src/pocketmine/resourcepacks/ResourcePack.php | 1 + src/pocketmine/resourcepacks/ZippedResourcePack.php | 3 ++- 7 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/command/Command.php b/src/pocketmine/command/Command.php index 0e949f3f46..5099801c8a 100644 --- a/src/pocketmine/command/Command.php +++ b/src/pocketmine/command/Command.php @@ -26,6 +26,7 @@ declare(strict_types=1); */ namespace pocketmine\command; +use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TextContainer; use pocketmine\lang\TranslationContainer; use pocketmine\permission\PermissionManager; @@ -92,6 +93,7 @@ abstract class Command{ * @param string[] $args * * @return mixed + * @throws InvalidCommandSyntaxException */ abstract public function execute(CommandSender $sender, string $commandLabel, array $args); diff --git a/src/pocketmine/event/Event.php b/src/pocketmine/event/Event.php index 6123806812..9e96ccc175 100644 --- a/src/pocketmine/event/Event.php +++ b/src/pocketmine/event/Event.php @@ -48,8 +48,6 @@ abstract class Event{ * Calls event handlers registered for this event. * * @throws \RuntimeException if event call recursion reaches the max depth limit - * - * @throws \ReflectionException */ public function call() : void{ if(self::$eventCallDepth >= self::MAX_EVENT_CALL_DEPTH){ diff --git a/src/pocketmine/inventory/transaction/CraftingTransaction.php b/src/pocketmine/inventory/transaction/CraftingTransaction.php index c8610ebbc7..e01926ad14 100644 --- a/src/pocketmine/inventory/transaction/CraftingTransaction.php +++ b/src/pocketmine/inventory/transaction/CraftingTransaction.php @@ -50,6 +50,7 @@ class CraftingTransaction extends InventoryTransaction{ * @param int $iterations * * @return int + * @throws TransactionValidationException */ protected function matchRecipeItems(array $txItems, array $recipeItems, bool $wildcards, int $iterations = 0) : int{ if(empty($recipeItems)){ diff --git a/src/pocketmine/level/format/io/region/RegionLoader.php b/src/pocketmine/level/format/io/region/RegionLoader.php index f3b35ef828..b606267ddb 100644 --- a/src/pocketmine/level/format/io/region/RegionLoader.php +++ b/src/pocketmine/level/format/io/region/RegionLoader.php @@ -75,6 +75,9 @@ class RegionLoader{ $this->filePath = $filePath; } + /** + * @throws CorruptedRegionException + */ public function open() : void{ $exists = file_exists($this->filePath); if(!$exists){ @@ -219,6 +222,9 @@ class RegionLoader{ } } + /** + * @throws CorruptedRegionException + */ protected function loadLocationTable() : void{ fseek($this->filePointer, 0); $this->lastSector = 1; diff --git a/src/pocketmine/network/mcpe/NetworkCipher.php b/src/pocketmine/network/mcpe/NetworkCipher.php index 79bdfaba4e..b243fb88b4 100644 --- a/src/pocketmine/network/mcpe/NetworkCipher.php +++ b/src/pocketmine/network/mcpe/NetworkCipher.php @@ -63,6 +63,12 @@ class NetworkCipher{ $this->encryptCipher->encryptInit($this->key, $iv); } + /** + * @param string $encrypted + * + * @return string + * @throws \UnexpectedValueException + */ public function decrypt(string $encrypted) : string{ if(strlen($encrypted) < 9){ throw new \UnexpectedValueException("Payload is too short"); diff --git a/src/pocketmine/resourcepacks/ResourcePack.php b/src/pocketmine/resourcepacks/ResourcePack.php index 06c3b6ce52..c411c8fa6a 100644 --- a/src/pocketmine/resourcepacks/ResourcePack.php +++ b/src/pocketmine/resourcepacks/ResourcePack.php @@ -73,6 +73,7 @@ interface ResourcePack{ * @param int $length Maximum length of data to return. * * @return string byte-array + * @throws \InvalidArgumentException if the chunk does not exist */ public function getPackChunk(int $start, int $length) : string; } diff --git a/src/pocketmine/resourcepacks/ZippedResourcePack.php b/src/pocketmine/resourcepacks/ZippedResourcePack.php index 8aa4ca8cb7..7d23b3f9e3 100644 --- a/src/pocketmine/resourcepacks/ZippedResourcePack.php +++ b/src/pocketmine/resourcepacks/ZippedResourcePack.php @@ -75,6 +75,7 @@ class ZippedResourcePack implements ResourcePack{ /** * @param string $zipPath Path to the resource pack zip + * @throws ResourcePackException */ public function __construct(string $zipPath){ $this->path = $zipPath; @@ -148,7 +149,7 @@ class ZippedResourcePack implements ResourcePack{ public function getPackChunk(int $start, int $length) : string{ fseek($this->fileResource, $start); if(feof($this->fileResource)){ - throw new \RuntimeException("Requested a resource pack chunk with invalid start offset"); + throw new \InvalidArgumentException("Requested a resource pack chunk with invalid start offset"); } return fread($this->fileResource, $length); } From ad6ae20d6b59bf786520666becbfd836ccc0f4cc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Feb 2019 15:16:03 +0000 Subject: [PATCH 0447/3224] Server: fixed getOfflinePlayerData() trying to load terrain (?!?!?!?), closes #2725 getOfflinePlayerData() will now return NULL if there is no stored data for a given player. The responsibility of checking the spawn point is now delegated to the Player, after it registers a chunk loader on its spawn chunk. --- src/pocketmine/OfflinePlayer.php | 4 +--- src/pocketmine/Player.php | 41 ++++++++++++++++++++++---------- src/pocketmine/Server.php | 30 ++++++++--------------- 3 files changed, 40 insertions(+), 35 deletions(-) diff --git a/src/pocketmine/OfflinePlayer.php b/src/pocketmine/OfflinePlayer.php index 2b1d87a85b..9e9d88e147 100644 --- a/src/pocketmine/OfflinePlayer.php +++ b/src/pocketmine/OfflinePlayer.php @@ -45,9 +45,7 @@ class OfflinePlayer implements IPlayer, Metadatable{ public function __construct(Server $server, string $name){ $this->server = $server; $this->name = $name; - if($this->server->hasOfflinePlayerData($this->name)){ - $this->namedtag = $this->server->getOfflinePlayerData($this->name); - } + $this->namedtag = $this->server->getOfflinePlayerData($this->name); } public function isOnline() : bool{ diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 25a4664ed1..193c8e58a0 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -32,6 +32,7 @@ use pocketmine\command\CommandSender; use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\Entity; +use pocketmine\entity\EntityFactory; use pocketmine\entity\Human; use pocketmine\entity\object\ItemEntity; use pocketmine\entity\projectile\Arrow; @@ -1847,21 +1848,37 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ public function _actuallyConstruct(){ $namedtag = $this->server->getOfflinePlayerData($this->username); //TODO: make this async - if(($level = $this->server->getLevelManager()->getLevelByName($namedtag->getString("Level", "", true))) === null){ - /** @var Level $level */ - $level = $this->server->getLevelManager()->getDefaultLevel(); //TODO: default level may be null + $spawnReset = false; - $spawnLocation = $level->getSafeSpawn(); - $namedtag->setTag(new ListTag("Pos", [ - new DoubleTag("", $spawnLocation->x), - new DoubleTag("", $spawnLocation->y), - new DoubleTag("", $spawnLocation->z) - ])); + if($namedtag !== null and ($level = $this->server->getLevelManager()->getLevelByName($namedtag->getString("Level", "", true))) !== null){ + /** @var float[] $pos */ + $pos = $namedtag->getListTag("Pos")->getAllValues(); + $spawn = new Vector3($pos[0], $pos[1], $pos[2]); + }else{ + $level = $this->server->getLevelManager()->getDefaultLevel(); //TODO: default level might be null + $spawn = $level->getSpawnLocation(); + $spawnReset = true; } - /** @var float[] $pos */ - $pos = $namedtag->getListTag("Pos")->getAllValues(); - $level->registerChunkLoader($this, ((int) floor($pos[0])) >> 4, ((int) floor($pos[2])) >> 4, true); + //load the spawn chunk so we can see the terrain + $level->registerChunkLoader($this, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4, true); + if($spawnReset){ + $spawn = $level->getSafeSpawn($spawn); + } + + if($namedtag === null){ + $namedtag = EntityFactory::createBaseNBT($spawn); + + $namedtag->setByte("OnGround", 1); //TODO: this hack is needed for new players in-air ticks - they don't get detected as on-ground until they move + //TODO: old code had a TODO for SpawnForced + + }elseif($spawnReset){ + $namedtag->setTag(new ListTag("Pos", [ + new DoubleTag("", $spawn->x), + new DoubleTag("", $spawn->y), + new DoubleTag("", $spawn->z) + ])); + } parent::__construct($level, $namedtag); $ev = new PlayerLoginEvent($this, "Plugin reason"); diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 071606e289..fd721f7c5e 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -648,31 +648,21 @@ class Server{ /** * @param string $name * - * @return CompoundTag + * @return CompoundTag|null */ - public function getOfflinePlayerData(string $name) : CompoundTag{ + public function getOfflinePlayerData(string $name) : ?CompoundTag{ $name = strtolower($name); $path = $this->getDataPath() . "players/"; - if($this->shouldSavePlayerData()){ - if(file_exists($path . "$name.dat")){ - try{ - return (new BigEndianNbtSerializer())->readCompressed(file_get_contents($path . "$name.dat")); - }catch(NbtDataException $e){ //zlib decode error / corrupt data - rename($path . "$name.dat", $path . "$name.dat.bak"); - $this->logger->error($this->getLanguage()->translateString("pocketmine.data.playerCorrupted", [$name])); - } + + if(file_exists($path . "$name.dat")){ + try{ + return (new BigEndianNbtSerializer())->readCompressed(file_get_contents($path . "$name.dat")); + }catch(NbtDataException $e){ //zlib decode error / corrupt data + rename($path . "$name.dat", $path . "$name.dat.bak"); + $this->logger->error($this->getLanguage()->translateString("pocketmine.data.playerCorrupted", [$name])); } - $this->logger->notice($this->getLanguage()->translateString("pocketmine.data.playerNotFound", [$name])); } - $spawn = $this->levelManager->getDefaultLevel()->getSafeSpawn(); - - $nbt = EntityFactory::createBaseNBT($spawn); - - $nbt->setString("Level", $this->levelManager->getDefaultLevel()->getFolderName()); - $nbt->setByte("OnGround", 1); //TODO: this hack is needed for new players in-air ticks - they don't get detected as on-ground until they move - //TODO: old code had a TODO for SpawnForced - - return $nbt; + return null; } /** From dbae667dec733a8db2d72810c321cc70a2fd2e62 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Feb 2019 17:47:07 +0000 Subject: [PATCH 0448/3224] Silence more InteractPacket noise --- .../network/mcpe/handler/SimpleSessionHandler.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index 925eb334a2..81e44e3cae 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -284,11 +284,12 @@ class SimpleSessionHandler extends SessionHandler{ } public function handleInteract(InteractPacket $packet) : bool{ - if($packet->action === InteractPacket::ACTION_MOUSEOVER and $packet->target === 0){ + if($packet->action === InteractPacket::ACTION_MOUSEOVER){ //TODO HACK: silence useless spam (MCPE 1.8) - //this packet is EXPECTED to only be sent when interacting with an entity, but due to some messy Mojang - //hacks, it also sends it when changing the held item now, which causes us to think the inventory was closed - //when it wasn't. + //due to some messy Mojang hacks, it sends this when changing the held item now, which causes us to think + //the inventory was closed when it wasn't. + //this is also sent whenever entity metadata updates, which can get really spammy. + //TODO: implement handling for this where it matters return true; } return false; //TODO From 002f030970eaeedb1f3deaa14504cde13869e8de Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Feb 2019 11:54:25 +0000 Subject: [PATCH 0449/3224] EnderPearl: make a hack less messy --- src/pocketmine/entity/projectile/EnderPearl.php | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/pocketmine/entity/projectile/EnderPearl.php b/src/pocketmine/entity/projectile/EnderPearl.php index 2191a71eed..69922eccd4 100644 --- a/src/pocketmine/entity/projectile/EnderPearl.php +++ b/src/pocketmine/entity/projectile/EnderPearl.php @@ -38,16 +38,7 @@ class EnderPearl extends Throwable{ protected function calculateInterceptWithBlock(Block $block, Vector3 $start, Vector3 $end) : ?RayTraceResult{ if($block->getId() !== Block::AIR and empty($block->getCollisionBoxes())){ //TODO: remove this once block collision boxes are fixed properly - $bb = new AxisAlignedBB( - $block->x, - $block->y, - $block->z, - $block->x + 1, - $block->y + 1, - $block->z + 1 - ); - - return $bb->calculateIntercept($start, $end); + return AxisAlignedBB::one()->offset($block->x, $block->y, $block->z)->calculateIntercept($start, $end); } return parent::calculateInterceptWithBlock($block, $start, $end); From ce8d9fa9f4736885362d29b73ca3172abb29cab4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Feb 2019 11:59:40 +0000 Subject: [PATCH 0450/3224] Player: load chunks when registering as a loader, closes #2726 populateChunk() _sometimes_ does this, but not if the chunk is locked. This means that the empty chunk needed to prevent the shit hitting the fan isn't created when chunks are locked. This change resolves the problem because registerChunkLoader() calls loadChunk() with the create parameter as true when autoload is used. This is a shitty fix but it's the simplest one we have right now, and it works well. --- src/pocketmine/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 193c8e58a0..7e68408953 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -976,7 +976,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ ++$count; $this->usedChunks[$index] = false; - $this->level->registerChunkLoader($this, $X, $Z, false); + $this->level->registerChunkLoader($this, $X, $Z, true); if(!$this->level->populateChunk($X, $Z)){ continue; From 2c0f91ce509c0fff88471edf3b6ba7848e23802a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Feb 2019 18:49:20 +0000 Subject: [PATCH 0451/3224] Player: clean up chunk selection code --- src/pocketmine/Player.php | 76 ++++++++++++++------------------------- 1 file changed, 27 insertions(+), 49 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 7e68408953..9e9eb9da37 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1022,19 +1022,10 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } } - protected function orderChunks() : void{ - if(!$this->isConnected() or $this->viewDistance === -1){ - return; - } - - Timings::$playerChunkOrderTimer->startTiming(); - + protected function selectChunks() : \Generator{ $radius = $this->server->getAllowedViewDistance($this->viewDistance); $radiusSquared = $radius ** 2; - $newOrder = []; - $unloadChunks = $this->usedChunks; - $centerX = $this->getFloorX() >> 4; $centerZ = $this->getFloorZ() >> 4; @@ -1047,57 +1038,44 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ //If the chunk is in the radius, others at the same offsets in different quadrants are also guaranteed to be. /* Top right quadrant */ - if(!isset($this->usedChunks[$index = Level::chunkHash($centerX + $x, $centerZ + $z)]) or $this->usedChunks[$index] === false){ - $newOrder[$index] = true; - } - unset($unloadChunks[$index]); - + yield Level::chunkHash($centerX + $x, $centerZ + $z); /* Top left quadrant */ - if(!isset($this->usedChunks[$index = Level::chunkHash($centerX - $x - 1, $centerZ + $z)]) or $this->usedChunks[$index] === false){ - $newOrder[$index] = true; - } - unset($unloadChunks[$index]); - + yield Level::chunkHash($centerX - $x - 1, $centerZ + $z); /* Bottom right quadrant */ - if(!isset($this->usedChunks[$index = Level::chunkHash($centerX + $x, $centerZ - $z - 1)]) or $this->usedChunks[$index] === false){ - $newOrder[$index] = true; - } - unset($unloadChunks[$index]); - - + yield Level::chunkHash($centerX + $x, $centerZ - $z - 1); /* Bottom left quadrant */ - if(!isset($this->usedChunks[$index = Level::chunkHash($centerX - $x - 1, $centerZ - $z - 1)]) or $this->usedChunks[$index] === false){ - $newOrder[$index] = true; - } - unset($unloadChunks[$index]); + yield Level::chunkHash($centerX - $x - 1, $centerZ - $z - 1); if($x !== $z){ /* Top right quadrant mirror */ - if(!isset($this->usedChunks[$index = Level::chunkHash($centerX + $z, $centerZ + $x)]) or $this->usedChunks[$index] === false){ - $newOrder[$index] = true; - } - unset($unloadChunks[$index]); - + yield Level::chunkHash($centerX + $z, $centerZ + $x); /* Top left quadrant mirror */ - if(!isset($this->usedChunks[$index = Level::chunkHash($centerX - $z - 1, $centerZ + $x)]) or $this->usedChunks[$index] === false){ - $newOrder[$index] = true; - } - unset($unloadChunks[$index]); - + yield Level::chunkHash($centerX - $z - 1, $centerZ + $x); /* Bottom right quadrant mirror */ - if(!isset($this->usedChunks[$index = Level::chunkHash($centerX + $z, $centerZ - $x - 1)]) or $this->usedChunks[$index] === false){ - $newOrder[$index] = true; - } - unset($unloadChunks[$index]); - + yield Level::chunkHash($centerX + $z, $centerZ - $x - 1); /* Bottom left quadrant mirror */ - if(!isset($this->usedChunks[$index = Level::chunkHash($centerX - $z - 1, $centerZ - $x - 1)]) or $this->usedChunks[$index] === false){ - $newOrder[$index] = true; - } - unset($unloadChunks[$index]); + yield Level::chunkHash($centerX - $z - 1, $centerZ - $x - 1); } } } + } + + protected function orderChunks() : void{ + if(!$this->isConnected() or $this->viewDistance === -1){ + return; + } + + Timings::$playerChunkOrderTimer->startTiming(); + + $newOrder = []; + $unloadChunks = $this->usedChunks; + + foreach($this->selectChunks() as $hash){ + if(!isset($this->usedChunks[$hash]) or $this->usedChunks[$hash] === false){ + $newOrder[$hash] = true; + } + unset($unloadChunks[$hash]); + } foreach($unloadChunks as $index => $bool){ Level::getXZ($index, $X, $Z); From 923b1ad9a6b7f6802a79b142a0377eb99d24beb5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Feb 2019 19:51:41 +0000 Subject: [PATCH 0452/3224] Split up ChunkLoader and ChunkListener --- src/pocketmine/Player.php | 7 ++- src/pocketmine/level/ChunkListener.php | 80 ++++++++++++++++++++++++++ src/pocketmine/level/ChunkLoader.php | 51 ++-------------- src/pocketmine/level/Level.php | 69 ++++++++++++++++++---- 4 files changed, 149 insertions(+), 58 deletions(-) create mode 100644 src/pocketmine/level/ChunkListener.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 9e9eb9da37..cbb2ed3e36 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -84,6 +84,7 @@ use pocketmine\item\WritableBook; use pocketmine\item\WrittenBook; use pocketmine\lang\TextContainer; use pocketmine\lang\TranslationContainer; +use pocketmine\level\ChunkListener; use pocketmine\level\ChunkLoader; use pocketmine\level\format\Chunk; use pocketmine\level\Level; @@ -174,7 +175,7 @@ use const PHP_INT_MAX; /** * Main class that handles networking, recovery, and packet sending to the server part */ -class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ +class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, IPlayer{ /** * Checks a supplied username and checks it is valid. @@ -920,6 +921,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ unset($this->usedChunks[$index]); } $level->unregisterChunkLoader($this, $x, $z); + $level->unregisterChunkListener($this, $x, $z); unset($this->loadQueue[$index]); } @@ -977,6 +979,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->usedChunks[$index] = false; $this->level->registerChunkLoader($this, $X, $Z, true); + $this->level->registerChunkListener($this, $X, $Z); if(!$this->level->populateChunk($X, $Z)){ continue; @@ -1840,6 +1843,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ //load the spawn chunk so we can see the terrain $level->registerChunkLoader($this, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4, true); + $level->registerChunkListener($this, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4); if($spawnReset){ $spawn = $level->getSafeSpawn($spawn); } @@ -2880,6 +2884,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ foreach($this->usedChunks as $index => $d){ Level::getXZ($index, $chunkX, $chunkZ); $this->level->unregisterChunkLoader($this, $chunkX, $chunkZ); + $this->level->unregisterChunkListener($this, $chunkX, $chunkZ); foreach($this->level->getChunkEntities($chunkX, $chunkZ) as $entity){ $entity->despawnFrom($this); } diff --git a/src/pocketmine/level/ChunkListener.php b/src/pocketmine/level/ChunkListener.php new file mode 100644 index 0000000000..ffa7127de6 --- /dev/null +++ b/src/pocketmine/level/ChunkListener.php @@ -0,0 +1,80 @@ +registerChunkLoader($this, $chunkX, $chunkZ) - * Unregister Level->unregisterChunkLoader($this, $chunkX, $chunkZ) + * @see Level::registerChunkLoader() + * @see Level::unregisterChunkLoader() * * WARNING: When moving this object around in the world or destroying it, - * be sure to free the existing references from Level, otherwise you'll leak memory. + * be sure to unregister the loader from chunks you're not using, otherwise you'll leak memory. */ interface ChunkLoader{ @@ -48,42 +43,4 @@ interface ChunkLoader{ * @return float */ public function getZ(); - - /** - * This method will be called when a Chunk is replaced by a new one - * - * @param Chunk $chunk - */ - public function onChunkChanged(Chunk $chunk); - - /** - * This method will be called when a registered chunk is loaded - * - * @param Chunk $chunk - */ - public function onChunkLoaded(Chunk $chunk); - - - /** - * This method will be called when a registered chunk is unloaded - * - * @param Chunk $chunk - */ - public function onChunkUnloaded(Chunk $chunk); - - /** - * This method will be called when a registered chunk is populated - * Usually it'll be sent with another call to onChunkChanged() - * - * @param Chunk $chunk - */ - public function onChunkPopulated(Chunk $chunk); - - /** - * This method will be called when a block changes in a registered chunk - * - * @param Block|Vector3 $block - */ - public function onBlockChanged(Vector3 $block); - } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 96d77defd3..ebe325583a 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -179,6 +179,9 @@ class Level implements ChunkManager, Metadatable{ /** @var Player[][] */ private $playerLoaders = []; + /** @var ChunkListener[][] */ + private $chunkListeners = []; + /** @var ClientboundPacket[][] */ private $chunkPackets = []; /** @var ClientboundPacket[] */ @@ -680,6 +683,52 @@ class Level implements ChunkManager, Metadatable{ } } + /** + * Registers a listener to receive events on a chunk. + * + * @param ChunkListener $listener + * @param int $chunkX + * @param int $chunkZ + */ + public function registerChunkListener(ChunkListener $listener, int $chunkX, int $chunkZ) : void{ + $hash = Level::chunkHash($chunkX, $chunkZ); + if(isset($this->chunkListeners[$hash])){ + $this->chunkListeners[$hash][spl_object_id($listener)] = $listener; + }else{ + $this->chunkListeners[$hash] = [spl_object_id($listener) => $listener]; + } + } + + /** + * Unregisters a chunk listener previously registered. + * @see Level::registerChunkListener() + * + * @param ChunkListener $listener + * @param int $chunkX + * @param int $chunkZ + */ + public function unregisterChunkListener(ChunkListener $listener, int $chunkX, int $chunkZ) : void{ + $hash = Level::chunkHash($chunkX, $chunkZ); + if(isset($this->chunkListeners[$hash])){ + unset($this->chunkListeners[$hash][spl_object_id($listener)]); + if(empty($this->chunkListeners[$hash])){ + unset($this->chunkListeners[$hash]); + } + } + } + + /** + * Returns all the listeners attached to this chunk. + * + * @param int $chunkX + * @param int $chunkZ + * + * @return ChunkListener[] + */ + public function getChunkListeners(int $chunkX, int $chunkZ) : array{ + return $this->chunkListeners[Level::chunkHash($chunkX, $chunkZ)] ?? []; + } + /** * @internal * @@ -1539,8 +1588,8 @@ class Level implements ChunkManager, Metadatable{ } $this->changedBlocks[$chunkHash][$relativeBlockHash] = $block; - foreach($this->getChunkLoaders($x >> 4, $z >> 4) as $loader){ - $loader->onBlockChanged($block); + foreach($this->getChunkListeners($x >> 4, $z >> 4) as $listener){ + $listener->onBlockChanged($block); } if($update){ @@ -2229,8 +2278,8 @@ class Level implements ChunkManager, Metadatable{ if(($oldChunk === null or !$oldChunk->isPopulated()) and $chunk->isPopulated()){ (new ChunkPopulateEvent($this, $chunk))->call(); - foreach($this->getChunkLoaders($x, $z) as $loader){ - $loader->onChunkPopulated($chunk); + foreach($this->getChunkListeners($x, $z) as $listener){ + $listener->onChunkPopulated($chunk); } } } @@ -2301,8 +2350,8 @@ class Level implements ChunkManager, Metadatable{ if(!$this->isChunkInUse($chunkX, $chunkZ)){ $this->unloadChunkRequest($chunkX, $chunkZ); }else{ - foreach($this->getChunkLoaders($chunkX, $chunkZ) as $loader){ - $loader->onChunkChanged($chunk); + foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){ + $listener->onChunkChanged($chunk); } } } @@ -2617,8 +2666,8 @@ class Level implements ChunkManager, Metadatable{ } if($this->isChunkInUse($x, $z)){ - foreach($this->getChunkLoaders($x, $z) as $loader){ - $loader->onChunkLoaded($chunk); + foreach($this->getChunkListeners($x, $z) as $listener){ + $listener->onChunkLoaded($chunk); } }else{ $this->server->getLogger()->debug("Newly loaded chunk $x $z has no loaders registered, will be unloaded at next available opportunity"); @@ -2678,8 +2727,8 @@ class Level implements ChunkManager, Metadatable{ } } - foreach($this->getChunkLoaders($x, $z) as $loader){ - $loader->onChunkUnloaded($chunk); + foreach($this->getChunkListeners($x, $z) as $listener){ + $listener->onChunkUnloaded($chunk); } $chunk->onUnload(); From 55cd1f263dc5488e1efba2c1667b924b849f3431 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Feb 2019 12:05:08 +0000 Subject: [PATCH 0453/3224] SnowLayer: implement layers, closes #2657 --- src/pocketmine/block/SnowLayer.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index a998a78bc4..f4ab367659 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -27,9 +27,12 @@ use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; +use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use function floor; +use function max; class SnowLayer extends Flowable{ @@ -74,7 +77,18 @@ class SnowLayer extends Flowable{ return TieredTool::TIER_WOODEN; } + protected function recalculateBoundingBox() : ?AxisAlignedBB{ + //TODO: this zero-height BB is intended to stay in lockstep with a MCPE bug + return AxisAlignedBB::one()->trim(Facing::UP, $this->layers >= 4 ? 0.5 : 1); + } + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + if($blockReplace instanceof SnowLayer){ + if($blockReplace->layers >= 8){ + return false; + } + $this->layers = $blockReplace->layers + 1; + } if($blockReplace->getSide(Facing::DOWN)->isSolid()){ //TODO: fix placement return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); @@ -101,7 +115,7 @@ class SnowLayer extends Flowable{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::SNOWBALL) //TODO: check layer count + ItemFactory::get(Item::SNOWBALL, 0, max(1, (int) floor($this->layers / 2))) ]; } From 537afbc23b9c25f1ce1086f3bd0134943fa8e385 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Feb 2019 12:24:19 +0000 Subject: [PATCH 0454/3224] EffectInstance: Require positive amplifiers, closes #2723 --- src/pocketmine/entity/effect/EffectInstance.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/entity/effect/EffectInstance.php b/src/pocketmine/entity/effect/EffectInstance.php index f3707f6725..2619a73d12 100644 --- a/src/pocketmine/entity/effect/EffectInstance.php +++ b/src/pocketmine/entity/effect/EffectInstance.php @@ -57,7 +57,7 @@ class EffectInstance{ public function __construct(Effect $effectType, ?int $duration = null, int $amplifier = 0, bool $visible = true, bool $ambient = false, ?Color $overrideColor = null){ $this->effectType = $effectType; $this->setDuration($duration ?? $effectType->getDefaultDuration()); - $this->amplifier = $amplifier; + $this->setAmplifier($amplifier); $this->visible = $visible; $this->ambient = $ambient; $this->color = $overrideColor ?? $effectType->getColor(); @@ -141,6 +141,9 @@ class EffectInstance{ * @return $this */ public function setAmplifier(int $amplifier) : EffectInstance{ + if($amplifier < 0 or $amplifier > 255){ + throw new \InvalidArgumentException("Amplifier must be in range 0 - 255, got $amplifier"); + } $this->amplifier = $amplifier; return $this; From acd0a8f2d4cd651bd465a8d9ac9fb50944e8ecfc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Feb 2019 13:36:35 +0000 Subject: [PATCH 0455/3224] fix possible crash in Projectile --- src/pocketmine/entity/projectile/Projectile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/entity/projectile/Projectile.php b/src/pocketmine/entity/projectile/Projectile.php index 2a1ebb9bf7..b6ef1154de 100644 --- a/src/pocketmine/entity/projectile/Projectile.php +++ b/src/pocketmine/entity/projectile/Projectile.php @@ -165,7 +165,7 @@ abstract class Projectile extends Entity{ } public function onNearbyBlockChange() : void{ - if($this->blockHit !== null and !$this->blockHit->isSameState($this->level->getBlock($this->blockHit))){ + if($this->blockHit !== null and $this->level->isInLoadedTerrain($this->blockHit) and !$this->blockHit->isSameState($this->level->getBlock($this->blockHit))){ $this->blockHit = null; } From c872b120d043d8f2cee87b2a15e0e9a95489b99f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Feb 2019 14:20:06 +0000 Subject: [PATCH 0456/3224] Entity->entityBaseTick() is now protected --- src/pocketmine/entity/Entity.php | 2 +- src/pocketmine/entity/Human.php | 2 +- src/pocketmine/entity/Living.php | 2 +- src/pocketmine/entity/Squid.php | 2 +- src/pocketmine/entity/object/ExperienceOrb.php | 2 +- src/pocketmine/entity/object/FallingBlock.php | 2 +- src/pocketmine/entity/object/ItemEntity.php | 2 +- src/pocketmine/entity/object/PrimedTNT.php | 2 +- src/pocketmine/entity/projectile/Arrow.php | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 015ae9f9b5..f6f80e8703 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -885,7 +885,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ return $this->propertyManager; } - public function entityBaseTick(int $tickDiff = 1) : bool{ + protected function entityBaseTick(int $tickDiff = 1) : bool{ //TODO: check vehicles $this->justCreated = false; diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 45573edbd5..f6c4c12171 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -689,7 +689,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::EXPERIENCE)); } - public function entityBaseTick(int $tickDiff = 1) : bool{ + protected function entityBaseTick(int $tickDiff = 1) : bool{ $hasUpdate = parent::entityBaseTick($tickDiff); $this->doFoodTick($tickDiff); diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 409184983a..e520c70f25 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -676,7 +676,7 @@ abstract class Living extends Entity implements Damageable{ $this->despawnFromAll(); } - public function entityBaseTick(int $tickDiff = 1) : bool{ + protected function entityBaseTick(int $tickDiff = 1) : bool{ Timings::$timerLivingEntityBaseTick->startTiming(); $hasUpdate = parent::entityBaseTick($tickDiff); diff --git a/src/pocketmine/entity/Squid.php b/src/pocketmine/entity/Squid.php index 9a2cf896b6..465975f54d 100644 --- a/src/pocketmine/entity/Squid.php +++ b/src/pocketmine/entity/Squid.php @@ -78,7 +78,7 @@ class Squid extends WaterAnimal{ } - public function entityBaseTick(int $tickDiff = 1) : bool{ + protected function entityBaseTick(int $tickDiff = 1) : bool{ if($this->closed){ return false; } diff --git a/src/pocketmine/entity/object/ExperienceOrb.php b/src/pocketmine/entity/object/ExperienceOrb.php index c1704fd1c2..1cb3ad5f94 100644 --- a/src/pocketmine/entity/object/ExperienceOrb.php +++ b/src/pocketmine/entity/object/ExperienceOrb.php @@ -163,7 +163,7 @@ class ExperienceOrb extends Entity{ $this->targetPlayerRuntimeId = $player !== null ? $player->getId() : null; } - public function entityBaseTick(int $tickDiff = 1) : bool{ + protected function entityBaseTick(int $tickDiff = 1) : bool{ $hasUpdate = parent::entityBaseTick($tickDiff); $this->age += $tickDiff; diff --git a/src/pocketmine/entity/object/FallingBlock.php b/src/pocketmine/entity/object/FallingBlock.php index 8d1dc44b68..6261110723 100644 --- a/src/pocketmine/entity/object/FallingBlock.php +++ b/src/pocketmine/entity/object/FallingBlock.php @@ -87,7 +87,7 @@ class FallingBlock extends Entity{ } } - public function entityBaseTick(int $tickDiff = 1) : bool{ + protected function entityBaseTick(int $tickDiff = 1) : bool{ if($this->closed){ return false; } diff --git a/src/pocketmine/entity/object/ItemEntity.php b/src/pocketmine/entity/object/ItemEntity.php index f6692d9190..9dfc73768f 100644 --- a/src/pocketmine/entity/object/ItemEntity.php +++ b/src/pocketmine/entity/object/ItemEntity.php @@ -83,7 +83,7 @@ class ItemEntity extends Entity{ (new ItemSpawnEvent($this))->call(); } - public function entityBaseTick(int $tickDiff = 1) : bool{ + protected function entityBaseTick(int $tickDiff = 1) : bool{ if($this->closed){ return false; } diff --git a/src/pocketmine/entity/object/PrimedTNT.php b/src/pocketmine/entity/object/PrimedTNT.php index e17aa596c2..4b171fb450 100644 --- a/src/pocketmine/entity/object/PrimedTNT.php +++ b/src/pocketmine/entity/object/PrimedTNT.php @@ -81,7 +81,7 @@ class PrimedTNT extends Entity implements Explosive{ return $nbt; } - public function entityBaseTick(int $tickDiff = 1) : bool{ + protected function entityBaseTick(int $tickDiff = 1) : bool{ if($this->closed){ return false; } diff --git a/src/pocketmine/entity/projectile/Arrow.php b/src/pocketmine/entity/projectile/Arrow.php index 442b021ad1..5a26666d55 100644 --- a/src/pocketmine/entity/projectile/Arrow.php +++ b/src/pocketmine/entity/projectile/Arrow.php @@ -116,7 +116,7 @@ class Arrow extends Projectile{ $this->punchKnockback = $punchKnockback; } - public function entityBaseTick(int $tickDiff = 1) : bool{ + protected function entityBaseTick(int $tickDiff = 1) : bool{ if($this->closed){ return false; } From c6a5829a9222d0a48542a57e44284c8429fa9223 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Feb 2019 14:23:55 +0000 Subject: [PATCH 0457/3224] Entity: remove dead function --- src/pocketmine/entity/Entity.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index f6f80e8703..91fdb15862 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -1305,10 +1305,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ ); } - public function canTriggerWalking() : bool{ - return true; - } - public function resetFallDistance() : void{ $this->fallDistance = 0.0; } From d23e32622ec9c00df1a0c7e8dc10858202630b86 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Feb 2019 13:52:34 +0000 Subject: [PATCH 0458/3224] Clean up internal inconsistency in Color --- .../protocol/ClientboundMapItemDataPacket.php | 10 ++++---- src/pocketmine/utils/Color.php | 23 ++++++------------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php b/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php index 6c716ffaa3..f9a4802d2c 100644 --- a/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php @@ -31,6 +31,7 @@ use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\protocol\types\MapTrackedObject; +use pocketmine\utils\Binary; use pocketmine\utils\Color; use function assert; use function count; @@ -106,7 +107,7 @@ class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPack $this->decorations[$i]["yOffset"] = $this->getByte(); $this->decorations[$i]["label"] = $this->getString(); - $this->decorations[$i]["color"] = Color::fromABGR($this->getUnsignedVarInt()); + $this->decorations[$i]["color"] = Color::fromRGBA(Binary::flipIntEndianness($this->getUnsignedVarInt())); } } @@ -123,7 +124,7 @@ class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPack for($y = 0; $y < $this->height; ++$y){ for($x = 0; $x < $this->width; ++$x){ - $this->colors[$y][$x] = Color::fromABGR($this->getUnsignedVarInt()); + $this->colors[$y][$x] = Color::fromRGBA(Binary::flipIntEndianness($this->getUnsignedVarInt())); } } } @@ -179,7 +180,7 @@ class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPack $this->putString($decoration["label"]); assert($decoration["color"] instanceof Color); - $this->putUnsignedVarInt($decoration["color"]->toABGR()); + $this->putUnsignedVarInt(Binary::flipIntEndianness($decoration["color"]->toRGBA())); } } @@ -193,7 +194,8 @@ class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPack for($y = 0; $y < $this->height; ++$y){ for($x = 0; $x < $this->width; ++$x){ - $this->putUnsignedVarInt($this->colors[$y][$x]->toABGR()); + //if mojang had any sense this would just be a regular LE int + $this->putUnsignedVarInt(Binary::flipIntEndianness($this->colors[$y][$x]->toRGBA())); } } } diff --git a/src/pocketmine/utils/Color.php b/src/pocketmine/utils/Color.php index 69a6ff852f..19289f7d8a 100644 --- a/src/pocketmine/utils/Color.php +++ b/src/pocketmine/utils/Color.php @@ -163,11 +163,14 @@ class Color{ } /** - * Returns a little-endian ARGB 32-bit colour value. - * @return int + * Returns a Color from the supplied RGBA colour code (32-bit) + * + * @param int $c + * + * @return Color */ - public function toBGRA() : int{ - return ($this->b << 24) | ($this->g << 16) | ($this->r << 8) | $this->a; + public static function fromRGBA(int $c) : Color{ + return new Color(($c >> 24) & 0xff, ($c >> 16) & 0xff, ($c >> 8) & 0xff, $c & 0xff); } /** @@ -177,16 +180,4 @@ class Color{ public function toRGBA() : int{ return ($this->r << 24) | ($this->g << 16) | ($this->b << 8) | $this->a; } - - /** - * Returns a little-endian RGBA colour value. - * @return int - */ - public function toABGR() : int{ - return ($this->a << 24) | ($this->b << 16) | ($this->g << 8) | $this->r; - } - - public static function fromABGR(int $code){ - return new Color($code & 0xff, ($code >> 8) & 0xff, ($code >> 16) & 0xff, ($code >> 24) & 0xff); - } } From b6bcb47deb586197bbde1d545fe43e230a5e54b5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 10 Feb 2019 17:07:58 +0000 Subject: [PATCH 0459/3224] Network->unregisterInterface() is now less useless Interfaces are now automatically shut down when unregistered. --- src/pocketmine/Server.php | 1 - src/pocketmine/network/Network.php | 8 +++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index fd721f7c5e..4c3dccb0df 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1683,7 +1683,6 @@ class Server{ $this->getLogger()->debug("Stopping network interfaces"); foreach($this->network->getInterfaces() as $interface){ $this->getLogger()->debug("Stopping network interface " . get_class($interface)); - $interface->shutdown(); $this->network->unregisterInterface($interface); } } diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index 60d0961ba7..ed6e484af3 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -30,6 +30,7 @@ use pocketmine\event\server\NetworkInterfaceRegisterEvent; use pocketmine\event\server\NetworkInterfaceUnregisterEvent; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\PacketPool; +use function get_class; use function spl_object_id; class Network{ @@ -116,10 +117,15 @@ class Network{ /** * @param NetworkInterface $interface + * @throws \InvalidArgumentException */ public function unregisterInterface(NetworkInterface $interface) : void{ + if(!isset($this->interfaces[$hash = spl_object_id($interface)])){ + throw new \InvalidArgumentException("Interface " . get_class($interface) . " is not registered on this network"); + } (new NetworkInterfaceUnregisterEvent($interface))->call(); - unset($this->interfaces[$hash = spl_object_id($interface)], $this->advancedInterfaces[$hash]); + unset($this->interfaces[$hash], $this->advancedInterfaces[$hash]); + $interface->shutdown(); } /** From 7b3993730a644c17e03b609938d5eafa1a49b20e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 12 Feb 2019 13:52:59 +0000 Subject: [PATCH 0460/3224] Block: Replace Color and WoodType magic numbers with type-safe objects this provides automatic type safety without the need for magic number value checking everywhere. --- src/pocketmine/block/Bed.php | 12 +- src/pocketmine/block/BlockFactory.php | 42 ++--- src/pocketmine/block/CocoaBlock.php | 5 +- src/pocketmine/block/Leaves.php | 14 +- src/pocketmine/block/Sapling.php | 12 +- src/pocketmine/block/Wood.php | 22 ++- src/pocketmine/block/WoodenSlab.php | 6 - src/pocketmine/block/utils/Color.php | 81 ---------- src/pocketmine/block/utils/DyeColor.php | 151 ++++++++++++++++++ src/pocketmine/block/utils/TreeType.php | 112 +++++++++++++ src/pocketmine/block/utils/WoodType.php | 51 ------ src/pocketmine/item/Banner.php | 4 +- src/pocketmine/item/Bed.php | 5 +- src/pocketmine/item/Dye.php | 4 +- src/pocketmine/item/ItemFactory.php | 13 +- src/pocketmine/level/biome/Biome.php | 3 +- src/pocketmine/level/biome/ForestBiome.php | 18 +-- src/pocketmine/level/biome/TaigaBiome.php | 4 +- .../level/generator/object/BirchTree.php | 4 +- .../level/generator/object/JungleTree.php | 4 +- .../level/generator/object/OakTree.php | 4 +- .../level/generator/object/SpruceTree.php | 4 +- .../level/generator/object/Tree.php | 60 +++---- .../level/generator/populator/Tree.php | 10 +- src/pocketmine/tile/Bed.php | 27 +++- 25 files changed, 422 insertions(+), 250 deletions(-) delete mode 100644 src/pocketmine/block/utils/Color.php create mode 100644 src/pocketmine/block/utils/DyeColor.php create mode 100644 src/pocketmine/block/utils/TreeType.php delete mode 100644 src/pocketmine/block/utils/WoodType.php diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 3a63b790c5..a4040d95cb 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; -use pocketmine\block\utils\Color; +use pocketmine\block\utils\DyeColor; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\lang\TranslationContainer; @@ -52,11 +52,11 @@ class Bed extends Transparent{ protected $occupied = false; /** @var bool */ protected $head = false; - /** @var int */ - protected $color = Color::RED; + /** @var DyeColor */ + protected $color; public function __construct(){ - + $this->color = DyeColor::$RED; } protected function writeStateToMeta() : int{ @@ -183,7 +183,7 @@ class Bed extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - $this->color = $item->getDamage(); //TODO: replace this with a proper colour getter + $this->color = DyeColor::fromMagicNumber($item->getDamage()); //TODO: replace this with a proper colour getter $down = $this->getSide(Facing::DOWN); if(!$down->isTransparent()){ $this->facing = $player !== null ? $player->getHorizontalFacing() : Facing::NORTH; @@ -211,7 +211,7 @@ class Bed extends Transparent{ } public function getItem() : Item{ - return ItemFactory::get($this->getItemId(), $this->color); + return ItemFactory::get($this->getItemId(), $this->color->getMagicNumber()); } public function isAffectedBySilkTouch() : bool{ diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 0e8e5c734c..5e5b62d7eb 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -23,10 +23,10 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\Color; +use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\block\utils\PillarRotationTrait; -use pocketmine\block\utils\WoodType; +use pocketmine\block\utils\TreeType; use pocketmine\item\Item; use pocketmine\level\Position; use function array_fill; @@ -93,17 +93,17 @@ class BlockFactory{ self::registerBlock(new Cobblestone()); - foreach(WoodType::ALL as $type){ - self::registerBlock(new Planks(Block::PLANKS, $type, WoodType::NAMES[$type] . " Planks")); - self::registerBlock(new Sapling(Block::SAPLING, $type, WoodType::NAMES[$type] . " Sapling")); - self::registerBlock(new WoodenFence(Block::FENCE, $type, WoodType::NAMES[$type] . " Fence")); - } + foreach(TreeType::getAll() as $treeType){ + $magicNumber = $treeType->getMagicNumber(); + $name = $treeType->getDisplayName(); + self::registerBlock(new Planks(Block::PLANKS, $magicNumber, $name . " Planks")); + self::registerBlock(new Sapling(Block::SAPLING, $magicNumber, $treeType, $name . " Sapling")); + self::registerBlock(new WoodenFence(Block::FENCE, $magicNumber, $name . " Fence")); - foreach(WoodType::ALL as $type){ //TODO: find a better way to deal with this split - self::registerBlock(new Log($type >= 4 ? Block::WOOD2 : Block::WOOD, $type & 0x03, WoodType::NAMES[$type] . " Log")); - self::registerBlock(new Wood($type >= 4 ? Block::WOOD2 : Block::WOOD, ($type & 0x03) | 0b1100, WoodType::NAMES[$type] . " Wood")); - self::registerBlock(new Leaves($type >= 4 ? Block::LEAVES2 : Block::LEAVES, $type & 0x03, $type, WoodType::NAMES[$type] . " Leaves")); + self::registerBlock(new Log($magicNumber >= 4 ? Block::WOOD2 : Block::WOOD, $magicNumber & 0x03, $treeType, $name . " Log")); + self::registerBlock(new Wood($magicNumber >= 4 ? Block::WOOD2 : Block::WOOD, ($magicNumber & 0x03) | 0b1100, $treeType, $name . " Wood")); + self::registerBlock(new Leaves($magicNumber >= 4 ? Block::LEAVES2 : Block::LEAVES, $magicNumber & 0x03, $treeType, $name . " Leaves")); } self::registerBlock(new Bedrock()); @@ -151,14 +151,14 @@ class BlockFactory{ //TODO: PISTON //TODO: PISTONARMCOLLISION - foreach(Color::ALL as $color){ - self::registerBlock(new Wool(Block::WOOL, $color, Color::NAMES[$color] . " Wool")); - self::registerBlock(new HardenedClay(Block::STAINED_CLAY, $color, Color::NAMES[$color] . " Stained Clay")); - self::registerBlock(new Glass(Block::STAINED_GLASS, $color, Color::NAMES[$color] . " Stained Glass")); - self::registerBlock(new GlassPane(Block::STAINED_GLASS_PANE, $color, Color::NAMES[$color] . " Stained Glass Pane")); - self::registerBlock(new Carpet(Block::CARPET, $color, Color::NAMES[$color] . " Carpet")); - self::registerBlock(new Concrete(Block::CONCRETE, $color, Color::NAMES[$color] . " Concrete")); - self::registerBlock(new ConcretePowder(Block::CONCRETE_POWDER, $color, Color::NAMES[$color] . " Concrete Powder")); + foreach(DyeColor::getAll() as $color){ + self::registerBlock(new Wool(Block::WOOL, $color->getMagicNumber(), $color->getDisplayName() . " Wool")); + self::registerBlock(new HardenedClay(Block::STAINED_CLAY, $color->getMagicNumber(), $color->getDisplayName() . " Stained Clay")); + self::registerBlock(new Glass(Block::STAINED_GLASS, $color->getMagicNumber(), $color->getDisplayName() . " Stained Glass")); + self::registerBlock(new GlassPane(Block::STAINED_GLASS_PANE, $color->getMagicNumber(), $color->getDisplayName() . " Stained Glass Pane")); + self::registerBlock(new Carpet(Block::CARPET, $color->getMagicNumber(), $color->getDisplayName() . " Carpet")); + self::registerBlock(new Concrete(Block::CONCRETE, $color->getMagicNumber(), $color->getDisplayName() . " Concrete")); + self::registerBlock(new ConcretePowder(Block::CONCRETE_POWDER, $color->getMagicNumber(), $color->getDisplayName() . " Concrete Powder")); } self::registerBlock(new Dandelion()); @@ -197,8 +197,8 @@ class BlockFactory{ new StoneSlab(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 6, "Smooth Sandstone"), new StoneSlab(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 7, "Red Nether Brick") ]; - foreach(WoodType::ALL as $woodType){ - $slabTypes[] = new WoodenSlab($woodType); + foreach(TreeType::getAll() as $woodType){ + $slabTypes[] = new WoodenSlab(Block::WOODEN_SLAB, Block::DOUBLE_WOODEN_SLAB, $woodType->getMagicNumber(), $woodType->getDisplayName()); } foreach($slabTypes as $type){ self::registerBlock($type); diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index 4294a87edd..9328fb9fc0 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\TreeType; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\AxisAlignedBB; @@ -85,7 +86,7 @@ class CocoaBlock extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if(Facing::axis($face) !== Facing::AXIS_Y and $blockClicked->getId() === Block::LOG and $blockClicked->getVariant() === Wood::JUNGLE){ + if(Facing::axis($face) !== Facing::AXIS_Y and $blockClicked instanceof Wood and $blockClicked->getTreeType() === TreeType::$JUNGLE){ $this->facing = $face; return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -103,7 +104,7 @@ class CocoaBlock extends Transparent{ public function onNearbyBlockChange() : void{ $side = $this->getSide(Facing::opposite($this->facing)); - if($side->getId() !== Block::LOG or $side->getVariant() !== Wood::JUNGLE){ + if(!($side instanceof Wood) or $side->getTreeType() !== TreeType::$JUNGLE){ $this->level->useBreakOn($this); } } diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 775a509011..2e45fed5e7 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\WoodType; +use pocketmine\block\utils\TreeType; use pocketmine\event\block\LeavesDecayEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; @@ -34,17 +34,17 @@ use pocketmine\Player; use function mt_rand; class Leaves extends Transparent{ - /** @var int */ - protected $woodType; + /** @var TreeType */ + protected $treeType; /** @var bool */ protected $noDecay = false; /** @var bool */ protected $checkDecay = false; - public function __construct(int $id, int $variant, int $woodType, ?string $name = null){ + public function __construct(int $id, int $variant, TreeType $treeType, ?string $name = null){ parent::__construct($id, $variant, $name); - $this->woodType = $woodType; + $this->treeType = $treeType; } protected function writeStateToMeta() : int{ @@ -132,9 +132,9 @@ class Leaves extends Transparent{ $drops = []; if(mt_rand(1, 20) === 1){ //Saplings - $drops[] = ItemFactory::get(Item::SAPLING, $this->woodType); + $drops[] = ItemFactory::get(Item::SAPLING, $this->treeType->getMagicNumber()); } - if(($this->woodType === WoodType::OAK or $this->woodType === WoodType::DARK_OAK) and mt_rand(1, 200) === 1){ //Apples + if(($this->treeType === TreeType::$OAK or $this->treeType === TreeType::$DARK_OAK) and mt_rand(1, 200) === 1){ //Apples $drops[] = ItemFactory::get(Item::APPLE); } diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index 8b4d51fd45..adacce1b86 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\TreeType; use pocketmine\item\Item; use pocketmine\level\generator\object\Tree; use pocketmine\math\Facing; @@ -35,6 +36,13 @@ class Sapling extends Flowable{ /** @var bool */ protected $ready = false; + /** @var TreeType */ + private $treeType; + + public function __construct(int $id, int $variant, TreeType $treeType, ?string $name = null, int $itemId = null){ + parent::__construct($id, $variant, $name, $itemId); + $this->treeType = $treeType; + } protected function writeStateToMeta() : int{ return ($this->ready ? 0x08 : 0); @@ -60,7 +68,7 @@ class Sapling extends Flowable{ public function onActivate(Item $item, Player $player = null) : bool{ if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal //TODO: change log type - Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->getVariant()); + Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->treeType); $item->pop(); @@ -83,7 +91,7 @@ class Sapling extends Flowable{ public function onRandomTick() : void{ if($this->level->getFullLightAt($this->x, $this->y, $this->z) >= 8 and mt_rand(1, 7) === 1){ if($this->ready){ - Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->getVariant()); + Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->treeType); }else{ $this->ready = true; $this->getLevel()->setBlock($this, $this); diff --git a/src/pocketmine/block/Wood.php b/src/pocketmine/block/Wood.php index b1d3477749..ff970322a5 100644 --- a/src/pocketmine/block/Wood.php +++ b/src/pocketmine/block/Wood.php @@ -23,11 +23,25 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\TreeType; + class Wood extends Solid{ - public const OAK = 0; - public const SPRUCE = 1; - public const BIRCH = 2; - public const JUNGLE = 3; + + /** @var TreeType */ + private $treeType; + + public function __construct(int $id, int $variant, TreeType $treeType, ?string $name = null, int $itemId = null){ + parent::__construct($id, $variant, $name, $itemId); + $this->treeType = $treeType; + } + + /** + * TODO: this is ad hoc, but add an interface for this to all tree-related blocks + * @return TreeType + */ + public function getTreeType() : TreeType{ + return $this->treeType; + } public function getHardness() : float{ return 2; diff --git a/src/pocketmine/block/WoodenSlab.php b/src/pocketmine/block/WoodenSlab.php index 36528d695d..39ae7ac6da 100644 --- a/src/pocketmine/block/WoodenSlab.php +++ b/src/pocketmine/block/WoodenSlab.php @@ -23,16 +23,10 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\WoodType; - class WoodenSlab extends Slab{ protected $id = self::WOODEN_SLAB; - public function __construct(int $variant = 0){ - parent::__construct(self::WOODEN_SLAB, self::DOUBLE_WOODEN_SLAB, $variant, WoodType::NAMES[$variant]); - } - public function getHardness() : float{ return 2; } diff --git a/src/pocketmine/block/utils/Color.php b/src/pocketmine/block/utils/Color.php deleted file mode 100644 index 2b89fad1f3..0000000000 --- a/src/pocketmine/block/utils/Color.php +++ /dev/null @@ -1,81 +0,0 @@ - "White", - self::ORANGE => "Orange", - self::MAGENTA => "Magenta", - self::LIGHT_BLUE => "Light Blue", - self::YELLOW => "Yellow", - self::LIME => "Lime", - self::PINK => "Pink", - self::GRAY => "Gray", - self::LIGHT_GRAY => "Light Gray", - self::CYAN => "Cyan", - self::PURPLE => "Purple", - self::BLUE => "Blue", - self::BROWN => "Brown", - self::GREEN => "Green", - self::RED => "Red", - self::BLACK => "Black" - ]; -} diff --git a/src/pocketmine/block/utils/DyeColor.php b/src/pocketmine/block/utils/DyeColor.php new file mode 100644 index 0000000000..a9fa04df59 --- /dev/null +++ b/src/pocketmine/block/utils/DyeColor.php @@ -0,0 +1,151 @@ +getMagicNumber()] = $color; + self::$all[] = $color; + } + + /** + * Returns a set of all known dye colours. + * + * @return DyeColor[] + */ + public static function getAll() : array{ + return self::$all; + } + + /** + * Returns a DyeColor object matching the given magic number + * @internal + * + * @param int $magicNumber + * @param bool $inverted Invert the ID before using it (useful for actual dye magic IDs) + * + * @return DyeColor + * @throws \InvalidArgumentException + */ + public static function fromMagicNumber(int $magicNumber, bool $inverted = false) : DyeColor{ + $real = $inverted ? ~$magicNumber & 0xf : $magicNumber; + if(!isset(self::$numericIdMap[$real])){ + throw new \InvalidArgumentException("Unknown dye colour magic number $magicNumber"); + } + return self::$numericIdMap[$real]; + } + + /** @var string */ + private $displayName; + /** @var int */ + private $magicNumber; + + private function __construct(string $displayName, int $magicNumber){ + $this->displayName = $displayName; + $this->magicNumber = $magicNumber; + } + + /** + * @return string + */ + public function getDisplayName() : string{ + return $this->displayName; + } + + /** + * @return int + */ + public function getMagicNumber() : int{ + return $this->magicNumber; + } + + /** + * @return int + */ + public function getInvertedMagicNumber() : int{ + return ~$this->magicNumber & 0xf; + } +} +DyeColor::_init(); diff --git a/src/pocketmine/block/utils/TreeType.php b/src/pocketmine/block/utils/TreeType.php new file mode 100644 index 0000000000..8b742c4e69 --- /dev/null +++ b/src/pocketmine/block/utils/TreeType.php @@ -0,0 +1,112 @@ +getMagicNumber()] = $type; + self::$all[] = $type; + } + + /** + * @return TreeType[] + */ + public static function getAll() : array{ + return self::$all; + } + + /** + * @internal + * @param int $magicNumber + * + * @return TreeType + * @throws \InvalidArgumentException + */ + public static function fromMagicNumber(int $magicNumber) : TreeType{ + if(!isset(self::$numericIdMap[$magicNumber])){ + throw new \InvalidArgumentException("Unknown tree type magic number $magicNumber"); + } + return self::$numericIdMap[$magicNumber]; + } + + /** @var string */ + private $displayName; + /** @var int */ + private $magicNumber; + + /** + * @param string $displayName + * @param int $magicNumber + */ + private function __construct(string $displayName, int $magicNumber){ + $this->displayName = $displayName; + $this->magicNumber = $magicNumber; + } + + /** + * @return string + */ + public function getDisplayName() : string{ + return $this->displayName; + } + + /** + * @return int + */ + public function getMagicNumber() : int{ + return $this->magicNumber; + } +} +TreeType::_init(); diff --git a/src/pocketmine/block/utils/WoodType.php b/src/pocketmine/block/utils/WoodType.php deleted file mode 100644 index 8963b5e5a7..0000000000 --- a/src/pocketmine/block/utils/WoodType.php +++ /dev/null @@ -1,51 +0,0 @@ - "Oak", - self::SPRUCE => "Spruce", - self::BIRCH => "Birch", - self::JUNGLE => "Jungle", - self::ACACIA => "Acacia", - self::DARK_OAK => "Dark Oak" - ]; -} diff --git a/src/pocketmine/item/Banner.php b/src/pocketmine/item/Banner.php index e5e79a70d5..34f0da17ad 100644 --- a/src/pocketmine/item/Banner.php +++ b/src/pocketmine/item/Banner.php @@ -38,8 +38,8 @@ class Banner extends Item{ public const TAG_PATTERN_COLOR = TileBanner::TAG_PATTERN_COLOR; public const TAG_PATTERN_NAME = TileBanner::TAG_PATTERN_NAME; - public function __construct(int $variant){ - parent::__construct(self::BANNER, $variant, "Banner"); + public function __construct(int $variant, string $name){ + parent::__construct(self::BANNER, $variant, $name); } public function getBlock() : Block{ diff --git a/src/pocketmine/item/Bed.php b/src/pocketmine/item/Bed.php index c451a6acce..b9950e360b 100644 --- a/src/pocketmine/item/Bed.php +++ b/src/pocketmine/item/Bed.php @@ -27,8 +27,9 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; class Bed extends Item{ - public function __construct(int $variant){ - parent::__construct(self::BED, $variant, "Bed"); + + public function __construct(int $variant, string $name){ + parent::__construct(self::BED, $variant, $name); } public function getBlock() : Block{ diff --git a/src/pocketmine/item/Dye.php b/src/pocketmine/item/Dye.php index fb91e3f3db..7fa2a404e0 100644 --- a/src/pocketmine/item/Dye.php +++ b/src/pocketmine/item/Dye.php @@ -27,8 +27,8 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; class Dye extends Item{ - public function __construct(int $variant){ - parent::__construct(self::DYE, $variant, "Dye"); + public function __construct(int $variant, string $name){ + parent::__construct(self::DYE, $variant, $name); } public function getBlock() : Block{ diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 8f18a77255..92118db5a5 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -25,6 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\utils\DyeColor; use pocketmine\entity\EntityFactory; use pocketmine\entity\Living; use pocketmine\nbt\tag\CompoundTag; @@ -151,11 +152,13 @@ class ItemFactory{ self::registerItem(new Item(Item::GLOWSTONE_DUST, 0, "Glowstone Dust")); self::registerItem(new RawFish()); self::registerItem(new CookedFish()); - for($i = 0; $i < 16; ++$i){ - //TODO: add colour constants (this is messy) - self::registerItem(new Dye($i)); - self::registerItem(new Bed($i)); - self::registerItem(new Banner($i)); + foreach(DyeColor::getAll() as $color){ + //TODO: use colour object directly + //TODO: add interface to dye-colour objects + //TODO: new dedicated dyes + self::registerItem(new Dye($color->getInvertedMagicNumber(), $color->getDisplayName() . " Dye")); + self::registerItem(new Bed($color->getMagicNumber(), $color->getDisplayName() . " Bed")); + self::registerItem(new Banner($color->getInvertedMagicNumber(), $color->getDisplayName() . " Banner")); } self::registerItem(new Item(Item::BONE, 0, "Bone")); self::registerItem(new Item(Item::SUGAR, 0, "Sugar")); diff --git a/src/pocketmine/level/biome/Biome.php b/src/pocketmine/level/biome/Biome.php index 7ccab348d6..b4f201a26d 100644 --- a/src/pocketmine/level/biome/Biome.php +++ b/src/pocketmine/level/biome/Biome.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\level\biome; use pocketmine\block\Block; +use pocketmine\block\utils\TreeType; use pocketmine\level\ChunkManager; use pocketmine\level\generator\populator\Populator; use pocketmine\utils\Random; @@ -98,7 +99,7 @@ abstract class Biome{ self::register(self::SMALL_MOUNTAINS, new SmallMountainsBiome()); - self::register(self::BIRCH_FOREST, new ForestBiome(ForestBiome::TYPE_BIRCH)); + self::register(self::BIRCH_FOREST, new ForestBiome(TreeType::$BIRCH)); } /** diff --git a/src/pocketmine/level/biome/ForestBiome.php b/src/pocketmine/level/biome/ForestBiome.php index 0c4699c405..b537f1cb50 100644 --- a/src/pocketmine/level/biome/ForestBiome.php +++ b/src/pocketmine/level/biome/ForestBiome.php @@ -23,23 +23,21 @@ declare(strict_types=1); namespace pocketmine\level\biome; -use pocketmine\block\utils\WoodType; +use pocketmine\block\utils\TreeType; use pocketmine\level\generator\populator\TallGrass; use pocketmine\level\generator\populator\Tree; class ForestBiome extends GrassyBiome{ - public const TYPE_NORMAL = 0; - public const TYPE_BIRCH = 1; + /** @var TreeType */ + private $type; - public $type; - - public function __construct(int $type = self::TYPE_NORMAL){ + public function __construct(?TreeType $type = null){ parent::__construct(); - $this->type = $type; + $this->type = $type ?? TreeType::$OAK; - $trees = new Tree($type === self::TYPE_BIRCH ? WoodType::BIRCH : WoodType::OAK); + $trees = new Tree($type); $trees->setBaseAmount(5); $this->addPopulator($trees); @@ -50,7 +48,7 @@ class ForestBiome extends GrassyBiome{ $this->setElevation(63, 81); - if($type === self::TYPE_BIRCH){ + if($type === TreeType::$BIRCH){ $this->temperature = 0.6; $this->rainfall = 0.5; }else{ @@ -60,6 +58,6 @@ class ForestBiome extends GrassyBiome{ } public function getName() : string{ - return $this->type === self::TYPE_BIRCH ? "Birch Forest" : "Forest"; + return $this->type->getDisplayName() . " Forest"; } } diff --git a/src/pocketmine/level/biome/TaigaBiome.php b/src/pocketmine/level/biome/TaigaBiome.php index 2404c59368..86b84de055 100644 --- a/src/pocketmine/level/biome/TaigaBiome.php +++ b/src/pocketmine/level/biome/TaigaBiome.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\level\biome; -use pocketmine\block\utils\WoodType; +use pocketmine\block\utils\TreeType; use pocketmine\level\generator\populator\TallGrass; use pocketmine\level\generator\populator\Tree; @@ -32,7 +32,7 @@ class TaigaBiome extends SnowyBiome{ public function __construct(){ parent::__construct(); - $trees = new Tree(WoodType::SPRUCE); + $trees = new Tree(TreeType::$SPRUCE); $trees->setBaseAmount(10); $this->addPopulator($trees); diff --git a/src/pocketmine/level/generator/object/BirchTree.php b/src/pocketmine/level/generator/object/BirchTree.php index eea3f37f63..8859e1e508 100644 --- a/src/pocketmine/level/generator/object/BirchTree.php +++ b/src/pocketmine/level/generator/object/BirchTree.php @@ -25,7 +25,7 @@ namespace pocketmine\level\generator\object; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\Wood; +use pocketmine\block\utils\TreeType; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; @@ -34,7 +34,7 @@ class BirchTree extends Tree{ protected $superBirch = false; public function __construct(bool $superBirch = false){ - parent::__construct(BlockFactory::get(Block::LOG, Wood::BIRCH), BlockFactory::get(Block::LEAVES, Wood::BIRCH)); + parent::__construct(BlockFactory::get(Block::LOG, TreeType::$BIRCH->getMagicNumber()), BlockFactory::get(Block::LEAVES, TreeType::$BIRCH->getMagicNumber())); $this->superBirch = $superBirch; } diff --git a/src/pocketmine/level/generator/object/JungleTree.php b/src/pocketmine/level/generator/object/JungleTree.php index 10a01d2837..77f8b68ab8 100644 --- a/src/pocketmine/level/generator/object/JungleTree.php +++ b/src/pocketmine/level/generator/object/JungleTree.php @@ -25,11 +25,11 @@ namespace pocketmine\level\generator\object; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\Wood; +use pocketmine\block\utils\TreeType; class JungleTree extends Tree{ public function __construct(){ - parent::__construct(BlockFactory::get(Block::LOG, Wood::JUNGLE), BlockFactory::get(Block::LEAVES, Wood::JUNGLE), 8); + parent::__construct(BlockFactory::get(Block::LOG, TreeType::$JUNGLE->getMagicNumber()), BlockFactory::get(Block::LEAVES, TreeType::$JUNGLE->getMagicNumber()), 8); } } diff --git a/src/pocketmine/level/generator/object/OakTree.php b/src/pocketmine/level/generator/object/OakTree.php index ade1b6da4a..531f13b0ab 100644 --- a/src/pocketmine/level/generator/object/OakTree.php +++ b/src/pocketmine/level/generator/object/OakTree.php @@ -25,14 +25,14 @@ namespace pocketmine\level\generator\object; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\Wood; +use pocketmine\block\utils\TreeType; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; class OakTree extends Tree{ public function __construct(){ - parent::__construct(BlockFactory::get(Block::LOG, Wood::OAK), BlockFactory::get(Block::LEAVES, Wood::OAK)); + parent::__construct(BlockFactory::get(Block::LOG, TreeType::$OAK->getMagicNumber()), BlockFactory::get(Block::LEAVES, TreeType::$OAK->getMagicNumber())); } public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ diff --git a/src/pocketmine/level/generator/object/SpruceTree.php b/src/pocketmine/level/generator/object/SpruceTree.php index 43a996d6e5..f0637f90d5 100644 --- a/src/pocketmine/level/generator/object/SpruceTree.php +++ b/src/pocketmine/level/generator/object/SpruceTree.php @@ -25,7 +25,7 @@ namespace pocketmine\level\generator\object; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\Wood; +use pocketmine\block\utils\TreeType; use pocketmine\level\BlockWriteBatch; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; @@ -34,7 +34,7 @@ use function abs; class SpruceTree extends Tree{ public function __construct(){ - parent::__construct(BlockFactory::get(Block::LOG, Wood::SPRUCE), BlockFactory::get(Block::LEAVES, Wood::SPRUCE), 10); + parent::__construct(BlockFactory::get(Block::LOG, TreeType::$SPRUCE->getMagicNumber()), BlockFactory::get(Block::LEAVES, TreeType::$SPRUCE->getMagicNumber()), 10); } protected function generateChunkHeight(Random $random) : int{ diff --git a/src/pocketmine/level/generator/object/Tree.php b/src/pocketmine/level/generator/object/Tree.php index 7a795e20ad..7caad66b20 100644 --- a/src/pocketmine/level/generator/object/Tree.php +++ b/src/pocketmine/level/generator/object/Tree.php @@ -27,7 +27,7 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\Leaves; use pocketmine\block\Sapling; -use pocketmine\block\utils\WoodType; +use pocketmine\block\utils\TreeType; use pocketmine\level\BlockWriteBatch; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; @@ -49,34 +49,40 @@ abstract class Tree{ $this->treeHeight = $treeHeight; } - public static function growTree(ChunkManager $level, int $x, int $y, int $z, Random $random, int $type = WoodType::OAK) : void{ - switch($type){ - case WoodType::SPRUCE: - $tree = new SpruceTree(); - break; - case WoodType::BIRCH: - if($random->nextBoundedInt(39) === 0){ - $tree = new BirchTree(true); - }else{ - $tree = new BirchTree(); - } - break; - case WoodType::JUNGLE: - $tree = new JungleTree(); - break; - case WoodType::ACACIA: - case WoodType::DARK_OAK: - return; //TODO - default: - $tree = new OakTree(); - /*if($random->nextRange(0, 9) === 0){ - $tree = new BigTree(); - }else{*/ + /** + * @param ChunkManager $level + * @param int $x + * @param int $y + * @param int $z + * @param Random $random + * @param TreeType|null $type default oak + * + * @throws \InvalidArgumentException + */ + public static function growTree(ChunkManager $level, int $x, int $y, int $z, Random $random, ?TreeType $type = null) : void{ + /** @var null|Tree $tree */ + $tree = null; + $type = $type ?? TreeType::$OAK; + if($type === TreeType::$SPRUCE){ + $tree = new SpruceTree(); + }elseif($type === TreeType::$BIRCH){ + if($random->nextBoundedInt(39) === 0){ + $tree = new BirchTree(true); + }else{ + $tree = new BirchTree(); + } + }elseif($type === TreeType::$JUNGLE){ + $tree = new JungleTree(); + }elseif($type === TreeType::$OAK){ //default + $tree = new OakTree(); + /*if($random->nextRange(0, 9) === 0){ + $tree = new BigTree(); + }else{*/ - //} - break; + //} } - if($tree->canPlaceObject($level, $x, $y, $z, $random)){ + + if($tree !== null and $tree->canPlaceObject($level, $x, $y, $z, $random)){ $tree->placeObject($level, $x, $y, $z, $random); } } diff --git a/src/pocketmine/level/generator/populator/Tree.php b/src/pocketmine/level/generator/populator/Tree.php index 17102fc448..e095f271c5 100644 --- a/src/pocketmine/level/generator/populator/Tree.php +++ b/src/pocketmine/level/generator/populator/Tree.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\level\generator\populator; use pocketmine\block\Block; -use pocketmine\block\utils\WoodType; +use pocketmine\block\utils\TreeType; use pocketmine\level\ChunkManager; use pocketmine\level\generator\object\Tree as ObjectTree; use pocketmine\utils\Random; @@ -35,10 +35,14 @@ class Tree extends Populator{ private $randomAmount; private $baseAmount; + /** @var TreeType */ private $type; - public function __construct(int $type = WoodType::OAK){ - $this->type = $type; + /** + * @param TreeType|null $type default oak + */ + public function __construct(?TreeType $type = null){ + $this->type = $type ?? TreeType::$OAK; } public function setRandomAmount(int $amount) : void{ diff --git a/src/pocketmine/tile/Bed.php b/src/pocketmine/tile/Bed.php index 42fe1c776f..4fc8669357 100644 --- a/src/pocketmine/tile/Bed.php +++ b/src/pocketmine/tile/Bed.php @@ -23,31 +23,42 @@ declare(strict_types=1); namespace pocketmine\tile; +use pocketmine\block\utils\DyeColor; +use pocketmine\level\Level; +use pocketmine\math\Vector3; +use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; class Bed extends Spawnable{ public const TAG_COLOR = "color"; - /** @var int */ - private $color = 14; //default to old red + /** @var DyeColor */ + private $color; - public function getColor() : int{ + public function __construct(Level $level, Vector3 $pos){ + $this->color = DyeColor::$RED; + parent::__construct($level, $pos); + } + + public function getColor() : DyeColor{ return $this->color; } - public function setColor(int $color){ - $this->color = $color & 0xf; + public function setColor(DyeColor $color){ + $this->color = $color; $this->onChanged(); } public function readSaveData(CompoundTag $nbt) : void{ - $this->color = $nbt->getByte(self::TAG_COLOR, 14, true); + if($nbt->hasTag(self::TAG_COLOR, ByteTag::class)){ + $this->color = DyeColor::fromMagicNumber($nbt->getByte(self::TAG_COLOR)); + } } protected function writeSaveData(CompoundTag $nbt) : void{ - $nbt->setByte(self::TAG_COLOR, $this->color); + $nbt->setByte(self::TAG_COLOR, $this->color->getMagicNumber()); } protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ - $nbt->setByte(self::TAG_COLOR, $this->color); + $nbt->setByte(self::TAG_COLOR, $this->color->getMagicNumber()); } } From 52276796024ea472865835c23d503a673390984d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 12 Feb 2019 16:01:25 +0000 Subject: [PATCH 0461/3224] sync item/block magic numbers with 1.9.0.15 --- src/pocketmine/block/BlockIds.php | 48 +++++++++++++++++++++++++++++++ src/pocketmine/item/ItemIds.php | 48 +++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/src/pocketmine/block/BlockIds.php b/src/pocketmine/block/BlockIds.php index 3cebed295a..31ff4663dc 100644 --- a/src/pocketmine/block/BlockIds.php +++ b/src/pocketmine/block/BlockIds.php @@ -323,5 +323,53 @@ interface BlockIds{ public const TURTLE_EGG = 414; public const BUBBLE_COLUMN = 415; public const BARRIER = 416; + public const STONE_SLAB3 = 417; + public const BAMBOO = 418; + public const BAMBOO_SAPLING = 419; + public const SCAFFOLDING = 420; + public const STONE_SLAB4 = 421; + public const DOUBLE_STONE_SLAB3 = 422; + public const DOUBLE_STONE_SLAB4 = 423; + public const GRANITE_STAIRS = 424; + public const DIORITE_STAIRS = 425; + public const ANDESITE_STAIRS = 426; + public const POLISHED_GRANITE_STAIRS = 427; + public const POLISHED_DIORITE_STAIRS = 428; + public const POLISHED_ANDESITE_STAIRS = 429; + public const MOSSY_STONE_BRICK_STAIRS = 430; + public const SMOOTH_RED_SANDSTONE_STAIRS = 431; + public const SMOOTH_SANDSTONE_STAIRS = 432; + public const END_BRICK_STAIRS = 433; + public const MOSSY_COBBLESTONE_STAIRS = 434; + public const NORMAL_STONE_STAIRS = 435; + public const SPRUCE_STANDING_SIGN = 436; + public const SPRUCE_WALL_SIGN = 437; + public const SMOOTH_STONE = 438; + public const RED_NETHER_BRICK_STAIRS = 439; + public const SMOOTH_QUARTZ_STAIRS = 440; + public const BIRCH_STANDING_SIGN = 441; + public const BIRCH_WALL_SIGN = 442; + public const JUNGLE_STANDING_SIGN = 443; + public const JUNGLE_WALL_SIGN = 444; + public const ACACIA_STANDING_SIGN = 445; + public const ACACIA_WALL_SIGN = 446; + public const DARKOAK_STANDING_SIGN = 447; + public const DARKOAK_WALL_SIGN = 448; + + public const GRINDSTONE = 450; + public const BLAST_FURNACE = 451; + + public const SMOKER = 453; + + public const CARTOGRAPHY_TABLE = 455; + public const FLETCHING_TABLE = 456; + public const SMITHING_TABLE = 457; + public const BARREL = 458; + + public const BELL = 461; + + public const LANTERN = 463; + + public const LAVA_CAULDRON = 465; } diff --git a/src/pocketmine/item/ItemIds.php b/src/pocketmine/item/ItemIds.php index 7f33791411..925f43c2ea 100644 --- a/src/pocketmine/item/ItemIds.php +++ b/src/pocketmine/item/ItemIds.php @@ -25,6 +25,54 @@ namespace pocketmine\item; interface ItemIds{ + public const LAVA_CAULDRON = -210; + + public const LANTERN = -208; + + public const BELL = -206; + + public const BARREL = -203; + public const SMITHING_TABLE = -202; + public const FLETCHING_TABLE = -201; + public const CARTOGRAPHY_TABLE = -200; + + public const SMOKER = -198; + + public const BLAST_FURNACE = -196; + public const GRINDSTONE = -195; + + public const DARKOAK_WALL_SIGN = -193; + public const DARKOAK_STANDING_SIGN = -192; + public const ACACIA_WALL_SIGN = -191; + public const ACACIA_STANDING_SIGN = -190; + public const JUNGLE_WALL_SIGN = -189; + public const JUNGLE_STANDING_SIGN = -188; + public const BIRCH_WALL_SIGN = -187; + public const BIRCH_STANDING_SIGN = -186; + public const SMOOTH_QUARTZ_STAIRS = -185; + public const RED_NETHER_BRICK_STAIRS = -184; + public const SMOOTH_STONE = -183; + public const SPRUCE_WALL_SIGN = -182; + public const SPRUCE_STANDING_SIGN = -181; + public const NORMAL_STONE_STAIRS = -180; + public const MOSSY_COBBLESTONE_STAIRS = -179; + public const END_BRICK_STAIRS = -178; + public const SMOOTH_SANDSTONE_STAIRS = -177; + public const SMOOTH_RED_SANDSTONE_STAIRS = -176; + public const MOSSY_STONE_BRICK_STAIRS = -175; + public const POLISHED_ANDESITE_STAIRS = -174; + public const POLISHED_DIORITE_STAIRS = -173; + public const POLISHED_GRANITE_STAIRS = -172; + public const ANDESITE_STAIRS = -171; + public const DIORITE_STAIRS = -170; + public const GRANITE_STAIRS = -169; + public const DOUBLE_STONE_SLAB4 = -168; + public const DOUBLE_STONE_SLAB3 = -167; + public const STONE_SLAB4 = -166; + public const SCAFFOLDING = -165; + public const BAMBOO_SAPLING = -164; + public const BAMBOO = -163; + public const STONE_SLAB3 = -162; public const BARRIER = -161; public const BUBBLE_COLUMN = -160; public const TURTLE_EGG = -159; From d30316101a08870edf388db76ecd7597782859e9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 12 Feb 2019 16:30:31 +0000 Subject: [PATCH 0462/3224] Of course, there was a bug in the script... --- src/pocketmine/item/ItemIds.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/item/ItemIds.php b/src/pocketmine/item/ItemIds.php index 925f43c2ea..0476f580bf 100644 --- a/src/pocketmine/item/ItemIds.php +++ b/src/pocketmine/item/ItemIds.php @@ -532,7 +532,7 @@ interface ItemIds{ public const RABBIT_HIDE = 415; public const HORSEARMORLEATHER = 416, HORSE_ARMOR_LEATHER = 416, LEATHER_HORSE_ARMOR = 416; public const HORSEARMORIRON = 417, HORSE_ARMOR_IRON = 417, IRON_HORSE_ARMOR = 417; - public const GOLD_HORSE_ARMOR = 418, GOLDEN_HORSE_ARMOR = 418, HORSEARMORGOLD = 418, HORSE_ARMOR_GOLD = 418; + public const GOLDEN_HORSE_ARMOR = 418, GOLD_HORSE_ARMOR = 418, HORSEARMORGOLD = 418, HORSE_ARMOR_GOLD = 418; public const DIAMOND_HORSE_ARMOR = 419, HORSEARMORDIAMOND = 419, HORSE_ARMOR_DIAMOND = 419; public const LEAD = 420; public const NAMETAG = 421, NAME_TAG = 421; @@ -583,6 +583,11 @@ interface ItemIds{ public const TURTLE_HELMET = 469; public const PHANTOM_MEMBRANE = 470; public const CROSSBOW = 471; + public const SPRUCE_SIGN = 472; + public const BIRCH_SIGN = 473; + public const JUNGLE_SIGN = 474; + public const ACACIA_SIGN = 475; + public const DARKOAK_SIGN = 476; public const COMPOUND = 499; public const RECORD_13 = 500; From 1496eefb8bd74cadff78014839f2da76d5016a62 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 12 Feb 2019 19:15:19 +0000 Subject: [PATCH 0463/3224] Regenerated TODOs for item and b,locks this sucks because it doesn't tell us anything about things that are meta values of other things (like dyes), but it's enough to start with. --- src/pocketmine/block/BlockFactory.php | 157 +++++++++++++++++++++----- src/pocketmine/item/ItemFactory.php | 108 ++++++++++-------- 2 files changed, 191 insertions(+), 74 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index a54769d5f3..f8a91a1b98 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -123,7 +123,6 @@ class BlockFactory{ self::registerBlock(new Glass(Block::GLASS, 0, "Glass")); self::registerBlock(new LapisOre()); self::registerBlock(new Lapis()); - //TODO: DISPENSER static $sandstoneTypes = [ Sandstone::NORMAL => "", @@ -139,7 +138,7 @@ class BlockFactory{ self::registerBlock(new Bed()); self::registerBlock(new PoweredRail()); self::registerBlock(new DetectorRail()); - //TODO: STICKY_PISTON + self::registerBlock(new Cobweb()); self::registerBlock(new TallGrass(Block::TALL_GRASS, 0, "Fern")); @@ -148,8 +147,6 @@ class BlockFactory{ self::registerBlock(new TallGrass(Block::TALL_GRASS, 3, "Fern")); self::registerBlock(new DeadBush()); - //TODO: PISTON - //TODO: PISTONARMCOLLISION foreach(DyeColor::getAll() as $color){ self::registerBlock(new Wool(Block::WOOL, $color->getMagicNumber(), $color->getDisplayName() . " Wool")); @@ -246,20 +243,18 @@ class BlockFactory{ self::registerBlock(new Cactus()); self::registerBlock(new Clay()); self::registerBlock(new Sugarcane()); - //TODO: JUKEBOX self::registerBlock(new Pumpkin()); self::registerBlock(new Netherrack()); self::registerBlock(new SoulSand()); self::registerBlock(new Glowstone()); - //TODO: PORTAL + self::registerBlock(new LitPumpkin()); self::registerBlock(new Cake()); self::registerBlock(new RedstoneRepeater()); self::registerBlock((new RedstoneRepeater())->setPowered()); self::registerBlock(new InvisibleBedrock()); self::registerBlock(new Trapdoor()); - //TODO: MONSTER_EGG self::registerBlock(new StoneBricks(Block::STONE_BRICKS, StoneBricks::NORMAL, "Stone Bricks")); self::registerBlock(new StoneBricks(Block::STONE_BRICKS, StoneBricks::MOSSY, "Mossy Stone Bricks")); @@ -285,14 +280,13 @@ class BlockFactory{ self::registerBlock(new NetherWartPlant()); self::registerBlock(new EnchantingTable()); self::registerBlock(new BrewingStand()); - //TODO: CAULDRON_BLOCK - //TODO: END_PORTAL + self::registerBlock(new EndPortalFrame()); self::registerBlock(new EndStone()); - //TODO: DRAGON_EGG + self::registerBlock(new RedstoneLamp()); self::registerBlock((new RedstoneLamp())->setLit()); //flattening hack - //TODO: DROPPER + self::registerBlock(new ActivatorRail()); self::registerBlock(new CocoaBlock()); self::registerBlock(new SandstoneStairs()); @@ -304,8 +298,6 @@ class BlockFactory{ self::registerBlock(new WoodenStairs(Block::SPRUCE_STAIRS, 0, "Spruce Stairs")); self::registerBlock(new WoodenStairs(Block::BIRCH_STAIRS, 0, "Birch Stairs")); self::registerBlock(new WoodenStairs(Block::JUNGLE_STAIRS, 0, "Jungle Stairs")); - //TODO: COMMAND_BLOCK - //TODO: BEACON static $wallTypes = [ CobblestoneWall::NONE_MOSSY_WALL => "Cobblestone", @@ -340,14 +332,12 @@ class BlockFactory{ self::registerBlock(new TrappedChest()); self::registerBlock(new WeightedPressurePlateLight()); self::registerBlock(new WeightedPressurePlateHeavy()); - //TODO: COMPARATOR_BLOCK - //TODO: POWERED_COMPARATOR + self::registerBlock(new DaylightSensor()); self::registerBlock((new DaylightSensor())->setInverted()); //flattening hack self::registerBlock(new Redstone()); self::registerBlock(new NetherQuartzOre()); - //TODO: HOPPER_BLOCK self::registerBlock(new Quartz(Block::QUARTZ_BLOCK, Quartz::NORMAL, "Quartz Block")); self::registerBlock(new class(Block::QUARTZ_BLOCK, Quartz::CHISELED, "Chiseled Quartz Block") extends Quartz{ @@ -366,7 +356,6 @@ class BlockFactory{ self::registerBlock(new WoodenStairs(Block::ACACIA_STAIRS, 0, "Acacia Stairs")); self::registerBlock(new WoodenStairs(Block::DARK_OAK_STAIRS, 0, "Dark Oak Stairs")); - //TODO: SLIME self::registerBlock(new IronTrapdoor()); @@ -397,8 +386,6 @@ class BlockFactory{ self::registerBlock(new FenceGate(Block::JUNGLE_FENCE_GATE, 0, "Jungle Fence Gate")); self::registerBlock(new FenceGate(Block::DARK_OAK_FENCE_GATE, 0, "Dark Oak Fence Gate")); self::registerBlock(new FenceGate(Block::ACACIA_FENCE_GATE, 0, "Acacia Fence Gate")); - //TODO: REPEATING_COMMAND_BLOCK - //TODO: CHAIN_COMMAND_BLOCK self::registerBlock(new WoodenDoor(Block::SPRUCE_DOOR_BLOCK, 0, "Spruce Door", Item::SPRUCE_DOOR)); self::registerBlock(new WoodenDoor(Block::BIRCH_DOOR_BLOCK, 0, "Birch Door", Item::BIRCH_DOOR)); @@ -407,22 +394,17 @@ class BlockFactory{ self::registerBlock(new WoodenDoor(Block::DARK_OAK_DOOR_BLOCK, 0, "Dark Oak Door", Item::DARK_OAK_DOOR)); self::registerBlock(new GrassPath()); self::registerBlock(new ItemFrame()); - //TODO: CHORUS_FLOWER self::registerBlock(new PurpurStairs()); - //TODO: UNDYED_SHULKER_BOX self::registerBlock(new EndStoneBricks()); - //TODO: FROSTED_ICE self::registerBlock(new EndRod()); - //TODO: END_GATEWAY self::registerBlock(new Magma()); self::registerBlock(new NetherWartBlock()); self::registerBlock(new NetherBrick(Block::RED_NETHER_BRICK, 0, "Red Nether Bricks")); self::registerBlock(new BoneBlock()); - //TODO: SHULKER_BOX self::registerBlock(new GlazedTerracotta(Block::PURPLE_GLAZED_TERRACOTTA, 0, "Purple Glazed Terracotta")); self::registerBlock(new GlazedTerracotta(Block::WHITE_GLAZED_TERRACOTTA, 0, "White Glazed Terracotta")); self::registerBlock(new GlazedTerracotta(Block::ORANGE_GLAZED_TERRACOTTA, 0, "Orange Glazed Terracotta")); @@ -441,8 +423,6 @@ class BlockFactory{ self::registerBlock(new GlazedTerracotta(Block::RED_GLAZED_TERRACOTTA, 0, "Red Glazed Terracotta")); self::registerBlock(new GlazedTerracotta(Block::BLACK_GLAZED_TERRACOTTA, 0, "Black Glazed Terracotta")); - //TODO: CHORUS_PLANT - self::registerBlock(new Podzol()); self::registerBlock(new Beetroot()); self::registerBlock(new Stonecutter()); @@ -450,11 +430,130 @@ class BlockFactory{ self::registerBlock(new NetherReactor()); self::registerBlock(new InfoUpdate(Block::INFO_UPDATE, 0, "update!")); self::registerBlock(new InfoUpdate(Block::INFO_UPDATE2, 0, "ate!upd")); - //TODO: MOVINGBLOCK - //TODO: OBSERVER - //TODO: STRUCTURE_BLOCK self::registerBlock(new Reserved6(Block::RESERVED6, 0, "reserved6")); + + //TODO: minecraft:acacia_button + //TODO: minecraft:acacia_pressure_plate + //TODO: minecraft:acacia_standing_sign + //TODO: minecraft:acacia_trapdoor + //TODO: minecraft:acacia_wall_sign + //TODO: minecraft:andesite_stairs + //TODO: minecraft:bamboo + //TODO: minecraft:bamboo_sapling + //TODO: minecraft:barrel + //TODO: minecraft:barrier + //TODO: minecraft:beacon + //TODO: minecraft:bell + //TODO: minecraft:birch_button + //TODO: minecraft:birch_pressure_plate + //TODO: minecraft:birch_standing_sign + //TODO: minecraft:birch_trapdoor + //TODO: minecraft:birch_wall_sign + //TODO: minecraft:blast_furnace + //TODO: minecraft:blue_ice + //TODO: minecraft:bubble_column + //TODO: minecraft:cartography_table + //TODO: minecraft:carved_pumpkin + //TODO: minecraft:cauldron + //TODO: minecraft:chain_command_block + //TODO: minecraft:chemical_heat + //TODO: minecraft:chemistry_table + //TODO: minecraft:chorus_flower + //TODO: minecraft:chorus_plant + //TODO: minecraft:colored_torch_bp + //TODO: minecraft:colored_torch_rg + //TODO: minecraft:command_block + //TODO: minecraft:conduit + //TODO: minecraft:coral + //TODO: minecraft:coral_block + //TODO: minecraft:coral_fan + //TODO: minecraft:coral_fan_dead + //TODO: minecraft:coral_fan_hang + //TODO: minecraft:coral_fan_hang2 + //TODO: minecraft:coral_fan_hang3 + //TODO: minecraft:dark_oak_button + //TODO: minecraft:dark_oak_pressure_plate + //TODO: minecraft:dark_oak_trapdoor + //TODO: minecraft:dark_prismarine_stairs + //TODO: minecraft:darkoak_standing_sign + //TODO: minecraft:darkoak_wall_sign + //TODO: minecraft:diorite_stairs + //TODO: minecraft:dispenser + //TODO: minecraft:double_stone_slab3 + //TODO: minecraft:double_stone_slab4 + //TODO: minecraft:dragon_egg + //TODO: minecraft:dried_kelp_block + //TODO: minecraft:dropper + //TODO: minecraft:element_0 + //TODO: minecraft:end_brick_stairs + //TODO: minecraft:end_gateway + //TODO: minecraft:end_portal + //TODO: minecraft:fletching_table + //TODO: minecraft:frosted_ice + //TODO: minecraft:granite_stairs + //TODO: minecraft:grindstone + //TODO: minecraft:hard_glass + //TODO: minecraft:hard_glass_pane + //TODO: minecraft:hard_stained_glass + //TODO: minecraft:hard_stained_glass_pane + //TODO: minecraft:hopper + //TODO: minecraft:jukebox + //TODO: minecraft:jungle_button + //TODO: minecraft:jungle_pressure_plate + //TODO: minecraft:jungle_standing_sign + //TODO: minecraft:jungle_trapdoor + //TODO: minecraft:jungle_wall_sign + //TODO: minecraft:kelp + //TODO: minecraft:lantern + //TODO: minecraft:lava_cauldron + //TODO: minecraft:monster_egg + //TODO: minecraft:mossy_cobblestone_stairs + //TODO: minecraft:mossy_stone_brick_stairs + //TODO: minecraft:movingBlock + //TODO: minecraft:normal_stone_stairs + //TODO: minecraft:observer + //TODO: minecraft:piston + //TODO: minecraft:pistonArmCollision + //TODO: minecraft:polished_andesite_stairs + //TODO: minecraft:polished_diorite_stairs + //TODO: minecraft:polished_granite_stairs + //TODO: minecraft:portal + //TODO: minecraft:powered_comparator + //TODO: minecraft:prismarine_bricks_stairs + //TODO: minecraft:prismarine_stairs + //TODO: minecraft:red_nether_brick_stairs + //TODO: minecraft:repeating_command_block + //TODO: minecraft:scaffolding + //TODO: minecraft:sea_pickle + //TODO: minecraft:seagrass + //TODO: minecraft:shulker_box + //TODO: minecraft:slime + //TODO: minecraft:smithing_table + //TODO: minecraft:smoker + //TODO: minecraft:smooth_quartz_stairs + //TODO: minecraft:smooth_red_sandstone_stairs + //TODO: minecraft:smooth_sandstone_stairs + //TODO: minecraft:smooth_stone + //TODO: minecraft:spruce_button + //TODO: minecraft:spruce_pressure_plate + //TODO: minecraft:spruce_standing_sign + //TODO: minecraft:spruce_trapdoor + //TODO: minecraft:spruce_wall_sign + //TODO: minecraft:sticky_piston + //TODO: minecraft:stone_slab3 + //TODO: minecraft:stone_slab4 + //TODO: minecraft:stripped_acacia_log + //TODO: minecraft:stripped_birch_log + //TODO: minecraft:stripped_dark_oak_log + //TODO: minecraft:stripped_jungle_log + //TODO: minecraft:stripped_oak_log + //TODO: minecraft:stripped_spruce_log + //TODO: minecraft:structure_block + //TODO: minecraft:turtle_egg + //TODO: minecraft:underwater_torch + //TODO: minecraft:undyed_shulker_box + //TODO: minecraft:unpowered_comparator } public static function isInit() : bool{ diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 92118db5a5..3b671d65f6 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -129,21 +129,20 @@ class ItemFactory{ self::registerItem(new LiquidBucket(Item::BUCKET, 10, "Lava Bucket", Block::FLOWING_LAVA)); self::registerItem(new Minecart()); - //TODO: SADDLE + self::registerItem(new ItemBlock(Block::IRON_DOOR_BLOCK, 0, Item::IRON_DOOR)); self::registerItem(new Redstone()); self::registerItem(new Snowball()); self::registerItem(new Boat()); self::registerItem(new Item(Item::LEATHER, 0, "Leather")); - //TODO: KELP + self::registerItem(new Item(Item::BRICK, 0, "Brick")); self::registerItem(new Item(Item::CLAY_BALL, 0, "Clay")); self::registerItem(new ItemBlock(Block::SUGARCANE_BLOCK, 0, Item::SUGARCANE)); self::registerItem(new Item(Item::PAPER, 0, "Paper")); self::registerItem(new Book()); self::registerItem(new Item(Item::SLIME_BALL, 0, "Slimeball")); - //TODO: CHEST_MINECART self::registerItem(new Egg()); self::registerItem(new Compass()); @@ -166,7 +165,7 @@ class ItemFactory{ self::registerItem(new ItemBlock(Block::REPEATER_BLOCK, 0, Item::REPEATER)); self::registerItem(new Cookie()); - //TODO: FILLED_MAP + self::registerItem(new Shears()); self::registerItem(new Melon()); self::registerItem(new PumpkinSeeds()); @@ -185,7 +184,6 @@ class ItemFactory{ foreach(Potion::ALL as $type){ self::registerItem(new Potion($type)); self::registerItem(new SplashPotion($type)); - //TODO: LINGERING_POTION } self::registerItem(new GlassBottle()); self::registerItem(new SpiderEye()); @@ -194,7 +192,7 @@ class ItemFactory{ self::registerItem(new Item(Item::MAGMA_CREAM, 0, "Magma Cream")); self::registerItem(new ItemBlock(Block::BREWING_STAND_BLOCK, 0, Item::BREWING_STAND)); self::registerItem(new ItemBlock(Block::CAULDRON_BLOCK, 0, Item::CAULDRON)); - //TODO: ENDER_EYE + self::registerItem(new Item(Item::GLISTERING_MELON, 0, "Glistering Melon")); foreach(EntityFactory::getKnownTypes() as $className){ @@ -205,7 +203,7 @@ class ItemFactory{ } self::registerItem(new ExperienceBottle()); - //TODO: FIREBALL + self::registerItem(new WritableBook()); self::registerItem(new WrittenBook()); self::registerItem(new Item(Item::EMERALD, 0, "Emerald")); @@ -215,7 +213,7 @@ class ItemFactory{ self::registerItem(new Potato()); self::registerItem(new BakedPotato()); self::registerItem(new PoisonousPotato()); - //TODO: EMPTYMAP + self::registerItem(new GoldenCarrot()); self::registerItem(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_SKELETON, Item::SKULL)); @@ -225,17 +223,13 @@ class ItemFactory{ self::registerItem(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_CREEPER, Item::SKULL)); self::registerItem(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_DRAGON, Item::SKULL)); - //TODO: CARROTONASTICK self::registerItem(new Item(Item::NETHER_STAR, 0, "Nether Star")); self::registerItem(new PumpkinPie()); - //TODO: FIREWORKS - //TODO: FIREWORKSCHARGE - //TODO: ENCHANTED_BOOK + self::registerItem(new ItemBlock(Block::COMPARATOR_BLOCK, 0, Item::COMPARATOR)); self::registerItem(new Item(Item::NETHER_BRICK, 0, "Nether Brick")); self::registerItem(new Item(Item::NETHER_QUARTZ, 0, "Nether Quartz")); - //TODO: MINECART_WITH_TNT - //TODO: HOPPER_MINECART + self::registerItem(new Item(Item::PRISMARINE_SHARD, 0, "Prismarine Shard")); self::registerItem(new ItemBlock(Block::HOPPER_BLOCK, 0, Item::HOPPER)); self::registerItem(new RawRabbit()); @@ -243,17 +237,11 @@ class ItemFactory{ self::registerItem(new RabbitStew()); self::registerItem(new Item(Item::RABBIT_FOOT, 0, "Rabbit's Foot")); self::registerItem(new Item(Item::RABBIT_HIDE, 0, "Rabbit Hide")); - //TODO: HORSEARMORLEATHER - //TODO: HORSEARMORIRON - //TODO: GOLD_HORSE_ARMOR - //TODO: DIAMOND_HORSE_ARMOR - //TODO: LEAD - //TODO: NAMETAG + self::registerItem(new Item(Item::PRISMARINE_CRYSTALS, 0, "Prismarine Crystals")); self::registerItem(new RawMutton()); self::registerItem(new CookedMutton()); - //TODO: ARMOR_STAND - //TODO: END_CRYSTAL + self::registerItem(new ItemBlock(Block::SPRUCE_DOOR_BLOCK, 0, Item::SPRUCE_DOOR)); self::registerItem(new ItemBlock(Block::BIRCH_DOOR_BLOCK, 0, Item::BIRCH_DOOR)); self::registerItem(new ItemBlock(Block::JUNGLE_DOOR_BLOCK, 0, Item::JUNGLE_DOOR)); @@ -264,20 +252,11 @@ class ItemFactory{ self::registerItem(new Item(Item::DRAGON_BREATH, 0, "Dragon's Breath")); - //TODO: SPARKLER - //TODO: COMMAND_BLOCK_MINECART - //TODO: ELYTRA self::registerItem(new Item(Item::SHULKER_SHELL, 0, "Shulker Shell")); - //TODO: MEDICINE - //TODO: BALLOON - //TODO: RAPID_FERTILIZER self::registerItem(new Totem()); self::registerItem(new Item(Item::BLEACH, 0, "Bleach")); //EDU self::registerItem(new Item(Item::IRON_NUGGET, 0, "Iron Nugget")); - //TODO: ICE_BOMB - - //TODO: TRIDENT self::registerItem(new Beetroot()); self::registerItem(new BeetrootSeeds()); @@ -291,21 +270,60 @@ class ItemFactory{ self::registerItem(new GoldenAppleEnchanted()); self::registerItem(new Item(Item::HEART_OF_THE_SEA, 0, "Heart of the Sea")); self::registerItem(new Item(Item::TURTLE_SHELL_PIECE, 0, "Scute")); - //TODO: TURTLE_HELMET - //TODO: COMPOUND - //TODO: RECORD_13 - //TODO: RECORD_CAT - //TODO: RECORD_BLOCKS - //TODO: RECORD_CHIRP - //TODO: RECORD_FAR - //TODO: RECORD_MALL - //TODO: RECORD_MELLOHI - //TODO: RECORD_STAL - //TODO: RECORD_STRAD - //TODO: RECORD_WARD - //TODO: RECORD_11 - //TODO: RECORD_WAIT + //TODO: minecraft:acacia_sign + //TODO: minecraft:armor_stand + //TODO: minecraft:balloon + //TODO: minecraft:birch_sign + //TODO: minecraft:carrotOnAStick + //TODO: minecraft:chest_minecart + //TODO: minecraft:command_block_minecart + //TODO: minecraft:compound + //TODO: minecraft:crossbow + //TODO: minecraft:darkoak_sign + //TODO: minecraft:elytra + //TODO: minecraft:emptyMap + //TODO: minecraft:enchanted_book + //TODO: minecraft:end_crystal + //TODO: minecraft:ender_eye + //TODO: minecraft:fireball + //TODO: minecraft:fireworks + //TODO: minecraft:fireworksCharge + //TODO: minecraft:glow_stick + //TODO: minecraft:hopper_minecart + //TODO: minecraft:horsearmordiamond + //TODO: minecraft:horsearmorgold + //TODO: minecraft:horsearmoriron + //TODO: minecraft:horsearmorleather + //TODO: minecraft:ice_bomb + //TODO: minecraft:jungle_sign + //TODO: minecraft:kelp + //TODO: minecraft:lead + //TODO: minecraft:lingering_potion + //TODO: minecraft:map + //TODO: minecraft:medicine + //TODO: minecraft:name_tag + //TODO: minecraft:phantom_membrane + //TODO: minecraft:rapid_fertilizer + //TODO: minecraft:record_11 + //TODO: minecraft:record_13 + //TODO: minecraft:record_blocks + //TODO: minecraft:record_cat + //TODO: minecraft:record_chirp + //TODO: minecraft:record_far + //TODO: minecraft:record_mall + //TODO: minecraft:record_mellohi + //TODO: minecraft:record_stal + //TODO: minecraft:record_strad + //TODO: minecraft:record_wait + //TODO: minecraft:record_ward + //TODO: minecraft:saddle + //TODO: minecraft:sparkler + //TODO: minecraft:spawn_egg + //TODO: minecraft:spruce_sign + //TODO: minecraft:tnt_minecart + //TODO: minecraft:trident + //TODO: minecraft:turtle_helmet } /** From 260c5dcf0051142138b3719750249b0c4e728dd5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 Feb 2019 12:02:04 +0000 Subject: [PATCH 0464/3224] Clean up tile destruction --- src/pocketmine/level/Explosion.php | 33 ++++++++------------------ src/pocketmine/level/Level.php | 12 +--------- src/pocketmine/tile/Chest.php | 9 ++++++- src/pocketmine/tile/ContainerTrait.php | 20 ++++++++++++++++ src/pocketmine/tile/Tile.php | 15 ++++++++++++ 5 files changed, 54 insertions(+), 35 deletions(-) diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index 5251ee366a..c58ffe0591 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -41,9 +41,6 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\ExplodePacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; -use pocketmine\tile\Chest; -use pocketmine\tile\Container; -use pocketmine\tile\Tile; use function ceil; use function floor; use function mt_rand; @@ -206,31 +203,21 @@ class Explosion{ $airBlock = BlockFactory::get(Block::AIR); foreach($this->affectedBlocks as $block){ - $yieldDrops = false; - if($block instanceof TNT){ $block->ignite(mt_rand(10, 30)); - }elseif($yieldDrops = (mt_rand(0, 100) < $yield)){ - foreach($block->getDrops($air) as $drop){ - $this->level->dropItem($block->add(0.5, 0.5, 0.5), $drop); + }else{ + if(mt_rand(0, 100) < $yield){ + foreach($block->getDrops($air) as $drop){ + $this->level->dropItem($block->add(0.5, 0.5, 0.5), $drop); + } } + if(($t = $this->level->getTileAt($block->x, $block->y, $block->z)) !== null){ + $t->onBlockDestroyed(); //needed to create drops for inventories + } + $this->level->setBlockAt($block->x, $block->y, $block->z, $airBlock, false); //TODO: should updating really be disabled here? + $this->level->updateAllLight($block); } - $this->level->setBlockAt($block->x, $block->y, $block->z, $airBlock, false); //TODO: should updating really be disabled here? - - $t = $this->level->getTileAt($block->x, $block->y, $block->z); - if($t instanceof Tile){ - if($t instanceof Chest){ - $t->unpair(); - } - if($yieldDrops and $t instanceof Container){ - $t->getInventory()->dropContents($this->level, $t->add(0.5, 0.5, 0.5)); - } - - $t->close(); - } - $this->level->updateAllLight($block); - $pos = new Vector3($block->x, $block->y, $block->z); foreach(Facing::ALL as $side){ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index ebe325583a..5734e85dc4 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -81,8 +81,6 @@ use pocketmine\network\mcpe\protocol\UpdateBlockPacket; use pocketmine\Player; use pocketmine\plugin\Plugin; use pocketmine\Server; -use pocketmine\tile\Chest; -use pocketmine\tile\Container; use pocketmine\tile\Spawnable; use pocketmine\tile\Tile; use pocketmine\timings\Timings; @@ -1759,15 +1757,7 @@ class Level implements ChunkManager, Metadatable{ $tile = $this->getTile($target); if($tile !== null){ - if($tile instanceof Container){ - if($tile instanceof Chest){ - $tile->unpair(); - } - - $tile->getInventory()->dropContents($this, $target); - } - - $tile->close(); + $tile->onBlockDestroyed(); } } diff --git a/src/pocketmine/tile/Chest.php b/src/pocketmine/tile/Chest.php index a5aad2fdab..7b2ffb25f2 100644 --- a/src/pocketmine/tile/Chest.php +++ b/src/pocketmine/tile/Chest.php @@ -35,7 +35,9 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ use NameableTrait { addAdditionalSpawnData as addNameSpawnData; } - use ContainerTrait; + use ContainerTrait { + onBlockDestroyedHook as containerTraitBlockDestroyedHook; + } public const TAG_PAIRX = "pairx"; public const TAG_PAIRZ = "pairz"; @@ -104,6 +106,11 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ } } + protected function onBlockDestroyedHook() : void{ + $this->unpair(); + $this->containerTraitBlockDestroyedHook(); + } + /** * @return ChestInventory|DoubleChestInventory */ diff --git a/src/pocketmine/tile/ContainerTrait.php b/src/pocketmine/tile/ContainerTrait.php index 71fe631521..b09bfb42cf 100644 --- a/src/pocketmine/tile/ContainerTrait.php +++ b/src/pocketmine/tile/ContainerTrait.php @@ -25,6 +25,7 @@ namespace pocketmine\tile; use pocketmine\inventory\Inventory; use pocketmine\item\Item; +use pocketmine\level\Position; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; @@ -85,4 +86,23 @@ trait ContainerTrait{ public function canOpenWith(string $key) : bool{ return $this->lock === null or $this->lock === $key; } + + /** + * @see Position::asPosition() + * @return Position + */ + abstract protected function asPosition() : Position; + + /** + * @see Tile::onBlockDestroyedHook() + */ + protected function onBlockDestroyedHook() : void{ + $inv = $this->getRealInventory(); + $pos = $this->asPosition(); + + foreach($inv->getContents() as $k => $item){ + $pos->level->dropItem($pos->add(0.5, 0.5, 0.5), $item); + } + $inv->clearAll(false); + } } diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/tile/Tile.php index 60bb22fff5..963129dfb6 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/tile/Tile.php @@ -129,6 +129,21 @@ abstract class Tile extends Position{ $this->close(); } + /** + * Called when the tile's block is destroyed. + */ + final public function onBlockDestroyed() : void{ + $this->onBlockDestroyedHook(); + $this->close(); + } + + /** + * Override this method to do actions you need to do when this tile is destroyed due to block being broken. + */ + protected function onBlockDestroyedHook() : void{ + + } + public function close() : void{ if(!$this->closed){ $this->closed = true; From 01e7ebeb5c3be054e04774d415b2bb31f63a68cc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 Feb 2019 12:27:13 +0000 Subject: [PATCH 0465/3224] Automate creation and deletion of Tiles for appropriate blocks closes #880 --- src/pocketmine/block/Bed.php | 13 ++++--- src/pocketmine/block/Block.php | 22 ++++++++++++ src/pocketmine/block/Chest.php | 45 +++++++++++------------- src/pocketmine/block/EnchantingTable.php | 11 ++---- src/pocketmine/block/EnderChest.php | 19 +++------- src/pocketmine/block/FlowerPot.php | 12 +++---- src/pocketmine/block/Furnace.php | 11 +++--- src/pocketmine/block/ItemFrame.php | 13 +++---- src/pocketmine/block/SignPost.php | 14 ++++---- src/pocketmine/block/Skull.php | 16 +++++---- src/pocketmine/block/StandingBanner.php | 14 ++++---- src/pocketmine/level/Level.php | 5 +++ src/pocketmine/tile/Banner.php | 2 +- 13 files changed, 100 insertions(+), 97 deletions(-) diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index a4040d95cb..1672346cb3 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -35,7 +35,6 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Bed as TileBed; -use pocketmine\tile\TileFactory; use pocketmine\utils\TextFormat; class Bed extends Transparent{ @@ -84,13 +83,17 @@ class Bed extends Transparent{ } } + protected function getTileClass() : ?string{ + return TileBed::class; + } + public function writeStateToWorld() : void{ parent::writeStateToWorld(); //extra block properties storage hack - /** @var TileBed $tile */ - $tile = TileFactory::create(TileBed::class, $this->getLevel(), $this->asVector3()); - $tile->setColor($this->color); - $this->level->addTile($tile); + $tile = $this->level->getTile($this); + if($tile instanceof TileBed){ + $tile->setColor($this->color); + } } public function getHardness() : float{ diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 1f5a23514b..681d16e9d9 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -41,6 +41,7 @@ use pocketmine\metadata\Metadatable; use pocketmine\metadata\MetadataValue; use pocketmine\Player; use pocketmine\plugin\Plugin; +use pocketmine\tile\TileFactory; use function array_merge; use function assert; use function dechex; @@ -172,8 +173,26 @@ class Block extends Position implements BlockIds, Metadatable{ $this->collisionBoxes = null; } + /** + * Returns the class of Tile associated with this block. + * + * @return string|null class extending Tile, or null + */ + protected function getTileClass() : ?string{ + return null; + } + public function writeStateToWorld() : void{ $this->level->getChunkAtPosition($this)->setBlock($this->x & 0xf, $this->y, $this->z & 0xf, $this->getId(), $this->getDamage()); + + $tileType = $this->getTileClass(); + $oldTile = $this->level->getTile($this); + if($oldTile !== null and ($tileType === null or !($oldTile instanceof $tileType))){ + $oldTile->close(); + } + if($tileType !== null){ + $this->level->addTile(TileFactory::create($tileType, $this->level, $this->asVector3())); + } } /** @@ -315,6 +334,9 @@ class Block extends Position implements BlockIds, Metadatable{ * @return bool */ public function onBreak(Item $item, Player $player = null) : bool{ + if(($t = $this->level->getTile($this)) !== null){ + $t->onBlockDestroyed(); + } return $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR)); } diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index a7bdc97509..24736b3db5 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -30,7 +30,6 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Chest as TileChest; -use pocketmine\tile\TileFactory; class Chest extends Transparent{ @@ -55,6 +54,10 @@ class Chest extends Transparent{ return 0b111; } + protected function getTileClass() : ?string{ + return TileChest::class; + } + public function getHardness() : float{ return 2.5; } @@ -73,34 +76,28 @@ class Chest extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - /** @var TileChest|null $pair */ - $pair = null; if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } - foreach([ - Facing::rotateY($player->getHorizontalFacing(), false), - Facing::rotateY($player->getHorizontalFacing(), true) - ] as $side){ - $c = $this->getSide($side); - if($c instanceof Chest and $c->isSameType($this) and $c->facing === $this->facing){ - $tile = $this->getLevel()->getTile($c); - if($tile instanceof TileChest and !$tile->isPaired()){ - $pair = $tile; - break; - } - } - } - if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - /** @var TileChest $tile */ - $tile = TileFactory::createFromItem(TileChest::class, $this->getLevel(), $this->asVector3(), $item); - $this->level->addTile($tile); - - if($pair instanceof TileChest){ - $pair->pairWith($tile); - $tile->pairWith($pair); + //TODO: this is fragile and might have unintended side effects on ender chests if modified carelessly + $tile = $this->level->getTile($this); + if($tile instanceof TileChest){ + foreach([ + Facing::rotateY($this->facing, true), + Facing::rotateY($this->facing, false) + ] as $side){ + $c = $this->getSide($side); + if($c instanceof Chest and $c->isSameType($this) and $c->facing === $this->facing){ + $pair = $this->level->getTile($c); + if($pair instanceof TileChest and !$pair->isPaired()){ + $pair->pairWith($tile); + $tile->pairWith($pair); + break; + } + } + } } return true; diff --git a/src/pocketmine/block/EnchantingTable.php b/src/pocketmine/block/EnchantingTable.php index 5a1a628634..30db64abef 100644 --- a/src/pocketmine/block/EnchantingTable.php +++ b/src/pocketmine/block/EnchantingTable.php @@ -28,10 +28,8 @@ use pocketmine\item\Item; use pocketmine\item\TieredTool; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; -use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\EnchantTable as TileEnchantingTable; -use pocketmine\tile\TileFactory; class EnchantingTable extends Transparent{ @@ -41,13 +39,8 @@ class EnchantingTable extends Transparent{ } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - $this->level->addTile(TileFactory::createFromItem(TileEnchantingTable::class, $this->getLevel(), $this->asVector3(), $item)); - return true; - } - - return false; + protected function getTileClass() : ?string{ + return TileEnchantingTable::class; } public function getHardness() : float{ diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index 1bde46ab26..34f6e68b6b 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -27,15 +27,17 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; use pocketmine\math\Facing; -use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\EnderChest as TileEnderChest; -use pocketmine\tile\TileFactory; class EnderChest extends Chest{ protected $id = self::ENDER_CHEST; + protected function getTileClass() : ?string{ + return TileEnderChest::class; + } + public function getHardness() : float{ return 22.5; } @@ -60,19 +62,6 @@ class EnderChest extends Chest{ return TieredTool::TIER_WOODEN; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if($player !== null){ //same as normal chest - TODO: clean up inheritance here - $this->facing = Facing::opposite($player->getHorizontalFacing()); - } - - if(Block::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - $this->level->addTile(TileFactory::createFromItem(TileEnderChest::class, $this->getLevel(), $this->asVector3(), $item)); - return true; - } - - return false; - } - public function onActivate(Item $item, Player $player = null) : bool{ if($player instanceof Player){ $enderChest = $this->getLevel()->getTile($this); diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 4b24d626a7..c3061f8b10 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -29,7 +29,6 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\FlowerPot as TileFlowerPot; -use pocketmine\tile\TileFactory; class FlowerPot extends Flowable{ @@ -55,6 +54,10 @@ class FlowerPot extends Flowable{ return 0b1111; //vanilla uses various values, we only care about 1 and 0 for PE } + protected function getTileClass() : ?string{ + return TileFlowerPot::class; + } + public function getName() : string{ return "Flower Pot"; } @@ -68,12 +71,7 @@ class FlowerPot extends Flowable{ return false; } - if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - $this->level->addTile(TileFactory::createFromItem(TileFlowerPot::class, $this->getLevel(), $this->asVector3(), $item)); - return true; - } - - return false; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onNearbyBlockChange() : void{ diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index 031accfad4..3f38829561 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -30,7 +30,6 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Furnace as TileFurnace; -use pocketmine\tile\TileFactory; class Furnace extends Solid{ @@ -61,6 +60,10 @@ class Furnace extends Solid{ return 0b111; } + protected function getTileClass() : ?string{ + return TileFurnace::class; + } + public function getName() : string{ return "Furnace"; } @@ -99,12 +102,8 @@ class Furnace extends Solid{ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } - if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - $this->level->addTile(TileFactory::createFromItem(TileFurnace::class, $this->getLevel(), $this->asVector3(), $item)); - return true; - } - return false; + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onActivate(Item $item, Player $player = null) : bool{ diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 827d7c2ba1..583e85b3fb 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -29,7 +29,6 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\ItemFrame as TileItemFrame; -use pocketmine\tile\TileFactory; use function lcg_value; class ItemFrame extends Flowable{ @@ -56,6 +55,10 @@ class ItemFrame extends Flowable{ return 0b11; } + protected function getTileClass() : ?string{ + return TileItemFrame::class; + } + public function getName() : string{ return "Item Frame"; } @@ -86,13 +89,7 @@ class ItemFrame extends Flowable{ $this->facing = $face; - if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - $this->level->addTile(TileFactory::createFromItem(TileItemFrame::class, $this->getLevel(), $this->asVector3(), $item)); - return true; - } - - return false; - + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/SignPost.php b/src/pocketmine/block/SignPost.php index d9d05131b6..e069472ea7 100644 --- a/src/pocketmine/block/SignPost.php +++ b/src/pocketmine/block/SignPost.php @@ -29,7 +29,6 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Sign as TileSign; -use pocketmine\tile\TileFactory; use function floor; class SignPost extends Transparent{ @@ -57,6 +56,10 @@ class SignPost extends Transparent{ return 0b1111; } + protected function getTileClass() : ?string{ + return TileSign::class; + } + public function getHardness() : float{ return 1; } @@ -78,15 +81,10 @@ class SignPost extends Transparent{ if($face === Facing::UP){ $this->rotation = $player !== null ? ((int) floor((($player->yaw + 180) * 16 / 360) + 0.5)) & 0x0f : 0; - $ret = parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); - }else{ - $ret = $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::WALL_SIGN, $face)); + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - if($ret){ - $this->level->addTile(TileFactory::createFromItem(TileSign::class, $this->getLevel(), $this->asVector3(), $item)); - return true; - } + return $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::WALL_SIGN, $face)); } return false; diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index 156ed0da7b..acce6c4c40 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -31,7 +31,6 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Skull as TileSkull; -use pocketmine\tile\TileFactory; use function floor; class Skull extends Flowable{ @@ -70,13 +69,18 @@ class Skull extends Flowable{ } } + protected function getTileClass() : ?string{ + return TileSkull::class; + } + public function writeStateToWorld() : void{ parent::writeStateToWorld(); - /** @var TileSkull $tile */ - $tile = TileFactory::create(TileSkull::class, $this->getLevel(), $this->asVector3()); - $tile->setRotation($this->rotation); - $tile->setType($this->type); - $this->level->addTile($tile); + //extra block properties storage hack + $tile = $this->level->getTile($this); + if($tile instanceof TileSkull){ + $tile->setRotation($this->rotation); + $tile->setType($this->type); + } } public function getHardness() : float{ diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index ff58a176e6..7679a10399 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -31,7 +31,6 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Banner as TileBanner; -use pocketmine\tile\TileFactory; use function floor; class StandingBanner extends Transparent{ @@ -59,6 +58,10 @@ class StandingBanner extends Transparent{ return 0b1111; } + protected function getTileClass() : ?string{ + return TileBanner::class; + } + public function getHardness() : float{ return 1; } @@ -79,15 +82,10 @@ class StandingBanner extends Transparent{ if($face !== Facing::DOWN){ if($face === Facing::UP and $player !== null){ $this->rotation = ((int) floor((($player->yaw + 180) * 16 / 360) + 0.5)) & 0x0f; - $ret = parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); - }else{ - $ret = $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::WALL_BANNER, $face)); + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - if($ret){ - $this->level->addTile(TileFactory::createFromItem(TileBanner::class, $this->getLevel(), $this->asVector3(), $item)); - return true; - } + return $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::WALL_BANNER, $face)); } return false; diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 5734e85dc4..c8ee60798b 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1869,6 +1869,11 @@ class Level implements ChunkManager, Metadatable{ if(!$hand->place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ return false; } + $tile = $this->getTile($hand); + if($tile !== null){ + //TODO: seal this up inside block placement + $tile->copyDataFromItem($item); + } if($playSound){ $this->broadcastLevelSoundEvent($hand, LevelSoundEventPacket::SOUND_PLACE, $hand->getRuntimeId()); diff --git a/src/pocketmine/tile/Banner.php b/src/pocketmine/tile/Banner.php index 3266236fb7..b799cc7136 100644 --- a/src/pocketmine/tile/Banner.php +++ b/src/pocketmine/tile/Banner.php @@ -36,7 +36,7 @@ use function assert; class Banner extends Spawnable implements Nameable{ use NameableTrait { addAdditionalSpawnData as addNameSpawnData; - copyDataFromItem as copyNameFromItem; + copyDataFromItem as protected copyNameFromItem; } public const TAG_BASE = "Base"; From 55be0716d83e8aa47105080321c2e9e4eb25d70a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 Feb 2019 13:49:44 +0000 Subject: [PATCH 0466/3224] Use DyeColor instead of ints for banners --- src/pocketmine/block/StandingBanner.php | 2 +- src/pocketmine/item/Banner.php | 35 ++++++++------- src/pocketmine/tile/Banner.php | 60 ++++++++++--------------- 3 files changed, 43 insertions(+), 54 deletions(-) diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index 7679a10399..738e5e2c14 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -104,7 +104,7 @@ class StandingBanner extends Transparent{ public function getDropsForCompatibleTool(Item $item) : array{ $tile = $this->level->getTile($this); - $drop = ItemFactory::get(Item::BANNER, ($tile instanceof TileBanner ? $tile->getBaseColor() : 0)); + $drop = ItemFactory::get(Item::BANNER, ($tile instanceof TileBanner ? $tile->getBaseColor()->getInvertedMagicNumber() : 0)); if($tile instanceof TileBanner and $drop instanceof ItemBanner and !($patterns = $tile->getPatterns())->empty()){ $drop->setPatterns($patterns); } diff --git a/src/pocketmine/item/Banner.php b/src/pocketmine/item/Banner.php index 34f0da17ad..a8e6c287e3 100644 --- a/src/pocketmine/item/Banner.php +++ b/src/pocketmine/item/Banner.php @@ -25,6 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\utils\DyeColor; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; @@ -53,21 +54,21 @@ class Banner extends Item{ /** * Returns the color of the banner base. * - * @return int + * @return DyeColor */ - public function getBaseColor() : int{ - return $this->getNamedTag()->getInt(self::TAG_BASE, $this->getDamage()); + public function getBaseColor() : DyeColor{ + return DyeColor::fromMagicNumber($this->getNamedTag()->getInt(self::TAG_BASE, $this->getDamage()), true); } /** * Sets the color of the banner base. * Banner items have to be resent to see the changes in the inventory. * - * @param int $color + * @param DyeColor $color */ - public function setBaseColor(int $color) : void{ + public function setBaseColor(DyeColor $color) : void{ $namedTag = $this->getNamedTag(); - $namedTag->setInt(self::TAG_BASE, $color & 0x0f); + $namedTag->setInt(self::TAG_BASE, $color->getInvertedMagicNumber()); $this->setNamedTag($namedTag); } @@ -75,17 +76,17 @@ class Banner extends Item{ * Applies a new pattern on the banner with the given color. * Banner items have to be resent to see the changes in the inventory. * - * @param string $pattern - * @param int $color + * @param string $pattern + * @param DyeColor $color * * @return int ID of pattern. */ - public function addPattern(string $pattern, int $color) : int{ + public function addPattern(string $pattern, DyeColor $color) : int{ $patternsTag = $this->getNamedTag()->getListTag(self::TAG_PATTERNS); assert($patternsTag !== null); $patternsTag->push(new CompoundTag("", [ - new IntTag(self::TAG_PATTERN_COLOR, $color & 0x0f), + new IntTag(self::TAG_PATTERN_COLOR, $color->getInvertedMagicNumber()), new StringTag(self::TAG_PATTERN_NAME, $pattern) ])); @@ -124,7 +125,7 @@ class Banner extends Item{ assert($pattern instanceof CompoundTag); return [ - self::TAG_PATTERN_COLOR => $pattern->getInt(self::TAG_PATTERN_COLOR), + self::TAG_PATTERN_COLOR => DyeColor::fromMagicNumber($pattern->getInt(self::TAG_PATTERN_COLOR), true), self::TAG_PATTERN_NAME => $pattern->getString(self::TAG_PATTERN_NAME) ]; } @@ -133,13 +134,13 @@ class Banner extends Item{ * Changes the pattern of a previously existing pattern. * Banner items have to be resent to see the changes in the inventory. * - * @param int $patternId - * @param string $pattern - * @param int $color + * @param int $patternId + * @param string $pattern + * @param DyeColor $color * * @return bool indicating success. */ - public function changePattern(int $patternId, string $pattern, int $color) : bool{ + public function changePattern(int $patternId, string $pattern, DyeColor $color) : bool{ if(!$this->patternExists($patternId)){ return false; } @@ -148,7 +149,7 @@ class Banner extends Item{ assert($patternsTag !== null); $patternsTag->set($patternId, new CompoundTag("", [ - new IntTag(self::TAG_PATTERN_COLOR, $color & 0x0f), + new IntTag(self::TAG_PATTERN_COLOR, $color->getInvertedMagicNumber()), new StringTag(self::TAG_PATTERN_NAME, $pattern) ])); @@ -224,7 +225,7 @@ class Banner extends Item{ public function correctNBT() : void{ $tag = $this->getNamedTag(); if(!$tag->hasTag(self::TAG_BASE, IntTag::class)){ - $tag->setInt(self::TAG_BASE, 0); + $tag->setInt(self::TAG_BASE, DyeColor::$BLACK->getInvertedMagicNumber()); } if(!$tag->hasTag(self::TAG_PATTERNS, ListTag::class)){ diff --git a/src/pocketmine/tile/Banner.php b/src/pocketmine/tile/Banner.php index b799cc7136..f1958e281c 100644 --- a/src/pocketmine/tile/Banner.php +++ b/src/pocketmine/tile/Banner.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\tile; +use pocketmine\block\utils\DyeColor; use pocketmine\item\Banner as ItemBanner; use pocketmine\item\Item; use pocketmine\level\Level; @@ -83,25 +84,8 @@ class Banner extends Spawnable implements Nameable{ public const PATTERN_FLOWER = "flo"; public const PATTERN_MOJANG = "moj"; - public const COLOR_BLACK = 0; - public const COLOR_RED = 1; - public const COLOR_GREEN = 2; - public const COLOR_BROWN = 3; - public const COLOR_BLUE = 4; - public const COLOR_PURPLE = 5; - public const COLOR_CYAN = 6; - public const COLOR_LIGHT_GRAY = 7; - public const COLOR_GRAY = 8; - public const COLOR_PINK = 9; - public const COLOR_LIME = 10; - public const COLOR_YELLOW = 11; - public const COLOR_LIGHT_BLUE = 12; - public const COLOR_MAGENTA = 13; - public const COLOR_ORANGE = 14; - public const COLOR_WHITE = 15; - - /** @var int */ - private $baseColor = self::COLOR_BLACK; + /** @var DyeColor */ + private $baseColor; /** * @var ListTag * TODO: break this down further and remove runtime NBT from here entirely @@ -109,24 +93,28 @@ class Banner extends Spawnable implements Nameable{ private $patterns; public function __construct(Level $level, Vector3 $pos){ + $this->baseColor = DyeColor::$BLACK; $this->patterns = new ListTag(self::TAG_PATTERNS); parent::__construct($level, $pos); } public function readSaveData(CompoundTag $nbt) : void{ - $this->baseColor = $nbt->getInt(self::TAG_BASE, $this->baseColor, true); + if($nbt->hasTag(self::TAG_BASE, IntTag::class)){ + $this->baseColor = DyeColor::fromMagicNumber($nbt->getInt(self::TAG_BASE), true); + } + $this->patterns = $nbt->getListTag(self::TAG_PATTERNS) ?? $this->patterns; $this->loadName($nbt); } protected function writeSaveData(CompoundTag $nbt) : void{ - $nbt->setInt(self::TAG_BASE, $this->baseColor); + $nbt->setInt(self::TAG_BASE, $this->baseColor->getInvertedMagicNumber()); $nbt->setTag($this->patterns); $this->saveName($nbt); } protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ - $nbt->setInt(self::TAG_BASE, $this->baseColor); + $nbt->setInt(self::TAG_BASE, $this->baseColor->getInvertedMagicNumber()); $nbt->setTag($this->patterns); $this->addNameSpawnData($nbt); } @@ -145,18 +133,18 @@ class Banner extends Spawnable implements Nameable{ /** * Returns the color of the banner base. * - * @return int + * @return DyeColor */ - public function getBaseColor() : int{ + public function getBaseColor() : DyeColor{ return $this->baseColor; } /** * Sets the color of the banner base. * - * @param int $color + * @param DyeColor $color */ - public function setBaseColor(int $color) : void{ + public function setBaseColor(DyeColor $color) : void{ $this->baseColor = $color; $this->onChanged(); } @@ -164,14 +152,14 @@ class Banner extends Spawnable implements Nameable{ /** * Applies a new pattern on the banner with the given color. * - * @param string $pattern - * @param int $color + * @param string $pattern + * @param DyeColor $color * * @return int ID of pattern. */ - public function addPattern(string $pattern, int $color) : int{ + public function addPattern(string $pattern, DyeColor $color) : int{ $this->patterns->push(new CompoundTag("", [ - new IntTag(self::TAG_PATTERN_COLOR, $color & 0x0f), + new IntTag(self::TAG_PATTERN_COLOR, $color->getInvertedMagicNumber()), new StringTag(self::TAG_PATTERN_NAME, $pattern) ])); @@ -206,7 +194,7 @@ class Banner extends Spawnable implements Nameable{ assert($patternTag instanceof CompoundTag); return [ - self::TAG_PATTERN_COLOR => $patternTag->getInt(self::TAG_PATTERN_COLOR), + self::TAG_PATTERN_COLOR => DyeColor::fromMagicNumber($patternTag->getInt(self::TAG_PATTERN_COLOR), true), self::TAG_PATTERN_NAME => $patternTag->getString(self::TAG_PATTERN_NAME) ]; } @@ -214,19 +202,19 @@ class Banner extends Spawnable implements Nameable{ /** * Changes the pattern of a previously existing pattern. * - * @param int $patternId - * @param string $pattern - * @param int $color + * @param int $patternId + * @param string $pattern + * @param DyeColor $color * * @return bool indicating success. */ - public function changePattern(int $patternId, string $pattern, int $color) : bool{ + public function changePattern(int $patternId, string $pattern, DyeColor $color) : bool{ if(!$this->patternExists($patternId)){ return false; } $this->patterns->set($patternId, new CompoundTag("", [ - new IntTag(self::TAG_PATTERN_COLOR, $color & 0x0f), + new IntTag(self::TAG_PATTERN_COLOR, $color->getInvertedMagicNumber()), new StringTag(self::TAG_PATTERN_NAME, $pattern) ])); From 7b6d76871c930d9350156cf77841381644de9ed7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 Feb 2019 14:29:59 +0000 Subject: [PATCH 0467/3224] Block: add face and clickVector to onActivate() parameters, closes #267 this is an old old old issue, i don't know why it wasn't addressed sooner. --- src/pocketmine/block/Anvil.php | 2 +- src/pocketmine/block/Bed.php | 2 +- src/pocketmine/block/Block.php | 4 +++- src/pocketmine/block/Button.php | 2 +- src/pocketmine/block/Cake.php | 2 +- src/pocketmine/block/Chest.php | 2 +- src/pocketmine/block/CoarseDirt.php | 6 ++++-- src/pocketmine/block/CocoaBlock.php | 2 +- src/pocketmine/block/CraftingTable.php | 3 ++- src/pocketmine/block/Crops.php | 2 +- src/pocketmine/block/DaylightSensor.php | 3 ++- src/pocketmine/block/Dirt.php | 6 ++++-- src/pocketmine/block/Door.php | 2 +- src/pocketmine/block/EnchantingTable.php | 3 ++- src/pocketmine/block/EnderChest.php | 3 ++- src/pocketmine/block/FenceGate.php | 2 +- src/pocketmine/block/FlowerPot.php | 2 +- src/pocketmine/block/Furnace.php | 2 +- src/pocketmine/block/Grass.php | 6 +++++- src/pocketmine/block/ItemFrame.php | 2 +- src/pocketmine/block/Lever.php | 2 +- src/pocketmine/block/RedstoneOre.php | 2 +- src/pocketmine/block/RedstoneRepeater.php | 2 +- src/pocketmine/block/Sapling.php | 2 +- src/pocketmine/block/Sugarcane.php | 2 +- src/pocketmine/block/TNT.php | 2 +- src/pocketmine/block/Trapdoor.php | 2 +- src/pocketmine/level/Level.php | 4 ++-- 28 files changed, 45 insertions(+), 31 deletions(-) diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index 0c0c0b0aea..1a035b355c 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -78,7 +78,7 @@ class Anvil extends Fallable{ return AxisAlignedBB::one()->squash(Facing::axis(Facing::rotateY($this->facing, false)), 1 / 8); } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ $player->addWindow(new AnvilInventory($this)); } diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 1672346cb3..286b8feb57 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -148,7 +148,7 @@ class Bed extends Transparent{ return null; } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $other = $this->getOtherHalf(); if($other === null){ diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 681d16e9d9..e290d6c4f1 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -402,11 +402,13 @@ class Block extends Position implements BlockIds, Metadatable{ * Do actions when activated by Item. Returns if it has done anything * * @param Item $item + * @param int $face + * @param Vector3 $clickVector * @param Player|null $player * * @return bool */ - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ return false; } diff --git a/src/pocketmine/block/Button.php b/src/pocketmine/block/Button.php index 54d16b337a..bc472bbe36 100644 --- a/src/pocketmine/block/Button.php +++ b/src/pocketmine/block/Button.php @@ -63,7 +63,7 @@ abstract class Button extends Flowable{ abstract protected function getActivationTime() : int; - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$this->powered){ $this->powered = true; $this->level->setBlock($this, $this); diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index 5518c467ec..47d21e4385 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -96,7 +96,7 @@ class Cake extends Transparent implements FoodSource{ return false; } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $player->consumeObject($this); return true; diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index 24736b3db5..b55a258289 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -106,7 +106,7 @@ class Chest extends Transparent{ return false; } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ $chest = $this->getLevel()->getTile($this); diff --git a/src/pocketmine/block/CoarseDirt.php b/src/pocketmine/block/CoarseDirt.php index 2f3a3eb253..23b16f716c 100644 --- a/src/pocketmine/block/CoarseDirt.php +++ b/src/pocketmine/block/CoarseDirt.php @@ -25,12 +25,14 @@ namespace pocketmine\block; use pocketmine\item\Hoe; use pocketmine\item\Item; +use pocketmine\math\Facing; +use pocketmine\math\Vector3; use pocketmine\Player; class CoarseDirt extends Dirt{ - public function onActivate(Item $item, Player $player = null) : bool{ - if($item instanceof Hoe){ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($face === Facing::UP and $item instanceof Hoe){ $item->applyDamage(1); $this->getLevel()->setBlock($this, BlockFactory::get(Block::DIRT)); return true; diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index 9328fb9fc0..72fdb5a52a 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -94,7 +94,7 @@ class CocoaBlock extends Transparent{ return false; } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($this->age < 2 and $item->getId() === Item::DYE and $item->getDamage() === 15){ //bone meal $this->age++; $this->level->setBlock($this, $this); diff --git a/src/pocketmine/block/CraftingTable.php b/src/pocketmine/block/CraftingTable.php index 1576e389d2..113cfb6b62 100644 --- a/src/pocketmine/block/CraftingTable.php +++ b/src/pocketmine/block/CraftingTable.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\inventory\CraftingGrid; use pocketmine\item\Item; +use pocketmine\math\Vector3; use pocketmine\Player; class CraftingTable extends Solid{ @@ -47,7 +48,7 @@ class CraftingTable extends Solid{ return BlockToolType::TYPE_AXE; } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ $player->setCraftingGrid(new CraftingGrid($player, CraftingGrid::SIZE_BIG)); } diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index c56c678b2c..4a575a8f91 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -60,7 +60,7 @@ abstract class Crops extends Flowable{ } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($this->age < 7 and $item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal $block = clone $this; $block->age += mt_rand(2, 5); diff --git a/src/pocketmine/block/DaylightSensor.php b/src/pocketmine/block/DaylightSensor.php index 9fdbd267c2..cdf9814a3e 100644 --- a/src/pocketmine/block/DaylightSensor.php +++ b/src/pocketmine/block/DaylightSensor.php @@ -27,6 +27,7 @@ use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; +use pocketmine\math\Vector3; use pocketmine\Player; class DaylightSensor extends Transparent{ @@ -93,7 +94,7 @@ class DaylightSensor extends Transparent{ return AxisAlignedBB::one()->trim(Facing::UP, 0.5); } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->inverted = !$this->inverted; $this->level->setBlock($this, $this); return true; diff --git a/src/pocketmine/block/Dirt.php b/src/pocketmine/block/Dirt.php index e810b0ab58..c19c9ff66d 100644 --- a/src/pocketmine/block/Dirt.php +++ b/src/pocketmine/block/Dirt.php @@ -25,6 +25,8 @@ namespace pocketmine\block; use pocketmine\item\Hoe; use pocketmine\item\Item; +use pocketmine\math\Facing; +use pocketmine\math\Vector3; use pocketmine\Player; class Dirt extends Solid{ @@ -39,8 +41,8 @@ class Dirt extends Solid{ return BlockToolType::TYPE_SHOVEL; } - public function onActivate(Item $item, Player $player = null) : bool{ - if($item instanceof Hoe){ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($face === Facing::UP and $item instanceof Hoe){ $item->applyDamage(1); $this->getLevel()->setBlock($this, BlockFactory::get(Block::FARMLAND)); diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index d2602c9522..424b6a4b3e 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -134,7 +134,7 @@ abstract class Door extends Transparent{ return false; } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->open = !$this->open; $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); diff --git a/src/pocketmine/block/EnchantingTable.php b/src/pocketmine/block/EnchantingTable.php index 30db64abef..b8719674b2 100644 --- a/src/pocketmine/block/EnchantingTable.php +++ b/src/pocketmine/block/EnchantingTable.php @@ -28,6 +28,7 @@ use pocketmine\item\Item; use pocketmine\item\TieredTool; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; +use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\EnchantTable as TileEnchantingTable; @@ -67,7 +68,7 @@ class EnchantingTable extends Transparent{ return AxisAlignedBB::one()->trim(Facing::UP, 0.25); } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ //TODO lock diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index 34f6e68b6b..c4d8610860 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -27,6 +27,7 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; use pocketmine\math\Facing; +use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\EnderChest as TileEnderChest; @@ -62,7 +63,7 @@ class EnderChest extends Chest{ return TieredTool::TIER_WOODEN; } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ $enderChest = $this->getLevel()->getTile($this); if($enderChest instanceof TileEnderChest and $this->getSide(Facing::UP)->isTransparent()){ diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index 4be8fd463d..0914d202da 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -76,7 +76,7 @@ class FenceGate extends Transparent{ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->open = !$this->open; if($this->open and $player !== null){ $playerFacing = $player->getHorizontalFacing(); diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index c3061f8b10..35968885bc 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -80,7 +80,7 @@ class FlowerPot extends Flowable{ } } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $pot = $this->getLevel()->getTile($this); if(!($pot instanceof TileFlowerPot)){ return false; diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index 3f38829561..5f1449496d 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -106,7 +106,7 @@ class Furnace extends Solid{ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ $furnace = $this->getLevel()->getTile($this); if($furnace instanceof TileFurnace and $furnace->canOpenWith($item->getCustomName())){ diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index 607d851b03..fadb3aaee0 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -30,6 +30,7 @@ use pocketmine\item\ItemFactory; use pocketmine\item\Shovel; use pocketmine\level\generator\object\TallGrass as TallGrassObject; use pocketmine\math\Facing; +use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\utils\Random; use function mt_rand; @@ -99,7 +100,10 @@ class Grass extends Solid{ } } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($face !== Facing::UP){ + return false; + } if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ $item->pop(); TallGrassObject::growGrass($this->getLevel(), $this, new Random(mt_rand()), 8, 2); diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 583e85b3fb..566b404023 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -63,7 +63,7 @@ class ItemFrame extends Flowable{ return "Item Frame"; } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $tile = $this->level->getTile($this); if($tile instanceof TileItemFrame){ if($tile->hasItem()){ diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index 11a8f4efe4..16873081d4 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -119,7 +119,7 @@ class Lever extends Flowable{ } } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->powered = !$this->powered; $this->level->setBlock($this, $this); $this->level->broadcastLevelSoundEvent( diff --git a/src/pocketmine/block/RedstoneOre.php b/src/pocketmine/block/RedstoneOre.php index 798a9cc593..3a452c21e0 100644 --- a/src/pocketmine/block/RedstoneOre.php +++ b/src/pocketmine/block/RedstoneOre.php @@ -75,7 +75,7 @@ class RedstoneOre extends Solid{ return $this->getLevel()->setBlock($this, $this, false); } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$this->lit){ $this->lit = true; $this->getLevel()->setBlock($this, $this); //no return here - this shouldn't prevent block placement diff --git a/src/pocketmine/block/RedstoneRepeater.php b/src/pocketmine/block/RedstoneRepeater.php index a8b98836d7..4917890d95 100644 --- a/src/pocketmine/block/RedstoneRepeater.php +++ b/src/pocketmine/block/RedstoneRepeater.php @@ -97,7 +97,7 @@ class RedstoneRepeater extends Flowable{ return false; } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(++$this->delay > 4){ $this->delay = 1; } diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index adacce1b86..e99ce48f14 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -65,7 +65,7 @@ class Sapling extends Flowable{ return false; } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal //TODO: change log type Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->treeType); diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index dcf03cbf70..d9ce7087e2 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -59,7 +59,7 @@ class Sugarcane extends Flowable{ return "Sugarcane"; } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal if($this->getSide(Facing::DOWN)->getId() !== self::SUGARCANE_BLOCK){ for($y = 1; $y < 3; ++$y){ diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index 76421375b8..3a9caf54d4 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -52,7 +52,7 @@ class TNT extends Solid{ return 0; } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof FlintSteel){ $item->applyDamage(1); $this->ignite(); diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index a943d6ad16..85583ac778 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -87,7 +87,7 @@ class Trapdoor extends Transparent{ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - public function onActivate(Item $item, Player $player = null) : bool{ + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->open = !$this->open; $this->level->setBlock($this, $this); $this->level->addSound($this, new DoorSound()); diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index c8ee60798b..4359f1b44e 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1794,7 +1794,7 @@ class Level implements ChunkManager, Metadatable{ $ev = new PlayerInteractEvent($player, $item, $blockClicked, $clickVector, $face, PlayerInteractEvent::RIGHT_CLICK_BLOCK); $ev->call(); if(!$ev->isCancelled()){ - if(!$player->isSneaking() and $blockClicked->onActivate($item, $player)){ + if(!$player->isSneaking() and $blockClicked->onActivate($item, $face, $clickVector, $player)){ return true; } @@ -1804,7 +1804,7 @@ class Level implements ChunkManager, Metadatable{ }else{ return false; } - }elseif($blockClicked->onActivate($item, $player)){ + }elseif($blockClicked->onActivate($item, $face, $clickVector, $player)){ return true; } From 205e13d88002bae9a4fbbf11ea4ab791b84d739d Mon Sep 17 00:00:00 2001 From: "Jack M. Taylor" <32965703+JackMD@users.noreply.github.com> Date: Thu, 14 Feb 2019 15:58:19 +0500 Subject: [PATCH 0468/3224] Config: add getPath() (#2758) Config->getPath() returns the path of the config i.e. the place where the config file is located. --- src/pocketmine/utils/Config.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/pocketmine/utils/Config.php b/src/pocketmine/utils/Config.php index e5617f0c56..7b9c2a7106 100644 --- a/src/pocketmine/utils/Config.php +++ b/src/pocketmine/utils/Config.php @@ -192,6 +192,15 @@ class Config{ } } + /** + * Returns the path of the config. + * + * @return string + */ + public function getPath() : string{ + return $this->file; + } + /** * Flushes the config to disk in the appropriate format. * From dce08b4e88bea4065149d6843d64344f7a25872a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 14 Feb 2019 19:21:29 +0000 Subject: [PATCH 0469/3224] Introduce Item use results - can be success, fail or none closes #2693, closes #2705, closes #2734 --- src/pocketmine/Player.php | 13 +++++- src/pocketmine/item/Bow.php | 53 ++++++++++----------- src/pocketmine/item/Bucket.php | 9 ++-- src/pocketmine/item/FlintSteel.php | 6 +-- src/pocketmine/item/Item.php | 18 +++---- src/pocketmine/item/ItemUseResult.php | 65 ++++++++++++++++++++++++++ src/pocketmine/item/LiquidBucket.php | 13 +++--- src/pocketmine/item/PaintingItem.php | 4 +- src/pocketmine/item/ProjectileItem.php | 13 +++--- src/pocketmine/item/SpawnEgg.php | 5 +- src/pocketmine/level/Level.php | 8 +++- 11 files changed, 143 insertions(+), 64 deletions(-) create mode 100644 src/pocketmine/item/ItemUseResult.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index aa5518afd0..012d47258c 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -80,6 +80,7 @@ use pocketmine\item\Durable; use pocketmine\item\enchantment\EnchantmentInstance; use pocketmine\item\enchantment\MeleeWeaponEnchantment; use pocketmine\item\Item; +use pocketmine\item\ItemUseResult; use pocketmine\item\WritableBook; use pocketmine\item\WrittenBook; use pocketmine\lang\TextContainer; @@ -2061,11 +2062,14 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return false; } - if($item->onClickAir($this, $directionVector)){ + $result = $item->onClickAir($this, $directionVector); + if($result === ItemUseResult::success()){ $this->resetItemCooldown($item); if($this->isSurvival()){ $this->inventory->setItemInHand($item); } + }elseif($result === ItemUseResult::fail()){ + $this->inventory->sendHeldItem($this); } //TODO: check if item has a release action - if it doesn't, this shouldn't be set @@ -2120,11 +2124,16 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->inventory->sendContents($this); return false; } - if($item->onReleaseUsing($this)){ + $result = $item->onReleaseUsing($this); + if($result === ItemUseResult::success()){ $this->resetItemCooldown($item); $this->inventory->setItemInHand($item); return true; } + if($result === ItemUseResult::fail()){ + $this->inventory->sendContents($this); + return true; + } } return false; diff --git a/src/pocketmine/item/Bow.php b/src/pocketmine/item/Bow.php index 9d1b500138..ec694619de 100644 --- a/src/pocketmine/item/Bow.php +++ b/src/pocketmine/item/Bow.php @@ -47,10 +47,9 @@ class Bow extends Tool{ return 385; } - public function onReleaseUsing(Player $player) : bool{ + public function onReleaseUsing(Player $player) : ItemUseResult{ if($player->isSurvival() and !$player->getInventory()->contains(ItemFactory::get(Item::ARROW, 0, 1))){ - $player->getInventory()->sendContents($player); - return false; + return ItemUseResult::fail(); } $nbt = EntityFactory::createBaseNBT( @@ -93,30 +92,32 @@ class Bow extends Tool{ if($ev->isCancelled()){ $entity->flagForDespawn(); - $player->getInventory()->sendContents($player); - }else{ - $entity->setMotion($entity->getMotion()->multiply($ev->getForce())); - if($player->isSurvival()){ - if(!$infinity){ //TODO: tipped arrows are still consumed when Infinity is applied - $player->getInventory()->removeItem(ItemFactory::get(Item::ARROW, 0, 1)); - } - $this->applyDamage(1); - } - - if($entity instanceof Projectile){ - $projectileEv = new ProjectileLaunchEvent($entity); - $projectileEv->call(); - if($projectileEv->isCancelled()){ - $ev->getProjectile()->flagForDespawn(); - }else{ - $ev->getProjectile()->spawnToAll(); - $player->getLevel()->broadcastLevelSoundEvent($player, LevelSoundEventPacket::SOUND_BOW); - } - }else{ - $entity->spawnToAll(); - } + return ItemUseResult::fail(); } - return true; + $entity->setMotion($entity->getMotion()->multiply($ev->getForce())); + + if($entity instanceof Projectile){ + $projectileEv = new ProjectileLaunchEvent($entity); + $projectileEv->call(); + if($projectileEv->isCancelled()){ + $ev->getProjectile()->flagForDespawn(); + return ItemUseResult::fail(); + } + + $ev->getProjectile()->spawnToAll(); + $player->getLevel()->broadcastLevelSoundEvent($player, LevelSoundEventPacket::SOUND_BOW); + }else{ + $entity->spawnToAll(); + } + + if($player->isSurvival()){ + if(!$infinity){ //TODO: tipped arrows are still consumed when Infinity is applied + $player->getInventory()->removeItem(ItemFactory::get(Item::ARROW, 0, 1)); + } + $this->applyDamage(1); + } + + return ItemUseResult::success(); } } diff --git a/src/pocketmine/item/Bucket.php b/src/pocketmine/item/Bucket.php index 3650e45f3a..5a17c2de17 100644 --- a/src/pocketmine/item/Bucket.php +++ b/src/pocketmine/item/Bucket.php @@ -36,7 +36,7 @@ class Bucket extends Item{ return 16; } - public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : bool{ + public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ //TODO: move this to generic placement logic if($blockClicked instanceof Liquid and $blockClicked->isSource()){ $stack = clone $this; @@ -58,13 +58,12 @@ class Bucket extends Item{ }else{ $player->getInventory()->addItem($ev->getItem()); } - }else{ - $player->getInventory()->sendContents($player); + return ItemUseResult::success(); } - return true; + return ItemUseResult::fail(); } - return false; + return ItemUseResult::none(); } } diff --git a/src/pocketmine/item/FlintSteel.php b/src/pocketmine/item/FlintSteel.php index a144c59cba..f36b687fac 100644 --- a/src/pocketmine/item/FlintSteel.php +++ b/src/pocketmine/item/FlintSteel.php @@ -35,7 +35,7 @@ class FlintSteel extends Tool{ parent::__construct(self::FLINT_STEEL, 0, "Flint and Steel"); } - public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : bool{ + public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ if($blockReplace->getId() === self::AIR){ $level = $player->getLevel(); assert($level !== null); @@ -44,10 +44,10 @@ class FlintSteel extends Tool{ $this->applyDamage(1); - return true; + return ItemUseResult::success(); } - return false; + return ItemUseResult::none(); } public function getMaxDurability() : int{ diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 60296abf76..d877b204ee 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -735,10 +735,10 @@ class Item implements ItemIds, \JsonSerializable{ * @param int $face * @param Vector3 $clickVector * - * @return bool + * @return ItemUseResult */ - public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : bool{ - return false; + public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ + return ItemUseResult::none(); } /** @@ -748,10 +748,10 @@ class Item implements ItemIds, \JsonSerializable{ * @param Player $player * @param Vector3 $directionVector * - * @return bool + * @return ItemUseResult */ - public function onClickAir(Player $player, Vector3 $directionVector) : bool{ - return false; + public function onClickAir(Player $player, Vector3 $directionVector) : ItemUseResult{ + return ItemUseResult::none(); } /** @@ -760,10 +760,10 @@ class Item implements ItemIds, \JsonSerializable{ * * @param Player $player * - * @return bool + * @return ItemUseResult */ - public function onReleaseUsing(Player $player) : bool{ - return false; + public function onReleaseUsing(Player $player) : ItemUseResult{ + return ItemUseResult::none(); } /** diff --git a/src/pocketmine/item/ItemUseResult.php b/src/pocketmine/item/ItemUseResult.php new file mode 100644 index 0000000000..78b89802c1 --- /dev/null +++ b/src/pocketmine/item/ItemUseResult.php @@ -0,0 +1,65 @@ +canBeReplaced()){ - return false; + return ItemUseResult::none(); } //TODO: move this to generic placement logic $resultBlock = BlockFactory::get($this->liquidId); - if($resultBlock instanceof Liquid){ + if($resultBlock instanceof Liquid){ //TODO: this should never be false $ev = new PlayerBucketEmptyEvent($player, $blockReplace, $face, $this, ItemFactory::get(Item::BUCKET)); $ev->call(); if(!$ev->isCancelled()){ @@ -69,13 +69,12 @@ class LiquidBucket extends Item{ if($player->isSurvival()){ $player->getInventory()->setItemInHand($ev->getItem()); } - }else{ - $player->getInventory()->sendContents($player); + return ItemUseResult::success(); } - return true; + return ItemUseResult::fail(); } - return false; + return ItemUseResult::none(); } } diff --git a/src/pocketmine/item/PaintingItem.php b/src/pocketmine/item/PaintingItem.php index 2856b7f925..03c51a14c0 100644 --- a/src/pocketmine/item/PaintingItem.php +++ b/src/pocketmine/item/PaintingItem.php @@ -38,9 +38,9 @@ class PaintingItem extends Item{ parent::__construct(self::PAINTING, 0, "Painting"); } - public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : bool{ + public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ if(Facing::axis($face) === Facing::AXIS_Y){ - return false; + return ItemUseResult::none(); } $motives = []; diff --git a/src/pocketmine/item/ProjectileItem.php b/src/pocketmine/item/ProjectileItem.php index 14bb8e5875..02b564d13c 100644 --- a/src/pocketmine/item/ProjectileItem.php +++ b/src/pocketmine/item/ProjectileItem.php @@ -53,7 +53,7 @@ abstract class ProjectileItem extends Item{ } - public function onClickAir(Player $player, Vector3 $directionVector) : bool{ + public function onClickAir(Player $player, Vector3 $directionVector) : ItemUseResult{ $nbt = EntityFactory::createBaseNBT($player->add(0, $player->getEyeHeight(), 0), $directionVector, $player->yaw, $player->pitch); $this->addExtraTags($nbt); @@ -68,14 +68,15 @@ abstract class ProjectileItem extends Item{ $projectileEv->call(); if($projectileEv->isCancelled()){ $projectile->flagForDespawn(); - }else{ - $projectile->spawnToAll(); - - $player->getLevel()->broadcastLevelSoundEvent($player, LevelSoundEventPacket::SOUND_THROW, 0, EntityIds::PLAYER); + return ItemUseResult::fail(); } + $projectile->spawnToAll(); + + $player->getLevel()->broadcastLevelSoundEvent($player, LevelSoundEventPacket::SOUND_THROW, 0, EntityIds::PLAYER); + $this->pop(); - return true; + return ItemUseResult::success(); } } diff --git a/src/pocketmine/item/SpawnEgg.php b/src/pocketmine/item/SpawnEgg.php index 7c7d86d288..3642809283 100644 --- a/src/pocketmine/item/SpawnEgg.php +++ b/src/pocketmine/item/SpawnEgg.php @@ -50,7 +50,7 @@ class SpawnEgg extends Item{ $this->entityClass = $entityClass; } - public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : bool{ + public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ $nbt = EntityFactory::createBaseNBT($blockReplace->add(0.5, 0, 0.5), null, lcg_value() * 360, 0); if($this->hasCustomName()){ @@ -60,6 +60,7 @@ class SpawnEgg extends Item{ $entity = EntityFactory::create($this->entityClass, $player->getLevel(), $nbt); $this->pop(); $entity->spawnToAll(); - return true; + //TODO: what if the entity was marked for deletion? + return ItemUseResult::success(); } } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 4359f1b44e..3ad2f7656e 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -44,6 +44,7 @@ use pocketmine\event\level\SpawnChangeEvent; use pocketmine\event\player\PlayerInteractEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\item\ItemUseResult; use pocketmine\level\biome\Biome; use pocketmine\level\format\Chunk; use pocketmine\level\format\ChunkException; @@ -1798,8 +1799,11 @@ class Level implements ChunkManager, Metadatable{ return true; } - if(!$player->isSneaking() and $item->onActivate($player, $blockReplace, $blockClicked, $face, $clickVector)){ - return true; + if(!$player->isSneaking()){ + $result = $item->onActivate($player, $blockReplace, $blockClicked, $face, $clickVector); + if($result !== ItemUseResult::none()){ + return $result === ItemUseResult::success(); + } } }else{ return false; From 19f0d7f3367c291917721e12d2e5feaf80b71712 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 15 Feb 2019 10:11:31 +0000 Subject: [PATCH 0470/3224] NetworkSession: Don't apply handlers to a disconnected session closes #2756 --- src/pocketmine/network/mcpe/NetworkSession.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 7ec01b79b7..6465646e82 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -166,8 +166,10 @@ class NetworkSession{ } public function setHandler(SessionHandler $handler) : void{ - $this->handler = $handler; - $this->handler->setUp(); + if($this->connected){ //TODO: this is fine since we can't handle anything from a disconnected session, but it might produce surprises in some cases + $this->handler = $handler; + $this->handler->setUp(); + } } /** From 01255c53681268b5dabf119a6236fbac7a2e598f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 15 Feb 2019 12:29:16 +0000 Subject: [PATCH 0471/3224] Updated RakLib to get ITC efficiency enhancements --- composer.lock | 8 ++--- .../network/mcpe/RakLibInterface.php | 30 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/composer.lock b/composer.lock index c41d2a79b3..bfe6aa6555 100644 --- a/composer.lock +++ b/composer.lock @@ -413,12 +413,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "44ebbd68eeb25c07f1d4c1d1af1f7abd5904b76c" + "reference": "2d19bbaa4fb92d9eabe8c027ea0af9dbd6a90100" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/44ebbd68eeb25c07f1d4c1d1af1f7abd5904b76c", - "reference": "44ebbd68eeb25c07f1d4c1d1af1f7abd5904b76c", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/2d19bbaa4fb92d9eabe8c027ea0af9dbd6a90100", + "reference": "2d19bbaa4fb92d9eabe8c027ea0af9dbd6a90100", "shasum": "" }, "require": { @@ -446,7 +446,7 @@ "source": "https://github.com/pmmp/RakLib/tree/master", "issues": "https://github.com/pmmp/RakLib/issues" }, - "time": "2019-01-26T16:51:18+00:00" + "time": "2019-02-15T12:21:28+00:00" }, { "name": "pocketmine/snooze", diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 17d073b84b..c24a84d41b 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -68,7 +68,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ /** @var NetworkSession[] */ private $sessions = []; - /** @var string[] */ + /** @var int[] */ private $identifiers = []; /** @var ServerHandler */ @@ -118,11 +118,11 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ } } - public function closeSession(string $identifier, string $reason) : void{ - if(isset($this->sessions[$identifier])){ - $session = $this->sessions[$identifier]; + public function closeSession(int $sessionId, string $reason) : void{ + if(isset($this->sessions[$sessionId])){ + $session = $this->sessions[$sessionId]; unset($this->identifiers[spl_object_id($session)]); - unset($this->sessions[$identifier]); + unset($this->sessions[$sessionId]); $session->onClientDisconnect($reason); } } @@ -140,19 +140,19 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $this->interface->shutdown(); } - public function openSession(string $identifier, string $address, int $port, int $clientID) : void{ + public function openSession(int $sessionId, string $address, int $port, int $clientID) : void{ $session = new NetworkSession($this->server, $this, $address, $port); - $this->sessions[$identifier] = $session; - $this->identifiers[spl_object_id($session)] = $identifier; + $this->sessions[$sessionId] = $session; + $this->identifiers[spl_object_id($session)] = $sessionId; } - public function handleEncapsulated(string $identifier, EncapsulatedPacket $packet, int $flags) : void{ - if(isset($this->sessions[$identifier])){ + public function handleEncapsulated(int $sessionId, EncapsulatedPacket $packet, int $flags) : void{ + if(isset($this->sessions[$sessionId])){ if($packet->buffer === "" or $packet->buffer{0} !== self::MCPE_RAKNET_PACKET_ID){ return; } //get this now for blocking in case the player was closed before the exception was raised - $session = $this->sessions[$identifier]; + $session = $this->sessions[$sessionId]; $address = $session->getIp(); $port = $session->getPort(); $buf = substr($packet->buffer, 1); @@ -193,7 +193,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $this->interface->addRawPacketFilter($regex); } - public function notifyACK(string $identifier, int $identifierACK) : void{ + public function notifyACK(int $sessionId, int $identifierACK) : void{ } @@ -239,9 +239,9 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ } } - public function updatePing(string $identifier, int $pingMS) : void{ - if(isset($this->sessions[$identifier])){ - $this->sessions[$identifier]->updatePing($pingMS); + public function updatePing(int $sessionId, int $pingMS) : void{ + if(isset($this->sessions[$sessionId])){ + $this->sessions[$sessionId]->updatePing($pingMS); } } } From 65ce1a75810b89f1e692facbcf76fff4841fe7c7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 15 Feb 2019 13:37:57 +0000 Subject: [PATCH 0472/3224] Block: fixed correct-type tiles getting overwritten this manifested by crashing the server whenever someone used a furnace. --- src/pocketmine/block/Block.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index e290d6c4f1..4a8dff988c 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -189,8 +189,9 @@ class Block extends Position implements BlockIds, Metadatable{ $oldTile = $this->level->getTile($this); if($oldTile !== null and ($tileType === null or !($oldTile instanceof $tileType))){ $oldTile->close(); + $oldTile = null; } - if($tileType !== null){ + if($oldTile === null and $tileType !== null){ $this->level->addTile(TileFactory::create($tileType, $this->level, $this->asVector3())); } } From f49d590794f7f0952456766ba42c9a108ec5252d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 15 Feb 2019 16:27:00 +0000 Subject: [PATCH 0473/3224] Level: remove getTiles(), more removal of tiles from user interface --- .../command/defaults/GarbageCollectorCommand.php | 5 +---- .../command/defaults/StatusCommand.php | 3 +-- src/pocketmine/level/Level.php | 16 +--------------- 3 files changed, 3 insertions(+), 21 deletions(-) diff --git a/src/pocketmine/command/defaults/GarbageCollectorCommand.php b/src/pocketmine/command/defaults/GarbageCollectorCommand.php index 7df2d16ed8..6058f160c2 100644 --- a/src/pocketmine/command/defaults/GarbageCollectorCommand.php +++ b/src/pocketmine/command/defaults/GarbageCollectorCommand.php @@ -48,17 +48,15 @@ class GarbageCollectorCommand extends VanillaCommand{ $chunksCollected = 0; $entitiesCollected = 0; - $tilesCollected = 0; $memory = memory_get_usage(); foreach($sender->getServer()->getLevelManager()->getLevels() as $level){ - $diff = [count($level->getChunks()), count($level->getEntities()), count($level->getTiles())]; + $diff = [count($level->getChunks()), count($level->getEntities())]; $level->doChunkGarbageCollection(); $level->unloadChunks(true); $chunksCollected += $diff[0] - count($level->getChunks()); $entitiesCollected += $diff[1] - count($level->getEntities()); - $tilesCollected += $diff[2] - count($level->getTiles()); $level->clearCache(true); } @@ -67,7 +65,6 @@ class GarbageCollectorCommand extends VanillaCommand{ $sender->sendMessage(TextFormat::GREEN . "---- " . TextFormat::WHITE . "Garbage collection result" . TextFormat::GREEN . " ----"); $sender->sendMessage(TextFormat::GOLD . "Chunks: " . TextFormat::RED . number_format($chunksCollected)); $sender->sendMessage(TextFormat::GOLD . "Entities: " . TextFormat::RED . number_format($entitiesCollected)); - $sender->sendMessage(TextFormat::GOLD . "Tiles: " . TextFormat::RED . number_format($tilesCollected)); $sender->sendMessage(TextFormat::GOLD . "Cycles: " . TextFormat::RED . number_format($cyclesCollected)); $sender->sendMessage(TextFormat::GOLD . "Memory freed: " . TextFormat::RED . number_format(round((($memory - memory_get_usage()) / 1024) / 1024, 2), 2) . " MB"); diff --git a/src/pocketmine/command/defaults/StatusCommand.php b/src/pocketmine/command/defaults/StatusCommand.php index d83f380192..96b811b2f2 100644 --- a/src/pocketmine/command/defaults/StatusCommand.php +++ b/src/pocketmine/command/defaults/StatusCommand.php @@ -112,8 +112,7 @@ class StatusCommand extends VanillaCommand{ $tickRate = $level->getTickRate() > 1 ? " (tick rate " . $level->getTickRate() . ")" : ""; $sender->sendMessage(TextFormat::GOLD . "World \"{$level->getFolderName()}\"$levelName: " . TextFormat::RED . number_format(count($level->getChunks())) . TextFormat::GREEN . " chunks, " . - TextFormat::RED . number_format(count($level->getEntities())) . TextFormat::GREEN . " entities, " . - TextFormat::RED . number_format(count($level->getTiles())) . TextFormat::GREEN . " tiles. " . + TextFormat::RED . number_format(count($level->getEntities())) . TextFormat::GREEN . " entities. " . "Time $timeColor" . round($level->getTickRateTime(), 2) . "ms" . $tickRate ); } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 3ad2f7656e..127f2c6a8a 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -133,9 +133,6 @@ class Level implements ChunkManager, Metadatable{ public const DIFFICULTY_NORMAL = 2; public const DIFFICULTY_HARD = 3; - /** @var Tile[] */ - private $tiles = []; - /** @var Player[] */ private $players = []; @@ -2008,16 +2005,6 @@ class Level implements ChunkManager, Metadatable{ return $currentTarget; } - - /** - * Returns a list of the Tile entities in this level - * - * @return Tile[] - */ - public function getTiles() : array{ - return $this->tiles; - } - /** * Returns a list of the players in this level * @@ -2576,7 +2563,6 @@ class Level implements ChunkManager, Metadatable{ throw new \InvalidStateException("Attempted to create tile " . get_class($tile) . " in unloaded chunk $chunkX $chunkZ"); } - $this->tiles[Level::blockHash($tile->x, $tile->y, $tile->z)] = $tile; $tile->scheduleUpdate(); } @@ -2590,7 +2576,7 @@ class Level implements ChunkManager, Metadatable{ throw new \InvalidArgumentException("Invalid Tile level"); } - unset($this->tiles[$blockHash = Level::blockHash($tile->x, $tile->y, $tile->z)], $this->updateTiles[$blockHash]); + unset($this->updateTiles[Level::blockHash($tile->x, $tile->y, $tile->z)]); $chunkX = $tile->getFloorX() >> 4; $chunkZ = $tile->getFloorZ() >> 4; From 0ac7164b16cd3cf2802ed1767552280749d61c19 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 16 Feb 2019 11:54:09 +0000 Subject: [PATCH 0474/3224] Inventory: remove dropContents(), remove circular dependency --- src/pocketmine/inventory/BaseInventory.php | 17 ----------------- src/pocketmine/inventory/Inventory.php | 11 ----------- 2 files changed, 28 deletions(-) diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index 2be0a0ef1e..4ac258e931 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -26,8 +26,6 @@ namespace pocketmine\inventory; use pocketmine\event\inventory\InventoryOpenEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\level\Level; -use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\InventoryContentPacket; use pocketmine\network\mcpe\protocol\InventorySlotPacket; use pocketmine\network\mcpe\protocol\types\ContainerIds; @@ -146,21 +144,6 @@ abstract class BaseInventory implements Inventory{ } } - /** - * Drops the contents of the inventory into the specified Level at the specified position and clears the inventory - * contents. - * - * @param Level $level - * @param Vector3 $position - */ - public function dropContents(Level $level, Vector3 $position) : void{ - foreach($this->getContents() as $item){ - $level->dropItem($position, $item); - } - - $this->clearAll(); - } - public function setItem(int $index, Item $item, bool $send = true) : bool{ if($item->isNull()){ $item = ItemFactory::get(Item::AIR, 0, 0); diff --git a/src/pocketmine/inventory/Inventory.php b/src/pocketmine/inventory/Inventory.php index f605961c19..cf251d03ea 100644 --- a/src/pocketmine/inventory/Inventory.php +++ b/src/pocketmine/inventory/Inventory.php @@ -27,8 +27,6 @@ declare(strict_types=1); namespace pocketmine\inventory; use pocketmine\item\Item; -use pocketmine\level\Level; -use pocketmine\math\Vector3; use pocketmine\Player; interface Inventory{ @@ -122,15 +120,6 @@ interface Inventory{ */ public function setContents(array $items, bool $send = true) : void; - /** - * Drops the contents of the inventory into the specified Level at the specified position and clears the inventory - * contents. - * - * @param Level $level - * @param Vector3 $position - */ - public function dropContents(Level $level, Vector3 $position) : void; - /** * @param Player|Player[] $target */ From b252be1c7a0976a91030f93360eaa17731e1374b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 16 Feb 2019 11:58:08 +0000 Subject: [PATCH 0475/3224] Added ItemFactory::air() sugar This makes it easier to create air stacks without accidents, and also reduces the amount of throwaway air objects which get created. --- src/pocketmine/inventory/BaseInventory.php | 9 ++++----- src/pocketmine/inventory/ShapedRecipe.php | 2 +- .../inventory/transaction/action/DropItemAction.php | 2 +- src/pocketmine/item/FlintSteel.php | 2 +- src/pocketmine/item/Food.php | 2 +- src/pocketmine/item/Item.php | 4 ++-- src/pocketmine/item/ItemFactory.php | 7 +++++++ src/pocketmine/level/Explosion.php | 3 +-- src/pocketmine/level/Level.php | 2 +- src/pocketmine/level/particle/FloatingTextParticle.php | 3 +-- src/pocketmine/tile/FlowerPot.php | 4 ++-- src/pocketmine/tile/ItemFrame.php | 4 ++-- 12 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index 4ac258e931..974ba3b26d 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -95,7 +95,7 @@ abstract class BaseInventory implements Inventory{ } public function getItem(int $index) : Item{ - return $this->slots[$index] !== null ? clone $this->slots[$index] : ItemFactory::get(Item::AIR, 0, 0); + return $this->slots[$index] !== null ? clone $this->slots[$index] : ItemFactory::air(); } /** @@ -105,13 +105,12 @@ abstract class BaseInventory implements Inventory{ */ public function getContents(bool $includeEmpty = false) : array{ $contents = []; - $air = null; foreach($this->slots as $i => $slot){ if($slot !== null){ $contents[$i] = clone $slot; }elseif($includeEmpty){ - $contents[$i] = $air ?? ($air = ItemFactory::get(Item::AIR, 0, 0)); + $contents[$i] = ItemFactory::air(); } } @@ -146,7 +145,7 @@ abstract class BaseInventory implements Inventory{ public function setItem(int $index, Item $item, bool $send = true) : bool{ if($item->isNull()){ - $item = ItemFactory::get(Item::AIR, 0, 0); + $item = ItemFactory::air(); }else{ $item = clone $item; } @@ -351,7 +350,7 @@ abstract class BaseInventory implements Inventory{ } public function clear(int $index, bool $send = true) : bool{ - return $this->setItem($index, ItemFactory::get(Item::AIR, 0, 0), $send); + return $this->setItem($index, ItemFactory::air(), $send); } public function clearAll(bool $send = true) : void{ diff --git a/src/pocketmine/inventory/ShapedRecipe.php b/src/pocketmine/inventory/ShapedRecipe.php index 13eb4b9d1d..16e46d569b 100644 --- a/src/pocketmine/inventory/ShapedRecipe.php +++ b/src/pocketmine/inventory/ShapedRecipe.php @@ -176,7 +176,7 @@ class ShapedRecipe implements CraftingRecipe{ */ public function getIngredient(int $x, int $y) : Item{ $exists = $this->ingredientList[$this->shape[$y]{$x}] ?? null; - return $exists !== null ? clone $exists : ItemFactory::get(Item::AIR, 0, 0); + return $exists !== null ? clone $exists : ItemFactory::air(); } /** diff --git a/src/pocketmine/inventory/transaction/action/DropItemAction.php b/src/pocketmine/inventory/transaction/action/DropItemAction.php index fcbe694d8b..692af129f5 100644 --- a/src/pocketmine/inventory/transaction/action/DropItemAction.php +++ b/src/pocketmine/inventory/transaction/action/DropItemAction.php @@ -34,7 +34,7 @@ use pocketmine\Player; class DropItemAction extends InventoryAction{ public function __construct(Item $targetItem){ - parent::__construct(ItemFactory::get(Item::AIR, 0, 0), $targetItem); + parent::__construct(ItemFactory::air(), $targetItem); } public function isValid(Player $source) : bool{ diff --git a/src/pocketmine/item/FlintSteel.php b/src/pocketmine/item/FlintSteel.php index f36b687fac..bb1d94dfd9 100644 --- a/src/pocketmine/item/FlintSteel.php +++ b/src/pocketmine/item/FlintSteel.php @@ -36,7 +36,7 @@ class FlintSteel extends Tool{ } public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ - if($blockReplace->getId() === self::AIR){ + if($blockReplace->getId() === Block::AIR){ $level = $player->getLevel(); assert($level !== null); $level->setBlock($blockReplace, BlockFactory::get(Block::FIRE)); diff --git a/src/pocketmine/item/Food.php b/src/pocketmine/item/Food.php index 36f4cee4fb..b880280c9a 100644 --- a/src/pocketmine/item/Food.php +++ b/src/pocketmine/item/Food.php @@ -34,7 +34,7 @@ abstract class Food extends Item implements FoodSource{ * @return Item */ public function getResidue(){ - return ItemFactory::get(Item::AIR, 0, 0); + return ItemFactory::air(); } public function getAdditionalEffects() : array{ diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index d877b204ee..743ccb81b5 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -640,7 +640,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return Block */ public function getBlock() : Block{ - return BlockFactory::get(self::AIR); + return BlockFactory::get(Block::AIR); } /** @@ -939,7 +939,7 @@ class Item implements ItemIds, \JsonSerializable{ $item = ItemFactory::fromString($idTag->getValue() . ":$meta"); }catch(\InvalidArgumentException $e){ //TODO: improve error handling - return ItemFactory::get(Item::AIR, 0, 0); + return ItemFactory::air(); } $item->setCount($count); }else{ diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 3b671d65f6..3192cdd7c5 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -47,6 +47,9 @@ class ItemFactory{ /** @var \SplFixedArray */ private static $list = []; + /** @var Item|null */ + private static $air = null; + public static function init(){ self::$list = []; //in case of re-initializing @@ -423,6 +426,10 @@ class ItemFactory{ return $item; } + public static function air() : Item{ + return self::$air ?? (self::$air = self::get(ItemIds::AIR, 0, 0)); + } + /** * Returns whether the specified item ID is already registered in the item factory. * diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index c58ffe0591..2b93386ddd 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -32,7 +32,6 @@ use pocketmine\event\entity\EntityDamageByBlockEvent; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityExplodeEvent; -use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\level\particle\HugeExplodeSeedParticle; use pocketmine\level\utils\SubChunkIteratorManager; @@ -199,7 +198,7 @@ class Explosion{ } - $air = ItemFactory::get(Item::AIR); + $air = ItemFactory::air(); $airBlock = BlockFactory::get(Block::AIR); foreach($this->affectedBlocks as $block){ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 127f2c6a8a..297c067bde 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1674,7 +1674,7 @@ class Level implements ChunkManager, Metadatable{ $affectedBlocks = $target->getAffectedBlocks(); if($item === null){ - $item = ItemFactory::get(Item::AIR, 0, 0); + $item = ItemFactory::air(); } $drops = []; diff --git a/src/pocketmine/level/particle/FloatingTextParticle.php b/src/pocketmine/level/particle/FloatingTextParticle.php index 043e4435ca..e800a1c74b 100644 --- a/src/pocketmine/level/particle/FloatingTextParticle.php +++ b/src/pocketmine/level/particle/FloatingTextParticle.php @@ -26,7 +26,6 @@ namespace pocketmine\level\particle; use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; use pocketmine\entity\Skin; -use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\AddPlayerPacket; @@ -103,7 +102,7 @@ class FloatingTextParticle implements Particle{ $pk->username = $name; $pk->entityRuntimeId = $this->entityId; $pk->position = $pos; //TODO: check offset - $pk->item = ItemFactory::get(Item::AIR, 0, 0); + $pk->item = ItemFactory::air(); $flags = ( 1 << Entity::DATA_FLAG_IMMOBILE diff --git a/src/pocketmine/tile/FlowerPot.php b/src/pocketmine/tile/FlowerPot.php index b8aefefc6c..977391db16 100644 --- a/src/pocketmine/tile/FlowerPot.php +++ b/src/pocketmine/tile/FlowerPot.php @@ -39,7 +39,7 @@ class FlowerPot extends Spawnable{ private $item; public function __construct(Level $level, Vector3 $pos){ - $this->item = ItemFactory::get(Item::AIR, 0, 0); + $this->item = ItemFactory::air(); parent::__construct($level, $pos); } @@ -87,7 +87,7 @@ class FlowerPot extends Spawnable{ } public function removeItem(){ - $this->setItem(ItemFactory::get(Item::AIR, 0, 0)); + $this->setItem(ItemFactory::air()); } public function isEmpty() : bool{ diff --git a/src/pocketmine/tile/ItemFrame.php b/src/pocketmine/tile/ItemFrame.php index a4c5108171..da6d3792fc 100644 --- a/src/pocketmine/tile/ItemFrame.php +++ b/src/pocketmine/tile/ItemFrame.php @@ -42,7 +42,7 @@ class ItemFrame extends Spawnable{ private $itemDropChance = 1.0; public function __construct(Level $level, Vector3 $pos){ - $this->item = ItemFactory::get(Item::AIR, 0, 0); + $this->item = ItemFactory::air(); parent::__construct($level, $pos); } @@ -72,7 +72,7 @@ class ItemFrame extends Spawnable{ if($item !== null and !$item->isNull()){ $this->item = clone $item; }else{ - $this->item = ItemFactory::get(Item::AIR, 0, 0); + $this->item = ItemFactory::air(); } $this->onChanged(); } From 0794c94b4bf181dd2d12ac302f277a73577510cf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 16 Feb 2019 19:53:15 +0000 Subject: [PATCH 0476/3224] Rename BlockWriteBatch -> BlockTransaction --- src/pocketmine/block/Door.php | 8 +++---- src/pocketmine/block/DoublePlant.php | 8 +++---- ...ockWriteBatch.php => BlockTransaction.php} | 18 +++++++------- .../level/generator/object/SpruceTree.php | 6 ++--- .../level/generator/object/Tree.php | 24 +++++++++---------- 5 files changed, 32 insertions(+), 32 deletions(-) rename src/pocketmine/level/{BlockWriteBatch.php => BlockTransaction.php} (88%) diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 424b6a4b3e..361704d909 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -25,7 +25,7 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; -use pocketmine\level\BlockWriteBatch; +use pocketmine\level\BlockTransaction; use pocketmine\level\sound\DoorSound; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; @@ -125,10 +125,10 @@ abstract class Door extends Transparent{ $topHalf = clone $this; $topHalf->top = true; - $write = new BlockWriteBatch(); - $write->addBlock($blockReplace, $this)->addBlock($blockUp, $topHalf); + $transaction = new BlockTransaction(); + $transaction->addBlock($blockReplace, $this)->addBlock($blockUp, $topHalf); - return $write->apply($this->level); + return $transaction->apply($this->level); } return false; diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index c730bf6962..b03e451df2 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\level\BlockWriteBatch; +use pocketmine\level\BlockTransaction; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; @@ -53,9 +53,9 @@ class DoublePlant extends Flowable{ $top = clone $this; $top->top = true; - $write = new BlockWriteBatch(); - $write->addBlock($blockReplace, $this)->addBlock($blockReplace->getSide(Facing::UP), $top); - return $write->apply($this->level); + $transaction = new BlockTransaction(); + $transaction->addBlock($blockReplace, $this)->addBlock($blockReplace->getSide(Facing::UP), $top); + return $transaction->apply($this->level); } return false; diff --git a/src/pocketmine/level/BlockWriteBatch.php b/src/pocketmine/level/BlockTransaction.php similarity index 88% rename from src/pocketmine/level/BlockWriteBatch.php rename to src/pocketmine/level/BlockTransaction.php index 11faaa2bc6..6f58534618 100644 --- a/src/pocketmine/level/BlockWriteBatch.php +++ b/src/pocketmine/level/BlockTransaction.php @@ -27,7 +27,7 @@ use pocketmine\block\Block; use pocketmine\math\Vector3; use pocketmine\utils\Utils; -class BlockWriteBatch{ +class BlockTransaction{ /** @var Block[][][] */ private $blocks = []; @@ -41,7 +41,7 @@ class BlockWriteBatch{ } /** - * Adds a block to the batch at the given position. + * Adds a block to the transaction at the given position. * * @param Vector3 $pos * @param Block $state @@ -68,8 +68,8 @@ class BlockWriteBatch{ } /** - * Reads a block from the given world, masked by the blocks in this writebatch. This can be useful if you want to - * add blocks to the batch that depend on previous blocks should they exist. + * Reads a block from the given world, masked by the blocks in this transaction. This can be useful if you want to + * add blocks to the transaction that depend on previous blocks should they exist. * * @param ChunkManager $world * @param Vector3 $pos @@ -81,7 +81,7 @@ class BlockWriteBatch{ } /** - * @see BlockWriteBatch::fetchBlock() + * @see BlockTransaction::fetchBlock() * * @param ChunkManager $world * @param int $x @@ -95,8 +95,8 @@ class BlockWriteBatch{ } /** - * Validates and attempts to apply the batch to the given world. If any part of the batch fails to validate, no - * changes will be made to the world. + * Validates and attempts to apply the transaction to the given world. If any part of the transaction fails to + * validate, no changes will be made to the world. * * @param ChunkManager $world * @@ -132,7 +132,7 @@ class BlockWriteBatch{ /** * Add a validation predicate which will be used to validate every block. * The callable signature should be the same as the below dummy function. - * @see BlockWriteBatch::dummyValidator() + * @see BlockTransaction::dummyValidator() * * @param callable $validator */ @@ -143,7 +143,7 @@ class BlockWriteBatch{ /** * Dummy function demonstrating the required closure signature for validators. - * @see BlockWriteBatch::addValidator() + * @see BlockTransaction::addValidator() * * @dummy * diff --git a/src/pocketmine/level/generator/object/SpruceTree.php b/src/pocketmine/level/generator/object/SpruceTree.php index f0637f90d5..e6a73f96a2 100644 --- a/src/pocketmine/level/generator/object/SpruceTree.php +++ b/src/pocketmine/level/generator/object/SpruceTree.php @@ -26,7 +26,7 @@ namespace pocketmine\level\generator\object; use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\utils\TreeType; -use pocketmine\level\BlockWriteBatch; +use pocketmine\level\BlockTransaction; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; use function abs; @@ -46,7 +46,7 @@ class SpruceTree extends Tree{ parent::placeObject($level, $x, $y, $z, $random); } - protected function placeCanopy(ChunkManager $level, int $x, int $y, int $z, Random $random, BlockWriteBatch $write) : void{ + protected function placeCanopy(ChunkManager $level, int $x, int $y, int $z, Random $random, BlockTransaction $transaction) : void{ $topSize = $this->treeHeight - (1 + $random->nextBoundedInt(2)); $lRadius = 2 + $random->nextBoundedInt(2); $radius = $random->nextBoundedInt(2); @@ -65,7 +65,7 @@ class SpruceTree extends Tree{ } if(!$level->getBlockAt($xx, $yyy, $zz)->isSolid()){ - $write->addBlockAt($xx, $yyy, $zz, $this->leafBlock); + $transaction->addBlockAt($xx, $yyy, $zz, $this->leafBlock); } } } diff --git a/src/pocketmine/level/generator/object/Tree.php b/src/pocketmine/level/generator/object/Tree.php index 7caad66b20..589f7218c2 100644 --- a/src/pocketmine/level/generator/object/Tree.php +++ b/src/pocketmine/level/generator/object/Tree.php @@ -28,7 +28,7 @@ use pocketmine\block\BlockFactory; use pocketmine\block\Leaves; use pocketmine\block\Sapling; use pocketmine\block\utils\TreeType; -use pocketmine\level\BlockWriteBatch; +use pocketmine\level\BlockTransaction; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; use function abs; @@ -107,29 +107,29 @@ abstract class Tree{ } public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ - $write = new BlockWriteBatch(); - $this->placeTrunk($level, $x, $y, $z, $random, $this->generateChunkHeight($random), $write); - $this->placeCanopy($level, $x, $y, $z, $random, $write); + $transaction = new BlockTransaction(); + $this->placeTrunk($level, $x, $y, $z, $random, $this->generateChunkHeight($random), $transaction); + $this->placeCanopy($level, $x, $y, $z, $random, $transaction); - $write->apply($level); //TODO: handle return value on failure + $transaction->apply($level); //TODO: handle return value on failure } protected function generateChunkHeight(Random $random) : int{ return $this->treeHeight - 1; } - protected function placeTrunk(ChunkManager $level, int $x, int $y, int $z, Random $random, int $trunkHeight, BlockWriteBatch $write) : void{ + protected function placeTrunk(ChunkManager $level, int $x, int $y, int $z, Random $random, int $trunkHeight, BlockTransaction $transaction) : void{ // The base dirt block - $write->addBlockAt($x, $y - 1, $z, BlockFactory::get(Block::DIRT)); + $transaction->addBlockAt($x, $y - 1, $z, BlockFactory::get(Block::DIRT)); for($yy = 0; $yy < $trunkHeight; ++$yy){ - if($this->canOverride($write->fetchBlockAt($level, $x, $y + $yy, $z))){ - $write->addBlockAt($x, $y + $yy, $z, $this->trunkBlock); + if($this->canOverride($transaction->fetchBlockAt($level, $x, $y + $yy, $z))){ + $transaction->addBlockAt($x, $y + $yy, $z, $this->trunkBlock); } } } - protected function placeCanopy(ChunkManager $level, int $x, int $y, int $z, Random $random, BlockWriteBatch $write) : void{ + protected function placeCanopy(ChunkManager $level, int $x, int $y, int $z, Random $random, BlockTransaction $transaction) : void{ for($yy = $y - 3 + $this->treeHeight; $yy <= $y + $this->treeHeight; ++$yy){ $yOff = $yy - ($y + $this->treeHeight); $mid = (int) (1 - $yOff / 2); @@ -140,8 +140,8 @@ abstract class Tree{ if($xOff === $mid and $zOff === $mid and ($yOff === 0 or $random->nextBoundedInt(2) === 0)){ continue; } - if(!$write->fetchBlockAt($level, $xx, $yy, $zz)->isSolid()){ - $write->addBlockAt($xx, $yy, $zz, $this->leafBlock); + if(!$transaction->fetchBlockAt($level, $xx, $yy, $zz)->isSolid()){ + $transaction->addBlockAt($xx, $yy, $zz, $this->leafBlock); } } } From 22a21ecfd643a12ef9121a903919ce14dcdfc218 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 16 Feb 2019 19:57:55 +0000 Subject: [PATCH 0477/3224] BlockTransaction: Take world in constructor --- src/pocketmine/block/Door.php | 4 +-- src/pocketmine/block/DoublePlant.php | 4 +-- src/pocketmine/level/BlockTransaction.php | 32 +++++++++---------- .../level/generator/object/SpruceTree.php | 4 +-- .../level/generator/object/Tree.php | 16 +++++----- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 361704d909..44ef368a67 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -125,10 +125,10 @@ abstract class Door extends Transparent{ $topHalf = clone $this; $topHalf->top = true; - $transaction = new BlockTransaction(); + $transaction = new BlockTransaction($this->level); $transaction->addBlock($blockReplace, $this)->addBlock($blockUp, $topHalf); - return $transaction->apply($this->level); + return $transaction->apply(); } return false; diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index b03e451df2..f25c842ddb 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -53,9 +53,9 @@ class DoublePlant extends Flowable{ $top = clone $this; $top->top = true; - $transaction = new BlockTransaction(); + $transaction = new BlockTransaction($this->level); $transaction->addBlock($blockReplace, $this)->addBlock($blockReplace->getSide(Facing::UP), $top); - return $transaction->apply($this->level); + return $transaction->apply(); } return false; diff --git a/src/pocketmine/level/BlockTransaction.php b/src/pocketmine/level/BlockTransaction.php index 6f58534618..d3aa55fc99 100644 --- a/src/pocketmine/level/BlockTransaction.php +++ b/src/pocketmine/level/BlockTransaction.php @@ -28,13 +28,17 @@ use pocketmine\math\Vector3; use pocketmine\utils\Utils; class BlockTransaction{ + /** @var ChunkManager */ + private $world; + /** @var Block[][][] */ private $blocks = []; /** @var \Closure[] */ private $validators = []; - public function __construct(){ + public function __construct(ChunkManager $world){ + $this->world = $world; $this->addValidator(function(ChunkManager $world, int $x, int $y, int $z) : bool{ return $world->isInWorld($x, $y, $z); }); @@ -71,47 +75,43 @@ class BlockTransaction{ * Reads a block from the given world, masked by the blocks in this transaction. This can be useful if you want to * add blocks to the transaction that depend on previous blocks should they exist. * - * @param ChunkManager $world - * @param Vector3 $pos + * @param Vector3 $pos * * @return Block */ - public function fetchBlock(ChunkManager $world, Vector3 $pos) : Block{ - return $this->fetchBlockAt($world, $pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ()); + public function fetchBlock(Vector3 $pos) : Block{ + return $this->fetchBlockAt($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ()); } /** * @see BlockTransaction::fetchBlock() * - * @param ChunkManager $world - * @param int $x - * @param int $y - * @param int $z + * @param int $x + * @param int $y + * @param int $z * * @return Block */ - public function fetchBlockAt(ChunkManager $world, int $x, int $y, int $z) : Block{ - return $this->blocks[$x][$y][$z] ?? $world->getBlockAt($x, $y, $z); + public function fetchBlockAt(int $x, int $y, int $z) : Block{ + return $this->blocks[$x][$y][$z] ?? $this->world->getBlockAt($x, $y, $z); } /** * Validates and attempts to apply the transaction to the given world. If any part of the transaction fails to * validate, no changes will be made to the world. * - * @param ChunkManager $world - * * @return bool if the application was successful */ - public function apply(ChunkManager $world) : bool{ + public function apply() : bool{ foreach($this->getBlocks() as [$x, $y, $z, $_]){ foreach($this->validators as $validator){ - if(!$validator($world, $x, $y, $z)){ + if(!$validator($this->world, $x, $y, $z)){ return false; } } } foreach($this->getBlocks() as [$x, $y, $z, $block]){ - $world->setBlockAt($x, $y, $z, $block); + $this->world->setBlockAt($x, $y, $z, $block); } return true; } diff --git a/src/pocketmine/level/generator/object/SpruceTree.php b/src/pocketmine/level/generator/object/SpruceTree.php index e6a73f96a2..cb5df458c2 100644 --- a/src/pocketmine/level/generator/object/SpruceTree.php +++ b/src/pocketmine/level/generator/object/SpruceTree.php @@ -46,7 +46,7 @@ class SpruceTree extends Tree{ parent::placeObject($level, $x, $y, $z, $random); } - protected function placeCanopy(ChunkManager $level, int $x, int $y, int $z, Random $random, BlockTransaction $transaction) : void{ + protected function placeCanopy(int $x, int $y, int $z, Random $random, BlockTransaction $transaction) : void{ $topSize = $this->treeHeight - (1 + $random->nextBoundedInt(2)); $lRadius = 2 + $random->nextBoundedInt(2); $radius = $random->nextBoundedInt(2); @@ -64,7 +64,7 @@ class SpruceTree extends Tree{ continue; } - if(!$level->getBlockAt($xx, $yyy, $zz)->isSolid()){ + if(!$transaction->fetchBlockAt($xx, $yyy, $zz)->isSolid()){ $transaction->addBlockAt($xx, $yyy, $zz, $this->leafBlock); } } diff --git a/src/pocketmine/level/generator/object/Tree.php b/src/pocketmine/level/generator/object/Tree.php index 589f7218c2..7074c3b33c 100644 --- a/src/pocketmine/level/generator/object/Tree.php +++ b/src/pocketmine/level/generator/object/Tree.php @@ -107,29 +107,29 @@ abstract class Tree{ } public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ - $transaction = new BlockTransaction(); - $this->placeTrunk($level, $x, $y, $z, $random, $this->generateChunkHeight($random), $transaction); - $this->placeCanopy($level, $x, $y, $z, $random, $transaction); + $transaction = new BlockTransaction($level); + $this->placeTrunk($x, $y, $z, $random, $this->generateChunkHeight($random), $transaction); + $this->placeCanopy($x, $y, $z, $random, $transaction); - $transaction->apply($level); //TODO: handle return value on failure + $transaction->apply(); //TODO: handle return value on failure } protected function generateChunkHeight(Random $random) : int{ return $this->treeHeight - 1; } - protected function placeTrunk(ChunkManager $level, int $x, int $y, int $z, Random $random, int $trunkHeight, BlockTransaction $transaction) : void{ + protected function placeTrunk(int $x, int $y, int $z, Random $random, int $trunkHeight, BlockTransaction $transaction) : void{ // The base dirt block $transaction->addBlockAt($x, $y - 1, $z, BlockFactory::get(Block::DIRT)); for($yy = 0; $yy < $trunkHeight; ++$yy){ - if($this->canOverride($transaction->fetchBlockAt($level, $x, $y + $yy, $z))){ + if($this->canOverride($transaction->fetchBlockAt($x, $y + $yy, $z))){ $transaction->addBlockAt($x, $y + $yy, $z, $this->trunkBlock); } } } - protected function placeCanopy(ChunkManager $level, int $x, int $y, int $z, Random $random, BlockTransaction $transaction) : void{ + protected function placeCanopy(int $x, int $y, int $z, Random $random, BlockTransaction $transaction) : void{ for($yy = $y - 3 + $this->treeHeight; $yy <= $y + $this->treeHeight; ++$yy){ $yOff = $yy - ($y + $this->treeHeight); $mid = (int) (1 - $yOff / 2); @@ -140,7 +140,7 @@ abstract class Tree{ if($xOff === $mid and $zOff === $mid and ($yOff === 0 or $random->nextBoundedInt(2) === 0)){ continue; } - if(!$transaction->fetchBlockAt($level, $xx, $yy, $zz)->isSolid()){ + if(!$transaction->fetchBlockAt($xx, $yy, $zz)->isSolid()){ $transaction->addBlockAt($xx, $yy, $zz, $this->leafBlock); } } From 84cf7c11e66f534f150f5f32d1976b17642fc8bc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 17 Feb 2019 06:01:08 -0500 Subject: [PATCH 0478/3224] Fixed some overlooked returns from dce08b4e88bea4065149d6843d64344f7a25872a --- src/pocketmine/item/PaintingItem.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/item/PaintingItem.php b/src/pocketmine/item/PaintingItem.php index 03c51a14c0..115a462dab 100644 --- a/src/pocketmine/item/PaintingItem.php +++ b/src/pocketmine/item/PaintingItem.php @@ -68,7 +68,7 @@ class PaintingItem extends Item{ } if(empty($motives)){ //No space available - return false; + return ItemUseResult::none(); } /** @var PaintingMotive $motive */ @@ -83,7 +83,7 @@ class PaintingItem extends Item{ $direction = $directions[$face] ?? -1; if($direction === -1){ - return false; + return ItemUseResult::none(); } $nbt = EntityFactory::createBaseNBT($blockReplace, null, $direction * 90, 0); @@ -99,6 +99,6 @@ class PaintingItem extends Item{ $entity->spawnToAll(); $player->getLevel()->broadcastLevelEvent($blockReplace->add(0.5, 0.5, 0.5), LevelEventPacket::EVENT_SOUND_ITEMFRAME_PLACE); //item frame and painting have the same sound - return true; + return ItemUseResult::success(); } } From 7ea1f4fc9102d0a76bb0a2f6479861752827a840 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 17 Feb 2019 11:10:17 +0000 Subject: [PATCH 0479/3224] Sign: fixed merge leftovers from 6424dc9c82e6137c00c178f3322cdb1a931cd82f --- src/pocketmine/tile/Sign.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/tile/Sign.php b/src/pocketmine/tile/Sign.php index 34a035e657..83fa79fa72 100644 --- a/src/pocketmine/tile/Sign.php +++ b/src/pocketmine/tile/Sign.php @@ -84,16 +84,16 @@ class Sign extends Spawnable{ */ public function setText(?string $line1 = "", ?string $line2 = "", ?string $line3 = "", ?string $line4 = "") : void{ if($line1 !== null){ - $this->setLine(0, $line1, false); + $this->setLine(0, $line1); } if($line2 !== null){ - $this->setLine(1, $line2, false); + $this->setLine(1, $line2); } if($line3 !== null){ - $this->setLine(2, $line3, false); + $this->setLine(2, $line3); } if($line4 !== null){ - $this->setLine(3, $line4, false); + $this->setLine(3, $line4); } $this->onChanged(); From 9137eb0757a9129316dce144c41f03bda5506609 Mon Sep 17 00:00:00 2001 From: SOFe Date: Wed, 16 Jan 2019 22:40:35 +0800 Subject: [PATCH 0480/3224] Added Dockerfile --- .docker/Dockerfile | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 .docker/Dockerfile diff --git a/.docker/Dockerfile b/.docker/Dockerfile new file mode 100644 index 0000000000..a8f515d2e1 --- /dev/null +++ b/.docker/Dockerfile @@ -0,0 +1,44 @@ +FROM ubuntu:bionic +MAINTAINER PMMP Team + +EXPOSE 19132/tcp +EXPOSE 19132/udp + +RUN apt-get update && apt-get --no-install-recommends -y install \ + sudo \ + ca-certificates \ + jq \ + curl \ + unzip + +RUN groupadd pocketmine && useradd -r -d /pocketmine -p "" -m -g pocketmine -g sudo pocketmine + +WORKDIR /pocketmine +RUN chown -R pocketmine:pocketmine . + +USER pocketmine +RUN echo Sleeping for 5 minutes to wait for Jenkins build && sleep 300 + +RUN mkdir tmp +RUN curl https://update.pmmp.io/api > tmp/api.json + +RUN jq -r '.php_version' < tmp/api.json > tmp/PHP_VERSION +RUN curl -SsL \ + https://jenkins.pmmp.io/job/PHP-`cat tmp/PHP_VERSION`-Aggregate/lastSuccessfulBuild/artifact/PHP-`cat tmp/PHP_VERSION`-Linux-x86_64.tar.gz | \ + tar zx >/dev/null 2>&1 + +RUN chmod +x bin/php7/bin/php + +RUN sed -i'.bak' "s/date.timezone=.*/date.timezone=$(date +%Z)/" bin/php7/bin/php.ini + +RUN curl -SsLo PocketMine-MP.phar `jq -r '.download_url' < tmp/api.json` + +RUN curl -SsLO https://raw.githubusercontent.com/pmmp/PocketMine-MP/`jq -r '.branch' < tmp/api.json`/start.sh +RUN chmod +x start.sh + +RUN rm -r tmp + +# RUN sudo mkdir /data /plugins +VOLUME ["/data", "/plugins"] +# CMD ./start.sh --no-wizard --enable-ansi --data=/data --plugins=/plugins +CMD sudo chgrp pocketmine /data /plugins -R && sudo chmod g+rw /data /plugins && ./start.sh --no-wizard --enable-ansi --data=/data --plugins=/plugins From 1bc6483608c4eb691c875dba3b5b1110a5eb5154 Mon Sep 17 00:00:00 2001 From: SOFe Date: Sun, 17 Feb 2019 18:10:40 +0000 Subject: [PATCH 0481/3224] Fixed Dockerfile permission issues --- .docker/Dockerfile | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.docker/Dockerfile b/.docker/Dockerfile index a8f515d2e1..19b07ba1ef 100644 --- a/.docker/Dockerfile +++ b/.docker/Dockerfile @@ -11,13 +11,15 @@ RUN apt-get update && apt-get --no-install-recommends -y install \ curl \ unzip -RUN groupadd pocketmine && useradd -r -d /pocketmine -p "" -m -g pocketmine -g sudo pocketmine +RUN groupadd -g 1000 pocketmine && useradd -r -d /pocketmine -p "" -u 1000 -m -g pocketmine -g sudo pocketmine WORKDIR /pocketmine -RUN chown -R pocketmine:pocketmine . +RUN chown -R pocketmine:1000 . USER pocketmine -RUN echo Sleeping for 5 minutes to wait for Jenkins build && sleep 300 +ARG WAIT_JENKINS +ENV WAIT_JENKINS ${WAIT_JENKINS:-wait} +RUN if [ "$WAIT_JENKINS" = "wait" ]; then echo Sleeping for 5 minutes to wait for Jenkins build && sleep 300; fi RUN mkdir tmp RUN curl https://update.pmmp.io/api > tmp/api.json @@ -41,4 +43,4 @@ RUN rm -r tmp # RUN sudo mkdir /data /plugins VOLUME ["/data", "/plugins"] # CMD ./start.sh --no-wizard --enable-ansi --data=/data --plugins=/plugins -CMD sudo chgrp pocketmine /data /plugins -R && sudo chmod g+rw /data /plugins && ./start.sh --no-wizard --enable-ansi --data=/data --plugins=/plugins +CMD bash -c 'sudo chown 1000 /data /plugins -R && ./start.sh --no-wizard --enable-ansi --data=/data --plugins=/plugins' From 00b92eaa40650c74a5ec5cb1f454349491bded86 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 17 Feb 2019 19:44:16 +0000 Subject: [PATCH 0482/3224] BlockFactory: Sort entries lexicographically ascending --- src/pocketmine/block/BlockFactory.php | 527 ++++++++++++-------------- 1 file changed, 239 insertions(+), 288 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index f8a91a1b98..e58ca16f3c 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -75,23 +75,234 @@ class BlockFactory{ self::$stateMasks = new \SplFixedArray(8192); + self::registerBlock(new ActivatorRail()); self::registerBlock(new Air()); - - self::registerBlock(new SmoothStone(Block::STONE, Stone::NORMAL, "Stone")); - - self::registerBlock(new Stone(Block::STONE, Stone::GRANITE, "Granite")); - self::registerBlock(new Stone(Block::STONE, Stone::POLISHED_GRANITE, "Polished Granite")); - self::registerBlock(new Stone(Block::STONE, Stone::DIORITE, "Diorite")); - self::registerBlock(new Stone(Block::STONE, Stone::POLISHED_DIORITE, "Polished Diorite")); - self::registerBlock(new Stone(Block::STONE, Stone::ANDESITE, "Andesite")); - self::registerBlock(new Stone(Block::STONE, Stone::POLISHED_ANDESITE, "Polished Andesite")); - - self::registerBlock(new Grass()); - - self::registerBlock(new Dirt(Block::DIRT, Dirt::NORMAL, "Dirt")); + self::registerBlock(new Anvil(Block::ANVIL, Anvil::TYPE_NORMAL, "Anvil")); + self::registerBlock(new Anvil(Block::ANVIL, Anvil::TYPE_SLIGHTLY_DAMAGED, "Slightly Damaged Anvil")); + self::registerBlock(new Anvil(Block::ANVIL, Anvil::TYPE_VERY_DAMAGED, "Very Damaged Anvil")); + self::registerBlock(new Bed()); + self::registerBlock(new Bedrock()); + self::registerBlock(new Beetroot()); + self::registerBlock(new BoneBlock()); + self::registerBlock(new Bookshelf()); + self::registerBlock(new BrewingStand()); + self::registerBlock(new BrickStairs()); + self::registerBlock(new Bricks()); + self::registerBlock(new BrownMushroom()); + self::registerBlock(new BrownMushroomBlock()); + self::registerBlock(new Cactus()); + self::registerBlock(new Cake()); + self::registerBlock(new Carrot()); + self::registerBlock(new Chest()); + self::registerBlock(new Clay()); + self::registerBlock(new Coal()); + self::registerBlock(new CoalOre()); self::registerBlock(new CoarseDirt(Block::DIRT, Dirt::COARSE, "Coarse Dirt")); - self::registerBlock(new Cobblestone()); + self::registerBlock(new CobblestoneStairs()); + self::registerBlock(new Cobweb()); + self::registerBlock(new CocoaBlock()); + self::registerBlock(new CraftingTable()); + self::registerBlock(new Dandelion()); + self::registerBlock(new DaylightSensor()); + self::registerBlock((new DaylightSensor())->setInverted()); //flattening hack + self::registerBlock(new DeadBush()); + self::registerBlock(new DetectorRail()); + self::registerBlock(new Diamond()); + self::registerBlock(new DiamondOre()); + self::registerBlock(new Dirt(Block::DIRT, Dirt::NORMAL, "Dirt")); + self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 0, "Sunflower")); + self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 1, "Lilac")); + self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 4, "Rose Bush")); + self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 5, "Peony")); + self::registerBlock(new DoubleTallGrass(Block::DOUBLE_PLANT, 2, "Double Tallgrass")); + self::registerBlock(new DoubleTallGrass(Block::DOUBLE_PLANT, 3, "Large Fern")); + self::registerBlock(new Emerald()); + self::registerBlock(new EmeraldOre()); + self::registerBlock(new EnchantingTable()); + self::registerBlock(new EndPortalFrame()); + self::registerBlock(new EndRod()); + self::registerBlock(new EndStone()); + self::registerBlock(new EndStoneBricks()); + self::registerBlock(new EnderChest()); + self::registerBlock(new Farmland()); + self::registerBlock(new FenceGate(Block::ACACIA_FENCE_GATE, 0, "Acacia Fence Gate")); + self::registerBlock(new FenceGate(Block::BIRCH_FENCE_GATE, 0, "Birch Fence Gate")); + self::registerBlock(new FenceGate(Block::DARK_OAK_FENCE_GATE, 0, "Dark Oak Fence Gate")); + self::registerBlock(new FenceGate(Block::JUNGLE_FENCE_GATE, 0, "Jungle Fence Gate")); + self::registerBlock(new FenceGate(Block::OAK_FENCE_GATE, 0, "Oak Fence Gate")); + self::registerBlock(new FenceGate(Block::SPRUCE_FENCE_GATE, 0, "Spruce Fence Gate")); + self::registerBlock(new Fire()); + self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_ALLIUM, "Allium")); + self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_AZURE_BLUET, "Azure Bluet")); + self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_BLUE_ORCHID, "Blue Orchid")); + self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_ORANGE_TULIP, "Orange Tulip")); + self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_OXEYE_DAISY, "Oxeye Daisy")); + self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_PINK_TULIP, "Pink Tulip")); + self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_POPPY, "Poppy")); + self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_RED_TULIP, "Red Tulip")); + self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_WHITE_TULIP, "White Tulip")); + self::registerBlock(new FlowerPot()); + self::registerBlock(new Furnace()); + self::registerBlock((new Furnace())->setLit()); //flattening hack + self::registerBlock(new Glass(Block::GLASS, 0, "Glass")); + self::registerBlock(new GlassPane(Block::GLASS_PANE, 0, "Glass Pane")); + self::registerBlock(new GlazedTerracotta(Block::BLACK_GLAZED_TERRACOTTA, 0, "Black Glazed Terracotta")); + self::registerBlock(new GlazedTerracotta(Block::BLUE_GLAZED_TERRACOTTA, 0, "Blue Glazed Terracotta")); + self::registerBlock(new GlazedTerracotta(Block::BROWN_GLAZED_TERRACOTTA, 0, "Brown Glazed Terracotta")); + self::registerBlock(new GlazedTerracotta(Block::CYAN_GLAZED_TERRACOTTA, 0, "Cyan Glazed Terracotta")); + self::registerBlock(new GlazedTerracotta(Block::GRAY_GLAZED_TERRACOTTA, 0, "Grey Glazed Terracotta")); + self::registerBlock(new GlazedTerracotta(Block::GREEN_GLAZED_TERRACOTTA, 0, "Green Glazed Terracotta")); + self::registerBlock(new GlazedTerracotta(Block::LIGHT_BLUE_GLAZED_TERRACOTTA, 0, "Light Blue Glazed Terracotta")); + self::registerBlock(new GlazedTerracotta(Block::LIME_GLAZED_TERRACOTTA, 0, "Lime Glazed Terracotta")); + self::registerBlock(new GlazedTerracotta(Block::MAGENTA_GLAZED_TERRACOTTA, 0, "Magenta Glazed Terracotta")); + self::registerBlock(new GlazedTerracotta(Block::ORANGE_GLAZED_TERRACOTTA, 0, "Orange Glazed Terracotta")); + self::registerBlock(new GlazedTerracotta(Block::PINK_GLAZED_TERRACOTTA, 0, "Pink Glazed Terracotta")); + self::registerBlock(new GlazedTerracotta(Block::PURPLE_GLAZED_TERRACOTTA, 0, "Purple Glazed Terracotta")); + self::registerBlock(new GlazedTerracotta(Block::RED_GLAZED_TERRACOTTA, 0, "Red Glazed Terracotta")); + self::registerBlock(new GlazedTerracotta(Block::SILVER_GLAZED_TERRACOTTA, 0, "Light Grey Glazed Terracotta")); + self::registerBlock(new GlazedTerracotta(Block::WHITE_GLAZED_TERRACOTTA, 0, "White Glazed Terracotta")); + self::registerBlock(new GlazedTerracotta(Block::YELLOW_GLAZED_TERRACOTTA, 0, "Yellow Glazed Terracotta")); + self::registerBlock(new GlowingObsidian()); + self::registerBlock(new Glowstone()); + self::registerBlock(new Gold()); + self::registerBlock(new GoldOre()); + self::registerBlock(new Grass()); + self::registerBlock(new GrassPath()); + self::registerBlock(new Gravel()); + self::registerBlock(new HardenedClay(Block::HARDENED_CLAY, 0, "Hardened Clay")); + self::registerBlock(new HayBale()); + self::registerBlock(new Ice()); + self::registerBlock(new InfoUpdate(Block::INFO_UPDATE, 0, "update!")); + self::registerBlock(new InfoUpdate(Block::INFO_UPDATE2, 0, "ate!upd")); + self::registerBlock(new InvisibleBedrock()); + self::registerBlock(new Iron()); + self::registerBlock(new IronBars()); + self::registerBlock(new IronDoor()); + self::registerBlock(new IronOre()); + self::registerBlock(new IronTrapdoor()); + self::registerBlock(new ItemFrame()); + self::registerBlock(new Ladder()); + self::registerBlock(new Lapis()); + self::registerBlock(new LapisOre()); + self::registerBlock(new Lava()); + self::registerBlock((new Lava())->setStill()); //flattening hack + self::registerBlock(new Lever()); + self::registerBlock(new LitPumpkin()); + self::registerBlock(new Magma()); + self::registerBlock(new Melon()); + self::registerBlock(new MelonStem()); + self::registerBlock(new MonsterSpawner()); + self::registerBlock(new MossyCobblestone()); + self::registerBlock(new Mycelium()); + self::registerBlock(new NetherBrick(Block::NETHER_BRICK_BLOCK, 0, "Nether Bricks")); + self::registerBlock(new NetherBrick(Block::RED_NETHER_BRICK, 0, "Red Nether Bricks")); + self::registerBlock(new NetherBrickFence()); + self::registerBlock(new NetherBrickStairs()); + self::registerBlock(new NetherQuartzOre()); + self::registerBlock(new NetherReactor()); + self::registerBlock(new NetherWartBlock()); + self::registerBlock(new NetherWartPlant()); + self::registerBlock(new Netherrack()); + self::registerBlock(new NoteBlock()); + self::registerBlock(new Obsidian()); + self::registerBlock(new PackedIce()); + self::registerBlock(new Podzol()); + self::registerBlock(new Potato()); + self::registerBlock(new PoweredRail()); + self::registerBlock(new Prismarine(Block::PRISMARINE, Prismarine::BRICKS, "Prismarine Bricks")); + self::registerBlock(new Prismarine(Block::PRISMARINE, Prismarine::DARK, "Dark Prismarine")); + self::registerBlock(new Prismarine(Block::PRISMARINE, Prismarine::NORMAL, "Prismarine")); + self::registerBlock(new Pumpkin()); + self::registerBlock(new PumpkinStem()); + self::registerBlock(new Purpur(Block::PURPUR_BLOCK, 0, "Purpur Block")); + self::registerBlock(new class(Block::PURPUR_BLOCK, 2, "Purpur Pillar") extends Purpur{ + use PillarRotationTrait; + }); + self::registerBlock(new PurpurStairs()); + self::registerBlock(new Quartz(Block::QUARTZ_BLOCK, Quartz::NORMAL, "Quartz Block")); + self::registerBlock(new class(Block::QUARTZ_BLOCK, Quartz::CHISELED, "Chiseled Quartz Block") extends Quartz{ + use PillarRotationTrait; + }); + self::registerBlock(new class(Block::QUARTZ_BLOCK, Quartz::PILLAR, "Quartz Pillar") extends Quartz{ + use PillarRotationTrait; + }); + self::registerBlock(new QuartzStairs()); + self::registerBlock(new Rail()); + self::registerBlock(new RedMushroom()); + self::registerBlock(new RedMushroomBlock()); + self::registerBlock(new RedSandstoneStairs()); + self::registerBlock(new Redstone()); + self::registerBlock(new RedstoneLamp()); + self::registerBlock((new RedstoneLamp())->setLit()); //flattening hack + self::registerBlock(new RedstoneOre()); + self::registerBlock((new RedstoneOre())->setLit()); //flattening hack + self::registerBlock(new RedstoneRepeater()); + self::registerBlock((new RedstoneRepeater())->setPowered()); + self::registerBlock(new RedstoneTorch()); + self::registerBlock((new RedstoneTorch())->setLit(false)); //flattening hack + self::registerBlock(new RedstoneWire()); + self::registerBlock(new Reserved6(Block::RESERVED6, 0, "reserved6")); + self::registerBlock(new Sand(Block::SAND, 0, "Sand")); + self::registerBlock(new Sand(Block::SAND, 1, "Red Sand")); + self::registerBlock(new SandstoneStairs()); + self::registerBlock(new SeaLantern()); + self::registerBlock(new SignPost()); + self::registerBlock(new Skull()); + self::registerBlock(new SmoothStone(Block::STONE, Stone::NORMAL, "Stone")); + self::registerBlock(new Snow()); + self::registerBlock(new SnowLayer()); + self::registerBlock(new SoulSand()); + self::registerBlock(new Sponge()); + self::registerBlock(new StandingBanner()); + self::registerBlock(new Stone(Block::STONE, Stone::ANDESITE, "Andesite")); + self::registerBlock(new Stone(Block::STONE, Stone::DIORITE, "Diorite")); + self::registerBlock(new Stone(Block::STONE, Stone::GRANITE, "Granite")); + self::registerBlock(new Stone(Block::STONE, Stone::POLISHED_ANDESITE, "Polished Andesite")); + self::registerBlock(new Stone(Block::STONE, Stone::POLISHED_DIORITE, "Polished Diorite")); + self::registerBlock(new Stone(Block::STONE, Stone::POLISHED_GRANITE, "Polished Granite")); + self::registerBlock(new StoneBrickStairs()); + self::registerBlock(new StoneBricks(Block::STONE_BRICKS, StoneBricks::CHISELED, "Chiseled Stone Bricks")); + self::registerBlock(new StoneBricks(Block::STONE_BRICKS, StoneBricks::CRACKED, "Cracked Stone Bricks")); + self::registerBlock(new StoneBricks(Block::STONE_BRICKS, StoneBricks::MOSSY, "Mossy Stone Bricks")); + self::registerBlock(new StoneBricks(Block::STONE_BRICKS, StoneBricks::NORMAL, "Stone Bricks")); + self::registerBlock(new StoneButton()); + self::registerBlock(new StonePressurePlate()); + self::registerBlock(new Stonecutter()); + self::registerBlock(new Sugarcane()); + self::registerBlock(new TNT()); + self::registerBlock(new TallGrass(Block::TALL_GRASS, 0, "Fern")); + self::registerBlock(new TallGrass(Block::TALL_GRASS, 1, "Tall Grass")); + self::registerBlock(new TallGrass(Block::TALL_GRASS, 2, "Fern")); + self::registerBlock(new TallGrass(Block::TALL_GRASS, 3, "Fern")); + self::registerBlock(new Torch()); + self::registerBlock(new Trapdoor()); + self::registerBlock(new TrappedChest()); + self::registerBlock(new Tripwire()); + self::registerBlock(new TripwireHook()); + self::registerBlock(new Vine()); + self::registerBlock(new WallBanner()); + self::registerBlock(new WallSign()); + self::registerBlock(new Water()); + self::registerBlock((new Water())->setStill()); //flattening hack + self::registerBlock(new WaterLily()); + self::registerBlock(new WeightedPressurePlateHeavy()); + self::registerBlock(new WeightedPressurePlateLight()); + self::registerBlock(new Wheat()); + self::registerBlock(new WoodenButton()); + self::registerBlock(new WoodenDoor(Block::ACACIA_DOOR_BLOCK, 0, "Acacia Door", Item::ACACIA_DOOR)); + self::registerBlock(new WoodenDoor(Block::BIRCH_DOOR_BLOCK, 0, "Birch Door", Item::BIRCH_DOOR)); + self::registerBlock(new WoodenDoor(Block::DARK_OAK_DOOR_BLOCK, 0, "Dark Oak Door", Item::DARK_OAK_DOOR)); + self::registerBlock(new WoodenDoor(Block::JUNGLE_DOOR_BLOCK, 0, "Jungle Door", Item::JUNGLE_DOOR)); + self::registerBlock(new WoodenDoor(Block::OAK_DOOR_BLOCK, 0, "Oak Door", Item::OAK_DOOR)); + self::registerBlock(new WoodenDoor(Block::SPRUCE_DOOR_BLOCK, 0, "Spruce Door", Item::SPRUCE_DOOR)); + self::registerBlock(new WoodenPressurePlate()); + self::registerBlock(new WoodenStairs(Block::ACACIA_STAIRS, 0, "Acacia Stairs")); + self::registerBlock(new WoodenStairs(Block::BIRCH_STAIRS, 0, "Birch Stairs")); + self::registerBlock(new WoodenStairs(Block::DARK_OAK_STAIRS, 0, "Dark Oak Stairs")); + self::registerBlock(new WoodenStairs(Block::JUNGLE_STAIRS, 0, "Jungle Stairs")); + self::registerBlock(new WoodenStairs(Block::OAK_STAIRS, 0, "Oak Stairs")); + self::registerBlock(new WoodenStairs(Block::SPRUCE_STAIRS, 0, "Spruce Stairs")); foreach(TreeType::getAll() as $treeType){ $magicNumber = $treeType->getMagicNumber(); @@ -101,29 +312,11 @@ class BlockFactory{ self::registerBlock(new WoodenFence(Block::FENCE, $magicNumber, $name . " Fence")); //TODO: find a better way to deal with this split + self::registerBlock(new Leaves($magicNumber >= 4 ? Block::LEAVES2 : Block::LEAVES, $magicNumber & 0x03, $treeType, $name . " Leaves")); self::registerBlock(new Log($magicNumber >= 4 ? Block::WOOD2 : Block::WOOD, $magicNumber & 0x03, $treeType, $name . " Log")); self::registerBlock(new Wood($magicNumber >= 4 ? Block::WOOD2 : Block::WOOD, ($magicNumber & 0x03) | 0b1100, $treeType, $name . " Wood")); - self::registerBlock(new Leaves($magicNumber >= 4 ? Block::LEAVES2 : Block::LEAVES, $magicNumber & 0x03, $treeType, $name . " Leaves")); } - self::registerBlock(new Bedrock()); - self::registerBlock(new Water()); - self::registerBlock((new Water())->setStill()); //flattening hack - self::registerBlock(new Lava()); - self::registerBlock((new Lava())->setStill()); //flattening hack - - self::registerBlock(new Sand(Block::SAND, 0, "Sand")); - self::registerBlock(new Sand(Block::SAND, 1, "Red Sand")); - - self::registerBlock(new Gravel()); - self::registerBlock(new GoldOre()); - self::registerBlock(new IronOre()); - self::registerBlock(new CoalOre()); - self::registerBlock(new Sponge()); - self::registerBlock(new Glass(Block::GLASS, 0, "Glass")); - self::registerBlock(new LapisOre()); - self::registerBlock(new Lapis()); - static $sandstoneTypes = [ Sandstone::NORMAL => "", Sandstone::CHISELED => "Chiseled ", @@ -134,47 +327,16 @@ class BlockFactory{ self::registerBlock(new Sandstone(Block::RED_SANDSTONE, $variant, $prefix . "Red Sandstone")); } - self::registerBlock(new NoteBlock()); - self::registerBlock(new Bed()); - self::registerBlock(new PoweredRail()); - self::registerBlock(new DetectorRail()); - - self::registerBlock(new Cobweb()); - - self::registerBlock(new TallGrass(Block::TALL_GRASS, 0, "Fern")); - self::registerBlock(new TallGrass(Block::TALL_GRASS, 1, "Tall Grass")); - self::registerBlock(new TallGrass(Block::TALL_GRASS, 2, "Fern")); - self::registerBlock(new TallGrass(Block::TALL_GRASS, 3, "Fern")); - - self::registerBlock(new DeadBush()); - foreach(DyeColor::getAll() as $color){ - self::registerBlock(new Wool(Block::WOOL, $color->getMagicNumber(), $color->getDisplayName() . " Wool")); - self::registerBlock(new HardenedClay(Block::STAINED_CLAY, $color->getMagicNumber(), $color->getDisplayName() . " Stained Clay")); - self::registerBlock(new Glass(Block::STAINED_GLASS, $color->getMagicNumber(), $color->getDisplayName() . " Stained Glass")); - self::registerBlock(new GlassPane(Block::STAINED_GLASS_PANE, $color->getMagicNumber(), $color->getDisplayName() . " Stained Glass Pane")); self::registerBlock(new Carpet(Block::CARPET, $color->getMagicNumber(), $color->getDisplayName() . " Carpet")); self::registerBlock(new Concrete(Block::CONCRETE, $color->getMagicNumber(), $color->getDisplayName() . " Concrete")); self::registerBlock(new ConcretePowder(Block::CONCRETE_POWDER, $color->getMagicNumber(), $color->getDisplayName() . " Concrete Powder")); + self::registerBlock(new Glass(Block::STAINED_GLASS, $color->getMagicNumber(), $color->getDisplayName() . " Stained Glass")); + self::registerBlock(new GlassPane(Block::STAINED_GLASS_PANE, $color->getMagicNumber(), $color->getDisplayName() . " Stained Glass Pane")); + self::registerBlock(new HardenedClay(Block::STAINED_CLAY, $color->getMagicNumber(), $color->getDisplayName() . " Stained Clay")); + self::registerBlock(new Wool(Block::WOOL, $color->getMagicNumber(), $color->getDisplayName() . " Wool")); } - self::registerBlock(new Dandelion()); - - self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_POPPY, "Poppy")); - self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_BLUE_ORCHID, "Blue Orchid")); - self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_ALLIUM, "Allium")); - self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_AZURE_BLUET, "Azure Bluet")); - self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_RED_TULIP, "Red Tulip")); - self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_ORANGE_TULIP, "Orange Tulip")); - self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_WHITE_TULIP, "White Tulip")); - self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_PINK_TULIP, "Pink Tulip")); - self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_OXEYE_DAISY, "Oxeye Daisy")); - - self::registerBlock(new BrownMushroom()); - self::registerBlock(new RedMushroom()); - self::registerBlock(new Gold()); - self::registerBlock(new Iron()); - /** @var Slab[] $slabTypes */ $slabTypes = [ new StoneSlab(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 0, "Stone"), @@ -202,237 +364,26 @@ class BlockFactory{ self::registerBlock(new DoubleSlab($type->getDoubleSlabId(), $type->getId(), $type->getVariant())); } - self::registerBlock(new Bricks()); - self::registerBlock(new TNT()); - self::registerBlock(new Bookshelf()); - self::registerBlock(new MossyCobblestone()); - self::registerBlock(new Obsidian()); - self::registerBlock(new Torch()); - self::registerBlock(new Fire()); - self::registerBlock(new MonsterSpawner()); - self::registerBlock(new WoodenStairs(Block::OAK_STAIRS, 0, "Oak Stairs")); - self::registerBlock(new Chest()); - self::registerBlock(new RedstoneWire()); - self::registerBlock(new DiamondOre()); - self::registerBlock(new Diamond()); - self::registerBlock(new CraftingTable()); - self::registerBlock(new Wheat()); - self::registerBlock(new Farmland()); - - self::registerBlock(new Furnace()); - self::registerBlock((new Furnace())->setLit()); //flattening hack - - self::registerBlock(new SignPost()); - self::registerBlock(new WoodenDoor(Block::OAK_DOOR_BLOCK, 0, "Oak Door", Item::OAK_DOOR)); - self::registerBlock(new Ladder()); - self::registerBlock(new Rail()); - self::registerBlock(new CobblestoneStairs()); - self::registerBlock(new WallSign()); - self::registerBlock(new Lever()); - self::registerBlock(new StonePressurePlate()); - self::registerBlock(new IronDoor()); - self::registerBlock(new WoodenPressurePlate()); - self::registerBlock(new RedstoneOre()); - self::registerBlock((new RedstoneOre())->setLit()); //flattening hack - self::registerBlock(new RedstoneTorch()); - self::registerBlock((new RedstoneTorch())->setLit(false)); //flattening hack - self::registerBlock(new StoneButton()); - self::registerBlock(new SnowLayer()); - self::registerBlock(new Ice()); - self::registerBlock(new Snow()); - self::registerBlock(new Cactus()); - self::registerBlock(new Clay()); - self::registerBlock(new Sugarcane()); - - self::registerBlock(new Pumpkin()); - self::registerBlock(new Netherrack()); - self::registerBlock(new SoulSand()); - self::registerBlock(new Glowstone()); - - self::registerBlock(new LitPumpkin()); - self::registerBlock(new Cake()); - self::registerBlock(new RedstoneRepeater()); - self::registerBlock((new RedstoneRepeater())->setPowered()); - self::registerBlock(new InvisibleBedrock()); - self::registerBlock(new Trapdoor()); - - self::registerBlock(new StoneBricks(Block::STONE_BRICKS, StoneBricks::NORMAL, "Stone Bricks")); - self::registerBlock(new StoneBricks(Block::STONE_BRICKS, StoneBricks::MOSSY, "Mossy Stone Bricks")); - self::registerBlock(new StoneBricks(Block::STONE_BRICKS, StoneBricks::CRACKED, "Cracked Stone Bricks")); - self::registerBlock(new StoneBricks(Block::STONE_BRICKS, StoneBricks::CHISELED, "Chiseled Stone Bricks")); - - self::registerBlock(new BrownMushroomBlock()); - self::registerBlock(new RedMushroomBlock()); - self::registerBlock(new IronBars()); - self::registerBlock(new GlassPane(Block::GLASS_PANE, 0, "Glass Pane")); - self::registerBlock(new Melon()); - self::registerBlock(new PumpkinStem()); - self::registerBlock(new MelonStem()); - self::registerBlock(new Vine()); - self::registerBlock(new FenceGate(Block::OAK_FENCE_GATE, 0, "Oak Fence Gate")); - self::registerBlock(new BrickStairs()); - self::registerBlock(new StoneBrickStairs()); - self::registerBlock(new Mycelium()); - self::registerBlock(new WaterLily()); - self::registerBlock(new NetherBrick(Block::NETHER_BRICK_BLOCK, 0, "Nether Bricks")); - self::registerBlock(new NetherBrickFence()); - self::registerBlock(new NetherBrickStairs()); - self::registerBlock(new NetherWartPlant()); - self::registerBlock(new EnchantingTable()); - self::registerBlock(new BrewingStand()); - - self::registerBlock(new EndPortalFrame()); - self::registerBlock(new EndStone()); - - self::registerBlock(new RedstoneLamp()); - self::registerBlock((new RedstoneLamp())->setLit()); //flattening hack - - self::registerBlock(new ActivatorRail()); - self::registerBlock(new CocoaBlock()); - self::registerBlock(new SandstoneStairs()); - self::registerBlock(new EmeraldOre()); - self::registerBlock(new EnderChest()); - self::registerBlock(new TripwireHook()); - self::registerBlock(new Tripwire()); - self::registerBlock(new Emerald()); - self::registerBlock(new WoodenStairs(Block::SPRUCE_STAIRS, 0, "Spruce Stairs")); - self::registerBlock(new WoodenStairs(Block::BIRCH_STAIRS, 0, "Birch Stairs")); - self::registerBlock(new WoodenStairs(Block::JUNGLE_STAIRS, 0, "Jungle Stairs")); - static $wallTypes = [ - CobblestoneWall::NONE_MOSSY_WALL => "Cobblestone", - CobblestoneWall::MOSSY_WALL => "Mossy Cobblestone", - CobblestoneWall::GRANITE_WALL => "Granite", - CobblestoneWall::DIORITE_WALL => "Diorite", CobblestoneWall::ANDESITE_WALL => "Andesite", - CobblestoneWall::SANDSTONE_WALL => "Sandstone", CobblestoneWall::BRICK_WALL => "Brick", - CobblestoneWall::STONE_BRICK_WALL => "Stone Brick", - CobblestoneWall::MOSSY_STONE_BRICK_WALL => "Mossy Stone Brick", - CobblestoneWall::NETHER_BRICK_WALL => "Nether Brick", + CobblestoneWall::DIORITE_WALL => "Diorite", CobblestoneWall::END_STONE_BRICK_WALL => "End Stone Brick", + CobblestoneWall::GRANITE_WALL => "Granite", + CobblestoneWall::MOSSY_STONE_BRICK_WALL => "Mossy Stone Brick", + CobblestoneWall::MOSSY_WALL => "Mossy Cobblestone", + CobblestoneWall::NETHER_BRICK_WALL => "Nether Brick", + CobblestoneWall::NONE_MOSSY_WALL => "Cobblestone", CobblestoneWall::PRISMARINE_WALL => "Prismarine", + CobblestoneWall::RED_NETHER_BRICK_WALL => "Red Nether Brick", CobblestoneWall::RED_SANDSTONE_WALL => "Red Sandstone", - CobblestoneWall::RED_NETHER_BRICK_WALL => "Red Nether Brick" + CobblestoneWall::SANDSTONE_WALL => "Sandstone", + CobblestoneWall::STONE_BRICK_WALL => "Stone Brick" ]; foreach($wallTypes as $magicNumber => $prefix){ self::registerBlock(new CobblestoneWall(Block::COBBLESTONE_WALL, $magicNumber, $prefix . " Wall")); } - self::registerBlock(new FlowerPot()); - self::registerBlock(new Carrot()); - self::registerBlock(new Potato()); - self::registerBlock(new WoodenButton()); - self::registerBlock(new Skull()); - - self::registerBlock(new Anvil(Block::ANVIL, Anvil::TYPE_NORMAL, "Anvil")); - self::registerBlock(new Anvil(Block::ANVIL, Anvil::TYPE_SLIGHTLY_DAMAGED, "Slightly Damaged Anvil")); - self::registerBlock(new Anvil(Block::ANVIL, Anvil::TYPE_VERY_DAMAGED, "Very Damaged Anvil")); - - self::registerBlock(new TrappedChest()); - self::registerBlock(new WeightedPressurePlateLight()); - self::registerBlock(new WeightedPressurePlateHeavy()); - - self::registerBlock(new DaylightSensor()); - self::registerBlock((new DaylightSensor())->setInverted()); //flattening hack - - self::registerBlock(new Redstone()); - self::registerBlock(new NetherQuartzOre()); - - self::registerBlock(new Quartz(Block::QUARTZ_BLOCK, Quartz::NORMAL, "Quartz Block")); - self::registerBlock(new class(Block::QUARTZ_BLOCK, Quartz::CHISELED, "Chiseled Quartz Block") extends Quartz{ - use PillarRotationTrait; - }); - self::registerBlock(new class(Block::QUARTZ_BLOCK, Quartz::PILLAR, "Quartz Pillar") extends Quartz{ - use PillarRotationTrait; - }); - - self::registerBlock(new Purpur(Block::PURPUR_BLOCK, 0, "Purpur Block")); - self::registerBlock(new class(Block::PURPUR_BLOCK, 2, "Purpur Pillar") extends Purpur{ - use PillarRotationTrait; - }); - - self::registerBlock(new QuartzStairs()); - - self::registerBlock(new WoodenStairs(Block::ACACIA_STAIRS, 0, "Acacia Stairs")); - self::registerBlock(new WoodenStairs(Block::DARK_OAK_STAIRS, 0, "Dark Oak Stairs")); - - self::registerBlock(new IronTrapdoor()); - - self::registerBlock(new Prismarine(Block::PRISMARINE, Prismarine::NORMAL, "Prismarine")); - self::registerBlock(new Prismarine(Block::PRISMARINE, Prismarine::DARK, "Dark Prismarine")); - self::registerBlock(new Prismarine(Block::PRISMARINE, Prismarine::BRICKS, "Prismarine Bricks")); - - self::registerBlock(new SeaLantern()); - self::registerBlock(new HayBale()); - - self::registerBlock(new HardenedClay(Block::HARDENED_CLAY, 0, "Hardened Clay")); - self::registerBlock(new Coal()); - self::registerBlock(new PackedIce()); - - self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 0, "Sunflower")); - self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 1, "Lilac")); - self::registerBlock(new DoubleTallGrass(Block::DOUBLE_PLANT, 2, "Double Tallgrass")); - self::registerBlock(new DoubleTallGrass(Block::DOUBLE_PLANT, 3, "Large Fern")); - self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 4, "Rose Bush")); - self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 5, "Peony")); - - self::registerBlock(new StandingBanner()); - self::registerBlock(new WallBanner()); - - self::registerBlock(new RedSandstoneStairs()); - self::registerBlock(new FenceGate(Block::SPRUCE_FENCE_GATE, 0, "Spruce Fence Gate")); - self::registerBlock(new FenceGate(Block::BIRCH_FENCE_GATE, 0, "Birch Fence Gate")); - self::registerBlock(new FenceGate(Block::JUNGLE_FENCE_GATE, 0, "Jungle Fence Gate")); - self::registerBlock(new FenceGate(Block::DARK_OAK_FENCE_GATE, 0, "Dark Oak Fence Gate")); - self::registerBlock(new FenceGate(Block::ACACIA_FENCE_GATE, 0, "Acacia Fence Gate")); - - self::registerBlock(new WoodenDoor(Block::SPRUCE_DOOR_BLOCK, 0, "Spruce Door", Item::SPRUCE_DOOR)); - self::registerBlock(new WoodenDoor(Block::BIRCH_DOOR_BLOCK, 0, "Birch Door", Item::BIRCH_DOOR)); - self::registerBlock(new WoodenDoor(Block::JUNGLE_DOOR_BLOCK, 0, "Jungle Door", Item::JUNGLE_DOOR)); - self::registerBlock(new WoodenDoor(Block::ACACIA_DOOR_BLOCK, 0, "Acacia Door", Item::ACACIA_DOOR)); - self::registerBlock(new WoodenDoor(Block::DARK_OAK_DOOR_BLOCK, 0, "Dark Oak Door", Item::DARK_OAK_DOOR)); - self::registerBlock(new GrassPath()); - self::registerBlock(new ItemFrame()); - - self::registerBlock(new PurpurStairs()); - - self::registerBlock(new EndStoneBricks()); - self::registerBlock(new EndRod()); - - self::registerBlock(new Magma()); - self::registerBlock(new NetherWartBlock()); - self::registerBlock(new NetherBrick(Block::RED_NETHER_BRICK, 0, "Red Nether Bricks")); - self::registerBlock(new BoneBlock()); - - self::registerBlock(new GlazedTerracotta(Block::PURPLE_GLAZED_TERRACOTTA, 0, "Purple Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::WHITE_GLAZED_TERRACOTTA, 0, "White Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::ORANGE_GLAZED_TERRACOTTA, 0, "Orange Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::MAGENTA_GLAZED_TERRACOTTA, 0, "Magenta Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::LIGHT_BLUE_GLAZED_TERRACOTTA, 0, "Light Blue Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::YELLOW_GLAZED_TERRACOTTA, 0, "Yellow Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::LIME_GLAZED_TERRACOTTA, 0, "Lime Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::PINK_GLAZED_TERRACOTTA, 0, "Pink Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::GRAY_GLAZED_TERRACOTTA, 0, "Grey Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::SILVER_GLAZED_TERRACOTTA, 0, "Light Grey Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::CYAN_GLAZED_TERRACOTTA, 0, "Cyan Glazed Terracotta")); - - self::registerBlock(new GlazedTerracotta(Block::BLUE_GLAZED_TERRACOTTA, 0, "Blue Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::BROWN_GLAZED_TERRACOTTA, 0, "Brown Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::GREEN_GLAZED_TERRACOTTA, 0, "Green Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::RED_GLAZED_TERRACOTTA, 0, "Red Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::BLACK_GLAZED_TERRACOTTA, 0, "Black Glazed Terracotta")); - - self::registerBlock(new Podzol()); - self::registerBlock(new Beetroot()); - self::registerBlock(new Stonecutter()); - self::registerBlock(new GlowingObsidian()); - self::registerBlock(new NetherReactor()); - self::registerBlock(new InfoUpdate(Block::INFO_UPDATE, 0, "update!")); - self::registerBlock(new InfoUpdate(Block::INFO_UPDATE2, 0, "ate!upd")); - - self::registerBlock(new Reserved6(Block::RESERVED6, 0, "reserved6")); - //TODO: minecraft:acacia_button //TODO: minecraft:acacia_pressure_plate //TODO: minecraft:acacia_standing_sign From cd733c658b610e0781f73488e2597d18bb63ce73 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 18 Feb 2019 10:49:17 +0000 Subject: [PATCH 0483/3224] Implement hard glass & hard glass pane --- src/pocketmine/block/BlockFactory.php | 8 +++--- src/pocketmine/block/HardenedGlass.php | 31 ++++++++++++++++++++++ src/pocketmine/block/HardenedGlassPane.php | 31 ++++++++++++++++++++++ 3 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 src/pocketmine/block/HardenedGlass.php create mode 100644 src/pocketmine/block/HardenedGlassPane.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index e58ca16f3c..62e05fed2a 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -171,6 +171,8 @@ class BlockFactory{ self::registerBlock(new GrassPath()); self::registerBlock(new Gravel()); self::registerBlock(new HardenedClay(Block::HARDENED_CLAY, 0, "Hardened Clay")); + self::registerBlock(new HardenedGlass(Block::HARD_GLASS, 0, "Hardened Glass")); + self::registerBlock(new HardenedGlassPane(Block::HARD_GLASS_PANE, 0, "Hardened Glass Pane")); self::registerBlock(new HayBale()); self::registerBlock(new Ice()); self::registerBlock(new InfoUpdate(Block::INFO_UPDATE, 0, "update!")); @@ -334,6 +336,8 @@ class BlockFactory{ self::registerBlock(new Glass(Block::STAINED_GLASS, $color->getMagicNumber(), $color->getDisplayName() . " Stained Glass")); self::registerBlock(new GlassPane(Block::STAINED_GLASS_PANE, $color->getMagicNumber(), $color->getDisplayName() . " Stained Glass Pane")); self::registerBlock(new HardenedClay(Block::STAINED_CLAY, $color->getMagicNumber(), $color->getDisplayName() . " Stained Clay")); + self::registerBlock(new HardenedGlass(Block::HARD_STAINED_GLASS, $color->getMagicNumber(), "Hardened " . $color->getDisplayName() . " Stained Glass")); + self::registerBlock(new HardenedGlassPane(Block::HARD_STAINED_GLASS_PANE, $color->getMagicNumber(), "Hardened " . $color->getDisplayName() . " Stained Glass Pane")); self::registerBlock(new Wool(Block::WOOL, $color->getMagicNumber(), $color->getDisplayName() . " Wool")); } @@ -444,10 +448,6 @@ class BlockFactory{ //TODO: minecraft:frosted_ice //TODO: minecraft:granite_stairs //TODO: minecraft:grindstone - //TODO: minecraft:hard_glass - //TODO: minecraft:hard_glass_pane - //TODO: minecraft:hard_stained_glass - //TODO: minecraft:hard_stained_glass_pane //TODO: minecraft:hopper //TODO: minecraft:jukebox //TODO: minecraft:jungle_button diff --git a/src/pocketmine/block/HardenedGlass.php b/src/pocketmine/block/HardenedGlass.php new file mode 100644 index 0000000000..65548cd2a2 --- /dev/null +++ b/src/pocketmine/block/HardenedGlass.php @@ -0,0 +1,31 @@ + Date: Mon, 18 Feb 2019 11:37:57 +0000 Subject: [PATCH 0484/3224] edu: implement coloured and underwater torches --- src/pocketmine/block/BlockFactory.php | 10 +++++--- src/pocketmine/block/RedstoneTorch.php | 4 +++ src/pocketmine/block/Torch.php | 10 -------- src/pocketmine/block/UnderwaterTorch.php | 31 ++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 14 deletions(-) create mode 100644 src/pocketmine/block/UnderwaterTorch.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 62e05fed2a..5040a5244f 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -277,11 +277,16 @@ class BlockFactory{ self::registerBlock(new TallGrass(Block::TALL_GRASS, 1, "Tall Grass")); self::registerBlock(new TallGrass(Block::TALL_GRASS, 2, "Fern")); self::registerBlock(new TallGrass(Block::TALL_GRASS, 3, "Fern")); - self::registerBlock(new Torch()); + self::registerBlock(new Torch(Block::COLORED_TORCH_BP, 0, "Blue Torch")); + self::registerBlock(new Torch(Block::COLORED_TORCH_BP, 8, "Purple Torch")); + self::registerBlock(new Torch(Block::COLORED_TORCH_RG, 0, "Red Torch")); + self::registerBlock(new Torch(Block::COLORED_TORCH_RG, 8, "Green Torch")); + self::registerBlock(new Torch(Block::TORCH, 0, "Torch")); self::registerBlock(new Trapdoor()); self::registerBlock(new TrappedChest()); self::registerBlock(new Tripwire()); self::registerBlock(new TripwireHook()); + self::registerBlock(new UnderwaterTorch(Block::UNDERWATER_TORCH, 0, "Underwater Torch")); self::registerBlock(new Vine()); self::registerBlock(new WallBanner()); self::registerBlock(new WallSign()); @@ -416,8 +421,6 @@ class BlockFactory{ //TODO: minecraft:chemistry_table //TODO: minecraft:chorus_flower //TODO: minecraft:chorus_plant - //TODO: minecraft:colored_torch_bp - //TODO: minecraft:colored_torch_rg //TODO: minecraft:command_block //TODO: minecraft:conduit //TODO: minecraft:coral @@ -502,7 +505,6 @@ class BlockFactory{ //TODO: minecraft:stripped_spruce_log //TODO: minecraft:structure_block //TODO: minecraft:turtle_egg - //TODO: minecraft:underwater_torch //TODO: minecraft:undyed_shulker_box //TODO: minecraft:unpowered_comparator } diff --git a/src/pocketmine/block/RedstoneTorch.php b/src/pocketmine/block/RedstoneTorch.php index 51b03843ff..b9956e37cc 100644 --- a/src/pocketmine/block/RedstoneTorch.php +++ b/src/pocketmine/block/RedstoneTorch.php @@ -30,6 +30,10 @@ class RedstoneTorch extends Torch{ /** @var bool */ protected $lit = true; + public function __construct(){ + parent::__construct(self::REDSTONE_TORCH, 0, "Redstone Torch", self::REDSTONE_TORCH); + } + public function getId() : int{ return $this->lit ? self::REDSTONE_TORCH : self::UNLIT_REDSTONE_TORCH; } diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index b50ceee6f0..2055f95a21 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -31,15 +31,9 @@ use pocketmine\Player; class Torch extends Flowable{ - protected $id = self::TORCH; - /** @var int */ protected $facing = Facing::UP; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return 6 - $this->facing; } @@ -56,10 +50,6 @@ class Torch extends Flowable{ return 14; } - public function getName() : string{ - return "Torch"; - } - public function onNearbyBlockChange() : void{ $below = $this->getSide(Facing::DOWN); $face = Facing::opposite($this->facing); diff --git a/src/pocketmine/block/UnderwaterTorch.php b/src/pocketmine/block/UnderwaterTorch.php new file mode 100644 index 0000000000..a83a7c44af --- /dev/null +++ b/src/pocketmine/block/UnderwaterTorch.php @@ -0,0 +1,31 @@ + Date: Mon, 18 Feb 2019 13:27:22 +0000 Subject: [PATCH 0485/3224] Block: Derive light filter level based on isTransparent() return this might be dynamic. --- src/pocketmine/block/Block.php | 2 +- src/pocketmine/block/Transparent.php | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 4a8dff988c..947d0d2a1b 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -450,7 +450,7 @@ class Block extends Position implements BlockIds, Metadatable{ * @return int 0-15 */ public function getLightFilter() : int{ - return 15; + return $this->isTransparent() ? 0 : 15; } /** diff --git a/src/pocketmine/block/Transparent.php b/src/pocketmine/block/Transparent.php index 8654cc4004..d079f39f9f 100644 --- a/src/pocketmine/block/Transparent.php +++ b/src/pocketmine/block/Transparent.php @@ -29,8 +29,4 @@ abstract class Transparent extends Block{ public function isTransparent() : bool{ return true; } - - public function getLightFilter() : int{ - return 0; - } } From 8f26c3a2d44047b94e0e143eaea90d4c35106564 Mon Sep 17 00:00:00 2001 From: SalmonDE Date: Mon, 18 Feb 2019 17:31:07 +0100 Subject: [PATCH 0486/3224] Fix bonemeal count not reduced by CocoaBlock (#2773) --- src/pocketmine/block/CocoaBlock.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index 72fdb5a52a..fc82079bbd 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -98,7 +98,12 @@ class CocoaBlock extends Transparent{ if($this->age < 2 and $item->getId() === Item::DYE and $item->getDamage() === 15){ //bone meal $this->age++; $this->level->setBlock($this, $this); + + $item->pop(); + + return true; } + return false; } From 6f7c63e2a81ff644aac59084f53ec8ad748a38f9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 18 Feb 2019 17:40:53 +0000 Subject: [PATCH 0487/3224] ItemFrame: add has-map bit this makes the frame appear to cover the full block instead of the usual size. --- src/pocketmine/block/ItemFrame.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index e8ecfa85bc..c685ea83a9 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -38,21 +38,24 @@ class ItemFrame extends Flowable{ /** @var int */ protected $facing = Facing::NORTH; + /** @var bool */ + protected $hasMap = false; //makes frame appear large if set public function __construct(){ } protected function writeStateToMeta() : int{ - return 5 - $this->facing; + return (5 - $this->facing) | ($this->hasMap ? 0x04 : 0); } public function readStateFromMeta(int $meta) : void{ - $this->facing = BlockDataValidator::readHorizontalFacing(5 - $meta); + $this->facing = BlockDataValidator::readHorizontalFacing(5 - ($meta & 0x03)); + $this->hasMap = ($meta & 0x04) !== 0; } public function getStateBitmask() : int{ - return 0b11; + return 0b111; } protected function getTileClass() : ?string{ From a95ecb3ff9581b94784645fd09eae30f1bf6b3cb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 18 Feb 2019 19:00:58 +0000 Subject: [PATCH 0488/3224] FenceGate: implement in-wall checks --- src/pocketmine/block/FenceGate.php | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index 0914d202da..c378a4ac3a 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -37,18 +37,21 @@ class FenceGate extends Transparent{ protected $open = false; /** @var int */ protected $facing = Facing::NORTH; + /** @var bool */ + protected $inWall = false; protected function writeStateToMeta() : int{ - return Bearing::fromFacing($this->facing) | ($this->open ? 0x04 : 0); + return Bearing::fromFacing($this->facing) | ($this->open ? 0x04 : 0) | ($this->inWall ? 0x08 : 0); } public function readStateFromMeta(int $meta) : void{ $this->facing = BlockDataValidator::readLegacyHorizontalFacing($meta & 0x03); $this->open = ($meta & 0x04) !== 0; + $this->inWall = ($meta & 0x08) !== 0; } public function getStateBitmask() : int{ - return 0b111; + return 0b1111; } public function getHardness() : float{ @@ -68,14 +71,31 @@ class FenceGate extends Transparent{ return AxisAlignedBB::one()->extend(Facing::UP, 0.5)->squash(Facing::axis($this->facing), 6 / 16); } + private function checkInWall() : bool{ + return ( + $this->getSide(Facing::rotateY($this->facing, false)) instanceof CobblestoneWall or + $this->getSide(Facing::rotateY($this->facing, true)) instanceof CobblestoneWall + ); + } + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ $this->facing = $player->getHorizontalFacing(); } + $this->inWall = $this->checkInWall(); + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } + public function onNearbyBlockChange() : void{ + $inWall = $this->checkInWall(); + if($inWall !== $this->inWall){ + $this->inWall = $inWall; + $this->level->setBlock($this, $this); + } + } + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->open = !$this->open; if($this->open and $player !== null){ From 6f4cec6465fb3cc87db2dddab0f1156995683687 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 18 Feb 2019 20:01:50 +0000 Subject: [PATCH 0489/3224] add some blocks introduced in 1.9 --- src/pocketmine/block/BlockFactory.php | 4 ++++ src/pocketmine/block/Flower.php | 2 ++ src/pocketmine/block/Quartz.php | 1 + src/pocketmine/block/Sandstone.php | 3 ++- 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 5040a5244f..e9a2f3c474 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -142,6 +142,8 @@ class BlockFactory{ self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_POPPY, "Poppy")); self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_RED_TULIP, "Red Tulip")); self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_WHITE_TULIP, "White Tulip")); + self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_CORNFLOWER, "Cornflower")); + self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_LILY_OF_THE_VALLEY, "Lily of the Valley")); self::registerBlock(new FlowerPot()); self::registerBlock(new Furnace()); self::registerBlock((new Furnace())->setLit()); //flattening hack @@ -229,6 +231,7 @@ class BlockFactory{ self::registerBlock(new class(Block::QUARTZ_BLOCK, Quartz::PILLAR, "Quartz Pillar") extends Quartz{ use PillarRotationTrait; }); + self::registerBlock(new Quartz(Block::QUARTZ_BLOCK, Quartz::SMOOTH, "Smooth Quartz Block")); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) self::registerBlock(new QuartzStairs()); self::registerBlock(new Rail()); self::registerBlock(new RedMushroom()); @@ -327,6 +330,7 @@ class BlockFactory{ static $sandstoneTypes = [ Sandstone::NORMAL => "", Sandstone::CHISELED => "Chiseled ", + Sandstone::CUT => "Cut ", Sandstone::SMOOTH => "Smooth " ]; foreach($sandstoneTypes as $variant => $prefix){ diff --git a/src/pocketmine/block/Flower.php b/src/pocketmine/block/Flower.php index 4ae18ae68a..8ab6d0b936 100644 --- a/src/pocketmine/block/Flower.php +++ b/src/pocketmine/block/Flower.php @@ -38,6 +38,8 @@ class Flower extends Flowable{ public const TYPE_WHITE_TULIP = 6; public const TYPE_PINK_TULIP = 7; public const TYPE_OXEYE_DAISY = 8; + public const TYPE_CORNFLOWER = 9; + public const TYPE_LILY_OF_THE_VALLEY = 10; public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); diff --git a/src/pocketmine/block/Quartz.php b/src/pocketmine/block/Quartz.php index 926a20a357..e650043832 100644 --- a/src/pocketmine/block/Quartz.php +++ b/src/pocketmine/block/Quartz.php @@ -30,6 +30,7 @@ class Quartz extends Solid{ public const NORMAL = 0; public const CHISELED = 1; public const PILLAR = 2; + public const SMOOTH = 3; public function getHardness() : float{ return 0.8; diff --git a/src/pocketmine/block/Sandstone.php b/src/pocketmine/block/Sandstone.php index 17571564a8..5bcf9b018d 100644 --- a/src/pocketmine/block/Sandstone.php +++ b/src/pocketmine/block/Sandstone.php @@ -29,7 +29,8 @@ class Sandstone extends Solid{ public const NORMAL = 0; public const CHISELED = 1; - public const SMOOTH = 2; + public const CUT = 2; + public const SMOOTH = 3; public function getHardness() : float{ return 0.8; From 6174f1e0ae37619182a9eec39d0562fd4c8a5833 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 18 Feb 2019 20:02:23 +0000 Subject: [PATCH 0490/3224] Pumpkin: fix BC issue, fix lit pumpkin rotation --- src/pocketmine/block/Pumpkin.php | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/pocketmine/block/Pumpkin.php b/src/pocketmine/block/Pumpkin.php index 245996a717..5e48324186 100644 --- a/src/pocketmine/block/Pumpkin.php +++ b/src/pocketmine/block/Pumpkin.php @@ -23,14 +23,36 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; +use pocketmine\item\Item; +use pocketmine\math\Bearing; +use pocketmine\math\Facing; +use pocketmine\math\Vector3; +use pocketmine\Player; + class Pumpkin extends Solid{ protected $id = self::PUMPKIN; + /** @var int */ + protected $facing = Facing::NORTH; + public function __construct(){ } + public function readStateFromMeta(int $meta) : void{ + $this->facing = BlockDataValidator::readLegacyHorizontalFacing($meta & 0x03); + } + + protected function writeStateToMeta() : int{ + return Bearing::fromFacing($this->facing); + } + + public function getStateBitmask() : int{ + return 0b11; + } + public function getHardness() : float{ return 1; } @@ -42,4 +64,11 @@ class Pumpkin extends Solid{ public function getName() : string{ return "Pumpkin"; } + + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + if($player !== null){ + $this->facing = Facing::opposite($player->getHorizontalFacing()); + } + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } } From a4c3ee20b24f58dae38b2b184d8bf8e0f4ea8428 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 19 Feb 2019 09:58:10 +0000 Subject: [PATCH 0491/3224] Extract Fallable into trait + interface Traits are inferior to components in pretty much every aspect imaginable :( --- src/pocketmine/block/Anvil.php | 13 ++++--- src/pocketmine/block/ConcretePowder.php | 9 ++++- src/pocketmine/block/Gravel.php | 9 ++++- src/pocketmine/block/Sand.php | 10 ++++- src/pocketmine/block/utils/Fallable.php | 38 +++++++++++++++++++ .../{Fallable.php => utils/FallableTrait.php} | 38 ++++++++++++------- src/pocketmine/entity/object/FallingBlock.php | 2 +- 7 files changed, 95 insertions(+), 24 deletions(-) create mode 100644 src/pocketmine/block/utils/Fallable.php rename src/pocketmine/block/{Fallable.php => utils/FallableTrait.php} (54%) diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index 1a035b355c..9c7bc8a5c4 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -24,6 +24,8 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\Fallable; +use pocketmine\block\utils\FallableTrait; use pocketmine\inventory\AnvilInventory; use pocketmine\item\Item; use pocketmine\item\TieredTool; @@ -33,7 +35,8 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; -class Anvil extends Fallable{ +class Anvil extends Transparent implements Fallable{ + use FallableTrait; public const TYPE_NORMAL = 0; public const TYPE_SLIGHTLY_DAMAGED = 4; @@ -54,10 +57,6 @@ class Anvil extends Fallable{ return 0b11; } - public function isTransparent() : bool{ - return true; - } - public function getHardness() : float{ return 5; } @@ -92,4 +91,8 @@ class Anvil extends Fallable{ } return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } + + public function tickFalling() : ?Block{ + return null; + } } diff --git a/src/pocketmine/block/ConcretePowder.php b/src/pocketmine/block/ConcretePowder.php index 5eff4ef028..3ff0916121 100644 --- a/src/pocketmine/block/ConcretePowder.php +++ b/src/pocketmine/block/ConcretePowder.php @@ -23,9 +23,14 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\Fallable; +use pocketmine\block\utils\FallableTrait; use pocketmine\math\Facing; -class ConcretePowder extends Fallable{ +class ConcretePowder extends Solid implements Fallable{ + use FallableTrait { + onNearbyBlockChange as protected startFalling; + } public function getHardness() : float{ return 0.5; @@ -39,7 +44,7 @@ class ConcretePowder extends Fallable{ if(($block = $this->checkAdjacentWater()) !== null){ $this->level->setBlock($this, $block); }else{ - parent::onNearbyBlockChange(); + $this->startFalling(); } } diff --git a/src/pocketmine/block/Gravel.php b/src/pocketmine/block/Gravel.php index 14227ff18d..939b0e8017 100644 --- a/src/pocketmine/block/Gravel.php +++ b/src/pocketmine/block/Gravel.php @@ -23,11 +23,14 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\Fallable; +use pocketmine\block\utils\FallableTrait; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use function mt_rand; -class Gravel extends Fallable{ +class Gravel extends Solid implements Fallable{ + use FallableTrait; protected $id = self::GRAVEL; @@ -56,4 +59,8 @@ class Gravel extends Fallable{ return parent::getDropsForCompatibleTool($item); } + + public function tickFalling() : ?Block{ + return null; + } } diff --git a/src/pocketmine/block/Sand.php b/src/pocketmine/block/Sand.php index 6c6a12a7d6..4b45bebce7 100644 --- a/src/pocketmine/block/Sand.php +++ b/src/pocketmine/block/Sand.php @@ -23,7 +23,11 @@ declare(strict_types=1); namespace pocketmine\block; -class Sand extends Fallable{ +use pocketmine\block\utils\Fallable; +use pocketmine\block\utils\FallableTrait; + +class Sand extends Solid implements Fallable{ + use FallableTrait; public function getHardness() : float{ return 0.5; @@ -32,4 +36,8 @@ class Sand extends Fallable{ public function getToolType() : int{ return BlockToolType::TYPE_SHOVEL; } + + public function tickFalling() : ?Block{ + return null; + } } diff --git a/src/pocketmine/block/utils/Fallable.php b/src/pocketmine/block/utils/Fallable.php new file mode 100644 index 0000000000..1eb3cd12d6 --- /dev/null +++ b/src/pocketmine/block/utils/Fallable.php @@ -0,0 +1,38 @@ +getSide(Facing::DOWN); - if($down->getId() === self::AIR or $down instanceof Liquid or $down instanceof Fire){ - $this->level->setBlock($this, BlockFactory::get(Block::AIR)); + $pos = $this->asPosition(); + $down = $pos->level->getBlock($pos->getSide(Facing::DOWN)); + if($down->getId() === Block::AIR or $down instanceof Liquid or $down instanceof Fire){ + $pos->level->setBlock($pos, BlockFactory::get(Block::AIR)); - $nbt = EntityFactory::createBaseNBT($this->add(0.5, 0, 0.5)); + $nbt = EntityFactory::createBaseNBT($pos->add(0.5, 0, 0.5)); $nbt->setInt("TileID", $this->getId()); $nbt->setByte("Data", $this->getDamage()); /** @var FallingBlock $fall */ - $fall = EntityFactory::create(FallingBlock::class, $this->getLevel(), $nbt); + $fall = EntityFactory::create(FallingBlock::class, $pos->getLevel(), $nbt); $fall->spawnToAll(); } } - - /** - * @return null|Block - */ - public function tickFalling() : ?Block{ - return null; - } } diff --git a/src/pocketmine/entity/object/FallingBlock.php b/src/pocketmine/entity/object/FallingBlock.php index 6261110723..c90c9c36eb 100644 --- a/src/pocketmine/entity/object/FallingBlock.php +++ b/src/pocketmine/entity/object/FallingBlock.php @@ -25,7 +25,7 @@ namespace pocketmine\entity\object; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\Fallable; +use pocketmine\block\utils\Fallable; use pocketmine\entity\Entity; use pocketmine\event\entity\EntityBlockChangeEvent; use pocketmine\event\entity\EntityDamageEvent; From bf71ddb0b56b5d6f8bb1b69eb4b250001debaa0a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 19 Feb 2019 10:01:57 +0000 Subject: [PATCH 0492/3224] Snow layers now fall as expected --- src/pocketmine/block/SnowLayer.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index f4ab367659..542d2f7003 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -24,6 +24,8 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\Fallable; +use pocketmine\block\utils\FallableTrait; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; @@ -34,7 +36,8 @@ use pocketmine\Player; use function floor; use function max; -class SnowLayer extends Flowable{ +class SnowLayer extends Flowable implements Fallable{ + use FallableTrait; protected $id = self::SNOW_LAYER; @@ -97,12 +100,6 @@ class SnowLayer extends Flowable{ return false; } - public function onNearbyBlockChange() : void{ - if(!$this->getSide(Facing::DOWN)->isSolid()){ - $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), false); - } - } - public function ticksRandomly() : bool{ return true; } @@ -113,6 +110,10 @@ class SnowLayer extends Flowable{ } } + public function tickFalling() : ?Block{ + return null; + } + public function getDropsForCompatibleTool(Item $item) : array{ return [ ItemFactory::get(Item::SNOWBALL, 0, max(1, (int) floor($this->layers / 2))) From 18f765338c2b199ba73ec27f40c5729e3bfd7a44 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 19 Feb 2019 11:09:07 +0000 Subject: [PATCH 0493/3224] Slab: fixed replacing $blockReplace not creating double slab when not clicking on the replaced block itself --- src/pocketmine/block/Slab.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index ef7950e2f5..d293c2768b 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -88,8 +88,8 @@ abstract class Slab extends Transparent{ } if($blockReplace instanceof Slab and $blockReplace->isSameType($this) and ( - ($blockReplace->top and $clickVector->y <= 0.5) or - (!$blockReplace->top and $clickVector->y >= 0.5) + ($blockReplace->top and ($clickVector->y <= 0.5 or $face === Facing::UP)) or + (!$blockReplace->top and ($clickVector->y >= 0.5 or $face === Facing::DOWN)) )){ //Clicked in empty half of existing slab return $this->level->setBlock($blockReplace, $this->getDouble()); From f351a866536f97a0e35d796cb9bde37b6d0c2634 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 19 Feb 2019 11:14:06 +0000 Subject: [PATCH 0494/3224] Flatten double slabs into Slab pseudo-variant --- src/pocketmine/block/BlockFactory.php | 3 +- src/pocketmine/block/DoubleSlab.php | 79 ------------------------- src/pocketmine/block/Slab.php | 78 +++++++++++++++++------- src/pocketmine/block/utils/SlabType.php | 58 ++++++++++++++++++ 4 files changed, 116 insertions(+), 102 deletions(-) delete mode 100644 src/pocketmine/block/DoubleSlab.php create mode 100644 src/pocketmine/block/utils/SlabType.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index e9a2f3c474..ac892a91d2 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\block\utils\PillarRotationTrait; +use pocketmine\block\utils\SlabType; use pocketmine\block\utils\TreeType; use pocketmine\item\Item; use pocketmine\level\Position; @@ -374,7 +375,7 @@ class BlockFactory{ } foreach($slabTypes as $type){ self::registerBlock($type); - self::registerBlock(new DoubleSlab($type->getDoubleSlabId(), $type->getId(), $type->getVariant())); + self::registerBlock((clone $type)->setSlabType(SlabType::double())); //flattening hack } static $wallTypes = [ diff --git a/src/pocketmine/block/DoubleSlab.php b/src/pocketmine/block/DoubleSlab.php deleted file mode 100644 index 41ad6a0d70..0000000000 --- a/src/pocketmine/block/DoubleSlab.php +++ /dev/null @@ -1,79 +0,0 @@ -singleId = $singleId; - } - - protected function getSingle() : Block{ - return BlockFactory::get($this->singleId, $this->variant); - } - - public function getHardness() : float{ - return $this->getSingle()->getHardness(); - } - - public function getToolType() : int{ - return $this->getSingle()->getToolType(); - } - - public function getToolHarvestLevel() : int{ - return $this->getSingle()->getToolHarvestLevel(); - } - - public function getFlameEncouragement() : int{ - return $this->getSingle()->getFlameEncouragement(); - } - - public function getFlammability() : int{ - return $this->getSingle()->getFlammability(); - } - - public function getName() : string{ - return "Double " . $this->getSingle()->getName(); - } - - public function getDropsForCompatibleTool(Item $item) : array{ - return [ - ItemFactory::get($this->singleId, $this->variant, 2) - ]; - } - - public function isAffectedBySilkTouch() : bool{ - return false; - } - - public function getPickedItem() : Item{ - return ItemFactory::get($this->singleId, $this->getVariant()); - } -} diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index d293c2768b..1b34e5f5d3 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\SlabType; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -33,32 +34,57 @@ abstract class Slab extends Transparent{ /** @var int */ protected $doubleId; - /** @var bool */ - protected $top = false; + /** @var SlabType */ + protected $slabType; public function __construct(int $id, int $doubleId, int $variant = 0, ?string $name = null){ - parent::__construct($id, $variant, $name . " Slab"); + parent::__construct($id, $variant, $name . " Slab", $id); $this->doubleId = $doubleId; + $this->slabType = SlabType::bottom(); + } + + public function getId() : int{ + return $this->slabType === SlabType::double() ? $this->doubleId : parent::getId(); } protected function writeStateToMeta() : int{ - return ($this->top ? 0x08 : 0); + if($this->slabType !== SlabType::double()){ + return ($this->slabType === SlabType::top() ? 0x08 : 0); + } + return 0; } public function readStateFromMeta(int $meta) : void{ - $this->top = ($meta & 0x08) !== 0; + if($this->slabType !== SlabType::double()){ + $this->slabType = ($meta & 0x08) !== 0 ? SlabType::top() : SlabType::bottom(); + } } public function getStateBitmask() : int{ return 0b1000; } - public function getDoubleSlabId() : int{ - return $this->doubleId; + public function isTransparent() : bool{ + return $this->slabType !== SlabType::double(); } - protected function getDouble() : Block{ - return BlockFactory::get($this->doubleId, $this->variant); + /** + * Returns the type of slab block. + * + * @return SlabType + */ + public function getSlabType() : SlabType{ + return $this->slabType; + } + + /** + * @param SlabType $slabType + * + * @return $this + */ + public function setSlabType(SlabType $slabType) : self{ + $this->slabType = $slabType; + return $this; } public function canBePlacedAt(Block $blockReplace, Vector3 $clickVector, int $face, bool $isClickedBlock) : bool{ @@ -66,8 +92,8 @@ abstract class Slab extends Transparent{ return true; } - if($blockReplace instanceof Slab and $blockReplace->isSameType($this)){ - if($blockReplace->top){ //Trying to combine with top slab + if($blockReplace instanceof Slab and $blockReplace->slabType !== SlabType::double() and $blockReplace->isSameType($this)){ + if($blockReplace->slabType === SlabType::top()){ //Trying to combine with top slab return $clickVector->y <= 0.5 or (!$isClickedBlock and $face === Facing::UP); }else{ return $clickVector->y >= 0.5 or (!$isClickedBlock and $face === Facing::DOWN); @@ -80,27 +106,35 @@ abstract class Slab extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ /* note these conditions can't be merged, since one targets clicked and the other replace */ - if($blockClicked instanceof Slab and $blockClicked->isSameType($this) and ( - ($face === Facing::DOWN and $blockClicked->top) or //Bottom face of top slab - ($face === Facing::UP and !$blockClicked->top) //Top face of bottom slab + if($blockClicked instanceof Slab and $blockClicked->slabType !== SlabType::double() and $blockClicked->isSameType($this) and ( + ($face === Facing::DOWN and $blockClicked->slabType === SlabType::top()) or + ($face === Facing::UP and $blockClicked->slabType === SlabType::bottom()) )){ - return $this->level->setBlock($blockClicked, $this->getDouble()); + $this->slabType = SlabType::double(); + return $this->level->setBlock($blockClicked, $this); } - if($blockReplace instanceof Slab and $blockReplace->isSameType($this) and ( - ($blockReplace->top and ($clickVector->y <= 0.5 or $face === Facing::UP)) or - (!$blockReplace->top and ($clickVector->y >= 0.5 or $face === Facing::DOWN)) + if($blockReplace instanceof Slab and $blockReplace->slabType !== SlabType::double() and $blockReplace->isSameType($this) and ( + ($blockReplace->slabType === SlabType::top() and ($clickVector->y <= 0.5 or $face === Facing::UP)) or + ($blockReplace->slabType === SlabType::bottom() and ($clickVector->y >= 0.5 or $face === Facing::DOWN)) )){ //Clicked in empty half of existing slab - return $this->level->setBlock($blockReplace, $this->getDouble()); + $this->slabType = SlabType::double(); + }else{ + $this->slabType = (($face !== Facing::UP && $clickVector->y > 0.5) || $face === Facing::DOWN) ? SlabType::top() : SlabType::bottom(); } - $this->top = ($face !== Facing::UP && $clickVector->y > 0.5) || $face === Facing::DOWN; - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one()->trim($this->top ? Facing::DOWN : Facing::UP, 0.5); + if($this->slabType === SlabType::double()){ + return parent::recalculateBoundingBox(); + } + return AxisAlignedBB::one()->trim($this->slabType === SlabType::top() ? Facing::DOWN : Facing::UP, 0.5); + } + + public function getDropsForCompatibleTool(Item $item) : array{ + return [$this->getItem()->setCount($this->slabType === SlabType::double() ? 2 : 1)]; } } diff --git a/src/pocketmine/block/utils/SlabType.php b/src/pocketmine/block/utils/SlabType.php new file mode 100644 index 0000000000..e3ba9d0402 --- /dev/null +++ b/src/pocketmine/block/utils/SlabType.php @@ -0,0 +1,58 @@ +name = $name; + } + + public function getName() : string{ + return $this->name; + } +} From 88c4b836f09278a2d81a14356ff3c29ce465de1d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Feb 2019 10:24:44 +0000 Subject: [PATCH 0495/3224] Make factory register methods less verbose --- src/pocketmine/block/BlockFactory.php | 506 +++++++++++++------------- src/pocketmine/item/ItemFactory.php | 366 +++++++++---------- 2 files changed, 436 insertions(+), 436 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index ac892a91d2..77761361e4 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -76,256 +76,256 @@ class BlockFactory{ self::$stateMasks = new \SplFixedArray(8192); - self::registerBlock(new ActivatorRail()); - self::registerBlock(new Air()); - self::registerBlock(new Anvil(Block::ANVIL, Anvil::TYPE_NORMAL, "Anvil")); - self::registerBlock(new Anvil(Block::ANVIL, Anvil::TYPE_SLIGHTLY_DAMAGED, "Slightly Damaged Anvil")); - self::registerBlock(new Anvil(Block::ANVIL, Anvil::TYPE_VERY_DAMAGED, "Very Damaged Anvil")); - self::registerBlock(new Bed()); - self::registerBlock(new Bedrock()); - self::registerBlock(new Beetroot()); - self::registerBlock(new BoneBlock()); - self::registerBlock(new Bookshelf()); - self::registerBlock(new BrewingStand()); - self::registerBlock(new BrickStairs()); - self::registerBlock(new Bricks()); - self::registerBlock(new BrownMushroom()); - self::registerBlock(new BrownMushroomBlock()); - self::registerBlock(new Cactus()); - self::registerBlock(new Cake()); - self::registerBlock(new Carrot()); - self::registerBlock(new Chest()); - self::registerBlock(new Clay()); - self::registerBlock(new Coal()); - self::registerBlock(new CoalOre()); - self::registerBlock(new CoarseDirt(Block::DIRT, Dirt::COARSE, "Coarse Dirt")); - self::registerBlock(new Cobblestone()); - self::registerBlock(new CobblestoneStairs()); - self::registerBlock(new Cobweb()); - self::registerBlock(new CocoaBlock()); - self::registerBlock(new CraftingTable()); - self::registerBlock(new Dandelion()); - self::registerBlock(new DaylightSensor()); - self::registerBlock((new DaylightSensor())->setInverted()); //flattening hack - self::registerBlock(new DeadBush()); - self::registerBlock(new DetectorRail()); - self::registerBlock(new Diamond()); - self::registerBlock(new DiamondOre()); - self::registerBlock(new Dirt(Block::DIRT, Dirt::NORMAL, "Dirt")); - self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 0, "Sunflower")); - self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 1, "Lilac")); - self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 4, "Rose Bush")); - self::registerBlock(new DoublePlant(Block::DOUBLE_PLANT, 5, "Peony")); - self::registerBlock(new DoubleTallGrass(Block::DOUBLE_PLANT, 2, "Double Tallgrass")); - self::registerBlock(new DoubleTallGrass(Block::DOUBLE_PLANT, 3, "Large Fern")); - self::registerBlock(new Emerald()); - self::registerBlock(new EmeraldOre()); - self::registerBlock(new EnchantingTable()); - self::registerBlock(new EndPortalFrame()); - self::registerBlock(new EndRod()); - self::registerBlock(new EndStone()); - self::registerBlock(new EndStoneBricks()); - self::registerBlock(new EnderChest()); - self::registerBlock(new Farmland()); - self::registerBlock(new FenceGate(Block::ACACIA_FENCE_GATE, 0, "Acacia Fence Gate")); - self::registerBlock(new FenceGate(Block::BIRCH_FENCE_GATE, 0, "Birch Fence Gate")); - self::registerBlock(new FenceGate(Block::DARK_OAK_FENCE_GATE, 0, "Dark Oak Fence Gate")); - self::registerBlock(new FenceGate(Block::JUNGLE_FENCE_GATE, 0, "Jungle Fence Gate")); - self::registerBlock(new FenceGate(Block::OAK_FENCE_GATE, 0, "Oak Fence Gate")); - self::registerBlock(new FenceGate(Block::SPRUCE_FENCE_GATE, 0, "Spruce Fence Gate")); - self::registerBlock(new Fire()); - self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_ALLIUM, "Allium")); - self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_AZURE_BLUET, "Azure Bluet")); - self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_BLUE_ORCHID, "Blue Orchid")); - self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_ORANGE_TULIP, "Orange Tulip")); - self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_OXEYE_DAISY, "Oxeye Daisy")); - self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_PINK_TULIP, "Pink Tulip")); - self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_POPPY, "Poppy")); - self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_RED_TULIP, "Red Tulip")); - self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_WHITE_TULIP, "White Tulip")); - self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_CORNFLOWER, "Cornflower")); - self::registerBlock(new Flower(Block::RED_FLOWER, Flower::TYPE_LILY_OF_THE_VALLEY, "Lily of the Valley")); - self::registerBlock(new FlowerPot()); - self::registerBlock(new Furnace()); - self::registerBlock((new Furnace())->setLit()); //flattening hack - self::registerBlock(new Glass(Block::GLASS, 0, "Glass")); - self::registerBlock(new GlassPane(Block::GLASS_PANE, 0, "Glass Pane")); - self::registerBlock(new GlazedTerracotta(Block::BLACK_GLAZED_TERRACOTTA, 0, "Black Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::BLUE_GLAZED_TERRACOTTA, 0, "Blue Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::BROWN_GLAZED_TERRACOTTA, 0, "Brown Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::CYAN_GLAZED_TERRACOTTA, 0, "Cyan Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::GRAY_GLAZED_TERRACOTTA, 0, "Grey Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::GREEN_GLAZED_TERRACOTTA, 0, "Green Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::LIGHT_BLUE_GLAZED_TERRACOTTA, 0, "Light Blue Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::LIME_GLAZED_TERRACOTTA, 0, "Lime Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::MAGENTA_GLAZED_TERRACOTTA, 0, "Magenta Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::ORANGE_GLAZED_TERRACOTTA, 0, "Orange Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::PINK_GLAZED_TERRACOTTA, 0, "Pink Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::PURPLE_GLAZED_TERRACOTTA, 0, "Purple Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::RED_GLAZED_TERRACOTTA, 0, "Red Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::SILVER_GLAZED_TERRACOTTA, 0, "Light Grey Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::WHITE_GLAZED_TERRACOTTA, 0, "White Glazed Terracotta")); - self::registerBlock(new GlazedTerracotta(Block::YELLOW_GLAZED_TERRACOTTA, 0, "Yellow Glazed Terracotta")); - self::registerBlock(new GlowingObsidian()); - self::registerBlock(new Glowstone()); - self::registerBlock(new Gold()); - self::registerBlock(new GoldOre()); - self::registerBlock(new Grass()); - self::registerBlock(new GrassPath()); - self::registerBlock(new Gravel()); - self::registerBlock(new HardenedClay(Block::HARDENED_CLAY, 0, "Hardened Clay")); - self::registerBlock(new HardenedGlass(Block::HARD_GLASS, 0, "Hardened Glass")); - self::registerBlock(new HardenedGlassPane(Block::HARD_GLASS_PANE, 0, "Hardened Glass Pane")); - self::registerBlock(new HayBale()); - self::registerBlock(new Ice()); - self::registerBlock(new InfoUpdate(Block::INFO_UPDATE, 0, "update!")); - self::registerBlock(new InfoUpdate(Block::INFO_UPDATE2, 0, "ate!upd")); - self::registerBlock(new InvisibleBedrock()); - self::registerBlock(new Iron()); - self::registerBlock(new IronBars()); - self::registerBlock(new IronDoor()); - self::registerBlock(new IronOre()); - self::registerBlock(new IronTrapdoor()); - self::registerBlock(new ItemFrame()); - self::registerBlock(new Ladder()); - self::registerBlock(new Lapis()); - self::registerBlock(new LapisOre()); - self::registerBlock(new Lava()); - self::registerBlock((new Lava())->setStill()); //flattening hack - self::registerBlock(new Lever()); - self::registerBlock(new LitPumpkin()); - self::registerBlock(new Magma()); - self::registerBlock(new Melon()); - self::registerBlock(new MelonStem()); - self::registerBlock(new MonsterSpawner()); - self::registerBlock(new MossyCobblestone()); - self::registerBlock(new Mycelium()); - self::registerBlock(new NetherBrick(Block::NETHER_BRICK_BLOCK, 0, "Nether Bricks")); - self::registerBlock(new NetherBrick(Block::RED_NETHER_BRICK, 0, "Red Nether Bricks")); - self::registerBlock(new NetherBrickFence()); - self::registerBlock(new NetherBrickStairs()); - self::registerBlock(new NetherQuartzOre()); - self::registerBlock(new NetherReactor()); - self::registerBlock(new NetherWartBlock()); - self::registerBlock(new NetherWartPlant()); - self::registerBlock(new Netherrack()); - self::registerBlock(new NoteBlock()); - self::registerBlock(new Obsidian()); - self::registerBlock(new PackedIce()); - self::registerBlock(new Podzol()); - self::registerBlock(new Potato()); - self::registerBlock(new PoweredRail()); - self::registerBlock(new Prismarine(Block::PRISMARINE, Prismarine::BRICKS, "Prismarine Bricks")); - self::registerBlock(new Prismarine(Block::PRISMARINE, Prismarine::DARK, "Dark Prismarine")); - self::registerBlock(new Prismarine(Block::PRISMARINE, Prismarine::NORMAL, "Prismarine")); - self::registerBlock(new Pumpkin()); - self::registerBlock(new PumpkinStem()); - self::registerBlock(new Purpur(Block::PURPUR_BLOCK, 0, "Purpur Block")); - self::registerBlock(new class(Block::PURPUR_BLOCK, 2, "Purpur Pillar") extends Purpur{ + self::register(new ActivatorRail()); + self::register(new Air()); + self::register(new Anvil(Block::ANVIL, Anvil::TYPE_NORMAL, "Anvil")); + self::register(new Anvil(Block::ANVIL, Anvil::TYPE_SLIGHTLY_DAMAGED, "Slightly Damaged Anvil")); + self::register(new Anvil(Block::ANVIL, Anvil::TYPE_VERY_DAMAGED, "Very Damaged Anvil")); + self::register(new Bed()); + self::register(new Bedrock()); + self::register(new Beetroot()); + self::register(new BoneBlock()); + self::register(new Bookshelf()); + self::register(new BrewingStand()); + self::register(new BrickStairs()); + self::register(new Bricks()); + self::register(new BrownMushroom()); + self::register(new BrownMushroomBlock()); + self::register(new Cactus()); + self::register(new Cake()); + self::register(new Carrot()); + self::register(new Chest()); + self::register(new Clay()); + self::register(new Coal()); + self::register(new CoalOre()); + self::register(new CoarseDirt(Block::DIRT, Dirt::COARSE, "Coarse Dirt")); + self::register(new Cobblestone()); + self::register(new CobblestoneStairs()); + self::register(new Cobweb()); + self::register(new CocoaBlock()); + self::register(new CraftingTable()); + self::register(new Dandelion()); + self::register(new DaylightSensor()); + self::register((new DaylightSensor())->setInverted()); //flattening hack + self::register(new DeadBush()); + self::register(new DetectorRail()); + self::register(new Diamond()); + self::register(new DiamondOre()); + self::register(new Dirt(Block::DIRT, Dirt::NORMAL, "Dirt")); + self::register(new DoublePlant(Block::DOUBLE_PLANT, 0, "Sunflower")); + self::register(new DoublePlant(Block::DOUBLE_PLANT, 1, "Lilac")); + self::register(new DoublePlant(Block::DOUBLE_PLANT, 4, "Rose Bush")); + self::register(new DoublePlant(Block::DOUBLE_PLANT, 5, "Peony")); + self::register(new DoubleTallGrass(Block::DOUBLE_PLANT, 2, "Double Tallgrass")); + self::register(new DoubleTallGrass(Block::DOUBLE_PLANT, 3, "Large Fern")); + self::register(new Emerald()); + self::register(new EmeraldOre()); + self::register(new EnchantingTable()); + self::register(new EndPortalFrame()); + self::register(new EndRod()); + self::register(new EndStone()); + self::register(new EndStoneBricks()); + self::register(new EnderChest()); + self::register(new Farmland()); + self::register(new FenceGate(Block::ACACIA_FENCE_GATE, 0, "Acacia Fence Gate")); + self::register(new FenceGate(Block::BIRCH_FENCE_GATE, 0, "Birch Fence Gate")); + self::register(new FenceGate(Block::DARK_OAK_FENCE_GATE, 0, "Dark Oak Fence Gate")); + self::register(new FenceGate(Block::JUNGLE_FENCE_GATE, 0, "Jungle Fence Gate")); + self::register(new FenceGate(Block::OAK_FENCE_GATE, 0, "Oak Fence Gate")); + self::register(new FenceGate(Block::SPRUCE_FENCE_GATE, 0, "Spruce Fence Gate")); + self::register(new Fire()); + self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_ALLIUM, "Allium")); + self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_AZURE_BLUET, "Azure Bluet")); + self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_BLUE_ORCHID, "Blue Orchid")); + self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_ORANGE_TULIP, "Orange Tulip")); + self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_OXEYE_DAISY, "Oxeye Daisy")); + self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_PINK_TULIP, "Pink Tulip")); + self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_POPPY, "Poppy")); + self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_RED_TULIP, "Red Tulip")); + self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_WHITE_TULIP, "White Tulip")); + self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_CORNFLOWER, "Cornflower")); + self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_LILY_OF_THE_VALLEY, "Lily of the Valley")); + self::register(new FlowerPot()); + self::register(new Furnace()); + self::register((new Furnace())->setLit()); //flattening hack + self::register(new Glass(Block::GLASS, 0, "Glass")); + self::register(new GlassPane(Block::GLASS_PANE, 0, "Glass Pane")); + self::register(new GlazedTerracotta(Block::BLACK_GLAZED_TERRACOTTA, 0, "Black Glazed Terracotta")); + self::register(new GlazedTerracotta(Block::BLUE_GLAZED_TERRACOTTA, 0, "Blue Glazed Terracotta")); + self::register(new GlazedTerracotta(Block::BROWN_GLAZED_TERRACOTTA, 0, "Brown Glazed Terracotta")); + self::register(new GlazedTerracotta(Block::CYAN_GLAZED_TERRACOTTA, 0, "Cyan Glazed Terracotta")); + self::register(new GlazedTerracotta(Block::GRAY_GLAZED_TERRACOTTA, 0, "Grey Glazed Terracotta")); + self::register(new GlazedTerracotta(Block::GREEN_GLAZED_TERRACOTTA, 0, "Green Glazed Terracotta")); + self::register(new GlazedTerracotta(Block::LIGHT_BLUE_GLAZED_TERRACOTTA, 0, "Light Blue Glazed Terracotta")); + self::register(new GlazedTerracotta(Block::LIME_GLAZED_TERRACOTTA, 0, "Lime Glazed Terracotta")); + self::register(new GlazedTerracotta(Block::MAGENTA_GLAZED_TERRACOTTA, 0, "Magenta Glazed Terracotta")); + self::register(new GlazedTerracotta(Block::ORANGE_GLAZED_TERRACOTTA, 0, "Orange Glazed Terracotta")); + self::register(new GlazedTerracotta(Block::PINK_GLAZED_TERRACOTTA, 0, "Pink Glazed Terracotta")); + self::register(new GlazedTerracotta(Block::PURPLE_GLAZED_TERRACOTTA, 0, "Purple Glazed Terracotta")); + self::register(new GlazedTerracotta(Block::RED_GLAZED_TERRACOTTA, 0, "Red Glazed Terracotta")); + self::register(new GlazedTerracotta(Block::SILVER_GLAZED_TERRACOTTA, 0, "Light Grey Glazed Terracotta")); + self::register(new GlazedTerracotta(Block::WHITE_GLAZED_TERRACOTTA, 0, "White Glazed Terracotta")); + self::register(new GlazedTerracotta(Block::YELLOW_GLAZED_TERRACOTTA, 0, "Yellow Glazed Terracotta")); + self::register(new GlowingObsidian()); + self::register(new Glowstone()); + self::register(new Gold()); + self::register(new GoldOre()); + self::register(new Grass()); + self::register(new GrassPath()); + self::register(new Gravel()); + self::register(new HardenedClay(Block::HARDENED_CLAY, 0, "Hardened Clay")); + self::register(new HardenedGlass(Block::HARD_GLASS, 0, "Hardened Glass")); + self::register(new HardenedGlassPane(Block::HARD_GLASS_PANE, 0, "Hardened Glass Pane")); + self::register(new HayBale()); + self::register(new Ice()); + self::register(new InfoUpdate(Block::INFO_UPDATE, 0, "update!")); + self::register(new InfoUpdate(Block::INFO_UPDATE2, 0, "ate!upd")); + self::register(new InvisibleBedrock()); + self::register(new Iron()); + self::register(new IronBars()); + self::register(new IronDoor()); + self::register(new IronOre()); + self::register(new IronTrapdoor()); + self::register(new ItemFrame()); + self::register(new Ladder()); + self::register(new Lapis()); + self::register(new LapisOre()); + self::register(new Lava()); + self::register((new Lava())->setStill()); //flattening hack + self::register(new Lever()); + self::register(new LitPumpkin()); + self::register(new Magma()); + self::register(new Melon()); + self::register(new MelonStem()); + self::register(new MonsterSpawner()); + self::register(new MossyCobblestone()); + self::register(new Mycelium()); + self::register(new NetherBrick(Block::NETHER_BRICK_BLOCK, 0, "Nether Bricks")); + self::register(new NetherBrick(Block::RED_NETHER_BRICK, 0, "Red Nether Bricks")); + self::register(new NetherBrickFence()); + self::register(new NetherBrickStairs()); + self::register(new NetherQuartzOre()); + self::register(new NetherReactor()); + self::register(new NetherWartBlock()); + self::register(new NetherWartPlant()); + self::register(new Netherrack()); + self::register(new NoteBlock()); + self::register(new Obsidian()); + self::register(new PackedIce()); + self::register(new Podzol()); + self::register(new Potato()); + self::register(new PoweredRail()); + self::register(new Prismarine(Block::PRISMARINE, Prismarine::BRICKS, "Prismarine Bricks")); + self::register(new Prismarine(Block::PRISMARINE, Prismarine::DARK, "Dark Prismarine")); + self::register(new Prismarine(Block::PRISMARINE, Prismarine::NORMAL, "Prismarine")); + self::register(new Pumpkin()); + self::register(new PumpkinStem()); + self::register(new Purpur(Block::PURPUR_BLOCK, 0, "Purpur Block")); + self::register(new class(Block::PURPUR_BLOCK, 2, "Purpur Pillar") extends Purpur{ use PillarRotationTrait; }); - self::registerBlock(new PurpurStairs()); - self::registerBlock(new Quartz(Block::QUARTZ_BLOCK, Quartz::NORMAL, "Quartz Block")); - self::registerBlock(new class(Block::QUARTZ_BLOCK, Quartz::CHISELED, "Chiseled Quartz Block") extends Quartz{ + self::register(new PurpurStairs()); + self::register(new Quartz(Block::QUARTZ_BLOCK, Quartz::NORMAL, "Quartz Block")); + self::register(new class(Block::QUARTZ_BLOCK, Quartz::CHISELED, "Chiseled Quartz Block") extends Quartz{ use PillarRotationTrait; }); - self::registerBlock(new class(Block::QUARTZ_BLOCK, Quartz::PILLAR, "Quartz Pillar") extends Quartz{ + self::register(new class(Block::QUARTZ_BLOCK, Quartz::PILLAR, "Quartz Pillar") extends Quartz{ use PillarRotationTrait; }); - self::registerBlock(new Quartz(Block::QUARTZ_BLOCK, Quartz::SMOOTH, "Smooth Quartz Block")); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) - self::registerBlock(new QuartzStairs()); - self::registerBlock(new Rail()); - self::registerBlock(new RedMushroom()); - self::registerBlock(new RedMushroomBlock()); - self::registerBlock(new RedSandstoneStairs()); - self::registerBlock(new Redstone()); - self::registerBlock(new RedstoneLamp()); - self::registerBlock((new RedstoneLamp())->setLit()); //flattening hack - self::registerBlock(new RedstoneOre()); - self::registerBlock((new RedstoneOre())->setLit()); //flattening hack - self::registerBlock(new RedstoneRepeater()); - self::registerBlock((new RedstoneRepeater())->setPowered()); - self::registerBlock(new RedstoneTorch()); - self::registerBlock((new RedstoneTorch())->setLit(false)); //flattening hack - self::registerBlock(new RedstoneWire()); - self::registerBlock(new Reserved6(Block::RESERVED6, 0, "reserved6")); - self::registerBlock(new Sand(Block::SAND, 0, "Sand")); - self::registerBlock(new Sand(Block::SAND, 1, "Red Sand")); - self::registerBlock(new SandstoneStairs()); - self::registerBlock(new SeaLantern()); - self::registerBlock(new SignPost()); - self::registerBlock(new Skull()); - self::registerBlock(new SmoothStone(Block::STONE, Stone::NORMAL, "Stone")); - self::registerBlock(new Snow()); - self::registerBlock(new SnowLayer()); - self::registerBlock(new SoulSand()); - self::registerBlock(new Sponge()); - self::registerBlock(new StandingBanner()); - self::registerBlock(new Stone(Block::STONE, Stone::ANDESITE, "Andesite")); - self::registerBlock(new Stone(Block::STONE, Stone::DIORITE, "Diorite")); - self::registerBlock(new Stone(Block::STONE, Stone::GRANITE, "Granite")); - self::registerBlock(new Stone(Block::STONE, Stone::POLISHED_ANDESITE, "Polished Andesite")); - self::registerBlock(new Stone(Block::STONE, Stone::POLISHED_DIORITE, "Polished Diorite")); - self::registerBlock(new Stone(Block::STONE, Stone::POLISHED_GRANITE, "Polished Granite")); - self::registerBlock(new StoneBrickStairs()); - self::registerBlock(new StoneBricks(Block::STONE_BRICKS, StoneBricks::CHISELED, "Chiseled Stone Bricks")); - self::registerBlock(new StoneBricks(Block::STONE_BRICKS, StoneBricks::CRACKED, "Cracked Stone Bricks")); - self::registerBlock(new StoneBricks(Block::STONE_BRICKS, StoneBricks::MOSSY, "Mossy Stone Bricks")); - self::registerBlock(new StoneBricks(Block::STONE_BRICKS, StoneBricks::NORMAL, "Stone Bricks")); - self::registerBlock(new StoneButton()); - self::registerBlock(new StonePressurePlate()); - self::registerBlock(new Stonecutter()); - self::registerBlock(new Sugarcane()); - self::registerBlock(new TNT()); - self::registerBlock(new TallGrass(Block::TALL_GRASS, 0, "Fern")); - self::registerBlock(new TallGrass(Block::TALL_GRASS, 1, "Tall Grass")); - self::registerBlock(new TallGrass(Block::TALL_GRASS, 2, "Fern")); - self::registerBlock(new TallGrass(Block::TALL_GRASS, 3, "Fern")); - self::registerBlock(new Torch(Block::COLORED_TORCH_BP, 0, "Blue Torch")); - self::registerBlock(new Torch(Block::COLORED_TORCH_BP, 8, "Purple Torch")); - self::registerBlock(new Torch(Block::COLORED_TORCH_RG, 0, "Red Torch")); - self::registerBlock(new Torch(Block::COLORED_TORCH_RG, 8, "Green Torch")); - self::registerBlock(new Torch(Block::TORCH, 0, "Torch")); - self::registerBlock(new Trapdoor()); - self::registerBlock(new TrappedChest()); - self::registerBlock(new Tripwire()); - self::registerBlock(new TripwireHook()); - self::registerBlock(new UnderwaterTorch(Block::UNDERWATER_TORCH, 0, "Underwater Torch")); - self::registerBlock(new Vine()); - self::registerBlock(new WallBanner()); - self::registerBlock(new WallSign()); - self::registerBlock(new Water()); - self::registerBlock((new Water())->setStill()); //flattening hack - self::registerBlock(new WaterLily()); - self::registerBlock(new WeightedPressurePlateHeavy()); - self::registerBlock(new WeightedPressurePlateLight()); - self::registerBlock(new Wheat()); - self::registerBlock(new WoodenButton()); - self::registerBlock(new WoodenDoor(Block::ACACIA_DOOR_BLOCK, 0, "Acacia Door", Item::ACACIA_DOOR)); - self::registerBlock(new WoodenDoor(Block::BIRCH_DOOR_BLOCK, 0, "Birch Door", Item::BIRCH_DOOR)); - self::registerBlock(new WoodenDoor(Block::DARK_OAK_DOOR_BLOCK, 0, "Dark Oak Door", Item::DARK_OAK_DOOR)); - self::registerBlock(new WoodenDoor(Block::JUNGLE_DOOR_BLOCK, 0, "Jungle Door", Item::JUNGLE_DOOR)); - self::registerBlock(new WoodenDoor(Block::OAK_DOOR_BLOCK, 0, "Oak Door", Item::OAK_DOOR)); - self::registerBlock(new WoodenDoor(Block::SPRUCE_DOOR_BLOCK, 0, "Spruce Door", Item::SPRUCE_DOOR)); - self::registerBlock(new WoodenPressurePlate()); - self::registerBlock(new WoodenStairs(Block::ACACIA_STAIRS, 0, "Acacia Stairs")); - self::registerBlock(new WoodenStairs(Block::BIRCH_STAIRS, 0, "Birch Stairs")); - self::registerBlock(new WoodenStairs(Block::DARK_OAK_STAIRS, 0, "Dark Oak Stairs")); - self::registerBlock(new WoodenStairs(Block::JUNGLE_STAIRS, 0, "Jungle Stairs")); - self::registerBlock(new WoodenStairs(Block::OAK_STAIRS, 0, "Oak Stairs")); - self::registerBlock(new WoodenStairs(Block::SPRUCE_STAIRS, 0, "Spruce Stairs")); + self::register(new Quartz(Block::QUARTZ_BLOCK, Quartz::SMOOTH, "Smooth Quartz Block")); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) + self::register(new QuartzStairs()); + self::register(new Rail()); + self::register(new RedMushroom()); + self::register(new RedMushroomBlock()); + self::register(new RedSandstoneStairs()); + self::register(new Redstone()); + self::register(new RedstoneLamp()); + self::register((new RedstoneLamp())->setLit()); //flattening hack + self::register(new RedstoneOre()); + self::register((new RedstoneOre())->setLit()); //flattening hack + self::register(new RedstoneRepeater()); + self::register((new RedstoneRepeater())->setPowered()); + self::register(new RedstoneTorch()); + self::register((new RedstoneTorch())->setLit(false)); //flattening hack + self::register(new RedstoneWire()); + self::register(new Reserved6(Block::RESERVED6, 0, "reserved6")); + self::register(new Sand(Block::SAND, 0, "Sand")); + self::register(new Sand(Block::SAND, 1, "Red Sand")); + self::register(new SandstoneStairs()); + self::register(new SeaLantern()); + self::register(new SignPost()); + self::register(new Skull()); + self::register(new SmoothStone(Block::STONE, Stone::NORMAL, "Stone")); + self::register(new Snow()); + self::register(new SnowLayer()); + self::register(new SoulSand()); + self::register(new Sponge()); + self::register(new StandingBanner()); + self::register(new Stone(Block::STONE, Stone::ANDESITE, "Andesite")); + self::register(new Stone(Block::STONE, Stone::DIORITE, "Diorite")); + self::register(new Stone(Block::STONE, Stone::GRANITE, "Granite")); + self::register(new Stone(Block::STONE, Stone::POLISHED_ANDESITE, "Polished Andesite")); + self::register(new Stone(Block::STONE, Stone::POLISHED_DIORITE, "Polished Diorite")); + self::register(new Stone(Block::STONE, Stone::POLISHED_GRANITE, "Polished Granite")); + self::register(new StoneBrickStairs()); + self::register(new StoneBricks(Block::STONE_BRICKS, StoneBricks::CHISELED, "Chiseled Stone Bricks")); + self::register(new StoneBricks(Block::STONE_BRICKS, StoneBricks::CRACKED, "Cracked Stone Bricks")); + self::register(new StoneBricks(Block::STONE_BRICKS, StoneBricks::MOSSY, "Mossy Stone Bricks")); + self::register(new StoneBricks(Block::STONE_BRICKS, StoneBricks::NORMAL, "Stone Bricks")); + self::register(new StoneButton()); + self::register(new StonePressurePlate()); + self::register(new Stonecutter()); + self::register(new Sugarcane()); + self::register(new TNT()); + self::register(new TallGrass(Block::TALL_GRASS, 0, "Fern")); + self::register(new TallGrass(Block::TALL_GRASS, 1, "Tall Grass")); + self::register(new TallGrass(Block::TALL_GRASS, 2, "Fern")); + self::register(new TallGrass(Block::TALL_GRASS, 3, "Fern")); + self::register(new Torch(Block::COLORED_TORCH_BP, 0, "Blue Torch")); + self::register(new Torch(Block::COLORED_TORCH_BP, 8, "Purple Torch")); + self::register(new Torch(Block::COLORED_TORCH_RG, 0, "Red Torch")); + self::register(new Torch(Block::COLORED_TORCH_RG, 8, "Green Torch")); + self::register(new Torch(Block::TORCH, 0, "Torch")); + self::register(new Trapdoor()); + self::register(new TrappedChest()); + self::register(new Tripwire()); + self::register(new TripwireHook()); + self::register(new UnderwaterTorch(Block::UNDERWATER_TORCH, 0, "Underwater Torch")); + self::register(new Vine()); + self::register(new WallBanner()); + self::register(new WallSign()); + self::register(new Water()); + self::register((new Water())->setStill()); //flattening hack + self::register(new WaterLily()); + self::register(new WeightedPressurePlateHeavy()); + self::register(new WeightedPressurePlateLight()); + self::register(new Wheat()); + self::register(new WoodenButton()); + self::register(new WoodenDoor(Block::ACACIA_DOOR_BLOCK, 0, "Acacia Door", Item::ACACIA_DOOR)); + self::register(new WoodenDoor(Block::BIRCH_DOOR_BLOCK, 0, "Birch Door", Item::BIRCH_DOOR)); + self::register(new WoodenDoor(Block::DARK_OAK_DOOR_BLOCK, 0, "Dark Oak Door", Item::DARK_OAK_DOOR)); + self::register(new WoodenDoor(Block::JUNGLE_DOOR_BLOCK, 0, "Jungle Door", Item::JUNGLE_DOOR)); + self::register(new WoodenDoor(Block::OAK_DOOR_BLOCK, 0, "Oak Door", Item::OAK_DOOR)); + self::register(new WoodenDoor(Block::SPRUCE_DOOR_BLOCK, 0, "Spruce Door", Item::SPRUCE_DOOR)); + self::register(new WoodenPressurePlate()); + self::register(new WoodenStairs(Block::ACACIA_STAIRS, 0, "Acacia Stairs")); + self::register(new WoodenStairs(Block::BIRCH_STAIRS, 0, "Birch Stairs")); + self::register(new WoodenStairs(Block::DARK_OAK_STAIRS, 0, "Dark Oak Stairs")); + self::register(new WoodenStairs(Block::JUNGLE_STAIRS, 0, "Jungle Stairs")); + self::register(new WoodenStairs(Block::OAK_STAIRS, 0, "Oak Stairs")); + self::register(new WoodenStairs(Block::SPRUCE_STAIRS, 0, "Spruce Stairs")); foreach(TreeType::getAll() as $treeType){ $magicNumber = $treeType->getMagicNumber(); $name = $treeType->getDisplayName(); - self::registerBlock(new Planks(Block::PLANKS, $magicNumber, $name . " Planks")); - self::registerBlock(new Sapling(Block::SAPLING, $magicNumber, $treeType, $name . " Sapling")); - self::registerBlock(new WoodenFence(Block::FENCE, $magicNumber, $name . " Fence")); + self::register(new Planks(Block::PLANKS, $magicNumber, $name . " Planks")); + self::register(new Sapling(Block::SAPLING, $magicNumber, $treeType, $name . " Sapling")); + self::register(new WoodenFence(Block::FENCE, $magicNumber, $name . " Fence")); //TODO: find a better way to deal with this split - self::registerBlock(new Leaves($magicNumber >= 4 ? Block::LEAVES2 : Block::LEAVES, $magicNumber & 0x03, $treeType, $name . " Leaves")); - self::registerBlock(new Log($magicNumber >= 4 ? Block::WOOD2 : Block::WOOD, $magicNumber & 0x03, $treeType, $name . " Log")); - self::registerBlock(new Wood($magicNumber >= 4 ? Block::WOOD2 : Block::WOOD, ($magicNumber & 0x03) | 0b1100, $treeType, $name . " Wood")); + self::register(new Leaves($magicNumber >= 4 ? Block::LEAVES2 : Block::LEAVES, $magicNumber & 0x03, $treeType, $name . " Leaves")); + self::register(new Log($magicNumber >= 4 ? Block::WOOD2 : Block::WOOD, $magicNumber & 0x03, $treeType, $name . " Log")); + self::register(new Wood($magicNumber >= 4 ? Block::WOOD2 : Block::WOOD, ($magicNumber & 0x03) | 0b1100, $treeType, $name . " Wood")); } static $sandstoneTypes = [ @@ -335,20 +335,20 @@ class BlockFactory{ Sandstone::SMOOTH => "Smooth " ]; foreach($sandstoneTypes as $variant => $prefix){ - self::registerBlock(new Sandstone(Block::SANDSTONE, $variant, $prefix . "Sandstone")); - self::registerBlock(new Sandstone(Block::RED_SANDSTONE, $variant, $prefix . "Red Sandstone")); + self::register(new Sandstone(Block::SANDSTONE, $variant, $prefix . "Sandstone")); + self::register(new Sandstone(Block::RED_SANDSTONE, $variant, $prefix . "Red Sandstone")); } foreach(DyeColor::getAll() as $color){ - self::registerBlock(new Carpet(Block::CARPET, $color->getMagicNumber(), $color->getDisplayName() . " Carpet")); - self::registerBlock(new Concrete(Block::CONCRETE, $color->getMagicNumber(), $color->getDisplayName() . " Concrete")); - self::registerBlock(new ConcretePowder(Block::CONCRETE_POWDER, $color->getMagicNumber(), $color->getDisplayName() . " Concrete Powder")); - self::registerBlock(new Glass(Block::STAINED_GLASS, $color->getMagicNumber(), $color->getDisplayName() . " Stained Glass")); - self::registerBlock(new GlassPane(Block::STAINED_GLASS_PANE, $color->getMagicNumber(), $color->getDisplayName() . " Stained Glass Pane")); - self::registerBlock(new HardenedClay(Block::STAINED_CLAY, $color->getMagicNumber(), $color->getDisplayName() . " Stained Clay")); - self::registerBlock(new HardenedGlass(Block::HARD_STAINED_GLASS, $color->getMagicNumber(), "Hardened " . $color->getDisplayName() . " Stained Glass")); - self::registerBlock(new HardenedGlassPane(Block::HARD_STAINED_GLASS_PANE, $color->getMagicNumber(), "Hardened " . $color->getDisplayName() . " Stained Glass Pane")); - self::registerBlock(new Wool(Block::WOOL, $color->getMagicNumber(), $color->getDisplayName() . " Wool")); + self::register(new Carpet(Block::CARPET, $color->getMagicNumber(), $color->getDisplayName() . " Carpet")); + self::register(new Concrete(Block::CONCRETE, $color->getMagicNumber(), $color->getDisplayName() . " Concrete")); + self::register(new ConcretePowder(Block::CONCRETE_POWDER, $color->getMagicNumber(), $color->getDisplayName() . " Concrete Powder")); + self::register(new Glass(Block::STAINED_GLASS, $color->getMagicNumber(), $color->getDisplayName() . " Stained Glass")); + self::register(new GlassPane(Block::STAINED_GLASS_PANE, $color->getMagicNumber(), $color->getDisplayName() . " Stained Glass Pane")); + self::register(new HardenedClay(Block::STAINED_CLAY, $color->getMagicNumber(), $color->getDisplayName() . " Stained Clay")); + self::register(new HardenedGlass(Block::HARD_STAINED_GLASS, $color->getMagicNumber(), "Hardened " . $color->getDisplayName() . " Stained Glass")); + self::register(new HardenedGlassPane(Block::HARD_STAINED_GLASS_PANE, $color->getMagicNumber(), "Hardened " . $color->getDisplayName() . " Stained Glass Pane")); + self::register(new Wool(Block::WOOL, $color->getMagicNumber(), $color->getDisplayName() . " Wool")); } /** @var Slab[] $slabTypes */ @@ -374,8 +374,8 @@ class BlockFactory{ $slabTypes[] = new WoodenSlab(Block::WOODEN_SLAB, Block::DOUBLE_WOODEN_SLAB, $woodType->getMagicNumber(), $woodType->getDisplayName()); } foreach($slabTypes as $type){ - self::registerBlock($type); - self::registerBlock((clone $type)->setSlabType(SlabType::double())); //flattening hack + self::register($type); + self::register((clone $type)->setSlabType(SlabType::double())); //flattening hack } static $wallTypes = [ @@ -395,7 +395,7 @@ class BlockFactory{ CobblestoneWall::STONE_BRICK_WALL => "Stone Brick" ]; foreach($wallTypes as $magicNumber => $prefix){ - self::registerBlock(new CobblestoneWall(Block::COBBLESTONE_WALL, $magicNumber, $prefix . " Wall")); + self::register(new CobblestoneWall(Block::COBBLESTONE_WALL, $magicNumber, $prefix . " Wall")); } //TODO: minecraft:acacia_button @@ -531,7 +531,7 @@ class BlockFactory{ * @throws \RuntimeException if something attempted to override an already-registered block without specifying the * $override parameter. */ - public static function registerBlock(Block $block, bool $override = false) : void{ + public static function register(Block $block, bool $override = false) : void{ $id = $block->getId(); $variant = $block->getVariant(); diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 3192cdd7c5..7bd81f3801 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -53,226 +53,226 @@ class ItemFactory{ public static function init(){ self::$list = []; //in case of re-initializing - self::registerItem(new Shovel(Item::IRON_SHOVEL, "Iron Shovel", TieredTool::TIER_IRON)); - self::registerItem(new Pickaxe(Item::IRON_PICKAXE, "Iron Pickaxe", TieredTool::TIER_IRON)); - self::registerItem(new Axe(Item::IRON_AXE, "Iron Axe", TieredTool::TIER_IRON)); - self::registerItem(new FlintSteel()); - self::registerItem(new Apple()); - self::registerItem(new Bow()); - self::registerItem(new Arrow()); - self::registerItem(new Coal(Item::COAL, 0, "Coal")); - self::registerItem(new Coal(Item::COAL, 1, "Charcoal")); - self::registerItem(new Item(Item::DIAMOND, 0, "Diamond")); - self::registerItem(new Item(Item::IRON_INGOT, 0, "Iron Ingot")); - self::registerItem(new Item(Item::GOLD_INGOT, 0, "Gold Ingot")); - self::registerItem(new Sword(Item::IRON_SWORD, "Iron Sword", TieredTool::TIER_IRON)); - self::registerItem(new Sword(Item::WOODEN_SWORD, "Wooden Sword", TieredTool::TIER_WOODEN)); - self::registerItem(new Shovel(Item::WOODEN_SHOVEL, "Wooden Shovel", TieredTool::TIER_WOODEN)); - self::registerItem(new Pickaxe(Item::WOODEN_PICKAXE, "Wooden Pickaxe", TieredTool::TIER_WOODEN)); - self::registerItem(new Axe(Item::WOODEN_AXE, "Wooden Axe", TieredTool::TIER_WOODEN)); - self::registerItem(new Sword(Item::STONE_SWORD, "Stone Sword", TieredTool::TIER_STONE)); - self::registerItem(new Shovel(Item::STONE_SHOVEL, "Stone Shovel", TieredTool::TIER_STONE)); - self::registerItem(new Pickaxe(Item::STONE_PICKAXE, "Stone Pickaxe", TieredTool::TIER_STONE)); - self::registerItem(new Axe(Item::STONE_AXE, "Stone Axe", TieredTool::TIER_STONE)); - self::registerItem(new Sword(Item::DIAMOND_SWORD, "Diamond Sword", TieredTool::TIER_DIAMOND)); - self::registerItem(new Shovel(Item::DIAMOND_SHOVEL, "Diamond Shovel", TieredTool::TIER_DIAMOND)); - self::registerItem(new Pickaxe(Item::DIAMOND_PICKAXE, "Diamond Pickaxe", TieredTool::TIER_DIAMOND)); - self::registerItem(new Axe(Item::DIAMOND_AXE, "Diamond Axe", TieredTool::TIER_DIAMOND)); - self::registerItem(new Stick()); - self::registerItem(new Bowl()); - self::registerItem(new MushroomStew()); - self::registerItem(new Sword(Item::GOLDEN_SWORD, "Gold Sword", TieredTool::TIER_GOLD)); - self::registerItem(new Shovel(Item::GOLDEN_SHOVEL, "Gold Shovel", TieredTool::TIER_GOLD)); - self::registerItem(new Pickaxe(Item::GOLDEN_PICKAXE, "Gold Pickaxe", TieredTool::TIER_GOLD)); - self::registerItem(new Axe(Item::GOLDEN_AXE, "Gold Axe", TieredTool::TIER_GOLD)); - self::registerItem(new StringItem()); - self::registerItem(new Item(Item::FEATHER, 0, "Feather")); - self::registerItem(new Item(Item::GUNPOWDER, 0, "Gunpowder")); - self::registerItem(new Hoe(Item::WOODEN_HOE, "Wooden Hoe", TieredTool::TIER_WOODEN)); - self::registerItem(new Hoe(Item::STONE_HOE, "Stone Hoe", TieredTool::TIER_STONE)); - self::registerItem(new Hoe(Item::IRON_HOE, "Iron Hoe", TieredTool::TIER_IRON)); - self::registerItem(new Hoe(Item::DIAMOND_HOE, "Diamond Hoe", TieredTool::TIER_DIAMOND)); - self::registerItem(new Hoe(Item::GOLDEN_HOE, "Golden Hoe", TieredTool::TIER_GOLD)); - self::registerItem(new WheatSeeds()); - self::registerItem(new Item(Item::WHEAT, 0, "Wheat")); - self::registerItem(new Bread()); - self::registerItem(new LeatherCap()); - self::registerItem(new LeatherTunic()); - self::registerItem(new LeatherPants()); - self::registerItem(new LeatherBoots()); - self::registerItem(new ChainHelmet()); - self::registerItem(new ChainChestplate()); - self::registerItem(new ChainLeggings()); - self::registerItem(new ChainBoots()); - self::registerItem(new IronHelmet()); - self::registerItem(new IronChestplate()); - self::registerItem(new IronLeggings()); - self::registerItem(new IronBoots()); - self::registerItem(new DiamondHelmet()); - self::registerItem(new DiamondChestplate()); - self::registerItem(new DiamondLeggings()); - self::registerItem(new DiamondBoots()); - self::registerItem(new GoldHelmet()); - self::registerItem(new GoldChestplate()); - self::registerItem(new GoldLeggings()); - self::registerItem(new GoldBoots()); - self::registerItem(new Item(Item::FLINT, 0, "Flint")); - self::registerItem(new RawPorkchop()); - self::registerItem(new CookedPorkchop()); - self::registerItem(new PaintingItem()); - self::registerItem(new GoldenApple()); - self::registerItem(new Sign()); - self::registerItem(new ItemBlock(Block::OAK_DOOR_BLOCK, 0, Item::OAK_DOOR)); + self::register(new Shovel(Item::IRON_SHOVEL, "Iron Shovel", TieredTool::TIER_IRON)); + self::register(new Pickaxe(Item::IRON_PICKAXE, "Iron Pickaxe", TieredTool::TIER_IRON)); + self::register(new Axe(Item::IRON_AXE, "Iron Axe", TieredTool::TIER_IRON)); + self::register(new FlintSteel()); + self::register(new Apple()); + self::register(new Bow()); + self::register(new Arrow()); + self::register(new Coal(Item::COAL, 0, "Coal")); + self::register(new Coal(Item::COAL, 1, "Charcoal")); + self::register(new Item(Item::DIAMOND, 0, "Diamond")); + self::register(new Item(Item::IRON_INGOT, 0, "Iron Ingot")); + self::register(new Item(Item::GOLD_INGOT, 0, "Gold Ingot")); + self::register(new Sword(Item::IRON_SWORD, "Iron Sword", TieredTool::TIER_IRON)); + self::register(new Sword(Item::WOODEN_SWORD, "Wooden Sword", TieredTool::TIER_WOODEN)); + self::register(new Shovel(Item::WOODEN_SHOVEL, "Wooden Shovel", TieredTool::TIER_WOODEN)); + self::register(new Pickaxe(Item::WOODEN_PICKAXE, "Wooden Pickaxe", TieredTool::TIER_WOODEN)); + self::register(new Axe(Item::WOODEN_AXE, "Wooden Axe", TieredTool::TIER_WOODEN)); + self::register(new Sword(Item::STONE_SWORD, "Stone Sword", TieredTool::TIER_STONE)); + self::register(new Shovel(Item::STONE_SHOVEL, "Stone Shovel", TieredTool::TIER_STONE)); + self::register(new Pickaxe(Item::STONE_PICKAXE, "Stone Pickaxe", TieredTool::TIER_STONE)); + self::register(new Axe(Item::STONE_AXE, "Stone Axe", TieredTool::TIER_STONE)); + self::register(new Sword(Item::DIAMOND_SWORD, "Diamond Sword", TieredTool::TIER_DIAMOND)); + self::register(new Shovel(Item::DIAMOND_SHOVEL, "Diamond Shovel", TieredTool::TIER_DIAMOND)); + self::register(new Pickaxe(Item::DIAMOND_PICKAXE, "Diamond Pickaxe", TieredTool::TIER_DIAMOND)); + self::register(new Axe(Item::DIAMOND_AXE, "Diamond Axe", TieredTool::TIER_DIAMOND)); + self::register(new Stick()); + self::register(new Bowl()); + self::register(new MushroomStew()); + self::register(new Sword(Item::GOLDEN_SWORD, "Gold Sword", TieredTool::TIER_GOLD)); + self::register(new Shovel(Item::GOLDEN_SHOVEL, "Gold Shovel", TieredTool::TIER_GOLD)); + self::register(new Pickaxe(Item::GOLDEN_PICKAXE, "Gold Pickaxe", TieredTool::TIER_GOLD)); + self::register(new Axe(Item::GOLDEN_AXE, "Gold Axe", TieredTool::TIER_GOLD)); + self::register(new StringItem()); + self::register(new Item(Item::FEATHER, 0, "Feather")); + self::register(new Item(Item::GUNPOWDER, 0, "Gunpowder")); + self::register(new Hoe(Item::WOODEN_HOE, "Wooden Hoe", TieredTool::TIER_WOODEN)); + self::register(new Hoe(Item::STONE_HOE, "Stone Hoe", TieredTool::TIER_STONE)); + self::register(new Hoe(Item::IRON_HOE, "Iron Hoe", TieredTool::TIER_IRON)); + self::register(new Hoe(Item::DIAMOND_HOE, "Diamond Hoe", TieredTool::TIER_DIAMOND)); + self::register(new Hoe(Item::GOLDEN_HOE, "Golden Hoe", TieredTool::TIER_GOLD)); + self::register(new WheatSeeds()); + self::register(new Item(Item::WHEAT, 0, "Wheat")); + self::register(new Bread()); + self::register(new LeatherCap()); + self::register(new LeatherTunic()); + self::register(new LeatherPants()); + self::register(new LeatherBoots()); + self::register(new ChainHelmet()); + self::register(new ChainChestplate()); + self::register(new ChainLeggings()); + self::register(new ChainBoots()); + self::register(new IronHelmet()); + self::register(new IronChestplate()); + self::register(new IronLeggings()); + self::register(new IronBoots()); + self::register(new DiamondHelmet()); + self::register(new DiamondChestplate()); + self::register(new DiamondLeggings()); + self::register(new DiamondBoots()); + self::register(new GoldHelmet()); + self::register(new GoldChestplate()); + self::register(new GoldLeggings()); + self::register(new GoldBoots()); + self::register(new Item(Item::FLINT, 0, "Flint")); + self::register(new RawPorkchop()); + self::register(new CookedPorkchop()); + self::register(new PaintingItem()); + self::register(new GoldenApple()); + self::register(new Sign()); + self::register(new ItemBlock(Block::OAK_DOOR_BLOCK, 0, Item::OAK_DOOR)); //TODO: fix metadata for buckets with still liquid in them //the meta values are intentionally hardcoded because block IDs will change in the future - self::registerItem(new Bucket(Item::BUCKET, 0, "Bucket")); - self::registerItem(new MilkBucket(Item::BUCKET, 1, "Milk Bucket")); - self::registerItem(new LiquidBucket(Item::BUCKET, 8, "Water Bucket", Block::FLOWING_WATER)); - self::registerItem(new LiquidBucket(Item::BUCKET, 10, "Lava Bucket", Block::FLOWING_LAVA)); + self::register(new Bucket(Item::BUCKET, 0, "Bucket")); + self::register(new MilkBucket(Item::BUCKET, 1, "Milk Bucket")); + self::register(new LiquidBucket(Item::BUCKET, 8, "Water Bucket", Block::FLOWING_WATER)); + self::register(new LiquidBucket(Item::BUCKET, 10, "Lava Bucket", Block::FLOWING_LAVA)); - self::registerItem(new Minecart()); + self::register(new Minecart()); - self::registerItem(new ItemBlock(Block::IRON_DOOR_BLOCK, 0, Item::IRON_DOOR)); - self::registerItem(new Redstone()); - self::registerItem(new Snowball()); + self::register(new ItemBlock(Block::IRON_DOOR_BLOCK, 0, Item::IRON_DOOR)); + self::register(new Redstone()); + self::register(new Snowball()); - self::registerItem(new Boat()); - self::registerItem(new Item(Item::LEATHER, 0, "Leather")); + self::register(new Boat()); + self::register(new Item(Item::LEATHER, 0, "Leather")); - self::registerItem(new Item(Item::BRICK, 0, "Brick")); - self::registerItem(new Item(Item::CLAY_BALL, 0, "Clay")); - self::registerItem(new ItemBlock(Block::SUGARCANE_BLOCK, 0, Item::SUGARCANE)); - self::registerItem(new Item(Item::PAPER, 0, "Paper")); - self::registerItem(new Book()); - self::registerItem(new Item(Item::SLIME_BALL, 0, "Slimeball")); + self::register(new Item(Item::BRICK, 0, "Brick")); + self::register(new Item(Item::CLAY_BALL, 0, "Clay")); + self::register(new ItemBlock(Block::SUGARCANE_BLOCK, 0, Item::SUGARCANE)); + self::register(new Item(Item::PAPER, 0, "Paper")); + self::register(new Book()); + self::register(new Item(Item::SLIME_BALL, 0, "Slimeball")); - self::registerItem(new Egg()); - self::registerItem(new Compass()); - self::registerItem(new FishingRod()); - self::registerItem(new Clock()); - self::registerItem(new Item(Item::GLOWSTONE_DUST, 0, "Glowstone Dust")); - self::registerItem(new RawFish()); - self::registerItem(new CookedFish()); + self::register(new Egg()); + self::register(new Compass()); + self::register(new FishingRod()); + self::register(new Clock()); + self::register(new Item(Item::GLOWSTONE_DUST, 0, "Glowstone Dust")); + self::register(new RawFish()); + self::register(new CookedFish()); foreach(DyeColor::getAll() as $color){ //TODO: use colour object directly //TODO: add interface to dye-colour objects //TODO: new dedicated dyes - self::registerItem(new Dye($color->getInvertedMagicNumber(), $color->getDisplayName() . " Dye")); - self::registerItem(new Bed($color->getMagicNumber(), $color->getDisplayName() . " Bed")); - self::registerItem(new Banner($color->getInvertedMagicNumber(), $color->getDisplayName() . " Banner")); + self::register(new Dye($color->getInvertedMagicNumber(), $color->getDisplayName() . " Dye")); + self::register(new Bed($color->getMagicNumber(), $color->getDisplayName() . " Bed")); + self::register(new Banner($color->getInvertedMagicNumber(), $color->getDisplayName() . " Banner")); } - self::registerItem(new Item(Item::BONE, 0, "Bone")); - self::registerItem(new Item(Item::SUGAR, 0, "Sugar")); - self::registerItem(new ItemBlock(Block::CAKE_BLOCK, 0, Item::CAKE)); + self::register(new Item(Item::BONE, 0, "Bone")); + self::register(new Item(Item::SUGAR, 0, "Sugar")); + self::register(new ItemBlock(Block::CAKE_BLOCK, 0, Item::CAKE)); - self::registerItem(new ItemBlock(Block::REPEATER_BLOCK, 0, Item::REPEATER)); - self::registerItem(new Cookie()); + self::register(new ItemBlock(Block::REPEATER_BLOCK, 0, Item::REPEATER)); + self::register(new Cookie()); - self::registerItem(new Shears()); - self::registerItem(new Melon()); - self::registerItem(new PumpkinSeeds()); - self::registerItem(new MelonSeeds()); - self::registerItem(new RawBeef()); - self::registerItem(new Steak()); - self::registerItem(new RawChicken()); - self::registerItem(new CookedChicken()); - self::registerItem(new RottenFlesh()); - self::registerItem(new EnderPearl()); - self::registerItem(new BlazeRod()); - self::registerItem(new Item(Item::GHAST_TEAR, 0, "Ghast Tear")); - self::registerItem(new Item(Item::GOLD_NUGGET, 0, "Gold Nugget")); - self::registerItem(new ItemBlock(Block::NETHER_WART_PLANT, 0, Item::NETHER_WART)); + self::register(new Shears()); + self::register(new Melon()); + self::register(new PumpkinSeeds()); + self::register(new MelonSeeds()); + self::register(new RawBeef()); + self::register(new Steak()); + self::register(new RawChicken()); + self::register(new CookedChicken()); + self::register(new RottenFlesh()); + self::register(new EnderPearl()); + self::register(new BlazeRod()); + self::register(new Item(Item::GHAST_TEAR, 0, "Ghast Tear")); + self::register(new Item(Item::GOLD_NUGGET, 0, "Gold Nugget")); + self::register(new ItemBlock(Block::NETHER_WART_PLANT, 0, Item::NETHER_WART)); foreach(Potion::ALL as $type){ - self::registerItem(new Potion($type)); - self::registerItem(new SplashPotion($type)); + self::register(new Potion($type)); + self::register(new SplashPotion($type)); } - self::registerItem(new GlassBottle()); - self::registerItem(new SpiderEye()); - self::registerItem(new Item(Item::FERMENTED_SPIDER_EYE, 0, "Fermented Spider Eye")); - self::registerItem(new Item(Item::BLAZE_POWDER, 0, "Blaze Powder")); - self::registerItem(new Item(Item::MAGMA_CREAM, 0, "Magma Cream")); - self::registerItem(new ItemBlock(Block::BREWING_STAND_BLOCK, 0, Item::BREWING_STAND)); - self::registerItem(new ItemBlock(Block::CAULDRON_BLOCK, 0, Item::CAULDRON)); + self::register(new GlassBottle()); + self::register(new SpiderEye()); + self::register(new Item(Item::FERMENTED_SPIDER_EYE, 0, "Fermented Spider Eye")); + self::register(new Item(Item::BLAZE_POWDER, 0, "Blaze Powder")); + self::register(new Item(Item::MAGMA_CREAM, 0, "Magma Cream")); + self::register(new ItemBlock(Block::BREWING_STAND_BLOCK, 0, Item::BREWING_STAND)); + self::register(new ItemBlock(Block::CAULDRON_BLOCK, 0, Item::CAULDRON)); - self::registerItem(new Item(Item::GLISTERING_MELON, 0, "Glistering Melon")); + self::register(new Item(Item::GLISTERING_MELON, 0, "Glistering Melon")); foreach(EntityFactory::getKnownTypes() as $className){ /** @var Living|string $className */ if(is_a($className, Living::class, true) and $className::NETWORK_ID !== -1){ - self::registerItem(new SpawnEgg(Item::SPAWN_EGG, $className::NETWORK_ID, $className, "Spawn Egg")); + self::register(new SpawnEgg(Item::SPAWN_EGG, $className::NETWORK_ID, $className, "Spawn Egg")); } } - self::registerItem(new ExperienceBottle()); + self::register(new ExperienceBottle()); - self::registerItem(new WritableBook()); - self::registerItem(new WrittenBook()); - self::registerItem(new Item(Item::EMERALD, 0, "Emerald")); - self::registerItem(new ItemBlock(Block::ITEM_FRAME_BLOCK, 0, Item::ITEM_FRAME)); - self::registerItem(new ItemBlock(Block::FLOWER_POT_BLOCK, 0, Item::FLOWER_POT)); - self::registerItem(new Carrot()); - self::registerItem(new Potato()); - self::registerItem(new BakedPotato()); - self::registerItem(new PoisonousPotato()); + self::register(new WritableBook()); + self::register(new WrittenBook()); + self::register(new Item(Item::EMERALD, 0, "Emerald")); + self::register(new ItemBlock(Block::ITEM_FRAME_BLOCK, 0, Item::ITEM_FRAME)); + self::register(new ItemBlock(Block::FLOWER_POT_BLOCK, 0, Item::FLOWER_POT)); + self::register(new Carrot()); + self::register(new Potato()); + self::register(new BakedPotato()); + self::register(new PoisonousPotato()); - self::registerItem(new GoldenCarrot()); + self::register(new GoldenCarrot()); - self::registerItem(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_SKELETON, Item::SKULL)); - self::registerItem(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_WITHER, Item::SKULL)); - self::registerItem(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_ZOMBIE, Item::SKULL)); - self::registerItem(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_HUMAN, Item::SKULL)); - self::registerItem(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_CREEPER, Item::SKULL)); - self::registerItem(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_DRAGON, Item::SKULL)); + self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_SKELETON, Item::SKULL)); + self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_WITHER, Item::SKULL)); + self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_ZOMBIE, Item::SKULL)); + self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_HUMAN, Item::SKULL)); + self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_CREEPER, Item::SKULL)); + self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_DRAGON, Item::SKULL)); - self::registerItem(new Item(Item::NETHER_STAR, 0, "Nether Star")); - self::registerItem(new PumpkinPie()); + self::register(new Item(Item::NETHER_STAR, 0, "Nether Star")); + self::register(new PumpkinPie()); - self::registerItem(new ItemBlock(Block::COMPARATOR_BLOCK, 0, Item::COMPARATOR)); - self::registerItem(new Item(Item::NETHER_BRICK, 0, "Nether Brick")); - self::registerItem(new Item(Item::NETHER_QUARTZ, 0, "Nether Quartz")); + self::register(new ItemBlock(Block::COMPARATOR_BLOCK, 0, Item::COMPARATOR)); + self::register(new Item(Item::NETHER_BRICK, 0, "Nether Brick")); + self::register(new Item(Item::NETHER_QUARTZ, 0, "Nether Quartz")); - self::registerItem(new Item(Item::PRISMARINE_SHARD, 0, "Prismarine Shard")); - self::registerItem(new ItemBlock(Block::HOPPER_BLOCK, 0, Item::HOPPER)); - self::registerItem(new RawRabbit()); - self::registerItem(new CookedRabbit()); - self::registerItem(new RabbitStew()); - self::registerItem(new Item(Item::RABBIT_FOOT, 0, "Rabbit's Foot")); - self::registerItem(new Item(Item::RABBIT_HIDE, 0, "Rabbit Hide")); + self::register(new Item(Item::PRISMARINE_SHARD, 0, "Prismarine Shard")); + self::register(new ItemBlock(Block::HOPPER_BLOCK, 0, Item::HOPPER)); + self::register(new RawRabbit()); + self::register(new CookedRabbit()); + self::register(new RabbitStew()); + self::register(new Item(Item::RABBIT_FOOT, 0, "Rabbit's Foot")); + self::register(new Item(Item::RABBIT_HIDE, 0, "Rabbit Hide")); - self::registerItem(new Item(Item::PRISMARINE_CRYSTALS, 0, "Prismarine Crystals")); - self::registerItem(new RawMutton()); - self::registerItem(new CookedMutton()); + self::register(new Item(Item::PRISMARINE_CRYSTALS, 0, "Prismarine Crystals")); + self::register(new RawMutton()); + self::register(new CookedMutton()); - self::registerItem(new ItemBlock(Block::SPRUCE_DOOR_BLOCK, 0, Item::SPRUCE_DOOR)); - self::registerItem(new ItemBlock(Block::BIRCH_DOOR_BLOCK, 0, Item::BIRCH_DOOR)); - self::registerItem(new ItemBlock(Block::JUNGLE_DOOR_BLOCK, 0, Item::JUNGLE_DOOR)); - self::registerItem(new ItemBlock(Block::ACACIA_DOOR_BLOCK, 0, Item::ACACIA_DOOR)); - self::registerItem(new ItemBlock(Block::DARK_OAK_DOOR_BLOCK, 0, Item::DARK_OAK_DOOR)); - self::registerItem(new ChorusFruit()); - self::registerItem(new Item(Item::CHORUS_FRUIT_POPPED, 0, "Popped Chorus Fruit")); + self::register(new ItemBlock(Block::SPRUCE_DOOR_BLOCK, 0, Item::SPRUCE_DOOR)); + self::register(new ItemBlock(Block::BIRCH_DOOR_BLOCK, 0, Item::BIRCH_DOOR)); + self::register(new ItemBlock(Block::JUNGLE_DOOR_BLOCK, 0, Item::JUNGLE_DOOR)); + self::register(new ItemBlock(Block::ACACIA_DOOR_BLOCK, 0, Item::ACACIA_DOOR)); + self::register(new ItemBlock(Block::DARK_OAK_DOOR_BLOCK, 0, Item::DARK_OAK_DOOR)); + self::register(new ChorusFruit()); + self::register(new Item(Item::CHORUS_FRUIT_POPPED, 0, "Popped Chorus Fruit")); - self::registerItem(new Item(Item::DRAGON_BREATH, 0, "Dragon's Breath")); + self::register(new Item(Item::DRAGON_BREATH, 0, "Dragon's Breath")); - self::registerItem(new Item(Item::SHULKER_SHELL, 0, "Shulker Shell")); + self::register(new Item(Item::SHULKER_SHELL, 0, "Shulker Shell")); - self::registerItem(new Totem()); - self::registerItem(new Item(Item::BLEACH, 0, "Bleach")); //EDU - self::registerItem(new Item(Item::IRON_NUGGET, 0, "Iron Nugget")); + self::register(new Totem()); + self::register(new Item(Item::BLEACH, 0, "Bleach")); //EDU + self::register(new Item(Item::IRON_NUGGET, 0, "Iron Nugget")); - self::registerItem(new Beetroot()); - self::registerItem(new BeetrootSeeds()); - self::registerItem(new BeetrootSoup()); - self::registerItem(new RawSalmon()); - self::registerItem(new Clownfish()); - self::registerItem(new Pufferfish()); - self::registerItem(new CookedSalmon()); - self::registerItem(new DriedKelp()); - self::registerItem(new Item(Item::NAUTILUS_SHELL, 0, "Nautilus Shell")); - self::registerItem(new GoldenAppleEnchanted()); - self::registerItem(new Item(Item::HEART_OF_THE_SEA, 0, "Heart of the Sea")); - self::registerItem(new Item(Item::TURTLE_SHELL_PIECE, 0, "Scute")); + self::register(new Beetroot()); + self::register(new BeetrootSeeds()); + self::register(new BeetrootSoup()); + self::register(new RawSalmon()); + self::register(new Clownfish()); + self::register(new Pufferfish()); + self::register(new CookedSalmon()); + self::register(new DriedKelp()); + self::register(new Item(Item::NAUTILUS_SHELL, 0, "Nautilus Shell")); + self::register(new GoldenAppleEnchanted()); + self::register(new Item(Item::HEART_OF_THE_SEA, 0, "Heart of the Sea")); + self::register(new Item(Item::TURTLE_SHELL_PIECE, 0, "Scute")); //TODO: minecraft:acacia_sign //TODO: minecraft:armor_stand @@ -342,7 +342,7 @@ class ItemFactory{ * @throws \RuntimeException if something attempted to override an already-registered item without specifying the * $override parameter. */ - public static function registerItem(Item $item, bool $override = false){ + public static function register(Item $item, bool $override = false){ $id = $item->getId(); $variant = $item->getDamage(); From 36e9db4c07aea565bd397128a1d77aa924d0ef98 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Feb 2019 11:09:22 +0000 Subject: [PATCH 0496/3224] Generate methods for surrogate enums, nip stupidity in the bud this also allows changing the internal implementation later without breaking plugins. --- src/pocketmine/block/Bed.php | 2 +- src/pocketmine/block/CocoaBlock.php | 4 +- src/pocketmine/block/Leaves.php | 2 +- src/pocketmine/block/utils/DyeColor.php | 98 ++++++++++++++++--- src/pocketmine/block/utils/TreeType.php | 38 +++++-- src/pocketmine/item/Banner.php | 2 +- src/pocketmine/level/biome/Biome.php | 2 +- src/pocketmine/level/biome/ForestBiome.php | 4 +- src/pocketmine/level/biome/TaigaBiome.php | 2 +- .../level/generator/object/BirchTree.php | 2 +- .../level/generator/object/JungleTree.php | 2 +- .../level/generator/object/OakTree.php | 2 +- .../level/generator/object/SpruceTree.php | 2 +- .../level/generator/object/Tree.php | 10 +- .../level/generator/populator/Tree.php | 2 +- src/pocketmine/tile/Banner.php | 2 +- src/pocketmine/tile/Bed.php | 2 +- 17 files changed, 135 insertions(+), 43 deletions(-) diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 286b8feb57..6e2e08e8f3 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -55,7 +55,7 @@ class Bed extends Transparent{ protected $color; public function __construct(){ - $this->color = DyeColor::$RED; + $this->color = DyeColor::RED(); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index fc82079bbd..29b852d3c5 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -86,7 +86,7 @@ class CocoaBlock extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ - if(Facing::axis($face) !== Facing::AXIS_Y and $blockClicked instanceof Wood and $blockClicked->getTreeType() === TreeType::$JUNGLE){ + if(Facing::axis($face) !== Facing::AXIS_Y and $blockClicked instanceof Wood and $blockClicked->getTreeType() === TreeType::JUNGLE()){ $this->facing = $face; return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -109,7 +109,7 @@ class CocoaBlock extends Transparent{ public function onNearbyBlockChange() : void{ $side = $this->getSide(Facing::opposite($this->facing)); - if(!($side instanceof Wood) or $side->getTreeType() !== TreeType::$JUNGLE){ + if(!($side instanceof Wood) or $side->getTreeType() !== TreeType::JUNGLE()){ $this->level->useBreakOn($this); } } diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 2e45fed5e7..90aa6924cd 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -134,7 +134,7 @@ class Leaves extends Transparent{ if(mt_rand(1, 20) === 1){ //Saplings $drops[] = ItemFactory::get(Item::SAPLING, $this->treeType->getMagicNumber()); } - if(($this->treeType === TreeType::$OAK or $this->treeType === TreeType::$DARK_OAK) and mt_rand(1, 200) === 1){ //Apples + if(($this->treeType === TreeType::OAK() or $this->treeType === TreeType::DARK_OAK()) and mt_rand(1, 200) === 1){ //Apples $drops[] = ItemFactory::get(Item::APPLE); } diff --git a/src/pocketmine/block/utils/DyeColor.php b/src/pocketmine/block/utils/DyeColor.php index a9fa04df59..c25ef02204 100644 --- a/src/pocketmine/block/utils/DyeColor.php +++ b/src/pocketmine/block/utils/DyeColor.php @@ -26,37 +26,103 @@ namespace pocketmine\block\utils; final class DyeColor{ /** @var DyeColor */ - public static $WHITE; + private static $WHITE; /** @var DyeColor */ - public static $ORANGE; + private static $ORANGE; /** @var DyeColor */ - public static $MAGENTA; + private static $MAGENTA; /** @var DyeColor */ - public static $LIGHT_BLUE; + private static $LIGHT_BLUE; /** @var DyeColor */ - public static $YELLOW; + private static $YELLOW; /** @var DyeColor */ - public static $LIME; + private static $LIME; /** @var DyeColor */ - public static $PINK; + private static $PINK; /** @var DyeColor */ - public static $GRAY; + private static $GRAY; /** @var DyeColor */ - public static $LIGHT_GRAY; + private static $LIGHT_GRAY; /** @var DyeColor */ - public static $CYAN; + private static $CYAN; /** @var DyeColor */ - public static $PURPLE; + private static $PURPLE; /** @var DyeColor */ - public static $BLUE; + private static $BLUE; /** @var DyeColor */ - public static $BROWN; + private static $BROWN; /** @var DyeColor */ - public static $GREEN; + private static $GREEN; /** @var DyeColor */ - public static $RED; + private static $RED; /** @var DyeColor */ - public static $BLACK; + private static $BLACK; + + /* auto-generated code */ + + public static function WHITE() : DyeColor{ + return self::$WHITE; + } + + public static function ORANGE() : DyeColor{ + return self::$ORANGE; + } + + public static function MAGENTA() : DyeColor{ + return self::$MAGENTA; + } + + public static function LIGHT_BLUE() : DyeColor{ + return self::$LIGHT_BLUE; + } + + public static function YELLOW() : DyeColor{ + return self::$YELLOW; + } + + public static function LIME() : DyeColor{ + return self::$LIME; + } + + public static function PINK() : DyeColor{ + return self::$PINK; + } + + public static function GRAY() : DyeColor{ + return self::$GRAY; + } + + public static function LIGHT_GRAY() : DyeColor{ + return self::$LIGHT_GRAY; + } + + public static function CYAN() : DyeColor{ + return self::$CYAN; + } + + public static function PURPLE() : DyeColor{ + return self::$PURPLE; + } + + public static function BLUE() : DyeColor{ + return self::$BLUE; + } + + public static function BROWN() : DyeColor{ + return self::$BROWN; + } + + public static function GREEN() : DyeColor{ + return self::$GREEN; + } + + public static function RED() : DyeColor{ + return self::$RED; + } + + public static function BLACK() : DyeColor{ + return self::$BLACK; + } /** @var DyeColor[] */ private static $numericIdMap = []; diff --git a/src/pocketmine/block/utils/TreeType.php b/src/pocketmine/block/utils/TreeType.php index 8b742c4e69..c6bce83f8c 100644 --- a/src/pocketmine/block/utils/TreeType.php +++ b/src/pocketmine/block/utils/TreeType.php @@ -26,17 +26,43 @@ namespace pocketmine\block\utils; final class TreeType{ /** @var TreeType */ - public static $OAK; + private static $OAK; /** @var TreeType */ - public static $SPRUCE; + private static $SPRUCE; /** @var TreeType */ - public static $BIRCH; + private static $BIRCH; /** @var TreeType */ - public static $JUNGLE; + private static $JUNGLE; /** @var TreeType */ - public static $ACACIA; + private static $ACACIA; /** @var TreeType */ - public static $DARK_OAK; + private static $DARK_OAK; + + /* auto-generated code */ + + public static function OAK() : TreeType{ + return self::$OAK; + } + + public static function SPRUCE() : TreeType{ + return self::$SPRUCE; + } + + public static function BIRCH() : TreeType{ + return self::$BIRCH; + } + + public static function JUNGLE() : TreeType{ + return self::$JUNGLE; + } + + public static function ACACIA() : TreeType{ + return self::$ACACIA; + } + + public static function DARK_OAK() : TreeType{ + return self::$DARK_OAK; + } /** @var TreeType[] */ private static $numericIdMap = []; diff --git a/src/pocketmine/item/Banner.php b/src/pocketmine/item/Banner.php index a8e6c287e3..7817469c3d 100644 --- a/src/pocketmine/item/Banner.php +++ b/src/pocketmine/item/Banner.php @@ -225,7 +225,7 @@ class Banner extends Item{ public function correctNBT() : void{ $tag = $this->getNamedTag(); if(!$tag->hasTag(self::TAG_BASE, IntTag::class)){ - $tag->setInt(self::TAG_BASE, DyeColor::$BLACK->getInvertedMagicNumber()); + $tag->setInt(self::TAG_BASE, DyeColor::BLACK()->getInvertedMagicNumber()); } if(!$tag->hasTag(self::TAG_PATTERNS, ListTag::class)){ diff --git a/src/pocketmine/level/biome/Biome.php b/src/pocketmine/level/biome/Biome.php index b4f201a26d..4840ae3284 100644 --- a/src/pocketmine/level/biome/Biome.php +++ b/src/pocketmine/level/biome/Biome.php @@ -99,7 +99,7 @@ abstract class Biome{ self::register(self::SMALL_MOUNTAINS, new SmallMountainsBiome()); - self::register(self::BIRCH_FOREST, new ForestBiome(TreeType::$BIRCH)); + self::register(self::BIRCH_FOREST, new ForestBiome(TreeType::BIRCH())); } /** diff --git a/src/pocketmine/level/biome/ForestBiome.php b/src/pocketmine/level/biome/ForestBiome.php index b537f1cb50..4f44bfc219 100644 --- a/src/pocketmine/level/biome/ForestBiome.php +++ b/src/pocketmine/level/biome/ForestBiome.php @@ -35,7 +35,7 @@ class ForestBiome extends GrassyBiome{ public function __construct(?TreeType $type = null){ parent::__construct(); - $this->type = $type ?? TreeType::$OAK; + $this->type = $type ?? TreeType::OAK(); $trees = new Tree($type); $trees->setBaseAmount(5); @@ -48,7 +48,7 @@ class ForestBiome extends GrassyBiome{ $this->setElevation(63, 81); - if($type === TreeType::$BIRCH){ + if($type === TreeType::BIRCH()){ $this->temperature = 0.6; $this->rainfall = 0.5; }else{ diff --git a/src/pocketmine/level/biome/TaigaBiome.php b/src/pocketmine/level/biome/TaigaBiome.php index 86b84de055..d1622ed24c 100644 --- a/src/pocketmine/level/biome/TaigaBiome.php +++ b/src/pocketmine/level/biome/TaigaBiome.php @@ -32,7 +32,7 @@ class TaigaBiome extends SnowyBiome{ public function __construct(){ parent::__construct(); - $trees = new Tree(TreeType::$SPRUCE); + $trees = new Tree(TreeType::SPRUCE()); $trees->setBaseAmount(10); $this->addPopulator($trees); diff --git a/src/pocketmine/level/generator/object/BirchTree.php b/src/pocketmine/level/generator/object/BirchTree.php index 8859e1e508..d0fd6bed29 100644 --- a/src/pocketmine/level/generator/object/BirchTree.php +++ b/src/pocketmine/level/generator/object/BirchTree.php @@ -34,7 +34,7 @@ class BirchTree extends Tree{ protected $superBirch = false; public function __construct(bool $superBirch = false){ - parent::__construct(BlockFactory::get(Block::LOG, TreeType::$BIRCH->getMagicNumber()), BlockFactory::get(Block::LEAVES, TreeType::$BIRCH->getMagicNumber())); + parent::__construct(BlockFactory::get(Block::LOG, TreeType::BIRCH()->getMagicNumber()), BlockFactory::get(Block::LEAVES, TreeType::BIRCH()->getMagicNumber())); $this->superBirch = $superBirch; } diff --git a/src/pocketmine/level/generator/object/JungleTree.php b/src/pocketmine/level/generator/object/JungleTree.php index 77f8b68ab8..47719e1c76 100644 --- a/src/pocketmine/level/generator/object/JungleTree.php +++ b/src/pocketmine/level/generator/object/JungleTree.php @@ -30,6 +30,6 @@ use pocketmine\block\utils\TreeType; class JungleTree extends Tree{ public function __construct(){ - parent::__construct(BlockFactory::get(Block::LOG, TreeType::$JUNGLE->getMagicNumber()), BlockFactory::get(Block::LEAVES, TreeType::$JUNGLE->getMagicNumber()), 8); + parent::__construct(BlockFactory::get(Block::LOG, TreeType::JUNGLE()->getMagicNumber()), BlockFactory::get(Block::LEAVES, TreeType::JUNGLE()->getMagicNumber()), 8); } } diff --git a/src/pocketmine/level/generator/object/OakTree.php b/src/pocketmine/level/generator/object/OakTree.php index 531f13b0ab..c50e0adf46 100644 --- a/src/pocketmine/level/generator/object/OakTree.php +++ b/src/pocketmine/level/generator/object/OakTree.php @@ -32,7 +32,7 @@ use pocketmine\utils\Random; class OakTree extends Tree{ public function __construct(){ - parent::__construct(BlockFactory::get(Block::LOG, TreeType::$OAK->getMagicNumber()), BlockFactory::get(Block::LEAVES, TreeType::$OAK->getMagicNumber())); + parent::__construct(BlockFactory::get(Block::LOG, TreeType::OAK()->getMagicNumber()), BlockFactory::get(Block::LEAVES, TreeType::OAK()->getMagicNumber())); } public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ diff --git a/src/pocketmine/level/generator/object/SpruceTree.php b/src/pocketmine/level/generator/object/SpruceTree.php index cb5df458c2..0966d15156 100644 --- a/src/pocketmine/level/generator/object/SpruceTree.php +++ b/src/pocketmine/level/generator/object/SpruceTree.php @@ -34,7 +34,7 @@ use function abs; class SpruceTree extends Tree{ public function __construct(){ - parent::__construct(BlockFactory::get(Block::LOG, TreeType::$SPRUCE->getMagicNumber()), BlockFactory::get(Block::LEAVES, TreeType::$SPRUCE->getMagicNumber()), 10); + parent::__construct(BlockFactory::get(Block::LOG, TreeType::SPRUCE()->getMagicNumber()), BlockFactory::get(Block::LEAVES, TreeType::SPRUCE()->getMagicNumber()), 10); } protected function generateChunkHeight(Random $random) : int{ diff --git a/src/pocketmine/level/generator/object/Tree.php b/src/pocketmine/level/generator/object/Tree.php index 7074c3b33c..202df28271 100644 --- a/src/pocketmine/level/generator/object/Tree.php +++ b/src/pocketmine/level/generator/object/Tree.php @@ -62,18 +62,18 @@ abstract class Tree{ public static function growTree(ChunkManager $level, int $x, int $y, int $z, Random $random, ?TreeType $type = null) : void{ /** @var null|Tree $tree */ $tree = null; - $type = $type ?? TreeType::$OAK; - if($type === TreeType::$SPRUCE){ + $type = $type ?? TreeType::OAK(); + if($type === TreeType::SPRUCE()){ $tree = new SpruceTree(); - }elseif($type === TreeType::$BIRCH){ + }elseif($type === TreeType::BIRCH()){ if($random->nextBoundedInt(39) === 0){ $tree = new BirchTree(true); }else{ $tree = new BirchTree(); } - }elseif($type === TreeType::$JUNGLE){ + }elseif($type === TreeType::JUNGLE()){ $tree = new JungleTree(); - }elseif($type === TreeType::$OAK){ //default + }elseif($type === TreeType::OAK()){ //default $tree = new OakTree(); /*if($random->nextRange(0, 9) === 0){ $tree = new BigTree(); diff --git a/src/pocketmine/level/generator/populator/Tree.php b/src/pocketmine/level/generator/populator/Tree.php index e095f271c5..a9e646fb2c 100644 --- a/src/pocketmine/level/generator/populator/Tree.php +++ b/src/pocketmine/level/generator/populator/Tree.php @@ -42,7 +42,7 @@ class Tree extends Populator{ * @param TreeType|null $type default oak */ public function __construct(?TreeType $type = null){ - $this->type = $type ?? TreeType::$OAK; + $this->type = $type ?? TreeType::OAK(); } public function setRandomAmount(int $amount) : void{ diff --git a/src/pocketmine/tile/Banner.php b/src/pocketmine/tile/Banner.php index f1958e281c..c423d2e71b 100644 --- a/src/pocketmine/tile/Banner.php +++ b/src/pocketmine/tile/Banner.php @@ -93,7 +93,7 @@ class Banner extends Spawnable implements Nameable{ private $patterns; public function __construct(Level $level, Vector3 $pos){ - $this->baseColor = DyeColor::$BLACK; + $this->baseColor = DyeColor::BLACK(); $this->patterns = new ListTag(self::TAG_PATTERNS); parent::__construct($level, $pos); } diff --git a/src/pocketmine/tile/Bed.php b/src/pocketmine/tile/Bed.php index 4fc8669357..692a6f4509 100644 --- a/src/pocketmine/tile/Bed.php +++ b/src/pocketmine/tile/Bed.php @@ -35,7 +35,7 @@ class Bed extends Spawnable{ private $color; public function __construct(Level $level, Vector3 $pos){ - $this->color = DyeColor::$RED; + $this->color = DyeColor::RED(); parent::__construct($level, $pos); } From 2c8a065b947a91789d585a66b841cb7490db0a15 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Feb 2019 11:14:07 +0000 Subject: [PATCH 0497/3224] Standardise SNAKE_CASE for surrogate enums --- src/pocketmine/Player.php | 8 ++--- src/pocketmine/block/BlockFactory.php | 2 +- src/pocketmine/block/Slab.php | 42 ++++++++++++------------- src/pocketmine/block/utils/SlabType.php | 6 ++-- src/pocketmine/item/Bow.php | 8 ++--- src/pocketmine/item/Bucket.php | 6 ++-- src/pocketmine/item/FlintSteel.php | 4 +-- src/pocketmine/item/Item.php | 6 ++-- src/pocketmine/item/ItemUseResult.php | 6 ++-- src/pocketmine/item/LiquidBucket.php | 8 ++--- src/pocketmine/item/PaintingItem.php | 8 ++--- src/pocketmine/item/ProjectileItem.php | 4 +-- src/pocketmine/item/SpawnEgg.php | 2 +- src/pocketmine/level/Level.php | 4 +-- 14 files changed, 57 insertions(+), 57 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 012d47258c..9197571058 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2063,12 +2063,12 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $result = $item->onClickAir($this, $directionVector); - if($result === ItemUseResult::success()){ + if($result === ItemUseResult::SUCCESS()){ $this->resetItemCooldown($item); if($this->isSurvival()){ $this->inventory->setItemInHand($item); } - }elseif($result === ItemUseResult::fail()){ + }elseif($result === ItemUseResult::FAIL()){ $this->inventory->sendHeldItem($this); } @@ -2125,12 +2125,12 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return false; } $result = $item->onReleaseUsing($this); - if($result === ItemUseResult::success()){ + if($result === ItemUseResult::SUCCESS()){ $this->resetItemCooldown($item); $this->inventory->setItemInHand($item); return true; } - if($result === ItemUseResult::fail()){ + if($result === ItemUseResult::FAIL()){ $this->inventory->sendContents($this); return true; } diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 77761361e4..11643f7ccf 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -375,7 +375,7 @@ class BlockFactory{ } foreach($slabTypes as $type){ self::register($type); - self::register((clone $type)->setSlabType(SlabType::double())); //flattening hack + self::register((clone $type)->setSlabType(SlabType::DOUBLE())); //flattening hack } static $wallTypes = [ diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index 1b34e5f5d3..92cb7d7919 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -40,23 +40,23 @@ abstract class Slab extends Transparent{ public function __construct(int $id, int $doubleId, int $variant = 0, ?string $name = null){ parent::__construct($id, $variant, $name . " Slab", $id); $this->doubleId = $doubleId; - $this->slabType = SlabType::bottom(); + $this->slabType = SlabType::BOTTOM(); } public function getId() : int{ - return $this->slabType === SlabType::double() ? $this->doubleId : parent::getId(); + return $this->slabType === SlabType::DOUBLE() ? $this->doubleId : parent::getId(); } protected function writeStateToMeta() : int{ - if($this->slabType !== SlabType::double()){ - return ($this->slabType === SlabType::top() ? 0x08 : 0); + if($this->slabType !== SlabType::DOUBLE()){ + return ($this->slabType === SlabType::TOP() ? 0x08 : 0); } return 0; } public function readStateFromMeta(int $meta) : void{ - if($this->slabType !== SlabType::double()){ - $this->slabType = ($meta & 0x08) !== 0 ? SlabType::top() : SlabType::bottom(); + if($this->slabType !== SlabType::DOUBLE()){ + $this->slabType = ($meta & 0x08) !== 0 ? SlabType::TOP() : SlabType::BOTTOM(); } } @@ -65,7 +65,7 @@ abstract class Slab extends Transparent{ } public function isTransparent() : bool{ - return $this->slabType !== SlabType::double(); + return $this->slabType !== SlabType::DOUBLE(); } /** @@ -92,8 +92,8 @@ abstract class Slab extends Transparent{ return true; } - if($blockReplace instanceof Slab and $blockReplace->slabType !== SlabType::double() and $blockReplace->isSameType($this)){ - if($blockReplace->slabType === SlabType::top()){ //Trying to combine with top slab + if($blockReplace instanceof Slab and $blockReplace->slabType !== SlabType::DOUBLE() and $blockReplace->isSameType($this)){ + if($blockReplace->slabType === SlabType::TOP()){ //Trying to combine with top slab return $clickVector->y <= 0.5 or (!$isClickedBlock and $face === Facing::UP); }else{ return $clickVector->y >= 0.5 or (!$isClickedBlock and $face === Facing::DOWN); @@ -106,35 +106,35 @@ abstract class Slab extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ /* note these conditions can't be merged, since one targets clicked and the other replace */ - if($blockClicked instanceof Slab and $blockClicked->slabType !== SlabType::double() and $blockClicked->isSameType($this) and ( - ($face === Facing::DOWN and $blockClicked->slabType === SlabType::top()) or - ($face === Facing::UP and $blockClicked->slabType === SlabType::bottom()) + if($blockClicked instanceof Slab and $blockClicked->slabType !== SlabType::DOUBLE() and $blockClicked->isSameType($this) and ( + ($face === Facing::DOWN and $blockClicked->slabType === SlabType::TOP()) or + ($face === Facing::UP and $blockClicked->slabType === SlabType::BOTTOM()) )){ - $this->slabType = SlabType::double(); + $this->slabType = SlabType::DOUBLE(); return $this->level->setBlock($blockClicked, $this); } - if($blockReplace instanceof Slab and $blockReplace->slabType !== SlabType::double() and $blockReplace->isSameType($this) and ( - ($blockReplace->slabType === SlabType::top() and ($clickVector->y <= 0.5 or $face === Facing::UP)) or - ($blockReplace->slabType === SlabType::bottom() and ($clickVector->y >= 0.5 or $face === Facing::DOWN)) + if($blockReplace instanceof Slab and $blockReplace->slabType !== SlabType::DOUBLE() and $blockReplace->isSameType($this) and ( + ($blockReplace->slabType === SlabType::TOP() and ($clickVector->y <= 0.5 or $face === Facing::UP)) or + ($blockReplace->slabType === SlabType::BOTTOM() and ($clickVector->y >= 0.5 or $face === Facing::DOWN)) )){ //Clicked in empty half of existing slab - $this->slabType = SlabType::double(); + $this->slabType = SlabType::DOUBLE(); }else{ - $this->slabType = (($face !== Facing::UP && $clickVector->y > 0.5) || $face === Facing::DOWN) ? SlabType::top() : SlabType::bottom(); + $this->slabType = (($face !== Facing::UP && $clickVector->y > 0.5) || $face === Facing::DOWN) ? SlabType::TOP() : SlabType::BOTTOM(); } return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - if($this->slabType === SlabType::double()){ + if($this->slabType === SlabType::DOUBLE()){ return parent::recalculateBoundingBox(); } - return AxisAlignedBB::one()->trim($this->slabType === SlabType::top() ? Facing::DOWN : Facing::UP, 0.5); + return AxisAlignedBB::one()->trim($this->slabType === SlabType::TOP() ? Facing::DOWN : Facing::UP, 0.5); } public function getDropsForCompatibleTool(Item $item) : array{ - return [$this->getItem()->setCount($this->slabType === SlabType::double() ? 2 : 1)]; + return [$this->getItem()->setCount($this->slabType === SlabType::DOUBLE() ? 2 : 1)]; } } diff --git a/src/pocketmine/block/utils/SlabType.php b/src/pocketmine/block/utils/SlabType.php index e3ba9d0402..57fa535ca7 100644 --- a/src/pocketmine/block/utils/SlabType.php +++ b/src/pocketmine/block/utils/SlabType.php @@ -30,19 +30,19 @@ final class SlabType{ */ private $name; - public static function bottom() : self{ + public static function BOTTOM() : self{ /** @var SlabType $ret */ static $ret = null; return $ret ?? ($ret = new self("bottom")); } - public static function top() : self{ + public static function TOP() : self{ /** @var SlabType $ret */ static $ret = null; return $ret ?? ($ret = new self("top")); } - public static function double() : self{ + public static function DOUBLE() : self{ /** @var SlabType $ret */ static $ret = null; return $ret ?? ($ret = new self("double")); diff --git a/src/pocketmine/item/Bow.php b/src/pocketmine/item/Bow.php index ec694619de..f2aefa10d7 100644 --- a/src/pocketmine/item/Bow.php +++ b/src/pocketmine/item/Bow.php @@ -49,7 +49,7 @@ class Bow extends Tool{ public function onReleaseUsing(Player $player) : ItemUseResult{ if($player->isSurvival() and !$player->getInventory()->contains(ItemFactory::get(Item::ARROW, 0, 1))){ - return ItemUseResult::fail(); + return ItemUseResult::FAIL(); } $nbt = EntityFactory::createBaseNBT( @@ -92,7 +92,7 @@ class Bow extends Tool{ if($ev->isCancelled()){ $entity->flagForDespawn(); - return ItemUseResult::fail(); + return ItemUseResult::FAIL(); } $entity->setMotion($entity->getMotion()->multiply($ev->getForce())); @@ -102,7 +102,7 @@ class Bow extends Tool{ $projectileEv->call(); if($projectileEv->isCancelled()){ $ev->getProjectile()->flagForDespawn(); - return ItemUseResult::fail(); + return ItemUseResult::FAIL(); } $ev->getProjectile()->spawnToAll(); @@ -118,6 +118,6 @@ class Bow extends Tool{ $this->applyDamage(1); } - return ItemUseResult::success(); + return ItemUseResult::SUCCESS(); } } diff --git a/src/pocketmine/item/Bucket.php b/src/pocketmine/item/Bucket.php index 5a17c2de17..2b850f749b 100644 --- a/src/pocketmine/item/Bucket.php +++ b/src/pocketmine/item/Bucket.php @@ -58,12 +58,12 @@ class Bucket extends Item{ }else{ $player->getInventory()->addItem($ev->getItem()); } - return ItemUseResult::success(); + return ItemUseResult::SUCCESS(); } - return ItemUseResult::fail(); + return ItemUseResult::FAIL(); } - return ItemUseResult::none(); + return ItemUseResult::NONE(); } } diff --git a/src/pocketmine/item/FlintSteel.php b/src/pocketmine/item/FlintSteel.php index bb1d94dfd9..4bd735a7ea 100644 --- a/src/pocketmine/item/FlintSteel.php +++ b/src/pocketmine/item/FlintSteel.php @@ -44,10 +44,10 @@ class FlintSteel extends Tool{ $this->applyDamage(1); - return ItemUseResult::success(); + return ItemUseResult::SUCCESS(); } - return ItemUseResult::none(); + return ItemUseResult::NONE(); } public function getMaxDurability() : int{ diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 743ccb81b5..4f3ca5ff90 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -738,7 +738,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return ItemUseResult */ public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ - return ItemUseResult::none(); + return ItemUseResult::NONE(); } /** @@ -751,7 +751,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return ItemUseResult */ public function onClickAir(Player $player, Vector3 $directionVector) : ItemUseResult{ - return ItemUseResult::none(); + return ItemUseResult::NONE(); } /** @@ -763,7 +763,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return ItemUseResult */ public function onReleaseUsing(Player $player) : ItemUseResult{ - return ItemUseResult::none(); + return ItemUseResult::NONE(); } /** diff --git a/src/pocketmine/item/ItemUseResult.php b/src/pocketmine/item/ItemUseResult.php index 78b89802c1..90e8b4724f 100644 --- a/src/pocketmine/item/ItemUseResult.php +++ b/src/pocketmine/item/ItemUseResult.php @@ -36,7 +36,7 @@ final class ItemUseResult{ * * @return ItemUseResult */ - public static function none() : ItemUseResult{ + public static function NONE() : ItemUseResult{ return self::$NONE ?? (self::$NONE = new self()); } @@ -46,7 +46,7 @@ final class ItemUseResult{ * * @return ItemUseResult */ - public static function fail() : ItemUseResult{ + public static function FAIL() : ItemUseResult{ return self::$FAILED ?? (self::$FAILED = new self()); } @@ -55,7 +55,7 @@ final class ItemUseResult{ * * @return ItemUseResult */ - public static function success() : ItemUseResult{ + public static function SUCCESS() : ItemUseResult{ return self::$SUCCEEDED ?? (self::$SUCCEEDED = new self()); } diff --git a/src/pocketmine/item/LiquidBucket.php b/src/pocketmine/item/LiquidBucket.php index 21a76b45e6..f8d9eb5e5d 100644 --- a/src/pocketmine/item/LiquidBucket.php +++ b/src/pocketmine/item/LiquidBucket.php @@ -54,7 +54,7 @@ class LiquidBucket extends Item{ public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ if(!$blockReplace->canBeReplaced()){ - return ItemUseResult::none(); + return ItemUseResult::NONE(); } //TODO: move this to generic placement logic @@ -69,12 +69,12 @@ class LiquidBucket extends Item{ if($player->isSurvival()){ $player->getInventory()->setItemInHand($ev->getItem()); } - return ItemUseResult::success(); + return ItemUseResult::SUCCESS(); } - return ItemUseResult::fail(); + return ItemUseResult::FAIL(); } - return ItemUseResult::none(); + return ItemUseResult::NONE(); } } diff --git a/src/pocketmine/item/PaintingItem.php b/src/pocketmine/item/PaintingItem.php index 115a462dab..e577d9b49b 100644 --- a/src/pocketmine/item/PaintingItem.php +++ b/src/pocketmine/item/PaintingItem.php @@ -40,7 +40,7 @@ class PaintingItem extends Item{ public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ if(Facing::axis($face) === Facing::AXIS_Y){ - return ItemUseResult::none(); + return ItemUseResult::NONE(); } $motives = []; @@ -68,7 +68,7 @@ class PaintingItem extends Item{ } if(empty($motives)){ //No space available - return ItemUseResult::none(); + return ItemUseResult::NONE(); } /** @var PaintingMotive $motive */ @@ -83,7 +83,7 @@ class PaintingItem extends Item{ $direction = $directions[$face] ?? -1; if($direction === -1){ - return ItemUseResult::none(); + return ItemUseResult::NONE(); } $nbt = EntityFactory::createBaseNBT($blockReplace, null, $direction * 90, 0); @@ -99,6 +99,6 @@ class PaintingItem extends Item{ $entity->spawnToAll(); $player->getLevel()->broadcastLevelEvent($blockReplace->add(0.5, 0.5, 0.5), LevelEventPacket::EVENT_SOUND_ITEMFRAME_PLACE); //item frame and painting have the same sound - return ItemUseResult::success(); + return ItemUseResult::SUCCESS(); } } diff --git a/src/pocketmine/item/ProjectileItem.php b/src/pocketmine/item/ProjectileItem.php index 02b564d13c..4208434d74 100644 --- a/src/pocketmine/item/ProjectileItem.php +++ b/src/pocketmine/item/ProjectileItem.php @@ -68,7 +68,7 @@ abstract class ProjectileItem extends Item{ $projectileEv->call(); if($projectileEv->isCancelled()){ $projectile->flagForDespawn(); - return ItemUseResult::fail(); + return ItemUseResult::FAIL(); } $projectile->spawnToAll(); @@ -77,6 +77,6 @@ abstract class ProjectileItem extends Item{ $this->pop(); - return ItemUseResult::success(); + return ItemUseResult::SUCCESS(); } } diff --git a/src/pocketmine/item/SpawnEgg.php b/src/pocketmine/item/SpawnEgg.php index 3642809283..6fd053a1f1 100644 --- a/src/pocketmine/item/SpawnEgg.php +++ b/src/pocketmine/item/SpawnEgg.php @@ -61,6 +61,6 @@ class SpawnEgg extends Item{ $this->pop(); $entity->spawnToAll(); //TODO: what if the entity was marked for deletion? - return ItemUseResult::success(); + return ItemUseResult::SUCCESS(); } } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 297c067bde..274a0bdf68 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1798,8 +1798,8 @@ class Level implements ChunkManager, Metadatable{ if(!$player->isSneaking()){ $result = $item->onActivate($player, $blockReplace, $blockClicked, $face, $clickVector); - if($result !== ItemUseResult::none()){ - return $result === ItemUseResult::success(); + if($result !== ItemUseResult::NONE()){ + return $result === ItemUseResult::SUCCESS(); } } }else{ From 15d4201c3abbe4e483f5855bf25c41558508a3fa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Feb 2019 11:16:08 +0000 Subject: [PATCH 0498/3224] Fixed tests broken by 88c4b836f09278a2d81a14356ff3c29ce465de1d --- tests/phpunit/block/BlockTest.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index d092023708..6c1ac5a2f3 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -37,7 +37,7 @@ class BlockTest extends TestCase{ public function testAccidentalOverrideBlock() : void{ $block = new MyCustomBlock(); $this->expectException(\InvalidArgumentException::class); - BlockFactory::registerBlock($block); + BlockFactory::register($block); } /** @@ -45,7 +45,7 @@ class BlockTest extends TestCase{ */ public function testDeliberateOverrideBlock() : void{ $block = new MyCustomBlock(); - BlockFactory::registerBlock($block, true); + BlockFactory::register($block, true); self::assertInstanceOf(MyCustomBlock::class, BlockFactory::get($block->getId())); } @@ -56,7 +56,7 @@ class BlockTest extends TestCase{ for($i = 0; $i < 256; ++$i){ if(!BlockFactory::isRegistered($i)){ $b = new StrangeNewBlock($i); - BlockFactory::registerBlock($b); + BlockFactory::register($b); self::assertInstanceOf(StrangeNewBlock::class, BlockFactory::get($b->getId())); return; } @@ -70,7 +70,7 @@ class BlockTest extends TestCase{ */ public function testRegisterIdTooLarge() : void{ self::expectException(\RuntimeException::class); - BlockFactory::registerBlock(new OutOfBoundsBlock(25555)); + BlockFactory::register(new OutOfBoundsBlock(25555)); } /** @@ -78,7 +78,7 @@ class BlockTest extends TestCase{ */ public function testRegisterIdTooSmall() : void{ self::expectException(\RuntimeException::class); - BlockFactory::registerBlock(new OutOfBoundsBlock(-1)); + BlockFactory::register(new OutOfBoundsBlock(-1)); } /** From 646fea5a4ecbbdf3f0cbfc590d874dedc1a7bfc0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Feb 2019 12:03:10 +0000 Subject: [PATCH 0499/3224] Effect: Introduce a bunch of static getters, change a bunch of API to use objects This introduces static getters for every currently-known effect type. At some point in the near future, the magic number constants (which are really network IDs, by the way) will disappear. Migrating: - If you used constants (like any sensible person would): for the most part it's just a case of adding a () anywhere you used an Effect constant. - If you hardcoded magic numbers: ... well, have fun fixing your code, and I reserve the right to say "I told you so" :) This achieves multiple goals: 1) creating an EffectInstance for application is much less verbose (see diff for examples, especially the Potion class) 2) plugin devs cannot use magic numbers to apply effects anymore and are forced to use type-safe objects. :) This is a warning shot for plugin devs who use magic numbers. More changes like this are coming in the not-too-distant future. --- src/pocketmine/Player.php | 2 +- .../command/defaults/EffectCommand.php | 6 +- src/pocketmine/entity/Human.php | 6 +- src/pocketmine/entity/Living.php | 48 ++++---- src/pocketmine/entity/effect/Effect.php | 108 ++++++++++++++++++ .../entity/EntityDamageByEntityEvent.php | 8 +- src/pocketmine/item/GoldenApple.php | 4 +- src/pocketmine/item/GoldenAppleEnchanted.php | 8 +- src/pocketmine/item/PoisonousPotato.php | 2 +- src/pocketmine/item/Potion.php | 64 +++++------ src/pocketmine/item/Pufferfish.php | 6 +- src/pocketmine/item/RawChicken.php | 2 +- src/pocketmine/item/RottenFlesh.php | 2 +- src/pocketmine/item/SpiderEye.php | 2 +- 14 files changed, 190 insertions(+), 78 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 9197571058..05ae682a4a 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2341,7 +2341,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $ev->setModifier($meleeEnchantmentDamage, EntityDamageEvent::MODIFIER_WEAPON_ENCHANTMENTS); - if(!$this->isSprinting() and !$this->isFlying() and $this->fallDistance > 0 and !$this->hasEffect(Effect::BLINDNESS) and !$this->isUnderwater()){ + if(!$this->isSprinting() and !$this->isFlying() and $this->fallDistance > 0 and !$this->hasEffect(Effect::BLINDNESS()) and !$this->isUnderwater()){ $ev->setModifier($ev->getFinalDamage() / 2, EntityDamageEvent::MODIFIER_CRITICAL); } diff --git a/src/pocketmine/command/defaults/EffectCommand.php b/src/pocketmine/command/defaults/EffectCommand.php index 5afb3895bb..58a7e8fa37 100644 --- a/src/pocketmine/command/defaults/EffectCommand.php +++ b/src/pocketmine/command/defaults/EffectCommand.php @@ -62,7 +62,7 @@ class EffectCommand extends VanillaCommand{ if(strtolower($args[1]) === "clear"){ foreach($player->getEffects() as $effect){ - $player->removeEffect($effect->getId()); + $player->removeEffect($effect->getType()); } $sender->sendMessage(new TranslationContainer("commands.effect.success.removed.all", [$player->getDisplayName()])); @@ -107,7 +107,7 @@ class EffectCommand extends VanillaCommand{ } if($duration === 0){ - if(!$player->hasEffect($effect->getId())){ + if(!$player->hasEffect($effect)){ if(count($player->getEffects()) === 0){ $sender->sendMessage(new TranslationContainer("commands.effect.failure.notActive.all", [$player->getDisplayName()])); }else{ @@ -116,7 +116,7 @@ class EffectCommand extends VanillaCommand{ return true; } - $player->removeEffect($effect->getId()); + $player->removeEffect($effect); $sender->sendMessage(new TranslationContainer("commands.effect.success.removed", [$effect->getName(), $player->getDisplayName()])); }else{ $instance = new EffectInstance($effect, $duration, $amplification, $visible); diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 6a814f7124..110e6e9a9a 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -765,9 +765,9 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ if($totemModifier < 0){ //Totem prevented death $this->removeAllEffects(); - $this->addEffect(new EffectInstance(Effect::getEffect(Effect::REGENERATION), 40 * 20, 1)); - $this->addEffect(new EffectInstance(Effect::getEffect(Effect::FIRE_RESISTANCE), 40 * 20, 1)); - $this->addEffect(new EffectInstance(Effect::getEffect(Effect::ABSORPTION), 5 * 20, 1)); + $this->addEffect(new EffectInstance(Effect::REGENERATION(), 40 * 20, 1)); + $this->addEffect(new EffectInstance(Effect::FIRE_RESISTANCE(), 40 * 20, 1)); + $this->addEffect(new EffectInstance(Effect::ABSORPTION(), 5 * 20, 1)); $this->broadcastEntityEvent(EntityEventPacket::CONSUME_TOTEM); $this->level->broadcastLevelEvent($this->add(0, $this->eyeHeight, 0), LevelEventPacket::EVENT_SOUND_TOTEM); diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 1bae0d5432..deb15c58ac 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -65,6 +65,7 @@ use function max; use function min; use function mt_getrandmax; use function mt_rand; +use function spl_object_id; use function sqrt; use const M_PI; @@ -212,18 +213,19 @@ abstract class Living extends Entity implements Damageable{ */ public function removeAllEffects() : void{ foreach($this->effects as $effect){ - $this->removeEffect($effect->getId()); + $this->removeEffect($effect->getType()); } } /** * Removes the effect with the specified ID from the mob. * - * @param int $effectId + * @param Effect $effectType */ - public function removeEffect(int $effectId) : void{ - if(isset($this->effects[$effectId])){ - $effect = $this->effects[$effectId]; + public function removeEffect(Effect $effectType) : void{ + $index = spl_object_id($effectType); + if(isset($this->effects[$index])){ + $effect = $this->effects[$index]; $hasExpired = $effect->hasExpired(); $ev = new EntityEffectRemoveEvent($this, $effect); $ev->call(); @@ -234,7 +236,7 @@ abstract class Living extends Entity implements Damageable{ return; } - unset($this->effects[$effectId]); + unset($this->effects[$index]); $effect->getType()->remove($this, $effect); $this->sendEffectRemove($effect); @@ -246,23 +248,23 @@ abstract class Living extends Entity implements Damageable{ * Returns the effect instance active on this entity with the specified ID, or null if the mob does not have the * effect. * - * @param int $effectId + * @param Effect $effect * * @return EffectInstance|null */ - public function getEffect(int $effectId) : ?EffectInstance{ - return $this->effects[$effectId] ?? null; + public function getEffect(Effect $effect) : ?EffectInstance{ + return $this->effects[spl_object_id($effect)] ?? null; } /** * Returns whether the specified effect is active on the mob. * - * @param int $effectId + * @param Effect $effect * * @return bool */ - public function hasEffect(int $effectId) : bool{ - return isset($this->effects[$effectId]); + public function hasEffect(Effect $effect) : bool{ + return isset($this->effects[spl_object_id($effect)]); } /** @@ -286,8 +288,10 @@ abstract class Living extends Entity implements Damageable{ $oldEffect = null; $cancelled = false; - if(isset($this->effects[$effect->getId()])){ - $oldEffect = $this->effects[$effect->getId()]; + $type = $effect->getType(); + $index = spl_object_id($type); + if(isset($this->effects[$index])){ + $oldEffect = $this->effects[$index]; if( abs($effect->getAmplifier()) < $oldEffect->getAmplifier() or (abs($effect->getAmplifier()) === abs($oldEffect->getAmplifier()) and $effect->getDuration() < $oldEffect->getDuration()) @@ -311,7 +315,7 @@ abstract class Living extends Entity implements Damageable{ $effect->getType()->add($this, $effect); $this->sendEffectAdd($effect, $oldEffect !== null); - $this->effects[$effect->getId()] = $effect; + $this->effects[$index] = $effect; $this->recalculateEffectColor(); @@ -398,7 +402,7 @@ abstract class Living extends Entity implements Damageable{ * @return float */ public function getJumpVelocity() : float{ - return $this->jumpVelocity + ($this->hasEffect(Effect::JUMP) ? ($this->getEffect(Effect::JUMP)->getEffectLevel() / 10) : 0); + return $this->jumpVelocity + ($this->hasEffect(Effect::JUMP_BOOST()) ? ($this->getEffect(Effect::JUMP_BOOST())->getEffectLevel() / 10) : 0); } /** @@ -411,7 +415,7 @@ abstract class Living extends Entity implements Damageable{ } public function fall(float $fallDistance) : void{ - $damage = ceil($fallDistance - 3 - ($this->hasEffect(Effect::JUMP) ? $this->getEffect(Effect::JUMP)->getEffectLevel() : 0)); + $damage = ceil($fallDistance - 3 - ($this->hasEffect(Effect::JUMP_BOOST()) ? $this->getEffect(Effect::JUMP_BOOST())->getEffectLevel() : 0)); if($damage > 0){ $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FALL, $damage); $this->attack($ev); @@ -474,8 +478,8 @@ abstract class Living extends Entity implements Damageable{ } $cause = $source->getCause(); - if($this->hasEffect(Effect::DAMAGE_RESISTANCE) and $cause !== EntityDamageEvent::CAUSE_VOID and $cause !== EntityDamageEvent::CAUSE_SUICIDE){ - $source->setModifier(-$source->getFinalDamage() * min(1, 0.2 * $this->getEffect(Effect::DAMAGE_RESISTANCE)->getEffectLevel()), EntityDamageEvent::MODIFIER_RESISTANCE); + if($this->hasEffect(Effect::RESISTANCE()) and $cause !== EntityDamageEvent::CAUSE_VOID and $cause !== EntityDamageEvent::CAUSE_SUICIDE){ + $source->setModifier(-$source->getFinalDamage() * min(1, 0.2 * $this->getEffect(Effect::RESISTANCE())->getEffectLevel()), EntityDamageEvent::MODIFIER_RESISTANCE); } $totalEpf = 0; @@ -555,7 +559,7 @@ abstract class Living extends Entity implements Damageable{ } } - if($this->hasEffect(Effect::FIRE_RESISTANCE) and ( + if($this->hasEffect(Effect::FIRE_RESISTANCE()) and ( $source->getCause() === EntityDamageEvent::CAUSE_FIRE or $source->getCause() === EntityDamageEvent::CAUSE_FIRE_TICK or $source->getCause() === EntityDamageEvent::CAUSE_LAVA @@ -714,7 +718,7 @@ abstract class Living extends Entity implements Damageable{ } $instance->decreaseDuration($tickDiff); if($instance->hasExpired()){ - $this->removeEffect($instance->getId()); + $this->removeEffect($instance->getType()); } } @@ -765,7 +769,7 @@ abstract class Living extends Entity implements Damageable{ * @return bool */ public function canBreathe() : bool{ - return $this->hasEffect(Effect::WATER_BREATHING) or $this->hasEffect(Effect::CONDUIT_POWER) or !$this->isUnderwater(); + return $this->hasEffect(Effect::WATER_BREATHING()) or $this->hasEffect(Effect::CONDUIT_POWER()) or !$this->isUnderwater(); } /** diff --git a/src/pocketmine/entity/effect/Effect.php b/src/pocketmine/entity/effect/Effect.php index f6d7466f34..8a1044fe89 100644 --- a/src/pocketmine/entity/effect/Effect.php +++ b/src/pocketmine/entity/effect/Effect.php @@ -31,6 +31,8 @@ use function defined; use function strtoupper; class Effect{ + + //TODO: remove our dependence on these magic numbers public const SPEED = 1; public const SLOWNESS = 2; public const HASTE = 3; @@ -90,6 +92,112 @@ class Effect{ self::registerEffect(new Effect(Effect::CONDUIT_POWER, "%potion.conduitPower", new Color(0x1d, 0xc2, 0xd1))); } + /* auto-generated code */ + + public static function ABSORPTION() : Effect{ + return self::getEffect(Effect::ABSORPTION); + } + + public static function BLINDNESS() : Effect{ + return self::getEffect(Effect::BLINDNESS); + } + + public static function CONDUIT_POWER() : Effect{ + return self::getEffect(Effect::CONDUIT_POWER); + } + + public static function FATAL_POISON() : Effect{ + return self::getEffect(Effect::FATAL_POISON); + } + + public static function FIRE_RESISTANCE() : Effect{ + return self::getEffect(Effect::FIRE_RESISTANCE); + } + + public static function HASTE() : Effect{ + return self::getEffect(Effect::HASTE); + } + + public static function HEALTH_BOOST() : Effect{ + return self::getEffect(Effect::HEALTH_BOOST); + } + + public static function HUNGER() : Effect{ + return self::getEffect(Effect::HUNGER); + } + + public static function INSTANT_DAMAGE() : Effect{ + return self::getEffect(Effect::INSTANT_DAMAGE); + } + + public static function INSTANT_HEALTH() : Effect{ + return self::getEffect(Effect::INSTANT_HEALTH); + } + + public static function INVISIBILITY() : Effect{ + return self::getEffect(Effect::INVISIBILITY); + } + + public static function JUMP_BOOST() : Effect{ + return self::getEffect(Effect::JUMP_BOOST); + } + + public static function LEVITATION() : Effect{ + return self::getEffect(Effect::LEVITATION); + } + + public static function MINING_FATIGUE() : Effect{ + return self::getEffect(Effect::MINING_FATIGUE); + } + + public static function NAUSEA() : Effect{ + return self::getEffect(Effect::NAUSEA); + } + + public static function NIGHT_VISION() : Effect{ + return self::getEffect(Effect::NIGHT_VISION); + } + + public static function POISON() : Effect{ + return self::getEffect(Effect::POISON); + } + + public static function REGENERATION() : Effect{ + return self::getEffect(Effect::REGENERATION); + } + + public static function RESISTANCE() : Effect{ + return self::getEffect(Effect::RESISTANCE); + } + + public static function SATURATION() : Effect{ + return self::getEffect(Effect::SATURATION); + } + + public static function SLOWNESS() : Effect{ + return self::getEffect(Effect::SLOWNESS); + } + + public static function SPEED() : Effect{ + return self::getEffect(Effect::SPEED); + } + + public static function STRENGTH() : Effect{ + return self::getEffect(Effect::STRENGTH); + } + + public static function WATER_BREATHING() : Effect{ + return self::getEffect(Effect::WATER_BREATHING); + } + + public static function WEAKNESS() : Effect{ + return self::getEffect(Effect::WEAKNESS); + } + + public static function WITHER() : Effect{ + return self::getEffect(Effect::WITHER); + } + /** * @param Effect $effect */ diff --git a/src/pocketmine/event/entity/EntityDamageByEntityEvent.php b/src/pocketmine/event/entity/EntityDamageByEntityEvent.php index d8f0212021..893c2672e7 100644 --- a/src/pocketmine/event/entity/EntityDamageByEntityEvent.php +++ b/src/pocketmine/event/entity/EntityDamageByEntityEvent.php @@ -53,12 +53,12 @@ class EntityDamageByEntityEvent extends EntityDamageEvent{ protected function addAttackerModifiers(Entity $damager) : void{ if($damager instanceof Living){ //TODO: move this to entity classes - if($damager->hasEffect(Effect::STRENGTH)){ - $this->setModifier($this->getBaseDamage() * 0.3 * $damager->getEffect(Effect::STRENGTH)->getEffectLevel(), self::MODIFIER_STRENGTH); + if($damager->hasEffect(Effect::STRENGTH())){ + $this->setModifier($this->getBaseDamage() * 0.3 * $damager->getEffect(Effect::STRENGTH())->getEffectLevel(), self::MODIFIER_STRENGTH); } - if($damager->hasEffect(Effect::WEAKNESS)){ - $this->setModifier(-($this->getBaseDamage() * 0.2 * $damager->getEffect(Effect::WEAKNESS)->getEffectLevel()), self::MODIFIER_WEAKNESS); + if($damager->hasEffect(Effect::WEAKNESS())){ + $this->setModifier(-($this->getBaseDamage() * 0.2 * $damager->getEffect(Effect::WEAKNESS())->getEffectLevel()), self::MODIFIER_WEAKNESS); } } } diff --git a/src/pocketmine/item/GoldenApple.php b/src/pocketmine/item/GoldenApple.php index edec3b2b3e..3e4482b218 100644 --- a/src/pocketmine/item/GoldenApple.php +++ b/src/pocketmine/item/GoldenApple.php @@ -46,8 +46,8 @@ class GoldenApple extends Food{ public function getAdditionalEffects() : array{ return [ - new EffectInstance(Effect::getEffect(Effect::REGENERATION), 100, 1), - new EffectInstance(Effect::getEffect(Effect::ABSORPTION), 2400) + new EffectInstance(Effect::REGENERATION(), 100, 1), + new EffectInstance(Effect::ABSORPTION(), 2400) ]; } } diff --git a/src/pocketmine/item/GoldenAppleEnchanted.php b/src/pocketmine/item/GoldenAppleEnchanted.php index 120d67871d..13fe4ee4c1 100644 --- a/src/pocketmine/item/GoldenAppleEnchanted.php +++ b/src/pocketmine/item/GoldenAppleEnchanted.php @@ -34,10 +34,10 @@ class GoldenAppleEnchanted extends GoldenApple{ public function getAdditionalEffects() : array{ return [ - new EffectInstance(Effect::getEffect(Effect::REGENERATION), 600, 4), - new EffectInstance(Effect::getEffect(Effect::ABSORPTION), 2400, 3), - new EffectInstance(Effect::getEffect(Effect::RESISTANCE), 6000), - new EffectInstance(Effect::getEffect(Effect::FIRE_RESISTANCE), 6000) + new EffectInstance(Effect::REGENERATION(), 600, 4), + new EffectInstance(Effect::ABSORPTION(), 2400, 3), + new EffectInstance(Effect::RESISTANCE(), 6000), + new EffectInstance(Effect::FIRE_RESISTANCE(), 6000) ]; } } diff --git a/src/pocketmine/item/PoisonousPotato.php b/src/pocketmine/item/PoisonousPotato.php index 7f6e1203dd..f869884f70 100644 --- a/src/pocketmine/item/PoisonousPotato.php +++ b/src/pocketmine/item/PoisonousPotato.php @@ -43,7 +43,7 @@ class PoisonousPotato extends Food{ public function getAdditionalEffects() : array{ if(mt_rand(0, 100) > 40){ return [ - new EffectInstance(Effect::getEffect(Effect::POISON), 100) + new EffectInstance(Effect::POISON(), 100) ]; } return []; diff --git a/src/pocketmine/item/Potion.php b/src/pocketmine/item/Potion.php index 40b8293e37..35c2b96b8e 100644 --- a/src/pocketmine/item/Potion.php +++ b/src/pocketmine/item/Potion.php @@ -124,131 +124,131 @@ class Potion extends Item implements Consumable{ return []; case self::NIGHT_VISION: return [ - new EffectInstance(Effect::getEffect(Effect::NIGHT_VISION), 3600) + new EffectInstance(Effect::NIGHT_VISION(), 3600) ]; case self::LONG_NIGHT_VISION: return [ - new EffectInstance(Effect::getEffect(Effect::NIGHT_VISION), 9600) + new EffectInstance(Effect::NIGHT_VISION(), 9600) ]; case self::INVISIBILITY: return [ - new EffectInstance(Effect::getEffect(Effect::INVISIBILITY), 3600) + new EffectInstance(Effect::INVISIBILITY(), 3600) ]; case self::LONG_INVISIBILITY: return [ - new EffectInstance(Effect::getEffect(Effect::INVISIBILITY), 9600) + new EffectInstance(Effect::INVISIBILITY(), 9600) ]; case self::LEAPING: return [ - new EffectInstance(Effect::getEffect(Effect::JUMP_BOOST), 3600) + new EffectInstance(Effect::JUMP_BOOST(), 3600) ]; case self::LONG_LEAPING: return [ - new EffectInstance(Effect::getEffect(Effect::JUMP_BOOST), 9600) + new EffectInstance(Effect::JUMP_BOOST(), 9600) ]; case self::STRONG_LEAPING: return [ - new EffectInstance(Effect::getEffect(Effect::JUMP_BOOST), 1800, 1) + new EffectInstance(Effect::JUMP_BOOST(), 1800, 1) ]; case self::FIRE_RESISTANCE: return [ - new EffectInstance(Effect::getEffect(Effect::FIRE_RESISTANCE), 3600) + new EffectInstance(Effect::FIRE_RESISTANCE(), 3600) ]; case self::LONG_FIRE_RESISTANCE: return [ - new EffectInstance(Effect::getEffect(Effect::FIRE_RESISTANCE), 9600) + new EffectInstance(Effect::FIRE_RESISTANCE(), 9600) ]; case self::SWIFTNESS: return [ - new EffectInstance(Effect::getEffect(Effect::SPEED), 3600) + new EffectInstance(Effect::SPEED(), 3600) ]; case self::LONG_SWIFTNESS: return [ - new EffectInstance(Effect::getEffect(Effect::SPEED), 9600) + new EffectInstance(Effect::SPEED(), 9600) ]; case self::STRONG_SWIFTNESS: return [ - new EffectInstance(Effect::getEffect(Effect::SPEED), 1800, 1) + new EffectInstance(Effect::SPEED(), 1800, 1) ]; case self::SLOWNESS: return [ - new EffectInstance(Effect::getEffect(Effect::SLOWNESS), 1800) + new EffectInstance(Effect::SLOWNESS(), 1800) ]; case self::LONG_SLOWNESS: return [ - new EffectInstance(Effect::getEffect(Effect::SLOWNESS), 4800) + new EffectInstance(Effect::SLOWNESS(), 4800) ]; case self::WATER_BREATHING: return [ - new EffectInstance(Effect::getEffect(Effect::WATER_BREATHING), 3600) + new EffectInstance(Effect::WATER_BREATHING(), 3600) ]; case self::LONG_WATER_BREATHING: return [ - new EffectInstance(Effect::getEffect(Effect::WATER_BREATHING), 9600) + new EffectInstance(Effect::WATER_BREATHING(), 9600) ]; case self::HEALING: return [ - new EffectInstance(Effect::getEffect(Effect::INSTANT_HEALTH)) + new EffectInstance(Effect::INSTANT_HEALTH()) ]; case self::STRONG_HEALING: return [ - new EffectInstance(Effect::getEffect(Effect::INSTANT_HEALTH), null, 1) + new EffectInstance(Effect::INSTANT_HEALTH(), null, 1) ]; case self::HARMING: return [ - new EffectInstance(Effect::getEffect(Effect::INSTANT_DAMAGE)) + new EffectInstance(Effect::INSTANT_DAMAGE()) ]; case self::STRONG_HARMING: return [ - new EffectInstance(Effect::getEffect(Effect::INSTANT_DAMAGE), null, 1) + new EffectInstance(Effect::INSTANT_DAMAGE(), null, 1) ]; case self::POISON: return [ - new EffectInstance(Effect::getEffect(Effect::POISON), 900) + new EffectInstance(Effect::POISON(), 900) ]; case self::LONG_POISON: return [ - new EffectInstance(Effect::getEffect(Effect::POISON), 2400) + new EffectInstance(Effect::POISON(), 2400) ]; case self::STRONG_POISON: return [ - new EffectInstance(Effect::getEffect(Effect::POISON), 440, 1) + new EffectInstance(Effect::POISON(), 440, 1) ]; case self::REGENERATION: return [ - new EffectInstance(Effect::getEffect(Effect::REGENERATION), 900) + new EffectInstance(Effect::REGENERATION(), 900) ]; case self::LONG_REGENERATION: return [ - new EffectInstance(Effect::getEffect(Effect::REGENERATION), 2400) + new EffectInstance(Effect::REGENERATION(), 2400) ]; case self::STRONG_REGENERATION: return [ - new EffectInstance(Effect::getEffect(Effect::REGENERATION), 440, 1) + new EffectInstance(Effect::REGENERATION(), 440, 1) ]; case self::STRENGTH: return [ - new EffectInstance(Effect::getEffect(Effect::STRENGTH), 3600) + new EffectInstance(Effect::STRENGTH(), 3600) ]; case self::LONG_STRENGTH: return [ - new EffectInstance(Effect::getEffect(Effect::STRENGTH), 9600) + new EffectInstance(Effect::STRENGTH(), 9600) ]; case self::STRONG_STRENGTH: return [ - new EffectInstance(Effect::getEffect(Effect::STRENGTH), 1800, 1) + new EffectInstance(Effect::STRENGTH(), 1800, 1) ]; case self::WEAKNESS: return [ - new EffectInstance(Effect::getEffect(Effect::WEAKNESS), 1800) + new EffectInstance(Effect::WEAKNESS(), 1800) ]; case self::LONG_WEAKNESS: return [ - new EffectInstance(Effect::getEffect(Effect::WEAKNESS), 4800) + new EffectInstance(Effect::WEAKNESS(), 4800) ]; case self::WITHER: return [ - new EffectInstance(Effect::getEffect(Effect::WITHER), 800, 1) + new EffectInstance(Effect::WITHER(), 800, 1) ]; } diff --git a/src/pocketmine/item/Pufferfish.php b/src/pocketmine/item/Pufferfish.php index 78b3958065..3d14512564 100644 --- a/src/pocketmine/item/Pufferfish.php +++ b/src/pocketmine/item/Pufferfish.php @@ -41,9 +41,9 @@ class Pufferfish extends Food{ public function getAdditionalEffects() : array{ return [ - new EffectInstance(Effect::getEffect(Effect::HUNGER), 300, 2), - new EffectInstance(Effect::getEffect(Effect::POISON), 1200, 3), - new EffectInstance(Effect::getEffect(Effect::NAUSEA), 300, 1) + new EffectInstance(Effect::HUNGER(), 300, 2), + new EffectInstance(Effect::POISON(), 1200, 3), + new EffectInstance(Effect::NAUSEA(), 300, 1) ]; } } diff --git a/src/pocketmine/item/RawChicken.php b/src/pocketmine/item/RawChicken.php index 36e59357b5..ef9fd3949a 100644 --- a/src/pocketmine/item/RawChicken.php +++ b/src/pocketmine/item/RawChicken.php @@ -41,6 +41,6 @@ class RawChicken extends Food{ } public function getAdditionalEffects() : array{ - return mt_rand(0, 9) < 3 ? [new EffectInstance(Effect::getEffect(Effect::HUNGER), 600)] : []; + return mt_rand(0, 9) < 3 ? [new EffectInstance(Effect::HUNGER(), 600)] : []; } } diff --git a/src/pocketmine/item/RottenFlesh.php b/src/pocketmine/item/RottenFlesh.php index 03045f76a5..3b4677478f 100644 --- a/src/pocketmine/item/RottenFlesh.php +++ b/src/pocketmine/item/RottenFlesh.php @@ -44,7 +44,7 @@ class RottenFlesh extends Food{ public function getAdditionalEffects() : array{ if(lcg_value() <= 0.8){ return [ - new EffectInstance(Effect::getEffect(Effect::HUNGER), 600) + new EffectInstance(Effect::HUNGER(), 600) ]; } diff --git a/src/pocketmine/item/SpiderEye.php b/src/pocketmine/item/SpiderEye.php index 97b6ff10d9..cc8c4c4aa4 100644 --- a/src/pocketmine/item/SpiderEye.php +++ b/src/pocketmine/item/SpiderEye.php @@ -40,6 +40,6 @@ class SpiderEye extends Food{ } public function getAdditionalEffects() : array{ - return [new EffectInstance(Effect::getEffect(Effect::POISON), 80)]; + return [new EffectInstance(Effect::POISON(), 80)]; } } From 7170d9009dfdb31923a016302336ede987ca7e96 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Feb 2019 13:45:50 +0000 Subject: [PATCH 0500/3224] Enchantment: more static getters, firehose magic numbers This is similar in nature to 646fea5a4ecbbdf3f0cbfc590d874dedc1a7bfc0. On a side note: Migrating this way is a pain in the ass due to lack of types. What the heck is int supposed to mean?!?!?!?! At least if we wanted to go _back_ to magic numbers, it would be easy to locate everything with an Enchantment typehint... --- src/pocketmine/block/Block.php | 4 +- src/pocketmine/block/Ice.php | 2 +- src/pocketmine/block/TNT.php | 2 +- src/pocketmine/entity/Human.php | 6 +- src/pocketmine/entity/Living.php | 14 ++-- src/pocketmine/item/Armor.php | 2 +- src/pocketmine/item/Bow.php | 8 +- src/pocketmine/item/Durable.php | 2 +- src/pocketmine/item/Item.php | 24 +++--- src/pocketmine/item/Tool.php | 2 +- .../item/enchantment/Enchantment.php | 76 +++++++++++++++++++ 11 files changed, 111 insertions(+), 31 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 947d0d2a1b..18b4e37029 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -526,7 +526,7 @@ class Block extends Position implements BlockIds, Metadatable{ */ public function getDrops(Item $item) : array{ if($this->isCompatibleWithTool($item)){ - if($this->isAffectedBySilkTouch() and $item->hasEnchantment(Enchantment::SILK_TOUCH)){ + if($this->isAffectedBySilkTouch() and $item->hasEnchantment(Enchantment::SILK_TOUCH())){ return $this->getSilkTouchDrops($item); } @@ -566,7 +566,7 @@ class Block extends Position implements BlockIds, Metadatable{ * @return int */ public function getXpDropForTool(Item $item) : int{ - if($item->hasEnchantment(Enchantment::SILK_TOUCH) or !$this->isCompatibleWithTool($item)){ + if($item->hasEnchantment(Enchantment::SILK_TOUCH()) or !$this->isCompatibleWithTool($item)){ return 0; } diff --git a/src/pocketmine/block/Ice.php b/src/pocketmine/block/Ice.php index acd4fbd2af..f499ea5883 100644 --- a/src/pocketmine/block/Ice.php +++ b/src/pocketmine/block/Ice.php @@ -56,7 +56,7 @@ class Ice extends Transparent{ } public function onBreak(Item $item, Player $player = null) : bool{ - if(($player === null or $player->isSurvival()) and !$item->hasEnchantment(Enchantment::SILK_TOUCH)){ + if(($player === null or $player->isSurvival()) and !$item->hasEnchantment(Enchantment::SILK_TOUCH())){ return $this->getLevel()->setBlock($this, BlockFactory::get(Block::WATER)); } return parent::onBreak($item, $player); diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index 92b49c3747..84515ff816 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -55,7 +55,7 @@ class TNT extends Solid{ } public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($item instanceof FlintSteel or $item->hasEnchantment(Enchantment::FIRE_ASPECT)){ + if($item instanceof FlintSteel or $item->hasEnchantment(Enchantment::FIRE_ASPECT())){ if($item instanceof Durable){ $item->applyDamage(1); } diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 110e6e9a9a..9c21083d89 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -537,12 +537,12 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ /** @var Durable[] $equipment */ $equipment = []; - if(($item = $this->inventory->getItemInHand()) instanceof Durable and $item->hasEnchantment(Enchantment::MENDING)){ + if(($item = $this->inventory->getItemInHand()) instanceof Durable and $item->hasEnchantment(Enchantment::MENDING())){ $equipment[$mainHandIndex] = $item; } //TODO: check offhand foreach($this->armorInventory->getContents() as $k => $item){ - if($item instanceof Durable and $item->hasEnchantment(Enchantment::MENDING)){ + if($item instanceof Durable and $item->hasEnchantment(Enchantment::MENDING())){ $equipment[$k] = $item; } } @@ -784,7 +784,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ return array_filter(array_merge( $this->inventory !== null ? array_values($this->inventory->getContents()) : [], $this->armorInventory !== null ? array_values($this->armorInventory->getContents()) : [] - ), function(Item $item) : bool{ return !$item->hasEnchantment(Enchantment::VANISHING); }); + ), function(Item $item) : bool{ return !$item->hasEnchantment(Enchantment::VANISHING()); }); } public function saveNBT() : CompoundTag{ diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index deb15c58ac..cfb23b3373 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -441,14 +441,14 @@ abstract class Living extends Entity implements Damageable{ /** * Returns the highest level of the specified enchantment on any armour piece that the entity is currently wearing. * - * @param int $enchantmentId + * @param Enchantment $enchantment * * @return int */ - public function getHighestArmorEnchantmentLevel(int $enchantmentId) : int{ + public function getHighestArmorEnchantmentLevel(Enchantment $enchantment) : int{ $result = 0; foreach($this->armorInventory->getContents() as $item){ - $result = max($result, $item->getEnchantmentLevel($enchantmentId)); + $result = max($result, $item->getEnchantmentLevel($enchantment)); } return $result; @@ -462,7 +462,7 @@ abstract class Living extends Entity implements Damageable{ } public function setOnFire(int $seconds) : void{ - parent::setOnFire($seconds - (int) min($seconds, $seconds * $this->getHighestArmorEnchantmentLevel(Enchantment::FIRE_PROTECTION) * 0.15)); + parent::setOnFire($seconds - (int) min($seconds, $seconds * $this->getHighestArmorEnchantmentLevel(Enchantment::FIRE_PROTECTION()) * 0.15)); } /** @@ -507,7 +507,7 @@ abstract class Living extends Entity implements Damageable{ if($source instanceof EntityDamageByEntityEvent){ $damage = 0; foreach($this->armorInventory->getContents() as $k => $item){ - if($item instanceof Armor and ($thornsLevel = $item->getEnchantmentLevel(Enchantment::THORNS)) > 0){ + if($item instanceof Armor and ($thornsLevel = $item->getEnchantmentLevel(Enchantment::THORNS())) > 0){ if(mt_rand(0, 99) < $thornsLevel * 15){ $this->damageItem($item, 3); $damage += ($thornsLevel > 10 ? $thornsLevel - 10 : 1 + mt_rand(0, 3)); @@ -577,7 +577,7 @@ abstract class Living extends Entity implements Damageable{ //TODO: knockback should not just apply for entity damage sources //this doesn't matter for TNT right now because the PrimedTNT entity is considered the source, not the block. $base = $source->getKnockBack(); - $source->setKnockBack($base - min($base, $base * $this->getHighestArmorEnchantmentLevel(Enchantment::BLAST_PROTECTION) * 0.15)); + $source->setKnockBack($base - min($base, $base * $this->getHighestArmorEnchantmentLevel(Enchantment::BLAST_PROTECTION()) * 0.15)); } parent::attack($source); @@ -738,7 +738,7 @@ abstract class Living extends Entity implements Damageable{ if(!$this->canBreathe()){ $this->setBreathing(false); - if(($respirationLevel = $this->armorInventory->getHelmet()->getEnchantmentLevel(Enchantment::RESPIRATION)) <= 0 or + if(($respirationLevel = $this->armorInventory->getHelmet()->getEnchantmentLevel(Enchantment::RESPIRATION())) <= 0 or lcg_value() <= (1 / ($respirationLevel + 1)) ){ $ticks -= $tickDiff; diff --git a/src/pocketmine/item/Armor.php b/src/pocketmine/item/Armor.php index 076a5f8158..e5852f1634 100644 --- a/src/pocketmine/item/Armor.php +++ b/src/pocketmine/item/Armor.php @@ -84,7 +84,7 @@ abstract class Armor extends Durable{ } protected function getUnbreakingDamageReduction(int $amount) : int{ - if(($unbreakingLevel = $this->getEnchantmentLevel(Enchantment::UNBREAKING)) > 0){ + if(($unbreakingLevel = $this->getEnchantmentLevel(Enchantment::UNBREAKING())) > 0){ $negated = 0; $chance = 1 / ($unbreakingLevel + 1); diff --git a/src/pocketmine/item/Bow.php b/src/pocketmine/item/Bow.php index f2aefa10d7..4718e0408d 100644 --- a/src/pocketmine/item/Bow.php +++ b/src/pocketmine/item/Bow.php @@ -67,17 +67,17 @@ class Bow extends Tool{ /** @var ArrowEntity $entity */ $entity = EntityFactory::create(ArrowEntity::class, $player->getLevel(), $nbt, $player, $baseForce >= 1); - $infinity = $this->hasEnchantment(Enchantment::INFINITY); + $infinity = $this->hasEnchantment(Enchantment::INFINITY()); if($infinity){ $entity->setPickupMode(ArrowEntity::PICKUP_CREATIVE); } - if(($punchLevel = $this->getEnchantmentLevel(Enchantment::PUNCH)) > 0){ + if(($punchLevel = $this->getEnchantmentLevel(Enchantment::PUNCH())) > 0){ $entity->setPunchKnockback($punchLevel); } - if(($powerLevel = $this->getEnchantmentLevel(Enchantment::POWER)) > 0){ + if(($powerLevel = $this->getEnchantmentLevel(Enchantment::POWER())) > 0){ $entity->setBaseDamage($entity->getBaseDamage() + (($powerLevel + 1) / 2)); } - if($this->hasEnchantment(Enchantment::FLAME)){ + if($this->hasEnchantment(Enchantment::FLAME())){ $entity->setOnFire(intdiv($entity->getFireTicks(), 20) + 100); } $ev = new EntityShootBowEvent($player, $this, $entity, $baseForce * 3); diff --git a/src/pocketmine/item/Durable.php b/src/pocketmine/item/Durable.php index b3a47a25af..6cd8af7801 100644 --- a/src/pocketmine/item/Durable.php +++ b/src/pocketmine/item/Durable.php @@ -85,7 +85,7 @@ abstract class Durable extends Item{ } protected function getUnbreakingDamageReduction(int $amount) : int{ - if(($unbreakingLevel = $this->getEnchantmentLevel(Enchantment::UNBREAKING)) > 0){ + if(($unbreakingLevel = $this->getEnchantmentLevel(Enchantment::UNBREAKING())) > 0){ $negated = 0; $chance = 1 / ($unbreakingLevel + 1); diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 4f3ca5ff90..c5e409b0ec 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -249,16 +249,17 @@ class Item implements ItemIds, \JsonSerializable{ } /** - * @param int $id - * @param int $level + * @param Enchantment $enchantment + * @param int $level * * @return bool */ - public function hasEnchantment(int $id, int $level = -1) : bool{ + public function hasEnchantment(Enchantment $enchantment, int $level = -1) : bool{ $ench = $this->getNamedTagEntry(self::TAG_ENCH); if(!($ench instanceof ListTag)){ return false; } + $id = $enchantment->getId(); /** @var CompoundTag $entry */ foreach($ench as $entry){ @@ -271,16 +272,17 @@ class Item implements ItemIds, \JsonSerializable{ } /** - * @param int $id + * @param Enchantment $enchantment * * @return EnchantmentInstance|null */ - public function getEnchantment(int $id) : ?EnchantmentInstance{ + public function getEnchantment(Enchantment $enchantment) : ?EnchantmentInstance{ $ench = $this->getNamedTagEntry(self::TAG_ENCH); if(!($ench instanceof ListTag)){ return null; } + $id = $enchantment->getId(); /** @var CompoundTag $entry */ foreach($ench as $entry){ if($entry->getShort("id") === $id){ @@ -295,17 +297,18 @@ class Item implements ItemIds, \JsonSerializable{ } /** - * @param int $id - * @param int $level + * @param Enchantment $enchantment + * @param int $level * * @return Item */ - public function removeEnchantment(int $id, int $level = -1) : Item{ + public function removeEnchantment(Enchantment $enchantment, int $level = -1) : Item{ $ench = $this->getNamedTagEntry(self::TAG_ENCH); if(!($ench instanceof ListTag)){ return $this; } + $id = $enchantment->getId(); /** @var CompoundTag $entry */ foreach($ench as $k => $entry){ if($entry->getShort("id") === $id and ($level === -1 or $entry->getShort("lvl") === $level)){ @@ -390,14 +393,15 @@ class Item implements ItemIds, \JsonSerializable{ * Returns the level of the enchantment on this item with the specified ID, or 0 if the item does not have the * enchantment. * - * @param int $enchantmentId + * @param Enchantment $enchantment * * @return int */ - public function getEnchantmentLevel(int $enchantmentId) : int{ + public function getEnchantmentLevel(Enchantment $enchantment) : int{ $ench = $this->getNamedTag()->getListTag(self::TAG_ENCH); if($ench !== null){ /** @var CompoundTag $entry */ + $enchantmentId = $enchantment->getId(); foreach($ench as $entry){ if($entry->getShort("id") === $enchantmentId){ return $entry->getShort("lvl"); diff --git a/src/pocketmine/item/Tool.php b/src/pocketmine/item/Tool.php index b0f3b1be0c..6671b05c20 100644 --- a/src/pocketmine/item/Tool.php +++ b/src/pocketmine/item/Tool.php @@ -36,7 +36,7 @@ abstract class Tool extends Durable{ $efficiency = 1; if(($block->getToolType() & $this->getBlockToolType()) !== 0){ $efficiency = $this->getBaseMiningEfficiency(); - if(($enchantmentLevel = $this->getEnchantmentLevel(Enchantment::EFFICIENCY)) > 0){ + if(($enchantmentLevel = $this->getEnchantmentLevel(Enchantment::EFFICIENCY())) > 0){ $efficiency += ($enchantmentLevel ** 2 + 1); } } diff --git a/src/pocketmine/item/enchantment/Enchantment.php b/src/pocketmine/item/enchantment/Enchantment.php index 80831911e9..9cbb07b0d9 100644 --- a/src/pocketmine/item/enchantment/Enchantment.php +++ b/src/pocketmine/item/enchantment/Enchantment.php @@ -140,6 +140,82 @@ class Enchantment{ self::registerEnchantment(new Enchantment(self::VANISHING, "%enchantment.curse.vanishing", self::RARITY_MYTHIC, self::SLOT_NONE, self::SLOT_ALL, 1)); } + public static function BLAST_PROTECTION() : Enchantment{ + return self::getEnchantment(self::BLAST_PROTECTION); + } + + public static function EFFICIENCY() : Enchantment{ + return self::getEnchantment(self::EFFICIENCY); + } + + public static function FEATHER_FALLING() : Enchantment{ + return self::getEnchantment(self::FEATHER_FALLING); + } + + public static function FIRE_ASPECT() : Enchantment{ + return self::getEnchantment(self::FIRE_ASPECT); + } + + public static function FIRE_PROTECTION() : Enchantment{ + return self::getEnchantment(self::FIRE_PROTECTION); + } + + public static function FLAME() : Enchantment{ + return self::getEnchantment(self::FLAME); + } + + public static function INFINITY() : Enchantment{ + return self::getEnchantment(self::INFINITY); + } + + public static function KNOCKBACK() : Enchantment{ + return self::getEnchantment(self::KNOCKBACK); + } + + public static function MENDING() : Enchantment{ + return self::getEnchantment(self::MENDING); + } + + public static function POWER() : Enchantment{ + return self::getEnchantment(self::POWER); + } + + public static function PROJECTILE_PROTECTION() : Enchantment{ + return self::getEnchantment(self::PROJECTILE_PROTECTION); + } + + public static function PROTECTION() : Enchantment{ + return self::getEnchantment(self::PROTECTION); + } + + public static function PUNCH() : Enchantment{ + return self::getEnchantment(self::PUNCH); + } + + public static function RESPIRATION() : Enchantment{ + return self::getEnchantment(self::RESPIRATION); + } + + public static function SHARPNESS() : Enchantment{ + return self::getEnchantment(self::SHARPNESS); + } + + public static function SILK_TOUCH() : Enchantment{ + return self::getEnchantment(self::SILK_TOUCH); + } + + public static function THORNS() : Enchantment{ + return self::getEnchantment(self::THORNS); + } + + public static function UNBREAKING() : Enchantment{ + return self::getEnchantment(self::UNBREAKING); + } + + public static function VANISHING() : Enchantment{ + return self::getEnchantment(self::VANISHING); + } + /** * Registers an enchantment type. * From 9354929cad26f8576424feedaa55a88635c27aab Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Feb 2019 14:43:57 +0000 Subject: [PATCH 0501/3224] added a whole bunch of tests for enchantment handling --- tests/phpunit/item/ItemFactoryTest.php | 81 +++++++++++++++++++ tests/phpunit/item/ItemTest.php | 103 +++++++++++++++++-------- 2 files changed, 150 insertions(+), 34 deletions(-) create mode 100644 tests/phpunit/item/ItemFactoryTest.php diff --git a/tests/phpunit/item/ItemFactoryTest.php b/tests/phpunit/item/ItemFactoryTest.php new file mode 100644 index 0000000000..c3d35c1a1b --- /dev/null +++ b/tests/phpunit/item/ItemFactoryTest.php @@ -0,0 +1,81 @@ +getId()); + self::assertEquals($meta, $item->getDamage()); + } + + /** + * Test that durable items are correctly created by the item factory + */ + public function testGetDurableItem() : void{ + self::assertInstanceOf(Sword::class, $i1 = ItemFactory::get(Item::WOODEN_SWORD)); + /** @var Sword $i1 */ + self::assertSame(0, $i1->getDamage()); + self::assertInstanceOf(Sword::class, $i2 = ItemFactory::get(Item::WOODEN_SWORD, 1)); + /** @var Sword $i2 */ + self::assertSame(1, $i2->getDamage()); + } +} diff --git a/tests/phpunit/item/ItemTest.php b/tests/phpunit/item/ItemTest.php index 63b4573cb2..9b164e88fc 100644 --- a/tests/phpunit/item/ItemTest.php +++ b/tests/phpunit/item/ItemTest.php @@ -25,12 +25,22 @@ namespace pocketmine\item; use PHPUnit\Framework\TestCase; use pocketmine\block\BlockFactory; +use pocketmine\item\enchantment\Enchantment; +use pocketmine\item\enchantment\EnchantmentInstance; class ItemTest extends TestCase{ - public function setUp() : void{ + public static function setUpBeforeClass() : void{ BlockFactory::init(); ItemFactory::init(); + Enchantment::init(); + } + + /** @var Item */ + private $item; + + public function setUp() : void{ + $this->item = ItemFactory::get(Item::DIAMOND_SWORD); } /** @@ -52,45 +62,70 @@ class ItemTest extends TestCase{ self::assertTrue($item1->equals($item2)); } - /** - * Tests that blocks are considered to be valid registered items - */ - public function testItemBlockRegistered() : void{ - for($id = 0; $id < 256; ++$id){ - self::assertEquals(BlockFactory::isRegistered($id), ItemFactory::isRegistered($id)); - } + public function testHasEnchantment() : void{ + $this->item->addEnchantment(new EnchantmentInstance(Enchantment::EFFICIENCY(), 5)); + self::assertTrue($this->item->hasEnchantment(Enchantment::EFFICIENCY())); + self::assertTrue($this->item->hasEnchantment(Enchantment::EFFICIENCY(), 5)); } - public function itemFromStringProvider() : array{ - return [ - ["dye:4", ItemIds::DYE, 4], - ["351", ItemIds::DYE, 0], - ["351:4", ItemIds::DYE, 4], - ["stone:3", ItemIds::STONE, 3], - ["minecraft:string", ItemIds::STRING, 0], - ["diamond_pickaxe", ItemIds::DIAMOND_PICKAXE, 0], - ["diamond_pickaxe:5", ItemIds::DIAMOND_PICKAXE, 5] + public function testHasEnchantments() : void{ + self::assertFalse($this->item->hasEnchantments()); + $this->item->addEnchantment(new EnchantmentInstance(Enchantment::FIRE_ASPECT())); + self::assertTrue($this->item->hasEnchantments()); + } + + public function testGetEnchantmentLevel() : void{ + $this->item->addEnchantment(new EnchantmentInstance(Enchantment::EFFICIENCY(), 5)); + self::assertSame(5, $this->item->getEnchantmentLevel(Enchantment::EFFICIENCY())); + } + + public function testGetEnchantments() : void{ + /** @var EnchantmentInstance[] $enchantments */ + $enchantments = [ + new EnchantmentInstance(Enchantment::EFFICIENCY(), 5), + new EnchantmentInstance(Enchantment::SHARPNESS(), 1) ]; + foreach($enchantments as $enchantment){ + $this->item->addEnchantment($enchantment); + } + foreach($this->item->getEnchantments() as $enchantment){ + foreach($enchantments as $k => $applied){ + if($enchantment->getType() === $applied->getType() and $enchantment->getLevel() === $applied->getLevel()){ + unset($enchantments[$k]); + continue 2; + } + } + self::assertTrue(false, "Unknown extra enchantment found: " . $enchantment->getType()->getName() . " x" . $enchantment->getLevel()); + } + self::assertEmpty($enchantments, "Expected all enchantments to be present"); } - /** - * @dataProvider itemFromStringProvider - * @param string $string - * @param int $id - * @param int $meta - */ - public function testFromStringSingle(string $string, int $id, int $meta) : void{ - $item = ItemFactory::fromString($string); - - self::assertEquals($id, $item->getId()); - self::assertEquals($meta, $item->getDamage()); + public function testOverwriteEnchantment() : void{ + $this->item->addEnchantment(new EnchantmentInstance(Enchantment::SHARPNESS())); + $this->item->addEnchantment(new EnchantmentInstance(Enchantment::SHARPNESS(), 5)); + self::assertSame(5, $this->item->getEnchantmentLevel(Enchantment::SHARPNESS())); } - /** - * Test that durable items are correctly created by the item factory - */ - public function testGetDurableItem() : void{ - self::assertInstanceOf(Sword::class, ItemFactory::get(Item::WOODEN_SWORD)); - self::assertInstanceOf(Sword::class, ItemFactory::get(Item::WOODEN_SWORD, 1)); + public function testRemoveAllEnchantments() : void{ + $this->item->addEnchantment(new EnchantmentInstance(Enchantment::FIRE_ASPECT())); + self::assertCount(1, $this->item->getEnchantments()); + $this->item->removeEnchantments(); + self::assertEmpty($this->item->getEnchantments()); + } + + public function testRemoveEnchantment() : void{ + $this->item->addEnchantment(new EnchantmentInstance(Enchantment::KNOCKBACK())); + $this->item->addEnchantment(new EnchantmentInstance(Enchantment::SHARPNESS())); + self::assertCount(2, $this->item->getEnchantments()); + $this->item->removeEnchantment(Enchantment::SHARPNESS()); + self::assertFalse($this->item->hasEnchantment(Enchantment::SHARPNESS())); + } + + public function testRemoveEnchantmentLevel() : void{ + $this->item->addEnchantment(new EnchantmentInstance(Enchantment::FIRE_ASPECT(), 2)); + $this->item->addEnchantment(new EnchantmentInstance(Enchantment::UNBREAKING())); + self::assertCount(2, $this->item->getEnchantments()); + $this->item->removeEnchantment(Enchantment::FIRE_ASPECT(), 2); + self::assertFalse($this->item->hasEnchantment(Enchantment::FIRE_ASPECT())); } } From 58cafc853f2caa013c65d98ab56f13ac3abe521c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Feb 2019 15:33:46 +0000 Subject: [PATCH 0502/3224] s/level/world (strings only) we should look at doing this for code too, but for now I'm not planning to break everyone's plugins. --- src/pocketmine/Server.php | 4 ++-- src/pocketmine/level/Explosion.php | 2 +- src/pocketmine/level/Level.php | 18 +++++++++--------- src/pocketmine/level/LevelManager.php | 14 +++++++------- src/pocketmine/level/Position.php | 4 ++-- .../level/format/io/BaseLevelProvider.php | 2 +- .../level/format/io/data/BedrockLevelData.php | 2 +- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 47983a88a0..12bf3f5225 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1577,7 +1577,7 @@ class Server{ } public function reload(){ - $this->logger->info("Saving levels..."); + $this->logger->info("Saving worlds..."); foreach($this->levelManager->getLevels() as $level){ $level->save(); @@ -1653,7 +1653,7 @@ class Server{ } if($this->levelManager instanceof LevelManager){ - $this->getLogger()->debug("Unloading all levels"); + $this->getLogger()->debug("Unloading all worlds"); foreach($this->levelManager->getLevels() as $level){ $this->levelManager->unloadLevel($level, true); } diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index 2b93386ddd..b92516a0b3 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -71,7 +71,7 @@ class Explosion{ */ public function __construct(Position $center, float $size, $what = null){ if(!$center->isValid()){ - throw new \InvalidArgumentException("Position does not have a valid level"); + throw new \InvalidArgumentException("Position does not have a valid world"); } $this->source = $center; $this->level = $center->getLevel(); diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 274a0bdf68..824b037a3c 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -458,7 +458,7 @@ class Level implements ChunkManager, Metadatable{ */ public function close(){ if($this->closed){ - throw new \InvalidStateException("Tried to close a level which is already closed"); + throw new \InvalidStateException("Tried to close a world which is already closed"); } foreach($this->chunks as $chunk){ @@ -753,7 +753,7 @@ class Level implements ChunkManager, Metadatable{ */ public function doTick(int $currentTick){ if($this->closed){ - throw new \InvalidStateException("Attempted to tick a Level which has been closed"); + throw new \InvalidStateException("Attempted to tick a world which has been closed"); } $this->timings->doTick->startTiming(); @@ -2488,7 +2488,7 @@ class Level implements ChunkManager, Metadatable{ $this->timings->syncChunkSendTimer->stopTiming(); }else{ - $this->server->getLogger()->debug("Dropped prepared chunk $x $z due to level not loaded"); + $this->server->getLogger()->debug("Dropped prepared chunk $x $z due to world not loaded"); } }); $this->server->getAsyncPool()->submitTask($task = new ChunkRequestTask($x, $z, $chunk, $promise)); @@ -2508,10 +2508,10 @@ class Level implements ChunkManager, Metadatable{ */ public function addEntity(Entity $entity){ if($entity->isClosed()){ - throw new \InvalidArgumentException("Attempted to add a garbage closed Entity to Level"); + throw new \InvalidArgumentException("Attempted to add a garbage closed Entity to world"); } if($entity->getLevel() !== $this){ - throw new \InvalidArgumentException("Invalid Entity level"); + throw new \InvalidArgumentException("Invalid Entity world"); } if($entity instanceof Player){ @@ -2529,7 +2529,7 @@ class Level implements ChunkManager, Metadatable{ */ public function removeEntity(Entity $entity){ if($entity->getLevel() !== $this){ - throw new \InvalidArgumentException("Invalid Entity level"); + throw new \InvalidArgumentException("Invalid Entity world"); } if($entity instanceof Player){ @@ -2548,10 +2548,10 @@ class Level implements ChunkManager, Metadatable{ */ public function addTile(Tile $tile){ if($tile->isClosed()){ - throw new \InvalidArgumentException("Attempted to add a garbage closed Tile to Level"); + throw new \InvalidArgumentException("Attempted to add a garbage closed Tile to world"); } if($tile->getLevel() !== $this){ - throw new \InvalidArgumentException("Invalid Tile level"); + throw new \InvalidArgumentException("Invalid Tile world"); } $chunkX = $tile->getFloorX() >> 4; @@ -2573,7 +2573,7 @@ class Level implements ChunkManager, Metadatable{ */ public function removeTile(Tile $tile){ if($tile->getLevel() !== $this){ - throw new \InvalidArgumentException("Invalid Tile level"); + throw new \InvalidArgumentException("Invalid Tile world"); } unset($this->updateTiles[Level::blockHash($tile->x, $tile->y, $tile->z)]); diff --git a/src/pocketmine/level/LevelManager.php b/src/pocketmine/level/LevelManager.php index 56cb8b6c85..2dbbdb1151 100644 --- a/src/pocketmine/level/LevelManager.php +++ b/src/pocketmine/level/LevelManager.php @@ -162,10 +162,10 @@ class LevelManager{ */ public function unloadLevel(Level $level, bool $forceUnload = false) : bool{ if($level === $this->getDefaultLevel() and !$forceUnload){ - throw new \InvalidArgumentException("The default level cannot be unloaded while running, please switch levels."); + throw new \InvalidArgumentException("The default world cannot be unloaded while running, please switch worlds."); } if($level->isDoingTick()){ - throw new \InvalidArgumentException("Cannot unload a level during level tick"); + throw new \InvalidArgumentException("Cannot unload a world during world tick"); } $ev = new LevelUnloadEvent($level); @@ -182,7 +182,7 @@ class LevelManager{ $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.level.unloading", [$level->getDisplayName()])); foreach($level->getPlayers() as $player){ if($level === $this->levelDefault or $this->levelDefault === null){ - $player->close($player->getLeaveMessage(), "Forced default level unload"); + $player->close($player->getLeaveMessage(), "Forced default world unload"); }elseif($this->levelDefault instanceof Level){ $player->teleport($this->levelDefault->getSafeSpawn()); } @@ -208,7 +208,7 @@ class LevelManager{ */ public function loadLevel(string $name) : bool{ if(trim($name) === ""){ - throw new LevelException("Invalid empty level name"); + throw new LevelException("Invalid empty world name"); } if($this->isLevelLoaded($name)){ return true; @@ -382,14 +382,14 @@ class LevelManager{ if($r > $this->baseTickRate){ $level->tickRateCounter = $level->getTickRate(); } - $this->server->getLogger()->debug("Raising level \"{$level->getDisplayName()}\" tick rate to {$level->getTickRate()} ticks"); + $this->server->getLogger()->debug("Raising world \"{$level->getDisplayName()}\" tick rate to {$level->getTickRate()} ticks"); }elseif($tickMs >= 50){ if($level->getTickRate() === $this->baseTickRate){ $level->setTickRate(max($this->baseTickRate + 1, min($this->autoTickRateLimit, (int) floor($tickMs / 50)))); - $this->server->getLogger()->debug(sprintf("Level \"%s\" took %gms, setting tick rate to %d ticks", $level->getDisplayName(), (int) round($tickMs, 2), $level->getTickRate())); + $this->server->getLogger()->debug(sprintf("World \"%s\" took %gms, setting tick rate to %d ticks", $level->getDisplayName(), (int) round($tickMs, 2), $level->getTickRate())); }elseif(($tickMs / $level->getTickRate()) >= 50 and $level->getTickRate() < $this->autoTickRateLimit){ $level->setTickRate($level->getTickRate() + 1); - $this->server->getLogger()->debug(sprintf("Level \"%s\" took %gms, setting tick rate to %d ticks", $level->getDisplayName(), (int) round($tickMs, 2), $level->getTickRate())); + $this->server->getLogger()->debug(sprintf("World \"%s\" took %gms, setting tick rate to %d ticks", $level->getDisplayName(), (int) round($tickMs, 2), $level->getTickRate())); } $level->tickRateCounter = $level->getTickRate(); } diff --git a/src/pocketmine/level/Position.php b/src/pocketmine/level/Position.php index 9f3898b097..0be7137a91 100644 --- a/src/pocketmine/level/Position.php +++ b/src/pocketmine/level/Position.php @@ -63,7 +63,7 @@ class Position extends Vector3{ */ public function getLevel(){ if($this->level !== null and $this->level->isClosed()){ - \GlobalLogger::get()->debug("Position was holding a reference to an unloaded Level"); + \GlobalLogger::get()->debug("Position was holding a reference to an unloaded world"); $this->level = null; } @@ -81,7 +81,7 @@ class Position extends Vector3{ */ public function setLevel(Level $level = null){ if($level !== null and $level->isClosed()){ - throw new \InvalidArgumentException("Specified level has been unloaded and cannot be used"); + throw new \InvalidArgumentException("Specified world has been unloaded and cannot be used"); } $this->level = $level; diff --git a/src/pocketmine/level/format/io/BaseLevelProvider.php b/src/pocketmine/level/format/io/BaseLevelProvider.php index 84066bc044..89a809d972 100644 --- a/src/pocketmine/level/format/io/BaseLevelProvider.php +++ b/src/pocketmine/level/format/io/BaseLevelProvider.php @@ -37,7 +37,7 @@ abstract class BaseLevelProvider implements LevelProvider{ public function __construct(string $path){ if(!file_exists($path)){ - throw new LevelException("Level does not exist"); + throw new LevelException("World does not exist"); } $this->path = $path; diff --git a/src/pocketmine/level/format/io/data/BedrockLevelData.php b/src/pocketmine/level/format/io/data/BedrockLevelData.php index bfdfdf1112..946f284a47 100644 --- a/src/pocketmine/level/format/io/data/BedrockLevelData.php +++ b/src/pocketmine/level/format/io/data/BedrockLevelData.php @@ -130,7 +130,7 @@ class BedrockLevelData extends BaseNbtLevelData{ case self::GENERATOR_LIMITED: throw new UnsupportedLevelFormatException("Limited worlds are not currently supported"); default: - throw new UnsupportedLevelFormatException("Unknown LevelDB world format type, this level cannot be loaded"); + throw new UnsupportedLevelFormatException("Unknown LevelDB world format type, this world cannot be loaded"); } }else{ $this->compoundTag->setString("generatorName", "default"); From efc2d72d5f8bcf24071502b2045b28764ae97562 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Feb 2019 16:20:48 +0000 Subject: [PATCH 0503/3224] Move permission parsing to dedicated PermissionParser class --- src/pocketmine/permission/Permission.php | 104 -------------- .../permission/PermissionParser.php | 127 ++++++++++++++++++ src/pocketmine/plugin/PluginDescription.php | 3 +- 3 files changed, 129 insertions(+), 105 deletions(-) create mode 100644 src/pocketmine/permission/PermissionParser.php diff --git a/src/pocketmine/permission/Permission.php b/src/pocketmine/permission/Permission.php index 38a3cc132a..9bbd374e56 100644 --- a/src/pocketmine/permission/Permission.php +++ b/src/pocketmine/permission/Permission.php @@ -27,10 +27,6 @@ declare(strict_types=1); namespace pocketmine\permission; -use function is_array; -use function is_bool; -use function strtolower; - /** * Represents a permission */ @@ -42,106 +38,6 @@ class Permission{ public static $DEFAULT_PERMISSION = self::DEFAULT_OP; - /** - * @param bool|string $value - * - * @return string - * - * @throws \InvalidArgumentException - */ - public static function getByName($value) : string{ - if(is_bool($value)){ - if($value){ - return "true"; - }else{ - return "false"; - } - } - switch(strtolower($value)){ - case "op": - case "isop": - case "operator": - case "isoperator": - case "admin": - case "isadmin": - return self::DEFAULT_OP; - - case "!op": - case "notop": - case "!operator": - case "notoperator": - case "!admin": - case "notadmin": - return self::DEFAULT_NOT_OP; - - case "true": - return self::DEFAULT_TRUE; - case "false": - return self::DEFAULT_FALSE; - } - - throw new \InvalidArgumentException("Unknown permission default name \"$value\""); - } - - /** - * @param array $data - * @param string $default - * - * @return Permission[] - */ - public static function loadPermissions(array $data, string $default = self::DEFAULT_OP) : array{ - $result = []; - foreach($data as $key => $entry){ - $result[] = self::loadPermission($key, $entry, $default, $result); - } - - return $result; - } - - /** - * @param string $name - * @param array $data - * @param string $default - * @param array $output - * - * @return Permission - * - * @throws \Exception - */ - public static function loadPermission(string $name, array $data, string $default = self::DEFAULT_OP, array &$output = []) : Permission{ - $desc = null; - $children = []; - if(isset($data["default"])){ - $value = Permission::getByName($data["default"]); - if($value !== null){ - $default = $value; - }else{ - throw new \InvalidStateException("'default' key contained unknown value"); - } - } - - if(isset($data["children"])){ - if(is_array($data["children"])){ - foreach($data["children"] as $k => $v){ - if(is_array($v)){ - if(($perm = self::loadPermission($k, $v, $default, $output)) !== null){ - $output[] = $perm; - } - } - $children[$k] = true; - } - }else{ - throw new \InvalidStateException("'children' key is of wrong type"); - } - } - - if(isset($data["description"])){ - $desc = $data["description"]; - } - - return new Permission($name, $desc, $default, $children); - } - /** @var string */ private $name; diff --git a/src/pocketmine/permission/PermissionParser.php b/src/pocketmine/permission/PermissionParser.php new file mode 100644 index 0000000000..811554eb4f --- /dev/null +++ b/src/pocketmine/permission/PermissionParser.php @@ -0,0 +1,127 @@ + $entry){ + $result[] = self::loadPermission($key, $entry, $default, $result); + } + + return $result; + } + + /** + * @param string $name + * @param array $data + * @param string $default + * @param array $output + * + * @return Permission + * + * @throws \Exception + */ + public static function loadPermission(string $name, array $data, string $default = Permission::DEFAULT_OP, array &$output = []) : Permission{ + $desc = null; + $children = []; + if(isset($data["default"])){ + $value = PermissionParser::defaultFromString($data["default"]); + if($value !== null){ + $default = $value; + }else{ + throw new \InvalidStateException("'default' key contained unknown value"); + } + } + + if(isset($data["children"])){ + if(is_array($data["children"])){ + foreach($data["children"] as $k => $v){ + if(is_array($v)){ + if(($perm = self::loadPermission($k, $v, $default, $output)) !== null){ + $output[] = $perm; + } + } + $children[$k] = true; + } + }else{ + throw new \InvalidStateException("'children' key is of wrong type"); + } + } + + if(isset($data["description"])){ + $desc = $data["description"]; + } + + return new Permission($name, $desc, $default, $children); + } +} diff --git a/src/pocketmine/plugin/PluginDescription.php b/src/pocketmine/plugin/PluginDescription.php index 7cdd1e95ab..b904bf491b 100644 --- a/src/pocketmine/plugin/PluginDescription.php +++ b/src/pocketmine/plugin/PluginDescription.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\plugin; use pocketmine\permission\Permission; +use pocketmine\permission\PermissionParser; use function array_map; use function array_values; use function constant; @@ -146,7 +147,7 @@ class PluginDescription{ } if(isset($plugin["permissions"])){ - $this->permissions = Permission::loadPermissions($plugin["permissions"]); + $this->permissions = PermissionParser::loadPermissions($plugin["permissions"]); } } From 7aa263d32070ed976ca00684024b9bae7a7b15ee Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Feb 2019 16:21:25 +0000 Subject: [PATCH 0504/3224] PermissionParser: add emitPermissions() --- .../permission/PermissionParser.php | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/pocketmine/permission/PermissionParser.php b/src/pocketmine/permission/PermissionParser.php index 811554eb4f..dd625d2e77 100644 --- a/src/pocketmine/permission/PermissionParser.php +++ b/src/pocketmine/permission/PermissionParser.php @@ -124,4 +124,39 @@ class PermissionParser{ return new Permission($name, $desc, $default, $children); } + + /** + * @param Permission[] $permissions + * + * @return array + */ + public static function emitPermissions(array $permissions) : array{ + $result = []; + foreach($permissions as $permission){ + $result[$permission->getName()] = self::emitPermission($permission); + } + ksort($result); + return $result; + } + + private static function emitPermission(Permission $permission) : array{ + $result = [ + "description" => $permission->getDescription(), + "default" => $permission->getDefault() + ]; + $children = []; + foreach($permission->getChildren() as $name => $bool){ + //TODO: really? wtf??? this system is so overengineered it makes my head hurt... + $child = PermissionManager::getInstance()->getPermission($name); + if($child === null){ + throw new \UnexpectedValueException("Permission child should be a registered permission"); + } + $children[$name] = self::emitPermission($child); + } + if(!empty($children)){ + ksort($children); + $result["children"] = $children; + } + return $result; + } } From 5fac5c72816c6e1b137ca59b14e567a9116c2baa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Feb 2019 16:22:45 +0000 Subject: [PATCH 0505/3224] Move core permissions to default_permissions.yml this is one of the few things that is actually better suited to a YAML file than code closes #2594 --- resources/default_permissions.yml | 192 ++++++++++++++++++ .../permission/DefaultPermissions.php | 88 +------- 2 files changed, 198 insertions(+), 82 deletions(-) create mode 100644 resources/default_permissions.yml diff --git a/resources/default_permissions.yml b/resources/default_permissions.yml new file mode 100644 index 0000000000..940c4da107 --- /dev/null +++ b/resources/default_permissions.yml @@ -0,0 +1,192 @@ +--- +pocketmine: + description: Allows using all PocketMine commands and utilities + default: op + children: + pocketmine.broadcast: + description: Allows the user to receive all broadcast messages + default: op + children: + pocketmine.broadcast.admin: + description: Allows the user to receive administrative broadcasts + default: op + pocketmine.broadcast.user: + description: Allows the user to receive user broadcasts + default: "true" + pocketmine.command: + description: Allows using all PocketMine commands + default: op + children: + pocketmine.command.ban: + description: Allows the user to ban people + default: op + children: + pocketmine.command.ban.ip: + description: Allows the user to ban IP addresses + default: op + pocketmine.command.ban.player: + description: Allows the user to ban players + default: op + pocketmine.command.defaultgamemode: + description: Allows the user to change the default gamemode + default: op + pocketmine.command.dumpmemory: + description: Allows the user to dump memory contents + default: "false" + pocketmine.command.effect: + description: Allows the user to give/take potion effects + default: op + pocketmine.command.enchant: + description: Allows the user to enchant items + default: op + pocketmine.command.gamemode: + description: Allows the user to change the gamemode of players + default: op + pocketmine.command.gc: + description: Allows the user to fire garbage collection tasks + default: op + pocketmine.command.give: + description: Allows the user to give items to players + default: op + pocketmine.command.help: + description: Allows the user to view the help menu + default: "true" + pocketmine.command.kick: + description: Allows the user to kick players + default: op + pocketmine.command.kill: + description: Allows the user to kill players + default: op + children: + pocketmine.command.kill.other: + description: Allows the user to kill other players + default: op + pocketmine.command.kill.self: + description: Allows the user to commit suicide + default: "true" + pocketmine.command.list: + description: Allows the user to list all online players + default: op + pocketmine.command.me: + description: Allows the user to perform a chat action + default: "true" + pocketmine.command.op: + description: Allows the user to change operators + default: op + children: + pocketmine.command.op.give: + description: Allows the user to give a player operator status + default: op + pocketmine.command.op.take: + description: Allows the user to take a player's operator status + default: op + pocketmine.command.particle: + description: Allows the user to create particle effects + default: op + pocketmine.command.plugins: + description: Allows the user to view the list of plugins + default: op + pocketmine.command.reload: + description: Allows the user to reload the server settings + default: op + pocketmine.command.save: + description: Allows the user to save the worlds + default: op + children: + pocketmine.command.save.disable: + description: Allows the user to disable automatic saving + default: op + pocketmine.command.save.enable: + description: Allows the user to enable automatic saving + default: op + pocketmine.command.save.perform: + description: Allows the user to perform a manual save + default: op + pocketmine.command.say: + description: Allows the user to talk as the console + default: op + pocketmine.command.seed: + description: Allows the user to view the seed of the world + default: op + pocketmine.command.setworldspawn: + description: Allows the user to change the world spawn + default: op + pocketmine.command.spawnpoint: + description: Allows the user to change player's spawnpoint + default: op + pocketmine.command.status: + description: Allows the user to view the server performance + default: op + pocketmine.command.stop: + description: Allows the user to stop the server + default: op + pocketmine.command.teleport: + description: Allows the user to teleport players + default: op + pocketmine.command.tell: + description: Allows the user to privately message another player + default: "true" + pocketmine.command.time: + description: Allows the user to alter the time + default: op + children: + pocketmine.command.time.add: + description: Allows the user to fast-forward time + default: op + pocketmine.command.time.query: + description: Allows the user query the time + default: op + pocketmine.command.time.set: + description: Allows the user to change the time + default: op + pocketmine.command.time.start: + description: Allows the user to restart the time + default: op + pocketmine.command.time.stop: + description: Allows the user to stop the time + default: op + pocketmine.command.timings: + description: Allows the user to records timings for all plugin events + default: op + pocketmine.command.title: + description: Allows the user to send a title to the specified player + default: op + pocketmine.command.transferserver: + description: Allows the user to transfer self to another server + default: op + pocketmine.command.unban: + description: Allows the user to unban people + default: op + children: + pocketmine.command.unban.ip: + description: Allows the user to unban IP addresses + default: op + pocketmine.command.unban.player: + description: Allows the user to unban players + default: op + pocketmine.command.version: + description: Allows the user to view the version of the server + default: "true" + pocketmine.command.whitelist: + description: Allows the user to modify the server whitelist + default: op + children: + pocketmine.command.whitelist.add: + description: Allows the user to add a player to the server whitelist + default: op + pocketmine.command.whitelist.disable: + description: Allows the user to disable the server whitelist + default: op + pocketmine.command.whitelist.enable: + description: Allows the user to enable the server whitelist + default: op + pocketmine.command.whitelist.list: + description: Allows the user to list all the players on the server whitelist + default: op + pocketmine.command.whitelist.reload: + description: Allows the user to reload the server whitelist + default: op + pocketmine.command.whitelist.remove: + description: Allows the user to remove a player to the server whitelist + default: op +... diff --git a/src/pocketmine/permission/DefaultPermissions.php b/src/pocketmine/permission/DefaultPermissions.php index 08a795de13..039b846c73 100644 --- a/src/pocketmine/permission/DefaultPermissions.php +++ b/src/pocketmine/permission/DefaultPermissions.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\permission; +use function yaml_parse_file; + abstract class DefaultPermissions{ public const ROOT = "pocketmine"; @@ -44,87 +46,9 @@ abstract class DefaultPermissions{ } public static function registerCorePermissions(){ - $parent = self::registerPermission(new Permission(self::ROOT, "Allows using all PocketMine commands and utilities")); - - $broadcasts = self::registerPermission(new Permission(self::ROOT . ".broadcast", "Allows the user to receive all broadcast messages"), $parent); - self::registerPermission(new Permission(self::ROOT . ".broadcast.admin", "Allows the user to receive administrative broadcasts", Permission::DEFAULT_OP), $broadcasts); - self::registerPermission(new Permission(self::ROOT . ".broadcast.user", "Allows the user to receive user broadcasts", Permission::DEFAULT_TRUE), $broadcasts); - $broadcasts->recalculatePermissibles(); - - $commands = self::registerPermission(new Permission(self::ROOT . ".command", "Allows using all PocketMine commands"), $parent); - - $whitelist = self::registerPermission(new Permission(self::ROOT . ".command.whitelist", "Allows the user to modify the server whitelist", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.whitelist.add", "Allows the user to add a player to the server whitelist"), $whitelist); - self::registerPermission(new Permission(self::ROOT . ".command.whitelist.remove", "Allows the user to remove a player to the server whitelist"), $whitelist); - self::registerPermission(new Permission(self::ROOT . ".command.whitelist.reload", "Allows the user to reload the server whitelist"), $whitelist); - self::registerPermission(new Permission(self::ROOT . ".command.whitelist.enable", "Allows the user to enable the server whitelist"), $whitelist); - self::registerPermission(new Permission(self::ROOT . ".command.whitelist.disable", "Allows the user to disable the server whitelist"), $whitelist); - self::registerPermission(new Permission(self::ROOT . ".command.whitelist.list", "Allows the user to list all the players on the server whitelist"), $whitelist); - $whitelist->recalculatePermissibles(); - - $ban = self::registerPermission(new Permission(self::ROOT . ".command.ban", "Allows the user to ban people", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.ban.player", "Allows the user to ban players"), $ban); - self::registerPermission(new Permission(self::ROOT . ".command.ban.ip", "Allows the user to ban IP addresses"), $ban); - $ban->recalculatePermissibles(); - - $unban = self::registerPermission(new Permission(self::ROOT . ".command.unban", "Allows the user to unban people", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.unban.player", "Allows the user to unban players"), $unban); - self::registerPermission(new Permission(self::ROOT . ".command.unban.ip", "Allows the user to unban IP addresses"), $unban); - $unban->recalculatePermissibles(); - - $op = self::registerPermission(new Permission(self::ROOT . ".command.op", "Allows the user to change operators", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.op.give", "Allows the user to give a player operator status"), $op); - self::registerPermission(new Permission(self::ROOT . ".command.op.take", "Allows the user to take a player's operator status"), $op); - $op->recalculatePermissibles(); - - $save = self::registerPermission(new Permission(self::ROOT . ".command.save", "Allows the user to save the worlds", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.save.enable", "Allows the user to enable automatic saving"), $save); - self::registerPermission(new Permission(self::ROOT . ".command.save.disable", "Allows the user to disable automatic saving"), $save); - self::registerPermission(new Permission(self::ROOT . ".command.save.perform", "Allows the user to perform a manual save"), $save); - $save->recalculatePermissibles(); - - $time = self::registerPermission(new Permission(self::ROOT . ".command.time", "Allows the user to alter the time", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.time.add", "Allows the user to fast-forward time"), $time); - self::registerPermission(new Permission(self::ROOT . ".command.time.set", "Allows the user to change the time"), $time); - self::registerPermission(new Permission(self::ROOT . ".command.time.start", "Allows the user to restart the time"), $time); - self::registerPermission(new Permission(self::ROOT . ".command.time.stop", "Allows the user to stop the time"), $time); - self::registerPermission(new Permission(self::ROOT . ".command.time.query", "Allows the user query the time"), $time); - $time->recalculatePermissibles(); - - $kill = self::registerPermission(new Permission(self::ROOT . ".command.kill", "Allows the user to kill players", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.kill.self", "Allows the user to commit suicide", Permission::DEFAULT_TRUE), $kill); - self::registerPermission(new Permission(self::ROOT . ".command.kill.other", "Allows the user to kill other players"), $kill); - $kill->recalculatePermissibles(); - - self::registerPermission(new Permission(self::ROOT . ".command.me", "Allows the user to perform a chat action", Permission::DEFAULT_TRUE), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.tell", "Allows the user to privately message another player", Permission::DEFAULT_TRUE), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.say", "Allows the user to talk as the console", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.give", "Allows the user to give items to players", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.effect", "Allows the user to give/take potion effects", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.enchant", "Allows the user to enchant items", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.particle", "Allows the user to create particle effects", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.teleport", "Allows the user to teleport players", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.kick", "Allows the user to kick players", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.stop", "Allows the user to stop the server", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.list", "Allows the user to list all online players", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.help", "Allows the user to view the help menu", Permission::DEFAULT_TRUE), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.plugins", "Allows the user to view the list of plugins", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.reload", "Allows the user to reload the server settings", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.version", "Allows the user to view the version of the server", Permission::DEFAULT_TRUE), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.gamemode", "Allows the user to change the gamemode of players", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.defaultgamemode", "Allows the user to change the default gamemode", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.seed", "Allows the user to view the seed of the world", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.status", "Allows the user to view the server performance", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.gc", "Allows the user to fire garbage collection tasks", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.dumpmemory", "Allows the user to dump memory contents", Permission::DEFAULT_FALSE), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.timings", "Allows the user to records timings for all plugin events", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.spawnpoint", "Allows the user to change player's spawnpoint", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.setworldspawn", "Allows the user to change the world spawn", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.transferserver", "Allows the user to transfer self to another server", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.title", "Allows the user to send a title to the specified player", Permission::DEFAULT_OP), $commands); - - $commands->recalculatePermissibles(); - - $parent->recalculatePermissibles(); + $manager = PermissionManager::getInstance(); + foreach(PermissionParser::loadPermissions(yaml_parse_file(\pocketmine\RESOURCE_PATH . 'default_permissions.yml')) as $permission){ + $manager->addPermission($permission); + } } } From e93464f318c48570b1cead8aac457f42a72a91fe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Feb 2019 16:29:34 +0000 Subject: [PATCH 0506/3224] SnowLayer: fixed 8x layers being replaceable this also fixes some placement bugs. --- src/pocketmine/block/SnowLayer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index 542d2f7003..3244742e15 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -65,7 +65,7 @@ class SnowLayer extends Flowable implements Fallable{ } public function canBeReplaced() : bool{ - return true; + return $this->layers < 8; } public function getHardness() : float{ From 89fce7712a9c8687159c6dbee896911b9a0ad67d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Feb 2019 19:21:51 +0000 Subject: [PATCH 0507/3224] Block: Clean up internal constructor inconsistencies I don't dare look how big this commit is or how many bugs it introduced... --- src/pocketmine/block/ActivatorRail.php | 6 - src/pocketmine/block/Air.php | 10 - src/pocketmine/block/BaseRail.php | 4 - src/pocketmine/block/Bed.php | 17 +- src/pocketmine/block/Bedrock.php | 10 - src/pocketmine/block/Beetroot.php | 6 - src/pocketmine/block/Block.php | 78 +-- src/pocketmine/block/BlockFactory.php | 544 +++++++++--------- src/pocketmine/block/BlockIdentifier.php | 71 +++ ...stone.php => BlockIdentifierFlattened.php} | 16 +- src/pocketmine/block/BoneBlock.php | 10 - src/pocketmine/block/Bookshelf.php | 10 - src/pocketmine/block/BrewingStand.php | 13 - src/pocketmine/block/BrickStairs.php | 10 - src/pocketmine/block/Bricks.php | 10 - src/pocketmine/block/BrownMushroom.php | 6 - src/pocketmine/block/BrownMushroomBlock.php | 6 - src/pocketmine/block/Button.php | 4 - src/pocketmine/block/Cactus.php | 10 - src/pocketmine/block/Cake.php | 12 - src/pocketmine/block/Carrot.php | 6 - src/pocketmine/block/Chest.php | 14 - src/pocketmine/block/Clay.php | 10 - src/pocketmine/block/Coal.php | 10 - src/pocketmine/block/CoalOre.php | 10 - src/pocketmine/block/Cobblestone.php | 10 - src/pocketmine/block/CobblestoneStairs.php | 10 - src/pocketmine/block/Cobweb.php | 10 - src/pocketmine/block/CocoaBlock.php | 10 - src/pocketmine/block/ConcretePowder.php | 2 +- src/pocketmine/block/CraftingTable.php | 10 - src/pocketmine/block/Crops.php | 4 - src/pocketmine/block/Dandelion.php | 10 - src/pocketmine/block/DaylightSensor.php | 14 +- src/pocketmine/block/DeadBush.php | 10 - src/pocketmine/block/DetectorRail.php | 6 - src/pocketmine/block/Diamond.php | 10 - src/pocketmine/block/DiamondOre.php | 10 - src/pocketmine/block/Emerald.php | 10 - src/pocketmine/block/EmeraldOre.php | 10 - src/pocketmine/block/EnchantingTable.php | 15 - src/pocketmine/block/EndPortalFrame.php | 10 - src/pocketmine/block/EndRod.php | 10 - src/pocketmine/block/EndStone.php | 10 - src/pocketmine/block/EndStoneBricks.php | 10 - src/pocketmine/block/EnderChest.php | 10 - src/pocketmine/block/Farmland.php | 10 - src/pocketmine/block/Fire.php | 10 - src/pocketmine/block/FlowerPot.php | 15 - src/pocketmine/block/Furnace.php | 18 +- src/pocketmine/block/GlowingObsidian.php | 10 - src/pocketmine/block/Glowstone.php | 10 - src/pocketmine/block/Gold.php | 10 - src/pocketmine/block/GoldOre.php | 10 - src/pocketmine/block/Grass.php | 10 - src/pocketmine/block/GrassPath.php | 10 - src/pocketmine/block/Gravel.php | 10 - src/pocketmine/block/HayBale.php | 10 - src/pocketmine/block/Ice.php | 10 - src/pocketmine/block/InvisibleBedrock.php | 10 - src/pocketmine/block/Iron.php | 10 - src/pocketmine/block/IronBars.php | 10 - src/pocketmine/block/IronDoor.php | 13 - src/pocketmine/block/IronOre.php | 10 - src/pocketmine/block/IronTrapdoor.php | 6 - src/pocketmine/block/ItemFrame.php | 15 - src/pocketmine/block/Ladder.php | 10 - src/pocketmine/block/Lapis.php | 10 - src/pocketmine/block/LapisOre.php | 10 - src/pocketmine/block/Lava.php | 4 - src/pocketmine/block/Leaves.php | 4 +- src/pocketmine/block/Lever.php | 10 - src/pocketmine/block/Liquid.php | 11 +- src/pocketmine/block/LitPumpkin.php | 6 - src/pocketmine/block/Magma.php | 10 - src/pocketmine/block/Melon.php | 10 - src/pocketmine/block/MelonStem.php | 10 - src/pocketmine/block/MonsterSpawner.php | 10 - src/pocketmine/block/Mycelium.php | 10 - src/pocketmine/block/NetherBrickFence.php | 10 - src/pocketmine/block/NetherBrickStairs.php | 10 - src/pocketmine/block/NetherQuartzOre.php | 10 - src/pocketmine/block/NetherReactor.php | 10 - src/pocketmine/block/NetherWartBlock.php | 10 - src/pocketmine/block/NetherWartPlant.php | 14 +- src/pocketmine/block/Netherrack.php | 10 - src/pocketmine/block/NoteBlock.php | 10 - src/pocketmine/block/Obsidian.php | 10 - src/pocketmine/block/PackedIce.php | 10 - src/pocketmine/block/Podzol.php | 10 - src/pocketmine/block/Potato.php | 6 - src/pocketmine/block/PoweredRail.php | 5 - src/pocketmine/block/Pumpkin.php | 10 - src/pocketmine/block/PumpkinStem.php | 10 - src/pocketmine/block/PurpurStairs.php | 10 - src/pocketmine/block/QuartzStairs.php | 10 - src/pocketmine/block/Rail.php | 6 - src/pocketmine/block/RedMushroom.php | 10 - src/pocketmine/block/RedMushroomBlock.php | 10 - src/pocketmine/block/RedSandstoneStairs.php | 33 -- src/pocketmine/block/Redstone.php | 10 - src/pocketmine/block/RedstoneLamp.php | 13 +- src/pocketmine/block/RedstoneOre.php | 14 +- src/pocketmine/block/RedstoneRepeater.php | 14 +- src/pocketmine/block/RedstoneTorch.php | 13 +- src/pocketmine/block/RedstoneWire.php | 13 - src/pocketmine/block/SandstoneStairs.php | 10 - src/pocketmine/block/Sapling.php | 4 +- src/pocketmine/block/SeaLantern.php | 10 - src/pocketmine/block/SignPost.php | 17 - src/pocketmine/block/Skull.php | 14 - src/pocketmine/block/Slab.php | 11 +- src/pocketmine/block/Snow.php | 10 - src/pocketmine/block/SnowLayer.php | 10 - src/pocketmine/block/SoulSand.php | 10 - src/pocketmine/block/Sponge.php | 10 - src/pocketmine/block/StandingBanner.php | 16 - src/pocketmine/block/Stem.php | 3 +- src/pocketmine/block/StoneBrickStairs.php | 10 - src/pocketmine/block/StoneButton.php | 6 - src/pocketmine/block/StonePressurePlate.php | 10 - src/pocketmine/block/Stonecutter.php | 10 - src/pocketmine/block/Sugarcane.php | 12 - src/pocketmine/block/TNT.php | 10 - src/pocketmine/block/Trapdoor.php | 10 - src/pocketmine/block/TrappedChest.php | 5 - src/pocketmine/block/Tripwire.php | 10 - src/pocketmine/block/TripwireHook.php | 10 - src/pocketmine/block/UnknownBlock.php | 5 +- src/pocketmine/block/Vine.php | 10 - src/pocketmine/block/WallBanner.php | 6 - src/pocketmine/block/WallSign.php | 6 - src/pocketmine/block/Water.php | 4 - src/pocketmine/block/WaterLily.php | 10 - .../block/WeightedPressurePlateHeavy.php | 6 - .../block/WeightedPressurePlateLight.php | 10 - src/pocketmine/block/Wheat.php | 6 - src/pocketmine/block/Wood.php | 4 +- src/pocketmine/block/WoodenButton.php | 6 - src/pocketmine/block/WoodenPressurePlate.php | 6 - src/pocketmine/block/WoodenSlab.php | 2 - 141 files changed, 427 insertions(+), 1609 deletions(-) create mode 100644 src/pocketmine/block/BlockIdentifier.php rename src/pocketmine/block/{MossyCobblestone.php => BlockIdentifierFlattened.php} (65%) delete mode 100644 src/pocketmine/block/RedSandstoneStairs.php diff --git a/src/pocketmine/block/ActivatorRail.php b/src/pocketmine/block/ActivatorRail.php index 88d4a9f7f5..063cd6d25c 100644 --- a/src/pocketmine/block/ActivatorRail.php +++ b/src/pocketmine/block/ActivatorRail.php @@ -25,11 +25,5 @@ namespace pocketmine\block; class ActivatorRail extends RedstoneRail{ - protected $id = self::ACTIVATOR_RAIL; - - public function getName() : string{ - return "Activator Rail"; - } - //TODO } diff --git a/src/pocketmine/block/Air.php b/src/pocketmine/block/Air.php index e7a11e0ea7..33aeccb843 100644 --- a/src/pocketmine/block/Air.php +++ b/src/pocketmine/block/Air.php @@ -32,16 +32,6 @@ use pocketmine\math\AxisAlignedBB; */ class Air extends Transparent{ - protected $id = self::AIR; - - public function __construct(){ - - } - - public function getName() : string{ - return "Air"; - } - public function isBreakable(Item $item) : bool{ return false; } diff --git a/src/pocketmine/block/BaseRail.php b/src/pocketmine/block/BaseRail.php index d8cfdde8f3..7dc0e48f79 100644 --- a/src/pocketmine/block/BaseRail.php +++ b/src/pocketmine/block/BaseRail.php @@ -80,10 +80,6 @@ abstract class BaseRail extends Flowable{ /** @var int[] */ protected $connections = []; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ if(empty($this->connections)){ return self::STRAIGHT_NORTH_SOUTH; diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 6e2e08e8f3..6123b35cf1 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -41,10 +41,6 @@ class Bed extends Transparent{ private const BITFLAG_OCCUPIED = 0x04; private const BITFLAG_HEAD = 0x08; - protected $id = self::BED_BLOCK; - - protected $itemId = Item::BED; - /** @var int */ protected $facing = Facing::NORTH; /** @var bool */ @@ -54,7 +50,8 @@ class Bed extends Transparent{ /** @var DyeColor */ protected $color; - public function __construct(){ + public function __construct(BlockIdentifier $idInfo, string $name){ + parent::__construct($idInfo, $name); $this->color = DyeColor::RED(); } @@ -83,10 +80,6 @@ class Bed extends Transparent{ } } - protected function getTileClass() : ?string{ - return TileBed::class; - } - public function writeStateToWorld() : void{ parent::writeStateToWorld(); //extra block properties storage hack @@ -100,10 +93,6 @@ class Bed extends Transparent{ return 0.2; } - public function getName() : string{ - return "Bed Block"; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ return AxisAlignedBB::one()->trim(Facing::UP, 7 / 16); } @@ -214,7 +203,7 @@ class Bed extends Transparent{ } public function getItem() : Item{ - return ItemFactory::get($this->getItemId(), $this->color->getMagicNumber()); + return ItemFactory::get($this->idInfo->getItemId(), $this->color->getMagicNumber()); } public function isAffectedBySilkTouch() : bool{ diff --git a/src/pocketmine/block/Bedrock.php b/src/pocketmine/block/Bedrock.php index c17173855f..91fb7fe4cb 100644 --- a/src/pocketmine/block/Bedrock.php +++ b/src/pocketmine/block/Bedrock.php @@ -27,16 +27,6 @@ use pocketmine\item\Item; class Bedrock extends Solid{ - protected $id = self::BEDROCK; - - public function __construct(){ - - } - - public function getName() : string{ - return "Bedrock"; - } - public function getHardness() : float{ return -1; } diff --git a/src/pocketmine/block/Beetroot.php b/src/pocketmine/block/Beetroot.php index b134fff2b3..5158c8fc4d 100644 --- a/src/pocketmine/block/Beetroot.php +++ b/src/pocketmine/block/Beetroot.php @@ -29,12 +29,6 @@ use function mt_rand; class Beetroot extends Crops{ - protected $id = self::BEETROOT_BLOCK; - - public function getName() : string{ - return "Beetroot Block"; - } - public function getDropsForCompatibleTool(Item $item) : array{ if($this->age >= 7){ return [ diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 18b4e37029..f0f40b94ed 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -65,71 +65,50 @@ class Block extends Position implements BlockIds, Metadatable{ return BlockFactory::get($id, $meta, $pos); } - /** @var int */ - protected $id; - /** @var int */ - protected $variant = 0; + /** @var BlockIdentifier */ + protected $idInfo; + /** @var string|null */ protected $fallbackName; - /** @var int|null */ - protected $itemId; + /** @var AxisAlignedBB */ protected $boundingBox = null; - - /** @var AxisAlignedBB[]|null */ protected $collisionBoxes = null; /** - * @param int $id The block type's ID, 0-255 - * @param int $variant Meta value of the block type - * @param string|null $name English name of the block type (TODO: implement translations) - * @param int $itemId The item ID of the block type, used for block picking and dropping items. + * @param BlockIdentifier $idInfo + * @param string|null $name English name of the block type (TODO: implement translations) */ - public function __construct(int $id, int $variant = 0, string $name = null, int $itemId = null){ - $this->id = $id; - - if(($variant & $this->getStateBitmask()) !== 0){ - throw new \InvalidArgumentException("Variant 0x" . dechex($variant) . " collides with state bitmask 0x" . dechex($this->getStateBitmask())); + public function __construct(BlockIdentifier $idInfo, string $name){ + if(($idInfo->getVariant() & $this->getStateBitmask()) !== 0){ + throw new \InvalidArgumentException("Variant 0x" . dechex($idInfo->getVariant()) . " collides with state bitmask 0x" . dechex($this->getStateBitmask())); } - $this->variant = $variant; + $this->idInfo = $idInfo; $this->fallbackName = $name; - $this->itemId = $itemId; + } + + public function getIdInfo() : BlockIdentifier{ + return $this->idInfo; } /** * @return string */ public function getName() : string{ - return $this->fallbackName ?? "Unknown"; + return $this->fallbackName; } /** * @return int */ public function getId() : int{ - return $this->id; - } - - /** - * Returns the ID of the item form of the block. - * Used for drops for blocks (some blocks such as doors have a different item ID). - * - * @return int - */ - public function getItemId() : int{ - if($this->itemId !== null){ - return $this->itemId; - } - if($this->id > 255){ - return 255 - $this->id; - } - return $this->id; + return $this->idInfo->getBlockId(); } public function getItem() : Item{ - return ItemFactory::get($this->getItemId(), $this->getVariant()); + return ItemFactory::get($this->idInfo->getItemId(), $this->idInfo->getVariant()); } /** @@ -146,7 +125,7 @@ class Block extends Position implements BlockIds, Metadatable{ public function getDamage() : int{ $stateMeta = $this->writeStateToMeta(); assert(($stateMeta & ~$this->getStateBitmask()) === 0); - return $this->variant | $stateMeta; + return $this->idInfo->getVariant() | $stateMeta; } protected function writeStateToMeta() : int{ @@ -173,19 +152,10 @@ class Block extends Position implements BlockIds, Metadatable{ $this->collisionBoxes = null; } - /** - * Returns the class of Tile associated with this block. - * - * @return string|null class extending Tile, or null - */ - protected function getTileClass() : ?string{ - return null; - } - public function writeStateToWorld() : void{ $this->level->getChunkAtPosition($this)->setBlock($this->x & 0xf, $this->y, $this->z & 0xf, $this->getId(), $this->getDamage()); - $tileType = $this->getTileClass(); + $tileType = $this->idInfo->getTileClass(); $oldTile = $this->level->getTile($this); if($oldTile !== null and ($tileType === null or !($oldTile instanceof $tileType))){ $oldTile->close(); @@ -205,14 +175,6 @@ class Block extends Position implements BlockIds, Metadatable{ return 0; } - /** - * Returns the block meta, stripped of non-variant flags. - * @return int - */ - public function getVariant() : int{ - return $this->variant; - } - /** * Returns whether the given block has an equivalent type to this one. * @@ -221,7 +183,7 @@ class Block extends Position implements BlockIds, Metadatable{ * @return bool */ public function isSameType(Block $other) : bool{ - return $this->getId() === $other->getId() and $this->getVariant() === $other->getVariant(); + return $this->idInfo->getBlockId() === $other->idInfo->getBlockId() and $this->idInfo->getVariant() === $other->idInfo->getVariant(); } /** diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 11643f7ccf..f271e2ef0e 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -23,12 +23,13 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\BlockIdentifier as BID; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\block\utils\PillarRotationTrait; use pocketmine\block\utils\SlabType; use pocketmine\block\utils\TreeType; -use pocketmine\item\Item; +use pocketmine\item\ItemIds; use pocketmine\level\Position; use function array_fill; use function file_get_contents; @@ -76,256 +77,256 @@ class BlockFactory{ self::$stateMasks = new \SplFixedArray(8192); - self::register(new ActivatorRail()); - self::register(new Air()); - self::register(new Anvil(Block::ANVIL, Anvil::TYPE_NORMAL, "Anvil")); - self::register(new Anvil(Block::ANVIL, Anvil::TYPE_SLIGHTLY_DAMAGED, "Slightly Damaged Anvil")); - self::register(new Anvil(Block::ANVIL, Anvil::TYPE_VERY_DAMAGED, "Very Damaged Anvil")); - self::register(new Bed()); - self::register(new Bedrock()); - self::register(new Beetroot()); - self::register(new BoneBlock()); - self::register(new Bookshelf()); - self::register(new BrewingStand()); - self::register(new BrickStairs()); - self::register(new Bricks()); - self::register(new BrownMushroom()); - self::register(new BrownMushroomBlock()); - self::register(new Cactus()); - self::register(new Cake()); - self::register(new Carrot()); - self::register(new Chest()); - self::register(new Clay()); - self::register(new Coal()); - self::register(new CoalOre()); - self::register(new CoarseDirt(Block::DIRT, Dirt::COARSE, "Coarse Dirt")); - self::register(new Cobblestone()); - self::register(new CobblestoneStairs()); - self::register(new Cobweb()); - self::register(new CocoaBlock()); - self::register(new CraftingTable()); - self::register(new Dandelion()); - self::register(new DaylightSensor()); - self::register((new DaylightSensor())->setInverted()); //flattening hack - self::register(new DeadBush()); - self::register(new DetectorRail()); - self::register(new Diamond()); - self::register(new DiamondOre()); - self::register(new Dirt(Block::DIRT, Dirt::NORMAL, "Dirt")); - self::register(new DoublePlant(Block::DOUBLE_PLANT, 0, "Sunflower")); - self::register(new DoublePlant(Block::DOUBLE_PLANT, 1, "Lilac")); - self::register(new DoublePlant(Block::DOUBLE_PLANT, 4, "Rose Bush")); - self::register(new DoublePlant(Block::DOUBLE_PLANT, 5, "Peony")); - self::register(new DoubleTallGrass(Block::DOUBLE_PLANT, 2, "Double Tallgrass")); - self::register(new DoubleTallGrass(Block::DOUBLE_PLANT, 3, "Large Fern")); - self::register(new Emerald()); - self::register(new EmeraldOre()); - self::register(new EnchantingTable()); - self::register(new EndPortalFrame()); - self::register(new EndRod()); - self::register(new EndStone()); - self::register(new EndStoneBricks()); - self::register(new EnderChest()); - self::register(new Farmland()); - self::register(new FenceGate(Block::ACACIA_FENCE_GATE, 0, "Acacia Fence Gate")); - self::register(new FenceGate(Block::BIRCH_FENCE_GATE, 0, "Birch Fence Gate")); - self::register(new FenceGate(Block::DARK_OAK_FENCE_GATE, 0, "Dark Oak Fence Gate")); - self::register(new FenceGate(Block::JUNGLE_FENCE_GATE, 0, "Jungle Fence Gate")); - self::register(new FenceGate(Block::OAK_FENCE_GATE, 0, "Oak Fence Gate")); - self::register(new FenceGate(Block::SPRUCE_FENCE_GATE, 0, "Spruce Fence Gate")); - self::register(new Fire()); - self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_ALLIUM, "Allium")); - self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_AZURE_BLUET, "Azure Bluet")); - self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_BLUE_ORCHID, "Blue Orchid")); - self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_ORANGE_TULIP, "Orange Tulip")); - self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_OXEYE_DAISY, "Oxeye Daisy")); - self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_PINK_TULIP, "Pink Tulip")); - self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_POPPY, "Poppy")); - self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_RED_TULIP, "Red Tulip")); - self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_WHITE_TULIP, "White Tulip")); - self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_CORNFLOWER, "Cornflower")); - self::register(new Flower(Block::RED_FLOWER, Flower::TYPE_LILY_OF_THE_VALLEY, "Lily of the Valley")); - self::register(new FlowerPot()); - self::register(new Furnace()); - self::register((new Furnace())->setLit()); //flattening hack - self::register(new Glass(Block::GLASS, 0, "Glass")); - self::register(new GlassPane(Block::GLASS_PANE, 0, "Glass Pane")); - self::register(new GlazedTerracotta(Block::BLACK_GLAZED_TERRACOTTA, 0, "Black Glazed Terracotta")); - self::register(new GlazedTerracotta(Block::BLUE_GLAZED_TERRACOTTA, 0, "Blue Glazed Terracotta")); - self::register(new GlazedTerracotta(Block::BROWN_GLAZED_TERRACOTTA, 0, "Brown Glazed Terracotta")); - self::register(new GlazedTerracotta(Block::CYAN_GLAZED_TERRACOTTA, 0, "Cyan Glazed Terracotta")); - self::register(new GlazedTerracotta(Block::GRAY_GLAZED_TERRACOTTA, 0, "Grey Glazed Terracotta")); - self::register(new GlazedTerracotta(Block::GREEN_GLAZED_TERRACOTTA, 0, "Green Glazed Terracotta")); - self::register(new GlazedTerracotta(Block::LIGHT_BLUE_GLAZED_TERRACOTTA, 0, "Light Blue Glazed Terracotta")); - self::register(new GlazedTerracotta(Block::LIME_GLAZED_TERRACOTTA, 0, "Lime Glazed Terracotta")); - self::register(new GlazedTerracotta(Block::MAGENTA_GLAZED_TERRACOTTA, 0, "Magenta Glazed Terracotta")); - self::register(new GlazedTerracotta(Block::ORANGE_GLAZED_TERRACOTTA, 0, "Orange Glazed Terracotta")); - self::register(new GlazedTerracotta(Block::PINK_GLAZED_TERRACOTTA, 0, "Pink Glazed Terracotta")); - self::register(new GlazedTerracotta(Block::PURPLE_GLAZED_TERRACOTTA, 0, "Purple Glazed Terracotta")); - self::register(new GlazedTerracotta(Block::RED_GLAZED_TERRACOTTA, 0, "Red Glazed Terracotta")); - self::register(new GlazedTerracotta(Block::SILVER_GLAZED_TERRACOTTA, 0, "Light Grey Glazed Terracotta")); - self::register(new GlazedTerracotta(Block::WHITE_GLAZED_TERRACOTTA, 0, "White Glazed Terracotta")); - self::register(new GlazedTerracotta(Block::YELLOW_GLAZED_TERRACOTTA, 0, "Yellow Glazed Terracotta")); - self::register(new GlowingObsidian()); - self::register(new Glowstone()); - self::register(new Gold()); - self::register(new GoldOre()); - self::register(new Grass()); - self::register(new GrassPath()); - self::register(new Gravel()); - self::register(new HardenedClay(Block::HARDENED_CLAY, 0, "Hardened Clay")); - self::register(new HardenedGlass(Block::HARD_GLASS, 0, "Hardened Glass")); - self::register(new HardenedGlassPane(Block::HARD_GLASS_PANE, 0, "Hardened Glass Pane")); - self::register(new HayBale()); - self::register(new Ice()); - self::register(new InfoUpdate(Block::INFO_UPDATE, 0, "update!")); - self::register(new InfoUpdate(Block::INFO_UPDATE2, 0, "ate!upd")); - self::register(new InvisibleBedrock()); - self::register(new Iron()); - self::register(new IronBars()); - self::register(new IronDoor()); - self::register(new IronOre()); - self::register(new IronTrapdoor()); - self::register(new ItemFrame()); - self::register(new Ladder()); - self::register(new Lapis()); - self::register(new LapisOre()); - self::register(new Lava()); - self::register((new Lava())->setStill()); //flattening hack - self::register(new Lever()); - self::register(new LitPumpkin()); - self::register(new Magma()); - self::register(new Melon()); - self::register(new MelonStem()); - self::register(new MonsterSpawner()); - self::register(new MossyCobblestone()); - self::register(new Mycelium()); - self::register(new NetherBrick(Block::NETHER_BRICK_BLOCK, 0, "Nether Bricks")); - self::register(new NetherBrick(Block::RED_NETHER_BRICK, 0, "Red Nether Bricks")); - self::register(new NetherBrickFence()); - self::register(new NetherBrickStairs()); - self::register(new NetherQuartzOre()); - self::register(new NetherReactor()); - self::register(new NetherWartBlock()); - self::register(new NetherWartPlant()); - self::register(new Netherrack()); - self::register(new NoteBlock()); - self::register(new Obsidian()); - self::register(new PackedIce()); - self::register(new Podzol()); - self::register(new Potato()); - self::register(new PoweredRail()); - self::register(new Prismarine(Block::PRISMARINE, Prismarine::BRICKS, "Prismarine Bricks")); - self::register(new Prismarine(Block::PRISMARINE, Prismarine::DARK, "Dark Prismarine")); - self::register(new Prismarine(Block::PRISMARINE, Prismarine::NORMAL, "Prismarine")); - self::register(new Pumpkin()); - self::register(new PumpkinStem()); - self::register(new Purpur(Block::PURPUR_BLOCK, 0, "Purpur Block")); - self::register(new class(Block::PURPUR_BLOCK, 2, "Purpur Pillar") extends Purpur{ + self::register(new ActivatorRail(new BID(Block::ACTIVATOR_RAIL, BaseRail::STRAIGHT_NORTH_SOUTH), "Activator Rail")); + self::register(new Air(new BID(Block::AIR), "Air")); + self::register(new Anvil(new BID(Block::ANVIL, Anvil::TYPE_NORMAL), "Anvil")); + self::register(new Anvil(new BID(Block::ANVIL, Anvil::TYPE_SLIGHTLY_DAMAGED), "Slightly Damaged Anvil")); + self::register(new Anvil(new BID(Block::ANVIL, Anvil::TYPE_VERY_DAMAGED), "Very Damaged Anvil")); + self::register(new Bed(new BID(Block::BED_BLOCK, 0, ItemIds::BED, \pocketmine\tile\Bed::class), "Bed Block")); + self::register(new Bedrock(new BID(Block::BEDROCK), "Bedrock")); + self::register(new Beetroot(new BID(Block::BEETROOT_BLOCK), "Beetroot Block")); + self::register(new BoneBlock(new BID(Block::BONE_BLOCK), "Bone Block")); + self::register(new Bookshelf(new BID(Block::BOOKSHELF), "Bookshelf")); + self::register(new BrewingStand(new BID(Block::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND), "Brewing Stand")); + self::register(new BrickStairs(new BID(Block::BRICK_STAIRS), "Brick Stairs")); + self::register(new Bricks(new BID(Block::BRICK_BLOCK), "Bricks")); + self::register(new BrownMushroom(new BID(Block::BROWN_MUSHROOM), "Brown Mushroom")); + self::register(new BrownMushroomBlock(new BID(Block::BROWN_MUSHROOM_BLOCK), "Brown Mushroom Block")); + self::register(new Cactus(new BID(Block::CACTUS), "Cactus")); + self::register(new Cake(new BID(Block::CAKE_BLOCK, 0, ItemIds::CAKE), "Cake")); + self::register(new Carrot(new BID(Block::CARROTS), "Carrot Block")); + self::register(new Chest(new BID(Block::CHEST, 0, null, \pocketmine\tile\Chest::class), "Chest")); + self::register(new Clay(new BID(Block::CLAY_BLOCK), "Clay Block")); + self::register(new Coal(new BID(Block::COAL_BLOCK), "Coal Block")); + self::register(new CoalOre(new BID(Block::COAL_ORE), "Coal Ore")); + self::register(new CoarseDirt(new BID(Block::DIRT, Dirt::COARSE), "Coarse Dirt")); + self::register(new Cobblestone(new BID(Block::COBBLESTONE), "Cobblestone")); + self::register(new Cobblestone(new BID(Block::MOSSY_COBBLESTONE), "Moss Stone")); + self::register(new CobblestoneStairs(new BID(Block::COBBLESTONE_STAIRS), "Cobblestone Stairs")); + self::register(new Cobweb(new BID(Block::COBWEB), "Cobweb")); + self::register(new CocoaBlock(new BID(Block::COCOA), "Cocoa Block")); + self::register(new CraftingTable(new BID(Block::CRAFTING_TABLE), "Crafting Table")); + self::register(new Dandelion(new BID(Block::DANDELION), "Dandelion")); + self::register($daylightSensor = new DaylightSensor(new BlockIdentifierFlattened(Block::DAYLIGHT_DETECTOR, Block::DAYLIGHT_DETECTOR_INVERTED), "Daylight Sensor")); + self::register((clone $daylightSensor)->setInverted()); //flattening hack + self::register(new DeadBush(new BID(Block::DEADBUSH), "Dead Bush")); + self::register(new DetectorRail(new BID(Block::DETECTOR_RAIL), "Detector Rail")); + self::register(new Diamond(new BID(Block::DIAMOND_BLOCK), "Diamond Block")); + self::register(new DiamondOre(new BID(Block::DIAMOND_ORE), "Diamond Ore")); + self::register(new Dirt(new BID(Block::DIRT, Dirt::NORMAL), "Dirt")); + self::register(new DoublePlant(new BID(Block::DOUBLE_PLANT, 0), "Sunflower")); + self::register(new DoublePlant(new BID(Block::DOUBLE_PLANT, 1), "Lilac")); + self::register(new DoublePlant(new BID(Block::DOUBLE_PLANT, 4), "Rose Bush")); + self::register(new DoublePlant(new BID(Block::DOUBLE_PLANT, 5), "Peony")); + self::register(new DoubleTallGrass(new BID(Block::DOUBLE_PLANT, 2), "Double Tallgrass")); + self::register(new DoubleTallGrass(new BID(Block::DOUBLE_PLANT, 3), "Large Fern")); + self::register(new Emerald(new BID(Block::EMERALD_BLOCK), "Emerald Block")); + self::register(new EmeraldOre(new BID(Block::EMERALD_ORE), "Emerald Ore")); + self::register(new EnchantingTable(new BID(Block::ENCHANTING_TABLE, 0, null, \pocketmine\tile\EnchantTable::class), "Enchanting Table")); + self::register(new EndPortalFrame(new BID(Block::END_PORTAL_FRAME), "End Portal Frame")); + self::register(new EndRod(new BID(Block::END_ROD), "End Rod")); + self::register(new EndStone(new BID(Block::END_STONE), "End Stone")); + self::register(new EndStoneBricks(new BID(Block::END_BRICKS), "End Stone Bricks")); + self::register(new EnderChest(new BID(Block::ENDER_CHEST, 0, null, \pocketmine\tile\EnderChest::class), "Ender Chest")); + self::register(new Farmland(new BID(Block::FARMLAND), "Farmland")); + self::register(new FenceGate(new BID(Block::ACACIA_FENCE_GATE), "Acacia Fence Gate")); + self::register(new FenceGate(new BID(Block::BIRCH_FENCE_GATE), "Birch Fence Gate")); + self::register(new FenceGate(new BID(Block::DARK_OAK_FENCE_GATE), "Dark Oak Fence Gate")); + self::register(new FenceGate(new BID(Block::OAK_FENCE_GATE), "Oak Fence Gate")); + self::register(new FenceGate(new BID(Block::JUNGLE_FENCE_GATE), "Jungle Fence Gate")); + self::register(new FenceGate(new BID(Block::SPRUCE_FENCE_GATE), "Spruce Fence Gate")); + self::register(new Fire(new BID(Block::FIRE), "Fire Block")); + self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_ALLIUM), "Allium")); + self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_AZURE_BLUET), "Azure Bluet")); + self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_BLUE_ORCHID), "Blue Orchid")); + self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_CORNFLOWER), "Cornflower")); + self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_LILY_OF_THE_VALLEY), "Lily of the Valley")); + self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_ORANGE_TULIP), "Orange Tulip")); + self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_OXEYE_DAISY), "Oxeye Daisy")); + self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_PINK_TULIP), "Pink Tulip")); + self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_POPPY), "Poppy")); + self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_RED_TULIP), "Red Tulip")); + self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_WHITE_TULIP), "White Tulip")); + self::register(new FlowerPot(new BID(Block::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, \pocketmine\tile\FlowerPot::class), "Flower Pot")); + self::register($furnace = new Furnace(new BlockIdentifierFlattened(Block::FURNACE, Block::LIT_FURNACE, 0, null, \pocketmine\tile\Furnace::class), "Furnace")); + self::register((clone $furnace)->setLit()); //flattening hack + self::register(new Glass(new BID(Block::GLASS), "Glass")); + self::register(new GlassPane(new BID(Block::GLASS_PANE), "Glass Pane")); + self::register(new GlazedTerracotta(new BID(Block::BLACK_GLAZED_TERRACOTTA), "Black Glazed Terracotta")); + self::register(new GlazedTerracotta(new BID(Block::BLUE_GLAZED_TERRACOTTA), "Blue Glazed Terracotta")); + self::register(new GlazedTerracotta(new BID(Block::BROWN_GLAZED_TERRACOTTA), "Brown Glazed Terracotta")); + self::register(new GlazedTerracotta(new BID(Block::CYAN_GLAZED_TERRACOTTA), "Cyan Glazed Terracotta")); + self::register(new GlazedTerracotta(new BID(Block::GRAY_GLAZED_TERRACOTTA), "Grey Glazed Terracotta")); + self::register(new GlazedTerracotta(new BID(Block::GREEN_GLAZED_TERRACOTTA), "Green Glazed Terracotta")); + self::register(new GlazedTerracotta(new BID(Block::LIGHT_BLUE_GLAZED_TERRACOTTA), "Light Blue Glazed Terracotta")); + self::register(new GlazedTerracotta(new BID(Block::LIME_GLAZED_TERRACOTTA), "Lime Glazed Terracotta")); + self::register(new GlazedTerracotta(new BID(Block::MAGENTA_GLAZED_TERRACOTTA), "Magenta Glazed Terracotta")); + self::register(new GlazedTerracotta(new BID(Block::ORANGE_GLAZED_TERRACOTTA), "Orange Glazed Terracotta")); + self::register(new GlazedTerracotta(new BID(Block::PINK_GLAZED_TERRACOTTA), "Pink Glazed Terracotta")); + self::register(new GlazedTerracotta(new BID(Block::PURPLE_GLAZED_TERRACOTTA), "Purple Glazed Terracotta")); + self::register(new GlazedTerracotta(new BID(Block::RED_GLAZED_TERRACOTTA), "Red Glazed Terracotta")); + self::register(new GlazedTerracotta(new BID(Block::SILVER_GLAZED_TERRACOTTA), "Light Grey Glazed Terracotta")); + self::register(new GlazedTerracotta(new BID(Block::WHITE_GLAZED_TERRACOTTA), "White Glazed Terracotta")); + self::register(new GlazedTerracotta(new BID(Block::YELLOW_GLAZED_TERRACOTTA), "Yellow Glazed Terracotta")); + self::register(new GlowingObsidian(new BID(Block::GLOWINGOBSIDIAN), "Glowing Obsidian")); + self::register(new Glowstone(new BID(Block::GLOWSTONE), "Glowstone")); + self::register(new Gold(new BID(Block::GOLD_BLOCK), "Gold Block")); + self::register(new GoldOre(new BID(Block::GOLD_ORE), "Gold Ore")); + self::register(new Grass(new BID(Block::GRASS), "Grass")); + self::register(new GrassPath(new BID(Block::GRASS_PATH), "Grass Path")); + self::register(new Gravel(new BID(Block::GRAVEL), "Gravel")); + self::register(new HardenedClay(new BID(Block::HARDENED_CLAY), "Hardened Clay")); + self::register(new HardenedGlass(new BID(Block::HARD_GLASS), "Hardened Glass")); + self::register(new HardenedGlassPane(new BID(Block::HARD_GLASS_PANE), "Hardened Glass Pane")); + self::register(new HayBale(new BID(Block::HAY_BALE), "Hay Bale")); + self::register(new Ice(new BID(Block::ICE), "Ice")); + self::register(new InfoUpdate(new BID(Block::INFO_UPDATE), "update!")); + self::register(new InfoUpdate(new BID(Block::INFO_UPDATE2), "ate!upd")); + self::register(new InvisibleBedrock(new BID(Block::INVISIBLEBEDROCK), "Invisible Bedrock")); + self::register(new Iron(new BID(Block::IRON_BLOCK), "Iron Block")); + self::register(new IronBars(new BID(Block::IRON_BARS), "Iron Bars")); + self::register(new IronDoor(new BID(Block::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door")); + self::register(new IronOre(new BID(Block::IRON_ORE), "Iron Ore")); + self::register(new IronTrapdoor(new BID(Block::IRON_TRAPDOOR), "Iron Trapdoor")); + self::register(new ItemFrame(new BID(Block::FRAME_BLOCK, 0, ItemIds::FRAME, \pocketmine\tile\ItemFrame::class), "Item Frame")); + self::register(new Ladder(new BID(Block::LADDER), "Ladder")); + self::register(new Lapis(new BID(Block::LAPIS_BLOCK), "Lapis Lazuli Block")); + self::register(new LapisOre(new BID(Block::LAPIS_ORE), "Lapis Lazuli Ore")); + self::register($lava = new Lava(new BlockIdentifierFlattened(Block::FLOWING_LAVA, Block::STILL_LAVA), "Lava")); + self::register((clone $lava)->setStill()); //flattening hack + self::register(new Lever(new BID(Block::LEVER), "Lever")); + self::register(new LitPumpkin(new BID(Block::JACK_O_LANTERN), "Jack o'Lantern")); + self::register(new Magma(new BID(Block::MAGMA), "Magma Block")); + self::register(new Melon(new BID(Block::MELON_BLOCK), "Melon Block")); + self::register(new MelonStem(new BID(Block::MELON_STEM, 0, ItemIds::MELON_SEEDS), "Melon Stem")); + self::register(new MonsterSpawner(new BID(Block::MOB_SPAWNER), "Monster Spawner")); + self::register(new Mycelium(new BID(Block::MYCELIUM), "Mycelium")); + self::register(new NetherBrick(new BID(Block::NETHER_BRICK_BLOCK), "Nether Bricks")); + self::register(new NetherBrick(new BID(Block::RED_NETHER_BRICK), "Red Nether Bricks")); + self::register(new NetherBrickFence(new BID(Block::NETHER_BRICK_FENCE), "Nether Brick Fence")); + self::register(new NetherBrickStairs(new BID(Block::NETHER_BRICK_STAIRS), "Nether Brick Stairs")); + self::register(new NetherQuartzOre(new BID(Block::NETHER_QUARTZ_ORE), "Nether Quartz Ore")); + self::register(new NetherReactor(new BID(Block::NETHERREACTOR), "Nether Reactor Core")); + self::register(new NetherWartBlock(new BID(Block::NETHER_WART_BLOCK), "Nether Wart Block")); + self::register(new NetherWartPlant(new BID(Block::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART), "Nether Wart")); + self::register(new Netherrack(new BID(Block::NETHERRACK), "Netherrack")); + self::register(new NoteBlock(new BID(Block::NOTEBLOCK), "Note Block")); + self::register(new Obsidian(new BID(Block::OBSIDIAN), "Obsidian")); + self::register(new PackedIce(new BID(Block::PACKED_ICE), "Packed Ice")); + self::register(new Podzol(new BID(Block::PODZOL), "Podzol")); + self::register(new Potato(new BID(Block::POTATOES), "Potato Block")); + self::register(new PoweredRail(new BID(Block::GOLDEN_RAIL, BaseRail::STRAIGHT_NORTH_SOUTH), "Powered Rail")); + self::register(new Prismarine(new BID(Block::PRISMARINE, Prismarine::BRICKS), "Prismarine Bricks")); + self::register(new Prismarine(new BID(Block::PRISMARINE, Prismarine::DARK), "Dark Prismarine")); + self::register(new Prismarine(new BID(Block::PRISMARINE, Prismarine::NORMAL), "Prismarine")); + self::register(new Pumpkin(new BID(Block::PUMPKIN), "Pumpkin")); + self::register(new PumpkinStem(new BID(Block::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem")); + self::register(new Purpur(new BID(Block::PURPUR_BLOCK), "Purpur Block")); + self::register(new class(new BID(Block::PURPUR_BLOCK, 2), "Purpur Pillar") extends Purpur{ use PillarRotationTrait; }); - self::register(new PurpurStairs()); - self::register(new Quartz(Block::QUARTZ_BLOCK, Quartz::NORMAL, "Quartz Block")); - self::register(new class(Block::QUARTZ_BLOCK, Quartz::CHISELED, "Chiseled Quartz Block") extends Quartz{ + self::register(new PurpurStairs(new BID(Block::PURPUR_STAIRS), "Purpur Stairs")); + self::register(new Quartz(new BID(Block::QUARTZ_BLOCK, Quartz::NORMAL), "Quartz Block")); + self::register(new class(new BID(Block::QUARTZ_BLOCK, Quartz::CHISELED), "Chiseled Quartz Block") extends Quartz{ use PillarRotationTrait; }); - self::register(new class(Block::QUARTZ_BLOCK, Quartz::PILLAR, "Quartz Pillar") extends Quartz{ + self::register(new class(new BID(Block::QUARTZ_BLOCK, Quartz::PILLAR), "Quartz Pillar") extends Quartz{ use PillarRotationTrait; }); - self::register(new Quartz(Block::QUARTZ_BLOCK, Quartz::SMOOTH, "Smooth Quartz Block")); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) - self::register(new QuartzStairs()); - self::register(new Rail()); - self::register(new RedMushroom()); - self::register(new RedMushroomBlock()); - self::register(new RedSandstoneStairs()); - self::register(new Redstone()); - self::register(new RedstoneLamp()); - self::register((new RedstoneLamp())->setLit()); //flattening hack - self::register(new RedstoneOre()); - self::register((new RedstoneOre())->setLit()); //flattening hack - self::register(new RedstoneRepeater()); - self::register((new RedstoneRepeater())->setPowered()); - self::register(new RedstoneTorch()); - self::register((new RedstoneTorch())->setLit(false)); //flattening hack - self::register(new RedstoneWire()); - self::register(new Reserved6(Block::RESERVED6, 0, "reserved6")); - self::register(new Sand(Block::SAND, 0, "Sand")); - self::register(new Sand(Block::SAND, 1, "Red Sand")); - self::register(new SandstoneStairs()); - self::register(new SeaLantern()); - self::register(new SignPost()); - self::register(new Skull()); - self::register(new SmoothStone(Block::STONE, Stone::NORMAL, "Stone")); - self::register(new Snow()); - self::register(new SnowLayer()); - self::register(new SoulSand()); - self::register(new Sponge()); - self::register(new StandingBanner()); - self::register(new Stone(Block::STONE, Stone::ANDESITE, "Andesite")); - self::register(new Stone(Block::STONE, Stone::DIORITE, "Diorite")); - self::register(new Stone(Block::STONE, Stone::GRANITE, "Granite")); - self::register(new Stone(Block::STONE, Stone::POLISHED_ANDESITE, "Polished Andesite")); - self::register(new Stone(Block::STONE, Stone::POLISHED_DIORITE, "Polished Diorite")); - self::register(new Stone(Block::STONE, Stone::POLISHED_GRANITE, "Polished Granite")); - self::register(new StoneBrickStairs()); - self::register(new StoneBricks(Block::STONE_BRICKS, StoneBricks::CHISELED, "Chiseled Stone Bricks")); - self::register(new StoneBricks(Block::STONE_BRICKS, StoneBricks::CRACKED, "Cracked Stone Bricks")); - self::register(new StoneBricks(Block::STONE_BRICKS, StoneBricks::MOSSY, "Mossy Stone Bricks")); - self::register(new StoneBricks(Block::STONE_BRICKS, StoneBricks::NORMAL, "Stone Bricks")); - self::register(new StoneButton()); - self::register(new StonePressurePlate()); - self::register(new Stonecutter()); - self::register(new Sugarcane()); - self::register(new TNT()); - self::register(new TallGrass(Block::TALL_GRASS, 0, "Fern")); - self::register(new TallGrass(Block::TALL_GRASS, 1, "Tall Grass")); - self::register(new TallGrass(Block::TALL_GRASS, 2, "Fern")); - self::register(new TallGrass(Block::TALL_GRASS, 3, "Fern")); - self::register(new Torch(Block::COLORED_TORCH_BP, 0, "Blue Torch")); - self::register(new Torch(Block::COLORED_TORCH_BP, 8, "Purple Torch")); - self::register(new Torch(Block::COLORED_TORCH_RG, 0, "Red Torch")); - self::register(new Torch(Block::COLORED_TORCH_RG, 8, "Green Torch")); - self::register(new Torch(Block::TORCH, 0, "Torch")); - self::register(new Trapdoor()); - self::register(new TrappedChest()); - self::register(new Tripwire()); - self::register(new TripwireHook()); - self::register(new UnderwaterTorch(Block::UNDERWATER_TORCH, 0, "Underwater Torch")); - self::register(new Vine()); - self::register(new WallBanner()); - self::register(new WallSign()); - self::register(new Water()); - self::register((new Water())->setStill()); //flattening hack - self::register(new WaterLily()); - self::register(new WeightedPressurePlateHeavy()); - self::register(new WeightedPressurePlateLight()); - self::register(new Wheat()); - self::register(new WoodenButton()); - self::register(new WoodenDoor(Block::ACACIA_DOOR_BLOCK, 0, "Acacia Door", Item::ACACIA_DOOR)); - self::register(new WoodenDoor(Block::BIRCH_DOOR_BLOCK, 0, "Birch Door", Item::BIRCH_DOOR)); - self::register(new WoodenDoor(Block::DARK_OAK_DOOR_BLOCK, 0, "Dark Oak Door", Item::DARK_OAK_DOOR)); - self::register(new WoodenDoor(Block::JUNGLE_DOOR_BLOCK, 0, "Jungle Door", Item::JUNGLE_DOOR)); - self::register(new WoodenDoor(Block::OAK_DOOR_BLOCK, 0, "Oak Door", Item::OAK_DOOR)); - self::register(new WoodenDoor(Block::SPRUCE_DOOR_BLOCK, 0, "Spruce Door", Item::SPRUCE_DOOR)); - self::register(new WoodenPressurePlate()); - self::register(new WoodenStairs(Block::ACACIA_STAIRS, 0, "Acacia Stairs")); - self::register(new WoodenStairs(Block::BIRCH_STAIRS, 0, "Birch Stairs")); - self::register(new WoodenStairs(Block::DARK_OAK_STAIRS, 0, "Dark Oak Stairs")); - self::register(new WoodenStairs(Block::JUNGLE_STAIRS, 0, "Jungle Stairs")); - self::register(new WoodenStairs(Block::OAK_STAIRS, 0, "Oak Stairs")); - self::register(new WoodenStairs(Block::SPRUCE_STAIRS, 0, "Spruce Stairs")); + self::register(new Quartz(new BID(Block::QUARTZ_BLOCK, Quartz::SMOOTH), "Smooth Quartz Block")); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) + self::register(new QuartzStairs(new BID(Block::QUARTZ_STAIRS), "Quartz Stairs")); + self::register(new Rail(new BID(Block::RAIL), "Rail")); + self::register(new RedMushroom(new BID(Block::RED_MUSHROOM), "Red Mushroom")); + self::register(new RedMushroomBlock(new BID(Block::RED_MUSHROOM_BLOCK), "Red Mushroom Block")); + self::register(new Redstone(new BID(Block::REDSTONE_BLOCK), "Redstone Block")); + self::register($redstoneLamp = new RedstoneLamp(new BlockIdentifierFlattened(Block::REDSTONE_LAMP, Block::LIT_REDSTONE_LAMP), "Redstone Lamp")); + self::register((clone $redstoneLamp)->setLit()); //flattening hack + self::register($redstoneOre = new RedstoneOre(new BlockIdentifierFlattened(Block::REDSTONE_ORE, Block::LIT_REDSTONE_ORE), "Redstone Ore")); + self::register((clone $redstoneOre)->setLit()); //flattening hack + self::register($repeater = new RedstoneRepeater(new BlockIdentifierFlattened(Block::UNPOWERED_REPEATER, Block::POWERED_REPEATER, 0, ItemIds::REPEATER), "Redstne Repeater")); + self::register((clone $repeater)->setPowered()); + self::register($redstoneTorch = new RedstoneTorch(new BlockIdentifierFlattened(Block::REDSTONE_TORCH, Block::UNLIT_REDSTONE_TORCH), "Redstone Torch")); + self::register((clone $redstoneTorch)->setLit(false)); //flattening hack + self::register(new RedstoneWire(new BID(Block::REDSTONE_WIRE, 0, ItemIds::REDSTONE), "Redstone")); + self::register(new Reserved6(new BID(Block::RESERVED6), "reserved6")); + self::register(new Sand(new BID(Block::SAND), "Sand")); + self::register(new Sand(new BID(Block::SAND, 1), "Red Sand")); + self::register(new SandstoneStairs(new BID(Block::RED_SANDSTONE_STAIRS), "Red Sandstone Stairs")); + self::register(new SandstoneStairs(new BID(Block::SANDSTONE_STAIRS), "Sandstone Stairs")); + self::register(new SeaLantern(new BID(Block::SEALANTERN), "Sea Lantern")); + self::register(new SignPost(new BID(Block::SIGN_POST, 0, ItemIds::SIGN, \pocketmine\tile\Sign::class), "Sign Post")); + self::register(new Skull(new BID(Block::MOB_HEAD_BLOCK, 0, null, \pocketmine\tile\Skull::class), "Mob Head")); + self::register(new SmoothStone(new BID(Block::STONE, Stone::NORMAL), "Stone")); + self::register(new Snow(new BID(Block::SNOW), "Snow Block")); + self::register(new SnowLayer(new BID(Block::SNOW_LAYER), "Snow Layer")); + self::register(new SoulSand(new BID(Block::SOUL_SAND), "Soul Sand")); + self::register(new Sponge(new BID(Block::SPONGE), "Sponge")); + self::register(new StandingBanner(new BID(Block::STANDING_BANNER, 0, ItemIds::BANNER, \pocketmine\tile\Banner::class), "Standing Banner")); + self::register(new Stone(new BID(Block::STONE, Stone::ANDESITE), "Andesite")); + self::register(new Stone(new BID(Block::STONE, Stone::DIORITE), "Diorite")); + self::register(new Stone(new BID(Block::STONE, Stone::GRANITE), "Granite")); + self::register(new Stone(new BID(Block::STONE, Stone::POLISHED_ANDESITE), "Polished Andesite")); + self::register(new Stone(new BID(Block::STONE, Stone::POLISHED_DIORITE), "Polished Diorite")); + self::register(new Stone(new BID(Block::STONE, Stone::POLISHED_GRANITE), "Polished Granite")); + self::register(new StoneBrickStairs(new BID(Block::STONE_BRICK_STAIRS), "Stone Brick Stairs")); + self::register(new StoneBricks(new BID(Block::STONEBRICK, StoneBricks::CHISELED), "Chiseled Stone Bricks")); + self::register(new StoneBricks(new BID(Block::STONEBRICK, StoneBricks::CRACKED), "Cracked Stone Bricks")); + self::register(new StoneBricks(new BID(Block::STONEBRICK, StoneBricks::MOSSY), "Mossy Stone Bricks")); + self::register(new StoneBricks(new BID(Block::STONEBRICK, StoneBricks::NORMAL), "Stone Bricks")); + self::register(new StoneButton(new BID(Block::STONE_BUTTON), "Stone Button")); + self::register(new StonePressurePlate(new BID(Block::STONE_PRESSURE_PLATE), "Stone Pressure Plate")); + self::register(new Stonecutter(new BID(Block::STONECUTTER), "Stonecutter")); + self::register(new Sugarcane(new BID(Block::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane")); + self::register(new TNT(new BID(Block::TNT), "TNT")); + self::register(new TallGrass(new BID(Block::TALLGRASS), "Fern")); + self::register(new TallGrass(new BID(Block::TALLGRASS, 1), "Tall Grass")); + self::register(new TallGrass(new BID(Block::TALLGRASS, 2), "Fern")); + self::register(new TallGrass(new BID(Block::TALLGRASS, 3), "Fern")); + self::register(new Torch(new BID(Block::COLORED_TORCH_BP), "Blue Torch")); + self::register(new Torch(new BID(Block::COLORED_TORCH_BP, 8), "Purple Torch")); + self::register(new Torch(new BID(Block::COLORED_TORCH_RG), "Red Torch")); + self::register(new Torch(new BID(Block::COLORED_TORCH_RG, 8), "Green Torch")); + self::register(new Torch(new BID(Block::TORCH), "Torch")); + self::register(new Trapdoor(new BID(Block::TRAPDOOR), "Wooden Trapdoor")); + self::register(new TrappedChest(new BID(Block::TRAPPED_CHEST, 0, null, \pocketmine\tile\Chest::class), "Trapped Chest")); + self::register(new Tripwire(new BID(Block::TRIPWIRE), "Tripwire")); + self::register(new TripwireHook(new BID(Block::TRIPWIRE_HOOK), "Tripwire Hook")); + self::register(new UnderwaterTorch(new BID(Block::UNDERWATER_TORCH), "Underwater Torch")); + self::register(new Vine(new BID(Block::VINE), "Vines")); + self::register(new WallBanner(new BID(Block::WALL_BANNER, 0, ItemIds::BANNER, \pocketmine\tile\Banner::class), "Wall Banner")); + self::register(new WallSign(new BID(Block::WALL_SIGN, 0, ItemIds::SIGN, \pocketmine\tile\Sign::class), "Wall Sign")); + self::register($water = new Water(new BlockIdentifierFlattened(Block::FLOWING_WATER, Block::STILL_WATER), "Water")); + self::register((clone $water)->setStill()); //flattening hack + self::register(new WaterLily(new BID(Block::LILY_PAD), "Lily Pad")); + self::register(new WeightedPressurePlateHeavy(new BID(Block::HEAVY_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Heavy")); + self::register(new WeightedPressurePlateLight(new BID(Block::LIGHT_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Light")); + self::register(new Wheat(new BID(Block::WHEAT_BLOCK), "Wheat Block")); + self::register(new WoodenButton(new BID(Block::WOODEN_BUTTON), "Wooden Button")); + self::register(new WoodenDoor(new BID(Block::ACACIA_DOOR_BLOCK, 0, ItemIds::ACACIA_DOOR), "Acacia Door")); + self::register(new WoodenDoor(new BID(Block::BIRCH_DOOR_BLOCK, 0, ItemIds::BIRCH_DOOR), "Birch Door")); + self::register(new WoodenDoor(new BID(Block::DARK_OAK_DOOR_BLOCK, 0, ItemIds::DARK_OAK_DOOR), "Dark Oak Door")); + self::register(new WoodenDoor(new BID(Block::JUNGLE_DOOR_BLOCK, 0, ItemIds::JUNGLE_DOOR), "Jungle Door")); + self::register(new WoodenDoor(new BID(Block::OAK_DOOR_BLOCK, 0, ItemIds::OAK_DOOR), "Oak Door")); + self::register(new WoodenDoor(new BID(Block::SPRUCE_DOOR_BLOCK, 0, ItemIds::SPRUCE_DOOR), "Spruce Door")); + self::register(new WoodenPressurePlate(new BID(Block::WOODEN_PRESSURE_PLATE), "Wooden Pressure Plate")); + self::register(new WoodenStairs(new BID(Block::ACACIA_STAIRS), "Acacia Stairs")); + self::register(new WoodenStairs(new BID(Block::BIRCH_STAIRS), "Birch Stairs")); + self::register(new WoodenStairs(new BID(Block::DARK_OAK_STAIRS), "Dark Oak Stairs")); + self::register(new WoodenStairs(new BID(Block::JUNGLE_STAIRS), "Jungle Stairs")); + self::register(new WoodenStairs(new BID(Block::OAK_STAIRS), "Oak Stairs")); + self::register(new WoodenStairs(new BID(Block::SPRUCE_STAIRS), "Spruce Stairs")); foreach(TreeType::getAll() as $treeType){ $magicNumber = $treeType->getMagicNumber(); $name = $treeType->getDisplayName(); - self::register(new Planks(Block::PLANKS, $magicNumber, $name . " Planks")); - self::register(new Sapling(Block::SAPLING, $magicNumber, $treeType, $name . " Sapling")); - self::register(new WoodenFence(Block::FENCE, $magicNumber, $name . " Fence")); + self::register(new Planks(new BID(Block::PLANKS, $magicNumber), $name . " Planks")); + self::register(new Sapling(new BID(Block::SAPLING, $magicNumber), $name . " Sapling", $treeType)); + self::register(new WoodenFence(new BID(Block::FENCE, $magicNumber), $name . " Fence")); //TODO: find a better way to deal with this split - self::register(new Leaves($magicNumber >= 4 ? Block::LEAVES2 : Block::LEAVES, $magicNumber & 0x03, $treeType, $name . " Leaves")); - self::register(new Log($magicNumber >= 4 ? Block::WOOD2 : Block::WOOD, $magicNumber & 0x03, $treeType, $name . " Log")); - self::register(new Wood($magicNumber >= 4 ? Block::WOOD2 : Block::WOOD, ($magicNumber & 0x03) | 0b1100, $treeType, $name . " Wood")); + self::register(new Leaves(new BID($magicNumber >= 4 ? Block::LEAVES2 : Block::LEAVES, $magicNumber & 0x03), $name . " Leaves", $treeType)); + self::register(new Log(new BID($magicNumber >= 4 ? Block::WOOD2 : Block::WOOD, $magicNumber & 0x03), $name . " Log", $treeType)); + self::register(new Wood(new BID($magicNumber >= 4 ? Block::WOOD2 : Block::WOOD, ($magicNumber & 0x03) | 0b1100), $name . " Wood", $treeType)); } static $sandstoneTypes = [ @@ -335,43 +336,43 @@ class BlockFactory{ Sandstone::SMOOTH => "Smooth " ]; foreach($sandstoneTypes as $variant => $prefix){ - self::register(new Sandstone(Block::SANDSTONE, $variant, $prefix . "Sandstone")); - self::register(new Sandstone(Block::RED_SANDSTONE, $variant, $prefix . "Red Sandstone")); + self::register(new Sandstone(new BID(Block::SANDSTONE, $variant), $prefix . "Sandstone")); + self::register(new Sandstone(new BID(Block::RED_SANDSTONE, $variant), $prefix . "Red Sandstone")); } foreach(DyeColor::getAll() as $color){ - self::register(new Carpet(Block::CARPET, $color->getMagicNumber(), $color->getDisplayName() . " Carpet")); - self::register(new Concrete(Block::CONCRETE, $color->getMagicNumber(), $color->getDisplayName() . " Concrete")); - self::register(new ConcretePowder(Block::CONCRETE_POWDER, $color->getMagicNumber(), $color->getDisplayName() . " Concrete Powder")); - self::register(new Glass(Block::STAINED_GLASS, $color->getMagicNumber(), $color->getDisplayName() . " Stained Glass")); - self::register(new GlassPane(Block::STAINED_GLASS_PANE, $color->getMagicNumber(), $color->getDisplayName() . " Stained Glass Pane")); - self::register(new HardenedClay(Block::STAINED_CLAY, $color->getMagicNumber(), $color->getDisplayName() . " Stained Clay")); - self::register(new HardenedGlass(Block::HARD_STAINED_GLASS, $color->getMagicNumber(), "Hardened " . $color->getDisplayName() . " Stained Glass")); - self::register(new HardenedGlassPane(Block::HARD_STAINED_GLASS_PANE, $color->getMagicNumber(), "Hardened " . $color->getDisplayName() . " Stained Glass Pane")); - self::register(new Wool(Block::WOOL, $color->getMagicNumber(), $color->getDisplayName() . " Wool")); + self::register(new Carpet(new BID(Block::CARPET, $color->getMagicNumber()), $color->getDisplayName() . " Carpet")); + self::register(new Concrete(new BID(Block::CONCRETE, $color->getMagicNumber()), $color->getDisplayName() . " Concrete")); + self::register(new ConcretePowder(new BID(Block::CONCRETE_POWDER, $color->getMagicNumber()), $color->getDisplayName() . " Concrete Powder")); + self::register(new Glass(new BID(Block::STAINED_GLASS, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass")); + self::register(new GlassPane(new BID(Block::STAINED_GLASS_PANE, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass Pane")); + self::register(new HardenedClay(new BID(Block::STAINED_CLAY, $color->getMagicNumber()), $color->getDisplayName() . " Stained Clay")); + self::register(new HardenedGlass(new BID(Block::HARD_STAINED_GLASS, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass")); + self::register(new HardenedGlassPane(new BID(Block::HARD_STAINED_GLASS_PANE, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass Pane")); + self::register(new Wool(new BID(Block::WOOL, $color->getMagicNumber()), $color->getDisplayName() . " Wool")); } /** @var Slab[] $slabTypes */ $slabTypes = [ - new StoneSlab(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 0, "Stone"), - new StoneSlab(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 1, "Sandstone"), - new StoneSlab(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 2, "Fake Wooden"), - new StoneSlab(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 3, "Cobblestone"), - new StoneSlab(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 4, "Brick"), - new StoneSlab(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 5, "Stone Brick"), - new StoneSlab(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 6, "Quartz"), - new StoneSlab(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 7, "Nether Brick"), - new StoneSlab(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 0, "Red Sandstone"), - new StoneSlab(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 1, "Purpur"), - new StoneSlab(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 2, "Prismarine"), - new StoneSlab(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 3, "Dark Prismarine"), - new StoneSlab(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 4, "Prismarine Bricks"), - new StoneSlab(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 5, "Mossy Cobblestone"), - new StoneSlab(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 6, "Smooth Sandstone"), - new StoneSlab(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 7, "Red Nether Brick") + new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 0), "Stone"), + new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 1), "Sandstone"), + new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 2), "Fake Wooden"), + new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 3), "Cobblestone"), + new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 4), "Brick"), + new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 5), "Stone Brick"), + new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 6), "Quartz"), + new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 7), "Nether Brick"), + new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 0), "Red Sandstone"), + new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 1), "Purpur"), + new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 2), "Prismarine"), + new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 3), "Dark Prismarine"), + new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 4), "Prismarine Bricks"), + new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 5), "Mossy Cobblestone"), + new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 6), "Smooth Sandstone"), + new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 7), "Red Nether Brick") ]; foreach(TreeType::getAll() as $woodType){ - $slabTypes[] = new WoodenSlab(Block::WOODEN_SLAB, Block::DOUBLE_WOODEN_SLAB, $woodType->getMagicNumber(), $woodType->getDisplayName()); + $slabTypes[] = new WoodenSlab(new BlockIdentifierFlattened(Block::WOODEN_SLAB, Block::DOUBLE_WOODEN_SLAB, $woodType->getMagicNumber()), $woodType->getDisplayName()); } foreach($slabTypes as $type){ self::register($type); @@ -395,7 +396,7 @@ class BlockFactory{ CobblestoneWall::STONE_BRICK_WALL => "Stone Brick" ]; foreach($wallTypes as $magicNumber => $prefix){ - self::register(new CobblestoneWall(Block::COBBLESTONE_WALL, $magicNumber, $prefix . " Wall")); + self::register(new CobblestoneWall(new BID(Block::COBBLESTONE_WALL, $magicNumber), $prefix . " Wall")); } //TODO: minecraft:acacia_button @@ -533,8 +534,7 @@ class BlockFactory{ */ public static function register(Block $block, bool $override = false) : void{ $id = $block->getId(); - $variant = $block->getVariant(); - + $variant = $block->getIdInfo()->getVariant(); $stateMask = $block->getStateBitmask(); if(($variant & $stateMask) !== 0){ @@ -542,7 +542,7 @@ class BlockFactory{ } if(!$override and self::isRegistered($id, $variant)){ - throw new \InvalidArgumentException("Block registration conflicts with an existing block"); + throw new \InvalidArgumentException("Block registration $id:$variant conflicts with an existing block"); } for($m = $variant; $m <= ($variant | $stateMask); ++$m){ @@ -608,7 +608,7 @@ class BlockFactory{ } if($block === null){ - $block = new UnknownBlock($id, $meta); + $block = new UnknownBlock(new BID($id, $meta)); } if($pos !== null){ diff --git a/src/pocketmine/block/BlockIdentifier.php b/src/pocketmine/block/BlockIdentifier.php new file mode 100644 index 0000000000..b5e855911b --- /dev/null +++ b/src/pocketmine/block/BlockIdentifier.php @@ -0,0 +1,71 @@ +blockId = $blockId; + $this->variant = $variant; + $this->itemId = $itemId; + $this->tileClass = $tileClass; + } + + /** + * @return int + */ + public function getBlockId() : int{ + return $this->blockId; + } + + /** + * @return int + */ + public function getVariant() : int{ + return $this->variant; + } + + /** + * @return int + */ + public function getItemId() : int{ + return $this->itemId ?? ($this->blockId > 255 ? 255 - $this->blockId : $this->blockId); + } + + /** + * @return string|null + */ + public function getTileClass() : ?string{ + return $this->tileClass; + } +} diff --git a/src/pocketmine/block/MossyCobblestone.php b/src/pocketmine/block/BlockIdentifierFlattened.php similarity index 65% rename from src/pocketmine/block/MossyCobblestone.php rename to src/pocketmine/block/BlockIdentifierFlattened.php index c9b83b6c8e..026134d8a4 100644 --- a/src/pocketmine/block/MossyCobblestone.php +++ b/src/pocketmine/block/BlockIdentifierFlattened.php @@ -23,12 +23,20 @@ declare(strict_types=1); namespace pocketmine\block; +class BlockIdentifierFlattened extends BlockIdentifier{ -class MossyCobblestone extends Cobblestone{ + /** @var int */ + private $secondId; - protected $id = self::MOSSY_COBBLESTONE; + public function __construct(int $blockId, int $secondId, int $variant = 0, ?int $itemId = null, ?string $tileClass = null){ + parent::__construct($blockId, $variant, $itemId, $tileClass); + $this->secondId = $secondId; + } - public function getName() : string{ - return "Moss Stone"; + /** + * @return int + */ + public function getSecondId() : int{ + return $this->secondId; } } diff --git a/src/pocketmine/block/BoneBlock.php b/src/pocketmine/block/BoneBlock.php index b8a183a1c5..857e30df95 100644 --- a/src/pocketmine/block/BoneBlock.php +++ b/src/pocketmine/block/BoneBlock.php @@ -29,16 +29,6 @@ use pocketmine\item\TieredTool; class BoneBlock extends Solid{ use PillarRotationTrait; - protected $id = Block::BONE_BLOCK; - - public function __construct(){ - - } - - public function getName() : string{ - return "Bone Block"; - } - public function getHardness() : float{ return 2; } diff --git a/src/pocketmine/block/Bookshelf.php b/src/pocketmine/block/Bookshelf.php index 417109f648..3be95be1e8 100644 --- a/src/pocketmine/block/Bookshelf.php +++ b/src/pocketmine/block/Bookshelf.php @@ -28,16 +28,6 @@ use pocketmine\item\ItemFactory; class Bookshelf extends Solid{ - protected $id = self::BOOKSHELF; - - public function __construct(){ - - } - - public function getName() : string{ - return "Bookshelf"; - } - public function getHardness() : float{ return 1.5; } diff --git a/src/pocketmine/block/BrewingStand.php b/src/pocketmine/block/BrewingStand.php index 21bbfed483..5651d1cc3e 100644 --- a/src/pocketmine/block/BrewingStand.php +++ b/src/pocketmine/block/BrewingStand.php @@ -23,15 +23,10 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\Item; use pocketmine\item\TieredTool; class BrewingStand extends Transparent{ - protected $id = self::BREWING_STAND_BLOCK; - - protected $itemId = Item::BREWING_STAND; - /** @var bool */ protected $eastSlot = false; /** @var bool */ @@ -39,10 +34,6 @@ class BrewingStand extends Transparent{ /** @var bool */ protected $southwestSlot = false; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return ($this->eastSlot ? 0x01 : 0) | ($this->southwestSlot ? 0x02 : 0) | ($this->northwestSlot ? 0x04 : 0); } @@ -57,10 +48,6 @@ class BrewingStand extends Transparent{ return 0b111; } - public function getName() : string{ - return "Brewing Stand"; - } - public function getHardness() : float{ return 0.5; } diff --git a/src/pocketmine/block/BrickStairs.php b/src/pocketmine/block/BrickStairs.php index d8fd303935..aa5aebf17c 100644 --- a/src/pocketmine/block/BrickStairs.php +++ b/src/pocketmine/block/BrickStairs.php @@ -27,12 +27,6 @@ use pocketmine\item\TieredTool; class BrickStairs extends Stair{ - protected $id = self::BRICK_STAIRS; - - public function __construct(){ - - } - public function getHardness() : float{ return 2; } @@ -48,8 +42,4 @@ class BrickStairs extends Stair{ public function getToolHarvestLevel() : int{ return TieredTool::TIER_WOODEN; } - - public function getName() : string{ - return "Brick Stairs"; - } } diff --git a/src/pocketmine/block/Bricks.php b/src/pocketmine/block/Bricks.php index ee50e8d6a6..c96efbb4ea 100644 --- a/src/pocketmine/block/Bricks.php +++ b/src/pocketmine/block/Bricks.php @@ -27,12 +27,6 @@ use pocketmine\item\TieredTool; class Bricks extends Solid{ - protected $id = self::BRICK_BLOCK; - - public function __construct(){ - - } - public function getHardness() : float{ return 2; } @@ -48,8 +42,4 @@ class Bricks extends Solid{ public function getToolHarvestLevel() : int{ return TieredTool::TIER_WOODEN; } - - public function getName() : string{ - return "Bricks"; - } } diff --git a/src/pocketmine/block/BrownMushroom.php b/src/pocketmine/block/BrownMushroom.php index dbb78e176a..47b3bc7e60 100644 --- a/src/pocketmine/block/BrownMushroom.php +++ b/src/pocketmine/block/BrownMushroom.php @@ -25,12 +25,6 @@ namespace pocketmine\block; class BrownMushroom extends RedMushroom{ - protected $id = self::BROWN_MUSHROOM; - - public function getName() : string{ - return "Brown Mushroom"; - } - public function getLightLevel() : int{ return 1; } diff --git a/src/pocketmine/block/BrownMushroomBlock.php b/src/pocketmine/block/BrownMushroomBlock.php index 8c6b9819c3..ac94d565ca 100644 --- a/src/pocketmine/block/BrownMushroomBlock.php +++ b/src/pocketmine/block/BrownMushroomBlock.php @@ -28,12 +28,6 @@ use function mt_rand; class BrownMushroomBlock extends RedMushroomBlock{ - protected $id = Block::BROWN_MUSHROOM_BLOCK; - - public function getName() : string{ - return "Brown Mushroom Block"; - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ Item::get(Item::BROWN_MUSHROOM, 0, mt_rand(0, 2)) diff --git a/src/pocketmine/block/Button.php b/src/pocketmine/block/Button.php index bc472bbe36..1c4316d02c 100644 --- a/src/pocketmine/block/Button.php +++ b/src/pocketmine/block/Button.php @@ -37,10 +37,6 @@ abstract class Button extends Flowable{ /** @var bool */ protected $powered = false; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return $this->facing | ($this->powered ? 0x08 : 0); } diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index a99bdd5a30..0b16b7403b 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -36,15 +36,9 @@ use pocketmine\Player; class Cactus extends Transparent{ - protected $id = self::CACTUS; - /** @var int */ protected $age = 0; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return $this->age; } @@ -65,10 +59,6 @@ class Cactus extends Transparent{ return true; } - public function getName() : string{ - return "Cactus"; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ static $shrinkSize = 1 / 16; return AxisAlignedBB::one()->contract($shrinkSize, 0, $shrinkSize)->trim(Facing::UP, $shrinkSize); diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index 47d21e4385..670e19e323 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -35,17 +35,9 @@ use pocketmine\Player; class Cake extends Transparent implements FoodSource{ - protected $id = self::CAKE_BLOCK; - - protected $itemId = Item::CAKE; - /** @var int */ protected $bites = 0; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return $this->bites; } @@ -62,10 +54,6 @@ class Cake extends Transparent implements FoodSource{ return 0.5; } - public function getName() : string{ - return "Cake"; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ return AxisAlignedBB::one() ->contract(1 / 16, 0, 1 / 16) diff --git a/src/pocketmine/block/Carrot.php b/src/pocketmine/block/Carrot.php index 25297ae51c..1e2c8b4591 100644 --- a/src/pocketmine/block/Carrot.php +++ b/src/pocketmine/block/Carrot.php @@ -29,12 +29,6 @@ use function mt_rand; class Carrot extends Crops{ - protected $id = self::CARROT_BLOCK; - - public function getName() : string{ - return "Carrot Block"; - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ ItemFactory::get(Item::CARROT, 0, $this->age >= 7 ? mt_rand(1, 4) : 1) diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index b55a258289..173efc56a2 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -33,15 +33,9 @@ use pocketmine\tile\Chest as TileChest; class Chest extends Transparent{ - protected $id = self::CHEST; - /** @var int */ protected $facing = Facing::NORTH; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return $this->facing; } @@ -54,18 +48,10 @@ class Chest extends Transparent{ return 0b111; } - protected function getTileClass() : ?string{ - return TileChest::class; - } - public function getHardness() : float{ return 2.5; } - public function getName() : string{ - return "Chest"; - } - public function getToolType() : int{ return BlockToolType::TYPE_AXE; } diff --git a/src/pocketmine/block/Clay.php b/src/pocketmine/block/Clay.php index cc279b2be4..c085dec934 100644 --- a/src/pocketmine/block/Clay.php +++ b/src/pocketmine/block/Clay.php @@ -28,12 +28,6 @@ use pocketmine\item\ItemFactory; class Clay extends Solid{ - protected $id = self::CLAY_BLOCK; - - public function __construct(){ - - } - public function getHardness() : float{ return 0.6; } @@ -42,10 +36,6 @@ class Clay extends Solid{ return BlockToolType::TYPE_SHOVEL; } - public function getName() : string{ - return "Clay Block"; - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ ItemFactory::get(Item::CLAY_BALL, 0, 4) diff --git a/src/pocketmine/block/Coal.php b/src/pocketmine/block/Coal.php index 36686bee76..0bef6e93a7 100644 --- a/src/pocketmine/block/Coal.php +++ b/src/pocketmine/block/Coal.php @@ -27,12 +27,6 @@ use pocketmine\item\TieredTool; class Coal extends Solid{ - protected $id = self::COAL_BLOCK; - - public function __construct(){ - - } - public function getHardness() : float{ return 5; } @@ -45,10 +39,6 @@ class Coal extends Solid{ return TieredTool::TIER_WOODEN; } - public function getName() : string{ - return "Coal Block"; - } - public function getFuelTime() : int{ return 16000; } diff --git a/src/pocketmine/block/CoalOre.php b/src/pocketmine/block/CoalOre.php index b935df923e..aa98370a1e 100644 --- a/src/pocketmine/block/CoalOre.php +++ b/src/pocketmine/block/CoalOre.php @@ -30,12 +30,6 @@ use function mt_rand; class CoalOre extends Solid{ - protected $id = self::COAL_ORE; - - public function __construct(){ - - } - public function getHardness() : float{ return 3; } @@ -48,10 +42,6 @@ class CoalOre extends Solid{ return TieredTool::TIER_WOODEN; } - public function getName() : string{ - return "Coal Ore"; - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ ItemFactory::get(Item::COAL) diff --git a/src/pocketmine/block/Cobblestone.php b/src/pocketmine/block/Cobblestone.php index 212a858753..988e6e4647 100644 --- a/src/pocketmine/block/Cobblestone.php +++ b/src/pocketmine/block/Cobblestone.php @@ -27,12 +27,6 @@ use pocketmine\item\TieredTool; class Cobblestone extends Solid{ - protected $id = self::COBBLESTONE; - - public function __construct(){ - - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } @@ -41,10 +35,6 @@ class Cobblestone extends Solid{ return TieredTool::TIER_WOODEN; } - public function getName() : string{ - return "Cobblestone"; - } - public function getHardness() : float{ return 2; } diff --git a/src/pocketmine/block/CobblestoneStairs.php b/src/pocketmine/block/CobblestoneStairs.php index b67c1a75de..780882e087 100644 --- a/src/pocketmine/block/CobblestoneStairs.php +++ b/src/pocketmine/block/CobblestoneStairs.php @@ -27,12 +27,6 @@ use pocketmine\item\TieredTool; class CobblestoneStairs extends Stair{ - protected $id = self::COBBLESTONE_STAIRS; - - public function __construct(){ - - } - public function getHardness() : float{ return 2; } @@ -44,8 +38,4 @@ class CobblestoneStairs extends Stair{ public function getToolHarvestLevel() : int{ return TieredTool::TIER_WOODEN; } - - public function getName() : string{ - return "Cobblestone Stairs"; - } } diff --git a/src/pocketmine/block/Cobweb.php b/src/pocketmine/block/Cobweb.php index 4f424b3485..a368851d93 100644 --- a/src/pocketmine/block/Cobweb.php +++ b/src/pocketmine/block/Cobweb.php @@ -29,20 +29,10 @@ use pocketmine\item\ItemFactory; class Cobweb extends Flowable{ - protected $id = self::COBWEB; - - public function __construct(){ - - } - public function hasEntityCollision() : bool{ return true; } - public function getName() : string{ - return "Cobweb"; - } - public function getHardness() : float{ return 4; } diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index 29b852d3c5..18b7fd2221 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -36,17 +36,11 @@ use function mt_rand; class CocoaBlock extends Transparent{ - protected $id = self::COCOA_BLOCK; - /** @var int */ protected $facing = Facing::NORTH; /** @var int */ protected $age = 0; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return Bearing::fromFacing(Facing::opposite($this->facing)) | ($this->age << 2); } @@ -60,10 +54,6 @@ class CocoaBlock extends Transparent{ return 0b1111; } - public function getName() : string{ - return "Cocoa Block"; - } - public function getHardness() : float{ return 0.2; } diff --git a/src/pocketmine/block/ConcretePowder.php b/src/pocketmine/block/ConcretePowder.php index 3ff0916121..9b030bd12d 100644 --- a/src/pocketmine/block/ConcretePowder.php +++ b/src/pocketmine/block/ConcretePowder.php @@ -64,7 +64,7 @@ class ConcretePowder extends Solid implements Fallable{ continue; } if($this->getSide($i) instanceof Water){ - return BlockFactory::get(Block::CONCRETE, $this->variant); + return BlockFactory::get(Block::CONCRETE, $this->idInfo->getVariant()); } } diff --git a/src/pocketmine/block/CraftingTable.php b/src/pocketmine/block/CraftingTable.php index 113cfb6b62..369deab4e5 100644 --- a/src/pocketmine/block/CraftingTable.php +++ b/src/pocketmine/block/CraftingTable.php @@ -30,20 +30,10 @@ use pocketmine\Player; class CraftingTable extends Solid{ - protected $id = self::CRAFTING_TABLE; - - public function __construct(){ - - } - public function getHardness() : float{ return 2.5; } - public function getName() : string{ - return "Crafting Table"; - } - public function getToolType() : int{ return BlockToolType::TYPE_AXE; } diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index 4a575a8f91..6d68af781b 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -35,10 +35,6 @@ abstract class Crops extends Flowable{ /** @var int */ protected $age = 0; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return $this->age; } diff --git a/src/pocketmine/block/Dandelion.php b/src/pocketmine/block/Dandelion.php index 15be4a8711..dba08c717e 100644 --- a/src/pocketmine/block/Dandelion.php +++ b/src/pocketmine/block/Dandelion.php @@ -30,16 +30,6 @@ use pocketmine\Player; class Dandelion extends Flowable{ - protected $id = self::DANDELION; - - public function __construct(){ - - } - - public function getName() : string{ - return "Dandelion"; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); diff --git a/src/pocketmine/block/DaylightSensor.php b/src/pocketmine/block/DaylightSensor.php index cdf9814a3e..7b60e65180 100644 --- a/src/pocketmine/block/DaylightSensor.php +++ b/src/pocketmine/block/DaylightSensor.php @@ -31,8 +31,8 @@ use pocketmine\math\Vector3; use pocketmine\Player; class DaylightSensor extends Transparent{ - - protected $itemId = self::DAYLIGHT_SENSOR; + /** @var BlockIdentifierFlattened */ + protected $idInfo; /** @var int */ protected $power = 0; @@ -40,12 +40,12 @@ class DaylightSensor extends Transparent{ /** @var bool */ protected $inverted = false; - public function __construct(){ - + public function __construct(BlockIdentifierFlattened $idInfo, string $name){ + parent::__construct($idInfo, $name); } public function getId() : int{ - return $this->inverted ? self::DAYLIGHT_SENSOR_INVERTED : self::DAYLIGHT_SENSOR; + return $this->inverted ? $this->idInfo->getSecondId() : parent::getId(); } protected function writeStateToMeta() : int{ @@ -74,10 +74,6 @@ class DaylightSensor extends Transparent{ return $this; } - public function getName() : string{ - return "Daylight Sensor"; - } - public function getHardness() : float{ return 0.2; } diff --git a/src/pocketmine/block/DeadBush.php b/src/pocketmine/block/DeadBush.php index 8983275070..b1167f6390 100644 --- a/src/pocketmine/block/DeadBush.php +++ b/src/pocketmine/block/DeadBush.php @@ -32,16 +32,6 @@ use function mt_rand; class DeadBush extends Flowable{ - protected $id = self::DEAD_BUSH; - - public function __construct(){ - - } - - public function getName() : string{ - return "Dead Bush"; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if(!$this->getSide(Facing::DOWN)->isTransparent()){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/DetectorRail.php b/src/pocketmine/block/DetectorRail.php index a4eddc9107..91f29bcb5e 100644 --- a/src/pocketmine/block/DetectorRail.php +++ b/src/pocketmine/block/DetectorRail.php @@ -25,11 +25,5 @@ namespace pocketmine\block; class DetectorRail extends RedstoneRail{ - protected $id = self::DETECTOR_RAIL; - - public function getName() : string{ - return "Detector Rail"; - } - //TODO } diff --git a/src/pocketmine/block/Diamond.php b/src/pocketmine/block/Diamond.php index 83a7935b64..5086a9d090 100644 --- a/src/pocketmine/block/Diamond.php +++ b/src/pocketmine/block/Diamond.php @@ -27,20 +27,10 @@ use pocketmine\item\TieredTool; class Diamond extends Solid{ - protected $id = self::DIAMOND_BLOCK; - - public function __construct(){ - - } - public function getHardness() : float{ return 5; } - public function getName() : string{ - return "Diamond Block"; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } diff --git a/src/pocketmine/block/DiamondOre.php b/src/pocketmine/block/DiamondOre.php index 5aece22d3d..9ff8273d71 100644 --- a/src/pocketmine/block/DiamondOre.php +++ b/src/pocketmine/block/DiamondOre.php @@ -30,20 +30,10 @@ use function mt_rand; class DiamondOre extends Solid{ - protected $id = self::DIAMOND_ORE; - - public function __construct(){ - - } - public function getHardness() : float{ return 3; } - public function getName() : string{ - return "Diamond Ore"; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } diff --git a/src/pocketmine/block/Emerald.php b/src/pocketmine/block/Emerald.php index d67dc1dc78..fe85118f50 100644 --- a/src/pocketmine/block/Emerald.php +++ b/src/pocketmine/block/Emerald.php @@ -27,12 +27,6 @@ use pocketmine\item\TieredTool; class Emerald extends Solid{ - protected $id = self::EMERALD_BLOCK; - - public function __construct(){ - - } - public function getHardness() : float{ return 5; } @@ -44,8 +38,4 @@ class Emerald extends Solid{ public function getToolHarvestLevel() : int{ return TieredTool::TIER_IRON; } - - public function getName() : string{ - return "Emerald Block"; - } } diff --git a/src/pocketmine/block/EmeraldOre.php b/src/pocketmine/block/EmeraldOre.php index 590211310c..7faf6986ec 100644 --- a/src/pocketmine/block/EmeraldOre.php +++ b/src/pocketmine/block/EmeraldOre.php @@ -30,16 +30,6 @@ use function mt_rand; class EmeraldOre extends Solid{ - protected $id = self::EMERALD_ORE; - - public function __construct(){ - - } - - public function getName() : string{ - return "Emerald Ore"; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } diff --git a/src/pocketmine/block/EnchantingTable.php b/src/pocketmine/block/EnchantingTable.php index b8719674b2..c2454f657a 100644 --- a/src/pocketmine/block/EnchantingTable.php +++ b/src/pocketmine/block/EnchantingTable.php @@ -30,20 +30,9 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; -use pocketmine\tile\EnchantTable as TileEnchantingTable; class EnchantingTable extends Transparent{ - protected $id = self::ENCHANTING_TABLE; - - public function __construct(){ - - } - - protected function getTileClass() : ?string{ - return TileEnchantingTable::class; - } - public function getHardness() : float{ return 5; } @@ -52,10 +41,6 @@ class EnchantingTable extends Transparent{ return 6000; } - public function getName() : string{ - return "Enchanting Table"; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } diff --git a/src/pocketmine/block/EndPortalFrame.php b/src/pocketmine/block/EndPortalFrame.php index e15b55dc55..6d38c4bfa5 100644 --- a/src/pocketmine/block/EndPortalFrame.php +++ b/src/pocketmine/block/EndPortalFrame.php @@ -33,17 +33,11 @@ use pocketmine\Player; class EndPortalFrame extends Solid{ - protected $id = self::END_PORTAL_FRAME; - /** @var int */ protected $facing = Facing::NORTH; /** @var bool */ protected $eye = false; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return Bearing::fromFacing($this->facing) | ($this->eye ? 0x04 : 0); } @@ -61,10 +55,6 @@ class EndPortalFrame extends Solid{ return 1; } - public function getName() : string{ - return "End Portal Frame"; - } - public function getHardness() : float{ return -1; } diff --git a/src/pocketmine/block/EndRod.php b/src/pocketmine/block/EndRod.php index aedfb03d5a..2975f8f41c 100644 --- a/src/pocketmine/block/EndRod.php +++ b/src/pocketmine/block/EndRod.php @@ -32,15 +32,9 @@ use pocketmine\Player; class EndRod extends Flowable{ - protected $id = Block::END_ROD; - /** @var int */ protected $facing = Facing::DOWN; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ if(Facing::axis($this->facing) === Facing::AXIS_Y){ return $this->facing; @@ -60,10 +54,6 @@ class EndRod extends Flowable{ return 0b111; } - public function getName() : string{ - return "End Rod"; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $this->facing = $face; if($blockClicked instanceof EndRod and $blockClicked->facing === $this->facing){ diff --git a/src/pocketmine/block/EndStone.php b/src/pocketmine/block/EndStone.php index 17953f776e..c27b757db3 100644 --- a/src/pocketmine/block/EndStone.php +++ b/src/pocketmine/block/EndStone.php @@ -27,16 +27,6 @@ use pocketmine\item\TieredTool; class EndStone extends Solid{ - protected $id = self::END_STONE; - - public function __construct(){ - - } - - public function getName() : string{ - return "End Stone"; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } diff --git a/src/pocketmine/block/EndStoneBricks.php b/src/pocketmine/block/EndStoneBricks.php index 0808f18b15..2028657cb7 100644 --- a/src/pocketmine/block/EndStoneBricks.php +++ b/src/pocketmine/block/EndStoneBricks.php @@ -27,16 +27,6 @@ use pocketmine\item\TieredTool; class EndStoneBricks extends Solid{ - protected $id = self::END_BRICKS; - - public function __construct(){ - - } - - public function getName() : string{ - return "End Stone Bricks"; - } - public function getHardness() : float{ return 0.8; } diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index c4d8610860..59c3429c36 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -33,12 +33,6 @@ use pocketmine\tile\EnderChest as TileEnderChest; class EnderChest extends Chest{ - protected $id = self::ENDER_CHEST; - - protected function getTileClass() : ?string{ - return TileEnderChest::class; - } - public function getHardness() : float{ return 22.5; } @@ -51,10 +45,6 @@ class EnderChest extends Chest{ return 7; } - public function getName() : string{ - return "Ender Chest"; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index 2e862559e6..6995d21e89 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -31,15 +31,9 @@ use pocketmine\math\Facing; class Farmland extends Transparent{ - protected $id = self::FARMLAND; - /** @var int */ protected $wetness = 0; //"moisture" blockstate property in PC - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return $this->wetness; } @@ -52,10 +46,6 @@ class Farmland extends Transparent{ return 0b111; } - public function getName() : string{ - return "Farmland"; - } - public function getHardness() : float{ return 0.6; } diff --git a/src/pocketmine/block/Fire.php b/src/pocketmine/block/Fire.php index cae80261ae..cf155413c1 100644 --- a/src/pocketmine/block/Fire.php +++ b/src/pocketmine/block/Fire.php @@ -37,15 +37,9 @@ use function mt_rand; class Fire extends Flowable{ - protected $id = self::FIRE; - /** @var int */ protected $age = 0; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return $this->age; } @@ -62,10 +56,6 @@ class Fire extends Flowable{ return true; } - public function getName() : string{ - return "Fire Block"; - } - public function getLightLevel() : int{ return 15; } diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 35968885bc..4ff07b9a31 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -32,16 +32,9 @@ use pocketmine\tile\FlowerPot as TileFlowerPot; class FlowerPot extends Flowable{ - protected $id = self::FLOWER_POT_BLOCK; - protected $itemId = Item::FLOWER_POT; - /** @var bool */ protected $occupied = false; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return $this->occupied ? 1 : 0; } @@ -54,14 +47,6 @@ class FlowerPot extends Flowable{ return 0b1111; //vanilla uses various values, we only care about 1 and 0 for PE } - protected function getTileClass() : ?string{ - return TileFlowerPot::class; - } - - public function getName() : string{ - return "Flower Pot"; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ return AxisAlignedBB::one()->contract(3 / 16, 0, 3 / 16)->trim(Facing::UP, 5 / 8); } diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index 5f1449496d..63e5c3948a 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -32,20 +32,16 @@ use pocketmine\Player; use pocketmine\tile\Furnace as TileFurnace; class Furnace extends Solid{ - - protected $itemId = self::FURNACE; + /** @var BlockIdentifierFlattened */ + protected $idInfo; /** @var int */ protected $facing = Facing::NORTH; /** @var bool */ protected $lit = false; //this is set based on the blockID - public function __construct(){ - - } - public function getId() : int{ - return $this->lit ? Block::BURNING_FURNACE : Block::FURNACE; + return $this->lit ? $this->idInfo->getSecondId() : parent::getId(); } protected function writeStateToMeta() : int{ @@ -60,14 +56,6 @@ class Furnace extends Solid{ return 0b111; } - protected function getTileClass() : ?string{ - return TileFurnace::class; - } - - public function getName() : string{ - return "Furnace"; - } - public function getHardness() : float{ return 3.5; } diff --git a/src/pocketmine/block/GlowingObsidian.php b/src/pocketmine/block/GlowingObsidian.php index 51e81c4502..ac0908a86e 100644 --- a/src/pocketmine/block/GlowingObsidian.php +++ b/src/pocketmine/block/GlowingObsidian.php @@ -28,16 +28,6 @@ use pocketmine\item\TieredTool; class GlowingObsidian extends Solid{ - protected $id = self::GLOWING_OBSIDIAN; - - public function __construct(){ - - } - - public function getName() : string{ - return "Glowing Obsidian"; - } - public function getLightLevel() : int{ return 12; } diff --git a/src/pocketmine/block/Glowstone.php b/src/pocketmine/block/Glowstone.php index 11a59b2c14..54a3784c98 100644 --- a/src/pocketmine/block/Glowstone.php +++ b/src/pocketmine/block/Glowstone.php @@ -29,16 +29,6 @@ use function mt_rand; class Glowstone extends Transparent{ - protected $id = self::GLOWSTONE; - - public function __construct(){ - - } - - public function getName() : string{ - return "Glowstone"; - } - public function getHardness() : float{ return 0.3; } diff --git a/src/pocketmine/block/Gold.php b/src/pocketmine/block/Gold.php index 8e6aa97c25..ce18ed78b3 100644 --- a/src/pocketmine/block/Gold.php +++ b/src/pocketmine/block/Gold.php @@ -27,16 +27,6 @@ use pocketmine\item\TieredTool; class Gold extends Solid{ - protected $id = self::GOLD_BLOCK; - - public function __construct(){ - - } - - public function getName() : string{ - return "Gold Block"; - } - public function getHardness() : float{ return 3; } diff --git a/src/pocketmine/block/GoldOre.php b/src/pocketmine/block/GoldOre.php index 9ef07f4cce..a4b465ee49 100644 --- a/src/pocketmine/block/GoldOre.php +++ b/src/pocketmine/block/GoldOre.php @@ -27,16 +27,6 @@ use pocketmine\item\TieredTool; class GoldOre extends Solid{ - protected $id = self::GOLD_ORE; - - public function __construct(){ - - } - - public function getName() : string{ - return "Gold Ore"; - } - public function getHardness() : float{ return 3; } diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index fadb3aaee0..5d32b8bdce 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -37,16 +37,6 @@ use function mt_rand; class Grass extends Solid{ - protected $id = self::GRASS; - - public function __construct(){ - - } - - public function getName() : string{ - return "Grass"; - } - public function getHardness() : float{ return 0.6; } diff --git a/src/pocketmine/block/GrassPath.php b/src/pocketmine/block/GrassPath.php index 459ff721d0..e41a4cf08d 100644 --- a/src/pocketmine/block/GrassPath.php +++ b/src/pocketmine/block/GrassPath.php @@ -30,16 +30,6 @@ use pocketmine\math\Facing; class GrassPath extends Transparent{ - protected $id = self::GRASS_PATH; - - public function __construct(){ - - } - - public function getName() : string{ - return "Grass Path"; - } - public function getToolType() : int{ return BlockToolType::TYPE_SHOVEL; } diff --git a/src/pocketmine/block/Gravel.php b/src/pocketmine/block/Gravel.php index 939b0e8017..b43848c462 100644 --- a/src/pocketmine/block/Gravel.php +++ b/src/pocketmine/block/Gravel.php @@ -32,16 +32,6 @@ use function mt_rand; class Gravel extends Solid implements Fallable{ use FallableTrait; - protected $id = self::GRAVEL; - - public function __construct(){ - - } - - public function getName() : string{ - return "Gravel"; - } - public function getHardness() : float{ return 0.6; } diff --git a/src/pocketmine/block/HayBale.php b/src/pocketmine/block/HayBale.php index e1bb4e19b9..8a78ba8fea 100644 --- a/src/pocketmine/block/HayBale.php +++ b/src/pocketmine/block/HayBale.php @@ -28,16 +28,6 @@ use pocketmine\block\utils\PillarRotationTrait; class HayBale extends Solid{ use PillarRotationTrait; - protected $id = self::HAY_BALE; - - public function __construct(){ - - } - - public function getName() : string{ - return "Hay Bale"; - } - public function getHardness() : float{ return 0.5; } diff --git a/src/pocketmine/block/Ice.php b/src/pocketmine/block/Ice.php index f499ea5883..ccd3e72d83 100644 --- a/src/pocketmine/block/Ice.php +++ b/src/pocketmine/block/Ice.php @@ -29,16 +29,6 @@ use pocketmine\Player; class Ice extends Transparent{ - protected $id = self::ICE; - - public function __construct(){ - - } - - public function getName() : string{ - return "Ice"; - } - public function getHardness() : float{ return 0.5; } diff --git a/src/pocketmine/block/InvisibleBedrock.php b/src/pocketmine/block/InvisibleBedrock.php index 689c90f6bd..0b83d4fb14 100644 --- a/src/pocketmine/block/InvisibleBedrock.php +++ b/src/pocketmine/block/InvisibleBedrock.php @@ -27,16 +27,6 @@ use pocketmine\item\Item; class InvisibleBedrock extends Transparent{ - protected $id = self::INVISIBLE_BEDROCK; - - public function __construct(){ - - } - - public function getName() : string{ - return "Invisible Bedrock"; - } - public function getHardness() : float{ return -1; } diff --git a/src/pocketmine/block/Iron.php b/src/pocketmine/block/Iron.php index 0246fe5364..fab064e318 100644 --- a/src/pocketmine/block/Iron.php +++ b/src/pocketmine/block/Iron.php @@ -27,16 +27,6 @@ use pocketmine\item\TieredTool; class Iron extends Solid{ - protected $id = self::IRON_BLOCK; - - public function __construct(){ - - } - - public function getName() : string{ - return "Iron Block"; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } diff --git a/src/pocketmine/block/IronBars.php b/src/pocketmine/block/IronBars.php index 755c0d12c5..3cfeb036d3 100644 --- a/src/pocketmine/block/IronBars.php +++ b/src/pocketmine/block/IronBars.php @@ -27,16 +27,6 @@ use pocketmine\item\TieredTool; class IronBars extends Thin{ - protected $id = self::IRON_BARS; - - public function __construct(){ - - } - - public function getName() : string{ - return "Iron Bars"; - } - public function getHardness() : float{ return 5; } diff --git a/src/pocketmine/block/IronDoor.php b/src/pocketmine/block/IronDoor.php index c9da8160a7..f735cdbcc0 100644 --- a/src/pocketmine/block/IronDoor.php +++ b/src/pocketmine/block/IronDoor.php @@ -23,23 +23,10 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\Item; use pocketmine\item\TieredTool; class IronDoor extends Door{ - protected $id = self::IRON_DOOR_BLOCK; - - protected $itemId = Item::IRON_DOOR; - - public function __construct(){ - - } - - public function getName() : string{ - return "Iron Door"; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } diff --git a/src/pocketmine/block/IronOre.php b/src/pocketmine/block/IronOre.php index c41c7518ee..acff32ea69 100644 --- a/src/pocketmine/block/IronOre.php +++ b/src/pocketmine/block/IronOre.php @@ -27,16 +27,6 @@ use pocketmine\item\TieredTool; class IronOre extends Solid{ - protected $id = self::IRON_ORE; - - public function __construct(){ - - } - - public function getName() : string{ - return "Iron Ore"; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } diff --git a/src/pocketmine/block/IronTrapdoor.php b/src/pocketmine/block/IronTrapdoor.php index cd52d50308..c807ef83d4 100644 --- a/src/pocketmine/block/IronTrapdoor.php +++ b/src/pocketmine/block/IronTrapdoor.php @@ -27,12 +27,6 @@ use pocketmine\item\TieredTool; class IronTrapdoor extends Trapdoor{ - protected $id = self::IRON_TRAPDOOR; - - public function getName() : string{ - return "Iron Trapdoor"; - } - public function getHardness() : float{ return 5; } diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index c685ea83a9..3eff935ca3 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -32,19 +32,12 @@ use pocketmine\tile\ItemFrame as TileItemFrame; use function lcg_value; class ItemFrame extends Flowable{ - protected $id = Block::ITEM_FRAME_BLOCK; - - protected $itemId = Item::ITEM_FRAME; /** @var int */ protected $facing = Facing::NORTH; /** @var bool */ protected $hasMap = false; //makes frame appear large if set - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return (5 - $this->facing) | ($this->hasMap ? 0x04 : 0); } @@ -58,14 +51,6 @@ class ItemFrame extends Flowable{ return 0b111; } - protected function getTileClass() : ?string{ - return TileItemFrame::class; - } - - public function getName() : string{ - return "Item Frame"; - } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $tile = $this->level->getTile($this); if($tile instanceof TileItemFrame){ diff --git a/src/pocketmine/block/Ladder.php b/src/pocketmine/block/Ladder.php index ab6fb62689..f99fdcc7a9 100644 --- a/src/pocketmine/block/Ladder.php +++ b/src/pocketmine/block/Ladder.php @@ -33,15 +33,9 @@ use pocketmine\Player; class Ladder extends Transparent{ - protected $id = self::LADDER; - /** @var int */ protected $facing = Facing::NORTH; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return $this->facing; } @@ -54,10 +48,6 @@ class Ladder extends Transparent{ return 0b111; } - public function getName() : string{ - return "Ladder"; - } - public function hasEntityCollision() : bool{ return true; } diff --git a/src/pocketmine/block/Lapis.php b/src/pocketmine/block/Lapis.php index 9af975e22e..0e48fc4d26 100644 --- a/src/pocketmine/block/Lapis.php +++ b/src/pocketmine/block/Lapis.php @@ -27,16 +27,6 @@ use pocketmine\item\TieredTool; class Lapis extends Solid{ - protected $id = self::LAPIS_BLOCK; - - public function __construct(){ - - } - - public function getName() : string{ - return "Lapis Lazuli Block"; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } diff --git a/src/pocketmine/block/LapisOre.php b/src/pocketmine/block/LapisOre.php index 1337f6f0f0..4c4326872d 100644 --- a/src/pocketmine/block/LapisOre.php +++ b/src/pocketmine/block/LapisOre.php @@ -30,12 +30,6 @@ use function mt_rand; class LapisOre extends Solid{ - protected $id = self::LAPIS_ORE; - - public function __construct(){ - - } - public function getHardness() : float{ return 3; } @@ -48,10 +42,6 @@ class LapisOre extends Solid{ return TieredTool::TIER_STONE; } - public function getName() : string{ - return "Lapis Lazuli Ore"; - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ ItemFactory::get(Item::DYE, 4, mt_rand(4, 8)) diff --git a/src/pocketmine/block/Lava.php b/src/pocketmine/block/Lava.php index 2221d87cb2..fb4d4f5876 100644 --- a/src/pocketmine/block/Lava.php +++ b/src/pocketmine/block/Lava.php @@ -32,10 +32,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class Lava extends Liquid{ - public function __construct(){ - parent::__construct(self::FLOWING_LAVA, self::STILL_LAVA, "Lava"); - } - public function getLightLevel() : int{ return 15; } diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 90aa6924cd..85963e14fa 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -42,8 +42,8 @@ class Leaves extends Transparent{ /** @var bool */ protected $checkDecay = false; - public function __construct(int $id, int $variant, TreeType $treeType, ?string $name = null){ - parent::__construct($id, $variant, $name); + public function __construct(BlockIdentifier $idInfo, string $name, TreeType $treeType){ + parent::__construct($idInfo, $name); $this->treeType = $treeType; } diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index 16873081d4..2f24233284 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -35,8 +35,6 @@ class Lever extends Flowable{ protected const SIDE = 1; protected const TOP = 2; - protected $id = self::LEVER; - /** @var int */ protected $position = self::BOTTOM; /** @var int */ @@ -44,10 +42,6 @@ class Lever extends Flowable{ /** @var bool */ protected $powered = false; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ if($this->position === self::BOTTOM){ $rotationMeta = Facing::axis($this->facing) === Facing::AXIS_Z ? 7 : 0; @@ -79,10 +73,6 @@ class Lever extends Flowable{ return 0b1111; } - public function getName() : string{ - return "Lever"; - } - public function getHardness() : float{ return 0.5; } diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index 72d788991e..d0280b012f 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -37,8 +37,8 @@ use function lcg_value; use function min; abstract class Liquid extends Transparent{ - /** @var int */ - private $stillId; + /** @var BlockIdentifierFlattened */ + protected $idInfo; public $adjacentSources = 0; @@ -59,13 +59,12 @@ abstract class Liquid extends Transparent{ /** @var bool */ protected $still = false; - public function __construct(int $id, int $stillId, string $name){ - parent::__construct($id, 0, $name); - $this->stillId = $stillId; + public function __construct(BlockIdentifierFlattened $idInfo, string $name){ + parent::__construct($idInfo, $name); } public function getId() : int{ - return $this->still ? $this->stillId : parent::getId(); + return $this->still ? $this->idInfo->getSecondId() : parent::getId(); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/LitPumpkin.php b/src/pocketmine/block/LitPumpkin.php index 5f9abf17e3..dbc173bf93 100644 --- a/src/pocketmine/block/LitPumpkin.php +++ b/src/pocketmine/block/LitPumpkin.php @@ -25,13 +25,7 @@ namespace pocketmine\block; class LitPumpkin extends Pumpkin{ - protected $id = self::LIT_PUMPKIN; - public function getLightLevel() : int{ return 15; } - - public function getName() : string{ - return "Jack o'Lantern"; - } } diff --git a/src/pocketmine/block/Magma.php b/src/pocketmine/block/Magma.php index d246a4969c..9d23abd34e 100644 --- a/src/pocketmine/block/Magma.php +++ b/src/pocketmine/block/Magma.php @@ -30,16 +30,6 @@ use pocketmine\item\TieredTool; class Magma extends Solid{ - protected $id = Block::MAGMA; - - public function __construct(){ - - } - - public function getName() : string{ - return "Magma Block"; - } - public function getHardness() : float{ return 0.5; } diff --git a/src/pocketmine/block/Melon.php b/src/pocketmine/block/Melon.php index d9dc6e2d4e..5498cb14db 100644 --- a/src/pocketmine/block/Melon.php +++ b/src/pocketmine/block/Melon.php @@ -29,16 +29,6 @@ use function mt_rand; class Melon extends Transparent{ - protected $id = self::MELON_BLOCK; - - public function __construct(){ - - } - - public function getName() : string{ - return "Melon Block"; - } - public function getHardness() : float{ return 1; } diff --git a/src/pocketmine/block/MelonStem.php b/src/pocketmine/block/MelonStem.php index 49646981d3..4e50519fb3 100644 --- a/src/pocketmine/block/MelonStem.php +++ b/src/pocketmine/block/MelonStem.php @@ -23,18 +23,8 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\Item; - class MelonStem extends Stem{ - protected $id = self::MELON_STEM; - - protected $itemId = Item::MELON_SEEDS; - - public function getName() : string{ - return "Melon Stem"; - } - protected function getPlant() : Block{ return BlockFactory::get(Block::MELON_BLOCK); } diff --git a/src/pocketmine/block/MonsterSpawner.php b/src/pocketmine/block/MonsterSpawner.php index bfe983cbbc..f67957095d 100644 --- a/src/pocketmine/block/MonsterSpawner.php +++ b/src/pocketmine/block/MonsterSpawner.php @@ -29,12 +29,6 @@ use function mt_rand; class MonsterSpawner extends Transparent{ - protected $id = self::MONSTER_SPAWNER; - - public function __construct(){ - - } - public function getHardness() : float{ return 5; } @@ -47,10 +41,6 @@ class MonsterSpawner extends Transparent{ return TieredTool::TIER_WOODEN; } - public function getName() : string{ - return "Monster Spawner"; - } - public function getDropsForCompatibleTool(Item $item) : array{ return []; } diff --git a/src/pocketmine/block/Mycelium.php b/src/pocketmine/block/Mycelium.php index b6b98e64e0..63d1c3653c 100644 --- a/src/pocketmine/block/Mycelium.php +++ b/src/pocketmine/block/Mycelium.php @@ -31,16 +31,6 @@ use function mt_rand; class Mycelium extends Solid{ - protected $id = self::MYCELIUM; - - public function __construct(){ - - } - - public function getName() : string{ - return "Mycelium"; - } - public function getToolType() : int{ return BlockToolType::TYPE_SHOVEL; } diff --git a/src/pocketmine/block/NetherBrickFence.php b/src/pocketmine/block/NetherBrickFence.php index b8cd98afb1..5b80e27fee 100644 --- a/src/pocketmine/block/NetherBrickFence.php +++ b/src/pocketmine/block/NetherBrickFence.php @@ -27,12 +27,6 @@ use pocketmine\item\TieredTool; class NetherBrickFence extends Fence{ - protected $id = self::NETHER_BRICK_FENCE; - - public function __construct(){ - - } - public function getHardness() : float{ return 2; } @@ -44,8 +38,4 @@ class NetherBrickFence extends Fence{ public function getToolHarvestLevel() : int{ return TieredTool::TIER_WOODEN; } - - public function getName() : string{ - return "Nether Brick Fence"; - } } diff --git a/src/pocketmine/block/NetherBrickStairs.php b/src/pocketmine/block/NetherBrickStairs.php index f67c877950..8f5c16134c 100644 --- a/src/pocketmine/block/NetherBrickStairs.php +++ b/src/pocketmine/block/NetherBrickStairs.php @@ -27,16 +27,6 @@ use pocketmine\item\TieredTool; class NetherBrickStairs extends Stair{ - protected $id = self::NETHER_BRICK_STAIRS; - - public function __construct(){ - - } - - public function getName() : string{ - return "Nether Brick Stairs"; - } - public function getHardness() : float{ return 2; } diff --git a/src/pocketmine/block/NetherQuartzOre.php b/src/pocketmine/block/NetherQuartzOre.php index 814f11f6ad..fc6cbaa3af 100644 --- a/src/pocketmine/block/NetherQuartzOre.php +++ b/src/pocketmine/block/NetherQuartzOre.php @@ -30,16 +30,6 @@ use function mt_rand; class NetherQuartzOre extends Solid{ - protected $id = Block::NETHER_QUARTZ_ORE; - - public function __construct(){ - - } - - public function getName() : string{ - return "Nether Quartz Ore"; - } - public function getHardness() : float{ return 3; } diff --git a/src/pocketmine/block/NetherReactor.php b/src/pocketmine/block/NetherReactor.php index 92c2c0bb2a..1ec7ab236c 100644 --- a/src/pocketmine/block/NetherReactor.php +++ b/src/pocketmine/block/NetherReactor.php @@ -33,15 +33,9 @@ class NetherReactor extends Solid{ protected const STATE_ACTIVE = 1; protected const STATE_USED = 2; - protected $id = Block::NETHER_REACTOR; - /** @var int */ protected $state = self::STATE_INACTIVE; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return $this->state; } @@ -54,10 +48,6 @@ class NetherReactor extends Solid{ return 0b11; } - public function getName() : string{ - return "Nether Reactor Core"; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } diff --git a/src/pocketmine/block/NetherWartBlock.php b/src/pocketmine/block/NetherWartBlock.php index 21cdc6f50c..2460a69c32 100644 --- a/src/pocketmine/block/NetherWartBlock.php +++ b/src/pocketmine/block/NetherWartBlock.php @@ -25,16 +25,6 @@ namespace pocketmine\block; class NetherWartBlock extends Solid{ - protected $id = Block::NETHER_WART_BLOCK; - - public function __construct(){ - - } - - public function getName() : string{ - return "Nether Wart Block"; - } - public function getHardness() : float{ return 1; } diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index 2aa9fdd6a7..9489847e9e 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -27,24 +27,16 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use function mt_rand; class NetherWartPlant extends Flowable{ - protected $id = Block::NETHER_WART_PLANT; - - protected $itemId = Item::NETHER_WART; /** @var int */ protected $age = 0; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return $this->age; } @@ -57,10 +49,6 @@ class NetherWartPlant extends Flowable{ return 0b11; } - public function getName() : string{ - return "Nether Wart"; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === Block::SOUL_SAND){ @@ -94,7 +82,7 @@ class NetherWartPlant extends Flowable{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get($this->getItemId(), 0, ($this->age === 3 ? mt_rand(2, 4) : 1)) + $this->getItem()->setCount($this->age === 3 ? mt_rand(2, 4) : 1) ]; } diff --git a/src/pocketmine/block/Netherrack.php b/src/pocketmine/block/Netherrack.php index 1a79ea9f9e..34ca389dba 100644 --- a/src/pocketmine/block/Netherrack.php +++ b/src/pocketmine/block/Netherrack.php @@ -27,16 +27,6 @@ use pocketmine\item\TieredTool; class Netherrack extends Solid{ - protected $id = self::NETHERRACK; - - public function __construct(){ - - } - - public function getName() : string{ - return "Netherrack"; - } - public function getHardness() : float{ return 0.4; } diff --git a/src/pocketmine/block/NoteBlock.php b/src/pocketmine/block/NoteBlock.php index 4c30cb60fe..113d6accf0 100644 --- a/src/pocketmine/block/NoteBlock.php +++ b/src/pocketmine/block/NoteBlock.php @@ -25,16 +25,6 @@ namespace pocketmine\block; class NoteBlock extends Solid{ - protected $id = self::NOTE_BLOCK; - - public function __construct(){ - - } - - public function getName() : string{ - return "Note Block"; - } - public function getFuelTime() : int{ return 300; } diff --git a/src/pocketmine/block/Obsidian.php b/src/pocketmine/block/Obsidian.php index ba821ec1bc..e204784cfc 100644 --- a/src/pocketmine/block/Obsidian.php +++ b/src/pocketmine/block/Obsidian.php @@ -27,16 +27,6 @@ use pocketmine\item\TieredTool; class Obsidian extends Solid{ - protected $id = self::OBSIDIAN; - - public function __construct(){ - - } - - public function getName() : string{ - return "Obsidian"; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } diff --git a/src/pocketmine/block/PackedIce.php b/src/pocketmine/block/PackedIce.php index 6ca48c390f..1455c31488 100644 --- a/src/pocketmine/block/PackedIce.php +++ b/src/pocketmine/block/PackedIce.php @@ -25,16 +25,6 @@ namespace pocketmine\block; class PackedIce extends Solid{ - protected $id = self::PACKED_ICE; - - public function __construct(){ - - } - - public function getName() : string{ - return "Packed Ice"; - } - public function getHardness() : float{ return 0.5; } diff --git a/src/pocketmine/block/Podzol.php b/src/pocketmine/block/Podzol.php index be44cf1b42..0cfa1ccda7 100644 --- a/src/pocketmine/block/Podzol.php +++ b/src/pocketmine/block/Podzol.php @@ -25,20 +25,10 @@ namespace pocketmine\block; class Podzol extends Solid{ - protected $id = self::PODZOL; - - public function __construct(){ - - } - public function getToolType() : int{ return BlockToolType::TYPE_SHOVEL; } - public function getName() : string{ - return "Podzol"; - } - public function getHardness() : float{ return 2.5; } diff --git a/src/pocketmine/block/Potato.php b/src/pocketmine/block/Potato.php index 5faf4d11a8..62aa45caf1 100644 --- a/src/pocketmine/block/Potato.php +++ b/src/pocketmine/block/Potato.php @@ -29,12 +29,6 @@ use function mt_rand; class Potato extends Crops{ - protected $id = self::POTATO_BLOCK; - - public function getName() : string{ - return "Potato Block"; - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ ItemFactory::get(Item::POTATO, 0, $this->age >= 7 ? mt_rand(1, 4) : 1) diff --git a/src/pocketmine/block/PoweredRail.php b/src/pocketmine/block/PoweredRail.php index ed7b1a00b7..0a66be5be4 100644 --- a/src/pocketmine/block/PoweredRail.php +++ b/src/pocketmine/block/PoweredRail.php @@ -24,9 +24,4 @@ declare(strict_types=1); namespace pocketmine\block; class PoweredRail extends RedstoneRail{ - protected $id = self::POWERED_RAIL; - - public function getName() : string{ - return "Powered Rail"; - } } diff --git a/src/pocketmine/block/Pumpkin.php b/src/pocketmine/block/Pumpkin.php index 5e48324186..7bd2e08b93 100644 --- a/src/pocketmine/block/Pumpkin.php +++ b/src/pocketmine/block/Pumpkin.php @@ -32,15 +32,9 @@ use pocketmine\Player; class Pumpkin extends Solid{ - protected $id = self::PUMPKIN; - /** @var int */ protected $facing = Facing::NORTH; - public function __construct(){ - - } - public function readStateFromMeta(int $meta) : void{ $this->facing = BlockDataValidator::readLegacyHorizontalFacing($meta & 0x03); } @@ -61,10 +55,6 @@ class Pumpkin extends Solid{ return BlockToolType::TYPE_AXE; } - public function getName() : string{ - return "Pumpkin"; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); diff --git a/src/pocketmine/block/PumpkinStem.php b/src/pocketmine/block/PumpkinStem.php index fa13fcc410..3c28e00e8f 100644 --- a/src/pocketmine/block/PumpkinStem.php +++ b/src/pocketmine/block/PumpkinStem.php @@ -23,18 +23,8 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\Item; - class PumpkinStem extends Stem{ - protected $id = self::PUMPKIN_STEM; - - protected $itemId = Item::PUMPKIN_SEEDS; - - public function getName() : string{ - return "Pumpkin Stem"; - } - protected function getPlant() : Block{ return BlockFactory::get(Block::PUMPKIN); } diff --git a/src/pocketmine/block/PurpurStairs.php b/src/pocketmine/block/PurpurStairs.php index 49409be4fa..4ba243108e 100644 --- a/src/pocketmine/block/PurpurStairs.php +++ b/src/pocketmine/block/PurpurStairs.php @@ -27,16 +27,6 @@ use pocketmine\item\TieredTool; class PurpurStairs extends Stair{ - protected $id = self::PURPUR_STAIRS; - - public function __construct(){ - - } - - public function getName() : string{ - return "Purpur Stairs"; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } diff --git a/src/pocketmine/block/QuartzStairs.php b/src/pocketmine/block/QuartzStairs.php index 56b93156d9..db910f0e88 100644 --- a/src/pocketmine/block/QuartzStairs.php +++ b/src/pocketmine/block/QuartzStairs.php @@ -27,12 +27,6 @@ use pocketmine\item\TieredTool; class QuartzStairs extends Stair{ - protected $id = self::QUARTZ_STAIRS; - - public function __construct(){ - - } - public function getHardness() : float{ return 0.8; } @@ -44,8 +38,4 @@ class QuartzStairs extends Stair{ public function getToolHarvestLevel() : int{ return TieredTool::TIER_WOODEN; } - - public function getName() : string{ - return "Quartz Stairs"; - } } diff --git a/src/pocketmine/block/Rail.php b/src/pocketmine/block/Rail.php index cc78c4c40a..93b9a0f9f6 100644 --- a/src/pocketmine/block/Rail.php +++ b/src/pocketmine/block/Rail.php @@ -52,12 +52,6 @@ class Rail extends BaseRail{ ] ]; - protected $id = self::RAIL; - - public function getName() : string{ - return "Rail"; - } - protected function getMetaForState(array $connections) : int{ try{ return self::searchState($connections, self::CURVE_CONNECTIONS); diff --git a/src/pocketmine/block/RedMushroom.php b/src/pocketmine/block/RedMushroom.php index be4d6e1bbb..8f23f1c488 100644 --- a/src/pocketmine/block/RedMushroom.php +++ b/src/pocketmine/block/RedMushroom.php @@ -30,16 +30,6 @@ use pocketmine\Player; class RedMushroom extends Flowable{ - protected $id = self::RED_MUSHROOM; - - public function __construct(){ - - } - - public function getName() : string{ - return "Red Mushroom"; - } - public function ticksRandomly() : bool{ return true; } diff --git a/src/pocketmine/block/RedMushroomBlock.php b/src/pocketmine/block/RedMushroomBlock.php index c94018ef2e..42403f67d6 100644 --- a/src/pocketmine/block/RedMushroomBlock.php +++ b/src/pocketmine/block/RedMushroomBlock.php @@ -28,8 +28,6 @@ use function mt_rand; class RedMushroomBlock extends Solid{ - protected $id = Block::RED_MUSHROOM_BLOCK; - /** * @var int * In PC they have blockstate properties for each of the sides (pores/not pores). Unfortunately, we can't support @@ -39,10 +37,6 @@ class RedMushroomBlock extends Solid{ */ protected $rotationData = 0; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return $this->rotationData; } @@ -55,10 +49,6 @@ class RedMushroomBlock extends Solid{ return 0b1111; } - public function getName() : string{ - return "Red Mushroom Block"; - } - public function getHardness() : float{ return 0.2; } diff --git a/src/pocketmine/block/RedSandstoneStairs.php b/src/pocketmine/block/RedSandstoneStairs.php deleted file mode 100644 index 5c1471f692..0000000000 --- a/src/pocketmine/block/RedSandstoneStairs.php +++ /dev/null @@ -1,33 +0,0 @@ -lit ? self::LIT_REDSTONE_LAMP : self::REDSTONE_LAMP; + return $this->lit ? $this->idInfo->getSecondId() : parent::getId(); } public function isLit() : bool{ @@ -56,10 +57,6 @@ class RedstoneLamp extends Solid{ return $this->lit ? 15 : 0; } - public function getName() : string{ - return "Redstone Lamp"; - } - public function getHardness() : float{ return 0.3; } diff --git a/src/pocketmine/block/RedstoneOre.php b/src/pocketmine/block/RedstoneOre.php index 3a452c21e0..306ae7db04 100644 --- a/src/pocketmine/block/RedstoneOre.php +++ b/src/pocketmine/block/RedstoneOre.php @@ -31,22 +31,18 @@ use pocketmine\Player; use function mt_rand; class RedstoneOre extends Solid{ - - protected $itemId = self::REDSTONE_ORE; + /** @var BlockIdentifierFlattened */ + protected $idInfo; /** @var bool */ protected $lit = false; - public function __construct(){ - + public function __construct(BlockIdentifierFlattened $idInfo, string $name){ + parent::__construct($idInfo, $name); } public function getId() : int{ - return $this->lit ? self::GLOWING_REDSTONE_ORE : self::REDSTONE_ORE; - } - - public function getName() : string{ - return "Redstone Ore"; + return $this->lit ? $this->idInfo->getSecondId() : parent::getId(); } public function getHardness() : float{ diff --git a/src/pocketmine/block/RedstoneRepeater.php b/src/pocketmine/block/RedstoneRepeater.php index 4917890d95..29c658f324 100644 --- a/src/pocketmine/block/RedstoneRepeater.php +++ b/src/pocketmine/block/RedstoneRepeater.php @@ -32,8 +32,8 @@ use pocketmine\math\Vector3; use pocketmine\Player; class RedstoneRepeater extends Flowable{ - /** @var int */ - protected $itemId = Item::REPEATER; + /** @var BlockIdentifierFlattened */ + protected $idInfo; /** @var bool */ protected $powered = false; @@ -42,12 +42,12 @@ class RedstoneRepeater extends Flowable{ /** @var int */ protected $delay = 1; - public function __construct(){ - + public function __construct(BlockIdentifierFlattened $idInfo, string $name){ + parent::__construct($idInfo, $name); } public function getId() : int{ - return $this->powered ? Block::POWERED_REPEATER : Block::UNPOWERED_REPEATER; + return $this->powered ? $this->idInfo->getSecondId() : parent::getId(); } public function readStateFromMeta(int $meta) : void{ @@ -63,10 +63,6 @@ class RedstoneRepeater extends Flowable{ return 0b1111; } - public function getName() : string{ - return "Redstone Repeater"; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ return AxisAlignedBB::one()->trim(Facing::UP, 7 / 8); } diff --git a/src/pocketmine/block/RedstoneTorch.php b/src/pocketmine/block/RedstoneTorch.php index b9956e37cc..44119dc26f 100644 --- a/src/pocketmine/block/RedstoneTorch.php +++ b/src/pocketmine/block/RedstoneTorch.php @@ -25,21 +25,18 @@ namespace pocketmine\block; class RedstoneTorch extends Torch{ - protected $itemId = self::REDSTONE_TORCH; + /** @var BlockIdentifierFlattened */ + protected $idInfo; /** @var bool */ protected $lit = true; - public function __construct(){ - parent::__construct(self::REDSTONE_TORCH, 0, "Redstone Torch", self::REDSTONE_TORCH); + public function __construct(BlockIdentifierFlattened $idInfo, string $name){ + parent::__construct($idInfo, $name); } public function getId() : int{ - return $this->lit ? self::REDSTONE_TORCH : self::UNLIT_REDSTONE_TORCH; - } - - public function getName() : string{ - return "Redstone Torch"; + return $this->lit ? parent::getId() : $this->idInfo->getSecondId(); } public function isLit() : bool{ diff --git a/src/pocketmine/block/RedstoneWire.php b/src/pocketmine/block/RedstoneWire.php index 6ad98d589d..e8d2a3b7db 100644 --- a/src/pocketmine/block/RedstoneWire.php +++ b/src/pocketmine/block/RedstoneWire.php @@ -24,21 +24,12 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; -use pocketmine\item\Item; class RedstoneWire extends Flowable{ - /** @var int */ - protected $id = Block::REDSTONE_WIRE; - /** @var int */ - protected $itemId = Item::REDSTONE; /** @var int */ protected $power = 0; - public function __construct(){ - - } - public function readStateFromMeta(int $meta) : void{ $this->power = BlockDataValidator::readBoundedInt("power", $meta, 0, 15); } @@ -51,10 +42,6 @@ class RedstoneWire extends Flowable{ return 0b1111; } - public function getName() : string{ - return "Redstone"; - } - public function readStateFromWorld() : void{ parent::readStateFromWorld(); //TODO: check connections to nearby redstone components diff --git a/src/pocketmine/block/SandstoneStairs.php b/src/pocketmine/block/SandstoneStairs.php index aeeb0152e3..19056fa739 100644 --- a/src/pocketmine/block/SandstoneStairs.php +++ b/src/pocketmine/block/SandstoneStairs.php @@ -27,12 +27,6 @@ use pocketmine\item\TieredTool; class SandstoneStairs extends Stair{ - protected $id = self::SANDSTONE_STAIRS; - - public function __construct(){ - - } - public function getHardness() : float{ return 0.8; } @@ -44,8 +38,4 @@ class SandstoneStairs extends Stair{ public function getToolHarvestLevel() : int{ return TieredTool::TIER_WOODEN; } - - public function getName() : string{ - return "Sandstone Stairs"; - } } diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index e99ce48f14..9e07f7ebc9 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -39,8 +39,8 @@ class Sapling extends Flowable{ /** @var TreeType */ private $treeType; - public function __construct(int $id, int $variant, TreeType $treeType, ?string $name = null, int $itemId = null){ - parent::__construct($id, $variant, $name, $itemId); + public function __construct(BlockIdentifier $idInfo, string $name, TreeType $treeType){ + parent::__construct($idInfo, $name); $this->treeType = $treeType; } diff --git a/src/pocketmine/block/SeaLantern.php b/src/pocketmine/block/SeaLantern.php index 3d0e3009fc..09947580ed 100644 --- a/src/pocketmine/block/SeaLantern.php +++ b/src/pocketmine/block/SeaLantern.php @@ -28,16 +28,6 @@ use pocketmine\item\ItemFactory; class SeaLantern extends Transparent{ - protected $id = self::SEA_LANTERN; - - public function __construct(){ - - } - - public function getName() : string{ - return "Sea Lantern"; - } - public function getHardness() : float{ return 0.3; } diff --git a/src/pocketmine/block/SignPost.php b/src/pocketmine/block/SignPost.php index e069472ea7..8cd0c16d17 100644 --- a/src/pocketmine/block/SignPost.php +++ b/src/pocketmine/block/SignPost.php @@ -28,22 +28,13 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; -use pocketmine\tile\Sign as TileSign; use function floor; class SignPost extends Transparent{ - protected $id = self::SIGN_POST; - - protected $itemId = Item::SIGN; - /** @var int */ protected $rotation = 0; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return $this->rotation; } @@ -56,10 +47,6 @@ class SignPost extends Transparent{ return 0b1111; } - protected function getTileClass() : ?string{ - return TileSign::class; - } - public function getHardness() : float{ return 1; } @@ -68,10 +55,6 @@ class SignPost extends Transparent{ return false; } - public function getName() : string{ - return "Sign Post"; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ return null; } diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index acce6c4c40..1b14ac161d 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -35,8 +35,6 @@ use function floor; class Skull extends Flowable{ - protected $id = self::SKULL_BLOCK; - /** @var int */ protected $facing = Facing::NORTH; @@ -44,10 +42,6 @@ class Skull extends Flowable{ /** @var int */ protected $rotation = 0; //TODO: split this into floor skull and wall skull handling - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return $this->facing; } @@ -69,10 +63,6 @@ class Skull extends Flowable{ } } - protected function getTileClass() : ?string{ - return TileSkull::class; - } - public function writeStateToWorld() : void{ parent::writeStateToWorld(); //extra block properties storage hack @@ -87,10 +77,6 @@ class Skull extends Flowable{ return 1; } - public function getName() : string{ - return "Mob Head"; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ //TODO: different bounds depending on attached face return AxisAlignedBB::one()->contract(0.25, 0, 0.25)->trim(Facing::UP, 0.5); diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index 92cb7d7919..311802e7a2 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -31,20 +31,19 @@ use pocketmine\math\Vector3; use pocketmine\Player; abstract class Slab extends Transparent{ - /** @var int */ - protected $doubleId; + /** @var BlockIdentifierFlattened */ + protected $idInfo; /** @var SlabType */ protected $slabType; - public function __construct(int $id, int $doubleId, int $variant = 0, ?string $name = null){ - parent::__construct($id, $variant, $name . " Slab", $id); - $this->doubleId = $doubleId; + public function __construct(BlockIdentifierFlattened $idInfo, string $name){ + parent::__construct($idInfo, $name . " Slab"); $this->slabType = SlabType::BOTTOM(); } public function getId() : int{ - return $this->slabType === SlabType::DOUBLE() ? $this->doubleId : parent::getId(); + return $this->slabType === SlabType::DOUBLE() ? $this->idInfo->getSecondId() : parent::getId(); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/Snow.php b/src/pocketmine/block/Snow.php index 707a72af23..c336908469 100644 --- a/src/pocketmine/block/Snow.php +++ b/src/pocketmine/block/Snow.php @@ -29,12 +29,6 @@ use pocketmine\item\TieredTool; class Snow extends Solid{ - protected $id = self::SNOW_BLOCK; - - public function __construct(){ - - } - public function getHardness() : float{ return 0.2; } @@ -47,10 +41,6 @@ class Snow extends Solid{ return TieredTool::TIER_WOODEN; } - public function getName() : string{ - return "Snow Block"; - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ ItemFactory::get(Item::SNOWBALL, 0, 4) diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index 3244742e15..733ea25957 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -39,15 +39,9 @@ use function max; class SnowLayer extends Flowable implements Fallable{ use FallableTrait; - protected $id = self::SNOW_LAYER; - /** @var int */ protected $layers = 1; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return $this->layers - 1; } @@ -60,10 +54,6 @@ class SnowLayer extends Flowable implements Fallable{ return 0b111; } - public function getName() : string{ - return "Snow Layer"; - } - public function canBeReplaced() : bool{ return $this->layers < 8; } diff --git a/src/pocketmine/block/SoulSand.php b/src/pocketmine/block/SoulSand.php index 8dc21f87c9..b006f06f1a 100644 --- a/src/pocketmine/block/SoulSand.php +++ b/src/pocketmine/block/SoulSand.php @@ -28,16 +28,6 @@ use pocketmine\math\Facing; class SoulSand extends Solid{ - protected $id = self::SOUL_SAND; - - public function __construct(){ - - } - - public function getName() : string{ - return "Soul Sand"; - } - public function getHardness() : float{ return 0.5; } diff --git a/src/pocketmine/block/Sponge.php b/src/pocketmine/block/Sponge.php index d84c352f61..dda5d8e65f 100644 --- a/src/pocketmine/block/Sponge.php +++ b/src/pocketmine/block/Sponge.php @@ -26,15 +26,9 @@ namespace pocketmine\block; class Sponge extends Solid{ - protected $id = self::SPONGE; - /** @var bool */ protected $wet = false; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return $this->wet ? 1 : 0; } @@ -50,8 +44,4 @@ class Sponge extends Solid{ public function getHardness() : float{ return 0.6; } - - public function getName() : string{ - return "Sponge"; - } } diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index 738e5e2c14..fd23d3a74e 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -35,17 +35,9 @@ use function floor; class StandingBanner extends Transparent{ - protected $id = self::STANDING_BANNER; - - protected $itemId = Item::BANNER; - /** @var int */ protected $rotation = 0; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return $this->rotation; } @@ -58,10 +50,6 @@ class StandingBanner extends Transparent{ return 0b1111; } - protected function getTileClass() : ?string{ - return TileBanner::class; - } - public function getHardness() : float{ return 1; } @@ -70,10 +58,6 @@ class StandingBanner extends Transparent{ return false; } - public function getName() : string{ - return "Standing Banner"; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ return null; } diff --git a/src/pocketmine/block/Stem.php b/src/pocketmine/block/Stem.php index e04485944f..8201085c4c 100644 --- a/src/pocketmine/block/Stem.php +++ b/src/pocketmine/block/Stem.php @@ -25,7 +25,6 @@ namespace pocketmine\block; use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\math\Facing; use function array_rand; use function mt_rand; @@ -67,7 +66,7 @@ abstract class Stem extends Crops{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get($this->getItemId(), 0, mt_rand(0, 2)) + $this->getItem()->setCount(mt_rand(0, 2)) ]; } } diff --git a/src/pocketmine/block/StoneBrickStairs.php b/src/pocketmine/block/StoneBrickStairs.php index c0cb53059e..bb3ae279be 100644 --- a/src/pocketmine/block/StoneBrickStairs.php +++ b/src/pocketmine/block/StoneBrickStairs.php @@ -27,12 +27,6 @@ use pocketmine\item\TieredTool; class StoneBrickStairs extends Stair{ - protected $id = self::STONE_BRICK_STAIRS; - - public function __construct(){ - - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } @@ -44,8 +38,4 @@ class StoneBrickStairs extends Stair{ public function getHardness() : float{ return 1.5; } - - public function getName() : string{ - return "Stone Brick Stairs"; - } } diff --git a/src/pocketmine/block/StoneButton.php b/src/pocketmine/block/StoneButton.php index 9471b1b78e..54d710d759 100644 --- a/src/pocketmine/block/StoneButton.php +++ b/src/pocketmine/block/StoneButton.php @@ -25,12 +25,6 @@ namespace pocketmine\block; class StoneButton extends Button{ - protected $id = self::STONE_BUTTON; - - public function getName() : string{ - return "Stone Button"; - } - public function getHardness() : float{ return 0.5; } diff --git a/src/pocketmine/block/StonePressurePlate.php b/src/pocketmine/block/StonePressurePlate.php index 027d10ae3c..501c2ee0f9 100644 --- a/src/pocketmine/block/StonePressurePlate.php +++ b/src/pocketmine/block/StonePressurePlate.php @@ -27,15 +27,9 @@ use pocketmine\item\TieredTool; class StonePressurePlate extends Transparent{ - protected $id = self::STONE_PRESSURE_PLATE; - /** @var bool */ protected $powered = false; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return $this->powered ? 1 : 0; } @@ -48,10 +42,6 @@ class StonePressurePlate extends Transparent{ return 0b1; } - public function getName() : string{ - return "Stone Pressure Plate"; - } - public function isSolid() : bool{ return false; } diff --git a/src/pocketmine/block/Stonecutter.php b/src/pocketmine/block/Stonecutter.php index daaf02d853..36ea459578 100644 --- a/src/pocketmine/block/Stonecutter.php +++ b/src/pocketmine/block/Stonecutter.php @@ -27,16 +27,6 @@ use pocketmine\item\TieredTool; class Stonecutter extends Solid{ - protected $id = self::STONECUTTER; - - public function __construct(){ - - } - - public function getName() : string{ - return "Stonecutter"; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index d9ce7087e2..cdde3cbdef 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -32,17 +32,9 @@ use pocketmine\Player; class Sugarcane extends Flowable{ - protected $id = self::SUGARCANE_BLOCK; - - protected $itemId = Item::SUGARCANE; - /** @var int */ protected $age = 0; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return $this->age; } @@ -55,10 +47,6 @@ class Sugarcane extends Flowable{ return 0b1111; } - public function getName() : string{ - return "Sugarcane"; - } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal if($this->getSide(Facing::DOWN)->getId() !== self::SUGARCANE_BLOCK){ diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index 84515ff816..4b71e5b563 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -40,16 +40,6 @@ use const M_PI; class TNT extends Solid{ - protected $id = self::TNT; - - public function __construct(){ - - } - - public function getName() : string{ - return "TNT"; - } - public function getHardness() : float{ return 0; } diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index 85583ac778..4349f7fd29 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -35,8 +35,6 @@ class Trapdoor extends Transparent{ private const MASK_UPPER = 0x04; private const MASK_OPENED = 0x08; - protected $id = self::TRAPDOOR; - /** @var int */ protected $facing = Facing::NORTH; /** @var bool */ @@ -44,10 +42,6 @@ class Trapdoor extends Transparent{ /** @var bool */ protected $top = false; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return (5 - $this->facing) | ($this->top ? self::MASK_UPPER : 0) | ($this->open ? self::MASK_OPENED : 0); } @@ -64,10 +58,6 @@ class Trapdoor extends Transparent{ return 0b1111; } - public function getName() : string{ - return "Wooden Trapdoor"; - } - public function getHardness() : float{ return 3; } diff --git a/src/pocketmine/block/TrappedChest.php b/src/pocketmine/block/TrappedChest.php index a559c69426..72f8c7a979 100644 --- a/src/pocketmine/block/TrappedChest.php +++ b/src/pocketmine/block/TrappedChest.php @@ -27,9 +27,4 @@ class TrappedChest extends Chest{ //TODO: Redstone! - protected $id = self::TRAPPED_CHEST; - - public function getName() : string{ - return "Trapped Chest"; - } } diff --git a/src/pocketmine/block/Tripwire.php b/src/pocketmine/block/Tripwire.php index 397a5f40d0..b55d283b9d 100644 --- a/src/pocketmine/block/Tripwire.php +++ b/src/pocketmine/block/Tripwire.php @@ -28,8 +28,6 @@ use pocketmine\item\ItemFactory; class Tripwire extends Flowable{ - protected $id = self::TRIPWIRE; - /** @var bool */ protected $triggered = false; /** @var bool */ @@ -37,10 +35,6 @@ class Tripwire extends Flowable{ /** @var bool */ protected $disarmed = false; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return ($this->triggered ? 0x01 : 0) | ($this->connected ? 0x04 : 0) | ($this->disarmed ? 0x08 : 0); } @@ -55,10 +49,6 @@ class Tripwire extends Flowable{ return 0b1111; } - public function getName() : string{ - return "Tripwire"; - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ ItemFactory::get(Item::STRING) diff --git a/src/pocketmine/block/TripwireHook.php b/src/pocketmine/block/TripwireHook.php index cf79a4919f..84356d34cf 100644 --- a/src/pocketmine/block/TripwireHook.php +++ b/src/pocketmine/block/TripwireHook.php @@ -32,8 +32,6 @@ use pocketmine\Player; class TripwireHook extends Flowable{ - protected $id = self::TRIPWIRE_HOOK; - /** @var int */ protected $facing = Facing::NORTH; /** @var bool */ @@ -41,10 +39,6 @@ class TripwireHook extends Flowable{ /** @var bool */ protected $powered = false; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return Bearing::fromFacing($this->facing) | ($this->connected ? 0x04 : 0) | ($this->powered ? 0x08 : 0); } @@ -59,10 +53,6 @@ class TripwireHook extends Flowable{ return 0b1111; } - public function getName() : string{ - return "Tripwire Hook"; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ if(Facing::axis($face) !== Facing::AXIS_Y){ //TODO: check face is valid diff --git a/src/pocketmine/block/UnknownBlock.php b/src/pocketmine/block/UnknownBlock.php index 37ea74af98..53e56d4ebd 100644 --- a/src/pocketmine/block/UnknownBlock.php +++ b/src/pocketmine/block/UnknownBlock.php @@ -27,9 +27,8 @@ use pocketmine\item\Item; class UnknownBlock extends Transparent{ - public function __construct(int $id, int $meta = 0){ - $this->id = $id; - $this->variant = $meta; + public function __construct(BlockIdentifier $idInfo){ + parent::__construct($idInfo, "Unknown"); } public function canBePlaced() : bool{ diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index 7247264464..a65fc48a88 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -39,15 +39,9 @@ class Vine extends Flowable{ private const FLAG_NORTH = 0x04; private const FLAG_EAST = 0x08; - protected $id = self::VINE; - /** @var bool[] */ protected $faces = []; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return (isset($this->faces[Facing::SOUTH]) ? self::FLAG_SOUTH : 0) | @@ -73,10 +67,6 @@ class Vine extends Flowable{ } } - public function getName() : string{ - return "Vines"; - } - public function getHardness() : float{ return 0.2; } diff --git a/src/pocketmine/block/WallBanner.php b/src/pocketmine/block/WallBanner.php index 41aac1639c..5aa2dc757c 100644 --- a/src/pocketmine/block/WallBanner.php +++ b/src/pocketmine/block/WallBanner.php @@ -28,8 +28,6 @@ use pocketmine\math\Facing; class WallBanner extends StandingBanner{ - protected $id = self::WALL_BANNER; - /** @var int */ protected $facing = Facing::NORTH; @@ -45,10 +43,6 @@ class WallBanner extends StandingBanner{ return 0b111; } - public function getName() : string{ - return "Wall Banner"; - } - public function onNearbyBlockChange() : void{ if($this->getSide(Facing::opposite($this->facing))->getId() === self::AIR){ $this->getLevel()->useBreakOn($this); diff --git a/src/pocketmine/block/WallSign.php b/src/pocketmine/block/WallSign.php index bca6b62692..b7c7448da2 100644 --- a/src/pocketmine/block/WallSign.php +++ b/src/pocketmine/block/WallSign.php @@ -28,8 +28,6 @@ use pocketmine\math\Facing; class WallSign extends SignPost{ - protected $id = self::WALL_SIGN; - /** @var int */ protected $facing = Facing::NORTH; @@ -45,10 +43,6 @@ class WallSign extends SignPost{ return 0b111; } - public function getName() : string{ - return "Wall Sign"; - } - public function onNearbyBlockChange() : void{ if($this->getSide(Facing::opposite($this->facing))->getId() === self::AIR){ $this->getLevel()->useBreakOn($this); diff --git a/src/pocketmine/block/Water.php b/src/pocketmine/block/Water.php index 961adb482c..c490df0114 100644 --- a/src/pocketmine/block/Water.php +++ b/src/pocketmine/block/Water.php @@ -28,10 +28,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class Water extends Liquid{ - public function __construct(){ - parent::__construct(self::FLOWING_WATER, self::STILL_WATER, "Water"); - } - public function getLightFilter() : int{ return 2; } diff --git a/src/pocketmine/block/WaterLily.php b/src/pocketmine/block/WaterLily.php index 0c4c05ff11..390891225d 100644 --- a/src/pocketmine/block/WaterLily.php +++ b/src/pocketmine/block/WaterLily.php @@ -31,16 +31,6 @@ use pocketmine\Player; class WaterLily extends Flowable{ - protected $id = self::WATER_LILY; - - public function __construct(){ - - } - - public function getName() : string{ - return "Lily Pad"; - } - public function getHardness() : float{ return 0.6; } diff --git a/src/pocketmine/block/WeightedPressurePlateHeavy.php b/src/pocketmine/block/WeightedPressurePlateHeavy.php index bcfe010d49..ba72c90009 100644 --- a/src/pocketmine/block/WeightedPressurePlateHeavy.php +++ b/src/pocketmine/block/WeightedPressurePlateHeavy.php @@ -24,10 +24,4 @@ declare(strict_types=1); namespace pocketmine\block; class WeightedPressurePlateHeavy extends WeightedPressurePlateLight{ - - protected $id = self::HEAVY_WEIGHTED_PRESSURE_PLATE; - - public function getName() : string{ - return "Weighted Pressure Plate Heavy"; - } } diff --git a/src/pocketmine/block/WeightedPressurePlateLight.php b/src/pocketmine/block/WeightedPressurePlateLight.php index 7bd0b74e58..9fac934c9c 100644 --- a/src/pocketmine/block/WeightedPressurePlateLight.php +++ b/src/pocketmine/block/WeightedPressurePlateLight.php @@ -28,15 +28,9 @@ use pocketmine\item\TieredTool; class WeightedPressurePlateLight extends Transparent{ - protected $id = self::LIGHT_WEIGHTED_PRESSURE_PLATE; - /** @var int */ protected $power = 0; - public function __construct(){ - - } - protected function writeStateToMeta() : int{ return $this->power; } @@ -49,10 +43,6 @@ class WeightedPressurePlateLight extends Transparent{ return 0b1111; } - public function getName() : string{ - return "Weighted Pressure Plate Light"; - } - public function isSolid() : bool{ return false; } diff --git a/src/pocketmine/block/Wheat.php b/src/pocketmine/block/Wheat.php index 8373e960dc..59bd52256c 100644 --- a/src/pocketmine/block/Wheat.php +++ b/src/pocketmine/block/Wheat.php @@ -29,12 +29,6 @@ use function mt_rand; class Wheat extends Crops{ - protected $id = self::WHEAT_BLOCK; - - public function getName() : string{ - return "Wheat Block"; - } - public function getDropsForCompatibleTool(Item $item) : array{ if($this->age >= 7){ return [ diff --git a/src/pocketmine/block/Wood.php b/src/pocketmine/block/Wood.php index ff970322a5..f9dd1c74a1 100644 --- a/src/pocketmine/block/Wood.php +++ b/src/pocketmine/block/Wood.php @@ -30,8 +30,8 @@ class Wood extends Solid{ /** @var TreeType */ private $treeType; - public function __construct(int $id, int $variant, TreeType $treeType, ?string $name = null, int $itemId = null){ - parent::__construct($id, $variant, $name, $itemId); + public function __construct(BlockIdentifier $idInfo, string $name, TreeType $treeType){ + parent::__construct($idInfo, $name); $this->treeType = $treeType; } diff --git a/src/pocketmine/block/WoodenButton.php b/src/pocketmine/block/WoodenButton.php index 85f7b978c4..d81b4e53b5 100644 --- a/src/pocketmine/block/WoodenButton.php +++ b/src/pocketmine/block/WoodenButton.php @@ -25,12 +25,6 @@ namespace pocketmine\block; class WoodenButton extends Button{ - protected $id = self::WOODEN_BUTTON; - - public function getName() : string{ - return "Wooden Button"; - } - public function getHardness() : float{ return 0.5; } diff --git a/src/pocketmine/block/WoodenPressurePlate.php b/src/pocketmine/block/WoodenPressurePlate.php index 8602ff3f21..a01bfaafd4 100644 --- a/src/pocketmine/block/WoodenPressurePlate.php +++ b/src/pocketmine/block/WoodenPressurePlate.php @@ -25,12 +25,6 @@ namespace pocketmine\block; class WoodenPressurePlate extends StonePressurePlate{ - protected $id = self::WOODEN_PRESSURE_PLATE; - - public function getName() : string{ - return "Wooden Pressure Plate"; - } - public function getFuelTime() : int{ return 300; } diff --git a/src/pocketmine/block/WoodenSlab.php b/src/pocketmine/block/WoodenSlab.php index 39ae7ac6da..c1a9de02f3 100644 --- a/src/pocketmine/block/WoodenSlab.php +++ b/src/pocketmine/block/WoodenSlab.php @@ -25,8 +25,6 @@ namespace pocketmine\block; class WoodenSlab extends Slab{ - protected $id = self::WOODEN_SLAB; - public function getHardness() : float{ return 2; } From 3d1502c9ad2b98f9e38f7a0d61e8148fb8ef660a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Feb 2019 17:11:26 -0500 Subject: [PATCH 0508/3224] Apparently yaml_parse_file() doesn't respect access protocol --- src/pocketmine/permission/DefaultPermissions.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/permission/DefaultPermissions.php b/src/pocketmine/permission/DefaultPermissions.php index 039b846c73..465f7a7754 100644 --- a/src/pocketmine/permission/DefaultPermissions.php +++ b/src/pocketmine/permission/DefaultPermissions.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\permission; +use function file_get_contents; use function yaml_parse_file; abstract class DefaultPermissions{ @@ -47,7 +48,7 @@ abstract class DefaultPermissions{ public static function registerCorePermissions(){ $manager = PermissionManager::getInstance(); - foreach(PermissionParser::loadPermissions(yaml_parse_file(\pocketmine\RESOURCE_PATH . 'default_permissions.yml')) as $permission){ + foreach(PermissionParser::loadPermissions(yaml_parse(file_get_contents(\pocketmine\RESOURCE_PATH . 'default_permissions.yml'))) as $permission){ $manager->addPermission($permission); } } From 635fb5dde43e7af6480b08fac84af30afb6131a3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Feb 2019 10:38:29 +0000 Subject: [PATCH 0509/3224] Clean up ID flattening hacks --- src/pocketmine/block/Anvil.php | 4 +- src/pocketmine/block/BaseRail.php | 6 +- src/pocketmine/block/Bed.php | 8 +- src/pocketmine/block/Block.php | 11 +- src/pocketmine/block/BlockFactory.php | 122 ++++++++---------- src/pocketmine/block/BlockIdentifier.php | 7 + .../block/BlockIdentifierFlattened.php | 4 + src/pocketmine/block/BrewingStand.php | 8 +- src/pocketmine/block/Button.php | 6 +- src/pocketmine/block/Cactus.php | 4 +- src/pocketmine/block/Cake.php | 4 +- src/pocketmine/block/Chest.php | 4 +- src/pocketmine/block/CocoaBlock.php | 6 +- src/pocketmine/block/Crops.php | 4 +- src/pocketmine/block/DaylightSensor.php | 5 +- src/pocketmine/block/Door.php | 12 +- src/pocketmine/block/DoublePlant.php | 4 +- src/pocketmine/block/EndPortalFrame.php | 6 +- src/pocketmine/block/EndRod.php | 8 +- src/pocketmine/block/Farmland.php | 4 +- src/pocketmine/block/FenceGate.php | 8 +- src/pocketmine/block/Fire.php | 4 +- src/pocketmine/block/FlowerPot.php | 4 +- src/pocketmine/block/Furnace.php | 5 +- src/pocketmine/block/GlazedTerracotta.php | 4 +- src/pocketmine/block/ItemFrame.php | 6 +- src/pocketmine/block/Ladder.php | 4 +- src/pocketmine/block/Leaves.php | 6 +- src/pocketmine/block/Lever.php | 6 +- src/pocketmine/block/Liquid.php | 7 +- src/pocketmine/block/NetherReactor.php | 4 +- src/pocketmine/block/NetherWartPlant.php | 4 +- src/pocketmine/block/Pumpkin.php | 4 +- src/pocketmine/block/RedMushroomBlock.php | 4 +- src/pocketmine/block/RedstoneLamp.php | 4 + src/pocketmine/block/RedstoneOre.php | 4 + src/pocketmine/block/RedstoneRail.php | 6 +- src/pocketmine/block/RedstoneRepeater.php | 7 +- src/pocketmine/block/RedstoneTorch.php | 5 + src/pocketmine/block/RedstoneWire.php | 4 +- src/pocketmine/block/Sapling.php | 4 +- src/pocketmine/block/SignPost.php | 4 +- src/pocketmine/block/Skull.php | 4 +- src/pocketmine/block/Slab.php | 8 +- src/pocketmine/block/SnowLayer.php | 4 +- src/pocketmine/block/Sponge.php | 4 +- src/pocketmine/block/Stair.php | 6 +- src/pocketmine/block/StandingBanner.php | 4 +- src/pocketmine/block/StonePressurePlate.php | 4 +- src/pocketmine/block/Sugarcane.php | 4 +- src/pocketmine/block/Torch.php | 4 +- src/pocketmine/block/Trapdoor.php | 8 +- src/pocketmine/block/Tripwire.php | 8 +- src/pocketmine/block/TripwireHook.php | 8 +- src/pocketmine/block/Vine.php | 10 +- src/pocketmine/block/WallBanner.php | 4 +- src/pocketmine/block/WallSign.php | 4 +- .../block/WeightedPressurePlateLight.php | 4 +- .../block/utils/PillarRotationTrait.php | 10 +- 59 files changed, 231 insertions(+), 212 deletions(-) diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index 9c7bc8a5c4..f5a017a245 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -49,8 +49,8 @@ class Anvil extends Transparent implements Fallable{ return Bearing::fromFacing($this->facing); } - public function readStateFromMeta(int $meta) : void{ - $this->facing = BlockDataValidator::readLegacyHorizontalFacing($meta); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/BaseRail.php b/src/pocketmine/block/BaseRail.php index 7dc0e48f79..ba9913d454 100644 --- a/src/pocketmine/block/BaseRail.php +++ b/src/pocketmine/block/BaseRail.php @@ -87,10 +87,10 @@ abstract class BaseRail extends Flowable{ return $this->getMetaForState($this->connections); } - public function readStateFromMeta(int $meta) : void{ - $connections = $this->getConnectionsFromMeta($meta); + public function readStateFromData(int $id, int $stateMeta) : void{ + $connections = $this->getConnectionsFromMeta($stateMeta); if($connections === null){ - throw new InvalidBlockStateException("Invalid rail type meta $meta"); + throw new InvalidBlockStateException("Invalid rail type meta $stateMeta"); } $this->connections = $connections; } diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 6123b35cf1..25fe965826 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -61,10 +61,10 @@ class Bed extends Transparent{ ($this->head ? self::BITFLAG_HEAD : 0); } - public function readStateFromMeta(int $meta) : void{ - $this->facing = BlockDataValidator::readLegacyHorizontalFacing($meta & 0x03); - $this->occupied = ($meta & self::BITFLAG_OCCUPIED) !== 0; - $this->head = ($meta & self::BITFLAG_HEAD) !== 0; + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); + $this->occupied = ($stateMeta & self::BITFLAG_OCCUPIED) !== 0; + $this->head = ($stateMeta & self::BITFLAG_HEAD) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index f0f40b94ed..53d85a9251 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -133,10 +133,12 @@ class Block extends Position implements BlockIds, Metadatable{ } /** - * @param int $meta + * @param int $id + * @param int $stateMeta + * * @throws InvalidBlockStateException */ - public function readStateFromMeta(int $meta) : void{ + public function readStateFromData(int $id, int $stateMeta) : void{ //NOOP } @@ -176,7 +178,10 @@ class Block extends Position implements BlockIds, Metadatable{ } /** - * Returns whether the given block has an equivalent type to this one. + * Returns whether the given block has an equivalent type to this one. This compares base legacy ID and variant. + * + * Note: This ignores additional IDs used to represent additional states. This means that, for example, a lit + * furnace and unlit furnace are considered the same type. * * @param Block $other * diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index f271e2ef0e..1b5977a90b 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -27,7 +27,6 @@ use pocketmine\block\BlockIdentifier as BID; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\block\utils\PillarRotationTrait; -use pocketmine\block\utils\SlabType; use pocketmine\block\utils\TreeType; use pocketmine\item\ItemIds; use pocketmine\level\Position; @@ -107,8 +106,7 @@ class BlockFactory{ self::register(new CocoaBlock(new BID(Block::COCOA), "Cocoa Block")); self::register(new CraftingTable(new BID(Block::CRAFTING_TABLE), "Crafting Table")); self::register(new Dandelion(new BID(Block::DANDELION), "Dandelion")); - self::register($daylightSensor = new DaylightSensor(new BlockIdentifierFlattened(Block::DAYLIGHT_DETECTOR, Block::DAYLIGHT_DETECTOR_INVERTED), "Daylight Sensor")); - self::register((clone $daylightSensor)->setInverted()); //flattening hack + self::register(new DaylightSensor(new BlockIdentifierFlattened(Block::DAYLIGHT_DETECTOR, Block::DAYLIGHT_DETECTOR_INVERTED), "Daylight Sensor")); self::register(new DeadBush(new BID(Block::DEADBUSH), "Dead Bush")); self::register(new DetectorRail(new BID(Block::DETECTOR_RAIL), "Detector Rail")); self::register(new Diamond(new BID(Block::DIAMOND_BLOCK), "Diamond Block")); @@ -148,8 +146,7 @@ class BlockFactory{ self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_RED_TULIP), "Red Tulip")); self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_WHITE_TULIP), "White Tulip")); self::register(new FlowerPot(new BID(Block::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, \pocketmine\tile\FlowerPot::class), "Flower Pot")); - self::register($furnace = new Furnace(new BlockIdentifierFlattened(Block::FURNACE, Block::LIT_FURNACE, 0, null, \pocketmine\tile\Furnace::class), "Furnace")); - self::register((clone $furnace)->setLit()); //flattening hack + self::register(new Furnace(new BlockIdentifierFlattened(Block::FURNACE, Block::LIT_FURNACE, 0, null, \pocketmine\tile\Furnace::class), "Furnace")); self::register(new Glass(new BID(Block::GLASS), "Glass")); self::register(new GlassPane(new BID(Block::GLASS_PANE), "Glass Pane")); self::register(new GlazedTerracotta(new BID(Block::BLACK_GLAZED_TERRACOTTA), "Black Glazed Terracotta")); @@ -192,8 +189,7 @@ class BlockFactory{ self::register(new Ladder(new BID(Block::LADDER), "Ladder")); self::register(new Lapis(new BID(Block::LAPIS_BLOCK), "Lapis Lazuli Block")); self::register(new LapisOre(new BID(Block::LAPIS_ORE), "Lapis Lazuli Ore")); - self::register($lava = new Lava(new BlockIdentifierFlattened(Block::FLOWING_LAVA, Block::STILL_LAVA), "Lava")); - self::register((clone $lava)->setStill()); //flattening hack + self::register(new Lava(new BlockIdentifierFlattened(Block::FLOWING_LAVA, Block::STILL_LAVA), "Lava")); self::register(new Lever(new BID(Block::LEVER), "Lever")); self::register(new LitPumpkin(new BID(Block::JACK_O_LANTERN), "Jack o'Lantern")); self::register(new Magma(new BID(Block::MAGMA), "Magma Block")); @@ -239,14 +235,10 @@ class BlockFactory{ self::register(new RedMushroom(new BID(Block::RED_MUSHROOM), "Red Mushroom")); self::register(new RedMushroomBlock(new BID(Block::RED_MUSHROOM_BLOCK), "Red Mushroom Block")); self::register(new Redstone(new BID(Block::REDSTONE_BLOCK), "Redstone Block")); - self::register($redstoneLamp = new RedstoneLamp(new BlockIdentifierFlattened(Block::REDSTONE_LAMP, Block::LIT_REDSTONE_LAMP), "Redstone Lamp")); - self::register((clone $redstoneLamp)->setLit()); //flattening hack - self::register($redstoneOre = new RedstoneOre(new BlockIdentifierFlattened(Block::REDSTONE_ORE, Block::LIT_REDSTONE_ORE), "Redstone Ore")); - self::register((clone $redstoneOre)->setLit()); //flattening hack - self::register($repeater = new RedstoneRepeater(new BlockIdentifierFlattened(Block::UNPOWERED_REPEATER, Block::POWERED_REPEATER, 0, ItemIds::REPEATER), "Redstne Repeater")); - self::register((clone $repeater)->setPowered()); - self::register($redstoneTorch = new RedstoneTorch(new BlockIdentifierFlattened(Block::REDSTONE_TORCH, Block::UNLIT_REDSTONE_TORCH), "Redstone Torch")); - self::register((clone $redstoneTorch)->setLit(false)); //flattening hack + self::register(new RedstoneLamp(new BlockIdentifierFlattened(Block::REDSTONE_LAMP, Block::LIT_REDSTONE_LAMP), "Redstone Lamp")); + self::register(new RedstoneOre(new BlockIdentifierFlattened(Block::REDSTONE_ORE, Block::LIT_REDSTONE_ORE), "Redstone Ore")); + self::register(new RedstoneRepeater(new BlockIdentifierFlattened(Block::UNPOWERED_REPEATER, Block::POWERED_REPEATER, 0, ItemIds::REPEATER), "Redstne Repeater")); + self::register(new RedstoneTorch(new BlockIdentifierFlattened(Block::REDSTONE_TORCH, Block::UNLIT_REDSTONE_TORCH), "Redstone Torch")); self::register(new RedstoneWire(new BID(Block::REDSTONE_WIRE, 0, ItemIds::REDSTONE), "Redstone")); self::register(new Reserved6(new BID(Block::RESERVED6), "reserved6")); self::register(new Sand(new BID(Block::SAND), "Sand")); @@ -275,6 +267,22 @@ class BlockFactory{ self::register(new StoneBricks(new BID(Block::STONEBRICK, StoneBricks::NORMAL), "Stone Bricks")); self::register(new StoneButton(new BID(Block::STONE_BUTTON), "Stone Button")); self::register(new StonePressurePlate(new BID(Block::STONE_PRESSURE_PLATE), "Stone Pressure Plate")); + self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 0), "Stone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 1), "Sandstone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 2), "Fake Wooden")); + self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 3), "Cobblestone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 4), "Brick")); + self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 5), "Stone Brick")); + self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 6), "Quartz")); + self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 7), "Nether Brick")); + self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 0), "Red Sandstone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 1), "Purpur")); + self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 2), "Prismarine")); + self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 3), "Dark Prismarine")); + self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 4), "Prismarine Bricks")); + self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 5), "Mossy Cobblestone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 6), "Smooth Sandstone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 7), "Red Nether Brick")); self::register(new Stonecutter(new BID(Block::STONECUTTER), "Stonecutter")); self::register(new Sugarcane(new BID(Block::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane")); self::register(new TNT(new BID(Block::TNT), "TNT")); @@ -295,8 +303,7 @@ class BlockFactory{ self::register(new Vine(new BID(Block::VINE), "Vines")); self::register(new WallBanner(new BID(Block::WALL_BANNER, 0, ItemIds::BANNER, \pocketmine\tile\Banner::class), "Wall Banner")); self::register(new WallSign(new BID(Block::WALL_SIGN, 0, ItemIds::SIGN, \pocketmine\tile\Sign::class), "Wall Sign")); - self::register($water = new Water(new BlockIdentifierFlattened(Block::FLOWING_WATER, Block::STILL_WATER), "Water")); - self::register((clone $water)->setStill()); //flattening hack + self::register(new Water(new BlockIdentifierFlattened(Block::FLOWING_WATER, Block::STILL_WATER), "Water")); self::register(new WaterLily(new BID(Block::LILY_PAD), "Lily Pad")); self::register(new WeightedPressurePlateHeavy(new BID(Block::HEAVY_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Heavy")); self::register(new WeightedPressurePlateLight(new BID(Block::LIGHT_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Light")); @@ -322,6 +329,7 @@ class BlockFactory{ self::register(new Planks(new BID(Block::PLANKS, $magicNumber), $name . " Planks")); self::register(new Sapling(new BID(Block::SAPLING, $magicNumber), $name . " Sapling", $treeType)); self::register(new WoodenFence(new BID(Block::FENCE, $magicNumber), $name . " Fence")); + self::register(new WoodenSlab(new BlockIdentifierFlattened(Block::WOODEN_SLAB, Block::DOUBLE_WOODEN_SLAB, $treeType->getMagicNumber()), $treeType->getDisplayName())); //TODO: find a better way to deal with this split self::register(new Leaves(new BID($magicNumber >= 4 ? Block::LEAVES2 : Block::LEAVES, $magicNumber & 0x03), $name . " Leaves", $treeType)); @@ -352,33 +360,6 @@ class BlockFactory{ self::register(new Wool(new BID(Block::WOOL, $color->getMagicNumber()), $color->getDisplayName() . " Wool")); } - /** @var Slab[] $slabTypes */ - $slabTypes = [ - new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 0), "Stone"), - new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 1), "Sandstone"), - new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 2), "Fake Wooden"), - new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 3), "Cobblestone"), - new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 4), "Brick"), - new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 5), "Stone Brick"), - new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 6), "Quartz"), - new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 7), "Nether Brick"), - new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 0), "Red Sandstone"), - new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 1), "Purpur"), - new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 2), "Prismarine"), - new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 3), "Dark Prismarine"), - new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 4), "Prismarine Bricks"), - new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 5), "Mossy Cobblestone"), - new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 6), "Smooth Sandstone"), - new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 7), "Red Nether Brick") - ]; - foreach(TreeType::getAll() as $woodType){ - $slabTypes[] = new WoodenSlab(new BlockIdentifierFlattened(Block::WOODEN_SLAB, Block::DOUBLE_WOODEN_SLAB, $woodType->getMagicNumber()), $woodType->getDisplayName()); - } - foreach($slabTypes as $type){ - self::register($type); - self::register((clone $type)->setSlabType(SlabType::DOUBLE())); //flattening hack - } - static $wallTypes = [ CobblestoneWall::ANDESITE_WALL => "Andesite", CobblestoneWall::BRICK_WALL => "Brick", @@ -533,7 +514,6 @@ class BlockFactory{ * $override parameter. */ public static function register(Block $block, bool $override = false) : void{ - $id = $block->getId(); $variant = $block->getIdInfo()->getVariant(); $stateMask = $block->getStateBitmask(); @@ -541,36 +521,38 @@ class BlockFactory{ throw new \InvalidArgumentException("Block variant collides with state bitmask"); } - if(!$override and self::isRegistered($id, $variant)){ - throw new \InvalidArgumentException("Block registration $id:$variant conflicts with an existing block"); - } - - for($m = $variant; $m <= ($variant | $stateMask); ++$m){ - if(($m & ~$stateMask) !== $variant){ - continue; + foreach($block->getIdInfo()->getAllBlockIds() as $id){ + if(!$override and self::isRegistered($id, $variant)){ + throw new \InvalidArgumentException("Block registration $id:$variant conflicts with an existing block"); } - if(!$override and self::isRegistered($id, $m)){ - throw new \InvalidArgumentException("Block registration " . get_class($block) . " has states which conflict with other blocks"); - } - - $index = ($id << 4) | $m; - - $v = clone $block; - try{ - $v->readStateFromMeta($m & $stateMask); - if($v->getDamage() !== $m){ - throw new InvalidBlockStateException("Corrupted meta"); //don't register anything that isn't the same when we read it back again + for($m = $variant; $m <= ($variant | $stateMask); ++$m){ + if(($m & ~$stateMask) !== $variant){ + continue; } - }catch(InvalidBlockStateException $e){ //invalid property combination - continue; + + if(!$override and self::isRegistered($id, $m)){ + throw new \InvalidArgumentException("Block registration " . get_class($block) . " has states which conflict with other blocks"); + } + + $index = ($id << 4) | $m; + + $v = clone $block; + try{ + $v->readStateFromData($id, $m & $stateMask); + if($v->getDamage() !== $m){ + throw new InvalidBlockStateException("Corrupted meta"); //don't register anything that isn't the same when we read it back again + } + }catch(InvalidBlockStateException $e){ //invalid property combination + continue; + } + + self::fillStaticArrays($index, $v); } - self::fillStaticArrays($index, $v); - } - - if(!self::isRegistered($id, $variant)){ - self::fillStaticArrays(($id << 4) | $variant, $block); //register default state mapped to variant, for blocks which don't use 0 as valid state + if(!self::isRegistered($id, $variant)){ + self::fillStaticArrays(($id << 4) | $variant, $block); //register default state mapped to variant, for blocks which don't use 0 as valid state + } } } diff --git a/src/pocketmine/block/BlockIdentifier.php b/src/pocketmine/block/BlockIdentifier.php index b5e855911b..87cae2ad7b 100644 --- a/src/pocketmine/block/BlockIdentifier.php +++ b/src/pocketmine/block/BlockIdentifier.php @@ -48,6 +48,13 @@ class BlockIdentifier{ return $this->blockId; } + /** + * @return int[] + */ + public function getAllBlockIds() : array{ + return [$this->blockId]; + } + /** * @return int */ diff --git a/src/pocketmine/block/BlockIdentifierFlattened.php b/src/pocketmine/block/BlockIdentifierFlattened.php index 026134d8a4..adbeddedeb 100644 --- a/src/pocketmine/block/BlockIdentifierFlattened.php +++ b/src/pocketmine/block/BlockIdentifierFlattened.php @@ -39,4 +39,8 @@ class BlockIdentifierFlattened extends BlockIdentifier{ public function getSecondId() : int{ return $this->secondId; } + + public function getAllBlockIds() : array{ + return [$this->getBlockId(), $this->getSecondId()]; + } } diff --git a/src/pocketmine/block/BrewingStand.php b/src/pocketmine/block/BrewingStand.php index 5651d1cc3e..f9833823b1 100644 --- a/src/pocketmine/block/BrewingStand.php +++ b/src/pocketmine/block/BrewingStand.php @@ -38,10 +38,10 @@ class BrewingStand extends Transparent{ return ($this->eastSlot ? 0x01 : 0) | ($this->southwestSlot ? 0x02 : 0) | ($this->northwestSlot ? 0x04 : 0); } - public function readStateFromMeta(int $meta) : void{ - $this->eastSlot = ($meta & 0x01) !== 0; - $this->southwestSlot = ($meta & 0x02) !== 0; - $this->northwestSlot = ($meta & 0x04) !== 0; + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->eastSlot = ($stateMeta & 0x01) !== 0; + $this->southwestSlot = ($stateMeta & 0x02) !== 0; + $this->northwestSlot = ($stateMeta & 0x04) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Button.php b/src/pocketmine/block/Button.php index 1c4316d02c..cc5086e87f 100644 --- a/src/pocketmine/block/Button.php +++ b/src/pocketmine/block/Button.php @@ -41,10 +41,10 @@ abstract class Button extends Flowable{ return $this->facing | ($this->powered ? 0x08 : 0); } - public function readStateFromMeta(int $meta) : void{ + public function readStateFromData(int $id, int $stateMeta) : void{ //TODO: in PC it's (6 - facing) for every meta except 0 (down) - $this->facing = BlockDataValidator::readFacing($meta & 0x07); - $this->powered = ($meta & 0x08) !== 0; + $this->facing = BlockDataValidator::readFacing($stateMeta & 0x07); + $this->powered = ($stateMeta & 0x08) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index 0b16b7403b..ec8b514005 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -43,8 +43,8 @@ class Cactus extends Transparent{ return $this->age; } - public function readStateFromMeta(int $meta) : void{ - $this->age = BlockDataValidator::readBoundedInt("age", $meta, 0, 15); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 15); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index 670e19e323..d180732435 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -42,8 +42,8 @@ class Cake extends Transparent implements FoodSource{ return $this->bites; } - public function readStateFromMeta(int $meta) : void{ - $this->bites = BlockDataValidator::readBoundedInt("bites", $meta, 0, 6); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->bites = BlockDataValidator::readBoundedInt("bites", $stateMeta, 0, 6); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index 173efc56a2..14e27f7c57 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -40,8 +40,8 @@ class Chest extends Transparent{ return $this->facing; } - public function readStateFromMeta(int $meta) : void{ - $this->facing = BlockDataValidator::readHorizontalFacing($meta); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index 18b7fd2221..7cb8058029 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -45,9 +45,9 @@ class CocoaBlock extends Transparent{ return Bearing::fromFacing(Facing::opposite($this->facing)) | ($this->age << 2); } - public function readStateFromMeta(int $meta) : void{ - $this->facing = Facing::opposite(BlockDataValidator::readLegacyHorizontalFacing($meta & 0x03)); - $this->age = BlockDataValidator::readBoundedInt("age", $meta >> 2, 0, 2); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = Facing::opposite(BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03)); + $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta >> 2, 0, 2); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index 6d68af781b..f38e970db7 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -39,8 +39,8 @@ abstract class Crops extends Flowable{ return $this->age; } - public function readStateFromMeta(int $meta) : void{ - $this->age = BlockDataValidator::readBoundedInt("age", $meta, 0, 7); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 7); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/DaylightSensor.php b/src/pocketmine/block/DaylightSensor.php index 7b60e65180..a379c5f146 100644 --- a/src/pocketmine/block/DaylightSensor.php +++ b/src/pocketmine/block/DaylightSensor.php @@ -52,8 +52,9 @@ class DaylightSensor extends Transparent{ return $this->power; } - public function readStateFromMeta(int $meta) : void{ - $this->power = BlockDataValidator::readBoundedInt("power", $meta, 0, 15); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->power = BlockDataValidator::readBoundedInt("power", $stateMeta, 0, 15); + $this->inverted = $id === $this->idInfo->getSecondId(); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 44ef368a67..15ad3518a1 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -56,14 +56,14 @@ abstract class Door extends Transparent{ return Bearing::fromFacing(Facing::rotateY($this->facing, true)) | ($this->open ? 0x04 : 0); } - public function readStateFromMeta(int $meta) : void{ - $this->top = $meta & 0x08; + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->top = $stateMeta & 0x08; if($this->top){ - $this->hingeRight = ($meta & 0x01) !== 0; - $this->powered = ($meta & 0x02) !== 0; + $this->hingeRight = ($stateMeta & 0x01) !== 0; + $this->powered = ($stateMeta & 0x02) !== 0; }else{ - $this->facing = Facing::rotateY(BlockDataValidator::readLegacyHorizontalFacing($meta & 0x03), false); - $this->open = ($meta & 0x04) !== 0; + $this->facing = Facing::rotateY(BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03), false); + $this->open = ($stateMeta & 0x04) !== 0; } } diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index f25c842ddb..30ecab2758 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -39,8 +39,8 @@ class DoublePlant extends Flowable{ return ($this->top ? self::BITFLAG_TOP : 0); } - public function readStateFromMeta(int $meta) : void{ - $this->top = ($meta & self::BITFLAG_TOP) !== 0; + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->top = ($stateMeta & self::BITFLAG_TOP) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/EndPortalFrame.php b/src/pocketmine/block/EndPortalFrame.php index 6d38c4bfa5..8f59f1ff3d 100644 --- a/src/pocketmine/block/EndPortalFrame.php +++ b/src/pocketmine/block/EndPortalFrame.php @@ -42,9 +42,9 @@ class EndPortalFrame extends Solid{ return Bearing::fromFacing($this->facing) | ($this->eye ? 0x04 : 0); } - public function readStateFromMeta(int $meta) : void{ - $this->facing = BlockDataValidator::readLegacyHorizontalFacing($meta & 0x03); - $this->eye = ($meta & 0x04) !== 0; + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); + $this->eye = ($stateMeta & 0x04) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/EndRod.php b/src/pocketmine/block/EndRod.php index 2975f8f41c..f831337058 100644 --- a/src/pocketmine/block/EndRod.php +++ b/src/pocketmine/block/EndRod.php @@ -42,12 +42,12 @@ class EndRod extends Flowable{ return $this->facing ^ 1; //TODO: in PC this is always the same as facing, just PE is stupid } - public function readStateFromMeta(int $meta) : void{ - if($meta !== 0 and $meta !== 1){ - $meta ^= 1; + public function readStateFromData(int $id, int $stateMeta) : void{ + if($stateMeta !== 0 and $stateMeta !== 1){ + $stateMeta ^= 1; } - $this->facing = BlockDataValidator::readFacing($meta); + $this->facing = BlockDataValidator::readFacing($stateMeta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index 6995d21e89..32d9079907 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -38,8 +38,8 @@ class Farmland extends Transparent{ return $this->wetness; } - public function readStateFromMeta(int $meta) : void{ - $this->wetness = BlockDataValidator::readBoundedInt("wetness", $meta, 0, 7); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->wetness = BlockDataValidator::readBoundedInt("wetness", $stateMeta, 0, 7); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index c378a4ac3a..a146b72519 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -44,10 +44,10 @@ class FenceGate extends Transparent{ return Bearing::fromFacing($this->facing) | ($this->open ? 0x04 : 0) | ($this->inWall ? 0x08 : 0); } - public function readStateFromMeta(int $meta) : void{ - $this->facing = BlockDataValidator::readLegacyHorizontalFacing($meta & 0x03); - $this->open = ($meta & 0x04) !== 0; - $this->inWall = ($meta & 0x08) !== 0; + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); + $this->open = ($stateMeta & 0x04) !== 0; + $this->inWall = ($stateMeta & 0x08) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Fire.php b/src/pocketmine/block/Fire.php index cf155413c1..faa722df4e 100644 --- a/src/pocketmine/block/Fire.php +++ b/src/pocketmine/block/Fire.php @@ -44,8 +44,8 @@ class Fire extends Flowable{ return $this->age; } - public function readStateFromMeta(int $meta) : void{ - $this->age = BlockDataValidator::readBoundedInt("age", $meta, 0, 15); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 15); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 4ff07b9a31..a8af03df7d 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -39,8 +39,8 @@ class FlowerPot extends Flowable{ return $this->occupied ? 1 : 0; } - public function readStateFromMeta(int $meta) : void{ - $this->occupied = $meta !== 0; + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->occupied = $stateMeta !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index 63e5c3948a..780771eaed 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -48,8 +48,9 @@ class Furnace extends Solid{ return $this->facing; } - public function readStateFromMeta(int $meta) : void{ - $this->facing = BlockDataValidator::readHorizontalFacing($meta); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); + $this->lit = $id === $this->idInfo->getSecondId(); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/GlazedTerracotta.php b/src/pocketmine/block/GlazedTerracotta.php index 0fb27de73f..83244b5567 100644 --- a/src/pocketmine/block/GlazedTerracotta.php +++ b/src/pocketmine/block/GlazedTerracotta.php @@ -40,8 +40,8 @@ class GlazedTerracotta extends Solid{ return $this->facing; } - public function readStateFromMeta(int $meta) : void{ - $this->facing = BlockDataValidator::readHorizontalFacing($meta); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 3eff935ca3..1f65296f1d 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -42,9 +42,9 @@ class ItemFrame extends Flowable{ return (5 - $this->facing) | ($this->hasMap ? 0x04 : 0); } - public function readStateFromMeta(int $meta) : void{ - $this->facing = BlockDataValidator::readHorizontalFacing(5 - ($meta & 0x03)); - $this->hasMap = ($meta & 0x04) !== 0; + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataValidator::readHorizontalFacing(5 - ($stateMeta & 0x03)); + $this->hasMap = ($stateMeta & 0x04) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Ladder.php b/src/pocketmine/block/Ladder.php index f99fdcc7a9..c7af4a453f 100644 --- a/src/pocketmine/block/Ladder.php +++ b/src/pocketmine/block/Ladder.php @@ -40,8 +40,8 @@ class Ladder extends Transparent{ return $this->facing; } - public function readStateFromMeta(int $meta) : void{ - $this->facing = BlockDataValidator::readHorizontalFacing($meta); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 85963e14fa..a61bacce74 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -51,9 +51,9 @@ class Leaves extends Transparent{ return ($this->noDecay ? 0x04 : 0) | ($this->checkDecay ? 0x08 : 0); } - public function readStateFromMeta(int $meta) : void{ - $this->noDecay = ($meta & 0x04) !== 0; - $this->checkDecay = ($meta & 0x08) !== 0; + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->noDecay = ($stateMeta & 0x04) !== 0; + $this->checkDecay = ($stateMeta & 0x08) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index 2f24233284..ce88e9bed5 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -53,8 +53,8 @@ class Lever extends Flowable{ return $rotationMeta | ($this->powered ? 0x08 : 0); } - public function readStateFromMeta(int $meta) : void{ - $rotationMeta = $meta & 0x07; + public function readStateFromData(int $id, int $stateMeta) : void{ + $rotationMeta = $stateMeta & 0x07; if($rotationMeta === 5 or $rotationMeta === 6){ $this->position = self::TOP; $this->facing = $rotationMeta === 5 ? Facing::SOUTH : Facing::EAST; @@ -66,7 +66,7 @@ class Lever extends Flowable{ $this->facing = BlockDataValidator::readHorizontalFacing(6 - $rotationMeta); } - $this->powered = ($meta & 0x08) !== 0; + $this->powered = ($stateMeta & 0x08) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index d0280b012f..cb98b7ca83 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -71,9 +71,10 @@ abstract class Liquid extends Transparent{ return $this->decay | ($this->falling ? 0x08 : 0); } - public function readStateFromMeta(int $meta) : void{ - $this->decay = BlockDataValidator::readBoundedInt("decay", $meta & 0x07, 0, 7); - $this->falling = ($meta & 0x08) !== 0; + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->decay = BlockDataValidator::readBoundedInt("decay", $stateMeta & 0x07, 0, 7); + $this->falling = ($stateMeta & 0x08) !== 0; + $this->still = $id === $this->idInfo->getSecondId(); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/NetherReactor.php b/src/pocketmine/block/NetherReactor.php index 1ec7ab236c..3a90117e83 100644 --- a/src/pocketmine/block/NetherReactor.php +++ b/src/pocketmine/block/NetherReactor.php @@ -40,8 +40,8 @@ class NetherReactor extends Solid{ return $this->state; } - public function readStateFromMeta(int $meta) : void{ - $this->state = BlockDataValidator::readBoundedInt("state", $meta, 0, 2); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->state = BlockDataValidator::readBoundedInt("state", $stateMeta, 0, 2); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index 9489847e9e..60775f8820 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -41,8 +41,8 @@ class NetherWartPlant extends Flowable{ return $this->age; } - public function readStateFromMeta(int $meta) : void{ - $this->age = BlockDataValidator::readBoundedInt("age", $meta, 0, 3); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 3); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Pumpkin.php b/src/pocketmine/block/Pumpkin.php index 7bd2e08b93..d0abc3653d 100644 --- a/src/pocketmine/block/Pumpkin.php +++ b/src/pocketmine/block/Pumpkin.php @@ -35,8 +35,8 @@ class Pumpkin extends Solid{ /** @var int */ protected $facing = Facing::NORTH; - public function readStateFromMeta(int $meta) : void{ - $this->facing = BlockDataValidator::readLegacyHorizontalFacing($meta & 0x03); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/RedMushroomBlock.php b/src/pocketmine/block/RedMushroomBlock.php index 42403f67d6..7e2bbf48ea 100644 --- a/src/pocketmine/block/RedMushroomBlock.php +++ b/src/pocketmine/block/RedMushroomBlock.php @@ -41,8 +41,8 @@ class RedMushroomBlock extends Solid{ return $this->rotationData; } - public function readStateFromMeta(int $meta) : void{ - $this->rotationData = $meta; + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->rotationData = $stateMeta; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/RedstoneLamp.php b/src/pocketmine/block/RedstoneLamp.php index 15df287eb1..eae4bdf2ce 100644 --- a/src/pocketmine/block/RedstoneLamp.php +++ b/src/pocketmine/block/RedstoneLamp.php @@ -39,6 +39,10 @@ class RedstoneLamp extends Solid{ return $this->lit ? $this->idInfo->getSecondId() : parent::getId(); } + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->lit = $id === $this->idInfo->getSecondId(); + } + public function isLit() : bool{ return $this->lit; } diff --git a/src/pocketmine/block/RedstoneOre.php b/src/pocketmine/block/RedstoneOre.php index 306ae7db04..c5f13c09f6 100644 --- a/src/pocketmine/block/RedstoneOre.php +++ b/src/pocketmine/block/RedstoneOre.php @@ -45,6 +45,10 @@ class RedstoneOre extends Solid{ return $this->lit ? $this->idInfo->getSecondId() : parent::getId(); } + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->lit = $id === $this->idInfo->getSecondId(); + } + public function getHardness() : float{ return 3; } diff --git a/src/pocketmine/block/RedstoneRail.php b/src/pocketmine/block/RedstoneRail.php index 01b1b10c98..3678a5f9fa 100644 --- a/src/pocketmine/block/RedstoneRail.php +++ b/src/pocketmine/block/RedstoneRail.php @@ -33,9 +33,9 @@ abstract class RedstoneRail extends BaseRail{ return parent::writeStateToMeta() | ($this->powered ? self::FLAG_POWERED : 0); } - public function readStateFromMeta(int $meta) : void{ - parent::readStateFromMeta($meta); - $this->powered = ($meta & self::FLAG_POWERED) !== 0; + public function readStateFromData(int $id, int $stateMeta) : void{ + parent::readStateFromData($id, $stateMeta); + $this->powered = ($stateMeta & self::FLAG_POWERED) !== 0; } protected function getConnectionsFromMeta(int $meta) : ?array{ diff --git a/src/pocketmine/block/RedstoneRepeater.php b/src/pocketmine/block/RedstoneRepeater.php index 29c658f324..160703cdcd 100644 --- a/src/pocketmine/block/RedstoneRepeater.php +++ b/src/pocketmine/block/RedstoneRepeater.php @@ -50,9 +50,10 @@ class RedstoneRepeater extends Flowable{ return $this->powered ? $this->idInfo->getSecondId() : parent::getId(); } - public function readStateFromMeta(int $meta) : void{ - $this->facing = BlockDataValidator::readLegacyHorizontalFacing($meta & 0x03); - $this->delay = BlockDataValidator::readBoundedInt("delay", ($meta >> 2) + 1, 1, 4); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); + $this->delay = BlockDataValidator::readBoundedInt("delay", ($stateMeta >> 2) + 1, 1, 4); + $this->powered = $id === $this->idInfo->getSecondId(); } public function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/RedstoneTorch.php b/src/pocketmine/block/RedstoneTorch.php index 44119dc26f..a1974c2ce3 100644 --- a/src/pocketmine/block/RedstoneTorch.php +++ b/src/pocketmine/block/RedstoneTorch.php @@ -39,6 +39,11 @@ class RedstoneTorch extends Torch{ return $this->lit ? parent::getId() : $this->idInfo->getSecondId(); } + public function readStateFromData(int $id, int $stateMeta) : void{ + parent::readStateFromData($id, $stateMeta); + $this->lit = $id !== $this->idInfo->getSecondId(); + } + public function isLit() : bool{ return $this->lit; } diff --git a/src/pocketmine/block/RedstoneWire.php b/src/pocketmine/block/RedstoneWire.php index e8d2a3b7db..6f95e906b4 100644 --- a/src/pocketmine/block/RedstoneWire.php +++ b/src/pocketmine/block/RedstoneWire.php @@ -30,8 +30,8 @@ class RedstoneWire extends Flowable{ /** @var int */ protected $power = 0; - public function readStateFromMeta(int $meta) : void{ - $this->power = BlockDataValidator::readBoundedInt("power", $meta, 0, 15); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->power = BlockDataValidator::readBoundedInt("power", $stateMeta, 0, 15); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index 9e07f7ebc9..1511ba3438 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -48,8 +48,8 @@ class Sapling extends Flowable{ return ($this->ready ? 0x08 : 0); } - public function readStateFromMeta(int $meta) : void{ - $this->ready = ($meta & 0x08) !== 0; + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->ready = ($stateMeta & 0x08) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/SignPost.php b/src/pocketmine/block/SignPost.php index 8cd0c16d17..e8a196865b 100644 --- a/src/pocketmine/block/SignPost.php +++ b/src/pocketmine/block/SignPost.php @@ -39,8 +39,8 @@ class SignPost extends Transparent{ return $this->rotation; } - public function readStateFromMeta(int $meta) : void{ - $this->rotation = $meta; + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->rotation = $stateMeta; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index 1b14ac161d..37d88cdd56 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -46,8 +46,8 @@ class Skull extends Flowable{ return $this->facing; } - public function readStateFromMeta(int $meta) : void{ - $this->facing = $meta === 1 ? Facing::UP : BlockDataValidator::readHorizontalFacing($meta); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = $stateMeta === 1 ? Facing::UP : BlockDataValidator::readHorizontalFacing($stateMeta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index 311802e7a2..e1de5a78eb 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -53,9 +53,11 @@ abstract class Slab extends Transparent{ return 0; } - public function readStateFromMeta(int $meta) : void{ - if($this->slabType !== SlabType::DOUBLE()){ - $this->slabType = ($meta & 0x08) !== 0 ? SlabType::TOP() : SlabType::BOTTOM(); + public function readStateFromData(int $id, int $stateMeta) : void{ + if($id === $this->idInfo->getSecondId()){ + $this->slabType = SlabType::DOUBLE(); + }else{ + $this->slabType = ($stateMeta & 0x08) !== 0 ? SlabType::TOP() : SlabType::BOTTOM(); } } diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index 733ea25957..617ef79c72 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -46,8 +46,8 @@ class SnowLayer extends Flowable implements Fallable{ return $this->layers - 1; } - public function readStateFromMeta(int $meta) : void{ - $this->layers = BlockDataValidator::readBoundedInt("layers", $meta + 1, 1, 8); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->layers = BlockDataValidator::readBoundedInt("layers", $stateMeta + 1, 1, 8); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Sponge.php b/src/pocketmine/block/Sponge.php index dda5d8e65f..f72ec0b7b7 100644 --- a/src/pocketmine/block/Sponge.php +++ b/src/pocketmine/block/Sponge.php @@ -33,8 +33,8 @@ class Sponge extends Solid{ return $this->wet ? 1 : 0; } - public function readStateFromMeta(int $meta) : void{ - $this->wet = $meta !== 0; + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->wet = $stateMeta !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index fba071a54f..2af550a0f5 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -48,9 +48,9 @@ abstract class Stair extends Transparent{ return (5 - $this->facing) | ($this->upsideDown ? 0x04 : 0); } - public function readStateFromMeta(int $meta) : void{ - $this->facing = BlockDataValidator::readHorizontalFacing(5 - ($meta & 0x03)); - $this->upsideDown = ($meta & 0x04) !== 0; + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataValidator::readHorizontalFacing(5 - ($stateMeta & 0x03)); + $this->upsideDown = ($stateMeta & 0x04) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index fd23d3a74e..aa2bf17351 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -42,8 +42,8 @@ class StandingBanner extends Transparent{ return $this->rotation; } - public function readStateFromMeta(int $meta) : void{ - $this->rotation = $meta; + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->rotation = $stateMeta; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/StonePressurePlate.php b/src/pocketmine/block/StonePressurePlate.php index 501c2ee0f9..650f63c364 100644 --- a/src/pocketmine/block/StonePressurePlate.php +++ b/src/pocketmine/block/StonePressurePlate.php @@ -34,8 +34,8 @@ class StonePressurePlate extends Transparent{ return $this->powered ? 1 : 0; } - public function readStateFromMeta(int $meta) : void{ - $this->powered = $meta !== 0; + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->powered = $stateMeta !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index cdde3cbdef..221e1e5318 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -39,8 +39,8 @@ class Sugarcane extends Flowable{ return $this->age; } - public function readStateFromMeta(int $meta) : void{ - $this->age = BlockDataValidator::readBoundedInt("age", $meta, 0, 15); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 15); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index 2055f95a21..46a2036c58 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -38,8 +38,8 @@ class Torch extends Flowable{ return 6 - $this->facing; } - public function readStateFromMeta(int $meta) : void{ - $this->facing = $meta === 5 ? Facing::UP : BlockDataValidator::readHorizontalFacing(6 - $meta); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = $stateMeta === 5 ? Facing::UP : BlockDataValidator::readHorizontalFacing(6 - $stateMeta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index 4349f7fd29..b2c6ddb4fe 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -46,12 +46,12 @@ class Trapdoor extends Transparent{ return (5 - $this->facing) | ($this->top ? self::MASK_UPPER : 0) | ($this->open ? self::MASK_OPENED : 0); } - public function readStateFromMeta(int $meta) : void{ + public function readStateFromData(int $id, int $stateMeta) : void{ //TODO: in PC the values are reversed (facing - 2) - $this->facing = BlockDataValidator::readHorizontalFacing(5 - ($meta & 0x03)); - $this->top = ($meta & self::MASK_UPPER) !== 0; - $this->open = ($meta & self::MASK_OPENED) !== 0; + $this->facing = BlockDataValidator::readHorizontalFacing(5 - ($stateMeta & 0x03)); + $this->top = ($stateMeta & self::MASK_UPPER) !== 0; + $this->open = ($stateMeta & self::MASK_OPENED) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Tripwire.php b/src/pocketmine/block/Tripwire.php index b55d283b9d..58c45a065b 100644 --- a/src/pocketmine/block/Tripwire.php +++ b/src/pocketmine/block/Tripwire.php @@ -39,10 +39,10 @@ class Tripwire extends Flowable{ return ($this->triggered ? 0x01 : 0) | ($this->connected ? 0x04 : 0) | ($this->disarmed ? 0x08 : 0); } - public function readStateFromMeta(int $meta) : void{ - $this->triggered = ($meta & 0x01) !== 0; - $this->connected = ($meta & 0x04) !== 0; - $this->disarmed = ($meta & 0x08) !== 0; + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->triggered = ($stateMeta & 0x01) !== 0; + $this->connected = ($stateMeta & 0x04) !== 0; + $this->disarmed = ($stateMeta & 0x08) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/TripwireHook.php b/src/pocketmine/block/TripwireHook.php index 84356d34cf..d35b15bc18 100644 --- a/src/pocketmine/block/TripwireHook.php +++ b/src/pocketmine/block/TripwireHook.php @@ -43,10 +43,10 @@ class TripwireHook extends Flowable{ return Bearing::fromFacing($this->facing) | ($this->connected ? 0x04 : 0) | ($this->powered ? 0x08 : 0); } - public function readStateFromMeta(int $meta) : void{ - $this->facing = BlockDataValidator::readLegacyHorizontalFacing($meta & 0x03); - $this->connected = ($meta & 0x04) !== 0; - $this->powered = ($meta & 0x08) !== 0; + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); + $this->connected = ($stateMeta & 0x04) !== 0; + $this->powered = ($stateMeta & 0x08) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index a65fc48a88..a4b6716526 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -50,11 +50,11 @@ class Vine extends Flowable{ (isset($this->faces[Facing::EAST]) ? self::FLAG_EAST : 0); } - public function readStateFromMeta(int $meta) : void{ - $this->setFaceFromMeta($meta, self::FLAG_SOUTH, Facing::SOUTH); - $this->setFaceFromMeta($meta, self::FLAG_WEST, Facing::WEST); - $this->setFaceFromMeta($meta, self::FLAG_NORTH, Facing::NORTH); - $this->setFaceFromMeta($meta, self::FLAG_EAST, Facing::EAST); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->setFaceFromMeta($stateMeta, self::FLAG_SOUTH, Facing::SOUTH); + $this->setFaceFromMeta($stateMeta, self::FLAG_WEST, Facing::WEST); + $this->setFaceFromMeta($stateMeta, self::FLAG_NORTH, Facing::NORTH); + $this->setFaceFromMeta($stateMeta, self::FLAG_EAST, Facing::EAST); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/WallBanner.php b/src/pocketmine/block/WallBanner.php index 5aa2dc757c..7acdba5b78 100644 --- a/src/pocketmine/block/WallBanner.php +++ b/src/pocketmine/block/WallBanner.php @@ -35,8 +35,8 @@ class WallBanner extends StandingBanner{ return $this->facing; } - public function readStateFromMeta(int $meta) : void{ - $this->facing = BlockDataValidator::readHorizontalFacing($meta); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/WallSign.php b/src/pocketmine/block/WallSign.php index b7c7448da2..79f85999af 100644 --- a/src/pocketmine/block/WallSign.php +++ b/src/pocketmine/block/WallSign.php @@ -35,8 +35,8 @@ class WallSign extends SignPost{ return $this->facing; } - public function readStateFromMeta(int $meta) : void{ - $this->facing = BlockDataValidator::readHorizontalFacing($meta); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/WeightedPressurePlateLight.php b/src/pocketmine/block/WeightedPressurePlateLight.php index 9fac934c9c..f6d717f5e9 100644 --- a/src/pocketmine/block/WeightedPressurePlateLight.php +++ b/src/pocketmine/block/WeightedPressurePlateLight.php @@ -35,8 +35,8 @@ class WeightedPressurePlateLight extends Transparent{ return $this->power; } - public function readStateFromMeta(int $meta) : void{ - $this->power = BlockDataValidator::readBoundedInt("power", $meta, 0, 15); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->power = BlockDataValidator::readBoundedInt("power", $stateMeta, 0, 15); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/utils/PillarRotationTrait.php b/src/pocketmine/block/utils/PillarRotationTrait.php index d742792f0f..8b4aa32cbb 100644 --- a/src/pocketmine/block/utils/PillarRotationTrait.php +++ b/src/pocketmine/block/utils/PillarRotationTrait.php @@ -43,11 +43,13 @@ trait PillarRotationTrait{ } /** - * @see Block::readStateFromMeta() - * @param int $meta + * @see Block::readStateFromData() + * + * @param int $id + * @param int $stateMeta */ - public function readStateFromMeta(int $meta) : void{ - $this->readAxisFromMeta($meta); + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->readAxisFromMeta($stateMeta); } /** From 6ab171d629225cf975d107f96e6b0dc9712c1fa0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Feb 2019 10:41:06 +0000 Subject: [PATCH 0510/3224] Fixed unit tests --- tests/phpunit/block/BlockTest.php | 10 +++++----- tests/phpunit/block/MyCustomBlock.php | 3 --- tests/phpunit/block/StrangeNewBlock.php | 4 +--- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index 6c1ac5a2f3..053cfc284c 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -35,7 +35,7 @@ class BlockTest extends TestCase{ * Test registering a block which would overwrite another block, without forcing it */ public function testAccidentalOverrideBlock() : void{ - $block = new MyCustomBlock(); + $block = new MyCustomBlock(new BlockIdentifier(Block::COBBLESTONE), "Cobblestone"); $this->expectException(\InvalidArgumentException::class); BlockFactory::register($block); } @@ -44,7 +44,7 @@ class BlockTest extends TestCase{ * Test registering a block deliberately overwriting another block works as expected */ public function testDeliberateOverrideBlock() : void{ - $block = new MyCustomBlock(); + $block = new MyCustomBlock(new BlockIdentifier(Block::COBBLESTONE), "Cobblestone"); BlockFactory::register($block, true); self::assertInstanceOf(MyCustomBlock::class, BlockFactory::get($block->getId())); } @@ -55,7 +55,7 @@ class BlockTest extends TestCase{ public function testRegisterNewBlock() : void{ for($i = 0; $i < 256; ++$i){ if(!BlockFactory::isRegistered($i)){ - $b = new StrangeNewBlock($i); + $b = new StrangeNewBlock(new BlockIdentifier($i), "Strange New Block"); BlockFactory::register($b); self::assertInstanceOf(StrangeNewBlock::class, BlockFactory::get($b->getId())); return; @@ -70,7 +70,7 @@ class BlockTest extends TestCase{ */ public function testRegisterIdTooLarge() : void{ self::expectException(\RuntimeException::class); - BlockFactory::register(new OutOfBoundsBlock(25555)); + BlockFactory::register(new OutOfBoundsBlock(new BlockIdentifier(25555), "Out Of Bounds Block")); } /** @@ -78,7 +78,7 @@ class BlockTest extends TestCase{ */ public function testRegisterIdTooSmall() : void{ self::expectException(\RuntimeException::class); - BlockFactory::register(new OutOfBoundsBlock(-1)); + BlockFactory::register(new OutOfBoundsBlock(new BlockIdentifier(-1), "Out Of Bounds Block")); } /** diff --git a/tests/phpunit/block/MyCustomBlock.php b/tests/phpunit/block/MyCustomBlock.php index 58bb1a6eb7..45b8a00e1c 100644 --- a/tests/phpunit/block/MyCustomBlock.php +++ b/tests/phpunit/block/MyCustomBlock.php @@ -25,7 +25,4 @@ namespace pocketmine\block; class MyCustomBlock extends Cobblestone{ - public function getName() : string{ - return "MyCobblestone"; - } } diff --git a/tests/phpunit/block/StrangeNewBlock.php b/tests/phpunit/block/StrangeNewBlock.php index 1e78a40928..3ffa820202 100644 --- a/tests/phpunit/block/StrangeNewBlock.php +++ b/tests/phpunit/block/StrangeNewBlock.php @@ -24,7 +24,5 @@ declare(strict_types=1); namespace pocketmine\block; class StrangeNewBlock extends Solid{ - public function getName() : string{ - return "Strange New Block"; - } + } From 0120585aee48c07691948acef6011ff6a27f662c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Feb 2019 11:37:21 +0000 Subject: [PATCH 0511/3224] Block: name is no longer nullable --- src/pocketmine/block/Block.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 53d85a9251..875ca491ff 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -68,7 +68,7 @@ class Block extends Position implements BlockIds, Metadatable{ /** @var BlockIdentifier */ protected $idInfo; - /** @var string|null */ + /** @var string */ protected $fallbackName; @@ -79,7 +79,7 @@ class Block extends Position implements BlockIds, Metadatable{ /** * @param BlockIdentifier $idInfo - * @param string|null $name English name of the block type (TODO: implement translations) + * @param string $name English name of the block type (TODO: implement translations) */ public function __construct(BlockIdentifier $idInfo, string $name){ if(($idInfo->getVariant() & $this->getStateBitmask()) !== 0){ From 28d01025b054b472a5fbbb753036c04d6941c3c7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Feb 2019 12:13:21 +0000 Subject: [PATCH 0512/3224] Improve consistency of handling coloured and wooden blocks this is ugly, but less ugly than the earlier version. --- src/pocketmine/block/BlockFactory.php | 85 ++++++++++++++++----------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 1b5977a90b..184e2016b4 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -127,12 +127,6 @@ class BlockFactory{ self::register(new EndStoneBricks(new BID(Block::END_BRICKS), "End Stone Bricks")); self::register(new EnderChest(new BID(Block::ENDER_CHEST, 0, null, \pocketmine\tile\EnderChest::class), "Ender Chest")); self::register(new Farmland(new BID(Block::FARMLAND), "Farmland")); - self::register(new FenceGate(new BID(Block::ACACIA_FENCE_GATE), "Acacia Fence Gate")); - self::register(new FenceGate(new BID(Block::BIRCH_FENCE_GATE), "Birch Fence Gate")); - self::register(new FenceGate(new BID(Block::DARK_OAK_FENCE_GATE), "Dark Oak Fence Gate")); - self::register(new FenceGate(new BID(Block::OAK_FENCE_GATE), "Oak Fence Gate")); - self::register(new FenceGate(new BID(Block::JUNGLE_FENCE_GATE), "Jungle Fence Gate")); - self::register(new FenceGate(new BID(Block::SPRUCE_FENCE_GATE), "Spruce Fence Gate")); self::register(new Fire(new BID(Block::FIRE), "Fire Block")); self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_ALLIUM), "Allium")); self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_AZURE_BLUET), "Azure Bluet")); @@ -149,22 +143,6 @@ class BlockFactory{ self::register(new Furnace(new BlockIdentifierFlattened(Block::FURNACE, Block::LIT_FURNACE, 0, null, \pocketmine\tile\Furnace::class), "Furnace")); self::register(new Glass(new BID(Block::GLASS), "Glass")); self::register(new GlassPane(new BID(Block::GLASS_PANE), "Glass Pane")); - self::register(new GlazedTerracotta(new BID(Block::BLACK_GLAZED_TERRACOTTA), "Black Glazed Terracotta")); - self::register(new GlazedTerracotta(new BID(Block::BLUE_GLAZED_TERRACOTTA), "Blue Glazed Terracotta")); - self::register(new GlazedTerracotta(new BID(Block::BROWN_GLAZED_TERRACOTTA), "Brown Glazed Terracotta")); - self::register(new GlazedTerracotta(new BID(Block::CYAN_GLAZED_TERRACOTTA), "Cyan Glazed Terracotta")); - self::register(new GlazedTerracotta(new BID(Block::GRAY_GLAZED_TERRACOTTA), "Grey Glazed Terracotta")); - self::register(new GlazedTerracotta(new BID(Block::GREEN_GLAZED_TERRACOTTA), "Green Glazed Terracotta")); - self::register(new GlazedTerracotta(new BID(Block::LIGHT_BLUE_GLAZED_TERRACOTTA), "Light Blue Glazed Terracotta")); - self::register(new GlazedTerracotta(new BID(Block::LIME_GLAZED_TERRACOTTA), "Lime Glazed Terracotta")); - self::register(new GlazedTerracotta(new BID(Block::MAGENTA_GLAZED_TERRACOTTA), "Magenta Glazed Terracotta")); - self::register(new GlazedTerracotta(new BID(Block::ORANGE_GLAZED_TERRACOTTA), "Orange Glazed Terracotta")); - self::register(new GlazedTerracotta(new BID(Block::PINK_GLAZED_TERRACOTTA), "Pink Glazed Terracotta")); - self::register(new GlazedTerracotta(new BID(Block::PURPLE_GLAZED_TERRACOTTA), "Purple Glazed Terracotta")); - self::register(new GlazedTerracotta(new BID(Block::RED_GLAZED_TERRACOTTA), "Red Glazed Terracotta")); - self::register(new GlazedTerracotta(new BID(Block::SILVER_GLAZED_TERRACOTTA), "Light Grey Glazed Terracotta")); - self::register(new GlazedTerracotta(new BID(Block::WHITE_GLAZED_TERRACOTTA), "White Glazed Terracotta")); - self::register(new GlazedTerracotta(new BID(Block::YELLOW_GLAZED_TERRACOTTA), "Yellow Glazed Terracotta")); self::register(new GlowingObsidian(new BID(Block::GLOWINGOBSIDIAN), "Glowing Obsidian")); self::register(new Glowstone(new BID(Block::GLOWSTONE), "Glowstone")); self::register(new Gold(new BID(Block::GOLD_BLOCK), "Gold Block")); @@ -309,19 +287,34 @@ class BlockFactory{ self::register(new WeightedPressurePlateLight(new BID(Block::LIGHT_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Light")); self::register(new Wheat(new BID(Block::WHEAT_BLOCK), "Wheat Block")); self::register(new WoodenButton(new BID(Block::WOODEN_BUTTON), "Wooden Button")); - self::register(new WoodenDoor(new BID(Block::ACACIA_DOOR_BLOCK, 0, ItemIds::ACACIA_DOOR), "Acacia Door")); - self::register(new WoodenDoor(new BID(Block::BIRCH_DOOR_BLOCK, 0, ItemIds::BIRCH_DOOR), "Birch Door")); - self::register(new WoodenDoor(new BID(Block::DARK_OAK_DOOR_BLOCK, 0, ItemIds::DARK_OAK_DOOR), "Dark Oak Door")); - self::register(new WoodenDoor(new BID(Block::JUNGLE_DOOR_BLOCK, 0, ItemIds::JUNGLE_DOOR), "Jungle Door")); - self::register(new WoodenDoor(new BID(Block::OAK_DOOR_BLOCK, 0, ItemIds::OAK_DOOR), "Oak Door")); - self::register(new WoodenDoor(new BID(Block::SPRUCE_DOOR_BLOCK, 0, ItemIds::SPRUCE_DOOR), "Spruce Door")); self::register(new WoodenPressurePlate(new BID(Block::WOODEN_PRESSURE_PLATE), "Wooden Pressure Plate")); - self::register(new WoodenStairs(new BID(Block::ACACIA_STAIRS), "Acacia Stairs")); - self::register(new WoodenStairs(new BID(Block::BIRCH_STAIRS), "Birch Stairs")); - self::register(new WoodenStairs(new BID(Block::DARK_OAK_STAIRS), "Dark Oak Stairs")); - self::register(new WoodenStairs(new BID(Block::JUNGLE_STAIRS), "Jungle Stairs")); - self::register(new WoodenStairs(new BID(Block::OAK_STAIRS), "Oak Stairs")); - self::register(new WoodenStairs(new BID(Block::SPRUCE_STAIRS), "Spruce Stairs")); + + /** @var int[]|\SplObjectStorage $woodenStairIds */ + $woodenStairIds = new \SplObjectStorage(); + $woodenStairIds[TreeType::OAK()] = Block::OAK_STAIRS; + $woodenStairIds[TreeType::SPRUCE()] = Block::SPRUCE_STAIRS; + $woodenStairIds[TreeType::BIRCH()] = Block::BIRCH_STAIRS; + $woodenStairIds[TreeType::JUNGLE()] = Block::JUNGLE_STAIRS; + $woodenStairIds[TreeType::ACACIA()] = Block::ACACIA_STAIRS; + $woodenStairIds[TreeType::DARK_OAK()] = Block::DARK_OAK_STAIRS; + + /** @var int[]|\SplObjectStorage $fenceGateIds */ + $fenceGateIds = new \SplObjectStorage(); + $fenceGateIds[TreeType::OAK()] = Block::OAK_FENCE_GATE; + $fenceGateIds[TreeType::SPRUCE()] = Block::SPRUCE_FENCE_GATE; + $fenceGateIds[TreeType::BIRCH()] = Block::BIRCH_FENCE_GATE; + $fenceGateIds[TreeType::JUNGLE()] = Block::JUNGLE_FENCE_GATE; + $fenceGateIds[TreeType::ACACIA()] = Block::ACACIA_FENCE_GATE; + $fenceGateIds[TreeType::DARK_OAK()] = Block::DARK_OAK_FENCE_GATE; + + /** @var BID[]|\SplObjectStorage $woodenDoorIds */ + $woodenDoorIds = new \SplObjectStorage(); + $woodenDoorIds[TreeType::OAK()] = new BID(Block::OAK_DOOR_BLOCK, 0, ItemIds::OAK_DOOR); + $woodenDoorIds[TreeType::SPRUCE()] = new BID(Block::SPRUCE_DOOR_BLOCK, 0, ItemIds::SPRUCE_DOOR); + $woodenDoorIds[TreeType::BIRCH()] = new BID(Block::BIRCH_DOOR_BLOCK, 0, ItemIds::BIRCH_DOOR); + $woodenDoorIds[TreeType::JUNGLE()] = new BID(Block::JUNGLE_DOOR_BLOCK, 0, ItemIds::JUNGLE_DOOR); + $woodenDoorIds[TreeType::ACACIA()] = new BID(Block::ACACIA_DOOR_BLOCK, 0, ItemIds::ACACIA_DOOR); + $woodenDoorIds[TreeType::DARK_OAK()] = new BID(Block::DARK_OAK_DOOR_BLOCK, 0, ItemIds::DARK_OAK_DOOR); foreach(TreeType::getAll() as $treeType){ $magicNumber = $treeType->getMagicNumber(); @@ -335,6 +328,10 @@ class BlockFactory{ self::register(new Leaves(new BID($magicNumber >= 4 ? Block::LEAVES2 : Block::LEAVES, $magicNumber & 0x03), $name . " Leaves", $treeType)); self::register(new Log(new BID($magicNumber >= 4 ? Block::WOOD2 : Block::WOOD, $magicNumber & 0x03), $name . " Log", $treeType)); self::register(new Wood(new BID($magicNumber >= 4 ? Block::WOOD2 : Block::WOOD, ($magicNumber & 0x03) | 0b1100), $name . " Wood", $treeType)); + + self::register(new FenceGate(new BID($fenceGateIds[$treeType]), $treeType->getDisplayName() . " Fence Gate")); + self::register(new WoodenStairs(new BID($woodenStairIds[$treeType]), $treeType->getDisplayName() . " Stairs")); + self::register(new WoodenDoor($woodenDoorIds[$treeType], $treeType->getDisplayName() . " Door")); } static $sandstoneTypes = [ @@ -348,12 +345,32 @@ class BlockFactory{ self::register(new Sandstone(new BID(Block::RED_SANDSTONE, $variant), $prefix . "Red Sandstone")); } + /** @var int[]|\SplObjectStorage $glazedTerracottaIds */ + $glazedTerracottaIds = new \SplObjectStorage(); + $glazedTerracottaIds[DyeColor::WHITE()] = Block::WHITE_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::ORANGE()] = Block::ORANGE_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::MAGENTA()] = Block::MAGENTA_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::LIGHT_BLUE()] = Block::LIGHT_BLUE_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::YELLOW()] = Block::YELLOW_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::LIME()] = Block::LIME_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::PINK()] = Block::PINK_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::GRAY()] = Block::GRAY_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::LIGHT_GRAY()] = Block::SILVER_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::CYAN()] = Block::CYAN_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::PURPLE()] = Block::PURPLE_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::BLUE()] = Block::BLUE_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::BROWN()] = Block::BROWN_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::GREEN()] = Block::GREEN_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::RED()] = Block::RED_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::BLACK()] = Block::BLACK_GLAZED_TERRACOTTA; + foreach(DyeColor::getAll() as $color){ self::register(new Carpet(new BID(Block::CARPET, $color->getMagicNumber()), $color->getDisplayName() . " Carpet")); self::register(new Concrete(new BID(Block::CONCRETE, $color->getMagicNumber()), $color->getDisplayName() . " Concrete")); self::register(new ConcretePowder(new BID(Block::CONCRETE_POWDER, $color->getMagicNumber()), $color->getDisplayName() . " Concrete Powder")); self::register(new Glass(new BID(Block::STAINED_GLASS, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass")); self::register(new GlassPane(new BID(Block::STAINED_GLASS_PANE, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass Pane")); + self::register(new GlazedTerracotta(new BID($glazedTerracottaIds[$color]), $color->getDisplayName() . " Glazed Terracotta")); self::register(new HardenedClay(new BID(Block::STAINED_CLAY, $color->getMagicNumber()), $color->getDisplayName() . " Stained Clay")); self::register(new HardenedGlass(new BID(Block::HARD_STAINED_GLASS, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass")); self::register(new HardenedGlassPane(new BID(Block::HARD_STAINED_GLASS_PANE, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass Pane")); From eabd8ce0265fe8edb973032f848419ad9436cab3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Feb 2019 13:06:08 +0000 Subject: [PATCH 0513/3224] Fixup pressure plate hierarchy --- src/pocketmine/block/PressurePlate.php | 33 ++++++++++++++ src/pocketmine/block/SimplePressurePlate.php | 42 ++++++++++++++++++ src/pocketmine/block/StonePressurePlate.php | 21 +-------- .../block/WeightedPressurePlate.php | 44 +++++++++++++++++++ .../block/WeightedPressurePlateHeavy.php | 16 ++++++- .../block/WeightedPressurePlateLight.php | 22 +--------- src/pocketmine/block/WoodenPressurePlate.php | 10 ++--- 7 files changed, 141 insertions(+), 47 deletions(-) create mode 100644 src/pocketmine/block/PressurePlate.php create mode 100644 src/pocketmine/block/SimplePressurePlate.php create mode 100644 src/pocketmine/block/WeightedPressurePlate.php diff --git a/src/pocketmine/block/PressurePlate.php b/src/pocketmine/block/PressurePlate.php new file mode 100644 index 0000000000..b2914fd3ae --- /dev/null +++ b/src/pocketmine/block/PressurePlate.php @@ -0,0 +1,33 @@ +powered ? 1 : 0; + } + + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->powered = $stateMeta !== 0; + } + + public function getStateBitmask() : int{ + return 0b1; + } +} diff --git a/src/pocketmine/block/StonePressurePlate.php b/src/pocketmine/block/StonePressurePlate.php index 650f63c364..2534010015 100644 --- a/src/pocketmine/block/StonePressurePlate.php +++ b/src/pocketmine/block/StonePressurePlate.php @@ -25,26 +25,7 @@ namespace pocketmine\block; use pocketmine\item\TieredTool; -class StonePressurePlate extends Transparent{ - - /** @var bool */ - protected $powered = false; - - protected function writeStateToMeta() : int{ - return $this->powered ? 1 : 0; - } - - public function readStateFromData(int $id, int $stateMeta) : void{ - $this->powered = $stateMeta !== 0; - } - - public function getStateBitmask() : int{ - return 0b1; - } - - public function isSolid() : bool{ - return false; - } +class StonePressurePlate extends SimplePressurePlate{ public function getHardness() : float{ return 0.5; diff --git a/src/pocketmine/block/WeightedPressurePlate.php b/src/pocketmine/block/WeightedPressurePlate.php new file mode 100644 index 0000000000..fb3c00051b --- /dev/null +++ b/src/pocketmine/block/WeightedPressurePlate.php @@ -0,0 +1,44 @@ +power; + } + + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->power = BlockDataValidator::readBoundedInt("power", $stateMeta, 0, 15); + } + + public function getStateBitmask() : int{ + return 0b1111; + } +} diff --git a/src/pocketmine/block/WeightedPressurePlateHeavy.php b/src/pocketmine/block/WeightedPressurePlateHeavy.php index ba72c90009..cc465d3d19 100644 --- a/src/pocketmine/block/WeightedPressurePlateHeavy.php +++ b/src/pocketmine/block/WeightedPressurePlateHeavy.php @@ -23,5 +23,19 @@ declare(strict_types=1); namespace pocketmine\block; -class WeightedPressurePlateHeavy extends WeightedPressurePlateLight{ +use pocketmine\item\TieredTool; + +class WeightedPressurePlateHeavy extends WeightedPressurePlate{ + + public function getHardness() : float{ + return 0.5; + } + + public function getToolType() : int{ + return BlockToolType::TYPE_PICKAXE; + } + + public function getToolHarvestLevel() : int{ + return TieredTool::TIER_WOODEN; + } } diff --git a/src/pocketmine/block/WeightedPressurePlateLight.php b/src/pocketmine/block/WeightedPressurePlateLight.php index f6d717f5e9..df13188ce9 100644 --- a/src/pocketmine/block/WeightedPressurePlateLight.php +++ b/src/pocketmine/block/WeightedPressurePlateLight.php @@ -23,29 +23,9 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\TieredTool; -class WeightedPressurePlateLight extends Transparent{ - - /** @var int */ - protected $power = 0; - - protected function writeStateToMeta() : int{ - return $this->power; - } - - public function readStateFromData(int $id, int $stateMeta) : void{ - $this->power = BlockDataValidator::readBoundedInt("power", $stateMeta, 0, 15); - } - - public function getStateBitmask() : int{ - return 0b1111; - } - - public function isSolid() : bool{ - return false; - } +class WeightedPressurePlateLight extends WeightedPressurePlate{ public function getHardness() : float{ return 0.5; diff --git a/src/pocketmine/block/WoodenPressurePlate.php b/src/pocketmine/block/WoodenPressurePlate.php index a01bfaafd4..62ccef9500 100644 --- a/src/pocketmine/block/WoodenPressurePlate.php +++ b/src/pocketmine/block/WoodenPressurePlate.php @@ -23,17 +23,17 @@ declare(strict_types=1); namespace pocketmine\block; -class WoodenPressurePlate extends StonePressurePlate{ +class WoodenPressurePlate extends SimplePressurePlate{ public function getFuelTime() : int{ return 300; } + public function getHardness() : float{ + return 0.5; + } + public function getToolType() : int{ return BlockToolType::TYPE_AXE; } - - public function getToolHarvestLevel() : int{ - return 0; //TODO: fix hierarchy problem - } } From f9da0f3ece011729a2f679f9530df377057467ac Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Feb 2019 13:09:05 +0000 Subject: [PATCH 0514/3224] Sapling: remove dead TODO --- src/pocketmine/block/Sapling.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index 1511ba3438..0211ece7bd 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -67,7 +67,6 @@ class Sapling extends Flowable{ public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal - //TODO: change log type Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->treeType); $item->pop(); From fd4a441f3a49ebb21beac51211432234c61cf7f6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Feb 2019 14:51:16 +0000 Subject: [PATCH 0515/3224] Level: add unregisterChunkListenerFromAll() it's not expected for chunk listeners to have to track all the chunks they are listening to under normal circumstances. --- src/pocketmine/level/Level.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 824b037a3c..cb465faef4 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -713,6 +713,23 @@ class Level implements ChunkManager, Metadatable{ } } + /** + * Unregisters a chunk listener from all chunks it is listening on in this Level. + * + * @param ChunkListener $listener + */ + public function unregisterChunkListenerFromAll(ChunkListener $listener) : void{ + $id = spl_object_id($listener); + foreach($this->chunkListeners as $hash => $listeners){ + if(isset($listeners[$id])){ + unset($this->chunkListeners[$hash][$id]); + if(empty($this->chunkListeners[$hash])){ + unset($this->chunkListeners[$hash]); + } + } + } + } + /** * Returns all the listeners attached to this chunk. * From 2bfcd258486ff509f51b4d37cefc2f841cc40e04 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Feb 2019 18:41:04 -0500 Subject: [PATCH 0516/3224] Fixed typo in Repeater name --- src/pocketmine/block/BlockFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 184e2016b4..3448741ae7 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -215,7 +215,7 @@ class BlockFactory{ self::register(new Redstone(new BID(Block::REDSTONE_BLOCK), "Redstone Block")); self::register(new RedstoneLamp(new BlockIdentifierFlattened(Block::REDSTONE_LAMP, Block::LIT_REDSTONE_LAMP), "Redstone Lamp")); self::register(new RedstoneOre(new BlockIdentifierFlattened(Block::REDSTONE_ORE, Block::LIT_REDSTONE_ORE), "Redstone Ore")); - self::register(new RedstoneRepeater(new BlockIdentifierFlattened(Block::UNPOWERED_REPEATER, Block::POWERED_REPEATER, 0, ItemIds::REPEATER), "Redstne Repeater")); + self::register(new RedstoneRepeater(new BlockIdentifierFlattened(Block::UNPOWERED_REPEATER, Block::POWERED_REPEATER, 0, ItemIds::REPEATER), "Redstone Repeater")); self::register(new RedstoneTorch(new BlockIdentifierFlattened(Block::REDSTONE_TORCH, Block::UNLIT_REDSTONE_TORCH), "Redstone Torch")); self::register(new RedstoneWire(new BID(Block::REDSTONE_WIRE, 0, ItemIds::REDSTONE), "Redstone")); self::register(new Reserved6(new BID(Block::RESERVED6), "reserved6")); From 3037f45a0cd6c72d80d2703b29e7e1295893e124 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 22 Feb 2019 11:43:11 +0000 Subject: [PATCH 0517/3224] Implement new dye types, split bonemeal and cocoa beans into their own classes --- src/pocketmine/block/CocoaBlock.php | 3 ++- src/pocketmine/block/Crops.php | 3 ++- src/pocketmine/block/Grass.php | 3 ++- src/pocketmine/block/Sapling.php | 3 ++- src/pocketmine/block/Sugarcane.php | 3 ++- src/pocketmine/item/CocoaBeans.php | 34 +++++++++++++++++++++++++++++ src/pocketmine/item/Dye.php | 12 ---------- src/pocketmine/item/Fertilizer.php | 28 ++++++++++++++++++++++++ src/pocketmine/item/ItemFactory.php | 15 +++++++++++-- 9 files changed, 85 insertions(+), 19 deletions(-) create mode 100644 src/pocketmine/item/CocoaBeans.php create mode 100644 src/pocketmine/item/Fertilizer.php diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index 7cb8058029..fca8c50781 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; use pocketmine\block\utils\TreeType; +use pocketmine\item\Fertilizer; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\AxisAlignedBB; @@ -85,7 +86,7 @@ class CocoaBlock extends Transparent{ } public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($this->age < 2 and $item->getId() === Item::DYE and $item->getDamage() === 15){ //bone meal + if($this->age < 2 and $item instanceof Fertilizer){ $this->age++; $this->level->setBlock($this, $this); diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index f38e970db7..50eb5aad4e 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; use pocketmine\event\block\BlockGrowEvent; +use pocketmine\item\Fertilizer; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -57,7 +58,7 @@ abstract class Crops extends Flowable{ public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($this->age < 7 and $item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal + if($this->age < 7 and $item instanceof Fertilizer){ $block = clone $this; $block->age += mt_rand(2, 5); if($block->age > 7){ diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index 5d32b8bdce..39c4eaa302 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\event\block\BlockSpreadEvent; +use pocketmine\item\Fertilizer; use pocketmine\item\Hoe; use pocketmine\item\Item; use pocketmine\item\ItemFactory; @@ -94,7 +95,7 @@ class Grass extends Solid{ if($face !== Facing::UP){ return false; } - if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ + if($item instanceof Fertilizer){ $item->pop(); TallGrassObject::growGrass($this->getLevel(), $this, new Random(mt_rand()), 8, 2); diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index 0211ece7bd..e6d789be66 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\TreeType; +use pocketmine\item\Fertilizer; use pocketmine\item\Item; use pocketmine\level\generator\object\Tree; use pocketmine\math\Facing; @@ -66,7 +67,7 @@ class Sapling extends Flowable{ } public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal + if($item instanceof Fertilizer){ Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->treeType); $item->pop(); diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index 221e1e5318..2b1bc5862d 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; use pocketmine\event\block\BlockGrowEvent; +use pocketmine\item\Fertilizer; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -48,7 +49,7 @@ class Sugarcane extends Flowable{ } public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal + if($item instanceof Fertilizer){ if($this->getSide(Facing::DOWN)->getId() !== self::SUGARCANE_BLOCK){ for($y = 1; $y < 3; ++$y){ $b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z); diff --git a/src/pocketmine/item/CocoaBeans.php b/src/pocketmine/item/CocoaBeans.php new file mode 100644 index 0000000000..18ad28c5db --- /dev/null +++ b/src/pocketmine/item/CocoaBeans.php @@ -0,0 +1,34 @@ +meta === 3){ //cocoa beans - return BlockFactory::get(Block::COCOA); - } - return parent::getBlock(); - } - - //TODO: names } diff --git a/src/pocketmine/item/Fertilizer.php b/src/pocketmine/item/Fertilizer.php new file mode 100644 index 0000000000..3399147c6b --- /dev/null +++ b/src/pocketmine/item/Fertilizer.php @@ -0,0 +1,28 @@ +getInvertedMagicNumber(), $color->getDisplayName() . " Dye")); + self::register(new Dye($dyeMap[$color] ?? $color->getInvertedMagicNumber(), $color->getDisplayName() . " Dye")); self::register(new Bed($color->getMagicNumber(), $color->getDisplayName() . " Bed")); self::register(new Banner($color->getInvertedMagicNumber(), $color->getDisplayName() . " Banner")); } From 461233db09ad2b0b45b8ef0fee2fe56e40aec8de Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 22 Feb 2019 11:52:22 +0000 Subject: [PATCH 0518/3224] ItemFactory: Sort items lexicographically ascending --- src/pocketmine/item/ItemFactory.php | 359 +++++++++++++--------------- 1 file changed, 168 insertions(+), 191 deletions(-) diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 0e5fe3f783..e1cc072f82 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -53,112 +53,188 @@ class ItemFactory{ public static function init(){ self::$list = []; //in case of re-initializing - self::register(new Shovel(Item::IRON_SHOVEL, "Iron Shovel", TieredTool::TIER_IRON)); - self::register(new Pickaxe(Item::IRON_PICKAXE, "Iron Pickaxe", TieredTool::TIER_IRON)); - self::register(new Axe(Item::IRON_AXE, "Iron Axe", TieredTool::TIER_IRON)); - self::register(new FlintSteel()); self::register(new Apple()); - self::register(new Bow()); self::register(new Arrow()); + self::register(new Axe(Item::DIAMOND_AXE, "Diamond Axe", TieredTool::TIER_DIAMOND)); + self::register(new Axe(Item::GOLDEN_AXE, "Gold Axe", TieredTool::TIER_GOLD)); + self::register(new Axe(Item::IRON_AXE, "Iron Axe", TieredTool::TIER_IRON)); + self::register(new Axe(Item::STONE_AXE, "Stone Axe", TieredTool::TIER_STONE)); + self::register(new Axe(Item::WOODEN_AXE, "Wooden Axe", TieredTool::TIER_WOODEN)); + self::register(new BakedPotato()); + self::register(new Beetroot()); + self::register(new BeetrootSeeds()); + self::register(new BeetrootSoup()); + self::register(new BlazeRod()); + self::register(new Boat()); + self::register(new Book()); + self::register(new Bow()); + self::register(new Bowl()); + self::register(new Bread()); + self::register(new Bucket(Item::BUCKET, 0, "Bucket")); + self::register(new Carrot()); + self::register(new ChainBoots()); + self::register(new ChainChestplate()); + self::register(new ChainHelmet()); + self::register(new ChainLeggings()); + self::register(new ChorusFruit()); + self::register(new Clock()); + self::register(new Clownfish()); self::register(new Coal(Item::COAL, 0, "Coal")); self::register(new Coal(Item::COAL, 1, "Charcoal")); - self::register(new Item(Item::DIAMOND, 0, "Diamond")); - self::register(new Item(Item::IRON_INGOT, 0, "Iron Ingot")); - self::register(new Item(Item::GOLD_INGOT, 0, "Gold Ingot")); - self::register(new Sword(Item::IRON_SWORD, "Iron Sword", TieredTool::TIER_IRON)); - self::register(new Sword(Item::WOODEN_SWORD, "Wooden Sword", TieredTool::TIER_WOODEN)); - self::register(new Shovel(Item::WOODEN_SHOVEL, "Wooden Shovel", TieredTool::TIER_WOODEN)); - self::register(new Pickaxe(Item::WOODEN_PICKAXE, "Wooden Pickaxe", TieredTool::TIER_WOODEN)); - self::register(new Axe(Item::WOODEN_AXE, "Wooden Axe", TieredTool::TIER_WOODEN)); - self::register(new Sword(Item::STONE_SWORD, "Stone Sword", TieredTool::TIER_STONE)); - self::register(new Shovel(Item::STONE_SHOVEL, "Stone Shovel", TieredTool::TIER_STONE)); - self::register(new Pickaxe(Item::STONE_PICKAXE, "Stone Pickaxe", TieredTool::TIER_STONE)); - self::register(new Axe(Item::STONE_AXE, "Stone Axe", TieredTool::TIER_STONE)); - self::register(new Sword(Item::DIAMOND_SWORD, "Diamond Sword", TieredTool::TIER_DIAMOND)); - self::register(new Shovel(Item::DIAMOND_SHOVEL, "Diamond Shovel", TieredTool::TIER_DIAMOND)); - self::register(new Pickaxe(Item::DIAMOND_PICKAXE, "Diamond Pickaxe", TieredTool::TIER_DIAMOND)); - self::register(new Axe(Item::DIAMOND_AXE, "Diamond Axe", TieredTool::TIER_DIAMOND)); - self::register(new Stick()); - self::register(new Bowl()); - self::register(new MushroomStew()); - self::register(new Sword(Item::GOLDEN_SWORD, "Gold Sword", TieredTool::TIER_GOLD)); - self::register(new Shovel(Item::GOLDEN_SHOVEL, "Gold Shovel", TieredTool::TIER_GOLD)); - self::register(new Pickaxe(Item::GOLDEN_PICKAXE, "Gold Pickaxe", TieredTool::TIER_GOLD)); - self::register(new Axe(Item::GOLDEN_AXE, "Gold Axe", TieredTool::TIER_GOLD)); - self::register(new StringItem()); - self::register(new Item(Item::FEATHER, 0, "Feather")); - self::register(new Item(Item::GUNPOWDER, 0, "Gunpowder")); - self::register(new Hoe(Item::WOODEN_HOE, "Wooden Hoe", TieredTool::TIER_WOODEN)); - self::register(new Hoe(Item::STONE_HOE, "Stone Hoe", TieredTool::TIER_STONE)); - self::register(new Hoe(Item::IRON_HOE, "Iron Hoe", TieredTool::TIER_IRON)); + self::register(new CocoaBeans(Item::DYE, 3, "Cocoa Beans")); + self::register(new Compass()); + self::register(new CookedChicken()); + self::register(new CookedFish()); + self::register(new CookedMutton()); + self::register(new CookedPorkchop()); + self::register(new CookedRabbit()); + self::register(new CookedSalmon()); + self::register(new Cookie()); + self::register(new DiamondBoots()); + self::register(new DiamondChestplate()); + self::register(new DiamondHelmet()); + self::register(new DiamondLeggings()); + self::register(new DriedKelp()); + self::register(new Egg()); + self::register(new EnderPearl()); + self::register(new ExperienceBottle()); + self::register(new Fertilizer(Item::DYE, 15, "Bone Meal")); + self::register(new FishingRod()); + self::register(new FlintSteel()); + self::register(new GlassBottle()); + self::register(new GoldBoots()); + self::register(new GoldChestplate()); + self::register(new GoldHelmet()); + self::register(new GoldLeggings()); + self::register(new GoldenApple()); + self::register(new GoldenAppleEnchanted()); + self::register(new GoldenCarrot()); self::register(new Hoe(Item::DIAMOND_HOE, "Diamond Hoe", TieredTool::TIER_DIAMOND)); self::register(new Hoe(Item::GOLDEN_HOE, "Golden Hoe", TieredTool::TIER_GOLD)); - self::register(new WheatSeeds()); - self::register(new Item(Item::WHEAT, 0, "Wheat")); - self::register(new Bread()); - self::register(new LeatherCap()); - self::register(new LeatherTunic()); - self::register(new LeatherPants()); - self::register(new LeatherBoots()); - self::register(new ChainHelmet()); - self::register(new ChainChestplate()); - self::register(new ChainLeggings()); - self::register(new ChainBoots()); - self::register(new IronHelmet()); - self::register(new IronChestplate()); - self::register(new IronLeggings()); + self::register(new Hoe(Item::IRON_HOE, "Iron Hoe", TieredTool::TIER_IRON)); + self::register(new Hoe(Item::STONE_HOE, "Stone Hoe", TieredTool::TIER_STONE)); + self::register(new Hoe(Item::WOODEN_HOE, "Wooden Hoe", TieredTool::TIER_WOODEN)); self::register(new IronBoots()); - self::register(new DiamondHelmet()); - self::register(new DiamondChestplate()); - self::register(new DiamondLeggings()); - self::register(new DiamondBoots()); - self::register(new GoldHelmet()); - self::register(new GoldChestplate()); - self::register(new GoldLeggings()); - self::register(new GoldBoots()); + self::register(new IronChestplate()); + self::register(new IronHelmet()); + self::register(new IronLeggings()); + self::register(new Item(Item::BLAZE_POWDER, 0, "Blaze Powder")); + self::register(new Item(Item::BLEACH, 0, "Bleach")); //EDU + self::register(new Item(Item::BONE, 0, "Bone")); + self::register(new Item(Item::BRICK, 0, "Brick")); + self::register(new Item(Item::CHORUS_FRUIT_POPPED, 0, "Popped Chorus Fruit")); + self::register(new Item(Item::CLAY_BALL, 0, "Clay")); + self::register(new Item(Item::DIAMOND, 0, "Diamond")); + self::register(new Item(Item::DRAGON_BREATH, 0, "Dragon's Breath")); + self::register(new Item(Item::DYE, 0, "Ink Sac")); + self::register(new Item(Item::DYE, 4, "Lapis Lazuli")); + self::register(new Item(Item::EMERALD, 0, "Emerald")); + self::register(new Item(Item::FEATHER, 0, "Feather")); + self::register(new Item(Item::FERMENTED_SPIDER_EYE, 0, "Fermented Spider Eye")); self::register(new Item(Item::FLINT, 0, "Flint")); - self::register(new RawPorkchop()); - self::register(new CookedPorkchop()); - self::register(new PaintingItem()); - self::register(new GoldenApple()); - self::register(new Sign()); + self::register(new Item(Item::GHAST_TEAR, 0, "Ghast Tear")); + self::register(new Item(Item::GLISTERING_MELON, 0, "Glistering Melon")); + self::register(new Item(Item::GLOWSTONE_DUST, 0, "Glowstone Dust")); + self::register(new Item(Item::GOLD_INGOT, 0, "Gold Ingot")); + self::register(new Item(Item::GOLD_NUGGET, 0, "Gold Nugget")); + self::register(new Item(Item::GUNPOWDER, 0, "Gunpowder")); + self::register(new Item(Item::HEART_OF_THE_SEA, 0, "Heart of the Sea")); + self::register(new Item(Item::IRON_INGOT, 0, "Iron Ingot")); + self::register(new Item(Item::IRON_NUGGET, 0, "Iron Nugget")); + self::register(new Item(Item::LEATHER, 0, "Leather")); + self::register(new Item(Item::MAGMA_CREAM, 0, "Magma Cream")); + self::register(new Item(Item::NAUTILUS_SHELL, 0, "Nautilus Shell")); + self::register(new Item(Item::NETHER_BRICK, 0, "Nether Brick")); + self::register(new Item(Item::NETHER_QUARTZ, 0, "Nether Quartz")); + self::register(new Item(Item::NETHER_STAR, 0, "Nether Star")); + self::register(new Item(Item::PAPER, 0, "Paper")); + self::register(new Item(Item::PRISMARINE_CRYSTALS, 0, "Prismarine Crystals")); + self::register(new Item(Item::PRISMARINE_SHARD, 0, "Prismarine Shard")); + self::register(new Item(Item::RABBIT_FOOT, 0, "Rabbit's Foot")); + self::register(new Item(Item::RABBIT_HIDE, 0, "Rabbit Hide")); + self::register(new Item(Item::SHULKER_SHELL, 0, "Shulker Shell")); + self::register(new Item(Item::SLIME_BALL, 0, "Slimeball")); + self::register(new Item(Item::SUGAR, 0, "Sugar")); + self::register(new Item(Item::TURTLE_SHELL_PIECE, 0, "Scute")); + self::register(new Item(Item::WHEAT, 0, "Wheat")); + self::register(new ItemBlock(Block::ACACIA_DOOR_BLOCK, 0, Item::ACACIA_DOOR)); + self::register(new ItemBlock(Block::BIRCH_DOOR_BLOCK, 0, Item::BIRCH_DOOR)); + self::register(new ItemBlock(Block::BREWING_STAND_BLOCK, 0, Item::BREWING_STAND)); + self::register(new ItemBlock(Block::CAKE_BLOCK, 0, Item::CAKE)); + self::register(new ItemBlock(Block::CAULDRON_BLOCK, 0, Item::CAULDRON)); + self::register(new ItemBlock(Block::COMPARATOR_BLOCK, 0, Item::COMPARATOR)); + self::register(new ItemBlock(Block::DARK_OAK_DOOR_BLOCK, 0, Item::DARK_OAK_DOOR)); + self::register(new ItemBlock(Block::FLOWER_POT_BLOCK, 0, Item::FLOWER_POT)); + self::register(new ItemBlock(Block::HOPPER_BLOCK, 0, Item::HOPPER)); + self::register(new ItemBlock(Block::IRON_DOOR_BLOCK, 0, Item::IRON_DOOR)); + self::register(new ItemBlock(Block::ITEM_FRAME_BLOCK, 0, Item::ITEM_FRAME)); + self::register(new ItemBlock(Block::JUNGLE_DOOR_BLOCK, 0, Item::JUNGLE_DOOR)); + self::register(new ItemBlock(Block::NETHER_WART_PLANT, 0, Item::NETHER_WART)); self::register(new ItemBlock(Block::OAK_DOOR_BLOCK, 0, Item::OAK_DOOR)); - + self::register(new ItemBlock(Block::REPEATER_BLOCK, 0, Item::REPEATER)); + self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_CREEPER, Item::SKULL)); + self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_DRAGON, Item::SKULL)); + self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_HUMAN, Item::SKULL)); + self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_SKELETON, Item::SKULL)); + self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_WITHER, Item::SKULL)); + self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_ZOMBIE, Item::SKULL)); + self::register(new ItemBlock(Block::SPRUCE_DOOR_BLOCK, 0, Item::SPRUCE_DOOR)); + self::register(new ItemBlock(Block::SUGARCANE_BLOCK, 0, Item::SUGARCANE)); + self::register(new LeatherBoots()); + self::register(new LeatherCap()); + self::register(new LeatherPants()); + self::register(new LeatherTunic()); //TODO: fix metadata for buckets with still liquid in them //the meta values are intentionally hardcoded because block IDs will change in the future - self::register(new Bucket(Item::BUCKET, 0, "Bucket")); - self::register(new MilkBucket(Item::BUCKET, 1, "Milk Bucket")); - self::register(new LiquidBucket(Item::BUCKET, 8, "Water Bucket", Block::FLOWING_WATER)); self::register(new LiquidBucket(Item::BUCKET, 10, "Lava Bucket", Block::FLOWING_LAVA)); - + self::register(new LiquidBucket(Item::BUCKET, 8, "Water Bucket", Block::FLOWING_WATER)); + self::register(new Melon()); + self::register(new MelonSeeds()); + self::register(new MilkBucket(Item::BUCKET, 1, "Milk Bucket")); self::register(new Minecart()); - - self::register(new ItemBlock(Block::IRON_DOOR_BLOCK, 0, Item::IRON_DOOR)); - self::register(new Redstone()); - self::register(new Snowball()); - - self::register(new Boat()); - self::register(new Item(Item::LEATHER, 0, "Leather")); - - self::register(new Item(Item::BRICK, 0, "Brick")); - self::register(new Item(Item::CLAY_BALL, 0, "Clay")); - self::register(new ItemBlock(Block::SUGARCANE_BLOCK, 0, Item::SUGARCANE)); - self::register(new Item(Item::PAPER, 0, "Paper")); - self::register(new Book()); - self::register(new Item(Item::SLIME_BALL, 0, "Slimeball")); - - self::register(new Egg()); - self::register(new Compass()); - self::register(new FishingRod()); - self::register(new Clock()); - self::register(new Item(Item::GLOWSTONE_DUST, 0, "Glowstone Dust")); + self::register(new MushroomStew()); + self::register(new PaintingItem()); + self::register(new Pickaxe(Item::DIAMOND_PICKAXE, "Diamond Pickaxe", TieredTool::TIER_DIAMOND)); + self::register(new Pickaxe(Item::GOLDEN_PICKAXE, "Gold Pickaxe", TieredTool::TIER_GOLD)); + self::register(new Pickaxe(Item::IRON_PICKAXE, "Iron Pickaxe", TieredTool::TIER_IRON)); + self::register(new Pickaxe(Item::STONE_PICKAXE, "Stone Pickaxe", TieredTool::TIER_STONE)); + self::register(new Pickaxe(Item::WOODEN_PICKAXE, "Wooden Pickaxe", TieredTool::TIER_WOODEN)); + self::register(new PoisonousPotato()); + self::register(new Potato()); + self::register(new Pufferfish()); + self::register(new PumpkinPie()); + self::register(new PumpkinSeeds()); + self::register(new RabbitStew()); + self::register(new RawBeef()); + self::register(new RawChicken()); self::register(new RawFish()); - self::register(new CookedFish()); - - self::register(new Item(Item::DYE, 0, "Ink Sac")); - self::register(new CocoaBeans(Item::DYE, 3, "Cocoa Beans")); - self::register(new Item(Item::DYE, 4, "Lapis Lazuli")); - self::register(new Fertilizer(Item::DYE, 15, "Bone Meal")); + self::register(new RawMutton()); + self::register(new RawPorkchop()); + self::register(new RawRabbit()); + self::register(new RawSalmon()); + self::register(new Redstone()); + self::register(new RottenFlesh()); + self::register(new Shears()); + self::register(new Shovel(Item::DIAMOND_SHOVEL, "Diamond Shovel", TieredTool::TIER_DIAMOND)); + self::register(new Shovel(Item::GOLDEN_SHOVEL, "Gold Shovel", TieredTool::TIER_GOLD)); + self::register(new Shovel(Item::IRON_SHOVEL, "Iron Shovel", TieredTool::TIER_IRON)); + self::register(new Shovel(Item::STONE_SHOVEL, "Stone Shovel", TieredTool::TIER_STONE)); + self::register(new Shovel(Item::WOODEN_SHOVEL, "Wooden Shovel", TieredTool::TIER_WOODEN)); + self::register(new Sign()); + self::register(new Snowball()); + self::register(new SpiderEye()); + self::register(new Steak()); + self::register(new Stick()); + self::register(new StringItem()); + self::register(new Sword(Item::DIAMOND_SWORD, "Diamond Sword", TieredTool::TIER_DIAMOND)); + self::register(new Sword(Item::GOLDEN_SWORD, "Gold Sword", TieredTool::TIER_GOLD)); + self::register(new Sword(Item::IRON_SWORD, "Iron Sword", TieredTool::TIER_IRON)); + self::register(new Sword(Item::STONE_SWORD, "Stone Sword", TieredTool::TIER_STONE)); + self::register(new Sword(Item::WOODEN_SWORD, "Wooden Sword", TieredTool::TIER_WOODEN)); + self::register(new Totem()); + self::register(new WheatSeeds()); + self::register(new WritableBook()); + self::register(new WrittenBook()); /** @var int[]|\SplObjectStorage $dyeMap */ $dyeMap = new \SplObjectStorage(); @@ -173,41 +249,11 @@ class ItemFactory{ self::register(new Bed($color->getMagicNumber(), $color->getDisplayName() . " Bed")); self::register(new Banner($color->getInvertedMagicNumber(), $color->getDisplayName() . " Banner")); } - self::register(new Item(Item::BONE, 0, "Bone")); - self::register(new Item(Item::SUGAR, 0, "Sugar")); - self::register(new ItemBlock(Block::CAKE_BLOCK, 0, Item::CAKE)); - - self::register(new ItemBlock(Block::REPEATER_BLOCK, 0, Item::REPEATER)); - self::register(new Cookie()); - - self::register(new Shears()); - self::register(new Melon()); - self::register(new PumpkinSeeds()); - self::register(new MelonSeeds()); - self::register(new RawBeef()); - self::register(new Steak()); - self::register(new RawChicken()); - self::register(new CookedChicken()); - self::register(new RottenFlesh()); - self::register(new EnderPearl()); - self::register(new BlazeRod()); - self::register(new Item(Item::GHAST_TEAR, 0, "Ghast Tear")); - self::register(new Item(Item::GOLD_NUGGET, 0, "Gold Nugget")); - self::register(new ItemBlock(Block::NETHER_WART_PLANT, 0, Item::NETHER_WART)); foreach(Potion::ALL as $type){ self::register(new Potion($type)); self::register(new SplashPotion($type)); } - self::register(new GlassBottle()); - self::register(new SpiderEye()); - self::register(new Item(Item::FERMENTED_SPIDER_EYE, 0, "Fermented Spider Eye")); - self::register(new Item(Item::BLAZE_POWDER, 0, "Blaze Powder")); - self::register(new Item(Item::MAGMA_CREAM, 0, "Magma Cream")); - self::register(new ItemBlock(Block::BREWING_STAND_BLOCK, 0, Item::BREWING_STAND)); - self::register(new ItemBlock(Block::CAULDRON_BLOCK, 0, Item::CAULDRON)); - - self::register(new Item(Item::GLISTERING_MELON, 0, "Glistering Melon")); foreach(EntityFactory::getKnownTypes() as $className){ /** @var Living|string $className */ @@ -216,75 +262,6 @@ class ItemFactory{ } } - self::register(new ExperienceBottle()); - - self::register(new WritableBook()); - self::register(new WrittenBook()); - self::register(new Item(Item::EMERALD, 0, "Emerald")); - self::register(new ItemBlock(Block::ITEM_FRAME_BLOCK, 0, Item::ITEM_FRAME)); - self::register(new ItemBlock(Block::FLOWER_POT_BLOCK, 0, Item::FLOWER_POT)); - self::register(new Carrot()); - self::register(new Potato()); - self::register(new BakedPotato()); - self::register(new PoisonousPotato()); - - self::register(new GoldenCarrot()); - - self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_SKELETON, Item::SKULL)); - self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_WITHER, Item::SKULL)); - self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_ZOMBIE, Item::SKULL)); - self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_HUMAN, Item::SKULL)); - self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_CREEPER, Item::SKULL)); - self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_DRAGON, Item::SKULL)); - - self::register(new Item(Item::NETHER_STAR, 0, "Nether Star")); - self::register(new PumpkinPie()); - - self::register(new ItemBlock(Block::COMPARATOR_BLOCK, 0, Item::COMPARATOR)); - self::register(new Item(Item::NETHER_BRICK, 0, "Nether Brick")); - self::register(new Item(Item::NETHER_QUARTZ, 0, "Nether Quartz")); - - self::register(new Item(Item::PRISMARINE_SHARD, 0, "Prismarine Shard")); - self::register(new ItemBlock(Block::HOPPER_BLOCK, 0, Item::HOPPER)); - self::register(new RawRabbit()); - self::register(new CookedRabbit()); - self::register(new RabbitStew()); - self::register(new Item(Item::RABBIT_FOOT, 0, "Rabbit's Foot")); - self::register(new Item(Item::RABBIT_HIDE, 0, "Rabbit Hide")); - - self::register(new Item(Item::PRISMARINE_CRYSTALS, 0, "Prismarine Crystals")); - self::register(new RawMutton()); - self::register(new CookedMutton()); - - self::register(new ItemBlock(Block::SPRUCE_DOOR_BLOCK, 0, Item::SPRUCE_DOOR)); - self::register(new ItemBlock(Block::BIRCH_DOOR_BLOCK, 0, Item::BIRCH_DOOR)); - self::register(new ItemBlock(Block::JUNGLE_DOOR_BLOCK, 0, Item::JUNGLE_DOOR)); - self::register(new ItemBlock(Block::ACACIA_DOOR_BLOCK, 0, Item::ACACIA_DOOR)); - self::register(new ItemBlock(Block::DARK_OAK_DOOR_BLOCK, 0, Item::DARK_OAK_DOOR)); - self::register(new ChorusFruit()); - self::register(new Item(Item::CHORUS_FRUIT_POPPED, 0, "Popped Chorus Fruit")); - - self::register(new Item(Item::DRAGON_BREATH, 0, "Dragon's Breath")); - - self::register(new Item(Item::SHULKER_SHELL, 0, "Shulker Shell")); - - self::register(new Totem()); - self::register(new Item(Item::BLEACH, 0, "Bleach")); //EDU - self::register(new Item(Item::IRON_NUGGET, 0, "Iron Nugget")); - - self::register(new Beetroot()); - self::register(new BeetrootSeeds()); - self::register(new BeetrootSoup()); - self::register(new RawSalmon()); - self::register(new Clownfish()); - self::register(new Pufferfish()); - self::register(new CookedSalmon()); - self::register(new DriedKelp()); - self::register(new Item(Item::NAUTILUS_SHELL, 0, "Nautilus Shell")); - self::register(new GoldenAppleEnchanted()); - self::register(new Item(Item::HEART_OF_THE_SEA, 0, "Heart of the Sea")); - self::register(new Item(Item::TURTLE_SHELL_PIECE, 0, "Scute")); - //TODO: minecraft:acacia_sign //TODO: minecraft:armor_stand //TODO: minecraft:balloon From a5c260352de5ae8ba3b4e6587966efdb40fc5da3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 22 Feb 2019 12:16:45 +0000 Subject: [PATCH 0519/3224] Infect remaining places with PHP 7.1 nullable typehints --- src/pocketmine/block/Anvil.php | 2 +- src/pocketmine/block/BaseRail.php | 2 +- src/pocketmine/block/Bed.php | 2 +- src/pocketmine/block/Block.php | 6 +++--- src/pocketmine/block/BlockFactory.php | 2 +- src/pocketmine/block/Button.php | 2 +- src/pocketmine/block/Cactus.php | 2 +- src/pocketmine/block/Cake.php | 2 +- src/pocketmine/block/Carpet.php | 2 +- src/pocketmine/block/Chest.php | 2 +- src/pocketmine/block/CocoaBlock.php | 2 +- src/pocketmine/block/Crops.php | 2 +- src/pocketmine/block/Dandelion.php | 2 +- src/pocketmine/block/DeadBush.php | 2 +- src/pocketmine/block/Door.php | 2 +- src/pocketmine/block/DoublePlant.php | 2 +- src/pocketmine/block/EndPortalFrame.php | 2 +- src/pocketmine/block/EndRod.php | 2 +- src/pocketmine/block/FenceGate.php | 2 +- src/pocketmine/block/Flower.php | 2 +- src/pocketmine/block/FlowerPot.php | 2 +- src/pocketmine/block/Furnace.php | 2 +- src/pocketmine/block/GlazedTerracotta.php | 2 +- src/pocketmine/block/Ice.php | 2 +- src/pocketmine/block/ItemFrame.php | 2 +- src/pocketmine/block/Ladder.php | 2 +- src/pocketmine/block/Leaves.php | 2 +- src/pocketmine/block/Lever.php | 2 +- src/pocketmine/block/NetherWartPlant.php | 2 +- src/pocketmine/block/Pumpkin.php | 2 +- src/pocketmine/block/RedMushroom.php | 2 +- src/pocketmine/block/RedstoneOre.php | 2 +- src/pocketmine/block/RedstoneRepeater.php | 2 +- src/pocketmine/block/Sapling.php | 2 +- src/pocketmine/block/SignPost.php | 2 +- src/pocketmine/block/Skull.php | 2 +- src/pocketmine/block/Slab.php | 2 +- src/pocketmine/block/SnowLayer.php | 2 +- src/pocketmine/block/Stair.php | 2 +- src/pocketmine/block/StandingBanner.php | 2 +- src/pocketmine/block/Sugarcane.php | 2 +- src/pocketmine/block/TallGrass.php | 2 +- src/pocketmine/block/Torch.php | 2 +- src/pocketmine/block/Trapdoor.php | 2 +- src/pocketmine/block/TripwireHook.php | 2 +- src/pocketmine/block/Vine.php | 2 +- src/pocketmine/block/WaterLily.php | 2 +- src/pocketmine/block/utils/PillarRotationTrait.php | 2 +- 48 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index f5a017a245..23ad43911e 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -85,7 +85,7 @@ class Anvil extends Transparent implements Fallable{ return true; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = Facing::rotateY($player->getHorizontalFacing(), true); } diff --git a/src/pocketmine/block/BaseRail.php b/src/pocketmine/block/BaseRail.php index ba9913d454..3dfb543ed9 100644 --- a/src/pocketmine/block/BaseRail.php +++ b/src/pocketmine/block/BaseRail.php @@ -103,7 +103,7 @@ abstract class BaseRail extends Flowable{ return 0.7; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$blockReplace->getSide(Facing::DOWN)->isTransparent()){ $this->tryReconnect(); return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 25fe965826..ef02373d95 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -174,7 +174,7 @@ class Bed extends Transparent{ } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->color = DyeColor::fromMagicNumber($item->getDamage()); //TODO: replace this with a proper colour getter $down = $this->getSide(Facing::DOWN); if(!$down->isTransparent()){ diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 875ca491ff..249502fced 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -61,7 +61,7 @@ class Block extends Position implements BlockIds, Metadatable{ * * @return Block */ - public static function get(int $id, int $meta = 0, Position $pos = null) : Block{ + public static function get(int $id, int $meta = 0, ?Position $pos = null) : Block{ return BlockFactory::get($id, $meta, $pos); } @@ -233,7 +233,7 @@ class Block extends Position implements BlockIds, Metadatable{ * * @return bool */ - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ return $this->getLevel()->setBlock($blockReplace, $this); } @@ -301,7 +301,7 @@ class Block extends Position implements BlockIds, Metadatable{ * * @return bool */ - public function onBreak(Item $item, Player $player = null) : bool{ + public function onBreak(Item $item, ?Player $player = null) : bool{ if(($t = $this->level->getTile($this)) !== null){ $t->onBlockDestroyed(); } diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 3448741ae7..6731ac0734 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -590,7 +590,7 @@ class BlockFactory{ * * @return Block */ - public static function get(int $id, int $meta = 0, Position $pos = null) : Block{ + public static function get(int $id, int $meta = 0, ?Position $pos = null) : Block{ if($meta < 0 or $meta > 0xf){ throw new \InvalidArgumentException("Block meta value $meta is out of bounds"); } diff --git a/src/pocketmine/block/Button.php b/src/pocketmine/block/Button.php index cc5086e87f..1ff2484147 100644 --- a/src/pocketmine/block/Button.php +++ b/src/pocketmine/block/Button.php @@ -51,7 +51,7 @@ abstract class Button extends Flowable{ return 0b1111; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ //TODO: check valid target block $this->facing = $face; return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index ec8b514005..dcf9655200 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -113,7 +113,7 @@ class Cactus extends Transparent{ } } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === self::SAND or $down->getId() === self::CACTUS){ foreach(Facing::HORIZONTAL as $side){ diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index d180732435..335f0f6447 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -61,7 +61,7 @@ class Cake extends Transparent implements FoodSource{ ->trim(Facing::WEST, $this->bites / 8); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() !== self::AIR){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/Carpet.php b/src/pocketmine/block/Carpet.php index bc8efe52c0..bf2974af89 100644 --- a/src/pocketmine/block/Carpet.php +++ b/src/pocketmine/block/Carpet.php @@ -43,7 +43,7 @@ class Carpet extends Flowable{ return AxisAlignedBB::one()->trim(Facing::UP, 15 / 16); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() !== self::AIR){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index 14e27f7c57..757e67c3dc 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -61,7 +61,7 @@ class Chest extends Transparent{ return AxisAlignedBB::one()->contract(0.025, 0, 0.025)->trim(Facing::UP, 0.05); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index fca8c50781..0046d27aab 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -76,7 +76,7 @@ class CocoaBlock extends Transparent{ ->trim($this->facing, (11 - $this->age * 2) / 16); //outward face } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(Facing::axis($face) !== Facing::AXIS_Y and $blockClicked instanceof Wood and $blockClicked->getTreeType() === TreeType::JUNGLE()){ $this->facing = $face; return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index 50eb5aad4e..2586d9109e 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -48,7 +48,7 @@ abstract class Crops extends Flowable{ return 0b111; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($blockReplace->getSide(Facing::DOWN)->getId() === Block::FARMLAND){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/pocketmine/block/Dandelion.php b/src/pocketmine/block/Dandelion.php index dba08c717e..410d98073e 100644 --- a/src/pocketmine/block/Dandelion.php +++ b/src/pocketmine/block/Dandelion.php @@ -31,7 +31,7 @@ use pocketmine\Player; class Dandelion extends Flowable{ - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === Block::GRASS or $down->getId() === Block::DIRT or $down->getId() === Block::FARMLAND){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/DeadBush.php b/src/pocketmine/block/DeadBush.php index b1167f6390..0ca036fcd9 100644 --- a/src/pocketmine/block/DeadBush.php +++ b/src/pocketmine/block/DeadBush.php @@ -32,7 +32,7 @@ use function mt_rand; class DeadBush extends Flowable{ - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$this->getSide(Facing::DOWN)->isTransparent()){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 15ad3518a1..39e56e5f8c 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -103,7 +103,7 @@ abstract class Door extends Transparent{ } } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP){ $blockUp = $this->getSide(Facing::UP); $blockDown = $this->getSide(Facing::DOWN); diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index 30ecab2758..a9dd48ee0f 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -47,7 +47,7 @@ class DoublePlant extends Flowable{ return 0b1000; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $id = $blockReplace->getSide(Facing::DOWN)->getId(); if(($id === Block::GRASS or $id === Block::DIRT) and $blockReplace->getSide(Facing::UP)->canBeReplaced()){ $top = clone $this; diff --git a/src/pocketmine/block/EndPortalFrame.php b/src/pocketmine/block/EndPortalFrame.php index 8f59f1ff3d..aebdc7b477 100644 --- a/src/pocketmine/block/EndPortalFrame.php +++ b/src/pocketmine/block/EndPortalFrame.php @@ -71,7 +71,7 @@ class EndPortalFrame extends Solid{ return AxisAlignedBB::one()->trim(Facing::UP, 3 / 16); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } diff --git a/src/pocketmine/block/EndRod.php b/src/pocketmine/block/EndRod.php index f831337058..1290815382 100644 --- a/src/pocketmine/block/EndRod.php +++ b/src/pocketmine/block/EndRod.php @@ -54,7 +54,7 @@ class EndRod extends Flowable{ return 0b111; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->facing = $face; if($blockClicked instanceof EndRod and $blockClicked->facing === $this->facing){ $this->facing = Facing::opposite($face); diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index a146b72519..b26152064e 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -78,7 +78,7 @@ class FenceGate extends Transparent{ ); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = $player->getHorizontalFacing(); } diff --git a/src/pocketmine/block/Flower.php b/src/pocketmine/block/Flower.php index 8ab6d0b936..a8465af397 100644 --- a/src/pocketmine/block/Flower.php +++ b/src/pocketmine/block/Flower.php @@ -41,7 +41,7 @@ class Flower extends Flowable{ public const TYPE_CORNFLOWER = 9; public const TYPE_LILY_OF_THE_VALLEY = 10; - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === Block::GRASS or $down->getId() === Block::DIRT or $down->getId() === Block::FARMLAND){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index a8af03df7d..057827e65c 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -51,7 +51,7 @@ class FlowerPot extends Flowable{ return AxisAlignedBB::one()->contract(3 / 16, 0, 3 / 16)->trim(Facing::UP, 5 / 8); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($this->getSide(Facing::DOWN)->isTransparent()){ return false; } diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index 780771eaed..a407aa75d4 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -87,7 +87,7 @@ class Furnace extends Solid{ return $this; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } diff --git a/src/pocketmine/block/GlazedTerracotta.php b/src/pocketmine/block/GlazedTerracotta.php index 83244b5567..a3f4957ba9 100644 --- a/src/pocketmine/block/GlazedTerracotta.php +++ b/src/pocketmine/block/GlazedTerracotta.php @@ -60,7 +60,7 @@ class GlazedTerracotta extends Solid{ return TieredTool::TIER_WOODEN; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } diff --git a/src/pocketmine/block/Ice.php b/src/pocketmine/block/Ice.php index ccd3e72d83..2bbacded16 100644 --- a/src/pocketmine/block/Ice.php +++ b/src/pocketmine/block/Ice.php @@ -45,7 +45,7 @@ class Ice extends Transparent{ return BlockToolType::TYPE_PICKAXE; } - public function onBreak(Item $item, Player $player = null) : bool{ + public function onBreak(Item $item, ?Player $player = null) : bool{ if(($player === null or $player->isSurvival()) and !$item->hasEnchantment(Enchantment::SILK_TOUCH())){ return $this->getLevel()->setBlock($this, BlockFactory::get(Block::WATER)); } diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 1f65296f1d..1c862fb0b7 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -70,7 +70,7 @@ class ItemFrame extends Flowable{ } } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::DOWN or $face === Facing::UP or !$blockClicked->isSolid()){ return false; } diff --git a/src/pocketmine/block/Ladder.php b/src/pocketmine/block/Ladder.php index c7af4a453f..e5589279e9 100644 --- a/src/pocketmine/block/Ladder.php +++ b/src/pocketmine/block/Ladder.php @@ -74,7 +74,7 @@ class Ladder extends Transparent{ } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$blockClicked->isTransparent() and Facing::axis($face) !== Facing::AXIS_Y){ $this->facing = $face; return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index a61bacce74..563f378e3b 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -120,7 +120,7 @@ class Leaves extends Transparent{ } } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->noDecay = true; //artificial leaves don't decay return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index ce88e9bed5..458fb89329 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -77,7 +77,7 @@ class Lever extends Flowable{ return 0.5; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$blockClicked->isSolid()){ return false; } diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index 60775f8820..fb2f9cb5ed 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -49,7 +49,7 @@ class NetherWartPlant extends Flowable{ return 0b11; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === Block::SOUL_SAND){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/Pumpkin.php b/src/pocketmine/block/Pumpkin.php index d0abc3653d..0f760987fd 100644 --- a/src/pocketmine/block/Pumpkin.php +++ b/src/pocketmine/block/Pumpkin.php @@ -55,7 +55,7 @@ class Pumpkin extends Solid{ return BlockToolType::TYPE_AXE; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } diff --git a/src/pocketmine/block/RedMushroom.php b/src/pocketmine/block/RedMushroom.php index 8f23f1c488..35f832da6e 100644 --- a/src/pocketmine/block/RedMushroom.php +++ b/src/pocketmine/block/RedMushroom.php @@ -40,7 +40,7 @@ class RedMushroom extends Flowable{ } } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if(!$down->isTransparent()){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/RedstoneOre.php b/src/pocketmine/block/RedstoneOre.php index c5f13c09f6..3ab072028f 100644 --- a/src/pocketmine/block/RedstoneOre.php +++ b/src/pocketmine/block/RedstoneOre.php @@ -71,7 +71,7 @@ class RedstoneOre extends Solid{ return $this->lit ? 9 : 0; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ return $this->getLevel()->setBlock($this, $this, false); } diff --git a/src/pocketmine/block/RedstoneRepeater.php b/src/pocketmine/block/RedstoneRepeater.php index 160703cdcd..ab16eead22 100644 --- a/src/pocketmine/block/RedstoneRepeater.php +++ b/src/pocketmine/block/RedstoneRepeater.php @@ -82,7 +82,7 @@ class RedstoneRepeater extends Flowable{ return $this; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$blockReplace->getSide(Facing::DOWN)->isTransparent()){ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index e6d789be66..0b725ffab8 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -57,7 +57,7 @@ class Sapling extends Flowable{ return 0b1000; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === self::GRASS or $down->getId() === self::DIRT or $down->getId() === self::FARMLAND){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/SignPost.php b/src/pocketmine/block/SignPost.php index e8a196865b..1470fea51a 100644 --- a/src/pocketmine/block/SignPost.php +++ b/src/pocketmine/block/SignPost.php @@ -59,7 +59,7 @@ class SignPost extends Transparent{ return null; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face !== Facing::DOWN){ if($face === Facing::UP){ diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index 37d88cdd56..78df03dc68 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -82,7 +82,7 @@ class Skull extends Flowable{ return AxisAlignedBB::one()->contract(0.25, 0, 0.25)->trim(Facing::UP, 0.5); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::DOWN){ return false; } diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index e1de5a78eb..75e3b6c7e8 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -104,7 +104,7 @@ abstract class Slab extends Transparent{ return false; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ /* note these conditions can't be merged, since one targets clicked and the other replace */ if($blockClicked instanceof Slab and $blockClicked->slabType !== SlabType::DOUBLE() and $blockClicked->isSameType($this) and ( diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index 617ef79c72..e80b18cf82 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -75,7 +75,7 @@ class SnowLayer extends Flowable implements Fallable{ return AxisAlignedBB::one()->trim(Facing::UP, $this->layers >= 4 ? 0.5 : 1); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($blockReplace instanceof SnowLayer){ if($blockReplace->layers >= 8){ return false; diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index 2af550a0f5..a66ef1d11d 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -106,7 +106,7 @@ abstract class Stair extends Transparent{ ) ? $side->facing : null; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = $player->getHorizontalFacing(); } diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index aa2bf17351..e20490fbb8 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -62,7 +62,7 @@ class StandingBanner extends Transparent{ return null; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face !== Facing::DOWN){ if($face === Facing::UP and $player !== null){ $this->rotation = ((int) floor((($player->yaw + 180) * 16 / 360) + 0.5)) & 0x0f; diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index 2b1bc5862d..6a02812130 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -106,7 +106,7 @@ class Sugarcane extends Flowable{ } } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === self::SUGARCANE_BLOCK){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/TallGrass.php b/src/pocketmine/block/TallGrass.php index 43e8f685d1..688a4a47ea 100644 --- a/src/pocketmine/block/TallGrass.php +++ b/src/pocketmine/block/TallGrass.php @@ -36,7 +36,7 @@ class TallGrass extends Flowable{ return true; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN)->getId(); if($down === self::GRASS or $down === self::DIRT){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index 46a2036c58..7e076f7c57 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -59,7 +59,7 @@ class Torch extends Flowable{ } } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($blockClicked->canBeReplaced() and !$blockClicked->getSide(Facing::DOWN)->isTransparent()){ $this->facing = Facing::UP; return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index b2c6ddb4fe..1cc736894d 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -66,7 +66,7 @@ class Trapdoor extends Transparent{ return AxisAlignedBB::one()->trim($this->open ? $this->facing : ($this->top ? Facing::DOWN : Facing::UP), 13 / 16); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } diff --git a/src/pocketmine/block/TripwireHook.php b/src/pocketmine/block/TripwireHook.php index d35b15bc18..b91887f36b 100644 --- a/src/pocketmine/block/TripwireHook.php +++ b/src/pocketmine/block/TripwireHook.php @@ -53,7 +53,7 @@ class TripwireHook extends Flowable{ return 0b1111; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(Facing::axis($face) !== Facing::AXIS_Y){ //TODO: check face is valid $this->facing = $face; diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index a4b6716526..27b59636a9 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -143,7 +143,7 @@ class Vine extends Flowable{ return []; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$blockClicked->isSolid() or Facing::axis($face) === Facing::AXIS_Y){ return false; } diff --git a/src/pocketmine/block/WaterLily.php b/src/pocketmine/block/WaterLily.php index 390891225d..9719427b28 100644 --- a/src/pocketmine/block/WaterLily.php +++ b/src/pocketmine/block/WaterLily.php @@ -39,7 +39,7 @@ class WaterLily extends Flowable{ return AxisAlignedBB::one()->contract(1 / 16, 0, 1 / 16)->trim(Facing::UP, 63 / 64); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($blockClicked instanceof Water){ $up = $blockClicked->getSide(Facing::UP); if($up->canBeReplaced()){ diff --git a/src/pocketmine/block/utils/PillarRotationTrait.php b/src/pocketmine/block/utils/PillarRotationTrait.php index 8b4aa32cbb..7113ae764e 100644 --- a/src/pocketmine/block/utils/PillarRotationTrait.php +++ b/src/pocketmine/block/utils/PillarRotationTrait.php @@ -94,7 +94,7 @@ trait PillarRotationTrait{ * * @return bool */ - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->axis = Facing::axis($face); /** @see Block::place() */ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); From 73a565355b77dff7f960a4aac743628bce8cfe47 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 22 Feb 2019 12:53:07 +0000 Subject: [PATCH 0520/3224] Make some forced-optional nullable parameters non-optional, PHP 7.1 style these parameters did not make any sense to be optional, but were forced to be this way because of the way nullable types worked before 7.1. --- src/pocketmine/Player.php | 2 +- src/pocketmine/command/Command.php | 2 +- src/pocketmine/command/CommandSender.php | 2 +- src/pocketmine/command/ConsoleCommandSender.php | 2 +- src/pocketmine/level/ChunkManager.php | 2 +- src/pocketmine/level/Level.php | 2 +- src/pocketmine/level/Position.php | 2 +- src/pocketmine/level/SimpleChunkManager.php | 2 +- src/pocketmine/level/format/Chunk.php | 2 +- src/pocketmine/permission/BanEntry.php | 2 +- src/pocketmine/permission/PermissionAttachmentInfo.php | 2 +- src/pocketmine/scheduler/Task.php | 2 +- src/pocketmine/tile/ItemFrame.php | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 05ae682a4a..4432a58a2d 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -477,7 +477,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->lineHeight ?? 7; } - public function setScreenLineHeight(int $height = null){ + public function setScreenLineHeight(?int $height){ if($height !== null and $height < 1){ throw new \InvalidArgumentException("Line height must be at least 1"); } diff --git a/src/pocketmine/command/Command.php b/src/pocketmine/command/Command.php index 2f47e20293..0cea12cd9b 100644 --- a/src/pocketmine/command/Command.php +++ b/src/pocketmine/command/Command.php @@ -115,7 +115,7 @@ abstract class Command{ /** * @param string|null $permission */ - public function setPermission(string $permission = null){ + public function setPermission(?string $permission){ $this->permission = $permission; } diff --git a/src/pocketmine/command/CommandSender.php b/src/pocketmine/command/CommandSender.php index 97fed1b297..027a1a5cfc 100644 --- a/src/pocketmine/command/CommandSender.php +++ b/src/pocketmine/command/CommandSender.php @@ -57,5 +57,5 @@ interface CommandSender extends Permissible{ * * @param int|null $height */ - public function setScreenLineHeight(int $height = null); + public function setScreenLineHeight(?int $height); } diff --git a/src/pocketmine/command/ConsoleCommandSender.php b/src/pocketmine/command/ConsoleCommandSender.php index 32c422a9c5..119c55fef2 100644 --- a/src/pocketmine/command/ConsoleCommandSender.php +++ b/src/pocketmine/command/ConsoleCommandSender.php @@ -142,7 +142,7 @@ class ConsoleCommandSender implements CommandSender{ return $this->lineHeight ?? PHP_INT_MAX; } - public function setScreenLineHeight(int $height = null){ + public function setScreenLineHeight(?int $height){ if($height !== null and $height < 1){ throw new \InvalidArgumentException("Line height must be at least 1"); } diff --git a/src/pocketmine/level/ChunkManager.php b/src/pocketmine/level/ChunkManager.php index 2e669253b4..b53996cbc3 100644 --- a/src/pocketmine/level/ChunkManager.php +++ b/src/pocketmine/level/ChunkManager.php @@ -106,7 +106,7 @@ interface ChunkManager{ * @param int $chunkZ * @param Chunk|null $chunk */ - public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk = null); + public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk); /** * Returns the height of the world diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index cb465faef4..61b5cb8681 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -2303,7 +2303,7 @@ class Level implements ChunkManager, Metadatable{ * @param Chunk|null $chunk * @param bool $deleteEntitiesAndTiles Whether to delete entities and tiles on the old chunk, or transfer them to the new one */ - public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk = null, bool $deleteEntitiesAndTiles = true){ + public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk, bool $deleteEntitiesAndTiles = true){ if($chunk === null){ return; } diff --git a/src/pocketmine/level/Position.php b/src/pocketmine/level/Position.php index 0be7137a91..b1de803aeb 100644 --- a/src/pocketmine/level/Position.php +++ b/src/pocketmine/level/Position.php @@ -79,7 +79,7 @@ class Position extends Vector3{ * * @throws \InvalidArgumentException if the specified Level has been closed */ - public function setLevel(Level $level = null){ + public function setLevel(?Level $level){ if($level !== null and $level->isClosed()){ throw new \InvalidArgumentException("Specified world has been unloaded and cannot be used"); } diff --git a/src/pocketmine/level/SimpleChunkManager.php b/src/pocketmine/level/SimpleChunkManager.php index 93512944dd..a51452cef6 100644 --- a/src/pocketmine/level/SimpleChunkManager.php +++ b/src/pocketmine/level/SimpleChunkManager.php @@ -102,7 +102,7 @@ class SimpleChunkManager implements ChunkManager{ * @param int $chunkZ * @param Chunk|null $chunk */ - public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk = null){ + public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk){ if($chunk === null){ unset($this->chunks[Level::chunkHash($chunkX, $chunkZ)]); return; diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index 38799b0601..9939cc59d6 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -696,7 +696,7 @@ class Chunk{ * * @return bool */ - public function setSubChunk(int $y, SubChunkInterface $subChunk = null, bool $allowEmpty = false) : bool{ + public function setSubChunk(int $y, ?SubChunkInterface $subChunk, bool $allowEmpty = false) : bool{ if($y < 0 or $y >= $this->height){ return false; } diff --git a/src/pocketmine/permission/BanEntry.php b/src/pocketmine/permission/BanEntry.php index 80aae0c6e2..cb64d7e7c9 100644 --- a/src/pocketmine/permission/BanEntry.php +++ b/src/pocketmine/permission/BanEntry.php @@ -90,7 +90,7 @@ class BanEntry{ * @param \DateTime|null $date * @throws \InvalidArgumentException */ - public function setExpires(\DateTime $date = null){ + public function setExpires(?\DateTime $date){ if($date !== null){ self::validateDate($date); } diff --git a/src/pocketmine/permission/PermissionAttachmentInfo.php b/src/pocketmine/permission/PermissionAttachmentInfo.php index 198f21bbfc..418edfb818 100644 --- a/src/pocketmine/permission/PermissionAttachmentInfo.php +++ b/src/pocketmine/permission/PermissionAttachmentInfo.php @@ -45,7 +45,7 @@ class PermissionAttachmentInfo{ * * @throws \InvalidStateException */ - public function __construct(Permissible $permissible, string $permission, PermissionAttachment $attachment = null, bool $value){ + public function __construct(Permissible $permissible, string $permission, ?PermissionAttachment $attachment, bool $value){ $this->permissible = $permissible; $this->permission = $permission; $this->attachment = $attachment; diff --git a/src/pocketmine/scheduler/Task.php b/src/pocketmine/scheduler/Task.php index c5851b587d..af7d0c50d1 100644 --- a/src/pocketmine/scheduler/Task.php +++ b/src/pocketmine/scheduler/Task.php @@ -55,7 +55,7 @@ abstract class Task{ /** * @param TaskHandler|null $taskHandler */ - final public function setHandler(TaskHandler $taskHandler = null){ + final public function setHandler(?TaskHandler $taskHandler){ if($this->taskHandler === null or $taskHandler === null){ $this->taskHandler = $taskHandler; } diff --git a/src/pocketmine/tile/ItemFrame.php b/src/pocketmine/tile/ItemFrame.php index da6d3792fc..cd75daeaf5 100644 --- a/src/pocketmine/tile/ItemFrame.php +++ b/src/pocketmine/tile/ItemFrame.php @@ -68,7 +68,7 @@ class ItemFrame extends Spawnable{ return clone $this->item; } - public function setItem(Item $item = null){ + public function setItem(?Item $item){ if($item !== null and !$item->isNull()){ $this->item = clone $item; }else{ From c26544475e679137a762aba7ba760feb82e9576c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 22 Feb 2019 12:55:34 +0000 Subject: [PATCH 0521/3224] More PHP 7.1 nullables --- src/pocketmine/Player.php | 10 +++++----- src/pocketmine/Server.php | 12 ++++++------ src/pocketmine/Thread.php | 2 +- src/pocketmine/Worker.php | 2 +- src/pocketmine/command/Command.php | 2 +- src/pocketmine/command/CommandMap.php | 2 +- src/pocketmine/command/ConsoleCommandSender.php | 2 +- src/pocketmine/command/SimpleCommandMap.php | 2 +- .../command/defaults/ParticleCommand.php | 2 +- .../event/entity/EntityEffectAddEvent.php | 2 +- src/pocketmine/event/player/PlayerChatEvent.php | 2 +- src/pocketmine/inventory/BaseInventory.php | 2 +- src/pocketmine/inventory/ContainerInventory.php | 2 +- src/pocketmine/item/ItemBlock.php | 2 +- src/pocketmine/lang/Language.php | 6 +++--- src/pocketmine/level/Level.php | 14 +++++++------- src/pocketmine/level/LevelManager.php | 2 +- src/pocketmine/level/Location.php | 4 ++-- src/pocketmine/level/Position.php | 4 ++-- src/pocketmine/permission/BanList.php | 2 +- src/pocketmine/permission/DefaultPermissions.php | 2 +- src/pocketmine/permission/Permissible.php | 2 +- src/pocketmine/permission/PermissibleBase.php | 2 +- src/pocketmine/permission/Permission.php | 2 +- src/pocketmine/plugin/PluginManager.php | 4 ++-- src/pocketmine/timings/TimingsHandler.php | 2 +- src/pocketmine/utils/Internet.php | 2 +- src/pocketmine/utils/UUID.php | 6 +++--- 28 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 4432a58a2d..7906844819 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -609,7 +609,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * * @return PermissionAttachment */ - public function addAttachment(Plugin $plugin, string $name = null, bool $value = null) : PermissionAttachment{ + public function addAttachment(Plugin $plugin, ?string $name = null, ?bool $value = null) : PermissionAttachment{ return $this->perm->addAttachment($plugin, $name, $value); } @@ -910,7 +910,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return false; } - protected function unloadChunk(int $x, int $z, Level $level = null){ + protected function unloadChunk(int $x, int $z, ?Level $level = null){ $level = $level ?? $this->level; $index = Level::chunkHash($x, $z); if(isset($this->usedChunks[$index])){ @@ -3132,7 +3132,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $result; } - public function sendPosition(Vector3 $pos, float $yaw = null, float $pitch = null, int $mode = MovePlayerPacket::MODE_NORMAL, array $targets = null){ + public function sendPosition(Vector3 $pos, ?float $yaw = null, ?float $pitch = null, int $mode = MovePlayerPacket::MODE_NORMAL, ?array $targets = null){ $yaw = $yaw ?? $this->yaw; $pitch = $pitch ?? $this->pitch; @@ -3156,7 +3156,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * {@inheritdoc} */ - public function teleport(Vector3 $pos, float $yaw = null, float $pitch = null) : bool{ + public function teleport(Vector3 $pos, ?float $yaw = null, ?float $pitch = null) : bool{ if(parent::teleport($pos, $yaw, $pitch)){ $this->removeAllWindows(); @@ -3298,7 +3298,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @throws \InvalidArgumentException if a forceID which is already in use is specified * @throws \InvalidStateException if trying to add a window without forceID when no slots are free */ - public function addWindow(Inventory $inventory, int $forceId = null, bool $isPermanent = false) : int{ + public function addWindow(Inventory $inventory, ?int $forceId = null, bool $isPermanent = false) : int{ if(($id = $this->getWindowId($inventory)) !== ContainerIds::NONE){ return $id; } diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 12bf3f5225..10d8302fc4 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1333,7 +1333,7 @@ class Server{ * * @return int */ - public function broadcastMessage($message, array $recipients = null) : int{ + public function broadcastMessage($message, ?array $recipients = null) : int{ if(!is_array($recipients)){ return $this->broadcast($message, self::BROADCAST_CHANNEL_USERS); } @@ -1363,7 +1363,7 @@ class Server{ * * @return int */ - public function broadcastTip(string $tip, array $recipients = null) : int{ + public function broadcastTip(string $tip, ?array $recipients = null) : int{ $recipients = $recipients ?? $this->selectPermittedPlayers(self::BROADCAST_CHANNEL_USERS); /** @var Player[] $recipients */ @@ -1380,7 +1380,7 @@ class Server{ * * @return int */ - public function broadcastPopup(string $popup, array $recipients = null) : int{ + public function broadcastPopup(string $popup, ?array $recipients = null) : int{ $recipients = $recipients ?? $this->selectPermittedPlayers(self::BROADCAST_CHANNEL_USERS); /** @var Player[] $recipients */ @@ -1401,7 +1401,7 @@ class Server{ * * @return int */ - public function broadcastTitle(string $title, string $subtitle = "", int $fadeIn = -1, int $stay = -1, int $fadeOut = -1, array $recipients = null) : int{ + public function broadcastTitle(string $title, string $subtitle = "", int $fadeIn = -1, int $stay = -1, int $fadeOut = -1, ?array $recipients = null) : int{ $recipients = $recipients ?? $this->selectPermittedPlayers(self::BROADCAST_CHANNEL_USERS); /** @var Player[] $recipients */ @@ -1916,7 +1916,7 @@ class Server{ * @param string $xboxUserId * @param Player[]|null $players */ - public function updatePlayerListData(UUID $uuid, int $entityId, string $name, Skin $skin, string $xboxUserId = "", array $players = null){ + public function updatePlayerListData(UUID $uuid, int $entityId, string $name, Skin $skin, string $xboxUserId = "", ?array $players = null){ $pk = new PlayerListPacket(); $pk->type = PlayerListPacket::TYPE_ADD; @@ -1929,7 +1929,7 @@ class Server{ * @param UUID $uuid * @param Player[]|null $players */ - public function removePlayerListData(UUID $uuid, array $players = null){ + public function removePlayerListData(UUID $uuid, ?array $players = null){ $pk = new PlayerListPacket(); $pk->type = PlayerListPacket::TYPE_REMOVE; $pk->entries[] = PlayerListEntry::createRemovalEntry($uuid); diff --git a/src/pocketmine/Thread.php b/src/pocketmine/Thread.php index 347ec62bcd..a51ba123f9 100644 --- a/src/pocketmine/Thread.php +++ b/src/pocketmine/Thread.php @@ -39,7 +39,7 @@ abstract class Thread extends \Thread{ return $this->classLoader; } - public function setClassLoader(\ClassLoader $loader = null){ + public function setClassLoader(?\ClassLoader $loader = null){ $this->composerAutoloaderPath = \pocketmine\COMPOSER_AUTOLOADER_PATH; if($loader === null){ diff --git a/src/pocketmine/Worker.php b/src/pocketmine/Worker.php index f4018ea48f..ee62a05400 100644 --- a/src/pocketmine/Worker.php +++ b/src/pocketmine/Worker.php @@ -39,7 +39,7 @@ abstract class Worker extends \Worker{ return $this->classLoader; } - public function setClassLoader(\ClassLoader $loader = null){ + public function setClassLoader(?\ClassLoader $loader = null){ $this->composerAutoloaderPath = \pocketmine\COMPOSER_AUTOLOADER_PATH; if($loader === null){ diff --git a/src/pocketmine/command/Command.php b/src/pocketmine/command/Command.php index 0cea12cd9b..02ab7989ae 100644 --- a/src/pocketmine/command/Command.php +++ b/src/pocketmine/command/Command.php @@ -79,7 +79,7 @@ abstract class Command{ * @param string $usageMessage * @param string[] $aliases */ - public function __construct(string $name, string $description = "", string $usageMessage = null, array $aliases = []){ + public function __construct(string $name, string $description = "", ?string $usageMessage = null, array $aliases = []){ $this->name = $name; $this->setLabel($name); $this->setDescription($description); diff --git a/src/pocketmine/command/CommandMap.php b/src/pocketmine/command/CommandMap.php index 837d6e2bdb..9583b4e83a 100644 --- a/src/pocketmine/command/CommandMap.php +++ b/src/pocketmine/command/CommandMap.php @@ -39,7 +39,7 @@ interface CommandMap{ * * @return bool */ - public function register(string $fallbackPrefix, Command $command, string $label = null) : bool; + public function register(string $fallbackPrefix, Command $command, ?string $label = null) : bool; /** * @param CommandSender $sender diff --git a/src/pocketmine/command/ConsoleCommandSender.php b/src/pocketmine/command/ConsoleCommandSender.php index 119c55fef2..8db5aa74db 100644 --- a/src/pocketmine/command/ConsoleCommandSender.php +++ b/src/pocketmine/command/ConsoleCommandSender.php @@ -71,7 +71,7 @@ class ConsoleCommandSender implements CommandSender{ * * @return PermissionAttachment */ - public function addAttachment(Plugin $plugin, string $name = null, bool $value = null) : PermissionAttachment{ + public function addAttachment(Plugin $plugin, ?string $name = null, ?bool $value = null) : PermissionAttachment{ return $this->perm->addAttachment($plugin, $name, $value); } diff --git a/src/pocketmine/command/SimpleCommandMap.php b/src/pocketmine/command/SimpleCommandMap.php index d7296f82f8..523089d658 100644 --- a/src/pocketmine/command/SimpleCommandMap.php +++ b/src/pocketmine/command/SimpleCommandMap.php @@ -151,7 +151,7 @@ class SimpleCommandMap implements CommandMap{ * * @return bool */ - public function register(string $fallbackPrefix, Command $command, string $label = null) : bool{ + public function register(string $fallbackPrefix, Command $command, ?string $label = null) : bool{ if($label === null){ $label = $command->getName(); } diff --git a/src/pocketmine/command/defaults/ParticleCommand.php b/src/pocketmine/command/defaults/ParticleCommand.php index 12b939eb39..c9ea96da11 100644 --- a/src/pocketmine/command/defaults/ParticleCommand.php +++ b/src/pocketmine/command/defaults/ParticleCommand.php @@ -141,7 +141,7 @@ class ParticleCommand extends VanillaCommand{ * * @return Particle|null */ - private function getParticle(string $name, int $data = null){ + private function getParticle(string $name, ?int $data = null){ switch($name){ case "explode": return new ExplodeParticle(); diff --git a/src/pocketmine/event/entity/EntityEffectAddEvent.php b/src/pocketmine/event/entity/EntityEffectAddEvent.php index a42747f75f..d8f5633576 100644 --- a/src/pocketmine/event/entity/EntityEffectAddEvent.php +++ b/src/pocketmine/event/entity/EntityEffectAddEvent.php @@ -38,7 +38,7 @@ class EntityEffectAddEvent extends EntityEffectEvent{ * @param EffectInstance $effect * @param EffectInstance $oldEffect */ - public function __construct(Entity $entity, EffectInstance $effect, EffectInstance $oldEffect = null){ + public function __construct(Entity $entity, EffectInstance $effect, ?EffectInstance $oldEffect = null){ parent::__construct($entity, $effect); $this->oldEffect = $oldEffect; } diff --git a/src/pocketmine/event/player/PlayerChatEvent.php b/src/pocketmine/event/player/PlayerChatEvent.php index b12fa0858a..ca54c1a5d1 100644 --- a/src/pocketmine/event/player/PlayerChatEvent.php +++ b/src/pocketmine/event/player/PlayerChatEvent.php @@ -52,7 +52,7 @@ class PlayerChatEvent extends PlayerEvent implements Cancellable{ * @param string $format * @param Player[] $recipients */ - public function __construct(Player $player, string $message, string $format = "chat.type.text", array $recipients = null){ + public function __construct(Player $player, string $message, string $format = "chat.type.text", ?array $recipients = null){ $this->player = $player; $this->message = $message; diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index 974ba3b26d..17fe9e66c8 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -57,7 +57,7 @@ abstract class BaseInventory implements Inventory{ * @param int $size * @param string $title */ - public function __construct(array $items = [], int $size = null, string $title = null){ + public function __construct(array $items = [], ?int $size = null, ?string $title = null){ $this->slots = new \SplFixedArray($size ?? $this->getDefaultSize()); $this->title = $title ?? $this->getName(); diff --git a/src/pocketmine/inventory/ContainerInventory.php b/src/pocketmine/inventory/ContainerInventory.php index 4ede6d8263..b807b0b08f 100644 --- a/src/pocketmine/inventory/ContainerInventory.php +++ b/src/pocketmine/inventory/ContainerInventory.php @@ -33,7 +33,7 @@ abstract class ContainerInventory extends BaseInventory{ /** @var Vector3 */ protected $holder; - public function __construct(Vector3 $holder, array $items = [], int $size = null, string $title = null){ + public function __construct(Vector3 $holder, array $items = [], ?int $size = null, ?string $title = null){ $this->holder = $holder; parent::__construct($items, $size, $title); } diff --git a/src/pocketmine/item/ItemBlock.php b/src/pocketmine/item/ItemBlock.php index a0c4375f58..e88576026b 100644 --- a/src/pocketmine/item/ItemBlock.php +++ b/src/pocketmine/item/ItemBlock.php @@ -38,7 +38,7 @@ class ItemBlock extends Item{ * @param int $meta usually 0-15 (placed blocks may only have meta values 0-15) * @param int|null $itemId */ - public function __construct(int $blockId, int $meta = 0, int $itemId = null){ + public function __construct(int $blockId, int $meta = 0, ?int $itemId = null){ if($blockId < 0){ //extended blocks if($itemId === null){ $itemId = $blockId; diff --git a/src/pocketmine/lang/Language.php b/src/pocketmine/lang/Language.php index 05efd6e5a3..13c1b228f5 100644 --- a/src/pocketmine/lang/Language.php +++ b/src/pocketmine/lang/Language.php @@ -94,7 +94,7 @@ class Language{ * * @throws LanguageNotFoundException */ - public function __construct(string $lang, string $path = null, string $fallback = self::FALLBACK_LANGUAGE){ + public function __construct(string $lang, ?string $path = null, string $fallback = self::FALLBACK_LANGUAGE){ $this->langName = strtolower($lang); if($path === null){ @@ -129,7 +129,7 @@ class Language{ * * @return string */ - public function translateString(string $str, array $params = [], string $onlyPrefix = null) : string{ + public function translateString(string $str, array $params = [], ?string $onlyPrefix = null) : string{ $baseText = $this->get($str); $baseText = $this->parseTranslation(($baseText !== null and ($onlyPrefix === null or strpos($str, $onlyPrefix) === 0)) ? $baseText : $str, $onlyPrefix); @@ -179,7 +179,7 @@ class Language{ * * @return string */ - protected function parseTranslation(string $text, string $onlyPrefix = null) : string{ + protected function parseTranslation(string $text, ?string $onlyPrefix = null) : string{ $newString = ""; $replaceString = null; diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 61b5cb8681..40981b0f17 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -478,7 +478,7 @@ class Level implements ChunkManager, Metadatable{ $this->closed = true; } - public function addSound(Vector3 $pos, Sound $sound, array $players = null){ + public function addSound(Vector3 $pos, Sound $sound, ?array $players = null){ $pk = $sound->encode($pos); if(!is_array($pk)){ $pk = [$pk]; @@ -494,7 +494,7 @@ class Level implements ChunkManager, Metadatable{ } } - public function addParticle(Vector3 $pos, Particle $particle, array $players = null){ + public function addParticle(Vector3 $pos, Particle $particle, ?array $players = null){ $pk = $particle->encode($pos); if(!is_array($pk)){ $pk = [$pk]; @@ -1626,7 +1626,7 @@ class Level implements ChunkManager, Metadatable{ * * @return ItemEntity|null */ - public function dropItem(Vector3 $source, Item $item, Vector3 $motion = null, int $delay = 10){ + public function dropItem(Vector3 $source, Item $item, ?Vector3 $motion = null, int $delay = 10){ $motion = $motion ?? new Vector3(lcg_value() * 0.2 - 0.1, 0.2, lcg_value() * 0.2 - 0.1); $itemTag = $item->nbtSerialize(); $itemTag->setName("Item"); @@ -1686,7 +1686,7 @@ class Level implements ChunkManager, Metadatable{ * * @return bool */ - public function useBreakOn(Vector3 $vector, Item &$item = null, Player $player = null, bool $createParticles = false) : bool{ + public function useBreakOn(Vector3 $vector, Item &$item = null, ?Player $player = null, bool $createParticles = false) : bool{ $target = $this->getBlock($vector); $affectedBlocks = $target->getAffectedBlocks(); @@ -1788,7 +1788,7 @@ class Level implements ChunkManager, Metadatable{ * * @return bool */ - public function useItemOn(Vector3 $vector, Item &$item, int $face, Vector3 $clickVector = null, Player $player = null, bool $playSound = false) : bool{ + public function useItemOn(Vector3 $vector, Item &$item, int $face, ?Vector3 $clickVector = null, ?Player $player = null, bool $playSound = false) : bool{ $blockClicked = $this->getBlock($vector); $blockReplace = $blockClicked->getSide($face); @@ -1928,7 +1928,7 @@ class Level implements ChunkManager, Metadatable{ * * @return Entity[] */ - public function getCollidingEntities(AxisAlignedBB $bb, Entity $entity = null) : array{ + public function getCollidingEntities(AxisAlignedBB $bb, ?Entity $entity = null) : array{ $nearby = []; if($entity === null or $entity->canCollide){ @@ -1960,7 +1960,7 @@ class Level implements ChunkManager, Metadatable{ * * @return Entity[] */ - public function getNearbyEntities(AxisAlignedBB $bb, Entity $entity = null) : array{ + public function getNearbyEntities(AxisAlignedBB $bb, ?Entity $entity = null) : array{ $nearby = []; $minX = ((int) floor($bb->minX - 2)) >> 4; diff --git a/src/pocketmine/level/LevelManager.php b/src/pocketmine/level/LevelManager.php index 2dbbdb1151..6ac55a4163 100644 --- a/src/pocketmine/level/LevelManager.php +++ b/src/pocketmine/level/LevelManager.php @@ -259,7 +259,7 @@ class LevelManager{ * @return bool * @throws \InvalidArgumentException */ - public function generateLevel(string $name, int $seed = null, string $generator = Normal::class, array $options = [], bool $backgroundGeneration = true) : bool{ + public function generateLevel(string $name, ?int $seed = null, string $generator = Normal::class, array $options = [], bool $backgroundGeneration = true) : bool{ if(trim($name) === "" or $this->isLevelGenerated($name)){ return false; } diff --git a/src/pocketmine/level/Location.php b/src/pocketmine/level/Location.php index b24d902421..beb129ef45 100644 --- a/src/pocketmine/level/Location.php +++ b/src/pocketmine/level/Location.php @@ -40,7 +40,7 @@ class Location extends Position{ * @param float $pitch * @param Level $level */ - public function __construct($x = 0, $y = 0, $z = 0, $yaw = 0.0, $pitch = 0.0, Level $level = null){ + public function __construct($x = 0, $y = 0, $z = 0, $yaw = 0.0, $pitch = 0.0, ?Level $level = null){ $this->yaw = $yaw; $this->pitch = $pitch; parent::__construct($x, $y, $z, $level); @@ -54,7 +54,7 @@ class Location extends Position{ * * @return Location */ - public static function fromObject(Vector3 $pos, Level $level = null, $yaw = 0.0, $pitch = 0.0) : Location{ + public static function fromObject(Vector3 $pos, ?Level $level = null, $yaw = 0.0, $pitch = 0.0) : Location{ return new Location($pos->x, $pos->y, $pos->z, $yaw, $pitch, $level ?? (($pos instanceof Position) ? $pos->level : null)); } diff --git a/src/pocketmine/level/Position.php b/src/pocketmine/level/Position.php index b1de803aeb..a6bb3ef67a 100644 --- a/src/pocketmine/level/Position.php +++ b/src/pocketmine/level/Position.php @@ -37,12 +37,12 @@ class Position extends Vector3{ * @param int $z * @param Level $level */ - public function __construct($x = 0, $y = 0, $z = 0, Level $level = null){ + public function __construct($x = 0, $y = 0, $z = 0, ?Level $level = null){ parent::__construct($x, $y, $z); $this->setLevel($level); } - public static function fromObject(Vector3 $pos, Level $level = null){ + public static function fromObject(Vector3 $pos, ?Level $level = null){ return new Position($pos->x, $pos->y, $pos->z, $level); } diff --git a/src/pocketmine/permission/BanList.php b/src/pocketmine/permission/BanList.php index df849c1c90..82493e1bf2 100644 --- a/src/pocketmine/permission/BanList.php +++ b/src/pocketmine/permission/BanList.php @@ -118,7 +118,7 @@ class BanList{ * * @return BanEntry */ - public function addBan(string $target, string $reason = null, \DateTime $expires = null, string $source = null) : BanEntry{ + public function addBan(string $target, ?string $reason = null, ?\DateTime $expires = null, ?string $source = null) : BanEntry{ $entry = new BanEntry($target); $entry->setSource($source ?? $entry->getSource()); $entry->setExpires($expires); diff --git a/src/pocketmine/permission/DefaultPermissions.php b/src/pocketmine/permission/DefaultPermissions.php index 465f7a7754..015f87d54f 100644 --- a/src/pocketmine/permission/DefaultPermissions.php +++ b/src/pocketmine/permission/DefaultPermissions.php @@ -35,7 +35,7 @@ abstract class DefaultPermissions{ * * @return Permission */ - public static function registerPermission(Permission $perm, Permission $parent = null) : Permission{ + public static function registerPermission(Permission $perm, ?Permission $parent = null) : Permission{ if($parent instanceof Permission){ $parent->getChildren()[$perm->getName()] = true; diff --git a/src/pocketmine/permission/Permissible.php b/src/pocketmine/permission/Permissible.php index 517750cacc..21ebba7b2c 100644 --- a/src/pocketmine/permission/Permissible.php +++ b/src/pocketmine/permission/Permissible.php @@ -52,7 +52,7 @@ interface Permissible extends ServerOperator{ * * @return PermissionAttachment */ - public function addAttachment(Plugin $plugin, string $name = null, bool $value = null) : PermissionAttachment; + public function addAttachment(Plugin $plugin, ?string $name = null, ?bool $value = null) : PermissionAttachment; /** * @param PermissionAttachment $attachment diff --git a/src/pocketmine/permission/PermissibleBase.php b/src/pocketmine/permission/PermissibleBase.php index 809d62c756..47b5acfde5 100644 --- a/src/pocketmine/permission/PermissibleBase.php +++ b/src/pocketmine/permission/PermissibleBase.php @@ -111,7 +111,7 @@ class PermissibleBase implements Permissible{ * * @return PermissionAttachment */ - public function addAttachment(Plugin $plugin, string $name = null, bool $value = null) : PermissionAttachment{ + public function addAttachment(Plugin $plugin, ?string $name = null, ?bool $value = null) : PermissionAttachment{ if(!$plugin->isEnabled()){ throw new PluginException("Plugin " . $plugin->getDescription()->getName() . " is disabled"); } diff --git a/src/pocketmine/permission/Permission.php b/src/pocketmine/permission/Permission.php index 9bbd374e56..4759d0666a 100644 --- a/src/pocketmine/permission/Permission.php +++ b/src/pocketmine/permission/Permission.php @@ -60,7 +60,7 @@ class Permission{ * @param string $defaultValue * @param bool[] $children */ - public function __construct(string $name, string $description = null, string $defaultValue = null, array $children = []){ + public function __construct(string $name, ?string $description = null, ?string $defaultValue = null, array $children = []){ $this->name = $name; $this->description = $description ?? ""; $this->defaultValue = $defaultValue ?? self::$DEFAULT_PERMISSION; diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index 3e7e1270f5..93f4c4edc6 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -137,7 +137,7 @@ class PluginManager{ * * @return Plugin|null */ - public function loadPlugin(string $path, array $loaders = null) : ?Plugin{ + public function loadPlugin(string $path, ?array $loaders = null) : ?Plugin{ foreach($loaders ?? $this->fileAssociations as $loader){ if($loader->canLoadPlugin($path)){ $description = $loader->getPluginDescription($path); @@ -193,7 +193,7 @@ class PluginManager{ * * @return Plugin[] */ - public function loadPlugins(string $directory, array $newLoaders = null){ + public function loadPlugins(string $directory, ?array $newLoaders = null){ if(!is_dir($directory)){ return []; } diff --git a/src/pocketmine/timings/TimingsHandler.php b/src/pocketmine/timings/TimingsHandler.php index 102f5466cc..8889e2b142 100644 --- a/src/pocketmine/timings/TimingsHandler.php +++ b/src/pocketmine/timings/TimingsHandler.php @@ -150,7 +150,7 @@ class TimingsHandler{ * @param string $name * @param TimingsHandler $parent */ - public function __construct(string $name, TimingsHandler $parent = null){ + public function __construct(string $name, ?TimingsHandler $parent = null){ $this->name = $name; $this->parent = $parent; diff --git a/src/pocketmine/utils/Internet.php b/src/pocketmine/utils/Internet.php index ebd704bdaa..b7f9ab1cf0 100644 --- a/src/pocketmine/utils/Internet.php +++ b/src/pocketmine/utils/Internet.php @@ -193,7 +193,7 @@ class Internet{ * * @throws InternetException if a cURL error occurs */ - public static function simpleCurl(string $page, $timeout = 10, array $extraHeaders = [], array $extraOpts = [], callable $onSuccess = null){ + public static function simpleCurl(string $page, $timeout = 10, array $extraHeaders = [], array $extraOpts = [], ?callable $onSuccess = null){ if(!self::$online){ throw new InternetException("Cannot execute web request while offline"); } diff --git a/src/pocketmine/utils/UUID.php b/src/pocketmine/utils/UUID.php index 0c21d8a7b8..703d9fdc74 100644 --- a/src/pocketmine/utils/UUID.php +++ b/src/pocketmine/utils/UUID.php @@ -41,7 +41,7 @@ class UUID{ private $parts = [0, 0, 0, 0]; private $version = null; - public function __construct(int $part1 = 0, int $part2 = 0, int $part3 = 0, int $part4 = 0, int $version = null){ + public function __construct(int $part1 = 0, int $part2 = 0, int $part3 = 0, int $part4 = 0, ?int $version = null){ $this->parts = [$part1, $part2, $part3, $part4]; $this->version = $version ?? ($this->parts[1] & 0xf000) >> 12; @@ -63,7 +63,7 @@ class UUID{ * * @return UUID */ - public static function fromString(string $uuid, int $version = null) : UUID{ + public static function fromString(string $uuid, ?int $version = null) : UUID{ return self::fromBinary(hex2bin(str_replace("-", "", trim($uuid))), $version); } @@ -77,7 +77,7 @@ class UUID{ * * @throws \InvalidArgumentException */ - public static function fromBinary(string $uuid, int $version = null) : UUID{ + public static function fromBinary(string $uuid, ?int $version = null) : UUID{ if(strlen($uuid) !== 16){ throw new \InvalidArgumentException("Must have exactly 16 bytes"); } From 9c085799e6b33f5f0dcfce1fc5c66e5259e5bcbf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 22 Feb 2019 12:56:14 +0000 Subject: [PATCH 0522/3224] Removed leftover import from 3d1502c9ad2b98f9e38f7a0d61e8148fb8ef660a --- src/pocketmine/permission/DefaultPermissions.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pocketmine/permission/DefaultPermissions.php b/src/pocketmine/permission/DefaultPermissions.php index 015f87d54f..46fa31d76a 100644 --- a/src/pocketmine/permission/DefaultPermissions.php +++ b/src/pocketmine/permission/DefaultPermissions.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\permission; use function file_get_contents; -use function yaml_parse_file; abstract class DefaultPermissions{ public const ROOT = "pocketmine"; From 707faef0f7536c27e64c3633ba3a53b52b96d3d7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 22 Feb 2019 18:54:21 +0000 Subject: [PATCH 0523/3224] BlockTest: remove redundant name test name is mandatory in the constructor now, so this isn't necessary anymore. --- tests/phpunit/block/BlockTest.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index 053cfc284c..5e19f4d15e 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -127,16 +127,6 @@ class BlockTest extends TestCase{ } } - /** - * Test that all blocks have correctly set names - */ - public function testBlockNames() : void{ - for($id = 0; $id < 256; ++$id){ - $b = BlockFactory::get($id); - self::assertTrue($b instanceof UnknownBlock or $b->getName() !== "Unknown", "Block with ID $id does not have a valid name"); - } - } - /** * Test that light filters in the static arrays have valid values. Wrong values can cause lots of unpleasant bugs * (like freezes) when doing light population. From f669677d1744b210dbf4f7ff36b3e1d3da7dc53d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 22 Feb 2019 18:56:14 +0000 Subject: [PATCH 0524/3224] BlockTest: fixed failing test this is a bad fix, but it doesn't matter a whole lot. The problem stems from furnace not having a valid 0 variant, so things go haywire when the default mapped 0 variant is registered to LIT_FURNACE because the default state is of course unlit. --- tests/phpunit/block/BlockTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index 5e19f4d15e..c6b68fd134 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -123,7 +123,7 @@ class BlockTest extends TestCase{ public function testBlockIds() : void{ for($i = 0; $i < 256; ++$i){ $b = BlockFactory::get($i); - self::assertEquals($i, $b->getId()); + self::assertContains($i, $b->getIdInfo()->getAllBlockIds()); } } From 991483938cd3eed56aa4dc08ad4b15e195a3d2e6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Feb 2019 13:18:37 +0000 Subject: [PATCH 0525/3224] SubChunk: remove legacy crap --- src/pocketmine/level/format/EmptySubChunk.php | 16 ---------- src/pocketmine/level/format/SubChunk.php | 17 ---------- .../level/format/SubChunkInterface.php | 32 ------------------- .../level/format/io/region/McRegion.php | 8 ++--- 4 files changed, 4 insertions(+), 69 deletions(-) diff --git a/src/pocketmine/level/format/EmptySubChunk.php b/src/pocketmine/level/format/EmptySubChunk.php index 1daf867234..5ca3980e09 100644 --- a/src/pocketmine/level/format/EmptySubChunk.php +++ b/src/pocketmine/level/format/EmptySubChunk.php @@ -77,22 +77,6 @@ class EmptySubChunk implements SubChunkInterface{ return -1; } - public function getBlockIdColumn(int $x, int $z) : string{ - return "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; - } - - public function getBlockDataColumn(int $x, int $z) : string{ - return "\x00\x00\x00\x00\x00\x00\x00\x00"; - } - - public function getBlockLightColumn(int $x, int $z) : string{ - return "\x00\x00\x00\x00\x00\x00\x00\x00"; - } - - public function getBlockSkyLightColumn(int $x, int $z) : string{ - return "\xff\xff\xff\xff\xff\xff\xff\xff"; - } - public function getBlockIdArray() : string{ return str_repeat("\x00", 4096); } diff --git a/src/pocketmine/level/format/SubChunk.php b/src/pocketmine/level/format/SubChunk.php index 2971690eab..1b6ed2f201 100644 --- a/src/pocketmine/level/format/SubChunk.php +++ b/src/pocketmine/level/format/SubChunk.php @@ -30,7 +30,6 @@ use function defined; use function ord; use function str_repeat; use function strlen; -use function substr; use function substr_count; if(!defined(__NAMESPACE__ . '\ZERO_NIBBLE_ARRAY')){ @@ -145,22 +144,6 @@ class SubChunk implements SubChunkInterface{ return -1; //highest block not in this subchunk } - public function getBlockIdColumn(int $x, int $z) : string{ - return substr($this->ids, ($x << 8) | ($z << 4), 16); - } - - public function getBlockDataColumn(int $x, int $z) : string{ - return substr($this->data, ($x << 7) | ($z << 3), 8); - } - - public function getBlockLightColumn(int $x, int $z) : string{ - return substr($this->blockLight, ($x << 7) | ($z << 3), 8); - } - - public function getBlockSkyLightColumn(int $x, int $z) : string{ - return substr($this->skyLight, ($x << 7) | ($z << 3), 8); - } - public function getBlockIdArray() : string{ assert(strlen($this->ids) === 4096, "Wrong length of ID array, expecting 4096 bytes, got " . strlen($this->ids)); return $this->ids; diff --git a/src/pocketmine/level/format/SubChunkInterface.php b/src/pocketmine/level/format/SubChunkInterface.php index 71226db908..5d3c718f0c 100644 --- a/src/pocketmine/level/format/SubChunkInterface.php +++ b/src/pocketmine/level/format/SubChunkInterface.php @@ -116,38 +116,6 @@ interface SubChunkInterface{ */ public function getHighestBlockAt(int $x, int $z) : int; - /** - * @param int $x - * @param int $z - * - * @return string - */ - public function getBlockIdColumn(int $x, int $z) : string; - - /** - * @param int $x - * @param int $z - * - * @return string - */ - public function getBlockDataColumn(int $x, int $z) : string; - - /** - * @param int $x - * @param int $z - * - * @return string - */ - public function getBlockLightColumn(int $x, int $z) : string; - - /** - * @param int $x - * @param int $z - * - * @return string - */ - public function getBlockSkyLightColumn(int $x, int $z) : string; - /** * @return string */ diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index 56f1e0326b..277e6ff893 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -65,10 +65,10 @@ class McRegion extends RegionLevelProvider{ for($z = 0; $z < 16; ++$z){ for($y = 0; $y < 8; ++$y){ $subChunk = $subChunks[$y]; - $ids .= $subChunk->getBlockIdColumn($x, $z); - $data .= $subChunk->getBlockDataColumn($x, $z); - $skyLight .= $subChunk->getBlockSkyLightColumn($x, $z); - $blockLight .= $subChunk->getBlockLightColumn($x, $z); + $ids .= substr($subChunk->getBlockIdArray(), ($x << 8) | ($z << 4), 16); + $data .= substr($subChunk->getBlockDataArray(), ($x << 7) | ($z << 3), 8); + $skyLight .= substr($subChunk->getBlockSkyLightArray(), ($x << 7) | ($z << 3), 8); + $blockLight .= substr($subChunk->getBlockLightArray(), ($x << 7) | ($z << 3), 8); } } } From e1ef52c7c32c37190d4ad3b62698f772b39bf0ad Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Feb 2019 15:57:53 +0000 Subject: [PATCH 0526/3224] TileFactory: remove dead function --- src/pocketmine/tile/TileFactory.php | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/pocketmine/tile/TileFactory.php b/src/pocketmine/tile/TileFactory.php index 7073b619af..7c1cbf2d75 100644 --- a/src/pocketmine/tile/TileFactory.php +++ b/src/pocketmine/tile/TileFactory.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\tile; -use pocketmine\item\Item; use pocketmine\level\Level; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; @@ -119,24 +118,6 @@ final class TileFactory{ throw new \InvalidArgumentException("Class $baseClass is not a registered tile"); } - /** - * @internal - * - * @param string $baseClass - * @param Level $level - * @param Vector3 $pos - * @param Item $item - * - * @return Tile (instanceof $baseClass) - * @throws \InvalidArgumentException if the base class is not a registered tile - */ - public static function createFromItem(string $baseClass, Level $level, Vector3 $pos, Item $item) : Tile{ - $tile = self::create($baseClass, $level, $pos); - $tile->copyDataFromItem($item); - - return $tile; - } - /** * @internal * From eadb1d310e967b95efdda333c067e95ccf19aca7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Feb 2019 16:52:30 +0000 Subject: [PATCH 0527/3224] Level->sendBlocks() now syncs tiles --- src/pocketmine/Player.php | 11 ++--------- src/pocketmine/level/Level.php | 6 +++++- src/pocketmine/tile/Spawnable.php | 10 ---------- 3 files changed, 7 insertions(+), 20 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 7906844819..3aaa1ee37b 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2254,13 +2254,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->level->sendBlocks([$this], $blocks); - foreach($blocks as $b){ - $tile = $this->level->getTile($b); - if($tile instanceof Spawnable){ - $tile->spawnTo($this); - } - } - return false; } @@ -2490,7 +2483,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, throw new BadPacketException($e->getMessage(), 0, $e); } if(!$t->updateCompoundTag($compound, $this)){ - $t->spawnTo($this); + $this->level->sendBlocks([$this], [$pos]); } } @@ -2508,7 +2501,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $ev->call(); if($ev->isCancelled()){ - $tile->spawnTo($this); + $this->level->sendBlocks([$this], [$tile]); return true; } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 40981b0f17..3c4a6f48b9 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -975,8 +975,12 @@ class Level implements ChunkManager, Metadatable{ $fullBlock = $this->getFullBlock($b->x, $b->y, $b->z); $pk->blockRuntimeId = BlockFactory::toStaticRuntimeId($fullBlock >> 4, $fullBlock & 0xf); } - $packets[] = $pk; + + $tile = $this->getTileAt($b->x, $b->y, $b->z); + if($tile instanceof Spawnable){ + $packets[] = $tile->createSpawnPacket(); + } } $this->server->broadcastPackets($target, $packets); diff --git a/src/pocketmine/tile/Spawnable.php b/src/pocketmine/tile/Spawnable.php index 10f2729018..d16eee621a 100644 --- a/src/pocketmine/tile/Spawnable.php +++ b/src/pocketmine/tile/Spawnable.php @@ -50,16 +50,6 @@ abstract class Spawnable extends Tile{ return $pk; } - public function spawnTo(Player $player) : bool{ - if($this->closed){ - return false; - } - - $player->sendDataPacket($this->createSpawnPacket()); - - return true; - } - /** * Flags the tile as modified, so that updates will be broadcasted at the next available opportunity. * This MUST be called any time a change is made that players must be able to see. From 49f96056201e5a7f5b75e144d34e62ff43008cd8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Feb 2019 17:01:59 +0000 Subject: [PATCH 0528/3224] Level: Allow tiles to be sent with regular block updates --- src/pocketmine/level/Level.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 3c4a6f48b9..45f5171127 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -855,9 +855,12 @@ class Level implements ChunkManager, Metadatable{ unset($this->updateTiles[$blockHash]); } if(!$tile->isClosed() and $tile instanceof Spawnable and $tile->isDirty()){ - $this->clearChunkCache($tile->getFloorX() >> 4, $tile->getFloorZ() >> 4); - //TODO: merge this with block-updating (it'll send useless data if a full-chunk resend happens) - $this->broadcastPacketToViewers($tile, $tile->createSpawnPacket()); + $chunkHash = Level::chunkHash($tile->getFloorX() >> 4, $tile->getFloorZ() >> 4); + if(!isset($this->changedBlocks[$chunkHash])){ + $this->changedBlocks[$chunkHash] = [$blockHash => $tile]; + }else{ + $this->changedBlocks[$chunkHash][$blockHash] = $tile; + } $tile->setDirty(false); } } From 878c704597ae46f9a061f3197bade85c27647864 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Feb 2019 17:15:50 +0000 Subject: [PATCH 0529/3224] Remove another dead function --- src/pocketmine/level/Level.php | 8 +++++++- src/pocketmine/tile/Spawnable.php | 11 ----------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 45f5171127..4a3c52489a 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -73,6 +73,7 @@ use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\ChunkRequestTask; use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\protocol\AddEntityPacket; +use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; @@ -982,7 +983,12 @@ class Level implements ChunkManager, Metadatable{ $tile = $this->getTileAt($b->x, $b->y, $b->z); if($tile instanceof Spawnable){ - $packets[] = $tile->createSpawnPacket(); + $tilepk = new BlockEntityDataPacket(); + $tilepk->x = $tile->x; + $tilepk->y = $tile->y; + $tilepk->z = $tile->z; + $tilepk->namedtag = $tile->getSerializedSpawnCompound(); + $packets[] = $tilepk; } } diff --git a/src/pocketmine/tile/Spawnable.php b/src/pocketmine/tile/Spawnable.php index d16eee621a..2e155acf67 100644 --- a/src/pocketmine/tile/Spawnable.php +++ b/src/pocketmine/tile/Spawnable.php @@ -27,7 +27,6 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\NetworkNbtSerializer; -use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\Player; use function get_class; @@ -40,16 +39,6 @@ abstract class Spawnable extends Tile{ /** @var NetworkNbtSerializer|null */ private static $nbtWriter = null; - public function createSpawnPacket() : BlockEntityDataPacket{ - $pk = new BlockEntityDataPacket(); - $pk->x = $this->x; - $pk->y = $this->y; - $pk->z = $this->z; - $pk->namedtag = $this->getSerializedSpawnCompound(); - - return $pk; - } - /** * Flags the tile as modified, so that updates will be broadcasted at the next available opportunity. * This MUST be called any time a change is made that players must be able to see. From 998dcb421e8fe69ea61f0ae1982ee6ea02a5a382 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Feb 2019 18:19:31 +0000 Subject: [PATCH 0530/3224] Flatten Item Frame implementation into its block (mostly) This exposes nice API on the ItemFrame class, while keeping the tile bullshit out of sight so that we can remove it later on. --- src/pocketmine/Player.php | 19 +++-- src/pocketmine/block/ItemFrame.php | 117 +++++++++++++++++++++++++---- src/pocketmine/tile/ItemFrame.php | 4 + 3 files changed, 115 insertions(+), 25 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 3aaa1ee37b..bb32dc89c1 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -26,6 +26,7 @@ namespace pocketmine; use pocketmine\block\Bed; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\ItemFrame; use pocketmine\block\UnknownBlock; use pocketmine\command\Command; use pocketmine\command\CommandSender; @@ -135,7 +136,6 @@ use pocketmine\permission\PermissionAttachment; use pocketmine\permission\PermissionAttachmentInfo; use pocketmine\permission\PermissionManager; use pocketmine\plugin\Plugin; -use pocketmine\tile\ItemFrame; use pocketmine\tile\Spawnable; use pocketmine\tile\Tile; use pocketmine\timings\Timings; @@ -2491,25 +2491,24 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } public function handleItemFrameDropItem(ItemFrameDropItemPacket $packet) : bool{ - $tile = $this->level->getTileAt($packet->x, $packet->y, $packet->z); - if($tile instanceof ItemFrame){ - //TODO: use facing blockstate property instead of damage value - $ev = new PlayerInteractEvent($this, $this->inventory->getItemInHand(), $tile->getBlock(), null, 5 - $tile->getBlock()->getDamage(), PlayerInteractEvent::LEFT_CLICK_BLOCK); + $block = $this->level->getBlockAt($packet->x, $packet->y, $packet->z); + if($block instanceof ItemFrame){ + $ev = new PlayerInteractEvent($this, $this->inventory->getItemInHand(), $block, null, $block->getFacing(), PlayerInteractEvent::LEFT_CLICK_BLOCK); if($this->isSpectator()){ $ev->setCancelled(); } $ev->call(); if($ev->isCancelled()){ - $this->level->sendBlocks([$this], [$tile]); + $this->level->sendBlocks([$this], [$block]); return true; } - if(lcg_value() <= $tile->getItemDropChance()){ - $this->level->dropItem($tile->getBlock(), $tile->getItem()); + if(lcg_value() <= $block->getItemDropChance()){ + $this->level->dropItem($block->add(0.5, 0.5, 0.5), $block->getFramedItem()); } - $tile->setItem(null); - $tile->setItemRotation(0); + $block->setFramedItem(null); + $this->level->setBlock($block, $block); } return true; diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 1c862fb0b7..770a1cd4cc 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -37,6 +37,12 @@ class ItemFrame extends Flowable{ protected $facing = Facing::NORTH; /** @var bool */ protected $hasMap = false; //makes frame appear large if set + /** @var Item|null */ + protected $framedItem = null; + /** @var int */ + protected $itemRotation = 0; + /** @var float */ + protected $itemDropChance = 1.0; protected function writeStateToMeta() : int{ return (5 - $this->facing) | ($this->hasMap ? 0x04 : 0); @@ -47,19 +53,105 @@ class ItemFrame extends Flowable{ $this->hasMap = ($stateMeta & 0x04) !== 0; } + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); + $tile = $this->level->getTile($this); + if($tile instanceof TileItemFrame){ + $this->framedItem = $tile->getItem(); + if($this->framedItem->isNull()){ + $this->framedItem = null; + } + $this->itemRotation = $tile->getItemRotation() % 8; + $this->itemDropChance = $tile->getItemDropChance(); + } + } + + public function writeStateToWorld() : void{ + parent::writeStateToWorld(); + $tile = $this->level->getTile($this); + if($tile instanceof TileItemFrame){ + $tile->setItem($this->framedItem); + $tile->setItemRotation($this->itemRotation); + $tile->setItemDropChance($this->itemDropChance); + } + } + public function getStateBitmask() : int{ return 0b111; } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - $tile = $this->level->getTile($this); - if($tile instanceof TileItemFrame){ - if($tile->hasItem()){ - $tile->setItemRotation(($tile->getItemRotation() + 1) % 8); - }elseif(!$item->isNull()){ - $tile->setItem($item->pop()); - } + /** + * @return int + */ + public function getFacing() : int{ + return $this->facing; + } + + /** + * @param int $facing + */ + public function setFacing(int $facing) : void{ + $this->facing = $facing; + } + + /** + * @return Item|null + */ + public function getFramedItem() : ?Item{ + return clone $this->framedItem; + } + + /** + * @param Item|null $item + */ + public function setFramedItem(?Item $item) : void{ + if($item === null or $item->isNull()){ + $this->framedItem = null; + $this->itemRotation = 0; + }else{ + $this->framedItem = clone $item; } + } + + /** + * @return int + */ + public function getItemRotation() : int{ + return $this->itemRotation; + } + + /** + * @param int $itemRotation + */ + public function setItemRotation(int $itemRotation) : void{ + $this->itemRotation = $itemRotation; + } + + /** + * @return float + */ + public function getItemDropChance() : float{ + return $this->itemDropChance; + } + + /** + * @param float $itemDropChance + */ + public function setItemDropChance(float $itemDropChance) : void{ + $this->itemDropChance = $itemDropChance; + } + + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($this->framedItem !== null){ + $this->itemRotation = ($this->itemRotation + 1) % 8; + $this->itemRotation %= 8; + }elseif(!$item->isNull()){ + $this->framedItem = $item->pop(); + }else{ + return true; + } + + $this->level->setBlock($this, $this); return true; } @@ -82,13 +174,8 @@ class ItemFrame extends Flowable{ public function getDropsForCompatibleTool(Item $item) : array{ $drops = parent::getDropsForCompatibleTool($item); - - $tile = $this->level->getTile($this); - if($tile instanceof TileItemFrame){ - $tileItem = $tile->getItem(); - if(lcg_value() <= $tile->getItemDropChance() and !$tileItem->isNull()){ - $drops[] = $tileItem; - } + if($this->framedItem !== null and lcg_value() <= $this->itemDropChance){ + $drops[] = clone $this->framedItem; } return $drops; diff --git a/src/pocketmine/tile/ItemFrame.php b/src/pocketmine/tile/ItemFrame.php index cd75daeaf5..cc831a4d06 100644 --- a/src/pocketmine/tile/ItemFrame.php +++ b/src/pocketmine/tile/ItemFrame.php @@ -29,6 +29,10 @@ use pocketmine\level\Level; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; +/** + * @deprecated + * @see \pocketmine\block\ItemFrame + */ class ItemFrame extends Spawnable{ public const TAG_ITEM_ROTATION = "ItemRotation"; public const TAG_ITEM_DROP_CHANCE = "ItemDropChance"; From ff35736bf92a85a5ff5e4332f4ab34725b33d71e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Feb 2019 18:27:47 +0000 Subject: [PATCH 0531/3224] ItemFrame: added ROTATIONS constant --- src/pocketmine/block/ItemFrame.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 770a1cd4cc..68891072db 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -32,6 +32,7 @@ use pocketmine\tile\ItemFrame as TileItemFrame; use function lcg_value; class ItemFrame extends Flowable{ + public const ROTATIONS = 8; /** @var int */ protected $facing = Facing::NORTH; @@ -61,7 +62,7 @@ class ItemFrame extends Flowable{ if($this->framedItem->isNull()){ $this->framedItem = null; } - $this->itemRotation = $tile->getItemRotation() % 8; + $this->itemRotation = $tile->getItemRotation() % self::ROTATIONS; $this->itemDropChance = $tile->getItemDropChance(); } } @@ -143,8 +144,7 @@ class ItemFrame extends Flowable{ public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($this->framedItem !== null){ - $this->itemRotation = ($this->itemRotation + 1) % 8; - $this->itemRotation %= 8; + $this->itemRotation = ($this->itemRotation + 1) % self::ROTATIONS; }elseif(!$item->isNull()){ $this->framedItem = $item->pop(); }else{ From 0bd1c1529e796d211359db79ecb401ac52bdb1af Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Feb 2019 10:23:40 +0000 Subject: [PATCH 0532/3224] Block: Rename getItem() to asItem() this has clearer meaning and is less likely to collide with other things. --- src/pocketmine/block/Bed.php | 2 +- src/pocketmine/block/Block.php | 8 ++++---- src/pocketmine/block/NetherWartPlant.php | 2 +- src/pocketmine/block/Skull.php | 2 +- src/pocketmine/block/Slab.php | 2 +- src/pocketmine/block/Stem.php | 2 +- src/pocketmine/entity/object/FallingBlock.php | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index ef02373d95..cf32837d1c 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -202,7 +202,7 @@ class Bed extends Transparent{ return []; } - public function getItem() : Item{ + public function asItem() : Item{ return ItemFactory::get($this->idInfo->getItemId(), $this->color->getMagicNumber()); } diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 249502fced..fb1deb2469 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -107,7 +107,7 @@ class Block extends Position implements BlockIds, Metadatable{ return $this->idInfo->getBlockId(); } - public function getItem() : Item{ + public function asItem() : Item{ return ItemFactory::get($this->idInfo->getItemId(), $this->idInfo->getVariant()); } @@ -511,7 +511,7 @@ class Block extends Position implements BlockIds, Metadatable{ * @return Item[] */ public function getDropsForCompatibleTool(Item $item) : array{ - return [$this->getItem()]; + return [$this->asItem()]; } /** @@ -522,7 +522,7 @@ class Block extends Position implements BlockIds, Metadatable{ * @return Item[] */ public function getSilkTouchDrops(Item $item) : array{ - return [$this->getItem()]; + return [$this->asItem()]; } /** @@ -564,7 +564,7 @@ class Block extends Position implements BlockIds, Metadatable{ * @return Item */ public function getPickedItem() : Item{ - return $this->getItem(); + return $this->asItem(); } /** diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index fb2f9cb5ed..f0027de2a9 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -82,7 +82,7 @@ class NetherWartPlant extends Flowable{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - $this->getItem()->setCount($this->age === 3 ? mt_rand(2, 4) : 1) + $this->asItem()->setCount($this->age === 3 ? mt_rand(2, 4) : 1) ]; } diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index 78df03dc68..da62c2c26d 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -95,7 +95,7 @@ class Skull extends Flowable{ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - public function getItem() : Item{ + public function asItem() : Item{ return ItemFactory::get(Item::SKULL, $this->type); } diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index 75e3b6c7e8..dd7599972f 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -136,6 +136,6 @@ abstract class Slab extends Transparent{ } public function getDropsForCompatibleTool(Item $item) : array{ - return [$this->getItem()->setCount($this->slabType === SlabType::DOUBLE() ? 2 : 1)]; + return [$this->asItem()->setCount($this->slabType === SlabType::DOUBLE() ? 2 : 1)]; } } diff --git a/src/pocketmine/block/Stem.php b/src/pocketmine/block/Stem.php index 8201085c4c..295f6e7185 100644 --- a/src/pocketmine/block/Stem.php +++ b/src/pocketmine/block/Stem.php @@ -66,7 +66,7 @@ abstract class Stem extends Crops{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - $this->getItem()->setCount(mt_rand(0, 2)) + $this->asItem()->setCount(mt_rand(0, 2)) ]; } } diff --git a/src/pocketmine/entity/object/FallingBlock.php b/src/pocketmine/entity/object/FallingBlock.php index c90c9c36eb..d13a588024 100644 --- a/src/pocketmine/entity/object/FallingBlock.php +++ b/src/pocketmine/entity/object/FallingBlock.php @@ -110,7 +110,7 @@ class FallingBlock extends Entity{ $block = $this->level->getBlock($pos); if($block->getId() > 0 and $block->isTransparent() and !$block->canBeReplaced()){ //FIXME: anvils are supposed to destroy torches - $this->getLevel()->dropItem($this, $this->block->getItem()); + $this->getLevel()->dropItem($this, $this->block->asItem()); }else{ $ev = new EntityBlockChangeEvent($this, $block, $blockTarget ?? $this->block); $ev->call(); From 97687f22362bd53f56b687b4a517b5c8577737f2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Feb 2019 10:48:40 +0000 Subject: [PATCH 0533/3224] Dye, banner and bed items now store DyeColor objects instead of using magic meta values --- src/pocketmine/block/Bed.php | 5 +++- src/pocketmine/item/Banner.php | 38 +++++++++-------------------- src/pocketmine/item/Bed.php | 14 ++++++++++- src/pocketmine/item/Dye.php | 16 +++++++++++- src/pocketmine/item/ItemFactory.php | 6 ++--- src/pocketmine/tile/Banner.php | 2 +- 6 files changed, 48 insertions(+), 33 deletions(-) diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index cf32837d1c..da51227e70 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; use pocketmine\block\utils\DyeColor; +use pocketmine\item\Bed as ItemBed; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\lang\TranslationContainer; @@ -175,7 +176,9 @@ class Bed extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - $this->color = DyeColor::fromMagicNumber($item->getDamage()); //TODO: replace this with a proper colour getter + if($item instanceof ItemBed){ //TODO: the item should do this + $this->color = $item->getColor(); + } $down = $this->getSide(Facing::DOWN); if(!$down->isTransparent()){ $this->facing = $player !== null ? $player->getHorizontalFacing() : Facing::NORTH; diff --git a/src/pocketmine/item/Banner.php b/src/pocketmine/item/Banner.php index 7817469c3d..c9deb5be4e 100644 --- a/src/pocketmine/item/Banner.php +++ b/src/pocketmine/item/Banner.php @@ -34,13 +34,23 @@ use pocketmine\tile\Banner as TileBanner; use function assert; class Banner extends Item{ - public const TAG_BASE = TileBanner::TAG_BASE; public const TAG_PATTERNS = TileBanner::TAG_PATTERNS; public const TAG_PATTERN_COLOR = TileBanner::TAG_PATTERN_COLOR; public const TAG_PATTERN_NAME = TileBanner::TAG_PATTERN_NAME; - public function __construct(int $variant, string $name){ + /** @var DyeColor */ + private $color; + + public function __construct(int $variant, string $name, DyeColor $color){ parent::__construct(self::BANNER, $variant, $name); + $this->color = $color; + } + + /** + * @return DyeColor + */ + public function getColor() : DyeColor{ + return $this->color; } public function getBlock() : Block{ @@ -51,27 +61,6 @@ class Banner extends Item{ return 16; } - /** - * Returns the color of the banner base. - * - * @return DyeColor - */ - public function getBaseColor() : DyeColor{ - return DyeColor::fromMagicNumber($this->getNamedTag()->getInt(self::TAG_BASE, $this->getDamage()), true); - } - - /** - * Sets the color of the banner base. - * Banner items have to be resent to see the changes in the inventory. - * - * @param DyeColor $color - */ - public function setBaseColor(DyeColor $color) : void{ - $namedTag = $this->getNamedTag(); - $namedTag->setInt(self::TAG_BASE, $color->getInvertedMagicNumber()); - $this->setNamedTag($namedTag); - } - /** * Applies a new pattern on the banner with the given color. * Banner items have to be resent to see the changes in the inventory. @@ -224,9 +213,6 @@ class Banner extends Item{ public function correctNBT() : void{ $tag = $this->getNamedTag(); - if(!$tag->hasTag(self::TAG_BASE, IntTag::class)){ - $tag->setInt(self::TAG_BASE, DyeColor::BLACK()->getInvertedMagicNumber()); - } if(!$tag->hasTag(self::TAG_PATTERNS, ListTag::class)){ $tag->setTag(new ListTag(self::TAG_PATTERNS)); diff --git a/src/pocketmine/item/Bed.php b/src/pocketmine/item/Bed.php index b9950e360b..27eb8cab64 100644 --- a/src/pocketmine/item/Bed.php +++ b/src/pocketmine/item/Bed.php @@ -25,11 +25,23 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\utils\DyeColor; class Bed extends Item{ - public function __construct(int $variant, string $name){ + /** @var DyeColor */ + private $color; + + public function __construct(int $variant, string $name, DyeColor $color){ parent::__construct(self::BED, $variant, $name); + $this->color = $color; + } + + /** + * @return DyeColor + */ + public function getColor() : DyeColor{ + return $this->color; } public function getBlock() : Block{ diff --git a/src/pocketmine/item/Dye.php b/src/pocketmine/item/Dye.php index ee4731df64..94452d67b7 100644 --- a/src/pocketmine/item/Dye.php +++ b/src/pocketmine/item/Dye.php @@ -23,8 +23,22 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\block\utils\DyeColor; + class Dye extends Item{ - public function __construct(int $variant, string $name){ + + /** @var DyeColor */ + private $color; + + public function __construct(int $variant, string $name, DyeColor $color){ parent::__construct(self::DYE, $variant, $name); + $this->color = $color; + } + + /** + * @return DyeColor + */ + public function getColor() : DyeColor{ + return $this->color; } } diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index e1cc072f82..7527a5d999 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -245,9 +245,9 @@ class ItemFactory{ foreach(DyeColor::getAll() as $color){ //TODO: use colour object directly //TODO: add interface to dye-colour objects - self::register(new Dye($dyeMap[$color] ?? $color->getInvertedMagicNumber(), $color->getDisplayName() . " Dye")); - self::register(new Bed($color->getMagicNumber(), $color->getDisplayName() . " Bed")); - self::register(new Banner($color->getInvertedMagicNumber(), $color->getDisplayName() . " Banner")); + self::register(new Dye($dyeMap[$color] ?? $color->getInvertedMagicNumber(), $color->getDisplayName() . " Dye", $color)); + self::register(new Bed($color->getMagicNumber(), $color->getDisplayName() . " Bed", $color)); + self::register(new Banner($color->getInvertedMagicNumber(), $color->getDisplayName() . " Banner", $color)); } foreach(Potion::ALL as $type){ diff --git a/src/pocketmine/tile/Banner.php b/src/pocketmine/tile/Banner.php index c423d2e71b..33af1753ea 100644 --- a/src/pocketmine/tile/Banner.php +++ b/src/pocketmine/tile/Banner.php @@ -123,7 +123,7 @@ class Banner extends Spawnable implements Nameable{ parent::copyDataFromItem($item); $this->copyNameFromItem($item); if($item instanceof ItemBanner){ - $this->setBaseColor($item->getBaseColor()); + $this->setBaseColor($item->getColor()); if(($patterns = $item->getPatterns()) !== null){ $this->setPatterns($patterns); } From 832ad0501a7322567be681fbf1d53644d77e2dc0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Feb 2019 12:19:15 +0000 Subject: [PATCH 0534/3224] Tripwire: added missing flag it's unclear what the purpose of this flag is. It appears to always be set on placement and is never changed at any other time. The result is that the hitbox becomes larger when it is set. --- src/pocketmine/block/Tripwire.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/block/Tripwire.php b/src/pocketmine/block/Tripwire.php index 58c45a065b..23764bb6b1 100644 --- a/src/pocketmine/block/Tripwire.php +++ b/src/pocketmine/block/Tripwire.php @@ -31,16 +31,19 @@ class Tripwire extends Flowable{ /** @var bool */ protected $triggered = false; /** @var bool */ + protected $suspended = false; //unclear usage, makes hitbox bigger if set + /** @var bool */ protected $connected = false; /** @var bool */ protected $disarmed = false; protected function writeStateToMeta() : int{ - return ($this->triggered ? 0x01 : 0) | ($this->connected ? 0x04 : 0) | ($this->disarmed ? 0x08 : 0); + return ($this->triggered ? 0x01 : 0) | ($this->suspended ? 0x02: 0) | ($this->connected ? 0x04 : 0) | ($this->disarmed ? 0x08 : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ $this->triggered = ($stateMeta & 0x01) !== 0; + $this->suspended = ($stateMeta & 0x02) !== 0; $this->connected = ($stateMeta & 0x04) !== 0; $this->disarmed = ($stateMeta & 0x08) !== 0; } From 369a1e14723fdb2ce8700e7279e99219d57f400d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Feb 2019 12:41:44 +0000 Subject: [PATCH 0535/3224] Tripwire: fixed block picking --- src/pocketmine/block/BlockFactory.php | 2 +- src/pocketmine/block/Tripwire.php | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 6731ac0734..80beb07696 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -275,7 +275,7 @@ class BlockFactory{ self::register(new Torch(new BID(Block::TORCH), "Torch")); self::register(new Trapdoor(new BID(Block::TRAPDOOR), "Wooden Trapdoor")); self::register(new TrappedChest(new BID(Block::TRAPPED_CHEST, 0, null, \pocketmine\tile\Chest::class), "Trapped Chest")); - self::register(new Tripwire(new BID(Block::TRIPWIRE), "Tripwire")); + self::register(new Tripwire(new BID(Block::TRIPWIRE, 0, ItemIds::STRING), "Tripwire")); self::register(new TripwireHook(new BID(Block::TRIPWIRE_HOOK), "Tripwire Hook")); self::register(new UnderwaterTorch(new BID(Block::UNDERWATER_TORCH), "Underwater Torch")); self::register(new Vine(new BID(Block::VINE), "Vines")); diff --git a/src/pocketmine/block/Tripwire.php b/src/pocketmine/block/Tripwire.php index 23764bb6b1..aa51787227 100644 --- a/src/pocketmine/block/Tripwire.php +++ b/src/pocketmine/block/Tripwire.php @@ -23,9 +23,6 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\Item; -use pocketmine\item\ItemFactory; - class Tripwire extends Flowable{ /** @var bool */ @@ -52,12 +49,6 @@ class Tripwire extends Flowable{ return 0b1111; } - public function getDropsForCompatibleTool(Item $item) : array{ - return [ - ItemFactory::get(Item::STRING) - ]; - } - public function isAffectedBySilkTouch() : bool{ return false; } From 899081e1b989717c93ec4c9454121c597dfdebaa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Feb 2019 13:10:45 +0000 Subject: [PATCH 0536/3224] Level: fixed randomTickBlocks, also delete some useless code the randomTickBlocks thing is populated with state IDs anyway, not variants... --- src/pocketmine/block/BlockFactory.php | 10 ---------- src/pocketmine/level/Level.php | 2 +- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 80beb07696..939a259318 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -51,9 +51,6 @@ class BlockFactory{ /** @var \SplFixedArray */ public static $blastResistance = null; - /** @var \SplFixedArray|int[] */ - private static $stateMasks = null; - /** @var int[] */ public static $staticRuntimeIdMap = []; @@ -74,8 +71,6 @@ class BlockFactory{ self::$diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 8192, false)); self::$blastResistance = \SplFixedArray::fromArray(array_fill(0, 8192, 0)); - self::$stateMasks = new \SplFixedArray(8192); - self::register(new ActivatorRail(new BID(Block::ACTIVATOR_RAIL, BaseRail::STRAIGHT_NORTH_SOUTH), "Activator Rail")); self::register(new Air(new BID(Block::AIR), "Air")); self::register(new Anvil(new BID(Block::ANVIL, Anvil::TYPE_NORMAL), "Anvil")); @@ -575,7 +570,6 @@ class BlockFactory{ private static function fillStaticArrays(int $index, Block $block) : void{ self::$fullList[$index] = $block; - self::$stateMasks[$index] = $block->getStateBitmask(); self::$lightFilter[$index] = min(15, $block->getLightFilter() + 1); //opacity plus 1 standard light filter self::$diffusesSkyLight[$index] = $block->diffusesSkyLight(); self::$blastResistance[$index] = $block->getBlastResistance(); @@ -621,10 +615,6 @@ class BlockFactory{ return self::get($fullState >> 4, $fullState & 0xf, $pos); } - public static function getStateMask(int $id) : int{ - return self::$stateMasks[$id] ?? 0; - } - /** * Returns whether a specified block state is already registered in the block factory. * diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 4a3c52489a..7d4f06a89d 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1085,7 +1085,7 @@ class Level implements ChunkManager, Metadatable{ $state = $subChunk->getFullBlock($x, $y, $z); - if($this->randomTickBlocks[$state & ~BlockFactory::getStateMask($state >> 4)]){ + if($this->randomTickBlocks[$state]){ /** @var Block $block */ $block = BlockFactory::fromFullBlock($state, $this->temporalPosition->setComponents( $chunkX * 16 + $x, From 73305a7425b8def74011753f68b20d09578e1d74 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Feb 2019 13:22:11 +0000 Subject: [PATCH 0537/3224] oops, formatting issue --- src/pocketmine/block/Tripwire.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/Tripwire.php b/src/pocketmine/block/Tripwire.php index aa51787227..3b68142ac4 100644 --- a/src/pocketmine/block/Tripwire.php +++ b/src/pocketmine/block/Tripwire.php @@ -35,7 +35,7 @@ class Tripwire extends Flowable{ protected $disarmed = false; protected function writeStateToMeta() : int{ - return ($this->triggered ? 0x01 : 0) | ($this->suspended ? 0x02: 0) | ($this->connected ? 0x04 : 0) | ($this->disarmed ? 0x08 : 0); + return ($this->triggered ? 0x01 : 0) | ($this->suspended ? 0x02 : 0) | ($this->connected ? 0x04 : 0) | ($this->disarmed ? 0x08 : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ From 6edd4fd9c79c6deb21adfaad284ef77cdaa5c893 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Feb 2019 13:40:59 +0000 Subject: [PATCH 0538/3224] BlockFactory: added getAllKnownStates() --- src/pocketmine/block/BlockFactory.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 939a259318..825567fef8 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -31,6 +31,7 @@ use pocketmine\block\utils\TreeType; use pocketmine\item\ItemIds; use pocketmine\level\Position; use function array_fill; +use function array_filter; use function file_get_contents; use function get_class; use function json_decode; @@ -675,4 +676,11 @@ class BlockFactory{ self::$legacyIdMap[$staticRuntimeId] = ($legacyId << 4) | $legacyMeta; self::$lastRuntimeId = max(self::$lastRuntimeId, $staticRuntimeId); } + + /** + * @return Block[] + */ + public static function getAllKnownStates() : array{ + return array_filter(self::$fullList->toArray(), function(?Block $v) : bool{ return $v !== null; }); + } } From 023fecabac560ef99756529405375acda437d1e4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Feb 2019 13:56:55 +0000 Subject: [PATCH 0539/3224] Added an annoying consistency check for BlockFactory This test is intended to enforce that the BlockFactory always has the same blocks in it from one commit to the next. Since there are a lot of changes going on right now around this, it's important that this is checked because bugs can go under the radar when large changes are happening. The consistency check will need to be regenerated whenever a new block is registered, new states are found or when things are removed. --- tests/phpunit/block/BlockTest.php | 13 +++++++ .../block_factory_consistency_check.json | 1 + .../block/regenerate_consistency_check.php | 36 +++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 tests/phpunit/block/block_factory_consistency_check.json create mode 100644 tests/phpunit/block/regenerate_consistency_check.php diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index c6b68fd134..0551ab9b62 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -24,6 +24,8 @@ declare(strict_types=1); namespace pocketmine\block; use PHPUnit\Framework\TestCase; +use function file_get_contents; +use function json_decode; class BlockTest extends TestCase{ @@ -138,4 +140,15 @@ class BlockTest extends TestCase{ self::assertGreaterThan(0, $value, "Light filter value for $id must be larger than 0"); } } + + public function testConsistency() : void{ + $list = json_decode(file_get_contents(__DIR__ . '/block_factory_consistency_check.json'), true); + $states = BlockFactory::getAllKnownStates(); + foreach($states as $k => $state){ + self::assertArrayHasKey($k, $list, "New block state $k (" . $state->getName() . ") - consistency check may need regenerating"); + } + foreach($list as $k => $name){ + self::assertArrayHasKey($k, $states, "Missing previously-known block state $k ($name)"); + } + } } diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json new file mode 100644 index 0000000000..273fba13ec --- /dev/null +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -0,0 +1 @@ +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","752":"Bookshelf","768":"Moss Stone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Sign Post","1009":"Sign Post","1010":"Sign Post","1011":"Sign Post","1012":"Sign Post","1013":"Sign Post","1014":"Sign Post","1015":"Sign Post","1016":"Sign Post","1017":"Sign Post","1018":"Sign Post","1019":"Sign Post","1020":"Sign Post","1021":"Sign Post","1022":"Sign Post","1023":"Sign Post","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Wall Sign","1090":"Wall Sign","1091":"Wall Sign","1092":"Wall Sign","1093":"Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Wooden Pressure Plate","1153":"Wooden Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Wooden Trapdoor","1537":"Wooden Trapdoor","1538":"Wooden Trapdoor","1539":"Wooden Trapdoor","1540":"Wooden Trapdoor","1541":"Wooden Trapdoor","1542":"Wooden Trapdoor","1543":"Wooden Trapdoor","1544":"Wooden Trapdoor","1545":"Wooden Trapdoor","1546":"Wooden Trapdoor","1547":"Wooden Trapdoor","1548":"Wooden Trapdoor","1549":"Wooden Trapdoor","1550":"Wooden Trapdoor","1551":"Wooden Trapdoor","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Wooden Button","2289":"Wooden Button","2290":"Wooden Button","2291":"Wooden Button","2292":"Wooden Button","2293":"Wooden Button","2296":"Wooden Button","2297":"Wooden Button","2298":"Wooden Button","2299":"Wooden Button","2300":"Wooden Button","2301":"Wooden Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Standing Banner","2817":"Standing Banner","2818":"Standing Banner","2819":"Standing Banner","2820":"Standing Banner","2821":"Standing Banner","2822":"Standing Banner","2823":"Standing Banner","2824":"Standing Banner","2825":"Standing Banner","2826":"Standing Banner","2827":"Standing Banner","2828":"Standing Banner","2829":"Standing Banner","2830":"Standing Banner","2831":"Standing Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6"} \ No newline at end of file diff --git a/tests/phpunit/block/regenerate_consistency_check.php b/tests/phpunit/block/regenerate_consistency_check.php new file mode 100644 index 0000000000..0f5cec065f --- /dev/null +++ b/tests/phpunit/block/regenerate_consistency_check.php @@ -0,0 +1,36 @@ +getName(); + }, + \pocketmine\block\BlockFactory::getAllKnownStates() + ) +)); From b7b05e729e4fcfbe74786342882d011f004658fa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Feb 2019 14:42:53 +0000 Subject: [PATCH 0540/3224] Block: Get rid of state bitmasks This story dates back to the days when getVariantBitmask() was introduced. The purpose of this function was to allow the variant info to be extracted from the metadata, for use with item drops. This was later changed to state bitmask for reasons I don't clearly recall. In the great 4.0 refactor, we now store variant magic numbers separately, so we don't need any generic bitmask to split up variant and state information anymore. Variant is now only ever serialized and never deserialized. The same thing goes for blockIDs. States are read from the world by matching the full stateID against a table of prefilled known blocks, so the variant doesn't need to be deserialized - only the state does, and the state metadata readers already do bit fuckery by themselves and don't need this mask - notice how little actual changes were required to get rid of this? --- src/pocketmine/block/Anvil.php | 6 +--- src/pocketmine/block/BaseRail.php | 4 --- src/pocketmine/block/Bed.php | 4 --- src/pocketmine/block/Block.php | 18 +----------- src/pocketmine/block/BlockFactory.php | 28 +++++-------------- src/pocketmine/block/BrewingStand.php | 4 --- src/pocketmine/block/Button.php | 4 --- src/pocketmine/block/Cactus.php | 4 --- src/pocketmine/block/Cake.php | 4 --- src/pocketmine/block/Chest.php | 4 --- src/pocketmine/block/CocoaBlock.php | 4 --- src/pocketmine/block/Crops.php | 4 --- src/pocketmine/block/DaylightSensor.php | 4 --- src/pocketmine/block/Door.php | 4 --- src/pocketmine/block/DoublePlant.php | 4 --- src/pocketmine/block/EndPortalFrame.php | 4 --- src/pocketmine/block/EndRod.php | 4 --- src/pocketmine/block/Farmland.php | 4 --- src/pocketmine/block/FenceGate.php | 4 --- src/pocketmine/block/Fire.php | 4 --- src/pocketmine/block/FlowerPot.php | 4 --- src/pocketmine/block/Furnace.php | 4 --- src/pocketmine/block/GlazedTerracotta.php | 4 --- src/pocketmine/block/ItemFrame.php | 4 --- src/pocketmine/block/Ladder.php | 4 --- src/pocketmine/block/Leaves.php | 4 --- src/pocketmine/block/Lever.php | 4 --- src/pocketmine/block/Liquid.php | 4 --- src/pocketmine/block/NetherReactor.php | 4 --- src/pocketmine/block/NetherWartPlant.php | 4 --- src/pocketmine/block/Pumpkin.php | 4 --- src/pocketmine/block/RedMushroomBlock.php | 4 --- src/pocketmine/block/RedstoneRepeater.php | 4 --- src/pocketmine/block/RedstoneWire.php | 4 --- src/pocketmine/block/Sapling.php | 4 --- src/pocketmine/block/SignPost.php | 4 --- src/pocketmine/block/SimplePressurePlate.php | 4 --- src/pocketmine/block/Skull.php | 4 --- src/pocketmine/block/Slab.php | 4 --- src/pocketmine/block/SnowLayer.php | 4 --- src/pocketmine/block/Sponge.php | 4 --- src/pocketmine/block/Stair.php | 4 --- src/pocketmine/block/StandingBanner.php | 4 --- src/pocketmine/block/Sugarcane.php | 4 --- src/pocketmine/block/Torch.php | 5 +--- src/pocketmine/block/Trapdoor.php | 4 --- src/pocketmine/block/Tripwire.php | 4 --- src/pocketmine/block/TripwireHook.php | 4 --- src/pocketmine/block/Vine.php | 4 --- src/pocketmine/block/WallBanner.php | 4 --- src/pocketmine/block/WallSign.php | 4 --- .../block/WeightedPressurePlate.php | 4 --- .../block/utils/PillarRotationTrait.php | 8 ------ 53 files changed, 10 insertions(+), 247 deletions(-) diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index 23ad43911e..dc81bcc078 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -50,11 +50,7 @@ class Anvil extends Transparent implements Fallable{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta); - } - - public function getStateBitmask() : int{ - return 0b11; + $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); } public function getHardness() : float{ diff --git a/src/pocketmine/block/BaseRail.php b/src/pocketmine/block/BaseRail.php index 3dfb543ed9..6fb66260fd 100644 --- a/src/pocketmine/block/BaseRail.php +++ b/src/pocketmine/block/BaseRail.php @@ -95,10 +95,6 @@ abstract class BaseRail extends Flowable{ $this->connections = $connections; } - public function getStateBitmask() : int{ - return 0b1111; - } - public function getHardness() : float{ return 0.7; } diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index da51227e70..74b245c516 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -68,10 +68,6 @@ class Bed extends Transparent{ $this->head = ($stateMeta & self::BITFLAG_HEAD) !== 0; } - public function getStateBitmask() : int{ - return 0b1111; - } - public function readStateFromWorld() : void{ parent::readStateFromWorld(); //read extra state information from the tile - this is an ugly hack diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index fb1deb2469..4f63c4f72e 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -43,8 +43,6 @@ use pocketmine\Player; use pocketmine\plugin\Plugin; use pocketmine\tile\TileFactory; use function array_merge; -use function assert; -use function dechex; use function get_class; use const PHP_INT_MAX; @@ -82,9 +80,6 @@ class Block extends Position implements BlockIds, Metadatable{ * @param string $name English name of the block type (TODO: implement translations) */ public function __construct(BlockIdentifier $idInfo, string $name){ - if(($idInfo->getVariant() & $this->getStateBitmask()) !== 0){ - throw new \InvalidArgumentException("Variant 0x" . dechex($idInfo->getVariant()) . " collides with state bitmask 0x" . dechex($this->getStateBitmask())); - } $this->idInfo = $idInfo; $this->fallbackName = $name; } @@ -123,9 +118,7 @@ class Block extends Position implements BlockIds, Metadatable{ * @return int */ public function getDamage() : int{ - $stateMeta = $this->writeStateToMeta(); - assert(($stateMeta & ~$this->getStateBitmask()) === 0); - return $this->idInfo->getVariant() | $stateMeta; + return $this->idInfo->getVariant() | $this->writeStateToMeta(); } protected function writeStateToMeta() : int{ @@ -168,15 +161,6 @@ class Block extends Position implements BlockIds, Metadatable{ } } - /** - * Returns a bitmask used to extract state bits from block metadata. - * - * @return int - */ - public function getStateBitmask() : int{ - return 0; - } - /** * Returns whether the given block has an equivalent type to this one. This compares base legacy ID and variant. * diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 825567fef8..818a124575 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -527,32 +527,13 @@ class BlockFactory{ * $override parameter. */ public static function register(Block $block, bool $override = false) : void{ - $variant = $block->getIdInfo()->getVariant(); - - $stateMask = $block->getStateBitmask(); - if(($variant & $stateMask) !== 0){ - throw new \InvalidArgumentException("Block variant collides with state bitmask"); - } - foreach($block->getIdInfo()->getAllBlockIds() as $id){ - if(!$override and self::isRegistered($id, $variant)){ - throw new \InvalidArgumentException("Block registration $id:$variant conflicts with an existing block"); - } - - for($m = $variant; $m <= ($variant | $stateMask); ++$m){ - if(($m & ~$stateMask) !== $variant){ - continue; - } - - if(!$override and self::isRegistered($id, $m)){ - throw new \InvalidArgumentException("Block registration " . get_class($block) . " has states which conflict with other blocks"); - } - + for($m = 0; $m < 16; ++$m){ $index = ($id << 4) | $m; $v = clone $block; try{ - $v->readStateFromData($id, $m & $stateMask); + $v->readStateFromData($id, $m); if($v->getDamage() !== $m){ throw new InvalidBlockStateException("Corrupted meta"); //don't register anything that isn't the same when we read it back again } @@ -560,9 +541,14 @@ class BlockFactory{ continue; } + if(!$override and self::isRegistered($id, $m)){ + throw new \InvalidArgumentException("Block registration " . get_class($block) . " has states which conflict with other blocks"); + } + self::fillStaticArrays($index, $v); } + $variant = $block->getIdInfo()->getVariant(); if(!self::isRegistered($id, $variant)){ self::fillStaticArrays(($id << 4) | $variant, $block); //register default state mapped to variant, for blocks which don't use 0 as valid state } diff --git a/src/pocketmine/block/BrewingStand.php b/src/pocketmine/block/BrewingStand.php index f9833823b1..775b2ba008 100644 --- a/src/pocketmine/block/BrewingStand.php +++ b/src/pocketmine/block/BrewingStand.php @@ -44,10 +44,6 @@ class BrewingStand extends Transparent{ $this->northwestSlot = ($stateMeta & 0x04) !== 0; } - public function getStateBitmask() : int{ - return 0b111; - } - public function getHardness() : float{ return 0.5; } diff --git a/src/pocketmine/block/Button.php b/src/pocketmine/block/Button.php index 1ff2484147..b05f94e7ae 100644 --- a/src/pocketmine/block/Button.php +++ b/src/pocketmine/block/Button.php @@ -47,10 +47,6 @@ abstract class Button extends Flowable{ $this->powered = ($stateMeta & 0x08) !== 0; } - public function getStateBitmask() : int{ - return 0b1111; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ //TODO: check valid target block $this->facing = $face; diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index dcf9655200..381c96174f 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -47,10 +47,6 @@ class Cactus extends Transparent{ $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 15); } - public function getStateBitmask() : int{ - return 0b1111; - } - public function getHardness() : float{ return 0.4; } diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index 335f0f6447..0e98fa117f 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -46,10 +46,6 @@ class Cake extends Transparent implements FoodSource{ $this->bites = BlockDataValidator::readBoundedInt("bites", $stateMeta, 0, 6); } - public function getStateBitmask() : int{ - return 0b111; - } - public function getHardness() : float{ return 0.5; } diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index 757e67c3dc..4c18414cfd 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -44,10 +44,6 @@ class Chest extends Transparent{ $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); } - public function getStateBitmask() : int{ - return 0b111; - } - public function getHardness() : float{ return 2.5; } diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index 0046d27aab..46c654c791 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -51,10 +51,6 @@ class CocoaBlock extends Transparent{ $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta >> 2, 0, 2); } - public function getStateBitmask() : int{ - return 0b1111; - } - public function getHardness() : float{ return 0.2; } diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index 2586d9109e..45f49b74b3 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -44,10 +44,6 @@ abstract class Crops extends Flowable{ $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 7); } - public function getStateBitmask() : int{ - return 0b111; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($blockReplace->getSide(Facing::DOWN)->getId() === Block::FARMLAND){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/DaylightSensor.php b/src/pocketmine/block/DaylightSensor.php index a379c5f146..c6806f98c3 100644 --- a/src/pocketmine/block/DaylightSensor.php +++ b/src/pocketmine/block/DaylightSensor.php @@ -57,10 +57,6 @@ class DaylightSensor extends Transparent{ $this->inverted = $id === $this->idInfo->getSecondId(); } - public function getStateBitmask() : int{ - return 0b1111; - } - public function isInverted() : bool{ return $this->inverted; } diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 39e56e5f8c..ac9d689f5f 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -67,10 +67,6 @@ abstract class Door extends Transparent{ } } - public function getStateBitmask() : int{ - return 0b1111; - } - public function readStateFromWorld() : void{ parent::readStateFromWorld(); diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index a9dd48ee0f..3b4151890a 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -43,10 +43,6 @@ class DoublePlant extends Flowable{ $this->top = ($stateMeta & self::BITFLAG_TOP) !== 0; } - public function getStateBitmask() : int{ - return 0b1000; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $id = $blockReplace->getSide(Facing::DOWN)->getId(); if(($id === Block::GRASS or $id === Block::DIRT) and $blockReplace->getSide(Facing::UP)->canBeReplaced()){ diff --git a/src/pocketmine/block/EndPortalFrame.php b/src/pocketmine/block/EndPortalFrame.php index aebdc7b477..53b7cc73f6 100644 --- a/src/pocketmine/block/EndPortalFrame.php +++ b/src/pocketmine/block/EndPortalFrame.php @@ -47,10 +47,6 @@ class EndPortalFrame extends Solid{ $this->eye = ($stateMeta & 0x04) !== 0; } - public function getStateBitmask() : int{ - return 0b111; - } - public function getLightLevel() : int{ return 1; } diff --git a/src/pocketmine/block/EndRod.php b/src/pocketmine/block/EndRod.php index 1290815382..03f7622722 100644 --- a/src/pocketmine/block/EndRod.php +++ b/src/pocketmine/block/EndRod.php @@ -50,10 +50,6 @@ class EndRod extends Flowable{ $this->facing = BlockDataValidator::readFacing($stateMeta); } - public function getStateBitmask() : int{ - return 0b111; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->facing = $face; if($blockClicked instanceof EndRod and $blockClicked->facing === $this->facing){ diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index 32d9079907..022bde450d 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -42,10 +42,6 @@ class Farmland extends Transparent{ $this->wetness = BlockDataValidator::readBoundedInt("wetness", $stateMeta, 0, 7); } - public function getStateBitmask() : int{ - return 0b111; - } - public function getHardness() : float{ return 0.6; } diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index b26152064e..0526b36897 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -50,10 +50,6 @@ class FenceGate extends Transparent{ $this->inWall = ($stateMeta & 0x08) !== 0; } - public function getStateBitmask() : int{ - return 0b1111; - } - public function getHardness() : float{ return 2; } diff --git a/src/pocketmine/block/Fire.php b/src/pocketmine/block/Fire.php index faa722df4e..5e79668b3b 100644 --- a/src/pocketmine/block/Fire.php +++ b/src/pocketmine/block/Fire.php @@ -48,10 +48,6 @@ class Fire extends Flowable{ $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 15); } - public function getStateBitmask() : int{ - return 0b1111; - } - public function hasEntityCollision() : bool{ return true; } diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 057827e65c..297fe13361 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -43,10 +43,6 @@ class FlowerPot extends Flowable{ $this->occupied = $stateMeta !== 0; } - public function getStateBitmask() : int{ - return 0b1111; //vanilla uses various values, we only care about 1 and 0 for PE - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ return AxisAlignedBB::one()->contract(3 / 16, 0, 3 / 16)->trim(Facing::UP, 5 / 8); } diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index a407aa75d4..595f2c1097 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -53,10 +53,6 @@ class Furnace extends Solid{ $this->lit = $id === $this->idInfo->getSecondId(); } - public function getStateBitmask() : int{ - return 0b111; - } - public function getHardness() : float{ return 3.5; } diff --git a/src/pocketmine/block/GlazedTerracotta.php b/src/pocketmine/block/GlazedTerracotta.php index a3f4957ba9..173d17d9ef 100644 --- a/src/pocketmine/block/GlazedTerracotta.php +++ b/src/pocketmine/block/GlazedTerracotta.php @@ -44,10 +44,6 @@ class GlazedTerracotta extends Solid{ $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); } - public function getStateBitmask() : int{ - return 0b111; - } - public function getHardness() : float{ return 1.4; } diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 68891072db..7faef10528 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -77,10 +77,6 @@ class ItemFrame extends Flowable{ } } - public function getStateBitmask() : int{ - return 0b111; - } - /** * @return int */ diff --git a/src/pocketmine/block/Ladder.php b/src/pocketmine/block/Ladder.php index e5589279e9..9d9c38b9df 100644 --- a/src/pocketmine/block/Ladder.php +++ b/src/pocketmine/block/Ladder.php @@ -44,10 +44,6 @@ class Ladder extends Transparent{ $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); } - public function getStateBitmask() : int{ - return 0b111; - } - public function hasEntityCollision() : bool{ return true; } diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 563f378e3b..41ba257f7e 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -56,10 +56,6 @@ class Leaves extends Transparent{ $this->checkDecay = ($stateMeta & 0x08) !== 0; } - public function getStateBitmask() : int{ - return 0b1100; - } - public function getHardness() : float{ return 0.2; } diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index 458fb89329..0221a30ac0 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -69,10 +69,6 @@ class Lever extends Flowable{ $this->powered = ($stateMeta & 0x08) !== 0; } - public function getStateBitmask() : int{ - return 0b1111; - } - public function getHardness() : float{ return 0.5; } diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index cb98b7ca83..3be306f145 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -77,10 +77,6 @@ abstract class Liquid extends Transparent{ $this->still = $id === $this->idInfo->getSecondId(); } - public function getStateBitmask() : int{ - return 0b1111; - } - public function hasEntityCollision() : bool{ return true; } diff --git a/src/pocketmine/block/NetherReactor.php b/src/pocketmine/block/NetherReactor.php index 3a90117e83..b7cd4eab53 100644 --- a/src/pocketmine/block/NetherReactor.php +++ b/src/pocketmine/block/NetherReactor.php @@ -44,10 +44,6 @@ class NetherReactor extends Solid{ $this->state = BlockDataValidator::readBoundedInt("state", $stateMeta, 0, 2); } - public function getStateBitmask() : int{ - return 0b11; - } - public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index f0027de2a9..7c7461af1c 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -45,10 +45,6 @@ class NetherWartPlant extends Flowable{ $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 3); } - public function getStateBitmask() : int{ - return 0b11; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === Block::SOUL_SAND){ diff --git a/src/pocketmine/block/Pumpkin.php b/src/pocketmine/block/Pumpkin.php index 0f760987fd..58e604463d 100644 --- a/src/pocketmine/block/Pumpkin.php +++ b/src/pocketmine/block/Pumpkin.php @@ -43,10 +43,6 @@ class Pumpkin extends Solid{ return Bearing::fromFacing($this->facing); } - public function getStateBitmask() : int{ - return 0b11; - } - public function getHardness() : float{ return 1; } diff --git a/src/pocketmine/block/RedMushroomBlock.php b/src/pocketmine/block/RedMushroomBlock.php index 7e2bbf48ea..166e5cb4ee 100644 --- a/src/pocketmine/block/RedMushroomBlock.php +++ b/src/pocketmine/block/RedMushroomBlock.php @@ -45,10 +45,6 @@ class RedMushroomBlock extends Solid{ $this->rotationData = $stateMeta; } - public function getStateBitmask() : int{ - return 0b1111; - } - public function getHardness() : float{ return 0.2; } diff --git a/src/pocketmine/block/RedstoneRepeater.php b/src/pocketmine/block/RedstoneRepeater.php index ab16eead22..d48926e5e1 100644 --- a/src/pocketmine/block/RedstoneRepeater.php +++ b/src/pocketmine/block/RedstoneRepeater.php @@ -60,10 +60,6 @@ class RedstoneRepeater extends Flowable{ return Bearing::fromFacing($this->facing) | (($this->delay - 1) << 2); } - public function getStateBitmask() : int{ - return 0b1111; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ return AxisAlignedBB::one()->trim(Facing::UP, 7 / 8); } diff --git a/src/pocketmine/block/RedstoneWire.php b/src/pocketmine/block/RedstoneWire.php index 6f95e906b4..677f0b3a4f 100644 --- a/src/pocketmine/block/RedstoneWire.php +++ b/src/pocketmine/block/RedstoneWire.php @@ -38,10 +38,6 @@ class RedstoneWire extends Flowable{ return $this->power; } - public function getStateBitmask() : int{ - return 0b1111; - } - public function readStateFromWorld() : void{ parent::readStateFromWorld(); //TODO: check connections to nearby redstone components diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index 0b725ffab8..80e82b7507 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -53,10 +53,6 @@ class Sapling extends Flowable{ $this->ready = ($stateMeta & 0x08) !== 0; } - public function getStateBitmask() : int{ - return 0b1000; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === self::GRASS or $down->getId() === self::DIRT or $down->getId() === self::FARMLAND){ diff --git a/src/pocketmine/block/SignPost.php b/src/pocketmine/block/SignPost.php index 1470fea51a..53f3331027 100644 --- a/src/pocketmine/block/SignPost.php +++ b/src/pocketmine/block/SignPost.php @@ -43,10 +43,6 @@ class SignPost extends Transparent{ $this->rotation = $stateMeta; } - public function getStateBitmask() : int{ - return 0b1111; - } - public function getHardness() : float{ return 1; } diff --git a/src/pocketmine/block/SimplePressurePlate.php b/src/pocketmine/block/SimplePressurePlate.php index 7ffb9a7748..79205d5d59 100644 --- a/src/pocketmine/block/SimplePressurePlate.php +++ b/src/pocketmine/block/SimplePressurePlate.php @@ -35,8 +35,4 @@ abstract class SimplePressurePlate extends PressurePlate{ public function readStateFromData(int $id, int $stateMeta) : void{ $this->powered = $stateMeta !== 0; } - - public function getStateBitmask() : int{ - return 0b1; - } } diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index da62c2c26d..4de79e1f0e 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -50,10 +50,6 @@ class Skull extends Flowable{ $this->facing = $stateMeta === 1 ? Facing::UP : BlockDataValidator::readHorizontalFacing($stateMeta); } - public function getStateBitmask() : int{ - return 0b111; - } - public function readStateFromWorld() : void{ parent::readStateFromWorld(); $tile = $this->level->getTile($this); diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index dd7599972f..078c39bf35 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -61,10 +61,6 @@ abstract class Slab extends Transparent{ } } - public function getStateBitmask() : int{ - return 0b1000; - } - public function isTransparent() : bool{ return $this->slabType !== SlabType::DOUBLE(); } diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index e80b18cf82..ff9ff49b91 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -50,10 +50,6 @@ class SnowLayer extends Flowable implements Fallable{ $this->layers = BlockDataValidator::readBoundedInt("layers", $stateMeta + 1, 1, 8); } - public function getStateBitmask() : int{ - return 0b111; - } - public function canBeReplaced() : bool{ return $this->layers < 8; } diff --git a/src/pocketmine/block/Sponge.php b/src/pocketmine/block/Sponge.php index f72ec0b7b7..402f938f89 100644 --- a/src/pocketmine/block/Sponge.php +++ b/src/pocketmine/block/Sponge.php @@ -37,10 +37,6 @@ class Sponge extends Solid{ $this->wet = $stateMeta !== 0; } - public function getStateBitmask() : int{ - return 0b1; - } - public function getHardness() : float{ return 0.6; } diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index a66ef1d11d..df2af2a3ff 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -53,10 +53,6 @@ abstract class Stair extends Transparent{ $this->upsideDown = ($stateMeta & 0x04) !== 0; } - public function getStateBitmask() : int{ - return 0b111; - } - public function readStateFromWorld() : void{ parent::readStateFromWorld(); diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index e20490fbb8..53603b471c 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -46,10 +46,6 @@ class StandingBanner extends Transparent{ $this->rotation = $stateMeta; } - public function getStateBitmask() : int{ - return 0b1111; - } - public function getHardness() : float{ return 1; } diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index 6a02812130..2bf55b58bb 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -44,10 +44,6 @@ class Sugarcane extends Flowable{ $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 15); } - public function getStateBitmask() : int{ - return 0b1111; - } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof Fertilizer){ if($this->getSide(Facing::DOWN)->getId() !== self::SUGARCANE_BLOCK){ diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index 7e076f7c57..bd97b94b90 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -39,13 +39,10 @@ class Torch extends Flowable{ } public function readStateFromData(int $id, int $stateMeta) : void{ + $stateMeta &= 0x07; $this->facing = $stateMeta === 5 ? Facing::UP : BlockDataValidator::readHorizontalFacing(6 - $stateMeta); } - public function getStateBitmask() : int{ - return 0b111; - } - public function getLightLevel() : int{ return 14; } diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index 1cc736894d..d3cacbd899 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -54,10 +54,6 @@ class Trapdoor extends Transparent{ $this->open = ($stateMeta & self::MASK_OPENED) !== 0; } - public function getStateBitmask() : int{ - return 0b1111; - } - public function getHardness() : float{ return 3; } diff --git a/src/pocketmine/block/Tripwire.php b/src/pocketmine/block/Tripwire.php index 3b68142ac4..e82c15d522 100644 --- a/src/pocketmine/block/Tripwire.php +++ b/src/pocketmine/block/Tripwire.php @@ -45,10 +45,6 @@ class Tripwire extends Flowable{ $this->disarmed = ($stateMeta & 0x08) !== 0; } - public function getStateBitmask() : int{ - return 0b1111; - } - public function isAffectedBySilkTouch() : bool{ return false; } diff --git a/src/pocketmine/block/TripwireHook.php b/src/pocketmine/block/TripwireHook.php index b91887f36b..7f9770530b 100644 --- a/src/pocketmine/block/TripwireHook.php +++ b/src/pocketmine/block/TripwireHook.php @@ -49,10 +49,6 @@ class TripwireHook extends Flowable{ $this->powered = ($stateMeta & 0x08) !== 0; } - public function getStateBitmask() : int{ - return 0b1111; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(Facing::axis($face) !== Facing::AXIS_Y){ //TODO: check face is valid diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index 27b59636a9..44a6b206ac 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -57,10 +57,6 @@ class Vine extends Flowable{ $this->setFaceFromMeta($stateMeta, self::FLAG_EAST, Facing::EAST); } - public function getStateBitmask() : int{ - return 0b1111; - } - private function setFaceFromMeta(int $meta, int $flag, int $face) : void{ if(($meta & $flag) !== 0){ $this->faces[$face] = true; diff --git a/src/pocketmine/block/WallBanner.php b/src/pocketmine/block/WallBanner.php index 7acdba5b78..ede176c85d 100644 --- a/src/pocketmine/block/WallBanner.php +++ b/src/pocketmine/block/WallBanner.php @@ -39,10 +39,6 @@ class WallBanner extends StandingBanner{ $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); } - public function getStateBitmask() : int{ - return 0b111; - } - public function onNearbyBlockChange() : void{ if($this->getSide(Facing::opposite($this->facing))->getId() === self::AIR){ $this->getLevel()->useBreakOn($this); diff --git a/src/pocketmine/block/WallSign.php b/src/pocketmine/block/WallSign.php index 79f85999af..cf2c615aa4 100644 --- a/src/pocketmine/block/WallSign.php +++ b/src/pocketmine/block/WallSign.php @@ -39,10 +39,6 @@ class WallSign extends SignPost{ $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); } - public function getStateBitmask() : int{ - return 0b111; - } - public function onNearbyBlockChange() : void{ if($this->getSide(Facing::opposite($this->facing))->getId() === self::AIR){ $this->getLevel()->useBreakOn($this); diff --git a/src/pocketmine/block/WeightedPressurePlate.php b/src/pocketmine/block/WeightedPressurePlate.php index fb3c00051b..7c3d310c15 100644 --- a/src/pocketmine/block/WeightedPressurePlate.php +++ b/src/pocketmine/block/WeightedPressurePlate.php @@ -37,8 +37,4 @@ abstract class WeightedPressurePlate extends PressurePlate{ public function readStateFromData(int $id, int $stateMeta) : void{ $this->power = BlockDataValidator::readBoundedInt("power", $stateMeta, 0, 15); } - - public function getStateBitmask() : int{ - return 0b1111; - } } diff --git a/src/pocketmine/block/utils/PillarRotationTrait.php b/src/pocketmine/block/utils/PillarRotationTrait.php index 7113ae764e..5ddc5fc12a 100644 --- a/src/pocketmine/block/utils/PillarRotationTrait.php +++ b/src/pocketmine/block/utils/PillarRotationTrait.php @@ -52,14 +52,6 @@ trait PillarRotationTrait{ $this->readAxisFromMeta($stateMeta); } - /** - * @see Block::getStateBitmask() - * @return int - */ - public function getStateBitmask() : int{ - return 0b1100; - } - protected function readAxisFromMeta(int $meta) : void{ static $map = [ 0 => Facing::AXIS_Y, From 6cb263fcca414bca04a01d309a4454feca426b4a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Feb 2019 17:59:09 +0000 Subject: [PATCH 0541/3224] BlockFactory: enforce stricter checks this can help catch out variant-related bugs. --- tests/phpunit/block/BlockTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index 0551ab9b62..5931f9c2bb 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -146,9 +146,11 @@ class BlockTest extends TestCase{ $states = BlockFactory::getAllKnownStates(); foreach($states as $k => $state){ self::assertArrayHasKey($k, $list, "New block state $k (" . $state->getName() . ") - consistency check may need regenerating"); + self::assertSame($list[$k], $state->getName()); } foreach($list as $k => $name){ self::assertArrayHasKey($k, $states, "Missing previously-known block state $k ($name)"); + self::assertSame($name, $states[$k]->getName()); } } } From 0f7f5362b84b317face28baa7eb7ce73faf99dd3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Feb 2019 18:30:18 +0000 Subject: [PATCH 0542/3224] Revert "Block: Get rid of state bitmasks" This reverts commit b7b05e729e4fcfbe74786342882d011f004658fa. Apparently this was premature, because we still need these things to deal with default state remapping. --- src/pocketmine/block/Anvil.php | 6 +++- src/pocketmine/block/BaseRail.php | 4 +++ src/pocketmine/block/Bed.php | 4 +++ src/pocketmine/block/Block.php | 18 +++++++++- src/pocketmine/block/BlockFactory.php | 36 +++++++++++++------ src/pocketmine/block/BrewingStand.php | 4 +++ src/pocketmine/block/Button.php | 4 +++ src/pocketmine/block/Cactus.php | 4 +++ src/pocketmine/block/Cake.php | 4 +++ src/pocketmine/block/Chest.php | 4 +++ src/pocketmine/block/CocoaBlock.php | 4 +++ src/pocketmine/block/Crops.php | 4 +++ src/pocketmine/block/DaylightSensor.php | 4 +++ src/pocketmine/block/Door.php | 4 +++ src/pocketmine/block/DoublePlant.php | 4 +++ src/pocketmine/block/EndPortalFrame.php | 4 +++ src/pocketmine/block/EndRod.php | 4 +++ src/pocketmine/block/Farmland.php | 4 +++ src/pocketmine/block/FenceGate.php | 4 +++ src/pocketmine/block/Fire.php | 4 +++ src/pocketmine/block/FlowerPot.php | 4 +++ src/pocketmine/block/Furnace.php | 4 +++ src/pocketmine/block/GlazedTerracotta.php | 4 +++ src/pocketmine/block/ItemFrame.php | 4 +++ src/pocketmine/block/Ladder.php | 4 +++ src/pocketmine/block/Leaves.php | 4 +++ src/pocketmine/block/Lever.php | 4 +++ src/pocketmine/block/Liquid.php | 4 +++ src/pocketmine/block/NetherReactor.php | 4 +++ src/pocketmine/block/NetherWartPlant.php | 4 +++ src/pocketmine/block/Pumpkin.php | 4 +++ src/pocketmine/block/RedMushroomBlock.php | 4 +++ src/pocketmine/block/RedstoneRepeater.php | 4 +++ src/pocketmine/block/RedstoneWire.php | 4 +++ src/pocketmine/block/Sapling.php | 4 +++ src/pocketmine/block/SignPost.php | 4 +++ src/pocketmine/block/SimplePressurePlate.php | 4 +++ src/pocketmine/block/Skull.php | 4 +++ src/pocketmine/block/Slab.php | 4 +++ src/pocketmine/block/SnowLayer.php | 4 +++ src/pocketmine/block/Sponge.php | 4 +++ src/pocketmine/block/Stair.php | 4 +++ src/pocketmine/block/StandingBanner.php | 4 +++ src/pocketmine/block/Sugarcane.php | 4 +++ src/pocketmine/block/Torch.php | 5 ++- src/pocketmine/block/Trapdoor.php | 4 +++ src/pocketmine/block/Tripwire.php | 4 +++ src/pocketmine/block/TripwireHook.php | 4 +++ src/pocketmine/block/Vine.php | 4 +++ src/pocketmine/block/WallBanner.php | 4 +++ src/pocketmine/block/WallSign.php | 4 +++ .../block/WeightedPressurePlate.php | 4 +++ .../block/utils/PillarRotationTrait.php | 8 +++++ 53 files changed, 251 insertions(+), 14 deletions(-) diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index dc81bcc078..23ad43911e 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -50,7 +50,11 @@ class Anvil extends Transparent implements Fallable{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); + $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta); + } + + public function getStateBitmask() : int{ + return 0b11; } public function getHardness() : float{ diff --git a/src/pocketmine/block/BaseRail.php b/src/pocketmine/block/BaseRail.php index 6fb66260fd..3dfb543ed9 100644 --- a/src/pocketmine/block/BaseRail.php +++ b/src/pocketmine/block/BaseRail.php @@ -95,6 +95,10 @@ abstract class BaseRail extends Flowable{ $this->connections = $connections; } + public function getStateBitmask() : int{ + return 0b1111; + } + public function getHardness() : float{ return 0.7; } diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 74b245c516..da51227e70 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -68,6 +68,10 @@ class Bed extends Transparent{ $this->head = ($stateMeta & self::BITFLAG_HEAD) !== 0; } + public function getStateBitmask() : int{ + return 0b1111; + } + public function readStateFromWorld() : void{ parent::readStateFromWorld(); //read extra state information from the tile - this is an ugly hack diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 4f63c4f72e..fb1deb2469 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -43,6 +43,8 @@ use pocketmine\Player; use pocketmine\plugin\Plugin; use pocketmine\tile\TileFactory; use function array_merge; +use function assert; +use function dechex; use function get_class; use const PHP_INT_MAX; @@ -80,6 +82,9 @@ class Block extends Position implements BlockIds, Metadatable{ * @param string $name English name of the block type (TODO: implement translations) */ public function __construct(BlockIdentifier $idInfo, string $name){ + if(($idInfo->getVariant() & $this->getStateBitmask()) !== 0){ + throw new \InvalidArgumentException("Variant 0x" . dechex($idInfo->getVariant()) . " collides with state bitmask 0x" . dechex($this->getStateBitmask())); + } $this->idInfo = $idInfo; $this->fallbackName = $name; } @@ -118,7 +123,9 @@ class Block extends Position implements BlockIds, Metadatable{ * @return int */ public function getDamage() : int{ - return $this->idInfo->getVariant() | $this->writeStateToMeta(); + $stateMeta = $this->writeStateToMeta(); + assert(($stateMeta & ~$this->getStateBitmask()) === 0); + return $this->idInfo->getVariant() | $stateMeta; } protected function writeStateToMeta() : int{ @@ -161,6 +168,15 @@ class Block extends Position implements BlockIds, Metadatable{ } } + /** + * Returns a bitmask used to extract state bits from block metadata. + * + * @return int + */ + public function getStateBitmask() : int{ + return 0; + } + /** * Returns whether the given block has an equivalent type to this one. This compares base legacy ID and variant. * diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 818a124575..825567fef8 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -527,17 +527,20 @@ class BlockFactory{ * $override parameter. */ public static function register(Block $block, bool $override = false) : void{ - foreach($block->getIdInfo()->getAllBlockIds() as $id){ - for($m = 0; $m < 16; ++$m){ - $index = ($id << 4) | $m; + $variant = $block->getIdInfo()->getVariant(); - $v = clone $block; - try{ - $v->readStateFromData($id, $m); - if($v->getDamage() !== $m){ - throw new InvalidBlockStateException("Corrupted meta"); //don't register anything that isn't the same when we read it back again - } - }catch(InvalidBlockStateException $e){ //invalid property combination + $stateMask = $block->getStateBitmask(); + if(($variant & $stateMask) !== 0){ + throw new \InvalidArgumentException("Block variant collides with state bitmask"); + } + + foreach($block->getIdInfo()->getAllBlockIds() as $id){ + if(!$override and self::isRegistered($id, $variant)){ + throw new \InvalidArgumentException("Block registration $id:$variant conflicts with an existing block"); + } + + for($m = $variant; $m <= ($variant | $stateMask); ++$m){ + if(($m & ~$stateMask) !== $variant){ continue; } @@ -545,10 +548,21 @@ class BlockFactory{ throw new \InvalidArgumentException("Block registration " . get_class($block) . " has states which conflict with other blocks"); } + $index = ($id << 4) | $m; + + $v = clone $block; + try{ + $v->readStateFromData($id, $m & $stateMask); + if($v->getDamage() !== $m){ + throw new InvalidBlockStateException("Corrupted meta"); //don't register anything that isn't the same when we read it back again + } + }catch(InvalidBlockStateException $e){ //invalid property combination + continue; + } + self::fillStaticArrays($index, $v); } - $variant = $block->getIdInfo()->getVariant(); if(!self::isRegistered($id, $variant)){ self::fillStaticArrays(($id << 4) | $variant, $block); //register default state mapped to variant, for blocks which don't use 0 as valid state } diff --git a/src/pocketmine/block/BrewingStand.php b/src/pocketmine/block/BrewingStand.php index 775b2ba008..f9833823b1 100644 --- a/src/pocketmine/block/BrewingStand.php +++ b/src/pocketmine/block/BrewingStand.php @@ -44,6 +44,10 @@ class BrewingStand extends Transparent{ $this->northwestSlot = ($stateMeta & 0x04) !== 0; } + public function getStateBitmask() : int{ + return 0b111; + } + public function getHardness() : float{ return 0.5; } diff --git a/src/pocketmine/block/Button.php b/src/pocketmine/block/Button.php index b05f94e7ae..1ff2484147 100644 --- a/src/pocketmine/block/Button.php +++ b/src/pocketmine/block/Button.php @@ -47,6 +47,10 @@ abstract class Button extends Flowable{ $this->powered = ($stateMeta & 0x08) !== 0; } + public function getStateBitmask() : int{ + return 0b1111; + } + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ //TODO: check valid target block $this->facing = $face; diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index 381c96174f..dcf9655200 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -47,6 +47,10 @@ class Cactus extends Transparent{ $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 15); } + public function getStateBitmask() : int{ + return 0b1111; + } + public function getHardness() : float{ return 0.4; } diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index 0e98fa117f..335f0f6447 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -46,6 +46,10 @@ class Cake extends Transparent implements FoodSource{ $this->bites = BlockDataValidator::readBoundedInt("bites", $stateMeta, 0, 6); } + public function getStateBitmask() : int{ + return 0b111; + } + public function getHardness() : float{ return 0.5; } diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index 4c18414cfd..757e67c3dc 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -44,6 +44,10 @@ class Chest extends Transparent{ $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); } + public function getStateBitmask() : int{ + return 0b111; + } + public function getHardness() : float{ return 2.5; } diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index 46c654c791..0046d27aab 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -51,6 +51,10 @@ class CocoaBlock extends Transparent{ $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta >> 2, 0, 2); } + public function getStateBitmask() : int{ + return 0b1111; + } + public function getHardness() : float{ return 0.2; } diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index 45f49b74b3..2586d9109e 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -44,6 +44,10 @@ abstract class Crops extends Flowable{ $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 7); } + public function getStateBitmask() : int{ + return 0b111; + } + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($blockReplace->getSide(Facing::DOWN)->getId() === Block::FARMLAND){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/DaylightSensor.php b/src/pocketmine/block/DaylightSensor.php index c6806f98c3..a379c5f146 100644 --- a/src/pocketmine/block/DaylightSensor.php +++ b/src/pocketmine/block/DaylightSensor.php @@ -57,6 +57,10 @@ class DaylightSensor extends Transparent{ $this->inverted = $id === $this->idInfo->getSecondId(); } + public function getStateBitmask() : int{ + return 0b1111; + } + public function isInverted() : bool{ return $this->inverted; } diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index ac9d689f5f..39e56e5f8c 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -67,6 +67,10 @@ abstract class Door extends Transparent{ } } + public function getStateBitmask() : int{ + return 0b1111; + } + public function readStateFromWorld() : void{ parent::readStateFromWorld(); diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index 3b4151890a..a9dd48ee0f 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -43,6 +43,10 @@ class DoublePlant extends Flowable{ $this->top = ($stateMeta & self::BITFLAG_TOP) !== 0; } + public function getStateBitmask() : int{ + return 0b1000; + } + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $id = $blockReplace->getSide(Facing::DOWN)->getId(); if(($id === Block::GRASS or $id === Block::DIRT) and $blockReplace->getSide(Facing::UP)->canBeReplaced()){ diff --git a/src/pocketmine/block/EndPortalFrame.php b/src/pocketmine/block/EndPortalFrame.php index 53b7cc73f6..aebdc7b477 100644 --- a/src/pocketmine/block/EndPortalFrame.php +++ b/src/pocketmine/block/EndPortalFrame.php @@ -47,6 +47,10 @@ class EndPortalFrame extends Solid{ $this->eye = ($stateMeta & 0x04) !== 0; } + public function getStateBitmask() : int{ + return 0b111; + } + public function getLightLevel() : int{ return 1; } diff --git a/src/pocketmine/block/EndRod.php b/src/pocketmine/block/EndRod.php index 03f7622722..1290815382 100644 --- a/src/pocketmine/block/EndRod.php +++ b/src/pocketmine/block/EndRod.php @@ -50,6 +50,10 @@ class EndRod extends Flowable{ $this->facing = BlockDataValidator::readFacing($stateMeta); } + public function getStateBitmask() : int{ + return 0b111; + } + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->facing = $face; if($blockClicked instanceof EndRod and $blockClicked->facing === $this->facing){ diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index 022bde450d..32d9079907 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -42,6 +42,10 @@ class Farmland extends Transparent{ $this->wetness = BlockDataValidator::readBoundedInt("wetness", $stateMeta, 0, 7); } + public function getStateBitmask() : int{ + return 0b111; + } + public function getHardness() : float{ return 0.6; } diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index 0526b36897..b26152064e 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -50,6 +50,10 @@ class FenceGate extends Transparent{ $this->inWall = ($stateMeta & 0x08) !== 0; } + public function getStateBitmask() : int{ + return 0b1111; + } + public function getHardness() : float{ return 2; } diff --git a/src/pocketmine/block/Fire.php b/src/pocketmine/block/Fire.php index 5e79668b3b..faa722df4e 100644 --- a/src/pocketmine/block/Fire.php +++ b/src/pocketmine/block/Fire.php @@ -48,6 +48,10 @@ class Fire extends Flowable{ $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 15); } + public function getStateBitmask() : int{ + return 0b1111; + } + public function hasEntityCollision() : bool{ return true; } diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 297fe13361..057827e65c 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -43,6 +43,10 @@ class FlowerPot extends Flowable{ $this->occupied = $stateMeta !== 0; } + public function getStateBitmask() : int{ + return 0b1111; //vanilla uses various values, we only care about 1 and 0 for PE + } + protected function recalculateBoundingBox() : ?AxisAlignedBB{ return AxisAlignedBB::one()->contract(3 / 16, 0, 3 / 16)->trim(Facing::UP, 5 / 8); } diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index 595f2c1097..a407aa75d4 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -53,6 +53,10 @@ class Furnace extends Solid{ $this->lit = $id === $this->idInfo->getSecondId(); } + public function getStateBitmask() : int{ + return 0b111; + } + public function getHardness() : float{ return 3.5; } diff --git a/src/pocketmine/block/GlazedTerracotta.php b/src/pocketmine/block/GlazedTerracotta.php index 173d17d9ef..a3f4957ba9 100644 --- a/src/pocketmine/block/GlazedTerracotta.php +++ b/src/pocketmine/block/GlazedTerracotta.php @@ -44,6 +44,10 @@ class GlazedTerracotta extends Solid{ $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); } + public function getStateBitmask() : int{ + return 0b111; + } + public function getHardness() : float{ return 1.4; } diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 7faef10528..68891072db 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -77,6 +77,10 @@ class ItemFrame extends Flowable{ } } + public function getStateBitmask() : int{ + return 0b111; + } + /** * @return int */ diff --git a/src/pocketmine/block/Ladder.php b/src/pocketmine/block/Ladder.php index 9d9c38b9df..e5589279e9 100644 --- a/src/pocketmine/block/Ladder.php +++ b/src/pocketmine/block/Ladder.php @@ -44,6 +44,10 @@ class Ladder extends Transparent{ $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); } + public function getStateBitmask() : int{ + return 0b111; + } + public function hasEntityCollision() : bool{ return true; } diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 41ba257f7e..563f378e3b 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -56,6 +56,10 @@ class Leaves extends Transparent{ $this->checkDecay = ($stateMeta & 0x08) !== 0; } + public function getStateBitmask() : int{ + return 0b1100; + } + public function getHardness() : float{ return 0.2; } diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index 0221a30ac0..458fb89329 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -69,6 +69,10 @@ class Lever extends Flowable{ $this->powered = ($stateMeta & 0x08) !== 0; } + public function getStateBitmask() : int{ + return 0b1111; + } + public function getHardness() : float{ return 0.5; } diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index 3be306f145..cb98b7ca83 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -77,6 +77,10 @@ abstract class Liquid extends Transparent{ $this->still = $id === $this->idInfo->getSecondId(); } + public function getStateBitmask() : int{ + return 0b1111; + } + public function hasEntityCollision() : bool{ return true; } diff --git a/src/pocketmine/block/NetherReactor.php b/src/pocketmine/block/NetherReactor.php index b7cd4eab53..3a90117e83 100644 --- a/src/pocketmine/block/NetherReactor.php +++ b/src/pocketmine/block/NetherReactor.php @@ -44,6 +44,10 @@ class NetherReactor extends Solid{ $this->state = BlockDataValidator::readBoundedInt("state", $stateMeta, 0, 2); } + public function getStateBitmask() : int{ + return 0b11; + } + public function getToolType() : int{ return BlockToolType::TYPE_PICKAXE; } diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index 7c7461af1c..f0027de2a9 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -45,6 +45,10 @@ class NetherWartPlant extends Flowable{ $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 3); } + public function getStateBitmask() : int{ + return 0b11; + } + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === Block::SOUL_SAND){ diff --git a/src/pocketmine/block/Pumpkin.php b/src/pocketmine/block/Pumpkin.php index 58e604463d..0f760987fd 100644 --- a/src/pocketmine/block/Pumpkin.php +++ b/src/pocketmine/block/Pumpkin.php @@ -43,6 +43,10 @@ class Pumpkin extends Solid{ return Bearing::fromFacing($this->facing); } + public function getStateBitmask() : int{ + return 0b11; + } + public function getHardness() : float{ return 1; } diff --git a/src/pocketmine/block/RedMushroomBlock.php b/src/pocketmine/block/RedMushroomBlock.php index 166e5cb4ee..7e2bbf48ea 100644 --- a/src/pocketmine/block/RedMushroomBlock.php +++ b/src/pocketmine/block/RedMushroomBlock.php @@ -45,6 +45,10 @@ class RedMushroomBlock extends Solid{ $this->rotationData = $stateMeta; } + public function getStateBitmask() : int{ + return 0b1111; + } + public function getHardness() : float{ return 0.2; } diff --git a/src/pocketmine/block/RedstoneRepeater.php b/src/pocketmine/block/RedstoneRepeater.php index d48926e5e1..ab16eead22 100644 --- a/src/pocketmine/block/RedstoneRepeater.php +++ b/src/pocketmine/block/RedstoneRepeater.php @@ -60,6 +60,10 @@ class RedstoneRepeater extends Flowable{ return Bearing::fromFacing($this->facing) | (($this->delay - 1) << 2); } + public function getStateBitmask() : int{ + return 0b1111; + } + protected function recalculateBoundingBox() : ?AxisAlignedBB{ return AxisAlignedBB::one()->trim(Facing::UP, 7 / 8); } diff --git a/src/pocketmine/block/RedstoneWire.php b/src/pocketmine/block/RedstoneWire.php index 677f0b3a4f..6f95e906b4 100644 --- a/src/pocketmine/block/RedstoneWire.php +++ b/src/pocketmine/block/RedstoneWire.php @@ -38,6 +38,10 @@ class RedstoneWire extends Flowable{ return $this->power; } + public function getStateBitmask() : int{ + return 0b1111; + } + public function readStateFromWorld() : void{ parent::readStateFromWorld(); //TODO: check connections to nearby redstone components diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index 80e82b7507..0b725ffab8 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -53,6 +53,10 @@ class Sapling extends Flowable{ $this->ready = ($stateMeta & 0x08) !== 0; } + public function getStateBitmask() : int{ + return 0b1000; + } + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === self::GRASS or $down->getId() === self::DIRT or $down->getId() === self::FARMLAND){ diff --git a/src/pocketmine/block/SignPost.php b/src/pocketmine/block/SignPost.php index 53f3331027..1470fea51a 100644 --- a/src/pocketmine/block/SignPost.php +++ b/src/pocketmine/block/SignPost.php @@ -43,6 +43,10 @@ class SignPost extends Transparent{ $this->rotation = $stateMeta; } + public function getStateBitmask() : int{ + return 0b1111; + } + public function getHardness() : float{ return 1; } diff --git a/src/pocketmine/block/SimplePressurePlate.php b/src/pocketmine/block/SimplePressurePlate.php index 79205d5d59..7ffb9a7748 100644 --- a/src/pocketmine/block/SimplePressurePlate.php +++ b/src/pocketmine/block/SimplePressurePlate.php @@ -35,4 +35,8 @@ abstract class SimplePressurePlate extends PressurePlate{ public function readStateFromData(int $id, int $stateMeta) : void{ $this->powered = $stateMeta !== 0; } + + public function getStateBitmask() : int{ + return 0b1; + } } diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index 4de79e1f0e..da62c2c26d 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -50,6 +50,10 @@ class Skull extends Flowable{ $this->facing = $stateMeta === 1 ? Facing::UP : BlockDataValidator::readHorizontalFacing($stateMeta); } + public function getStateBitmask() : int{ + return 0b111; + } + public function readStateFromWorld() : void{ parent::readStateFromWorld(); $tile = $this->level->getTile($this); diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index 078c39bf35..dd7599972f 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -61,6 +61,10 @@ abstract class Slab extends Transparent{ } } + public function getStateBitmask() : int{ + return 0b1000; + } + public function isTransparent() : bool{ return $this->slabType !== SlabType::DOUBLE(); } diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index ff9ff49b91..e80b18cf82 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -50,6 +50,10 @@ class SnowLayer extends Flowable implements Fallable{ $this->layers = BlockDataValidator::readBoundedInt("layers", $stateMeta + 1, 1, 8); } + public function getStateBitmask() : int{ + return 0b111; + } + public function canBeReplaced() : bool{ return $this->layers < 8; } diff --git a/src/pocketmine/block/Sponge.php b/src/pocketmine/block/Sponge.php index 402f938f89..f72ec0b7b7 100644 --- a/src/pocketmine/block/Sponge.php +++ b/src/pocketmine/block/Sponge.php @@ -37,6 +37,10 @@ class Sponge extends Solid{ $this->wet = $stateMeta !== 0; } + public function getStateBitmask() : int{ + return 0b1; + } + public function getHardness() : float{ return 0.6; } diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index df2af2a3ff..a66ef1d11d 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -53,6 +53,10 @@ abstract class Stair extends Transparent{ $this->upsideDown = ($stateMeta & 0x04) !== 0; } + public function getStateBitmask() : int{ + return 0b111; + } + public function readStateFromWorld() : void{ parent::readStateFromWorld(); diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index 53603b471c..e20490fbb8 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -46,6 +46,10 @@ class StandingBanner extends Transparent{ $this->rotation = $stateMeta; } + public function getStateBitmask() : int{ + return 0b1111; + } + public function getHardness() : float{ return 1; } diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index 2bf55b58bb..6a02812130 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -44,6 +44,10 @@ class Sugarcane extends Flowable{ $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 15); } + public function getStateBitmask() : int{ + return 0b1111; + } + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof Fertilizer){ if($this->getSide(Facing::DOWN)->getId() !== self::SUGARCANE_BLOCK){ diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index bd97b94b90..7e076f7c57 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -39,10 +39,13 @@ class Torch extends Flowable{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $stateMeta &= 0x07; $this->facing = $stateMeta === 5 ? Facing::UP : BlockDataValidator::readHorizontalFacing(6 - $stateMeta); } + public function getStateBitmask() : int{ + return 0b111; + } + public function getLightLevel() : int{ return 14; } diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index d3cacbd899..1cc736894d 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -54,6 +54,10 @@ class Trapdoor extends Transparent{ $this->open = ($stateMeta & self::MASK_OPENED) !== 0; } + public function getStateBitmask() : int{ + return 0b1111; + } + public function getHardness() : float{ return 3; } diff --git a/src/pocketmine/block/Tripwire.php b/src/pocketmine/block/Tripwire.php index e82c15d522..3b68142ac4 100644 --- a/src/pocketmine/block/Tripwire.php +++ b/src/pocketmine/block/Tripwire.php @@ -45,6 +45,10 @@ class Tripwire extends Flowable{ $this->disarmed = ($stateMeta & 0x08) !== 0; } + public function getStateBitmask() : int{ + return 0b1111; + } + public function isAffectedBySilkTouch() : bool{ return false; } diff --git a/src/pocketmine/block/TripwireHook.php b/src/pocketmine/block/TripwireHook.php index 7f9770530b..b91887f36b 100644 --- a/src/pocketmine/block/TripwireHook.php +++ b/src/pocketmine/block/TripwireHook.php @@ -49,6 +49,10 @@ class TripwireHook extends Flowable{ $this->powered = ($stateMeta & 0x08) !== 0; } + public function getStateBitmask() : int{ + return 0b1111; + } + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(Facing::axis($face) !== Facing::AXIS_Y){ //TODO: check face is valid diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index 44a6b206ac..27b59636a9 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -57,6 +57,10 @@ class Vine extends Flowable{ $this->setFaceFromMeta($stateMeta, self::FLAG_EAST, Facing::EAST); } + public function getStateBitmask() : int{ + return 0b1111; + } + private function setFaceFromMeta(int $meta, int $flag, int $face) : void{ if(($meta & $flag) !== 0){ $this->faces[$face] = true; diff --git a/src/pocketmine/block/WallBanner.php b/src/pocketmine/block/WallBanner.php index ede176c85d..7acdba5b78 100644 --- a/src/pocketmine/block/WallBanner.php +++ b/src/pocketmine/block/WallBanner.php @@ -39,6 +39,10 @@ class WallBanner extends StandingBanner{ $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); } + public function getStateBitmask() : int{ + return 0b111; + } + public function onNearbyBlockChange() : void{ if($this->getSide(Facing::opposite($this->facing))->getId() === self::AIR){ $this->getLevel()->useBreakOn($this); diff --git a/src/pocketmine/block/WallSign.php b/src/pocketmine/block/WallSign.php index cf2c615aa4..79f85999af 100644 --- a/src/pocketmine/block/WallSign.php +++ b/src/pocketmine/block/WallSign.php @@ -39,6 +39,10 @@ class WallSign extends SignPost{ $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); } + public function getStateBitmask() : int{ + return 0b111; + } + public function onNearbyBlockChange() : void{ if($this->getSide(Facing::opposite($this->facing))->getId() === self::AIR){ $this->getLevel()->useBreakOn($this); diff --git a/src/pocketmine/block/WeightedPressurePlate.php b/src/pocketmine/block/WeightedPressurePlate.php index 7c3d310c15..fb3c00051b 100644 --- a/src/pocketmine/block/WeightedPressurePlate.php +++ b/src/pocketmine/block/WeightedPressurePlate.php @@ -37,4 +37,8 @@ abstract class WeightedPressurePlate extends PressurePlate{ public function readStateFromData(int $id, int $stateMeta) : void{ $this->power = BlockDataValidator::readBoundedInt("power", $stateMeta, 0, 15); } + + public function getStateBitmask() : int{ + return 0b1111; + } } diff --git a/src/pocketmine/block/utils/PillarRotationTrait.php b/src/pocketmine/block/utils/PillarRotationTrait.php index 5ddc5fc12a..7113ae764e 100644 --- a/src/pocketmine/block/utils/PillarRotationTrait.php +++ b/src/pocketmine/block/utils/PillarRotationTrait.php @@ -52,6 +52,14 @@ trait PillarRotationTrait{ $this->readAxisFromMeta($stateMeta); } + /** + * @see Block::getStateBitmask() + * @return int + */ + public function getStateBitmask() : int{ + return 0b1100; + } + protected function readAxisFromMeta(int $meta) : void{ static $map = [ 0 => Facing::AXIS_Y, From fb378d9091fba5553e36db63bb51494e06ccf552 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Feb 2019 18:41:12 +0000 Subject: [PATCH 0543/3224] BlockFactory: fixed auto complete --- src/pocketmine/block/BlockFactory.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 825567fef8..c45fd44401 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -42,14 +42,14 @@ use function min; * Manages block registration and instance creation */ class BlockFactory{ - /** @var \SplFixedArray */ + /** @var \SplFixedArray|Block[] */ private static $fullList = null; - /** @var \SplFixedArray */ + /** @var \SplFixedArray|int[] */ public static $lightFilter = null; - /** @var \SplFixedArray */ + /** @var \SplFixedArray|bool[] */ public static $diffusesSkyLight = null; - /** @var \SplFixedArray */ + /** @var \SplFixedArray|float[] */ public static $blastResistance = null; /** @var int[] */ From 6124f93cb4287b1fd4d91ee162d6b8a4b8050ff5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 25 Feb 2019 18:40:04 +0000 Subject: [PATCH 0544/3224] Player: Clean up item frame drop-item hack This is now re-routed through a newly-created attack-block handler. Closes #339 --- src/pocketmine/Player.php | 41 ++++++------------- src/pocketmine/block/Block.php | 14 +++++++ src/pocketmine/block/ItemFrame.php | 12 ++++++ .../mcpe/handler/SimpleSessionHandler.php | 9 +++- 4 files changed, 46 insertions(+), 30 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 21b12d1701..83d8e04180 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -26,7 +26,6 @@ namespace pocketmine; use pocketmine\block\Bed; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\ItemFrame; use pocketmine\block\UnknownBlock; use pocketmine\command\Command; use pocketmine\command\CommandSender; @@ -112,7 +111,6 @@ use pocketmine\network\mcpe\protocol\BookEditPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\EntityEventPacket; -use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\LoginPacket; @@ -154,7 +152,6 @@ use function in_array; use function is_int; use function json_encode; use function json_last_error_msg; -use function lcg_value; use function max; use function microtime; use function min; @@ -2174,7 +2171,15 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return true; } - public function startBreakBlock(Vector3 $pos, int $face) : bool{ + /** + * Performs a left-click (attack) action on the block. + * + * @param Vector3 $pos + * @param int $face + * + * @return bool + */ + public function attackBlock(Vector3 $pos, int $face) : bool{ if($pos->distanceSquared($this) > 10000){ return false; //TODO: maybe this should throw an exception instead? } @@ -2184,9 +2189,13 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $ev = new PlayerInteractEvent($this, $this->inventory->getItemInHand(), $target, null, $face, PlayerInteractEvent::LEFT_CLICK_BLOCK); $ev->call(); if($ev->isCancelled()){ + $this->level->sendBlocks([$this], [$target]); $this->inventory->sendHeldItem($this); return true; } + if($target->onAttack($this->inventory->getItemInHand(), $face, $this)){ + return true; + } $block = $target->getSide($face); if($block->getId() === Block::FIRE){ @@ -2490,30 +2499,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return true; } - public function handleItemFrameDropItem(ItemFrameDropItemPacket $packet) : bool{ - $block = $this->level->getBlockAt($packet->x, $packet->y, $packet->z); - if($block instanceof ItemFrame){ - $ev = new PlayerInteractEvent($this, $this->inventory->getItemInHand(), $block, null, $block->getFacing(), PlayerInteractEvent::LEFT_CLICK_BLOCK); - if($this->isSpectator()){ - $ev->setCancelled(); - } - - $ev->call(); - if($ev->isCancelled()){ - $this->level->sendBlocks([$this], [$block]); - return true; - } - - if(lcg_value() <= $block->getItemDropChance()){ - $this->level->dropItem($block->add(0.5, 0.5, 0.5), $block->getFramedItem()); - } - $block->setFramedItem(null); - $this->level->setBlock($block, $block); - } - - return true; - } - public function handleBookEdit(BookEditPacket $packet) : bool{ /** @var WritableBook $oldBook */ $oldBook = $this->inventory->getItem($packet->inventorySlot); diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index fb1deb2469..1bbb61d4cf 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -380,6 +380,20 @@ class Block extends Position implements BlockIds, Metadatable{ return false; } + /** + * Called when this block is attacked (left-clicked). This is called when a player left-clicks the block to try and + * start to break it in survival mode. + * + * @param Item $item + * @param int $face + * @param Player|null $player + * + * @return bool if an action took place, prevents starting to break the block if true. + */ + public function onAttack(Item $item, int $face, ?Player $player = null) : bool{ + return false; + } + /** * Returns a base value used to compute block break times. * @return float diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 68891072db..430ee3a1a2 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -156,6 +156,18 @@ class ItemFrame extends Flowable{ return true; } + public function onAttack(Item $item, int $face, ?Player $player = null) : bool{ + if($this->framedItem === null){ + return false; + } + if(lcg_value() <= $this->itemDropChance){ + $this->level->dropItem($this->add(0.5, 0.5, 0.5), $this->getFramedItem()); + } + $this->setFramedItem(null); + $this->level->setBlock($this, $this); + return true; + } + public function onNearbyBlockChange() : void{ if(!$this->getSide(Facing::opposite($this->facing))->isSolid()){ $this->level->useBreakOn($this); diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index 2255283c61..49476ed98e 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; +use pocketmine\block\ItemFrame; use pocketmine\inventory\transaction\action\InventoryAction; use pocketmine\inventory\transaction\CraftingTransaction; use pocketmine\inventory\transaction\InventoryTransaction; @@ -309,7 +310,7 @@ class SimpleSessionHandler extends SessionHandler{ switch($packet->action){ case PlayerActionPacket::ACTION_START_BREAK: - $this->player->startBreakBlock($pos, $packet->face); + $this->player->attackBlock($pos, $packet->face); break; @@ -415,7 +416,11 @@ class SimpleSessionHandler extends SessionHandler{ } public function handleItemFrameDropItem(ItemFrameDropItemPacket $packet) : bool{ - return $this->player->handleItemFrameDropItem($packet); + $block = $this->player->getLevel()->getBlockAt($packet->x, $packet->y, $packet->z); + if($block instanceof ItemFrame and $block->getFramedItem() !== null){ + return $this->player->attackBlock(new Vector3($packet->x, $packet->y, $packet->z), $block->getFacing()); + } + return false; } public function handleBossEvent(BossEventPacket $packet) : bool{ From 2d51622b1253b662d2edd19edab2f69250e9299c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 25 Feb 2019 13:04:05 +0000 Subject: [PATCH 0545/3224] Implemented frosted ice --- src/pocketmine/block/BlockFactory.php | 1 + src/pocketmine/block/FrostedIce.php | 115 ++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 src/pocketmine/block/FrostedIce.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index c45fd44401..b1573b6c23 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -136,6 +136,7 @@ class BlockFactory{ self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_RED_TULIP), "Red Tulip")); self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_WHITE_TULIP), "White Tulip")); self::register(new FlowerPot(new BID(Block::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, \pocketmine\tile\FlowerPot::class), "Flower Pot")); + self::register(new FrostedIce(new BID(Block::FROSTED_ICE), "Frosted Ice")); self::register(new Furnace(new BlockIdentifierFlattened(Block::FURNACE, Block::LIT_FURNACE, 0, null, \pocketmine\tile\Furnace::class), "Furnace")); self::register(new Glass(new BID(Block::GLASS), "Glass")); self::register(new GlassPane(new BID(Block::GLASS_PANE), "Glass Pane")); diff --git a/src/pocketmine/block/FrostedIce.php b/src/pocketmine/block/FrostedIce.php new file mode 100644 index 0000000000..aaae971607 --- /dev/null +++ b/src/pocketmine/block/FrostedIce.php @@ -0,0 +1,115 @@ +age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 3); + } + + protected function writeStateToMeta() : int{ + return $this->age; + } + + public function getStateBitmask() : int{ + return 0b11; + } + + public function getHardness() : float{ + return 2.5; + } + + public function onNearbyBlockChange() : void{ + if(!$this->checkAdjacentBlocks(2)){ + $this->level->useBreakOn($this); + }else{ + $this->level->scheduleDelayedBlockUpdate($this, mt_rand(20, 40)); + } + } + + public function onRandomTick() : void{ + if((!$this->checkAdjacentBlocks(4) or mt_rand(0, 2) === 0) and + max( //TODO: move this to Level + $this->level->getHighestAdjacentBlockLight($this->x, $this->y, $this->z), + $this->level->getHighestAdjacentBlockSkyLight($this->x, $this->y, $this->z) - $this->level->getSkyLightReduction() + ) >= 12 - $this->age){ + if($this->tryMelt()){ + foreach($this->getAllSides() as $block){ + if($block instanceof FrostedIce){ + $block->tryMelt(); + } + } + } + }else{ + $this->level->scheduleDelayedBlockUpdate($this, mt_rand(20, 40)); + } + } + + public function onScheduledUpdate() : void{ + $this->onRandomTick(); + } + + private function checkAdjacentBlocks(int $requirement) : bool{ + $found = 0; + for($x = -1; $x <= 1; ++$x){ + for($z = -1; $z <= 1; ++$z){ + if($x === 0 and $z === 0){ + continue; + } + if( + $this->level->getBlockAt($this->x + $x, $this->y, $this->z + $z) instanceof FrostedIce and + ++$found >= $requirement + ){ + return true; + } + } + } + return false; + } + + /** + * Updates the age of the ice, destroying it if appropriate. + * + * @return bool Whether the ice was destroyed. + */ + private function tryMelt() : bool{ + if($this->age >= 3){ + $this->level->useBreakOn($this); + return true; + } + + $this->age++; + $this->level->setBlock($this, $this); + $this->level->scheduleDelayedBlockUpdate($this, mt_rand(20, 40)); + return false; + } +} From 53af7f5da8b60ccc82ff0a0625104a9961a5d916 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 25 Feb 2019 20:00:58 +0000 Subject: [PATCH 0546/3224] Implemented dragon egg --- src/pocketmine/block/BlockFactory.php | 1 + src/pocketmine/block/DragonEgg.php | 87 +++++++++++++++++++ .../particle/DragonEggTeleportParticle.php | 66 ++++++++++++++ .../mcpe/protocol/LevelEventPacket.php | 1 + 4 files changed, 155 insertions(+) create mode 100644 src/pocketmine/block/DragonEgg.php create mode 100644 src/pocketmine/level/particle/DragonEggTeleportParticle.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index b1573b6c23..4db1f4b9e6 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -114,6 +114,7 @@ class BlockFactory{ self::register(new DoublePlant(new BID(Block::DOUBLE_PLANT, 5), "Peony")); self::register(new DoubleTallGrass(new BID(Block::DOUBLE_PLANT, 2), "Double Tallgrass")); self::register(new DoubleTallGrass(new BID(Block::DOUBLE_PLANT, 3), "Large Fern")); + self::register(new DragonEgg(new BID(Block::DRAGON_EGG), "Dragon Egg")); self::register(new Emerald(new BID(Block::EMERALD_BLOCK), "Emerald Block")); self::register(new EmeraldOre(new BID(Block::EMERALD_ORE), "Emerald Ore")); self::register(new EnchantingTable(new BID(Block::ENCHANTING_TABLE, 0, null, \pocketmine\tile\EnchantTable::class), "Enchanting Table")); diff --git a/src/pocketmine/block/DragonEgg.php b/src/pocketmine/block/DragonEgg.php new file mode 100644 index 0000000000..8879681665 --- /dev/null +++ b/src/pocketmine/block/DragonEgg.php @@ -0,0 +1,87 @@ +teleport(); + return true; + } + + public function onAttack(Item $item, int $face, ?Player $player = null) : bool{ + $this->teleport(); + return true; + } + + protected function teleport() : void{ + for($tries = 0; $tries < 16; ++$tries){ + $block = $this->level->getBlockAt( + $this->x + mt_rand(-16, 16), + max(0, min(Level::Y_MAX - 1, $this->y + mt_rand(-8, 8))), + $this->z + mt_rand(-16, 16) + ); + if($block instanceof Air){ + $this->level->addParticle($this, new DragonEggTeleportParticle($this->x - $block->x, $this->y - $block->y, $this->z - $block->z)); + //TODO: add events + $this->level->setBlock($this, BlockFactory::get(Block::AIR)); + $this->level->setBlock($block, $this); + break; + } + } + } +} diff --git a/src/pocketmine/level/particle/DragonEggTeleportParticle.php b/src/pocketmine/level/particle/DragonEggTeleportParticle.php new file mode 100644 index 0000000000..65b2e75408 --- /dev/null +++ b/src/pocketmine/level/particle/DragonEggTeleportParticle.php @@ -0,0 +1,66 @@ +xDiff = self::boundOrThrow($xDiff); + $this->yDiff = self::boundOrThrow($yDiff); + $this->zDiff = self::boundOrThrow($zDiff); + } + + private static function boundOrThrow(int $v) : int{ + if($v < -255 or $v > 255){ + throw new \InvalidArgumentException("Value must be between -255 and 255"); + } + return $v; + } + + public function encode(Vector3 $pos){ + $pk = new LevelEventPacket(); + $pk->evid = LevelEventPacket::EVENT_PARTICLE_DRAGON_EGG_TELEPORT; + $pk->position = $pos; + $pk->data = + ($this->zDiff < 0 ? 1 << 26 : 0) | + ($this->yDiff < 0 ? 1 << 25 : 0) | + ($this->xDiff < 0 ? 1 << 24 : 0) | + (abs($this->xDiff) << 16) | + (abs($this->yDiff) << 8) | + abs($this->zDiff); + + return $pk; + } +} diff --git a/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php b/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php index aa3fc980ce..73510dca7b 100644 --- a/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php @@ -81,6 +81,7 @@ class LevelEventPacket extends DataPacket implements ClientboundPacket{ public const EVENT_PARTICLE_BLOCK_FORCE_FIELD = 2008; public const EVENT_PARTICLE_PROJECTILE_HIT = 2009; + public const EVENT_PARTICLE_DRAGON_EGG_TELEPORT = 2010; public const EVENT_PARTICLE_ENDERMAN_TELEPORT = 2013; public const EVENT_PARTICLE_PUNCH_BLOCK = 2014; From 9afcd72fb69391adde8f6fae315c008d0ee90143 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Feb 2019 16:31:38 +0000 Subject: [PATCH 0547/3224] Flatten FlowerPot tile into its block (mostly) --- src/pocketmine/block/FlowerPot.php | 84 ++++++++++++++++++++++++------ src/pocketmine/tile/FlowerPot.php | 84 ++++++++++++------------------ 2 files changed, 100 insertions(+), 68 deletions(-) diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 057827e65c..7a7b8ad765 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -29,12 +29,19 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\FlowerPot as TileFlowerPot; +use function assert; class FlowerPot extends Flowable{ - /** @var bool */ + /** + * TODO: get rid of this hack (it's currently needed to deal with blockfactory state handling) + * @var bool + */ protected $occupied = false; + /** @var Block|null */ + protected $plant = null; + protected function writeStateToMeta() : int{ return $this->occupied ? 1 : 0; } @@ -47,6 +54,59 @@ class FlowerPot extends Flowable{ return 0b1111; //vanilla uses various values, we only care about 1 and 0 for PE } + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); + $tile = $this->level->getTile($this); + if($tile instanceof TileFlowerPot){ + $this->setPlant($tile->getPlant()); + }else{ + $this->occupied = false; + } + } + + public function writeStateToWorld() : void{ + parent::writeStateToWorld(); + + $tile = $this->level->getTile($this); + assert($tile instanceof TileFlowerPot); + $tile->setPlant($this->plant); + } + + /** + * @return Block|null + */ + public function getPlant() : ?Block{ + return $this->plant; + } + + /** + * @param Block|null $plant + */ + public function setPlant(?Block $plant) : void{ + if($plant === null or $plant instanceof Air){ + $this->plant = null; + }else{ + $this->plant = clone $plant; + } + $this->occupied = $this->plant !== null; + } + + public function canAddPlant(Block $block) : bool{ + if($this->plant !== null){ + return false; + } + + return + $block instanceof Cactus or + $block instanceof Dandelion or + $block instanceof DeadBush or + $block instanceof Flower or + $block instanceof RedMushroom or + $block instanceof Sapling or + ($block instanceof TallGrass and $block->getIdInfo()->getVariant() === 2); //fern - TODO: clean up + //TODO: bamboo + } + protected function recalculateBoundingBox() : ?AxisAlignedBB{ return AxisAlignedBB::one()->contract(3 / 16, 0, 3 / 16)->trim(Facing::UP, 5 / 8); } @@ -66,30 +126,22 @@ class FlowerPot extends Flowable{ } public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - $pot = $this->getLevel()->getTile($this); - if(!($pot instanceof TileFlowerPot)){ + $plant = $item->getBlock(); + if(!$this->canAddPlant($plant)){ return false; } - if(!$pot->canAddItem($item)){ - return true; - } - $this->occupied = true; - $this->getLevel()->setBlock($this, $this, false); - $pot->setItem($item->pop()); + $this->setPlant($plant); + $item->pop(); + $this->level->setBlock($this, $this); return true; } public function getDropsForCompatibleTool(Item $item) : array{ $items = parent::getDropsForCompatibleTool($item); - - $tile = $this->getLevel()->getTile($this); - if($tile instanceof TileFlowerPot){ - $item = $tile->getItem(); - if($item->getId() !== Item::AIR){ - $items[] = $item; - } + if($this->plant !== null){ + $items[] = $this->plant->asItem(); } return $items; diff --git a/src/pocketmine/tile/FlowerPot.php b/src/pocketmine/tile/FlowerPot.php index 977391db16..ccfc5bc314 100644 --- a/src/pocketmine/tile/FlowerPot.php +++ b/src/pocketmine/tile/FlowerPot.php @@ -23,79 +23,59 @@ declare(strict_types=1); namespace pocketmine\tile; -use pocketmine\item\Item; -use pocketmine\item\ItemFactory; -use pocketmine\level\Level; -use pocketmine\math\Vector3; +use pocketmine\block\Air; +use pocketmine\block\Block; +use pocketmine\block\BlockFactory; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ShortTag; +/** + * @deprecated + * @see \pocketmine\block\FlowerPot + */ class FlowerPot extends Spawnable{ - public const TAG_ITEM = "item"; - public const TAG_ITEM_DATA = "mData"; + private const TAG_ITEM = "item"; + private const TAG_ITEM_DATA = "mData"; - /** @var Item */ - private $item; - - public function __construct(Level $level, Vector3 $pos){ - $this->item = ItemFactory::air(); - parent::__construct($level, $pos); - } + /** @var Block|null */ + private $plant = null; public function readSaveData(CompoundTag $nbt) : void{ if($nbt->hasTag(self::TAG_ITEM, ShortTag::class) and $nbt->hasTag(self::TAG_ITEM_DATA, IntTag::class)){ - $this->item = ItemFactory::get($nbt->getShort(self::TAG_ITEM, 0), $nbt->getInt(self::TAG_ITEM_DATA, 0), 1); + //prevent stupidity with wrong items + if(($id = $nbt->getShort(self::TAG_ITEM)) >= 0 and $id <= 255 and ($data = $nbt->getInt(self::TAG_ITEM_DATA)) >= 0 and $data <= 15){ + $this->setPlant(BlockFactory::get($id, $data)); + } + }else{ + //TODO: new PlantBlock tag } } protected function writeSaveData(CompoundTag $nbt) : void{ - $nbt->setShort(self::TAG_ITEM, $this->item->getId()); - $nbt->setInt(self::TAG_ITEM_DATA, $this->item->getDamage()); - } - - public function canAddItem(Item $item) : bool{ - if(!$this->isEmpty()){ - return false; - } - switch($item->getId()){ - /** @noinspection PhpMissingBreakStatementInspection */ - case Item::TALL_GRASS: - if($item->getDamage() === 1){ - return false; - } - case Item::SAPLING: - case Item::DEAD_BUSH: - case Item::DANDELION: - case Item::RED_FLOWER: - case Item::BROWN_MUSHROOM: - case Item::RED_MUSHROOM: - case Item::CACTUS: - return true; - default: - return false; + if($this->plant !== null){ + $nbt->setShort(self::TAG_ITEM, $this->plant->getId()); + $nbt->setInt(self::TAG_ITEM_DATA, $this->plant->getDamage()); } } - public function getItem() : Item{ - return clone $this->item; + public function getPlant() : ?Block{ + return $this->plant !== null ? clone $this->plant : null; } - public function setItem(Item $item){ - $this->item = clone $item; + public function setPlant(?Block $plant){ + if($plant === null or $plant instanceof Air){ + $this->plant = null; + }else{ + $this->plant = clone $plant; + } $this->onChanged(); } - public function removeItem(){ - $this->setItem(ItemFactory::air()); - } - - public function isEmpty() : bool{ - return $this->getItem()->isNull(); - } - protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ - $nbt->setShort(self::TAG_ITEM, $this->item->getId()); - $nbt->setInt(self::TAG_ITEM_DATA, $this->item->getDamage()); + if($this->plant !== null){ + $nbt->setShort(self::TAG_ITEM, $this->plant->getId()); + $nbt->setInt(self::TAG_ITEM_DATA, $this->plant->getDamage()); + } } } From d7e73705c2e45efd5c3b3e043b80f27883ec9fc8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Feb 2019 16:35:14 +0000 Subject: [PATCH 0548/3224] consistency check regen script now emits which states were added/removed --- .../block/regenerate_consistency_check.php | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/tests/phpunit/block/regenerate_consistency_check.php b/tests/phpunit/block/regenerate_consistency_check.php index 0f5cec065f..07227301ba 100644 --- a/tests/phpunit/block/regenerate_consistency_check.php +++ b/tests/phpunit/block/regenerate_consistency_check.php @@ -26,11 +26,24 @@ require dirname(__DIR__, 3) . '/vendor/autoload.php'; /* This script needs to be re-run after any intentional blockfactory change (adding or removing a block state). */ \pocketmine\block\BlockFactory::init(); + +$old = json_decode(file_get_contents(__DIR__ . '/block_factory_consistency_check.json'), true); +$new = array_map( + function(\pocketmine\block\Block $block) : string{ + return $block->getName(); + }, + \pocketmine\block\BlockFactory::getAllKnownStates() +); +foreach($old as $k => $name){ + if(!isset($new[$k])){ + echo "Removed state for $name (" . ($k >> 4) . ":" . ($k & 0xf) . ")\n"; + } +} +foreach($new as $k => $name){ + if(!isset($old[$k])){ + echo "Added state for $name (" . ($k >> 4) . ":" . ($k & 0xf) . ")\n"; + } +} file_put_contents(__DIR__ . '/block_factory_consistency_check.json', json_encode( - array_map( - function(\pocketmine\block\Block $block) : string{ - return $block->getName(); - }, - \pocketmine\block\BlockFactory::getAllKnownStates() - ) + $new )); From 202aef9846bcb69b7550540e9b53e741f461dc07 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Feb 2019 16:35:33 +0000 Subject: [PATCH 0549/3224] fix failing tests --- tests/phpunit/block/block_factory_consistency_check.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 273fba13ec..eb1cc83f85 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","752":"Bookshelf","768":"Moss Stone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Sign Post","1009":"Sign Post","1010":"Sign Post","1011":"Sign Post","1012":"Sign Post","1013":"Sign Post","1014":"Sign Post","1015":"Sign Post","1016":"Sign Post","1017":"Sign Post","1018":"Sign Post","1019":"Sign Post","1020":"Sign Post","1021":"Sign Post","1022":"Sign Post","1023":"Sign Post","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Wall Sign","1090":"Wall Sign","1091":"Wall Sign","1092":"Wall Sign","1093":"Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Wooden Pressure Plate","1153":"Wooden Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Wooden Trapdoor","1537":"Wooden Trapdoor","1538":"Wooden Trapdoor","1539":"Wooden Trapdoor","1540":"Wooden Trapdoor","1541":"Wooden Trapdoor","1542":"Wooden Trapdoor","1543":"Wooden Trapdoor","1544":"Wooden Trapdoor","1545":"Wooden Trapdoor","1546":"Wooden Trapdoor","1547":"Wooden Trapdoor","1548":"Wooden Trapdoor","1549":"Wooden Trapdoor","1550":"Wooden Trapdoor","1551":"Wooden Trapdoor","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Wooden Button","2289":"Wooden Button","2290":"Wooden Button","2291":"Wooden Button","2292":"Wooden Button","2293":"Wooden Button","2296":"Wooden Button","2297":"Wooden Button","2298":"Wooden Button","2299":"Wooden Button","2300":"Wooden Button","2301":"Wooden Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Standing Banner","2817":"Standing Banner","2818":"Standing Banner","2819":"Standing Banner","2820":"Standing Banner","2821":"Standing Banner","2822":"Standing Banner","2823":"Standing Banner","2824":"Standing Banner","2825":"Standing Banner","2826":"Standing Banner","2827":"Standing Banner","2828":"Standing Banner","2829":"Standing Banner","2830":"Standing Banner","2831":"Standing Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","752":"Bookshelf","768":"Moss Stone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Sign Post","1009":"Sign Post","1010":"Sign Post","1011":"Sign Post","1012":"Sign Post","1013":"Sign Post","1014":"Sign Post","1015":"Sign Post","1016":"Sign Post","1017":"Sign Post","1018":"Sign Post","1019":"Sign Post","1020":"Sign Post","1021":"Sign Post","1022":"Sign Post","1023":"Sign Post","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Wall Sign","1090":"Wall Sign","1091":"Wall Sign","1092":"Wall Sign","1093":"Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Wooden Pressure Plate","1153":"Wooden Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Wooden Trapdoor","1537":"Wooden Trapdoor","1538":"Wooden Trapdoor","1539":"Wooden Trapdoor","1540":"Wooden Trapdoor","1541":"Wooden Trapdoor","1542":"Wooden Trapdoor","1543":"Wooden Trapdoor","1544":"Wooden Trapdoor","1545":"Wooden Trapdoor","1546":"Wooden Trapdoor","1547":"Wooden Trapdoor","1548":"Wooden Trapdoor","1549":"Wooden Trapdoor","1550":"Wooden Trapdoor","1551":"Wooden Trapdoor","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Wooden Button","2289":"Wooden Button","2290":"Wooden Button","2291":"Wooden Button","2292":"Wooden Button","2293":"Wooden Button","2296":"Wooden Button","2297":"Wooden Button","2298":"Wooden Button","2299":"Wooden Button","2300":"Wooden Button","2301":"Wooden Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Standing Banner","2817":"Standing Banner","2818":"Standing Banner","2819":"Standing Banner","2820":"Standing Banner","2821":"Standing Banner","2822":"Standing Banner","2823":"Standing Banner","2824":"Standing Banner","2825":"Standing Banner","2826":"Standing Banner","2827":"Standing Banner","2828":"Standing Banner","2829":"Standing Banner","2830":"Standing Banner","2831":"Standing Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6"} \ No newline at end of file From edf4a719d5e98aeb2d95eab2350ac0dc10a3db79 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Feb 2019 17:16:35 +0000 Subject: [PATCH 0550/3224] DyeColor: add RGB colour values --- src/pocketmine/block/utils/DyeColor.php | 46 ++++++++++++++++--------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/src/pocketmine/block/utils/DyeColor.php b/src/pocketmine/block/utils/DyeColor.php index c25ef02204..35a5bb9d09 100644 --- a/src/pocketmine/block/utils/DyeColor.php +++ b/src/pocketmine/block/utils/DyeColor.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\block\utils; +use pocketmine\utils\Color; + final class DyeColor{ /** @var DyeColor */ @@ -133,22 +135,22 @@ final class DyeColor{ * @internal */ public static function _init() : void{ - self::register(self::$WHITE = new DyeColor("White", 0)); - self::register(self::$ORANGE = new DyeColor("Orange", 1)); - self::register(self::$MAGENTA = new DyeColor("Magenta", 2)); - self::register(self::$LIGHT_BLUE = new DyeColor("Light Blue", 3)); - self::register(self::$YELLOW = new DyeColor("Yellow", 4)); - self::register(self::$LIME = new DyeColor("Lime", 5)); - self::register(self::$PINK = new DyeColor("Pink", 6)); - self::register(self::$GRAY = new DyeColor("Gray", 7)); - self::register(self::$LIGHT_GRAY = new DyeColor("Light Gray", 8)); - self::register(self::$CYAN = new DyeColor("Cyan", 9)); - self::register(self::$PURPLE = new DyeColor("Purple", 10)); - self::register(self::$BLUE = new DyeColor("Blue", 11)); - self::register(self::$BROWN = new DyeColor("Brown", 12)); - self::register(self::$GREEN = new DyeColor("Green", 13)); - self::register(self::$RED = new DyeColor("Red", 14)); - self::register(self::$BLACK = new DyeColor("Black", 15)); + self::register(self::$WHITE = new DyeColor("White", 0, new Color(0xf0, 0xf0, 0xf0))); + self::register(self::$ORANGE = new DyeColor("Orange", 1, new Color(0xf9, 0x80, 0x1d))); + self::register(self::$MAGENTA = new DyeColor("Magenta", 2, new Color(0xc7, 0x4e, 0xbd))); + self::register(self::$LIGHT_BLUE = new DyeColor("Light Blue", 3, new Color(0x3a, 0xb3, 0xda))); + self::register(self::$YELLOW = new DyeColor("Yellow", 4, new Color(0xfe, 0xd8, 0x3d))); + self::register(self::$LIME = new DyeColor("Lime", 5, new Color(0x80, 0xc7, 0x1f))); + self::register(self::$PINK = new DyeColor("Pink", 6, new Color(0xf3, 0x8b, 0xaa))); + self::register(self::$GRAY = new DyeColor("Gray", 7, new Color(0x47, 0x4f, 0x52))); + self::register(self::$LIGHT_GRAY = new DyeColor("Light Gray", 8, new Color(0x9d, 0x9d, 0x97))); + self::register(self::$CYAN = new DyeColor("Cyan", 9, new Color(0x16, 0x9c, 0x9c))); + self::register(self::$PURPLE = new DyeColor("Purple", 10, new Color(0x89, 0x32, 0xb8))); + self::register(self::$BLUE = new DyeColor("Blue", 11, new Color(0x3c, 0x44, 0xaa))); + self::register(self::$BROWN = new DyeColor("Brown", 12, new Color(0x83, 0x54, 0x32))); + self::register(self::$GREEN = new DyeColor("Green", 13, new Color(0x5e, 0x7c, 0x16))); + self::register(self::$RED = new DyeColor("Red", 14, new Color(0xb0, 0x2e, 0x26))); + self::register(self::$BLACK = new DyeColor("Black", 15, new Color(0x1d, 0x1d, 0x21))); } private static function register(DyeColor $color) : void{ @@ -187,10 +189,13 @@ final class DyeColor{ private $displayName; /** @var int */ private $magicNumber; + /** @var Color */ + private $rgbValue; - private function __construct(string $displayName, int $magicNumber){ + private function __construct(string $displayName, int $magicNumber, Color $rgbValue){ $this->displayName = $displayName; $this->magicNumber = $magicNumber; + $this->rgbValue = $rgbValue; } /** @@ -200,6 +205,13 @@ final class DyeColor{ return $this->displayName; } + /** + * @return Color + */ + public function getRgbValue() : Color{ + return $this->rgbValue; + } + /** * @return int */ From cb91afcc0037374a35cea29aba82dca484acf9c6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Feb 2019 18:27:30 +0000 Subject: [PATCH 0551/3224] Added SkullType enum, some cleanup to skull handling this is still more ugly than I'd like it to be because of the way the blockfactory currently works. --- src/pocketmine/block/Skull.php | 33 ++++-- src/pocketmine/block/utils/SkullType.php | 131 +++++++++++++++++++++++ src/pocketmine/item/ItemFactory.php | 12 +-- src/pocketmine/item/Skull.php | 47 ++++++++ src/pocketmine/tile/Skull.php | 52 +++++---- 5 files changed, 242 insertions(+), 33 deletions(-) create mode 100644 src/pocketmine/block/utils/SkullType.php create mode 100644 src/pocketmine/item/Skull.php diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index da62c2c26d..c067fc3d87 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -24,24 +24,33 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\SkullType; use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\item\Skull as ItemSkull; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Skull as TileSkull; +use function assert; use function floor; class Skull extends Flowable{ + /** @var SkullType */ + protected $skullType; /** @var int */ protected $facing = Facing::NORTH; - protected $type = TileSkull::TYPE_SKELETON; /** @var int */ protected $rotation = 0; //TODO: split this into floor skull and wall skull handling + public function __construct(BlockIdentifier $idInfo, string $name){ + $this->skullType = SkullType::SKELETON(); //TODO: this should be a parameter + parent::__construct($idInfo, $name); + } + protected function writeStateToMeta() : int{ return $this->facing; } @@ -58,7 +67,7 @@ class Skull extends Flowable{ parent::readStateFromWorld(); $tile = $this->level->getTile($this); if($tile instanceof TileSkull){ - $this->type = $tile->getType(); + $this->skullType = $tile->getSkullType(); $this->rotation = $tile->getRotation(); } } @@ -67,16 +76,22 @@ class Skull extends Flowable{ parent::writeStateToWorld(); //extra block properties storage hack $tile = $this->level->getTile($this); - if($tile instanceof TileSkull){ - $tile->setRotation($this->rotation); - $tile->setType($this->type); - } + assert($tile instanceof TileSkull); + $tile->setRotation($this->rotation); + $tile->setSkullType($this->skullType); } public function getHardness() : float{ return 1; } + /** + * @return SkullType + */ + public function getSkullType() : SkullType{ + return $this->skullType; + } + protected function recalculateBoundingBox() : ?AxisAlignedBB{ //TODO: different bounds depending on attached face return AxisAlignedBB::one()->contract(0.25, 0, 0.25)->trim(Facing::UP, 0.5); @@ -88,7 +103,9 @@ class Skull extends Flowable{ } $this->facing = $face; - $this->type = $item->getDamage(); //TODO: replace this with a proper variant getter + if($item instanceof ItemSkull){ + $this->skullType = $item->getSkullType(); //TODO: the item should handle this, but this hack is currently needed because of tile mess + } if($player !== null and $face === Facing::UP){ $this->rotation = ((int) floor(($player->yaw * 16 / 360) + 0.5)) & 0xf; } @@ -96,7 +113,7 @@ class Skull extends Flowable{ } public function asItem() : Item{ - return ItemFactory::get(Item::SKULL, $this->type); + return ItemFactory::get(Item::SKULL, $this->skullType->getMagicNumber()); } public function isAffectedBySilkTouch() : bool{ diff --git a/src/pocketmine/block/utils/SkullType.php b/src/pocketmine/block/utils/SkullType.php new file mode 100644 index 0000000000..ecbdd93028 --- /dev/null +++ b/src/pocketmine/block/utils/SkullType.php @@ -0,0 +1,131 @@ +getMagicNumber()] = $type; + self::$all[] = $type; + } + + /** + * @return SkullType[] + */ + public static function getAll() : array{ + return self::$all; + } + + /** + * @internal + * @param int $magicNumber + * + * @return SkullType + * @throws \InvalidArgumentException + */ + public static function fromMagicNumber(int $magicNumber) : SkullType{ + if(!isset(self::$numericIdMap[$magicNumber])){ + throw new \InvalidArgumentException("Unknown skull type magic number $magicNumber"); + } + return self::$numericIdMap[$magicNumber]; + } + + /** @var string */ + private $displayName; + /** @var int */ + private $magicNumber; + + public function __construct(string $displayName, int $magicNumber){ + $this->displayName = $displayName; + $this->magicNumber = $magicNumber; + } + + /** + * @return string + */ + public function getDisplayName() : string{ + return $this->displayName; + } + + /** + * @return int + */ + public function getMagicNumber() : int{ + return $this->magicNumber; + } +} +SkullType::_init(); diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 7527a5d999..5f5a57844e 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -26,10 +26,10 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\utils\DyeColor; +use pocketmine\block\utils\SkullType; use pocketmine\entity\EntityFactory; use pocketmine\entity\Living; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\tile\Skull; use function constant; use function defined; use function explode; @@ -172,12 +172,6 @@ class ItemFactory{ self::register(new ItemBlock(Block::NETHER_WART_PLANT, 0, Item::NETHER_WART)); self::register(new ItemBlock(Block::OAK_DOOR_BLOCK, 0, Item::OAK_DOOR)); self::register(new ItemBlock(Block::REPEATER_BLOCK, 0, Item::REPEATER)); - self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_CREEPER, Item::SKULL)); - self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_DRAGON, Item::SKULL)); - self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_HUMAN, Item::SKULL)); - self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_SKELETON, Item::SKULL)); - self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_WITHER, Item::SKULL)); - self::register(new ItemBlock(Block::SKULL_BLOCK, Skull::TYPE_ZOMBIE, Item::SKULL)); self::register(new ItemBlock(Block::SPRUCE_DOOR_BLOCK, 0, Item::SPRUCE_DOOR)); self::register(new ItemBlock(Block::SUGARCANE_BLOCK, 0, Item::SUGARCANE)); self::register(new LeatherBoots()); @@ -236,6 +230,10 @@ class ItemFactory{ self::register(new WritableBook()); self::register(new WrittenBook()); + foreach(SkullType::getAll() as $skullType){ + self::register(new Skull(Item::SKULL, $skullType->getMagicNumber(), $skullType->getDisplayName(), $skullType)); + } + /** @var int[]|\SplObjectStorage $dyeMap */ $dyeMap = new \SplObjectStorage(); $dyeMap[DyeColor::BLACK()] = 16; diff --git a/src/pocketmine/item/Skull.php b/src/pocketmine/item/Skull.php new file mode 100644 index 0000000000..8ad4272434 --- /dev/null +++ b/src/pocketmine/item/Skull.php @@ -0,0 +1,47 @@ +skullType = $skullType; + } + + public function getBlock() : Block{ + return BlockFactory::get(Block::SKULL_BLOCK); + } + + public function getSkullType() : SkullType{ + return $this->skullType; + } +} diff --git a/src/pocketmine/tile/Skull.php b/src/pocketmine/tile/Skull.php index 87876a76c7..42802db666 100644 --- a/src/pocketmine/tile/Skull.php +++ b/src/pocketmine/tile/Skull.php @@ -23,42 +23,58 @@ declare(strict_types=1); namespace pocketmine\tile; +use pocketmine\block\utils\SkullType; +use pocketmine\level\Level; +use pocketmine\math\Vector3; +use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; +/** + * @deprecated + * @see \pocketmine\block\Skull + */ class Skull extends Spawnable{ - public const TYPE_SKELETON = 0; - public const TYPE_WITHER = 1; - public const TYPE_ZOMBIE = 2; - public const TYPE_HUMAN = 3; - public const TYPE_CREEPER = 4; - public const TYPE_DRAGON = 5; - public const TAG_SKULL_TYPE = "SkullType"; //TAG_Byte - public const TAG_ROT = "Rot"; //TAG_Byte - public const TAG_MOUTH_MOVING = "MouthMoving"; //TAG_Byte - public const TAG_MOUTH_TICK_COUNT = "MouthTickCount"; //TAG_Int + private const TAG_SKULL_TYPE = "SkullType"; //TAG_Byte + private const TAG_ROT = "Rot"; //TAG_Byte + private const TAG_MOUTH_MOVING = "MouthMoving"; //TAG_Byte + private const TAG_MOUTH_TICK_COUNT = "MouthTickCount"; //TAG_Int - /** @var int */ - private $skullType = self::TYPE_SKELETON; + /** @var SkullType */ + private $skullType; /** @var int */ private $skullRotation = 0; + public function __construct(Level $level, Vector3 $pos){ + $this->skullType = SkullType::SKELETON(); + parent::__construct($level, $pos); + } + public function readSaveData(CompoundTag $nbt) : void{ - $this->skullType = $nbt->getByte(self::TAG_SKULL_TYPE, $this->skullType, true); - $this->skullRotation = $nbt->getByte(self::TAG_ROT, $this->skullRotation, true); + if($nbt->hasTag(self::TAG_SKULL_TYPE, ByteTag::class)){ + try{ + $this->skullType = SkullType::fromMagicNumber($nbt->getByte(self::TAG_SKULL_TYPE)); + }catch(\InvalidArgumentException $e){ + //bad data, drop it + } + } + $rotation = $nbt->getByte(self::TAG_ROT, 0, true); + if($rotation >= 0 and $rotation <= 15){ + $this->skullRotation = $rotation; + } } protected function writeSaveData(CompoundTag $nbt) : void{ - $nbt->setByte(self::TAG_SKULL_TYPE, $this->skullType); + $nbt->setByte(self::TAG_SKULL_TYPE, $this->skullType->getMagicNumber()); $nbt->setByte(self::TAG_ROT, $this->skullRotation); } - public function setType(int $type){ + public function setSkullType(SkullType $type){ $this->skullType = $type; $this->onChanged(); } - public function getType() : int{ + public function getSkullType() : SkullType{ return $this->skullType; } @@ -72,7 +88,7 @@ class Skull extends Spawnable{ } protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ - $nbt->setByte(self::TAG_SKULL_TYPE, $this->skullType); + $nbt->setByte(self::TAG_SKULL_TYPE, $this->skullType->getMagicNumber()); $nbt->setByte(self::TAG_ROT, $this->skullRotation); } } From ceaf969203b57d7ace05af9946b1182020b607f4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Feb 2019 19:41:56 +0000 Subject: [PATCH 0552/3224] EnderChest: fix hierarchy --- src/pocketmine/block/Chest.php | 1 - src/pocketmine/block/EnderChest.php | 35 ++++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index 757e67c3dc..be2f38ea1d 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -67,7 +67,6 @@ class Chest extends Transparent{ } if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - //TODO: this is fragile and might have unintended side effects on ender chests if modified carelessly $tile = $this->level->getTile($this); if($tile instanceof TileChest){ foreach([ diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index 59c3429c36..6630ffcb0f 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -23,15 +23,32 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; +use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\EnderChest as TileEnderChest; -class EnderChest extends Chest{ +class EnderChest extends Transparent{ + + /** @var int */ + protected $facing = Facing::NORTH; + + protected function writeStateToMeta() : int{ + return $this->facing; + } + + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); + } + + public function getStateBitmask() : int{ + return 0b111; + } public function getHardness() : float{ return 22.5; @@ -53,6 +70,18 @@ class EnderChest extends Chest{ return TieredTool::TIER_WOODEN; } + protected function recalculateBoundingBox() : ?AxisAlignedBB{ + //these are slightly bigger than in PC + return AxisAlignedBB::one()->contract(0.025, 0, 0.025)->trim(Facing::UP, 0.05); + } + + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($player !== null){ + $this->facing = Facing::opposite($player->getHorizontalFacing()); + } + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ $enderChest = $this->getLevel()->getTile($this); @@ -70,8 +99,4 @@ class EnderChest extends Chest{ ItemFactory::get(Item::OBSIDIAN, 0, 8) ]; } - - public function getFuelTime() : int{ - return 0; - } } From 2d8480d801408bdd0c484660c7e4d677212db796 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 27 Feb 2019 10:36:05 +0000 Subject: [PATCH 0553/3224] Inventory: remove a bunch of crap from interface some of these (notably the on* methods) are internal and shouldn't be exposed via interface (same crap as Plugin->onEnable() onDisable() etc) and the rest of the stuff is entirely unused. --- src/pocketmine/inventory/AnvilInventory.php | 6 +---- src/pocketmine/inventory/ArmorInventory.php | 4 --- src/pocketmine/inventory/BaseInventory.php | 21 +++------------ src/pocketmine/inventory/ChestInventory.php | 8 ++---- .../inventory/ContainerInventory.php | 6 ++--- src/pocketmine/inventory/CraftingGrid.php | 4 --- .../inventory/DoubleChestInventory.php | 8 ++---- src/pocketmine/inventory/EnchantInventory.php | 6 +---- .../inventory/EnderChestInventory.php | 4 --- src/pocketmine/inventory/FurnaceInventory.php | 4 --- src/pocketmine/inventory/Inventory.php | 27 ------------------- .../inventory/PlayerCursorInventory.php | 4 --- src/pocketmine/inventory/PlayerInventory.php | 4 --- 13 files changed, 13 insertions(+), 93 deletions(-) diff --git a/src/pocketmine/inventory/AnvilInventory.php b/src/pocketmine/inventory/AnvilInventory.php index c13d872513..37490a1057 100644 --- a/src/pocketmine/inventory/AnvilInventory.php +++ b/src/pocketmine/inventory/AnvilInventory.php @@ -40,10 +40,6 @@ class AnvilInventory extends ContainerInventory{ return WindowTypes::ANVIL; } - public function getName() : string{ - return "Anvil"; - } - public function getDefaultSize() : int{ return 2; //1 input, 1 material } @@ -56,7 +52,7 @@ class AnvilInventory extends ContainerInventory{ return $this->holder; } - public function onClose(Player $who) : void{ + protected function onClose(Player $who) : void{ parent::onClose($who); foreach($this->getContents() as $item){ diff --git a/src/pocketmine/inventory/ArmorInventory.php b/src/pocketmine/inventory/ArmorInventory.php index 7ecc438af1..ac51541291 100644 --- a/src/pocketmine/inventory/ArmorInventory.php +++ b/src/pocketmine/inventory/ArmorInventory.php @@ -50,10 +50,6 @@ class ArmorInventory extends BaseInventory{ return $this->holder; } - public function getName() : string{ - return "Armor"; - } - public function getDefaultSize() : int{ return 4; } diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index 17fe9e66c8..c0c8c1cf33 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -41,10 +41,6 @@ abstract class BaseInventory implements Inventory{ /** @var int */ protected $maxStackSize = Inventory::MAX_STACK; - /** @var string */ - protected $name; - /** @var string */ - protected $title; /** @var \SplFixedArray|Item[] */ protected $slots = []; /** @var Player[] */ @@ -55,21 +51,13 @@ abstract class BaseInventory implements Inventory{ /** * @param Item[] $items * @param int $size - * @param string $title */ - public function __construct(array $items = [], ?int $size = null, ?string $title = null){ + public function __construct(array $items = [], ?int $size = null){ $this->slots = new \SplFixedArray($size ?? $this->getDefaultSize()); - $this->title = $title ?? $this->getName(); $this->setContents($items, false); } - abstract public function getName() : string; - - public function getTitle() : string{ - return $this->title; - } - /** * Returns the size of the inventory. * @return int @@ -401,21 +389,20 @@ abstract class BaseInventory implements Inventory{ $this->onClose($who); } - public function onOpen(Player $who) : void{ + protected function onOpen(Player $who) : void{ $this->viewers[spl_object_id($who)] = $who; } - public function onClose(Player $who) : void{ + protected function onClose(Player $who) : void{ unset($this->viewers[spl_object_id($who)]); } - public function onSlotChange(int $index, Item $before, bool $send) : void{ + protected function onSlotChange(int $index, Item $before, bool $send) : void{ if($send){ $this->sendSlot($index, $this->getViewers()); } } - /** * @param Player|Player[] $target */ diff --git a/src/pocketmine/inventory/ChestInventory.php b/src/pocketmine/inventory/ChestInventory.php index feb079d5f1..cbf63df122 100644 --- a/src/pocketmine/inventory/ChestInventory.php +++ b/src/pocketmine/inventory/ChestInventory.php @@ -46,10 +46,6 @@ class ChestInventory extends ContainerInventory{ return WindowTypes::CONTAINER; } - public function getName() : string{ - return "Chest"; - } - public function getDefaultSize() : int{ return 27; } @@ -70,7 +66,7 @@ class ChestInventory extends ContainerInventory{ return LevelSoundEventPacket::SOUND_CHEST_CLOSED; } - public function onOpen(Player $who) : void{ + protected function onOpen(Player $who) : void{ parent::onOpen($who); if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){ @@ -80,7 +76,7 @@ class ChestInventory extends ContainerInventory{ } } - public function onClose(Player $who) : void{ + protected function onClose(Player $who) : void{ if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){ //TODO: this crap really shouldn't be managed by the inventory $this->broadcastBlockEventPacket(false); diff --git a/src/pocketmine/inventory/ContainerInventory.php b/src/pocketmine/inventory/ContainerInventory.php index b807b0b08f..3db1072f32 100644 --- a/src/pocketmine/inventory/ContainerInventory.php +++ b/src/pocketmine/inventory/ContainerInventory.php @@ -35,10 +35,10 @@ abstract class ContainerInventory extends BaseInventory{ public function __construct(Vector3 $holder, array $items = [], ?int $size = null, ?string $title = null){ $this->holder = $holder; - parent::__construct($items, $size, $title); + parent::__construct($items, $size); } - public function onOpen(Player $who) : void{ + protected function onOpen(Player $who) : void{ parent::onOpen($who); $pk = new ContainerOpenPacket(); $pk->windowId = $who->getWindowId($this); @@ -61,7 +61,7 @@ abstract class ContainerInventory extends BaseInventory{ $this->sendContents($who); } - public function onClose(Player $who) : void{ + protected function onClose(Player $who) : void{ $pk = new ContainerClosePacket(); $pk->windowId = $who->getWindowId($this); $who->sendDataPacket($pk); diff --git a/src/pocketmine/inventory/CraftingGrid.php b/src/pocketmine/inventory/CraftingGrid.php index 4beb9ed71a..1c2ca40e3d 100644 --- a/src/pocketmine/inventory/CraftingGrid.php +++ b/src/pocketmine/inventory/CraftingGrid.php @@ -65,10 +65,6 @@ class CraftingGrid extends BaseInventory{ throw new \BadMethodCallException("Cannot change the size of a crafting grid"); } - public function getName() : string{ - return "Crafting"; - } - public function setItem(int $index, Item $item, bool $send = true) : bool{ if(parent::setItem($index, $item, $send)){ $this->seekRecipeBounds(); diff --git a/src/pocketmine/inventory/DoubleChestInventory.php b/src/pocketmine/inventory/DoubleChestInventory.php index 45df2d92d1..06b4395513 100644 --- a/src/pocketmine/inventory/DoubleChestInventory.php +++ b/src/pocketmine/inventory/DoubleChestInventory.php @@ -43,10 +43,6 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ BaseInventory::__construct($items); } - public function getName() : string{ - return "Double Chest"; - } - public function getDefaultSize() : int{ return $this->left->getDefaultSize() + $this->right->getDefaultSize(); } @@ -113,7 +109,7 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ } } - public function onOpen(Player $who) : void{ + protected function onOpen(Player $who) : void{ parent::onOpen($who); if(count($this->getViewers()) === 1 and $this->right->getHolder()->isValid()){ @@ -121,7 +117,7 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ } } - public function onClose(Player $who) : void{ + protected function onClose(Player $who) : void{ if(count($this->getViewers()) === 1 and $this->right->getHolder()->isValid()){ $this->right->broadcastBlockEventPacket(false); } diff --git a/src/pocketmine/inventory/EnchantInventory.php b/src/pocketmine/inventory/EnchantInventory.php index 059b229b64..80709f5c99 100644 --- a/src/pocketmine/inventory/EnchantInventory.php +++ b/src/pocketmine/inventory/EnchantInventory.php @@ -40,10 +40,6 @@ class EnchantInventory extends ContainerInventory{ return WindowTypes::ENCHANTMENT; } - public function getName() : string{ - return "Enchantment Table"; - } - public function getDefaultSize() : int{ return 2; //1 input, 1 lapis } @@ -56,7 +52,7 @@ class EnchantInventory extends ContainerInventory{ return $this->holder; } - public function onClose(Player $who) : void{ + protected function onClose(Player $who) : void{ parent::onClose($who); foreach($this->getContents() as $item){ diff --git a/src/pocketmine/inventory/EnderChestInventory.php b/src/pocketmine/inventory/EnderChestInventory.php index ce0f1e51e0..f3dc11f76b 100644 --- a/src/pocketmine/inventory/EnderChestInventory.php +++ b/src/pocketmine/inventory/EnderChestInventory.php @@ -41,10 +41,6 @@ class EnderChestInventory extends ChestInventory{ return WindowTypes::CONTAINER; } - public function getName() : string{ - return "EnderChest"; - } - public function getDefaultSize() : int{ return 27; } diff --git a/src/pocketmine/inventory/FurnaceInventory.php b/src/pocketmine/inventory/FurnaceInventory.php index 00f876b761..1418adb47a 100644 --- a/src/pocketmine/inventory/FurnaceInventory.php +++ b/src/pocketmine/inventory/FurnaceInventory.php @@ -39,10 +39,6 @@ class FurnaceInventory extends ContainerInventory{ return WindowTypes::FURNACE; } - public function getName() : string{ - return "Furnace"; - } - public function getDefaultSize() : int{ return 3; //1 input, 1 fuel, 1 output } diff --git a/src/pocketmine/inventory/Inventory.php b/src/pocketmine/inventory/Inventory.php index cf251d03ea..edbdfc46ac 100644 --- a/src/pocketmine/inventory/Inventory.php +++ b/src/pocketmine/inventory/Inventory.php @@ -47,16 +47,6 @@ interface Inventory{ */ public function setMaxStackSize(int $size) : void; - /** - * @return string - */ - public function getName() : string; - - /** - * @return string - */ - public function getTitle() : string; - /** * @param int $index * @@ -212,11 +202,6 @@ interface Inventory{ */ public function getViewers() : array; - /** - * @param Player $who - */ - public function onOpen(Player $who) : void; - /** * Tries to open the inventory to a player * @@ -228,18 +213,6 @@ interface Inventory{ public function close(Player $who) : void; - /** - * @param Player $who - */ - public function onClose(Player $who) : void; - - /** - * @param int $index - * @param Item $before - * @param bool $send - */ - public function onSlotChange(int $index, Item $before, bool $send) : void; - /** * Returns whether the specified slot exists in the inventory. * diff --git a/src/pocketmine/inventory/PlayerCursorInventory.php b/src/pocketmine/inventory/PlayerCursorInventory.php index b967139f5f..370704f8d6 100644 --- a/src/pocketmine/inventory/PlayerCursorInventory.php +++ b/src/pocketmine/inventory/PlayerCursorInventory.php @@ -34,10 +34,6 @@ class PlayerCursorInventory extends BaseInventory{ parent::__construct(); } - public function getName() : string{ - return "Cursor"; - } - public function getDefaultSize() : int{ return 1; } diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index d6db90a992..fd566acd2e 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -48,10 +48,6 @@ class PlayerInventory extends BaseInventory{ parent::__construct(); } - public function getName() : string{ - return "Player"; - } - public function getDefaultSize() : int{ return 36; } From 31336a0d0971289b438312e8c6cba4c241493b9e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 27 Feb 2019 10:37:13 +0000 Subject: [PATCH 0554/3224] missed one --- src/pocketmine/inventory/ContainerInventory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/inventory/ContainerInventory.php b/src/pocketmine/inventory/ContainerInventory.php index 3db1072f32..4a808ca576 100644 --- a/src/pocketmine/inventory/ContainerInventory.php +++ b/src/pocketmine/inventory/ContainerInventory.php @@ -33,7 +33,7 @@ abstract class ContainerInventory extends BaseInventory{ /** @var Vector3 */ protected $holder; - public function __construct(Vector3 $holder, array $items = [], ?int $size = null, ?string $title = null){ + public function __construct(Vector3 $holder, array $items = [], ?int $size = null){ $this->holder = $holder; parent::__construct($items, $size); } From ba616ed8a7691c603c8b8dc3d99d1835fc622cff Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 27 Feb 2019 11:01:26 +0000 Subject: [PATCH 0555/3224] Player: Don't rely on magic numbers for gamemodes --- src/pocketmine/Player.php | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 91dff1ea4a..521e3f83db 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1379,11 +1379,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool */ public function isSurvival(bool $literal = false) : bool{ - if($literal){ - return $this->gamemode === GameMode::SURVIVAL; - }else{ - return ($this->gamemode & 0x01) === 0; - } + return $this->gamemode === GameMode::SURVIVAL or (!$literal and $this->gamemode === GameMode::ADVENTURE); } /** @@ -1395,11 +1391,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool */ public function isCreative(bool $literal = false) : bool{ - if($literal){ - return $this->gamemode === GameMode::CREATIVE; - }else{ - return ($this->gamemode & 0x01) === 1; - } + return $this->gamemode === GameMode::CREATIVE or (!$literal and $this->gamemode === GameMode::SPECTATOR); } /** @@ -1411,11 +1403,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool */ public function isAdventure(bool $literal = false) : bool{ - if($literal){ - return $this->gamemode === GameMode::ADVENTURE; - }else{ - return ($this->gamemode & 0x02) > 0; - } + return $this->gamemode === GameMode::ADVENTURE or (!$literal and $this->gamemode === GameMode::SPECTATOR); } /** From 9ad0ea85c7caeea065ccfadf3bd12bd97cc5f0b6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 27 Feb 2019 12:59:12 +0000 Subject: [PATCH 0556/3224] Rename two misleadingly-named functions --- src/pocketmine/block/Block.php | 8 ++++---- src/pocketmine/block/BlockFactory.php | 2 +- src/pocketmine/block/Grass.php | 2 +- src/pocketmine/command/defaults/GiveCommand.php | 2 +- src/pocketmine/entity/object/FallingBlock.php | 2 +- src/pocketmine/entity/projectile/Projectile.php | 2 +- src/pocketmine/inventory/CraftingManager.php | 6 +++--- src/pocketmine/item/Durable.php | 4 ++++ src/pocketmine/item/Item.php | 12 ++++++------ src/pocketmine/item/ItemFactory.php | 2 +- src/pocketmine/level/SimpleChunkManager.php | 2 +- src/pocketmine/level/generator/Flat.php | 2 +- .../level/generator/populator/GroundCover.php | 2 +- src/pocketmine/level/particle/ItemBreakParticle.php | 2 +- src/pocketmine/network/mcpe/NetworkBinaryStream.php | 2 +- .../network/mcpe/protocol/CraftingDataPacket.php | 2 +- src/pocketmine/tile/FlowerPot.php | 4 ++-- src/pocketmine/tile/Furnace.php | 2 +- tests/phpunit/block/BlockTest.php | 2 +- tests/phpunit/item/ItemFactoryTest.php | 2 +- 20 files changed, 34 insertions(+), 30 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 1bbb61d4cf..36926fd1b1 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -116,13 +116,13 @@ class Block extends Position implements BlockIds, Metadatable{ * @return int */ public function getRuntimeId() : int{ - return BlockFactory::toStaticRuntimeId($this->getId(), $this->getDamage()); + return BlockFactory::toStaticRuntimeId($this->getId(), $this->getMeta()); } /** * @return int */ - public function getDamage() : int{ + public function getMeta() : int{ $stateMeta = $this->writeStateToMeta(); assert(($stateMeta & ~$this->getStateBitmask()) === 0); return $this->idInfo->getVariant() | $stateMeta; @@ -155,7 +155,7 @@ class Block extends Position implements BlockIds, Metadatable{ } public function writeStateToWorld() : void{ - $this->level->getChunkAtPosition($this)->setBlock($this->x & 0xf, $this->y, $this->z & 0xf, $this->getId(), $this->getDamage()); + $this->level->getChunkAtPosition($this)->setBlock($this->x & 0xf, $this->y, $this->z & 0xf, $this->getId(), $this->getMeta()); $tileType = $this->idInfo->getTileClass(); $oldTile = $this->level->getTile($this); @@ -692,7 +692,7 @@ class Block extends Position implements BlockIds, Metadatable{ * @return string */ public function __toString(){ - return "Block[" . $this->getName() . "] (" . $this->getId() . ":" . $this->getDamage() . ")"; + return "Block[" . $this->getName() . "] (" . $this->getId() . ":" . $this->getMeta() . ")"; } /** diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 4db1f4b9e6..b51dab9d06 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -555,7 +555,7 @@ class BlockFactory{ $v = clone $block; try{ $v->readStateFromData($id, $m & $stateMask); - if($v->getDamage() !== $m){ + if($v->getMeta() !== $m){ throw new InvalidBlockStateException("Corrupted meta"); //don't register anything that isn't the same when we read it back again } }catch(InvalidBlockStateException $e){ //invalid property combination diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index 39c4eaa302..4f095efba1 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -75,7 +75,7 @@ class Grass extends Solid{ $b = $this->level->getBlockAt($x, $y, $z); if( $b->getId() !== Block::DIRT or - $b->getDamage() === 1 or //coarse dirt + $b->getMeta() === 1 or //coarse dirt $this->level->getFullLightAt($x, $y + 1, $z) < 4 or $this->level->getBlockAt($x, $y + 1, $z)->getLightFilter() >= 2 ){ diff --git a/src/pocketmine/command/defaults/GiveCommand.php b/src/pocketmine/command/defaults/GiveCommand.php index 0e43bcac1a..c84ee33456 100644 --- a/src/pocketmine/command/defaults/GiveCommand.php +++ b/src/pocketmine/command/defaults/GiveCommand.php @@ -90,7 +90,7 @@ class GiveCommand extends VanillaCommand{ $player->getInventory()->addItem(clone $item); Command::broadcastCommandMessage($sender, new TranslationContainer("%commands.give.success", [ - $item->getName() . " (" . $item->getId() . ":" . $item->getDamage() . ")", + $item->getName() . " (" . $item->getId() . ":" . $item->getMeta() . ")", (string) $item->getCount(), $player->getName() ])); diff --git a/src/pocketmine/entity/object/FallingBlock.php b/src/pocketmine/entity/object/FallingBlock.php index d13a588024..4016ceed7f 100644 --- a/src/pocketmine/entity/object/FallingBlock.php +++ b/src/pocketmine/entity/object/FallingBlock.php @@ -132,7 +132,7 @@ class FallingBlock extends Entity{ public function saveNBT() : CompoundTag{ $nbt = parent::saveNBT(); $nbt->setInt("TileID", $this->block->getId()); - $nbt->setByte("Data", $this->block->getDamage()); + $nbt->setByte("Data", $this->block->getMeta()); return $nbt; } diff --git a/src/pocketmine/entity/projectile/Projectile.php b/src/pocketmine/entity/projectile/Projectile.php index b6ef1154de..57bb71307a 100644 --- a/src/pocketmine/entity/projectile/Projectile.php +++ b/src/pocketmine/entity/projectile/Projectile.php @@ -154,7 +154,7 @@ abstract class Projectile extends Entity{ //we intentionally use different ones to PC because we don't have stringy IDs $nbt->setInt("blockId", $this->blockHit->getId()); - $nbt->setByte("blockData", $this->blockHit->getDamage()); + $nbt->setByte("blockData", $this->blockHit->getMeta()); } return $nbt; diff --git a/src/pocketmine/inventory/CraftingManager.php b/src/pocketmine/inventory/CraftingManager.php index 8cb3e843ff..b35f3a9e51 100644 --- a/src/pocketmine/inventory/CraftingManager.php +++ b/src/pocketmine/inventory/CraftingManager.php @@ -139,7 +139,7 @@ class CraftingManager{ */ public static function sort(Item $i1, Item $i2){ //Use spaceship operator to compare each property, then try the next one if they are equivalent. - ($retval = $i1->getId() <=> $i2->getId()) === 0 && ($retval = $i1->getDamage() <=> $i2->getDamage()) === 0 && ($retval = $i1->getCount() <=> $i2->getCount()); + ($retval = $i1->getId() <=> $i2->getId()) === 0 && ($retval = $i1->getMeta() <=> $i2->getMeta()) === 0 && ($retval = $i1->getCount() <=> $i2->getCount()); return $retval; } @@ -223,7 +223,7 @@ class CraftingManager{ */ public function registerFurnaceRecipe(FurnaceRecipe $recipe) : void{ $input = $recipe->getInput(); - $this->furnaceRecipes[$input->getId() . ":" . ($input->hasAnyDamageValue() ? "?" : $input->getDamage())] = $recipe; + $this->furnaceRecipes[$input->getId() . ":" . ($input->hasAnyDamageValue() ? "?" : $input->getMeta())] = $recipe; $this->craftingDataCache = null; } @@ -286,6 +286,6 @@ class CraftingManager{ * @return FurnaceRecipe|null */ public function matchFurnaceRecipe(Item $input) : ?FurnaceRecipe{ - return $this->furnaceRecipes[$input->getId() . ":" . $input->getDamage()] ?? $this->furnaceRecipes[$input->getId() . ":?"] ?? null; + return $this->furnaceRecipes[$input->getId() . ":" . $input->getMeta()] ?? $this->furnaceRecipes[$input->getId() . ":?"] ?? null; } } diff --git a/src/pocketmine/item/Durable.php b/src/pocketmine/item/Durable.php index 6cd8af7801..0f43bd125b 100644 --- a/src/pocketmine/item/Durable.php +++ b/src/pocketmine/item/Durable.php @@ -33,6 +33,10 @@ abstract class Durable extends Item{ /** @var int */ protected $damage = 0; + public function getMeta() : int{ + return $this->damage; + } + /** * Returns whether this item will take damage when used. * @return bool diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index c5e409b0ec..259adb6829 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -657,7 +657,7 @@ class Item implements ItemIds, \JsonSerializable{ /** * @return int */ - public function getDamage() : int{ + public function getMeta() : int{ return $this->meta; } @@ -811,7 +811,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return bool */ final public function equals(Item $item, bool $checkDamage = true, bool $checkCompound = true) : bool{ - if($this->id === $item->getId() and (!$checkDamage or $this->getDamage() === $item->getDamage())){ + if($this->id === $item->getId() and (!$checkDamage or $this->getMeta() === $item->getMeta())){ if($checkCompound){ if($this->hasNamedTag() and $item->hasNamedTag()){ //both items have NBT return $this->getNamedTag()->equals($item->getNamedTag()); @@ -841,7 +841,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return string */ final public function __toString() : string{ - return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->getDamage()) . ")x" . $this->count . ($this->hasNamedTag() ? " tags:0x" . self::writeCompoundTag($this->nbt) : ""); + return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->getMeta()) . ")x" . $this->count . ($this->hasNamedTag() ? " tags:0x" . self::writeCompoundTag($this->nbt) : ""); } /** @@ -854,8 +854,8 @@ class Item implements ItemIds, \JsonSerializable{ "id" => $this->getId() ]; - if($this->getDamage() !== 0){ - $data["damage"] = $this->getDamage(); + if($this->getMeta() !== 0){ + $data["damage"] = $this->getMeta(); } if($this->getCount() !== 1){ @@ -904,7 +904,7 @@ class Item implements ItemIds, \JsonSerializable{ $result = new CompoundTag($tagName, [ new ShortTag("id", $this->id), new ByteTag("Count", Binary::signByte($this->count)), - new ShortTag("Damage", $this->getDamage()) + new ShortTag("Damage", $this->getMeta()) ]); if($this->hasNamedTag()){ diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 5f5a57844e..d83c1e4e6b 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -330,7 +330,7 @@ class ItemFactory{ */ public static function register(Item $item, bool $override = false){ $id = $item->getId(); - $variant = $item->getDamage(); + $variant = $item->getMeta(); if(!$override and self::isRegistered($id, $variant)){ throw new \RuntimeException("Trying to overwrite an already registered item"); diff --git a/src/pocketmine/level/SimpleChunkManager.php b/src/pocketmine/level/SimpleChunkManager.php index a51452cef6..aa875b3717 100644 --- a/src/pocketmine/level/SimpleChunkManager.php +++ b/src/pocketmine/level/SimpleChunkManager.php @@ -54,7 +54,7 @@ class SimpleChunkManager implements ChunkManager{ public function setBlockAt(int $x, int $y, int $z, Block $block) : bool{ if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ - return $chunk->setBlock($x & 0xf, $y, $z & 0xf, $block->getId(), $block->getDamage()); + return $chunk->setBlock($x & 0xf, $y, $z & 0xf, $block->getId(), $block->getMeta()); } return false; } diff --git a/src/pocketmine/level/generator/Flat.php b/src/pocketmine/level/generator/Flat.php index 2c488b74c6..220ec3a0e7 100644 --- a/src/pocketmine/level/generator/Flat.php +++ b/src/pocketmine/level/generator/Flat.php @@ -116,7 +116,7 @@ class Flat extends Generator{ throw new InvalidGeneratorOptionsException("Invalid preset layer \"$line\": " . $e->getMessage(), 0, $e); } for($cY = $y, $y += $cnt; $cY < $y; ++$cY){ - $result[$cY] = [$b->getId(), $b->getDamage()]; + $result[$cY] = [$b->getId(), $b->getMeta()]; } } diff --git a/src/pocketmine/level/generator/populator/GroundCover.php b/src/pocketmine/level/generator/populator/GroundCover.php index 9e36da3370..6127d66a0c 100644 --- a/src/pocketmine/level/generator/populator/GroundCover.php +++ b/src/pocketmine/level/generator/populator/GroundCover.php @@ -64,7 +64,7 @@ class GroundCover extends Populator{ continue; } - $chunk->setBlock($x, $y, $z, $b->getId(), $b->getDamage()); + $chunk->setBlock($x, $y, $z, $b->getId(), $b->getMeta()); } } } diff --git a/src/pocketmine/level/particle/ItemBreakParticle.php b/src/pocketmine/level/particle/ItemBreakParticle.php index 0baffed371..3e706c6876 100644 --- a/src/pocketmine/level/particle/ItemBreakParticle.php +++ b/src/pocketmine/level/particle/ItemBreakParticle.php @@ -28,6 +28,6 @@ use pocketmine\network\mcpe\protocol\types\ParticleIds; class ItemBreakParticle extends GenericParticle{ public function __construct(Item $item){ - parent::__construct(ParticleIds::ITEM_BREAK, ($item->getId() << 16) | $item->getDamage()); + parent::__construct(ParticleIds::ITEM_BREAK, ($item->getId() << 16) | $item->getMeta()); } } diff --git a/src/pocketmine/network/mcpe/NetworkBinaryStream.php b/src/pocketmine/network/mcpe/NetworkBinaryStream.php index 3c78b3cbf6..160bac86b8 100644 --- a/src/pocketmine/network/mcpe/NetworkBinaryStream.php +++ b/src/pocketmine/network/mcpe/NetworkBinaryStream.php @@ -132,7 +132,7 @@ class NetworkBinaryStream extends BinaryStream{ } $this->putVarInt($item->getId()); - $auxValue = (($item->getDamage() & 0x7fff) << 8) | $item->getCount(); + $auxValue = (($item->getMeta() & 0x7fff) << 8) | $item->getCount(); $this->putVarInt($auxValue); if($item->hasNamedTag()){ diff --git a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php b/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php index f3940dd82c..781ad8392a 100644 --- a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php @@ -169,7 +169,7 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{ private static function writeFurnaceRecipe(FurnaceRecipe $recipe, NetworkBinaryStream $stream) : int{ if(!$recipe->getInput()->hasAnyDamageValue()){ //Data recipe $stream->putVarInt($recipe->getInput()->getId()); - $stream->putVarInt($recipe->getInput()->getDamage()); + $stream->putVarInt($recipe->getInput()->getMeta()); $stream->putSlot($recipe->getResult()); return CraftingDataPacket::ENTRY_FURNACE_DATA; diff --git a/src/pocketmine/tile/FlowerPot.php b/src/pocketmine/tile/FlowerPot.php index ccfc5bc314..a9005c7067 100644 --- a/src/pocketmine/tile/FlowerPot.php +++ b/src/pocketmine/tile/FlowerPot.php @@ -55,7 +55,7 @@ class FlowerPot extends Spawnable{ protected function writeSaveData(CompoundTag $nbt) : void{ if($this->plant !== null){ $nbt->setShort(self::TAG_ITEM, $this->plant->getId()); - $nbt->setInt(self::TAG_ITEM_DATA, $this->plant->getDamage()); + $nbt->setInt(self::TAG_ITEM_DATA, $this->plant->getMeta()); } } @@ -75,7 +75,7 @@ class FlowerPot extends Spawnable{ protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ if($this->plant !== null){ $nbt->setShort(self::TAG_ITEM, $this->plant->getId()); - $nbt->setInt(self::TAG_ITEM_DATA, $this->plant->getDamage()); + $nbt->setInt(self::TAG_ITEM_DATA, $this->plant->getMeta()); } } } diff --git a/src/pocketmine/tile/Furnace.php b/src/pocketmine/tile/Furnace.php index b98dd5b551..29dbc53c59 100644 --- a/src/pocketmine/tile/Furnace.php +++ b/src/pocketmine/tile/Furnace.php @@ -177,7 +177,7 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ ++$this->cookTime; if($this->cookTime >= 200){ //10 seconds - $product = ItemFactory::get($smelt->getResult()->getId(), $smelt->getResult()->getDamage(), $product->getCount() + 1); + $product = ItemFactory::get($smelt->getResult()->getId(), $smelt->getResult()->getMeta(), $product->getCount() + 1); $ev = new FurnaceSmeltEvent($this, $raw, $product); $ev->call(); diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index 5931f9c2bb..faf52a96a1 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -119,7 +119,7 @@ class BlockTest extends TestCase{ $block = BlockFactory::get($id, $meta); self::assertEquals($id, $block->getId()); - self::assertEquals($meta, $block->getDamage()); + self::assertEquals($meta, $block->getMeta()); } public function testBlockIds() : void{ diff --git a/tests/phpunit/item/ItemFactoryTest.php b/tests/phpunit/item/ItemFactoryTest.php index c3d35c1a1b..5676f7b837 100644 --- a/tests/phpunit/item/ItemFactoryTest.php +++ b/tests/phpunit/item/ItemFactoryTest.php @@ -64,7 +64,7 @@ class ItemFactoryTest extends TestCase{ $item = ItemFactory::fromString($string); self::assertEquals($id, $item->getId()); - self::assertEquals($meta, $item->getDamage()); + self::assertEquals($meta, $item->getMeta()); } /** From 08673172c72a8b8cbb53696b3a430d03f20ce8d8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 27 Feb 2019 13:03:23 +0000 Subject: [PATCH 0557/3224] Grass: Avoid usage of meta --- src/pocketmine/block/Grass.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index 4f095efba1..493efc6206 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -74,8 +74,8 @@ class Grass extends Solid{ $b = $this->level->getBlockAt($x, $y, $z); if( - $b->getId() !== Block::DIRT or - $b->getMeta() === 1 or //coarse dirt + !($b instanceof Dirt) or + $b instanceof CoarseDirt or $this->level->getFullLightAt($x, $y + 1, $z) < 4 or $this->level->getBlockAt($x, $y + 1, $z)->getLightFilter() >= 2 ){ From fb02071a9dd42563bd6c9d82b00085159f90455a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 27 Feb 2019 16:50:51 +0000 Subject: [PATCH 0558/3224] Traits suck. Fixed missed getDamage() from 9ad0ea85c7caeea065ccfadf3bd12bd97cc5f0b6 --- src/pocketmine/block/utils/FallableTrait.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/block/utils/FallableTrait.php b/src/pocketmine/block/utils/FallableTrait.php index 026d39f85c..dfdebf58de 100644 --- a/src/pocketmine/block/utils/FallableTrait.php +++ b/src/pocketmine/block/utils/FallableTrait.php @@ -43,7 +43,7 @@ trait FallableTrait{ abstract protected function getId() : int; - abstract protected function getDamage() : int; + abstract protected function getMeta() : int; public function onNearbyBlockChange() : void{ $pos = $this->asPosition(); @@ -53,7 +53,7 @@ trait FallableTrait{ $nbt = EntityFactory::createBaseNBT($pos->add(0.5, 0, 0.5)); $nbt->setInt("TileID", $this->getId()); - $nbt->setByte("Data", $this->getDamage()); + $nbt->setByte("Data", $this->getMeta()); /** @var FallingBlock $fall */ $fall = EntityFactory::create(FallingBlock::class, $pos->getLevel(), $nbt); From d528fdddfabc9ff423077de02de877cdd69f27d0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Feb 2019 16:20:58 +0000 Subject: [PATCH 0559/3224] DataPacket: Remove useless abstract function this is declared in the Packet interface, so it doesn't need to be here anymore. --- .../network/mcpe/protocol/DataPacket.php | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/DataPacket.php b/src/pocketmine/network/mcpe/protocol/DataPacket.php index 3d683ee990..ffea84b634 100644 --- a/src/pocketmine/network/mcpe/protocol/DataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/DataPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; use pocketmine\utils\Utils; @@ -121,23 +120,6 @@ abstract class DataPacket extends NetworkBinaryStream implements Packet{ */ abstract protected function encodePayload() : void; - /** - * Performs handling for this packet. Usually you'll want an appropriately named method in the session handler for - * this. - * - * This method returns a bool to indicate whether the packet was handled or not. If the packet was unhandled, a - * debug message will be logged with a hexdump of the packet. - * - * Typically this method returns the return value of the handler in the supplied SessionHandler. See other packets - * for examples how to implement this. - * - * @param SessionHandler $handler - * - * @return bool true if the packet was handled successfully, false if not. - * @throws BadPacketException if broken data was found in the packet - */ - abstract public function handle(SessionHandler $handler) : bool; - public function __debugInfo(){ $data = []; foreach($this as $k => $v){ From 13b9fd7b66dd36588e40973eb84f41e2088d1612 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Feb 2019 16:31:14 +0000 Subject: [PATCH 0560/3224] RakLibInterface: Add error ID to make logs searchable when players report legitimate issues --- src/pocketmine/network/mcpe/RakLibInterface.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index c24a84d41b..15b4f02fbf 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -39,8 +39,10 @@ use raklib\server\ServerHandler; use raklib\server\ServerInstance; use raklib\utils\InternetAddress; use function addcslashes; +use function bin2hex; use function count; use function implode; +use function random_bytes; use function rtrim; use function spl_object_id; use function substr; @@ -159,15 +161,16 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ try{ $session->handleEncoded($buf); }catch(BadPacketException $e){ + $errorId = bin2hex(random_bytes(6)); $logger = $this->server->getLogger(); - $logger->error("Bad packet from $address $port: " . $e->getMessage()); + $logger->error("Bad packet from $address $port (error ID $errorId): " . $e->getMessage()); //intentionally doesn't use logException, we don't want spammy packet error traces to appear in release mode $logger->debug("Origin: " . Utils::cleanPath($e->getFile()) . "(" . $e->getLine() . ")"); foreach(Utils::printableTrace($e->getTrace()) as $frame){ $logger->debug($frame); } - $session->disconnect("Packet processing error"); + $session->disconnect("Packet processing error (Error ID: $errorId)"); $this->interface->blockAddress($address, 5); } } From f680a239f776f875639cd8ac9cf05020233a5277 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Feb 2019 16:36:03 +0000 Subject: [PATCH 0561/3224] NetworkSession: some exception handling cleanup --- .../network/mcpe/NetworkSession.php | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 6465646e82..a5089562cd 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -207,12 +207,18 @@ class NetworkSession{ while(!$stream->feof() and $this->connected){ try{ - $buf = $stream->getString(); + $pk = PacketPool::getPacket($stream->getString()); }catch(BinaryDataException $e){ $this->server->getLogger()->debug("Packet batch from " . $this->getDisplayName() . ": " . bin2hex($stream->getBuffer())); throw new BadPacketException("Packet batch decode error: " . $e->getMessage(), 0, $e); } - $this->handleDataPacket(PacketPool::getPacket($buf)); + + try{ + $this->handleDataPacket($pk); + }catch(BadPacketException $e){ + $this->server->getLogger()->debug($pk->getName() . " from " . $this->getDisplayName() . ": " . bin2hex($pk->getBuffer())); + throw new BadPacketException("Error processing " . $pk->getName() . ": " . $e->getMessage(), 0, $e); + } } } @@ -223,7 +229,7 @@ class NetworkSession{ */ public function handleDataPacket(Packet $packet) : void{ if(!($packet instanceof ServerboundPacket)){ - throw new BadPacketException("Unexpected non-serverbound packet " . $packet->getName()); + throw new BadPacketException("Unexpected non-serverbound packet"); } $timings = Timings::getReceiveDataPacketTimings($packet); @@ -231,22 +237,19 @@ class NetworkSession{ try{ $packet->decode(); - }catch(BadPacketException $e){ - $this->server->getLogger()->debug($packet->getName() . " from " . $this->getDisplayName() . ": " . bin2hex($packet->getBuffer())); - throw $e; - } - if(!$packet->feof() and !$packet->mayHaveUnreadBytes()){ - $remains = substr($packet->getBuffer(), $packet->getOffset()); - $this->server->getLogger()->debug("Still " . strlen($remains) . " bytes unread in " . $packet->getName() . ": " . bin2hex($remains)); - } + if(!$packet->feof() and !$packet->mayHaveUnreadBytes()){ + $remains = substr($packet->getBuffer(), $packet->getOffset()); + $this->server->getLogger()->debug("Still " . strlen($remains) . " bytes unread in " . $packet->getName() . ": " . bin2hex($remains)); + } - $ev = new DataPacketReceiveEvent($this->player, $packet); - $ev->call(); - if(!$ev->isCancelled() and !$packet->handle($this->handler)){ - $this->server->getLogger()->debug("Unhandled " . $packet->getName() . " received from " . $this->getDisplayName() . ": " . bin2hex($packet->getBuffer())); + $ev = new DataPacketReceiveEvent($this->player, $packet); + $ev->call(); + if(!$ev->isCancelled() and !$packet->handle($this->handler)){ + $this->server->getLogger()->debug("Unhandled " . $packet->getName() . " received from " . $this->getDisplayName() . ": " . bin2hex($packet->getBuffer())); + } + }finally{ + $timings->stopTiming(); } - - $timings->stopTiming(); } public function sendDataPacket(ClientboundPacket $packet, bool $immediate = false) : bool{ From 5cca4b5e31ded225dca3079548e2c1fd71431ea3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Feb 2019 17:10:37 +0000 Subject: [PATCH 0562/3224] Revamp Sign API, flatten API into blocks --- src/pocketmine/Player.php | 35 ----- src/pocketmine/block/SignPost.php | 61 ++++++++ .../event/block/SignChangeEvent.php | 82 +++++------ .../mcpe/handler/SimpleSessionHandler.php | 38 ++++- src/pocketmine/tile/Sign.php | 131 +++++------------- src/pocketmine/tile/Spawnable.php | 14 -- 6 files changed, 170 insertions(+), 191 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 521e3f83db..f48431571f 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -92,21 +92,17 @@ use pocketmine\level\Level; use pocketmine\level\Position; use pocketmine\math\Vector3; use pocketmine\metadata\MetadataValue; -use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\ListTag; -use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\NetworkCipher; -use pocketmine\network\mcpe\NetworkNbtSerializer; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\ProcessLoginTask; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; -use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\network\mcpe\protocol\BookEditPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; @@ -134,7 +130,6 @@ use pocketmine\permission\PermissionAttachment; use pocketmine\permission\PermissionAttachmentInfo; use pocketmine\permission\PermissionManager; use pocketmine\plugin\Plugin; -use pocketmine\tile\Spawnable; use pocketmine\tile\Tile; use pocketmine\timings\Timings; use pocketmine\utils\TextFormat; @@ -2457,36 +2452,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $handled; } - /** - * @param BlockEntityDataPacket $packet - * - * @return bool - * @throws BadPacketException - */ - public function handleBlockEntityData(BlockEntityDataPacket $packet) : bool{ - $this->doCloseInventory(); - - $pos = new Vector3($packet->x, $packet->y, $packet->z); - if($pos->distanceSquared($this) > 10000){ - return true; - } - - $t = $this->level->getTile($pos); - if($t instanceof Spawnable){ - $nbt = new NetworkNbtSerializer(); - try{ - $compound = $nbt->read($packet->namedtag); - }catch(NbtDataException $e){ - throw new BadPacketException($e->getMessage(), 0, $e); - } - if(!$t->updateCompoundTag($compound, $this)){ - $this->level->sendBlocks([$this], [$pos]); - } - } - - return true; - } - public function handleBookEdit(BookEditPacket $packet) : bool{ /** @var WritableBook $oldBook */ $oldBook = $this->inventory->getItem($packet->inventorySlot); diff --git a/src/pocketmine/block/SignPost.php b/src/pocketmine/block/SignPost.php index 1470fea51a..48748c6edc 100644 --- a/src/pocketmine/block/SignPost.php +++ b/src/pocketmine/block/SignPost.php @@ -23,11 +23,17 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\SignText; +use pocketmine\event\block\SignChangeEvent; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\tile\Sign as TileSign; +use pocketmine\utils\TextFormat; +use function array_map; +use function assert; use function floor; class SignPost extends Transparent{ @@ -35,6 +41,14 @@ class SignPost extends Transparent{ /** @var int */ protected $rotation = 0; + /** @var SignText */ + protected $text; + + public function __construct(BlockIdentifier $idInfo, string $name){ + parent::__construct($idInfo, $name); + $this->text = new SignText(); + } + protected function writeStateToMeta() : int{ return $this->rotation; } @@ -43,6 +57,21 @@ class SignPost extends Transparent{ $this->rotation = $stateMeta; } + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); + $tile = $this->level->getTile($this); + if($tile instanceof TileSign){ + $this->text = $tile->getText(); + } + } + + public function writeStateToWorld() : void{ + parent::writeStateToWorld(); + $tile = $this->level->getTile($this); + assert($tile instanceof TileSign); + $tile->setText($this->text); + } + public function getStateBitmask() : int{ return 0b1111; } @@ -82,4 +111,36 @@ class SignPost extends Transparent{ public function getToolType() : int{ return BlockToolType::TYPE_AXE; } + + /** + * Returns an object containing information about the sign text. + * + * @return SignText + */ + public function getText() : SignText{ + return $this->text; + } + + /** + * Called by the player controller (network session) to update the sign text, firing events as appropriate. + * + * @param Player $author + * @param SignText $text + * + * @return bool if the sign update was successful. + */ + public function updateText(Player $author, SignText $text) : bool{ + $removeFormat = $author->getRemoveFormat(); + $ev = new SignChangeEvent($this, $author, new SignText(array_map(function(string $line) use ($removeFormat){ + return TextFormat::clean($line, $removeFormat); + }, $text->getLines()))); + $ev->call(); + if(!$ev->isCancelled()){ + $this->text = clone $ev->getNewText(); + $this->level->setBlock($this, $this); + return true; + } + + return false; + } } diff --git a/src/pocketmine/event/block/SignChangeEvent.php b/src/pocketmine/event/block/SignChangeEvent.php index 267f002247..66af600e17 100644 --- a/src/pocketmine/event/block/SignChangeEvent.php +++ b/src/pocketmine/event/block/SignChangeEvent.php @@ -23,32 +23,44 @@ declare(strict_types=1); namespace pocketmine\event\block; -use pocketmine\block\Block; +use pocketmine\block\SignPost; +use pocketmine\block\utils\SignText; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\Player; -use function count; /** - * Called when a sign is changed by a player. + * Called when a sign's text is changed by a player. */ class SignChangeEvent extends BlockEvent implements Cancellable{ use CancellableTrait; + /** @var SignPost */ + private $sign; + /** @var Player */ private $player; - /** @var string[] */ - private $lines = []; + + /** @var SignText */ + private $text; /** - * @param Block $theBlock - * @param Player $thePlayer - * @param string[] $theLines + * @param SignPost $sign + * @param Player $player + * @param SignText $text */ - public function __construct(Block $theBlock, Player $thePlayer, array $theLines){ - parent::__construct($theBlock); - $this->player = $thePlayer; - $this->setLines($theLines); + public function __construct(SignPost $sign, Player $player, SignText $text){ + parent::__construct($sign); + $this->sign = $sign; + $this->player = $player; + $this->text = $text; + } + + /** + * @return SignPost + */ + public function getSign() : SignPost{ + return $this->sign; } /** @@ -59,49 +71,29 @@ class SignChangeEvent extends BlockEvent implements Cancellable{ } /** - * @return string[] + * Returns the text currently on the sign. + * + * @return SignText */ - public function getLines() : array{ - return $this->lines; + public function getOldText() : SignText{ + return $this->sign->getText(); } /** - * @param int $index 0-3 + * Returns the text which will be on the sign after the event. * - * @return string - * - * @throws \InvalidArgumentException if the index is out of bounds + * @return SignText */ - public function getLine(int $index) : string{ - if($index < 0 or $index > 3){ - throw new \InvalidArgumentException("Index must be in the range 0-3!"); - } - - return $this->lines[$index]; + public function getNewText() : SignText{ + return $this->text; } /** - * @param string[] $lines + * Sets the text to be written on the sign after the event. * - * @throws \InvalidArgumentException if there are more or less than 4 lines in the passed array + * @param SignText $text */ - public function setLines(array $lines) : void{ - if(count($lines) !== 4){ - throw new \InvalidArgumentException("Array size must be 4!"); - } - $this->lines = $lines; - } - - /** - * @param int $index 0-3 - * @param string $line - * - * @throws \InvalidArgumentException if the index is out of bounds - */ - public function setLine(int $index, string $line) : void{ - if($index < 0 or $index > 3){ - throw new \InvalidArgumentException("Index must be in the range 0-3!"); - } - $this->lines[$index] = $line; + public function setNewText(SignText $text) : void{ + $this->text = $text; } } diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index 49476ed98e..0b93502e14 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -24,12 +24,17 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; use pocketmine\block\ItemFrame; +use pocketmine\block\SignPost; +use pocketmine\block\utils\SignText; use pocketmine\inventory\transaction\action\InventoryAction; use pocketmine\inventory\transaction\CraftingTransaction; use pocketmine\inventory\transaction\InventoryTransaction; use pocketmine\inventory\transaction\TransactionValidationException; use pocketmine\math\Vector3; +use pocketmine\nbt\NbtDataException; +use pocketmine\nbt\tag\StringTag; use pocketmine\network\BadPacketException; +use pocketmine\network\mcpe\NetworkNbtSerializer; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; @@ -72,6 +77,7 @@ use pocketmine\network\mcpe\protocol\types\ReleaseItemTransactionData; use pocketmine\network\mcpe\protocol\types\UseItemOnEntityTransactionData; use pocketmine\network\mcpe\protocol\types\UseItemTransactionData; use pocketmine\Player; +use function base64_encode; use function implode; use function json_decode; use function json_encode; @@ -385,7 +391,37 @@ class SimpleSessionHandler extends SessionHandler{ } public function handleBlockEntityData(BlockEntityDataPacket $packet) : bool{ - return $this->player->handleBlockEntityData($packet); + $pos = new Vector3($packet->x, $packet->y, $packet->z); + if($pos->distanceSquared($this->player) > 10000){ + return false; + } + + $block = $this->player->getLevel()->getBlock($pos); + try{ + $nbt = (new NetworkNbtSerializer())->read($packet->namedtag); + }catch(NbtDataException $e){ + throw new BadPacketException($e->getMessage(), 0, $e); + } + + if($block instanceof SignPost){ + if($nbt->hasTag("Text", StringTag::class)){ + try{ + $text = SignText::fromBlob($nbt->getString("Text")); + }catch(\InvalidArgumentException $e){ + throw new BadPacketException("Invalid sign text update: " . $e->getMessage(), 0, $e); + } + + if(!$block->updateText($this->player, $text)){ + $this->player->getLevel()->sendBlocks([$this->player], [$block]); + } + + return true; + } + + $this->player->getServer()->getLogger()->debug("Invalid sign update data from " . $this->player->getName() . ": " . base64_encode($packet->namedtag)); + } + + return false; } public function handlePlayerInput(PlayerInputPacket $packet) : bool{ diff --git a/src/pocketmine/tile/Sign.php b/src/pocketmine/tile/Sign.php index 83fa79fa72..14a034dc43 100644 --- a/src/pocketmine/tile/Sign.php +++ b/src/pocketmine/tile/Sign.php @@ -23,139 +23,78 @@ declare(strict_types=1); namespace pocketmine\tile; -use pocketmine\event\block\SignChangeEvent; +use pocketmine\block\SignPost; +use pocketmine\block\utils\SignText; +use pocketmine\level\Level; +use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\StringTag; -use pocketmine\Player; -use pocketmine\utils\TextFormat; -use function array_map; use function array_pad; use function array_slice; use function explode; use function implode; -use function mb_check_encoding; use function mb_scrub; use function sprintf; +/** + * @deprecated + * @see SignPost + */ class Sign extends Spawnable{ public const TAG_TEXT_BLOB = "Text"; public const TAG_TEXT_LINE = "Text%d"; //sprintf()able - private static function fixTextBlob(string $blob) : array{ + public static function fixTextBlob(string $blob) : array{ return array_slice(array_pad(explode("\n", $blob), 4, ""), 0, 4); } - /** @var string[] */ - protected $text = ["", "", "", ""]; + /** @var SignText */ + protected $text; + + public function __construct(Level $level, Vector3 $pos){ + $this->text = new SignText(); + parent::__construct($level, $pos); + } public function readSaveData(CompoundTag $nbt) : void{ if($nbt->hasTag(self::TAG_TEXT_BLOB, StringTag::class)){ //MCPE 1.2 save format - $this->text = self::fixTextBlob($nbt->getString(self::TAG_TEXT_BLOB)); + $this->text = SignText::fromBlob(mb_scrub($nbt->getString(self::TAG_TEXT_BLOB), 'UTF-8')); }else{ - for($i = 1; $i <= 4; ++$i){ - $textKey = sprintf(self::TAG_TEXT_LINE, $i); + $this->text = new SignText(); + for($i = 0; $i < SignText::LINE_COUNT; ++$i){ + $textKey = sprintf(self::TAG_TEXT_LINE, $i + 1); if($nbt->hasTag($textKey, StringTag::class)){ - $this->text[$i - 1] = $nbt->getString($textKey); + $this->text->setLine($i, mb_scrub($nbt->getString($textKey), 'UTF-8')); } } } - $this->text = array_map(function(string $line) : string{ - return mb_scrub($line, 'UTF-8'); - }, $this->text); } protected function writeSaveData(CompoundTag $nbt) : void{ - $nbt->setString(self::TAG_TEXT_BLOB, implode("\n", $this->text)); + $nbt->setString(self::TAG_TEXT_BLOB, implode("\n", $this->text->getLines())); - for($i = 1; $i <= 4; ++$i){ //Backwards-compatibility - $textKey = sprintf(self::TAG_TEXT_LINE, $i); - $nbt->setString($textKey, $this->getLine($i - 1)); + for($i = 0; $i < SignText::LINE_COUNT; ++$i){ //Backwards-compatibility + $textKey = sprintf(self::TAG_TEXT_LINE, $i + 1); + $nbt->setString($textKey, $this->text->getLine($i)); } } /** - * Changes contents of the specific lines to the string provided. - * Leaves contents of the specific lines as is if null is provided. - * - * @param null|string $line1 - * @param null|string $line2 - * @param null|string $line3 - * @param null|string $line4 + * @return SignText */ - public function setText(?string $line1 = "", ?string $line2 = "", ?string $line3 = "", ?string $line4 = "") : void{ - if($line1 !== null){ - $this->setLine(0, $line1); - } - if($line2 !== null){ - $this->setLine(1, $line2); - } - if($line3 !== null){ - $this->setLine(2, $line3); - } - if($line4 !== null){ - $this->setLine(3, $line4); - } - - $this->onChanged(); - } - - /** - * @param int $index 0-3 - * @param string $line - */ - public function setLine(int $index, string $line) : void{ - if($index < 0 or $index > 3){ - throw new \InvalidArgumentException("Index must be in the range 0-3!"); - } - if(!mb_check_encoding($line, 'UTF-8')){ - throw new \InvalidArgumentException("Text must be valid UTF-8"); - } - - $this->text[$index] = $line; - $this->onChanged(); - } - - /** - * @param int $index 0-3 - * - * @return string - */ - public function getLine(int $index) : string{ - if($index < 0 or $index > 3){ - throw new \InvalidArgumentException("Index must be in the range 0-3!"); - } - return $this->text[$index]; - } - - /** - * @return string[] - */ - public function getText() : array{ + public function getText() : SignText{ return $this->text; } - protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ - $nbt->setString(self::TAG_TEXT_BLOB, implode("\n", $this->text)); + /** + * @param SignText $text + */ + public function setText(SignText $text) : void{ + $this->text = $text; + $this->onChanged(); } - public function updateCompoundTag(CompoundTag $nbt, Player $player) : bool{ - if($nbt->hasTag(self::TAG_TEXT_BLOB, StringTag::class)){ - $lines = self::fixTextBlob($nbt->getString(self::TAG_TEXT_BLOB)); - }else{ - return false; - } - - $removeFormat = $player->getRemoveFormat(); - - $ev = new SignChangeEvent($this->getBlock(), $player, array_map(function(string $line) use ($removeFormat){ return TextFormat::clean($line, $removeFormat); }, $lines)); - $ev->call(); - - if(!$ev->isCancelled()){ - $this->setText(...$ev->getLines()); - - return true; - }else{ - return false; - } + protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ + $nbt->setString(self::TAG_TEXT_BLOB, implode("\n", $this->text->getLines())); } } diff --git a/src/pocketmine/tile/Spawnable.php b/src/pocketmine/tile/Spawnable.php index 2e155acf67..0d707bce20 100644 --- a/src/pocketmine/tile/Spawnable.php +++ b/src/pocketmine/tile/Spawnable.php @@ -27,7 +27,6 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\NetworkNbtSerializer; -use pocketmine\Player; use function get_class; abstract class Spawnable extends Tile{ @@ -104,17 +103,4 @@ abstract class Spawnable extends Tile{ * @param CompoundTag $nbt */ abstract protected function addAdditionalSpawnData(CompoundTag $nbt) : void; - - /** - * Called when a player updates a block entity's NBT data - * for example when writing on a sign. - * - * @param CompoundTag $nbt - * @param Player $player - * - * @return bool indication of success, will respawn the tile to the player if false. - */ - public function updateCompoundTag(CompoundTag $nbt, Player $player) : bool{ - return false; - } } From 08e799c35a3a11a192e8c0e0fd329caea4f3c878 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Feb 2019 17:14:04 +0000 Subject: [PATCH 0563/3224] Once again... add a missing file... --- src/pocketmine/block/utils/SignText.php | 130 ++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 src/pocketmine/block/utils/SignText.php diff --git a/src/pocketmine/block/utils/SignText.php b/src/pocketmine/block/utils/SignText.php new file mode 100644 index 0000000000..74aea044ba --- /dev/null +++ b/src/pocketmine/block/utils/SignText.php @@ -0,0 +1,130 @@ +setLines($lines ?? array_fill(0, self::LINE_COUNT, "")); + } + + /** + * Parses sign lines from the given string blob. + * TODO: add a strict mode for this + * + * @param string $blob + * + * @return SignText + * @throws \InvalidArgumentException if the text is not valid UTF-8 + */ + public static function fromBlob(string $blob) : SignText{ + return new self(array_slice(array_pad(explode("\n", $blob), self::LINE_COUNT, ""), 0, self::LINE_COUNT)); + } + + /** + * Returns an array of lines currently on the sign. + * + * @return string[] + */ + public function getLines() : array{ + return $this->lines; + } + + /** + * Sets the sign text. + * + * @param string[] $lines index-sensitive; omitting an index will leave it unchanged + * + * @throws \InvalidArgumentException if the array size is greater than 4 + * @throws \InvalidArgumentException if invalid keys (out of bounds or string) are found in the array + */ + public function setLines(array $lines) : void{ + if(count($lines) > self::LINE_COUNT){ + throw new \InvalidArgumentException("Expected at most 4 lines, got " . count($lines)); + } + foreach($lines as $k => $line){ + $this->checkLineIndex($k); + $this->setLine($k, $line); + } + } + + private function checkLineIndex($index) : void{ + if(!is_int($index)){ + throw new \InvalidArgumentException("Index must be an integer"); + } + if($index < 0 or $index >= self::LINE_COUNT){ + throw new \InvalidArgumentException("Line index is out of bounds"); + } + } + + /** + * Returns the sign line at the given offset. + * + * @param int $index + * + * @return string + * @throws \InvalidArgumentException + */ + public function getLine(int $index) : string{ + $this->checkLineIndex($index); + return $this->lines[$index]; + } + + /** + * Sets the line at the given offset. + * + * @param int $index + * @param string $line + * + * @throws \InvalidArgumentException if the text is not valid UTF-8 + * @throws \InvalidArgumentException if the text contains a newline + */ + public function setLine(int $index, string $line) : void{ + $this->checkLineIndex($index); + if(!mb_check_encoding($line, 'UTF-8')){ + throw new \InvalidArgumentException("Line must be valid UTF-8 text"); + } + if(strpos($line, "\n") !== false){ + throw new \InvalidArgumentException("Line must not contain newlines"); + } + //TODO: add length checks + $this->lines[$index] = $line; + } +} From c9eb642afd637e7b1b147a27c5edfe8e75ea696f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Feb 2019 17:15:06 +0000 Subject: [PATCH 0564/3224] PacketPool: missing @throws --- src/pocketmine/network/mcpe/protocol/PacketPool.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pocketmine/network/mcpe/protocol/PacketPool.php b/src/pocketmine/network/mcpe/protocol/PacketPool.php index 679b4287c0..3d5385cfb2 100644 --- a/src/pocketmine/network/mcpe/protocol/PacketPool.php +++ b/src/pocketmine/network/mcpe/protocol/PacketPool.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; use pocketmine\utils\Binary; +use pocketmine\utils\BinaryDataException; class PacketPool{ /** @var \SplFixedArray */ @@ -175,6 +176,7 @@ class PacketPool{ * @param string $buffer * * @return DataPacket + * @throws BinaryDataException */ public static function getPacket(string $buffer) : DataPacket{ $offset = 0; From d679fb7546fb78f725510667af5bc965aac8e863 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Feb 2019 17:35:30 +0000 Subject: [PATCH 0565/3224] Block: Rename onActivate() -> onInteract() --- src/pocketmine/block/Anvil.php | 2 +- src/pocketmine/block/Bed.php | 2 +- src/pocketmine/block/Block.php | 4 ++-- src/pocketmine/block/Button.php | 2 +- src/pocketmine/block/Cake.php | 2 +- src/pocketmine/block/Chest.php | 2 +- src/pocketmine/block/CoarseDirt.php | 2 +- src/pocketmine/block/CocoaBlock.php | 2 +- src/pocketmine/block/CraftingTable.php | 2 +- src/pocketmine/block/Crops.php | 2 +- src/pocketmine/block/DaylightSensor.php | 2 +- src/pocketmine/block/Dirt.php | 2 +- src/pocketmine/block/Door.php | 2 +- src/pocketmine/block/DragonEgg.php | 2 +- src/pocketmine/block/EnchantingTable.php | 2 +- src/pocketmine/block/EnderChest.php | 2 +- src/pocketmine/block/FenceGate.php | 2 +- src/pocketmine/block/FlowerPot.php | 2 +- src/pocketmine/block/Furnace.php | 2 +- src/pocketmine/block/Grass.php | 2 +- src/pocketmine/block/ItemFrame.php | 2 +- src/pocketmine/block/Lever.php | 2 +- src/pocketmine/block/RedstoneOre.php | 2 +- src/pocketmine/block/RedstoneRepeater.php | 2 +- src/pocketmine/block/Sapling.php | 2 +- src/pocketmine/block/Sugarcane.php | 2 +- src/pocketmine/block/TNT.php | 2 +- src/pocketmine/block/Trapdoor.php | 2 +- src/pocketmine/level/Level.php | 4 ++-- 29 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index 23ad43911e..ae433ee9e0 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -77,7 +77,7 @@ class Anvil extends Transparent implements Fallable{ return AxisAlignedBB::one()->squash(Facing::axis(Facing::rotateY($this->facing, false)), 1 / 8); } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ $player->addWindow(new AnvilInventory($this)); } diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index da51227e70..7f4caee1ec 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -138,7 +138,7 @@ class Bed extends Transparent{ return null; } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $other = $this->getOtherHalf(); if($other === null){ diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 36926fd1b1..8ae99f582b 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -367,7 +367,7 @@ class Block extends Position implements BlockIds, Metadatable{ } /** - * Do actions when activated by Item. Returns if it has done anything + * Do actions when interacted by Item. Returns if it has done anything * * @param Item $item * @param int $face @@ -376,7 +376,7 @@ class Block extends Position implements BlockIds, Metadatable{ * * @return bool */ - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ return false; } diff --git a/src/pocketmine/block/Button.php b/src/pocketmine/block/Button.php index 1ff2484147..a2d8cc3c63 100644 --- a/src/pocketmine/block/Button.php +++ b/src/pocketmine/block/Button.php @@ -59,7 +59,7 @@ abstract class Button extends Flowable{ abstract protected function getActivationTime() : int; - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$this->powered){ $this->powered = true; $this->level->setBlock($this, $this); diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index 335f0f6447..ec6e32fdbb 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -84,7 +84,7 @@ class Cake extends Transparent implements FoodSource{ return false; } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $player->consumeObject($this); return true; diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index be2f38ea1d..678564d4a0 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -91,7 +91,7 @@ class Chest extends Transparent{ return false; } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ $chest = $this->getLevel()->getTile($this); diff --git a/src/pocketmine/block/CoarseDirt.php b/src/pocketmine/block/CoarseDirt.php index 23b16f716c..67d606bb18 100644 --- a/src/pocketmine/block/CoarseDirt.php +++ b/src/pocketmine/block/CoarseDirt.php @@ -31,7 +31,7 @@ use pocketmine\Player; class CoarseDirt extends Dirt{ - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP and $item instanceof Hoe){ $item->applyDamage(1); $this->getLevel()->setBlock($this, BlockFactory::get(Block::DIRT)); diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index 0046d27aab..1c74c16e88 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -85,7 +85,7 @@ class CocoaBlock extends Transparent{ return false; } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($this->age < 2 and $item instanceof Fertilizer){ $this->age++; $this->level->setBlock($this, $this); diff --git a/src/pocketmine/block/CraftingTable.php b/src/pocketmine/block/CraftingTable.php index 369deab4e5..0042bcb1cb 100644 --- a/src/pocketmine/block/CraftingTable.php +++ b/src/pocketmine/block/CraftingTable.php @@ -38,7 +38,7 @@ class CraftingTable extends Solid{ return BlockToolType::TYPE_AXE; } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ $player->setCraftingGrid(new CraftingGrid($player, CraftingGrid::SIZE_BIG)); } diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index 2586d9109e..771968daa0 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -57,7 +57,7 @@ abstract class Crops extends Flowable{ } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($this->age < 7 and $item instanceof Fertilizer){ $block = clone $this; $block->age += mt_rand(2, 5); diff --git a/src/pocketmine/block/DaylightSensor.php b/src/pocketmine/block/DaylightSensor.php index a379c5f146..41e53794a4 100644 --- a/src/pocketmine/block/DaylightSensor.php +++ b/src/pocketmine/block/DaylightSensor.php @@ -91,7 +91,7 @@ class DaylightSensor extends Transparent{ return AxisAlignedBB::one()->trim(Facing::UP, 0.5); } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->inverted = !$this->inverted; $this->level->setBlock($this, $this); return true; diff --git a/src/pocketmine/block/Dirt.php b/src/pocketmine/block/Dirt.php index c19c9ff66d..c74f42e57a 100644 --- a/src/pocketmine/block/Dirt.php +++ b/src/pocketmine/block/Dirt.php @@ -41,7 +41,7 @@ class Dirt extends Solid{ return BlockToolType::TYPE_SHOVEL; } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP and $item instanceof Hoe){ $item->applyDamage(1); $this->getLevel()->setBlock($this, BlockFactory::get(Block::FARMLAND)); diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 39e56e5f8c..8e588fd596 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -134,7 +134,7 @@ abstract class Door extends Transparent{ return false; } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->open = !$this->open; $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); diff --git a/src/pocketmine/block/DragonEgg.php b/src/pocketmine/block/DragonEgg.php index 8879681665..cf9c53457f 100644 --- a/src/pocketmine/block/DragonEgg.php +++ b/src/pocketmine/block/DragonEgg.php @@ -58,7 +58,7 @@ class DragonEgg extends Transparent implements Fallable{ return null; } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->teleport(); return true; } diff --git a/src/pocketmine/block/EnchantingTable.php b/src/pocketmine/block/EnchantingTable.php index c2454f657a..e8b884c331 100644 --- a/src/pocketmine/block/EnchantingTable.php +++ b/src/pocketmine/block/EnchantingTable.php @@ -53,7 +53,7 @@ class EnchantingTable extends Transparent{ return AxisAlignedBB::one()->trim(Facing::UP, 0.25); } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ //TODO lock diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index 6630ffcb0f..4235fa9841 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -82,7 +82,7 @@ class EnderChest extends Transparent{ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ $enderChest = $this->getLevel()->getTile($this); if($enderChest instanceof TileEnderChest and $this->getSide(Facing::UP)->isTransparent()){ diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index b26152064e..564c9d6101 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -96,7 +96,7 @@ class FenceGate extends Transparent{ } } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->open = !$this->open; if($this->open and $player !== null){ $playerFacing = $player->getHorizontalFacing(); diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 7a7b8ad765..33de6c9adc 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -125,7 +125,7 @@ class FlowerPot extends Flowable{ } } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $plant = $item->getBlock(); if(!$this->canAddPlant($plant)){ return false; diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index a407aa75d4..c5921cb035 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -95,7 +95,7 @@ class Furnace extends Solid{ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ $furnace = $this->getLevel()->getTile($this); if($furnace instanceof TileFurnace and $furnace->canOpenWith($item->getCustomName())){ diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index 493efc6206..b3d4992b51 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -91,7 +91,7 @@ class Grass extends Solid{ } } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face !== Facing::UP){ return false; } diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 430ee3a1a2..5c8279d00b 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -142,7 +142,7 @@ class ItemFrame extends Flowable{ $this->itemDropChance = $itemDropChance; } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($this->framedItem !== null){ $this->itemRotation = ($this->itemRotation + 1) % self::ROTATIONS; }elseif(!$item->isNull()){ diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index 458fb89329..3b3b01af38 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -109,7 +109,7 @@ class Lever extends Flowable{ } } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->powered = !$this->powered; $this->level->setBlock($this, $this); $this->level->broadcastLevelSoundEvent( diff --git a/src/pocketmine/block/RedstoneOre.php b/src/pocketmine/block/RedstoneOre.php index 3ab072028f..66c2f085e6 100644 --- a/src/pocketmine/block/RedstoneOre.php +++ b/src/pocketmine/block/RedstoneOre.php @@ -75,7 +75,7 @@ class RedstoneOre extends Solid{ return $this->getLevel()->setBlock($this, $this, false); } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$this->lit){ $this->lit = true; $this->getLevel()->setBlock($this, $this); //no return here - this shouldn't prevent block placement diff --git a/src/pocketmine/block/RedstoneRepeater.php b/src/pocketmine/block/RedstoneRepeater.php index ab16eead22..651607d0ee 100644 --- a/src/pocketmine/block/RedstoneRepeater.php +++ b/src/pocketmine/block/RedstoneRepeater.php @@ -94,7 +94,7 @@ class RedstoneRepeater extends Flowable{ return false; } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(++$this->delay > 4){ $this->delay = 1; } diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index 0b725ffab8..0fa70f3ce8 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -66,7 +66,7 @@ class Sapling extends Flowable{ return false; } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof Fertilizer){ Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->treeType); diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index 6a02812130..ef4baba17d 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -48,7 +48,7 @@ class Sugarcane extends Flowable{ return 0b1111; } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof Fertilizer){ if($this->getSide(Facing::DOWN)->getId() !== self::SUGARCANE_BLOCK){ for($y = 1; $y < 3; ++$y){ diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index 4b71e5b563..4d499da071 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -44,7 +44,7 @@ class TNT extends Solid{ return 0; } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof FlintSteel or $item->hasEnchantment(Enchantment::FIRE_ASPECT())){ if($item instanceof Durable){ $item->applyDamage(1); diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index 1cc736894d..c815b85ee9 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -77,7 +77,7 @@ class Trapdoor extends Transparent{ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->open = !$this->open; $this->level->setBlock($this, $this); $this->level->addSound($this, new DoorSound()); diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 7d4f06a89d..effddbf695 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1822,7 +1822,7 @@ class Level implements ChunkManager, Metadatable{ $ev = new PlayerInteractEvent($player, $item, $blockClicked, $clickVector, $face, PlayerInteractEvent::RIGHT_CLICK_BLOCK); $ev->call(); if(!$ev->isCancelled()){ - if(!$player->isSneaking() and $blockClicked->onActivate($item, $face, $clickVector, $player)){ + if(!$player->isSneaking() and $blockClicked->onInteract($item, $face, $clickVector, $player)){ return true; } @@ -1835,7 +1835,7 @@ class Level implements ChunkManager, Metadatable{ }else{ return false; } - }elseif($blockClicked->onActivate($item, $face, $clickVector, $player)){ + }elseif($blockClicked->onInteract($item, $face, $clickVector, $player)){ return true; } From 97a1d997e81eaae83cab210fd6f9cd2a244c4317 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Feb 2019 17:47:32 +0000 Subject: [PATCH 0566/3224] ItemFrame: yield framed item when block-picking, fixes [1] in #2706 --- src/pocketmine/block/ItemFrame.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 5c8279d00b..16800a6431 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -193,6 +193,10 @@ class ItemFrame extends Flowable{ return $drops; } + public function getPickedItem() : Item{ + return $this->framedItem !== null ? clone $this->framedItem : parent::getPickedItem(); + } + public function isAffectedBySilkTouch() : bool{ return false; } From 7b23baa020c48e4c5690d3209d6031525b98d92c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Feb 2019 17:49:48 +0000 Subject: [PATCH 0567/3224] FlowerPot: yield contained plant when block-picking --- src/pocketmine/block/FlowerPot.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 33de6c9adc..d7505029ab 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -147,6 +147,10 @@ class FlowerPot extends Flowable{ return $items; } + public function getPickedItem() : Item{ + return $this->plant !== null ? $this->plant->asItem() : parent::getPickedItem(); + } + public function isAffectedBySilkTouch() : bool{ return false; } From 943906cc6b8a95c62ed7227466de5500eb7548b0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Feb 2019 19:26:47 +0000 Subject: [PATCH 0568/3224] Partial comparator implementation this supports placement, toggling compare/subtract mode, simple stuff. No redstone functionality yet. This is needed for blockstate mapping in blockfactory. --- src/pocketmine/block/BlockFactory.php | 2 + src/pocketmine/block/RedstoneComparator.php | 172 ++++++++++++++++++++ src/pocketmine/tile/Comparator.php | 60 +++++++ src/pocketmine/tile/TileFactory.php | 1 + 4 files changed, 235 insertions(+) create mode 100644 src/pocketmine/block/RedstoneComparator.php create mode 100644 src/pocketmine/tile/Comparator.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index b51dab9d06..5ab6a5367e 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -30,6 +30,7 @@ use pocketmine\block\utils\PillarRotationTrait; use pocketmine\block\utils\TreeType; use pocketmine\item\ItemIds; use pocketmine\level\Position; +use pocketmine\tile\Comparator; use function array_fill; use function array_filter; use function file_get_contents; @@ -211,6 +212,7 @@ class BlockFactory{ self::register(new RedMushroom(new BID(Block::RED_MUSHROOM), "Red Mushroom")); self::register(new RedMushroomBlock(new BID(Block::RED_MUSHROOM_BLOCK), "Red Mushroom Block")); self::register(new Redstone(new BID(Block::REDSTONE_BLOCK), "Redstone Block")); + self::register(new RedstoneComparator(new BlockIdentifierFlattened(Block::UNPOWERED_COMPARATOR, Block::POWERED_COMPARATOR, 0, ItemIds::COMPARATOR, Comparator::class), "Redstone Comparator")); self::register(new RedstoneLamp(new BlockIdentifierFlattened(Block::REDSTONE_LAMP, Block::LIT_REDSTONE_LAMP), "Redstone Lamp")); self::register(new RedstoneOre(new BlockIdentifierFlattened(Block::REDSTONE_ORE, Block::LIT_REDSTONE_ORE), "Redstone Ore")); self::register(new RedstoneRepeater(new BlockIdentifierFlattened(Block::UNPOWERED_REPEATER, Block::POWERED_REPEATER, 0, ItemIds::REPEATER), "Redstone Repeater")); diff --git a/src/pocketmine/block/RedstoneComparator.php b/src/pocketmine/block/RedstoneComparator.php new file mode 100644 index 0000000000..2b8121fd45 --- /dev/null +++ b/src/pocketmine/block/RedstoneComparator.php @@ -0,0 +1,172 @@ +powered ? $this->idInfo->getSecondId() : parent::getId(); + } + + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); + $this->isSubtractMode = ($stateMeta & 0x04) !== 0; + $this->powered = ($id === $this->idInfo->getSecondId() or ($stateMeta & 0x08) !== 0); + } + + public function writeStateToMeta() : int{ + return Bearing::fromFacing($this->facing) | ($this->isSubtractMode ? 0x04 : 0) | ($this->powered ? 0x08 : 0); + } + + public function getStateBitmask() : int{ + return 0b1111; + } + + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); + $tile = $this->level->getTile($this); + if($tile instanceof Comparator){ + $this->signalStrength = $tile->getSignalStrength(); + } + } + + public function writeStateToWorld() : void{ + parent::writeStateToWorld(); + $tile = $this->level->getTile($this); + assert($tile instanceof Comparator); + $tile->setSignalStrength($this->signalStrength); + } + + /** + * TODO: ad hoc, move to interface + * @return int + */ + public function getFacing() : int{ + return $this->facing; + } + + /** + * TODO: ad hoc, move to interface + * @param int $facing + */ + public function setFacing(int $facing) : void{ + $this->facing = $facing; + } + + /** + * @return bool + */ + public function isSubtractMode() : bool{ + return $this->isSubtractMode; + } + + /** + * @param bool $isSubtractMode + */ + public function setSubtractMode(bool $isSubtractMode) : void{ + $this->isSubtractMode = $isSubtractMode; + } + + /** + * @return bool + */ + public function isPowered() : bool{ + return $this->powered; + } + + /** + * @param bool $powered + */ + public function setPowered(bool $powered) : void{ + $this->powered = $powered; + } + + /** + * @return int + */ + public function getSignalStrength() : int{ + return $this->signalStrength; + } + + /** + * @param int $signalStrength + */ + public function setSignalStrength(int $signalStrength) : void{ + $this->signalStrength = $signalStrength; + } + + protected function recalculateBoundingBox() : ?AxisAlignedBB{ + return AxisAlignedBB::one()->trim(Facing::UP, 7 / 8); + } + + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if(!$blockReplace->getSide(Facing::DOWN)->isTransparent()){ + if($player !== null){ + $this->facing = Facing::opposite($player->getHorizontalFacing()); + } + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + + return false; + } + + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + $this->isSubtractMode = !$this->isSubtractMode; + $this->level->setBlock($this, $this); + return true; + } + + public function onNearbyBlockChange() : void{ + if($this->getSide(Facing::DOWN)->isTransparent()){ + $this->level->useBreakOn($this); + } + } + + //TODO: redstone functionality +} diff --git a/src/pocketmine/tile/Comparator.php b/src/pocketmine/tile/Comparator.php new file mode 100644 index 0000000000..4e66512707 --- /dev/null +++ b/src/pocketmine/tile/Comparator.php @@ -0,0 +1,60 @@ +signalStrength; + } + + /** + * @param int $signalStrength + */ + public function setSignalStrength(int $signalStrength) : void{ + $this->signalStrength = $signalStrength; + } + + public function readSaveData(CompoundTag $nbt) : void{ + $this->signalStrength = $nbt->getInt(self::TAG_OUTPUT_SIGNAL, 0, true); + } + + protected function writeSaveData(CompoundTag $nbt) : void{ + $nbt->setInt(self::TAG_OUTPUT_SIGNAL, $this->signalStrength); + } +} diff --git a/src/pocketmine/tile/TileFactory.php b/src/pocketmine/tile/TileFactory.php index 7c1cbf2d75..d866e30eac 100644 --- a/src/pocketmine/tile/TileFactory.php +++ b/src/pocketmine/tile/TileFactory.php @@ -49,6 +49,7 @@ final class TileFactory{ self::register(Banner::class, ["Banner", "minecraft:banner"]); self::register(Bed::class, ["Bed", "minecraft:bed"]); self::register(Chest::class, ["Chest", "minecraft:chest"]); + self::register(Comparator::class, ["Comparator", "minecraft:comparator"]); self::register(EnchantTable::class, ["EnchantTable", "minecraft:enchanting_table"]); self::register(EnderChest::class, ["EnderChest", "minecraft:ender_chest"]); self::register(FlowerPot::class, ["FlowerPot", "minecraft:flower_pot"]); From 741d061415f9c1ccb9859f4e80eb8c60ee931ffa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Feb 2019 19:59:33 +0000 Subject: [PATCH 0569/3224] NoteBlock: added //TODO --- src/pocketmine/block/NoteBlock.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pocketmine/block/NoteBlock.php b/src/pocketmine/block/NoteBlock.php index 113d6accf0..c471b8185e 100644 --- a/src/pocketmine/block/NoteBlock.php +++ b/src/pocketmine/block/NoteBlock.php @@ -36,4 +36,6 @@ class NoteBlock extends Solid{ public function getToolType() : int{ return BlockToolType::TYPE_AXE; } + + //TODO } From 1e9e179ec0b45ad5c5006eea4fa0833e5f88209f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Mar 2019 08:24:25 +0000 Subject: [PATCH 0570/3224] Fixed Block consistency check failure since 943906cc6b8a95c62ed7227466de5500eb7548b0 --- tests/phpunit/block/block_factory_consistency_check.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index eb1cc83f85..34ec5b5dd5 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","752":"Bookshelf","768":"Moss Stone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Sign Post","1009":"Sign Post","1010":"Sign Post","1011":"Sign Post","1012":"Sign Post","1013":"Sign Post","1014":"Sign Post","1015":"Sign Post","1016":"Sign Post","1017":"Sign Post","1018":"Sign Post","1019":"Sign Post","1020":"Sign Post","1021":"Sign Post","1022":"Sign Post","1023":"Sign Post","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Wall Sign","1090":"Wall Sign","1091":"Wall Sign","1092":"Wall Sign","1093":"Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Wooden Pressure Plate","1153":"Wooden Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Wooden Trapdoor","1537":"Wooden Trapdoor","1538":"Wooden Trapdoor","1539":"Wooden Trapdoor","1540":"Wooden Trapdoor","1541":"Wooden Trapdoor","1542":"Wooden Trapdoor","1543":"Wooden Trapdoor","1544":"Wooden Trapdoor","1545":"Wooden Trapdoor","1546":"Wooden Trapdoor","1547":"Wooden Trapdoor","1548":"Wooden Trapdoor","1549":"Wooden Trapdoor","1550":"Wooden Trapdoor","1551":"Wooden Trapdoor","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Wooden Button","2289":"Wooden Button","2290":"Wooden Button","2291":"Wooden Button","2292":"Wooden Button","2293":"Wooden Button","2296":"Wooden Button","2297":"Wooden Button","2298":"Wooden Button","2299":"Wooden Button","2300":"Wooden Button","2301":"Wooden Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Standing Banner","2817":"Standing Banner","2818":"Standing Banner","2819":"Standing Banner","2820":"Standing Banner","2821":"Standing Banner","2822":"Standing Banner","2823":"Standing Banner","2824":"Standing Banner","2825":"Standing Banner","2826":"Standing Banner","2827":"Standing Banner","2828":"Standing Banner","2829":"Standing Banner","2830":"Standing Banner","2831":"Standing Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","752":"Bookshelf","768":"Moss Stone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Sign Post","1009":"Sign Post","1010":"Sign Post","1011":"Sign Post","1012":"Sign Post","1013":"Sign Post","1014":"Sign Post","1015":"Sign Post","1016":"Sign Post","1017":"Sign Post","1018":"Sign Post","1019":"Sign Post","1020":"Sign Post","1021":"Sign Post","1022":"Sign Post","1023":"Sign Post","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Wall Sign","1090":"Wall Sign","1091":"Wall Sign","1092":"Wall Sign","1093":"Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Wooden Pressure Plate","1153":"Wooden Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Wooden Trapdoor","1537":"Wooden Trapdoor","1538":"Wooden Trapdoor","1539":"Wooden Trapdoor","1540":"Wooden Trapdoor","1541":"Wooden Trapdoor","1542":"Wooden Trapdoor","1543":"Wooden Trapdoor","1544":"Wooden Trapdoor","1545":"Wooden Trapdoor","1546":"Wooden Trapdoor","1547":"Wooden Trapdoor","1548":"Wooden Trapdoor","1549":"Wooden Trapdoor","1550":"Wooden Trapdoor","1551":"Wooden Trapdoor","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Wooden Button","2289":"Wooden Button","2290":"Wooden Button","2291":"Wooden Button","2292":"Wooden Button","2293":"Wooden Button","2296":"Wooden Button","2297":"Wooden Button","2298":"Wooden Button","2299":"Wooden Button","2300":"Wooden Button","2301":"Wooden Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Standing Banner","2817":"Standing Banner","2818":"Standing Banner","2819":"Standing Banner","2820":"Standing Banner","2821":"Standing Banner","2822":"Standing Banner","2823":"Standing Banner","2824":"Standing Banner","2825":"Standing Banner","2826":"Standing Banner","2827":"Standing Banner","2828":"Standing Banner","2829":"Standing Banner","2830":"Standing Banner","2831":"Standing Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6"} \ No newline at end of file From 12dfcc9eb6190402f8efd4ed041f01a679ff60df Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Mar 2019 11:05:37 +0000 Subject: [PATCH 0571/3224] Banner: Sort lines lexicographically ascending --- src/pocketmine/tile/Banner.php | 60 +++++++++++++++++----------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/pocketmine/tile/Banner.php b/src/pocketmine/tile/Banner.php index 33af1753ea..043d875f94 100644 --- a/src/pocketmine/tile/Banner.php +++ b/src/pocketmine/tile/Banner.php @@ -45,44 +45,44 @@ class Banner extends Spawnable implements Nameable{ public const TAG_PATTERN_COLOR = "Color"; public const TAG_PATTERN_NAME = "Pattern"; - public const PATTERN_BOTTOM_STRIPE = "bs"; - public const PATTERN_TOP_STRIPE = "ts"; - public const PATTERN_LEFT_STRIPE = "ls"; - public const PATTERN_RIGHT_STRIPE = "rs"; - public const PATTERN_CENTER_STRIPE = "cs"; - public const PATTERN_MIDDLE_STRIPE = "ms"; - public const PATTERN_DOWN_RIGHT_STRIPE = "drs"; - public const PATTERN_DOWN_LEFT_STRIPE = "dls"; - public const PATTERN_SMALL_STRIPES = "ss"; - public const PATTERN_DIAGONAL_CROSS = "cr"; - public const PATTERN_SQUARE_CROSS = "sc"; - public const PATTERN_LEFT_OF_DIAGONAL = "ld"; - public const PATTERN_RIGHT_OF_UPSIDE_DOWN_DIAGONAL = "rud"; - public const PATTERN_LEFT_OF_UPSIDE_DOWN_DIAGONAL = "lud"; - public const PATTERN_RIGHT_OF_DIAGONAL = "rd"; - public const PATTERN_VERTICAL_HALF_LEFT = "vh"; - public const PATTERN_VERTICAL_HALF_RIGHT = "vhr"; - public const PATTERN_HORIZONTAL_HALF_TOP = "hh"; - public const PATTERN_HORIZONTAL_HALF_BOTTOM = "hhb"; + public const PATTERN_BORDER = "bo"; public const PATTERN_BOTTOM_LEFT_CORNER = "bl"; public const PATTERN_BOTTOM_RIGHT_CORNER = "br"; - public const PATTERN_TOP_LEFT_CORNER = "tl"; - public const PATTERN_TOP_RIGHT_CORNER = "tr"; + public const PATTERN_BOTTOM_STRIPE = "bs"; public const PATTERN_BOTTOM_TRIANGLE = "bt"; - public const PATTERN_TOP_TRIANGLE = "tt"; public const PATTERN_BOTTOM_TRIANGLE_SAWTOOTH = "bts"; - public const PATTERN_TOP_TRIANGLE_SAWTOOTH = "tts"; - public const PATTERN_MIDDLE_CIRCLE = "mc"; - public const PATTERN_MIDDLE_RHOMBUS = "mr"; - public const PATTERN_BORDER = "bo"; - public const PATTERN_CURLY_BORDER = "cbo"; public const PATTERN_BRICK = "bri"; + public const PATTERN_CENTER_STRIPE = "cs"; + public const PATTERN_CREEPER = "cre"; + public const PATTERN_CURLY_BORDER = "cbo"; + public const PATTERN_DIAGONAL_CROSS = "cr"; + public const PATTERN_DOWN_LEFT_STRIPE = "dls"; + public const PATTERN_DOWN_RIGHT_STRIPE = "drs"; + public const PATTERN_FLOWER = "flo"; public const PATTERN_GRADIENT = "gra"; public const PATTERN_GRADIENT_UPSIDE_DOWN = "gru"; - public const PATTERN_CREEPER = "cre"; - public const PATTERN_SKULL = "sku"; - public const PATTERN_FLOWER = "flo"; + public const PATTERN_HORIZONTAL_HALF_BOTTOM = "hhb"; + public const PATTERN_HORIZONTAL_HALF_TOP = "hh"; + public const PATTERN_LEFT_OF_DIAGONAL = "ld"; + public const PATTERN_LEFT_OF_UPSIDE_DOWN_DIAGONAL = "lud"; + public const PATTERN_LEFT_STRIPE = "ls"; + public const PATTERN_MIDDLE_CIRCLE = "mc"; + public const PATTERN_MIDDLE_RHOMBUS = "mr"; + public const PATTERN_MIDDLE_STRIPE = "ms"; public const PATTERN_MOJANG = "moj"; + public const PATTERN_RIGHT_OF_DIAGONAL = "rd"; + public const PATTERN_RIGHT_OF_UPSIDE_DOWN_DIAGONAL = "rud"; + public const PATTERN_RIGHT_STRIPE = "rs"; + public const PATTERN_SKULL = "sku"; + public const PATTERN_SMALL_STRIPES = "ss"; + public const PATTERN_SQUARE_CROSS = "sc"; + public const PATTERN_TOP_LEFT_CORNER = "tl"; + public const PATTERN_TOP_RIGHT_CORNER = "tr"; + public const PATTERN_TOP_STRIPE = "ts"; + public const PATTERN_TOP_TRIANGLE = "tt"; + public const PATTERN_TOP_TRIANGLE_SAWTOOTH = "tts"; + public const PATTERN_VERTICAL_HALF_LEFT = "vh"; + public const PATTERN_VERTICAL_HALF_RIGHT = "vhr"; /** @var DyeColor */ private $baseColor; From 80ac0180b3e09c0a27a3f4e433b858017556ff85 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Mar 2019 13:34:32 +0000 Subject: [PATCH 0572/3224] Remove redundant isAffectedBySilkTouch() overrides this was needed previously to prevent dropping blockitems when these blocks were destroyed. Now the item form is always yielded instead. --- src/pocketmine/block/Bed.php | 10 +++------- src/pocketmine/block/Door.php | 10 +++------- src/pocketmine/block/NetherWartPlant.php | 4 ---- src/pocketmine/block/Skull.php | 4 ---- 4 files changed, 6 insertions(+), 22 deletions(-) diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 7f4caee1ec..d44f5ca2f2 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -197,9 +197,9 @@ class Bed extends Transparent{ return false; } - public function getDropsForCompatibleTool(Item $item) : array{ - if($this->isHeadPart()){ - return parent::getDropsForCompatibleTool($item); + public function getDrops(Item $item) : array{ + if($this->head){ + return parent::getDrops($item); } return []; @@ -209,10 +209,6 @@ class Bed extends Transparent{ return ItemFactory::get($this->idInfo->getItemId(), $this->color->getMagicNumber()); } - public function isAffectedBySilkTouch() : bool{ - return false; - } - public function getAffectedBlocks() : array{ if(($other = $this->getOtherHalf()) !== null){ return [$this, $other]; diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 8e588fd596..461a3878f4 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -149,18 +149,14 @@ abstract class Door extends Transparent{ return true; } - public function getDropsForCompatibleTool(Item $item) : array{ - if(!$this->top){ //bottom half only - return parent::getDropsForCompatibleTool($item); + public function getDrops(Item $item) : array{ + if(!$this->top){ + return parent::getDrops($item); } return []; } - public function isAffectedBySilkTouch() : bool{ - return false; - } - public function getAffectedBlocks() : array{ $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); if($other->isSameType($this)){ diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index f0027de2a9..c119907d74 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -85,8 +85,4 @@ class NetherWartPlant extends Flowable{ $this->asItem()->setCount($this->age === 3 ? mt_rand(2, 4) : 1) ]; } - - public function isAffectedBySilkTouch() : bool{ - return false; - } } diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index c067fc3d87..68e564a828 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -115,8 +115,4 @@ class Skull extends Flowable{ public function asItem() : Item{ return ItemFactory::get(Item::SKULL, $this->skullType->getMagicNumber()); } - - public function isAffectedBySilkTouch() : bool{ - return false; - } } From e9125af51d7f8c1cfe9b2a950009c1f851302b15 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Mar 2019 17:57:07 +0000 Subject: [PATCH 0573/3224] Revamp Banner API (still rather ghetto) this needs more work, like signs do. --- src/pocketmine/block/StandingBanner.php | 78 ++++++- src/pocketmine/block/utils/BannerPattern.php | 95 ++++++++ src/pocketmine/item/Banner.php | 172 ++------------ src/pocketmine/tile/Banner.php | 232 ++++--------------- 4 files changed, 230 insertions(+), 347 deletions(-) create mode 100644 src/pocketmine/block/utils/BannerPattern.php diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index e20490fbb8..18aa397434 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -23,6 +23,9 @@ declare(strict_types=1); namespace pocketmine\block; +use Ds\Deque; +use pocketmine\block\utils\BannerPattern; +use pocketmine\block\utils\DyeColor; use pocketmine\item\Banner as ItemBanner; use pocketmine\item\Item; use pocketmine\item\ItemFactory; @@ -31,6 +34,7 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Banner as TileBanner; +use function assert; use function floor; class StandingBanner extends Transparent{ @@ -38,6 +42,18 @@ class StandingBanner extends Transparent{ /** @var int */ protected $rotation = 0; + /** @var DyeColor */ + protected $baseColor; + + /** @var Deque|BannerPattern[] */ + protected $patterns; + + public function __construct(BlockIdentifier $idInfo, string $name){ + parent::__construct($idInfo, $name); + $this->baseColor = DyeColor::BLACK(); + $this->patterns = new Deque(); + } + protected function writeStateToMeta() : int{ return $this->rotation; } @@ -50,6 +66,23 @@ class StandingBanner extends Transparent{ return 0b1111; } + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); + $tile = $this->level->getTile($this); + if($tile instanceof TileBanner){ + $this->baseColor = $tile->getBaseColor(); + $this->setPatterns($tile->getPatterns()); + } + } + + public function writeStateToWorld() : void{ + parent::writeStateToWorld(); + $tile = $this->level->getTile($this); + assert($tile instanceof TileBanner); + $tile->setBaseColor($this->baseColor); + $tile->setPatterns($this->patterns); + } + public function getHardness() : float{ return 1; } @@ -58,18 +91,53 @@ class StandingBanner extends Transparent{ return false; } + /** + * TODO: interface method? this is only the BASE colour... + * @return DyeColor + */ + public function getColor() : DyeColor{ + return $this->baseColor; + } + + /** + * @return Deque|BannerPattern[] + */ + public function getPatterns() : Deque{ + return $this->patterns; + } + + /** + * @param Deque|BannerPattern[] $patterns + */ + public function setPatterns(Deque $patterns) : void{ + $checked = $patterns->filter(function($v){ return $v instanceof BannerPattern; }); + if($checked->count() !== $patterns->count()){ + throw new \TypeError("Deque must only contain " . BannerPattern::class . " objects"); + } + $this->patterns = $checked; + } + protected function recalculateBoundingBox() : ?AxisAlignedBB{ return null; } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($item instanceof ItemBanner){ + $this->baseColor = $item->getColor(); + $this->setPatterns($item->getPatterns()); + } if($face !== Facing::DOWN){ if($face === Facing::UP and $player !== null){ $this->rotation = ((int) floor((($player->yaw + 180) * 16 / 360) + 0.5)) & 0x0f; return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - return $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::WALL_BANNER, $face)); + //TODO: awful hack :( + $wallBanner = BlockFactory::get(Block::WALL_BANNER, $face); + assert($wallBanner instanceof WallBanner); + $wallBanner->baseColor = $this->baseColor; + $wallBanner->setPatterns($this->patterns); + return $this->getLevel()->setBlock($blockReplace, $wallBanner); } return false; @@ -86,11 +154,9 @@ class StandingBanner extends Transparent{ } public function getDropsForCompatibleTool(Item $item) : array{ - $tile = $this->level->getTile($this); - - $drop = ItemFactory::get(Item::BANNER, ($tile instanceof TileBanner ? $tile->getBaseColor()->getInvertedMagicNumber() : 0)); - if($tile instanceof TileBanner and $drop instanceof ItemBanner and !($patterns = $tile->getPatterns())->empty()){ - $drop->setPatterns($patterns); + $drop = ItemFactory::get(Item::BANNER, $this->baseColor->getInvertedMagicNumber()); + if($drop instanceof ItemBanner and !$this->patterns->isEmpty()){ + $drop->setPatterns($this->patterns); } return [$drop]; diff --git a/src/pocketmine/block/utils/BannerPattern.php b/src/pocketmine/block/utils/BannerPattern.php new file mode 100644 index 0000000000..cde366b254 --- /dev/null +++ b/src/pocketmine/block/utils/BannerPattern.php @@ -0,0 +1,95 @@ +id = $id; + $this->color = $color; + } + + /** + * @return string + */ + public function getId() : string{ + return $this->id; + } + + /** + * @return DyeColor + */ + public function getColor() : DyeColor{ + return $this->color; + } +} diff --git a/src/pocketmine/item/Banner.php b/src/pocketmine/item/Banner.php index c9deb5be4e..33bb1456df 100644 --- a/src/pocketmine/item/Banner.php +++ b/src/pocketmine/item/Banner.php @@ -23,15 +23,16 @@ declare(strict_types=1); namespace pocketmine\item; +use Ds\Deque; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\utils\BannerPattern; use pocketmine\block\utils\DyeColor; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; use pocketmine\tile\Banner as TileBanner; -use function assert; class Banner extends Item{ public const TAG_PATTERNS = TileBanner::TAG_PATTERNS; @@ -62,162 +63,33 @@ class Banner extends Item{ } /** - * Applies a new pattern on the banner with the given color. - * Banner items have to be resent to see the changes in the inventory. - * - * @param string $pattern - * @param DyeColor $color - * - * @return int ID of pattern. + * @return Deque|BannerPattern[] */ - public function addPattern(string $pattern, DyeColor $color) : int{ - $patternsTag = $this->getNamedTag()->getListTag(self::TAG_PATTERNS); - assert($patternsTag !== null); - - $patternsTag->push(new CompoundTag("", [ - new IntTag(self::TAG_PATTERN_COLOR, $color->getInvertedMagicNumber()), - new StringTag(self::TAG_PATTERN_NAME, $pattern) - ])); - - $this->setNamedTagEntry($patternsTag); - - return $patternsTag->count() - 1; - } - - /** - * Returns whether a pattern with the given ID exists on the banner or not. - * - * @param int $patternId - * - * @return bool - */ - public function patternExists(int $patternId) : bool{ - $this->correctNBT(); - return $this->getNamedTag()->getListTag(self::TAG_PATTERNS)->isset($patternId); - } - - /** - * Returns the data of a pattern with the given ID. - * - * @param int $patternId - * - * @return array - */ - public function getPatternData(int $patternId) : array{ - if(!$this->patternExists($patternId)){ - return []; + public function getPatterns() : Deque{ + $result = new Deque(); + $tag = $this->getNamedTag()->getListTag(self::TAG_PATTERNS); + if($tag !== null){ + /** @var CompoundTag $t */ + foreach($tag as $t){ + $result->push(new BannerPattern($t->getString(self::TAG_PATTERN_NAME), DyeColor::fromMagicNumber($t->getInt(self::TAG_PATTERN_COLOR), true))); + } } - - $patternsTag = $this->getNamedTag()->getListTag(self::TAG_PATTERNS); - assert($patternsTag !== null); - $pattern = $patternsTag->get($patternId); - assert($pattern instanceof CompoundTag); - - return [ - self::TAG_PATTERN_COLOR => DyeColor::fromMagicNumber($pattern->getInt(self::TAG_PATTERN_COLOR), true), - self::TAG_PATTERN_NAME => $pattern->getString(self::TAG_PATTERN_NAME) - ]; + return $result; } /** - * Changes the pattern of a previously existing pattern. - * Banner items have to be resent to see the changes in the inventory. - * - * @param int $patternId - * @param string $pattern - * @param DyeColor $color - * - * @return bool indicating success. + * @param Deque|BannerPattern[] $patterns */ - public function changePattern(int $patternId, string $pattern, DyeColor $color) : bool{ - if(!$this->patternExists($patternId)){ - return false; + public function setPatterns(Deque $patterns) : void{ + $tag = new ListTag(self::TAG_PATTERNS); + /** @var BannerPattern $pattern */ + foreach($patterns as $pattern){ + $tag->push(new CompoundTag("", [ + new StringTag(self::TAG_PATTERN_NAME, $pattern->getId()), + new IntTag(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) + ])); } - - $patternsTag = $this->getNamedTag()->getListTag(self::TAG_PATTERNS); - assert($patternsTag !== null); - - $patternsTag->set($patternId, new CompoundTag("", [ - new IntTag(self::TAG_PATTERN_COLOR, $color->getInvertedMagicNumber()), - new StringTag(self::TAG_PATTERN_NAME, $pattern) - ])); - - $this->setNamedTagEntry($patternsTag); - return true; - } - - /** - * Deletes a pattern from the banner with the given ID. - * Banner items have to be resent to see the changes in the inventory. - * - * @param int $patternId - * - * @return bool indicating whether the pattern existed or not. - */ - public function deletePattern(int $patternId) : bool{ - if(!$this->patternExists($patternId)){ - return false; - } - - $patternsTag = $this->getNamedTag()->getListTag(self::TAG_PATTERNS); - if($patternsTag instanceof ListTag){ - $patternsTag->remove($patternId); - $this->setNamedTagEntry($patternsTag); - } - - return true; - } - - /** - * Deletes the top most pattern of the banner. - * Banner items have to be resent to see the changes in the inventory. - * - * @return bool indicating whether the banner was empty or not. - */ - public function deleteTopPattern() : bool{ - return $this->deletePattern($this->getPatternCount() - 1); - } - - /** - * Deletes the bottom pattern of the banner. - * Banner items have to be resent to see the changes in the inventory. - * - * @return bool indicating whether the banner was empty or not. - */ - public function deleteBottomPattern() : bool{ - return $this->deletePattern(0); - } - - /** - * Returns the total count of patterns on this banner. - * - * @return int - */ - public function getPatternCount() : int{ - return $this->getNamedTag()->getListTag(self::TAG_PATTERNS)->count(); - } - - /** - * @return ListTag|null - */ - public function getPatterns() : ?ListTag{ - return $this->getNamedTag()->getListTag(self::TAG_PATTERNS); - } - - /** - * @param ListTag $patterns - */ - public function setPatterns(ListTag $patterns) : void{ - $this->setNamedTagEntry(clone $patterns); - } - - public function correctNBT() : void{ - $tag = $this->getNamedTag(); - - if(!$tag->hasTag(self::TAG_PATTERNS, ListTag::class)){ - $tag->setTag(new ListTag(self::TAG_PATTERNS)); - } - $this->setNamedTag($tag); + $this->setNamedTagEntry($tag); } public function getFuelTime() : int{ diff --git a/src/pocketmine/tile/Banner.php b/src/pocketmine/tile/Banner.php index 043d875f94..73593fd86c 100644 --- a/src/pocketmine/tile/Banner.php +++ b/src/pocketmine/tile/Banner.php @@ -23,78 +23,37 @@ declare(strict_types=1); namespace pocketmine\tile; +use Ds\Deque; +use pocketmine\block\StandingBanner; +use pocketmine\block\utils\BannerPattern; use pocketmine\block\utils\DyeColor; -use pocketmine\item\Banner as ItemBanner; -use pocketmine\item\Item; use pocketmine\level\Level; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; -use function assert; -class Banner extends Spawnable implements Nameable{ - use NameableTrait { - addAdditionalSpawnData as addNameSpawnData; - copyDataFromItem as protected copyNameFromItem; - } +/** + * @deprecated + * @see StandingBanner + */ +class Banner extends Spawnable{ public const TAG_BASE = "Base"; public const TAG_PATTERNS = "Patterns"; public const TAG_PATTERN_COLOR = "Color"; public const TAG_PATTERN_NAME = "Pattern"; - public const PATTERN_BORDER = "bo"; - public const PATTERN_BOTTOM_LEFT_CORNER = "bl"; - public const PATTERN_BOTTOM_RIGHT_CORNER = "br"; - public const PATTERN_BOTTOM_STRIPE = "bs"; - public const PATTERN_BOTTOM_TRIANGLE = "bt"; - public const PATTERN_BOTTOM_TRIANGLE_SAWTOOTH = "bts"; - public const PATTERN_BRICK = "bri"; - public const PATTERN_CENTER_STRIPE = "cs"; - public const PATTERN_CREEPER = "cre"; - public const PATTERN_CURLY_BORDER = "cbo"; - public const PATTERN_DIAGONAL_CROSS = "cr"; - public const PATTERN_DOWN_LEFT_STRIPE = "dls"; - public const PATTERN_DOWN_RIGHT_STRIPE = "drs"; - public const PATTERN_FLOWER = "flo"; - public const PATTERN_GRADIENT = "gra"; - public const PATTERN_GRADIENT_UPSIDE_DOWN = "gru"; - public const PATTERN_HORIZONTAL_HALF_BOTTOM = "hhb"; - public const PATTERN_HORIZONTAL_HALF_TOP = "hh"; - public const PATTERN_LEFT_OF_DIAGONAL = "ld"; - public const PATTERN_LEFT_OF_UPSIDE_DOWN_DIAGONAL = "lud"; - public const PATTERN_LEFT_STRIPE = "ls"; - public const PATTERN_MIDDLE_CIRCLE = "mc"; - public const PATTERN_MIDDLE_RHOMBUS = "mr"; - public const PATTERN_MIDDLE_STRIPE = "ms"; - public const PATTERN_MOJANG = "moj"; - public const PATTERN_RIGHT_OF_DIAGONAL = "rd"; - public const PATTERN_RIGHT_OF_UPSIDE_DOWN_DIAGONAL = "rud"; - public const PATTERN_RIGHT_STRIPE = "rs"; - public const PATTERN_SKULL = "sku"; - public const PATTERN_SMALL_STRIPES = "ss"; - public const PATTERN_SQUARE_CROSS = "sc"; - public const PATTERN_TOP_LEFT_CORNER = "tl"; - public const PATTERN_TOP_RIGHT_CORNER = "tr"; - public const PATTERN_TOP_STRIPE = "ts"; - public const PATTERN_TOP_TRIANGLE = "tt"; - public const PATTERN_TOP_TRIANGLE_SAWTOOTH = "tts"; - public const PATTERN_VERTICAL_HALF_LEFT = "vh"; - public const PATTERN_VERTICAL_HALF_RIGHT = "vhr"; - /** @var DyeColor */ private $baseColor; - /** - * @var ListTag - * TODO: break this down further and remove runtime NBT from here entirely - */ - private $patterns; + + /** @var BannerPattern[]|Deque */ + private $patterns = []; public function __construct(Level $level, Vector3 $pos){ $this->baseColor = DyeColor::BLACK(); - $this->patterns = new ListTag(self::TAG_PATTERNS); + $this->patterns = new Deque(); parent::__construct($level, $pos); } @@ -103,31 +62,37 @@ class Banner extends Spawnable implements Nameable{ $this->baseColor = DyeColor::fromMagicNumber($nbt->getInt(self::TAG_BASE), true); } - $this->patterns = $nbt->getListTag(self::TAG_PATTERNS) ?? $this->patterns; - $this->loadName($nbt); + $patterns = $nbt->getListTag(self::TAG_PATTERNS); + if($patterns !== null){ + /** @var CompoundTag $pattern */ + foreach($patterns as $pattern){ + $this->patterns[] = new BannerPattern($pattern->getString(self::TAG_PATTERN_NAME), DyeColor::fromMagicNumber($pattern->getInt(self::TAG_PATTERN_COLOR), true)); + } + } } protected function writeSaveData(CompoundTag $nbt) : void{ $nbt->setInt(self::TAG_BASE, $this->baseColor->getInvertedMagicNumber()); - $nbt->setTag($this->patterns); - $this->saveName($nbt); + $patterns = new ListTag(self::TAG_PATTERNS); + foreach($this->patterns as $pattern){ + $patterns->push(new CompoundTag("", [ + new StringTag(self::TAG_PATTERN_NAME, $pattern->getId()), + new IntTag(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) + ])); + } + $nbt->setTag($patterns); } protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ $nbt->setInt(self::TAG_BASE, $this->baseColor->getInvertedMagicNumber()); - $nbt->setTag($this->patterns); - $this->addNameSpawnData($nbt); - } - - public function copyDataFromItem(Item $item) : void{ - parent::copyDataFromItem($item); - $this->copyNameFromItem($item); - if($item instanceof ItemBanner){ - $this->setBaseColor($item->getColor()); - if(($patterns = $item->getPatterns()) !== null){ - $this->setPatterns($patterns); - } + $patterns = new ListTag(self::TAG_PATTERNS); + foreach($this->patterns as $pattern){ + $patterns->push(new CompoundTag("", [ + new StringTag(self::TAG_PATTERN_NAME, $pattern->getId()), + new IntTag(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) + ])); } + $nbt->setTag($patterns); } /** @@ -150,132 +115,17 @@ class Banner extends Spawnable implements Nameable{ } /** - * Applies a new pattern on the banner with the given color. - * - * @param string $pattern - * @param DyeColor $color - * - * @return int ID of pattern. + * @return BannerPattern[]|Deque */ - public function addPattern(string $pattern, DyeColor $color) : int{ - $this->patterns->push(new CompoundTag("", [ - new IntTag(self::TAG_PATTERN_COLOR, $color->getInvertedMagicNumber()), - new StringTag(self::TAG_PATTERN_NAME, $pattern) - ])); - - $this->onChanged(); - return $this->patterns->count() - 1; //Last offset in the list - } - - /** - * Returns whether a pattern with the given ID exists on the banner or not. - * - * @param int $patternId - * - * @return bool - */ - public function patternExists(int $patternId) : bool{ - return $this->patterns->isset($patternId); - } - - /** - * Returns the data of a pattern with the given ID. - * - * @param int $patternId - * - * @return array - */ - public function getPatternData(int $patternId) : array{ - if(!$this->patternExists($patternId)){ - return []; - } - - $patternTag = $this->patterns->get($patternId); - assert($patternTag instanceof CompoundTag); - - return [ - self::TAG_PATTERN_COLOR => DyeColor::fromMagicNumber($patternTag->getInt(self::TAG_PATTERN_COLOR), true), - self::TAG_PATTERN_NAME => $patternTag->getString(self::TAG_PATTERN_NAME) - ]; - } - - /** - * Changes the pattern of a previously existing pattern. - * - * @param int $patternId - * @param string $pattern - * @param DyeColor $color - * - * @return bool indicating success. - */ - public function changePattern(int $patternId, string $pattern, DyeColor $color) : bool{ - if(!$this->patternExists($patternId)){ - return false; - } - - $this->patterns->set($patternId, new CompoundTag("", [ - new IntTag(self::TAG_PATTERN_COLOR, $color->getInvertedMagicNumber()), - new StringTag(self::TAG_PATTERN_NAME, $pattern) - ])); - - $this->onChanged(); - return true; - } - - /** - * Deletes a pattern from the banner with the given ID. - * - * @param int $patternId - * - * @return bool indicating whether the pattern existed or not. - */ - public function deletePattern(int $patternId) : bool{ - if(!$this->patternExists($patternId)){ - return false; - } - - $this->patterns->remove($patternId); - - $this->onChanged(); - return true; - } - - /** - * Deletes the top most pattern of the banner. - * - * @return bool indicating whether the banner was empty or not. - */ - public function deleteTopPattern() : bool{ - return $this->deletePattern($this->getPatternCount() - 1); - } - - /** - * Deletes the bottom pattern of the banner. - * - * @return bool indicating whether the banner was empty or not. - */ - public function deleteBottomPattern() : bool{ - return $this->deletePattern(0); - } - - /** - * Returns the total count of patterns on this banner. - * - * @return int - */ - public function getPatternCount() : int{ - return $this->patterns->count(); - } - - /** - * @return ListTag - */ - public function getPatterns() : ListTag{ + public function getPatterns() : Deque{ return $this->patterns; } - public function setPatterns(ListTag $patterns) : void{ - $this->patterns = clone $patterns; + /** + * @param BannerPattern[]|Deque $patterns + */ + public function setPatterns(Deque $patterns) : void{ + $this->patterns = $patterns; $this->onChanged(); } From 72233a509d8d0d5dd1122729e07477dc1fec0f9f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Mar 2019 18:08:03 +0000 Subject: [PATCH 0574/3224] preprocessor fix --- .../network/mcpe/protocol/ClientboundMapItemDataPacket.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php b/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php index f9a4802d2c..2c5ed30a86 100644 --- a/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php @@ -31,10 +31,12 @@ use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\protocol\types\MapTrackedObject; -use pocketmine\utils\Binary; use pocketmine\utils\Color; use function assert; use function count; +#ifndef COMPILE +use pocketmine\utils\Binary; +#endif class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CLIENTBOUND_MAP_ITEM_DATA_PACKET; From d961b272c72ae894b82e73fa18a24a8125fcd521 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Mar 2019 18:18:56 +0000 Subject: [PATCH 0575/3224] Remove Tool <-> Block circular dependency in efficiency calculation --- src/pocketmine/block/Block.php | 2 +- src/pocketmine/item/Item.php | 2 +- src/pocketmine/item/Sword.php | 4 ++-- src/pocketmine/item/Tool.php | 5 ++--- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 8ae99f582b..8d25ed1927 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -325,7 +325,7 @@ class Block extends Position implements BlockIds, Metadatable{ $base *= 5; } - $efficiency = $item->getMiningEfficiency($this); + $efficiency = $item->getMiningEfficiency(($this->getToolType() & $item->getBlockToolType()) !== 0); if($efficiency <= 0){ throw new \InvalidArgumentException(get_class($item) . " has invalid mining efficiency: expected >= 0, got $efficiency"); } diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 259adb6829..9e07fbc7c8 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -726,7 +726,7 @@ class Item implements ItemIds, \JsonSerializable{ return 0; } - public function getMiningEfficiency(Block $block) : float{ + public function getMiningEfficiency(bool $isCorrectTool) : float{ return 1; } diff --git a/src/pocketmine/item/Sword.php b/src/pocketmine/item/Sword.php index ea411352d3..39d72a6716 100644 --- a/src/pocketmine/item/Sword.php +++ b/src/pocketmine/item/Sword.php @@ -41,8 +41,8 @@ class Sword extends TieredTool{ return 1; } - public function getMiningEfficiency(Block $block) : float{ - return parent::getMiningEfficiency($block) * 1.5; //swords break any block 1.5x faster than hand + public function getMiningEfficiency(bool $isCorrectTool) : float{ + return parent::getMiningEfficiency($isCorrectTool) * 1.5; //swords break any block 1.5x faster than hand } protected function getBaseMiningEfficiency() : float{ diff --git a/src/pocketmine/item/Tool.php b/src/pocketmine/item/Tool.php index 6671b05c20..47a9b651b9 100644 --- a/src/pocketmine/item/Tool.php +++ b/src/pocketmine/item/Tool.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\block\Block; use pocketmine\item\enchantment\Enchantment; abstract class Tool extends Durable{ @@ -32,9 +31,9 @@ abstract class Tool extends Durable{ return 1; } - public function getMiningEfficiency(Block $block) : float{ + public function getMiningEfficiency(bool $isCorrectTool) : float{ $efficiency = 1; - if(($block->getToolType() & $this->getBlockToolType()) !== 0){ + if($isCorrectTool){ $efficiency = $this->getBaseMiningEfficiency(); if(($enchantmentLevel = $this->getEnchantmentLevel(Enchantment::EFFICIENCY())) > 0){ $efficiency += ($enchantmentLevel ** 2 + 1); From 418d0f12fb5fe2810b63b1ec2d1e9d24b17f011a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Mar 2019 19:15:24 +0000 Subject: [PATCH 0576/3224] Slab: placement logic clean up past me was full of shit, because blockReplace is the same as blockClicked when we click a single slab top/bottom to make a double slab, and the logic is identical to the below block with that in mind. --- src/pocketmine/block/Slab.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index dd7599972f..74c0d6e96d 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -105,16 +105,6 @@ abstract class Slab extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - /* note these conditions can't be merged, since one targets clicked and the other replace */ - - if($blockClicked instanceof Slab and $blockClicked->slabType !== SlabType::DOUBLE() and $blockClicked->isSameType($this) and ( - ($face === Facing::DOWN and $blockClicked->slabType === SlabType::TOP()) or - ($face === Facing::UP and $blockClicked->slabType === SlabType::BOTTOM()) - )){ - $this->slabType = SlabType::DOUBLE(); - return $this->level->setBlock($blockClicked, $this); - } - if($blockReplace instanceof Slab and $blockReplace->slabType !== SlabType::DOUBLE() and $blockReplace->isSameType($this) and ( ($blockReplace->slabType === SlabType::TOP() and ($clickVector->y <= 0.5 or $face === Facing::UP)) or ($blockReplace->slabType === SlabType::BOTTOM() and ($clickVector->y >= 0.5 or $face === Facing::DOWN)) From 1f5c901f298e0877f17b9061988f6232082a599f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Mar 2019 20:03:16 +0000 Subject: [PATCH 0577/3224] ext-ds is now required --- .travis.yml | 1 + composer.json | 1 + composer.lock | 19 ++++++++++--------- src/pocketmine/PocketMine.php | 1 + 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2f6d0fb357..68590462f1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ before_script: # - pecl install channel://pecl.php.net/pthreads-3.1.6 - echo | pecl install channel://pecl.php.net/yaml-2.0.4 - pecl install channel://pecl.php.net/crypto-0.3.1 + - pecl install channel://pecl.php.net/ds-1.2.8 - git clone https://github.com/pmmp/pthreads.git - cd pthreads - git checkout 6ca019c58b4fa09ee2ff490f2444e34bef0773d0 diff --git a/composer.json b/composer.json index 7a4bcb21bc..013babad38 100644 --- a/composer.json +++ b/composer.json @@ -12,6 +12,7 @@ "ext-crypto": "^0.3.1", "ext-ctype": "*", "ext-date": "*", + "ext-ds": "^1.2.7", "ext-gmp": "*", "ext-hash": "*", "ext-json": "*", diff --git a/composer.lock b/composer.lock index bfe6aa6555..7d512129d1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "959fe32be1db4613fd22eb2c7c7b23c6", + "content-hash": "d865f72c482e34c96a7e46bc535d0c15", "packages": [ { "name": "adhocore/json-comment", @@ -413,12 +413,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "2d19bbaa4fb92d9eabe8c027ea0af9dbd6a90100" + "reference": "d9f15311ef328bddd5891fb7e92d2b3a7e48f501" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/2d19bbaa4fb92d9eabe8c027ea0af9dbd6a90100", - "reference": "2d19bbaa4fb92d9eabe8c027ea0af9dbd6a90100", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/d9f15311ef328bddd5891fb7e92d2b3a7e48f501", + "reference": "d9f15311ef328bddd5891fb7e92d2b3a7e48f501", "shasum": "" }, "require": { @@ -446,7 +446,7 @@ "source": "https://github.com/pmmp/RakLib/tree/master", "issues": "https://github.com/pmmp/RakLib/issues" }, - "time": "2019-02-15T12:21:28+00:00" + "time": "2019-02-21T14:39:41+00:00" }, { "name": "pocketmine/snooze", @@ -488,12 +488,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/SPL.git", - "reference": "d7bd7b8cb10c264ca6e6b5c3ef9b52e48a6f29d8" + "reference": "35110fcc742701d5f2b8093d63365c42900236c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/SPL/zipball/d7bd7b8cb10c264ca6e6b5c3ef9b52e48a6f29d8", - "reference": "d7bd7b8cb10c264ca6e6b5c3ef9b52e48a6f29d8", + "url": "https://api.github.com/repos/pmmp/SPL/zipball/35110fcc742701d5f2b8093d63365c42900236c1", + "reference": "35110fcc742701d5f2b8093d63365c42900236c1", "shasum": "" }, "type": "library", @@ -512,7 +512,7 @@ "support": { "source": "https://github.com/pmmp/SPL/tree/master" }, - "time": "2019-01-17T18:54:01+00:00" + "time": "2019-02-23T12:20:29+00:00" } ], "packages-dev": [], @@ -536,6 +536,7 @@ "ext-crypto": "^0.3.1", "ext-ctype": "*", "ext-date": "*", + "ext-ds": "^1.2.7", "ext-gmp": "*", "ext-hash": "*", "ext-json": "*", diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index b51cc9ebb6..daf84e6cb1 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -80,6 +80,7 @@ namespace pocketmine { "crypto" => "php-crypto", "ctype" => "ctype", "date" => "Date", + "ds" => "Data Structures", "gmp" => "GMP", "hash" => "Hash", "json" => "JSON", From 6c8fa8ae283eebaed245ab4334b792fc9453fe8a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Mar 2019 10:29:11 +0000 Subject: [PATCH 0578/3224] More nullable and void typehints --- src/pocketmine/CrashDump.php | 16 ++--- src/pocketmine/IPlayer.php | 10 +-- src/pocketmine/MemoryManager.php | 12 ++-- src/pocketmine/OfflinePlayer.php | 18 +++--- src/pocketmine/Player.php | 48 ++++++++------ src/pocketmine/Server.php | 62 +++++++++---------- src/pocketmine/Thread.php | 8 +-- src/pocketmine/ThreadManager.php | 8 +-- src/pocketmine/Worker.php | 8 +-- src/pocketmine/block/Bed.php | 2 +- src/pocketmine/block/Block.php | 4 +- src/pocketmine/block/Lava.php | 2 +- src/pocketmine/block/Liquid.php | 2 +- src/pocketmine/block/TNT.php | 2 +- src/pocketmine/command/Command.php | 14 ++--- src/pocketmine/command/CommandMap.php | 6 +- src/pocketmine/command/CommandReader.php | 10 +-- src/pocketmine/command/CommandSender.php | 6 +- .../command/ConsoleCommandSender.php | 12 ++-- src/pocketmine/command/SimpleCommandMap.php | 12 ++-- .../command/defaults/BanIpCommand.php | 2 +- .../command/defaults/ParticleCommand.php | 2 +- .../command/defaults/VersionCommand.php | 2 +- src/pocketmine/entity/Entity.php | 4 +- src/pocketmine/entity/Explosive.php | 2 +- src/pocketmine/event/Cancellable.php | 2 +- .../event/player/PlayerCreationEvent.php | 4 +- src/pocketmine/inventory/BaseInventory.php | 2 +- src/pocketmine/inventory/CraftingGrid.php | 2 +- src/pocketmine/inventory/CraftingManager.php | 2 +- .../inventory/EnderChestInventory.php | 2 +- src/pocketmine/inventory/FurnaceRecipe.php | 2 +- .../inventory/PlayerCursorInventory.php | 2 +- src/pocketmine/inventory/PlayerInventory.php | 8 +-- src/pocketmine/item/ChorusFruit.php | 2 +- src/pocketmine/item/Consumable.php | 2 +- src/pocketmine/item/Durable.php | 2 +- src/pocketmine/item/Food.php | 2 +- src/pocketmine/item/Item.php | 2 +- src/pocketmine/item/ItemFactory.php | 4 +- src/pocketmine/item/MilkBucket.php | 2 +- src/pocketmine/item/Potion.php | 2 +- src/pocketmine/lang/Language.php | 2 +- src/pocketmine/lang/TextContainer.php | 2 +- src/pocketmine/lang/TranslationContainer.php | 6 +- src/pocketmine/level/ChunkListener.php | 10 +-- src/pocketmine/level/ChunkManager.php | 8 +-- src/pocketmine/level/Level.php | 24 +++---- src/pocketmine/level/LevelManager.php | 4 +- src/pocketmine/level/Location.php | 10 +-- src/pocketmine/level/SimpleChunkManager.php | 10 +-- src/pocketmine/level/biome/Biome.php | 16 ++--- src/pocketmine/level/format/Chunk.php | 40 ++++++------ src/pocketmine/level/format/EmptySubChunk.php | 4 +- src/pocketmine/level/format/SubChunk.php | 6 +- .../level/format/SubChunkInterface.php | 4 +- .../level/format/io/LevelProviderManager.php | 2 +- .../level/light/BlockLightUpdate.php | 2 +- src/pocketmine/level/light/LightUpdate.php | 10 +-- src/pocketmine/level/light/SkyLightUpdate.php | 2 +- .../metadata/BlockMetadataStore.php | 4 +- .../metadata/EntityMetadataStore.php | 4 +- .../metadata/LevelMetadataStore.php | 4 +- src/pocketmine/metadata/MetadataStore.php | 6 +- src/pocketmine/metadata/MetadataValue.php | 4 +- src/pocketmine/metadata/Metadatable.php | 4 +- .../metadata/PlayerMetadataStore.php | 4 +- src/pocketmine/permission/BanEntry.php | 10 +-- src/pocketmine/permission/BanList.php | 12 ++-- .../permission/DefaultPermissions.php | 2 +- src/pocketmine/permission/Permissible.php | 4 +- src/pocketmine/permission/PermissibleBase.php | 10 +-- src/pocketmine/permission/Permission.php | 8 +-- .../permission/PermissionAttachment.php | 16 ++--- .../permission/PermissionAttachmentInfo.php | 2 +- .../permission/PermissionManager.php | 18 +++--- .../permission/PermissionRemovedExecutor.php | 2 +- src/pocketmine/permission/ServerOperator.php | 2 +- src/pocketmine/plugin/Plugin.php | 2 +- src/pocketmine/plugin/PluginBase.php | 2 +- src/pocketmine/plugin/PluginDescription.php | 4 +- src/pocketmine/plugin/PluginManager.php | 12 ++-- src/pocketmine/plugin/RegisteredListener.php | 2 +- .../resourcepacks/ResourcePackManager.php | 2 +- src/pocketmine/scheduler/AsyncTask.php | 2 +- src/pocketmine/scheduler/AsyncWorker.php | 4 +- src/pocketmine/scheduler/ClosureTask.php | 2 +- src/pocketmine/scheduler/Task.php | 2 +- src/pocketmine/scheduler/TaskHandler.php | 8 +-- src/pocketmine/scheduler/TaskScheduler.php | 16 ++--- src/pocketmine/tile/Bed.php | 2 +- src/pocketmine/tile/FlowerPot.php | 2 +- src/pocketmine/tile/ItemFrame.php | 6 +- src/pocketmine/tile/Nameable.php | 2 +- src/pocketmine/tile/Skull.php | 2 +- src/pocketmine/tile/TileFactory.php | 2 +- src/pocketmine/timings/Timings.php | 2 +- src/pocketmine/timings/TimingsHandler.php | 14 ++--- src/pocketmine/updater/AutoUpdater.php | 18 +++--- src/pocketmine/utils/Color.php | 12 ++-- src/pocketmine/utils/Config.php | 16 ++--- src/pocketmine/utils/Internet.php | 2 +- src/pocketmine/utils/MainLogger.php | 14 ++--- src/pocketmine/utils/Random.php | 2 +- src/pocketmine/utils/ServerKiller.php | 2 +- src/pocketmine/utils/Terminal.php | 4 +- src/pocketmine/utils/Utils.php | 4 +- src/pocketmine/wizard/SetupWizard.php | 16 ++--- 108 files changed, 392 insertions(+), 384 deletions(-) diff --git a/src/pocketmine/CrashDump.php b/src/pocketmine/CrashDump.php index 7c9cfeb808..5c98a82e4b 100644 --- a/src/pocketmine/CrashDump.php +++ b/src/pocketmine/CrashDump.php @@ -118,7 +118,7 @@ class CrashDump{ return $this->path; } - public function getEncodedData(){ + public function getEncodedData() : string{ return $this->encodedData; } @@ -126,7 +126,7 @@ class CrashDump{ return $this->data; } - private function encodeData(){ + private function encodeData() : void{ $this->addLine(); $this->addLine("----------------------REPORT THE DATA BELOW THIS LINE-----------------------"); $this->addLine(); @@ -142,7 +142,7 @@ class CrashDump{ $this->addLine("===END CRASH DUMP==="); } - private function pluginsData(){ + private function pluginsData() : void{ if($this->server->getPluginManager() instanceof PluginManager){ $this->addLine(); $this->addLine("Loaded plugins:"); @@ -166,7 +166,7 @@ class CrashDump{ } } - private function extraData(){ + private function extraData() : void{ global $argv; if($this->server->getProperty("auto-report.send-settings", true) !== false){ @@ -192,7 +192,7 @@ class CrashDump{ } } - private function baseCrash(){ + private function baseCrash() : void{ global $lastExceptionError, $lastError; if(isset($lastExceptionError)){ @@ -287,7 +287,7 @@ class CrashDump{ return false; } - private function generalData(){ + private function generalData() : void{ $version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER); $this->data["general"] = []; $this->data["general"]["name"] = $this->server->getName(); @@ -310,11 +310,11 @@ class CrashDump{ $this->addLine("OS : " . PHP_OS . ", " . Utils::getOS()); } - public function addLine($line = ""){ + public function addLine($line = "") : void{ fwrite($this->fp, $line . PHP_EOL); } - public function add($str){ + public function add($str) : void{ fwrite($this->fp, $str); } } diff --git a/src/pocketmine/IPlayer.php b/src/pocketmine/IPlayer.php index bc0e8bc9dc..4d007a1888 100644 --- a/src/pocketmine/IPlayer.php +++ b/src/pocketmine/IPlayer.php @@ -45,7 +45,7 @@ interface IPlayer extends ServerOperator{ /** * @param bool $banned */ - public function setBanned(bool $banned); + public function setBanned(bool $banned) : void; /** * @return bool @@ -55,22 +55,22 @@ interface IPlayer extends ServerOperator{ /** * @param bool $value */ - public function setWhitelisted(bool $value); + public function setWhitelisted(bool $value) : void; /** * @return Player|null */ - public function getPlayer(); + public function getPlayer() : ?Player; /** * @return int|null */ - public function getFirstPlayed(); + public function getFirstPlayed() : ?int; /** * @return int|null */ - public function getLastPlayed(); + public function getLastPlayed() : ?int; /** * @return bool diff --git a/src/pocketmine/MemoryManager.php b/src/pocketmine/MemoryManager.php index fcf29504af..db35ca765a 100644 --- a/src/pocketmine/MemoryManager.php +++ b/src/pocketmine/MemoryManager.php @@ -115,7 +115,7 @@ class MemoryManager{ $this->init(); } - private function init(){ + private function init() : void{ $this->memoryLimit = ((int) $this->server->getProperty("memory.main-limit", 0)) * 1024 * 1024; $defaultMemory = 1024; @@ -202,7 +202,7 @@ class MemoryManager{ * @param bool $global * @param int $triggerCount */ - public function trigger(int $memory, int $limit, bool $global = false, int $triggerCount = 0){ + public function trigger(int $memory, int $limit, bool $global = false, int $triggerCount = 0) : void{ $this->server->getLogger()->debug(sprintf("[Memory Manager] %sLow memory triggered, limit %gMB, using %gMB", $global ? "Global " : "", round(($limit / 1024) / 1024, 2), round(($memory / 1024) / 1024, 2))); if($this->lowMemClearWorldCache){ @@ -231,7 +231,7 @@ class MemoryManager{ /** * Called every tick to update the memory manager state. */ - public function check(){ + public function check() : void{ Timings::$memoryManagerTimer->startTiming(); if(($this->memoryLimit > 0 or $this->globalMemoryLimit > 0) and ++$this->checkTicker >= $this->checkRate){ @@ -298,7 +298,7 @@ class MemoryManager{ * @param int $maxNesting * @param int $maxStringSize */ - public function dumpServerMemory(string $outputFolder, int $maxNesting, int $maxStringSize){ + public function dumpServerMemory(string $outputFolder, int $maxNesting, int $maxStringSize) : void{ $this->server->getLogger()->notice("[Dump] After the memory dump is done, the server might crash"); self::dumpMemory($this->server, $outputFolder, $maxNesting, $maxStringSize, $this->server->getLogger()); @@ -321,7 +321,7 @@ class MemoryManager{ * * @throws \ReflectionException */ - public static function dumpMemory($startingObject, string $outputFolder, int $maxNesting, int $maxStringSize, \Logger $logger){ + public static function dumpMemory($startingObject, string $outputFolder, int $maxNesting, int $maxStringSize, \Logger $logger) : void{ $hardLimit = ini_get('memory_limit'); ini_set('memory_limit', '-1'); gc_disable(); @@ -479,7 +479,7 @@ class MemoryManager{ * @param int $maxNesting * @param int $maxStringSize */ - private static function continueDump($from, &$data, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize){ + private static function continueDump($from, &$data, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize) : void{ if($maxNesting <= 0){ $data = "(error) NESTING LIMIT REACHED"; return; diff --git a/src/pocketmine/OfflinePlayer.php b/src/pocketmine/OfflinePlayer.php index 9e9d88e147..8de4013fec 100644 --- a/src/pocketmine/OfflinePlayer.php +++ b/src/pocketmine/OfflinePlayer.php @@ -64,7 +64,7 @@ class OfflinePlayer implements IPlayer, Metadatable{ return $this->server->isOp($this->name); } - public function setOp(bool $value){ + public function setOp(bool $value) : void{ if($value === $this->isOp()){ return; } @@ -80,8 +80,8 @@ class OfflinePlayer implements IPlayer, Metadatable{ return $this->server->getNameBans()->isBanned($this->name); } - public function setBanned(bool $value){ - if($value){ + public function setBanned(bool $banned) : void{ + if($banned){ $this->server->getNameBans()->addBan($this->name, null, null, null); }else{ $this->server->getNameBans()->remove($this->name); @@ -92,7 +92,7 @@ class OfflinePlayer implements IPlayer, Metadatable{ return $this->server->isWhitelisted($this->name); } - public function setWhitelisted(bool $value){ + public function setWhitelisted(bool $value) : void{ if($value){ $this->server->addWhitelist($this->name); }else{ @@ -100,15 +100,15 @@ class OfflinePlayer implements IPlayer, Metadatable{ } } - public function getPlayer(){ + public function getPlayer() : ?Player{ return $this->server->getPlayerExact($this->name); } - public function getFirstPlayed(){ + public function getFirstPlayed() : ?int{ return ($this->namedtag !== null and $this->namedtag->hasTag("firstPlayed", LongTag::class)) ? $this->namedtag->getInt("firstPlayed") : null; } - public function getLastPlayed(){ + public function getLastPlayed() : ?int{ return ($this->namedtag !== null and $this->namedtag->hasTag("lastPlayed", LongTag::class)) ? $this->namedtag->getLong("lastPlayed") : null; } @@ -116,7 +116,7 @@ class OfflinePlayer implements IPlayer, Metadatable{ return $this->namedtag !== null; } - public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue){ + public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue) : void{ $this->server->getPlayerMetadata()->setMetadata($this, $metadataKey, $newMetadataValue); } @@ -128,7 +128,7 @@ class OfflinePlayer implements IPlayer, Metadatable{ return $this->server->getPlayerMetadata()->hasMetadata($this, $metadataKey); } - public function removeMetadata(string $metadataKey, Plugin $owningPlugin){ + public function removeMetadata(string $metadataKey, Plugin $owningPlugin) : void{ $this->server->getPlayerMetadata()->removeMetadata($this, $metadataKey, $owningPlugin); } } diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index f48431571f..96333618a2 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -325,8 +325,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->server->getNameBans()->isBanned($this->username); } - public function setBanned(bool $value){ - if($value){ + public function setBanned(bool $banned) : void{ + if($banned){ $this->server->getNameBans()->addBan($this->getName(), null, null, null); $this->kick("You have been banned"); }else{ @@ -338,7 +338,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->server->isWhitelisted($this->username); } - public function setWhitelisted(bool $value){ + public function setWhitelisted(bool $value) : void{ if($value){ $this->server->addWhitelist($this->username); }else{ @@ -381,15 +381,23 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return parent::getUniqueId(); } - public function getPlayer(){ + public function getPlayer() : ?Player{ return $this; } - public function getFirstPlayed(){ + /** + * TODO: not sure this should be nullable + * @return int|null + */ + public function getFirstPlayed() : ?int{ return $this->firstPlayed; } - public function getLastPlayed(){ + /** + * TODO: not sure this should be nullable + * @return int|null + */ + public function getLastPlayed() : ?int{ return $this->lastPlayed; } @@ -447,7 +455,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * @return Server */ - public function getServer(){ + public function getServer() : Server{ return $this->server; } @@ -469,7 +477,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->lineHeight ?? 7; } - public function setScreenLineHeight(?int $height){ + public function setScreenLineHeight(?int $height) : void{ if($height !== null and $height < 1){ throw new \InvalidArgumentException("Line height must be at least 1"); } @@ -557,7 +565,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * @param bool $value */ - public function setOp(bool $value){ + public function setOp(bool $value) : void{ if($value === $this->isOp()){ return; } @@ -608,11 +616,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * @param PermissionAttachment $attachment */ - public function removeAttachment(PermissionAttachment $attachment){ + public function removeAttachment(PermissionAttachment $attachment) : void{ $this->perm->removeAttachment($attachment); } - public function recalculatePermissions(){ + public function recalculatePermissions() : void{ $permManager = PermissionManager::getInstance(); $permManager->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this); $permManager->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this); @@ -2678,7 +2686,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * * @param TextContainer|string $message */ - public function sendMessage($message){ + public function sendMessage($message) : void{ if($message instanceof TextContainer){ if($message instanceof TranslationContainer){ $this->sendTranslation($message->getText(), $message->getParameters()); @@ -3215,7 +3223,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * * @return Inventory|null */ - public function getWindow(int $windowId){ + public function getWindow(int $windowId) : ?Inventory{ return $this->windowIndex[$windowId] ?? null; } @@ -3309,7 +3317,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } - public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue){ + public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue) : void{ $this->server->getPlayerMetadata()->setMetadata($this, $metadataKey, $newMetadataValue); } @@ -3321,30 +3329,30 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->server->getPlayerMetadata()->hasMetadata($this, $metadataKey); } - public function removeMetadata(string $metadataKey, Plugin $owningPlugin){ + public function removeMetadata(string $metadataKey, Plugin $owningPlugin) : void{ $this->server->getPlayerMetadata()->removeMetadata($this, $metadataKey, $owningPlugin); } - public function onChunkChanged(Chunk $chunk){ + public function onChunkChanged(Chunk $chunk) : void{ if(isset($this->usedChunks[$hash = Level::chunkHash($chunk->getX(), $chunk->getZ())])){ $this->usedChunks[$hash] = false; $this->nextChunkOrderRun = 0; } } - public function onChunkLoaded(Chunk $chunk){ + public function onChunkLoaded(Chunk $chunk) : void{ } - public function onChunkPopulated(Chunk $chunk){ + public function onChunkPopulated(Chunk $chunk) : void{ } - public function onChunkUnloaded(Chunk $chunk){ + public function onChunkUnloaded(Chunk $chunk) : void{ } - public function onBlockChanged(Vector3 $block){ + public function onBlockChanged(Vector3 $block) : void{ } } diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 10d8302fc4..9b4ab06fac 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -668,7 +668,7 @@ class Server{ * @param string $name * @param CompoundTag $nbtTag */ - public function saveOfflinePlayerData(string $name, CompoundTag $nbtTag){ + public function saveOfflinePlayerData(string $name, CompoundTag $nbtTag) : void{ $ev = new PlayerDataSaveEvent($nbtTag, $name); $ev->setCancelled(!$this->shouldSavePlayerData()); @@ -690,7 +690,7 @@ class Server{ * * @return Player|null */ - public function getPlayer(string $name){ + public function getPlayer(string $name) : ?Player{ $found = null; $name = strtolower($name); $delta = PHP_INT_MAX; @@ -715,7 +715,7 @@ class Server{ * * @return Player|null */ - public function getPlayerExact(string $name){ + public function getPlayerExact(string $name) : ?Player{ $name = strtolower($name); foreach($this->getOnlinePlayers() as $player){ if($player->getLowerCaseName() === $name){ @@ -806,7 +806,7 @@ class Server{ * @param string $variable * @param string $value */ - public function setConfigString(string $variable, string $value){ + public function setConfigString(string $variable, string $value) : void{ $this->properties->set($variable, $value); } @@ -829,7 +829,7 @@ class Server{ * @param string $variable * @param int $value */ - public function setConfigInt(string $variable, int $value){ + public function setConfigInt(string $variable, int $value) : void{ $this->properties->set($variable, $value); } @@ -865,7 +865,7 @@ class Server{ * @param string $variable * @param bool $value */ - public function setConfigBool(string $variable, bool $value){ + public function setConfigBool(string $variable, bool $value) : void{ $this->properties->set($variable, $value ? "1" : "0"); } @@ -899,7 +899,7 @@ class Server{ /** * @param string $name */ - public function addOp(string $name){ + public function addOp(string $name) : void{ $this->operators->set(strtolower($name), true); if(($player = $this->getPlayerExact($name)) !== null){ @@ -911,7 +911,7 @@ class Server{ /** * @param string $name */ - public function removeOp(string $name){ + public function removeOp(string $name) : void{ $this->operators->remove(strtolower($name)); if(($player = $this->getPlayerExact($name)) !== null){ @@ -923,7 +923,7 @@ class Server{ /** * @param string $name */ - public function addWhitelist(string $name){ + public function addWhitelist(string $name) : void{ $this->whitelist->set(strtolower($name), true); $this->whitelist->save(); } @@ -931,7 +931,7 @@ class Server{ /** * @param string $name */ - public function removeWhitelist(string $name){ + public function removeWhitelist(string $name) : void{ $this->whitelist->remove(strtolower($name)); $this->whitelist->save(); } @@ -968,7 +968,7 @@ class Server{ return $this->operators; } - public function reloadWhitelist(){ + public function reloadWhitelist() : void{ $this->whitelist->reload(); } @@ -1533,7 +1533,7 @@ class Server{ /** * @param int $type */ - public function enablePlugins(int $type){ + public function enablePlugins(int $type) : void{ foreach($this->pluginManager->getPlugins() as $plugin){ if(!$plugin->isEnabled() and $plugin->getDescription()->getOrder() === $type){ $this->pluginManager->enablePlugin($plugin); @@ -1576,7 +1576,7 @@ class Server{ return false; } - public function reload(){ + public function reload() : void{ $this->logger->info("Saving worlds..."); foreach($this->levelManager->getLevels() as $level){ @@ -1616,11 +1616,11 @@ class Server{ /** * Shuts the server down correctly */ - public function shutdown(){ + public function shutdown() : void{ $this->isRunning = false; } - public function forceShutdown(){ + public function forceShutdown() : void{ if($this->hasStopped){ return; } @@ -1703,7 +1703,7 @@ class Server{ /** * Starts the PocketMine-MP server and starts processing ticks and packets */ - private function start(){ + private function start() : void{ if($this->getConfigBool("enable-query", true)){ $this->queryHandler = new QueryHandler(); } @@ -1741,7 +1741,7 @@ class Server{ * @param \Throwable $e * @param array|null $trace */ - public function exceptionHandler(\Throwable $e, $trace = null){ + public function exceptionHandler(\Throwable $e, $trace = null) : void{ global $lastError; if($trace === null){ @@ -1772,7 +1772,7 @@ class Server{ $this->crashDump(); } - public function crashDump(){ + public function crashDump() : void{ if(!$this->isRunning){ return; } @@ -1860,7 +1860,7 @@ class Server{ return $this->tickSleeper; } - private function tickProcessor(){ + private function tickProcessor() : void{ $this->nextTick = microtime(true); while($this->isRunning){ @@ -1871,7 +1871,7 @@ class Server{ } } - public function onPlayerLogin(Player $player){ + public function onPlayerLogin(Player $player) : void{ if($this->sendUsageTicker > 0){ $this->uniquePlayers[$player->getRawUniqueId()] = $player->getRawUniqueId(); } @@ -1879,28 +1879,28 @@ class Server{ $this->loggedInPlayers[$player->getRawUniqueId()] = $player; } - public function onPlayerLogout(Player $player){ + public function onPlayerLogout(Player $player) : void{ unset($this->loggedInPlayers[$player->getRawUniqueId()]); } - public function addPlayer(Player $player){ + public function addPlayer(Player $player) : void{ $this->players[spl_object_id($player)] = $player; } /** * @param Player $player */ - public function removePlayer(Player $player){ + public function removePlayer(Player $player) : void{ unset($this->players[spl_object_id($player)]); } - public function addOnlinePlayer(Player $player){ + public function addOnlinePlayer(Player $player) : void{ $this->updatePlayerListData($player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkin(), $player->getXuid()); $this->playerList[$player->getRawUniqueId()] = $player; } - public function removeOnlinePlayer(Player $player){ + public function removeOnlinePlayer(Player $player) : void{ if(isset($this->playerList[$player->getRawUniqueId()])){ unset($this->playerList[$player->getRawUniqueId()]); @@ -1916,7 +1916,7 @@ class Server{ * @param string $xboxUserId * @param Player[]|null $players */ - public function updatePlayerListData(UUID $uuid, int $entityId, string $name, Skin $skin, string $xboxUserId = "", ?array $players = null){ + public function updatePlayerListData(UUID $uuid, int $entityId, string $name, Skin $skin, string $xboxUserId = "", ?array $players = null) : void{ $pk = new PlayerListPacket(); $pk->type = PlayerListPacket::TYPE_ADD; @@ -1929,7 +1929,7 @@ class Server{ * @param UUID $uuid * @param Player[]|null $players */ - public function removePlayerListData(UUID $uuid, ?array $players = null){ + public function removePlayerListData(UUID $uuid, ?array $players = null) : void{ $pk = new PlayerListPacket(); $pk->type = PlayerListPacket::TYPE_REMOVE; $pk->entries[] = PlayerListEntry::createRemovalEntry($uuid); @@ -1939,7 +1939,7 @@ class Server{ /** * @param Player $p */ - public function sendFullPlayerListData(Player $p){ + public function sendFullPlayerListData(Player $p) : void{ $pk = new PlayerListPacket(); $pk->type = PlayerListPacket::TYPE_ADD; foreach($this->playerList as $player){ @@ -1949,7 +1949,7 @@ class Server{ $p->sendDataPacket($pk); } - public function sendUsage($type = SendUsageTask::TYPE_STATUS){ + public function sendUsage(int $type = SendUsageTask::TYPE_STATUS) : void{ if((bool) $this->getProperty("anonymous-statistics.enabled", true)){ $this->asyncPool->submitTask(new SendUsageTask($this, $type, $this->uniquePlayers)); } @@ -1985,7 +1985,7 @@ class Server{ return $this->memoryManager; } - private function titleTick(){ + private function titleTick() : void{ Timings::$titleTickTimer->startTiming(); $d = Utils::getRealMemoryUsage(); @@ -2016,7 +2016,7 @@ class Server{ * * TODO: move this to Network */ - public function handlePacket(AdvancedNetworkInterface $interface, string $address, int $port, string $payload){ + public function handlePacket(AdvancedNetworkInterface $interface, string $address, int $port, string $payload) : void{ if($this->queryHandler === null or !$this->queryHandler->handle($interface, $address, $port, $payload)){ $this->logger->debug("Unhandled raw packet from $address $port: " . bin2hex($payload)); } diff --git a/src/pocketmine/Thread.php b/src/pocketmine/Thread.php index a51ba123f9..ad20748813 100644 --- a/src/pocketmine/Thread.php +++ b/src/pocketmine/Thread.php @@ -39,7 +39,7 @@ abstract class Thread extends \Thread{ return $this->classLoader; } - public function setClassLoader(?\ClassLoader $loader = null){ + public function setClassLoader(?\ClassLoader $loader = null) : void{ $this->composerAutoloaderPath = \pocketmine\COMPOSER_AUTOLOADER_PATH; if($loader === null){ @@ -55,7 +55,7 @@ abstract class Thread extends \Thread{ * If you do not do this, you will not be able to use new classes that were not loaded when the thread was started * (unless you are using a custom autoloader). */ - public function registerClassLoader(){ + public function registerClassLoader() : void{ if($this->composerAutoloaderPath !== null){ require $this->composerAutoloaderPath; } @@ -64,7 +64,7 @@ abstract class Thread extends \Thread{ } } - public function start(?int $options = \PTHREADS_INHERIT_ALL){ + public function start(?int $options = \PTHREADS_INHERIT_ALL) : bool{ ThreadManager::getInstance()->add($this); if($this->getClassLoader() === null){ @@ -76,7 +76,7 @@ abstract class Thread extends \Thread{ /** * Stops the thread using the best way possible. Try to stop it yourself before calling this. */ - public function quit(){ + public function quit() : void{ $this->isKilled = true; if(!$this->isJoined()){ diff --git a/src/pocketmine/ThreadManager.php b/src/pocketmine/ThreadManager.php index a4bbe2a57a..027770920a 100644 --- a/src/pocketmine/ThreadManager.php +++ b/src/pocketmine/ThreadManager.php @@ -30,21 +30,21 @@ class ThreadManager extends \Volatile{ /** @var ThreadManager */ private static $instance = null; - public static function init(){ + public static function init() : void{ self::$instance = new ThreadManager(); } /** * @return ThreadManager */ - public static function getInstance(){ + public static function getInstance() : ThreadManager{ return self::$instance; } /** * @param Worker|Thread $thread */ - public function add($thread){ + public function add($thread) : void{ if($thread instanceof Thread or $thread instanceof Worker){ $this->{spl_object_id($thread)} = $thread; } @@ -53,7 +53,7 @@ class ThreadManager extends \Volatile{ /** * @param Worker|Thread $thread */ - public function remove($thread){ + public function remove($thread) : void{ if($thread instanceof Thread or $thread instanceof Worker){ unset($this->{spl_object_id($thread)}); } diff --git a/src/pocketmine/Worker.php b/src/pocketmine/Worker.php index ee62a05400..e6859f41b2 100644 --- a/src/pocketmine/Worker.php +++ b/src/pocketmine/Worker.php @@ -39,7 +39,7 @@ abstract class Worker extends \Worker{ return $this->classLoader; } - public function setClassLoader(?\ClassLoader $loader = null){ + public function setClassLoader(?\ClassLoader $loader = null) : void{ $this->composerAutoloaderPath = \pocketmine\COMPOSER_AUTOLOADER_PATH; if($loader === null){ @@ -55,7 +55,7 @@ abstract class Worker extends \Worker{ * If you do not do this, you will not be able to use new classes that were not loaded when the thread was started * (unless you are using a custom autoloader). */ - public function registerClassLoader(){ + public function registerClassLoader() : void{ if($this->composerAutoloaderPath !== null){ require $this->composerAutoloaderPath; } @@ -64,7 +64,7 @@ abstract class Worker extends \Worker{ } } - public function start(?int $options = \PTHREADS_INHERIT_ALL){ + public function start(?int $options = \PTHREADS_INHERIT_ALL) : bool{ ThreadManager::getInstance()->add($this); if($this->getClassLoader() === null){ @@ -76,7 +76,7 @@ abstract class Worker extends \Worker{ /** * Stops the thread using the best way possible. Try to stop it yourself before calling this. */ - public function quit(){ + public function quit() : void{ $this->isKilled = true; if($this->isRunning()){ diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index d44f5ca2f2..a82e3ecdbb 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -109,7 +109,7 @@ class Bed extends Transparent{ return $this->occupied; } - public function setOccupied(bool $occupied = true){ + public function setOccupied(bool $occupied = true) : void{ $this->occupied = $occupied; $this->level->setBlock($this, $this, false); diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 8d25ed1927..6056ec5ffe 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -800,7 +800,7 @@ class Block extends Position implements BlockIds, Metadatable{ return $currentHit; } - public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue){ + public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue) : void{ if($this->isValid()){ $this->level->getBlockMetadata()->setMetadata($this, $metadataKey, $newMetadataValue); } @@ -822,7 +822,7 @@ class Block extends Position implements BlockIds, Metadatable{ return false; } - public function removeMetadata(string $metadataKey, Plugin $owningPlugin){ + public function removeMetadata(string $metadataKey, Plugin $owningPlugin) : void{ if($this->isValid()){ $this->level->getBlockMetadata()->removeMetadata($this, $metadataKey, $owningPlugin); } diff --git a/src/pocketmine/block/Lava.php b/src/pocketmine/block/Lava.php index fb4d4f5876..06a534ce62 100644 --- a/src/pocketmine/block/Lava.php +++ b/src/pocketmine/block/Lava.php @@ -52,7 +52,7 @@ class Lava extends Liquid{ return 2; //TODO: this is 1 in the nether } - protected function checkForHarden(){ + protected function checkForHarden() : void{ $colliding = null; foreach(Facing::ALL as $side){ if($side === Facing::DOWN){ diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index cb98b7ca83..e9b17e6e43 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -471,7 +471,7 @@ abstract class Liquid extends Transparent{ return ($decay >= 0 && $blockDecay >= $decay) ? $decay : $blockDecay; } - protected function checkForHarden(){ + protected function checkForHarden() : void{ } diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index 4d499da071..d56d7b74bf 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -66,7 +66,7 @@ class TNT extends Solid{ } } - public function ignite(int $fuse = 80){ + public function ignite(int $fuse = 80) : void{ $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR)); $mot = (new Random())->nextSignedFloat() * M_PI * 2; diff --git a/src/pocketmine/command/Command.php b/src/pocketmine/command/Command.php index 02ab7989ae..9874efa02d 100644 --- a/src/pocketmine/command/Command.php +++ b/src/pocketmine/command/Command.php @@ -107,7 +107,7 @@ abstract class Command{ /** * @return string|null */ - public function getPermission(){ + public function getPermission() : ?string{ return $this->permission; } @@ -115,7 +115,7 @@ abstract class Command{ /** * @param string|null $permission */ - public function setPermission(?string $permission){ + public function setPermission(?string $permission) : void{ $this->permission = $permission; } @@ -260,7 +260,7 @@ abstract class Command{ /** * @param string[] $aliases */ - public function setAliases(array $aliases){ + public function setAliases(array $aliases) : void{ $this->aliases = $aliases; if(!$this->isRegistered()){ $this->activeAliases = $aliases; @@ -270,21 +270,21 @@ abstract class Command{ /** * @param string $description */ - public function setDescription(string $description){ + public function setDescription(string $description) : void{ $this->description = $description; } /** * @param string $permissionMessage */ - public function setPermissionMessage(string $permissionMessage){ + public function setPermissionMessage(string $permissionMessage) : void{ $this->permissionMessage = $permissionMessage; } /** * @param string $usage */ - public function setUsage(string $usage){ + public function setUsage(string $usage) : void{ $this->usageMessage = $usage; } @@ -293,7 +293,7 @@ abstract class Command{ * @param TextContainer|string $message * @param bool $sendToSource */ - public static function broadcastCommandMessage(CommandSender $source, $message, bool $sendToSource = true){ + public static function broadcastCommandMessage(CommandSender $source, $message, bool $sendToSource = true) : void{ if($message instanceof TextContainer){ $m = clone $message; $result = "[" . $source->getName() . ": " . ($source->getServer()->getLanguage()->get($m->getText()) !== $m->getText() ? "%" : "") . $m->getText() . "]"; diff --git a/src/pocketmine/command/CommandMap.php b/src/pocketmine/command/CommandMap.php index 9583b4e83a..c8dda90193 100644 --- a/src/pocketmine/command/CommandMap.php +++ b/src/pocketmine/command/CommandMap.php @@ -30,7 +30,7 @@ interface CommandMap{ * @param string $fallbackPrefix * @param Command[] $commands */ - public function registerAll(string $fallbackPrefix, array $commands); + public function registerAll(string $fallbackPrefix, array $commands) : void; /** * @param string $fallbackPrefix @@ -52,14 +52,14 @@ interface CommandMap{ /** * @return void */ - public function clearCommands(); + public function clearCommands() : void; /** * @param string $name * * @return Command|null */ - public function getCommand(string $name); + public function getCommand(string $name) : ?Command; } diff --git a/src/pocketmine/command/CommandReader.php b/src/pocketmine/command/CommandReader.php index dfa66ba283..1f18dd0e97 100644 --- a/src/pocketmine/command/CommandReader.php +++ b/src/pocketmine/command/CommandReader.php @@ -71,11 +71,11 @@ class CommandReader extends Thread{ } } - public function shutdown(){ + public function shutdown() : void{ $this->shutdown = true; } - public function quit(){ + public function quit() : void{ $wait = microtime(true) + 0.5; while(microtime(true) < $wait){ if($this->isRunning()){ @@ -94,7 +94,7 @@ class CommandReader extends Thread{ throw new \ThreadException($message); } - private function initStdin(){ + private function initStdin() : void{ if(is_resource(self::$stdin)){ fclose(self::$stdin); } @@ -176,7 +176,7 @@ class CommandReader extends Thread{ * * @return string|null */ - public function getLine(){ + public function getLine() : ?string{ if($this->buffer->count() !== 0){ return (string) $this->buffer->shift(); } @@ -184,7 +184,7 @@ class CommandReader extends Thread{ return null; } - public function run(){ + public function run() : void{ $this->registerClassLoader(); if($this->type !== self::TYPE_READLINE){ diff --git a/src/pocketmine/command/CommandSender.php b/src/pocketmine/command/CommandSender.php index 027a1a5cfc..ab707ffcad 100644 --- a/src/pocketmine/command/CommandSender.php +++ b/src/pocketmine/command/CommandSender.php @@ -32,12 +32,12 @@ interface CommandSender extends Permissible{ /** * @param TextContainer|string $message */ - public function sendMessage($message); + public function sendMessage($message) : void; /** * @return Server */ - public function getServer(); + public function getServer() : Server; /** * @return string @@ -57,5 +57,5 @@ interface CommandSender extends Permissible{ * * @param int|null $height */ - public function setScreenLineHeight(?int $height); + public function setScreenLineHeight(?int $height) : void; } diff --git a/src/pocketmine/command/ConsoleCommandSender.php b/src/pocketmine/command/ConsoleCommandSender.php index 8db5aa74db..9f42a99f94 100644 --- a/src/pocketmine/command/ConsoleCommandSender.php +++ b/src/pocketmine/command/ConsoleCommandSender.php @@ -80,11 +80,11 @@ class ConsoleCommandSender implements CommandSender{ * * @return void */ - public function removeAttachment(PermissionAttachment $attachment){ + public function removeAttachment(PermissionAttachment $attachment) : void{ $this->perm->removeAttachment($attachment); } - public function recalculatePermissions(){ + public function recalculatePermissions() : void{ $this->perm->recalculatePermissions(); } @@ -98,14 +98,14 @@ class ConsoleCommandSender implements CommandSender{ /** * @return Server */ - public function getServer(){ + public function getServer() : Server{ return Server::getInstance(); } /** * @param TextContainer|string $message */ - public function sendMessage($message){ + public function sendMessage($message) : void{ if($message instanceof TextContainer){ $message = $this->getServer()->getLanguage()->translate($message); }else{ @@ -134,7 +134,7 @@ class ConsoleCommandSender implements CommandSender{ /** * @param bool $value */ - public function setOp(bool $value){ + public function setOp(bool $value) : void{ } @@ -142,7 +142,7 @@ class ConsoleCommandSender implements CommandSender{ return $this->lineHeight ?? PHP_INT_MAX; } - public function setScreenLineHeight(?int $height){ + public function setScreenLineHeight(?int $height) : void{ if($height !== null and $height < 1){ throw new \InvalidArgumentException("Line height must be at least 1"); } diff --git a/src/pocketmine/command/SimpleCommandMap.php b/src/pocketmine/command/SimpleCommandMap.php index 523089d658..6b3419e8d1 100644 --- a/src/pocketmine/command/SimpleCommandMap.php +++ b/src/pocketmine/command/SimpleCommandMap.php @@ -92,7 +92,7 @@ class SimpleCommandMap implements CommandMap{ $this->setDefaultCommands(); } - private function setDefaultCommands(){ + private function setDefaultCommands() : void{ $this->registerAll("pocketmine", [ new BanCommand("ban"), new BanIpCommand("ban-ip"), @@ -138,7 +138,7 @@ class SimpleCommandMap implements CommandMap{ } - public function registerAll(string $fallbackPrefix, array $commands){ + public function registerAll(string $fallbackPrefix, array $commands) : void{ foreach($commands as $command){ $this->register($fallbackPrefix, $command); } @@ -231,7 +231,7 @@ class SimpleCommandMap implements CommandMap{ * * @return Command|null */ - public function matchCommand(string &$commandName, array &$args){ + public function matchCommand(string &$commandName, array &$args) : ?Command{ $count = min(count($args), 255); for($i = 0; $i < $count; ++$i){ @@ -277,7 +277,7 @@ class SimpleCommandMap implements CommandMap{ return true; } - public function clearCommands(){ + public function clearCommands() : void{ foreach($this->knownCommands as $command){ $command->unregister($this); } @@ -285,7 +285,7 @@ class SimpleCommandMap implements CommandMap{ $this->setDefaultCommands(); } - public function getCommand(string $name){ + public function getCommand(string $name) : ?Command{ return $this->knownCommands[$name] ?? null; } @@ -300,7 +300,7 @@ class SimpleCommandMap implements CommandMap{ /** * @return void */ - public function registerServerAliases(){ + public function registerServerAliases() : void{ $values = $this->server->getCommandAliases(); foreach($values as $alias => $commandStrings){ diff --git a/src/pocketmine/command/defaults/BanIpCommand.php b/src/pocketmine/command/defaults/BanIpCommand.php index 6f491a240a..c27b652219 100644 --- a/src/pocketmine/command/defaults/BanIpCommand.php +++ b/src/pocketmine/command/defaults/BanIpCommand.php @@ -76,7 +76,7 @@ class BanIpCommand extends VanillaCommand{ return true; } - private function processIPBan(string $ip, CommandSender $sender, string $reason){ + private function processIPBan(string $ip, CommandSender $sender, string $reason) : void{ $sender->getServer()->getIPBans()->addBan($ip, $reason, null, $sender->getName()); foreach($sender->getServer()->getOnlinePlayers() as $player){ diff --git a/src/pocketmine/command/defaults/ParticleCommand.php b/src/pocketmine/command/defaults/ParticleCommand.php index c9ea96da11..9b4d57b7e5 100644 --- a/src/pocketmine/command/defaults/ParticleCommand.php +++ b/src/pocketmine/command/defaults/ParticleCommand.php @@ -141,7 +141,7 @@ class ParticleCommand extends VanillaCommand{ * * @return Particle|null */ - private function getParticle(string $name, ?int $data = null){ + private function getParticle(string $name, ?int $data = null) : ?Particle{ switch($name){ case "explode": return new ExplodeParticle(); diff --git a/src/pocketmine/command/defaults/VersionCommand.php b/src/pocketmine/command/defaults/VersionCommand.php index b6140939bd..e132671bd1 100644 --- a/src/pocketmine/command/defaults/VersionCommand.php +++ b/src/pocketmine/command/defaults/VersionCommand.php @@ -84,7 +84,7 @@ class VersionCommand extends VanillaCommand{ return true; } - private function describeToSender(Plugin $plugin, CommandSender $sender){ + private function describeToSender(Plugin $plugin, CommandSender $sender) : void{ $desc = $plugin->getDescription(); $sender->sendMessage(TextFormat::DARK_GREEN . $desc->getName() . TextFormat::WHITE . " version " . TextFormat::DARK_GREEN . $desc->getVersion()); diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 79722e4e5c..d5d7fae7e6 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -1982,7 +1982,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->close(); } - public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue){ + public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue) : void{ $this->server->getEntityMetadata()->setMetadata($this, $metadataKey, $newMetadataValue); } @@ -1994,7 +1994,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ return $this->server->getEntityMetadata()->hasMetadata($this, $metadataKey); } - public function removeMetadata(string $metadataKey, Plugin $owningPlugin){ + public function removeMetadata(string $metadataKey, Plugin $owningPlugin) : void{ $this->server->getEntityMetadata()->removeMetadata($this, $metadataKey, $owningPlugin); } diff --git a/src/pocketmine/entity/Explosive.php b/src/pocketmine/entity/Explosive.php index 77099ef586..347c68a49a 100644 --- a/src/pocketmine/entity/Explosive.php +++ b/src/pocketmine/entity/Explosive.php @@ -26,5 +26,5 @@ namespace pocketmine\entity; interface Explosive{ - public function explode(); + public function explode() : void; } diff --git a/src/pocketmine/event/Cancellable.php b/src/pocketmine/event/Cancellable.php index f4017a199f..63e4a3f1e5 100644 --- a/src/pocketmine/event/Cancellable.php +++ b/src/pocketmine/event/Cancellable.php @@ -36,5 +36,5 @@ interface Cancellable{ /** * @param bool $value */ - public function setCancelled(bool $value = true); + public function setCancelled(bool $value = true) : void; } diff --git a/src/pocketmine/event/player/PlayerCreationEvent.php b/src/pocketmine/event/player/PlayerCreationEvent.php index 62dfff2538..a1d8b2a58d 100644 --- a/src/pocketmine/event/player/PlayerCreationEvent.php +++ b/src/pocketmine/event/player/PlayerCreationEvent.php @@ -88,7 +88,7 @@ class PlayerCreationEvent extends Event{ /** * @param Player::class $class */ - public function setBaseClass($class){ + public function setBaseClass($class) : void{ if(!is_a($class, $this->baseClass, true)){ throw new \RuntimeException("Base class $class must extend " . $this->baseClass); } @@ -106,7 +106,7 @@ class PlayerCreationEvent extends Event{ /** * @param Player::class $class */ - public function setPlayerClass($class){ + public function setPlayerClass($class) : void{ if(!is_a($class, $this->baseClass, true)){ throw new \RuntimeException("Class $class must extend " . $this->baseClass); } diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index c0c8c1cf33..ebe147bddd 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -72,7 +72,7 @@ abstract class BaseInventory implements Inventory{ * * @param int $size */ - public function setSize(int $size){ + public function setSize(int $size) : void{ $this->slots->setSize($size); } diff --git a/src/pocketmine/inventory/CraftingGrid.php b/src/pocketmine/inventory/CraftingGrid.php index 1c2ca40e3d..3da867cd5e 100644 --- a/src/pocketmine/inventory/CraftingGrid.php +++ b/src/pocketmine/inventory/CraftingGrid.php @@ -61,7 +61,7 @@ class CraftingGrid extends BaseInventory{ return $this->getGridWidth() ** 2; } - public function setSize(int $size){ + public function setSize(int $size) : void{ throw new \BadMethodCallException("Cannot change the size of a crafting grid"); } diff --git a/src/pocketmine/inventory/CraftingManager.php b/src/pocketmine/inventory/CraftingManager.php index b35f3a9e51..eb02dfd3f3 100644 --- a/src/pocketmine/inventory/CraftingManager.php +++ b/src/pocketmine/inventory/CraftingManager.php @@ -137,7 +137,7 @@ class CraftingManager{ * * @return int */ - public static function sort(Item $i1, Item $i2){ + public static function sort(Item $i1, Item $i2) : int{ //Use spaceship operator to compare each property, then try the next one if they are equivalent. ($retval = $i1->getId() <=> $i2->getId()) === 0 && ($retval = $i1->getMeta() <=> $i2->getMeta()) === 0 && ($retval = $i1->getCount() <=> $i2->getCount()); diff --git a/src/pocketmine/inventory/EnderChestInventory.php b/src/pocketmine/inventory/EnderChestInventory.php index f3dc11f76b..d7605d837c 100644 --- a/src/pocketmine/inventory/EnderChestInventory.php +++ b/src/pocketmine/inventory/EnderChestInventory.php @@ -50,7 +50,7 @@ class EnderChestInventory extends ChestInventory{ * * @param EnderChest $enderChest */ - public function setHolderPosition(EnderChest $enderChest){ + public function setHolderPosition(EnderChest $enderChest) : void{ $this->holder->setComponents($enderChest->getFloorX(), $enderChest->getFloorY(), $enderChest->getFloorZ()); $this->holder->setLevel($enderChest->getLevel()); } diff --git a/src/pocketmine/inventory/FurnaceRecipe.php b/src/pocketmine/inventory/FurnaceRecipe.php index bcd333f8a0..038c885a1a 100644 --- a/src/pocketmine/inventory/FurnaceRecipe.php +++ b/src/pocketmine/inventory/FurnaceRecipe.php @@ -45,7 +45,7 @@ class FurnaceRecipe{ /** * @param Item $item */ - public function setInput(Item $item){ + public function setInput(Item $item) : void{ $this->ingredient = clone $item; } diff --git a/src/pocketmine/inventory/PlayerCursorInventory.php b/src/pocketmine/inventory/PlayerCursorInventory.php index 370704f8d6..4ad1a4050f 100644 --- a/src/pocketmine/inventory/PlayerCursorInventory.php +++ b/src/pocketmine/inventory/PlayerCursorInventory.php @@ -38,7 +38,7 @@ class PlayerCursorInventory extends BaseInventory{ return 1; } - public function setSize(int $size){ + public function setSize(int $size) : void{ throw new \BadMethodCallException("Cursor can only carry one item at a time"); } diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index fd566acd2e..ff355fad3b 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -61,7 +61,7 @@ class PlayerInventory extends BaseInventory{ * * @throws \InvalidArgumentException */ - private function throwIfNotHotbarSlot(int $slot){ + private function throwIfNotHotbarSlot(int $slot) : void{ if(!$this->isHotbarSlot($slot)){ throw new \InvalidArgumentException("$slot is not a valid hotbar slot index (expected 0 - " . ($this->getHotbarSize() - 1) . ")"); } @@ -98,7 +98,7 @@ class PlayerInventory extends BaseInventory{ * * @throws \InvalidArgumentException if the hotbar slot is out of range */ - public function setHeldItemIndex(int $hotbarSlot, bool $send = true){ + public function setHeldItemIndex(int $hotbarSlot, bool $send = true) : void{ $this->throwIfNotHotbarSlot($hotbarSlot); $this->itemInHandIndex = $hotbarSlot; @@ -140,7 +140,7 @@ class PlayerInventory extends BaseInventory{ * * @param Player|Player[] $target */ - public function sendHeldItem($target){ + public function sendHeldItem($target) : void{ $item = $this->getItemInHand(); $pk = new MobEquipmentPacket(); @@ -170,7 +170,7 @@ class PlayerInventory extends BaseInventory{ return 9; } - public function sendCreativeContents(){ + public function sendCreativeContents() : void{ //TODO: this mess shouldn't be in here $holder = $this->getHolder(); if(!($holder instanceof Player)){ diff --git a/src/pocketmine/item/ChorusFruit.php b/src/pocketmine/item/ChorusFruit.php index f542b4c52c..757fd126b1 100644 --- a/src/pocketmine/item/ChorusFruit.php +++ b/src/pocketmine/item/ChorusFruit.php @@ -49,7 +49,7 @@ class ChorusFruit extends Food{ return false; } - public function onConsume(Living $consumer){ + public function onConsume(Living $consumer) : void{ $level = $consumer->getLevel(); assert($level !== null); diff --git a/src/pocketmine/item/Consumable.php b/src/pocketmine/item/Consumable.php index eac296fc8f..b9f0c1c3c4 100644 --- a/src/pocketmine/item/Consumable.php +++ b/src/pocketmine/item/Consumable.php @@ -50,5 +50,5 @@ interface Consumable{ * * @param Living $consumer */ - public function onConsume(Living $consumer); + public function onConsume(Living $consumer) : void; } diff --git a/src/pocketmine/item/Durable.php b/src/pocketmine/item/Durable.php index 0f43bd125b..afe842d6c4 100644 --- a/src/pocketmine/item/Durable.php +++ b/src/pocketmine/item/Durable.php @@ -50,7 +50,7 @@ abstract class Durable extends Item{ * * @param bool $value */ - public function setUnbreakable(bool $value = true){ + public function setUnbreakable(bool $value = true) : void{ $this->setNamedTagEntry(new ByteTag("Unbreakable", $value ? 1 : 0)); } diff --git a/src/pocketmine/item/Food.php b/src/pocketmine/item/Food.php index b880280c9a..0483f9d5d5 100644 --- a/src/pocketmine/item/Food.php +++ b/src/pocketmine/item/Food.php @@ -41,7 +41,7 @@ abstract class Food extends Item implements FoodSource{ return []; } - public function onConsume(Living $consumer){ + public function onConsume(Living $consumer) : void{ } } diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 9e07fbc7c8..920c048c79 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -163,7 +163,7 @@ class Item implements ItemIds, \JsonSerializable{ * * @return Item|null */ - public static function getCreativeItem(int $index){ + public static function getCreativeItem(int $index) : ?Item{ return Item::$creative[$index] ?? null; } diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index d83c1e4e6b..d6ca10de5c 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -50,7 +50,7 @@ class ItemFactory{ /** @var Item|null */ private static $air = null; - public static function init(){ + public static function init() : void{ self::$list = []; //in case of re-initializing self::register(new Apple()); @@ -328,7 +328,7 @@ class ItemFactory{ * @throws \RuntimeException if something attempted to override an already-registered item without specifying the * $override parameter. */ - public static function register(Item $item, bool $override = false){ + public static function register(Item $item, bool $override = false) : void{ $id = $item->getId(); $variant = $item->getMeta(); diff --git a/src/pocketmine/item/MilkBucket.php b/src/pocketmine/item/MilkBucket.php index 628be6033f..d0851d2e9e 100644 --- a/src/pocketmine/item/MilkBucket.php +++ b/src/pocketmine/item/MilkBucket.php @@ -39,7 +39,7 @@ class MilkBucket extends Item implements Consumable{ return []; } - public function onConsume(Living $consumer){ + public function onConsume(Living $consumer) : void{ $consumer->removeAllEffects(); } } diff --git a/src/pocketmine/item/Potion.php b/src/pocketmine/item/Potion.php index 35c2b96b8e..6e7acb06d3 100644 --- a/src/pocketmine/item/Potion.php +++ b/src/pocketmine/item/Potion.php @@ -263,7 +263,7 @@ class Potion extends Item implements Consumable{ return 1; } - public function onConsume(Living $consumer){ + public function onConsume(Living $consumer) : void{ } diff --git a/src/pocketmine/lang/Language.php b/src/pocketmine/lang/Language.php index 13c1b228f5..270b7183a8 100644 --- a/src/pocketmine/lang/Language.php +++ b/src/pocketmine/lang/Language.php @@ -160,7 +160,7 @@ class Language{ * * @return string|null */ - protected function internalGet(string $id){ + protected function internalGet(string $id) : ?string{ return $this->lang[$id] ?? $this->fallbackLang[$id] ?? null; } diff --git a/src/pocketmine/lang/TextContainer.php b/src/pocketmine/lang/TextContainer.php index 99504d0aea..557fa2f5ed 100644 --- a/src/pocketmine/lang/TextContainer.php +++ b/src/pocketmine/lang/TextContainer.php @@ -38,7 +38,7 @@ class TextContainer{ /** * @param string $text */ - public function setText(string $text){ + public function setText(string $text) : void{ $this->text = $text; } diff --git a/src/pocketmine/lang/TranslationContainer.php b/src/pocketmine/lang/TranslationContainer.php index aa9bf3d016..1c4f34d21f 100644 --- a/src/pocketmine/lang/TranslationContainer.php +++ b/src/pocketmine/lang/TranslationContainer.php @@ -52,7 +52,7 @@ class TranslationContainer extends TextContainer{ * * @return string|null */ - public function getParameter(int $i){ + public function getParameter(int $i) : ?string{ return $this->params[$i] ?? null; } @@ -60,7 +60,7 @@ class TranslationContainer extends TextContainer{ * @param int $i * @param string $str */ - public function setParameter(int $i, string $str){ + public function setParameter(int $i, string $str) : void{ if($i < 0 or $i > count($this->params)){ //Intended, allow to set the last throw new \InvalidArgumentException("Invalid index $i, have " . count($this->params)); } @@ -71,7 +71,7 @@ class TranslationContainer extends TextContainer{ /** * @param string[] $params */ - public function setParameters(array $params){ + public function setParameters(array $params) : void{ $i = 0; foreach($params as $str){ $this->params[$i] = (string) $str; diff --git a/src/pocketmine/level/ChunkListener.php b/src/pocketmine/level/ChunkListener.php index ffa7127de6..74e80944ab 100644 --- a/src/pocketmine/level/ChunkListener.php +++ b/src/pocketmine/level/ChunkListener.php @@ -46,14 +46,14 @@ interface ChunkListener{ * * @param Chunk $chunk */ - public function onChunkChanged(Chunk $chunk); + public function onChunkChanged(Chunk $chunk) : void; /** * This method will be called when a registered chunk is loaded * * @param Chunk $chunk */ - public function onChunkLoaded(Chunk $chunk); + public function onChunkLoaded(Chunk $chunk) : void; /** @@ -61,7 +61,7 @@ interface ChunkListener{ * * @param Chunk $chunk */ - public function onChunkUnloaded(Chunk $chunk); + public function onChunkUnloaded(Chunk $chunk) : void; /** * This method will be called when a registered chunk is populated @@ -69,12 +69,12 @@ interface ChunkListener{ * * @param Chunk $chunk */ - public function onChunkPopulated(Chunk $chunk); + public function onChunkPopulated(Chunk $chunk) : void; /** * This method will be called when a block changes in a registered chunk * * @param Block|Vector3 $block */ - public function onBlockChanged(Vector3 $block); + public function onBlockChanged(Vector3 $block) : void; } diff --git a/src/pocketmine/level/ChunkManager.php b/src/pocketmine/level/ChunkManager.php index b53996cbc3..c814531048 100644 --- a/src/pocketmine/level/ChunkManager.php +++ b/src/pocketmine/level/ChunkManager.php @@ -70,7 +70,7 @@ interface ChunkManager{ * @param int $z * @param int $level */ - public function setBlockLightAt(int $x, int $y, int $z, int $level); + public function setBlockLightAt(int $x, int $y, int $z, int $level) : void; /** * Returns the highest amount of sky light can reach the specified coordinates. @@ -91,7 +91,7 @@ interface ChunkManager{ * @param int $z * @param int $level */ - public function setBlockSkyLightAt(int $x, int $y, int $z, int $level); + public function setBlockSkyLightAt(int $x, int $y, int $z, int $level) : void; /** * @param int $chunkX @@ -99,14 +99,14 @@ interface ChunkManager{ * * @return Chunk|null */ - public function getChunk(int $chunkX, int $chunkZ); + public function getChunk(int $chunkX, int $chunkZ) : ?Chunk; /** * @param int $chunkX * @param int $chunkZ * @param Chunk|null $chunk */ - public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk); + public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk) : void; /** * Returns the height of the world diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index effddbf695..a029c1d51e 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1639,7 +1639,7 @@ class Level implements ChunkManager, Metadatable{ * * @return ItemEntity|null */ - public function dropItem(Vector3 $source, Item $item, ?Vector3 $motion = null, int $delay = 10){ + public function dropItem(Vector3 $source, Item $item, ?Vector3 $motion = null, int $delay = 10) : ?ItemEntity{ $motion = $motion ?? new Vector3(lcg_value() * 0.2 - 0.1, 0.2, lcg_value() * 0.2 - 0.1); $itemTag = $item->nbtSerialize(); $itemTag->setName("Item"); @@ -1920,7 +1920,7 @@ class Level implements ChunkManager, Metadatable{ * * @return Entity|null */ - public function getEntity(int $entityId){ + public function getEntity(int $entityId) : ?Entity{ return $this->entities[$entityId] ?? null; } @@ -2123,7 +2123,7 @@ class Level implements ChunkManager, Metadatable{ * @param int $z * @param int $level 0-15 */ - public function setBlockSkyLightAt(int $x, int $y, int $z, int $level){ + public function setBlockSkyLightAt(int $x, int $y, int $z, int $level) : void{ $this->getChunk($x >> 4, $z >> 4, true)->setBlockSkyLight($x & 0x0f, $y, $z & 0x0f, $level & 0x0f); } @@ -2148,7 +2148,7 @@ class Level implements ChunkManager, Metadatable{ * @param int $z * @param int $level 0-15 */ - public function setBlockLightAt(int $x, int $y, int $z, int $level){ + public function setBlockLightAt(int $x, int $y, int $z, int $level) : void{ $this->getChunk($x >> 4, $z >> 4, true)->setBlockLight($x & 0x0f, $y, $z & 0x0f, $level & 0x0f); } @@ -2211,16 +2211,16 @@ class Level implements ChunkManager, Metadatable{ * Returns the chunk at the specified X/Z coordinates. If the chunk is not loaded, attempts to (synchronously!!!) * load it. * - * @param int $x - * @param int $z + * @param int $chunkX + * @param int $chunkZ * @param bool $create Whether to create an empty chunk as a placeholder if the chunk does not exist * * @return Chunk|null */ - public function getChunk(int $x, int $z, bool $create = false){ - if(isset($this->chunks[$index = Level::chunkHash($x, $z)])){ + public function getChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk{ + if(isset($this->chunks[$index = Level::chunkHash($chunkX, $chunkZ)])){ return $this->chunks[$index]; - }elseif($this->loadChunk($x, $z, $create)){ + }elseif($this->loadChunk($chunkX, $chunkZ, $create)){ return $this->chunks[$index]; } @@ -2316,7 +2316,7 @@ class Level implements ChunkManager, Metadatable{ * @param Chunk|null $chunk * @param bool $deleteEntitiesAndTiles Whether to delete entities and tiles on the old chunk, or transfer them to the new one */ - public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk, bool $deleteEntitiesAndTiles = true){ + public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk, bool $deleteEntitiesAndTiles = true) : void{ if($chunk === null){ return; } @@ -3000,7 +3000,7 @@ class Level implements ChunkManager, Metadatable{ } } - public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue){ + public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue) : void{ $this->server->getLevelMetadata()->setMetadata($this, $metadataKey, $newMetadataValue); } @@ -3012,7 +3012,7 @@ class Level implements ChunkManager, Metadatable{ return $this->server->getLevelMetadata()->hasMetadata($this, $metadataKey); } - public function removeMetadata(string $metadataKey, Plugin $owningPlugin){ + public function removeMetadata(string $metadataKey, Plugin $owningPlugin) : void{ $this->server->getLevelMetadata()->removeMetadata($this, $metadataKey, $owningPlugin); } } diff --git a/src/pocketmine/level/LevelManager.php b/src/pocketmine/level/LevelManager.php index 6ac55a4163..dd9699987f 100644 --- a/src/pocketmine/level/LevelManager.php +++ b/src/pocketmine/level/LevelManager.php @@ -342,7 +342,7 @@ class LevelManager{ * * @return Entity|null */ - public function findEntity(int $entityId){ + public function findEntity(int $entityId) : ?Entity{ foreach($this->levels as $level){ assert(!$level->isClosed()); if(($entity = $level->getEntity($entityId)) instanceof Entity){ @@ -413,7 +413,7 @@ class LevelManager{ /** * @param bool $value */ - public function setAutoSave(bool $value){ + public function setAutoSave(bool $value) : void{ $this->autoSave = $value; foreach($this->levels as $level){ $level->setAutoSave($this->autoSave); diff --git a/src/pocketmine/level/Location.php b/src/pocketmine/level/Location.php index beb129ef45..9b11d01d75 100644 --- a/src/pocketmine/level/Location.php +++ b/src/pocketmine/level/Location.php @@ -40,7 +40,7 @@ class Location extends Position{ * @param float $pitch * @param Level $level */ - public function __construct($x = 0, $y = 0, $z = 0, $yaw = 0.0, $pitch = 0.0, ?Level $level = null){ + public function __construct($x = 0, $y = 0, $z = 0, float $yaw = 0.0, float $pitch = 0.0, ?Level $level = null){ $this->yaw = $yaw; $this->pitch = $pitch; parent::__construct($x, $y, $z, $level); @@ -49,12 +49,12 @@ class Location extends Position{ /** * @param Vector3 $pos * @param Level|null $level default null - * @param float $yaw default 0.0 + * @param float $yaw default 0.0 * @param float $pitch default 0.0 * * @return Location */ - public static function fromObject(Vector3 $pos, ?Level $level = null, $yaw = 0.0, $pitch = 0.0) : Location{ + public static function fromObject(Vector3 $pos, ?Level $level = null, float $yaw = 0.0, float $pitch = 0.0){ return new Location($pos->x, $pos->y, $pos->z, $yaw, $pitch, $level ?? (($pos instanceof Position) ? $pos->level : null)); } @@ -67,11 +67,11 @@ class Location extends Position{ return new Location($this->x, $this->y, $this->z, $this->yaw, $this->pitch, $this->level); } - public function getYaw(){ + public function getYaw() : float{ return $this->yaw; } - public function getPitch(){ + public function getPitch() : float{ return $this->pitch; } diff --git a/src/pocketmine/level/SimpleChunkManager.php b/src/pocketmine/level/SimpleChunkManager.php index aa875b3717..7c3c038d17 100644 --- a/src/pocketmine/level/SimpleChunkManager.php +++ b/src/pocketmine/level/SimpleChunkManager.php @@ -67,7 +67,7 @@ class SimpleChunkManager implements ChunkManager{ return 0; } - public function setBlockLightAt(int $x, int $y, int $z, int $level){ + public function setBlockLightAt(int $x, int $y, int $z, int $level) : void{ if($chunk = $this->getChunk($x >> 4, $z >> 4)){ $chunk->setBlockLight($x & 0xf, $y, $z & 0xf, $level); } @@ -81,7 +81,7 @@ class SimpleChunkManager implements ChunkManager{ return 0; } - public function setBlockSkyLightAt(int $x, int $y, int $z, int $level){ + public function setBlockSkyLightAt(int $x, int $y, int $z, int $level) : void{ if($chunk = $this->getChunk($x >> 4, $z >> 4)){ $chunk->setBlockSkyLight($x & 0xf, $y, $z & 0xf, $level); } @@ -93,7 +93,7 @@ class SimpleChunkManager implements ChunkManager{ * * @return Chunk|null */ - public function getChunk(int $chunkX, int $chunkZ){ + public function getChunk(int $chunkX, int $chunkZ) : ?Chunk{ return $this->chunks[Level::chunkHash($chunkX, $chunkZ)] ?? null; } @@ -102,7 +102,7 @@ class SimpleChunkManager implements ChunkManager{ * @param int $chunkZ * @param Chunk|null $chunk */ - public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk){ + public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk) : void{ if($chunk === null){ unset($this->chunks[Level::chunkHash($chunkX, $chunkZ)]); return; @@ -110,7 +110,7 @@ class SimpleChunkManager implements ChunkManager{ $this->chunks[Level::chunkHash($chunkX, $chunkZ)] = $chunk; } - public function cleanChunks(){ + public function cleanChunks() : void{ $this->chunks = []; } diff --git a/src/pocketmine/level/biome/Biome.php b/src/pocketmine/level/biome/Biome.php index 4840ae3284..30b413927d 100644 --- a/src/pocketmine/level/biome/Biome.php +++ b/src/pocketmine/level/biome/Biome.php @@ -77,12 +77,12 @@ abstract class Biome{ /** @var float */ protected $temperature = 0.5; - protected static function register(int $id, Biome $biome){ + protected static function register(int $id, Biome $biome) : void{ self::$biomes[$id] = $biome; $biome->setId($id); } - public static function init(){ + public static function init() : void{ self::$biomes = new \SplFixedArray(self::MAX_BIOMES); self::register(self::OCEAN, new OceanBiome()); @@ -114,11 +114,11 @@ abstract class Biome{ return self::$biomes[$id]; } - public function clearPopulators(){ + public function clearPopulators() : void{ $this->populators = []; } - public function addPopulator(Populator $populator){ + public function addPopulator(Populator $populator) : void{ $this->populators[] = $populator; } @@ -128,7 +128,7 @@ abstract class Biome{ * @param int $chunkZ * @param Random $random */ - public function populateChunk(ChunkManager $level, int $chunkX, int $chunkZ, Random $random){ + public function populateChunk(ChunkManager $level, int $chunkX, int $chunkZ, Random $random) : void{ foreach($this->populators as $populator){ $populator->populate($level, $chunkX, $chunkZ, $random); } @@ -141,7 +141,7 @@ abstract class Biome{ return $this->populators; } - public function setId(int $id){ + public function setId(int $id) : void{ if(!$this->registered){ $this->registered = true; $this->id = $id; @@ -162,7 +162,7 @@ abstract class Biome{ return $this->maxElevation; } - public function setElevation(int $min, int $max){ + public function setElevation(int $min, int $max) : void{ $this->minElevation = $min; $this->maxElevation = $max; } @@ -177,7 +177,7 @@ abstract class Biome{ /** * @param Block[] $covers */ - public function setGroundCover(array $covers){ + public function setGroundCover(array $covers) : void{ $this->groundCover = $covers; } diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index 9939cc59d6..948516e945 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -152,14 +152,14 @@ class Chunk{ return $this->z; } - public function setX(int $x){ + public function setX(int $x) : void{ $this->x = $x; } /** * @param int $z */ - public function setZ(int $z){ + public function setZ(int $z) : void{ $this->z = $z; } @@ -251,7 +251,7 @@ class Chunk{ * @param int $z 0-15 * @param int $level 0-15 */ - public function setBlockSkyLight(int $x, int $y, int $z, int $level){ + public function setBlockSkyLight(int $x, int $y, int $z, int $level) : void{ if($this->getSubChunk($y >> 4, true)->setBlockSkyLight($x, $y & 0x0f, $z, $level)){ $this->hasChanged = true; } @@ -260,7 +260,7 @@ class Chunk{ /** * @param int $level */ - public function setAllBlockSkyLight(int $level){ + public function setAllBlockSkyLight(int $level) : void{ $char = chr(($level & 0x0f) | ($level << 4)); $data = str_repeat($char, 2048); for($y = $this->getHighestSubChunkIndex(); $y >= 0; --$y){ @@ -289,7 +289,7 @@ class Chunk{ * @param int $z 0-15 * @param int $level 0-15 */ - public function setBlockLight(int $x, int $y, int $z, int $level){ + public function setBlockLight(int $x, int $y, int $z, int $level) : void{ if($this->getSubChunk($y >> 4, true)->setBlockLight($x, $y & 0x0f, $z, $level)){ $this->hasChanged = true; } @@ -298,7 +298,7 @@ class Chunk{ /** * @param int $level */ - public function setAllBlockLight(int $level){ + public function setAllBlockLight(int $level) : void{ $char = chr(($level & 0x0f) | ($level << 4)); $data = str_repeat($char, 2048); for($y = $this->getHighestSubChunkIndex(); $y >= 0; --$y){ @@ -353,14 +353,14 @@ class Chunk{ * @param int $z 0-15 * @param int $value */ - public function setHeightMap(int $x, int $z, int $value){ + public function setHeightMap(int $x, int $z, int $value) : void{ $this->heightMap[($z << 4) | $x] = $value; } /** * Recalculates the heightmap for the whole chunk. */ - public function recalculateHeightMap(){ + public function recalculateHeightMap() : void{ for($z = 0; $z < 16; ++$z){ for($x = 0; $x < 16; ++$x){ $this->recalculateHeightMapColumn($x, $z); @@ -395,7 +395,7 @@ class Chunk{ * * TODO: fast adjacent light spread */ - public function populateSkyLight(){ + public function populateSkyLight() : void{ $maxY = $this->getMaxY(); $this->setAllBlockSkyLight(0); @@ -441,7 +441,7 @@ class Chunk{ * @param int $z 0-15 * @param int $biomeId 0-255 */ - public function setBiomeId(int $x, int $z, int $biomeId){ + public function setBiomeId(int $x, int $z, int $biomeId) : void{ $this->hasChanged = true; $this->biomeIds{($z << 4) | $x} = chr($biomeId & 0xff); } @@ -456,7 +456,7 @@ class Chunk{ /** * @param bool $value */ - public function setLightPopulated(bool $value = true){ + public function setLightPopulated(bool $value = true) : void{ $this->lightPopulated = $value; } @@ -470,7 +470,7 @@ class Chunk{ /** * @param bool $value */ - public function setPopulated(bool $value = true){ + public function setPopulated(bool $value = true) : void{ $this->terrainPopulated = $value; } @@ -484,14 +484,14 @@ class Chunk{ /** * @param bool $value */ - public function setGenerated(bool $value = true){ + public function setGenerated(bool $value = true) : void{ $this->terrainGenerated = $value; } /** * @param Entity $entity */ - public function addEntity(Entity $entity){ + public function addEntity(Entity $entity) : void{ if($entity->isClosed()){ throw new \InvalidArgumentException("Attempted to add a garbage closed Entity to a chunk"); } @@ -504,7 +504,7 @@ class Chunk{ /** * @param Entity $entity */ - public function removeEntity(Entity $entity){ + public function removeEntity(Entity $entity) : void{ unset($this->entities[$entity->getId()]); if(!($entity instanceof Player) and $this->isInit){ $this->hasChanged = true; @@ -514,7 +514,7 @@ class Chunk{ /** * @param Tile $tile */ - public function addTile(Tile $tile){ + public function addTile(Tile $tile) : void{ if($tile->isClosed()){ throw new \InvalidArgumentException("Attempted to add a garbage closed Tile to a chunk"); } @@ -531,7 +531,7 @@ class Chunk{ /** * @param Tile $tile */ - public function removeTile(Tile $tile){ + public function removeTile(Tile $tile) : void{ unset($this->tiles[Chunk::blockHash($tile->x, $tile->y, $tile->z)]); if($this->isInit){ $this->hasChanged = true; @@ -570,7 +570,7 @@ class Chunk{ * * @return Tile|null */ - public function getTile(int $x, int $y, int $z){ + public function getTile(int $x, int $y, int $z) : ?Tile{ return $this->tiles[Chunk::blockHash($x, $y, $z)] ?? null; } @@ -595,7 +595,7 @@ class Chunk{ * * @param Level $level */ - public function initChunk(Level $level){ + public function initChunk(Level $level) : void{ if(!$this->isInit){ $changed = false; if($this->NBTentities !== null){ @@ -665,7 +665,7 @@ class Chunk{ /** * @param bool $value */ - public function setChanged(bool $value = true){ + public function setChanged(bool $value = true) : void{ $this->hasChanged = $value; } diff --git a/src/pocketmine/level/format/EmptySubChunk.php b/src/pocketmine/level/format/EmptySubChunk.php index 5ca3980e09..a26341c6ae 100644 --- a/src/pocketmine/level/format/EmptySubChunk.php +++ b/src/pocketmine/level/format/EmptySubChunk.php @@ -89,7 +89,7 @@ class EmptySubChunk implements SubChunkInterface{ return str_repeat("\x00", 2048); } - public function setBlockLightArray(string $data){ + public function setBlockLightArray(string $data) : void{ } @@ -97,7 +97,7 @@ class EmptySubChunk implements SubChunkInterface{ return str_repeat("\xff", 2048); } - public function setBlockSkyLightArray(string $data){ + public function setBlockSkyLightArray(string $data) : void{ } diff --git a/src/pocketmine/level/format/SubChunk.php b/src/pocketmine/level/format/SubChunk.php index 1b6ed2f201..66528434b5 100644 --- a/src/pocketmine/level/format/SubChunk.php +++ b/src/pocketmine/level/format/SubChunk.php @@ -42,7 +42,7 @@ class SubChunk implements SubChunkInterface{ protected $blockLight; protected $skyLight; - private static function assignData(&$target, string $data, int $length, string $value = "\x00"){ + private static function assignData(&$target, string $data, int $length, string $value = "\x00") : void{ if(strlen($data) !== $length){ assert($data === "", "Invalid non-zero length given, expected $length, got " . strlen($data)); $target = str_repeat($value, $length); @@ -159,7 +159,7 @@ class SubChunk implements SubChunkInterface{ return $this->skyLight; } - public function setBlockSkyLightArray(string $data){ + public function setBlockSkyLightArray(string $data) : void{ assert(strlen($data) === 2048, "Wrong length of skylight array, expecting 2048 bytes, got " . strlen($data)); $this->skyLight = $data; } @@ -169,7 +169,7 @@ class SubChunk implements SubChunkInterface{ return $this->blockLight; } - public function setBlockLightArray(string $data){ + public function setBlockLightArray(string $data) : void{ assert(strlen($data) === 2048, "Wrong length of light array, expecting 2048 bytes, got " . strlen($data)); $this->blockLight = $data; } diff --git a/src/pocketmine/level/format/SubChunkInterface.php b/src/pocketmine/level/format/SubChunkInterface.php index 5d3c718f0c..d058efd55e 100644 --- a/src/pocketmine/level/format/SubChunkInterface.php +++ b/src/pocketmine/level/format/SubChunkInterface.php @@ -134,7 +134,7 @@ interface SubChunkInterface{ /** * @param string $data */ - public function setBlockSkyLightArray(string $data); + public function setBlockSkyLightArray(string $data) : void; /** * @return string @@ -144,7 +144,7 @@ interface SubChunkInterface{ /** * @param string $data */ - public function setBlockLightArray(string $data); + public function setBlockLightArray(string $data) : void; /** * @return string diff --git a/src/pocketmine/level/format/io/LevelProviderManager.php b/src/pocketmine/level/format/io/LevelProviderManager.php index efd13f76f4..5c9b33f5d1 100644 --- a/src/pocketmine/level/format/io/LevelProviderManager.php +++ b/src/pocketmine/level/format/io/LevelProviderManager.php @@ -109,7 +109,7 @@ abstract class LevelProviderManager{ * * @return string|null */ - public static function getProviderByName(string $name){ + public static function getProviderByName(string $name) : ?string{ return self::$providers[trim(strtolower($name))] ?? null; } } diff --git a/src/pocketmine/level/light/BlockLightUpdate.php b/src/pocketmine/level/light/BlockLightUpdate.php index 0f7020f011..1538165819 100644 --- a/src/pocketmine/level/light/BlockLightUpdate.php +++ b/src/pocketmine/level/light/BlockLightUpdate.php @@ -29,7 +29,7 @@ class BlockLightUpdate extends LightUpdate{ return $this->subChunkHandler->currentSubChunk->getBlockLight($x & 0x0f, $y & 0x0f, $z & 0x0f); } - public function setLight(int $x, int $y, int $z, int $level){ + public function setLight(int $x, int $y, int $z, int $level) : void{ $this->subChunkHandler->currentSubChunk->setBlockLight($x & 0x0f, $y & 0x0f, $z & 0x0f, $level); } } diff --git a/src/pocketmine/level/light/LightUpdate.php b/src/pocketmine/level/light/LightUpdate.php index 567270a1eb..cf360acab3 100644 --- a/src/pocketmine/level/light/LightUpdate.php +++ b/src/pocketmine/level/light/LightUpdate.php @@ -59,9 +59,9 @@ abstract class LightUpdate{ abstract protected function getLight(int $x, int $y, int $z) : int; - abstract protected function setLight(int $x, int $y, int $z, int $level); + abstract protected function setLight(int $x, int $y, int $z, int $level) : void; - public function setAndUpdateLight(int $x, int $y, int $z, int $newLevel){ + public function setAndUpdateLight(int $x, int $y, int $z, int $newLevel) : void{ $this->updateNodes[Level::blockHash($x, $y, $z)] = [$x, $y, $z, $newLevel]; } @@ -84,7 +84,7 @@ abstract class LightUpdate{ } } - public function execute(){ + public function execute() : void{ $this->prepareNodes(); while(!$this->removalQueue->isEmpty()){ @@ -137,7 +137,7 @@ abstract class LightUpdate{ } } - protected function computeRemoveLight(int $x, int $y, int $z, int $oldAdjacentLevel){ + protected function computeRemoveLight(int $x, int $y, int $z, int $oldAdjacentLevel) : void{ $current = $this->getLight($x, $y, $z); if($current !== 0 and $current < $oldAdjacentLevel){ @@ -157,7 +157,7 @@ abstract class LightUpdate{ } } - protected function computeSpreadLight(int $x, int $y, int $z, int $newAdjacentLevel){ + protected function computeSpreadLight(int $x, int $y, int $z, int $newAdjacentLevel) : void{ $current = $this->getLight($x, $y, $z); $potentialLight = $newAdjacentLevel - BlockFactory::$lightFilter[$this->subChunkHandler->currentSubChunk->getFullBlock($x & 0x0f, $y & 0x0f, $z & 0x0f)]; diff --git a/src/pocketmine/level/light/SkyLightUpdate.php b/src/pocketmine/level/light/SkyLightUpdate.php index d38b997714..bc6666b691 100644 --- a/src/pocketmine/level/light/SkyLightUpdate.php +++ b/src/pocketmine/level/light/SkyLightUpdate.php @@ -29,7 +29,7 @@ class SkyLightUpdate extends LightUpdate{ return $this->subChunkHandler->currentSubChunk->getBlockSkyLight($x & 0x0f, $y & 0x0f, $z & 0x0f); } - public function setLight(int $x, int $y, int $z, int $level){ + public function setLight(int $x, int $y, int $z, int $level) : void{ $this->subChunkHandler->currentSubChunk->setBlockSkyLight($x & 0x0f, $y & 0x0f, $z & 0x0f, $level); } } diff --git a/src/pocketmine/metadata/BlockMetadataStore.php b/src/pocketmine/metadata/BlockMetadataStore.php index dd16447ba2..b8968e1d70 100644 --- a/src/pocketmine/metadata/BlockMetadataStore.php +++ b/src/pocketmine/metadata/BlockMetadataStore.php @@ -50,11 +50,11 @@ class BlockMetadataStore extends MetadataStore{ return $this->hasMetadataInternal($this->disambiguate($subject, $metadataKey)); } - public function removeMetadata(Block $subject, string $metadataKey, Plugin $owningPlugin){ + public function removeMetadata(Block $subject, string $metadataKey, Plugin $owningPlugin) : void{ $this->removeMetadataInternal($this->disambiguate($subject, $metadataKey), $owningPlugin); } - public function setMetadata(Block $subject, string $metadataKey, MetadataValue $newMetadataValue){ + public function setMetadata(Block $subject, string $metadataKey, MetadataValue $newMetadataValue) : void{ $this->setMetadataInternal($this->disambiguate($subject, $metadataKey), $newMetadataValue); } } diff --git a/src/pocketmine/metadata/EntityMetadataStore.php b/src/pocketmine/metadata/EntityMetadataStore.php index 681ecf7f24..b7d1332617 100644 --- a/src/pocketmine/metadata/EntityMetadataStore.php +++ b/src/pocketmine/metadata/EntityMetadataStore.php @@ -40,11 +40,11 @@ class EntityMetadataStore extends MetadataStore{ return $this->hasMetadataInternal($this->disambiguate($subject, $metadataKey)); } - public function removeMetadata(Entity $subject, string $metadataKey, Plugin $owningPlugin){ + public function removeMetadata(Entity $subject, string $metadataKey, Plugin $owningPlugin) : void{ $this->removeMetadataInternal($this->disambiguate($subject, $metadataKey), $owningPlugin); } - public function setMetadata(Entity $subject, string $metadataKey, MetadataValue $newMetadataValue){ + public function setMetadata(Entity $subject, string $metadataKey, MetadataValue $newMetadataValue) : void{ $this->setMetadataInternal($this->disambiguate($subject, $metadataKey), $newMetadataValue); } } diff --git a/src/pocketmine/metadata/LevelMetadataStore.php b/src/pocketmine/metadata/LevelMetadataStore.php index b31099f414..259d7fbc87 100644 --- a/src/pocketmine/metadata/LevelMetadataStore.php +++ b/src/pocketmine/metadata/LevelMetadataStore.php @@ -41,11 +41,11 @@ class LevelMetadataStore extends MetadataStore{ return $this->hasMetadataInternal($this->disambiguate($subject, $metadataKey)); } - public function removeMetadata(Level $subject, string $metadataKey, Plugin $owningPlugin){ + public function removeMetadata(Level $subject, string $metadataKey, Plugin $owningPlugin) : void{ $this->removeMetadataInternal($this->disambiguate($subject, $metadataKey), $owningPlugin); } - public function setMetadata(Level $subject, string $metadataKey, MetadataValue $newMetadataValue){ + public function setMetadata(Level $subject, string $metadataKey, MetadataValue $newMetadataValue) : void{ $this->setMetadataInternal($this->disambiguate($subject, $metadataKey), $newMetadataValue); } } diff --git a/src/pocketmine/metadata/MetadataStore.php b/src/pocketmine/metadata/MetadataStore.php index c6a9736e38..99e21a25e6 100644 --- a/src/pocketmine/metadata/MetadataStore.php +++ b/src/pocketmine/metadata/MetadataStore.php @@ -38,7 +38,7 @@ abstract class MetadataStore{ * @param string $key * @param MetadataValue $newMetadataValue */ - protected function setMetadataInternal(string $key, MetadataValue $newMetadataValue){ + protected function setMetadataInternal(string $key, MetadataValue $newMetadataValue) : void{ $owningPlugin = $newMetadataValue->getOwningPlugin(); if(!isset($this->metadataMap[$key])){ @@ -83,7 +83,7 @@ abstract class MetadataStore{ * @param string $key * @param Plugin $owningPlugin */ - protected function removeMetadataInternal(string $key, Plugin $owningPlugin){ + protected function removeMetadataInternal(string $key, Plugin $owningPlugin) : void{ if(isset($this->metadataMap[$key])){ unset($this->metadataMap[$key][$owningPlugin]); if($this->metadataMap[$key]->count() === 0){ @@ -99,7 +99,7 @@ abstract class MetadataStore{ * * @param Plugin $owningPlugin */ - public function invalidateAll(Plugin $owningPlugin){ + public function invalidateAll(Plugin $owningPlugin) : void{ /** @var MetadataValue[] $values */ foreach($this->metadataMap as $values){ if(isset($values[$owningPlugin])){ diff --git a/src/pocketmine/metadata/MetadataValue.php b/src/pocketmine/metadata/MetadataValue.php index 6d3ab6d85c..9f678df3aa 100644 --- a/src/pocketmine/metadata/MetadataValue.php +++ b/src/pocketmine/metadata/MetadataValue.php @@ -36,7 +36,7 @@ abstract class MetadataValue{ /** * @return Plugin */ - public function getOwningPlugin(){ + public function getOwningPlugin() : Plugin{ return $this->owningPlugin; } @@ -51,5 +51,5 @@ abstract class MetadataValue{ * Invalidates this metadata item, forcing it to recompute when next * accessed. */ - abstract public function invalidate(); + abstract public function invalidate() : void; } diff --git a/src/pocketmine/metadata/Metadatable.php b/src/pocketmine/metadata/Metadatable.php index 802071b03f..eadcbef734 100644 --- a/src/pocketmine/metadata/Metadatable.php +++ b/src/pocketmine/metadata/Metadatable.php @@ -33,7 +33,7 @@ interface Metadatable{ * @param string $metadataKey * @param MetadataValue $newMetadataValue */ - public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue); + public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue) : void; /** * Returns a list of previously set metadata values from the implementing @@ -62,6 +62,6 @@ interface Metadatable{ * @param string $metadataKey * @param Plugin $owningPlugin */ - public function removeMetadata(string $metadataKey, Plugin $owningPlugin); + public function removeMetadata(string $metadataKey, Plugin $owningPlugin) : void; } diff --git a/src/pocketmine/metadata/PlayerMetadataStore.php b/src/pocketmine/metadata/PlayerMetadataStore.php index 7c4fce37d9..0c2a967989 100644 --- a/src/pocketmine/metadata/PlayerMetadataStore.php +++ b/src/pocketmine/metadata/PlayerMetadataStore.php @@ -41,11 +41,11 @@ class PlayerMetadataStore extends MetadataStore{ return $this->hasMetadataInternal($this->disambiguate($subject, $metadataKey)); } - public function removeMetadata(IPlayer $subject, string $metadataKey, Plugin $owningPlugin){ + public function removeMetadata(IPlayer $subject, string $metadataKey, Plugin $owningPlugin) : void{ $this->removeMetadataInternal($this->disambiguate($subject, $metadataKey), $owningPlugin); } - public function setMetadata(IPlayer $subject, string $metadataKey, MetadataValue $newMetadataValue){ + public function setMetadata(IPlayer $subject, string $metadataKey, MetadataValue $newMetadataValue) : void{ $this->setMetadataInternal($this->disambiguate($subject, $metadataKey), $newMetadataValue); } } diff --git a/src/pocketmine/permission/BanEntry.php b/src/pocketmine/permission/BanEntry.php index cb64d7e7c9..ce34c7068d 100644 --- a/src/pocketmine/permission/BanEntry.php +++ b/src/pocketmine/permission/BanEntry.php @@ -66,7 +66,7 @@ class BanEntry{ * * @throws \InvalidArgumentException */ - public function setCreated(\DateTime $date){ + public function setCreated(\DateTime $date) : void{ self::validateDate($date); $this->creationDate = $date; } @@ -75,14 +75,14 @@ class BanEntry{ return $this->source; } - public function setSource(string $source){ + public function setSource(string $source) : void{ $this->source = $source; } /** * @return \DateTime|null */ - public function getExpires(){ + public function getExpires() : ?\DateTime{ return $this->expirationDate; } @@ -90,7 +90,7 @@ class BanEntry{ * @param \DateTime|null $date * @throws \InvalidArgumentException */ - public function setExpires(?\DateTime $date){ + public function setExpires(?\DateTime $date) : void{ if($date !== null){ self::validateDate($date); } @@ -108,7 +108,7 @@ class BanEntry{ return $this->reason; } - public function setReason(string $reason){ + public function setReason(string $reason) : void{ $this->reason = $reason; } diff --git a/src/pocketmine/permission/BanList.php b/src/pocketmine/permission/BanList.php index 82493e1bf2..cc0b038c51 100644 --- a/src/pocketmine/permission/BanList.php +++ b/src/pocketmine/permission/BanList.php @@ -62,7 +62,7 @@ class BanList{ /** * @param bool $flag */ - public function setEnabled(bool $flag){ + public function setEnabled(bool $flag) : void{ $this->enabled = $flag; } @@ -105,7 +105,7 @@ class BanList{ /** * @param BanEntry $entry */ - public function add(BanEntry $entry){ + public function add(BanEntry $entry) : void{ $this->list[$entry->getName()] = $entry; $this->save(); } @@ -133,7 +133,7 @@ class BanList{ /** * @param string $name */ - public function remove(string $name){ + public function remove(string $name) : void{ $name = strtolower($name); if(isset($this->list[$name])){ unset($this->list[$name]); @@ -141,7 +141,7 @@ class BanList{ } } - public function removeExpired(){ + public function removeExpired() : void{ foreach($this->list as $name => $entry){ if($entry->hasExpired()){ unset($this->list[$name]); @@ -149,7 +149,7 @@ class BanList{ } } - public function load(){ + public function load() : void{ $this->list = []; $fp = @fopen($this->file, "r"); if(is_resource($fp)){ @@ -176,7 +176,7 @@ class BanList{ /** * @param bool $writeHeader */ - public function save(bool $writeHeader = true){ + public function save(bool $writeHeader = true) : void{ $this->removeExpired(); $fp = @fopen($this->file, "w"); if(is_resource($fp)){ diff --git a/src/pocketmine/permission/DefaultPermissions.php b/src/pocketmine/permission/DefaultPermissions.php index 46fa31d76a..2bf4e8a76c 100644 --- a/src/pocketmine/permission/DefaultPermissions.php +++ b/src/pocketmine/permission/DefaultPermissions.php @@ -45,7 +45,7 @@ abstract class DefaultPermissions{ return PermissionManager::getInstance()->getPermission($perm->getName()); } - public static function registerCorePermissions(){ + public static function registerCorePermissions() : void{ $manager = PermissionManager::getInstance(); foreach(PermissionParser::loadPermissions(yaml_parse(file_get_contents(\pocketmine\RESOURCE_PATH . 'default_permissions.yml'))) as $permission){ $manager->addPermission($permission); diff --git a/src/pocketmine/permission/Permissible.php b/src/pocketmine/permission/Permissible.php index 21ebba7b2c..a9065bc4cb 100644 --- a/src/pocketmine/permission/Permissible.php +++ b/src/pocketmine/permission/Permissible.php @@ -59,13 +59,13 @@ interface Permissible extends ServerOperator{ * * @return void */ - public function removeAttachment(PermissionAttachment $attachment); + public function removeAttachment(PermissionAttachment $attachment) : void; /** * @return void */ - public function recalculatePermissions(); + public function recalculatePermissions() : void; /** * @return PermissionAttachmentInfo[] diff --git a/src/pocketmine/permission/PermissibleBase.php b/src/pocketmine/permission/PermissibleBase.php index 47b5acfde5..3e2a96eeac 100644 --- a/src/pocketmine/permission/PermissibleBase.php +++ b/src/pocketmine/permission/PermissibleBase.php @@ -65,7 +65,7 @@ class PermissibleBase implements Permissible{ /** * @param bool $value */ - public function setOp(bool $value){ + public function setOp(bool $value) : void{ $this->opable->setOp($value); } @@ -130,7 +130,7 @@ class PermissibleBase implements Permissible{ /** * @param PermissionAttachment $attachment */ - public function removeAttachment(PermissionAttachment $attachment){ + public function removeAttachment(PermissionAttachment $attachment) : void{ if(isset($this->attachments[spl_object_id($attachment)])){ unset($this->attachments[spl_object_id($attachment)]); if(($ex = $attachment->getRemovalCallback()) !== null){ @@ -143,7 +143,7 @@ class PermissibleBase implements Permissible{ } - public function recalculatePermissions(){ + public function recalculatePermissions() : void{ Timings::$permissibleCalculationTimer->startTiming(); $this->clearPermissions(); @@ -165,7 +165,7 @@ class PermissibleBase implements Permissible{ Timings::$permissibleCalculationTimer->stopTiming(); } - public function clearPermissions(){ + public function clearPermissions() : void{ $permManager = PermissionManager::getInstance(); $permManager->unsubscribeFromAllPermissions($this->parent ?? $this); @@ -180,7 +180,7 @@ class PermissibleBase implements Permissible{ * @param bool $invert * @param PermissionAttachment|null $attachment */ - private function calculateChildPermissions(array $children, bool $invert, ?PermissionAttachment $attachment){ + private function calculateChildPermissions(array $children, bool $invert, ?PermissionAttachment $attachment) : void{ $permManager = PermissionManager::getInstance(); foreach($children as $name => $v){ $perm = $permManager->getPermission($name); diff --git a/src/pocketmine/permission/Permission.php b/src/pocketmine/permission/Permission.php index 4759d0666a..41090f5c91 100644 --- a/src/pocketmine/permission/Permission.php +++ b/src/pocketmine/permission/Permission.php @@ -93,7 +93,7 @@ class Permission{ /** * @param string $value */ - public function setDefault(string $value){ + public function setDefault(string $value) : void{ if($value !== $this->defaultValue){ $this->defaultValue = $value; $this->recalculatePermissibles(); @@ -110,7 +110,7 @@ class Permission{ /** * @param string $value */ - public function setDescription(string $value){ + public function setDescription(string $value) : void{ $this->description = $value; } @@ -121,7 +121,7 @@ class Permission{ return PermissionManager::getInstance()->getPermissionSubscriptions($this->name); } - public function recalculatePermissibles(){ + public function recalculatePermissibles() : void{ $perms = $this->getPermissibles(); PermissionManager::getInstance()->recalculatePermissionDefaults($this); @@ -138,7 +138,7 @@ class Permission{ * * @return Permission|null Permission if $name is a string, null if it's a Permission */ - public function addParent($name, bool $value){ + public function addParent($name, bool $value) : ?Permission{ if($name instanceof Permission){ $name->getChildren()[$this->getName()] = $value; $name->recalculatePermissibles(); diff --git a/src/pocketmine/permission/PermissionAttachment.php b/src/pocketmine/permission/PermissionAttachment.php index 1d4693c18e..7697503710 100644 --- a/src/pocketmine/permission/PermissionAttachment.php +++ b/src/pocketmine/permission/PermissionAttachment.php @@ -66,14 +66,14 @@ class PermissionAttachment{ /** * @param PermissionRemovedExecutor $ex */ - public function setRemovalCallback(PermissionRemovedExecutor $ex){ + public function setRemovalCallback(PermissionRemovedExecutor $ex) : void{ $this->removed = $ex; } /** * @return PermissionRemovedExecutor|null */ - public function getRemovalCallback(){ + public function getRemovalCallback() : ?PermissionRemovedExecutor{ return $this->removed; } @@ -91,7 +91,7 @@ class PermissionAttachment{ return $this->permissions; } - public function clearPermissions(){ + public function clearPermissions() : void{ $this->permissions = []; $this->permissible->recalculatePermissions(); } @@ -99,7 +99,7 @@ class PermissionAttachment{ /** * @param bool[] $permissions */ - public function setPermissions(array $permissions){ + public function setPermissions(array $permissions) : void{ foreach($permissions as $key => $value){ $this->permissions[$key] = (bool) $value; } @@ -109,7 +109,7 @@ class PermissionAttachment{ /** * @param string[] $permissions */ - public function unsetPermissions(array $permissions){ + public function unsetPermissions(array $permissions) : void{ foreach($permissions as $node){ unset($this->permissions[$node]); } @@ -120,7 +120,7 @@ class PermissionAttachment{ * @param string|Permission $name * @param bool $value */ - public function setPermission($name, bool $value){ + public function setPermission($name, bool $value) : void{ $name = $name instanceof Permission ? $name->getName() : $name; if(isset($this->permissions[$name])){ if($this->permissions[$name] === $value){ @@ -135,7 +135,7 @@ class PermissionAttachment{ /** * @param string|Permission $name */ - public function unsetPermission($name){ + public function unsetPermission($name) : void{ $name = $name instanceof Permission ? $name->getName() : $name; if(isset($this->permissions[$name])){ unset($this->permissions[$name]); @@ -146,7 +146,7 @@ class PermissionAttachment{ /** * @return void */ - public function remove(){ + public function remove() : void{ $this->permissible->removeAttachment($this); } } diff --git a/src/pocketmine/permission/PermissionAttachmentInfo.php b/src/pocketmine/permission/PermissionAttachmentInfo.php index 418edfb818..002a480d44 100644 --- a/src/pocketmine/permission/PermissionAttachmentInfo.php +++ b/src/pocketmine/permission/PermissionAttachmentInfo.php @@ -69,7 +69,7 @@ class PermissionAttachmentInfo{ /** * @return PermissionAttachment|null */ - public function getAttachment(){ + public function getAttachment() : ?PermissionAttachment{ return $this->attachment; } diff --git a/src/pocketmine/permission/PermissionManager.php b/src/pocketmine/permission/PermissionManager.php index 6cd1d8ab18..12d1791204 100644 --- a/src/pocketmine/permission/PermissionManager.php +++ b/src/pocketmine/permission/PermissionManager.php @@ -57,7 +57,7 @@ class PermissionManager{ * * @return null|Permission */ - public function getPermission(string $name){ + public function getPermission(string $name) : ?Permission{ return $this->permissions[$name] ?? null; } @@ -80,7 +80,7 @@ class PermissionManager{ /** * @param string|Permission $permission */ - public function removePermission($permission){ + public function removePermission($permission) : void{ if($permission instanceof Permission){ unset($this->permissions[$permission->getName()]); }else{ @@ -104,7 +104,7 @@ class PermissionManager{ /** * @param Permission $permission */ - public function recalculatePermissionDefaults(Permission $permission){ + public function recalculatePermissionDefaults(Permission $permission) : void{ if(isset($this->permissions[$permission->getName()])){ unset($this->defaultPermsOp[$permission->getName()]); unset($this->defaultPerms[$permission->getName()]); @@ -115,7 +115,7 @@ class PermissionManager{ /** * @param Permission $permission */ - private function calculatePermissionDefault(Permission $permission){ + private function calculatePermissionDefault(Permission $permission) : void{ Timings::$permissionDefaultTimer->startTiming(); if($permission->getDefault() === Permission::DEFAULT_OP or $permission->getDefault() === Permission::DEFAULT_TRUE){ $this->defaultPermsOp[$permission->getName()] = $permission; @@ -132,7 +132,7 @@ class PermissionManager{ /** * @param bool $op */ - private function dirtyPermissibles(bool $op){ + private function dirtyPermissibles(bool $op) : void{ foreach($this->getDefaultPermSubscriptions($op) as $p){ $p->recalculatePermissions(); } @@ -142,7 +142,7 @@ class PermissionManager{ * @param string $permission * @param Permissible $permissible */ - public function subscribeToPermission(string $permission, Permissible $permissible){ + public function subscribeToPermission(string $permission, Permissible $permissible) : void{ if(!isset($this->permSubs[$permission])){ $this->permSubs[$permission] = []; } @@ -153,7 +153,7 @@ class PermissionManager{ * @param string $permission * @param Permissible $permissible */ - public function unsubscribeFromPermission(string $permission, Permissible $permissible){ + public function unsubscribeFromPermission(string $permission, Permissible $permissible) : void{ if(isset($this->permSubs[$permission])){ unset($this->permSubs[$permission][spl_object_id($permissible)]); if(count($this->permSubs[$permission]) === 0){ @@ -187,7 +187,7 @@ class PermissionManager{ * @param bool $op * @param Permissible $permissible */ - public function subscribeToDefaultPerms(bool $op, Permissible $permissible){ + public function subscribeToDefaultPerms(bool $op, Permissible $permissible) : void{ if($op){ $this->defSubsOp[spl_object_id($permissible)] = $permissible; }else{ @@ -199,7 +199,7 @@ class PermissionManager{ * @param bool $op * @param Permissible $permissible */ - public function unsubscribeFromDefaultPerms(bool $op, Permissible $permissible){ + public function unsubscribeFromDefaultPerms(bool $op, Permissible $permissible) : void{ if($op){ unset($this->defSubsOp[spl_object_id($permissible)]); }else{ diff --git a/src/pocketmine/permission/PermissionRemovedExecutor.php b/src/pocketmine/permission/PermissionRemovedExecutor.php index 3eb5598831..0298f1bfac 100644 --- a/src/pocketmine/permission/PermissionRemovedExecutor.php +++ b/src/pocketmine/permission/PermissionRemovedExecutor.php @@ -31,5 +31,5 @@ interface PermissionRemovedExecutor{ * * @return void */ - public function attachmentRemoved(PermissionAttachment $attachment); + public function attachmentRemoved(PermissionAttachment $attachment) : void; } diff --git a/src/pocketmine/permission/ServerOperator.php b/src/pocketmine/permission/ServerOperator.php index a31f67d00c..55601af288 100644 --- a/src/pocketmine/permission/ServerOperator.php +++ b/src/pocketmine/permission/ServerOperator.php @@ -37,5 +37,5 @@ interface ServerOperator{ * * @param bool $value */ - public function setOp(bool $value); + public function setOp(bool $value) : void; } diff --git a/src/pocketmine/plugin/Plugin.php b/src/pocketmine/plugin/Plugin.php index 9a33b4920d..a25a549cbb 100644 --- a/src/pocketmine/plugin/Plugin.php +++ b/src/pocketmine/plugin/Plugin.php @@ -88,7 +88,7 @@ interface Plugin{ /** * @return PluginLoader */ - public function getPluginLoader(); + public function getPluginLoader() : PluginLoader; /** * @return TaskScheduler diff --git a/src/pocketmine/plugin/PluginBase.php b/src/pocketmine/plugin/PluginBase.php index 3dc692d4e9..8c81ff6d1c 100644 --- a/src/pocketmine/plugin/PluginBase.php +++ b/src/pocketmine/plugin/PluginBase.php @@ -387,7 +387,7 @@ abstract class PluginBase implements Plugin, CommandExecutor{ /** * @return PluginLoader */ - public function getPluginLoader(){ + public function getPluginLoader() : PluginLoader{ return $this->loader; } diff --git a/src/pocketmine/plugin/PluginDescription.php b/src/pocketmine/plugin/PluginDescription.php index b904bf491b..49ca9b0729 100644 --- a/src/pocketmine/plugin/PluginDescription.php +++ b/src/pocketmine/plugin/PluginDescription.php @@ -82,7 +82,7 @@ class PluginDescription{ * * @throws PluginException */ - private function loadMap(array $plugin){ + private function loadMap(array $plugin) : void{ $this->map = $plugin; $this->name = $plugin["name"]; @@ -205,7 +205,7 @@ class PluginDescription{ * * @throws PluginException if there are required extensions missing or have incompatible version, or if the version constraint cannot be parsed */ - public function checkRequiredExtensions(){ + public function checkRequiredExtensions() : void{ foreach($this->extensions as $name => $versionConstrs){ if(!extension_loaded($name)){ throw new PluginException("Required extension $name not loaded"); diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index b1079daeca..a6d2e41e11 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -102,7 +102,7 @@ class PluginManager{ * * @return null|Plugin */ - public function getPlugin(string $name){ + public function getPlugin(string $name) : ?Plugin{ if(isset($this->plugins[$name])){ return $this->plugins[$name]; } @@ -193,7 +193,7 @@ class PluginManager{ * * @return Plugin[] */ - public function loadPlugins(string $directory, ?array $newLoaders = null){ + public function loadPlugins(string $directory, ?array $newLoaders = null) : array{ if(!is_dir($directory)){ return []; } @@ -408,7 +408,7 @@ class PluginManager{ /** * @param Plugin $plugin */ - public function enablePlugin(Plugin $plugin){ + public function enablePlugin(Plugin $plugin) : void{ if(!$plugin->isEnabled()){ $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.plugin.enable", [$plugin->getDescription()->getFullName()])); @@ -425,7 +425,7 @@ class PluginManager{ } } - public function disablePlugins(){ + public function disablePlugins() : void{ foreach($this->getPlugins() as $plugin){ $this->disablePlugin($plugin); } @@ -434,7 +434,7 @@ class PluginManager{ /** * @param Plugin $plugin */ - public function disablePlugin(Plugin $plugin){ + public function disablePlugin(Plugin $plugin) : void{ if($plugin->isEnabled()){ $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.plugin.disable", [$plugin->getDescription()->getFullName()])); (new PluginDisableEvent($plugin))->call(); @@ -457,7 +457,7 @@ class PluginManager{ } } - public function clearPlugins(){ + public function clearPlugins() : void{ $this->disablePlugins(); $this->plugins = []; $this->enabledPlugins = []; diff --git a/src/pocketmine/plugin/RegisteredListener.php b/src/pocketmine/plugin/RegisteredListener.php index 0af6b197c7..0cc684a59a 100644 --- a/src/pocketmine/plugin/RegisteredListener.php +++ b/src/pocketmine/plugin/RegisteredListener.php @@ -81,7 +81,7 @@ class RegisteredListener{ /** * @param Event $event */ - public function callEvent(Event $event){ + public function callEvent(Event $event) : void{ if($event instanceof Cancellable and $event->isCancelled() and $this->isIgnoringCancelled()){ return; } diff --git a/src/pocketmine/resourcepacks/ResourcePackManager.php b/src/pocketmine/resourcepacks/ResourcePackManager.php index f004df611f..5071016d0c 100644 --- a/src/pocketmine/resourcepacks/ResourcePackManager.php +++ b/src/pocketmine/resourcepacks/ResourcePackManager.php @@ -151,7 +151,7 @@ class ResourcePackManager{ * * @return ResourcePack|null */ - public function getPackById(string $id){ + public function getPackById(string $id) : ?ResourcePack{ return $this->uuidList[strtolower($id)] ?? null; } diff --git a/src/pocketmine/scheduler/AsyncTask.php b/src/pocketmine/scheduler/AsyncTask.php index 38f6429c68..6b6f597890 100644 --- a/src/pocketmine/scheduler/AsyncTask.php +++ b/src/pocketmine/scheduler/AsyncTask.php @@ -196,7 +196,7 @@ abstract class AsyncTask extends \Threaded{ * * @param mixed $progress A value that can be safely serialize()'ed. */ - public function publishProgress($progress){ + public function publishProgress($progress) : void{ $this->progressUpdates[] = serialize($progress); } diff --git a/src/pocketmine/scheduler/AsyncWorker.php b/src/pocketmine/scheduler/AsyncWorker.php index 67bf176bb8..f4d98de4ee 100644 --- a/src/pocketmine/scheduler/AsyncWorker.php +++ b/src/pocketmine/scheduler/AsyncWorker.php @@ -45,7 +45,7 @@ class AsyncWorker extends Worker{ $this->memoryLimit = $memoryLimit; } - public function run(){ + public function run() : void{ error_reporting(-1); $this->registerClassLoader(); @@ -73,7 +73,7 @@ class AsyncWorker extends Worker{ return $this->logger; } - public function handleException(\Throwable $e){ + public function handleException(\Throwable $e) : void{ $this->logger->logException($e); } diff --git a/src/pocketmine/scheduler/ClosureTask.php b/src/pocketmine/scheduler/ClosureTask.php index f023173d47..3e46d5b483 100644 --- a/src/pocketmine/scheduler/ClosureTask.php +++ b/src/pocketmine/scheduler/ClosureTask.php @@ -53,7 +53,7 @@ class ClosureTask extends Task{ return Utils::getNiceClosureName($this->closure); } - public function onRun(int $currentTick){ + public function onRun(int $currentTick) : void{ ($this->closure)($currentTick); } } diff --git a/src/pocketmine/scheduler/Task.php b/src/pocketmine/scheduler/Task.php index af7d0c50d1..0da2b2346d 100644 --- a/src/pocketmine/scheduler/Task.php +++ b/src/pocketmine/scheduler/Task.php @@ -55,7 +55,7 @@ abstract class Task{ /** * @param TaskHandler|null $taskHandler */ - final public function setHandler(?TaskHandler $taskHandler){ + final public function setHandler(?TaskHandler $taskHandler) : void{ if($this->taskHandler === null or $taskHandler === null){ $this->taskHandler = $taskHandler; } diff --git a/src/pocketmine/scheduler/TaskHandler.php b/src/pocketmine/scheduler/TaskHandler.php index e2188af1e5..fb798eda9b 100644 --- a/src/pocketmine/scheduler/TaskHandler.php +++ b/src/pocketmine/scheduler/TaskHandler.php @@ -89,7 +89,7 @@ class TaskHandler{ /** * @param int $ticks */ - public function setNextRun(int $ticks){ + public function setNextRun(int $ticks) : void{ $this->nextRun = $ticks; } @@ -135,7 +135,7 @@ class TaskHandler{ return $this->period; } - public function cancel(){ + public function cancel() : void{ try{ if(!$this->isCancelled()){ $this->task->onCancel(); @@ -145,7 +145,7 @@ class TaskHandler{ } } - public function remove(){ + public function remove() : void{ $this->cancelled = true; $this->task->setHandler(null); } @@ -153,7 +153,7 @@ class TaskHandler{ /** * @param int $currentTick */ - public function run(int $currentTick){ + public function run(int $currentTick) : void{ $this->timings->startTiming(); try{ $this->task->onRun($currentTick); diff --git a/src/pocketmine/scheduler/TaskScheduler.php b/src/pocketmine/scheduler/TaskScheduler.php index 95df7add4c..d68e480d27 100644 --- a/src/pocketmine/scheduler/TaskScheduler.php +++ b/src/pocketmine/scheduler/TaskScheduler.php @@ -65,7 +65,7 @@ class TaskScheduler{ * * @return TaskHandler */ - public function scheduleTask(Task $task){ + public function scheduleTask(Task $task) : TaskHandler{ return $this->addTask($task, -1, -1); } @@ -75,7 +75,7 @@ class TaskScheduler{ * * @return TaskHandler */ - public function scheduleDelayedTask(Task $task, int $delay){ + public function scheduleDelayedTask(Task $task, int $delay) : TaskHandler{ return $this->addTask($task, $delay, -1); } @@ -85,7 +85,7 @@ class TaskScheduler{ * * @return TaskHandler */ - public function scheduleRepeatingTask(Task $task, int $period){ + public function scheduleRepeatingTask(Task $task, int $period) : TaskHandler{ return $this->addTask($task, -1, $period); } @@ -96,14 +96,14 @@ class TaskScheduler{ * * @return TaskHandler */ - public function scheduleDelayedRepeatingTask(Task $task, int $delay, int $period){ + public function scheduleDelayedRepeatingTask(Task $task, int $delay, int $period) : TaskHandler{ return $this->addTask($task, $delay, $period); } /** * @param int $taskId */ - public function cancelTask(int $taskId){ + public function cancelTask(int $taskId) : void{ if(isset($this->tasks[$taskId])){ try{ $this->tasks[$taskId]->cancel(); @@ -113,7 +113,7 @@ class TaskScheduler{ } } - public function cancelAllTasks(){ + public function cancelAllTasks() : void{ foreach($this->tasks as $id => $task){ $this->cancelTask($id); } @@ -142,7 +142,7 @@ class TaskScheduler{ * * @throws \InvalidStateException */ - private function addTask(Task $task, int $delay, int $period){ + private function addTask(Task $task, int $delay, int $period) : TaskHandler{ if(!$this->enabled){ throw new \InvalidStateException("Tried to schedule task to disabled scheduler"); } @@ -186,7 +186,7 @@ class TaskScheduler{ /** * @param int $currentTick */ - public function mainThreadHeartbeat(int $currentTick){ + public function mainThreadHeartbeat(int $currentTick) : void{ $this->currentTick = $currentTick; while($this->isReady($this->currentTick)){ /** @var TaskHandler $task */ diff --git a/src/pocketmine/tile/Bed.php b/src/pocketmine/tile/Bed.php index 692a6f4509..442eb31b81 100644 --- a/src/pocketmine/tile/Bed.php +++ b/src/pocketmine/tile/Bed.php @@ -43,7 +43,7 @@ class Bed extends Spawnable{ return $this->color; } - public function setColor(DyeColor $color){ + public function setColor(DyeColor $color) : void{ $this->color = $color; $this->onChanged(); } diff --git a/src/pocketmine/tile/FlowerPot.php b/src/pocketmine/tile/FlowerPot.php index a9005c7067..4aeeceac05 100644 --- a/src/pocketmine/tile/FlowerPot.php +++ b/src/pocketmine/tile/FlowerPot.php @@ -63,7 +63,7 @@ class FlowerPot extends Spawnable{ return $this->plant !== null ? clone $this->plant : null; } - public function setPlant(?Block $plant){ + public function setPlant(?Block $plant) : void{ if($plant === null or $plant instanceof Air){ $this->plant = null; }else{ diff --git a/src/pocketmine/tile/ItemFrame.php b/src/pocketmine/tile/ItemFrame.php index cc831a4d06..9d041e6e87 100644 --- a/src/pocketmine/tile/ItemFrame.php +++ b/src/pocketmine/tile/ItemFrame.php @@ -72,7 +72,7 @@ class ItemFrame extends Spawnable{ return clone $this->item; } - public function setItem(?Item $item){ + public function setItem(?Item $item) : void{ if($item !== null and !$item->isNull()){ $this->item = clone $item; }else{ @@ -85,7 +85,7 @@ class ItemFrame extends Spawnable{ return $this->itemRotation; } - public function setItemRotation(int $rotation){ + public function setItemRotation(int $rotation) : void{ $this->itemRotation = $rotation; $this->onChanged(); } @@ -94,7 +94,7 @@ class ItemFrame extends Spawnable{ return $this->itemDropChance; } - public function setItemDropChance(float $chance){ + public function setItemDropChance(float $chance) : void{ $this->itemDropChance = $chance; $this->onChanged(); } diff --git a/src/pocketmine/tile/Nameable.php b/src/pocketmine/tile/Nameable.php index ab66b101c3..9f407461ef 100644 --- a/src/pocketmine/tile/Nameable.php +++ b/src/pocketmine/tile/Nameable.php @@ -39,7 +39,7 @@ interface Nameable{ /** * @param string $str */ - public function setName(string $str); + public function setName(string $str) : void; /** * @return bool diff --git a/src/pocketmine/tile/Skull.php b/src/pocketmine/tile/Skull.php index 42802db666..6567a1b028 100644 --- a/src/pocketmine/tile/Skull.php +++ b/src/pocketmine/tile/Skull.php @@ -69,7 +69,7 @@ class Skull extends Spawnable{ $nbt->setByte(self::TAG_ROT, $this->skullRotation); } - public function setSkullType(SkullType $type){ + public function setSkullType(SkullType $type) : void{ $this->skullType = $type; $this->onChanged(); } diff --git a/src/pocketmine/tile/TileFactory.php b/src/pocketmine/tile/TileFactory.php index d866e30eac..c329d47260 100644 --- a/src/pocketmine/tile/TileFactory.php +++ b/src/pocketmine/tile/TileFactory.php @@ -45,7 +45,7 @@ final class TileFactory{ //NOOP } - public static function init(){ + public static function init() : void{ self::register(Banner::class, ["Banner", "minecraft:banner"]); self::register(Bed::class, ["Bed", "minecraft:bed"]); self::register(Chest::class, ["Chest", "minecraft:chest"]); diff --git a/src/pocketmine/timings/Timings.php b/src/pocketmine/timings/Timings.php index 9622154184..ee218952b3 100644 --- a/src/pocketmine/timings/Timings.php +++ b/src/pocketmine/timings/Timings.php @@ -112,7 +112,7 @@ abstract class Timings{ /** @var TimingsHandler[] */ public static $pluginTaskTimingMap = []; - public static function init(){ + public static function init() : void{ if(self::$serverTickTimer instanceof TimingsHandler){ return; } diff --git a/src/pocketmine/timings/TimingsHandler.php b/src/pocketmine/timings/TimingsHandler.php index 8889e2b142..bb89d07e2a 100644 --- a/src/pocketmine/timings/TimingsHandler.php +++ b/src/pocketmine/timings/TimingsHandler.php @@ -44,7 +44,7 @@ class TimingsHandler{ /** * @param resource $fp */ - public static function printTimings($fp){ + public static function printTimings($fp) : void{ fwrite($fp, "Minecraft" . PHP_EOL); foreach(self::$HANDLERS as $timings){ @@ -93,7 +93,7 @@ class TimingsHandler{ return self::$timingStart; } - public static function reload(){ + public static function reload() : void{ if(self::$enabled){ foreach(self::$HANDLERS as $timings){ $timings->reset(); @@ -102,7 +102,7 @@ class TimingsHandler{ } } - public static function tick(bool $measure = true){ + public static function tick(bool $measure = true) : void{ if(self::$enabled){ if($measure){ foreach(self::$HANDLERS as $timings){ @@ -157,7 +157,7 @@ class TimingsHandler{ self::$HANDLERS[spl_object_id($this)] = $this; } - public function startTiming(){ + public function startTiming() : void{ if(self::$enabled and ++$this->timingDepth === 1){ $this->start = microtime(true); if($this->parent !== null and ++$this->parent->timingDepth === 1){ @@ -166,7 +166,7 @@ class TimingsHandler{ } } - public function stopTiming(){ + public function stopTiming() : void{ if(self::$enabled){ if(--$this->timingDepth !== 0 or $this->start === 0){ return; @@ -184,7 +184,7 @@ class TimingsHandler{ } } - public function reset(){ + public function reset() : void{ $this->count = 0; $this->curCount = 0; $this->violations = 0; @@ -194,7 +194,7 @@ class TimingsHandler{ $this->timingDepth = 0; } - public function remove(){ + public function remove() : void{ unset(self::$HANDLERS[spl_object_id($this)]); } } diff --git a/src/pocketmine/updater/AutoUpdater.php b/src/pocketmine/updater/AutoUpdater.php index 98932e2ad6..4e6ad925af 100644 --- a/src/pocketmine/updater/AutoUpdater.php +++ b/src/pocketmine/updater/AutoUpdater.php @@ -68,7 +68,7 @@ class AutoUpdater{ * * @param array $updateInfo */ - public function checkUpdateCallback(array $updateInfo){ + public function checkUpdateCallback(array $updateInfo) : void{ $this->updateInfo = $updateInfo; $this->checkUpdate(); if($this->hasUpdate()){ @@ -97,7 +97,7 @@ class AutoUpdater{ /** * Posts a warning to the console to tell the user there is an update available */ - public function showConsoleUpdate(){ + public function showConsoleUpdate() : void{ $messages = [ "Your version of " . $this->server->getName() . " is out of date. Version " . $this->newVersion->getFullVersion(true) . " was released on " . date("D M j h:i:s Y", $this->updateInfo["date"]) ]; @@ -114,26 +114,26 @@ class AutoUpdater{ * * @param Player $player */ - public function showPlayerUpdate(Player $player){ + public function showPlayerUpdate(Player $player) : void{ $player->sendMessage(TextFormat::DARK_PURPLE . "The version of " . $this->server->getName() . " that this server is running is out of date. Please consider updating to the latest version."); $player->sendMessage(TextFormat::DARK_PURPLE . "Check the console for more details."); } - protected function showChannelSuggestionStable(){ + protected function showChannelSuggestionStable() : void{ $this->printConsoleMessage([ "It appears you're running a Stable build, when you've specified that you prefer to run " . ucfirst($this->getChannel()) . " builds.", "If you would like to be kept informed about new Stable builds only, it is recommended that you change 'preferred-channel' in your pocketmine.yml to 'stable'." ]); } - protected function showChannelSuggestionBeta(){ + protected function showChannelSuggestionBeta() : void{ $this->printConsoleMessage([ "It appears you're running a Beta build, when you've specified that you prefer to run Stable builds.", "If you would like to be kept informed about new Beta or Development builds, it is recommended that you change 'preferred-channel' in your pocketmine.yml to 'beta' or 'development'." ]); } - protected function printConsoleMessage(array $lines, string $logLevel = \LogLevel::INFO){ + protected function printConsoleMessage(array $lines, string $logLevel = \LogLevel::INFO) : void{ $logger = $this->server->getLogger(); $title = $this->server->getName() . ' Auto Updater'; @@ -149,21 +149,21 @@ class AutoUpdater{ * * @return array|null */ - public function getUpdateInfo(){ + public function getUpdateInfo() : ?array{ return $this->updateInfo; } /** * Schedules an AsyncTask to check for an update. */ - public function doCheck(){ + public function doCheck() : void{ $this->server->getAsyncPool()->submitTask(new UpdateCheckTask($this, $this->endpoint, $this->getChannel())); } /** * Checks the update information against the current server version to decide if there's an update */ - protected function checkUpdate(){ + protected function checkUpdate() : void{ if($this->updateInfo === null){ return; } diff --git a/src/pocketmine/utils/Color.php b/src/pocketmine/utils/Color.php index 018b60ac93..c860d05211 100644 --- a/src/pocketmine/utils/Color.php +++ b/src/pocketmine/utils/Color.php @@ -58,7 +58,7 @@ class Color{ * * @param int $a */ - public function setA(int $a){ + public function setA(int $a) : void{ $this->a = $a & 0xff; } @@ -75,7 +75,7 @@ class Color{ * * @param int $r */ - public function setR(int $r){ + public function setR(int $r) : void{ $this->r = $r & 0xff; } @@ -92,7 +92,7 @@ class Color{ * * @param int $g */ - public function setG(int $g){ + public function setG(int $g) : void{ $this->g = $g & 0xff; } @@ -109,7 +109,7 @@ class Color{ * * @param int $b */ - public function setB(int $b){ + public function setB(int $b) : void{ $this->b = $b & 0xff; } @@ -145,7 +145,7 @@ class Color{ * * @return Color */ - public static function fromRGB(int $code){ + public static function fromRGB(int $code) : Color{ return new Color(($code >> 16) & 0xff, ($code >> 8) & 0xff, $code & 0xff); } @@ -156,7 +156,7 @@ class Color{ * * @return Color */ - public static function fromARGB(int $code){ + public static function fromARGB(int $code) : Color{ return new Color(($code >> 16) & 0xff, ($code >> 8) & 0xff, $code & 0xff, ($code >> 24) & 0xff); } diff --git a/src/pocketmine/utils/Config.php b/src/pocketmine/utils/Config.php index 7b9c2a7106..7ca76ffc48 100644 --- a/src/pocketmine/utils/Config.php +++ b/src/pocketmine/utils/Config.php @@ -113,7 +113,7 @@ class Config{ /** * Removes all the changes in memory and loads the file again */ - public function reload(){ + public function reload() : void{ $this->config = []; $this->nestedCache = []; $this->load($this->file, $this->type); @@ -341,7 +341,7 @@ class Config{ * @param string $key * @param mixed $value */ - public function setNested($key, $value){ + public function setNested($key, $value) : void{ $vars = explode(".", $key); $base = array_shift($vars); @@ -430,7 +430,7 @@ class Config{ * @param string $k key to be set * @param mixed $v value to set key */ - public function set($k, $v = true){ + public function set($k, $v = true) : void{ $this->config[$k] = $v; $this->changed = true; foreach($this->nestedCache as $nestedKey => $nvalue){ @@ -443,7 +443,7 @@ class Config{ /** * @param array $v */ - public function setAll(array $v){ + public function setAll(array $v) : void{ $this->config = $v; $this->changed = true; } @@ -467,7 +467,7 @@ class Config{ /** * @param string $k */ - public function remove($k){ + public function remove($k) : void{ unset($this->config[$k]); $this->changed = true; } @@ -484,7 +484,7 @@ class Config{ /** * @param array $defaults */ - public function setDefaults(array $defaults){ + public function setDefaults(array $defaults) : void{ $this->fillDefaults($defaults, $this->config); } @@ -518,7 +518,7 @@ class Config{ /** * @param string $content */ - private function parseList(string $content){ + private function parseList(string $content) : void{ foreach(explode("\n", trim(str_replace("\r\n", "\n", $content))) as $v){ $v = trim($v); if($v == ""){ @@ -548,7 +548,7 @@ class Config{ /** * @param string $content */ - private function parseProperties(string $content){ + private function parseProperties(string $content) : void{ if(preg_match_all('/^\s*([a-zA-Z0-9\-_\.]+)[ \t]*=([^\r\n]*)/um', $content, $matches) > 0){ //false or 0 matches foreach($matches[1] as $i => $k){ $v = trim($matches[2][$i]); diff --git a/src/pocketmine/utils/Internet.php b/src/pocketmine/utils/Internet.php index b7f9ab1cf0..67035f5e6c 100644 --- a/src/pocketmine/utils/Internet.php +++ b/src/pocketmine/utils/Internet.php @@ -193,7 +193,7 @@ class Internet{ * * @throws InternetException if a cURL error occurs */ - public static function simpleCurl(string $page, $timeout = 10, array $extraHeaders = [], array $extraOpts = [], ?callable $onSuccess = null){ + public static function simpleCurl(string $page, $timeout = 10, array $extraHeaders = [], array $extraOpts = [], ?callable $onSuccess = null) : array{ if(!self::$online){ throw new InternetException("Cannot execute web request while offline"); } diff --git a/src/pocketmine/utils/MainLogger.php b/src/pocketmine/utils/MainLogger.php index f942249c9e..68c46ff019 100644 --- a/src/pocketmine/utils/MainLogger.php +++ b/src/pocketmine/utils/MainLogger.php @@ -111,7 +111,7 @@ class MainLogger extends \AttachableThreadedLogger{ * WARNING: Because static properties are thread-local, this MUST be called from the body of every Thread if you * want the logger to be accessible via {@link MainLogger#getLogger}. */ - public function registerStatic(){ + public function registerStatic() : void{ if(static::$logger === null){ static::$logger = $this; } @@ -181,7 +181,7 @@ class MainLogger extends \AttachableThreadedLogger{ /** * @param bool $logDebug */ - public function setLogDebug(bool $logDebug){ + public function setLogDebug(bool $logDebug) : void{ $this->logDebug = $logDebug; } @@ -253,12 +253,12 @@ class MainLogger extends \AttachableThreadedLogger{ } } - public function shutdown(){ + public function shutdown() : void{ $this->shutdown = true; $this->notify(); } - protected function send($message, $level, $prefix, $color){ + protected function send($message, $level, $prefix, $color) : void{ /** @var \DateTime|null $time */ static $time = null; if($time === null){ //thread-local @@ -292,7 +292,7 @@ class MainLogger extends \AttachableThreadedLogger{ }); } - public function syncFlushBuffer(){ + public function syncFlushBuffer() : void{ $this->syncFlush = true; $this->synchronized(function(){ $this->notify(); //write immediately @@ -306,7 +306,7 @@ class MainLogger extends \AttachableThreadedLogger{ /** * @param resource $logResource */ - private function writeLogStream($logResource){ + private function writeLogStream($logResource) : void{ while($this->logStream->count() > 0){ $chunk = $this->logStream->shift(); fwrite($logResource, $chunk); @@ -318,7 +318,7 @@ class MainLogger extends \AttachableThreadedLogger{ } } - public function run(){ + public function run() : void{ $this->shutdown = false; $logResource = fopen($this->logFile, "ab"); if(!is_resource($logResource)){ diff --git a/src/pocketmine/utils/Random.php b/src/pocketmine/utils/Random.php index b927631256..679d6bdc68 100644 --- a/src/pocketmine/utils/Random.php +++ b/src/pocketmine/utils/Random.php @@ -72,7 +72,7 @@ class Random{ /** * @param int $seed Integer to be used as seed. */ - public function setSeed(int $seed){ + public function setSeed(int $seed) : void{ $this->seed = $seed; $this->x = self::X ^ $seed; $this->y = self::Y ^ ($seed << 17) | (($seed >> 15) & 0x7fffffff) & 0xffffffff; diff --git a/src/pocketmine/utils/ServerKiller.php b/src/pocketmine/utils/ServerKiller.php index ff3ecd4480..4a4dfe81d1 100644 --- a/src/pocketmine/utils/ServerKiller.php +++ b/src/pocketmine/utils/ServerKiller.php @@ -38,7 +38,7 @@ class ServerKiller extends Thread{ $this->time = $time; } - public function run(){ + public function run() : void{ $this->registerClassLoader(); $start = time(); $this->synchronized(function(){ diff --git a/src/pocketmine/utils/Terminal.php b/src/pocketmine/utils/Terminal.php index 6823a64c1a..eb3f35a699 100644 --- a/src/pocketmine/utils/Terminal.php +++ b/src/pocketmine/utils/Terminal.php @@ -80,7 +80,7 @@ abstract class Terminal{ return $result; } - protected static function getFallbackEscapeCodes(){ + protected static function getFallbackEscapeCodes() : void{ self::$FORMAT_BOLD = "\x1b[1m"; self::$FORMAT_OBFUSCATED = ""; self::$FORMAT_ITALIC = "\x1b[3m"; @@ -107,7 +107,7 @@ abstract class Terminal{ self::$COLOR_WHITE = "\x1b[38;5;231m"; } - protected static function getEscapeCodes(){ + protected static function getEscapeCodes() : void{ self::$FORMAT_BOLD = `tput bold`; self::$FORMAT_OBFUSCATED = `tput smacs`; self::$FORMAT_ITALIC = `tput sitm`; diff --git a/src/pocketmine/utils/Utils.php b/src/pocketmine/utils/Utils.php index 0a94cb3e10..4527e8973a 100644 --- a/src/pocketmine/utils/Utils.php +++ b/src/pocketmine/utils/Utils.php @@ -110,7 +110,7 @@ class Utils{ * * @return string */ - public static function getCallableIdentifier(callable $variable){ + public static function getCallableIdentifier(callable $variable) : string{ if(is_array($variable)){ return sha1(strtolower(spl_object_hash($variable[0])) . "::" . strtolower($variable[1])); }else{ @@ -532,7 +532,7 @@ class Utils{ * * @return int */ - public static function getReferenceCount($value, bool $includeCurrent = true){ + public static function getReferenceCount($value, bool $includeCurrent = true) : int{ ob_start(); debug_zval_dump($value); $ret = explode("\n", ob_get_contents()); diff --git a/src/pocketmine/wizard/SetupWizard.php b/src/pocketmine/wizard/SetupWizard.php index 464066994d..3ecc9de05b 100644 --- a/src/pocketmine/wizard/SetupWizard.php +++ b/src/pocketmine/wizard/SetupWizard.php @@ -125,13 +125,13 @@ LICENSE; return true; } - private function welcome(){ + private function welcome() : void{ $this->message($this->lang->get("setting_up_server_now")); $this->message($this->lang->get("default_values_info")); $this->message($this->lang->get("server_properties")); } - private function generateBaseConfig(){ + private function generateBaseConfig() : void{ $config = new Config(\pocketmine\DATA . "server.properties", Config::PROPERTIES); $config->set("motd", ($name = $this->getInput($this->lang->get("name_your_server"), self::DEFAULT_NAME))); @@ -162,7 +162,7 @@ LICENSE; $config->save(); } - private function generateUserFiles(){ + private function generateUserFiles() : void{ $this->message($this->lang->get("op_info")); $op = strtolower($this->getInput($this->lang->get("op_who"), "")); @@ -186,7 +186,7 @@ LICENSE; $config->save(); } - private function networkFunctions(){ + private function networkFunctions() : void{ $config = new Config(\pocketmine\DATA . "server.properties", Config::PROPERTIES); $this->error($this->lang->get("query_warning1")); $this->error($this->lang->get("query_warning2")); @@ -216,7 +216,7 @@ LICENSE; $this->readLine(); } - private function endWizard(){ + private function endWizard() : void{ $this->message($this->lang->get("you_have_finished")); $this->message($this->lang->get("pocketmine_plugins")); $this->message($this->lang->translateString("pocketmine_will_start", [\pocketmine\NAME])); @@ -227,7 +227,7 @@ LICENSE; sleep(4); } - private function writeLine(string $line = ""){ + private function writeLine(string $line = "") : void{ echo $line . PHP_EOL; } @@ -235,11 +235,11 @@ LICENSE; return trim((string) fgets(STDIN)); } - private function message(string $message){ + private function message(string $message) : void{ $this->writeLine("[*] " . $message); } - private function error(string $message){ + private function error(string $message) : void{ $this->writeLine("[!] " . $message); } From 808259dccd650d41fad9c9adfdf5d936a0a7e292 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Mar 2019 10:45:01 +0000 Subject: [PATCH 0579/3224] Introduce CancellableClosureTask before anyone picks a fight about the naming, take it up with shoghi... let's be consistently wrong at least --- .../scheduler/CancellableClosureTask.php | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 src/pocketmine/scheduler/CancellableClosureTask.php diff --git a/src/pocketmine/scheduler/CancellableClosureTask.php b/src/pocketmine/scheduler/CancellableClosureTask.php new file mode 100644 index 0000000000..dbcd1f6e00 --- /dev/null +++ b/src/pocketmine/scheduler/CancellableClosureTask.php @@ -0,0 +1,73 @@ +scheduleTask(new CancellableClosureTask(function(int $currentTick) : bool{ + * echo "HI on $currentTick\n"; + * $continue = false; + * return $continue; //stop repeating + * }); + * ``` + * + * @see ClosureTask + */ +class CancellableClosureTask extends Task{ + public const CONTINUE = true; + public const CANCEL = false; + + /** @var \Closure */ + private $closure; + + /** + * CancellableClosureTask constructor. + * + * The closure should follow the signature callback(int $currentTick) : bool. The return value will be used to + * decide whether to continue repeating. + * + * @param \Closure $closure + */ + public function __construct(\Closure $closure){ + Utils::validateCallableSignature(function(int $currentTick) : bool{ return false; }, $closure); + $this->closure = $closure; + } + + public function getName() : string{ + return Utils::getNiceClosureName($this->closure); + } + + public function onRun(int $currentTick) : void{ + if(!($this->closure)($currentTick)){ + $this->getHandler()->cancel(); + } + } +} From 382488dd07fb11fd0ccec8333e6ca2ca4e6c993a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Mar 2019 17:20:37 +0000 Subject: [PATCH 0580/3224] sync locale submodule --- resources/locale | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/locale b/resources/locale index 5dad5db214..34386f9e86 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 5dad5db214ce0c94be0235e93d8253d0aec19c82 +Subproject commit 34386f9e86fef8690f34193412f086e5516f1a22 From 2bffd5cc1c326670c25386ce78e5c690f4c5fd54 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Mar 2019 18:20:25 +0000 Subject: [PATCH 0581/3224] Add timer measurements for autosave --- resources/locale | 2 +- src/pocketmine/command/defaults/SaveCommand.php | 7 +++++-- src/pocketmine/level/LevelManager.php | 3 +++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/resources/locale b/resources/locale index 34386f9e86..73ed1ab3e1 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 34386f9e86fef8690f34193412f086e5516f1a22 +Subproject commit 73ed1ab3e1f2a1644fe908b439f8cf8ed6c12ab5 diff --git a/src/pocketmine/command/defaults/SaveCommand.php b/src/pocketmine/command/defaults/SaveCommand.php index d1f4882fbf..5ed458296f 100644 --- a/src/pocketmine/command/defaults/SaveCommand.php +++ b/src/pocketmine/command/defaults/SaveCommand.php @@ -26,6 +26,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\lang\TranslationContainer; +use function microtime; +use function round; class SaveCommand extends VanillaCommand{ @@ -43,7 +45,8 @@ class SaveCommand extends VanillaCommand{ return true; } - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.save.start")); + Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.save.start")); + $start = microtime(true); foreach($sender->getServer()->getOnlinePlayers() as $player){ $player->save(); @@ -53,7 +56,7 @@ class SaveCommand extends VanillaCommand{ $level->save(true); } - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.save.success")); + Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.save.success", [round(microtime(true) - $start, 3)])); return true; } diff --git a/src/pocketmine/level/LevelManager.php b/src/pocketmine/level/LevelManager.php index dd9699987f..09ef7bd3b5 100644 --- a/src/pocketmine/level/LevelManager.php +++ b/src/pocketmine/level/LevelManager.php @@ -398,7 +398,10 @@ class LevelManager{ if($this->autoSave and ++$this->autoSaveTicker >= $this->autoSaveTicks){ $this->autoSaveTicker = 0; + $this->server->getLogger()->debug("[Auto Save] Saving worlds..."); + $start = microtime(true); $this->doAutoSave(); + $this->server->getLogger()->debug("[Auto Save] Save completed in " . round(microtime(true) - $start, 3) . "s"); } } From 0573838be3034735fa293a8e7ae45a17f07322c0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Mar 2019 11:47:00 +0000 Subject: [PATCH 0582/3224] rename submodules --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index ffdd6fb4f1..5e9c29a9b9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ -[submodule "src/pocketmine/lang/locale"] +[submodule "resources/locale"] path = resources/locale url = https://github.com/pmmp/PocketMine-Language.git [submodule "tests/preprocessor"] @@ -7,6 +7,6 @@ [submodule "tests/plugins/PocketMine-DevTools"] path = tests/plugins/PocketMine-DevTools url = https://github.com/pmmp/PocketMine-DevTools.git -[submodule "src/pocketmine/resources/vanilla"] +[submodule "resources/vanilla"] path = resources/vanilla url = https://github.com/pmmp/BedrockData.git From abbdd7efddcaa4ab6dcc1c9f9ac82945eeeec66b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Mar 2019 12:33:28 +0000 Subject: [PATCH 0583/3224] Item: make __toString() use base64 for displaying NBT --- src/pocketmine/item/Item.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 920c048c79..37236f6153 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -841,7 +841,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return string */ final public function __toString() : string{ - return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->getMeta()) . ")x" . $this->count . ($this->hasNamedTag() ? " tags:0x" . self::writeCompoundTag($this->nbt) : ""); + return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->getMeta()) . ")x" . $this->count . ($this->hasNamedTag() ? " tags:" . base64_encode(self::writeCompoundTag($this->nbt)) : ""); } /** From fc9a61859ac375c2e419b842f412ff45b266f398 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Mar 2019 12:36:46 +0000 Subject: [PATCH 0584/3224] Item: remove misleading methods & premature optimization --- src/pocketmine/item/Item.php | 34 +++++----------------------------- 1 file changed, 5 insertions(+), 29 deletions(-) diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 37236f6153..bb2f0b11a1 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -61,32 +61,6 @@ class Item implements ItemIds, \JsonSerializable{ public const TAG_DISPLAY_NAME = "Name"; public const TAG_DISPLAY_LORE = "Lore"; - - /** @var LittleEndianNbtSerializer */ - private static $cachedParser = null; - - /** - * @param string $tag - * - * @return CompoundTag - * @throws NbtDataException - */ - private static function parseCompoundTag(string $tag) : CompoundTag{ - if(self::$cachedParser === null){ - self::$cachedParser = new LittleEndianNbtSerializer(); - } - - return self::$cachedParser->read($tag); - } - - private static function writeCompoundTag(CompoundTag $tag) : string{ - if(self::$cachedParser === null){ - self::$cachedParser = new LittleEndianNbtSerializer(); - } - - return self::$cachedParser->write($tag); - } - /** * Returns a new Item instance with the specified ID, damage, count and NBT. * @@ -841,7 +815,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return string */ final public function __toString() : string{ - return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->getMeta()) . ")x" . $this->count . ($this->hasNamedTag() ? " tags:" . base64_encode(self::writeCompoundTag($this->nbt)) : ""); + return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->getMeta()) . ")x" . $this->count . ($this->hasNamedTag() ? " tags:" . base64_encode((new LittleEndianNbtSerializer())->write($this->nbt)) : ""); } /** @@ -863,7 +837,7 @@ class Item implements ItemIds, \JsonSerializable{ } if($this->hasNamedTag()){ - $data["nbt_b64"] = base64_encode(self::writeCompoundTag($this->getNamedTag())); + $data["nbt_b64"] = base64_encode((new LittleEndianNbtSerializer())->write($this->getNamedTag())); } return $data; @@ -875,6 +849,8 @@ class Item implements ItemIds, \JsonSerializable{ * @param array $data * * @return Item + * @throws NbtDataException + * @throws \InvalidArgumentException */ final public static function jsonDeserialize(array $data) : Item{ $nbt = ""; @@ -888,7 +864,7 @@ class Item implements ItemIds, \JsonSerializable{ $nbt = base64_decode($data["nbt_b64"], true); } return ItemFactory::get( - (int) $data["id"], (int) ($data["damage"] ?? 0), (int) ($data["count"] ?? 1), $nbt !== "" ? self::parseCompoundTag($nbt) : null + (int) $data["id"], (int) ($data["damage"] ?? 0), (int) ($data["count"] ?? 1), $nbt !== "" ? (new LittleEndianNbtSerializer())->read($nbt) : null ); } From d9880de2ef2156b432818c81ee1f8fba36776aac Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Mar 2019 12:43:02 +0000 Subject: [PATCH 0585/3224] LevelManager: improve debug message for autosave --- src/pocketmine/level/LevelManager.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/level/LevelManager.php b/src/pocketmine/level/LevelManager.php index 09ef7bd3b5..d0aff8a8ba 100644 --- a/src/pocketmine/level/LevelManager.php +++ b/src/pocketmine/level/LevelManager.php @@ -401,7 +401,8 @@ class LevelManager{ $this->server->getLogger()->debug("[Auto Save] Saving worlds..."); $start = microtime(true); $this->doAutoSave(); - $this->server->getLogger()->debug("[Auto Save] Save completed in " . round(microtime(true) - $start, 3) . "s"); + $time = microtime(true) - $start; + $this->server->getLogger()->debug("[Auto Save] Save completed in " . ($time >= 1 ? round($time, 3) . "s" : round($time * 1000) . "ms")); } } From 6bd43a8215b9e612478fe789da9a58b36f0f0e73 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Mar 2019 13:24:53 +0000 Subject: [PATCH 0586/3224] Firehose auto-tick-rate anti-feature, closes #2665 --- .../command/defaults/StatusCommand.php | 5 +- src/pocketmine/entity/Entity.php | 3 +- src/pocketmine/level/Level.php | 13 ----- src/pocketmine/level/LevelManager.php | 48 ------------------- 4 files changed, 4 insertions(+), 65 deletions(-) diff --git a/src/pocketmine/command/defaults/StatusCommand.php b/src/pocketmine/command/defaults/StatusCommand.php index 96b811b2f2..2a1d474e1c 100644 --- a/src/pocketmine/command/defaults/StatusCommand.php +++ b/src/pocketmine/command/defaults/StatusCommand.php @@ -108,12 +108,11 @@ class StatusCommand extends VanillaCommand{ foreach($server->getLevelManager()->getLevels() as $level){ $levelName = $level->getFolderName() !== $level->getDisplayName() ? " (" . $level->getDisplayName() . ")" : ""; - $timeColor = ($level->getTickRate() > 1 or $level->getTickRateTime() > 40) ? TextFormat::RED : TextFormat::YELLOW; - $tickRate = $level->getTickRate() > 1 ? " (tick rate " . $level->getTickRate() . ")" : ""; + $timeColor = $level->getTickRateTime() > 40 ? TextFormat::RED : TextFormat::YELLOW; $sender->sendMessage(TextFormat::GOLD . "World \"{$level->getFolderName()}\"$levelName: " . TextFormat::RED . number_format(count($level->getChunks())) . TextFormat::GREEN . " chunks, " . TextFormat::RED . number_format(count($level->getEntities())) . TextFormat::GREEN . " entities. " . - "Time $timeColor" . round($level->getTickRateTime(), 2) . "ms" . $tickRate + "Time $timeColor" . round($level->getTickRateTime(), 2) . "ms" ); } diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index d5d7fae7e6..49014c4636 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -1422,7 +1422,8 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ assert(abs($dx) <= 20 and abs($dy) <= 20 and abs($dz) <= 20, "Movement distance is excessive: dx=$dx, dy=$dy, dz=$dz"); - $list = $this->level->getCollisionBoxes($this, $this->level->getTickRate() > 1 ? $this->boundingBox->offsetCopy($dx, $dy, $dz) : $this->boundingBox->addCoord($dx, $dy, $dz), false); + //TODO: bad hack here will cause unexpected behaviour under heavy lag + $list = $this->level->getCollisionBoxes($this, $this->level->getTickRateTime() > 50 ? $this->boundingBox->offsetCopy($dx, $dy, $dz) : $this->boundingBox->addCoord($dx, $dy, $dz), false); foreach($list as $bb){ $dy = $bb->calculateYOffset($this->boundingBox, $dy); diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index a029c1d51e..201ed48b5d 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -256,12 +256,8 @@ class Level implements ChunkManager, Metadatable{ /** @var LevelTimings */ public $timings; - /** @var int */ - private $tickRate; /** @var int */ public $tickRateTime = 0; - /** @var int */ - public $tickRateCounter = 0; /** @var bool */ private $doingTick = false; @@ -401,21 +397,12 @@ class Level implements ChunkManager, Metadatable{ $this->timings = new LevelTimings($this); $this->temporalPosition = new Position(0, 0, 0, $this); $this->temporalVector = new Vector3(0, 0, 0); - $this->tickRate = 1; - } - - public function getTickRate() : int{ - return $this->tickRate; } public function getTickRateTime() : float{ return $this->tickRateTime; } - public function setTickRate(int $tickRate){ - $this->tickRate = $tickRate; - } - public function registerGeneratorToWorker(int $worker) : void{ $this->generatorRegisteredWorkers[$worker] = true; $this->server->getAsyncPool()->submitTaskToWorker(new GeneratorRegisterTask($this, $this->generator, $this->provider->getLevelData()->getGeneratorOptions()), $worker); diff --git a/src/pocketmine/level/LevelManager.php b/src/pocketmine/level/LevelManager.php index d0aff8a8ba..c44f82f4ce 100644 --- a/src/pocketmine/level/LevelManager.php +++ b/src/pocketmine/level/LevelManager.php @@ -40,11 +40,8 @@ use function array_shift; use function asort; use function assert; use function count; -use function floor; use function implode; -use function max; use function microtime; -use function min; use function random_int; use function round; use function sprintf; @@ -61,31 +58,17 @@ class LevelManager{ /** @var Server */ private $server; - /** @var bool */ - private $autoTickRate = true; - /** @var int */ - private $autoTickRateLimit = 20; - /** @var bool */ - private $alwaysTickPlayers = false; - /** @var int */ - private $baseTickRate = 1; /** @var bool */ private $autoSave = true; /** @var int */ private $autoSaveTicks = 6000; - /** @var int */ private $autoSaveTicker = 0; public function __construct(Server $server){ $this->server = $server; - $this->autoTickRate = (bool) $this->server->getProperty("level-settings.auto-tick-rate", $this->autoTickRate); - $this->autoTickRateLimit = (int) $this->server->getProperty("level-settings.auto-tick-rate-limit", $this->autoTickRateLimit); - $this->alwaysTickPlayers = (bool) $this->server->getProperty("level-settings.always-tick-players", $this->alwaysTickPlayers); - $this->baseTickRate = (int) $this->server->getProperty("level-settings.base-tick-rate", $this->baseTickRate); - $this->autoSave = $this->server->getConfigBool("auto-save", $this->autoSave); $this->autoSaveTicks = (int) $this->server->getProperty("ticks-per.autosave", 6000); } @@ -239,7 +222,6 @@ class LevelManager{ } $this->levels[$level->getId()] = $level; - $level->setTickRate($this->baseTickRate); $level->setAutoSave($this->autoSave); (new LevelLoadEvent($level))->call(); @@ -278,7 +260,6 @@ class LevelManager{ $level = new Level($this->server, $name, new $providerClass($path)); $this->levels[$level->getId()] = $level; - $level->setTickRate($this->baseTickRate); $level->setAutoSave($this->autoSave); (new LevelInitEvent($level))->call(); @@ -360,40 +341,11 @@ class LevelManager{ // Level unloaded during the tick of a level earlier in this loop, perhaps by plugin continue; } - if($level->getTickRate() > $this->baseTickRate and --$level->tickRateCounter > 0){ - if($this->alwaysTickPlayers){ - foreach($level->getPlayers() as $p){ - if($p->spawned){ - $p->onUpdate($currentTick); - } - } - } - continue; - } $levelTime = microtime(true); $level->doTick($currentTick); $tickMs = (microtime(true) - $levelTime) * 1000; $level->tickRateTime = $tickMs; - - if($this->autoTickRate){ - if($tickMs < 50 and $level->getTickRate() > $this->baseTickRate){ - $level->setTickRate($r = $level->getTickRate() - 1); - if($r > $this->baseTickRate){ - $level->tickRateCounter = $level->getTickRate(); - } - $this->server->getLogger()->debug("Raising world \"{$level->getDisplayName()}\" tick rate to {$level->getTickRate()} ticks"); - }elseif($tickMs >= 50){ - if($level->getTickRate() === $this->baseTickRate){ - $level->setTickRate(max($this->baseTickRate + 1, min($this->autoTickRateLimit, (int) floor($tickMs / 50)))); - $this->server->getLogger()->debug(sprintf("World \"%s\" took %gms, setting tick rate to %d ticks", $level->getDisplayName(), (int) round($tickMs, 2), $level->getTickRate())); - }elseif(($tickMs / $level->getTickRate()) >= 50 and $level->getTickRate() < $this->autoTickRateLimit){ - $level->setTickRate($level->getTickRate() + 1); - $this->server->getLogger()->debug(sprintf("World \"%s\" took %gms, setting tick rate to %d ticks", $level->getDisplayName(), (int) round($tickMs, 2), $level->getTickRate())); - } - $level->tickRateCounter = $level->getTickRate(); - } - } } if($this->autoSave and ++$this->autoSaveTicker >= $this->autoSaveTicks){ From c3e66e0adc1a0d5ccc2b48dc2ec44e51f5c5383d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Mar 2019 13:26:16 +0000 Subject: [PATCH 0587/3224] LevelManager: add debug message when a level takes too long to tick --- src/pocketmine/level/LevelManager.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pocketmine/level/LevelManager.php b/src/pocketmine/level/LevelManager.php index c44f82f4ce..f4d29b4c40 100644 --- a/src/pocketmine/level/LevelManager.php +++ b/src/pocketmine/level/LevelManager.php @@ -346,6 +346,9 @@ class LevelManager{ $level->doTick($currentTick); $tickMs = (microtime(true) - $levelTime) * 1000; $level->tickRateTime = $tickMs; + if($tickMs >= 50){ + $this->server->getLogger()->debug(sprintf("World \"%s\" took too long to tick: %gms (%g ticks)", $level->getDisplayName(), $tickMs, round($tickMs / 50, 2))); + } } if($this->autoSave and ++$this->autoSaveTicker >= $this->autoSaveTicks){ From 93cd00ae8ffdfe7f7959b5e2ca5ca20b59d54012 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Mar 2019 13:28:18 +0000 Subject: [PATCH 0588/3224] Remove dead settings from pocketmine.yml --- resources/pocketmine.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/resources/pocketmine.yml b/resources/pocketmine.yml index 342beb6429..368388004d 100644 --- a/resources/pocketmine.yml +++ b/resources/pocketmine.yml @@ -112,13 +112,6 @@ player: level-settings: #The default format that levels will use when created default-format: pmanvil - #Automatically change levels tick rate to maintain 20 ticks per second - auto-tick-rate: true - auto-tick-rate-limit: 20 - #Sets the base tick rate (1 = 20 ticks per second, 2 = 10 ticks per second, etc.) - base-tick-rate: 1 - #Tick all players each tick even when other settings disallow this. - always-tick-players: false chunk-sending: #To change server normal render distance, change view-distance in server.properties. From 6e00ab20698a5f87c244425908ec3fc2b31cffbf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Mar 2019 14:00:46 +0000 Subject: [PATCH 0589/3224] Chunk: add getNBTentities() and getNBTtiles() this shit is horrible, but it's needed for now... --- src/pocketmine/level/format/Chunk.php | 15 +++++++++++++++ .../level/format/io/leveldb/LevelDB.php | 15 ++------------- .../format/io/region/LegacyAnvilChunkTrait.php | 16 ++-------------- .../level/format/io/region/McRegion.php | 16 ++-------------- 4 files changed, 21 insertions(+), 41 deletions(-) diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index 948516e945..f8796afb80 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -38,6 +38,7 @@ use pocketmine\tile\TileFactory; use pocketmine\utils\BinaryStream; use function array_fill; use function array_filter; +use function array_map; use function array_values; use function assert; use function chr; @@ -590,6 +591,20 @@ class Chunk{ } } + /** + * @return CompoundTag[] + */ + public function getNBTtiles() : array{ + return $this->NBTtiles ?? array_map(function(Tile $tile) : CompoundTag{ return $tile->saveNBT(); }, $this->tiles); + } + + /** + * @return CompoundTag[] + */ + public function getNBTentities() : array{ + return $this->NBTentities ?? array_map(function(Entity $entity) : CompoundTag{ return $entity->saveNBT(); }, $this->getSavableEntities()); + } + /** * Deserializes tiles and entities from NBT * diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index 069692c7cf..cd91e59fc4 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -343,19 +343,8 @@ class LevelDB extends BaseLevelProvider{ //TODO: use this properly $this->db->put($index . self::TAG_STATE_FINALISATION, chr(self::FINALISATION_DONE)); - /** @var CompoundTag[] $tiles */ - $tiles = []; - foreach($chunk->getTiles() as $tile){ - $tiles[] = $tile->saveNBT(); - } - $this->writeTags($tiles, $index . self::TAG_BLOCK_ENTITY); - - /** @var CompoundTag[] $entities */ - $entities = []; - foreach($chunk->getSavableEntities() as $entity){ - $entities[] = $entity->saveNBT(); - } - $this->writeTags($entities, $index . self::TAG_ENTITY); + $this->writeTags($chunk->getNBTtiles(), $index . self::TAG_BLOCK_ENTITY); + $this->writeTags($chunk->getNBTentities(), $index . self::TAG_ENTITY); $this->db->delete($index . self::TAG_DATA_2D_LEGACY); $this->db->delete($index . self::TAG_LEGACY_TERRAIN); diff --git a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php b/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php index 3d68f5f6c2..e10e6eb287 100644 --- a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php @@ -73,20 +73,8 @@ trait LegacyAnvilChunkTrait{ $nbt->setByteArray("Biomes", $chunk->getBiomeIdArray()); $nbt->setIntArray("HeightMap", $chunk->getHeightMapArray()); - $entities = []; - - foreach($chunk->getSavableEntities() as $entity){ - $entities[] = $entity->saveNBT(); - } - - $nbt->setTag(new ListTag("Entities", $entities, NBT::TAG_Compound)); - - $tiles = []; - foreach($chunk->getTiles() as $tile){ - $tiles[] = $tile->saveNBT(); - } - - $nbt->setTag(new ListTag("TileEntities", $tiles, NBT::TAG_Compound)); + $nbt->setTag(new ListTag("Entities", $chunk->getNBTentities(), NBT::TAG_Compound)); + $nbt->setTag(new ListTag("TileEntities", $chunk->getNBTtiles(), NBT::TAG_Compound)); //TODO: TileTicks diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index 277e6ff893..b4047ce96d 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -81,20 +81,8 @@ class McRegion extends RegionLevelProvider{ $nbt->setByteArray("Biomes", $chunk->getBiomeIdArray()); //doesn't exist in regular McRegion, this is here for PocketMine-MP only $nbt->setByteArray("HeightMap", pack("C*", ...$chunk->getHeightMapArray())); //this is ByteArray in McRegion, but IntArray in Anvil (due to raised build height) - $entities = []; - - foreach($chunk->getSavableEntities() as $entity){ - $entities[] = $entity->saveNBT(); - } - - $nbt->setTag(new ListTag("Entities", $entities, NBT::TAG_Compound)); - - $tiles = []; - foreach($chunk->getTiles() as $tile){ - $tiles[] = $tile->saveNBT(); - } - - $nbt->setTag(new ListTag("TileEntities", $tiles, NBT::TAG_Compound)); + $nbt->setTag(new ListTag("Entities", $chunk->getNBTentities(), NBT::TAG_Compound)); + $nbt->setTag(new ListTag("TileEntities", $chunk->getNBTtiles(), NBT::TAG_Compound)); $writer = new BigEndianNbtSerializer(); return $writer->writeCompressed(new CompoundTag("", [$nbt]), ZLIB_ENCODING_DEFLATE, RegionLoader::$COMPRESSION_LEVEL); From 1bb9b3d3ab56536efc71e453737f240248ca86ad Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Mar 2019 16:22:44 +0000 Subject: [PATCH 0590/3224] Discard light information from disk storage this makes world conversion faster and offers the opportunity to correct age-old lighting bugs. --- src/pocketmine/level/Level.php | 2 +- .../level/format/io/leveldb/LevelDB.php | 50 +++++-------------- .../level/format/io/region/Anvil.php | 10 ++-- .../io/region/LegacyAnvilChunkTrait.php | 9 ++-- .../level/format/io/region/McRegion.php | 42 +++------------- .../level/format/io/region/PMAnvil.php | 9 ++-- 6 files changed, 33 insertions(+), 89 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 201ed48b5d..f5c51f9c14 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -2663,7 +2663,7 @@ class Level implements ChunkManager, Metadatable{ (new ChunkLoadEvent($this, $chunk, !$chunk->isGenerated()))->call(); - if(!$chunk->isLightPopulated() and $chunk->isPopulated() and $this->getServer()->getProperty("chunk-ticking.light-updates", false)){ + if($chunk->isPopulated() and $this->getServer()->getProperty("chunk-ticking.light-updates", false)){ $this->getServer()->getAsyncPool()->submitTask(new LightPopulationTask($this, $chunk)); } diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index cd91e59fc4..e6a60d4d61 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -46,7 +46,7 @@ use function file_exists; use function is_dir; use function mkdir; use function ord; -use function pack; +use function str_repeat; use function strlen; use function substr; use function unpack; @@ -146,14 +146,9 @@ class LevelDB extends BaseLevelProvider{ /** @var SubChunk[] $subChunks */ $subChunks = []; - /** @var int[] $heightMap */ - $heightMap = []; /** @var string $biomeIds */ $biomeIds = ""; - /** @var bool $lightPopulated */ - $lightPopulated = true; - $chunkVersion = ord($this->db->get($index . self::TAG_VERSION)); $binaryStream = new BinaryStream(); @@ -179,20 +174,15 @@ class LevelDB extends BaseLevelProvider{ try{ $blocks = $binaryStream->get(4096); $blockData = $binaryStream->get(2048); + if($chunkVersion < 4){ - $blockSkyLight = $binaryStream->get(2048); - $blockLight = $binaryStream->get(2048); - }else{ - //Mojang didn't bother changing the subchunk version when they stopped saving sky light -_- - $blockSkyLight = ""; - $blockLight = ""; - $lightPopulated = false; + $binaryStream->get(4096); //legacy light info, discard it } }catch(BinaryDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } - $subChunks[$y] = new SubChunk($blocks, $blockData, $blockSkyLight, $blockLight); + $subChunks[$y] = new SubChunk($blocks, $blockData); break; default: //TODO: set chunks read-only so the version on disk doesn't get overwritten @@ -204,7 +194,7 @@ class LevelDB extends BaseLevelProvider{ $binaryStream->setBuffer($maps2d); try{ - $heightMap = array_values(unpack("v*", $binaryStream->get(512))); + $binaryStream->get(512); //heightmap, discard it $biomeIds = $binaryStream->get(256); }catch(BinaryDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); @@ -220,8 +210,7 @@ class LevelDB extends BaseLevelProvider{ try{ $fullIds = $binaryStream->get(32768); $fullData = $binaryStream->get(16384); - $fullSkyLight = $binaryStream->get(16384); - $fullBlockLight = $binaryStream->get(16384); + $binaryStream->get(32768); //legacy light info, discard it }catch(BinaryDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } @@ -239,23 +228,12 @@ class LevelDB extends BaseLevelProvider{ $data .= substr($fullData, $subOffset, 8); $subOffset += 64; } - $skyLight = ""; - $subOffset = ($yy << 3); - for($i = 0; $i < 256; ++$i){ - $skyLight .= substr($fullSkyLight, $subOffset, 8); - $subOffset += 64; - } - $blockLight = ""; - $subOffset = ($yy << 3); - for($i = 0; $i < 256; ++$i){ - $blockLight .= substr($fullBlockLight, $subOffset, 8); - $subOffset += 64; - } - $subChunks[$yy] = new SubChunk($ids, $data, $skyLight, $blockLight); + + $subChunks[$yy] = new SubChunk($ids, $data); } try{ - $heightMap = array_values(unpack("C*", $binaryStream->get(256))); + $binaryStream->get(256); //heightmap, discard it $biomeIds = ChunkUtils::convertBiomeColors(array_values(unpack("N*", $binaryStream->get(1024)))); }catch(BinaryDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); @@ -307,15 +285,13 @@ class LevelDB extends BaseLevelProvider{ $subChunks, $entities, $tiles, - $biomeIds, - $heightMap + $biomeIds ); //TODO: tile ticks, biome states (?) - $chunk->setGenerated(true); - $chunk->setPopulated(true); - $chunk->setLightPopulated($lightPopulated); + $chunk->setGenerated(); + $chunk->setPopulated(); return $chunk; } @@ -338,7 +314,7 @@ class LevelDB extends BaseLevelProvider{ } } - $this->db->put($index . self::TAG_DATA_2D, pack("v*", ...$chunk->getHeightMapArray()) . $chunk->getBiomeIdArray()); + $this->db->put($index . self::TAG_DATA_2D, str_repeat("\x00", 512) . $chunk->getBiomeIdArray()); //TODO: use this properly $this->db->put($index . self::TAG_STATE_FINALISATION, chr(self::FINALISATION_DONE)); diff --git a/src/pocketmine/level/format/io/region/Anvil.php b/src/pocketmine/level/format/io/region/Anvil.php index b5fc667188..998b41840e 100644 --- a/src/pocketmine/level/format/io/region/Anvil.php +++ b/src/pocketmine/level/format/io/region/Anvil.php @@ -27,6 +27,7 @@ use pocketmine\level\format\io\ChunkUtils; use pocketmine\level\format\SubChunk; use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\CompoundTag; +use function str_repeat; class Anvil extends RegionLevelProvider{ use LegacyAnvilChunkTrait; @@ -35,17 +36,16 @@ class Anvil extends RegionLevelProvider{ return new CompoundTag("", [ new ByteArrayTag("Blocks", ChunkUtils::reorderByteArray($subChunk->getBlockIdArray())), //Generic in-memory chunks are currently always XZY new ByteArrayTag("Data", ChunkUtils::reorderNibbleArray($subChunk->getBlockDataArray())), - new ByteArrayTag("SkyLight", ChunkUtils::reorderNibbleArray($subChunk->getBlockSkyLightArray(), "\xff")), - new ByteArrayTag("BlockLight", ChunkUtils::reorderNibbleArray($subChunk->getBlockLightArray())) + new ByteArrayTag("SkyLight", str_repeat("\x00", 2048)), + new ByteArrayTag("BlockLight", str_repeat("\x00", 2048)) ]); } protected function deserializeSubChunk(CompoundTag $subChunk) : SubChunk{ return new SubChunk( ChunkUtils::reorderByteArray($subChunk->getByteArray("Blocks")), - ChunkUtils::reorderNibbleArray($subChunk->getByteArray("Data")), - ChunkUtils::reorderNibbleArray($subChunk->getByteArray("SkyLight"), "\xff"), - ChunkUtils::reorderNibbleArray($subChunk->getByteArray("BlockLight")) + ChunkUtils::reorderNibbleArray($subChunk->getByteArray("Data")) + //ignore legacy light information ); } diff --git a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php b/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php index e10e6eb287..fc2ac45d0e 100644 --- a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php @@ -33,6 +33,7 @@ use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntArrayTag; use pocketmine\nbt\tag\ListTag; +use function array_fill; /** * Trait containing I/O methods for handling legacy Anvil-style chunks. @@ -56,7 +57,7 @@ trait LegacyAnvilChunkTrait{ $nbt->setLong("LastUpdate", 0); //TODO $nbt->setLong("InhabitedTime", 0); //TODO $nbt->setByte("TerrainPopulated", $chunk->isPopulated() ? 1 : 0); - $nbt->setByte("LightPopulated", $chunk->isLightPopulated() ? 1 : 0); + $nbt->setByte("LightPopulated", 0); $subChunks = []; foreach($chunk->getSubChunks() as $y => $subChunk){ @@ -71,7 +72,7 @@ trait LegacyAnvilChunkTrait{ $nbt->setTag(new ListTag("Sections", $subChunks, NBT::TAG_Compound)); $nbt->setByteArray("Biomes", $chunk->getBiomeIdArray()); - $nbt->setIntArray("HeightMap", $chunk->getHeightMapArray()); + $nbt->setIntArray("HeightMap", array_fill(0, 256, 0)); $nbt->setTag(new ListTag("Entities", $chunk->getNBTentities(), NBT::TAG_Compound)); $nbt->setTag(new ListTag("TileEntities", $chunk->getNBTtiles(), NBT::TAG_Compound)); @@ -123,10 +124,8 @@ trait LegacyAnvilChunkTrait{ $subChunks, $chunk->hasTag("Entities", ListTag::class) ? $chunk->getListTag("Entities")->getValue() : [], $chunk->hasTag("TileEntities", ListTag::class) ? $chunk->getListTag("TileEntities")->getValue() : [], - $biomeIds, - $chunk->getIntArray("HeightMap", []) + $biomeIds ); - $result->setLightPopulated($chunk->getByte("LightPopulated", 0) !== 0); $result->setPopulated($chunk->getByte("TerrainPopulated", 0) !== 0); $result->setGenerated(); return $result; diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index b4047ce96d..11aef62797 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -34,11 +34,8 @@ use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntArrayTag; use pocketmine\nbt\tag\ListTag; -use function array_values; -use function pack; use function str_repeat; use function substr; -use function unpack; class McRegion extends RegionLevelProvider{ @@ -54,12 +51,10 @@ class McRegion extends RegionLevelProvider{ $nbt->setLong("LastUpdate", 0); //TODO $nbt->setByte("TerrainPopulated", $chunk->isPopulated() ? 1 : 0); - $nbt->setByte("LightPopulated", $chunk->isLightPopulated() ? 1 : 0); + $nbt->setByte("LightPopulated", 0); $ids = ""; $data = ""; - $skyLight = ""; - $blockLight = ""; $subChunks = $chunk->getSubChunks(); for($x = 0; $x < 16; ++$x){ for($z = 0; $z < 16; ++$z){ @@ -67,19 +62,17 @@ class McRegion extends RegionLevelProvider{ $subChunk = $subChunks[$y]; $ids .= substr($subChunk->getBlockIdArray(), ($x << 8) | ($z << 4), 16); $data .= substr($subChunk->getBlockDataArray(), ($x << 7) | ($z << 3), 8); - $skyLight .= substr($subChunk->getBlockSkyLightArray(), ($x << 7) | ($z << 3), 8); - $blockLight .= substr($subChunk->getBlockLightArray(), ($x << 7) | ($z << 3), 8); } } } $nbt->setByteArray("Blocks", $ids); $nbt->setByteArray("Data", $data); - $nbt->setByteArray("SkyLight", $skyLight); - $nbt->setByteArray("BlockLight", $blockLight); + $nbt->setByteArray("SkyLight", str_repeat("\x00", 16384)); + $nbt->setByteArray("BlockLight", str_repeat("\x00", 16384)); $nbt->setByteArray("Biomes", $chunk->getBiomeIdArray()); //doesn't exist in regular McRegion, this is here for PocketMine-MP only - $nbt->setByteArray("HeightMap", pack("C*", ...$chunk->getHeightMapArray())); //this is ByteArray in McRegion, but IntArray in Anvil (due to raised build height) + $nbt->setByteArray("HeightMap", str_repeat("\x00", 256)); //this is ByteArray in McRegion, but IntArray in Anvil (due to raised build height) $nbt->setTag(new ListTag("Entities", $chunk->getNBTentities(), NBT::TAG_Compound)); $nbt->setTag(new ListTag("TileEntities", $chunk->getNBTtiles(), NBT::TAG_Compound)); @@ -110,8 +103,6 @@ class McRegion extends RegionLevelProvider{ $subChunks = []; $fullIds = $chunk->hasTag("Blocks", ByteArrayTag::class) ? $chunk->getByteArray("Blocks") : str_repeat("\x00", 32768); $fullData = $chunk->hasTag("Data", ByteArrayTag::class) ? $chunk->getByteArray("Data") : str_repeat("\x00", 16384); - $fullSkyLight = $chunk->hasTag("SkyLight", ByteArrayTag::class) ? $chunk->getByteArray("SkyLight") : str_repeat("\xff", 16384); - $fullBlockLight = $chunk->hasTag("BlockLight", ByteArrayTag::class) ? $chunk->getByteArray("BlockLight") : str_repeat("\x00", 16384); for($y = 0; $y < 8; ++$y){ $offset = ($y << 4); @@ -126,19 +117,7 @@ class McRegion extends RegionLevelProvider{ $data .= substr($fullData, $offset, 8); $offset += 64; } - $skyLight = ""; - $offset = ($y << 3); - for($i = 0; $i < 256; ++$i){ - $skyLight .= substr($fullSkyLight, $offset, 8); - $offset += 64; - } - $blockLight = ""; - $offset = ($y << 3); - for($i = 0; $i < 256; ++$i){ - $blockLight .= substr($fullBlockLight, $offset, 8); - $offset += 64; - } - $subChunks[$y] = new SubChunk($ids, $data, $skyLight, $blockLight); + $subChunks[$y] = new SubChunk($ids, $data); } if($chunk->hasTag("BiomeColors", IntArrayTag::class)){ @@ -149,23 +128,14 @@ class McRegion extends RegionLevelProvider{ $biomeIds = ""; } - $heightMap = []; - if($chunk->hasTag("HeightMap", ByteArrayTag::class)){ - $heightMap = array_values(unpack("C*", $chunk->getByteArray("HeightMap"))); - }elseif($chunk->hasTag("HeightMap", IntArrayTag::class)){ - $heightMap = $chunk->getIntArray("HeightMap"); #blameshoghicp - } - $result = new Chunk( $chunk->getInt("xPos"), $chunk->getInt("zPos"), $subChunks, $chunk->hasTag("Entities", ListTag::class) ? $chunk->getListTag("Entities")->getValue() : [], $chunk->hasTag("TileEntities", ListTag::class) ? $chunk->getListTag("TileEntities")->getValue() : [], - $biomeIds, - $heightMap + $biomeIds ); - $result->setLightPopulated($chunk->getByte("LightPopulated", 0) !== 0); $result->setPopulated($chunk->getByte("TerrainPopulated", 0) !== 0); $result->setGenerated(true); return $result; diff --git a/src/pocketmine/level/format/io/region/PMAnvil.php b/src/pocketmine/level/format/io/region/PMAnvil.php index 84ab25ac79..566a5b82e0 100644 --- a/src/pocketmine/level/format/io/region/PMAnvil.php +++ b/src/pocketmine/level/format/io/region/PMAnvil.php @@ -26,6 +26,7 @@ namespace pocketmine\level\format\io\region; use pocketmine\level\format\SubChunk; use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\CompoundTag; +use function str_repeat; /** * This format is exactly the same as the PC Anvil format, with the only difference being that the stored data order @@ -38,17 +39,15 @@ class PMAnvil extends RegionLevelProvider{ return new CompoundTag("", [ new ByteArrayTag("Blocks", $subChunk->getBlockIdArray()), new ByteArrayTag("Data", $subChunk->getBlockDataArray()), - new ByteArrayTag("SkyLight", $subChunk->getBlockSkyLightArray()), - new ByteArrayTag("BlockLight", $subChunk->getBlockLightArray()) + new ByteArrayTag("SkyLight", str_repeat("\x00", 2048)), + new ByteArrayTag("BlockLight", str_repeat("\x00", 2048)) ]); } protected function deserializeSubChunk(CompoundTag $subChunk) : SubChunk{ return new SubChunk( $subChunk->getByteArray("Blocks"), - $subChunk->getByteArray("Data"), - $subChunk->getByteArray("SkyLight"), - $subChunk->getByteArray("BlockLight") + $subChunk->getByteArray("Data") ); } From 3509b267514df467473f683d1d8dc24a7bcf798e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Mar 2019 17:32:57 +0000 Subject: [PATCH 0591/3224] LevelProvider: added calculateChunkCount() this will be used to provide progress information to the user during world conversion. --- .../level/format/io/LevelProvider.php | 6 ++++++ .../level/format/io/leveldb/LevelDB.php | 10 ++++++++++ .../format/io/region/RegionLevelProvider.php | 17 +++++++++++++++-- .../level/format/io/region/RegionLoader.php | 10 ++++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/level/format/io/LevelProvider.php b/src/pocketmine/level/format/io/LevelProvider.php index 975ea71436..4a7e089e9a 100644 --- a/src/pocketmine/level/format/io/LevelProvider.php +++ b/src/pocketmine/level/format/io/LevelProvider.php @@ -111,4 +111,10 @@ interface LevelProvider{ */ public function getAllChunks() : \Generator; + /** + * Returns the number of chunks in the provider. Used for world conversion time estimations. + * + * @return int + */ + public function calculateChunkCount() : int; } diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index e6a60d4d61..2c7b6e3855 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -373,4 +373,14 @@ class LevelDB extends BaseLevelProvider{ } } } + + public function calculateChunkCount() : int{ + $count = 0; + foreach($this->db->getIterator() as $key => $_){ + if(strlen($key) === 9 and substr($key, -1) === self::TAG_VERSION){ + $count++; + } + } + return $count; + } } diff --git a/src/pocketmine/level/format/io/region/RegionLevelProvider.php b/src/pocketmine/level/format/io/region/RegionLevelProvider.php index 3874e960f7..671cedb02c 100644 --- a/src/pocketmine/level/format/io/region/RegionLevelProvider.php +++ b/src/pocketmine/level/format/io/region/RegionLevelProvider.php @@ -208,8 +208,8 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ $this->getRegion($regionX, $regionZ)->writeChunk($chunkX & 0x1f, $chunkZ & 0x1f, $this->serializeChunk($chunk)); } - public function getAllChunks() : \Generator{ - $iterator = new \RegexIterator( + private function createRegionIterator() : \RegexIterator{ + return new \RegexIterator( new \FilesystemIterator( $this->path . '/region/', \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS @@ -217,6 +217,10 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ '/\/r\.(-?\d+)\.(-?\d+)\.' . static::getRegionFileExtension() . '$/', \RegexIterator::GET_MATCH ); + } + + public function getAllChunks() : \Generator{ + $iterator = $this->createRegionIterator(); foreach($iterator as $region){ $rX = ((int) $region[1]) << 5; @@ -232,4 +236,13 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ } } } + + public function calculateChunkCount() : int{ + $count = 0; + foreach($this->createRegionIterator() as $region){ + $this->loadRegion((int) $region[1], (int) $region[2]); + $count += $this->getRegion((int) $region[1], (int) $region[2])->calculateChunkCount(); + } + return $count; + } } diff --git a/src/pocketmine/level/format/io/region/RegionLoader.php b/src/pocketmine/level/format/io/region/RegionLoader.php index b606267ddb..12d7750f6b 100644 --- a/src/pocketmine/level/format/io/region/RegionLoader.php +++ b/src/pocketmine/level/format/io/region/RegionLoader.php @@ -289,4 +289,14 @@ class RegionLoader{ public function getFilePath() : string{ return $this->filePath; } + + public function calculateChunkCount() : int{ + $count = 0; + for($i = 0; $i < 1024; ++$i){ + if($this->isChunkGenerated($i)){ + $count++; + } + } + return $count; + } } From f5dbbea5f5978522120376deeeebe4ea1d76c6b9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Mar 2019 17:39:13 +0000 Subject: [PATCH 0592/3224] Utils: added recursiveUnlink() --- src/pocketmine/utils/Utils.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/pocketmine/utils/Utils.php b/src/pocketmine/utils/Utils.php index 4527e8973a..0757a282ea 100644 --- a/src/pocketmine/utils/Utils.php +++ b/src/pocketmine/utils/Utils.php @@ -54,6 +54,8 @@ use function gettype; use function hexdec; use function implode; use function is_array; +use function is_dir; +use function is_file; use function is_object; use function is_readable; use function is_string; @@ -73,6 +75,8 @@ use function preg_match_all; use function preg_replace; use function proc_close; use function proc_open; +use function rmdir; +use function scandir; use function sha1; use function spl_object_hash; use function str_pad; @@ -87,11 +91,13 @@ use function strval; use function substr; use function sys_get_temp_dir; use function trim; +use function unlink; use function xdebug_get_function_stack; use const PHP_EOL; use const PHP_INT_MAX; use const PHP_INT_SIZE; use const PHP_MAXPATHLEN; +use const SCANDIR_SORT_NONE; use const STR_PAD_LEFT; use const STR_PAD_RIGHT; @@ -664,4 +670,22 @@ class Utils{ throw new \TypeError("Declaration of callable `" . CallbackType::createFromCallable($subject) . "` must be compatible with `" . $sigType . "`"); } } + + public static function recursiveUnlink(string $dir) : void{ + if(is_dir($dir)){ + $objects = scandir($dir, SCANDIR_SORT_NONE); + foreach($objects as $object){ + if($object !== "." and $object !== ".."){ + if(is_dir($dir . "/" . $object)){ + self::recursiveUnlink($dir . "/" . $object); + }else{ + unlink($dir . "/" . $object); + } + } + } + rmdir($dir); + }elseif(is_file($dir)){ + unlink($dir); + } + } } From 54ef965b2ad5307729cb615b18f43d025c8858f3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Mar 2019 18:02:34 +0000 Subject: [PATCH 0593/3224] Added warnings when unknown entities and tiles are removed --- src/pocketmine/level/format/Chunk.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index f8796afb80..f271c31769 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -620,6 +620,7 @@ class Chunk{ try{ $entity = EntityFactory::createFromData($level, $nbt); if(!($entity instanceof Entity)){ + $level->getServer()->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown entity type " . $nbt->getString("id", "", true)); $changed = true; continue; } @@ -638,6 +639,7 @@ class Chunk{ if(($tile = TileFactory::createFromData($level, $nbt)) !== null){ $level->addTile($tile); }else{ + $level->getServer()->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown tile entity type " . $nbt->getString("id", "", true)); $changed = true; continue; } From f83e5c195c9ba250a08b2c98bd97158a70320154 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Mar 2019 18:26:05 +0000 Subject: [PATCH 0594/3224] fixed tiles and entities not getting saved on fast-deserialized chunks --- src/pocketmine/level/format/Chunk.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index f271c31769..094205db79 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -107,7 +107,7 @@ class Chunk{ * @param string $biomeIds * @param int[] $heightMap */ - public function __construct(int $chunkX, int $chunkZ, array $subChunks = [], array $entities = [], array $tiles = [], string $biomeIds = "", array $heightMap = []){ + public function __construct(int $chunkX, int $chunkZ, array $subChunks = [], ?array $entities = null, ?array $tiles = null, string $biomeIds = "", array $heightMap = []){ $this->x = $chunkX; $this->z = $chunkZ; @@ -875,7 +875,7 @@ class Chunk{ } } - $chunk = new Chunk($x, $z, $subChunks, [], [], $biomeIds, $heightMap); + $chunk = new Chunk($x, $z, $subChunks, null, null, $biomeIds, $heightMap); $chunk->setGenerated($terrainGenerated); $chunk->setPopulated($terrainPopulated); $chunk->setLightPopulated($lightPopulated); From 5017e61cb2ef839231330b60f084044d81cea11f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Mar 2019 21:12:52 +0000 Subject: [PATCH 0595/3224] ItemFrame: fixed cloning null --- src/pocketmine/block/ItemFrame.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 16800a6431..264914fe02 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -99,7 +99,7 @@ class ItemFrame extends Flowable{ * @return Item|null */ public function getFramedItem() : ?Item{ - return clone $this->framedItem; + return $this->framedItem !== null ? clone $this->framedItem : null; } /** From 2cad7166b1df41eac9ee7fcbb5065ac037015473 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Mar 2019 09:30:22 +0000 Subject: [PATCH 0596/3224] GeneratorManager::getGeneratorName() now throws InvalidArgumentException on unregistered generator classes the old behaviour allowed a bug in the world converter to go unnoticed. --- src/pocketmine/level/generator/GeneratorManager.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/level/generator/GeneratorManager.php b/src/pocketmine/level/generator/GeneratorManager.php index fbf8fb5327..edd38d599c 100644 --- a/src/pocketmine/level/generator/GeneratorManager.php +++ b/src/pocketmine/level/generator/GeneratorManager.php @@ -91,6 +91,7 @@ final class GeneratorManager{ * @param string $class Fully qualified name of class that extends \pocketmine\level\generator\Generator * * @return string + * @throws \InvalidArgumentException if the class type cannot be matched to a known alias */ public static function getGeneratorName(string $class) : string{ foreach(self::$list as $name => $c){ @@ -99,7 +100,7 @@ final class GeneratorManager{ } } - return "unknown"; + throw new \InvalidArgumentException("Generator class $class is not registered"); } private function __construct(){ From 2795ad674b08d9d2255580fc7dc1cb2b3c14e661 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Mar 2019 09:36:22 +0000 Subject: [PATCH 0597/3224] add boilerplate code to check for generator validity perhaps we should use an enum for this...? --- src/pocketmine/level/format/io/data/BedrockLevelData.php | 3 +++ src/pocketmine/level/format/io/data/JavaLevelData.php | 3 +++ src/pocketmine/level/format/io/leveldb/LevelDB.php | 3 +++ src/pocketmine/level/format/io/region/RegionLevelProvider.php | 3 +++ src/pocketmine/level/generator/GeneratorManager.php | 1 + 5 files changed, 13 insertions(+) diff --git a/src/pocketmine/level/format/io/data/BedrockLevelData.php b/src/pocketmine/level/format/io/data/BedrockLevelData.php index 946f284a47..7f8025af74 100644 --- a/src/pocketmine/level/format/io/data/BedrockLevelData.php +++ b/src/pocketmine/level/format/io/data/BedrockLevelData.php @@ -25,6 +25,7 @@ namespace pocketmine\level\format\io\data; use pocketmine\level\format\io\exception\UnsupportedLevelFormatException; use pocketmine\level\generator\Flat; +use pocketmine\level\generator\Generator; use pocketmine\level\generator\GeneratorManager; use pocketmine\level\Level; use pocketmine\nbt\LittleEndianNbtSerializer; @@ -36,6 +37,7 @@ use pocketmine\nbt\tag\LongTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\utils\Binary; +use pocketmine\utils\Utils; use function file_get_contents; use function file_put_contents; use function strlen; @@ -51,6 +53,7 @@ class BedrockLevelData extends BaseNbtLevelData{ public const GENERATOR_FLAT = 2; public static function generate(string $path, string $name, int $seed, string $generator, array $options = []) : void{ + Utils::testValidInstance($generator, Generator::class); switch($generator){ case Flat::class: $generatorType = self::GENERATOR_FLAT; diff --git a/src/pocketmine/level/format/io/data/JavaLevelData.php b/src/pocketmine/level/format/io/data/JavaLevelData.php index 893d7cef0a..ac1aa39f23 100644 --- a/src/pocketmine/level/format/io/data/JavaLevelData.php +++ b/src/pocketmine/level/format/io/data/JavaLevelData.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\level\format\io\data; +use pocketmine\level\generator\Generator; use pocketmine\level\generator\GeneratorManager; use pocketmine\level\Level; use pocketmine\nbt\BigEndianNbtSerializer; @@ -32,6 +33,7 @@ use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\LongTag; use pocketmine\nbt\tag\StringTag; +use pocketmine\utils\Utils; use function ceil; use function file_get_contents; use function file_put_contents; @@ -40,6 +42,7 @@ use function microtime; class JavaLevelData extends BaseNbtLevelData{ public static function generate(string $path, string $name, int $seed, string $generator, array $options = [], int $version = 19133) : void{ + Utils::testValidInstance($generator, Generator::class); //TODO, add extra details $levelData = new CompoundTag("Data", [ new ByteTag("hardcore", ($options["hardcore"] ?? false) === true ? 1 : 0), diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index 2c7b6e3855..c15098de85 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -32,12 +32,14 @@ use pocketmine\level\format\io\exception\UnsupportedChunkFormatException; use pocketmine\level\format\io\exception\UnsupportedLevelFormatException; use pocketmine\level\format\io\LevelData; use pocketmine\level\format\SubChunk; +use pocketmine\level\generator\Generator; use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\utils\Binary; use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; +use pocketmine\utils\Utils; use function array_values; use function chr; use function defined; @@ -119,6 +121,7 @@ class LevelDB extends BaseLevelProvider{ } public static function generate(string $path, string $name, int $seed, string $generator, array $options = []) : void{ + Utils::testValidInstance($generator, Generator::class); self::checkForLevelDBExtension(); if(!file_exists($path . "/db")){ diff --git a/src/pocketmine/level/format/io/region/RegionLevelProvider.php b/src/pocketmine/level/format/io/region/RegionLevelProvider.php index 671cedb02c..2a356ec131 100644 --- a/src/pocketmine/level/format/io/region/RegionLevelProvider.php +++ b/src/pocketmine/level/format/io/region/RegionLevelProvider.php @@ -28,7 +28,9 @@ use pocketmine\level\format\io\BaseLevelProvider; use pocketmine\level\format\io\data\JavaLevelData; use pocketmine\level\format\io\exception\CorruptedChunkException; use pocketmine\level\format\io\LevelData; +use pocketmine\level\generator\Generator; use pocketmine\level\Level; +use pocketmine\utils\Utils; use function assert; use function file_exists; use function is_dir; @@ -69,6 +71,7 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ } public static function generate(string $path, string $name, int $seed, string $generator, array $options = []) : void{ + Utils::testValidInstance($generator, Generator::class); if(!file_exists($path)){ mkdir($path, 0777, true); } diff --git a/src/pocketmine/level/generator/GeneratorManager.php b/src/pocketmine/level/generator/GeneratorManager.php index edd38d599c..ee61cecd08 100644 --- a/src/pocketmine/level/generator/GeneratorManager.php +++ b/src/pocketmine/level/generator/GeneratorManager.php @@ -94,6 +94,7 @@ final class GeneratorManager{ * @throws \InvalidArgumentException if the class type cannot be matched to a known alias */ public static function getGeneratorName(string $class) : string{ + Utils::testValidInstance($class, Generator::class); foreach(self::$list as $name => $c){ if($c === $class){ return $name; From 07a9c35ee29a9aedde6bbc603cc6b47d0e798ffc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Mar 2019 13:10:17 +0000 Subject: [PATCH 0598/3224] RegionLoader: Use objects instead of arrays --- .../level/format/io/region/RegionLoader.php | 72 +++++++------- .../io/region/RegionLocationTableEntry.php | 98 +++++++++++++++++++ 2 files changed, 133 insertions(+), 37 deletions(-) create mode 100644 src/pocketmine/level/format/io/region/RegionLocationTableEntry.php diff --git a/src/pocketmine/level/format/io/region/RegionLoader.php b/src/pocketmine/level/format/io/region/RegionLoader.php index 3bf7acedb8..7e8662b5ff 100644 --- a/src/pocketmine/level/format/io/region/RegionLoader.php +++ b/src/pocketmine/level/format/io/region/RegionLoader.php @@ -26,7 +26,6 @@ namespace pocketmine\level\format\io\region; use pocketmine\level\format\ChunkException; use pocketmine\level\format\io\exception\CorruptedChunkException; use pocketmine\utils\Binary; -use function array_fill; use function ceil; use function chr; use function fclose; @@ -39,6 +38,7 @@ use function fseek; use function ftruncate; use function fwrite; use function is_resource; +use function max; use function ord; use function pack; use function str_pad; @@ -66,7 +66,7 @@ class RegionLoader{ protected $filePointer; /** @var int */ protected $lastSector; - /** @var int[][] [offset in sectors, chunk size in sectors, timestamp] */ + /** @var RegionLocationTableEntry[] */ protected $locationTable = []; /** @var int */ public $lastUsed = 0; @@ -106,7 +106,7 @@ class RegionLoader{ } protected function isChunkGenerated(int $index) : bool{ - return !($this->locationTable[$index][0] === 0 or $this->locationTable[$index][1] === 0); + return !$this->locationTable[$index]->isNull(); } /** @@ -126,23 +126,25 @@ class RegionLoader{ return null; } - fseek($this->filePointer, $this->locationTable[$index][0] << 12); + fseek($this->filePointer, $this->locationTable[$index]->getFirstSector() << 12); + $prefix = fread($this->filePointer, 4); if($prefix === false or strlen($prefix) !== 4){ throw new CorruptedChunkException("Corrupted chunk header detected (unexpected end of file reading length prefix)"); } $length = Binary::readInt($prefix); - if($length <= 0 or $length > self::MAX_SECTOR_LENGTH){ //Not yet generated / corrupted - if($length >= self::MAX_SECTOR_LENGTH){ - throw new CorruptedChunkException("Corrupted chunk header detected (sector count $length larger than max " . self::MAX_SECTOR_LENGTH . ")"); - } + if($length <= 0){ //TODO: if we reached here, the locationTable probably needs updating return null; } + if($length > self::MAX_SECTOR_LENGTH){ //corrupted + throw new CorruptedChunkException("Length for chunk x=$x,z=$z ($length) is larger than maximum " . self::MAX_SECTOR_LENGTH); + } - if($length > ($this->locationTable[$index][1] << 12)){ //Invalid chunk, bigger than defined number of sectors - \GlobalLogger::get()->error("Chunk x=$x,z=$z length mismatch (expected " . ($this->locationTable[$index][1] << 12) . " sectors, got $length sectors)"); - $this->locationTable[$index][1] = $length >> 12; + if($length > ($this->locationTable[$index]->getSectorCount() << 12)){ //Invalid chunk, bigger than defined number of sectors + \GlobalLogger::get()->error("Chunk x=$x,z=$z length mismatch (expected " . ($this->locationTable[$index]->getSectorCount() << 12) . " sectors, got $length sectors)"); + $old = $this->locationTable[$index]; + $this->locationTable[$index] = new RegionLocationTableEntry($old->getFirstSector(), $length >> 12, time()); $this->writeLocationIndex($index); } @@ -185,26 +187,22 @@ class RegionLoader{ if($length + 4 > self::MAX_SECTOR_LENGTH){ throw new ChunkException("Chunk is too big! " . ($length + 4) . " > " . self::MAX_SECTOR_LENGTH); } - $sectors = (int) ceil(($length + 4) / 4096); + + $newSize = (int) ceil(($length + 4) / 4096); $index = self::getChunkOffset($x, $z); - $indexChanged = false; - if($this->locationTable[$index][1] < $sectors){ - $this->locationTable[$index][0] = $this->lastSector + 1; - $this->lastSector += $sectors; //The GC will clean this shift "later" - $indexChanged = true; - }elseif($this->locationTable[$index][1] != $sectors){ - $indexChanged = true; + $offset = $this->locationTable[$index]->getFirstSector(); + + if($this->locationTable[$index]->getSectorCount() < $newSize){ + $offset = $this->lastSector + 1; } - $this->locationTable[$index][1] = $sectors; - $this->locationTable[$index][2] = time(); + $this->locationTable[$index] = new RegionLocationTableEntry($offset, $newSize, time()); + $this->lastSector = max($this->lastSector, $this->locationTable[$index]->getLastSector()); - fseek($this->filePointer, $this->locationTable[$index][0] << 12); - fwrite($this->filePointer, str_pad(Binary::writeInt($length) . chr(self::COMPRESSION_ZLIB) . $chunkData, $sectors << 12, "\x00", STR_PAD_RIGHT)); + fseek($this->filePointer, $offset << 12); + fwrite($this->filePointer, str_pad(Binary::writeInt($length) . chr(self::COMPRESSION_ZLIB) . $chunkData, $newSize << 12, "\x00", STR_PAD_RIGHT)); - if($indexChanged){ - $this->writeLocationIndex($index); - } + $this->writeLocationIndex($index); } /** @@ -215,8 +213,7 @@ class RegionLoader{ */ public function removeChunk(int $x, int $z) : void{ $index = self::getChunkOffset($x, $z); - $this->locationTable[$index][0] = 0; - $this->locationTable[$index][1] = 0; + $this->locationTable[$index] = new RegionLocationTableEntry(0, 0, 0); } /** @@ -276,6 +273,7 @@ class RegionLoader{ for($i = 0; $i < 1024; ++$i){ $index = $data[$i + 1]; $offset = $index >> 8; + $timestamp = $data[$i + 1025]; if($offset !== 0){ self::getChunkCoords($i, $x, $z); $fileOffset = $offset << 12; @@ -291,10 +289,8 @@ class RegionLoader{ } } - $this->locationTable[$i] = [$index >> 8, $index & 0xff, $data[1024 + $i + 1]]; - if(($this->locationTable[$i][0] + $this->locationTable[$i][1] - 1) > $this->lastSector){ - $this->lastSector = $this->locationTable[$i][0] + $this->locationTable[$i][1] - 1; - } + $this->locationTable[$i] = new RegionLocationTableEntry($offset, $index & 0xff, $timestamp); + $this->lastSector = max($this->lastSector, $this->locationTable[$i]->getLastSector()); } fseek($this->filePointer, 0); @@ -304,10 +300,10 @@ class RegionLoader{ $write = []; for($i = 0; $i < 1024; ++$i){ - $write[] = (($this->locationTable[$i][0] << 8) | $this->locationTable[$i][1]); + $write[] = (($this->locationTable[$i]->getFirstSector() << 8) | $this->locationTable[$i]->getSectorCount()); } for($i = 0; $i < 1024; ++$i){ - $write[] = $this->locationTable[$i][2]; + $write[] = $this->locationTable[$i]->getTimestamp(); } fseek($this->filePointer, 0); fwrite($this->filePointer, pack("N*", ...$write), 4096 * 2); @@ -315,16 +311,18 @@ class RegionLoader{ protected function writeLocationIndex(int $index) : void{ fseek($this->filePointer, $index << 2); - fwrite($this->filePointer, Binary::writeInt(($this->locationTable[$index][0] << 8) | $this->locationTable[$index][1]), 4); + fwrite($this->filePointer, Binary::writeInt(($this->locationTable[$index]->getFirstSector() << 8) | $this->locationTable[$index]->getSectorCount()), 4); fseek($this->filePointer, 4096 + ($index << 2)); - fwrite($this->filePointer, Binary::writeInt($this->locationTable[$index][2]), 4); + fwrite($this->filePointer, Binary::writeInt($this->locationTable[$index]->getTimestamp()), 4); } protected function createBlank() : void{ fseek($this->filePointer, 0); ftruncate($this->filePointer, 8192); // this fills the file with the null byte $this->lastSector = 1; - $this->locationTable = array_fill(0, 1024, [0, 0, 0]); + for($i = 0; $i < 1024; ++$i){ + $this->locationTable[$i] = new RegionLocationTableEntry(0, 0, 0); + } } public function getFilePath() : string{ diff --git a/src/pocketmine/level/format/io/region/RegionLocationTableEntry.php b/src/pocketmine/level/format/io/region/RegionLocationTableEntry.php new file mode 100644 index 0000000000..f17ae5bdc5 --- /dev/null +++ b/src/pocketmine/level/format/io/region/RegionLocationTableEntry.php @@ -0,0 +1,98 @@ +firstSector = $firstSector; + if($sectorCount < 0 or $sectorCount > 255){ + throw new \InvalidArgumentException("Sector count must be in range 0...255, got $sectorCount"); + } + $this->sectorCount = $sectorCount; + $this->timestamp = $timestamp; + } + + /** + * @return int + */ + public function getFirstSector() : int{ + return $this->firstSector; + } + + /** + * @return int + */ + public function getLastSector() : int{ + return $this->firstSector + $this->sectorCount - 1; + } + + /** + * Returns an array of sector offsets reserved by this chunk. + * @return int[] + */ + public function getUsedSectors() : array{ + return range($this->getFirstSector(), $this->getLastSector()); + } + + /** + * @return int + */ + public function getSectorCount() : int{ + return $this->sectorCount; + } + + /** + * @return int + */ + public function getTimestamp() : int{ + return $this->timestamp; + } + + /** + * @return bool + */ + public function isNull() : bool{ + return $this->firstSector === 0 or $this->sectorCount === 0; + } +} From f2404804d7084421ffbe7652f6d211dd7dbf7936 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Mar 2019 13:18:14 +0000 Subject: [PATCH 0599/3224] RegionLoader: clean up lastSector handling --- .../level/format/io/region/RegionLoader.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/level/format/io/region/RegionLoader.php b/src/pocketmine/level/format/io/region/RegionLoader.php index 7e8662b5ff..e5fb6b39bd 100644 --- a/src/pocketmine/level/format/io/region/RegionLoader.php +++ b/src/pocketmine/level/format/io/region/RegionLoader.php @@ -58,6 +58,8 @@ class RegionLoader{ private const MAX_SECTOR_LENGTH = 255 << 12; //255 sectors (~0.996 MiB) private const REGION_HEADER_LENGTH = 8192; //4096 location table + 4096 timestamps + private const FIRST_SECTOR = 2; //location table occupies 0 and 1 + public static $COMPRESSION_LEVEL = 7; /** @var string */ @@ -65,7 +67,7 @@ class RegionLoader{ /** @var resource */ protected $filePointer; /** @var int */ - protected $lastSector; + protected $nextSector = self::FIRST_SECTOR; /** @var RegionLocationTableEntry[] */ protected $locationTable = []; /** @var int */ @@ -193,11 +195,11 @@ class RegionLoader{ $offset = $this->locationTable[$index]->getFirstSector(); if($this->locationTable[$index]->getSectorCount() < $newSize){ - $offset = $this->lastSector + 1; + $offset = $this->nextSector; } $this->locationTable[$index] = new RegionLocationTableEntry($offset, $newSize, time()); - $this->lastSector = max($this->lastSector, $this->locationTable[$index]->getLastSector()); + $this->bumpNextFreeSector($this->locationTable[$index]); fseek($this->filePointer, $offset << 12); fwrite($this->filePointer, str_pad(Binary::writeInt($length) . chr(self::COMPRESSION_ZLIB) . $chunkData, $newSize << 12, "\x00", STR_PAD_RIGHT)); @@ -260,7 +262,6 @@ class RegionLoader{ */ protected function loadLocationTable() : void{ fseek($this->filePointer, 0); - $this->lastSector = 1; $headerRaw = fread($this->filePointer, self::REGION_HEADER_LENGTH); if(($len = strlen($headerRaw)) !== self::REGION_HEADER_LENGTH){ @@ -290,7 +291,7 @@ class RegionLoader{ } $this->locationTable[$i] = new RegionLocationTableEntry($offset, $index & 0xff, $timestamp); - $this->lastSector = max($this->lastSector, $this->locationTable[$i]->getLastSector()); + $this->bumpNextFreeSector($this->locationTable[$i]); } fseek($this->filePointer, 0); @@ -319,12 +320,15 @@ class RegionLoader{ protected function createBlank() : void{ fseek($this->filePointer, 0); ftruncate($this->filePointer, 8192); // this fills the file with the null byte - $this->lastSector = 1; for($i = 0; $i < 1024; ++$i){ $this->locationTable[$i] = new RegionLocationTableEntry(0, 0, 0); } } + private function bumpNextFreeSector(RegionLocationTableEntry $entry) : void{ + $this->nextSector = max($this->nextSector, $entry->getLastSector()) + 1; + } + public function getFilePath() : string{ return $this->filePath; } From 3f666002719282d4b77442577f99fe49788e7666 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Mar 2019 13:28:56 +0000 Subject: [PATCH 0600/3224] RegionLoader: Extract location table validation to separate function --- .../level/format/io/region/RegionLoader.php | 56 +++++++++++++------ 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/src/pocketmine/level/format/io/region/RegionLoader.php b/src/pocketmine/level/format/io/region/RegionLoader.php index e5fb6b39bd..d9a1cbf072 100644 --- a/src/pocketmine/level/format/io/region/RegionLoader.php +++ b/src/pocketmine/level/format/io/region/RegionLoader.php @@ -269,34 +269,56 @@ class RegionLoader{ } $data = unpack("N*", $headerRaw); - /** @var int[] $usedOffsets */ - $usedOffsets = []; + for($i = 0; $i < 1024; ++$i){ $index = $data[$i + 1]; $offset = $index >> 8; $timestamp = $data[$i + 1025]; - if($offset !== 0){ - self::getChunkCoords($i, $x, $z); - $fileOffset = $offset << 12; - fseek($this->filePointer, $fileOffset); - if(fgetc($this->filePointer) === false){ //Try and read from the location - throw new CorruptedRegionException("Region file location offset x=$x,z=$z points to invalid file location $fileOffset"); - }elseif(isset($usedOffsets[$offset])){ - self::getChunkCoords($usedOffsets[$offset], $existingX, $existingZ); - throw new CorruptedRegionException("Found two chunk offsets (chunk1: x=$existingX,z=$existingZ, chunk2: x=$x,z=$z) pointing to the file location $fileOffset"); - }else{ - $usedOffsets[$offset] = $i; - } + if($offset === 0){ + $this->locationTable[$i] = new RegionLocationTableEntry(0, 0, 0); + }else{ + $this->locationTable[$i] = new RegionLocationTableEntry($offset, $index & 0xff, $timestamp); + $this->bumpNextFreeSector($this->locationTable[$i]); } - - $this->locationTable[$i] = new RegionLocationTableEntry($offset, $index & 0xff, $timestamp); - $this->bumpNextFreeSector($this->locationTable[$i]); } + $this->checkLocationTableValidity(); + fseek($this->filePointer, 0); } + /** + * @throws CorruptedRegionException + */ + private function checkLocationTableValidity() : void{ + /** @var int[] $usedOffsets */ + $usedOffsets = []; + + for($i = 0; $i < 1024; ++$i){ + $entry = $this->locationTable[$i]; + if($entry->isNull()){ + continue; + } + + self::getChunkCoords($i, $x, $z); + $offset = $entry->getFirstSector(); + $fileOffset = $offset << 12; + + //TODO: more validity checks + + fseek($this->filePointer, $fileOffset); + if(fgetc($this->filePointer) === false){ //Try and read from the location + throw new CorruptedRegionException("Region file location offset x=$x,z=$z points to invalid file location $fileOffset"); + } + if(isset($usedOffsets[$offset])){ + self::getChunkCoords($usedOffsets[$offset], $existingX, $existingZ); + throw new CorruptedRegionException("Found two chunk offsets (chunk1: x=$existingX,z=$existingZ, chunk2: x=$x,z=$z) pointing to the file location $fileOffset"); + } + $usedOffsets[$offset] = $i; + } + } + private function writeLocationTable() : void{ $write = []; From 2b6a62be7756c7e6764138cb84c8ac5d3aa92671 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Mar 2019 15:32:06 +0000 Subject: [PATCH 0601/3224] Fixed BlockFactory corruption with signs and banners --- src/pocketmine/block/SignPost.php | 4 ++++ src/pocketmine/block/StandingBanner.php | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/pocketmine/block/SignPost.php b/src/pocketmine/block/SignPost.php index 48748c6edc..761ea70dd4 100644 --- a/src/pocketmine/block/SignPost.php +++ b/src/pocketmine/block/SignPost.php @@ -49,6 +49,10 @@ class SignPost extends Transparent{ $this->text = new SignText(); } + public function __clone(){ + $this->text = clone $this->text; + } + protected function writeStateToMeta() : int{ return $this->rotation; } diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index 18aa397434..f1021445fd 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -54,6 +54,10 @@ class StandingBanner extends Transparent{ $this->patterns = new Deque(); } + public function __clone(){ + $this->patterns = $this->patterns->map(function(BannerPattern $pattern) : BannerPattern{ return clone $pattern; }); + } + protected function writeStateToMeta() : int{ return $this->rotation; } From c68ee1d9d94371f5d1b4aca9cfbaf56c0edf6c27 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 8 Mar 2019 13:55:56 +0000 Subject: [PATCH 0602/3224] LevelDB: Mark chunks as changed when upgraded from an older chunk format --- src/pocketmine/level/format/io/leveldb/LevelDB.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index 3ea3cd9188..d75f0e7797 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -311,6 +311,7 @@ class LevelDB extends BaseLevelProvider{ $lightPopulated = true; $chunkVersion = ord($this->db->get($index . self::TAG_VERSION)); + $hasBeenUpgraded = $chunkVersion < self::CURRENT_LEVEL_CHUNK_VERSION; $binaryStream = new BinaryStream(); @@ -326,6 +327,9 @@ class LevelDB extends BaseLevelProvider{ $binaryStream->setBuffer($data, 0); $subChunkVersion = $binaryStream->getByte(); + if($subChunkVersion < self::CURRENT_LEVEL_SUBCHUNK_VERSION){ + $hasBeenUpgraded = true; + } switch($subChunkVersion){ case 0: @@ -334,6 +338,7 @@ class LevelDB extends BaseLevelProvider{ if($chunkVersion < 4){ $blockSkyLight = $binaryStream->get(2048); $blockLight = $binaryStream->get(2048); + $hasBeenUpgraded = true; //drop saved light }else{ //Mojang didn't bother changing the subchunk version when they stopped saving sky light -_- $blockSkyLight = ""; @@ -453,6 +458,7 @@ class LevelDB extends BaseLevelProvider{ $chunk->setGenerated(true); $chunk->setPopulated(true); $chunk->setLightPopulated($lightPopulated); + $chunk->setChanged($hasBeenUpgraded); //trigger rewriting chunk to disk if it was converted from an older format return $chunk; } From 8f1bc5d497a1efc3b5a234b70e8a23112461203a Mon Sep 17 00:00:00 2001 From: Dylan T Date: Fri, 8 Mar 2019 16:37:26 +0000 Subject: [PATCH 0603/3224] Flatten wall_banner and wall_sign into single blocks (#2798) This comes with some problems, but the problems are more bearable than the previous code. --- .../block/{StandingBanner.php => Banner.php} | 43 +++++++++++----- src/pocketmine/block/BlockFactory.php | 6 +-- .../block/{SignPost.php => Sign.php} | 35 ++++++++++--- src/pocketmine/block/WallBanner.php | 51 ------------------- src/pocketmine/block/WallSign.php | 51 ------------------- src/pocketmine/block/utils/BannerPattern.php | 4 +- .../event/block/SignChangeEvent.php | 12 ++--- .../mcpe/handler/SimpleSessionHandler.php | 4 +- src/pocketmine/tile/Banner.php | 3 +- src/pocketmine/tile/Sign.php | 3 +- .../block_factory_consistency_check.json | 2 +- 11 files changed, 71 insertions(+), 143 deletions(-) rename src/pocketmine/block/{StandingBanner.php => Banner.php} (78%) rename src/pocketmine/block/{SignPost.php => Sign.php} (78%) delete mode 100644 src/pocketmine/block/WallBanner.php delete mode 100644 src/pocketmine/block/WallSign.php diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/Banner.php similarity index 78% rename from src/pocketmine/block/StandingBanner.php rename to src/pocketmine/block/Banner.php index f1021445fd..6a0d2605f9 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/Banner.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use Ds\Deque; use pocketmine\block\utils\BannerPattern; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\block\utils\DyeColor; use pocketmine\item\Banner as ItemBanner; use pocketmine\item\Item; @@ -37,18 +38,25 @@ use pocketmine\tile\Banner as TileBanner; use function assert; use function floor; -class StandingBanner extends Transparent{ +class Banner extends Transparent{ + /** @var BlockIdentifierFlattened */ + protected $idInfo; + + //TODO: conditionally useless properties, find a way to fix /** @var int */ protected $rotation = 0; + /** @var int */ + protected $facing = Facing::UP; + /** @var DyeColor */ protected $baseColor; /** @var Deque|BannerPattern[] */ protected $patterns; - public function __construct(BlockIdentifier $idInfo, string $name){ + public function __construct(BlockIdentifierFlattened $idInfo, string $name){ parent::__construct($idInfo, $name); $this->baseColor = DyeColor::BLACK(); $this->patterns = new Deque(); @@ -58,12 +66,24 @@ class StandingBanner extends Transparent{ $this->patterns = $this->patterns->map(function(BannerPattern $pattern) : BannerPattern{ return clone $pattern; }); } + public function getId() : int{ + return $this->facing === Facing::UP ? parent::getId() : $this->idInfo->getSecondId(); + } + protected function writeStateToMeta() : int{ - return $this->rotation; + if($this->facing === Facing::UP){ + return $this->rotation; + } + return $this->facing; } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->rotation = $stateMeta; + if($id === $this->idInfo->getSecondId()){ + $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); + }else{ + $this->facing = Facing::UP; + $this->rotation = $stateMeta; + } } public function getStateBitmask() : int{ @@ -131,24 +151,19 @@ class StandingBanner extends Transparent{ $this->setPatterns($item->getPatterns()); } if($face !== Facing::DOWN){ - if($face === Facing::UP and $player !== null){ - $this->rotation = ((int) floor((($player->yaw + 180) * 16 / 360) + 0.5)) & 0x0f; - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + $this->facing = $face; + if($face === Facing::UP){ + $this->rotation = $player !== null ? ((int) floor((($player->yaw + 180) * 16 / 360) + 0.5)) & 0x0f : 0; } - //TODO: awful hack :( - $wallBanner = BlockFactory::get(Block::WALL_BANNER, $face); - assert($wallBanner instanceof WallBanner); - $wallBanner->baseColor = $this->baseColor; - $wallBanner->setPatterns($this->patterns); - return $this->getLevel()->setBlock($blockReplace, $wallBanner); + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; } public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::DOWN)->getId() === self::AIR){ + if($this->getSide(Facing::opposite($this->facing))->getId() === self::AIR){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 5ab6a5367e..e33fee7bb3 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -78,6 +78,7 @@ class BlockFactory{ self::register(new Anvil(new BID(Block::ANVIL, Anvil::TYPE_NORMAL), "Anvil")); self::register(new Anvil(new BID(Block::ANVIL, Anvil::TYPE_SLIGHTLY_DAMAGED), "Slightly Damaged Anvil")); self::register(new Anvil(new BID(Block::ANVIL, Anvil::TYPE_VERY_DAMAGED), "Very Damaged Anvil")); + self::register(new Banner(new BlockIdentifierFlattened(Block::STANDING_BANNER, Block::WALL_BANNER, 0, ItemIds::BANNER, \pocketmine\tile\Banner::class), "Banner")); self::register(new Bed(new BID(Block::BED_BLOCK, 0, ItemIds::BED, \pocketmine\tile\Bed::class), "Bed Block")); self::register(new Bedrock(new BID(Block::BEDROCK), "Bedrock")); self::register(new Beetroot(new BID(Block::BEETROOT_BLOCK), "Beetroot Block")); @@ -224,14 +225,13 @@ class BlockFactory{ self::register(new SandstoneStairs(new BID(Block::RED_SANDSTONE_STAIRS), "Red Sandstone Stairs")); self::register(new SandstoneStairs(new BID(Block::SANDSTONE_STAIRS), "Sandstone Stairs")); self::register(new SeaLantern(new BID(Block::SEALANTERN), "Sea Lantern")); - self::register(new SignPost(new BID(Block::SIGN_POST, 0, ItemIds::SIGN, \pocketmine\tile\Sign::class), "Sign Post")); + self::register(new Sign(new BlockIdentifierFlattened(Block::STANDING_SIGN, Block::WALL_SIGN, 0, ItemIds::SIGN, \pocketmine\tile\Sign::class), "Sign")); self::register(new Skull(new BID(Block::MOB_HEAD_BLOCK, 0, null, \pocketmine\tile\Skull::class), "Mob Head")); self::register(new SmoothStone(new BID(Block::STONE, Stone::NORMAL), "Stone")); self::register(new Snow(new BID(Block::SNOW), "Snow Block")); self::register(new SnowLayer(new BID(Block::SNOW_LAYER), "Snow Layer")); self::register(new SoulSand(new BID(Block::SOUL_SAND), "Soul Sand")); self::register(new Sponge(new BID(Block::SPONGE), "Sponge")); - self::register(new StandingBanner(new BID(Block::STANDING_BANNER, 0, ItemIds::BANNER, \pocketmine\tile\Banner::class), "Standing Banner")); self::register(new Stone(new BID(Block::STONE, Stone::ANDESITE), "Andesite")); self::register(new Stone(new BID(Block::STONE, Stone::DIORITE), "Diorite")); self::register(new Stone(new BID(Block::STONE, Stone::GRANITE), "Granite")); @@ -279,8 +279,6 @@ class BlockFactory{ self::register(new TripwireHook(new BID(Block::TRIPWIRE_HOOK), "Tripwire Hook")); self::register(new UnderwaterTorch(new BID(Block::UNDERWATER_TORCH), "Underwater Torch")); self::register(new Vine(new BID(Block::VINE), "Vines")); - self::register(new WallBanner(new BID(Block::WALL_BANNER, 0, ItemIds::BANNER, \pocketmine\tile\Banner::class), "Wall Banner")); - self::register(new WallSign(new BID(Block::WALL_SIGN, 0, ItemIds::SIGN, \pocketmine\tile\Sign::class), "Wall Sign")); self::register(new Water(new BlockIdentifierFlattened(Block::FLOWING_WATER, Block::STILL_WATER), "Water")); self::register(new WaterLily(new BID(Block::LILY_PAD), "Lily Pad")); self::register(new WeightedPressurePlateHeavy(new BID(Block::HEAVY_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Heavy")); diff --git a/src/pocketmine/block/SignPost.php b/src/pocketmine/block/Sign.php similarity index 78% rename from src/pocketmine/block/SignPost.php rename to src/pocketmine/block/Sign.php index 761ea70dd4..f8527ce6d8 100644 --- a/src/pocketmine/block/SignPost.php +++ b/src/pocketmine/block/Sign.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\BlockDataValidator; use pocketmine\block\utils\SignText; use pocketmine\event\block\SignChangeEvent; use pocketmine\item\Item; @@ -36,15 +37,22 @@ use function array_map; use function assert; use function floor; -class SignPost extends Transparent{ +class Sign extends Transparent{ + /** @var BlockIdentifierFlattened */ + protected $idInfo; + + //TODO: conditionally useless properties, find a way to fix /** @var int */ protected $rotation = 0; + /** @var int */ + protected $facing = Facing::UP; + /** @var SignText */ protected $text; - public function __construct(BlockIdentifier $idInfo, string $name){ + public function __construct(BlockIdentifierFlattened $idInfo, string $name){ parent::__construct($idInfo, $name); $this->text = new SignText(); } @@ -53,12 +61,24 @@ class SignPost extends Transparent{ $this->text = clone $this->text; } + public function getId() : int{ + return $this->facing === Facing::UP ? parent::getId() : $this->idInfo->getSecondId(); + } + protected function writeStateToMeta() : int{ - return $this->rotation; + if($this->facing === Facing::UP){ + return $this->rotation; + } + return $this->facing; } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->rotation = $stateMeta; + if($id === $this->idInfo->getSecondId()){ + $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); + }else{ + $this->facing = Facing::UP; + $this->rotation = $stateMeta; + } } public function readStateFromWorld() : void{ @@ -94,20 +114,19 @@ class SignPost extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face !== Facing::DOWN){ - + $this->facing = $face; if($face === Facing::UP){ $this->rotation = $player !== null ? ((int) floor((($player->yaw + 180) * 16 / 360) + 0.5)) & 0x0f : 0; - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - return $this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::WALL_SIGN, $face)); + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; } public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::DOWN)->getId() === self::AIR){ + if($this->getSide(Facing::opposite($this->facing))->getId() === self::AIR){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/WallBanner.php b/src/pocketmine/block/WallBanner.php deleted file mode 100644 index 7acdba5b78..0000000000 --- a/src/pocketmine/block/WallBanner.php +++ /dev/null @@ -1,51 +0,0 @@ -facing; - } - - public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); - } - - public function getStateBitmask() : int{ - return 0b111; - } - - public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::opposite($this->facing))->getId() === self::AIR){ - $this->getLevel()->useBreakOn($this); - } - } -} diff --git a/src/pocketmine/block/WallSign.php b/src/pocketmine/block/WallSign.php deleted file mode 100644 index 79f85999af..0000000000 --- a/src/pocketmine/block/WallSign.php +++ /dev/null @@ -1,51 +0,0 @@ -facing; - } - - public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); - } - - public function getStateBitmask() : int{ - return 0b111; - } - - public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::opposite($this->facing))->getId() === self::AIR){ - $this->getLevel()->useBreakOn($this); - } - } -} diff --git a/src/pocketmine/block/utils/BannerPattern.php b/src/pocketmine/block/utils/BannerPattern.php index cde366b254..857bde3ac2 100644 --- a/src/pocketmine/block/utils/BannerPattern.php +++ b/src/pocketmine/block/utils/BannerPattern.php @@ -23,11 +23,11 @@ declare(strict_types=1); namespace pocketmine\block\utils; -use pocketmine\block\StandingBanner; +use pocketmine\block\Banner; /** * Contains information about a pattern layer on a banner. - * @see StandingBanner + * @see Banner */ class BannerPattern{ public const BORDER = "bo"; diff --git a/src/pocketmine/event/block/SignChangeEvent.php b/src/pocketmine/event/block/SignChangeEvent.php index 66af600e17..a695089425 100644 --- a/src/pocketmine/event/block/SignChangeEvent.php +++ b/src/pocketmine/event/block/SignChangeEvent.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\event\block; -use pocketmine\block\SignPost; +use pocketmine\block\Sign; use pocketmine\block\utils\SignText; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; @@ -35,7 +35,7 @@ use pocketmine\Player; class SignChangeEvent extends BlockEvent implements Cancellable{ use CancellableTrait; - /** @var SignPost */ + /** @var Sign */ private $sign; /** @var Player */ @@ -45,11 +45,11 @@ class SignChangeEvent extends BlockEvent implements Cancellable{ private $text; /** - * @param SignPost $sign + * @param Sign $sign * @param Player $player * @param SignText $text */ - public function __construct(SignPost $sign, Player $player, SignText $text){ + public function __construct(Sign $sign, Player $player, SignText $text){ parent::__construct($sign); $this->sign = $sign; $this->player = $player; @@ -57,9 +57,9 @@ class SignChangeEvent extends BlockEvent implements Cancellable{ } /** - * @return SignPost + * @return Sign */ - public function getSign() : SignPost{ + public function getSign() : Sign{ return $this->sign; } diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index 0b93502e14..bb09244ad8 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; use pocketmine\block\ItemFrame; -use pocketmine\block\SignPost; +use pocketmine\block\Sign; use pocketmine\block\utils\SignText; use pocketmine\inventory\transaction\action\InventoryAction; use pocketmine\inventory\transaction\CraftingTransaction; @@ -403,7 +403,7 @@ class SimpleSessionHandler extends SessionHandler{ throw new BadPacketException($e->getMessage(), 0, $e); } - if($block instanceof SignPost){ + if($block instanceof Sign){ if($nbt->hasTag("Text", StringTag::class)){ try{ $text = SignText::fromBlob($nbt->getString("Text")); diff --git a/src/pocketmine/tile/Banner.php b/src/pocketmine/tile/Banner.php index 73593fd86c..839c6ca729 100644 --- a/src/pocketmine/tile/Banner.php +++ b/src/pocketmine/tile/Banner.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\tile; use Ds\Deque; -use pocketmine\block\StandingBanner; use pocketmine\block\utils\BannerPattern; use pocketmine\block\utils\DyeColor; use pocketmine\level\Level; @@ -36,7 +35,7 @@ use pocketmine\nbt\tag\StringTag; /** * @deprecated - * @see StandingBanner + * @see \pocketmine\block\Banner */ class Banner extends Spawnable{ diff --git a/src/pocketmine/tile/Sign.php b/src/pocketmine/tile/Sign.php index 14a034dc43..b0ac37e375 100644 --- a/src/pocketmine/tile/Sign.php +++ b/src/pocketmine/tile/Sign.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\tile; -use pocketmine\block\SignPost; use pocketmine\block\utils\SignText; use pocketmine\level\Level; use pocketmine\math\Vector3; @@ -38,7 +37,7 @@ use function sprintf; /** * @deprecated - * @see SignPost + * @see \pocketmine\block\Sign */ class Sign extends Spawnable{ public const TAG_TEXT_BLOB = "Text"; diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 34ec5b5dd5..ab633daa93 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","752":"Bookshelf","768":"Moss Stone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Sign Post","1009":"Sign Post","1010":"Sign Post","1011":"Sign Post","1012":"Sign Post","1013":"Sign Post","1014":"Sign Post","1015":"Sign Post","1016":"Sign Post","1017":"Sign Post","1018":"Sign Post","1019":"Sign Post","1020":"Sign Post","1021":"Sign Post","1022":"Sign Post","1023":"Sign Post","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Wall Sign","1090":"Wall Sign","1091":"Wall Sign","1092":"Wall Sign","1093":"Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Wooden Pressure Plate","1153":"Wooden Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Wooden Trapdoor","1537":"Wooden Trapdoor","1538":"Wooden Trapdoor","1539":"Wooden Trapdoor","1540":"Wooden Trapdoor","1541":"Wooden Trapdoor","1542":"Wooden Trapdoor","1543":"Wooden Trapdoor","1544":"Wooden Trapdoor","1545":"Wooden Trapdoor","1546":"Wooden Trapdoor","1547":"Wooden Trapdoor","1548":"Wooden Trapdoor","1549":"Wooden Trapdoor","1550":"Wooden Trapdoor","1551":"Wooden Trapdoor","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Wooden Button","2289":"Wooden Button","2290":"Wooden Button","2291":"Wooden Button","2292":"Wooden Button","2293":"Wooden Button","2296":"Wooden Button","2297":"Wooden Button","2298":"Wooden Button","2299":"Wooden Button","2300":"Wooden Button","2301":"Wooden Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Standing Banner","2817":"Standing Banner","2818":"Standing Banner","2819":"Standing Banner","2820":"Standing Banner","2821":"Standing Banner","2822":"Standing Banner","2823":"Standing Banner","2824":"Standing Banner","2825":"Standing Banner","2826":"Standing Banner","2827":"Standing Banner","2828":"Standing Banner","2829":"Standing Banner","2830":"Standing Banner","2831":"Standing Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","752":"Bookshelf","768":"Moss Stone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Sign","1009":"Sign","1010":"Sign","1011":"Sign","1012":"Sign","1013":"Sign","1014":"Sign","1015":"Sign","1016":"Sign","1017":"Sign","1018":"Sign","1019":"Sign","1020":"Sign","1021":"Sign","1022":"Sign","1023":"Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Sign","1090":"Sign","1091":"Sign","1092":"Sign","1093":"Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Wooden Pressure Plate","1153":"Wooden Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Wooden Trapdoor","1537":"Wooden Trapdoor","1538":"Wooden Trapdoor","1539":"Wooden Trapdoor","1540":"Wooden Trapdoor","1541":"Wooden Trapdoor","1542":"Wooden Trapdoor","1543":"Wooden Trapdoor","1544":"Wooden Trapdoor","1545":"Wooden Trapdoor","1546":"Wooden Trapdoor","1547":"Wooden Trapdoor","1548":"Wooden Trapdoor","1549":"Wooden Trapdoor","1550":"Wooden Trapdoor","1551":"Wooden Trapdoor","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Wooden Button","2289":"Wooden Button","2290":"Wooden Button","2291":"Wooden Button","2292":"Wooden Button","2293":"Wooden Button","2296":"Wooden Button","2297":"Wooden Button","2298":"Wooden Button","2299":"Wooden Button","2300":"Wooden Button","2301":"Wooden Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6"} \ No newline at end of file From 6fe366e1ac2ce3127ab434f1cd7816d03e236ac9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 9 Mar 2019 16:49:37 +0000 Subject: [PATCH 0604/3224] Added some missing block properties --- src/pocketmine/block/Bedrock.php | 19 +++++++++++++++++++ src/pocketmine/block/TNT.php | 23 +++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/pocketmine/block/Bedrock.php b/src/pocketmine/block/Bedrock.php index 91fb7fe4cb..c2ef580939 100644 --- a/src/pocketmine/block/Bedrock.php +++ b/src/pocketmine/block/Bedrock.php @@ -27,6 +27,21 @@ use pocketmine\item\Item; class Bedrock extends Solid{ + /** @var bool */ + private $burnsForever = false; + + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->burnsForever = $stateMeta !== 0; + } + + protected function writeStateToMeta() : int{ + return $this->burnsForever ? 1 : 0; + } + + public function getStateBitmask() : int{ + return 0b1; + } + public function getHardness() : float{ return -1; } @@ -38,4 +53,8 @@ class Bedrock extends Solid{ public function isBreakable(Item $item) : bool{ return false; } + + public function burnsForever() : bool{ + return $this->burnsForever; + } } diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index d56d7b74bf..3b74bee1cc 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -40,10 +40,33 @@ use const M_PI; class TNT extends Solid{ + /** @var bool */ + protected $unstable = false; //TODO: Usage unclear, seems to be a weird hack in vanilla + + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->unstable = $stateMeta !== 0; + } + + protected function writeStateToMeta() : int{ + return $this->unstable ? 1 : 0; + } + + public function getStateBitmask() : int{ + return 0b1; + } + public function getHardness() : float{ return 0; } + public function onBreak(Item $item, ?Player $player = null) : bool{ + if($this->unstable){ + $this->ignite(); + return true; + } + return parent::onBreak($item, $player); + } + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof FlintSteel or $item->hasEnchantment(Enchantment::FIRE_ASPECT())){ if($item instanceof Durable){ From 2ae09f635bcd22ae646c45a19debbab3b432ffbf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 9 Mar 2019 17:19:17 +0000 Subject: [PATCH 0605/3224] Add more output to consistency check script this helps catching state mapping bugs. --- tests/phpunit/block/regenerate_consistency_check.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/phpunit/block/regenerate_consistency_check.php b/tests/phpunit/block/regenerate_consistency_check.php index 07227301ba..693bd89aea 100644 --- a/tests/phpunit/block/regenerate_consistency_check.php +++ b/tests/phpunit/block/regenerate_consistency_check.php @@ -42,6 +42,8 @@ foreach($old as $k => $name){ foreach($new as $k => $name){ if(!isset($old[$k])){ echo "Added state for $name (" . ($k >> 4) . ":" . ($k & 0xf) . ")\n"; + }elseif($old[$k] !== $name){ + echo "Name changed (" . ($k >> 4) . ":" . ($k & 0xf) . "): " . $old[$k] . " -> " . $name . "\n"; } } file_put_contents(__DIR__ . '/block_factory_consistency_check.json', json_encode( From 3079fd02510d1cf4234f96383ec2236a4c1b4820 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 9 Mar 2019 19:05:32 +0000 Subject: [PATCH 0606/3224] Fixed test failures introduced by 6fe366e1ac2ce3127ab434f1cd7816d03e236ac9 --- tests/phpunit/block/block_factory_consistency_check.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index ab633daa93..a49775bb7a 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","752":"Bookshelf","768":"Moss Stone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Sign","1009":"Sign","1010":"Sign","1011":"Sign","1012":"Sign","1013":"Sign","1014":"Sign","1015":"Sign","1016":"Sign","1017":"Sign","1018":"Sign","1019":"Sign","1020":"Sign","1021":"Sign","1022":"Sign","1023":"Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Sign","1090":"Sign","1091":"Sign","1092":"Sign","1093":"Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Wooden Pressure Plate","1153":"Wooden Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Wooden Trapdoor","1537":"Wooden Trapdoor","1538":"Wooden Trapdoor","1539":"Wooden Trapdoor","1540":"Wooden Trapdoor","1541":"Wooden Trapdoor","1542":"Wooden Trapdoor","1543":"Wooden Trapdoor","1544":"Wooden Trapdoor","1545":"Wooden Trapdoor","1546":"Wooden Trapdoor","1547":"Wooden Trapdoor","1548":"Wooden Trapdoor","1549":"Wooden Trapdoor","1550":"Wooden Trapdoor","1551":"Wooden Trapdoor","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Wooden Button","2289":"Wooden Button","2290":"Wooden Button","2291":"Wooden Button","2292":"Wooden Button","2293":"Wooden Button","2296":"Wooden Button","2297":"Wooden Button","2298":"Wooden Button","2299":"Wooden Button","2300":"Wooden Button","2301":"Wooden Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Moss Stone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Sign","1009":"Sign","1010":"Sign","1011":"Sign","1012":"Sign","1013":"Sign","1014":"Sign","1015":"Sign","1016":"Sign","1017":"Sign","1018":"Sign","1019":"Sign","1020":"Sign","1021":"Sign","1022":"Sign","1023":"Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Sign","1090":"Sign","1091":"Sign","1092":"Sign","1093":"Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Wooden Pressure Plate","1153":"Wooden Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Wooden Trapdoor","1537":"Wooden Trapdoor","1538":"Wooden Trapdoor","1539":"Wooden Trapdoor","1540":"Wooden Trapdoor","1541":"Wooden Trapdoor","1542":"Wooden Trapdoor","1543":"Wooden Trapdoor","1544":"Wooden Trapdoor","1545":"Wooden Trapdoor","1546":"Wooden Trapdoor","1547":"Wooden Trapdoor","1548":"Wooden Trapdoor","1549":"Wooden Trapdoor","1550":"Wooden Trapdoor","1551":"Wooden Trapdoor","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Wooden Button","2289":"Wooden Button","2290":"Wooden Button","2291":"Wooden Button","2292":"Wooden Button","2293":"Wooden Button","2296":"Wooden Button","2297":"Wooden Button","2298":"Wooden Button","2299":"Wooden Button","2300":"Wooden Button","2301":"Wooden Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6"} \ No newline at end of file From c266f86b1b86adbfb8068e3c1741d8bd5c1c13d8 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Sun, 10 Mar 2019 12:05:21 +0000 Subject: [PATCH 0607/3224] ItemEntity: introduce controls for despawn timers (#2769) This opts _not_ to expose item "age" a la #2753 because "age" is a misleading term for it. In addition, further inspection of the problem led me to realize that exposing control of that AND despawn timeout was more complicated than simply having a despawn delay timer exactly like the pickup delay one. Everyone knows a countdown timer stops at 0, so this way we don't need any method to control the limit. Closes #2667 Closes #2753 --- src/pocketmine/entity/object/ItemEntity.php | 51 ++++++++++++++++++--- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/entity/object/ItemEntity.php b/src/pocketmine/entity/object/ItemEntity.php index 9dfc73768f..415b6a1968 100644 --- a/src/pocketmine/entity/object/ItemEntity.php +++ b/src/pocketmine/entity/object/ItemEntity.php @@ -33,10 +33,15 @@ use pocketmine\network\mcpe\protocol\AddItemEntityPacket; use pocketmine\network\mcpe\protocol\TakeItemEntityPacket; use pocketmine\Player; use function get_class; +use function max; class ItemEntity extends Entity{ public const NETWORK_ID = self::ITEM; + public const DEFAULT_DESPAWN_DELAY = 6000; //5 minutes + public const NEVER_DESPAWN = -1; + public const MAX_DESPAWN_DELAY = 32767 + self::DEFAULT_DESPAWN_DELAY; //max value storable by mojang NBT :( + /** @var string */ protected $owner = ""; /** @var string */ @@ -56,14 +61,20 @@ class ItemEntity extends Entity{ public $canCollide = false; /** @var int */ - protected $age = 0; + protected $despawnDelay = self::DEFAULT_DESPAWN_DELAY; protected function initEntity(CompoundTag $nbt) : void{ parent::initEntity($nbt); $this->setMaxHealth(5); $this->setHealth($nbt->getShort("Health", (int) $this->getHealth())); - $this->age = $nbt->getShort("Age", $this->age); + + $age = $nbt->getShort("Age", 0); + if($age === -32768){ + $this->despawnDelay = self::NEVER_DESPAWN; + }else{ + $this->despawnDelay = max(0, self::DEFAULT_DESPAWN_DELAY - $age); + } $this->pickupDelay = $nbt->getShort("PickupDelay", $this->pickupDelay); $this->owner = $nbt->getString("Owner", $this->owner); $this->thrower = $nbt->getString("Thrower", $this->thrower); @@ -90,18 +101,18 @@ class ItemEntity extends Entity{ $hasUpdate = parent::entityBaseTick($tickDiff); - if(!$this->isFlaggedForDespawn() and $this->pickupDelay > -1 and $this->pickupDelay < 32767){ //Infinite delay + if(!$this->isFlaggedForDespawn() and $this->pickupDelay !== self::NEVER_DESPAWN){ //Infinite delay $this->pickupDelay -= $tickDiff; if($this->pickupDelay < 0){ $this->pickupDelay = 0; } - $this->age += $tickDiff; - if($this->age > 6000){ + $this->despawnDelay -= $tickDiff; + if($this->despawnDelay <= 0){ $ev = new ItemDespawnEvent($this); $ev->call(); if($ev->isCancelled()){ - $this->age = 0; + $this->despawnDelay = self::DEFAULT_DESPAWN_DELAY; }else{ $this->flagForDespawn(); $hasUpdate = true; @@ -125,7 +136,12 @@ class ItemEntity extends Entity{ $nbt = parent::saveNBT(); $nbt->setTag($this->item->nbtSerialize(-1, "Item")); $nbt->setShort("Health", (int) $this->getHealth()); - $nbt->setShort("Age", $this->age); + if($this->despawnDelay === self::NEVER_DESPAWN){ + $age = -32768; + }else{ + $age = self::DEFAULT_DESPAWN_DELAY - $this->despawnDelay; + } + $nbt->setShort("Age", $age); $nbt->setShort("PickupDelay", $this->pickupDelay); if($this->owner !== null){ $nbt->setString("Owner", $this->owner); @@ -166,6 +182,27 @@ class ItemEntity extends Entity{ $this->pickupDelay = $delay; } + /** + * Returns the number of ticks left before this item will despawn. If -1, the item will never despawn. + * + * @return int + */ + public function getDespawnDelay() : int{ + return $this->despawnDelay; + } + + /** + * @param int $despawnDelay + * + * @throws \InvalidArgumentException + */ + public function setDespawnDelay(int $despawnDelay) : void{ + if(($despawnDelay < 0 or $despawnDelay > self::MAX_DESPAWN_DELAY) and $despawnDelay !== self::NEVER_DESPAWN){ + throw new \InvalidArgumentException("Despawn ticker must be in range 0 ... " . self::MAX_DESPAWN_DELAY . " or " . self::NEVER_DESPAWN . ", got $despawnDelay"); + } + $this->despawnDelay = $despawnDelay; + } + /** * @return string */ From ae9f57ac285e3fb588a95e649f5113676b70a8d4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 10 Mar 2019 19:46:23 +0000 Subject: [PATCH 0608/3224] Revert "Remove hacks for triggering adjacent light refill" This reverts commit 1dca9074d5f087d15f8d30d2941150fe51617489. This change introduced performance issues with transparent blocks. --- src/pocketmine/level/Level.php | 8 +++++--- src/pocketmine/level/light/LightUpdate.php | 14 +++++++------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index f5c51f9c14..b20e4b9d12 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1492,8 +1492,8 @@ class Level implements ChunkManager, Metadatable{ for($i = $y; $i >= $newHeightMap; --$i){ $this->skyLightUpdate->setAndUpdateLight($x, $i, $z, 15); } - }else{ //No heightmap change, block changed "underground" - trigger recalculation from surroundings - $this->skyLightUpdate->setAndUpdateLight($x, $y, $z, 0); + }else{ //No heightmap change, block changed "underground" + $this->skyLightUpdate->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentBlockSkyLight($x, $y, $z) - BlockFactory::$lightFilter[($source->getId() << 4) | $source->getMeta()])); } $this->timings->doBlockSkyLightUpdates->stopTiming(); @@ -1523,10 +1523,12 @@ class Level implements ChunkManager, Metadatable{ $this->timings->doBlockLightUpdates->startTiming(); $block = $this->getBlockAt($x, $y, $z); + $newLevel = max($block->getLightLevel(), $this->getHighestAdjacentBlockLight($x, $y, $z) - BlockFactory::$lightFilter[($block->getId() << 4) | $block->getMeta()]); + if($this->blockLightUpdate === null){ $this->blockLightUpdate = new BlockLightUpdate($this); } - $this->blockLightUpdate->setAndUpdateLight($x, $y, $z, $block->getLightLevel()); + $this->blockLightUpdate->setAndUpdateLight($x, $y, $z, $newLevel); $this->timings->doBlockLightUpdates->stopTiming(); } diff --git a/src/pocketmine/level/light/LightUpdate.php b/src/pocketmine/level/light/LightUpdate.php index cf360acab3..c141b2ee34 100644 --- a/src/pocketmine/level/light/LightUpdate.php +++ b/src/pocketmine/level/light/LightUpdate.php @@ -72,13 +72,13 @@ abstract class LightUpdate{ if($oldLevel !== $newLevel){ $this->setLight($x, $y, $z, $newLevel); - } - if($newLevel > $oldLevel){ //light increased - $this->spreadVisited[$blockHash] = true; - $this->spreadQueue->enqueue([$x, $y, $z]); - }elseif($newLevel < 15){ //light removed or stayed the same, force recheck nearby environment - $this->removalVisited[$blockHash] = true; - $this->removalQueue->enqueue([$x, $y, $z, $oldLevel]); + if($oldLevel < $newLevel){ //light increased + $this->spreadVisited[$blockHash] = true; + $this->spreadQueue->enqueue([$x, $y, $z]); + }else{ //light removed + $this->removalVisited[$blockHash] = true; + $this->removalQueue->enqueue([$x, $y, $z, $oldLevel]); + } } } } From a0a8026cba6fca44aed8a8f6d43084e1f76d2f1a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Mar 2019 17:37:20 +0000 Subject: [PATCH 0609/3224] Implemented automatic world format conversion --- .gitignore | 1 + src/pocketmine/Server.php | 11 +- src/pocketmine/level/Level.php | 14 +- src/pocketmine/level/LevelManager.php | 29 +++- .../level/format/io/FormatConverter.php | 146 ++++++++++++++++++ .../level/format/io/LevelProvider.php | 25 +-- .../level/format/io/LevelProviderManager.php | 6 +- .../level/format/io/WritableLevelProvider.php | 46 ++++++ .../level/format/io/leveldb/LevelDB.php | 18 ++- .../level/format/io/region/Anvil.php | 3 +- .../level/format/io/region/McRegion.php | 3 +- .../level/format/io/region/PMAnvil.php | 3 +- .../format/io/region/RegionLevelProvider.php | 17 +- 13 files changed, 274 insertions(+), 48 deletions(-) create mode 100644 src/pocketmine/level/format/io/FormatConverter.php create mode 100644 src/pocketmine/level/format/io/WritableLevelProvider.php diff --git a/.gitignore b/.gitignore index 9824e60382..afc4ebbca4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ players/* worlds/* +world_conversion_backups/* plugin_data/* plugins/* bin*/* diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 93e5afc94c..62ccae495f 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -49,6 +49,7 @@ use pocketmine\lang\LanguageNotFoundException; use pocketmine\lang\TextContainer; use pocketmine\level\biome\Biome; use pocketmine\level\format\io\LevelProviderManager; +use pocketmine\level\format\io\WritableLevelProvider; use pocketmine\level\generator\Generator; use pocketmine\level\generator\GeneratorManager; use pocketmine\level\generator\normal\Normal; @@ -118,6 +119,7 @@ use function getopt; use function implode; use function ini_get; use function ini_set; +use function is_a; use function is_array; use function is_bool; use function is_string; @@ -1244,7 +1246,10 @@ class Server{ $this->pluginManager->registerInterface(new ScriptPluginLoader()); LevelProviderManager::init(); - if(($format = LevelProviderManager::getProviderByName($formatName = (string) $this->getProperty("level-settings.default-format"))) !== null){ + if( + ($format = LevelProviderManager::getProviderByName($formatName = (string) $this->getProperty("level-settings.default-format"))) !== null and + is_a($format, WritableLevelProvider::class, true) + ){ LevelProviderManager::setDefault($format); }elseif($formatName !== ""){ $this->logger->warning($this->language->translateString("pocketmine.level.badDefaultFormat", [$formatName])); @@ -1275,7 +1280,7 @@ class Server{ }elseif(!is_array($options)){ continue; } - if(!$this->levelManager->loadLevel($name)){ + if(!$this->levelManager->loadLevel($name, true)){ if(isset($options["generator"])){ $generatorOptions = explode(":", $options["generator"]); $generator = GeneratorManager::getGenerator(array_shift($generatorOptions)); @@ -1297,7 +1302,7 @@ class Server{ $default = "world"; $this->setConfigString("level-name", "world"); } - if(!$this->levelManager->loadLevel($default)){ + if(!$this->levelManager->loadLevel($default, true)){ $this->levelManager->generateLevel( $default, Generator::convertSeed($this->getConfigString("level-seed")), diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index b20e4b9d12..1c57ff5ca4 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -51,7 +51,7 @@ use pocketmine\level\format\ChunkException; use pocketmine\level\format\EmptySubChunk; use pocketmine\level\format\io\exception\CorruptedChunkException; use pocketmine\level\format\io\exception\UnsupportedChunkFormatException; -use pocketmine\level\format\io\LevelProvider; +use pocketmine\level\format\io\WritableLevelProvider; use pocketmine\level\generator\Generator; use pocketmine\level\generator\GeneratorManager; use pocketmine\level\generator\GeneratorRegisterTask; @@ -159,7 +159,7 @@ class Level implements ChunkManager, Metadatable{ /** @var int */ private $levelId; - /** @var LevelProvider */ + /** @var WritableLevelProvider */ private $provider; /** @var int */ private $providerGarbageCollectionTicker = 0; @@ -347,11 +347,11 @@ class Level implements ChunkManager, Metadatable{ /** * Init the default level data * - * @param Server $server - * @param string $name - * @param LevelProvider $provider + * @param Server $server + * @param string $name + * @param WritableLevelProvider $provider */ - public function __construct(Server $server, string $name, LevelProvider $provider){ + public function __construct(Server $server, string $name, WritableLevelProvider $provider){ $this->levelId = static::$levelIdCounter++; $this->blockMetadata = new BlockMetadataStore($this); $this->server = $server; @@ -426,7 +426,7 @@ class Level implements ChunkManager, Metadatable{ return $this->server; } - final public function getProvider() : LevelProvider{ + final public function getProvider() : WritableLevelProvider{ return $this->provider; } diff --git a/src/pocketmine/level/LevelManager.php b/src/pocketmine/level/LevelManager.php index f4d29b4c40..7f0eebe32b 100644 --- a/src/pocketmine/level/LevelManager.php +++ b/src/pocketmine/level/LevelManager.php @@ -28,8 +28,10 @@ use pocketmine\event\level\LevelInitEvent; use pocketmine\event\level\LevelLoadEvent; use pocketmine\event\level\LevelUnloadEvent; use pocketmine\level\format\io\exception\UnsupportedLevelFormatException; +use pocketmine\level\format\io\FormatConverter; use pocketmine\level\format\io\LevelProvider; use pocketmine\level\format\io\LevelProviderManager; +use pocketmine\level\format\io\WritableLevelProvider; use pocketmine\level\generator\Generator; use pocketmine\level\generator\normal\Normal; use pocketmine\Server; @@ -184,12 +186,13 @@ class LevelManager{ * Loads a level from the data directory * * @param string $name + * @param bool $autoUpgrade Converts worlds to the default format if the world's format is not writable / deprecated * * @return bool * * @throws LevelException */ - public function loadLevel(string $name) : bool{ + public function loadLevel(string $name, bool $autoUpgrade = false) : bool{ if(trim($name) === ""){ throw new LevelException("Invalid empty world name"); } @@ -213,9 +216,25 @@ class LevelManager{ } $providerClass = array_shift($providers); + /** + * @var LevelProvider + * @see LevelProvider::__construct() + */ + $provider = new $providerClass($path); + if(!($provider instanceof WritableLevelProvider)){ + if(!$autoUpgrade){ + throw new LevelException("World \"$name\" is in an unsupported format and needs to be upgraded"); + } + $this->server->getLogger()->notice("Upgrading world \"$name\" to new format. This may take a while."); + + $converter = new FormatConverter($provider, LevelProviderManager::getDefault(), $this->server->getDataPath() . "world_conversion_backups", $this->server->getLogger()); + $provider = $converter->execute(); + + $this->server->getLogger()->notice("Upgraded world \"$name\" to new format successfully. Backed up pre-conversion world at " . $converter->getBackupPath()); + } + try{ - /** @see LevelProvider::__construct() */ - $level = new Level($this->server, $name, new $providerClass($path)); + $level = new Level($this->server, $name, $provider); }catch(UnsupportedLevelFormatException $e){ $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.level.loadError", [$name, $e->getMessage()])); return false; @@ -253,10 +272,10 @@ class LevelManager{ $providerClass = LevelProviderManager::getDefault(); $path = $this->server->getDataPath() . "worlds/" . $name . "/"; - /** @var LevelProvider $providerClass */ + /** @var WritableLevelProvider $providerClass */ $providerClass::generate($path, $name, $seed, $generator, $options); - /** @see LevelProvider::__construct() */ + /** @see WritableLevelProvider::__construct() */ $level = new Level($this->server, $name, new $providerClass($path)); $this->levels[$level->getId()] = $level; diff --git a/src/pocketmine/level/format/io/FormatConverter.php b/src/pocketmine/level/format/io/FormatConverter.php new file mode 100644 index 0000000000..b9bce909f0 --- /dev/null +++ b/src/pocketmine/level/format/io/FormatConverter.php @@ -0,0 +1,146 @@ +oldProvider = $oldProvider; + Utils::testValidInstance($newProvider, WritableLevelProvider::class); + $this->newProvider = $newProvider; + + $this->backupPath = $backupPath . DIRECTORY_SEPARATOR . basename($this->oldProvider->getPath()); + if(!file_exists($backupPath)){ + @mkdir($backupPath); + }elseif(!is_dir($backupPath)){ + throw new \RuntimeException("Backup path $backupPath exists and is not a directory"); + } + + $this->logger = new \PrefixedLogger($logger, "World Converter - " . $this->oldProvider->getLevelData()->getName()); + } + + public function getBackupPath() : string{ + return $this->backupPath; + } + + public function execute() : WritableLevelProvider{ + $new = $this->generateNew(); + + $this->populateLevelData($new->getLevelData()); + $this->convertTerrain($new); + + $path = $this->oldProvider->getPath(); + $this->oldProvider->close(); + $new->close(); + + $this->logger->info("Backing up pre-conversion world to " . $this->backupPath); + rename($path, $this->backupPath); + rename($new->getPath(), $path); + + $this->logger->info("Conversion completed"); + /** + * @see WritableLevelProvider::__construct() + */ + return new $this->newProvider($path); + } + + private function generateNew() : WritableLevelProvider{ + $this->logger->info("Generating new world"); + $data = $this->oldProvider->getLevelData(); + + $convertedOutput = rtrim($this->oldProvider->getPath(), "/\\") . "_converted" . DIRECTORY_SEPARATOR; + if(file_exists($convertedOutput)){ + $this->logger->info("Found previous conversion attempt, deleting..."); + Utils::recursiveUnlink($convertedOutput); + } + $this->newProvider::generate($convertedOutput, $data->getName(), $data->getSeed(), $data->getGenerator(), $data->getGeneratorOptions()); + + /** + * @see WritableLevelProvider::__construct() + */ + return new $this->newProvider($convertedOutput); + } + + private function populateLevelData(LevelData $data) : void{ + $this->logger->info("Converting world manifest"); + $oldData = $this->oldProvider->getLevelData(); + $data->setDifficulty($oldData->getDifficulty()); + $data->setLightningLevel($oldData->getLightningLevel()); + $data->setLightningTime($oldData->getLightningTime()); + $data->setRainLevel($oldData->getRainLevel()); + $data->setRainTime($oldData->getRainTime()); + $data->setSpawn($oldData->getSpawn()); + $data->setTime($oldData->getTime()); + + $this->logger->info("Finished converting manifest"); + //TODO: add more properties as-needed + } + + private function convertTerrain(WritableLevelProvider $new) : void{ + $this->logger->info("Calculating chunk count"); + $count = $this->oldProvider->calculateChunkCount(); + $this->logger->info("Discovered $count chunks"); + + $counter = 0; + + $start = microtime(true); + $thisRound = $start; + static $reportInterval = 256; + foreach($this->oldProvider->getAllChunks(true) as $chunk){ + $new->saveChunk($chunk); + $counter++; + if(($counter % $reportInterval) === 0){ + $time = microtime(true); + $diff = $time - $thisRound; + $thisRound = $time; + $this->logger->info("Converted $counter / $count chunks (" . floor($reportInterval / $diff) . " chunks/sec)"); + } + } + $total = microtime(true) - $start; + $this->logger->info("Converted $counter / $counter chunks in " . round($total, 3) . " seconds (" . floor($counter / $total) . " chunks/sec)"); + } +} diff --git a/src/pocketmine/level/format/io/LevelProvider.php b/src/pocketmine/level/format/io/LevelProvider.php index 4a7e089e9a..e70bf2cc36 100644 --- a/src/pocketmine/level/format/io/LevelProvider.php +++ b/src/pocketmine/level/format/io/LevelProvider.php @@ -56,24 +56,6 @@ interface LevelProvider{ */ public static function isValid(string $path) : bool; - /** - * Generate the needed files in the path given - * - * @param string $path - * @param string $name - * @param int $seed - * @param string $generator - * @param array[] $options - */ - public static function generate(string $path, string $name, int $seed, string $generator, array $options = []) : void; - - /** - * Saves a chunk (usually to disk). - * - * @param Chunk $chunk - */ - public function saveChunk(Chunk $chunk) : void; - /** * Loads a chunk (usually from disk storage) and returns it. If the chunk does not exist, null is returned. * @@ -107,9 +89,14 @@ interface LevelProvider{ /** * Returns a generator which yields all the chunks in this level. * + * @param bool $skipCorrupted + * + * @param \Logger|null $logger + * * @return \Generator|Chunk[] + * @throws CorruptedChunkException */ - public function getAllChunks() : \Generator; + public function getAllChunks(bool $skipCorrupted = false, ?\Logger $logger = null) : \Generator; /** * Returns the number of chunks in the provider. Used for world conversion time estimations. diff --git a/src/pocketmine/level/format/io/LevelProviderManager.php b/src/pocketmine/level/format/io/LevelProviderManager.php index 5c9b33f5d1..7585f077e6 100644 --- a/src/pocketmine/level/format/io/LevelProviderManager.php +++ b/src/pocketmine/level/format/io/LevelProviderManager.php @@ -47,7 +47,7 @@ abstract class LevelProviderManager{ /** * Returns the default format used to generate new levels. * - * @return string + * @return string|WritableLevelProvider */ public static function getDefault() : string{ return self::$default; @@ -56,12 +56,12 @@ abstract class LevelProviderManager{ /** * Sets the default format. * - * @param string $class Class extending LevelProvider + * @param string $class Class implementing WritableLevelProvider * * @throws \InvalidArgumentException */ public static function setDefault(string $class) : void{ - Utils::testValidInstance($class, LevelProvider::class); + Utils::testValidInstance($class, WritableLevelProvider::class); self::$default = $class; } diff --git a/src/pocketmine/level/format/io/WritableLevelProvider.php b/src/pocketmine/level/format/io/WritableLevelProvider.php new file mode 100644 index 0000000000..fca2024d66 --- /dev/null +++ b/src/pocketmine/level/format/io/WritableLevelProvider.php @@ -0,0 +1,46 @@ +db->close(); } - public function getAllChunks() : \Generator{ + public function getAllChunks(bool $skipCorrupted = false, ?\Logger $logger = null) : \Generator{ foreach($this->db->getIterator() as $key => $_){ if(strlen($key) === 9 and substr($key, -1) === self::TAG_VERSION){ $chunkX = Binary::readLInt(substr($key, 0, 4)); $chunkZ = Binary::readLInt(substr($key, 4, 4)); - if(($chunk = $this->loadChunk($chunkX, $chunkZ)) !== null){ - yield $chunk; + try{ + if(($chunk = $this->loadChunk($chunkX, $chunkZ)) !== null){ + yield $chunk; + } + }catch(CorruptedChunkException $e){ + if(!$skipCorrupted){ + throw $e; + } + if($logger !== null){ + $logger->error("Skipped corrupted chunk $chunkX $chunkZ (" . $e->getMessage() . ")"); + } } } } diff --git a/src/pocketmine/level/format/io/region/Anvil.php b/src/pocketmine/level/format/io/region/Anvil.php index 998b41840e..abeef950d7 100644 --- a/src/pocketmine/level/format/io/region/Anvil.php +++ b/src/pocketmine/level/format/io/region/Anvil.php @@ -24,12 +24,13 @@ declare(strict_types=1); namespace pocketmine\level\format\io\region; use pocketmine\level\format\io\ChunkUtils; +use pocketmine\level\format\io\WritableLevelProvider; use pocketmine\level\format\SubChunk; use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\CompoundTag; use function str_repeat; -class Anvil extends RegionLevelProvider{ +class Anvil extends RegionLevelProvider implements WritableLevelProvider{ use LegacyAnvilChunkTrait; protected function serializeSubChunk(SubChunk $subChunk) : CompoundTag{ diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index 11aef62797..194662a845 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -26,6 +26,7 @@ namespace pocketmine\level\format\io\region; use pocketmine\level\format\Chunk; use pocketmine\level\format\io\ChunkUtils; use pocketmine\level\format\io\exception\CorruptedChunkException; +use pocketmine\level\format\io\WritableLevelProvider; use pocketmine\level\format\SubChunk; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NBT; @@ -37,7 +38,7 @@ use pocketmine\nbt\tag\ListTag; use function str_repeat; use function substr; -class McRegion extends RegionLevelProvider{ +class McRegion extends RegionLevelProvider implements WritableLevelProvider{ /** * @param Chunk $chunk diff --git a/src/pocketmine/level/format/io/region/PMAnvil.php b/src/pocketmine/level/format/io/region/PMAnvil.php index 566a5b82e0..a1b1f46e45 100644 --- a/src/pocketmine/level/format/io/region/PMAnvil.php +++ b/src/pocketmine/level/format/io/region/PMAnvil.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\level\format\io\region; +use pocketmine\level\format\io\WritableLevelProvider; use pocketmine\level\format\SubChunk; use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\CompoundTag; @@ -32,7 +33,7 @@ use function str_repeat; * This format is exactly the same as the PC Anvil format, with the only difference being that the stored data order * is XZY instead of YZX for more performance loading and saving worlds. */ -class PMAnvil extends RegionLevelProvider{ +class PMAnvil extends RegionLevelProvider implements WritableLevelProvider{ use LegacyAnvilChunkTrait; protected function serializeSubChunk(SubChunk $subChunk) : CompoundTag{ diff --git a/src/pocketmine/level/format/io/region/RegionLevelProvider.php b/src/pocketmine/level/format/io/region/RegionLevelProvider.php index 2a356ec131..56f8f1ef54 100644 --- a/src/pocketmine/level/format/io/region/RegionLevelProvider.php +++ b/src/pocketmine/level/format/io/region/RegionLevelProvider.php @@ -222,7 +222,7 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ ); } - public function getAllChunks() : \Generator{ + public function getAllChunks(bool $skipCorrupted = false, ?\Logger $logger = null) : \Generator{ $iterator = $this->createRegionIterator(); foreach($iterator as $region){ @@ -231,9 +231,18 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ for($chunkX = $rX; $chunkX < $rX + 32; ++$chunkX){ for($chunkZ = $rZ; $chunkZ < $rZ + 32; ++$chunkZ){ - $chunk = $this->loadChunk($chunkX, $chunkZ); - if($chunk !== null){ - yield $chunk; + try{ + $chunk = $this->loadChunk($chunkX, $chunkZ); + if($chunk !== null){ + yield $chunk; + } + }catch(CorruptedChunkException $e){ + if(!$skipCorrupted){ + throw $e; + } + if($logger !== null){ + $logger->error("Skipped corrupted chunk $chunkX $chunkZ (" . $e->getMessage() . ")"); + } } } } From 8d83d59cf09b1070759434c64818bd5dce7b3c34 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Mar 2019 18:59:37 +0000 Subject: [PATCH 0610/3224] Work around collisions in backup names --- .../level/format/io/FormatConverter.php | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/pocketmine/level/format/io/FormatConverter.php b/src/pocketmine/level/format/io/FormatConverter.php index b9bce909f0..c76778457b 100644 --- a/src/pocketmine/level/format/io/FormatConverter.php +++ b/src/pocketmine/level/format/io/FormatConverter.php @@ -25,11 +25,12 @@ namespace pocketmine\level\format\io; use pocketmine\utils\Utils; use function basename; +use function crc32; use function file_exists; use function floor; -use function is_dir; use function microtime; use function mkdir; +use function random_bytes; use function rename; use function round; use function rtrim; @@ -52,15 +53,16 @@ class FormatConverter{ $this->oldProvider = $oldProvider; Utils::testValidInstance($newProvider, WritableLevelProvider::class); $this->newProvider = $newProvider; - - $this->backupPath = $backupPath . DIRECTORY_SEPARATOR . basename($this->oldProvider->getPath()); - if(!file_exists($backupPath)){ - @mkdir($backupPath); - }elseif(!is_dir($backupPath)){ - throw new \RuntimeException("Backup path $backupPath exists and is not a directory"); - } - $this->logger = new \PrefixedLogger($logger, "World Converter - " . $this->oldProvider->getLevelData()->getName()); + + if(!file_exists($backupPath)){ + @mkdir($backupPath, 0777, true); + } + $nextSuffix = ""; + do{ + $this->backupPath = $backupPath . DIRECTORY_SEPARATOR . basename($this->oldProvider->getPath()) . $nextSuffix; + $nextSuffix = "_" . crc32(random_bytes(4)); + }while(file_exists($this->backupPath)); } public function getBackupPath() : string{ From 8cb24547ff2b3e385647ba4cfeffb6bea9231570 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Mar 2019 19:02:18 +0000 Subject: [PATCH 0611/3224] Goodbye McRegion o/ --- .../level/format/io/region/McRegion.php | 41 ++----------------- 1 file changed, 3 insertions(+), 38 deletions(-) diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index 194662a845..4059a48956 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -26,60 +26,25 @@ namespace pocketmine\level\format\io\region; use pocketmine\level\format\Chunk; use pocketmine\level\format\io\ChunkUtils; use pocketmine\level\format\io\exception\CorruptedChunkException; -use pocketmine\level\format\io\WritableLevelProvider; use pocketmine\level\format\SubChunk; use pocketmine\nbt\BigEndianNbtSerializer; -use pocketmine\nbt\NBT; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\ByteArrayTag; -use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntArrayTag; use pocketmine\nbt\tag\ListTag; use function str_repeat; use function substr; -class McRegion extends RegionLevelProvider implements WritableLevelProvider{ +class McRegion extends RegionLevelProvider{ /** * @param Chunk $chunk * * @return string + * @throws \RuntimeException */ protected function serializeChunk(Chunk $chunk) : string{ - $nbt = new CompoundTag("Level", []); - $nbt->setInt("xPos", $chunk->getX()); - $nbt->setInt("zPos", $chunk->getZ()); - - $nbt->setLong("LastUpdate", 0); //TODO - $nbt->setByte("TerrainPopulated", $chunk->isPopulated() ? 1 : 0); - $nbt->setByte("LightPopulated", 0); - - $ids = ""; - $data = ""; - $subChunks = $chunk->getSubChunks(); - for($x = 0; $x < 16; ++$x){ - for($z = 0; $z < 16; ++$z){ - for($y = 0; $y < 8; ++$y){ - $subChunk = $subChunks[$y]; - $ids .= substr($subChunk->getBlockIdArray(), ($x << 8) | ($z << 4), 16); - $data .= substr($subChunk->getBlockDataArray(), ($x << 7) | ($z << 3), 8); - } - } - } - - $nbt->setByteArray("Blocks", $ids); - $nbt->setByteArray("Data", $data); - $nbt->setByteArray("SkyLight", str_repeat("\x00", 16384)); - $nbt->setByteArray("BlockLight", str_repeat("\x00", 16384)); - - $nbt->setByteArray("Biomes", $chunk->getBiomeIdArray()); //doesn't exist in regular McRegion, this is here for PocketMine-MP only - $nbt->setByteArray("HeightMap", str_repeat("\x00", 256)); //this is ByteArray in McRegion, but IntArray in Anvil (due to raised build height) - - $nbt->setTag(new ListTag("Entities", $chunk->getNBTentities(), NBT::TAG_Compound)); - $nbt->setTag(new ListTag("TileEntities", $chunk->getNBTtiles(), NBT::TAG_Compound)); - - $writer = new BigEndianNbtSerializer(); - return $writer->writeCompressed(new CompoundTag("", [$nbt]), ZLIB_ENCODING_DEFLATE, RegionLoader::$COMPRESSION_LEVEL); + throw new \RuntimeException("Unsupported"); } /** From dfc26395e27ab88fa3f8da7e44d611dcd923303b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Mar 2019 23:31:23 +0000 Subject: [PATCH 0612/3224] Fixed missing logger injection --- src/pocketmine/level/format/io/FormatConverter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/level/format/io/FormatConverter.php b/src/pocketmine/level/format/io/FormatConverter.php index c76778457b..80d2d27077 100644 --- a/src/pocketmine/level/format/io/FormatConverter.php +++ b/src/pocketmine/level/format/io/FormatConverter.php @@ -132,7 +132,7 @@ class FormatConverter{ $start = microtime(true); $thisRound = $start; static $reportInterval = 256; - foreach($this->oldProvider->getAllChunks(true) as $chunk){ + foreach($this->oldProvider->getAllChunks(true, $this->logger) as $chunk){ $new->saveChunk($chunk); $counter++; if(($counter % $reportInterval) === 0){ From a858103e6b861cc889328ee73dbae2a5215309ac Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 4 Mar 2019 20:02:06 +0000 Subject: [PATCH 0613/3224] Support paletted subchunks, drop all formats except leveldb --- composer.json | 2 + composer.lock | 4 +- resources/legacy_id_map.json | 87 ++++++++++++- src/pocketmine/PocketMine.php | 2 + src/pocketmine/level/Level.php | 5 +- src/pocketmine/level/format/Chunk.php | 116 ++++++++++-------- src/pocketmine/level/format/EmptySubChunk.php | 24 +--- .../level/format/PalettedBlockArray.php | 53 ++++++++ src/pocketmine/level/format/SubChunk.php | 108 ++++++++-------- .../level/format/SubChunkInterface.php | 38 +----- .../level/format/io/LevelProviderManager.php | 2 +- .../level/format/io/SubChunkConverter.php | 37 ++++++ .../level/format/io/data/BedrockLevelData.php | 2 +- .../level/format/io/leveldb/LevelDB.php | 109 ++++++++++++---- .../level/format/io/region/Anvil.php | 21 +--- .../io/region/LegacyAnvilChunkTrait.php | 37 +----- .../level/format/io/region/McRegion.php | 16 +-- .../level/format/io/region/PMAnvil.php | 20 +-- .../level/generator/populator/GroundCover.php | 9 +- 19 files changed, 421 insertions(+), 271 deletions(-) create mode 100644 src/pocketmine/level/format/PalettedBlockArray.php create mode 100644 src/pocketmine/level/format/io/SubChunkConverter.php diff --git a/composer.json b/composer.json index 013babad38..a1ad3c1223 100644 --- a/composer.json +++ b/composer.json @@ -8,6 +8,7 @@ "php": ">=7.2.0", "php-64bit": "*", "ext-bcmath": "*", + "ext-chunkutils2": "^0.1.0", "ext-curl": "*", "ext-crypto": "^0.3.1", "ext-ctype": "*", @@ -16,6 +17,7 @@ "ext-gmp": "*", "ext-hash": "*", "ext-json": "*", + "ext-leveldb": "^0.2.1", "ext-mbstring": "*", "ext-openssl": "*", "ext-pcre": "*", diff --git a/composer.lock b/composer.lock index 7d512129d1..f46ba97f7c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d865f72c482e34c96a7e46bc535d0c15", + "content-hash": "7d9bec9f6226ca3ec19b06f6ed406718", "packages": [ { "name": "adhocore/json-comment", @@ -532,6 +532,7 @@ "php": ">=7.2.0", "php-64bit": "*", "ext-bcmath": "*", + "ext-chunkutils2": "^0.1.0", "ext-curl": "*", "ext-crypto": "^0.3.1", "ext-ctype": "*", @@ -540,6 +541,7 @@ "ext-gmp": "*", "ext-hash": "*", "ext-json": "*", + "ext-leveldb": "^0.2.1", "ext-mbstring": "*", "ext-openssl": "*", "ext-pcre": "*", diff --git a/resources/legacy_id_map.json b/resources/legacy_id_map.json index 3f83bf1241..9795ee3146 100644 --- a/resources/legacy_id_map.json +++ b/resources/legacy_id_map.json @@ -247,5 +247,88 @@ "minecraft:structure_block": 252, "minecraft:hard_glass": 253, "minecraft:hard_stained_glass": 254, - "minecraft:reserved6": 255 -} \ No newline at end of file + "minecraft:reserved6": 255, + "minecraft:prismarine_stairs": 257, + "minecraft:dark_prismarine_stairs": 258, + "minecraft:prismarine_bricks_stairs": 259, + "minecraft:stripped_spruce_log": 260, + "minecraft:stripped_birch_log": 261, + "minecraft:stripped_jungle_log": 262, + "minecraft:stripped_acacia_log": 263, + "minecraft:stripped_dark_oak_log": 264, + "minecraft:stripped_oak_log": 265, + "minecraft:blue_ice": 266, + "minecraft:seagrass": 385, + "minecraft:coral": 386, + "minecraft:coral_block": 387, + "minecraft:coral_fan": 388, + "minecraft:coral_fan_dead": 389, + "minecraft:coral_fan_hang": 390, + "minecraft:coral_fan_hang2": 391, + "minecraft:coral_fan_hang3": 392, + "minecraft:kelp": 393, + "minecraft:dried_kelp_block": 394, + "minecraft:acacia_button": 395, + "minecraft:birch_button": 396, + "minecraft:dark_oak_button": 397, + "minecraft:jungle_button": 398, + "minecraft:spruce_button": 399, + "minecraft:acacia_trapdoor": 400, + "minecraft:birch_trapdoor": 401, + "minecraft:dark_oak_trapdoor": 402, + "minecraft:jungle_trapdoor": 403, + "minecraft:spruce_trapdoor": 404, + "minecraft:acacia_pressure_plate": 405, + "minecraft:birch_pressure_plate": 406, + "minecraft:dark_oak_pressure_plate": 407, + "minecraft:jungle_pressure_plate": 408, + "minecraft:spruce_pressure_plate": 409, + "minecraft:carved_pumpkin": 410, + "minecraft:sea_pickle": 411, + "minecraft:conduit": 412, + "minecraft:turtle_egg": 414, + "minecraft:bubble_column": 415, + "minecraft:barrier": 416, + "minecraft:stone_slab3": 417, + "minecraft:bamboo": 418, + "minecraft:bamboo_sapling": 419, + "minecraft:scaffolding": 420, + "minecraft:stone_slab4": 421, + "minecraft:double_stone_slab3": 422, + "minecraft:double_stone_slab4": 423, + "minecraft:granite_stairs": 424, + "minecraft:diorite_stairs": 425, + "minecraft:andesite_stairs": 426, + "minecraft:polished_granite_stairs": 427, + "minecraft:polished_diorite_stairs": 428, + "minecraft:polished_andesite_stairs": 429, + "minecraft:mossy_stone_brick_stairs": 430, + "minecraft:smooth_red_sandstone_stairs": 431, + "minecraft:smooth_sandstone_stairs": 432, + "minecraft:end_brick_stairs": 433, + "minecraft:mossy_cobblestone_stairs": 434, + "minecraft:normal_stone_stairs": 435, + "minecraft:spruce_standing_sign": 436, + "minecraft:spruce_wall_sign": 437, + "minecraft:smooth_stone": 438, + "minecraft:red_nether_brick_stairs": 439, + "minecraft:smooth_quartz_stairs": 440, + "minecraft:birch_standing_sign": 441, + "minecraft:birch_wall_sign": 442, + "minecraft:jungle_standing_sign": 443, + "minecraft:jungle_wall_sign": 444, + "minecraft:acacia_standing_sign": 445, + "minecraft:acacia_wall_sign": 446, + "minecraft:darkoak_standing_sign": 447, + "minecraft:darkoak_wall_sign": 448, + "minecraft:grindstone": 450, + "minecraft:blast_furnace": 451, + "minecraft:smoker": 453, + "minecraft:cartography_table": 455, + "minecraft:fletching_table": 456, + "minecraft:smithing_table": 457, + "minecraft:barrel": 458, + "minecraft:bell": 461, + "minecraft:lantern": 463, + "minecraft:lava_cauldron": 465 +} diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index daf84e6cb1..f98081703f 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -76,6 +76,7 @@ namespace pocketmine { $extensions = [ "bcmath" => "BC Math", + "chunkutils2" => "PocketMine ChunkUtils v2", "curl" => "cURL", "crypto" => "php-crypto", "ctype" => "ctype", @@ -84,6 +85,7 @@ namespace pocketmine { "gmp" => "GMP", "hash" => "Hash", "json" => "JSON", + "leveldb" => "LevelDB", "mbstring" => "Multibyte String", "openssl" => "OpenSSL", "pcre" => "PCRE", diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 1c57ff5ca4..f8c3ffa841 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -28,6 +28,7 @@ namespace pocketmine\level; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\block\UnknownBlock; use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; @@ -380,7 +381,7 @@ class Level implements ChunkManager, Metadatable{ $dontTickBlocks = array_fill_keys($this->server->getProperty("chunk-ticking.disable-block-ticking", []), true); - $this->randomTickBlocks = new \SplFixedArray(4096); + $this->randomTickBlocks = new \SplFixedArray(16384); foreach($this->randomTickBlocks as $i => $null){ $id = $i >> 4; $meta = $i & 0xf; @@ -2783,7 +2784,7 @@ class Level implements ChunkManager, Metadatable{ $z = (int) $v->z; if($chunk !== null and $chunk->isGenerated()){ $y = (int) min($max - 2, $v->y); - $wasAir = ($chunk->getBlockId($x & 0x0f, $y - 1, $z & 0x0f) === 0); + $wasAir = $this->getBlockAt($x, $y - 1, $z)->getId() === BlockIds::AIR; //TODO: bad hack, clean up for(; $y > 0; --$y){ if($this->isFullBlock($this->getBlockAt($x, $y, $z))){ if($wasAir){ diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index 094205db79..476e69048b 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -27,10 +27,12 @@ declare(strict_types=1); namespace pocketmine\level\format; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; use pocketmine\level\Level; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\network\mcpe\NetworkBinaryStream; use pocketmine\Player; use pocketmine\tile\Spawnable; use pocketmine\tile\Tile; @@ -205,32 +207,6 @@ class Chunk{ return false; } - /** - * Returns the block ID at the specified chunk block coordinates - * - * @param int $x 0-15 - * @param int $y - * @param int $z 0-15 - * - * @return int 0-255 - */ - public function getBlockId(int $x, int $y, int $z) : int{ - return $this->getSubChunk($y >> 4)->getBlockId($x, $y & 0x0f, $z); - } - - /** - * Returns the block meta value at the specified chunk block coordinates - * - * @param int $x 0-15 - * @param int $y - * @param int $z 0-15 - * - * @return int 0-15 - */ - public function getBlockData(int $x, int $y, int $z) : int{ - return $this->getSubChunk($y >> 4)->getBlockData($x, $y & 0x0f, $z); - } - /** * Returns the sky light level at the specified chunk block coordinates * @@ -698,7 +674,7 @@ class Chunk{ if($y < 0 or $y >= $this->height){ return $this->emptySubChunk; }elseif($generateNew and $this->subChunks[$y] instanceof EmptySubChunk){ - $this->subChunks[$y] = new SubChunk(); + $this->subChunks[$y] = new SubChunk([new PalettedBlockArray(BlockIds::AIR << 4)]); } return $this->subChunks[$y]; @@ -765,10 +741,9 @@ class Chunk{ public function collectGarbage() : void{ foreach($this->subChunks as $y => $subChunk){ if($subChunk instanceof SubChunk){ + $subChunk->collectGarbage(); if($subChunk->isEmpty()){ $this->subChunks[$y] = $this->emptySubChunk; - }else{ - $subChunk->collectGarbage(); } } } @@ -780,24 +755,42 @@ class Chunk{ * @return string */ public function networkSerialize() : string{ - $result = ""; + $stream = new NetworkBinaryStream(); $subChunkCount = $this->getSubChunkSendCount(); - $result .= chr($subChunkCount); - for($y = 0; $y < $subChunkCount; ++$y){ - $result .= $this->subChunks[$y]->networkSerialize(); + $stream->putByte($subChunkCount); + + if(empty(BlockFactory::$staticRuntimeIdMap)){ + BlockFactory::registerStaticRuntimeIdMappings(); } - $result .= pack("v*", ...$this->heightMap) - . $this->biomeIds - . chr(0); //border block array count + + for($y = 0; $y < $subChunkCount; ++$y){ + $layers = $this->subChunks[$y]->getBlockLayers(); + $stream->putByte(8); //version + + $stream->putByte(count($layers)); + + foreach($layers as $blocks){ + $stream->putByte(($blocks->getBitsPerBlock() << 1) | 1); //last 1-bit means "network format", but seems pointless + $stream->put($blocks->getWordArray()); + $palette = $blocks->getPalette(); + $stream->putVarInt(count($palette)); //yes, this is intentionally zigzag + foreach($palette as $p){ + $stream->putVarInt(BlockFactory::toStaticRuntimeId($p >> 4, $p & 0xf)); + } + } + } + $stream->put(pack("v*", ...$this->heightMap)); + $stream->put($this->biomeIds); + $stream->putByte(0); //border block array count //Border block entry format: 1 byte (4 bits X, 4 bits Z). These are however useless since they crash the regular client. foreach($this->tiles as $tile){ if($tile instanceof Spawnable){ - $result .= $tile->getSerializedSpawnCompound(); + $stream->put($tile->getSerializedSpawnCompound()); } } - return $result; + return $stream->getBuffer(); } /** @@ -814,19 +807,35 @@ class Chunk{ if($this->terrainGenerated){ //subchunks $count = 0; - $subChunks = ""; + $subStream = new BinaryStream(); foreach($this->subChunks as $y => $subChunk){ if($subChunk instanceof EmptySubChunk){ continue; } ++$count; - $subChunks .= chr($y) . $subChunk->getBlockIdArray() . $subChunk->getBlockDataArray(); + + $subStream->putByte($y); + $layers = $subChunk->getBlockLayers(); + $subStream->putByte(count($subChunk->getBlockLayers())); + foreach($layers as $blocks){ + $wordArray = $blocks->getWordArray(); + $palette = $blocks->getPalette(); + + $subStream->putByte($blocks->getBitsPerBlock()); + $subStream->put($wordArray); + $subStream->putInt(count($palette)); + foreach($palette as $p){ + $subStream->putInt($p); + } + } + if($this->lightPopulated){ - $subChunks .= $subChunk->getBlockSkyLightArray() . $subChunk->getBlockLightArray(); + $subStream->put($subChunk->getBlockSkyLightArray()); + $subStream->put($subChunk->getBlockLightArray()); } } $stream->putByte($count); - $stream->put($subChunks); + $stream->put($subStream->getBuffer()); //biomes $stream->put($this->biomeIds); @@ -860,12 +869,23 @@ class Chunk{ $heightMap = []; if($terrainGenerated){ $count = $stream->getByte(); - for($y = 0; $y < $count; ++$y){ - $subChunks[$stream->getByte()] = new SubChunk( - $stream->get(4096), //blockids - $stream->get(2048), //blockdata - $lightPopulated ? $stream->get(2048) : "", //skylight - $lightPopulated ? $stream->get(2048) : "" //blocklight + for($subCount = 0; $subCount < $count; ++$subCount){ + $y = $stream->getByte(); + + /** @var PalettedBlockArray[] $layers */ + $layers = []; + for($i = 0, $layerCount = $stream->getByte(); $i < $layerCount; ++$i){ + $bitsPerBlock = $stream->getByte(); + $words = $stream->get(PalettedBlockArray::getExpectedWordArraySize($bitsPerBlock)); + $palette = []; + for($k = 0, $paletteSize = $stream->getInt(); $k < $paletteSize; ++$k){ + $palette[] = $stream->getInt(); + } + + $layers[] = PalettedBlockArray::fromData($bitsPerBlock, $words, $palette); + } + $subChunks[$y] = new SubChunk( + $layers, $lightPopulated ? $stream->get(2048) : "", $lightPopulated ? $stream->get(2048) : "" //blocklight ); } diff --git a/src/pocketmine/level/format/EmptySubChunk.php b/src/pocketmine/level/format/EmptySubChunk.php index a26341c6ae..f45a8b0717 100644 --- a/src/pocketmine/level/format/EmptySubChunk.php +++ b/src/pocketmine/level/format/EmptySubChunk.php @@ -41,14 +41,6 @@ class EmptySubChunk implements SubChunkInterface{ return true; } - public function getBlockId(int $x, int $y, int $z) : int{ - return 0; - } - - public function getBlockData(int $x, int $y, int $z) : int{ - return 0; - } - public function getFullBlock(int $x, int $y, int $z) : int{ return 0; } @@ -57,6 +49,10 @@ class EmptySubChunk implements SubChunkInterface{ return false; } + public function getBlockLayers() : array{ + return []; + } + public function getBlockLight(int $x, int $y, int $z) : int{ return 0; } @@ -77,14 +73,6 @@ class EmptySubChunk implements SubChunkInterface{ return -1; } - public function getBlockIdArray() : string{ - return str_repeat("\x00", 4096); - } - - public function getBlockDataArray() : string{ - return str_repeat("\x00", 2048); - } - public function getBlockLightArray() : string{ return str_repeat("\x00", 2048); } @@ -100,8 +88,4 @@ class EmptySubChunk implements SubChunkInterface{ public function setBlockSkyLightArray(string $data) : void{ } - - public function networkSerialize() : string{ - return "\x00" . str_repeat("\x00", 6144); - } } diff --git a/src/pocketmine/level/format/PalettedBlockArray.php b/src/pocketmine/level/format/PalettedBlockArray.php new file mode 100644 index 0000000000..90a380873d --- /dev/null +++ b/src/pocketmine/level/format/PalettedBlockArray.php @@ -0,0 +1,53 @@ +ids, $ids, 4096); - self::assignData($this->data, $data, 2048); + /** + * SubChunk constructor. + * + * @param PalettedBlockArray[] $blocks + * @param string $skyLight + * @param string $blockLight + */ + public function __construct(array $blocks, string $skyLight = "", string $blockLight = ""){ + $this->blockLayers = $blocks; + self::assignData($this->skyLight, $skyLight, 2048, "\xff"); self::assignData($this->blockLight, $blockLight, 2048); - $this->collectGarbage(); } public function isEmpty(bool $checkLight = true) : bool{ - return ( - substr_count($this->ids, "\x00") === 4096 and + foreach($this->blockLayers as $layer){ + $palette = $layer->getPalette(); + foreach($palette as $p){ + if(($p >> 4) !== BlockIds::AIR){ + return false; + } + } + } + return (!$checkLight or ( substr_count($this->skyLight, "\xff") === 2048 and $this->blockLight === ZERO_NIBBLE_ARRAY - )) + ) ); } - public function getBlockId(int $x, int $y, int $z) : int{ - return ord($this->ids{($x << 8) | ($z << 4) | $y}); - } - - public function getBlockData(int $x, int $y, int $z) : int{ - return (ord($this->data{($x << 7) | ($z << 3) | ($y >> 1)}) >> (($y & 1) << 2)) & 0xf; - } - public function getFullBlock(int $x, int $y, int $z) : int{ - $i = ($x << 8) | ($z << 4) | $y; - return (ord($this->ids{$i}) << 4) | ((ord($this->data{$i >> 1}) >> (($y & 1) << 2)) & 0xf); + if(empty($this->blockLayers)){ + return BlockIds::AIR << 4; + } + return $this->blockLayers[0]->get($x, $y, $z); } public function setBlock(int $x, int $y, int $z, int $id, int $data) : bool{ - $i = ($x << 8) | ($z << 4) | $y; - $changed = false; - - $block = chr($id); - if($this->ids{$i} !== $block){ - $this->ids{$i} = $block; - $changed = true; + if(empty($this->blockLayers)){ + $this->blockLayers[] = new PalettedBlockArray(BlockIds::AIR << 4); } + $this->blockLayers[0]->set($x, $y, $z, ($id << 4) | $data); + return true; + } - $i >>= 1; - $shift = ($y & 1) << 2; - $oldPair = ord($this->data{$i}); - $newPair = ($oldPair & ~(0xf << $shift)) | (($data & 0xf) << $shift); - if($newPair !== $oldPair){ - $this->data{$i} = chr($newPair); - $changed = true; - } - - return $changed; + /** + * @return PalettedBlockArray[] + */ + public function getBlockLayers() : array{ + return $this->blockLayers; } public function getBlockLight(int $x, int $y, int $z) : int{ @@ -136,7 +141,7 @@ class SubChunk implements SubChunkInterface{ $low = ($x << 8) | ($z << 4); $i = $low | 0x0f; for(; $i >= $low; --$i){ - if($this->ids{$i} !== "\x00"){ + if(($this->blockLayers[0]->get($x, $i, $z) >> 4) !== BlockIds::AIR){ return $i & 0x0f; } } @@ -144,16 +149,6 @@ class SubChunk implements SubChunkInterface{ return -1; //highest block not in this subchunk } - public function getBlockIdArray() : string{ - assert(strlen($this->ids) === 4096, "Wrong length of ID array, expecting 4096 bytes, got " . strlen($this->ids)); - return $this->ids; - } - - public function getBlockDataArray() : string{ - assert(strlen($this->data) === 2048, "Wrong length of data array, expecting 2048 bytes, got " . strlen($this->data)); - return $this->data; - } - public function getBlockSkyLightArray() : string{ assert(strlen($this->skyLight) === 2048, "Wrong length of skylight array, expecting 2048 bytes, got " . strlen($this->skyLight)); return $this->skyLight; @@ -174,23 +169,28 @@ class SubChunk implements SubChunkInterface{ $this->blockLight = $data; } - public function networkSerialize() : string{ - return "\x00" . $this->ids . $this->data; - } - public function __debugInfo(){ return []; } public function collectGarbage() : void{ + foreach($this->blockLayers as $k => $layer){ + $layer->collectGarbage(); + + foreach($layer->getPalette() as $p){ + if(($p >> 4) !== BlockIds::AIR){ + continue 2; + } + } + unset($this->blockLayers[$k]); + } + $this->blockLayers = array_values($this->blockLayers); + /* * This strange looking code is designed to exploit PHP's copy-on-write behaviour. Assigning will copy a * reference to the const instead of duplicating the whole string. The string will only be duplicated when * modified, which is perfect for this purpose. */ - if($this->data === ZERO_NIBBLE_ARRAY){ - $this->data = ZERO_NIBBLE_ARRAY; - } if($this->skyLight === ZERO_NIBBLE_ARRAY){ $this->skyLight = ZERO_NIBBLE_ARRAY; } diff --git a/src/pocketmine/level/format/SubChunkInterface.php b/src/pocketmine/level/format/SubChunkInterface.php index d058efd55e..6b57b6bec3 100644 --- a/src/pocketmine/level/format/SubChunkInterface.php +++ b/src/pocketmine/level/format/SubChunkInterface.php @@ -32,24 +32,6 @@ interface SubChunkInterface{ */ public function isEmpty(bool $checkLight = true) : bool; - /** - * @param int $x - * @param int $y - * @param int $z - * - * @return int - */ - public function getBlockId(int $x, int $y, int $z) : int; - - /** - * @param int $x - * @param int $y - * @param int $z - * - * @return int - */ - public function getBlockData(int $x, int $y, int $z) : int; - /** * @param int $x * @param int $y @@ -70,6 +52,11 @@ interface SubChunkInterface{ */ public function setBlock(int $x, int $y, int $z, int $id, int $data) : bool; + /** + * @return PalettedBlockArray[] + */ + public function getBlockLayers() : array; + /** * @param int $x * @param int $y @@ -116,16 +103,6 @@ interface SubChunkInterface{ */ public function getHighestBlockAt(int $x, int $z) : int; - /** - * @return string - */ - public function getBlockIdArray() : string; - - /** - * @return string - */ - public function getBlockDataArray() : string; - /** * @return string */ @@ -145,9 +122,4 @@ interface SubChunkInterface{ * @param string $data */ public function setBlockLightArray(string $data) : void; - - /** - * @return string - */ - public function networkSerialize() : string; } diff --git a/src/pocketmine/level/format/io/LevelProviderManager.php b/src/pocketmine/level/format/io/LevelProviderManager.php index 7585f077e6..75268fd883 100644 --- a/src/pocketmine/level/format/io/LevelProviderManager.php +++ b/src/pocketmine/level/format/io/LevelProviderManager.php @@ -35,7 +35,7 @@ abstract class LevelProviderManager{ protected static $providers = []; /** @var string|LevelProvider */ - private static $default = PMAnvil::class; + private static $default = LevelDB::class; public static function init() : void{ self::addProvider(Anvil::class, "anvil"); diff --git a/src/pocketmine/level/format/io/SubChunkConverter.php b/src/pocketmine/level/format/io/SubChunkConverter.php new file mode 100644 index 0000000000..8aaab68ce1 --- /dev/null +++ b/src/pocketmine/level/format/io/SubChunkConverter.php @@ -0,0 +1,37 @@ +getByte() >> 1; + + try{ + $words = $stream->get(PalettedBlockArray::getExpectedWordArraySize($bitsPerBlock)); + }catch(\InvalidArgumentException $e){ + throw new CorruptedChunkException("Failed to deserialize paletted storage: " . $e->getMessage(), 0, $e); + } + $nbt = new LittleEndianNbtSerializer(); + $palette = []; + for($i = 0, $paletteSize = $stream->getLInt(); $i < $paletteSize; ++$i){ + $offset = $stream->getOffset(); + $tag = $nbt->read($stream->getBuffer(), $offset); + $stream->setOffset($offset); + + $id = $stringToLegacyId[$tag->getString("name")] ?? BlockIds::INFO_UPDATE; + $data = $tag->getShort("val"); + $palette[] = ($id << 4) | $data; + } + + //TODO: exceptions + return PalettedBlockArray::fromData($bitsPerBlock, $words, $palette); + } + /** * @param int $chunkX * @param int $chunkZ @@ -159,6 +198,8 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ $binaryStream = new BinaryStream(); switch($chunkVersion){ + case 10: //MCPE 1.9 (???) + case 9: //MCPE 1.8 (???) case 7: //MCPE 1.2 (???) case 4: //MCPE 1.1 //TODO: check beds @@ -179,6 +220,12 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ switch($subChunkVersion){ case 0: + case 2: //these are all identical to version 0, but vanilla respects these so we should also + case 3: + case 4: + case 5: + case 6: + case 7: try{ $blocks = $binaryStream->get(4096); $blockData = $binaryStream->get(2048); @@ -191,7 +238,17 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ throw new CorruptedChunkException($e->getMessage(), 0, $e); } - $subChunks[$y] = new SubChunk($blocks, $blockData); + $subChunks[$y] = new SubChunk([SubChunkConverter::convertSubChunkXZY($blocks, $blockData)]); + break; + case 1: //paletted v1, has a single blockstorage + $subChunks[$y] = new SubChunk([$this->deserializePaletted($binaryStream)]); + break; + case 8: + $storages = []; + for($k = 0, $storageCount = $binaryStream->getByte(); $k < $storageCount; ++$k){ + $storages[] = $this->deserializePaletted($binaryStream); + } + $subChunks[$y] = new SubChunk($storages); break; default: //TODO: set chunks read-only so the version on disk doesn't get overwritten @@ -225,20 +282,7 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ } for($yy = 0; $yy < 8; ++$yy){ - $subOffset = ($yy << 4); - $ids = ""; - for($i = 0; $i < 256; ++$i){ - $ids .= substr($fullIds, $subOffset, 16); - $subOffset += 128; - } - $data = ""; - $subOffset = ($yy << 3); - for($i = 0; $i < 256; ++$i){ - $data .= substr($fullData, $subOffset, 8); - $subOffset += 64; - } - - $subChunks[$yy] = new SubChunk($ids, $data); + $subChunks[$yy] = new SubChunk([SubChunkConverter::convertSubChunkFromLegacyColumn($fullIds, $fullData, $yy)]); } try{ @@ -307,6 +351,10 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ } protected function writeChunk(Chunk $chunk) : void{ + static $idMap = null; + if($idMap === null){ + $idMap = array_flip(json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . '/legacy_id_map.json'), true)); + } $index = LevelDB::chunkIndex($chunk->getX(), $chunk->getZ()); $this->db->put($index . self::TAG_VERSION, chr(self::CURRENT_LEVEL_CHUNK_VERSION)); @@ -316,11 +364,30 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ if($subChunk->isEmpty(false)){ //MCPE doesn't save light anymore as of 1.1 $this->db->delete($key); }else{ - $this->db->put($key, - chr(self::CURRENT_LEVEL_SUBCHUNK_VERSION) . - $subChunk->getBlockIdArray() . - $subChunk->getBlockDataArray() - ); + $subStream = new BinaryStream(); + $subStream->putByte(self::CURRENT_LEVEL_SUBCHUNK_VERSION); + + $layers = $subChunk->getBlockLayers(); + $subStream->putByte(count($layers)); + foreach($layers as $blocks){ + $subStream->putByte($blocks->getBitsPerBlock() << 1); + $subStream->put($blocks->getWordArray()); + + $palette = $blocks->getPalette(); + $subStream->putLInt(count($palette)); + $tags = []; + foreach($palette as $p){ + $tags[] = new CompoundTag("", [ + new StringTag("name", $idMap[$p >> 4] ?? "minecraft:info_update"), + new IntTag("oldid", $p >> 4), //PM only (debugging), vanilla doesn't have this + new ShortTag("val", $p & 0xf) + ]); + } + + $subStream->put((new LittleEndianNbtSerializer())->writeMultiple($tags)); + } + + $this->db->put($key, $subStream->getBuffer()); } } diff --git a/src/pocketmine/level/format/io/region/Anvil.php b/src/pocketmine/level/format/io/region/Anvil.php index abeef950d7..6d81486b3c 100644 --- a/src/pocketmine/level/format/io/region/Anvil.php +++ b/src/pocketmine/level/format/io/region/Anvil.php @@ -23,31 +23,20 @@ declare(strict_types=1); namespace pocketmine\level\format\io\region; -use pocketmine\level\format\io\ChunkUtils; -use pocketmine\level\format\io\WritableLevelProvider; +use pocketmine\level\format\io\SubChunkConverter; use pocketmine\level\format\SubChunk; -use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\CompoundTag; -use function str_repeat; -class Anvil extends RegionLevelProvider implements WritableLevelProvider{ +class Anvil extends RegionLevelProvider{ use LegacyAnvilChunkTrait; protected function serializeSubChunk(SubChunk $subChunk) : CompoundTag{ - return new CompoundTag("", [ - new ByteArrayTag("Blocks", ChunkUtils::reorderByteArray($subChunk->getBlockIdArray())), //Generic in-memory chunks are currently always XZY - new ByteArrayTag("Data", ChunkUtils::reorderNibbleArray($subChunk->getBlockDataArray())), - new ByteArrayTag("SkyLight", str_repeat("\x00", 2048)), - new ByteArrayTag("BlockLight", str_repeat("\x00", 2048)) - ]); + throw new \RuntimeException("Unsupported"); } protected function deserializeSubChunk(CompoundTag $subChunk) : SubChunk{ - return new SubChunk( - ChunkUtils::reorderByteArray($subChunk->getByteArray("Blocks")), - ChunkUtils::reorderNibbleArray($subChunk->getByteArray("Data")) - //ignore legacy light information - ); + return new SubChunk([SubChunkConverter::convertSubChunkYZX($subChunk->getByteArray("Blocks"), $subChunk->getByteArray("Data"))]); + //ignore legacy light information } protected static function getRegionFileExtension() : string{ diff --git a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php b/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php index fc2ac45d0e..a60c914e30 100644 --- a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php @@ -28,12 +28,10 @@ use pocketmine\level\format\io\ChunkUtils; use pocketmine\level\format\io\exception\CorruptedChunkException; use pocketmine\level\format\SubChunk; use pocketmine\nbt\BigEndianNbtSerializer; -use pocketmine\nbt\NBT; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntArrayTag; use pocketmine\nbt\tag\ListTag; -use function array_fill; /** * Trait containing I/O methods for handling legacy Anvil-style chunks. @@ -49,42 +47,9 @@ use function array_fill; trait LegacyAnvilChunkTrait{ protected function serializeChunk(Chunk $chunk) : string{ - $nbt = new CompoundTag("Level", []); - $nbt->setInt("xPos", $chunk->getX()); - $nbt->setInt("zPos", $chunk->getZ()); - - $nbt->setByte("V", 1); - $nbt->setLong("LastUpdate", 0); //TODO - $nbt->setLong("InhabitedTime", 0); //TODO - $nbt->setByte("TerrainPopulated", $chunk->isPopulated() ? 1 : 0); - $nbt->setByte("LightPopulated", 0); - - $subChunks = []; - foreach($chunk->getSubChunks() as $y => $subChunk){ - if($subChunk->isEmpty()){ - continue; - } - - $tag = $this->serializeSubChunk($subChunk); - $tag->setByte("Y", $y); - $subChunks[] = $tag; - } - $nbt->setTag(new ListTag("Sections", $subChunks, NBT::TAG_Compound)); - - $nbt->setByteArray("Biomes", $chunk->getBiomeIdArray()); - $nbt->setIntArray("HeightMap", array_fill(0, 256, 0)); - - $nbt->setTag(new ListTag("Entities", $chunk->getNBTentities(), NBT::TAG_Compound)); - $nbt->setTag(new ListTag("TileEntities", $chunk->getNBTtiles(), NBT::TAG_Compound)); - - //TODO: TileTicks - - $writer = new BigEndianNbtSerializer(); - return $writer->writeCompressed(new CompoundTag("", [$nbt]), ZLIB_ENCODING_DEFLATE, RegionLoader::$COMPRESSION_LEVEL); + throw new \RuntimeException("Unsupported"); } - abstract protected function serializeSubChunk(SubChunk $subChunk) : CompoundTag; - /** * @param string $data * diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index 4059a48956..c4a81aa14c 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -26,6 +26,7 @@ namespace pocketmine\level\format\io\region; use pocketmine\level\format\Chunk; use pocketmine\level\format\io\ChunkUtils; use pocketmine\level\format\io\exception\CorruptedChunkException; +use pocketmine\level\format\io\SubChunkConverter; use pocketmine\level\format\SubChunk; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NbtDataException; @@ -33,7 +34,6 @@ use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\IntArrayTag; use pocketmine\nbt\tag\ListTag; use function str_repeat; -use function substr; class McRegion extends RegionLevelProvider{ @@ -71,19 +71,7 @@ class McRegion extends RegionLevelProvider{ $fullData = $chunk->hasTag("Data", ByteArrayTag::class) ? $chunk->getByteArray("Data") : str_repeat("\x00", 16384); for($y = 0; $y < 8; ++$y){ - $offset = ($y << 4); - $ids = ""; - for($i = 0; $i < 256; ++$i){ - $ids .= substr($fullIds, $offset, 16); - $offset += 128; - } - $data = ""; - $offset = ($y << 3); - for($i = 0; $i < 256; ++$i){ - $data .= substr($fullData, $offset, 8); - $offset += 64; - } - $subChunks[$y] = new SubChunk($ids, $data); + $subChunks[$y] = new SubChunk([SubChunkConverter::convertSubChunkFromLegacyColumn($fullIds, $fullData, $y)]); } if($chunk->hasTag("BiomeColors", IntArrayTag::class)){ diff --git a/src/pocketmine/level/format/io/region/PMAnvil.php b/src/pocketmine/level/format/io/region/PMAnvil.php index a1b1f46e45..c726ea6d40 100644 --- a/src/pocketmine/level/format/io/region/PMAnvil.php +++ b/src/pocketmine/level/format/io/region/PMAnvil.php @@ -23,33 +23,19 @@ declare(strict_types=1); namespace pocketmine\level\format\io\region; -use pocketmine\level\format\io\WritableLevelProvider; +use pocketmine\level\format\io\SubChunkConverter; use pocketmine\level\format\SubChunk; -use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\CompoundTag; -use function str_repeat; /** * This format is exactly the same as the PC Anvil format, with the only difference being that the stored data order * is XZY instead of YZX for more performance loading and saving worlds. */ -class PMAnvil extends RegionLevelProvider implements WritableLevelProvider{ +class PMAnvil extends RegionLevelProvider{ use LegacyAnvilChunkTrait; - protected function serializeSubChunk(SubChunk $subChunk) : CompoundTag{ - return new CompoundTag("", [ - new ByteArrayTag("Blocks", $subChunk->getBlockIdArray()), - new ByteArrayTag("Data", $subChunk->getBlockDataArray()), - new ByteArrayTag("SkyLight", str_repeat("\x00", 2048)), - new ByteArrayTag("BlockLight", str_repeat("\x00", 2048)) - ]); - } - protected function deserializeSubChunk(CompoundTag $subChunk) : SubChunk{ - return new SubChunk( - $subChunk->getByteArray("Blocks"), - $subChunk->getByteArray("Data") - ); + return new SubChunk([SubChunkConverter::convertSubChunkXZY($subChunk->getByteArray("Blocks"), $subChunk->getByteArray("Data"))]); } protected static function getRegionFileExtension() : string{ diff --git a/src/pocketmine/level/generator/populator/GroundCover.php b/src/pocketmine/level/generator/populator/GroundCover.php index 6127d66a0c..84e0405c86 100644 --- a/src/pocketmine/level/generator/populator/GroundCover.php +++ b/src/pocketmine/level/generator/populator/GroundCover.php @@ -47,8 +47,7 @@ class GroundCover extends Populator{ } for($y = 127; $y > 0; --$y){ - $id = $chunk->getBlockId($x, $y, $z); - if($id !== Block::AIR and !BlockFactory::get($id)->isTransparent()){ + if(!BlockFactory::fromFullBlock($chunk->getFullBlock($x, $y, $z))->isTransparent()){ break; } } @@ -56,11 +55,11 @@ class GroundCover extends Populator{ $endY = $startY - count($cover); for($y = $startY; $y > $endY and $y >= 0; --$y){ $b = $cover[$startY - $y]; - $id = $chunk->getBlockId($x, $y, $z); - if($id === Block::AIR and $b->isSolid()){ + $id = BlockFactory::fromFullBlock($chunk->getFullBlock($x, $y, $z)); + if($id->getId() === Block::AIR and $b->isSolid()){ break; } - if($b->canBeFlowedInto() and BlockFactory::get($id) instanceof Liquid){ + if($b->canBeFlowedInto() and $id instanceof Liquid){ continue; } From 7aa4c18afa7828213e05c49b17007d087bea60f8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 4 Mar 2019 16:50:10 -0500 Subject: [PATCH 0614/3224] Fixed assert failure in SubChunk --- src/pocketmine/level/format/SubChunk.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/level/format/SubChunk.php b/src/pocketmine/level/format/SubChunk.php index cd3ceb0c9d..857277fe8b 100644 --- a/src/pocketmine/level/format/SubChunk.php +++ b/src/pocketmine/level/format/SubChunk.php @@ -138,11 +138,9 @@ class SubChunk implements SubChunkInterface{ } public function getHighestBlockAt(int $x, int $z) : int{ - $low = ($x << 8) | ($z << 4); - $i = $low | 0x0f; - for(; $i >= $low; --$i){ - if(($this->blockLayers[0]->get($x, $i, $z) >> 4) !== BlockIds::AIR){ - return $i & 0x0f; + for($y = 15; $y >= 0; --$y){ + if(($this->blockLayers[0]->get($x, $y, $z) >> 4) !== BlockIds::AIR){ + return $y; } } From 18e16f8615b6c0907a725ae1c87888c05fa73684 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 4 Mar 2019 16:54:44 -0500 Subject: [PATCH 0615/3224] Fixed blockID truncation --- src/pocketmine/level/format/Chunk.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index 476e69048b..e1555dd8fb 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -200,7 +200,7 @@ class Chunk{ * @return bool */ public function setBlock(int $x, int $y, int $z, int $blockId, int $meta) : bool{ - if($this->getSubChunk($y >> 4, true)->setBlock($x, $y & 0x0f, $z, $blockId & 0xff, $meta & 0x0f)){ + if($this->getSubChunk($y >> 4, true)->setBlock($x, $y & 0x0f, $z, $blockId, $meta & 0x0f)){ $this->hasChanged = true; return true; } From 85e1b77caeb352b5088269be6938c4772976965f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Mar 2019 04:14:28 -0500 Subject: [PATCH 0616/3224] fix crash in getHighestBlockAt() --- src/pocketmine/level/format/SubChunk.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pocketmine/level/format/SubChunk.php b/src/pocketmine/level/format/SubChunk.php index 857277fe8b..4a4aa4f43c 100644 --- a/src/pocketmine/level/format/SubChunk.php +++ b/src/pocketmine/level/format/SubChunk.php @@ -138,6 +138,9 @@ class SubChunk implements SubChunkInterface{ } public function getHighestBlockAt(int $x, int $z) : int{ + if(empty($this->blockLayers)){ + return -1; + } for($y = 15; $y >= 0; --$y){ if(($this->blockLayers[0]->get($x, $y, $z) >> 4) !== BlockIds::AIR){ return $y; From 84bbd14a2198b963c8d12e6f728ba0416a7cf299 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Mar 2019 09:39:53 +0000 Subject: [PATCH 0617/3224] fixed wrong generator being set on converted worlds --- src/pocketmine/level/format/io/FormatConverter.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/level/format/io/FormatConverter.php b/src/pocketmine/level/format/io/FormatConverter.php index 80d2d27077..574deb9029 100644 --- a/src/pocketmine/level/format/io/FormatConverter.php +++ b/src/pocketmine/level/format/io/FormatConverter.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\level\format\io; +use pocketmine\level\generator\GeneratorManager; use pocketmine\utils\Utils; use function basename; use function crc32; @@ -99,7 +100,7 @@ class FormatConverter{ $this->logger->info("Found previous conversion attempt, deleting..."); Utils::recursiveUnlink($convertedOutput); } - $this->newProvider::generate($convertedOutput, $data->getName(), $data->getSeed(), $data->getGenerator(), $data->getGeneratorOptions()); + $this->newProvider::generate($convertedOutput, $data->getName(), $data->getSeed(), GeneratorManager::getGenerator($data->getGenerator()), $data->getGeneratorOptions()); /** * @see WritableLevelProvider::__construct() From c2a069afd3f1e0972b9278cb8cded79e273a16fa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Mar 2019 16:27:24 +0000 Subject: [PATCH 0618/3224] Implemented a bunch of new wood blocks --- src/pocketmine/block/BlockFactory.php | 34 ++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index e33fee7bb3..9901708c66 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -273,7 +273,6 @@ class BlockFactory{ self::register(new Torch(new BID(Block::COLORED_TORCH_RG), "Red Torch")); self::register(new Torch(new BID(Block::COLORED_TORCH_RG, 8), "Green Torch")); self::register(new Torch(new BID(Block::TORCH), "Torch")); - self::register(new Trapdoor(new BID(Block::TRAPDOOR), "Wooden Trapdoor")); self::register(new TrappedChest(new BID(Block::TRAPPED_CHEST, 0, null, \pocketmine\tile\Chest::class), "Trapped Chest")); self::register(new Tripwire(new BID(Block::TRIPWIRE, 0, ItemIds::STRING), "Tripwire")); self::register(new TripwireHook(new BID(Block::TRIPWIRE_HOOK), "Tripwire Hook")); @@ -284,8 +283,6 @@ class BlockFactory{ self::register(new WeightedPressurePlateHeavy(new BID(Block::HEAVY_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Heavy")); self::register(new WeightedPressurePlateLight(new BID(Block::LIGHT_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Light")); self::register(new Wheat(new BID(Block::WHEAT_BLOCK), "Wheat Block")); - self::register(new WoodenButton(new BID(Block::WOODEN_BUTTON), "Wooden Button")); - self::register(new WoodenPressurePlate(new BID(Block::WOODEN_PRESSURE_PLATE), "Wooden Pressure Plate")); /** @var int[]|\SplObjectStorage $woodenStairIds */ $woodenStairIds = new \SplObjectStorage(); @@ -314,6 +311,33 @@ class BlockFactory{ $woodenDoorIds[TreeType::ACACIA()] = new BID(Block::ACACIA_DOOR_BLOCK, 0, ItemIds::ACACIA_DOOR); $woodenDoorIds[TreeType::DARK_OAK()] = new BID(Block::DARK_OAK_DOOR_BLOCK, 0, ItemIds::DARK_OAK_DOOR); + /** @var int[]|\SplObjectStorage $woodenPressurePlateIds */ + $woodenPressurePlateIds = new \SplObjectStorage(); + $woodenPressurePlateIds[TreeType::OAK()] = Block::WOODEN_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::SPRUCE()] = Block::SPRUCE_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::BIRCH()] = Block::BIRCH_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::JUNGLE()] = Block::JUNGLE_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::ACACIA()] = Block::ACACIA_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::DARK_OAK()] = Block::DARK_OAK_PRESSURE_PLATE; + + /** @var int[]|\SplObjectStorage $woodenButtonIds */ + $woodenButtonIds = new \SplObjectStorage(); + $woodenButtonIds[TreeType::OAK()] = Block::WOODEN_BUTTON; + $woodenButtonIds[TreeType::SPRUCE()] = Block::SPRUCE_BUTTON; + $woodenButtonIds[TreeType::BIRCH()] = Block::BIRCH_BUTTON; + $woodenButtonIds[TreeType::JUNGLE()] = Block::JUNGLE_BUTTON; + $woodenButtonIds[TreeType::ACACIA()] = Block::ACACIA_BUTTON; + $woodenButtonIds[TreeType::DARK_OAK()] = Block::DARK_OAK_BUTTON; + + /** @var int[]|\SplObjectStorage $woodenTrapdoorIds */ + $woodenTrapdoorIds = new \SplObjectStorage(); + $woodenTrapdoorIds[TreeType::OAK()] = Block::WOODEN_TRAPDOOR; + $woodenTrapdoorIds[TreeType::SPRUCE()] = Block::SPRUCE_TRAPDOOR; + $woodenTrapdoorIds[TreeType::BIRCH()] = Block::BIRCH_TRAPDOOR; + $woodenTrapdoorIds[TreeType::JUNGLE()] = Block::JUNGLE_TRAPDOOR; + $woodenTrapdoorIds[TreeType::ACACIA()] = Block::ACACIA_TRAPDOOR; + $woodenTrapdoorIds[TreeType::DARK_OAK()] = Block::DARK_OAK_TRAPDOOR; + foreach(TreeType::getAll() as $treeType){ $magicNumber = $treeType->getMagicNumber(); $name = $treeType->getDisplayName(); @@ -330,6 +354,10 @@ class BlockFactory{ self::register(new FenceGate(new BID($fenceGateIds[$treeType]), $treeType->getDisplayName() . " Fence Gate")); self::register(new WoodenStairs(new BID($woodenStairIds[$treeType]), $treeType->getDisplayName() . " Stairs")); self::register(new WoodenDoor($woodenDoorIds[$treeType], $treeType->getDisplayName() . " Door")); + + self::register(new WoodenButton(new BID($woodenButtonIds[$treeType]), $treeType->getDisplayName() . " Button")); + self::register(new WoodenPressurePlate(new BID($woodenPressurePlateIds[$treeType]), $treeType->getDisplayName() . " Pressure Plate")); + self::register(new Trapdoor(new BID($woodenTrapdoorIds[$treeType]), $treeType->getDisplayName() . " Trapdoor")); } static $sandstoneTypes = [ From 437750785feb13774c69525591b13160bbcab168 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Mar 2019 18:00:41 +0000 Subject: [PATCH 0619/3224] Implemented barrier block --- src/pocketmine/block/Barrier.php | 41 +++++++++++++++++++++++++++ src/pocketmine/block/BlockFactory.php | 1 + 2 files changed, 42 insertions(+) create mode 100644 src/pocketmine/block/Barrier.php diff --git a/src/pocketmine/block/Barrier.php b/src/pocketmine/block/Barrier.php new file mode 100644 index 0000000000..e00db80f20 --- /dev/null +++ b/src/pocketmine/block/Barrier.php @@ -0,0 +1,41 @@ + Date: Sat, 9 Mar 2019 17:41:29 +0000 Subject: [PATCH 0620/3224] Regenerated BlockFactory TODOs --- src/pocketmine/block/BlockFactory.php | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 27268b1d68..f23a734438 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -424,22 +424,15 @@ class BlockFactory{ self::register(new CobblestoneWall(new BID(Block::COBBLESTONE_WALL, $magicNumber), $prefix . " Wall")); } - //TODO: minecraft:acacia_button - //TODO: minecraft:acacia_pressure_plate //TODO: minecraft:acacia_standing_sign - //TODO: minecraft:acacia_trapdoor //TODO: minecraft:acacia_wall_sign //TODO: minecraft:andesite_stairs //TODO: minecraft:bamboo //TODO: minecraft:bamboo_sapling //TODO: minecraft:barrel - //TODO: minecraft:barrier //TODO: minecraft:beacon //TODO: minecraft:bell - //TODO: minecraft:birch_button - //TODO: minecraft:birch_pressure_plate //TODO: minecraft:birch_standing_sign - //TODO: minecraft:birch_trapdoor //TODO: minecraft:birch_wall_sign //TODO: minecraft:blast_furnace //TODO: minecraft:blue_ice @@ -461,9 +454,6 @@ class BlockFactory{ //TODO: minecraft:coral_fan_hang //TODO: minecraft:coral_fan_hang2 //TODO: minecraft:coral_fan_hang3 - //TODO: minecraft:dark_oak_button - //TODO: minecraft:dark_oak_pressure_plate - //TODO: minecraft:dark_oak_trapdoor //TODO: minecraft:dark_prismarine_stairs //TODO: minecraft:darkoak_standing_sign //TODO: minecraft:darkoak_wall_sign @@ -471,7 +461,6 @@ class BlockFactory{ //TODO: minecraft:dispenser //TODO: minecraft:double_stone_slab3 //TODO: minecraft:double_stone_slab4 - //TODO: minecraft:dragon_egg //TODO: minecraft:dried_kelp_block //TODO: minecraft:dropper //TODO: minecraft:element_0 @@ -479,15 +468,11 @@ class BlockFactory{ //TODO: minecraft:end_gateway //TODO: minecraft:end_portal //TODO: minecraft:fletching_table - //TODO: minecraft:frosted_ice //TODO: minecraft:granite_stairs //TODO: minecraft:grindstone //TODO: minecraft:hopper //TODO: minecraft:jukebox - //TODO: minecraft:jungle_button - //TODO: minecraft:jungle_pressure_plate //TODO: minecraft:jungle_standing_sign - //TODO: minecraft:jungle_trapdoor //TODO: minecraft:jungle_wall_sign //TODO: minecraft:kelp //TODO: minecraft:lantern @@ -504,7 +489,6 @@ class BlockFactory{ //TODO: minecraft:polished_diorite_stairs //TODO: minecraft:polished_granite_stairs //TODO: minecraft:portal - //TODO: minecraft:powered_comparator //TODO: minecraft:prismarine_bricks_stairs //TODO: minecraft:prismarine_stairs //TODO: minecraft:red_nether_brick_stairs @@ -520,10 +504,7 @@ class BlockFactory{ //TODO: minecraft:smooth_red_sandstone_stairs //TODO: minecraft:smooth_sandstone_stairs //TODO: minecraft:smooth_stone - //TODO: minecraft:spruce_button - //TODO: minecraft:spruce_pressure_plate //TODO: minecraft:spruce_standing_sign - //TODO: minecraft:spruce_trapdoor //TODO: minecraft:spruce_wall_sign //TODO: minecraft:sticky_piston //TODO: minecraft:stone_slab3 @@ -537,7 +518,6 @@ class BlockFactory{ //TODO: minecraft:structure_block //TODO: minecraft:turtle_egg //TODO: minecraft:undyed_shulker_box - //TODO: minecraft:unpowered_comparator } public static function isInit() : bool{ From 13bea6c7873a64c08e872971d227d119fd87dc61 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Sun, 10 Mar 2019 15:18:03 +0000 Subject: [PATCH 0621/3224] Updated Travis configuration --- .travis.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/.travis.yml b/.travis.yml index 68590462f1..b86d5c9b95 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ +dist: xenial language: php php: @@ -5,6 +6,22 @@ php: - 7.3 before_script: + - LEVELDB_VERSION=f1463cb0b2486b0caf7d42ca3c7684545e875f04 + - curl -fsSL "https://github.com/pmmp/leveldb-mcpe/archive/f1463cb0b2486b0caf7d42ca3c7684545e875f04.tar.gz" | tar -zx + - mv leveldb-mcpe-$LEVELDB_VERSION leveldb-mcpe + - cd leveldb-mcpe && make -j4 && mv out-shared/libleveldb.* . && cd .. + - git clone https://github.com/reeze/php-leveldb.git leveldb + - cd leveldb + - git checkout 9bcae79f71b81a5c3ea6f67e45ae9ae9fb2775a5 + - phpize + - ./configure --with-leveldb=../leveldb-mcpe && make && make install + - cd .. + - git clone https://github.com/pmmp/ext-chunkutils2.git chunkutils + - cd chunkutils + - git checkout 5c96eeea7667ef15aa684b6a455a2a46699aff37 + - phpize + - ./configure && make && make install + - cd .. # - pecl install channel://pecl.php.net/pthreads-3.1.6 - echo | pecl install channel://pecl.php.net/yaml-2.0.4 - pecl install channel://pecl.php.net/crypto-0.3.1 @@ -18,6 +35,8 @@ before_script: - make install - cd .. - echo "extension=pthreads.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini + - echo "extension=chunkutils2.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini + - echo "extension=leveldb.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini - composer install script: From 1d4f44d25958b4954fb96134542dc6ad2e098dd5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 10 Mar 2019 16:48:25 +0000 Subject: [PATCH 0622/3224] Updated BlockFactory consistency check data --- tests/phpunit/block/block_factory_consistency_check.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index a49775bb7a..bf6878d676 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Moss Stone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Sign","1009":"Sign","1010":"Sign","1011":"Sign","1012":"Sign","1013":"Sign","1014":"Sign","1015":"Sign","1016":"Sign","1017":"Sign","1018":"Sign","1019":"Sign","1020":"Sign","1021":"Sign","1022":"Sign","1023":"Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Sign","1090":"Sign","1091":"Sign","1092":"Sign","1093":"Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Wooden Pressure Plate","1153":"Wooden Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Wooden Trapdoor","1537":"Wooden Trapdoor","1538":"Wooden Trapdoor","1539":"Wooden Trapdoor","1540":"Wooden Trapdoor","1541":"Wooden Trapdoor","1542":"Wooden Trapdoor","1543":"Wooden Trapdoor","1544":"Wooden Trapdoor","1545":"Wooden Trapdoor","1546":"Wooden Trapdoor","1547":"Wooden Trapdoor","1548":"Wooden Trapdoor","1549":"Wooden Trapdoor","1550":"Wooden Trapdoor","1551":"Wooden Trapdoor","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Wooden Button","2289":"Wooden Button","2290":"Wooden Button","2291":"Wooden Button","2292":"Wooden Button","2293":"Wooden Button","2296":"Wooden Button","2297":"Wooden Button","2298":"Wooden Button","2299":"Wooden Button","2300":"Wooden Button","2301":"Wooden Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Moss Stone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Sign","1009":"Sign","1010":"Sign","1011":"Sign","1012":"Sign","1013":"Sign","1014":"Sign","1015":"Sign","1016":"Sign","1017":"Sign","1018":"Sign","1019":"Sign","1020":"Sign","1021":"Sign","1022":"Sign","1023":"Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Sign","1090":"Sign","1091":"Sign","1092":"Sign","1093":"Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6656":"Barrier"} \ No newline at end of file From 2e4b3d3d46448d0ca013d2114d77cef833c16d87 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Mar 2019 17:38:02 +0000 Subject: [PATCH 0623/3224] Sync legacyID map (thanks @MCMrARM) --- resources/legacy_id_map.json | 118 +++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/resources/legacy_id_map.json b/resources/legacy_id_map.json index 9795ee3146..89fe0bbe83 100644 --- a/resources/legacy_id_map.json +++ b/resources/legacy_id_map.json @@ -258,6 +258,124 @@ "minecraft:stripped_dark_oak_log": 264, "minecraft:stripped_oak_log": 265, "minecraft:blue_ice": 266, + "minecraft:element_1": 267, + "minecraft:element_2": 268, + "minecraft:element_3": 269, + "minecraft:element_4": 270, + "minecraft:element_5": 271, + "minecraft:element_6": 272, + "minecraft:element_7": 273, + "minecraft:element_8": 274, + "minecraft:element_9": 275, + "minecraft:element_10": 276, + "minecraft:element_11": 277, + "minecraft:element_12": 278, + "minecraft:element_13": 279, + "minecraft:element_14": 280, + "minecraft:element_15": 281, + "minecraft:element_16": 282, + "minecraft:element_17": 283, + "minecraft:element_18": 284, + "minecraft:element_19": 285, + "minecraft:element_20": 286, + "minecraft:element_21": 287, + "minecraft:element_22": 288, + "minecraft:element_23": 289, + "minecraft:element_24": 290, + "minecraft:element_25": 291, + "minecraft:element_26": 292, + "minecraft:element_27": 293, + "minecraft:element_28": 294, + "minecraft:element_29": 295, + "minecraft:element_30": 296, + "minecraft:element_31": 297, + "minecraft:element_32": 298, + "minecraft:element_33": 299, + "minecraft:element_34": 300, + "minecraft:element_35": 301, + "minecraft:element_36": 302, + "minecraft:element_37": 303, + "minecraft:element_38": 304, + "minecraft:element_39": 305, + "minecraft:element_40": 306, + "minecraft:element_41": 307, + "minecraft:element_42": 308, + "minecraft:element_43": 309, + "minecraft:element_44": 310, + "minecraft:element_45": 311, + "minecraft:element_46": 312, + "minecraft:element_47": 313, + "minecraft:element_48": 314, + "minecraft:element_49": 315, + "minecraft:element_50": 316, + "minecraft:element_51": 317, + "minecraft:element_52": 318, + "minecraft:element_53": 319, + "minecraft:element_54": 320, + "minecraft:element_55": 321, + "minecraft:element_56": 322, + "minecraft:element_57": 323, + "minecraft:element_58": 324, + "minecraft:element_59": 325, + "minecraft:element_60": 326, + "minecraft:element_61": 327, + "minecraft:element_62": 328, + "minecraft:element_63": 329, + "minecraft:element_64": 330, + "minecraft:element_65": 331, + "minecraft:element_66": 332, + "minecraft:element_67": 333, + "minecraft:element_68": 334, + "minecraft:element_69": 335, + "minecraft:element_70": 336, + "minecraft:element_71": 337, + "minecraft:element_72": 338, + "minecraft:element_73": 339, + "minecraft:element_74": 340, + "minecraft:element_75": 341, + "minecraft:element_76": 342, + "minecraft:element_77": 343, + "minecraft:element_78": 344, + "minecraft:element_79": 345, + "minecraft:element_80": 346, + "minecraft:element_81": 347, + "minecraft:element_82": 348, + "minecraft:element_83": 349, + "minecraft:element_84": 350, + "minecraft:element_85": 351, + "minecraft:element_86": 352, + "minecraft:element_87": 353, + "minecraft:element_88": 354, + "minecraft:element_89": 355, + "minecraft:element_90": 356, + "minecraft:element_91": 357, + "minecraft:element_92": 358, + "minecraft:element_93": 359, + "minecraft:element_94": 360, + "minecraft:element_95": 361, + "minecraft:element_96": 362, + "minecraft:element_97": 363, + "minecraft:element_98": 364, + "minecraft:element_99": 365, + "minecraft:element_100": 366, + "minecraft:element_101": 367, + "minecraft:element_102": 368, + "minecraft:element_103": 369, + "minecraft:element_104": 370, + "minecraft:element_105": 371, + "minecraft:element_106": 372, + "minecraft:element_107": 373, + "minecraft:element_108": 374, + "minecraft:element_109": 375, + "minecraft:element_110": 376, + "minecraft:element_111": 377, + "minecraft:element_112": 378, + "minecraft:element_113": 379, + "minecraft:element_114": 380, + "minecraft:element_115": 381, + "minecraft:element_116": 382, + "minecraft:element_117": 383, + "minecraft:element_118": 384, "minecraft:seagrass": 385, "minecraft:coral": 386, "minecraft:coral_block": 387, From 8b9eeb0b7fb3351d5a62e78aa4615d27d5832fa8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 12 Mar 2019 18:53:51 +0000 Subject: [PATCH 0624/3224] Clean up Armor classes --- src/pocketmine/item/Armor.php | 23 ++++++++++ .../{ChainBoots.php => ArmorTypeInfo.php} | 22 +++++++--- .../item/{GoldBoots.php => Boots.php} | 14 ++----- src/pocketmine/item/ChainChestplate.php | 39 ----------------- src/pocketmine/item/ChainHelmet.php | 39 ----------------- src/pocketmine/item/ChainLeggings.php | 39 ----------------- .../item/{IronBoots.php => Chestplate.php} | 14 ++----- src/pocketmine/item/DiamondBoots.php | 39 ----------------- src/pocketmine/item/DiamondChestplate.php | 39 ----------------- src/pocketmine/item/DiamondHelmet.php | 39 ----------------- src/pocketmine/item/DiamondLeggings.php | 39 ----------------- src/pocketmine/item/GoldChestplate.php | 39 ----------------- src/pocketmine/item/GoldLeggings.php | 39 ----------------- .../item/{LeatherCap.php => Helmet.php} | 14 ++----- src/pocketmine/item/IronChestplate.php | 39 ----------------- src/pocketmine/item/IronHelmet.php | 39 ----------------- src/pocketmine/item/IronLeggings.php | 39 ----------------- src/pocketmine/item/ItemFactory.php | 42 +++++++++---------- src/pocketmine/item/LeatherBoots.php | 39 ----------------- src/pocketmine/item/LeatherPants.php | 39 ----------------- src/pocketmine/item/LeatherTunic.php | 39 ----------------- .../item/{GoldHelmet.php => Leggings.php} | 14 ++----- 22 files changed, 77 insertions(+), 651 deletions(-) rename src/pocketmine/item/{ChainBoots.php => ArmorTypeInfo.php} (69%) rename src/pocketmine/item/{GoldBoots.php => Boots.php} (76%) delete mode 100644 src/pocketmine/item/ChainChestplate.php delete mode 100644 src/pocketmine/item/ChainHelmet.php delete mode 100644 src/pocketmine/item/ChainLeggings.php rename src/pocketmine/item/{IronBoots.php => Chestplate.php} (76%) delete mode 100644 src/pocketmine/item/DiamondBoots.php delete mode 100644 src/pocketmine/item/DiamondChestplate.php delete mode 100644 src/pocketmine/item/DiamondHelmet.php delete mode 100644 src/pocketmine/item/DiamondLeggings.php delete mode 100644 src/pocketmine/item/GoldChestplate.php delete mode 100644 src/pocketmine/item/GoldLeggings.php rename src/pocketmine/item/{LeatherCap.php => Helmet.php} (76%) delete mode 100644 src/pocketmine/item/IronChestplate.php delete mode 100644 src/pocketmine/item/IronHelmet.php delete mode 100644 src/pocketmine/item/IronLeggings.php delete mode 100644 src/pocketmine/item/LeatherBoots.php delete mode 100644 src/pocketmine/item/LeatherPants.php delete mode 100644 src/pocketmine/item/LeatherTunic.php rename src/pocketmine/item/{GoldHelmet.php => Leggings.php} (76%) diff --git a/src/pocketmine/item/Armor.php b/src/pocketmine/item/Armor.php index e5852f1634..8b2d641b9e 100644 --- a/src/pocketmine/item/Armor.php +++ b/src/pocketmine/item/Armor.php @@ -25,6 +25,7 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\event\entity\EntityDamageEvent; +use pocketmine\inventory\ArmorInventory; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\ProtectionEnchantment; use pocketmine\nbt\tag\IntTag; @@ -37,6 +38,28 @@ abstract class Armor extends Durable{ public const TAG_CUSTOM_COLOR = "customColor"; //TAG_Int + /** @var ArmorTypeInfo */ + private $armorInfo; + + public function __construct(int $id, int $variant, string $name, ArmorTypeInfo $info){ + parent::__construct($id, $variant, $name); + $this->armorInfo = $info; + } + + public function getMaxDurability() : int{ + return $this->armorInfo->getMaxDurability(); + } + + public function getDefensePoints() : int{ + return $this->armorInfo->getDefensePoints(); + } + + /** + * @see ArmorInventory + * @return int + */ + abstract public function getArmorSlot() : int; + public function getMaxStackSize() : int{ return 1; } diff --git a/src/pocketmine/item/ChainBoots.php b/src/pocketmine/item/ArmorTypeInfo.php similarity index 69% rename from src/pocketmine/item/ChainBoots.php rename to src/pocketmine/item/ArmorTypeInfo.php index 9048917733..9a89a0c5df 100644 --- a/src/pocketmine/item/ChainBoots.php +++ b/src/pocketmine/item/ArmorTypeInfo.php @@ -23,17 +23,29 @@ declare(strict_types=1); namespace pocketmine\item; +class ArmorTypeInfo{ -class ChainBoots extends Armor{ - public function __construct(){ - parent::__construct(self::CHAIN_BOOTS, 0, "Chainmail Boots"); + /** @var int */ + private $defensePoints; + /** @var int */ + private $maxDurability; + + public function __construct(int $defensePoints, int $maxDurability){ + $this->defensePoints = $defensePoints; + $this->maxDurability = $maxDurability; } + /** + * @return int + */ public function getDefensePoints() : int{ - return 1; + return $this->defensePoints; } + /** + * @return int + */ public function getMaxDurability() : int{ - return 196; + return $this->maxDurability; } } diff --git a/src/pocketmine/item/GoldBoots.php b/src/pocketmine/item/Boots.php similarity index 76% rename from src/pocketmine/item/GoldBoots.php rename to src/pocketmine/item/Boots.php index 038639fa3a..13753328dd 100644 --- a/src/pocketmine/item/GoldBoots.php +++ b/src/pocketmine/item/Boots.php @@ -23,17 +23,11 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\inventory\ArmorInventory; -class GoldBoots extends Armor{ - public function __construct(){ - parent::__construct(self::GOLD_BOOTS, 0, "Gold Boots"); - } +class Boots extends Armor{ - public function getDefensePoints() : int{ - return 1; - } - - public function getMaxDurability() : int{ - return 92; + public function getArmorSlot() : int{ + return ArmorInventory::SLOT_FEET; } } diff --git a/src/pocketmine/item/ChainChestplate.php b/src/pocketmine/item/ChainChestplate.php deleted file mode 100644 index 0e1f90a1b3..0000000000 --- a/src/pocketmine/item/ChainChestplate.php +++ /dev/null @@ -1,39 +0,0 @@ - Date: Tue, 12 Mar 2019 19:01:36 +0000 Subject: [PATCH 0625/3224] Armor: Implement right-click to equip, closes #2641 --- src/pocketmine/item/Armor.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/pocketmine/item/Armor.php b/src/pocketmine/item/Armor.php index 8b2d641b9e..c00141e795 100644 --- a/src/pocketmine/item/Armor.php +++ b/src/pocketmine/item/Armor.php @@ -24,11 +24,14 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\block\Block; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\inventory\ArmorInventory; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\ProtectionEnchantment; +use pocketmine\math\Vector3; use pocketmine\nbt\tag\IntTag; +use pocketmine\Player; use pocketmine\utils\Binary; use pocketmine\utils\Color; use function lcg_value; @@ -122,4 +125,13 @@ abstract class Armor extends Durable{ return 0; } + + public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ + $existing = $player->getArmorInventory()->getItem($this->getArmorSlot()); + if(!$existing->isNull()){ + return ItemUseResult::FAIL(); + } + $player->getArmorInventory()->setItem($this->getArmorSlot(), $this->pop()); + return ItemUseResult::SUCCESS(); + } } From 7f4b76aa860d2c149a88527a2972126d3c866773 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 12 Mar 2019 19:38:03 +0000 Subject: [PATCH 0626/3224] Implemented blue ice --- src/pocketmine/block/BlockFactory.php | 1 + src/pocketmine/block/BlueIce.php | 49 +++++++++++++++++++ .../block_factory_consistency_check.json | 2 +- 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/pocketmine/block/BlueIce.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index f23a734438..29e2634c72 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -83,6 +83,7 @@ class BlockFactory{ self::register(new Bed(new BID(Block::BED_BLOCK, 0, ItemIds::BED, \pocketmine\tile\Bed::class), "Bed Block")); self::register(new Bedrock(new BID(Block::BEDROCK), "Bedrock")); self::register(new Beetroot(new BID(Block::BEETROOT_BLOCK), "Beetroot Block")); + self::register(new BlueIce(new BID(Block::BLUE_ICE), "Blue Ice")); self::register(new BoneBlock(new BID(Block::BONE_BLOCK), "Bone Block")); self::register(new Bookshelf(new BID(Block::BOOKSHELF), "Bookshelf")); self::register(new BrewingStand(new BID(Block::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND), "Brewing Stand")); diff --git a/src/pocketmine/block/BlueIce.php b/src/pocketmine/block/BlueIce.php new file mode 100644 index 0000000000..688b70aceb --- /dev/null +++ b/src/pocketmine/block/BlueIce.php @@ -0,0 +1,49 @@ + Date: Wed, 13 Mar 2019 15:10:31 +0000 Subject: [PATCH 0627/3224] Improve enum implementations, move some components to traits The reason this uses a trait is because `self` refers to the including class in a trait, which offers a small amount of automatic type safety. If we had templates or generics, this would be a generic class instead. --- src/pocketmine/block/utils/DyeColor.php | 183 +++++++---------------- src/pocketmine/block/utils/SkullType.php | 88 ++++------- src/pocketmine/block/utils/SlabType.php | 47 +++--- src/pocketmine/block/utils/TreeType.php | 93 ++++-------- src/pocketmine/item/ItemUseResult.php | 54 +++---- src/pocketmine/utils/EnumTrait.php | 172 +++++++++++++++++++++ 6 files changed, 320 insertions(+), 317 deletions(-) create mode 100644 src/pocketmine/utils/EnumTrait.php diff --git a/src/pocketmine/block/utils/DyeColor.php b/src/pocketmine/block/utils/DyeColor.php index 35a5bb9d09..122403e95b 100644 --- a/src/pocketmine/block/utils/DyeColor.php +++ b/src/pocketmine/block/utils/DyeColor.php @@ -24,147 +24,63 @@ declare(strict_types=1); namespace pocketmine\block\utils; use pocketmine\utils\Color; +use pocketmine\utils\EnumTrait; +/** + * This doc-block is generated automatically, do not modify it manually. + * This must be regenerated whenever enum members are added, removed or changed. + * @see EnumTrait::_generateMethodAnnotations() + * + * @method static self WHITE() + * @method static self ORANGE() + * @method static self MAGENTA() + * @method static self LIGHT_BLUE() + * @method static self YELLOW() + * @method static self LIME() + * @method static self PINK() + * @method static self GRAY() + * @method static self LIGHT_GRAY() + * @method static self CYAN() + * @method static self PURPLE() + * @method static self BLUE() + * @method static self BROWN() + * @method static self GREEN() + * @method static self RED() + * @method static self BLACK() + */ final class DyeColor{ - - /** @var DyeColor */ - private static $WHITE; - /** @var DyeColor */ - private static $ORANGE; - /** @var DyeColor */ - private static $MAGENTA; - /** @var DyeColor */ - private static $LIGHT_BLUE; - /** @var DyeColor */ - private static $YELLOW; - /** @var DyeColor */ - private static $LIME; - /** @var DyeColor */ - private static $PINK; - /** @var DyeColor */ - private static $GRAY; - /** @var DyeColor */ - private static $LIGHT_GRAY; - /** @var DyeColor */ - private static $CYAN; - /** @var DyeColor */ - private static $PURPLE; - /** @var DyeColor */ - private static $BLUE; - /** @var DyeColor */ - private static $BROWN; - /** @var DyeColor */ - private static $GREEN; - /** @var DyeColor */ - private static $RED; - /** @var DyeColor */ - private static $BLACK; - - /* auto-generated code */ - - public static function WHITE() : DyeColor{ - return self::$WHITE; - } - - public static function ORANGE() : DyeColor{ - return self::$ORANGE; - } - - public static function MAGENTA() : DyeColor{ - return self::$MAGENTA; - } - - public static function LIGHT_BLUE() : DyeColor{ - return self::$LIGHT_BLUE; - } - - public static function YELLOW() : DyeColor{ - return self::$YELLOW; - } - - public static function LIME() : DyeColor{ - return self::$LIME; - } - - public static function PINK() : DyeColor{ - return self::$PINK; - } - - public static function GRAY() : DyeColor{ - return self::$GRAY; - } - - public static function LIGHT_GRAY() : DyeColor{ - return self::$LIGHT_GRAY; - } - - public static function CYAN() : DyeColor{ - return self::$CYAN; - } - - public static function PURPLE() : DyeColor{ - return self::$PURPLE; - } - - public static function BLUE() : DyeColor{ - return self::$BLUE; - } - - public static function BROWN() : DyeColor{ - return self::$BROWN; - } - - public static function GREEN() : DyeColor{ - return self::$GREEN; - } - - public static function RED() : DyeColor{ - return self::$RED; - } - - public static function BLACK() : DyeColor{ - return self::$BLACK; + use EnumTrait { + register as Enum_register; + __construct as Enum___construct; } /** @var DyeColor[] */ private static $numericIdMap = []; - /** @var DyeColor[] separate mapping that doesn't depend on magic numbers */ - private static $all = []; - /** - * @internal - */ - public static function _init() : void{ - self::register(self::$WHITE = new DyeColor("White", 0, new Color(0xf0, 0xf0, 0xf0))); - self::register(self::$ORANGE = new DyeColor("Orange", 1, new Color(0xf9, 0x80, 0x1d))); - self::register(self::$MAGENTA = new DyeColor("Magenta", 2, new Color(0xc7, 0x4e, 0xbd))); - self::register(self::$LIGHT_BLUE = new DyeColor("Light Blue", 3, new Color(0x3a, 0xb3, 0xda))); - self::register(self::$YELLOW = new DyeColor("Yellow", 4, new Color(0xfe, 0xd8, 0x3d))); - self::register(self::$LIME = new DyeColor("Lime", 5, new Color(0x80, 0xc7, 0x1f))); - self::register(self::$PINK = new DyeColor("Pink", 6, new Color(0xf3, 0x8b, 0xaa))); - self::register(self::$GRAY = new DyeColor("Gray", 7, new Color(0x47, 0x4f, 0x52))); - self::register(self::$LIGHT_GRAY = new DyeColor("Light Gray", 8, new Color(0x9d, 0x9d, 0x97))); - self::register(self::$CYAN = new DyeColor("Cyan", 9, new Color(0x16, 0x9c, 0x9c))); - self::register(self::$PURPLE = new DyeColor("Purple", 10, new Color(0x89, 0x32, 0xb8))); - self::register(self::$BLUE = new DyeColor("Blue", 11, new Color(0x3c, 0x44, 0xaa))); - self::register(self::$BROWN = new DyeColor("Brown", 12, new Color(0x83, 0x54, 0x32))); - self::register(self::$GREEN = new DyeColor("Green", 13, new Color(0x5e, 0x7c, 0x16))); - self::register(self::$RED = new DyeColor("Red", 14, new Color(0xb0, 0x2e, 0x26))); - self::register(self::$BLACK = new DyeColor("Black", 15, new Color(0x1d, 0x1d, 0x21))); + protected static function setup() : array{ + return [ + new DyeColor("white", "White", 0, new Color(0xf0, 0xf0, 0xf0)), + new DyeColor("orange", "Orange", 1, new Color(0xf9, 0x80, 0x1d)), + new DyeColor("magenta", "Magenta", 2, new Color(0xc7, 0x4e, 0xbd)), + new DyeColor("light_blue", "Light Blue", 3, new Color(0x3a, 0xb3, 0xda)), + new DyeColor("yellow", "Yellow", 4, new Color(0xfe, 0xd8, 0x3d)), + new DyeColor("lime", "Lime", 5, new Color(0x80, 0xc7, 0x1f)), + new DyeColor("pink", "Pink", 6, new Color(0xf3, 0x8b, 0xaa)), + new DyeColor("gray", "Gray", 7, new Color(0x47, 0x4f, 0x52)), + new DyeColor("light_gray", "Light Gray", 8, new Color(0x9d, 0x9d, 0x97)), + new DyeColor("cyan", "Cyan", 9, new Color(0x16, 0x9c, 0x9c)), + new DyeColor("purple", "Purple", 10, new Color(0x89, 0x32, 0xb8)), + new DyeColor("blue", "Blue", 11, new Color(0x3c, 0x44, 0xaa)), + new DyeColor("brown", "Brown", 12, new Color(0x83, 0x54, 0x32)), + new DyeColor("green", "Green", 13, new Color(0x5e, 0x7c, 0x16)), + new DyeColor("red", "Red", 14, new Color(0xb0, 0x2e, 0x26)), + new DyeColor("black", "Black", 15, new Color(0x1d, 0x1d, 0x21)), + ]; } - private static function register(DyeColor $color) : void{ + protected static function register(DyeColor $color) : void{ + self::Enum_register($color); self::$numericIdMap[$color->getMagicNumber()] = $color; - self::$all[] = $color; - } - - /** - * Returns a set of all known dye colours. - * - * @return DyeColor[] - */ - public static function getAll() : array{ - return self::$all; } /** @@ -178,6 +94,7 @@ final class DyeColor{ * @throws \InvalidArgumentException */ public static function fromMagicNumber(int $magicNumber, bool $inverted = false) : DyeColor{ + self::checkInit(); $real = $inverted ? ~$magicNumber & 0xf : $magicNumber; if(!isset(self::$numericIdMap[$real])){ throw new \InvalidArgumentException("Unknown dye colour magic number $magicNumber"); @@ -192,7 +109,8 @@ final class DyeColor{ /** @var Color */ private $rgbValue; - private function __construct(string $displayName, int $magicNumber, Color $rgbValue){ + private function __construct(string $enumName, string $displayName, int $magicNumber, Color $rgbValue){ + $this->Enum___construct($enumName); $this->displayName = $displayName; $this->magicNumber = $magicNumber; $this->rgbValue = $rgbValue; @@ -226,4 +144,3 @@ final class DyeColor{ return ~$this->magicNumber & 0xf; } } -DyeColor::_init(); diff --git a/src/pocketmine/block/utils/SkullType.php b/src/pocketmine/block/utils/SkullType.php index ecbdd93028..3055737880 100644 --- a/src/pocketmine/block/utils/SkullType.php +++ b/src/pocketmine/block/utils/SkullType.php @@ -23,71 +23,43 @@ declare(strict_types=1); namespace pocketmine\block\utils; +use pocketmine\utils\EnumTrait; + +/** + * This doc-block is generated automatically, do not modify it manually. + * This must be regenerated whenever enum members are added, removed or changed. + * @see EnumTrait::_generateMethodAnnotations() + * + * @method static self SKELETON() + * @method static self WITHER_SKELETON() + * @method static self ZOMBIE() + * @method static self PLAYER() + * @method static self CREEPER() + * @method static self DRAGON() + */ final class SkullType{ - - /** @var SkullType */ - private static $SKELETON; - /** @var SkullType */ - private static $WITHER_SKELETON; - /** @var SkullType */ - private static $ZOMBIE; - /** @var SkullType */ - private static $HUMAN; - /** @var SkullType */ - private static $CREEPER; - /** @var SkullType */ - private static $DRAGON; - - /* auto-generated code */ - - public static function SKELETON() : SkullType{ - return self::$SKELETON; + use EnumTrait { + register as Enum_register; + __construct as Enum___construct; } - public static function WITHER_SKELETON() : SkullType{ - return self::$WITHER_SKELETON; - } - - public static function ZOMBIE() : SkullType{ - return self::$ZOMBIE; - } - - public static function HUMAN() : SkullType{ - return self::$HUMAN; - } - - public static function CREEPER() : SkullType{ - return self::$CREEPER; - } - - public static function DRAGON() : SkullType{ - return self::$DRAGON; - } - - /** @var SkullType[] */ - private static $all = []; /** @var SkullType[] */ private static $numericIdMap = []; - public static function _init() : void{ - self::register(self::$SKELETON = new SkullType("Skeleton Skull", 0)); - self::register(self::$WITHER_SKELETON = new SkullType("Wither Skeleton Skull", 1)); - self::register(self::$ZOMBIE = new SkullType("Zombie Head", 2)); - self::register(self::$HUMAN = new SkullType("Player Head", 3)); - self::register(self::$CREEPER = new SkullType("Creeper Head", 4)); - self::register(self::$DRAGON = new SkullType("Dragon Head", 5)); + protected static function setup() : array{ + return [ + new SkullType("skeleton", "Skeleton Skull", 0), + new SkullType("wither_skeleton", "Wither Skeleton Skull", 1), + new SkullType("zombie", "Zombie Head", 2), + new SkullType("player", "Player Head", 3), + new SkullType("creeper", "Creeper Head", 4), + new SkullType("dragon", "Dragon Head", 5) + ]; } - private static function register(SkullType $type) : void{ + protected static function register(SkullType $type) : void{ + self::Enum_register($type); self::$numericIdMap[$type->getMagicNumber()] = $type; - self::$all[] = $type; - } - - /** - * @return SkullType[] - */ - public static function getAll() : array{ - return self::$all; } /** @@ -109,7 +81,8 @@ final class SkullType{ /** @var int */ private $magicNumber; - public function __construct(string $displayName, int $magicNumber){ + public function __construct(string $enumName, string $displayName, int $magicNumber){ + $this->Enum___construct($enumName); $this->displayName = $displayName; $this->magicNumber = $magicNumber; } @@ -128,4 +101,3 @@ final class SkullType{ return $this->magicNumber; } } -SkullType::_init(); diff --git a/src/pocketmine/block/utils/SlabType.php b/src/pocketmine/block/utils/SlabType.php index 57fa535ca7..53550520f8 100644 --- a/src/pocketmine/block/utils/SlabType.php +++ b/src/pocketmine/block/utils/SlabType.php @@ -23,36 +23,25 @@ declare(strict_types=1); namespace pocketmine\block\utils; +use pocketmine\utils\EnumTrait; + +/** + * This doc-block is generated automatically, do not modify it manually. + * This must be regenerated whenever enum members are added, removed or changed. + * @see EnumTrait::_generateMethodAnnotations() + * + * @method static self BOTTOM() + * @method static self TOP() + * @method static self DOUBLE() + */ final class SlabType{ + use EnumTrait; - /** - * @var string - */ - private $name; - - public static function BOTTOM() : self{ - /** @var SlabType $ret */ - static $ret = null; - return $ret ?? ($ret = new self("bottom")); - } - - public static function TOP() : self{ - /** @var SlabType $ret */ - static $ret = null; - return $ret ?? ($ret = new self("top")); - } - - public static function DOUBLE() : self{ - /** @var SlabType $ret */ - static $ret = null; - return $ret ?? ($ret = new self("double")); - } - - private function __construct(string $name){ - $this->name = $name; - } - - public function getName() : string{ - return $this->name; + protected static function setup() : array{ + return [ + new self("bottom"), + new self("top"), + new self("double") + ]; } } diff --git a/src/pocketmine/block/utils/TreeType.php b/src/pocketmine/block/utils/TreeType.php index c6bce83f8c..a2c894f5d4 100644 --- a/src/pocketmine/block/utils/TreeType.php +++ b/src/pocketmine/block/utils/TreeType.php @@ -23,74 +23,43 @@ declare(strict_types=1); namespace pocketmine\block\utils; +use pocketmine\utils\EnumTrait; + +/** + * This doc-block is generated automatically, do not modify it manually. + * This must be regenerated whenever enum members are added, removed or changed. + * @see EnumTrait::_generateMethodAnnotations() + * + * @method static self OAK() + * @method static self SPRUCE() + * @method static self BIRCH() + * @method static self JUNGLE() + * @method static self ACACIA() + * @method static self DARK_OAK() + */ final class TreeType{ - - /** @var TreeType */ - private static $OAK; - /** @var TreeType */ - private static $SPRUCE; - /** @var TreeType */ - private static $BIRCH; - /** @var TreeType */ - private static $JUNGLE; - /** @var TreeType */ - private static $ACACIA; - /** @var TreeType */ - private static $DARK_OAK; - - /* auto-generated code */ - - public static function OAK() : TreeType{ - return self::$OAK; - } - - public static function SPRUCE() : TreeType{ - return self::$SPRUCE; - } - - public static function BIRCH() : TreeType{ - return self::$BIRCH; - } - - public static function JUNGLE() : TreeType{ - return self::$JUNGLE; - } - - public static function ACACIA() : TreeType{ - return self::$ACACIA; - } - - public static function DARK_OAK() : TreeType{ - return self::$DARK_OAK; + use EnumTrait { + register as Enum_register; + __construct as Enum___construct; } /** @var TreeType[] */ private static $numericIdMap = []; - /** @var TreeType[] */ - private static $all = []; - /** - * @internal - */ - public static function _init() : void{ - self::register(self::$OAK = new TreeType("Oak", 0)); - self::register(self::$SPRUCE = new TreeType("Spruce", 1)); - self::register(self::$BIRCH = new TreeType("Birch", 2)); - self::register(self::$JUNGLE = new TreeType("Jungle", 3)); - self::register(self::$ACACIA = new TreeType("Acacia", 4)); - self::register(self::$DARK_OAK = new TreeType("Dark Oak", 5)); + protected static function setup() : array{ + return [ + new TreeType("oak", "Oak", 0), + new TreeType("spruce", "Spruce", 1), + new TreeType("birch", "Birch", 2), + new TreeType("jungle", "Jungle", 3), + new TreeType("acacia", "Acacia", 4), + new TreeType("dark_oak","Dark Oak", 5) + ]; } - private static function register(TreeType $type) : void{ + protected static function register(TreeType $type) : void{ + self::Enum_register($type); self::$numericIdMap[$type->getMagicNumber()] = $type; - self::$all[] = $type; - } - - /** - * @return TreeType[] - */ - public static function getAll() : array{ - return self::$all; } /** @@ -101,6 +70,7 @@ final class TreeType{ * @throws \InvalidArgumentException */ public static function fromMagicNumber(int $magicNumber) : TreeType{ + self::checkInit(); if(!isset(self::$numericIdMap[$magicNumber])){ throw new \InvalidArgumentException("Unknown tree type magic number $magicNumber"); } @@ -113,10 +83,12 @@ final class TreeType{ private $magicNumber; /** + * @param string $enumName * @param string $displayName * @param int $magicNumber */ - private function __construct(string $displayName, int $magicNumber){ + private function __construct(string $enumName, string $displayName, int $magicNumber){ + $this->Enum___construct($enumName); $this->displayName = $displayName; $this->magicNumber = $magicNumber; } @@ -135,4 +107,3 @@ final class TreeType{ return $this->magicNumber; } } -TreeType::_init(); diff --git a/src/pocketmine/item/ItemUseResult.php b/src/pocketmine/item/ItemUseResult.php index 90e8b4724f..3341d91619 100644 --- a/src/pocketmine/item/ItemUseResult.php +++ b/src/pocketmine/item/ItemUseResult.php @@ -23,43 +23,25 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\utils\EnumTrait; + +/** + * This doc-block is generated automatically, do not modify it manually. + * This must be regenerated whenever enum members are added, removed or changed. + * @see EnumTrait::_generateMethodAnnotations() + * + * @method static self NONE() + * @method static self FAIL() + * @method static self SUCCESS() + */ final class ItemUseResult{ - /** @var ItemUseResult */ - private static $NONE; - /** @var ItemUseResult */ - private static $FAILED; - /** @var ItemUseResult */ - private static $SUCCEEDED; + use EnumTrait; - /** - * No action attempted to take place. Does nothing. - * - * @return ItemUseResult - */ - public static function NONE() : ItemUseResult{ - return self::$NONE ?? (self::$NONE = new self()); - } - - /** - * An action attempted to take place, but failed due to cancellation. This triggers rollback behaviour for a remote - * player. - * - * @return ItemUseResult - */ - public static function FAIL() : ItemUseResult{ - return self::$FAILED ?? (self::$FAILED = new self()); - } - - /** - * An action took place successfully. Changes inventory contents if appropriate. - * - * @return ItemUseResult - */ - public static function SUCCESS() : ItemUseResult{ - return self::$SUCCEEDED ?? (self::$SUCCEEDED = new self()); - } - - private function __construct(){ - //NOOP + protected static function setup() : array{ + return [ + new self("none"), + new self("fail"), + new self("success") + ]; } } diff --git a/src/pocketmine/utils/EnumTrait.php b/src/pocketmine/utils/EnumTrait.php new file mode 100644 index 0000000000..263996400e --- /dev/null +++ b/src/pocketmine/utils/EnumTrait.php @@ -0,0 +1,172 @@ +getEnumName()); + if(isset(self::$members[$name])){ + throw new \InvalidArgumentException("Enum member name \"$name\" is already reserved"); + } + self::$members[strtoupper($member->getEnumName())] = $member; + } + + /** + * Returns an array of enum members to be registered. + * + * (This ought to be private, but traits suck too much for that.) + * + * @return self[] + */ + abstract protected static function setup() : array; + + /** + * @internal Lazy-inits the enum if necessary. + * + * @throws \InvalidArgumentException + */ + private static function checkInit() : void{ + if(self::$members === null){ + self::$members = []; + foreach(self::setup() as $item){ + self::register($item); + } + } + } + + /** + * @param string $name + * + * @return self + */ + public static function fromString(string $name) : self{ + self::checkInit(); + $name = strtoupper($name); + if(!isset(self::$members[$name])){ + throw new \Error("Undefined enum member: " . self::class . "::" . $name); + } + return self::$members[$name]; + } + + /** + * @param string $name + * @param array $arguments + * + * @return self + */ + public static function __callStatic($name, $arguments){ + if(!empty($arguments)){ + throw new \ArgumentCountError("Expected exactly 0 arguments, " . count($arguments) . " passed"); + } + return self::fromString($name); + } + + /** + * @return self[] + */ + public static function getAll() : array{ + self::checkInit(); + return self::$members; + } + + /** + * Generates code for static methods for all known enum members. + * + * @return string + */ + public static function _generateGetters() : string{ + $lines = []; + + static $fnTmpl = ' +public static function %1$s() : self{ + return self::fromString("%1$s"); +}'; + + foreach(self::getAll() as $name => $member){ + $lines[] = sprintf($fnTmpl, $name); + } + return "/* --- auto-generated code start --- */\n" . implode("\n", $lines) . "\n\n/* --- auto-generated code end --- */\n"; + } + + /** + * Generates a block of @ method annotations for accessors for this enum's known members. + * + * @return string + */ + public static function _generateMethodAnnotations() : string{ + $traitName = (new \ReflectionClass(__TRAIT__))->getShortName(); + $fnName = (new \ReflectionMethod(__METHOD__))->getShortName(); + $lines = ["/**"]; + $lines[] = " * This doc-block is generated automatically, do not modify it manually."; + $lines[] = " * This must be regenerated whenever enum members are added, removed or changed."; + $lines[] = " * @see $traitName::$fnName()"; + $lines[] = " *"; + static $lineTmpl = " * @method static self %s()"; + + foreach(self::getAll() as $name => $member){ + $lines[] = sprintf($lineTmpl, $name); + } + $lines[] = " */\n"; + return implode("\n", $lines); + } + + /** @var string */ + private $enumName; + + /** + * @param string $enumName + * @throws \InvalidArgumentException + */ + private function __construct(string $enumName){ + static $pattern = '/^\D[A-Za-z\d_]+$/u'; + if(preg_match($pattern, $enumName, $matches) === 0){ + throw new \InvalidArgumentException("Invalid enum member name \"$enumName\", should only contain letters, numbers and underscores, and must not start with a number"); + } + $this->enumName = $enumName; + } + + /** + * @return string + */ + public function getEnumName() : string{ + return $this->enumName; + } +} From ad19696364e033c44ba9948ef6d5615b2a02056a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 Mar 2019 15:26:21 +0000 Subject: [PATCH 0628/3224] Make Effect and Enchantment functions less verbose --- .../command/defaults/EffectCommand.php | 4 +- .../command/defaults/EnchantCommand.php | 4 +- src/pocketmine/entity/Living.php | 2 +- src/pocketmine/entity/effect/Effect.php | 112 +++++++++--------- src/pocketmine/item/Item.php | 4 +- .../item/enchantment/Enchantment.php | 84 ++++++------- 6 files changed, 105 insertions(+), 105 deletions(-) diff --git a/src/pocketmine/command/defaults/EffectCommand.php b/src/pocketmine/command/defaults/EffectCommand.php index 58a7e8fa37..373434c664 100644 --- a/src/pocketmine/command/defaults/EffectCommand.php +++ b/src/pocketmine/command/defaults/EffectCommand.php @@ -69,10 +69,10 @@ class EffectCommand extends VanillaCommand{ return true; } - $effect = Effect::getEffectByName($args[1]); + $effect = Effect::fromString($args[1]); if($effect === null){ - $effect = Effect::getEffect((int) $args[1]); + $effect = Effect::get((int) $args[1]); } if($effect === null){ diff --git a/src/pocketmine/command/defaults/EnchantCommand.php b/src/pocketmine/command/defaults/EnchantCommand.php index c40886297a..2f770699b3 100644 --- a/src/pocketmine/command/defaults/EnchantCommand.php +++ b/src/pocketmine/command/defaults/EnchantCommand.php @@ -67,9 +67,9 @@ class EnchantCommand extends VanillaCommand{ } if(is_numeric($args[1])){ - $enchantment = Enchantment::getEnchantment((int) $args[1]); + $enchantment = Enchantment::get((int) $args[1]); }else{ - $enchantment = Enchantment::getEnchantmentByName($args[1]); + $enchantment = Enchantment::fromString($args[1]); } if(!($enchantment instanceof Enchantment)){ diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index cfb23b3373..7b18eb7ae1 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -121,7 +121,7 @@ abstract class Living extends Entity implements Damageable{ $activeEffectsTag = $nbt->getListTag("ActiveEffects"); if($activeEffectsTag !== null){ foreach($activeEffectsTag as $e){ - $effect = Effect::getEffect($e->getByte("Id")); + $effect = Effect::get($e->getByte("Id")); if($effect === null){ continue; } diff --git a/src/pocketmine/entity/effect/Effect.php b/src/pocketmine/entity/effect/Effect.php index 8a1044fe89..12f09d0a5f 100644 --- a/src/pocketmine/entity/effect/Effect.php +++ b/src/pocketmine/entity/effect/Effect.php @@ -64,144 +64,144 @@ class Effect{ protected static $effects = []; public static function init() : void{ - self::registerEffect(new SpeedEffect(Effect::SPEED, "%potion.moveSpeed", new Color(0x7c, 0xaf, 0xc6))); - self::registerEffect(new SlownessEffect(Effect::SLOWNESS, "%potion.moveSlowdown", new Color(0x5a, 0x6c, 0x81), true)); - self::registerEffect(new Effect(Effect::HASTE, "%potion.digSpeed", new Color(0xd9, 0xc0, 0x43))); - self::registerEffect(new Effect(Effect::MINING_FATIGUE, "%potion.digSlowDown", new Color(0x4a, 0x42, 0x17), true)); - self::registerEffect(new Effect(Effect::STRENGTH, "%potion.damageBoost", new Color(0x93, 0x24, 0x23))); - self::registerEffect(new InstantHealthEffect(Effect::INSTANT_HEALTH, "%potion.heal", new Color(0xf8, 0x24, 0x23), false, false)); - self::registerEffect(new InstantDamageEffect(Effect::INSTANT_DAMAGE, "%potion.harm", new Color(0x43, 0x0a, 0x09), true, false)); - self::registerEffect(new Effect(Effect::JUMP_BOOST, "%potion.jump", new Color(0x22, 0xff, 0x4c))); - self::registerEffect(new Effect(Effect::NAUSEA, "%potion.confusion", new Color(0x55, 0x1d, 0x4a), true)); - self::registerEffect(new RegenerationEffect(Effect::REGENERATION, "%potion.regeneration", new Color(0xcd, 0x5c, 0xab))); - self::registerEffect(new Effect(Effect::RESISTANCE, "%potion.resistance", new Color(0x99, 0x45, 0x3a))); - self::registerEffect(new Effect(Effect::FIRE_RESISTANCE, "%potion.fireResistance", new Color(0xe4, 0x9a, 0x3a))); - self::registerEffect(new Effect(Effect::WATER_BREATHING, "%potion.waterBreathing", new Color(0x2e, 0x52, 0x99))); - self::registerEffect(new InvisibilityEffect(Effect::INVISIBILITY, "%potion.invisibility", new Color(0x7f, 0x83, 0x92))); - self::registerEffect(new Effect(Effect::BLINDNESS, "%potion.blindness", new Color(0x1f, 0x1f, 0x23), true)); - self::registerEffect(new Effect(Effect::NIGHT_VISION, "%potion.nightVision", new Color(0x1f, 0x1f, 0xa1))); - self::registerEffect(new HungerEffect(Effect::HUNGER, "%potion.hunger", new Color(0x58, 0x76, 0x53), true)); - self::registerEffect(new Effect(Effect::WEAKNESS, "%potion.weakness", new Color(0x48, 0x4d, 0x48), true)); - self::registerEffect(new PoisonEffect(Effect::POISON, "%potion.poison", new Color(0x4e, 0x93, 0x31), true)); - self::registerEffect(new WitherEffect(Effect::WITHER, "%potion.wither", new Color(0x35, 0x2a, 0x27), true)); - self::registerEffect(new HealthBoostEffect(Effect::HEALTH_BOOST, "%potion.healthBoost", new Color(0xf8, 0x7d, 0x23))); - self::registerEffect(new AbsorptionEffect(Effect::ABSORPTION, "%potion.absorption", new Color(0x25, 0x52, 0xa5))); - self::registerEffect(new SaturationEffect(Effect::SATURATION, "%potion.saturation", new Color(0xf8, 0x24, 0x23), false)); - self::registerEffect(new LevitationEffect(Effect::LEVITATION, "%potion.levitation", new Color(0xce, 0xff, 0xff))); - self::registerEffect(new PoisonEffect(Effect::FATAL_POISON, "%potion.poison", new Color(0x4e, 0x93, 0x31), true, true, true)); - self::registerEffect(new Effect(Effect::CONDUIT_POWER, "%potion.conduitPower", new Color(0x1d, 0xc2, 0xd1))); + self::register(new SpeedEffect(Effect::SPEED, "%potion.moveSpeed", new Color(0x7c, 0xaf, 0xc6))); + self::register(new SlownessEffect(Effect::SLOWNESS, "%potion.moveSlowdown", new Color(0x5a, 0x6c, 0x81), true)); + self::register(new Effect(Effect::HASTE, "%potion.digSpeed", new Color(0xd9, 0xc0, 0x43))); + self::register(new Effect(Effect::MINING_FATIGUE, "%potion.digSlowDown", new Color(0x4a, 0x42, 0x17), true)); + self::register(new Effect(Effect::STRENGTH, "%potion.damageBoost", new Color(0x93, 0x24, 0x23))); + self::register(new InstantHealthEffect(Effect::INSTANT_HEALTH, "%potion.heal", new Color(0xf8, 0x24, 0x23), false, false)); + self::register(new InstantDamageEffect(Effect::INSTANT_DAMAGE, "%potion.harm", new Color(0x43, 0x0a, 0x09), true, false)); + self::register(new Effect(Effect::JUMP_BOOST, "%potion.jump", new Color(0x22, 0xff, 0x4c))); + self::register(new Effect(Effect::NAUSEA, "%potion.confusion", new Color(0x55, 0x1d, 0x4a), true)); + self::register(new RegenerationEffect(Effect::REGENERATION, "%potion.regeneration", new Color(0xcd, 0x5c, 0xab))); + self::register(new Effect(Effect::RESISTANCE, "%potion.resistance", new Color(0x99, 0x45, 0x3a))); + self::register(new Effect(Effect::FIRE_RESISTANCE, "%potion.fireResistance", new Color(0xe4, 0x9a, 0x3a))); + self::register(new Effect(Effect::WATER_BREATHING, "%potion.waterBreathing", new Color(0x2e, 0x52, 0x99))); + self::register(new InvisibilityEffect(Effect::INVISIBILITY, "%potion.invisibility", new Color(0x7f, 0x83, 0x92))); + self::register(new Effect(Effect::BLINDNESS, "%potion.blindness", new Color(0x1f, 0x1f, 0x23), true)); + self::register(new Effect(Effect::NIGHT_VISION, "%potion.nightVision", new Color(0x1f, 0x1f, 0xa1))); + self::register(new HungerEffect(Effect::HUNGER, "%potion.hunger", new Color(0x58, 0x76, 0x53), true)); + self::register(new Effect(Effect::WEAKNESS, "%potion.weakness", new Color(0x48, 0x4d, 0x48), true)); + self::register(new PoisonEffect(Effect::POISON, "%potion.poison", new Color(0x4e, 0x93, 0x31), true)); + self::register(new WitherEffect(Effect::WITHER, "%potion.wither", new Color(0x35, 0x2a, 0x27), true)); + self::register(new HealthBoostEffect(Effect::HEALTH_BOOST, "%potion.healthBoost", new Color(0xf8, 0x7d, 0x23))); + self::register(new AbsorptionEffect(Effect::ABSORPTION, "%potion.absorption", new Color(0x25, 0x52, 0xa5))); + self::register(new SaturationEffect(Effect::SATURATION, "%potion.saturation", new Color(0xf8, 0x24, 0x23), false)); + self::register(new LevitationEffect(Effect::LEVITATION, "%potion.levitation", new Color(0xce, 0xff, 0xff))); + self::register(new PoisonEffect(Effect::FATAL_POISON, "%potion.poison", new Color(0x4e, 0x93, 0x31), true, true, true)); + self::register(new Effect(Effect::CONDUIT_POWER, "%potion.conduitPower", new Color(0x1d, 0xc2, 0xd1))); } /* auto-generated code */ public static function ABSORPTION() : Effect{ - return self::getEffect(Effect::ABSORPTION); + return self::get(Effect::ABSORPTION); } public static function BLINDNESS() : Effect{ - return self::getEffect(Effect::BLINDNESS); + return self::get(Effect::BLINDNESS); } public static function CONDUIT_POWER() : Effect{ - return self::getEffect(Effect::CONDUIT_POWER); + return self::get(Effect::CONDUIT_POWER); } public static function FATAL_POISON() : Effect{ - return self::getEffect(Effect::FATAL_POISON); + return self::get(Effect::FATAL_POISON); } public static function FIRE_RESISTANCE() : Effect{ - return self::getEffect(Effect::FIRE_RESISTANCE); + return self::get(Effect::FIRE_RESISTANCE); } public static function HASTE() : Effect{ - return self::getEffect(Effect::HASTE); + return self::get(Effect::HASTE); } public static function HEALTH_BOOST() : Effect{ - return self::getEffect(Effect::HEALTH_BOOST); + return self::get(Effect::HEALTH_BOOST); } public static function HUNGER() : Effect{ - return self::getEffect(Effect::HUNGER); + return self::get(Effect::HUNGER); } public static function INSTANT_DAMAGE() : Effect{ - return self::getEffect(Effect::INSTANT_DAMAGE); + return self::get(Effect::INSTANT_DAMAGE); } public static function INSTANT_HEALTH() : Effect{ - return self::getEffect(Effect::INSTANT_HEALTH); + return self::get(Effect::INSTANT_HEALTH); } public static function INVISIBILITY() : Effect{ - return self::getEffect(Effect::INVISIBILITY); + return self::get(Effect::INVISIBILITY); } public static function JUMP_BOOST() : Effect{ - return self::getEffect(Effect::JUMP_BOOST); + return self::get(Effect::JUMP_BOOST); } public static function LEVITATION() : Effect{ - return self::getEffect(Effect::LEVITATION); + return self::get(Effect::LEVITATION); } public static function MINING_FATIGUE() : Effect{ - return self::getEffect(Effect::MINING_FATIGUE); + return self::get(Effect::MINING_FATIGUE); } public static function NAUSEA() : Effect{ - return self::getEffect(Effect::NAUSEA); + return self::get(Effect::NAUSEA); } public static function NIGHT_VISION() : Effect{ - return self::getEffect(Effect::NIGHT_VISION); + return self::get(Effect::NIGHT_VISION); } public static function POISON() : Effect{ - return self::getEffect(Effect::POISON); + return self::get(Effect::POISON); } public static function REGENERATION() : Effect{ - return self::getEffect(Effect::REGENERATION); + return self::get(Effect::REGENERATION); } public static function RESISTANCE() : Effect{ - return self::getEffect(Effect::RESISTANCE); + return self::get(Effect::RESISTANCE); } public static function SATURATION() : Effect{ - return self::getEffect(Effect::SATURATION); + return self::get(Effect::SATURATION); } public static function SLOWNESS() : Effect{ - return self::getEffect(Effect::SLOWNESS); + return self::get(Effect::SLOWNESS); } public static function SPEED() : Effect{ - return self::getEffect(Effect::SPEED); + return self::get(Effect::SPEED); } public static function STRENGTH() : Effect{ - return self::getEffect(Effect::STRENGTH); + return self::get(Effect::STRENGTH); } public static function WATER_BREATHING() : Effect{ - return self::getEffect(Effect::WATER_BREATHING); + return self::get(Effect::WATER_BREATHING); } public static function WEAKNESS() : Effect{ - return self::getEffect(Effect::WEAKNESS); + return self::get(Effect::WEAKNESS); } public static function WITHER() : Effect{ - return self::getEffect(Effect::WITHER); + return self::get(Effect::WITHER); } /** * @param Effect $effect */ - public static function registerEffect(Effect $effect) : void{ + public static function register(Effect $effect) : void{ self::$effects[$effect->getId()] = $effect; } @@ -210,7 +210,7 @@ class Effect{ * * @return Effect|null */ - public static function getEffect(int $id) : ?Effect{ + public static function get(int $id) : ?Effect{ return self::$effects[$id] ?? null; } @@ -219,10 +219,10 @@ class Effect{ * * @return Effect|null */ - public static function getEffectByName(string $name) : ?Effect{ + public static function fromString(string $name) : ?Effect{ $const = self::class . "::" . strtoupper($name); if(defined($const)){ - return self::getEffect(constant($const)); + return self::get(constant($const)); } return null; } diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index bb2f0b11a1..eeb7a92a38 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -260,7 +260,7 @@ class Item implements ItemIds, \JsonSerializable{ /** @var CompoundTag $entry */ foreach($ench as $entry){ if($entry->getShort("id") === $id){ - $e = Enchantment::getEnchantment($entry->getShort("id")); + $e = Enchantment::get($entry->getShort("id")); if($e !== null){ return new EnchantmentInstance($e, $entry->getShort("lvl")); } @@ -353,7 +353,7 @@ class Item implements ItemIds, \JsonSerializable{ if($ench instanceof ListTag){ /** @var CompoundTag $entry */ foreach($ench as $entry){ - $e = Enchantment::getEnchantment($entry->getShort("id")); + $e = Enchantment::get($entry->getShort("id")); if($e !== null){ $enchantments[] = new EnchantmentInstance($e, $entry->getShort("lvl")); } diff --git a/src/pocketmine/item/enchantment/Enchantment.php b/src/pocketmine/item/enchantment/Enchantment.php index 9cbb07b0d9..5a8b643db5 100644 --- a/src/pocketmine/item/enchantment/Enchantment.php +++ b/src/pocketmine/item/enchantment/Enchantment.php @@ -100,120 +100,120 @@ class Enchantment{ public static function init() : void{ self::$enchantments = new \SplFixedArray(256); - self::registerEnchantment(new ProtectionEnchantment(self::PROTECTION, "%enchantment.protect.all", self::RARITY_COMMON, self::SLOT_ARMOR, self::SLOT_NONE, 4, 0.75, null)); - self::registerEnchantment(new ProtectionEnchantment(self::FIRE_PROTECTION, "%enchantment.protect.fire", self::RARITY_UNCOMMON, self::SLOT_ARMOR, self::SLOT_NONE, 4, 1.25, [ + self::register(new ProtectionEnchantment(self::PROTECTION, "%enchantment.protect.all", self::RARITY_COMMON, self::SLOT_ARMOR, self::SLOT_NONE, 4, 0.75, null)); + self::register(new ProtectionEnchantment(self::FIRE_PROTECTION, "%enchantment.protect.fire", self::RARITY_UNCOMMON, self::SLOT_ARMOR, self::SLOT_NONE, 4, 1.25, [ EntityDamageEvent::CAUSE_FIRE, EntityDamageEvent::CAUSE_FIRE_TICK, EntityDamageEvent::CAUSE_LAVA //TODO: check fireballs ])); - self::registerEnchantment(new ProtectionEnchantment(self::FEATHER_FALLING, "%enchantment.protect.fall", self::RARITY_UNCOMMON, self::SLOT_FEET, self::SLOT_NONE, 4, 2.5, [ + self::register(new ProtectionEnchantment(self::FEATHER_FALLING, "%enchantment.protect.fall", self::RARITY_UNCOMMON, self::SLOT_FEET, self::SLOT_NONE, 4, 2.5, [ EntityDamageEvent::CAUSE_FALL ])); - self::registerEnchantment(new ProtectionEnchantment(self::BLAST_PROTECTION, "%enchantment.protect.explosion", self::RARITY_RARE, self::SLOT_ARMOR, self::SLOT_NONE, 4, 1.5, [ + self::register(new ProtectionEnchantment(self::BLAST_PROTECTION, "%enchantment.protect.explosion", self::RARITY_RARE, self::SLOT_ARMOR, self::SLOT_NONE, 4, 1.5, [ EntityDamageEvent::CAUSE_BLOCK_EXPLOSION, EntityDamageEvent::CAUSE_ENTITY_EXPLOSION ])); - self::registerEnchantment(new ProtectionEnchantment(self::PROJECTILE_PROTECTION, "%enchantment.protect.projectile", self::RARITY_UNCOMMON, self::SLOT_ARMOR, self::SLOT_NONE, 4, 1.5, [ + self::register(new ProtectionEnchantment(self::PROJECTILE_PROTECTION, "%enchantment.protect.projectile", self::RARITY_UNCOMMON, self::SLOT_ARMOR, self::SLOT_NONE, 4, 1.5, [ EntityDamageEvent::CAUSE_PROJECTILE ])); - self::registerEnchantment(new Enchantment(self::THORNS, "%enchantment.thorns", self::RARITY_MYTHIC, self::SLOT_TORSO, self::SLOT_HEAD | self::SLOT_LEGS | self::SLOT_FEET, 3)); - self::registerEnchantment(new Enchantment(self::RESPIRATION, "%enchantment.oxygen", self::RARITY_RARE, self::SLOT_HEAD, self::SLOT_NONE, 3)); + self::register(new Enchantment(self::THORNS, "%enchantment.thorns", self::RARITY_MYTHIC, self::SLOT_TORSO, self::SLOT_HEAD | self::SLOT_LEGS | self::SLOT_FEET, 3)); + self::register(new Enchantment(self::RESPIRATION, "%enchantment.oxygen", self::RARITY_RARE, self::SLOT_HEAD, self::SLOT_NONE, 3)); - self::registerEnchantment(new SharpnessEnchantment(self::SHARPNESS, "%enchantment.damage.all", self::RARITY_COMMON, self::SLOT_SWORD, self::SLOT_AXE, 5)); + self::register(new SharpnessEnchantment(self::SHARPNESS, "%enchantment.damage.all", self::RARITY_COMMON, self::SLOT_SWORD, self::SLOT_AXE, 5)); //TODO: smite, bane of arthropods (these don't make sense now because their applicable mobs don't exist yet) - self::registerEnchantment(new KnockbackEnchantment(self::KNOCKBACK, "%enchantment.knockback", self::RARITY_UNCOMMON, self::SLOT_SWORD, self::SLOT_NONE, 2)); - self::registerEnchantment(new FireAspectEnchantment(self::FIRE_ASPECT, "%enchantment.fire", self::RARITY_RARE, self::SLOT_SWORD, self::SLOT_NONE, 2)); + self::register(new KnockbackEnchantment(self::KNOCKBACK, "%enchantment.knockback", self::RARITY_UNCOMMON, self::SLOT_SWORD, self::SLOT_NONE, 2)); + self::register(new FireAspectEnchantment(self::FIRE_ASPECT, "%enchantment.fire", self::RARITY_RARE, self::SLOT_SWORD, self::SLOT_NONE, 2)); - self::registerEnchantment(new Enchantment(self::EFFICIENCY, "%enchantment.digging", self::RARITY_COMMON, self::SLOT_DIG, self::SLOT_SHEARS, 5)); - self::registerEnchantment(new Enchantment(self::SILK_TOUCH, "%enchantment.untouching", self::RARITY_MYTHIC, self::SLOT_DIG, self::SLOT_SHEARS, 1)); - self::registerEnchantment(new Enchantment(self::UNBREAKING, "%enchantment.durability", self::RARITY_UNCOMMON, self::SLOT_DIG | self::SLOT_ARMOR | self::SLOT_FISHING_ROD | self::SLOT_BOW, self::SLOT_TOOL | self::SLOT_CARROT_STICK | self::SLOT_ELYTRA, 3)); + self::register(new Enchantment(self::EFFICIENCY, "%enchantment.digging", self::RARITY_COMMON, self::SLOT_DIG, self::SLOT_SHEARS, 5)); + self::register(new Enchantment(self::SILK_TOUCH, "%enchantment.untouching", self::RARITY_MYTHIC, self::SLOT_DIG, self::SLOT_SHEARS, 1)); + self::register(new Enchantment(self::UNBREAKING, "%enchantment.durability", self::RARITY_UNCOMMON, self::SLOT_DIG | self::SLOT_ARMOR | self::SLOT_FISHING_ROD | self::SLOT_BOW, self::SLOT_TOOL | self::SLOT_CARROT_STICK | self::SLOT_ELYTRA, 3)); - self::registerEnchantment(new Enchantment(self::POWER, "%enchantment.arrowDamage", self::RARITY_COMMON, self::SLOT_BOW, self::SLOT_NONE, 5)); - self::registerEnchantment(new Enchantment(self::PUNCH, "%enchantment.arrowKnockback", self::RARITY_RARE, self::SLOT_BOW, self::SLOT_NONE, 2)); - self::registerEnchantment(new Enchantment(self::FLAME, "%enchantment.arrowFire", self::RARITY_RARE, self::SLOT_BOW, self::SLOT_NONE, 1)); - self::registerEnchantment(new Enchantment(self::INFINITY, "%enchantment.arrowInfinite", self::RARITY_MYTHIC, self::SLOT_BOW, self::SLOT_NONE, 1)); + self::register(new Enchantment(self::POWER, "%enchantment.arrowDamage", self::RARITY_COMMON, self::SLOT_BOW, self::SLOT_NONE, 5)); + self::register(new Enchantment(self::PUNCH, "%enchantment.arrowKnockback", self::RARITY_RARE, self::SLOT_BOW, self::SLOT_NONE, 2)); + self::register(new Enchantment(self::FLAME, "%enchantment.arrowFire", self::RARITY_RARE, self::SLOT_BOW, self::SLOT_NONE, 1)); + self::register(new Enchantment(self::INFINITY, "%enchantment.arrowInfinite", self::RARITY_MYTHIC, self::SLOT_BOW, self::SLOT_NONE, 1)); - self::registerEnchantment(new Enchantment(self::MENDING, "%enchantment.mending", self::RARITY_RARE, self::SLOT_NONE, self::SLOT_ALL, 1)); + self::register(new Enchantment(self::MENDING, "%enchantment.mending", self::RARITY_RARE, self::SLOT_NONE, self::SLOT_ALL, 1)); - self::registerEnchantment(new Enchantment(self::VANISHING, "%enchantment.curse.vanishing", self::RARITY_MYTHIC, self::SLOT_NONE, self::SLOT_ALL, 1)); + self::register(new Enchantment(self::VANISHING, "%enchantment.curse.vanishing", self::RARITY_MYTHIC, self::SLOT_NONE, self::SLOT_ALL, 1)); } public static function BLAST_PROTECTION() : Enchantment{ - return self::getEnchantment(self::BLAST_PROTECTION); + return self::get(self::BLAST_PROTECTION); } public static function EFFICIENCY() : Enchantment{ - return self::getEnchantment(self::EFFICIENCY); + return self::get(self::EFFICIENCY); } public static function FEATHER_FALLING() : Enchantment{ - return self::getEnchantment(self::FEATHER_FALLING); + return self::get(self::FEATHER_FALLING); } public static function FIRE_ASPECT() : Enchantment{ - return self::getEnchantment(self::FIRE_ASPECT); + return self::get(self::FIRE_ASPECT); } public static function FIRE_PROTECTION() : Enchantment{ - return self::getEnchantment(self::FIRE_PROTECTION); + return self::get(self::FIRE_PROTECTION); } public static function FLAME() : Enchantment{ - return self::getEnchantment(self::FLAME); + return self::get(self::FLAME); } public static function INFINITY() : Enchantment{ - return self::getEnchantment(self::INFINITY); + return self::get(self::INFINITY); } public static function KNOCKBACK() : Enchantment{ - return self::getEnchantment(self::KNOCKBACK); + return self::get(self::KNOCKBACK); } public static function MENDING() : Enchantment{ - return self::getEnchantment(self::MENDING); + return self::get(self::MENDING); } public static function POWER() : Enchantment{ - return self::getEnchantment(self::POWER); + return self::get(self::POWER); } public static function PROJECTILE_PROTECTION() : Enchantment{ - return self::getEnchantment(self::PROJECTILE_PROTECTION); + return self::get(self::PROJECTILE_PROTECTION); } public static function PROTECTION() : Enchantment{ - return self::getEnchantment(self::PROTECTION); + return self::get(self::PROTECTION); } public static function PUNCH() : Enchantment{ - return self::getEnchantment(self::PUNCH); + return self::get(self::PUNCH); } public static function RESPIRATION() : Enchantment{ - return self::getEnchantment(self::RESPIRATION); + return self::get(self::RESPIRATION); } public static function SHARPNESS() : Enchantment{ - return self::getEnchantment(self::SHARPNESS); + return self::get(self::SHARPNESS); } public static function SILK_TOUCH() : Enchantment{ - return self::getEnchantment(self::SILK_TOUCH); + return self::get(self::SILK_TOUCH); } public static function THORNS() : Enchantment{ - return self::getEnchantment(self::THORNS); + return self::get(self::THORNS); } public static function UNBREAKING() : Enchantment{ - return self::getEnchantment(self::UNBREAKING); + return self::get(self::UNBREAKING); } public static function VANISHING() : Enchantment{ - return self::getEnchantment(self::VANISHING); + return self::get(self::VANISHING); } /** @@ -221,7 +221,7 @@ class Enchantment{ * * @param Enchantment $enchantment */ - public static function registerEnchantment(Enchantment $enchantment) : void{ + public static function register(Enchantment $enchantment) : void{ self::$enchantments[$enchantment->getId()] = clone $enchantment; } @@ -230,7 +230,7 @@ class Enchantment{ * * @return Enchantment|null */ - public static function getEnchantment(int $id) : ?Enchantment{ + public static function get(int $id) : ?Enchantment{ return self::$enchantments[$id] ?? null; } @@ -239,10 +239,10 @@ class Enchantment{ * * @return Enchantment|null */ - public static function getEnchantmentByName(string $name) : ?Enchantment{ + public static function fromString(string $name) : ?Enchantment{ $const = Enchantment::class . "::" . strtoupper($name); if(defined($const)){ - return self::getEnchantment(constant($const)); + return self::get(constant($const)); } return null; } From 08c399529d8687175aa16526b863cf55acce9437 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 Mar 2019 17:32:34 +0000 Subject: [PATCH 0629/3224] RegionLevelProvider: Unload regions when finished scanning them, fixes running out of file descriptors during conversion --- .../level/format/io/region/RegionLevelProvider.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/pocketmine/level/format/io/region/RegionLevelProvider.php b/src/pocketmine/level/format/io/region/RegionLevelProvider.php index 56f8f1ef54..cee91d0035 100644 --- a/src/pocketmine/level/format/io/region/RegionLevelProvider.php +++ b/src/pocketmine/level/format/io/region/RegionLevelProvider.php @@ -162,6 +162,13 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ } } + protected function unloadRegion(int $regionX, int $regionZ) : void{ + if(isset($this->regions[$hash = Level::chunkHash($regionX, $regionZ)])){ + $this->regions[$hash]->close(); + unset($this->regions[$hash]); + } + } + public function close() : void{ foreach($this->regions as $index => $region){ $region->close(); @@ -246,6 +253,8 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ } } } + + $this->unloadRegion($rX, $rZ); } } @@ -254,6 +263,7 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ foreach($this->createRegionIterator() as $region){ $this->loadRegion((int) $region[1], (int) $region[2]); $count += $this->getRegion((int) $region[1], (int) $region[2])->calculateChunkCount(); + $this->unloadRegion((int) $region[1], (int) $region[2]); } return $count; } From 34758e3bc6b9b64a76be64d7cbd98787f2a329ef Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 Mar 2019 17:35:09 +0000 Subject: [PATCH 0630/3224] RegionLevelProvider: clean up coordinate extraction, fixed a stupid bug --- .../format/io/region/RegionLevelProvider.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/level/format/io/region/RegionLevelProvider.php b/src/pocketmine/level/format/io/region/RegionLevelProvider.php index cee91d0035..da83762260 100644 --- a/src/pocketmine/level/format/io/region/RegionLevelProvider.php +++ b/src/pocketmine/level/format/io/region/RegionLevelProvider.php @@ -233,8 +233,10 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ $iterator = $this->createRegionIterator(); foreach($iterator as $region){ - $rX = ((int) $region[1]) << 5; - $rZ = ((int) $region[2]) << 5; + $regionX = ((int) $region[1]); + $regionZ = ((int) $region[2]); + $rX = $regionX << 5; + $rZ = $regionZ << 5; for($chunkX = $rX; $chunkX < $rX + 32; ++$chunkX){ for($chunkZ = $rZ; $chunkZ < $rZ + 32; ++$chunkZ){ @@ -254,16 +256,18 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ } } - $this->unloadRegion($rX, $rZ); + $this->unloadRegion($regionX, $regionZ); } } public function calculateChunkCount() : int{ $count = 0; foreach($this->createRegionIterator() as $region){ - $this->loadRegion((int) $region[1], (int) $region[2]); - $count += $this->getRegion((int) $region[1], (int) $region[2])->calculateChunkCount(); - $this->unloadRegion((int) $region[1], (int) $region[2]); + $regionX = ((int) $region[1]); + $regionZ = ((int) $region[2]); + $this->loadRegion($regionX, $regionZ); + $count += $this->getRegion($regionX, $regionZ)->calculateChunkCount(); + $this->unloadRegion($regionX, $regionZ); } return $count; } From fa7a4dc22ef2227a9caaf46be0dc984ebccbd4e8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 Mar 2019 21:43:07 +0000 Subject: [PATCH 0631/3224] Fixed warning of bad default format on new installs --- resources/pocketmine.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/pocketmine.yml b/resources/pocketmine.yml index 368388004d..c905880b7f 100644 --- a/resources/pocketmine.yml +++ b/resources/pocketmine.yml @@ -111,7 +111,7 @@ player: level-settings: #The default format that levels will use when created - default-format: pmanvil + default-format: leveldb chunk-sending: #To change server normal render distance, change view-distance in server.properties. From 26a5d97499d441c9ad8d4deb4c2eaa3494ad098a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 14 Mar 2019 14:32:27 +0000 Subject: [PATCH 0632/3224] Some cleanup to player net session handling for connect/disconnect --- src/pocketmine/Player.php | 18 +-- src/pocketmine/Server.php | 34 +---- src/pocketmine/level/LevelManager.php | 2 - src/pocketmine/network/Network.php | 29 ++-- .../network/NetworkSessionManager.php | 129 ++++++++++++++++++ .../network/mcpe/NetworkSession.php | 51 +++++-- .../network/mcpe/RakLibInterface.php | 2 +- .../mcpe/handler/LoginSessionHandler.php | 2 + 8 files changed, 187 insertions(+), 80 deletions(-) create mode 100644 src/pocketmine/network/NetworkSessionManager.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 96333618a2..7641d9802f 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -50,7 +50,6 @@ use pocketmine\event\player\PlayerChangeSkinEvent; use pocketmine\event\player\PlayerChatEvent; use pocketmine\event\player\PlayerCommandPreprocessEvent; use pocketmine\event\player\PlayerDeathEvent; -use pocketmine\event\player\PlayerDuplicateLoginEvent; use pocketmine\event\player\PlayerEditBookEvent; use pocketmine\event\player\PlayerExhaustEvent; use pocketmine\event\player\PlayerGameModeChangeEvent; @@ -1795,20 +1794,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->server->getLogger()->debug($this->getName() . " is logged into Xbox Live"); } - foreach($this->server->getLoggedInPlayers() as $p){ - if($p !== $this and ($p->iusername === $this->iusername or $this->getUniqueId()->equals($p->getUniqueId()))){ - $ev = new PlayerDuplicateLoginEvent($this->networkSession, $p->networkSession); - $ev->call(); - if($ev->isCancelled()){ - $this->networkSession->disconnect($ev->getDisconnectMessage()); - return false; - } - - $p->networkSession->disconnect($ev->getDisconnectMessage()); - } - } - - return true; + return $this->server->getNetwork()->getSessionManager()->kickDuplicates($this->networkSession); } public function onLoginSuccess() : void{ @@ -2843,7 +2829,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->loadQueue = []; if($this->loggedIn){ - $this->server->onPlayerLogout($this); foreach($this->server->getOnlinePlayers() as $player){ if(!$player->canSee($this)){ $player->showPlayer($this); @@ -2869,7 +2854,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->loggedIn = false; $this->server->removeOnlinePlayer($this); } - $this->server->removePlayer($this); $this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logOut", [ TextFormat::AQUA . $this->getName() . TextFormat::WHITE, diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 62ccae495f..d5d99752a6 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -291,12 +291,6 @@ class Server{ /** @var Config */ private $config; - /** @var Player[] */ - private $players = []; - - /** @var Player[] */ - private $loggedInPlayers = []; - /** @var Player[] */ private $playerList = []; @@ -602,13 +596,6 @@ class Server{ return $this->commandMap; } - /** - * @return Player[] - */ - public function getLoggedInPlayers() : array{ - return $this->loggedInPlayers; - } - /** * @return Player[] */ @@ -1654,8 +1641,8 @@ class Server{ $this->pluginManager->disablePlugins(); } - foreach($this->players as $player){ - $player->close($player->getLeaveMessage(), $this->getProperty("settings.shutdown-message", "Server closed")); + if($this->network instanceof Network){ + $this->network->getSessionManager()->close($this->getProperty("settings.shutdown-message", "Server closed")); } if($this->levelManager instanceof LevelManager){ @@ -1883,23 +1870,6 @@ class Server{ if($this->sendUsageTicker > 0){ $this->uniquePlayers[$player->getRawUniqueId()] = $player->getRawUniqueId(); } - - $this->loggedInPlayers[$player->getRawUniqueId()] = $player; - } - - public function onPlayerLogout(Player $player) : void{ - unset($this->loggedInPlayers[$player->getRawUniqueId()]); - } - - public function addPlayer(Player $player) : void{ - $this->players[spl_object_id($player)] = $player; - } - - /** - * @param Player $player - */ - public function removePlayer(Player $player) : void{ - unset($this->players[spl_object_id($player)]); } public function addOnlinePlayer(Player $player) : void{ diff --git a/src/pocketmine/level/LevelManager.php b/src/pocketmine/level/LevelManager.php index 7f0eebe32b..b6d8e9cbd4 100644 --- a/src/pocketmine/level/LevelManager.php +++ b/src/pocketmine/level/LevelManager.php @@ -404,8 +404,6 @@ class LevelManager{ foreach($level->getPlayers() as $player){ if($player->spawned){ $player->save(); - }elseif(!$player->isConnected()){ //TODO: check if this is ever possible - $this->server->removePlayer($player); } } $level->save(false); diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index ed6e484af3..5524232634 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -28,7 +28,6 @@ namespace pocketmine\network; use pocketmine\event\server\NetworkInterfaceRegisterEvent; use pocketmine\event\server\NetworkInterfaceUnregisterEvent; -use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\PacketPool; use function get_class; use function spl_object_id; @@ -46,11 +45,12 @@ class Network{ /** @var string */ private $name; - /** @var NetworkSession[] */ - private $updateSessions = []; + /** @var NetworkSessionManager */ + private $sessionManager; public function __construct(){ PacketPool::init(); + $this->sessionManager = new NetworkSessionManager(); } public function addStatistics(float $upload, float $download) : void{ @@ -78,12 +78,15 @@ class Network{ return $this->interfaces; } + /** + * @return NetworkSessionManager + */ + public function getSessionManager() : NetworkSessionManager{ + return $this->sessionManager; + } + public function getConnectionCount() : int{ - $count = 0; - foreach($this->interfaces as $interface){ - $count += $interface->getConnectionCount(); - } - return $count; + return $this->sessionManager->getSessionCount(); } public function tick() : void{ @@ -91,11 +94,7 @@ class Network{ $interface->tick(); } - foreach($this->updateSessions as $k => $session){ - if(!$session->isConnected() or !$session->tick()){ - unset($this->updateSessions[$k]); - } - } + $this->sessionManager->tick(); } /** @@ -187,8 +186,4 @@ class Network{ $interface->addRawPacketFilter($regex); } } - - public function scheduleSessionTick(NetworkSession $session) : void{ - $this->updateSessions[spl_object_id($session)] = $session; - } } diff --git a/src/pocketmine/network/NetworkSessionManager.php b/src/pocketmine/network/NetworkSessionManager.php new file mode 100644 index 0000000000..179ba38db2 --- /dev/null +++ b/src/pocketmine/network/NetworkSessionManager.php @@ -0,0 +1,129 @@ +sessions[$idx] = $this->updateSessions[$idx] = $session; + } + + /** + * Removes the given network session, due to disconnect. This should only be called by a network session on + * disconnection. + * + * @param NetworkSession $session + */ + public function remove(NetworkSession $session) : void{ + $idx = spl_object_id($session); + unset($this->sessions[$idx], $this->updateSessions[$idx]); + } + + /** + * Requests an update to be scheduled on the given network session at the next tick. + * + * @param NetworkSession $session + */ + public function scheduleUpdate(NetworkSession $session) : void{ + $this->updateSessions[spl_object_id($session)] = $session; + } + + /** + * Checks whether this network session is a duplicate of an already-connected session (same player connecting from + * 2 locations). + * + * @param NetworkSession $connectingSession + * + * @return bool if the network session is still connected. + */ + public function kickDuplicates(NetworkSession $connectingSession) : bool{ + foreach($this->sessions as $existingSession){ + if($existingSession === $connectingSession){ + continue; + } + $info = $existingSession->getPlayerInfo(); + if($info !== null and ($info->getUsername() === $connectingSession->getPlayerInfo()->getUsername() or $info->getUuid()->equals($connectingSession->getPlayerInfo()->getUuid()))){ + $ev = new PlayerDuplicateLoginEvent($connectingSession, $existingSession); + $ev->call(); + if($ev->isCancelled()){ + $connectingSession->disconnect($ev->getDisconnectMessage()); + return false; + } + + $existingSession->disconnect($ev->getDisconnectMessage()); + } + } + + return true; + } + + /** + * Returns the number of known connected sessions. + * + * @return int + */ + public function getSessionCount() : int{ + return count($this->sessions); + } + + /** + * Updates all sessions which need it. + */ + public function tick() : void{ + foreach($this->updateSessions as $k => $session){ + if(!$session->tick()){ + unset($this->updateSessions[$k]); + } + } + } + + /** + * Terminates all connected sessions with the given reason. + * + * @param string $reason + */ + public function close(string $reason = "") : void{ + foreach($this->sessions as $session){ + $session->disconnect($reason); + } + $this->sessions = []; + $this->updateSessions = []; + } +} diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index a5089562cd..6e0751e6df 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -42,7 +42,9 @@ use pocketmine\network\mcpe\protocol\PlayStatusPacket; use pocketmine\network\mcpe\protocol\ServerboundPacket; use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket; use pocketmine\network\NetworkInterface; +use pocketmine\network\NetworkSessionManager; use pocketmine\Player; +use pocketmine\PlayerInfo; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\BinaryDataException; @@ -56,12 +58,16 @@ class NetworkSession{ private $server; /** @var Player|null */ private $player; + /** @var NetworkSessionManager */ + private $manager; /** @var NetworkInterface */ private $interface; /** @var string */ private $ip; /** @var int */ private $port; + /** @var PlayerInfo */ + private $info; /** @var int */ private $ping; @@ -82,8 +88,9 @@ class NetworkSession{ /** @var \SplQueue|CompressBatchPromise[] */ private $compressedQueue; - public function __construct(Server $server, NetworkInterface $interface, string $ip, int $port){ + public function __construct(Server $server, NetworkSessionManager $manager, NetworkInterface $interface, string $ip, int $port){ $this->server = $server; + $this->manager = $manager; $this->interface = $interface; $this->ip = $ip; $this->port = $port; @@ -91,12 +98,13 @@ class NetworkSession{ $this->compressedQueue = new \SplQueue(); $this->connectTime = time(); - $this->server->getNetwork()->scheduleSessionTick($this); //TODO: this should happen later in the login sequence $this->createPlayer(); $this->setHandler(new LoginSessionHandler($this->player, $this)); + + $this->manager->add($this); } protected function createPlayer() : void{ @@ -109,14 +117,29 @@ class NetworkSession{ * @see Player::__construct() */ $this->player = new $class($this->server, $this); - - $this->server->addPlayer($this->player); } public function getPlayer() : ?Player{ return $this->player; } + public function getPlayerInfo() : ?PlayerInfo{ + return $this->info; + } + + /** + * TODO: this shouldn't be accessible after the initial login phase + * + * @param PlayerInfo $info + * @throws \InvalidStateException + */ + public function setPlayerInfo(PlayerInfo $info) : void{ + if($this->info !== null){ + throw new \InvalidStateException("Player info has already been set"); + } + $this->info = $info; + } + public function isConnected() : bool{ return $this->connected; } @@ -285,7 +308,7 @@ class NetworkSession{ $this->sendBuffer = new PacketStream(); } $this->sendBuffer->putPacket($packet); - $this->server->getNetwork()->scheduleSessionTick($this); + $this->manager->scheduleUpdate($this); //schedule flush at end of tick }finally{ $timings->stopTiming(); } @@ -337,6 +360,15 @@ class NetworkSession{ $this->interface->putPacket($this, $payload, $immediate); } + private function checkDisconnect() : bool{ + if($this->connected){ + $this->connected = false; + $this->manager->remove($this); + return true; + } + return false; + } + /** * Disconnects the session, destroying the associated player (if it exists). * @@ -344,8 +376,7 @@ class NetworkSession{ * @param bool $notify */ public function disconnect(string $reason, bool $notify = true) : void{ - if($this->connected){ - $this->connected = false; + if($this->checkDisconnect()){ $this->player->close($this->player->getLeaveMessage(), $reason); $this->doServerDisconnect($reason, $notify); } @@ -358,8 +389,7 @@ class NetworkSession{ * @param bool $notify */ public function onPlayerDestroyed(string $reason, bool $notify = true) : void{ - if($this->connected){ - $this->connected = false; + if($this->checkDisconnect()){ $this->doServerDisconnect($reason, $notify); } } @@ -388,8 +418,7 @@ class NetworkSession{ * @param string $reason */ public function onClientDisconnect(string $reason) : void{ - if($this->connected){ - $this->connected = false; + if($this->checkDisconnect()){ $this->player->close($this->player->getLeaveMessage(), $reason); } } diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 15b4f02fbf..491806c51b 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -143,7 +143,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ } public function openSession(int $sessionId, string $address, int $port, int $clientID) : void{ - $session = new NetworkSession($this->server, $this, $address, $port); + $session = new NetworkSession($this->server, $this->network->getSessionManager(), $this, $address, $port); $this->sessions[$sessionId] = $session; $this->identifiers[spl_object_id($session)] = $sessionId; } diff --git a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php index 7db8565413..acb4d75c8f 100644 --- a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php @@ -45,6 +45,8 @@ class LoginSessionHandler extends SessionHandler{ } public function handleLogin(LoginPacket $packet) : bool{ + $this->session->setPlayerInfo($packet->playerInfo); + if(!$this->isCompatibleProtocol($packet->protocol)){ $pk = new PlayStatusPacket(); $pk->status = $packet->protocol < ProtocolInfo::CURRENT_PROTOCOL ? From ebfe9caca37a5a48ab466acecf4a0f094bdb8e62 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 14 Mar 2019 14:45:30 +0000 Subject: [PATCH 0633/3224] Move too-early-send check to NetworkSession --- src/pocketmine/Player.php | 5 ----- src/pocketmine/network/mcpe/NetworkSession.php | 10 ++++++++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 7641d9802f..7ab383db22 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2506,11 +2506,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return false; } - //Basic safety restriction. TODO: improve this - if(!$this->loggedIn and !$packet->canBeSentBeforeLogin()){ - throw new \InvalidArgumentException("Attempted to send " . get_class($packet) . " to " . $this->getName() . " too early"); - } - return $this->networkSession->sendDataPacket($packet, $immediate); } diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 6e0751e6df..2a8f1da8fe 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -49,6 +49,7 @@ use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\BinaryDataException; use function bin2hex; +use function get_class; use function strlen; use function substr; use function time; @@ -76,6 +77,8 @@ class NetworkSession{ /** @var bool */ private $connected = true; + /** @var bool */ + private $loggedIn = false; /** @var int */ private $connectTime; @@ -276,6 +279,11 @@ class NetworkSession{ } public function sendDataPacket(ClientboundPacket $packet, bool $immediate = false) : bool{ + //Basic safety restriction. TODO: improve this + if(!$this->loggedIn and !$packet->canBeSentBeforeLogin()){ + throw new \InvalidArgumentException("Attempted to send " . get_class($packet) . " to " . $this->getDisplayName() . " too early"); + } + $timings = Timings::getSendDataPacketTimings($packet); $timings->startTiming(); try{ @@ -435,6 +443,8 @@ class NetworkSession{ } public function onLoginSuccess() : void{ + $this->loggedIn = true; + $pk = new PlayStatusPacket(); $pk->status = PlayStatusPacket::LOGIN_SUCCESS; $this->sendDataPacket($pk); From a1ffaffa7ff58b4f56c8af10cb21b9f9f4dce0e7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 14 Mar 2019 14:46:19 +0000 Subject: [PATCH 0634/3224] Don't record player on stats until they actually exist --- src/pocketmine/Player.php | 1 - src/pocketmine/Server.php | 10 ++++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 7ab383db22..e9615e1029 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1799,7 +1799,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, public function onLoginSuccess() : void{ $this->loggedIn = true; - $this->server->onPlayerLogin($this); } public function _actuallyConstruct(){ diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index d5d99752a6..d5ea787e11 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1866,16 +1866,14 @@ class Server{ } } - public function onPlayerLogin(Player $player) : void{ - if($this->sendUsageTicker > 0){ - $this->uniquePlayers[$player->getRawUniqueId()] = $player->getRawUniqueId(); - } - } - public function addOnlinePlayer(Player $player) : void{ $this->updatePlayerListData($player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkin(), $player->getXuid()); $this->playerList[$player->getRawUniqueId()] = $player; + + if($this->sendUsageTicker > 0){ + $this->uniquePlayers[$player->getRawUniqueId()] = $player->getRawUniqueId(); + } } public function removeOnlinePlayer(Player $player) : void{ From 41d13b6f064515cd9f0bc51c9366d5e1d41a93f9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 14 Mar 2019 14:47:20 +0000 Subject: [PATCH 0635/3224] Player: remove dead condition this can't be reached because the only place it's called is from Level->actuallyDoTick(), where it won't appear until long after the player is logged in. --- src/pocketmine/Player.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index e9615e1029..11f320a4ab 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1604,10 +1604,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } public function onUpdate(int $currentTick) : bool{ - if(!$this->loggedIn){ - return false; - } - $tickDiff = $currentTick - $this->lastUpdate; if($tickDiff <= 0){ From d080d3bae0ad2e55e3743e36c4071f807623180d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 14 Mar 2019 15:02:15 +0000 Subject: [PATCH 0636/3224] RegionLoader: Write location table changes when deleting chunks --- src/pocketmine/level/format/io/region/RegionLoader.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pocketmine/level/format/io/region/RegionLoader.php b/src/pocketmine/level/format/io/region/RegionLoader.php index d9a1cbf072..8b6c9e9e93 100644 --- a/src/pocketmine/level/format/io/region/RegionLoader.php +++ b/src/pocketmine/level/format/io/region/RegionLoader.php @@ -216,6 +216,7 @@ class RegionLoader{ public function removeChunk(int $x, int $z) : void{ $index = self::getChunkOffset($x, $z); $this->locationTable[$index] = new RegionLocationTableEntry(0, 0, 0); + $this->writeLocationIndex($index); } /** From 1e0f1e5b1a5ff28e05cbdbe4078e3a8bb297b586 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 14 Mar 2019 15:06:13 +0000 Subject: [PATCH 0637/3224] RegionLoader: Stop unnecessarily writing location header on close Any time a region is modified, the location header is written anyway, so this is entirely unnecessary. --- .../format/io/region/RegionLevelProvider.php | 2 +- .../level/format/io/region/RegionLoader.php | 25 ++----------------- 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/src/pocketmine/level/format/io/region/RegionLevelProvider.php b/src/pocketmine/level/format/io/region/RegionLevelProvider.php index da83762260..d0e634beaa 100644 --- a/src/pocketmine/level/format/io/region/RegionLevelProvider.php +++ b/src/pocketmine/level/format/io/region/RegionLevelProvider.php @@ -148,7 +148,7 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ $logger = \GlobalLogger::get(); $logger->error("Corrupted region file detected: " . $e->getMessage()); - $region->close(false); //Do not write anything to the file + $region->close(); //Do not write anything to the file $backupPath = $path . ".bak." . time(); rename($path, $backupPath); diff --git a/src/pocketmine/level/format/io/region/RegionLoader.php b/src/pocketmine/level/format/io/region/RegionLoader.php index 8b6c9e9e93..3deb687bb2 100644 --- a/src/pocketmine/level/format/io/region/RegionLoader.php +++ b/src/pocketmine/level/format/io/region/RegionLoader.php @@ -40,7 +40,6 @@ use function fwrite; use function is_resource; use function max; use function ord; -use function pack; use function str_pad; use function stream_set_read_buffer; use function stream_set_write_buffer; @@ -102,7 +101,6 @@ class RegionLoader{ public function __destruct(){ if(is_resource($this->filePointer)){ - $this->writeLocationTable(); fclose($this->filePointer); } } @@ -244,16 +242,10 @@ class RegionLoader{ } /** - * Writes the region header and closes the file - * - * @param bool $writeHeader + * Closes the file */ - public function close(bool $writeHeader = true) : void{ + public function close() : void{ if(is_resource($this->filePointer)){ - if($writeHeader){ - $this->writeLocationTable(); - } - fclose($this->filePointer); } } @@ -320,19 +312,6 @@ class RegionLoader{ } } - private function writeLocationTable() : void{ - $write = []; - - for($i = 0; $i < 1024; ++$i){ - $write[] = (($this->locationTable[$i]->getFirstSector() << 8) | $this->locationTable[$i]->getSectorCount()); - } - for($i = 0; $i < 1024; ++$i){ - $write[] = $this->locationTable[$i]->getTimestamp(); - } - fseek($this->filePointer, 0); - fwrite($this->filePointer, pack("N*", ...$write), 4096 * 2); - } - protected function writeLocationIndex(int $index) : void{ fseek($this->filePointer, $index << 2); fwrite($this->filePointer, Binary::writeInt(($this->locationTable[$index]->getFirstSector() << 8) | $this->locationTable[$index]->getSectorCount()), 4); From 62185d476bc2463be6de20604cd4ef83733dcce2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 14 Mar 2019 15:22:44 +0000 Subject: [PATCH 0638/3224] RegionLoader: Fixed performance issue converting huge worlds I was big nub when i wrote this code. --- src/pocketmine/level/format/io/region/RegionLoader.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/level/format/io/region/RegionLoader.php b/src/pocketmine/level/format/io/region/RegionLoader.php index 3deb687bb2..9d0aac0ff4 100644 --- a/src/pocketmine/level/format/io/region/RegionLoader.php +++ b/src/pocketmine/level/format/io/region/RegionLoader.php @@ -29,7 +29,7 @@ use pocketmine\utils\Binary; use function ceil; use function chr; use function fclose; -use function fgetc; +use function feof; use function file_exists; use function filesize; use function fopen; @@ -301,7 +301,7 @@ class RegionLoader{ //TODO: more validity checks fseek($this->filePointer, $fileOffset); - if(fgetc($this->filePointer) === false){ //Try and read from the location + if(feof($this->filePointer)){ throw new CorruptedRegionException("Region file location offset x=$x,z=$z points to invalid file location $fileOffset"); } if(isset($usedOffsets[$offset])){ From a91f49220cc02d6c180e9321810aad051e34655a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 14 Mar 2019 16:34:14 +0000 Subject: [PATCH 0639/3224] Chunk: Do not mark as changed on lighting updates Since we don't save light to disk anymore, we don't need to care if a light update took place. This improves I/O performance. --- src/pocketmine/level/format/Chunk.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index e1555dd8fb..efa0819ac6 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -229,9 +229,7 @@ class Chunk{ * @param int $level 0-15 */ public function setBlockSkyLight(int $x, int $y, int $z, int $level) : void{ - if($this->getSubChunk($y >> 4, true)->setBlockSkyLight($x, $y & 0x0f, $z, $level)){ - $this->hasChanged = true; - } + $this->getSubChunk($y >> 4, true)->setBlockSkyLight($x, $y & 0x0f, $z, $level); } /** @@ -267,9 +265,7 @@ class Chunk{ * @param int $level 0-15 */ public function setBlockLight(int $x, int $y, int $z, int $level) : void{ - if($this->getSubChunk($y >> 4, true)->setBlockLight($x, $y & 0x0f, $z, $level)){ - $this->hasChanged = true; - } + $this->getSubChunk($y >> 4, true)->setBlockLight($x, $y & 0x0f, $z, $level); } /** From 9205bbaa42dca7312c47e361ad4d482b8317ea9e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 15 Mar 2019 04:43:19 -0400 Subject: [PATCH 0640/3224] ... why is this not saved on provider close...? --- src/pocketmine/level/format/io/FormatConverter.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pocketmine/level/format/io/FormatConverter.php b/src/pocketmine/level/format/io/FormatConverter.php index 574deb9029..878b81c331 100644 --- a/src/pocketmine/level/format/io/FormatConverter.php +++ b/src/pocketmine/level/format/io/FormatConverter.php @@ -119,6 +119,7 @@ class FormatConverter{ $data->setSpawn($oldData->getSpawn()); $data->setTime($oldData->getTime()); + $data->save(); $this->logger->info("Finished converting manifest"); //TODO: add more properties as-needed } From 7d72b8e756729b0c4e8503b527f5369839bb4d0a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 15 Mar 2019 15:27:33 +0000 Subject: [PATCH 0641/3224] leveldb: use writebatch for chunk saving (faster I/O) i don't know why this wasn't already using a writebatch, but it should have been. --- .../level/format/io/leveldb/LevelDB.php | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index 16c9562547..195271cbd7 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -356,13 +356,15 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ $idMap = array_flip(json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . '/legacy_id_map.json'), true)); } $index = LevelDB::chunkIndex($chunk->getX(), $chunk->getZ()); - $this->db->put($index . self::TAG_VERSION, chr(self::CURRENT_LEVEL_CHUNK_VERSION)); + + $write = new \LevelDBWriteBatch(); + $write->put($index . self::TAG_VERSION, chr(self::CURRENT_LEVEL_CHUNK_VERSION)); $subChunks = $chunk->getSubChunks(); foreach($subChunks as $y => $subChunk){ $key = $index . self::TAG_SUBCHUNK_PREFIX . chr($y); if($subChunk->isEmpty(false)){ //MCPE doesn't save light anymore as of 1.1 - $this->db->delete($key); + $write->delete($key); }else{ $subStream = new BinaryStream(); $subStream->putByte(self::CURRENT_LEVEL_SUBCHUNK_VERSION); @@ -387,32 +389,35 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ $subStream->put((new LittleEndianNbtSerializer())->writeMultiple($tags)); } - $this->db->put($key, $subStream->getBuffer()); + $write->put($key, $subStream->getBuffer()); } } - $this->db->put($index . self::TAG_DATA_2D, str_repeat("\x00", 512) . $chunk->getBiomeIdArray()); + $write->put($index . self::TAG_DATA_2D, str_repeat("\x00", 512) . $chunk->getBiomeIdArray()); //TODO: use this properly - $this->db->put($index . self::TAG_STATE_FINALISATION, chr(self::FINALISATION_DONE)); + $write->put($index . self::TAG_STATE_FINALISATION, chr(self::FINALISATION_DONE)); - $this->writeTags($chunk->getNBTtiles(), $index . self::TAG_BLOCK_ENTITY); - $this->writeTags($chunk->getNBTentities(), $index . self::TAG_ENTITY); + $this->writeTags($chunk->getNBTtiles(), $index . self::TAG_BLOCK_ENTITY, $write); + $this->writeTags($chunk->getNBTentities(), $index . self::TAG_ENTITY, $write); - $this->db->delete($index . self::TAG_DATA_2D_LEGACY); - $this->db->delete($index . self::TAG_LEGACY_TERRAIN); + $write->delete($index . self::TAG_DATA_2D_LEGACY); + $write->delete($index . self::TAG_LEGACY_TERRAIN); + + $this->db->write($write); } /** - * @param CompoundTag[] $targets - * @param string $index + * @param CompoundTag[] $targets + * @param string $index + * @param \LevelDBWriteBatch $write */ - private function writeTags(array $targets, string $index) : void{ + private function writeTags(array $targets, string $index, \LevelDBWriteBatch $write) : void{ if(!empty($targets)){ $nbt = new LittleEndianNbtSerializer(); - $this->db->put($index, $nbt->writeMultiple($targets)); + $write->put($index, $nbt->writeMultiple($targets)); }else{ - $this->db->delete($index); + $write->delete($index); } } From 87928038e69895d4f717006e6b42a10c1ccd30eb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 17 Mar 2019 15:19:47 +0000 Subject: [PATCH 0642/3224] sync deps --- composer.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.lock b/composer.lock index f46ba97f7c..b942bb6f51 100644 --- a/composer.lock +++ b/composer.lock @@ -372,12 +372,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "87a0312552d679365c6e3304637cd0e3963175da" + "reference": "cb170cf827e265cfb492de2af684cba23574dfec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/87a0312552d679365c6e3304637cd0e3963175da", - "reference": "87a0312552d679365c6e3304637cd0e3963175da", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/cb170cf827e265cfb492de2af684cba23574dfec", + "reference": "cb170cf827e265cfb492de2af684cba23574dfec", "shasum": "" }, "require": { @@ -405,7 +405,7 @@ "source": "https://github.com/pmmp/NBT/tree/master", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2019-02-07T17:04:08+00:00" + "time": "2019-03-16T12:12:20+00:00" }, { "name": "pocketmine/raklib", @@ -488,12 +488,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/SPL.git", - "reference": "35110fcc742701d5f2b8093d63365c42900236c1" + "reference": "02476b8990ad31c38fa999ec0392f6d01208574d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/SPL/zipball/35110fcc742701d5f2b8093d63365c42900236c1", - "reference": "35110fcc742701d5f2b8093d63365c42900236c1", + "url": "https://api.github.com/repos/pmmp/SPL/zipball/02476b8990ad31c38fa999ec0392f6d01208574d", + "reference": "02476b8990ad31c38fa999ec0392f6d01208574d", "shasum": "" }, "type": "library", @@ -512,7 +512,7 @@ "support": { "source": "https://github.com/pmmp/SPL/tree/master" }, - "time": "2019-02-23T12:20:29+00:00" + "time": "2019-03-15T15:22:36+00:00" } ], "packages-dev": [], From 6f54b53f7adb9bdd3ccc7119c68f600526bf67e4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 17 Mar 2019 15:53:59 +0000 Subject: [PATCH 0643/3224] thanks for being useless PhpStorm these problems didn't show up in any inspections until I opened the fucking files... --- src/pocketmine/entity/Entity.php | 2 +- src/pocketmine/item/Item.php | 2 +- src/pocketmine/tile/Tile.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 49014c4636..7e62b59fd4 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -715,7 +715,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } public function saveNBT() : CompoundTag{ - $nbt = new CompoundTag(); + $nbt = new CompoundTag(""); if(!($this instanceof Player)){ $nbt->setString("id", EntityFactory::getSaveId(get_class($this))); diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index eeb7a92a38..ea17e6978e 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -518,7 +518,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return CompoundTag */ public function getNamedTag() : CompoundTag{ - return $this->nbt ?? ($this->nbt = new CompoundTag()); + return $this->nbt ?? ($this->nbt = new CompoundTag("")); } /** diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/tile/Tile.php index 963129dfb6..4cadd2b517 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/tile/Tile.php @@ -72,7 +72,7 @@ abstract class Tile extends Position{ abstract protected function writeSaveData(CompoundTag $nbt) : void; public function saveNBT() : CompoundTag{ - $nbt = new CompoundTag(); + $nbt = new CompoundTag(""); $nbt->setString(self::TAG_ID, TileFactory::getSaveId(get_class($this))); $nbt->setInt(self::TAG_X, $this->x); $nbt->setInt(self::TAG_Y, $this->y); @@ -83,7 +83,7 @@ abstract class Tile extends Position{ } public function getCleanedNBT() : ?CompoundTag{ - $this->writeSaveData($tag = new CompoundTag()); + $this->writeSaveData($tag = new CompoundTag("")); return $tag->getCount() > 0 ? $tag : null; } From 5830ca958b959725f70009c0299a2e05cf1e0fbe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 17 Mar 2019 16:01:04 +0000 Subject: [PATCH 0644/3224] Further out-phasing of legacy ID/meta this paves the way for making internal IDs fully dynamic. --- src/pocketmine/block/Block.php | 10 ++++++++- src/pocketmine/level/SimpleChunkManager.php | 3 ++- src/pocketmine/level/format/Chunk.php | 22 +++++++------------ src/pocketmine/level/format/EmptySubChunk.php | 4 ++-- src/pocketmine/level/format/SubChunk.php | 5 ++--- .../level/format/SubChunkInterface.php | 7 ++---- src/pocketmine/level/generator/Flat.php | 10 ++++----- .../level/generator/hell/Nether.php | 11 +++++++--- .../level/generator/normal/Normal.php | 10 ++++++--- .../level/generator/populator/GroundCover.php | 2 +- 10 files changed, 46 insertions(+), 38 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 6056ec5ffe..9e9db82032 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -107,6 +107,14 @@ class Block extends Position implements BlockIds, Metadatable{ return $this->idInfo->getBlockId(); } + /** + * @internal + * @return int + */ + public function getFullId() : int{ + return ($this->getId() << 4) | $this->getMeta(); + } + public function asItem() : Item{ return ItemFactory::get($this->idInfo->getItemId(), $this->idInfo->getVariant()); } @@ -155,7 +163,7 @@ class Block extends Position implements BlockIds, Metadatable{ } public function writeStateToWorld() : void{ - $this->level->getChunkAtPosition($this)->setBlock($this->x & 0xf, $this->y, $this->z & 0xf, $this->getId(), $this->getMeta()); + $this->level->getChunkAtPosition($this)->setFullBlock($this->x & 0xf, $this->y, $this->z & 0xf, $this->getFullId()); $tileType = $this->idInfo->getTileClass(); $oldTile = $this->level->getTile($this); diff --git a/src/pocketmine/level/SimpleChunkManager.php b/src/pocketmine/level/SimpleChunkManager.php index 7c3c038d17..6d019cc204 100644 --- a/src/pocketmine/level/SimpleChunkManager.php +++ b/src/pocketmine/level/SimpleChunkManager.php @@ -54,7 +54,8 @@ class SimpleChunkManager implements ChunkManager{ public function setBlockAt(int $x, int $y, int $z, Block $block) : bool{ if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ - return $chunk->setBlock($x & 0xf, $y, $z & 0xf, $block->getId(), $block->getMeta()); + $chunk->setFullBlock($x & 0xf, $y, $z & 0xf, $block->getFullId()); + return true; } return false; } diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index efa0819ac6..68a3103c2f 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -176,7 +176,7 @@ class Chunk{ } /** - * Returns a bitmap of block ID and meta at the specified chunk block coordinates + * Returns the internal ID of the blockstate at the given coordinates. * * @param int $x 0-15 * @param int $y @@ -189,22 +189,16 @@ class Chunk{ } /** - * Sets block ID and meta in one call at the specified chunk block coordinates + * Sets the blockstate at the given coordinate by internal ID. * - * @param int $x 0-15 + * @param int $x * @param int $y - * @param int $z 0-15 - * @param int $blockId 0-255 - * @param int $meta 0-15 - * - * @return bool + * @param int $z + * @param int $block */ - public function setBlock(int $x, int $y, int $z, int $blockId, int $meta) : bool{ - if($this->getSubChunk($y >> 4, true)->setBlock($x, $y & 0x0f, $z, $blockId, $meta & 0x0f)){ - $this->hasChanged = true; - return true; - } - return false; + public function setFullBlock(int $x, int $y, int $z, int $block) : void{ + $this->getSubChunk($y >> 4)->setFullBlock($x, $y & 0xf, $z, $block); + $this->hasChanged = true; } /** diff --git a/src/pocketmine/level/format/EmptySubChunk.php b/src/pocketmine/level/format/EmptySubChunk.php index f45a8b0717..54bb0d69cb 100644 --- a/src/pocketmine/level/format/EmptySubChunk.php +++ b/src/pocketmine/level/format/EmptySubChunk.php @@ -45,8 +45,8 @@ class EmptySubChunk implements SubChunkInterface{ return 0; } - public function setBlock(int $x, int $y, int $z, int $id, int $data) : bool{ - return false; + public function setFullBlock(int $x, int $y, int $z, int $block) : void{ + } public function getBlockLayers() : array{ diff --git a/src/pocketmine/level/format/SubChunk.php b/src/pocketmine/level/format/SubChunk.php index 4a4aa4f43c..0bb3a0b3f2 100644 --- a/src/pocketmine/level/format/SubChunk.php +++ b/src/pocketmine/level/format/SubChunk.php @@ -94,12 +94,11 @@ class SubChunk implements SubChunkInterface{ return $this->blockLayers[0]->get($x, $y, $z); } - public function setBlock(int $x, int $y, int $z, int $id, int $data) : bool{ + public function setFullBlock(int $x, int $y, int $z, int $block) : void{ if(empty($this->blockLayers)){ $this->blockLayers[] = new PalettedBlockArray(BlockIds::AIR << 4); } - $this->blockLayers[0]->set($x, $y, $z, ($id << 4) | $data); - return true; + $this->blockLayers[0]->set($x, $y, $z, $block); } /** diff --git a/src/pocketmine/level/format/SubChunkInterface.php b/src/pocketmine/level/format/SubChunkInterface.php index 6b57b6bec3..245c492989 100644 --- a/src/pocketmine/level/format/SubChunkInterface.php +++ b/src/pocketmine/level/format/SubChunkInterface.php @@ -45,12 +45,9 @@ interface SubChunkInterface{ * @param int $x * @param int $y * @param int $z - * @param int $id - * @param int $data - * - * @return bool + * @param int $block */ - public function setBlock(int $x, int $y, int $z, int $id, int $data) : bool; + public function setFullBlock(int $x, int $y, int $z, int $block) : void; /** * @return PalettedBlockArray[] diff --git a/src/pocketmine/level/generator/Flat.php b/src/pocketmine/level/generator/Flat.php index 220ec3a0e7..a0aebdca58 100644 --- a/src/pocketmine/level/generator/Flat.php +++ b/src/pocketmine/level/generator/Flat.php @@ -43,7 +43,7 @@ class Flat extends Generator{ private $chunk; /** @var Populator[] */ private $populators = []; - /** @var int[][] */ + /** @var int[] */ private $structure; /** @var int */ private $floorLevel; @@ -96,7 +96,7 @@ class Flat extends Generator{ /** * @param string $layers * - * @return int[][] + * @return int[] * @throws InvalidGeneratorOptionsException */ public static function parseLayers(string $layers) : array{ @@ -116,7 +116,7 @@ class Flat extends Generator{ throw new InvalidGeneratorOptionsException("Invalid preset layer \"$line\": " . $e->getMessage(), 0, $e); } for($cY = $y, $y += $cnt; $cY < $y; ++$cY){ - $result[$cY] = [$b->getId(), $b->getMeta()]; + $result[$cY] = $b->getFullId(); } } @@ -164,11 +164,11 @@ class Flat extends Generator{ for($sy = 0; $sy < $count; $sy += 16){ $subchunk = $this->chunk->getSubChunk($sy >> 4, true); for($y = 0; $y < 16 and isset($this->structure[$y | $sy]); ++$y){ - list($id, $meta) = $this->structure[$y | $sy]; + $id = $this->structure[$y | $sy]; for($Z = 0; $Z < 16; ++$Z){ for($X = 0; $X < 16; ++$X){ - $subchunk->setBlock($X, $y, $Z, $id, $meta); + $subchunk->setFullBlock($X, $y, $Z, $id); } } } diff --git a/src/pocketmine/level/generator/hell/Nether.php b/src/pocketmine/level/generator/hell/Nether.php index 5f1c096d33..9a6115ea7e 100644 --- a/src/pocketmine/level/generator/hell/Nether.php +++ b/src/pocketmine/level/generator/hell/Nether.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\level\generator\hell; use pocketmine\block\Block; +use pocketmine\block\BlockFactory; use pocketmine\level\biome\Biome; use pocketmine\level\ChunkManager; use pocketmine\level\generator\Generator; @@ -89,6 +90,10 @@ class Nether extends Generator{ $chunk = $this->level->getChunk($chunkX, $chunkZ); + $bedrock = BlockFactory::get(Block::BEDROCK)->getFullId(); + $netherrack = BlockFactory::get(Block::NETHERRACK)->getFullId(); + $stillLava = BlockFactory::get(Block::STILL_LAVA)->getFullId(); + for($x = 0; $x < 16; ++$x){ for($z = 0; $z < 16; ++$z){ @@ -97,16 +102,16 @@ class Nether extends Generator{ for($y = 0; $y < 128; ++$y){ if($y === 0 or $y === 127){ - $chunk->setBlock($x, $y, $z, Block::BEDROCK, 0); + $chunk->setFullBlock($x, $y, $z, $bedrock); continue; } $noiseValue = (abs($this->emptyHeight - $y) / $this->emptyHeight) * $this->emptyAmplitude - $noise[$x][$z][$y]; $noiseValue -= 1 - $this->density; if($noiseValue > 0){ - $chunk->setBlock($x, $y, $z, Block::NETHERRACK, 0); + $chunk->setFullBlock($x, $y, $z, $netherrack); }elseif($y <= $this->waterHeight){ - $chunk->setBlock($x, $y, $z, Block::STILL_LAVA, 0); + $chunk->setFullBlock($x, $y, $z, $stillLava); } } } diff --git a/src/pocketmine/level/generator/normal/Normal.php b/src/pocketmine/level/generator/normal/Normal.php index 091fb995b3..660a6e3ba2 100644 --- a/src/pocketmine/level/generator/normal/Normal.php +++ b/src/pocketmine/level/generator/normal/Normal.php @@ -178,6 +178,10 @@ class Normal extends Generator{ $biomeCache = []; + $bedrock = BlockFactory::get(Block::BEDROCK)->getFullId(); + $stillWater = BlockFactory::get(Block::STILL_WATER)->getFullId(); + $stone = BlockFactory::get(Block::STONE)->getFullId(); + for($x = 0; $x < 16; ++$x){ for($z = 0; $z < 16; ++$z){ $minSum = 0; @@ -217,15 +221,15 @@ class Normal extends Generator{ for($y = 0; $y < 128; ++$y){ if($y === 0){ - $chunk->setBlock($x, $y, $z, Block::BEDROCK, 0); + $chunk->setFullBlock($x, $y, $z, $bedrock); continue; } $noiseValue = $noise[$x][$z][$y] - 1 / $smoothHeight * ($y - $smoothHeight - $minSum); if($noiseValue > 0){ - $chunk->setBlock($x, $y, $z, Block::STONE, 0); + $chunk->setFullBlock($x, $y, $z, $stone); }elseif($y <= $this->waterHeight){ - $chunk->setBlock($x, $y, $z, Block::STILL_WATER, 0); + $chunk->setFullBlock($x, $y, $z, $stillWater); } } } diff --git a/src/pocketmine/level/generator/populator/GroundCover.php b/src/pocketmine/level/generator/populator/GroundCover.php index 84e0405c86..e493a103b6 100644 --- a/src/pocketmine/level/generator/populator/GroundCover.php +++ b/src/pocketmine/level/generator/populator/GroundCover.php @@ -63,7 +63,7 @@ class GroundCover extends Populator{ continue; } - $chunk->setBlock($x, $y, $z, $b->getId(), $b->getMeta()); + $chunk->setFullBlock($x, $y, $z, $b->getFullId()); } } } From 8de9e616512ac8a049b31fb4833f26b135e80f4d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 17 Mar 2019 17:49:09 +0000 Subject: [PATCH 0645/3224] Item: Remove get/set/removeNamedTagEntry() --- src/pocketmine/item/Armor.php | 2 +- src/pocketmine/item/Banner.php | 2 +- src/pocketmine/item/Durable.php | 3 +- src/pocketmine/item/Item.php | 69 +++++++++------------------- src/pocketmine/item/WritableBook.php | 7 ++- src/pocketmine/level/Level.php | 4 +- 6 files changed, 30 insertions(+), 57 deletions(-) diff --git a/src/pocketmine/item/Armor.php b/src/pocketmine/item/Armor.php index c00141e795..4f8812b214 100644 --- a/src/pocketmine/item/Armor.php +++ b/src/pocketmine/item/Armor.php @@ -85,7 +85,7 @@ abstract class Armor extends Durable{ * @param Color $color */ public function setCustomColor(Color $color) : void{ - $this->setNamedTagEntry(new IntTag(self::TAG_CUSTOM_COLOR, Binary::signInt($color->toARGB()))); + $this->getNamedTag()->setInt(self::TAG_CUSTOM_COLOR, Binary::signInt($color->toARGB())); } /** diff --git a/src/pocketmine/item/Banner.php b/src/pocketmine/item/Banner.php index 33bb1456df..7db0be7130 100644 --- a/src/pocketmine/item/Banner.php +++ b/src/pocketmine/item/Banner.php @@ -89,7 +89,7 @@ class Banner extends Item{ new IntTag(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) ])); } - $this->setNamedTagEntry($tag); + $this->getNamedTag()->setTag($tag); } public function getFuelTime() : int{ diff --git a/src/pocketmine/item/Durable.php b/src/pocketmine/item/Durable.php index afe842d6c4..b30610fca4 100644 --- a/src/pocketmine/item/Durable.php +++ b/src/pocketmine/item/Durable.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\item\enchantment\Enchantment; -use pocketmine\nbt\tag\ByteTag; use function lcg_value; use function min; @@ -51,7 +50,7 @@ abstract class Durable extends Item{ * @param bool $value */ public function setUnbreakable(bool $value = true) : void{ - $this->setNamedTagEntry(new ByteTag("Unbreakable", $value ? 1 : 0)); + $this->getNamedTag()->setByte("Unbreakable", $value ? 1 : 0); } /** diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index ea17e6978e..4b243e4155 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -39,7 +39,6 @@ use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; -use pocketmine\nbt\tag\NamedTag; use pocketmine\nbt\tag\ShortTag; use pocketmine\nbt\tag\StringTag; use pocketmine\Player; @@ -186,11 +185,11 @@ class Item implements ItemIds, \JsonSerializable{ * @return bool */ public function hasCustomBlockData() : bool{ - return $this->getNamedTagEntry(self::TAG_BLOCK_ENTITY_TAG) instanceof CompoundTag; + return $this->getNamedTag()->hasTag(self::TAG_BLOCK_ENTITY_TAG, CompoundTag::class); } public function clearCustomBlockData(){ - $this->removeNamedTagEntry(self::TAG_BLOCK_ENTITY_TAG); + $this->getNamedTag()->removeTag(self::TAG_BLOCK_ENTITY_TAG); return $this; } @@ -202,7 +201,7 @@ class Item implements ItemIds, \JsonSerializable{ public function setCustomBlockData(CompoundTag $compound) : Item{ $tags = clone $compound; $tags->setName(self::TAG_BLOCK_ENTITY_TAG); - $this->setNamedTagEntry($tags); + $this->getNamedTag()->setTag($tags); return $this; } @@ -211,15 +210,14 @@ class Item implements ItemIds, \JsonSerializable{ * @return CompoundTag|null */ public function getCustomBlockData() : ?CompoundTag{ - $tag = $this->getNamedTagEntry(self::TAG_BLOCK_ENTITY_TAG); - return $tag instanceof CompoundTag ? $tag : null; + return $this->getNamedTag()->getCompoundTag(self::TAG_BLOCK_ENTITY_TAG); } /** * @return bool */ public function hasEnchantments() : bool{ - return $this->getNamedTagEntry(self::TAG_ENCH) instanceof ListTag; + return $this->getNamedTag()->hasTag(self::TAG_ENCH, ListTag::class); } /** @@ -229,7 +227,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return bool */ public function hasEnchantment(Enchantment $enchantment, int $level = -1) : bool{ - $ench = $this->getNamedTagEntry(self::TAG_ENCH); + $ench = $this->getNamedTag()->getListTag(self::TAG_ENCH); if(!($ench instanceof ListTag)){ return false; } @@ -251,7 +249,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return EnchantmentInstance|null */ public function getEnchantment(Enchantment $enchantment) : ?EnchantmentInstance{ - $ench = $this->getNamedTagEntry(self::TAG_ENCH); + $ench = $this->getNamedTag()->getListTag(self::TAG_ENCH); if(!($ench instanceof ListTag)){ return null; } @@ -277,7 +275,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return Item */ public function removeEnchantment(Enchantment $enchantment, int $level = -1) : Item{ - $ench = $this->getNamedTagEntry(self::TAG_ENCH); + $ench = $this->getNamedTag()->getListTag(self::TAG_ENCH); if(!($ench instanceof ListTag)){ return $this; } @@ -291,8 +289,6 @@ class Item implements ItemIds, \JsonSerializable{ } } - $this->setNamedTagEntry($ench); - return $this; } @@ -300,7 +296,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return Item */ public function removeEnchantments() : Item{ - $this->removeNamedTagEntry(self::TAG_ENCH); + $this->getNamedTag()->removeTag(self::TAG_ENCH); return $this; } @@ -313,7 +309,7 @@ class Item implements ItemIds, \JsonSerializable{ public function addEnchantment(EnchantmentInstance $enchantment) : Item{ $found = false; - $ench = $this->getNamedTagEntry(self::TAG_ENCH); + $ench = $this->getNamedTag()->getListTag(self::TAG_ENCH); if(!($ench instanceof ListTag)){ $ench = new ListTag(self::TAG_ENCH, [], NBT::TAG_Compound); }else{ @@ -337,7 +333,7 @@ class Item implements ItemIds, \JsonSerializable{ ])); } - $this->setNamedTagEntry($ench); + $this->getNamedTag()->setTag($ench); return $this; } @@ -349,7 +345,7 @@ class Item implements ItemIds, \JsonSerializable{ /** @var EnchantmentInstance[] $enchantments */ $enchantments = []; - $ench = $this->getNamedTagEntry(self::TAG_ENCH); + $ench = $this->getNamedTag()->getListTag(self::TAG_ENCH); if($ench instanceof ListTag){ /** @var CompoundTag $entry */ foreach($ench as $entry){ @@ -390,7 +386,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return bool */ public function hasCustomName() : bool{ - $display = $this->getNamedTagEntry(self::TAG_DISPLAY); + $display = $this->getNamedTag()->getCompoundTag(self::TAG_DISPLAY); if($display instanceof CompoundTag){ return $display->hasTag(self::TAG_DISPLAY_NAME); } @@ -402,7 +398,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return string */ public function getCustomName() : string{ - $display = $this->getNamedTagEntry(self::TAG_DISPLAY); + $display = $this->getNamedTag()->getCompoundTag(self::TAG_DISPLAY); if($display instanceof CompoundTag){ return $display->getString(self::TAG_DISPLAY_NAME, ""); } @@ -421,13 +417,13 @@ class Item implements ItemIds, \JsonSerializable{ } /** @var CompoundTag $display */ - $display = $this->getNamedTagEntry(self::TAG_DISPLAY); + $display = $this->getNamedTag()->getCompoundTag(self::TAG_DISPLAY); if(!($display instanceof CompoundTag)){ $display = new CompoundTag(self::TAG_DISPLAY); } $display->setString(self::TAG_DISPLAY_NAME, $name); - $this->setNamedTagEntry($display); + $this->getNamedTag()->setTag($display); return $this; } @@ -436,14 +432,14 @@ class Item implements ItemIds, \JsonSerializable{ * @return Item */ public function clearCustomName() : Item{ - $display = $this->getNamedTagEntry(self::TAG_DISPLAY); + $display = $this->getNamedTag()->getCompoundTag(self::TAG_DISPLAY); if($display instanceof CompoundTag){ $display->removeTag(self::TAG_DISPLAY_NAME); if($display->getCount() === 0){ - $this->removeNamedTagEntry($display->getName()); + $this->getNamedTag()->removeTag(self::TAG_DISPLAY); }else{ - $this->setNamedTagEntry($display); + $this->getNamedTag()->setTag($display); } } @@ -454,7 +450,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return string[] */ public function getLore() : array{ - $display = $this->getNamedTagEntry(self::TAG_DISPLAY); + $display = $this->getNamedTag()->getCompoundTag(self::TAG_DISPLAY); if($display instanceof CompoundTag and ($lore = $display->getListTag(self::TAG_DISPLAY_LORE)) !== null){ return $lore->getAllValues(); } @@ -468,7 +464,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return Item */ public function setLore(array $lines) : Item{ - $display = $this->getNamedTagEntry(self::TAG_DISPLAY); + $display = $this->getNamedTag()->getCompoundTag(self::TAG_DISPLAY); if(!($display instanceof CompoundTag)){ $display = new CompoundTag(self::TAG_DISPLAY, []); } @@ -477,32 +473,11 @@ class Item implements ItemIds, \JsonSerializable{ return new StringTag("", $str); }, $lines), NBT::TAG_String)); - $this->setNamedTagEntry($display); + $this->getNamedTag()->setTag($display); return $this; } - /** - * @param string $name - * - * @return NamedTag|null - */ - public function getNamedTagEntry(string $name) : ?NamedTag{ - return $this->getNamedTag()->getTag($name); - } - - public function setNamedTagEntry(NamedTag $new) : void{ - $tag = $this->getNamedTag(); - $tag->setTag($new); - $this->setNamedTag($tag); - } - - public function removeNamedTagEntry(string $name) : void{ - $tag = $this->getNamedTag(); - $tag->removeTag($name); - $this->setNamedTag($tag); - } - /** * Returns whether this Item has a non-empty NBT. * @return bool diff --git a/src/pocketmine/item/WritableBook.php b/src/pocketmine/item/WritableBook.php index 2bd083e83a..3040bb7bb4 100644 --- a/src/pocketmine/item/WritableBook.php +++ b/src/pocketmine/item/WritableBook.php @@ -91,7 +91,7 @@ class WritableBook extends Item{ $page = $pagesTag->get($pageId); $page->setString(self::TAG_PAGE_TEXT, $pageText); - $this->setNamedTagEntry($pagesTag); + $this->getNamedTag()->setTag($pagesTag); return $created; } @@ -116,7 +116,7 @@ class WritableBook extends Item{ ])); } - $this->setNamedTagEntry($pagesTag); + $this->getNamedTag()->setTag($pagesTag); } /** @@ -129,7 +129,6 @@ class WritableBook extends Item{ public function deletePage(int $pageId) : bool{ $pagesTag = $this->getPagesTag(); $pagesTag->remove($pageId); - $this->setNamedTagEntry($pagesTag); return true; } @@ -150,7 +149,7 @@ class WritableBook extends Item{ new StringTag(self::TAG_PAGE_PHOTONAME, "") ])); - $this->setNamedTagEntry($pagesTag); + $this->getNamedTag()->setTag($pagesTag); return true; } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index f8c3ffa841..468741093f 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1715,7 +1715,7 @@ class Level implements ChunkManager, Metadatable{ } if($player->isAdventure(true) and !$ev->isCancelled()){ - $tag = $item->getNamedTagEntry("CanDestroy"); + $tag = $item->getNamedTag()->getListTag("CanDestroy"); $canBreak = false; if($tag instanceof ListTag){ foreach($tag as $v){ @@ -1865,7 +1865,7 @@ class Level implements ChunkManager, Metadatable{ $ev = new BlockPlaceEvent($player, $hand, $blockReplace, $blockClicked, $item); if($player->isAdventure(true) and !$ev->isCancelled()){ $canPlace = false; - $tag = $item->getNamedTagEntry("CanPlaceOn"); + $tag = $item->getNamedTag()->getListTag("CanPlaceOn"); if($tag instanceof ListTag){ foreach($tag as $v){ if($v instanceof StringTag){ From 2966e87aae2ebaf4b25b1a866c2cec8308ae4b7f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Mar 2019 14:33:56 +0000 Subject: [PATCH 0646/3224] BlockFactory: Regenerate TODO list --- src/pocketmine/block/BlockFactory.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 29e2634c72..3d16e49ea3 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -436,8 +436,8 @@ class BlockFactory{ //TODO: minecraft:birch_standing_sign //TODO: minecraft:birch_wall_sign //TODO: minecraft:blast_furnace - //TODO: minecraft:blue_ice //TODO: minecraft:bubble_column + //TODO: minecraft:campfire //TODO: minecraft:cartography_table //TODO: minecraft:carved_pumpkin //TODO: minecraft:cauldron @@ -447,6 +447,7 @@ class BlockFactory{ //TODO: minecraft:chorus_flower //TODO: minecraft:chorus_plant //TODO: minecraft:command_block + //TODO: minecraft:composter //TODO: minecraft:conduit //TODO: minecraft:coral //TODO: minecraft:coral_block @@ -464,7 +465,6 @@ class BlockFactory{ //TODO: minecraft:double_stone_slab4 //TODO: minecraft:dried_kelp_block //TODO: minecraft:dropper - //TODO: minecraft:element_0 //TODO: minecraft:end_brick_stairs //TODO: minecraft:end_gateway //TODO: minecraft:end_portal @@ -472,12 +472,15 @@ class BlockFactory{ //TODO: minecraft:granite_stairs //TODO: minecraft:grindstone //TODO: minecraft:hopper + //TODO: minecraft:jigsaw //TODO: minecraft:jukebox //TODO: minecraft:jungle_standing_sign //TODO: minecraft:jungle_wall_sign //TODO: minecraft:kelp //TODO: minecraft:lantern //TODO: minecraft:lava_cauldron + //TODO: minecraft:lectern + //TODO: minecraft:loom //TODO: minecraft:monster_egg //TODO: minecraft:mossy_cobblestone_stairs //TODO: minecraft:mossy_stone_brick_stairs @@ -510,6 +513,7 @@ class BlockFactory{ //TODO: minecraft:sticky_piston //TODO: minecraft:stone_slab3 //TODO: minecraft:stone_slab4 + //TODO: minecraft:stonecutter_block //TODO: minecraft:stripped_acacia_log //TODO: minecraft:stripped_birch_log //TODO: minecraft:stripped_dark_oak_log @@ -517,8 +521,10 @@ class BlockFactory{ //TODO: minecraft:stripped_oak_log //TODO: minecraft:stripped_spruce_log //TODO: minecraft:structure_block + //TODO: minecraft:sweet_berry_bush //TODO: minecraft:turtle_egg //TODO: minecraft:undyed_shulker_box + //TODO: minecraft:wood } public static function isInit() : bool{ From 1ac255f95518525085f58ed8dfe1ec2beeb47252 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Mar 2019 15:46:07 +0000 Subject: [PATCH 0647/3224] fix some formatting issues --- src/pocketmine/block/utils/TreeType.php | 3 ++- src/pocketmine/tile/EnchantTable.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/block/utils/TreeType.php b/src/pocketmine/block/utils/TreeType.php index a2c894f5d4..36183d396f 100644 --- a/src/pocketmine/block/utils/TreeType.php +++ b/src/pocketmine/block/utils/TreeType.php @@ -53,7 +53,7 @@ final class TreeType{ new TreeType("birch", "Birch", 2), new TreeType("jungle", "Jungle", 3), new TreeType("acacia", "Acacia", 4), - new TreeType("dark_oak","Dark Oak", 5) + new TreeType("dark_oak", "Dark Oak", 5) ]; } @@ -64,6 +64,7 @@ final class TreeType{ /** * @internal + * * @param int $magicNumber * * @return TreeType diff --git a/src/pocketmine/tile/EnchantTable.php b/src/pocketmine/tile/EnchantTable.php index d6dc08a20b..00e64412b8 100644 --- a/src/pocketmine/tile/EnchantTable.php +++ b/src/pocketmine/tile/EnchantTable.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\tile; class EnchantTable extends Spawnable implements Nameable{ - use NameableTrait{ + use NameableTrait { loadName as public readSaveData; saveName as writeSaveData; } From 8c536c248d6103e838ec94efd318854ee06b356a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Mar 2019 15:58:22 +0000 Subject: [PATCH 0648/3224] Updating for latest PocketMine-NBT changes --- composer.lock | 8 +- src/pocketmine/Player.php | 26 +++---- src/pocketmine/Server.php | 5 +- src/pocketmine/entity/Entity.php | 24 +++--- src/pocketmine/entity/EntityFactory.php | 31 ++++---- src/pocketmine/entity/Human.php | 20 ++--- src/pocketmine/entity/Living.php | 17 ++--- src/pocketmine/entity/object/ItemEntity.php | 2 +- src/pocketmine/item/Banner.php | 14 ++-- src/pocketmine/item/Item.php | 76 ++++++++----------- src/pocketmine/item/WritableBook.php | 27 ++++--- src/pocketmine/level/Level.php | 29 ++++--- .../level/format/io/data/BedrockLevelData.php | 75 +++++++++--------- .../level/format/io/data/JavaLevelData.php | 55 ++++++-------- .../level/format/io/leveldb/LevelDB.php | 22 +++--- .../io/region/LegacyAnvilChunkTrait.php | 2 +- .../level/format/io/region/McRegion.php | 2 +- .../network/mcpe/NetworkBinaryStream.php | 7 +- .../mcpe/handler/SimpleSessionHandler.php | 2 +- src/pocketmine/tile/Banner.php | 25 +++--- src/pocketmine/tile/ContainerTrait.php | 2 +- src/pocketmine/tile/ItemFrame.php | 4 +- src/pocketmine/tile/Spawnable.php | 16 ++-- src/pocketmine/tile/Tile.php | 12 +-- 24 files changed, 237 insertions(+), 266 deletions(-) diff --git a/composer.lock b/composer.lock index b942bb6f51..8395d5e19e 100644 --- a/composer.lock +++ b/composer.lock @@ -372,12 +372,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "cb170cf827e265cfb492de2af684cba23574dfec" + "reference": "772f627884c92beb750cc1c50a8d25f155a9c006" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/cb170cf827e265cfb492de2af684cba23574dfec", - "reference": "cb170cf827e265cfb492de2af684cba23574dfec", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/772f627884c92beb750cc1c50a8d25f155a9c006", + "reference": "772f627884c92beb750cc1c50a8d25f155a9c006", "shasum": "" }, "require": { @@ -405,7 +405,7 @@ "source": "https://github.com/pmmp/NBT/tree/master", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2019-03-16T12:12:20+00:00" + "time": "2019-03-18T14:38:07+00:00" }, { "name": "pocketmine/raklib", diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 11f320a4ab..ea3cee7cc3 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1826,10 +1826,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, //TODO: old code had a TODO for SpawnForced }elseif($spawnReset){ - $namedtag->setTag(new ListTag("Pos", [ - new DoubleTag("", $spawn->x), - new DoubleTag("", $spawn->y), - new DoubleTag("", $spawn->z) + $namedtag->setTag("Pos", new ListTag([ + new DoubleTag($spawn->x), + new DoubleTag($spawn->y), + new DoubleTag($spawn->z) ])); } @@ -1882,9 +1882,9 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->achievements = []; $achievements = $nbt->getCompoundTag("Achievements"); if($achievements !== null){ - /** @var ByteTag $achievement */ - foreach($achievements as $achievement){ - $this->achievements[$achievement->getName()] = $achievement->getValue() !== 0; + /** @var ByteTag $tag */ + foreach($achievements as $name => $tag){ + $this->achievements[$name] = $tag->getValue() !== 0; } } @@ -2897,19 +2897,19 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if(!$this->isAlive()){ //hack for respawn after quit - $nbt->setTag(new ListTag("Pos", [ - new DoubleTag("", $this->spawnPosition->x), - new DoubleTag("", $this->spawnPosition->y), - new DoubleTag("", $this->spawnPosition->z) + $nbt->setTag("Pos", new ListTag([ + new DoubleTag($this->spawnPosition->x), + new DoubleTag($this->spawnPosition->y), + new DoubleTag($this->spawnPosition->z) ])); } } - $achievements = new CompoundTag("Achievements"); + $achievements = new CompoundTag(); foreach($this->achievements as $achievement => $status){ $achievements->setByte($achievement, $status ? 1 : 0); } - $nbt->setTag($achievements); + $nbt->setTag("Achievements", $achievements); $nbt->setInt("playerGameType", $this->gamemode); $nbt->setLong("firstPlayed", $this->firstPlayed); diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index d5ea787e11..b2978f9ca7 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -61,6 +61,7 @@ use pocketmine\metadata\PlayerMetadataStore; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\TreeRoot; use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\CompressBatchTask; @@ -645,7 +646,7 @@ class Server{ if(file_exists($path . "$name.dat")){ try{ - return (new BigEndianNbtSerializer())->readCompressed(file_get_contents($path . "$name.dat")); + return (new BigEndianNbtSerializer())->readCompressed(file_get_contents($path . "$name.dat"))->getTag(); }catch(NbtDataException $e){ //zlib decode error / corrupt data rename($path . "$name.dat", $path . "$name.dat.bak"); $this->logger->error($this->getLanguage()->translateString("pocketmine.data.playerCorrupted", [$name])); @@ -667,7 +668,7 @@ class Server{ if(!$ev->isCancelled()){ $nbt = new BigEndianNbtSerializer(); try{ - file_put_contents($this->getDataPath() . "players/" . strtolower($name) . ".dat", $nbt->writeCompressed($ev->getSaveData())); + file_put_contents($this->getDataPath() . "players/" . strtolower($name) . ".dat", $nbt->writeCompressed(new TreeRoot($ev->getSaveData()))); }catch(\ErrorException $e){ $this->logger->critical($this->getLanguage()->translateString("pocketmine.data.saveError", [$name, $e->getMessage()])); $this->logger->logException($e); diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 7e62b59fd4..a191cf47e0 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -715,7 +715,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } public function saveNBT() : CompoundTag{ - $nbt = new CompoundTag(""); + $nbt = new CompoundTag(); if(!($this instanceof Player)){ $nbt->setString("id", EntityFactory::getSaveId(get_class($this))); @@ -725,21 +725,21 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } } - $nbt->setTag(new ListTag("Pos", [ - new DoubleTag("", $this->x), - new DoubleTag("", $this->y), - new DoubleTag("", $this->z) + $nbt->setTag("Pos", new ListTag([ + new DoubleTag($this->x), + new DoubleTag($this->y), + new DoubleTag($this->z) ])); - $nbt->setTag(new ListTag("Motion", [ - new DoubleTag("", $this->motion->x), - new DoubleTag("", $this->motion->y), - new DoubleTag("", $this->motion->z) + $nbt->setTag("Motion", new ListTag([ + new DoubleTag($this->motion->x), + new DoubleTag($this->motion->y), + new DoubleTag($this->motion->z) ])); - $nbt->setTag(new ListTag("Rotation", [ - new FloatTag("", $this->yaw), - new FloatTag("", $this->pitch) + $nbt->setTag("Rotation", new ListTag([ + new FloatTag($this->yaw), + new FloatTag($this->pitch) ])); $nbt->setFloat("FallDistance", $this->fallDistance); diff --git a/src/pocketmine/entity/EntityFactory.php b/src/pocketmine/entity/EntityFactory.php index 75bd41e19d..2b31913743 100644 --- a/src/pocketmine/entity/EntityFactory.php +++ b/src/pocketmine/entity/EntityFactory.php @@ -246,21 +246,20 @@ final class EntityFactory{ * @return CompoundTag */ public static function createBaseNBT(Vector3 $pos, ?Vector3 $motion = null, float $yaw = 0.0, float $pitch = 0.0) : CompoundTag{ - return new CompoundTag("", [ - new ListTag("Pos", [ - new DoubleTag("", $pos->x), - new DoubleTag("", $pos->y), - new DoubleTag("", $pos->z) - ]), - new ListTag("Motion", [ - new DoubleTag("", $motion ? $motion->x : 0.0), - new DoubleTag("", $motion ? $motion->y : 0.0), - new DoubleTag("", $motion ? $motion->z : 0.0) - ]), - new ListTag("Rotation", [ - new FloatTag("", $yaw), - new FloatTag("", $pitch) - ]) - ]); + return CompoundTag::create() + ->setTag("Pos", new ListTag([ + new DoubleTag($pos->x), + new DoubleTag($pos->y), + new DoubleTag($pos->z) + ])) + ->setTag("Motion", new ListTag([ + new DoubleTag($motion ? $motion->x : 0.0), + new DoubleTag($motion ? $motion->y : 0.0), + new DoubleTag($motion ? $motion->z : 0.0) + ])) + ->setTag("Rotation", new ListTag([ + new FloatTag($yaw), + new FloatTag($pitch) + ])); } } diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 9c21083d89..9748fd0dea 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -800,8 +800,8 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $nbt->setInt("XpTotal", $this->totalXp); $nbt->setInt("XpSeed", $this->xpSeed); - $inventoryTag = new ListTag("Inventory", [], NBT::TAG_Compound); - $nbt->setTag($inventoryTag); + $inventoryTag = new ListTag([], NBT::TAG_Compound); + $nbt->setTag("Inventory", $inventoryTag); if($this->inventory !== null){ //Normal inventory $slotCount = $this->inventory->getSize() + $this->inventory->getHotbarSize(); @@ -835,17 +835,17 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ } } - $nbt->setTag(new ListTag("EnderChestInventory", $items, NBT::TAG_Compound)); + $nbt->setTag("EnderChestInventory", new ListTag($items, NBT::TAG_Compound)); } if($this->skin !== null){ - $nbt->setTag(new CompoundTag("Skin", [ - new StringTag("Name", $this->skin->getSkinId()), - new ByteArrayTag("Data", $this->skin->getSkinData()), - new ByteArrayTag("CapeData", $this->skin->getCapeData()), - new StringTag("GeometryName", $this->skin->getGeometryName()), - new ByteArrayTag("GeometryData", $this->skin->getGeometryData()) - ])); + $nbt->setTag("Skin", CompoundTag::create() + ->setString("Name", $this->skin->getSkinId()) + ->setByteArray("Data", $this->skin->getSkinData()) + ->setByteArray("CapeData", $this->skin->getCapeData()) + ->setString("GeometryName", $this->skin->getGeometryName()) + ->setByteArray("GeometryData", $this->skin->getGeometryData()) + ); } return $nbt; diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 7b18eb7ae1..0f41ed1468 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -42,10 +42,8 @@ use pocketmine\item\enchantment\Enchantment; use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\math\VoxelRayTrace; -use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\FloatTag; -use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; @@ -178,16 +176,15 @@ abstract class Living extends Entity implements Damageable{ if(count($this->effects) > 0){ $effects = []; foreach($this->effects as $effect){ - $effects[] = new CompoundTag("", [ - new ByteTag("Id", $effect->getId()), - new ByteTag("Amplifier", Binary::signByte($effect->getAmplifier())), - new IntTag("Duration", $effect->getDuration()), - new ByteTag("Ambient", $effect->isAmbient() ? 1 : 0), - new ByteTag("ShowParticles", $effect->isVisible() ? 1 : 0) - ]); + $effects[] = CompoundTag::create() + ->setByte("Id", $effect->getId()) + ->setByte("Amplifier", Binary::signByte($effect->getAmplifier())) + ->setInt("Duration", $effect->getDuration()) + ->setByte("Ambient", $effect->isAmbient() ? 1 : 0) + ->setByte("ShowParticles", $effect->isVisible() ? 1 : 0); } - $nbt->setTag(new ListTag("ActiveEffects", $effects)); + $nbt->setTag("ActiveEffects", new ListTag($effects)); } return $nbt; diff --git a/src/pocketmine/entity/object/ItemEntity.php b/src/pocketmine/entity/object/ItemEntity.php index 415b6a1968..74baf8e488 100644 --- a/src/pocketmine/entity/object/ItemEntity.php +++ b/src/pocketmine/entity/object/ItemEntity.php @@ -134,7 +134,7 @@ class ItemEntity extends Entity{ public function saveNBT() : CompoundTag{ $nbt = parent::saveNBT(); - $nbt->setTag($this->item->nbtSerialize(-1, "Item")); + $nbt->setTag("Item", $this->item->nbtSerialize()); $nbt->setShort("Health", (int) $this->getHealth()); if($this->despawnDelay === self::NEVER_DESPAWN){ $age = -32768; diff --git a/src/pocketmine/item/Banner.php b/src/pocketmine/item/Banner.php index 7db0be7130..469e0f3b2b 100644 --- a/src/pocketmine/item/Banner.php +++ b/src/pocketmine/item/Banner.php @@ -29,9 +29,7 @@ use pocketmine\block\BlockFactory; use pocketmine\block\utils\BannerPattern; use pocketmine\block\utils\DyeColor; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; -use pocketmine\nbt\tag\StringTag; use pocketmine\tile\Banner as TileBanner; class Banner extends Item{ @@ -81,15 +79,15 @@ class Banner extends Item{ * @param Deque|BannerPattern[] $patterns */ public function setPatterns(Deque $patterns) : void{ - $tag = new ListTag(self::TAG_PATTERNS); + $tag = new ListTag(); /** @var BannerPattern $pattern */ foreach($patterns as $pattern){ - $tag->push(new CompoundTag("", [ - new StringTag(self::TAG_PATTERN_NAME, $pattern->getId()), - new IntTag(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) - ])); + $tag->push(CompoundTag::create() + ->setString(self::TAG_PATTERN_NAME, $pattern->getId()) + ->setInt(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) + ); } - $this->getNamedTag()->setTag($tag); + $this->getNamedTag()->setTag(self::TAG_PATTERNS, $tag); } public function getFuelTime() : int{ diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 4b243e4155..c4efba3aee 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -36,11 +36,11 @@ use pocketmine\math\Vector3; use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\NBT; use pocketmine\nbt\NbtDataException; -use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ShortTag; use pocketmine\nbt\tag\StringTag; +use pocketmine\nbt\TreeRoot; use pocketmine\Player; use pocketmine\utils\Binary; use function array_map; @@ -199,10 +199,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return Item */ public function setCustomBlockData(CompoundTag $compound) : Item{ - $tags = clone $compound; - $tags->setName(self::TAG_BLOCK_ENTITY_TAG); - $this->getNamedTag()->setTag($tags); - + $this->getNamedTag()->setTag(self::TAG_BLOCK_ENTITY_TAG, clone $compound); return $this; } @@ -311,15 +308,15 @@ class Item implements ItemIds, \JsonSerializable{ $ench = $this->getNamedTag()->getListTag(self::TAG_ENCH); if(!($ench instanceof ListTag)){ - $ench = new ListTag(self::TAG_ENCH, [], NBT::TAG_Compound); + $ench = new ListTag([], NBT::TAG_Compound); }else{ /** @var CompoundTag $entry */ foreach($ench as $k => $entry){ if($entry->getShort("id") === $enchantment->getId()){ - $ench->set($k, new CompoundTag("", [ - new ShortTag("id", $enchantment->getId()), - new ShortTag("lvl", $enchantment->getLevel()) - ])); + $ench->set($k, CompoundTag::create() + ->setShort("id", $enchantment->getId()) + ->setShort("lvl", $enchantment->getLevel()) + ); $found = true; break; } @@ -327,13 +324,13 @@ class Item implements ItemIds, \JsonSerializable{ } if(!$found){ - $ench->push(new CompoundTag("", [ - new ShortTag("id", $enchantment->getId()), - new ShortTag("lvl", $enchantment->getLevel()) - ])); + $ench->push(CompoundTag::create() + ->setShort("id", $enchantment->getId()) + ->setShort("lvl", $enchantment->getLevel()) + ); } - $this->getNamedTag()->setTag($ench); + $this->getNamedTag()->setTag(self::TAG_ENCH, $ench); return $this; } @@ -418,12 +415,12 @@ class Item implements ItemIds, \JsonSerializable{ /** @var CompoundTag $display */ $display = $this->getNamedTag()->getCompoundTag(self::TAG_DISPLAY); - if(!($display instanceof CompoundTag)){ - $display = new CompoundTag(self::TAG_DISPLAY); + if($display === null){ + $display = new CompoundTag(); } $display->setString(self::TAG_DISPLAY_NAME, $name); - $this->getNamedTag()->setTag($display); + $this->getNamedTag()->setTag(self::TAG_DISPLAY, $display); return $this; } @@ -439,7 +436,7 @@ class Item implements ItemIds, \JsonSerializable{ if($display->getCount() === 0){ $this->getNamedTag()->removeTag(self::TAG_DISPLAY); }else{ - $this->getNamedTag()->setTag($display); + $this->getNamedTag()->setTag(self::TAG_DISPLAY, $display); } } @@ -466,14 +463,14 @@ class Item implements ItemIds, \JsonSerializable{ public function setLore(array $lines) : Item{ $display = $this->getNamedTag()->getCompoundTag(self::TAG_DISPLAY); if(!($display instanceof CompoundTag)){ - $display = new CompoundTag(self::TAG_DISPLAY, []); + $display = new CompoundTag(); } - $display->setTag(new ListTag(self::TAG_DISPLAY_LORE, array_map(function(string $str) : StringTag{ - return new StringTag("", $str); + $display->setTag(self::TAG_DISPLAY_LORE, new ListTag(array_map(function(string $str) : StringTag{ + return new StringTag($str); }, $lines), NBT::TAG_String)); - $this->getNamedTag()->setTag($display); + $this->getNamedTag()->setTag(self::TAG_DISPLAY, $display); return $this; } @@ -493,7 +490,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return CompoundTag */ public function getNamedTag() : CompoundTag{ - return $this->nbt ?? ($this->nbt = new CompoundTag("")); + return $this->nbt ?? ($this->nbt = new CompoundTag()); } /** @@ -790,7 +787,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return string */ final public function __toString() : string{ - return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->getMeta()) . ")x" . $this->count . ($this->hasNamedTag() ? " tags:" . base64_encode((new LittleEndianNbtSerializer())->write($this->nbt)) : ""); + return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->getMeta()) . ")x" . $this->count . ($this->hasNamedTag() ? " tags:" . base64_encode((new LittleEndianNbtSerializer())->write(new TreeRoot($this->nbt))) : ""); } /** @@ -812,7 +809,7 @@ class Item implements ItemIds, \JsonSerializable{ } if($this->hasNamedTag()){ - $data["nbt_b64"] = base64_encode((new LittleEndianNbtSerializer())->write($this->getNamedTag())); + $data["nbt_b64"] = base64_encode((new LittleEndianNbtSerializer())->write(new TreeRoot($this->getNamedTag()))); } return $data; @@ -839,29 +836,25 @@ class Item implements ItemIds, \JsonSerializable{ $nbt = base64_decode($data["nbt_b64"], true); } return ItemFactory::get( - (int) $data["id"], (int) ($data["damage"] ?? 0), (int) ($data["count"] ?? 1), $nbt !== "" ? (new LittleEndianNbtSerializer())->read($nbt) : null + (int) $data["id"], (int) ($data["damage"] ?? 0), (int) ($data["count"] ?? 1), $nbt !== "" ? (new LittleEndianNbtSerializer())->read($nbt)->getTag() : null ); } /** * Serializes the item to an NBT CompoundTag * - * @param int $slot optional, the inventory slot of the item - * @param string $tagName the name to assign to the CompoundTag object + * @param int $slot optional, the inventory slot of the item * * @return CompoundTag */ - public function nbtSerialize(int $slot = -1, string $tagName = "") : CompoundTag{ - $result = new CompoundTag($tagName, [ - new ShortTag("id", $this->id), - new ByteTag("Count", Binary::signByte($this->count)), - new ShortTag("Damage", $this->getMeta()) - ]); + public function nbtSerialize(int $slot = -1) : CompoundTag{ + $result = CompoundTag::create() + ->setShort("id", $this->id) + ->setByte("Count", Binary::signByte($this->count)) + ->setShort("Damage", $this->getMeta()); if($this->hasNamedTag()){ - $itemNBT = clone $this->getNamedTag(); - $itemNBT->setName("tag"); - $result->setTag($itemNBT); + $result->setTag("tag", clone $this->getNamedTag()); } if($slot !== -1){ @@ -902,11 +895,8 @@ class Item implements ItemIds, \JsonSerializable{ } $itemNBT = $tag->getCompoundTag("tag"); - if($itemNBT instanceof CompoundTag){ - /** @var CompoundTag $t */ - $t = clone $itemNBT; - $t->setName(""); - $item->setNamedTag($t); + if($itemNBT !== null){ + $item->setNamedTag(clone $itemNBT); } return $item; diff --git a/src/pocketmine/item/WritableBook.php b/src/pocketmine/item/WritableBook.php index 3040bb7bb4..cc1a311cf7 100644 --- a/src/pocketmine/item/WritableBook.php +++ b/src/pocketmine/item/WritableBook.php @@ -26,7 +26,6 @@ namespace pocketmine\item; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; -use pocketmine\nbt\tag\StringTag; class WritableBook extends Item{ @@ -91,7 +90,7 @@ class WritableBook extends Item{ $page = $pagesTag->get($pageId); $page->setString(self::TAG_PAGE_TEXT, $pageText); - $this->getNamedTag()->setTag($pagesTag); + $this->getNamedTag()->setTag(self::TAG_PAGES, $pagesTag); return $created; } @@ -110,13 +109,13 @@ class WritableBook extends Item{ $pagesTag = $this->getPagesTag(); for($current = $pagesTag->count(); $current <= $pageId; $current++){ - $pagesTag->push(new CompoundTag("", [ - new StringTag(self::TAG_PAGE_TEXT, ""), - new StringTag(self::TAG_PAGE_PHOTONAME, "") - ])); + $pagesTag->push(CompoundTag::create() + ->setString(self::TAG_PAGE_TEXT, "") + ->setString(self::TAG_PAGE_PHOTONAME, "") + ); } - $this->getNamedTag()->setTag($pagesTag); + $this->getNamedTag()->setTag(self::TAG_PAGES, $pagesTag); } /** @@ -144,12 +143,12 @@ class WritableBook extends Item{ public function insertPage(int $pageId, string $pageText = "") : bool{ $pagesTag = $this->getPagesTag(); - $pagesTag->insert($pageId, new CompoundTag("", [ - new StringTag(self::TAG_PAGE_TEXT, $pageText), - new StringTag(self::TAG_PAGE_PHOTONAME, "") - ])); + $pagesTag->insert($pageId, CompoundTag::create() + ->setString(self::TAG_PAGE_TEXT, $pageText) + ->setString(self::TAG_PAGE_PHOTONAME, "") + ); - $this->getNamedTag()->setTag($pagesTag); + $this->getNamedTag()->setTag(self::TAG_PAGES, $pagesTag); return true; } @@ -194,7 +193,7 @@ class WritableBook extends Item{ } protected function getPagesTag() : ListTag{ - return $this->getNamedTag()->getListTag(self::TAG_PAGES) ?? new ListTag(self::TAG_PAGES, [], NBT::TAG_Compound); + return $this->getNamedTag()->getListTag(self::TAG_PAGES) ?? new ListTag([], NBT::TAG_Compound); } /** @@ -203,7 +202,7 @@ class WritableBook extends Item{ */ public function setPages(array $pages) : void{ $nbt = $this->getNamedTag(); - $nbt->setTag(new ListTag(self::TAG_PAGES, $pages, NBT::TAG_Compound)); + $nbt->setTag(self::TAG_PAGES, new ListTag($pages, NBT::TAG_Compound)); $this->setNamedTag($nbt); } } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 468741093f..150dd15dc6 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1630,22 +1630,21 @@ class Level implements ChunkManager, Metadatable{ * @return ItemEntity|null */ public function dropItem(Vector3 $source, Item $item, ?Vector3 $motion = null, int $delay = 10) : ?ItemEntity{ - $motion = $motion ?? new Vector3(lcg_value() * 0.2 - 0.1, 0.2, lcg_value() * 0.2 - 0.1); - $itemTag = $item->nbtSerialize(); - $itemTag->setName("Item"); - - if(!$item->isNull()){ - $nbt = EntityFactory::createBaseNBT($source, $motion, lcg_value() * 360, 0); - $nbt->setShort("Health", 5); - $nbt->setShort("PickupDelay", $delay); - $nbt->setTag($itemTag); - - /** @var ItemEntity $itemEntity */ - $itemEntity = EntityFactory::create(ItemEntity::class, $this, $nbt); - $itemEntity->spawnToAll(); - return $itemEntity; + if($item->isNull()){ + return null; } - return null; + + $motion = $motion ?? new Vector3(lcg_value() * 0.2 - 0.1, 0.2, lcg_value() * 0.2 - 0.1); + $nbt = EntityFactory::createBaseNBT($source, $motion, lcg_value() * 360, 0); + $nbt->setShort("Health", 5); + $nbt->setShort("PickupDelay", $delay); + $nbt->setTag("Item", $item->nbtSerialize()); + + /** @var ItemEntity $itemEntity */ + $itemEntity = EntityFactory::create(ItemEntity::class, $this, $nbt); + $itemEntity->spawnToAll(); + return $itemEntity; + } /** diff --git a/src/pocketmine/level/format/io/data/BedrockLevelData.php b/src/pocketmine/level/format/io/data/BedrockLevelData.php index d70b34309b..7f793b9395 100644 --- a/src/pocketmine/level/format/io/data/BedrockLevelData.php +++ b/src/pocketmine/level/format/io/data/BedrockLevelData.php @@ -29,12 +29,10 @@ use pocketmine\level\generator\Generator; use pocketmine\level\generator\GeneratorManager; use pocketmine\level\Level; use pocketmine\nbt\LittleEndianNbtSerializer; -use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\IntTag; -use pocketmine\nbt\tag\LongTag; use pocketmine\nbt\tag\StringTag; +use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\utils\Binary; use pocketmine\utils\Utils; @@ -63,51 +61,50 @@ class BedrockLevelData extends BaseNbtLevelData{ //TODO: add support for limited worlds } - $levelData = new CompoundTag("", [ + $levelData = CompoundTag::create() //Vanilla fields - new IntTag("DayCycleStopTime", -1), - new IntTag("Difficulty", Level::getDifficultyFromString((string) ($options["difficulty"] ?? "normal"))), - new ByteTag("ForceGameType", 0), - new IntTag("GameType", 0), - new IntTag("Generator", $generatorType), - new LongTag("LastPlayed", time()), - new StringTag("LevelName", $name), - new IntTag("NetworkVersion", ProtocolInfo::CURRENT_PROTOCOL), - //new IntTag("Platform", 2), //TODO: find out what the possible values are for - new LongTag("RandomSeed", $seed), - new IntTag("SpawnX", 0), - new IntTag("SpawnY", 32767), - new IntTag("SpawnZ", 0), - new IntTag("StorageVersion", self::CURRENT_STORAGE_VERSION), - new LongTag("Time", 0), - new ByteTag("eduLevel", 0), - new ByteTag("falldamage", 1), - new ByteTag("firedamage", 1), - new ByteTag("hasBeenLoadedInCreative", 1), //badly named, this actually determines whether achievements can be earned in this world... - new ByteTag("immutableWorld", 0), - new FloatTag("lightningLevel", 0.0), - new IntTag("lightningTime", 0), - new ByteTag("pvp", 1), - new FloatTag("rainLevel", 0.0), - new IntTag("rainTime", 0), - new ByteTag("spawnMobs", 1), - new ByteTag("texturePacksRequired", 0), //TODO + ->setInt("DayCycleStopTime", -1) + ->setInt("Difficulty", Level::getDifficultyFromString((string) ($options["difficulty"] ?? "normal"))) + ->setByte("ForceGameType", 0) + ->setInt("GameType", 0) + ->setInt("Generator", $generatorType) + ->setLong("LastPlayed", time()) + ->setString("LevelName", $name) + ->setInt("NetworkVersion", ProtocolInfo::CURRENT_PROTOCOL) + //->setInt("Platform", 2) //TODO: find out what the possible values are for + ->setLong("RandomSeed", $seed) + ->setInt("SpawnX", 0) + ->setInt("SpawnY", 32767) + ->setInt("SpawnZ", 0) + ->setInt("StorageVersion", self::CURRENT_STORAGE_VERSION) + ->setLong("Time", 0) + ->setByte("eduLevel", 0) + ->setByte("falldamage", 1) + ->setByte("firedamage", 1) + ->setByte("hasBeenLoadedInCreative", 1) //badly named, this actually determines whether achievements can be earned in this world... + ->setByte("immutableWorld", 0) + ->setFloat("lightningLevel", 0.0) + ->setInt("lightningTime", 0) + ->setByte("pvp", 1) + ->setFloat("rainLevel", 0.0) + ->setInt("rainTime", 0) + ->setByte("spawnMobs", 1) + ->setByte("texturePacksRequired", 0) //TODO //Additional PocketMine-MP fields - new CompoundTag("GameRules", []), - new ByteTag("hardcore", ($options["hardcore"] ?? false) === true ? 1 : 0), - new StringTag("generatorName", GeneratorManager::getGeneratorName($generator)), - new StringTag("generatorOptions", $options["preset"] ?? "") - ]); + ->setTag("GameRules", new CompoundTag()) + ->setByte("hardcore", ($options["hardcore"] ?? false) === true ? 1 : 0) + ->setString("generatorName", GeneratorManager::getGeneratorName($generator)) + ->setString("generatorOptions", $options["preset"] ?? ""); $nbt = new LittleEndianNbtSerializer(); - $buffer = $nbt->write($levelData); + $buffer = $nbt->write(new TreeRoot($levelData)); file_put_contents($path . "level.dat", Binary::writeLInt(self::CURRENT_STORAGE_VERSION) . Binary::writeLInt(strlen($buffer)) . $buffer); } protected function load() : ?CompoundTag{ $nbt = new LittleEndianNbtSerializer(); - $levelData = $nbt->read(substr(file_get_contents($this->dataPath), 8)); + $levelData = $nbt->read(substr(file_get_contents($this->dataPath), 8))->getTag(); $version = $levelData->getInt("StorageVersion", INT32_MAX, true); if($version > self::CURRENT_STORAGE_VERSION){ @@ -152,7 +149,7 @@ class BedrockLevelData extends BaseNbtLevelData{ $this->compoundTag->setInt("StorageVersion", self::CURRENT_STORAGE_VERSION); $nbt = new LittleEndianNbtSerializer(); - $buffer = $nbt->write($this->compoundTag); + $buffer = $nbt->write(new TreeRoot($this->compoundTag)); file_put_contents($this->dataPath, Binary::writeLInt(self::CURRENT_STORAGE_VERSION) . Binary::writeLInt(strlen($buffer)) . $buffer); } diff --git a/src/pocketmine/level/format/io/data/JavaLevelData.php b/src/pocketmine/level/format/io/data/JavaLevelData.php index ac1aa39f23..c360b1dec7 100644 --- a/src/pocketmine/level/format/io/data/JavaLevelData.php +++ b/src/pocketmine/level/format/io/data/JavaLevelData.php @@ -27,12 +27,10 @@ use pocketmine\level\generator\Generator; use pocketmine\level\generator\GeneratorManager; use pocketmine\level\Level; use pocketmine\nbt\BigEndianNbtSerializer; -use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\FloatTag; -use pocketmine\nbt\tag\IntTag; -use pocketmine\nbt\tag\LongTag; use pocketmine\nbt\tag\StringTag; +use pocketmine\nbt\TreeRoot; use pocketmine\utils\Utils; use function ceil; use function file_get_contents; @@ -44,36 +42,34 @@ class JavaLevelData extends BaseNbtLevelData{ public static function generate(string $path, string $name, int $seed, string $generator, array $options = [], int $version = 19133) : void{ Utils::testValidInstance($generator, Generator::class); //TODO, add extra details - $levelData = new CompoundTag("Data", [ - new ByteTag("hardcore", ($options["hardcore"] ?? false) === true ? 1 : 0), - new ByteTag("Difficulty", Level::getDifficultyFromString((string) ($options["difficulty"] ?? "normal"))), - new ByteTag("initialized", 1), - new IntTag("GameType", 0), - new IntTag("generatorVersion", 1), //2 in MCPE - new IntTag("SpawnX", 256), - new IntTag("SpawnY", 70), - new IntTag("SpawnZ", 256), - new IntTag("version", $version), - new IntTag("DayTime", 0), - new LongTag("LastPlayed", (int) (microtime(true) * 1000)), - new LongTag("RandomSeed", $seed), - new LongTag("SizeOnDisk", 0), - new LongTag("Time", 0), - new StringTag("generatorName", GeneratorManager::getGeneratorName($generator)), - new StringTag("generatorOptions", $options["preset"] ?? ""), - new StringTag("LevelName", $name), - new CompoundTag("GameRules", []) - ]); + $levelData = CompoundTag::create() + ->setByte("hardcore", ($options["hardcore"] ?? false) === true ? 1 : 0) + ->setByte("Difficulty", Level::getDifficultyFromString((string) ($options["difficulty"] ?? "normal"))) + ->setByte("initialized", 1) + ->setInt("GameType", 0) + ->setInt("generatorVersion", 1) //2 in MCPE + ->setInt("SpawnX", 256) + ->setInt("SpawnY", 70) + ->setInt("SpawnZ", 256) + ->setInt("version", $version) + ->setInt("DayTime", 0) + ->setLong("LastPlayed", (int) (microtime(true) * 1000)) + ->setLong("RandomSeed", $seed) + ->setLong("SizeOnDisk", 0) + ->setLong("Time", 0) + ->setString("generatorName", GeneratorManager::getGeneratorName($generator)) + ->setString("generatorOptions", $options["preset"] ?? "") + ->setString("LevelName", $name) + ->setTag("GameRules", new CompoundTag()); + $nbt = new BigEndianNbtSerializer(); - $buffer = $nbt->writeCompressed(new CompoundTag("", [ - $levelData - ])); + $buffer = $nbt->writeCompressed(new TreeRoot(CompoundTag::create()->setTag("Data", $levelData))); file_put_contents($path . "level.dat", $buffer); } protected function load() : ?CompoundTag{ $nbt = new BigEndianNbtSerializer(); - $levelData = $nbt->readCompressed(file_get_contents($this->dataPath)); + $levelData = $nbt->readCompressed(file_get_contents($this->dataPath))->getTag(); if($levelData->hasTag("Data", CompoundTag::class)){ return $levelData->getCompoundTag("Data"); } @@ -94,10 +90,7 @@ class JavaLevelData extends BaseNbtLevelData{ public function save() : void{ $nbt = new BigEndianNbtSerializer(); - $this->compoundTag->setName("Data"); - $buffer = $nbt->writeCompressed(new CompoundTag("", [ - $this->compoundTag - ])); + $buffer = $nbt->writeCompressed(new TreeRoot(CompoundTag::create()->setTag("Data", $this->compoundTag))); file_put_contents($this->dataPath, $buffer); } diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index 195271cbd7..ecf9ad567e 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -40,14 +40,13 @@ use pocketmine\level\generator\Generator; use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\IntTag; -use pocketmine\nbt\tag\ShortTag; -use pocketmine\nbt\tag\StringTag; +use pocketmine\nbt\TreeRoot; use pocketmine\utils\Binary; use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; use pocketmine\utils\Utils; use function array_flip; +use function array_map; use function array_values; use function chr; use function count; @@ -159,7 +158,7 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ $palette = []; for($i = 0, $paletteSize = $stream->getLInt(); $i < $paletteSize; ++$i){ $offset = $stream->getOffset(); - $tag = $nbt->read($stream->getBuffer(), $offset); + $tag = $nbt->read($stream->getBuffer(), $offset)->getTag(); $stream->setOffset($offset); $id = $stringToLegacyId[$tag->getString("name")] ?? BlockIds::INFO_UPDATE; @@ -303,7 +302,7 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ $entities = []; if(($entityData = $this->db->get($index . self::TAG_ENTITY)) !== false and $entityData !== ""){ try{ - $entities = $nbt->readMultiple($entityData); + $entities = array_map(function(TreeRoot $root) : CompoundTag{ return $root->getTag(); }, $nbt->readMultiple($entityData)); }catch(NbtDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } @@ -313,7 +312,7 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ $tiles = []; if(($tileData = $this->db->get($index . self::TAG_BLOCK_ENTITY)) !== false and $tileData !== ""){ try{ - $tiles = $nbt->readMultiple($tileData); + $tiles = array_map(function(TreeRoot $root) : CompoundTag{ return $root->getTag(); }, $nbt->readMultiple($tileData)); }catch(NbtDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } @@ -379,11 +378,10 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ $subStream->putLInt(count($palette)); $tags = []; foreach($palette as $p){ - $tags[] = new CompoundTag("", [ - new StringTag("name", $idMap[$p >> 4] ?? "minecraft:info_update"), - new IntTag("oldid", $p >> 4), //PM only (debugging), vanilla doesn't have this - new ShortTag("val", $p & 0xf) - ]); + $tags[] = new TreeRoot(CompoundTag::create() + ->setString("name", $idMap[$p >> 4] ?? "minecraft:info_update") + ->setInt("oldid", $p >> 4) //PM only (debugging), vanilla doesn't have this + ->setShort("val", $p & 0xf)); } $subStream->put((new LittleEndianNbtSerializer())->writeMultiple($tags)); @@ -415,7 +413,7 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ private function writeTags(array $targets, string $index, \LevelDBWriteBatch $write) : void{ if(!empty($targets)){ $nbt = new LittleEndianNbtSerializer(); - $write->put($index, $nbt->writeMultiple($targets)); + $write->put($index, $nbt->writeMultiple(array_map(function(CompoundTag $tag) : TreeRoot{ return new TreeRoot($tag); }, $targets))); }else{ $write->delete($index); } diff --git a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php b/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php index a60c914e30..978c8a69a1 100644 --- a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php @@ -59,7 +59,7 @@ trait LegacyAnvilChunkTrait{ protected function deserializeChunk(string $data) : Chunk{ $nbt = new BigEndianNbtSerializer(); try{ - $chunk = $nbt->readCompressed($data); + $chunk = $nbt->readCompressed($data)->getTag(); }catch(NbtDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index c4a81aa14c..56146df0a8 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -56,7 +56,7 @@ class McRegion extends RegionLevelProvider{ protected function deserializeChunk(string $data) : Chunk{ $nbt = new BigEndianNbtSerializer(); try{ - $chunk = $nbt->readCompressed($data); + $chunk = $nbt->readCompressed($data)->getTag(); }catch(NbtDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } diff --git a/src/pocketmine/network/mcpe/NetworkBinaryStream.php b/src/pocketmine/network/mcpe/NetworkBinaryStream.php index 54c918524b..aceb3c60c2 100644 --- a/src/pocketmine/network/mcpe/NetworkBinaryStream.php +++ b/src/pocketmine/network/mcpe/NetworkBinaryStream.php @@ -31,6 +31,8 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\ItemIds; use pocketmine\math\Vector3; +use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\TreeRoot; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\types\CommandOriginData; use pocketmine\network\mcpe\protocol\types\EntityLink; @@ -96,13 +98,14 @@ class NetworkBinaryStream extends BinaryStream{ $cnt = $auxValue & 0xff; $nbtLen = $this->getLShort(); + /** @var CompoundTag|null $compound */ $compound = null; if($nbtLen === 0xffff){ $c = $this->getByte(); if($c !== 1){ throw new BadPacketException("Unexpected NBT count $c"); } - $compound = (new NetworkNbtSerializer())->read($this->buffer, $this->offset); + $compound = (new NetworkNbtSerializer())->read($this->buffer, $this->offset)->getTag(); }elseif($nbtLen !== 0){ throw new BadPacketException("Unexpected fake NBT length $nbtLen"); } @@ -143,7 +146,7 @@ class NetworkBinaryStream extends BinaryStream{ if($item->hasNamedTag()){ $this->putLShort(0xffff); $this->putByte(1); //TODO: some kind of count field? always 1 as of 1.9.0 - $this->put((new NetworkNbtSerializer())->write($item->getNamedTag())); + $this->put((new NetworkNbtSerializer())->write(new TreeRoot($item->getNamedTag()))); }else{ $this->putLShort(0); } diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index bb09244ad8..c329737f65 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -398,7 +398,7 @@ class SimpleSessionHandler extends SessionHandler{ $block = $this->player->getLevel()->getBlock($pos); try{ - $nbt = (new NetworkNbtSerializer())->read($packet->namedtag); + $nbt = (new NetworkNbtSerializer())->read($packet->namedtag)->getTag(); }catch(NbtDataException $e){ throw new BadPacketException($e->getMessage(), 0, $e); } diff --git a/src/pocketmine/tile/Banner.php b/src/pocketmine/tile/Banner.php index 839c6ca729..6da72e874c 100644 --- a/src/pocketmine/tile/Banner.php +++ b/src/pocketmine/tile/Banner.php @@ -31,7 +31,6 @@ use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; -use pocketmine\nbt\tag\StringTag; /** * @deprecated @@ -72,26 +71,26 @@ class Banner extends Spawnable{ protected function writeSaveData(CompoundTag $nbt) : void{ $nbt->setInt(self::TAG_BASE, $this->baseColor->getInvertedMagicNumber()); - $patterns = new ListTag(self::TAG_PATTERNS); + $patterns = new ListTag(); foreach($this->patterns as $pattern){ - $patterns->push(new CompoundTag("", [ - new StringTag(self::TAG_PATTERN_NAME, $pattern->getId()), - new IntTag(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) - ])); + $patterns->push(CompoundTag::create() + ->setString(self::TAG_PATTERN_NAME, $pattern->getId()) + ->setInt(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) + ); } - $nbt->setTag($patterns); + $nbt->setTag(self::TAG_PATTERNS, $patterns); } protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ $nbt->setInt(self::TAG_BASE, $this->baseColor->getInvertedMagicNumber()); - $patterns = new ListTag(self::TAG_PATTERNS); + $patterns = new ListTag(); foreach($this->patterns as $pattern){ - $patterns->push(new CompoundTag("", [ - new StringTag(self::TAG_PATTERN_NAME, $pattern->getId()), - new IntTag(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) - ])); + $patterns->push(CompoundTag::create() + ->setString(self::TAG_PATTERN_NAME, $pattern->getId()) + ->setInt(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) + ); } - $nbt->setTag($patterns); + $nbt->setTag(self::TAG_PATTERNS, $patterns); } /** diff --git a/src/pocketmine/tile/ContainerTrait.php b/src/pocketmine/tile/ContainerTrait.php index b09bfb42cf..efacc7bd22 100644 --- a/src/pocketmine/tile/ContainerTrait.php +++ b/src/pocketmine/tile/ContainerTrait.php @@ -69,7 +69,7 @@ trait ContainerTrait{ $items[] = $item->nbtSerialize($slot); } - $tag->setTag(new ListTag(Container::TAG_ITEMS, $items, NBT::TAG_Compound)); + $tag->setTag(Container::TAG_ITEMS, new ListTag($items, NBT::TAG_Compound)); if($this->lock !== null){ $tag->setString(Container::TAG_LOCK, $this->lock); diff --git a/src/pocketmine/tile/ItemFrame.php b/src/pocketmine/tile/ItemFrame.php index 9d041e6e87..0841f540cc 100644 --- a/src/pocketmine/tile/ItemFrame.php +++ b/src/pocketmine/tile/ItemFrame.php @@ -61,7 +61,7 @@ class ItemFrame extends Spawnable{ protected function writeSaveData(CompoundTag $nbt) : void{ $nbt->setFloat(self::TAG_ITEM_DROP_CHANCE, $this->itemDropChance); $nbt->setByte(self::TAG_ITEM_ROTATION, $this->itemRotation); - $nbt->setTag($this->item->nbtSerialize(-1, self::TAG_ITEM)); + $nbt->setTag(self::TAG_ITEM, $this->item->nbtSerialize()); } public function hasItem() : bool{ @@ -102,6 +102,6 @@ class ItemFrame extends Spawnable{ protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ $nbt->setFloat(self::TAG_ITEM_DROP_CHANCE, $this->itemDropChance); $nbt->setByte(self::TAG_ITEM_ROTATION, $this->itemRotation); - $nbt->setTag($this->item->nbtSerialize(-1, self::TAG_ITEM)); + $nbt->setTag(self::TAG_ITEM, $this->item->nbtSerialize()); } } diff --git a/src/pocketmine/tile/Spawnable.php b/src/pocketmine/tile/Spawnable.php index 0d707bce20..0eaac54613 100644 --- a/src/pocketmine/tile/Spawnable.php +++ b/src/pocketmine/tile/Spawnable.php @@ -24,8 +24,7 @@ declare(strict_types=1); namespace pocketmine\tile; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\IntTag; -use pocketmine\nbt\tag\StringTag; +use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\NetworkNbtSerializer; use function get_class; @@ -76,7 +75,7 @@ abstract class Spawnable extends Tile{ self::$nbtWriter = new NetworkNbtSerializer(); } - $this->spawnCompoundCache = self::$nbtWriter->write($this->getSpawnCompound()); + $this->spawnCompoundCache = self::$nbtWriter->write(new TreeRoot($this->getSpawnCompound())); } return $this->spawnCompoundCache; @@ -86,12 +85,11 @@ abstract class Spawnable extends Tile{ * @return CompoundTag */ final public function getSpawnCompound() : CompoundTag{ - $nbt = new CompoundTag("", [ - new StringTag(self::TAG_ID, TileFactory::getSaveId(get_class($this))), //TODO: disassociate network ID from save ID - new IntTag(self::TAG_X, $this->x), - new IntTag(self::TAG_Y, $this->y), - new IntTag(self::TAG_Z, $this->z) - ]); + $nbt = CompoundTag::create() + ->setString(self::TAG_ID, TileFactory::getSaveId(get_class($this))) //TODO: disassociate network ID from save ID + ->setInt(self::TAG_X, $this->x) + ->setInt(self::TAG_Y, $this->y) + ->setInt(self::TAG_Z, $this->z); $this->addAdditionalSpawnData($nbt); return $nbt; } diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/tile/Tile.php index 4cadd2b517..c0caea1512 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/tile/Tile.php @@ -72,18 +72,18 @@ abstract class Tile extends Position{ abstract protected function writeSaveData(CompoundTag $nbt) : void; public function saveNBT() : CompoundTag{ - $nbt = new CompoundTag(""); - $nbt->setString(self::TAG_ID, TileFactory::getSaveId(get_class($this))); - $nbt->setInt(self::TAG_X, $this->x); - $nbt->setInt(self::TAG_Y, $this->y); - $nbt->setInt(self::TAG_Z, $this->z); + $nbt = CompoundTag::create() + ->setString(self::TAG_ID, TileFactory::getSaveId(get_class($this))) + ->setInt(self::TAG_X, $this->x) + ->setInt(self::TAG_Y, $this->y) + ->setInt(self::TAG_Z, $this->z); $this->writeSaveData($nbt); return $nbt; } public function getCleanedNBT() : ?CompoundTag{ - $this->writeSaveData($tag = new CompoundTag("")); + $this->writeSaveData($tag = new CompoundTag()); return $tag->getCount() > 0 ? $tag : null; } From 588ebe446fd03c9ff0f622f7e7c589c55ba09365 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Mar 2019 18:47:24 +0000 Subject: [PATCH 0649/3224] Fixed Chunk->setFullBlock() not creating new subchunks, closes #2821 --- src/pocketmine/level/format/Chunk.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index 68a3103c2f..e707eb2ad6 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -197,7 +197,7 @@ class Chunk{ * @param int $block */ public function setFullBlock(int $x, int $y, int $z, int $block) : void{ - $this->getSubChunk($y >> 4)->setFullBlock($x, $y & 0xf, $z, $block); + $this->getSubChunk($y >> 4, true)->setFullBlock($x, $y & 0xf, $z, $block); $this->hasChanged = true; } From 89c08360477d8b07db844de24e8e4573b5550b57 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Mar 2019 19:46:43 +0000 Subject: [PATCH 0650/3224] Fixed paintings dropping multiple times, closes #2774 --- src/pocketmine/Player.php | 15 ++++++--------- src/pocketmine/entity/Entity.php | 15 ++++++++++++--- src/pocketmine/entity/Living.php | 8 ++------ src/pocketmine/entity/object/Painting.php | 4 ++-- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index ea3cee7cc3..c336b9075d 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2918,17 +2918,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->server->saveOfflinePlayerData($this->username, $nbt); } - public function kill() : void{ - if(!$this->spawned){ + protected function onDeath() : void{ + if(!$this->spawned){ //TODO: drop this hack return; } - - parent::kill(); - - $this->networkSession->onDeath(); - } - - protected function onDeath() : void{ //Crafting grid must always be evacuated even if keep-inventory is true. This dumps the contents into the //main inventory and drops the rest on the ground. $this->doCloseInventory(); @@ -2957,6 +2950,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($ev->getDeathMessage() != ""){ $this->server->broadcastMessage($ev->getDeathMessage()); } + + $this->startDeathAnimation(); + + $this->networkSession->onDeath(); } protected function onDeathUpdate(int $tickDiff) : bool{ diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index a191cf47e0..4d42567172 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -806,8 +806,18 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } public function kill() : void{ - $this->health = 0; - $this->scheduleUpdate(); + if($this->isAlive()){ + $this->health = 0; + $this->onDeath(); + $this->scheduleUpdate(); + } + } + + /** + * Override this to do actions on death. + */ + protected function onDeath() : void{ + } /** @@ -844,7 +854,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ if($amount <= 0){ if($this->isAlive()){ - $this->health = 0; $this->kill(); } }elseif($amount <= $this->getMaxHealth() or $amount < $this->health){ diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 0f41ed1468..d87e7df72f 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -640,12 +640,6 @@ abstract class Living extends Entity implements Damageable{ } } - public function kill() : void{ - parent::kill(); - $this->onDeath(); - $this->startDeathAnimation(); - } - protected function onDeath() : void{ $ev = new EntityDeathEvent($this, $this->getDrops()); $ev->call(); @@ -656,6 +650,8 @@ abstract class Living extends Entity implements Damageable{ //TODO: check death conditions (must have been damaged by player < 5 seconds from death) //TODO: allow this number to be manipulated during EntityDeathEvent $this->level->dropExperience($this, $this->getXpDropAmount()); + + $this->startDeathAnimation(); } protected function onDeathUpdate(int $tickDiff) : bool{ diff --git a/src/pocketmine/entity/object/Painting.php b/src/pocketmine/entity/object/Painting.php index 2cfadd4046..0f8b39f956 100644 --- a/src/pocketmine/entity/object/Painting.php +++ b/src/pocketmine/entity/object/Painting.php @@ -93,8 +93,8 @@ class Painting extends Entity{ return $nbt; } - public function kill() : void{ - parent::kill(); + protected function onDeath() : void{ + parent::onDeath(); $drops = true; From b8d1eb20b054618be8631e4f97eac904659c5aa8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Mar 2019 19:53:14 +0000 Subject: [PATCH 0651/3224] EntityDeathEvent: add XP amount API, closes #2690 --- src/pocketmine/Player.php | 5 ++-- src/pocketmine/entity/Living.php | 5 ++-- .../event/entity/EntityDeathEvent.php | 26 ++++++++++++++++++- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index c336b9075d..63fedcbb8a 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2926,7 +2926,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, //main inventory and drops the rest on the ground. $this->doCloseInventory(); - $ev = new PlayerDeathEvent($this, $this->getDrops()); + $ev = new PlayerDeathEvent($this, $this->getDrops(), $this->getXpDropAmount()); $ev->call(); if(!$ev->getKeepInventory()){ @@ -2943,8 +2943,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } - //TODO: allow this number to be manipulated during PlayerDeathEvent - $this->level->dropExperience($this, $this->getXpDropAmount()); + $this->level->dropExperience($this, $ev->getXpDropAmount()); $this->setXpAndProgress(0, 0); if($ev->getDeathMessage() != ""){ diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index d87e7df72f..23350e3a48 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -641,15 +641,14 @@ abstract class Living extends Entity implements Damageable{ } protected function onDeath() : void{ - $ev = new EntityDeathEvent($this, $this->getDrops()); + $ev = new EntityDeathEvent($this, $this->getDrops(), $this->getXpDropAmount()); $ev->call(); foreach($ev->getDrops() as $item){ $this->getLevel()->dropItem($this, $item); } //TODO: check death conditions (must have been damaged by player < 5 seconds from death) - //TODO: allow this number to be manipulated during EntityDeathEvent - $this->level->dropExperience($this, $this->getXpDropAmount()); + $this->level->dropExperience($this, $ev->getXpDropAmount()); $this->startDeathAnimation(); } diff --git a/src/pocketmine/event/entity/EntityDeathEvent.php b/src/pocketmine/event/entity/EntityDeathEvent.php index c4ca6111dc..aeb7e55744 100644 --- a/src/pocketmine/event/entity/EntityDeathEvent.php +++ b/src/pocketmine/event/entity/EntityDeathEvent.php @@ -29,14 +29,18 @@ use pocketmine\item\Item; class EntityDeathEvent extends EntityEvent{ /** @var Item[] */ private $drops = []; + /** @var int */ + private $xp; /** * @param Living $entity * @param Item[] $drops + * @param int $xp */ - public function __construct(Living $entity, array $drops = []){ + public function __construct(Living $entity, array $drops = [], int $xp = 0){ $this->entity = $entity; $this->drops = $drops; + $this->xp = $xp; } /** @@ -59,4 +63,24 @@ class EntityDeathEvent extends EntityEvent{ public function setDrops(array $drops) : void{ $this->drops = $drops; } + + /** + * Returns how much experience is dropped due to this entity's death. + * @return int + */ + public function getXpDropAmount() : int{ + return $this->xp; + } + + /** + * @param int $xp + * + * @throws \InvalidArgumentException + */ + public function setXpDropAmount(int $xp) : void{ + if($xp < 0){ + throw new \InvalidArgumentException("XP drop amount must not be negative"); + } + $this->xp = $xp; + } } From 3dbed830eff53e7e78efbb58c342567eab003f82 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Mar 2019 20:03:10 +0000 Subject: [PATCH 0652/3224] Fixed entities not loading on imported MCPE worlds --- src/pocketmine/entity/EntityFactory.php | 3 +++ src/pocketmine/level/format/Chunk.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/entity/EntityFactory.php b/src/pocketmine/entity/EntityFactory.php index 2b31913743..f2e1251ab7 100644 --- a/src/pocketmine/entity/EntityFactory.php +++ b/src/pocketmine/entity/EntityFactory.php @@ -207,6 +207,9 @@ final class EntityFactory{ */ public static function createFromData(Level $level, CompoundTag $nbt) : ?Entity{ $saveId = $nbt->getTag("id"); + if($saveId === null){ + $saveId = $nbt->getTag("identifier"); //new MCPE format + } $baseClass = null; if($saveId instanceof StringTag){ $baseClass = self::$knownEntities[$saveId->getValue()] ?? null; diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index e707eb2ad6..adb968eb57 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -586,7 +586,7 @@ class Chunk{ try{ $entity = EntityFactory::createFromData($level, $nbt); if(!($entity instanceof Entity)){ - $level->getServer()->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown entity type " . $nbt->getString("id", "", true)); + $level->getServer()->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown entity type " . $nbt->getString("id", $nbt->getString("identifier", "", true), true)); $changed = true; continue; } From 6ec2a694172a09a70ce51d1df374fca63a257ae7 Mon Sep 17 00:00:00 2001 From: SOFe Date: Fri, 22 Mar 2019 12:51:22 +0800 Subject: [PATCH 0653/3224] Removed .docker/Dockerfile 1. The current Dockerfile is not directly related to the project, but just our very complex highly-coupled full-of-hacks build/release/deploy system. 2. We are no longer using Docker Hub Builder. An internal Dockerfile will be used on our Jenkins server instead, using the correct upstream phar build to prevent race conditions. --- .docker/Dockerfile | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) delete mode 100644 .docker/Dockerfile diff --git a/.docker/Dockerfile b/.docker/Dockerfile deleted file mode 100644 index 19b07ba1ef..0000000000 --- a/.docker/Dockerfile +++ /dev/null @@ -1,46 +0,0 @@ -FROM ubuntu:bionic -MAINTAINER PMMP Team - -EXPOSE 19132/tcp -EXPOSE 19132/udp - -RUN apt-get update && apt-get --no-install-recommends -y install \ - sudo \ - ca-certificates \ - jq \ - curl \ - unzip - -RUN groupadd -g 1000 pocketmine && useradd -r -d /pocketmine -p "" -u 1000 -m -g pocketmine -g sudo pocketmine - -WORKDIR /pocketmine -RUN chown -R pocketmine:1000 . - -USER pocketmine -ARG WAIT_JENKINS -ENV WAIT_JENKINS ${WAIT_JENKINS:-wait} -RUN if [ "$WAIT_JENKINS" = "wait" ]; then echo Sleeping for 5 minutes to wait for Jenkins build && sleep 300; fi - -RUN mkdir tmp -RUN curl https://update.pmmp.io/api > tmp/api.json - -RUN jq -r '.php_version' < tmp/api.json > tmp/PHP_VERSION -RUN curl -SsL \ - https://jenkins.pmmp.io/job/PHP-`cat tmp/PHP_VERSION`-Aggregate/lastSuccessfulBuild/artifact/PHP-`cat tmp/PHP_VERSION`-Linux-x86_64.tar.gz | \ - tar zx >/dev/null 2>&1 - -RUN chmod +x bin/php7/bin/php - -RUN sed -i'.bak' "s/date.timezone=.*/date.timezone=$(date +%Z)/" bin/php7/bin/php.ini - -RUN curl -SsLo PocketMine-MP.phar `jq -r '.download_url' < tmp/api.json` - -RUN curl -SsLO https://raw.githubusercontent.com/pmmp/PocketMine-MP/`jq -r '.branch' < tmp/api.json`/start.sh -RUN chmod +x start.sh - -RUN rm -r tmp - -# RUN sudo mkdir /data /plugins -VOLUME ["/data", "/plugins"] -# CMD ./start.sh --no-wizard --enable-ansi --data=/data --plugins=/plugins -CMD bash -c 'sudo chown 1000 /data /plugins -R && ./start.sh --no-wizard --enable-ansi --data=/data --plugins=/plugins' From d03f0aab37974f16c0e1dbf3e63e68436e93e380 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Fri, 22 Mar 2019 15:01:11 +0000 Subject: [PATCH 0654/3224] Remove /reload (#2823) For many years, this has been the cause of many users (particularly plugin devs) confusion. The reality is that /reload has little to no practical value. It does not reload plugin source code (contrary to popular belief). --- src/pocketmine/Server.php | 37 ------------- src/pocketmine/command/SimpleCommandMap.php | 2 - .../command/defaults/ReloadCommand.php | 54 ------------------- 3 files changed, 93 deletions(-) delete mode 100644 src/pocketmine/command/defaults/ReloadCommand.php diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index b2978f9ca7..aa22dc602c 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1570,43 +1570,6 @@ class Server{ return false; } - public function reload() : void{ - $this->logger->info("Saving worlds..."); - - foreach($this->levelManager->getLevels() as $level){ - $level->save(); - } - - $this->pluginManager->disablePlugins(); - $this->pluginManager->clearPlugins(); - PermissionManager::getInstance()->clearPermissions(); - $this->commandMap->clearCommands(); - - $this->logger->info("Reloading properties..."); - $this->properties->reload(); - $this->maxPlayers = $this->getConfigInt("max-players", 20); - - if($this->getConfigBool("hardcore", false) and $this->getDifficulty() < Level::DIFFICULTY_HARD){ - $this->setConfigInt("difficulty", Level::DIFFICULTY_HARD); - } - - $this->banByIP->load(); - $this->banByName->load(); - $this->reloadWhitelist(); - $this->operators->reload(); - - foreach($this->getIPBans()->getEntries() as $entry){ - $this->getNetwork()->blockAddress($entry->getName(), -1); - } - - $this->pluginManager->registerInterface(new PharPluginLoader($this->autoloader)); - $this->pluginManager->registerInterface(new ScriptPluginLoader()); - $this->pluginManager->loadPlugins($this->pluginPath); - $this->enablePlugins(PluginLoadOrder::STARTUP); - $this->enablePlugins(PluginLoadOrder::POSTWORLD); - TimingsHandler::reload(); - } - /** * Shuts the server down correctly */ diff --git a/src/pocketmine/command/SimpleCommandMap.php b/src/pocketmine/command/SimpleCommandMap.php index 6b3419e8d1..97d3226fde 100644 --- a/src/pocketmine/command/SimpleCommandMap.php +++ b/src/pocketmine/command/SimpleCommandMap.php @@ -45,7 +45,6 @@ use pocketmine\command\defaults\PardonCommand; use pocketmine\command\defaults\PardonIpCommand; use pocketmine\command\defaults\ParticleCommand; use pocketmine\command\defaults\PluginsCommand; -use pocketmine\command\defaults\ReloadCommand; use pocketmine\command\defaults\SaveCommand; use pocketmine\command\defaults\SaveOffCommand; use pocketmine\command\defaults\SaveOnCommand; @@ -116,7 +115,6 @@ class SimpleCommandMap implements CommandMap{ new PardonIpCommand("pardon-ip"), new ParticleCommand("particle"), new PluginsCommand("plugins"), - new ReloadCommand("reload"), new SaveCommand("save-all"), new SaveOffCommand("save-off"), new SaveOnCommand("save-on"), diff --git a/src/pocketmine/command/defaults/ReloadCommand.php b/src/pocketmine/command/defaults/ReloadCommand.php deleted file mode 100644 index 33e498ac8f..0000000000 --- a/src/pocketmine/command/defaults/ReloadCommand.php +++ /dev/null @@ -1,54 +0,0 @@ -setPermission("pocketmine.command.reload"); - } - - public function execute(CommandSender $sender, string $commandLabel, array $args){ - if(!$this->testPermission($sender)){ - return true; - } - - Command::broadcastCommandMessage($sender, new TranslationContainer(TextFormat::YELLOW . "%pocketmine.command.reload.reloading")); - - $sender->getServer()->reload(); - Command::broadcastCommandMessage($sender, new TranslationContainer(TextFormat::YELLOW . "%pocketmine.command.reload.reloaded")); - - return true; - } -} From 9b11e39efc4a8300092de9696ea09acdc0238c6b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 22 Mar 2019 13:42:06 +0000 Subject: [PATCH 0655/3224] use ?? --- src/pocketmine/entity/EntityFactory.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/pocketmine/entity/EntityFactory.php b/src/pocketmine/entity/EntityFactory.php index f2e1251ab7..deca79678c 100644 --- a/src/pocketmine/entity/EntityFactory.php +++ b/src/pocketmine/entity/EntityFactory.php @@ -206,10 +206,7 @@ final class EntityFactory{ * @throws \RuntimeException */ public static function createFromData(Level $level, CompoundTag $nbt) : ?Entity{ - $saveId = $nbt->getTag("id"); - if($saveId === null){ - $saveId = $nbt->getTag("identifier"); //new MCPE format - } + $saveId = $nbt->getTag("id") ?? $nbt->getTag("identifier"); $baseClass = null; if($saveId instanceof StringTag){ $baseClass = self::$knownEntities[$saveId->getValue()] ?? null; From f84a1729c620b6bc5b97afb422d1f2d7039d1ca9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 22 Mar 2019 18:11:32 +0000 Subject: [PATCH 0656/3224] Inventory: added swap() function --- src/pocketmine/inventory/BaseInventory.php | 7 +++++++ src/pocketmine/inventory/Inventory.php | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index e87105e43a..5a96002da1 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -349,6 +349,13 @@ abstract class BaseInventory implements Inventory{ } } + public function swap(int $slot1, int $slot2) : void{ + $i1 = $this->getItem($slot1); + $i2 = $this->getItem($slot2); + $this->setItem($slot1, $i2); + $this->setItem($slot2, $i1); + } + /** * @return Player[] */ diff --git a/src/pocketmine/inventory/Inventory.php b/src/pocketmine/inventory/Inventory.php index edbdfc46ac..c0fba1d2be 100644 --- a/src/pocketmine/inventory/Inventory.php +++ b/src/pocketmine/inventory/Inventory.php @@ -194,6 +194,14 @@ interface Inventory{ */ public function clearAll(bool $send = true) : void; + /** + * Swaps the specified slots. + * + * @param int $slot1 + * @param int $slot2 + */ + public function swap(int $slot1, int $slot2) : void; + /** * Gets all the Players viewing the inventory * Players will view their inventory at all times, even when not open. From 60225a378f76196b5e598db3f7b880efd49a4ea0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 22 Mar 2019 18:28:36 +0000 Subject: [PATCH 0657/3224] Player: fixed block-picking logic this now matches vanilla (with some minor intentional differences) and works in survival. --- src/pocketmine/Player.php | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 63fedcbb8a..b6ecf35e90 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2130,14 +2130,28 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $ev = new PlayerBlockPickEvent($this, $block, $item); - if(!$this->isCreative(true)){ - $this->server->getLogger()->debug("Got block-pick request from " . $this->getName() . " when not in creative mode (gamemode " . $this->getGamemode() . ")"); - $ev->setCancelled(); - } - $ev->call(); + if(!$ev->isCancelled()){ - $this->inventory->setItemInHand($item); + $existing = $this->inventory->first($item); + if($existing !== -1){ + if($existing < $this->inventory->getHotbarSize()){ + $this->inventory->setHeldItemIndex($existing); + }else{ + $this->inventory->swap($this->inventory->getHeldItemIndex(), $existing); + } + }elseif($this->isCreative(true)){ //TODO: plugins won't know this isn't going to execute + $firstEmpty = $this->inventory->firstEmpty(); + if($firstEmpty === -1){ //full inventory + $this->inventory->setItemInHand($item); + }elseif($firstEmpty < $this->inventory->getHotbarSize()){ + $this->inventory->setItem($firstEmpty, $item); + $this->inventory->setHeldItemIndex($firstEmpty); + }else{ + $this->inventory->swap($this->inventory->getHeldItemIndex(), $firstEmpty); + $this->inventory->setItemInHand($item); + } + } } return true; From 9904810f2410e5ef13df734c9a53a7a95ca4615d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 22 Mar 2019 19:21:41 +0000 Subject: [PATCH 0658/3224] BaseInventory: Remove getDefaultSize() it's possible to want to initialize dynamically-sized inventories which don't have a default size. --- src/pocketmine/inventory/AnvilInventory.php | 6 +----- src/pocketmine/inventory/ArmorInventory.php | 6 +----- src/pocketmine/inventory/BaseInventory.php | 8 +++----- src/pocketmine/inventory/ChestInventory.php | 6 +----- src/pocketmine/inventory/ContainerInventory.php | 4 ++-- src/pocketmine/inventory/CraftingGrid.php | 6 +----- src/pocketmine/inventory/DoubleChestInventory.php | 6 +----- src/pocketmine/inventory/EnchantInventory.php | 6 +----- src/pocketmine/inventory/EnderChestInventory.php | 6 +----- src/pocketmine/inventory/FurnaceInventory.php | 6 +----- src/pocketmine/inventory/PlayerCursorInventory.php | 6 +----- src/pocketmine/inventory/PlayerInventory.php | 6 +----- tests/phpunit/inventory/BaseInventoryTest.php | 9 ++------- 13 files changed, 17 insertions(+), 64 deletions(-) diff --git a/src/pocketmine/inventory/AnvilInventory.php b/src/pocketmine/inventory/AnvilInventory.php index 37490a1057..f22b56674c 100644 --- a/src/pocketmine/inventory/AnvilInventory.php +++ b/src/pocketmine/inventory/AnvilInventory.php @@ -33,17 +33,13 @@ class AnvilInventory extends ContainerInventory{ protected $holder; public function __construct(Position $pos){ - parent::__construct($pos->asPosition()); + parent::__construct($pos->asPosition(), 2); } public function getNetworkType() : int{ return WindowTypes::ANVIL; } - public function getDefaultSize() : int{ - return 2; //1 input, 1 material - } - /** * This override is here for documentation and code completion purposes only. * @return Position diff --git a/src/pocketmine/inventory/ArmorInventory.php b/src/pocketmine/inventory/ArmorInventory.php index ac51541291..39700c51d4 100644 --- a/src/pocketmine/inventory/ArmorInventory.php +++ b/src/pocketmine/inventory/ArmorInventory.php @@ -43,17 +43,13 @@ class ArmorInventory extends BaseInventory{ public function __construct(Living $holder){ $this->holder = $holder; - parent::__construct(); + parent::__construct(4); } public function getHolder() : Living{ return $this->holder; } - public function getDefaultSize() : int{ - return 4; - } - public function getHelmet() : Item{ return $this->getItem(self::SLOT_HEAD); } diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index 5a96002da1..73e0798753 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -49,11 +49,11 @@ abstract class BaseInventory implements Inventory{ protected $slotChangeListener; /** - * @param Item[] $items * @param int $size + * @param Item[] $items */ - public function __construct(array $items = [], ?int $size = null){ - $this->slots = new \SplFixedArray($size ?? $this->getDefaultSize()); + public function __construct(int $size, array $items = []){ + $this->slots = new \SplFixedArray($size); $this->setContents($items, false); } @@ -76,8 +76,6 @@ abstract class BaseInventory implements Inventory{ $this->slots->setSize($size); } - abstract public function getDefaultSize() : int; - public function getMaxStackSize() : int{ return $this->maxStackSize; } diff --git a/src/pocketmine/inventory/ChestInventory.php b/src/pocketmine/inventory/ChestInventory.php index cbf63df122..dc4fa69f44 100644 --- a/src/pocketmine/inventory/ChestInventory.php +++ b/src/pocketmine/inventory/ChestInventory.php @@ -39,17 +39,13 @@ class ChestInventory extends ContainerInventory{ * @param Chest $tile */ public function __construct(Chest $tile){ - parent::__construct($tile); + parent::__construct($tile, 27); } public function getNetworkType() : int{ return WindowTypes::CONTAINER; } - public function getDefaultSize() : int{ - return 27; - } - /** * This override is here for documentation and code completion purposes only. * @return Chest diff --git a/src/pocketmine/inventory/ContainerInventory.php b/src/pocketmine/inventory/ContainerInventory.php index 4a808ca576..8a41a73a4a 100644 --- a/src/pocketmine/inventory/ContainerInventory.php +++ b/src/pocketmine/inventory/ContainerInventory.php @@ -33,9 +33,9 @@ abstract class ContainerInventory extends BaseInventory{ /** @var Vector3 */ protected $holder; - public function __construct(Vector3 $holder, array $items = [], ?int $size = null){ + public function __construct(Vector3 $holder, int $size, array $items = []){ $this->holder = $holder; - parent::__construct($items, $size); + parent::__construct($size, $items); } protected function onOpen(Player $who) : void{ diff --git a/src/pocketmine/inventory/CraftingGrid.php b/src/pocketmine/inventory/CraftingGrid.php index 3da867cd5e..b15ac65b09 100644 --- a/src/pocketmine/inventory/CraftingGrid.php +++ b/src/pocketmine/inventory/CraftingGrid.php @@ -50,17 +50,13 @@ class CraftingGrid extends BaseInventory{ public function __construct(Player $holder, int $gridWidth){ $this->holder = $holder; $this->gridWidth = $gridWidth; - parent::__construct(); + parent::__construct($this->getGridWidth() ** 2); } public function getGridWidth() : int{ return $this->gridWidth; } - public function getDefaultSize() : int{ - return $this->getGridWidth() ** 2; - } - public function setSize(int $size) : void{ throw new \BadMethodCallException("Cannot change the size of a crafting grid"); } diff --git a/src/pocketmine/inventory/DoubleChestInventory.php b/src/pocketmine/inventory/DoubleChestInventory.php index 06b4395513..51a46e8c44 100644 --- a/src/pocketmine/inventory/DoubleChestInventory.php +++ b/src/pocketmine/inventory/DoubleChestInventory.php @@ -40,11 +40,7 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ $this->left = $left->getRealInventory(); $this->right = $right->getRealInventory(); $items = array_merge($this->left->getContents(true), $this->right->getContents(true)); - BaseInventory::__construct($items); - } - - public function getDefaultSize() : int{ - return $this->left->getDefaultSize() + $this->right->getDefaultSize(); + BaseInventory::__construct($this->left->getSize() + $this->right->getSize(), $items); } public function getInventory(){ diff --git a/src/pocketmine/inventory/EnchantInventory.php b/src/pocketmine/inventory/EnchantInventory.php index 80709f5c99..4d3a6b97fa 100644 --- a/src/pocketmine/inventory/EnchantInventory.php +++ b/src/pocketmine/inventory/EnchantInventory.php @@ -33,17 +33,13 @@ class EnchantInventory extends ContainerInventory{ protected $holder; public function __construct(Position $pos){ - parent::__construct($pos->asPosition()); + parent::__construct($pos->asPosition(), 2); } public function getNetworkType() : int{ return WindowTypes::ENCHANTMENT; } - public function getDefaultSize() : int{ - return 2; //1 input, 1 lapis - } - /** * This override is here for documentation and code completion purposes only. * @return Position diff --git a/src/pocketmine/inventory/EnderChestInventory.php b/src/pocketmine/inventory/EnderChestInventory.php index d7605d837c..a0fdfe24cf 100644 --- a/src/pocketmine/inventory/EnderChestInventory.php +++ b/src/pocketmine/inventory/EnderChestInventory.php @@ -34,17 +34,13 @@ class EnderChestInventory extends ChestInventory{ protected $holder; public function __construct(){ - ContainerInventory::__construct(new Position()); + ContainerInventory::__construct(new Position(), 27); } public function getNetworkType() : int{ return WindowTypes::CONTAINER; } - public function getDefaultSize() : int{ - return 27; - } - /** * Set the holder's position to that of a tile * diff --git a/src/pocketmine/inventory/FurnaceInventory.php b/src/pocketmine/inventory/FurnaceInventory.php index 1418adb47a..79a400c066 100644 --- a/src/pocketmine/inventory/FurnaceInventory.php +++ b/src/pocketmine/inventory/FurnaceInventory.php @@ -32,17 +32,13 @@ class FurnaceInventory extends ContainerInventory{ protected $holder; public function __construct(Furnace $tile){ - parent::__construct($tile); + parent::__construct($tile, 3); } public function getNetworkType() : int{ return WindowTypes::FURNACE; } - public function getDefaultSize() : int{ - return 3; //1 input, 1 fuel, 1 output - } - /** * This override is here for documentation and code completion purposes only. * @return Furnace diff --git a/src/pocketmine/inventory/PlayerCursorInventory.php b/src/pocketmine/inventory/PlayerCursorInventory.php index 4ad1a4050f..e760493f2f 100644 --- a/src/pocketmine/inventory/PlayerCursorInventory.php +++ b/src/pocketmine/inventory/PlayerCursorInventory.php @@ -31,11 +31,7 @@ class PlayerCursorInventory extends BaseInventory{ public function __construct(Player $holder){ $this->holder = $holder; - parent::__construct(); - } - - public function getDefaultSize() : int{ - return 1; + parent::__construct(1); } public function setSize(int $size) : void{ diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index ff355fad3b..df0fedcc21 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -45,11 +45,7 @@ class PlayerInventory extends BaseInventory{ */ public function __construct(Human $player){ $this->holder = $player; - parent::__construct(); - } - - public function getDefaultSize() : int{ - return 36; + parent::__construct(36); } public function isHotbarSlot(int $slot) : bool{ diff --git a/tests/phpunit/inventory/BaseInventoryTest.php b/tests/phpunit/inventory/BaseInventoryTest.php index ade55f317b..a00bbc1b13 100644 --- a/tests/phpunit/inventory/BaseInventoryTest.php +++ b/tests/phpunit/inventory/BaseInventoryTest.php @@ -34,13 +34,8 @@ class BaseInventoryTest extends TestCase{ } public function testAddItemDifferentUserData() : void{ - $inv = new class extends BaseInventory{ - public function getDefaultSize() : int{ - return 1; - } - public function getName() : string{ - return ""; - } + $inv = new class(1) extends BaseInventory{ + }; $item1 = ItemFactory::get(Item::ARROW, 0, 1); $item2 = ItemFactory::get(Item::ARROW, 0, 1)->setCustomName("TEST"); From 712e077bc15656af976ab16e64f268c730ab8be8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 22 Mar 2019 19:31:10 +0000 Subject: [PATCH 0659/3224] Server: remove useless debug message leveldb is now mandatory, so this message will always be emitted. --- src/pocketmine/Server.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index aa22dc602c..ade1b690cd 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -109,7 +109,6 @@ use function bin2hex; use function count; use function define; use function explode; -use function extension_loaded; use function file_exists; use function file_get_contents; use function file_put_contents; @@ -1242,9 +1241,6 @@ class Server{ }elseif($formatName !== ""){ $this->logger->warning($this->language->translateString("pocketmine.level.badDefaultFormat", [$formatName])); } - if(extension_loaded("leveldb")){ - $this->logger->debug($this->getLanguage()->translateString("pocketmine.debug.enable")); - } $this->levelManager = new LevelManager($this); From afbd0166114a9196fba36e8063a130975321f6d0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 22 Mar 2019 19:38:33 +0000 Subject: [PATCH 0660/3224] Server: remove useless function --- src/pocketmine/Server.php | 69 ++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 38 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index ade1b690cd..435cd41ced 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1311,7 +1311,37 @@ class Server{ $this->enablePlugins(PluginLoadOrder::POSTWORLD); - $this->start(); + if($this->getConfigBool("enable-query", true)){ + $this->queryHandler = new QueryHandler(); + } + + foreach($this->getIPBans()->getEntries() as $entry){ + $this->network->blockAddress($entry->getName(), -1); + } + + if($this->getProperty("settings.send-usage", true)){ + $this->sendUsageTicker = 6000; + $this->sendUsage(SendUsageTask::TYPE_OPEN); + } + + + if($this->getProperty("network.upnp-forwarding", false)){ + $this->logger->info("[UPnP] Trying to port forward..."); + try{ + UPnP::PortForward($this->getPort()); + }catch(\RuntimeException $e){ + $this->logger->alert("UPnP portforward failed: " . $e->getMessage()); + } + } + + $this->tickCounter = 0; + + $this->logger->info($this->getLanguage()->translateString("pocketmine.server.defaultGameMode", [GameMode::toTranslation($this->getGamemode())])); + + $this->logger->info($this->getLanguage()->translateString("pocketmine.server.startFinished", [round(microtime(true) - \pocketmine\START_TIME, 3)])); + + $this->tickProcessor(); + $this->forceShutdown(); }catch(\Throwable $e){ $this->exceptionHandler($e); } @@ -1653,43 +1683,6 @@ class Server{ return $this->queryRegenerateTask; } - /** - * Starts the PocketMine-MP server and starts processing ticks and packets - */ - private function start() : void{ - if($this->getConfigBool("enable-query", true)){ - $this->queryHandler = new QueryHandler(); - } - - foreach($this->getIPBans()->getEntries() as $entry){ - $this->network->blockAddress($entry->getName(), -1); - } - - if($this->getProperty("settings.send-usage", true)){ - $this->sendUsageTicker = 6000; - $this->sendUsage(SendUsageTask::TYPE_OPEN); - } - - - if($this->getProperty("network.upnp-forwarding", false)){ - $this->logger->info("[UPnP] Trying to port forward..."); - try{ - UPnP::PortForward($this->getPort()); - }catch(\RuntimeException $e){ - $this->logger->alert("UPnP portforward failed: " . $e->getMessage()); - } - } - - $this->tickCounter = 0; - - $this->logger->info($this->getLanguage()->translateString("pocketmine.server.defaultGameMode", [GameMode::toTranslation($this->getGamemode())])); - - $this->logger->info($this->getLanguage()->translateString("pocketmine.server.startFinished", [round(microtime(true) - \pocketmine\START_TIME, 3)])); - - $this->tickProcessor(); - $this->forceShutdown(); - } - /** * @param \Throwable $e * @param array|null $trace From 433dab078bf85946237700fb5f2bb88cb93c0535 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 09:52:03 +0000 Subject: [PATCH 0661/3224] DataPacket events now use network sessions instead of players --- src/pocketmine/Server.php | 29 ++++++++++--------- .../event/server/DataPacketBroadcastEvent.php | 24 +++++++-------- .../event/server/DataPacketReceiveEvent.php | 18 ++++++------ .../event/server/DataPacketSendEvent.php | 18 ++++++------ .../network/mcpe/NetworkSession.php | 4 +-- 5 files changed, 47 insertions(+), 46 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 435cd41ced..46a2c1bcf2 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1479,22 +1479,23 @@ class Server{ throw new \InvalidArgumentException("Cannot broadcast empty list of packets"); } - $ev = new DataPacketBroadcastEvent($players, $packets); + /** @var NetworkSession[] $recipients */ + $recipients = []; + foreach($players as $player){ + if($player->isConnected()){ + $recipients[] = $player->getNetworkSession(); + } + } + if(empty($recipients)){ + return false; + } + + $ev = new DataPacketBroadcastEvent($recipients, $packets); $ev->call(); if($ev->isCancelled()){ return false; } - - /** @var NetworkSession[] $targets */ - $targets = []; - foreach($ev->getPlayers() as $player){ - if($player->isConnected()){ - $targets[] = $player->getNetworkSession(); - } - } - if(empty($targets)){ - return false; - } + $recipients = $ev->getTargets(); $stream = new PacketStream(); foreach($ev->getPackets() as $packet){ @@ -1502,14 +1503,14 @@ class Server{ } if(NetworkCompression::$THRESHOLD < 0 or strlen($stream->getBuffer()) < NetworkCompression::$THRESHOLD){ - foreach($targets as $target){ + foreach($recipients as $target){ foreach($ev->getPackets() as $pk){ $target->addToSendBuffer($pk); } } }else{ $promise = $this->prepareBatch($stream); - foreach($targets as $target){ + foreach($recipients as $target){ $target->queueCompressed($promise); } } diff --git a/src/pocketmine/event/server/DataPacketBroadcastEvent.php b/src/pocketmine/event/server/DataPacketBroadcastEvent.php index d42d6ea3f9..46bb4ea57c 100644 --- a/src/pocketmine/event/server/DataPacketBroadcastEvent.php +++ b/src/pocketmine/event/server/DataPacketBroadcastEvent.php @@ -25,8 +25,8 @@ namespace pocketmine\event\server; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; +use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\ClientboundPacket; -use pocketmine\Player; /** * Called when a list of packets is broadcasted to 1 or more players. @@ -34,32 +34,32 @@ use pocketmine\Player; class DataPacketBroadcastEvent extends ServerEvent implements Cancellable{ use CancellableTrait; - /** @var Player[] */ - private $players; + /** @var NetworkSession[] */ + private $targets; /** @var ClientboundPacket[] */ private $packets; /** - * @param Player[] $players + * @param NetworkSession[] $targets * @param ClientboundPacket[] $packets */ - public function __construct(array $players, array $packets){ - $this->players = $players; + public function __construct(array $targets, array $packets){ + $this->targets = $targets; $this->packets = $packets; } /** - * @return Player[] + * @return NetworkSession[] */ - public function getPlayers() : array{ - return $this->players; + public function getTargets() : array{ + return $this->targets; } /** - * @param Player[] $players + * @param NetworkSession[] $targets */ - public function setPlayers(array $players) : void{ - $this->players = $players; + public function setTargets(array $targets) : void{ + $this->targets = $targets; } /** diff --git a/src/pocketmine/event/server/DataPacketReceiveEvent.php b/src/pocketmine/event/server/DataPacketReceiveEvent.php index 946cd7ee90..7b25a28c7f 100644 --- a/src/pocketmine/event/server/DataPacketReceiveEvent.php +++ b/src/pocketmine/event/server/DataPacketReceiveEvent.php @@ -25,24 +25,24 @@ namespace pocketmine\event\server; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; +use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\ServerboundPacket; -use pocketmine\Player; class DataPacketReceiveEvent extends ServerEvent implements Cancellable{ use CancellableTrait; /** @var ServerboundPacket */ private $packet; - /** @var Player */ - private $player; + /** @var NetworkSession */ + private $origin; /** - * @param Player $player + * @param NetworkSession $origin * @param ServerboundPacket $packet */ - public function __construct(Player $player, ServerboundPacket $packet){ + public function __construct(NetworkSession $origin, ServerboundPacket $packet){ $this->packet = $packet; - $this->player = $player; + $this->origin = $origin; } /** @@ -53,9 +53,9 @@ class DataPacketReceiveEvent extends ServerEvent implements Cancellable{ } /** - * @return Player + * @return NetworkSession */ - public function getPlayer() : Player{ - return $this->player; + public function getOrigin() : NetworkSession{ + return $this->origin; } } diff --git a/src/pocketmine/event/server/DataPacketSendEvent.php b/src/pocketmine/event/server/DataPacketSendEvent.php index c14b16037e..6de229482c 100644 --- a/src/pocketmine/event/server/DataPacketSendEvent.php +++ b/src/pocketmine/event/server/DataPacketSendEvent.php @@ -25,24 +25,24 @@ namespace pocketmine\event\server; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; +use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\ClientboundPacket; -use pocketmine\Player; class DataPacketSendEvent extends ServerEvent implements Cancellable{ use CancellableTrait; /** @var ClientboundPacket */ private $packet; - /** @var Player */ - private $player; + /** @var NetworkSession */ + private $target; /** - * @param Player $player + * @param NetworkSession $target * @param ClientboundPacket $packet */ - public function __construct(Player $player, ClientboundPacket $packet){ + public function __construct(NetworkSession $target, ClientboundPacket $packet){ $this->packet = $packet; - $this->player = $player; + $this->target = $target; } /** @@ -53,9 +53,9 @@ class DataPacketSendEvent extends ServerEvent implements Cancellable{ } /** - * @return Player + * @return NetworkSession */ - public function getPlayer() : Player{ - return $this->player; + public function getTarget() : NetworkSession{ + return $this->target; } } diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 2a8f1da8fe..d23aa1f1c2 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -268,7 +268,7 @@ class NetworkSession{ $this->server->getLogger()->debug("Still " . strlen($remains) . " bytes unread in " . $packet->getName() . ": " . bin2hex($remains)); } - $ev = new DataPacketReceiveEvent($this->player, $packet); + $ev = new DataPacketReceiveEvent($this, $packet); $ev->call(); if(!$ev->isCancelled() and !$packet->handle($this->handler)){ $this->server->getLogger()->debug("Unhandled " . $packet->getName() . " received from " . $this->getDisplayName() . ": " . bin2hex($packet->getBuffer())); @@ -287,7 +287,7 @@ class NetworkSession{ $timings = Timings::getSendDataPacketTimings($packet); $timings->startTiming(); try{ - $ev = new DataPacketSendEvent($this->player, $packet); + $ev = new DataPacketSendEvent($this, $packet); $ev->call(); if($ev->isCancelled()){ return false; From 9ec62643d576faa719395f20fe1e1fcb3a3cd7a4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 10:13:14 +0000 Subject: [PATCH 0662/3224] Player construction now happens when we're ready to create the player entity this fixes a wide range of bugs with the initial spawn sequence, and allows to simplify a whole lot of player setup logic. --- src/pocketmine/Player.php | 146 ++++-------------- src/pocketmine/PlayerInfo.php | 3 +- src/pocketmine/entity/Entity.php | 5 - .../network/mcpe/NetworkSession.php | 54 +++++-- .../network/mcpe/ProcessLoginTask.php | 19 ++- .../mcpe/handler/LoginSessionHandler.php | 57 +++++-- .../handler/ResourcePacksSessionHandler.php | 13 +- 7 files changed, 137 insertions(+), 160 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index b6ecf35e90..97fac651d7 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -62,7 +62,6 @@ use pocketmine\event\player\PlayerJumpEvent; use pocketmine\event\player\PlayerKickEvent; use pocketmine\event\player\PlayerLoginEvent; use pocketmine\event\player\PlayerMoveEvent; -use pocketmine\event\player\PlayerPreLoginEvent; use pocketmine\event\player\PlayerQuitEvent; use pocketmine\event\player\PlayerRespawnEvent; use pocketmine\event\player\PlayerToggleFlightEvent; @@ -96,9 +95,7 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\CompressBatchPromise; -use pocketmine\network\mcpe\NetworkCipher; use pocketmine\network\mcpe\NetworkSession; -use pocketmine\network\mcpe\ProcessLoginTask; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; @@ -108,7 +105,6 @@ use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; -use pocketmine\network\mcpe\protocol\LoginPacket; use pocketmine\network\mcpe\protocol\MobEffectPacket; use pocketmine\network\mcpe\protocol\ModalFormRequestPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; @@ -189,9 +185,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** @var NetworkSession */ protected $networkSession; - /** @var bool */ - protected $loggedIn = false; - /** @var bool */ public $spawned = false; @@ -206,9 +199,9 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** @var string */ protected $xuid = ""; /** @var bool */ - protected $authenticated = false; - /** @var PlayerInfo|null */ - protected $playerInfo = null; + protected $authenticated; + /** @var PlayerInfo */ + protected $playerInfo; protected $windowCnt = 2; /** @var int[] */ @@ -551,7 +544,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool */ public function isOnline() : bool{ - return $this->isConnected() and $this->loggedIn; + return $this->isConnected(); } /** @@ -687,21 +680,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } - /** - * @param Server $server - * @param NetworkSession $session - */ - public function __construct(Server $server, NetworkSession $session){ - $this->server = $server; - $this->networkSession = $session; - - $this->perm = new PermissibleBase($this); - $this->chunksPerTick = (int) $this->server->getProperty("chunk-sending.per-tick", 4); - $this->spawnThreshold = (int) (($this->server->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); - - $this->allowMovementCheats = (bool) $this->server->getProperty("player.anti-cheat.allow-movement-cheats", false); - } - /** * @return bool */ @@ -1712,8 +1690,19 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return ($targetDot - $eyeDot) >= -$maxDiff; } - public function handleLogin(LoginPacket $packet) : bool{ - $this->playerInfo = $packet->playerInfo; + /** + * @param Server $server + * @param NetworkSession $session + * @param PlayerInfo $playerInfo + * @param bool $authenticated + */ + public function __construct(Server $server, NetworkSession $session, PlayerInfo $playerInfo, bool $authenticated){ + $this->server = $server; + $this->networkSession = $session; + $this->playerInfo = $playerInfo; + $this->authenticated = $authenticated; + $this->skin = $this->playerInfo->getSkin(); + $this->username = TextFormat::clean($this->playerInfo->getUsername()); $this->displayName = $this->username; $this->iusername = strtolower($this->username); @@ -1722,82 +1711,14 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->uuid = $this->playerInfo->getUuid(); $this->rawUUID = $this->uuid->toBinary(); - $this->xuid = $this->playerInfo->getXuid(); + $this->xuid = $authenticated ? $this->playerInfo->getXuid() : ""; - $this->setSkin($this->playerInfo->getSkin()); + $this->perm = new PermissibleBase($this); + $this->chunksPerTick = (int) $this->server->getProperty("chunk-sending.per-tick", 4); + $this->spawnThreshold = (int) (($this->server->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); - $ev = new PlayerPreLoginEvent( - $this->playerInfo, - $this->networkSession->getIp(), - $this->networkSession->getPort(), - $this->server->requiresAuthentication() - ); - if($this->server->getNetwork()->getConnectionCount() > $this->server->getMaxPlayers()){ - $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_SERVER_FULL, "disconnectionScreen.serverFull"); - } - if(!$this->server->isWhitelisted($this->username)){ - $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_SERVER_WHITELISTED, "Server is whitelisted"); - } - if($this->isBanned() or $this->server->getIPBans()->isBanned($this->getAddress())){ - $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_BANNED, "You are banned"); - } + $this->allowMovementCheats = (bool) $this->server->getProperty("player.anti-cheat.allow-movement-cheats", false); - $ev->call(); - if(!$ev->isAllowed()){ - $this->close("", $ev->getFinalKickMessage()); - return true; - } - - if(!$packet->skipVerification){ - $this->server->getAsyncPool()->submitTask(new ProcessLoginTask($this, $packet, $ev->isAuthRequired(), NetworkCipher::$ENABLED)); - }else{ - $this->setAuthenticationStatus(false, false, null); - $this->networkSession->onLoginSuccess(); - } - - return true; - } - - public function setAuthenticationStatus(bool $authenticated, bool $authRequired, ?string $error) : bool{ - if($this->networkSession === null){ - return false; - } - - if($authenticated and $this->xuid === ""){ - $error = "Expected XUID but none found"; - } - - if($error !== null){ - $this->close("", $this->server->getLanguage()->translateString("pocketmine.disconnect.invalidSession", [$error])); - - return false; - } - - $this->authenticated = $authenticated; - - if(!$this->authenticated){ - if($authRequired){ - $this->close("", "disconnectionScreen.notAuthenticated"); - return false; - } - - $this->server->getLogger()->debug($this->getName() . " is NOT logged into Xbox Live"); - if($this->xuid !== ""){ - $this->server->getLogger()->warning($this->getName() . " has an XUID, but their login keychain is not signed by Mojang"); - $this->xuid = ""; - } - }else{ - $this->server->getLogger()->debug($this->getName() . " is logged into Xbox Live"); - } - - return $this->server->getNetwork()->getSessionManager()->kickDuplicates($this->networkSession); - } - - public function onLoginSuccess() : void{ - $this->loggedIn = true; - } - - public function _actuallyConstruct(){ $namedtag = $this->server->getOfflinePlayerData($this->username); //TODO: make this async $spawnReset = false; @@ -1834,6 +1755,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } parent::__construct($level, $namedtag); + $ev = new PlayerLoginEvent($this, "Plugin reason"); $ev->call(); if($ev->isCancelled()){ @@ -2832,14 +2754,12 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->usedChunks = []; $this->loadQueue = []; - if($this->loggedIn){ - foreach($this->server->getOnlinePlayers() as $player){ - if(!$player->canSee($this)){ - $player->showPlayer($this); - } + foreach($this->server->getOnlinePlayers() as $player){ + if(!$player->canSee($this)){ + $player->showPlayer($this); } - $this->hiddenPlayers = []; } + $this->hiddenPlayers = []; $this->removeAllWindows(true); $this->windows = []; @@ -2847,17 +2767,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->cursorInventory = null; $this->craftingGrid = null; - if($this->constructed){ - parent::close(); - }else{ - $this->closed = true; - } + parent::close(); + $this->spawned = false; - if($this->loggedIn){ - $this->loggedIn = false; - $this->server->removeOnlinePlayer($this); - } + $this->server->removeOnlinePlayer($this); $this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logOut", [ TextFormat::AQUA . $this->getName() . TextFormat::WHITE, diff --git a/src/pocketmine/PlayerInfo.php b/src/pocketmine/PlayerInfo.php index cc54f5529d..f0363bd2f8 100644 --- a/src/pocketmine/PlayerInfo.php +++ b/src/pocketmine/PlayerInfo.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine; use pocketmine\entity\Skin; +use pocketmine\utils\TextFormat; use pocketmine\utils\UUID; /** @@ -45,7 +46,7 @@ class PlayerInfo{ private $clientId; public function __construct(string $username, UUID $uuid, Skin $skin, string $locale, string $xuid, int $clientId){ - $this->username = $username; + $this->username = TextFormat::clean($username); $this->uuid = $uuid; $this->skin = $skin; $this->locale = $locale; diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 4d42567172..b45215a349 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -378,12 +378,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ /** @var TimingsHandler */ protected $timings; - /** @var bool */ - protected $constructed = false; - - public function __construct(Level $level, CompoundTag $nbt){ - $this->constructed = true; $this->timings = Timings::getEntityTimings($this); $this->temporalVector = new Vector3(); diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index d23aa1f1c2..c53037f5c6 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -58,7 +58,7 @@ class NetworkSession{ /** @var Server */ private $server; /** @var Player|null */ - private $player; + private $player = null; /** @var NetworkSessionManager */ private $manager; /** @var NetworkInterface */ @@ -79,6 +79,8 @@ class NetworkSession{ private $connected = true; /** @var bool */ private $loggedIn = false; + /** @var bool */ + private $authenticated = false; /** @var int */ private $connectTime; @@ -102,10 +104,7 @@ class NetworkSession{ $this->connectTime = time(); - //TODO: this should happen later in the login sequence - $this->createPlayer(); - - $this->setHandler(new LoginSessionHandler($this->player, $this)); + $this->setHandler(new LoginSessionHandler($this->server, $this)); $this->manager->add($this); } @@ -119,7 +118,7 @@ class NetworkSession{ * @var Player $player * @see Player::__construct() */ - $this->player = new $class($this->server, $this); + $this->player = new $class($this->server, $this, $this->info, $this->authenticated); } public function getPlayer() : ?Player{ @@ -166,7 +165,7 @@ class NetworkSession{ } public function getDisplayName() : string{ - return ($this->player !== null and $this->player->getName() !== "") ? $this->player->getName() : $this->ip . " " . $this->port; + return $this->info !== null ? $this->info->getUsername() : $this->ip . " " . $this->port; } /** @@ -385,7 +384,9 @@ class NetworkSession{ */ public function disconnect(string $reason, bool $notify = true) : void{ if($this->checkDisconnect()){ - $this->player->close($this->player->getLeaveMessage(), $reason); + if($this->player !== null){ + $this->player->close($this->player->getLeaveMessage(), $reason); + } $this->doServerDisconnect($reason, $notify); } } @@ -426,11 +427,41 @@ class NetworkSession{ * @param string $reason */ public function onClientDisconnect(string $reason) : void{ - if($this->checkDisconnect()){ + if($this->checkDisconnect() and $this->player !== null){ $this->player->close($this->player->getLeaveMessage(), $reason); } } + public function setAuthenticationStatus(bool $authenticated, bool $authRequired, ?string $error) : bool{ + if($authenticated and $this->info->getXuid() === ""){ + $error = "Expected XUID but none found"; + } + + if($error !== null){ + $this->disconnect($this->server->getLanguage()->translateString("pocketmine.disconnect.invalidSession", [$error])); + + return false; + } + + $this->authenticated = $authenticated; + + if(!$this->authenticated){ + if($authRequired){ + $this->disconnect("disconnectionScreen.notAuthenticated"); + return false; + } + + $this->server->getLogger()->debug($this->getDisplayName() . " is NOT logged into Xbox Live"); + if($this->info->getXuid() !== ""){ + $this->server->getLogger()->warning($this->getDisplayName() . " has an XUID, but their login keychain is not signed by Mojang"); + } + }else{ + $this->server->getLogger()->debug($this->getDisplayName() . " is logged into Xbox Live"); + } + + return $this->manager->kickDuplicates($this); + } + public function enableEncryption(string $encryptionKey, string $handshakeJwt) : void{ $pk = new ServerToClientHandshakePacket(); $pk->jwt = $handshakeJwt; @@ -449,12 +480,11 @@ class NetworkSession{ $pk->status = PlayStatusPacket::LOGIN_SUCCESS; $this->sendDataPacket($pk); - $this->player->onLoginSuccess(); - $this->setHandler(new ResourcePacksSessionHandler($this->player, $this, $this->server->getResourcePackManager())); + $this->setHandler(new ResourcePacksSessionHandler($this->server, $this, $this->server->getResourcePackManager())); } public function onResourcePacksDone() : void{ - $this->player->_actuallyConstruct(); + $this->createPlayer(); $this->setHandler(new PreSpawnSessionHandler($this->server, $this->player, $this)); } diff --git a/src/pocketmine/network/mcpe/ProcessLoginTask.php b/src/pocketmine/network/mcpe/ProcessLoginTask.php index f6c7d4d186..6c19792847 100644 --- a/src/pocketmine/network/mcpe/ProcessLoginTask.php +++ b/src/pocketmine/network/mcpe/ProcessLoginTask.php @@ -33,7 +33,6 @@ use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; use Mdanter\Ecc\Serializer\PublicKey\PemPublicKeySerializer; use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer; use pocketmine\network\mcpe\protocol\LoginPacket; -use pocketmine\Player; use pocketmine\scheduler\AsyncTask; use function assert; use function base64_decode; @@ -100,8 +99,8 @@ class ProcessLoginTask extends AsyncTask{ /** @var string|null */ private $handshakeJwt = null; - public function __construct(Player $player, LoginPacket $packet, bool $authRequired, bool $useEncryption = true){ - $this->storeLocal($player); + public function __construct(NetworkSession $session, LoginPacket $packet, bool $authRequired, bool $useEncryption = true){ + $this->storeLocal($session); $this->packet = $packet; $this->authRequired = $authRequired; $this->useEncryption = $useEncryption; @@ -243,15 +242,15 @@ class ProcessLoginTask extends AsyncTask{ } public function onCompletion() : void{ - /** @var Player $player */ - $player = $this->fetchLocal(); - if(!$player->isConnected()){ - $this->worker->getLogger()->error("Player " . $player->getName() . " was disconnected before their login could be verified"); - }elseif($player->setAuthenticationStatus($this->authenticated, $this->authRequired, $this->error)){ + /** @var NetworkSession $session */ + $session = $this->fetchLocal(); + if(!$session->isConnected()){ + $this->worker->getLogger()->error("Player " . $session->getDisplayName() . " was disconnected before their login could be verified"); + }elseif($session->setAuthenticationStatus($this->authenticated, $this->authRequired, $this->error)){ if(!$this->useEncryption){ - $player->getNetworkSession()->onLoginSuccess(); + $session->onLoginSuccess(); }else{ - $player->getNetworkSession()->enableEncryption($this->aesKey, $this->handshakeJwt); + $session->enableEncryption($this->aesKey, $this->handshakeJwt); } } } diff --git a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php index acb4d75c8f..32007e4579 100644 --- a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php @@ -23,25 +23,30 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; +use pocketmine\event\player\PlayerPreLoginEvent; +use pocketmine\network\mcpe\NetworkCipher; use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\ProcessLoginTask; use pocketmine\network\mcpe\protocol\LoginPacket; use pocketmine\network\mcpe\protocol\PlayStatusPacket; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\Player; +use pocketmine\Server; /** * Handles the initial login phase of the session. This handler is used as the initial state. */ class LoginSessionHandler extends SessionHandler{ - /** @var Player */ - private $player; + /** @var Server */ + private $server; /** @var NetworkSession */ private $session; - public function __construct(Player $player, NetworkSession $session){ - $this->player = $player; + + public function __construct(Server $server, NetworkSession $session){ $this->session = $session; + $this->server = $server; } public function handleLogin(LoginPacket $packet) : bool{ @@ -55,7 +60,7 @@ class LoginSessionHandler extends SessionHandler{ //This pocketmine disconnect message will only be seen by the console (PlayStatusPacket causes the messages to be shown for the client) $this->session->disconnect( - $this->player->getServer()->getLanguage()->translateString("pocketmine.disconnect.incompatibleProtocol", [$packet->protocol]), + $this->server->getLanguage()->translateString("pocketmine.disconnect.incompatibleProtocol", [$packet->protocol]), false ); @@ -74,13 +79,45 @@ class LoginSessionHandler extends SessionHandler{ return true; } - if($this->player->handleLogin($packet)){ - if($this->session->isConnected() and $this->session->getHandler() === $this){ //when login verification is disabled, the handler will already have been replaced - $this->session->setHandler(new NullSessionHandler()); //drop packets received during login verification - } + $ev = new PlayerPreLoginEvent( + $packet->playerInfo, + $this->session->getIp(), + $this->session->getPort(), + $this->server->requiresAuthentication() + ); + if($this->server->getNetwork()->getConnectionCount() > $this->server->getMaxPlayers()){ + $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_SERVER_FULL, "disconnectionScreen.serverFull"); + } + if(!$this->server->isWhitelisted($packet->playerInfo->getUsername())){ + $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_SERVER_WHITELISTED, "Server is whitelisted"); + } + if($this->server->getNameBans()->isBanned($packet->playerInfo->getUsername()) or $this->server->getIPBans()->isBanned($this->session->getIp())){ + $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_BANNED, "You are banned"); + } + + $ev->call(); + if(!$ev->isAllowed()){ + $this->session->disconnect($ev->getFinalKickMessage()); return true; } - return false; + + $this->processLogin($packet, $ev->isAuthRequired()); + + return true; + } + + /** + * TODO: This is separated for the purposes of allowing plugins (like Specter) to hack it and bypass authentication. + * In the future this won't be necessary. + * + * @param LoginPacket $packet + * @param bool $authRequired + * + * @throws \InvalidArgumentException + */ + protected function processLogin(LoginPacket $packet, bool $authRequired) : void{ + $this->server->getAsyncPool()->submitTask(new ProcessLoginTask($this->session, $packet, $authRequired, NetworkCipher::$ENABLED)); + $this->session->setHandler(new NullSessionHandler()); //drop packets received during login verification } protected function isCompatibleProtocol(int $protocolVersion) : bool{ diff --git a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php index 9d79c2c4f7..0b6d2ae1e5 100644 --- a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php @@ -30,9 +30,9 @@ use pocketmine\network\mcpe\protocol\ResourcePackClientResponsePacket; use pocketmine\network\mcpe\protocol\ResourcePackDataInfoPacket; use pocketmine\network\mcpe\protocol\ResourcePacksInfoPacket; use pocketmine\network\mcpe\protocol\ResourcePackStackPacket; -use pocketmine\Player; use pocketmine\resourcepacks\ResourcePack; use pocketmine\resourcepacks\ResourcePackManager; +use pocketmine\Server; use function ceil; use function implode; use function strpos; @@ -45,8 +45,8 @@ use function substr; class ResourcePacksSessionHandler extends SessionHandler{ private const PACK_CHUNK_SIZE = 1048576; //1MB - /** @var Player */ - private $player; + /** @var Server */ + private $server; /** @var NetworkSession */ private $session; /** @var ResourcePackManager */ @@ -55,8 +55,9 @@ class ResourcePacksSessionHandler extends SessionHandler{ /** @var bool[][] uuid => [chunk index => hasSent] */ private $downloadedChunks = []; - public function __construct(Player $player, NetworkSession $session, ResourcePackManager $resourcePackManager){ - $this->player = $player; + + public function __construct(Server $server, NetworkSession $session, ResourcePackManager $resourcePackManager){ + $this->server = $server; $this->session = $session; $this->resourcePackManager = $resourcePackManager; } @@ -69,7 +70,7 @@ class ResourcePacksSessionHandler extends SessionHandler{ } private function disconnectWithError(string $error) : void{ - $this->player->getServer()->getLogger()->error("Error while downloading resource packs for " . $this->player->getName() . ": " . $error); + $this->server->getLogger()->error("Error while downloading resource packs for " . $this->session->getDisplayName() . ": " . $error); $this->session->disconnect("disconnectionScreen.resourcePack"); } From f3309d3aec24fb859141e44ade8d5f086c1c3c68 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 10:29:16 +0000 Subject: [PATCH 0663/3224] Player: remove some field defaults --- src/pocketmine/Player.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 97fac651d7..d26cd30ae3 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -189,11 +189,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, public $spawned = false; /** @var string */ - protected $username = ""; + protected $username; /** @var string */ - protected $iusername = ""; + protected $iusername; /** @var string */ - protected $displayName = ""; + protected $displayName; /** @var int */ protected $randomClientId; /** @var string */ From 1d1a416afe5bdc5ab6c045d6bc162b371cc5eb1e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 10:38:38 +0000 Subject: [PATCH 0664/3224] Player: Move construction logic to the top --- src/pocketmine/Player.php | 258 +++++++++++++++++++------------------- 1 file changed, 129 insertions(+), 129 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index d26cd30ae3..79a37cbea9 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -290,6 +290,135 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** @var Form[] */ protected $forms = []; + /** + * @param Server $server + * @param NetworkSession $session + * @param PlayerInfo $playerInfo + * @param bool $authenticated + */ + public function __construct(Server $server, NetworkSession $session, PlayerInfo $playerInfo, bool $authenticated){ + $this->server = $server; + $this->networkSession = $session; + $this->playerInfo = $playerInfo; + $this->authenticated = $authenticated; + $this->skin = $this->playerInfo->getSkin(); + + $this->username = TextFormat::clean($this->playerInfo->getUsername()); + $this->displayName = $this->username; + $this->iusername = strtolower($this->username); + $this->locale = $this->playerInfo->getLocale(); + $this->randomClientId = $this->playerInfo->getClientId(); + + $this->uuid = $this->playerInfo->getUuid(); + $this->rawUUID = $this->uuid->toBinary(); + $this->xuid = $authenticated ? $this->playerInfo->getXuid() : ""; + + $this->perm = new PermissibleBase($this); + $this->chunksPerTick = (int) $this->server->getProperty("chunk-sending.per-tick", 4); + $this->spawnThreshold = (int) (($this->server->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); + + $this->allowMovementCheats = (bool) $this->server->getProperty("player.anti-cheat.allow-movement-cheats", false); + + $namedtag = $this->server->getOfflinePlayerData($this->username); //TODO: make this async + + $spawnReset = false; + + if($namedtag !== null and ($level = $this->server->getLevelManager()->getLevelByName($namedtag->getString("Level", "", true))) !== null){ + /** @var float[] $pos */ + $pos = $namedtag->getListTag("Pos")->getAllValues(); + $spawn = new Vector3($pos[0], $pos[1], $pos[2]); + }else{ + $level = $this->server->getLevelManager()->getDefaultLevel(); //TODO: default level might be null + $spawn = $level->getSpawnLocation(); + $spawnReset = true; + } + + //load the spawn chunk so we can see the terrain + $level->registerChunkLoader($this, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4, true); + $level->registerChunkListener($this, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4); + if($spawnReset){ + $spawn = $level->getSafeSpawn($spawn); + } + + if($namedtag === null){ + $namedtag = EntityFactory::createBaseNBT($spawn); + + $namedtag->setByte("OnGround", 1); //TODO: this hack is needed for new players in-air ticks - they don't get detected as on-ground until they move + //TODO: old code had a TODO for SpawnForced + + }elseif($spawnReset){ + $namedtag->setTag("Pos", new ListTag([ + new DoubleTag($spawn->x), + new DoubleTag($spawn->y), + new DoubleTag($spawn->z) + ])); + } + + parent::__construct($level, $namedtag); + + $ev = new PlayerLoginEvent($this, "Plugin reason"); + $ev->call(); + if($ev->isCancelled()){ + $this->close($this->getLeaveMessage(), $ev->getKickMessage()); + + return; + } + + $this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logIn", [ + TextFormat::AQUA . $this->username . TextFormat::WHITE, + $this->networkSession->getIp(), + $this->networkSession->getPort(), + $this->id, + $this->level->getDisplayName(), + round($this->x, 4), + round($this->y, 4), + round($this->z, 4) + ])); + + $this->server->addOnlinePlayer($this); + } + + protected function initHumanData(CompoundTag $nbt) : void{ + $this->setNameTag($this->username); + } + + protected function initEntity(CompoundTag $nbt) : void{ + parent::initEntity($nbt); + $this->addDefaultWindows(); + + $this->firstPlayed = $nbt->getLong("firstPlayed", $now = (int) (microtime(true) * 1000)); + $this->lastPlayed = $nbt->getLong("lastPlayed", $now); + + $this->gamemode = $this->server->getForceGamemode() ? $this->server->getGamemode() : $nbt->getInt("playerGameType", $this->server->getGamemode()) & 0x03; + + $this->allowFlight = $this->isCreative(); + $this->keepMovement = $this->isSpectator() || $this->allowMovementCheats(); + if($this->isOp()){ + $this->setRemoveFormat(false); + } + + $this->setNameTagVisible(); + $this->setNameTagAlwaysVisible(); + $this->setCanClimb(); + + $this->achievements = []; + $achievements = $nbt->getCompoundTag("Achievements"); + if($achievements !== null){ + /** @var ByteTag $tag */ + foreach($achievements as $name => $tag){ + $this->achievements[$name] = $tag->getValue() !== 0; + } + } + + if(!$this->hasValidSpawnPosition()){ + if(($level = $this->server->getLevelManager()->getLevelByName($nbt->getString("SpawnLevel", ""))) instanceof Level){ + $this->spawnPosition = new Position($nbt->getInt("SpawnX"), $nbt->getInt("SpawnY"), $nbt->getInt("SpawnZ"), $level); + }else{ + $this->spawnPosition = $this->level->getSafeSpawn(); + } + } + } + /** * @return TranslationContainer|string */ @@ -1690,135 +1819,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return ($targetDot - $eyeDot) >= -$maxDiff; } - /** - * @param Server $server - * @param NetworkSession $session - * @param PlayerInfo $playerInfo - * @param bool $authenticated - */ - public function __construct(Server $server, NetworkSession $session, PlayerInfo $playerInfo, bool $authenticated){ - $this->server = $server; - $this->networkSession = $session; - $this->playerInfo = $playerInfo; - $this->authenticated = $authenticated; - $this->skin = $this->playerInfo->getSkin(); - - $this->username = TextFormat::clean($this->playerInfo->getUsername()); - $this->displayName = $this->username; - $this->iusername = strtolower($this->username); - $this->locale = $this->playerInfo->getLocale(); - $this->randomClientId = $this->playerInfo->getClientId(); - - $this->uuid = $this->playerInfo->getUuid(); - $this->rawUUID = $this->uuid->toBinary(); - $this->xuid = $authenticated ? $this->playerInfo->getXuid() : ""; - - $this->perm = new PermissibleBase($this); - $this->chunksPerTick = (int) $this->server->getProperty("chunk-sending.per-tick", 4); - $this->spawnThreshold = (int) (($this->server->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); - - $this->allowMovementCheats = (bool) $this->server->getProperty("player.anti-cheat.allow-movement-cheats", false); - - $namedtag = $this->server->getOfflinePlayerData($this->username); //TODO: make this async - - $spawnReset = false; - - if($namedtag !== null and ($level = $this->server->getLevelManager()->getLevelByName($namedtag->getString("Level", "", true))) !== null){ - /** @var float[] $pos */ - $pos = $namedtag->getListTag("Pos")->getAllValues(); - $spawn = new Vector3($pos[0], $pos[1], $pos[2]); - }else{ - $level = $this->server->getLevelManager()->getDefaultLevel(); //TODO: default level might be null - $spawn = $level->getSpawnLocation(); - $spawnReset = true; - } - - //load the spawn chunk so we can see the terrain - $level->registerChunkLoader($this, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4, true); - $level->registerChunkListener($this, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4); - if($spawnReset){ - $spawn = $level->getSafeSpawn($spawn); - } - - if($namedtag === null){ - $namedtag = EntityFactory::createBaseNBT($spawn); - - $namedtag->setByte("OnGround", 1); //TODO: this hack is needed for new players in-air ticks - they don't get detected as on-ground until they move - //TODO: old code had a TODO for SpawnForced - - }elseif($spawnReset){ - $namedtag->setTag("Pos", new ListTag([ - new DoubleTag($spawn->x), - new DoubleTag($spawn->y), - new DoubleTag($spawn->z) - ])); - } - - parent::__construct($level, $namedtag); - - $ev = new PlayerLoginEvent($this, "Plugin reason"); - $ev->call(); - if($ev->isCancelled()){ - $this->close($this->getLeaveMessage(), $ev->getKickMessage()); - - return; - } - - $this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logIn", [ - TextFormat::AQUA . $this->username . TextFormat::WHITE, - $this->networkSession->getIp(), - $this->networkSession->getPort(), - $this->id, - $this->level->getDisplayName(), - round($this->x, 4), - round($this->y, 4), - round($this->z, 4) - ])); - - $this->server->addOnlinePlayer($this); - } - - protected function initHumanData(CompoundTag $nbt) : void{ - $this->setNameTag($this->username); - } - - protected function initEntity(CompoundTag $nbt) : void{ - parent::initEntity($nbt); - $this->addDefaultWindows(); - - $this->firstPlayed = $nbt->getLong("firstPlayed", $now = (int) (microtime(true) * 1000)); - $this->lastPlayed = $nbt->getLong("lastPlayed", $now); - - $this->gamemode = $this->server->getForceGamemode() ? $this->server->getGamemode() : $nbt->getInt("playerGameType", $this->server->getGamemode()) & 0x03; - - $this->allowFlight = $this->isCreative(); - $this->keepMovement = $this->isSpectator() || $this->allowMovementCheats(); - if($this->isOp()){ - $this->setRemoveFormat(false); - } - - $this->setNameTagVisible(); - $this->setNameTagAlwaysVisible(); - $this->setCanClimb(); - - $this->achievements = []; - $achievements = $nbt->getCompoundTag("Achievements"); - if($achievements !== null){ - /** @var ByteTag $tag */ - foreach($achievements as $name => $tag){ - $this->achievements[$name] = $tag->getValue() !== 0; - } - } - - if(!$this->hasValidSpawnPosition()){ - if(($level = $this->server->getLevelManager()->getLevelByName($nbt->getString("SpawnLevel", ""))) instanceof Level){ - $this->spawnPosition = new Position($nbt->getInt("SpawnX"), $nbt->getInt("SpawnY"), $nbt->getInt("SpawnZ"), $level); - }else{ - $this->spawnPosition = $this->level->getSafeSpawn(); - } - } - } - /** * Sends a chat message as this player. If the message begins with a / (forward-slash) it will be treated * as a command. From 9cddfdf8eca6a7fefba865dae1010eee2e528c87 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 10:41:50 +0000 Subject: [PATCH 0665/3224] Revert "Move core permissions to default_permissions.yml" This reverts commit 5fac5c72816c6e1b137ca59b14e567a9116c2baa. --- resources/default_permissions.yml | 192 ------------------ .../permission/DefaultPermissions.php | 90 +++++++- 2 files changed, 83 insertions(+), 199 deletions(-) delete mode 100644 resources/default_permissions.yml diff --git a/resources/default_permissions.yml b/resources/default_permissions.yml deleted file mode 100644 index 940c4da107..0000000000 --- a/resources/default_permissions.yml +++ /dev/null @@ -1,192 +0,0 @@ ---- -pocketmine: - description: Allows using all PocketMine commands and utilities - default: op - children: - pocketmine.broadcast: - description: Allows the user to receive all broadcast messages - default: op - children: - pocketmine.broadcast.admin: - description: Allows the user to receive administrative broadcasts - default: op - pocketmine.broadcast.user: - description: Allows the user to receive user broadcasts - default: "true" - pocketmine.command: - description: Allows using all PocketMine commands - default: op - children: - pocketmine.command.ban: - description: Allows the user to ban people - default: op - children: - pocketmine.command.ban.ip: - description: Allows the user to ban IP addresses - default: op - pocketmine.command.ban.player: - description: Allows the user to ban players - default: op - pocketmine.command.defaultgamemode: - description: Allows the user to change the default gamemode - default: op - pocketmine.command.dumpmemory: - description: Allows the user to dump memory contents - default: "false" - pocketmine.command.effect: - description: Allows the user to give/take potion effects - default: op - pocketmine.command.enchant: - description: Allows the user to enchant items - default: op - pocketmine.command.gamemode: - description: Allows the user to change the gamemode of players - default: op - pocketmine.command.gc: - description: Allows the user to fire garbage collection tasks - default: op - pocketmine.command.give: - description: Allows the user to give items to players - default: op - pocketmine.command.help: - description: Allows the user to view the help menu - default: "true" - pocketmine.command.kick: - description: Allows the user to kick players - default: op - pocketmine.command.kill: - description: Allows the user to kill players - default: op - children: - pocketmine.command.kill.other: - description: Allows the user to kill other players - default: op - pocketmine.command.kill.self: - description: Allows the user to commit suicide - default: "true" - pocketmine.command.list: - description: Allows the user to list all online players - default: op - pocketmine.command.me: - description: Allows the user to perform a chat action - default: "true" - pocketmine.command.op: - description: Allows the user to change operators - default: op - children: - pocketmine.command.op.give: - description: Allows the user to give a player operator status - default: op - pocketmine.command.op.take: - description: Allows the user to take a player's operator status - default: op - pocketmine.command.particle: - description: Allows the user to create particle effects - default: op - pocketmine.command.plugins: - description: Allows the user to view the list of plugins - default: op - pocketmine.command.reload: - description: Allows the user to reload the server settings - default: op - pocketmine.command.save: - description: Allows the user to save the worlds - default: op - children: - pocketmine.command.save.disable: - description: Allows the user to disable automatic saving - default: op - pocketmine.command.save.enable: - description: Allows the user to enable automatic saving - default: op - pocketmine.command.save.perform: - description: Allows the user to perform a manual save - default: op - pocketmine.command.say: - description: Allows the user to talk as the console - default: op - pocketmine.command.seed: - description: Allows the user to view the seed of the world - default: op - pocketmine.command.setworldspawn: - description: Allows the user to change the world spawn - default: op - pocketmine.command.spawnpoint: - description: Allows the user to change player's spawnpoint - default: op - pocketmine.command.status: - description: Allows the user to view the server performance - default: op - pocketmine.command.stop: - description: Allows the user to stop the server - default: op - pocketmine.command.teleport: - description: Allows the user to teleport players - default: op - pocketmine.command.tell: - description: Allows the user to privately message another player - default: "true" - pocketmine.command.time: - description: Allows the user to alter the time - default: op - children: - pocketmine.command.time.add: - description: Allows the user to fast-forward time - default: op - pocketmine.command.time.query: - description: Allows the user query the time - default: op - pocketmine.command.time.set: - description: Allows the user to change the time - default: op - pocketmine.command.time.start: - description: Allows the user to restart the time - default: op - pocketmine.command.time.stop: - description: Allows the user to stop the time - default: op - pocketmine.command.timings: - description: Allows the user to records timings for all plugin events - default: op - pocketmine.command.title: - description: Allows the user to send a title to the specified player - default: op - pocketmine.command.transferserver: - description: Allows the user to transfer self to another server - default: op - pocketmine.command.unban: - description: Allows the user to unban people - default: op - children: - pocketmine.command.unban.ip: - description: Allows the user to unban IP addresses - default: op - pocketmine.command.unban.player: - description: Allows the user to unban players - default: op - pocketmine.command.version: - description: Allows the user to view the version of the server - default: "true" - pocketmine.command.whitelist: - description: Allows the user to modify the server whitelist - default: op - children: - pocketmine.command.whitelist.add: - description: Allows the user to add a player to the server whitelist - default: op - pocketmine.command.whitelist.disable: - description: Allows the user to disable the server whitelist - default: op - pocketmine.command.whitelist.enable: - description: Allows the user to enable the server whitelist - default: op - pocketmine.command.whitelist.list: - description: Allows the user to list all the players on the server whitelist - default: op - pocketmine.command.whitelist.reload: - description: Allows the user to reload the server whitelist - default: op - pocketmine.command.whitelist.remove: - description: Allows the user to remove a player to the server whitelist - default: op -... diff --git a/src/pocketmine/permission/DefaultPermissions.php b/src/pocketmine/permission/DefaultPermissions.php index 2bf4e8a76c..6eb592e8b2 100644 --- a/src/pocketmine/permission/DefaultPermissions.php +++ b/src/pocketmine/permission/DefaultPermissions.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\permission; -use function file_get_contents; - abstract class DefaultPermissions{ public const ROOT = "pocketmine"; @@ -45,10 +43,88 @@ abstract class DefaultPermissions{ return PermissionManager::getInstance()->getPermission($perm->getName()); } - public static function registerCorePermissions() : void{ - $manager = PermissionManager::getInstance(); - foreach(PermissionParser::loadPermissions(yaml_parse(file_get_contents(\pocketmine\RESOURCE_PATH . 'default_permissions.yml'))) as $permission){ - $manager->addPermission($permission); - } + public static function registerCorePermissions(){ + $parent = self::registerPermission(new Permission(self::ROOT, "Allows using all PocketMine commands and utilities")); + + $broadcasts = self::registerPermission(new Permission(self::ROOT . ".broadcast", "Allows the user to receive all broadcast messages"), $parent); + self::registerPermission(new Permission(self::ROOT . ".broadcast.admin", "Allows the user to receive administrative broadcasts", Permission::DEFAULT_OP), $broadcasts); + self::registerPermission(new Permission(self::ROOT . ".broadcast.user", "Allows the user to receive user broadcasts", Permission::DEFAULT_TRUE), $broadcasts); + $broadcasts->recalculatePermissibles(); + + $commands = self::registerPermission(new Permission(self::ROOT . ".command", "Allows using all PocketMine commands"), $parent); + + $whitelist = self::registerPermission(new Permission(self::ROOT . ".command.whitelist", "Allows the user to modify the server whitelist", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.whitelist.add", "Allows the user to add a player to the server whitelist"), $whitelist); + self::registerPermission(new Permission(self::ROOT . ".command.whitelist.remove", "Allows the user to remove a player to the server whitelist"), $whitelist); + self::registerPermission(new Permission(self::ROOT . ".command.whitelist.reload", "Allows the user to reload the server whitelist"), $whitelist); + self::registerPermission(new Permission(self::ROOT . ".command.whitelist.enable", "Allows the user to enable the server whitelist"), $whitelist); + self::registerPermission(new Permission(self::ROOT . ".command.whitelist.disable", "Allows the user to disable the server whitelist"), $whitelist); + self::registerPermission(new Permission(self::ROOT . ".command.whitelist.list", "Allows the user to list all the players on the server whitelist"), $whitelist); + $whitelist->recalculatePermissibles(); + + $ban = self::registerPermission(new Permission(self::ROOT . ".command.ban", "Allows the user to ban people", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.ban.player", "Allows the user to ban players"), $ban); + self::registerPermission(new Permission(self::ROOT . ".command.ban.ip", "Allows the user to ban IP addresses"), $ban); + $ban->recalculatePermissibles(); + + $unban = self::registerPermission(new Permission(self::ROOT . ".command.unban", "Allows the user to unban people", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.unban.player", "Allows the user to unban players"), $unban); + self::registerPermission(new Permission(self::ROOT . ".command.unban.ip", "Allows the user to unban IP addresses"), $unban); + $unban->recalculatePermissibles(); + + $op = self::registerPermission(new Permission(self::ROOT . ".command.op", "Allows the user to change operators", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.op.give", "Allows the user to give a player operator status"), $op); + self::registerPermission(new Permission(self::ROOT . ".command.op.take", "Allows the user to take a player's operator status"), $op); + $op->recalculatePermissibles(); + + $save = self::registerPermission(new Permission(self::ROOT . ".command.save", "Allows the user to save the worlds", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.save.enable", "Allows the user to enable automatic saving"), $save); + self::registerPermission(new Permission(self::ROOT . ".command.save.disable", "Allows the user to disable automatic saving"), $save); + self::registerPermission(new Permission(self::ROOT . ".command.save.perform", "Allows the user to perform a manual save"), $save); + $save->recalculatePermissibles(); + + $time = self::registerPermission(new Permission(self::ROOT . ".command.time", "Allows the user to alter the time", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.time.add", "Allows the user to fast-forward time"), $time); + self::registerPermission(new Permission(self::ROOT . ".command.time.set", "Allows the user to change the time"), $time); + self::registerPermission(new Permission(self::ROOT . ".command.time.start", "Allows the user to restart the time"), $time); + self::registerPermission(new Permission(self::ROOT . ".command.time.stop", "Allows the user to stop the time"), $time); + self::registerPermission(new Permission(self::ROOT . ".command.time.query", "Allows the user query the time"), $time); + $time->recalculatePermissibles(); + + $kill = self::registerPermission(new Permission(self::ROOT . ".command.kill", "Allows the user to kill players", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.kill.self", "Allows the user to commit suicide", Permission::DEFAULT_TRUE), $kill); + self::registerPermission(new Permission(self::ROOT . ".command.kill.other", "Allows the user to kill other players"), $kill); + $kill->recalculatePermissibles(); + + self::registerPermission(new Permission(self::ROOT . ".command.me", "Allows the user to perform a chat action", Permission::DEFAULT_TRUE), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.tell", "Allows the user to privately message another player", Permission::DEFAULT_TRUE), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.say", "Allows the user to talk as the console", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.give", "Allows the user to give items to players", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.effect", "Allows the user to give/take potion effects", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.enchant", "Allows the user to enchant items", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.particle", "Allows the user to create particle effects", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.teleport", "Allows the user to teleport players", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.kick", "Allows the user to kick players", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.stop", "Allows the user to stop the server", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.list", "Allows the user to list all online players", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.help", "Allows the user to view the help menu", Permission::DEFAULT_TRUE), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.plugins", "Allows the user to view the list of plugins", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.reload", "Allows the user to reload the server settings", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.version", "Allows the user to view the version of the server", Permission::DEFAULT_TRUE), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.gamemode", "Allows the user to change the gamemode of players", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.defaultgamemode", "Allows the user to change the default gamemode", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.seed", "Allows the user to view the seed of the world", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.status", "Allows the user to view the server performance", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.gc", "Allows the user to fire garbage collection tasks", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.dumpmemory", "Allows the user to dump memory contents", Permission::DEFAULT_FALSE), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.timings", "Allows the user to records timings for all plugin events", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.spawnpoint", "Allows the user to change player's spawnpoint", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.setworldspawn", "Allows the user to change the world spawn", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.transferserver", "Allows the user to transfer self to another server", Permission::DEFAULT_OP), $commands); + self::registerPermission(new Permission(self::ROOT . ".command.title", "Allows the user to send a title to the specified player", Permission::DEFAULT_OP), $commands); + + $commands->recalculatePermissibles(); + + $parent->recalculatePermissibles(); } } From 1bc37a1a8a4d89cd3f0115db11e1ed6339b47fbe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 11:33:32 +0000 Subject: [PATCH 0666/3224] Player: Clean up movement processing, now API-ified --- src/pocketmine/Player.php | 81 ++++++++++--------- .../mcpe/handler/SimpleSessionHandler.php | 12 ++- 2 files changed, 53 insertions(+), 40 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 79a37cbea9..b64d9e285b 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -136,7 +136,6 @@ use function ceil; use function count; use function explode; use function floor; -use function fmod; use function get_class; use function in_array; use function is_int; @@ -928,17 +927,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->networkSession->getPing(); } - /** - * @return Position - */ - public function getNextPosition() : Position{ - return $this->newPosition !== null ? Position::fromObject($this->newPosition, $this->level) : $this->getPosition(); - } - - public function getInAirTicks() : int{ - return $this->inAirTicks; - } - /** * Returns whether the player is currently using an item (right-click and hold). * @return bool @@ -1566,6 +1554,48 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } + /** + * Returns the location that the player wants to be in at the end of this tick. Note that this may not be their + * actual result position at the end due to plugin interference or a range of other things. + * + * @return Vector3 + */ + public function getNextPosition() : Vector3{ + return $this->newPosition !== null ? clone $this->newPosition : $this->asVector3(); + } + + /** + * Sets the coordinates the player will move to next. This is processed at the end of each tick. Unless you have + * some particularly specialized logic, you probably want to use teleport() instead of this. + * + * This is used for processing movements sent by the player over network. + * + * @param Vector3 $newPos Coordinates of the player's feet, centered horizontally at the base of their bounding box. + * + * @return bool if the + */ + public function updateNextPosition(Vector3 $newPos) : bool{ + $newPos = $newPos->asVector3(); + if($this->isTeleporting and $newPos->distanceSquared($this) > 1){ //Tolerate up to 1 block to avoid problems with client-sided physics when spawning in blocks + $this->sendPosition($this, null, null, MovePlayerPacket::MODE_RESET); + $this->server->getLogger()->debug("Got outdated pre-teleport movement from " . $this->getName() . ", received " . $newPos . ", expected " . $this->asVector3()); + //Still getting movements from before teleport, ignore them + return false; + } + + // Once we get a movement within a reasonable distance, treat it as a teleport ACK and remove position lock + if($this->isTeleporting){ + $this->isTeleporting = false; + } + + $this->newPosition = $newPos; + return true; + } + + public function getInAirTicks() : int{ + return $this->inAirTicks; + } + protected function processMovement(int $tickDiff){ if($this->newPosition === null or $this->isSleeping()){ return; @@ -1861,33 +1891,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return true; } - public function handleMovePlayer(MovePlayerPacket $packet) : bool{ - $newPos = $packet->position->subtract(0, $this->baseOffset, 0); - - if($this->isTeleporting and $newPos->distanceSquared($this) > 1){ //Tolerate up to 1 block to avoid problems with client-sided physics when spawning in blocks - $this->sendPosition($this, null, null, MovePlayerPacket::MODE_RESET); - $this->server->getLogger()->debug("Got outdated pre-teleport movement from " . $this->getName() . ", received " . $newPos . ", expected " . $this->asVector3()); - //Still getting movements from before teleport, ignore them - }else{ - // Once we get a movement within a reasonable distance, treat it as a teleport ACK and remove position lock - if($this->isTeleporting){ - $this->isTeleporting = false; - } - - $packet->yaw = fmod($packet->yaw, 360); - $packet->pitch = fmod($packet->pitch, 360); - - if($packet->yaw < 0){ - $packet->yaw += 360; - } - - $this->setRotation($packet->yaw, $packet->pitch); - $this->newPosition = $newPos; - } - - return true; - } - public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{ //TODO: add events so plugins can change this $this->getLevel()->broadcastPacketToViewers($this, $packet); diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index c329737f65..9c2899b068 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -78,6 +78,7 @@ use pocketmine\network\mcpe\protocol\types\UseItemOnEntityTransactionData; use pocketmine\network\mcpe\protocol\types\UseItemTransactionData; use pocketmine\Player; use function base64_encode; +use function fmod; use function implode; use function json_decode; use function json_encode; @@ -117,7 +118,16 @@ class SimpleSessionHandler extends SessionHandler{ } public function handleMovePlayer(MovePlayerPacket $packet) : bool{ - return $this->player->handleMovePlayer($packet); + $yaw = fmod($packet->yaw, 360); + $pitch = fmod($packet->pitch, 360); + if($yaw < 0){ + $yaw += 360; + } + + $this->player->setRotation($yaw, $pitch); + $this->player->updateNextPosition($packet->position->subtract(0, 1.62, 0)); + + return true; } public function handleLevelSoundEventPacketV1(LevelSoundEventPacketV1 $packet) : bool{ From 1045088668a72c08729b1971e8f8e48b4d721da1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 12:12:30 +0000 Subject: [PATCH 0667/3224] Move more packet handling logic out of Player there is now only (1) packet handler remaining in Player. The reason I haven't targeted this is because it needs improvements of its own. --- src/pocketmine/Player.php | 56 +------------------ .../mcpe/handler/SimpleSessionHandler.php | 35 +++++++++++- 2 files changed, 35 insertions(+), 56 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index b64d9e285b..62a0e135fd 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -102,9 +102,7 @@ use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; use pocketmine\network\mcpe\protocol\BookEditPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; -use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\MobEffectPacket; use pocketmine\network\mcpe\protocol\ModalFormRequestPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; @@ -1891,31 +1889,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return true; } - public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{ - //TODO: add events so plugins can change this - $this->getLevel()->broadcastPacketToViewers($this, $packet); - return true; - } - - public function handleEntityEvent(EntityEventPacket $packet) : bool{ - $this->doCloseInventory(); - - switch($packet->event){ - case EntityEventPacket::EATING_ITEM: - if($packet->data === 0){ - return false; - } - - $this->sendDataPacket($packet); - $this->server->broadcastPacket($this->getViewers(), $packet); - break; - default: - return false; - } - - return true; - } - public function equipItem(int $hotbarSlot) : bool{ if(!$this->inventory->isHotbarSlot($hotbarSlot)){ $this->inventory->sendContents($this); @@ -2325,6 +2298,9 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, public function toggleFlight(bool $fly) : void{ $ev = new PlayerToggleFlightEvent($this, $fly); + if(!$this->allowFlight){ + $ev->setCancelled(); + } $ev->call(); if($ev->isCancelled()){ $this->sendSettings(); @@ -2354,32 +2330,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->level->dropItem($this->add(0, 1.3, 0), $item, $this->getDirectionVector()->multiply(0.4), 40); } - public function handleAdventureSettings(AdventureSettingsPacket $packet) : bool{ - if($packet->entityUniqueId !== $this->getId()){ - return false; //TODO - } - - $handled = false; - - $isFlying = $packet->getFlag(AdventureSettingsPacket::FLYING); - if($isFlying and !$this->allowFlight){ - $this->kick($this->server->getLanguage()->translateString("kick.reason.cheat", ["%ability.flight"])); - return true; - }elseif($isFlying !== $this->isFlying()){ - $this->toggleFlight($isFlying); - $handled = true; - } - - if($packet->getFlag(AdventureSettingsPacket::NO_CLIP) and !$this->allowMovementCheats and !$this->isSpectator()){ - $this->kick($this->server->getLanguage()->translateString("kick.reason.cheat", ["%ability.noclip"])); - return true; - } - - //TODO: check other changes - - return $handled; - } - public function handleBookEdit(BookEditPacket $packet) : bool{ /** @var WritableBook $oldBook */ $oldBook = $this->inventory->getItem($packet->inventorySlot); diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index 9c2899b068..724f19ea3b 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -135,7 +135,21 @@ class SimpleSessionHandler extends SessionHandler{ } public function handleEntityEvent(EntityEventPacket $packet) : bool{ - return $this->player->handleEntityEvent($packet); + $this->player->doCloseInventory(); + + switch($packet->event){ + case EntityEventPacket::EATING_ITEM: //TODO: ignore this and handle it server-side + if($packet->data === 0){ + return false; + } + + $this->player->broadcastEntityEvent(EntityEventPacket::EATING_ITEM, $packet->data); + break; + default: + return false; + } + + return true; } public function handleInventoryTransaction(InventoryTransactionPacket $packet) : bool{ @@ -397,7 +411,21 @@ class SimpleSessionHandler extends SessionHandler{ } public function handleAdventureSettings(AdventureSettingsPacket $packet) : bool{ - return $this->player->handleAdventureSettings($packet); + if($packet->entityUniqueId !== $this->player->getId()){ + return false; //TODO: operators can change other people's permissions using this + } + + $handled = false; + + $isFlying = $packet->getFlag(AdventureSettingsPacket::FLYING); + if($isFlying !== $this->player->isFlying()){ + $this->player->toggleFlight($isFlying); + $handled = true; + } + + //TODO: check for other changes + + return $handled; } public function handleBlockEntityData(BlockEntityDataPacket $packet) : bool{ @@ -541,7 +569,8 @@ class SimpleSessionHandler extends SessionHandler{ } public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{ - return $this->player->handleLevelSoundEvent($packet); + $this->player->getLevel()->broadcastPacketToViewers($this->player->asVector3(), $packet); + return true; } public function handleNetworkStackLatency(NetworkStackLatencyPacket $packet) : bool{ From d4fe0043759bbc743b7268f1ee612e7c1b731103 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 12:20:35 +0000 Subject: [PATCH 0668/3224] More consistent fluency in Item API --- src/pocketmine/item/Armor.php | 5 ++++- src/pocketmine/item/Banner.php | 5 ++++- src/pocketmine/item/Durable.php | 5 ++++- src/pocketmine/item/WritableBook.php | 31 +++++++++++++++------------- src/pocketmine/item/WrittenBook.php | 15 +++++++++++--- 5 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/pocketmine/item/Armor.php b/src/pocketmine/item/Armor.php index 4f8812b214..f2ceb5adfa 100644 --- a/src/pocketmine/item/Armor.php +++ b/src/pocketmine/item/Armor.php @@ -83,9 +83,12 @@ abstract class Armor extends Durable{ * Sets the dyed colour of this armour piece. This generally only applies to leather armour. * * @param Color $color + * + * @return $this */ - public function setCustomColor(Color $color) : void{ + public function setCustomColor(Color $color) : self{ $this->getNamedTag()->setInt(self::TAG_CUSTOM_COLOR, Binary::signInt($color->toARGB())); + return $this; } /** diff --git a/src/pocketmine/item/Banner.php b/src/pocketmine/item/Banner.php index 469e0f3b2b..08126eb023 100644 --- a/src/pocketmine/item/Banner.php +++ b/src/pocketmine/item/Banner.php @@ -77,8 +77,10 @@ class Banner extends Item{ /** * @param Deque|BannerPattern[] $patterns + * + * @return $this */ - public function setPatterns(Deque $patterns) : void{ + public function setPatterns(Deque $patterns) : self{ $tag = new ListTag(); /** @var BannerPattern $pattern */ foreach($patterns as $pattern){ @@ -88,6 +90,7 @@ class Banner extends Item{ ); } $this->getNamedTag()->setTag(self::TAG_PATTERNS, $tag); + return $this; } public function getFuelTime() : int{ diff --git a/src/pocketmine/item/Durable.php b/src/pocketmine/item/Durable.php index b30610fca4..68e40e87d7 100644 --- a/src/pocketmine/item/Durable.php +++ b/src/pocketmine/item/Durable.php @@ -48,9 +48,12 @@ abstract class Durable extends Item{ * Sets whether the item will take damage when used. * * @param bool $value + * + * @return $this */ - public function setUnbreakable(bool $value = true) : void{ + public function setUnbreakable(bool $value = true) : self{ $this->getNamedTag()->setByte("Unbreakable", $value ? 1 : 0); + return $this; } /** diff --git a/src/pocketmine/item/WritableBook.php b/src/pocketmine/item/WritableBook.php index cc1a311cf7..bb97e726e2 100644 --- a/src/pocketmine/item/WritableBook.php +++ b/src/pocketmine/item/WritableBook.php @@ -75,13 +75,11 @@ class WritableBook extends Item{ * @param int $pageId * @param string $pageText * - * @return bool indicating whether the page was created or not. + * @return $this */ - public function setPageText(int $pageId, string $pageText) : bool{ - $created = false; + public function setPageText(int $pageId, string $pageText) : self{ if(!$this->pageExists($pageId)){ $this->addPage($pageId); - $created = true; } /** @var CompoundTag[]|ListTag $pagesTag */ @@ -92,7 +90,7 @@ class WritableBook extends Item{ $this->getNamedTag()->setTag(self::TAG_PAGES, $pagesTag); - return $created; + return $this; } /** @@ -100,8 +98,10 @@ class WritableBook extends Item{ * Creates a new page for every page between the given ID and existing pages that doesn't yet exist. * * @param int $pageId + * + * @return $this */ - public function addPage(int $pageId) : void{ + public function addPage(int $pageId) : self{ if($pageId < 0){ throw new \InvalidArgumentException("Page number \"$pageId\" is out of range"); } @@ -116,6 +116,7 @@ class WritableBook extends Item{ } $this->getNamedTag()->setTag(self::TAG_PAGES, $pagesTag); + return $this; } /** @@ -123,13 +124,13 @@ class WritableBook extends Item{ * * @param int $pageId * - * @return bool indicating success + * @return $this */ - public function deletePage(int $pageId) : bool{ + public function deletePage(int $pageId) : self{ $pagesTag = $this->getPagesTag(); $pagesTag->remove($pageId); - return true; + return $this; } /** @@ -138,9 +139,9 @@ class WritableBook extends Item{ * @param int $pageId * @param string $pageText * - * @return bool indicating success + * @return $this */ - public function insertPage(int $pageId, string $pageText = "") : bool{ + public function insertPage(int $pageId, string $pageText = "") : self{ $pagesTag = $this->getPagesTag(); $pagesTag->insert($pageId, CompoundTag::create() @@ -150,7 +151,7 @@ class WritableBook extends Item{ $this->getNamedTag()->setTag(self::TAG_PAGES, $pagesTag); - return true; + return $this; } /** @@ -197,12 +198,14 @@ class WritableBook extends Item{ } /** - * * @param CompoundTag[] $pages + * + * @return $this */ - public function setPages(array $pages) : void{ + public function setPages(array $pages) : self{ $nbt = $this->getNamedTag(); $nbt->setTag(self::TAG_PAGES, new ListTag($pages, NBT::TAG_Compound)); $this->setNamedTag($nbt); + return $this; } } diff --git a/src/pocketmine/item/WrittenBook.php b/src/pocketmine/item/WrittenBook.php index 1be3b5025f..37c4dd02de 100644 --- a/src/pocketmine/item/WrittenBook.php +++ b/src/pocketmine/item/WrittenBook.php @@ -56,14 +56,17 @@ class WrittenBook extends WritableBook{ * Sets the generation of a book. * * @param int $generation + * + * @return $this */ - public function setGeneration(int $generation) : void{ + public function setGeneration(int $generation) : self{ if($generation < 0 or $generation > 3){ throw new \InvalidArgumentException("Generation \"$generation\" is out of range"); } $namedTag = $this->getNamedTag(); $namedTag->setInt(self::TAG_GENERATION, $generation); $this->setNamedTag($namedTag); + return $this; } /** @@ -81,11 +84,14 @@ class WrittenBook extends WritableBook{ * Sets the author of this book. * * @param string $authorName + * + * @return $this */ - public function setAuthor(string $authorName) : void{ + public function setAuthor(string $authorName) : self{ $namedTag = $this->getNamedTag(); $namedTag->setString(self::TAG_AUTHOR, $authorName); $this->setNamedTag($namedTag); + return $this; } /** @@ -101,10 +107,13 @@ class WrittenBook extends WritableBook{ * Sets the author of this book. * * @param string $title + * + * @return $this */ - public function setTitle(string $title) : void{ + public function setTitle(string $title) : self{ $namedTag = $this->getNamedTag(); $namedTag->setString(self::TAG_TITLE, $title); $this->setNamedTag($namedTag); + return $this; } } From 15c6554d8a52f70c69382c37a64c905db8005303 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 12:52:50 +0000 Subject: [PATCH 0669/3224] Updated RakLib dependency --- composer.lock | 8 ++++---- src/pocketmine/network/mcpe/RakLibInterface.php | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/composer.lock b/composer.lock index 8395d5e19e..ede5690c9d 100644 --- a/composer.lock +++ b/composer.lock @@ -413,12 +413,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "d9f15311ef328bddd5891fb7e92d2b3a7e48f501" + "reference": "1a213053c51c6793ea050eb9e7d0bc4184dce52c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/d9f15311ef328bddd5891fb7e92d2b3a7e48f501", - "reference": "d9f15311ef328bddd5891fb7e92d2b3a7e48f501", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/1a213053c51c6793ea050eb9e7d0bc4184dce52c", + "reference": "1a213053c51c6793ea050eb9e7d0bc4184dce52c", "shasum": "" }, "require": { @@ -446,7 +446,7 @@ "source": "https://github.com/pmmp/RakLib/tree/master", "issues": "https://github.com/pmmp/RakLib/issues" }, - "time": "2019-02-21T14:39:41+00:00" + "time": "2019-03-23T12:51:03+00:00" }, { "name": "pocketmine/snooze", diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 491806c51b..0346023c9e 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -99,7 +99,9 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $this->server->getTickSleeper()->addNotifier($this->sleeper, function() : void{ while($this->interface->handlePacket()); }); - $this->rakLib->start(PTHREADS_INHERIT_CONSTANTS); //HACK: MainLogger needs constants for exception logging + $this->server->getLogger()->debug("Waiting for RakLib to start..."); + $this->rakLib->startAndWait(PTHREADS_INHERIT_CONSTANTS); //HACK: MainLogger needs constants for exception logging + $this->server->getLogger()->debug("RakLib booted successfully"); } public function getConnectionCount() : int{ From 98f56087de8b250970c512d9de0c972af0784f51 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 12:53:00 +0000 Subject: [PATCH 0670/3224] make composer happy --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index ede5690c9d..81dc093108 100644 --- a/composer.lock +++ b/composer.lock @@ -372,12 +372,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "772f627884c92beb750cc1c50a8d25f155a9c006" + "reference": "98b727aa9125a56c3dac9b65cde3f75acf5f6b2a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/772f627884c92beb750cc1c50a8d25f155a9c006", - "reference": "772f627884c92beb750cc1c50a8d25f155a9c006", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/98b727aa9125a56c3dac9b65cde3f75acf5f6b2a", + "reference": "98b727aa9125a56c3dac9b65cde3f75acf5f6b2a", "shasum": "" }, "require": { @@ -405,7 +405,7 @@ "source": "https://github.com/pmmp/NBT/tree/master", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2019-03-18T14:38:07+00:00" + "time": "2019-03-23T08:59:10+00:00" }, { "name": "pocketmine/raklib", From a74a4b579da2e3d8ac100225d905ac257805f8e2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 12:56:02 +0000 Subject: [PATCH 0671/3224] wtf @sandertv --- src/pocketmine/item/WrittenBook.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/item/WrittenBook.php b/src/pocketmine/item/WrittenBook.php index 37c4dd02de..fa92cb2eeb 100644 --- a/src/pocketmine/item/WrittenBook.php +++ b/src/pocketmine/item/WrittenBook.php @@ -49,7 +49,7 @@ class WrittenBook extends WritableBook{ * @return int */ public function getGeneration() : int{ - return $this->getNamedTag()->getInt(self::TAG_GENERATION, -1); + return $this->getNamedTag()->getInt(self::TAG_GENERATION, self::GENERATION_ORIGINAL); } /** From 034bd716c8539e2b4ba2e246832d1f042b7d2f03 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 14:36:03 +0000 Subject: [PATCH 0672/3224] Clean up WritableBook hierarchy --- src/pocketmine/Player.php | 2 +- .../event/player/PlayerEditBookEvent.php | 20 +- src/pocketmine/item/WritableBook.php | 182 +-------------- src/pocketmine/item/WritableBookBase.php | 207 ++++++++++++++++++ src/pocketmine/item/WrittenBook.php | 4 +- 5 files changed, 221 insertions(+), 194 deletions(-) create mode 100644 src/pocketmine/item/WritableBookBase.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 62a0e135fd..9c75e6c4ed 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2333,7 +2333,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, public function handleBookEdit(BookEditPacket $packet) : bool{ /** @var WritableBook $oldBook */ $oldBook = $this->inventory->getItem($packet->inventorySlot); - if($oldBook->getId() !== Item::WRITABLE_BOOK){ + if(!($oldBook instanceof WritableBook)){ return false; } diff --git a/src/pocketmine/event/player/PlayerEditBookEvent.php b/src/pocketmine/event/player/PlayerEditBookEvent.php index 6aac41d9e3..ee0e0b252f 100644 --- a/src/pocketmine/event/player/PlayerEditBookEvent.php +++ b/src/pocketmine/event/player/PlayerEditBookEvent.php @@ -25,7 +25,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\item\WritableBook; +use pocketmine\item\WritableBookBase; use pocketmine\Player; class PlayerEditBookEvent extends PlayerEvent implements Cancellable{ @@ -37,16 +37,16 @@ class PlayerEditBookEvent extends PlayerEvent implements Cancellable{ public const ACTION_SWAP_PAGES = 3; public const ACTION_SIGN_BOOK = 4; - /** @var WritableBook */ + /** @var WritableBookBase */ private $oldBook; /** @var int */ private $action; - /** @var WritableBook */ + /** @var WritableBookBase */ private $newBook; /** @var int[] */ private $modifiedPages; - public function __construct(Player $player, WritableBook $oldBook, WritableBook $newBook, int $action, array $modifiedPages){ + public function __construct(Player $player, WritableBookBase $oldBook, WritableBookBase $newBook, int $action, array $modifiedPages){ $this->player = $player; $this->oldBook = $oldBook; $this->newBook = $newBook; @@ -66,9 +66,9 @@ class PlayerEditBookEvent extends PlayerEvent implements Cancellable{ /** * Returns the book before it was modified. * - * @return WritableBook + * @return WritableBookBase */ - public function getOldBook() : WritableBook{ + public function getOldBook() : WritableBookBase{ return $this->oldBook; } @@ -76,18 +76,18 @@ class PlayerEditBookEvent extends PlayerEvent implements Cancellable{ * Returns the book after it was modified. * The new book may be a written book, if the book was signed. * - * @return WritableBook + * @return WritableBookBase */ - public function getNewBook() : WritableBook{ + public function getNewBook() : WritableBookBase{ return $this->newBook; } /** * Sets the new book as the given instance. * - * @param WritableBook $book + * @param WritableBookBase $book */ - public function setNewBook(WritableBook $book) : void{ + public function setNewBook(WritableBookBase $book) : void{ $this->newBook = $book; } diff --git a/src/pocketmine/item/WritableBook.php b/src/pocketmine/item/WritableBook.php index bb97e726e2..d4ae343c16 100644 --- a/src/pocketmine/item/WritableBook.php +++ b/src/pocketmine/item/WritableBook.php @@ -23,189 +23,9 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\nbt\NBT; -use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\ListTag; - -class WritableBook extends Item{ - - public const TAG_PAGES = "pages"; //TAG_List - public const TAG_PAGE_TEXT = "text"; //TAG_String - public const TAG_PAGE_PHOTONAME = "photoname"; //TAG_String - TODO +class WritableBook extends WritableBookBase{ public function __construct(){ parent::__construct(self::WRITABLE_BOOK, 0, "Book & Quill"); } - - /** - * Returns whether the given page exists in this book. - * - * @param int $pageId - * - * @return bool - */ - public function pageExists(int $pageId) : bool{ - return $this->getPagesTag()->isset($pageId); - } - - /** - * Returns a string containing the content of a page (which could be empty), or null if the page doesn't exist. - * - * @param int $pageId - * - * @return string|null - */ - public function getPageText(int $pageId) : ?string{ - $pages = $this->getNamedTag()->getListTag(self::TAG_PAGES); - if($pages === null){ - return null; - } - - $page = $pages->get($pageId); - if($page instanceof CompoundTag){ - return $page->getString(self::TAG_PAGE_TEXT, ""); - } - - return null; - } - - /** - * Sets the text of a page in the book. Adds the page if the page does not yet exist. - * - * @param int $pageId - * @param string $pageText - * - * @return $this - */ - public function setPageText(int $pageId, string $pageText) : self{ - if(!$this->pageExists($pageId)){ - $this->addPage($pageId); - } - - /** @var CompoundTag[]|ListTag $pagesTag */ - $pagesTag = $this->getPagesTag(); - /** @var CompoundTag $page */ - $page = $pagesTag->get($pageId); - $page->setString(self::TAG_PAGE_TEXT, $pageText); - - $this->getNamedTag()->setTag(self::TAG_PAGES, $pagesTag); - - return $this; - } - - /** - * Adds a new page with the given page ID. - * Creates a new page for every page between the given ID and existing pages that doesn't yet exist. - * - * @param int $pageId - * - * @return $this - */ - public function addPage(int $pageId) : self{ - if($pageId < 0){ - throw new \InvalidArgumentException("Page number \"$pageId\" is out of range"); - } - - $pagesTag = $this->getPagesTag(); - - for($current = $pagesTag->count(); $current <= $pageId; $current++){ - $pagesTag->push(CompoundTag::create() - ->setString(self::TAG_PAGE_TEXT, "") - ->setString(self::TAG_PAGE_PHOTONAME, "") - ); - } - - $this->getNamedTag()->setTag(self::TAG_PAGES, $pagesTag); - return $this; - } - - /** - * Deletes an existing page with the given page ID. - * - * @param int $pageId - * - * @return $this - */ - public function deletePage(int $pageId) : self{ - $pagesTag = $this->getPagesTag(); - $pagesTag->remove($pageId); - - return $this; - } - - /** - * Inserts a new page with the given text and moves other pages upwards. - * - * @param int $pageId - * @param string $pageText - * - * @return $this - */ - public function insertPage(int $pageId, string $pageText = "") : self{ - $pagesTag = $this->getPagesTag(); - - $pagesTag->insert($pageId, CompoundTag::create() - ->setString(self::TAG_PAGE_TEXT, $pageText) - ->setString(self::TAG_PAGE_PHOTONAME, "") - ); - - $this->getNamedTag()->setTag(self::TAG_PAGES, $pagesTag); - - return $this; - } - - /** - * Switches the text of two pages with each other. - * - * @param int $pageId1 - * @param int $pageId2 - * - * @return bool indicating success - */ - public function swapPages(int $pageId1, int $pageId2) : bool{ - if(!$this->pageExists($pageId1) or !$this->pageExists($pageId2)){ - return false; - } - - $pageContents1 = $this->getPageText($pageId1); - $pageContents2 = $this->getPageText($pageId2); - $this->setPageText($pageId1, $pageContents2); - $this->setPageText($pageId2, $pageContents1); - - return true; - } - - public function getMaxStackSize() : int{ - return 1; - } - - /** - * Returns an array containing all pages of this book. - * - * @return CompoundTag[] - */ - public function getPages() : array{ - $pages = $this->getNamedTag()->getListTag(self::TAG_PAGES); - if($pages === null){ - return []; - } - - return $pages->getValue(); - } - - protected function getPagesTag() : ListTag{ - return $this->getNamedTag()->getListTag(self::TAG_PAGES) ?? new ListTag([], NBT::TAG_Compound); - } - - /** - * @param CompoundTag[] $pages - * - * @return $this - */ - public function setPages(array $pages) : self{ - $nbt = $this->getNamedTag(); - $nbt->setTag(self::TAG_PAGES, new ListTag($pages, NBT::TAG_Compound)); - $this->setNamedTag($nbt); - return $this; - } } diff --git a/src/pocketmine/item/WritableBookBase.php b/src/pocketmine/item/WritableBookBase.php new file mode 100644 index 0000000000..defe4189cf --- /dev/null +++ b/src/pocketmine/item/WritableBookBase.php @@ -0,0 +1,207 @@ + + public const TAG_PAGE_TEXT = "text"; //TAG_String + public const TAG_PAGE_PHOTONAME = "photoname"; //TAG_String - TODO + + /** + * Returns whether the given page exists in this book. + * + * @param int $pageId + * + * @return bool + */ + public function pageExists(int $pageId) : bool{ + return $this->getPagesTag()->isset($pageId); + } + + /** + * Returns a string containing the content of a page (which could be empty), or null if the page doesn't exist. + * + * @param int $pageId + * + * @return string|null + */ + public function getPageText(int $pageId) : ?string{ + $pages = $this->getNamedTag()->getListTag(self::TAG_PAGES); + if($pages === null){ + return null; + } + + $page = $pages->get($pageId); + if($page instanceof CompoundTag){ + return $page->getString(self::TAG_PAGE_TEXT, ""); + } + + return null; + } + + /** + * Sets the text of a page in the book. Adds the page if the page does not yet exist. + * + * @param int $pageId + * @param string $pageText + * + * @return $this + */ + public function setPageText(int $pageId, string $pageText) : self{ + if(!$this->pageExists($pageId)){ + $this->addPage($pageId); + } + + /** @var CompoundTag[]|ListTag $pagesTag */ + $pagesTag = $this->getPagesTag(); + /** @var CompoundTag $page */ + $page = $pagesTag->get($pageId); + $page->setString(self::TAG_PAGE_TEXT, $pageText); + + $this->getNamedTag()->setTag(self::TAG_PAGES, $pagesTag); + + return $this; + } + + /** + * Adds a new page with the given page ID. + * Creates a new page for every page between the given ID and existing pages that doesn't yet exist. + * + * @param int $pageId + * + * @return $this + */ + public function addPage(int $pageId) : self{ + if($pageId < 0){ + throw new \InvalidArgumentException("Page number \"$pageId\" is out of range"); + } + + $pagesTag = $this->getPagesTag(); + + for($current = $pagesTag->count(); $current <= $pageId; $current++){ + $pagesTag->push(CompoundTag::create() + ->setString(self::TAG_PAGE_TEXT, "") + ->setString(self::TAG_PAGE_PHOTONAME, "") + ); + } + + $this->getNamedTag()->setTag(self::TAG_PAGES, $pagesTag); + return $this; + } + + /** + * Deletes an existing page with the given page ID. + * + * @param int $pageId + * + * @return $this + */ + public function deletePage(int $pageId) : self{ + $pagesTag = $this->getPagesTag(); + $pagesTag->remove($pageId); + + return $this; + } + + /** + * Inserts a new page with the given text and moves other pages upwards. + * + * @param int $pageId + * @param string $pageText + * + * @return $this + */ + public function insertPage(int $pageId, string $pageText = "") : self{ + $pagesTag = $this->getPagesTag(); + + $pagesTag->insert($pageId, CompoundTag::create() + ->setString(self::TAG_PAGE_TEXT, $pageText) + ->setString(self::TAG_PAGE_PHOTONAME, "") + ); + + $this->getNamedTag()->setTag(self::TAG_PAGES, $pagesTag); + + return $this; + } + + /** + * Switches the text of two pages with each other. + * + * @param int $pageId1 + * @param int $pageId2 + * + * @return bool indicating success + */ + public function swapPages(int $pageId1, int $pageId2) : bool{ + if(!$this->pageExists($pageId1) or !$this->pageExists($pageId2)){ + return false; + } + + $pageContents1 = $this->getPageText($pageId1); + $pageContents2 = $this->getPageText($pageId2); + $this->setPageText($pageId1, $pageContents2); + $this->setPageText($pageId2, $pageContents1); + + return true; + } + + public function getMaxStackSize() : int{ + return 1; + } + + /** + * Returns an array containing all pages of this book. + * + * @return CompoundTag[] + */ + public function getPages() : array{ + $pages = $this->getNamedTag()->getListTag(self::TAG_PAGES); + if($pages === null){ + return []; + } + + return $pages->getValue(); + } + + protected function getPagesTag() : ListTag{ + return $this->getNamedTag()->getListTag(self::TAG_PAGES) ?? new ListTag([], NBT::TAG_Compound); + } + + /** + * @param CompoundTag[] $pages + * + * @return $this + */ + public function setPages(array $pages) : self{ + $nbt = $this->getNamedTag(); + $nbt->setTag(self::TAG_PAGES, new ListTag($pages, NBT::TAG_Compound)); + $this->setNamedTag($nbt); + return $this; + } +} diff --git a/src/pocketmine/item/WrittenBook.php b/src/pocketmine/item/WrittenBook.php index fa92cb2eeb..7173816bae 100644 --- a/src/pocketmine/item/WrittenBook.php +++ b/src/pocketmine/item/WrittenBook.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\item; -class WrittenBook extends WritableBook{ +class WrittenBook extends WritableBookBase{ public const GENERATION_ORIGINAL = 0; public const GENERATION_COPY = 1; @@ -35,7 +35,7 @@ class WrittenBook extends WritableBook{ public const TAG_TITLE = "title"; //TAG_String public function __construct(){ - Item::__construct(self::WRITTEN_BOOK, 0, "Written Book"); + parent::__construct(self::WRITTEN_BOOK, 0, "Written Book"); } public function getMaxStackSize() : int{ From 53bb05a6a7e72df16b01711eff0e5565a73b85f6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 14:51:58 +0000 Subject: [PATCH 0673/3224] Fixed different woodtype boats being missing --- src/pocketmine/item/Boat.php | 17 +++++++++++++++-- src/pocketmine/item/ItemFactory.php | 6 +++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/item/Boat.php b/src/pocketmine/item/Boat.php index cfff0224a0..122e4fa0d4 100644 --- a/src/pocketmine/item/Boat.php +++ b/src/pocketmine/item/Boat.php @@ -23,9 +23,22 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\block\utils\TreeType; + class Boat extends Item{ - public function __construct(){ - parent::__construct(self::BOAT, 0, "Boat"); + /** @var TreeType */ + private $woodType; + + public function __construct(TreeType $woodType){ + parent::__construct(self::BOAT, $woodType->getMagicNumber(), $woodType->getDisplayName() . " Boat"); + $this->woodType = $woodType; + } + + /** + * @return TreeType + */ + public function getWoodType() : TreeType{ + return $this->woodType; } public function getFuelTime() : int{ diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index ab8b2f5f9f..4d20320fcd 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -27,6 +27,7 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\SkullType; +use pocketmine\block\utils\TreeType; use pocketmine\entity\EntityFactory; use pocketmine\entity\Living; use pocketmine\nbt\tag\CompoundTag; @@ -65,7 +66,6 @@ class ItemFactory{ self::register(new BeetrootSeeds()); self::register(new BeetrootSoup()); self::register(new BlazeRod()); - self::register(new Boat()); self::register(new Book()); self::register(new Boots(Item::CHAIN_BOOTS, 0, "Chainmail Boots", new ArmorTypeInfo(1, 196))); self::register(new Boots(Item::DIAMOND_BOOTS, 0, "Diamond Boots", new ArmorTypeInfo(3, 430))); @@ -260,6 +260,10 @@ class ItemFactory{ } } + foreach(TreeType::getAll() as $type){ + self::register(new Boat($type)); + } + //TODO: minecraft:acacia_sign //TODO: minecraft:armor_stand //TODO: minecraft:balloon From 765c5963a87b4fd38c03a5f2eee3a8d30a35ed10 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 15:01:35 +0000 Subject: [PATCH 0674/3224] Block: move a function --- src/pocketmine/block/Block.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 9e9db82032..11fe307f8c 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -136,6 +136,16 @@ class Block extends Position implements BlockIds, Metadatable{ return $this->idInfo->getVariant() | $stateMeta; } + + /** + * Returns a bitmask used to extract state bits from block metadata. + * + * @return int + */ + public function getStateBitmask() : int{ + return 0; + } + protected function writeStateToMeta() : int{ return 0; } @@ -176,15 +186,6 @@ class Block extends Position implements BlockIds, Metadatable{ } } - /** - * Returns a bitmask used to extract state bits from block metadata. - * - * @return int - */ - public function getStateBitmask() : int{ - return 0; - } - /** * Returns whether the given block has an equivalent type to this one. This compares base legacy ID and variant. * From 905cb7544a3164b282d9c7eaf7e9890df7c4e447 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 15:44:28 +0000 Subject: [PATCH 0675/3224] hack in different wood sign types --- src/pocketmine/block/BlockFactory.php | 12 +++++++++++- src/pocketmine/item/ItemFactory.php | 7 ++++++- src/pocketmine/item/Sign.php | 12 +----------- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 3d16e49ea3..ab4c3c4fc7 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -227,7 +227,6 @@ class BlockFactory{ self::register(new SandstoneStairs(new BID(Block::RED_SANDSTONE_STAIRS), "Red Sandstone Stairs")); self::register(new SandstoneStairs(new BID(Block::SANDSTONE_STAIRS), "Sandstone Stairs")); self::register(new SeaLantern(new BID(Block::SEALANTERN), "Sea Lantern")); - self::register(new Sign(new BlockIdentifierFlattened(Block::STANDING_SIGN, Block::WALL_SIGN, 0, ItemIds::SIGN, \pocketmine\tile\Sign::class), "Sign")); self::register(new Skull(new BID(Block::MOB_HEAD_BLOCK, 0, null, \pocketmine\tile\Skull::class), "Mob Head")); self::register(new SmoothStone(new BID(Block::STONE, Stone::NORMAL), "Stone")); self::register(new Snow(new BID(Block::SNOW), "Snow Block")); @@ -340,6 +339,15 @@ class BlockFactory{ $woodenTrapdoorIds[TreeType::ACACIA()] = Block::ACACIA_TRAPDOOR; $woodenTrapdoorIds[TreeType::DARK_OAK()] = Block::DARK_OAK_TRAPDOOR; + /** @var BlockIdentifierFlattened[]|\SplObjectStorage $woodenSignIds */ + $woodenSignIds = new \SplObjectStorage(); + $woodenSignIds[TreeType::OAK()] = new BlockIdentifierFlattened(Block::SIGN_POST, Block::WALL_SIGN, 0, ItemIds::SIGN, \pocketmine\tile\Sign::class); + $woodenSignIds[TreeType::SPRUCE()] = new BlockIdentifierFlattened(Block::SPRUCE_STANDING_SIGN, Block::SPRUCE_WALL_SIGN, 0, ItemIds::SPRUCE_SIGN, \pocketmine\tile\Sign::class); + $woodenSignIds[TreeType::BIRCH()] = new BlockIdentifierFlattened(Block::BIRCH_STANDING_SIGN, Block::BIRCH_WALL_SIGN, 0, ItemIds::BIRCH_SIGN, \pocketmine\tile\Sign::class); + $woodenSignIds[TreeType::JUNGLE()] = new BlockIdentifierFlattened(Block::JUNGLE_STANDING_SIGN, Block::JUNGLE_WALL_SIGN, 0, ItemIds::JUNGLE_SIGN, \pocketmine\tile\Sign::class); + $woodenSignIds[TreeType::ACACIA()] = new BlockIdentifierFlattened(Block::ACACIA_STANDING_SIGN, Block::ACACIA_WALL_SIGN, 0, ItemIds::ACACIA_SIGN, \pocketmine\tile\Sign::class); + $woodenSignIds[TreeType::DARK_OAK()] = new BlockIdentifierFlattened(Block::DARKOAK_STANDING_SIGN, Block::DARKOAK_WALL_SIGN, 0, ItemIds::DARKOAK_SIGN, \pocketmine\tile\Sign::class); + foreach(TreeType::getAll() as $treeType){ $magicNumber = $treeType->getMagicNumber(); $name = $treeType->getDisplayName(); @@ -360,6 +368,8 @@ class BlockFactory{ self::register(new WoodenButton(new BID($woodenButtonIds[$treeType]), $treeType->getDisplayName() . " Button")); self::register(new WoodenPressurePlate(new BID($woodenPressurePlateIds[$treeType]), $treeType->getDisplayName() . " Pressure Plate")); self::register(new Trapdoor(new BID($woodenTrapdoorIds[$treeType]), $treeType->getDisplayName() . " Trapdoor")); + + self::register(new Sign($woodenSignIds[$treeType], $treeType->getDisplayName() . " Sign")); } static $sandstoneTypes = [ diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 4d20320fcd..987165dcbd 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -214,7 +214,12 @@ class ItemFactory{ self::register(new Shovel(Item::IRON_SHOVEL, "Iron Shovel", TieredTool::TIER_IRON)); self::register(new Shovel(Item::STONE_SHOVEL, "Stone Shovel", TieredTool::TIER_STONE)); self::register(new Shovel(Item::WOODEN_SHOVEL, "Wooden Shovel", TieredTool::TIER_WOODEN)); - self::register(new Sign()); + self::register(new Sign(Block::STANDING_SIGN, 0, Item::SIGN)); + self::register(new Sign(Block::SPRUCE_STANDING_SIGN, 0, Item::SPRUCE_SIGN)); + self::register(new Sign(Block::BIRCH_STANDING_SIGN, 0, Item::BIRCH_SIGN)); + self::register(new Sign(Block::JUNGLE_STANDING_SIGN, 0, Item::JUNGLE_SIGN)); + self::register(new Sign(Block::ACACIA_STANDING_SIGN, 0, Item::ACACIA_SIGN)); + self::register(new Sign(Block::DARKOAK_STANDING_SIGN, 0, Item::DARKOAK_SIGN)); self::register(new Snowball()); self::register(new SpiderEye()); self::register(new Steak()); diff --git a/src/pocketmine/item/Sign.php b/src/pocketmine/item/Sign.php index 723c460b6e..69aa82aabb 100644 --- a/src/pocketmine/item/Sign.php +++ b/src/pocketmine/item/Sign.php @@ -23,17 +23,7 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\block\Block; -use pocketmine\block\BlockFactory; - -class Sign extends Item{ - public function __construct(){ - parent::__construct(self::SIGN, 0, "Sign"); - } - - public function getBlock() : Block{ - return BlockFactory::get(Block::SIGN_POST); - } +class Sign extends ItemBlock{ public function getMaxStackSize() : int{ return 16; From 3c283aa700f9e0a6a30dbe2b8f10ca7a7aca3d73 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 15:45:39 +0000 Subject: [PATCH 0676/3224] fix consistency check (again) --- tests/phpunit/block/block_factory_consistency_check.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 5e8e8fcf2f..29bf9834cb 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Moss Stone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Sign","1009":"Sign","1010":"Sign","1011":"Sign","1012":"Sign","1013":"Sign","1014":"Sign","1015":"Sign","1016":"Sign","1017":"Sign","1018":"Sign","1019":"Sign","1020":"Sign","1021":"Sign","1022":"Sign","1023":"Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Sign","1090":"Sign","1091":"Sign","1092":"Sign","1093":"Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4256":"Blue Ice","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6656":"Barrier"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Moss Stone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4256":"Blue Ice","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6656":"Barrier","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign"} \ No newline at end of file From a8fa8572e105ac98a30cbd68f468ab7bffee71af Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 18:11:27 +0000 Subject: [PATCH 0677/3224] partial sea pickle implementation --- src/pocketmine/block/BlockFactory.php | 1 + src/pocketmine/block/SeaPickle.php | 84 +++++++++++++++++++ .../block_factory_consistency_check.json | 2 +- 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 src/pocketmine/block/SeaPickle.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index ab4c3c4fc7..695a446086 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -227,6 +227,7 @@ class BlockFactory{ self::register(new SandstoneStairs(new BID(Block::RED_SANDSTONE_STAIRS), "Red Sandstone Stairs")); self::register(new SandstoneStairs(new BID(Block::SANDSTONE_STAIRS), "Sandstone Stairs")); self::register(new SeaLantern(new BID(Block::SEALANTERN), "Sea Lantern")); + self::register(new SeaPickle(new BID(Block::SEA_PICKLE), "Sea Pickle")); self::register(new Skull(new BID(Block::MOB_HEAD_BLOCK, 0, null, \pocketmine\tile\Skull::class), "Mob Head")); self::register(new SmoothStone(new BID(Block::STONE, Stone::NORMAL), "Stone")); self::register(new Snow(new BID(Block::SNOW), "Snow Block")); diff --git a/src/pocketmine/block/SeaPickle.php b/src/pocketmine/block/SeaPickle.php new file mode 100644 index 0000000000..6b7fee520e --- /dev/null +++ b/src/pocketmine/block/SeaPickle.php @@ -0,0 +1,84 @@ +count = ($stateMeta & 0x03) + 1; + $this->underwater = ($stateMeta & 0x04) === 0; + } + + protected function writeStateToMeta() : int{ + return ($this->count - 1) | ($this->underwater ? 0 : 0x04); + } + + public function getStateBitmask() : int{ + return 0b111; + } + + public function getHardness() : float{ + return 0; + } + + public function isSolid() : bool{ + return false; + } + + public function getLightLevel() : int{ + return $this->underwater ? ($this->count + 1) * 3 : 0; + } + + protected function recalculateBoundingBox() : ?AxisAlignedBB{ + return null; + } + + public function canBePlacedAt(Block $blockReplace, Vector3 $clickVector, int $face, bool $isClickedBlock) : bool{ + //TODO: proper placement logic (needs a supporting face below) + return ($blockReplace instanceof SeaPickle and $blockReplace->count < 4) or parent::canBePlacedAt($blockReplace, $clickVector, $face, $isClickedBlock); + } + + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + $this->underwater = false; //TODO: implement this once we have new water logic in place + if($blockReplace instanceof SeaPickle and $blockReplace->count < 4){ + $this->count = $blockReplace->count + 1; + } + + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + //TODO: bonemeal logic (requires coral) + return parent::onInteract($item, $face, $clickVector, $player); + } +} diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 29bf9834cb..f0e21f1caa 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Moss Stone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4256":"Blue Ice","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6656":"Barrier","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Moss Stone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4256":"Blue Ice","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign"} \ No newline at end of file From 74e134136dadfac94eb6622b2fe9c1c707dbb247 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 25 Feb 2019 10:53:45 +0000 Subject: [PATCH 0678/3224] Make Infested Stone blocks known this is not remotely a complete implementation, it's just here to make PM aware of these states so that world conversion can be handled correctly. A full implementation will come later. Any blocks added in this fashion should be marked with a //TODO so future maintainers can find which blocks need work. --- src/pocketmine/block/BlockFactory.php | 32 +++++++++++++++++++++ src/pocketmine/block/InfestedStone.php | 39 ++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 src/pocketmine/block/InfestedStone.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 695a446086..a18489588a 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -28,6 +28,8 @@ use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\block\utils\PillarRotationTrait; use pocketmine\block\utils\TreeType; +use pocketmine\item\Item; +use pocketmine\item\ItemFactory; use pocketmine\item\ItemIds; use pocketmine\level\Position; use pocketmine\tile\Comparator; @@ -157,6 +159,36 @@ class BlockFactory{ self::register(new HardenedGlassPane(new BID(Block::HARD_GLASS_PANE), "Hardened Glass Pane")); self::register(new HayBale(new BID(Block::HAY_BALE), "Hay Bale")); self::register(new Ice(new BID(Block::ICE), "Ice")); + self::register(new class(new BID(Block::MONSTER_EGG), "Infested Stone") extends InfestedStone{ + public function getSilkTouchDrops(Item $item) : array{ + return [ItemFactory::get(ItemIds::STONE)]; + } + }); + self::register(new class(new BID(Block::MONSTER_EGG, 1), "Infested Cobblestone") extends InfestedStone{ + public function getSilkTouchDrops(Item $item) : array{ + return [ItemFactory::get(ItemIds::COBBLESTONE)]; + } + }); + self::register(new class(new BID(Block::MONSTER_EGG, 2), "Infested Stone Brick") extends InfestedStone{ + public function getSilkTouchDrops(Item $item) : array{ + return [ItemFactory::get(ItemIds::STONE_BRICK)]; + } + }); + self::register(new class(new BID(Block::MONSTER_EGG, 3), "Infested Mossy Stone Brick") extends InfestedStone{ + public function getSilkTouchDrops(Item $item) : array{ + return [ItemFactory::get(ItemIds::STONE_BRICK, StoneBricks::MOSSY)]; + } + }); + self::register(new class(new BID(Block::MONSTER_EGG, 4), "Infested Cracked Stone Brick") extends InfestedStone{ + public function getSilkTouchDrops(Item $item) : array{ + return [ItemFactory::get(ItemIds::STONE_BRICK, StoneBricks::CRACKED)]; + } + }); + self::register(new class(new BID(Block::MONSTER_EGG, 5), "Infested Chiseled Stone Brick") extends InfestedStone{ + public function getSilkTouchDrops(Item $item) : array{ + return [ItemFactory::get(ItemIds::STONE_BRICK, StoneBricks::CHISELED)]; + } + }); self::register(new InfoUpdate(new BID(Block::INFO_UPDATE), "update!")); self::register(new InfoUpdate(new BID(Block::INFO_UPDATE2), "ate!upd")); self::register(new InvisibleBedrock(new BID(Block::INVISIBLEBEDROCK), "Invisible Bedrock")); diff --git a/src/pocketmine/block/InfestedStone.php b/src/pocketmine/block/InfestedStone.php new file mode 100644 index 0000000000..6e80996a0a --- /dev/null +++ b/src/pocketmine/block/InfestedStone.php @@ -0,0 +1,39 @@ + Date: Mon, 25 Feb 2019 10:54:48 +0000 Subject: [PATCH 0679/3224] Cram Nether Portal again, this is here for the state handling and the implementation is unfinished. --- src/pocketmine/block/BlockFactory.php | 1 + src/pocketmine/block/NetherPortal.php | 96 +++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 src/pocketmine/block/NetherPortal.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index a18489588a..3b8e976986 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -213,6 +213,7 @@ class BlockFactory{ self::register(new NetherBrick(new BID(Block::RED_NETHER_BRICK), "Red Nether Bricks")); self::register(new NetherBrickFence(new BID(Block::NETHER_BRICK_FENCE), "Nether Brick Fence")); self::register(new NetherBrickStairs(new BID(Block::NETHER_BRICK_STAIRS), "Nether Brick Stairs")); + self::register(new NetherPortal(new BID(Block::PORTAL), "Nether Portal")); self::register(new NetherQuartzOre(new BID(Block::NETHER_QUARTZ_ORE), "Nether Quartz Ore")); self::register(new NetherReactor(new BID(Block::NETHERREACTOR), "Nether Reactor Core")); self::register(new NetherWartBlock(new BID(Block::NETHER_WART_BLOCK), "Nether Wart Block")); diff --git a/src/pocketmine/block/NetherPortal.php b/src/pocketmine/block/NetherPortal.php new file mode 100644 index 0000000000..39b4485224 --- /dev/null +++ b/src/pocketmine/block/NetherPortal.php @@ -0,0 +1,96 @@ +axis = $stateMeta === 2 ? Facing::AXIS_Z : Facing::AXIS_X; //mojang u dumb + } + + protected function writeStateToMeta() : int{ + return $this->axis === Facing::AXIS_Z ? 2 : 1; + } + + public function getStateBitmask() : int{ + return 0b11; + } + + /** + * @return int + */ + public function getAxis() : int{ + return $this->axis; + } + + /** + * @param int $axis + * @throws \InvalidArgumentException + */ + public function setAxis(int $axis) : void{ + if($axis !== Facing::AXIS_X and $axis !== Facing::AXIS_Z){ + throw new \InvalidArgumentException("Invalid axis"); + } + $this->axis = $axis; + } + + public function getLightLevel() : int{ + return 11; + } + + public function isSolid() : bool{ + return false; + } + + public function getBoundingBox() : ?AxisAlignedBB{ + return null; + } + + public function isBreakable(Item $item) : bool{ + return false; + } + + public function getHardness() : float{ + return -1; + } + + public function getBlastResistance() : float{ + return 0; + } + + public function getDrops(Item $item) : array{ + return []; + } + + public function onEntityInside(Entity $entity) : void{ + //TODO + } +} From a2f42a7016d91b7b313cc2558a11d2c82958c204 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 18:54:45 +0000 Subject: [PATCH 0680/3224] Updated block/item ID constants from 1.10 --- src/pocketmine/block/BlockIds.php | 131 ++++++++++++++++++++++++++++-- src/pocketmine/item/ItemIds.php | 131 ++++++++++++++++++++++++++++-- 2 files changed, 252 insertions(+), 10 deletions(-) diff --git a/src/pocketmine/block/BlockIds.php b/src/pocketmine/block/BlockIds.php index 31ff4663dc..acc6e4c140 100644 --- a/src/pocketmine/block/BlockIds.php +++ b/src/pocketmine/block/BlockIds.php @@ -290,7 +290,124 @@ interface BlockIds{ public const STRIPPED_DARK_OAK_LOG = 264; public const STRIPPED_OAK_LOG = 265; public const BLUE_ICE = 266; - + public const ELEMENT_1 = 267; + public const ELEMENT_2 = 268; + public const ELEMENT_3 = 269; + public const ELEMENT_4 = 270; + public const ELEMENT_5 = 271; + public const ELEMENT_6 = 272; + public const ELEMENT_7 = 273; + public const ELEMENT_8 = 274; + public const ELEMENT_9 = 275; + public const ELEMENT_10 = 276; + public const ELEMENT_11 = 277; + public const ELEMENT_12 = 278; + public const ELEMENT_13 = 279; + public const ELEMENT_14 = 280; + public const ELEMENT_15 = 281; + public const ELEMENT_16 = 282; + public const ELEMENT_17 = 283; + public const ELEMENT_18 = 284; + public const ELEMENT_19 = 285; + public const ELEMENT_20 = 286; + public const ELEMENT_21 = 287; + public const ELEMENT_22 = 288; + public const ELEMENT_23 = 289; + public const ELEMENT_24 = 290; + public const ELEMENT_25 = 291; + public const ELEMENT_26 = 292; + public const ELEMENT_27 = 293; + public const ELEMENT_28 = 294; + public const ELEMENT_29 = 295; + public const ELEMENT_30 = 296; + public const ELEMENT_31 = 297; + public const ELEMENT_32 = 298; + public const ELEMENT_33 = 299; + public const ELEMENT_34 = 300; + public const ELEMENT_35 = 301; + public const ELEMENT_36 = 302; + public const ELEMENT_37 = 303; + public const ELEMENT_38 = 304; + public const ELEMENT_39 = 305; + public const ELEMENT_40 = 306; + public const ELEMENT_41 = 307; + public const ELEMENT_42 = 308; + public const ELEMENT_43 = 309; + public const ELEMENT_44 = 310; + public const ELEMENT_45 = 311; + public const ELEMENT_46 = 312; + public const ELEMENT_47 = 313; + public const ELEMENT_48 = 314; + public const ELEMENT_49 = 315; + public const ELEMENT_50 = 316; + public const ELEMENT_51 = 317; + public const ELEMENT_52 = 318; + public const ELEMENT_53 = 319; + public const ELEMENT_54 = 320; + public const ELEMENT_55 = 321; + public const ELEMENT_56 = 322; + public const ELEMENT_57 = 323; + public const ELEMENT_58 = 324; + public const ELEMENT_59 = 325; + public const ELEMENT_60 = 326; + public const ELEMENT_61 = 327; + public const ELEMENT_62 = 328; + public const ELEMENT_63 = 329; + public const ELEMENT_64 = 330; + public const ELEMENT_65 = 331; + public const ELEMENT_66 = 332; + public const ELEMENT_67 = 333; + public const ELEMENT_68 = 334; + public const ELEMENT_69 = 335; + public const ELEMENT_70 = 336; + public const ELEMENT_71 = 337; + public const ELEMENT_72 = 338; + public const ELEMENT_73 = 339; + public const ELEMENT_74 = 340; + public const ELEMENT_75 = 341; + public const ELEMENT_76 = 342; + public const ELEMENT_77 = 343; + public const ELEMENT_78 = 344; + public const ELEMENT_79 = 345; + public const ELEMENT_80 = 346; + public const ELEMENT_81 = 347; + public const ELEMENT_82 = 348; + public const ELEMENT_83 = 349; + public const ELEMENT_84 = 350; + public const ELEMENT_85 = 351; + public const ELEMENT_86 = 352; + public const ELEMENT_87 = 353; + public const ELEMENT_88 = 354; + public const ELEMENT_89 = 355; + public const ELEMENT_90 = 356; + public const ELEMENT_91 = 357; + public const ELEMENT_92 = 358; + public const ELEMENT_93 = 359; + public const ELEMENT_94 = 360; + public const ELEMENT_95 = 361; + public const ELEMENT_96 = 362; + public const ELEMENT_97 = 363; + public const ELEMENT_98 = 364; + public const ELEMENT_99 = 365; + public const ELEMENT_100 = 366; + public const ELEMENT_101 = 367; + public const ELEMENT_102 = 368; + public const ELEMENT_103 = 369; + public const ELEMENT_104 = 370; + public const ELEMENT_105 = 371; + public const ELEMENT_106 = 372; + public const ELEMENT_107 = 373; + public const ELEMENT_108 = 374; + public const ELEMENT_109 = 375; + public const ELEMENT_110 = 376; + public const ELEMENT_111 = 377; + public const ELEMENT_112 = 378; + public const ELEMENT_113 = 379; + public const ELEMENT_114 = 380; + public const ELEMENT_115 = 381; + public const ELEMENT_116 = 382; + public const ELEMENT_117 = 383; + public const ELEMENT_118 = 384; public const SEAGRASS = 385; public const CORAL = 386; public const CORAL_BLOCK = 387; @@ -355,21 +472,25 @@ interface BlockIds{ public const ACACIA_WALL_SIGN = 446; public const DARKOAK_STANDING_SIGN = 447; public const DARKOAK_WALL_SIGN = 448; - + public const LECTERN = 449; public const GRINDSTONE = 450; public const BLAST_FURNACE = 451; - + public const STONECUTTER_BLOCK = 452; public const SMOKER = 453; public const CARTOGRAPHY_TABLE = 455; public const FLETCHING_TABLE = 456; public const SMITHING_TABLE = 457; public const BARREL = 458; + public const LOOM = 459; public const BELL = 461; - + public const SWEET_BERRY_BUSH = 462; public const LANTERN = 463; - + public const CAMPFIRE = 464; public const LAVA_CAULDRON = 465; + public const JIGSAW = 466; + + public const COMPOSTER = 468; } diff --git a/src/pocketmine/item/ItemIds.php b/src/pocketmine/item/ItemIds.php index 2e94d8c703..770911789f 100644 --- a/src/pocketmine/item/ItemIds.php +++ b/src/pocketmine/item/ItemIds.php @@ -25,22 +25,26 @@ namespace pocketmine\item; interface ItemIds{ + public const COMPOSTER = -213; + + public const JIGSAW = -211; public const LAVA_CAULDRON = -210; - + public const CAMPFIRE = -209; public const LANTERN = -208; - + public const SWEET_BERRY_BUSH = -207; public const BELL = -206; + public const LOOM = -204; public const BARREL = -203; public const SMITHING_TABLE = -202; public const FLETCHING_TABLE = -201; public const CARTOGRAPHY_TABLE = -200; public const SMOKER = -198; - + public const STONECUTTER_BLOCK = -197; public const BLAST_FURNACE = -196; public const GRINDSTONE = -195; - + public const LECTERN = -194; public const DARKOAK_WALL_SIGN = -193; public const DARKOAK_STANDING_SIGN = -192; public const ACACIA_WALL_SIGN = -191; @@ -105,7 +109,124 @@ interface ItemIds{ public const CORAL_BLOCK = -132; public const CORAL = -131; public const SEAGRASS = -130; - + public const ELEMENT_118 = -129; + public const ELEMENT_117 = -128; + public const ELEMENT_116 = -127; + public const ELEMENT_115 = -126; + public const ELEMENT_114 = -125; + public const ELEMENT_113 = -124; + public const ELEMENT_112 = -123; + public const ELEMENT_111 = -122; + public const ELEMENT_110 = -121; + public const ELEMENT_109 = -120; + public const ELEMENT_108 = -119; + public const ELEMENT_107 = -118; + public const ELEMENT_106 = -117; + public const ELEMENT_105 = -116; + public const ELEMENT_104 = -115; + public const ELEMENT_103 = -114; + public const ELEMENT_102 = -113; + public const ELEMENT_101 = -112; + public const ELEMENT_100 = -111; + public const ELEMENT_99 = -110; + public const ELEMENT_98 = -109; + public const ELEMENT_97 = -108; + public const ELEMENT_96 = -107; + public const ELEMENT_95 = -106; + public const ELEMENT_94 = -105; + public const ELEMENT_93 = -104; + public const ELEMENT_92 = -103; + public const ELEMENT_91 = -102; + public const ELEMENT_90 = -101; + public const ELEMENT_89 = -100; + public const ELEMENT_88 = -99; + public const ELEMENT_87 = -98; + public const ELEMENT_86 = -97; + public const ELEMENT_85 = -96; + public const ELEMENT_84 = -95; + public const ELEMENT_83 = -94; + public const ELEMENT_82 = -93; + public const ELEMENT_81 = -92; + public const ELEMENT_80 = -91; + public const ELEMENT_79 = -90; + public const ELEMENT_78 = -89; + public const ELEMENT_77 = -88; + public const ELEMENT_76 = -87; + public const ELEMENT_75 = -86; + public const ELEMENT_74 = -85; + public const ELEMENT_73 = -84; + public const ELEMENT_72 = -83; + public const ELEMENT_71 = -82; + public const ELEMENT_70 = -81; + public const ELEMENT_69 = -80; + public const ELEMENT_68 = -79; + public const ELEMENT_67 = -78; + public const ELEMENT_66 = -77; + public const ELEMENT_65 = -76; + public const ELEMENT_64 = -75; + public const ELEMENT_63 = -74; + public const ELEMENT_62 = -73; + public const ELEMENT_61 = -72; + public const ELEMENT_60 = -71; + public const ELEMENT_59 = -70; + public const ELEMENT_58 = -69; + public const ELEMENT_57 = -68; + public const ELEMENT_56 = -67; + public const ELEMENT_55 = -66; + public const ELEMENT_54 = -65; + public const ELEMENT_53 = -64; + public const ELEMENT_52 = -63; + public const ELEMENT_51 = -62; + public const ELEMENT_50 = -61; + public const ELEMENT_49 = -60; + public const ELEMENT_48 = -59; + public const ELEMENT_47 = -58; + public const ELEMENT_46 = -57; + public const ELEMENT_45 = -56; + public const ELEMENT_44 = -55; + public const ELEMENT_43 = -54; + public const ELEMENT_42 = -53; + public const ELEMENT_41 = -52; + public const ELEMENT_40 = -51; + public const ELEMENT_39 = -50; + public const ELEMENT_38 = -49; + public const ELEMENT_37 = -48; + public const ELEMENT_36 = -47; + public const ELEMENT_35 = -46; + public const ELEMENT_34 = -45; + public const ELEMENT_33 = -44; + public const ELEMENT_32 = -43; + public const ELEMENT_31 = -42; + public const ELEMENT_30 = -41; + public const ELEMENT_29 = -40; + public const ELEMENT_28 = -39; + public const ELEMENT_27 = -38; + public const ELEMENT_26 = -37; + public const ELEMENT_25 = -36; + public const ELEMENT_24 = -35; + public const ELEMENT_23 = -34; + public const ELEMENT_22 = -33; + public const ELEMENT_21 = -32; + public const ELEMENT_20 = -31; + public const ELEMENT_19 = -30; + public const ELEMENT_18 = -29; + public const ELEMENT_17 = -28; + public const ELEMENT_16 = -27; + public const ELEMENT_15 = -26; + public const ELEMENT_14 = -25; + public const ELEMENT_13 = -24; + public const ELEMENT_12 = -23; + public const ELEMENT_11 = -22; + public const ELEMENT_10 = -21; + public const ELEMENT_9 = -20; + public const ELEMENT_8 = -19; + public const ELEMENT_7 = -18; + public const ELEMENT_6 = -17; + public const ELEMENT_5 = -16; + public const ELEMENT_4 = -15; + public const ELEMENT_3 = -14; + public const ELEMENT_2 = -13; + public const ELEMENT_1 = -12; public const BLUE_ICE = -11; public const STRIPPED_OAK_LOG = -10; public const STRIPPED_DARK_OAK_LOG = -9; From d51ca0b655a28c224aa607f76d6376f906bc60e7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 19:02:07 +0000 Subject: [PATCH 0681/3224] Leaves: use instanceof Wood instead of legacy ID checks --- src/pocketmine/block/Leaves.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 563f378e3b..e96f16b04d 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -80,8 +80,7 @@ class Leaves extends Transparent{ } $visited[$index] = true; - $id = $pos->getId(); - if($id === Block::WOOD or $id === Block::WOOD2){ + if($pos instanceof Wood){ //type doesn't matter return true; } From e088da320cc5c4e3cf283e83ad05acb652bec2ba Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 19:06:35 +0000 Subject: [PATCH 0682/3224] ItemEntity: fixed mineWood achievement not working for acacia/dark-oak --- src/pocketmine/entity/object/ItemEntity.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/entity/object/ItemEntity.php b/src/pocketmine/entity/object/ItemEntity.php index 74baf8e488..c01a496184 100644 --- a/src/pocketmine/entity/object/ItemEntity.php +++ b/src/pocketmine/entity/object/ItemEntity.php @@ -23,11 +23,13 @@ declare(strict_types=1); namespace pocketmine\entity\object; +use pocketmine\block\Wood; use pocketmine\entity\Entity; use pocketmine\event\entity\ItemDespawnEvent; use pocketmine\event\entity\ItemSpawnEvent; use pocketmine\event\inventory\InventoryPickupItemEvent; use pocketmine\item\Item; +use pocketmine\item\ItemIds; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\AddItemEntityPacket; use pocketmine\network\mcpe\protocol\TakeItemEntityPacket; @@ -260,13 +262,10 @@ class ItemEntity extends Entity{ return; } - switch($item->getId()){ - case Item::WOOD: - $player->awardAchievement("mineWood"); - break; - case Item::DIAMOND: - $player->awardAchievement("diamond"); - break; + if($item->getBlock() instanceof Wood){ + $player->awardAchievement("mineWood"); + }elseif($item->getId() === ItemIds::DIAMOND){ + $player->awardAchievement("diamond"); } $pk = new TakeItemEntityPacket(); From 06a37cc462030687157eafa2c41806a4d292d36b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 19:08:17 +0000 Subject: [PATCH 0683/3224] Fixed "wood" collision why the fuck Mojang... --- src/pocketmine/block/BlockFactory.php | 4 ++-- src/pocketmine/block/BlockIds.php | 6 +++--- src/pocketmine/item/ItemIds.php | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 3b8e976986..f14b8f6f31 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -392,8 +392,8 @@ class BlockFactory{ //TODO: find a better way to deal with this split self::register(new Leaves(new BID($magicNumber >= 4 ? Block::LEAVES2 : Block::LEAVES, $magicNumber & 0x03), $name . " Leaves", $treeType)); - self::register(new Log(new BID($magicNumber >= 4 ? Block::WOOD2 : Block::WOOD, $magicNumber & 0x03), $name . " Log", $treeType)); - self::register(new Wood(new BID($magicNumber >= 4 ? Block::WOOD2 : Block::WOOD, ($magicNumber & 0x03) | 0b1100), $name . " Wood", $treeType)); + self::register(new Log(new BID($magicNumber >= 4 ? Block::LOG2 : Block::LOG, $magicNumber & 0x03), $name . " Log", $treeType)); + self::register(new Wood(new BID($magicNumber >= 4 ? Block::LOG2 : Block::LOG, ($magicNumber & 0x03) | 0b1100), $name . " Wood", $treeType)); self::register(new FenceGate(new BID($fenceGateIds[$treeType]), $treeType->getDisplayName() . " Fence Gate")); self::register(new WoodenStairs(new BID($woodenStairIds[$treeType]), $treeType->getDisplayName() . " Stairs")); diff --git a/src/pocketmine/block/BlockIds.php b/src/pocketmine/block/BlockIds.php index acc6e4c140..93aa32c937 100644 --- a/src/pocketmine/block/BlockIds.php +++ b/src/pocketmine/block/BlockIds.php @@ -42,7 +42,7 @@ interface BlockIds{ public const GOLD_ORE = 14; public const IRON_ORE = 15; public const COAL_ORE = 16; - public const LOG = 17, WOOD = 17; + public const LOG = 17; public const LEAVES = 18; public const SPONGE = 19; public const GLASS = 20; @@ -187,7 +187,7 @@ interface BlockIds{ public const STAINED_CLAY = 159, STAINED_HARDENED_CLAY = 159, TERRACOTTA = 159; public const STAINED_GLASS_PANE = 160; public const LEAVES2 = 161; - public const LOG2 = 162, WOOD2 = 162; + public const LOG2 = 162; public const ACACIA_STAIRS = 163; public const DARK_OAK_STAIRS = 164; public const SLIME = 165, SLIME_BLOCK = 165; @@ -490,7 +490,7 @@ interface BlockIds{ public const CAMPFIRE = 464; public const LAVA_CAULDRON = 465; public const JIGSAW = 466; - + public const WOOD = 467; public const COMPOSTER = 468; } diff --git a/src/pocketmine/item/ItemIds.php b/src/pocketmine/item/ItemIds.php index 770911789f..01c999e2da 100644 --- a/src/pocketmine/item/ItemIds.php +++ b/src/pocketmine/item/ItemIds.php @@ -26,7 +26,7 @@ namespace pocketmine\item; interface ItemIds{ public const COMPOSTER = -213; - + public const WOOD = -212; public const JIGSAW = -211; public const LAVA_CAULDRON = -210; public const CAMPFIRE = -209; @@ -255,7 +255,7 @@ interface ItemIds{ public const GOLD_ORE = 14; public const IRON_ORE = 15; public const COAL_ORE = 16; - public const LOG = 17, WOOD = 17; + public const LOG = 17; public const LEAVES = 18; public const SPONGE = 19; public const GLASS = 20; @@ -400,7 +400,7 @@ interface ItemIds{ public const STAINED_CLAY = 159, STAINED_HARDENED_CLAY = 159, TERRACOTTA = 159; public const STAINED_GLASS_PANE = 160; public const LEAVES2 = 161; - public const LOG2 = 162, WOOD2 = 162; + public const LOG2 = 162; public const ACACIA_STAIRS = 163; public const DARK_OAK_STAIRS = 164; public const SLIME = 165, SLIME_BLOCK = 165; From 6efdac63d0118fe2bd0940ef9258fa2518e3b9c8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 19:18:25 +0000 Subject: [PATCH 0684/3224] added new Wood block --- src/pocketmine/block/BlockFactory.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index f14b8f6f31..8c04e82a18 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -393,7 +393,10 @@ class BlockFactory{ //TODO: find a better way to deal with this split self::register(new Leaves(new BID($magicNumber >= 4 ? Block::LEAVES2 : Block::LEAVES, $magicNumber & 0x03), $name . " Leaves", $treeType)); self::register(new Log(new BID($magicNumber >= 4 ? Block::LOG2 : Block::LOG, $magicNumber & 0x03), $name . " Log", $treeType)); + + //TODO: the old bug-block needs to be remapped to the new dedicated block self::register(new Wood(new BID($magicNumber >= 4 ? Block::LOG2 : Block::LOG, ($magicNumber & 0x03) | 0b1100), $name . " Wood", $treeType)); + self::register(new Wood(new BID(Block::WOOD, $magicNumber), $name . " Wood", $treeType)); self::register(new FenceGate(new BID($fenceGateIds[$treeType]), $treeType->getDisplayName() . " Fence Gate")); self::register(new WoodenStairs(new BID($woodenStairIds[$treeType]), $treeType->getDisplayName() . " Stairs")); From 397713247db76d1056415343fcf21a246920cdce Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 19:19:38 +0000 Subject: [PATCH 0685/3224] SeaPickle: fix drops --- src/pocketmine/block/SeaPickle.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pocketmine/block/SeaPickle.php b/src/pocketmine/block/SeaPickle.php index 6b7fee520e..7f838fac46 100644 --- a/src/pocketmine/block/SeaPickle.php +++ b/src/pocketmine/block/SeaPickle.php @@ -81,4 +81,8 @@ class SeaPickle extends Transparent{ //TODO: bonemeal logic (requires coral) return parent::onInteract($item, $face, $clickVector, $player); } + + public function getDropsForCompatibleTool(Item $item) : array{ + return [$this->asItem()->setCount($this->count)]; + } } From be0436b2a00249c63858584fecb160492c64d9b8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 19:20:52 +0000 Subject: [PATCH 0686/3224] fix consistency check (again) --- tests/phpunit/block/block_factory_consistency_check.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index f0e21f1caa..334fc33ea7 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Moss Stone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4256":"Blue Ice","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Moss Stone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4256":"Blue Ice","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From f84d7ad70dd8aa10c91005650470f2673b3c48df Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 19:21:11 +0000 Subject: [PATCH 0687/3224] sync block TODOs --- src/pocketmine/block/BlockFactory.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 8c04e82a18..fdd10eb801 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -472,16 +472,12 @@ class BlockFactory{ self::register(new CobblestoneWall(new BID(Block::COBBLESTONE_WALL, $magicNumber), $prefix . " Wall")); } - //TODO: minecraft:acacia_standing_sign - //TODO: minecraft:acacia_wall_sign //TODO: minecraft:andesite_stairs //TODO: minecraft:bamboo //TODO: minecraft:bamboo_sapling //TODO: minecraft:barrel //TODO: minecraft:beacon //TODO: minecraft:bell - //TODO: minecraft:birch_standing_sign - //TODO: minecraft:birch_wall_sign //TODO: minecraft:blast_furnace //TODO: minecraft:bubble_column //TODO: minecraft:campfire @@ -504,8 +500,6 @@ class BlockFactory{ //TODO: minecraft:coral_fan_hang2 //TODO: minecraft:coral_fan_hang3 //TODO: minecraft:dark_prismarine_stairs - //TODO: minecraft:darkoak_standing_sign - //TODO: minecraft:darkoak_wall_sign //TODO: minecraft:diorite_stairs //TODO: minecraft:dispenser //TODO: minecraft:double_stone_slab3 @@ -521,14 +515,11 @@ class BlockFactory{ //TODO: minecraft:hopper //TODO: minecraft:jigsaw //TODO: minecraft:jukebox - //TODO: minecraft:jungle_standing_sign - //TODO: minecraft:jungle_wall_sign //TODO: minecraft:kelp //TODO: minecraft:lantern //TODO: minecraft:lava_cauldron //TODO: minecraft:lectern //TODO: minecraft:loom - //TODO: minecraft:monster_egg //TODO: minecraft:mossy_cobblestone_stairs //TODO: minecraft:mossy_stone_brick_stairs //TODO: minecraft:movingBlock @@ -539,13 +530,11 @@ class BlockFactory{ //TODO: minecraft:polished_andesite_stairs //TODO: minecraft:polished_diorite_stairs //TODO: minecraft:polished_granite_stairs - //TODO: minecraft:portal //TODO: minecraft:prismarine_bricks_stairs //TODO: minecraft:prismarine_stairs //TODO: minecraft:red_nether_brick_stairs //TODO: minecraft:repeating_command_block //TODO: minecraft:scaffolding - //TODO: minecraft:sea_pickle //TODO: minecraft:seagrass //TODO: minecraft:shulker_box //TODO: minecraft:slime @@ -555,8 +544,6 @@ class BlockFactory{ //TODO: minecraft:smooth_red_sandstone_stairs //TODO: minecraft:smooth_sandstone_stairs //TODO: minecraft:smooth_stone - //TODO: minecraft:spruce_standing_sign - //TODO: minecraft:spruce_wall_sign //TODO: minecraft:sticky_piston //TODO: minecraft:stone_slab3 //TODO: minecraft:stone_slab4 @@ -571,7 +558,6 @@ class BlockFactory{ //TODO: minecraft:sweet_berry_bush //TODO: minecraft:turtle_egg //TODO: minecraft:undyed_shulker_box - //TODO: minecraft:wood } public static function isInit() : bool{ From 79ef8e080367f6c29243db8bb67146e09c42e466 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 19:36:09 +0000 Subject: [PATCH 0688/3224] Replace all legacy blockID references with BlockIds:: --- src/pocketmine/Player.php | 5 +- src/pocketmine/block/Banner.php | 2 +- src/pocketmine/block/Block.php | 4 +- src/pocketmine/block/BlockFactory.php | 582 +++++++++--------- src/pocketmine/block/Cactus.php | 10 +- src/pocketmine/block/Cake.php | 8 +- src/pocketmine/block/Carpet.php | 4 +- src/pocketmine/block/CoarseDirt.php | 2 +- src/pocketmine/block/CobblestoneWall.php | 2 +- src/pocketmine/block/ConcretePowder.php | 2 +- src/pocketmine/block/Crops.php | 4 +- src/pocketmine/block/Dandelion.php | 2 +- src/pocketmine/block/Dirt.php | 2 +- src/pocketmine/block/Door.php | 2 +- src/pocketmine/block/DoublePlant.php | 2 +- src/pocketmine/block/DragonEgg.php | 2 +- src/pocketmine/block/Farmland.php | 4 +- src/pocketmine/block/Fire.php | 8 +- src/pocketmine/block/Flower.php | 2 +- src/pocketmine/block/Grass.php | 10 +- src/pocketmine/block/GrassPath.php | 2 +- src/pocketmine/block/Ice.php | 2 +- src/pocketmine/block/Lava.php | 6 +- src/pocketmine/block/Liquid.php | 2 +- src/pocketmine/block/MelonStem.php | 2 +- src/pocketmine/block/Mycelium.php | 4 +- src/pocketmine/block/NetherWartPlant.php | 4 +- src/pocketmine/block/PumpkinStem.php | 2 +- src/pocketmine/block/Sapling.php | 2 +- src/pocketmine/block/Sign.php | 2 +- src/pocketmine/block/SnowLayer.php | 2 +- src/pocketmine/block/Stem.php | 2 +- src/pocketmine/block/Sugarcane.php | 18 +- src/pocketmine/block/TNT.php | 2 +- src/pocketmine/block/TallGrass.php | 4 +- src/pocketmine/block/Torch.php | 4 +- src/pocketmine/block/utils/FallableTrait.php | 6 +- src/pocketmine/entity/object/Painting.php | 4 +- .../entity/projectile/EnderPearl.php | 3 +- .../entity/projectile/SplashPotion.php | 10 +- .../event/player/PlayerDeathEvent.php | 4 +- src/pocketmine/item/Banner.php | 3 +- src/pocketmine/item/Bed.php | 3 +- src/pocketmine/item/BeetrootSeeds.php | 3 +- src/pocketmine/item/Bucket.php | 3 +- src/pocketmine/item/Carrot.php | 3 +- src/pocketmine/item/CocoaBeans.php | 3 +- src/pocketmine/item/FlintSteel.php | 5 +- src/pocketmine/item/Item.php | 3 +- src/pocketmine/item/ItemFactory.php | 52 +- src/pocketmine/item/MelonSeeds.php | 3 +- src/pocketmine/item/Potato.php | 3 +- src/pocketmine/item/PumpkinSeeds.php | 3 +- src/pocketmine/item/Redstone.php | 3 +- src/pocketmine/item/Skull.php | 3 +- src/pocketmine/item/StringItem.php | 3 +- src/pocketmine/item/WheatSeeds.php | 3 +- src/pocketmine/level/Explosion.php | 3 +- src/pocketmine/level/Level.php | 2 +- src/pocketmine/level/SimpleChunkManager.php | 3 +- src/pocketmine/level/biome/GrassyBiome.php | 12 +- src/pocketmine/level/biome/OceanBiome.php | 12 +- src/pocketmine/level/biome/RiverBiome.php | 12 +- src/pocketmine/level/biome/SandyBiome.php | 12 +- src/pocketmine/level/biome/SnowyBiome.php | 12 +- src/pocketmine/level/generator/Flat.php | 18 +- .../level/generator/hell/Nether.php | 8 +- .../level/generator/normal/Normal.php | 24 +- .../level/generator/object/BirchTree.php | 4 +- .../level/generator/object/JungleTree.php | 4 +- .../level/generator/object/OakTree.php | 4 +- src/pocketmine/level/generator/object/Ore.php | 6 +- .../level/generator/object/SpruceTree.php | 4 +- .../level/generator/object/TallGrass.php | 9 +- .../level/generator/object/Tree.php | 3 +- .../level/generator/populator/GroundCover.php | 4 +- .../level/generator/populator/TallGrass.php | 8 +- .../level/generator/populator/Tree.php | 6 +- tests/phpunit/block/BlockTest.php | 16 +- 79 files changed, 526 insertions(+), 505 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 9c75e6c4ed..5709ef6cec 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -26,6 +26,7 @@ namespace pocketmine; use pocketmine\block\Bed; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\block\UnknownBlock; use pocketmine\command\Command; use pocketmine\command\CommandSender; @@ -2082,8 +2083,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $block = $target->getSide($face); - if($block->getId() === Block::FIRE){ - $this->level->setBlock($block, BlockFactory::get(Block::AIR)); + if($block->getId() === BlockIds::FIRE){ + $this->level->setBlock($block, BlockFactory::get(BlockIds::AIR)); return true; } diff --git a/src/pocketmine/block/Banner.php b/src/pocketmine/block/Banner.php index 6a0d2605f9..d156f339d4 100644 --- a/src/pocketmine/block/Banner.php +++ b/src/pocketmine/block/Banner.php @@ -163,7 +163,7 @@ class Banner extends Transparent{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::opposite($this->facing))->getId() === self::AIR){ + if($this->getSide(Facing::opposite($this->facing))->getId() === BlockIds::AIR){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 11fe307f8c..27c18f6bdb 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -314,7 +314,7 @@ class Block extends Position implements BlockIds, Metadatable{ if(($t = $this->level->getTile($this)) !== null){ $t->onBlockDestroyed(); } - return $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR)); + return $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::AIR)); } @@ -655,7 +655,7 @@ class Block extends Position implements BlockIds, Metadatable{ return $this->getLevel()->getBlock(Vector3::getSide($side, $step)); } - return BlockFactory::get(Block::AIR, 0, Position::fromObject(Vector3::getSide($side, $step))); + return BlockFactory::get(BlockIds::AIR, 0, Position::fromObject(Vector3::getSide($side, $step))); } /** diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index fdd10eb801..686a549b76 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -75,328 +75,328 @@ class BlockFactory{ self::$diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 8192, false)); self::$blastResistance = \SplFixedArray::fromArray(array_fill(0, 8192, 0)); - self::register(new ActivatorRail(new BID(Block::ACTIVATOR_RAIL, BaseRail::STRAIGHT_NORTH_SOUTH), "Activator Rail")); - self::register(new Air(new BID(Block::AIR), "Air")); - self::register(new Anvil(new BID(Block::ANVIL, Anvil::TYPE_NORMAL), "Anvil")); - self::register(new Anvil(new BID(Block::ANVIL, Anvil::TYPE_SLIGHTLY_DAMAGED), "Slightly Damaged Anvil")); - self::register(new Anvil(new BID(Block::ANVIL, Anvil::TYPE_VERY_DAMAGED), "Very Damaged Anvil")); - self::register(new Banner(new BlockIdentifierFlattened(Block::STANDING_BANNER, Block::WALL_BANNER, 0, ItemIds::BANNER, \pocketmine\tile\Banner::class), "Banner")); - self::register(new Barrier(new BID(Block::BARRIER), "Barrier")); - self::register(new Bed(new BID(Block::BED_BLOCK, 0, ItemIds::BED, \pocketmine\tile\Bed::class), "Bed Block")); - self::register(new Bedrock(new BID(Block::BEDROCK), "Bedrock")); - self::register(new Beetroot(new BID(Block::BEETROOT_BLOCK), "Beetroot Block")); - self::register(new BlueIce(new BID(Block::BLUE_ICE), "Blue Ice")); - self::register(new BoneBlock(new BID(Block::BONE_BLOCK), "Bone Block")); - self::register(new Bookshelf(new BID(Block::BOOKSHELF), "Bookshelf")); - self::register(new BrewingStand(new BID(Block::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND), "Brewing Stand")); - self::register(new BrickStairs(new BID(Block::BRICK_STAIRS), "Brick Stairs")); - self::register(new Bricks(new BID(Block::BRICK_BLOCK), "Bricks")); - self::register(new BrownMushroom(new BID(Block::BROWN_MUSHROOM), "Brown Mushroom")); - self::register(new BrownMushroomBlock(new BID(Block::BROWN_MUSHROOM_BLOCK), "Brown Mushroom Block")); - self::register(new Cactus(new BID(Block::CACTUS), "Cactus")); - self::register(new Cake(new BID(Block::CAKE_BLOCK, 0, ItemIds::CAKE), "Cake")); - self::register(new Carrot(new BID(Block::CARROTS), "Carrot Block")); - self::register(new Chest(new BID(Block::CHEST, 0, null, \pocketmine\tile\Chest::class), "Chest")); - self::register(new Clay(new BID(Block::CLAY_BLOCK), "Clay Block")); - self::register(new Coal(new BID(Block::COAL_BLOCK), "Coal Block")); - self::register(new CoalOre(new BID(Block::COAL_ORE), "Coal Ore")); - self::register(new CoarseDirt(new BID(Block::DIRT, Dirt::COARSE), "Coarse Dirt")); - self::register(new Cobblestone(new BID(Block::COBBLESTONE), "Cobblestone")); - self::register(new Cobblestone(new BID(Block::MOSSY_COBBLESTONE), "Moss Stone")); - self::register(new CobblestoneStairs(new BID(Block::COBBLESTONE_STAIRS), "Cobblestone Stairs")); - self::register(new Cobweb(new BID(Block::COBWEB), "Cobweb")); - self::register(new CocoaBlock(new BID(Block::COCOA), "Cocoa Block")); - self::register(new CraftingTable(new BID(Block::CRAFTING_TABLE), "Crafting Table")); - self::register(new Dandelion(new BID(Block::DANDELION), "Dandelion")); - self::register(new DaylightSensor(new BlockIdentifierFlattened(Block::DAYLIGHT_DETECTOR, Block::DAYLIGHT_DETECTOR_INVERTED), "Daylight Sensor")); - self::register(new DeadBush(new BID(Block::DEADBUSH), "Dead Bush")); - self::register(new DetectorRail(new BID(Block::DETECTOR_RAIL), "Detector Rail")); - self::register(new Diamond(new BID(Block::DIAMOND_BLOCK), "Diamond Block")); - self::register(new DiamondOre(new BID(Block::DIAMOND_ORE), "Diamond Ore")); - self::register(new Dirt(new BID(Block::DIRT, Dirt::NORMAL), "Dirt")); - self::register(new DoublePlant(new BID(Block::DOUBLE_PLANT, 0), "Sunflower")); - self::register(new DoublePlant(new BID(Block::DOUBLE_PLANT, 1), "Lilac")); - self::register(new DoublePlant(new BID(Block::DOUBLE_PLANT, 4), "Rose Bush")); - self::register(new DoublePlant(new BID(Block::DOUBLE_PLANT, 5), "Peony")); - self::register(new DoubleTallGrass(new BID(Block::DOUBLE_PLANT, 2), "Double Tallgrass")); - self::register(new DoubleTallGrass(new BID(Block::DOUBLE_PLANT, 3), "Large Fern")); - self::register(new DragonEgg(new BID(Block::DRAGON_EGG), "Dragon Egg")); - self::register(new Emerald(new BID(Block::EMERALD_BLOCK), "Emerald Block")); - self::register(new EmeraldOre(new BID(Block::EMERALD_ORE), "Emerald Ore")); - self::register(new EnchantingTable(new BID(Block::ENCHANTING_TABLE, 0, null, \pocketmine\tile\EnchantTable::class), "Enchanting Table")); - self::register(new EndPortalFrame(new BID(Block::END_PORTAL_FRAME), "End Portal Frame")); - self::register(new EndRod(new BID(Block::END_ROD), "End Rod")); - self::register(new EndStone(new BID(Block::END_STONE), "End Stone")); - self::register(new EndStoneBricks(new BID(Block::END_BRICKS), "End Stone Bricks")); - self::register(new EnderChest(new BID(Block::ENDER_CHEST, 0, null, \pocketmine\tile\EnderChest::class), "Ender Chest")); - self::register(new Farmland(new BID(Block::FARMLAND), "Farmland")); - self::register(new Fire(new BID(Block::FIRE), "Fire Block")); - self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_ALLIUM), "Allium")); - self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_AZURE_BLUET), "Azure Bluet")); - self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_BLUE_ORCHID), "Blue Orchid")); - self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_CORNFLOWER), "Cornflower")); - self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_LILY_OF_THE_VALLEY), "Lily of the Valley")); - self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_ORANGE_TULIP), "Orange Tulip")); - self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_OXEYE_DAISY), "Oxeye Daisy")); - self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_PINK_TULIP), "Pink Tulip")); - self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_POPPY), "Poppy")); - self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_RED_TULIP), "Red Tulip")); - self::register(new Flower(new BID(Block::RED_FLOWER, Flower::TYPE_WHITE_TULIP), "White Tulip")); - self::register(new FlowerPot(new BID(Block::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, \pocketmine\tile\FlowerPot::class), "Flower Pot")); - self::register(new FrostedIce(new BID(Block::FROSTED_ICE), "Frosted Ice")); - self::register(new Furnace(new BlockIdentifierFlattened(Block::FURNACE, Block::LIT_FURNACE, 0, null, \pocketmine\tile\Furnace::class), "Furnace")); - self::register(new Glass(new BID(Block::GLASS), "Glass")); - self::register(new GlassPane(new BID(Block::GLASS_PANE), "Glass Pane")); - self::register(new GlowingObsidian(new BID(Block::GLOWINGOBSIDIAN), "Glowing Obsidian")); - self::register(new Glowstone(new BID(Block::GLOWSTONE), "Glowstone")); - self::register(new Gold(new BID(Block::GOLD_BLOCK), "Gold Block")); - self::register(new GoldOre(new BID(Block::GOLD_ORE), "Gold Ore")); - self::register(new Grass(new BID(Block::GRASS), "Grass")); - self::register(new GrassPath(new BID(Block::GRASS_PATH), "Grass Path")); - self::register(new Gravel(new BID(Block::GRAVEL), "Gravel")); - self::register(new HardenedClay(new BID(Block::HARDENED_CLAY), "Hardened Clay")); - self::register(new HardenedGlass(new BID(Block::HARD_GLASS), "Hardened Glass")); - self::register(new HardenedGlassPane(new BID(Block::HARD_GLASS_PANE), "Hardened Glass Pane")); - self::register(new HayBale(new BID(Block::HAY_BALE), "Hay Bale")); - self::register(new Ice(new BID(Block::ICE), "Ice")); - self::register(new class(new BID(Block::MONSTER_EGG), "Infested Stone") extends InfestedStone{ + self::register(new ActivatorRail(new BID(BlockIds::ACTIVATOR_RAIL, BaseRail::STRAIGHT_NORTH_SOUTH), "Activator Rail")); + self::register(new Air(new BID(BlockIds::AIR), "Air")); + self::register(new Anvil(new BID(BlockIds::ANVIL, Anvil::TYPE_NORMAL), "Anvil")); + self::register(new Anvil(new BID(BlockIds::ANVIL, Anvil::TYPE_SLIGHTLY_DAMAGED), "Slightly Damaged Anvil")); + self::register(new Anvil(new BID(BlockIds::ANVIL, Anvil::TYPE_VERY_DAMAGED), "Very Damaged Anvil")); + self::register(new Banner(new BlockIdentifierFlattened(BlockIds::STANDING_BANNER, BlockIds::WALL_BANNER, 0, ItemIds::BANNER, \pocketmine\tile\Banner::class), "Banner")); + self::register(new Barrier(new BID(BlockIds::BARRIER), "Barrier")); + self::register(new Bed(new BID(BlockIds::BED_BLOCK, 0, ItemIds::BED, \pocketmine\tile\Bed::class), "Bed Block")); + self::register(new Bedrock(new BID(BlockIds::BEDROCK), "Bedrock")); + self::register(new Beetroot(new BID(BlockIds::BEETROOT_BLOCK), "Beetroot Block")); + self::register(new BlueIce(new BID(BlockIds::BLUE_ICE), "Blue Ice")); + self::register(new BoneBlock(new BID(BlockIds::BONE_BLOCK), "Bone Block")); + self::register(new Bookshelf(new BID(BlockIds::BOOKSHELF), "Bookshelf")); + self::register(new BrewingStand(new BID(BlockIds::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND), "Brewing Stand")); + self::register(new BrickStairs(new BID(BlockIds::BRICK_STAIRS), "Brick Stairs")); + self::register(new Bricks(new BID(BlockIds::BRICK_BLOCK), "Bricks")); + self::register(new BrownMushroom(new BID(BlockIds::BROWN_MUSHROOM), "Brown Mushroom")); + self::register(new BrownMushroomBlock(new BID(BlockIds::BROWN_MUSHROOM_BLOCK), "Brown Mushroom Block")); + self::register(new Cactus(new BID(BlockIds::CACTUS), "Cactus")); + self::register(new Cake(new BID(BlockIds::CAKE_BLOCK, 0, ItemIds::CAKE), "Cake")); + self::register(new Carrot(new BID(BlockIds::CARROTS), "Carrot Block")); + self::register(new Chest(new BID(BlockIds::CHEST, 0, null, \pocketmine\tile\Chest::class), "Chest")); + self::register(new Clay(new BID(BlockIds::CLAY_BLOCK), "Clay Block")); + self::register(new Coal(new BID(BlockIds::COAL_BLOCK), "Coal Block")); + self::register(new CoalOre(new BID(BlockIds::COAL_ORE), "Coal Ore")); + self::register(new CoarseDirt(new BID(BlockIds::DIRT, Dirt::COARSE), "Coarse Dirt")); + self::register(new Cobblestone(new BID(BlockIds::COBBLESTONE), "Cobblestone")); + self::register(new Cobblestone(new BID(BlockIds::MOSSY_COBBLESTONE), "Moss Stone")); + self::register(new CobblestoneStairs(new BID(BlockIds::COBBLESTONE_STAIRS), "Cobblestone Stairs")); + self::register(new Cobweb(new BID(BlockIds::COBWEB), "Cobweb")); + self::register(new CocoaBlock(new BID(BlockIds::COCOA), "Cocoa Block")); + self::register(new CraftingTable(new BID(BlockIds::CRAFTING_TABLE), "Crafting Table")); + self::register(new Dandelion(new BID(BlockIds::DANDELION), "Dandelion")); + self::register(new DaylightSensor(new BlockIdentifierFlattened(BlockIds::DAYLIGHT_DETECTOR, BlockIds::DAYLIGHT_DETECTOR_INVERTED), "Daylight Sensor")); + self::register(new DeadBush(new BID(BlockIds::DEADBUSH), "Dead Bush")); + self::register(new DetectorRail(new BID(BlockIds::DETECTOR_RAIL), "Detector Rail")); + self::register(new Diamond(new BID(BlockIds::DIAMOND_BLOCK), "Diamond Block")); + self::register(new DiamondOre(new BID(BlockIds::DIAMOND_ORE), "Diamond Ore")); + self::register(new Dirt(new BID(BlockIds::DIRT, Dirt::NORMAL), "Dirt")); + self::register(new DoublePlant(new BID(BlockIds::DOUBLE_PLANT, 0), "Sunflower")); + self::register(new DoublePlant(new BID(BlockIds::DOUBLE_PLANT, 1), "Lilac")); + self::register(new DoublePlant(new BID(BlockIds::DOUBLE_PLANT, 4), "Rose Bush")); + self::register(new DoublePlant(new BID(BlockIds::DOUBLE_PLANT, 5), "Peony")); + self::register(new DoubleTallGrass(new BID(BlockIds::DOUBLE_PLANT, 2), "Double Tallgrass")); + self::register(new DoubleTallGrass(new BID(BlockIds::DOUBLE_PLANT, 3), "Large Fern")); + self::register(new DragonEgg(new BID(BlockIds::DRAGON_EGG), "Dragon Egg")); + self::register(new Emerald(new BID(BlockIds::EMERALD_BLOCK), "Emerald Block")); + self::register(new EmeraldOre(new BID(BlockIds::EMERALD_ORE), "Emerald Ore")); + self::register(new EnchantingTable(new BID(BlockIds::ENCHANTING_TABLE, 0, null, \pocketmine\tile\EnchantTable::class), "Enchanting Table")); + self::register(new EndPortalFrame(new BID(BlockIds::END_PORTAL_FRAME), "End Portal Frame")); + self::register(new EndRod(new BID(BlockIds::END_ROD), "End Rod")); + self::register(new EndStone(new BID(BlockIds::END_STONE), "End Stone")); + self::register(new EndStoneBricks(new BID(BlockIds::END_BRICKS), "End Stone Bricks")); + self::register(new EnderChest(new BID(BlockIds::ENDER_CHEST, 0, null, \pocketmine\tile\EnderChest::class), "Ender Chest")); + self::register(new Farmland(new BID(BlockIds::FARMLAND), "Farmland")); + self::register(new Fire(new BID(BlockIds::FIRE), "Fire Block")); + self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_ALLIUM), "Allium")); + self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_AZURE_BLUET), "Azure Bluet")); + self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_BLUE_ORCHID), "Blue Orchid")); + self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_CORNFLOWER), "Cornflower")); + self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_LILY_OF_THE_VALLEY), "Lily of the Valley")); + self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_ORANGE_TULIP), "Orange Tulip")); + self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_OXEYE_DAISY), "Oxeye Daisy")); + self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_PINK_TULIP), "Pink Tulip")); + self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_POPPY), "Poppy")); + self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_RED_TULIP), "Red Tulip")); + self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_WHITE_TULIP), "White Tulip")); + self::register(new FlowerPot(new BID(BlockIds::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, \pocketmine\tile\FlowerPot::class), "Flower Pot")); + self::register(new FrostedIce(new BID(BlockIds::FROSTED_ICE), "Frosted Ice")); + self::register(new Furnace(new BlockIdentifierFlattened(BlockIds::FURNACE, BlockIds::LIT_FURNACE, 0, null, \pocketmine\tile\Furnace::class), "Furnace")); + self::register(new Glass(new BID(BlockIds::GLASS), "Glass")); + self::register(new GlassPane(new BID(BlockIds::GLASS_PANE), "Glass Pane")); + self::register(new GlowingObsidian(new BID(BlockIds::GLOWINGOBSIDIAN), "Glowing Obsidian")); + self::register(new Glowstone(new BID(BlockIds::GLOWSTONE), "Glowstone")); + self::register(new Gold(new BID(BlockIds::GOLD_BLOCK), "Gold Block")); + self::register(new GoldOre(new BID(BlockIds::GOLD_ORE), "Gold Ore")); + self::register(new Grass(new BID(BlockIds::GRASS), "Grass")); + self::register(new GrassPath(new BID(BlockIds::GRASS_PATH), "Grass Path")); + self::register(new Gravel(new BID(BlockIds::GRAVEL), "Gravel")); + self::register(new HardenedClay(new BID(BlockIds::HARDENED_CLAY), "Hardened Clay")); + self::register(new HardenedGlass(new BID(BlockIds::HARD_GLASS), "Hardened Glass")); + self::register(new HardenedGlassPane(new BID(BlockIds::HARD_GLASS_PANE), "Hardened Glass Pane")); + self::register(new HayBale(new BID(BlockIds::HAY_BALE), "Hay Bale")); + self::register(new Ice(new BID(BlockIds::ICE), "Ice")); + self::register(new class(new BID(BlockIds::MONSTER_EGG), "Infested Stone") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [ItemFactory::get(ItemIds::STONE)]; } }); - self::register(new class(new BID(Block::MONSTER_EGG, 1), "Infested Cobblestone") extends InfestedStone{ + self::register(new class(new BID(BlockIds::MONSTER_EGG, 1), "Infested Cobblestone") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [ItemFactory::get(ItemIds::COBBLESTONE)]; } }); - self::register(new class(new BID(Block::MONSTER_EGG, 2), "Infested Stone Brick") extends InfestedStone{ + self::register(new class(new BID(BlockIds::MONSTER_EGG, 2), "Infested Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [ItemFactory::get(ItemIds::STONE_BRICK)]; } }); - self::register(new class(new BID(Block::MONSTER_EGG, 3), "Infested Mossy Stone Brick") extends InfestedStone{ + self::register(new class(new BID(BlockIds::MONSTER_EGG, 3), "Infested Mossy Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [ItemFactory::get(ItemIds::STONE_BRICK, StoneBricks::MOSSY)]; } }); - self::register(new class(new BID(Block::MONSTER_EGG, 4), "Infested Cracked Stone Brick") extends InfestedStone{ + self::register(new class(new BID(BlockIds::MONSTER_EGG, 4), "Infested Cracked Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [ItemFactory::get(ItemIds::STONE_BRICK, StoneBricks::CRACKED)]; } }); - self::register(new class(new BID(Block::MONSTER_EGG, 5), "Infested Chiseled Stone Brick") extends InfestedStone{ + self::register(new class(new BID(BlockIds::MONSTER_EGG, 5), "Infested Chiseled Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [ItemFactory::get(ItemIds::STONE_BRICK, StoneBricks::CHISELED)]; } }); - self::register(new InfoUpdate(new BID(Block::INFO_UPDATE), "update!")); - self::register(new InfoUpdate(new BID(Block::INFO_UPDATE2), "ate!upd")); - self::register(new InvisibleBedrock(new BID(Block::INVISIBLEBEDROCK), "Invisible Bedrock")); - self::register(new Iron(new BID(Block::IRON_BLOCK), "Iron Block")); - self::register(new IronBars(new BID(Block::IRON_BARS), "Iron Bars")); - self::register(new IronDoor(new BID(Block::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door")); - self::register(new IronOre(new BID(Block::IRON_ORE), "Iron Ore")); - self::register(new IronTrapdoor(new BID(Block::IRON_TRAPDOOR), "Iron Trapdoor")); - self::register(new ItemFrame(new BID(Block::FRAME_BLOCK, 0, ItemIds::FRAME, \pocketmine\tile\ItemFrame::class), "Item Frame")); - self::register(new Ladder(new BID(Block::LADDER), "Ladder")); - self::register(new Lapis(new BID(Block::LAPIS_BLOCK), "Lapis Lazuli Block")); - self::register(new LapisOre(new BID(Block::LAPIS_ORE), "Lapis Lazuli Ore")); - self::register(new Lava(new BlockIdentifierFlattened(Block::FLOWING_LAVA, Block::STILL_LAVA), "Lava")); - self::register(new Lever(new BID(Block::LEVER), "Lever")); - self::register(new LitPumpkin(new BID(Block::JACK_O_LANTERN), "Jack o'Lantern")); - self::register(new Magma(new BID(Block::MAGMA), "Magma Block")); - self::register(new Melon(new BID(Block::MELON_BLOCK), "Melon Block")); - self::register(new MelonStem(new BID(Block::MELON_STEM, 0, ItemIds::MELON_SEEDS), "Melon Stem")); - self::register(new MonsterSpawner(new BID(Block::MOB_SPAWNER), "Monster Spawner")); - self::register(new Mycelium(new BID(Block::MYCELIUM), "Mycelium")); - self::register(new NetherBrick(new BID(Block::NETHER_BRICK_BLOCK), "Nether Bricks")); - self::register(new NetherBrick(new BID(Block::RED_NETHER_BRICK), "Red Nether Bricks")); - self::register(new NetherBrickFence(new BID(Block::NETHER_BRICK_FENCE), "Nether Brick Fence")); - self::register(new NetherBrickStairs(new BID(Block::NETHER_BRICK_STAIRS), "Nether Brick Stairs")); - self::register(new NetherPortal(new BID(Block::PORTAL), "Nether Portal")); - self::register(new NetherQuartzOre(new BID(Block::NETHER_QUARTZ_ORE), "Nether Quartz Ore")); - self::register(new NetherReactor(new BID(Block::NETHERREACTOR), "Nether Reactor Core")); - self::register(new NetherWartBlock(new BID(Block::NETHER_WART_BLOCK), "Nether Wart Block")); - self::register(new NetherWartPlant(new BID(Block::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART), "Nether Wart")); - self::register(new Netherrack(new BID(Block::NETHERRACK), "Netherrack")); - self::register(new NoteBlock(new BID(Block::NOTEBLOCK), "Note Block")); - self::register(new Obsidian(new BID(Block::OBSIDIAN), "Obsidian")); - self::register(new PackedIce(new BID(Block::PACKED_ICE), "Packed Ice")); - self::register(new Podzol(new BID(Block::PODZOL), "Podzol")); - self::register(new Potato(new BID(Block::POTATOES), "Potato Block")); - self::register(new PoweredRail(new BID(Block::GOLDEN_RAIL, BaseRail::STRAIGHT_NORTH_SOUTH), "Powered Rail")); - self::register(new Prismarine(new BID(Block::PRISMARINE, Prismarine::BRICKS), "Prismarine Bricks")); - self::register(new Prismarine(new BID(Block::PRISMARINE, Prismarine::DARK), "Dark Prismarine")); - self::register(new Prismarine(new BID(Block::PRISMARINE, Prismarine::NORMAL), "Prismarine")); - self::register(new Pumpkin(new BID(Block::PUMPKIN), "Pumpkin")); - self::register(new PumpkinStem(new BID(Block::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem")); - self::register(new Purpur(new BID(Block::PURPUR_BLOCK), "Purpur Block")); - self::register(new class(new BID(Block::PURPUR_BLOCK, 2), "Purpur Pillar") extends Purpur{ + self::register(new InfoUpdate(new BID(BlockIds::INFO_UPDATE), "update!")); + self::register(new InfoUpdate(new BID(BlockIds::INFO_UPDATE2), "ate!upd")); + self::register(new InvisibleBedrock(new BID(BlockIds::INVISIBLEBEDROCK), "Invisible Bedrock")); + self::register(new Iron(new BID(BlockIds::IRON_BLOCK), "Iron Block")); + self::register(new IronBars(new BID(BlockIds::IRON_BARS), "Iron Bars")); + self::register(new IronDoor(new BID(BlockIds::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door")); + self::register(new IronOre(new BID(BlockIds::IRON_ORE), "Iron Ore")); + self::register(new IronTrapdoor(new BID(BlockIds::IRON_TRAPDOOR), "Iron Trapdoor")); + self::register(new ItemFrame(new BID(BlockIds::FRAME_BLOCK, 0, ItemIds::FRAME, \pocketmine\tile\ItemFrame::class), "Item Frame")); + self::register(new Ladder(new BID(BlockIds::LADDER), "Ladder")); + self::register(new Lapis(new BID(BlockIds::LAPIS_BLOCK), "Lapis Lazuli Block")); + self::register(new LapisOre(new BID(BlockIds::LAPIS_ORE), "Lapis Lazuli Ore")); + self::register(new Lava(new BlockIdentifierFlattened(BlockIds::FLOWING_LAVA, BlockIds::STILL_LAVA), "Lava")); + self::register(new Lever(new BID(BlockIds::LEVER), "Lever")); + self::register(new LitPumpkin(new BID(BlockIds::JACK_O_LANTERN), "Jack o'Lantern")); + self::register(new Magma(new BID(BlockIds::MAGMA), "Magma Block")); + self::register(new Melon(new BID(BlockIds::MELON_BLOCK), "Melon Block")); + self::register(new MelonStem(new BID(BlockIds::MELON_STEM, 0, ItemIds::MELON_SEEDS), "Melon Stem")); + self::register(new MonsterSpawner(new BID(BlockIds::MOB_SPAWNER), "Monster Spawner")); + self::register(new Mycelium(new BID(BlockIds::MYCELIUM), "Mycelium")); + self::register(new NetherBrick(new BID(BlockIds::NETHER_BRICK_BLOCK), "Nether Bricks")); + self::register(new NetherBrick(new BID(BlockIds::RED_NETHER_BRICK), "Red Nether Bricks")); + self::register(new NetherBrickFence(new BID(BlockIds::NETHER_BRICK_FENCE), "Nether Brick Fence")); + self::register(new NetherBrickStairs(new BID(BlockIds::NETHER_BRICK_STAIRS), "Nether Brick Stairs")); + self::register(new NetherPortal(new BID(BlockIds::PORTAL), "Nether Portal")); + self::register(new NetherQuartzOre(new BID(BlockIds::NETHER_QUARTZ_ORE), "Nether Quartz Ore")); + self::register(new NetherReactor(new BID(BlockIds::NETHERREACTOR), "Nether Reactor Core")); + self::register(new NetherWartBlock(new BID(BlockIds::NETHER_WART_BLOCK), "Nether Wart Block")); + self::register(new NetherWartPlant(new BID(BlockIds::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART), "Nether Wart")); + self::register(new Netherrack(new BID(BlockIds::NETHERRACK), "Netherrack")); + self::register(new NoteBlock(new BID(BlockIds::NOTEBLOCK), "Note Block")); + self::register(new Obsidian(new BID(BlockIds::OBSIDIAN), "Obsidian")); + self::register(new PackedIce(new BID(BlockIds::PACKED_ICE), "Packed Ice")); + self::register(new Podzol(new BID(BlockIds::PODZOL), "Podzol")); + self::register(new Potato(new BID(BlockIds::POTATOES), "Potato Block")); + self::register(new PoweredRail(new BID(BlockIds::GOLDEN_RAIL, BaseRail::STRAIGHT_NORTH_SOUTH), "Powered Rail")); + self::register(new Prismarine(new BID(BlockIds::PRISMARINE, Prismarine::BRICKS), "Prismarine Bricks")); + self::register(new Prismarine(new BID(BlockIds::PRISMARINE, Prismarine::DARK), "Dark Prismarine")); + self::register(new Prismarine(new BID(BlockIds::PRISMARINE, Prismarine::NORMAL), "Prismarine")); + self::register(new Pumpkin(new BID(BlockIds::PUMPKIN), "Pumpkin")); + self::register(new PumpkinStem(new BID(BlockIds::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem")); + self::register(new Purpur(new BID(BlockIds::PURPUR_BLOCK), "Purpur Block")); + self::register(new class(new BID(BlockIds::PURPUR_BLOCK, 2), "Purpur Pillar") extends Purpur{ use PillarRotationTrait; }); - self::register(new PurpurStairs(new BID(Block::PURPUR_STAIRS), "Purpur Stairs")); - self::register(new Quartz(new BID(Block::QUARTZ_BLOCK, Quartz::NORMAL), "Quartz Block")); - self::register(new class(new BID(Block::QUARTZ_BLOCK, Quartz::CHISELED), "Chiseled Quartz Block") extends Quartz{ + self::register(new PurpurStairs(new BID(BlockIds::PURPUR_STAIRS), "Purpur Stairs")); + self::register(new Quartz(new BID(BlockIds::QUARTZ_BLOCK, Quartz::NORMAL), "Quartz Block")); + self::register(new class(new BID(BlockIds::QUARTZ_BLOCK, Quartz::CHISELED), "Chiseled Quartz Block") extends Quartz{ use PillarRotationTrait; }); - self::register(new class(new BID(Block::QUARTZ_BLOCK, Quartz::PILLAR), "Quartz Pillar") extends Quartz{ + self::register(new class(new BID(BlockIds::QUARTZ_BLOCK, Quartz::PILLAR), "Quartz Pillar") extends Quartz{ use PillarRotationTrait; }); - self::register(new Quartz(new BID(Block::QUARTZ_BLOCK, Quartz::SMOOTH), "Smooth Quartz Block")); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) - self::register(new QuartzStairs(new BID(Block::QUARTZ_STAIRS), "Quartz Stairs")); - self::register(new Rail(new BID(Block::RAIL), "Rail")); - self::register(new RedMushroom(new BID(Block::RED_MUSHROOM), "Red Mushroom")); - self::register(new RedMushroomBlock(new BID(Block::RED_MUSHROOM_BLOCK), "Red Mushroom Block")); - self::register(new Redstone(new BID(Block::REDSTONE_BLOCK), "Redstone Block")); - self::register(new RedstoneComparator(new BlockIdentifierFlattened(Block::UNPOWERED_COMPARATOR, Block::POWERED_COMPARATOR, 0, ItemIds::COMPARATOR, Comparator::class), "Redstone Comparator")); - self::register(new RedstoneLamp(new BlockIdentifierFlattened(Block::REDSTONE_LAMP, Block::LIT_REDSTONE_LAMP), "Redstone Lamp")); - self::register(new RedstoneOre(new BlockIdentifierFlattened(Block::REDSTONE_ORE, Block::LIT_REDSTONE_ORE), "Redstone Ore")); - self::register(new RedstoneRepeater(new BlockIdentifierFlattened(Block::UNPOWERED_REPEATER, Block::POWERED_REPEATER, 0, ItemIds::REPEATER), "Redstone Repeater")); - self::register(new RedstoneTorch(new BlockIdentifierFlattened(Block::REDSTONE_TORCH, Block::UNLIT_REDSTONE_TORCH), "Redstone Torch")); - self::register(new RedstoneWire(new BID(Block::REDSTONE_WIRE, 0, ItemIds::REDSTONE), "Redstone")); - self::register(new Reserved6(new BID(Block::RESERVED6), "reserved6")); - self::register(new Sand(new BID(Block::SAND), "Sand")); - self::register(new Sand(new BID(Block::SAND, 1), "Red Sand")); - self::register(new SandstoneStairs(new BID(Block::RED_SANDSTONE_STAIRS), "Red Sandstone Stairs")); - self::register(new SandstoneStairs(new BID(Block::SANDSTONE_STAIRS), "Sandstone Stairs")); - self::register(new SeaLantern(new BID(Block::SEALANTERN), "Sea Lantern")); - self::register(new SeaPickle(new BID(Block::SEA_PICKLE), "Sea Pickle")); - self::register(new Skull(new BID(Block::MOB_HEAD_BLOCK, 0, null, \pocketmine\tile\Skull::class), "Mob Head")); - self::register(new SmoothStone(new BID(Block::STONE, Stone::NORMAL), "Stone")); - self::register(new Snow(new BID(Block::SNOW), "Snow Block")); - self::register(new SnowLayer(new BID(Block::SNOW_LAYER), "Snow Layer")); - self::register(new SoulSand(new BID(Block::SOUL_SAND), "Soul Sand")); - self::register(new Sponge(new BID(Block::SPONGE), "Sponge")); - self::register(new Stone(new BID(Block::STONE, Stone::ANDESITE), "Andesite")); - self::register(new Stone(new BID(Block::STONE, Stone::DIORITE), "Diorite")); - self::register(new Stone(new BID(Block::STONE, Stone::GRANITE), "Granite")); - self::register(new Stone(new BID(Block::STONE, Stone::POLISHED_ANDESITE), "Polished Andesite")); - self::register(new Stone(new BID(Block::STONE, Stone::POLISHED_DIORITE), "Polished Diorite")); - self::register(new Stone(new BID(Block::STONE, Stone::POLISHED_GRANITE), "Polished Granite")); - self::register(new StoneBrickStairs(new BID(Block::STONE_BRICK_STAIRS), "Stone Brick Stairs")); - self::register(new StoneBricks(new BID(Block::STONEBRICK, StoneBricks::CHISELED), "Chiseled Stone Bricks")); - self::register(new StoneBricks(new BID(Block::STONEBRICK, StoneBricks::CRACKED), "Cracked Stone Bricks")); - self::register(new StoneBricks(new BID(Block::STONEBRICK, StoneBricks::MOSSY), "Mossy Stone Bricks")); - self::register(new StoneBricks(new BID(Block::STONEBRICK, StoneBricks::NORMAL), "Stone Bricks")); - self::register(new StoneButton(new BID(Block::STONE_BUTTON), "Stone Button")); - self::register(new StonePressurePlate(new BID(Block::STONE_PRESSURE_PLATE), "Stone Pressure Plate")); - self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 0), "Stone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 1), "Sandstone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 2), "Fake Wooden")); - self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 3), "Cobblestone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 4), "Brick")); - self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 5), "Stone Brick")); - self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 6), "Quartz")); - self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB, Block::DOUBLE_STONE_SLAB, 7), "Nether Brick")); - self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 0), "Red Sandstone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 1), "Purpur")); - self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 2), "Prismarine")); - self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 3), "Dark Prismarine")); - self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 4), "Prismarine Bricks")); - self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 5), "Mossy Cobblestone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 6), "Smooth Sandstone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(Block::STONE_SLAB2, Block::DOUBLE_STONE_SLAB2, 7), "Red Nether Brick")); - self::register(new Stonecutter(new BID(Block::STONECUTTER), "Stonecutter")); - self::register(new Sugarcane(new BID(Block::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane")); - self::register(new TNT(new BID(Block::TNT), "TNT")); - self::register(new TallGrass(new BID(Block::TALLGRASS), "Fern")); - self::register(new TallGrass(new BID(Block::TALLGRASS, 1), "Tall Grass")); - self::register(new TallGrass(new BID(Block::TALLGRASS, 2), "Fern")); - self::register(new TallGrass(new BID(Block::TALLGRASS, 3), "Fern")); - self::register(new Torch(new BID(Block::COLORED_TORCH_BP), "Blue Torch")); - self::register(new Torch(new BID(Block::COLORED_TORCH_BP, 8), "Purple Torch")); - self::register(new Torch(new BID(Block::COLORED_TORCH_RG), "Red Torch")); - self::register(new Torch(new BID(Block::COLORED_TORCH_RG, 8), "Green Torch")); - self::register(new Torch(new BID(Block::TORCH), "Torch")); - self::register(new TrappedChest(new BID(Block::TRAPPED_CHEST, 0, null, \pocketmine\tile\Chest::class), "Trapped Chest")); - self::register(new Tripwire(new BID(Block::TRIPWIRE, 0, ItemIds::STRING), "Tripwire")); - self::register(new TripwireHook(new BID(Block::TRIPWIRE_HOOK), "Tripwire Hook")); - self::register(new UnderwaterTorch(new BID(Block::UNDERWATER_TORCH), "Underwater Torch")); - self::register(new Vine(new BID(Block::VINE), "Vines")); - self::register(new Water(new BlockIdentifierFlattened(Block::FLOWING_WATER, Block::STILL_WATER), "Water")); - self::register(new WaterLily(new BID(Block::LILY_PAD), "Lily Pad")); - self::register(new WeightedPressurePlateHeavy(new BID(Block::HEAVY_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Heavy")); - self::register(new WeightedPressurePlateLight(new BID(Block::LIGHT_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Light")); - self::register(new Wheat(new BID(Block::WHEAT_BLOCK), "Wheat Block")); + self::register(new Quartz(new BID(BlockIds::QUARTZ_BLOCK, Quartz::SMOOTH), "Smooth Quartz Block")); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) + self::register(new QuartzStairs(new BID(BlockIds::QUARTZ_STAIRS), "Quartz Stairs")); + self::register(new Rail(new BID(BlockIds::RAIL), "Rail")); + self::register(new RedMushroom(new BID(BlockIds::RED_MUSHROOM), "Red Mushroom")); + self::register(new RedMushroomBlock(new BID(BlockIds::RED_MUSHROOM_BLOCK), "Red Mushroom Block")); + self::register(new Redstone(new BID(BlockIds::REDSTONE_BLOCK), "Redstone Block")); + self::register(new RedstoneComparator(new BlockIdentifierFlattened(BlockIds::UNPOWERED_COMPARATOR, BlockIds::POWERED_COMPARATOR, 0, ItemIds::COMPARATOR, Comparator::class), "Redstone Comparator")); + self::register(new RedstoneLamp(new BlockIdentifierFlattened(BlockIds::REDSTONE_LAMP, BlockIds::LIT_REDSTONE_LAMP), "Redstone Lamp")); + self::register(new RedstoneOre(new BlockIdentifierFlattened(BlockIds::REDSTONE_ORE, BlockIds::LIT_REDSTONE_ORE), "Redstone Ore")); + self::register(new RedstoneRepeater(new BlockIdentifierFlattened(BlockIds::UNPOWERED_REPEATER, BlockIds::POWERED_REPEATER, 0, ItemIds::REPEATER), "Redstone Repeater")); + self::register(new RedstoneTorch(new BlockIdentifierFlattened(BlockIds::REDSTONE_TORCH, BlockIds::UNLIT_REDSTONE_TORCH), "Redstone Torch")); + self::register(new RedstoneWire(new BID(BlockIds::REDSTONE_WIRE, 0, ItemIds::REDSTONE), "Redstone")); + self::register(new Reserved6(new BID(BlockIds::RESERVED6), "reserved6")); + self::register(new Sand(new BID(BlockIds::SAND), "Sand")); + self::register(new Sand(new BID(BlockIds::SAND, 1), "Red Sand")); + self::register(new SandstoneStairs(new BID(BlockIds::RED_SANDSTONE_STAIRS), "Red Sandstone Stairs")); + self::register(new SandstoneStairs(new BID(BlockIds::SANDSTONE_STAIRS), "Sandstone Stairs")); + self::register(new SeaLantern(new BID(BlockIds::SEALANTERN), "Sea Lantern")); + self::register(new SeaPickle(new BID(BlockIds::SEA_PICKLE), "Sea Pickle")); + self::register(new Skull(new BID(BlockIds::MOB_HEAD_BLOCK, 0, null, \pocketmine\tile\Skull::class), "Mob Head")); + self::register(new SmoothStone(new BID(BlockIds::STONE, Stone::NORMAL), "Stone")); + self::register(new Snow(new BID(BlockIds::SNOW), "Snow Block")); + self::register(new SnowLayer(new BID(BlockIds::SNOW_LAYER), "Snow Layer")); + self::register(new SoulSand(new BID(BlockIds::SOUL_SAND), "Soul Sand")); + self::register(new Sponge(new BID(BlockIds::SPONGE), "Sponge")); + self::register(new Stone(new BID(BlockIds::STONE, Stone::ANDESITE), "Andesite")); + self::register(new Stone(new BID(BlockIds::STONE, Stone::DIORITE), "Diorite")); + self::register(new Stone(new BID(BlockIds::STONE, Stone::GRANITE), "Granite")); + self::register(new Stone(new BID(BlockIds::STONE, Stone::POLISHED_ANDESITE), "Polished Andesite")); + self::register(new Stone(new BID(BlockIds::STONE, Stone::POLISHED_DIORITE), "Polished Diorite")); + self::register(new Stone(new BID(BlockIds::STONE, Stone::POLISHED_GRANITE), "Polished Granite")); + self::register(new StoneBrickStairs(new BID(BlockIds::STONE_BRICK_STAIRS), "Stone Brick Stairs")); + self::register(new StoneBricks(new BID(BlockIds::STONEBRICK, StoneBricks::CHISELED), "Chiseled Stone Bricks")); + self::register(new StoneBricks(new BID(BlockIds::STONEBRICK, StoneBricks::CRACKED), "Cracked Stone Bricks")); + self::register(new StoneBricks(new BID(BlockIds::STONEBRICK, StoneBricks::MOSSY), "Mossy Stone Bricks")); + self::register(new StoneBricks(new BID(BlockIds::STONEBRICK, StoneBricks::NORMAL), "Stone Bricks")); + self::register(new StoneButton(new BID(BlockIds::STONE_BUTTON), "Stone Button")); + self::register(new StonePressurePlate(new BID(BlockIds::STONE_PRESSURE_PLATE), "Stone Pressure Plate")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB, BlockIds::DOUBLE_STONE_SLAB, 0), "Stone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB, BlockIds::DOUBLE_STONE_SLAB, 1), "Sandstone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB, BlockIds::DOUBLE_STONE_SLAB, 2), "Fake Wooden")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB, BlockIds::DOUBLE_STONE_SLAB, 3), "Cobblestone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB, BlockIds::DOUBLE_STONE_SLAB, 4), "Brick")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB, BlockIds::DOUBLE_STONE_SLAB, 5), "Stone Brick")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB, BlockIds::DOUBLE_STONE_SLAB, 6), "Quartz")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB, BlockIds::DOUBLE_STONE_SLAB, 7), "Nether Brick")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB2, BlockIds::DOUBLE_STONE_SLAB2, 0), "Red Sandstone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB2, BlockIds::DOUBLE_STONE_SLAB2, 1), "Purpur")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB2, BlockIds::DOUBLE_STONE_SLAB2, 2), "Prismarine")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB2, BlockIds::DOUBLE_STONE_SLAB2, 3), "Dark Prismarine")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB2, BlockIds::DOUBLE_STONE_SLAB2, 4), "Prismarine Bricks")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB2, BlockIds::DOUBLE_STONE_SLAB2, 5), "Mossy Cobblestone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB2, BlockIds::DOUBLE_STONE_SLAB2, 6), "Smooth Sandstone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB2, BlockIds::DOUBLE_STONE_SLAB2, 7), "Red Nether Brick")); + self::register(new Stonecutter(new BID(BlockIds::STONECUTTER), "Stonecutter")); + self::register(new Sugarcane(new BID(BlockIds::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane")); + self::register(new TNT(new BID(BlockIds::TNT), "TNT")); + self::register(new TallGrass(new BID(BlockIds::TALLGRASS), "Fern")); + self::register(new TallGrass(new BID(BlockIds::TALLGRASS, 1), "Tall Grass")); + self::register(new TallGrass(new BID(BlockIds::TALLGRASS, 2), "Fern")); + self::register(new TallGrass(new BID(BlockIds::TALLGRASS, 3), "Fern")); + self::register(new Torch(new BID(BlockIds::COLORED_TORCH_BP), "Blue Torch")); + self::register(new Torch(new BID(BlockIds::COLORED_TORCH_BP, 8), "Purple Torch")); + self::register(new Torch(new BID(BlockIds::COLORED_TORCH_RG), "Red Torch")); + self::register(new Torch(new BID(BlockIds::COLORED_TORCH_RG, 8), "Green Torch")); + self::register(new Torch(new BID(BlockIds::TORCH), "Torch")); + self::register(new TrappedChest(new BID(BlockIds::TRAPPED_CHEST, 0, null, \pocketmine\tile\Chest::class), "Trapped Chest")); + self::register(new Tripwire(new BID(BlockIds::TRIPWIRE, 0, ItemIds::STRING), "Tripwire")); + self::register(new TripwireHook(new BID(BlockIds::TRIPWIRE_HOOK), "Tripwire Hook")); + self::register(new UnderwaterTorch(new BID(BlockIds::UNDERWATER_TORCH), "Underwater Torch")); + self::register(new Vine(new BID(BlockIds::VINE), "Vines")); + self::register(new Water(new BlockIdentifierFlattened(BlockIds::FLOWING_WATER, BlockIds::STILL_WATER), "Water")); + self::register(new WaterLily(new BID(BlockIds::LILY_PAD), "Lily Pad")); + self::register(new WeightedPressurePlateHeavy(new BID(BlockIds::HEAVY_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Heavy")); + self::register(new WeightedPressurePlateLight(new BID(BlockIds::LIGHT_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Light")); + self::register(new Wheat(new BID(BlockIds::WHEAT_BLOCK), "Wheat Block")); /** @var int[]|\SplObjectStorage $woodenStairIds */ $woodenStairIds = new \SplObjectStorage(); - $woodenStairIds[TreeType::OAK()] = Block::OAK_STAIRS; - $woodenStairIds[TreeType::SPRUCE()] = Block::SPRUCE_STAIRS; - $woodenStairIds[TreeType::BIRCH()] = Block::BIRCH_STAIRS; - $woodenStairIds[TreeType::JUNGLE()] = Block::JUNGLE_STAIRS; - $woodenStairIds[TreeType::ACACIA()] = Block::ACACIA_STAIRS; - $woodenStairIds[TreeType::DARK_OAK()] = Block::DARK_OAK_STAIRS; + $woodenStairIds[TreeType::OAK()] = BlockIds::OAK_STAIRS; + $woodenStairIds[TreeType::SPRUCE()] = BlockIds::SPRUCE_STAIRS; + $woodenStairIds[TreeType::BIRCH()] = BlockIds::BIRCH_STAIRS; + $woodenStairIds[TreeType::JUNGLE()] = BlockIds::JUNGLE_STAIRS; + $woodenStairIds[TreeType::ACACIA()] = BlockIds::ACACIA_STAIRS; + $woodenStairIds[TreeType::DARK_OAK()] = BlockIds::DARK_OAK_STAIRS; /** @var int[]|\SplObjectStorage $fenceGateIds */ $fenceGateIds = new \SplObjectStorage(); - $fenceGateIds[TreeType::OAK()] = Block::OAK_FENCE_GATE; - $fenceGateIds[TreeType::SPRUCE()] = Block::SPRUCE_FENCE_GATE; - $fenceGateIds[TreeType::BIRCH()] = Block::BIRCH_FENCE_GATE; - $fenceGateIds[TreeType::JUNGLE()] = Block::JUNGLE_FENCE_GATE; - $fenceGateIds[TreeType::ACACIA()] = Block::ACACIA_FENCE_GATE; - $fenceGateIds[TreeType::DARK_OAK()] = Block::DARK_OAK_FENCE_GATE; + $fenceGateIds[TreeType::OAK()] = BlockIds::OAK_FENCE_GATE; + $fenceGateIds[TreeType::SPRUCE()] = BlockIds::SPRUCE_FENCE_GATE; + $fenceGateIds[TreeType::BIRCH()] = BlockIds::BIRCH_FENCE_GATE; + $fenceGateIds[TreeType::JUNGLE()] = BlockIds::JUNGLE_FENCE_GATE; + $fenceGateIds[TreeType::ACACIA()] = BlockIds::ACACIA_FENCE_GATE; + $fenceGateIds[TreeType::DARK_OAK()] = BlockIds::DARK_OAK_FENCE_GATE; /** @var BID[]|\SplObjectStorage $woodenDoorIds */ $woodenDoorIds = new \SplObjectStorage(); - $woodenDoorIds[TreeType::OAK()] = new BID(Block::OAK_DOOR_BLOCK, 0, ItemIds::OAK_DOOR); - $woodenDoorIds[TreeType::SPRUCE()] = new BID(Block::SPRUCE_DOOR_BLOCK, 0, ItemIds::SPRUCE_DOOR); - $woodenDoorIds[TreeType::BIRCH()] = new BID(Block::BIRCH_DOOR_BLOCK, 0, ItemIds::BIRCH_DOOR); - $woodenDoorIds[TreeType::JUNGLE()] = new BID(Block::JUNGLE_DOOR_BLOCK, 0, ItemIds::JUNGLE_DOOR); - $woodenDoorIds[TreeType::ACACIA()] = new BID(Block::ACACIA_DOOR_BLOCK, 0, ItemIds::ACACIA_DOOR); - $woodenDoorIds[TreeType::DARK_OAK()] = new BID(Block::DARK_OAK_DOOR_BLOCK, 0, ItemIds::DARK_OAK_DOOR); + $woodenDoorIds[TreeType::OAK()] = new BID(BlockIds::OAK_DOOR_BLOCK, 0, ItemIds::OAK_DOOR); + $woodenDoorIds[TreeType::SPRUCE()] = new BID(BlockIds::SPRUCE_DOOR_BLOCK, 0, ItemIds::SPRUCE_DOOR); + $woodenDoorIds[TreeType::BIRCH()] = new BID(BlockIds::BIRCH_DOOR_BLOCK, 0, ItemIds::BIRCH_DOOR); + $woodenDoorIds[TreeType::JUNGLE()] = new BID(BlockIds::JUNGLE_DOOR_BLOCK, 0, ItemIds::JUNGLE_DOOR); + $woodenDoorIds[TreeType::ACACIA()] = new BID(BlockIds::ACACIA_DOOR_BLOCK, 0, ItemIds::ACACIA_DOOR); + $woodenDoorIds[TreeType::DARK_OAK()] = new BID(BlockIds::DARK_OAK_DOOR_BLOCK, 0, ItemIds::DARK_OAK_DOOR); /** @var int[]|\SplObjectStorage $woodenPressurePlateIds */ $woodenPressurePlateIds = new \SplObjectStorage(); - $woodenPressurePlateIds[TreeType::OAK()] = Block::WOODEN_PRESSURE_PLATE; - $woodenPressurePlateIds[TreeType::SPRUCE()] = Block::SPRUCE_PRESSURE_PLATE; - $woodenPressurePlateIds[TreeType::BIRCH()] = Block::BIRCH_PRESSURE_PLATE; - $woodenPressurePlateIds[TreeType::JUNGLE()] = Block::JUNGLE_PRESSURE_PLATE; - $woodenPressurePlateIds[TreeType::ACACIA()] = Block::ACACIA_PRESSURE_PLATE; - $woodenPressurePlateIds[TreeType::DARK_OAK()] = Block::DARK_OAK_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::OAK()] = BlockIds::WOODEN_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::SPRUCE()] = BlockIds::SPRUCE_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::BIRCH()] = BlockIds::BIRCH_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::JUNGLE()] = BlockIds::JUNGLE_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::ACACIA()] = BlockIds::ACACIA_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::DARK_OAK()] = BlockIds::DARK_OAK_PRESSURE_PLATE; /** @var int[]|\SplObjectStorage $woodenButtonIds */ $woodenButtonIds = new \SplObjectStorage(); - $woodenButtonIds[TreeType::OAK()] = Block::WOODEN_BUTTON; - $woodenButtonIds[TreeType::SPRUCE()] = Block::SPRUCE_BUTTON; - $woodenButtonIds[TreeType::BIRCH()] = Block::BIRCH_BUTTON; - $woodenButtonIds[TreeType::JUNGLE()] = Block::JUNGLE_BUTTON; - $woodenButtonIds[TreeType::ACACIA()] = Block::ACACIA_BUTTON; - $woodenButtonIds[TreeType::DARK_OAK()] = Block::DARK_OAK_BUTTON; + $woodenButtonIds[TreeType::OAK()] = BlockIds::WOODEN_BUTTON; + $woodenButtonIds[TreeType::SPRUCE()] = BlockIds::SPRUCE_BUTTON; + $woodenButtonIds[TreeType::BIRCH()] = BlockIds::BIRCH_BUTTON; + $woodenButtonIds[TreeType::JUNGLE()] = BlockIds::JUNGLE_BUTTON; + $woodenButtonIds[TreeType::ACACIA()] = BlockIds::ACACIA_BUTTON; + $woodenButtonIds[TreeType::DARK_OAK()] = BlockIds::DARK_OAK_BUTTON; /** @var int[]|\SplObjectStorage $woodenTrapdoorIds */ $woodenTrapdoorIds = new \SplObjectStorage(); - $woodenTrapdoorIds[TreeType::OAK()] = Block::WOODEN_TRAPDOOR; - $woodenTrapdoorIds[TreeType::SPRUCE()] = Block::SPRUCE_TRAPDOOR; - $woodenTrapdoorIds[TreeType::BIRCH()] = Block::BIRCH_TRAPDOOR; - $woodenTrapdoorIds[TreeType::JUNGLE()] = Block::JUNGLE_TRAPDOOR; - $woodenTrapdoorIds[TreeType::ACACIA()] = Block::ACACIA_TRAPDOOR; - $woodenTrapdoorIds[TreeType::DARK_OAK()] = Block::DARK_OAK_TRAPDOOR; + $woodenTrapdoorIds[TreeType::OAK()] = BlockIds::WOODEN_TRAPDOOR; + $woodenTrapdoorIds[TreeType::SPRUCE()] = BlockIds::SPRUCE_TRAPDOOR; + $woodenTrapdoorIds[TreeType::BIRCH()] = BlockIds::BIRCH_TRAPDOOR; + $woodenTrapdoorIds[TreeType::JUNGLE()] = BlockIds::JUNGLE_TRAPDOOR; + $woodenTrapdoorIds[TreeType::ACACIA()] = BlockIds::ACACIA_TRAPDOOR; + $woodenTrapdoorIds[TreeType::DARK_OAK()] = BlockIds::DARK_OAK_TRAPDOOR; /** @var BlockIdentifierFlattened[]|\SplObjectStorage $woodenSignIds */ $woodenSignIds = new \SplObjectStorage(); - $woodenSignIds[TreeType::OAK()] = new BlockIdentifierFlattened(Block::SIGN_POST, Block::WALL_SIGN, 0, ItemIds::SIGN, \pocketmine\tile\Sign::class); - $woodenSignIds[TreeType::SPRUCE()] = new BlockIdentifierFlattened(Block::SPRUCE_STANDING_SIGN, Block::SPRUCE_WALL_SIGN, 0, ItemIds::SPRUCE_SIGN, \pocketmine\tile\Sign::class); - $woodenSignIds[TreeType::BIRCH()] = new BlockIdentifierFlattened(Block::BIRCH_STANDING_SIGN, Block::BIRCH_WALL_SIGN, 0, ItemIds::BIRCH_SIGN, \pocketmine\tile\Sign::class); - $woodenSignIds[TreeType::JUNGLE()] = new BlockIdentifierFlattened(Block::JUNGLE_STANDING_SIGN, Block::JUNGLE_WALL_SIGN, 0, ItemIds::JUNGLE_SIGN, \pocketmine\tile\Sign::class); - $woodenSignIds[TreeType::ACACIA()] = new BlockIdentifierFlattened(Block::ACACIA_STANDING_SIGN, Block::ACACIA_WALL_SIGN, 0, ItemIds::ACACIA_SIGN, \pocketmine\tile\Sign::class); - $woodenSignIds[TreeType::DARK_OAK()] = new BlockIdentifierFlattened(Block::DARKOAK_STANDING_SIGN, Block::DARKOAK_WALL_SIGN, 0, ItemIds::DARKOAK_SIGN, \pocketmine\tile\Sign::class); + $woodenSignIds[TreeType::OAK()] = new BlockIdentifierFlattened(BlockIds::SIGN_POST, BlockIds::WALL_SIGN, 0, ItemIds::SIGN, \pocketmine\tile\Sign::class); + $woodenSignIds[TreeType::SPRUCE()] = new BlockIdentifierFlattened(BlockIds::SPRUCE_STANDING_SIGN, BlockIds::SPRUCE_WALL_SIGN, 0, ItemIds::SPRUCE_SIGN, \pocketmine\tile\Sign::class); + $woodenSignIds[TreeType::BIRCH()] = new BlockIdentifierFlattened(BlockIds::BIRCH_STANDING_SIGN, BlockIds::BIRCH_WALL_SIGN, 0, ItemIds::BIRCH_SIGN, \pocketmine\tile\Sign::class); + $woodenSignIds[TreeType::JUNGLE()] = new BlockIdentifierFlattened(BlockIds::JUNGLE_STANDING_SIGN, BlockIds::JUNGLE_WALL_SIGN, 0, ItemIds::JUNGLE_SIGN, \pocketmine\tile\Sign::class); + $woodenSignIds[TreeType::ACACIA()] = new BlockIdentifierFlattened(BlockIds::ACACIA_STANDING_SIGN, BlockIds::ACACIA_WALL_SIGN, 0, ItemIds::ACACIA_SIGN, \pocketmine\tile\Sign::class); + $woodenSignIds[TreeType::DARK_OAK()] = new BlockIdentifierFlattened(BlockIds::DARKOAK_STANDING_SIGN, BlockIds::DARKOAK_WALL_SIGN, 0, ItemIds::DARKOAK_SIGN, \pocketmine\tile\Sign::class); foreach(TreeType::getAll() as $treeType){ $magicNumber = $treeType->getMagicNumber(); $name = $treeType->getDisplayName(); - self::register(new Planks(new BID(Block::PLANKS, $magicNumber), $name . " Planks")); - self::register(new Sapling(new BID(Block::SAPLING, $magicNumber), $name . " Sapling", $treeType)); - self::register(new WoodenFence(new BID(Block::FENCE, $magicNumber), $name . " Fence")); - self::register(new WoodenSlab(new BlockIdentifierFlattened(Block::WOODEN_SLAB, Block::DOUBLE_WOODEN_SLAB, $treeType->getMagicNumber()), $treeType->getDisplayName())); + self::register(new Planks(new BID(BlockIds::PLANKS, $magicNumber), $name . " Planks")); + self::register(new Sapling(new BID(BlockIds::SAPLING, $magicNumber), $name . " Sapling", $treeType)); + self::register(new WoodenFence(new BID(BlockIds::FENCE, $magicNumber), $name . " Fence")); + self::register(new WoodenSlab(new BlockIdentifierFlattened(BlockIds::WOODEN_SLAB, BlockIds::DOUBLE_WOODEN_SLAB, $treeType->getMagicNumber()), $treeType->getDisplayName())); //TODO: find a better way to deal with this split - self::register(new Leaves(new BID($magicNumber >= 4 ? Block::LEAVES2 : Block::LEAVES, $magicNumber & 0x03), $name . " Leaves", $treeType)); - self::register(new Log(new BID($magicNumber >= 4 ? Block::LOG2 : Block::LOG, $magicNumber & 0x03), $name . " Log", $treeType)); + self::register(new Leaves(new BID($magicNumber >= 4 ? BlockIds::LEAVES2 : BlockIds::LEAVES, $magicNumber & 0x03), $name . " Leaves", $treeType)); + self::register(new Log(new BID($magicNumber >= 4 ? BlockIds::LOG2 : BlockIds::LOG, $magicNumber & 0x03), $name . " Log", $treeType)); //TODO: the old bug-block needs to be remapped to the new dedicated block - self::register(new Wood(new BID($magicNumber >= 4 ? Block::LOG2 : Block::LOG, ($magicNumber & 0x03) | 0b1100), $name . " Wood", $treeType)); - self::register(new Wood(new BID(Block::WOOD, $magicNumber), $name . " Wood", $treeType)); + self::register(new Wood(new BID($magicNumber >= 4 ? BlockIds::LOG2 : BlockIds::LOG, ($magicNumber & 0x03) | 0b1100), $name . " Wood", $treeType)); + self::register(new Wood(new BID(BlockIds::WOOD, $magicNumber), $name . " Wood", $treeType)); self::register(new FenceGate(new BID($fenceGateIds[$treeType]), $treeType->getDisplayName() . " Fence Gate")); self::register(new WoodenStairs(new BID($woodenStairIds[$treeType]), $treeType->getDisplayName() . " Stairs")); @@ -416,40 +416,40 @@ class BlockFactory{ Sandstone::SMOOTH => "Smooth " ]; foreach($sandstoneTypes as $variant => $prefix){ - self::register(new Sandstone(new BID(Block::SANDSTONE, $variant), $prefix . "Sandstone")); - self::register(new Sandstone(new BID(Block::RED_SANDSTONE, $variant), $prefix . "Red Sandstone")); + self::register(new Sandstone(new BID(BlockIds::SANDSTONE, $variant), $prefix . "Sandstone")); + self::register(new Sandstone(new BID(BlockIds::RED_SANDSTONE, $variant), $prefix . "Red Sandstone")); } /** @var int[]|\SplObjectStorage $glazedTerracottaIds */ $glazedTerracottaIds = new \SplObjectStorage(); - $glazedTerracottaIds[DyeColor::WHITE()] = Block::WHITE_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::ORANGE()] = Block::ORANGE_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::MAGENTA()] = Block::MAGENTA_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::LIGHT_BLUE()] = Block::LIGHT_BLUE_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::YELLOW()] = Block::YELLOW_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::LIME()] = Block::LIME_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::PINK()] = Block::PINK_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::GRAY()] = Block::GRAY_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::LIGHT_GRAY()] = Block::SILVER_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::CYAN()] = Block::CYAN_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::PURPLE()] = Block::PURPLE_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::BLUE()] = Block::BLUE_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::BROWN()] = Block::BROWN_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::GREEN()] = Block::GREEN_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::RED()] = Block::RED_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::BLACK()] = Block::BLACK_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::WHITE()] = BlockIds::WHITE_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::ORANGE()] = BlockIds::ORANGE_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::MAGENTA()] = BlockIds::MAGENTA_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::LIGHT_BLUE()] = BlockIds::LIGHT_BLUE_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::YELLOW()] = BlockIds::YELLOW_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::LIME()] = BlockIds::LIME_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::PINK()] = BlockIds::PINK_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::GRAY()] = BlockIds::GRAY_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::LIGHT_GRAY()] = BlockIds::SILVER_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::CYAN()] = BlockIds::CYAN_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::PURPLE()] = BlockIds::PURPLE_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::BLUE()] = BlockIds::BLUE_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::BROWN()] = BlockIds::BROWN_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::GREEN()] = BlockIds::GREEN_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::RED()] = BlockIds::RED_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::BLACK()] = BlockIds::BLACK_GLAZED_TERRACOTTA; foreach(DyeColor::getAll() as $color){ - self::register(new Carpet(new BID(Block::CARPET, $color->getMagicNumber()), $color->getDisplayName() . " Carpet")); - self::register(new Concrete(new BID(Block::CONCRETE, $color->getMagicNumber()), $color->getDisplayName() . " Concrete")); - self::register(new ConcretePowder(new BID(Block::CONCRETE_POWDER, $color->getMagicNumber()), $color->getDisplayName() . " Concrete Powder")); - self::register(new Glass(new BID(Block::STAINED_GLASS, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass")); - self::register(new GlassPane(new BID(Block::STAINED_GLASS_PANE, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass Pane")); + self::register(new Carpet(new BID(BlockIds::CARPET, $color->getMagicNumber()), $color->getDisplayName() . " Carpet")); + self::register(new Concrete(new BID(BlockIds::CONCRETE, $color->getMagicNumber()), $color->getDisplayName() . " Concrete")); + self::register(new ConcretePowder(new BID(BlockIds::CONCRETE_POWDER, $color->getMagicNumber()), $color->getDisplayName() . " Concrete Powder")); + self::register(new Glass(new BID(BlockIds::STAINED_GLASS, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass")); + self::register(new GlassPane(new BID(BlockIds::STAINED_GLASS_PANE, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass Pane")); self::register(new GlazedTerracotta(new BID($glazedTerracottaIds[$color]), $color->getDisplayName() . " Glazed Terracotta")); - self::register(new HardenedClay(new BID(Block::STAINED_CLAY, $color->getMagicNumber()), $color->getDisplayName() . " Stained Clay")); - self::register(new HardenedGlass(new BID(Block::HARD_STAINED_GLASS, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass")); - self::register(new HardenedGlassPane(new BID(Block::HARD_STAINED_GLASS_PANE, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass Pane")); - self::register(new Wool(new BID(Block::WOOL, $color->getMagicNumber()), $color->getDisplayName() . " Wool")); + self::register(new HardenedClay(new BID(BlockIds::STAINED_CLAY, $color->getMagicNumber()), $color->getDisplayName() . " Stained Clay")); + self::register(new HardenedGlass(new BID(BlockIds::HARD_STAINED_GLASS, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass")); + self::register(new HardenedGlassPane(new BID(BlockIds::HARD_STAINED_GLASS_PANE, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass Pane")); + self::register(new Wool(new BID(BlockIds::WOOL, $color->getMagicNumber()), $color->getDisplayName() . " Wool")); } static $wallTypes = [ @@ -469,7 +469,7 @@ class BlockFactory{ CobblestoneWall::STONE_BRICK_WALL => "Stone Brick" ]; foreach($wallTypes as $magicNumber => $prefix){ - self::register(new CobblestoneWall(new BID(Block::COBBLESTONE_WALL, $magicNumber), $prefix . " Wall")); + self::register(new CobblestoneWall(new BID(BlockIds::COBBLESTONE_WALL, $magicNumber), $prefix . " Wall")); } //TODO: minecraft:andesite_stairs diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index dcf9655200..74842f3552 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -71,7 +71,7 @@ class Cactus extends Transparent{ public function onNearbyBlockChange() : void{ $down = $this->getSide(Facing::DOWN); - if($down->getId() !== self::SAND and $down->getId() !== self::CACTUS){ + if($down->getId() !== BlockIds::SAND and $down->getId() !== BlockIds::CACTUS){ $this->getLevel()->useBreakOn($this); }else{ foreach(Facing::HORIZONTAL as $side){ @@ -89,12 +89,12 @@ class Cactus extends Transparent{ } public function onRandomTick() : void{ - if($this->getSide(Facing::DOWN)->getId() !== self::CACTUS){ + if($this->getSide(Facing::DOWN)->getId() !== BlockIds::CACTUS){ if($this->age === 15){ for($y = 1; $y < 3; ++$y){ $b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z); - if($b->getId() === self::AIR){ - $ev = new BlockGrowEvent($b, BlockFactory::get(Block::CACTUS)); + if($b->getId() === BlockIds::AIR){ + $ev = new BlockGrowEvent($b, BlockFactory::get(BlockIds::CACTUS)); $ev->call(); if($ev->isCancelled()){ break; @@ -115,7 +115,7 @@ class Cactus extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); - if($down->getId() === self::SAND or $down->getId() === self::CACTUS){ + if($down->getId() === BlockIds::SAND or $down->getId() === BlockIds::CACTUS){ foreach(Facing::HORIZONTAL as $side){ if($this->getSide($side)->isSolid()){ return false; diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index ec6e32fdbb..37e9ddb9d1 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -63,7 +63,7 @@ class Cake extends Transparent implements FoodSource{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); - if($down->getId() !== self::AIR){ + if($down->getId() !== BlockIds::AIR){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -71,8 +71,8 @@ class Cake extends Transparent implements FoodSource{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::DOWN)->getId() === self::AIR){ //Replace with common break method - $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR)); + if($this->getSide(Facing::DOWN)->getId() === BlockIds::AIR){ //Replace with common break method + $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::AIR)); } } @@ -112,7 +112,7 @@ class Cake extends Transparent implements FoodSource{ $clone = clone $this; $clone->bites++; if($clone->bites > 6){ - $clone = BlockFactory::get(Block::AIR); + $clone = BlockFactory::get(BlockIds::AIR); } return $clone; } diff --git a/src/pocketmine/block/Carpet.php b/src/pocketmine/block/Carpet.php index bf2974af89..882b06bb5c 100644 --- a/src/pocketmine/block/Carpet.php +++ b/src/pocketmine/block/Carpet.php @@ -45,7 +45,7 @@ class Carpet extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); - if($down->getId() !== self::AIR){ + if($down->getId() !== BlockIds::AIR){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -53,7 +53,7 @@ class Carpet extends Flowable{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::DOWN)->getId() === self::AIR){ + if($this->getSide(Facing::DOWN)->getId() === BlockIds::AIR){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/CoarseDirt.php b/src/pocketmine/block/CoarseDirt.php index 67d606bb18..7791b378af 100644 --- a/src/pocketmine/block/CoarseDirt.php +++ b/src/pocketmine/block/CoarseDirt.php @@ -34,7 +34,7 @@ class CoarseDirt extends Dirt{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP and $item instanceof Hoe){ $item->applyDamage(1); - $this->getLevel()->setBlock($this, BlockFactory::get(Block::DIRT)); + $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::DIRT)); return true; } diff --git a/src/pocketmine/block/CobblestoneWall.php b/src/pocketmine/block/CobblestoneWall.php index ccad87f6e9..3aad8e8c85 100644 --- a/src/pocketmine/block/CobblestoneWall.php +++ b/src/pocketmine/block/CobblestoneWall.php @@ -72,7 +72,7 @@ class CobblestoneWall extends Transparent{ } } - $this->up = $this->getSide(Facing::UP)->getId() !== Block::AIR; + $this->up = $this->getSide(Facing::UP)->getId() !== BlockIds::AIR; } protected function recalculateBoundingBox() : ?AxisAlignedBB{ diff --git a/src/pocketmine/block/ConcretePowder.php b/src/pocketmine/block/ConcretePowder.php index 9b030bd12d..64c85c2ce6 100644 --- a/src/pocketmine/block/ConcretePowder.php +++ b/src/pocketmine/block/ConcretePowder.php @@ -64,7 +64,7 @@ class ConcretePowder extends Solid implements Fallable{ continue; } if($this->getSide($i) instanceof Water){ - return BlockFactory::get(Block::CONCRETE, $this->idInfo->getVariant()); + return BlockFactory::get(BlockIds::CONCRETE, $this->idInfo->getVariant()); } } diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index 771968daa0..fbdd6387c3 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -49,7 +49,7 @@ abstract class Crops extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($blockReplace->getSide(Facing::DOWN)->getId() === Block::FARMLAND){ + if($blockReplace->getSide(Facing::DOWN)->getId() === BlockIds::FARMLAND){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -80,7 +80,7 @@ abstract class Crops extends Flowable{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::DOWN)->getId() !== Block::FARMLAND){ + if($this->getSide(Facing::DOWN)->getId() !== BlockIds::FARMLAND){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/Dandelion.php b/src/pocketmine/block/Dandelion.php index 410d98073e..0c588d2ba0 100644 --- a/src/pocketmine/block/Dandelion.php +++ b/src/pocketmine/block/Dandelion.php @@ -33,7 +33,7 @@ class Dandelion extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); - if($down->getId() === Block::GRASS or $down->getId() === Block::DIRT or $down->getId() === Block::FARMLAND){ + if($down->getId() === BlockIds::GRASS or $down->getId() === BlockIds::DIRT or $down->getId() === BlockIds::FARMLAND){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/pocketmine/block/Dirt.php b/src/pocketmine/block/Dirt.php index c74f42e57a..a7fd382629 100644 --- a/src/pocketmine/block/Dirt.php +++ b/src/pocketmine/block/Dirt.php @@ -44,7 +44,7 @@ class Dirt extends Solid{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP and $item instanceof Hoe){ $item->applyDamage(1); - $this->getLevel()->setBlock($this, BlockFactory::get(Block::FARMLAND)); + $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::FARMLAND)); return true; } diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 461a3878f4..ed7d745461 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -98,7 +98,7 @@ abstract class Door extends Transparent{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::DOWN)->getId() === self::AIR){ //Replace with common break method + if($this->getSide(Facing::DOWN)->getId() === BlockIds::AIR){ //Replace with common break method $this->getLevel()->useBreakOn($this); //this will delete both halves if they exist } } diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index a9dd48ee0f..3f3264a35c 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -49,7 +49,7 @@ class DoublePlant extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $id = $blockReplace->getSide(Facing::DOWN)->getId(); - if(($id === Block::GRASS or $id === Block::DIRT) and $blockReplace->getSide(Facing::UP)->canBeReplaced()){ + if(($id === BlockIds::GRASS or $id === BlockIds::DIRT) and $blockReplace->getSide(Facing::UP)->canBeReplaced()){ $top = clone $this; $top->top = true; diff --git a/src/pocketmine/block/DragonEgg.php b/src/pocketmine/block/DragonEgg.php index cf9c53457f..73c11042fa 100644 --- a/src/pocketmine/block/DragonEgg.php +++ b/src/pocketmine/block/DragonEgg.php @@ -78,7 +78,7 @@ class DragonEgg extends Transparent implements Fallable{ if($block instanceof Air){ $this->level->addParticle($this, new DragonEggTeleportParticle($this->x - $block->x, $this->y - $block->y, $this->z - $block->z)); //TODO: add events - $this->level->setBlock($this, BlockFactory::get(Block::AIR)); + $this->level->setBlock($this, BlockFactory::get(BlockIds::AIR)); $this->level->setBlock($block, $this); break; } diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index 32d9079907..0585568419 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -60,7 +60,7 @@ class Farmland extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::UP)->isSolid()){ - $this->level->setBlock($this, BlockFactory::get(Block::DIRT)); + $this->level->setBlock($this, BlockFactory::get(BlockIds::DIRT)); } } @@ -74,7 +74,7 @@ class Farmland extends Transparent{ $this->wetness--; $this->level->setBlock($this, $this, false); }else{ - $this->level->setBlock($this, BlockFactory::get(Block::DIRT)); + $this->level->setBlock($this, BlockFactory::get(BlockIds::DIRT)); } }elseif($this->wetness < 7){ $this->wetness = 7; diff --git a/src/pocketmine/block/Fire.php b/src/pocketmine/block/Fire.php index faa722df4e..8b0a578df2 100644 --- a/src/pocketmine/block/Fire.php +++ b/src/pocketmine/block/Fire.php @@ -88,7 +88,7 @@ class Fire extends Flowable{ public function onNearbyBlockChange() : void{ if(!$this->getSide(Facing::DOWN)->isSolid() and !$this->hasAdjacentFlammableBlocks()){ - $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR)); + $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::AIR)); }else{ $this->level->scheduleDelayedBlockUpdate($this, mt_rand(30, 40)); } @@ -113,12 +113,12 @@ class Fire extends Flowable{ if($this->age === 15){ if(!$down->isFlammable() and mt_rand(0, 3) === 3){ //1/4 chance to extinguish $canSpread = false; - $result = BlockFactory::get(Block::AIR); + $result = BlockFactory::get(BlockIds::AIR); } }elseif(!$this->hasAdjacentFlammableBlocks()){ $canSpread = false; if(!$down->isSolid() or $this->age > 3){ - $result = BlockFactory::get(Block::AIR); + $result = BlockFactory::get(BlockIds::AIR); } } } @@ -170,7 +170,7 @@ class Fire extends Flowable{ $fire->age = min(15, $fire->age + (mt_rand(0, 4) >> 2)); $this->level->setBlock($block, $fire); }else{ - $this->level->setBlock($block, BlockFactory::get(Block::AIR)); + $this->level->setBlock($block, BlockFactory::get(BlockIds::AIR)); } } } diff --git a/src/pocketmine/block/Flower.php b/src/pocketmine/block/Flower.php index a8465af397..ff8f31b940 100644 --- a/src/pocketmine/block/Flower.php +++ b/src/pocketmine/block/Flower.php @@ -43,7 +43,7 @@ class Flower extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); - if($down->getId() === Block::GRASS or $down->getId() === Block::DIRT or $down->getId() === Block::FARMLAND){ + if($down->getId() === BlockIds::GRASS or $down->getId() === BlockIds::DIRT or $down->getId() === BlockIds::FARMLAND){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index b3d4992b51..9557c25182 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -60,7 +60,7 @@ class Grass extends Solid{ $lightAbove = $this->level->getFullLightAt($this->x, $this->y + 1, $this->z); if($lightAbove < 4 and $this->level->getBlockAt($this->x, $this->y + 1, $this->z)->getLightFilter() >= 2){ //grass dies - $ev = new BlockSpreadEvent($this, $this, BlockFactory::get(Block::DIRT)); + $ev = new BlockSpreadEvent($this, $this, BlockFactory::get(BlockIds::DIRT)); $ev->call(); if(!$ev->isCancelled()){ $this->level->setBlock($this, $ev->getNewState(), false); @@ -82,7 +82,7 @@ class Grass extends Solid{ continue; } - $ev = new BlockSpreadEvent($b, $this, BlockFactory::get(Block::GRASS)); + $ev = new BlockSpreadEvent($b, $this, BlockFactory::get(BlockIds::GRASS)); $ev->call(); if(!$ev->isCancelled()){ $this->level->setBlock($b, $ev->getNewState(), false); @@ -102,12 +102,12 @@ class Grass extends Solid{ return true; }elseif($item instanceof Hoe){ $item->applyDamage(1); - $this->getLevel()->setBlock($this, BlockFactory::get(Block::FARMLAND)); + $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::FARMLAND)); return true; - }elseif($item instanceof Shovel and $this->getSide(Facing::UP)->getId() === Block::AIR){ + }elseif($item instanceof Shovel and $this->getSide(Facing::UP)->getId() === BlockIds::AIR){ $item->applyDamage(1); - $this->getLevel()->setBlock($this, BlockFactory::get(Block::GRASS_PATH)); + $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::GRASS_PATH)); return true; } diff --git a/src/pocketmine/block/GrassPath.php b/src/pocketmine/block/GrassPath.php index e41a4cf08d..ec6c9c53f0 100644 --- a/src/pocketmine/block/GrassPath.php +++ b/src/pocketmine/block/GrassPath.php @@ -44,7 +44,7 @@ class GrassPath extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::UP)->isSolid()){ - $this->level->setBlock($this, BlockFactory::get(Block::DIRT)); + $this->level->setBlock($this, BlockFactory::get(BlockIds::DIRT)); } } diff --git a/src/pocketmine/block/Ice.php b/src/pocketmine/block/Ice.php index 2bbacded16..89f9e20058 100644 --- a/src/pocketmine/block/Ice.php +++ b/src/pocketmine/block/Ice.php @@ -47,7 +47,7 @@ class Ice extends Transparent{ public function onBreak(Item $item, ?Player $player = null) : bool{ if(($player === null or $player->isSurvival()) and !$item->hasEnchantment(Enchantment::SILK_TOUCH())){ - return $this->getLevel()->setBlock($this, BlockFactory::get(Block::WATER)); + return $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::WATER)); } return parent::onBreak($item, $player); } diff --git a/src/pocketmine/block/Lava.php b/src/pocketmine/block/Lava.php index 06a534ce62..1e339927a7 100644 --- a/src/pocketmine/block/Lava.php +++ b/src/pocketmine/block/Lava.php @@ -67,16 +67,16 @@ class Lava extends Liquid{ if($colliding !== null){ if($this->decay === 0){ - $this->liquidCollide($colliding, BlockFactory::get(Block::OBSIDIAN)); + $this->liquidCollide($colliding, BlockFactory::get(BlockIds::OBSIDIAN)); }elseif($this->decay <= 4){ - $this->liquidCollide($colliding, BlockFactory::get(Block::COBBLESTONE)); + $this->liquidCollide($colliding, BlockFactory::get(BlockIds::COBBLESTONE)); } } } protected function flowIntoBlock(Block $block, int $newFlowDecay, bool $falling) : void{ if($block instanceof Water){ - $block->liquidCollide($this, BlockFactory::get(Block::STONE)); + $block->liquidCollide($this, BlockFactory::get(BlockIds::STONE)); }else{ parent::flowIntoBlock($block, $newFlowDecay, $falling); } diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index e9b17e6e43..0c88ef3f98 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -289,7 +289,7 @@ abstract class Liquid extends Transparent{ if($falling !== $this->falling or (!$falling and $newDecay !== $this->decay)){ if(!$falling and $newDecay < 0){ - $this->level->setBlock($this, BlockFactory::get(Block::AIR)); + $this->level->setBlock($this, BlockFactory::get(BlockIds::AIR)); return; } diff --git a/src/pocketmine/block/MelonStem.php b/src/pocketmine/block/MelonStem.php index 4e50519fb3..047912e92b 100644 --- a/src/pocketmine/block/MelonStem.php +++ b/src/pocketmine/block/MelonStem.php @@ -26,6 +26,6 @@ namespace pocketmine\block; class MelonStem extends Stem{ protected function getPlant() : Block{ - return BlockFactory::get(Block::MELON_BLOCK); + return BlockFactory::get(BlockIds::MELON_BLOCK); } } diff --git a/src/pocketmine/block/Mycelium.php b/src/pocketmine/block/Mycelium.php index 63d1c3653c..69a9f5cc1c 100644 --- a/src/pocketmine/block/Mycelium.php +++ b/src/pocketmine/block/Mycelium.php @@ -55,9 +55,9 @@ class Mycelium extends Solid{ $y = mt_rand($this->y - 2, $this->y + 2); $z = mt_rand($this->z - 1, $this->z + 1); $block = $this->getLevel()->getBlockAt($x, $y, $z); - if($block->getId() === Block::DIRT){ + if($block->getId() === BlockIds::DIRT){ if($block->getSide(Facing::UP) instanceof Transparent){ - $ev = new BlockSpreadEvent($block, $this, BlockFactory::get(Block::MYCELIUM)); + $ev = new BlockSpreadEvent($block, $this, BlockFactory::get(BlockIds::MYCELIUM)); $ev->call(); if(!$ev->isCancelled()){ $this->getLevel()->setBlock($block, $ev->getNewState()); diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index c119907d74..995d6dc081 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -51,7 +51,7 @@ class NetherWartPlant extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); - if($down->getId() === Block::SOUL_SAND){ + if($down->getId() === BlockIds::SOUL_SAND){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -59,7 +59,7 @@ class NetherWartPlant extends Flowable{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::DOWN)->getId() !== Block::SOUL_SAND){ + if($this->getSide(Facing::DOWN)->getId() !== BlockIds::SOUL_SAND){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/PumpkinStem.php b/src/pocketmine/block/PumpkinStem.php index 3c28e00e8f..0090a9d681 100644 --- a/src/pocketmine/block/PumpkinStem.php +++ b/src/pocketmine/block/PumpkinStem.php @@ -26,6 +26,6 @@ namespace pocketmine\block; class PumpkinStem extends Stem{ protected function getPlant() : Block{ - return BlockFactory::get(Block::PUMPKIN); + return BlockFactory::get(BlockIds::PUMPKIN); } } diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index 0fa70f3ce8..79e1394e55 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -59,7 +59,7 @@ class Sapling extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); - if($down->getId() === self::GRASS or $down->getId() === self::DIRT or $down->getId() === self::FARMLAND){ + if($down->getId() === BlockIds::GRASS or $down->getId() === BlockIds::DIRT or $down->getId() === BlockIds::FARMLAND){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/pocketmine/block/Sign.php b/src/pocketmine/block/Sign.php index f8527ce6d8..ef1952c474 100644 --- a/src/pocketmine/block/Sign.php +++ b/src/pocketmine/block/Sign.php @@ -126,7 +126,7 @@ class Sign extends Transparent{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::opposite($this->facing))->getId() === self::AIR){ + if($this->getSide(Facing::opposite($this->facing))->getId() === BlockIds::AIR){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index e80b18cf82..1b48fc1fa1 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -96,7 +96,7 @@ class SnowLayer extends Flowable implements Fallable{ public function onRandomTick() : void{ if($this->level->getBlockLightAt($this->x, $this->y, $this->z) >= 12){ - $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), false); + $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::AIR), false); } } diff --git a/src/pocketmine/block/Stem.php b/src/pocketmine/block/Stem.php index 295f6e7185..2d03b7924b 100644 --- a/src/pocketmine/block/Stem.php +++ b/src/pocketmine/block/Stem.php @@ -53,7 +53,7 @@ abstract class Stem extends Crops{ $side = $this->getSide(Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)]); $d = $side->getSide(Facing::DOWN); - if($side->getId() === self::AIR and ($d->getId() === self::FARMLAND or $d->getId() === self::GRASS or $d->getId() === self::DIRT)){ + if($side->getId() === BlockIds::AIR and ($d->getId() === BlockIds::FARMLAND or $d->getId() === BlockIds::GRASS or $d->getId() === BlockIds::DIRT)){ $ev = new BlockGrowEvent($side, $grow); $ev->call(); if(!$ev->isCancelled()){ diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index ef4baba17d..5e539f79d5 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -50,11 +50,11 @@ class Sugarcane extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof Fertilizer){ - if($this->getSide(Facing::DOWN)->getId() !== self::SUGARCANE_BLOCK){ + if($this->getSide(Facing::DOWN)->getId() !== BlockIds::SUGARCANE_BLOCK){ for($y = 1; $y < 3; ++$y){ $b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z); - if($b->getId() === self::AIR){ - $ev = new BlockGrowEvent($b, BlockFactory::get(Block::SUGARCANE_BLOCK)); + if($b->getId() === BlockIds::AIR){ + $ev = new BlockGrowEvent($b, BlockFactory::get(BlockIds::SUGARCANE_BLOCK)); $ev->call(); if($ev->isCancelled()){ break; @@ -78,7 +78,7 @@ class Sugarcane extends Flowable{ public function onNearbyBlockChange() : void{ $down = $this->getSide(Facing::DOWN); - if($down->isTransparent() and $down->getId() !== self::SUGARCANE_BLOCK){ + if($down->isTransparent() and $down->getId() !== BlockIds::SUGARCANE_BLOCK){ $this->getLevel()->useBreakOn($this); } } @@ -88,12 +88,12 @@ class Sugarcane extends Flowable{ } public function onRandomTick() : void{ - if($this->getSide(Facing::DOWN)->getId() !== self::SUGARCANE_BLOCK){ + if($this->getSide(Facing::DOWN)->getId() !== BlockIds::SUGARCANE_BLOCK){ if($this->age === 15){ for($y = 1; $y < 3; ++$y){ $b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z); - if($b->getId() === self::AIR){ - $this->getLevel()->setBlock($b, BlockFactory::get(Block::SUGARCANE_BLOCK)); + if($b->getId() === BlockIds::AIR){ + $this->getLevel()->setBlock($b, BlockFactory::get(BlockIds::SUGARCANE_BLOCK)); break; } } @@ -108,9 +108,9 @@ class Sugarcane extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); - if($down->getId() === self::SUGARCANE_BLOCK){ + if($down->getId() === BlockIds::SUGARCANE_BLOCK){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); - }elseif($down->getId() === self::GRASS or $down->getId() === self::DIRT or $down->getId() === self::SAND){ + }elseif($down->getId() === BlockIds::GRASS or $down->getId() === BlockIds::DIRT or $down->getId() === BlockIds::SAND){ foreach(Facing::HORIZONTAL as $side){ if($down->getSide($side) instanceof Water){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index 3b74bee1cc..741d81524a 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -90,7 +90,7 @@ class TNT extends Solid{ } public function ignite(int $fuse = 80) : void{ - $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR)); + $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::AIR)); $mot = (new Random())->nextSignedFloat() * M_PI * 2; $nbt = EntityFactory::createBaseNBT($this->add(0.5, 0, 0.5), new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02)); diff --git a/src/pocketmine/block/TallGrass.php b/src/pocketmine/block/TallGrass.php index 688a4a47ea..0c3b7f4a4c 100644 --- a/src/pocketmine/block/TallGrass.php +++ b/src/pocketmine/block/TallGrass.php @@ -38,7 +38,7 @@ class TallGrass extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN)->getId(); - if($down === self::GRASS or $down === self::DIRT){ + if($down === BlockIds::GRASS or $down === BlockIds::DIRT){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -47,7 +47,7 @@ class TallGrass extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ //Replace with common break method - $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR)); + $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::AIR)); } } diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index 7e076f7c57..2643398abd 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -54,7 +54,7 @@ class Torch extends Flowable{ $below = $this->getSide(Facing::DOWN); $face = Facing::opposite($this->facing); - if($this->getSide($face)->isTransparent() and !($face === Facing::DOWN and ($below->getId() === self::FENCE or $below->getId() === self::COBBLESTONE_WALL))){ + if($this->getSide($face)->isTransparent() and !($face === Facing::DOWN and ($below->getId() === BlockIds::FENCE or $below->getId() === BlockIds::COBBLESTONE_WALL))){ $this->getLevel()->useBreakOn($this); } } @@ -63,7 +63,7 @@ class Torch extends Flowable{ if($blockClicked->canBeReplaced() and !$blockClicked->getSide(Facing::DOWN)->isTransparent()){ $this->facing = Facing::UP; return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); - }elseif($face !== Facing::DOWN and (!$blockClicked->isTransparent() or ($face === Facing::UP and ($blockClicked->getId() === self::FENCE or $blockClicked->getId() === self::COBBLESTONE_WALL)))){ + }elseif($face !== Facing::DOWN and (!$blockClicked->isTransparent() or ($face === Facing::UP and ($blockClicked->getId() === BlockIds::FENCE or $blockClicked->getId() === BlockIds::COBBLESTONE_WALL)))){ $this->facing = $face; return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); }else{ diff --git a/src/pocketmine/block/utils/FallableTrait.php b/src/pocketmine/block/utils/FallableTrait.php index dfdebf58de..dfb3f36495 100644 --- a/src/pocketmine/block/utils/FallableTrait.php +++ b/src/pocketmine/block/utils/FallableTrait.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\block\utils; -use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\block\Fire; use pocketmine\block\Liquid; use pocketmine\entity\EntityFactory; @@ -48,8 +48,8 @@ trait FallableTrait{ public function onNearbyBlockChange() : void{ $pos = $this->asPosition(); $down = $pos->level->getBlock($pos->getSide(Facing::DOWN)); - if($down->getId() === Block::AIR or $down instanceof Liquid or $down instanceof Fire){ - $pos->level->setBlock($pos, BlockFactory::get(Block::AIR)); + if($down->getId() === BlockIds::AIR or $down instanceof Liquid or $down instanceof Fire){ + $pos->level->setBlock($pos, BlockFactory::get(BlockIds::AIR)); $nbt = EntityFactory::createBaseNBT($pos->add(0.5, 0, 0.5)); $nbt->setInt("TileID", $this->getId()); diff --git a/src/pocketmine/entity/object/Painting.php b/src/pocketmine/entity/object/Painting.php index 0f8b39f956..b2f95f4023 100644 --- a/src/pocketmine/entity/object/Painting.php +++ b/src/pocketmine/entity/object/Painting.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\entity\object; -use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\entity\Entity; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\item\Item; @@ -109,7 +109,7 @@ class Painting extends Entity{ //non-living entities don't have a way to create drops generically yet $this->level->dropItem($this, ItemFactory::get(Item::PAINTING)); } - $this->level->addParticle($this->add(0.5, 0.5, 0.5), new DestroyBlockParticle(BlockFactory::get(Block::PLANKS))); + $this->level->addParticle($this->add(0.5, 0.5, 0.5), new DestroyBlockParticle(BlockFactory::get(BlockIds::PLANKS))); } protected function recalculateBoundingBox() : void{ diff --git a/src/pocketmine/entity/projectile/EnderPearl.php b/src/pocketmine/entity/projectile/EnderPearl.php index 69922eccd4..c1cbab8d16 100644 --- a/src/pocketmine/entity/projectile/EnderPearl.php +++ b/src/pocketmine/entity/projectile/EnderPearl.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity\projectile; use pocketmine\block\Block; +use pocketmine\block\BlockIds; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\level\sound\EndermanTeleportSound; @@ -36,7 +37,7 @@ class EnderPearl extends Throwable{ public const NETWORK_ID = self::ENDER_PEARL; protected function calculateInterceptWithBlock(Block $block, Vector3 $start, Vector3 $end) : ?RayTraceResult{ - if($block->getId() !== Block::AIR and empty($block->getCollisionBoxes())){ + if($block->getId() !== BlockIds::AIR and empty($block->getCollisionBoxes())){ //TODO: remove this once block collision boxes are fixed properly return AxisAlignedBB::one()->offset($block->x, $block->y, $block->z)->calculateIntercept($start, $end); } diff --git a/src/pocketmine/entity/projectile/SplashPotion.php b/src/pocketmine/entity/projectile/SplashPotion.php index 2e3427dd94..36eb780f82 100644 --- a/src/pocketmine/entity/projectile/SplashPotion.php +++ b/src/pocketmine/entity/projectile/SplashPotion.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\entity\projectile; -use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\InstantEffect; use pocketmine\entity\Living; @@ -121,12 +121,12 @@ class SplashPotion extends Throwable{ }elseif($event instanceof ProjectileHitBlockEvent and $this->getPotionId() === Potion::WATER){ $blockIn = $event->getBlockHit()->getSide($event->getRayTraceResult()->getHitFace()); - if($blockIn->getId() === Block::FIRE){ - $this->level->setBlock($blockIn, BlockFactory::get(Block::AIR)); + if($blockIn->getId() === BlockIds::FIRE){ + $this->level->setBlock($blockIn, BlockFactory::get(BlockIds::AIR)); } foreach($blockIn->getHorizontalSides() as $horizontalSide){ - if($horizontalSide->getId() === Block::FIRE){ - $this->level->setBlock($horizontalSide, BlockFactory::get(Block::AIR)); + if($horizontalSide->getId() === BlockIds::FIRE){ + $this->level->setBlock($horizontalSide, BlockFactory::get(BlockIds::AIR)); } } } diff --git a/src/pocketmine/event/player/PlayerDeathEvent.php b/src/pocketmine/event/player/PlayerDeathEvent.php index fa93a8ae28..634f53f758 100644 --- a/src/pocketmine/event/player/PlayerDeathEvent.php +++ b/src/pocketmine/event/player/PlayerDeathEvent.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\event\player; -use pocketmine\block\Block; +use pocketmine\block\BlockIds; use pocketmine\entity\Living; use pocketmine\event\entity\EntityDamageByBlockEvent; use pocketmine\event\entity\EntityDamageByEntityEvent; @@ -170,7 +170,7 @@ class PlayerDeathEvent extends EntityDeathEvent{ case EntityDamageEvent::CAUSE_CONTACT: if($deathCause instanceof EntityDamageByBlockEvent){ - if($deathCause->getDamager()->getId() === Block::CACTUS){ + if($deathCause->getDamager()->getId() === BlockIds::CACTUS){ $message = "death.attack.cactus"; } } diff --git a/src/pocketmine/item/Banner.php b/src/pocketmine/item/Banner.php index 08126eb023..0425a4f376 100644 --- a/src/pocketmine/item/Banner.php +++ b/src/pocketmine/item/Banner.php @@ -26,6 +26,7 @@ namespace pocketmine\item; use Ds\Deque; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\block\utils\BannerPattern; use pocketmine\block\utils\DyeColor; use pocketmine\nbt\tag\CompoundTag; @@ -53,7 +54,7 @@ class Banner extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(Block::STANDING_BANNER); + return BlockFactory::get(BlockIds::STANDING_BANNER); } public function getMaxStackSize() : int{ diff --git a/src/pocketmine/item/Bed.php b/src/pocketmine/item/Bed.php index 27eb8cab64..9c0a16271b 100644 --- a/src/pocketmine/item/Bed.php +++ b/src/pocketmine/item/Bed.php @@ -25,6 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\block\utils\DyeColor; class Bed extends Item{ @@ -45,7 +46,7 @@ class Bed extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(Block::BED_BLOCK); + return BlockFactory::get(BlockIds::BED_BLOCK); } public function getMaxStackSize() : int{ diff --git a/src/pocketmine/item/BeetrootSeeds.php b/src/pocketmine/item/BeetrootSeeds.php index 0243fd6d65..ce33238165 100644 --- a/src/pocketmine/item/BeetrootSeeds.php +++ b/src/pocketmine/item/BeetrootSeeds.php @@ -25,6 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; class BeetrootSeeds extends Item{ public function __construct(){ @@ -32,6 +33,6 @@ class BeetrootSeeds extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(Block::BEETROOT_BLOCK); + return BlockFactory::get(BlockIds::BEETROOT_BLOCK); } } diff --git a/src/pocketmine/item/Bucket.php b/src/pocketmine/item/Bucket.php index 2b850f749b..7c7abc5a06 100644 --- a/src/pocketmine/item/Bucket.php +++ b/src/pocketmine/item/Bucket.php @@ -25,6 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\block\Liquid; use pocketmine\event\player\PlayerBucketFillEvent; use pocketmine\math\Vector3; @@ -46,7 +47,7 @@ class Bucket extends Item{ $ev = new PlayerBucketFillEvent($player, $blockReplace, $face, $this, $resultItem); $ev->call(); if(!$ev->isCancelled()){ - $player->getLevel()->setBlock($blockClicked, BlockFactory::get(Block::AIR)); + $player->getLevel()->setBlock($blockClicked, BlockFactory::get(BlockIds::AIR)); $player->getLevel()->broadcastLevelSoundEvent($blockClicked->add(0.5, 0.5, 0.5), $blockClicked->getBucketFillSound()); if($player->isSurvival()){ if($stack->getCount() === 0){ diff --git a/src/pocketmine/item/Carrot.php b/src/pocketmine/item/Carrot.php index fb70484ed0..7bd2f211eb 100644 --- a/src/pocketmine/item/Carrot.php +++ b/src/pocketmine/item/Carrot.php @@ -25,6 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; class Carrot extends Food{ public function __construct(){ @@ -32,7 +33,7 @@ class Carrot extends Food{ } public function getBlock() : Block{ - return BlockFactory::get(Block::CARROT_BLOCK); + return BlockFactory::get(BlockIds::CARROT_BLOCK); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/CocoaBeans.php b/src/pocketmine/item/CocoaBeans.php index 18ad28c5db..69fff936f3 100644 --- a/src/pocketmine/item/CocoaBeans.php +++ b/src/pocketmine/item/CocoaBeans.php @@ -25,10 +25,11 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; class CocoaBeans extends Item{ public function getBlock() : Block{ - return BlockFactory::get(Block::COCOA); + return BlockFactory::get(BlockIds::COCOA); } } diff --git a/src/pocketmine/item/FlintSteel.php b/src/pocketmine/item/FlintSteel.php index 4bd735a7ea..21673d9821 100644 --- a/src/pocketmine/item/FlintSteel.php +++ b/src/pocketmine/item/FlintSteel.php @@ -25,6 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\Player; @@ -36,10 +37,10 @@ class FlintSteel extends Tool{ } public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ - if($blockReplace->getId() === Block::AIR){ + if($blockReplace->getId() === BlockIds::AIR){ $level = $player->getLevel(); assert($level !== null); - $level->setBlock($blockReplace, BlockFactory::get(Block::FIRE)); + $level->setBlock($blockReplace, BlockFactory::get(BlockIds::FIRE)); $level->broadcastLevelSoundEvent($blockReplace->add(0.5, 0.5, 0.5), LevelSoundEventPacket::SOUND_IGNITE); $this->applyDamage(1); diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index c4efba3aee..8f4f4dd435 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -28,6 +28,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\block\BlockToolType; use pocketmine\entity\Entity; use pocketmine\item\enchantment\Enchantment; @@ -590,7 +591,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return Block */ public function getBlock() : Block{ - return BlockFactory::get(Block::AIR); + return BlockFactory::get(BlockIds::AIR); } /** diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 987165dcbd..1ba8f1b362 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\SkullType; use pocketmine\block\utils\TreeType; @@ -156,23 +156,23 @@ class ItemFactory{ self::register(new Item(Item::SUGAR, 0, "Sugar")); self::register(new Item(Item::TURTLE_SHELL_PIECE, 0, "Scute")); self::register(new Item(Item::WHEAT, 0, "Wheat")); - self::register(new ItemBlock(Block::ACACIA_DOOR_BLOCK, 0, Item::ACACIA_DOOR)); - self::register(new ItemBlock(Block::BIRCH_DOOR_BLOCK, 0, Item::BIRCH_DOOR)); - self::register(new ItemBlock(Block::BREWING_STAND_BLOCK, 0, Item::BREWING_STAND)); - self::register(new ItemBlock(Block::CAKE_BLOCK, 0, Item::CAKE)); - self::register(new ItemBlock(Block::CAULDRON_BLOCK, 0, Item::CAULDRON)); - self::register(new ItemBlock(Block::COMPARATOR_BLOCK, 0, Item::COMPARATOR)); - self::register(new ItemBlock(Block::DARK_OAK_DOOR_BLOCK, 0, Item::DARK_OAK_DOOR)); - self::register(new ItemBlock(Block::FLOWER_POT_BLOCK, 0, Item::FLOWER_POT)); - self::register(new ItemBlock(Block::HOPPER_BLOCK, 0, Item::HOPPER)); - self::register(new ItemBlock(Block::IRON_DOOR_BLOCK, 0, Item::IRON_DOOR)); - self::register(new ItemBlock(Block::ITEM_FRAME_BLOCK, 0, Item::ITEM_FRAME)); - self::register(new ItemBlock(Block::JUNGLE_DOOR_BLOCK, 0, Item::JUNGLE_DOOR)); - self::register(new ItemBlock(Block::NETHER_WART_PLANT, 0, Item::NETHER_WART)); - self::register(new ItemBlock(Block::OAK_DOOR_BLOCK, 0, Item::OAK_DOOR)); - self::register(new ItemBlock(Block::REPEATER_BLOCK, 0, Item::REPEATER)); - self::register(new ItemBlock(Block::SPRUCE_DOOR_BLOCK, 0, Item::SPRUCE_DOOR)); - self::register(new ItemBlock(Block::SUGARCANE_BLOCK, 0, Item::SUGARCANE)); + self::register(new ItemBlock(BlockIds::ACACIA_DOOR_BLOCK, 0, Item::ACACIA_DOOR)); + self::register(new ItemBlock(BlockIds::BIRCH_DOOR_BLOCK, 0, Item::BIRCH_DOOR)); + self::register(new ItemBlock(BlockIds::BREWING_STAND_BLOCK, 0, Item::BREWING_STAND)); + self::register(new ItemBlock(BlockIds::CAKE_BLOCK, 0, Item::CAKE)); + self::register(new ItemBlock(BlockIds::CAULDRON_BLOCK, 0, Item::CAULDRON)); + self::register(new ItemBlock(BlockIds::COMPARATOR_BLOCK, 0, Item::COMPARATOR)); + self::register(new ItemBlock(BlockIds::DARK_OAK_DOOR_BLOCK, 0, Item::DARK_OAK_DOOR)); + self::register(new ItemBlock(BlockIds::FLOWER_POT_BLOCK, 0, Item::FLOWER_POT)); + self::register(new ItemBlock(BlockIds::HOPPER_BLOCK, 0, Item::HOPPER)); + self::register(new ItemBlock(BlockIds::IRON_DOOR_BLOCK, 0, Item::IRON_DOOR)); + self::register(new ItemBlock(BlockIds::ITEM_FRAME_BLOCK, 0, Item::ITEM_FRAME)); + self::register(new ItemBlock(BlockIds::JUNGLE_DOOR_BLOCK, 0, Item::JUNGLE_DOOR)); + self::register(new ItemBlock(BlockIds::NETHER_WART_PLANT, 0, Item::NETHER_WART)); + self::register(new ItemBlock(BlockIds::OAK_DOOR_BLOCK, 0, Item::OAK_DOOR)); + self::register(new ItemBlock(BlockIds::REPEATER_BLOCK, 0, Item::REPEATER)); + self::register(new ItemBlock(BlockIds::SPRUCE_DOOR_BLOCK, 0, Item::SPRUCE_DOOR)); + self::register(new ItemBlock(BlockIds::SUGARCANE_BLOCK, 0, Item::SUGARCANE)); self::register(new Leggings(Item::CHAIN_LEGGINGS, 0, "Chainmail Leggings", new ArmorTypeInfo(4, 226))); self::register(new Leggings(Item::DIAMOND_LEGGINGS, 0, "Diamond Leggings", new ArmorTypeInfo(6, 496))); self::register(new Leggings(Item::GOLDEN_LEGGINGS, 0, "Gold Leggings", new ArmorTypeInfo(3, 106))); @@ -180,8 +180,8 @@ class ItemFactory{ self::register(new Leggings(Item::LEATHER_LEGGINGS, 0, "Leather Pants", new ArmorTypeInfo(2, 76))); //TODO: fix metadata for buckets with still liquid in them //the meta values are intentionally hardcoded because block IDs will change in the future - self::register(new LiquidBucket(Item::BUCKET, 8, "Water Bucket", Block::FLOWING_WATER)); - self::register(new LiquidBucket(Item::BUCKET, 10, "Lava Bucket", Block::FLOWING_LAVA)); + self::register(new LiquidBucket(Item::BUCKET, 8, "Water Bucket", BlockIds::FLOWING_WATER)); + self::register(new LiquidBucket(Item::BUCKET, 10, "Lava Bucket", BlockIds::FLOWING_LAVA)); self::register(new Melon()); self::register(new MelonSeeds()); self::register(new MilkBucket(Item::BUCKET, 1, "Milk Bucket")); @@ -214,12 +214,12 @@ class ItemFactory{ self::register(new Shovel(Item::IRON_SHOVEL, "Iron Shovel", TieredTool::TIER_IRON)); self::register(new Shovel(Item::STONE_SHOVEL, "Stone Shovel", TieredTool::TIER_STONE)); self::register(new Shovel(Item::WOODEN_SHOVEL, "Wooden Shovel", TieredTool::TIER_WOODEN)); - self::register(new Sign(Block::STANDING_SIGN, 0, Item::SIGN)); - self::register(new Sign(Block::SPRUCE_STANDING_SIGN, 0, Item::SPRUCE_SIGN)); - self::register(new Sign(Block::BIRCH_STANDING_SIGN, 0, Item::BIRCH_SIGN)); - self::register(new Sign(Block::JUNGLE_STANDING_SIGN, 0, Item::JUNGLE_SIGN)); - self::register(new Sign(Block::ACACIA_STANDING_SIGN, 0, Item::ACACIA_SIGN)); - self::register(new Sign(Block::DARKOAK_STANDING_SIGN, 0, Item::DARKOAK_SIGN)); + self::register(new Sign(BlockIds::STANDING_SIGN, 0, Item::SIGN)); + self::register(new Sign(BlockIds::SPRUCE_STANDING_SIGN, 0, Item::SPRUCE_SIGN)); + self::register(new Sign(BlockIds::BIRCH_STANDING_SIGN, 0, Item::BIRCH_SIGN)); + self::register(new Sign(BlockIds::JUNGLE_STANDING_SIGN, 0, Item::JUNGLE_SIGN)); + self::register(new Sign(BlockIds::ACACIA_STANDING_SIGN, 0, Item::ACACIA_SIGN)); + self::register(new Sign(BlockIds::DARKOAK_STANDING_SIGN, 0, Item::DARKOAK_SIGN)); self::register(new Snowball()); self::register(new SpiderEye()); self::register(new Steak()); diff --git a/src/pocketmine/item/MelonSeeds.php b/src/pocketmine/item/MelonSeeds.php index 0f359b9db7..41741d8d34 100644 --- a/src/pocketmine/item/MelonSeeds.php +++ b/src/pocketmine/item/MelonSeeds.php @@ -25,6 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; class MelonSeeds extends Item{ public function __construct(){ @@ -32,6 +33,6 @@ class MelonSeeds extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(Block::MELON_STEM); + return BlockFactory::get(BlockIds::MELON_STEM); } } diff --git a/src/pocketmine/item/Potato.php b/src/pocketmine/item/Potato.php index f7278e93ea..07aba80db2 100644 --- a/src/pocketmine/item/Potato.php +++ b/src/pocketmine/item/Potato.php @@ -25,6 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; class Potato extends Food{ public function __construct(){ @@ -32,7 +33,7 @@ class Potato extends Food{ } public function getBlock() : Block{ - return BlockFactory::get(Block::POTATO_BLOCK); + return BlockFactory::get(BlockIds::POTATO_BLOCK); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/PumpkinSeeds.php b/src/pocketmine/item/PumpkinSeeds.php index 01ec1a6e1e..4f5b0dd847 100644 --- a/src/pocketmine/item/PumpkinSeeds.php +++ b/src/pocketmine/item/PumpkinSeeds.php @@ -25,6 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; class PumpkinSeeds extends Item{ public function __construct(){ @@ -32,6 +33,6 @@ class PumpkinSeeds extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(Block::PUMPKIN_STEM); + return BlockFactory::get(BlockIds::PUMPKIN_STEM); } } diff --git a/src/pocketmine/item/Redstone.php b/src/pocketmine/item/Redstone.php index a67f8365a9..c89d3a9d23 100644 --- a/src/pocketmine/item/Redstone.php +++ b/src/pocketmine/item/Redstone.php @@ -25,6 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; class Redstone extends Item{ public function __construct(){ @@ -32,6 +33,6 @@ class Redstone extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(Block::REDSTONE_WIRE); + return BlockFactory::get(BlockIds::REDSTONE_WIRE); } } diff --git a/src/pocketmine/item/Skull.php b/src/pocketmine/item/Skull.php index 8ad4272434..ff7e98090b 100644 --- a/src/pocketmine/item/Skull.php +++ b/src/pocketmine/item/Skull.php @@ -25,6 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\block\utils\SkullType; class Skull extends Item{ @@ -38,7 +39,7 @@ class Skull extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(Block::SKULL_BLOCK); + return BlockFactory::get(BlockIds::SKULL_BLOCK); } public function getSkullType() : SkullType{ diff --git a/src/pocketmine/item/StringItem.php b/src/pocketmine/item/StringItem.php index c3023b82c1..9367678bd1 100644 --- a/src/pocketmine/item/StringItem.php +++ b/src/pocketmine/item/StringItem.php @@ -25,6 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; class StringItem extends Item{ public function __construct(){ @@ -32,6 +33,6 @@ class StringItem extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(Block::TRIPWIRE); + return BlockFactory::get(BlockIds::TRIPWIRE); } } diff --git a/src/pocketmine/item/WheatSeeds.php b/src/pocketmine/item/WheatSeeds.php index 538d56368f..8c4ff62d39 100644 --- a/src/pocketmine/item/WheatSeeds.php +++ b/src/pocketmine/item/WheatSeeds.php @@ -25,6 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; class WheatSeeds extends Item{ public function __construct(){ @@ -32,6 +33,6 @@ class WheatSeeds extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(Block::WHEAT_BLOCK); + return BlockFactory::get(BlockIds::WHEAT_BLOCK); } } diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index b92516a0b3..3c89f982fd 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -25,6 +25,7 @@ namespace pocketmine\level; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\block\TNT; use pocketmine\entity\Entity; use pocketmine\event\block\BlockUpdateEvent; @@ -199,7 +200,7 @@ class Explosion{ $air = ItemFactory::air(); - $airBlock = BlockFactory::get(Block::AIR); + $airBlock = BlockFactory::get(BlockIds::AIR); foreach($this->affectedBlocks as $block){ if($block instanceof TNT){ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 150dd15dc6..f9c5806643 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1803,7 +1803,7 @@ class Level implements ChunkManager, Metadatable{ return false; } - if($blockClicked->getId() === Block::AIR){ + if($blockClicked->getId() === BlockIds::AIR){ return false; } diff --git a/src/pocketmine/level/SimpleChunkManager.php b/src/pocketmine/level/SimpleChunkManager.php index 6d019cc204..20cf014702 100644 --- a/src/pocketmine/level/SimpleChunkManager.php +++ b/src/pocketmine/level/SimpleChunkManager.php @@ -25,6 +25,7 @@ namespace pocketmine\level; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\level\format\Chunk; use const INT32_MAX; use const INT32_MIN; @@ -49,7 +50,7 @@ class SimpleChunkManager implements ChunkManager{ if($chunk = $this->getChunk($x >> 4, $z >> 4)){ return BlockFactory::fromFullBlock($chunk->getFullBlock($x & 0xf, $y, $z & 0xf)); } - return BlockFactory::get(Block::AIR); + return BlockFactory::get(BlockIds::AIR); } public function setBlockAt(int $x, int $y, int $z, Block $block) : bool{ diff --git a/src/pocketmine/level/biome/GrassyBiome.php b/src/pocketmine/level/biome/GrassyBiome.php index ad327b6599..db44ed38a7 100644 --- a/src/pocketmine/level/biome/GrassyBiome.php +++ b/src/pocketmine/level/biome/GrassyBiome.php @@ -23,18 +23,18 @@ declare(strict_types=1); namespace pocketmine\level\biome; -use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; abstract class GrassyBiome extends Biome{ public function __construct(){ $this->setGroundCover([ - BlockFactory::get(Block::GRASS), - BlockFactory::get(Block::DIRT), - BlockFactory::get(Block::DIRT), - BlockFactory::get(Block::DIRT), - BlockFactory::get(Block::DIRT) + BlockFactory::get(BlockIds::GRASS), + BlockFactory::get(BlockIds::DIRT), + BlockFactory::get(BlockIds::DIRT), + BlockFactory::get(BlockIds::DIRT), + BlockFactory::get(BlockIds::DIRT) ]); } } diff --git a/src/pocketmine/level/biome/OceanBiome.php b/src/pocketmine/level/biome/OceanBiome.php index 174ac70e4e..f2e36c04ae 100644 --- a/src/pocketmine/level/biome/OceanBiome.php +++ b/src/pocketmine/level/biome/OceanBiome.php @@ -23,19 +23,19 @@ declare(strict_types=1); namespace pocketmine\level\biome; -use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\level\generator\populator\TallGrass; class OceanBiome extends Biome{ public function __construct(){ $this->setGroundCover([ - BlockFactory::get(Block::GRAVEL), - BlockFactory::get(Block::GRAVEL), - BlockFactory::get(Block::GRAVEL), - BlockFactory::get(Block::GRAVEL), - BlockFactory::get(Block::GRAVEL) + BlockFactory::get(BlockIds::GRAVEL), + BlockFactory::get(BlockIds::GRAVEL), + BlockFactory::get(BlockIds::GRAVEL), + BlockFactory::get(BlockIds::GRAVEL), + BlockFactory::get(BlockIds::GRAVEL) ]); $tallGrass = new TallGrass(); diff --git a/src/pocketmine/level/biome/RiverBiome.php b/src/pocketmine/level/biome/RiverBiome.php index f52c978617..3ad29767c1 100644 --- a/src/pocketmine/level/biome/RiverBiome.php +++ b/src/pocketmine/level/biome/RiverBiome.php @@ -23,19 +23,19 @@ declare(strict_types=1); namespace pocketmine\level\biome; -use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\level\generator\populator\TallGrass; class RiverBiome extends Biome{ public function __construct(){ $this->setGroundCover([ - BlockFactory::get(Block::DIRT), - BlockFactory::get(Block::DIRT), - BlockFactory::get(Block::DIRT), - BlockFactory::get(Block::DIRT), - BlockFactory::get(Block::DIRT) + BlockFactory::get(BlockIds::DIRT), + BlockFactory::get(BlockIds::DIRT), + BlockFactory::get(BlockIds::DIRT), + BlockFactory::get(BlockIds::DIRT), + BlockFactory::get(BlockIds::DIRT) ]); $tallGrass = new TallGrass(); diff --git a/src/pocketmine/level/biome/SandyBiome.php b/src/pocketmine/level/biome/SandyBiome.php index e033c10e68..c165eca909 100644 --- a/src/pocketmine/level/biome/SandyBiome.php +++ b/src/pocketmine/level/biome/SandyBiome.php @@ -23,18 +23,18 @@ declare(strict_types=1); namespace pocketmine\level\biome; -use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; abstract class SandyBiome extends Biome{ public function __construct(){ $this->setGroundCover([ - BlockFactory::get(Block::SAND), - BlockFactory::get(Block::SAND), - BlockFactory::get(Block::SANDSTONE), - BlockFactory::get(Block::SANDSTONE), - BlockFactory::get(Block::SANDSTONE) + BlockFactory::get(BlockIds::SAND), + BlockFactory::get(BlockIds::SAND), + BlockFactory::get(BlockIds::SANDSTONE), + BlockFactory::get(BlockIds::SANDSTONE), + BlockFactory::get(BlockIds::SANDSTONE) ]); } } diff --git a/src/pocketmine/level/biome/SnowyBiome.php b/src/pocketmine/level/biome/SnowyBiome.php index 463deae4b2..f43b877364 100644 --- a/src/pocketmine/level/biome/SnowyBiome.php +++ b/src/pocketmine/level/biome/SnowyBiome.php @@ -23,18 +23,18 @@ declare(strict_types=1); namespace pocketmine\level\biome; -use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; abstract class SnowyBiome extends Biome{ public function __construct(){ $this->setGroundCover([ - BlockFactory::get(Block::SNOW_LAYER), - BlockFactory::get(Block::GRASS), - BlockFactory::get(Block::DIRT), - BlockFactory::get(Block::DIRT), - BlockFactory::get(Block::DIRT) + BlockFactory::get(BlockIds::SNOW_LAYER), + BlockFactory::get(BlockIds::GRASS), + BlockFactory::get(BlockIds::DIRT), + BlockFactory::get(BlockIds::DIRT), + BlockFactory::get(BlockIds::DIRT) ]); } } diff --git a/src/pocketmine/level/generator/Flat.php b/src/pocketmine/level/generator/Flat.php index 9fb39a477b..e10aae6b1a 100644 --- a/src/pocketmine/level/generator/Flat.php +++ b/src/pocketmine/level/generator/Flat.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\generator; -use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\item\ItemFactory; use pocketmine\level\ChunkManager; use pocketmine\level\format\Chunk; @@ -78,14 +78,14 @@ class Flat extends Generator{ if(isset($this->options["decoration"])){ $ores = new Ore(); $ores->setOreTypes([ - new OreType(BlockFactory::get(Block::COAL_ORE), 20, 16, 0, 128), - new OreType(BlockFactory::get(Block::IRON_ORE), 20, 8, 0, 64), - new OreType(BlockFactory::get(Block::REDSTONE_ORE), 8, 7, 0, 16), - new OreType(BlockFactory::get(Block::LAPIS_ORE), 1, 6, 0, 32), - new OreType(BlockFactory::get(Block::GOLD_ORE), 2, 8, 0, 32), - new OreType(BlockFactory::get(Block::DIAMOND_ORE), 1, 7, 0, 16), - new OreType(BlockFactory::get(Block::DIRT), 20, 32, 0, 128), - new OreType(BlockFactory::get(Block::GRAVEL), 10, 16, 0, 128) + new OreType(BlockFactory::get(BlockIds::COAL_ORE), 20, 16, 0, 128), + new OreType(BlockFactory::get(BlockIds::IRON_ORE), 20, 8, 0, 64), + new OreType(BlockFactory::get(BlockIds::REDSTONE_ORE), 8, 7, 0, 16), + new OreType(BlockFactory::get(BlockIds::LAPIS_ORE), 1, 6, 0, 32), + new OreType(BlockFactory::get(BlockIds::GOLD_ORE), 2, 8, 0, 32), + new OreType(BlockFactory::get(BlockIds::DIAMOND_ORE), 1, 7, 0, 16), + new OreType(BlockFactory::get(BlockIds::DIRT), 20, 32, 0, 128), + new OreType(BlockFactory::get(BlockIds::GRAVEL), 10, 16, 0, 128) ]); $this->populators[] = $ores; } diff --git a/src/pocketmine/level/generator/hell/Nether.php b/src/pocketmine/level/generator/hell/Nether.php index 9a6115ea7e..fbeba2a584 100644 --- a/src/pocketmine/level/generator/hell/Nether.php +++ b/src/pocketmine/level/generator/hell/Nether.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\generator\hell; -use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\level\biome\Biome; use pocketmine\level\ChunkManager; use pocketmine\level\generator\Generator; @@ -90,9 +90,9 @@ class Nether extends Generator{ $chunk = $this->level->getChunk($chunkX, $chunkZ); - $bedrock = BlockFactory::get(Block::BEDROCK)->getFullId(); - $netherrack = BlockFactory::get(Block::NETHERRACK)->getFullId(); - $stillLava = BlockFactory::get(Block::STILL_LAVA)->getFullId(); + $bedrock = BlockFactory::get(BlockIds::BEDROCK)->getFullId(); + $netherrack = BlockFactory::get(BlockIds::NETHERRACK)->getFullId(); + $stillLava = BlockFactory::get(BlockIds::STILL_LAVA)->getFullId(); for($x = 0; $x < 16; ++$x){ for($z = 0; $z < 16; ++$z){ diff --git a/src/pocketmine/level/generator/normal/Normal.php b/src/pocketmine/level/generator/normal/Normal.php index 660a6e3ba2..3b366049fe 100644 --- a/src/pocketmine/level/generator/normal/Normal.php +++ b/src/pocketmine/level/generator/normal/Normal.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\generator\normal; -use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\level\biome\Biome; use pocketmine\level\ChunkManager; use pocketmine\level\generator\biome\BiomeSelector; @@ -121,14 +121,14 @@ class Normal extends Generator{ $ores = new Ore(); $ores->setOreTypes([ - new OreType(BlockFactory::get(Block::COAL_ORE), 20, 16, 0, 128), - new OreType(BlockFactory::get(Block::IRON_ORE), 20, 8, 0, 64), - new OreType(BlockFactory::get(Block::REDSTONE_ORE), 8, 7, 0, 16), - new OreType(BlockFactory::get(Block::LAPIS_ORE), 1, 6, 0, 32), - new OreType(BlockFactory::get(Block::GOLD_ORE), 2, 8, 0, 32), - new OreType(BlockFactory::get(Block::DIAMOND_ORE), 1, 7, 0, 16), - new OreType(BlockFactory::get(Block::DIRT), 20, 32, 0, 128), - new OreType(BlockFactory::get(Block::GRAVEL), 10, 16, 0, 128) + new OreType(BlockFactory::get(BlockIds::COAL_ORE), 20, 16, 0, 128), + new OreType(BlockFactory::get(BlockIds::IRON_ORE), 20, 8, 0, 64), + new OreType(BlockFactory::get(BlockIds::REDSTONE_ORE), 8, 7, 0, 16), + new OreType(BlockFactory::get(BlockIds::LAPIS_ORE), 1, 6, 0, 32), + new OreType(BlockFactory::get(BlockIds::GOLD_ORE), 2, 8, 0, 32), + new OreType(BlockFactory::get(BlockIds::DIAMOND_ORE), 1, 7, 0, 16), + new OreType(BlockFactory::get(BlockIds::DIRT), 20, 32, 0, 128), + new OreType(BlockFactory::get(BlockIds::GRAVEL), 10, 16, 0, 128) ]); $this->populators[] = $ores; } @@ -178,9 +178,9 @@ class Normal extends Generator{ $biomeCache = []; - $bedrock = BlockFactory::get(Block::BEDROCK)->getFullId(); - $stillWater = BlockFactory::get(Block::STILL_WATER)->getFullId(); - $stone = BlockFactory::get(Block::STONE)->getFullId(); + $bedrock = BlockFactory::get(BlockIds::BEDROCK)->getFullId(); + $stillWater = BlockFactory::get(BlockIds::STILL_WATER)->getFullId(); + $stone = BlockFactory::get(BlockIds::STONE)->getFullId(); for($x = 0; $x < 16; ++$x){ for($z = 0; $z < 16; ++$z){ diff --git a/src/pocketmine/level/generator/object/BirchTree.php b/src/pocketmine/level/generator/object/BirchTree.php index d0fd6bed29..b6f8e4a0a1 100644 --- a/src/pocketmine/level/generator/object/BirchTree.php +++ b/src/pocketmine/level/generator/object/BirchTree.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\generator\object; -use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\block\utils\TreeType; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; @@ -34,7 +34,7 @@ class BirchTree extends Tree{ protected $superBirch = false; public function __construct(bool $superBirch = false){ - parent::__construct(BlockFactory::get(Block::LOG, TreeType::BIRCH()->getMagicNumber()), BlockFactory::get(Block::LEAVES, TreeType::BIRCH()->getMagicNumber())); + parent::__construct(BlockFactory::get(BlockIds::LOG, TreeType::BIRCH()->getMagicNumber()), BlockFactory::get(BlockIds::LEAVES, TreeType::BIRCH()->getMagicNumber())); $this->superBirch = $superBirch; } diff --git a/src/pocketmine/level/generator/object/JungleTree.php b/src/pocketmine/level/generator/object/JungleTree.php index 47719e1c76..3090127bcb 100644 --- a/src/pocketmine/level/generator/object/JungleTree.php +++ b/src/pocketmine/level/generator/object/JungleTree.php @@ -23,13 +23,13 @@ declare(strict_types=1); namespace pocketmine\level\generator\object; -use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\block\utils\TreeType; class JungleTree extends Tree{ public function __construct(){ - parent::__construct(BlockFactory::get(Block::LOG, TreeType::JUNGLE()->getMagicNumber()), BlockFactory::get(Block::LEAVES, TreeType::JUNGLE()->getMagicNumber()), 8); + parent::__construct(BlockFactory::get(BlockIds::LOG, TreeType::JUNGLE()->getMagicNumber()), BlockFactory::get(BlockIds::LEAVES, TreeType::JUNGLE()->getMagicNumber()), 8); } } diff --git a/src/pocketmine/level/generator/object/OakTree.php b/src/pocketmine/level/generator/object/OakTree.php index c50e0adf46..56f9fb25ef 100644 --- a/src/pocketmine/level/generator/object/OakTree.php +++ b/src/pocketmine/level/generator/object/OakTree.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\generator\object; -use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\block\utils\TreeType; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; @@ -32,7 +32,7 @@ use pocketmine\utils\Random; class OakTree extends Tree{ public function __construct(){ - parent::__construct(BlockFactory::get(Block::LOG, TreeType::OAK()->getMagicNumber()), BlockFactory::get(Block::LEAVES, TreeType::OAK()->getMagicNumber())); + parent::__construct(BlockFactory::get(BlockIds::LOG, TreeType::OAK()->getMagicNumber()), BlockFactory::get(BlockIds::LEAVES, TreeType::OAK()->getMagicNumber())); } public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ diff --git a/src/pocketmine/level/generator/object/Ore.php b/src/pocketmine/level/generator/object/Ore.php index 08ed226c67..1949c04ecf 100644 --- a/src/pocketmine/level/generator/object/Ore.php +++ b/src/pocketmine/level/generator/object/Ore.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\level\generator\object; -use pocketmine\block\Block; +use pocketmine\block\BlockIds; use pocketmine\level\ChunkManager; use pocketmine\math\VectorMath; use pocketmine\utils\Random; @@ -46,7 +46,7 @@ class Ore{ } public function canPlaceObject(ChunkManager $level, int $x, int $y, int $z) : bool{ - return $level->getBlockAt($x, $y, $z)->getId() === Block::STONE; + return $level->getBlockAt($x, $y, $z)->getId() === BlockIds::STONE; } public function placeObject(ChunkManager $level, int $x, int $y, int $z) : void{ @@ -86,7 +86,7 @@ class Ore{ $sizeZ = ($z + 0.5 - $seedZ) / $size; $sizeZ *= $sizeZ; - if(($sizeX + $sizeY + $sizeZ) < 1 and $level->getBlockAt($x, $y, $z)->getId() === Block::STONE){ + if(($sizeX + $sizeY + $sizeZ) < 1 and $level->getBlockAt($x, $y, $z)->getId() === BlockIds::STONE){ $level->setBlockAt($x, $y, $z, $this->type->material); } } diff --git a/src/pocketmine/level/generator/object/SpruceTree.php b/src/pocketmine/level/generator/object/SpruceTree.php index 0966d15156..97313dc2ae 100644 --- a/src/pocketmine/level/generator/object/SpruceTree.php +++ b/src/pocketmine/level/generator/object/SpruceTree.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\generator\object; -use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\block\utils\TreeType; use pocketmine\level\BlockTransaction; use pocketmine\level\ChunkManager; @@ -34,7 +34,7 @@ use function abs; class SpruceTree extends Tree{ public function __construct(){ - parent::__construct(BlockFactory::get(Block::LOG, TreeType::SPRUCE()->getMagicNumber()), BlockFactory::get(Block::LEAVES, TreeType::SPRUCE()->getMagicNumber()), 10); + parent::__construct(BlockFactory::get(BlockIds::LOG, TreeType::SPRUCE()->getMagicNumber()), BlockFactory::get(BlockIds::LEAVES, TreeType::SPRUCE()->getMagicNumber()), 10); } protected function generateChunkHeight(Random $random) : int{ diff --git a/src/pocketmine/level/generator/object/TallGrass.php b/src/pocketmine/level/generator/object/TallGrass.php index 71eaecbefb..04add8a9d1 100644 --- a/src/pocketmine/level/generator/object/TallGrass.php +++ b/src/pocketmine/level/generator/object/TallGrass.php @@ -25,6 +25,7 @@ namespace pocketmine\level\generator\object; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\level\ChunkManager; use pocketmine\math\Vector3; use pocketmine\utils\Random; @@ -35,9 +36,9 @@ class TallGrass{ public static function growGrass(ChunkManager $level, Vector3 $pos, Random $random, int $count = 15, int $radius = 10) : void{ /** @var Block[] $arr */ $arr = [ - BlockFactory::get(Block::DANDELION), - BlockFactory::get(Block::POPPY), - $tallGrass = BlockFactory::get(Block::TALL_GRASS, 1), + BlockFactory::get(BlockIds::DANDELION), + BlockFactory::get(BlockIds::POPPY), + $tallGrass = BlockFactory::get(BlockIds::TALL_GRASS, 1), $tallGrass, $tallGrass, $tallGrass @@ -46,7 +47,7 @@ class TallGrass{ for($c = 0; $c < $count; ++$c){ $x = $random->nextRange($pos->x - $radius, $pos->x + $radius); $z = $random->nextRange($pos->z - $radius, $pos->z + $radius); - if($level->getBlockAt($x, $pos->y + 1, $z)->getId() === Block::AIR and $level->getBlockAt($x, $pos->y, $z)->getId() === Block::GRASS){ + if($level->getBlockAt($x, $pos->y + 1, $z)->getId() === BlockIds::AIR and $level->getBlockAt($x, $pos->y, $z)->getId() === BlockIds::GRASS){ $level->setBlockAt($x, $pos->y + 1, $z, $arr[$random->nextRange(0, $arrC)]); } } diff --git a/src/pocketmine/level/generator/object/Tree.php b/src/pocketmine/level/generator/object/Tree.php index 202df28271..e70fac4025 100644 --- a/src/pocketmine/level/generator/object/Tree.php +++ b/src/pocketmine/level/generator/object/Tree.php @@ -25,6 +25,7 @@ namespace pocketmine\level\generator\object; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\block\Leaves; use pocketmine\block\Sapling; use pocketmine\block\utils\TreeType; @@ -120,7 +121,7 @@ abstract class Tree{ protected function placeTrunk(int $x, int $y, int $z, Random $random, int $trunkHeight, BlockTransaction $transaction) : void{ // The base dirt block - $transaction->addBlockAt($x, $y - 1, $z, BlockFactory::get(Block::DIRT)); + $transaction->addBlockAt($x, $y - 1, $z, BlockFactory::get(BlockIds::DIRT)); for($yy = 0; $yy < $trunkHeight; ++$yy){ if($this->canOverride($transaction->fetchBlockAt($x, $y + $yy, $z))){ diff --git a/src/pocketmine/level/generator/populator/GroundCover.php b/src/pocketmine/level/generator/populator/GroundCover.php index e493a103b6..e6b8e59e75 100644 --- a/src/pocketmine/level/generator/populator/GroundCover.php +++ b/src/pocketmine/level/generator/populator/GroundCover.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\generator\populator; -use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\block\Liquid; use pocketmine\level\biome\Biome; use pocketmine\level\ChunkManager; @@ -56,7 +56,7 @@ class GroundCover extends Populator{ for($y = $startY; $y > $endY and $y >= 0; --$y){ $b = $cover[$startY - $y]; $id = BlockFactory::fromFullBlock($chunk->getFullBlock($x, $y, $z)); - if($id->getId() === Block::AIR and $b->isSolid()){ + if($id->getId() === BlockIds::AIR and $b->isSolid()){ break; } if($b->canBeFlowedInto() and $id instanceof Liquid){ diff --git a/src/pocketmine/level/generator/populator/TallGrass.php b/src/pocketmine/level/generator/populator/TallGrass.php index 353a67e184..7d00744765 100644 --- a/src/pocketmine/level/generator/populator/TallGrass.php +++ b/src/pocketmine/level/generator/populator/TallGrass.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\level\generator\populator; -use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\BlockIds; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; @@ -46,7 +46,7 @@ class TallGrass extends Populator{ $this->level = $level; $amount = $random->nextRange(0, $this->randomAmount + 1) + $this->baseAmount; - $block = BlockFactory::get(Block::TALL_GRASS, 1); + $block = BlockFactory::get(BlockIds::TALL_GRASS, 1); for($i = 0; $i < $amount; ++$i){ $x = $random->nextRange($chunkX * 16, $chunkX * 16 + 15); $z = $random->nextRange($chunkZ * 16, $chunkZ * 16 + 15); @@ -60,13 +60,13 @@ class TallGrass extends Populator{ private function canTallGrassStay(int $x, int $y, int $z) : bool{ $b = $this->level->getBlockAt($x, $y, $z)->getId(); - return ($b === Block::AIR or $b === Block::SNOW_LAYER) and $this->level->getBlockAt($x, $y - 1, $z)->getId() === Block::GRASS; + return ($b === BlockIds::AIR or $b === BlockIds::SNOW_LAYER) and $this->level->getBlockAt($x, $y - 1, $z)->getId() === BlockIds::GRASS; } private function getHighestWorkableBlock(int $x, int $z) : int{ for($y = 127; $y >= 0; --$y){ $b = $this->level->getBlockAt($x, $y, $z)->getId(); - if($b !== Block::AIR and $b !== Block::LEAVES and $b !== Block::LEAVES2 and $b !== Block::SNOW_LAYER){ + if($b !== BlockIds::AIR and $b !== BlockIds::LEAVES and $b !== BlockIds::LEAVES2 and $b !== BlockIds::SNOW_LAYER){ break; } } diff --git a/src/pocketmine/level/generator/populator/Tree.php b/src/pocketmine/level/generator/populator/Tree.php index a9e646fb2c..68d1b2c6ce 100644 --- a/src/pocketmine/level/generator/populator/Tree.php +++ b/src/pocketmine/level/generator/populator/Tree.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\level\generator\populator; -use pocketmine\block\Block; +use pocketmine\block\BlockIds; use pocketmine\block\utils\TreeType; use pocketmine\level\ChunkManager; use pocketmine\level\generator\object\Tree as ObjectTree; @@ -70,9 +70,9 @@ class Tree extends Populator{ private function getHighestWorkableBlock(int $x, int $z) : int{ for($y = 127; $y > 0; --$y){ $b = $this->level->getBlockAt($x, $y, $z)->getId(); - if($b === Block::DIRT or $b === Block::GRASS){ + if($b === BlockIds::DIRT or $b === BlockIds::GRASS){ break; - }elseif($b !== Block::AIR and $b !== Block::SNOW_LAYER){ + }elseif($b !== BlockIds::AIR and $b !== BlockIds::SNOW_LAYER){ return -1; } } diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index faf52a96a1..6c591c3527 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -37,7 +37,7 @@ class BlockTest extends TestCase{ * Test registering a block which would overwrite another block, without forcing it */ public function testAccidentalOverrideBlock() : void{ - $block = new MyCustomBlock(new BlockIdentifier(Block::COBBLESTONE), "Cobblestone"); + $block = new MyCustomBlock(new BlockIdentifier(BlockIds::COBBLESTONE), "Cobblestone"); $this->expectException(\InvalidArgumentException::class); BlockFactory::register($block); } @@ -46,7 +46,7 @@ class BlockTest extends TestCase{ * Test registering a block deliberately overwriting another block works as expected */ public function testDeliberateOverrideBlock() : void{ - $block = new MyCustomBlock(new BlockIdentifier(Block::COBBLESTONE), "Cobblestone"); + $block = new MyCustomBlock(new BlockIdentifier(BlockIds::COBBLESTONE), "Cobblestone"); BlockFactory::register($block, true); self::assertInstanceOf(MyCustomBlock::class, BlockFactory::get($block->getId())); } @@ -101,12 +101,12 @@ class BlockTest extends TestCase{ */ public function blockGetProvider() : array{ return [ - [Block::STONE, 5], - [Block::STONE, 15], - [Block::GOLD_BLOCK, 0], - [Block::WOODEN_PLANKS, 5], - [Block::SAND, 0], - [Block::GOLD_BLOCK, 0] + [BlockIds::STONE, 5], + [BlockIds::STONE, 15], + [BlockIds::GOLD_BLOCK, 0], + [BlockIds::WOODEN_PLANKS, 5], + [BlockIds::SAND, 0], + [BlockIds::GOLD_BLOCK, 0] ]; } From 2a3e6dcf00dcb0bcb4c016c93955ff86a6909045 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 19:46:31 +0000 Subject: [PATCH 0689/3224] Rename BlockIds -> BlockLegacyIds --- src/pocketmine/Player.php | 6 +- src/pocketmine/block/Banner.php | 2 +- src/pocketmine/block/Block.php | 6 +- src/pocketmine/block/BlockFactory.php | 584 +++++++++--------- .../{BlockIds.php => BlockLegacyIds.php} | 2 +- src/pocketmine/block/Cactus.php | 10 +- src/pocketmine/block/Cake.php | 8 +- src/pocketmine/block/Carpet.php | 4 +- src/pocketmine/block/CoarseDirt.php | 2 +- src/pocketmine/block/CobblestoneWall.php | 2 +- src/pocketmine/block/ConcretePowder.php | 2 +- src/pocketmine/block/Crops.php | 4 +- src/pocketmine/block/Dandelion.php | 2 +- src/pocketmine/block/Dirt.php | 2 +- src/pocketmine/block/Door.php | 2 +- src/pocketmine/block/DoublePlant.php | 2 +- src/pocketmine/block/DragonEgg.php | 2 +- src/pocketmine/block/Farmland.php | 4 +- src/pocketmine/block/Fire.php | 8 +- src/pocketmine/block/Flower.php | 2 +- src/pocketmine/block/Grass.php | 10 +- src/pocketmine/block/GrassPath.php | 2 +- src/pocketmine/block/Ice.php | 2 +- src/pocketmine/block/Lava.php | 6 +- src/pocketmine/block/Liquid.php | 2 +- src/pocketmine/block/MelonStem.php | 2 +- src/pocketmine/block/Mycelium.php | 4 +- src/pocketmine/block/NetherWartPlant.php | 4 +- src/pocketmine/block/PumpkinStem.php | 2 +- src/pocketmine/block/Sapling.php | 2 +- src/pocketmine/block/Sign.php | 2 +- src/pocketmine/block/SnowLayer.php | 2 +- src/pocketmine/block/Stem.php | 2 +- src/pocketmine/block/Sugarcane.php | 18 +- src/pocketmine/block/TNT.php | 2 +- src/pocketmine/block/TallGrass.php | 4 +- src/pocketmine/block/Torch.php | 4 +- src/pocketmine/block/utils/FallableTrait.php | 6 +- src/pocketmine/entity/object/Painting.php | 4 +- .../entity/projectile/EnderPearl.php | 4 +- .../entity/projectile/SplashPotion.php | 10 +- .../event/player/PlayerDeathEvent.php | 4 +- src/pocketmine/item/Banner.php | 4 +- src/pocketmine/item/Bed.php | 4 +- src/pocketmine/item/BeetrootSeeds.php | 4 +- src/pocketmine/item/Bucket.php | 4 +- src/pocketmine/item/Carrot.php | 4 +- src/pocketmine/item/CocoaBeans.php | 4 +- src/pocketmine/item/FlintSteel.php | 6 +- src/pocketmine/item/Item.php | 4 +- src/pocketmine/item/ItemFactory.php | 52 +- src/pocketmine/item/MelonSeeds.php | 4 +- src/pocketmine/item/Potato.php | 4 +- src/pocketmine/item/PumpkinSeeds.php | 4 +- src/pocketmine/item/Redstone.php | 4 +- src/pocketmine/item/Skull.php | 4 +- src/pocketmine/item/StringItem.php | 4 +- src/pocketmine/item/WheatSeeds.php | 4 +- src/pocketmine/level/Explosion.php | 4 +- src/pocketmine/level/Level.php | 6 +- src/pocketmine/level/SimpleChunkManager.php | 4 +- src/pocketmine/level/biome/GrassyBiome.php | 12 +- src/pocketmine/level/biome/OceanBiome.php | 12 +- src/pocketmine/level/biome/RiverBiome.php | 12 +- src/pocketmine/level/biome/SandyBiome.php | 12 +- src/pocketmine/level/biome/SnowyBiome.php | 12 +- src/pocketmine/level/format/Chunk.php | 4 +- src/pocketmine/level/format/SubChunk.php | 12 +- .../level/format/io/leveldb/LevelDB.php | 4 +- src/pocketmine/level/generator/Flat.php | 18 +- .../level/generator/hell/Nether.php | 8 +- .../level/generator/normal/Normal.php | 24 +- .../level/generator/object/BirchTree.php | 4 +- .../level/generator/object/JungleTree.php | 4 +- .../level/generator/object/OakTree.php | 4 +- src/pocketmine/level/generator/object/Ore.php | 6 +- .../level/generator/object/SpruceTree.php | 4 +- .../level/generator/object/TallGrass.php | 10 +- .../level/generator/object/Tree.php | 4 +- .../level/generator/populator/GroundCover.php | 4 +- .../level/generator/populator/TallGrass.php | 8 +- .../level/generator/populator/Tree.php | 6 +- tests/phpunit/block/BlockTest.php | 16 +- 83 files changed, 541 insertions(+), 541 deletions(-) rename src/pocketmine/block/{BlockIds.php => BlockLegacyIds.php} (99%) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 5709ef6cec..8192747223 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -26,7 +26,7 @@ namespace pocketmine; use pocketmine\block\Bed; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\block\UnknownBlock; use pocketmine\command\Command; use pocketmine\command\CommandSender; @@ -2083,8 +2083,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $block = $target->getSide($face); - if($block->getId() === BlockIds::FIRE){ - $this->level->setBlock($block, BlockFactory::get(BlockIds::AIR)); + if($block->getId() === BlockLegacyIds::FIRE){ + $this->level->setBlock($block, BlockFactory::get(BlockLegacyIds::AIR)); return true; } diff --git a/src/pocketmine/block/Banner.php b/src/pocketmine/block/Banner.php index d156f339d4..fac53405b0 100644 --- a/src/pocketmine/block/Banner.php +++ b/src/pocketmine/block/Banner.php @@ -163,7 +163,7 @@ class Banner extends Transparent{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::opposite($this->facing))->getId() === BlockIds::AIR){ + if($this->getSide(Facing::opposite($this->facing))->getId() === BlockLegacyIds::AIR){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 27c18f6bdb..93784eedaf 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -48,7 +48,7 @@ use function dechex; use function get_class; use const PHP_INT_MAX; -class Block extends Position implements BlockIds, Metadatable{ +class Block extends Position implements BlockLegacyIds, Metadatable{ /** * Returns a new Block instance with the specified ID, meta and position. @@ -314,7 +314,7 @@ class Block extends Position implements BlockIds, Metadatable{ if(($t = $this->level->getTile($this)) !== null){ $t->onBlockDestroyed(); } - return $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::AIR)); + return $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); } @@ -655,7 +655,7 @@ class Block extends Position implements BlockIds, Metadatable{ return $this->getLevel()->getBlock(Vector3::getSide($side, $step)); } - return BlockFactory::get(BlockIds::AIR, 0, Position::fromObject(Vector3::getSide($side, $step))); + return BlockFactory::get(BlockLegacyIds::AIR, 0, Position::fromObject(Vector3::getSide($side, $step))); } /** diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 686a549b76..5494c61b56 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -75,328 +75,328 @@ class BlockFactory{ self::$diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 8192, false)); self::$blastResistance = \SplFixedArray::fromArray(array_fill(0, 8192, 0)); - self::register(new ActivatorRail(new BID(BlockIds::ACTIVATOR_RAIL, BaseRail::STRAIGHT_NORTH_SOUTH), "Activator Rail")); - self::register(new Air(new BID(BlockIds::AIR), "Air")); - self::register(new Anvil(new BID(BlockIds::ANVIL, Anvil::TYPE_NORMAL), "Anvil")); - self::register(new Anvil(new BID(BlockIds::ANVIL, Anvil::TYPE_SLIGHTLY_DAMAGED), "Slightly Damaged Anvil")); - self::register(new Anvil(new BID(BlockIds::ANVIL, Anvil::TYPE_VERY_DAMAGED), "Very Damaged Anvil")); - self::register(new Banner(new BlockIdentifierFlattened(BlockIds::STANDING_BANNER, BlockIds::WALL_BANNER, 0, ItemIds::BANNER, \pocketmine\tile\Banner::class), "Banner")); - self::register(new Barrier(new BID(BlockIds::BARRIER), "Barrier")); - self::register(new Bed(new BID(BlockIds::BED_BLOCK, 0, ItemIds::BED, \pocketmine\tile\Bed::class), "Bed Block")); - self::register(new Bedrock(new BID(BlockIds::BEDROCK), "Bedrock")); - self::register(new Beetroot(new BID(BlockIds::BEETROOT_BLOCK), "Beetroot Block")); - self::register(new BlueIce(new BID(BlockIds::BLUE_ICE), "Blue Ice")); - self::register(new BoneBlock(new BID(BlockIds::BONE_BLOCK), "Bone Block")); - self::register(new Bookshelf(new BID(BlockIds::BOOKSHELF), "Bookshelf")); - self::register(new BrewingStand(new BID(BlockIds::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND), "Brewing Stand")); - self::register(new BrickStairs(new BID(BlockIds::BRICK_STAIRS), "Brick Stairs")); - self::register(new Bricks(new BID(BlockIds::BRICK_BLOCK), "Bricks")); - self::register(new BrownMushroom(new BID(BlockIds::BROWN_MUSHROOM), "Brown Mushroom")); - self::register(new BrownMushroomBlock(new BID(BlockIds::BROWN_MUSHROOM_BLOCK), "Brown Mushroom Block")); - self::register(new Cactus(new BID(BlockIds::CACTUS), "Cactus")); - self::register(new Cake(new BID(BlockIds::CAKE_BLOCK, 0, ItemIds::CAKE), "Cake")); - self::register(new Carrot(new BID(BlockIds::CARROTS), "Carrot Block")); - self::register(new Chest(new BID(BlockIds::CHEST, 0, null, \pocketmine\tile\Chest::class), "Chest")); - self::register(new Clay(new BID(BlockIds::CLAY_BLOCK), "Clay Block")); - self::register(new Coal(new BID(BlockIds::COAL_BLOCK), "Coal Block")); - self::register(new CoalOre(new BID(BlockIds::COAL_ORE), "Coal Ore")); - self::register(new CoarseDirt(new BID(BlockIds::DIRT, Dirt::COARSE), "Coarse Dirt")); - self::register(new Cobblestone(new BID(BlockIds::COBBLESTONE), "Cobblestone")); - self::register(new Cobblestone(new BID(BlockIds::MOSSY_COBBLESTONE), "Moss Stone")); - self::register(new CobblestoneStairs(new BID(BlockIds::COBBLESTONE_STAIRS), "Cobblestone Stairs")); - self::register(new Cobweb(new BID(BlockIds::COBWEB), "Cobweb")); - self::register(new CocoaBlock(new BID(BlockIds::COCOA), "Cocoa Block")); - self::register(new CraftingTable(new BID(BlockIds::CRAFTING_TABLE), "Crafting Table")); - self::register(new Dandelion(new BID(BlockIds::DANDELION), "Dandelion")); - self::register(new DaylightSensor(new BlockIdentifierFlattened(BlockIds::DAYLIGHT_DETECTOR, BlockIds::DAYLIGHT_DETECTOR_INVERTED), "Daylight Sensor")); - self::register(new DeadBush(new BID(BlockIds::DEADBUSH), "Dead Bush")); - self::register(new DetectorRail(new BID(BlockIds::DETECTOR_RAIL), "Detector Rail")); - self::register(new Diamond(new BID(BlockIds::DIAMOND_BLOCK), "Diamond Block")); - self::register(new DiamondOre(new BID(BlockIds::DIAMOND_ORE), "Diamond Ore")); - self::register(new Dirt(new BID(BlockIds::DIRT, Dirt::NORMAL), "Dirt")); - self::register(new DoublePlant(new BID(BlockIds::DOUBLE_PLANT, 0), "Sunflower")); - self::register(new DoublePlant(new BID(BlockIds::DOUBLE_PLANT, 1), "Lilac")); - self::register(new DoublePlant(new BID(BlockIds::DOUBLE_PLANT, 4), "Rose Bush")); - self::register(new DoublePlant(new BID(BlockIds::DOUBLE_PLANT, 5), "Peony")); - self::register(new DoubleTallGrass(new BID(BlockIds::DOUBLE_PLANT, 2), "Double Tallgrass")); - self::register(new DoubleTallGrass(new BID(BlockIds::DOUBLE_PLANT, 3), "Large Fern")); - self::register(new DragonEgg(new BID(BlockIds::DRAGON_EGG), "Dragon Egg")); - self::register(new Emerald(new BID(BlockIds::EMERALD_BLOCK), "Emerald Block")); - self::register(new EmeraldOre(new BID(BlockIds::EMERALD_ORE), "Emerald Ore")); - self::register(new EnchantingTable(new BID(BlockIds::ENCHANTING_TABLE, 0, null, \pocketmine\tile\EnchantTable::class), "Enchanting Table")); - self::register(new EndPortalFrame(new BID(BlockIds::END_PORTAL_FRAME), "End Portal Frame")); - self::register(new EndRod(new BID(BlockIds::END_ROD), "End Rod")); - self::register(new EndStone(new BID(BlockIds::END_STONE), "End Stone")); - self::register(new EndStoneBricks(new BID(BlockIds::END_BRICKS), "End Stone Bricks")); - self::register(new EnderChest(new BID(BlockIds::ENDER_CHEST, 0, null, \pocketmine\tile\EnderChest::class), "Ender Chest")); - self::register(new Farmland(new BID(BlockIds::FARMLAND), "Farmland")); - self::register(new Fire(new BID(BlockIds::FIRE), "Fire Block")); - self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_ALLIUM), "Allium")); - self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_AZURE_BLUET), "Azure Bluet")); - self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_BLUE_ORCHID), "Blue Orchid")); - self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_CORNFLOWER), "Cornflower")); - self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_LILY_OF_THE_VALLEY), "Lily of the Valley")); - self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_ORANGE_TULIP), "Orange Tulip")); - self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_OXEYE_DAISY), "Oxeye Daisy")); - self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_PINK_TULIP), "Pink Tulip")); - self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_POPPY), "Poppy")); - self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_RED_TULIP), "Red Tulip")); - self::register(new Flower(new BID(BlockIds::RED_FLOWER, Flower::TYPE_WHITE_TULIP), "White Tulip")); - self::register(new FlowerPot(new BID(BlockIds::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, \pocketmine\tile\FlowerPot::class), "Flower Pot")); - self::register(new FrostedIce(new BID(BlockIds::FROSTED_ICE), "Frosted Ice")); - self::register(new Furnace(new BlockIdentifierFlattened(BlockIds::FURNACE, BlockIds::LIT_FURNACE, 0, null, \pocketmine\tile\Furnace::class), "Furnace")); - self::register(new Glass(new BID(BlockIds::GLASS), "Glass")); - self::register(new GlassPane(new BID(BlockIds::GLASS_PANE), "Glass Pane")); - self::register(new GlowingObsidian(new BID(BlockIds::GLOWINGOBSIDIAN), "Glowing Obsidian")); - self::register(new Glowstone(new BID(BlockIds::GLOWSTONE), "Glowstone")); - self::register(new Gold(new BID(BlockIds::GOLD_BLOCK), "Gold Block")); - self::register(new GoldOre(new BID(BlockIds::GOLD_ORE), "Gold Ore")); - self::register(new Grass(new BID(BlockIds::GRASS), "Grass")); - self::register(new GrassPath(new BID(BlockIds::GRASS_PATH), "Grass Path")); - self::register(new Gravel(new BID(BlockIds::GRAVEL), "Gravel")); - self::register(new HardenedClay(new BID(BlockIds::HARDENED_CLAY), "Hardened Clay")); - self::register(new HardenedGlass(new BID(BlockIds::HARD_GLASS), "Hardened Glass")); - self::register(new HardenedGlassPane(new BID(BlockIds::HARD_GLASS_PANE), "Hardened Glass Pane")); - self::register(new HayBale(new BID(BlockIds::HAY_BALE), "Hay Bale")); - self::register(new Ice(new BID(BlockIds::ICE), "Ice")); - self::register(new class(new BID(BlockIds::MONSTER_EGG), "Infested Stone") extends InfestedStone{ + self::register(new ActivatorRail(new BID(BlockLegacyIds::ACTIVATOR_RAIL, BaseRail::STRAIGHT_NORTH_SOUTH), "Activator Rail")); + self::register(new Air(new BID(BlockLegacyIds::AIR), "Air")); + self::register(new Anvil(new BID(BlockLegacyIds::ANVIL, Anvil::TYPE_NORMAL), "Anvil")); + self::register(new Anvil(new BID(BlockLegacyIds::ANVIL, Anvil::TYPE_SLIGHTLY_DAMAGED), "Slightly Damaged Anvil")); + self::register(new Anvil(new BID(BlockLegacyIds::ANVIL, Anvil::TYPE_VERY_DAMAGED), "Very Damaged Anvil")); + self::register(new Banner(new BlockIdentifierFlattened(BlockLegacyIds::STANDING_BANNER, BlockLegacyIds::WALL_BANNER, 0, ItemIds::BANNER, \pocketmine\tile\Banner::class), "Banner")); + self::register(new Barrier(new BID(BlockLegacyIds::BARRIER), "Barrier")); + self::register(new Bed(new BID(BlockLegacyIds::BED_BLOCK, 0, ItemIds::BED, \pocketmine\tile\Bed::class), "Bed Block")); + self::register(new Bedrock(new BID(BlockLegacyIds::BEDROCK), "Bedrock")); + self::register(new Beetroot(new BID(BlockLegacyIds::BEETROOT_BLOCK), "Beetroot Block")); + self::register(new BlueIce(new BID(BlockLegacyIds::BLUE_ICE), "Blue Ice")); + self::register(new BoneBlock(new BID(BlockLegacyIds::BONE_BLOCK), "Bone Block")); + self::register(new Bookshelf(new BID(BlockLegacyIds::BOOKSHELF), "Bookshelf")); + self::register(new BrewingStand(new BID(BlockLegacyIds::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND), "Brewing Stand")); + self::register(new BrickStairs(new BID(BlockLegacyIds::BRICK_STAIRS), "Brick Stairs")); + self::register(new Bricks(new BID(BlockLegacyIds::BRICK_BLOCK), "Bricks")); + self::register(new BrownMushroom(new BID(BlockLegacyIds::BROWN_MUSHROOM), "Brown Mushroom")); + self::register(new BrownMushroomBlock(new BID(BlockLegacyIds::BROWN_MUSHROOM_BLOCK), "Brown Mushroom Block")); + self::register(new Cactus(new BID(BlockLegacyIds::CACTUS), "Cactus")); + self::register(new Cake(new BID(BlockLegacyIds::CAKE_BLOCK, 0, ItemIds::CAKE), "Cake")); + self::register(new Carrot(new BID(BlockLegacyIds::CARROTS), "Carrot Block")); + self::register(new Chest(new BID(BlockLegacyIds::CHEST, 0, null, \pocketmine\tile\Chest::class), "Chest")); + self::register(new Clay(new BID(BlockLegacyIds::CLAY_BLOCK), "Clay Block")); + self::register(new Coal(new BID(BlockLegacyIds::COAL_BLOCK), "Coal Block")); + self::register(new CoalOre(new BID(BlockLegacyIds::COAL_ORE), "Coal Ore")); + self::register(new CoarseDirt(new BID(BlockLegacyIds::DIRT, Dirt::COARSE), "Coarse Dirt")); + self::register(new Cobblestone(new BID(BlockLegacyIds::COBBLESTONE), "Cobblestone")); + self::register(new Cobblestone(new BID(BlockLegacyIds::MOSSY_COBBLESTONE), "Moss Stone")); + self::register(new CobblestoneStairs(new BID(BlockLegacyIds::COBBLESTONE_STAIRS), "Cobblestone Stairs")); + self::register(new Cobweb(new BID(BlockLegacyIds::COBWEB), "Cobweb")); + self::register(new CocoaBlock(new BID(BlockLegacyIds::COCOA), "Cocoa Block")); + self::register(new CraftingTable(new BID(BlockLegacyIds::CRAFTING_TABLE), "Crafting Table")); + self::register(new Dandelion(new BID(BlockLegacyIds::DANDELION), "Dandelion")); + self::register(new DaylightSensor(new BlockIdentifierFlattened(BlockLegacyIds::DAYLIGHT_DETECTOR, BlockLegacyIds::DAYLIGHT_DETECTOR_INVERTED), "Daylight Sensor")); + self::register(new DeadBush(new BID(BlockLegacyIds::DEADBUSH), "Dead Bush")); + self::register(new DetectorRail(new BID(BlockLegacyIds::DETECTOR_RAIL), "Detector Rail")); + self::register(new Diamond(new BID(BlockLegacyIds::DIAMOND_BLOCK), "Diamond Block")); + self::register(new DiamondOre(new BID(BlockLegacyIds::DIAMOND_ORE), "Diamond Ore")); + self::register(new Dirt(new BID(BlockLegacyIds::DIRT, Dirt::NORMAL), "Dirt")); + self::register(new DoublePlant(new BID(BlockLegacyIds::DOUBLE_PLANT, 0), "Sunflower")); + self::register(new DoublePlant(new BID(BlockLegacyIds::DOUBLE_PLANT, 1), "Lilac")); + self::register(new DoublePlant(new BID(BlockLegacyIds::DOUBLE_PLANT, 4), "Rose Bush")); + self::register(new DoublePlant(new BID(BlockLegacyIds::DOUBLE_PLANT, 5), "Peony")); + self::register(new DoubleTallGrass(new BID(BlockLegacyIds::DOUBLE_PLANT, 2), "Double Tallgrass")); + self::register(new DoubleTallGrass(new BID(BlockLegacyIds::DOUBLE_PLANT, 3), "Large Fern")); + self::register(new DragonEgg(new BID(BlockLegacyIds::DRAGON_EGG), "Dragon Egg")); + self::register(new Emerald(new BID(BlockLegacyIds::EMERALD_BLOCK), "Emerald Block")); + self::register(new EmeraldOre(new BID(BlockLegacyIds::EMERALD_ORE), "Emerald Ore")); + self::register(new EnchantingTable(new BID(BlockLegacyIds::ENCHANTING_TABLE, 0, null, \pocketmine\tile\EnchantTable::class), "Enchanting Table")); + self::register(new EndPortalFrame(new BID(BlockLegacyIds::END_PORTAL_FRAME), "End Portal Frame")); + self::register(new EndRod(new BID(BlockLegacyIds::END_ROD), "End Rod")); + self::register(new EndStone(new BID(BlockLegacyIds::END_STONE), "End Stone")); + self::register(new EndStoneBricks(new BID(BlockLegacyIds::END_BRICKS), "End Stone Bricks")); + self::register(new EnderChest(new BID(BlockLegacyIds::ENDER_CHEST, 0, null, \pocketmine\tile\EnderChest::class), "Ender Chest")); + self::register(new Farmland(new BID(BlockLegacyIds::FARMLAND), "Farmland")); + self::register(new Fire(new BID(BlockLegacyIds::FIRE), "Fire Block")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_ALLIUM), "Allium")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_AZURE_BLUET), "Azure Bluet")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_BLUE_ORCHID), "Blue Orchid")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_CORNFLOWER), "Cornflower")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_LILY_OF_THE_VALLEY), "Lily of the Valley")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_ORANGE_TULIP), "Orange Tulip")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_OXEYE_DAISY), "Oxeye Daisy")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_PINK_TULIP), "Pink Tulip")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_POPPY), "Poppy")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_RED_TULIP), "Red Tulip")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_WHITE_TULIP), "White Tulip")); + self::register(new FlowerPot(new BID(BlockLegacyIds::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, \pocketmine\tile\FlowerPot::class), "Flower Pot")); + self::register(new FrostedIce(new BID(BlockLegacyIds::FROSTED_ICE), "Frosted Ice")); + self::register(new Furnace(new BlockIdentifierFlattened(BlockLegacyIds::FURNACE, BlockLegacyIds::LIT_FURNACE, 0, null, \pocketmine\tile\Furnace::class), "Furnace")); + self::register(new Glass(new BID(BlockLegacyIds::GLASS), "Glass")); + self::register(new GlassPane(new BID(BlockLegacyIds::GLASS_PANE), "Glass Pane")); + self::register(new GlowingObsidian(new BID(BlockLegacyIds::GLOWINGOBSIDIAN), "Glowing Obsidian")); + self::register(new Glowstone(new BID(BlockLegacyIds::GLOWSTONE), "Glowstone")); + self::register(new Gold(new BID(BlockLegacyIds::GOLD_BLOCK), "Gold Block")); + self::register(new GoldOre(new BID(BlockLegacyIds::GOLD_ORE), "Gold Ore")); + self::register(new Grass(new BID(BlockLegacyIds::GRASS), "Grass")); + self::register(new GrassPath(new BID(BlockLegacyIds::GRASS_PATH), "Grass Path")); + self::register(new Gravel(new BID(BlockLegacyIds::GRAVEL), "Gravel")); + self::register(new HardenedClay(new BID(BlockLegacyIds::HARDENED_CLAY), "Hardened Clay")); + self::register(new HardenedGlass(new BID(BlockLegacyIds::HARD_GLASS), "Hardened Glass")); + self::register(new HardenedGlassPane(new BID(BlockLegacyIds::HARD_GLASS_PANE), "Hardened Glass Pane")); + self::register(new HayBale(new BID(BlockLegacyIds::HAY_BALE), "Hay Bale")); + self::register(new Ice(new BID(BlockLegacyIds::ICE), "Ice")); + self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG), "Infested Stone") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [ItemFactory::get(ItemIds::STONE)]; } }); - self::register(new class(new BID(BlockIds::MONSTER_EGG, 1), "Infested Cobblestone") extends InfestedStone{ + self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, 1), "Infested Cobblestone") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [ItemFactory::get(ItemIds::COBBLESTONE)]; } }); - self::register(new class(new BID(BlockIds::MONSTER_EGG, 2), "Infested Stone Brick") extends InfestedStone{ + self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, 2), "Infested Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [ItemFactory::get(ItemIds::STONE_BRICK)]; } }); - self::register(new class(new BID(BlockIds::MONSTER_EGG, 3), "Infested Mossy Stone Brick") extends InfestedStone{ + self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, 3), "Infested Mossy Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [ItemFactory::get(ItemIds::STONE_BRICK, StoneBricks::MOSSY)]; } }); - self::register(new class(new BID(BlockIds::MONSTER_EGG, 4), "Infested Cracked Stone Brick") extends InfestedStone{ + self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, 4), "Infested Cracked Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [ItemFactory::get(ItemIds::STONE_BRICK, StoneBricks::CRACKED)]; } }); - self::register(new class(new BID(BlockIds::MONSTER_EGG, 5), "Infested Chiseled Stone Brick") extends InfestedStone{ + self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, 5), "Infested Chiseled Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [ItemFactory::get(ItemIds::STONE_BRICK, StoneBricks::CHISELED)]; } }); - self::register(new InfoUpdate(new BID(BlockIds::INFO_UPDATE), "update!")); - self::register(new InfoUpdate(new BID(BlockIds::INFO_UPDATE2), "ate!upd")); - self::register(new InvisibleBedrock(new BID(BlockIds::INVISIBLEBEDROCK), "Invisible Bedrock")); - self::register(new Iron(new BID(BlockIds::IRON_BLOCK), "Iron Block")); - self::register(new IronBars(new BID(BlockIds::IRON_BARS), "Iron Bars")); - self::register(new IronDoor(new BID(BlockIds::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door")); - self::register(new IronOre(new BID(BlockIds::IRON_ORE), "Iron Ore")); - self::register(new IronTrapdoor(new BID(BlockIds::IRON_TRAPDOOR), "Iron Trapdoor")); - self::register(new ItemFrame(new BID(BlockIds::FRAME_BLOCK, 0, ItemIds::FRAME, \pocketmine\tile\ItemFrame::class), "Item Frame")); - self::register(new Ladder(new BID(BlockIds::LADDER), "Ladder")); - self::register(new Lapis(new BID(BlockIds::LAPIS_BLOCK), "Lapis Lazuli Block")); - self::register(new LapisOre(new BID(BlockIds::LAPIS_ORE), "Lapis Lazuli Ore")); - self::register(new Lava(new BlockIdentifierFlattened(BlockIds::FLOWING_LAVA, BlockIds::STILL_LAVA), "Lava")); - self::register(new Lever(new BID(BlockIds::LEVER), "Lever")); - self::register(new LitPumpkin(new BID(BlockIds::JACK_O_LANTERN), "Jack o'Lantern")); - self::register(new Magma(new BID(BlockIds::MAGMA), "Magma Block")); - self::register(new Melon(new BID(BlockIds::MELON_BLOCK), "Melon Block")); - self::register(new MelonStem(new BID(BlockIds::MELON_STEM, 0, ItemIds::MELON_SEEDS), "Melon Stem")); - self::register(new MonsterSpawner(new BID(BlockIds::MOB_SPAWNER), "Monster Spawner")); - self::register(new Mycelium(new BID(BlockIds::MYCELIUM), "Mycelium")); - self::register(new NetherBrick(new BID(BlockIds::NETHER_BRICK_BLOCK), "Nether Bricks")); - self::register(new NetherBrick(new BID(BlockIds::RED_NETHER_BRICK), "Red Nether Bricks")); - self::register(new NetherBrickFence(new BID(BlockIds::NETHER_BRICK_FENCE), "Nether Brick Fence")); - self::register(new NetherBrickStairs(new BID(BlockIds::NETHER_BRICK_STAIRS), "Nether Brick Stairs")); - self::register(new NetherPortal(new BID(BlockIds::PORTAL), "Nether Portal")); - self::register(new NetherQuartzOre(new BID(BlockIds::NETHER_QUARTZ_ORE), "Nether Quartz Ore")); - self::register(new NetherReactor(new BID(BlockIds::NETHERREACTOR), "Nether Reactor Core")); - self::register(new NetherWartBlock(new BID(BlockIds::NETHER_WART_BLOCK), "Nether Wart Block")); - self::register(new NetherWartPlant(new BID(BlockIds::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART), "Nether Wart")); - self::register(new Netherrack(new BID(BlockIds::NETHERRACK), "Netherrack")); - self::register(new NoteBlock(new BID(BlockIds::NOTEBLOCK), "Note Block")); - self::register(new Obsidian(new BID(BlockIds::OBSIDIAN), "Obsidian")); - self::register(new PackedIce(new BID(BlockIds::PACKED_ICE), "Packed Ice")); - self::register(new Podzol(new BID(BlockIds::PODZOL), "Podzol")); - self::register(new Potato(new BID(BlockIds::POTATOES), "Potato Block")); - self::register(new PoweredRail(new BID(BlockIds::GOLDEN_RAIL, BaseRail::STRAIGHT_NORTH_SOUTH), "Powered Rail")); - self::register(new Prismarine(new BID(BlockIds::PRISMARINE, Prismarine::BRICKS), "Prismarine Bricks")); - self::register(new Prismarine(new BID(BlockIds::PRISMARINE, Prismarine::DARK), "Dark Prismarine")); - self::register(new Prismarine(new BID(BlockIds::PRISMARINE, Prismarine::NORMAL), "Prismarine")); - self::register(new Pumpkin(new BID(BlockIds::PUMPKIN), "Pumpkin")); - self::register(new PumpkinStem(new BID(BlockIds::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem")); - self::register(new Purpur(new BID(BlockIds::PURPUR_BLOCK), "Purpur Block")); - self::register(new class(new BID(BlockIds::PURPUR_BLOCK, 2), "Purpur Pillar") extends Purpur{ + self::register(new InfoUpdate(new BID(BlockLegacyIds::INFO_UPDATE), "update!")); + self::register(new InfoUpdate(new BID(BlockLegacyIds::INFO_UPDATE2), "ate!upd")); + self::register(new InvisibleBedrock(new BID(BlockLegacyIds::INVISIBLEBEDROCK), "Invisible Bedrock")); + self::register(new Iron(new BID(BlockLegacyIds::IRON_BLOCK), "Iron Block")); + self::register(new IronBars(new BID(BlockLegacyIds::IRON_BARS), "Iron Bars")); + self::register(new IronDoor(new BID(BlockLegacyIds::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door")); + self::register(new IronOre(new BID(BlockLegacyIds::IRON_ORE), "Iron Ore")); + self::register(new IronTrapdoor(new BID(BlockLegacyIds::IRON_TRAPDOOR), "Iron Trapdoor")); + self::register(new ItemFrame(new BID(BlockLegacyIds::FRAME_BLOCK, 0, ItemIds::FRAME, \pocketmine\tile\ItemFrame::class), "Item Frame")); + self::register(new Ladder(new BID(BlockLegacyIds::LADDER), "Ladder")); + self::register(new Lapis(new BID(BlockLegacyIds::LAPIS_BLOCK), "Lapis Lazuli Block")); + self::register(new LapisOre(new BID(BlockLegacyIds::LAPIS_ORE), "Lapis Lazuli Ore")); + self::register(new Lava(new BlockIdentifierFlattened(BlockLegacyIds::FLOWING_LAVA, BlockLegacyIds::STILL_LAVA), "Lava")); + self::register(new Lever(new BID(BlockLegacyIds::LEVER), "Lever")); + self::register(new LitPumpkin(new BID(BlockLegacyIds::JACK_O_LANTERN), "Jack o'Lantern")); + self::register(new Magma(new BID(BlockLegacyIds::MAGMA), "Magma Block")); + self::register(new Melon(new BID(BlockLegacyIds::MELON_BLOCK), "Melon Block")); + self::register(new MelonStem(new BID(BlockLegacyIds::MELON_STEM, 0, ItemIds::MELON_SEEDS), "Melon Stem")); + self::register(new MonsterSpawner(new BID(BlockLegacyIds::MOB_SPAWNER), "Monster Spawner")); + self::register(new Mycelium(new BID(BlockLegacyIds::MYCELIUM), "Mycelium")); + self::register(new NetherBrick(new BID(BlockLegacyIds::NETHER_BRICK_BLOCK), "Nether Bricks")); + self::register(new NetherBrick(new BID(BlockLegacyIds::RED_NETHER_BRICK), "Red Nether Bricks")); + self::register(new NetherBrickFence(new BID(BlockLegacyIds::NETHER_BRICK_FENCE), "Nether Brick Fence")); + self::register(new NetherBrickStairs(new BID(BlockLegacyIds::NETHER_BRICK_STAIRS), "Nether Brick Stairs")); + self::register(new NetherPortal(new BID(BlockLegacyIds::PORTAL), "Nether Portal")); + self::register(new NetherQuartzOre(new BID(BlockLegacyIds::NETHER_QUARTZ_ORE), "Nether Quartz Ore")); + self::register(new NetherReactor(new BID(BlockLegacyIds::NETHERREACTOR), "Nether Reactor Core")); + self::register(new NetherWartBlock(new BID(BlockLegacyIds::NETHER_WART_BLOCK), "Nether Wart Block")); + self::register(new NetherWartPlant(new BID(BlockLegacyIds::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART), "Nether Wart")); + self::register(new Netherrack(new BID(BlockLegacyIds::NETHERRACK), "Netherrack")); + self::register(new NoteBlock(new BID(BlockLegacyIds::NOTEBLOCK), "Note Block")); + self::register(new Obsidian(new BID(BlockLegacyIds::OBSIDIAN), "Obsidian")); + self::register(new PackedIce(new BID(BlockLegacyIds::PACKED_ICE), "Packed Ice")); + self::register(new Podzol(new BID(BlockLegacyIds::PODZOL), "Podzol")); + self::register(new Potato(new BID(BlockLegacyIds::POTATOES), "Potato Block")); + self::register(new PoweredRail(new BID(BlockLegacyIds::GOLDEN_RAIL, BaseRail::STRAIGHT_NORTH_SOUTH), "Powered Rail")); + self::register(new Prismarine(new BID(BlockLegacyIds::PRISMARINE, Prismarine::BRICKS), "Prismarine Bricks")); + self::register(new Prismarine(new BID(BlockLegacyIds::PRISMARINE, Prismarine::DARK), "Dark Prismarine")); + self::register(new Prismarine(new BID(BlockLegacyIds::PRISMARINE, Prismarine::NORMAL), "Prismarine")); + self::register(new Pumpkin(new BID(BlockLegacyIds::PUMPKIN), "Pumpkin")); + self::register(new PumpkinStem(new BID(BlockLegacyIds::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem")); + self::register(new Purpur(new BID(BlockLegacyIds::PURPUR_BLOCK), "Purpur Block")); + self::register(new class(new BID(BlockLegacyIds::PURPUR_BLOCK, 2), "Purpur Pillar") extends Purpur{ use PillarRotationTrait; }); - self::register(new PurpurStairs(new BID(BlockIds::PURPUR_STAIRS), "Purpur Stairs")); - self::register(new Quartz(new BID(BlockIds::QUARTZ_BLOCK, Quartz::NORMAL), "Quartz Block")); - self::register(new class(new BID(BlockIds::QUARTZ_BLOCK, Quartz::CHISELED), "Chiseled Quartz Block") extends Quartz{ + self::register(new PurpurStairs(new BID(BlockLegacyIds::PURPUR_STAIRS), "Purpur Stairs")); + self::register(new Quartz(new BID(BlockLegacyIds::QUARTZ_BLOCK, Quartz::NORMAL), "Quartz Block")); + self::register(new class(new BID(BlockLegacyIds::QUARTZ_BLOCK, Quartz::CHISELED), "Chiseled Quartz Block") extends Quartz{ use PillarRotationTrait; }); - self::register(new class(new BID(BlockIds::QUARTZ_BLOCK, Quartz::PILLAR), "Quartz Pillar") extends Quartz{ + self::register(new class(new BID(BlockLegacyIds::QUARTZ_BLOCK, Quartz::PILLAR), "Quartz Pillar") extends Quartz{ use PillarRotationTrait; }); - self::register(new Quartz(new BID(BlockIds::QUARTZ_BLOCK, Quartz::SMOOTH), "Smooth Quartz Block")); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) - self::register(new QuartzStairs(new BID(BlockIds::QUARTZ_STAIRS), "Quartz Stairs")); - self::register(new Rail(new BID(BlockIds::RAIL), "Rail")); - self::register(new RedMushroom(new BID(BlockIds::RED_MUSHROOM), "Red Mushroom")); - self::register(new RedMushroomBlock(new BID(BlockIds::RED_MUSHROOM_BLOCK), "Red Mushroom Block")); - self::register(new Redstone(new BID(BlockIds::REDSTONE_BLOCK), "Redstone Block")); - self::register(new RedstoneComparator(new BlockIdentifierFlattened(BlockIds::UNPOWERED_COMPARATOR, BlockIds::POWERED_COMPARATOR, 0, ItemIds::COMPARATOR, Comparator::class), "Redstone Comparator")); - self::register(new RedstoneLamp(new BlockIdentifierFlattened(BlockIds::REDSTONE_LAMP, BlockIds::LIT_REDSTONE_LAMP), "Redstone Lamp")); - self::register(new RedstoneOre(new BlockIdentifierFlattened(BlockIds::REDSTONE_ORE, BlockIds::LIT_REDSTONE_ORE), "Redstone Ore")); - self::register(new RedstoneRepeater(new BlockIdentifierFlattened(BlockIds::UNPOWERED_REPEATER, BlockIds::POWERED_REPEATER, 0, ItemIds::REPEATER), "Redstone Repeater")); - self::register(new RedstoneTorch(new BlockIdentifierFlattened(BlockIds::REDSTONE_TORCH, BlockIds::UNLIT_REDSTONE_TORCH), "Redstone Torch")); - self::register(new RedstoneWire(new BID(BlockIds::REDSTONE_WIRE, 0, ItemIds::REDSTONE), "Redstone")); - self::register(new Reserved6(new BID(BlockIds::RESERVED6), "reserved6")); - self::register(new Sand(new BID(BlockIds::SAND), "Sand")); - self::register(new Sand(new BID(BlockIds::SAND, 1), "Red Sand")); - self::register(new SandstoneStairs(new BID(BlockIds::RED_SANDSTONE_STAIRS), "Red Sandstone Stairs")); - self::register(new SandstoneStairs(new BID(BlockIds::SANDSTONE_STAIRS), "Sandstone Stairs")); - self::register(new SeaLantern(new BID(BlockIds::SEALANTERN), "Sea Lantern")); - self::register(new SeaPickle(new BID(BlockIds::SEA_PICKLE), "Sea Pickle")); - self::register(new Skull(new BID(BlockIds::MOB_HEAD_BLOCK, 0, null, \pocketmine\tile\Skull::class), "Mob Head")); - self::register(new SmoothStone(new BID(BlockIds::STONE, Stone::NORMAL), "Stone")); - self::register(new Snow(new BID(BlockIds::SNOW), "Snow Block")); - self::register(new SnowLayer(new BID(BlockIds::SNOW_LAYER), "Snow Layer")); - self::register(new SoulSand(new BID(BlockIds::SOUL_SAND), "Soul Sand")); - self::register(new Sponge(new BID(BlockIds::SPONGE), "Sponge")); - self::register(new Stone(new BID(BlockIds::STONE, Stone::ANDESITE), "Andesite")); - self::register(new Stone(new BID(BlockIds::STONE, Stone::DIORITE), "Diorite")); - self::register(new Stone(new BID(BlockIds::STONE, Stone::GRANITE), "Granite")); - self::register(new Stone(new BID(BlockIds::STONE, Stone::POLISHED_ANDESITE), "Polished Andesite")); - self::register(new Stone(new BID(BlockIds::STONE, Stone::POLISHED_DIORITE), "Polished Diorite")); - self::register(new Stone(new BID(BlockIds::STONE, Stone::POLISHED_GRANITE), "Polished Granite")); - self::register(new StoneBrickStairs(new BID(BlockIds::STONE_BRICK_STAIRS), "Stone Brick Stairs")); - self::register(new StoneBricks(new BID(BlockIds::STONEBRICK, StoneBricks::CHISELED), "Chiseled Stone Bricks")); - self::register(new StoneBricks(new BID(BlockIds::STONEBRICK, StoneBricks::CRACKED), "Cracked Stone Bricks")); - self::register(new StoneBricks(new BID(BlockIds::STONEBRICK, StoneBricks::MOSSY), "Mossy Stone Bricks")); - self::register(new StoneBricks(new BID(BlockIds::STONEBRICK, StoneBricks::NORMAL), "Stone Bricks")); - self::register(new StoneButton(new BID(BlockIds::STONE_BUTTON), "Stone Button")); - self::register(new StonePressurePlate(new BID(BlockIds::STONE_PRESSURE_PLATE), "Stone Pressure Plate")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB, BlockIds::DOUBLE_STONE_SLAB, 0), "Stone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB, BlockIds::DOUBLE_STONE_SLAB, 1), "Sandstone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB, BlockIds::DOUBLE_STONE_SLAB, 2), "Fake Wooden")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB, BlockIds::DOUBLE_STONE_SLAB, 3), "Cobblestone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB, BlockIds::DOUBLE_STONE_SLAB, 4), "Brick")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB, BlockIds::DOUBLE_STONE_SLAB, 5), "Stone Brick")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB, BlockIds::DOUBLE_STONE_SLAB, 6), "Quartz")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB, BlockIds::DOUBLE_STONE_SLAB, 7), "Nether Brick")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB2, BlockIds::DOUBLE_STONE_SLAB2, 0), "Red Sandstone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB2, BlockIds::DOUBLE_STONE_SLAB2, 1), "Purpur")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB2, BlockIds::DOUBLE_STONE_SLAB2, 2), "Prismarine")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB2, BlockIds::DOUBLE_STONE_SLAB2, 3), "Dark Prismarine")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB2, BlockIds::DOUBLE_STONE_SLAB2, 4), "Prismarine Bricks")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB2, BlockIds::DOUBLE_STONE_SLAB2, 5), "Mossy Cobblestone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB2, BlockIds::DOUBLE_STONE_SLAB2, 6), "Smooth Sandstone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockIds::STONE_SLAB2, BlockIds::DOUBLE_STONE_SLAB2, 7), "Red Nether Brick")); - self::register(new Stonecutter(new BID(BlockIds::STONECUTTER), "Stonecutter")); - self::register(new Sugarcane(new BID(BlockIds::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane")); - self::register(new TNT(new BID(BlockIds::TNT), "TNT")); - self::register(new TallGrass(new BID(BlockIds::TALLGRASS), "Fern")); - self::register(new TallGrass(new BID(BlockIds::TALLGRASS, 1), "Tall Grass")); - self::register(new TallGrass(new BID(BlockIds::TALLGRASS, 2), "Fern")); - self::register(new TallGrass(new BID(BlockIds::TALLGRASS, 3), "Fern")); - self::register(new Torch(new BID(BlockIds::COLORED_TORCH_BP), "Blue Torch")); - self::register(new Torch(new BID(BlockIds::COLORED_TORCH_BP, 8), "Purple Torch")); - self::register(new Torch(new BID(BlockIds::COLORED_TORCH_RG), "Red Torch")); - self::register(new Torch(new BID(BlockIds::COLORED_TORCH_RG, 8), "Green Torch")); - self::register(new Torch(new BID(BlockIds::TORCH), "Torch")); - self::register(new TrappedChest(new BID(BlockIds::TRAPPED_CHEST, 0, null, \pocketmine\tile\Chest::class), "Trapped Chest")); - self::register(new Tripwire(new BID(BlockIds::TRIPWIRE, 0, ItemIds::STRING), "Tripwire")); - self::register(new TripwireHook(new BID(BlockIds::TRIPWIRE_HOOK), "Tripwire Hook")); - self::register(new UnderwaterTorch(new BID(BlockIds::UNDERWATER_TORCH), "Underwater Torch")); - self::register(new Vine(new BID(BlockIds::VINE), "Vines")); - self::register(new Water(new BlockIdentifierFlattened(BlockIds::FLOWING_WATER, BlockIds::STILL_WATER), "Water")); - self::register(new WaterLily(new BID(BlockIds::LILY_PAD), "Lily Pad")); - self::register(new WeightedPressurePlateHeavy(new BID(BlockIds::HEAVY_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Heavy")); - self::register(new WeightedPressurePlateLight(new BID(BlockIds::LIGHT_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Light")); - self::register(new Wheat(new BID(BlockIds::WHEAT_BLOCK), "Wheat Block")); + self::register(new Quartz(new BID(BlockLegacyIds::QUARTZ_BLOCK, Quartz::SMOOTH), "Smooth Quartz Block")); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) + self::register(new QuartzStairs(new BID(BlockLegacyIds::QUARTZ_STAIRS), "Quartz Stairs")); + self::register(new Rail(new BID(BlockLegacyIds::RAIL), "Rail")); + self::register(new RedMushroom(new BID(BlockLegacyIds::RED_MUSHROOM), "Red Mushroom")); + self::register(new RedMushroomBlock(new BID(BlockLegacyIds::RED_MUSHROOM_BLOCK), "Red Mushroom Block")); + self::register(new Redstone(new BID(BlockLegacyIds::REDSTONE_BLOCK), "Redstone Block")); + self::register(new RedstoneComparator(new BlockIdentifierFlattened(BlockLegacyIds::UNPOWERED_COMPARATOR, BlockLegacyIds::POWERED_COMPARATOR, 0, ItemIds::COMPARATOR, Comparator::class), "Redstone Comparator")); + self::register(new RedstoneLamp(new BlockIdentifierFlattened(BlockLegacyIds::REDSTONE_LAMP, BlockLegacyIds::LIT_REDSTONE_LAMP), "Redstone Lamp")); + self::register(new RedstoneOre(new BlockIdentifierFlattened(BlockLegacyIds::REDSTONE_ORE, BlockLegacyIds::LIT_REDSTONE_ORE), "Redstone Ore")); + self::register(new RedstoneRepeater(new BlockIdentifierFlattened(BlockLegacyIds::UNPOWERED_REPEATER, BlockLegacyIds::POWERED_REPEATER, 0, ItemIds::REPEATER), "Redstone Repeater")); + self::register(new RedstoneTorch(new BlockIdentifierFlattened(BlockLegacyIds::REDSTONE_TORCH, BlockLegacyIds::UNLIT_REDSTONE_TORCH), "Redstone Torch")); + self::register(new RedstoneWire(new BID(BlockLegacyIds::REDSTONE_WIRE, 0, ItemIds::REDSTONE), "Redstone")); + self::register(new Reserved6(new BID(BlockLegacyIds::RESERVED6), "reserved6")); + self::register(new Sand(new BID(BlockLegacyIds::SAND), "Sand")); + self::register(new Sand(new BID(BlockLegacyIds::SAND, 1), "Red Sand")); + self::register(new SandstoneStairs(new BID(BlockLegacyIds::RED_SANDSTONE_STAIRS), "Red Sandstone Stairs")); + self::register(new SandstoneStairs(new BID(BlockLegacyIds::SANDSTONE_STAIRS), "Sandstone Stairs")); + self::register(new SeaLantern(new BID(BlockLegacyIds::SEALANTERN), "Sea Lantern")); + self::register(new SeaPickle(new BID(BlockLegacyIds::SEA_PICKLE), "Sea Pickle")); + self::register(new Skull(new BID(BlockLegacyIds::MOB_HEAD_BLOCK, 0, null, \pocketmine\tile\Skull::class), "Mob Head")); + self::register(new SmoothStone(new BID(BlockLegacyIds::STONE, Stone::NORMAL), "Stone")); + self::register(new Snow(new BID(BlockLegacyIds::SNOW), "Snow Block")); + self::register(new SnowLayer(new BID(BlockLegacyIds::SNOW_LAYER), "Snow Layer")); + self::register(new SoulSand(new BID(BlockLegacyIds::SOUL_SAND), "Soul Sand")); + self::register(new Sponge(new BID(BlockLegacyIds::SPONGE), "Sponge")); + self::register(new Stone(new BID(BlockLegacyIds::STONE, Stone::ANDESITE), "Andesite")); + self::register(new Stone(new BID(BlockLegacyIds::STONE, Stone::DIORITE), "Diorite")); + self::register(new Stone(new BID(BlockLegacyIds::STONE, Stone::GRANITE), "Granite")); + self::register(new Stone(new BID(BlockLegacyIds::STONE, Stone::POLISHED_ANDESITE), "Polished Andesite")); + self::register(new Stone(new BID(BlockLegacyIds::STONE, Stone::POLISHED_DIORITE), "Polished Diorite")); + self::register(new Stone(new BID(BlockLegacyIds::STONE, Stone::POLISHED_GRANITE), "Polished Granite")); + self::register(new StoneBrickStairs(new BID(BlockLegacyIds::STONE_BRICK_STAIRS), "Stone Brick Stairs")); + self::register(new StoneBricks(new BID(BlockLegacyIds::STONEBRICK, StoneBricks::CHISELED), "Chiseled Stone Bricks")); + self::register(new StoneBricks(new BID(BlockLegacyIds::STONEBRICK, StoneBricks::CRACKED), "Cracked Stone Bricks")); + self::register(new StoneBricks(new BID(BlockLegacyIds::STONEBRICK, StoneBricks::MOSSY), "Mossy Stone Bricks")); + self::register(new StoneBricks(new BID(BlockLegacyIds::STONEBRICK, StoneBricks::NORMAL), "Stone Bricks")); + self::register(new StoneButton(new BID(BlockLegacyIds::STONE_BUTTON), "Stone Button")); + self::register(new StonePressurePlate(new BID(BlockLegacyIds::STONE_PRESSURE_PLATE), "Stone Pressure Plate")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 0), "Stone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 1), "Sandstone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 2), "Fake Wooden")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 3), "Cobblestone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 4), "Brick")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 5), "Stone Brick")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 6), "Quartz")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 7), "Nether Brick")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, 0), "Red Sandstone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, 1), "Purpur")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, 2), "Prismarine")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, 3), "Dark Prismarine")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, 4), "Prismarine Bricks")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, 5), "Mossy Cobblestone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, 6), "Smooth Sandstone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, 7), "Red Nether Brick")); + self::register(new Stonecutter(new BID(BlockLegacyIds::STONECUTTER), "Stonecutter")); + self::register(new Sugarcane(new BID(BlockLegacyIds::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane")); + self::register(new TNT(new BID(BlockLegacyIds::TNT), "TNT")); + self::register(new TallGrass(new BID(BlockLegacyIds::TALLGRASS), "Fern")); + self::register(new TallGrass(new BID(BlockLegacyIds::TALLGRASS, 1), "Tall Grass")); + self::register(new TallGrass(new BID(BlockLegacyIds::TALLGRASS, 2), "Fern")); + self::register(new TallGrass(new BID(BlockLegacyIds::TALLGRASS, 3), "Fern")); + self::register(new Torch(new BID(BlockLegacyIds::COLORED_TORCH_BP), "Blue Torch")); + self::register(new Torch(new BID(BlockLegacyIds::COLORED_TORCH_BP, 8), "Purple Torch")); + self::register(new Torch(new BID(BlockLegacyIds::COLORED_TORCH_RG), "Red Torch")); + self::register(new Torch(new BID(BlockLegacyIds::COLORED_TORCH_RG, 8), "Green Torch")); + self::register(new Torch(new BID(BlockLegacyIds::TORCH), "Torch")); + self::register(new TrappedChest(new BID(BlockLegacyIds::TRAPPED_CHEST, 0, null, \pocketmine\tile\Chest::class), "Trapped Chest")); + self::register(new Tripwire(new BID(BlockLegacyIds::TRIPWIRE, 0, ItemIds::STRING), "Tripwire")); + self::register(new TripwireHook(new BID(BlockLegacyIds::TRIPWIRE_HOOK), "Tripwire Hook")); + self::register(new UnderwaterTorch(new BID(BlockLegacyIds::UNDERWATER_TORCH), "Underwater Torch")); + self::register(new Vine(new BID(BlockLegacyIds::VINE), "Vines")); + self::register(new Water(new BlockIdentifierFlattened(BlockLegacyIds::FLOWING_WATER, BlockLegacyIds::STILL_WATER), "Water")); + self::register(new WaterLily(new BID(BlockLegacyIds::LILY_PAD), "Lily Pad")); + self::register(new WeightedPressurePlateHeavy(new BID(BlockLegacyIds::HEAVY_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Heavy")); + self::register(new WeightedPressurePlateLight(new BID(BlockLegacyIds::LIGHT_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Light")); + self::register(new Wheat(new BID(BlockLegacyIds::WHEAT_BLOCK), "Wheat Block")); /** @var int[]|\SplObjectStorage $woodenStairIds */ $woodenStairIds = new \SplObjectStorage(); - $woodenStairIds[TreeType::OAK()] = BlockIds::OAK_STAIRS; - $woodenStairIds[TreeType::SPRUCE()] = BlockIds::SPRUCE_STAIRS; - $woodenStairIds[TreeType::BIRCH()] = BlockIds::BIRCH_STAIRS; - $woodenStairIds[TreeType::JUNGLE()] = BlockIds::JUNGLE_STAIRS; - $woodenStairIds[TreeType::ACACIA()] = BlockIds::ACACIA_STAIRS; - $woodenStairIds[TreeType::DARK_OAK()] = BlockIds::DARK_OAK_STAIRS; + $woodenStairIds[TreeType::OAK()] = BlockLegacyIds::OAK_STAIRS; + $woodenStairIds[TreeType::SPRUCE()] = BlockLegacyIds::SPRUCE_STAIRS; + $woodenStairIds[TreeType::BIRCH()] = BlockLegacyIds::BIRCH_STAIRS; + $woodenStairIds[TreeType::JUNGLE()] = BlockLegacyIds::JUNGLE_STAIRS; + $woodenStairIds[TreeType::ACACIA()] = BlockLegacyIds::ACACIA_STAIRS; + $woodenStairIds[TreeType::DARK_OAK()] = BlockLegacyIds::DARK_OAK_STAIRS; /** @var int[]|\SplObjectStorage $fenceGateIds */ $fenceGateIds = new \SplObjectStorage(); - $fenceGateIds[TreeType::OAK()] = BlockIds::OAK_FENCE_GATE; - $fenceGateIds[TreeType::SPRUCE()] = BlockIds::SPRUCE_FENCE_GATE; - $fenceGateIds[TreeType::BIRCH()] = BlockIds::BIRCH_FENCE_GATE; - $fenceGateIds[TreeType::JUNGLE()] = BlockIds::JUNGLE_FENCE_GATE; - $fenceGateIds[TreeType::ACACIA()] = BlockIds::ACACIA_FENCE_GATE; - $fenceGateIds[TreeType::DARK_OAK()] = BlockIds::DARK_OAK_FENCE_GATE; + $fenceGateIds[TreeType::OAK()] = BlockLegacyIds::OAK_FENCE_GATE; + $fenceGateIds[TreeType::SPRUCE()] = BlockLegacyIds::SPRUCE_FENCE_GATE; + $fenceGateIds[TreeType::BIRCH()] = BlockLegacyIds::BIRCH_FENCE_GATE; + $fenceGateIds[TreeType::JUNGLE()] = BlockLegacyIds::JUNGLE_FENCE_GATE; + $fenceGateIds[TreeType::ACACIA()] = BlockLegacyIds::ACACIA_FENCE_GATE; + $fenceGateIds[TreeType::DARK_OAK()] = BlockLegacyIds::DARK_OAK_FENCE_GATE; /** @var BID[]|\SplObjectStorage $woodenDoorIds */ $woodenDoorIds = new \SplObjectStorage(); - $woodenDoorIds[TreeType::OAK()] = new BID(BlockIds::OAK_DOOR_BLOCK, 0, ItemIds::OAK_DOOR); - $woodenDoorIds[TreeType::SPRUCE()] = new BID(BlockIds::SPRUCE_DOOR_BLOCK, 0, ItemIds::SPRUCE_DOOR); - $woodenDoorIds[TreeType::BIRCH()] = new BID(BlockIds::BIRCH_DOOR_BLOCK, 0, ItemIds::BIRCH_DOOR); - $woodenDoorIds[TreeType::JUNGLE()] = new BID(BlockIds::JUNGLE_DOOR_BLOCK, 0, ItemIds::JUNGLE_DOOR); - $woodenDoorIds[TreeType::ACACIA()] = new BID(BlockIds::ACACIA_DOOR_BLOCK, 0, ItemIds::ACACIA_DOOR); - $woodenDoorIds[TreeType::DARK_OAK()] = new BID(BlockIds::DARK_OAK_DOOR_BLOCK, 0, ItemIds::DARK_OAK_DOOR); + $woodenDoorIds[TreeType::OAK()] = new BID(BlockLegacyIds::OAK_DOOR_BLOCK, 0, ItemIds::OAK_DOOR); + $woodenDoorIds[TreeType::SPRUCE()] = new BID(BlockLegacyIds::SPRUCE_DOOR_BLOCK, 0, ItemIds::SPRUCE_DOOR); + $woodenDoorIds[TreeType::BIRCH()] = new BID(BlockLegacyIds::BIRCH_DOOR_BLOCK, 0, ItemIds::BIRCH_DOOR); + $woodenDoorIds[TreeType::JUNGLE()] = new BID(BlockLegacyIds::JUNGLE_DOOR_BLOCK, 0, ItemIds::JUNGLE_DOOR); + $woodenDoorIds[TreeType::ACACIA()] = new BID(BlockLegacyIds::ACACIA_DOOR_BLOCK, 0, ItemIds::ACACIA_DOOR); + $woodenDoorIds[TreeType::DARK_OAK()] = new BID(BlockLegacyIds::DARK_OAK_DOOR_BLOCK, 0, ItemIds::DARK_OAK_DOOR); /** @var int[]|\SplObjectStorage $woodenPressurePlateIds */ $woodenPressurePlateIds = new \SplObjectStorage(); - $woodenPressurePlateIds[TreeType::OAK()] = BlockIds::WOODEN_PRESSURE_PLATE; - $woodenPressurePlateIds[TreeType::SPRUCE()] = BlockIds::SPRUCE_PRESSURE_PLATE; - $woodenPressurePlateIds[TreeType::BIRCH()] = BlockIds::BIRCH_PRESSURE_PLATE; - $woodenPressurePlateIds[TreeType::JUNGLE()] = BlockIds::JUNGLE_PRESSURE_PLATE; - $woodenPressurePlateIds[TreeType::ACACIA()] = BlockIds::ACACIA_PRESSURE_PLATE; - $woodenPressurePlateIds[TreeType::DARK_OAK()] = BlockIds::DARK_OAK_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::OAK()] = BlockLegacyIds::WOODEN_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::SPRUCE()] = BlockLegacyIds::SPRUCE_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::BIRCH()] = BlockLegacyIds::BIRCH_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::JUNGLE()] = BlockLegacyIds::JUNGLE_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::ACACIA()] = BlockLegacyIds::ACACIA_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::DARK_OAK()] = BlockLegacyIds::DARK_OAK_PRESSURE_PLATE; /** @var int[]|\SplObjectStorage $woodenButtonIds */ $woodenButtonIds = new \SplObjectStorage(); - $woodenButtonIds[TreeType::OAK()] = BlockIds::WOODEN_BUTTON; - $woodenButtonIds[TreeType::SPRUCE()] = BlockIds::SPRUCE_BUTTON; - $woodenButtonIds[TreeType::BIRCH()] = BlockIds::BIRCH_BUTTON; - $woodenButtonIds[TreeType::JUNGLE()] = BlockIds::JUNGLE_BUTTON; - $woodenButtonIds[TreeType::ACACIA()] = BlockIds::ACACIA_BUTTON; - $woodenButtonIds[TreeType::DARK_OAK()] = BlockIds::DARK_OAK_BUTTON; + $woodenButtonIds[TreeType::OAK()] = BlockLegacyIds::WOODEN_BUTTON; + $woodenButtonIds[TreeType::SPRUCE()] = BlockLegacyIds::SPRUCE_BUTTON; + $woodenButtonIds[TreeType::BIRCH()] = BlockLegacyIds::BIRCH_BUTTON; + $woodenButtonIds[TreeType::JUNGLE()] = BlockLegacyIds::JUNGLE_BUTTON; + $woodenButtonIds[TreeType::ACACIA()] = BlockLegacyIds::ACACIA_BUTTON; + $woodenButtonIds[TreeType::DARK_OAK()] = BlockLegacyIds::DARK_OAK_BUTTON; /** @var int[]|\SplObjectStorage $woodenTrapdoorIds */ $woodenTrapdoorIds = new \SplObjectStorage(); - $woodenTrapdoorIds[TreeType::OAK()] = BlockIds::WOODEN_TRAPDOOR; - $woodenTrapdoorIds[TreeType::SPRUCE()] = BlockIds::SPRUCE_TRAPDOOR; - $woodenTrapdoorIds[TreeType::BIRCH()] = BlockIds::BIRCH_TRAPDOOR; - $woodenTrapdoorIds[TreeType::JUNGLE()] = BlockIds::JUNGLE_TRAPDOOR; - $woodenTrapdoorIds[TreeType::ACACIA()] = BlockIds::ACACIA_TRAPDOOR; - $woodenTrapdoorIds[TreeType::DARK_OAK()] = BlockIds::DARK_OAK_TRAPDOOR; + $woodenTrapdoorIds[TreeType::OAK()] = BlockLegacyIds::WOODEN_TRAPDOOR; + $woodenTrapdoorIds[TreeType::SPRUCE()] = BlockLegacyIds::SPRUCE_TRAPDOOR; + $woodenTrapdoorIds[TreeType::BIRCH()] = BlockLegacyIds::BIRCH_TRAPDOOR; + $woodenTrapdoorIds[TreeType::JUNGLE()] = BlockLegacyIds::JUNGLE_TRAPDOOR; + $woodenTrapdoorIds[TreeType::ACACIA()] = BlockLegacyIds::ACACIA_TRAPDOOR; + $woodenTrapdoorIds[TreeType::DARK_OAK()] = BlockLegacyIds::DARK_OAK_TRAPDOOR; /** @var BlockIdentifierFlattened[]|\SplObjectStorage $woodenSignIds */ $woodenSignIds = new \SplObjectStorage(); - $woodenSignIds[TreeType::OAK()] = new BlockIdentifierFlattened(BlockIds::SIGN_POST, BlockIds::WALL_SIGN, 0, ItemIds::SIGN, \pocketmine\tile\Sign::class); - $woodenSignIds[TreeType::SPRUCE()] = new BlockIdentifierFlattened(BlockIds::SPRUCE_STANDING_SIGN, BlockIds::SPRUCE_WALL_SIGN, 0, ItemIds::SPRUCE_SIGN, \pocketmine\tile\Sign::class); - $woodenSignIds[TreeType::BIRCH()] = new BlockIdentifierFlattened(BlockIds::BIRCH_STANDING_SIGN, BlockIds::BIRCH_WALL_SIGN, 0, ItemIds::BIRCH_SIGN, \pocketmine\tile\Sign::class); - $woodenSignIds[TreeType::JUNGLE()] = new BlockIdentifierFlattened(BlockIds::JUNGLE_STANDING_SIGN, BlockIds::JUNGLE_WALL_SIGN, 0, ItemIds::JUNGLE_SIGN, \pocketmine\tile\Sign::class); - $woodenSignIds[TreeType::ACACIA()] = new BlockIdentifierFlattened(BlockIds::ACACIA_STANDING_SIGN, BlockIds::ACACIA_WALL_SIGN, 0, ItemIds::ACACIA_SIGN, \pocketmine\tile\Sign::class); - $woodenSignIds[TreeType::DARK_OAK()] = new BlockIdentifierFlattened(BlockIds::DARKOAK_STANDING_SIGN, BlockIds::DARKOAK_WALL_SIGN, 0, ItemIds::DARKOAK_SIGN, \pocketmine\tile\Sign::class); + $woodenSignIds[TreeType::OAK()] = new BlockIdentifierFlattened(BlockLegacyIds::SIGN_POST, BlockLegacyIds::WALL_SIGN, 0, ItemIds::SIGN, \pocketmine\tile\Sign::class); + $woodenSignIds[TreeType::SPRUCE()] = new BlockIdentifierFlattened(BlockLegacyIds::SPRUCE_STANDING_SIGN, BlockLegacyIds::SPRUCE_WALL_SIGN, 0, ItemIds::SPRUCE_SIGN, \pocketmine\tile\Sign::class); + $woodenSignIds[TreeType::BIRCH()] = new BlockIdentifierFlattened(BlockLegacyIds::BIRCH_STANDING_SIGN, BlockLegacyIds::BIRCH_WALL_SIGN, 0, ItemIds::BIRCH_SIGN, \pocketmine\tile\Sign::class); + $woodenSignIds[TreeType::JUNGLE()] = new BlockIdentifierFlattened(BlockLegacyIds::JUNGLE_STANDING_SIGN, BlockLegacyIds::JUNGLE_WALL_SIGN, 0, ItemIds::JUNGLE_SIGN, \pocketmine\tile\Sign::class); + $woodenSignIds[TreeType::ACACIA()] = new BlockIdentifierFlattened(BlockLegacyIds::ACACIA_STANDING_SIGN, BlockLegacyIds::ACACIA_WALL_SIGN, 0, ItemIds::ACACIA_SIGN, \pocketmine\tile\Sign::class); + $woodenSignIds[TreeType::DARK_OAK()] = new BlockIdentifierFlattened(BlockLegacyIds::DARKOAK_STANDING_SIGN, BlockLegacyIds::DARKOAK_WALL_SIGN, 0, ItemIds::DARKOAK_SIGN, \pocketmine\tile\Sign::class); foreach(TreeType::getAll() as $treeType){ $magicNumber = $treeType->getMagicNumber(); $name = $treeType->getDisplayName(); - self::register(new Planks(new BID(BlockIds::PLANKS, $magicNumber), $name . " Planks")); - self::register(new Sapling(new BID(BlockIds::SAPLING, $magicNumber), $name . " Sapling", $treeType)); - self::register(new WoodenFence(new BID(BlockIds::FENCE, $magicNumber), $name . " Fence")); - self::register(new WoodenSlab(new BlockIdentifierFlattened(BlockIds::WOODEN_SLAB, BlockIds::DOUBLE_WOODEN_SLAB, $treeType->getMagicNumber()), $treeType->getDisplayName())); + self::register(new Planks(new BID(BlockLegacyIds::PLANKS, $magicNumber), $name . " Planks")); + self::register(new Sapling(new BID(BlockLegacyIds::SAPLING, $magicNumber), $name . " Sapling", $treeType)); + self::register(new WoodenFence(new BID(BlockLegacyIds::FENCE, $magicNumber), $name . " Fence")); + self::register(new WoodenSlab(new BlockIdentifierFlattened(BlockLegacyIds::WOODEN_SLAB, BlockLegacyIds::DOUBLE_WOODEN_SLAB, $treeType->getMagicNumber()), $treeType->getDisplayName())); //TODO: find a better way to deal with this split - self::register(new Leaves(new BID($magicNumber >= 4 ? BlockIds::LEAVES2 : BlockIds::LEAVES, $magicNumber & 0x03), $name . " Leaves", $treeType)); - self::register(new Log(new BID($magicNumber >= 4 ? BlockIds::LOG2 : BlockIds::LOG, $magicNumber & 0x03), $name . " Log", $treeType)); + self::register(new Leaves(new BID($magicNumber >= 4 ? BlockLegacyIds::LEAVES2 : BlockLegacyIds::LEAVES, $magicNumber & 0x03), $name . " Leaves", $treeType)); + self::register(new Log(new BID($magicNumber >= 4 ? BlockLegacyIds::LOG2 : BlockLegacyIds::LOG, $magicNumber & 0x03), $name . " Log", $treeType)); //TODO: the old bug-block needs to be remapped to the new dedicated block - self::register(new Wood(new BID($magicNumber >= 4 ? BlockIds::LOG2 : BlockIds::LOG, ($magicNumber & 0x03) | 0b1100), $name . " Wood", $treeType)); - self::register(new Wood(new BID(BlockIds::WOOD, $magicNumber), $name . " Wood", $treeType)); + self::register(new Wood(new BID($magicNumber >= 4 ? BlockLegacyIds::LOG2 : BlockLegacyIds::LOG, ($magicNumber & 0x03) | 0b1100), $name . " Wood", $treeType)); + self::register(new Wood(new BID(BlockLegacyIds::WOOD, $magicNumber), $name . " Wood", $treeType)); self::register(new FenceGate(new BID($fenceGateIds[$treeType]), $treeType->getDisplayName() . " Fence Gate")); self::register(new WoodenStairs(new BID($woodenStairIds[$treeType]), $treeType->getDisplayName() . " Stairs")); @@ -416,40 +416,40 @@ class BlockFactory{ Sandstone::SMOOTH => "Smooth " ]; foreach($sandstoneTypes as $variant => $prefix){ - self::register(new Sandstone(new BID(BlockIds::SANDSTONE, $variant), $prefix . "Sandstone")); - self::register(new Sandstone(new BID(BlockIds::RED_SANDSTONE, $variant), $prefix . "Red Sandstone")); + self::register(new Sandstone(new BID(BlockLegacyIds::SANDSTONE, $variant), $prefix . "Sandstone")); + self::register(new Sandstone(new BID(BlockLegacyIds::RED_SANDSTONE, $variant), $prefix . "Red Sandstone")); } /** @var int[]|\SplObjectStorage $glazedTerracottaIds */ $glazedTerracottaIds = new \SplObjectStorage(); - $glazedTerracottaIds[DyeColor::WHITE()] = BlockIds::WHITE_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::ORANGE()] = BlockIds::ORANGE_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::MAGENTA()] = BlockIds::MAGENTA_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::LIGHT_BLUE()] = BlockIds::LIGHT_BLUE_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::YELLOW()] = BlockIds::YELLOW_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::LIME()] = BlockIds::LIME_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::PINK()] = BlockIds::PINK_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::GRAY()] = BlockIds::GRAY_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::LIGHT_GRAY()] = BlockIds::SILVER_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::CYAN()] = BlockIds::CYAN_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::PURPLE()] = BlockIds::PURPLE_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::BLUE()] = BlockIds::BLUE_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::BROWN()] = BlockIds::BROWN_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::GREEN()] = BlockIds::GREEN_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::RED()] = BlockIds::RED_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::BLACK()] = BlockIds::BLACK_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::WHITE()] = BlockLegacyIds::WHITE_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::ORANGE()] = BlockLegacyIds::ORANGE_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::MAGENTA()] = BlockLegacyIds::MAGENTA_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::LIGHT_BLUE()] = BlockLegacyIds::LIGHT_BLUE_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::YELLOW()] = BlockLegacyIds::YELLOW_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::LIME()] = BlockLegacyIds::LIME_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::PINK()] = BlockLegacyIds::PINK_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::GRAY()] = BlockLegacyIds::GRAY_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::LIGHT_GRAY()] = BlockLegacyIds::SILVER_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::CYAN()] = BlockLegacyIds::CYAN_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::PURPLE()] = BlockLegacyIds::PURPLE_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::BLUE()] = BlockLegacyIds::BLUE_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::BROWN()] = BlockLegacyIds::BROWN_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::GREEN()] = BlockLegacyIds::GREEN_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::RED()] = BlockLegacyIds::RED_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::BLACK()] = BlockLegacyIds::BLACK_GLAZED_TERRACOTTA; foreach(DyeColor::getAll() as $color){ - self::register(new Carpet(new BID(BlockIds::CARPET, $color->getMagicNumber()), $color->getDisplayName() . " Carpet")); - self::register(new Concrete(new BID(BlockIds::CONCRETE, $color->getMagicNumber()), $color->getDisplayName() . " Concrete")); - self::register(new ConcretePowder(new BID(BlockIds::CONCRETE_POWDER, $color->getMagicNumber()), $color->getDisplayName() . " Concrete Powder")); - self::register(new Glass(new BID(BlockIds::STAINED_GLASS, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass")); - self::register(new GlassPane(new BID(BlockIds::STAINED_GLASS_PANE, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass Pane")); + self::register(new Carpet(new BID(BlockLegacyIds::CARPET, $color->getMagicNumber()), $color->getDisplayName() . " Carpet")); + self::register(new Concrete(new BID(BlockLegacyIds::CONCRETE, $color->getMagicNumber()), $color->getDisplayName() . " Concrete")); + self::register(new ConcretePowder(new BID(BlockLegacyIds::CONCRETE_POWDER, $color->getMagicNumber()), $color->getDisplayName() . " Concrete Powder")); + self::register(new Glass(new BID(BlockLegacyIds::STAINED_GLASS, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass")); + self::register(new GlassPane(new BID(BlockLegacyIds::STAINED_GLASS_PANE, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass Pane")); self::register(new GlazedTerracotta(new BID($glazedTerracottaIds[$color]), $color->getDisplayName() . " Glazed Terracotta")); - self::register(new HardenedClay(new BID(BlockIds::STAINED_CLAY, $color->getMagicNumber()), $color->getDisplayName() . " Stained Clay")); - self::register(new HardenedGlass(new BID(BlockIds::HARD_STAINED_GLASS, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass")); - self::register(new HardenedGlassPane(new BID(BlockIds::HARD_STAINED_GLASS_PANE, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass Pane")); - self::register(new Wool(new BID(BlockIds::WOOL, $color->getMagicNumber()), $color->getDisplayName() . " Wool")); + self::register(new HardenedClay(new BID(BlockLegacyIds::STAINED_CLAY, $color->getMagicNumber()), $color->getDisplayName() . " Stained Clay")); + self::register(new HardenedGlass(new BID(BlockLegacyIds::HARD_STAINED_GLASS, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass")); + self::register(new HardenedGlassPane(new BID(BlockLegacyIds::HARD_STAINED_GLASS_PANE, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass Pane")); + self::register(new Wool(new BID(BlockLegacyIds::WOOL, $color->getMagicNumber()), $color->getDisplayName() . " Wool")); } static $wallTypes = [ @@ -469,7 +469,7 @@ class BlockFactory{ CobblestoneWall::STONE_BRICK_WALL => "Stone Brick" ]; foreach($wallTypes as $magicNumber => $prefix){ - self::register(new CobblestoneWall(new BID(BlockIds::COBBLESTONE_WALL, $magicNumber), $prefix . " Wall")); + self::register(new CobblestoneWall(new BID(BlockLegacyIds::COBBLESTONE_WALL, $magicNumber), $prefix . " Wall")); } //TODO: minecraft:andesite_stairs @@ -707,7 +707,7 @@ class BlockFactory{ * if not found, try id+0 (strip meta) * if still not found, return update! block */ - return self::$staticRuntimeIdMap[($id << 4) | $meta] ?? self::$staticRuntimeIdMap[$id << 4] ?? self::$staticRuntimeIdMap[BlockIds::INFO_UPDATE << 4]; + return self::$staticRuntimeIdMap[($id << 4) | $meta] ?? self::$staticRuntimeIdMap[$id << 4] ?? self::$staticRuntimeIdMap[BlockLegacyIds::INFO_UPDATE << 4]; } /** diff --git a/src/pocketmine/block/BlockIds.php b/src/pocketmine/block/BlockLegacyIds.php similarity index 99% rename from src/pocketmine/block/BlockIds.php rename to src/pocketmine/block/BlockLegacyIds.php index 93aa32c937..67e110a60a 100644 --- a/src/pocketmine/block/BlockIds.php +++ b/src/pocketmine/block/BlockLegacyIds.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -interface BlockIds{ +interface BlockLegacyIds{ public const AIR = 0; public const STONE = 1; diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index 74842f3552..f52a149fd9 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -71,7 +71,7 @@ class Cactus extends Transparent{ public function onNearbyBlockChange() : void{ $down = $this->getSide(Facing::DOWN); - if($down->getId() !== BlockIds::SAND and $down->getId() !== BlockIds::CACTUS){ + if($down->getId() !== BlockLegacyIds::SAND and $down->getId() !== BlockLegacyIds::CACTUS){ $this->getLevel()->useBreakOn($this); }else{ foreach(Facing::HORIZONTAL as $side){ @@ -89,12 +89,12 @@ class Cactus extends Transparent{ } public function onRandomTick() : void{ - if($this->getSide(Facing::DOWN)->getId() !== BlockIds::CACTUS){ + if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::CACTUS){ if($this->age === 15){ for($y = 1; $y < 3; ++$y){ $b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z); - if($b->getId() === BlockIds::AIR){ - $ev = new BlockGrowEvent($b, BlockFactory::get(BlockIds::CACTUS)); + if($b->getId() === BlockLegacyIds::AIR){ + $ev = new BlockGrowEvent($b, BlockFactory::get(BlockLegacyIds::CACTUS)); $ev->call(); if($ev->isCancelled()){ break; @@ -115,7 +115,7 @@ class Cactus extends Transparent{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); - if($down->getId() === BlockIds::SAND or $down->getId() === BlockIds::CACTUS){ + if($down->getId() === BlockLegacyIds::SAND or $down->getId() === BlockLegacyIds::CACTUS){ foreach(Facing::HORIZONTAL as $side){ if($this->getSide($side)->isSolid()){ return false; diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index 37e9ddb9d1..6410a5cd91 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -63,7 +63,7 @@ class Cake extends Transparent implements FoodSource{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); - if($down->getId() !== BlockIds::AIR){ + if($down->getId() !== BlockLegacyIds::AIR){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -71,8 +71,8 @@ class Cake extends Transparent implements FoodSource{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::DOWN)->getId() === BlockIds::AIR){ //Replace with common break method - $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::AIR)); + if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ //Replace with common break method + $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); } } @@ -112,7 +112,7 @@ class Cake extends Transparent implements FoodSource{ $clone = clone $this; $clone->bites++; if($clone->bites > 6){ - $clone = BlockFactory::get(BlockIds::AIR); + $clone = BlockFactory::get(BlockLegacyIds::AIR); } return $clone; } diff --git a/src/pocketmine/block/Carpet.php b/src/pocketmine/block/Carpet.php index 882b06bb5c..8a11ea2edf 100644 --- a/src/pocketmine/block/Carpet.php +++ b/src/pocketmine/block/Carpet.php @@ -45,7 +45,7 @@ class Carpet extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); - if($down->getId() !== BlockIds::AIR){ + if($down->getId() !== BlockLegacyIds::AIR){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -53,7 +53,7 @@ class Carpet extends Flowable{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::DOWN)->getId() === BlockIds::AIR){ + if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/CoarseDirt.php b/src/pocketmine/block/CoarseDirt.php index 7791b378af..90ff2ef9d4 100644 --- a/src/pocketmine/block/CoarseDirt.php +++ b/src/pocketmine/block/CoarseDirt.php @@ -34,7 +34,7 @@ class CoarseDirt extends Dirt{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP and $item instanceof Hoe){ $item->applyDamage(1); - $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::DIRT)); + $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::DIRT)); return true; } diff --git a/src/pocketmine/block/CobblestoneWall.php b/src/pocketmine/block/CobblestoneWall.php index 3aad8e8c85..79579f1172 100644 --- a/src/pocketmine/block/CobblestoneWall.php +++ b/src/pocketmine/block/CobblestoneWall.php @@ -72,7 +72,7 @@ class CobblestoneWall extends Transparent{ } } - $this->up = $this->getSide(Facing::UP)->getId() !== BlockIds::AIR; + $this->up = $this->getSide(Facing::UP)->getId() !== BlockLegacyIds::AIR; } protected function recalculateBoundingBox() : ?AxisAlignedBB{ diff --git a/src/pocketmine/block/ConcretePowder.php b/src/pocketmine/block/ConcretePowder.php index 64c85c2ce6..fae849dac8 100644 --- a/src/pocketmine/block/ConcretePowder.php +++ b/src/pocketmine/block/ConcretePowder.php @@ -64,7 +64,7 @@ class ConcretePowder extends Solid implements Fallable{ continue; } if($this->getSide($i) instanceof Water){ - return BlockFactory::get(BlockIds::CONCRETE, $this->idInfo->getVariant()); + return BlockFactory::get(BlockLegacyIds::CONCRETE, $this->idInfo->getVariant()); } } diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index fbdd6387c3..9f39280d3a 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -49,7 +49,7 @@ abstract class Crops extends Flowable{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($blockReplace->getSide(Facing::DOWN)->getId() === BlockIds::FARMLAND){ + if($blockReplace->getSide(Facing::DOWN)->getId() === BlockLegacyIds::FARMLAND){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -80,7 +80,7 @@ abstract class Crops extends Flowable{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::DOWN)->getId() !== BlockIds::FARMLAND){ + if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::FARMLAND){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/Dandelion.php b/src/pocketmine/block/Dandelion.php index 0c588d2ba0..dda14ad05c 100644 --- a/src/pocketmine/block/Dandelion.php +++ b/src/pocketmine/block/Dandelion.php @@ -33,7 +33,7 @@ class Dandelion extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); - if($down->getId() === BlockIds::GRASS or $down->getId() === BlockIds::DIRT or $down->getId() === BlockIds::FARMLAND){ + if($down->getId() === BlockLegacyIds::GRASS or $down->getId() === BlockLegacyIds::DIRT or $down->getId() === BlockLegacyIds::FARMLAND){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/pocketmine/block/Dirt.php b/src/pocketmine/block/Dirt.php index a7fd382629..663544e52e 100644 --- a/src/pocketmine/block/Dirt.php +++ b/src/pocketmine/block/Dirt.php @@ -44,7 +44,7 @@ class Dirt extends Solid{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP and $item instanceof Hoe){ $item->applyDamage(1); - $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::FARMLAND)); + $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::FARMLAND)); return true; } diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index ed7d745461..314b8d0f9d 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -98,7 +98,7 @@ abstract class Door extends Transparent{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::DOWN)->getId() === BlockIds::AIR){ //Replace with common break method + if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ //Replace with common break method $this->getLevel()->useBreakOn($this); //this will delete both halves if they exist } } diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index 3f3264a35c..60c1f6c3d3 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -49,7 +49,7 @@ class DoublePlant extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $id = $blockReplace->getSide(Facing::DOWN)->getId(); - if(($id === BlockIds::GRASS or $id === BlockIds::DIRT) and $blockReplace->getSide(Facing::UP)->canBeReplaced()){ + if(($id === BlockLegacyIds::GRASS or $id === BlockLegacyIds::DIRT) and $blockReplace->getSide(Facing::UP)->canBeReplaced()){ $top = clone $this; $top->top = true; diff --git a/src/pocketmine/block/DragonEgg.php b/src/pocketmine/block/DragonEgg.php index 73c11042fa..e9c44045f5 100644 --- a/src/pocketmine/block/DragonEgg.php +++ b/src/pocketmine/block/DragonEgg.php @@ -78,7 +78,7 @@ class DragonEgg extends Transparent implements Fallable{ if($block instanceof Air){ $this->level->addParticle($this, new DragonEggTeleportParticle($this->x - $block->x, $this->y - $block->y, $this->z - $block->z)); //TODO: add events - $this->level->setBlock($this, BlockFactory::get(BlockIds::AIR)); + $this->level->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); $this->level->setBlock($block, $this); break; } diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index 0585568419..b762e6aa2b 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -60,7 +60,7 @@ class Farmland extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::UP)->isSolid()){ - $this->level->setBlock($this, BlockFactory::get(BlockIds::DIRT)); + $this->level->setBlock($this, BlockFactory::get(BlockLegacyIds::DIRT)); } } @@ -74,7 +74,7 @@ class Farmland extends Transparent{ $this->wetness--; $this->level->setBlock($this, $this, false); }else{ - $this->level->setBlock($this, BlockFactory::get(BlockIds::DIRT)); + $this->level->setBlock($this, BlockFactory::get(BlockLegacyIds::DIRT)); } }elseif($this->wetness < 7){ $this->wetness = 7; diff --git a/src/pocketmine/block/Fire.php b/src/pocketmine/block/Fire.php index 8b0a578df2..dd739f50b7 100644 --- a/src/pocketmine/block/Fire.php +++ b/src/pocketmine/block/Fire.php @@ -88,7 +88,7 @@ class Fire extends Flowable{ public function onNearbyBlockChange() : void{ if(!$this->getSide(Facing::DOWN)->isSolid() and !$this->hasAdjacentFlammableBlocks()){ - $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::AIR)); + $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); }else{ $this->level->scheduleDelayedBlockUpdate($this, mt_rand(30, 40)); } @@ -113,12 +113,12 @@ class Fire extends Flowable{ if($this->age === 15){ if(!$down->isFlammable() and mt_rand(0, 3) === 3){ //1/4 chance to extinguish $canSpread = false; - $result = BlockFactory::get(BlockIds::AIR); + $result = BlockFactory::get(BlockLegacyIds::AIR); } }elseif(!$this->hasAdjacentFlammableBlocks()){ $canSpread = false; if(!$down->isSolid() or $this->age > 3){ - $result = BlockFactory::get(BlockIds::AIR); + $result = BlockFactory::get(BlockLegacyIds::AIR); } } } @@ -170,7 +170,7 @@ class Fire extends Flowable{ $fire->age = min(15, $fire->age + (mt_rand(0, 4) >> 2)); $this->level->setBlock($block, $fire); }else{ - $this->level->setBlock($block, BlockFactory::get(BlockIds::AIR)); + $this->level->setBlock($block, BlockFactory::get(BlockLegacyIds::AIR)); } } } diff --git a/src/pocketmine/block/Flower.php b/src/pocketmine/block/Flower.php index ff8f31b940..d4d2949acf 100644 --- a/src/pocketmine/block/Flower.php +++ b/src/pocketmine/block/Flower.php @@ -43,7 +43,7 @@ class Flower extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); - if($down->getId() === BlockIds::GRASS or $down->getId() === BlockIds::DIRT or $down->getId() === BlockIds::FARMLAND){ + if($down->getId() === BlockLegacyIds::GRASS or $down->getId() === BlockLegacyIds::DIRT or $down->getId() === BlockLegacyIds::FARMLAND){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index 9557c25182..ec7325053e 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -60,7 +60,7 @@ class Grass extends Solid{ $lightAbove = $this->level->getFullLightAt($this->x, $this->y + 1, $this->z); if($lightAbove < 4 and $this->level->getBlockAt($this->x, $this->y + 1, $this->z)->getLightFilter() >= 2){ //grass dies - $ev = new BlockSpreadEvent($this, $this, BlockFactory::get(BlockIds::DIRT)); + $ev = new BlockSpreadEvent($this, $this, BlockFactory::get(BlockLegacyIds::DIRT)); $ev->call(); if(!$ev->isCancelled()){ $this->level->setBlock($this, $ev->getNewState(), false); @@ -82,7 +82,7 @@ class Grass extends Solid{ continue; } - $ev = new BlockSpreadEvent($b, $this, BlockFactory::get(BlockIds::GRASS)); + $ev = new BlockSpreadEvent($b, $this, BlockFactory::get(BlockLegacyIds::GRASS)); $ev->call(); if(!$ev->isCancelled()){ $this->level->setBlock($b, $ev->getNewState(), false); @@ -102,12 +102,12 @@ class Grass extends Solid{ return true; }elseif($item instanceof Hoe){ $item->applyDamage(1); - $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::FARMLAND)); + $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::FARMLAND)); return true; - }elseif($item instanceof Shovel and $this->getSide(Facing::UP)->getId() === BlockIds::AIR){ + }elseif($item instanceof Shovel and $this->getSide(Facing::UP)->getId() === BlockLegacyIds::AIR){ $item->applyDamage(1); - $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::GRASS_PATH)); + $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::GRASS_PATH)); return true; } diff --git a/src/pocketmine/block/GrassPath.php b/src/pocketmine/block/GrassPath.php index ec6c9c53f0..74b426a3de 100644 --- a/src/pocketmine/block/GrassPath.php +++ b/src/pocketmine/block/GrassPath.php @@ -44,7 +44,7 @@ class GrassPath extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::UP)->isSolid()){ - $this->level->setBlock($this, BlockFactory::get(BlockIds::DIRT)); + $this->level->setBlock($this, BlockFactory::get(BlockLegacyIds::DIRT)); } } diff --git a/src/pocketmine/block/Ice.php b/src/pocketmine/block/Ice.php index 89f9e20058..2427fc00c4 100644 --- a/src/pocketmine/block/Ice.php +++ b/src/pocketmine/block/Ice.php @@ -47,7 +47,7 @@ class Ice extends Transparent{ public function onBreak(Item $item, ?Player $player = null) : bool{ if(($player === null or $player->isSurvival()) and !$item->hasEnchantment(Enchantment::SILK_TOUCH())){ - return $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::WATER)); + return $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::WATER)); } return parent::onBreak($item, $player); } diff --git a/src/pocketmine/block/Lava.php b/src/pocketmine/block/Lava.php index 1e339927a7..4ac9013d3d 100644 --- a/src/pocketmine/block/Lava.php +++ b/src/pocketmine/block/Lava.php @@ -67,16 +67,16 @@ class Lava extends Liquid{ if($colliding !== null){ if($this->decay === 0){ - $this->liquidCollide($colliding, BlockFactory::get(BlockIds::OBSIDIAN)); + $this->liquidCollide($colliding, BlockFactory::get(BlockLegacyIds::OBSIDIAN)); }elseif($this->decay <= 4){ - $this->liquidCollide($colliding, BlockFactory::get(BlockIds::COBBLESTONE)); + $this->liquidCollide($colliding, BlockFactory::get(BlockLegacyIds::COBBLESTONE)); } } } protected function flowIntoBlock(Block $block, int $newFlowDecay, bool $falling) : void{ if($block instanceof Water){ - $block->liquidCollide($this, BlockFactory::get(BlockIds::STONE)); + $block->liquidCollide($this, BlockFactory::get(BlockLegacyIds::STONE)); }else{ parent::flowIntoBlock($block, $newFlowDecay, $falling); } diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index 0c88ef3f98..e0319ee071 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -289,7 +289,7 @@ abstract class Liquid extends Transparent{ if($falling !== $this->falling or (!$falling and $newDecay !== $this->decay)){ if(!$falling and $newDecay < 0){ - $this->level->setBlock($this, BlockFactory::get(BlockIds::AIR)); + $this->level->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); return; } diff --git a/src/pocketmine/block/MelonStem.php b/src/pocketmine/block/MelonStem.php index 047912e92b..9486b4df35 100644 --- a/src/pocketmine/block/MelonStem.php +++ b/src/pocketmine/block/MelonStem.php @@ -26,6 +26,6 @@ namespace pocketmine\block; class MelonStem extends Stem{ protected function getPlant() : Block{ - return BlockFactory::get(BlockIds::MELON_BLOCK); + return BlockFactory::get(BlockLegacyIds::MELON_BLOCK); } } diff --git a/src/pocketmine/block/Mycelium.php b/src/pocketmine/block/Mycelium.php index 69a9f5cc1c..5870822c25 100644 --- a/src/pocketmine/block/Mycelium.php +++ b/src/pocketmine/block/Mycelium.php @@ -55,9 +55,9 @@ class Mycelium extends Solid{ $y = mt_rand($this->y - 2, $this->y + 2); $z = mt_rand($this->z - 1, $this->z + 1); $block = $this->getLevel()->getBlockAt($x, $y, $z); - if($block->getId() === BlockIds::DIRT){ + if($block->getId() === BlockLegacyIds::DIRT){ if($block->getSide(Facing::UP) instanceof Transparent){ - $ev = new BlockSpreadEvent($block, $this, BlockFactory::get(BlockIds::MYCELIUM)); + $ev = new BlockSpreadEvent($block, $this, BlockFactory::get(BlockLegacyIds::MYCELIUM)); $ev->call(); if(!$ev->isCancelled()){ $this->getLevel()->setBlock($block, $ev->getNewState()); diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index 995d6dc081..b1c8661ed5 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -51,7 +51,7 @@ class NetherWartPlant extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); - if($down->getId() === BlockIds::SOUL_SAND){ + if($down->getId() === BlockLegacyIds::SOUL_SAND){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -59,7 +59,7 @@ class NetherWartPlant extends Flowable{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::DOWN)->getId() !== BlockIds::SOUL_SAND){ + if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::SOUL_SAND){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/PumpkinStem.php b/src/pocketmine/block/PumpkinStem.php index 0090a9d681..12ae62c161 100644 --- a/src/pocketmine/block/PumpkinStem.php +++ b/src/pocketmine/block/PumpkinStem.php @@ -26,6 +26,6 @@ namespace pocketmine\block; class PumpkinStem extends Stem{ protected function getPlant() : Block{ - return BlockFactory::get(BlockIds::PUMPKIN); + return BlockFactory::get(BlockLegacyIds::PUMPKIN); } } diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index 79e1394e55..86d9c54974 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -59,7 +59,7 @@ class Sapling extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); - if($down->getId() === BlockIds::GRASS or $down->getId() === BlockIds::DIRT or $down->getId() === BlockIds::FARMLAND){ + if($down->getId() === BlockLegacyIds::GRASS or $down->getId() === BlockLegacyIds::DIRT or $down->getId() === BlockLegacyIds::FARMLAND){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/pocketmine/block/Sign.php b/src/pocketmine/block/Sign.php index ef1952c474..3d055b3cbe 100644 --- a/src/pocketmine/block/Sign.php +++ b/src/pocketmine/block/Sign.php @@ -126,7 +126,7 @@ class Sign extends Transparent{ } public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::opposite($this->facing))->getId() === BlockIds::AIR){ + if($this->getSide(Facing::opposite($this->facing))->getId() === BlockLegacyIds::AIR){ $this->getLevel()->useBreakOn($this); } } diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index 1b48fc1fa1..f7a4a2bee1 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -96,7 +96,7 @@ class SnowLayer extends Flowable implements Fallable{ public function onRandomTick() : void{ if($this->level->getBlockLightAt($this->x, $this->y, $this->z) >= 12){ - $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::AIR), false); + $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR), false); } } diff --git a/src/pocketmine/block/Stem.php b/src/pocketmine/block/Stem.php index 2d03b7924b..397bcd8e56 100644 --- a/src/pocketmine/block/Stem.php +++ b/src/pocketmine/block/Stem.php @@ -53,7 +53,7 @@ abstract class Stem extends Crops{ $side = $this->getSide(Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)]); $d = $side->getSide(Facing::DOWN); - if($side->getId() === BlockIds::AIR and ($d->getId() === BlockIds::FARMLAND or $d->getId() === BlockIds::GRASS or $d->getId() === BlockIds::DIRT)){ + if($side->getId() === BlockLegacyIds::AIR and ($d->getId() === BlockLegacyIds::FARMLAND or $d->getId() === BlockLegacyIds::GRASS or $d->getId() === BlockLegacyIds::DIRT)){ $ev = new BlockGrowEvent($side, $grow); $ev->call(); if(!$ev->isCancelled()){ diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index 5e539f79d5..6823a8eb91 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -50,11 +50,11 @@ class Sugarcane extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof Fertilizer){ - if($this->getSide(Facing::DOWN)->getId() !== BlockIds::SUGARCANE_BLOCK){ + if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::SUGARCANE_BLOCK){ for($y = 1; $y < 3; ++$y){ $b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z); - if($b->getId() === BlockIds::AIR){ - $ev = new BlockGrowEvent($b, BlockFactory::get(BlockIds::SUGARCANE_BLOCK)); + if($b->getId() === BlockLegacyIds::AIR){ + $ev = new BlockGrowEvent($b, BlockFactory::get(BlockLegacyIds::SUGARCANE_BLOCK)); $ev->call(); if($ev->isCancelled()){ break; @@ -78,7 +78,7 @@ class Sugarcane extends Flowable{ public function onNearbyBlockChange() : void{ $down = $this->getSide(Facing::DOWN); - if($down->isTransparent() and $down->getId() !== BlockIds::SUGARCANE_BLOCK){ + if($down->isTransparent() and $down->getId() !== BlockLegacyIds::SUGARCANE_BLOCK){ $this->getLevel()->useBreakOn($this); } } @@ -88,12 +88,12 @@ class Sugarcane extends Flowable{ } public function onRandomTick() : void{ - if($this->getSide(Facing::DOWN)->getId() !== BlockIds::SUGARCANE_BLOCK){ + if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::SUGARCANE_BLOCK){ if($this->age === 15){ for($y = 1; $y < 3; ++$y){ $b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z); - if($b->getId() === BlockIds::AIR){ - $this->getLevel()->setBlock($b, BlockFactory::get(BlockIds::SUGARCANE_BLOCK)); + if($b->getId() === BlockLegacyIds::AIR){ + $this->getLevel()->setBlock($b, BlockFactory::get(BlockLegacyIds::SUGARCANE_BLOCK)); break; } } @@ -108,9 +108,9 @@ class Sugarcane extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); - if($down->getId() === BlockIds::SUGARCANE_BLOCK){ + if($down->getId() === BlockLegacyIds::SUGARCANE_BLOCK){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); - }elseif($down->getId() === BlockIds::GRASS or $down->getId() === BlockIds::DIRT or $down->getId() === BlockIds::SAND){ + }elseif($down->getId() === BlockLegacyIds::GRASS or $down->getId() === BlockLegacyIds::DIRT or $down->getId() === BlockLegacyIds::SAND){ foreach(Facing::HORIZONTAL as $side){ if($down->getSide($side) instanceof Water){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index 741d81524a..226eff1371 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -90,7 +90,7 @@ class TNT extends Solid{ } public function ignite(int $fuse = 80) : void{ - $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::AIR)); + $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); $mot = (new Random())->nextSignedFloat() * M_PI * 2; $nbt = EntityFactory::createBaseNBT($this->add(0.5, 0, 0.5), new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02)); diff --git a/src/pocketmine/block/TallGrass.php b/src/pocketmine/block/TallGrass.php index 0c3b7f4a4c..5fba37304d 100644 --- a/src/pocketmine/block/TallGrass.php +++ b/src/pocketmine/block/TallGrass.php @@ -38,7 +38,7 @@ class TallGrass extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN)->getId(); - if($down === BlockIds::GRASS or $down === BlockIds::DIRT){ + if($down === BlockLegacyIds::GRASS or $down === BlockLegacyIds::DIRT){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -47,7 +47,7 @@ class TallGrass extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ //Replace with common break method - $this->getLevel()->setBlock($this, BlockFactory::get(BlockIds::AIR)); + $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); } } diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index 2643398abd..4a45c706f3 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -54,7 +54,7 @@ class Torch extends Flowable{ $below = $this->getSide(Facing::DOWN); $face = Facing::opposite($this->facing); - if($this->getSide($face)->isTransparent() and !($face === Facing::DOWN and ($below->getId() === BlockIds::FENCE or $below->getId() === BlockIds::COBBLESTONE_WALL))){ + if($this->getSide($face)->isTransparent() and !($face === Facing::DOWN and ($below->getId() === BlockLegacyIds::FENCE or $below->getId() === BlockLegacyIds::COBBLESTONE_WALL))){ $this->getLevel()->useBreakOn($this); } } @@ -63,7 +63,7 @@ class Torch extends Flowable{ if($blockClicked->canBeReplaced() and !$blockClicked->getSide(Facing::DOWN)->isTransparent()){ $this->facing = Facing::UP; return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); - }elseif($face !== Facing::DOWN and (!$blockClicked->isTransparent() or ($face === Facing::UP and ($blockClicked->getId() === BlockIds::FENCE or $blockClicked->getId() === BlockIds::COBBLESTONE_WALL)))){ + }elseif($face !== Facing::DOWN and (!$blockClicked->isTransparent() or ($face === Facing::UP and ($blockClicked->getId() === BlockLegacyIds::FENCE or $blockClicked->getId() === BlockLegacyIds::COBBLESTONE_WALL)))){ $this->facing = $face; return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); }else{ diff --git a/src/pocketmine/block/utils/FallableTrait.php b/src/pocketmine/block/utils/FallableTrait.php index dfb3f36495..451af2221d 100644 --- a/src/pocketmine/block/utils/FallableTrait.php +++ b/src/pocketmine/block/utils/FallableTrait.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block\utils; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\block\Fire; use pocketmine\block\Liquid; use pocketmine\entity\EntityFactory; @@ -48,8 +48,8 @@ trait FallableTrait{ public function onNearbyBlockChange() : void{ $pos = $this->asPosition(); $down = $pos->level->getBlock($pos->getSide(Facing::DOWN)); - if($down->getId() === BlockIds::AIR or $down instanceof Liquid or $down instanceof Fire){ - $pos->level->setBlock($pos, BlockFactory::get(BlockIds::AIR)); + if($down->getId() === BlockLegacyIds::AIR or $down instanceof Liquid or $down instanceof Fire){ + $pos->level->setBlock($pos, BlockFactory::get(BlockLegacyIds::AIR)); $nbt = EntityFactory::createBaseNBT($pos->add(0.5, 0, 0.5)); $nbt->setInt("TileID", $this->getId()); diff --git a/src/pocketmine/entity/object/Painting.php b/src/pocketmine/entity/object/Painting.php index b2f95f4023..18d143704f 100644 --- a/src/pocketmine/entity/object/Painting.php +++ b/src/pocketmine/entity/object/Painting.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity\object; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\entity\Entity; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\item\Item; @@ -109,7 +109,7 @@ class Painting extends Entity{ //non-living entities don't have a way to create drops generically yet $this->level->dropItem($this, ItemFactory::get(Item::PAINTING)); } - $this->level->addParticle($this->add(0.5, 0.5, 0.5), new DestroyBlockParticle(BlockFactory::get(BlockIds::PLANKS))); + $this->level->addParticle($this->add(0.5, 0.5, 0.5), new DestroyBlockParticle(BlockFactory::get(BlockLegacyIds::PLANKS))); } protected function recalculateBoundingBox() : void{ diff --git a/src/pocketmine/entity/projectile/EnderPearl.php b/src/pocketmine/entity/projectile/EnderPearl.php index c1cbab8d16..da9610732c 100644 --- a/src/pocketmine/entity/projectile/EnderPearl.php +++ b/src/pocketmine/entity/projectile/EnderPearl.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity\projectile; use pocketmine\block\Block; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\level\sound\EndermanTeleportSound; @@ -37,7 +37,7 @@ class EnderPearl extends Throwable{ public const NETWORK_ID = self::ENDER_PEARL; protected function calculateInterceptWithBlock(Block $block, Vector3 $start, Vector3 $end) : ?RayTraceResult{ - if($block->getId() !== BlockIds::AIR and empty($block->getCollisionBoxes())){ + if($block->getId() !== BlockLegacyIds::AIR and empty($block->getCollisionBoxes())){ //TODO: remove this once block collision boxes are fixed properly return AxisAlignedBB::one()->offset($block->x, $block->y, $block->z)->calculateIntercept($start, $end); } diff --git a/src/pocketmine/entity/projectile/SplashPotion.php b/src/pocketmine/entity/projectile/SplashPotion.php index 36eb780f82..54e93c2e3e 100644 --- a/src/pocketmine/entity/projectile/SplashPotion.php +++ b/src/pocketmine/entity/projectile/SplashPotion.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity\projectile; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\InstantEffect; use pocketmine\entity\Living; @@ -121,12 +121,12 @@ class SplashPotion extends Throwable{ }elseif($event instanceof ProjectileHitBlockEvent and $this->getPotionId() === Potion::WATER){ $blockIn = $event->getBlockHit()->getSide($event->getRayTraceResult()->getHitFace()); - if($blockIn->getId() === BlockIds::FIRE){ - $this->level->setBlock($blockIn, BlockFactory::get(BlockIds::AIR)); + if($blockIn->getId() === BlockLegacyIds::FIRE){ + $this->level->setBlock($blockIn, BlockFactory::get(BlockLegacyIds::AIR)); } foreach($blockIn->getHorizontalSides() as $horizontalSide){ - if($horizontalSide->getId() === BlockIds::FIRE){ - $this->level->setBlock($horizontalSide, BlockFactory::get(BlockIds::AIR)); + if($horizontalSide->getId() === BlockLegacyIds::FIRE){ + $this->level->setBlock($horizontalSide, BlockFactory::get(BlockLegacyIds::AIR)); } } } diff --git a/src/pocketmine/event/player/PlayerDeathEvent.php b/src/pocketmine/event/player/PlayerDeathEvent.php index 634f53f758..af2d229904 100644 --- a/src/pocketmine/event/player/PlayerDeathEvent.php +++ b/src/pocketmine/event/player/PlayerDeathEvent.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\event\player; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\entity\Living; use pocketmine\event\entity\EntityDamageByBlockEvent; use pocketmine\event\entity\EntityDamageByEntityEvent; @@ -170,7 +170,7 @@ class PlayerDeathEvent extends EntityDeathEvent{ case EntityDamageEvent::CAUSE_CONTACT: if($deathCause instanceof EntityDamageByBlockEvent){ - if($deathCause->getDamager()->getId() === BlockIds::CACTUS){ + if($deathCause->getDamager()->getId() === BlockLegacyIds::CACTUS){ $message = "death.attack.cactus"; } } diff --git a/src/pocketmine/item/Banner.php b/src/pocketmine/item/Banner.php index 0425a4f376..473158f623 100644 --- a/src/pocketmine/item/Banner.php +++ b/src/pocketmine/item/Banner.php @@ -26,7 +26,7 @@ namespace pocketmine\item; use Ds\Deque; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\BannerPattern; use pocketmine\block\utils\DyeColor; use pocketmine\nbt\tag\CompoundTag; @@ -54,7 +54,7 @@ class Banner extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(BlockIds::STANDING_BANNER); + return BlockFactory::get(BlockLegacyIds::STANDING_BANNER); } public function getMaxStackSize() : int{ diff --git a/src/pocketmine/item/Bed.php b/src/pocketmine/item/Bed.php index 9c0a16271b..3b83cd19f2 100644 --- a/src/pocketmine/item/Bed.php +++ b/src/pocketmine/item/Bed.php @@ -25,7 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\DyeColor; class Bed extends Item{ @@ -46,7 +46,7 @@ class Bed extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(BlockIds::BED_BLOCK); + return BlockFactory::get(BlockLegacyIds::BED_BLOCK); } public function getMaxStackSize() : int{ diff --git a/src/pocketmine/item/BeetrootSeeds.php b/src/pocketmine/item/BeetrootSeeds.php index ce33238165..a5f961f60a 100644 --- a/src/pocketmine/item/BeetrootSeeds.php +++ b/src/pocketmine/item/BeetrootSeeds.php @@ -25,7 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; class BeetrootSeeds extends Item{ public function __construct(){ @@ -33,6 +33,6 @@ class BeetrootSeeds extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(BlockIds::BEETROOT_BLOCK); + return BlockFactory::get(BlockLegacyIds::BEETROOT_BLOCK); } } diff --git a/src/pocketmine/item/Bucket.php b/src/pocketmine/item/Bucket.php index 7c7abc5a06..f23ce0dd1e 100644 --- a/src/pocketmine/item/Bucket.php +++ b/src/pocketmine/item/Bucket.php @@ -25,7 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\block\Liquid; use pocketmine\event\player\PlayerBucketFillEvent; use pocketmine\math\Vector3; @@ -47,7 +47,7 @@ class Bucket extends Item{ $ev = new PlayerBucketFillEvent($player, $blockReplace, $face, $this, $resultItem); $ev->call(); if(!$ev->isCancelled()){ - $player->getLevel()->setBlock($blockClicked, BlockFactory::get(BlockIds::AIR)); + $player->getLevel()->setBlock($blockClicked, BlockFactory::get(BlockLegacyIds::AIR)); $player->getLevel()->broadcastLevelSoundEvent($blockClicked->add(0.5, 0.5, 0.5), $blockClicked->getBucketFillSound()); if($player->isSurvival()){ if($stack->getCount() === 0){ diff --git a/src/pocketmine/item/Carrot.php b/src/pocketmine/item/Carrot.php index 7bd2f211eb..e402f07eeb 100644 --- a/src/pocketmine/item/Carrot.php +++ b/src/pocketmine/item/Carrot.php @@ -25,7 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; class Carrot extends Food{ public function __construct(){ @@ -33,7 +33,7 @@ class Carrot extends Food{ } public function getBlock() : Block{ - return BlockFactory::get(BlockIds::CARROT_BLOCK); + return BlockFactory::get(BlockLegacyIds::CARROT_BLOCK); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/CocoaBeans.php b/src/pocketmine/item/CocoaBeans.php index 69fff936f3..d1461e9846 100644 --- a/src/pocketmine/item/CocoaBeans.php +++ b/src/pocketmine/item/CocoaBeans.php @@ -25,11 +25,11 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; class CocoaBeans extends Item{ public function getBlock() : Block{ - return BlockFactory::get(BlockIds::COCOA); + return BlockFactory::get(BlockLegacyIds::COCOA); } } diff --git a/src/pocketmine/item/FlintSteel.php b/src/pocketmine/item/FlintSteel.php index 21673d9821..ba1752d12c 100644 --- a/src/pocketmine/item/FlintSteel.php +++ b/src/pocketmine/item/FlintSteel.php @@ -25,7 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\Player; @@ -37,10 +37,10 @@ class FlintSteel extends Tool{ } public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ - if($blockReplace->getId() === BlockIds::AIR){ + if($blockReplace->getId() === BlockLegacyIds::AIR){ $level = $player->getLevel(); assert($level !== null); - $level->setBlock($blockReplace, BlockFactory::get(BlockIds::FIRE)); + $level->setBlock($blockReplace, BlockFactory::get(BlockLegacyIds::FIRE)); $level->broadcastLevelSoundEvent($blockReplace->add(0.5, 0.5, 0.5), LevelSoundEventPacket::SOUND_IGNITE); $this->applyDamage(1); diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 8f4f4dd435..82877b40d7 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -28,7 +28,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\block\BlockToolType; use pocketmine\entity\Entity; use pocketmine\item\enchantment\Enchantment; @@ -591,7 +591,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return Block */ public function getBlock() : Block{ - return BlockFactory::get(BlockIds::AIR); + return BlockFactory::get(BlockLegacyIds::AIR); } /** diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 1ba8f1b362..91fb13a6f5 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\SkullType; use pocketmine\block\utils\TreeType; @@ -156,23 +156,23 @@ class ItemFactory{ self::register(new Item(Item::SUGAR, 0, "Sugar")); self::register(new Item(Item::TURTLE_SHELL_PIECE, 0, "Scute")); self::register(new Item(Item::WHEAT, 0, "Wheat")); - self::register(new ItemBlock(BlockIds::ACACIA_DOOR_BLOCK, 0, Item::ACACIA_DOOR)); - self::register(new ItemBlock(BlockIds::BIRCH_DOOR_BLOCK, 0, Item::BIRCH_DOOR)); - self::register(new ItemBlock(BlockIds::BREWING_STAND_BLOCK, 0, Item::BREWING_STAND)); - self::register(new ItemBlock(BlockIds::CAKE_BLOCK, 0, Item::CAKE)); - self::register(new ItemBlock(BlockIds::CAULDRON_BLOCK, 0, Item::CAULDRON)); - self::register(new ItemBlock(BlockIds::COMPARATOR_BLOCK, 0, Item::COMPARATOR)); - self::register(new ItemBlock(BlockIds::DARK_OAK_DOOR_BLOCK, 0, Item::DARK_OAK_DOOR)); - self::register(new ItemBlock(BlockIds::FLOWER_POT_BLOCK, 0, Item::FLOWER_POT)); - self::register(new ItemBlock(BlockIds::HOPPER_BLOCK, 0, Item::HOPPER)); - self::register(new ItemBlock(BlockIds::IRON_DOOR_BLOCK, 0, Item::IRON_DOOR)); - self::register(new ItemBlock(BlockIds::ITEM_FRAME_BLOCK, 0, Item::ITEM_FRAME)); - self::register(new ItemBlock(BlockIds::JUNGLE_DOOR_BLOCK, 0, Item::JUNGLE_DOOR)); - self::register(new ItemBlock(BlockIds::NETHER_WART_PLANT, 0, Item::NETHER_WART)); - self::register(new ItemBlock(BlockIds::OAK_DOOR_BLOCK, 0, Item::OAK_DOOR)); - self::register(new ItemBlock(BlockIds::REPEATER_BLOCK, 0, Item::REPEATER)); - self::register(new ItemBlock(BlockIds::SPRUCE_DOOR_BLOCK, 0, Item::SPRUCE_DOOR)); - self::register(new ItemBlock(BlockIds::SUGARCANE_BLOCK, 0, Item::SUGARCANE)); + self::register(new ItemBlock(BlockLegacyIds::ACACIA_DOOR_BLOCK, 0, Item::ACACIA_DOOR)); + self::register(new ItemBlock(BlockLegacyIds::BIRCH_DOOR_BLOCK, 0, Item::BIRCH_DOOR)); + self::register(new ItemBlock(BlockLegacyIds::BREWING_STAND_BLOCK, 0, Item::BREWING_STAND)); + self::register(new ItemBlock(BlockLegacyIds::CAKE_BLOCK, 0, Item::CAKE)); + self::register(new ItemBlock(BlockLegacyIds::CAULDRON_BLOCK, 0, Item::CAULDRON)); + self::register(new ItemBlock(BlockLegacyIds::COMPARATOR_BLOCK, 0, Item::COMPARATOR)); + self::register(new ItemBlock(BlockLegacyIds::DARK_OAK_DOOR_BLOCK, 0, Item::DARK_OAK_DOOR)); + self::register(new ItemBlock(BlockLegacyIds::FLOWER_POT_BLOCK, 0, Item::FLOWER_POT)); + self::register(new ItemBlock(BlockLegacyIds::HOPPER_BLOCK, 0, Item::HOPPER)); + self::register(new ItemBlock(BlockLegacyIds::IRON_DOOR_BLOCK, 0, Item::IRON_DOOR)); + self::register(new ItemBlock(BlockLegacyIds::ITEM_FRAME_BLOCK, 0, Item::ITEM_FRAME)); + self::register(new ItemBlock(BlockLegacyIds::JUNGLE_DOOR_BLOCK, 0, Item::JUNGLE_DOOR)); + self::register(new ItemBlock(BlockLegacyIds::NETHER_WART_PLANT, 0, Item::NETHER_WART)); + self::register(new ItemBlock(BlockLegacyIds::OAK_DOOR_BLOCK, 0, Item::OAK_DOOR)); + self::register(new ItemBlock(BlockLegacyIds::REPEATER_BLOCK, 0, Item::REPEATER)); + self::register(new ItemBlock(BlockLegacyIds::SPRUCE_DOOR_BLOCK, 0, Item::SPRUCE_DOOR)); + self::register(new ItemBlock(BlockLegacyIds::SUGARCANE_BLOCK, 0, Item::SUGARCANE)); self::register(new Leggings(Item::CHAIN_LEGGINGS, 0, "Chainmail Leggings", new ArmorTypeInfo(4, 226))); self::register(new Leggings(Item::DIAMOND_LEGGINGS, 0, "Diamond Leggings", new ArmorTypeInfo(6, 496))); self::register(new Leggings(Item::GOLDEN_LEGGINGS, 0, "Gold Leggings", new ArmorTypeInfo(3, 106))); @@ -180,8 +180,8 @@ class ItemFactory{ self::register(new Leggings(Item::LEATHER_LEGGINGS, 0, "Leather Pants", new ArmorTypeInfo(2, 76))); //TODO: fix metadata for buckets with still liquid in them //the meta values are intentionally hardcoded because block IDs will change in the future - self::register(new LiquidBucket(Item::BUCKET, 8, "Water Bucket", BlockIds::FLOWING_WATER)); - self::register(new LiquidBucket(Item::BUCKET, 10, "Lava Bucket", BlockIds::FLOWING_LAVA)); + self::register(new LiquidBucket(Item::BUCKET, 8, "Water Bucket", BlockLegacyIds::FLOWING_WATER)); + self::register(new LiquidBucket(Item::BUCKET, 10, "Lava Bucket", BlockLegacyIds::FLOWING_LAVA)); self::register(new Melon()); self::register(new MelonSeeds()); self::register(new MilkBucket(Item::BUCKET, 1, "Milk Bucket")); @@ -214,12 +214,12 @@ class ItemFactory{ self::register(new Shovel(Item::IRON_SHOVEL, "Iron Shovel", TieredTool::TIER_IRON)); self::register(new Shovel(Item::STONE_SHOVEL, "Stone Shovel", TieredTool::TIER_STONE)); self::register(new Shovel(Item::WOODEN_SHOVEL, "Wooden Shovel", TieredTool::TIER_WOODEN)); - self::register(new Sign(BlockIds::STANDING_SIGN, 0, Item::SIGN)); - self::register(new Sign(BlockIds::SPRUCE_STANDING_SIGN, 0, Item::SPRUCE_SIGN)); - self::register(new Sign(BlockIds::BIRCH_STANDING_SIGN, 0, Item::BIRCH_SIGN)); - self::register(new Sign(BlockIds::JUNGLE_STANDING_SIGN, 0, Item::JUNGLE_SIGN)); - self::register(new Sign(BlockIds::ACACIA_STANDING_SIGN, 0, Item::ACACIA_SIGN)); - self::register(new Sign(BlockIds::DARKOAK_STANDING_SIGN, 0, Item::DARKOAK_SIGN)); + self::register(new Sign(BlockLegacyIds::STANDING_SIGN, 0, Item::SIGN)); + self::register(new Sign(BlockLegacyIds::SPRUCE_STANDING_SIGN, 0, Item::SPRUCE_SIGN)); + self::register(new Sign(BlockLegacyIds::BIRCH_STANDING_SIGN, 0, Item::BIRCH_SIGN)); + self::register(new Sign(BlockLegacyIds::JUNGLE_STANDING_SIGN, 0, Item::JUNGLE_SIGN)); + self::register(new Sign(BlockLegacyIds::ACACIA_STANDING_SIGN, 0, Item::ACACIA_SIGN)); + self::register(new Sign(BlockLegacyIds::DARKOAK_STANDING_SIGN, 0, Item::DARKOAK_SIGN)); self::register(new Snowball()); self::register(new SpiderEye()); self::register(new Steak()); diff --git a/src/pocketmine/item/MelonSeeds.php b/src/pocketmine/item/MelonSeeds.php index 41741d8d34..f7715ed6e0 100644 --- a/src/pocketmine/item/MelonSeeds.php +++ b/src/pocketmine/item/MelonSeeds.php @@ -25,7 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; class MelonSeeds extends Item{ public function __construct(){ @@ -33,6 +33,6 @@ class MelonSeeds extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(BlockIds::MELON_STEM); + return BlockFactory::get(BlockLegacyIds::MELON_STEM); } } diff --git a/src/pocketmine/item/Potato.php b/src/pocketmine/item/Potato.php index 07aba80db2..b550a4f248 100644 --- a/src/pocketmine/item/Potato.php +++ b/src/pocketmine/item/Potato.php @@ -25,7 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; class Potato extends Food{ public function __construct(){ @@ -33,7 +33,7 @@ class Potato extends Food{ } public function getBlock() : Block{ - return BlockFactory::get(BlockIds::POTATO_BLOCK); + return BlockFactory::get(BlockLegacyIds::POTATO_BLOCK); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/PumpkinSeeds.php b/src/pocketmine/item/PumpkinSeeds.php index 4f5b0dd847..28ec69cbf2 100644 --- a/src/pocketmine/item/PumpkinSeeds.php +++ b/src/pocketmine/item/PumpkinSeeds.php @@ -25,7 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; class PumpkinSeeds extends Item{ public function __construct(){ @@ -33,6 +33,6 @@ class PumpkinSeeds extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(BlockIds::PUMPKIN_STEM); + return BlockFactory::get(BlockLegacyIds::PUMPKIN_STEM); } } diff --git a/src/pocketmine/item/Redstone.php b/src/pocketmine/item/Redstone.php index c89d3a9d23..2a08dda693 100644 --- a/src/pocketmine/item/Redstone.php +++ b/src/pocketmine/item/Redstone.php @@ -25,7 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; class Redstone extends Item{ public function __construct(){ @@ -33,6 +33,6 @@ class Redstone extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(BlockIds::REDSTONE_WIRE); + return BlockFactory::get(BlockLegacyIds::REDSTONE_WIRE); } } diff --git a/src/pocketmine/item/Skull.php b/src/pocketmine/item/Skull.php index ff7e98090b..b5baae5045 100644 --- a/src/pocketmine/item/Skull.php +++ b/src/pocketmine/item/Skull.php @@ -25,7 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\SkullType; class Skull extends Item{ @@ -39,7 +39,7 @@ class Skull extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(BlockIds::SKULL_BLOCK); + return BlockFactory::get(BlockLegacyIds::SKULL_BLOCK); } public function getSkullType() : SkullType{ diff --git a/src/pocketmine/item/StringItem.php b/src/pocketmine/item/StringItem.php index 9367678bd1..4253ba9809 100644 --- a/src/pocketmine/item/StringItem.php +++ b/src/pocketmine/item/StringItem.php @@ -25,7 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; class StringItem extends Item{ public function __construct(){ @@ -33,6 +33,6 @@ class StringItem extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(BlockIds::TRIPWIRE); + return BlockFactory::get(BlockLegacyIds::TRIPWIRE); } } diff --git a/src/pocketmine/item/WheatSeeds.php b/src/pocketmine/item/WheatSeeds.php index 8c4ff62d39..9679424927 100644 --- a/src/pocketmine/item/WheatSeeds.php +++ b/src/pocketmine/item/WheatSeeds.php @@ -25,7 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; class WheatSeeds extends Item{ public function __construct(){ @@ -33,6 +33,6 @@ class WheatSeeds extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(BlockIds::WHEAT_BLOCK); + return BlockFactory::get(BlockLegacyIds::WHEAT_BLOCK); } } diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index 3c89f982fd..eab86a0115 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -25,7 +25,7 @@ namespace pocketmine\level; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\block\TNT; use pocketmine\entity\Entity; use pocketmine\event\block\BlockUpdateEvent; @@ -200,7 +200,7 @@ class Explosion{ $air = ItemFactory::air(); - $airBlock = BlockFactory::get(BlockIds::AIR); + $airBlock = BlockFactory::get(BlockLegacyIds::AIR); foreach($this->affectedBlocks as $block){ if($block instanceof TNT){ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index f9c5806643..2e9a202e7f 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -28,7 +28,7 @@ namespace pocketmine\level; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\block\UnknownBlock; use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; @@ -1803,7 +1803,7 @@ class Level implements ChunkManager, Metadatable{ return false; } - if($blockClicked->getId() === BlockIds::AIR){ + if($blockClicked->getId() === BlockLegacyIds::AIR){ return false; } @@ -2783,7 +2783,7 @@ class Level implements ChunkManager, Metadatable{ $z = (int) $v->z; if($chunk !== null and $chunk->isGenerated()){ $y = (int) min($max - 2, $v->y); - $wasAir = $this->getBlockAt($x, $y - 1, $z)->getId() === BlockIds::AIR; //TODO: bad hack, clean up + $wasAir = $this->getBlockAt($x, $y - 1, $z)->getId() === BlockLegacyIds::AIR; //TODO: bad hack, clean up for(; $y > 0; --$y){ if($this->isFullBlock($this->getBlockAt($x, $y, $z))){ if($wasAir){ diff --git a/src/pocketmine/level/SimpleChunkManager.php b/src/pocketmine/level/SimpleChunkManager.php index 20cf014702..d8eb2397c6 100644 --- a/src/pocketmine/level/SimpleChunkManager.php +++ b/src/pocketmine/level/SimpleChunkManager.php @@ -25,7 +25,7 @@ namespace pocketmine\level; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\level\format\Chunk; use const INT32_MAX; use const INT32_MIN; @@ -50,7 +50,7 @@ class SimpleChunkManager implements ChunkManager{ if($chunk = $this->getChunk($x >> 4, $z >> 4)){ return BlockFactory::fromFullBlock($chunk->getFullBlock($x & 0xf, $y, $z & 0xf)); } - return BlockFactory::get(BlockIds::AIR); + return BlockFactory::get(BlockLegacyIds::AIR); } public function setBlockAt(int $x, int $y, int $z, Block $block) : bool{ diff --git a/src/pocketmine/level/biome/GrassyBiome.php b/src/pocketmine/level/biome/GrassyBiome.php index db44ed38a7..3a0d39cf16 100644 --- a/src/pocketmine/level/biome/GrassyBiome.php +++ b/src/pocketmine/level/biome/GrassyBiome.php @@ -24,17 +24,17 @@ declare(strict_types=1); namespace pocketmine\level\biome; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; abstract class GrassyBiome extends Biome{ public function __construct(){ $this->setGroundCover([ - BlockFactory::get(BlockIds::GRASS), - BlockFactory::get(BlockIds::DIRT), - BlockFactory::get(BlockIds::DIRT), - BlockFactory::get(BlockIds::DIRT), - BlockFactory::get(BlockIds::DIRT) + BlockFactory::get(BlockLegacyIds::GRASS), + BlockFactory::get(BlockLegacyIds::DIRT), + BlockFactory::get(BlockLegacyIds::DIRT), + BlockFactory::get(BlockLegacyIds::DIRT), + BlockFactory::get(BlockLegacyIds::DIRT) ]); } } diff --git a/src/pocketmine/level/biome/OceanBiome.php b/src/pocketmine/level/biome/OceanBiome.php index f2e36c04ae..3f9f1e6371 100644 --- a/src/pocketmine/level/biome/OceanBiome.php +++ b/src/pocketmine/level/biome/OceanBiome.php @@ -24,18 +24,18 @@ declare(strict_types=1); namespace pocketmine\level\biome; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\level\generator\populator\TallGrass; class OceanBiome extends Biome{ public function __construct(){ $this->setGroundCover([ - BlockFactory::get(BlockIds::GRAVEL), - BlockFactory::get(BlockIds::GRAVEL), - BlockFactory::get(BlockIds::GRAVEL), - BlockFactory::get(BlockIds::GRAVEL), - BlockFactory::get(BlockIds::GRAVEL) + BlockFactory::get(BlockLegacyIds::GRAVEL), + BlockFactory::get(BlockLegacyIds::GRAVEL), + BlockFactory::get(BlockLegacyIds::GRAVEL), + BlockFactory::get(BlockLegacyIds::GRAVEL), + BlockFactory::get(BlockLegacyIds::GRAVEL) ]); $tallGrass = new TallGrass(); diff --git a/src/pocketmine/level/biome/RiverBiome.php b/src/pocketmine/level/biome/RiverBiome.php index 3ad29767c1..06e3393845 100644 --- a/src/pocketmine/level/biome/RiverBiome.php +++ b/src/pocketmine/level/biome/RiverBiome.php @@ -24,18 +24,18 @@ declare(strict_types=1); namespace pocketmine\level\biome; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\level\generator\populator\TallGrass; class RiverBiome extends Biome{ public function __construct(){ $this->setGroundCover([ - BlockFactory::get(BlockIds::DIRT), - BlockFactory::get(BlockIds::DIRT), - BlockFactory::get(BlockIds::DIRT), - BlockFactory::get(BlockIds::DIRT), - BlockFactory::get(BlockIds::DIRT) + BlockFactory::get(BlockLegacyIds::DIRT), + BlockFactory::get(BlockLegacyIds::DIRT), + BlockFactory::get(BlockLegacyIds::DIRT), + BlockFactory::get(BlockLegacyIds::DIRT), + BlockFactory::get(BlockLegacyIds::DIRT) ]); $tallGrass = new TallGrass(); diff --git a/src/pocketmine/level/biome/SandyBiome.php b/src/pocketmine/level/biome/SandyBiome.php index c165eca909..b9f35642e2 100644 --- a/src/pocketmine/level/biome/SandyBiome.php +++ b/src/pocketmine/level/biome/SandyBiome.php @@ -24,17 +24,17 @@ declare(strict_types=1); namespace pocketmine\level\biome; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; abstract class SandyBiome extends Biome{ public function __construct(){ $this->setGroundCover([ - BlockFactory::get(BlockIds::SAND), - BlockFactory::get(BlockIds::SAND), - BlockFactory::get(BlockIds::SANDSTONE), - BlockFactory::get(BlockIds::SANDSTONE), - BlockFactory::get(BlockIds::SANDSTONE) + BlockFactory::get(BlockLegacyIds::SAND), + BlockFactory::get(BlockLegacyIds::SAND), + BlockFactory::get(BlockLegacyIds::SANDSTONE), + BlockFactory::get(BlockLegacyIds::SANDSTONE), + BlockFactory::get(BlockLegacyIds::SANDSTONE) ]); } } diff --git a/src/pocketmine/level/biome/SnowyBiome.php b/src/pocketmine/level/biome/SnowyBiome.php index f43b877364..0d3c18e201 100644 --- a/src/pocketmine/level/biome/SnowyBiome.php +++ b/src/pocketmine/level/biome/SnowyBiome.php @@ -24,17 +24,17 @@ declare(strict_types=1); namespace pocketmine\level\biome; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; abstract class SnowyBiome extends Biome{ public function __construct(){ $this->setGroundCover([ - BlockFactory::get(BlockIds::SNOW_LAYER), - BlockFactory::get(BlockIds::GRASS), - BlockFactory::get(BlockIds::DIRT), - BlockFactory::get(BlockIds::DIRT), - BlockFactory::get(BlockIds::DIRT) + BlockFactory::get(BlockLegacyIds::SNOW_LAYER), + BlockFactory::get(BlockLegacyIds::GRASS), + BlockFactory::get(BlockLegacyIds::DIRT), + BlockFactory::get(BlockLegacyIds::DIRT), + BlockFactory::get(BlockLegacyIds::DIRT) ]); } } diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/level/format/Chunk.php index adb968eb57..1e338e34e3 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/level/format/Chunk.php @@ -27,7 +27,7 @@ declare(strict_types=1); namespace pocketmine\level\format; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; use pocketmine\level\Level; @@ -664,7 +664,7 @@ class Chunk{ if($y < 0 or $y >= $this->height){ return $this->emptySubChunk; }elseif($generateNew and $this->subChunks[$y] instanceof EmptySubChunk){ - $this->subChunks[$y] = new SubChunk([new PalettedBlockArray(BlockIds::AIR << 4)]); + $this->subChunks[$y] = new SubChunk([new PalettedBlockArray(BlockLegacyIds::AIR << 4)]); } return $this->subChunks[$y]; diff --git a/src/pocketmine/level/format/SubChunk.php b/src/pocketmine/level/format/SubChunk.php index 0bb3a0b3f2..78fb8046b7 100644 --- a/src/pocketmine/level/format/SubChunk.php +++ b/src/pocketmine/level/format/SubChunk.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\level\format; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use function array_values; use function assert; use function chr; @@ -74,7 +74,7 @@ class SubChunk implements SubChunkInterface{ foreach($this->blockLayers as $layer){ $palette = $layer->getPalette(); foreach($palette as $p){ - if(($p >> 4) !== BlockIds::AIR){ + if(($p >> 4) !== BlockLegacyIds::AIR){ return false; } } @@ -89,14 +89,14 @@ class SubChunk implements SubChunkInterface{ public function getFullBlock(int $x, int $y, int $z) : int{ if(empty($this->blockLayers)){ - return BlockIds::AIR << 4; + return BlockLegacyIds::AIR << 4; } return $this->blockLayers[0]->get($x, $y, $z); } public function setFullBlock(int $x, int $y, int $z, int $block) : void{ if(empty($this->blockLayers)){ - $this->blockLayers[] = new PalettedBlockArray(BlockIds::AIR << 4); + $this->blockLayers[] = new PalettedBlockArray(BlockLegacyIds::AIR << 4); } $this->blockLayers[0]->set($x, $y, $z, $block); } @@ -141,7 +141,7 @@ class SubChunk implements SubChunkInterface{ return -1; } for($y = 15; $y >= 0; --$y){ - if(($this->blockLayers[0]->get($x, $y, $z) >> 4) !== BlockIds::AIR){ + if(($this->blockLayers[0]->get($x, $y, $z) >> 4) !== BlockLegacyIds::AIR){ return $y; } } @@ -178,7 +178,7 @@ class SubChunk implements SubChunkInterface{ $layer->collectGarbage(); foreach($layer->getPalette() as $p){ - if(($p >> 4) !== BlockIds::AIR){ + if(($p >> 4) !== BlockLegacyIds::AIR){ continue 2; } } diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index ecf9ad567e..e7f11c7ba7 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\level\format\io\leveldb; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\level\format\Chunk; use pocketmine\level\format\io\BaseLevelProvider; use pocketmine\level\format\io\ChunkUtils; @@ -161,7 +161,7 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ $tag = $nbt->read($stream->getBuffer(), $offset)->getTag(); $stream->setOffset($offset); - $id = $stringToLegacyId[$tag->getString("name")] ?? BlockIds::INFO_UPDATE; + $id = $stringToLegacyId[$tag->getString("name")] ?? BlockLegacyIds::INFO_UPDATE; $data = $tag->getShort("val"); $palette[] = ($id << 4) | $data; } diff --git a/src/pocketmine/level/generator/Flat.php b/src/pocketmine/level/generator/Flat.php index e10aae6b1a..33ec839958 100644 --- a/src/pocketmine/level/generator/Flat.php +++ b/src/pocketmine/level/generator/Flat.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\level\generator; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\item\ItemFactory; use pocketmine\level\ChunkManager; use pocketmine\level\format\Chunk; @@ -78,14 +78,14 @@ class Flat extends Generator{ if(isset($this->options["decoration"])){ $ores = new Ore(); $ores->setOreTypes([ - new OreType(BlockFactory::get(BlockIds::COAL_ORE), 20, 16, 0, 128), - new OreType(BlockFactory::get(BlockIds::IRON_ORE), 20, 8, 0, 64), - new OreType(BlockFactory::get(BlockIds::REDSTONE_ORE), 8, 7, 0, 16), - new OreType(BlockFactory::get(BlockIds::LAPIS_ORE), 1, 6, 0, 32), - new OreType(BlockFactory::get(BlockIds::GOLD_ORE), 2, 8, 0, 32), - new OreType(BlockFactory::get(BlockIds::DIAMOND_ORE), 1, 7, 0, 16), - new OreType(BlockFactory::get(BlockIds::DIRT), 20, 32, 0, 128), - new OreType(BlockFactory::get(BlockIds::GRAVEL), 10, 16, 0, 128) + new OreType(BlockFactory::get(BlockLegacyIds::COAL_ORE), 20, 16, 0, 128), + new OreType(BlockFactory::get(BlockLegacyIds::IRON_ORE), 20, 8, 0, 64), + new OreType(BlockFactory::get(BlockLegacyIds::REDSTONE_ORE), 8, 7, 0, 16), + new OreType(BlockFactory::get(BlockLegacyIds::LAPIS_ORE), 1, 6, 0, 32), + new OreType(BlockFactory::get(BlockLegacyIds::GOLD_ORE), 2, 8, 0, 32), + new OreType(BlockFactory::get(BlockLegacyIds::DIAMOND_ORE), 1, 7, 0, 16), + new OreType(BlockFactory::get(BlockLegacyIds::DIRT), 20, 32, 0, 128), + new OreType(BlockFactory::get(BlockLegacyIds::GRAVEL), 10, 16, 0, 128) ]); $this->populators[] = $ores; } diff --git a/src/pocketmine/level/generator/hell/Nether.php b/src/pocketmine/level/generator/hell/Nether.php index fbeba2a584..e00dfd59d3 100644 --- a/src/pocketmine/level/generator/hell/Nether.php +++ b/src/pocketmine/level/generator/hell/Nether.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\level\generator\hell; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\level\biome\Biome; use pocketmine\level\ChunkManager; use pocketmine\level\generator\Generator; @@ -90,9 +90,9 @@ class Nether extends Generator{ $chunk = $this->level->getChunk($chunkX, $chunkZ); - $bedrock = BlockFactory::get(BlockIds::BEDROCK)->getFullId(); - $netherrack = BlockFactory::get(BlockIds::NETHERRACK)->getFullId(); - $stillLava = BlockFactory::get(BlockIds::STILL_LAVA)->getFullId(); + $bedrock = BlockFactory::get(BlockLegacyIds::BEDROCK)->getFullId(); + $netherrack = BlockFactory::get(BlockLegacyIds::NETHERRACK)->getFullId(); + $stillLava = BlockFactory::get(BlockLegacyIds::STILL_LAVA)->getFullId(); for($x = 0; $x < 16; ++$x){ for($z = 0; $z < 16; ++$z){ diff --git a/src/pocketmine/level/generator/normal/Normal.php b/src/pocketmine/level/generator/normal/Normal.php index 3b366049fe..24f0eff246 100644 --- a/src/pocketmine/level/generator/normal/Normal.php +++ b/src/pocketmine/level/generator/normal/Normal.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\level\generator\normal; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\level\biome\Biome; use pocketmine\level\ChunkManager; use pocketmine\level\generator\biome\BiomeSelector; @@ -121,14 +121,14 @@ class Normal extends Generator{ $ores = new Ore(); $ores->setOreTypes([ - new OreType(BlockFactory::get(BlockIds::COAL_ORE), 20, 16, 0, 128), - new OreType(BlockFactory::get(BlockIds::IRON_ORE), 20, 8, 0, 64), - new OreType(BlockFactory::get(BlockIds::REDSTONE_ORE), 8, 7, 0, 16), - new OreType(BlockFactory::get(BlockIds::LAPIS_ORE), 1, 6, 0, 32), - new OreType(BlockFactory::get(BlockIds::GOLD_ORE), 2, 8, 0, 32), - new OreType(BlockFactory::get(BlockIds::DIAMOND_ORE), 1, 7, 0, 16), - new OreType(BlockFactory::get(BlockIds::DIRT), 20, 32, 0, 128), - new OreType(BlockFactory::get(BlockIds::GRAVEL), 10, 16, 0, 128) + new OreType(BlockFactory::get(BlockLegacyIds::COAL_ORE), 20, 16, 0, 128), + new OreType(BlockFactory::get(BlockLegacyIds::IRON_ORE), 20, 8, 0, 64), + new OreType(BlockFactory::get(BlockLegacyIds::REDSTONE_ORE), 8, 7, 0, 16), + new OreType(BlockFactory::get(BlockLegacyIds::LAPIS_ORE), 1, 6, 0, 32), + new OreType(BlockFactory::get(BlockLegacyIds::GOLD_ORE), 2, 8, 0, 32), + new OreType(BlockFactory::get(BlockLegacyIds::DIAMOND_ORE), 1, 7, 0, 16), + new OreType(BlockFactory::get(BlockLegacyIds::DIRT), 20, 32, 0, 128), + new OreType(BlockFactory::get(BlockLegacyIds::GRAVEL), 10, 16, 0, 128) ]); $this->populators[] = $ores; } @@ -178,9 +178,9 @@ class Normal extends Generator{ $biomeCache = []; - $bedrock = BlockFactory::get(BlockIds::BEDROCK)->getFullId(); - $stillWater = BlockFactory::get(BlockIds::STILL_WATER)->getFullId(); - $stone = BlockFactory::get(BlockIds::STONE)->getFullId(); + $bedrock = BlockFactory::get(BlockLegacyIds::BEDROCK)->getFullId(); + $stillWater = BlockFactory::get(BlockLegacyIds::STILL_WATER)->getFullId(); + $stone = BlockFactory::get(BlockLegacyIds::STONE)->getFullId(); for($x = 0; $x < 16; ++$x){ for($z = 0; $z < 16; ++$z){ diff --git a/src/pocketmine/level/generator/object/BirchTree.php b/src/pocketmine/level/generator/object/BirchTree.php index b6f8e4a0a1..001e601483 100644 --- a/src/pocketmine/level/generator/object/BirchTree.php +++ b/src/pocketmine/level/generator/object/BirchTree.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\level\generator\object; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\TreeType; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; @@ -34,7 +34,7 @@ class BirchTree extends Tree{ protected $superBirch = false; public function __construct(bool $superBirch = false){ - parent::__construct(BlockFactory::get(BlockIds::LOG, TreeType::BIRCH()->getMagicNumber()), BlockFactory::get(BlockIds::LEAVES, TreeType::BIRCH()->getMagicNumber())); + parent::__construct(BlockFactory::get(BlockLegacyIds::LOG, TreeType::BIRCH()->getMagicNumber()), BlockFactory::get(BlockLegacyIds::LEAVES, TreeType::BIRCH()->getMagicNumber())); $this->superBirch = $superBirch; } diff --git a/src/pocketmine/level/generator/object/JungleTree.php b/src/pocketmine/level/generator/object/JungleTree.php index 3090127bcb..bbf45c4bc9 100644 --- a/src/pocketmine/level/generator/object/JungleTree.php +++ b/src/pocketmine/level/generator/object/JungleTree.php @@ -24,12 +24,12 @@ declare(strict_types=1); namespace pocketmine\level\generator\object; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\TreeType; class JungleTree extends Tree{ public function __construct(){ - parent::__construct(BlockFactory::get(BlockIds::LOG, TreeType::JUNGLE()->getMagicNumber()), BlockFactory::get(BlockIds::LEAVES, TreeType::JUNGLE()->getMagicNumber()), 8); + parent::__construct(BlockFactory::get(BlockLegacyIds::LOG, TreeType::JUNGLE()->getMagicNumber()), BlockFactory::get(BlockLegacyIds::LEAVES, TreeType::JUNGLE()->getMagicNumber()), 8); } } diff --git a/src/pocketmine/level/generator/object/OakTree.php b/src/pocketmine/level/generator/object/OakTree.php index 56f9fb25ef..715798cd42 100644 --- a/src/pocketmine/level/generator/object/OakTree.php +++ b/src/pocketmine/level/generator/object/OakTree.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\level\generator\object; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\TreeType; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; @@ -32,7 +32,7 @@ use pocketmine\utils\Random; class OakTree extends Tree{ public function __construct(){ - parent::__construct(BlockFactory::get(BlockIds::LOG, TreeType::OAK()->getMagicNumber()), BlockFactory::get(BlockIds::LEAVES, TreeType::OAK()->getMagicNumber())); + parent::__construct(BlockFactory::get(BlockLegacyIds::LOG, TreeType::OAK()->getMagicNumber()), BlockFactory::get(BlockLegacyIds::LEAVES, TreeType::OAK()->getMagicNumber())); } public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ diff --git a/src/pocketmine/level/generator/object/Ore.php b/src/pocketmine/level/generator/object/Ore.php index 1949c04ecf..859cc1415c 100644 --- a/src/pocketmine/level/generator/object/Ore.php +++ b/src/pocketmine/level/generator/object/Ore.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\level\generator\object; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\level\ChunkManager; use pocketmine\math\VectorMath; use pocketmine\utils\Random; @@ -46,7 +46,7 @@ class Ore{ } public function canPlaceObject(ChunkManager $level, int $x, int $y, int $z) : bool{ - return $level->getBlockAt($x, $y, $z)->getId() === BlockIds::STONE; + return $level->getBlockAt($x, $y, $z)->getId() === BlockLegacyIds::STONE; } public function placeObject(ChunkManager $level, int $x, int $y, int $z) : void{ @@ -86,7 +86,7 @@ class Ore{ $sizeZ = ($z + 0.5 - $seedZ) / $size; $sizeZ *= $sizeZ; - if(($sizeX + $sizeY + $sizeZ) < 1 and $level->getBlockAt($x, $y, $z)->getId() === BlockIds::STONE){ + if(($sizeX + $sizeY + $sizeZ) < 1 and $level->getBlockAt($x, $y, $z)->getId() === BlockLegacyIds::STONE){ $level->setBlockAt($x, $y, $z, $this->type->material); } } diff --git a/src/pocketmine/level/generator/object/SpruceTree.php b/src/pocketmine/level/generator/object/SpruceTree.php index 97313dc2ae..7bc65c9d9d 100644 --- a/src/pocketmine/level/generator/object/SpruceTree.php +++ b/src/pocketmine/level/generator/object/SpruceTree.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\level\generator\object; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\TreeType; use pocketmine\level\BlockTransaction; use pocketmine\level\ChunkManager; @@ -34,7 +34,7 @@ use function abs; class SpruceTree extends Tree{ public function __construct(){ - parent::__construct(BlockFactory::get(BlockIds::LOG, TreeType::SPRUCE()->getMagicNumber()), BlockFactory::get(BlockIds::LEAVES, TreeType::SPRUCE()->getMagicNumber()), 10); + parent::__construct(BlockFactory::get(BlockLegacyIds::LOG, TreeType::SPRUCE()->getMagicNumber()), BlockFactory::get(BlockLegacyIds::LEAVES, TreeType::SPRUCE()->getMagicNumber()), 10); } protected function generateChunkHeight(Random $random) : int{ diff --git a/src/pocketmine/level/generator/object/TallGrass.php b/src/pocketmine/level/generator/object/TallGrass.php index 04add8a9d1..34ef563b0e 100644 --- a/src/pocketmine/level/generator/object/TallGrass.php +++ b/src/pocketmine/level/generator/object/TallGrass.php @@ -25,7 +25,7 @@ namespace pocketmine\level\generator\object; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\level\ChunkManager; use pocketmine\math\Vector3; use pocketmine\utils\Random; @@ -36,9 +36,9 @@ class TallGrass{ public static function growGrass(ChunkManager $level, Vector3 $pos, Random $random, int $count = 15, int $radius = 10) : void{ /** @var Block[] $arr */ $arr = [ - BlockFactory::get(BlockIds::DANDELION), - BlockFactory::get(BlockIds::POPPY), - $tallGrass = BlockFactory::get(BlockIds::TALL_GRASS, 1), + BlockFactory::get(BlockLegacyIds::DANDELION), + BlockFactory::get(BlockLegacyIds::POPPY), + $tallGrass = BlockFactory::get(BlockLegacyIds::TALL_GRASS, 1), $tallGrass, $tallGrass, $tallGrass @@ -47,7 +47,7 @@ class TallGrass{ for($c = 0; $c < $count; ++$c){ $x = $random->nextRange($pos->x - $radius, $pos->x + $radius); $z = $random->nextRange($pos->z - $radius, $pos->z + $radius); - if($level->getBlockAt($x, $pos->y + 1, $z)->getId() === BlockIds::AIR and $level->getBlockAt($x, $pos->y, $z)->getId() === BlockIds::GRASS){ + if($level->getBlockAt($x, $pos->y + 1, $z)->getId() === BlockLegacyIds::AIR and $level->getBlockAt($x, $pos->y, $z)->getId() === BlockLegacyIds::GRASS){ $level->setBlockAt($x, $pos->y + 1, $z, $arr[$random->nextRange(0, $arrC)]); } } diff --git a/src/pocketmine/level/generator/object/Tree.php b/src/pocketmine/level/generator/object/Tree.php index e70fac4025..5af5fdbe2a 100644 --- a/src/pocketmine/level/generator/object/Tree.php +++ b/src/pocketmine/level/generator/object/Tree.php @@ -25,7 +25,7 @@ namespace pocketmine\level\generator\object; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\block\Leaves; use pocketmine\block\Sapling; use pocketmine\block\utils\TreeType; @@ -121,7 +121,7 @@ abstract class Tree{ protected function placeTrunk(int $x, int $y, int $z, Random $random, int $trunkHeight, BlockTransaction $transaction) : void{ // The base dirt block - $transaction->addBlockAt($x, $y - 1, $z, BlockFactory::get(BlockIds::DIRT)); + $transaction->addBlockAt($x, $y - 1, $z, BlockFactory::get(BlockLegacyIds::DIRT)); for($yy = 0; $yy < $trunkHeight; ++$yy){ if($this->canOverride($transaction->fetchBlockAt($x, $y + $yy, $z))){ diff --git a/src/pocketmine/level/generator/populator/GroundCover.php b/src/pocketmine/level/generator/populator/GroundCover.php index e6b8e59e75..578fcd0f34 100644 --- a/src/pocketmine/level/generator/populator/GroundCover.php +++ b/src/pocketmine/level/generator/populator/GroundCover.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\level\generator\populator; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\block\Liquid; use pocketmine\level\biome\Biome; use pocketmine\level\ChunkManager; @@ -56,7 +56,7 @@ class GroundCover extends Populator{ for($y = $startY; $y > $endY and $y >= 0; --$y){ $b = $cover[$startY - $y]; $id = BlockFactory::fromFullBlock($chunk->getFullBlock($x, $y, $z)); - if($id->getId() === BlockIds::AIR and $b->isSolid()){ + if($id->getId() === BlockLegacyIds::AIR and $b->isSolid()){ break; } if($b->canBeFlowedInto() and $id instanceof Liquid){ diff --git a/src/pocketmine/level/generator/populator/TallGrass.php b/src/pocketmine/level/generator/populator/TallGrass.php index 7d00744765..88d21690fa 100644 --- a/src/pocketmine/level/generator/populator/TallGrass.php +++ b/src/pocketmine/level/generator/populator/TallGrass.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\level\generator\populator; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\level\ChunkManager; use pocketmine\utils\Random; @@ -46,7 +46,7 @@ class TallGrass extends Populator{ $this->level = $level; $amount = $random->nextRange(0, $this->randomAmount + 1) + $this->baseAmount; - $block = BlockFactory::get(BlockIds::TALL_GRASS, 1); + $block = BlockFactory::get(BlockLegacyIds::TALL_GRASS, 1); for($i = 0; $i < $amount; ++$i){ $x = $random->nextRange($chunkX * 16, $chunkX * 16 + 15); $z = $random->nextRange($chunkZ * 16, $chunkZ * 16 + 15); @@ -60,13 +60,13 @@ class TallGrass extends Populator{ private function canTallGrassStay(int $x, int $y, int $z) : bool{ $b = $this->level->getBlockAt($x, $y, $z)->getId(); - return ($b === BlockIds::AIR or $b === BlockIds::SNOW_LAYER) and $this->level->getBlockAt($x, $y - 1, $z)->getId() === BlockIds::GRASS; + return ($b === BlockLegacyIds::AIR or $b === BlockLegacyIds::SNOW_LAYER) and $this->level->getBlockAt($x, $y - 1, $z)->getId() === BlockLegacyIds::GRASS; } private function getHighestWorkableBlock(int $x, int $z) : int{ for($y = 127; $y >= 0; --$y){ $b = $this->level->getBlockAt($x, $y, $z)->getId(); - if($b !== BlockIds::AIR and $b !== BlockIds::LEAVES and $b !== BlockIds::LEAVES2 and $b !== BlockIds::SNOW_LAYER){ + if($b !== BlockLegacyIds::AIR and $b !== BlockLegacyIds::LEAVES and $b !== BlockLegacyIds::LEAVES2 and $b !== BlockLegacyIds::SNOW_LAYER){ break; } } diff --git a/src/pocketmine/level/generator/populator/Tree.php b/src/pocketmine/level/generator/populator/Tree.php index 68d1b2c6ce..ca7be9e2c4 100644 --- a/src/pocketmine/level/generator/populator/Tree.php +++ b/src/pocketmine/level/generator/populator/Tree.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\level\generator\populator; -use pocketmine\block\BlockIds; +use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\TreeType; use pocketmine\level\ChunkManager; use pocketmine\level\generator\object\Tree as ObjectTree; @@ -70,9 +70,9 @@ class Tree extends Populator{ private function getHighestWorkableBlock(int $x, int $z) : int{ for($y = 127; $y > 0; --$y){ $b = $this->level->getBlockAt($x, $y, $z)->getId(); - if($b === BlockIds::DIRT or $b === BlockIds::GRASS){ + if($b === BlockLegacyIds::DIRT or $b === BlockLegacyIds::GRASS){ break; - }elseif($b !== BlockIds::AIR and $b !== BlockIds::SNOW_LAYER){ + }elseif($b !== BlockLegacyIds::AIR and $b !== BlockLegacyIds::SNOW_LAYER){ return -1; } } diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index 6c591c3527..2911838221 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -37,7 +37,7 @@ class BlockTest extends TestCase{ * Test registering a block which would overwrite another block, without forcing it */ public function testAccidentalOverrideBlock() : void{ - $block = new MyCustomBlock(new BlockIdentifier(BlockIds::COBBLESTONE), "Cobblestone"); + $block = new MyCustomBlock(new BlockIdentifier(BlockLegacyIds::COBBLESTONE), "Cobblestone"); $this->expectException(\InvalidArgumentException::class); BlockFactory::register($block); } @@ -46,7 +46,7 @@ class BlockTest extends TestCase{ * Test registering a block deliberately overwriting another block works as expected */ public function testDeliberateOverrideBlock() : void{ - $block = new MyCustomBlock(new BlockIdentifier(BlockIds::COBBLESTONE), "Cobblestone"); + $block = new MyCustomBlock(new BlockIdentifier(BlockLegacyIds::COBBLESTONE), "Cobblestone"); BlockFactory::register($block, true); self::assertInstanceOf(MyCustomBlock::class, BlockFactory::get($block->getId())); } @@ -101,12 +101,12 @@ class BlockTest extends TestCase{ */ public function blockGetProvider() : array{ return [ - [BlockIds::STONE, 5], - [BlockIds::STONE, 15], - [BlockIds::GOLD_BLOCK, 0], - [BlockIds::WOODEN_PLANKS, 5], - [BlockIds::SAND, 0], - [BlockIds::GOLD_BLOCK, 0] + [BlockLegacyIds::STONE, 5], + [BlockLegacyIds::STONE, 15], + [BlockLegacyIds::GOLD_BLOCK, 0], + [BlockLegacyIds::WOODEN_PLANKS, 5], + [BlockLegacyIds::SAND, 0], + [BlockLegacyIds::GOLD_BLOCK, 0] ]; } From d9134f28e406390e9d73e786741ad25beba352c8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 19:50:07 +0000 Subject: [PATCH 0690/3224] Rename CobblestoneWall -> Wall --- src/pocketmine/block/BlockFactory.php | 30 +++++++++---------- src/pocketmine/block/FenceGate.php | 4 +-- .../block/{CobblestoneWall.php => Wall.php} | 2 +- 3 files changed, 18 insertions(+), 18 deletions(-) rename src/pocketmine/block/{CobblestoneWall.php => Wall.php} (98%) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 5494c61b56..0074439f0f 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -453,23 +453,23 @@ class BlockFactory{ } static $wallTypes = [ - CobblestoneWall::ANDESITE_WALL => "Andesite", - CobblestoneWall::BRICK_WALL => "Brick", - CobblestoneWall::DIORITE_WALL => "Diorite", - CobblestoneWall::END_STONE_BRICK_WALL => "End Stone Brick", - CobblestoneWall::GRANITE_WALL => "Granite", - CobblestoneWall::MOSSY_STONE_BRICK_WALL => "Mossy Stone Brick", - CobblestoneWall::MOSSY_WALL => "Mossy Cobblestone", - CobblestoneWall::NETHER_BRICK_WALL => "Nether Brick", - CobblestoneWall::NONE_MOSSY_WALL => "Cobblestone", - CobblestoneWall::PRISMARINE_WALL => "Prismarine", - CobblestoneWall::RED_NETHER_BRICK_WALL => "Red Nether Brick", - CobblestoneWall::RED_SANDSTONE_WALL => "Red Sandstone", - CobblestoneWall::SANDSTONE_WALL => "Sandstone", - CobblestoneWall::STONE_BRICK_WALL => "Stone Brick" + Wall::ANDESITE_WALL => "Andesite", + Wall::BRICK_WALL => "Brick", + Wall::DIORITE_WALL => "Diorite", + Wall::END_STONE_BRICK_WALL => "End Stone Brick", + Wall::GRANITE_WALL => "Granite", + Wall::MOSSY_STONE_BRICK_WALL => "Mossy Stone Brick", + Wall::MOSSY_WALL => "Mossy Cobblestone", + Wall::NETHER_BRICK_WALL => "Nether Brick", + Wall::NONE_MOSSY_WALL => "Cobblestone", + Wall::PRISMARINE_WALL => "Prismarine", + Wall::RED_NETHER_BRICK_WALL => "Red Nether Brick", + Wall::RED_SANDSTONE_WALL => "Red Sandstone", + Wall::SANDSTONE_WALL => "Sandstone", + Wall::STONE_BRICK_WALL => "Stone Brick" ]; foreach($wallTypes as $magicNumber => $prefix){ - self::register(new CobblestoneWall(new BID(BlockLegacyIds::COBBLESTONE_WALL, $magicNumber), $prefix . " Wall")); + self::register(new Wall(new BID(BlockLegacyIds::COBBLESTONE_WALL, $magicNumber), $prefix . " Wall")); } //TODO: minecraft:andesite_stairs diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index 564c9d6101..a338f8bf4e 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -73,8 +73,8 @@ class FenceGate extends Transparent{ private function checkInWall() : bool{ return ( - $this->getSide(Facing::rotateY($this->facing, false)) instanceof CobblestoneWall or - $this->getSide(Facing::rotateY($this->facing, true)) instanceof CobblestoneWall + $this->getSide(Facing::rotateY($this->facing, false)) instanceof Wall or + $this->getSide(Facing::rotateY($this->facing, true)) instanceof Wall ); } diff --git a/src/pocketmine/block/CobblestoneWall.php b/src/pocketmine/block/Wall.php similarity index 98% rename from src/pocketmine/block/CobblestoneWall.php rename to src/pocketmine/block/Wall.php index 79579f1172..389b8619bf 100644 --- a/src/pocketmine/block/CobblestoneWall.php +++ b/src/pocketmine/block/Wall.php @@ -27,7 +27,7 @@ use pocketmine\item\TieredTool; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; -class CobblestoneWall extends Transparent{ +class Wall extends Transparent{ public const NONE_MOSSY_WALL = 0; public const MOSSY_WALL = 1; public const GRANITE_WALL = 2; From aea775c7c6234d436238417026a5a1c68faec026 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Mar 2019 19:58:35 +0000 Subject: [PATCH 0691/3224] TallGrass: fixed seeds never being dropped when support is removed --- src/pocketmine/block/TallGrass.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/TallGrass.php b/src/pocketmine/block/TallGrass.php index 5fba37304d..eaf36f9b4d 100644 --- a/src/pocketmine/block/TallGrass.php +++ b/src/pocketmine/block/TallGrass.php @@ -47,7 +47,7 @@ class TallGrass extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ //Replace with common break method - $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); + $this->level->useBreakOn($this); } } From 9c76fb7d96f286e06a907be864e626b20dcccc60 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Sun, 24 Mar 2019 16:18:13 +0000 Subject: [PATCH 0692/3224] Implemented plugin loading whitelist/blacklist by config file (#2783) --- .gitignore | 1 + resources/plugin_list.yml | 8 +++ src/pocketmine/Server.php | 17 ++++- src/pocketmine/plugin/PluginGraylist.php | 91 ++++++++++++++++++++++++ src/pocketmine/plugin/PluginManager.php | 18 ++++- 5 files changed, 131 insertions(+), 4 deletions(-) create mode 100644 resources/plugin_list.yml create mode 100644 src/pocketmine/plugin/PluginGraylist.php diff --git a/.gitignore b/.gitignore index afc4ebbca4..9074846c37 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ crashdumps/* *.phar server.properties /pocketmine.yml +/plugin_list.yml memory_dumps/* resource_packs/ diff --git a/resources/plugin_list.yml b/resources/plugin_list.yml new file mode 100644 index 0000000000..e74f0221aa --- /dev/null +++ b/resources/plugin_list.yml @@ -0,0 +1,8 @@ +#This configuration file allows you to control which plugins are loaded on your server. + +#List behaviour +# - blacklist: Only plugins which ARE NOT listed will load. +# - whitelist: Only plugins which ARE listed will load. +mode: blacklist +#List names of plugins here. +plugins: [] diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 46a2c1bcf2..d52a1462a4 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -82,6 +82,7 @@ use pocketmine\permission\DefaultPermissions; use pocketmine\permission\PermissionManager; use pocketmine\plugin\PharPluginLoader; use pocketmine\plugin\Plugin; +use pocketmine\plugin\PluginGraylist; use pocketmine\plugin\PluginLoadOrder; use pocketmine\plugin\PluginManager; use pocketmine\plugin\ScriptPluginLoader; @@ -106,6 +107,7 @@ use function array_shift; use function array_sum; use function base64_encode; use function bin2hex; +use function copy; use function count; use function define; use function explode; @@ -147,6 +149,7 @@ use function strtolower; use function time; use function touch; use function trim; +use function yaml_parse; use const DIRECTORY_SEPARATOR; use const PHP_EOL; use const PHP_INT_MAX; @@ -1227,7 +1230,19 @@ class Server{ $this->resourceManager = new ResourcePackManager($this->getDataPath() . "resource_packs" . DIRECTORY_SEPARATOR, $this->logger); - $this->pluginManager = new PluginManager($this, ((bool) $this->getProperty("plugins.legacy-data-dir", true)) ? null : $this->getDataPath() . "plugin_data" . DIRECTORY_SEPARATOR); + $pluginGraylist = null; + $graylistFile = $this->dataPath . "plugin_list.yml"; + if(!file_exists($graylistFile)){ + copy(\pocketmine\RESOURCE_PATH . 'plugin_list.yml', $graylistFile); + } + try{ + $pluginGraylist = PluginGraylist::fromArray(yaml_parse(file_get_contents($graylistFile))); + }catch(\InvalidArgumentException $e){ + $this->logger->emergency("Failed to load $graylistFile: " . $e->getMessage()); + $this->forceShutdown(); + return; + } + $this->pluginManager = new PluginManager($this, ((bool) $this->getProperty("plugins.legacy-data-dir", true)) ? null : $this->getDataPath() . "plugin_data" . DIRECTORY_SEPARATOR, $pluginGraylist); $this->profilingTickRate = (float) $this->getProperty("settings.profile-report-trigger", 20); $this->pluginManager->registerInterface(new PharPluginLoader($this->autoloader)); $this->pluginManager->registerInterface(new ScriptPluginLoader()); diff --git a/src/pocketmine/plugin/PluginGraylist.php b/src/pocketmine/plugin/PluginGraylist.php new file mode 100644 index 0000000000..2438b8281a --- /dev/null +++ b/src/pocketmine/plugin/PluginGraylist.php @@ -0,0 +1,91 @@ +plugins = array_flip($plugins); + $this->isWhitelist = $whitelist; + } + + /** + * @return string[] + */ + public function getPlugins() : array{ + return array_flip($this->plugins); + } + + /** + * @return bool + */ + public function isWhitelist() : bool{ + return $this->isWhitelist; + } + + /** + * Returns whether the given name is permitted by this graylist. + * + * @param string $name + * + * @return bool + */ + public function isAllowed(string $name) : bool{ + return $this->isWhitelist() === isset($this->plugins[$name]); + } + + public static function fromArray(array $array) : PluginGraylist{ + $v = new Validator(); + $v->required("mode")->inArray(['whitelist', 'blacklist'], true); + $v->required("plugins")->isArray()->allowEmpty(true)->callback(function(array $elements) : bool{ return count(array_filter($elements, '\is_string')) === count($elements); }); + + $result = $v->validate($array); + if($result->isNotValid()){ + $messages = []; + foreach($result->getFailures() as $f){ + $messages[] = $f->format(); + } + throw new \InvalidArgumentException("Invalid data: " . implode(", ", $messages)); + } + return new PluginGraylist($array["plugins"], $array["mode"] === 'whitelist'); + } + + public function toArray() : array{ + return [ + "mode" => $this->isWhitelist ? 'whitelist' : 'blacklist', + "plugins" => $this->plugins + ]; + } +} diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index a6d2e41e11..6bf0564009 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -80,12 +80,15 @@ class PluginManager{ /** @var string|null */ private $pluginDataDirectory; + /** @var PluginGraylist|null */ + private $graylist; /** - * @param Server $server - * @param null|string $pluginDataDirectory + * @param Server $server + * @param null|string $pluginDataDirectory + * @param PluginGraylist|null $graylist */ - public function __construct(Server $server, ?string $pluginDataDirectory){ + public function __construct(Server $server, ?string $pluginDataDirectory, ?PluginGraylist $graylist = null){ $this->server = $server; $this->pluginDataDirectory = $pluginDataDirectory; if($this->pluginDataDirectory !== null){ @@ -95,6 +98,8 @@ class PluginManager{ throw new \RuntimeException("Plugin data path $this->pluginDataDirectory exists and is not a directory"); } } + + $this->graylist = $graylist; } /** @@ -265,6 +270,13 @@ class PluginManager{ } } + if($this->graylist !== null and !$this->graylist->isAllowed($name)){ + $this->server->getLogger()->notice($this->server->getLanguage()->translateString("pocketmine.plugin.loadError", [ + $name, + "Disallowed by graylist" + ])); + continue; + } $plugins[$name] = $file; $softDependencies[$name] = $description->getSoftDepend(); From a753c1342d5c6fe6b092dfcb2abdf6c176b959e9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Mar 2019 17:42:41 +0000 Subject: [PATCH 0693/3224] Clean up Query cache handling, remove useless timeouts the timeout was entirely useless, because: - when shorter than 25.6 seconds (512 ticks) it would cause caches to be needlessly destroyed and regenerated - when longer than 25.6 seconds, just made outdated caches persist for longer, even after the query info was regenerated. This now uses a mark-dirty model to deal with caches, which means that plugin modifications to the query data will be reflected immediately, regardless of when they are made. Previously, modifying the result of Server->getQueryInformation() would have inconsistent results. --- src/pocketmine/Server.php | 7 +-- .../event/server/QueryRegenerateEvent.php | 43 ++++++++++--------- src/pocketmine/network/query/QueryHandler.php | 23 +--------- 3 files changed, 26 insertions(+), 47 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index d52a1462a4..f0a9af271d 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1263,7 +1263,7 @@ class Server{ register_shutdown_function([$this, "crashDump"]); - $this->queryRegenerateTask = new QueryRegenerateEvent($this, 5); + $this->queryRegenerateTask = new QueryRegenerateEvent($this); $this->pluginManager->loadPlugins($this->pluginPath); @@ -2008,10 +2008,7 @@ class Server{ } if(($this->tickCounter & 0b111111111) === 0){ - ($this->queryRegenerateTask = new QueryRegenerateEvent($this, 5))->call(); - if($this->queryHandler !== null){ - $this->queryHandler->regenerateInfo(); - } + ($this->queryRegenerateTask = new QueryRegenerateEvent($this))->call(); } if($this->sendUsageTicker > 0 and --$this->sendUsageTicker === 0){ diff --git a/src/pocketmine/event/server/QueryRegenerateEvent.php b/src/pocketmine/event/server/QueryRegenerateEvent.php index a9393a1c6a..d7267baac2 100644 --- a/src/pocketmine/event/server/QueryRegenerateEvent.php +++ b/src/pocketmine/event/server/QueryRegenerateEvent.php @@ -35,8 +35,6 @@ use function substr; class QueryRegenerateEvent extends ServerEvent{ public const GAME_ID = "MINECRAFTPE"; - /** @var int */ - private $timeout; /** @var string */ private $serverName; /** @var bool */ @@ -68,13 +66,16 @@ class QueryRegenerateEvent extends ServerEvent{ /** @var array */ private $extraData = []; + /** @var string|null */ + private $longQueryCache = null; + /** @var string|null */ + private $shortQueryCache = null; + /** * @param Server $server - * @param int $timeout */ - public function __construct(Server $server, int $timeout = 5){ - $this->timeout = $timeout; + public function __construct(Server $server){ $this->serverName = $server->getMotd(); $this->listPlugins = $server->getProperty("settings.query-plugins", true); $this->plugins = $server->getPluginManager()->getPlugins(); @@ -98,20 +99,9 @@ class QueryRegenerateEvent extends ServerEvent{ } - /** - * Gets the min. timeout for Query Regeneration - * - * @return int - */ - public function getTimeout() : int{ - return $this->timeout; - } - - /** - * @param int $timeout - */ - public function setTimeout(int $timeout) : void{ - $this->timeout = $timeout; + private function destroyCache() : void{ + $this->longQueryCache = null; + $this->shortQueryCache = null; } /** @@ -126,6 +116,7 @@ class QueryRegenerateEvent extends ServerEvent{ */ public function setServerName(string $serverName) : void{ $this->serverName = $serverName; + $this->destroyCache(); } /** @@ -140,6 +131,7 @@ class QueryRegenerateEvent extends ServerEvent{ */ public function setListPlugins(bool $value) : void{ $this->listPlugins = $value; + $this->destroyCache(); } /** @@ -154,6 +146,7 @@ class QueryRegenerateEvent extends ServerEvent{ */ public function setPlugins(array $plugins) : void{ $this->plugins = $plugins; + $this->destroyCache(); } /** @@ -168,6 +161,7 @@ class QueryRegenerateEvent extends ServerEvent{ */ public function setPlayerList(array $players) : void{ $this->players = $players; + $this->destroyCache(); } /** @@ -182,6 +176,7 @@ class QueryRegenerateEvent extends ServerEvent{ */ public function setPlayerCount(int $count) : void{ $this->numPlayers = $count; + $this->destroyCache(); } /** @@ -196,6 +191,7 @@ class QueryRegenerateEvent extends ServerEvent{ */ public function setMaxPlayerCount(int $count) : void{ $this->maxPlayers = $count; + $this->destroyCache(); } /** @@ -210,6 +206,7 @@ class QueryRegenerateEvent extends ServerEvent{ */ public function setWorld(string $world) : void{ $this->map = $world; + $this->destroyCache(); } /** @@ -226,12 +223,16 @@ class QueryRegenerateEvent extends ServerEvent{ */ public function setExtraData(array $extraData) : void{ $this->extraData = $extraData; + $this->destroyCache(); } /** * @return string */ public function getLongQuery() : string{ + if($this->longQueryCache !== null){ + return $this->longQueryCache; + } $query = ""; $plist = $this->server_engine; @@ -274,13 +275,13 @@ class QueryRegenerateEvent extends ServerEvent{ } $query .= "\x00"; - return $query; + return $this->longQueryCache = $query; } /** * @return string */ public function getShortQuery() : string{ - return $this->serverName . "\x00" . $this->gametype . "\x00" . $this->map . "\x00" . $this->numPlayers . "\x00" . $this->maxPlayers . "\x00" . Binary::writeLShort($this->port) . $this->ip . "\x00"; + return $this->shortQueryCache ?? ($this->shortQueryCache = $this->serverName . "\x00" . $this->gametype . "\x00" . $this->map . "\x00" . $this->numPlayers . "\x00" . $this->maxPlayers . "\x00" . Binary::writeLShort($this->port) . $this->ip . "\x00"); } } diff --git a/src/pocketmine/network/query/QueryHandler.php b/src/pocketmine/network/query/QueryHandler.php index 0b620f81cd..9092e15463 100644 --- a/src/pocketmine/network/query/QueryHandler.php +++ b/src/pocketmine/network/query/QueryHandler.php @@ -34,7 +34,6 @@ use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; use function chr; use function hash; -use function microtime; use function random_bytes; use function strlen; use function substr; @@ -46,12 +45,6 @@ class QueryHandler{ private $lastToken; /** @var string */ private $token; - /** @var string */ - private $longData; - /** @var string */ - private $shortData; - /** @var float */ - private $timeout; public const HANDSHAKE = 9; public const STATISTICS = 0; @@ -74,7 +67,6 @@ class QueryHandler{ $this->regenerateToken(); $this->lastToken = $this->token; - $this->regenerateInfo(); $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.server.query.running", [$addr, $port])); } @@ -83,13 +75,6 @@ class QueryHandler{ $this->server->getLogger()->debug("[Query] $message"); } - public function regenerateInfo() : void{ - $ev = $this->server->getQueryInformation(); - $this->longData = $ev->getLongQuery(); - $this->shortData = $ev->getShortQuery(); - $this->timeout = microtime(true) + $ev->getTimeout(); - } - public function regenerateToken() : void{ $this->lastToken = $this->token; $this->token = random_bytes(16); @@ -136,15 +121,11 @@ class QueryHandler{ $reply = chr(self::STATISTICS); $reply .= Binary::writeInt($sessionID); - if($this->timeout < microtime(true)){ - $this->regenerateInfo(); - } - $remaining = $stream->getRemaining(); if(strlen($remaining) === 4){ //TODO: check this! according to the spec, this should always be here and always be FF FF FF 01 - $reply .= $this->longData; + $reply .= $this->server->getQueryInformation()->getLongQuery(); }else{ - $reply .= $this->shortData; + $reply .= $this->server->getQueryInformation()->getShortQuery(); } $interface->sendRawPacket($address, $port, $reply); From 6990d6239eca9c83c08763d5494307db24777e51 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Mar 2019 18:02:19 +0000 Subject: [PATCH 0694/3224] Network: Added RawPacketHandler interface, query handler is now a component --- src/pocketmine/Server.php | 25 +-------- src/pocketmine/network/Network.php | 55 ++++++++++++++++++- src/pocketmine/network/RawPacketHandler.php | 46 ++++++++++++++++ .../network/mcpe/RakLibInterface.php | 2 +- src/pocketmine/network/query/QueryHandler.php | 8 ++- 5 files changed, 108 insertions(+), 28 deletions(-) create mode 100644 src/pocketmine/network/RawPacketHandler.php diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index f0a9af271d..6f33abae03 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -62,7 +62,6 @@ use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; -use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\CompressBatchTask; use pocketmine\network\mcpe\NetworkCipher; @@ -106,7 +105,6 @@ use function array_key_exists; use function array_shift; use function array_sum; use function base64_encode; -use function bin2hex; use function copy; use function count; use function define; @@ -280,9 +278,6 @@ class Server{ /** @var string[] */ private $uniquePlayers = []; - /** @var QueryHandler */ - private $queryHandler; - /** @var QueryRegenerateEvent */ private $queryRegenerateTask = null; @@ -1201,7 +1196,7 @@ class Server{ $this->getLogger()->debug("Server unique id: " . $this->getServerUniqueId()); $this->getLogger()->debug("Machine unique id: " . Utils::getMachineUniqueId()); - $this->network = new Network(); + $this->network = new Network($this->logger); $this->network->setName($this->getMotd()); @@ -1327,7 +1322,7 @@ class Server{ $this->enablePlugins(PluginLoadOrder::POSTWORLD); if($this->getConfigBool("enable-query", true)){ - $this->queryHandler = new QueryHandler(); + $this->network->registerRawPacketHandler(new QueryHandler()); } foreach($this->getIPBans()->getEntries() as $entry){ @@ -1953,22 +1948,6 @@ class Server{ Timings::$titleTickTimer->stopTiming(); } - /** - * @param AdvancedNetworkInterface $interface - * @param string $address - * @param int $port - * @param string $payload - * - * TODO: move this to Network - */ - public function handlePacket(AdvancedNetworkInterface $interface, string $address, int $port, string $payload) : void{ - if($this->queryHandler === null or !$this->queryHandler->handle($interface, $address, $port, $payload)){ - $this->logger->debug("Unhandled raw packet from $address $port: " . bin2hex($payload)); - } - //TODO: add raw packet events - } - - /** * Tries to execute a server tick */ diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index 5524232634..529a689f1a 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -29,7 +29,9 @@ namespace pocketmine\network; use pocketmine\event\server\NetworkInterfaceRegisterEvent; use pocketmine\event\server\NetworkInterfaceUnregisterEvent; use pocketmine\network\mcpe\protocol\PacketPool; +use function bin2hex; use function get_class; +use function preg_match; use function spl_object_id; class Network{ @@ -39,6 +41,9 @@ class Network{ /** @var AdvancedNetworkInterface[] */ private $advancedInterfaces = []; + /** @var RawPacketHandler[] */ + private $rawPacketHandlers = []; + private $upload = 0; private $download = 0; @@ -48,9 +53,13 @@ class Network{ /** @var NetworkSessionManager */ private $sessionManager; - public function __construct(){ + /** @var \Logger */ + private $logger; + + public function __construct(\Logger $logger){ PacketPool::init(); $this->sessionManager = new NetworkSessionManager(); + $this->logger = $logger; } public function addStatistics(float $upload, float $download) : void{ @@ -181,9 +190,51 @@ class Network{ } } - public function addRawPacketFilter(string $regex) : void{ + /** + * Registers a raw packet handler on the network. + * + * @param RawPacketHandler $handler + */ + public function registerRawPacketHandler(RawPacketHandler $handler) : void{ + $this->rawPacketHandlers[spl_object_id($handler)] = $handler; + + $regex = $handler->getPattern(); foreach($this->advancedInterfaces as $interface){ $interface->addRawPacketFilter($regex); } } + + /** + * Unregisters a previously-registered raw packet handler. + * + * @param RawPacketHandler $handler + */ + public function unregisterRawPacketHandler(RawPacketHandler $handler) : void{ + unset($this->rawPacketHandlers[spl_object_id($handler)]); + } + + /** + * @param AdvancedNetworkInterface $interface + * @param string $address + * @param int $port + * @param string $packet + */ + public function processRawPacket(AdvancedNetworkInterface $interface, string $address, int $port, string $packet) : void{ + $handled = false; + foreach($this->rawPacketHandlers as $handler){ + if(preg_match($handler->getPattern(), $packet) === 1){ + $handled = true; + try{ + $handler->handle($interface, $address, $port, $packet); + }catch(BadPacketException $e){ + $this->logger->error("Bad raw packet from /$address:$port: " . $e->getMessage()); + $this->blockAddress($address, 600); + break; + } + } + } + if(!$handled){ + $this->logger->debug("Unhandled raw packet from /$address:$port: " . bin2hex($packet)); + } + } } diff --git a/src/pocketmine/network/RawPacketHandler.php b/src/pocketmine/network/RawPacketHandler.php new file mode 100644 index 0000000000..e73d1f30eb --- /dev/null +++ b/src/pocketmine/network/RawPacketHandler.php @@ -0,0 +1,46 @@ +server->handlePacket($this, $address, $port, $payload); + $this->network->processRawPacket($this, $address, $port, $payload); } public function sendRawPacket(string $address, int $port, string $payload) : void{ diff --git a/src/pocketmine/network/query/QueryHandler.php b/src/pocketmine/network/query/QueryHandler.php index 9092e15463..7722c709ec 100644 --- a/src/pocketmine/network/query/QueryHandler.php +++ b/src/pocketmine/network/query/QueryHandler.php @@ -28,6 +28,7 @@ declare(strict_types=1); namespace pocketmine\network\query; use pocketmine\network\AdvancedNetworkInterface; +use pocketmine\network\RawPacketHandler; use pocketmine\Server; use pocketmine\utils\Binary; use pocketmine\utils\BinaryDataException; @@ -38,7 +39,7 @@ use function random_bytes; use function strlen; use function substr; -class QueryHandler{ +class QueryHandler implements RawPacketHandler{ /** @var Server */ private $server; /** @var string */ @@ -51,7 +52,6 @@ class QueryHandler{ public function __construct(){ $this->server = Server::getInstance(); - $this->server->getNetwork()->addRawPacketFilter('/^\xfe\xfd.+$/s'); $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.server.query.start")); $addr = $this->server->getIp(); $port = $this->server->getPort(); @@ -70,6 +70,10 @@ class QueryHandler{ $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.server.query.running", [$addr, $port])); } + public function getPattern() : string{ + return '/^\xfe\xfd.+$/s'; + } + private function debug(string $message) : void{ //TODO: replace this with a proper prefixed logger $this->server->getLogger()->debug("[Query] $message"); From d0940e4be2d642be4ce9c4f8237cb2aa56fc2527 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Mar 2019 18:26:52 +0000 Subject: [PATCH 0695/3224] Fixed raw packets in the buffer pre-ban still getting processed post-ban --- src/pocketmine/network/Network.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index 529a689f1a..d4276ee34a 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -33,6 +33,8 @@ use function bin2hex; use function get_class; use function preg_match; use function spl_object_id; +use function time; +use const PHP_INT_MAX; class Network{ /** @var NetworkInterface[] */ @@ -44,6 +46,9 @@ class Network{ /** @var RawPacketHandler[] */ private $rawPacketHandlers = []; + /** @var int[] */ + private $bannedIps = []; + private $upload = 0; private $download = 0; @@ -118,6 +123,9 @@ class Network{ if($interface instanceof AdvancedNetworkInterface){ $this->advancedInterfaces[$hash] = $interface; $interface->setNetwork($this); + foreach($this->bannedIps as $ip => $until){ + $interface->blockAddress($ip); + } } $interface->setName($this->name); } @@ -179,12 +187,14 @@ class Network{ * @param int $timeout */ public function blockAddress(string $address, int $timeout = 300) : void{ + $this->bannedIps[$address] = $timeout > 0 ? time() + $timeout : PHP_INT_MAX; foreach($this->advancedInterfaces as $interface){ $interface->blockAddress($address, $timeout); } } public function unblockAddress(string $address) : void{ + unset($this->bannedIps[$address]); foreach($this->advancedInterfaces as $interface){ $interface->unblockAddress($address); } @@ -220,6 +230,10 @@ class Network{ * @param string $packet */ public function processRawPacket(AdvancedNetworkInterface $interface, string $address, int $port, string $packet) : void{ + if(isset($this->bannedIps[$address]) and time() < $this->bannedIps[$address]){ + $this->logger->debug("Dropped raw packet from banned address $address $port"); + return; + } $handled = false; foreach($this->rawPacketHandlers as $handler){ if(preg_match($handler->getPattern(), $packet) === 1){ From 97ccc6e880b562eceb048352e2a0ad7eacaf0a5f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Mar 2019 18:31:32 +0000 Subject: [PATCH 0696/3224] Network: Don't ignore retval of raw handlers --- src/pocketmine/network/Network.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index d4276ee34a..c793ca82b7 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -237,9 +237,8 @@ class Network{ $handled = false; foreach($this->rawPacketHandlers as $handler){ if(preg_match($handler->getPattern(), $packet) === 1){ - $handled = true; try{ - $handler->handle($interface, $address, $port, $packet); + $handled = $handler->handle($interface, $address, $port, $packet); }catch(BadPacketException $e){ $this->logger->error("Bad raw packet from /$address:$port: " . $e->getMessage()); $this->blockAddress($address, 600); From 1ea5316a37f5102fb7f758eda0775f0db5ca0084 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Mar 2019 18:38:26 +0000 Subject: [PATCH 0697/3224] Whose idea was it to make this public... --- src/pocketmine/utils/Utils.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/utils/Utils.php b/src/pocketmine/utils/Utils.php index 0757a282ea..2447841652 100644 --- a/src/pocketmine/utils/Utils.php +++ b/src/pocketmine/utils/Utils.php @@ -105,7 +105,8 @@ use const STR_PAD_RIGHT; * Big collection of functions */ class Utils{ - public static $os; + /** @var string */ + private static $os; /** @var UUID|null */ private static $serverUniqueId = null; From 23071d257e9694157e8ed32efe854a8e4cb4018d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Mar 2019 18:57:32 +0000 Subject: [PATCH 0698/3224] Extract process-related functions from Utils into a separate Process class --- src/pocketmine/MemoryManager.php | 3 +- src/pocketmine/PocketMine.php | 8 +- src/pocketmine/Server.php | 11 +- .../command/defaults/StatusCommand.php | 8 +- .../event/server/LowMemoryEvent.php | 4 +- src/pocketmine/scheduler/SendUsageTask.php | 5 +- src/pocketmine/utils/Process.php | 171 ++++++++++++++++++ src/pocketmine/utils/ServerKiller.php | 2 +- src/pocketmine/utils/Utils.php | 130 ------------- 9 files changed, 193 insertions(+), 149 deletions(-) create mode 100644 src/pocketmine/utils/Process.php diff --git a/src/pocketmine/MemoryManager.php b/src/pocketmine/MemoryManager.php index db35ca765a..3392ea2c64 100644 --- a/src/pocketmine/MemoryManager.php +++ b/src/pocketmine/MemoryManager.php @@ -27,6 +27,7 @@ use pocketmine\event\server\LowMemoryEvent; use pocketmine\scheduler\DumpWorkerMemoryTask; use pocketmine\scheduler\GarbageCollectionTask; use pocketmine\timings\Timings; +use pocketmine\utils\Process; use pocketmine\utils\Utils; use function arsort; use function count; @@ -236,7 +237,7 @@ class MemoryManager{ if(($this->memoryLimit > 0 or $this->globalMemoryLimit > 0) and ++$this->checkTicker >= $this->checkRate){ $this->checkTicker = 0; - $memory = Utils::getMemoryUsage(true); + $memory = Process::getMemoryUsage(true); $trigger = false; if($this->memoryLimit > 0 and $memory[0] > $this->memoryLimit){ $trigger = 0; diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index f98081703f..ce43925823 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -29,10 +29,10 @@ namespace { namespace pocketmine { use pocketmine\utils\MainLogger; + use pocketmine\utils\Process; use pocketmine\utils\ServerKiller; use pocketmine\utils\Terminal; use pocketmine\utils\Timezone; - use pocketmine\utils\Utils; use pocketmine\utils\VersionString; use pocketmine\wizard\SetupWizard; @@ -223,9 +223,9 @@ namespace pocketmine { $gitHash = str_repeat("00", 20); if(\Phar::running(true) === ""){ - if(Utils::execute("git rev-parse HEAD", $out) === 0 and $out !== false and strlen($out = trim($out)) === 40){ + if(Process::execute("git rev-parse HEAD", $out) === 0 and $out !== false and strlen($out = trim($out)) === 40){ $gitHash = trim($out); - if(Utils::execute("git diff --quiet") === 1 or Utils::execute("git diff --cached --quiet") === 1){ //Locally-modified + if(Process::execute("git diff --quiet") === 1 or Process::execute("git diff --cached --quiet") === 1){ //Locally-modified $gitHash .= "-dirty"; } } @@ -268,7 +268,7 @@ namespace pocketmine { if(\pocketmine\DEBUG > 1){ echo "Some threads could not be stopped, performing a force-kill" . PHP_EOL . PHP_EOL; } - Utils::kill(getmypid()); + Process::kill(getmypid()); } }while(false); diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 6f33abae03..576504f5b1 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -97,6 +97,7 @@ use pocketmine\updater\AutoUpdater; use pocketmine\utils\Config; use pocketmine\utils\Internet; use pocketmine\utils\MainLogger; +use pocketmine\utils\Process; use pocketmine\utils\Terminal; use pocketmine\utils\TextFormat; use pocketmine\utils\Utils; @@ -1682,7 +1683,7 @@ class Server{ }catch(\Throwable $e){ $this->logger->logException($e); $this->logger->emergency("Crashed while crashing, killing process"); - @Utils::kill(getmypid()); + @Process::kill(getmypid()); } } @@ -1807,7 +1808,7 @@ class Server{ echo "--- Waiting $spacing seconds to throttle automatic restart (you can kill the process safely now) ---" . PHP_EOL; sleep($spacing); } - @Utils::kill(getmypid()); + @Process::kill(getmypid()); exit(1); } @@ -1927,10 +1928,10 @@ class Server{ private function titleTick() : void{ Timings::$titleTickTimer->startTiming(); - $d = Utils::getRealMemoryUsage(); + $d = Process::getRealMemoryUsage(); - $u = Utils::getMemoryUsage(true); - $usage = sprintf("%g/%g/%g/%g MB @ %d threads", round(($u[0] / 1024) / 1024, 2), round(($d[0] / 1024) / 1024, 2), round(($u[1] / 1024) / 1024, 2), round(($u[2] / 1024) / 1024, 2), Utils::getThreadCount()); + $u = Process::getMemoryUsage(true); + $usage = sprintf("%g/%g/%g/%g MB @ %d threads", round(($u[0] / 1024) / 1024, 2), round(($d[0] / 1024) / 1024, 2), round(($u[1] / 1024) / 1024, 2), round(($u[2] / 1024) / 1024, 2), Process::getThreadCount()); $online = count($this->playerList); $connecting = $this->network->getConnectionCount() - $online; diff --git a/src/pocketmine/command/defaults/StatusCommand.php b/src/pocketmine/command/defaults/StatusCommand.php index 2a1d474e1c..ac707ca784 100644 --- a/src/pocketmine/command/defaults/StatusCommand.php +++ b/src/pocketmine/command/defaults/StatusCommand.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; +use pocketmine\utils\Process; use pocketmine\utils\TextFormat; -use pocketmine\utils\Utils; use function count; use function floor; use function microtime; @@ -48,8 +48,8 @@ class StatusCommand extends VanillaCommand{ return true; } - $rUsage = Utils::getRealMemoryUsage(); - $mUsage = Utils::getMemoryUsage(true); + $rUsage = Process::getRealMemoryUsage(); + $mUsage = Process::getMemoryUsage(true); $server = $sender->getServer(); $sender->sendMessage(TextFormat::GREEN . "---- " . TextFormat::WHITE . "Server status" . TextFormat::GREEN . " ----"); @@ -94,7 +94,7 @@ class StatusCommand extends VanillaCommand{ $sender->sendMessage(TextFormat::GOLD . "Network upload: " . TextFormat::RED . round($server->getNetwork()->getUpload() / 1024, 2) . " kB/s"); $sender->sendMessage(TextFormat::GOLD . "Network download: " . TextFormat::RED . round($server->getNetwork()->getDownload() / 1024, 2) . " kB/s"); - $sender->sendMessage(TextFormat::GOLD . "Thread count: " . TextFormat::RED . Utils::getThreadCount()); + $sender->sendMessage(TextFormat::GOLD . "Thread count: " . TextFormat::RED . Process::getThreadCount()); $sender->sendMessage(TextFormat::GOLD . "Main thread memory: " . TextFormat::RED . number_format(round(($mUsage[0] / 1024) / 1024, 2), 2) . " MB."); $sender->sendMessage(TextFormat::GOLD . "Total memory: " . TextFormat::RED . number_format(round(($mUsage[1] / 1024) / 1024, 2), 2) . " MB."); diff --git a/src/pocketmine/event/server/LowMemoryEvent.php b/src/pocketmine/event/server/LowMemoryEvent.php index 5e7412b1f4..aaaaded625 100644 --- a/src/pocketmine/event/server/LowMemoryEvent.php +++ b/src/pocketmine/event/server/LowMemoryEvent.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\event\server; -use pocketmine\utils\Utils; +use pocketmine\utils\Process; /** @@ -87,6 +87,6 @@ class LowMemoryEvent extends ServerEvent{ * @return int */ public function getMemoryFreed() : int{ - return $this->getMemory() - ($this->isGlobal() ? Utils::getMemoryUsage(true)[1] : Utils::getMemoryUsage(true)[0]); + return $this->getMemory() - ($this->isGlobal() ? Process::getMemoryUsage(true)[1] : Process::getMemoryUsage(true)[0]); } } diff --git a/src/pocketmine/scheduler/SendUsageTask.php b/src/pocketmine/scheduler/SendUsageTask.php index ce0fce78ec..c37cd1d4e0 100644 --- a/src/pocketmine/scheduler/SendUsageTask.php +++ b/src/pocketmine/scheduler/SendUsageTask.php @@ -26,6 +26,7 @@ namespace pocketmine\scheduler; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\Server; use pocketmine\utils\Internet; +use pocketmine\utils\Process; use pocketmine\utils\Utils; use pocketmine\utils\UUID; use pocketmine\utils\VersionString; @@ -135,12 +136,12 @@ class SendUsageTask extends AsyncTask{ "historyList" => array_values($playerList) ]; - $info = Utils::getMemoryUsage(true); + $info = Process::getMemoryUsage(true); $data["system"] = [ "mainMemory" => $info[0], "totalMemory" => $info[1], "availableMemory" => $info[2], - "threadCount" => Utils::getThreadCount() + "threadCount" => Process::getThreadCount() ]; break; diff --git a/src/pocketmine/utils/Process.php b/src/pocketmine/utils/Process.php new file mode 100644 index 0000000000..3bca4302ae --- /dev/null +++ b/src/pocketmine/utils/Process.php @@ -0,0 +1,171 @@ + 0){ + $VmRSS = $matches[1] * 1024; + } + + if(preg_match("/VmSize:[ \t]+([0-9]+) kB/", $status, $matches) > 0){ + $VmSize = $matches[1] * 1024; + } + } + + //TODO: more OS + + if($VmRSS === null){ + $VmRSS = memory_get_usage(); + } + + if(!$advanced){ + return $VmRSS; + } + + if($VmSize === null){ + $VmSize = memory_get_usage(true); + } + + return [$reserved, $VmRSS, $VmSize]; + } + + /** + * @return int[] + */ + public static function getRealMemoryUsage() : array{ + $stack = 0; + $heap = 0; + + if(Utils::getOS() === "linux" or Utils::getOS() === "android"){ + $mappings = file("/proc/self/maps"); + foreach($mappings as $line){ + if(preg_match("#([a-z0-9]+)\\-([a-z0-9]+) [rwxp\\-]{4} [a-z0-9]+ [^\\[]*\\[([a-zA-z0-9]+)\\]#", trim($line), $matches) > 0){ + if(strpos($matches[3], "heap") === 0){ + $heap += hexdec($matches[2]) - hexdec($matches[1]); + }elseif(strpos($matches[3], "stack") === 0){ + $stack += hexdec($matches[2]) - hexdec($matches[1]); + } + } + } + } + + return [$heap, $stack]; + } + + + public static function getThreadCount() : int{ + if(Utils::getOS() === "linux" or Utils::getOS() === "android"){ + if(preg_match("/Threads:[ \t]+([0-9]+)/", file_get_contents("/proc/self/status"), $matches) > 0){ + return (int) $matches[1]; + } + } + + //TODO: more OS + + return count(ThreadManager::getInstance()->getAll()) + 3; //RakLib + MainLogger + Main Thread + } + + public static function kill($pid) : void{ + $logger = \GlobalLogger::get(); + if($logger instanceof MainLogger){ + $logger->syncFlushBuffer(); + } + switch(Utils::getOS()){ + case "win": + exec("taskkill.exe /F /PID " . ((int) $pid) . " > NUL"); + break; + case "mac": + case "linux": + default: + if(function_exists("posix_kill")){ + posix_kill($pid, 9); //SIGKILL + }else{ + exec("kill -9 " . ((int) $pid) . " > /dev/null 2>&1"); + } + } + } + + /** + * @param string $command Command to execute + * @param string|null &$stdout Reference parameter to write stdout to + * @param string|null &$stderr Reference parameter to write stderr to + * + * @return int process exit code + */ + public static function execute(string $command, string &$stdout = null, string &$stderr = null) : int{ + $process = proc_open($command, [ + ["pipe", "r"], + ["pipe", "w"], + ["pipe", "w"] + ], $pipes); + + if($process === false){ + $stderr = "Failed to open process"; + $stdout = ""; + + return -1; + } + + $stdout = stream_get_contents($pipes[1]); + $stderr = stream_get_contents($pipes[2]); + + foreach($pipes as $p){ + fclose($p); + } + + return proc_close($process); + } +} diff --git a/src/pocketmine/utils/ServerKiller.php b/src/pocketmine/utils/ServerKiller.php index 4a4dfe81d1..d8abd40d33 100644 --- a/src/pocketmine/utils/ServerKiller.php +++ b/src/pocketmine/utils/ServerKiller.php @@ -48,7 +48,7 @@ class ServerKiller extends Thread{ }); if(time() - $start >= $this->time){ echo "\nTook too long to stop, server was killed forcefully!\n"; - @Utils::kill(getmypid()); + @Process::kill(getmypid()); } } diff --git a/src/pocketmine/utils/Utils.php b/src/pocketmine/utils/Utils.php index 2447841652..25c3142e5f 100644 --- a/src/pocketmine/utils/Utils.php +++ b/src/pocketmine/utils/Utils.php @@ -28,7 +28,6 @@ declare(strict_types=1); namespace pocketmine\utils; use DaveRandom\CallbackValidator\CallbackType; -use pocketmine\ThreadManager; use function array_combine; use function array_map; use function array_reverse; @@ -41,7 +40,6 @@ use function debug_zval_dump; use function dechex; use function exec; use function explode; -use function fclose; use function file; use function file_exists; use function file_get_contents; @@ -51,7 +49,6 @@ use function get_current_user; use function get_loaded_extensions; use function getenv; use function gettype; -use function hexdec; use function implode; use function is_array; use function is_dir; @@ -61,20 +58,16 @@ use function is_readable; use function is_string; use function json_decode; use function json_last_error_msg; -use function memory_get_usage; use function ob_end_clean; use function ob_get_contents; use function ob_start; use function ord; use function php_uname; use function phpversion; -use function posix_kill; use function preg_grep; use function preg_match; use function preg_match_all; use function preg_replace; -use function proc_close; -use function proc_open; use function rmdir; use function scandir; use function sha1; @@ -82,7 +75,6 @@ use function spl_object_hash; use function str_pad; use function str_replace; use function str_split; -use function stream_get_contents; use function stripos; use function strlen; use function strpos; @@ -279,77 +271,6 @@ class Utils{ return self::$os; } - /** - * @return int[] - */ - public static function getRealMemoryUsage() : array{ - $stack = 0; - $heap = 0; - - if(Utils::getOS() === "linux" or Utils::getOS() === "android"){ - $mappings = file("/proc/self/maps"); - foreach($mappings as $line){ - if(preg_match("#([a-z0-9]+)\\-([a-z0-9]+) [rwxp\\-]{4} [a-z0-9]+ [^\\[]*\\[([a-zA-z0-9]+)\\]#", trim($line), $matches) > 0){ - if(strpos($matches[3], "heap") === 0){ - $heap += hexdec($matches[2]) - hexdec($matches[1]); - }elseif(strpos($matches[3], "stack") === 0){ - $stack += hexdec($matches[2]) - hexdec($matches[1]); - } - } - } - } - - return [$heap, $stack]; - } - - /** - * @param bool $advanced - * - * @return int[]|int - */ - public static function getMemoryUsage(bool $advanced = false){ - $reserved = memory_get_usage(); - $VmSize = null; - $VmRSS = null; - if(Utils::getOS() === "linux" or Utils::getOS() === "android"){ - $status = file_get_contents("/proc/self/status"); - if(preg_match("/VmRSS:[ \t]+([0-9]+) kB/", $status, $matches) > 0){ - $VmRSS = $matches[1] * 1024; - } - - if(preg_match("/VmSize:[ \t]+([0-9]+) kB/", $status, $matches) > 0){ - $VmSize = $matches[1] * 1024; - } - } - - //TODO: more OS - - if($VmRSS === null){ - $VmRSS = memory_get_usage(); - } - - if(!$advanced){ - return $VmRSS; - } - - if($VmSize === null){ - $VmSize = memory_get_usage(true); - } - - return [$reserved, $VmRSS, $VmSize]; - } - - public static function getThreadCount() : int{ - if(Utils::getOS() === "linux" or Utils::getOS() === "android"){ - if(preg_match("/Threads:[ \t]+([0-9]+)/", file_get_contents("/proc/self/status"), $matches) > 0){ - return (int) $matches[1]; - } - } - //TODO: more OS - - return count(ThreadManager::getInstance()->getAll()) + 3; //RakLib + MainLogger + Main Thread - } - /** * @param bool $recalculate * @@ -457,37 +378,6 @@ class Utils{ } - /** - * @param string $command Command to execute - * @param string|null &$stdout Reference parameter to write stdout to - * @param string|null &$stderr Reference parameter to write stderr to - * - * @return int process exit code - */ - public static function execute(string $command, string &$stdout = null, string &$stderr = null) : int{ - $process = proc_open($command, [ - ["pipe", "r"], - ["pipe", "w"], - ["pipe", "w"] - ], $pipes); - - if($process === false){ - $stderr = "Failed to open process"; - $stdout = ""; - - return -1; - } - - $stdout = stream_get_contents($pipes[1]); - $stderr = stream_get_contents($pipes[2]); - - foreach($pipes as $p){ - fclose($p); - } - - return proc_close($process); - } - /** * @param string $token * @@ -513,26 +403,6 @@ class Utils{ return $result; } - public static function kill($pid) : void{ - $logger = \GlobalLogger::get(); - if($logger instanceof MainLogger){ - $logger->syncFlushBuffer(); - } - switch(Utils::getOS()){ - case "win": - exec("taskkill.exe /F /PID " . ((int) $pid) . " > NUL"); - break; - case "mac": - case "linux": - default: - if(function_exists("posix_kill")){ - posix_kill($pid, 9); //SIGKILL - }else{ - exec("kill -9 " . ((int) $pid) . " > /dev/null 2>&1"); - } - } - } - /** * @param object $value * @param bool $includeCurrent From 0811ce81e5a650c36565b658e337052e80f205bb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 Mar 2019 19:53:14 +0000 Subject: [PATCH 0699/3224] Query: remove useless noise why do we need 3 log messages for something that does ... basically nothing? --- resources/locale | 2 +- src/pocketmine/network/query/QueryHandler.php | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/resources/locale b/resources/locale index 73ed1ab3e1..5f9877c1bc 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 73ed1ab3e1f2a1644fe908b439f8cf8ed6c12ab5 +Subproject commit 5f9877c1bc08082f0917f284be023e26bb83d3ae diff --git a/src/pocketmine/network/query/QueryHandler.php b/src/pocketmine/network/query/QueryHandler.php index 7722c709ec..1bc42178e1 100644 --- a/src/pocketmine/network/query/QueryHandler.php +++ b/src/pocketmine/network/query/QueryHandler.php @@ -52,10 +52,9 @@ class QueryHandler implements RawPacketHandler{ public function __construct(){ $this->server = Server::getInstance(); - $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.server.query.start")); $addr = $this->server->getIp(); $port = $this->server->getPort(); - $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.server.query.info", [$port])); + /* The Query protocol is built on top of the existing Minecraft PE UDP network stack. Because the 0xFE packet does not exist in the MCPE protocol, From 999174b0a7541868f862eadf97191071b8fc428d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 25 Mar 2019 14:49:12 +0000 Subject: [PATCH 0700/3224] Server: Delay RakLib start until after world loading fixes #2816 --- src/pocketmine/Server.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 576504f5b1..c14cfcc8b2 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1267,8 +1267,6 @@ class Server{ $this->enablePlugins(PluginLoadOrder::STARTUP); - $this->network->registerInterface(new RakLibInterface($this)); - foreach((array) $this->getProperty("worlds", []) as $name => $options){ if($options === null){ $options = []; @@ -1322,6 +1320,8 @@ class Server{ $this->enablePlugins(PluginLoadOrder::POSTWORLD); + $this->network->registerInterface(new RakLibInterface($this)); + if($this->getConfigBool("enable-query", true)){ $this->network->registerRawPacketHandler(new QueryHandler()); } From ca22223b62ffa4cdc5a303ca5a0c4fbece471460 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 25 Mar 2019 14:55:25 +0000 Subject: [PATCH 0701/3224] PlayerDeathEvent: fixed constructor signature, closes #2835 can we ban multi-type parameters already? this is tiresome... --- src/pocketmine/Player.php | 2 +- src/pocketmine/event/player/PlayerDeathEvent.php | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 8192747223..0146f52605 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2808,7 +2808,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, //main inventory and drops the rest on the ground. $this->doCloseInventory(); - $ev = new PlayerDeathEvent($this, $this->getDrops(), $this->getXpDropAmount()); + $ev = new PlayerDeathEvent($this, $this->getDrops(), $this->getXpDropAmount(), null); $ev->call(); if(!$ev->getKeepInventory()){ diff --git a/src/pocketmine/event/player/PlayerDeathEvent.php b/src/pocketmine/event/player/PlayerDeathEvent.php index af2d229904..74f41cf37a 100644 --- a/src/pocketmine/event/player/PlayerDeathEvent.php +++ b/src/pocketmine/event/player/PlayerDeathEvent.php @@ -45,10 +45,11 @@ class PlayerDeathEvent extends EntityDeathEvent{ /** * @param Player $entity * @param Item[] $drops + * @param int $xp * @param string|TextContainer|null $deathMessage Null will cause the default vanilla message to be used */ - public function __construct(Player $entity, array $drops, $deathMessage = null){ - parent::__construct($entity, $drops); + public function __construct(Player $entity, array $drops, int $xp, $deathMessage){ + parent::__construct($entity, $drops, $xp); $this->deathMessage = $deathMessage ?? self::deriveMessage($entity->getDisplayName(), $entity->getLastDamageCause()); } From 01e048c4d1ed4e855f9ffd42d9062248f006ad60 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Mar 2019 14:07:32 +0000 Subject: [PATCH 0702/3224] Move networkStart message to where we actually start network i.e. the point at which a normal user can reasonably expect to be able to connect to the server ... --- resources/locale | 2 +- src/pocketmine/Server.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/locale b/resources/locale index 5f9877c1bc..b8ec058c4c 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 5f9877c1bc08082f0917f284be023e26bb83d3ae +Subproject commit b8ec058c4cf341ff0c4f08f315feb990b62ae0e5 diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index c14cfcc8b2..4008d8af97 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1190,7 +1190,6 @@ class Server{ @cli_set_process_title($this->getName() . " " . $this->getPocketMineVersion()); } - $this->logger->info($this->getLanguage()->translateString("pocketmine.server.networkStart", [$this->getIp(), $this->getPort()])); define("BOOTUP_RANDOM", random_bytes(16)); $this->serverID = Utils::getMachineUniqueId($this->getIp() . $this->getPort()); @@ -1321,6 +1320,7 @@ class Server{ $this->enablePlugins(PluginLoadOrder::POSTWORLD); $this->network->registerInterface(new RakLibInterface($this)); + $this->logger->info($this->getLanguage()->translateString("pocketmine.server.networkStart", [$this->getIp(), $this->getPort()])); if($this->getConfigBool("enable-query", true)){ $this->network->registerRawPacketHandler(new QueryHandler()); From a9c76c2424540fa84d639dcade6e6c83cdc65cb2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Mar 2019 15:09:43 +0000 Subject: [PATCH 0703/3224] NetworkInterface: remove unused function --- src/pocketmine/network/NetworkInterface.php | 7 ------- src/pocketmine/network/mcpe/RakLibInterface.php | 5 ----- 2 files changed, 12 deletions(-) diff --git a/src/pocketmine/network/NetworkInterface.php b/src/pocketmine/network/NetworkInterface.php index 96207498cd..8ef8484637 100644 --- a/src/pocketmine/network/NetworkInterface.php +++ b/src/pocketmine/network/NetworkInterface.php @@ -38,13 +38,6 @@ interface NetworkInterface{ */ public function start() : void; - /** - * Returns the number of connections on this interface. - * - * @return int - */ - public function getConnectionCount() : int; - /** * Sends a packet to the interface, returns an unique identifier for the packet if $needACK is true * diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 97d3f9b3c0..e33b0767b6 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -40,7 +40,6 @@ use raklib\server\ServerInstance; use raklib\utils\InternetAddress; use function addcslashes; use function bin2hex; -use function count; use function implode; use function random_bytes; use function rtrim; @@ -104,10 +103,6 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $this->server->getLogger()->debug("RakLib booted successfully"); } - public function getConnectionCount() : int{ - return count($this->sessions); - } - public function setNetwork(Network $network) : void{ $this->network = $network; } From c98801402b062c1f86a692089a9040c8bb6db089 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Mar 2019 15:13:36 +0000 Subject: [PATCH 0704/3224] Network: silence unhandled packet message on bad raw packet --- src/pocketmine/network/Network.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index c793ca82b7..a1e872cb31 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -240,6 +240,7 @@ class Network{ try{ $handled = $handler->handle($interface, $address, $port, $packet); }catch(BadPacketException $e){ + $handled = true; $this->logger->error("Bad raw packet from /$address:$port: " . $e->getMessage()); $this->blockAddress($address, 600); break; From 7333e7118ebd076c39bb8833b1d15f17a3a0f564 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Mar 2019 15:52:34 +0000 Subject: [PATCH 0705/3224] Server: remove useless function --- src/pocketmine/Server.php | 4 ---- src/pocketmine/command/defaults/WhitelistCommand.php | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 4008d8af97..1b511bf08a 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -957,10 +957,6 @@ class Server{ return $this->operators; } - public function reloadWhitelist() : void{ - $this->whitelist->reload(); - } - /** * @return string[] */ diff --git a/src/pocketmine/command/defaults/WhitelistCommand.php b/src/pocketmine/command/defaults/WhitelistCommand.php index 81fb16f0bf..527bf91b09 100644 --- a/src/pocketmine/command/defaults/WhitelistCommand.php +++ b/src/pocketmine/command/defaults/WhitelistCommand.php @@ -59,7 +59,7 @@ class WhitelistCommand extends VanillaCommand{ } switch(strtolower($args[0])){ case "reload": - $sender->getServer()->reloadWhitelist(); + $sender->getServer()->getWhitelisted()->reload(); Command::broadcastCommandMessage($sender, new TranslationContainer("commands.whitelist.reloaded")); return true; From 1bf08022751c96bca2df16f7ac7b0e634a64e480 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Mar 2019 16:38:35 +0000 Subject: [PATCH 0706/3224] LevelEventPacket: added create() to reduce boilerplate code --- src/pocketmine/level/Level.php | 6 +----- src/pocketmine/level/particle/DestroyBlockParticle.php | 7 +------ .../level/particle/DragonEggTeleportParticle.php | 8 ++------ src/pocketmine/level/particle/GenericParticle.php | 7 +------ src/pocketmine/level/particle/MobSpawnParticle.php | 8 ++------ src/pocketmine/level/sound/LevelEventSound.php | 7 +------ src/pocketmine/network/mcpe/protocol/LevelEventPacket.php | 8 ++++++++ 7 files changed, 16 insertions(+), 35 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 2e9a202e7f..51d02b6de2 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -507,14 +507,10 @@ class Level implements ChunkManager, Metadatable{ * @param int $data */ public function broadcastLevelEvent(?Vector3 $pos, int $evid, int $data = 0){ - $pk = new LevelEventPacket(); - $pk->evid = $evid; - $pk->data = $data; + $pk = LevelEventPacket::create($evid, $data, $pos); if($pos !== null){ - $pk->position = $pos->asVector3(); $this->broadcastPacketToViewers($pos, $pk); }else{ - $pk->position = null; $this->broadcastGlobalPacket($pk); } } diff --git a/src/pocketmine/level/particle/DestroyBlockParticle.php b/src/pocketmine/level/particle/DestroyBlockParticle.php index cb278a4ede..98126e7cec 100644 --- a/src/pocketmine/level/particle/DestroyBlockParticle.php +++ b/src/pocketmine/level/particle/DestroyBlockParticle.php @@ -37,11 +37,6 @@ class DestroyBlockParticle implements Particle{ } public function encode(Vector3 $pos){ - $pk = new LevelEventPacket; - $pk->evid = LevelEventPacket::EVENT_PARTICLE_DESTROY; - $pk->position = $pos; - $pk->data = $this->data; - - return $pk; + return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_DESTROY, $this->data, $pos); } } diff --git a/src/pocketmine/level/particle/DragonEggTeleportParticle.php b/src/pocketmine/level/particle/DragonEggTeleportParticle.php index 65b2e75408..96bb822c8f 100644 --- a/src/pocketmine/level/particle/DragonEggTeleportParticle.php +++ b/src/pocketmine/level/particle/DragonEggTeleportParticle.php @@ -50,17 +50,13 @@ class DragonEggTeleportParticle implements Particle{ } public function encode(Vector3 $pos){ - $pk = new LevelEventPacket(); - $pk->evid = LevelEventPacket::EVENT_PARTICLE_DRAGON_EGG_TELEPORT; - $pk->position = $pos; - $pk->data = - ($this->zDiff < 0 ? 1 << 26 : 0) | + $data = ($this->zDiff < 0 ? 1 << 26 : 0) | ($this->yDiff < 0 ? 1 << 25 : 0) | ($this->xDiff < 0 ? 1 << 24 : 0) | (abs($this->xDiff) << 16) | (abs($this->yDiff) << 8) | abs($this->zDiff); - return $pk; + return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_DRAGON_EGG_TELEPORT, $data, $pos); } } diff --git a/src/pocketmine/level/particle/GenericParticle.php b/src/pocketmine/level/particle/GenericParticle.php index 2731eaba7a..892dad64af 100644 --- a/src/pocketmine/level/particle/GenericParticle.php +++ b/src/pocketmine/level/particle/GenericParticle.php @@ -38,11 +38,6 @@ class GenericParticle implements Particle{ } public function encode(Vector3 $pos){ - $pk = new LevelEventPacket; - $pk->evid = LevelEventPacket::EVENT_ADD_PARTICLE_MASK | $this->id; - $pk->position = $pos; - $pk->data = $this->data; - - return $pk; + return LevelEventPacket::create(LevelEventPacket::EVENT_ADD_PARTICLE_MASK | $this->id, $this->data, $pos); } } diff --git a/src/pocketmine/level/particle/MobSpawnParticle.php b/src/pocketmine/level/particle/MobSpawnParticle.php index 87c971aa5a..5955a2c887 100644 --- a/src/pocketmine/level/particle/MobSpawnParticle.php +++ b/src/pocketmine/level/particle/MobSpawnParticle.php @@ -33,16 +33,12 @@ class MobSpawnParticle implements Particle{ protected $height; public function __construct(int $width = 0, int $height = 0){ + //TODO: bounds checks $this->width = $width; $this->height = $height; } public function encode(Vector3 $pos){ - $pk = new LevelEventPacket; - $pk->evid = LevelEventPacket::EVENT_PARTICLE_SPAWN; - $pk->position = $pos; - $pk->data = ($this->width & 0xff) + (($this->height & 0xff) << 8); - - return $pk; + return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_SPAWN, ($this->width & 0xff) | (($this->height & 0xff) << 8), $pos); } } diff --git a/src/pocketmine/level/sound/LevelEventSound.php b/src/pocketmine/level/sound/LevelEventSound.php index 710567fa40..37c6ee3164 100644 --- a/src/pocketmine/level/sound/LevelEventSound.php +++ b/src/pocketmine/level/sound/LevelEventSound.php @@ -49,11 +49,6 @@ abstract class LevelEventSound implements Sound{ } public function encode(Vector3 $pos){ - $pk = new LevelEventPacket; - $pk->evid = $this->getLevelEventId(); - $pk->position = $pos; - $pk->data = (int) $this->pitch; - - return $pk; + return LevelEventPacket::create($this->getLevelEventId(), (int) $this->pitch, $pos); } } diff --git a/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php b/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php index 73510dca7b..d44d1fa4a3 100644 --- a/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php @@ -119,6 +119,14 @@ class LevelEventPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $data; + public static function create(int $evid, int $data, ?Vector3 $pos) : self{ + $pk = new self; + $pk->evid = $evid; + $pk->data = $data; + $pk->position = $pos !== null ? $pos->asVector3() : null; + return $pk; + } + protected function decodePayload() : void{ $this->evid = $this->getVarInt(); $this->position = $this->getVector3(); From 37b5ad835033aca63446d49e403e09e19f413ada Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Mar 2019 17:00:00 +0000 Subject: [PATCH 0707/3224] Remove remaining direct protocol usages for particles --- .../entity/projectile/EnderPearl.php | 4 +- .../entity/projectile/ExperienceBottle.php | 5 +- .../entity/projectile/SplashPotion.php | 9 ++- .../particle/EndermanTeleportParticle.php | 34 +++++++++++ .../level/particle/PotionSplashParticle.php | 60 +++++++++++++++++++ 5 files changed, 102 insertions(+), 10 deletions(-) create mode 100644 src/pocketmine/level/particle/EndermanTeleportParticle.php create mode 100644 src/pocketmine/level/particle/PotionSplashParticle.php diff --git a/src/pocketmine/entity/projectile/EnderPearl.php b/src/pocketmine/entity/projectile/EnderPearl.php index da9610732c..2d102909cf 100644 --- a/src/pocketmine/entity/projectile/EnderPearl.php +++ b/src/pocketmine/entity/projectile/EnderPearl.php @@ -27,11 +27,11 @@ use pocketmine\block\Block; use pocketmine\block\BlockLegacyIds; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\ProjectileHitEvent; +use pocketmine\level\particle\EndermanTeleportParticle; use pocketmine\level\sound\EndermanTeleportSound; use pocketmine\math\AxisAlignedBB; use pocketmine\math\RayTraceResult; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\LevelEventPacket; class EnderPearl extends Throwable{ public const NETWORK_ID = self::ENDER_PEARL; @@ -51,7 +51,7 @@ class EnderPearl extends Throwable{ //TODO: check end gateways (when they are added) //TODO: spawn endermites at origin - $this->level->broadcastLevelEvent($owner, LevelEventPacket::EVENT_PARTICLE_ENDERMAN_TELEPORT); + $this->level->addParticle($owner, new EndermanTeleportParticle()); $this->level->addSound($owner, new EndermanTeleportSound()); $owner->teleport($target = $event->getRayTraceResult()->getHitVector()); $this->level->addSound($target, new EndermanTeleportSound()); diff --git a/src/pocketmine/entity/projectile/ExperienceBottle.php b/src/pocketmine/entity/projectile/ExperienceBottle.php index 213f52b0b0..ff7095f5dd 100644 --- a/src/pocketmine/entity/projectile/ExperienceBottle.php +++ b/src/pocketmine/entity/projectile/ExperienceBottle.php @@ -24,9 +24,8 @@ declare(strict_types=1); namespace pocketmine\entity\projectile; use pocketmine\event\entity\ProjectileHitEvent; -use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\level\particle\PotionSplashParticle; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; -use pocketmine\utils\Color; use function mt_rand; class ExperienceBottle extends Throwable{ @@ -39,7 +38,7 @@ class ExperienceBottle extends Throwable{ } public function onHit(ProjectileHitEvent $event) : void{ - $this->level->broadcastLevelEvent($this, LevelEventPacket::EVENT_PARTICLE_SPLASH, (new Color(0x38, 0x5d, 0xc6))->toARGB()); + $this->level->addParticle($this, new PotionSplashParticle(PotionSplashParticle::DEFAULT_COLOR())); $this->level->broadcastLevelSoundEvent($this, LevelSoundEventPacket::SOUND_GLASS); $this->level->dropExperience($this, mt_rand(3, 11)); diff --git a/src/pocketmine/entity/projectile/SplashPotion.php b/src/pocketmine/entity/projectile/SplashPotion.php index 54e93c2e3e..9a2a8b07e5 100644 --- a/src/pocketmine/entity/projectile/SplashPotion.php +++ b/src/pocketmine/entity/projectile/SplashPotion.php @@ -32,8 +32,8 @@ use pocketmine\event\entity\ProjectileHitBlockEvent; use pocketmine\event\entity\ProjectileHitEntityEvent; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\item\Potion; +use pocketmine\level\particle\PotionSplashParticle; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\utils\Color; use function round; @@ -68,9 +68,7 @@ class SplashPotion extends Throwable{ $hasEffects = true; if(empty($effects)){ - $colors = [ - new Color(0x38, 0x5d, 0xc6) //Default colour for splash water bottle and similar with no effects. - ]; + $particle = new PotionSplashParticle(PotionSplashParticle::DEFAULT_COLOR()); $hasEffects = false; }else{ $colors = []; @@ -80,9 +78,10 @@ class SplashPotion extends Throwable{ $colors[] = $effect->getColor(); } } + $particle = new PotionSplashParticle(Color::mix(...$colors)); } - $this->level->broadcastLevelEvent($this, LevelEventPacket::EVENT_PARTICLE_SPLASH, Color::mix(...$colors)->toARGB()); + $this->level->addParticle($this, $particle); $this->level->broadcastLevelSoundEvent($this, LevelSoundEventPacket::SOUND_GLASS); if($hasEffects){ diff --git a/src/pocketmine/level/particle/EndermanTeleportParticle.php b/src/pocketmine/level/particle/EndermanTeleportParticle.php new file mode 100644 index 0000000000..cb117e107d --- /dev/null +++ b/src/pocketmine/level/particle/EndermanTeleportParticle.php @@ -0,0 +1,34 @@ +color = $color; + } + + /** + * Returns the default water-bottle splash colour. + * + * TODO: replace this with a standard surrogate object constant (first we need to implement them!) + * + * @return Color + */ + public static function DEFAULT_COLOR() : Color{ + return new Color(0x38, 0x5d, 0xc6); + } + + /** + * @return Color + */ + public function getColor() : Color{ + return $this->color; + } + + public function encode(Vector3 $pos){ + return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_SPLASH, $this->color->toARGB(), $pos); + } +} From 10db57655ef96e019c8c0f338aea59d9c8227eba Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Mar 2019 18:06:12 +0000 Subject: [PATCH 0708/3224] clean up some direct LevelEvent usages for sounds --- src/pocketmine/entity/Human.php | 8 ++--- src/pocketmine/entity/object/PrimedTNT.php | 4 +-- src/pocketmine/level/sound/IgniteSound.php | 34 +++++++++++++++++++ src/pocketmine/level/sound/TotemUseSound.php | 34 +++++++++++++++++++ src/pocketmine/level/sound/XpCollectSound.php | 34 +++++++++++++++++++ 5 files changed, 108 insertions(+), 6 deletions(-) create mode 100644 src/pocketmine/level/sound/IgniteSound.php create mode 100644 src/pocketmine/level/sound/TotemUseSound.php create mode 100644 src/pocketmine/level/sound/XpCollectSound.php diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 9748fd0dea..816f8cb7d8 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -43,6 +43,8 @@ use pocketmine\item\FoodSource; use pocketmine\item\Item; use pocketmine\item\Totem; use pocketmine\level\Level; +use pocketmine\level\sound\TotemUseSound; +use pocketmine\level\sound\XpCollectSound; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\CompoundTag; @@ -51,7 +53,6 @@ use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\protocol\AddPlayerPacket; use pocketmine\network\mcpe\protocol\EntityEventPacket; -use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\PlayerSkinPacket; @@ -65,7 +66,6 @@ use function array_values; use function ceil; use function max; use function min; -use function mt_rand; use function random_int; use function strlen; use const INT32_MAX; @@ -448,7 +448,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ if((int) ($newLevel / 5) > (int) ($oldLevel / 5)){ $this->playLevelUpSound($newLevel); }elseif($this->getCurrentTotalXp() > $oldTotal){ - $this->level->broadcastLevelEvent($this, LevelEventPacket::EVENT_SOUND_ORB, mt_rand()); + $this->level->addSound($this, new XpCollectSound()); } } @@ -770,7 +770,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $this->addEffect(new EffectInstance(Effect::ABSORPTION(), 5 * 20, 1)); $this->broadcastEntityEvent(EntityEventPacket::CONSUME_TOTEM); - $this->level->broadcastLevelEvent($this->add(0, $this->eyeHeight, 0), LevelEventPacket::EVENT_SOUND_TOTEM); + $this->level->addSound($this->add(0, $this->eyeHeight, 0), new TotemUseSound()); $hand = $this->inventory->getItemInHand(); if($hand instanceof Totem){ diff --git a/src/pocketmine/entity/object/PrimedTNT.php b/src/pocketmine/entity/object/PrimedTNT.php index 4b171fb450..ec2b2da97b 100644 --- a/src/pocketmine/entity/object/PrimedTNT.php +++ b/src/pocketmine/entity/object/PrimedTNT.php @@ -28,9 +28,9 @@ use pocketmine\entity\Explosive; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\ExplosionPrimeEvent; use pocketmine\level\Explosion; +use pocketmine\level\sound\IgniteSound; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ShortTag; -use pocketmine\network\mcpe\protocol\LevelEventPacket; class PrimedTNT extends Entity implements Explosive{ public const NETWORK_ID = self::TNT; @@ -66,7 +66,7 @@ class PrimedTNT extends Entity implements Explosive{ $this->setGenericFlag(self::DATA_FLAG_IGNITED, true); $this->propertyManager->setInt(self::DATA_FUSE_LENGTH, $this->fuse); - $this->level->broadcastLevelEvent($this, LevelEventPacket::EVENT_SOUND_IGNITE); + $this->level->addSound($this, new IgniteSound()); } diff --git a/src/pocketmine/level/sound/IgniteSound.php b/src/pocketmine/level/sound/IgniteSound.php new file mode 100644 index 0000000000..3fa28fface --- /dev/null +++ b/src/pocketmine/level/sound/IgniteSound.php @@ -0,0 +1,34 @@ + Date: Tue, 26 Mar 2019 18:14:33 +0000 Subject: [PATCH 0709/3224] LevelSoundEventPacket: more helpers --- src/pocketmine/level/Level.php | 23 +++++++++++-------- .../mcpe/protocol/LevelSoundEventPacket.php | 11 +++++++++ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 51d02b6de2..09cff9285a 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -523,17 +523,20 @@ class Level implements ChunkManager, Metadatable{ * @param int $extraData * @param int $entityTypeId * @param bool $isBabyMob - * @param bool $disableRelativeVolume If true, all players receiving this sound-event will hear the sound at full volume regardless of distance */ - public function broadcastLevelSoundEvent(Vector3 $pos, int $soundId, int $extraData = -1, int $entityTypeId = -1, bool $isBabyMob = false, bool $disableRelativeVolume = false){ - $pk = new LevelSoundEventPacket(); - $pk->sound = $soundId; - $pk->extraData = $extraData; - $pk->entityType = AddEntityPacket::LEGACY_ID_MAP_BC[$entityTypeId] ?? ":"; - $pk->isBabyMob = $isBabyMob; - $pk->disableRelativeVolume = $disableRelativeVolume; - $pk->position = $pos->asVector3(); - $this->broadcastPacketToViewers($pos, $pk); + public function broadcastLevelSoundEvent(?Vector3 $pos, int $soundId, int $extraData = -1, int $entityTypeId = -1, bool $isBabyMob = false){ + $pk = LevelSoundEventPacket::create( + $soundId, + $extraData, + $pos, + AddEntityPacket::LEGACY_ID_MAP_BC[$entityTypeId] ?? ":", + $isBabyMob + ); + if($pos !== null){ + $this->broadcastPacketToViewers($pos, $pk); + }else{ + $this->broadcastGlobalPacket($pk); + } } public function getAutoSave() : bool{ diff --git a/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacket.php b/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacket.php index 63350029ae..61a0293c91 100644 --- a/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacket.php @@ -285,6 +285,17 @@ class LevelSoundEventPacket extends DataPacket implements ClientboundPacket, Ser public const SOUND_CANT_BREED = 254; public const SOUND_UNDEFINED = 255; + public static function create(int $sound, int $extraData, ?Vector3 $pos, string $entityType = ":", bool $isBabyMob = false) : self{ + $result = new self; + $result->sound = $sound; + $result->extraData = $extraData; + $result->position = $pos; + $result->disableRelativeVolume = $pos === null; + $result->entityType = $entityType; + $result->isBabyMob = $isBabyMob; + return $result; + } + /** @var int */ public $sound; /** @var Vector3 */ From 0aebb3f4fb726e4bd6250a3bafbcf73ae1161a4e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Mar 2019 19:53:40 +0000 Subject: [PATCH 0710/3224] Clean up LevelSoundEvent handling --- src/pocketmine/block/Button.php | 7 ++-- src/pocketmine/block/Lava.php | 12 +++--- src/pocketmine/block/Lever.php | 7 ++-- src/pocketmine/block/Liquid.php | 5 ++- src/pocketmine/block/Water.php | 12 +++--- src/pocketmine/entity/Human.php | 11 ++--- src/pocketmine/entity/Living.php | 4 +- src/pocketmine/entity/projectile/Arrow.php | 4 +- .../entity/projectile/ExperienceBottle.php | 4 +- .../entity/projectile/SplashPotion.php | 4 +- src/pocketmine/inventory/ChestInventory.php | 16 +++---- .../inventory/EnderChestInventory.php | 12 +++--- src/pocketmine/item/Bow.php | 4 +- src/pocketmine/item/Bucket.php | 2 +- src/pocketmine/item/FlintSteel.php | 4 +- src/pocketmine/item/LiquidBucket.php | 2 +- src/pocketmine/item/ProjectileItem.php | 5 +-- src/pocketmine/level/Explosion.php | 4 +- src/pocketmine/level/Level.php | 29 +------------ src/pocketmine/level/sound/ArrowHitSound.php | 34 +++++++++++++++ .../level/sound/BlockBreakSound.php | 42 +++++++++++++++++++ .../level/sound/BlockPlaceSound.php | 42 +++++++++++++++++++ src/pocketmine/level/sound/BowShootSound.php | 34 +++++++++++++++ .../level/sound/BucketEmptyLavaSound.php | 34 +++++++++++++++ .../level/sound/BucketEmptyWaterSound.php | 34 +++++++++++++++ .../level/sound/BucketFillLavaSound.php | 34 +++++++++++++++ .../level/sound/BucketFillWaterSound.php | 34 +++++++++++++++ .../level/sound/ChestCloseSound.php | 34 +++++++++++++++ src/pocketmine/level/sound/ChestOpenSound.php | 34 +++++++++++++++ .../level/sound/EnderChestCloseSound.php | 34 +++++++++++++++ .../level/sound/EnderChestOpenSound.php | 34 +++++++++++++++ src/pocketmine/level/sound/ExplodeSound.php | 34 +++++++++++++++ .../level/sound/FlintSteelSound.php | 34 +++++++++++++++ .../level/sound/PotionSplashSound.php | 34 +++++++++++++++ .../level/sound/RedstonePowerOffSound.php | 34 +++++++++++++++ .../level/sound/RedstonePowerOnSound.php | 34 +++++++++++++++ src/pocketmine/level/sound/ThrowSound.php | 34 +++++++++++++++ .../mcpe/protocol/LevelSoundEventPacket.php | 2 +- 38 files changed, 693 insertions(+), 85 deletions(-) create mode 100644 src/pocketmine/level/sound/ArrowHitSound.php create mode 100644 src/pocketmine/level/sound/BlockBreakSound.php create mode 100644 src/pocketmine/level/sound/BlockPlaceSound.php create mode 100644 src/pocketmine/level/sound/BowShootSound.php create mode 100644 src/pocketmine/level/sound/BucketEmptyLavaSound.php create mode 100644 src/pocketmine/level/sound/BucketEmptyWaterSound.php create mode 100644 src/pocketmine/level/sound/BucketFillLavaSound.php create mode 100644 src/pocketmine/level/sound/BucketFillWaterSound.php create mode 100644 src/pocketmine/level/sound/ChestCloseSound.php create mode 100644 src/pocketmine/level/sound/ChestOpenSound.php create mode 100644 src/pocketmine/level/sound/EnderChestCloseSound.php create mode 100644 src/pocketmine/level/sound/EnderChestOpenSound.php create mode 100644 src/pocketmine/level/sound/ExplodeSound.php create mode 100644 src/pocketmine/level/sound/FlintSteelSound.php create mode 100644 src/pocketmine/level/sound/PotionSplashSound.php create mode 100644 src/pocketmine/level/sound/RedstonePowerOffSound.php create mode 100644 src/pocketmine/level/sound/RedstonePowerOnSound.php create mode 100644 src/pocketmine/level/sound/ThrowSound.php diff --git a/src/pocketmine/block/Button.php b/src/pocketmine/block/Button.php index a2d8cc3c63..da13e9aeec 100644 --- a/src/pocketmine/block/Button.php +++ b/src/pocketmine/block/Button.php @@ -25,9 +25,10 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; +use pocketmine\level\sound\RedstonePowerOffSound; +use pocketmine\level\sound\RedstonePowerOnSound; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\Player; abstract class Button extends Flowable{ @@ -64,7 +65,7 @@ abstract class Button extends Flowable{ $this->powered = true; $this->level->setBlock($this, $this); $this->level->scheduleDelayedBlockUpdate($this, $this->getActivationTime()); - $this->level->broadcastLevelSoundEvent($this->add(0.5, 0.5, 0.5), LevelSoundEventPacket::SOUND_POWER_ON); + $this->level->addSound($this->add(0.5, 0.5, 0.5), new RedstonePowerOnSound()); } return true; @@ -74,7 +75,7 @@ abstract class Button extends Flowable{ if($this->powered){ $this->powered = false; $this->level->setBlock($this, $this); - $this->level->broadcastLevelSoundEvent($this->add(0.5, 0.5, 0.5), LevelSoundEventPacket::SOUND_POWER_OFF); + $this->level->addSound($this->add(0.5, 0.5, 0.5), new RedstonePowerOffSound()); } } } diff --git a/src/pocketmine/block/Lava.php b/src/pocketmine/block/Lava.php index 4ac9013d3d..388d441d8b 100644 --- a/src/pocketmine/block/Lava.php +++ b/src/pocketmine/block/Lava.php @@ -27,8 +27,10 @@ use pocketmine\entity\Entity; use pocketmine\event\entity\EntityCombustByBlockEvent; use pocketmine\event\entity\EntityDamageByBlockEvent; use pocketmine\event\entity\EntityDamageEvent; +use pocketmine\level\sound\BucketEmptyLavaSound; +use pocketmine\level\sound\BucketFillLavaSound; +use pocketmine\level\sound\Sound; use pocketmine\math\Facing; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class Lava extends Liquid{ @@ -36,12 +38,12 @@ class Lava extends Liquid{ return 15; } - public function getBucketFillSound() : int{ - return LevelSoundEventPacket::SOUND_BUCKET_FILL_LAVA; + public function getBucketFillSound() : Sound{ + return new BucketFillLavaSound(); } - public function getBucketEmptySound() : int{ - return LevelSoundEventPacket::SOUND_BUCKET_EMPTY_LAVA; + public function getBucketEmptySound() : Sound{ + return new BucketEmptyLavaSound(); } public function tickRate() : int{ diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index 3b3b01af38..98d63e2997 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -25,9 +25,10 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; +use pocketmine\level\sound\RedstonePowerOffSound; +use pocketmine\level\sound\RedstonePowerOnSound; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\Player; class Lever extends Flowable{ @@ -112,9 +113,9 @@ class Lever extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->powered = !$this->powered; $this->level->setBlock($this, $this); - $this->level->broadcastLevelSoundEvent( + $this->level->addSound( $this->add(0.5, 0.5, 0.5), - $this->powered ? LevelSoundEventPacket::SOUND_POWER_ON : LevelSoundEventPacket::SOUND_POWER_OFF + $this->powered ? new RedstonePowerOnSound() : new RedstonePowerOffSound() ); return true; } diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index e0319ee071..c983267bf3 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -30,6 +30,7 @@ use pocketmine\event\block\BlockSpreadEvent; use pocketmine\item\Item; use pocketmine\level\Level; use pocketmine\level\sound\FizzSound; +use pocketmine\level\sound\Sound; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; use function array_fill; @@ -125,9 +126,9 @@ abstract class Liquid extends Transparent{ return $b; } - abstract public function getBucketFillSound() : int; + abstract public function getBucketFillSound() : Sound; - abstract public function getBucketEmptySound() : int; + abstract public function getBucketEmptySound() : Sound; public function isSource() : bool{ return !$this->falling and $this->decay === 0; diff --git a/src/pocketmine/block/Water.php b/src/pocketmine/block/Water.php index c490df0114..5423847bc6 100644 --- a/src/pocketmine/block/Water.php +++ b/src/pocketmine/block/Water.php @@ -24,7 +24,9 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\entity\Entity; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\level\sound\BucketEmptyWaterSound; +use pocketmine\level\sound\BucketFillWaterSound; +use pocketmine\level\sound\Sound; class Water extends Liquid{ @@ -32,12 +34,12 @@ class Water extends Liquid{ return 2; } - public function getBucketFillSound() : int{ - return LevelSoundEventPacket::SOUND_BUCKET_FILL_WATER; + public function getBucketFillSound() : Sound{ + return new BucketFillWaterSound(); } - public function getBucketEmptySound() : int{ - return LevelSoundEventPacket::SOUND_BUCKET_EMPTY_WATER; + public function getBucketEmptySound() : Sound{ + return new BucketEmptyWaterSound(); } public function tickRate() : int{ diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 816f8cb7d8..c116fb2ba4 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -45,6 +45,7 @@ use pocketmine\item\Totem; use pocketmine\level\Level; use pocketmine\level\sound\TotemUseSound; use pocketmine\level\sound\XpCollectSound; +use pocketmine\level\sound\XpLevelUpSound; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\CompoundTag; @@ -53,7 +54,6 @@ use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\protocol\AddPlayerPacket; use pocketmine\network\mcpe\protocol\EntityEventPacket; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\PlayerSkinPacket; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; @@ -354,7 +354,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ if($playSound){ $newLevel = $this->getXpLevel(); if((int) ($newLevel / 5) > (int) ($oldLevel / 5)){ - $this->playLevelUpSound($newLevel); + $this->level->addSound($this, new XpLevelUpSound($newLevel)); } } @@ -446,7 +446,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ if($playSound){ $newLevel = $this->getXpLevel(); if((int) ($newLevel / 5) > (int) ($oldLevel / 5)){ - $this->playLevelUpSound($newLevel); + $this->level->addSound($this, new XpLevelUpSound($newLevel)); }elseif($this->getCurrentTotalXp() > $oldTotal){ $this->level->addSound($this, new XpCollectSound()); } @@ -458,11 +458,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ return false; } - private function playLevelUpSound(int $newLevel) : void{ - $volume = 0x10000000 * (min(30, $newLevel) / 5); //No idea why such odd numbers, but this works... - $this->level->broadcastLevelSoundEvent($this, LevelSoundEventPacket::SOUND_LEVELUP, (int) $volume); - } - /** * Takes an amount of XP from the player, recalculating their XP level and progress. * diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 23350e3a48..fccfd75bd6 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -40,13 +40,13 @@ use pocketmine\item\Consumable; use pocketmine\item\Durable; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\Item; +use pocketmine\level\sound\ItemBreakSound; use pocketmine\math\Vector3; use pocketmine\math\VoxelRayTrace; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\protocol\EntityEventPacket; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\MobEffectPacket; use pocketmine\Player; use pocketmine\timings\Timings; @@ -544,7 +544,7 @@ abstract class Living extends Entity implements Damageable{ private function damageItem(Durable $item, int $durabilityRemoved) : void{ $item->applyDamage($durabilityRemoved); if($item->isBroken()){ - $this->level->broadcastLevelSoundEvent($this, LevelSoundEventPacket::SOUND_BREAK); + $this->level->addSound($this, new ItemBreakSound()); } } diff --git a/src/pocketmine/entity/projectile/Arrow.php b/src/pocketmine/entity/projectile/Arrow.php index de4b857927..6f79c3ed8e 100644 --- a/src/pocketmine/entity/projectile/Arrow.php +++ b/src/pocketmine/entity/projectile/Arrow.php @@ -30,10 +30,10 @@ use pocketmine\event\inventory\InventoryPickupArrowEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\level\Level; +use pocketmine\level\sound\ArrowHitSound; use pocketmine\math\RayTraceResult; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\EntityEventPacket; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\TakeItemEntityPacket; use pocketmine\Player; use function mt_rand; @@ -138,7 +138,7 @@ class Arrow extends Projectile{ protected function onHit(ProjectileHitEvent $event) : void{ $this->setCritical(false); - $this->level->broadcastLevelSoundEvent($this, LevelSoundEventPacket::SOUND_BOW_HIT); + $this->level->addSound($this, new ArrowHitSound()); } protected function onHitBlock(Block $blockHit, RayTraceResult $hitResult) : void{ diff --git a/src/pocketmine/entity/projectile/ExperienceBottle.php b/src/pocketmine/entity/projectile/ExperienceBottle.php index ff7095f5dd..2a32aa6477 100644 --- a/src/pocketmine/entity/projectile/ExperienceBottle.php +++ b/src/pocketmine/entity/projectile/ExperienceBottle.php @@ -25,7 +25,7 @@ namespace pocketmine\entity\projectile; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\level\particle\PotionSplashParticle; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\level\sound\PotionSplashSound; use function mt_rand; class ExperienceBottle extends Throwable{ @@ -39,7 +39,7 @@ class ExperienceBottle extends Throwable{ public function onHit(ProjectileHitEvent $event) : void{ $this->level->addParticle($this, new PotionSplashParticle(PotionSplashParticle::DEFAULT_COLOR())); - $this->level->broadcastLevelSoundEvent($this, LevelSoundEventPacket::SOUND_GLASS); + $this->level->addSound($this, new PotionSplashSound()); $this->level->dropExperience($this, mt_rand(3, 11)); } diff --git a/src/pocketmine/entity/projectile/SplashPotion.php b/src/pocketmine/entity/projectile/SplashPotion.php index 9a2a8b07e5..0fb687d6a7 100644 --- a/src/pocketmine/entity/projectile/SplashPotion.php +++ b/src/pocketmine/entity/projectile/SplashPotion.php @@ -33,8 +33,8 @@ use pocketmine\event\entity\ProjectileHitEntityEvent; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\item\Potion; use pocketmine\level\particle\PotionSplashParticle; +use pocketmine\level\sound\PotionSplashSound; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\utils\Color; use function round; use function sqrt; @@ -82,7 +82,7 @@ class SplashPotion extends Throwable{ } $this->level->addParticle($this, $particle); - $this->level->broadcastLevelSoundEvent($this, LevelSoundEventPacket::SOUND_GLASS); + $this->level->addSound($this, new PotionSplashSound()); if($hasEffects){ if(!$this->willLinger()){ diff --git a/src/pocketmine/inventory/ChestInventory.php b/src/pocketmine/inventory/ChestInventory.php index dc4fa69f44..0b5f269b7e 100644 --- a/src/pocketmine/inventory/ChestInventory.php +++ b/src/pocketmine/inventory/ChestInventory.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\inventory; +use pocketmine\level\sound\ChestCloseSound; +use pocketmine\level\sound\ChestOpenSound; +use pocketmine\level\sound\Sound; use pocketmine\network\mcpe\protocol\BlockEventPacket; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\types\WindowTypes; use pocketmine\Player; use pocketmine\tile\Chest; @@ -54,12 +56,12 @@ class ChestInventory extends ContainerInventory{ return $this->holder; } - protected function getOpenSound() : int{ - return LevelSoundEventPacket::SOUND_CHEST_OPEN; + protected function getOpenSound() : Sound{ + return new ChestOpenSound(); } - protected function getCloseSound() : int{ - return LevelSoundEventPacket::SOUND_CHEST_CLOSED; + protected function getCloseSound() : Sound{ + return new ChestCloseSound(); } protected function onOpen(Player $who) : void{ @@ -68,7 +70,7 @@ class ChestInventory extends ContainerInventory{ if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){ //TODO: this crap really shouldn't be managed by the inventory $this->broadcastBlockEventPacket(true); - $this->getHolder()->getLevel()->broadcastLevelSoundEvent($this->getHolder()->add(0.5, 0.5, 0.5), $this->getOpenSound()); + $this->getHolder()->getLevel()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getOpenSound()); } } @@ -76,7 +78,7 @@ class ChestInventory extends ContainerInventory{ if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){ //TODO: this crap really shouldn't be managed by the inventory $this->broadcastBlockEventPacket(false); - $this->getHolder()->getLevel()->broadcastLevelSoundEvent($this->getHolder()->add(0.5, 0.5, 0.5), $this->getCloseSound()); + $this->getHolder()->getLevel()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getCloseSound()); } parent::onClose($who); } diff --git a/src/pocketmine/inventory/EnderChestInventory.php b/src/pocketmine/inventory/EnderChestInventory.php index a0fdfe24cf..7523b87025 100644 --- a/src/pocketmine/inventory/EnderChestInventory.php +++ b/src/pocketmine/inventory/EnderChestInventory.php @@ -24,7 +24,9 @@ declare(strict_types=1); namespace pocketmine\inventory; use pocketmine\level\Position; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\level\sound\EnderChestCloseSound; +use pocketmine\level\sound\EnderChestOpenSound; +use pocketmine\level\sound\Sound; use pocketmine\network\mcpe\protocol\types\WindowTypes; use pocketmine\tile\EnderChest; @@ -51,12 +53,12 @@ class EnderChestInventory extends ChestInventory{ $this->holder->setLevel($enderChest->getLevel()); } - protected function getOpenSound() : int{ - return LevelSoundEventPacket::SOUND_ENDERCHEST_OPEN; + protected function getOpenSound() : Sound{ + return new EnderChestOpenSound(); } - protected function getCloseSound() : int{ - return LevelSoundEventPacket::SOUND_ENDERCHEST_CLOSED; + protected function getCloseSound() : Sound{ + return new EnderChestCloseSound(); } /** diff --git a/src/pocketmine/item/Bow.php b/src/pocketmine/item/Bow.php index 4718e0408d..d3e9a9ba52 100644 --- a/src/pocketmine/item/Bow.php +++ b/src/pocketmine/item/Bow.php @@ -29,7 +29,7 @@ use pocketmine\entity\projectile\Projectile; use pocketmine\event\entity\EntityShootBowEvent; use pocketmine\event\entity\ProjectileLaunchEvent; use pocketmine\item\enchantment\Enchantment; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\level\sound\BowShootSound; use pocketmine\Player; use function intdiv; use function min; @@ -106,7 +106,7 @@ class Bow extends Tool{ } $ev->getProjectile()->spawnToAll(); - $player->getLevel()->broadcastLevelSoundEvent($player, LevelSoundEventPacket::SOUND_BOW); + $player->getLevel()->addSound($player, new BowShootSound()); }else{ $entity->spawnToAll(); } diff --git a/src/pocketmine/item/Bucket.php b/src/pocketmine/item/Bucket.php index f23ce0dd1e..b1f0ff6cd4 100644 --- a/src/pocketmine/item/Bucket.php +++ b/src/pocketmine/item/Bucket.php @@ -48,7 +48,7 @@ class Bucket extends Item{ $ev->call(); if(!$ev->isCancelled()){ $player->getLevel()->setBlock($blockClicked, BlockFactory::get(BlockLegacyIds::AIR)); - $player->getLevel()->broadcastLevelSoundEvent($blockClicked->add(0.5, 0.5, 0.5), $blockClicked->getBucketFillSound()); + $player->getLevel()->addSound($blockClicked->add(0.5, 0.5, 0.5), $blockClicked->getBucketFillSound()); if($player->isSurvival()){ if($stack->getCount() === 0){ $player->getInventory()->setItemInHand($ev->getItem()); diff --git a/src/pocketmine/item/FlintSteel.php b/src/pocketmine/item/FlintSteel.php index ba1752d12c..241d4f5af1 100644 --- a/src/pocketmine/item/FlintSteel.php +++ b/src/pocketmine/item/FlintSteel.php @@ -26,8 +26,8 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; +use pocketmine\level\sound\FlintSteelSound; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\Player; use function assert; @@ -41,7 +41,7 @@ class FlintSteel extends Tool{ $level = $player->getLevel(); assert($level !== null); $level->setBlock($blockReplace, BlockFactory::get(BlockLegacyIds::FIRE)); - $level->broadcastLevelSoundEvent($blockReplace->add(0.5, 0.5, 0.5), LevelSoundEventPacket::SOUND_IGNITE); + $level->addSound($blockReplace->add(0.5, 0.5, 0.5), new FlintSteelSound()); $this->applyDamage(1); diff --git a/src/pocketmine/item/LiquidBucket.php b/src/pocketmine/item/LiquidBucket.php index f8d9eb5e5d..3c4c8e4e7d 100644 --- a/src/pocketmine/item/LiquidBucket.php +++ b/src/pocketmine/item/LiquidBucket.php @@ -64,7 +64,7 @@ class LiquidBucket extends Item{ $ev->call(); if(!$ev->isCancelled()){ $player->getLevel()->setBlock($blockReplace, $resultBlock->getFlowingForm()); - $player->getLevel()->broadcastLevelSoundEvent($blockClicked->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound()); + $player->getLevel()->addSound($blockClicked->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound()); if($player->isSurvival()){ $player->getInventory()->setItemInHand($ev->getItem()); diff --git a/src/pocketmine/item/ProjectileItem.php b/src/pocketmine/item/ProjectileItem.php index 4208434d74..f633057fe6 100644 --- a/src/pocketmine/item/ProjectileItem.php +++ b/src/pocketmine/item/ProjectileItem.php @@ -24,12 +24,11 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\entity\EntityFactory; -use pocketmine\entity\EntityIds; use pocketmine\entity\projectile\Throwable; use pocketmine\event\entity\ProjectileLaunchEvent; +use pocketmine\level\sound\ThrowSound; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\Player; use pocketmine\utils\Utils; @@ -73,7 +72,7 @@ abstract class ProjectileItem extends Item{ $projectile->spawnToAll(); - $player->getLevel()->broadcastLevelSoundEvent($player, LevelSoundEventPacket::SOUND_THROW, 0, EntityIds::PLAYER); + $player->getLevel()->addSound($player, new ThrowSound()); $this->pop(); diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index eab86a0115..14272a7a75 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -35,12 +35,12 @@ use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityExplodeEvent; use pocketmine\item\ItemFactory; use pocketmine\level\particle\HugeExplodeSeedParticle; +use pocketmine\level\sound\ExplodeSound; use pocketmine\level\utils\SubChunkIteratorManager; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\ExplodePacket; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use function ceil; use function floor; use function mt_rand; @@ -247,7 +247,7 @@ class Explosion{ $this->level->broadcastPacketToViewers($source, $pk); $this->level->addParticle($source, new HugeExplodeSeedParticle()); - $this->level->broadcastLevelSoundEvent($source, LevelSoundEventPacket::SOUND_EXPLODE); + $this->level->addSound($source, new ExplodeSound()); return true; } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 09cff9285a..5f6a886681 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -63,6 +63,7 @@ use pocketmine\level\light\LightPopulationTask; use pocketmine\level\light\SkyLightUpdate; use pocketmine\level\particle\DestroyBlockParticle; use pocketmine\level\particle\Particle; +use pocketmine\level\sound\BlockPlaceSound; use pocketmine\level\sound\Sound; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; @@ -73,11 +74,9 @@ use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\ChunkRequestTask; use pocketmine\network\mcpe\CompressBatchPromise; -use pocketmine\network\mcpe\protocol\AddEntityPacket; use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\SetDifficultyPacket; use pocketmine\network\mcpe\protocol\SetTimePacket; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; @@ -515,30 +514,6 @@ class Level implements ChunkManager, Metadatable{ } } - /** - * Broadcasts a LevelSoundEvent to players in the area. - * - * @param Vector3 $pos - * @param int $soundId - * @param int $extraData - * @param int $entityTypeId - * @param bool $isBabyMob - */ - public function broadcastLevelSoundEvent(?Vector3 $pos, int $soundId, int $extraData = -1, int $entityTypeId = -1, bool $isBabyMob = false){ - $pk = LevelSoundEventPacket::create( - $soundId, - $extraData, - $pos, - AddEntityPacket::LEGACY_ID_MAP_BC[$entityTypeId] ?? ":", - $isBabyMob - ); - if($pos !== null){ - $this->broadcastPacketToViewers($pos, $pk); - }else{ - $this->broadcastGlobalPacket($pk); - } - } - public function getAutoSave() : bool{ return $this->autoSave; } @@ -1895,7 +1870,7 @@ class Level implements ChunkManager, Metadatable{ } if($playSound){ - $this->broadcastLevelSoundEvent($hand, LevelSoundEventPacket::SOUND_PLACE, $hand->getRuntimeId()); + $this->addSound($hand, new BlockPlaceSound($hand)); } $item->pop(); diff --git a/src/pocketmine/level/sound/ArrowHitSound.php b/src/pocketmine/level/sound/ArrowHitSound.php new file mode 100644 index 0000000000..e19bdd16a2 --- /dev/null +++ b/src/pocketmine/level/sound/ArrowHitSound.php @@ -0,0 +1,34 @@ +block = $block; + } + + public function encode(Vector3 $pos){ + return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BREAK, $pos, $this->block->getRuntimeId()); + } +} diff --git a/src/pocketmine/level/sound/BlockPlaceSound.php b/src/pocketmine/level/sound/BlockPlaceSound.php new file mode 100644 index 0000000000..1d0b8b75c4 --- /dev/null +++ b/src/pocketmine/level/sound/BlockPlaceSound.php @@ -0,0 +1,42 @@ +block = $block; + } + + public function encode(Vector3 $pos){ + return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_PLACE, $pos, $this->block->getRuntimeId()); + } +} diff --git a/src/pocketmine/level/sound/BowShootSound.php b/src/pocketmine/level/sound/BowShootSound.php new file mode 100644 index 0000000000..139abbf342 --- /dev/null +++ b/src/pocketmine/level/sound/BowShootSound.php @@ -0,0 +1,34 @@ +sound = $sound; $result->extraData = $extraData; From 7b2b43c0ca14c36e1ef566724e55763268393c89 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Mar 2019 19:56:03 +0000 Subject: [PATCH 0711/3224] .................... --- src/pocketmine/level/sound/ItemBreakSound.php | 34 +++++++++++++ src/pocketmine/level/sound/XpLevelUpSound.php | 51 +++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 src/pocketmine/level/sound/ItemBreakSound.php create mode 100644 src/pocketmine/level/sound/XpLevelUpSound.php diff --git a/src/pocketmine/level/sound/ItemBreakSound.php b/src/pocketmine/level/sound/ItemBreakSound.php new file mode 100644 index 0000000000..35cf8e2587 --- /dev/null +++ b/src/pocketmine/level/sound/ItemBreakSound.php @@ -0,0 +1,34 @@ +xpLevel = $xpLevel; + } + + /** + * @return int + */ + public function getXpLevel() : int{ + return $this->xpLevel; + } + + public function encode(Vector3 $pos){ + //No idea why such odd numbers, but this works... + //TODO: check arbitrary volume + return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_LEVELUP, $pos, 0x10000000 * (min(30, $this->xpLevel) / 5)); + } +} From d8c81c0a113bcc1dec3e5d9f61811662c2e52207 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 27 Mar 2019 15:39:06 +0000 Subject: [PATCH 0712/3224] UUID: remove useless default values these are overwritten by the constructor, so they have no use here. --- src/pocketmine/utils/UUID.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/utils/UUID.php b/src/pocketmine/utils/UUID.php index 703d9fdc74..a870c00d4e 100644 --- a/src/pocketmine/utils/UUID.php +++ b/src/pocketmine/utils/UUID.php @@ -38,8 +38,8 @@ use function trim; class UUID{ - private $parts = [0, 0, 0, 0]; - private $version = null; + private $parts; + private $version; public function __construct(int $part1 = 0, int $part2 = 0, int $part3 = 0, int $part4 = 0, ?int $version = null){ $this->parts = [$part1, $part2, $part3, $part4]; From 20913549277b4447fdad4f87dcff4df331f3a706 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 27 Mar 2019 15:39:41 +0000 Subject: [PATCH 0713/3224] UUID: add type docs --- src/pocketmine/utils/UUID.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pocketmine/utils/UUID.php b/src/pocketmine/utils/UUID.php index a870c00d4e..b522f43d15 100644 --- a/src/pocketmine/utils/UUID.php +++ b/src/pocketmine/utils/UUID.php @@ -38,7 +38,9 @@ use function trim; class UUID{ + /** @var int[] */ private $parts; + /** @var int */ private $version; public function __construct(int $part1 = 0, int $part2 = 0, int $part3 = 0, int $part4 = 0, ?int $version = null){ From 3de08bf45206030fc59e1d0eec2c961a293ca2ce Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 27 Mar 2019 18:28:40 +0000 Subject: [PATCH 0714/3224] Convert PluginLoadOrder into enum --- src/pocketmine/CrashDump.php | 4 ++-- src/pocketmine/Server.php | 10 ++++---- src/pocketmine/plugin/PluginDescription.php | 22 ++++++++--------- src/pocketmine/plugin/PluginLoadOrder.php | 26 ++++++++++++++------- tests/plugins/PocketMine-DevTools | 2 +- 5 files changed, 36 insertions(+), 28 deletions(-) diff --git a/src/pocketmine/CrashDump.php b/src/pocketmine/CrashDump.php index 5c98a82e4b..2948036d99 100644 --- a/src/pocketmine/CrashDump.php +++ b/src/pocketmine/CrashDump.php @@ -25,7 +25,6 @@ namespace pocketmine; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\plugin\PluginBase; -use pocketmine\plugin\PluginLoadOrder; use pocketmine\plugin\PluginManager; use pocketmine\utils\Utils; use pocketmine\utils\VersionString; @@ -55,6 +54,7 @@ use function phpinfo; use function phpversion; use function str_split; use function strpos; +use function strtoupper; use function substr; use function time; use function zend_version; @@ -158,7 +158,7 @@ class CrashDump{ "depends" => $d->getDepend(), "softDepends" => $d->getSoftDepend(), "main" => $d->getMain(), - "load" => $d->getOrder() === PluginLoadOrder::POSTWORLD ? "POSTWORLD" : "STARTUP", + "load" => strtoupper($d->getOrder()->getEnumName()), "website" => $d->getWebsite() ]; $this->addLine($d->getName() . " " . $d->getVersion() . " by " . implode(", ", $d->getAuthors()) . " for API(s) " . implode(", ", $d->getCompatibleApis())); diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 1b511bf08a..980a97f192 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1260,7 +1260,7 @@ class Server{ $this->updater = new AutoUpdater($this, $this->getProperty("auto-updater.host", "update.pmmp.io")); - $this->enablePlugins(PluginLoadOrder::STARTUP); + $this->enablePlugins(PluginLoadOrder::STARTUP()); foreach((array) $this->getProperty("worlds", []) as $name => $options){ if($options === null){ @@ -1313,7 +1313,7 @@ class Server{ $this->properties->save(); } - $this->enablePlugins(PluginLoadOrder::POSTWORLD); + $this->enablePlugins(PluginLoadOrder::POSTWORLD()); $this->network->registerInterface(new RakLibInterface($this)); $this->logger->info($this->getLanguage()->translateString("pocketmine.server.networkStart", [$this->getIp(), $this->getPort()])); @@ -1559,16 +1559,16 @@ class Server{ } /** - * @param int $type + * @param PluginLoadOrder $type */ - public function enablePlugins(int $type) : void{ + public function enablePlugins(PluginLoadOrder $type) : void{ foreach($this->pluginManager->getPlugins() as $plugin){ if(!$plugin->isEnabled() and $plugin->getDescription()->getOrder() === $type){ $this->pluginManager->enablePlugin($plugin); } } - if($type === PluginLoadOrder::POSTWORLD){ + if($type === PluginLoadOrder::POSTWORLD()){ $this->commandMap->registerServerAliases(); DefaultPermissions::registerCorePermissions(); } diff --git a/src/pocketmine/plugin/PluginDescription.php b/src/pocketmine/plugin/PluginDescription.php index 49ca9b0729..3550a1ed72 100644 --- a/src/pocketmine/plugin/PluginDescription.php +++ b/src/pocketmine/plugin/PluginDescription.php @@ -27,8 +27,6 @@ use pocketmine\permission\Permission; use pocketmine\permission\PermissionParser; use function array_map; use function array_values; -use function constant; -use function defined; use function extension_loaded; use function is_array; use function phpversion; @@ -36,7 +34,6 @@ use function preg_match; use function str_replace; use function stripos; use function strlen; -use function strtoupper; use function substr; use function version_compare; @@ -63,7 +60,8 @@ class PluginDescription{ private $website = ""; /** @var string */ private $prefix = ""; - private $order = PluginLoadOrder::POSTWORLD; + /** @var PluginLoadOrder */ + private $order; /** * @var Permission[] @@ -129,13 +127,15 @@ class PluginDescription{ $this->prefix = (string) ($plugin["prefix"] ?? $this->prefix); if(isset($plugin["load"])){ - $order = strtoupper($plugin["load"]); - if(!defined(PluginLoadOrder::class . "::" . $order)){ - throw new PluginException("Invalid PluginDescription load"); - }else{ - $this->order = constant(PluginLoadOrder::class . "::" . $order); + try{ + $this->order = PluginLoadOrder::fromString($plugin["load"]); + }catch(\Error $e){ + throw new PluginException("Invalid PluginDescription \"load\""); } + }else{ + $this->order = PluginLoadOrder::POSTWORLD(); } + $this->authors = []; if(isset($plugin["author"])){ $this->authors[] = $plugin["author"]; @@ -273,9 +273,9 @@ class PluginDescription{ } /** - * @return int + * @return PluginLoadOrder */ - public function getOrder() : int{ + public function getOrder() : PluginLoadOrder{ return $this->order; } diff --git a/src/pocketmine/plugin/PluginLoadOrder.php b/src/pocketmine/plugin/PluginLoadOrder.php index 1a44ed7015..ebca6528ba 100644 --- a/src/pocketmine/plugin/PluginLoadOrder.php +++ b/src/pocketmine/plugin/PluginLoadOrder.php @@ -23,15 +23,23 @@ declare(strict_types=1); namespace pocketmine\plugin; +use pocketmine\utils\EnumTrait; -abstract class PluginLoadOrder{ - /* - * The plugin will be loaded at startup - */ - public const STARTUP = 0; +/** + * This doc-block is generated automatically, do not modify it manually. + * This must be regenerated whenever enum members are added, removed or changed. + * @see EnumTrait::_generateMethodAnnotations() + * + * @method static self STARTUP() + * @method static self POSTWORLD() + */ +final class PluginLoadOrder{ + use EnumTrait; - /* - * The plugin will be loaded after the first world has been loaded/created. - */ - public const POSTWORLD = 1; + protected static function setup() : array{ + return [ + new self("startup"), + new self("postworld") + ]; + } } diff --git a/tests/plugins/PocketMine-DevTools b/tests/plugins/PocketMine-DevTools index dafd417d0b..9a992364d4 160000 --- a/tests/plugins/PocketMine-DevTools +++ b/tests/plugins/PocketMine-DevTools @@ -1 +1 @@ -Subproject commit dafd417d0b601da926408f16a5e6fa341a54405b +Subproject commit 9a992364d4458ccf09640befeb0e991b5d67ad8a From 0e806854b9a1e82b0fc30dccebeb557e7d1b69b2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 27 Mar 2019 19:16:39 +0000 Subject: [PATCH 0715/3224] Server: clean up startup order a little --- src/pocketmine/Server.php | 67 ++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 980a97f192..e5bea63487 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1135,21 +1135,6 @@ class Server{ $this->doTitleTick = ((bool) $this->getProperty("console.title-tick", true)) && Terminal::hasFormattingCodes(); - - $consoleSender = new ConsoleCommandSender(); - PermissionManager::getInstance()->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $consoleSender); - - $consoleNotifier = new SleeperNotifier(); - $this->console = new CommandReader($consoleNotifier); - $this->tickSleeper->addNotifier($consoleNotifier, function() use ($consoleSender) : void{ - Timings::$serverCommandTimer->startTiming(); - while(($line = $this->console->getLine()) !== null){ - $this->dispatchCommand($consoleSender, $line); - } - Timings::$serverCommandTimer->stopTiming(); - }); - $this->console->start(PTHREADS_INHERIT_NONE); - $this->entityMetadata = new EntityMetadataStore(); $this->playerMetadata = new PlayerMetadataStore(); $this->levelMetadata = new LevelMetadataStore(); @@ -1195,16 +1180,15 @@ class Server{ $this->network = new Network($this->logger); $this->network->setName($this->getMotd()); - $this->logger->info($this->getLanguage()->translateString("pocketmine.server.info", [ $this->getName(), (\pocketmine\IS_DEVELOPMENT_BUILD ? TextFormat::YELLOW : "") . $this->getPocketMineVersion() . TextFormat::RESET ])); $this->logger->info($this->getLanguage()->translateString("pocketmine.server.license", [$this->getName()])); - Timings::init(); TimingsHandler::setEnabled((bool) $this->getProperty("settings.enable-profiling", false)); + $this->profilingTickRate = (float) $this->getProperty("settings.profile-report-trigger", 20); $this->commandMap = new SimpleCommandMap($this); @@ -1234,7 +1218,6 @@ class Server{ return; } $this->pluginManager = new PluginManager($this, ((bool) $this->getProperty("plugins.legacy-data-dir", true)) ? null : $this->getDataPath() . "plugin_data" . DIRECTORY_SEPARATOR, $pluginGraylist); - $this->profilingTickRate = (float) $this->getProperty("settings.profile-report-trigger", 20); $this->pluginManager->registerInterface(new PharPluginLoader($this->autoloader)); $this->pluginManager->registerInterface(new ScriptPluginLoader()); @@ -1248,18 +1231,16 @@ class Server{ $this->logger->warning($this->language->translateString("pocketmine.level.badDefaultFormat", [$formatName])); } - $this->levelManager = new LevelManager($this); - GeneratorManager::registerDefaultGenerators(); - - register_shutdown_function([$this, "crashDump"]); - - $this->queryRegenerateTask = new QueryRegenerateEvent($this); - - $this->pluginManager->loadPlugins($this->pluginPath); + $this->levelManager = new LevelManager($this); $this->updater = new AutoUpdater($this, $this->getProperty("auto-updater.host", "update.pmmp.io")); + $this->queryRegenerateTask = new QueryRegenerateEvent($this); + + register_shutdown_function([$this, "crashDump"]); + + $this->pluginManager->loadPlugins($this->pluginPath); $this->enablePlugins(PluginLoadOrder::STARTUP()); foreach((array) $this->getProperty("worlds", []) as $name => $options){ @@ -1309,10 +1290,6 @@ class Server{ $this->levelManager->setDefaultLevel($level); } - if($this->properties->hasChanged()){ - $this->properties->save(); - } - $this->enablePlugins(PluginLoadOrder::POSTWORLD()); $this->network->registerInterface(new RakLibInterface($this)); @@ -1326,12 +1303,6 @@ class Server{ $this->network->blockAddress($entry->getName(), -1); } - if($this->getProperty("settings.send-usage", true)){ - $this->sendUsageTicker = 6000; - $this->sendUsage(SendUsageTask::TYPE_OPEN); - } - - if($this->getProperty("network.upnp-forwarding", false)){ $this->logger->info("[UPnP] Trying to port forward..."); try{ @@ -1341,12 +1312,36 @@ class Server{ } } + if($this->getProperty("settings.send-usage", true)){ + $this->sendUsageTicker = 6000; + $this->sendUsage(SendUsageTask::TYPE_OPEN); + } + + if($this->properties->hasChanged()){ + $this->properties->save(); + } + $this->tickCounter = 0; $this->logger->info($this->getLanguage()->translateString("pocketmine.server.defaultGameMode", [GameMode::toTranslation($this->getGamemode())])); $this->logger->info($this->getLanguage()->translateString("pocketmine.server.startFinished", [round(microtime(true) - \pocketmine\START_TIME, 3)])); + //TODO: move console parts to a separate component + $consoleSender = new ConsoleCommandSender(); + PermissionManager::getInstance()->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $consoleSender); + + $consoleNotifier = new SleeperNotifier(); + $this->console = new CommandReader($consoleNotifier); + $this->tickSleeper->addNotifier($consoleNotifier, function() use ($consoleSender) : void{ + Timings::$serverCommandTimer->startTiming(); + while(($line = $this->console->getLine()) !== null){ + $this->dispatchCommand($consoleSender, $line); + } + Timings::$serverCommandTimer->stopTiming(); + }); + $this->console->start(PTHREADS_INHERIT_NONE); + $this->tickProcessor(); $this->forceShutdown(); }catch(\Throwable $e){ From 649ce5080b1138e1efe408371ceab64698c2526c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 27 Mar 2019 19:24:06 +0000 Subject: [PATCH 0716/3224] StatusCommand: don't use config for reading global limit --- src/pocketmine/MemoryManager.php | 7 +++++++ src/pocketmine/command/defaults/StatusCommand.php | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/MemoryManager.php b/src/pocketmine/MemoryManager.php index 3392ea2c64..530dd3bcf3 100644 --- a/src/pocketmine/MemoryManager.php +++ b/src/pocketmine/MemoryManager.php @@ -177,6 +177,13 @@ class MemoryManager{ return $this->lowMemory; } + /** + * @return int + */ + public function getGlobalMemoryLimit() : int{ + return $this->globalMemoryLimit; + } + /** * @return bool */ diff --git a/src/pocketmine/command/defaults/StatusCommand.php b/src/pocketmine/command/defaults/StatusCommand.php index ac707ca784..d937f75e04 100644 --- a/src/pocketmine/command/defaults/StatusCommand.php +++ b/src/pocketmine/command/defaults/StatusCommand.php @@ -102,8 +102,9 @@ class StatusCommand extends VanillaCommand{ $sender->sendMessage(TextFormat::GOLD . "Heap memory: " . TextFormat::RED . number_format(round(($rUsage[0] / 1024) / 1024, 2), 2) . " MB."); $sender->sendMessage(TextFormat::GOLD . "Maximum memory (system): " . TextFormat::RED . number_format(round(($mUsage[2] / 1024) / 1024, 2), 2) . " MB."); - if($server->getProperty("memory.global-limit") > 0){ - $sender->sendMessage(TextFormat::GOLD . "Maximum memory (manager): " . TextFormat::RED . number_format(round($server->getProperty("memory.global-limit"), 2), 2) . " MB."); + $globalLimit = $server->getMemoryManager()->getGlobalMemoryLimit(); + if($globalLimit > 0){ + $sender->sendMessage(TextFormat::GOLD . "Maximum memory (manager): " . TextFormat::RED . number_format(round($globalLimit, 2), 2) . " MB."); } foreach($server->getLevelManager()->getLevels() as $level){ From de193d41a037e9f6403b3b7f6d7d90d71fc3ba8c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 27 Mar 2019 23:53:39 +0000 Subject: [PATCH 0717/3224] Server: fixed console not receiving user broadcast channel messages I'm not entirely clear how this managed to work to begin with really, but it's now fixed properly. --- src/pocketmine/Server.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index e5bea63487..726a71e668 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1330,6 +1330,7 @@ class Server{ //TODO: move console parts to a separate component $consoleSender = new ConsoleCommandSender(); PermissionManager::getInstance()->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $consoleSender); + PermissionManager::getInstance()->subscribeToPermission(Server::BROADCAST_CHANNEL_USERS, $consoleSender); $consoleNotifier = new SleeperNotifier(); $this->console = new CommandReader($consoleNotifier); From 260fa50db4f57a5fb1fa3ec1e20f3e043a7e24ac Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Mar 2019 14:23:42 +0000 Subject: [PATCH 0718/3224] Register Edu compound items --- src/pocketmine/item/ItemFactory.php | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 91fb13a6f5..24017c86ff 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -123,6 +123,44 @@ class ItemFactory{ self::register(new Item(Item::BRICK, 0, "Brick")); self::register(new Item(Item::CHORUS_FRUIT_POPPED, 0, "Popped Chorus Fruit")); self::register(new Item(Item::CLAY_BALL, 0, "Clay")); + self::register(new Item(Item::COMPOUND, 0, "Salt")); + self::register(new Item(Item::COMPOUND, 1, "Sodium Oxide")); + self::register(new Item(Item::COMPOUND, 2, "Sodium Hydroxide")); + self::register(new Item(Item::COMPOUND, 3, "Magnesium Nitrate")); + self::register(new Item(Item::COMPOUND, 4, "Iron Sulphide")); + self::register(new Item(Item::COMPOUND, 5, "Lithium Hydride")); + self::register(new Item(Item::COMPOUND, 6, "Sodium Hydride")); + self::register(new Item(Item::COMPOUND, 7, "Calcium Bromide")); + self::register(new Item(Item::COMPOUND, 8, "Magnesium Oxide")); + self::register(new Item(Item::COMPOUND, 9, "Sodium Acetate")); + self::register(new Item(Item::COMPOUND, 10, "Luminol")); + self::register(new Item(Item::COMPOUND, 11, "Charcoal")); //??? maybe bug + self::register(new Item(Item::COMPOUND, 12, "Sugar")); //??? maybe bug + self::register(new Item(Item::COMPOUND, 13, "Aluminium Oxide")); + self::register(new Item(Item::COMPOUND, 14, "Boron Trioxide")); + self::register(new Item(Item::COMPOUND, 15, "Soap")); + self::register(new Item(Item::COMPOUND, 16, "Polyethylene")); + self::register(new Item(Item::COMPOUND, 17, "Rubbish")); + self::register(new Item(Item::COMPOUND, 18, "Magnesium Salts")); + self::register(new Item(Item::COMPOUND, 19, "Sulphate")); + self::register(new Item(Item::COMPOUND, 20, "Barium Sulphate")); + self::register(new Item(Item::COMPOUND, 21, "Potassium Chloride")); + self::register(new Item(Item::COMPOUND, 22, "Mercuric Chloride")); + self::register(new Item(Item::COMPOUND, 23, "Cerium Chloride")); + self::register(new Item(Item::COMPOUND, 24, "Tungsten Chloride")); + self::register(new Item(Item::COMPOUND, 25, "Calcium Chloride")); + self::register(new Item(Item::COMPOUND, 26, "Water")); //??? + self::register(new Item(Item::COMPOUND, 27, "Glue")); + self::register(new Item(Item::COMPOUND, 28, "Hypochlorite")); + self::register(new Item(Item::COMPOUND, 29, "Crude Oil")); + self::register(new Item(Item::COMPOUND, 30, "Latex")); + self::register(new Item(Item::COMPOUND, 31, "Potassium Iodide")); + self::register(new Item(Item::COMPOUND, 32, "Sodium Fluoride")); + self::register(new Item(Item::COMPOUND, 33, "Benzene")); + self::register(new Item(Item::COMPOUND, 34, "Ink")); + self::register(new Item(Item::COMPOUND, 35, "Hydrogen Peroxide")); + self::register(new Item(Item::COMPOUND, 36, "Ammonia")); + self::register(new Item(Item::COMPOUND, 37, "Sodium Hypochlorite")); self::register(new Item(Item::DIAMOND, 0, "Diamond")); self::register(new Item(Item::DRAGON_BREATH, 0, "Dragon's Breath")); self::register(new Item(Item::DYE, 0, "Ink Sac")); From 1fd40779075604d64f4a4628715be270ed52bd26 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 29 Mar 2019 15:28:11 +0000 Subject: [PATCH 0719/3224] MainLogger: Always use CRITICAL for logException() --- src/pocketmine/utils/MainLogger.php | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/pocketmine/utils/MainLogger.php b/src/pocketmine/utils/MainLogger.php index 68c46ff019..a6a43da617 100644 --- a/src/pocketmine/utils/MainLogger.php +++ b/src/pocketmine/utils/MainLogger.php @@ -36,10 +36,6 @@ use function sprintf; use function time; use function touch; use function trim; -use const E_ERROR; -use const E_USER_ERROR; -use const E_USER_WARNING; -use const E_WARNING; use const PHP_EOL; use const PTHREADS_INHERIT_NONE; @@ -198,11 +194,6 @@ class MainLogger extends \AttachableThreadedLogger{ $errno = $e->getCode(); $errline = $e->getLine(); - if($errno === 0){ - $type = LogLevel::CRITICAL; - }else{ - $type = ($errno === E_ERROR or $errno === E_USER_ERROR) ? LogLevel::ERROR : (($errno === E_USER_WARNING or $errno === E_WARNING) ? LogLevel::WARNING : LogLevel::NOTICE); - } try{ $errno = \ErrorUtils::errorTypeToString($errno); }catch(\InvalidArgumentException $e){ @@ -214,8 +205,8 @@ class MainLogger extends \AttachableThreadedLogger{ $message = get_class($e) . ": \"$errstr\" ($errno) in \"$errfile\" at line $errline"; $stack = Utils::printableTrace($trace); - $this->synchronized(function() use ($type, $message, $stack) : void{ - $this->log($type, $message); + $this->synchronized(function() use ($message, $stack) : void{ + $this->log(LogLevel::CRITICAL, $message); foreach($stack as $line){ $this->debug($line, true); } From 3ea52609353da4ce00be239fccb4606314ebc5c3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 30 Mar 2019 18:28:42 +0000 Subject: [PATCH 0720/3224] Sync composer dependencies --- composer.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.lock b/composer.lock index 81dc093108..60d9cfe674 100644 --- a/composer.lock +++ b/composer.lock @@ -372,12 +372,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "98b727aa9125a56c3dac9b65cde3f75acf5f6b2a" + "reference": "a9719e3b0d11713a461ca5ed2e8c608c503e09b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/98b727aa9125a56c3dac9b65cde3f75acf5f6b2a", - "reference": "98b727aa9125a56c3dac9b65cde3f75acf5f6b2a", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/a9719e3b0d11713a461ca5ed2e8c608c503e09b1", + "reference": "a9719e3b0d11713a461ca5ed2e8c608c503e09b1", "shasum": "" }, "require": { @@ -405,7 +405,7 @@ "source": "https://github.com/pmmp/NBT/tree/master", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2019-03-23T08:59:10+00:00" + "time": "2019-03-30T17:32:31+00:00" }, { "name": "pocketmine/raklib", @@ -413,12 +413,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "1a213053c51c6793ea050eb9e7d0bc4184dce52c" + "reference": "c2d5262d10e1b25f764f2e8ea09e1e3d0e578b72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/1a213053c51c6793ea050eb9e7d0bc4184dce52c", - "reference": "1a213053c51c6793ea050eb9e7d0bc4184dce52c", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/c2d5262d10e1b25f764f2e8ea09e1e3d0e578b72", + "reference": "c2d5262d10e1b25f764f2e8ea09e1e3d0e578b72", "shasum": "" }, "require": { @@ -446,7 +446,7 @@ "source": "https://github.com/pmmp/RakLib/tree/master", "issues": "https://github.com/pmmp/RakLib/issues" }, - "time": "2019-03-23T12:51:03+00:00" + "time": "2019-03-24T16:57:27+00:00" }, { "name": "pocketmine/snooze", From 004e81ea35045fdca4e63a5d841d013feb0435c9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 30 Mar 2019 18:44:30 +0000 Subject: [PATCH 0721/3224] XpLevelUpSound: fixed crash on non-multiples of 5 --- src/pocketmine/level/sound/XpLevelUpSound.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/level/sound/XpLevelUpSound.php b/src/pocketmine/level/sound/XpLevelUpSound.php index 1057105768..0020e0ea6a 100644 --- a/src/pocketmine/level/sound/XpLevelUpSound.php +++ b/src/pocketmine/level/sound/XpLevelUpSound.php @@ -25,6 +25,7 @@ namespace pocketmine\level\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use function intdiv; use function min; class XpLevelUpSound implements Sound{ @@ -46,6 +47,6 @@ class XpLevelUpSound implements Sound{ public function encode(Vector3 $pos){ //No idea why such odd numbers, but this works... //TODO: check arbitrary volume - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_LEVELUP, $pos, 0x10000000 * (min(30, $this->xpLevel) / 5)); + return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_LEVELUP, $pos, 0x10000000 * intdiv(min(30, $this->xpLevel), 5)); } } From cdeb3ea5a650dd2e9375743a3f0e69fc22a06cd4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 30 Mar 2019 19:53:24 +0000 Subject: [PATCH 0722/3224] Sync NBT dependency --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 60d9cfe674..607f08db32 100644 --- a/composer.lock +++ b/composer.lock @@ -372,12 +372,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "a9719e3b0d11713a461ca5ed2e8c608c503e09b1" + "reference": "d2a9d578e3d677f5a007b16881e3390f1bad8fb9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/a9719e3b0d11713a461ca5ed2e8c608c503e09b1", - "reference": "a9719e3b0d11713a461ca5ed2e8c608c503e09b1", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/d2a9d578e3d677f5a007b16881e3390f1bad8fb9", + "reference": "d2a9d578e3d677f5a007b16881e3390f1bad8fb9", "shasum": "" }, "require": { @@ -405,7 +405,7 @@ "source": "https://github.com/pmmp/NBT/tree/master", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2019-03-30T17:32:31+00:00" + "time": "2019-03-30T19:51:58+00:00" }, { "name": "pocketmine/raklib", From 8c19f6cac8fc8b874ae294335f6a4ca185378fe2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Mar 2019 16:07:42 +0100 Subject: [PATCH 0723/3224] EnumTrait: throw InvalidArgumentException from fromString() this is more in line with expected behaviour, since this might be used to process arbitrary user input. Only calling an undefined magic static method should throw an Error. --- src/pocketmine/utils/EnumTrait.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/utils/EnumTrait.php b/src/pocketmine/utils/EnumTrait.php index 263996400e..9843c4b141 100644 --- a/src/pocketmine/utils/EnumTrait.php +++ b/src/pocketmine/utils/EnumTrait.php @@ -76,12 +76,13 @@ trait EnumTrait{ * @param string $name * * @return self + * @throws \InvalidArgumentException */ public static function fromString(string $name) : self{ self::checkInit(); $name = strtoupper($name); if(!isset(self::$members[$name])){ - throw new \Error("Undefined enum member: " . self::class . "::" . $name); + throw new \InvalidArgumentException("Undefined enum member: " . self::class . "::" . $name); } return self::$members[$name]; } @@ -96,7 +97,11 @@ trait EnumTrait{ if(!empty($arguments)){ throw new \ArgumentCountError("Expected exactly 0 arguments, " . count($arguments) . " passed"); } - return self::fromString($name); + try{ + return self::fromString($name); + }catch(\InvalidArgumentException $e){ + throw new \Error($e->getMessage(), 0, $e); + } } /** From 0017c0087a524caf04768f3fdaa3b8c5038ed37a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Mar 2019 16:17:01 +0100 Subject: [PATCH 0724/3224] oopsie woopsie --- src/pocketmine/plugin/PluginDescription.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/plugin/PluginDescription.php b/src/pocketmine/plugin/PluginDescription.php index 3550a1ed72..eea1e213d7 100644 --- a/src/pocketmine/plugin/PluginDescription.php +++ b/src/pocketmine/plugin/PluginDescription.php @@ -129,7 +129,7 @@ class PluginDescription{ if(isset($plugin["load"])){ try{ $this->order = PluginLoadOrder::fromString($plugin["load"]); - }catch(\Error $e){ + }catch(\InvalidArgumentException $e){ throw new PluginException("Invalid PluginDescription \"load\""); } }else{ From 42a263a9dfb77e8d21f2282a9a31429c47d2f801 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Mar 2019 16:19:36 +0100 Subject: [PATCH 0725/3224] GameMode is now an enum --- src/pocketmine/GameMode.php | 155 ++++++++++-------- src/pocketmine/Player.php | 44 ++--- src/pocketmine/Server.php | 8 +- .../defaults/DefaultGamemodeCommand.php | 5 +- .../command/defaults/GamemodeCommand.php | 6 +- .../player/PlayerGameModeChangeEvent.php | 7 +- .../event/server/QueryRegenerateEvent.php | 2 +- .../network/mcpe/RakLibInterface.php | 3 +- .../mcpe/handler/SimpleSessionHandler.php | 2 +- 9 files changed, 128 insertions(+), 104 deletions(-) diff --git a/src/pocketmine/GameMode.php b/src/pocketmine/GameMode.php index 99e0bd4c92..409ebe4b0a 100644 --- a/src/pocketmine/GameMode.php +++ b/src/pocketmine/GameMode.php @@ -23,88 +23,109 @@ declare(strict_types=1); namespace pocketmine; -final class GameMode{ - public const SURVIVAL = 0; - public const CREATIVE = 1; - public const ADVENTURE = 2; - public const SPECTATOR = 3; - public const VIEW = GameMode::SPECTATOR; +use pocketmine\utils\EnumTrait; - private function __construct(){ - //NOOP +/** + * This doc-block is generated automatically, do not modify it manually. + * This must be regenerated whenever enum members are added, removed or changed. + * @see EnumTrait::_generateMethodAnnotations() + * + * @method static self SURVIVAL() + * @method static self CREATIVE() + * @method static self ADVENTURE() + * @method static self SPECTATOR() + */ +final class GameMode{ + use EnumTrait { + __construct as Enum___construct; + register as Enum_register; + fromString as Enum_fromString; + } + + /** @var self[] */ + protected static $aliasMap = []; + /** @var self[] */ + protected static $magicNumberMap = []; + + protected static function setup() : array{ + return [ + new self("survival", 0, "Survival", "gameMode.survival", ["s", "0"]), + new self("creative", 1, "Creative", "gameMode.creative", ["c", "1"]), + new self("adventure", 2, "Adventure", "gameMode.adventure", ["a", "2"]), + new self("spectator", 3, "Spectator", "gameMode.spectator", ["v", "view", "3"]) + ]; + } + + protected static function register(self $member) : void{ + self::Enum_register($member); + self::$magicNumberMap[$member->getMagicNumber()] = $member; + foreach($member->getAliases() as $alias){ + self::$aliasMap[$alias] = $member; + } + } + + public static function fromString(string $str) : self{ + self::checkInit(); + return self::$aliasMap[$str] ?? self::Enum_fromString($str); } /** - * Parses a string and returns a gamemode integer, -1 if not found - * - * @param string $str - * - * @return int + * @param int $n * + * @return GameMode * @throws \InvalidArgumentException */ - public static function fromString(string $str) : int{ - switch(strtolower(trim($str))){ - case (string) self::SURVIVAL: - case "survival": - case "s": - return self::SURVIVAL; - - case (string) self::CREATIVE: - case "creative": - case "c": - return self::CREATIVE; - - case (string) self::ADVENTURE: - case "adventure": - case "a": - return self::ADVENTURE; - - case (string) self::SPECTATOR: - case "spectator": - case "view": - case "v": - return self::SPECTATOR; + public static function fromMagicNumber(int $n) : self{ + self::checkInit(); + if(!isset(self::$magicNumberMap[$n])){ + throw new \InvalidArgumentException("No " . self::class . " enum member matches magic number $n"); } + return self::$magicNumberMap[$n]; + } - throw new \InvalidArgumentException("Unknown gamemode string \"$str\""); + /** @var int */ + private $magicNumber; + /** @var string */ + private $englishName; + /** @var string */ + private $translationKey; + /** @var string[] */ + private $aliases; + + private function __construct(string $enumName, int $magicNumber, string $englishName, string $translationKey, array $aliases = []){ + $this->Enum___construct($enumName); + $this->magicNumber = $magicNumber; + $this->englishName = $englishName; + $this->translationKey = $translationKey; + $this->aliases = $aliases; } /** - * Returns the gamemode text name - * - * @param int $mode - * - * @return string + * @return int */ - public static function toTranslation(int $mode) : string{ - switch($mode){ - case self::SURVIVAL: - return "%gameMode.survival"; - case self::CREATIVE: - return "%gameMode.creative"; - case self::ADVENTURE: - return "%gameMode.adventure"; - case self::SPECTATOR: - return "%gameMode.spectator"; - } - - return "UNKNOWN"; + public function getMagicNumber() : int{ + return $this->magicNumber; } - public static function toString(int $mode) : string{ - switch($mode){ - case self::SURVIVAL: - return "Survival"; - case self::CREATIVE: - return "Creative"; - case self::ADVENTURE: - return "Adventure"; - case self::SPECTATOR: - return "Spectator"; - default: - throw new \InvalidArgumentException("Invalid gamemode $mode"); - } + /** + * @return string + */ + public function getEnglishName() : string{ + return $this->englishName; + } + + /** + * @return string + */ + public function getTranslationKey() : string{ + return "%" . $this->translationKey; + } + + /** + * @return string[] + */ + public function getAliases() : array{ + return $this->aliases; } //TODO: ability sets per gamemode diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 0146f52605..2b3195003e 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -94,6 +94,7 @@ use pocketmine\metadata\MetadataValue; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\DoubleTag; +use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\NetworkSession; @@ -224,7 +225,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, protected $firstPlayed; /** @var int */ protected $lastPlayed; - /** @var int */ + /** @var GameMode */ protected $gamemode; /** @var bool[] chunkHash => bool (true = sent, false = needs sending) */ @@ -387,7 +388,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->firstPlayed = $nbt->getLong("firstPlayed", $now = (int) (microtime(true) * 1000)); $this->lastPlayed = $nbt->getLong("lastPlayed", $now); - $this->gamemode = $this->server->getForceGamemode() ? $this->server->getGamemode() : $nbt->getInt("playerGameType", $this->server->getGamemode()) & 0x03; + if($this->server->getForceGamemode() or !$nbt->hasTag("playerGameType", IntTag::class)){ + $this->gamemode = $this->server->getGamemode(); + }else{ + $this->gamemode = GameMode::fromMagicNumber($nbt->getInt("playerGameType") & 0x03); //TODO: bad hack here to avoid crashes on corrupted data + } $this->allowFlight = $this->isCreative(); $this->keepMovement = $this->isSpectator() || $this->allowMovementCheats(); @@ -1360,9 +1365,9 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } /** - * @return int + * @return GameMode */ - public function getGamemode() : int{ + public function getGamemode() : GameMode{ return $this->gamemode; } @@ -1374,29 +1379,28 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * * TODO: remove this when Spectator Mode gets added properly to MCPE * - * @param int $gamemode + * @param GameMode $gamemode * * @return int */ - public static function getClientFriendlyGamemode(int $gamemode) : int{ - $gamemode &= 0x03; - if($gamemode === GameMode::SPECTATOR){ - return GameMode::CREATIVE; + public static function getClientFriendlyGamemode(GameMode $gamemode) : int{ + if($gamemode === GameMode::SPECTATOR()){ + return GameMode::CREATIVE()->getMagicNumber(); } - return $gamemode; + return $gamemode->getMagicNumber(); } /** * Sets the gamemode, and if needed, kicks the Player. * - * @param int $gm - * @param bool $client if the client made this change in their GUI + * @param GameMode $gm + * @param bool $client if the client made this change in their GUI * * @return bool */ - public function setGamemode(int $gm, bool $client = false) : bool{ - if($gm < 0 or $gm > 3 or $this->gamemode === $gm){ + public function setGamemode(GameMode $gm, bool $client = false) : bool{ + if($this->gamemode === $gm){ return false; } @@ -1427,7 +1431,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if(!$client){ //Gamemode changed by server, do not send for client changes $this->sendGamemode(); }else{ - Command::broadcastCommandMessage($this, new TranslationContainer("commands.gamemode.success.self", [GameMode::toTranslation($gm)])); + Command::broadcastCommandMessage($this, new TranslationContainer("commands.gamemode.success.self", [$gm->getTranslationKey()])); } $this->sendSettings(); @@ -1475,7 +1479,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool */ public function isSurvival(bool $literal = false) : bool{ - return $this->gamemode === GameMode::SURVIVAL or (!$literal and $this->gamemode === GameMode::ADVENTURE); + return $this->gamemode === GameMode::SURVIVAL() or (!$literal and $this->gamemode === GameMode::ADVENTURE()); } /** @@ -1487,7 +1491,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool */ public function isCreative(bool $literal = false) : bool{ - return $this->gamemode === GameMode::CREATIVE or (!$literal and $this->gamemode === GameMode::SPECTATOR); + return $this->gamemode === GameMode::CREATIVE() or (!$literal and $this->gamemode === GameMode::SPECTATOR()); } /** @@ -1499,14 +1503,14 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool */ public function isAdventure(bool $literal = false) : bool{ - return $this->gamemode === GameMode::ADVENTURE or (!$literal and $this->gamemode === GameMode::SPECTATOR); + return $this->gamemode === GameMode::ADVENTURE() or (!$literal and $this->gamemode === GameMode::SPECTATOR()); } /** * @return bool */ public function isSpectator() : bool{ - return $this->gamemode === GameMode::SPECTATOR; + return $this->gamemode === GameMode::SPECTATOR(); } public function isFireProof() : bool{ @@ -2793,7 +2797,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $nbt->setTag("Achievements", $achievements); - $nbt->setInt("playerGameType", $this->gamemode); + $nbt->setInt("playerGameType", $this->gamemode->getMagicNumber()); $nbt->setLong("firstPlayed", $this->firstPlayed); $nbt->setLong("lastPlayed", (int) floor(microtime(true) * 1000)); diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 787c496214..e12ebdc229 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -422,10 +422,10 @@ class Server{ } /** - * @return int + * @return GameMode */ - public function getGamemode() : int{ - return $this->getConfigInt("gamemode", 0) & 0b11; + public function getGamemode() : GameMode{ + return GameMode::fromMagicNumber($this->getConfigInt("gamemode", 0) & 0b11); } /** @@ -1322,7 +1322,7 @@ class Server{ $this->tickCounter = 0; - $this->logger->info($this->getLanguage()->translateString("pocketmine.server.defaultGameMode", [GameMode::toTranslation($this->getGamemode())])); + $this->logger->info($this->getLanguage()->translateString("pocketmine.server.defaultGameMode", [$this->getGamemode()->getTranslationKey()])); $this->logger->info($this->getLanguage()->translateString("pocketmine.server.startFinished", [round(microtime(true) - \pocketmine\START_TIME, 3)])); diff --git a/src/pocketmine/command/defaults/DefaultGamemodeCommand.php b/src/pocketmine/command/defaults/DefaultGamemodeCommand.php index 294ba3a276..74a4f5c92b 100644 --- a/src/pocketmine/command/defaults/DefaultGamemodeCommand.php +++ b/src/pocketmine/command/defaults/DefaultGamemodeCommand.php @@ -56,9 +56,8 @@ class DefaultGamemodeCommand extends VanillaCommand{ return true; } - $sender->getServer()->setConfigInt("gamemode", $gameMode); - $sender->sendMessage(new TranslationContainer("commands.defaultgamemode.success", [GameMode::toTranslation($gameMode)])); - + $sender->getServer()->setConfigInt("gamemode", $gameMode->getMagicNumber()); + $sender->sendMessage(new TranslationContainer("commands.defaultgamemode.success", [$gameMode->getTranslationKey()])); return true; } } diff --git a/src/pocketmine/command/defaults/GamemodeCommand.php b/src/pocketmine/command/defaults/GamemodeCommand.php index d8db3fcca8..6f13bab5b3 100644 --- a/src/pocketmine/command/defaults/GamemodeCommand.php +++ b/src/pocketmine/command/defaults/GamemodeCommand.php @@ -76,10 +76,10 @@ class GamemodeCommand extends VanillaCommand{ $sender->sendMessage("Game mode change for " . $target->getName() . " failed!"); }else{ if($target === $sender){ - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.gamemode.success.self", [GameMode::toTranslation($gameMode)])); + Command::broadcastCommandMessage($sender, new TranslationContainer("commands.gamemode.success.self", [$gameMode->getTranslationKey()])); }else{ - $target->sendMessage(new TranslationContainer("gameMode.changed", [GameMode::toTranslation($gameMode)])); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.gamemode.success.other", [GameMode::toTranslation($gameMode), $target->getName()])); + $target->sendMessage(new TranslationContainer("gameMode.changed", [$gameMode->getTranslationKey()])); + Command::broadcastCommandMessage($sender, new TranslationContainer("commands.gamemode.success.other", [$gameMode->getTranslationKey(), $target->getName()])); } } diff --git a/src/pocketmine/event/player/PlayerGameModeChangeEvent.php b/src/pocketmine/event/player/PlayerGameModeChangeEvent.php index 0a399e0bc3..8e4415bd9e 100644 --- a/src/pocketmine/event/player/PlayerGameModeChangeEvent.php +++ b/src/pocketmine/event/player/PlayerGameModeChangeEvent.php @@ -25,6 +25,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; +use pocketmine\GameMode; use pocketmine\Player; /** @@ -33,15 +34,15 @@ use pocketmine\Player; class PlayerGameModeChangeEvent extends PlayerEvent implements Cancellable{ use CancellableTrait; - /** @var int */ + /** @var GameMode */ protected $gamemode; - public function __construct(Player $player, int $newGamemode){ + public function __construct(Player $player, GameMode $newGamemode){ $this->player = $player; $this->gamemode = $newGamemode; } - public function getNewGamemode() : int{ + public function getNewGamemode() : GameMode{ return $this->gamemode; } } diff --git a/src/pocketmine/event/server/QueryRegenerateEvent.php b/src/pocketmine/event/server/QueryRegenerateEvent.php index d7267baac2..c4effc1f9a 100644 --- a/src/pocketmine/event/server/QueryRegenerateEvent.php +++ b/src/pocketmine/event/server/QueryRegenerateEvent.php @@ -86,7 +86,7 @@ class QueryRegenerateEvent extends ServerEvent{ } } - $this->gametype = ($server->getGamemode() & 0x01) === 0 ? "SMP" : "CMP"; + $this->gametype = ($server->getGamemode()->getMagicNumber() & 0x01) === 0 ? "SMP" : "CMP"; $this->version = $server->getVersion(); $this->server_engine = $server->getName() . " " . $server->getPocketMineVersion(); $level = $server->getLevelManager()->getDefaultLevel(); diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index e33b0767b6..70b30033e7 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; -use pocketmine\GameMode; use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\ProtocolInfo; @@ -210,7 +209,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $info->getMaxPlayerCount(), $this->rakLib->getServerId(), $this->server->getName(), - GameMode::toString($this->server->getGamemode()) + $this->server->getGamemode()->getEnglishName() ]) . ";" ); } diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index 640764c84b..3be514f5b4 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -468,7 +468,7 @@ class SimpleSessionHandler extends SessionHandler{ } public function handleSetPlayerGameType(SetPlayerGameTypePacket $packet) : bool{ - if($packet->gamemode !== $this->player->getGamemode()){ + if($packet->gamemode !== $this->player->getGamemode()->getMagicNumber()){ //Set this back to default. TODO: handle this properly $this->player->sendGamemode(); $this->player->sendSettings(); From f8ce7797db57f9e347d38a4aaa3d288c0664868f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Mar 2019 16:40:54 +0100 Subject: [PATCH 0726/3224] Player: add hasFiniteResources() --- src/pocketmine/Player.php | 27 +++++++++++++-------- src/pocketmine/entity/object/ItemEntity.php | 2 +- src/pocketmine/entity/projectile/Arrow.php | 2 +- src/pocketmine/item/Bow.php | 4 +-- src/pocketmine/item/Bucket.php | 2 +- src/pocketmine/item/LiquidBucket.php | 2 +- 6 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 2b3195003e..ae20ed50fc 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1513,6 +1513,15 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->gamemode === GameMode::SPECTATOR(); } + /** + * TODO: make this a dynamic ability instead of being hardcoded + * + * @return bool + */ + public function hasFiniteResources() : bool{ + return $this->gamemode === GameMode::SURVIVAL() or $this->gamemode === GameMode::ADVENTURE(); + } + public function isFireProof() : bool{ return $this->isCreative(); } @@ -1937,7 +1946,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $result = $item->onClickAir($this, $directionVector); if($result === ItemUseResult::SUCCESS()){ $this->resetItemCooldown($item); - if($this->isSurvival()){ + if($this->hasFiniteResources()){ $this->inventory->setItemInHand($item); } }elseif($result === ItemUseResult::FAIL()){ @@ -1971,7 +1980,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->resetItemCooldown($slot); - if($this->isSurvival()){ + if($this->hasFiniteResources()){ $slot->pop(); $this->inventory->setItemInHand($slot); $this->inventory->addItem($slot->getResidue()); @@ -2132,12 +2141,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $item = $this->inventory->getItemInHand(); $oldItem = clone $item; if($this->level->useBreakOn($pos, $item, $this, true)){ - if($this->isSurvival()){ - if(!$item->equalsExact($oldItem)){ - $this->inventory->setItemInHand($item); - } - $this->exhaust(0.025, PlayerExhaustEvent::CAUSE_MINING); + if($this->hasFiniteResources() and !$item->equalsExact($oldItem)){ + $this->inventory->setItemInHand($item); } + $this->exhaust(0.025, PlayerExhaustEvent::CAUSE_MINING); return true; } } @@ -2171,7 +2178,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $item = $this->inventory->getItemInHand(); //this is a copy of the real item $oldItem = clone $item; if($this->level->useItemOn($pos, $item, $face, $clickOffset, $this, true)){ - if($this->isSurvival() and !$item->equalsExact($oldItem)){ + if($this->hasFiniteResources() and !$item->equalsExact($oldItem)){ $this->inventory->setItemInHand($item); } return true; @@ -2239,7 +2246,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $entity->attack($ev); if($ev->isCancelled()){ - if($heldItem instanceof Durable and $this->isSurvival()){ + if($heldItem instanceof Durable and $this->hasFiniteResources()){ $this->inventory->sendContents($this); } return false; @@ -2258,7 +2265,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($this->isAlive()){ //reactive damage like thorns might cause us to be killed by attacking another mob, which //would mean we'd already have dropped the inventory by the time we reached here - if($heldItem->onAttackEntity($entity) and $this->isSurvival()){ //always fire the hook, even if we are survival + if($heldItem->onAttackEntity($entity) and $this->hasFiniteResources()){ //always fire the hook, even if we are survival $this->inventory->setItemInHand($heldItem); } diff --git a/src/pocketmine/entity/object/ItemEntity.php b/src/pocketmine/entity/object/ItemEntity.php index c01a496184..0dadfdd232 100644 --- a/src/pocketmine/entity/object/ItemEntity.php +++ b/src/pocketmine/entity/object/ItemEntity.php @@ -252,7 +252,7 @@ class ItemEntity extends Entity{ $item = $this->getItem(); $playerInventory = $player->getInventory(); - if($player->isSurvival() and !$playerInventory->canAddItem($item)){ + if($player->hasFiniteResources() and !$playerInventory->canAddItem($item)){ return; } diff --git a/src/pocketmine/entity/projectile/Arrow.php b/src/pocketmine/entity/projectile/Arrow.php index 6f79c3ed8e..dda7b92178 100644 --- a/src/pocketmine/entity/projectile/Arrow.php +++ b/src/pocketmine/entity/projectile/Arrow.php @@ -179,7 +179,7 @@ class Arrow extends Projectile{ $item = ItemFactory::get(Item::ARROW, 0, 1); $playerInventory = $player->getInventory(); - if($player->isSurvival() and !$playerInventory->canAddItem($item)){ + if($player->hasFiniteResources() and !$playerInventory->canAddItem($item)){ return; } diff --git a/src/pocketmine/item/Bow.php b/src/pocketmine/item/Bow.php index d3e9a9ba52..74d3f41bd1 100644 --- a/src/pocketmine/item/Bow.php +++ b/src/pocketmine/item/Bow.php @@ -48,7 +48,7 @@ class Bow extends Tool{ } public function onReleaseUsing(Player $player) : ItemUseResult{ - if($player->isSurvival() and !$player->getInventory()->contains(ItemFactory::get(Item::ARROW, 0, 1))){ + if($player->hasFiniteResources() and !$player->getInventory()->contains(ItemFactory::get(Item::ARROW, 0, 1))){ return ItemUseResult::FAIL(); } @@ -111,7 +111,7 @@ class Bow extends Tool{ $entity->spawnToAll(); } - if($player->isSurvival()){ + if($player->hasFiniteResources()){ if(!$infinity){ //TODO: tipped arrows are still consumed when Infinity is applied $player->getInventory()->removeItem(ItemFactory::get(Item::ARROW, 0, 1)); } diff --git a/src/pocketmine/item/Bucket.php b/src/pocketmine/item/Bucket.php index b1f0ff6cd4..4af42b9ac7 100644 --- a/src/pocketmine/item/Bucket.php +++ b/src/pocketmine/item/Bucket.php @@ -49,7 +49,7 @@ class Bucket extends Item{ if(!$ev->isCancelled()){ $player->getLevel()->setBlock($blockClicked, BlockFactory::get(BlockLegacyIds::AIR)); $player->getLevel()->addSound($blockClicked->add(0.5, 0.5, 0.5), $blockClicked->getBucketFillSound()); - if($player->isSurvival()){ + if($player->hasFiniteResources()){ if($stack->getCount() === 0){ $player->getInventory()->setItemInHand($ev->getItem()); }else{ diff --git a/src/pocketmine/item/LiquidBucket.php b/src/pocketmine/item/LiquidBucket.php index 3c4c8e4e7d..4ef4cdcd11 100644 --- a/src/pocketmine/item/LiquidBucket.php +++ b/src/pocketmine/item/LiquidBucket.php @@ -66,7 +66,7 @@ class LiquidBucket extends Item{ $player->getLevel()->setBlock($blockReplace, $resultBlock->getFlowingForm()); $player->getLevel()->addSound($blockClicked->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound()); - if($player->isSurvival()){ + if($player->hasFiniteResources()){ $player->getInventory()->setItemInHand($ev->getItem()); } return ItemUseResult::SUCCESS(); From c59a2d1b9328276b6ac55991f60bc55eb6f0ad12 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Mar 2019 16:51:43 +0100 Subject: [PATCH 0727/3224] More hasFiniteResources() usages --- src/pocketmine/Player.php | 6 +++--- src/pocketmine/entity/object/Painting.php | 2 +- .../transaction/action/CreativeInventoryAction.php | 2 +- src/pocketmine/level/Level.php | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index ae20ed50fc..e06619371c 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1527,7 +1527,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } public function getDrops() : array{ - if(!$this->isCreative()){ + if($this->hasFiniteResources()){ return parent::getDrops(); } @@ -1535,7 +1535,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } public function getXpDropAmount() : int{ - if(!$this->isCreative()){ + if($this->hasFiniteResources()){ return parent::getXpDropAmount(); } @@ -2052,7 +2052,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, }else{ $this->inventory->swap($this->inventory->getHeldItemIndex(), $existing); } - }elseif($this->isCreative(true)){ //TODO: plugins won't know this isn't going to execute + }elseif(!$this->hasFiniteResources()){ //TODO: plugins won't know this isn't going to execute $firstEmpty = $this->inventory->firstEmpty(); if($firstEmpty === -1){ //full inventory $this->inventory->setItemInHand($item); diff --git a/src/pocketmine/entity/object/Painting.php b/src/pocketmine/entity/object/Painting.php index 18d143704f..e5ea041cd3 100644 --- a/src/pocketmine/entity/object/Painting.php +++ b/src/pocketmine/entity/object/Painting.php @@ -100,7 +100,7 @@ class Painting extends Entity{ if($this->lastDamageCause instanceof EntityDamageByEntityEvent){ $killer = $this->lastDamageCause->getDamager(); - if($killer instanceof Player and $killer->isCreative()){ + if($killer instanceof Player and !$killer->hasFiniteResources()){ $drops = false; } } diff --git a/src/pocketmine/inventory/transaction/action/CreativeInventoryAction.php b/src/pocketmine/inventory/transaction/action/CreativeInventoryAction.php index af861c00f9..4b1f618031 100644 --- a/src/pocketmine/inventory/transaction/action/CreativeInventoryAction.php +++ b/src/pocketmine/inventory/transaction/action/CreativeInventoryAction.php @@ -52,7 +52,7 @@ class CreativeInventoryAction extends InventoryAction{ * @return bool */ public function isValid(Player $source) : bool{ - return $source->isCreative(true) and + return !$source->hasFiniteResources() and ($this->actionType === self::TYPE_DELETE_ITEM or Item::getCreativeItemIndex($this->sourceItem) !== -1); } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 10743f696a..603cffb584 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1672,12 +1672,12 @@ class Level implements ChunkManager, Metadatable{ } $drops = []; - if($player === null or !$player->isCreative()){ + if($player === null or $player->hasFiniteResources()){ $drops = array_merge(...array_map(function(Block $block) use ($item) : array{ return $block->getDrops($item); }, $affectedBlocks)); } $xpDrop = 0; - if($player !== null and !$player->isCreative()){ + if($player !== null and $player->hasFiniteResources()){ $xpDrop = array_sum(array_map(function(Block $block) use ($item) : int{ return $block->getXpDropForTool($item); }, $affectedBlocks)); } From f0b85936cf76d4935a52f3d73a5da9c8d8f807c9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Mar 2019 19:08:35 +0100 Subject: [PATCH 0728/3224] Improved /tell --- resources/locale | 2 +- src/pocketmine/command/defaults/TellCommand.php | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/resources/locale b/resources/locale index b8ec058c4c..15a2b7d4f0 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit b8ec058c4cf341ff0c4f08f315feb990b62ae0e5 +Subproject commit 15a2b7d4f05959376e3ef6d71e793b7bbdb2b60e diff --git a/src/pocketmine/command/defaults/TellCommand.php b/src/pocketmine/command/defaults/TellCommand.php index b81df78587..ed1c3f05ec 100644 --- a/src/pocketmine/command/defaults/TellCommand.php +++ b/src/pocketmine/command/defaults/TellCommand.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\command\defaults; +use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; @@ -61,9 +62,11 @@ class TellCommand extends VanillaCommand{ } if($player instanceof Player){ - $sender->sendMessage("[{$sender->getName()} -> {$player->getDisplayName()}] " . implode(" ", $args)); + $message = implode(" ", $args); + $sender->sendMessage(new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . "%commands.message.display.outgoing", [$player->getDisplayName(), $message])); $name = $sender instanceof Player ? $sender->getDisplayName() : $sender->getName(); - $player->sendMessage("[$name -> {$player->getName()}] " . implode(" ", $args)); + $player->sendMessage(new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . "%commands.message.display.incoming", [$name, $message])); + Command::broadcastCommandMessage($sender, new TranslationContainer("%commands.message.display.outgoing", [$player->getDisplayName(), $message]), false); }else{ $sender->sendMessage(new TranslationContainer("commands.generic.player.notFound")); } From 6214a9398dafbf6231a871303bef49fea318b1d9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Mar 2019 19:25:09 +0100 Subject: [PATCH 0729/3224] Player: remove sendWhisper() this can be done with a standard translated message, and with more customizability. --- src/pocketmine/Player.php | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index e06619371c..f1194ea23e 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2621,18 +2621,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->sendDataPacket($pk); } - /** - * @param string $sender - * @param string $message - */ - public function sendWhisper(string $sender, string $message){ - $pk = new TextPacket(); - $pk->type = TextPacket::TYPE_WHISPER; - $pk->sourceName = $sender; - $pk->message = $message; - $this->sendDataPacket($pk); - } - /** * Sends a Form to the player, or queue to send it if a form is already open. * From 2c4f2810d2654375c2b834fe12999b465bfa2caf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Apr 2019 14:57:11 +0100 Subject: [PATCH 0730/3224] AsyncTask: Remove misleading methods getFromThreadStore(),saveToThreadStore(),removeFromThreadStore() These methods are commonly mixed up when we talk about thread-local storage. What these things actually do is store persistent data on the worker thread. --- .../level/generator/GeneratorRegisterTask.php | 4 +- .../generator/GeneratorUnregisterTask.php | 4 +- .../level/generator/PopulationTask.php | 4 +- src/pocketmine/scheduler/AsyncTask.php | 39 ------------------- 4 files changed, 6 insertions(+), 45 deletions(-) diff --git a/src/pocketmine/level/generator/GeneratorRegisterTask.php b/src/pocketmine/level/generator/GeneratorRegisterTask.php index 7ce2618f50..ebb64e2c50 100644 --- a/src/pocketmine/level/generator/GeneratorRegisterTask.php +++ b/src/pocketmine/level/generator/GeneratorRegisterTask.php @@ -51,13 +51,13 @@ class GeneratorRegisterTask extends AsyncTask{ BlockFactory::init(); Biome::init(); $manager = new SimpleChunkManager($this->worldHeight); - $this->saveToThreadStore("generation.level{$this->levelId}.manager", $manager); + $this->worker->saveToThreadStore("generation.level{$this->levelId}.manager", $manager); /** * @var Generator $generator * @see Generator::__construct() */ $generator = new $this->generatorClass($manager, $this->seed, unserialize($this->settings)); - $this->saveToThreadStore("generation.level{$this->levelId}.generator", $generator); + $this->worker->saveToThreadStore("generation.level{$this->levelId}.generator", $generator); } } diff --git a/src/pocketmine/level/generator/GeneratorUnregisterTask.php b/src/pocketmine/level/generator/GeneratorUnregisterTask.php index 54aa2fb481..9732571a0c 100644 --- a/src/pocketmine/level/generator/GeneratorUnregisterTask.php +++ b/src/pocketmine/level/generator/GeneratorUnregisterTask.php @@ -35,7 +35,7 @@ class GeneratorUnregisterTask extends AsyncTask{ } public function onRun() : void{ - $this->removeFromThreadStore("generation.level{$this->levelId}.manager"); - $this->removeFromThreadStore("generation.level{$this->levelId}.generator"); + $this->worker->removeFromThreadStore("generation.level{$this->levelId}.manager"); + $this->worker->removeFromThreadStore("generation.level{$this->levelId}.generator"); } } diff --git a/src/pocketmine/level/generator/PopulationTask.php b/src/pocketmine/level/generator/PopulationTask.php index 165bc9ca77..5ca622ca55 100644 --- a/src/pocketmine/level/generator/PopulationTask.php +++ b/src/pocketmine/level/generator/PopulationTask.php @@ -58,9 +58,9 @@ class PopulationTask extends AsyncTask{ public function onRun() : void{ /** @var SimpleChunkManager $manager */ - $manager = $this->getFromThreadStore("generation.level{$this->levelId}.manager"); + $manager = $this->worker->getFromThreadStore("generation.level{$this->levelId}.manager"); /** @var Generator $generator */ - $generator = $this->getFromThreadStore("generation.level{$this->levelId}.generator"); + $generator = $this->worker->getFromThreadStore("generation.level{$this->levelId}.generator"); if($manager === null or $generator === null){ $this->state = false; return; diff --git a/src/pocketmine/scheduler/AsyncTask.php b/src/pocketmine/scheduler/AsyncTask.php index 6b6f597890..65fbef49bd 100644 --- a/src/pocketmine/scheduler/AsyncTask.php +++ b/src/pocketmine/scheduler/AsyncTask.php @@ -138,45 +138,6 @@ abstract class AsyncTask extends \Threaded{ return $this->submitted; } - /** - * @see AsyncWorker::getFromThreadStore() - * - * @param string $identifier - * - * @return mixed - */ - public function getFromThreadStore(string $identifier){ - if($this->worker === null or $this->isFinished()){ - throw new \BadMethodCallException("Objects stored in AsyncWorker thread-local storage can only be retrieved during task execution"); - } - return $this->worker->getFromThreadStore($identifier); - } - - /** - * @see AsyncWorker::saveToThreadStore() - * - * @param string $identifier - * @param mixed $value - */ - public function saveToThreadStore(string $identifier, $value) : void{ - if($this->worker === null or $this->isFinished()){ - throw new \BadMethodCallException("Objects can only be added to AsyncWorker thread-local storage during task execution"); - } - $this->worker->saveToThreadStore($identifier, $value); - } - - /** - * @see AsyncWorker::removeFromThreadStore() - * - * @param string $identifier - */ - public function removeFromThreadStore(string $identifier) : void{ - if($this->worker === null or $this->isFinished()){ - throw new \BadMethodCallException("Objects can only be removed from AsyncWorker thread-local storage during task execution"); - } - $this->worker->removeFromThreadStore($identifier); - } - /** * Actions to execute when run */ From e5756dbf0b8afa0b2ff1828421f9cfdbedfd71e5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Apr 2019 18:31:16 +0100 Subject: [PATCH 0731/3224] Move a whole bunch of packet crap to NetworkSession --- composer.lock | 8 +- src/pocketmine/Player.php | 257 +++--------------- src/pocketmine/entity/Living.php | 10 +- .../network/mcpe/NetworkSession.php | 247 ++++++++++++++++- .../mcpe/handler/PreSpawnSessionHandler.php | 10 +- .../mcpe/handler/SimpleSessionHandler.php | 10 +- 6 files changed, 308 insertions(+), 234 deletions(-) diff --git a/composer.lock b/composer.lock index 607f08db32..af042e1f6c 100644 --- a/composer.lock +++ b/composer.lock @@ -488,12 +488,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/SPL.git", - "reference": "02476b8990ad31c38fa999ec0392f6d01208574d" + "reference": "463152d5d2ee052a89fe44dcc27b56663f891912" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/SPL/zipball/02476b8990ad31c38fa999ec0392f6d01208574d", - "reference": "02476b8990ad31c38fa999ec0392f6d01208574d", + "url": "https://api.github.com/repos/pmmp/SPL/zipball/463152d5d2ee052a89fe44dcc27b56663f891912", + "reference": "463152d5d2ee052a89fe44dcc27b56663f891912", "shasum": "" }, "type": "library", @@ -512,7 +512,7 @@ "support": { "source": "https://github.com/pmmp/SPL/tree/master" }, - "time": "2019-03-15T15:22:36+00:00" + "time": "2019-03-31T16:30:20+00:00" } ], "packages-dev": [], diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index f1194ea23e..92138677a2 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -98,28 +98,13 @@ use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\NetworkSession; -use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; -use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; use pocketmine\network\mcpe\protocol\BookEditPacket; -use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; -use pocketmine\network\mcpe\protocol\MobEffectPacket; -use pocketmine\network\mcpe\protocol\ModalFormRequestPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; -use pocketmine\network\mcpe\protocol\NetworkChunkPublisherUpdatePacket; -use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; -use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket; use pocketmine\network\mcpe\protocol\SetTitlePacket; -use pocketmine\network\mcpe\protocol\TextPacket; -use pocketmine\network\mcpe\protocol\TransferPacket; -use pocketmine\network\mcpe\protocol\types\CommandData; -use pocketmine\network\mcpe\protocol\types\CommandEnum; -use pocketmine\network\mcpe\protocol\types\CommandParameter; use pocketmine\network\mcpe\protocol\types\ContainerIds; -use pocketmine\network\mcpe\protocol\types\PlayerPermissions; -use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissionAttachment; use pocketmine\permission\PermissionAttachmentInfo; @@ -137,10 +122,7 @@ use function count; use function explode; use function floor; use function get_class; -use function in_array; use function is_int; -use function json_encode; -use function json_last_error_msg; use function max; use function microtime; use function min; @@ -153,7 +135,6 @@ use function strpos; use function strtolower; use function substr; use function trim; -use function ucfirst; use const M_PI; use const M_SQRT3; use const PHP_INT_MAX; @@ -531,7 +512,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, public function setAllowFlight(bool $value){ $this->allowFlight = $value; - $this->sendSettings(); + $this->networkSession->syncAdventureSettings($this); } public function getAllowFlight() : bool{ @@ -542,7 +523,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($this->flying !== $value){ $this->flying = $value; $this->resetFallDistance(); - $this->sendSettings(); + $this->networkSession->syncAdventureSettings($this); } } @@ -552,7 +533,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, public function setAutoJump(bool $value){ $this->autoJump = $value; - $this->sendSettings(); + $this->networkSession->syncAdventureSettings($this); } public function hasAutoJump() : bool{ @@ -665,9 +646,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->nextChunkOrderRun = 0; - $pk = new ChunkRadiusUpdatedPacket(); - $pk->radius = $this->viewDistance; - $this->sendDataPacket($pk); + $this->networkSession->syncViewAreaRadius($this->viewDistance); $this->server->getLogger()->debug("Setting view distance for " . $this->getName() . " to " . $this->viewDistance . " (requested " . $distance . ")"); } @@ -700,7 +679,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->server->removeOp($this->getName()); } - $this->sendSettings(); + $this->networkSession->syncAdventureSettings($this); } /** @@ -763,7 +742,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $permManager->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this); } - $this->sendCommandData(); + $this->networkSession->syncAvailableCommands(); } } @@ -774,44 +753,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->perm->getEffectivePermissions(); } - public function sendCommandData(){ - $pk = new AvailableCommandsPacket(); - foreach($this->server->getCommandMap()->getCommands() as $name => $command){ - if(isset($pk->commandData[$command->getName()]) or $command->getName() === "help" or !$command->testPermissionSilent($this)){ - continue; - } - - $data = new CommandData(); - //TODO: commands containing uppercase letters in the name crash 1.9.0 client - $data->commandName = strtolower($command->getName()); - $data->commandDescription = $this->server->getLanguage()->translateString($command->getDescription()); - $data->flags = 0; - $data->permission = 0; - - $parameter = new CommandParameter(); - $parameter->paramName = "args"; - $parameter->paramType = AvailableCommandsPacket::ARG_FLAG_VALID | AvailableCommandsPacket::ARG_TYPE_RAWTEXT; - $parameter->isOptional = true; - $data->overloads[0][0] = $parameter; - - $aliases = $command->getAliases(); - if(!empty($aliases)){ - if(!in_array($data->commandName, $aliases, true)){ - //work around a client bug which makes the original name not show when aliases are used - $aliases[] = $data->commandName; - } - $data->aliases = new CommandEnum(); - $data->aliases->enumName = ucfirst($command->getName()) . "Aliases"; - $data->aliases->enumValues = $aliases; - } - - $pk->commandData[$command->getName()] = $data; - } - - $this->sendDataPacket($pk); - - } - /** * @return bool */ @@ -1187,12 +1128,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->loadQueue = $newOrder; if(!empty($this->loadQueue) or !empty($unloadChunks)){ - $pk = new NetworkChunkPublisherUpdatePacket(); - $pk->x = $this->getFloorX(); - $pk->y = $this->getFloorY(); - $pk->z = $this->getFloorZ(); - $pk->radius = $this->viewDistance * 16; //blocks, not chunks >.> - $this->sendDataPacket($pk); + $this->networkSession->syncViewAreaCenterPoint($this, $this->viewDistance); } Timings::$playerChunkOrderTimer->stopTiming(); @@ -1246,13 +1182,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $level = $pos->getLevel(); } $this->spawnPosition = new Position($pos->x, $pos->y, $pos->z, $level); - $pk = new SetSpawnPositionPacket(); - $pk->x = $this->spawnPosition->getFloorX(); - $pk->y = $this->spawnPosition->getFloorY(); - $pk->z = $this->spawnPosition->getFloorZ(); - $pk->spawnType = SetSpawnPositionPacket::TYPE_PLAYER_SPAWN; - $pk->spawnForced = false; - $this->sendDataPacket($pk); + $this->networkSession->syncPlayerSpawnPoint($this->spawnPosition); } /** @@ -1371,26 +1301,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->gamemode; } - /** - * @internal - * - * Returns a client-friendly gamemode of the specified real gamemode - * This function takes care of handling gamemodes known to MCPE (as of 1.1.0.3, that includes Survival, Creative and Adventure) - * - * TODO: remove this when Spectator Mode gets added properly to MCPE - * - * @param GameMode $gamemode - * - * @return int - */ - public static function getClientFriendlyGamemode(GameMode $gamemode) : int{ - if($gamemode === GameMode::SPECTATOR()){ - return GameMode::CREATIVE()->getMagicNumber(); - } - - return $gamemode->getMagicNumber(); - } - /** * Sets the gamemode, and if needed, kicks the Player. * @@ -1408,7 +1318,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $ev->call(); if($ev->isCancelled()){ if($client){ //gamemode change by client in the GUI - $this->sendGamemode(); + $this->networkSession->syncGameMode($this->gamemode); } return false; } @@ -1429,47 +1339,17 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } if(!$client){ //Gamemode changed by server, do not send for client changes - $this->sendGamemode(); + $this->networkSession->syncGameMode($this->gamemode); }else{ Command::broadcastCommandMessage($this, new TranslationContainer("commands.gamemode.success.self", [$gm->getTranslationKey()])); } - $this->sendSettings(); + $this->networkSession->syncAdventureSettings($this); $this->inventory->sendCreativeContents(); return true; } - /** - * @internal - * Sends the player's gamemode to the client. - */ - public function sendGamemode(){ - $pk = new SetPlayerGameTypePacket(); - $pk->gamemode = Player::getClientFriendlyGamemode($this->gamemode); - $this->sendDataPacket($pk); - } - - /** - * Sends all the option flags - */ - public function sendSettings(){ - $pk = new AdventureSettingsPacket(); - - $pk->setFlag(AdventureSettingsPacket::WORLD_IMMUTABLE, $this->isSpectator()); - $pk->setFlag(AdventureSettingsPacket::NO_PVP, $this->isSpectator()); - $pk->setFlag(AdventureSettingsPacket::AUTO_JUMP, $this->autoJump); - $pk->setFlag(AdventureSettingsPacket::ALLOW_FLIGHT, $this->allowFlight); - $pk->setFlag(AdventureSettingsPacket::NO_CLIP, $this->isSpectator()); - $pk->setFlag(AdventureSettingsPacket::FLYING, $this->flying); - - $pk->commandPermission = ($this->isOp() ? AdventureSettingsPacket::PERMISSION_OPERATOR : AdventureSettingsPacket::PERMISSION_NORMAL); - $pk->playerPermission = ($this->isOp() ? PlayerPermissions::OPERATOR : PlayerPermissions::MEMBER); - $pk->entityUniqueId = $this->getId(); - - $this->sendDataPacket($pk); - } - /** * NOTE: Because Survival and Adventure Mode share some similar behaviour, this method will also return true if the player is * in Adventure Mode. Supply the $literal parameter as true to force a literal Survival Mode check. @@ -1587,6 +1467,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool if the */ public function updateNextPosition(Vector3 $newPos) : bool{ + //TODO: teleport acks are a network specific thing and shouldn't be here + $newPos = $newPos->asVector3(); if($this->isTeleporting and $newPos->distanceSquared($this) > 1){ //Tolerate up to 1 block to avoid problems with client-sided physics when spawning in blocks $this->sendPosition($this, null, null, MovePlayerPacket::MODE_RESET); @@ -1739,19 +1621,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } - public function sendAttributes(bool $sendAll = false){ - $entries = $sendAll ? $this->attributeMap->getAll() : $this->attributeMap->needSend(); - if(count($entries) > 0){ - $pk = new UpdateAttributesPacket(); - $pk->entityRuntimeId = $this->id; - $pk->entries = $entries; - $this->sendDataPacket($pk); - foreach($entries as $entry){ - $entry->markSynchronized(); - } - } - } - public function onUpdate(int $currentTick) : bool{ $tickDiff = $currentTick - $this->lastUpdate; @@ -1763,7 +1632,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->lastUpdate = $currentTick; - $this->sendAttributes(); + //TODO: move this to network session ticking (this is specifically related to net sync) + $this->networkSession->syncAttributes($this); if(!$this->isAlive() and $this->spawned){ $this->onDeathUpdate($tickDiff); @@ -1819,25 +1689,12 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->isCreative() or parent::canBreathe(); } - protected function sendEffectAdd(EffectInstance $effect, bool $replacesOldEffect) : void{ - $pk = new MobEffectPacket(); - $pk->entityRuntimeId = $this->getId(); - $pk->eventId = $replacesOldEffect ? MobEffectPacket::EVENT_MODIFY : MobEffectPacket::EVENT_ADD; - $pk->effectId = $effect->getId(); - $pk->amplifier = $effect->getAmplifier(); - $pk->particles = $effect->isVisible(); - $pk->duration = $effect->getDuration(); - - $this->sendDataPacket($pk); + protected function onEffectAdded(EffectInstance $effect, bool $replacesOldEffect) : void{ + $this->networkSession->onEntityEffectAdded($this, $effect, $replacesOldEffect); } - protected function sendEffectRemove(EffectInstance $effect) : void{ - $pk = new MobEffectPacket(); - $pk->entityRuntimeId = $this->getId(); - $pk->eventId = MobEffectPacket::EVENT_REMOVE; - $pk->effectId = $effect->getId(); - - $this->sendDataPacket($pk); + protected function onEffectRemoved(EffectInstance $effect) : void{ + $this->networkSession->onEntityEffectRemoved($this, $effect); } /** @@ -2315,7 +2172,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $ev->call(); if($ev->isCancelled()){ - $this->sendSettings(); + $this->networkSession->syncAdventureSettings($this); }else{ //don't use setFlying() here, to avoid feedback loops $this->flying = $fly; $this->resetFallDistance(); @@ -2430,12 +2287,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $ev = new PlayerTransferEvent($this, $address, $port, $message); $ev->call(); if(!$ev->isCancelled()){ - $pk = new TransferPacket(); - $pk->address = $ev->getAddress(); - $pk->port = $ev->getPort(); - $this->sendDataPacket($pk, true); - $this->close("", $ev->getMessage(), false); - + $this->networkSession->transfer($ev->getAddress(), $ev->getPort(), $ev->getMessage()); return true; } @@ -2572,10 +2424,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $message = $message->getText(); } - $pk = new TextPacket(); - $pk->type = TextPacket::TYPE_RAW; - $pk->message = $this->server->getLanguage()->translateString($message); - $this->sendDataPacket($pk); + $this->networkSession->onRawChatMessage($this->server->getLanguage()->translateString($message)); } /** @@ -2583,20 +2432,14 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @param string[] $parameters */ public function sendTranslation(string $message, array $parameters = []){ - $pk = new TextPacket(); if(!$this->server->isLanguageForced()){ - $pk->type = TextPacket::TYPE_TRANSLATION; - $pk->needsTranslation = true; - $pk->message = $this->server->getLanguage()->translateString($message, $parameters, "pocketmine."); foreach($parameters as $i => $p){ $parameters[$i] = $this->server->getLanguage()->translateString($p, $parameters, "pocketmine."); } - $pk->parameters = $parameters; + $this->networkSession->onTranslatedChatMessage($this->server->getLanguage()->translateString($message, $parameters, "pocketmine."), $parameters); }else{ - $pk->type = TextPacket::TYPE_RAW; - $pk->message = $this->server->getLanguage()->translateString($message, $parameters); + $this->sendMessage($this->server->getLanguage()->translateString($message, $parameters)); } - $this->sendDataPacket($pk); } /** @@ -2608,33 +2451,23 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @param string $subtitle @deprecated */ public function sendPopup(string $message, string $subtitle = ""){ - $pk = new TextPacket(); - $pk->type = TextPacket::TYPE_POPUP; - $pk->message = $message; - $this->sendDataPacket($pk); + $this->networkSession->onPopup($message); } public function sendTip(string $message){ - $pk = new TextPacket(); - $pk->type = TextPacket::TYPE_TIP; - $pk->message = $message; - $this->sendDataPacket($pk); + $this->networkSession->onTip($message); } /** * Sends a Form to the player, or queue to send it if a form is already open. * * @param Form $form + * + * @throws \InvalidArgumentException */ public function sendForm(Form $form) : void{ $id = $this->formIdCounter++; - $pk = new ModalFormRequestPacket(); - $pk->formId = $id; - $pk->formData = json_encode($form); - if($pk->formData === false){ - throw new \InvalidArgumentException("Failed to encode form JSON: " . json_last_error_msg()); - } - if($this->sendDataPacket($pk)){ + if($this->networkSession->onFormSent($id, $form)){ $this->forms[$id] = $form; } } @@ -2871,7 +2704,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->sendData($this); $this->sendData($this->getViewers()); - $this->sendSettings(); + $this->networkSession->syncAdventureSettings($this); $this->sendAllInventories(); $this->spawnToAll(); @@ -2925,24 +2758,18 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $result; } - public function sendPosition(Vector3 $pos, ?float $yaw = null, ?float $pitch = null, int $mode = MovePlayerPacket::MODE_NORMAL, ?array $targets = null){ - $yaw = $yaw ?? $this->yaw; - $pitch = $pitch ?? $this->pitch; - - $pk = new MovePlayerPacket(); - $pk->entityRuntimeId = $this->getId(); - $pk->position = $this->getOffsetPosition($pos); - $pk->pitch = $pitch; - $pk->headYaw = $yaw; - $pk->yaw = $yaw; - $pk->mode = $mode; - - if($targets !== null){ - $this->server->broadcastPacket($targets, $pk); - }else{ - $this->sendDataPacket($pk); - } + /** + * TODO: remove this + * + * @param Vector3 $pos + * @param float|null $yaw + * @param float|null $pitch + * @param int $mode + */ + public function sendPosition(Vector3 $pos, ?float $yaw = null, ?float $pitch = null, int $mode = MovePlayerPacket::MODE_NORMAL){ + $this->networkSession->syncMovement($pos, $yaw, $pitch, $mode); + //TODO: get rid of this $this->newPosition = null; } @@ -2955,7 +2782,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->removeAllWindows(); $this->sendPosition($this, $this->yaw, $this->pitch, MovePlayerPacket::MODE_TELEPORT); - $this->sendPosition($this, $this->yaw, $this->pitch, MovePlayerPacket::MODE_TELEPORT, $this->getViewers()); + $this->broadcastMovement(true); $this->spawnToAll(); diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index fccfd75bd6..97bec4f149 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -228,14 +228,14 @@ abstract class Living extends Entity implements Damageable{ $ev->call(); if($ev->isCancelled()){ if($hasExpired and !$ev->getEffect()->hasExpired()){ //altered duration of an expired effect to make it not get removed - $this->sendEffectAdd($ev->getEffect(), true); + $this->onEffectAdded($ev->getEffect(), true); } return; } unset($this->effects[$index]); $effect->getType()->remove($this, $effect); - $this->sendEffectRemove($effect); + $this->onEffectRemoved($effect); $this->recalculateEffectColor(); } @@ -310,7 +310,7 @@ abstract class Living extends Entity implements Damageable{ } $effect->getType()->add($this, $effect); - $this->sendEffectAdd($effect, $oldEffect !== null); + $this->onEffectAdded($effect, $oldEffect !== null); $this->effects[$index] = $effect; @@ -368,11 +368,11 @@ abstract class Living extends Entity implements Damageable{ } } - protected function sendEffectAdd(EffectInstance $effect, bool $replacesOldEffect) : void{ + protected function onEffectAdded(EffectInstance $effect, bool $replacesOldEffect) : void{ } - protected function sendEffectRemove(EffectInstance $effect) : void{ + protected function onEffectRemoved(EffectInstance $effect) : void{ } diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index c53037f5c6..6a975c43f0 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -23,9 +23,15 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; +use pocketmine\entity\effect\EffectInstance; +use pocketmine\entity\Living; use pocketmine\event\player\PlayerCreationEvent; use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\event\server\DataPacketSendEvent; +use pocketmine\form\Form; +use pocketmine\GameMode; +use pocketmine\level\Position; +use pocketmine\math\Vector3; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\DeathSessionHandler; use pocketmine\network\mcpe\handler\HandshakeSessionHandler; @@ -34,13 +40,29 @@ use pocketmine\network\mcpe\handler\PreSpawnSessionHandler; use pocketmine\network\mcpe\handler\ResourcePacksSessionHandler; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\handler\SimpleSessionHandler; +use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; +use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; +use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\DisconnectPacket; +use pocketmine\network\mcpe\protocol\MobEffectPacket; +use pocketmine\network\mcpe\protocol\ModalFormRequestPacket; +use pocketmine\network\mcpe\protocol\MovePlayerPacket; +use pocketmine\network\mcpe\protocol\NetworkChunkPublisherUpdatePacket; use pocketmine\network\mcpe\protocol\Packet; use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\network\mcpe\protocol\PlayStatusPacket; use pocketmine\network\mcpe\protocol\ServerboundPacket; use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket; +use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; +use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket; +use pocketmine\network\mcpe\protocol\TextPacket; +use pocketmine\network\mcpe\protocol\TransferPacket; +use pocketmine\network\mcpe\protocol\types\CommandData; +use pocketmine\network\mcpe\protocol\types\CommandEnum; +use pocketmine\network\mcpe\protocol\types\CommandParameter; +use pocketmine\network\mcpe\protocol\types\PlayerPermissions; +use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; use pocketmine\network\NetworkInterface; use pocketmine\network\NetworkSessionManager; use pocketmine\Player; @@ -49,10 +71,16 @@ use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\BinaryDataException; use function bin2hex; +use function count; use function get_class; +use function in_array; +use function json_encode; +use function json_last_error_msg; use function strlen; +use function strtolower; use function substr; use function time; +use function ucfirst; class NetworkSession{ /** @var Server */ @@ -391,6 +419,23 @@ class NetworkSession{ } } + /** + * Instructs the remote client to connect to a different server. + * + * @param string $ip + * @param int $port + * @param string $reason + * + * @throws \UnsupportedOperationException + */ + public function transfer(string $ip, int $port, string $reason = "transfer") : void{ + $pk = new TransferPacket(); + $pk->address = $ip; + $pk->port = $port; + $this->sendDataPacket($pk, true); + $this->disconnect($reason); + } + /** * Called by the Player when it is closed (for example due to getting kicked). * @@ -496,7 +541,7 @@ class NetworkSession{ } public function onSpawn() : void{ - $this->setHandler(new SimpleSessionHandler($this->player)); + $this->setHandler(new SimpleSessionHandler($this->player, $this)); } public function onDeath() : void{ @@ -504,7 +549,188 @@ class NetworkSession{ } public function onRespawn() : void{ - $this->setHandler(new SimpleSessionHandler($this->player)); + $this->setHandler(new SimpleSessionHandler($this->player, $this)); + } + + public function syncMovement(Vector3 $pos, ?float $yaw = null, ?float $pitch = null, int $mode = MovePlayerPacket::MODE_NORMAL) : void{ + $yaw = $yaw ?? $this->player->getYaw(); + $pitch = $pitch ?? $this->player->getPitch(); + + $pk = new MovePlayerPacket(); + $pk->entityRuntimeId = $this->player->getId(); + $pk->position = $this->player->getOffsetPosition($pos); + $pk->pitch = $pitch; + $pk->headYaw = $yaw; + $pk->yaw = $yaw; + $pk->mode = $mode; + + $this->sendDataPacket($pk); + } + + public function syncViewAreaRadius(int $distance) : void{ + $pk = new ChunkRadiusUpdatedPacket(); + $pk->radius = $distance; + $this->sendDataPacket($pk); + } + + public function syncViewAreaCenterPoint(Vector3 $newPos, int $viewDistance) : void{ + $pk = new NetworkChunkPublisherUpdatePacket(); + $pk->x = $newPos->getFloorX(); + $pk->y = $newPos->getFloorY(); + $pk->z = $newPos->getFloorZ(); + $pk->radius = $viewDistance * 16; //blocks, not chunks >.> + $this->sendDataPacket($pk); + } + + public function syncPlayerSpawnPoint(Position $newSpawn) : void{ + $pk = new SetSpawnPositionPacket(); + $pk->x = $newSpawn->getFloorX(); + $pk->y = $newSpawn->getFloorY(); + $pk->z = $newSpawn->getFloorZ(); + $pk->spawnType = SetSpawnPositionPacket::TYPE_PLAYER_SPAWN; + $pk->spawnForced = false; + $this->sendDataPacket($pk); + } + + public function syncGameMode(GameMode $mode) : void{ + $pk = new SetPlayerGameTypePacket(); + $pk->gamemode = self::getClientFriendlyGamemode($mode); + $this->sendDataPacket($pk); + } + + /** + * TODO: make this less specialized + * + * @param Player $for + */ + public function syncAdventureSettings(Player $for) : void{ + $pk = new AdventureSettingsPacket(); + + $pk->setFlag(AdventureSettingsPacket::WORLD_IMMUTABLE, $for->isSpectator()); + $pk->setFlag(AdventureSettingsPacket::NO_PVP, $for->isSpectator()); + $pk->setFlag(AdventureSettingsPacket::AUTO_JUMP, $for->hasAutoJump()); + $pk->setFlag(AdventureSettingsPacket::ALLOW_FLIGHT, $for->getAllowFlight()); + $pk->setFlag(AdventureSettingsPacket::NO_CLIP, $for->isSpectator()); + $pk->setFlag(AdventureSettingsPacket::FLYING, $for->isFlying()); + + //TODO: permission flags + + $pk->commandPermission = ($for->isOp() ? AdventureSettingsPacket::PERMISSION_OPERATOR : AdventureSettingsPacket::PERMISSION_NORMAL); + $pk->playerPermission = ($for->isOp() ? PlayerPermissions::OPERATOR : PlayerPermissions::MEMBER); + $pk->entityUniqueId = $for->getId(); + + $this->sendDataPacket($pk); + } + + public function syncAttributes(Living $entity, bool $sendAll = false){ + $entries = $sendAll ? $entity->getAttributeMap()->getAll() : $entity->getAttributeMap()->needSend(); + if(count($entries) > 0){ + $pk = new UpdateAttributesPacket(); + $pk->entityRuntimeId = $entity->getId(); + $pk->entries = $entries; + $this->sendDataPacket($pk); + foreach($entries as $entry){ + $entry->markSynchronized(); + } + } + } + + public function onEntityEffectAdded(Living $entity, EffectInstance $effect, bool $replacesOldEffect) : void{ + $pk = new MobEffectPacket(); + $pk->entityRuntimeId = $entity->getId(); + $pk->eventId = $replacesOldEffect ? MobEffectPacket::EVENT_MODIFY : MobEffectPacket::EVENT_ADD; + $pk->effectId = $effect->getId(); + $pk->amplifier = $effect->getAmplifier(); + $pk->particles = $effect->isVisible(); + $pk->duration = $effect->getDuration(); + + $this->sendDataPacket($pk); + } + + public function onEntityEffectRemoved(Living $entity, EffectInstance $effect) : void{ + $pk = new MobEffectPacket(); + $pk->entityRuntimeId = $entity->getId(); + $pk->eventId = MobEffectPacket::EVENT_REMOVE; + $pk->effectId = $effect->getId(); + + $this->sendDataPacket($pk); + } + + public function syncAvailableCommands() : void{ + $pk = new AvailableCommandsPacket(); + foreach($this->server->getCommandMap()->getCommands() as $name => $command){ + if(isset($pk->commandData[$command->getName()]) or $command->getName() === "help" or !$command->testPermissionSilent($this->player)){ + continue; + } + + $data = new CommandData(); + //TODO: commands containing uppercase letters in the name crash 1.9.0 client + $data->commandName = strtolower($command->getName()); + $data->commandDescription = $this->server->getLanguage()->translateString($command->getDescription()); + $data->flags = 0; + $data->permission = 0; + + $parameter = new CommandParameter(); + $parameter->paramName = "args"; + $parameter->paramType = AvailableCommandsPacket::ARG_FLAG_VALID | AvailableCommandsPacket::ARG_TYPE_RAWTEXT; + $parameter->isOptional = true; + $data->overloads[0][0] = $parameter; + + $aliases = $command->getAliases(); + if(!empty($aliases)){ + if(!in_array($data->commandName, $aliases, true)){ + //work around a client bug which makes the original name not show when aliases are used + $aliases[] = $data->commandName; + } + $data->aliases = new CommandEnum(); + $data->aliases->enumName = ucfirst($command->getName()) . "Aliases"; + $data->aliases->enumValues = $aliases; + } + + $pk->commandData[$command->getName()] = $data; + } + + $this->sendDataPacket($pk); + } + + public function onRawChatMessage(string $message) : void{ + $pk = new TextPacket(); + $pk->type = TextPacket::TYPE_RAW; + $pk->message = $message; + $this->sendDataPacket($pk); + } + + public function onTranslatedChatMessage(string $key, array $parameters) : void{ + $pk = new TextPacket(); + $pk->type = TextPacket::TYPE_TRANSLATION; + $pk->needsTranslation = true; + $pk->message = $key; + $pk->parameters = $parameters; + $this->sendDataPacket($pk); + } + + public function onPopup(string $message) : void{ + $pk = new TextPacket(); + $pk->type = TextPacket::TYPE_POPUP; + $pk->message = $message; + $this->sendDataPacket($pk); + } + + public function onTip(string $message) : void{ + $pk = new TextPacket(); + $pk->type = TextPacket::TYPE_TIP; + $pk->message = $message; + $this->sendDataPacket($pk); + } + + public function onFormSent(int $id, Form $form) : bool{ + $pk = new ModalFormRequestPacket(); + $pk->formId = $id; + $pk->formData = json_encode($form); + if($pk->formData === false){ + throw new \InvalidArgumentException("Failed to encode form JSON: " . json_last_error_msg()); + } + return $this->sendDataPacket($pk); } public function tick() : bool{ @@ -523,4 +749,21 @@ class NetworkSession{ return false; } + + /** + * Returns a client-friendly gamemode of the specified real gamemode + * This function takes care of handling gamemodes known to MCPE (as of 1.1.0.3, that includes Survival, Creative and Adventure) + * + * @internal + * @param GameMode $gamemode + * + * @return int + */ + public static function getClientFriendlyGamemode(GameMode $gamemode) : int{ + if($gamemode === GameMode::SPECTATOR()){ + return GameMode::CREATIVE()->getMagicNumber(); + } + + return $gamemode->getMagicNumber(); + } } diff --git a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php index bc75efd58f..7c1abf5fbd 100644 --- a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php @@ -57,13 +57,13 @@ class PreSpawnSessionHandler extends SessionHandler{ $pk = new StartGamePacket(); $pk->entityUniqueId = $this->player->getId(); $pk->entityRuntimeId = $this->player->getId(); - $pk->playerGamemode = Player::getClientFriendlyGamemode($this->player->getGamemode()); + $pk->playerGamemode = NetworkSession::getClientFriendlyGamemode($this->player->getGamemode()); $pk->playerPosition = $this->player->getOffsetPosition($this->player); $pk->pitch = $this->player->pitch; $pk->yaw = $this->player->yaw; $pk->seed = -1; $pk->dimension = DimensionIds::OVERWORLD; //TODO: implement this properly - $pk->worldGamemode = Player::getClientFriendlyGamemode($this->server->getGamemode()); + $pk->worldGamemode = NetworkSession::getClientFriendlyGamemode($this->server->getGamemode()); $pk->difficulty = $this->player->getLevel()->getDifficulty(); $pk->spawnX = $spawnPosition->getFloorX(); $pk->spawnY = $spawnPosition->getFloorY(); @@ -85,9 +85,9 @@ class PreSpawnSessionHandler extends SessionHandler{ $this->player->getLevel()->sendTime($this->player); - $this->player->sendAttributes(true); - $this->player->sendCommandData(); - $this->player->sendSettings(); + $this->session->syncAttributes($this->player, true); + $this->session->syncAvailableCommands(); + $this->session->syncAdventureSettings($this->player); $this->player->sendPotionEffects($this->player); $this->player->sendData($this->player); diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index 3be514f5b4..fc2ce94f42 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -35,6 +35,7 @@ use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\StringTag; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\NetworkNbtSerializer; +use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; @@ -96,6 +97,8 @@ class SimpleSessionHandler extends SessionHandler{ /** @var Player */ private $player; + /** @var NetworkSession */ + private $session; /** @var CraftingTransaction|null */ protected $craftingTransaction = null; @@ -105,8 +108,9 @@ class SimpleSessionHandler extends SessionHandler{ /** @var Vector3|null */ protected $lastRightClickPos = null; - public function __construct(Player $player){ + public function __construct(Player $player, NetworkSession $session){ $this->player = $player; + $this->session = $session; } public function handleText(TextPacket $packet) : bool{ @@ -470,8 +474,8 @@ class SimpleSessionHandler extends SessionHandler{ public function handleSetPlayerGameType(SetPlayerGameTypePacket $packet) : bool{ if($packet->gamemode !== $this->player->getGamemode()->getMagicNumber()){ //Set this back to default. TODO: handle this properly - $this->player->sendGamemode(); - $this->player->sendSettings(); + $this->session->syncGameMode($this->player->getGamemode()); + $this->session->syncAdventureSettings($this->player); } return true; } From 7d22b2a6d7d372a5020b9a2b44a93cdc821565c8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Apr 2019 18:43:14 +0100 Subject: [PATCH 0732/3224] Player: removed useless addActionBarMessage() this is exactly the same as sendTip(). --- src/pocketmine/Player.php | 9 --------- src/pocketmine/command/defaults/TitleCommand.php | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 92138677a2..4d115ec9a7 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2352,15 +2352,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->sendTitleText($subtitle, SetTitlePacket::TYPE_SET_SUBTITLE); } - /** - * Adds small text to the user's screen. - * - * @param string $message - */ - public function addActionBarMessage(string $message){ - $this->sendTitleText($message, SetTitlePacket::TYPE_SET_ACTIONBAR_MESSAGE); - } - /** * Removes the title from the client's screen. */ diff --git a/src/pocketmine/command/defaults/TitleCommand.php b/src/pocketmine/command/defaults/TitleCommand.php index 667eeee082..6a49ec5442 100644 --- a/src/pocketmine/command/defaults/TitleCommand.php +++ b/src/pocketmine/command/defaults/TitleCommand.php @@ -82,7 +82,7 @@ class TitleCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $player->addActionBarMessage(implode(" ", array_slice($args, 2))); + $player->sendTip(implode(" ", array_slice($args, 2))); break; case "times": if(count($args) < 5){ From b6e453a5f43832b47e6c170954c0c9325bd4e421 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Apr 2019 19:13:41 +0100 Subject: [PATCH 0733/3224] LegacyAnvilChunkTrait: remove obsolete TODO --- src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php b/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php index 978c8a69a1..6f0df55b72 100644 --- a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php @@ -40,8 +40,6 @@ use pocketmine\nbt\tag\ListTag; * of handling worlds in the PC 1.13 format. Thus, we don't want PMAnvil getting accidentally influenced by changes * happening to the underlying Anvil, because it only uses the legacy part. * - * TODO: When the formats are deprecated, the write parts of this trait can be eliminated. - * * @internal */ trait LegacyAnvilChunkTrait{ From 80a6fc5dd12588b34c106fbcb2b8e517945c5c5f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Apr 2019 19:15:29 +0100 Subject: [PATCH 0734/3224] BlockFactory: remove deprecated functions --- src/pocketmine/block/BlockFactory.php | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index fbef665a02..691e11a2c1 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -32,7 +32,6 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\ItemIds; use pocketmine\level\Position; -use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; use pocketmine\tile\Comparator; use function array_fill; use function array_filter; @@ -669,31 +668,6 @@ class BlockFactory{ return $b !== null and !($b instanceof UnknownBlock); } - /** - * @internal - * @deprecated - * - * @param int $id - * @param int $meta - * - * @return int - */ - public static function toStaticRuntimeId(int $id, int $meta = 0) : int{ - return RuntimeBlockMapping::toStaticRuntimeId($id, $meta); - } - - /** - * @deprecated - * @internal - * - * @param int $runtimeId - * - * @return int[] [id, meta] - */ - public static function fromStaticRuntimeId(int $runtimeId) : array{ - return RuntimeBlockMapping::fromStaticRuntimeId($runtimeId); - } - /** * @return Block[] */ From f332550e52d3b7241b4085a7a582b3fe0c574151 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Apr 2019 19:49:53 +0100 Subject: [PATCH 0735/3224] Player: move toggle* rollback handling to network session this allows network sessions to react to it how they want, or (in the case of things like Specter) perhaps ignore it. --- src/pocketmine/Player.php | 31 +++++++++---------- .../mcpe/handler/SimpleSessionHandler.php | 20 +++++++++--- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 4d115ec9a7..f37d4f0744 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2145,38 +2145,37 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return false; } - public function toggleSprint(bool $sprint) : void{ + public function toggleSprint(bool $sprint) : bool{ $ev = new PlayerToggleSprintEvent($this, $sprint); $ev->call(); if($ev->isCancelled()){ - $this->sendData($this); - }else{ - $this->setSprinting($sprint); + return false; } + $this->setSprinting($sprint); + return true; } - public function toggleSneak(bool $sneak) : void{ + public function toggleSneak(bool $sneak) : bool{ $ev = new PlayerToggleSneakEvent($this, $sneak); $ev->call(); if($ev->isCancelled()){ - $this->sendData($this); - }else{ - $this->setSneaking($sneak); + return false; } + $this->setSneaking($sneak); + return true; } - public function toggleFlight(bool $fly) : void{ + public function toggleFlight(bool $fly) : bool{ $ev = new PlayerToggleFlightEvent($this, $fly); - if(!$this->allowFlight){ - $ev->setCancelled(); - } + $ev->setCancelled(!$this->allowFlight); $ev->call(); if($ev->isCancelled()){ - $this->networkSession->syncAdventureSettings($this); - }else{ //don't use setFlying() here, to avoid feedback loops - $this->flying = $fly; - $this->resetFallDistance(); + return false; } + //don't use setFlying() here, to avoid feedback loops - TODO: get rid of this hack + $this->flying = $fly; + $this->resetFallDistance(); + return true; } public function animate(int $action) : bool{ diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index fc2ce94f42..b9677d6586 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -362,16 +362,24 @@ class SimpleSessionHandler extends SessionHandler{ $this->player->jump(); return true; case PlayerActionPacket::ACTION_START_SPRINT: - $this->player->toggleSprint(true); + if(!$this->player->toggleSprint(true)){ + $this->player->sendData($this->player); + } return true; case PlayerActionPacket::ACTION_STOP_SPRINT: - $this->player->toggleSprint(false); + if(!$this->player->toggleSprint(false)){ + $this->player->sendData($this->player); + } return true; case PlayerActionPacket::ACTION_START_SNEAK: - $this->player->toggleSneak(true); + if(!$this->player->toggleSneak(true)){ + $this->player->sendData($this->player); + } return true; case PlayerActionPacket::ACTION_STOP_SNEAK: - $this->player->toggleSneak(false); + if(!$this->player->toggleSneak(false)){ + $this->player->sendData($this->player); + } return true; case PlayerActionPacket::ACTION_START_GLIDE: case PlayerActionPacket::ACTION_STOP_GLIDE: @@ -423,7 +431,9 @@ class SimpleSessionHandler extends SessionHandler{ $isFlying = $packet->getFlag(AdventureSettingsPacket::FLYING); if($isFlying !== $this->player->isFlying()){ - $this->player->toggleFlight($isFlying); + if(!$this->player->toggleFlight($isFlying)){ + $this->session->syncAdventureSettings($this->player); + } $handled = true; } From f901c2a6127103bfa60cb9d0b36a05065ebaf392 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Apr 2019 19:57:10 +0100 Subject: [PATCH 0736/3224] Player: move some functions to a more sensible place let's keep disconnect-related logic grouped together. --- src/pocketmine/Player.php | 104 +++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index f37d4f0744..bc03a58637 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2273,58 +2273,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->sendDataPacket($packet, false); } - /** - * Transfers a player to another server. - * - * @param string $address The IP address or hostname of the destination server - * @param int $port The destination port, defaults to 19132 - * @param string $message Message to show in the console when closing the player - * - * @return bool if transfer was successful. - */ - public function transfer(string $address, int $port = 19132, string $message = "transfer") : bool{ - $ev = new PlayerTransferEvent($this, $address, $port, $message); - $ev->call(); - if(!$ev->isCancelled()){ - $this->networkSession->transfer($ev->getAddress(), $ev->getPort(), $ev->getMessage()); - return true; - } - - return false; - } - - /** - * Kicks a player from the server - * - * @param string $reason - * @param bool $isAdmin - * @param TextContainer|string $quitMessage - * - * @return bool - */ - public function kick(string $reason = "", bool $isAdmin = true, $quitMessage = null) : bool{ - $ev = new PlayerKickEvent($this, $reason, $quitMessage ?? $this->getLeaveMessage()); - $ev->call(); - if(!$ev->isCancelled()){ - $reason = $ev->getReason(); - $message = $reason; - if($isAdmin){ - if(!$this->isBanned()){ - $message = "Kicked by admin." . ($reason !== "" ? " Reason: " . $reason : ""); - } - }else{ - if($reason === ""){ - $message = "disconnectionScreen.noReason"; - } - } - $this->close($ev->getQuitMessage(), $message); - - return true; - } - - return false; - } - /** * Adds a title text to the user's screen, with an optional subtitle. * @@ -2486,6 +2434,58 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return true; } + /** + * Transfers a player to another server. + * + * @param string $address The IP address or hostname of the destination server + * @param int $port The destination port, defaults to 19132 + * @param string $message Message to show in the console when closing the player + * + * @return bool if transfer was successful. + */ + public function transfer(string $address, int $port = 19132, string $message = "transfer") : bool{ + $ev = new PlayerTransferEvent($this, $address, $port, $message); + $ev->call(); + if(!$ev->isCancelled()){ + $this->networkSession->transfer($ev->getAddress(), $ev->getPort(), $ev->getMessage()); + return true; + } + + return false; + } + + /** + * Kicks a player from the server + * + * @param string $reason + * @param bool $isAdmin + * @param TextContainer|string $quitMessage + * + * @return bool + */ + public function kick(string $reason = "", bool $isAdmin = true, $quitMessage = null) : bool{ + $ev = new PlayerKickEvent($this, $reason, $quitMessage ?? $this->getLeaveMessage()); + $ev->call(); + if(!$ev->isCancelled()){ + $reason = $ev->getReason(); + $message = $reason; + if($isAdmin){ + if(!$this->isBanned()){ + $message = "Kicked by admin." . ($reason !== "" ? " Reason: " . $reason : ""); + } + }else{ + if($reason === ""){ + $message = "disconnectionScreen.noReason"; + } + } + $this->close($ev->getQuitMessage(), $message); + + return true; + } + + return false; + } + /** * Note for plugin developers: use kick() with the isAdmin * flag set to kick without the "Kicked by admin" part instead of this method. From 0e3e984db98191c54fb8e1da4f76d37f73f62a03 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 3 Apr 2019 17:44:34 +0100 Subject: [PATCH 0737/3224] Player: Disconnects no longer nuke player internals, (mostly) fixes #1239 there are some problems that haven't been accounted for yet, but this fixes all the direct crashes. --- src/pocketmine/Player.php | 145 ++++++++++-------- src/pocketmine/level/LevelManager.php | 2 +- .../network/mcpe/NetworkSession.php | 45 ++++-- 3 files changed, 107 insertions(+), 85 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 2b55d434dc..b1afebec12 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -339,8 +339,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $ev = new PlayerLoginEvent($this, "Plugin reason"); $ev->call(); - if($ev->isCancelled()){ - $this->close($this->getLeaveMessage(), $ev->getKickMessage()); + if($ev->isCancelled() or !$this->isConnected()){ + $this->disconnect($ev->getKickMessage()); return; } @@ -758,7 +758,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool */ public function isConnected() : bool{ - return $this->networkSession !== null; + return $this->networkSession !== null and $this->networkSession->isConnected(); } /** @@ -2479,7 +2479,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $message = "disconnectionScreen.noReason"; } } - $this->close($ev->getQuitMessage(), $message); + $this->disconnect($message, $ev->getQuitMessage()); return true; } @@ -2488,81 +2488,92 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } /** - * Note for plugin developers: use kick() with the isAdmin - * flag set to kick without the "Kicked by admin" part instead of this method. + * Removes the player from the server. This cannot be cancelled. + * This is used for remote disconnects and for uninterruptible disconnects (for example, when the server shuts down). * - * @param TextContainer|string $message Message to be broadcasted - * @param string $reason Reason showed in console + * Note for plugin developers: Prefer kick() with the isAdmin flag set to kick without the "Kicked by admin" part + * instead of this method. This way other plugins can have a say in whether the player is removed or not. + * + * @param string $reason Shown to the player, usually this will appear on their disconnect screen. + * @param TextContainer|string $quitMessage Message to broadcast to online players (null will use default) * @param bool $notify */ - final public function close($message = "", string $reason = "generic reason", bool $notify = true) : void{ - if($this->isConnected() and !$this->closed){ - $ip = $this->networkSession->getIp(); - $port = $this->networkSession->getPort(); - $this->networkSession->onPlayerDestroyed($reason, $notify); + public function disconnect(string $reason, $quitMessage = null, bool $notify = true) : void{ + if(!$this->isConnected()){ + return; + } + + $this->networkSession->onPlayerDestroyed($reason, $notify); + + //prevent the player receiving their own disconnect message + PermissionManager::getInstance()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this); + PermissionManager::getInstance()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this); + + $ev = new PlayerQuitEvent($this, $quitMessage ?? $this->getLeaveMessage(), $reason); + $ev->call(); + if(!empty($ev->getQuitMessage())){ + $this->server->broadcastMessage($ev->getQuitMessage()); + } + $this->save(); + + $this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logOut", [ + TextFormat::AQUA . $this->getName() . TextFormat::WHITE, + $this->networkSession->getIp(), + $this->networkSession->getPort(), + $this->getServer()->getLanguage()->translateString($reason) + ])); + + $this->spawned = false; + + $this->stopSleep(); + $this->despawnFromAll(); + + $this->server->removeOnlinePlayer($this); + + foreach($this->server->getOnlinePlayers() as $player){ + if(!$player->canSee($this)){ + $player->showPlayer($this); + } + } + $this->hiddenPlayers = []; + + if($this->isValid()){ + foreach($this->usedChunks as $index => $d){ + Level::getXZ($index, $chunkX, $chunkZ); + $this->level->unregisterChunkLoader($this, $chunkX, $chunkZ); + $this->level->unregisterChunkListener($this, $chunkX, $chunkZ); + foreach($this->level->getChunkEntities($chunkX, $chunkZ) as $entity){ + $entity->despawnFrom($this); + } + unset($this->usedChunks[$index]); + } + } + $this->usedChunks = []; + $this->loadQueue = []; + + $this->removeAllWindows(true); + $this->windows = []; + $this->windowIndex = []; + + $this->perm->clearPermissions(); + + $this->flagForDespawn(); + } + + final public function close() : void{ + if(!$this->closed){ + $this->disconnect("Player destroyed"); $this->networkSession = null; - PermissionManager::getInstance()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this); - PermissionManager::getInstance()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this); - - $this->stopSleep(); - - if($this->spawned){ - $ev = new PlayerQuitEvent($this, $message, $reason); - $ev->call(); - if($ev->getQuitMessage() != ""){ - $this->server->broadcastMessage($ev->getQuitMessage()); - } - - $this->save(); - } - - if($this->isValid()){ - foreach($this->usedChunks as $index => $d){ - Level::getXZ($index, $chunkX, $chunkZ); - $this->level->unregisterChunkLoader($this, $chunkX, $chunkZ); - $this->level->unregisterChunkListener($this, $chunkX, $chunkZ); - foreach($this->level->getChunkEntities($chunkX, $chunkZ) as $entity){ - $entity->despawnFrom($this); - } - unset($this->usedChunks[$index]); - } - } - $this->usedChunks = []; - $this->loadQueue = []; - - foreach($this->server->getOnlinePlayers() as $player){ - if(!$player->canSee($this)){ - $player->showPlayer($this); - } - } - $this->hiddenPlayers = []; - - $this->removeAllWindows(true); - $this->windows = []; - $this->windowIndex = []; $this->cursorInventory = null; $this->craftingGrid = null; - parent::close(); - $this->spawned = false; - $this->server->removeOnlinePlayer($this); - - $this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logOut", [ - TextFormat::AQUA . $this->getName() . TextFormat::WHITE, - $ip, - $port, - $this->getServer()->getLanguage()->translateString($reason) - ])); - $this->spawnPosition = null; + $this->perm = null; - if($this->perm !== null){ - $this->perm->clearPermissions(); - $this->perm = null; - } + parent::close(); } } diff --git a/src/pocketmine/level/LevelManager.php b/src/pocketmine/level/LevelManager.php index b6d8e9cbd4..bae08a0e17 100644 --- a/src/pocketmine/level/LevelManager.php +++ b/src/pocketmine/level/LevelManager.php @@ -167,7 +167,7 @@ class LevelManager{ $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.level.unloading", [$level->getDisplayName()])); foreach($level->getPlayers() as $player){ if($level === $this->levelDefault or $this->levelDefault === null){ - $player->close($player->getLeaveMessage(), "Forced default world unload"); + $player->disconnect("Forced default world unload"); }elseif($this->levelDefault instanceof Level){ $player->teleport($this->levelDefault->getSafeSpawn()); } diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 6a975c43f0..838e4cc6ba 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -106,6 +106,8 @@ class NetworkSession{ /** @var bool */ private $connected = true; /** @var bool */ + private $disconnectGuard = false; + /** @var bool */ private $loggedIn = false; /** @var bool */ private $authenticated = false; @@ -395,13 +397,14 @@ class NetworkSession{ $this->interface->putPacket($this, $payload, $immediate); } - private function checkDisconnect() : bool{ - if($this->connected){ + private function tryDisconnect(\Closure $func) : void{ + if($this->connected and !$this->disconnectGuard){ + $this->disconnectGuard = true; + $func(); + $this->disconnectGuard = false; $this->connected = false; $this->manager->remove($this); - return true; } - return false; } /** @@ -411,12 +414,12 @@ class NetworkSession{ * @param bool $notify */ public function disconnect(string $reason, bool $notify = true) : void{ - if($this->checkDisconnect()){ + $this->tryDisconnect(function() use($reason, $notify){ if($this->player !== null){ - $this->player->close($this->player->getLeaveMessage(), $reason); + $this->player->disconnect($reason, null, $notify); } $this->doServerDisconnect($reason, $notify); - } + }); } /** @@ -429,11 +432,17 @@ class NetworkSession{ * @throws \UnsupportedOperationException */ public function transfer(string $ip, int $port, string $reason = "transfer") : void{ - $pk = new TransferPacket(); - $pk->address = $ip; - $pk->port = $port; - $this->sendDataPacket($pk, true); - $this->disconnect($reason); + $this->tryDisconnect(function() use($ip, $port, $reason){ + $pk = new TransferPacket(); + $pk->address = $ip; + $pk->port = $port; + $this->sendDataPacket($pk, true); + $this->disconnect($reason, false); + if($this->player !== null){ + $this->player->disconnect($reason, null, false); + } + $this->doServerDisconnect($reason, false); + }); } /** @@ -443,9 +452,9 @@ class NetworkSession{ * @param bool $notify */ public function onPlayerDestroyed(string $reason, bool $notify = true) : void{ - if($this->checkDisconnect()){ + $this->tryDisconnect(function() use($reason, $notify){ $this->doServerDisconnect($reason, $notify); - } + }); } /** @@ -472,9 +481,11 @@ class NetworkSession{ * @param string $reason */ public function onClientDisconnect(string $reason) : void{ - if($this->checkDisconnect() and $this->player !== null){ - $this->player->close($this->player->getLeaveMessage(), $reason); - } + $this->tryDisconnect(function() use($reason){ + if($this->player !== null){ + $this->player->disconnect($reason, null, false); + } + }); } public function setAuthenticationStatus(bool $authenticated, bool $authRequired, ?string $error) : bool{ From e6a1f0eb8de11dc0046308525a8332e5026dbfde Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 3 Apr 2019 18:06:22 +0100 Subject: [PATCH 0738/3224] Command: remove duplicated code --- src/pocketmine/command/Command.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pocketmine/command/Command.php b/src/pocketmine/command/Command.php index 9874efa02d..6d7628b63f 100644 --- a/src/pocketmine/command/Command.php +++ b/src/pocketmine/command/Command.php @@ -294,11 +294,11 @@ abstract class Command{ * @param bool $sendToSource */ public static function broadcastCommandMessage(CommandSender $source, $message, bool $sendToSource = true) : void{ + $users = PermissionManager::getInstance()->getPermissionSubscriptions(Server::BROADCAST_CHANNEL_ADMINISTRATIVE); if($message instanceof TextContainer){ $m = clone $message; $result = "[" . $source->getName() . ": " . ($source->getServer()->getLanguage()->get($m->getText()) !== $m->getText() ? "%" : "") . $m->getText() . "]"; - $users = PermissionManager::getInstance()->getPermissionSubscriptions(Server::BROADCAST_CHANNEL_ADMINISTRATIVE); $colored = TextFormat::GRAY . TextFormat::ITALIC . $result; $m->setText($result); @@ -306,7 +306,6 @@ abstract class Command{ $m->setText($colored); $colored = clone $m; }else{ - $users = PermissionManager::getInstance()->getPermissionSubscriptions(Server::BROADCAST_CHANNEL_ADMINISTRATIVE); $result = new TranslationContainer("chat.type.admin", [$source->getName(), $message]); $colored = new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . "%chat.type.admin", [$source->getName(), $message]); } From 5a989d82bba44a5f045b95be5a79cc2ddfcaf05e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Apr 2019 16:43:04 +0100 Subject: [PATCH 0739/3224] Generator: remove useless function getName() --- src/pocketmine/level/generator/Flat.php | 4 ---- src/pocketmine/level/generator/Generator.php | 2 -- src/pocketmine/level/generator/hell/Nether.php | 4 ---- src/pocketmine/level/generator/normal/Normal.php | 4 ---- 4 files changed, 14 deletions(-) diff --git a/src/pocketmine/level/generator/Flat.php b/src/pocketmine/level/generator/Flat.php index 33ec839958..2ca909db61 100644 --- a/src/pocketmine/level/generator/Flat.php +++ b/src/pocketmine/level/generator/Flat.php @@ -52,10 +52,6 @@ class Flat extends Generator{ /** @var string */ private $preset; - public function getName() : string{ - return "flat"; - } - /** * @param ChunkManager $level * @param int $seed diff --git a/src/pocketmine/level/generator/Generator.php b/src/pocketmine/level/generator/Generator.php index 4143c98f06..89767c9ae2 100644 --- a/src/pocketmine/level/generator/Generator.php +++ b/src/pocketmine/level/generator/Generator.php @@ -85,7 +85,5 @@ abstract class Generator{ return $this->options; } - abstract public function getName() : string; - abstract public function getSpawn() : Vector3; } diff --git a/src/pocketmine/level/generator/hell/Nether.php b/src/pocketmine/level/generator/hell/Nether.php index e00dfd59d3..c73931d748 100644 --- a/src/pocketmine/level/generator/hell/Nether.php +++ b/src/pocketmine/level/generator/hell/Nether.php @@ -79,10 +79,6 @@ class Nether extends Generator{ $this->populators[] = $ores;*/ } - public function getName() : string{ - return "nether"; - } - public function generateChunk(int $chunkX, int $chunkZ) : void{ $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed); diff --git a/src/pocketmine/level/generator/normal/Normal.php b/src/pocketmine/level/generator/normal/Normal.php index 24f0eff246..b5a2307a6d 100644 --- a/src/pocketmine/level/generator/normal/Normal.php +++ b/src/pocketmine/level/generator/normal/Normal.php @@ -150,10 +150,6 @@ class Normal extends Generator{ } } - public function getName() : string{ - return "normal"; - } - private function pickBiome(int $x, int $z) : Biome{ $hash = $x * 2345803 ^ $z * 9236449 ^ $this->seed; $hash *= $hash + 223; From 86a5a50330c5555e71aba73e5192a29f979de465 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Apr 2019 17:53:25 +0100 Subject: [PATCH 0740/3224] Generator: remove more useless functions these are red herrings for plugin developers since they are not used. --- src/pocketmine/level/generator/Flat.php | 5 ----- src/pocketmine/level/generator/Generator.php | 7 ------- src/pocketmine/level/generator/hell/Nether.php | 5 ----- src/pocketmine/level/generator/normal/Normal.php | 5 ----- 4 files changed, 22 deletions(-) diff --git a/src/pocketmine/level/generator/Flat.php b/src/pocketmine/level/generator/Flat.php index 2ca909db61..1b41e60932 100644 --- a/src/pocketmine/level/generator/Flat.php +++ b/src/pocketmine/level/generator/Flat.php @@ -31,7 +31,6 @@ use pocketmine\level\format\Chunk; use pocketmine\level\generator\object\OreType; use pocketmine\level\generator\populator\Ore; use pocketmine\level\generator\populator\Populator; -use pocketmine\math\Vector3; use function array_map; use function count; use function explode; @@ -185,8 +184,4 @@ class Flat extends Generator{ } } - - public function getSpawn() : Vector3{ - return new Vector3(128, $this->floorLevel, 128); - } } diff --git a/src/pocketmine/level/generator/Generator.php b/src/pocketmine/level/generator/Generator.php index 89767c9ae2..8357a8e6f4 100644 --- a/src/pocketmine/level/generator/Generator.php +++ b/src/pocketmine/level/generator/Generator.php @@ -27,7 +27,6 @@ declare(strict_types=1); namespace pocketmine\level\generator; use pocketmine\level\ChunkManager; -use pocketmine\math\Vector3; use pocketmine\utils\Random; use pocketmine\utils\Utils; use function ctype_digit; @@ -80,10 +79,4 @@ abstract class Generator{ abstract public function generateChunk(int $chunkX, int $chunkZ) : void; abstract public function populateChunk(int $chunkX, int $chunkZ) : void; - - public function getSettings() : array{ - return $this->options; - } - - abstract public function getSpawn() : Vector3; } diff --git a/src/pocketmine/level/generator/hell/Nether.php b/src/pocketmine/level/generator/hell/Nether.php index c73931d748..bb89cfedb9 100644 --- a/src/pocketmine/level/generator/hell/Nether.php +++ b/src/pocketmine/level/generator/hell/Nether.php @@ -31,7 +31,6 @@ use pocketmine\level\generator\Generator; use pocketmine\level\generator\InvalidGeneratorOptionsException; use pocketmine\level\generator\noise\Simplex; use pocketmine\level\generator\populator\Populator; -use pocketmine\math\Vector3; use function abs; class Nether extends Generator{ @@ -128,8 +127,4 @@ class Nether extends Generator{ $biome = Biome::getBiome($chunk->getBiomeId(7, 7)); $biome->populateChunk($this->level, $chunkX, $chunkZ, $this->random); } - - public function getSpawn() : Vector3{ - return new Vector3(127.5, 128, 127.5); - } } diff --git a/src/pocketmine/level/generator/normal/Normal.php b/src/pocketmine/level/generator/normal/Normal.php index b5a2307a6d..c6141d36a0 100644 --- a/src/pocketmine/level/generator/normal/Normal.php +++ b/src/pocketmine/level/generator/normal/Normal.php @@ -36,7 +36,6 @@ use pocketmine\level\generator\populator\GroundCover; use pocketmine\level\generator\populator\Ore; use pocketmine\level\generator\populator\Populator; use pocketmine\level\Level; -use pocketmine\math\Vector3; use function exp; class Normal extends Generator{ @@ -246,8 +245,4 @@ class Normal extends Generator{ $biome = Biome::getBiome($chunk->getBiomeId(7, 7)); $biome->populateChunk($this->level, $chunkX, $chunkZ, $this->random); } - - public function getSpawn() : Vector3{ - return new Vector3(127.5, 128, 127.5); - } } From 342b48b758ef56a37f1119c8eb97360b59a0bb6f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 12 Apr 2019 18:32:15 +0100 Subject: [PATCH 0741/3224] VersionString: Use the correct bitwise operators --- src/pocketmine/utils/VersionString.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/utils/VersionString.php b/src/pocketmine/utils/VersionString.php index dd01356d0d..e9a5f3c60b 100644 --- a/src/pocketmine/utils/VersionString.php +++ b/src/pocketmine/utils/VersionString.php @@ -70,7 +70,7 @@ class VersionString{ } public function getNumber() : int{ - return (($this->major << 9) + ($this->minor << 5) + $this->patch); + return (($this->major << 9) | ($this->minor << 5) | $this->patch); } public function getBaseVersion() : string{ From bf2851f324bdc1a8ee54c033b93bd6d956ecfc31 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 12 Apr 2019 19:45:41 +0100 Subject: [PATCH 0742/3224] Move API checking to its own class so it can be unit-tested --- src/pocketmine/plugin/ApiVersion.php | 65 +++++++++++++++++++++++++ src/pocketmine/plugin/PluginManager.php | 2 +- tests/phpunit/plugin/ApiVersionTest.php | 55 +++++++++++++++++++++ 3 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 src/pocketmine/plugin/ApiVersion.php create mode 100644 tests/phpunit/plugin/ApiVersionTest.php diff --git a/src/pocketmine/plugin/ApiVersion.php b/src/pocketmine/plugin/ApiVersion.php new file mode 100644 index 0000000000..2dc83dc8be --- /dev/null +++ b/src/pocketmine/plugin/ApiVersion.php @@ -0,0 +1,65 @@ +getBaseVersion() !== $myVersion->getBaseVersion()){ + if($version->getMajor() !== $myVersion->getMajor() or $version->getSuffix() !== $myVersion->getSuffix()){ + continue; + } + + if($version->getMinor() > $myVersion->getMinor()){ //If the plugin requires new API features, being backwards compatible + continue; + } + + if($version->getMinor() === $myVersion->getMinor() and $version->getPatch() > $myVersion->getPatch()){ //If the plugin requires bug fixes in patches, being backwards compatible + continue; + } + } + + return true; + } + + return false; + } +} diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index 6bf0564009..4d48bbe267 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -251,7 +251,7 @@ class PluginManager{ continue; } - if(!$this->isCompatibleApi(...$description->getCompatibleApis())){ + if(!ApiVersion::isCompatible($this->server->getApiVersion(), $description->getCompatibleApis())){ $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.loadError", [ $name, $this->server->getLanguage()->translateString("%pocketmine.plugin.incompatibleAPI", [implode(", ", $description->getCompatibleApis())]) diff --git a/tests/phpunit/plugin/ApiVersionTest.php b/tests/phpunit/plugin/ApiVersionTest.php new file mode 100644 index 0000000000..7c347a339c --- /dev/null +++ b/tests/phpunit/plugin/ApiVersionTest.php @@ -0,0 +1,55 @@ + Date: Fri, 12 Apr 2019 19:51:43 +0100 Subject: [PATCH 0743/3224] Refuse to load plugins with ambiguous minAPI versions closes #2381 --- resources/locale | 2 +- src/pocketmine/plugin/ApiVersion.php | 38 +++++++++++++++++++++++++ src/pocketmine/plugin/PluginManager.php | 8 ++++++ tests/phpunit/plugin/ApiVersionTest.php | 23 +++++++++++++++ 4 files changed, 70 insertions(+), 1 deletion(-) diff --git a/resources/locale b/resources/locale index 15a2b7d4f0..64844b7b6b 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 15a2b7d4f05959376e3ef6d71e793b7bbdb2b60e +Subproject commit 64844b7b6b94a866367831f998281801a86f07a1 diff --git a/src/pocketmine/plugin/ApiVersion.php b/src/pocketmine/plugin/ApiVersion.php index 2dc83dc8be..e935fa0fbb 100644 --- a/src/pocketmine/plugin/ApiVersion.php +++ b/src/pocketmine/plugin/ApiVersion.php @@ -24,6 +24,10 @@ declare(strict_types=1); namespace pocketmine\plugin; use pocketmine\utils\VersionString; +use function array_map; +use function array_push; +use function count; +use function usort; final class ApiVersion{ @@ -62,4 +66,38 @@ final class ApiVersion{ return false; } + + /** + * @param string[] $versions + * + * @return string[] + */ + public static function checkAmbiguousVersions(array $versions) : array{ + /** @var VersionString[][] $indexedVersions */ + $indexedVersions = []; + + foreach($versions as $str){ + $v = new VersionString($str); + if($v->getSuffix() !== ""){ //suffix is always unambiguous + continue; + } + if(!isset($indexedVersions[$v->getMajor()])){ + $indexedVersions[$v->getMajor()] = [$v]; + }else{ + $indexedVersions[$v->getMajor()][] = $v; + } + } + + /** @var VersionString[] $result */ + $result = []; + foreach($indexedVersions as $major => $list){ + if(count($list) > 1){ + array_push($result, ...$list); + } + } + + usort($result, static function(VersionString $string1, VersionString $string2){ return $string1->compare($string2); }); + + return array_map(static function(VersionString $string){ return $string->getBaseVersion(); }, $result); + } } diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index 4d48bbe267..36d63f4773 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -258,6 +258,14 @@ class PluginManager{ ])); continue; } + $ambiguousVersions = ApiVersion::checkAmbiguousVersions($description->getCompatibleApis()); + if(!empty($ambiguousVersions)){ + $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.loadError", [ + $name, + $this->server->getLanguage()->translateString("pocketmine.plugin.ambiguousMinAPI", [implode(", ", $ambiguousVersions)]) + ])); + continue; + } if(count($pluginMcpeProtocols = $description->getCompatibleMcpeProtocols()) > 0){ $serverMcpeProtocols = [ProtocolInfo::CURRENT_PROTOCOL]; diff --git a/tests/phpunit/plugin/ApiVersionTest.php b/tests/phpunit/plugin/ApiVersionTest.php index 7c347a339c..236b5b2c95 100644 --- a/tests/phpunit/plugin/ApiVersionTest.php +++ b/tests/phpunit/plugin/ApiVersionTest.php @@ -52,4 +52,27 @@ class ApiVersionTest extends TestCase{ public function testCompatibleApi(string $myVersion, string $wantVersion, bool $expected) : void{ self::assertSame($expected, ApiVersion::isCompatible($myVersion, [$wantVersion]), "my version: $myVersion, their version: $wantVersion, expect " . ($expected ? "yes" : "no")); } + + public function ambiguousVersionsProvider() : \Generator{ + yield [["3.0.0"], []]; + yield [["3.0.0", "3.0.1"], ["3.0.0", "3.0.1"]]; + yield [["3.0.0", "3.1.0", "4.0.0"], ["3.0.0", "3.1.0"]]; + yield [["3.0.0", "4.0.0"], []]; + yield [["3.0.0-ALPHA1", "3.0.0-ALPHA2"], []]; + } + + /** + * @dataProvider ambiguousVersionsProvider + * + * @param string[] $input + * @param string[] $expectedOutput + */ + public function testFindAmbiguousVersions(array $input, array $expectedOutput) : void{ + $ambiguous = ApiVersion::checkAmbiguousVersions($input); + + sort($expectedOutput); + sort($ambiguous); + + self::assertSame($expectedOutput, $ambiguous); + } } From 8a1c362db7eaef3bf77c926863afb7cced1a18e1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 13 Apr 2019 14:31:58 +0100 Subject: [PATCH 0744/3224] Server: remove dead function getDefaultGamemode() this was functionally identical to getGamemode() and is now just a red herring. --- src/pocketmine/Server.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index e12ebdc229..d042f4b1f9 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -457,13 +457,6 @@ class Server{ return $this->getConfigBool("hardcore", false); } - /** - * @return int - */ - public function getDefaultGamemode() : int{ - return $this->getConfigInt("gamemode", 0) & 0b11; - } - /** * @return string */ From 9b0b8b9a0c70415a2586105d6f22924a139dcc88 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 14 Apr 2019 17:11:56 +0100 Subject: [PATCH 0745/3224] Sync NBT dependency --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index af042e1f6c..543fce4e30 100644 --- a/composer.lock +++ b/composer.lock @@ -372,12 +372,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "d2a9d578e3d677f5a007b16881e3390f1bad8fb9" + "reference": "38485dbfa94a80b8c5439457307a70ee0703d579" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/d2a9d578e3d677f5a007b16881e3390f1bad8fb9", - "reference": "d2a9d578e3d677f5a007b16881e3390f1bad8fb9", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/38485dbfa94a80b8c5439457307a70ee0703d579", + "reference": "38485dbfa94a80b8c5439457307a70ee0703d579", "shasum": "" }, "require": { @@ -405,7 +405,7 @@ "source": "https://github.com/pmmp/NBT/tree/master", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2019-03-30T19:51:58+00:00" + "time": "2019-04-13T14:34:37+00:00" }, { "name": "pocketmine/raklib", From cfd4580388cfd4952cd215970024dbcda91b4290 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 14 Apr 2019 17:14:44 +0100 Subject: [PATCH 0746/3224] sync NBT network string length cap --- src/pocketmine/network/mcpe/NetworkNbtSerializer.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/network/mcpe/NetworkNbtSerializer.php b/src/pocketmine/network/mcpe/NetworkNbtSerializer.php index 689dcb7baf..776d3e9356 100644 --- a/src/pocketmine/network/mcpe/NetworkNbtSerializer.php +++ b/src/pocketmine/network/mcpe/NetworkNbtSerializer.php @@ -46,15 +46,11 @@ class NetworkNbtSerializer extends LittleEndianNbtSerializer{ } public function readString() : string{ - return $this->buffer->get($this->buffer->getUnsignedVarInt()); + return $this->buffer->get(self::checkReadStringLength($this->buffer->getUnsignedVarInt())); } public function writeString(string $v) : void{ - $len = strlen($v); - if($len > 32767){ - throw new \InvalidArgumentException("NBT strings cannot be longer than 32767 bytes, got $len bytes"); - } - $this->buffer->putUnsignedVarInt($len); + $this->buffer->putUnsignedVarInt(self::checkWriteStringLength(strlen($v))); $this->buffer->put($v); } From e506c7f7def85e013d67f6a30ba9152023fad6f0 Mon Sep 17 00:00:00 2001 From: Frago9876543210 Date: Sun, 14 Apr 2019 19:46:22 +0300 Subject: [PATCH 0747/3224] Call BlockTeleportEvent when dragon egg teleports (#2840) --- src/pocketmine/block/DragonEgg.php | 9 ++- .../event/block/BlockTeleportEvent.php | 59 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/pocketmine/event/block/BlockTeleportEvent.php diff --git a/src/pocketmine/block/DragonEgg.php b/src/pocketmine/block/DragonEgg.php index e9c44045f5..e91f7eb58f 100644 --- a/src/pocketmine/block/DragonEgg.php +++ b/src/pocketmine/block/DragonEgg.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\block\utils\Fallable; use pocketmine\block\utils\FallableTrait; +use pocketmine\event\block\BlockTeleportEvent; use pocketmine\item\Item; use pocketmine\item\TieredTool; use pocketmine\level\Level; @@ -76,8 +77,14 @@ class DragonEgg extends Transparent implements Fallable{ $this->z + mt_rand(-16, 16) ); if($block instanceof Air){ + $ev = new BlockTeleportEvent($this, $block); + $ev->call(); + if($ev->isCancelled()){ + break; + }else{ + $block = $ev->getTo(); + } $this->level->addParticle($this, new DragonEggTeleportParticle($this->x - $block->x, $this->y - $block->y, $this->z - $block->z)); - //TODO: add events $this->level->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); $this->level->setBlock($block, $this); break; diff --git a/src/pocketmine/event/block/BlockTeleportEvent.php b/src/pocketmine/event/block/BlockTeleportEvent.php new file mode 100644 index 0000000000..ac4d6ae519 --- /dev/null +++ b/src/pocketmine/event/block/BlockTeleportEvent.php @@ -0,0 +1,59 @@ +to = $to; + } + + /** + * @return Vector3 + */ + public function getTo() : Vector3{ + return $this->to; + } + + /** + * @param Vector3 $to + */ + public function setTo(Vector3 $to) : void{ + $this->to = $to; + } +} From e62bbd47543165e6ff4f14c754aae494f5d22e16 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 16 Apr 2019 17:44:14 +0100 Subject: [PATCH 0748/3224] AsyncTask: added onError() main thread hook, closes #2512 --- src/pocketmine/scheduler/AsyncPool.php | 1 + src/pocketmine/scheduler/AsyncTask.php | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/pocketmine/scheduler/AsyncPool.php b/src/pocketmine/scheduler/AsyncPool.php index 60e1bcac55..838a49dc91 100644 --- a/src/pocketmine/scheduler/AsyncPool.php +++ b/src/pocketmine/scheduler/AsyncPool.php @@ -239,6 +239,7 @@ class AsyncPool{ if($task->isCrashed()){ $this->logger->critical("Could not execute asynchronous task " . (new \ReflectionClass($task))->getShortName() . ": Task crashed"); + $task->onError(); }elseif(!$task->hasCancelledRun()){ /* * It's possible for a task to submit a progress update and then finish before the progress diff --git a/src/pocketmine/scheduler/AsyncTask.php b/src/pocketmine/scheduler/AsyncTask.php index 65fbef49bd..b063b79c16 100644 --- a/src/pocketmine/scheduler/AsyncTask.php +++ b/src/pocketmine/scheduler/AsyncTask.php @@ -183,6 +183,14 @@ abstract class AsyncTask extends \Threaded{ } + /** + * Called from the main thread when the async task experiences an error during onRun(). Use this for things like + * promise rejection. + */ + public function onError() : void{ + + } + /** * Saves mixed data in thread-local storage. Data stored using this storage is **only accessible from the thread it * was stored on**. Data stored using this method will **not** be serialized. From 3468f006a2b621485caa4ef6ef611153b23b081f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Apr 2019 16:00:17 +0100 Subject: [PATCH 0749/3224] Use AsyncTask->onError() for chunk task crash tracking --- src/pocketmine/level/Level.php | 16 ++++++++-------- src/pocketmine/network/mcpe/ChunkRequestTask.php | 11 ++++++++--- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index fb785553da..cf251a43bd 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -2440,13 +2440,8 @@ class Level implements ChunkManager, Metadatable{ Level::getXZ($index, $x, $z); if(isset($this->chunkSendTasks[$index])){ - if($this->chunkSendTasks[$index]->isCrashed()){ - unset($this->chunkSendTasks[$index]); - $this->server->getLogger()->error("Failed to prepare chunk $x $z for sending, retrying"); - }else{ - //Not ready for sending yet - continue; - } + //Not ready for sending yet + continue; } if(isset($this->chunkCache[$index])){ @@ -2485,7 +2480,12 @@ class Level implements ChunkManager, Metadatable{ $this->server->getLogger()->debug("Dropped prepared chunk $x $z due to world not loaded"); } }); - $this->server->getAsyncPool()->submitTask($task = new ChunkRequestTask($x, $z, $chunk, $promise)); + $this->server->getAsyncPool()->submitTask($task = new ChunkRequestTask($x, $z, $chunk, $promise, function() use($index, $x, $z){ + if(isset($this->chunkSendTasks[$index])){ + unset($this->chunkSendTasks[$index]); + $this->server->getLogger()->error("Failed to prepare chunk $x $z for sending, retrying"); + } + })); $this->chunkSendTasks[$index] = $task; $this->timings->syncChunkSendPrepareTimer->stopTiming(); diff --git a/src/pocketmine/network/mcpe/ChunkRequestTask.php b/src/pocketmine/network/mcpe/ChunkRequestTask.php index 4053dd6c5a..11bf7ae580 100644 --- a/src/pocketmine/network/mcpe/ChunkRequestTask.php +++ b/src/pocketmine/network/mcpe/ChunkRequestTask.php @@ -37,14 +37,14 @@ class ChunkRequestTask extends AsyncTask{ protected $compressionLevel; - public function __construct(int $chunkX, int $chunkZ, Chunk $chunk, CompressBatchPromise $promise){ + public function __construct(int $chunkX, int $chunkZ, Chunk $chunk, CompressBatchPromise $promise, ?\Closure $onError = null){ $this->compressionLevel = NetworkCompression::$LEVEL; $this->chunk = $chunk->networkSerialize(); $this->chunkX = $chunkX; $this->chunkZ = $chunkZ; - $this->storeLocal($promise); + $this->storeLocal(["promise" => $promise, "errorHook" => $onError]); } public function onRun() : void{ @@ -59,9 +59,14 @@ class ChunkRequestTask extends AsyncTask{ $this->setResult(NetworkCompression::compress($stream->getBuffer(), $this->compressionLevel)); } + public function onError() : void{ + $hook = $this->fetchLocal()["errorHook"]; + $hook(); + } + public function onCompletion() : void{ /** @var CompressBatchPromise $promise */ - $promise = $this->fetchLocal(); + $promise = $this->fetchLocal()["promise"]; $promise->resolve($this->getResult()); } } From 0973e39697579e6ccbb22cd40a49cbc3498f63f8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Apr 2019 16:13:40 +0100 Subject: [PATCH 0750/3224] Level: Fixed ChunkListeners not receiving some events when no loaders are using a chunk --- src/pocketmine/level/Level.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index cf251a43bd..be360ae48f 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -2329,10 +2329,9 @@ class Level implements ChunkManager, Metadatable{ if(!$this->isChunkInUse($chunkX, $chunkZ)){ $this->unloadChunkRequest($chunkX, $chunkZ); - }else{ - foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){ - $listener->onChunkChanged($chunk); - } + } + foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){ + $listener->onChunkChanged($chunk); } } @@ -2644,14 +2643,13 @@ class Level implements ChunkManager, Metadatable{ $this->getServer()->getAsyncPool()->submitTask(new LightPopulationTask($this, $chunk)); } - if($this->isChunkInUse($x, $z)){ - foreach($this->getChunkListeners($x, $z) as $listener){ - $listener->onChunkLoaded($chunk); - } - }else{ + if(!$this->isChunkInUse($x, $z)){ $this->server->getLogger()->debug("Newly loaded chunk $x $z has no loaders registered, will be unloaded at next available opportunity"); $this->unloadChunkRequest($x, $z); } + foreach($this->getChunkListeners($x, $z) as $listener){ + $listener->onChunkLoaded($chunk); + } $this->timings->syncChunkLoadTimer->stopTiming(); From 939dfd9269df0feaff5b96d0dd628055b9706b95 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Apr 2019 19:33:37 +0100 Subject: [PATCH 0751/3224] First look at separating chunk sending from Level --- src/pocketmine/Player.php | 39 +-- src/pocketmine/level/Level.php | 79 +----- src/pocketmine/network/mcpe/ChunkCache.php | 231 ++++++++++++++++++ .../network/mcpe/CompressBatchPromise.php | 62 ++++- .../network/mcpe/NetworkSession.php | 37 +++ 5 files changed, 337 insertions(+), 111 deletions(-) create mode 100644 src/pocketmine/network/mcpe/ChunkCache.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index b1afebec12..d76212d0a2 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -96,7 +96,6 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; -use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\BookEditPacket; @@ -954,12 +953,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $level = $level ?? $this->level; $index = Level::chunkHash($x, $z); if(isset($this->usedChunks[$index])){ - foreach($level->getChunkEntities($x, $z) as $entity){ - if($entity !== $this){ - $entity->despawnFrom($this); - } - } - + $this->networkSession->stopUsingChunk($x, $z); unset($this->usedChunks[$index]); } $level->unregisterChunkLoader($this, $x, $z); @@ -967,39 +961,24 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, unset($this->loadQueue[$index]); } - public function sendChunk(int $x, int $z, CompressBatchPromise $promise){ + public function onChunkReady(int $x, int $z){ if(!$this->isConnected()){ return; } + assert(isset($this->usedChunks[Level::chunkHash($x, $z)])); $this->usedChunks[Level::chunkHash($x, $z)] = true; - $this->networkSession->queueCompressed($promise); + $spawn = ++$this->spawnChunkLoadCount === $this->spawnThreshold; + $this->networkSession->startUsingChunk($x, $z, $spawn); - if($this->spawned){ - foreach($this->level->getChunkEntities($x, $z) as $entity){ - if($entity !== $this and !$entity->isClosed() and $entity->isAlive()){ - $entity->spawnTo($this); - } - } - }elseif(++$this->spawnChunkLoadCount >= $this->spawnThreshold){ - $this->spawnChunkLoadCount = -1; + if($spawn){ + //TODO: not sure this should be here $this->spawned = true; - - foreach($this->usedChunks as $index => $c){ - Level::getXZ($index, $chunkX, $chunkZ); - foreach($this->level->getChunkEntities($chunkX, $chunkZ) as $entity){ - if($entity !== $this and !$entity->isClosed() and $entity->isAlive() and !$entity->isFlaggedForDespawn()){ - $entity->spawnTo($this); - } - } - } - - $this->networkSession->onTerrainReady(); } } - protected function sendNextChunk(){ + protected function requestChunks(){ if(!$this->isConnected()){ return; } @@ -1146,7 +1125,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } if(count($this->loadQueue) > 0){ - $this->sendNextChunk(); + $this->requestChunks(); } } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index be360ae48f..66701c559a 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -72,8 +72,6 @@ use pocketmine\metadata\Metadatable; use pocketmine\metadata\MetadataValue; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; -use pocketmine\network\mcpe\ChunkRequestTask; -use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; @@ -148,9 +146,6 @@ class Level implements ChunkManager, Metadatable{ /** @var Block[][] */ private $blockCache = []; - /** @var CompressBatchPromise[] */ - private $chunkCache = []; - /** @var int */ private $sendTimeTicker = 0; @@ -221,8 +216,6 @@ class Level implements ChunkManager, Metadatable{ /** @var Player[][] */ private $chunkSendQueue = []; - /** @var ChunkRequestTask[] */ - private $chunkSendTasks = []; /** @var bool[] */ private $chunkPopulationQueue = []; @@ -843,7 +836,6 @@ class Level implements ChunkManager, Metadatable{ if(empty($blocks)){ //blocks can be set normally and then later re-set with direct send continue; } - unset($this->chunkCache[$index]); Level::getXZ($index, $chunkX, $chunkZ); if(count($blocks) > 512){ $chunk = $this->getChunk($chunkX, $chunkZ); @@ -854,8 +846,6 @@ class Level implements ChunkManager, Metadatable{ $this->sendBlocks($this->getChunkPlayers($chunkX, $chunkZ), $blocks); } } - }else{ - $this->chunkCache = []; } $this->changedBlocks = []; @@ -960,7 +950,6 @@ class Level implements ChunkManager, Metadatable{ public function clearCache(bool $force = false){ if($force){ - $this->chunkCache = []; $this->blockCache = []; }else{ $count = 0; @@ -974,10 +963,6 @@ class Level implements ChunkManager, Metadatable{ } } - public function clearChunkCache(int $chunkX, int $chunkZ){ - unset($this->chunkCache[Level::chunkHash($chunkX, $chunkZ)]); - } - public function getRandomTickedBlocks() : \SplFixedArray{ return $this->randomTickBlocks; } @@ -2319,17 +2304,13 @@ class Level implements ChunkManager, Metadatable{ $this->chunks[$chunkHash] = $chunk; unset($this->blockCache[$chunkHash]); - unset($this->chunkCache[$chunkHash]); unset($this->changedBlocks[$chunkHash]); - if(isset($this->chunkSendTasks[$chunkHash])){ //invalidate pending caches - $this->chunkSendTasks[$chunkHash]->cancelRun(); - unset($this->chunkSendTasks[$chunkHash]); - } $chunk->setChanged(); if(!$this->isChunkInUse($chunkX, $chunkZ)){ $this->unloadChunkRequest($chunkX, $chunkZ); } + foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){ $listener->onChunkChanged($chunk); } @@ -2419,13 +2400,11 @@ class Level implements ChunkManager, Metadatable{ $this->chunkSendQueue[$index][spl_object_id($player)] = $player; } - private function sendCachedChunk(int $x, int $z){ + private function onChunkReady(int $x, int $z){ if(isset($this->chunkSendQueue[$index = Level::chunkHash($x, $z)])){ foreach($this->chunkSendQueue[$index] as $player){ /** @var Player $player */ - if($player->isConnected() and isset($player->usedChunks[$index])){ - $player->sendChunk($x, $z, $this->chunkCache[$index]); - } + $player->onChunkReady($x, $z); } unset($this->chunkSendQueue[$index]); } @@ -2438,55 +2417,13 @@ class Level implements ChunkManager, Metadatable{ foreach($this->chunkSendQueue as $index => $players){ Level::getXZ($index, $x, $z); - if(isset($this->chunkSendTasks[$index])){ - //Not ready for sending yet - continue; - } - - if(isset($this->chunkCache[$index])){ - $this->sendCachedChunk($x, $z); - continue; - } - $this->timings->syncChunkSendPrepareTimer->startTiming(); $chunk = $this->chunks[$index] ?? null; - if(!($chunk instanceof Chunk)){ + if($chunk === null or !$chunk->isGenerated() or !$chunk->isPopulated()){ throw new ChunkException("Invalid Chunk sent"); } - assert($chunk->getX() === $x and $chunk->getZ() === $z, "Chunk coordinate mismatch: expected $x $z, but chunk has coordinates " . $chunk->getX() . " " . $chunk->getZ() . ", did you forget to clone a chunk before setting?"); - - /* - * we don't send promises directly to the players here because unresolved promises of chunk sending - * would slow down the sending of other packets, especially if a chunk takes a long time to prepare. - */ - - $promise = new CompressBatchPromise(); - $promise->onResolve(function(CompressBatchPromise $promise) use ($x, $z, $index): void{ - if(!$this->closed){ - $this->timings->syncChunkSendTimer->startTiming(); - - unset($this->chunkSendTasks[$index]); - - $this->chunkCache[$index] = $promise; - $this->sendCachedChunk($x, $z); - if(!$this->server->getMemoryManager()->canUseChunkCache()){ - unset($this->chunkCache[$index]); - } - - $this->timings->syncChunkSendTimer->stopTiming(); - }else{ - $this->server->getLogger()->debug("Dropped prepared chunk $x $z due to world not loaded"); - } - }); - $this->server->getAsyncPool()->submitTask($task = new ChunkRequestTask($x, $z, $chunk, $promise, function() use($index, $x, $z){ - if(isset($this->chunkSendTasks[$index])){ - unset($this->chunkSendTasks[$index]); - $this->server->getLogger()->error("Failed to prepare chunk $x $z for sending, retrying"); - } - })); - $this->chunkSendTasks[$index] = $task; - + $this->onChunkReady($x, $z); $this->timings->syncChunkSendPrepareTimer->stopTiming(); } @@ -2577,7 +2514,9 @@ class Level implements ChunkManager, Metadatable{ if(isset($this->chunks[$hash = Level::chunkHash($chunkX, $chunkZ)])){ $this->chunks[$hash]->removeTile($tile); } - $this->clearChunkCache($chunkX, $chunkZ); + foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){ + $listener->onBlockChanged($tile); + } } /** @@ -2712,11 +2651,9 @@ class Level implements ChunkManager, Metadatable{ } unset($this->chunks[$chunkHash]); - unset($this->chunkCache[$chunkHash]); unset($this->blockCache[$chunkHash]); unset($this->changedBlocks[$chunkHash]); unset($this->chunkSendQueue[$chunkHash]); - unset($this->chunkSendTasks[$chunkHash]); $this->timings->doChunkUnload->stopTiming(); diff --git a/src/pocketmine/network/mcpe/ChunkCache.php b/src/pocketmine/network/mcpe/ChunkCache.php new file mode 100644 index 0000000000..dcadd609d6 --- /dev/null +++ b/src/pocketmine/network/mcpe/ChunkCache.php @@ -0,0 +1,231 @@ +world = $world; + } + + /** + * Requests asynchronous preparation of the chunk at the given coordinates. + * + * @param int $chunkX + * @param int $chunkZ + * + * @return CompressBatchPromise a promise of resolution which will contain a compressed chunk packet. + */ + public function request(int $chunkX, int $chunkZ) : CompressBatchPromise{ + $this->world->registerChunkListener($this, $chunkX, $chunkZ); + $chunkHash = Level::chunkHash($chunkX, $chunkZ); + + if(isset($this->caches[$chunkHash])){ + ++$this->hits; + return $this->caches[$chunkHash]; + } + + ++$this->misses; + + $this->world->timings->syncChunkSendPrepareTimer->startTiming(); + try{ + $this->caches[$chunkHash] = new CompressBatchPromise(); + + $this->world->getServer()->getAsyncPool()->submitTask( + new ChunkRequestTask( + $chunkX, + $chunkZ, + $this->world->getChunk($chunkX, $chunkZ), + $this->caches[$chunkHash], + function() use($chunkX, $chunkZ){ + $this->world->getServer()->getLogger()->error("Failed preparing chunk for " . $this->world->getDisplayName() . " chunk $chunkX $chunkZ, retrying"); + + $this->restartPendingRequest($chunkX, $chunkZ); + } + ) + ); + + return $this->caches[$chunkHash]; + }finally{ + $this->world->timings->syncChunkSendPrepareTimer->stopTiming(); + } + } + + private function destroy(int $chunkX, int $chunkZ) : bool{ + $chunkHash = Level::chunkHash($chunkX, $chunkZ); + $existing = $this->caches[$chunkHash] ?? null; + unset($this->caches[$chunkHash]); + + return $existing !== null; + } + + /** + * Restarts an async request for an unresolved chunk. + * + * @param int $chunkX + * @param int $chunkZ + * + * @throws \InvalidArgumentException + */ + private function restartPendingRequest(int $chunkX, int $chunkZ) : void{ + $chunkHash = Level::chunkHash($chunkX, $chunkZ); + $existing = $this->caches[$chunkHash]; + if($existing === null or $existing->hasResult()){ + throw new \InvalidArgumentException("Restart can only be applied to unresolved promises"); + } + $existing->cancel(); + unset($this->caches[$chunkHash]); + + $this->request($chunkX, $chunkZ)->onResolve(...$existing->getResolveCallbacks()); + } + + /** + * @param int $chunkX + * @param int $chunkZ + * + * @throws \InvalidArgumentException + */ + private function destroyOrRestart(int $chunkX, int $chunkZ) : void{ + $cache = $this->caches[Level::chunkHash($chunkX, $chunkZ)] ?? null; + if($cache !== null){ + if(!$cache->hasResult()){ + //some requesters are waiting for this chunk, so their request needs to be fulfilled + $this->restartPendingRequest($chunkX, $chunkZ); + }else{ + //dump the cache, it'll be regenerated the next time it's requested + $this->destroy($chunkX, $chunkZ); + } + } + } + + /** + * @see ChunkListener::onChunkChanged() + * @param Chunk $chunk + */ + public function onChunkChanged(Chunk $chunk) : void{ + //FIXME: this gets fired for stuff that doesn't change terrain related things (like lighting updates) + $this->destroyOrRestart($chunk->getX(), $chunk->getZ()); + } + + /** + * @see ChunkListener::onBlockChanged() + * @param Vector3 $block + */ + public function onBlockChanged(Vector3 $block) : void{ + //FIXME: requesters will still receive this chunk after it's been dropped, but we can't mark this for a simple + //sync here because it can spam the worker pool + $this->destroy($block->getFloorX() >> 4, $block->getFloorZ() >> 4); + } + + /** + * @see ChunkListener::onChunkUnloaded() + * @param Chunk $chunk + */ + public function onChunkUnloaded(Chunk $chunk) : void{ + $this->destroy($chunk->getX(), $chunk->getZ()); + $this->world->unregisterChunkListener($this, $chunk->getX(), $chunk->getZ()); + } + + /** + * @see ChunkListener::onChunkLoaded() + * @param Chunk $chunk + */ + public function onChunkLoaded(Chunk $chunk) : void{ + //NOOP + } + + /** + * @see ChunkListener::onChunkPopulated() + * @param Chunk $chunk + */ + public function onChunkPopulated(Chunk $chunk) : void{ + //NOOP - we also receive this in onChunkChanged, so we don't care here + } + + /** + * Returns the number of bytes occupied by the cache data in this cache. This does not include the size of any + * promises referenced by the cache. + * + * @return int + */ + public function calculateCacheSize() : int{ + $result = 0; + foreach($this->caches as $cache){ + if($cache->hasResult()){ + $result += strlen($cache->getResult()); + } + } + return $result; + } + + /** + * Returns the percentage of requests to the cache which resulted in a cache hit. + * + * @return float + */ + public function getHitPercentage() : float{ + $total = $this->hits + $this->misses; + return $total > 0 ? $this->hits / $total : 0.0; + } +} diff --git a/src/pocketmine/network/mcpe/CompressBatchPromise.php b/src/pocketmine/network/mcpe/CompressBatchPromise.php index 6707c08c28..f58ef6ca06 100644 --- a/src/pocketmine/network/mcpe/CompressBatchPromise.php +++ b/src/pocketmine/network/mcpe/CompressBatchPromise.php @@ -23,6 +23,9 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; +use pocketmine\utils\Utils; +use function array_push; + class CompressBatchPromise{ /** @var callable[] */ private $callbacks = []; @@ -30,26 +33,45 @@ class CompressBatchPromise{ /** @var string|null */ private $result = null; - public function onResolve(callable $callback) : void{ + /** @var bool */ + private $cancelled = false; + + public function onResolve(callable ...$callbacks) : void{ + $this->checkCancelled(); + foreach($callbacks as $callback){ + Utils::validateCallableSignature(function(CompressBatchPromise $promise){}, $callback); + } if($this->result !== null){ - $callback($this); + foreach($callbacks as $callback){ + $callback($this); + } }else{ - $this->callbacks[] = $callback; + array_push($this->callbacks, ...$callbacks); } } public function resolve(string $result) : void{ - if($this->result !== null){ - throw new \InvalidStateException("Cannot resolve promise more than once"); + if(!$this->cancelled){ + if($this->result !== null){ + throw new \InvalidStateException("Cannot resolve promise more than once"); + } + $this->result = $result; + foreach($this->callbacks as $callback){ + $callback($this); + } + $this->callbacks = []; } - $this->result = $result; - foreach($this->callbacks as $callback){ - $callback($this); - } - $this->callbacks = []; + } + + /** + * @return callable[] + */ + public function getResolveCallbacks() : array{ + return $this->callbacks; } public function getResult() : string{ + $this->checkCancelled(); if($this->result === null){ throw new \InvalidStateException("Promise has not yet been resolved"); } @@ -59,4 +81,24 @@ class CompressBatchPromise{ public function hasResult() : bool{ return $this->result !== null; } + + /** + * @return bool + */ + public function isCancelled() : bool{ + return $this->cancelled; + } + + public function cancel() : void{ + if($this->hasResult()){ + throw new \InvalidStateException("Cannot cancel a resolved promise"); + } + $this->cancelled = true; + } + + private function checkCancelled() : void{ + if($this->cancelled){ + throw new \InvalidArgumentException("Promise has been cancelled"); + } + } } diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 838e4cc6ba..3a76c908be 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -744,6 +744,43 @@ class NetworkSession{ return $this->sendDataPacket($pk); } + public function startUsingChunk(int $chunkX, int $chunkZ, bool $spawn = false) : void{ + ChunkCache::getInstance($this->player->getLevel())->request($chunkX, $chunkZ)->onResolve( + + //this callback may be called synchronously or asynchronously, depending on whether the promise is resolved yet + function(CompressBatchPromise $promise) use($chunkX, $chunkZ, $spawn){ + if(!$this->isConnected()){ + return; + } + $this->player->level->timings->syncChunkSendTimer->startTiming(); + try{ + $this->queueCompressed($promise); + + foreach($this->player->getLevel()->getChunkEntities($chunkX, $chunkZ) as $entity){ + if($entity !== $this->player and !$entity->isClosed() and !$entity->isFlaggedForDespawn()){ + $entity->spawnTo($this->player); + } + } + + if($spawn){ + //TODO: potential race condition during chunk sending could cause this to be called too early + $this->onTerrainReady(); + } + }finally{ + $this->player->level->timings->syncChunkSendTimer->stopTiming(); + } + } + ); + } + + public function stopUsingChunk(int $chunkX, int $chunkZ) : void{ + foreach($this->player->getLevel()->getChunkEntities($chunkX, $chunkZ) as $entity){ + if($entity !== $this->player){ + $entity->despawnFrom($this->player); + } + } + } + public function tick() : bool{ if($this->handler instanceof LoginSessionHandler){ if(time() >= $this->connectTime + 10){ From d68501c748c07f53e7008afda4b365ec79eca22c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Apr 2019 16:12:20 +0100 Subject: [PATCH 0752/3224] fixed spawn-radius: 0 --- src/pocketmine/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index d76212d0a2..6e0d8cd80b 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -969,7 +969,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, assert(isset($this->usedChunks[Level::chunkHash($x, $z)])); $this->usedChunks[Level::chunkHash($x, $z)] = true; - $spawn = ++$this->spawnChunkLoadCount === $this->spawnThreshold; + $spawn = $this->spawnChunkLoadCount++ === $this->spawnThreshold; $this->networkSession->startUsingChunk($x, $z, $spawn); if($spawn){ From cc01dfe8df1203d672283d74a1744e36a9915c70 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Apr 2019 16:20:56 +0100 Subject: [PATCH 0753/3224] Player: protect usedChunks --- src/pocketmine/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 6e0d8cd80b..0121a1489e 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -209,7 +209,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, protected $gamemode; /** @var bool[] chunkHash => bool (true = sent, false = needs sending) */ - public $usedChunks = []; + protected $usedChunks = []; /** @var bool[] chunkHash => dummy */ protected $loadQueue = []; /** @var int */ From 5913d5038b6f55e618c76b855a8b49a27a62b212 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Apr 2019 17:23:48 +0100 Subject: [PATCH 0754/3224] Cleaned up Entity->close() handling --- src/pocketmine/Player.php | 27 +++++++++---------- src/pocketmine/entity/Entity.php | 46 +++++++++++++++++++++----------- src/pocketmine/entity/Human.php | 22 +++++++-------- src/pocketmine/entity/Living.php | 16 +++++------ 4 files changed, 61 insertions(+), 50 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 0121a1489e..90194a3ffe 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2539,21 +2539,20 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->flagForDespawn(); } - final public function close() : void{ - if(!$this->closed){ - $this->disconnect("Player destroyed"); - $this->networkSession = null; + protected function onDispose() : void{ + $this->disconnect("Player destroyed"); + $this->cursorInventory->removeAllViewers(true); + $this->craftingGrid->removeAllViewers(true); + parent::onDispose(); + } - $this->cursorInventory = null; - $this->craftingGrid = null; - - $this->spawned = false; - - $this->spawnPosition = null; - $this->perm = null; - - parent::close(); - } + protected function destroyCycles() : void{ + $this->networkSession = null; + $this->cursorInventory = null; + $this->craftingGrid = null; + $this->spawnPosition = null; + $this->perm = null; + parent::destroyCycles(); } public function __debugInfo(){ diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 126d2923d4..1e33278a64 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -1897,28 +1897,42 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ * * WARNING: Entities are unusable after this has been executed! */ - public function close() : void{ + final public function close() : void{ if(!$this->closed){ - (new EntityDespawnEvent($this))->call(); $this->closed = true; + (new EntityDespawnEvent($this))->call(); - $this->despawnFromAll(); - $this->hasSpawned = []; - - if($this->chunk !== null){ - $this->chunk->removeEntity($this); - $this->chunk = null; - } - - if($this->isValid()){ - $this->level->removeEntity($this); - $this->setLevel(null); - } - - $this->lastDamageCause = null; + $this->onDispose(); + $this->destroyCycles(); } } + /** + * Called when the entity is disposed to clean up things like viewers. This SHOULD NOT destroy internal state, + * because it may be needed by descendent classes. + */ + protected function onDispose() : void{ + $this->despawnFromAll(); + if($this->chunk !== null){ + $this->chunk->removeEntity($this); + } + if($this->isValid()){ + $this->level->removeEntity($this); + } + } + + /** + * Called when the entity is disposed, after all events have been fired. This should be used to perform destructive + * circular object references and things which could impact memory usage. + * + * It is expected that the object is unusable after this is called. + */ + protected function destroyCycles() : void{ + $this->chunk = null; + $this->setLevel(null); + $this->lastDamageCause = null; + } + /** * @param int $propertyId * @param int $flagId diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 5beeb8b66e..443a1ffe45 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -883,18 +883,16 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ } } - public function close() : void{ - if(!$this->closed){ - if($this->inventory !== null){ - $this->inventory->removeAllViewers(true); - $this->inventory = null; - } - if($this->enderChestInventory !== null){ - $this->enderChestInventory->removeAllViewers(true); - $this->enderChestInventory = null; - } - parent::close(); - } + protected function onDispose() : void{ + $this->inventory->removeAllViewers(true); + $this->enderChestInventory->removeAllViewers(true); + parent::onDispose(); + } + + protected function destroyCycles() : void{ + $this->inventory = null; + $this->enderChestInventory = null; + parent::destroyCycles(); } /** diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 97bec4f149..2b07024d9a 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -926,13 +926,13 @@ abstract class Living extends Entity implements Damageable{ $this->armorInventory->sendContents($player); } - public function close() : void{ - if(!$this->closed){ - if($this->armorInventory !== null){ - $this->armorInventory->removeAllViewers(true); - $this->armorInventory = null; - } - parent::close(); - } + protected function onDispose() : void{ + $this->armorInventory->removeAllViewers(true); + parent::onDispose(); + } + + protected function destroyCycles() : void{ + $this->armorInventory = null; + parent::destroyCycles(); } } From a4c7ec077b1b5320e1e303034d7e45d52060662d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Apr 2019 17:45:14 +0100 Subject: [PATCH 0755/3224] Fixed possible crash in ChunkRequestTask --- src/pocketmine/network/mcpe/ChunkRequestTask.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/ChunkRequestTask.php b/src/pocketmine/network/mcpe/ChunkRequestTask.php index 11bf7ae580..0337cf2c88 100644 --- a/src/pocketmine/network/mcpe/ChunkRequestTask.php +++ b/src/pocketmine/network/mcpe/ChunkRequestTask.php @@ -61,7 +61,9 @@ class ChunkRequestTask extends AsyncTask{ public function onError() : void{ $hook = $this->fetchLocal()["errorHook"]; - $hook(); + if($hook !== null){ + $hook(); + } } public function onCompletion() : void{ From 752e3989704afbe0d146680a169550d68240d512 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Apr 2019 18:58:31 +0100 Subject: [PATCH 0756/3224] AsyncTask: TLS now supports storing multiple values (now requires a key/value pair) --- .../command/defaults/TimingsCommand.php | 7 +++++-- .../level/generator/PopulationTask.php | 5 +++-- .../level/light/LightPopulationTask.php | 5 +++-- src/pocketmine/network/mcpe/ChunkRequestTask.php | 11 ++++++++--- .../network/mcpe/CompressBatchTask.php | 6 ++++-- src/pocketmine/network/mcpe/ProcessLoginTask.php | 5 +++-- src/pocketmine/scheduler/AsyncTask.php | 16 ++++++++++------ src/pocketmine/updater/UpdateCheckTask.php | 5 +++-- .../tests/AsyncTaskPublishProgressRaceTest.php | 6 ++++-- 9 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/pocketmine/command/defaults/TimingsCommand.php b/src/pocketmine/command/defaults/TimingsCommand.php index a56430f0e2..2c17170a4a 100644 --- a/src/pocketmine/command/defaults/TimingsCommand.php +++ b/src/pocketmine/command/defaults/TimingsCommand.php @@ -122,6 +122,8 @@ class TimingsCommand extends VanillaCommand{ $host = $sender->getServer()->getProperty("timings.host", "timings.pmmp.io"); $sender->getServer()->getAsyncPool()->submitTask(new class($sender, $host, $agent, $data) extends BulkCurlTask{ + private const TLS_KEY_SENDER = "sender"; + /** @var string */ private $host; @@ -139,11 +141,12 @@ class TimingsCommand extends VanillaCommand{ ]] ]); $this->host = $host; - $this->storeLocal($sender); + $this->storeLocal(self::TLS_KEY_SENDER, $sender); } public function onCompletion() : void{ - $sender = $this->fetchLocal(); + /** @var CommandSender $sender */ + $sender = $this->fetchLocal(self::TLS_KEY_SENDER); if($sender instanceof Player and !$sender->isOnline()){ // TODO replace with a more generic API method for checking availability of CommandSender return; } diff --git a/src/pocketmine/level/generator/PopulationTask.php b/src/pocketmine/level/generator/PopulationTask.php index 5ca622ca55..7dcb32c325 100644 --- a/src/pocketmine/level/generator/PopulationTask.php +++ b/src/pocketmine/level/generator/PopulationTask.php @@ -29,6 +29,7 @@ use pocketmine\level\SimpleChunkManager; use pocketmine\scheduler\AsyncTask; class PopulationTask extends AsyncTask{ + private const TLS_KEY_WORLD = "world"; public $state; public $levelId; @@ -53,7 +54,7 @@ class PopulationTask extends AsyncTask{ $this->{"chunk$i"} = $c !== null ? $c->fastSerialize() : null; } - $this->storeLocal($level); + $this->storeLocal(self::TLS_KEY_WORLD, $level); } public function onRun() : void{ @@ -138,7 +139,7 @@ class PopulationTask extends AsyncTask{ public function onCompletion() : void{ /** @var Level $level */ - $level = $this->fetchLocal(); + $level = $this->fetchLocal(self::TLS_KEY_WORLD); if(!$level->isClosed()){ if(!$this->state){ $level->registerGeneratorToWorker($this->worker->getAsyncWorkerId()); diff --git a/src/pocketmine/level/light/LightPopulationTask.php b/src/pocketmine/level/light/LightPopulationTask.php index e066a6b2fe..fdff68f6ce 100644 --- a/src/pocketmine/level/light/LightPopulationTask.php +++ b/src/pocketmine/level/light/LightPopulationTask.php @@ -29,11 +29,12 @@ use pocketmine\level\Level; use pocketmine\scheduler\AsyncTask; class LightPopulationTask extends AsyncTask{ + private const TLS_KEY_WORLD = "world"; public $chunk; public function __construct(Level $level, Chunk $chunk){ - $this->storeLocal($level); + $this->storeLocal(self::TLS_KEY_WORLD, $level); $this->chunk = $chunk->fastSerialize(); } @@ -53,7 +54,7 @@ class LightPopulationTask extends AsyncTask{ public function onCompletion() : void{ /** @var Level $level */ - $level = $this->fetchLocal(); + $level = $this->fetchLocal(self::TLS_KEY_WORLD); if(!$level->isClosed()){ /** @var Chunk $chunk */ $chunk = Chunk::fastDeserialize($this->chunk); diff --git a/src/pocketmine/network/mcpe/ChunkRequestTask.php b/src/pocketmine/network/mcpe/ChunkRequestTask.php index 0337cf2c88..2d07e0b61d 100644 --- a/src/pocketmine/network/mcpe/ChunkRequestTask.php +++ b/src/pocketmine/network/mcpe/ChunkRequestTask.php @@ -28,6 +28,9 @@ use pocketmine\network\mcpe\protocol\FullChunkDataPacket; use pocketmine\scheduler\AsyncTask; class ChunkRequestTask extends AsyncTask{ + private const TLS_KEY_PROMISE = "promise"; + private const TLS_KEY_ERROR_HOOK = "errorHook"; + /** @var string */ protected $chunk; /** @var int */ @@ -44,7 +47,8 @@ class ChunkRequestTask extends AsyncTask{ $this->chunkX = $chunkX; $this->chunkZ = $chunkZ; - $this->storeLocal(["promise" => $promise, "errorHook" => $onError]); + $this->storeLocal(self::TLS_KEY_PROMISE, $promise); + $this->storeLocal(self::TLS_KEY_ERROR_HOOK, $onError); } public function onRun() : void{ @@ -60,7 +64,8 @@ class ChunkRequestTask extends AsyncTask{ } public function onError() : void{ - $hook = $this->fetchLocal()["errorHook"]; + /** @var \Closure $hook */ + $hook = $this->fetchLocal(self::TLS_KEY_ERROR_HOOK); if($hook !== null){ $hook(); } @@ -68,7 +73,7 @@ class ChunkRequestTask extends AsyncTask{ public function onCompletion() : void{ /** @var CompressBatchPromise $promise */ - $promise = $this->fetchLocal()["promise"]; + $promise = $this->fetchLocal(self::TLS_KEY_PROMISE); $promise->resolve($this->getResult()); } } diff --git a/src/pocketmine/network/mcpe/CompressBatchTask.php b/src/pocketmine/network/mcpe/CompressBatchTask.php index 41498ec9b6..2a64a63d1e 100644 --- a/src/pocketmine/network/mcpe/CompressBatchTask.php +++ b/src/pocketmine/network/mcpe/CompressBatchTask.php @@ -27,6 +27,8 @@ use pocketmine\scheduler\AsyncTask; class CompressBatchTask extends AsyncTask{ + private const TLS_KEY_PROMISE = "promise"; + private $level; private $data; @@ -38,7 +40,7 @@ class CompressBatchTask extends AsyncTask{ public function __construct(string $data, int $compressionLevel, CompressBatchPromise $promise){ $this->data = $data; $this->level = $compressionLevel; - $this->storeLocal($promise); + $this->storeLocal(self::TLS_KEY_PROMISE, $promise); } public function onRun() : void{ @@ -47,7 +49,7 @@ class CompressBatchTask extends AsyncTask{ public function onCompletion() : void{ /** @var CompressBatchPromise $promise */ - $promise = $this->fetchLocal(); + $promise = $this->fetchLocal(self::TLS_KEY_PROMISE); $promise->resolve($this->getResult()); } } diff --git a/src/pocketmine/network/mcpe/ProcessLoginTask.php b/src/pocketmine/network/mcpe/ProcessLoginTask.php index 6c19792847..1898d562b3 100644 --- a/src/pocketmine/network/mcpe/ProcessLoginTask.php +++ b/src/pocketmine/network/mcpe/ProcessLoginTask.php @@ -58,6 +58,7 @@ use const OPENSSL_ALGO_SHA384; use const STR_PAD_LEFT; class ProcessLoginTask extends AsyncTask{ + private const TLS_KEY_SESSION = "session"; public const MOJANG_ROOT_PUBLIC_KEY = "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8ELkixyLcwlZryUQcu1TvPOmI2B7vX83ndnWRUaXm74wFfa5f/lwQNTfrLVHa2PmenpGI6JhIMUJaWZrjmMj90NoKNFSNBuKdm8rYiXsfaz3K36x/1U26HpG0ZxK/V1V"; @@ -100,7 +101,7 @@ class ProcessLoginTask extends AsyncTask{ private $handshakeJwt = null; public function __construct(NetworkSession $session, LoginPacket $packet, bool $authRequired, bool $useEncryption = true){ - $this->storeLocal($session); + $this->storeLocal(self::TLS_KEY_SESSION, $session); $this->packet = $packet; $this->authRequired = $authRequired; $this->useEncryption = $useEncryption; @@ -243,7 +244,7 @@ class ProcessLoginTask extends AsyncTask{ public function onCompletion() : void{ /** @var NetworkSession $session */ - $session = $this->fetchLocal(); + $session = $this->fetchLocal(self::TLS_KEY_SESSION); if(!$session->isConnected()){ $this->worker->getLogger()->error("Player " . $session->getDisplayName() . " was disconnected before their login could be verified"); }elseif($session->setAuthenticationStatus($this->authenticated, $this->authRequired, $this->error)){ diff --git a/src/pocketmine/scheduler/AsyncTask.php b/src/pocketmine/scheduler/AsyncTask.php index b063b79c16..08639ad58a 100644 --- a/src/pocketmine/scheduler/AsyncTask.php +++ b/src/pocketmine/scheduler/AsyncTask.php @@ -213,9 +213,10 @@ abstract class AsyncTask extends \Threaded{ * (E.g. a {@link \pocketmine\Level} object is no longer usable because it is unloaded while the AsyncTask is * executing, or even a plugin might be unloaded). * - * @param mixed $complexData the data to store + * @param string $key + * @param mixed $complexData the data to store */ - protected function storeLocal($complexData) : void{ + protected function storeLocal(string $key, $complexData) : void{ if(self::$threadLocalStorage === null){ /* * It's necessary to use an object (not array) here because pthreads is stupid. Non-default array statics @@ -225,7 +226,7 @@ abstract class AsyncTask extends \Threaded{ */ self::$threadLocalStorage = new \ArrayObject(); } - self::$threadLocalStorage[spl_object_id($this)] = $complexData; + self::$threadLocalStorage[spl_object_id($this)][$key] = $complexData; } /** @@ -234,16 +235,19 @@ abstract class AsyncTask extends \Threaded{ * If you used storeLocal(), you can use this on the same thread to fetch data stored. This should be used during * onProgressUpdate() and onCompletion() to fetch thread-local data stored on the parent thread. * + * @param string $key + * * @return mixed * * @throws \InvalidArgumentException if no data were stored by this AsyncTask instance. */ - protected function fetchLocal(){ - if(self::$threadLocalStorage === null or !isset(self::$threadLocalStorage[spl_object_id($this)])){ + protected function fetchLocal(string $key){ + $id = spl_object_id($this); + if(self::$threadLocalStorage === null or !isset(self::$threadLocalStorage[$id][$key])){ throw new \InvalidArgumentException("No matching thread-local data found on this thread"); } - return self::$threadLocalStorage[spl_object_id($this)]; + return self::$threadLocalStorage[$id][$key]; } final public function __destruct(){ diff --git a/src/pocketmine/updater/UpdateCheckTask.php b/src/pocketmine/updater/UpdateCheckTask.php index f81169d990..23efebb1bf 100644 --- a/src/pocketmine/updater/UpdateCheckTask.php +++ b/src/pocketmine/updater/UpdateCheckTask.php @@ -30,6 +30,7 @@ use function is_array; use function json_decode; class UpdateCheckTask extends AsyncTask{ + private const TLS_KEY_UPDATER = "updater"; /** @var string */ private $endpoint; @@ -39,7 +40,7 @@ class UpdateCheckTask extends AsyncTask{ private $error = "Unknown error"; public function __construct(AutoUpdater $updater, string $endpoint, string $channel){ - $this->storeLocal($updater); + $this->storeLocal(self::TLS_KEY_UPDATER, $updater); $this->endpoint = $endpoint; $this->channel = $channel; } @@ -74,7 +75,7 @@ class UpdateCheckTask extends AsyncTask{ public function onCompletion() : void{ /** @var AutoUpdater $updater */ - $updater = $this->fetchLocal(); + $updater = $this->fetchLocal(self::TLS_KEY_UPDATER); if($this->hasResult()){ $updater->checkUpdateCallback($this->getResult()); }else{ diff --git a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskPublishProgressRaceTest.php b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskPublishProgressRaceTest.php index d85ecc073d..ea637a57d7 100644 --- a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskPublishProgressRaceTest.php +++ b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskPublishProgressRaceTest.php @@ -40,10 +40,12 @@ class AsyncTaskPublishProgressRaceTest extends Test{ //this test is racy, but it should fail often enough to be a pest if something is broken $this->getPlugin()->getServer()->getAsyncPool()->submitTask(new class($this) extends AsyncTask{ + private const TLS_KEY_TEST = "test"; + private static $success = false; public function __construct(AsyncTaskPublishProgressRaceTest $t){ - $this->storeLocal($t); + $this->storeLocal(self::TLS_KEY_TEST, $t); } public function onRun() : void{ @@ -59,7 +61,7 @@ class AsyncTaskPublishProgressRaceTest extends Test{ public function onCompletion() : void{ /** @var AsyncTaskPublishProgressRaceTest $t */ - $t = $this->fetchLocal(); + $t = $this->fetchLocal(self::TLS_KEY_TEST); $t->setResult(self::$success ? Test::RESULT_OK : Test::RESULT_FAILED); } }); From 7720a0534e3c4f0dcc70cf3fbc12699de6f04374 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Apr 2019 19:57:40 +0100 Subject: [PATCH 0757/3224] Network: Each interface now keeps its own statistics this allows more detailed analysis. --- .../network/AdvancedNetworkInterface.php | 19 ++++++++++++++ src/pocketmine/network/Network.php | 25 ++++++++++--------- .../network/mcpe/RakLibInterface.php | 20 ++++++++++++++- 3 files changed, 51 insertions(+), 13 deletions(-) diff --git a/src/pocketmine/network/AdvancedNetworkInterface.php b/src/pocketmine/network/AdvancedNetworkInterface.php index 42c1ef62d5..1e54275b23 100644 --- a/src/pocketmine/network/AdvancedNetworkInterface.php +++ b/src/pocketmine/network/AdvancedNetworkInterface.php @@ -68,4 +68,23 @@ interface AdvancedNetworkInterface extends NetworkInterface{ * @param string $regex */ public function addRawPacketFilter(string $regex) : void; + + /** + * Returns the number of bytes sent on this network interface since the last statistics reset. + * + * @return int + */ + public function getBytesSent() : int; + + /** + * Returns the number of bytes received on this network interface since the last statistics reset. + * + * @return int + */ + public function getBytesReceived() : int; + + /** + * Resets the upload/download statistics to zero. + */ + public function resetTrafficStats() : void; } diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index a1e872cb31..654ff40700 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -49,9 +49,6 @@ class Network{ /** @var int[] */ private $bannedIps = []; - private $upload = 0; - private $download = 0; - /** @var string */ private $name; @@ -67,22 +64,26 @@ class Network{ $this->logger = $logger; } - public function addStatistics(float $upload, float $download) : void{ - $this->upload += $upload; - $this->download += $download; - } - public function getUpload() : float{ - return $this->upload; + $result = 0; + foreach($this->advancedInterfaces as $interface){ + $result += $interface->getBytesSent(); + } + return $result; } public function getDownload() : float{ - return $this->download; + $result = 0; + foreach($this->advancedInterfaces as $interface){ + $result += $interface->getBytesReceived(); + } + return $result; } public function resetStatistics() : void{ - $this->upload = 0; - $this->download = 0; + foreach($this->advancedInterfaces as $interface){ + $interface->resetTrafficStats(); + } } /** diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 70b30033e7..3565dc825e 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -77,6 +77,11 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ /** @var SleeperNotifier */ private $sleeper; + /** @var int */ + private $sendBytes = 0; + /** @var int */ + private $receiveBytes = 0; + public function __construct(Server $server){ $this->server = $server; @@ -221,7 +226,8 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ public function handleOption(string $option, string $value) : void{ if($option === "bandwidth"){ $v = unserialize($value); - $this->network->addStatistics($v["up"], $v["down"]); + $this->sendBytes = $v["up"]; + $this->receiveBytes = $v["down"]; } } @@ -243,4 +249,16 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $this->sessions[$sessionId]->updatePing($pingMS); } } + + public function getBytesSent() : int{ + return $this->sendBytes; + } + + public function getBytesReceived() : int{ + return $this->receiveBytes; + } + + public function resetTrafficStats() : void{ + $this->sendBytes = $this->receiveBytes = 0; + } } From 86cc151e6064ff709793a82048628832afba799c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Apr 2019 15:45:03 -0400 Subject: [PATCH 0758/3224] Revert "Network: Each interface now keeps its own statistics" This reverts commit 7720a0534e3c4f0dcc70cf3fbc12699de6f04374. --- .../network/AdvancedNetworkInterface.php | 19 -------------- src/pocketmine/network/Network.php | 25 +++++++++---------- .../network/mcpe/RakLibInterface.php | 20 +-------------- 3 files changed, 13 insertions(+), 51 deletions(-) diff --git a/src/pocketmine/network/AdvancedNetworkInterface.php b/src/pocketmine/network/AdvancedNetworkInterface.php index 1e54275b23..42c1ef62d5 100644 --- a/src/pocketmine/network/AdvancedNetworkInterface.php +++ b/src/pocketmine/network/AdvancedNetworkInterface.php @@ -68,23 +68,4 @@ interface AdvancedNetworkInterface extends NetworkInterface{ * @param string $regex */ public function addRawPacketFilter(string $regex) : void; - - /** - * Returns the number of bytes sent on this network interface since the last statistics reset. - * - * @return int - */ - public function getBytesSent() : int; - - /** - * Returns the number of bytes received on this network interface since the last statistics reset. - * - * @return int - */ - public function getBytesReceived() : int; - - /** - * Resets the upload/download statistics to zero. - */ - public function resetTrafficStats() : void; } diff --git a/src/pocketmine/network/Network.php b/src/pocketmine/network/Network.php index 654ff40700..a1e872cb31 100644 --- a/src/pocketmine/network/Network.php +++ b/src/pocketmine/network/Network.php @@ -49,6 +49,9 @@ class Network{ /** @var int[] */ private $bannedIps = []; + private $upload = 0; + private $download = 0; + /** @var string */ private $name; @@ -64,26 +67,22 @@ class Network{ $this->logger = $logger; } + public function addStatistics(float $upload, float $download) : void{ + $this->upload += $upload; + $this->download += $download; + } + public function getUpload() : float{ - $result = 0; - foreach($this->advancedInterfaces as $interface){ - $result += $interface->getBytesSent(); - } - return $result; + return $this->upload; } public function getDownload() : float{ - $result = 0; - foreach($this->advancedInterfaces as $interface){ - $result += $interface->getBytesReceived(); - } - return $result; + return $this->download; } public function resetStatistics() : void{ - foreach($this->advancedInterfaces as $interface){ - $interface->resetTrafficStats(); - } + $this->upload = 0; + $this->download = 0; } /** diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 3565dc825e..70b30033e7 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -77,11 +77,6 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ /** @var SleeperNotifier */ private $sleeper; - /** @var int */ - private $sendBytes = 0; - /** @var int */ - private $receiveBytes = 0; - public function __construct(Server $server){ $this->server = $server; @@ -226,8 +221,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ public function handleOption(string $option, string $value) : void{ if($option === "bandwidth"){ $v = unserialize($value); - $this->sendBytes = $v["up"]; - $this->receiveBytes = $v["down"]; + $this->network->addStatistics($v["up"], $v["down"]); } } @@ -249,16 +243,4 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $this->sessions[$sessionId]->updatePing($pingMS); } } - - public function getBytesSent() : int{ - return $this->sendBytes; - } - - public function getBytesReceived() : int{ - return $this->receiveBytes; - } - - public function resetTrafficStats() : void{ - $this->sendBytes = $this->receiveBytes = 0; - } } From ffb0ed80a26ad79c8c6f893ebe583933aeefee68 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 22 Apr 2019 22:29:54 +0100 Subject: [PATCH 0759/3224] resync RakLib dependency --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 4c7bc9167b..85476965be 100644 --- a/composer.lock +++ b/composer.lock @@ -413,12 +413,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "34a7600d6b4124ecbbc1654cb2dab0d1342a5622" + "reference": "a0be471c23bf5d896c8ed394b1c7a377c86cde71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/34a7600d6b4124ecbbc1654cb2dab0d1342a5622", - "reference": "34a7600d6b4124ecbbc1654cb2dab0d1342a5622", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/a0be471c23bf5d896c8ed394b1c7a377c86cde71", + "reference": "a0be471c23bf5d896c8ed394b1c7a377c86cde71", "shasum": "" }, "require": { @@ -446,7 +446,7 @@ "source": "https://github.com/pmmp/RakLib/tree/master", "issues": "https://github.com/pmmp/RakLib/issues" }, - "time": "2019-04-21T13:19:16+00:00" + "time": "2019-04-22T19:12:20+00:00" }, { "name": "pocketmine/snooze", From a3dea09e2abe08d24da050fdbb27ee5912d2342c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 25 Apr 2019 15:19:15 +0100 Subject: [PATCH 0760/3224] sync with latest codegen changes --- .../network/mcpe/protocol/PacketPool.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/PacketPool.php b/src/pocketmine/network/mcpe/protocol/PacketPool.php index 58e22900b2..992da8f962 100644 --- a/src/pocketmine/network/mcpe/protocol/PacketPool.php +++ b/src/pocketmine/network/mcpe/protocol/PacketPool.php @@ -27,7 +27,7 @@ use pocketmine\utils\Binary; use pocketmine\utils\BinaryDataException; class PacketPool{ - /** @var \SplFixedArray */ + /** @var \SplFixedArray */ protected static $pool = null; public static function init() : void{ @@ -159,28 +159,28 @@ class PacketPool{ } /** - * @param DataPacket $packet + * @param Packet $packet */ - public static function registerPacket(DataPacket $packet) : void{ + public static function registerPacket(Packet $packet) : void{ static::$pool[$packet->pid()] = clone $packet; } /** * @param int $pid * - * @return DataPacket + * @return Packet */ - public static function getPacketById(int $pid) : DataPacket{ + public static function getPacketById(int $pid) : Packet{ return isset(static::$pool[$pid]) ? clone static::$pool[$pid] : new UnknownPacket(); } /** * @param string $buffer * - * @return DataPacket + * @return Packet * @throws BinaryDataException */ - public static function getPacket(string $buffer) : DataPacket{ + public static function getPacket(string $buffer) : Packet{ $offset = 0; $pk = static::getPacketById(Binary::readUnsignedVarInt($buffer, $offset)); $pk->setBuffer($buffer, $offset); From 6aa827653230ace3fd122749724ed2c1aac2b65e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Apr 2019 15:41:19 +0100 Subject: [PATCH 0761/3224] Revert "Player: removed useless addActionBarMessage()" This reverts commit 7d22b2a6d7d372a5020b9a2b44a93cdc821565c8. --- src/pocketmine/Player.php | 9 +++++++++ src/pocketmine/command/defaults/TitleCommand.php | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 90194a3ffe..8ac2816c2a 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2279,6 +2279,15 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->sendTitleText($subtitle, SetTitlePacket::TYPE_SET_SUBTITLE); } + /** + * Adds small text to the user's screen. + * + * @param string $message + */ + public function addActionBarMessage(string $message){ + $this->sendTitleText($message, SetTitlePacket::TYPE_SET_ACTIONBAR_MESSAGE); + } + /** * Removes the title from the client's screen. */ diff --git a/src/pocketmine/command/defaults/TitleCommand.php b/src/pocketmine/command/defaults/TitleCommand.php index 6a49ec5442..667eeee082 100644 --- a/src/pocketmine/command/defaults/TitleCommand.php +++ b/src/pocketmine/command/defaults/TitleCommand.php @@ -82,7 +82,7 @@ class TitleCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $player->sendTip(implode(" ", array_slice($args, 2))); + $player->addActionBarMessage(implode(" ", array_slice($args, 2))); break; case "times": if(count($args) < 5){ From 7c7f42eba6f6cc3ad7425de575060e925ce7a9a9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Apr 2019 18:01:40 +0100 Subject: [PATCH 0762/3224] Added API method to get & set autosave interval --- src/pocketmine/level/LevelManager.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/pocketmine/level/LevelManager.php b/src/pocketmine/level/LevelManager.php index 2ec9322c23..4210224c5f 100644 --- a/src/pocketmine/level/LevelManager.php +++ b/src/pocketmine/level/LevelManager.php @@ -405,6 +405,25 @@ class LevelManager{ } } + /** + * Returns the period after which loaded worlds will be automatically saved to disk. + * + * @return int + */ + public function getAutoSaveTicks() : int{ + return $this->autoSaveTicks; + } + + /** + * @param int $autoSaveTicks + */ + public function setAutoSaveTicks(int $autoSaveTicks) : void{ + if($autoSaveTicks <= 0){ + throw new \InvalidArgumentException("Autosave ticks must be positive"); + } + $this->autoSaveTicks = $autoSaveTicks; + } + private function doAutoSave() : void{ Timings::$worldSaveTimer->startTiming(); foreach($this->levels as $level){ From 854c3a816ccbca4e511970eebcea2631a6c958a1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Apr 2019 18:05:34 +0100 Subject: [PATCH 0763/3224] LevelManager::generateLevel(): avoid multiple return points this could cause unexpected results if additional code is added after background generation in the future. --- src/pocketmine/level/LevelManager.php | 40 +++++++++++++-------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/pocketmine/level/LevelManager.php b/src/pocketmine/level/LevelManager.php index 4210224c5f..9581e780ce 100644 --- a/src/pocketmine/level/LevelManager.php +++ b/src/pocketmine/level/LevelManager.php @@ -292,33 +292,31 @@ class LevelManager{ (new LevelLoadEvent($level))->call(); - if(!$backgroundGeneration){ - return true; - } + if($backgroundGeneration){ + $this->server->getLogger()->notice($this->server->getLanguage()->translateString("pocketmine.level.backgroundGeneration", [$name])); - $this->server->getLogger()->notice($this->server->getLanguage()->translateString("pocketmine.level.backgroundGeneration", [$name])); + $spawnLocation = $level->getSpawnLocation(); + $centerX = $spawnLocation->getFloorX() >> 4; + $centerZ = $spawnLocation->getFloorZ() >> 4; - $spawnLocation = $level->getSpawnLocation(); - $centerX = $spawnLocation->getFloorX() >> 4; - $centerZ = $spawnLocation->getFloorZ() >> 4; + $order = []; - $order = []; - - for($X = -3; $X <= 3; ++$X){ - for($Z = -3; $Z <= 3; ++$Z){ - $distance = $X ** 2 + $Z ** 2; - $chunkX = $X + $centerX; - $chunkZ = $Z + $centerZ; - $index = Level::chunkHash($chunkX, $chunkZ); - $order[$index] = $distance; + for($X = -3; $X <= 3; ++$X){ + for($Z = -3; $Z <= 3; ++$Z){ + $distance = $X ** 2 + $Z ** 2; + $chunkX = $X + $centerX; + $chunkZ = $Z + $centerZ; + $index = Level::chunkHash($chunkX, $chunkZ); + $order[$index] = $distance; + } } - } - asort($order); + asort($order); - foreach($order as $index => $distance){ - Level::getXZ($index, $chunkX, $chunkZ); - $level->populateChunk($chunkX, $chunkZ, true); + foreach($order as $index => $distance){ + Level::getXZ($index, $chunkX, $chunkZ); + $level->populateChunk($chunkX, $chunkZ, true); + } } return true; From ea8c7230922fd3fcf542842d75b11afbd438aa2c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Apr 2019 18:15:31 +0100 Subject: [PATCH 0764/3224] EntityFactory: added some documentation --- src/pocketmine/entity/EntityFactory.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/pocketmine/entity/EntityFactory.php b/src/pocketmine/entity/EntityFactory.php index deca79678c..467bc36256 100644 --- a/src/pocketmine/entity/EntityFactory.php +++ b/src/pocketmine/entity/EntityFactory.php @@ -51,6 +51,14 @@ use function in_array; use function is_a; use function reset; +/** + * This class manages the creation of entities loaded from disk (and optionally entities created at runtime). + * + * You need to register your entity class into this factory if: + * a) you want to load/save your entity on disk (saving with chunks) + * b) you want to allow custom things to provide a custom class for your entity. Note that you must use + * create(MyEntity::class) instead of `new MyEntity()` if you want to allow this. + */ final class EntityFactory{ private static $entityCount = 1; From 854a2f5135f0a3f4580de2966f143246f85f3081 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Apr 2019 18:52:38 +0100 Subject: [PATCH 0765/3224] Move a giant heap of network garbage out of Entity --- src/pocketmine/Player.php | 15 +- src/pocketmine/entity/Animal.php | 4 +- src/pocketmine/entity/DataPropertyManager.php | 37 ++- src/pocketmine/entity/Entity.php | 308 +++--------------- src/pocketmine/entity/Human.php | 13 +- src/pocketmine/entity/Living.php | 22 +- src/pocketmine/entity/Villager.php | 8 +- src/pocketmine/entity/WaterAnimal.php | 3 +- .../entity/object/ExperienceOrb.php | 5 +- src/pocketmine/entity/object/FallingBlock.php | 3 +- src/pocketmine/entity/object/PrimedTNT.php | 8 +- src/pocketmine/entity/projectile/Arrow.php | 5 +- .../entity/projectile/SplashPotion.php | 10 +- .../level/particle/FloatingTextParticle.php | 10 +- .../network/mcpe/NetworkBinaryStream.php | 38 +-- .../protocol/types/EntityMetadataFlags.php | 120 +++++++ .../types/EntityMetadataProperties.php | 143 ++++++++ .../protocol/types/EntityMetadataTypes.php | 41 +++ .../protocol/types/PlayerMetadataFlags.php | 34 ++ 19 files changed, 488 insertions(+), 339 deletions(-) create mode 100644 src/pocketmine/network/mcpe/protocol/types/EntityMetadataFlags.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/EntityMetadataProperties.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/EntityMetadataTypes.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/PlayerMetadataFlags.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 8ac2816c2a..942329b304 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -104,6 +104,9 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\SetTitlePacket; use pocketmine\network\mcpe\protocol\types\ContainerIds; +use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; +use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; +use pocketmine\network\mcpe\protocol\types\PlayerMetadataFlags; use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissionAttachment; use pocketmine\permission\PermissionAttachmentInfo; @@ -877,12 +880,12 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool */ public function isUsingItem() : bool{ - return $this->getGenericFlag(self::DATA_FLAG_ACTION) and $this->startAction > -1; + return $this->getGenericFlag(EntityMetadataFlags::ACTION) and $this->startAction > -1; } public function setUsingItem(bool $value){ $this->startAction = $value ? $this->server->getTick() : -1; - $this->setGenericFlag(self::DATA_FLAG_ACTION, $value); + $this->setGenericFlag(EntityMetadataFlags::ACTION, $value); } /** @@ -1197,8 +1200,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->sleeping = clone $pos; - $this->propertyManager->setBlockPos(self::DATA_PLAYER_BED_POSITION, $pos); - $this->setPlayerFlag(self::DATA_PLAYER_FLAG_SLEEP, true); + $this->propertyManager->setBlockPos(EntityMetadataProperties::PLAYER_BED_POSITION, $pos); + $this->setPlayerFlag(PlayerMetadataFlags::SLEEP, true); $this->setSpawn($pos); @@ -1216,8 +1219,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, (new PlayerBedLeaveEvent($this, $b))->call(); $this->sleeping = null; - $this->propertyManager->setBlockPos(self::DATA_PLAYER_BED_POSITION, null); - $this->setPlayerFlag(self::DATA_PLAYER_FLAG_SLEEP, false); + $this->propertyManager->setBlockPos(EntityMetadataProperties::PLAYER_BED_POSITION, null); + $this->setPlayerFlag(PlayerMetadataFlags::SLEEP, false); $this->level->setSleepTicks(0); diff --git a/src/pocketmine/entity/Animal.php b/src/pocketmine/entity/Animal.php index 5474c39ca7..d651057e82 100644 --- a/src/pocketmine/entity/Animal.php +++ b/src/pocketmine/entity/Animal.php @@ -24,9 +24,11 @@ declare(strict_types=1); namespace pocketmine\entity; +use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; + abstract class Animal extends Creature implements Ageable{ public function isBaby() : bool{ - return $this->getGenericFlag(self::DATA_FLAG_BABY); + return $this->getGenericFlag(EntityMetadataFlags::BABY); } } diff --git a/src/pocketmine/entity/DataPropertyManager.php b/src/pocketmine/entity/DataPropertyManager.php index c8646132f1..96014e7988 100644 --- a/src/pocketmine/entity/DataPropertyManager.php +++ b/src/pocketmine/entity/DataPropertyManager.php @@ -25,6 +25,7 @@ namespace pocketmine\entity; use pocketmine\item\Item; use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\types\EntityMetadataTypes; use function assert; use function is_float; use function is_int; @@ -46,7 +47,7 @@ class DataPropertyManager{ * @return int|null */ public function getByte(int $key) : ?int{ - $value = $this->getPropertyValue($key, Entity::DATA_TYPE_BYTE); + $value = $this->getPropertyValue($key, EntityMetadataTypes::BYTE); assert(is_int($value) or $value === null); return $value; } @@ -57,7 +58,7 @@ class DataPropertyManager{ * @param bool $force */ public function setByte(int $key, int $value, bool $force = false) : void{ - $this->setPropertyValue($key, Entity::DATA_TYPE_BYTE, $value, $force); + $this->setPropertyValue($key, EntityMetadataTypes::BYTE, $value, $force); } /** @@ -66,7 +67,7 @@ class DataPropertyManager{ * @return int|null */ public function getShort(int $key) : ?int{ - $value = $this->getPropertyValue($key, Entity::DATA_TYPE_SHORT); + $value = $this->getPropertyValue($key, EntityMetadataTypes::SHORT); assert(is_int($value) or $value === null); return $value; } @@ -77,7 +78,7 @@ class DataPropertyManager{ * @param bool $force */ public function setShort(int $key, int $value, bool $force = false) : void{ - $this->setPropertyValue($key, Entity::DATA_TYPE_SHORT, $value, $force); + $this->setPropertyValue($key, EntityMetadataTypes::SHORT, $value, $force); } /** @@ -86,7 +87,7 @@ class DataPropertyManager{ * @return int|null */ public function getInt(int $key) : ?int{ - $value = $this->getPropertyValue($key, Entity::DATA_TYPE_INT); + $value = $this->getPropertyValue($key, EntityMetadataTypes::INT); assert(is_int($value) or $value === null); return $value; } @@ -97,7 +98,7 @@ class DataPropertyManager{ * @param bool $force */ public function setInt(int $key, int $value, bool $force = false) : void{ - $this->setPropertyValue($key, Entity::DATA_TYPE_INT, $value, $force); + $this->setPropertyValue($key, EntityMetadataTypes::INT, $value, $force); } /** @@ -106,7 +107,7 @@ class DataPropertyManager{ * @return float|null */ public function getFloat(int $key) : ?float{ - $value = $this->getPropertyValue($key, Entity::DATA_TYPE_FLOAT); + $value = $this->getPropertyValue($key, EntityMetadataTypes::FLOAT); assert(is_float($value) or $value === null); return $value; } @@ -117,7 +118,7 @@ class DataPropertyManager{ * @param bool $force */ public function setFloat(int $key, float $value, bool $force = false) : void{ - $this->setPropertyValue($key, Entity::DATA_TYPE_FLOAT, $value, $force); + $this->setPropertyValue($key, EntityMetadataTypes::FLOAT, $value, $force); } /** @@ -126,7 +127,7 @@ class DataPropertyManager{ * @return null|string */ public function getString(int $key) : ?string{ - $value = $this->getPropertyValue($key, Entity::DATA_TYPE_STRING); + $value = $this->getPropertyValue($key, EntityMetadataTypes::STRING); assert(is_string($value) or $value === null); return $value; } @@ -137,7 +138,7 @@ class DataPropertyManager{ * @param bool $force */ public function setString(int $key, string $value, bool $force = false) : void{ - $this->setPropertyValue($key, Entity::DATA_TYPE_STRING, $value, $force); + $this->setPropertyValue($key, EntityMetadataTypes::STRING, $value, $force); } /** @@ -146,7 +147,7 @@ class DataPropertyManager{ * @return null|Item */ public function getItem(int $key) : ?Item{ - $value = $this->getPropertyValue($key, Entity::DATA_TYPE_SLOT); + $value = $this->getPropertyValue($key, EntityMetadataTypes::SLOT); assert($value instanceof Item or $value === null); return $value; @@ -158,7 +159,7 @@ class DataPropertyManager{ * @param bool $force */ public function setItem(int $key, Item $value, bool $force = false) : void{ - $this->setPropertyValue($key, Entity::DATA_TYPE_SLOT, $value, $force); + $this->setPropertyValue($key, EntityMetadataTypes::SLOT, $value, $force); } /** @@ -167,7 +168,7 @@ class DataPropertyManager{ * @return null|Vector3 */ public function getBlockPos(int $key) : ?Vector3{ - $value = $this->getPropertyValue($key, Entity::DATA_TYPE_POS); + $value = $this->getPropertyValue($key, EntityMetadataTypes::POS); assert($value instanceof Vector3 or $value === null); return $value; } @@ -178,7 +179,7 @@ class DataPropertyManager{ * @param bool $force */ public function setBlockPos(int $key, ?Vector3 $value, bool $force = false) : void{ - $this->setPropertyValue($key, Entity::DATA_TYPE_POS, $value ? $value->floor() : null, $force); + $this->setPropertyValue($key, EntityMetadataTypes::POS, $value ? $value->floor() : null, $force); } /** @@ -187,7 +188,7 @@ class DataPropertyManager{ * @return int|null */ public function getLong(int $key) : ?int{ - $value = $this->getPropertyValue($key, Entity::DATA_TYPE_LONG); + $value = $this->getPropertyValue($key, EntityMetadataTypes::LONG); assert(is_int($value) or $value === null); return $value; } @@ -198,7 +199,7 @@ class DataPropertyManager{ * @param bool $force */ public function setLong(int $key, int $value, bool $force = false) : void{ - $this->setPropertyValue($key, Entity::DATA_TYPE_LONG, $value, $force); + $this->setPropertyValue($key, EntityMetadataTypes::LONG, $value, $force); } /** @@ -207,7 +208,7 @@ class DataPropertyManager{ * @return null|Vector3 */ public function getVector3(int $key) : ?Vector3{ - $value = $this->getPropertyValue($key, Entity::DATA_TYPE_VECTOR3F); + $value = $this->getPropertyValue($key, EntityMetadataTypes::VECTOR3F); assert($value instanceof Vector3 or $value === null); return $value; } @@ -218,7 +219,7 @@ class DataPropertyManager{ * @param bool $force */ public function setVector3(int $key, ?Vector3 $value, bool $force = false) : void{ - $this->setPropertyValue($key, Entity::DATA_TYPE_VECTOR3F, $value ? $value->asVector3() : null, $force); + $this->setPropertyValue($key, EntityMetadataTypes::VECTOR3F, $value ? $value->asVector3() : null, $force); } /** diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 9eb1d7c157..8cb9d5ab48 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -58,6 +58,9 @@ use pocketmine\network\mcpe\protocol\MoveEntityAbsolutePacket; use pocketmine\network\mcpe\protocol\RemoveEntityPacket; use pocketmine\network\mcpe\protocol\SetEntityDataPacket; use pocketmine\network\mcpe\protocol\SetEntityMotionPacket; +use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; +use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; +use pocketmine\network\mcpe\protocol\types\EntityMetadataTypes; use pocketmine\Player; use pocketmine\plugin\Plugin; use pocketmine\Server; @@ -84,221 +87,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ public const NETWORK_ID = -1; - public const DATA_TYPE_BYTE = 0; - public const DATA_TYPE_SHORT = 1; - public const DATA_TYPE_INT = 2; - public const DATA_TYPE_FLOAT = 3; - public const DATA_TYPE_STRING = 4; - public const DATA_TYPE_SLOT = 5; - public const DATA_TYPE_POS = 6; - public const DATA_TYPE_LONG = 7; - public const DATA_TYPE_VECTOR3F = 8; - - /* - * Readers beware: this isn't a nice list. Some of the properties have different types for different entities, and - * are used for entirely different things. - */ - public const DATA_FLAGS = 0; - public const DATA_HEALTH = 1; //int (minecart/boat) - public const DATA_VARIANT = 2; //int - public const DATA_COLOR = 3, DATA_COLOUR = 3; //byte - public const DATA_NAMETAG = 4; //string - public const DATA_OWNER_EID = 5; //long - public const DATA_TARGET_EID = 6; //long - public const DATA_AIR = 7; //short - public const DATA_POTION_COLOR = 8; //int (ARGB!) - public const DATA_POTION_AMBIENT = 9; //byte - /* 10 (byte) */ - public const DATA_HURT_TIME = 11; //int (minecart/boat) - public const DATA_HURT_DIRECTION = 12; //int (minecart/boat) - public const DATA_PADDLE_TIME_LEFT = 13; //float - public const DATA_PADDLE_TIME_RIGHT = 14; //float - public const DATA_EXPERIENCE_VALUE = 15; //int (xp orb) - public const DATA_MINECART_DISPLAY_BLOCK = 16; //int (id | (data << 16)) - public const DATA_HORSE_FLAGS = 16; //int - /* 16 (byte) used by wither skull */ - public const DATA_MINECART_DISPLAY_OFFSET = 17; //int - public const DATA_SHOOTER_ID = 17; //long (used by arrows) - public const DATA_MINECART_HAS_DISPLAY = 18; //byte (must be 1 for minecart to show block inside) - public const DATA_HORSE_TYPE = 19; //byte - /* 20 (unknown) - * 21 (unknown) */ - public const DATA_CHARGE_AMOUNT = 22; //int8, used for ghasts and also crossbow charging - public const DATA_ENDERMAN_HELD_ITEM_ID = 23; //short - public const DATA_ENTITY_AGE = 24; //short - /* 25 (int) used by horse, (byte) used by witch */ - public const DATA_PLAYER_FLAGS = 26; //byte - public const DATA_PLAYER_INDEX = 27; //int, used for marker colours and agent nametag colours - public const DATA_PLAYER_BED_POSITION = 28; //blockpos - public const DATA_FIREBALL_POWER_X = 29; //float - public const DATA_FIREBALL_POWER_Y = 30; - public const DATA_FIREBALL_POWER_Z = 31; - /* 32 (unknown) - * 33 (float) fishing bobber - * 34 (float) fishing bobber - * 35 (float) fishing bobber */ - public const DATA_POTION_AUX_VALUE = 36; //short - public const DATA_LEAD_HOLDER_EID = 37; //long - public const DATA_SCALE = 38; //float - public const DATA_HAS_NPC_COMPONENT = 39; //byte (???) - public const DATA_SKIN_ID = 40; //string - public const DATA_NPC_SKIN_ID = 41; //string - public const DATA_URL_TAG = 42; //string - public const DATA_MAX_AIR = 43; //short - public const DATA_MARK_VARIANT = 44; //int - public const DATA_CONTAINER_TYPE = 45; //byte (ContainerComponent) - public const DATA_CONTAINER_BASE_SIZE = 46; //int (ContainerComponent) - public const DATA_CONTAINER_EXTRA_SLOTS_PER_STRENGTH = 47; //int (used for llamas, inventory size is baseSize + thisProp * strength) - public const DATA_BLOCK_TARGET = 48; //block coords (ender crystal) - public const DATA_WITHER_INVULNERABLE_TICKS = 49; //int - public const DATA_WITHER_TARGET_1 = 50; //long - public const DATA_WITHER_TARGET_2 = 51; //long - public const DATA_WITHER_TARGET_3 = 52; //long - /* 53 (short) */ - public const DATA_BOUNDING_BOX_WIDTH = 54; //float - public const DATA_BOUNDING_BOX_HEIGHT = 55; //float - public const DATA_FUSE_LENGTH = 56; //int - public const DATA_RIDER_SEAT_POSITION = 57; //vector3f - public const DATA_RIDER_ROTATION_LOCKED = 58; //byte - public const DATA_RIDER_MAX_ROTATION = 59; //float - public const DATA_RIDER_MIN_ROTATION = 60; //float - public const DATA_AREA_EFFECT_CLOUD_RADIUS = 61; //float - public const DATA_AREA_EFFECT_CLOUD_WAITING = 62; //int - public const DATA_AREA_EFFECT_CLOUD_PARTICLE_ID = 63; //int - /* 64 (int) shulker-related */ - public const DATA_SHULKER_ATTACH_FACE = 65; //byte - /* 66 (short) shulker-related */ - public const DATA_SHULKER_ATTACH_POS = 67; //block coords - public const DATA_TRADING_PLAYER_EID = 68; //long - - /* 70 (byte) command-block */ - public const DATA_COMMAND_BLOCK_COMMAND = 71; //string - public const DATA_COMMAND_BLOCK_LAST_OUTPUT = 72; //string - public const DATA_COMMAND_BLOCK_TRACK_OUTPUT = 73; //byte - public const DATA_CONTROLLING_RIDER_SEAT_NUMBER = 74; //byte - public const DATA_STRENGTH = 75; //int - public const DATA_MAX_STRENGTH = 76; //int - /* 77 (int) */ - public const DATA_LIMITED_LIFE = 78; - public const DATA_ARMOR_STAND_POSE_INDEX = 79; //int - public const DATA_ENDER_CRYSTAL_TIME_OFFSET = 80; //int - public const DATA_ALWAYS_SHOW_NAMETAG = 81; //byte: -1 = default, 0 = only when looked at, 1 = always - public const DATA_COLOR_2 = 82; //byte - /* 83 (unknown) */ - public const DATA_SCORE_TAG = 84; //string - public const DATA_BALLOON_ATTACHED_ENTITY = 85; //int64, entity unique ID of owner - public const DATA_PUFFERFISH_SIZE = 86; //byte - public const DATA_BOAT_BUBBLE_TIME = 87; //int (time in bubble column) - public const DATA_PLAYER_AGENT_EID = 88; //long - /* 89 (float) related to panda sitting - * 90 (float) related to panda sitting */ - public const DATA_EAT_COUNTER = 91; //int (used by pandas) - public const DATA_FLAGS2 = 92; //long (extended data flags) - /* 93 (float) related to panda lying down - * 94 (float) related to panda lying down */ - public const DATA_AREA_EFFECT_CLOUD_DURATION = 95; //int - public const DATA_AREA_EFFECT_CLOUD_SPAWN_TIME = 96; //int - public const DATA_AREA_EFFECT_CLOUD_RADIUS_PER_TICK = 97; //float, usually negative - public const DATA_AREA_EFFECT_CLOUD_RADIUS_CHANGE_ON_PICKUP = 98; //float - public const DATA_AREA_EFFECT_CLOUD_PICKUP_COUNT = 99; //int - public const DATA_INTERACTIVE_TAG = 100; //string (button text) - public const DATA_TRADE_TIER = 101; //int - public const DATA_MAX_TRADE_TIER = 102; //int - public const DATA_TRADE_XP = 103; //int - - public const DATA_FLAG_ONFIRE = 0; - public const DATA_FLAG_SNEAKING = 1; - public const DATA_FLAG_RIDING = 2; - public const DATA_FLAG_SPRINTING = 3; - public const DATA_FLAG_ACTION = 4; - public const DATA_FLAG_INVISIBLE = 5; - public const DATA_FLAG_TEMPTED = 6; - public const DATA_FLAG_INLOVE = 7; - public const DATA_FLAG_SADDLED = 8; - public const DATA_FLAG_POWERED = 9; - public const DATA_FLAG_IGNITED = 10; - public const DATA_FLAG_BABY = 11; - public const DATA_FLAG_CONVERTING = 12; - public const DATA_FLAG_CRITICAL = 13; - public const DATA_FLAG_CAN_SHOW_NAMETAG = 14; - public const DATA_FLAG_ALWAYS_SHOW_NAMETAG = 15; - public const DATA_FLAG_IMMOBILE = 16, DATA_FLAG_NO_AI = 16; - public const DATA_FLAG_SILENT = 17; - public const DATA_FLAG_WALLCLIMBING = 18; - public const DATA_FLAG_CAN_CLIMB = 19; - public const DATA_FLAG_SWIMMER = 20; - public const DATA_FLAG_CAN_FLY = 21; - public const DATA_FLAG_WALKER = 22; - public const DATA_FLAG_RESTING = 23; - public const DATA_FLAG_SITTING = 24; - public const DATA_FLAG_ANGRY = 25; - public const DATA_FLAG_INTERESTED = 26; - public const DATA_FLAG_CHARGED = 27; - public const DATA_FLAG_TAMED = 28; - public const DATA_FLAG_ORPHANED = 29; - public const DATA_FLAG_LEASHED = 30; - public const DATA_FLAG_SHEARED = 31; - public const DATA_FLAG_GLIDING = 32; - public const DATA_FLAG_ELDER = 33; - public const DATA_FLAG_MOVING = 34; - public const DATA_FLAG_BREATHING = 35; - public const DATA_FLAG_CHESTED = 36; - public const DATA_FLAG_STACKABLE = 37; - public const DATA_FLAG_SHOWBASE = 38; - public const DATA_FLAG_REARING = 39; - public const DATA_FLAG_VIBRATING = 40; - public const DATA_FLAG_IDLING = 41; - public const DATA_FLAG_EVOKER_SPELL = 42; - public const DATA_FLAG_CHARGE_ATTACK = 43; - public const DATA_FLAG_WASD_CONTROLLED = 44; - public const DATA_FLAG_CAN_POWER_JUMP = 45; - public const DATA_FLAG_LINGER = 46; - public const DATA_FLAG_HAS_COLLISION = 47; - public const DATA_FLAG_AFFECTED_BY_GRAVITY = 48; - public const DATA_FLAG_FIRE_IMMUNE = 49; - public const DATA_FLAG_DANCING = 50; - public const DATA_FLAG_ENCHANTED = 51; - public const DATA_FLAG_SHOW_TRIDENT_ROPE = 52; // tridents show an animated rope when enchanted with loyalty after they are thrown and return to their owner. To be combined with DATA_OWNER_EID - public const DATA_FLAG_CONTAINER_PRIVATE = 53; //inventory is private, doesn't drop contents when killed if true - public const DATA_FLAG_TRANSFORMING = 54; - public const DATA_FLAG_SPIN_ATTACK = 55; - public const DATA_FLAG_SWIMMING = 56; - public const DATA_FLAG_BRIBED = 57; //dolphins have this set when they go to find treasure for the player - public const DATA_FLAG_PREGNANT = 58; - public const DATA_FLAG_LAYING_EGG = 59; - public const DATA_FLAG_RIDER_CAN_PICK = 60; //??? - public const DATA_FLAG_TRANSITION_SITTING = 61; - public const DATA_FLAG_EATING = 62; - public const DATA_FLAG_LAYING_DOWN = 63; - public const DATA_FLAG_SNEEZING = 64; - public const DATA_FLAG_TRUSTING = 65; - public const DATA_FLAG_ROLLING = 66; - public const DATA_FLAG_SCARED = 67; - public const DATA_FLAG_IN_SCAFFOLDING = 68; - public const DATA_FLAG_OVER_SCAFFOLDING = 69; - public const DATA_FLAG_FALL_THROUGH_SCAFFOLDING = 70; - public const DATA_FLAG_BLOCKING = 71; //shield - public const DATA_FLAG_DISABLE_BLOCKING = 72; - //73 is set when a player is attacked while using shield, unclear on purpose - //74 related to shield usage, needs further investigation - public const DATA_FLAG_SLEEPING = 75; - //76 related to sleeping, unclear usage - public const DATA_FLAG_TRADE_INTEREST = 77; - public const DATA_FLAG_DOOR_BREAKER = 78; //... - public const DATA_FLAG_BREAKING_OBSTRUCTION = 79; - public const DATA_FLAG_DOOR_OPENER = 80; //... - public const DATA_FLAG_ILLAGER_CAPTAIN = 81; - public const DATA_FLAG_STUNNED = 82; - public const DATA_FLAG_ROARING = 83; - public const DATA_FLAG_DELAYED_ATTACKING = 84; - public const DATA_FLAG_AVOIDING_MOBS = 85; - //86 used by RangedAttackGoal - //87 used by NearestAttackableTargetGoal - - public const DATA_PLAYER_FLAG_SLEEP = 1; - public const DATA_PLAYER_FLAG_DEAD = 2; //TODO: CHECK - - /** * @var Player[] */ @@ -448,19 +236,19 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->propertyManager = new DataPropertyManager(); - $this->propertyManager->setLong(self::DATA_FLAGS, 0); - $this->propertyManager->setShort(self::DATA_MAX_AIR, 400); - $this->propertyManager->setString(self::DATA_NAMETAG, ""); - $this->propertyManager->setLong(self::DATA_LEAD_HOLDER_EID, -1); - $this->propertyManager->setFloat(self::DATA_SCALE, 1); - $this->propertyManager->setFloat(self::DATA_BOUNDING_BOX_WIDTH, $this->width); - $this->propertyManager->setFloat(self::DATA_BOUNDING_BOX_HEIGHT, $this->height); + $this->propertyManager->setLong(EntityMetadataProperties::FLAGS, 0); + $this->propertyManager->setShort(EntityMetadataProperties::MAX_AIR, 400); + $this->propertyManager->setString(EntityMetadataProperties::NAMETAG, ""); + $this->propertyManager->setLong(EntityMetadataProperties::LEAD_HOLDER_EID, -1); + $this->propertyManager->setFloat(EntityMetadataProperties::SCALE, 1); + $this->propertyManager->setFloat(EntityMetadataProperties::BOUNDING_BOX_WIDTH, $this->width); + $this->propertyManager->setFloat(EntityMetadataProperties::BOUNDING_BOX_HEIGHT, $this->height); $this->attributeMap = new AttributeMap(); $this->addAttributes(); - $this->setGenericFlag(self::DATA_FLAG_AFFECTED_BY_GRAVITY, true); - $this->setGenericFlag(self::DATA_FLAG_HAS_COLLISION, true); + $this->setGenericFlag(EntityMetadataFlags::AFFECTED_BY_GRAVITY, true); + $this->setGenericFlag(EntityMetadataFlags::HAS_COLLISION, true); $this->initEntity($nbt); $this->propertyManager->clearDirtyProperties(); //Prevents resending properties that were set during construction @@ -479,21 +267,21 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ * @return string */ public function getNameTag() : string{ - return $this->propertyManager->getString(self::DATA_NAMETAG); + return $this->propertyManager->getString(EntityMetadataProperties::NAMETAG); } /** * @return bool */ public function isNameTagVisible() : bool{ - return $this->getGenericFlag(self::DATA_FLAG_CAN_SHOW_NAMETAG); + return $this->getGenericFlag(EntityMetadataFlags::CAN_SHOW_NAMETAG); } /** * @return bool */ public function isNameTagAlwaysVisible() : bool{ - return $this->getGenericFlag(self::DATA_FLAG_ALWAYS_SHOW_NAMETAG); + return $this->getGenericFlag(EntityMetadataFlags::ALWAYS_SHOW_NAMETAG); } @@ -501,42 +289,42 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ * @param string $name */ public function setNameTag(string $name) : void{ - $this->propertyManager->setString(self::DATA_NAMETAG, $name); + $this->propertyManager->setString(EntityMetadataProperties::NAMETAG, $name); } /** * @param bool $value */ public function setNameTagVisible(bool $value = true) : void{ - $this->setGenericFlag(self::DATA_FLAG_CAN_SHOW_NAMETAG, $value); + $this->setGenericFlag(EntityMetadataFlags::CAN_SHOW_NAMETAG, $value); } /** * @param bool $value */ public function setNameTagAlwaysVisible(bool $value = true) : void{ - $this->propertyManager->setByte(self::DATA_ALWAYS_SHOW_NAMETAG, $value ? 1 : 0); + $this->propertyManager->setByte(EntityMetadataProperties::ALWAYS_SHOW_NAMETAG, $value ? 1 : 0); } /** * @return string|null */ public function getScoreTag() : ?string{ - return $this->propertyManager->getString(self::DATA_SCORE_TAG); + return $this->propertyManager->getString(EntityMetadataProperties::SCORE_TAG); } /** * @param string $score */ public function setScoreTag(string $score) : void{ - $this->propertyManager->setString(self::DATA_SCORE_TAG, $score); + $this->propertyManager->setString(EntityMetadataProperties::SCORE_TAG, $score); } /** * @return float */ public function getScale() : float{ - return $this->propertyManager->getFloat(self::DATA_SCALE); + return $this->propertyManager->getFloat(EntityMetadataProperties::SCALE); } /** @@ -554,7 +342,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->recalculateBoundingBox(); - $this->propertyManager->setFloat(self::DATA_SCALE, $value); + $this->propertyManager->setFloat(EntityMetadataProperties::SCALE, $value); } public function getBoundingBox() : AxisAlignedBB{ @@ -575,39 +363,39 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } public function isSneaking() : bool{ - return $this->getGenericFlag(self::DATA_FLAG_SNEAKING); + return $this->getGenericFlag(EntityMetadataFlags::SNEAKING); } public function setSneaking(bool $value = true) : void{ - $this->setGenericFlag(self::DATA_FLAG_SNEAKING, $value); + $this->setGenericFlag(EntityMetadataFlags::SNEAKING, $value); } public function isSprinting() : bool{ - return $this->getGenericFlag(self::DATA_FLAG_SPRINTING); + return $this->getGenericFlag(EntityMetadataFlags::SPRINTING); } public function setSprinting(bool $value = true) : void{ if($value !== $this->isSprinting()){ - $this->setGenericFlag(self::DATA_FLAG_SPRINTING, $value); + $this->setGenericFlag(EntityMetadataFlags::SPRINTING, $value); $attr = $this->attributeMap->getAttribute(Attribute::MOVEMENT_SPEED); $attr->setValue($value ? ($attr->getValue() * 1.3) : ($attr->getValue() / 1.3), false, true); } } public function isImmobile() : bool{ - return $this->getGenericFlag(self::DATA_FLAG_IMMOBILE); + return $this->getGenericFlag(EntityMetadataFlags::IMMOBILE); } public function setImmobile(bool $value = true) : void{ - $this->setGenericFlag(self::DATA_FLAG_IMMOBILE, $value); + $this->setGenericFlag(EntityMetadataFlags::IMMOBILE, $value); } public function isInvisible() : bool{ - return $this->getGenericFlag(self::DATA_FLAG_INVISIBLE); + return $this->getGenericFlag(EntityMetadataFlags::INVISIBLE); } public function setInvisible(bool $value = true) : void{ - $this->setGenericFlag(self::DATA_FLAG_INVISIBLE, $value); + $this->setGenericFlag(EntityMetadataFlags::INVISIBLE, $value); } /** @@ -615,7 +403,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ * @return bool */ public function canClimb() : bool{ - return $this->getGenericFlag(self::DATA_FLAG_CAN_CLIMB); + return $this->getGenericFlag(EntityMetadataFlags::CAN_CLIMB); } /** @@ -624,7 +412,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ * @param bool $value */ public function setCanClimb(bool $value = true) : void{ - $this->setGenericFlag(self::DATA_FLAG_CAN_CLIMB, $value); + $this->setGenericFlag(EntityMetadataFlags::CAN_CLIMB, $value); } /** @@ -633,7 +421,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ * @return bool */ public function canClimbWalls() : bool{ - return $this->getGenericFlag(self::DATA_FLAG_WALLCLIMBING); + return $this->getGenericFlag(EntityMetadataFlags::WALLCLIMBING); } /** @@ -642,7 +430,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ * @param bool $value */ public function setCanClimbWalls(bool $value = true) : void{ - $this->setGenericFlag(self::DATA_FLAG_WALLCLIMBING, $value); + $this->setGenericFlag(EntityMetadataFlags::WALLCLIMBING, $value); } /** @@ -650,7 +438,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ * @return int|null */ public function getOwningEntityId() : ?int{ - return $this->propertyManager->getLong(self::DATA_OWNER_EID); + return $this->propertyManager->getLong(EntityMetadataProperties::OWNER_EID); } /** @@ -675,11 +463,11 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ */ public function setOwningEntity(?Entity $owner) : void{ if($owner === null){ - $this->propertyManager->removeProperty(self::DATA_OWNER_EID); + $this->propertyManager->removeProperty(EntityMetadataProperties::OWNER_EID); }elseif($owner->closed){ throw new \InvalidArgumentException("Supplied owning entity is garbage and cannot be used"); }else{ - $this->propertyManager->setLong(self::DATA_OWNER_EID, $owner->getId()); + $this->propertyManager->setLong(EntityMetadataProperties::OWNER_EID, $owner->getId()); } } @@ -688,7 +476,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ * @return int|null */ public function getTargetEntityId() : ?int{ - return $this->propertyManager->getLong(self::DATA_TARGET_EID); + return $this->propertyManager->getLong(EntityMetadataProperties::TARGET_EID); } /** @@ -715,11 +503,11 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ */ public function setTargetEntity(?Entity $target) : void{ if($target === null){ - $this->propertyManager->removeProperty(self::DATA_TARGET_EID); + $this->propertyManager->removeProperty(EntityMetadataProperties::TARGET_EID); }elseif($target->closed){ throw new \InvalidArgumentException("Supplied target entity is garbage and cannot be used"); }else{ - $this->propertyManager->setLong(self::DATA_TARGET_EID, $target->getId()); + $this->propertyManager->setLong(EntityMetadataProperties::TARGET_EID, $target->getId()); } } @@ -771,7 +559,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $nbt->setFloat("FallDistance", $this->fallDistance); $nbt->setShort("Fire", $this->fireTicks); - $nbt->setShort("Air", $this->propertyManager->getShort(self::DATA_AIR)); + $nbt->setShort("Air", $this->propertyManager->getShort(EntityMetadataProperties::AIR)); $nbt->setByte("OnGround", $this->onGround ? 1 : 0); $nbt->setByte("Invulnerable", $this->invulnerable ? 1 : 0); @@ -781,10 +569,10 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ protected function initEntity(CompoundTag $nbt) : void{ $this->fireTicks = $nbt->getShort("Fire", 0); if($this->isOnFire()){ - $this->setGenericFlag(self::DATA_FLAG_ONFIRE); + $this->setGenericFlag(EntityMetadataFlags::ONFIRE); } - $this->propertyManager->setShort(self::DATA_AIR, $nbt->getShort("Air", 300)); + $this->propertyManager->setShort(EntityMetadataProperties::AIR, $nbt->getShort("Air", 300)); $this->onGround = $nbt->getByte("OnGround", 0) !== 0; $this->invulnerable = $nbt->getByte("Invulnerable", 0) !== 0; @@ -973,7 +761,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->setFireTicks($ticks); } - $this->setGenericFlag(self::DATA_FLAG_ONFIRE, true); + $this->setGenericFlag(EntityMetadataFlags::ONFIRE, true); } /** @@ -996,7 +784,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ public function extinguish() : void{ $this->fireTicks = 0; - $this->setGenericFlag(self::DATA_FLAG_ONFIRE, false); + $this->setGenericFlag(EntityMetadataFlags::ONFIRE, false); } public function isFireProof() : bool{ @@ -1949,7 +1737,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ * @param bool $value * @param int $propertyType */ - public function setDataFlag(int $propertyId, int $flagId, bool $value = true, int $propertyType = self::DATA_TYPE_LONG) : void{ + public function setDataFlag(int $propertyId, int $flagId, bool $value = true, int $propertyType = EntityMetadataTypes::LONG) : void{ if($this->getDataFlag($propertyId, $flagId) !== $value){ $flags = (int) $this->propertyManager->getPropertyValue($propertyId, $propertyType); $flags ^= 1 << $flagId; @@ -1975,7 +1763,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ * @return bool */ public function getGenericFlag(int $flagId) : bool{ - return $this->getDataFlag($flagId >= 64 ? self::DATA_FLAGS2 : self::DATA_FLAGS, $flagId % 64); + return $this->getDataFlag($flagId >= 64 ? EntityMetadataProperties::FLAGS2 : EntityMetadataProperties::FLAGS, $flagId % 64); } /** @@ -1985,7 +1773,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ * @param bool $value */ public function setGenericFlag(int $flagId, bool $value = true) : void{ - $this->setDataFlag($flagId >= 64 ? self::DATA_FLAGS2 : self::DATA_FLAGS, $flagId % 64, $value, self::DATA_TYPE_LONG); + $this->setDataFlag($flagId >= 64 ? EntityMetadataProperties::FLAGS2 : EntityMetadataProperties::FLAGS, $flagId % 64, $value, EntityMetadataTypes::LONG); } /** diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 443a1ffe45..f497ac6a3e 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -56,7 +56,10 @@ use pocketmine\network\mcpe\protocol\AddPlayerPacket; use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\PlayerSkinPacket; +use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; +use pocketmine\network\mcpe\protocol\types\EntityMetadataTypes; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; +use pocketmine\network\mcpe\protocol\types\PlayerMetadataFlags; use pocketmine\Player; use pocketmine\utils\UUID; use function array_filter; @@ -604,8 +607,8 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ protected function initEntity(CompoundTag $nbt) : void{ parent::initEntity($nbt); - $this->setPlayerFlag(self::DATA_PLAYER_FLAG_SLEEP, false); - $this->propertyManager->setBlockPos(self::DATA_PLAYER_BED_POSITION, null); + $this->setPlayerFlag(PlayerMetadataFlags::SLEEP, false); + $this->propertyManager->setBlockPos(EntityMetadataProperties::PLAYER_BED_POSITION, null); $this->inventory = new PlayerInventory($this); $this->enderChestInventory = new EnderChestInventory(); @@ -871,7 +874,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $player->sendDataPacket($pk); //TODO: Hack for MCPE 1.2.13: DATA_NAMETAG is useless in AddPlayerPacket, so it has to be sent separately - $this->sendData($player, [self::DATA_NAMETAG => [self::DATA_TYPE_STRING, $this->getNameTag()]]); + $this->sendData($player, [EntityMetadataProperties::NAMETAG => [EntityMetadataTypes::STRING, $this->getNameTag()]]); $this->armorInventory->sendContents($player); @@ -903,7 +906,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ * @return bool */ public function getPlayerFlag(int $flagId) : bool{ - return $this->getDataFlag(self::DATA_PLAYER_FLAGS, $flagId); + return $this->getDataFlag(EntityMetadataProperties::PLAYER_FLAGS, $flagId); } /** @@ -913,6 +916,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ * @param bool $value */ public function setPlayerFlag(int $flagId, bool $value = true) : void{ - $this->setDataFlag(self::DATA_PLAYER_FLAGS, $flagId, $value, self::DATA_TYPE_BYTE); + $this->setDataFlag(EntityMetadataProperties::PLAYER_FLAGS, $flagId, $value, EntityMetadataTypes::BYTE); } } diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 2b07024d9a..197dc68406 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -48,6 +48,8 @@ use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\MobEffectPacket; +use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; +use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; use pocketmine\Player; use pocketmine\timings\Timings; use pocketmine\utils\Binary; @@ -341,11 +343,11 @@ abstract class Living extends Entity implements Damageable{ } if(!empty($colors)){ - $this->propertyManager->setInt(Entity::DATA_POTION_COLOR, Color::mix(...$colors)->toARGB()); - $this->propertyManager->setByte(Entity::DATA_POTION_AMBIENT, $ambient ? 1 : 0); + $this->propertyManager->setInt(EntityMetadataProperties::POTION_COLOR, Color::mix(...$colors)->toARGB()); + $this->propertyManager->setByte(EntityMetadataProperties::POTION_AMBIENT, $ambient ? 1 : 0); }else{ - $this->propertyManager->setInt(Entity::DATA_POTION_COLOR, 0); - $this->propertyManager->setByte(Entity::DATA_POTION_AMBIENT, 0); + $this->propertyManager->setInt(EntityMetadataProperties::POTION_COLOR, 0); + $this->propertyManager->setByte(EntityMetadataProperties::POTION_AMBIENT, 0); } } @@ -769,7 +771,7 @@ abstract class Living extends Entity implements Damageable{ * @return bool */ public function isBreathing() : bool{ - return $this->getGenericFlag(self::DATA_FLAG_BREATHING); + return $this->getGenericFlag(EntityMetadataFlags::BREATHING); } /** @@ -779,7 +781,7 @@ abstract class Living extends Entity implements Damageable{ * @param bool $value */ public function setBreathing(bool $value = true) : void{ - $this->setGenericFlag(self::DATA_FLAG_BREATHING, $value); + $this->setGenericFlag(EntityMetadataFlags::BREATHING, $value); } /** @@ -789,7 +791,7 @@ abstract class Living extends Entity implements Damageable{ * @return int */ public function getAirSupplyTicks() : int{ - return $this->propertyManager->getShort(self::DATA_AIR); + return $this->propertyManager->getShort(EntityMetadataProperties::AIR); } /** @@ -798,7 +800,7 @@ abstract class Living extends Entity implements Damageable{ * @param int $ticks */ public function setAirSupplyTicks(int $ticks) : void{ - $this->propertyManager->setShort(self::DATA_AIR, $ticks); + $this->propertyManager->setShort(EntityMetadataProperties::AIR, $ticks); } /** @@ -806,7 +808,7 @@ abstract class Living extends Entity implements Damageable{ * @return int */ public function getMaxAirSupplyTicks() : int{ - return $this->propertyManager->getShort(self::DATA_MAX_AIR); + return $this->propertyManager->getShort(EntityMetadataProperties::MAX_AIR); } /** @@ -815,7 +817,7 @@ abstract class Living extends Entity implements Damageable{ * @param int $ticks */ public function setMaxAirSupplyTicks(int $ticks) : void{ - $this->propertyManager->setShort(self::DATA_MAX_AIR, $ticks); + $this->propertyManager->setShort(EntityMetadataProperties::MAX_AIR, $ticks); } /** diff --git a/src/pocketmine/entity/Villager.php b/src/pocketmine/entity/Villager.php index 52b0d1bdd4..836c817f59 100644 --- a/src/pocketmine/entity/Villager.php +++ b/src/pocketmine/entity/Villager.php @@ -24,6 +24,8 @@ declare(strict_types=1); namespace pocketmine\entity; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; +use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; class Villager extends Creature implements NPC, Ageable{ public const PROFESSION_FARMER = 0; @@ -67,14 +69,14 @@ class Villager extends Creature implements NPC, Ageable{ * @param int $profession */ public function setProfession(int $profession) : void{ - $this->propertyManager->setInt(self::DATA_VARIANT, $profession); + $this->propertyManager->setInt(EntityMetadataProperties::VARIANT, $profession); } public function getProfession() : int{ - return $this->propertyManager->getInt(self::DATA_VARIANT); + return $this->propertyManager->getInt(EntityMetadataProperties::VARIANT); } public function isBaby() : bool{ - return $this->getGenericFlag(self::DATA_FLAG_BABY); + return $this->getGenericFlag(EntityMetadataFlags::BABY); } } diff --git a/src/pocketmine/entity/WaterAnimal.php b/src/pocketmine/entity/WaterAnimal.php index 4bcc7d3b98..56c846465e 100644 --- a/src/pocketmine/entity/WaterAnimal.php +++ b/src/pocketmine/entity/WaterAnimal.php @@ -24,11 +24,12 @@ declare(strict_types=1); namespace pocketmine\entity; use pocketmine\event\entity\EntityDamageEvent; +use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; abstract class WaterAnimal extends Creature implements Ageable{ public function isBaby() : bool{ - return $this->getGenericFlag(self::DATA_FLAG_BABY); + return $this->getGenericFlag(EntityMetadataFlags::BABY); } public function canBreathe() : bool{ diff --git a/src/pocketmine/entity/object/ExperienceOrb.php b/src/pocketmine/entity/object/ExperienceOrb.php index 1cb3ad5f94..c0141bae24 100644 --- a/src/pocketmine/entity/object/ExperienceOrb.php +++ b/src/pocketmine/entity/object/ExperienceOrb.php @@ -28,6 +28,7 @@ use pocketmine\entity\Human; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ShortTag; +use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; use pocketmine\Player; use function sqrt; @@ -132,14 +133,14 @@ class ExperienceOrb extends Entity{ } public function getXpValue() : int{ - return $this->propertyManager->getInt(self::DATA_EXPERIENCE_VALUE) ?? 0; + return $this->propertyManager->getInt(EntityMetadataProperties::EXPERIENCE_VALUE) ?? 0; } public function setXpValue(int $amount) : void{ if($amount <= 0){ throw new \InvalidArgumentException("XP amount must be greater than 0, got $amount"); } - $this->propertyManager->setInt(self::DATA_EXPERIENCE_VALUE, $amount); + $this->propertyManager->setInt(EntityMetadataProperties::EXPERIENCE_VALUE, $amount); } public function hasTargetPlayer() : bool{ diff --git a/src/pocketmine/entity/object/FallingBlock.php b/src/pocketmine/entity/object/FallingBlock.php index 4016ceed7f..c22e849087 100644 --- a/src/pocketmine/entity/object/FallingBlock.php +++ b/src/pocketmine/entity/object/FallingBlock.php @@ -32,6 +32,7 @@ use pocketmine\event\entity\EntityDamageEvent; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; +use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; use function get_class; class FallingBlock extends Entity{ @@ -70,7 +71,7 @@ class FallingBlock extends Entity{ $this->block = BlockFactory::get($blockId, $damage); - $this->propertyManager->setInt(self::DATA_VARIANT, $this->block->getRuntimeId()); + $this->propertyManager->setInt(EntityMetadataProperties::VARIANT, $this->block->getRuntimeId()); } public function canCollideWith(Entity $entity) : bool{ diff --git a/src/pocketmine/entity/object/PrimedTNT.php b/src/pocketmine/entity/object/PrimedTNT.php index ec2b2da97b..92fc9870bd 100644 --- a/src/pocketmine/entity/object/PrimedTNT.php +++ b/src/pocketmine/entity/object/PrimedTNT.php @@ -31,6 +31,8 @@ use pocketmine\level\Explosion; use pocketmine\level\sound\IgniteSound; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ShortTag; +use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; +use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; class PrimedTNT extends Entity implements Explosive{ public const NETWORK_ID = self::TNT; @@ -63,8 +65,8 @@ class PrimedTNT extends Entity implements Explosive{ $this->fuse = 80; } - $this->setGenericFlag(self::DATA_FLAG_IGNITED, true); - $this->propertyManager->setInt(self::DATA_FUSE_LENGTH, $this->fuse); + $this->setGenericFlag(EntityMetadataFlags::IGNITED, true); + $this->propertyManager->setInt(EntityMetadataProperties::FUSE_LENGTH, $this->fuse); $this->level->addSound($this, new IgniteSound()); } @@ -89,7 +91,7 @@ class PrimedTNT extends Entity implements Explosive{ $hasUpdate = parent::entityBaseTick($tickDiff); if($this->fuse % 5 === 0){ //don't spam it every tick, it's not necessary - $this->propertyManager->setInt(self::DATA_FUSE_LENGTH, $this->fuse); + $this->propertyManager->setInt(EntityMetadataProperties::FUSE_LENGTH, $this->fuse); } if(!$this->isFlaggedForDespawn()){ diff --git a/src/pocketmine/entity/projectile/Arrow.php b/src/pocketmine/entity/projectile/Arrow.php index dda7b92178..e20c679a64 100644 --- a/src/pocketmine/entity/projectile/Arrow.php +++ b/src/pocketmine/entity/projectile/Arrow.php @@ -35,6 +35,7 @@ use pocketmine\math\RayTraceResult; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\TakeItemEntityPacket; +use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; use pocketmine\Player; use function mt_rand; use function sqrt; @@ -86,11 +87,11 @@ class Arrow extends Projectile{ } public function isCritical() : bool{ - return $this->getGenericFlag(self::DATA_FLAG_CRITICAL); + return $this->getGenericFlag(EntityMetadataFlags::CRITICAL); } public function setCritical(bool $value = true) : void{ - $this->setGenericFlag(self::DATA_FLAG_CRITICAL, $value); + $this->setGenericFlag(EntityMetadataFlags::CRITICAL, $value); } public function getResultDamage() : int{ diff --git a/src/pocketmine/entity/projectile/SplashPotion.php b/src/pocketmine/entity/projectile/SplashPotion.php index 0fb687d6a7..5c74c75693 100644 --- a/src/pocketmine/entity/projectile/SplashPotion.php +++ b/src/pocketmine/entity/projectile/SplashPotion.php @@ -35,6 +35,8 @@ use pocketmine\item\Potion; use pocketmine\level\particle\PotionSplashParticle; use pocketmine\level\sound\PotionSplashSound; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; +use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; use pocketmine\utils\Color; use function round; use function sqrt; @@ -136,14 +138,14 @@ class SplashPotion extends Throwable{ * @return int */ public function getPotionId() : int{ - return $this->propertyManager->getShort(self::DATA_POTION_AUX_VALUE) ?? 0; + return $this->propertyManager->getShort(EntityMetadataProperties::POTION_AUX_VALUE) ?? 0; } /** * @param int $id */ public function setPotionId(int $id) : void{ - $this->propertyManager->setShort(self::DATA_POTION_AUX_VALUE, $id); + $this->propertyManager->setShort(EntityMetadataProperties::POTION_AUX_VALUE, $id); } /** @@ -151,7 +153,7 @@ class SplashPotion extends Throwable{ * @return bool */ public function willLinger() : bool{ - return $this->getDataFlag(self::DATA_FLAGS, self::DATA_FLAG_LINGER); + return $this->getDataFlag(EntityMetadataProperties::FLAGS, EntityMetadataFlags::LINGER); } /** @@ -160,7 +162,7 @@ class SplashPotion extends Throwable{ * @param bool $value */ public function setLinger(bool $value = true) : void{ - $this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_LINGER, $value); + $this->setDataFlag(EntityMetadataProperties::FLAGS, EntityMetadataFlags::LINGER, $value); } /** diff --git a/src/pocketmine/level/particle/FloatingTextParticle.php b/src/pocketmine/level/particle/FloatingTextParticle.php index e800a1c74b..1eef46fd84 100644 --- a/src/pocketmine/level/particle/FloatingTextParticle.php +++ b/src/pocketmine/level/particle/FloatingTextParticle.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\level\particle; -use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; use pocketmine\entity\Skin; use pocketmine\item\ItemFactory; @@ -31,6 +30,9 @@ use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\AddPlayerPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\RemoveEntityPacket; +use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; +use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; +use pocketmine\network\mcpe\protocol\types\EntityMetadataTypes; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\utils\UUID; use function str_repeat; @@ -105,11 +107,11 @@ class FloatingTextParticle implements Particle{ $pk->item = ItemFactory::air(); $flags = ( - 1 << Entity::DATA_FLAG_IMMOBILE + 1 << EntityMetadataFlags::IMMOBILE ); $pk->metadata = [ - Entity::DATA_FLAGS => [Entity::DATA_TYPE_LONG, $flags], - Entity::DATA_SCALE => [Entity::DATA_TYPE_FLOAT, 0.01] //zero causes problems on debug builds + EntityMetadataProperties::FLAGS => [EntityMetadataTypes::LONG, $flags], + EntityMetadataProperties::SCALE => [EntityMetadataTypes::FLOAT, 0.01] //zero causes problems on debug builds ]; $p[] = $pk; diff --git a/src/pocketmine/network/mcpe/NetworkBinaryStream.php b/src/pocketmine/network/mcpe/NetworkBinaryStream.php index b0d75682ab..cbc0d75ee5 100644 --- a/src/pocketmine/network/mcpe/NetworkBinaryStream.php +++ b/src/pocketmine/network/mcpe/NetworkBinaryStream.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe; #include use pocketmine\entity\Attribute; -use pocketmine\entity\Entity; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\ItemIds; @@ -36,6 +35,7 @@ use pocketmine\nbt\TreeRoot; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\types\CommandOriginData; use pocketmine\network\mcpe\protocol\types\EntityLink; +use pocketmine\network\mcpe\protocol\types\EntityMetadataTypes; use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; use pocketmine\utils\UUID; @@ -177,32 +177,32 @@ class NetworkBinaryStream extends BinaryStream{ $type = $this->getUnsignedVarInt(); $value = null; switch($type){ - case Entity::DATA_TYPE_BYTE: + case EntityMetadataTypes::BYTE: $value = $this->getByte(); break; - case Entity::DATA_TYPE_SHORT: + case EntityMetadataTypes::SHORT: $value = $this->getSignedLShort(); break; - case Entity::DATA_TYPE_INT: + case EntityMetadataTypes::INT: $value = $this->getVarInt(); break; - case Entity::DATA_TYPE_FLOAT: + case EntityMetadataTypes::FLOAT: $value = $this->getLFloat(); break; - case Entity::DATA_TYPE_STRING: + case EntityMetadataTypes::STRING: $value = $this->getString(); break; - case Entity::DATA_TYPE_SLOT: + case EntityMetadataTypes::SLOT: $value = $this->getSlot(); break; - case Entity::DATA_TYPE_POS: + case EntityMetadataTypes::POS: $value = new Vector3(); $this->getSignedBlockPosition($value->x, $value->y, $value->z); break; - case Entity::DATA_TYPE_LONG: + case EntityMetadataTypes::LONG: $value = $this->getVarLong(); break; - case Entity::DATA_TYPE_VECTOR3F: + case EntityMetadataTypes::VECTOR3F: $value = $this->getVector3(); break; default: @@ -229,25 +229,25 @@ class NetworkBinaryStream extends BinaryStream{ $this->putUnsignedVarInt($key); //data key $this->putUnsignedVarInt($d[0]); //data type switch($d[0]){ - case Entity::DATA_TYPE_BYTE: + case EntityMetadataTypes::BYTE: $this->putByte($d[1]); break; - case Entity::DATA_TYPE_SHORT: + case EntityMetadataTypes::SHORT: $this->putLShort($d[1]); //SIGNED short! break; - case Entity::DATA_TYPE_INT: + case EntityMetadataTypes::INT: $this->putVarInt($d[1]); break; - case Entity::DATA_TYPE_FLOAT: + case EntityMetadataTypes::FLOAT: $this->putLFloat($d[1]); break; - case Entity::DATA_TYPE_STRING: + case EntityMetadataTypes::STRING: $this->putString($d[1]); break; - case Entity::DATA_TYPE_SLOT: + case EntityMetadataTypes::SLOT: $this->putSlot($d[1]); break; - case Entity::DATA_TYPE_POS: + case EntityMetadataTypes::POS: $v = $d[1]; if($v !== null){ $this->putSignedBlockPosition($v->x, $v->y, $v->z); @@ -255,10 +255,10 @@ class NetworkBinaryStream extends BinaryStream{ $this->putSignedBlockPosition(0, 0, 0); } break; - case Entity::DATA_TYPE_LONG: + case EntityMetadataTypes::LONG: $this->putVarLong($d[1]); break; - case Entity::DATA_TYPE_VECTOR3F: + case EntityMetadataTypes::VECTOR3F: $this->putVector3Nullable($d[1]); break; default: diff --git a/src/pocketmine/network/mcpe/protocol/types/EntityMetadataFlags.php b/src/pocketmine/network/mcpe/protocol/types/EntityMetadataFlags.php new file mode 100644 index 0000000000..566cf5ae1e --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/EntityMetadataFlags.php @@ -0,0 +1,120 @@ + Date: Fri, 26 Apr 2019 18:57:44 +0100 Subject: [PATCH 0766/3224] Moved DataPropertyManager to network namespace this is _extremely_ network-focused code. --- src/pocketmine/entity/Entity.php | 1 + .../mcpe/protocol/types}/DataPropertyManager.php | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/pocketmine/{entity => network/mcpe/protocol/types}/DataPropertyManager.php (98%) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 8cb9d5ab48..11ac268de7 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -58,6 +58,7 @@ use pocketmine\network\mcpe\protocol\MoveEntityAbsolutePacket; use pocketmine\network\mcpe\protocol\RemoveEntityPacket; use pocketmine\network\mcpe\protocol\SetEntityDataPacket; use pocketmine\network\mcpe\protocol\SetEntityMotionPacket; +use pocketmine\network\mcpe\protocol\types\DataPropertyManager; use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\EntityMetadataTypes; diff --git a/src/pocketmine/entity/DataPropertyManager.php b/src/pocketmine/network/mcpe/protocol/types/DataPropertyManager.php similarity index 98% rename from src/pocketmine/entity/DataPropertyManager.php rename to src/pocketmine/network/mcpe/protocol/types/DataPropertyManager.php index 96014e7988..8a24c5869a 100644 --- a/src/pocketmine/entity/DataPropertyManager.php +++ b/src/pocketmine/network/mcpe/protocol/types/DataPropertyManager.php @@ -21,11 +21,10 @@ declare(strict_types=1); -namespace pocketmine\entity; +namespace pocketmine\network\mcpe\protocol\types; use pocketmine\item\Item; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\types\EntityMetadataTypes; use function assert; use function is_float; use function is_int; From 1730415643cedff907590e8123794644dc76afac Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 1 May 2019 14:43:11 -0400 Subject: [PATCH 0767/3224] Player: remove useless checks from spawnTo(), closes #2897 this was caused by changes on 4.0, but this code is nonetheless useless. --- src/pocketmine/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index f5021ac584..13738689f5 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -555,7 +555,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @param Player $player */ public function spawnTo(Player $player) : void{ - if($this->spawned and $player->spawned and $this->isAlive() and $player->isAlive() and $player->getLevel() === $this->level and $player->canSee($this) and !$this->isSpectator()){ + if($this->isAlive() and $player->isAlive() and $player->getLevel() === $this->level and $player->canSee($this) and !$this->isSpectator()){ parent::spawnTo($player); } } From 7ae84944ca0ab2593154e51bc5cc23fc76376e4d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 2 May 2019 17:35:54 +0100 Subject: [PATCH 0768/3224] protocol: add some missing interfaces for new packets --- .../network/mcpe/protocol/MapCreateLockedCopyPacket.php | 2 +- .../network/mcpe/protocol/OnScreenTextureAnimationPacket.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/MapCreateLockedCopyPacket.php b/src/pocketmine/network/mcpe/protocol/MapCreateLockedCopyPacket.php index 766337dbcc..fd65e8f423 100644 --- a/src/pocketmine/network/mcpe/protocol/MapCreateLockedCopyPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MapCreateLockedCopyPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\SessionHandler; -class MapCreateLockedCopyPacket extends DataPacket{ +class MapCreateLockedCopyPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MAP_CREATE_LOCKED_COPY_PACKET; /** @var int */ diff --git a/src/pocketmine/network/mcpe/protocol/OnScreenTextureAnimationPacket.php b/src/pocketmine/network/mcpe/protocol/OnScreenTextureAnimationPacket.php index 7f07ecb3ee..e98fda2922 100644 --- a/src/pocketmine/network/mcpe/protocol/OnScreenTextureAnimationPacket.php +++ b/src/pocketmine/network/mcpe/protocol/OnScreenTextureAnimationPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\SessionHandler; -class OnScreenTextureAnimationPacket extends DataPacket{ +class OnScreenTextureAnimationPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ON_SCREEN_TEXTURE_ANIMATION_PACKET; /** @var int */ From 5250a432d1bd7d61155d29fbe908cf244fe9b3e9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 6 May 2019 16:32:34 +0100 Subject: [PATCH 0769/3224] NetworkSession: add a dedicated PrefixedLogger, clean up some boilerplate code --- .../network/mcpe/NetworkSession.php | 35 ++++++++++++------- .../network/mcpe/ProcessLoginTask.php | 2 +- .../handler/ResourcePacksSessionHandler.php | 8 ++--- .../mcpe/handler/SimpleSessionHandler.php | 14 ++++---- 4 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index dd1fab6272..0aa4f9dec8 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -83,6 +83,8 @@ use function time; use function ucfirst; class NetworkSession{ + /** @var \PrefixedLogger */ + private $logger; /** @var Server */ private $server; /** @var Player|null */ @@ -130,6 +132,8 @@ class NetworkSession{ $this->ip = $ip; $this->port = $port; + $this->logger = new \PrefixedLogger($this->server->getLogger(), $this->getLogPrefix()); + $this->compressedQueue = new \SplQueue(); $this->connectTime = time(); @@ -139,6 +143,14 @@ class NetworkSession{ $this->manager->add($this); } + private function getLogPrefix() : string{ + return "NetworkSession: " . $this->getDisplayName(); + } + + public function getLogger() : \Logger{ + return $this->logger; + } + protected function createPlayer() : void{ $ev = new PlayerCreationEvent($this); $ev->call(); @@ -170,6 +182,7 @@ class NetworkSession{ throw new \InvalidStateException("Player info has already been set"); } $this->info = $info; + $this->logger->setPrefix($this->getLogPrefix()); } public function isConnected() : bool{ @@ -242,7 +255,7 @@ class NetworkSession{ try{ $payload = $this->cipher->decrypt($payload); }catch(\UnexpectedValueException $e){ - $this->server->getLogger()->debug("Encrypted packet from " . $this->getDisplayName() . ": " . bin2hex($payload)); + $this->logger->debug("Encrypted packet: " . bin2hex($payload)); throw new BadPacketException("Packet decryption error: " . $e->getMessage(), 0, $e); }finally{ Timings::$playerNetworkReceiveDecryptTimer->stopTiming(); @@ -253,7 +266,7 @@ class NetworkSession{ try{ $stream = new PacketStream(NetworkCompression::decompress($payload)); }catch(\ErrorException $e){ - $this->server->getLogger()->debug("Failed to decompress packet from " . $this->getDisplayName() . ": " . bin2hex($payload)); + $this->logger->debug("Failed to decompress packet: " . bin2hex($payload)); //TODO: this isn't incompatible game version if we already established protocol version throw new BadPacketException("Compressed packet batch decode error (incompatible game version?)", 0, $e); }finally{ @@ -268,14 +281,14 @@ class NetworkSession{ try{ $pk = PacketPool::getPacket($stream->getString()); }catch(BinaryDataException $e){ - $this->server->getLogger()->debug("Packet batch from " . $this->getDisplayName() . ": " . bin2hex($stream->getBuffer())); + $this->logger->debug("Packet batch: " . bin2hex($stream->getBuffer())); throw new BadPacketException("Packet batch decode error: " . $e->getMessage(), 0, $e); } try{ $this->handleDataPacket($pk); }catch(BadPacketException $e){ - $this->server->getLogger()->debug($pk->getName() . " from " . $this->getDisplayName() . ": " . bin2hex($pk->getBuffer())); + $this->logger->debug($pk->getName() . ": " . bin2hex($pk->getBuffer())); throw new BadPacketException("Error processing " . $pk->getName() . ": " . $e->getMessage(), 0, $e); } } @@ -298,13 +311,13 @@ class NetworkSession{ $packet->decode(); if(!$packet->feof() and !$packet->mayHaveUnreadBytes()){ $remains = substr($packet->getBuffer(), $packet->getOffset()); - $this->server->getLogger()->debug("Still " . strlen($remains) . " bytes unread in " . $packet->getName() . ": " . bin2hex($remains)); + $this->logger->debug("Still " . strlen($remains) . " bytes unread in " . $packet->getName() . ": " . bin2hex($remains)); } $ev = new DataPacketReceiveEvent($this, $packet); $ev->call(); if(!$ev->isCancelled() and !$packet->handle($this->handler)){ - $this->server->getLogger()->debug("Unhandled " . $packet->getName() . " received from " . $this->getDisplayName() . ": " . bin2hex($packet->getBuffer())); + $this->logger->debug("Unhandled " . $packet->getName() . ": " . bin2hex($packet->getBuffer())); } }finally{ $timings->stopTiming(); @@ -511,13 +524,11 @@ class NetworkSession{ return false; } - $this->server->getLogger()->debug($this->getDisplayName() . " is NOT logged into Xbox Live"); if($this->info->getXuid() !== ""){ - $this->server->getLogger()->warning($this->getDisplayName() . " has an XUID, but their login keychain is not signed by Mojang"); + $this->logger->warning("Found XUID, but login keychain is not signed by Mojang"); } - }else{ - $this->server->getLogger()->debug($this->getDisplayName() . " is logged into Xbox Live"); } + $this->logger->debug("Xbox Live authenticated: " . ($this->authenticated ? "YES" : "NO")); return $this->manager->kickDuplicates($this); } @@ -530,7 +541,7 @@ class NetworkSession{ $this->cipher = new NetworkCipher($encryptionKey); $this->setHandler(new HandshakeSessionHandler($this)); - $this->server->getLogger()->debug("Enabled encryption for " . $this->getDisplayName()); + $this->logger->debug("Enabled encryption"); } public function onLoginSuccess() : void{ @@ -540,7 +551,7 @@ class NetworkSession{ $pk->status = PlayStatusPacket::LOGIN_SUCCESS; $this->sendDataPacket($pk); - $this->setHandler(new ResourcePacksSessionHandler($this->server, $this, $this->server->getResourcePackManager())); + $this->setHandler(new ResourcePacksSessionHandler($this, $this->server->getResourcePackManager())); } public function onResourcePacksDone() : void{ diff --git a/src/pocketmine/network/mcpe/ProcessLoginTask.php b/src/pocketmine/network/mcpe/ProcessLoginTask.php index 1898d562b3..909b5f5222 100644 --- a/src/pocketmine/network/mcpe/ProcessLoginTask.php +++ b/src/pocketmine/network/mcpe/ProcessLoginTask.php @@ -246,7 +246,7 @@ class ProcessLoginTask extends AsyncTask{ /** @var NetworkSession $session */ $session = $this->fetchLocal(self::TLS_KEY_SESSION); if(!$session->isConnected()){ - $this->worker->getLogger()->error("Player " . $session->getDisplayName() . " was disconnected before their login could be verified"); + $session->getLogger()->debug("Disconnected before login could be verified"); }elseif($session->setAuthenticationStatus($this->authenticated, $this->authRequired, $this->error)){ if(!$this->useEncryption){ $session->onLoginSuccess(); diff --git a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php index d51716a135..be6dd90e1e 100644 --- a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php @@ -32,7 +32,6 @@ use pocketmine\network\mcpe\protocol\ResourcePacksInfoPacket; use pocketmine\network\mcpe\protocol\ResourcePackStackPacket; use pocketmine\resourcepacks\ResourcePack; use pocketmine\resourcepacks\ResourcePackManager; -use pocketmine\Server; use function ceil; use function implode; use function strpos; @@ -45,8 +44,6 @@ use function substr; class ResourcePacksSessionHandler extends SessionHandler{ private const PACK_CHUNK_SIZE = 1048576; //1MB - /** @var Server */ - private $server; /** @var NetworkSession */ private $session; /** @var ResourcePackManager */ @@ -56,8 +53,7 @@ class ResourcePacksSessionHandler extends SessionHandler{ private $downloadedChunks = []; - public function __construct(Server $server, NetworkSession $session, ResourcePackManager $resourcePackManager){ - $this->server = $server; + public function __construct(NetworkSession $session, ResourcePackManager $resourcePackManager){ $this->session = $session; $this->resourcePackManager = $resourcePackManager; } @@ -70,7 +66,7 @@ class ResourcePacksSessionHandler extends SessionHandler{ } private function disconnectWithError(string $error) : void{ - $this->server->getLogger()->error("Error while downloading resource packs for " . $this->session->getDisplayName() . ": " . $error); + $this->session->getLogger()->error("Error downloading resource packs: " . $error); $this->session->disconnect("disconnectionScreen.resourcePack"); } diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index 8a969d907d..23bd64215a 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -199,7 +199,7 @@ class SimpleSessionHandler extends SessionHandler{ $actions[] = $action; } }catch(\UnexpectedValueException $e){ - $this->player->getServer()->getLogger()->debug("Unhandled inventory action from " . $this->player->getName() . ": " . $e->getMessage()); + $this->session->getLogger()->debug("Unhandled inventory action: " . $e->getMessage()); return false; } } @@ -220,7 +220,7 @@ class SimpleSessionHandler extends SessionHandler{ try{ $this->craftingTransaction->execute(); }catch(TransactionValidationException $e){ - $this->player->getServer()->getLogger()->debug("Failed to execute crafting transaction for " . $this->player->getName() . ": " . $e->getMessage()); + $this->session->getLogger()->debug("Failed to execute crafting transaction: " . $e->getMessage()); return false; }finally{ $this->craftingTransaction = null; @@ -229,7 +229,7 @@ class SimpleSessionHandler extends SessionHandler{ }else{ //normal transaction fallthru if($this->craftingTransaction !== null){ - $this->player->getServer()->getLogger()->debug("Got unexpected normal inventory action with incomplete crafting transaction from " . $this->player->getName() . ", refusing to execute crafting"); + $this->session->getLogger()->debug("Got unexpected normal inventory action with incomplete crafting transaction, refusing to execute crafting"); $this->craftingTransaction = null; return false; } @@ -238,8 +238,8 @@ class SimpleSessionHandler extends SessionHandler{ try{ $transaction->execute(); }catch(TransactionValidationException $e){ - $logger = $this->player->getServer()->getLogger(); - $logger->debug("Failed to execute inventory transaction from " . $this->player->getName() . ": " . $e->getMessage()); + $logger = $this->session->getLogger(); + $logger->debug("Failed to execute inventory transaction: " . $e->getMessage()); $logger->debug("Actions: " . json_encode($data->getActions())); return false; @@ -393,7 +393,7 @@ class SimpleSessionHandler extends SessionHandler{ //TODO: handle this when it doesn't spam every damn tick (yet another spam bug!!) break; default: - $this->player->getServer()->getLogger()->debug("Unhandled/unknown player action type " . $packet->action . " from " . $this->player->getName()); + $this->session->getLogger()->debug("Unhandled/unknown player action type " . $packet->action); return false; } @@ -475,7 +475,7 @@ class SimpleSessionHandler extends SessionHandler{ return true; } - $this->player->getServer()->getLogger()->debug("Invalid sign update data from " . $this->player->getName() . ": " . base64_encode($packet->namedtag)); + $this->session->getLogger()->debug("Invalid sign update data: " . base64_encode($packet->namedtag)); } return false; From 685481b1720c62e07ecc9ab3657645e6b75e28a6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 6 May 2019 16:43:05 +0100 Subject: [PATCH 0770/3224] NetworkSession: improve GC performance without crashing everything this is necessary because some handlers have circular references to the session, which causes GC lag collecting them. This change allows them to be collected immediately without nuking internal state. --- src/pocketmine/network/mcpe/NetworkSession.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 0aa4f9dec8..2038e073da 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -36,6 +36,7 @@ use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\DeathSessionHandler; use pocketmine\network\mcpe\handler\HandshakeSessionHandler; use pocketmine\network\mcpe\handler\LoginSessionHandler; +use pocketmine\network\mcpe\handler\NullSessionHandler; use pocketmine\network\mcpe\handler\PreSpawnSessionHandler; use pocketmine\network\mcpe\handler\ResourcePacksSessionHandler; use pocketmine\network\mcpe\handler\SessionHandler; @@ -419,6 +420,7 @@ class NetworkSession{ $this->disconnectGuard = true; $func(); $this->disconnectGuard = false; + $this->setHandler(new NullSessionHandler()); $this->connected = false; $this->manager->remove($this); } From 82974e027143e4a6d59749fe03056861ada84b77 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 6 May 2019 17:28:56 +0100 Subject: [PATCH 0771/3224] NullSessionHandler: possibly premature optimization --- src/pocketmine/network/mcpe/NetworkSession.php | 2 +- .../network/mcpe/handler/LoginSessionHandler.php | 2 +- .../network/mcpe/handler/NullSessionHandler.php | 11 ++++++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 2038e073da..bf53852f97 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -420,7 +420,7 @@ class NetworkSession{ $this->disconnectGuard = true; $func(); $this->disconnectGuard = false; - $this->setHandler(new NullSessionHandler()); + $this->setHandler(NullSessionHandler::getInstance()); $this->connected = false; $this->manager->remove($this); } diff --git a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php index 32007e4579..909afed42c 100644 --- a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php @@ -117,7 +117,7 @@ class LoginSessionHandler extends SessionHandler{ */ protected function processLogin(LoginPacket $packet, bool $authRequired) : void{ $this->server->getAsyncPool()->submitTask(new ProcessLoginTask($this->session, $packet, $authRequired, NetworkCipher::$ENABLED)); - $this->session->setHandler(new NullSessionHandler()); //drop packets received during login verification + $this->session->setHandler(NullSessionHandler::getInstance()); //drop packets received during login verification } protected function isCompatibleProtocol(int $protocolVersion) : bool{ diff --git a/src/pocketmine/network/mcpe/handler/NullSessionHandler.php b/src/pocketmine/network/mcpe/handler/NullSessionHandler.php index a36a3989db..ac61c359ef 100644 --- a/src/pocketmine/network/mcpe/handler/NullSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/NullSessionHandler.php @@ -26,6 +26,15 @@ namespace pocketmine\network\mcpe\handler; /** * Handler which simply ignores all packets received. */ -class NullSessionHandler extends SessionHandler{ +final class NullSessionHandler extends SessionHandler{ + /** @var self|null */ + private static $instance = null; + public static function getInstance() : self{ + return self::$instance ?? (self::$instance = new self); + } + + private function __construct(){ + + } } From c2771eba88a61883683adea58835335dce0a1fbe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 6 May 2019 17:46:17 +0100 Subject: [PATCH 0772/3224] use the appropriate API for decoding packet batches --- src/pocketmine/network/mcpe/NetworkSession.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index bf53852f97..579351f4f2 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -51,7 +51,6 @@ use pocketmine\network\mcpe\protocol\ModalFormRequestPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\NetworkChunkPublisherUpdatePacket; use pocketmine\network\mcpe\protocol\Packet; -use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\network\mcpe\protocol\PlayStatusPacket; use pocketmine\network\mcpe\protocol\ServerboundPacket; use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket; @@ -280,7 +279,7 @@ class NetworkSession{ throw new BadPacketException("Too many packets in a single batch"); } try{ - $pk = PacketPool::getPacket($stream->getString()); + $pk = $stream->getPacket(); }catch(BinaryDataException $e){ $this->logger->debug("Packet batch: " . bin2hex($stream->getBuffer())); throw new BadPacketException("Packet batch decode error: " . $e->getMessage(), 0, $e); From 3415edf60031044efe94d4c5ebe3a03d87cc8fad Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 6 May 2019 17:46:37 +0100 Subject: [PATCH 0773/3224] PacketStream: add @throws --- src/pocketmine/network/mcpe/PacketStream.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pocketmine/network/mcpe/PacketStream.php b/src/pocketmine/network/mcpe/PacketStream.php index dd79f9704b..ece641510d 100644 --- a/src/pocketmine/network/mcpe/PacketStream.php +++ b/src/pocketmine/network/mcpe/PacketStream.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe; use pocketmine\network\mcpe\protocol\Packet; use pocketmine\network\mcpe\protocol\PacketPool; +use pocketmine\utils\BinaryDataException; class PacketStream extends NetworkBinaryStream{ @@ -35,6 +36,10 @@ class PacketStream extends NetworkBinaryStream{ $this->putString($packet->getBuffer()); } + /** + * @return Packet + * @throws BinaryDataException + */ public function getPacket() : Packet{ return PacketPool::getPacket($this->getString()); } From ce61c6e0fdaf053084161e620769340885174f19 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 6 May 2019 19:54:42 +0100 Subject: [PATCH 0774/3224] PacketStream: added fromPackets() sugar --- src/pocketmine/Server.php | 5 +---- src/pocketmine/inventory/CraftingManager.php | 5 +---- src/pocketmine/network/mcpe/ChunkRequestTask.php | 5 +---- src/pocketmine/network/mcpe/PacketStream.php | 15 +++++++++++++++ 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index ee6885b8b0..531657d195 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1492,10 +1492,7 @@ class Server{ } $recipients = $ev->getTargets(); - $stream = new PacketStream(); - foreach($ev->getPackets() as $packet){ - $stream->putPacket($packet); - } + $stream = PacketStream::fromPackets(...$ev->getPackets()); if(NetworkCompression::$THRESHOLD < 0 or strlen($stream->getBuffer()) < NetworkCompression::$THRESHOLD){ foreach($recipients as $target){ diff --git a/src/pocketmine/inventory/CraftingManager.php b/src/pocketmine/inventory/CraftingManager.php index f769990b94..79aa26799f 100644 --- a/src/pocketmine/inventory/CraftingManager.php +++ b/src/pocketmine/inventory/CraftingManager.php @@ -115,11 +115,8 @@ class CraftingManager{ $pk->addFurnaceRecipe($recipe); } - $batch = new PacketStream(); - $batch->putPacket($pk); - $this->craftingDataCache = new CompressBatchPromise(); - $this->craftingDataCache->resolve(NetworkCompression::compress($batch->getBuffer())); + $this->craftingDataCache->resolve(NetworkCompression::compress(PacketStream::fromPackets($pk)->getBuffer())); Timings::$craftingDataCacheRebuildTimer->stopTiming(); } diff --git a/src/pocketmine/network/mcpe/ChunkRequestTask.php b/src/pocketmine/network/mcpe/ChunkRequestTask.php index 2d07e0b61d..097e300cc0 100644 --- a/src/pocketmine/network/mcpe/ChunkRequestTask.php +++ b/src/pocketmine/network/mcpe/ChunkRequestTask.php @@ -57,10 +57,7 @@ class ChunkRequestTask extends AsyncTask{ $pk->chunkZ = $this->chunkZ; $pk->data = $this->chunk; - $stream = new PacketStream(); - $stream->putPacket($pk); - - $this->setResult(NetworkCompression::compress($stream->getBuffer(), $this->compressionLevel)); + $this->setResult(NetworkCompression::compress(PacketStream::fromPackets($pk)->getBuffer(), $this->compressionLevel)); } public function onError() : void{ diff --git a/src/pocketmine/network/mcpe/PacketStream.php b/src/pocketmine/network/mcpe/PacketStream.php index ece641510d..df3cfae2d8 100644 --- a/src/pocketmine/network/mcpe/PacketStream.php +++ b/src/pocketmine/network/mcpe/PacketStream.php @@ -43,4 +43,19 @@ class PacketStream extends NetworkBinaryStream{ public function getPacket() : Packet{ return PacketPool::getPacket($this->getString()); } + + /** + * Constructs a packet batch from the given list of packets. + * + * @param Packet ...$packets + * + * @return PacketStream + */ + public static function fromPackets(Packet ...$packets) : self{ + $result = new self(); + foreach($packets as $packet){ + $result->putPacket($packet); + } + return $result; + } } From 427e33442606e01af995f6dcd502fe9199216eb2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 6 May 2019 19:58:02 +0100 Subject: [PATCH 0775/3224] rename PacketStream to PacketBatch --- src/pocketmine/Server.php | 10 +++++----- src/pocketmine/inventory/CraftingManager.php | 4 ++-- src/pocketmine/network/mcpe/ChunkRequestTask.php | 2 +- src/pocketmine/network/mcpe/NetworkSession.php | 6 +++--- .../network/mcpe/{PacketStream.php => PacketBatch.php} | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) rename src/pocketmine/network/mcpe/{PacketStream.php => PacketBatch.php} (95%) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 531657d195..346e79dbf3 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -67,7 +67,7 @@ use pocketmine\network\mcpe\CompressBatchTask; use pocketmine\network\mcpe\NetworkCipher; use pocketmine\network\mcpe\NetworkCompression; use pocketmine\network\mcpe\NetworkSession; -use pocketmine\network\mcpe\PacketStream; +use pocketmine\network\mcpe\PacketBatch; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\ProtocolInfo; @@ -1492,7 +1492,7 @@ class Server{ } $recipients = $ev->getTargets(); - $stream = PacketStream::fromPackets(...$ev->getPackets()); + $stream = PacketBatch::fromPackets(...$ev->getPackets()); if(NetworkCompression::$THRESHOLD < 0 or strlen($stream->getBuffer()) < NetworkCompression::$THRESHOLD){ foreach($recipients as $target){ @@ -1513,12 +1513,12 @@ class Server{ /** * Broadcasts a list of packets in a batch to a list of players * - * @param PacketStream $stream - * @param bool $forceSync + * @param PacketBatch $stream + * @param bool $forceSync * * @return CompressBatchPromise */ - public function prepareBatch(PacketStream $stream, bool $forceSync = false) : CompressBatchPromise{ + public function prepareBatch(PacketBatch $stream, bool $forceSync = false) : CompressBatchPromise{ try{ Timings::$playerNetworkSendCompressTimer->startTiming(); diff --git a/src/pocketmine/inventory/CraftingManager.php b/src/pocketmine/inventory/CraftingManager.php index 79aa26799f..bc54c53cf4 100644 --- a/src/pocketmine/inventory/CraftingManager.php +++ b/src/pocketmine/inventory/CraftingManager.php @@ -26,7 +26,7 @@ namespace pocketmine\inventory; use pocketmine\item\Item; use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\NetworkCompression; -use pocketmine\network\mcpe\PacketStream; +use pocketmine\network\mcpe\PacketBatch; use pocketmine\network\mcpe\protocol\CraftingDataPacket; use pocketmine\timings\Timings; use function array_map; @@ -116,7 +116,7 @@ class CraftingManager{ } $this->craftingDataCache = new CompressBatchPromise(); - $this->craftingDataCache->resolve(NetworkCompression::compress(PacketStream::fromPackets($pk)->getBuffer())); + $this->craftingDataCache->resolve(NetworkCompression::compress(PacketBatch::fromPackets($pk)->getBuffer())); Timings::$craftingDataCacheRebuildTimer->stopTiming(); } diff --git a/src/pocketmine/network/mcpe/ChunkRequestTask.php b/src/pocketmine/network/mcpe/ChunkRequestTask.php index 097e300cc0..30d2725c10 100644 --- a/src/pocketmine/network/mcpe/ChunkRequestTask.php +++ b/src/pocketmine/network/mcpe/ChunkRequestTask.php @@ -57,7 +57,7 @@ class ChunkRequestTask extends AsyncTask{ $pk->chunkZ = $this->chunkZ; $pk->data = $this->chunk; - $this->setResult(NetworkCompression::compress(PacketStream::fromPackets($pk)->getBuffer(), $this->compressionLevel)); + $this->setResult(NetworkCompression::compress(PacketBatch::fromPackets($pk)->getBuffer(), $this->compressionLevel)); } public function onError() : void{ diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 579351f4f2..d12347a75e 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -119,7 +119,7 @@ class NetworkSession{ /** @var NetworkCipher */ private $cipher; - /** @var PacketStream|null */ + /** @var PacketBatch|null */ private $sendBuffer; /** @var \SplQueue|CompressBatchPromise[] */ @@ -264,7 +264,7 @@ class NetworkSession{ Timings::$playerNetworkReceiveDecompressTimer->startTiming(); try{ - $stream = new PacketStream(NetworkCompression::decompress($payload)); + $stream = new PacketBatch(NetworkCompression::decompress($payload)); }catch(\ErrorException $e){ $this->logger->debug("Failed to decompress packet: " . bin2hex($payload)); //TODO: this isn't incompatible game version if we already established protocol version @@ -359,7 +359,7 @@ class NetworkSession{ $timings->startTiming(); try{ if($this->sendBuffer === null){ - $this->sendBuffer = new PacketStream(); + $this->sendBuffer = new PacketBatch(); } $this->sendBuffer->putPacket($packet); $this->manager->scheduleUpdate($this); //schedule flush at end of tick diff --git a/src/pocketmine/network/mcpe/PacketStream.php b/src/pocketmine/network/mcpe/PacketBatch.php similarity index 95% rename from src/pocketmine/network/mcpe/PacketStream.php rename to src/pocketmine/network/mcpe/PacketBatch.php index df3cfae2d8..4f710c84d4 100644 --- a/src/pocketmine/network/mcpe/PacketStream.php +++ b/src/pocketmine/network/mcpe/PacketBatch.php @@ -27,7 +27,7 @@ use pocketmine\network\mcpe\protocol\Packet; use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\utils\BinaryDataException; -class PacketStream extends NetworkBinaryStream{ +class PacketBatch extends NetworkBinaryStream{ public function putPacket(Packet $packet) : void{ if(!$packet->isEncoded()){ @@ -49,7 +49,7 @@ class PacketStream extends NetworkBinaryStream{ * * @param Packet ...$packets * - * @return PacketStream + * @return PacketBatch */ public static function fromPackets(Packet ...$packets) : self{ $result = new self(); From 3cd6e12e718a6d846c1c2e75ae2667a148e2c613 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Tue, 7 May 2019 14:47:28 +0100 Subject: [PATCH 0776/3224] Renaming "Level" -> "World" (#2907) This has been a pain point for a long time due to the misleading nature of the name "level". It's also confusing when trying to do things like getting the XP level of the player or such, and also does not translate well to other languages. This transition was already executed on the UI some time ago (language strings) and now it's time for the same change to occur on the API. This will burn a lot of plugins, but they'll acclimatize. Despite the scary size of this PR, there isn't actually so many changes to make. Most of this came from renaming `Position->getLevel()` to `Position->getWorld()`, or cosmetic changes like changing variable names or doc comments. --- .travis.yml | 2 +- src/pocketmine/MemoryManager.php | 8 +- src/pocketmine/Player.php | 170 +++++------ src/pocketmine/Server.php | 84 +++--- src/pocketmine/block/Banner.php | 6 +- src/pocketmine/block/BaseRail.php | 6 +- src/pocketmine/block/Bed.php | 16 +- src/pocketmine/block/Block.php | 39 +-- src/pocketmine/block/BlockFactory.php | 4 +- src/pocketmine/block/Button.php | 14 +- src/pocketmine/block/Cactus.php | 12 +- src/pocketmine/block/Cake.php | 4 +- src/pocketmine/block/Carpet.php | 2 +- src/pocketmine/block/Chest.php | 6 +- src/pocketmine/block/CoarseDirt.php | 2 +- src/pocketmine/block/CocoaBlock.php | 6 +- src/pocketmine/block/ConcretePowder.php | 2 +- src/pocketmine/block/Crops.php | 6 +- src/pocketmine/block/Dandelion.php | 2 +- src/pocketmine/block/DaylightSensor.php | 2 +- src/pocketmine/block/DeadBush.php | 2 +- src/pocketmine/block/Dirt.php | 2 +- src/pocketmine/block/Door.php | 14 +- src/pocketmine/block/DoublePlant.php | 6 +- src/pocketmine/block/DragonEgg.php | 14 +- src/pocketmine/block/EnderChest.php | 2 +- src/pocketmine/block/Farmland.php | 10 +- src/pocketmine/block/FenceGate.php | 8 +- src/pocketmine/block/Fire.php | 12 +- src/pocketmine/block/Flower.php | 2 +- src/pocketmine/block/FlowerPot.php | 8 +- src/pocketmine/block/FrostedIce.php | 20 +- src/pocketmine/block/Furnace.php | 2 +- src/pocketmine/block/Grass.php | 22 +- src/pocketmine/block/GrassPath.php | 2 +- src/pocketmine/block/Ice.php | 6 +- src/pocketmine/block/ItemFrame.php | 12 +- src/pocketmine/block/Ladder.php | 2 +- src/pocketmine/block/Lava.php | 6 +- src/pocketmine/block/Leaves.php | 10 +- src/pocketmine/block/Lever.php | 10 +- src/pocketmine/block/Liquid.php | 80 +++--- src/pocketmine/block/Mycelium.php | 4 +- src/pocketmine/block/NetherWartPlant.php | 4 +- src/pocketmine/block/RedMushroom.php | 2 +- src/pocketmine/block/RedstoneComparator.php | 8 +- src/pocketmine/block/RedstoneOre.php | 8 +- src/pocketmine/block/RedstoneRepeater.php | 4 +- src/pocketmine/block/Sapling.php | 12 +- src/pocketmine/block/Sign.php | 8 +- src/pocketmine/block/Skull.php | 4 +- src/pocketmine/block/SnowLayer.php | 4 +- src/pocketmine/block/Stem.php | 4 +- src/pocketmine/block/Sugarcane.php | 16 +- src/pocketmine/block/TNT.php | 4 +- src/pocketmine/block/TallGrass.php | 2 +- src/pocketmine/block/Torch.php | 2 +- src/pocketmine/block/Trapdoor.php | 6 +- src/pocketmine/block/Vine.php | 4 +- src/pocketmine/block/Water.php | 6 +- src/pocketmine/block/WaterLily.php | 2 +- src/pocketmine/block/utils/FallableTrait.php | 8 +- .../command/defaults/DifficultyCommand.php | 10 +- .../defaults/GarbageCollectorCommand.php | 14 +- .../command/defaults/ParticleCommand.php | 66 ++--- .../command/defaults/SaveCommand.php | 4 +- .../command/defaults/SaveOffCommand.php | 2 +- .../command/defaults/SaveOnCommand.php | 2 +- .../command/defaults/SeedCommand.php | 4 +- .../command/defaults/SetWorldSpawnCommand.php | 6 +- .../command/defaults/SpawnpointCommand.php | 14 +- .../command/defaults/StatusCommand.php | 14 +- .../command/defaults/TimeCommand.php | 28 +- src/pocketmine/entity/Entity.php | 90 +++--- src/pocketmine/entity/EntityFactory.php | 19 +- src/pocketmine/entity/Human.php | 26 +- src/pocketmine/entity/Living.php | 12 +- .../entity/object/ExperienceOrb.php | 4 +- src/pocketmine/entity/object/FallingBlock.php | 8 +- src/pocketmine/entity/object/Painting.php | 22 +- src/pocketmine/entity/object/PrimedTNT.php | 6 +- src/pocketmine/entity/projectile/Arrow.php | 10 +- src/pocketmine/entity/projectile/Egg.php | 4 +- .../entity/projectile/EnderPearl.php | 10 +- .../entity/projectile/ExperienceBottle.php | 10 +- .../entity/projectile/Projectile.php | 16 +- src/pocketmine/entity/projectile/Snowball.php | 4 +- .../entity/projectile/SplashPotion.php | 14 +- .../entity/EntityDamageByChildEntityEvent.php | 2 +- .../entity/EntityDamageByEntityEvent.php | 2 +- .../event/entity/EntityExplodeEvent.php | 2 +- .../event/entity/EntityTeleportEvent.php | 2 +- ...geEvent.php => EntityWorldChangeEvent.php} | 26 +- .../event/player/PlayerMoveEvent.php | 2 +- .../event/player/PlayerRespawnEvent.php | 2 +- .../event/server/QueryRegenerateEvent.php | 4 +- .../event/{level => world}/ChunkEvent.php | 14 +- .../event/{level => world}/ChunkLoadEvent.php | 10 +- .../{level => world}/ChunkPopulateEvent.php | 2 +- .../{level => world}/ChunkUnloadEvent.php | 2 +- .../{level => world}/SpawnChangeEvent.php | 16 +- .../LevelEvent.php => world/WorldEvent.php} | 24 +- .../WorldInitEvent.php} | 6 +- .../WorldLoadEvent.php} | 6 +- .../WorldSaveEvent.php} | 6 +- .../WorldUnloadEvent.php} | 6 +- src/pocketmine/inventory/AnvilInventory.php | 2 +- src/pocketmine/inventory/ArmorInventory.php | 4 +- src/pocketmine/inventory/ChestInventory.php | 12 +- src/pocketmine/inventory/EnchantInventory.php | 2 +- .../inventory/EnderChestInventory.php | 10 +- src/pocketmine/inventory/PlayerInventory.php | 2 +- src/pocketmine/item/Bow.php | 6 +- src/pocketmine/item/Bucket.php | 4 +- src/pocketmine/item/ChorusFruit.php | 18 +- src/pocketmine/item/FlintSteel.php | 10 +- src/pocketmine/item/LiquidBucket.php | 4 +- src/pocketmine/item/PaintingItem.php | 6 +- src/pocketmine/item/ProjectileItem.php | 6 +- src/pocketmine/item/SpawnEgg.php | 2 +- .../metadata/BlockMetadataStore.php | 8 +- ...tadataStore.php => WorldMetadataStore.php} | 16 +- src/pocketmine/network/mcpe/ChunkCache.php | 24 +- .../network/mcpe/ChunkRequestTask.php | 2 +- .../network/mcpe/NetworkSession.php | 12 +- .../mcpe/handler/PreSpawnSessionHandler.php | 6 +- .../mcpe/handler/SimpleSessionHandler.php | 10 +- src/pocketmine/scheduler/AsyncTask.php | 2 +- src/pocketmine/tile/Banner.php | 6 +- src/pocketmine/tile/Bed.php | 6 +- src/pocketmine/tile/Chest.php | 12 +- src/pocketmine/tile/ContainerTrait.php | 4 +- src/pocketmine/tile/Furnace.php | 12 +- src/pocketmine/tile/ItemFrame.php | 6 +- src/pocketmine/tile/Sign.php | 6 +- src/pocketmine/tile/Skull.php | 6 +- src/pocketmine/tile/Spawnable.php | 2 +- src/pocketmine/tile/Tile.php | 16 +- src/pocketmine/tile/TileFactory.php | 18 +- src/pocketmine/timings/TimingsHandler.php | 6 +- src/pocketmine/utils/EnumTrait.php | 11 + .../{level => world}/BlockTransaction.php | 2 +- .../{level => world}/ChunkListener.php | 8 +- .../{level => world}/ChunkLoader.php | 8 +- .../{level => world}/ChunkManager.php | 4 +- src/pocketmine/{level => world}/Explosion.php | 44 +-- src/pocketmine/{level => world}/Location.php | 18 +- src/pocketmine/{level => world}/Position.php | 58 ++-- .../{level => world}/SimpleChunkManager.php | 12 +- .../{level/Level.php => world/World.php} | 263 +++++++++--------- .../WorldException.php} | 4 +- .../WorldManager.php} | 220 +++++++-------- .../WorldTimings.php} | 8 +- .../{level => world}/biome/Biome.php | 12 +- .../{level => world}/biome/DesertBiome.php | 2 +- .../{level => world}/biome/ForestBiome.php | 6 +- .../{level => world}/biome/GrassyBiome.php | 2 +- .../{level => world}/biome/HellBiome.php | 2 +- .../{level => world}/biome/IcePlainsBiome.php | 4 +- .../{level => world}/biome/MountainsBiome.php | 6 +- .../{level => world}/biome/OceanBiome.php | 4 +- .../{level => world}/biome/PlainBiome.php | 4 +- .../{level => world}/biome/RiverBiome.php | 4 +- .../{level => world}/biome/SandyBiome.php | 2 +- .../biome/SmallMountainsBiome.php | 2 +- .../{level => world}/biome/SnowyBiome.php | 2 +- .../{level => world}/biome/SwampBiome.php | 2 +- .../{level => world}/biome/TaigaBiome.php | 6 +- .../{level => world}/biome/UnknownBiome.php | 2 +- .../{level => world}/format/Chunk.php | 28 +- .../format/ChunkException.php | 2 +- .../{level => world}/format/EmptySubChunk.php | 2 +- .../format/PalettedBlockArray.php | 3 +- .../{level => world}/format/SubChunk.php | 2 +- .../format/SubChunkInterface.php | 2 +- .../format/io/BaseWorldProvider.php} | 28 +- .../{level => world}/format/io/ChunkUtils.php | 2 +- .../format/io/FormatConverter.php | 32 +-- .../format/io/WorldData.php} | 8 +- .../format/io/WorldProvider.php} | 22 +- .../format/io/WorldProviderManager.php} | 34 +-- .../format/io/WritableWorldProvider.php} | 6 +- .../format/io/data/BaseNbtWorldData.php} | 12 +- .../format/io/data/BedrockWorldData.php} | 34 +-- .../format/io/data/JavaWorldData.php} | 24 +- .../io/exception/CorruptedChunkException.php | 4 +- .../UnsupportedChunkFormatException.php | 4 +- .../UnsupportedWorldFormatException.php} | 4 +- .../format/io/leveldb/LevelDB.php | 40 +-- .../format/io/region/Anvil.php | 8 +- .../io/region/CorruptedRegionException.php | 2 +- .../io/region/LegacyAnvilChunkTrait.php | 10 +- .../format/io/region/McRegion.php | 14 +- .../format/io/region/PMAnvil.php | 8 +- .../format/io/region/RegionException.php | 2 +- .../format/io/region/RegionLoader.php | 6 +- .../io/region/RegionLocationTableEntry.php | 2 +- .../format/io/region/RegionWorldProvider.php} | 30 +- .../{level => world}/generator/Flat.php | 22 +- .../{level => world}/generator/Generator.php | 16 +- .../generator/GeneratorManager.php | 10 +- .../generator/GeneratorRegisterTask.php | 24 +- .../generator/GeneratorUnregisterTask.php | 14 +- .../InvalidGeneratorOptionsException.php | 2 +- .../generator/PopulationTask.php | 34 +-- .../generator/biome/BiomeSelector.php | 8 +- .../generator/hell/Nether.php | 30 +- .../generator/noise/Noise.php | 4 +- .../generator/noise/Simplex.php | 2 +- .../generator/normal/Normal.php | 42 +-- .../generator/object/BirchTree.php | 8 +- .../generator/object/JungleTree.php | 2 +- .../generator/object/OakTree.php | 8 +- .../{level => world}/generator/object/Ore.php | 14 +- .../generator/object/OreType.php | 2 +- .../generator/object/SpruceTree.php | 10 +- .../generator/object/TallGrass.php | 10 +- .../generator/object/Tree.php | 22 +- .../generator/populator/GroundCover.php | 10 +- .../generator/populator/Ore.php | 14 +- .../generator/populator/Populator.php | 8 +- .../generator/populator/TallGrass.php | 18 +- .../generator/populator/Tree.php | 16 +- .../light/BlockLightUpdate.php | 2 +- .../light/LightPopulationTask.php | 18 +- .../{level => world}/light/LightUpdate.php | 26 +- .../{level => world}/light/SkyLightUpdate.php | 2 +- .../particle/AngryVillagerParticle.php | 2 +- .../particle/BlockForceFieldParticle.php | 2 +- .../particle/BubbleParticle.php | 2 +- .../particle/CriticalParticle.php | 2 +- .../particle/DestroyBlockParticle.php | 2 +- .../particle/DragonEggTeleportParticle.php | 2 +- .../particle/DustParticle.php | 2 +- .../particle/EnchantParticle.php | 2 +- .../particle/EnchantmentTableParticle.php | 2 +- .../particle/EndermanTeleportParticle.php | 2 +- .../particle/EntityFlameParticle.php | 2 +- .../particle/ExplodeParticle.php | 2 +- .../particle/FlameParticle.php | 2 +- .../particle/FloatingTextParticle.php | 2 +- .../particle/GenericParticle.php | 2 +- .../particle/HappyVillagerParticle.php | 2 +- .../particle/HeartParticle.php | 2 +- .../particle/HugeExplodeParticle.php | 2 +- .../particle/HugeExplodeSeedParticle.php | 2 +- .../{level => world}/particle/InkParticle.php | 2 +- .../particle/InstantEnchantParticle.php | 2 +- .../particle/ItemBreakParticle.php | 2 +- .../particle/LavaDripParticle.php | 2 +- .../particle/LavaParticle.php | 2 +- .../particle/MobSpawnParticle.php | 2 +- .../{level => world}/particle/Particle.php | 2 +- .../particle/PortalParticle.php | 2 +- .../particle/PotionSplashParticle.php | 2 +- .../particle/RainSplashParticle.php | 2 +- .../particle/RedstoneParticle.php | 2 +- .../particle/SmokeParticle.php | 2 +- .../particle/SnowballPoofParticle.php | 2 +- .../particle/SplashParticle.php | 2 +- .../particle/SporeParticle.php | 2 +- .../particle/TerrainParticle.php | 2 +- .../particle/WaterDripParticle.php | 2 +- .../particle/WaterParticle.php | 2 +- .../sound/AnvilBreakSound.php | 2 +- .../{level => world}/sound/AnvilFallSound.php | 2 +- .../{level => world}/sound/AnvilUseSound.php | 2 +- .../{level => world}/sound/ArrowHitSound.php | 2 +- .../sound/BlazeShootSound.php | 2 +- .../sound/BlockBreakSound.php | 2 +- .../sound/BlockPlaceSound.php | 2 +- .../{level => world}/sound/BowShootSound.php | 2 +- .../sound/BucketEmptyLavaSound.php | 2 +- .../sound/BucketEmptyWaterSound.php | 2 +- .../sound/BucketFillLavaSound.php | 2 +- .../sound/BucketFillWaterSound.php | 2 +- .../sound/ChestCloseSound.php | 2 +- .../{level => world}/sound/ChestOpenSound.php | 2 +- .../{level => world}/sound/ClickSound.php | 2 +- .../{level => world}/sound/DoorBumpSound.php | 2 +- .../{level => world}/sound/DoorCrashSound.php | 2 +- .../{level => world}/sound/DoorSound.php | 2 +- .../sound/EnderChestCloseSound.php | 2 +- .../sound/EnderChestOpenSound.php | 2 +- .../sound/EndermanTeleportSound.php | 2 +- .../{level => world}/sound/ExplodeSound.php | 2 +- .../{level => world}/sound/FizzSound.php | 2 +- .../sound/FlintSteelSound.php | 2 +- .../sound/GhastShootSound.php | 2 +- .../{level => world}/sound/GhastSound.php | 2 +- .../{level => world}/sound/IgniteSound.php | 2 +- .../{level => world}/sound/ItemBreakSound.php | 2 +- .../{level => world}/sound/LaunchSound.php | 2 +- .../sound/LevelEventSound.php | 2 +- .../{level => world}/sound/PopSound.php | 2 +- .../sound/PotionSplashSound.php | 2 +- .../sound/RedstonePowerOffSound.php | 2 +- .../sound/RedstonePowerOnSound.php | 2 +- .../{level => world}/sound/Sound.php | 2 +- .../{level => world}/sound/ThrowSound.php | 2 +- .../{level => world}/sound/TotemUseSound.php | 2 +- .../{level => world}/sound/XpCollectSound.php | 2 +- .../{level => world}/sound/XpLevelUpSound.php | 2 +- .../utils/SubChunkIteratorManager.php | 18 +- ...Provider.php => AbstractWorldProvider.php} | 4 +- ...rovider.php => InterfaceWorldProvider.php} | 4 +- .../format/io/LevelProviderManagerTest.php | 10 +- .../level/format/io/SubChunkConverter.php | 5 +- .../format/io/region/RegionLoaderTest.php | 7 +- tests/preprocessor | 2 +- 310 files changed, 1647 insertions(+), 1628 deletions(-) rename src/pocketmine/event/entity/{EntityLevelChangeEvent.php => EntityWorldChangeEvent.php} (66%) rename src/pocketmine/event/{level => world}/ChunkEvent.php (78%) rename src/pocketmine/event/{level => world}/ChunkLoadEvent.php (83%) rename src/pocketmine/event/{level => world}/ChunkPopulateEvent.php (96%) rename src/pocketmine/event/{level => world}/ChunkUnloadEvent.php (96%) rename src/pocketmine/event/{level => world}/SpawnChangeEvent.php (76%) rename src/pocketmine/event/{level/LevelEvent.php => world/WorldEvent.php} (70%) rename src/pocketmine/event/{level/LevelInitEvent.php => world/WorldInitEvent.php} (86%) rename src/pocketmine/event/{level/LevelLoadEvent.php => world/WorldLoadEvent.php} (87%) rename src/pocketmine/event/{level/LevelSaveEvent.php => world/WorldSaveEvent.php} (87%) rename src/pocketmine/event/{level/LevelUnloadEvent.php => world/WorldUnloadEvent.php} (86%) rename src/pocketmine/metadata/{LevelMetadataStore.php => WorldMetadataStore.php} (73%) rename src/pocketmine/{level => world}/BlockTransaction.php (99%) rename src/pocketmine/{level => world}/ChunkListener.php (93%) rename src/pocketmine/{level => world}/ChunkLoader.php (87%) rename src/pocketmine/{level => world}/ChunkManager.php (97%) rename src/pocketmine/{level => world}/Explosion.php (86%) rename src/pocketmine/{level => world}/Location.php (80%) rename src/pocketmine/{level => world}/Position.php (61%) rename src/pocketmine/{level => world}/SimpleChunkManager.php (90%) rename src/pocketmine/{level/Level.php => world/World.php} (92%) rename src/pocketmine/{level/LevelException.php => world/WorldException.php} (91%) rename src/pocketmine/{level/LevelManager.php => world/WorldManager.php} (60%) rename src/pocketmine/{level/LevelTimings.php => world/WorldTimings.php} (96%) rename src/pocketmine/{level => world}/biome/Biome.php (93%) rename src/pocketmine/{level => world}/biome/DesertBiome.php (96%) rename src/pocketmine/{level => world}/biome/ForestBiome.php (91%) rename src/pocketmine/{level => world}/biome/GrassyBiome.php (97%) rename src/pocketmine/{level => world}/biome/HellBiome.php (96%) rename src/pocketmine/{level => world}/biome/IcePlainsBiome.php (92%) rename src/pocketmine/{level => world}/biome/MountainsBiome.php (90%) rename src/pocketmine/{level => world}/biome/OceanBiome.php (94%) rename src/pocketmine/{level => world}/biome/PlainBiome.php (92%) rename src/pocketmine/{level => world}/biome/RiverBiome.php (94%) rename src/pocketmine/{level => world}/biome/SandyBiome.php (97%) rename src/pocketmine/{level => world}/biome/SmallMountainsBiome.php (96%) rename src/pocketmine/{level => world}/biome/SnowyBiome.php (97%) rename src/pocketmine/{level => world}/biome/SwampBiome.php (96%) rename src/pocketmine/{level => world}/biome/TaigaBiome.php (90%) rename src/pocketmine/{level => world}/biome/UnknownBiome.php (96%) rename src/pocketmine/{level => world}/format/Chunk.php (96%) rename src/pocketmine/{level => world}/format/ChunkException.php (95%) rename src/pocketmine/{level => world}/format/EmptySubChunk.php (98%) rename src/pocketmine/{level => world}/format/PalettedBlockArray.php (92%) rename src/pocketmine/{level => world}/format/SubChunk.php (99%) rename src/pocketmine/{level => world}/format/SubChunkInterface.php (98%) rename src/pocketmine/{level/format/io/BaseLevelProvider.php => world/format/io/BaseWorldProvider.php} (74%) rename src/pocketmine/{level => world}/format/io/ChunkUtils.php (98%) rename src/pocketmine/{level => world}/format/io/FormatConverter.php (83%) rename src/pocketmine/{level/format/io/LevelData.php => world/format/io/WorldData.php} (93%) rename src/pocketmine/{level/format/io/LevelProvider.php => world/format/io/WorldProvider.php} (80%) rename src/pocketmine/{level/format/io/LevelProviderManager.php => world/format/io/WorldProviderManager.php} (73%) rename src/pocketmine/{level/format/io/WritableLevelProvider.php => world/format/io/WritableWorldProvider.php} (90%) rename src/pocketmine/{level/format/io/data/BaseNbtLevelData.php => world/format/io/data/BaseNbtWorldData.php} (93%) rename src/pocketmine/{level/format/io/data/BedrockLevelData.php => world/format/io/data/BedrockWorldData.php} (88%) rename src/pocketmine/{level/format/io/data/JavaLevelData.php => world/format/io/data/JavaWorldData.php} (88%) rename src/pocketmine/{level => world}/format/io/exception/CorruptedChunkException.php (89%) rename src/pocketmine/{level => world}/format/io/exception/UnsupportedChunkFormatException.php (89%) rename src/pocketmine/{level/format/io/exception/UnsupportedLevelFormatException.php => world/format/io/exception/UnsupportedWorldFormatException.php} (86%) rename src/pocketmine/{level => world}/format/io/leveldb/LevelDB.php (93%) rename src/pocketmine/{level => world}/format/io/region/Anvil.php (89%) rename src/pocketmine/{level => world}/format/io/region/CorruptedRegionException.php (94%) rename src/pocketmine/{level => world}/format/io/region/LegacyAnvilChunkTrait.php (93%) rename src/pocketmine/{level => world}/format/io/region/McRegion.php (90%) rename src/pocketmine/{level => world}/format/io/region/PMAnvil.php (89%) rename src/pocketmine/{level => world}/format/io/region/RegionException.php (94%) rename src/pocketmine/{level => world}/format/io/region/RegionLoader.php (98%) rename src/pocketmine/{level => world}/format/io/region/RegionLocationTableEntry.php (98%) rename src/pocketmine/{level/format/io/region/RegionLevelProvider.php => world/format/io/region/RegionWorldProvider.php} (89%) rename src/pocketmine/{level => world}/generator/Flat.php (90%) rename src/pocketmine/{level => world}/generator/Generator.php (85%) rename src/pocketmine/{level => world}/generator/GeneratorManager.php (94%) rename src/pocketmine/{level => world}/generator/GeneratorRegisterTask.php (71%) rename src/pocketmine/{level => world}/generator/GeneratorUnregisterTask.php (72%) rename src/pocketmine/{level => world}/generator/InvalidGeneratorOptionsException.php (95%) rename src/pocketmine/{level => world}/generator/PopulationTask.php (80%) rename src/pocketmine/{level => world}/generator/biome/BiomeSelector.php (93%) rename src/pocketmine/{level => world}/generator/hell/Nether.php (81%) rename src/pocketmine/{level => world}/generator/noise/Noise.php (98%) rename src/pocketmine/{level => world}/generator/noise/Simplex.php (99%) rename src/pocketmine/{level => world}/generator/normal/Normal.php (86%) rename src/pocketmine/{level => world}/generator/object/BirchTree.php (87%) rename src/pocketmine/{level => world}/generator/object/JungleTree.php (96%) rename src/pocketmine/{level => world}/generator/object/OakTree.php (86%) rename src/pocketmine/{level => world}/generator/object/Ore.php (86%) rename src/pocketmine/{level => world}/generator/object/OreType.php (96%) rename src/pocketmine/{level => world}/generator/object/SpruceTree.php (90%) rename src/pocketmine/{level => world}/generator/object/TallGrass.php (81%) rename src/pocketmine/{level => world}/generator/object/Tree.php (88%) rename src/pocketmine/{level => world}/generator/populator/GroundCover.php (89%) rename src/pocketmine/{level => world}/generator/populator/Ore.php (79%) rename src/pocketmine/{level => world}/generator/populator/Populator.php (84%) rename src/pocketmine/{level => world}/generator/populator/TallGrass.php (83%) rename src/pocketmine/{level => world}/generator/populator/Tree.php (84%) rename src/pocketmine/{level => world}/light/BlockLightUpdate.php (97%) rename src/pocketmine/{level => world}/light/LightPopulationTask.php (78%) rename src/pocketmine/{level => world}/light/LightUpdate.php (87%) rename src/pocketmine/{level => world}/light/SkyLightUpdate.php (97%) rename src/pocketmine/{level => world}/particle/AngryVillagerParticle.php (96%) rename src/pocketmine/{level => world}/particle/BlockForceFieldParticle.php (96%) rename src/pocketmine/{level => world}/particle/BubbleParticle.php (96%) rename src/pocketmine/{level => world}/particle/CriticalParticle.php (96%) rename src/pocketmine/{level => world}/particle/DestroyBlockParticle.php (96%) rename src/pocketmine/{level => world}/particle/DragonEggTeleportParticle.php (97%) rename src/pocketmine/{level => world}/particle/DustParticle.php (96%) rename src/pocketmine/{level => world}/particle/EnchantParticle.php (96%) rename src/pocketmine/{level => world}/particle/EnchantmentTableParticle.php (96%) rename src/pocketmine/{level => world}/particle/EndermanTeleportParticle.php (96%) rename src/pocketmine/{level => world}/particle/EntityFlameParticle.php (96%) rename src/pocketmine/{level => world}/particle/ExplodeParticle.php (96%) rename src/pocketmine/{level => world}/particle/FlameParticle.php (96%) rename src/pocketmine/{level => world}/particle/FloatingTextParticle.php (98%) rename src/pocketmine/{level => world}/particle/GenericParticle.php (96%) rename src/pocketmine/{level => world}/particle/HappyVillagerParticle.php (96%) rename src/pocketmine/{level => world}/particle/HeartParticle.php (96%) rename src/pocketmine/{level => world}/particle/HugeExplodeParticle.php (96%) rename src/pocketmine/{level => world}/particle/HugeExplodeSeedParticle.php (96%) rename src/pocketmine/{level => world}/particle/InkParticle.php (96%) rename src/pocketmine/{level => world}/particle/InstantEnchantParticle.php (96%) rename src/pocketmine/{level => world}/particle/ItemBreakParticle.php (96%) rename src/pocketmine/{level => world}/particle/LavaDripParticle.php (96%) rename src/pocketmine/{level => world}/particle/LavaParticle.php (96%) rename src/pocketmine/{level => world}/particle/MobSpawnParticle.php (97%) rename src/pocketmine/{level => world}/particle/Particle.php (96%) rename src/pocketmine/{level => world}/particle/PortalParticle.php (96%) rename src/pocketmine/{level => world}/particle/PotionSplashParticle.php (97%) rename src/pocketmine/{level => world}/particle/RainSplashParticle.php (96%) rename src/pocketmine/{level => world}/particle/RedstoneParticle.php (96%) rename src/pocketmine/{level => world}/particle/SmokeParticle.php (96%) rename src/pocketmine/{level => world}/particle/SnowballPoofParticle.php (96%) rename src/pocketmine/{level => world}/particle/SplashParticle.php (96%) rename src/pocketmine/{level => world}/particle/SporeParticle.php (96%) rename src/pocketmine/{level => world}/particle/TerrainParticle.php (96%) rename src/pocketmine/{level => world}/particle/WaterDripParticle.php (96%) rename src/pocketmine/{level => world}/particle/WaterParticle.php (96%) rename src/pocketmine/{level => world}/sound/AnvilBreakSound.php (96%) rename src/pocketmine/{level => world}/sound/AnvilFallSound.php (96%) rename src/pocketmine/{level => world}/sound/AnvilUseSound.php (96%) rename src/pocketmine/{level => world}/sound/ArrowHitSound.php (96%) rename src/pocketmine/{level => world}/sound/BlazeShootSound.php (96%) rename src/pocketmine/{level => world}/sound/BlockBreakSound.php (97%) rename src/pocketmine/{level => world}/sound/BlockPlaceSound.php (97%) rename src/pocketmine/{level => world}/sound/BowShootSound.php (96%) rename src/pocketmine/{level => world}/sound/BucketEmptyLavaSound.php (96%) rename src/pocketmine/{level => world}/sound/BucketEmptyWaterSound.php (96%) rename src/pocketmine/{level => world}/sound/BucketFillLavaSound.php (96%) rename src/pocketmine/{level => world}/sound/BucketFillWaterSound.php (96%) rename src/pocketmine/{level => world}/sound/ChestCloseSound.php (96%) rename src/pocketmine/{level => world}/sound/ChestOpenSound.php (96%) rename src/pocketmine/{level => world}/sound/ClickSound.php (96%) rename src/pocketmine/{level => world}/sound/DoorBumpSound.php (96%) rename src/pocketmine/{level => world}/sound/DoorCrashSound.php (96%) rename src/pocketmine/{level => world}/sound/DoorSound.php (96%) rename src/pocketmine/{level => world}/sound/EnderChestCloseSound.php (96%) rename src/pocketmine/{level => world}/sound/EnderChestOpenSound.php (96%) rename src/pocketmine/{level => world}/sound/EndermanTeleportSound.php (96%) rename src/pocketmine/{level => world}/sound/ExplodeSound.php (96%) rename src/pocketmine/{level => world}/sound/FizzSound.php (96%) rename src/pocketmine/{level => world}/sound/FlintSteelSound.php (96%) rename src/pocketmine/{level => world}/sound/GhastShootSound.php (96%) rename src/pocketmine/{level => world}/sound/GhastSound.php (96%) rename src/pocketmine/{level => world}/sound/IgniteSound.php (96%) rename src/pocketmine/{level => world}/sound/ItemBreakSound.php (96%) rename src/pocketmine/{level => world}/sound/LaunchSound.php (96%) rename src/pocketmine/{level => world}/sound/LevelEventSound.php (97%) rename src/pocketmine/{level => world}/sound/PopSound.php (96%) rename src/pocketmine/{level => world}/sound/PotionSplashSound.php (96%) rename src/pocketmine/{level => world}/sound/RedstonePowerOffSound.php (96%) rename src/pocketmine/{level => world}/sound/RedstonePowerOnSound.php (96%) rename src/pocketmine/{level => world}/sound/Sound.php (96%) rename src/pocketmine/{level => world}/sound/ThrowSound.php (96%) rename src/pocketmine/{level => world}/sound/TotemUseSound.php (96%) rename src/pocketmine/{level => world}/sound/XpCollectSound.php (96%) rename src/pocketmine/{level => world}/sound/XpLevelUpSound.php (97%) rename src/pocketmine/{level => world}/utils/SubChunkIteratorManager.php (83%) rename tests/phpunit/level/format/io/{AbstractLevelProvider.php => AbstractWorldProvider.php} (87%) rename tests/phpunit/level/format/io/{InterfaceLevelProvider.php => InterfaceWorldProvider.php} (88%) rename {src/pocketmine => tests/phpunit}/level/format/io/SubChunkConverter.php (86%) diff --git a/.travis.yml b/.travis.yml index b86d5c9b95..79aab78362 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ before_script: - cd .. - git clone https://github.com/pmmp/ext-chunkutils2.git chunkutils - cd chunkutils - - git checkout 5c96eeea7667ef15aa684b6a455a2a46699aff37 + - git checkout d8d762a597ac0da6f333f862096d6af0e6286b75 - phpize - ./configure && make && make install - cd .. diff --git a/src/pocketmine/MemoryManager.php b/src/pocketmine/MemoryManager.php index 530dd3bcf3..79c31a95dd 100644 --- a/src/pocketmine/MemoryManager.php +++ b/src/pocketmine/MemoryManager.php @@ -214,14 +214,14 @@ class MemoryManager{ $this->server->getLogger()->debug(sprintf("[Memory Manager] %sLow memory triggered, limit %gMB, using %gMB", $global ? "Global " : "", round(($limit / 1024) / 1024, 2), round(($memory / 1024) / 1024, 2))); if($this->lowMemClearWorldCache){ - foreach($this->server->getLevelManager()->getLevels() as $level){ - $level->clearCache(true); + foreach($this->server->getWorldManager()->getWorlds() as $world){ + $world->clearCache(true); } } if($this->lowMemChunkGC){ - foreach($this->server->getLevelManager()->getLevels() as $level){ - $level->doChunkGarbageCollection(); + foreach($this->server->getWorldManager()->getWorlds() as $world){ + $world->doChunkGarbageCollection(); } } diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 13738689f5..a470e21802 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -84,11 +84,6 @@ use pocketmine\item\WritableBook; use pocketmine\item\WrittenBook; use pocketmine\lang\TextContainer; use pocketmine\lang\TranslationContainer; -use pocketmine\level\ChunkListener; -use pocketmine\level\ChunkLoader; -use pocketmine\level\format\Chunk; -use pocketmine\level\Level; -use pocketmine\level\Position; use pocketmine\math\Vector3; use pocketmine\metadata\MetadataValue; use pocketmine\nbt\tag\ByteTag; @@ -116,6 +111,11 @@ use pocketmine\tile\Tile; use pocketmine\timings\Timings; use pocketmine\utils\TextFormat; use pocketmine\utils\UUID; +use pocketmine\world\ChunkListener; +use pocketmine\world\ChunkLoader; +use pocketmine\world\format\Chunk; +use pocketmine\world\Position; +use pocketmine\world\World; use function abs; use function array_merge; use function assert; @@ -305,22 +305,22 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $spawnReset = false; - if($namedtag !== null and ($level = $this->server->getLevelManager()->getLevelByName($namedtag->getString("Level", "", true))) !== null){ + if($namedtag !== null and ($world = $this->server->getWorldManager()->getWorldByName($namedtag->getString("Level", "", true))) !== null){ /** @var float[] $pos */ $pos = $namedtag->getListTag("Pos")->getAllValues(); $spawn = new Vector3($pos[0], $pos[1], $pos[2]); }else{ - $level = $this->server->getLevelManager()->getDefaultLevel(); //TODO: default level might be null - $spawn = $level->getSpawnLocation(); + $world = $this->server->getWorldManager()->getDefaultWorld(); //TODO: default world might be null + $spawn = $world->getSpawnLocation(); $spawnReset = true; } //load the spawn chunk so we can see the terrain - $level->registerChunkLoader($this, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4, true); - $level->registerChunkListener($this, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4); - $this->usedChunks[Level::chunkHash($spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4)] = false; + $world->registerChunkLoader($this, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4, true); + $world->registerChunkListener($this, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4); + $this->usedChunks[World::chunkHash($spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4)] = false; if($spawnReset){ - $spawn = $level->getSafeSpawn($spawn); + $spawn = $world->getSafeSpawn($spawn); } if($namedtag === null){ @@ -337,7 +337,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, ])); } - parent::__construct($level, $namedtag); + parent::__construct($world, $namedtag); $ev = new PlayerLoginEvent($this, "Plugin reason"); $ev->call(); @@ -352,7 +352,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->networkSession->getIp(), $this->networkSession->getPort(), $this->id, - $this->level->getDisplayName(), + $this->world->getDisplayName(), round($this->x, 4), round($this->y, 4), round($this->z, 4) @@ -398,10 +398,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } if(!$this->hasValidSpawnPosition()){ - if(($level = $this->server->getLevelManager()->getLevelByName($nbt->getString("SpawnLevel", ""))) instanceof Level){ - $this->spawnPosition = new Position($nbt->getInt("SpawnX"), $nbt->getInt("SpawnY"), $nbt->getInt("SpawnZ"), $level); + if(($world = $this->server->getWorldManager()->getWorldByName($nbt->getString("SpawnLevel", ""))) instanceof World){ + $this->spawnPosition = new Position($nbt->getInt("SpawnX"), $nbt->getInt("SpawnY"), $nbt->getInt("SpawnZ"), $world); }else{ - $this->spawnPosition = $this->level->getSafeSpawn(); + $this->spawnPosition = $this->world->getSafeSpawn(); } } } @@ -555,7 +555,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @param Player $player */ public function spawnTo(Player $player) : void{ - if($this->isAlive() and $player->isAlive() and $player->getLevel() === $this->level and $player->canSee($this) and !$this->isSpectator()){ + if($this->isAlive() and $player->isAlive() and $player->getWorld() === $this->world and $player->canSee($this) and !$this->isSpectator()){ parent::spawnTo($player); } } @@ -931,20 +931,20 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } - protected function switchLevel(Level $targetLevel) : bool{ - $oldLevel = $this->level; - if(parent::switchLevel($targetLevel)){ - if($oldLevel !== null){ + protected function switchWorld(World $targetWorld) : bool{ + $oldWorld = $this->world; + if(parent::switchWorld($targetWorld)){ + if($oldWorld !== null){ foreach($this->usedChunks as $index => $d){ - Level::getXZ($index, $X, $Z); - $this->unloadChunk($X, $Z, $oldLevel); + World::getXZ($index, $X, $Z); + $this->unloadChunk($X, $Z, $oldWorld); } } $this->usedChunks = []; $this->loadQueue = []; - $this->level->sendTime($this); - $this->level->sendDifficulty($this); + $this->world->sendTime($this); + $this->world->sendDifficulty($this); return true; } @@ -952,15 +952,15 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return false; } - protected function unloadChunk(int $x, int $z, ?Level $level = null){ - $level = $level ?? $this->level; - $index = Level::chunkHash($x, $z); + protected function unloadChunk(int $x, int $z, ?World $world = null){ + $world = $world ?? $this->world; + $index = World::chunkHash($x, $z); if(isset($this->usedChunks[$index])){ $this->networkSession->stopUsingChunk($x, $z); unset($this->usedChunks[$index]); } - $level->unregisterChunkLoader($this, $x, $z); - $level->unregisterChunkListener($this, $x, $z); + $world->unregisterChunkLoader($this, $x, $z); + $world->unregisterChunkListener($this, $x, $z); unset($this->loadQueue[$index]); } @@ -969,8 +969,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return; } - assert(isset($this->usedChunks[Level::chunkHash($x, $z)])); - $this->usedChunks[Level::chunkHash($x, $z)] = true; + assert(isset($this->usedChunks[World::chunkHash($x, $z)])); + $this->usedChunks[World::chunkHash($x, $z)] = true; $spawn = $this->spawnChunkLoadCount++ === $this->spawnThreshold; $this->networkSession->startUsingChunk($x, $z, $spawn); @@ -996,21 +996,21 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $X = null; $Z = null; - Level::getXZ($index, $X, $Z); + World::getXZ($index, $X, $Z); assert(is_int($X) and is_int($Z)); ++$count; $this->usedChunks[$index] = false; - $this->level->registerChunkLoader($this, $X, $Z, true); - $this->level->registerChunkListener($this, $X, $Z); + $this->world->registerChunkLoader($this, $X, $Z, true); + $this->world->registerChunkListener($this, $X, $Z); - if(!$this->level->populateChunk($X, $Z)){ + if(!$this->world->populateChunk($X, $Z)){ continue; } unset($this->loadQueue[$index]); - $this->level->requestChunk($X, $Z, $this); + $this->world->requestChunk($X, $Z, $this); } Timings::$playerChunkSendTimer->stopTiming(); @@ -1065,23 +1065,23 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, //If the chunk is in the radius, others at the same offsets in different quadrants are also guaranteed to be. /* Top right quadrant */ - yield Level::chunkHash($centerX + $x, $centerZ + $z); + yield World::chunkHash($centerX + $x, $centerZ + $z); /* Top left quadrant */ - yield Level::chunkHash($centerX - $x - 1, $centerZ + $z); + yield World::chunkHash($centerX - $x - 1, $centerZ + $z); /* Bottom right quadrant */ - yield Level::chunkHash($centerX + $x, $centerZ - $z - 1); + yield World::chunkHash($centerX + $x, $centerZ - $z - 1); /* Bottom left quadrant */ - yield Level::chunkHash($centerX - $x - 1, $centerZ - $z - 1); + yield World::chunkHash($centerX - $x - 1, $centerZ - $z - 1); if($x !== $z){ /* Top right quadrant mirror */ - yield Level::chunkHash($centerX + $z, $centerZ + $x); + yield World::chunkHash($centerX + $z, $centerZ + $x); /* Top left quadrant mirror */ - yield Level::chunkHash($centerX - $z - 1, $centerZ + $x); + yield World::chunkHash($centerX - $z - 1, $centerZ + $x); /* Bottom right quadrant mirror */ - yield Level::chunkHash($centerX + $z, $centerZ - $x - 1); + yield World::chunkHash($centerX + $z, $centerZ - $x - 1); /* Bottom left quadrant mirror */ - yield Level::chunkHash($centerX - $z - 1, $centerZ - $x - 1); + yield World::chunkHash($centerX - $z - 1, $centerZ - $x - 1); } } } @@ -1105,7 +1105,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } foreach($unloadChunks as $index => $bool){ - Level::getXZ($index, $X, $Z); + World::getXZ($index, $X, $Z); $this->unloadChunk($X, $Z); } @@ -1139,9 +1139,9 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($this->hasValidSpawnPosition()){ return $this->spawnPosition; }else{ - $level = $this->server->getLevelManager()->getDefaultLevel(); + $world = $this->server->getWorldManager()->getDefaultWorld(); - return $level->getSafeSpawn(); + return $world->getSafeSpawn(); } } @@ -1160,11 +1160,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, */ public function setSpawn(Vector3 $pos){ if(!($pos instanceof Position)){ - $level = $this->level; + $world = $this->world; }else{ - $level = $pos->getLevel(); + $world = $pos->getWorld(); } - $this->spawnPosition = new Position($pos->x, $pos->y, $pos->z, $level); + $this->spawnPosition = new Position($pos->x, $pos->y, $pos->z, $world); $this->networkSession->syncPlayerSpawnPoint($this->spawnPosition); } @@ -1186,7 +1186,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $pos = $pos->floor(); - $b = $this->level->getBlock($pos); + $b = $this->world->getBlock($pos); $ev = new PlayerBedEnterEvent($this, $b); $ev->call(); @@ -1205,14 +1205,14 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->setSpawn($pos); - $this->level->setSleepTicks(60); + $this->world->setSleepTicks(60); return true; } public function stopSleep(){ if($this->sleeping instanceof Vector3){ - $b = $this->level->getBlock($this->sleeping); + $b = $this->world->getBlock($this->sleeping); if($b instanceof Bed){ $b->setOccupied(false); } @@ -1222,7 +1222,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->propertyManager->setBlockPos(EntityMetadataProperties::PLAYER_BED_POSITION, null); $this->setPlayerFlag(PlayerMetadataFlags::SLEEP, false); - $this->level->setSleepTicks(0); + $this->world->setSleepTicks(0); $this->broadcastAnimation([$this], AnimatePacket::ACTION_STOP_SLEEP); } @@ -1410,7 +1410,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $bb->minY = $this->y - 0.2; $bb->maxY = $this->y + 0.2; - $this->onGround = $this->isCollided = count($this->level->getCollisionBlocks($bb, true)) > 0; + $this->onGround = $this->isCollided = count($this->world->getCollisionBlocks($bb, true)) > 0; } public function canBeMovedByCurrents() : bool{ @@ -1418,7 +1418,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } protected function checkNearEntities(){ - foreach($this->level->getNearbyEntities($this->boundingBox->expandedCopy(1, 0.5, 1), $this) as $entity){ + foreach($this->world->getNearbyEntities($this->boundingBox->expandedCopy(1, 0.5, 1), $this) as $entity){ $entity->scheduleUpdate(); if(!$entity->isAlive() or $entity->isFlaggedForDespawn()){ @@ -1500,7 +1500,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->server->getLogger()->warning($this->getName() . " moved too fast, reverting movement"); $this->server->getLogger()->debug("Old position: " . $this->asVector3() . ", new position: " . $this->newPosition); $revert = true; - }elseif(!$this->level->isInLoadedTerrain($newPos) or !$this->level->isChunkGenerated($newPos->getFloorX() >> 4, $newPos->getFloorZ() >> 4)){ + }elseif(!$this->world->isInLoadedTerrain($newPos) or !$this->world->isChunkGenerated($newPos->getFloorX() >> 4, $newPos->getFloorZ() >> 4)){ $revert = true; $this->nextChunkOrderRun = 0; } @@ -1864,14 +1864,14 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } public function pickBlock(Vector3 $pos, bool $addTileNBT) : bool{ - $block = $this->level->getBlock($pos); + $block = $this->world->getBlock($pos); if($block instanceof UnknownBlock){ return true; } $item = $block->getPickedItem(); if($addTileNBT){ - $tile = $this->getLevel()->getTile($block); + $tile = $this->getWorld()->getTile($block); if($tile instanceof Tile){ $nbt = $tile->getCleanedNBT(); if($nbt instanceof CompoundTag){ @@ -1922,12 +1922,12 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return false; //TODO: maybe this should throw an exception instead? } - $target = $this->level->getBlock($pos); + $target = $this->world->getBlock($pos); $ev = new PlayerInteractEvent($this, $this->inventory->getItemInHand(), $target, null, $face, PlayerInteractEvent::LEFT_CLICK_BLOCK); $ev->call(); if($ev->isCancelled()){ - $this->level->sendBlocks([$this], [$target]); + $this->world->sendBlocks([$this], [$target]); $this->inventory->sendHeldItem($this); return true; } @@ -1937,7 +1937,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $block = $target->getSide($face); if($block->getId() === BlockLegacyIds::FIRE){ - $this->level->setBlock($block, BlockFactory::get(BlockLegacyIds::AIR)); + $this->world->setBlock($block, BlockFactory::get(BlockLegacyIds::AIR)); return true; } @@ -1945,7 +1945,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, //TODO: improve this to take stuff like swimming, ladders, enchanted tools into account, fix wrong tool break time calculations for bad tools (pmmp/PocketMine-MP#211) $breakTime = ceil($target->getBreakTime($this->inventory->getItemInHand()) * 20); if($breakTime > 0){ - $this->level->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_START_BREAK, (int) (65535 / $breakTime)); + $this->world->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_START_BREAK, (int) (65535 / $breakTime)); } } @@ -1953,8 +1953,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } public function continueBreakBlock(Vector3 $pos, int $face) : void{ - $block = $this->level->getBlock($pos); - $this->level->broadcastLevelEvent( + $block = $this->world->getBlock($pos); + $this->world->broadcastLevelEvent( $pos, LevelEventPacket::EVENT_PARTICLE_PUNCH_BLOCK, $block->getRuntimeId() | ($face << 24) @@ -1964,7 +1964,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } public function stopBreakBlock(Vector3 $pos) : void{ - $this->level->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_STOP_BREAK); + $this->world->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_STOP_BREAK); } /** @@ -1980,7 +1980,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($this->canInteract($pos->add(0.5, 0.5, 0.5), $this->isCreative() ? 13 : 7) and !$this->isSpectator()){ $item = $this->inventory->getItemInHand(); $oldItem = clone $item; - if($this->level->useBreakOn($pos, $item, $this, true)){ + if($this->world->useBreakOn($pos, $item, $this, true)){ if($this->hasFiniteResources() and !$item->equalsExact($oldItem)){ $this->inventory->setItemInHand($item); } @@ -1992,12 +1992,12 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->inventory->sendContents($this); $this->inventory->sendHeldItem($this); - $target = $this->level->getBlock($pos); + $target = $this->world->getBlock($pos); /** @var Block[] $blocks */ $blocks = $target->getAllSides(); $blocks[] = $target; - $this->level->sendBlocks([$this], $blocks); + $this->world->sendBlocks([$this], $blocks); return false; } @@ -2017,7 +2017,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($this->canInteract($pos->add(0.5, 0.5, 0.5), 13) and !$this->isSpectator()){ $item = $this->inventory->getItemInHand(); //this is a copy of the real item $oldItem = clone $item; - if($this->level->useItemOn($pos, $item, $face, $clickOffset, $this, true)){ + if($this->world->useItemOn($pos, $item, $face, $clickOffset, $this, true)){ if($this->hasFiniteResources() and !$item->equalsExact($oldItem)){ $this->inventory->setItemInHand($item); } @@ -2031,13 +2031,13 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return true; } - $target = $this->level->getBlock($pos); + $target = $this->world->getBlock($pos); $block = $target->getSide($face); /** @var Block[] $blocks */ $blocks = array_merge($target->getAllSides(), $block->getAllSides()); //getAllSides() on each of these will include $target and $block because they are next to each other - $this->level->sendBlocks([$this], $blocks); + $this->world->sendBlocks([$this], $blocks); return false; } @@ -2178,7 +2178,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @param Item $item */ public function dropItem(Item $item) : void{ - $this->level->dropItem($this->add(0, 1.3, 0), $item, $this->getDirectionVector()->multiply(0.4), 40); + $this->world->dropItem($this->add(0, 1.3, 0), $item, $this->getDirectionVector()->multiply(0.4), 40); } public function handleBookEdit(BookEditPacket $packet) : bool{ @@ -2564,10 +2564,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($this->isValid()){ foreach($this->usedChunks as $index => $d){ - Level::getXZ($index, $chunkX, $chunkZ); - $this->level->unregisterChunkLoader($this, $chunkX, $chunkZ); - $this->level->unregisterChunkListener($this, $chunkX, $chunkZ); - foreach($this->level->getChunkEntities($chunkX, $chunkZ) as $entity){ + World::getXZ($index, $chunkX, $chunkZ); + $this->world->unregisterChunkLoader($this, $chunkX, $chunkZ); + $this->world->unregisterChunkListener($this, $chunkX, $chunkZ); + foreach($this->world->getChunkEntities($chunkX, $chunkZ) as $entity){ $entity->despawnFrom($this); } unset($this->usedChunks[$index]); @@ -2626,11 +2626,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $nbt = $this->saveNBT(); if($this->isValid()){ - $nbt->setString("Level", $this->level->getFolderName()); + $nbt->setString("Level", $this->world->getFolderName()); } if($this->hasValidSpawnPosition()){ - $nbt->setString("SpawnLevel", $this->spawnPosition->getLevel()->getFolderName()); + $nbt->setString("SpawnLevel", $this->spawnPosition->getWorld()->getFolderName()); $nbt->setInt("SpawnX", $this->spawnPosition->getFloorX()); $nbt->setInt("SpawnY", $this->spawnPosition->getFloorY()); $nbt->setInt("SpawnZ", $this->spawnPosition->getFloorZ()); @@ -2671,7 +2671,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if(!$ev->getKeepInventory()){ foreach($ev->getDrops() as $item){ - $this->level->dropItem($this, $item); + $this->world->dropItem($this, $item); } if($this->inventory !== null){ @@ -2683,7 +2683,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } - $this->level->dropExperience($this, $ev->getXpDropAmount()); + $this->world->dropExperience($this, $ev->getXpDropAmount()); $this->setXpAndProgress(0, 0); if($ev->getDeathMessage() != ""){ @@ -2709,7 +2709,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $ev = new PlayerRespawnEvent($this, $this->getSpawn()); $ev->call(); - $realSpawn = Position::fromObject($ev->getRespawnPosition()->add(0.5, 0, 0.5), $ev->getRespawnPosition()->getLevel()); + $realSpawn = Position::fromObject($ev->getRespawnPosition()->add(0.5, 0, 0.5), $ev->getRespawnPosition()->getWorld()); $this->teleport($realSpawn); $this->setSprinting(false); @@ -3038,7 +3038,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } public function onChunkChanged(Chunk $chunk) : void{ - if(isset($this->usedChunks[$hash = Level::chunkHash($chunk->getX(), $chunk->getZ())])){ + if(isset($this->usedChunks[$hash = World::chunkHash($chunk->getX(), $chunk->getZ())])){ $this->usedChunks[$hash] = false; $this->nextChunkOrderRun = 0; } diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 346e79dbf3..6a41f1fdef 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -47,17 +47,9 @@ use pocketmine\item\ItemFactory; use pocketmine\lang\Language; use pocketmine\lang\LanguageNotFoundException; use pocketmine\lang\TextContainer; -use pocketmine\level\biome\Biome; -use pocketmine\level\format\io\LevelProviderManager; -use pocketmine\level\format\io\WritableLevelProvider; -use pocketmine\level\generator\Generator; -use pocketmine\level\generator\GeneratorManager; -use pocketmine\level\generator\normal\Normal; -use pocketmine\level\Level; -use pocketmine\level\LevelManager; use pocketmine\metadata\EntityMetadataStore; -use pocketmine\metadata\LevelMetadataStore; use pocketmine\metadata\PlayerMetadataStore; +use pocketmine\metadata\WorldMetadataStore; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; @@ -102,6 +94,14 @@ use pocketmine\utils\Terminal; use pocketmine\utils\TextFormat; use pocketmine\utils\Utils; use pocketmine\utils\UUID; +use pocketmine\world\biome\Biome; +use pocketmine\world\format\io\WorldProviderManager; +use pocketmine\world\format\io\WritableWorldProvider; +use pocketmine\world\generator\Generator; +use pocketmine\world\generator\GeneratorManager; +use pocketmine\world\generator\normal\Normal; +use pocketmine\world\World; +use pocketmine\world\WorldManager; use function array_key_exists; use function array_shift; use function array_sum; @@ -238,8 +238,8 @@ class Server{ /** @var ResourcePackManager */ private $resourceManager; - /** @var LevelManager */ - private $levelManager; + /** @var WorldManager */ + private $worldManager; /** @var int */ private $maxPlayers; @@ -253,8 +253,8 @@ class Server{ /** @var PlayerMetadataStore */ private $playerMetadata; - /** @var LevelMetadataStore */ - private $levelMetadata; + /** @var WorldMetadataStore */ + private $worldMetadata; /** @var Network */ private $network; @@ -436,7 +436,7 @@ class Server{ } /** - * Returns Server global difficulty. Note that this may be overridden in individual Levels. + * Returns Server global difficulty. Note that this may be overridden in individual worlds. * @return int */ public function getDifficulty() : int{ @@ -493,10 +493,10 @@ class Server{ } /** - * @return LevelMetadataStore + * @return WorldMetadataStore */ - public function getLevelMetadata(){ - return $this->levelMetadata; + public function getWorldMetadata(){ + return $this->worldMetadata; } /** @@ -528,10 +528,10 @@ class Server{ } /** - * @return LevelManager + * @return WorldManager */ - public function getLevelManager() : LevelManager{ - return $this->levelManager; + public function getWorldManager() : WorldManager{ + return $this->worldManager; } public function getAsyncPool() : AsyncPool{ @@ -1130,7 +1130,7 @@ class Server{ $this->entityMetadata = new EntityMetadataStore(); $this->playerMetadata = new PlayerMetadataStore(); - $this->levelMetadata = new LevelMetadataStore(); + $this->worldMetadata = new WorldMetadataStore(); $this->operators = new Config($this->dataPath . "ops.txt", Config::ENUM); $this->whitelist = new Config($this->dataPath . "white-list.txt", Config::ENUM); @@ -1156,8 +1156,8 @@ class Server{ $this->logger->warning($this->getLanguage()->translateString("pocketmine.server.authProperty.disabled")); } - if($this->getConfigBool("hardcore", false) and $this->getDifficulty() < Level::DIFFICULTY_HARD){ - $this->setConfigInt("difficulty", Level::DIFFICULTY_HARD); + if($this->getConfigBool("hardcore", false) and $this->getDifficulty() < World::DIFFICULTY_HARD){ + $this->setConfigInt("difficulty", World::DIFFICULTY_HARD); } if(\pocketmine\DEBUG >= 0){ @@ -1213,18 +1213,18 @@ class Server{ $this->pluginManager->registerInterface(new PharPluginLoader($this->autoloader)); $this->pluginManager->registerInterface(new ScriptPluginLoader()); - LevelProviderManager::init(); + WorldProviderManager::init(); if( - ($format = LevelProviderManager::getProviderByName($formatName = (string) $this->getProperty("level-settings.default-format"))) !== null and - is_a($format, WritableLevelProvider::class, true) + ($format = WorldProviderManager::getProviderByName($formatName = (string) $this->getProperty("level-settings.default-format"))) !== null and + is_a($format, WritableWorldProvider::class, true) ){ - LevelProviderManager::setDefault($format); + WorldProviderManager::setDefault($format); }elseif($formatName !== ""){ $this->logger->warning($this->language->translateString("pocketmine.level.badDefaultFormat", [$formatName])); } GeneratorManager::registerDefaultGenerators(); - $this->levelManager = new LevelManager($this); + $this->worldManager = new WorldManager($this); $this->updater = new AutoUpdater($this, $this->getProperty("auto-updater.host", "update.pmmp.io")); @@ -1241,7 +1241,7 @@ class Server{ }elseif(!is_array($options)){ continue; } - if(!$this->levelManager->loadLevel($name, true)){ + if(!$this->worldManager->loadWorld($name, true)){ if(isset($options["generator"])){ $generatorOptions = explode(":", $options["generator"]); $generator = GeneratorManager::getGenerator(array_shift($generatorOptions)); @@ -1252,19 +1252,19 @@ class Server{ $generator = Normal::class; } - $this->levelManager->generateLevel($name, Generator::convertSeed((string) ($options["seed"] ?? "")), $generator, $options); + $this->worldManager->generateWorld($name, Generator::convertSeed((string) ($options["seed"] ?? "")), $generator, $options); } } - if($this->levelManager->getDefaultLevel() === null){ + if($this->worldManager->getDefaultWorld() === null){ $default = $this->getConfigString("level-name", "world"); if(trim($default) == ""){ $this->getLogger()->warning("level-name cannot be null, using default"); $default = "world"; $this->setConfigString("level-name", "world"); } - if(!$this->levelManager->loadLevel($default, true)){ - $this->levelManager->generateLevel( + if(!$this->worldManager->loadWorld($default, true)){ + $this->worldManager->generateWorld( $default, Generator::convertSeed($this->getConfigString("level-seed")), GeneratorManager::getGenerator($this->getConfigString("level-type")), @@ -1272,14 +1272,14 @@ class Server{ ); } - $level = $this->levelManager->getLevelByName($default); - if($level === null){ + $world = $this->worldManager->getWorldByName($default); + if($world === null){ $this->getLogger()->emergency($this->getLanguage()->translateString("pocketmine.level.defaultError")); $this->forceShutdown(); return; } - $this->levelManager->setDefaultLevel($level); + $this->worldManager->setDefaultWorld($world); } $this->enablePlugins(PluginLoadOrder::POSTWORLD()); @@ -1628,10 +1628,10 @@ class Server{ $this->network->getSessionManager()->close($this->getProperty("settings.shutdown-message", "Server closed")); } - if($this->levelManager instanceof LevelManager){ + if($this->worldManager instanceof WorldManager){ $this->getLogger()->debug("Unloading all worlds"); - foreach($this->levelManager->getLevels() as $level){ - $this->levelManager->unloadLevel($level, true); + foreach($this->worldManager->getWorlds() as $world){ + $this->worldManager->unloadWorld($world, true); } } @@ -1951,7 +1951,7 @@ class Server{ $this->asyncPool->collectTasks(); Timings::$schedulerAsyncTimer->stopTiming(); - $this->levelManager->tick($this->tickCounter); + $this->worldManager->tick($this->tickCounter); Timings::$connectionTimer->startTiming(); $this->network->tick(); @@ -1978,8 +1978,8 @@ class Server{ } if(($this->tickCounter % 100) === 0){ - foreach($this->levelManager->getLevels() as $level){ - $level->clearCache(); + foreach($this->worldManager->getWorlds() as $world){ + $world->clearCache(); } if($this->getTicksPerSecondAverage() < 12){ diff --git a/src/pocketmine/block/Banner.php b/src/pocketmine/block/Banner.php index fac53405b0..9d6b9998f5 100644 --- a/src/pocketmine/block/Banner.php +++ b/src/pocketmine/block/Banner.php @@ -92,7 +92,7 @@ class Banner extends Transparent{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->level->getTile($this); + $tile = $this->world->getTile($this); if($tile instanceof TileBanner){ $this->baseColor = $tile->getBaseColor(); $this->setPatterns($tile->getPatterns()); @@ -101,7 +101,7 @@ class Banner extends Transparent{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->level->getTile($this); + $tile = $this->world->getTile($this); assert($tile instanceof TileBanner); $tile->setBaseColor($this->baseColor); $tile->setPatterns($this->patterns); @@ -164,7 +164,7 @@ class Banner extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::opposite($this->facing))->getId() === BlockLegacyIds::AIR){ - $this->getLevel()->useBreakOn($this); + $this->getWorld()->useBreakOn($this); } } diff --git a/src/pocketmine/block/BaseRail.php b/src/pocketmine/block/BaseRail.php index 3dfb543ed9..1d894108ac 100644 --- a/src/pocketmine/block/BaseRail.php +++ b/src/pocketmine/block/BaseRail.php @@ -247,7 +247,7 @@ abstract class BaseRail extends Flowable{ if(isset($otherPossible[$otherSide])){ $otherConnections[] = $otherSide; $other->setConnections($otherConnections); - $other->level->setBlock($other, $other); + $other->world->setBlock($other, $other); $changed = true; $thisConnections[] = $thisSide; @@ -275,11 +275,11 @@ abstract class BaseRail extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->level->useBreakOn($this); + $this->world->useBreakOn($this); }else{ foreach($this->connections as $connection){ if(($connection & self::FLAG_ASCEND) !== 0 and $this->getSide($connection & ~self::FLAG_ASCEND)->isTransparent()){ - $this->level->useBreakOn($this); + $this->world->useBreakOn($this); break; } } diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index a82e3ecdbb..841589b531 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -29,7 +29,6 @@ use pocketmine\item\Bed as ItemBed; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\lang\TranslationContainer; -use pocketmine\level\Level; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; use pocketmine\math\Facing; @@ -37,6 +36,7 @@ use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\tile\Bed as TileBed; use pocketmine\utils\TextFormat; +use pocketmine\world\World; class Bed extends Transparent{ private const BITFLAG_OCCUPIED = 0x04; @@ -75,7 +75,7 @@ class Bed extends Transparent{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); //read extra state information from the tile - this is an ugly hack - $tile = $this->level->getTile($this); + $tile = $this->world->getTile($this); if($tile instanceof TileBed){ $this->color = $tile->getColor(); } @@ -84,7 +84,7 @@ class Bed extends Transparent{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); //extra block properties storage hack - $tile = $this->level->getTile($this); + $tile = $this->world->getTile($this); if($tile instanceof TileBed){ $tile->setColor($this->color); } @@ -111,11 +111,11 @@ class Bed extends Transparent{ public function setOccupied(bool $occupied = true) : void{ $this->occupied = $occupied; - $this->level->setBlock($this, $this, false); + $this->world->setBlock($this, $this, false); if(($other = $this->getOtherHalf()) !== null){ $other->occupied = $occupied; - $this->level->setBlock($other, $other, false); + $this->world->setBlock($other, $other, false); } } @@ -150,9 +150,9 @@ class Bed extends Transparent{ return true; } - $time = $this->getLevel()->getTime() % Level::TIME_FULL; + $time = $this->getWorld()->getTime() % World::TIME_FULL; - $isNight = ($time >= Level::TIME_NIGHT and $time < Level::TIME_SUNRISE); + $isNight = ($time >= World::TIME_NIGHT and $time < World::TIME_SUNRISE); if(!$isNight){ $player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.noSleep")); @@ -188,7 +188,7 @@ class Bed extends Transparent{ parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); $nextState = clone $this; $nextState->head = true; - $this->getLevel()->setBlock($next, $nextState); + $this->getWorld()->setBlock($next, $nextState); return true; } diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 0eb7f1efcd..bd573b15b4 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -31,8 +31,6 @@ use pocketmine\entity\Entity; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\level\Level; -use pocketmine\level\Position; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\RayTraceResult; @@ -43,6 +41,8 @@ use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; use pocketmine\Player; use pocketmine\plugin\Plugin; use pocketmine\tile\TileFactory; +use pocketmine\world\Position; +use pocketmine\world\World; use function array_merge; use function assert; use function dechex; @@ -174,16 +174,16 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ } public function writeStateToWorld() : void{ - $this->level->getChunkAtPosition($this)->setFullBlock($this->x & 0xf, $this->y, $this->z & 0xf, $this->getFullId()); + $this->world->getChunkAtPosition($this)->setFullBlock($this->x & 0xf, $this->y, $this->z & 0xf, $this->getFullId()); $tileType = $this->idInfo->getTileClass(); - $oldTile = $this->level->getTile($this); + $oldTile = $this->world->getTile($this); if($oldTile !== null and ($tileType === null or !($oldTile instanceof $tileType))){ $oldTile->close(); $oldTile = null; } if($oldTile === null and $tileType !== null){ - $this->level->addTile(TileFactory::create($tileType, $this->level, $this->asVector3())); + $this->world->addTile(TileFactory::create($tileType, $this->world, $this->asVector3())); } } @@ -244,7 +244,7 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ * @return bool */ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - return $this->getLevel()->setBlock($blockReplace, $this); + return $this->getWorld()->setBlock($blockReplace, $this); } /** @@ -312,10 +312,10 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ * @return bool */ public function onBreak(Item $item, ?Player $player = null) : bool{ - if(($t = $this->level->getTile($this)) !== null){ + if(($t = $this->world->getTile($this)) !== null){ $t->onBlockDestroyed(); } - return $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); + return $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); } @@ -370,7 +370,7 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ } /** - * Called when this block is updated by the delayed blockupdate scheduler in the level. + * Called when this block is updated by the delayed blockupdate scheduler in the world. */ public function onScheduledUpdate() : void{ @@ -494,18 +494,19 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ } /** - * @internal - * - * @param Level $level + * @param World $world * @param int $x * @param int $y * @param int $z + * + *@internal + * */ - final public function position(Level $level, int $x, int $y, int $z) : void{ + final public function position(World $world, int $x, int $y, int $z) : void{ $this->x = $x; $this->y = $y; $this->z = $z; - $this->level = $level; + $this->world = $world; } /** @@ -653,7 +654,7 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ */ public function getSide(int $side, int $step = 1){ if($this->isValid()){ - return $this->getLevel()->getBlock(Vector3::getSide($side, $step)); + return $this->getWorld()->getBlock(Vector3::getSide($side, $step)); } return BlockFactory::get(BlockLegacyIds::AIR, 0, Position::fromObject(Vector3::getSide($side, $step))); @@ -812,13 +813,13 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue) : void{ if($this->isValid()){ - $this->level->getBlockMetadata()->setMetadata($this, $metadataKey, $newMetadataValue); + $this->world->getBlockMetadata()->setMetadata($this, $metadataKey, $newMetadataValue); } } public function getMetadata(string $metadataKey){ if($this->isValid()){ - return $this->level->getBlockMetadata()->getMetadata($this, $metadataKey); + return $this->world->getBlockMetadata()->getMetadata($this, $metadataKey); } return null; @@ -826,7 +827,7 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ public function hasMetadata(string $metadataKey) : bool{ if($this->isValid()){ - return $this->level->getBlockMetadata()->hasMetadata($this, $metadataKey); + return $this->world->getBlockMetadata()->hasMetadata($this, $metadataKey); } return false; @@ -834,7 +835,7 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ public function removeMetadata(string $metadataKey, Plugin $owningPlugin) : void{ if($this->isValid()){ - $this->level->getBlockMetadata()->removeMetadata($this, $metadataKey, $owningPlugin); + $this->world->getBlockMetadata()->removeMetadata($this, $metadataKey, $owningPlugin); } } } diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 691e11a2c1..217f06e2d1 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -31,7 +31,7 @@ use pocketmine\block\utils\TreeType; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\ItemIds; -use pocketmine\level\Position; +use pocketmine\world\Position; use pocketmine\tile\Comparator; use function array_fill; use function array_filter; @@ -645,7 +645,7 @@ class BlockFactory{ } if($pos !== null){ - $block->position($pos->getLevel(), $pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ()); + $block->position($pos->getWorld(), $pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ()); } return $block; diff --git a/src/pocketmine/block/Button.php b/src/pocketmine/block/Button.php index da13e9aeec..87247a9600 100644 --- a/src/pocketmine/block/Button.php +++ b/src/pocketmine/block/Button.php @@ -25,11 +25,11 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; -use pocketmine\level\sound\RedstonePowerOffSound; -use pocketmine\level\sound\RedstonePowerOnSound; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\sound\RedstonePowerOffSound; +use pocketmine\world\sound\RedstonePowerOnSound; abstract class Button extends Flowable{ @@ -63,9 +63,9 @@ abstract class Button extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$this->powered){ $this->powered = true; - $this->level->setBlock($this, $this); - $this->level->scheduleDelayedBlockUpdate($this, $this->getActivationTime()); - $this->level->addSound($this->add(0.5, 0.5, 0.5), new RedstonePowerOnSound()); + $this->world->setBlock($this, $this); + $this->world->scheduleDelayedBlockUpdate($this, $this->getActivationTime()); + $this->world->addSound($this->add(0.5, 0.5, 0.5), new RedstonePowerOnSound()); } return true; @@ -74,8 +74,8 @@ abstract class Button extends Flowable{ public function onScheduledUpdate() : void{ if($this->powered){ $this->powered = false; - $this->level->setBlock($this, $this); - $this->level->addSound($this->add(0.5, 0.5, 0.5), new RedstonePowerOffSound()); + $this->world->setBlock($this, $this); + $this->world->addSound($this->add(0.5, 0.5, 0.5), new RedstonePowerOffSound()); } } } diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index f52a149fd9..9a8c76235f 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -72,12 +72,12 @@ class Cactus extends Transparent{ public function onNearbyBlockChange() : void{ $down = $this->getSide(Facing::DOWN); if($down->getId() !== BlockLegacyIds::SAND and $down->getId() !== BlockLegacyIds::CACTUS){ - $this->getLevel()->useBreakOn($this); + $this->getWorld()->useBreakOn($this); }else{ foreach(Facing::HORIZONTAL as $side){ $b = $this->getSide($side); if($b->isSolid()){ - $this->getLevel()->useBreakOn($this); + $this->getWorld()->useBreakOn($this); break; } } @@ -92,23 +92,23 @@ class Cactus extends Transparent{ if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::CACTUS){ if($this->age === 15){ for($y = 1; $y < 3; ++$y){ - $b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z); + $b = $this->getWorld()->getBlockAt($this->x, $this->y + $y, $this->z); if($b->getId() === BlockLegacyIds::AIR){ $ev = new BlockGrowEvent($b, BlockFactory::get(BlockLegacyIds::CACTUS)); $ev->call(); if($ev->isCancelled()){ break; } - $this->getLevel()->setBlock($b, $ev->getNewState()); + $this->getWorld()->setBlock($b, $ev->getNewState()); }else{ break; } } $this->age = 0; - $this->getLevel()->setBlock($this, $this); + $this->getWorld()->setBlock($this, $this); }else{ ++$this->age; - $this->getLevel()->setBlock($this, $this); + $this->getWorld()->setBlock($this, $this); } } } diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index 6410a5cd91..d121490edd 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -72,7 +72,7 @@ class Cake extends Transparent implements FoodSource{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ //Replace with common break method - $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); + $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); } } @@ -125,6 +125,6 @@ class Cake extends Transparent implements FoodSource{ } public function onConsume(Living $consumer) : void{ - $this->level->setBlock($this, $this->getResidue()); + $this->world->setBlock($this, $this->getResidue()); } } diff --git a/src/pocketmine/block/Carpet.php b/src/pocketmine/block/Carpet.php index 8a11ea2edf..2397145d84 100644 --- a/src/pocketmine/block/Carpet.php +++ b/src/pocketmine/block/Carpet.php @@ -54,7 +54,7 @@ class Carpet extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ - $this->getLevel()->useBreakOn($this); + $this->getWorld()->useBreakOn($this); } } diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index 678564d4a0..993b004d68 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -67,7 +67,7 @@ class Chest extends Transparent{ } if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - $tile = $this->level->getTile($this); + $tile = $this->world->getTile($this); if($tile instanceof TileChest){ foreach([ Facing::rotateY($this->facing, true), @@ -75,7 +75,7 @@ class Chest extends Transparent{ ] as $side){ $c = $this->getSide($side); if($c instanceof Chest and $c->isSameType($this) and $c->facing === $this->facing){ - $pair = $this->level->getTile($c); + $pair = $this->world->getTile($c); if($pair instanceof TileChest and !$pair->isPaired()){ $pair->pairWith($tile); $tile->pairWith($pair); @@ -94,7 +94,7 @@ class Chest extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $chest = $this->getLevel()->getTile($this); + $chest = $this->getWorld()->getTile($this); if($chest instanceof TileChest){ if( !$this->getSide(Facing::UP)->isTransparent() or diff --git a/src/pocketmine/block/CoarseDirt.php b/src/pocketmine/block/CoarseDirt.php index 90ff2ef9d4..ac26869a5a 100644 --- a/src/pocketmine/block/CoarseDirt.php +++ b/src/pocketmine/block/CoarseDirt.php @@ -34,7 +34,7 @@ class CoarseDirt extends Dirt{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP and $item instanceof Hoe){ $item->applyDamage(1); - $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::DIRT)); + $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::DIRT)); return true; } diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index 1c74c16e88..e56c157202 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -88,7 +88,7 @@ class CocoaBlock extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($this->age < 2 and $item instanceof Fertilizer){ $this->age++; - $this->level->setBlock($this, $this); + $this->world->setBlock($this, $this); $item->pop(); @@ -101,7 +101,7 @@ class CocoaBlock extends Transparent{ public function onNearbyBlockChange() : void{ $side = $this->getSide(Facing::opposite($this->facing)); if(!($side instanceof Wood) or $side->getTreeType() !== TreeType::JUNGLE()){ - $this->level->useBreakOn($this); + $this->world->useBreakOn($this); } } @@ -112,7 +112,7 @@ class CocoaBlock extends Transparent{ public function onRandomTick() : void{ if($this->age < 2 and mt_rand(1, 5) === 1){ $this->age++; - $this->level->setBlock($this, $this); + $this->world->setBlock($this, $this); } } diff --git a/src/pocketmine/block/ConcretePowder.php b/src/pocketmine/block/ConcretePowder.php index fae849dac8..ee3baed924 100644 --- a/src/pocketmine/block/ConcretePowder.php +++ b/src/pocketmine/block/ConcretePowder.php @@ -42,7 +42,7 @@ class ConcretePowder extends Solid implements Fallable{ public function onNearbyBlockChange() : void{ if(($block = $this->checkAdjacentWater()) !== null){ - $this->level->setBlock($this, $block); + $this->world->setBlock($this, $block); }else{ $this->startFalling(); } diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index 9f39280d3a..4c6e84536a 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -68,7 +68,7 @@ abstract class Crops extends Flowable{ $ev = new BlockGrowEvent($this, $block); $ev->call(); if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($this, $ev->getNewState()); + $this->getWorld()->setBlock($this, $ev->getNewState()); } $item->pop(); @@ -81,7 +81,7 @@ abstract class Crops extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::FARMLAND){ - $this->getLevel()->useBreakOn($this); + $this->getWorld()->useBreakOn($this); } } @@ -96,7 +96,7 @@ abstract class Crops extends Flowable{ $ev = new BlockGrowEvent($this, $block); $ev->call(); if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($this, $ev->getNewState()); + $this->getWorld()->setBlock($this, $ev->getNewState()); } } } diff --git a/src/pocketmine/block/Dandelion.php b/src/pocketmine/block/Dandelion.php index dda14ad05c..b80b8d8b76 100644 --- a/src/pocketmine/block/Dandelion.php +++ b/src/pocketmine/block/Dandelion.php @@ -42,7 +42,7 @@ class Dandelion extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->getLevel()->useBreakOn($this); + $this->getWorld()->useBreakOn($this); } } diff --git a/src/pocketmine/block/DaylightSensor.php b/src/pocketmine/block/DaylightSensor.php index 41e53794a4..a471d013dc 100644 --- a/src/pocketmine/block/DaylightSensor.php +++ b/src/pocketmine/block/DaylightSensor.php @@ -93,7 +93,7 @@ class DaylightSensor extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->inverted = !$this->inverted; - $this->level->setBlock($this, $this); + $this->world->setBlock($this, $this); return true; } diff --git a/src/pocketmine/block/DeadBush.php b/src/pocketmine/block/DeadBush.php index 0ca036fcd9..9c43fbb504 100644 --- a/src/pocketmine/block/DeadBush.php +++ b/src/pocketmine/block/DeadBush.php @@ -42,7 +42,7 @@ class DeadBush extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->getLevel()->useBreakOn($this); + $this->getWorld()->useBreakOn($this); } } diff --git a/src/pocketmine/block/Dirt.php b/src/pocketmine/block/Dirt.php index 663544e52e..feb23e7aed 100644 --- a/src/pocketmine/block/Dirt.php +++ b/src/pocketmine/block/Dirt.php @@ -44,7 +44,7 @@ class Dirt extends Solid{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP and $item instanceof Hoe){ $item->applyDamage(1); - $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::FARMLAND)); + $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::FARMLAND)); return true; } diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 314b8d0f9d..4654b787d0 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -25,13 +25,13 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; -use pocketmine\level\BlockTransaction; -use pocketmine\level\sound\DoorSound; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; +use pocketmine\world\sound\DoorSound; abstract class Door extends Transparent{ @@ -99,7 +99,7 @@ abstract class Door extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ //Replace with common break method - $this->getLevel()->useBreakOn($this); //this will delete both halves if they exist + $this->getWorld()->useBreakOn($this); //this will delete both halves if they exist } } @@ -125,7 +125,7 @@ abstract class Door extends Transparent{ $topHalf = clone $this; $topHalf->top = true; - $transaction = new BlockTransaction($this->level); + $transaction = new BlockTransaction($this->world); $transaction->addBlock($blockReplace, $this)->addBlock($blockUp, $topHalf); return $transaction->apply(); @@ -140,11 +140,11 @@ abstract class Door extends Transparent{ $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); if($other instanceof Door and $other->isSameType($this)){ $other->open = $this->open; - $this->level->setBlock($other, $other); + $this->world->setBlock($other, $other); } - $this->level->setBlock($this, $this); - $this->level->addSound($this, new DoorSound()); + $this->world->setBlock($this, $this); + $this->world->addSound($this, new DoorSound()); return true; } diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index 60c1f6c3d3..c58abbab0a 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -24,10 +24,10 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\level\BlockTransaction; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class DoublePlant extends Flowable{ private const BITFLAG_TOP = 0x08; @@ -53,7 +53,7 @@ class DoublePlant extends Flowable{ $top = clone $this; $top->top = true; - $transaction = new BlockTransaction($this->level); + $transaction = new BlockTransaction($this->world); $transaction->addBlock($blockReplace, $this)->addBlock($blockReplace->getSide(Facing::UP), $top); return $transaction->apply(); } @@ -77,7 +77,7 @@ class DoublePlant extends Flowable{ public function onNearbyBlockChange() : void{ if(!$this->isValidHalfPlant() or (!$this->top and $this->getSide(Facing::DOWN)->isTransparent())){ - $this->getLevel()->useBreakOn($this); + $this->getWorld()->useBreakOn($this); } } diff --git a/src/pocketmine/block/DragonEgg.php b/src/pocketmine/block/DragonEgg.php index e91f7eb58f..27de6cc9d4 100644 --- a/src/pocketmine/block/DragonEgg.php +++ b/src/pocketmine/block/DragonEgg.php @@ -28,10 +28,10 @@ use pocketmine\block\utils\FallableTrait; use pocketmine\event\block\BlockTeleportEvent; use pocketmine\item\Item; use pocketmine\item\TieredTool; -use pocketmine\level\Level; -use pocketmine\level\particle\DragonEggTeleportParticle; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\particle\DragonEggTeleportParticle; +use pocketmine\world\World; use function max; use function min; use function mt_rand; @@ -71,9 +71,9 @@ class DragonEgg extends Transparent implements Fallable{ protected function teleport() : void{ for($tries = 0; $tries < 16; ++$tries){ - $block = $this->level->getBlockAt( + $block = $this->world->getBlockAt( $this->x + mt_rand(-16, 16), - max(0, min(Level::Y_MAX - 1, $this->y + mt_rand(-8, 8))), + max(0, min(World::Y_MAX - 1, $this->y + mt_rand(-8, 8))), $this->z + mt_rand(-16, 16) ); if($block instanceof Air){ @@ -84,9 +84,9 @@ class DragonEgg extends Transparent implements Fallable{ }else{ $block = $ev->getTo(); } - $this->level->addParticle($this, new DragonEggTeleportParticle($this->x - $block->x, $this->y - $block->y, $this->z - $block->z)); - $this->level->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); - $this->level->setBlock($block, $this); + $this->world->addParticle($this, new DragonEggTeleportParticle($this->x - $block->x, $this->y - $block->y, $this->z - $block->z)); + $this->world->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); + $this->world->setBlock($block, $this); break; } } diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index 4235fa9841..7e934e84e6 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -84,7 +84,7 @@ class EnderChest extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $enderChest = $this->getLevel()->getTile($this); + $enderChest = $this->getWorld()->getTile($this); if($enderChest instanceof TileEnderChest and $this->getSide(Facing::UP)->isTransparent()){ $player->getEnderChestInventory()->setHolderPosition($enderChest); $player->addWindow($player->getEnderChestInventory()); diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index b762e6aa2b..9bbc2bd0d7 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -60,7 +60,7 @@ class Farmland extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::UP)->isSolid()){ - $this->level->setBlock($this, BlockFactory::get(BlockLegacyIds::DIRT)); + $this->world->setBlock($this, BlockFactory::get(BlockLegacyIds::DIRT)); } } @@ -72,13 +72,13 @@ class Farmland extends Transparent{ if(!$this->canHydrate()){ if($this->wetness > 0){ $this->wetness--; - $this->level->setBlock($this, $this, false); + $this->world->setBlock($this, $this, false); }else{ - $this->level->setBlock($this, BlockFactory::get(BlockLegacyIds::DIRT)); + $this->world->setBlock($this, BlockFactory::get(BlockLegacyIds::DIRT)); } }elseif($this->wetness < 7){ $this->wetness = 7; - $this->level->setBlock($this, $this, false); + $this->world->setBlock($this, $this, false); } } @@ -89,7 +89,7 @@ class Farmland extends Transparent{ for($y = $start->y; $y <= $end->y; ++$y){ for($z = $start->z; $z <= $end->z; ++$z){ for($x = $start->x; $x <= $end->x; ++$x){ - if($this->level->getBlockAt($x, $y, $z) instanceof Water){ + if($this->world->getBlockAt($x, $y, $z) instanceof Water){ return true; } } diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index a338f8bf4e..c27ed843c5 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -25,12 +25,12 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; -use pocketmine\level\sound\DoorSound; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\sound\DoorSound; class FenceGate extends Transparent{ /** @var bool */ @@ -92,7 +92,7 @@ class FenceGate extends Transparent{ $inWall = $this->checkInWall(); if($inWall !== $this->inWall){ $this->inWall = $inWall; - $this->level->setBlock($this, $this); + $this->world->setBlock($this, $this); } } @@ -105,8 +105,8 @@ class FenceGate extends Transparent{ } } - $this->getLevel()->setBlock($this, $this); - $this->level->addSound($this, new DoorSound()); + $this->getWorld()->setBlock($this, $this); + $this->world->addSound($this, new DoorSound()); return true; } diff --git a/src/pocketmine/block/Fire.php b/src/pocketmine/block/Fire.php index dd739f50b7..298a1bf5ab 100644 --- a/src/pocketmine/block/Fire.php +++ b/src/pocketmine/block/Fire.php @@ -88,9 +88,9 @@ class Fire extends Flowable{ public function onNearbyBlockChange() : void{ if(!$this->getSide(Facing::DOWN)->isSolid() and !$this->hasAdjacentFlammableBlocks()){ - $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); + $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); }else{ - $this->level->scheduleDelayedBlockUpdate($this, mt_rand(30, 40)); + $this->world->scheduleDelayedBlockUpdate($this, mt_rand(30, 40)); } } @@ -124,10 +124,10 @@ class Fire extends Flowable{ } if($result !== null){ - $this->level->setBlock($this, $result); + $this->world->setBlock($this, $result); } - $this->level->scheduleDelayedBlockUpdate($this, mt_rand(30, 40)); + $this->world->scheduleDelayedBlockUpdate($this, mt_rand(30, 40)); if($canSpread){ //TODO: raise upper bound for chance in humid biomes @@ -168,9 +168,9 @@ class Fire extends Flowable{ if(mt_rand(0, $this->age + 9) < 5){ //TODO: check rain $fire = clone $this; $fire->age = min(15, $fire->age + (mt_rand(0, 4) >> 2)); - $this->level->setBlock($block, $fire); + $this->world->setBlock($block, $fire); }else{ - $this->level->setBlock($block, BlockFactory::get(BlockLegacyIds::AIR)); + $this->world->setBlock($block, BlockFactory::get(BlockLegacyIds::AIR)); } } } diff --git a/src/pocketmine/block/Flower.php b/src/pocketmine/block/Flower.php index d4d2949acf..165abadfed 100644 --- a/src/pocketmine/block/Flower.php +++ b/src/pocketmine/block/Flower.php @@ -52,7 +52,7 @@ class Flower extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->getLevel()->useBreakOn($this); + $this->getWorld()->useBreakOn($this); } } diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index d7505029ab..1c2644c9b7 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -56,7 +56,7 @@ class FlowerPot extends Flowable{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->level->getTile($this); + $tile = $this->world->getTile($this); if($tile instanceof TileFlowerPot){ $this->setPlant($tile->getPlant()); }else{ @@ -67,7 +67,7 @@ class FlowerPot extends Flowable{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->level->getTile($this); + $tile = $this->world->getTile($this); assert($tile instanceof TileFlowerPot); $tile->setPlant($this->plant); } @@ -121,7 +121,7 @@ class FlowerPot extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->getLevel()->useBreakOn($this); + $this->getWorld()->useBreakOn($this); } } @@ -133,7 +133,7 @@ class FlowerPot extends Flowable{ $this->setPlant($plant); $item->pop(); - $this->level->setBlock($this, $this); + $this->world->setBlock($this, $this); return true; } diff --git a/src/pocketmine/block/FrostedIce.php b/src/pocketmine/block/FrostedIce.php index aaae971607..5a1446db14 100644 --- a/src/pocketmine/block/FrostedIce.php +++ b/src/pocketmine/block/FrostedIce.php @@ -50,17 +50,17 @@ class FrostedIce extends Ice{ public function onNearbyBlockChange() : void{ if(!$this->checkAdjacentBlocks(2)){ - $this->level->useBreakOn($this); + $this->world->useBreakOn($this); }else{ - $this->level->scheduleDelayedBlockUpdate($this, mt_rand(20, 40)); + $this->world->scheduleDelayedBlockUpdate($this, mt_rand(20, 40)); } } public function onRandomTick() : void{ if((!$this->checkAdjacentBlocks(4) or mt_rand(0, 2) === 0) and - max( //TODO: move this to Level - $this->level->getHighestAdjacentBlockLight($this->x, $this->y, $this->z), - $this->level->getHighestAdjacentBlockSkyLight($this->x, $this->y, $this->z) - $this->level->getSkyLightReduction() + max( //TODO: move this to World + $this->world->getHighestAdjacentBlockLight($this->x, $this->y, $this->z), + $this->world->getHighestAdjacentBlockSkyLight($this->x, $this->y, $this->z) - $this->world->getSkyLightReduction() ) >= 12 - $this->age){ if($this->tryMelt()){ foreach($this->getAllSides() as $block){ @@ -70,7 +70,7 @@ class FrostedIce extends Ice{ } } }else{ - $this->level->scheduleDelayedBlockUpdate($this, mt_rand(20, 40)); + $this->world->scheduleDelayedBlockUpdate($this, mt_rand(20, 40)); } } @@ -86,7 +86,7 @@ class FrostedIce extends Ice{ continue; } if( - $this->level->getBlockAt($this->x + $x, $this->y, $this->z + $z) instanceof FrostedIce and + $this->world->getBlockAt($this->x + $x, $this->y, $this->z + $z) instanceof FrostedIce and ++$found >= $requirement ){ return true; @@ -103,13 +103,13 @@ class FrostedIce extends Ice{ */ private function tryMelt() : bool{ if($this->age >= 3){ - $this->level->useBreakOn($this); + $this->world->useBreakOn($this); return true; } $this->age++; - $this->level->setBlock($this, $this); - $this->level->scheduleDelayedBlockUpdate($this, mt_rand(20, 40)); + $this->world->setBlock($this, $this); + $this->world->scheduleDelayedBlockUpdate($this, mt_rand(20, 40)); return false; } } diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index c5921cb035..87fe907175 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -97,7 +97,7 @@ class Furnace extends Solid{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $furnace = $this->getLevel()->getTile($this); + $furnace = $this->getWorld()->getTile($this); if($furnace instanceof TileFurnace and $furnace->canOpenWith($item->getCustomName())){ $player->addWindow($furnace->getInventory()); } diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index ec7325053e..8fe2c09798 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -29,11 +29,11 @@ use pocketmine\item\Hoe; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\Shovel; -use pocketmine\level\generator\object\TallGrass as TallGrassObject; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\utils\Random; +use pocketmine\world\generator\object\TallGrass as TallGrassObject; use function mt_rand; class Grass extends Solid{ @@ -57,13 +57,13 @@ class Grass extends Solid{ } public function onRandomTick() : void{ - $lightAbove = $this->level->getFullLightAt($this->x, $this->y + 1, $this->z); - if($lightAbove < 4 and $this->level->getBlockAt($this->x, $this->y + 1, $this->z)->getLightFilter() >= 2){ + $lightAbove = $this->world->getFullLightAt($this->x, $this->y + 1, $this->z); + if($lightAbove < 4 and $this->world->getBlockAt($this->x, $this->y + 1, $this->z)->getLightFilter() >= 2){ //grass dies $ev = new BlockSpreadEvent($this, $this, BlockFactory::get(BlockLegacyIds::DIRT)); $ev->call(); if(!$ev->isCancelled()){ - $this->level->setBlock($this, $ev->getNewState(), false); + $this->world->setBlock($this, $ev->getNewState(), false); } }elseif($lightAbove >= 9){ //try grass spread @@ -72,12 +72,12 @@ class Grass extends Solid{ $y = mt_rand($this->y - 3, $this->y + 1); $z = mt_rand($this->z - 1, $this->z + 1); - $b = $this->level->getBlockAt($x, $y, $z); + $b = $this->world->getBlockAt($x, $y, $z); if( !($b instanceof Dirt) or $b instanceof CoarseDirt or - $this->level->getFullLightAt($x, $y + 1, $z) < 4 or - $this->level->getBlockAt($x, $y + 1, $z)->getLightFilter() >= 2 + $this->world->getFullLightAt($x, $y + 1, $z) < 4 or + $this->world->getBlockAt($x, $y + 1, $z)->getLightFilter() >= 2 ){ continue; } @@ -85,7 +85,7 @@ class Grass extends Solid{ $ev = new BlockSpreadEvent($b, $this, BlockFactory::get(BlockLegacyIds::GRASS)); $ev->call(); if(!$ev->isCancelled()){ - $this->level->setBlock($b, $ev->getNewState(), false); + $this->world->setBlock($b, $ev->getNewState(), false); } } } @@ -97,17 +97,17 @@ class Grass extends Solid{ } if($item instanceof Fertilizer){ $item->pop(); - TallGrassObject::growGrass($this->getLevel(), $this, new Random(mt_rand()), 8, 2); + TallGrassObject::growGrass($this->getWorld(), $this, new Random(mt_rand()), 8, 2); return true; }elseif($item instanceof Hoe){ $item->applyDamage(1); - $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::FARMLAND)); + $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::FARMLAND)); return true; }elseif($item instanceof Shovel and $this->getSide(Facing::UP)->getId() === BlockLegacyIds::AIR){ $item->applyDamage(1); - $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::GRASS_PATH)); + $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::GRASS_PATH)); return true; } diff --git a/src/pocketmine/block/GrassPath.php b/src/pocketmine/block/GrassPath.php index 74b426a3de..9c7fb29cf0 100644 --- a/src/pocketmine/block/GrassPath.php +++ b/src/pocketmine/block/GrassPath.php @@ -44,7 +44,7 @@ class GrassPath extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::UP)->isSolid()){ - $this->level->setBlock($this, BlockFactory::get(BlockLegacyIds::DIRT)); + $this->world->setBlock($this, BlockFactory::get(BlockLegacyIds::DIRT)); } } diff --git a/src/pocketmine/block/Ice.php b/src/pocketmine/block/Ice.php index 2427fc00c4..0a3265134c 100644 --- a/src/pocketmine/block/Ice.php +++ b/src/pocketmine/block/Ice.php @@ -47,7 +47,7 @@ class Ice extends Transparent{ public function onBreak(Item $item, ?Player $player = null) : bool{ if(($player === null or $player->isSurvival()) and !$item->hasEnchantment(Enchantment::SILK_TOUCH())){ - return $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::WATER)); + return $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::WATER)); } return parent::onBreak($item, $player); } @@ -57,8 +57,8 @@ class Ice extends Transparent{ } public function onRandomTick() : void{ - if($this->level->getHighestAdjacentBlockLight($this->x, $this->y, $this->z) >= 12){ - $this->level->useBreakOn($this); + if($this->world->getHighestAdjacentBlockLight($this->x, $this->y, $this->z) >= 12){ + $this->world->useBreakOn($this); } } diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 264914fe02..ffc8d5bc1f 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -56,7 +56,7 @@ class ItemFrame extends Flowable{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->level->getTile($this); + $tile = $this->world->getTile($this); if($tile instanceof TileItemFrame){ $this->framedItem = $tile->getItem(); if($this->framedItem->isNull()){ @@ -69,7 +69,7 @@ class ItemFrame extends Flowable{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->level->getTile($this); + $tile = $this->world->getTile($this); if($tile instanceof TileItemFrame){ $tile->setItem($this->framedItem); $tile->setItemRotation($this->itemRotation); @@ -151,7 +151,7 @@ class ItemFrame extends Flowable{ return true; } - $this->level->setBlock($this, $this); + $this->world->setBlock($this, $this); return true; } @@ -161,16 +161,16 @@ class ItemFrame extends Flowable{ return false; } if(lcg_value() <= $this->itemDropChance){ - $this->level->dropItem($this->add(0.5, 0.5, 0.5), $this->getFramedItem()); + $this->world->dropItem($this->add(0.5, 0.5, 0.5), $this->getFramedItem()); } $this->setFramedItem(null); - $this->level->setBlock($this, $this); + $this->world->setBlock($this, $this); return true; } public function onNearbyBlockChange() : void{ if(!$this->getSide(Facing::opposite($this->facing))->isSolid()){ - $this->level->useBreakOn($this); + $this->world->useBreakOn($this); } } diff --git a/src/pocketmine/block/Ladder.php b/src/pocketmine/block/Ladder.php index 35df7a25f7..2c8023a538 100644 --- a/src/pocketmine/block/Ladder.php +++ b/src/pocketmine/block/Ladder.php @@ -87,7 +87,7 @@ class Ladder extends Transparent{ public function onNearbyBlockChange() : void{ if(!$this->getSide(Facing::opposite($this->facing))->isSolid()){ //Replace with common break method - $this->level->useBreakOn($this); + $this->world->useBreakOn($this); } } diff --git a/src/pocketmine/block/Lava.php b/src/pocketmine/block/Lava.php index 388d441d8b..7b3a2a0745 100644 --- a/src/pocketmine/block/Lava.php +++ b/src/pocketmine/block/Lava.php @@ -27,9 +27,9 @@ use pocketmine\entity\Entity; use pocketmine\event\entity\EntityCombustByBlockEvent; use pocketmine\event\entity\EntityDamageByBlockEvent; use pocketmine\event\entity\EntityDamageEvent; -use pocketmine\level\sound\BucketEmptyLavaSound; -use pocketmine\level\sound\BucketFillLavaSound; -use pocketmine\level\sound\Sound; +use pocketmine\world\sound\BucketEmptyLavaSound; +use pocketmine\world\sound\BucketFillLavaSound; +use pocketmine\world\sound\Sound; use pocketmine\math\Facing; class Lava extends Liquid{ diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index e96f16b04d..e594171b7f 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -27,10 +27,10 @@ use pocketmine\block\utils\TreeType; use pocketmine\event\block\LeavesDecayEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\level\Level; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\World; use function mt_rand; class Leaves extends Transparent{ @@ -74,7 +74,7 @@ class Leaves extends Transparent{ protected function findLog(Block $pos, array &$visited = [], int $distance = 0) : bool{ - $index = Level::blockHash($pos->x, $pos->y, $pos->z); + $index = World::blockHash($pos->x, $pos->y, $pos->z); if(isset($visited[$index])){ return false; } @@ -98,7 +98,7 @@ class Leaves extends Transparent{ public function onNearbyBlockChange() : void{ if(!$this->noDecay and !$this->checkDecay){ $this->checkDecay = true; - $this->getLevel()->setBlock($this, $this, false); + $this->getWorld()->setBlock($this, $this, false); } } @@ -112,9 +112,9 @@ class Leaves extends Transparent{ $ev->call(); if($ev->isCancelled() or $this->findLog($this)){ $this->checkDecay = false; - $this->getLevel()->setBlock($this, $this, false); + $this->getWorld()->setBlock($this, $this, false); }else{ - $this->getLevel()->useBreakOn($this); + $this->getWorld()->useBreakOn($this); } } } diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index 98d63e2997..4c925ac6b0 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -25,11 +25,11 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; -use pocketmine\level\sound\RedstonePowerOffSound; -use pocketmine\level\sound\RedstonePowerOnSound; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\sound\RedstonePowerOffSound; +use pocketmine\world\sound\RedstonePowerOnSound; class Lever extends Flowable{ protected const BOTTOM = 0; @@ -106,14 +106,14 @@ class Lever extends Flowable{ } if(!$this->getSide($face)->isSolid()){ - $this->level->useBreakOn($this); + $this->world->useBreakOn($this); } } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->powered = !$this->powered; - $this->level->setBlock($this, $this); - $this->level->addSound( + $this->world->setBlock($this, $this); + $this->world->addSound( $this->add(0.5, 0.5, 0.5), $this->powered ? new RedstonePowerOnSound() : new RedstonePowerOffSound() ); diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index c983267bf3..29a5dd22f4 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -28,11 +28,11 @@ use pocketmine\entity\Entity; use pocketmine\event\block\BlockFormEvent; use pocketmine\event\block\BlockSpreadEvent; use pocketmine\item\Item; -use pocketmine\level\Level; -use pocketmine\level\sound\FizzSound; -use pocketmine\level\sound\Sound; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; +use pocketmine\world\sound\FizzSound; +use pocketmine\world\sound\Sound; +use pocketmine\world\World; use function array_fill; use function lcg_value; use function min; @@ -189,7 +189,7 @@ abstract class Liquid extends Transparent{ }elseif($j === 3){ ++$z; } - $sideBlock = $this->level->getBlockAt($x, $y, $z); + $sideBlock = $this->world->getBlockAt($x, $y, $z); $blockDecay = $this->getEffectiveFlowDecay($sideBlock); if($blockDecay < 0){ @@ -197,7 +197,7 @@ abstract class Liquid extends Transparent{ continue; } - $blockDecay = $this->getEffectiveFlowDecay($this->level->getBlockAt($x, $y - 1, $z)); + $blockDecay = $this->getEffectiveFlowDecay($this->world->getBlockAt($x, $y - 1, $z)); if($blockDecay >= 0){ $realDecay = $blockDecay - ($decay - 8); @@ -217,14 +217,14 @@ abstract class Liquid extends Transparent{ if($this->falling){ if( - !$this->canFlowInto($this->level->getBlockAt($this->x, $this->y, $this->z - 1)) or - !$this->canFlowInto($this->level->getBlockAt($this->x, $this->y, $this->z + 1)) or - !$this->canFlowInto($this->level->getBlockAt($this->x - 1, $this->y, $this->z)) or - !$this->canFlowInto($this->level->getBlockAt($this->x + 1, $this->y, $this->z)) or - !$this->canFlowInto($this->level->getBlockAt($this->x, $this->y + 1, $this->z - 1)) or - !$this->canFlowInto($this->level->getBlockAt($this->x, $this->y + 1, $this->z + 1)) or - !$this->canFlowInto($this->level->getBlockAt($this->x - 1, $this->y + 1, $this->z)) or - !$this->canFlowInto($this->level->getBlockAt($this->x + 1, $this->y + 1, $this->z)) + !$this->canFlowInto($this->world->getBlockAt($this->x, $this->y, $this->z - 1)) or + !$this->canFlowInto($this->world->getBlockAt($this->x, $this->y, $this->z + 1)) or + !$this->canFlowInto($this->world->getBlockAt($this->x - 1, $this->y, $this->z)) or + !$this->canFlowInto($this->world->getBlockAt($this->x + 1, $this->y, $this->z)) or + !$this->canFlowInto($this->world->getBlockAt($this->x, $this->y + 1, $this->z - 1)) or + !$this->canFlowInto($this->world->getBlockAt($this->x, $this->y + 1, $this->z + 1)) or + !$this->canFlowInto($this->world->getBlockAt($this->x - 1, $this->y + 1, $this->z)) or + !$this->canFlowInto($this->world->getBlockAt($this->x + 1, $this->y + 1, $this->z)) ){ $vector = $vector->normalize()->add(0, -6, 0); } @@ -255,7 +255,7 @@ abstract class Liquid extends Transparent{ public function onNearbyBlockChange() : void{ $this->checkForHarden(); - $this->level->scheduleDelayedBlockUpdate($this, $this->tickRate()); + $this->world->scheduleDelayedBlockUpdate($this, $this->tickRate()); } public function onScheduledUpdate() : void{ @@ -264,10 +264,10 @@ abstract class Liquid extends Transparent{ if(!$this->isSource()){ $smallestFlowDecay = -100; $this->adjacentSources = 0; - $smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlockAt($this->x, $this->y, $this->z - 1), $smallestFlowDecay); - $smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlockAt($this->x, $this->y, $this->z + 1), $smallestFlowDecay); - $smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlockAt($this->x - 1, $this->y, $this->z), $smallestFlowDecay); - $smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlockAt($this->x + 1, $this->y, $this->z), $smallestFlowDecay); + $smallestFlowDecay = $this->getSmallestFlowDecay($this->world->getBlockAt($this->x, $this->y, $this->z - 1), $smallestFlowDecay); + $smallestFlowDecay = $this->getSmallestFlowDecay($this->world->getBlockAt($this->x, $this->y, $this->z + 1), $smallestFlowDecay); + $smallestFlowDecay = $this->getSmallestFlowDecay($this->world->getBlockAt($this->x - 1, $this->y, $this->z), $smallestFlowDecay); + $smallestFlowDecay = $this->getSmallestFlowDecay($this->world->getBlockAt($this->x + 1, $this->y, $this->z), $smallestFlowDecay); $newDecay = $smallestFlowDecay + $multiplier; $falling = false; @@ -276,12 +276,12 @@ abstract class Liquid extends Transparent{ $newDecay = -1; } - if($this->getEffectiveFlowDecay($this->level->getBlockAt($this->x, $this->y + 1, $this->z)) >= 0){ + if($this->getEffectiveFlowDecay($this->world->getBlockAt($this->x, $this->y + 1, $this->z)) >= 0){ $falling = true; } if($this->adjacentSources >= 2 and $this instanceof Water){ - $bottomBlock = $this->level->getBlockAt($this->x, $this->y - 1, $this->z); + $bottomBlock = $this->world->getBlockAt($this->x, $this->y - 1, $this->z); if($bottomBlock->isSolid() or ($bottomBlock instanceof Water and $bottomBlock->isSource())){ $newDecay = 0; $falling = false; @@ -290,17 +290,17 @@ abstract class Liquid extends Transparent{ if($falling !== $this->falling or (!$falling and $newDecay !== $this->decay)){ if(!$falling and $newDecay < 0){ - $this->level->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); + $this->world->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); return; } $this->falling = $falling; $this->decay = $falling ? 0 : $newDecay; - $this->level->setBlock($this, $this); //local block update will cause an update to be scheduled + $this->world->setBlock($this, $this); //local block update will cause an update to be scheduled } } - $bottomBlock = $this->level->getBlockAt($this->x, $this->y - 1, $this->z); + $bottomBlock = $this->world->getBlockAt($this->x, $this->y - 1, $this->z); $this->flowIntoBlock($bottomBlock, 0, true); @@ -315,19 +315,19 @@ abstract class Liquid extends Transparent{ $flags = $this->getOptimalFlowDirections(); if($flags[0]){ - $this->flowIntoBlock($this->level->getBlockAt($this->x - 1, $this->y, $this->z), $adjacentDecay, false); + $this->flowIntoBlock($this->world->getBlockAt($this->x - 1, $this->y, $this->z), $adjacentDecay, false); } if($flags[1]){ - $this->flowIntoBlock($this->level->getBlockAt($this->x + 1, $this->y, $this->z), $adjacentDecay, false); + $this->flowIntoBlock($this->world->getBlockAt($this->x + 1, $this->y, $this->z), $adjacentDecay, false); } if($flags[2]){ - $this->flowIntoBlock($this->level->getBlockAt($this->x, $this->y, $this->z - 1), $adjacentDecay, false); + $this->flowIntoBlock($this->world->getBlockAt($this->x, $this->y, $this->z - 1), $adjacentDecay, false); } if($flags[3]){ - $this->flowIntoBlock($this->level->getBlockAt($this->x, $this->y, $this->z + 1), $adjacentDecay, false); + $this->flowIntoBlock($this->world->getBlockAt($this->x, $this->y, $this->z + 1), $adjacentDecay, false); } } } @@ -345,10 +345,10 @@ abstract class Liquid extends Transparent{ $ev->call(); if(!$ev->isCancelled()){ if($block->getId() > 0){ - $this->level->useBreakOn($block); + $this->world->useBreakOn($block); } - $this->level->setBlock($block, $ev->getNewState()); + $this->world->setBlock($block, $ev->getNewState()); } } } @@ -375,11 +375,11 @@ abstract class Liquid extends Transparent{ ++$z; } - if(!isset($this->flowCostVisited[$hash = Level::blockHash($x, $y, $z)])){ - $blockSide = $this->level->getBlockAt($x, $y, $z); + if(!isset($this->flowCostVisited[$hash = World::blockHash($x, $y, $z)])){ + $blockSide = $this->world->getBlockAt($x, $y, $z); if(!$this->canFlowInto($blockSide)){ $this->flowCostVisited[$hash] = self::BLOCKED; - }elseif($this->level->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ + }elseif($this->world->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ $this->flowCostVisited[$hash] = self::CAN_FLOW_DOWN; }else{ $this->flowCostVisited[$hash] = self::CAN_FLOW; @@ -428,16 +428,16 @@ abstract class Liquid extends Transparent{ }elseif($j === 3){ ++$z; } - $block = $this->level->getBlockAt($x, $y, $z); + $block = $this->world->getBlockAt($x, $y, $z); if(!$this->canFlowInto($block)){ - $this->flowCostVisited[Level::blockHash($x, $y, $z)] = self::BLOCKED; + $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::BLOCKED; continue; - }elseif($this->level->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ - $this->flowCostVisited[Level::blockHash($x, $y, $z)] = self::CAN_FLOW_DOWN; + }elseif($this->world->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ + $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::CAN_FLOW_DOWN; $flowCost[$j] = $maxCost = 0; }elseif($maxCost > 0){ - $this->flowCostVisited[Level::blockHash($x, $y, $z)] = self::CAN_FLOW; + $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::CAN_FLOW; $flowCost[$j] = $this->calculateFlowCost($x, $y, $z, 1, $maxCost, $j ^ 0x01, $j ^ 0x01); $maxCost = min($maxCost, $flowCost[$j]); } @@ -480,13 +480,13 @@ abstract class Liquid extends Transparent{ $ev = new BlockFormEvent($this, $result); $ev->call(); if(!$ev->isCancelled()){ - $this->level->setBlock($this, $ev->getNewState()); - $this->level->addSound($this->add(0.5, 0.5, 0.5), new FizzSound(2.6 + (lcg_value() - lcg_value()) * 0.8)); + $this->world->setBlock($this, $ev->getNewState()); + $this->world->addSound($this->add(0.5, 0.5, 0.5), new FizzSound(2.6 + (lcg_value() - lcg_value()) * 0.8)); } return true; } protected function canFlowInto(Block $block) : bool{ - return $this->level->isInWorld($block->x, $block->y, $block->z) and $block->canBeFlowedInto() and !($block instanceof Liquid and $block->isSource()); //TODO: I think this should only be liquids of the same type + return $this->world->isInWorld($block->x, $block->y, $block->z) and $block->canBeFlowedInto() and !($block instanceof Liquid and $block->isSource()); //TODO: I think this should only be liquids of the same type } } diff --git a/src/pocketmine/block/Mycelium.php b/src/pocketmine/block/Mycelium.php index 5870822c25..1271f07855 100644 --- a/src/pocketmine/block/Mycelium.php +++ b/src/pocketmine/block/Mycelium.php @@ -54,13 +54,13 @@ class Mycelium extends Solid{ $x = mt_rand($this->x - 1, $this->x + 1); $y = mt_rand($this->y - 2, $this->y + 2); $z = mt_rand($this->z - 1, $this->z + 1); - $block = $this->getLevel()->getBlockAt($x, $y, $z); + $block = $this->getWorld()->getBlockAt($x, $y, $z); if($block->getId() === BlockLegacyIds::DIRT){ if($block->getSide(Facing::UP) instanceof Transparent){ $ev = new BlockSpreadEvent($block, $this, BlockFactory::get(BlockLegacyIds::MYCELIUM)); $ev->call(); if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($block, $ev->getNewState()); + $this->getWorld()->setBlock($block, $ev->getNewState()); } } } diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index b1c8661ed5..6d14c1c43a 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -60,7 +60,7 @@ class NetherWartPlant extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::SOUL_SAND){ - $this->getLevel()->useBreakOn($this); + $this->getWorld()->useBreakOn($this); } } @@ -75,7 +75,7 @@ class NetherWartPlant extends Flowable{ $ev = new BlockGrowEvent($this, $block); $ev->call(); if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($this, $ev->getNewState()); + $this->getWorld()->setBlock($this, $ev->getNewState()); } } } diff --git a/src/pocketmine/block/RedMushroom.php b/src/pocketmine/block/RedMushroom.php index 35f832da6e..1f6a98bad8 100644 --- a/src/pocketmine/block/RedMushroom.php +++ b/src/pocketmine/block/RedMushroom.php @@ -36,7 +36,7 @@ class RedMushroom extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->getLevel()->useBreakOn($this); + $this->getWorld()->useBreakOn($this); } } diff --git a/src/pocketmine/block/RedstoneComparator.php b/src/pocketmine/block/RedstoneComparator.php index 2b8121fd45..aea91205c0 100644 --- a/src/pocketmine/block/RedstoneComparator.php +++ b/src/pocketmine/block/RedstoneComparator.php @@ -70,7 +70,7 @@ class RedstoneComparator extends Flowable{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->level->getTile($this); + $tile = $this->world->getTile($this); if($tile instanceof Comparator){ $this->signalStrength = $tile->getSignalStrength(); } @@ -78,7 +78,7 @@ class RedstoneComparator extends Flowable{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->level->getTile($this); + $tile = $this->world->getTile($this); assert($tile instanceof Comparator); $tile->setSignalStrength($this->signalStrength); } @@ -158,13 +158,13 @@ class RedstoneComparator extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->isSubtractMode = !$this->isSubtractMode; - $this->level->setBlock($this, $this); + $this->world->setBlock($this, $this); return true; } public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->level->useBreakOn($this); + $this->world->useBreakOn($this); } } diff --git a/src/pocketmine/block/RedstoneOre.php b/src/pocketmine/block/RedstoneOre.php index 66c2f085e6..33f8ffb3ad 100644 --- a/src/pocketmine/block/RedstoneOre.php +++ b/src/pocketmine/block/RedstoneOre.php @@ -72,13 +72,13 @@ class RedstoneOre extends Solid{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - return $this->getLevel()->setBlock($this, $this, false); + return $this->getWorld()->setBlock($this, $this, false); } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$this->lit){ $this->lit = true; - $this->getLevel()->setBlock($this, $this); //no return here - this shouldn't prevent block placement + $this->getWorld()->setBlock($this, $this); //no return here - this shouldn't prevent block placement } return false; } @@ -86,7 +86,7 @@ class RedstoneOre extends Solid{ public function onNearbyBlockChange() : void{ if(!$this->lit){ $this->lit = true; - $this->getLevel()->setBlock($this, $this); + $this->getWorld()->setBlock($this, $this); } } @@ -97,7 +97,7 @@ class RedstoneOre extends Solid{ public function onRandomTick() : void{ if($this->lit){ $this->lit = false; - $this->level->setBlock($this, $this); + $this->world->setBlock($this, $this); } } diff --git a/src/pocketmine/block/RedstoneRepeater.php b/src/pocketmine/block/RedstoneRepeater.php index 651607d0ee..6f7a4070f7 100644 --- a/src/pocketmine/block/RedstoneRepeater.php +++ b/src/pocketmine/block/RedstoneRepeater.php @@ -98,13 +98,13 @@ class RedstoneRepeater extends Flowable{ if(++$this->delay > 4){ $this->delay = 1; } - $this->level->setBlock($this, $this); + $this->world->setBlock($this, $this); return true; } public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->level->useBreakOn($this); + $this->world->useBreakOn($this); } } diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index 86d9c54974..06a164e118 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -26,11 +26,11 @@ namespace pocketmine\block; use pocketmine\block\utils\TreeType; use pocketmine\item\Fertilizer; use pocketmine\item\Item; -use pocketmine\level\generator\object\Tree; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\utils\Random; +use pocketmine\world\generator\object\Tree; use function mt_rand; class Sapling extends Flowable{ @@ -68,7 +68,7 @@ class Sapling extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof Fertilizer){ - Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->treeType); + Tree::growTree($this->getWorld(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->treeType); $item->pop(); @@ -80,7 +80,7 @@ class Sapling extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->getLevel()->useBreakOn($this); + $this->getWorld()->useBreakOn($this); } } @@ -89,12 +89,12 @@ class Sapling extends Flowable{ } public function onRandomTick() : void{ - if($this->level->getFullLightAt($this->x, $this->y, $this->z) >= 8 and mt_rand(1, 7) === 1){ + if($this->world->getFullLightAt($this->x, $this->y, $this->z) >= 8 and mt_rand(1, 7) === 1){ if($this->ready){ - Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->treeType); + Tree::growTree($this->getWorld(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->treeType); }else{ $this->ready = true; - $this->getLevel()->setBlock($this, $this); + $this->getWorld()->setBlock($this, $this); } } } diff --git a/src/pocketmine/block/Sign.php b/src/pocketmine/block/Sign.php index 0b1a9e4169..4a51f3fda7 100644 --- a/src/pocketmine/block/Sign.php +++ b/src/pocketmine/block/Sign.php @@ -84,7 +84,7 @@ class Sign extends Transparent{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->level->getTile($this); + $tile = $this->world->getTile($this); if($tile instanceof TileSign){ $this->text = $tile->getText(); } @@ -92,7 +92,7 @@ class Sign extends Transparent{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->level->getTile($this); + $tile = $this->world->getTile($this); assert($tile instanceof TileSign); $tile->setText($this->text); } @@ -128,7 +128,7 @@ class Sign extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::opposite($this->facing))->getId() === BlockLegacyIds::AIR){ - $this->getLevel()->useBreakOn($this); + $this->getWorld()->useBreakOn($this); } } @@ -169,7 +169,7 @@ class Sign extends Transparent{ $ev->call(); if(!$ev->isCancelled()){ $this->text = clone $ev->getNewText(); - $this->level->setBlock($this, $this); + $this->world->setBlock($this, $this); return true; } diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index 68e564a828..99c6b93594 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -65,7 +65,7 @@ class Skull extends Flowable{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->level->getTile($this); + $tile = $this->world->getTile($this); if($tile instanceof TileSkull){ $this->skullType = $tile->getSkullType(); $this->rotation = $tile->getRotation(); @@ -75,7 +75,7 @@ class Skull extends Flowable{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); //extra block properties storage hack - $tile = $this->level->getTile($this); + $tile = $this->world->getTile($this); assert($tile instanceof TileSkull); $tile->setRotation($this->rotation); $tile->setSkullType($this->skullType); diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index f7a4a2bee1..6fa335de99 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -95,8 +95,8 @@ class SnowLayer extends Flowable implements Fallable{ } public function onRandomTick() : void{ - if($this->level->getBlockLightAt($this->x, $this->y, $this->z) >= 12){ - $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR), false); + if($this->world->getBlockLightAt($this->x, $this->y, $this->z) >= 12){ + $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR), false); } } diff --git a/src/pocketmine/block/Stem.php b/src/pocketmine/block/Stem.php index 397bcd8e56..0bc2b478bf 100644 --- a/src/pocketmine/block/Stem.php +++ b/src/pocketmine/block/Stem.php @@ -41,7 +41,7 @@ abstract class Stem extends Crops{ $ev = new BlockGrowEvent($this, $block); $ev->call(); if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($this, $ev->getNewState()); + $this->getWorld()->setBlock($this, $ev->getNewState()); } }else{ $grow = $this->getPlant(); @@ -57,7 +57,7 @@ abstract class Stem extends Crops{ $ev = new BlockGrowEvent($side, $grow); $ev->call(); if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($side, $ev->getNewState()); + $this->getWorld()->setBlock($side, $ev->getNewState()); } } } diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index 6823a8eb91..9c2abd907e 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -52,20 +52,20 @@ class Sugarcane extends Flowable{ if($item instanceof Fertilizer){ if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::SUGARCANE_BLOCK){ for($y = 1; $y < 3; ++$y){ - $b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z); + $b = $this->getWorld()->getBlockAt($this->x, $this->y + $y, $this->z); if($b->getId() === BlockLegacyIds::AIR){ $ev = new BlockGrowEvent($b, BlockFactory::get(BlockLegacyIds::SUGARCANE_BLOCK)); $ev->call(); if($ev->isCancelled()){ break; } - $this->getLevel()->setBlock($b, $ev->getNewState()); + $this->getWorld()->setBlock($b, $ev->getNewState()); }else{ break; } } $this->age = 0; - $this->getLevel()->setBlock($this, $this); + $this->getWorld()->setBlock($this, $this); } $item->pop(); @@ -79,7 +79,7 @@ class Sugarcane extends Flowable{ public function onNearbyBlockChange() : void{ $down = $this->getSide(Facing::DOWN); if($down->isTransparent() and $down->getId() !== BlockLegacyIds::SUGARCANE_BLOCK){ - $this->getLevel()->useBreakOn($this); + $this->getWorld()->useBreakOn($this); } } @@ -91,17 +91,17 @@ class Sugarcane extends Flowable{ if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::SUGARCANE_BLOCK){ if($this->age === 15){ for($y = 1; $y < 3; ++$y){ - $b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z); + $b = $this->getWorld()->getBlockAt($this->x, $this->y + $y, $this->z); if($b->getId() === BlockLegacyIds::AIR){ - $this->getLevel()->setBlock($b, BlockFactory::get(BlockLegacyIds::SUGARCANE_BLOCK)); + $this->getWorld()->setBlock($b, BlockFactory::get(BlockLegacyIds::SUGARCANE_BLOCK)); break; } } $this->age = 0; - $this->getLevel()->setBlock($this, $this); + $this->getWorld()->setBlock($this, $this); }else{ ++$this->age; - $this->getLevel()->setBlock($this, $this); + $this->getWorld()->setBlock($this, $this); } } } diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index 226eff1371..c968e6a50b 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -90,14 +90,14 @@ class TNT extends Solid{ } public function ignite(int $fuse = 80) : void{ - $this->getLevel()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); + $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); $mot = (new Random())->nextSignedFloat() * M_PI * 2; $nbt = EntityFactory::createBaseNBT($this->add(0.5, 0, 0.5), new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02)); $nbt->setShort("Fuse", $fuse); /** @var PrimedTNT $tnt */ - $tnt = EntityFactory::create(PrimedTNT::class, $this->getLevel(), $nbt); + $tnt = EntityFactory::create(PrimedTNT::class, $this->getWorld(), $nbt); $tnt->spawnToAll(); } diff --git a/src/pocketmine/block/TallGrass.php b/src/pocketmine/block/TallGrass.php index eaf36f9b4d..41a67eb114 100644 --- a/src/pocketmine/block/TallGrass.php +++ b/src/pocketmine/block/TallGrass.php @@ -47,7 +47,7 @@ class TallGrass extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ //Replace with common break method - $this->level->useBreakOn($this); + $this->world->useBreakOn($this); } } diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index 4a45c706f3..e5a5533b66 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -55,7 +55,7 @@ class Torch extends Flowable{ $face = Facing::opposite($this->facing); if($this->getSide($face)->isTransparent() and !($face === Facing::DOWN and ($below->getId() === BlockLegacyIds::FENCE or $below->getId() === BlockLegacyIds::COBBLESTONE_WALL))){ - $this->getLevel()->useBreakOn($this); + $this->getWorld()->useBreakOn($this); } } diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index c815b85ee9..0c063eae1f 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -25,11 +25,11 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; -use pocketmine\level\sound\DoorSound; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\sound\DoorSound; class Trapdoor extends Transparent{ private const MASK_UPPER = 0x04; @@ -79,8 +79,8 @@ class Trapdoor extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->open = !$this->open; - $this->level->setBlock($this, $this); - $this->level->addSound($this, new DoorSound()); + $this->world->setBlock($this, $this); + $this->world->addSound($this, new DoorSound()); return true; } diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index 27b59636a9..1fa2112b27 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -170,9 +170,9 @@ class Vine extends Flowable{ if($changed){ if(empty($this->faces)){ - $this->level->useBreakOn($this); + $this->world->useBreakOn($this); }else{ - $this->level->setBlock($this, $this); + $this->world->setBlock($this, $this); } } } diff --git a/src/pocketmine/block/Water.php b/src/pocketmine/block/Water.php index 5423847bc6..c4d9762a2e 100644 --- a/src/pocketmine/block/Water.php +++ b/src/pocketmine/block/Water.php @@ -24,9 +24,9 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\entity\Entity; -use pocketmine\level\sound\BucketEmptyWaterSound; -use pocketmine\level\sound\BucketFillWaterSound; -use pocketmine\level\sound\Sound; +use pocketmine\world\sound\BucketEmptyWaterSound; +use pocketmine\world\sound\BucketFillWaterSound; +use pocketmine\world\sound\Sound; class Water extends Liquid{ diff --git a/src/pocketmine/block/WaterLily.php b/src/pocketmine/block/WaterLily.php index 9719427b28..00eb99f514 100644 --- a/src/pocketmine/block/WaterLily.php +++ b/src/pocketmine/block/WaterLily.php @@ -52,7 +52,7 @@ class WaterLily extends Flowable{ public function onNearbyBlockChange() : void{ if(!($this->getSide(Facing::DOWN) instanceof Water)){ - $this->getLevel()->useBreakOn($this); + $this->getWorld()->useBreakOn($this); } } } diff --git a/src/pocketmine/block/utils/FallableTrait.php b/src/pocketmine/block/utils/FallableTrait.php index 451af2221d..86b9bfee4d 100644 --- a/src/pocketmine/block/utils/FallableTrait.php +++ b/src/pocketmine/block/utils/FallableTrait.php @@ -29,8 +29,8 @@ use pocketmine\block\Fire; use pocketmine\block\Liquid; use pocketmine\entity\EntityFactory; use pocketmine\entity\object\FallingBlock; -use pocketmine\level\Position; use pocketmine\math\Facing; +use pocketmine\world\Position; /** * This trait handles falling behaviour for blocks that need them. @@ -47,16 +47,16 @@ trait FallableTrait{ public function onNearbyBlockChange() : void{ $pos = $this->asPosition(); - $down = $pos->level->getBlock($pos->getSide(Facing::DOWN)); + $down = $pos->world->getBlock($pos->getSide(Facing::DOWN)); if($down->getId() === BlockLegacyIds::AIR or $down instanceof Liquid or $down instanceof Fire){ - $pos->level->setBlock($pos, BlockFactory::get(BlockLegacyIds::AIR)); + $pos->world->setBlock($pos, BlockFactory::get(BlockLegacyIds::AIR)); $nbt = EntityFactory::createBaseNBT($pos->add(0.5, 0, 0.5)); $nbt->setInt("TileID", $this->getId()); $nbt->setByte("Data", $this->getMeta()); /** @var FallingBlock $fall */ - $fall = EntityFactory::create(FallingBlock::class, $pos->getLevel(), $nbt); + $fall = EntityFactory::create(FallingBlock::class, $pos->getWorld(), $nbt); $fall->spawnToAll(); } } diff --git a/src/pocketmine/command/defaults/DifficultyCommand.php b/src/pocketmine/command/defaults/DifficultyCommand.php index 8addfb0a87..9b2bbd6027 100644 --- a/src/pocketmine/command/defaults/DifficultyCommand.php +++ b/src/pocketmine/command/defaults/DifficultyCommand.php @@ -27,7 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; -use pocketmine\level\Level; +use pocketmine\world\World; use function count; class DifficultyCommand extends VanillaCommand{ @@ -50,18 +50,18 @@ class DifficultyCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $difficulty = Level::getDifficultyFromString($args[0]); + $difficulty = World::getDifficultyFromString($args[0]); if($sender->getServer()->isHardcore()){ - $difficulty = Level::DIFFICULTY_HARD; + $difficulty = World::DIFFICULTY_HARD; } if($difficulty !== -1){ $sender->getServer()->setConfigInt("difficulty", $difficulty); //TODO: add per-world support - foreach($sender->getServer()->getLevelManager()->getLevels() as $level){ - $level->setDifficulty($difficulty); + foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){ + $world->setDifficulty($difficulty); } Command::broadcastCommandMessage($sender, new TranslationContainer("commands.difficulty.success", [$difficulty])); diff --git a/src/pocketmine/command/defaults/GarbageCollectorCommand.php b/src/pocketmine/command/defaults/GarbageCollectorCommand.php index 6058f160c2..1fc6b7f739 100644 --- a/src/pocketmine/command/defaults/GarbageCollectorCommand.php +++ b/src/pocketmine/command/defaults/GarbageCollectorCommand.php @@ -51,13 +51,13 @@ class GarbageCollectorCommand extends VanillaCommand{ $memory = memory_get_usage(); - foreach($sender->getServer()->getLevelManager()->getLevels() as $level){ - $diff = [count($level->getChunks()), count($level->getEntities())]; - $level->doChunkGarbageCollection(); - $level->unloadChunks(true); - $chunksCollected += $diff[0] - count($level->getChunks()); - $entitiesCollected += $diff[1] - count($level->getEntities()); - $level->clearCache(true); + foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){ + $diff = [count($world->getChunks()), count($world->getEntities())]; + $world->doChunkGarbageCollection(); + $world->unloadChunks(true); + $chunksCollected += $diff[0] - count($world->getChunks()); + $entitiesCollected += $diff[1] - count($world->getEntities()); + $world->clearCache(true); } $cyclesCollected = $sender->getServer()->getMemoryManager()->triggerGarbageCollector(); diff --git a/src/pocketmine/command/defaults/ParticleCommand.php b/src/pocketmine/command/defaults/ParticleCommand.php index 9b4d57b7e5..ddec2514b1 100644 --- a/src/pocketmine/command/defaults/ParticleCommand.php +++ b/src/pocketmine/command/defaults/ParticleCommand.php @@ -29,39 +29,39 @@ use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\lang\TranslationContainer; -use pocketmine\level\Level; -use pocketmine\level\particle\AngryVillagerParticle; -use pocketmine\level\particle\BlockForceFieldParticle; -use pocketmine\level\particle\BubbleParticle; -use pocketmine\level\particle\CriticalParticle; -use pocketmine\level\particle\DustParticle; -use pocketmine\level\particle\EnchantmentTableParticle; -use pocketmine\level\particle\EnchantParticle; -use pocketmine\level\particle\ExplodeParticle; -use pocketmine\level\particle\FlameParticle; -use pocketmine\level\particle\HappyVillagerParticle; -use pocketmine\level\particle\HeartParticle; -use pocketmine\level\particle\HugeExplodeParticle; -use pocketmine\level\particle\HugeExplodeSeedParticle; -use pocketmine\level\particle\InkParticle; -use pocketmine\level\particle\InstantEnchantParticle; -use pocketmine\level\particle\ItemBreakParticle; -use pocketmine\level\particle\LavaDripParticle; -use pocketmine\level\particle\LavaParticle; -use pocketmine\level\particle\Particle; -use pocketmine\level\particle\PortalParticle; -use pocketmine\level\particle\RainSplashParticle; -use pocketmine\level\particle\RedstoneParticle; -use pocketmine\level\particle\SmokeParticle; -use pocketmine\level\particle\SplashParticle; -use pocketmine\level\particle\SporeParticle; -use pocketmine\level\particle\TerrainParticle; -use pocketmine\level\particle\WaterDripParticle; -use pocketmine\level\particle\WaterParticle; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\utils\Random; use pocketmine\utils\TextFormat; +use pocketmine\world\particle\AngryVillagerParticle; +use pocketmine\world\particle\BlockForceFieldParticle; +use pocketmine\world\particle\BubbleParticle; +use pocketmine\world\particle\CriticalParticle; +use pocketmine\world\particle\DustParticle; +use pocketmine\world\particle\EnchantmentTableParticle; +use pocketmine\world\particle\EnchantParticle; +use pocketmine\world\particle\ExplodeParticle; +use pocketmine\world\particle\FlameParticle; +use pocketmine\world\particle\HappyVillagerParticle; +use pocketmine\world\particle\HeartParticle; +use pocketmine\world\particle\HugeExplodeParticle; +use pocketmine\world\particle\HugeExplodeSeedParticle; +use pocketmine\world\particle\InkParticle; +use pocketmine\world\particle\InstantEnchantParticle; +use pocketmine\world\particle\ItemBreakParticle; +use pocketmine\world\particle\LavaDripParticle; +use pocketmine\world\particle\LavaParticle; +use pocketmine\world\particle\Particle; +use pocketmine\world\particle\PortalParticle; +use pocketmine\world\particle\RainSplashParticle; +use pocketmine\world\particle\RedstoneParticle; +use pocketmine\world\particle\SmokeParticle; +use pocketmine\world\particle\SplashParticle; +use pocketmine\world\particle\SporeParticle; +use pocketmine\world\particle\TerrainParticle; +use pocketmine\world\particle\WaterDripParticle; +use pocketmine\world\particle\WaterParticle; +use pocketmine\world\World; use function count; use function explode; use function max; @@ -91,14 +91,14 @@ class ParticleCommand extends VanillaCommand{ } if($sender instanceof Player){ - $level = $sender->getLevel(); + $world = $sender->getWorld(); $pos = new Vector3( $this->getRelativeDouble($sender->getX(), $sender, $args[1]), - $this->getRelativeDouble($sender->getY(), $sender, $args[2], 0, Level::Y_MAX), + $this->getRelativeDouble($sender->getY(), $sender, $args[2], 0, World::Y_MAX), $this->getRelativeDouble($sender->getZ(), $sender, $args[3]) ); }else{ - $level = $sender->getServer()->getLevelManager()->getDefaultLevel(); + $world = $sender->getServer()->getWorldManager()->getDefaultWorld(); $pos = new Vector3((float) $args[1], (float) $args[2], (float) $args[3]); } @@ -125,7 +125,7 @@ class ParticleCommand extends VanillaCommand{ $random = new Random((int) (microtime(true) * 1000) + mt_rand()); for($i = 0; $i < $count; ++$i){ - $level->addParticle($pos->add( + $world->addParticle($pos->add( $random->nextSignedFloat() * $xd, $random->nextSignedFloat() * $yd, $random->nextSignedFloat() * $zd diff --git a/src/pocketmine/command/defaults/SaveCommand.php b/src/pocketmine/command/defaults/SaveCommand.php index 5ed458296f..1949baa307 100644 --- a/src/pocketmine/command/defaults/SaveCommand.php +++ b/src/pocketmine/command/defaults/SaveCommand.php @@ -52,8 +52,8 @@ class SaveCommand extends VanillaCommand{ $player->save(); } - foreach($sender->getServer()->getLevelManager()->getLevels() as $level){ - $level->save(true); + foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){ + $world->save(true); } Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.save.success", [round(microtime(true) - $start, 3)])); diff --git a/src/pocketmine/command/defaults/SaveOffCommand.php b/src/pocketmine/command/defaults/SaveOffCommand.php index e5b8d79e31..82687867af 100644 --- a/src/pocketmine/command/defaults/SaveOffCommand.php +++ b/src/pocketmine/command/defaults/SaveOffCommand.php @@ -43,7 +43,7 @@ class SaveOffCommand extends VanillaCommand{ return true; } - $sender->getServer()->getLevelManager()->setAutoSave(false); + $sender->getServer()->getWorldManager()->setAutoSave(false); Command::broadcastCommandMessage($sender, new TranslationContainer("commands.save.disabled")); diff --git a/src/pocketmine/command/defaults/SaveOnCommand.php b/src/pocketmine/command/defaults/SaveOnCommand.php index d79f03be50..3df4808bd6 100644 --- a/src/pocketmine/command/defaults/SaveOnCommand.php +++ b/src/pocketmine/command/defaults/SaveOnCommand.php @@ -43,7 +43,7 @@ class SaveOnCommand extends VanillaCommand{ return true; } - $sender->getServer()->getLevelManager()->setAutoSave(true); + $sender->getServer()->getWorldManager()->setAutoSave(true); Command::broadcastCommandMessage($sender, new TranslationContainer("commands.save.enabled")); diff --git a/src/pocketmine/command/defaults/SeedCommand.php b/src/pocketmine/command/defaults/SeedCommand.php index 5fdaa50b9e..9ea9fb26fd 100644 --- a/src/pocketmine/command/defaults/SeedCommand.php +++ b/src/pocketmine/command/defaults/SeedCommand.php @@ -44,9 +44,9 @@ class SeedCommand extends VanillaCommand{ } if($sender instanceof Player){ - $seed = $sender->getLevel()->getSeed(); + $seed = $sender->getWorld()->getSeed(); }else{ - $seed = $sender->getServer()->getLevelManager()->getDefaultLevel()->getSeed(); + $seed = $sender->getServer()->getWorldManager()->getDefaultWorld()->getSeed(); } $sender->sendMessage(new TranslationContainer("commands.seed.success", [$seed])); diff --git a/src/pocketmine/command/defaults/SetWorldSpawnCommand.php b/src/pocketmine/command/defaults/SetWorldSpawnCommand.php index fe50ec205e..f406b6a460 100644 --- a/src/pocketmine/command/defaults/SetWorldSpawnCommand.php +++ b/src/pocketmine/command/defaults/SetWorldSpawnCommand.php @@ -51,7 +51,7 @@ class SetWorldSpawnCommand extends VanillaCommand{ if(count($args) === 0){ if($sender instanceof Player){ - $level = $sender->getLevel(); + $world = $sender->getWorld(); $pos = (new Vector3($sender->x, $sender->y, $sender->z))->round(); }else{ $sender->sendMessage(TextFormat::RED . "You can only perform this command as a player"); @@ -59,13 +59,13 @@ class SetWorldSpawnCommand extends VanillaCommand{ return true; } }elseif(count($args) === 3){ - $level = $sender->getServer()->getLevelManager()->getDefaultLevel(); + $world = $sender->getServer()->getWorldManager()->getDefaultWorld(); $pos = new Vector3($this->getInteger($sender, $args[0]), $this->getInteger($sender, $args[1]), $this->getInteger($sender, $args[2])); }else{ throw new InvalidCommandSyntaxException(); } - $level->setSpawnLocation($pos); + $world->setSpawnLocation($pos); Command::broadcastCommandMessage($sender, new TranslationContainer("commands.setworldspawn.success", [round($pos->x, 2), round($pos->y, 2), round($pos->z, 2)])); diff --git a/src/pocketmine/command/defaults/SpawnpointCommand.php b/src/pocketmine/command/defaults/SpawnpointCommand.php index 775e896f5c..eac5caafa7 100644 --- a/src/pocketmine/command/defaults/SpawnpointCommand.php +++ b/src/pocketmine/command/defaults/SpawnpointCommand.php @@ -27,10 +27,10 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; -use pocketmine\level\Level; -use pocketmine\level\Position; use pocketmine\Player; use pocketmine\utils\TextFormat; +use pocketmine\world\Position; +use pocketmine\world\World; use function count; use function round; @@ -71,12 +71,12 @@ class SpawnpointCommand extends VanillaCommand{ if(count($args) === 4){ if($target->isValid()){ - $level = $target->getLevel(); - $pos = $sender instanceof Player ? $sender->getPosition() : $level->getSpawnLocation(); + $world = $target->getWorld(); + $pos = $sender instanceof Player ? $sender->getPosition() : $world->getSpawnLocation(); $x = $this->getRelativeDouble($pos->x, $sender, $args[1]); - $y = $this->getRelativeDouble($pos->y, $sender, $args[2], 0, Level::Y_MAX); + $y = $this->getRelativeDouble($pos->y, $sender, $args[2], 0, World::Y_MAX); $z = $this->getRelativeDouble($pos->z, $sender, $args[3]); - $target->setSpawn(new Position($x, $y, $z, $level)); + $target->setSpawn(new Position($x, $y, $z, $world)); Command::broadcastCommandMessage($sender, new TranslationContainer("commands.spawnpoint.success", [$target->getName(), round($x, 2), round($y, 2), round($z, 2)])); @@ -84,7 +84,7 @@ class SpawnpointCommand extends VanillaCommand{ } }elseif(count($args) <= 1){ if($sender instanceof Player){ - $pos = new Position($sender->getFloorX(), $sender->getFloorY(), $sender->getFloorZ(), $sender->getLevel()); + $pos = new Position($sender->getFloorX(), $sender->getFloorY(), $sender->getFloorZ(), $sender->getWorld()); $target->setSpawn($pos); Command::broadcastCommandMessage($sender, new TranslationContainer("commands.spawnpoint.success", [$target->getName(), round($pos->x, 2), round($pos->y, 2), round($pos->z, 2)])); diff --git a/src/pocketmine/command/defaults/StatusCommand.php b/src/pocketmine/command/defaults/StatusCommand.php index d937f75e04..74d22076ea 100644 --- a/src/pocketmine/command/defaults/StatusCommand.php +++ b/src/pocketmine/command/defaults/StatusCommand.php @@ -107,13 +107,13 @@ class StatusCommand extends VanillaCommand{ $sender->sendMessage(TextFormat::GOLD . "Maximum memory (manager): " . TextFormat::RED . number_format(round($globalLimit, 2), 2) . " MB."); } - foreach($server->getLevelManager()->getLevels() as $level){ - $levelName = $level->getFolderName() !== $level->getDisplayName() ? " (" . $level->getDisplayName() . ")" : ""; - $timeColor = $level->getTickRateTime() > 40 ? TextFormat::RED : TextFormat::YELLOW; - $sender->sendMessage(TextFormat::GOLD . "World \"{$level->getFolderName()}\"$levelName: " . - TextFormat::RED . number_format(count($level->getChunks())) . TextFormat::GREEN . " chunks, " . - TextFormat::RED . number_format(count($level->getEntities())) . TextFormat::GREEN . " entities. " . - "Time $timeColor" . round($level->getTickRateTime(), 2) . "ms" + foreach($server->getWorldManager()->getWorlds() as $world){ + $worldName = $world->getFolderName() !== $world->getDisplayName() ? " (" . $world->getDisplayName() . ")" : ""; + $timeColor = $world->getTickRateTime() > 40 ? TextFormat::RED : TextFormat::YELLOW; + $sender->sendMessage(TextFormat::GOLD . "World \"{$world->getFolderName()}\"$worldName: " . + TextFormat::RED . number_format(count($world->getChunks())) . TextFormat::GREEN . " chunks, " . + TextFormat::RED . number_format(count($world->getEntities())) . TextFormat::GREEN . " entities. " . + "Time $timeColor" . round($world->getTickRateTime(), 2) . "ms" ); } diff --git a/src/pocketmine/command/defaults/TimeCommand.php b/src/pocketmine/command/defaults/TimeCommand.php index 0ca094c9cc..ce12e7986d 100644 --- a/src/pocketmine/command/defaults/TimeCommand.php +++ b/src/pocketmine/command/defaults/TimeCommand.php @@ -27,9 +27,9 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; -use pocketmine\level\Level; use pocketmine\Player; use pocketmine\utils\TextFormat; +use pocketmine\world\World; use function count; class TimeCommand extends VanillaCommand{ @@ -54,8 +54,8 @@ class TimeCommand extends VanillaCommand{ return true; } - foreach($sender->getServer()->getLevelManager()->getLevels() as $level){ - $level->startTime(); + foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){ + $world->startTime(); } Command::broadcastCommandMessage($sender, "Restarted the time"); return true; @@ -65,8 +65,8 @@ class TimeCommand extends VanillaCommand{ return true; } - foreach($sender->getServer()->getLevelManager()->getLevels() as $level){ - $level->stopTime(); + foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){ + $world->stopTime(); } Command::broadcastCommandMessage($sender, "Stopped the time"); return true; @@ -77,11 +77,11 @@ class TimeCommand extends VanillaCommand{ return true; } if($sender instanceof Player){ - $level = $sender->getLevel(); + $world = $sender->getWorld(); }else{ - $level = $sender->getServer()->getLevelManager()->getDefaultLevel(); + $world = $sender->getServer()->getWorldManager()->getDefaultWorld(); } - $sender->sendMessage(new TranslationContainer("commands.time.query", [$level->getTime()])); + $sender->sendMessage(new TranslationContainer("commands.time.query", [$world->getTime()])); return true; } @@ -98,15 +98,15 @@ class TimeCommand extends VanillaCommand{ } if($args[1] === "day"){ - $value = Level::TIME_DAY; + $value = World::TIME_DAY; }elseif($args[1] === "night"){ - $value = Level::TIME_NIGHT; + $value = World::TIME_NIGHT; }else{ $value = $this->getInteger($sender, $args[1], 0); } - foreach($sender->getServer()->getLevelManager()->getLevels() as $level){ - $level->setTime($value); + foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){ + $world->setTime($value); } Command::broadcastCommandMessage($sender, new TranslationContainer("commands.time.set", [$value])); }elseif($args[0] === "add"){ @@ -117,8 +117,8 @@ class TimeCommand extends VanillaCommand{ } $value = $this->getInteger($sender, $args[1], 0); - foreach($sender->getServer()->getLevelManager()->getLevels() as $level){ - $level->setTime($level->getTime() + $value); + foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){ + $world->setTime($world->getTime() + $value); } Command::broadcastCommandMessage($sender, new TranslationContainer("commands.time.added", [$value])); }else{ diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index ab29ea83f1..71c8f5e705 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -30,15 +30,11 @@ use pocketmine\block\Block; use pocketmine\block\Water; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDespawnEvent; -use pocketmine\event\entity\EntityLevelChangeEvent; use pocketmine\event\entity\EntityMotionEvent; use pocketmine\event\entity\EntityRegainHealthEvent; use pocketmine\event\entity\EntitySpawnEvent; use pocketmine\event\entity\EntityTeleportEvent; -use pocketmine\level\format\Chunk; -use pocketmine\level\Level; -use pocketmine\level\Location; -use pocketmine\level\Position; +use pocketmine\event\entity\EntityWorldChangeEvent; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; use pocketmine\math\Facing; @@ -67,6 +63,10 @@ use pocketmine\plugin\Plugin; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; +use pocketmine\world\format\Chunk; +use pocketmine\world\Location; +use pocketmine\world\Position; +use pocketmine\world\World; use function abs; use function assert; use function cos; @@ -199,7 +199,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ /** @var TimingsHandler */ protected $timings; - public function __construct(Level $level, CompoundTag $nbt){ + public function __construct(World $world, CompoundTag $nbt){ $this->timings = Timings::getEntityTimings($this); $this->temporalVector = new Vector3(); @@ -209,20 +209,20 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } $this->id = EntityFactory::nextRuntimeId(); - $this->server = $level->getServer(); + $this->server = $world->getServer(); /** @var float[] $pos */ $pos = $nbt->getListTag("Pos")->getAllValues(); /** @var float[] $rotation */ $rotation = $nbt->getListTag("Rotation")->getAllValues(); - parent::__construct($pos[0], $pos[1], $pos[2], $rotation[0], $rotation[1], $level); + parent::__construct($pos[0], $pos[1], $pos[2], $rotation[0], $rotation[1], $world); assert(!is_nan($this->x) and !is_infinite($this->x) and !is_nan($this->y) and !is_infinite($this->y) and !is_nan($this->z) and !is_infinite($this->z)); $this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0); $this->recalculateBoundingBox(); - $this->chunk = $this->level->getChunkAtPosition($this, false); + $this->chunk = $this->world->getChunkAtPosition($this, false); if($this->chunk === null){ throw new \InvalidStateException("Cannot create entities in unloaded chunks"); } @@ -256,7 +256,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->propertyManager->clearDirtyProperties(); //Prevents resending properties that were set during construction $this->chunk->addEntity($this); - $this->level->addEntity($this); + $this->world->addEntity($this); $this->lastUpdate = $this->server->getTick(); (new EntitySpawnEvent($this))->call(); @@ -450,7 +450,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ public function getOwningEntity() : ?Entity{ $eid = $this->getOwningEntityId(); if($eid !== null){ - return $this->server->getLevelManager()->findEntity($eid); + return $this->server->getWorldManager()->findEntity($eid); } return null; @@ -490,7 +490,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ public function getTargetEntity() : ?Entity{ $eid = $this->getTargetEntityId(); if($eid !== null){ - return $this->server->getLevelManager()->findEntity($eid); + return $this->server->getWorldManager()->findEntity($eid); } return null; @@ -871,7 +871,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $pk->flags |= MoveEntityAbsolutePacket::FLAG_TELEPORT; } - $this->level->broadcastPacketToViewers($this, $pk); + $this->world->broadcastPacketToViewers($this, $pk); } protected function broadcastMotion() : void{ @@ -879,7 +879,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $pk->entityRuntimeId = $this->id; $pk->motion = $this->getMotion(); - $this->level->broadcastPacketToViewers($this, $pk); + $this->world->broadcastPacketToViewers($this, $pk); } public function hasGravity() : bool{ @@ -914,7 +914,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } if($this->onGround){ - $friction *= $this->level->getBlockAt((int) floor($this->x), (int) floor($this->y - 1), (int) floor($this->z))->getFrictionFactor(); + $friction *= $this->world->getBlockAt((int) floor($this->x), (int) floor($this->y - 1), (int) floor($this->z))->getFrictionFactor(); } $this->motion->x *= $friction; @@ -922,7 +922,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } protected function checkObstruction(float $x, float $y, float $z) : bool{ - if(count($this->level->getCollisionBoxes($this, $this->getBoundingBox(), false)) === 0){ + if(count($this->world->getCollisionBoxes($this, $this->getBoundingBox(), false)) === 0){ return false; } @@ -934,13 +934,13 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $diffY = $y - $floorY; $diffZ = $z - $floorZ; - if($this->level->getBlockAt($floorX, $floorY, $floorZ)->isSolid()){ - $westNonSolid = !$this->level->getBlockAt($floorX - 1, $floorY, $floorZ)->isSolid(); - $eastNonSolid = !$this->level->getBlockAt($floorX + 1, $floorY, $floorZ)->isSolid(); - $downNonSolid = !$this->level->getBlockAt($floorX, $floorY - 1, $floorZ)->isSolid(); - $upNonSolid = !$this->level->getBlockAt($floorX, $floorY + 1, $floorZ)->isSolid(); - $northNonSolid = !$this->level->getBlockAt($floorX, $floorY, $floorZ - 1)->isSolid(); - $southNonSolid = !$this->level->getBlockAt($floorX, $floorY, $floorZ + 1)->isSolid(); + if($this->world->getBlockAt($floorX, $floorY, $floorZ)->isSolid()){ + $westNonSolid = !$this->world->getBlockAt($floorX - 1, $floorY, $floorZ)->isSolid(); + $eastNonSolid = !$this->world->getBlockAt($floorX + 1, $floorY, $floorZ)->isSolid(); + $downNonSolid = !$this->world->getBlockAt($floorX, $floorY - 1, $floorZ)->isSolid(); + $upNonSolid = !$this->world->getBlockAt($floorX, $floorY + 1, $floorZ)->isSolid(); + $northNonSolid = !$this->world->getBlockAt($floorX, $floorY, $floorZ - 1)->isSolid(); + $southNonSolid = !$this->world->getBlockAt($floorX, $floorY, $floorZ + 1)->isSolid(); $direction = -1; $limit = 9999; @@ -1105,7 +1105,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ if($this->closed){ throw new \InvalidStateException("Cannot schedule update on garbage entity " . get_class($this)); } - $this->level->updateEntities[$this->id] = $this; + $this->world->updateEntities[$this->id] = $this; } public function onNearbyBlockChange() : void{ @@ -1176,7 +1176,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } public function isUnderwater() : bool{ - $block = $this->level->getBlockAt((int) floor($this->x), (int) floor($y = ($this->y + $this->getEyeHeight())), (int) floor($this->z)); + $block = $this->world->getBlockAt((int) floor($this->x), (int) floor($y = ($this->y + $this->getEyeHeight())), (int) floor($this->z)); if($block instanceof Water){ $f = ($block->y + 1) - ($block->getFluidHeightPercent() - 0.1111111); @@ -1187,7 +1187,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } public function isInsideOfSolid() : bool{ - $block = $this->level->getBlockAt((int) floor($this->x), (int) floor($y = ($this->y + $this->getEyeHeight())), (int) floor($this->z)); + $block = $this->world->getBlockAt((int) floor($this->x), (int) floor($y = ($this->y + $this->getEyeHeight())), (int) floor($this->z)); return $block->isSolid() and !$block->isTransparent() and $block->collidesWithBB($this->getBoundingBox()); } @@ -1223,7 +1223,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ /*$sneakFlag = $this->onGround and $this instanceof Player; if($sneakFlag){ - for($mov = 0.05; $dx != 0.0 and count($this->level->getCollisionCubes($this, $this->boundingBox->getOffsetBoundingBox($dx, -1, 0))) === 0; $movX = $dx){ + for($mov = 0.05; $dx != 0.0 and count($this->world->getCollisionCubes($this, $this->boundingBox->getOffsetBoundingBox($dx, -1, 0))) === 0; $movX = $dx){ if($dx < $mov and $dx >= -$mov){ $dx = 0; }elseif($dx > 0){ @@ -1233,7 +1233,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } } - for(; $dz != 0.0 and count($this->level->getCollisionCubes($this, $this->boundingBox->getOffsetBoundingBox(0, -1, $dz))) === 0; $movZ = $dz){ + for(; $dz != 0.0 and count($this->world->getCollisionCubes($this, $this->boundingBox->getOffsetBoundingBox(0, -1, $dz))) === 0; $movZ = $dz){ if($dz < $mov and $dz >= -$mov){ $dz = 0; }elseif($dz > 0){ @@ -1249,7 +1249,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ assert(abs($dx) <= 20 and abs($dy) <= 20 and abs($dz) <= 20, "Movement distance is excessive: dx=$dx, dy=$dy, dz=$dz"); //TODO: bad hack here will cause unexpected behaviour under heavy lag - $list = $this->level->getCollisionBoxes($this, $this->level->getTickRateTime() > 50 ? $this->boundingBox->offsetCopy($dx, $dy, $dz) : $this->boundingBox->addCoord($dx, $dy, $dz), false); + $list = $this->world->getCollisionBoxes($this, $this->world->getTickRateTime() > 50 ? $this->boundingBox->offsetCopy($dx, $dy, $dz) : $this->boundingBox->addCoord($dx, $dy, $dz), false); foreach($list as $bb){ $dy = $bb->calculateYOffset($this->boundingBox, $dy); @@ -1284,7 +1284,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->boundingBox->setBB($axisalignedbb); - $list = $this->level->getCollisionBoxes($this, $this->boundingBox->addCoord($dx, $dy, $dz), false); + $list = $this->world->getCollisionBoxes($this, $this->boundingBox->addCoord($dx, $dy, $dz), false); foreach($list as $bb){ $dy = $bb->calculateYOffset($this->boundingBox, $dy); @@ -1367,7 +1367,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ for($z = $minZ; $z <= $maxZ; ++$z){ for($x = $minX; $x <= $maxX; ++$x){ for($y = $minY; $y <= $maxY; ++$y){ - $block = $this->level->getBlockAt($x, $y, $z); + $block = $this->world->getBlockAt($x, $y, $z); if($block->hasEntityCollision()){ $this->blocksAround[] = $block; } @@ -1418,8 +1418,8 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ return false; } - if($pos instanceof Position and $pos->level !== null and $pos->level !== $this->level){ - if(!$this->switchLevel($pos->getLevel())){ + if($pos instanceof Position and $pos->world !== null and $pos->world !== $this->world){ + if(!$this->switchWorld($pos->getWorld())){ return false; } } @@ -1460,10 +1460,10 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ if($this->chunk !== null){ $this->chunk->removeEntity($this); } - $this->chunk = $this->level->getChunk($chunkX, $chunkZ, true); + $this->chunk = $this->world->getChunk($chunkX, $chunkZ, true); if(!$this->justCreated){ - $newChunk = $this->level->getViewersForPosition($this); + $newChunk = $this->world->getViewersForPosition($this); foreach($this->hasSpawned as $player){ if(!isset($newChunk[spl_object_id($player)])){ $this->despawnFrom($player); @@ -1540,8 +1540,8 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $yaw = $yaw ?? $pos->yaw; $pitch = $pitch ?? $pos->pitch; } - $from = Position::fromObject($this, $this->level); - $to = Position::fromObject($pos, $pos instanceof Position ? $pos->getLevel() : $this->level); + $from = Position::fromObject($this, $this->world); + $to = Position::fromObject($pos, $pos instanceof Position ? $pos->getWorld() : $this->world); $ev = new EntityTeleportEvent($this, $from, $to); $ev->call(); if($ev->isCancelled()){ @@ -1563,27 +1563,27 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ return false; } - protected function switchLevel(Level $targetLevel) : bool{ + protected function switchWorld(World $targetWorld) : bool{ if($this->closed){ return false; } if($this->isValid()){ - $ev = new EntityLevelChangeEvent($this, $this->level, $targetLevel); + $ev = new EntityWorldChangeEvent($this, $this->world, $targetWorld); $ev->call(); if($ev->isCancelled()){ return false; } - $this->level->removeEntity($this); + $this->world->removeEntity($this); if($this->chunk !== null){ $this->chunk->removeEntity($this); } $this->despawnFromAll(); } - $this->setLevel($targetLevel); - $this->level->addEntity($this); + $this->setWorld($targetWorld); + $this->world->addEntity($this); $this->chunk = null; return true; @@ -1636,7 +1636,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ if($this->chunk === null or $this->closed){ return; } - foreach($this->level->getViewersForPosition($this) as $player){ + foreach($this->world->getViewersForPosition($this) as $player){ if($player->isOnline()){ $this->spawnTo($player); } @@ -1717,7 +1717,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->chunk->removeEntity($this); } if($this->isValid()){ - $this->level->removeEntity($this); + $this->world->removeEntity($this); } } @@ -1729,7 +1729,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ */ protected function destroyCycles() : void{ $this->chunk = null; - $this->setLevel(null); + $this->setWorld(null); $this->lastDamageCause = null; } diff --git a/src/pocketmine/entity/EntityFactory.php b/src/pocketmine/entity/EntityFactory.php index 467bc36256..d14632908a 100644 --- a/src/pocketmine/entity/EntityFactory.php +++ b/src/pocketmine/entity/EntityFactory.php @@ -36,7 +36,6 @@ use pocketmine\entity\projectile\EnderPearl; use pocketmine\entity\projectile\ExperienceBottle; use pocketmine\entity\projectile\Snowball; use pocketmine\entity\projectile\SplashPotion; -use pocketmine\level\Level; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\DoubleTag; @@ -45,6 +44,7 @@ use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; use pocketmine\utils\Utils; +use pocketmine\world\World; use function array_keys; use function assert; use function in_array; @@ -174,20 +174,20 @@ final class EntityFactory{ } /** - * Creates an entity with the specified type, level and NBT, with optional additional arguments to pass to the + * Creates an entity with the specified type, world and NBT, with optional additional arguments to pass to the * entity's constructor. * * TODO: make this NBT-independent * * @param string $baseClass - * @param Level $level + * @param World $world * @param CompoundTag $nbt * @param mixed ...$args * * @return Entity instanceof $baseClass * @throws \InvalidArgumentException if the class doesn't exist or is not registered */ - public static function create(string $baseClass, Level $level, CompoundTag $nbt, ...$args) : Entity{ + public static function create(string $baseClass, World $world, CompoundTag $nbt, ...$args) : Entity{ if(isset(self::$classMapping[$baseClass])){ $class = self::$classMapping[$baseClass]; assert(is_a($class, $baseClass, true)); @@ -195,7 +195,7 @@ final class EntityFactory{ * @var Entity $entity * @see Entity::__construct() */ - $entity = new $class($level, $nbt, ...$args); + $entity = new $class($world, $nbt, ...$args); return $entity; } @@ -205,15 +205,16 @@ final class EntityFactory{ /** * Creates an entity from data stored on a chunk. - * @internal * - * @param Level $level + * @param World $world * @param CompoundTag $nbt * * @return Entity|null * @throws \RuntimeException + *@internal + * */ - public static function createFromData(Level $level, CompoundTag $nbt) : ?Entity{ + public static function createFromData(World $world, CompoundTag $nbt) : ?Entity{ $saveId = $nbt->getTag("id") ?? $nbt->getTag("identifier"); $baseClass = null; if($saveId instanceof StringTag){ @@ -230,7 +231,7 @@ final class EntityFactory{ * @var Entity $entity * @see Entity::__construct() */ - $entity = new $class($level, $nbt); + $entity = new $class($world, $nbt); return $entity; } diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index f497ac6a3e..e4f8725d00 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -42,10 +42,6 @@ use pocketmine\item\enchantment\Enchantment; use pocketmine\item\FoodSource; use pocketmine\item\Item; use pocketmine\item\Totem; -use pocketmine\level\Level; -use pocketmine\level\sound\TotemUseSound; -use pocketmine\level\sound\XpCollectSound; -use pocketmine\level\sound\XpLevelUpSound; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\CompoundTag; @@ -62,6 +58,10 @@ use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\network\mcpe\protocol\types\PlayerMetadataFlags; use pocketmine\Player; use pocketmine\utils\UUID; +use pocketmine\world\sound\TotemUseSound; +use pocketmine\world\sound\XpCollectSound; +use pocketmine\world\sound\XpLevelUpSound; +use pocketmine\world\World; use function array_filter; use function array_merge; use function array_rand; @@ -101,7 +101,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ protected $baseOffset = 1.62; - public function __construct(Level $level, CompoundTag $nbt){ + public function __construct(World $world, CompoundTag $nbt){ if($this->skin === null){ $skinTag = $nbt->getCompoundTag("Skin"); if($skinTag === null or !self::isValidSkin($skinTag->hasTag("Data", ByteArrayTag::class) ? @@ -112,7 +112,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ } } - parent::__construct($level, $nbt); + parent::__construct($world, $nbt); } /** @@ -350,7 +350,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ if($playSound){ $newLevel = $this->getXpLevel(); if((int) ($newLevel / 5) > (int) ($oldLevel / 5)){ - $this->level->addSound($this, new XpLevelUpSound($newLevel)); + $this->world->addSound($this, new XpLevelUpSound($newLevel)); } } @@ -442,9 +442,9 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ if($playSound){ $newLevel = $this->getXpLevel(); if((int) ($newLevel / 5) > (int) ($oldLevel / 5)){ - $this->level->addSound($this, new XpLevelUpSound($newLevel)); + $this->world->addSound($this, new XpLevelUpSound($newLevel)); }elseif($this->getCurrentTotalXp() > $oldTotal){ - $this->level->addSound($this, new XpCollectSound()); + $this->world->addSound($this, new XpCollectSound()); } } @@ -696,14 +696,14 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ if($this->isAlive()){ $food = $this->getFood(); $health = $this->getHealth(); - $difficulty = $this->level->getDifficulty(); + $difficulty = $this->world->getDifficulty(); $this->foodTickTimer += $tickDiff; if($this->foodTickTimer >= 80){ $this->foodTickTimer = 0; } - if($difficulty === Level::DIFFICULTY_PEACEFUL and $this->foodTickTimer % 10 === 0){ + if($difficulty === World::DIFFICULTY_PEACEFUL and $this->foodTickTimer % 10 === 0){ if($food < $this->getMaxFood()){ $this->addFood(1.0); $food = $this->getFood(); @@ -720,7 +720,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $this->exhaust(3.0, PlayerExhaustEvent::CAUSE_HEALTH_REGEN); } }elseif($food <= 0){ - if(($difficulty === Level::DIFFICULTY_EASY and $health > 10) or ($difficulty === Level::DIFFICULTY_NORMAL and $health > 1) or $difficulty === Level::DIFFICULTY_HARD){ + if(($difficulty === World::DIFFICULTY_EASY and $health > 10) or ($difficulty === World::DIFFICULTY_NORMAL and $health > 1) or $difficulty === World::DIFFICULTY_HARD){ $this->attack(new EntityDamageEvent($this, EntityDamageEvent::CAUSE_STARVATION, 1)); } } @@ -761,7 +761,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $this->addEffect(new EffectInstance(Effect::ABSORPTION(), 5 * 20, 1)); $this->broadcastEntityEvent(EntityEventPacket::CONSUME_TOTEM); - $this->level->addSound($this->add(0, $this->eyeHeight, 0), new TotemUseSound()); + $this->world->addSound($this->add(0, $this->eyeHeight, 0), new TotemUseSound()); $hand = $this->inventory->getItemInHand(); if($hand instanceof Totem){ diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 197dc68406..6605bca068 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -40,7 +40,6 @@ use pocketmine\item\Consumable; use pocketmine\item\Durable; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\Item; -use pocketmine\level\sound\ItemBreakSound; use pocketmine\math\Vector3; use pocketmine\math\VoxelRayTrace; use pocketmine\nbt\tag\CompoundTag; @@ -54,6 +53,7 @@ use pocketmine\Player; use pocketmine\timings\Timings; use pocketmine\utils\Binary; use pocketmine\utils\Color; +use pocketmine\world\sound\ItemBreakSound; use function abs; use function array_shift; use function atan2; @@ -546,7 +546,7 @@ abstract class Living extends Entity implements Damageable{ private function damageItem(Durable $item, int $durabilityRemoved) : void{ $item->applyDamage($durabilityRemoved); if($item->isBroken()){ - $this->level->addSound($this, new ItemBreakSound()); + $this->world->addSound($this, new ItemBreakSound()); } } @@ -598,7 +598,7 @@ abstract class Living extends Entity implements Damageable{ $source->getCause() === EntityDamageEvent::CAUSE_PROJECTILE or $source->getCause() === EntityDamageEvent::CAUSE_ENTITY_ATTACK ) and $e->isOnFire()){ - $this->setOnFire(2 * $this->level->getDifficulty()); + $this->setOnFire(2 * $this->world->getDifficulty()); } $deltaX = $this->x - $e->x; @@ -646,11 +646,11 @@ abstract class Living extends Entity implements Damageable{ $ev = new EntityDeathEvent($this, $this->getDrops(), $this->getXpDropAmount()); $ev->call(); foreach($ev->getDrops() as $item){ - $this->getLevel()->dropItem($this, $item); + $this->getWorld()->dropItem($this, $item); } //TODO: check death conditions (must have been damaged by player < 5 seconds from death) - $this->level->dropExperience($this, $ev->getXpDropAmount()); + $this->world->dropExperience($this, $ev->getXpDropAmount()); $this->startDeathAnimation(); } @@ -864,7 +864,7 @@ abstract class Living extends Entity implements Damageable{ $nextIndex = 0; foreach(VoxelRayTrace::inDirection($this->add(0, $this->eyeHeight, 0), $this->getDirectionVector(), $maxDistance) as $vector3){ - $block = $this->level->getBlockAt($vector3->x, $vector3->y, $vector3->z); + $block = $this->world->getBlockAt($vector3->x, $vector3->y, $vector3->z); $blocks[$nextIndex++] = $block; if($maxLength !== 0 and count($blocks) > $maxLength){ diff --git a/src/pocketmine/entity/object/ExperienceOrb.php b/src/pocketmine/entity/object/ExperienceOrb.php index c0141bae24..612f055f5b 100644 --- a/src/pocketmine/entity/object/ExperienceOrb.php +++ b/src/pocketmine/entity/object/ExperienceOrb.php @@ -152,7 +152,7 @@ class ExperienceOrb extends Entity{ return null; } - $entity = $this->level->getEntity($this->targetPlayerRuntimeId); + $entity = $this->world->getEntity($this->targetPlayerRuntimeId); if($entity instanceof Human){ return $entity; } @@ -180,7 +180,7 @@ class ExperienceOrb extends Entity{ if($this->lookForTargetTime >= 20){ if($currentTarget === null){ - $newTarget = $this->level->getNearestEntity($this, self::MAX_TARGET_DISTANCE, Human::class); + $newTarget = $this->world->getNearestEntity($this, self::MAX_TARGET_DISTANCE, Human::class); if($newTarget instanceof Human and !($newTarget instanceof Player and $newTarget->isSpectator())){ $currentTarget = $newTarget; diff --git a/src/pocketmine/entity/object/FallingBlock.php b/src/pocketmine/entity/object/FallingBlock.php index c22e849087..c563b486ec 100644 --- a/src/pocketmine/entity/object/FallingBlock.php +++ b/src/pocketmine/entity/object/FallingBlock.php @@ -98,7 +98,7 @@ class FallingBlock extends Entity{ if(!$this->isFlaggedForDespawn()){ $pos = $this->add(-$this->width / 2, $this->height, -$this->width / 2)->floor(); - $this->block->position($this->level, $pos->x, $pos->y, $pos->z); + $this->block->position($this->world, $pos->x, $pos->y, $pos->z); $blockTarget = null; if($this->block instanceof Fallable){ @@ -108,15 +108,15 @@ class FallingBlock extends Entity{ if($this->onGround or $blockTarget !== null){ $this->flagForDespawn(); - $block = $this->level->getBlock($pos); + $block = $this->world->getBlock($pos); if($block->getId() > 0 and $block->isTransparent() and !$block->canBeReplaced()){ //FIXME: anvils are supposed to destroy torches - $this->getLevel()->dropItem($this, $this->block->asItem()); + $this->getWorld()->dropItem($this, $this->block->asItem()); }else{ $ev = new EntityBlockChangeEvent($this, $block, $blockTarget ?? $this->block); $ev->call(); if(!$ev->isCancelled()){ - $this->getLevel()->setBlock($pos, $ev->getTo()); + $this->getWorld()->setBlock($pos, $ev->getTo()); } } $hasUpdate = true; diff --git a/src/pocketmine/entity/object/Painting.php b/src/pocketmine/entity/object/Painting.php index e5ea041cd3..44f545f892 100644 --- a/src/pocketmine/entity/object/Painting.php +++ b/src/pocketmine/entity/object/Painting.php @@ -29,8 +29,6 @@ use pocketmine\entity\Entity; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\level\Level; -use pocketmine\level\particle\DestroyBlockParticle; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; use pocketmine\math\Facing; @@ -39,6 +37,8 @@ use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\AddPaintingPacket; use pocketmine\Player; +use pocketmine\world\particle\DestroyBlockParticle; +use pocketmine\world\World; use function ceil; class Painting extends Entity{ @@ -62,7 +62,7 @@ class Painting extends Entity{ /** @var string */ protected $motive; - public function __construct(Level $level, CompoundTag $nbt){ + public function __construct(World $world, CompoundTag $nbt){ $this->motive = $nbt->getString("Motive"); $this->blockIn = new Vector3($nbt->getInt("TileX"), $nbt->getInt("TileY"), $nbt->getInt("TileZ")); if($nbt->hasTag("Direction", ByteTag::class)){ @@ -70,7 +70,7 @@ class Painting extends Entity{ }elseif($nbt->hasTag("Facing", ByteTag::class)){ $this->direction = $nbt->getByte("Facing"); } - parent::__construct($level, $nbt); + parent::__construct($world, $nbt); } protected function initEntity(CompoundTag $nbt) : void{ @@ -107,9 +107,9 @@ class Painting extends Entity{ if($drops){ //non-living entities don't have a way to create drops generically yet - $this->level->dropItem($this, ItemFactory::get(Item::PAINTING)); + $this->world->dropItem($this, ItemFactory::get(Item::PAINTING)); } - $this->level->addParticle($this->add(0.5, 0.5, 0.5), new DestroyBlockParticle(BlockFactory::get(BlockLegacyIds::PLANKS))); + $this->world->addParticle($this->add(0.5, 0.5, 0.5), new DestroyBlockParticle(BlockFactory::get(BlockLegacyIds::PLANKS))); } protected function recalculateBoundingBox() : void{ @@ -121,7 +121,7 @@ class Painting extends Entity{ parent::onNearbyBlockChange(); $face = Bearing::toFacing($this->direction); - if(!self::canFit($this->level, $this->blockIn->getSide($face), $face, false, $this->getMotive())){ + if(!self::canFit($this->world, $this->blockIn->getSide($face), $face, false, $this->getMotive())){ $this->kill(); } } @@ -226,7 +226,7 @@ class Painting extends Entity{ /** * Returns whether a painting with the specified motive can be placed at the given position. * - * @param Level $level + * @param World $world * @param Vector3 $blockIn * @param int $facing * @param bool $checkOverlap @@ -234,7 +234,7 @@ class Painting extends Entity{ * * @return bool */ - public static function canFit(Level $level, Vector3 $blockIn, int $facing, bool $checkOverlap, PaintingMotive $motive) : bool{ + public static function canFit(World $world, Vector3 $blockIn, int $facing, bool $checkOverlap, PaintingMotive $motive) : bool{ $width = $motive->getWidth(); $height = $motive->getHeight(); @@ -251,7 +251,7 @@ class Painting extends Entity{ for($h = 0; $h < $height; ++$h){ $pos = $startPos->getSide($rotatedFace, $w)->getSide(Facing::UP, $h); - $block = $level->getBlockAt($pos->x, $pos->y, $pos->z); + $block = $world->getBlockAt($pos->x, $pos->y, $pos->z); if($block->isSolid() or !$block->getSide($oppositeSide)->isSolid()){ return false; } @@ -261,7 +261,7 @@ class Painting extends Entity{ if($checkOverlap){ $bb = self::getPaintingBB($blockIn, $facing, $motive); - foreach($level->getNearbyEntities($bb) as $entity){ + foreach($world->getNearbyEntities($bb) as $entity){ if($entity instanceof self){ return false; } diff --git a/src/pocketmine/entity/object/PrimedTNT.php b/src/pocketmine/entity/object/PrimedTNT.php index 92fc9870bd..58406b2aaa 100644 --- a/src/pocketmine/entity/object/PrimedTNT.php +++ b/src/pocketmine/entity/object/PrimedTNT.php @@ -27,12 +27,12 @@ use pocketmine\entity\Entity; use pocketmine\entity\Explosive; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\ExplosionPrimeEvent; -use pocketmine\level\Explosion; -use pocketmine\level\sound\IgniteSound; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ShortTag; use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; +use pocketmine\world\Explosion; +use pocketmine\world\sound\IgniteSound; class PrimedTNT extends Entity implements Explosive{ public const NETWORK_ID = self::TNT; @@ -68,7 +68,7 @@ class PrimedTNT extends Entity implements Explosive{ $this->setGenericFlag(EntityMetadataFlags::IGNITED, true); $this->propertyManager->setInt(EntityMetadataProperties::FUSE_LENGTH, $this->fuse); - $this->level->addSound($this, new IgniteSound()); + $this->world->addSound($this, new IgniteSound()); } diff --git a/src/pocketmine/entity/projectile/Arrow.php b/src/pocketmine/entity/projectile/Arrow.php index e20c679a64..0dde2ed117 100644 --- a/src/pocketmine/entity/projectile/Arrow.php +++ b/src/pocketmine/entity/projectile/Arrow.php @@ -29,14 +29,14 @@ use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\event\inventory\InventoryPickupArrowEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\level\Level; -use pocketmine\level\sound\ArrowHitSound; use pocketmine\math\RayTraceResult; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\TakeItemEntityPacket; use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; use pocketmine\Player; +use pocketmine\world\sound\ArrowHitSound; +use pocketmine\world\World; use function mt_rand; use function sqrt; @@ -67,8 +67,8 @@ class Arrow extends Projectile{ /** @var int */ protected $collideTicks = 0; - public function __construct(Level $level, CompoundTag $nbt, ?Entity $shootingEntity = null, bool $critical = false){ - parent::__construct($level, $nbt, $shootingEntity); + public function __construct(World $world, CompoundTag $nbt, ?Entity $shootingEntity = null, bool $critical = false){ + parent::__construct($world, $nbt, $shootingEntity); $this->setCritical($critical); } @@ -139,7 +139,7 @@ class Arrow extends Projectile{ protected function onHit(ProjectileHitEvent $event) : void{ $this->setCritical(false); - $this->level->addSound($this, new ArrowHitSound()); + $this->world->addSound($this, new ArrowHitSound()); } protected function onHitBlock(Block $blockHit, RayTraceResult $hitResult) : void{ diff --git a/src/pocketmine/entity/projectile/Egg.php b/src/pocketmine/entity/projectile/Egg.php index 70a1605544..f643220b25 100644 --- a/src/pocketmine/entity/projectile/Egg.php +++ b/src/pocketmine/entity/projectile/Egg.php @@ -26,7 +26,7 @@ namespace pocketmine\entity\projectile; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\level\particle\ItemBreakParticle; +use pocketmine\world\particle\ItemBreakParticle; class Egg extends Throwable{ public const NETWORK_ID = self::EGG; @@ -35,7 +35,7 @@ class Egg extends Throwable{ protected function onHit(ProjectileHitEvent $event) : void{ for($i = 0; $i < 6; ++$i){ - $this->level->addParticle($this, new ItemBreakParticle(ItemFactory::get(Item::EGG))); + $this->world->addParticle($this, new ItemBreakParticle(ItemFactory::get(Item::EGG))); } } } diff --git a/src/pocketmine/entity/projectile/EnderPearl.php b/src/pocketmine/entity/projectile/EnderPearl.php index 2d102909cf..9293219bab 100644 --- a/src/pocketmine/entity/projectile/EnderPearl.php +++ b/src/pocketmine/entity/projectile/EnderPearl.php @@ -27,11 +27,11 @@ use pocketmine\block\Block; use pocketmine\block\BlockLegacyIds; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\ProjectileHitEvent; -use pocketmine\level\particle\EndermanTeleportParticle; -use pocketmine\level\sound\EndermanTeleportSound; use pocketmine\math\AxisAlignedBB; use pocketmine\math\RayTraceResult; use pocketmine\math\Vector3; +use pocketmine\world\particle\EndermanTeleportParticle; +use pocketmine\world\sound\EndermanTeleportSound; class EnderPearl extends Throwable{ public const NETWORK_ID = self::ENDER_PEARL; @@ -51,10 +51,10 @@ class EnderPearl extends Throwable{ //TODO: check end gateways (when they are added) //TODO: spawn endermites at origin - $this->level->addParticle($owner, new EndermanTeleportParticle()); - $this->level->addSound($owner, new EndermanTeleportSound()); + $this->world->addParticle($owner, new EndermanTeleportParticle()); + $this->world->addSound($owner, new EndermanTeleportSound()); $owner->teleport($target = $event->getRayTraceResult()->getHitVector()); - $this->level->addSound($target, new EndermanTeleportSound()); + $this->world->addSound($target, new EndermanTeleportSound()); $owner->attack(new EntityDamageEvent($owner, EntityDamageEvent::CAUSE_FALL, 5)); } diff --git a/src/pocketmine/entity/projectile/ExperienceBottle.php b/src/pocketmine/entity/projectile/ExperienceBottle.php index 2a32aa6477..103ce1c03d 100644 --- a/src/pocketmine/entity/projectile/ExperienceBottle.php +++ b/src/pocketmine/entity/projectile/ExperienceBottle.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\entity\projectile; use pocketmine\event\entity\ProjectileHitEvent; -use pocketmine\level\particle\PotionSplashParticle; -use pocketmine\level\sound\PotionSplashSound; +use pocketmine\world\particle\PotionSplashParticle; +use pocketmine\world\sound\PotionSplashSound; use function mt_rand; class ExperienceBottle extends Throwable{ @@ -38,9 +38,9 @@ class ExperienceBottle extends Throwable{ } public function onHit(ProjectileHitEvent $event) : void{ - $this->level->addParticle($this, new PotionSplashParticle(PotionSplashParticle::DEFAULT_COLOR())); - $this->level->addSound($this, new PotionSplashSound()); + $this->world->addParticle($this, new PotionSplashParticle(PotionSplashParticle::DEFAULT_COLOR())); + $this->world->addSound($this, new PotionSplashSound()); - $this->level->dropExperience($this, mt_rand(3, 11)); + $this->world->dropExperience($this, mt_rand(3, 11)); } } diff --git a/src/pocketmine/entity/projectile/Projectile.php b/src/pocketmine/entity/projectile/Projectile.php index ee29edf4e8..1079046af2 100644 --- a/src/pocketmine/entity/projectile/Projectile.php +++ b/src/pocketmine/entity/projectile/Projectile.php @@ -34,8 +34,6 @@ use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\ProjectileHitBlockEvent; use pocketmine\event\entity\ProjectileHitEntityEvent; use pocketmine\event\entity\ProjectileHitEvent; -use pocketmine\level\Level; -use pocketmine\level\Position; use pocketmine\math\RayTraceResult; use pocketmine\math\Vector3; use pocketmine\math\VoxelRayTrace; @@ -43,6 +41,8 @@ use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\timings\Timings; +use pocketmine\world\Position; +use pocketmine\world\World; use function assert; use function atan2; use function ceil; @@ -58,8 +58,8 @@ abstract class Projectile extends Entity{ /** @var Block|null */ protected $blockHit; - public function __construct(Level $level, CompoundTag $nbt, ?Entity $shootingEntity = null){ - parent::__construct($level, $nbt); + public function __construct(World $world, CompoundTag $nbt, ?Entity $shootingEntity = null){ + parent::__construct($world, $nbt); if($shootingEntity !== null){ $this->setOwningEntity($shootingEntity); } @@ -84,7 +84,7 @@ abstract class Projectile extends Entity{ $blockData = null; if($nbt->hasTag("tileX", IntTag::class) and $nbt->hasTag("tileY", IntTag::class) and $nbt->hasTag("tileZ", IntTag::class)){ - $blockPos = new Position($nbt->getInt("tileX"), $nbt->getInt("tileY"), $nbt->getInt("tileZ"), $this->level); + $blockPos = new Position($nbt->getInt("tileX"), $nbt->getInt("tileY"), $nbt->getInt("tileZ"), $this->world); }else{ break; } @@ -163,7 +163,7 @@ abstract class Projectile extends Entity{ } public function onNearbyBlockChange() : void{ - if($this->blockHit !== null and $this->level->isInLoadedTerrain($this->blockHit) and !$this->blockHit->isSameState($this->level->getBlock($this->blockHit))){ + if($this->blockHit !== null and $this->world->isInLoadedTerrain($this->blockHit) and !$this->blockHit->isSameState($this->world->getBlock($this->blockHit))){ $this->blockHit = null; } @@ -187,7 +187,7 @@ abstract class Projectile extends Entity{ $hitResult = null; foreach(VoxelRayTrace::betweenPoints($start, $end) as $vector3){ - $block = $this->level->getBlockAt($vector3->x, $vector3->y, $vector3->z); + $block = $this->world->getBlockAt($vector3->x, $vector3->y, $vector3->z); $blockHitResult = $this->calculateInterceptWithBlock($block, $start, $end); if($blockHitResult !== null){ @@ -201,7 +201,7 @@ abstract class Projectile extends Entity{ $entityDistance = PHP_INT_MAX; $newDiff = $end->subtract($start); - foreach($this->level->getCollidingEntities($this->boundingBox->addCoord($newDiff->x, $newDiff->y, $newDiff->z)->expand(1, 1, 1), $this) as $entity){ + foreach($this->world->getCollidingEntities($this->boundingBox->addCoord($newDiff->x, $newDiff->y, $newDiff->z)->expand(1, 1, 1), $this) as $entity){ if($entity->getId() === $this->getOwningEntityId() and $this->ticksLived < 5){ continue; } diff --git a/src/pocketmine/entity/projectile/Snowball.php b/src/pocketmine/entity/projectile/Snowball.php index 587d980488..1ff3fc2f67 100644 --- a/src/pocketmine/entity/projectile/Snowball.php +++ b/src/pocketmine/entity/projectile/Snowball.php @@ -24,14 +24,14 @@ declare(strict_types=1); namespace pocketmine\entity\projectile; use pocketmine\event\entity\ProjectileHitEvent; -use pocketmine\level\particle\SnowballPoofParticle; +use pocketmine\world\particle\SnowballPoofParticle; class Snowball extends Throwable{ public const NETWORK_ID = self::SNOWBALL; protected function onHit(ProjectileHitEvent $event) : void{ for($i = 0; $i < 6; ++$i){ - $this->level->addParticle($this, new SnowballPoofParticle()); + $this->world->addParticle($this, new SnowballPoofParticle()); } } } diff --git a/src/pocketmine/entity/projectile/SplashPotion.php b/src/pocketmine/entity/projectile/SplashPotion.php index 5c74c75693..40c8ef0baf 100644 --- a/src/pocketmine/entity/projectile/SplashPotion.php +++ b/src/pocketmine/entity/projectile/SplashPotion.php @@ -32,12 +32,12 @@ use pocketmine\event\entity\ProjectileHitBlockEvent; use pocketmine\event\entity\ProjectileHitEntityEvent; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\item\Potion; -use pocketmine\level\particle\PotionSplashParticle; -use pocketmine\level\sound\PotionSplashSound; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; use pocketmine\utils\Color; +use pocketmine\world\particle\PotionSplashParticle; +use pocketmine\world\sound\PotionSplashSound; use function round; use function sqrt; @@ -83,12 +83,12 @@ class SplashPotion extends Throwable{ $particle = new PotionSplashParticle(Color::mix(...$colors)); } - $this->level->addParticle($this, $particle); - $this->level->addSound($this, new PotionSplashSound()); + $this->world->addParticle($this, $particle); + $this->world->addSound($this, new PotionSplashSound()); if($hasEffects){ if(!$this->willLinger()){ - foreach($this->level->getNearbyEntities($this->boundingBox->expandedCopy(4.125, 2.125, 4.125), $this) as $entity){ + foreach($this->world->getNearbyEntities($this->boundingBox->expandedCopy(4.125, 2.125, 4.125), $this) as $entity){ if($entity instanceof Living and $entity->isAlive()){ $distanceSquared = $entity->add(0, $entity->getEyeHeight(), 0)->distanceSquared($this); if($distanceSquared > 16){ //4 blocks @@ -123,11 +123,11 @@ class SplashPotion extends Throwable{ $blockIn = $event->getBlockHit()->getSide($event->getRayTraceResult()->getHitFace()); if($blockIn->getId() === BlockLegacyIds::FIRE){ - $this->level->setBlock($blockIn, BlockFactory::get(BlockLegacyIds::AIR)); + $this->world->setBlock($blockIn, BlockFactory::get(BlockLegacyIds::AIR)); } foreach($blockIn->getHorizontalSides() as $horizontalSide){ if($horizontalSide->getId() === BlockLegacyIds::FIRE){ - $this->level->setBlock($horizontalSide, BlockFactory::get(BlockLegacyIds::AIR)); + $this->world->setBlock($horizontalSide, BlockFactory::get(BlockLegacyIds::AIR)); } } } diff --git a/src/pocketmine/event/entity/EntityDamageByChildEntityEvent.php b/src/pocketmine/event/entity/EntityDamageByChildEntityEvent.php index e10e062ba9..ab994ad63a 100644 --- a/src/pocketmine/event/entity/EntityDamageByChildEntityEvent.php +++ b/src/pocketmine/event/entity/EntityDamageByChildEntityEvent.php @@ -51,6 +51,6 @@ class EntityDamageByChildEntityEvent extends EntityDamageByEntityEvent{ * @return Entity|null */ public function getChild() : ?Entity{ - return $this->getEntity()->getLevel()->getServer()->getLevelManager()->findEntity($this->childEntityEid); + return $this->getEntity()->getWorld()->getServer()->getWorldManager()->findEntity($this->childEntityEid); } } diff --git a/src/pocketmine/event/entity/EntityDamageByEntityEvent.php b/src/pocketmine/event/entity/EntityDamageByEntityEvent.php index 893c2672e7..ab0fdf8d70 100644 --- a/src/pocketmine/event/entity/EntityDamageByEntityEvent.php +++ b/src/pocketmine/event/entity/EntityDamageByEntityEvent.php @@ -69,7 +69,7 @@ class EntityDamageByEntityEvent extends EntityDamageEvent{ * @return Entity|null */ public function getDamager() : ?Entity{ - return $this->getEntity()->getLevel()->getServer()->getLevelManager()->findEntity($this->damagerEntityId); + return $this->getEntity()->getWorld()->getServer()->getWorldManager()->findEntity($this->damagerEntityId); } /** diff --git a/src/pocketmine/event/entity/EntityExplodeEvent.php b/src/pocketmine/event/entity/EntityExplodeEvent.php index f3aa1c98fb..106a6f6796 100644 --- a/src/pocketmine/event/entity/EntityExplodeEvent.php +++ b/src/pocketmine/event/entity/EntityExplodeEvent.php @@ -27,7 +27,7 @@ use pocketmine\block\Block; use pocketmine\entity\Entity; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\level\Position; +use pocketmine\world\Position; /** * Called when a entity explodes diff --git a/src/pocketmine/event/entity/EntityTeleportEvent.php b/src/pocketmine/event/entity/EntityTeleportEvent.php index 3c5c5dc573..160b5f9b77 100644 --- a/src/pocketmine/event/entity/EntityTeleportEvent.php +++ b/src/pocketmine/event/entity/EntityTeleportEvent.php @@ -26,7 +26,7 @@ namespace pocketmine\event\entity; use pocketmine\entity\Entity; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\level\Position; +use pocketmine\world\Position; class EntityTeleportEvent extends EntityEvent implements Cancellable{ use CancellableTrait; diff --git a/src/pocketmine/event/entity/EntityLevelChangeEvent.php b/src/pocketmine/event/entity/EntityWorldChangeEvent.php similarity index 66% rename from src/pocketmine/event/entity/EntityLevelChangeEvent.php rename to src/pocketmine/event/entity/EntityWorldChangeEvent.php index cb792115ef..fc020a7a45 100644 --- a/src/pocketmine/event/entity/EntityLevelChangeEvent.php +++ b/src/pocketmine/event/entity/EntityWorldChangeEvent.php @@ -26,27 +26,27 @@ namespace pocketmine\event\entity; use pocketmine\entity\Entity; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\level\Level; +use pocketmine\world\World; -class EntityLevelChangeEvent extends EntityEvent implements Cancellable{ +class EntityWorldChangeEvent extends EntityEvent implements Cancellable{ use CancellableTrait; - /** @var Level */ - private $originLevel; - /** @var Level */ - private $targetLevel; + /** @var World */ + private $originWorld; + /** @var World */ + private $targetWorld; - public function __construct(Entity $entity, Level $originLevel, Level $targetLevel){ + public function __construct(Entity $entity, World $originWorld, World $targetWorld){ $this->entity = $entity; - $this->originLevel = $originLevel; - $this->targetLevel = $targetLevel; + $this->originWorld = $originWorld; + $this->targetWorld = $targetWorld; } - public function getOrigin() : Level{ - return $this->originLevel; + public function getOrigin() : World{ + return $this->originWorld; } - public function getTarget() : Level{ - return $this->targetLevel; + public function getTarget() : World{ + return $this->targetWorld; } } diff --git a/src/pocketmine/event/player/PlayerMoveEvent.php b/src/pocketmine/event/player/PlayerMoveEvent.php index 720a98b95b..f949abd671 100644 --- a/src/pocketmine/event/player/PlayerMoveEvent.php +++ b/src/pocketmine/event/player/PlayerMoveEvent.php @@ -25,7 +25,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\level\Location; +use pocketmine\world\Location; use pocketmine\Player; class PlayerMoveEvent extends PlayerEvent implements Cancellable{ diff --git a/src/pocketmine/event/player/PlayerRespawnEvent.php b/src/pocketmine/event/player/PlayerRespawnEvent.php index 9a9380f2fc..1df9eac36b 100644 --- a/src/pocketmine/event/player/PlayerRespawnEvent.php +++ b/src/pocketmine/event/player/PlayerRespawnEvent.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\event\player; -use pocketmine\level\Position; +use pocketmine\world\Position; use pocketmine\Player; /** diff --git a/src/pocketmine/event/server/QueryRegenerateEvent.php b/src/pocketmine/event/server/QueryRegenerateEvent.php index c4effc1f9a..0550de3325 100644 --- a/src/pocketmine/event/server/QueryRegenerateEvent.php +++ b/src/pocketmine/event/server/QueryRegenerateEvent.php @@ -89,8 +89,8 @@ class QueryRegenerateEvent extends ServerEvent{ $this->gametype = ($server->getGamemode()->getMagicNumber() & 0x01) === 0 ? "SMP" : "CMP"; $this->version = $server->getVersion(); $this->server_engine = $server->getName() . " " . $server->getPocketMineVersion(); - $level = $server->getLevelManager()->getDefaultLevel(); - $this->map = $level === null ? "unknown" : $level->getDisplayName(); + $world = $server->getWorldManager()->getDefaultWorld(); + $this->map = $world === null ? "unknown" : $world->getDisplayName(); $this->numPlayers = count($this->players); $this->maxPlayers = $server->getMaxPlayers(); $this->whitelist = $server->hasWhitelist() ? "on" : "off"; diff --git a/src/pocketmine/event/level/ChunkEvent.php b/src/pocketmine/event/world/ChunkEvent.php similarity index 78% rename from src/pocketmine/event/level/ChunkEvent.php rename to src/pocketmine/event/world/ChunkEvent.php index b155a14a10..993e77d25d 100644 --- a/src/pocketmine/event/level/ChunkEvent.php +++ b/src/pocketmine/event/world/ChunkEvent.php @@ -22,24 +22,24 @@ declare(strict_types=1); -namespace pocketmine\event\level; +namespace pocketmine\event\world; -use pocketmine\level\format\Chunk; -use pocketmine\level\Level; +use pocketmine\world\format\Chunk; +use pocketmine\world\World; /** * Chunk-related events */ -abstract class ChunkEvent extends LevelEvent{ +abstract class ChunkEvent extends WorldEvent{ /** @var Chunk */ private $chunk; /** - * @param Level $level + * @param World $world * @param Chunk $chunk */ - public function __construct(Level $level, Chunk $chunk){ - parent::__construct($level); + public function __construct(World $world, Chunk $chunk){ + parent::__construct($world); $this->chunk = $chunk; } diff --git a/src/pocketmine/event/level/ChunkLoadEvent.php b/src/pocketmine/event/world/ChunkLoadEvent.php similarity index 83% rename from src/pocketmine/event/level/ChunkLoadEvent.php rename to src/pocketmine/event/world/ChunkLoadEvent.php index 660248d7f1..575bf74cf8 100644 --- a/src/pocketmine/event/level/ChunkLoadEvent.php +++ b/src/pocketmine/event/world/ChunkLoadEvent.php @@ -22,10 +22,10 @@ declare(strict_types=1); -namespace pocketmine\event\level; +namespace pocketmine\event\world; -use pocketmine\level\format\Chunk; -use pocketmine\level\Level; +use pocketmine\world\format\Chunk; +use pocketmine\world\World; /** * Called when a Chunk is loaded @@ -34,8 +34,8 @@ class ChunkLoadEvent extends ChunkEvent{ /** @var bool */ private $newChunk; - public function __construct(Level $level, Chunk $chunk, bool $newChunk){ - parent::__construct($level, $chunk); + public function __construct(World $world, Chunk $chunk, bool $newChunk){ + parent::__construct($world, $chunk); $this->newChunk = $newChunk; } diff --git a/src/pocketmine/event/level/ChunkPopulateEvent.php b/src/pocketmine/event/world/ChunkPopulateEvent.php similarity index 96% rename from src/pocketmine/event/level/ChunkPopulateEvent.php rename to src/pocketmine/event/world/ChunkPopulateEvent.php index 76c6abb8da..3797bb58b4 100644 --- a/src/pocketmine/event/level/ChunkPopulateEvent.php +++ b/src/pocketmine/event/world/ChunkPopulateEvent.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\event\level; +namespace pocketmine\event\world; /** * Called when a Chunk is populated (after receiving it on the main thread) diff --git a/src/pocketmine/event/level/ChunkUnloadEvent.php b/src/pocketmine/event/world/ChunkUnloadEvent.php similarity index 96% rename from src/pocketmine/event/level/ChunkUnloadEvent.php rename to src/pocketmine/event/world/ChunkUnloadEvent.php index e37df56cd1..89b58b6d47 100644 --- a/src/pocketmine/event/level/ChunkUnloadEvent.php +++ b/src/pocketmine/event/world/ChunkUnloadEvent.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\event\level; +namespace pocketmine\event\world; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; diff --git a/src/pocketmine/event/level/SpawnChangeEvent.php b/src/pocketmine/event/world/SpawnChangeEvent.php similarity index 76% rename from src/pocketmine/event/level/SpawnChangeEvent.php rename to src/pocketmine/event/world/SpawnChangeEvent.php index 5c6476fe6f..2088568598 100644 --- a/src/pocketmine/event/level/SpawnChangeEvent.php +++ b/src/pocketmine/event/world/SpawnChangeEvent.php @@ -21,25 +21,25 @@ declare(strict_types=1); -namespace pocketmine\event\level; +namespace pocketmine\event\world; -use pocketmine\level\Level; -use pocketmine\level\Position; +use pocketmine\world\Position; +use pocketmine\world\World; /** - * An event that is called when a level spawn changes. + * An event that is called when a world spawn changes. * The previous spawn is included */ -class SpawnChangeEvent extends LevelEvent{ +class SpawnChangeEvent extends WorldEvent{ /** @var Position */ private $previousSpawn; /** - * @param Level $level + * @param World $world * @param Position $previousSpawn */ - public function __construct(Level $level, Position $previousSpawn){ - parent::__construct($level); + public function __construct(World $world, Position $previousSpawn){ + parent::__construct($world); $this->previousSpawn = $previousSpawn; } diff --git a/src/pocketmine/event/level/LevelEvent.php b/src/pocketmine/event/world/WorldEvent.php similarity index 70% rename from src/pocketmine/event/level/LevelEvent.php rename to src/pocketmine/event/world/WorldEvent.php index 7e24f5d281..193a0d8e1c 100644 --- a/src/pocketmine/event/level/LevelEvent.php +++ b/src/pocketmine/event/world/WorldEvent.php @@ -22,28 +22,28 @@ declare(strict_types=1); /** - * Level related events + * World related events */ -namespace pocketmine\event\level; +namespace pocketmine\event\world; use pocketmine\event\Event; -use pocketmine\level\Level; +use pocketmine\world\World; -abstract class LevelEvent extends Event{ - /** @var Level */ - private $level; +abstract class WorldEvent extends Event{ + /** @var World */ + private $world; /** - * @param Level $level + * @param World $world */ - public function __construct(Level $level){ - $this->level = $level; + public function __construct(World $world){ + $this->world = $world; } /** - * @return Level + * @return World */ - public function getLevel() : Level{ - return $this->level; + public function getWorld() : World{ + return $this->world; } } diff --git a/src/pocketmine/event/level/LevelInitEvent.php b/src/pocketmine/event/world/WorldInitEvent.php similarity index 86% rename from src/pocketmine/event/level/LevelInitEvent.php rename to src/pocketmine/event/world/WorldInitEvent.php index 7bf1b4c256..4b85571ed9 100644 --- a/src/pocketmine/event/level/LevelInitEvent.php +++ b/src/pocketmine/event/world/WorldInitEvent.php @@ -21,11 +21,11 @@ declare(strict_types=1); -namespace pocketmine\event\level; +namespace pocketmine\event\world; /** - * Called when a Level is initializing + * Called when a World is initializing */ -class LevelInitEvent extends LevelEvent{ +class WorldInitEvent extends WorldEvent{ } diff --git a/src/pocketmine/event/level/LevelLoadEvent.php b/src/pocketmine/event/world/WorldLoadEvent.php similarity index 87% rename from src/pocketmine/event/level/LevelLoadEvent.php rename to src/pocketmine/event/world/WorldLoadEvent.php index 32e58bbc37..18235c29b6 100644 --- a/src/pocketmine/event/level/LevelLoadEvent.php +++ b/src/pocketmine/event/world/WorldLoadEvent.php @@ -21,11 +21,11 @@ declare(strict_types=1); -namespace pocketmine\event\level; +namespace pocketmine\event\world; /** - * Called when a Level is loaded + * Called when a World is loaded */ -class LevelLoadEvent extends LevelEvent{ +class WorldLoadEvent extends WorldEvent{ } diff --git a/src/pocketmine/event/level/LevelSaveEvent.php b/src/pocketmine/event/world/WorldSaveEvent.php similarity index 87% rename from src/pocketmine/event/level/LevelSaveEvent.php rename to src/pocketmine/event/world/WorldSaveEvent.php index 5e077f343a..e438947911 100644 --- a/src/pocketmine/event/level/LevelSaveEvent.php +++ b/src/pocketmine/event/world/WorldSaveEvent.php @@ -21,11 +21,11 @@ declare(strict_types=1); -namespace pocketmine\event\level; +namespace pocketmine\event\world; /** - * Called when a Level is saved + * Called when a World is saved */ -class LevelSaveEvent extends LevelEvent{ +class WorldSaveEvent extends WorldEvent{ } diff --git a/src/pocketmine/event/level/LevelUnloadEvent.php b/src/pocketmine/event/world/WorldUnloadEvent.php similarity index 86% rename from src/pocketmine/event/level/LevelUnloadEvent.php rename to src/pocketmine/event/world/WorldUnloadEvent.php index 14b950396b..7f5b3ff8b4 100644 --- a/src/pocketmine/event/level/LevelUnloadEvent.php +++ b/src/pocketmine/event/world/WorldUnloadEvent.php @@ -21,14 +21,14 @@ declare(strict_types=1); -namespace pocketmine\event\level; +namespace pocketmine\event\world; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; /** - * Called when a Level is unloaded + * Called when a World is unloaded */ -class LevelUnloadEvent extends LevelEvent implements Cancellable{ +class WorldUnloadEvent extends WorldEvent implements Cancellable{ use CancellableTrait; } diff --git a/src/pocketmine/inventory/AnvilInventory.php b/src/pocketmine/inventory/AnvilInventory.php index f22b56674c..b1891531be 100644 --- a/src/pocketmine/inventory/AnvilInventory.php +++ b/src/pocketmine/inventory/AnvilInventory.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\inventory; -use pocketmine\level\Position; +use pocketmine\world\Position; use pocketmine\network\mcpe\protocol\types\WindowTypes; use pocketmine\Player; diff --git a/src/pocketmine/inventory/ArmorInventory.php b/src/pocketmine/inventory/ArmorInventory.php index 39700c51d4..744ccde8ba 100644 --- a/src/pocketmine/inventory/ArmorInventory.php +++ b/src/pocketmine/inventory/ArmorInventory.php @@ -101,7 +101,7 @@ class ArmorInventory extends BaseInventory{ $pk = new MobArmorEquipmentPacket(); $pk->entityRuntimeId = $this->getHolder()->getId(); $pk->slots = $this->getContents(true); - $this->holder->getLevel()->getServer()->broadcastPacket($target, $pk); + $this->holder->getWorld()->getServer()->broadcastPacket($target, $pk); } } @@ -123,7 +123,7 @@ class ArmorInventory extends BaseInventory{ $pk = new MobArmorEquipmentPacket(); $pk->entityRuntimeId = $this->getHolder()->getId(); $pk->slots = $armor; - $this->holder->getLevel()->getServer()->broadcastPacket($target, $pk); + $this->holder->getWorld()->getServer()->broadcastPacket($target, $pk); } } diff --git a/src/pocketmine/inventory/ChestInventory.php b/src/pocketmine/inventory/ChestInventory.php index 0b5f269b7e..f9da8aea5a 100644 --- a/src/pocketmine/inventory/ChestInventory.php +++ b/src/pocketmine/inventory/ChestInventory.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace pocketmine\inventory; -use pocketmine\level\sound\ChestCloseSound; -use pocketmine\level\sound\ChestOpenSound; -use pocketmine\level\sound\Sound; +use pocketmine\world\sound\ChestCloseSound; +use pocketmine\world\sound\ChestOpenSound; +use pocketmine\world\sound\Sound; use pocketmine\network\mcpe\protocol\BlockEventPacket; use pocketmine\network\mcpe\protocol\types\WindowTypes; use pocketmine\Player; @@ -70,7 +70,7 @@ class ChestInventory extends ContainerInventory{ if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){ //TODO: this crap really shouldn't be managed by the inventory $this->broadcastBlockEventPacket(true); - $this->getHolder()->getLevel()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getOpenSound()); + $this->getHolder()->getWorld()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getOpenSound()); } } @@ -78,7 +78,7 @@ class ChestInventory extends ContainerInventory{ if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){ //TODO: this crap really shouldn't be managed by the inventory $this->broadcastBlockEventPacket(false); - $this->getHolder()->getLevel()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getCloseSound()); + $this->getHolder()->getWorld()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getCloseSound()); } parent::onClose($who); } @@ -92,6 +92,6 @@ class ChestInventory extends ContainerInventory{ $pk->z = (int) $holder->z; $pk->eventType = 1; //it's always 1 for a chest $pk->eventData = $isOpen ? 1 : 0; - $holder->getLevel()->broadcastPacketToViewers($holder, $pk); + $holder->getWorld()->broadcastPacketToViewers($holder, $pk); } } diff --git a/src/pocketmine/inventory/EnchantInventory.php b/src/pocketmine/inventory/EnchantInventory.php index 4d3a6b97fa..d3e41cf436 100644 --- a/src/pocketmine/inventory/EnchantInventory.php +++ b/src/pocketmine/inventory/EnchantInventory.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\inventory; -use pocketmine\level\Position; +use pocketmine\world\Position; use pocketmine\network\mcpe\protocol\types\WindowTypes; use pocketmine\Player; diff --git a/src/pocketmine/inventory/EnderChestInventory.php b/src/pocketmine/inventory/EnderChestInventory.php index 7523b87025..6395f4d30c 100644 --- a/src/pocketmine/inventory/EnderChestInventory.php +++ b/src/pocketmine/inventory/EnderChestInventory.php @@ -23,12 +23,12 @@ declare(strict_types=1); namespace pocketmine\inventory; -use pocketmine\level\Position; -use pocketmine\level\sound\EnderChestCloseSound; -use pocketmine\level\sound\EnderChestOpenSound; -use pocketmine\level\sound\Sound; use pocketmine\network\mcpe\protocol\types\WindowTypes; use pocketmine\tile\EnderChest; +use pocketmine\world\Position; +use pocketmine\world\sound\EnderChestCloseSound; +use pocketmine\world\sound\EnderChestOpenSound; +use pocketmine\world\sound\Sound; class EnderChestInventory extends ChestInventory{ @@ -50,7 +50,7 @@ class EnderChestInventory extends ChestInventory{ */ public function setHolderPosition(EnderChest $enderChest) : void{ $this->holder->setComponents($enderChest->getFloorX(), $enderChest->getFloorY(), $enderChest->getFloorZ()); - $this->holder->setLevel($enderChest->getLevel()); + $this->holder->setWorld($enderChest->getWorld()); } protected function getOpenSound() : Sound{ diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index df0fedcc21..e6b93a44c2 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -151,7 +151,7 @@ class PlayerInventory extends BaseInventory{ $this->sendSlot($this->getHeldItemIndex(), $target); } }else{ - $this->getHolder()->getLevel()->getServer()->broadcastPacket($target, $pk); + $this->getHolder()->getWorld()->getServer()->broadcastPacket($target, $pk); if(in_array($this->getHolder(), $target, true)){ $this->sendSlot($this->getHeldItemIndex(), $this->getHolder()); } diff --git a/src/pocketmine/item/Bow.php b/src/pocketmine/item/Bow.php index 74d3f41bd1..290a220d40 100644 --- a/src/pocketmine/item/Bow.php +++ b/src/pocketmine/item/Bow.php @@ -29,7 +29,7 @@ use pocketmine\entity\projectile\Projectile; use pocketmine\event\entity\EntityShootBowEvent; use pocketmine\event\entity\ProjectileLaunchEvent; use pocketmine\item\enchantment\Enchantment; -use pocketmine\level\sound\BowShootSound; +use pocketmine\world\sound\BowShootSound; use pocketmine\Player; use function intdiv; use function min; @@ -65,7 +65,7 @@ class Bow extends Tool{ $baseForce = min((($p ** 2) + $p * 2) / 3, 1); /** @var ArrowEntity $entity */ - $entity = EntityFactory::create(ArrowEntity::class, $player->getLevel(), $nbt, $player, $baseForce >= 1); + $entity = EntityFactory::create(ArrowEntity::class, $player->getWorld(), $nbt, $player, $baseForce >= 1); $infinity = $this->hasEnchantment(Enchantment::INFINITY()); if($infinity){ @@ -106,7 +106,7 @@ class Bow extends Tool{ } $ev->getProjectile()->spawnToAll(); - $player->getLevel()->addSound($player, new BowShootSound()); + $player->getWorld()->addSound($player, new BowShootSound()); }else{ $entity->spawnToAll(); } diff --git a/src/pocketmine/item/Bucket.php b/src/pocketmine/item/Bucket.php index 4af42b9ac7..095ae7fd94 100644 --- a/src/pocketmine/item/Bucket.php +++ b/src/pocketmine/item/Bucket.php @@ -47,8 +47,8 @@ class Bucket extends Item{ $ev = new PlayerBucketFillEvent($player, $blockReplace, $face, $this, $resultItem); $ev->call(); if(!$ev->isCancelled()){ - $player->getLevel()->setBlock($blockClicked, BlockFactory::get(BlockLegacyIds::AIR)); - $player->getLevel()->addSound($blockClicked->add(0.5, 0.5, 0.5), $blockClicked->getBucketFillSound()); + $player->getWorld()->setBlock($blockClicked, BlockFactory::get(BlockLegacyIds::AIR)); + $player->getWorld()->addSound($blockClicked->add(0.5, 0.5, 0.5), $blockClicked->getBucketFillSound()); if($player->hasFiniteResources()){ if($stack->getCount() === 0){ $player->getInventory()->setItemInHand($ev->getItem()); diff --git a/src/pocketmine/item/ChorusFruit.php b/src/pocketmine/item/ChorusFruit.php index 757fd126b1..5bbb9dd10d 100644 --- a/src/pocketmine/item/ChorusFruit.php +++ b/src/pocketmine/item/ChorusFruit.php @@ -25,8 +25,8 @@ namespace pocketmine\item; use pocketmine\block\Liquid; use pocketmine\entity\Living; -use pocketmine\level\sound\EndermanTeleportSound; use pocketmine\math\Vector3; +use pocketmine\world\sound\EndermanTeleportSound; use function assert; use function min; use function mt_rand; @@ -50,11 +50,11 @@ class ChorusFruit extends Food{ } public function onConsume(Living $consumer) : void{ - $level = $consumer->getLevel(); - assert($level !== null); + $world = $consumer->getWorld(); + assert($world !== null); $minX = $consumer->getFloorX() - 8; - $minY = min($consumer->getFloorY(), $consumer->getLevel()->getWorldHeight()) - 8; + $minY = min($consumer->getFloorY(), $consumer->getWorld()->getWorldHeight()) - 8; $minZ = $consumer->getFloorZ() - 8; $maxX = $minX + 16; @@ -66,23 +66,23 @@ class ChorusFruit extends Food{ $y = mt_rand($minY, $maxY); $z = mt_rand($minZ, $maxZ); - while($y >= 0 and !$level->getBlockAt($x, $y, $z)->isSolid()){ + while($y >= 0 and !$world->getBlockAt($x, $y, $z)->isSolid()){ $y--; } if($y < 0){ continue; } - $blockUp = $level->getBlockAt($x, $y + 1, $z); - $blockUp2 = $level->getBlockAt($x, $y + 2, $z); + $blockUp = $world->getBlockAt($x, $y + 1, $z); + $blockUp2 = $world->getBlockAt($x, $y + 2, $z); if($blockUp->isSolid() or $blockUp instanceof Liquid or $blockUp2->isSolid() or $blockUp2 instanceof Liquid){ continue; } //Sounds are broadcasted at both source and destination - $level->addSound($consumer->asVector3(), new EndermanTeleportSound()); + $world->addSound($consumer->asVector3(), new EndermanTeleportSound()); $consumer->teleport($target = new Vector3($x + 0.5, $y + 1, $z + 0.5)); - $level->addSound($target, new EndermanTeleportSound()); + $world->addSound($target, new EndermanTeleportSound()); break; } diff --git a/src/pocketmine/item/FlintSteel.php b/src/pocketmine/item/FlintSteel.php index 241d4f5af1..e69df4d412 100644 --- a/src/pocketmine/item/FlintSteel.php +++ b/src/pocketmine/item/FlintSteel.php @@ -26,9 +26,9 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; -use pocketmine\level\sound\FlintSteelSound; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\sound\FlintSteelSound; use function assert; class FlintSteel extends Tool{ @@ -38,10 +38,10 @@ class FlintSteel extends Tool{ public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ if($blockReplace->getId() === BlockLegacyIds::AIR){ - $level = $player->getLevel(); - assert($level !== null); - $level->setBlock($blockReplace, BlockFactory::get(BlockLegacyIds::FIRE)); - $level->addSound($blockReplace->add(0.5, 0.5, 0.5), new FlintSteelSound()); + $world = $player->getWorld(); + assert($world !== null); + $world->setBlock($blockReplace, BlockFactory::get(BlockLegacyIds::FIRE)); + $world->addSound($blockReplace->add(0.5, 0.5, 0.5), new FlintSteelSound()); $this->applyDamage(1); diff --git a/src/pocketmine/item/LiquidBucket.php b/src/pocketmine/item/LiquidBucket.php index 4ef4cdcd11..5ec0efe31d 100644 --- a/src/pocketmine/item/LiquidBucket.php +++ b/src/pocketmine/item/LiquidBucket.php @@ -63,8 +63,8 @@ class LiquidBucket extends Item{ $ev = new PlayerBucketEmptyEvent($player, $blockReplace, $face, $this, ItemFactory::get(Item::BUCKET)); $ev->call(); if(!$ev->isCancelled()){ - $player->getLevel()->setBlock($blockReplace, $resultBlock->getFlowingForm()); - $player->getLevel()->addSound($blockClicked->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound()); + $player->getWorld()->setBlock($blockReplace, $resultBlock->getFlowingForm()); + $player->getWorld()->addSound($blockClicked->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound()); if($player->hasFiniteResources()){ $player->getInventory()->setItemInHand($ev->getItem()); diff --git a/src/pocketmine/item/PaintingItem.php b/src/pocketmine/item/PaintingItem.php index e577d9b49b..8d9642c49c 100644 --- a/src/pocketmine/item/PaintingItem.php +++ b/src/pocketmine/item/PaintingItem.php @@ -52,7 +52,7 @@ class PaintingItem extends Item{ continue; } - if(Painting::canFit($player->getLevel(), $blockReplace, $face, true, $motive)){ + if(Painting::canFit($player->getWorld(), $blockReplace, $face, true, $motive)){ if($currentTotalDimension > $totalDimension){ $totalDimension = $currentTotalDimension; /* @@ -94,11 +94,11 @@ class PaintingItem extends Item{ $nbt->setInt("TileZ", $blockClicked->getFloorZ()); /** @var Painting $entity */ - $entity = EntityFactory::create(Painting::class, $blockReplace->getLevel(), $nbt); + $entity = EntityFactory::create(Painting::class, $blockReplace->getWorld(), $nbt); $this->pop(); $entity->spawnToAll(); - $player->getLevel()->broadcastLevelEvent($blockReplace->add(0.5, 0.5, 0.5), LevelEventPacket::EVENT_SOUND_ITEMFRAME_PLACE); //item frame and painting have the same sound + $player->getWorld()->broadcastLevelEvent($blockReplace->add(0.5, 0.5, 0.5), LevelEventPacket::EVENT_SOUND_ITEMFRAME_PLACE); //item frame and painting have the same sound return ItemUseResult::SUCCESS(); } } diff --git a/src/pocketmine/item/ProjectileItem.php b/src/pocketmine/item/ProjectileItem.php index f633057fe6..66adef0b06 100644 --- a/src/pocketmine/item/ProjectileItem.php +++ b/src/pocketmine/item/ProjectileItem.php @@ -26,7 +26,7 @@ namespace pocketmine\item; use pocketmine\entity\EntityFactory; use pocketmine\entity\projectile\Throwable; use pocketmine\event\entity\ProjectileLaunchEvent; -use pocketmine\level\sound\ThrowSound; +use pocketmine\world\sound\ThrowSound; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\Player; @@ -60,7 +60,7 @@ abstract class ProjectileItem extends Item{ Utils::testValidInstance($class, Throwable::class); /** @var Throwable $projectile */ - $projectile = EntityFactory::create($class, $player->getLevel(), $nbt, $player); + $projectile = EntityFactory::create($class, $player->getWorld(), $nbt, $player); $projectile->setMotion($projectile->getMotion()->multiply($this->getThrowForce())); $projectileEv = new ProjectileLaunchEvent($projectile); @@ -72,7 +72,7 @@ abstract class ProjectileItem extends Item{ $projectile->spawnToAll(); - $player->getLevel()->addSound($player, new ThrowSound()); + $player->getWorld()->addSound($player, new ThrowSound()); $this->pop(); diff --git a/src/pocketmine/item/SpawnEgg.php b/src/pocketmine/item/SpawnEgg.php index 6fd053a1f1..de42271d83 100644 --- a/src/pocketmine/item/SpawnEgg.php +++ b/src/pocketmine/item/SpawnEgg.php @@ -57,7 +57,7 @@ class SpawnEgg extends Item{ $nbt->setString("CustomName", $this->getCustomName()); } - $entity = EntityFactory::create($this->entityClass, $player->getLevel(), $nbt); + $entity = EntityFactory::create($this->entityClass, $player->getWorld(), $nbt); $this->pop(); $entity->spawnToAll(); //TODO: what if the entity was marked for deletion? diff --git a/src/pocketmine/metadata/BlockMetadataStore.php b/src/pocketmine/metadata/BlockMetadataStore.php index b8968e1d70..87cfd85f96 100644 --- a/src/pocketmine/metadata/BlockMetadataStore.php +++ b/src/pocketmine/metadata/BlockMetadataStore.php @@ -24,19 +24,19 @@ declare(strict_types=1); namespace pocketmine\metadata; use pocketmine\block\Block; -use pocketmine\level\Level; use pocketmine\plugin\Plugin; +use pocketmine\world\World; class BlockMetadataStore extends MetadataStore{ - /** @var Level */ + /** @var World */ private $owningLevel; - public function __construct(Level $owningLevel){ + public function __construct(World $owningLevel){ $this->owningLevel = $owningLevel; } private function disambiguate(Block $block, string $metadataKey) : string{ - if($block->getLevel() !== $this->owningLevel){ + if($block->getWorld() !== $this->owningLevel){ throw new \InvalidStateException("Block does not belong to world " . $this->owningLevel->getDisplayName()); } return $block->x . ":" . $block->y . ":" . $block->z . ":" . $metadataKey; diff --git a/src/pocketmine/metadata/LevelMetadataStore.php b/src/pocketmine/metadata/WorldMetadataStore.php similarity index 73% rename from src/pocketmine/metadata/LevelMetadataStore.php rename to src/pocketmine/metadata/WorldMetadataStore.php index 259d7fbc87..7893ba19aa 100644 --- a/src/pocketmine/metadata/LevelMetadataStore.php +++ b/src/pocketmine/metadata/WorldMetadataStore.php @@ -23,29 +23,29 @@ declare(strict_types=1); namespace pocketmine\metadata; -use pocketmine\level\Level; use pocketmine\plugin\Plugin; +use pocketmine\world\World; use function strtolower; -class LevelMetadataStore extends MetadataStore{ +class WorldMetadataStore extends MetadataStore{ - private function disambiguate(Level $level, string $metadataKey) : string{ - return strtolower($level->getFolderName()) . ":" . $metadataKey; + private function disambiguate(World $world, string $metadataKey) : string{ + return strtolower($world->getFolderName()) . ":" . $metadataKey; } - public function getMetadata(Level $subject, string $metadataKey){ + public function getMetadata(World $subject, string $metadataKey){ return $this->getMetadataInternal($this->disambiguate($subject, $metadataKey)); } - public function hasMetadata(Level $subject, string $metadataKey) : bool{ + public function hasMetadata(World $subject, string $metadataKey) : bool{ return $this->hasMetadataInternal($this->disambiguate($subject, $metadataKey)); } - public function removeMetadata(Level $subject, string $metadataKey, Plugin $owningPlugin) : void{ + public function removeMetadata(World $subject, string $metadataKey, Plugin $owningPlugin) : void{ $this->removeMetadataInternal($this->disambiguate($subject, $metadataKey), $owningPlugin); } - public function setMetadata(Level $subject, string $metadataKey, MetadataValue $newMetadataValue) : void{ + public function setMetadata(World $subject, string $metadataKey, MetadataValue $newMetadataValue) : void{ $this->setMetadataInternal($this->disambiguate($subject, $metadataKey), $newMetadataValue); } } diff --git a/src/pocketmine/network/mcpe/ChunkCache.php b/src/pocketmine/network/mcpe/ChunkCache.php index dcadd609d6..52134e5d0c 100644 --- a/src/pocketmine/network/mcpe/ChunkCache.php +++ b/src/pocketmine/network/mcpe/ChunkCache.php @@ -23,10 +23,10 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; -use pocketmine\level\ChunkListener; -use pocketmine\level\format\Chunk; -use pocketmine\level\Level; use pocketmine\math\Vector3; +use pocketmine\world\ChunkListener; +use pocketmine\world\format\Chunk; +use pocketmine\world\World; use function spl_object_id; use function strlen; @@ -43,15 +43,15 @@ class ChunkCache implements ChunkListener{ /** * Fetches the ChunkCache instance for the given world. This lazily creates cache systems as needed. * - * @param Level $world + * @param World $world * * @return ChunkCache */ - public static function getInstance(Level $world) : self{ + public static function getInstance(World $world) : self{ return self::$instances[spl_object_id($world)] ?? (self::$instances[spl_object_id($world)] = new self($world)); } - /** @var Level */ + /** @var World */ private $world; /** @var CompressBatchPromise[] */ @@ -63,9 +63,9 @@ class ChunkCache implements ChunkListener{ private $misses = 0; /** - * @param Level $world + * @param World $world */ - private function __construct(Level $world){ + private function __construct(World $world){ $this->world = $world; } @@ -79,7 +79,7 @@ class ChunkCache implements ChunkListener{ */ public function request(int $chunkX, int $chunkZ) : CompressBatchPromise{ $this->world->registerChunkListener($this, $chunkX, $chunkZ); - $chunkHash = Level::chunkHash($chunkX, $chunkZ); + $chunkHash = World::chunkHash($chunkX, $chunkZ); if(isset($this->caches[$chunkHash])){ ++$this->hits; @@ -113,7 +113,7 @@ class ChunkCache implements ChunkListener{ } private function destroy(int $chunkX, int $chunkZ) : bool{ - $chunkHash = Level::chunkHash($chunkX, $chunkZ); + $chunkHash = World::chunkHash($chunkX, $chunkZ); $existing = $this->caches[$chunkHash] ?? null; unset($this->caches[$chunkHash]); @@ -129,7 +129,7 @@ class ChunkCache implements ChunkListener{ * @throws \InvalidArgumentException */ private function restartPendingRequest(int $chunkX, int $chunkZ) : void{ - $chunkHash = Level::chunkHash($chunkX, $chunkZ); + $chunkHash = World::chunkHash($chunkX, $chunkZ); $existing = $this->caches[$chunkHash]; if($existing === null or $existing->hasResult()){ throw new \InvalidArgumentException("Restart can only be applied to unresolved promises"); @@ -147,7 +147,7 @@ class ChunkCache implements ChunkListener{ * @throws \InvalidArgumentException */ private function destroyOrRestart(int $chunkX, int $chunkZ) : void{ - $cache = $this->caches[Level::chunkHash($chunkX, $chunkZ)] ?? null; + $cache = $this->caches[World::chunkHash($chunkX, $chunkZ)] ?? null; if($cache !== null){ if(!$cache->hasResult()){ //some requesters are waiting for this chunk, so their request needs to be fulfilled diff --git a/src/pocketmine/network/mcpe/ChunkRequestTask.php b/src/pocketmine/network/mcpe/ChunkRequestTask.php index 30d2725c10..635348367b 100644 --- a/src/pocketmine/network/mcpe/ChunkRequestTask.php +++ b/src/pocketmine/network/mcpe/ChunkRequestTask.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; -use pocketmine\level\format\Chunk; +use pocketmine\world\format\Chunk; use pocketmine\network\mcpe\protocol\FullChunkDataPacket; use pocketmine\scheduler\AsyncTask; diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index d12347a75e..f28d3b44ad 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -30,7 +30,6 @@ use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\event\server\DataPacketSendEvent; use pocketmine\form\Form; use pocketmine\GameMode; -use pocketmine\level\Position; use pocketmine\math\Vector3; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\DeathSessionHandler; @@ -70,6 +69,7 @@ use pocketmine\PlayerInfo; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\BinaryDataException; +use pocketmine\world\Position; use function bin2hex; use function count; use function get_class; @@ -761,18 +761,18 @@ class NetworkSession{ } public function startUsingChunk(int $chunkX, int $chunkZ, bool $spawn = false) : void{ - ChunkCache::getInstance($this->player->getLevel())->request($chunkX, $chunkZ)->onResolve( + ChunkCache::getInstance($this->player->getWorld())->request($chunkX, $chunkZ)->onResolve( //this callback may be called synchronously or asynchronously, depending on whether the promise is resolved yet function(CompressBatchPromise $promise) use($chunkX, $chunkZ, $spawn){ if(!$this->isConnected()){ return; } - $this->player->level->timings->syncChunkSendTimer->startTiming(); + $this->player->world->timings->syncChunkSendTimer->startTiming(); try{ $this->queueCompressed($promise); - foreach($this->player->getLevel()->getChunkEntities($chunkX, $chunkZ) as $entity){ + foreach($this->player->getWorld()->getChunkEntities($chunkX, $chunkZ) as $entity){ if($entity !== $this->player and !$entity->isClosed() and !$entity->isFlaggedForDespawn()){ $entity->spawnTo($this->player); } @@ -783,14 +783,14 @@ class NetworkSession{ $this->onTerrainReady(); } }finally{ - $this->player->level->timings->syncChunkSendTimer->stopTiming(); + $this->player->world->timings->syncChunkSendTimer->stopTiming(); } } ); } public function stopUsingChunk(int $chunkX, int $chunkZ) : void{ - foreach($this->player->getLevel()->getChunkEntities($chunkX, $chunkZ) as $entity){ + foreach($this->player->getWorld()->getChunkEntities($chunkX, $chunkZ) as $entity){ if($entity !== $this->player){ $entity->despawnFrom($this->player); } diff --git a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php index 7c1abf5fbd..1d69a38d07 100644 --- a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php @@ -64,12 +64,12 @@ class PreSpawnSessionHandler extends SessionHandler{ $pk->seed = -1; $pk->dimension = DimensionIds::OVERWORLD; //TODO: implement this properly $pk->worldGamemode = NetworkSession::getClientFriendlyGamemode($this->server->getGamemode()); - $pk->difficulty = $this->player->getLevel()->getDifficulty(); + $pk->difficulty = $this->player->getWorld()->getDifficulty(); $pk->spawnX = $spawnPosition->getFloorX(); $pk->spawnY = $spawnPosition->getFloorY(); $pk->spawnZ = $spawnPosition->getFloorZ(); $pk->hasAchievementsDisabled = true; - $pk->time = $this->player->getLevel()->getTime(); + $pk->time = $this->player->getWorld()->getTime(); $pk->eduMode = false; $pk->rainLevel = 0; //TODO: implement these properly $pk->lightningLevel = 0; @@ -83,7 +83,7 @@ class PreSpawnSessionHandler extends SessionHandler{ $this->player->setImmobile(); //HACK: fix client-side falling pre-spawn - $this->player->getLevel()->sendTime($this->player); + $this->player->getWorld()->sendTime($this->player); $this->session->syncAttributes($this->player, true); $this->session->syncAvailableCommands(); diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index 23bd64215a..380ee768f2 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -281,7 +281,7 @@ class SimpleSessionHandler extends SessionHandler{ } private function handleUseItemOnEntityTransaction(UseItemOnEntityTransactionData $data) : bool{ - $target = $this->player->getLevel()->getEntity($data->getEntityRuntimeId()); + $target = $this->player->getWorld()->getEntity($data->getEntityRuntimeId()); if($target === null){ return false; } @@ -448,7 +448,7 @@ class SimpleSessionHandler extends SessionHandler{ return false; } - $block = $this->player->getLevel()->getBlock($pos); + $block = $this->player->getWorld()->getBlock($pos); try{ $offset = 0; $nbt = (new NetworkNbtSerializer())->read($packet->namedtag, $offset, 512)->getTag(); @@ -466,7 +466,7 @@ class SimpleSessionHandler extends SessionHandler{ try{ if(!$block->updateText($this->player, $text)){ - $this->player->getLevel()->sendBlocks([$this->player], [$block]); + $this->player->getWorld()->sendBlocks([$this->player], [$block]); } }catch(\UnexpectedValueException $e){ throw new BadPacketException($e->getMessage(), 0, $e); @@ -509,7 +509,7 @@ class SimpleSessionHandler extends SessionHandler{ } public function handleItemFrameDropItem(ItemFrameDropItemPacket $packet) : bool{ - $block = $this->player->getLevel()->getBlockAt($packet->x, $packet->y, $packet->z); + $block = $this->player->getWorld()->getBlockAt($packet->x, $packet->y, $packet->z); if($block instanceof ItemFrame and $block->getFramedItem() !== null){ return $this->player->attackBlock(new Vector3($packet->x, $packet->y, $packet->z), $block->getFacing()); } @@ -588,7 +588,7 @@ class SimpleSessionHandler extends SessionHandler{ } public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{ - $this->player->getLevel()->broadcastPacketToViewers($this->player->asVector3(), $packet); + $this->player->getWorld()->broadcastPacketToViewers($this->player->asVector3(), $packet); return true; } diff --git a/src/pocketmine/scheduler/AsyncTask.php b/src/pocketmine/scheduler/AsyncTask.php index 08639ad58a..a6add8740c 100644 --- a/src/pocketmine/scheduler/AsyncTask.php +++ b/src/pocketmine/scheduler/AsyncTask.php @@ -210,7 +210,7 @@ abstract class AsyncTask extends \Threaded{ * leak. Usually this does not cause memory failure, but be aware that the object may be no longer usable when the * AsyncTask completes. Since a strong reference is retained, the objects still exist, but the implementation is * responsible for checking whether these objects are still usable. - * (E.g. a {@link \pocketmine\Level} object is no longer usable because it is unloaded while the AsyncTask is + * (E.g. a {@link \pocketmine\World} object is no longer usable because it is unloaded while the AsyncTask is * executing, or even a plugin might be unloaded). * * @param string $key diff --git a/src/pocketmine/tile/Banner.php b/src/pocketmine/tile/Banner.php index 6da72e874c..0b8997f3d9 100644 --- a/src/pocketmine/tile/Banner.php +++ b/src/pocketmine/tile/Banner.php @@ -26,11 +26,11 @@ namespace pocketmine\tile; use Ds\Deque; use pocketmine\block\utils\BannerPattern; use pocketmine\block\utils\DyeColor; -use pocketmine\level\Level; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; +use pocketmine\world\World; /** * @deprecated @@ -49,10 +49,10 @@ class Banner extends Spawnable{ /** @var BannerPattern[]|Deque */ private $patterns = []; - public function __construct(Level $level, Vector3 $pos){ + public function __construct(World $world, Vector3 $pos){ $this->baseColor = DyeColor::BLACK(); $this->patterns = new Deque(); - parent::__construct($level, $pos); + parent::__construct($world, $pos); } public function readSaveData(CompoundTag $nbt) : void{ diff --git a/src/pocketmine/tile/Bed.php b/src/pocketmine/tile/Bed.php index 442eb31b81..bc8f9b444b 100644 --- a/src/pocketmine/tile/Bed.php +++ b/src/pocketmine/tile/Bed.php @@ -24,19 +24,19 @@ declare(strict_types=1); namespace pocketmine\tile; use pocketmine\block\utils\DyeColor; -use pocketmine\level\Level; use pocketmine\math\Vector3; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\world\World; class Bed extends Spawnable{ public const TAG_COLOR = "color"; /** @var DyeColor */ private $color; - public function __construct(Level $level, Vector3 $pos){ + public function __construct(World $world, Vector3 $pos){ $this->color = DyeColor::RED(); - parent::__construct($level, $pos); + parent::__construct($world, $pos); } public function getColor() : DyeColor{ diff --git a/src/pocketmine/tile/Chest.php b/src/pocketmine/tile/Chest.php index 7b2ffb25f2..b59fd3b5f0 100644 --- a/src/pocketmine/tile/Chest.php +++ b/src/pocketmine/tile/Chest.php @@ -26,10 +26,10 @@ namespace pocketmine\tile; use pocketmine\inventory\ChestInventory; use pocketmine\inventory\DoubleChestInventory; use pocketmine\inventory\InventoryHolder; -use pocketmine\level\Level; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; +use pocketmine\world\World; class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ use NameableTrait { @@ -53,9 +53,9 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ /** @var int|null */ private $pairZ; - public function __construct(Level $level, Vector3 $pos){ + public function __construct(World $world, Vector3 $pos){ $this->inventory = new ChestInventory($this); - parent::__construct($level, $pos); + parent::__construct($world, $pos); } public function readSaveData(CompoundTag $nbt) : void{ @@ -90,7 +90,7 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ $this->inventory->removeAllViewers(true); if($this->doubleInventory !== null){ - if($this->isPaired() and $this->level->isChunkLoaded($this->pairX >> 4, $this->pairZ >> 4)){ + if($this->isPaired() and $this->world->isChunkLoaded($this->pairX >> 4, $this->pairZ >> 4)){ $this->doubleInventory->removeAllViewers(true); $this->doubleInventory->invalidate(); if(($pair = $this->getPair()) !== null){ @@ -129,7 +129,7 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ } protected function checkPairing(){ - if($this->isPaired() and !$this->getLevel()->isInLoadedTerrain(new Vector3($this->pairX, $this->y, $this->pairZ))){ + if($this->isPaired() and !$this->getWorld()->isInLoadedTerrain(new Vector3($this->pairX, $this->y, $this->pairZ))){ //paired to a tile in an unloaded chunk $this->doubleInventory = null; @@ -171,7 +171,7 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ */ public function getPair() : ?Chest{ if($this->isPaired()){ - $tile = $this->getLevel()->getTileAt($this->pairX, $this->y, $this->pairZ); + $tile = $this->getWorld()->getTileAt($this->pairX, $this->y, $this->pairZ); if($tile instanceof Chest){ return $tile; } diff --git a/src/pocketmine/tile/ContainerTrait.php b/src/pocketmine/tile/ContainerTrait.php index efacc7bd22..1ef2737d1a 100644 --- a/src/pocketmine/tile/ContainerTrait.php +++ b/src/pocketmine/tile/ContainerTrait.php @@ -25,11 +25,11 @@ namespace pocketmine\tile; use pocketmine\inventory\Inventory; use pocketmine\item\Item; -use pocketmine\level\Position; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; +use pocketmine\world\Position; /** * This trait implements most methods in the {@link Container} interface. It should only be used by Tiles. @@ -101,7 +101,7 @@ trait ContainerTrait{ $pos = $this->asPosition(); foreach($inv->getContents() as $k => $item){ - $pos->level->dropItem($pos->add(0.5, 0.5, 0.5), $item); + $pos->world->dropItem($pos->add(0.5, 0.5, 0.5), $item); } $inv->clearAll(false); } diff --git a/src/pocketmine/tile/Furnace.php b/src/pocketmine/tile/Furnace.php index 29dbc53c59..ebf281c80d 100644 --- a/src/pocketmine/tile/Furnace.php +++ b/src/pocketmine/tile/Furnace.php @@ -32,10 +32,10 @@ use pocketmine\inventory\Inventory; use pocketmine\inventory\InventoryHolder; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\level\Level; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\ContainerSetDataPacket; +use pocketmine\world\World; use function ceil; use function max; @@ -58,14 +58,14 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ /** @var int */ private $maxTime = 0; - public function __construct(Level $level, Vector3 $pos){ + public function __construct(World $world, Vector3 $pos){ $this->inventory = new FurnaceInventory($this); $this->inventory->setSlotChangeListener(function(Inventory $inventory, int $slot, Item $oldItem, Item $newItem) : ?Item{ $this->scheduleUpdate(); return $newItem; }); - parent::__construct($level, $pos); + parent::__construct($world, $pos); } public function readSaveData(CompoundTag $nbt) : void{ @@ -135,7 +135,7 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ $block = $this->getBlock(); if($block instanceof BlockFurnace and !$block->isLit()){ $block->setLit(true); - $this->getLevel()->setBlock($block, $block); + $this->getWorld()->setBlock($block, $block); } if($this->burnTime > 0 and $ev->isBurning()){ @@ -163,7 +163,7 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ $fuel = $this->inventory->getFuel(); $raw = $this->inventory->getSmelting(); $product = $this->inventory->getResult(); - $smelt = $this->level->getServer()->getCraftingManager()->matchFurnaceRecipe($raw); + $smelt = $this->world->getServer()->getCraftingManager()->matchFurnaceRecipe($raw); $canSmelt = ($smelt instanceof FurnaceRecipe and $raw->getCount() > 0 and (($smelt->getResult()->equals($product) and $product->getCount() < $product->getMaxStackSize()) or $product->isNull())); if($this->burnTime <= 0 and $canSmelt and $fuel->getFuelTime() > 0 and $fuel->getCount() > 0){ @@ -200,7 +200,7 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ $block = $this->getBlock(); if($block instanceof BlockFurnace and $block->isLit()){ $block->setLit(false); - $this->getLevel()->setBlock($block, $block); + $this->getWorld()->setBlock($block, $block); } $this->burnTime = $this->cookTime = $this->maxTime = 0; } diff --git a/src/pocketmine/tile/ItemFrame.php b/src/pocketmine/tile/ItemFrame.php index 0841f540cc..dd54ef6d6c 100644 --- a/src/pocketmine/tile/ItemFrame.php +++ b/src/pocketmine/tile/ItemFrame.php @@ -25,9 +25,9 @@ namespace pocketmine\tile; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\level\Level; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\world\World; /** * @deprecated @@ -45,9 +45,9 @@ class ItemFrame extends Spawnable{ /** @var float */ private $itemDropChance = 1.0; - public function __construct(Level $level, Vector3 $pos){ + public function __construct(World $world, Vector3 $pos){ $this->item = ItemFactory::air(); - parent::__construct($level, $pos); + parent::__construct($world, $pos); } public function readSaveData(CompoundTag $nbt) : void{ diff --git a/src/pocketmine/tile/Sign.php b/src/pocketmine/tile/Sign.php index b0ac37e375..09ff5d44f6 100644 --- a/src/pocketmine/tile/Sign.php +++ b/src/pocketmine/tile/Sign.php @@ -24,10 +24,10 @@ declare(strict_types=1); namespace pocketmine\tile; use pocketmine\block\utils\SignText; -use pocketmine\level\Level; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\StringTag; +use pocketmine\world\World; use function array_pad; use function array_slice; use function explode; @@ -50,9 +50,9 @@ class Sign extends Spawnable{ /** @var SignText */ protected $text; - public function __construct(Level $level, Vector3 $pos){ + public function __construct(World $world, Vector3 $pos){ $this->text = new SignText(); - parent::__construct($level, $pos); + parent::__construct($world, $pos); } public function readSaveData(CompoundTag $nbt) : void{ diff --git a/src/pocketmine/tile/Skull.php b/src/pocketmine/tile/Skull.php index 6567a1b028..10b330d8d6 100644 --- a/src/pocketmine/tile/Skull.php +++ b/src/pocketmine/tile/Skull.php @@ -24,10 +24,10 @@ declare(strict_types=1); namespace pocketmine\tile; use pocketmine\block\utils\SkullType; -use pocketmine\level\Level; use pocketmine\math\Vector3; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\world\World; /** * @deprecated @@ -45,9 +45,9 @@ class Skull extends Spawnable{ /** @var int */ private $skullRotation = 0; - public function __construct(Level $level, Vector3 $pos){ + public function __construct(World $world, Vector3 $pos){ $this->skullType = SkullType::SKELETON(); - parent::__construct($level, $pos); + parent::__construct($world, $pos); } public function readSaveData(CompoundTag $nbt) : void{ diff --git a/src/pocketmine/tile/Spawnable.php b/src/pocketmine/tile/Spawnable.php index 0eaac54613..6bb21cddbf 100644 --- a/src/pocketmine/tile/Spawnable.php +++ b/src/pocketmine/tile/Spawnable.php @@ -32,7 +32,7 @@ abstract class Spawnable extends Tile{ /** @var string|null */ private $spawnCompoundCache = null; /** @var bool */ - private $dirty = true; //default dirty, until it's been spawned appropriately on the level + private $dirty = true; //default dirty, until it's been spawned appropriately on the world /** @var NetworkNbtSerializer|null */ private static $nbtWriter = null; diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/tile/Tile.php index c0caea1512..ee041cc63b 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/tile/Tile.php @@ -29,12 +29,12 @@ namespace pocketmine\tile; use pocketmine\block\Block; use pocketmine\item\Item; -use pocketmine\level\Level; -use pocketmine\level\Position; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; +use pocketmine\world\Position; +use pocketmine\world\World; use function get_class; abstract class Tile extends Position{ @@ -51,9 +51,9 @@ abstract class Tile extends Position{ /** @var TimingsHandler */ protected $timings; - public function __construct(Level $level, Vector3 $pos){ + public function __construct(World $world, Vector3 $pos){ $this->timings = Timings::getTileEntityTimings($this); - parent::__construct($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ(), $level); + parent::__construct($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ(), $world); } /** @@ -104,7 +104,7 @@ abstract class Tile extends Position{ * @return Block */ public function getBlock() : Block{ - return $this->level->getBlockAt($this->x, $this->y, $this->z); + return $this->world->getBlockAt($this->x, $this->y, $this->z); } /** @@ -118,7 +118,7 @@ abstract class Tile extends Position{ if($this->closed){ throw new \InvalidStateException("Cannot schedule update on garbage tile " . get_class($this)); } - $this->level->updateTiles[Level::blockHash($this->x, $this->y, $this->z)] = $this; + $this->world->updateTiles[World::blockHash($this->x, $this->y, $this->z)] = $this; } public function isClosed() : bool{ @@ -149,8 +149,8 @@ abstract class Tile extends Position{ $this->closed = true; if($this->isValid()){ - $this->level->removeTile($this); - $this->setLevel(null); + $this->world->removeTile($this); + $this->setWorld(null); } } } diff --git a/src/pocketmine/tile/TileFactory.php b/src/pocketmine/tile/TileFactory.php index c329d47260..35bab3e899 100644 --- a/src/pocketmine/tile/TileFactory.php +++ b/src/pocketmine/tile/TileFactory.php @@ -23,10 +23,10 @@ declare(strict_types=1); namespace pocketmine\tile; -use pocketmine\level\Level; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\utils\Utils; +use pocketmine\world\World; use function assert; use function in_array; use function is_a; @@ -97,13 +97,13 @@ final class TileFactory{ /** * @param string $baseClass - * @param Level $level + * @param World $world * @param Vector3 $pos * * @return Tile (will be an instanceof $baseClass) * @throws \InvalidArgumentException if the specified class is not a registered tile */ - public static function create(string $baseClass, Level $level, Vector3 $pos) : Tile{ + public static function create(string $baseClass, World $world, Vector3 $pos) : Tile{ if(isset(self::$classMapping[$baseClass])){ $class = self::$classMapping[$baseClass]; assert(is_a($class, $baseClass, true)); @@ -111,7 +111,7 @@ final class TileFactory{ * @var Tile $tile * @see Tile::__construct() */ - $tile = new $class($level, $pos); + $tile = new $class($world, $pos); return $tile; } @@ -120,14 +120,14 @@ final class TileFactory{ } /** - * @internal - * - * @param Level $level + * @param World $world * @param CompoundTag $nbt * * @return Tile|null + *@internal + * */ - public static function createFromData(Level $level, CompoundTag $nbt) : ?Tile{ + public static function createFromData(World $world, CompoundTag $nbt) : ?Tile{ $type = $nbt->getString(Tile::TAG_ID, "", true); if(!isset(self::$knownTiles[$type])){ return null; @@ -138,7 +138,7 @@ final class TileFactory{ * @var Tile $tile * @see Tile::__construct() */ - $tile = new $class($level, new Vector3($nbt->getInt(Tile::TAG_X), $nbt->getInt(Tile::TAG_Y), $nbt->getInt(Tile::TAG_Z))); + $tile = new $class($world, new Vector3($nbt->getInt(Tile::TAG_X), $nbt->getInt(Tile::TAG_Y), $nbt->getInt(Tile::TAG_Z))); $tile->readSaveData($nbt); return $tile; diff --git a/src/pocketmine/timings/TimingsHandler.php b/src/pocketmine/timings/TimingsHandler.php index bb89d07e2a..11db46a3a8 100644 --- a/src/pocketmine/timings/TimingsHandler.php +++ b/src/pocketmine/timings/TimingsHandler.php @@ -64,9 +64,9 @@ class TimingsHandler{ $entities = 0; $livingEntities = 0; - foreach(Server::getInstance()->getLevelManager()->getLevels() as $level){ - $entities += count($level->getEntities()); - foreach($level->getEntities() as $e){ + foreach(Server::getInstance()->getWorldManager()->getWorlds() as $world){ + $entities += count($world->getEntities()); + foreach($world->getEntities() as $e){ if($e instanceof Living){ ++$livingEntities; } diff --git a/src/pocketmine/utils/EnumTrait.php b/src/pocketmine/utils/EnumTrait.php index 9843c4b141..518a84d618 100644 --- a/src/pocketmine/utils/EnumTrait.php +++ b/src/pocketmine/utils/EnumTrait.php @@ -174,4 +174,15 @@ public static function %1$s() : self{ public function getEnumName() : string{ return $this->enumName; } + + /** + * Returns whether the two objects are equivalent. + * + * @param self $other + * + * @return bool + */ + public function equals(self $other) : bool{ + return $this->enumName === $other->enumName; + } } diff --git a/src/pocketmine/level/BlockTransaction.php b/src/pocketmine/world/BlockTransaction.php similarity index 99% rename from src/pocketmine/level/BlockTransaction.php rename to src/pocketmine/world/BlockTransaction.php index d3aa55fc99..6232f44785 100644 --- a/src/pocketmine/level/BlockTransaction.php +++ b/src/pocketmine/world/BlockTransaction.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level; +namespace pocketmine\world; use pocketmine\block\Block; use pocketmine\math\Vector3; diff --git a/src/pocketmine/level/ChunkListener.php b/src/pocketmine/world/ChunkListener.php similarity index 93% rename from src/pocketmine/level/ChunkListener.php rename to src/pocketmine/world/ChunkListener.php index 74e80944ab..3685d6dfa9 100644 --- a/src/pocketmine/level/ChunkListener.php +++ b/src/pocketmine/world/ChunkListener.php @@ -21,18 +21,18 @@ declare(strict_types=1); -namespace pocketmine\level; +namespace pocketmine\world; use pocketmine\block\Block; -use pocketmine\level\format\Chunk; use pocketmine\math\Vector3; +use pocketmine\world\format\Chunk; /** * This interface allows you to listen for events occurring on or in specific chunks. This will receive events for any * chunks which it is registered to listen to. * - * @see Level::registerChunkListener() - * @see Level::unregisterChunkListener() + * @see World::registerChunkListener() + * @see World::unregisterChunkListener() * * WARNING: When you're done with the listener, make sure you unregister it from all chunks it's listening to, otherwise * the object will not be destroyed. diff --git a/src/pocketmine/level/ChunkLoader.php b/src/pocketmine/world/ChunkLoader.php similarity index 87% rename from src/pocketmine/level/ChunkLoader.php rename to src/pocketmine/world/ChunkLoader.php index 7529cb5488..e68f88b561 100644 --- a/src/pocketmine/level/ChunkLoader.php +++ b/src/pocketmine/world/ChunkLoader.php @@ -21,13 +21,13 @@ declare(strict_types=1); -namespace pocketmine\level; +namespace pocketmine\world; /** - * If you want to keep chunks loaded, implement this interface and register it into Level. This will also tick chunks. + * If you want to keep chunks loaded, implement this interface and register it into World. This will also tick chunks. * - * @see Level::registerChunkLoader() - * @see Level::unregisterChunkLoader() + * @see World::registerChunkLoader() + * @see World::unregisterChunkLoader() * * WARNING: When moving this object around in the world or destroying it, * be sure to unregister the loader from chunks you're not using, otherwise you'll leak memory. diff --git a/src/pocketmine/level/ChunkManager.php b/src/pocketmine/world/ChunkManager.php similarity index 97% rename from src/pocketmine/level/ChunkManager.php rename to src/pocketmine/world/ChunkManager.php index c814531048..b0153b3d21 100644 --- a/src/pocketmine/level/ChunkManager.php +++ b/src/pocketmine/world/ChunkManager.php @@ -21,10 +21,10 @@ declare(strict_types=1); -namespace pocketmine\level; +namespace pocketmine\world; use pocketmine\block\Block; -use pocketmine\level\format\Chunk; +use pocketmine\world\format\Chunk; interface ChunkManager{ diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/world/Explosion.php similarity index 86% rename from src/pocketmine/level/Explosion.php rename to src/pocketmine/world/Explosion.php index 14272a7a75..ee0b86c9ed 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/world/Explosion.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level; +namespace pocketmine\world; use pocketmine\block\Block; use pocketmine\block\BlockFactory; @@ -34,13 +34,13 @@ use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityExplodeEvent; use pocketmine\item\ItemFactory; -use pocketmine\level\particle\HugeExplodeSeedParticle; -use pocketmine\level\sound\ExplodeSound; -use pocketmine\level\utils\SubChunkIteratorManager; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\ExplodePacket; +use pocketmine\world\particle\HugeExplodeSeedParticle; +use pocketmine\world\sound\ExplodeSound; +use pocketmine\world\utils\SubChunkIteratorManager; use function ceil; use function floor; use function mt_rand; @@ -48,8 +48,8 @@ use function mt_rand; class Explosion{ /** @var int */ private $rays = 16; - /** @var Level */ - public $level; + /** @var World */ + public $world; /** @var Position */ public $source; /** @var float */ @@ -75,7 +75,7 @@ class Explosion{ throw new \InvalidArgumentException("Position does not have a valid world"); } $this->source = $center; - $this->level = $center->getLevel(); + $this->world = $center->getWorld(); if($size <= 0){ throw new \InvalidArgumentException("Explosion radius must be greater than 0, got $size"); @@ -83,7 +83,7 @@ class Explosion{ $this->size = $size; $this->what = $what; - $this->subChunkHandler = new SubChunkIteratorManager($this->level, false); + $this->subChunkHandler = new SubChunkIteratorManager($this->world, false); } /** @@ -95,7 +95,7 @@ class Explosion{ } $vector = new Vector3(0, 0, 0); - $vBlock = new Position(0, 0, 0, $this->level); + $vBlock = new Position(0, 0, 0, $this->world); $currentChunk = null; $currentSubChunk = null; @@ -128,7 +128,7 @@ class Explosion{ if($state !== 0){ $blastForce -= (BlockFactory::$blastResistance[$state] / 5 + 0.3) * $this->stepLen; if($blastForce > 0){ - if(!isset($this->affectedBlocks[$index = Level::blockHash($vBlock->x, $vBlock->y, $vBlock->z)])){ + if(!isset($this->affectedBlocks[$index = World::blockHash($vBlock->x, $vBlock->y, $vBlock->z)])){ $this->affectedBlocks[$index] = BlockFactory::get($state >> 4, $state & 0xf, $vBlock); } } @@ -174,7 +174,7 @@ class Explosion{ $explosionBB = new AxisAlignedBB($minX, $minY, $minZ, $maxX, $maxY, $maxZ); - $list = $this->level->getNearbyEntities($explosionBB, $this->what instanceof Entity ? $this->what : null); + $list = $this->world->getNearbyEntities($explosionBB, $this->what instanceof Entity ? $this->what : null); foreach($list as $entity){ $distance = $entity->distance($this->source) / $explosionSize; @@ -208,28 +208,28 @@ class Explosion{ }else{ if(mt_rand(0, 100) < $yield){ foreach($block->getDrops($air) as $drop){ - $this->level->dropItem($block->add(0.5, 0.5, 0.5), $drop); + $this->world->dropItem($block->add(0.5, 0.5, 0.5), $drop); } } - if(($t = $this->level->getTileAt($block->x, $block->y, $block->z)) !== null){ + if(($t = $this->world->getTileAt($block->x, $block->y, $block->z)) !== null){ $t->onBlockDestroyed(); //needed to create drops for inventories } - $this->level->setBlockAt($block->x, $block->y, $block->z, $airBlock, false); //TODO: should updating really be disabled here? - $this->level->updateAllLight($block); + $this->world->setBlockAt($block->x, $block->y, $block->z, $airBlock, false); //TODO: should updating really be disabled here? + $this->world->updateAllLight($block); } $pos = new Vector3($block->x, $block->y, $block->z); foreach(Facing::ALL as $side){ $sideBlock = $pos->getSide($side); - if(!$this->level->isInWorld($sideBlock->x, $sideBlock->y, $sideBlock->z)){ + if(!$this->world->isInWorld($sideBlock->x, $sideBlock->y, $sideBlock->z)){ continue; } - if(!isset($this->affectedBlocks[$index = Level::blockHash($sideBlock->x, $sideBlock->y, $sideBlock->z)]) and !isset($updateBlocks[$index])){ - $ev = new BlockUpdateEvent($this->level->getBlockAt($sideBlock->x, $sideBlock->y, $sideBlock->z)); + if(!isset($this->affectedBlocks[$index = World::blockHash($sideBlock->x, $sideBlock->y, $sideBlock->z)]) and !isset($updateBlocks[$index])){ + $ev = new BlockUpdateEvent($this->world->getBlockAt($sideBlock->x, $sideBlock->y, $sideBlock->z)); $ev->call(); if(!$ev->isCancelled()){ - foreach($this->level->getNearbyEntities(AxisAlignedBB::one()->offset($sideBlock->x, $sideBlock->y, $sideBlock->z)->expand(1, 1, 1)) as $entity){ + foreach($this->world->getNearbyEntities(AxisAlignedBB::one()->offset($sideBlock->x, $sideBlock->y, $sideBlock->z)->expand(1, 1, 1)) as $entity){ $entity->onNearbyBlockChange(); } $ev->getBlock()->onNearbyBlockChange(); @@ -244,10 +244,10 @@ class Explosion{ $pk->position = $this->source->asVector3(); $pk->radius = $this->size; $pk->records = $send; - $this->level->broadcastPacketToViewers($source, $pk); + $this->world->broadcastPacketToViewers($source, $pk); - $this->level->addParticle($source, new HugeExplodeSeedParticle()); - $this->level->addSound($source, new ExplodeSound()); + $this->world->addParticle($source, new HugeExplodeSeedParticle()); + $this->world->addSound($source, new ExplodeSound()); return true; } diff --git a/src/pocketmine/level/Location.php b/src/pocketmine/world/Location.php similarity index 80% rename from src/pocketmine/level/Location.php rename to src/pocketmine/world/Location.php index 9b11d01d75..96349af866 100644 --- a/src/pocketmine/level/Location.php +++ b/src/pocketmine/world/Location.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level; +namespace pocketmine\world; use pocketmine\math\Vector3; @@ -38,24 +38,24 @@ class Location extends Position{ * @param int $z * @param float $yaw * @param float $pitch - * @param Level $level + * @param World $world */ - public function __construct($x = 0, $y = 0, $z = 0, float $yaw = 0.0, float $pitch = 0.0, ?Level $level = null){ + public function __construct($x = 0, $y = 0, $z = 0, float $yaw = 0.0, float $pitch = 0.0, ?World $world = null){ $this->yaw = $yaw; $this->pitch = $pitch; - parent::__construct($x, $y, $z, $level); + parent::__construct($x, $y, $z, $world); } /** * @param Vector3 $pos - * @param Level|null $level default null + * @param World|null $world default null * @param float $yaw default 0.0 * @param float $pitch default 0.0 * * @return Location */ - public static function fromObject(Vector3 $pos, ?Level $level = null, float $yaw = 0.0, float $pitch = 0.0){ - return new Location($pos->x, $pos->y, $pos->z, $yaw, $pitch, $level ?? (($pos instanceof Position) ? $pos->level : null)); + public static function fromObject(Vector3 $pos, ?World $world = null, float $yaw = 0.0, float $pitch = 0.0){ + return new Location($pos->x, $pos->y, $pos->z, $yaw, $pitch, $world ?? (($pos instanceof Position) ? $pos->world : null)); } /** @@ -64,7 +64,7 @@ class Location extends Position{ * @return Location */ public function asLocation() : Location{ - return new Location($this->x, $this->y, $this->z, $this->yaw, $this->pitch, $this->level); + return new Location($this->x, $this->y, $this->z, $this->yaw, $this->pitch, $this->world); } public function getYaw() : float{ @@ -76,7 +76,7 @@ class Location extends Position{ } public function __toString(){ - return "Location (level=" . ($this->isValid() ? $this->getLevel()->getDisplayName() : "null") . ", x=$this->x, y=$this->y, z=$this->z, yaw=$this->yaw, pitch=$this->pitch)"; + return "Location (world=" . ($this->isValid() ? $this->getWorld()->getDisplayName() : "null") . ", x=$this->x, y=$this->y, z=$this->z, yaw=$this->yaw, pitch=$this->pitch)"; } public function equals(Vector3 $v) : bool{ diff --git a/src/pocketmine/level/Position.php b/src/pocketmine/world/Position.php similarity index 61% rename from src/pocketmine/level/Position.php rename to src/pocketmine/world/Position.php index a6bb3ef67a..58c8fbcf24 100644 --- a/src/pocketmine/level/Position.php +++ b/src/pocketmine/world/Position.php @@ -21,29 +21,29 @@ declare(strict_types=1); -namespace pocketmine\level; +namespace pocketmine\world; use pocketmine\math\Vector3; use function assert; class Position extends Vector3{ - /** @var Level */ - public $level = null; + /** @var World */ + public $world = null; /** * @param int $x * @param int $y * @param int $z - * @param Level $level + * @param World $world */ - public function __construct($x = 0, $y = 0, $z = 0, ?Level $level = null){ + public function __construct($x = 0, $y = 0, $z = 0, ?World $world = null){ parent::__construct($x, $y, $z); - $this->setLevel($level); + $this->setWorld($world); } - public static function fromObject(Vector3 $pos, ?Level $level = null){ - return new Position($pos->x, $pos->y, $pos->z, $level); + public static function fromObject(Vector3 $pos, ?World $world = null){ + return new Position($pos->x, $pos->y, $pos->z, $world); } /** @@ -52,55 +52,55 @@ class Position extends Vector3{ * @return Position */ public function asPosition() : Position{ - return new Position($this->x, $this->y, $this->z, $this->level); + return new Position($this->x, $this->y, $this->z, $this->world); } /** - * Returns the target Level, or null if the target is not valid. - * If a reference exists to a Level which is closed, the reference will be destroyed and null will be returned. + * Returns the target world, or null if the target is not valid. + * If a reference exists to a world which is closed, the reference will be destroyed and null will be returned. * - * @return Level|null + * @return World|null */ - public function getLevel(){ - if($this->level !== null and $this->level->isClosed()){ + public function getWorld(){ + if($this->world !== null and $this->world->isClosed()){ \GlobalLogger::get()->debug("Position was holding a reference to an unloaded world"); - $this->level = null; + $this->world = null; } - return $this->level; + return $this->world; } /** - * Sets the target Level of the position. + * Sets the target world of the position. * - * @param Level|null $level + * @param World|null $world * * @return $this * - * @throws \InvalidArgumentException if the specified Level has been closed + * @throws \InvalidArgumentException if the specified World has been closed */ - public function setLevel(?Level $level){ - if($level !== null and $level->isClosed()){ + public function setWorld(?World $world){ + if($world !== null and $world->isClosed()){ throw new \InvalidArgumentException("Specified world has been unloaded and cannot be used"); } - $this->level = $level; + $this->world = $world; return $this; } /** - * Checks if this object has a valid reference to a loaded Level + * Checks if this object has a valid reference to a loaded world * * @return bool */ public function isValid() : bool{ - if($this->level !== null and $this->level->isClosed()){ - $this->level = null; + if($this->world !== null and $this->world->isClosed()){ + $this->world = null; return false; } - return $this->level !== null; + return $this->world !== null; } /** @@ -114,16 +114,16 @@ class Position extends Vector3{ public function getSide(int $side, int $step = 1){ assert($this->isValid()); - return Position::fromObject(parent::getSide($side, $step), $this->level); + return Position::fromObject(parent::getSide($side, $step), $this->world); } public function __toString(){ - return "Position(level=" . ($this->isValid() ? $this->getLevel()->getDisplayName() : "null") . ",x=" . $this->x . ",y=" . $this->y . ",z=" . $this->z . ")"; + return "Position(world=" . ($this->isValid() ? $this->getWorld()->getDisplayName() : "null") . ",x=" . $this->x . ",y=" . $this->y . ",z=" . $this->z . ")"; } public function equals(Vector3 $v) : bool{ if($v instanceof Position){ - return parent::equals($v) and $v->getLevel() === $this->getLevel(); + return parent::equals($v) and $v->getWorld() === $this->getWorld(); } return parent::equals($v); } diff --git a/src/pocketmine/level/SimpleChunkManager.php b/src/pocketmine/world/SimpleChunkManager.php similarity index 90% rename from src/pocketmine/level/SimpleChunkManager.php rename to src/pocketmine/world/SimpleChunkManager.php index d8eb2397c6..d9297ebac8 100644 --- a/src/pocketmine/level/SimpleChunkManager.php +++ b/src/pocketmine/world/SimpleChunkManager.php @@ -21,12 +21,12 @@ declare(strict_types=1); -namespace pocketmine\level; +namespace pocketmine\world; use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; -use pocketmine\level\format\Chunk; +use pocketmine\world\format\Chunk; use const INT32_MAX; use const INT32_MIN; @@ -42,7 +42,7 @@ class SimpleChunkManager implements ChunkManager{ * * @param int $worldHeight */ - public function __construct(int $worldHeight = Level::Y_MAX){ + public function __construct(int $worldHeight = World::Y_MAX){ $this->worldHeight = $worldHeight; } @@ -96,7 +96,7 @@ class SimpleChunkManager implements ChunkManager{ * @return Chunk|null */ public function getChunk(int $chunkX, int $chunkZ) : ?Chunk{ - return $this->chunks[Level::chunkHash($chunkX, $chunkZ)] ?? null; + return $this->chunks[World::chunkHash($chunkX, $chunkZ)] ?? null; } /** @@ -106,10 +106,10 @@ class SimpleChunkManager implements ChunkManager{ */ public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk) : void{ if($chunk === null){ - unset($this->chunks[Level::chunkHash($chunkX, $chunkZ)]); + unset($this->chunks[World::chunkHash($chunkX, $chunkZ)]); return; } - $this->chunks[Level::chunkHash($chunkX, $chunkZ)] = $chunk; + $this->chunks[World::chunkHash($chunkX, $chunkZ)] = $chunk; } public function cleanChunks() : void{ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/world/World.php similarity index 92% rename from src/pocketmine/level/Level.php rename to src/pocketmine/world/World.php index 3964f017b7..a18d03da69 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/world/World.php @@ -22,9 +22,9 @@ declare(strict_types=1); /** - * All Level related classes are here, like Generators, Populators, Noise, ... + * All World related classes are here, like Generators, Populators, Noise, ... */ -namespace pocketmine\level; +namespace pocketmine\world; use pocketmine\block\Air; use pocketmine\block\Block; @@ -38,34 +38,15 @@ use pocketmine\entity\object\ItemEntity; use pocketmine\event\block\BlockBreakEvent; use pocketmine\event\block\BlockPlaceEvent; use pocketmine\event\block\BlockUpdateEvent; -use pocketmine\event\level\ChunkLoadEvent; -use pocketmine\event\level\ChunkPopulateEvent; -use pocketmine\event\level\ChunkUnloadEvent; -use pocketmine\event\level\LevelSaveEvent; -use pocketmine\event\level\SpawnChangeEvent; use pocketmine\event\player\PlayerInteractEvent; +use pocketmine\event\world\ChunkLoadEvent; +use pocketmine\event\world\ChunkPopulateEvent; +use pocketmine\event\world\ChunkUnloadEvent; +use pocketmine\event\world\SpawnChangeEvent; +use pocketmine\event\world\WorldSaveEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\ItemUseResult; -use pocketmine\level\biome\Biome; -use pocketmine\level\format\Chunk; -use pocketmine\level\format\ChunkException; -use pocketmine\level\format\EmptySubChunk; -use pocketmine\level\format\io\exception\CorruptedChunkException; -use pocketmine\level\format\io\exception\UnsupportedChunkFormatException; -use pocketmine\level\format\io\WritableLevelProvider; -use pocketmine\level\generator\Generator; -use pocketmine\level\generator\GeneratorManager; -use pocketmine\level\generator\GeneratorRegisterTask; -use pocketmine\level\generator\GeneratorUnregisterTask; -use pocketmine\level\generator\PopulationTask; -use pocketmine\level\light\BlockLightUpdate; -use pocketmine\level\light\LightPopulationTask; -use pocketmine\level\light\SkyLightUpdate; -use pocketmine\level\particle\DestroyBlockParticle; -use pocketmine\level\particle\Particle; -use pocketmine\level\sound\BlockPlaceSound; -use pocketmine\level\sound\Sound; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; use pocketmine\metadata\BlockMetadataStore; @@ -87,6 +68,25 @@ use pocketmine\tile\Spawnable; use pocketmine\tile\Tile; use pocketmine\timings\Timings; use pocketmine\utils\ReversePriorityQueue; +use pocketmine\world\biome\Biome; +use pocketmine\world\format\Chunk; +use pocketmine\world\format\ChunkException; +use pocketmine\world\format\EmptySubChunk; +use pocketmine\world\format\io\exception\CorruptedChunkException; +use pocketmine\world\format\io\exception\UnsupportedChunkFormatException; +use pocketmine\world\format\io\WritableWorldProvider; +use pocketmine\world\generator\Generator; +use pocketmine\world\generator\GeneratorManager; +use pocketmine\world\generator\GeneratorRegisterTask; +use pocketmine\world\generator\GeneratorUnregisterTask; +use pocketmine\world\generator\PopulationTask; +use pocketmine\world\light\BlockLightUpdate; +use pocketmine\world\light\LightPopulationTask; +use pocketmine\world\light\SkyLightUpdate; +use pocketmine\world\particle\DestroyBlockParticle; +use pocketmine\world\particle\Particle; +use pocketmine\world\sound\BlockPlaceSound; +use pocketmine\world\sound\Sound; use function abs; use function array_fill_keys; use function array_map; @@ -115,11 +115,11 @@ use const M_PI; use const PHP_INT_MAX; use const PHP_INT_MIN; -#include +#include -class Level implements ChunkManager, Metadatable{ +class World implements ChunkManager, Metadatable{ - private static $levelIdCounter = 1; + private static $worldIdCounter = 1; public const Y_MASK = 0xFF; public const Y_MAX = 0x100; //256 @@ -156,9 +156,9 @@ class Level implements ChunkManager, Metadatable{ private $server; /** @var int */ - private $levelId; + private $worldId; - /** @var WritableLevelProvider */ + /** @var WritableWorldProvider */ private $provider; /** @var int */ private $providerGarbageCollectionTicker = 0; @@ -250,7 +250,7 @@ class Level implements ChunkManager, Metadatable{ /** @var \SplFixedArray */ private $randomTickBlocks = null; - /** @var LevelTimings */ + /** @var WorldTimings */ public $timings; /** @var int */ @@ -275,10 +275,10 @@ class Level implements ChunkManager, Metadatable{ } public static function blockHash(int $x, int $y, int $z) : int{ - if($y < 0 or $y >= Level::Y_MAX){ + if($y < 0 or $y >= World::Y_MAX){ throw new \InvalidArgumentException("Y coordinate $y is out of range!"); } - return (($x & 0xFFFFFFF) << 36) | (($y & Level::Y_MASK) << 28) | ($z & 0xFFFFFFF); + return (($x & 0xFFFFFFF) << 36) | (($y & World::Y_MASK) << 28) | ($z & 0xFFFFFFF); } /** @@ -296,7 +296,7 @@ class Level implements ChunkManager, Metadatable{ public static function getBlockXYZ(int $hash, ?int &$x, ?int &$y, ?int &$z) : void{ $x = $hash >> 36; - $y = ($hash >> 28) & Level::Y_MASK; //it's always positive + $y = ($hash >> 28) & World::Y_MASK; //it's always positive $z = ($hash & 0xFFFFFFF) << 36 >> 36; } @@ -320,46 +320,46 @@ class Level implements ChunkManager, Metadatable{ case "0": case "peaceful": case "p": - return Level::DIFFICULTY_PEACEFUL; + return World::DIFFICULTY_PEACEFUL; case "1": case "easy": case "e": - return Level::DIFFICULTY_EASY; + return World::DIFFICULTY_EASY; case "2": case "normal": case "n": - return Level::DIFFICULTY_NORMAL; + return World::DIFFICULTY_NORMAL; case "3": case "hard": case "h": - return Level::DIFFICULTY_HARD; + return World::DIFFICULTY_HARD; } return -1; } /** - * Init the default level data + * Init the default world data * * @param Server $server * @param string $name - * @param WritableLevelProvider $provider + * @param WritableWorldProvider $provider */ - public function __construct(Server $server, string $name, WritableLevelProvider $provider){ - $this->levelId = static::$levelIdCounter++; + public function __construct(Server $server, string $name, WritableWorldProvider $provider){ + $this->worldId = static::$worldIdCounter++; $this->blockMetadata = new BlockMetadataStore($this); $this->server = $server; $this->provider = $provider; - $this->displayName = $this->provider->getLevelData()->getName(); + $this->displayName = $this->provider->getWorldData()->getName(); $this->worldHeight = $this->provider->getWorldHeight(); $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.level.preparing", [$this->displayName])); - $this->generator = GeneratorManager::getGenerator($this->provider->getLevelData()->getGenerator(), true); + $this->generator = GeneratorManager::getGenerator($this->provider->getWorldData()->getGenerator(), true); //TODO: validate generator options $this->folderName = $name; @@ -369,7 +369,7 @@ class Level implements ChunkManager, Metadatable{ $this->neighbourBlockUpdateQueue = new \SplQueue(); - $this->time = $this->provider->getLevelData()->getTime(); + $this->time = $this->provider->getWorldData()->getTime(); $this->chunkTickRadius = min($this->server->getViewDistance(), max(1, (int) $this->server->getProperty("chunk-ticking.tick-radius", 4))); $this->chunksPerTick = (int) $this->server->getProperty("chunk-ticking.per-tick", 40); @@ -391,7 +391,7 @@ class Level implements ChunkManager, Metadatable{ } } - $this->timings = new LevelTimings($this); + $this->timings = new WorldTimings($this); $this->temporalPosition = new Position(0, 0, 0, $this); $this->temporalVector = new Vector3(0, 0, 0); } @@ -402,7 +402,7 @@ class Level implements ChunkManager, Metadatable{ public function registerGeneratorToWorker(int $worker) : void{ $this->generatorRegisteredWorkers[$worker] = true; - $this->server->getAsyncPool()->submitTaskToWorker(new GeneratorRegisterTask($this, $this->generator, $this->provider->getLevelData()->getGeneratorOptions()), $worker); + $this->server->getAsyncPool()->submitTaskToWorker(new GeneratorRegisterTask($this, $this->generator, $this->provider->getWorldData()->getGeneratorOptions()), $worker); } public function unregisterGenerator(){ @@ -423,15 +423,15 @@ class Level implements ChunkManager, Metadatable{ return $this->server; } - final public function getProvider() : WritableLevelProvider{ + final public function getProvider() : WritableWorldProvider{ return $this->provider; } /** - * Returns the unique level identifier + * Returns the unique world identifier */ final public function getId() : int{ - return $this->levelId; + return $this->worldId; } public function isClosed() : bool{ @@ -498,7 +498,7 @@ class Level implements ChunkManager, Metadatable{ /** * Broadcasts a LevelEvent to players in the area. This could be sound, particles, weather changes, etc. * - * @param Vector3|null $pos If null, broadcasts to every player in the Level + * @param Vector3|null $pos If null, broadcasts to every player in the World * @param int $evid * @param int $data */ @@ -531,7 +531,7 @@ class Level implements ChunkManager, Metadatable{ * @return Player[] */ public function getChunkPlayers(int $chunkX, int $chunkZ) : array{ - return $this->playerLoaders[Level::chunkHash($chunkX, $chunkZ)] ?? []; + return $this->playerLoaders[World::chunkHash($chunkX, $chunkZ)] ?? []; } /** @@ -543,7 +543,7 @@ class Level implements ChunkManager, Metadatable{ * @return ChunkLoader[] */ public function getChunkLoaders(int $chunkX, int $chunkZ) : array{ - return $this->chunkLoaders[Level::chunkHash($chunkX, $chunkZ)] ?? []; + return $this->chunkLoaders[World::chunkHash($chunkX, $chunkZ)] ?? []; } /** @@ -565,7 +565,7 @@ class Level implements ChunkManager, Metadatable{ * @param ClientboundPacket $packet */ public function addChunkPacket(int $chunkX, int $chunkZ, ClientboundPacket $packet){ - if(!isset($this->chunkPackets[$index = Level::chunkHash($chunkX, $chunkZ)])){ + if(!isset($this->chunkPackets[$index = World::chunkHash($chunkX, $chunkZ)])){ $this->chunkPackets[$index] = [$packet]; }else{ $this->chunkPackets[$index][] = $packet; @@ -583,7 +583,7 @@ class Level implements ChunkManager, Metadatable{ } /** - * Broadcasts a packet to every player in the level. + * Broadcasts a packet to every player in the world. * * @param ClientboundPacket $packet */ @@ -594,7 +594,7 @@ class Level implements ChunkManager, Metadatable{ public function registerChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ, bool $autoLoad = true){ $loaderId = spl_object_id($loader); - if(!isset($this->chunkLoaders[$chunkHash = Level::chunkHash($chunkX, $chunkZ)])){ + if(!isset($this->chunkLoaders[$chunkHash = World::chunkHash($chunkX, $chunkZ)])){ $this->chunkLoaders[$chunkHash] = []; $this->playerLoaders[$chunkHash] = []; }elseif(isset($this->chunkLoaders[$chunkHash][$loaderId])){ @@ -621,7 +621,7 @@ class Level implements ChunkManager, Metadatable{ } public function unregisterChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ){ - $chunkHash = Level::chunkHash($chunkX, $chunkZ); + $chunkHash = World::chunkHash($chunkX, $chunkZ); $loaderId = spl_object_id($loader); if(isset($this->chunkLoaders[$chunkHash][$loaderId])){ unset($this->chunkLoaders[$chunkHash][$loaderId]); @@ -647,7 +647,7 @@ class Level implements ChunkManager, Metadatable{ * @param int $chunkZ */ public function registerChunkListener(ChunkListener $listener, int $chunkX, int $chunkZ) : void{ - $hash = Level::chunkHash($chunkX, $chunkZ); + $hash = World::chunkHash($chunkX, $chunkZ); if(isset($this->chunkListeners[$hash])){ $this->chunkListeners[$hash][spl_object_id($listener)] = $listener; }else{ @@ -657,14 +657,16 @@ class Level implements ChunkManager, Metadatable{ /** * Unregisters a chunk listener previously registered. - * @see Level::registerChunkListener() * * @param ChunkListener $listener * @param int $chunkX * @param int $chunkZ + * + *@see World::registerChunkListener() + * */ public function unregisterChunkListener(ChunkListener $listener, int $chunkX, int $chunkZ) : void{ - $hash = Level::chunkHash($chunkX, $chunkZ); + $hash = World::chunkHash($chunkX, $chunkZ); if(isset($this->chunkListeners[$hash])){ unset($this->chunkListeners[$hash][spl_object_id($listener)]); if(empty($this->chunkListeners[$hash])){ @@ -674,7 +676,7 @@ class Level implements ChunkManager, Metadatable{ } /** - * Unregisters a chunk listener from all chunks it is listening on in this Level. + * Unregisters a chunk listener from all chunks it is listening on in this World. * * @param ChunkListener $listener */ @@ -699,13 +701,13 @@ class Level implements ChunkManager, Metadatable{ * @return ChunkListener[] */ public function getChunkListeners(int $chunkX, int $chunkZ) : array{ - return $this->chunkListeners[Level::chunkHash($chunkX, $chunkZ)] ?? []; + return $this->chunkListeners[World::chunkHash($chunkX, $chunkZ)] ?? []; } /** * @internal * - * @param Player ...$targets If empty, will send to all players in the level. + * @param Player ...$targets If empty, will send to all players in the world. */ public function sendTime(Player ...$targets){ $pk = new SetTimePacket(); @@ -773,14 +775,14 @@ class Level implements ChunkManager, Metadatable{ //Delayed updates while($this->scheduledBlockUpdateQueue->count() > 0 and $this->scheduledBlockUpdateQueue->current()["priority"] <= $currentTick){ $block = $this->getBlock($this->scheduledBlockUpdateQueue->extract()["data"]); - unset($this->scheduledBlockUpdateQueueIndex[Level::blockHash($block->x, $block->y, $block->z)]); + unset($this->scheduledBlockUpdateQueueIndex[World::blockHash($block->x, $block->y, $block->z)]); $block->onScheduledUpdate(); } //Normal updates while($this->neighbourBlockUpdateQueue->count() > 0){ $index = $this->neighbourBlockUpdateQueue->dequeue(); - Level::getBlockXYZ($index, $x, $y, $z); + World::getBlockXYZ($index, $x, $y, $z); $block = $this->getBlockAt($x, $y, $z); $block->readStateFromWorld(); //for blocks like fences, force recalculation of connected AABBs @@ -820,7 +822,7 @@ class Level implements ChunkManager, Metadatable{ unset($this->updateTiles[$blockHash]); } if(!$tile->isClosed() and $tile instanceof Spawnable and $tile->isDirty()){ - $chunkHash = Level::chunkHash($tile->getFloorX() >> 4, $tile->getFloorZ() >> 4); + $chunkHash = World::chunkHash($tile->getFloorX() >> 4, $tile->getFloorZ() >> 4); if(!isset($this->changedBlocks[$chunkHash])){ $this->changedBlocks[$chunkHash] = [$blockHash => $tile]; }else{ @@ -844,7 +846,7 @@ class Level implements ChunkManager, Metadatable{ if(empty($blocks)){ //blocks can be set normally and then later re-set with direct send continue; } - Level::getXZ($index, $chunkX, $chunkZ); + World::getXZ($index, $chunkX, $chunkZ); if(count($blocks) > 512){ $chunk = $this->getChunk($chunkX, $chunkZ); foreach($this->getChunkPlayers($chunkX, $chunkZ) as $p){ @@ -877,7 +879,7 @@ class Level implements ChunkManager, Metadatable{ } foreach($this->chunkPackets as $index => $entries){ - Level::getXZ($index, $chunkX, $chunkZ); + World::getXZ($index, $chunkX, $chunkZ); $chunkPlayers = $this->getChunkPlayers($chunkX, $chunkZ); if(count($chunkPlayers) > 0){ $this->server->broadcastPackets($chunkPlayers, $entries); @@ -901,10 +903,10 @@ class Level implements ChunkManager, Metadatable{ } if($resetTime){ - $time = $this->getTime() % Level::TIME_FULL; + $time = $this->getTime() % World::TIME_FULL; - if($time >= Level::TIME_NIGHT and $time < Level::TIME_SUNRISE){ - $this->setTime($this->getTime() + Level::TIME_FULL - $time); + if($time >= World::TIME_NIGHT and $time < World::TIME_SUNRISE){ + $this->setTime($this->getTime() + World::TIME_FULL - $time); foreach($this->getPlayers() as $p){ $p->stopSleep(); @@ -1006,12 +1008,12 @@ class Level implements ChunkManager, Metadatable{ for($chunk = 0; $chunk < $chunksPerLoader; ++$chunk){ $dx = mt_rand(-$randRange, $randRange); $dz = mt_rand(-$randRange, $randRange); - $hash = Level::chunkHash($dx + $chunkX, $dz + $chunkZ); + $hash = World::chunkHash($dx + $chunkX, $dz + $chunkZ); if(!isset($chunkTickList[$hash]) and isset($this->chunks[$hash])){ //check adjacent chunks are loaded for($cx = -1; $cx <= 1; ++$cx){ for($cz = -1; $cz <= 1; ++$cz){ - if(!isset($this->chunks[Level::chunkHash($chunkX + $dx + $cx, $chunkZ + $dz + $cz)])){ + if(!isset($this->chunks[World::chunkHash($chunkX + $dx + $cx, $chunkZ + $dz + $cz)])){ continue 3; } } @@ -1022,7 +1024,7 @@ class Level implements ChunkManager, Metadatable{ } foreach($chunkTickList as $index => $_){ - Level::getXZ($index, $chunkX, $chunkZ); + World::getXZ($index, $chunkX, $chunkZ); $chunk = $this->chunks[$index]; foreach($chunk->getEntities() as $entity){ @@ -1071,11 +1073,11 @@ class Level implements ChunkManager, Metadatable{ return false; } - (new LevelSaveEvent($this))->call(); + (new WorldSaveEvent($this))->call(); - $this->provider->getLevelData()->setTime($this->time); + $this->provider->getWorldData()->setTime($this->time); $this->saveChunks(); - $this->provider->getLevelData()->save(); + $this->provider->getWorldData()->save(); return true; } @@ -1104,7 +1106,7 @@ class Level implements ChunkManager, Metadatable{ public function scheduleDelayedBlockUpdate(Vector3 $pos, int $delay){ if( !$this->isInWorld($pos->x, $pos->y, $pos->z) or - (isset($this->scheduledBlockUpdateQueueIndex[$index = Level::blockHash($pos->x, $pos->y, $pos->z)]) and $this->scheduledBlockUpdateQueueIndex[$index] <= $delay) + (isset($this->scheduledBlockUpdateQueueIndex[$index = World::blockHash($pos->x, $pos->y, $pos->z)]) and $this->scheduledBlockUpdateQueueIndex[$index] <= $delay) ){ return; } @@ -1114,7 +1116,7 @@ class Level implements ChunkManager, Metadatable{ private function tryAddToNeighbourUpdateQueue(Vector3 $pos) : void{ if($this->isInWorld($pos->x, $pos->y, $pos->z)){ - $hash = Level::blockHash($pos->x, $pos->y, $pos->z); + $hash = World::blockHash($pos->x, $pos->y, $pos->z); if(!isset($this->neighbourBlockUpdateQueueIndex[$hash])){ $this->neighbourBlockUpdateQueue->enqueue($hash); $this->neighbourBlockUpdateQueueIndex[$hash] = true; @@ -1368,10 +1370,10 @@ class Level implements ChunkManager, Metadatable{ public function getBlockAt(int $x, int $y, int $z, bool $cached = true, bool $addToCache = true) : Block{ $fullState = 0; $relativeBlockHash = null; - $chunkHash = Level::chunkHash($x >> 4, $z >> 4); + $chunkHash = World::chunkHash($x >> 4, $z >> 4); if($this->isInWorld($x, $y, $z)){ - $relativeBlockHash = Level::chunkBlockHash($x, $y, $z); + $relativeBlockHash = World::chunkBlockHash($x, $y, $z); if($cached and isset($this->blockCache[$chunkHash][$relativeBlockHash])){ return $this->blockCache[$chunkHash][$relativeBlockHash]; @@ -1525,7 +1527,6 @@ class Level implements ChunkManager, Metadatable{ /** * Sets the block at the given Vector3 coordinates. - * @see Level::setBlockAt() * * @param Vector3 $pos * @param Block $block @@ -1534,6 +1535,8 @@ class Level implements ChunkManager, Metadatable{ * @return bool Whether the block has been updated or not * * @throws \InvalidArgumentException if the position is out of the world bounds + *@see World::setBlockAt() + * */ public function setBlock(Vector3 $pos, Block $block, bool $update = true) : bool{ return $this->setBlockAt((int) floor($pos->x), (int) floor($pos->y), (int) floor($pos->z), $block, $update); @@ -1567,8 +1570,8 @@ class Level implements ChunkManager, Metadatable{ $block->position($this, $x, $y, $z); $block->writeStateToWorld(); - $chunkHash = Level::chunkHash($x >> 4, $z >> 4); - $relativeBlockHash = Level::chunkBlockHash($x, $y, $z); + $chunkHash = World::chunkHash($x >> 4, $z >> 4); + $relativeBlockHash = World::chunkBlockHash($x, $y, $z); unset($this->blockCache[$chunkHash][$relativeBlockHash]); @@ -1887,7 +1890,7 @@ class Level implements ChunkManager, Metadatable{ } /** - * Gets the list of all the entities in this level + * Gets the list of all the entities in this world * * @return Entity[] */ @@ -1998,7 +2001,7 @@ class Level implements ChunkManager, Metadatable{ } /** - * Returns a list of the players in this level + * Returns a list of the players in this world * * @return Player[] */ @@ -2180,7 +2183,7 @@ class Level implements ChunkManager, Metadatable{ * @return Chunk|null */ public function getChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk{ - if(isset($this->chunks[$index = Level::chunkHash($chunkX, $chunkZ)])){ + if(isset($this->chunks[$index = World::chunkHash($chunkX, $chunkZ)])){ return $this->chunks[$index]; }elseif($this->loadChunk($chunkX, $chunkZ, $create)){ return $this->chunks[$index]; @@ -2225,7 +2228,7 @@ class Level implements ChunkManager, Metadatable{ } public function lockChunk(int $chunkX, int $chunkZ) : void{ - $chunkHash = Level::chunkHash($chunkX, $chunkZ); + $chunkHash = World::chunkHash($chunkX, $chunkZ); if(isset($this->chunkLock[$chunkHash])){ throw new \InvalidArgumentException("Chunk $chunkX $chunkZ is already locked"); } @@ -2233,16 +2236,16 @@ class Level implements ChunkManager, Metadatable{ } public function unlockChunk(int $chunkX, int $chunkZ) : void{ - unset($this->chunkLock[Level::chunkHash($chunkX, $chunkZ)]); + unset($this->chunkLock[World::chunkHash($chunkX, $chunkZ)]); } public function isChunkLocked(int $chunkX, int $chunkZ) : bool{ - return isset($this->chunkLock[Level::chunkHash($chunkX, $chunkZ)]); + return isset($this->chunkLock[World::chunkHash($chunkX, $chunkZ)]); } public function generateChunkCallback(int $x, int $z, ?Chunk $chunk){ Timings::$generationCallbackTimer->startTiming(); - if(isset($this->chunkPopulationQueue[$index = Level::chunkHash($x, $z)])){ + if(isset($this->chunkPopulationQueue[$index = World::chunkHash($x, $z)])){ for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ $this->unlockChunk($x + $xx, $z + $zz); @@ -2286,7 +2289,7 @@ class Level implements ChunkManager, Metadatable{ $chunk->setX($chunkX); $chunk->setZ($chunkZ); - $chunkHash = Level::chunkHash($chunkX, $chunkZ); + $chunkHash = World::chunkHash($chunkX, $chunkZ); $oldChunk = $this->getChunk($chunkX, $chunkZ, false); if($oldChunk !== null and $oldChunk !== $chunk){ if($deleteEntitiesAndTiles){ @@ -2359,7 +2362,7 @@ class Level implements ChunkManager, Metadatable{ * @return bool */ public function isChunkLoaded(int $x, int $z) : bool{ - return isset($this->chunks[Level::chunkHash($x, $z)]); + return isset($this->chunks[World::chunkHash($x, $z)]); } /** @@ -2390,22 +2393,22 @@ class Level implements ChunkManager, Metadatable{ * @return Position */ public function getSpawnLocation() : Position{ - return Position::fromObject($this->provider->getLevelData()->getSpawn(), $this); + return Position::fromObject($this->provider->getWorldData()->getSpawn(), $this); } /** - * Sets the level spawn location + * Sets the world spawn location * * @param Vector3 $pos */ public function setSpawnLocation(Vector3 $pos){ $previousSpawn = $this->getSpawnLocation(); - $this->provider->getLevelData()->setSpawn($pos); + $this->provider->getWorldData()->setSpawn($pos); (new SpawnChangeEvent($this, $previousSpawn))->call(); } public function requestChunk(int $x, int $z, Player $player){ - $index = Level::chunkHash($x, $z); + $index = World::chunkHash($x, $z); if(!isset($this->chunkSendQueue[$index])){ $this->chunkSendQueue[$index] = []; } @@ -2414,7 +2417,7 @@ class Level implements ChunkManager, Metadatable{ } private function onChunkReady(int $x, int $z){ - if(isset($this->chunkSendQueue[$index = Level::chunkHash($x, $z)])){ + if(isset($this->chunkSendQueue[$index = World::chunkHash($x, $z)])){ foreach($this->chunkSendQueue[$index] as $player){ /** @var Player $player */ $player->onChunkReady($x, $z); @@ -2428,7 +2431,7 @@ class Level implements ChunkManager, Metadatable{ $this->timings->syncChunkSendTimer->startTiming(); foreach($this->chunkSendQueue as $index => $players){ - Level::getXZ($index, $x, $z); + World::getXZ($index, $x, $z); $this->timings->syncChunkSendPrepareTimer->startTiming(); @@ -2453,7 +2456,7 @@ class Level implements ChunkManager, Metadatable{ if($entity->isClosed()){ throw new \InvalidArgumentException("Attempted to add a garbage closed Entity to world"); } - if($entity->getLevel() !== $this){ + if($entity->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Entity world"); } @@ -2464,14 +2467,14 @@ class Level implements ChunkManager, Metadatable{ } /** - * Removes the entity from the level index + * Removes the entity from the world index * * @param Entity $entity * * @throws \InvalidArgumentException */ public function removeEntity(Entity $entity){ - if($entity->getLevel() !== $this){ + if($entity->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Entity world"); } @@ -2493,14 +2496,14 @@ class Level implements ChunkManager, Metadatable{ if($tile->isClosed()){ throw new \InvalidArgumentException("Attempted to add a garbage closed Tile to world"); } - if($tile->getLevel() !== $this){ + if($tile->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Tile world"); } $chunkX = $tile->getFloorX() >> 4; $chunkZ = $tile->getFloorZ() >> 4; - if(isset($this->chunks[$hash = Level::chunkHash($chunkX, $chunkZ)])){ + if(isset($this->chunks[$hash = World::chunkHash($chunkX, $chunkZ)])){ $this->chunks[$hash]->addTile($tile); }else{ throw new \InvalidStateException("Attempted to create tile " . get_class($tile) . " in unloaded chunk $chunkX $chunkZ"); @@ -2515,16 +2518,16 @@ class Level implements ChunkManager, Metadatable{ * @throws \InvalidArgumentException */ public function removeTile(Tile $tile){ - if($tile->getLevel() !== $this){ + if($tile->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Tile world"); } - unset($this->updateTiles[Level::blockHash($tile->x, $tile->y, $tile->z)]); + unset($this->updateTiles[World::blockHash($tile->x, $tile->y, $tile->z)]); $chunkX = $tile->getFloorX() >> 4; $chunkZ = $tile->getFloorZ() >> 4; - if(isset($this->chunks[$hash = Level::chunkHash($chunkX, $chunkZ)])){ + if(isset($this->chunks[$hash = World::chunkHash($chunkX, $chunkZ)])){ $this->chunks[$hash]->removeTile($tile); } foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){ @@ -2539,11 +2542,11 @@ class Level implements ChunkManager, Metadatable{ * @return bool */ public function isChunkInUse(int $x, int $z) : bool{ - return isset($this->chunkLoaders[$index = Level::chunkHash($x, $z)]) and count($this->chunkLoaders[$index]) > 0; + return isset($this->chunkLoaders[$index = World::chunkHash($x, $z)]) and count($this->chunkLoaders[$index]) > 0; } /** - * Attempts to load a chunk from the level provider (if not already loaded). + * Attempts to load a chunk from the world provider (if not already loaded). * * @param int $x * @param int $z @@ -2554,7 +2557,7 @@ class Level implements ChunkManager, Metadatable{ * @throws \InvalidStateException */ public function loadChunk(int $x, int $z, bool $create = true) : bool{ - if(isset($this->chunks[$chunkHash = Level::chunkHash($x, $z)])){ + if(isset($this->chunks[$chunkHash = World::chunkHash($x, $z)])){ return true; } @@ -2609,7 +2612,7 @@ class Level implements ChunkManager, Metadatable{ } private function queueUnloadChunk(int $x, int $z){ - $this->unloadQueue[Level::chunkHash($x, $z)] = microtime(true); + $this->unloadQueue[World::chunkHash($x, $z)] = microtime(true); } public function unloadChunkRequest(int $x, int $z, bool $safe = true){ @@ -2623,7 +2626,7 @@ class Level implements ChunkManager, Metadatable{ } public function cancelUnloadChunkRequest(int $x, int $z){ - unset($this->unloadQueue[Level::chunkHash($x, $z)]); + unset($this->unloadQueue[World::chunkHash($x, $z)]); } public function unloadChunk(int $x, int $z, bool $safe = true, bool $trySave = true) : bool{ @@ -2637,7 +2640,7 @@ class Level implements ChunkManager, Metadatable{ $this->timings->doChunkUnload->startTiming(); - $chunkHash = Level::chunkHash($x, $z); + $chunkHash = World::chunkHash($x, $z); $chunk = $this->chunks[$chunkHash] ?? null; @@ -2749,8 +2752,8 @@ class Level implements ChunkManager, Metadatable{ } /** - * Returns the Level display name. - * WARNING: This is NOT guaranteed to be unique. Multiple levels at runtime may share the same display name. + * Returns the World display name. + * WARNING: This is NOT guaranteed to be unique. Multiple worlds at runtime may share the same display name. * * @return string */ @@ -2759,7 +2762,7 @@ class Level implements ChunkManager, Metadatable{ } /** - * Returns the Level folder name. This will not change at runtime and will be unique to a level per runtime. + * Returns the World folder name. This will not change at runtime and will be unique to a world per runtime. * * @return string */ @@ -2768,7 +2771,7 @@ class Level implements ChunkManager, Metadatable{ } /** - * Sets the current time on the level + * Sets the current time on the world * * @param int $time */ @@ -2778,7 +2781,7 @@ class Level implements ChunkManager, Metadatable{ } /** - * Stops the time for the level, will not save the lock state to disk + * Stops the time for the world, will not save the lock state to disk */ public function stopTime(){ $this->stopTime = true; @@ -2794,12 +2797,12 @@ class Level implements ChunkManager, Metadatable{ } /** - * Gets the level seed + * Gets the world seed * * @return int */ public function getSeed() : int{ - return $this->provider->getLevelData()->getSeed(); + return $this->provider->getWorldData()->getSeed(); } public function getWorldHeight() : int{ @@ -2810,7 +2813,7 @@ class Level implements ChunkManager, Metadatable{ * @return int */ public function getDifficulty() : int{ - return $this->provider->getLevelData()->getDifficulty(); + return $this->provider->getWorldData()->getDifficulty(); } /** @@ -2820,7 +2823,7 @@ class Level implements ChunkManager, Metadatable{ if($difficulty < 0 or $difficulty > 3){ throw new \InvalidArgumentException("Invalid difficulty level $difficulty"); } - $this->provider->getLevelData()->setDifficulty($difficulty); + $this->provider->getWorldData()->setDifficulty($difficulty); $this->sendDifficulty(); } @@ -2839,7 +2842,7 @@ class Level implements ChunkManager, Metadatable{ } public function populateChunk(int $x, int $z, bool $force = false) : bool{ - if(isset($this->chunkPopulationQueue[$index = Level::chunkHash($x, $z)]) or (count($this->chunkPopulationQueue) >= $this->chunkPopulationQueueSize and !$force)){ + if(isset($this->chunkPopulationQueue[$index = World::chunkHash($x, $z)]) or (count($this->chunkPopulationQueue) >= $this->chunkPopulationQueueSize and !$force)){ return false; } for($xx = -1; $xx <= 1; ++$xx){ @@ -2880,7 +2883,7 @@ class Level implements ChunkManager, Metadatable{ foreach($this->chunks as $index => $chunk){ if(!isset($this->unloadQueue[$index])){ - Level::getXZ($index, $X, $Z); + World::getXZ($index, $X, $Z); if(!$this->isSpawnChunk($X, $Z)){ $this->unloadChunkRequest($X, $Z, true); } @@ -2898,7 +2901,7 @@ class Level implements ChunkManager, Metadatable{ $maxUnload = 96; $now = microtime(true); foreach($this->unloadQueue as $index => $time){ - Level::getXZ($index, $X, $Z); + World::getXZ($index, $X, $Z); if(!$force){ if($maxUnload <= 0){ @@ -2918,18 +2921,18 @@ class Level implements ChunkManager, Metadatable{ } public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue) : void{ - $this->server->getLevelMetadata()->setMetadata($this, $metadataKey, $newMetadataValue); + $this->server->getWorldMetadata()->setMetadata($this, $metadataKey, $newMetadataValue); } public function getMetadata(string $metadataKey){ - return $this->server->getLevelMetadata()->getMetadata($this, $metadataKey); + return $this->server->getWorldMetadata()->getMetadata($this, $metadataKey); } public function hasMetadata(string $metadataKey) : bool{ - return $this->server->getLevelMetadata()->hasMetadata($this, $metadataKey); + return $this->server->getWorldMetadata()->hasMetadata($this, $metadataKey); } public function removeMetadata(string $metadataKey, Plugin $owningPlugin) : void{ - $this->server->getLevelMetadata()->removeMetadata($this, $metadataKey, $owningPlugin); + $this->server->getWorldMetadata()->removeMetadata($this, $metadataKey, $owningPlugin); } } diff --git a/src/pocketmine/level/LevelException.php b/src/pocketmine/world/WorldException.php similarity index 91% rename from src/pocketmine/level/LevelException.php rename to src/pocketmine/world/WorldException.php index cda361f862..73966649f4 100644 --- a/src/pocketmine/level/LevelException.php +++ b/src/pocketmine/world/WorldException.php @@ -21,10 +21,10 @@ declare(strict_types=1); -namespace pocketmine\level; +namespace pocketmine\world; use pocketmine\utils\ServerException; -class LevelException extends ServerException{ +class WorldException extends ServerException{ } diff --git a/src/pocketmine/level/LevelManager.php b/src/pocketmine/world/WorldManager.php similarity index 60% rename from src/pocketmine/level/LevelManager.php rename to src/pocketmine/world/WorldManager.php index 9581e780ce..8c79909228 100644 --- a/src/pocketmine/level/LevelManager.php +++ b/src/pocketmine/world/WorldManager.php @@ -21,23 +21,23 @@ declare(strict_types=1); -namespace pocketmine\level; +namespace pocketmine\world; use pocketmine\entity\Entity; -use pocketmine\event\level\LevelInitEvent; -use pocketmine\event\level\LevelLoadEvent; -use pocketmine\event\level\LevelUnloadEvent; -use pocketmine\level\format\io\exception\UnsupportedLevelFormatException; -use pocketmine\level\format\io\FormatConverter; -use pocketmine\level\format\io\LevelProvider; -use pocketmine\level\format\io\LevelProviderManager; -use pocketmine\level\format\io\WritableLevelProvider; -use pocketmine\level\generator\Generator; -use pocketmine\level\generator\GeneratorManager; -use pocketmine\level\generator\normal\Normal; +use pocketmine\event\world\WorldInitEvent; +use pocketmine\event\world\WorldLoadEvent; +use pocketmine\event\world\WorldUnloadEvent; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\Utils; +use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; +use pocketmine\world\format\io\FormatConverter; +use pocketmine\world\format\io\WorldProvider; +use pocketmine\world\format\io\WorldProviderManager; +use pocketmine\world\format\io\WritableWorldProvider; +use pocketmine\world\generator\Generator; +use pocketmine\world\generator\GeneratorManager; +use pocketmine\world\generator\normal\Normal; use function array_keys; use function array_shift; use function asort; @@ -52,11 +52,11 @@ use function trim; use const INT32_MAX; use const INT32_MIN; -class LevelManager{ - /** @var Level[] */ - private $levels = []; - /** @var Level|null */ - private $levelDefault; +class WorldManager{ + /** @var World[] */ + private $worlds = []; + /** @var World|null */ + private $defaultWorld; /** @var Server */ private $server; @@ -77,29 +77,29 @@ class LevelManager{ } /** - * @return Level[] + * @return World[] */ - public function getLevels() : array{ - return $this->levels; + public function getWorlds() : array{ + return $this->worlds; } /** - * @return Level|null + * @return World|null */ - public function getDefaultLevel() : ?Level{ - return $this->levelDefault; + public function getDefaultWorld() : ?World{ + return $this->defaultWorld; } /** - * Sets the default level to a different level + * Sets the default world to a different world * This won't change the level-name property, * it only affects the server on runtime * - * @param Level|null $level + * @param World|null $world */ - public function setDefaultLevel(?Level $level) : void{ - if($level === null or ($this->isLevelLoaded($level->getFolderName()) and $level !== $this->levelDefault)){ - $this->levelDefault = $level; + public function setDefaultWorld(?World $world) : void{ + if($world === null or ($this->isWorldLoaded($world->getFolderName()) and $world !== $this->defaultWorld)){ + $this->defaultWorld = $world; } } @@ -108,30 +108,30 @@ class LevelManager{ * * @return bool */ - public function isLevelLoaded(string $name) : bool{ - return $this->getLevelByName($name) instanceof Level; + public function isWorldLoaded(string $name) : bool{ + return $this->getWorldByName($name) instanceof World; } /** - * @param int $levelId + * @param int $worldId * - * @return Level|null + * @return World|null */ - public function getLevel(int $levelId) : ?Level{ - return $this->levels[$levelId] ?? null; + public function getLevel(int $worldId) : ?World{ + return $this->worlds[$worldId] ?? null; } /** - * NOTE: This matches levels based on the FOLDER name, NOT the display name. + * NOTE: This matches worlds based on the FOLDER name, NOT the display name. * * @param string $name * - * @return Level|null + * @return World|null */ - public function getLevelByName(string $name) : ?Level{ - foreach($this->levels as $level){ - if($level->getFolderName() === $name){ - return $level; + public function getWorldByName(string $name) : ?World{ + foreach($this->worlds as $world){ + if($world->getFolderName() === $name){ + return $world; } } @@ -139,23 +139,23 @@ class LevelManager{ } /** - * @param Level $level + * @param World $world * @param bool $forceUnload * * @return bool * * @throws \InvalidArgumentException */ - public function unloadLevel(Level $level, bool $forceUnload = false) : bool{ - if($level === $this->getDefaultLevel() and !$forceUnload){ + public function unloadWorld(World $world, bool $forceUnload = false) : bool{ + if($world === $this->getDefaultWorld() and !$forceUnload){ throw new \InvalidArgumentException("The default world cannot be unloaded while running, please switch worlds."); } - if($level->isDoingTick()){ + if($world->isDoingTick()){ throw new \InvalidArgumentException("Cannot unload a world during world tick"); } - $ev = new LevelUnloadEvent($level); - if($level === $this->levelDefault and !$forceUnload){ + $ev = new WorldUnloadEvent($world); + if($world === $this->defaultWorld and !$forceUnload){ $ev->setCancelled(true); } @@ -165,47 +165,47 @@ class LevelManager{ return false; } - $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.level.unloading", [$level->getDisplayName()])); - foreach($level->getPlayers() as $player){ - if($level === $this->levelDefault or $this->levelDefault === null){ + $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.level.unloading", [$world->getDisplayName()])); + foreach($world->getPlayers() as $player){ + if($world === $this->defaultWorld or $this->defaultWorld === null){ $player->disconnect("Forced default world unload"); - }elseif($this->levelDefault instanceof Level){ - $player->teleport($this->levelDefault->getSafeSpawn()); + }elseif($this->defaultWorld instanceof World){ + $player->teleport($this->defaultWorld->getSafeSpawn()); } } - if($level === $this->levelDefault){ - $this->levelDefault = null; + if($world === $this->defaultWorld){ + $this->defaultWorld = null; } - unset($this->levels[$level->getId()]); + unset($this->worlds[$world->getId()]); - $level->close(); + $world->close(); return true; } /** - * Loads a level from the data directory + * Loads a world from the data directory * * @param string $name * @param bool $autoUpgrade Converts worlds to the default format if the world's format is not writable / deprecated * * @return bool * - * @throws LevelException + * @throws WorldException */ - public function loadLevel(string $name, bool $autoUpgrade = false) : bool{ + public function loadWorld(string $name, bool $autoUpgrade = false) : bool{ if(trim($name) === ""){ - throw new LevelException("Invalid empty world name"); + throw new WorldException("Invalid empty world name"); } - if($this->isLevelLoaded($name)){ + if($this->isWorldLoaded($name)){ return true; - }elseif(!$this->isLevelGenerated($name)){ + }elseif(!$this->isWorldGenerated($name)){ return false; } $path = $this->server->getDataPath() . "worlds/" . $name . "/"; - $providers = LevelProviderManager::getMatchingProviders($path); + $providers = WorldProviderManager::getMatchingProviders($path); if(count($providers) !== 1){ $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.level.loadError", [ $name, @@ -218,57 +218,57 @@ class LevelManager{ $providerClass = array_shift($providers); /** - * @var LevelProvider $provider - * @see LevelProvider::__construct() + * @var WorldProvider $provider + * @see WorldProvider::__construct() */ $provider = new $providerClass($path); try{ - GeneratorManager::getGenerator($provider->getLevelData()->getGenerator(), true); + GeneratorManager::getGenerator($provider->getWorldData()->getGenerator(), true); }catch(\InvalidArgumentException $e){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.level.loadError", [$name, "Unknown generator \"" . $provider->getLevelData()->getGenerator() . "\""])); + $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.level.loadError", [$name, "Unknown generator \"" . $provider->getWorldData()->getGenerator() . "\""])); return false; } - if(!($provider instanceof WritableLevelProvider)){ + if(!($provider instanceof WritableWorldProvider)){ if(!$autoUpgrade){ - throw new LevelException("World \"$name\" is in an unsupported format and needs to be upgraded"); + throw new WorldException("World \"$name\" is in an unsupported format and needs to be upgraded"); } $this->server->getLogger()->notice("Upgrading world \"$name\" to new format. This may take a while."); - $converter = new FormatConverter($provider, LevelProviderManager::getDefault(), $this->server->getDataPath() . "world_conversion_backups", $this->server->getLogger()); + $converter = new FormatConverter($provider, WorldProviderManager::getDefault(), $this->server->getDataPath() . "world_conversion_backups", $this->server->getLogger()); $provider = $converter->execute(); $this->server->getLogger()->notice("Upgraded world \"$name\" to new format successfully. Backed up pre-conversion world at " . $converter->getBackupPath()); } try{ - $level = new Level($this->server, $name, $provider); - }catch(UnsupportedLevelFormatException $e){ + $world = new World($this->server, $name, $provider); + }catch(UnsupportedWorldFormatException $e){ $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.level.loadError", [$name, $e->getMessage()])); return false; } - $this->levels[$level->getId()] = $level; - $level->setAutoSave($this->autoSave); + $this->worlds[$world->getId()] = $world; + $world->setAutoSave($this->autoSave); - (new LevelLoadEvent($level))->call(); + (new WorldLoadEvent($world))->call(); return true; } /** - * Generates a new level if it does not exist + * Generates a new world if it does not exist * * @param string $name * @param int|null $seed - * @param string $generator Class name that extends pocketmine\level\generator\Generator + * @param string $generator Class name that extends pocketmine\world\generator\Generator * @param array $options * @param bool $backgroundGeneration * * @return bool * @throws \InvalidArgumentException */ - public function generateLevel(string $name, ?int $seed = null, string $generator = Normal::class, array $options = [], bool $backgroundGeneration = true) : bool{ - if(trim($name) === "" or $this->isLevelGenerated($name)){ + public function generateWorld(string $name, ?int $seed = null, string $generator = Normal::class, array $options = [], bool $backgroundGeneration = true) : bool{ + if(trim($name) === "" or $this->isWorldGenerated($name)){ return false; } @@ -276,26 +276,26 @@ class LevelManager{ Utils::testValidInstance($generator, Generator::class); - $providerClass = LevelProviderManager::getDefault(); + $providerClass = WorldProviderManager::getDefault(); $path = $this->server->getDataPath() . "worlds/" . $name . "/"; - /** @var WritableLevelProvider $providerClass */ + /** @var WritableWorldProvider $providerClass */ $providerClass::generate($path, $name, $seed, $generator, $options); - /** @see WritableLevelProvider::__construct() */ - $level = new Level($this->server, $name, new $providerClass($path)); - $this->levels[$level->getId()] = $level; + /** @see WritableWorldProvider::__construct() */ + $world = new World($this->server, $name, new $providerClass($path)); + $this->worlds[$world->getId()] = $world; - $level->setAutoSave($this->autoSave); + $world->setAutoSave($this->autoSave); - (new LevelInitEvent($level))->call(); + (new WorldInitEvent($world))->call(); - (new LevelLoadEvent($level))->call(); + (new WorldLoadEvent($world))->call(); if($backgroundGeneration){ $this->server->getLogger()->notice($this->server->getLanguage()->translateString("pocketmine.level.backgroundGeneration", [$name])); - $spawnLocation = $level->getSpawnLocation(); + $spawnLocation = $world->getSpawnLocation(); $centerX = $spawnLocation->getFloorX() >> 4; $centerZ = $spawnLocation->getFloorZ() >> 4; @@ -306,7 +306,7 @@ class LevelManager{ $distance = $X ** 2 + $Z ** 2; $chunkX = $X + $centerX; $chunkZ = $Z + $centerZ; - $index = Level::chunkHash($chunkX, $chunkZ); + $index = World::chunkHash($chunkX, $chunkZ); $order[$index] = $distance; } } @@ -314,8 +314,8 @@ class LevelManager{ asort($order); foreach($order as $index => $distance){ - Level::getXZ($index, $chunkX, $chunkZ); - $level->populateChunk($chunkX, $chunkZ, true); + World::getXZ($index, $chunkX, $chunkZ); + $world->populateChunk($chunkX, $chunkZ, true); } } @@ -327,20 +327,20 @@ class LevelManager{ * * @return bool */ - public function isLevelGenerated(string $name) : bool{ + public function isWorldGenerated(string $name) : bool{ if(trim($name) === ""){ return false; } $path = $this->server->getDataPath() . "worlds/" . $name . "/"; - if(!($this->getLevelByName($name) instanceof Level)){ - return !empty(LevelProviderManager::getMatchingProviders($path)); + if(!($this->getWorldByName($name) instanceof World)){ + return !empty(WorldProviderManager::getMatchingProviders($path)); } return true; } /** - * Searches all levels for the entity with the specified ID. + * Searches all worlds for the entity with the specified ID. * Useful for tracking entities across multiple worlds without needing strong references. * * @param int $entityId @@ -348,9 +348,9 @@ class LevelManager{ * @return Entity|null */ public function findEntity(int $entityId) : ?Entity{ - foreach($this->levels as $level){ - assert(!$level->isClosed()); - if(($entity = $level->getEntity($entityId)) instanceof Entity){ + foreach($this->worlds as $world){ + assert(!$world->isClosed()); + if(($entity = $world->getEntity($entityId)) instanceof Entity){ return $entity; } } @@ -360,18 +360,18 @@ class LevelManager{ public function tick(int $currentTick) : void{ - foreach($this->levels as $k => $level){ - if(!isset($this->levels[$k])){ - // Level unloaded during the tick of a level earlier in this loop, perhaps by plugin + foreach($this->worlds as $k => $world){ + if(!isset($this->worlds[$k])){ + // World unloaded during the tick of a world earlier in this loop, perhaps by plugin continue; } - $levelTime = microtime(true); - $level->doTick($currentTick); - $tickMs = (microtime(true) - $levelTime) * 1000; - $level->tickRateTime = $tickMs; + $worldTime = microtime(true); + $world->doTick($currentTick); + $tickMs = (microtime(true) - $worldTime) * 1000; + $world->tickRateTime = $tickMs; if($tickMs >= 50){ - $this->server->getLogger()->debug(sprintf("World \"%s\" took too long to tick: %gms (%g ticks)", $level->getDisplayName(), $tickMs, round($tickMs / 50, 2))); + $this->server->getLogger()->debug(sprintf("World \"%s\" took too long to tick: %gms (%g ticks)", $world->getDisplayName(), $tickMs, round($tickMs / 50, 2))); } } @@ -398,8 +398,8 @@ class LevelManager{ */ public function setAutoSave(bool $value) : void{ $this->autoSave = $value; - foreach($this->levels as $level){ - $level->setAutoSave($this->autoSave); + foreach($this->worlds as $world){ + $world->setAutoSave($this->autoSave); } } @@ -424,13 +424,13 @@ class LevelManager{ private function doAutoSave() : void{ Timings::$worldSaveTimer->startTiming(); - foreach($this->levels as $level){ - foreach($level->getPlayers() as $player){ + foreach($this->worlds as $world){ + foreach($world->getPlayers() as $player){ if($player->spawned){ $player->save(); } } - $level->save(false); + $world->save(false); } Timings::$worldSaveTimer->stopTiming(); } diff --git a/src/pocketmine/level/LevelTimings.php b/src/pocketmine/world/WorldTimings.php similarity index 96% rename from src/pocketmine/level/LevelTimings.php rename to src/pocketmine/world/WorldTimings.php index de925cd6cc..c79f48d7ef 100644 --- a/src/pocketmine/level/LevelTimings.php +++ b/src/pocketmine/world/WorldTimings.php @@ -21,12 +21,12 @@ declare(strict_types=1); -namespace pocketmine\level; +namespace pocketmine\world; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; -class LevelTimings{ +class WorldTimings{ /** @var TimingsHandler */ public $setBlock; @@ -66,8 +66,8 @@ class LevelTimings{ /** @var TimingsHandler */ public $syncChunkSaveTimer; - public function __construct(Level $level){ - $name = $level->getFolderName() . " - "; + public function __construct(World $world){ + $name = $world->getFolderName() . " - "; $this->setBlock = new TimingsHandler("** " . $name . "setBlock"); $this->doBlockLightUpdates = new TimingsHandler("** " . $name . "doBlockLightUpdates"); diff --git a/src/pocketmine/level/biome/Biome.php b/src/pocketmine/world/biome/Biome.php similarity index 93% rename from src/pocketmine/level/biome/Biome.php rename to src/pocketmine/world/biome/Biome.php index 30b413927d..92800eae0a 100644 --- a/src/pocketmine/level/biome/Biome.php +++ b/src/pocketmine/world/biome/Biome.php @@ -21,13 +21,13 @@ declare(strict_types=1); -namespace pocketmine\level\biome; +namespace pocketmine\world\biome; use pocketmine\block\Block; use pocketmine\block\utils\TreeType; -use pocketmine\level\ChunkManager; -use pocketmine\level\generator\populator\Populator; use pocketmine\utils\Random; +use pocketmine\world\ChunkManager; +use pocketmine\world\generator\populator\Populator; abstract class Biome{ @@ -123,14 +123,14 @@ abstract class Biome{ } /** - * @param ChunkManager $level + * @param ChunkManager $world * @param int $chunkX * @param int $chunkZ * @param Random $random */ - public function populateChunk(ChunkManager $level, int $chunkX, int $chunkZ, Random $random) : void{ + public function populateChunk(ChunkManager $world, int $chunkX, int $chunkZ, Random $random) : void{ foreach($this->populators as $populator){ - $populator->populate($level, $chunkX, $chunkZ, $random); + $populator->populate($world, $chunkX, $chunkZ, $random); } } diff --git a/src/pocketmine/level/biome/DesertBiome.php b/src/pocketmine/world/biome/DesertBiome.php similarity index 96% rename from src/pocketmine/level/biome/DesertBiome.php rename to src/pocketmine/world/biome/DesertBiome.php index d520ad5853..dac51c8718 100644 --- a/src/pocketmine/level/biome/DesertBiome.php +++ b/src/pocketmine/world/biome/DesertBiome.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\biome; +namespace pocketmine\world\biome; class DesertBiome extends SandyBiome{ diff --git a/src/pocketmine/level/biome/ForestBiome.php b/src/pocketmine/world/biome/ForestBiome.php similarity index 91% rename from src/pocketmine/level/biome/ForestBiome.php rename to src/pocketmine/world/biome/ForestBiome.php index 4f44bfc219..b3e45cdcc6 100644 --- a/src/pocketmine/level/biome/ForestBiome.php +++ b/src/pocketmine/world/biome/ForestBiome.php @@ -21,11 +21,11 @@ declare(strict_types=1); -namespace pocketmine\level\biome; +namespace pocketmine\world\biome; use pocketmine\block\utils\TreeType; -use pocketmine\level\generator\populator\TallGrass; -use pocketmine\level\generator\populator\Tree; +use pocketmine\world\generator\populator\TallGrass; +use pocketmine\world\generator\populator\Tree; class ForestBiome extends GrassyBiome{ diff --git a/src/pocketmine/level/biome/GrassyBiome.php b/src/pocketmine/world/biome/GrassyBiome.php similarity index 97% rename from src/pocketmine/level/biome/GrassyBiome.php rename to src/pocketmine/world/biome/GrassyBiome.php index 3a0d39cf16..142b18b811 100644 --- a/src/pocketmine/level/biome/GrassyBiome.php +++ b/src/pocketmine/world/biome/GrassyBiome.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\biome; +namespace pocketmine\world\biome; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; diff --git a/src/pocketmine/level/biome/HellBiome.php b/src/pocketmine/world/biome/HellBiome.php similarity index 96% rename from src/pocketmine/level/biome/HellBiome.php rename to src/pocketmine/world/biome/HellBiome.php index 4fcb761927..38556ad258 100644 --- a/src/pocketmine/level/biome/HellBiome.php +++ b/src/pocketmine/world/biome/HellBiome.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\biome; +namespace pocketmine\world\biome; class HellBiome extends Biome{ diff --git a/src/pocketmine/level/biome/IcePlainsBiome.php b/src/pocketmine/world/biome/IcePlainsBiome.php similarity index 92% rename from src/pocketmine/level/biome/IcePlainsBiome.php rename to src/pocketmine/world/biome/IcePlainsBiome.php index 5d61c9ce67..5b7756971a 100644 --- a/src/pocketmine/level/biome/IcePlainsBiome.php +++ b/src/pocketmine/world/biome/IcePlainsBiome.php @@ -21,9 +21,9 @@ declare(strict_types=1); -namespace pocketmine\level\biome; +namespace pocketmine\world\biome; -use pocketmine\level\generator\populator\TallGrass; +use pocketmine\world\generator\populator\TallGrass; class IcePlainsBiome extends SnowyBiome{ diff --git a/src/pocketmine/level/biome/MountainsBiome.php b/src/pocketmine/world/biome/MountainsBiome.php similarity index 90% rename from src/pocketmine/level/biome/MountainsBiome.php rename to src/pocketmine/world/biome/MountainsBiome.php index da3585b6db..0d9a8a0e26 100644 --- a/src/pocketmine/level/biome/MountainsBiome.php +++ b/src/pocketmine/world/biome/MountainsBiome.php @@ -21,10 +21,10 @@ declare(strict_types=1); -namespace pocketmine\level\biome; +namespace pocketmine\world\biome; -use pocketmine\level\generator\populator\TallGrass; -use pocketmine\level\generator\populator\Tree; +use pocketmine\world\generator\populator\TallGrass; +use pocketmine\world\generator\populator\Tree; class MountainsBiome extends GrassyBiome{ diff --git a/src/pocketmine/level/biome/OceanBiome.php b/src/pocketmine/world/biome/OceanBiome.php similarity index 94% rename from src/pocketmine/level/biome/OceanBiome.php rename to src/pocketmine/world/biome/OceanBiome.php index 3f9f1e6371..c3274c90db 100644 --- a/src/pocketmine/level/biome/OceanBiome.php +++ b/src/pocketmine/world/biome/OceanBiome.php @@ -21,11 +21,11 @@ declare(strict_types=1); -namespace pocketmine\level\biome; +namespace pocketmine\world\biome; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; -use pocketmine\level\generator\populator\TallGrass; +use pocketmine\world\generator\populator\TallGrass; class OceanBiome extends Biome{ diff --git a/src/pocketmine/level/biome/PlainBiome.php b/src/pocketmine/world/biome/PlainBiome.php similarity index 92% rename from src/pocketmine/level/biome/PlainBiome.php rename to src/pocketmine/world/biome/PlainBiome.php index 0f927a5827..e6d0f07e1d 100644 --- a/src/pocketmine/level/biome/PlainBiome.php +++ b/src/pocketmine/world/biome/PlainBiome.php @@ -21,9 +21,9 @@ declare(strict_types=1); -namespace pocketmine\level\biome; +namespace pocketmine\world\biome; -use pocketmine\level\generator\populator\TallGrass; +use pocketmine\world\generator\populator\TallGrass; class PlainBiome extends GrassyBiome{ diff --git a/src/pocketmine/level/biome/RiverBiome.php b/src/pocketmine/world/biome/RiverBiome.php similarity index 94% rename from src/pocketmine/level/biome/RiverBiome.php rename to src/pocketmine/world/biome/RiverBiome.php index 06e3393845..7752d5da8c 100644 --- a/src/pocketmine/level/biome/RiverBiome.php +++ b/src/pocketmine/world/biome/RiverBiome.php @@ -21,11 +21,11 @@ declare(strict_types=1); -namespace pocketmine\level\biome; +namespace pocketmine\world\biome; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; -use pocketmine\level\generator\populator\TallGrass; +use pocketmine\world\generator\populator\TallGrass; class RiverBiome extends Biome{ diff --git a/src/pocketmine/level/biome/SandyBiome.php b/src/pocketmine/world/biome/SandyBiome.php similarity index 97% rename from src/pocketmine/level/biome/SandyBiome.php rename to src/pocketmine/world/biome/SandyBiome.php index b9f35642e2..3e45c709b2 100644 --- a/src/pocketmine/level/biome/SandyBiome.php +++ b/src/pocketmine/world/biome/SandyBiome.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\biome; +namespace pocketmine\world\biome; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; diff --git a/src/pocketmine/level/biome/SmallMountainsBiome.php b/src/pocketmine/world/biome/SmallMountainsBiome.php similarity index 96% rename from src/pocketmine/level/biome/SmallMountainsBiome.php rename to src/pocketmine/world/biome/SmallMountainsBiome.php index 12a9b52293..8e649d889c 100644 --- a/src/pocketmine/level/biome/SmallMountainsBiome.php +++ b/src/pocketmine/world/biome/SmallMountainsBiome.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\biome; +namespace pocketmine\world\biome; class SmallMountainsBiome extends MountainsBiome{ diff --git a/src/pocketmine/level/biome/SnowyBiome.php b/src/pocketmine/world/biome/SnowyBiome.php similarity index 97% rename from src/pocketmine/level/biome/SnowyBiome.php rename to src/pocketmine/world/biome/SnowyBiome.php index 0d3c18e201..19d8ca0574 100644 --- a/src/pocketmine/level/biome/SnowyBiome.php +++ b/src/pocketmine/world/biome/SnowyBiome.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\biome; +namespace pocketmine\world\biome; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; diff --git a/src/pocketmine/level/biome/SwampBiome.php b/src/pocketmine/world/biome/SwampBiome.php similarity index 96% rename from src/pocketmine/level/biome/SwampBiome.php rename to src/pocketmine/world/biome/SwampBiome.php index e80dc72e95..a1db3621a3 100644 --- a/src/pocketmine/level/biome/SwampBiome.php +++ b/src/pocketmine/world/biome/SwampBiome.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\biome; +namespace pocketmine\world\biome; class SwampBiome extends GrassyBiome{ diff --git a/src/pocketmine/level/biome/TaigaBiome.php b/src/pocketmine/world/biome/TaigaBiome.php similarity index 90% rename from src/pocketmine/level/biome/TaigaBiome.php rename to src/pocketmine/world/biome/TaigaBiome.php index d1622ed24c..18a8ca3448 100644 --- a/src/pocketmine/level/biome/TaigaBiome.php +++ b/src/pocketmine/world/biome/TaigaBiome.php @@ -21,11 +21,11 @@ declare(strict_types=1); -namespace pocketmine\level\biome; +namespace pocketmine\world\biome; use pocketmine\block\utils\TreeType; -use pocketmine\level\generator\populator\TallGrass; -use pocketmine\level\generator\populator\Tree; +use pocketmine\world\generator\populator\TallGrass; +use pocketmine\world\generator\populator\Tree; class TaigaBiome extends SnowyBiome{ diff --git a/src/pocketmine/level/biome/UnknownBiome.php b/src/pocketmine/world/biome/UnknownBiome.php similarity index 96% rename from src/pocketmine/level/biome/UnknownBiome.php rename to src/pocketmine/world/biome/UnknownBiome.php index 7bed7718e1..c8ac018979 100644 --- a/src/pocketmine/level/biome/UnknownBiome.php +++ b/src/pocketmine/world/biome/UnknownBiome.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\biome; +namespace pocketmine\world\biome; /** * Polyfill class for biomes that are unknown to PocketMine-MP diff --git a/src/pocketmine/level/format/Chunk.php b/src/pocketmine/world/format/Chunk.php similarity index 96% rename from src/pocketmine/level/format/Chunk.php rename to src/pocketmine/world/format/Chunk.php index a523df3c73..6346634278 100644 --- a/src/pocketmine/level/format/Chunk.php +++ b/src/pocketmine/world/format/Chunk.php @@ -24,13 +24,12 @@ */ declare(strict_types=1); -namespace pocketmine\level\format; +namespace pocketmine\world\format; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; -use pocketmine\level\Level; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; @@ -39,6 +38,7 @@ use pocketmine\tile\Spawnable; use pocketmine\tile\Tile; use pocketmine\tile\TileFactory; use pocketmine\utils\BinaryStream; +use pocketmine\world\World; use function array_fill; use function array_filter; use function array_map; @@ -575,45 +575,45 @@ class Chunk{ /** * Deserializes tiles and entities from NBT * - * @param Level $level + * @param World $world */ - public function initChunk(Level $level) : void{ + public function initChunk(World $world) : void{ if(!$this->isInit){ $changed = false; if($this->NBTentities !== null){ - $level->timings->syncChunkLoadEntitiesTimer->startTiming(); + $world->timings->syncChunkLoadEntitiesTimer->startTiming(); foreach($this->NBTentities as $nbt){ if($nbt instanceof CompoundTag){ try{ - $entity = EntityFactory::createFromData($level, $nbt); + $entity = EntityFactory::createFromData($world, $nbt); if(!($entity instanceof Entity)){ - $level->getServer()->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown entity type " . $nbt->getString("id", $nbt->getString("identifier", "", true), true)); + $world->getServer()->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown entity type " . $nbt->getString("id", $nbt->getString("identifier", "", true), true)); $changed = true; continue; } }catch(\Exception $t){ //TODO: this shouldn't be here - $level->getServer()->getLogger()->logException($t); + $world->getServer()->getLogger()->logException($t); $changed = true; continue; } } } - $level->timings->syncChunkLoadEntitiesTimer->stopTiming(); + $world->timings->syncChunkLoadEntitiesTimer->stopTiming(); - $level->timings->syncChunkLoadTileEntitiesTimer->startTiming(); + $world->timings->syncChunkLoadTileEntitiesTimer->startTiming(); foreach($this->NBTtiles as $nbt){ if($nbt instanceof CompoundTag){ - if(($tile = TileFactory::createFromData($level, $nbt)) !== null){ - $level->addTile($tile); + if(($tile = TileFactory::createFromData($world, $nbt)) !== null){ + $world->addTile($tile); }else{ - $level->getServer()->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown tile entity type " . $nbt->getString("id", "", true)); + $world->getServer()->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown tile entity type " . $nbt->getString("id", "", true)); $changed = true; continue; } } } - $level->timings->syncChunkLoadTileEntitiesTimer->stopTiming(); + $world->timings->syncChunkLoadTileEntitiesTimer->stopTiming(); $this->NBTentities = null; $this->NBTtiles = null; diff --git a/src/pocketmine/level/format/ChunkException.php b/src/pocketmine/world/format/ChunkException.php similarity index 95% rename from src/pocketmine/level/format/ChunkException.php rename to src/pocketmine/world/format/ChunkException.php index 0d373f4868..d8f97d057c 100644 --- a/src/pocketmine/level/format/ChunkException.php +++ b/src/pocketmine/world/format/ChunkException.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\format; +namespace pocketmine\world\format; class ChunkException extends \RuntimeException{ diff --git a/src/pocketmine/level/format/EmptySubChunk.php b/src/pocketmine/world/format/EmptySubChunk.php similarity index 98% rename from src/pocketmine/level/format/EmptySubChunk.php rename to src/pocketmine/world/format/EmptySubChunk.php index 54bb0d69cb..8606f1d390 100644 --- a/src/pocketmine/level/format/EmptySubChunk.php +++ b/src/pocketmine/world/format/EmptySubChunk.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\format; +namespace pocketmine\world\format; use function str_repeat; diff --git a/src/pocketmine/level/format/PalettedBlockArray.php b/src/pocketmine/world/format/PalettedBlockArray.php similarity index 92% rename from src/pocketmine/level/format/PalettedBlockArray.php rename to src/pocketmine/world/format/PalettedBlockArray.php index 90a380873d..622f1150be 100644 --- a/src/pocketmine/level/format/PalettedBlockArray.php +++ b/src/pocketmine/world/format/PalettedBlockArray.php @@ -21,10 +21,11 @@ declare(strict_types=1); -namespace pocketmine\level\format; +namespace pocketmine\world\format; die("This is a stub file for code completion purposes"); +//TODO: this can't be moved right now because of compatibility issues with the extension class PalettedBlockArray{ public function __construct(int $fillEntry){} diff --git a/src/pocketmine/level/format/SubChunk.php b/src/pocketmine/world/format/SubChunk.php similarity index 99% rename from src/pocketmine/level/format/SubChunk.php rename to src/pocketmine/world/format/SubChunk.php index 78fb8046b7..e1b0c6f50d 100644 --- a/src/pocketmine/level/format/SubChunk.php +++ b/src/pocketmine/world/format/SubChunk.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\format; +namespace pocketmine\world\format; use pocketmine\block\BlockLegacyIds; use function array_values; diff --git a/src/pocketmine/level/format/SubChunkInterface.php b/src/pocketmine/world/format/SubChunkInterface.php similarity index 98% rename from src/pocketmine/level/format/SubChunkInterface.php rename to src/pocketmine/world/format/SubChunkInterface.php index 245c492989..fff078c9b0 100644 --- a/src/pocketmine/level/format/SubChunkInterface.php +++ b/src/pocketmine/world/format/SubChunkInterface.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\format; +namespace pocketmine\world\format; interface SubChunkInterface{ diff --git a/src/pocketmine/level/format/io/BaseLevelProvider.php b/src/pocketmine/world/format/io/BaseWorldProvider.php similarity index 74% rename from src/pocketmine/level/format/io/BaseLevelProvider.php rename to src/pocketmine/world/format/io/BaseWorldProvider.php index 89a809d972..97be13a15c 100644 --- a/src/pocketmine/level/format/io/BaseLevelProvider.php +++ b/src/pocketmine/world/format/io/BaseWorldProvider.php @@ -21,40 +21,40 @@ declare(strict_types=1); -namespace pocketmine\level\format\io; +namespace pocketmine\world\format\io; -use pocketmine\level\format\Chunk; -use pocketmine\level\format\io\exception\CorruptedChunkException; -use pocketmine\level\format\io\exception\UnsupportedChunkFormatException; -use pocketmine\level\LevelException; +use pocketmine\world\format\Chunk; +use pocketmine\world\format\io\exception\CorruptedChunkException; +use pocketmine\world\format\io\exception\UnsupportedChunkFormatException; +use pocketmine\world\WorldException; use function file_exists; -abstract class BaseLevelProvider implements LevelProvider{ +abstract class BaseWorldProvider implements WorldProvider{ /** @var string */ protected $path; - /** @var LevelData */ - protected $levelData; + /** @var WorldData */ + protected $worldData; public function __construct(string $path){ if(!file_exists($path)){ - throw new LevelException("World does not exist"); + throw new WorldException("World does not exist"); } $this->path = $path; - $this->levelData = $this->loadLevelData(); + $this->worldData = $this->loadLevelData(); } - abstract protected function loadLevelData() : LevelData; + abstract protected function loadLevelData() : WorldData; public function getPath() : string{ return $this->path; } /** - * @return LevelData + * @return WorldData */ - public function getLevelData() : LevelData{ - return $this->levelData; + public function getWorldData() : WorldData{ + return $this->worldData; } /** diff --git a/src/pocketmine/level/format/io/ChunkUtils.php b/src/pocketmine/world/format/io/ChunkUtils.php similarity index 98% rename from src/pocketmine/level/format/io/ChunkUtils.php rename to src/pocketmine/world/format/io/ChunkUtils.php index fcb9800768..2eb0d2ff13 100644 --- a/src/pocketmine/level/format/io/ChunkUtils.php +++ b/src/pocketmine/world/format/io/ChunkUtils.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\format\io; +namespace pocketmine\world\format\io; use function chr; use function extension_loaded; diff --git a/src/pocketmine/level/format/io/FormatConverter.php b/src/pocketmine/world/format/io/FormatConverter.php similarity index 83% rename from src/pocketmine/level/format/io/FormatConverter.php rename to src/pocketmine/world/format/io/FormatConverter.php index 878b81c331..c86daa084d 100644 --- a/src/pocketmine/level/format/io/FormatConverter.php +++ b/src/pocketmine/world/format/io/FormatConverter.php @@ -21,10 +21,10 @@ declare(strict_types=1); -namespace pocketmine\level\format\io; +namespace pocketmine\world\format\io; -use pocketmine\level\generator\GeneratorManager; use pocketmine\utils\Utils; +use pocketmine\world\generator\GeneratorManager; use function basename; use function crc32; use function file_exists; @@ -39,9 +39,9 @@ use const DIRECTORY_SEPARATOR; class FormatConverter{ - /** @var LevelProvider */ + /** @var WorldProvider */ private $oldProvider; - /** @var WritableLevelProvider|string */ + /** @var WritableWorldProvider|string */ private $newProvider; /** @var string */ @@ -50,11 +50,11 @@ class FormatConverter{ /** @var \Logger */ private $logger; - public function __construct(LevelProvider $oldProvider, string $newProvider, string $backupPath, \Logger $logger){ + public function __construct(WorldProvider $oldProvider, string $newProvider, string $backupPath, \Logger $logger){ $this->oldProvider = $oldProvider; - Utils::testValidInstance($newProvider, WritableLevelProvider::class); + Utils::testValidInstance($newProvider, WritableWorldProvider::class); $this->newProvider = $newProvider; - $this->logger = new \PrefixedLogger($logger, "World Converter - " . $this->oldProvider->getLevelData()->getName()); + $this->logger = new \PrefixedLogger($logger, "World Converter - " . $this->oldProvider->getWorldData()->getName()); if(!file_exists($backupPath)){ @mkdir($backupPath, 0777, true); @@ -70,10 +70,10 @@ class FormatConverter{ return $this->backupPath; } - public function execute() : WritableLevelProvider{ + public function execute() : WritableWorldProvider{ $new = $this->generateNew(); - $this->populateLevelData($new->getLevelData()); + $this->populateLevelData($new->getWorldData()); $this->convertTerrain($new); $path = $this->oldProvider->getPath(); @@ -86,14 +86,14 @@ class FormatConverter{ $this->logger->info("Conversion completed"); /** - * @see WritableLevelProvider::__construct() + * @see WritableWorldProvider::__construct() */ return new $this->newProvider($path); } - private function generateNew() : WritableLevelProvider{ + private function generateNew() : WritableWorldProvider{ $this->logger->info("Generating new world"); - $data = $this->oldProvider->getLevelData(); + $data = $this->oldProvider->getWorldData(); $convertedOutput = rtrim($this->oldProvider->getPath(), "/\\") . "_converted" . DIRECTORY_SEPARATOR; if(file_exists($convertedOutput)){ @@ -103,14 +103,14 @@ class FormatConverter{ $this->newProvider::generate($convertedOutput, $data->getName(), $data->getSeed(), GeneratorManager::getGenerator($data->getGenerator()), $data->getGeneratorOptions()); /** - * @see WritableLevelProvider::__construct() + * @see WritableWorldProvider::__construct() */ return new $this->newProvider($convertedOutput); } - private function populateLevelData(LevelData $data) : void{ + private function populateLevelData(WorldData $data) : void{ $this->logger->info("Converting world manifest"); - $oldData = $this->oldProvider->getLevelData(); + $oldData = $this->oldProvider->getWorldData(); $data->setDifficulty($oldData->getDifficulty()); $data->setLightningLevel($oldData->getLightningLevel()); $data->setLightningTime($oldData->getLightningTime()); @@ -124,7 +124,7 @@ class FormatConverter{ //TODO: add more properties as-needed } - private function convertTerrain(WritableLevelProvider $new) : void{ + private function convertTerrain(WritableWorldProvider $new) : void{ $this->logger->info("Calculating chunk count"); $count = $this->oldProvider->calculateChunkCount(); $this->logger->info("Discovered $count chunks"); diff --git a/src/pocketmine/level/format/io/LevelData.php b/src/pocketmine/world/format/io/WorldData.php similarity index 93% rename from src/pocketmine/level/format/io/LevelData.php rename to src/pocketmine/world/format/io/WorldData.php index 15b2980e92..b24b660d28 100644 --- a/src/pocketmine/level/format/io/LevelData.php +++ b/src/pocketmine/world/format/io/WorldData.php @@ -21,14 +21,14 @@ declare(strict_types=1); -namespace pocketmine\level\format\io; +namespace pocketmine\world\format\io; use pocketmine\math\Vector3; -interface LevelData{ +interface WorldData{ /** - * Saves information about the level state, such as weather, time, etc. + * Saves information about the world state, such as weather, time, etc. */ public function save() : void; @@ -78,7 +78,7 @@ interface LevelData{ public function setSpawn(Vector3 $pos) : void; /** - * Returns the world difficulty. This will be one of the Level constants. + * Returns the world difficulty. This will be one of the World constants. * @return int */ public function getDifficulty() : int; diff --git a/src/pocketmine/level/format/io/LevelProvider.php b/src/pocketmine/world/format/io/WorldProvider.php similarity index 80% rename from src/pocketmine/level/format/io/LevelProvider.php rename to src/pocketmine/world/format/io/WorldProvider.php index e70bf2cc36..62f98cb689 100644 --- a/src/pocketmine/level/format/io/LevelProvider.php +++ b/src/pocketmine/world/format/io/WorldProvider.php @@ -21,13 +21,13 @@ declare(strict_types=1); -namespace pocketmine\level\format\io; +namespace pocketmine\world\format\io; -use pocketmine\level\format\Chunk; -use pocketmine\level\format\io\exception\CorruptedChunkException; -use pocketmine\level\format\io\exception\UnsupportedChunkFormatException; +use pocketmine\world\format\Chunk; +use pocketmine\world\format\io\exception\CorruptedChunkException; +use pocketmine\world\format\io\exception\UnsupportedChunkFormatException; -interface LevelProvider{ +interface WorldProvider{ /** * @param string $path @@ -47,7 +47,7 @@ interface LevelProvider{ public function getPath() : string; /** - * Tells if the path is a valid level. + * Tells if the path is a valid world. * This must tell if the current format supports opening the files in the directory * * @param string $path @@ -70,24 +70,24 @@ interface LevelProvider{ public function loadChunk(int $chunkX, int $chunkZ) : ?Chunk; /** - * Performs garbage collection in the level provider, such as cleaning up regions in Region-based worlds. + * Performs garbage collection in the world provider, such as cleaning up regions in Region-based worlds. */ public function doGarbageCollection() : void; /** * Returns information about the world * - * @return LevelData + * @return WorldData */ - public function getLevelData() : LevelData; + public function getWorldData() : WorldData; /** - * Performs cleanups necessary when the level provider is closed and no longer needed. + * Performs cleanups necessary when the world provider is closed and no longer needed. */ public function close() : void; /** - * Returns a generator which yields all the chunks in this level. + * Returns a generator which yields all the chunks in this world. * * @param bool $skipCorrupted * diff --git a/src/pocketmine/level/format/io/LevelProviderManager.php b/src/pocketmine/world/format/io/WorldProviderManager.php similarity index 73% rename from src/pocketmine/level/format/io/LevelProviderManager.php rename to src/pocketmine/world/format/io/WorldProviderManager.php index 75268fd883..cdd655653e 100644 --- a/src/pocketmine/level/format/io/LevelProviderManager.php +++ b/src/pocketmine/world/format/io/WorldProviderManager.php @@ -21,20 +21,20 @@ declare(strict_types=1); -namespace pocketmine\level\format\io; +namespace pocketmine\world\format\io; -use pocketmine\level\format\io\leveldb\LevelDB; -use pocketmine\level\format\io\region\Anvil; -use pocketmine\level\format\io\region\McRegion; -use pocketmine\level\format\io\region\PMAnvil; use pocketmine\utils\Utils; +use pocketmine\world\format\io\leveldb\LevelDB; +use pocketmine\world\format\io\region\Anvil; +use pocketmine\world\format\io\region\McRegion; +use pocketmine\world\format\io\region\PMAnvil; use function strtolower; use function trim; -abstract class LevelProviderManager{ +abstract class WorldProviderManager{ protected static $providers = []; - /** @var string|LevelProvider */ + /** @var string|WorldProvider */ private static $default = LevelDB::class; public static function init() : void{ @@ -45,9 +45,9 @@ abstract class LevelProviderManager{ } /** - * Returns the default format used to generate new levels. + * Returns the default format used to generate new worlds. * - * @return string|WritableLevelProvider + * @return string|WritableWorldProvider */ public static function getDefault() : string{ return self::$default; @@ -56,12 +56,12 @@ abstract class LevelProviderManager{ /** * Sets the default format. * - * @param string $class Class implementing WritableLevelProvider + * @param string $class Class implementing WritableWorldProvider * * @throws \InvalidArgumentException */ public static function setDefault(string $class) : void{ - Utils::testValidInstance($class, WritableLevelProvider::class); + Utils::testValidInstance($class, WritableWorldProvider::class); self::$default = $class; } @@ -73,28 +73,28 @@ abstract class LevelProviderManager{ * @param bool $overwrite */ public static function addProvider(string $class, string $name, bool $overwrite = false) : void{ - Utils::testValidInstance($class, LevelProvider::class); + Utils::testValidInstance($class, WorldProvider::class); $name = strtolower($name); if(!$overwrite and isset(self::$providers[$name])){ throw new \InvalidArgumentException("Alias \"$name\" is already assigned"); } - /** @var LevelProvider $class */ + /** @var WorldProvider $class */ self::$providers[$name] = $class; } /** - * Returns a LevelProvider class for this path, or null + * Returns a WorldProvider class for this path, or null * * @param string $path * - * @return string[]|LevelProvider[] + * @return string[]|WorldProvider[] */ public static function getMatchingProviders(string $path) : array{ $result = []; foreach(self::$providers as $alias => $provider){ - /** @var LevelProvider|string $provider */ + /** @var WorldProvider|string $provider */ if($provider::isValid($path)){ $result[$alias] = $provider; } @@ -103,7 +103,7 @@ abstract class LevelProviderManager{ } /** - * Returns a LevelProvider by name, or null if not found + * Returns a WorldProvider by name, or null if not found * * @param string $name * diff --git a/src/pocketmine/level/format/io/WritableLevelProvider.php b/src/pocketmine/world/format/io/WritableWorldProvider.php similarity index 90% rename from src/pocketmine/level/format/io/WritableLevelProvider.php rename to src/pocketmine/world/format/io/WritableWorldProvider.php index fca2024d66..e947240023 100644 --- a/src/pocketmine/level/format/io/WritableLevelProvider.php +++ b/src/pocketmine/world/format/io/WritableWorldProvider.php @@ -21,11 +21,11 @@ declare(strict_types=1); -namespace pocketmine\level\format\io; +namespace pocketmine\world\format\io; -use pocketmine\level\format\Chunk; +use pocketmine\world\format\Chunk; -interface WritableLevelProvider extends LevelProvider{ +interface WritableWorldProvider extends WorldProvider{ /** * Generate the needed files in the path given * diff --git a/src/pocketmine/level/format/io/data/BaseNbtLevelData.php b/src/pocketmine/world/format/io/data/BaseNbtWorldData.php similarity index 93% rename from src/pocketmine/level/format/io/data/BaseNbtLevelData.php rename to src/pocketmine/world/format/io/data/BaseNbtWorldData.php index 75eaf29c47..3d2568f1fd 100644 --- a/src/pocketmine/level/format/io/data/BaseNbtLevelData.php +++ b/src/pocketmine/world/format/io/data/BaseNbtWorldData.php @@ -21,15 +21,15 @@ declare(strict_types=1); -namespace pocketmine\level\format\io\data; +namespace pocketmine\world\format\io\data; -use pocketmine\level\format\io\LevelData; -use pocketmine\level\LevelException; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\world\format\io\WorldData; +use pocketmine\world\WorldException; use function file_exists; -abstract class BaseNbtLevelData implements LevelData{ +abstract class BaseNbtWorldData implements WorldData{ /** @var string */ protected $dataPath; @@ -41,12 +41,12 @@ abstract class BaseNbtLevelData implements LevelData{ $this->dataPath = $dataPath; if(!file_exists($this->dataPath)){ - throw new LevelException("Level data not found at $dataPath"); + throw new WorldException("World data not found at $dataPath"); } $this->compoundTag = $this->load(); if($this->compoundTag === null){ - throw new LevelException("Invalid level data"); + throw new WorldException("Invalid world data"); } $this->fix(); } diff --git a/src/pocketmine/level/format/io/data/BedrockLevelData.php b/src/pocketmine/world/format/io/data/BedrockWorldData.php similarity index 88% rename from src/pocketmine/level/format/io/data/BedrockLevelData.php rename to src/pocketmine/world/format/io/data/BedrockWorldData.php index 7f793b9395..042cbfee24 100644 --- a/src/pocketmine/level/format/io/data/BedrockLevelData.php +++ b/src/pocketmine/world/format/io/data/BedrockWorldData.php @@ -21,13 +21,8 @@ declare(strict_types=1); -namespace pocketmine\level\format\io\data; +namespace pocketmine\world\format\io\data; -use pocketmine\level\format\io\exception\UnsupportedLevelFormatException; -use pocketmine\level\generator\Flat; -use pocketmine\level\generator\Generator; -use pocketmine\level\generator\GeneratorManager; -use pocketmine\level\Level; use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; @@ -36,13 +31,18 @@ use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\utils\Binary; use pocketmine\utils\Utils; +use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; +use pocketmine\world\generator\Flat; +use pocketmine\world\generator\Generator; +use pocketmine\world\generator\GeneratorManager; +use pocketmine\world\World; use function file_get_contents; use function file_put_contents; use function strlen; use function substr; use function time; -class BedrockLevelData extends BaseNbtLevelData{ +class BedrockWorldData extends BaseNbtWorldData{ public const CURRENT_STORAGE_VERSION = 8; @@ -61,10 +61,10 @@ class BedrockLevelData extends BaseNbtLevelData{ //TODO: add support for limited worlds } - $levelData = CompoundTag::create() + $worldData = CompoundTag::create() //Vanilla fields ->setInt("DayCycleStopTime", -1) - ->setInt("Difficulty", Level::getDifficultyFromString((string) ($options["difficulty"] ?? "normal"))) + ->setInt("Difficulty", World::getDifficultyFromString((string) ($options["difficulty"] ?? "normal"))) ->setByte("ForceGameType", 0) ->setInt("GameType", 0) ->setInt("Generator", $generatorType) @@ -98,20 +98,20 @@ class BedrockLevelData extends BaseNbtLevelData{ ->setString("generatorOptions", $options["preset"] ?? ""); $nbt = new LittleEndianNbtSerializer(); - $buffer = $nbt->write(new TreeRoot($levelData)); + $buffer = $nbt->write(new TreeRoot($worldData)); file_put_contents($path . "level.dat", Binary::writeLInt(self::CURRENT_STORAGE_VERSION) . Binary::writeLInt(strlen($buffer)) . $buffer); } protected function load() : ?CompoundTag{ $nbt = new LittleEndianNbtSerializer(); - $levelData = $nbt->read(substr(file_get_contents($this->dataPath), 8))->getTag(); + $worldData = $nbt->read(substr(file_get_contents($this->dataPath), 8))->getTag(); - $version = $levelData->getInt("StorageVersion", INT32_MAX, true); + $version = $worldData->getInt("StorageVersion", INT32_MAX, true); if($version > self::CURRENT_STORAGE_VERSION){ - throw new UnsupportedLevelFormatException("Specified LevelDB world format version ($version) is not supported by " . \pocketmine\NAME); + throw new UnsupportedWorldFormatException("Specified LevelDB world format version ($version) is not supported by " . \pocketmine\NAME); } - return $levelData; + return $worldData; } protected function fix() : void{ @@ -128,9 +128,9 @@ class BedrockLevelData extends BaseNbtLevelData{ $this->compoundTag->setString("generatorOptions", ""); break; case self::GENERATOR_LIMITED: - throw new UnsupportedLevelFormatException("Limited worlds are not currently supported"); + throw new UnsupportedWorldFormatException("Limited worlds are not currently supported"); default: - throw new UnsupportedLevelFormatException("Unknown LevelDB world format type, this world cannot be loaded"); + throw new UnsupportedWorldFormatException("Unknown LevelDB world format type, this world cannot be loaded"); } }else{ $this->compoundTag->setString("generatorName", "default"); @@ -154,7 +154,7 @@ class BedrockLevelData extends BaseNbtLevelData{ } public function getDifficulty() : int{ - return $this->compoundTag->getInt("Difficulty", Level::DIFFICULTY_NORMAL); + return $this->compoundTag->getInt("Difficulty", World::DIFFICULTY_NORMAL); } public function setDifficulty(int $difficulty) : void{ diff --git a/src/pocketmine/level/format/io/data/JavaLevelData.php b/src/pocketmine/world/format/io/data/JavaWorldData.php similarity index 88% rename from src/pocketmine/level/format/io/data/JavaLevelData.php rename to src/pocketmine/world/format/io/data/JavaWorldData.php index c360b1dec7..875b800b06 100644 --- a/src/pocketmine/level/format/io/data/JavaLevelData.php +++ b/src/pocketmine/world/format/io/data/JavaWorldData.php @@ -21,30 +21,30 @@ declare(strict_types=1); -namespace pocketmine\level\format\io\data; +namespace pocketmine\world\format\io\data; -use pocketmine\level\generator\Generator; -use pocketmine\level\generator\GeneratorManager; -use pocketmine\level\Level; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\TreeRoot; use pocketmine\utils\Utils; +use pocketmine\world\generator\Generator; +use pocketmine\world\generator\GeneratorManager; +use pocketmine\world\World; use function ceil; use function file_get_contents; use function file_put_contents; use function microtime; -class JavaLevelData extends BaseNbtLevelData{ +class JavaWorldData extends BaseNbtWorldData{ public static function generate(string $path, string $name, int $seed, string $generator, array $options = [], int $version = 19133) : void{ Utils::testValidInstance($generator, Generator::class); //TODO, add extra details - $levelData = CompoundTag::create() + $worldData = CompoundTag::create() ->setByte("hardcore", ($options["hardcore"] ?? false) === true ? 1 : 0) - ->setByte("Difficulty", Level::getDifficultyFromString((string) ($options["difficulty"] ?? "normal"))) + ->setByte("Difficulty", World::getDifficultyFromString((string) ($options["difficulty"] ?? "normal"))) ->setByte("initialized", 1) ->setInt("GameType", 0) ->setInt("generatorVersion", 1) //2 in MCPE @@ -63,15 +63,15 @@ class JavaLevelData extends BaseNbtLevelData{ ->setTag("GameRules", new CompoundTag()); $nbt = new BigEndianNbtSerializer(); - $buffer = $nbt->writeCompressed(new TreeRoot(CompoundTag::create()->setTag("Data", $levelData))); + $buffer = $nbt->writeCompressed(new TreeRoot(CompoundTag::create()->setTag("Data", $worldData))); file_put_contents($path . "level.dat", $buffer); } protected function load() : ?CompoundTag{ $nbt = new BigEndianNbtSerializer(); - $levelData = $nbt->readCompressed(file_get_contents($this->dataPath))->getTag(); - if($levelData->hasTag("Data", CompoundTag::class)){ - return $levelData->getCompoundTag("Data"); + $worldData = $nbt->readCompressed(file_get_contents($this->dataPath))->getTag(); + if($worldData->hasTag("Data", CompoundTag::class)){ + return $worldData->getCompoundTag("Data"); } return null; } @@ -96,7 +96,7 @@ class JavaLevelData extends BaseNbtLevelData{ public function getDifficulty() : int{ - return $this->compoundTag->getByte("Difficulty", Level::DIFFICULTY_NORMAL); + return $this->compoundTag->getByte("Difficulty", World::DIFFICULTY_NORMAL); } public function setDifficulty(int $difficulty) : void{ diff --git a/src/pocketmine/level/format/io/exception/CorruptedChunkException.php b/src/pocketmine/world/format/io/exception/CorruptedChunkException.php similarity index 89% rename from src/pocketmine/level/format/io/exception/CorruptedChunkException.php rename to src/pocketmine/world/format/io/exception/CorruptedChunkException.php index 9c0705fbd8..38dd61f6d5 100644 --- a/src/pocketmine/level/format/io/exception/CorruptedChunkException.php +++ b/src/pocketmine/world/format/io/exception/CorruptedChunkException.php @@ -21,9 +21,9 @@ declare(strict_types=1); -namespace pocketmine\level\format\io\exception; +namespace pocketmine\world\format\io\exception; -use pocketmine\level\format\ChunkException; +use pocketmine\world\format\ChunkException; class CorruptedChunkException extends ChunkException{ diff --git a/src/pocketmine/level/format/io/exception/UnsupportedChunkFormatException.php b/src/pocketmine/world/format/io/exception/UnsupportedChunkFormatException.php similarity index 89% rename from src/pocketmine/level/format/io/exception/UnsupportedChunkFormatException.php rename to src/pocketmine/world/format/io/exception/UnsupportedChunkFormatException.php index e88ba4f833..3694c9f46d 100644 --- a/src/pocketmine/level/format/io/exception/UnsupportedChunkFormatException.php +++ b/src/pocketmine/world/format/io/exception/UnsupportedChunkFormatException.php @@ -21,9 +21,9 @@ declare(strict_types=1); -namespace pocketmine\level\format\io\exception; +namespace pocketmine\world\format\io\exception; -use pocketmine\level\format\ChunkException; +use pocketmine\world\format\ChunkException; class UnsupportedChunkFormatException extends ChunkException{ diff --git a/src/pocketmine/level/format/io/exception/UnsupportedLevelFormatException.php b/src/pocketmine/world/format/io/exception/UnsupportedWorldFormatException.php similarity index 86% rename from src/pocketmine/level/format/io/exception/UnsupportedLevelFormatException.php rename to src/pocketmine/world/format/io/exception/UnsupportedWorldFormatException.php index 4e0dc310c4..8ed53b84c7 100644 --- a/src/pocketmine/level/format/io/exception/UnsupportedLevelFormatException.php +++ b/src/pocketmine/world/format/io/exception/UnsupportedWorldFormatException.php @@ -21,8 +21,8 @@ declare(strict_types=1); -namespace pocketmine\level\format\io\exception; +namespace pocketmine\world\format\io\exception; -class UnsupportedLevelFormatException extends \RuntimeException{ +class UnsupportedWorldFormatException extends \RuntimeException{ } diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/world/format/io/leveldb/LevelDB.php similarity index 93% rename from src/pocketmine/level/format/io/leveldb/LevelDB.php rename to src/pocketmine/world/format/io/leveldb/LevelDB.php index 111c8f3bb3..c49ce1853a 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/world/format/io/leveldb/LevelDB.php @@ -21,22 +21,9 @@ declare(strict_types=1); -namespace pocketmine\level\format\io\leveldb; +namespace pocketmine\world\format\io\leveldb; use pocketmine\block\BlockLegacyIds; -use pocketmine\level\format\Chunk; -use pocketmine\level\format\io\BaseLevelProvider; -use pocketmine\level\format\io\ChunkUtils; -use pocketmine\level\format\io\data\BedrockLevelData; -use pocketmine\level\format\io\exception\CorruptedChunkException; -use pocketmine\level\format\io\exception\UnsupportedChunkFormatException; -use pocketmine\level\format\io\exception\UnsupportedLevelFormatException; -use pocketmine\level\format\io\LevelData; -use pocketmine\level\format\io\SubChunkConverter; -use pocketmine\level\format\io\WritableLevelProvider; -use pocketmine\level\format\PalettedBlockArray; -use pocketmine\level\format\SubChunk; -use pocketmine\level\generator\Generator; use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; @@ -45,6 +32,19 @@ use pocketmine\utils\Binary; use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; use pocketmine\utils\Utils; +use pocketmine\world\format\Chunk; +use pocketmine\world\format\io\BaseWorldProvider; +use pocketmine\world\format\io\ChunkUtils; +use pocketmine\world\format\io\data\BedrockWorldData; +use pocketmine\world\format\io\exception\CorruptedChunkException; +use pocketmine\world\format\io\exception\UnsupportedChunkFormatException; +use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; +use pocketmine\world\format\io\SubChunkConverter; +use pocketmine\world\format\io\WorldData; +use pocketmine\world\format\io\WritableWorldProvider; +use pocketmine\world\format\PalettedBlockArray; +use pocketmine\world\format\SubChunk; +use pocketmine\world\generator\Generator; use function array_flip; use function array_map; use function array_values; @@ -64,7 +64,7 @@ use function substr; use function unpack; use const LEVELDB_ZLIB_RAW_COMPRESSION; -class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ +class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ //According to Tomasso, these aren't supposed to be readable anymore. Thankfully he didn't change the readable ones... protected const TAG_DATA_2D = "\x2d"; @@ -97,11 +97,11 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ private static function checkForLevelDBExtension() : void{ if(!extension_loaded('leveldb')){ - throw new UnsupportedLevelFormatException("The leveldb PHP extension is required to use this world format"); + throw new UnsupportedWorldFormatException("The leveldb PHP extension is required to use this world format"); } if(!defined('LEVELDB_ZLIB_RAW_COMPRESSION')){ - throw new UnsupportedLevelFormatException("Given version of php-leveldb doesn't support zlib raw compression"); + throw new UnsupportedWorldFormatException("Given version of php-leveldb doesn't support zlib raw compression"); } } @@ -118,8 +118,8 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ $this->db = self::createDB($path); } - protected function loadLevelData() : LevelData{ - return new BedrockLevelData($this->getPath() . "level.dat"); + protected function loadLevelData() : WorldData{ + return new BedrockWorldData($this->getPath() . "level.dat"); } public function getWorldHeight() : int{ @@ -138,7 +138,7 @@ class LevelDB extends BaseLevelProvider implements WritableLevelProvider{ mkdir($path . "/db", 0777, true); } - BedrockLevelData::generate($path, $name, $seed, $generator, $options); + BedrockWorldData::generate($path, $name, $seed, $generator, $options); } protected function deserializePaletted(BinaryStream $stream) : PalettedBlockArray{ diff --git a/src/pocketmine/level/format/io/region/Anvil.php b/src/pocketmine/world/format/io/region/Anvil.php similarity index 89% rename from src/pocketmine/level/format/io/region/Anvil.php rename to src/pocketmine/world/format/io/region/Anvil.php index 6d81486b3c..e66e2a3452 100644 --- a/src/pocketmine/level/format/io/region/Anvil.php +++ b/src/pocketmine/world/format/io/region/Anvil.php @@ -21,13 +21,13 @@ declare(strict_types=1); -namespace pocketmine\level\format\io\region; +namespace pocketmine\world\format\io\region; -use pocketmine\level\format\io\SubChunkConverter; -use pocketmine\level\format\SubChunk; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\world\format\io\SubChunkConverter; +use pocketmine\world\format\SubChunk; -class Anvil extends RegionLevelProvider{ +class Anvil extends RegionWorldProvider{ use LegacyAnvilChunkTrait; protected function serializeSubChunk(SubChunk $subChunk) : CompoundTag{ diff --git a/src/pocketmine/level/format/io/region/CorruptedRegionException.php b/src/pocketmine/world/format/io/region/CorruptedRegionException.php similarity index 94% rename from src/pocketmine/level/format/io/region/CorruptedRegionException.php rename to src/pocketmine/world/format/io/region/CorruptedRegionException.php index 6a63080229..6c3943bcdf 100644 --- a/src/pocketmine/level/format/io/region/CorruptedRegionException.php +++ b/src/pocketmine/world/format/io/region/CorruptedRegionException.php @@ -22,7 +22,7 @@ declare(strict_types=1); -namespace pocketmine\level\format\io\region; +namespace pocketmine\world\format\io\region; class CorruptedRegionException extends RegionException{ diff --git a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php b/src/pocketmine/world/format/io/region/LegacyAnvilChunkTrait.php similarity index 93% rename from src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php rename to src/pocketmine/world/format/io/region/LegacyAnvilChunkTrait.php index 6f0df55b72..8a82aa8db7 100644 --- a/src/pocketmine/level/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/pocketmine/world/format/io/region/LegacyAnvilChunkTrait.php @@ -21,12 +21,12 @@ declare(strict_types=1); -namespace pocketmine\level\format\io\region; +namespace pocketmine\world\format\io\region; -use pocketmine\level\format\Chunk; -use pocketmine\level\format\io\ChunkUtils; -use pocketmine\level\format\io\exception\CorruptedChunkException; -use pocketmine\level\format\SubChunk; +use pocketmine\world\format\Chunk; +use pocketmine\world\format\io\ChunkUtils; +use pocketmine\world\format\io\exception\CorruptedChunkException; +use pocketmine\world\format\SubChunk; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/world/format/io/region/McRegion.php similarity index 90% rename from src/pocketmine/level/format/io/region/McRegion.php rename to src/pocketmine/world/format/io/region/McRegion.php index 56146df0a8..46e2b9f387 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/world/format/io/region/McRegion.php @@ -21,21 +21,21 @@ declare(strict_types=1); -namespace pocketmine\level\format\io\region; +namespace pocketmine\world\format\io\region; -use pocketmine\level\format\Chunk; -use pocketmine\level\format\io\ChunkUtils; -use pocketmine\level\format\io\exception\CorruptedChunkException; -use pocketmine\level\format\io\SubChunkConverter; -use pocketmine\level\format\SubChunk; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\IntArrayTag; use pocketmine\nbt\tag\ListTag; +use pocketmine\world\format\Chunk; +use pocketmine\world\format\io\ChunkUtils; +use pocketmine\world\format\io\exception\CorruptedChunkException; +use pocketmine\world\format\io\SubChunkConverter; +use pocketmine\world\format\SubChunk; use function str_repeat; -class McRegion extends RegionLevelProvider{ +class McRegion extends RegionWorldProvider{ /** * @param Chunk $chunk diff --git a/src/pocketmine/level/format/io/region/PMAnvil.php b/src/pocketmine/world/format/io/region/PMAnvil.php similarity index 89% rename from src/pocketmine/level/format/io/region/PMAnvil.php rename to src/pocketmine/world/format/io/region/PMAnvil.php index c726ea6d40..3842dff7d3 100644 --- a/src/pocketmine/level/format/io/region/PMAnvil.php +++ b/src/pocketmine/world/format/io/region/PMAnvil.php @@ -21,17 +21,17 @@ declare(strict_types=1); -namespace pocketmine\level\format\io\region; +namespace pocketmine\world\format\io\region; -use pocketmine\level\format\io\SubChunkConverter; -use pocketmine\level\format\SubChunk; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\world\format\io\SubChunkConverter; +use pocketmine\world\format\SubChunk; /** * This format is exactly the same as the PC Anvil format, with the only difference being that the stored data order * is XZY instead of YZX for more performance loading and saving worlds. */ -class PMAnvil extends RegionLevelProvider{ +class PMAnvil extends RegionWorldProvider{ use LegacyAnvilChunkTrait; protected function deserializeSubChunk(CompoundTag $subChunk) : SubChunk{ diff --git a/src/pocketmine/level/format/io/region/RegionException.php b/src/pocketmine/world/format/io/region/RegionException.php similarity index 94% rename from src/pocketmine/level/format/io/region/RegionException.php rename to src/pocketmine/world/format/io/region/RegionException.php index 4118a00d32..fc9dcdb048 100644 --- a/src/pocketmine/level/format/io/region/RegionException.php +++ b/src/pocketmine/world/format/io/region/RegionException.php @@ -22,7 +22,7 @@ declare(strict_types=1); -namespace pocketmine\level\format\io\region; +namespace pocketmine\world\format\io\region; class RegionException extends \RuntimeException{ diff --git a/src/pocketmine/level/format/io/region/RegionLoader.php b/src/pocketmine/world/format/io/region/RegionLoader.php similarity index 98% rename from src/pocketmine/level/format/io/region/RegionLoader.php rename to src/pocketmine/world/format/io/region/RegionLoader.php index 9d0aac0ff4..492a1110ad 100644 --- a/src/pocketmine/level/format/io/region/RegionLoader.php +++ b/src/pocketmine/world/format/io/region/RegionLoader.php @@ -21,10 +21,10 @@ declare(strict_types=1); -namespace pocketmine\level\format\io\region; +namespace pocketmine\world\format\io\region; -use pocketmine\level\format\ChunkException; -use pocketmine\level\format\io\exception\CorruptedChunkException; +use pocketmine\world\format\ChunkException; +use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\utils\Binary; use function ceil; use function chr; diff --git a/src/pocketmine/level/format/io/region/RegionLocationTableEntry.php b/src/pocketmine/world/format/io/region/RegionLocationTableEntry.php similarity index 98% rename from src/pocketmine/level/format/io/region/RegionLocationTableEntry.php rename to src/pocketmine/world/format/io/region/RegionLocationTableEntry.php index f17ae5bdc5..2d5c69ee60 100644 --- a/src/pocketmine/level/format/io/region/RegionLocationTableEntry.php +++ b/src/pocketmine/world/format/io/region/RegionLocationTableEntry.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\format\io\region; +namespace pocketmine\world\format\io\region; use function range; diff --git a/src/pocketmine/level/format/io/region/RegionLevelProvider.php b/src/pocketmine/world/format/io/region/RegionWorldProvider.php similarity index 89% rename from src/pocketmine/level/format/io/region/RegionLevelProvider.php rename to src/pocketmine/world/format/io/region/RegionWorldProvider.php index d0e634beaa..0fc1aed406 100644 --- a/src/pocketmine/level/format/io/region/RegionLevelProvider.php +++ b/src/pocketmine/world/format/io/region/RegionWorldProvider.php @@ -21,16 +21,16 @@ declare(strict_types=1); -namespace pocketmine\level\format\io\region; +namespace pocketmine\world\format\io\region; -use pocketmine\level\format\Chunk; -use pocketmine\level\format\io\BaseLevelProvider; -use pocketmine\level\format\io\data\JavaLevelData; -use pocketmine\level\format\io\exception\CorruptedChunkException; -use pocketmine\level\format\io\LevelData; -use pocketmine\level\generator\Generator; -use pocketmine\level\Level; use pocketmine\utils\Utils; +use pocketmine\world\format\Chunk; +use pocketmine\world\format\io\BaseWorldProvider; +use pocketmine\world\format\io\data\JavaWorldData; +use pocketmine\world\format\io\exception\CorruptedChunkException; +use pocketmine\world\format\io\WorldData; +use pocketmine\world\generator\Generator; +use pocketmine\world\World; use function assert; use function file_exists; use function is_dir; @@ -43,7 +43,7 @@ use function substr; use function time; use const SCANDIR_SORT_NONE; -abstract class RegionLevelProvider extends BaseLevelProvider{ +abstract class RegionWorldProvider extends BaseWorldProvider{ /** * Returns the file extension used for regions in this region-based format. @@ -80,14 +80,14 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ mkdir($path . "/region", 0777); } - JavaLevelData::generate($path, $name, $seed, $generator, $options, static::getPcWorldFormatVersion()); + JavaWorldData::generate($path, $name, $seed, $generator, $options, static::getPcWorldFormatVersion()); } /** @var RegionLoader[] */ protected $regions = []; - protected function loadLevelData() : LevelData{ - return new JavaLevelData($this->getPath() . "level.dat"); + protected function loadLevelData() : WorldData{ + return new JavaWorldData($this->getPath() . "level.dat"); } public function doGarbageCollection() : void{ @@ -118,7 +118,7 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ * @return RegionLoader|null */ protected function getRegion(int $regionX, int $regionZ) : ?RegionLoader{ - return $this->regions[Level::chunkHash($regionX, $regionZ)] ?? null; + return $this->regions[World::chunkHash($regionX, $regionZ)] ?? null; } /** @@ -138,7 +138,7 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ * @param int $regionZ */ protected function loadRegion(int $regionX, int $regionZ) : void{ - if(!isset($this->regions[$index = Level::chunkHash($regionX, $regionZ)])){ + if(!isset($this->regions[$index = World::chunkHash($regionX, $regionZ)])){ $path = $this->pathToRegion($regionX, $regionZ); $region = new RegionLoader($path); @@ -163,7 +163,7 @@ abstract class RegionLevelProvider extends BaseLevelProvider{ } protected function unloadRegion(int $regionX, int $regionZ) : void{ - if(isset($this->regions[$hash = Level::chunkHash($regionX, $regionZ)])){ + if(isset($this->regions[$hash = World::chunkHash($regionX, $regionZ)])){ $this->regions[$hash]->close(); unset($this->regions[$hash]); } diff --git a/src/pocketmine/level/generator/Flat.php b/src/pocketmine/world/generator/Flat.php similarity index 90% rename from src/pocketmine/level/generator/Flat.php rename to src/pocketmine/world/generator/Flat.php index 1b41e60932..1ea1b9b66a 100644 --- a/src/pocketmine/level/generator/Flat.php +++ b/src/pocketmine/world/generator/Flat.php @@ -21,16 +21,16 @@ declare(strict_types=1); -namespace pocketmine\level\generator; +namespace pocketmine\world\generator; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\item\ItemFactory; -use pocketmine\level\ChunkManager; -use pocketmine\level\format\Chunk; -use pocketmine\level\generator\object\OreType; -use pocketmine\level\generator\populator\Ore; -use pocketmine\level\generator\populator\Populator; +use pocketmine\world\ChunkManager; +use pocketmine\world\format\Chunk; +use pocketmine\world\generator\object\OreType; +use pocketmine\world\generator\populator\Ore; +use pocketmine\world\generator\populator\Populator; use function array_map; use function count; use function explode; @@ -52,14 +52,14 @@ class Flat extends Generator{ private $preset; /** - * @param ChunkManager $level + * @param ChunkManager $world * @param int $seed * @param array $options * * @throws InvalidGeneratorOptionsException */ - public function __construct(ChunkManager $level, int $seed, array $options = []){ - parent::__construct($level, $seed, $options); + public function __construct(ChunkManager $world, int $seed, array $options = []){ + parent::__construct($world, $seed, $options); if(isset($this->options["preset"]) and $this->options["preset"] != ""){ $this->preset = $this->options["preset"]; @@ -174,13 +174,13 @@ class Flat extends Generator{ $chunk = clone $this->chunk; $chunk->setX($chunkX); $chunk->setZ($chunkZ); - $this->level->setChunk($chunkX, $chunkZ, $chunk); + $this->world->setChunk($chunkX, $chunkZ, $chunk); } public function populateChunk(int $chunkX, int $chunkZ) : void{ $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed); foreach($this->populators as $populator){ - $populator->populate($this->level, $chunkX, $chunkZ, $this->random); + $populator->populate($this->world, $chunkX, $chunkZ, $this->random); } } diff --git a/src/pocketmine/level/generator/Generator.php b/src/pocketmine/world/generator/Generator.php similarity index 85% rename from src/pocketmine/level/generator/Generator.php rename to src/pocketmine/world/generator/Generator.php index 8357a8e6f4..0005138ac2 100644 --- a/src/pocketmine/level/generator/Generator.php +++ b/src/pocketmine/world/generator/Generator.php @@ -22,19 +22,19 @@ declare(strict_types=1); /** - * Noise classes used in Levels + * Noise classes used in world generation */ -namespace pocketmine\level\generator; +namespace pocketmine\world\generator; -use pocketmine\level\ChunkManager; use pocketmine\utils\Random; use pocketmine\utils\Utils; +use pocketmine\world\ChunkManager; use function ctype_digit; abstract class Generator{ /** - * Converts a string level seed into an integer for use by the generator. + * Converts a string world seed into an integer for use by the generator. * * @param string $seed * @@ -53,7 +53,7 @@ abstract class Generator{ } /** @var ChunkManager */ - protected $level; + protected $world; /** @var int */ protected $seed; /** @var array */ @@ -63,14 +63,14 @@ abstract class Generator{ protected $random; /** - * @param ChunkManager $level + * @param ChunkManager $world * @param int $seed * @param array $options * * @throws InvalidGeneratorOptionsException */ - public function __construct(ChunkManager $level, int $seed, array $options = []){ - $this->level = $level; + public function __construct(ChunkManager $world, int $seed, array $options = []){ + $this->world = $world; $this->seed = $seed; $this->options = $options; $this->random = new Random($seed); diff --git a/src/pocketmine/level/generator/GeneratorManager.php b/src/pocketmine/world/generator/GeneratorManager.php similarity index 94% rename from src/pocketmine/level/generator/GeneratorManager.php rename to src/pocketmine/world/generator/GeneratorManager.php index 765499ab32..38e40007be 100644 --- a/src/pocketmine/level/generator/GeneratorManager.php +++ b/src/pocketmine/world/generator/GeneratorManager.php @@ -21,11 +21,11 @@ declare(strict_types=1); -namespace pocketmine\level\generator; +namespace pocketmine\world\generator; -use pocketmine\level\generator\hell\Nether; -use pocketmine\level\generator\normal\Normal; use pocketmine\utils\Utils; +use pocketmine\world\generator\hell\Nether; +use pocketmine\world\generator\normal\Normal; use function array_keys; use function strtolower; @@ -45,7 +45,7 @@ final class GeneratorManager{ } /** - * @param string $class Fully qualified name of class that extends \pocketmine\level\generator\Generator + * @param string $class Fully qualified name of class that extends \pocketmine\world\generator\Generator * @param string $name Alias for this generator type that can be written in configs * @param bool $overwrite Whether to force overwriting any existing registered generator with the same name * @@ -93,7 +93,7 @@ final class GeneratorManager{ /** * Returns the registered name of the given Generator class. * - * @param string $class Fully qualified name of class that extends \pocketmine\level\generator\Generator + * @param string $class Fully qualified name of class that extends \pocketmine\world\generator\Generator * * @return string * @throws \InvalidArgumentException if the class type cannot be matched to a known alias diff --git a/src/pocketmine/level/generator/GeneratorRegisterTask.php b/src/pocketmine/world/generator/GeneratorRegisterTask.php similarity index 71% rename from src/pocketmine/level/generator/GeneratorRegisterTask.php rename to src/pocketmine/world/generator/GeneratorRegisterTask.php index ebb64e2c50..8dd110c66e 100644 --- a/src/pocketmine/level/generator/GeneratorRegisterTask.php +++ b/src/pocketmine/world/generator/GeneratorRegisterTask.php @@ -21,13 +21,13 @@ declare(strict_types=1); -namespace pocketmine\level\generator; +namespace pocketmine\world\generator; use pocketmine\block\BlockFactory; -use pocketmine\level\biome\Biome; -use pocketmine\level\Level; -use pocketmine\level\SimpleChunkManager; use pocketmine\scheduler\AsyncTask; +use pocketmine\world\biome\Biome; +use pocketmine\world\SimpleChunkManager; +use pocketmine\world\World; use function serialize; use function unserialize; @@ -36,28 +36,28 @@ class GeneratorRegisterTask extends AsyncTask{ public $generatorClass; public $settings; public $seed; - public $levelId; - public $worldHeight = Level::Y_MAX; + public $worldId; + public $worldHeight = World::Y_MAX; - public function __construct(Level $level, string $generatorClass, array $generatorSettings = []){ + public function __construct(World $world, string $generatorClass, array $generatorSettings = []){ $this->generatorClass = $generatorClass; $this->settings = serialize($generatorSettings); - $this->seed = $level->getSeed(); - $this->levelId = $level->getId(); - $this->worldHeight = $level->getWorldHeight(); + $this->seed = $world->getSeed(); + $this->worldId = $world->getId(); + $this->worldHeight = $world->getWorldHeight(); } public function onRun() : void{ BlockFactory::init(); Biome::init(); $manager = new SimpleChunkManager($this->worldHeight); - $this->worker->saveToThreadStore("generation.level{$this->levelId}.manager", $manager); + $this->worker->saveToThreadStore("generation.world{$this->worldId}.manager", $manager); /** * @var Generator $generator * @see Generator::__construct() */ $generator = new $this->generatorClass($manager, $this->seed, unserialize($this->settings)); - $this->worker->saveToThreadStore("generation.level{$this->levelId}.generator", $generator); + $this->worker->saveToThreadStore("generation.world{$this->worldId}.generator", $generator); } } diff --git a/src/pocketmine/level/generator/GeneratorUnregisterTask.php b/src/pocketmine/world/generator/GeneratorUnregisterTask.php similarity index 72% rename from src/pocketmine/level/generator/GeneratorUnregisterTask.php rename to src/pocketmine/world/generator/GeneratorUnregisterTask.php index 9732571a0c..4f7a5c7e02 100644 --- a/src/pocketmine/level/generator/GeneratorUnregisterTask.php +++ b/src/pocketmine/world/generator/GeneratorUnregisterTask.php @@ -21,21 +21,21 @@ declare(strict_types=1); -namespace pocketmine\level\generator; +namespace pocketmine\world\generator; -use pocketmine\level\Level; use pocketmine\scheduler\AsyncTask; +use pocketmine\world\World; class GeneratorUnregisterTask extends AsyncTask{ - public $levelId; + public $worldId; - public function __construct(Level $level){ - $this->levelId = $level->getId(); + public function __construct(World $world){ + $this->worldId = $world->getId(); } public function onRun() : void{ - $this->worker->removeFromThreadStore("generation.level{$this->levelId}.manager"); - $this->worker->removeFromThreadStore("generation.level{$this->levelId}.generator"); + $this->worker->removeFromThreadStore("generation.world{$this->worldId}.manager"); + $this->worker->removeFromThreadStore("generation.world{$this->worldId}.generator"); } } diff --git a/src/pocketmine/level/generator/InvalidGeneratorOptionsException.php b/src/pocketmine/world/generator/InvalidGeneratorOptionsException.php similarity index 95% rename from src/pocketmine/level/generator/InvalidGeneratorOptionsException.php rename to src/pocketmine/world/generator/InvalidGeneratorOptionsException.php index 9489589f0d..b6274f91b8 100644 --- a/src/pocketmine/level/generator/InvalidGeneratorOptionsException.php +++ b/src/pocketmine/world/generator/InvalidGeneratorOptionsException.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\generator; +namespace pocketmine\world\generator; class InvalidGeneratorOptionsException extends \UnexpectedValueException{ diff --git a/src/pocketmine/level/generator/PopulationTask.php b/src/pocketmine/world/generator/PopulationTask.php similarity index 80% rename from src/pocketmine/level/generator/PopulationTask.php rename to src/pocketmine/world/generator/PopulationTask.php index 7dcb32c325..f599dce8e6 100644 --- a/src/pocketmine/level/generator/PopulationTask.php +++ b/src/pocketmine/world/generator/PopulationTask.php @@ -21,18 +21,18 @@ declare(strict_types=1); -namespace pocketmine\level\generator; +namespace pocketmine\world\generator; -use pocketmine\level\format\Chunk; -use pocketmine\level\Level; -use pocketmine\level\SimpleChunkManager; use pocketmine\scheduler\AsyncTask; +use pocketmine\world\format\Chunk; +use pocketmine\world\SimpleChunkManager; +use pocketmine\world\World; class PopulationTask extends AsyncTask{ private const TLS_KEY_WORLD = "world"; public $state; - public $levelId; + public $worldId; public $chunk; public $chunk0; @@ -45,23 +45,23 @@ class PopulationTask extends AsyncTask{ public $chunk7; public $chunk8; - public function __construct(Level $level, Chunk $chunk){ + public function __construct(World $world, Chunk $chunk){ $this->state = true; - $this->levelId = $level->getId(); + $this->worldId = $world->getId(); $this->chunk = $chunk->fastSerialize(); - foreach($level->getAdjacentChunks($chunk->getX(), $chunk->getZ()) as $i => $c){ + foreach($world->getAdjacentChunks($chunk->getX(), $chunk->getZ()) as $i => $c){ $this->{"chunk$i"} = $c !== null ? $c->fastSerialize() : null; } - $this->storeLocal(self::TLS_KEY_WORLD, $level); + $this->storeLocal(self::TLS_KEY_WORLD, $world); } public function onRun() : void{ /** @var SimpleChunkManager $manager */ - $manager = $this->worker->getFromThreadStore("generation.level{$this->levelId}.manager"); + $manager = $this->worker->getFromThreadStore("generation.world{$this->worldId}.manager"); /** @var Generator $generator */ - $generator = $this->worker->getFromThreadStore("generation.level{$this->levelId}.generator"); + $generator = $this->worker->getFromThreadStore("generation.world{$this->worldId}.generator"); if($manager === null or $generator === null){ $this->state = false; return; @@ -138,11 +138,11 @@ class PopulationTask extends AsyncTask{ } public function onCompletion() : void{ - /** @var Level $level */ - $level = $this->fetchLocal(self::TLS_KEY_WORLD); - if(!$level->isClosed()){ + /** @var World $world */ + $world = $this->fetchLocal(self::TLS_KEY_WORLD); + if(!$world->isClosed()){ if(!$this->state){ - $level->registerGeneratorToWorker($this->worker->getAsyncWorkerId()); + $world->registerGeneratorToWorker($this->worker->getAsyncWorkerId()); } $chunk = Chunk::fastDeserialize($this->chunk); @@ -154,11 +154,11 @@ class PopulationTask extends AsyncTask{ $c = $this->{"chunk$i"}; if($c !== null){ $c = Chunk::fastDeserialize($c); - $level->generateChunkCallback($c->getX(), $c->getZ(), $this->state ? $c : null); + $world->generateChunkCallback($c->getX(), $c->getZ(), $this->state ? $c : null); } } - $level->generateChunkCallback($chunk->getX(), $chunk->getZ(), $this->state ? $chunk : null); + $world->generateChunkCallback($chunk->getX(), $chunk->getZ(), $this->state ? $chunk : null); } } } diff --git a/src/pocketmine/level/generator/biome/BiomeSelector.php b/src/pocketmine/world/generator/biome/BiomeSelector.php similarity index 93% rename from src/pocketmine/level/generator/biome/BiomeSelector.php rename to src/pocketmine/world/generator/biome/BiomeSelector.php index 6ff55e9ada..28e2fff14c 100644 --- a/src/pocketmine/level/generator/biome/BiomeSelector.php +++ b/src/pocketmine/world/generator/biome/BiomeSelector.php @@ -21,11 +21,11 @@ declare(strict_types=1); -namespace pocketmine\level\generator\biome; +namespace pocketmine\world\generator\biome; -use pocketmine\level\biome\Biome; -use pocketmine\level\biome\UnknownBiome; -use pocketmine\level\generator\noise\Simplex; +use pocketmine\world\biome\Biome; +use pocketmine\world\biome\UnknownBiome; +use pocketmine\world\generator\noise\Simplex; use pocketmine\utils\Random; abstract class BiomeSelector{ diff --git a/src/pocketmine/level/generator/hell/Nether.php b/src/pocketmine/world/generator/hell/Nether.php similarity index 81% rename from src/pocketmine/level/generator/hell/Nether.php rename to src/pocketmine/world/generator/hell/Nether.php index bb89cfedb9..da8bef88a2 100644 --- a/src/pocketmine/level/generator/hell/Nether.php +++ b/src/pocketmine/world/generator/hell/Nether.php @@ -21,16 +21,16 @@ declare(strict_types=1); -namespace pocketmine\level\generator\hell; +namespace pocketmine\world\generator\hell; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; -use pocketmine\level\biome\Biome; -use pocketmine\level\ChunkManager; -use pocketmine\level\generator\Generator; -use pocketmine\level\generator\InvalidGeneratorOptionsException; -use pocketmine\level\generator\noise\Simplex; -use pocketmine\level\generator\populator\Populator; +use pocketmine\world\biome\Biome; +use pocketmine\world\ChunkManager; +use pocketmine\world\generator\Generator; +use pocketmine\world\generator\InvalidGeneratorOptionsException; +use pocketmine\world\generator\noise\Simplex; +use pocketmine\world\generator\populator\Populator; use function abs; class Nether extends Generator{ @@ -52,14 +52,14 @@ class Nether extends Generator{ private $noiseBase; /** - * @param ChunkManager $level + * @param ChunkManager $world * @param int $seed * @param array $options * * @throws InvalidGeneratorOptionsException */ - public function __construct(ChunkManager $level, int $seed, array $options = []){ - parent::__construct($level, $seed, $options); + public function __construct(ChunkManager $world, int $seed, array $options = []){ + parent::__construct($world, $seed, $options); $this->noiseBase = new Simplex($this->random, 4, 1 / 4, 1 / 64); $this->random->setSeed($this->seed); @@ -83,7 +83,7 @@ class Nether extends Generator{ $noise = $this->noiseBase->getFastNoise3D(16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16); - $chunk = $this->level->getChunk($chunkX, $chunkZ); + $chunk = $this->world->getChunk($chunkX, $chunkZ); $bedrock = BlockFactory::get(BlockLegacyIds::BEDROCK)->getFullId(); $netherrack = BlockFactory::get(BlockLegacyIds::NETHERRACK)->getFullId(); @@ -113,18 +113,18 @@ class Nether extends Generator{ } foreach($this->generationPopulators as $populator){ - $populator->populate($this->level, $chunkX, $chunkZ, $this->random); + $populator->populate($this->world, $chunkX, $chunkZ, $this->random); } } public function populateChunk(int $chunkX, int $chunkZ) : void{ $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed); foreach($this->populators as $populator){ - $populator->populate($this->level, $chunkX, $chunkZ, $this->random); + $populator->populate($this->world, $chunkX, $chunkZ, $this->random); } - $chunk = $this->level->getChunk($chunkX, $chunkZ); + $chunk = $this->world->getChunk($chunkX, $chunkZ); $biome = Biome::getBiome($chunk->getBiomeId(7, 7)); - $biome->populateChunk($this->level, $chunkX, $chunkZ, $this->random); + $biome->populateChunk($this->world, $chunkX, $chunkZ, $this->random); } } diff --git a/src/pocketmine/level/generator/noise/Noise.php b/src/pocketmine/world/generator/noise/Noise.php similarity index 98% rename from src/pocketmine/level/generator/noise/Noise.php rename to src/pocketmine/world/generator/noise/Noise.php index 4059eb78e9..90e2b48eb9 100644 --- a/src/pocketmine/level/generator/noise/Noise.php +++ b/src/pocketmine/world/generator/noise/Noise.php @@ -22,9 +22,9 @@ declare(strict_types=1); /** - * Different noise generators for level generation + * Different noise generators for world generation */ -namespace pocketmine\level\generator\noise; +namespace pocketmine\world\generator\noise; use function array_fill; diff --git a/src/pocketmine/level/generator/noise/Simplex.php b/src/pocketmine/world/generator/noise/Simplex.php similarity index 99% rename from src/pocketmine/level/generator/noise/Simplex.php rename to src/pocketmine/world/generator/noise/Simplex.php index ea604d021c..85ee993b30 100644 --- a/src/pocketmine/level/generator/noise/Simplex.php +++ b/src/pocketmine/world/generator/noise/Simplex.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\generator\noise; +namespace pocketmine\world\generator\noise; use pocketmine\utils\Random; use const M_SQRT3; diff --git a/src/pocketmine/level/generator/normal/Normal.php b/src/pocketmine/world/generator/normal/Normal.php similarity index 86% rename from src/pocketmine/level/generator/normal/Normal.php rename to src/pocketmine/world/generator/normal/Normal.php index c6141d36a0..dd96272837 100644 --- a/src/pocketmine/level/generator/normal/Normal.php +++ b/src/pocketmine/world/generator/normal/Normal.php @@ -21,21 +21,21 @@ declare(strict_types=1); -namespace pocketmine\level\generator\normal; +namespace pocketmine\world\generator\normal; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; -use pocketmine\level\biome\Biome; -use pocketmine\level\ChunkManager; -use pocketmine\level\generator\biome\BiomeSelector; -use pocketmine\level\generator\Generator; -use pocketmine\level\generator\InvalidGeneratorOptionsException; -use pocketmine\level\generator\noise\Simplex; -use pocketmine\level\generator\object\OreType; -use pocketmine\level\generator\populator\GroundCover; -use pocketmine\level\generator\populator\Ore; -use pocketmine\level\generator\populator\Populator; -use pocketmine\level\Level; +use pocketmine\world\biome\Biome; +use pocketmine\world\ChunkManager; +use pocketmine\world\generator\biome\BiomeSelector; +use pocketmine\world\generator\Generator; +use pocketmine\world\generator\InvalidGeneratorOptionsException; +use pocketmine\world\generator\noise\Simplex; +use pocketmine\world\generator\object\OreType; +use pocketmine\world\generator\populator\GroundCover; +use pocketmine\world\generator\populator\Ore; +use pocketmine\world\generator\populator\Populator; +use pocketmine\world\World; use function exp; class Normal extends Generator{ @@ -57,14 +57,14 @@ class Normal extends Generator{ private static $SMOOTH_SIZE = 2; /** - * @param ChunkManager $level + * @param ChunkManager $world * @param int $seed * @param array $options * * @throws InvalidGeneratorOptionsException */ - public function __construct(ChunkManager $level, int $seed, array $options = []){ - parent::__construct($level, $seed, $options); + public function __construct(ChunkManager $world, int $seed, array $options = []){ + parent::__construct($world, $seed, $options); if(self::$GAUSSIAN_KERNEL === null){ self::generateKernel(); } @@ -169,7 +169,7 @@ class Normal extends Generator{ $noise = $this->noiseBase->getFastNoise3D(16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16); - $chunk = $this->level->getChunk($chunkX, $chunkZ); + $chunk = $this->world->getChunk($chunkX, $chunkZ); $biomeCache = []; @@ -194,7 +194,7 @@ class Normal extends Generator{ if($sx === 0 and $sz === 0){ $adjacent = $biome; }else{ - $index = Level::chunkHash($chunkX * 16 + $x + $sx, $chunkZ * 16 + $z + $sz); + $index = World::chunkHash($chunkX * 16 + $x + $sx, $chunkZ * 16 + $z + $sz); if(isset($biomeCache[$index])){ $adjacent = $biomeCache[$index]; }else{ @@ -231,18 +231,18 @@ class Normal extends Generator{ } foreach($this->generationPopulators as $populator){ - $populator->populate($this->level, $chunkX, $chunkZ, $this->random); + $populator->populate($this->world, $chunkX, $chunkZ, $this->random); } } public function populateChunk(int $chunkX, int $chunkZ) : void{ $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed); foreach($this->populators as $populator){ - $populator->populate($this->level, $chunkX, $chunkZ, $this->random); + $populator->populate($this->world, $chunkX, $chunkZ, $this->random); } - $chunk = $this->level->getChunk($chunkX, $chunkZ); + $chunk = $this->world->getChunk($chunkX, $chunkZ); $biome = Biome::getBiome($chunk->getBiomeId(7, 7)); - $biome->populateChunk($this->level, $chunkX, $chunkZ, $this->random); + $biome->populateChunk($this->world, $chunkX, $chunkZ, $this->random); } } diff --git a/src/pocketmine/level/generator/object/BirchTree.php b/src/pocketmine/world/generator/object/BirchTree.php similarity index 87% rename from src/pocketmine/level/generator/object/BirchTree.php rename to src/pocketmine/world/generator/object/BirchTree.php index 001e601483..65c3365e77 100644 --- a/src/pocketmine/level/generator/object/BirchTree.php +++ b/src/pocketmine/world/generator/object/BirchTree.php @@ -21,13 +21,13 @@ declare(strict_types=1); -namespace pocketmine\level\generator\object; +namespace pocketmine\world\generator\object; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\TreeType; -use pocketmine\level\ChunkManager; use pocketmine\utils\Random; +use pocketmine\world\ChunkManager; class BirchTree extends Tree{ /** @var bool */ @@ -38,11 +38,11 @@ class BirchTree extends Tree{ $this->superBirch = $superBirch; } - public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ + public function placeObject(ChunkManager $world, int $x, int $y, int $z, Random $random) : void{ $this->treeHeight = $random->nextBoundedInt(3) + 5; if($this->superBirch){ $this->treeHeight += 5; } - parent::placeObject($level, $x, $y, $z, $random); + parent::placeObject($world, $x, $y, $z, $random); } } diff --git a/src/pocketmine/level/generator/object/JungleTree.php b/src/pocketmine/world/generator/object/JungleTree.php similarity index 96% rename from src/pocketmine/level/generator/object/JungleTree.php rename to src/pocketmine/world/generator/object/JungleTree.php index bbf45c4bc9..0daeaaa67f 100644 --- a/src/pocketmine/level/generator/object/JungleTree.php +++ b/src/pocketmine/world/generator/object/JungleTree.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\generator\object; +namespace pocketmine\world\generator\object; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; diff --git a/src/pocketmine/level/generator/object/OakTree.php b/src/pocketmine/world/generator/object/OakTree.php similarity index 86% rename from src/pocketmine/level/generator/object/OakTree.php rename to src/pocketmine/world/generator/object/OakTree.php index 715798cd42..01d06425ae 100644 --- a/src/pocketmine/level/generator/object/OakTree.php +++ b/src/pocketmine/world/generator/object/OakTree.php @@ -21,13 +21,13 @@ declare(strict_types=1); -namespace pocketmine\level\generator\object; +namespace pocketmine\world\generator\object; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\TreeType; -use pocketmine\level\ChunkManager; use pocketmine\utils\Random; +use pocketmine\world\ChunkManager; class OakTree extends Tree{ @@ -35,8 +35,8 @@ class OakTree extends Tree{ parent::__construct(BlockFactory::get(BlockLegacyIds::LOG, TreeType::OAK()->getMagicNumber()), BlockFactory::get(BlockLegacyIds::LEAVES, TreeType::OAK()->getMagicNumber())); } - public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ + public function placeObject(ChunkManager $world, int $x, int $y, int $z, Random $random) : void{ $this->treeHeight = $random->nextBoundedInt(3) + 4; - parent::placeObject($level, $x, $y, $z, $random); + parent::placeObject($world, $x, $y, $z, $random); } } diff --git a/src/pocketmine/level/generator/object/Ore.php b/src/pocketmine/world/generator/object/Ore.php similarity index 86% rename from src/pocketmine/level/generator/object/Ore.php rename to src/pocketmine/world/generator/object/Ore.php index 859cc1415c..6e3981ec8f 100644 --- a/src/pocketmine/level/generator/object/Ore.php +++ b/src/pocketmine/world/generator/object/Ore.php @@ -21,12 +21,12 @@ declare(strict_types=1); -namespace pocketmine\level\generator\object; +namespace pocketmine\world\generator\object; use pocketmine\block\BlockLegacyIds; -use pocketmine\level\ChunkManager; use pocketmine\math\VectorMath; use pocketmine\utils\Random; +use pocketmine\world\ChunkManager; use function sin; use const M_PI; @@ -45,11 +45,11 @@ class Ore{ return $this->type; } - public function canPlaceObject(ChunkManager $level, int $x, int $y, int $z) : bool{ - return $level->getBlockAt($x, $y, $z)->getId() === BlockLegacyIds::STONE; + public function canPlaceObject(ChunkManager $world, int $x, int $y, int $z) : bool{ + return $world->getBlockAt($x, $y, $z)->getId() === BlockLegacyIds::STONE; } - public function placeObject(ChunkManager $level, int $x, int $y, int $z) : void{ + public function placeObject(ChunkManager $world, int $x, int $y, int $z) : void{ $clusterSize = $this->type->clusterSize; $angle = $this->random->nextFloat() * M_PI; $offset = VectorMath::getDirection2D($angle)->multiply($clusterSize / 8); @@ -86,8 +86,8 @@ class Ore{ $sizeZ = ($z + 0.5 - $seedZ) / $size; $sizeZ *= $sizeZ; - if(($sizeX + $sizeY + $sizeZ) < 1 and $level->getBlockAt($x, $y, $z)->getId() === BlockLegacyIds::STONE){ - $level->setBlockAt($x, $y, $z, $this->type->material); + if(($sizeX + $sizeY + $sizeZ) < 1 and $world->getBlockAt($x, $y, $z)->getId() === BlockLegacyIds::STONE){ + $world->setBlockAt($x, $y, $z, $this->type->material); } } } diff --git a/src/pocketmine/level/generator/object/OreType.php b/src/pocketmine/world/generator/object/OreType.php similarity index 96% rename from src/pocketmine/level/generator/object/OreType.php rename to src/pocketmine/world/generator/object/OreType.php index 84269d0727..1f10ea7b9f 100644 --- a/src/pocketmine/level/generator/object/OreType.php +++ b/src/pocketmine/world/generator/object/OreType.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\generator\object; +namespace pocketmine\world\generator\object; use pocketmine\block\Block; diff --git a/src/pocketmine/level/generator/object/SpruceTree.php b/src/pocketmine/world/generator/object/SpruceTree.php similarity index 90% rename from src/pocketmine/level/generator/object/SpruceTree.php rename to src/pocketmine/world/generator/object/SpruceTree.php index 7bc65c9d9d..59f74e83d6 100644 --- a/src/pocketmine/level/generator/object/SpruceTree.php +++ b/src/pocketmine/world/generator/object/SpruceTree.php @@ -21,14 +21,14 @@ declare(strict_types=1); -namespace pocketmine\level\generator\object; +namespace pocketmine\world\generator\object; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\TreeType; -use pocketmine\level\BlockTransaction; -use pocketmine\level\ChunkManager; use pocketmine\utils\Random; +use pocketmine\world\BlockTransaction; +use pocketmine\world\ChunkManager; use function abs; class SpruceTree extends Tree{ @@ -41,9 +41,9 @@ class SpruceTree extends Tree{ return $this->treeHeight - $random->nextBoundedInt(3); } - public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ + public function placeObject(ChunkManager $world, int $x, int $y, int $z, Random $random) : void{ $this->treeHeight = $random->nextBoundedInt(4) + 6; - parent::placeObject($level, $x, $y, $z, $random); + parent::placeObject($world, $x, $y, $z, $random); } protected function placeCanopy(int $x, int $y, int $z, Random $random, BlockTransaction $transaction) : void{ diff --git a/src/pocketmine/level/generator/object/TallGrass.php b/src/pocketmine/world/generator/object/TallGrass.php similarity index 81% rename from src/pocketmine/level/generator/object/TallGrass.php rename to src/pocketmine/world/generator/object/TallGrass.php index 34ef563b0e..eb8fc38af1 100644 --- a/src/pocketmine/level/generator/object/TallGrass.php +++ b/src/pocketmine/world/generator/object/TallGrass.php @@ -21,19 +21,19 @@ declare(strict_types=1); -namespace pocketmine\level\generator\object; +namespace pocketmine\world\generator\object; use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; -use pocketmine\level\ChunkManager; use pocketmine\math\Vector3; use pocketmine\utils\Random; +use pocketmine\world\ChunkManager; use function count; class TallGrass{ - public static function growGrass(ChunkManager $level, Vector3 $pos, Random $random, int $count = 15, int $radius = 10) : void{ + public static function growGrass(ChunkManager $world, Vector3 $pos, Random $random, int $count = 15, int $radius = 10) : void{ /** @var Block[] $arr */ $arr = [ BlockFactory::get(BlockLegacyIds::DANDELION), @@ -47,8 +47,8 @@ class TallGrass{ for($c = 0; $c < $count; ++$c){ $x = $random->nextRange($pos->x - $radius, $pos->x + $radius); $z = $random->nextRange($pos->z - $radius, $pos->z + $radius); - if($level->getBlockAt($x, $pos->y + 1, $z)->getId() === BlockLegacyIds::AIR and $level->getBlockAt($x, $pos->y, $z)->getId() === BlockLegacyIds::GRASS){ - $level->setBlockAt($x, $pos->y + 1, $z, $arr[$random->nextRange(0, $arrC)]); + if($world->getBlockAt($x, $pos->y + 1, $z)->getId() === BlockLegacyIds::AIR and $world->getBlockAt($x, $pos->y, $z)->getId() === BlockLegacyIds::GRASS){ + $world->setBlockAt($x, $pos->y + 1, $z, $arr[$random->nextRange(0, $arrC)]); } } } diff --git a/src/pocketmine/level/generator/object/Tree.php b/src/pocketmine/world/generator/object/Tree.php similarity index 88% rename from src/pocketmine/level/generator/object/Tree.php rename to src/pocketmine/world/generator/object/Tree.php index 5af5fdbe2a..eaa9142366 100644 --- a/src/pocketmine/level/generator/object/Tree.php +++ b/src/pocketmine/world/generator/object/Tree.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\generator\object; +namespace pocketmine\world\generator\object; use pocketmine\block\Block; use pocketmine\block\BlockFactory; @@ -29,9 +29,9 @@ use pocketmine\block\BlockLegacyIds; use pocketmine\block\Leaves; use pocketmine\block\Sapling; use pocketmine\block\utils\TreeType; -use pocketmine\level\BlockTransaction; -use pocketmine\level\ChunkManager; use pocketmine\utils\Random; +use pocketmine\world\BlockTransaction; +use pocketmine\world\ChunkManager; use function abs; abstract class Tree{ @@ -51,7 +51,7 @@ abstract class Tree{ } /** - * @param ChunkManager $level + * @param ChunkManager $world * @param int $x * @param int $y * @param int $z @@ -60,7 +60,7 @@ abstract class Tree{ * * @throws \InvalidArgumentException */ - public static function growTree(ChunkManager $level, int $x, int $y, int $z, Random $random, ?TreeType $type = null) : void{ + public static function growTree(ChunkManager $world, int $x, int $y, int $z, Random $random, ?TreeType $type = null) : void{ /** @var null|Tree $tree */ $tree = null; $type = $type ?? TreeType::OAK(); @@ -83,13 +83,13 @@ abstract class Tree{ //} } - if($tree !== null and $tree->canPlaceObject($level, $x, $y, $z, $random)){ - $tree->placeObject($level, $x, $y, $z, $random); + if($tree !== null and $tree->canPlaceObject($world, $x, $y, $z, $random)){ + $tree->placeObject($world, $x, $y, $z, $random); } } - public function canPlaceObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : bool{ + public function canPlaceObject(ChunkManager $world, int $x, int $y, int $z, Random $random) : bool{ $radiusToCheck = 0; for($yy = 0; $yy < $this->treeHeight + 3; ++$yy){ if($yy === 1 or $yy === $this->treeHeight){ @@ -97,7 +97,7 @@ abstract class Tree{ } for($xx = -$radiusToCheck; $xx < ($radiusToCheck + 1); ++$xx){ for($zz = -$radiusToCheck; $zz < ($radiusToCheck + 1); ++$zz){ - if(!$this->canOverride($level->getBlockAt($x + $xx, $y + $yy, $z + $zz))){ + if(!$this->canOverride($world->getBlockAt($x + $xx, $y + $yy, $z + $zz))){ return false; } } @@ -107,8 +107,8 @@ abstract class Tree{ return true; } - public function placeObject(ChunkManager $level, int $x, int $y, int $z, Random $random) : void{ - $transaction = new BlockTransaction($level); + public function placeObject(ChunkManager $world, int $x, int $y, int $z, Random $random) : void{ + $transaction = new BlockTransaction($world); $this->placeTrunk($x, $y, $z, $random, $this->generateChunkHeight($random), $transaction); $this->placeCanopy($x, $y, $z, $random, $transaction); diff --git a/src/pocketmine/level/generator/populator/GroundCover.php b/src/pocketmine/world/generator/populator/GroundCover.php similarity index 89% rename from src/pocketmine/level/generator/populator/GroundCover.php rename to src/pocketmine/world/generator/populator/GroundCover.php index 578fcd0f34..dff67ce7be 100644 --- a/src/pocketmine/level/generator/populator/GroundCover.php +++ b/src/pocketmine/world/generator/populator/GroundCover.php @@ -21,21 +21,21 @@ declare(strict_types=1); -namespace pocketmine\level\generator\populator; +namespace pocketmine\world\generator\populator; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\block\Liquid; -use pocketmine\level\biome\Biome; -use pocketmine\level\ChunkManager; use pocketmine\utils\Random; +use pocketmine\world\biome\Biome; +use pocketmine\world\ChunkManager; use function count; use function min; class GroundCover extends Populator{ - public function populate(ChunkManager $level, int $chunkX, int $chunkZ, Random $random) : void{ - $chunk = $level->getChunk($chunkX, $chunkZ); + public function populate(ChunkManager $world, int $chunkX, int $chunkZ, Random $random) : void{ + $chunk = $world->getChunk($chunkX, $chunkZ); for($x = 0; $x < 16; ++$x){ for($z = 0; $z < 16; ++$z){ $biome = Biome::getBiome($chunk->getBiomeId($x, $z)); diff --git a/src/pocketmine/level/generator/populator/Ore.php b/src/pocketmine/world/generator/populator/Ore.php similarity index 79% rename from src/pocketmine/level/generator/populator/Ore.php rename to src/pocketmine/world/generator/populator/Ore.php index 0b7f982e81..8590852d8c 100644 --- a/src/pocketmine/level/generator/populator/Ore.php +++ b/src/pocketmine/world/generator/populator/Ore.php @@ -21,26 +21,26 @@ declare(strict_types=1); -namespace pocketmine\level\generator\populator; +namespace pocketmine\world\generator\populator; -use pocketmine\level\ChunkManager; -use pocketmine\level\generator\object\Ore as ObjectOre; -use pocketmine\level\generator\object\OreType; use pocketmine\utils\Random; +use pocketmine\world\ChunkManager; +use pocketmine\world\generator\object\Ore as ObjectOre; +use pocketmine\world\generator\object\OreType; class Ore extends Populator{ /** @var OreType[] */ private $oreTypes = []; - public function populate(ChunkManager $level, int $chunkX, int $chunkZ, Random $random) : void{ + public function populate(ChunkManager $world, int $chunkX, int $chunkZ, Random $random) : void{ foreach($this->oreTypes as $type){ $ore = new ObjectOre($random, $type); for($i = 0; $i < $ore->type->clusterCount; ++$i){ $x = $random->nextRange($chunkX << 4, ($chunkX << 4) + 15); $y = $random->nextRange($ore->type->minHeight, $ore->type->maxHeight); $z = $random->nextRange($chunkZ << 4, ($chunkZ << 4) + 15); - if($ore->canPlaceObject($level, $x, $y, $z)){ - $ore->placeObject($level, $x, $y, $z); + if($ore->canPlaceObject($world, $x, $y, $z)){ + $ore->placeObject($world, $x, $y, $z); } } } diff --git a/src/pocketmine/level/generator/populator/Populator.php b/src/pocketmine/world/generator/populator/Populator.php similarity index 84% rename from src/pocketmine/level/generator/populator/Populator.php rename to src/pocketmine/world/generator/populator/Populator.php index c913e7a618..5c43d964c9 100644 --- a/src/pocketmine/level/generator/populator/Populator.php +++ b/src/pocketmine/world/generator/populator/Populator.php @@ -24,18 +24,18 @@ declare(strict_types=1); /** * All the Object populator classes */ -namespace pocketmine\level\generator\populator; +namespace pocketmine\world\generator\populator; -use pocketmine\level\ChunkManager; use pocketmine\utils\Random; +use pocketmine\world\ChunkManager; abstract class Populator{ /** - * @param ChunkManager $level + * @param ChunkManager $world * @param int $chunkX * @param int $chunkZ * @param Random $random */ - abstract public function populate(ChunkManager $level, int $chunkX, int $chunkZ, Random $random) : void; + abstract public function populate(ChunkManager $world, int $chunkX, int $chunkZ, Random $random) : void; } diff --git a/src/pocketmine/level/generator/populator/TallGrass.php b/src/pocketmine/world/generator/populator/TallGrass.php similarity index 83% rename from src/pocketmine/level/generator/populator/TallGrass.php rename to src/pocketmine/world/generator/populator/TallGrass.php index 88d21690fa..d46026744c 100644 --- a/src/pocketmine/level/generator/populator/TallGrass.php +++ b/src/pocketmine/world/generator/populator/TallGrass.php @@ -21,16 +21,16 @@ declare(strict_types=1); -namespace pocketmine\level\generator\populator; +namespace pocketmine\world\generator\populator; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; -use pocketmine\level\ChunkManager; use pocketmine\utils\Random; +use pocketmine\world\ChunkManager; class TallGrass extends Populator{ /** @var ChunkManager */ - private $level; + private $world; private $randomAmount; private $baseAmount; @@ -42,8 +42,8 @@ class TallGrass extends Populator{ $this->baseAmount = $amount; } - public function populate(ChunkManager $level, int $chunkX, int $chunkZ, Random $random) : void{ - $this->level = $level; + public function populate(ChunkManager $world, int $chunkX, int $chunkZ, Random $random) : void{ + $this->world = $world; $amount = $random->nextRange(0, $this->randomAmount + 1) + $this->baseAmount; $block = BlockFactory::get(BlockLegacyIds::TALL_GRASS, 1); @@ -53,19 +53,19 @@ class TallGrass extends Populator{ $y = $this->getHighestWorkableBlock($x, $z); if($y !== -1 and $this->canTallGrassStay($x, $y, $z)){ - $this->level->setBlockAt($x, $y, $z, $block); + $this->world->setBlockAt($x, $y, $z, $block); } } } private function canTallGrassStay(int $x, int $y, int $z) : bool{ - $b = $this->level->getBlockAt($x, $y, $z)->getId(); - return ($b === BlockLegacyIds::AIR or $b === BlockLegacyIds::SNOW_LAYER) and $this->level->getBlockAt($x, $y - 1, $z)->getId() === BlockLegacyIds::GRASS; + $b = $this->world->getBlockAt($x, $y, $z)->getId(); + return ($b === BlockLegacyIds::AIR or $b === BlockLegacyIds::SNOW_LAYER) and $this->world->getBlockAt($x, $y - 1, $z)->getId() === BlockLegacyIds::GRASS; } private function getHighestWorkableBlock(int $x, int $z) : int{ for($y = 127; $y >= 0; --$y){ - $b = $this->level->getBlockAt($x, $y, $z)->getId(); + $b = $this->world->getBlockAt($x, $y, $z)->getId(); if($b !== BlockLegacyIds::AIR and $b !== BlockLegacyIds::LEAVES and $b !== BlockLegacyIds::LEAVES2 and $b !== BlockLegacyIds::SNOW_LAYER){ break; } diff --git a/src/pocketmine/level/generator/populator/Tree.php b/src/pocketmine/world/generator/populator/Tree.php similarity index 84% rename from src/pocketmine/level/generator/populator/Tree.php rename to src/pocketmine/world/generator/populator/Tree.php index ca7be9e2c4..cc577d9b9c 100644 --- a/src/pocketmine/level/generator/populator/Tree.php +++ b/src/pocketmine/world/generator/populator/Tree.php @@ -21,17 +21,17 @@ declare(strict_types=1); -namespace pocketmine\level\generator\populator; +namespace pocketmine\world\generator\populator; use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\TreeType; -use pocketmine\level\ChunkManager; -use pocketmine\level\generator\object\Tree as ObjectTree; use pocketmine\utils\Random; +use pocketmine\world\ChunkManager; +use pocketmine\world\generator\object\Tree as ObjectTree; class Tree extends Populator{ /** @var ChunkManager */ - private $level; + private $world; private $randomAmount; private $baseAmount; @@ -53,8 +53,8 @@ class Tree extends Populator{ $this->baseAmount = $amount; } - public function populate(ChunkManager $level, int $chunkX, int $chunkZ, Random $random) : void{ - $this->level = $level; + public function populate(ChunkManager $world, int $chunkX, int $chunkZ, Random $random) : void{ + $this->world = $world; $amount = $random->nextRange(0, $this->randomAmount + 1) + $this->baseAmount; for($i = 0; $i < $amount; ++$i){ $x = $random->nextRange($chunkX << 4, ($chunkX << 4) + 15); @@ -63,13 +63,13 @@ class Tree extends Populator{ if($y === -1){ continue; } - ObjectTree::growTree($this->level, $x, $y, $z, $random, $this->type); + ObjectTree::growTree($this->world, $x, $y, $z, $random, $this->type); } } private function getHighestWorkableBlock(int $x, int $z) : int{ for($y = 127; $y > 0; --$y){ - $b = $this->level->getBlockAt($x, $y, $z)->getId(); + $b = $this->world->getBlockAt($x, $y, $z)->getId(); if($b === BlockLegacyIds::DIRT or $b === BlockLegacyIds::GRASS){ break; }elseif($b !== BlockLegacyIds::AIR and $b !== BlockLegacyIds::SNOW_LAYER){ diff --git a/src/pocketmine/level/light/BlockLightUpdate.php b/src/pocketmine/world/light/BlockLightUpdate.php similarity index 97% rename from src/pocketmine/level/light/BlockLightUpdate.php rename to src/pocketmine/world/light/BlockLightUpdate.php index 1538165819..bfc014fd40 100644 --- a/src/pocketmine/level/light/BlockLightUpdate.php +++ b/src/pocketmine/world/light/BlockLightUpdate.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\light; +namespace pocketmine\world\light; class BlockLightUpdate extends LightUpdate{ diff --git a/src/pocketmine/level/light/LightPopulationTask.php b/src/pocketmine/world/light/LightPopulationTask.php similarity index 78% rename from src/pocketmine/level/light/LightPopulationTask.php rename to src/pocketmine/world/light/LightPopulationTask.php index fdff68f6ce..1c1e7c7e8a 100644 --- a/src/pocketmine/level/light/LightPopulationTask.php +++ b/src/pocketmine/world/light/LightPopulationTask.php @@ -21,20 +21,20 @@ declare(strict_types=1); -namespace pocketmine\level\light; +namespace pocketmine\world\light; use pocketmine\block\BlockFactory; -use pocketmine\level\format\Chunk; -use pocketmine\level\Level; use pocketmine\scheduler\AsyncTask; +use pocketmine\world\format\Chunk; +use pocketmine\world\World; class LightPopulationTask extends AsyncTask{ private const TLS_KEY_WORLD = "world"; public $chunk; - public function __construct(Level $level, Chunk $chunk){ - $this->storeLocal(self::TLS_KEY_WORLD, $level); + public function __construct(World $world, Chunk $chunk){ + $this->storeLocal(self::TLS_KEY_WORLD, $world); $this->chunk = $chunk->fastSerialize(); } @@ -53,12 +53,12 @@ class LightPopulationTask extends AsyncTask{ } public function onCompletion() : void{ - /** @var Level $level */ - $level = $this->fetchLocal(self::TLS_KEY_WORLD); - if(!$level->isClosed()){ + /** @var World $world */ + $world = $this->fetchLocal(self::TLS_KEY_WORLD); + if(!$world->isClosed()){ /** @var Chunk $chunk */ $chunk = Chunk::fastDeserialize($this->chunk); - $level->generateChunkCallback($chunk->getX(), $chunk->getZ(), $chunk); + $world->generateChunkCallback($chunk->getX(), $chunk->getZ(), $chunk); } } } diff --git a/src/pocketmine/level/light/LightUpdate.php b/src/pocketmine/world/light/LightUpdate.php similarity index 87% rename from src/pocketmine/level/light/LightUpdate.php rename to src/pocketmine/world/light/LightUpdate.php index c141b2ee34..fe0d153ae2 100644 --- a/src/pocketmine/level/light/LightUpdate.php +++ b/src/pocketmine/world/light/LightUpdate.php @@ -21,18 +21,18 @@ declare(strict_types=1); -namespace pocketmine\level\light; +namespace pocketmine\world\light; use pocketmine\block\BlockFactory; -use pocketmine\level\ChunkManager; -use pocketmine\level\Level; -use pocketmine\level\utils\SubChunkIteratorManager; +use pocketmine\world\ChunkManager; +use pocketmine\world\utils\SubChunkIteratorManager; +use pocketmine\world\World; //TODO: make light updates asynchronous abstract class LightUpdate{ /** @var ChunkManager */ - protected $level; + protected $world; /** @var int[] blockhash => new light level */ protected $updateNodes = []; @@ -49,12 +49,12 @@ abstract class LightUpdate{ /** @var SubChunkIteratorManager */ protected $subChunkHandler; - public function __construct(ChunkManager $level){ - $this->level = $level; + public function __construct(ChunkManager $world){ + $this->world = $world; $this->removalQueue = new \SplQueue(); $this->spreadQueue = new \SplQueue(); - $this->subChunkHandler = new SubChunkIteratorManager($this->level); + $this->subChunkHandler = new SubChunkIteratorManager($this->world); } abstract protected function getLight(int $x, int $y, int $z) : int; @@ -62,7 +62,7 @@ abstract class LightUpdate{ abstract protected function setLight(int $x, int $y, int $z, int $level) : void; public function setAndUpdateLight(int $x, int $y, int $z, int $newLevel) : void{ - $this->updateNodes[Level::blockHash($x, $y, $z)] = [$x, $y, $z, $newLevel]; + $this->updateNodes[World::blockHash($x, $y, $z)] = [$x, $y, $z, $newLevel]; } private function prepareNodes() : void{ @@ -109,7 +109,7 @@ abstract class LightUpdate{ while(!$this->spreadQueue->isEmpty()){ list($x, $y, $z) = $this->spreadQueue->dequeue(); - unset($this->spreadVisited[Level::blockHash($x, $y, $z)]); + unset($this->spreadVisited[World::blockHash($x, $y, $z)]); if(!$this->subChunkHandler->moveTo($x, $y, $z)){ continue; @@ -143,14 +143,14 @@ abstract class LightUpdate{ if($current !== 0 and $current < $oldAdjacentLevel){ $this->setLight($x, $y, $z, 0); - if(!isset($this->removalVisited[$index = Level::blockHash($x, $y, $z)])){ + if(!isset($this->removalVisited[$index = World::blockHash($x, $y, $z)])){ $this->removalVisited[$index] = true; if($current > 1){ $this->removalQueue->enqueue([$x, $y, $z, $current]); } } }elseif($current >= $oldAdjacentLevel){ - if(!isset($this->spreadVisited[$index = Level::blockHash($x, $y, $z)])){ + if(!isset($this->spreadVisited[$index = World::blockHash($x, $y, $z)])){ $this->spreadVisited[$index] = true; $this->spreadQueue->enqueue([$x, $y, $z]); } @@ -164,7 +164,7 @@ abstract class LightUpdate{ if($current < $potentialLight){ $this->setLight($x, $y, $z, $potentialLight); - if(!isset($this->spreadVisited[$index = Level::blockHash($x, $y, $z)]) and $potentialLight > 1){ + if(!isset($this->spreadVisited[$index = World::blockHash($x, $y, $z)]) and $potentialLight > 1){ $this->spreadVisited[$index] = true; $this->spreadQueue->enqueue([$x, $y, $z]); } diff --git a/src/pocketmine/level/light/SkyLightUpdate.php b/src/pocketmine/world/light/SkyLightUpdate.php similarity index 97% rename from src/pocketmine/level/light/SkyLightUpdate.php rename to src/pocketmine/world/light/SkyLightUpdate.php index bc6666b691..2241604192 100644 --- a/src/pocketmine/level/light/SkyLightUpdate.php +++ b/src/pocketmine/world/light/SkyLightUpdate.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\light; +namespace pocketmine\world\light; class SkyLightUpdate extends LightUpdate{ diff --git a/src/pocketmine/level/particle/AngryVillagerParticle.php b/src/pocketmine/world/particle/AngryVillagerParticle.php similarity index 96% rename from src/pocketmine/level/particle/AngryVillagerParticle.php rename to src/pocketmine/world/particle/AngryVillagerParticle.php index 5841170c89..c265c34f17 100644 --- a/src/pocketmine/level/particle/AngryVillagerParticle.php +++ b/src/pocketmine/world/particle/AngryVillagerParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/BlockForceFieldParticle.php b/src/pocketmine/world/particle/BlockForceFieldParticle.php similarity index 96% rename from src/pocketmine/level/particle/BlockForceFieldParticle.php rename to src/pocketmine/world/particle/BlockForceFieldParticle.php index 2da0a9aa60..2ea6e5e185 100644 --- a/src/pocketmine/level/particle/BlockForceFieldParticle.php +++ b/src/pocketmine/world/particle/BlockForceFieldParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/BubbleParticle.php b/src/pocketmine/world/particle/BubbleParticle.php similarity index 96% rename from src/pocketmine/level/particle/BubbleParticle.php rename to src/pocketmine/world/particle/BubbleParticle.php index 777eade96a..47e9618ad3 100644 --- a/src/pocketmine/level/particle/BubbleParticle.php +++ b/src/pocketmine/world/particle/BubbleParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/CriticalParticle.php b/src/pocketmine/world/particle/CriticalParticle.php similarity index 96% rename from src/pocketmine/level/particle/CriticalParticle.php rename to src/pocketmine/world/particle/CriticalParticle.php index 17e7ca1284..b35ca50751 100644 --- a/src/pocketmine/level/particle/CriticalParticle.php +++ b/src/pocketmine/world/particle/CriticalParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/DestroyBlockParticle.php b/src/pocketmine/world/particle/DestroyBlockParticle.php similarity index 96% rename from src/pocketmine/level/particle/DestroyBlockParticle.php rename to src/pocketmine/world/particle/DestroyBlockParticle.php index 98126e7cec..71fe7075d8 100644 --- a/src/pocketmine/level/particle/DestroyBlockParticle.php +++ b/src/pocketmine/world/particle/DestroyBlockParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\block\Block; use pocketmine\math\Vector3; diff --git a/src/pocketmine/level/particle/DragonEggTeleportParticle.php b/src/pocketmine/world/particle/DragonEggTeleportParticle.php similarity index 97% rename from src/pocketmine/level/particle/DragonEggTeleportParticle.php rename to src/pocketmine/world/particle/DragonEggTeleportParticle.php index 96bb822c8f..b8a615f8e3 100644 --- a/src/pocketmine/level/particle/DragonEggTeleportParticle.php +++ b/src/pocketmine/world/particle/DragonEggTeleportParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/particle/DustParticle.php b/src/pocketmine/world/particle/DustParticle.php similarity index 96% rename from src/pocketmine/level/particle/DustParticle.php rename to src/pocketmine/world/particle/DustParticle.php index bd3b40d142..483e87cd80 100644 --- a/src/pocketmine/level/particle/DustParticle.php +++ b/src/pocketmine/world/particle/DustParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/EnchantParticle.php b/src/pocketmine/world/particle/EnchantParticle.php similarity index 96% rename from src/pocketmine/level/particle/EnchantParticle.php rename to src/pocketmine/world/particle/EnchantParticle.php index 5be274b692..abe6a151ca 100644 --- a/src/pocketmine/level/particle/EnchantParticle.php +++ b/src/pocketmine/world/particle/EnchantParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/EnchantmentTableParticle.php b/src/pocketmine/world/particle/EnchantmentTableParticle.php similarity index 96% rename from src/pocketmine/level/particle/EnchantmentTableParticle.php rename to src/pocketmine/world/particle/EnchantmentTableParticle.php index bd6e288dbf..2ccf221663 100644 --- a/src/pocketmine/level/particle/EnchantmentTableParticle.php +++ b/src/pocketmine/world/particle/EnchantmentTableParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/EndermanTeleportParticle.php b/src/pocketmine/world/particle/EndermanTeleportParticle.php similarity index 96% rename from src/pocketmine/level/particle/EndermanTeleportParticle.php rename to src/pocketmine/world/particle/EndermanTeleportParticle.php index cb117e107d..18689d9a99 100644 --- a/src/pocketmine/level/particle/EndermanTeleportParticle.php +++ b/src/pocketmine/world/particle/EndermanTeleportParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/particle/EntityFlameParticle.php b/src/pocketmine/world/particle/EntityFlameParticle.php similarity index 96% rename from src/pocketmine/level/particle/EntityFlameParticle.php rename to src/pocketmine/world/particle/EntityFlameParticle.php index e3a94c53c8..7274a73767 100644 --- a/src/pocketmine/level/particle/EntityFlameParticle.php +++ b/src/pocketmine/world/particle/EntityFlameParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/ExplodeParticle.php b/src/pocketmine/world/particle/ExplodeParticle.php similarity index 96% rename from src/pocketmine/level/particle/ExplodeParticle.php rename to src/pocketmine/world/particle/ExplodeParticle.php index 962f576550..239459f722 100644 --- a/src/pocketmine/level/particle/ExplodeParticle.php +++ b/src/pocketmine/world/particle/ExplodeParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/FlameParticle.php b/src/pocketmine/world/particle/FlameParticle.php similarity index 96% rename from src/pocketmine/level/particle/FlameParticle.php rename to src/pocketmine/world/particle/FlameParticle.php index 41a6433192..e117192f36 100644 --- a/src/pocketmine/level/particle/FlameParticle.php +++ b/src/pocketmine/world/particle/FlameParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/FloatingTextParticle.php b/src/pocketmine/world/particle/FloatingTextParticle.php similarity index 98% rename from src/pocketmine/level/particle/FloatingTextParticle.php rename to src/pocketmine/world/particle/FloatingTextParticle.php index 1eef46fd84..d8efe445bf 100644 --- a/src/pocketmine/level/particle/FloatingTextParticle.php +++ b/src/pocketmine/world/particle/FloatingTextParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\entity\EntityFactory; use pocketmine\entity\Skin; diff --git a/src/pocketmine/level/particle/GenericParticle.php b/src/pocketmine/world/particle/GenericParticle.php similarity index 96% rename from src/pocketmine/level/particle/GenericParticle.php rename to src/pocketmine/world/particle/GenericParticle.php index 892dad64af..778a184414 100644 --- a/src/pocketmine/level/particle/GenericParticle.php +++ b/src/pocketmine/world/particle/GenericParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/particle/HappyVillagerParticle.php b/src/pocketmine/world/particle/HappyVillagerParticle.php similarity index 96% rename from src/pocketmine/level/particle/HappyVillagerParticle.php rename to src/pocketmine/world/particle/HappyVillagerParticle.php index 71ce2d6b67..bb452744ee 100644 --- a/src/pocketmine/level/particle/HappyVillagerParticle.php +++ b/src/pocketmine/world/particle/HappyVillagerParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/HeartParticle.php b/src/pocketmine/world/particle/HeartParticle.php similarity index 96% rename from src/pocketmine/level/particle/HeartParticle.php rename to src/pocketmine/world/particle/HeartParticle.php index dc196ca3b4..e115976d48 100644 --- a/src/pocketmine/level/particle/HeartParticle.php +++ b/src/pocketmine/world/particle/HeartParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/HugeExplodeParticle.php b/src/pocketmine/world/particle/HugeExplodeParticle.php similarity index 96% rename from src/pocketmine/level/particle/HugeExplodeParticle.php rename to src/pocketmine/world/particle/HugeExplodeParticle.php index 26f80fc759..fe0d67ecc6 100644 --- a/src/pocketmine/level/particle/HugeExplodeParticle.php +++ b/src/pocketmine/world/particle/HugeExplodeParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/HugeExplodeSeedParticle.php b/src/pocketmine/world/particle/HugeExplodeSeedParticle.php similarity index 96% rename from src/pocketmine/level/particle/HugeExplodeSeedParticle.php rename to src/pocketmine/world/particle/HugeExplodeSeedParticle.php index 409d08a2ec..153d05f738 100644 --- a/src/pocketmine/level/particle/HugeExplodeSeedParticle.php +++ b/src/pocketmine/world/particle/HugeExplodeSeedParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/InkParticle.php b/src/pocketmine/world/particle/InkParticle.php similarity index 96% rename from src/pocketmine/level/particle/InkParticle.php rename to src/pocketmine/world/particle/InkParticle.php index 7a6e8d6af7..b7e88531af 100644 --- a/src/pocketmine/level/particle/InkParticle.php +++ b/src/pocketmine/world/particle/InkParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/InstantEnchantParticle.php b/src/pocketmine/world/particle/InstantEnchantParticle.php similarity index 96% rename from src/pocketmine/level/particle/InstantEnchantParticle.php rename to src/pocketmine/world/particle/InstantEnchantParticle.php index da58d16960..4a49833a2b 100644 --- a/src/pocketmine/level/particle/InstantEnchantParticle.php +++ b/src/pocketmine/world/particle/InstantEnchantParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/ItemBreakParticle.php b/src/pocketmine/world/particle/ItemBreakParticle.php similarity index 96% rename from src/pocketmine/level/particle/ItemBreakParticle.php rename to src/pocketmine/world/particle/ItemBreakParticle.php index 3e706c6876..574c3dcdaa 100644 --- a/src/pocketmine/level/particle/ItemBreakParticle.php +++ b/src/pocketmine/world/particle/ItemBreakParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\item\Item; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/LavaDripParticle.php b/src/pocketmine/world/particle/LavaDripParticle.php similarity index 96% rename from src/pocketmine/level/particle/LavaDripParticle.php rename to src/pocketmine/world/particle/LavaDripParticle.php index 6ca209e0b8..adf6d7163e 100644 --- a/src/pocketmine/level/particle/LavaDripParticle.php +++ b/src/pocketmine/world/particle/LavaDripParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/LavaParticle.php b/src/pocketmine/world/particle/LavaParticle.php similarity index 96% rename from src/pocketmine/level/particle/LavaParticle.php rename to src/pocketmine/world/particle/LavaParticle.php index 9a3e65e66f..c9eafc2dcc 100644 --- a/src/pocketmine/level/particle/LavaParticle.php +++ b/src/pocketmine/world/particle/LavaParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/MobSpawnParticle.php b/src/pocketmine/world/particle/MobSpawnParticle.php similarity index 97% rename from src/pocketmine/level/particle/MobSpawnParticle.php rename to src/pocketmine/world/particle/MobSpawnParticle.php index 5955a2c887..6ebe243a2a 100644 --- a/src/pocketmine/level/particle/MobSpawnParticle.php +++ b/src/pocketmine/world/particle/MobSpawnParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/particle/Particle.php b/src/pocketmine/world/particle/Particle.php similarity index 96% rename from src/pocketmine/level/particle/Particle.php rename to src/pocketmine/world/particle/Particle.php index ab393ecfd0..b800a66d96 100644 --- a/src/pocketmine/level/particle/Particle.php +++ b/src/pocketmine/world/particle/Particle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\ClientboundPacket; diff --git a/src/pocketmine/level/particle/PortalParticle.php b/src/pocketmine/world/particle/PortalParticle.php similarity index 96% rename from src/pocketmine/level/particle/PortalParticle.php rename to src/pocketmine/world/particle/PortalParticle.php index 9175d3a6ba..fa511145e7 100644 --- a/src/pocketmine/level/particle/PortalParticle.php +++ b/src/pocketmine/world/particle/PortalParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/PotionSplashParticle.php b/src/pocketmine/world/particle/PotionSplashParticle.php similarity index 97% rename from src/pocketmine/level/particle/PotionSplashParticle.php rename to src/pocketmine/world/particle/PotionSplashParticle.php index 73b91632d3..70ccd96329 100644 --- a/src/pocketmine/level/particle/PotionSplashParticle.php +++ b/src/pocketmine/world/particle/PotionSplashParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/particle/RainSplashParticle.php b/src/pocketmine/world/particle/RainSplashParticle.php similarity index 96% rename from src/pocketmine/level/particle/RainSplashParticle.php rename to src/pocketmine/world/particle/RainSplashParticle.php index 20ca50ec0f..cafa5b3243 100644 --- a/src/pocketmine/level/particle/RainSplashParticle.php +++ b/src/pocketmine/world/particle/RainSplashParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/RedstoneParticle.php b/src/pocketmine/world/particle/RedstoneParticle.php similarity index 96% rename from src/pocketmine/level/particle/RedstoneParticle.php rename to src/pocketmine/world/particle/RedstoneParticle.php index 15b464e4bf..13fbacba78 100644 --- a/src/pocketmine/level/particle/RedstoneParticle.php +++ b/src/pocketmine/world/particle/RedstoneParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/SmokeParticle.php b/src/pocketmine/world/particle/SmokeParticle.php similarity index 96% rename from src/pocketmine/level/particle/SmokeParticle.php rename to src/pocketmine/world/particle/SmokeParticle.php index f057c5ed5d..501e373e1d 100644 --- a/src/pocketmine/level/particle/SmokeParticle.php +++ b/src/pocketmine/world/particle/SmokeParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/SnowballPoofParticle.php b/src/pocketmine/world/particle/SnowballPoofParticle.php similarity index 96% rename from src/pocketmine/level/particle/SnowballPoofParticle.php rename to src/pocketmine/world/particle/SnowballPoofParticle.php index 24e8d14c12..b5b4f1fc15 100644 --- a/src/pocketmine/level/particle/SnowballPoofParticle.php +++ b/src/pocketmine/world/particle/SnowballPoofParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/SplashParticle.php b/src/pocketmine/world/particle/SplashParticle.php similarity index 96% rename from src/pocketmine/level/particle/SplashParticle.php rename to src/pocketmine/world/particle/SplashParticle.php index b79e8ee07b..8d9e965960 100644 --- a/src/pocketmine/level/particle/SplashParticle.php +++ b/src/pocketmine/world/particle/SplashParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/SporeParticle.php b/src/pocketmine/world/particle/SporeParticle.php similarity index 96% rename from src/pocketmine/level/particle/SporeParticle.php rename to src/pocketmine/world/particle/SporeParticle.php index 846c7149ef..23e2b3e0a8 100644 --- a/src/pocketmine/level/particle/SporeParticle.php +++ b/src/pocketmine/world/particle/SporeParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/TerrainParticle.php b/src/pocketmine/world/particle/TerrainParticle.php similarity index 96% rename from src/pocketmine/level/particle/TerrainParticle.php rename to src/pocketmine/world/particle/TerrainParticle.php index 296934af87..2514cc66a8 100644 --- a/src/pocketmine/level/particle/TerrainParticle.php +++ b/src/pocketmine/world/particle/TerrainParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\block\Block; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/WaterDripParticle.php b/src/pocketmine/world/particle/WaterDripParticle.php similarity index 96% rename from src/pocketmine/level/particle/WaterDripParticle.php rename to src/pocketmine/world/particle/WaterDripParticle.php index 6a8431fa28..65b2f12e21 100644 --- a/src/pocketmine/level/particle/WaterDripParticle.php +++ b/src/pocketmine/world/particle/WaterDripParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/particle/WaterParticle.php b/src/pocketmine/world/particle/WaterParticle.php similarity index 96% rename from src/pocketmine/level/particle/WaterParticle.php rename to src/pocketmine/world/particle/WaterParticle.php index fb85ff9d62..473a226e09 100644 --- a/src/pocketmine/level/particle/WaterParticle.php +++ b/src/pocketmine/world/particle/WaterParticle.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\particle; +namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; diff --git a/src/pocketmine/level/sound/AnvilBreakSound.php b/src/pocketmine/world/sound/AnvilBreakSound.php similarity index 96% rename from src/pocketmine/level/sound/AnvilBreakSound.php rename to src/pocketmine/world/sound/AnvilBreakSound.php index a7dc6a2a7f..7a75dd415d 100644 --- a/src/pocketmine/level/sound/AnvilBreakSound.php +++ b/src/pocketmine/world/sound/AnvilBreakSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/sound/AnvilFallSound.php b/src/pocketmine/world/sound/AnvilFallSound.php similarity index 96% rename from src/pocketmine/level/sound/AnvilFallSound.php rename to src/pocketmine/world/sound/AnvilFallSound.php index 82fa3c4801..08aebde71e 100644 --- a/src/pocketmine/level/sound/AnvilFallSound.php +++ b/src/pocketmine/world/sound/AnvilFallSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/sound/AnvilUseSound.php b/src/pocketmine/world/sound/AnvilUseSound.php similarity index 96% rename from src/pocketmine/level/sound/AnvilUseSound.php rename to src/pocketmine/world/sound/AnvilUseSound.php index d3862c2d8e..090289a3d4 100644 --- a/src/pocketmine/level/sound/AnvilUseSound.php +++ b/src/pocketmine/world/sound/AnvilUseSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/sound/ArrowHitSound.php b/src/pocketmine/world/sound/ArrowHitSound.php similarity index 96% rename from src/pocketmine/level/sound/ArrowHitSound.php rename to src/pocketmine/world/sound/ArrowHitSound.php index e19bdd16a2..0490d5fa8d 100644 --- a/src/pocketmine/level/sound/ArrowHitSound.php +++ b/src/pocketmine/world/sound/ArrowHitSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; diff --git a/src/pocketmine/level/sound/BlazeShootSound.php b/src/pocketmine/world/sound/BlazeShootSound.php similarity index 96% rename from src/pocketmine/level/sound/BlazeShootSound.php rename to src/pocketmine/world/sound/BlazeShootSound.php index c9d32f4bdc..97ac023ccb 100644 --- a/src/pocketmine/level/sound/BlazeShootSound.php +++ b/src/pocketmine/world/sound/BlazeShootSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/sound/BlockBreakSound.php b/src/pocketmine/world/sound/BlockBreakSound.php similarity index 97% rename from src/pocketmine/level/sound/BlockBreakSound.php rename to src/pocketmine/world/sound/BlockBreakSound.php index c951b0c7ab..32ea532daa 100644 --- a/src/pocketmine/level/sound/BlockBreakSound.php +++ b/src/pocketmine/world/sound/BlockBreakSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\block\Block; use pocketmine\math\Vector3; diff --git a/src/pocketmine/level/sound/BlockPlaceSound.php b/src/pocketmine/world/sound/BlockPlaceSound.php similarity index 97% rename from src/pocketmine/level/sound/BlockPlaceSound.php rename to src/pocketmine/world/sound/BlockPlaceSound.php index 1d0b8b75c4..3f5427472a 100644 --- a/src/pocketmine/level/sound/BlockPlaceSound.php +++ b/src/pocketmine/world/sound/BlockPlaceSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\block\Block; use pocketmine\math\Vector3; diff --git a/src/pocketmine/level/sound/BowShootSound.php b/src/pocketmine/world/sound/BowShootSound.php similarity index 96% rename from src/pocketmine/level/sound/BowShootSound.php rename to src/pocketmine/world/sound/BowShootSound.php index 139abbf342..00355b17fd 100644 --- a/src/pocketmine/level/sound/BowShootSound.php +++ b/src/pocketmine/world/sound/BowShootSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; diff --git a/src/pocketmine/level/sound/BucketEmptyLavaSound.php b/src/pocketmine/world/sound/BucketEmptyLavaSound.php similarity index 96% rename from src/pocketmine/level/sound/BucketEmptyLavaSound.php rename to src/pocketmine/world/sound/BucketEmptyLavaSound.php index 2549334003..d33fa5d156 100644 --- a/src/pocketmine/level/sound/BucketEmptyLavaSound.php +++ b/src/pocketmine/world/sound/BucketEmptyLavaSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; diff --git a/src/pocketmine/level/sound/BucketEmptyWaterSound.php b/src/pocketmine/world/sound/BucketEmptyWaterSound.php similarity index 96% rename from src/pocketmine/level/sound/BucketEmptyWaterSound.php rename to src/pocketmine/world/sound/BucketEmptyWaterSound.php index 11995a2c07..47a4686d33 100644 --- a/src/pocketmine/level/sound/BucketEmptyWaterSound.php +++ b/src/pocketmine/world/sound/BucketEmptyWaterSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; diff --git a/src/pocketmine/level/sound/BucketFillLavaSound.php b/src/pocketmine/world/sound/BucketFillLavaSound.php similarity index 96% rename from src/pocketmine/level/sound/BucketFillLavaSound.php rename to src/pocketmine/world/sound/BucketFillLavaSound.php index f2c88090d9..83cebdc0f9 100644 --- a/src/pocketmine/level/sound/BucketFillLavaSound.php +++ b/src/pocketmine/world/sound/BucketFillLavaSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; diff --git a/src/pocketmine/level/sound/BucketFillWaterSound.php b/src/pocketmine/world/sound/BucketFillWaterSound.php similarity index 96% rename from src/pocketmine/level/sound/BucketFillWaterSound.php rename to src/pocketmine/world/sound/BucketFillWaterSound.php index de146e5ec1..24bb709838 100644 --- a/src/pocketmine/level/sound/BucketFillWaterSound.php +++ b/src/pocketmine/world/sound/BucketFillWaterSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; diff --git a/src/pocketmine/level/sound/ChestCloseSound.php b/src/pocketmine/world/sound/ChestCloseSound.php similarity index 96% rename from src/pocketmine/level/sound/ChestCloseSound.php rename to src/pocketmine/world/sound/ChestCloseSound.php index 3d19f8bd7c..78fc5e740d 100644 --- a/src/pocketmine/level/sound/ChestCloseSound.php +++ b/src/pocketmine/world/sound/ChestCloseSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; diff --git a/src/pocketmine/level/sound/ChestOpenSound.php b/src/pocketmine/world/sound/ChestOpenSound.php similarity index 96% rename from src/pocketmine/level/sound/ChestOpenSound.php rename to src/pocketmine/world/sound/ChestOpenSound.php index 5eb1f9d27a..33dde66272 100644 --- a/src/pocketmine/level/sound/ChestOpenSound.php +++ b/src/pocketmine/world/sound/ChestOpenSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; diff --git a/src/pocketmine/level/sound/ClickSound.php b/src/pocketmine/world/sound/ClickSound.php similarity index 96% rename from src/pocketmine/level/sound/ClickSound.php rename to src/pocketmine/world/sound/ClickSound.php index 79509bd8e3..cec95842de 100644 --- a/src/pocketmine/level/sound/ClickSound.php +++ b/src/pocketmine/world/sound/ClickSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/sound/DoorBumpSound.php b/src/pocketmine/world/sound/DoorBumpSound.php similarity index 96% rename from src/pocketmine/level/sound/DoorBumpSound.php rename to src/pocketmine/world/sound/DoorBumpSound.php index 88dac8efae..7ae4e0c923 100644 --- a/src/pocketmine/level/sound/DoorBumpSound.php +++ b/src/pocketmine/world/sound/DoorBumpSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/sound/DoorCrashSound.php b/src/pocketmine/world/sound/DoorCrashSound.php similarity index 96% rename from src/pocketmine/level/sound/DoorCrashSound.php rename to src/pocketmine/world/sound/DoorCrashSound.php index 6946593ede..d702e83f53 100644 --- a/src/pocketmine/level/sound/DoorCrashSound.php +++ b/src/pocketmine/world/sound/DoorCrashSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/sound/DoorSound.php b/src/pocketmine/world/sound/DoorSound.php similarity index 96% rename from src/pocketmine/level/sound/DoorSound.php rename to src/pocketmine/world/sound/DoorSound.php index ee5a526747..7799422581 100644 --- a/src/pocketmine/level/sound/DoorSound.php +++ b/src/pocketmine/world/sound/DoorSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/sound/EnderChestCloseSound.php b/src/pocketmine/world/sound/EnderChestCloseSound.php similarity index 96% rename from src/pocketmine/level/sound/EnderChestCloseSound.php rename to src/pocketmine/world/sound/EnderChestCloseSound.php index f6446c446c..d092646c20 100644 --- a/src/pocketmine/level/sound/EnderChestCloseSound.php +++ b/src/pocketmine/world/sound/EnderChestCloseSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; diff --git a/src/pocketmine/level/sound/EnderChestOpenSound.php b/src/pocketmine/world/sound/EnderChestOpenSound.php similarity index 96% rename from src/pocketmine/level/sound/EnderChestOpenSound.php rename to src/pocketmine/world/sound/EnderChestOpenSound.php index e2cba0e19b..e8b02367fd 100644 --- a/src/pocketmine/level/sound/EnderChestOpenSound.php +++ b/src/pocketmine/world/sound/EnderChestOpenSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; diff --git a/src/pocketmine/level/sound/EndermanTeleportSound.php b/src/pocketmine/world/sound/EndermanTeleportSound.php similarity index 96% rename from src/pocketmine/level/sound/EndermanTeleportSound.php rename to src/pocketmine/world/sound/EndermanTeleportSound.php index ab8801657f..d29787a4eb 100644 --- a/src/pocketmine/level/sound/EndermanTeleportSound.php +++ b/src/pocketmine/world/sound/EndermanTeleportSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/sound/ExplodeSound.php b/src/pocketmine/world/sound/ExplodeSound.php similarity index 96% rename from src/pocketmine/level/sound/ExplodeSound.php rename to src/pocketmine/world/sound/ExplodeSound.php index cee3fbd2fa..11849ef1f8 100644 --- a/src/pocketmine/level/sound/ExplodeSound.php +++ b/src/pocketmine/world/sound/ExplodeSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; diff --git a/src/pocketmine/level/sound/FizzSound.php b/src/pocketmine/world/sound/FizzSound.php similarity index 96% rename from src/pocketmine/level/sound/FizzSound.php rename to src/pocketmine/world/sound/FizzSound.php index 09fb4b9af4..52d525620f 100644 --- a/src/pocketmine/level/sound/FizzSound.php +++ b/src/pocketmine/world/sound/FizzSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/sound/FlintSteelSound.php b/src/pocketmine/world/sound/FlintSteelSound.php similarity index 96% rename from src/pocketmine/level/sound/FlintSteelSound.php rename to src/pocketmine/world/sound/FlintSteelSound.php index a4240c4751..94d130bdfa 100644 --- a/src/pocketmine/level/sound/FlintSteelSound.php +++ b/src/pocketmine/world/sound/FlintSteelSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; diff --git a/src/pocketmine/level/sound/GhastShootSound.php b/src/pocketmine/world/sound/GhastShootSound.php similarity index 96% rename from src/pocketmine/level/sound/GhastShootSound.php rename to src/pocketmine/world/sound/GhastShootSound.php index 0d2b3fe64f..c376afbf55 100644 --- a/src/pocketmine/level/sound/GhastShootSound.php +++ b/src/pocketmine/world/sound/GhastShootSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/sound/GhastSound.php b/src/pocketmine/world/sound/GhastSound.php similarity index 96% rename from src/pocketmine/level/sound/GhastSound.php rename to src/pocketmine/world/sound/GhastSound.php index 13cd6509fd..3b29b1d79f 100644 --- a/src/pocketmine/level/sound/GhastSound.php +++ b/src/pocketmine/world/sound/GhastSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/sound/IgniteSound.php b/src/pocketmine/world/sound/IgniteSound.php similarity index 96% rename from src/pocketmine/level/sound/IgniteSound.php rename to src/pocketmine/world/sound/IgniteSound.php index 3fa28fface..4d70f65c5f 100644 --- a/src/pocketmine/level/sound/IgniteSound.php +++ b/src/pocketmine/world/sound/IgniteSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/sound/ItemBreakSound.php b/src/pocketmine/world/sound/ItemBreakSound.php similarity index 96% rename from src/pocketmine/level/sound/ItemBreakSound.php rename to src/pocketmine/world/sound/ItemBreakSound.php index 35cf8e2587..d1246c712c 100644 --- a/src/pocketmine/level/sound/ItemBreakSound.php +++ b/src/pocketmine/world/sound/ItemBreakSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; diff --git a/src/pocketmine/level/sound/LaunchSound.php b/src/pocketmine/world/sound/LaunchSound.php similarity index 96% rename from src/pocketmine/level/sound/LaunchSound.php rename to src/pocketmine/world/sound/LaunchSound.php index 243c5fc2e1..7b02daff6f 100644 --- a/src/pocketmine/level/sound/LaunchSound.php +++ b/src/pocketmine/world/sound/LaunchSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/sound/LevelEventSound.php b/src/pocketmine/world/sound/LevelEventSound.php similarity index 97% rename from src/pocketmine/level/sound/LevelEventSound.php rename to src/pocketmine/world/sound/LevelEventSound.php index 37c6ee3164..1e2d75b454 100644 --- a/src/pocketmine/level/sound/LevelEventSound.php +++ b/src/pocketmine/world/sound/LevelEventSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/sound/PopSound.php b/src/pocketmine/world/sound/PopSound.php similarity index 96% rename from src/pocketmine/level/sound/PopSound.php rename to src/pocketmine/world/sound/PopSound.php index 126ca9366f..e74a253523 100644 --- a/src/pocketmine/level/sound/PopSound.php +++ b/src/pocketmine/world/sound/PopSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/sound/PotionSplashSound.php b/src/pocketmine/world/sound/PotionSplashSound.php similarity index 96% rename from src/pocketmine/level/sound/PotionSplashSound.php rename to src/pocketmine/world/sound/PotionSplashSound.php index af5473efd5..24ce0fcdf7 100644 --- a/src/pocketmine/level/sound/PotionSplashSound.php +++ b/src/pocketmine/world/sound/PotionSplashSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; diff --git a/src/pocketmine/level/sound/RedstonePowerOffSound.php b/src/pocketmine/world/sound/RedstonePowerOffSound.php similarity index 96% rename from src/pocketmine/level/sound/RedstonePowerOffSound.php rename to src/pocketmine/world/sound/RedstonePowerOffSound.php index 24505d11a5..5e2dcf16e6 100644 --- a/src/pocketmine/level/sound/RedstonePowerOffSound.php +++ b/src/pocketmine/world/sound/RedstonePowerOffSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; diff --git a/src/pocketmine/level/sound/RedstonePowerOnSound.php b/src/pocketmine/world/sound/RedstonePowerOnSound.php similarity index 96% rename from src/pocketmine/level/sound/RedstonePowerOnSound.php rename to src/pocketmine/world/sound/RedstonePowerOnSound.php index 3abae67788..bcd2389396 100644 --- a/src/pocketmine/level/sound/RedstonePowerOnSound.php +++ b/src/pocketmine/world/sound/RedstonePowerOnSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; diff --git a/src/pocketmine/level/sound/Sound.php b/src/pocketmine/world/sound/Sound.php similarity index 96% rename from src/pocketmine/level/sound/Sound.php rename to src/pocketmine/world/sound/Sound.php index 83f1ff4435..63f6739be4 100644 --- a/src/pocketmine/level/sound/Sound.php +++ b/src/pocketmine/world/sound/Sound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\ClientboundPacket; diff --git a/src/pocketmine/level/sound/ThrowSound.php b/src/pocketmine/world/sound/ThrowSound.php similarity index 96% rename from src/pocketmine/level/sound/ThrowSound.php rename to src/pocketmine/world/sound/ThrowSound.php index 0d6a84fe87..bc387654a2 100644 --- a/src/pocketmine/level/sound/ThrowSound.php +++ b/src/pocketmine/world/sound/ThrowSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; diff --git a/src/pocketmine/level/sound/TotemUseSound.php b/src/pocketmine/world/sound/TotemUseSound.php similarity index 96% rename from src/pocketmine/level/sound/TotemUseSound.php rename to src/pocketmine/world/sound/TotemUseSound.php index 8f67a7e69d..20d3810f2d 100644 --- a/src/pocketmine/level/sound/TotemUseSound.php +++ b/src/pocketmine/world/sound/TotemUseSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/sound/XpCollectSound.php b/src/pocketmine/world/sound/XpCollectSound.php similarity index 96% rename from src/pocketmine/level/sound/XpCollectSound.php rename to src/pocketmine/world/sound/XpCollectSound.php index 2374699dda..8b3994eccf 100644 --- a/src/pocketmine/level/sound/XpCollectSound.php +++ b/src/pocketmine/world/sound/XpCollectSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; diff --git a/src/pocketmine/level/sound/XpLevelUpSound.php b/src/pocketmine/world/sound/XpLevelUpSound.php similarity index 97% rename from src/pocketmine/level/sound/XpLevelUpSound.php rename to src/pocketmine/world/sound/XpLevelUpSound.php index 0020e0ea6a..e173ca7be0 100644 --- a/src/pocketmine/level/sound/XpLevelUpSound.php +++ b/src/pocketmine/world/sound/XpLevelUpSound.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\sound; +namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; diff --git a/src/pocketmine/level/utils/SubChunkIteratorManager.php b/src/pocketmine/world/utils/SubChunkIteratorManager.php similarity index 83% rename from src/pocketmine/level/utils/SubChunkIteratorManager.php rename to src/pocketmine/world/utils/SubChunkIteratorManager.php index 62bcf2dfca..ef1e6cdee1 100644 --- a/src/pocketmine/level/utils/SubChunkIteratorManager.php +++ b/src/pocketmine/world/utils/SubChunkIteratorManager.php @@ -21,16 +21,16 @@ declare(strict_types=1); -namespace pocketmine\level\utils; +namespace pocketmine\world\utils; -use pocketmine\level\ChunkManager; -use pocketmine\level\format\Chunk; -use pocketmine\level\format\EmptySubChunk; -use pocketmine\level\format\SubChunkInterface; +use pocketmine\world\ChunkManager; +use pocketmine\world\format\Chunk; +use pocketmine\world\format\EmptySubChunk; +use pocketmine\world\format\SubChunkInterface; class SubChunkIteratorManager{ /** @var ChunkManager */ - public $level; + public $world; /** @var Chunk|null */ public $currentChunk; @@ -46,8 +46,8 @@ class SubChunkIteratorManager{ /** @var bool */ protected $allocateEmptySubs = true; - public function __construct(ChunkManager $level, bool $allocateEmptySubs = true){ - $this->level = $level; + public function __construct(ChunkManager $world, bool $allocateEmptySubs = true){ + $this->world = $world; $this->allocateEmptySubs = $allocateEmptySubs; } @@ -57,7 +57,7 @@ class SubChunkIteratorManager{ $this->currentZ = $z >> 4; $this->currentSubChunk = null; - $this->currentChunk = $this->level->getChunk($this->currentX, $this->currentZ); + $this->currentChunk = $this->world->getChunk($this->currentX, $this->currentZ); if($this->currentChunk === null){ return false; } diff --git a/tests/phpunit/level/format/io/AbstractLevelProvider.php b/tests/phpunit/level/format/io/AbstractWorldProvider.php similarity index 87% rename from tests/phpunit/level/format/io/AbstractLevelProvider.php rename to tests/phpunit/level/format/io/AbstractWorldProvider.php index 7f63048e17..29e78451ee 100644 --- a/tests/phpunit/level/format/io/AbstractLevelProvider.php +++ b/tests/phpunit/level/format/io/AbstractWorldProvider.php @@ -21,8 +21,8 @@ declare(strict_types=1); -namespace pocketmine\level\format\io; +namespace pocketmine\world\format\io; -abstract class AbstractLevelProvider implements LevelProvider{ +abstract class AbstractWorldProvider implements WorldProvider{ } diff --git a/tests/phpunit/level/format/io/InterfaceLevelProvider.php b/tests/phpunit/level/format/io/InterfaceWorldProvider.php similarity index 88% rename from tests/phpunit/level/format/io/InterfaceLevelProvider.php rename to tests/phpunit/level/format/io/InterfaceWorldProvider.php index e01f08e43e..baaa3337d1 100644 --- a/tests/phpunit/level/format/io/InterfaceLevelProvider.php +++ b/tests/phpunit/level/format/io/InterfaceWorldProvider.php @@ -21,8 +21,8 @@ declare(strict_types=1); -namespace pocketmine\level\format\io; +namespace pocketmine\world\format\io; -interface InterfaceLevelProvider extends LevelProvider{ +interface InterfaceWorldProvider extends WorldProvider{ } diff --git a/tests/phpunit/level/format/io/LevelProviderManagerTest.php b/tests/phpunit/level/format/io/LevelProviderManagerTest.php index 10c484a76d..738a16bc3e 100644 --- a/tests/phpunit/level/format/io/LevelProviderManagerTest.php +++ b/tests/phpunit/level/format/io/LevelProviderManagerTest.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\level\format\io; +namespace pocketmine\world\format\io; use PHPUnit\Framework\TestCase; @@ -30,24 +30,24 @@ class LevelProviderManagerTest extends TestCase{ public function testAddNonClassProvider() : void{ $this->expectException(\InvalidArgumentException::class); - LevelProviderManager::addProvider("lol", "nope"); + WorldProviderManager::addProvider("lol", "nope"); } public function testAddAbstractClassProvider() : void{ $this->expectException(\InvalidArgumentException::class); - LevelProviderManager::addProvider(AbstractLevelProvider::class, "abstract"); + WorldProviderManager::addProvider(AbstractWorldProvider::class, "abstract"); } public function testAddInterfaceProvider() : void{ $this->expectException(\InvalidArgumentException::class); - LevelProviderManager::addProvider(InterfaceLevelProvider::class, "interface"); + WorldProviderManager::addProvider(InterfaceWorldProvider::class, "interface"); } public function testAddWrongClassProvider() : void{ $this->expectException(\InvalidArgumentException::class); - LevelProviderManager::addProvider(LevelProviderManagerTest::class, "bad_class"); + WorldProviderManager::addProvider(LevelProviderManagerTest::class, "bad_class"); } } diff --git a/src/pocketmine/level/format/io/SubChunkConverter.php b/tests/phpunit/level/format/io/SubChunkConverter.php similarity index 86% rename from src/pocketmine/level/format/io/SubChunkConverter.php rename to tests/phpunit/level/format/io/SubChunkConverter.php index 8aaab68ce1..a5f6d4dfa5 100644 --- a/src/pocketmine/level/format/io/SubChunkConverter.php +++ b/tests/phpunit/level/format/io/SubChunkConverter.php @@ -21,12 +21,13 @@ declare(strict_types=1); -namespace pocketmine\level\format\io; +namespace pocketmine\world\format\io; -use pocketmine\level\format\PalettedBlockArray; +use pocketmine\world\format\PalettedBlockArray; die("This is a stub file for code completion purposes"); +//TODO: this can't be moved right now because of compatibility issues with the extension class SubChunkConverter{ public static function convertSubChunkXZY(string $idArray, string $metaArray) : PalettedBlockArray{} diff --git a/tests/phpunit/level/format/io/region/RegionLoaderTest.php b/tests/phpunit/level/format/io/region/RegionLoaderTest.php index 39b69bc4f1..3ed4c4a73c 100644 --- a/tests/phpunit/level/format/io/region/RegionLoaderTest.php +++ b/tests/phpunit/level/format/io/region/RegionLoaderTest.php @@ -21,10 +21,10 @@ declare(strict_types=1); -namespace pocketmine\level\format\io\region; +namespace pocketmine\world\format\io\region; use PHPUnit\Framework\TestCase; -use pocketmine\level\format\ChunkException; +use pocketmine\world\format\ChunkException; use function file_exists; use function random_bytes; use function str_repeat; @@ -105,11 +105,12 @@ class RegionLoaderTest extends TestCase{ /** * @dataProvider outOfBoundsCoordsProvider + * * @param int $x * @param int $z * * @throws \InvalidArgumentException - * @throws \pocketmine\level\format\io\exception\CorruptedChunkException + * @throws \pocketmine\world\format\io\exception\CorruptedChunkException */ public function testReadChunkOutOfBounds(int $x, int $z) : void{ $this->expectException(\InvalidArgumentException::class); diff --git a/tests/preprocessor b/tests/preprocessor index b01f50c50e..63e0092d62 160000 --- a/tests/preprocessor +++ b/tests/preprocessor @@ -1 +1 @@ -Subproject commit b01f50c50ef6546d000bdde16dc868b4147b31ba +Subproject commit 63e0092d623d13e47f9083b3d65fdf431933a471 From 00944eff721eb11b67cf514680eb59182c008d7a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 May 2019 17:37:10 +0100 Subject: [PATCH 0777/3224] Removed EntityWorldChangeEvent there's nothing that can be done with this event that can't be done with EntityTeleportEvent. Having this extra event needlessly increases system complexity. --- src/pocketmine/entity/Entity.php | 7 --- .../event/entity/EntityWorldChangeEvent.php | 52 ------------------- 2 files changed, 59 deletions(-) delete mode 100644 src/pocketmine/event/entity/EntityWorldChangeEvent.php diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 71c8f5e705..6c16ac7a95 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -34,7 +34,6 @@ use pocketmine\event\entity\EntityMotionEvent; use pocketmine\event\entity\EntityRegainHealthEvent; use pocketmine\event\entity\EntitySpawnEvent; use pocketmine\event\entity\EntityTeleportEvent; -use pocketmine\event\entity\EntityWorldChangeEvent; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; use pocketmine\math\Facing; @@ -1569,12 +1568,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } if($this->isValid()){ - $ev = new EntityWorldChangeEvent($this, $this->world, $targetWorld); - $ev->call(); - if($ev->isCancelled()){ - return false; - } - $this->world->removeEntity($this); if($this->chunk !== null){ $this->chunk->removeEntity($this); diff --git a/src/pocketmine/event/entity/EntityWorldChangeEvent.php b/src/pocketmine/event/entity/EntityWorldChangeEvent.php deleted file mode 100644 index fc020a7a45..0000000000 --- a/src/pocketmine/event/entity/EntityWorldChangeEvent.php +++ /dev/null @@ -1,52 +0,0 @@ -entity = $entity; - $this->originWorld = $originWorld; - $this->targetWorld = $targetWorld; - } - - public function getOrigin() : World{ - return $this->originWorld; - } - - public function getTarget() : World{ - return $this->targetWorld; - } -} From 66481fedebf6108ce95aa6e80039799e2c9292e2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 May 2019 17:38:33 +0100 Subject: [PATCH 0778/3224] Entity: Protect internal methods setPosition() and setPositionAndRotation() teleport() should be used instead (or setRotation() for rotation-only changes). --- src/pocketmine/entity/Entity.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 6c16ac7a95..a17b9f0914 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -1412,7 +1412,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ return $this->asLocation(); } - public function setPosition(Vector3 $pos) : bool{ + protected function setPosition(Vector3 $pos) : bool{ if($this->closed){ return false; } @@ -1442,7 +1442,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->scheduleUpdate(); } - public function setPositionAndRotation(Vector3 $pos, float $yaw, float $pitch) : bool{ + protected function setPositionAndRotation(Vector3 $pos, float $yaw, float $pitch) : bool{ if($this->setPosition($pos)){ $this->setRotation($yaw, $pitch); From d7a7ab5102164f05a5447eec8241300e9a3457d8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 May 2019 18:01:23 +0100 Subject: [PATCH 0779/3224] Move Entity despawn logic back to Player this is not network-session specific, and different implementations will need to do this. --- src/pocketmine/Player.php | 5 +++++ src/pocketmine/network/mcpe/NetworkSession.php | 6 +----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index a470e21802..b7a7f9def2 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -956,6 +956,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $world = $world ?? $this->world; $index = World::chunkHash($x, $z); if(isset($this->usedChunks[$index])){ + foreach($this->getWorld()->getChunkEntities($x, $z) as $entity){ + if($entity !== $this){ + $entity->despawnFrom($this); + } + } $this->networkSession->stopUsingChunk($x, $z); unset($this->usedChunks[$index]); } diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index f28d3b44ad..508f3b2664 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -790,11 +790,7 @@ class NetworkSession{ } public function stopUsingChunk(int $chunkX, int $chunkZ) : void{ - foreach($this->player->getWorld()->getChunkEntities($chunkX, $chunkZ) as $entity){ - if($entity !== $this->player){ - $entity->despawnFrom($this->player); - } - } + } public function tick() : bool{ From c1a483a36d308353a37c6988cc17e6e90ffa87ab Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 May 2019 18:35:04 +0100 Subject: [PATCH 0780/3224] move entity spawning logic back to Player --- src/pocketmine/Player.php | 25 +++++++++++++++---- .../network/mcpe/NetworkSession.php | 25 +++++++++---------- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index b7a7f9def2..492a58d8b6 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -977,12 +977,27 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, assert(isset($this->usedChunks[World::chunkHash($x, $z)])); $this->usedChunks[World::chunkHash($x, $z)] = true; - $spawn = $this->spawnChunkLoadCount++ === $this->spawnThreshold; - $this->networkSession->startUsingChunk($x, $z, $spawn); + $this->networkSession->startUsingChunk($x, $z, function(int $chunkX, int $chunkZ) : void{ + if($this->spawned){ + $this->spawnEntitiesOnChunk($chunkX, $chunkZ); + }elseif($this->spawnChunkLoadCount++ === $this->spawnThreshold){ + $this->spawned = true; - if($spawn){ - //TODO: not sure this should be here - $this->spawned = true; + foreach($this->usedChunks as $chunkHash => $_){ + World::getXZ($chunkHash, $_x, $_z); + $this->spawnEntitiesOnChunk($_x, $_z); + } + + $this->networkSession->onTerrainReady(); + } + }); + } + + protected function spawnEntitiesOnChunk(int $chunkX, int $chunkZ) : void{ + foreach($this->world->getChunkEntities($chunkX, $chunkZ) as $entity){ + if($entity !== $this and !$entity->isClosed() and !$entity->isFlaggedForDespawn()){ + $entity->spawnTo($this); + } } } diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 508f3b2664..ba9e465b06 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -69,6 +69,7 @@ use pocketmine\PlayerInfo; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\BinaryDataException; +use pocketmine\utils\Utils; use pocketmine\world\Position; use function bin2hex; use function count; @@ -760,28 +761,26 @@ class NetworkSession{ return $this->sendDataPacket($pk); } - public function startUsingChunk(int $chunkX, int $chunkZ, bool $spawn = false) : void{ + /** + * Instructs the networksession to start using the chunk at the given coordinates. This may occur asynchronously. + * @param int $chunkX + * @param int $chunkZ + * @param \Closure $onCompletion To be called when chunk sending has completed. + */ + public function startUsingChunk(int $chunkX, int $chunkZ, \Closure $onCompletion) : void{ + Utils::validateCallableSignature(function(int $chunkX, int $chunkZ){}, $onCompletion); + ChunkCache::getInstance($this->player->getWorld())->request($chunkX, $chunkZ)->onResolve( //this callback may be called synchronously or asynchronously, depending on whether the promise is resolved yet - function(CompressBatchPromise $promise) use($chunkX, $chunkZ, $spawn){ + function(CompressBatchPromise $promise) use($chunkX, $chunkZ, $onCompletion){ if(!$this->isConnected()){ return; } $this->player->world->timings->syncChunkSendTimer->startTiming(); try{ $this->queueCompressed($promise); - - foreach($this->player->getWorld()->getChunkEntities($chunkX, $chunkZ) as $entity){ - if($entity !== $this->player and !$entity->isClosed() and !$entity->isFlaggedForDespawn()){ - $entity->spawnTo($this->player); - } - } - - if($spawn){ - //TODO: potential race condition during chunk sending could cause this to be called too early - $this->onTerrainReady(); - } + $onCompletion($chunkX, $chunkZ); }finally{ $this->player->world->timings->syncChunkSendTimer->stopTiming(); } From 51548d1a27a1e827933c6c35dcc8221741d57038 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 May 2019 18:51:26 +0100 Subject: [PATCH 0781/3224] World: remove useless internal function this just complicates the logic for no reason. It had a purpose once, but no longer. --- src/pocketmine/world/World.php | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index a18d03da69..b97ab5ccac 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -2416,16 +2416,6 @@ class World implements ChunkManager, Metadatable{ $this->chunkSendQueue[$index][spl_object_id($player)] = $player; } - private function onChunkReady(int $x, int $z){ - if(isset($this->chunkSendQueue[$index = World::chunkHash($x, $z)])){ - foreach($this->chunkSendQueue[$index] as $player){ - /** @var Player $player */ - $player->onChunkReady($x, $z); - } - unset($this->chunkSendQueue[$index]); - } - } - private function processChunkRequests(){ if(count($this->chunkSendQueue) > 0){ $this->timings->syncChunkSendTimer->startTiming(); @@ -2439,10 +2429,16 @@ class World implements ChunkManager, Metadatable{ if($chunk === null or !$chunk->isGenerated() or !$chunk->isPopulated()){ throw new ChunkException("Invalid Chunk sent"); } - $this->onChunkReady($x, $z); + + foreach($players as $player){ + $player->onChunkReady($x, $z); + } + $this->timings->syncChunkSendPrepareTimer->stopTiming(); } + $this->chunkSendQueue = []; + $this->timings->syncChunkSendTimer->stopTiming(); } } From 78bb6f4a0c9c6190c701514a0b64694a68af4a2f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 May 2019 19:26:01 +0100 Subject: [PATCH 0782/3224] Reduce complexity of chunk sending system --- src/pocketmine/Player.php | 41 +++++++++++++-------------------- src/pocketmine/world/World.php | 42 ---------------------------------- 2 files changed, 16 insertions(+), 67 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 492a58d8b6..ed92972909 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -969,30 +969,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, unset($this->loadQueue[$index]); } - public function onChunkReady(int $x, int $z){ - if(!$this->isConnected()){ - return; - } - - assert(isset($this->usedChunks[World::chunkHash($x, $z)])); - $this->usedChunks[World::chunkHash($x, $z)] = true; - - $this->networkSession->startUsingChunk($x, $z, function(int $chunkX, int $chunkZ) : void{ - if($this->spawned){ - $this->spawnEntitiesOnChunk($chunkX, $chunkZ); - }elseif($this->spawnChunkLoadCount++ === $this->spawnThreshold){ - $this->spawned = true; - - foreach($this->usedChunks as $chunkHash => $_){ - World::getXZ($chunkHash, $_x, $_z); - $this->spawnEntitiesOnChunk($_x, $_z); - } - - $this->networkSession->onTerrainReady(); - } - }); - } - protected function spawnEntitiesOnChunk(int $chunkX, int $chunkZ) : void{ foreach($this->world->getChunkEntities($chunkX, $chunkZ) as $entity){ if($entity !== $this and !$entity->isClosed() and !$entity->isFlaggedForDespawn()){ @@ -1030,7 +1006,22 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } unset($this->loadQueue[$index]); - $this->world->requestChunk($X, $Z, $this); + $this->usedChunks[$index] = true; + + $this->networkSession->startUsingChunk($X, $Z, function(int $chunkX, int $chunkZ) : void{ + if($this->spawned){ + $this->spawnEntitiesOnChunk($chunkX, $chunkZ); + }elseif($this->spawnChunkLoadCount++ === $this->spawnThreshold){ + $this->spawned = true; + + foreach($this->usedChunks as $chunkHash => $_){ + World::getXZ($chunkHash, $_x, $_z); + $this->spawnEntitiesOnChunk($_x, $_z); + } + + $this->networkSession->onTerrainReady(); + } + }); } Timings::$playerChunkSendTimer->stopTiming(); diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index b97ab5ccac..5ec6013734 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -70,7 +70,6 @@ use pocketmine\timings\Timings; use pocketmine\utils\ReversePriorityQueue; use pocketmine\world\biome\Biome; use pocketmine\world\format\Chunk; -use pocketmine\world\format\ChunkException; use pocketmine\world\format\EmptySubChunk; use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\exception\UnsupportedChunkFormatException; @@ -217,9 +216,6 @@ class World implements ChunkManager, Metadatable{ /** @var bool[] blockhash => dummy */ private $neighbourBlockUpdateQueueIndex = []; - /** @var Player[][] */ - private $chunkSendQueue = []; - /** @var bool[] */ private $chunkPopulationQueue = []; /** @var bool[] */ @@ -865,7 +861,6 @@ class World implements ChunkManager, Metadatable{ foreach($this->players as $p){ $p->doChunkRequests(); } - $this->processChunkRequests(); if($this->sleepTicks > 0 and --$this->sleepTicks <= 0){ $this->checkSleep(); @@ -2407,42 +2402,6 @@ class World implements ChunkManager, Metadatable{ (new SpawnChangeEvent($this, $previousSpawn))->call(); } - public function requestChunk(int $x, int $z, Player $player){ - $index = World::chunkHash($x, $z); - if(!isset($this->chunkSendQueue[$index])){ - $this->chunkSendQueue[$index] = []; - } - - $this->chunkSendQueue[$index][spl_object_id($player)] = $player; - } - - private function processChunkRequests(){ - if(count($this->chunkSendQueue) > 0){ - $this->timings->syncChunkSendTimer->startTiming(); - - foreach($this->chunkSendQueue as $index => $players){ - World::getXZ($index, $x, $z); - - $this->timings->syncChunkSendPrepareTimer->startTiming(); - - $chunk = $this->chunks[$index] ?? null; - if($chunk === null or !$chunk->isGenerated() or !$chunk->isPopulated()){ - throw new ChunkException("Invalid Chunk sent"); - } - - foreach($players as $player){ - $player->onChunkReady($x, $z); - } - - $this->timings->syncChunkSendPrepareTimer->stopTiming(); - } - - $this->chunkSendQueue = []; - - $this->timings->syncChunkSendTimer->stopTiming(); - } - } - /** * @param Entity $entity * @@ -2670,7 +2629,6 @@ class World implements ChunkManager, Metadatable{ unset($this->chunks[$chunkHash]); unset($this->blockCache[$chunkHash]); unset($this->changedBlocks[$chunkHash]); - unset($this->chunkSendQueue[$chunkHash]); $this->timings->doChunkUnload->stopTiming(); From cf0c0e72a9661d8a0871b2f8e2593d5ba17c35d5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 May 2019 19:49:06 +0100 Subject: [PATCH 0783/3224] Assume the player is online when they are, uh, assumed to be online the checks removed here should never be hit under normal circumstances. If they were hit, they'd just conceal bugs which would cause a crash to happen later anyway. --- src/pocketmine/Player.php | 8 -------- src/pocketmine/command/defaults/ListCommand.php | 2 +- src/pocketmine/entity/Entity.php | 4 +--- src/pocketmine/event/server/QueryRegenerateEvent.php | 7 +------ src/pocketmine/scheduler/SendUsageTask.php | 9 +++------ 5 files changed, 6 insertions(+), 24 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index ed92972909..116eca17db 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1129,10 +1129,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } public function doChunkRequests(){ - if(!$this->isOnline()){ - return; - } - if($this->nextChunkOrderRun !== PHP_INT_MAX and $this->nextChunkOrderRun-- <= 0){ $this->nextChunkOrderRun = PHP_INT_MAX; $this->orderChunks(); @@ -1192,10 +1188,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool */ public function sleepOn(Vector3 $pos) : bool{ - if(!$this->isOnline()){ - return false; - } - $pos = $pos->floor(); $b = $this->world->getBlock($pos); diff --git a/src/pocketmine/command/defaults/ListCommand.php b/src/pocketmine/command/defaults/ListCommand.php index f87248096b..6fe084b1e1 100644 --- a/src/pocketmine/command/defaults/ListCommand.php +++ b/src/pocketmine/command/defaults/ListCommand.php @@ -50,7 +50,7 @@ class ListCommand extends VanillaCommand{ $playerNames = array_map(function(Player $player){ return $player->getName(); }, array_filter($sender->getServer()->getOnlinePlayers(), function(Player $player) use ($sender){ - return $player->isOnline() and (!($sender instanceof Player) or $sender->canSee($player)); + return !($sender instanceof Player) or $sender->canSee($player); })); $sender->sendMessage(new TranslationContainer("commands.players.list", [count($playerNames), $sender->getServer()->getMaxPlayers()])); diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index a17b9f0914..6040a2abf5 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -1630,9 +1630,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ return; } foreach($this->world->getViewersForPosition($this) as $player){ - if($player->isOnline()){ - $this->spawnTo($player); - } + $this->spawnTo($player); } } diff --git a/src/pocketmine/event/server/QueryRegenerateEvent.php b/src/pocketmine/event/server/QueryRegenerateEvent.php index 0550de3325..d7e49c22f3 100644 --- a/src/pocketmine/event/server/QueryRegenerateEvent.php +++ b/src/pocketmine/event/server/QueryRegenerateEvent.php @@ -79,12 +79,7 @@ class QueryRegenerateEvent extends ServerEvent{ $this->serverName = $server->getMotd(); $this->listPlugins = $server->getProperty("settings.query-plugins", true); $this->plugins = $server->getPluginManager()->getPlugins(); - $this->players = []; - foreach($server->getOnlinePlayers() as $player){ - if($player->isOnline()){ - $this->players[] = $player; - } - } + $this->players = $server->getOnlinePlayers(); $this->gametype = ($server->getGamemode()->getMagicNumber() & 0x01) === 0 ? "SMP" : "CMP"; $this->version = $server->getVersion(); diff --git a/src/pocketmine/scheduler/SendUsageTask.php b/src/pocketmine/scheduler/SendUsageTask.php index c37cd1d4e0..3f66a0e073 100644 --- a/src/pocketmine/scheduler/SendUsageTask.php +++ b/src/pocketmine/scheduler/SendUsageTask.php @@ -24,12 +24,14 @@ declare(strict_types=1); namespace pocketmine\scheduler; use pocketmine\network\mcpe\protocol\ProtocolInfo; +use pocketmine\Player; use pocketmine\Server; use pocketmine\utils\Internet; use pocketmine\utils\Process; use pocketmine\utils\Utils; use pocketmine\utils\UUID; use pocketmine\utils\VersionString; +use function array_map; use function array_values; use function count; use function json_encode; @@ -122,12 +124,7 @@ class SendUsageTask extends AsyncTask{ $playerList[$k] = md5($v); } - $players = []; - foreach($server->getOnlinePlayers() as $p){ - if($p->isOnline()){ - $players[] = md5($p->getUniqueId()->toBinary()); - } - } + $players = array_map(function(Player $p){ return md5($p->getUniqueId()->toBinary()); }, $server->getOnlinePlayers()); $data["players"] = [ "count" => count($players), From fc90cdcc9577dba5e0c832c6be05d3dab1fea6c0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 8 May 2019 14:05:42 +0100 Subject: [PATCH 0784/3224] fix #2910 WorldManager->getLevel() missed in refactor --- src/pocketmine/world/WorldManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/world/WorldManager.php b/src/pocketmine/world/WorldManager.php index 8c79909228..ee48c201be 100644 --- a/src/pocketmine/world/WorldManager.php +++ b/src/pocketmine/world/WorldManager.php @@ -117,7 +117,7 @@ class WorldManager{ * * @return World|null */ - public function getLevel(int $worldId) : ?World{ + public function getWorld(int $worldId) : ?World{ return $this->worlds[$worldId] ?? null; } From a331c5e13f317fda2746ccf41c0424bc666fc3f3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 8 May 2019 16:43:05 +0100 Subject: [PATCH 0785/3224] Player: reduce SetTitlePacket creation boilerplate it's better to encapsulate all this logic in one place so that third party developers can more easily understand this, and also to reduce the amount of crap we have in Player. --- src/pocketmine/Player.php | 34 +++------------- .../network/mcpe/protocol/SetTitlePacket.php | 40 +++++++++++++++++++ 2 files changed, 46 insertions(+), 28 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index eb92d86797..01864d68cb 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2290,7 +2290,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($subtitle !== ""){ $this->sendSubTitle($subtitle); } - $this->sendTitleText($title, SetTitlePacket::TYPE_SET_TITLE); + $this->sendDataPacket(SetTitlePacket::title($title)); } /** @@ -2309,7 +2309,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @param string $subtitle */ public function sendSubTitle(string $subtitle) : void{ - $this->sendTitleText($subtitle, SetTitlePacket::TYPE_SET_SUBTITLE); + $this->sendDataPacket(SetTitlePacket::subtitle($subtitle)); } /** @@ -2328,25 +2328,21 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @param string $message */ public function sendActionBarMessage(string $message) : void{ - $this->sendTitleText($message, SetTitlePacket::TYPE_SET_ACTIONBAR_MESSAGE); + $this->sendDataPacket(SetTitlePacket::actionBarMessage($message)); } /** * Removes the title from the client's screen. */ public function removeTitles(){ - $pk = new SetTitlePacket(); - $pk->type = SetTitlePacket::TYPE_CLEAR_TITLE; - $this->sendDataPacket($pk); + $this->sendDataPacket(SetTitlePacket::clearTitle()); } /** * Resets the title duration settings. */ public function resetTitles(){ - $pk = new SetTitlePacket(); - $pk->type = SetTitlePacket::TYPE_RESET_TITLE; - $this->sendDataPacket($pk); + $this->sendDataPacket(SetTitlePacket::resetTitleOptions()); } /** @@ -2358,28 +2354,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, */ public function setTitleDuration(int $fadeIn, int $stay, int $fadeOut){ if($fadeIn >= 0 and $stay >= 0 and $fadeOut >= 0){ - $pk = new SetTitlePacket(); - $pk->type = SetTitlePacket::TYPE_SET_ANIMATION_TIMES; - $pk->fadeInTime = $fadeIn; - $pk->stayTime = $stay; - $pk->fadeOutTime = $fadeOut; - $this->sendDataPacket($pk); + $this->sendDataPacket(SetTitlePacket::setAnimationTimes($fadeIn, $stay, $fadeOut)); } } - /** - * Internal function used for sending titles. - * - * @param string $title - * @param int $type - */ - protected function sendTitleText(string $title, int $type){ - $pk = new SetTitlePacket(); - $pk->type = $type; - $pk->text = $title; - $this->sendDataPacket($pk); - } - /** * Sends a direct chat message to a player * diff --git a/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php b/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php index 207a9f86aa..d9227b8efe 100644 --- a/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php @@ -69,4 +69,44 @@ class SetTitlePacket extends DataPacket implements ClientboundPacket{ public function handle(SessionHandler $handler) : bool{ return $handler->handleSetTitle($this); } + + private static function type(int $type) : self{ + $result = new self; + $result->type = $type; + return $result; + } + + private static function text(int $type, string $text) : self{ + $result = self::type($type); + $result->text = $text; + return $result; + } + + public static function title(string $text) : self{ + return self::text(self::TYPE_SET_TITLE, $text); + } + + public static function subtitle(string $text) : self{ + return self::text(self::TYPE_SET_SUBTITLE, $text); + } + + public static function actionBarMessage(string $text) : self{ + return self::text(self::TYPE_SET_ACTIONBAR_MESSAGE, $text); + } + + public static function clearTitle() : self{ + return self::type(self::TYPE_CLEAR_TITLE); + } + + public static function resetTitleOptions() : self{ + return self::type(self::TYPE_RESET_TITLE); + } + + public static function setAnimationTimes(int $fadeIn, int $stay, int $fadeOut) : self{ + $result = self::type(self::TYPE_SET_ANIMATION_TIMES); + $result->fadeInTime = $fadeIn; + $result->stayTime = $stay; + $result->fadeOutTime = $fadeOut; + return $result; + } } From 19ac0811f4c1fbe77867e275ea41710ba86cf64a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 8 May 2019 16:44:18 +0100 Subject: [PATCH 0786/3224] Player: remove deprecated title functions --- src/pocketmine/Player.php | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 01864d68cb..a48bffcb72 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2262,20 +2262,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->sendDataPacket($packet, false); } - /** - * @deprecated - * @see Player::sendTitle() - * - * @param string $title - * @param string $subtitle - * @param int $fadeIn Duration in ticks for fade-in. If -1 is given, client-sided defaults will be used. - * @param int $stay Duration in ticks to stay on screen for - * @param int $fadeOut Duration in ticks for fade-out. - */ - public function addTitle(string $title, string $subtitle = "", int $fadeIn = -1, int $stay = -1, int $fadeOut = -1){ - $this->sendTitle($title, $subtitle, $fadeIn, $stay, $fadeOut); - } - /** * Adds a title text to the user's screen, with an optional subtitle. * @@ -2293,16 +2279,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->sendDataPacket(SetTitlePacket::title($title)); } - /** - * @deprecated - * @see Player::sendSubTitle() - * - * @param string $subtitle - */ - public function addSubTitle(string $subtitle){ - $this->sendSubTitle($subtitle); - } - /** * Sets the subtitle message, without sending a title. * @@ -2312,16 +2288,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->sendDataPacket(SetTitlePacket::subtitle($subtitle)); } - /** - * @deprecated - * @see Player::sendActionBarMessage() - * - * @param string $message - */ - public function addActionBarMessage(string $message){ - $this->sendActionBarMessage($message); - } - /** * Adds small text to the user's screen. * From cf73c7f5c1f0e9c549864fe0434238aa66d49649 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 8 May 2019 18:26:41 +0100 Subject: [PATCH 0787/3224] Cleanup to world provider exception handling --- src/pocketmine/world/WorldManager.php | 22 ++++++++------ .../world/format/io/BaseWorldProvider.php | 7 +++++ .../world/format/io/WorldProvider.php | 4 +++ .../world/format/io/data/BaseNbtWorldData.php | 27 ++++++++++++----- .../world/format/io/data/BedrockWorldData.php | 14 ++++++--- .../world/format/io/data/JavaWorldData.php | 17 +++++++---- .../io/exception/CorruptedWorldException.php | 30 +++++++++++++++++++ .../UnsupportedWorldFormatException.php | 4 ++- .../world/format/io/leveldb/LevelDB.php | 15 +++++++++- 9 files changed, 113 insertions(+), 27 deletions(-) create mode 100644 src/pocketmine/world/format/io/exception/CorruptedWorldException.php diff --git a/src/pocketmine/world/WorldManager.php b/src/pocketmine/world/WorldManager.php index ee48c201be..55e0d1fbfd 100644 --- a/src/pocketmine/world/WorldManager.php +++ b/src/pocketmine/world/WorldManager.php @@ -30,6 +30,7 @@ use pocketmine\event\world\WorldUnloadEvent; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\Utils; +use pocketmine\world\format\io\exception\CorruptedWorldException; use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; use pocketmine\world\format\io\FormatConverter; use pocketmine\world\format\io\WorldProvider; @@ -195,7 +196,7 @@ class WorldManager{ */ public function loadWorld(string $name, bool $autoUpgrade = false) : bool{ if(trim($name) === ""){ - throw new WorldException("Invalid empty world name"); + throw new \InvalidArgumentException("Invalid empty world name"); } if($this->isWorldLoaded($name)){ return true; @@ -221,7 +222,15 @@ class WorldManager{ * @var WorldProvider $provider * @see WorldProvider::__construct() */ - $provider = new $providerClass($path); + try{ + $provider = new $providerClass($path); + }catch(CorruptedWorldException $e){ + $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.level.loadError", [$name, "Corruption detected: " . $e->getMessage()])); + return false; + }catch(UnsupportedWorldFormatException $e){ + $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.level.loadError", [$name, "Unsupported format: " . $e->getMessage()])); + return false; + } try{ GeneratorManager::getGenerator($provider->getWorldData()->getGenerator(), true); }catch(\InvalidArgumentException $e){ @@ -230,7 +239,7 @@ class WorldManager{ } if(!($provider instanceof WritableWorldProvider)){ if(!$autoUpgrade){ - throw new WorldException("World \"$name\" is in an unsupported format and needs to be upgraded"); + throw new UnsupportedWorldFormatException("World \"$name\" is in an unsupported format and needs to be upgraded"); } $this->server->getLogger()->notice("Upgrading world \"$name\" to new format. This may take a while."); @@ -240,12 +249,7 @@ class WorldManager{ $this->server->getLogger()->notice("Upgraded world \"$name\" to new format successfully. Backed up pre-conversion world at " . $converter->getBackupPath()); } - try{ - $world = new World($this->server, $name, $provider); - }catch(UnsupportedWorldFormatException $e){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.level.loadError", [$name, $e->getMessage()])); - return false; - } + $world = new World($this->server, $name, $provider); $this->worlds[$world->getId()] = $world; $world->setAutoSave($this->autoSave); diff --git a/src/pocketmine/world/format/io/BaseWorldProvider.php b/src/pocketmine/world/format/io/BaseWorldProvider.php index 97be13a15c..890e78d81c 100644 --- a/src/pocketmine/world/format/io/BaseWorldProvider.php +++ b/src/pocketmine/world/format/io/BaseWorldProvider.php @@ -25,7 +25,9 @@ namespace pocketmine\world\format\io; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\exception\CorruptedChunkException; +use pocketmine\world\format\io\exception\CorruptedWorldException; use pocketmine\world\format\io\exception\UnsupportedChunkFormatException; +use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; use pocketmine\world\WorldException; use function file_exists; @@ -44,6 +46,11 @@ abstract class BaseWorldProvider implements WorldProvider{ $this->worldData = $this->loadLevelData(); } + /** + * @return WorldData + * @throws CorruptedWorldException + * @throws UnsupportedWorldFormatException + */ abstract protected function loadLevelData() : WorldData; public function getPath() : string{ diff --git a/src/pocketmine/world/format/io/WorldProvider.php b/src/pocketmine/world/format/io/WorldProvider.php index 62f98cb689..71cebcaae3 100644 --- a/src/pocketmine/world/format/io/WorldProvider.php +++ b/src/pocketmine/world/format/io/WorldProvider.php @@ -25,12 +25,16 @@ namespace pocketmine\world\format\io; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\exception\CorruptedChunkException; +use pocketmine\world\format\io\exception\CorruptedWorldException; use pocketmine\world\format\io\exception\UnsupportedChunkFormatException; +use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; interface WorldProvider{ /** * @param string $path + * @throws CorruptedWorldException + * @throws UnsupportedWorldFormatException */ public function __construct(string $path); diff --git a/src/pocketmine/world/format/io/data/BaseNbtWorldData.php b/src/pocketmine/world/format/io/data/BaseNbtWorldData.php index 3d2568f1fd..4fd3fc1fc1 100644 --- a/src/pocketmine/world/format/io/data/BaseNbtWorldData.php +++ b/src/pocketmine/world/format/io/data/BaseNbtWorldData.php @@ -25,8 +25,9 @@ namespace pocketmine\world\format\io\data; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\world\format\io\exception\CorruptedWorldException; +use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; use pocketmine\world\format\io\WorldData; -use pocketmine\world\WorldException; use function file_exists; abstract class BaseNbtWorldData implements WorldData{ @@ -37,26 +38,38 @@ abstract class BaseNbtWorldData implements WorldData{ /** @var CompoundTag */ protected $compoundTag; + /** + * @param string $dataPath + * + * @throws CorruptedWorldException + * @throws UnsupportedWorldFormatException + */ public function __construct(string $dataPath){ $this->dataPath = $dataPath; if(!file_exists($this->dataPath)){ - throw new WorldException("World data not found at $dataPath"); + throw new CorruptedWorldException("World data not found at $dataPath"); } - $this->compoundTag = $this->load(); - if($this->compoundTag === null){ - throw new WorldException("Invalid world data"); + try{ + $this->compoundTag = $this->load(); + }catch(CorruptedWorldException $e){ + throw new CorruptedWorldException("Corrupted world data: " . $e->getMessage(), 0, $e); } $this->fix(); } /** * @return CompoundTag + * @throws CorruptedWorldException + * @throws UnsupportedWorldFormatException */ - abstract protected function load() : ?CompoundTag; - + abstract protected function load() : CompoundTag; + /** + * @throws CorruptedWorldException + * @throws UnsupportedWorldFormatException + */ abstract protected function fix() : void; /** diff --git a/src/pocketmine/world/format/io/data/BedrockWorldData.php b/src/pocketmine/world/format/io/data/BedrockWorldData.php index 042cbfee24..b38c5fa839 100644 --- a/src/pocketmine/world/format/io/data/BedrockWorldData.php +++ b/src/pocketmine/world/format/io/data/BedrockWorldData.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\world\format\io\data; use pocketmine\nbt\LittleEndianNbtSerializer; +use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\StringTag; @@ -31,6 +32,7 @@ use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\utils\Binary; use pocketmine\utils\Utils; +use pocketmine\world\format\io\exception\CorruptedWorldException; use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; use pocketmine\world\generator\Flat; use pocketmine\world\generator\Generator; @@ -102,13 +104,17 @@ class BedrockWorldData extends BaseNbtWorldData{ file_put_contents($path . "level.dat", Binary::writeLInt(self::CURRENT_STORAGE_VERSION) . Binary::writeLInt(strlen($buffer)) . $buffer); } - protected function load() : ?CompoundTag{ + protected function load() : CompoundTag{ $nbt = new LittleEndianNbtSerializer(); - $worldData = $nbt->read(substr(file_get_contents($this->dataPath), 8))->getTag(); + try{ + $worldData = $nbt->read(substr(file_get_contents($this->dataPath), 8))->getTag(); + }catch(NbtDataException $e){ + throw new CorruptedWorldException($e->getMessage(), 0, $e); + } $version = $worldData->getInt("StorageVersion", INT32_MAX, true); if($version > self::CURRENT_STORAGE_VERSION){ - throw new UnsupportedWorldFormatException("Specified LevelDB world format version ($version) is not supported by " . \pocketmine\NAME); + throw new UnsupportedWorldFormatException("LevelDB world format version $version is currently unsupported"); } return $worldData; @@ -130,7 +136,7 @@ class BedrockWorldData extends BaseNbtWorldData{ case self::GENERATOR_LIMITED: throw new UnsupportedWorldFormatException("Limited worlds are not currently supported"); default: - throw new UnsupportedWorldFormatException("Unknown LevelDB world format type, this world cannot be loaded"); + throw new UnsupportedWorldFormatException("Unknown LevelDB generator type"); } }else{ $this->compoundTag->setString("generatorName", "default"); diff --git a/src/pocketmine/world/format/io/data/JavaWorldData.php b/src/pocketmine/world/format/io/data/JavaWorldData.php index 875b800b06..2b142a6484 100644 --- a/src/pocketmine/world/format/io/data/JavaWorldData.php +++ b/src/pocketmine/world/format/io/data/JavaWorldData.php @@ -24,11 +24,13 @@ declare(strict_types=1); namespace pocketmine\world\format\io\data; use pocketmine\nbt\BigEndianNbtSerializer; +use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\TreeRoot; use pocketmine\utils\Utils; +use pocketmine\world\format\io\exception\CorruptedWorldException; use pocketmine\world\generator\Generator; use pocketmine\world\generator\GeneratorManager; use pocketmine\world\World; @@ -67,13 +69,18 @@ class JavaWorldData extends BaseNbtWorldData{ file_put_contents($path . "level.dat", $buffer); } - protected function load() : ?CompoundTag{ + protected function load() : CompoundTag{ $nbt = new BigEndianNbtSerializer(); - $worldData = $nbt->readCompressed(file_get_contents($this->dataPath))->getTag(); - if($worldData->hasTag("Data", CompoundTag::class)){ - return $worldData->getCompoundTag("Data"); + try{ + $worldData = $nbt->readCompressed(file_get_contents($this->dataPath))->getTag(); + }catch(NbtDataException $e){ + throw new CorruptedWorldException($e->getMessage(), 0, $e); } - return null; + + if(!$worldData->hasTag("Data", CompoundTag::class)){ + throw new CorruptedWorldException("Missing 'Data' key or wrong type"); + } + return $worldData->getCompoundTag("Data"); } protected function fix() : void{ diff --git a/src/pocketmine/world/format/io/exception/CorruptedWorldException.php b/src/pocketmine/world/format/io/exception/CorruptedWorldException.php new file mode 100644 index 0000000000..982bc5e5f7 --- /dev/null +++ b/src/pocketmine/world/format/io/exception/CorruptedWorldException.php @@ -0,0 +1,30 @@ + LEVELDB_ZLIB_RAW_COMPRESSION @@ -115,7 +123,12 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ self::checkForLevelDBExtension(); parent::__construct($path); - $this->db = self::createDB($path); + try{ + $this->db = self::createDB($path); + }catch(\LevelDBException $e){ + //we can't tell the difference between errors caused by bad permissions and actual corruption :( + throw new CorruptedWorldException(trim($e->getMessage()), 0, $e); + } } protected function loadLevelData() : WorldData{ From 4634baeb02919625d54f42079da3445ffe764489 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 8 May 2019 19:38:57 +0100 Subject: [PATCH 0788/3224] Player: don't repeat yourself --- src/pocketmine/Player.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 3dc474aa0e..15eb4a57ba 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2515,12 +2515,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($this->isValid()){ foreach($this->usedChunks as $index => $d){ World::getXZ($index, $chunkX, $chunkZ); - $this->world->unregisterChunkLoader($this, $chunkX, $chunkZ); - $this->world->unregisterChunkListener($this, $chunkX, $chunkZ); - foreach($this->world->getChunkEntities($chunkX, $chunkZ) as $entity){ - $entity->despawnFrom($this); - } - unset($this->usedChunks[$index]); + $this->unloadChunk($chunkX, $chunkZ); } } $this->usedChunks = []; From ca7c23c137844adbb566b5a160c9957a0159e978 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 8 May 2019 19:47:25 +0100 Subject: [PATCH 0789/3224] Player: remove dead functions these functions belong in the network session, and they are currently just proxies for them. In the future we might have players who don't have IPs at all depending on how they connected (for example Specter) so this stuff shouldn't be in here. --- src/pocketmine/Player.php | 26 ------------------- .../command/defaults/BanIpCommand.php | 4 +-- 2 files changed, 2 insertions(+), 28 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 15eb4a57ba..fa90bc91f8 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -849,32 +849,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, parent::sendSkin($targets ?? $this->server->getOnlinePlayers()); } - /** - * Gets the player IP address - * - * @return string - */ - public function getAddress() : string{ - return $this->networkSession->getIp(); - } - - /** - * @return int - */ - public function getPort() : int{ - return $this->networkSession->getPort(); - } - - /** - * Returns the last measured latency for this player, in milliseconds. This is measured automatically and reported - * back by the network interface. - * - * @return int - */ - public function getPing() : int{ - return $this->networkSession->getPing(); - } - /** * Returns whether the player is currently using an item (right-click and hold). * @return bool diff --git a/src/pocketmine/command/defaults/BanIpCommand.php b/src/pocketmine/command/defaults/BanIpCommand.php index c27b652219..6f10b192d7 100644 --- a/src/pocketmine/command/defaults/BanIpCommand.php +++ b/src/pocketmine/command/defaults/BanIpCommand.php @@ -62,7 +62,7 @@ class BanIpCommand extends VanillaCommand{ Command::broadcastCommandMessage($sender, new TranslationContainer("commands.banip.success", [$value])); }else{ if(($player = $sender->getServer()->getPlayer($value)) instanceof Player){ - $ip = $player->getAddress(); + $ip = $player->getNetworkSession()->getIp(); $this->processIPBan($ip, $sender, $reason); Command::broadcastCommandMessage($sender, new TranslationContainer("commands.banip.success.players", [$ip, $player->getName()])); @@ -80,7 +80,7 @@ class BanIpCommand extends VanillaCommand{ $sender->getServer()->getIPBans()->addBan($ip, $reason, null, $sender->getName()); foreach($sender->getServer()->getOnlinePlayers() as $player){ - if($player->getAddress() === $ip){ + if($player->getNetworkSession()->getIp() === $ip){ $player->kick($reason !== "" ? $reason : "IP banned."); } } From 51a8c2be9d296bb73d25a589592013bf7262f91c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 May 2019 14:54:56 +0100 Subject: [PATCH 0790/3224] Player: Move rollback responsibility to network for interact/break block Custom player implementations might not need rollbacks (f.e. Specter). --- src/pocketmine/Player.php | 28 +------------- .../mcpe/handler/SimpleSessionHandler.php | 37 ++++++++++++++++++- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index fa90bc91f8..b171a01fcb 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine; use pocketmine\block\Bed; -use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\block\UnknownBlock; @@ -117,7 +116,6 @@ use pocketmine\world\format\Chunk; use pocketmine\world\Position; use pocketmine\world\World; use function abs; -use function array_merge; use function assert; use function ceil; use function count; @@ -1952,7 +1950,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * * @param Vector3 $pos * - * @return bool if the block was successfully broken. + * @return bool if the block was successfully broken, false if a rollback needs to take place. */ public function breakBlock(Vector3 $pos) : bool{ $this->doCloseInventory(); @@ -1969,16 +1967,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } - $this->inventory->sendContents($this); - $this->inventory->sendHeldItem($this); - - $target = $this->world->getBlock($pos); - /** @var Block[] $blocks */ - $blocks = $target->getAllSides(); - $blocks[] = $target; - - $this->world->sendBlocks([$this], $blocks); - return false; } @@ -2005,20 +1993,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } - $this->inventory->sendHeldItem($this); - - if($pos->distanceSquared($this) > 10000){ - return true; - } - - $target = $this->world->getBlock($pos); - $block = $target->getSide($face); - - /** @var Block[] $blocks */ - $blocks = array_merge($target->getAllSides(), $block->getAllSides()); //getAllSides() on each of these will include $target and $block because they are next to each other - - $this->world->sendBlocks([$this], $blocks); - return false; } diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index 380ee768f2..8ff6c6ae38 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; +use pocketmine\block\Block; use pocketmine\block\ItemFrame; use pocketmine\block\Sign; use pocketmine\block\utils\SignText; @@ -78,6 +79,7 @@ use pocketmine\network\mcpe\protocol\types\ReleaseItemTransactionData; use pocketmine\network\mcpe\protocol\types\UseItemOnEntityTransactionData; use pocketmine\network\mcpe\protocol\types\UseItemTransactionData; use pocketmine\Player; +use function array_push; use function base64_encode; use function fmod; use function implode; @@ -267,10 +269,17 @@ class SimpleSessionHandler extends SessionHandler{ return true; } //TODO: end hack for client spam bug - $this->player->interactBlock($data->getBlockPos(), $data->getFace(), $clickPos); + + $blockPos = $data->getBlockPos(); + if(!$this->player->interactBlock($blockPos, $data->getFace(), $clickPos)){ + $this->onFailedBlockAction($blockPos, $data->getFace()); + } return true; case UseItemTransactionData::ACTION_BREAK_BLOCK: - $this->player->breakBlock($data->getBlockPos()); + $blockPos = $data->getBlockPos(); + if(!$this->player->breakBlock($blockPos)){ + $this->onFailedBlockAction($blockPos, null); + } return true; case UseItemTransactionData::ACTION_CLICK_AIR: $this->player->useHeldItem(); @@ -280,6 +289,30 @@ class SimpleSessionHandler extends SessionHandler{ return false; } + /** + * Internal function used to execute rollbacks when an action fails on a block. + * + * @param Vector3 $blockPos + * @param int|null $face + */ + private function onFailedBlockAction(Vector3 $blockPos, ?int $face) : void{ + $this->player->getInventory()->sendHeldItem($this->player); + if($blockPos->distanceSquared($this->player) < 10000){ + $target = $this->player->getWorld()->getBlock($blockPos); + + $blocks = $target->getAllSides(); + if($face !== null){ + $sideBlock = $target->getSide($face); + + /** @var Block[] $blocks */ + array_push($blocks, ...$sideBlock->getAllSides()); //getAllSides() on each of these will include $target and $sideBlock because they are next to each other + }else{ + $blocks[] = $target; + } + $this->player->getWorld()->sendBlocks([$this->player], $blocks); + } + } + private function handleUseItemOnEntityTransaction(UseItemOnEntityTransactionData $data) : bool{ $target = $this->player->getWorld()->getEntity($data->getEntityRuntimeId()); if($target === null){ From 5eb3c52a3712045f57e9448e1f9288e9d359ce23 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 May 2019 15:40:58 +0100 Subject: [PATCH 0791/3224] added PunchBlockParticle, encapsulate more network logic --- src/pocketmine/Player.php | 7 +-- .../world/particle/PunchBlockParticle.php | 48 +++++++++++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 src/pocketmine/world/particle/PunchBlockParticle.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index b171a01fcb..c0c32313c7 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -113,6 +113,7 @@ use pocketmine\utils\UUID; use pocketmine\world\ChunkListener; use pocketmine\world\ChunkLoader; use pocketmine\world\format\Chunk; +use pocketmine\world\particle\PunchBlockParticle; use pocketmine\world\Position; use pocketmine\world\World; use function abs; @@ -1932,11 +1933,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, public function continueBreakBlock(Vector3 $pos, int $face) : void{ $block = $this->world->getBlock($pos); - $this->world->broadcastLevelEvent( - $pos, - LevelEventPacket::EVENT_PARTICLE_PUNCH_BLOCK, - $block->getRuntimeId() | ($face << 24) - ); + $this->world->addParticle($pos, new PunchBlockParticle($block, $face)); //TODO: destroy-progress level event } diff --git a/src/pocketmine/world/particle/PunchBlockParticle.php b/src/pocketmine/world/particle/PunchBlockParticle.php new file mode 100644 index 0000000000..ff461c87e8 --- /dev/null +++ b/src/pocketmine/world/particle/PunchBlockParticle.php @@ -0,0 +1,48 @@ +block = $block; + $this->face = $face; + } + + public function encode(Vector3 $pos){ + return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_PUNCH_BLOCK, $this->block->getRuntimeId() | ($this->face << 24), $pos); + } +} From 3be5de4570c6b36828e7a9d7a952b4415a2a5d9d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 May 2019 19:30:18 +0100 Subject: [PATCH 0792/3224] Separate WoodenTrapdoor from Trapdoor, fixed iron trapdoors being valid furnace fuel, closes #2914 for bleeding-edge --- src/pocketmine/block/BlockFactory.php | 2 +- src/pocketmine/block/Trapdoor.php | 14 +-------- src/pocketmine/block/WoodenTrapdoor.php | 39 +++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 14 deletions(-) create mode 100644 src/pocketmine/block/WoodenTrapdoor.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 217f06e2d1..45bd78c525 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -392,7 +392,7 @@ class BlockFactory{ self::register(new WoodenButton(new BID($woodenButtonIds[$treeType]), $treeType->getDisplayName() . " Button")); self::register(new WoodenPressurePlate(new BID($woodenPressurePlateIds[$treeType]), $treeType->getDisplayName() . " Pressure Plate")); - self::register(new Trapdoor(new BID($woodenTrapdoorIds[$treeType]), $treeType->getDisplayName() . " Trapdoor")); + self::register(new WoodenTrapdoor(new BID($woodenTrapdoorIds[$treeType]), $treeType->getDisplayName() . " Trapdoor")); self::register(new Sign($woodenSignIds[$treeType], $treeType->getDisplayName() . " Sign")); } diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index 0c063eae1f..0beee587ba 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -31,7 +31,7 @@ use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\world\sound\DoorSound; -class Trapdoor extends Transparent{ +abstract class Trapdoor extends Transparent{ private const MASK_UPPER = 0x04; private const MASK_OPENED = 0x08; @@ -58,10 +58,6 @@ class Trapdoor extends Transparent{ return 0b1111; } - public function getHardness() : float{ - return 3; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ return AxisAlignedBB::one()->trim($this->open ? $this->facing : ($this->top ? Facing::DOWN : Facing::UP), 13 / 16); } @@ -83,12 +79,4 @@ class Trapdoor extends Transparent{ $this->world->addSound($this, new DoorSound()); return true; } - - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; - } - - public function getFuelTime() : int{ - return 300; - } } diff --git a/src/pocketmine/block/WoodenTrapdoor.php b/src/pocketmine/block/WoodenTrapdoor.php new file mode 100644 index 0000000000..8aaf8ccb8a --- /dev/null +++ b/src/pocketmine/block/WoodenTrapdoor.php @@ -0,0 +1,39 @@ + Date: Fri, 10 May 2019 16:24:59 +0100 Subject: [PATCH 0793/3224] Separate block break-info to a separate dynamic unit --- src/pocketmine/Player.php | 2 +- src/pocketmine/block/Air.php | 14 +- src/pocketmine/block/Anvil.php | 20 +-- src/pocketmine/block/Banner.php | 12 +- src/pocketmine/block/Barrier.php | 14 +- src/pocketmine/block/BaseRail.php | 8 +- src/pocketmine/block/Bed.php | 8 +- src/pocketmine/block/Bedrock.php | 18 +- src/pocketmine/block/Block.php | 110 ++---------- src/pocketmine/block/BlockBreakInfo.php | 165 ++++++++++++++++++ src/pocketmine/block/BlockFactory.php | 4 +- src/pocketmine/block/BlueIce.php | 8 +- src/pocketmine/block/BoneBlock.php | 12 +- src/pocketmine/block/Bookshelf.php | 8 +- src/pocketmine/block/BrewingStand.php | 16 +- src/pocketmine/block/BrickStairs.php | 16 +- src/pocketmine/block/Bricks.php | 16 +- src/pocketmine/block/Cactus.php | 8 +- src/pocketmine/block/Cake.php | 8 +- src/pocketmine/block/Carpet.php | 4 +- src/pocketmine/block/Chest.php | 12 +- src/pocketmine/block/Clay.php | 8 +- src/pocketmine/block/Coal.php | 12 +- src/pocketmine/block/CoalOre.php | 12 +- src/pocketmine/block/Cobblestone.php | 12 +- src/pocketmine/block/CobblestoneStairs.php | 12 +- src/pocketmine/block/Cobweb.php | 16 +- src/pocketmine/block/CocoaBlock.php | 12 +- src/pocketmine/block/Concrete.php | 12 +- src/pocketmine/block/ConcretePowder.php | 8 +- src/pocketmine/block/CraftingTable.php | 8 +- src/pocketmine/block/DaylightSensor.php | 12 +- src/pocketmine/block/DeadBush.php | 14 +- src/pocketmine/block/Diamond.php | 12 +- src/pocketmine/block/DiamondOre.php | 12 +- src/pocketmine/block/Dirt.php | 8 +- src/pocketmine/block/DoubleTallGrass.php | 14 +- src/pocketmine/block/DragonEgg.php | 12 +- src/pocketmine/block/Emerald.php | 12 +- src/pocketmine/block/EmeraldOre.php | 12 +- src/pocketmine/block/EnchantingTable.php | 16 +- src/pocketmine/block/EndPortalFrame.php | 16 +- src/pocketmine/block/EndStone.php | 12 +- src/pocketmine/block/EndStoneBricks.php | 12 +- src/pocketmine/block/EnderChest.php | 20 +-- src/pocketmine/block/Farmland.php | 12 +- src/pocketmine/block/FenceGate.php | 13 +- src/pocketmine/block/Fire.php | 4 - src/pocketmine/block/Flowable.php | 8 +- src/pocketmine/block/FrostedIce.php | 8 +- src/pocketmine/block/Furnace.php | 16 +- src/pocketmine/block/Glass.php | 4 +- src/pocketmine/block/GlassPane.php | 4 +- src/pocketmine/block/GlazedTerracotta.php | 16 +- src/pocketmine/block/GlowingObsidian.php | 20 +-- src/pocketmine/block/Glowstone.php | 8 +- src/pocketmine/block/Gold.php | 12 +- src/pocketmine/block/GoldOre.php | 12 +- src/pocketmine/block/Grass.php | 8 +- src/pocketmine/block/GrassPath.php | 8 +- src/pocketmine/block/Gravel.php | 8 +- src/pocketmine/block/HardenedClay.php | 12 +- src/pocketmine/block/HardenedGlass.php | 4 +- src/pocketmine/block/HardenedGlassPane.php | 4 +- src/pocketmine/block/HayBale.php | 4 +- src/pocketmine/block/Ice.php | 8 +- src/pocketmine/block/InfestedStone.php | 4 +- src/pocketmine/block/InfoUpdate.php | 4 +- src/pocketmine/block/InvisibleBedrock.php | 14 +- src/pocketmine/block/Iron.php | 12 +- src/pocketmine/block/IronBars.php | 12 +- src/pocketmine/block/IronDoor.php | 12 +- src/pocketmine/block/IronOre.php | 12 +- src/pocketmine/block/IronTrapdoor.php | 12 +- src/pocketmine/block/ItemFrame.php | 8 +- src/pocketmine/block/Ladder.php | 12 +- src/pocketmine/block/Lapis.php | 12 +- src/pocketmine/block/LapisOre.php | 12 +- src/pocketmine/block/Leaves.php | 12 +- src/pocketmine/block/Lever.php | 8 +- src/pocketmine/block/Liquid.php | 12 +- src/pocketmine/block/Magma.php | 12 +- src/pocketmine/block/Melon.php | 8 +- src/pocketmine/block/MonsterSpawner.php | 12 +- src/pocketmine/block/Mycelium.php | 8 +- src/pocketmine/block/NetherBrick.php | 12 +- src/pocketmine/block/NetherBrickFence.php | 12 +- src/pocketmine/block/NetherBrickStairs.php | 12 +- src/pocketmine/block/NetherPortal.php | 16 +- src/pocketmine/block/NetherQuartzOre.php | 12 +- src/pocketmine/block/NetherReactor.php | 16 +- src/pocketmine/block/NetherWartBlock.php | 4 +- src/pocketmine/block/Netherrack.php | 12 +- src/pocketmine/block/NoteBlock.php | 12 +- src/pocketmine/block/Obsidian.php | 16 +- src/pocketmine/block/PackedIce.php | 8 +- src/pocketmine/block/Planks.php | 8 +- src/pocketmine/block/Podzol.php | 8 +- src/pocketmine/block/Prismarine.php | 12 +- src/pocketmine/block/Pumpkin.php | 12 +- src/pocketmine/block/Purpur.php | 16 +- src/pocketmine/block/PurpurStairs.php | 16 +- src/pocketmine/block/Quartz.php | 12 +- src/pocketmine/block/QuartzStairs.php | 12 +- src/pocketmine/block/RedMushroomBlock.php | 12 +- src/pocketmine/block/Redstone.php | 12 +- src/pocketmine/block/RedstoneLamp.php | 8 +- src/pocketmine/block/RedstoneOre.php | 16 +- src/pocketmine/block/Reserved6.php | 4 +- src/pocketmine/block/Sand.php | 8 +- src/pocketmine/block/Sandstone.php | 12 +- src/pocketmine/block/SandstoneStairs.php | 12 +- src/pocketmine/block/SeaLantern.php | 4 +- src/pocketmine/block/SeaPickle.php | 8 +- src/pocketmine/block/Sign.php | 12 +- src/pocketmine/block/Skull.php | 8 +- src/pocketmine/block/Slab.php | 4 +- src/pocketmine/block/Snow.php | 12 +- src/pocketmine/block/SnowLayer.php | 16 +- src/pocketmine/block/SoulSand.php | 8 +- src/pocketmine/block/Sponge.php | 8 +- src/pocketmine/block/Stone.php | 12 +- src/pocketmine/block/StoneBrickStairs.php | 12 +- src/pocketmine/block/StoneBricks.php | 12 +- src/pocketmine/block/StoneButton.php | 8 +- src/pocketmine/block/StonePressurePlate.php | 12 +- src/pocketmine/block/StoneSlab.php | 12 +- src/pocketmine/block/Stonecutter.php | 8 +- src/pocketmine/block/TNT.php | 8 +- src/pocketmine/block/TallGrass.php | 14 +- src/pocketmine/block/UnknownBlock.php | 8 +- src/pocketmine/block/Vine.php | 12 +- src/pocketmine/block/Wall.php | 12 +- src/pocketmine/block/WaterLily.php | 4 +- .../block/WeightedPressurePlateHeavy.php | 12 +- .../block/WeightedPressurePlateLight.php | 12 +- src/pocketmine/block/Wood.php | 12 +- src/pocketmine/block/WoodenButton.php | 8 +- src/pocketmine/block/WoodenDoor.php | 8 +- src/pocketmine/block/WoodenFence.php | 8 +- src/pocketmine/block/WoodenPressurePlate.php | 12 +- src/pocketmine/block/WoodenSlab.php | 8 +- src/pocketmine/block/WoodenStairs.php | 12 +- src/pocketmine/block/WoodenTrapdoor.php | 8 +- src/pocketmine/block/Wool.php | 25 ++- src/pocketmine/item/Axe.php | 2 +- src/pocketmine/item/Item.php | 3 +- src/pocketmine/item/Pickaxe.php | 2 +- src/pocketmine/item/Shears.php | 5 +- src/pocketmine/item/Shovel.php | 2 +- src/pocketmine/item/Sword.php | 2 +- src/pocketmine/world/World.php | 4 +- tests/phpunit/block/BlockTest.php | 6 +- tests/plugins/PocketMine-DevTools | 2 +- tests/preprocessor | 2 +- 155 files changed, 556 insertions(+), 1295 deletions(-) create mode 100644 src/pocketmine/block/BlockBreakInfo.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index c0c32313c7..1af1e957ef 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1922,7 +1922,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if(!$this->isCreative()){ //TODO: improve this to take stuff like swimming, ladders, enchanted tools into account, fix wrong tool break time calculations for bad tools (pmmp/PocketMine-MP#211) - $breakTime = ceil($target->getBreakTime($this->inventory->getItemInHand()) * 20); + $breakTime = ceil($target->getBreakInfo()->getBreakTime($this->inventory->getItemInHand()) * 20); if($breakTime > 0){ $this->world->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_START_BREAK, (int) (65535 / $breakTime)); } diff --git a/src/pocketmine/block/Air.php b/src/pocketmine/block/Air.php index 33aeccb843..995c68d0ff 100644 --- a/src/pocketmine/block/Air.php +++ b/src/pocketmine/block/Air.php @@ -23,17 +23,15 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; - /** * Air block */ class Air extends Transparent{ - public function isBreakable(Item $item) : bool{ - return false; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(-1.0, BlockToolType::TYPE_NONE, 0, 0.0)); } public function canBeFlowedInto() : bool{ @@ -59,12 +57,4 @@ class Air extends Transparent{ public function getCollisionBoxes() : array{ return []; } - - public function getHardness() : float{ - return -1; - } - - public function getBlastResistance() : float{ - return 0; - } } diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index ae433ee9e0..928a1b8e78 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -45,6 +45,10 @@ class Anvil extends Transparent implements Fallable{ /** @var int */ protected $facing = Facing::NORTH; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 6000.0)); + } + protected function writeStateToMeta() : int{ return Bearing::fromFacing($this->facing); } @@ -57,22 +61,6 @@ class Anvil extends Transparent implements Fallable{ return 0b11; } - public function getHardness() : float{ - return 5; - } - - public function getBlastResistance() : float{ - return 6000; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; - } - public function recalculateBoundingBox() : ?AxisAlignedBB{ return AxisAlignedBB::one()->squash(Facing::axis(Facing::rotateY($this->facing, false)), 1 / 8); } diff --git a/src/pocketmine/block/Banner.php b/src/pocketmine/block/Banner.php index 9d6b9998f5..cc810f3bf3 100644 --- a/src/pocketmine/block/Banner.php +++ b/src/pocketmine/block/Banner.php @@ -56,8 +56,8 @@ class Banner extends Transparent{ /** @var Deque|BannerPattern[] */ protected $patterns; - public function __construct(BlockIdentifierFlattened $idInfo, string $name){ - parent::__construct($idInfo, $name); + public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0, BlockToolType::TYPE_AXE)); $this->baseColor = DyeColor::BLACK(); $this->patterns = new Deque(); } @@ -107,10 +107,6 @@ class Banner extends Transparent{ $tile->setPatterns($this->patterns); } - public function getHardness() : float{ - return 1; - } - public function isSolid() : bool{ return false; } @@ -168,10 +164,6 @@ class Banner extends Transparent{ } } - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; - } - public function getDropsForCompatibleTool(Item $item) : array{ $drop = ItemFactory::get(Item::BANNER, $this->baseColor->getInvertedMagicNumber()); if($drop instanceof ItemBanner and !$this->patterns->isEmpty()){ diff --git a/src/pocketmine/block/Barrier.php b/src/pocketmine/block/Barrier.php index e00db80f20..6b5bee1a31 100644 --- a/src/pocketmine/block/Barrier.php +++ b/src/pocketmine/block/Barrier.php @@ -23,19 +23,9 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\Item; - class Barrier extends Transparent{ - public function getHardness() : float{ - return -1; - } - - public function getBlastResistance() : float{ - return 18000003; //don't even ask - } - - public function isBreakable(Item $item) : bool{ - return false; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::indestructible()); } } diff --git a/src/pocketmine/block/BaseRail.php b/src/pocketmine/block/BaseRail.php index 1d894108ac..8e157951a8 100644 --- a/src/pocketmine/block/BaseRail.php +++ b/src/pocketmine/block/BaseRail.php @@ -80,6 +80,10 @@ abstract class BaseRail extends Flowable{ /** @var int[] */ protected $connections = []; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.7)); + } + protected function writeStateToMeta() : int{ if(empty($this->connections)){ return self::STRAIGHT_NORTH_SOUTH; @@ -99,10 +103,6 @@ abstract class BaseRail extends Flowable{ return 0b1111; } - public function getHardness() : float{ - return 0.7; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$blockReplace->getSide(Facing::DOWN)->isTransparent()){ $this->tryReconnect(); diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 841589b531..e9597552a4 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -51,8 +51,8 @@ class Bed extends Transparent{ /** @var DyeColor */ protected $color; - public function __construct(BlockIdentifier $idInfo, string $name){ - parent::__construct($idInfo, $name); + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2)); $this->color = DyeColor::RED(); } @@ -90,10 +90,6 @@ class Bed extends Transparent{ } } - public function getHardness() : float{ - return 0.2; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ return AxisAlignedBB::one()->trim(Facing::UP, 7 / 16); } diff --git a/src/pocketmine/block/Bedrock.php b/src/pocketmine/block/Bedrock.php index c2ef580939..1c40563a3f 100644 --- a/src/pocketmine/block/Bedrock.php +++ b/src/pocketmine/block/Bedrock.php @@ -23,13 +23,15 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\Item; - class Bedrock extends Solid{ /** @var bool */ private $burnsForever = false; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::indestructible()); + } + public function readStateFromData(int $id, int $stateMeta) : void{ $this->burnsForever = $stateMeta !== 0; } @@ -42,18 +44,6 @@ class Bedrock extends Solid{ return 0b1; } - public function getHardness() : float{ - return -1; - } - - public function getBlastResistance() : float{ - return 18000000; - } - - public function isBreakable(Item $item) : bool{ - return false; - } - public function burnsForever() : bool{ return $this->burnsForever; } diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index bd573b15b4..5d3f5b32ac 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -46,7 +46,6 @@ use pocketmine\world\World; use function array_merge; use function assert; use function dechex; -use function get_class; use const PHP_INT_MAX; class Block extends Position implements BlockLegacyIds, Metadatable{ @@ -72,6 +71,9 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ /** @var string */ protected $fallbackName; + /** @var BlockBreakInfo */ + protected $breakInfo; + /** @var AxisAlignedBB */ protected $boundingBox = null; @@ -81,13 +83,15 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ /** * @param BlockIdentifier $idInfo * @param string $name English name of the block type (TODO: implement translations) + * @param BlockBreakInfo $breakInfo */ - public function __construct(BlockIdentifier $idInfo, string $name){ + public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ if(($idInfo->getVariant() & $this->getStateBitmask()) !== 0){ throw new \InvalidArgumentException("Variant 0x" . dechex($idInfo->getVariant()) . " collides with state bitmask 0x" . dechex($this->getStateBitmask())); } $this->idInfo = $idInfo; $this->fallbackName = $name; + $this->breakInfo = $breakInfo; } public function getIdInfo() : BlockIdentifier{ @@ -248,59 +252,12 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ } /** - * Returns if the block can be broken with an specific Item + * Returns an object containing information about the destruction requirements of this block. * - * @param Item $item - * - * @return bool + * @return BlockBreakInfo */ - public function isBreakable(Item $item) : bool{ - return true; - } - - /** - * @return int - */ - public function getToolType() : int{ - return BlockToolType::TYPE_NONE; - } - - /** - * Returns the level of tool required to harvest this block (for normal blocks). When the tool type matches the - * block's required tool type, the tool must have a harvest level greater than or equal to this value to be able to - * successfully harvest the block. - * - * If the block requires a specific minimum tier of tiered tool, the minimum tier required should be returned. - * Otherwise, 1 should be returned if a tool is required, 0 if not. - * - * @see Item::getBlockToolHarvestLevel() - * - * @return int - */ - public function getToolHarvestLevel() : int{ - return 0; - } - - /** - * Returns whether the specified item is the proper tool to use for breaking this block. This checks tool type and - * harvest level requirement. - * - * In most cases this is also used to determine whether block drops should be created or not, except in some - * special cases such as vines. - * - * @param Item $tool - * - * @return bool - */ - public function isCompatibleWithTool(Item $tool) : bool{ - if($this->getHardness() < 0){ - return false; - } - - $toolType = $this->getToolType(); - $harvestLevel = $this->getToolHarvestLevel(); - return $toolType === BlockToolType::TYPE_NONE or $harvestLevel === 0 or ( - ($toolType & $tool->getBlockToolType()) !== 0 and $tool->getBlockToolHarvestLevel() >= $harvestLevel); + public function getBreakInfo() : BlockBreakInfo{ + return $this->breakInfo; } /** @@ -318,33 +275,6 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ return $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); } - - /** - * Returns the seconds that this block takes to be broken using an specific Item - * - * @param Item $item - * - * @return float - * @throws \InvalidArgumentException if the item efficiency is not a positive number - */ - public function getBreakTime(Item $item) : float{ - $base = $this->getHardness(); - if($this->isCompatibleWithTool($item)){ - $base *= 1.5; - }else{ - $base *= 5; - } - - $efficiency = $item->getMiningEfficiency(($this->getToolType() & $item->getBlockToolType()) !== 0); - if($efficiency <= 0){ - throw new \InvalidArgumentException(get_class($item) . " has invalid mining efficiency: expected >= 0, got $efficiency"); - } - - $base /= $efficiency; - - return $base; - } - /** * Called when this block or a block immediately adjacent to it changes state. */ @@ -404,22 +334,6 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ return false; } - /** - * Returns a base value used to compute block break times. - * @return float - */ - public function getHardness() : float{ - return 10; - } - - /** - * Returns the block's resistance to explosions. Usually 5x hardness. - * @return float - */ - public function getBlastResistance() : float{ - return $this->getHardness() * 5; - } - /** * @return float */ @@ -517,7 +431,7 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ * @return Item[] */ public function getDrops(Item $item) : array{ - if($this->isCompatibleWithTool($item)){ + if($this->breakInfo->isToolCompatible($item)){ if($this->isAffectedBySilkTouch() and $item->hasEnchantment(Enchantment::SILK_TOUCH())){ return $this->getSilkTouchDrops($item); } @@ -558,7 +472,7 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ * @return int */ public function getXpDropForTool(Item $item) : int{ - if($item->hasEnchantment(Enchantment::SILK_TOUCH()) or !$this->isCompatibleWithTool($item)){ + if($item->hasEnchantment(Enchantment::SILK_TOUCH()) or !$this->breakInfo->isToolCompatible($item)){ return 0; } diff --git a/src/pocketmine/block/BlockBreakInfo.php b/src/pocketmine/block/BlockBreakInfo.php new file mode 100644 index 0000000000..e900b927f0 --- /dev/null +++ b/src/pocketmine/block/BlockBreakInfo.php @@ -0,0 +1,165 @@ +hardness = $hardness; + $this->toolType = $toolType; + $this->toolHarvestLevel = $toolHarvestLevel; + $this->blastResistance = $blastResistance ?? $hardness * 5; + } + + public static function instant(int $toolType = BlockToolType::TYPE_NONE, int $toolHarvestLevel = 0) : self{ + return new self(0.0, $toolType, $toolHarvestLevel, 0.0); + } + + public static function indestructible(float $blastResistance = 18000000.0) : self{ + return new self(-1.0, BlockToolType::TYPE_NONE, 0, $blastResistance); + } + + /** + * Returns a base value used to compute block break times. + * + * @return float + */ + public function getHardness() : float{ + return $this->hardness; + } + + /** + * Returns whether the block can be broken at all. + * + * @return bool + */ + public function isBreakable() : bool{ + return $this->hardness >= 0; + } + + /** + * Returns whether this block can be instantly broken. + * + * @return bool + */ + public function breaksInstantly() : bool{ + return $this->hardness == 0.0; + } + + /** + * Returns the block's resistance to explosions. Usually 5x hardness. + * + * @return float + */ + public function getBlastResistance() : float{ + return $this->blastResistance; + } + + /** + * @return int + */ + public function getToolType() : int{ + return $this->toolType; + } + + /** + * Returns the level of tool required to harvest the block (for normal blocks). When the tool type matches the + * block's required tool type, the tool must have a harvest level greater than or equal to this value to be able to + * successfully harvest the block. + * + * If the block requires a specific minimum tier of tiered tool, the minimum tier required should be returned. + * Otherwise, 1 should be returned if a tool is required, 0 if not. + * + * @see Item::getBlockToolHarvestLevel() + * + * @return int + */ + public function getToolHarvestLevel() : int{ + return $this->toolHarvestLevel; + } + + /** + * Returns whether the specified item is the proper tool to use for breaking this block. This checks tool type and + * harvest level requirement. + * + * In most cases this is also used to determine whether block drops should be created or not, except in some + * special cases such as vines. + * + * @param Item $tool + * + * @return bool + */ + public function isToolCompatible(Item $tool) : bool{ + if($this->hardness < 0){ + return false; + } + + return $this->toolType === BlockToolType::TYPE_NONE or $this->toolHarvestLevel === 0 or ( + ($this->toolType & $tool->getBlockToolType()) !== 0 and $tool->getBlockToolHarvestLevel() >= $this->toolHarvestLevel); + } + + /** + * Returns the seconds that this block takes to be broken using an specific Item + * + * @param Item $item + * + * @return float + * @throws \InvalidArgumentException if the item efficiency is not a positive number + */ + public function getBreakTime(Item $item) : float{ + $base = $this->hardness; + if($this->isToolCompatible($item)){ + $base *= 1.5; + }else{ + $base *= 5; + } + + $efficiency = $item->getMiningEfficiency(($this->toolType & $item->getBlockToolType()) !== 0); + if($efficiency <= 0){ + throw new \InvalidArgumentException(get_class($item) . " has invalid mining efficiency: expected >= 0, got $efficiency"); + } + + $base /= $efficiency; + + return $base; + } +} diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 45bd78c525..8f922b5534 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -31,8 +31,8 @@ use pocketmine\block\utils\TreeType; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\ItemIds; -use pocketmine\world\Position; use pocketmine\tile\Comparator; +use pocketmine\world\Position; use function array_fill; use function array_filter; use function get_class; @@ -612,7 +612,7 @@ class BlockFactory{ self::$fullList[$index] = $block; self::$lightFilter[$index] = min(15, $block->getLightFilter() + 1); //opacity plus 1 standard light filter self::$diffusesSkyLight[$index] = $block->diffusesSkyLight(); - self::$blastResistance[$index] = $block->getBlastResistance(); + self::$blastResistance[$index] = $block->getBreakInfo()->getBlastResistance(); } /** diff --git a/src/pocketmine/block/BlueIce.php b/src/pocketmine/block/BlueIce.php index 688b70aceb..07fa1c6902 100644 --- a/src/pocketmine/block/BlueIce.php +++ b/src/pocketmine/block/BlueIce.php @@ -27,12 +27,8 @@ use pocketmine\item\Item; class BlueIce extends Solid{ - public function getHardness() : float{ - return 2.8; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.8, BlockToolType::TYPE_PICKAXE)); } public function getLightLevel() : int{ diff --git a/src/pocketmine/block/BoneBlock.php b/src/pocketmine/block/BoneBlock.php index 857e30df95..4b95c222b6 100644 --- a/src/pocketmine/block/BoneBlock.php +++ b/src/pocketmine/block/BoneBlock.php @@ -29,15 +29,7 @@ use pocketmine\item\TieredTool; class BoneBlock extends Solid{ use PillarRotationTrait; - public function getHardness() : float{ - return 2; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); } } diff --git a/src/pocketmine/block/Bookshelf.php b/src/pocketmine/block/Bookshelf.php index 3be95be1e8..30729420c9 100644 --- a/src/pocketmine/block/Bookshelf.php +++ b/src/pocketmine/block/Bookshelf.php @@ -28,12 +28,8 @@ use pocketmine\item\ItemFactory; class Bookshelf extends Solid{ - public function getHardness() : float{ - return 1.5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.5, BlockToolType::TYPE_AXE)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/BrewingStand.php b/src/pocketmine/block/BrewingStand.php index f9833823b1..815ca12054 100644 --- a/src/pocketmine/block/BrewingStand.php +++ b/src/pocketmine/block/BrewingStand.php @@ -34,6 +34,10 @@ class BrewingStand extends Transparent{ /** @var bool */ protected $southwestSlot = false; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); + } + protected function writeStateToMeta() : int{ return ($this->eastSlot ? 0x01 : 0) | ($this->southwestSlot ? 0x02 : 0) | ($this->northwestSlot ? 0x04 : 0); } @@ -48,17 +52,5 @@ class BrewingStand extends Transparent{ return 0b111; } - public function getHardness() : float{ - return 0.5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; - } - //TODO } diff --git a/src/pocketmine/block/BrickStairs.php b/src/pocketmine/block/BrickStairs.php index aa5aebf17c..7d942c2fe1 100644 --- a/src/pocketmine/block/BrickStairs.php +++ b/src/pocketmine/block/BrickStairs.php @@ -27,19 +27,7 @@ use pocketmine\item\TieredTool; class BrickStairs extends Stair{ - public function getHardness() : float{ - return 2; - } - - public function getBlastResistance() : float{ - return 30; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } } diff --git a/src/pocketmine/block/Bricks.php b/src/pocketmine/block/Bricks.php index c96efbb4ea..b7a3886367 100644 --- a/src/pocketmine/block/Bricks.php +++ b/src/pocketmine/block/Bricks.php @@ -27,19 +27,7 @@ use pocketmine\item\TieredTool; class Bricks extends Solid{ - public function getHardness() : float{ - return 2; - } - - public function getBlastResistance() : float{ - return 30; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } } diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index 9a8c76235f..89a43c13c0 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -39,6 +39,10 @@ class Cactus extends Transparent{ /** @var int */ protected $age = 0; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.4)); + } + protected function writeStateToMeta() : int{ return $this->age; } @@ -51,10 +55,6 @@ class Cactus extends Transparent{ return 0b1111; } - public function getHardness() : float{ - return 0.4; - } - public function hasEntityCollision() : bool{ return true; } diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index d121490edd..ced7195f62 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -38,6 +38,10 @@ class Cake extends Transparent implements FoodSource{ /** @var int */ protected $bites = 0; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5)); + } + protected function writeStateToMeta() : int{ return $this->bites; } @@ -50,10 +54,6 @@ class Cake extends Transparent implements FoodSource{ return 0b111; } - public function getHardness() : float{ - return 0.5; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ return AxisAlignedBB::one() ->contract(1 / 16, 0, 1 / 16) diff --git a/src/pocketmine/block/Carpet.php b/src/pocketmine/block/Carpet.php index 2397145d84..3e95f9b237 100644 --- a/src/pocketmine/block/Carpet.php +++ b/src/pocketmine/block/Carpet.php @@ -31,8 +31,8 @@ use pocketmine\Player; class Carpet extends Flowable{ - public function getHardness() : float{ - return 0.1; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.1)); } public function isSolid() : bool{ diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index 993b004d68..f2b41e89cb 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -36,6 +36,10 @@ class Chest extends Transparent{ /** @var int */ protected $facing = Facing::NORTH; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.5, BlockToolType::TYPE_AXE)); + } + protected function writeStateToMeta() : int{ return $this->facing; } @@ -48,14 +52,6 @@ class Chest extends Transparent{ return 0b111; } - public function getHardness() : float{ - return 2.5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ //these are slightly bigger than in PC return AxisAlignedBB::one()->contract(0.025, 0, 0.025)->trim(Facing::UP, 0.05); diff --git a/src/pocketmine/block/Clay.php b/src/pocketmine/block/Clay.php index c085dec934..f32f808ce7 100644 --- a/src/pocketmine/block/Clay.php +++ b/src/pocketmine/block/Clay.php @@ -28,12 +28,8 @@ use pocketmine\item\ItemFactory; class Clay extends Solid{ - public function getHardness() : float{ - return 0.6; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_SHOVEL; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::TYPE_SHOVEL)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/Coal.php b/src/pocketmine/block/Coal.php index 0bef6e93a7..097b883ff8 100644 --- a/src/pocketmine/block/Coal.php +++ b/src/pocketmine/block/Coal.php @@ -27,16 +27,8 @@ use pocketmine\item\TieredTool; class Coal extends Solid{ - public function getHardness() : float{ - return 5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } public function getFuelTime() : int{ diff --git a/src/pocketmine/block/CoalOre.php b/src/pocketmine/block/CoalOre.php index aa98370a1e..090509bbc3 100644 --- a/src/pocketmine/block/CoalOre.php +++ b/src/pocketmine/block/CoalOre.php @@ -30,16 +30,8 @@ use function mt_rand; class CoalOre extends Solid{ - public function getHardness() : float{ - return 3; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/Cobblestone.php b/src/pocketmine/block/Cobblestone.php index 988e6e4647..906e774f42 100644 --- a/src/pocketmine/block/Cobblestone.php +++ b/src/pocketmine/block/Cobblestone.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class Cobblestone extends Solid{ - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; - } - - public function getHardness() : float{ - return 2; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } } diff --git a/src/pocketmine/block/CobblestoneStairs.php b/src/pocketmine/block/CobblestoneStairs.php index 780882e087..7174b417c0 100644 --- a/src/pocketmine/block/CobblestoneStairs.php +++ b/src/pocketmine/block/CobblestoneStairs.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class CobblestoneStairs extends Stair{ - public function getHardness() : float{ - return 2; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } } diff --git a/src/pocketmine/block/Cobweb.php b/src/pocketmine/block/Cobweb.php index a368851d93..c3ea9447c5 100644 --- a/src/pocketmine/block/Cobweb.php +++ b/src/pocketmine/block/Cobweb.php @@ -29,22 +29,14 @@ use pocketmine\item\ItemFactory; class Cobweb extends Flowable{ + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(4.0, BlockToolType::TYPE_SWORD | BlockToolType::TYPE_SHEARS, 1)); + } + public function hasEntityCollision() : bool{ return true; } - public function getHardness() : float{ - return 4; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_SWORD | BlockToolType::TYPE_SHEARS; - } - - public function getToolHarvestLevel() : int{ - return 1; - } - public function onEntityInside(Entity $entity) : void{ $entity->resetFallDistance(); } diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index e56c157202..b2ccd8816a 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -42,6 +42,10 @@ class CocoaBlock extends Transparent{ /** @var int */ protected $age = 0; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::TYPE_AXE, 0, 15.0)); + } + protected function writeStateToMeta() : int{ return Bearing::fromFacing(Facing::opposite($this->facing)) | ($this->age << 2); } @@ -55,14 +59,6 @@ class CocoaBlock extends Transparent{ return 0b1111; } - public function getHardness() : float{ - return 0.2; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; - } - public function isAffectedBySilkTouch() : bool{ return false; } diff --git a/src/pocketmine/block/Concrete.php b/src/pocketmine/block/Concrete.php index 0b8673ab6f..38af139761 100644 --- a/src/pocketmine/block/Concrete.php +++ b/src/pocketmine/block/Concrete.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class Concrete extends Solid{ - public function getHardness() : float{ - return 1.8; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.8, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); } } diff --git a/src/pocketmine/block/ConcretePowder.php b/src/pocketmine/block/ConcretePowder.php index ee3baed924..e18f1a9527 100644 --- a/src/pocketmine/block/ConcretePowder.php +++ b/src/pocketmine/block/ConcretePowder.php @@ -32,12 +32,8 @@ class ConcretePowder extends Solid implements Fallable{ onNearbyBlockChange as protected startFalling; } - public function getHardness() : float{ - return 0.5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_SHOVEL; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_SHOVEL)); } public function onNearbyBlockChange() : void{ diff --git a/src/pocketmine/block/CraftingTable.php b/src/pocketmine/block/CraftingTable.php index 0042bcb1cb..67a38b5e01 100644 --- a/src/pocketmine/block/CraftingTable.php +++ b/src/pocketmine/block/CraftingTable.php @@ -30,12 +30,8 @@ use pocketmine\Player; class CraftingTable extends Solid{ - public function getHardness() : float{ - return 2.5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.5, BlockToolType::TYPE_AXE)); } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/pocketmine/block/DaylightSensor.php b/src/pocketmine/block/DaylightSensor.php index a471d013dc..a936ec24e3 100644 --- a/src/pocketmine/block/DaylightSensor.php +++ b/src/pocketmine/block/DaylightSensor.php @@ -40,8 +40,8 @@ class DaylightSensor extends Transparent{ /** @var bool */ protected $inverted = false; - public function __construct(BlockIdentifierFlattened $idInfo, string $name){ - parent::__construct($idInfo, $name); + public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::TYPE_AXE)); } public function getId() : int{ @@ -75,18 +75,10 @@ class DaylightSensor extends Transparent{ return $this; } - public function getHardness() : float{ - return 0.2; - } - public function getFuelTime() : int{ return 300; } - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ return AxisAlignedBB::one()->trim(Facing::UP, 0.5); } diff --git a/src/pocketmine/block/DeadBush.php b/src/pocketmine/block/DeadBush.php index 9c43fbb504..cfff53f3ae 100644 --- a/src/pocketmine/block/DeadBush.php +++ b/src/pocketmine/block/DeadBush.php @@ -32,6 +32,10 @@ use function mt_rand; class DeadBush extends Flowable{ + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant(BlockToolType::TYPE_SHEARS, 1)); + } + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$this->getSide(Facing::DOWN)->isTransparent()){ return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); @@ -46,16 +50,8 @@ class DeadBush extends Flowable{ } } - public function getToolType() : int{ - return BlockToolType::TYPE_SHEARS; - } - - public function getToolHarvestLevel() : int{ - return 1; - } - public function getDrops(Item $item) : array{ - if(!$this->isCompatibleWithTool($item)){ + if(!$this->breakInfo->isToolCompatible($item)){ return [ ItemFactory::get(Item::STICK, 0, mt_rand(0, 2)) ]; diff --git a/src/pocketmine/block/Diamond.php b/src/pocketmine/block/Diamond.php index 5086a9d090..6efdc6c2b3 100644 --- a/src/pocketmine/block/Diamond.php +++ b/src/pocketmine/block/Diamond.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class Diamond extends Solid{ - public function getHardness() : float{ - return 5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_IRON; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON, 30.0)); } } diff --git a/src/pocketmine/block/DiamondOre.php b/src/pocketmine/block/DiamondOre.php index 9ff8273d71..e872f78d8b 100644 --- a/src/pocketmine/block/DiamondOre.php +++ b/src/pocketmine/block/DiamondOre.php @@ -30,16 +30,8 @@ use function mt_rand; class DiamondOre extends Solid{ - public function getHardness() : float{ - return 3; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_IRON; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/Dirt.php b/src/pocketmine/block/Dirt.php index feb23e7aed..2280a27124 100644 --- a/src/pocketmine/block/Dirt.php +++ b/src/pocketmine/block/Dirt.php @@ -33,12 +33,8 @@ class Dirt extends Solid{ public const NORMAL = 0; public const COARSE = 1; - public function getHardness() : float{ - return 0.5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_SHOVEL; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_SHOVEL)); } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/pocketmine/block/DoubleTallGrass.php b/src/pocketmine/block/DoubleTallGrass.php index 5fdba22e01..c0b5d858fe 100644 --- a/src/pocketmine/block/DoubleTallGrass.php +++ b/src/pocketmine/block/DoubleTallGrass.php @@ -29,20 +29,16 @@ use function mt_rand; class DoubleTallGrass extends DoublePlant{ + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant(BlockToolType::TYPE_SHEARS, 1)); + } + public function canBeReplaced() : bool{ return true; } - public function getToolType() : int{ - return BlockToolType::TYPE_SHEARS; - } - - public function getToolHarvestLevel() : int{ - return 1; - } - public function getDrops(Item $item) : array{ - if($this->top and !$this->isCompatibleWithTool($item) and mt_rand(0, 7) === 0){ + if($this->top and !$this->breakInfo->isToolCompatible($item) and mt_rand(0, 7) === 0){ return [ ItemFactory::get(Item::SEEDS) ]; diff --git a/src/pocketmine/block/DragonEgg.php b/src/pocketmine/block/DragonEgg.php index 27de6cc9d4..ffd1d549b2 100644 --- a/src/pocketmine/block/DragonEgg.php +++ b/src/pocketmine/block/DragonEgg.php @@ -39,16 +39,8 @@ use function mt_rand; class DragonEgg extends Transparent implements Fallable{ use FallableTrait; - public function getHardness() : float{ - return 3; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); } public function getLightLevel() : int{ diff --git a/src/pocketmine/block/Emerald.php b/src/pocketmine/block/Emerald.php index fe85118f50..6d9d526751 100644 --- a/src/pocketmine/block/Emerald.php +++ b/src/pocketmine/block/Emerald.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class Emerald extends Solid{ - public function getHardness() : float{ - return 5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_IRON; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON, 30.0)); } } diff --git a/src/pocketmine/block/EmeraldOre.php b/src/pocketmine/block/EmeraldOre.php index 7faf6986ec..d9d48df4af 100644 --- a/src/pocketmine/block/EmeraldOre.php +++ b/src/pocketmine/block/EmeraldOre.php @@ -30,16 +30,8 @@ use function mt_rand; class EmeraldOre extends Solid{ - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_IRON; - } - - public function getHardness() : float{ - return 3; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/EnchantingTable.php b/src/pocketmine/block/EnchantingTable.php index e8b884c331..2e3db817ef 100644 --- a/src/pocketmine/block/EnchantingTable.php +++ b/src/pocketmine/block/EnchantingTable.php @@ -33,20 +33,8 @@ use pocketmine\Player; class EnchantingTable extends Transparent{ - public function getHardness() : float{ - return 5; - } - - public function getBlastResistance() : float{ - return 6000; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 6000.0)); } protected function recalculateBoundingBox() : ?AxisAlignedBB{ diff --git a/src/pocketmine/block/EndPortalFrame.php b/src/pocketmine/block/EndPortalFrame.php index aebdc7b477..dd4561d489 100644 --- a/src/pocketmine/block/EndPortalFrame.php +++ b/src/pocketmine/block/EndPortalFrame.php @@ -38,6 +38,10 @@ class EndPortalFrame extends Solid{ /** @var bool */ protected $eye = false; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::indestructible()); + } + protected function writeStateToMeta() : int{ return Bearing::fromFacing($this->facing) | ($this->eye ? 0x04 : 0); } @@ -55,18 +59,6 @@ class EndPortalFrame extends Solid{ return 1; } - public function getHardness() : float{ - return -1; - } - - public function getBlastResistance() : float{ - return 18000000; - } - - public function isBreakable(Item $item) : bool{ - return false; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ return AxisAlignedBB::one()->trim(Facing::UP, 3 / 16); } diff --git a/src/pocketmine/block/EndStone.php b/src/pocketmine/block/EndStone.php index c27b757db3..bd4dc23876 100644 --- a/src/pocketmine/block/EndStone.php +++ b/src/pocketmine/block/EndStone.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class EndStone extends Solid{ - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; - } - - public function getHardness() : float{ - return 3; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 45.0)); } } diff --git a/src/pocketmine/block/EndStoneBricks.php b/src/pocketmine/block/EndStoneBricks.php index 2028657cb7..ffdbffd3c1 100644 --- a/src/pocketmine/block/EndStoneBricks.php +++ b/src/pocketmine/block/EndStoneBricks.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class EndStoneBricks extends Solid{ - public function getHardness() : float{ - return 0.8; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.8, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 4.0)); } } diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index 7e934e84e6..9c697cba46 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -38,6 +38,10 @@ class EnderChest extends Transparent{ /** @var int */ protected $facing = Facing::NORTH; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(22.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 3000.0)); + } + protected function writeStateToMeta() : int{ return $this->facing; } @@ -50,26 +54,10 @@ class EnderChest extends Transparent{ return 0b111; } - public function getHardness() : float{ - return 22.5; - } - - public function getBlastResistance() : float{ - return 3000; - } - public function getLightLevel() : int{ return 7; } - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ //these are slightly bigger than in PC return AxisAlignedBB::one()->contract(0.025, 0, 0.025)->trim(Facing::UP, 0.05); diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index 9bbc2bd0d7..bcff0c7731 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -34,6 +34,10 @@ class Farmland extends Transparent{ /** @var int */ protected $wetness = 0; //"moisture" blockstate property in PC + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::TYPE_SHOVEL)); + } + protected function writeStateToMeta() : int{ return $this->wetness; } @@ -46,14 +50,6 @@ class Farmland extends Transparent{ return 0b111; } - public function getHardness() : float{ - return 0.6; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_SHOVEL; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ return AxisAlignedBB::one(); //TODO: this should be trimmed at the top by 1/16, but MCPE currently treats them as a full block (https://bugs.mojang.com/browse/MCPE-12109) } diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index c27ed843c5..db9d5c8159 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -40,6 +40,10 @@ class FenceGate extends Transparent{ /** @var bool */ protected $inWall = false; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_AXE)); + } + protected function writeStateToMeta() : int{ return Bearing::fromFacing($this->facing) | ($this->open ? 0x04 : 0) | ($this->inWall ? 0x08 : 0); } @@ -54,15 +58,6 @@ class FenceGate extends Transparent{ return 0b1111; } - public function getHardness() : float{ - return 2; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; - } - - protected function recalculateBoundingBox() : ?AxisAlignedBB{ if($this->open){ return null; diff --git a/src/pocketmine/block/Fire.php b/src/pocketmine/block/Fire.php index 298a1bf5ab..29dd6caaef 100644 --- a/src/pocketmine/block/Fire.php +++ b/src/pocketmine/block/Fire.php @@ -60,10 +60,6 @@ class Fire extends Flowable{ return 15; } - public function isBreakable(Item $item) : bool{ - return false; - } - public function canBeReplaced() : bool{ return true; } diff --git a/src/pocketmine/block/Flowable.php b/src/pocketmine/block/Flowable.php index 5df4e9690d..1461925070 100644 --- a/src/pocketmine/block/Flowable.php +++ b/src/pocketmine/block/Flowable.php @@ -27,12 +27,12 @@ use pocketmine\math\AxisAlignedBB; abstract class Flowable extends Transparent{ - public function canBeFlowedInto() : bool{ - return true; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); } - public function getHardness() : float{ - return 0; + public function canBeFlowedInto() : bool{ + return true; } public function isSolid() : bool{ diff --git a/src/pocketmine/block/FrostedIce.php b/src/pocketmine/block/FrostedIce.php index 5a1446db14..c1effff0ff 100644 --- a/src/pocketmine/block/FrostedIce.php +++ b/src/pocketmine/block/FrostedIce.php @@ -32,6 +32,10 @@ class FrostedIce extends Ice{ /** @var int */ protected $age = 0; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.5, BlockToolType::TYPE_PICKAXE)); + } + public function readStateFromData(int $id, int $stateMeta) : void{ $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 3); } @@ -44,10 +48,6 @@ class FrostedIce extends Ice{ return 0b11; } - public function getHardness() : float{ - return 2.5; - } - public function onNearbyBlockChange() : void{ if(!$this->checkAdjacentBlocks(2)){ $this->world->useBreakOn($this); diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index 87fe907175..952d5ba331 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -40,6 +40,10 @@ class Furnace extends Solid{ /** @var bool */ protected $lit = false; //this is set based on the blockID + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); + } + public function getId() : int{ return $this->lit ? $this->idInfo->getSecondId() : parent::getId(); } @@ -57,18 +61,6 @@ class Furnace extends Solid{ return 0b111; } - public function getHardness() : float{ - return 3.5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; - } - public function getLightLevel() : int{ return $this->lit ? 13 : 0; } diff --git a/src/pocketmine/block/Glass.php b/src/pocketmine/block/Glass.php index dd25ea7423..5ba7742f5f 100644 --- a/src/pocketmine/block/Glass.php +++ b/src/pocketmine/block/Glass.php @@ -27,8 +27,8 @@ use pocketmine\item\Item; class Glass extends Transparent{ - public function getHardness() : float{ - return 0.3; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.3)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/GlassPane.php b/src/pocketmine/block/GlassPane.php index 7f2e02fd60..464b178a7d 100644 --- a/src/pocketmine/block/GlassPane.php +++ b/src/pocketmine/block/GlassPane.php @@ -27,8 +27,8 @@ use pocketmine\item\Item; class GlassPane extends Thin{ - public function getHardness() : float{ - return 0.3; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.3)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/GlazedTerracotta.php b/src/pocketmine/block/GlazedTerracotta.php index a3f4957ba9..c5b41331cc 100644 --- a/src/pocketmine/block/GlazedTerracotta.php +++ b/src/pocketmine/block/GlazedTerracotta.php @@ -36,6 +36,10 @@ class GlazedTerracotta extends Solid{ /** @var int */ protected $facing = Facing::NORTH; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.4, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); + } + protected function writeStateToMeta() : int{ return $this->facing; } @@ -48,18 +52,6 @@ class GlazedTerracotta extends Solid{ return 0b111; } - public function getHardness() : float{ - return 1.4; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); diff --git a/src/pocketmine/block/GlowingObsidian.php b/src/pocketmine/block/GlowingObsidian.php index ac0908a86e..4f63de52dd 100644 --- a/src/pocketmine/block/GlowingObsidian.php +++ b/src/pocketmine/block/GlowingObsidian.php @@ -28,23 +28,11 @@ use pocketmine\item\TieredTool; class GlowingObsidian extends Solid{ + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(10.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_DIAMOND, 50.0)); + } + public function getLightLevel() : int{ return 12; } - - public function getHardness() : float{ - return 10; - } - - public function getBlastResistance() : float{ - return 50; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_DIAMOND; - } } diff --git a/src/pocketmine/block/Glowstone.php b/src/pocketmine/block/Glowstone.php index 54a3784c98..c09ab8437f 100644 --- a/src/pocketmine/block/Glowstone.php +++ b/src/pocketmine/block/Glowstone.php @@ -29,12 +29,8 @@ use function mt_rand; class Glowstone extends Transparent{ - public function getHardness() : float{ - return 0.3; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.3, BlockToolType::TYPE_PICKAXE)); } public function getLightLevel() : int{ diff --git a/src/pocketmine/block/Gold.php b/src/pocketmine/block/Gold.php index ce18ed78b3..5fcda706b3 100644 --- a/src/pocketmine/block/Gold.php +++ b/src/pocketmine/block/Gold.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class Gold extends Solid{ - public function getHardness() : float{ - return 3; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_IRON; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON, 30.0)); } } diff --git a/src/pocketmine/block/GoldOre.php b/src/pocketmine/block/GoldOre.php index a4b465ee49..30c9af2c4e 100644 --- a/src/pocketmine/block/GoldOre.php +++ b/src/pocketmine/block/GoldOre.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class GoldOre extends Solid{ - public function getHardness() : float{ - return 3; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_IRON; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON)); } } diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index 8fe2c09798..29eb1712ca 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -38,12 +38,8 @@ use function mt_rand; class Grass extends Solid{ - public function getHardness() : float{ - return 0.6; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_SHOVEL; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::TYPE_SHOVEL)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/GrassPath.php b/src/pocketmine/block/GrassPath.php index 9c7fb29cf0..de41bbf38f 100644 --- a/src/pocketmine/block/GrassPath.php +++ b/src/pocketmine/block/GrassPath.php @@ -30,18 +30,14 @@ use pocketmine\math\Facing; class GrassPath extends Transparent{ - public function getToolType() : int{ - return BlockToolType::TYPE_SHOVEL; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::TYPE_SHOVEL)); } protected function recalculateBoundingBox() : ?AxisAlignedBB{ return AxisAlignedBB::one(); //TODO: this should be trimmed at the top by 1/16, but MCPE currently treats them as a full block (https://bugs.mojang.com/browse/MCPE-12109) } - public function getHardness() : float{ - return 0.6; - } - public function onNearbyBlockChange() : void{ if($this->getSide(Facing::UP)->isSolid()){ $this->world->setBlock($this, BlockFactory::get(BlockLegacyIds::DIRT)); diff --git a/src/pocketmine/block/Gravel.php b/src/pocketmine/block/Gravel.php index b43848c462..01b3ddd6eb 100644 --- a/src/pocketmine/block/Gravel.php +++ b/src/pocketmine/block/Gravel.php @@ -32,12 +32,8 @@ use function mt_rand; class Gravel extends Solid implements Fallable{ use FallableTrait; - public function getHardness() : float{ - return 0.6; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_SHOVEL; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::TYPE_SHOVEL)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/HardenedClay.php b/src/pocketmine/block/HardenedClay.php index 77b06e2a3c..88902b756b 100644 --- a/src/pocketmine/block/HardenedClay.php +++ b/src/pocketmine/block/HardenedClay.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class HardenedClay extends Solid{ - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; - } - - public function getHardness() : float{ - return 1.25; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.25, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 21.0)); } } diff --git a/src/pocketmine/block/HardenedGlass.php b/src/pocketmine/block/HardenedGlass.php index 65548cd2a2..39a506696e 100644 --- a/src/pocketmine/block/HardenedGlass.php +++ b/src/pocketmine/block/HardenedGlass.php @@ -25,7 +25,7 @@ namespace pocketmine\block; class HardenedGlass extends Transparent{ - public function getHardness() : float{ - return 10; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(10.0)); } } diff --git a/src/pocketmine/block/HardenedGlassPane.php b/src/pocketmine/block/HardenedGlassPane.php index 0e7c707c49..2d9173e60b 100644 --- a/src/pocketmine/block/HardenedGlassPane.php +++ b/src/pocketmine/block/HardenedGlassPane.php @@ -25,7 +25,7 @@ namespace pocketmine\block; class HardenedGlassPane extends Thin{ - public function getHardness() : float{ - return 10; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(10.0)); } } diff --git a/src/pocketmine/block/HayBale.php b/src/pocketmine/block/HayBale.php index 8a78ba8fea..38e480a9e6 100644 --- a/src/pocketmine/block/HayBale.php +++ b/src/pocketmine/block/HayBale.php @@ -28,8 +28,8 @@ use pocketmine\block\utils\PillarRotationTrait; class HayBale extends Solid{ use PillarRotationTrait; - public function getHardness() : float{ - return 0.5; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5)); } public function getFlameEncouragement() : int{ diff --git a/src/pocketmine/block/Ice.php b/src/pocketmine/block/Ice.php index 0a3265134c..725aa0375b 100644 --- a/src/pocketmine/block/Ice.php +++ b/src/pocketmine/block/Ice.php @@ -29,8 +29,8 @@ use pocketmine\Player; class Ice extends Transparent{ - public function getHardness() : float{ - return 0.5; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_PICKAXE)); } public function getLightFilter() : int{ @@ -41,10 +41,6 @@ class Ice extends Transparent{ return 0.98; } - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - public function onBreak(Item $item, ?Player $player = null) : bool{ if(($player === null or $player->isSurvival()) and !$item->hasEnchantment(Enchantment::SILK_TOUCH())){ return $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::WATER)); diff --git a/src/pocketmine/block/InfestedStone.php b/src/pocketmine/block/InfestedStone.php index 6e80996a0a..c08a0c5c76 100644 --- a/src/pocketmine/block/InfestedStone.php +++ b/src/pocketmine/block/InfestedStone.php @@ -27,8 +27,8 @@ use pocketmine\item\Item; abstract class InfestedStone extends Solid{ - public function getHardness() : float{ - return 0.75; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.75)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/InfoUpdate.php b/src/pocketmine/block/InfoUpdate.php index f640e49d4f..74b7d60a0b 100644 --- a/src/pocketmine/block/InfoUpdate.php +++ b/src/pocketmine/block/InfoUpdate.php @@ -25,7 +25,7 @@ namespace pocketmine\block; class InfoUpdate extends Solid{ - public function getHardness() : float{ - return 1; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0)); } } diff --git a/src/pocketmine/block/InvisibleBedrock.php b/src/pocketmine/block/InvisibleBedrock.php index 0b83d4fb14..6bcb74bd97 100644 --- a/src/pocketmine/block/InvisibleBedrock.php +++ b/src/pocketmine/block/InvisibleBedrock.php @@ -23,19 +23,9 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\Item; - class InvisibleBedrock extends Transparent{ - public function getHardness() : float{ - return -1; - } - - public function getBlastResistance() : float{ - return 18000000; - } - - public function isBreakable(Item $item) : bool{ - return false; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::indestructible()); } } diff --git a/src/pocketmine/block/Iron.php b/src/pocketmine/block/Iron.php index fab064e318..f5e26bf63d 100644 --- a/src/pocketmine/block/Iron.php +++ b/src/pocketmine/block/Iron.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class Iron extends Solid{ - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_STONE; - } - - public function getHardness() : float{ - return 5; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_STONE, 30.0)); } } diff --git a/src/pocketmine/block/IronBars.php b/src/pocketmine/block/IronBars.php index 3cfeb036d3..55729180f6 100644 --- a/src/pocketmine/block/IronBars.php +++ b/src/pocketmine/block/IronBars.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class IronBars extends Thin{ - public function getHardness() : float{ - return 5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } } diff --git a/src/pocketmine/block/IronDoor.php b/src/pocketmine/block/IronDoor.php index f735cdbcc0..54906819db 100644 --- a/src/pocketmine/block/IronDoor.php +++ b/src/pocketmine/block/IronDoor.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class IronDoor extends Door{ - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; - } - - public function getHardness() : float{ - return 5; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 25.0)); } } diff --git a/src/pocketmine/block/IronOre.php b/src/pocketmine/block/IronOre.php index acff32ea69..7dfb1d8afb 100644 --- a/src/pocketmine/block/IronOre.php +++ b/src/pocketmine/block/IronOre.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class IronOre extends Solid{ - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_STONE; - } - - public function getHardness() : float{ - return 3; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_STONE)); } } diff --git a/src/pocketmine/block/IronTrapdoor.php b/src/pocketmine/block/IronTrapdoor.php index c807ef83d4..3236ce0a58 100644 --- a/src/pocketmine/block/IronTrapdoor.php +++ b/src/pocketmine/block/IronTrapdoor.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class IronTrapdoor extends Trapdoor{ - public function getHardness() : float{ - return 5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); } } diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index ffc8d5bc1f..a579c8785d 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -45,6 +45,10 @@ class ItemFrame extends Flowable{ /** @var float */ protected $itemDropChance = 1.0; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.25)); + } + protected function writeStateToMeta() : int{ return (5 - $this->facing) | ($this->hasMap ? 0x04 : 0); } @@ -200,8 +204,4 @@ class ItemFrame extends Flowable{ public function isAffectedBySilkTouch() : bool{ return false; } - - public function getHardness() : float{ - return 0.25; - } } diff --git a/src/pocketmine/block/Ladder.php b/src/pocketmine/block/Ladder.php index 2c8023a538..29846f3c4f 100644 --- a/src/pocketmine/block/Ladder.php +++ b/src/pocketmine/block/Ladder.php @@ -36,6 +36,10 @@ class Ladder extends Transparent{ /** @var int */ protected $facing = Facing::NORTH; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.4, BlockToolType::TYPE_AXE)); + } + protected function writeStateToMeta() : int{ return $this->facing; } @@ -56,10 +60,6 @@ class Ladder extends Transparent{ return false; } - public function getHardness() : float{ - return 0.4; - } - public function canClimb() : bool{ return true; } @@ -90,8 +90,4 @@ class Ladder extends Transparent{ $this->world->useBreakOn($this); } } - - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; - } } diff --git a/src/pocketmine/block/Lapis.php b/src/pocketmine/block/Lapis.php index 0e48fc4d26..159aa6f412 100644 --- a/src/pocketmine/block/Lapis.php +++ b/src/pocketmine/block/Lapis.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class Lapis extends Solid{ - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_STONE; - } - - public function getHardness() : float{ - return 3; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_STONE)); } } diff --git a/src/pocketmine/block/LapisOre.php b/src/pocketmine/block/LapisOre.php index 4c4326872d..a9554559d7 100644 --- a/src/pocketmine/block/LapisOre.php +++ b/src/pocketmine/block/LapisOre.php @@ -30,16 +30,8 @@ use function mt_rand; class LapisOre extends Solid{ - public function getHardness() : float{ - return 3; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_STONE; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_STONE)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index e594171b7f..db1024b4bd 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -42,8 +42,8 @@ class Leaves extends Transparent{ /** @var bool */ protected $checkDecay = false; - public function __construct(BlockIdentifier $idInfo, string $name, TreeType $treeType){ - parent::__construct($idInfo, $name); + public function __construct(BlockIdentifier $idInfo, string $name, TreeType $treeType, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::TYPE_SHEARS)); $this->treeType = $treeType; } @@ -60,14 +60,6 @@ class Leaves extends Transparent{ return 0b1100; } - public function getHardness() : float{ - return 0.2; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_SHEARS; - } - public function diffusesSkyLight() : bool{ return true; } diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index 4c925ac6b0..7eaeb01bd1 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -43,6 +43,10 @@ class Lever extends Flowable{ /** @var bool */ protected $powered = false; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5)); + } + protected function writeStateToMeta() : int{ if($this->position === self::BOTTOM){ $rotationMeta = Facing::axis($this->facing) === Facing::AXIS_Z ? 7 : 0; @@ -74,10 +78,6 @@ class Lever extends Flowable{ return 0b1111; } - public function getHardness() : float{ - return 0.5; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$blockClicked->isSolid()){ return false; diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index 29a5dd22f4..532a2aeb5a 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -60,8 +60,8 @@ abstract class Liquid extends Transparent{ /** @var bool */ protected $still = false; - public function __construct(BlockIdentifierFlattened $idInfo, string $name){ - parent::__construct($idInfo, $name); + public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::indestructible(500.0)); } public function getId() : int{ @@ -86,10 +86,6 @@ abstract class Liquid extends Transparent{ return true; } - public function isBreakable(Item $item) : bool{ - return false; - } - public function canBeReplaced() : bool{ return true; } @@ -102,10 +98,6 @@ abstract class Liquid extends Transparent{ return false; } - public function getHardness() : float{ - return 100; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ return null; } diff --git a/src/pocketmine/block/Magma.php b/src/pocketmine/block/Magma.php index 9d23abd34e..266bd5fe9e 100644 --- a/src/pocketmine/block/Magma.php +++ b/src/pocketmine/block/Magma.php @@ -30,16 +30,8 @@ use pocketmine\item\TieredTool; class Magma extends Solid{ - public function getHardness() : float{ - return 0.5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); } public function getLightLevel() : int{ diff --git a/src/pocketmine/block/Melon.php b/src/pocketmine/block/Melon.php index 5498cb14db..3a08773fbb 100644 --- a/src/pocketmine/block/Melon.php +++ b/src/pocketmine/block/Melon.php @@ -29,12 +29,8 @@ use function mt_rand; class Melon extends Transparent{ - public function getHardness() : float{ - return 1; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0, BlockToolType::TYPE_AXE)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/MonsterSpawner.php b/src/pocketmine/block/MonsterSpawner.php index f67957095d..e8b44b9dbb 100644 --- a/src/pocketmine/block/MonsterSpawner.php +++ b/src/pocketmine/block/MonsterSpawner.php @@ -29,16 +29,8 @@ use function mt_rand; class MonsterSpawner extends Transparent{ - public function getHardness() : float{ - return 5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/Mycelium.php b/src/pocketmine/block/Mycelium.php index 1271f07855..40027b93a8 100644 --- a/src/pocketmine/block/Mycelium.php +++ b/src/pocketmine/block/Mycelium.php @@ -31,12 +31,8 @@ use function mt_rand; class Mycelium extends Solid{ - public function getToolType() : int{ - return BlockToolType::TYPE_SHOVEL; - } - - public function getHardness() : float{ - return 0.6; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::TYPE_SHOVEL)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/NetherBrick.php b/src/pocketmine/block/NetherBrick.php index e1f074af43..9948b29d1b 100644 --- a/src/pocketmine/block/NetherBrick.php +++ b/src/pocketmine/block/NetherBrick.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class NetherBrick extends Solid{ - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; - } - - public function getHardness() : float{ - return 2; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } } diff --git a/src/pocketmine/block/NetherBrickFence.php b/src/pocketmine/block/NetherBrickFence.php index 5b80e27fee..6dc47a4f59 100644 --- a/src/pocketmine/block/NetherBrickFence.php +++ b/src/pocketmine/block/NetherBrickFence.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class NetherBrickFence extends Fence{ - public function getHardness() : float{ - return 2; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } } diff --git a/src/pocketmine/block/NetherBrickStairs.php b/src/pocketmine/block/NetherBrickStairs.php index 8f5c16134c..4fefa4136d 100644 --- a/src/pocketmine/block/NetherBrickStairs.php +++ b/src/pocketmine/block/NetherBrickStairs.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class NetherBrickStairs extends Stair{ - public function getHardness() : float{ - return 2; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } } diff --git a/src/pocketmine/block/NetherPortal.php b/src/pocketmine/block/NetherPortal.php index 39b4485224..63c17dbe67 100644 --- a/src/pocketmine/block/NetherPortal.php +++ b/src/pocketmine/block/NetherPortal.php @@ -32,6 +32,10 @@ class NetherPortal extends Transparent{ /** @var int */ protected $axis = Facing::AXIS_X; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::indestructible(0.0)); + } + public function readStateFromData(int $id, int $stateMeta) : void{ $this->axis = $stateMeta === 2 ? Facing::AXIS_Z : Facing::AXIS_X; //mojang u dumb } @@ -74,18 +78,6 @@ class NetherPortal extends Transparent{ return null; } - public function isBreakable(Item $item) : bool{ - return false; - } - - public function getHardness() : float{ - return -1; - } - - public function getBlastResistance() : float{ - return 0; - } - public function getDrops(Item $item) : array{ return []; } diff --git a/src/pocketmine/block/NetherQuartzOre.php b/src/pocketmine/block/NetherQuartzOre.php index fc6cbaa3af..a72851d1e2 100644 --- a/src/pocketmine/block/NetherQuartzOre.php +++ b/src/pocketmine/block/NetherQuartzOre.php @@ -30,16 +30,8 @@ use function mt_rand; class NetherQuartzOre extends Solid{ - public function getHardness() : float{ - return 3; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/NetherReactor.php b/src/pocketmine/block/NetherReactor.php index 3a90117e83..c90289f30b 100644 --- a/src/pocketmine/block/NetherReactor.php +++ b/src/pocketmine/block/NetherReactor.php @@ -36,6 +36,10 @@ class NetherReactor extends Solid{ /** @var int */ protected $state = self::STATE_INACTIVE; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); + } + protected function writeStateToMeta() : int{ return $this->state; } @@ -48,18 +52,6 @@ class NetherReactor extends Solid{ return 0b11; } - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; - } - - public function getHardness() : float{ - return 3; - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ ItemFactory::get(Item::IRON_INGOT, 0, 6), diff --git a/src/pocketmine/block/NetherWartBlock.php b/src/pocketmine/block/NetherWartBlock.php index 2460a69c32..5c61c11b5d 100644 --- a/src/pocketmine/block/NetherWartBlock.php +++ b/src/pocketmine/block/NetherWartBlock.php @@ -25,7 +25,7 @@ namespace pocketmine\block; class NetherWartBlock extends Solid{ - public function getHardness() : float{ - return 1; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0)); } } diff --git a/src/pocketmine/block/Netherrack.php b/src/pocketmine/block/Netherrack.php index 34ca389dba..e5e84dd113 100644 --- a/src/pocketmine/block/Netherrack.php +++ b/src/pocketmine/block/Netherrack.php @@ -27,16 +27,8 @@ use pocketmine\item\TieredTool; class Netherrack extends Solid{ - public function getHardness() : float{ - return 0.4; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.4, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); } public function burnsForever() : bool{ diff --git a/src/pocketmine/block/NoteBlock.php b/src/pocketmine/block/NoteBlock.php index c471b8185e..000c6889f0 100644 --- a/src/pocketmine/block/NoteBlock.php +++ b/src/pocketmine/block/NoteBlock.php @@ -25,17 +25,13 @@ namespace pocketmine\block; class NoteBlock extends Solid{ + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.8, BlockToolType::TYPE_AXE)); + } + public function getFuelTime() : int{ return 300; } - public function getHardness() : float{ - return 0.8; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; - } - //TODO } diff --git a/src/pocketmine/block/Obsidian.php b/src/pocketmine/block/Obsidian.php index e204784cfc..aa37ef217a 100644 --- a/src/pocketmine/block/Obsidian.php +++ b/src/pocketmine/block/Obsidian.php @@ -27,19 +27,7 @@ use pocketmine\item\TieredTool; class Obsidian extends Solid{ - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_DIAMOND; - } - - public function getHardness() : float{ - return 35; //50 in PC - } - - public function getBlastResistance() : float{ - return 6000; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(35.0 /* 50 in PC */, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_DIAMOND, 6000.0)); } } diff --git a/src/pocketmine/block/PackedIce.php b/src/pocketmine/block/PackedIce.php index 5fe41f38a3..298ce4bb3d 100644 --- a/src/pocketmine/block/PackedIce.php +++ b/src/pocketmine/block/PackedIce.php @@ -27,18 +27,14 @@ use pocketmine\item\Item; class PackedIce extends Solid{ - public function getHardness() : float{ - return 0.5; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_PICKAXE)); } public function getFrictionFactor() : float{ return 0.98; } - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - public function getDropsForCompatibleTool(Item $item) : array{ return []; } diff --git a/src/pocketmine/block/Planks.php b/src/pocketmine/block/Planks.php index 2acf2c0719..9da5889c79 100644 --- a/src/pocketmine/block/Planks.php +++ b/src/pocketmine/block/Planks.php @@ -25,12 +25,8 @@ namespace pocketmine\block; class Planks extends Solid{ - public function getHardness() : float{ - return 2; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_AXE, 0, 15.0)); } public function getFuelTime() : int{ diff --git a/src/pocketmine/block/Podzol.php b/src/pocketmine/block/Podzol.php index 0cfa1ccda7..df2f931dda 100644 --- a/src/pocketmine/block/Podzol.php +++ b/src/pocketmine/block/Podzol.php @@ -25,11 +25,7 @@ namespace pocketmine\block; class Podzol extends Solid{ - public function getToolType() : int{ - return BlockToolType::TYPE_SHOVEL; - } - - public function getHardness() : float{ - return 2.5; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.5, BlockToolType::TYPE_SHOVEL)); } } diff --git a/src/pocketmine/block/Prismarine.php b/src/pocketmine/block/Prismarine.php index c850bfaaf6..514af27c63 100644 --- a/src/pocketmine/block/Prismarine.php +++ b/src/pocketmine/block/Prismarine.php @@ -31,15 +31,7 @@ class Prismarine extends Solid{ public const DARK = 1; public const BRICKS = 2; - public function getHardness() : float{ - return 1.5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } } diff --git a/src/pocketmine/block/Pumpkin.php b/src/pocketmine/block/Pumpkin.php index 0f760987fd..f73396e247 100644 --- a/src/pocketmine/block/Pumpkin.php +++ b/src/pocketmine/block/Pumpkin.php @@ -35,6 +35,10 @@ class Pumpkin extends Solid{ /** @var int */ protected $facing = Facing::NORTH; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0, BlockToolType::TYPE_AXE)); + } + public function readStateFromData(int $id, int $stateMeta) : void{ $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); } @@ -47,14 +51,6 @@ class Pumpkin extends Solid{ return 0b11; } - public function getHardness() : float{ - return 1; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; - } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); diff --git a/src/pocketmine/block/Purpur.php b/src/pocketmine/block/Purpur.php index 43db8c9aa1..9870573e07 100644 --- a/src/pocketmine/block/Purpur.php +++ b/src/pocketmine/block/Purpur.php @@ -27,19 +27,7 @@ use pocketmine\item\TieredTool; class Purpur extends Solid{ - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; - } - - public function getHardness() : float{ - return 1.5; - } - - public function getBlastResistance() : float{ - return 30; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } } diff --git a/src/pocketmine/block/PurpurStairs.php b/src/pocketmine/block/PurpurStairs.php index 4ba243108e..c07c31ccd5 100644 --- a/src/pocketmine/block/PurpurStairs.php +++ b/src/pocketmine/block/PurpurStairs.php @@ -27,19 +27,7 @@ use pocketmine\item\TieredTool; class PurpurStairs extends Stair{ - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; - } - - public function getHardness() : float{ - return 1.5; - } - - public function getBlastResistance() : float{ - return 30; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } } diff --git a/src/pocketmine/block/Quartz.php b/src/pocketmine/block/Quartz.php index e650043832..7efdfa64f4 100644 --- a/src/pocketmine/block/Quartz.php +++ b/src/pocketmine/block/Quartz.php @@ -32,15 +32,7 @@ class Quartz extends Solid{ public const PILLAR = 2; public const SMOOTH = 3; - public function getHardness() : float{ - return 0.8; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.8, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); } } diff --git a/src/pocketmine/block/QuartzStairs.php b/src/pocketmine/block/QuartzStairs.php index db910f0e88..a611b7dea8 100644 --- a/src/pocketmine/block/QuartzStairs.php +++ b/src/pocketmine/block/QuartzStairs.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class QuartzStairs extends Stair{ - public function getHardness() : float{ - return 0.8; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.8, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); } } diff --git a/src/pocketmine/block/RedMushroomBlock.php b/src/pocketmine/block/RedMushroomBlock.php index 7e2bbf48ea..409e946532 100644 --- a/src/pocketmine/block/RedMushroomBlock.php +++ b/src/pocketmine/block/RedMushroomBlock.php @@ -37,6 +37,10 @@ class RedMushroomBlock extends Solid{ */ protected $rotationData = 0; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::TYPE_AXE)); + } + protected function writeStateToMeta() : int{ return $this->rotationData; } @@ -49,14 +53,6 @@ class RedMushroomBlock extends Solid{ return 0b1111; } - public function getHardness() : float{ - return 0.2; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ Item::get(Item::RED_MUSHROOM, 0, mt_rand(0, 2)) diff --git a/src/pocketmine/block/Redstone.php b/src/pocketmine/block/Redstone.php index 6bc85cd211..7195844bb6 100644 --- a/src/pocketmine/block/Redstone.php +++ b/src/pocketmine/block/Redstone.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class Redstone extends Solid{ - public function getHardness() : float{ - return 5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } } diff --git a/src/pocketmine/block/RedstoneLamp.php b/src/pocketmine/block/RedstoneLamp.php index eae4bdf2ce..b896ad03de 100644 --- a/src/pocketmine/block/RedstoneLamp.php +++ b/src/pocketmine/block/RedstoneLamp.php @@ -31,8 +31,8 @@ class RedstoneLamp extends Solid{ /** @var bool */ protected $lit = false; - public function __construct(BlockIdentifierFlattened $idInfo, string $name){ - parent::__construct($idInfo, $name); + public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.3)); } public function getId() : int{ @@ -60,8 +60,4 @@ class RedstoneLamp extends Solid{ public function getLightLevel() : int{ return $this->lit ? 15 : 0; } - - public function getHardness() : float{ - return 0.3; - } } diff --git a/src/pocketmine/block/RedstoneOre.php b/src/pocketmine/block/RedstoneOre.php index 33f8ffb3ad..533859b883 100644 --- a/src/pocketmine/block/RedstoneOre.php +++ b/src/pocketmine/block/RedstoneOre.php @@ -37,8 +37,8 @@ class RedstoneOre extends Solid{ /** @var bool */ protected $lit = false; - public function __construct(BlockIdentifierFlattened $idInfo, string $name){ - parent::__construct($idInfo, $name); + public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON)); } public function getId() : int{ @@ -49,10 +49,6 @@ class RedstoneOre extends Solid{ $this->lit = $id === $this->idInfo->getSecondId(); } - public function getHardness() : float{ - return 3; - } - public function isLit() : bool{ return $this->lit; } @@ -101,14 +97,6 @@ class RedstoneOre extends Solid{ } } - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_IRON; - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ ItemFactory::get(Item::REDSTONE_DUST, 0, mt_rand(4, 5)) diff --git a/src/pocketmine/block/Reserved6.php b/src/pocketmine/block/Reserved6.php index 074717cc6d..85d6b6b479 100644 --- a/src/pocketmine/block/Reserved6.php +++ b/src/pocketmine/block/Reserved6.php @@ -25,7 +25,7 @@ namespace pocketmine\block; class Reserved6 extends Solid{ - public function getHardness() : float{ - return 0; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); } } diff --git a/src/pocketmine/block/Sand.php b/src/pocketmine/block/Sand.php index 4b45bebce7..1a5101921e 100644 --- a/src/pocketmine/block/Sand.php +++ b/src/pocketmine/block/Sand.php @@ -29,12 +29,8 @@ use pocketmine\block\utils\FallableTrait; class Sand extends Solid implements Fallable{ use FallableTrait; - public function getHardness() : float{ - return 0.5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_SHOVEL; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_SHOVEL)); } public function tickFalling() : ?Block{ diff --git a/src/pocketmine/block/Sandstone.php b/src/pocketmine/block/Sandstone.php index 5bcf9b018d..bb0de7b991 100644 --- a/src/pocketmine/block/Sandstone.php +++ b/src/pocketmine/block/Sandstone.php @@ -32,15 +32,7 @@ class Sandstone extends Solid{ public const CUT = 2; public const SMOOTH = 3; - public function getHardness() : float{ - return 0.8; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.8, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); } } diff --git a/src/pocketmine/block/SandstoneStairs.php b/src/pocketmine/block/SandstoneStairs.php index 19056fa739..8cf0472805 100644 --- a/src/pocketmine/block/SandstoneStairs.php +++ b/src/pocketmine/block/SandstoneStairs.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class SandstoneStairs extends Stair{ - public function getHardness() : float{ - return 0.8; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.8, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); } } diff --git a/src/pocketmine/block/SeaLantern.php b/src/pocketmine/block/SeaLantern.php index 09947580ed..bd0c068731 100644 --- a/src/pocketmine/block/SeaLantern.php +++ b/src/pocketmine/block/SeaLantern.php @@ -28,8 +28,8 @@ use pocketmine\item\ItemFactory; class SeaLantern extends Transparent{ - public function getHardness() : float{ - return 0.3; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.3)); } public function getLightLevel() : int{ diff --git a/src/pocketmine/block/SeaPickle.php b/src/pocketmine/block/SeaPickle.php index 7f838fac46..5a40ce34e4 100644 --- a/src/pocketmine/block/SeaPickle.php +++ b/src/pocketmine/block/SeaPickle.php @@ -34,6 +34,10 @@ class SeaPickle extends Transparent{ /** @var bool */ protected $underwater = false; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); + } + public function readStateFromData(int $id, int $stateMeta) : void{ $this->count = ($stateMeta & 0x03) + 1; $this->underwater = ($stateMeta & 0x04) === 0; @@ -47,10 +51,6 @@ class SeaPickle extends Transparent{ return 0b111; } - public function getHardness() : float{ - return 0; - } - public function isSolid() : bool{ return false; } diff --git a/src/pocketmine/block/Sign.php b/src/pocketmine/block/Sign.php index 4a51f3fda7..d61b700c15 100644 --- a/src/pocketmine/block/Sign.php +++ b/src/pocketmine/block/Sign.php @@ -53,8 +53,8 @@ class Sign extends Transparent{ /** @var SignText */ protected $text; - public function __construct(BlockIdentifierFlattened $idInfo, string $name){ - parent::__construct($idInfo, $name); + public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0, BlockToolType::TYPE_AXE)); $this->text = new SignText(); } @@ -101,10 +101,6 @@ class Sign extends Transparent{ return 0b1111; } - public function getHardness() : float{ - return 1; - } - public function isSolid() : bool{ return false; } @@ -132,10 +128,6 @@ class Sign extends Transparent{ } } - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; - } - /** * Returns an object containing information about the sign text. * diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index 99c6b93594..ef450e7f1e 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -46,9 +46,9 @@ class Skull extends Flowable{ /** @var int */ protected $rotation = 0; //TODO: split this into floor skull and wall skull handling - public function __construct(BlockIdentifier $idInfo, string $name){ + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ $this->skullType = SkullType::SKELETON(); //TODO: this should be a parameter - parent::__construct($idInfo, $name); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0)); } protected function writeStateToMeta() : int{ @@ -81,10 +81,6 @@ class Skull extends Flowable{ $tile->setSkullType($this->skullType); } - public function getHardness() : float{ - return 1; - } - /** * @return SkullType */ diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index 74c0d6e96d..1fee7d4252 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -37,8 +37,8 @@ abstract class Slab extends Transparent{ /** @var SlabType */ protected $slabType; - public function __construct(BlockIdentifierFlattened $idInfo, string $name){ - parent::__construct($idInfo, $name . " Slab"); + public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + parent::__construct($idInfo, $name . " Slab", $breakInfo); $this->slabType = SlabType::BOTTOM(); } diff --git a/src/pocketmine/block/Snow.php b/src/pocketmine/block/Snow.php index c336908469..dea7b5d61e 100644 --- a/src/pocketmine/block/Snow.php +++ b/src/pocketmine/block/Snow.php @@ -29,16 +29,8 @@ use pocketmine\item\TieredTool; class Snow extends Solid{ - public function getHardness() : float{ - return 0.2; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_SHOVEL; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::TYPE_SHOVEL, TieredTool::TIER_WOODEN)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index 6fa335de99..b7418125f1 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -42,6 +42,10 @@ class SnowLayer extends Flowable implements Fallable{ /** @var int */ protected $layers = 1; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.1, BlockToolType::TYPE_SHOVEL, TieredTool::TIER_WOODEN)); + } + protected function writeStateToMeta() : int{ return $this->layers - 1; } @@ -58,18 +62,6 @@ class SnowLayer extends Flowable implements Fallable{ return $this->layers < 8; } - public function getHardness() : float{ - return 0.1; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_SHOVEL; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; - } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ //TODO: this zero-height BB is intended to stay in lockstep with a MCPE bug return AxisAlignedBB::one()->trim(Facing::UP, $this->layers >= 4 ? 0.5 : 1); diff --git a/src/pocketmine/block/SoulSand.php b/src/pocketmine/block/SoulSand.php index b006f06f1a..bcf2fb4faf 100644 --- a/src/pocketmine/block/SoulSand.php +++ b/src/pocketmine/block/SoulSand.php @@ -28,12 +28,8 @@ use pocketmine\math\Facing; class SoulSand extends Solid{ - public function getHardness() : float{ - return 0.5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_SHOVEL; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_SHOVEL)); } protected function recalculateBoundingBox() : ?AxisAlignedBB{ diff --git a/src/pocketmine/block/Sponge.php b/src/pocketmine/block/Sponge.php index f72ec0b7b7..da1e15545a 100644 --- a/src/pocketmine/block/Sponge.php +++ b/src/pocketmine/block/Sponge.php @@ -29,6 +29,10 @@ class Sponge extends Solid{ /** @var bool */ protected $wet = false; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6)); + } + protected function writeStateToMeta() : int{ return $this->wet ? 1 : 0; } @@ -40,8 +44,4 @@ class Sponge extends Solid{ public function getStateBitmask() : int{ return 0b1; } - - public function getHardness() : float{ - return 0.6; - } } diff --git a/src/pocketmine/block/Stone.php b/src/pocketmine/block/Stone.php index 47272c2f86..e3255a2da9 100644 --- a/src/pocketmine/block/Stone.php +++ b/src/pocketmine/block/Stone.php @@ -34,15 +34,7 @@ class Stone extends Solid{ public const ANDESITE = 5; public const POLISHED_ANDESITE = 6; - public function getHardness() : float{ - return 1.5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } } diff --git a/src/pocketmine/block/StoneBrickStairs.php b/src/pocketmine/block/StoneBrickStairs.php index bb3ae279be..7e379129aa 100644 --- a/src/pocketmine/block/StoneBrickStairs.php +++ b/src/pocketmine/block/StoneBrickStairs.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class StoneBrickStairs extends Stair{ - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; - } - - public function getHardness() : float{ - return 1.5; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } } diff --git a/src/pocketmine/block/StoneBricks.php b/src/pocketmine/block/StoneBricks.php index fca2d99374..5677960c05 100644 --- a/src/pocketmine/block/StoneBricks.php +++ b/src/pocketmine/block/StoneBricks.php @@ -31,15 +31,7 @@ class StoneBricks extends Solid{ public const CRACKED = 2; public const CHISELED = 3; - public function getHardness() : float{ - return 1.5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } } diff --git a/src/pocketmine/block/StoneButton.php b/src/pocketmine/block/StoneButton.php index 54d710d759..36bbefec79 100644 --- a/src/pocketmine/block/StoneButton.php +++ b/src/pocketmine/block/StoneButton.php @@ -25,12 +25,8 @@ namespace pocketmine\block; class StoneButton extends Button{ - public function getHardness() : float{ - return 0.5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_PICKAXE)); } protected function getActivationTime() : int{ diff --git a/src/pocketmine/block/StonePressurePlate.php b/src/pocketmine/block/StonePressurePlate.php index 2534010015..411b5e0fa6 100644 --- a/src/pocketmine/block/StonePressurePlate.php +++ b/src/pocketmine/block/StonePressurePlate.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class StonePressurePlate extends SimplePressurePlate{ - public function getHardness() : float{ - return 0.5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); } } diff --git a/src/pocketmine/block/StoneSlab.php b/src/pocketmine/block/StoneSlab.php index 56ae176d98..4d124f391b 100644 --- a/src/pocketmine/block/StoneSlab.php +++ b/src/pocketmine/block/StoneSlab.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class StoneSlab extends Slab{ - public function getHardness() : float{ - return 2; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } } diff --git a/src/pocketmine/block/Stonecutter.php b/src/pocketmine/block/Stonecutter.php index 36ea459578..8c55b473bc 100644 --- a/src/pocketmine/block/Stonecutter.php +++ b/src/pocketmine/block/Stonecutter.php @@ -27,11 +27,7 @@ use pocketmine\item\TieredTool; class Stonecutter extends Solid{ - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); } } diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index c968e6a50b..23f5850767 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -43,6 +43,10 @@ class TNT extends Solid{ /** @var bool */ protected $unstable = false; //TODO: Usage unclear, seems to be a weird hack in vanilla + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); + } + public function readStateFromData(int $id, int $stateMeta) : void{ $this->unstable = $stateMeta !== 0; } @@ -55,10 +59,6 @@ class TNT extends Solid{ return 0b1; } - public function getHardness() : float{ - return 0; - } - public function onBreak(Item $item, ?Player $player = null) : bool{ if($this->unstable){ $this->ignite(); diff --git a/src/pocketmine/block/TallGrass.php b/src/pocketmine/block/TallGrass.php index 41a67eb114..53fe1b9db7 100644 --- a/src/pocketmine/block/TallGrass.php +++ b/src/pocketmine/block/TallGrass.php @@ -32,6 +32,10 @@ use function mt_rand; class TallGrass extends Flowable{ + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant(BlockToolType::TYPE_SHEARS, 1)); + } + public function canBeReplaced() : bool{ return true; } @@ -51,16 +55,8 @@ class TallGrass extends Flowable{ } } - public function getToolType() : int{ - return BlockToolType::TYPE_SHEARS; - } - - public function getToolHarvestLevel() : int{ - return 1; - } - public function getDrops(Item $item) : array{ - if($this->isCompatibleWithTool($item)){ + if($this->breakInfo->isToolCompatible($item)){ return parent::getDrops($item); } diff --git a/src/pocketmine/block/UnknownBlock.php b/src/pocketmine/block/UnknownBlock.php index 53e56d4ebd..ee2974b38b 100644 --- a/src/pocketmine/block/UnknownBlock.php +++ b/src/pocketmine/block/UnknownBlock.php @@ -27,18 +27,14 @@ use pocketmine\item\Item; class UnknownBlock extends Transparent{ - public function __construct(BlockIdentifier $idInfo){ - parent::__construct($idInfo, "Unknown"); + public function __construct(BlockIdentifier $idInfo, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, "Unknown", $breakInfo ?? BlockBreakInfo::instant()); } public function canBePlaced() : bool{ return false; } - public function getHardness() : float{ - return 0; - } - public function getDrops(Item $item) : array{ return []; } diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index 1fa2112b27..40f7278ed3 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -42,6 +42,10 @@ class Vine extends Flowable{ /** @var bool[] */ protected $faces = []; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::TYPE_AXE)); + } + protected function writeStateToMeta() : int{ return (isset($this->faces[Facing::SOUTH]) ? self::FLAG_SOUTH : 0) | @@ -67,10 +71,6 @@ class Vine extends Flowable{ } } - public function getHardness() : float{ - return 0.2; - } - public function hasEntityCollision() : bool{ return true; } @@ -193,10 +193,6 @@ class Vine extends Flowable{ return []; } - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; - } - public function getFlameEncouragement() : int{ return 15; } diff --git a/src/pocketmine/block/Wall.php b/src/pocketmine/block/Wall.php index 389b8619bf..c586fb1d7b 100644 --- a/src/pocketmine/block/Wall.php +++ b/src/pocketmine/block/Wall.php @@ -48,16 +48,8 @@ class Wall extends Transparent{ /** @var bool */ protected $up = false; - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; - } - - public function getHardness() : float{ - return 2; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } public function readStateFromWorld() : void{ diff --git a/src/pocketmine/block/WaterLily.php b/src/pocketmine/block/WaterLily.php index 00eb99f514..b93f6d9d38 100644 --- a/src/pocketmine/block/WaterLily.php +++ b/src/pocketmine/block/WaterLily.php @@ -31,8 +31,8 @@ use pocketmine\Player; class WaterLily extends Flowable{ - public function getHardness() : float{ - return 0.6; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6)); } protected function recalculateBoundingBox() : ?AxisAlignedBB{ diff --git a/src/pocketmine/block/WeightedPressurePlateHeavy.php b/src/pocketmine/block/WeightedPressurePlateHeavy.php index cc465d3d19..00220d80c8 100644 --- a/src/pocketmine/block/WeightedPressurePlateHeavy.php +++ b/src/pocketmine/block/WeightedPressurePlateHeavy.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class WeightedPressurePlateHeavy extends WeightedPressurePlate{ - public function getHardness() : float{ - return 0.5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); } } diff --git a/src/pocketmine/block/WeightedPressurePlateLight.php b/src/pocketmine/block/WeightedPressurePlateLight.php index df13188ce9..54cf57f5f8 100644 --- a/src/pocketmine/block/WeightedPressurePlateLight.php +++ b/src/pocketmine/block/WeightedPressurePlateLight.php @@ -27,15 +27,7 @@ use pocketmine\item\TieredTool; class WeightedPressurePlateLight extends WeightedPressurePlate{ - public function getHardness() : float{ - return 0.5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_PICKAXE; - } - - public function getToolHarvestLevel() : int{ - return TieredTool::TIER_WOODEN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); } } diff --git a/src/pocketmine/block/Wood.php b/src/pocketmine/block/Wood.php index f9dd1c74a1..2882c002c1 100644 --- a/src/pocketmine/block/Wood.php +++ b/src/pocketmine/block/Wood.php @@ -30,8 +30,8 @@ class Wood extends Solid{ /** @var TreeType */ private $treeType; - public function __construct(BlockIdentifier $idInfo, string $name, TreeType $treeType){ - parent::__construct($idInfo, $name); + public function __construct(BlockIdentifier $idInfo, string $name, TreeType $treeType, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_AXE)); $this->treeType = $treeType; } @@ -43,14 +43,6 @@ class Wood extends Solid{ return $this->treeType; } - public function getHardness() : float{ - return 2; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; - } - public function getFuelTime() : int{ return 300; } diff --git a/src/pocketmine/block/WoodenButton.php b/src/pocketmine/block/WoodenButton.php index d81b4e53b5..0cbec1f93b 100644 --- a/src/pocketmine/block/WoodenButton.php +++ b/src/pocketmine/block/WoodenButton.php @@ -25,12 +25,8 @@ namespace pocketmine\block; class WoodenButton extends Button{ - public function getHardness() : float{ - return 0.5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_AXE)); } protected function getActivationTime() : int{ diff --git a/src/pocketmine/block/WoodenDoor.php b/src/pocketmine/block/WoodenDoor.php index 2ef5155c31..1686a7c820 100644 --- a/src/pocketmine/block/WoodenDoor.php +++ b/src/pocketmine/block/WoodenDoor.php @@ -25,11 +25,7 @@ namespace pocketmine\block; class WoodenDoor extends Door{ - public function getHardness() : float{ - return 3; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_AXE)); } } diff --git a/src/pocketmine/block/WoodenFence.php b/src/pocketmine/block/WoodenFence.php index 3190e9d877..eec484a7f1 100644 --- a/src/pocketmine/block/WoodenFence.php +++ b/src/pocketmine/block/WoodenFence.php @@ -25,12 +25,8 @@ namespace pocketmine\block; class WoodenFence extends Fence{ - public function getHardness() : float{ - return 2; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_AXE, 0, 15.0)); } public function getFuelTime() : int{ diff --git a/src/pocketmine/block/WoodenPressurePlate.php b/src/pocketmine/block/WoodenPressurePlate.php index 62ccef9500..996ec27d1b 100644 --- a/src/pocketmine/block/WoodenPressurePlate.php +++ b/src/pocketmine/block/WoodenPressurePlate.php @@ -25,15 +25,11 @@ namespace pocketmine\block; class WoodenPressurePlate extends SimplePressurePlate{ + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_AXE)); + } + public function getFuelTime() : int{ return 300; } - - public function getHardness() : float{ - return 0.5; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; - } } diff --git a/src/pocketmine/block/WoodenSlab.php b/src/pocketmine/block/WoodenSlab.php index c1a9de02f3..474036490a 100644 --- a/src/pocketmine/block/WoodenSlab.php +++ b/src/pocketmine/block/WoodenSlab.php @@ -25,12 +25,8 @@ namespace pocketmine\block; class WoodenSlab extends Slab{ - public function getHardness() : float{ - return 2; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; + public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_AXE, 0, 15.0)); } public function getFuelTime() : int{ diff --git a/src/pocketmine/block/WoodenStairs.php b/src/pocketmine/block/WoodenStairs.php index 0d6537ed4d..09d7ab2b25 100644 --- a/src/pocketmine/block/WoodenStairs.php +++ b/src/pocketmine/block/WoodenStairs.php @@ -25,16 +25,8 @@ namespace pocketmine\block; class WoodenStairs extends Stair{ - public function getHardness() : float{ - return 2; - } - - public function getBlastResistance() : float{ - return 15; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_AXE, 0, 15.0)); } public function getFlameEncouragement() : int{ diff --git a/src/pocketmine/block/WoodenTrapdoor.php b/src/pocketmine/block/WoodenTrapdoor.php index 8aaf8ccb8a..ace3a2baae 100644 --- a/src/pocketmine/block/WoodenTrapdoor.php +++ b/src/pocketmine/block/WoodenTrapdoor.php @@ -25,12 +25,8 @@ namespace pocketmine\block; class WoodenTrapdoor extends Trapdoor{ - public function getHardness() : float{ - return 3; - } - - public function getToolType() : int{ - return BlockToolType::TYPE_AXE; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_AXE, 0, 15.0)); } public function getFuelTime() : int{ diff --git a/src/pocketmine/block/Wool.php b/src/pocketmine/block/Wool.php index 0a7b107f53..c13ad3af0d 100644 --- a/src/pocketmine/block/Wool.php +++ b/src/pocketmine/block/Wool.php @@ -27,21 +27,18 @@ use pocketmine\item\Item; class Wool extends Solid{ - public function getHardness() : float{ - return 0.8; - } + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? new class(0.8, BlockToolType::TYPE_SHEARS) extends BlockBreakInfo{ + public function getBreakTime(Item $item) : float{ + $time = parent::getBreakTime($item); + if($item->getBlockToolType() === BlockToolType::TYPE_SHEARS){ + $time *= 3; //shears break compatible blocks 15x faster, but wool 5x + } - public function getToolType() : int{ - return BlockToolType::TYPE_SHEARS; - } - - public function getBreakTime(Item $item) : float{ - $time = parent::getBreakTime($item); - if($item->getBlockToolType() === BlockToolType::TYPE_SHEARS){ - $time *= 3; //shears break compatible blocks 15x faster, but wool 5x - } - - return $time; + return $time; + } + } + ); } public function getFlameEncouragement() : int{ diff --git a/src/pocketmine/item/Axe.php b/src/pocketmine/item/Axe.php index 1369110e37..08c08f953f 100644 --- a/src/pocketmine/item/Axe.php +++ b/src/pocketmine/item/Axe.php @@ -42,7 +42,7 @@ class Axe extends TieredTool{ } public function onDestroyBlock(Block $block) : bool{ - if($block->getHardness() > 0){ + if(!$block->getBreakInfo()->breaksInstantly()){ return $this->applyDamage(1); } return false; diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 82877b40d7..39d03d4db9 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -27,6 +27,7 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\Block; +use pocketmine\block\BlockBreakInfo; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\block\BlockToolType; @@ -665,7 +666,7 @@ class Item implements ItemIds, \JsonSerializable{ * the mined block. * This should return 1 for non-tiered tools, and the tool tier for tiered tools. * - * @see Block::getToolHarvestLevel() + * @see BlockBreakInfo::getToolHarvestLevel() * * @return int */ diff --git a/src/pocketmine/item/Pickaxe.php b/src/pocketmine/item/Pickaxe.php index 64bef6a3fe..d5b49c3fa2 100644 --- a/src/pocketmine/item/Pickaxe.php +++ b/src/pocketmine/item/Pickaxe.php @@ -42,7 +42,7 @@ class Pickaxe extends TieredTool{ } public function onDestroyBlock(Block $block) : bool{ - if($block->getHardness() > 0){ + if(!$block->getBreakInfo()->breaksInstantly()){ return $this->applyDamage(1); } return false; diff --git a/src/pocketmine/item/Shears.php b/src/pocketmine/item/Shears.php index 4bd563e8e7..811bb380f1 100644 --- a/src/pocketmine/item/Shears.php +++ b/src/pocketmine/item/Shears.php @@ -48,9 +48,6 @@ class Shears extends Tool{ } public function onDestroyBlock(Block $block) : bool{ - if($block->getHardness() === 0 or $block->isCompatibleWithTool($this)){ - return $this->applyDamage(1); - } - return false; + return $this->applyDamage(1); } } diff --git a/src/pocketmine/item/Shovel.php b/src/pocketmine/item/Shovel.php index fe4ebe9e80..d9a1b0f500 100644 --- a/src/pocketmine/item/Shovel.php +++ b/src/pocketmine/item/Shovel.php @@ -42,7 +42,7 @@ class Shovel extends TieredTool{ } public function onDestroyBlock(Block $block) : bool{ - if($block->getHardness() > 0){ + if(!$block->getBreakInfo()->breaksInstantly()){ return $this->applyDamage(1); } return false; diff --git a/src/pocketmine/item/Sword.php b/src/pocketmine/item/Sword.php index 39d72a6716..5f801461d4 100644 --- a/src/pocketmine/item/Sword.php +++ b/src/pocketmine/item/Sword.php @@ -50,7 +50,7 @@ class Sword extends TieredTool{ } public function onDestroyBlock(Block $block) : bool{ - if($block->getHardness() > 0){ + if(!$block->getBreakInfo()->breaksInstantly()){ return $this->applyDamage(2); } return false; diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 5ec6013734..48df73655d 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -1680,7 +1680,7 @@ class World implements ChunkManager, Metadatable{ if($player !== null){ $ev = new BlockBreakEvent($player, $target, $item, $player->isCreative(), $drops, $xpDrop); - if($target instanceof Air or ($player->isSurvival() and !$target->isBreakable($item)) or $player->isSpectator()){ + if($target instanceof Air or ($player->isSurvival() and !$target->getBreakInfo()->isBreakable()) or $player->isSpectator()){ $ev->setCancelled(); } @@ -1710,7 +1710,7 @@ class World implements ChunkManager, Metadatable{ $drops = $ev->getDrops(); $xpDrop = $ev->getXpDropAmount(); - }elseif(!$target->isBreakable($item)){ + }elseif(!$target->getBreakInfo()->isBreakable()){ return false; } diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index 2911838221..8c3fbc6a06 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -57,7 +57,7 @@ class BlockTest extends TestCase{ public function testRegisterNewBlock() : void{ for($i = 0; $i < 256; ++$i){ if(!BlockFactory::isRegistered($i)){ - $b = new StrangeNewBlock(new BlockIdentifier($i), "Strange New Block"); + $b = new StrangeNewBlock(new BlockIdentifier($i), "Strange New Block", BlockBreakInfo::instant()); BlockFactory::register($b); self::assertInstanceOf(StrangeNewBlock::class, BlockFactory::get($b->getId())); return; @@ -72,7 +72,7 @@ class BlockTest extends TestCase{ */ public function testRegisterIdTooLarge() : void{ self::expectException(\RuntimeException::class); - BlockFactory::register(new OutOfBoundsBlock(new BlockIdentifier(25555), "Out Of Bounds Block")); + BlockFactory::register(new OutOfBoundsBlock(new BlockIdentifier(25555), "Out Of Bounds Block", BlockBreakInfo::instant())); } /** @@ -80,7 +80,7 @@ class BlockTest extends TestCase{ */ public function testRegisterIdTooSmall() : void{ self::expectException(\RuntimeException::class); - BlockFactory::register(new OutOfBoundsBlock(new BlockIdentifier(-1), "Out Of Bounds Block")); + BlockFactory::register(new OutOfBoundsBlock(new BlockIdentifier(-1), "Out Of Bounds Block", BlockBreakInfo::instant())); } /** diff --git a/tests/plugins/PocketMine-DevTools b/tests/plugins/PocketMine-DevTools index 9a992364d4..c0f0f9383d 160000 --- a/tests/plugins/PocketMine-DevTools +++ b/tests/plugins/PocketMine-DevTools @@ -1 +1 @@ -Subproject commit 9a992364d4458ccf09640befeb0e991b5d67ad8a +Subproject commit c0f0f9383d27d0efb2c1d04ea3678beb6a14d3af diff --git a/tests/preprocessor b/tests/preprocessor index 63e0092d62..b01f50c50e 160000 --- a/tests/preprocessor +++ b/tests/preprocessor @@ -1 +1 @@ -Subproject commit 63e0092d623d13e47f9083b3d65fdf431933a471 +Subproject commit b01f50c50ef6546d000bdde16dc868b4147b31ba From 01ad568256f1da27dc0b034b2a9346c8b433f782 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 10 May 2019 16:30:14 +0100 Subject: [PATCH 0794/3224] Air: use BlockBreakInfo::indestructible() --- src/pocketmine/block/Air.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/Air.php b/src/pocketmine/block/Air.php index 995c68d0ff..88f4063f09 100644 --- a/src/pocketmine/block/Air.php +++ b/src/pocketmine/block/Air.php @@ -31,7 +31,7 @@ use pocketmine\math\AxisAlignedBB; class Air extends Transparent{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(-1.0, BlockToolType::TYPE_NONE, 0, 0.0)); + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::indestructible(0.0)); } public function canBeFlowedInto() : bool{ From 650e186481a8a4917997bcf08fa70919d1e7057e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 10 May 2019 17:00:01 +0100 Subject: [PATCH 0795/3224] Removed bad assumption that every Flowable descendent is an instant-breaking block I'm wondering if there is even a point to Flowable at this point. Half of the blocks inheriting from it do not break instantly, or have some other modification to tool requirements. --- src/pocketmine/block/Crops.php | 4 ++++ src/pocketmine/block/Dandelion.php | 3 +++ src/pocketmine/block/DoublePlant.php | 4 ++++ src/pocketmine/block/EndRod.php | 4 ++++ src/pocketmine/block/Fire.php | 4 ++++ src/pocketmine/block/Flowable.php | 4 ---- src/pocketmine/block/Flower.php | 4 ++++ src/pocketmine/block/FlowerPot.php | 4 ++++ src/pocketmine/block/NetherWartPlant.php | 4 ++++ src/pocketmine/block/RedMushroom.php | 4 ++++ src/pocketmine/block/RedstoneComparator.php | 4 ++-- src/pocketmine/block/RedstoneRepeater.php | 4 ++-- src/pocketmine/block/RedstoneWire.php | 4 ++++ src/pocketmine/block/Sapling.php | 4 ++-- src/pocketmine/block/Stem.php | 4 ++++ src/pocketmine/block/Sugarcane.php | 4 ++++ src/pocketmine/block/Torch.php | 4 ++++ src/pocketmine/block/Tripwire.php | 4 ++++ src/pocketmine/block/TripwireHook.php | 4 ++++ 19 files changed, 65 insertions(+), 10 deletions(-) diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index 4c6e84536a..2609134d63 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -36,6 +36,10 @@ abstract class Crops extends Flowable{ /** @var int */ protected $age = 0; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); + } + protected function writeStateToMeta() : int{ return $this->age; } diff --git a/src/pocketmine/block/Dandelion.php b/src/pocketmine/block/Dandelion.php index b80b8d8b76..d562afbd82 100644 --- a/src/pocketmine/block/Dandelion.php +++ b/src/pocketmine/block/Dandelion.php @@ -30,6 +30,9 @@ use pocketmine\Player; class Dandelion extends Flowable{ + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); + } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index c58abbab0a..8b2562a94b 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -35,6 +35,10 @@ class DoublePlant extends Flowable{ /** @var bool */ protected $top = false; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); + } + protected function writeStateToMeta() : int{ return ($this->top ? self::BITFLAG_TOP : 0); } diff --git a/src/pocketmine/block/EndRod.php b/src/pocketmine/block/EndRod.php index 1290815382..ecf7243022 100644 --- a/src/pocketmine/block/EndRod.php +++ b/src/pocketmine/block/EndRod.php @@ -35,6 +35,10 @@ class EndRod extends Flowable{ /** @var int */ protected $facing = Facing::DOWN; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); + } + protected function writeStateToMeta() : int{ if(Facing::axis($this->facing) === Facing::AXIS_Y){ return $this->facing; diff --git a/src/pocketmine/block/Fire.php b/src/pocketmine/block/Fire.php index 29dd6caaef..68b96942b7 100644 --- a/src/pocketmine/block/Fire.php +++ b/src/pocketmine/block/Fire.php @@ -40,6 +40,10 @@ class Fire extends Flowable{ /** @var int */ protected $age = 0; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); + } + protected function writeStateToMeta() : int{ return $this->age; } diff --git a/src/pocketmine/block/Flowable.php b/src/pocketmine/block/Flowable.php index 1461925070..fd98e057f9 100644 --- a/src/pocketmine/block/Flowable.php +++ b/src/pocketmine/block/Flowable.php @@ -27,10 +27,6 @@ use pocketmine\math\AxisAlignedBB; abstract class Flowable extends Transparent{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); - } - public function canBeFlowedInto() : bool{ return true; } diff --git a/src/pocketmine/block/Flower.php b/src/pocketmine/block/Flower.php index 165abadfed..af4ff97ffd 100644 --- a/src/pocketmine/block/Flower.php +++ b/src/pocketmine/block/Flower.php @@ -41,6 +41,10 @@ class Flower extends Flowable{ public const TYPE_CORNFLOWER = 9; public const TYPE_LILY_OF_THE_VALLEY = 10; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); + } + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === BlockLegacyIds::GRASS or $down->getId() === BlockLegacyIds::DIRT or $down->getId() === BlockLegacyIds::FARMLAND){ diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 1c2644c9b7..2cd993830f 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -42,6 +42,10 @@ class FlowerPot extends Flowable{ /** @var Block|null */ protected $plant = null; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); + } + protected function writeStateToMeta() : int{ return $this->occupied ? 1 : 0; } diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index 6d14c1c43a..8fd0a6a31c 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -37,6 +37,10 @@ class NetherWartPlant extends Flowable{ /** @var int */ protected $age = 0; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); + } + protected function writeStateToMeta() : int{ return $this->age; } diff --git a/src/pocketmine/block/RedMushroom.php b/src/pocketmine/block/RedMushroom.php index 1f6a98bad8..40c0652005 100644 --- a/src/pocketmine/block/RedMushroom.php +++ b/src/pocketmine/block/RedMushroom.php @@ -30,6 +30,10 @@ use pocketmine\Player; class RedMushroom extends Flowable{ + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); + } + public function ticksRandomly() : bool{ return true; } diff --git a/src/pocketmine/block/RedstoneComparator.php b/src/pocketmine/block/RedstoneComparator.php index aea91205c0..2ec142ea05 100644 --- a/src/pocketmine/block/RedstoneComparator.php +++ b/src/pocketmine/block/RedstoneComparator.php @@ -46,8 +46,8 @@ class RedstoneComparator extends Flowable{ /** @var int */ protected $signalStrength = 0; - public function __construct(BlockIdentifierFlattened $idInfo, string $name){ - parent::__construct($idInfo, $name); + public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); } public function getId() : int{ diff --git a/src/pocketmine/block/RedstoneRepeater.php b/src/pocketmine/block/RedstoneRepeater.php index 6f7a4070f7..8c4dbec511 100644 --- a/src/pocketmine/block/RedstoneRepeater.php +++ b/src/pocketmine/block/RedstoneRepeater.php @@ -42,8 +42,8 @@ class RedstoneRepeater extends Flowable{ /** @var int */ protected $delay = 1; - public function __construct(BlockIdentifierFlattened $idInfo, string $name){ - parent::__construct($idInfo, $name); + public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); } public function getId() : int{ diff --git a/src/pocketmine/block/RedstoneWire.php b/src/pocketmine/block/RedstoneWire.php index 6f95e906b4..a665db097c 100644 --- a/src/pocketmine/block/RedstoneWire.php +++ b/src/pocketmine/block/RedstoneWire.php @@ -30,6 +30,10 @@ class RedstoneWire extends Flowable{ /** @var int */ protected $power = 0; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); + } + public function readStateFromData(int $id, int $stateMeta) : void{ $this->power = BlockDataValidator::readBoundedInt("power", $stateMeta, 0, 15); } diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index 06a164e118..a16cadb71b 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -40,8 +40,8 @@ class Sapling extends Flowable{ /** @var TreeType */ private $treeType; - public function __construct(BlockIdentifier $idInfo, string $name, TreeType $treeType){ - parent::__construct($idInfo, $name); + public function __construct(BlockIdentifier $idInfo, string $name, TreeType $treeType, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); $this->treeType = $treeType; } diff --git a/src/pocketmine/block/Stem.php b/src/pocketmine/block/Stem.php index 0bc2b478bf..4d0dbf8490 100644 --- a/src/pocketmine/block/Stem.php +++ b/src/pocketmine/block/Stem.php @@ -31,6 +31,10 @@ use function mt_rand; abstract class Stem extends Crops{ + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); + } + abstract protected function getPlant() : Block; public function onRandomTick() : void{ diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index 9c2abd907e..4f8c01c4cf 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -36,6 +36,10 @@ class Sugarcane extends Flowable{ /** @var int */ protected $age = 0; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); + } + protected function writeStateToMeta() : int{ return $this->age; } diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index e5a5533b66..24e7e4573c 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -34,6 +34,10 @@ class Torch extends Flowable{ /** @var int */ protected $facing = Facing::UP; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); + } + protected function writeStateToMeta() : int{ return 6 - $this->facing; } diff --git a/src/pocketmine/block/Tripwire.php b/src/pocketmine/block/Tripwire.php index 3b68142ac4..d1a4732c47 100644 --- a/src/pocketmine/block/Tripwire.php +++ b/src/pocketmine/block/Tripwire.php @@ -34,6 +34,10 @@ class Tripwire extends Flowable{ /** @var bool */ protected $disarmed = false; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); + } + protected function writeStateToMeta() : int{ return ($this->triggered ? 0x01 : 0) | ($this->suspended ? 0x02 : 0) | ($this->connected ? 0x04 : 0) | ($this->disarmed ? 0x08 : 0); } diff --git a/src/pocketmine/block/TripwireHook.php b/src/pocketmine/block/TripwireHook.php index b91887f36b..f54ed36aaf 100644 --- a/src/pocketmine/block/TripwireHook.php +++ b/src/pocketmine/block/TripwireHook.php @@ -39,6 +39,10 @@ class TripwireHook extends Flowable{ /** @var bool */ protected $powered = false; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); + } + protected function writeStateToMeta() : int{ return Bearing::fromFacing($this->facing) | ($this->connected ? 0x04 : 0) | ($this->powered ? 0x08 : 0); } From 0bf7fd2c0d823c6e1c1070e42e169fa6c432b1f8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 11 May 2019 09:46:20 +0100 Subject: [PATCH 0796/3224] Partially revert "Separate block break-info to a separate dynamic unit" This reverts commit 9e72bc91a2987aa43fb1d25715b5aff789b27b63. --- tests/plugins/PocketMine-DevTools | 2 +- tests/preprocessor | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/plugins/PocketMine-DevTools b/tests/plugins/PocketMine-DevTools index c0f0f9383d..9a992364d4 160000 --- a/tests/plugins/PocketMine-DevTools +++ b/tests/plugins/PocketMine-DevTools @@ -1 +1 @@ -Subproject commit c0f0f9383d27d0efb2c1d04ea3678beb6a14d3af +Subproject commit 9a992364d4458ccf09640befeb0e991b5d67ad8a diff --git a/tests/preprocessor b/tests/preprocessor index b01f50c50e..63e0092d62 160000 --- a/tests/preprocessor +++ b/tests/preprocessor @@ -1 +1 @@ -Subproject commit b01f50c50ef6546d000bdde16dc868b4147b31ba +Subproject commit 63e0092d623d13e47f9083b3d65fdf431933a471 From 51f96b195eeb85ecbfca6357517c4685a84dd62a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 11 May 2019 18:00:56 +0100 Subject: [PATCH 0797/3224] ItemFactory: fix wrong typehint --- src/pocketmine/item/ItemFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 24017c86ff..119682ffe4 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -45,7 +45,7 @@ use function trim; */ class ItemFactory{ - /** @var \SplFixedArray */ + /** @var Item[] */ private static $list = []; /** @var Item|null */ From c99846e0698161239b8ca5847b8c770eaa79bee5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 11 May 2019 18:24:21 +0100 Subject: [PATCH 0798/3224] Unify Item constructor style this exposed a few more dead classes. --- src/pocketmine/item/Apple.php | 3 - src/pocketmine/item/Arrow.php | 4 +- src/pocketmine/item/BakedPotato.php | 3 - src/pocketmine/item/Banner.php | 4 +- src/pocketmine/item/Bed.php | 4 +- src/pocketmine/item/Beetroot.php | 3 - src/pocketmine/item/BeetrootSeeds.php | 3 - src/pocketmine/item/BeetrootSoup.php | 3 - src/pocketmine/item/BlazeRod.php | 4 - src/pocketmine/item/Boat.php | 4 +- src/pocketmine/item/Book.php | 4 +- src/pocketmine/item/Bow.php | 5 +- src/pocketmine/item/Bowl.php | 3 - src/pocketmine/item/Bread.php | 3 - src/pocketmine/item/Carrot.php | 3 - src/pocketmine/item/ChorusFruit.php | 4 - src/pocketmine/item/Clock.php | 4 +- src/pocketmine/item/Clownfish.php | 3 - src/pocketmine/item/Compass.php | 4 +- src/pocketmine/item/CookedChicken.php | 3 - src/pocketmine/item/CookedFish.php | 3 - src/pocketmine/item/CookedMutton.php | 3 - src/pocketmine/item/CookedPorkchop.php | 3 - src/pocketmine/item/CookedRabbit.php | 3 - src/pocketmine/item/CookedSalmon.php | 3 - src/pocketmine/item/Cookie.php | 3 - src/pocketmine/item/DriedKelp.php | 3 - src/pocketmine/item/Dye.php | 4 +- src/pocketmine/item/Egg.php | 3 - src/pocketmine/item/EnderPearl.php | 3 - src/pocketmine/item/ExperienceBottle.php | 3 - src/pocketmine/item/FishingRod.php | 3 - src/pocketmine/item/FlintSteel.php | 3 - src/pocketmine/item/GlassBottle.php | 4 +- src/pocketmine/item/GoldenApple.php | 4 - src/pocketmine/item/GoldenAppleEnchanted.php | 4 - src/pocketmine/item/GoldenCarrot.php | 3 - src/pocketmine/item/ItemFactory.php | 140 +++++++++---------- src/pocketmine/item/Melon.php | 3 - src/pocketmine/item/MelonSeeds.php | 3 - src/pocketmine/item/Minecart.php | 3 - src/pocketmine/item/MushroomStew.php | 3 - src/pocketmine/item/PaintingItem.php | 3 - src/pocketmine/item/PoisonousPotato.php | 3 - src/pocketmine/item/Potato.php | 3 - src/pocketmine/item/Potion.php | 4 - src/pocketmine/item/Pufferfish.php | 3 - src/pocketmine/item/PumpkinPie.php | 3 - src/pocketmine/item/PumpkinSeeds.php | 3 - src/pocketmine/item/RabbitStew.php | 3 - src/pocketmine/item/RawBeef.php | 3 - src/pocketmine/item/RawChicken.php | 3 - src/pocketmine/item/RawFish.php | 3 - src/pocketmine/item/RawMutton.php | 3 - src/pocketmine/item/RawPorkchop.php | 3 - src/pocketmine/item/RawRabbit.php | 3 - src/pocketmine/item/RawSalmon.php | 3 - src/pocketmine/item/Redstone.php | 3 - src/pocketmine/item/RottenFlesh.php | 4 - src/pocketmine/item/Shears.php | 3 - src/pocketmine/item/Snowball.php | 3 - src/pocketmine/item/SpawnEgg.php | 5 +- src/pocketmine/item/SpiderEye.php | 3 - src/pocketmine/item/SplashPotion.php | 4 - src/pocketmine/item/Steak.php | 3 - src/pocketmine/item/Stick.php | 3 - src/pocketmine/item/StringItem.php | 3 - src/pocketmine/item/Totem.php | 3 - src/pocketmine/item/WheatSeeds.php | 3 - src/pocketmine/item/WritableBook.php | 3 - src/pocketmine/item/WrittenBook.php | 4 - 71 files changed, 87 insertions(+), 284 deletions(-) diff --git a/src/pocketmine/item/Apple.php b/src/pocketmine/item/Apple.php index eea93a02fd..82dfcf7890 100644 --- a/src/pocketmine/item/Apple.php +++ b/src/pocketmine/item/Apple.php @@ -25,9 +25,6 @@ namespace pocketmine\item; class Apple extends Food{ - public function __construct(){ - parent::__construct(self::APPLE, 0, "Apple"); - } public function getFoodRestore() : int{ return 4; diff --git a/src/pocketmine/item/Arrow.php b/src/pocketmine/item/Arrow.php index dab935e877..592d76141a 100644 --- a/src/pocketmine/item/Arrow.php +++ b/src/pocketmine/item/Arrow.php @@ -24,7 +24,5 @@ declare(strict_types=1); namespace pocketmine\item; class Arrow extends Item{ - public function __construct(){ - parent::__construct(self::ARROW, 0, "Arrow"); - } + } diff --git a/src/pocketmine/item/BakedPotato.php b/src/pocketmine/item/BakedPotato.php index 95b45e682b..c4527e7697 100644 --- a/src/pocketmine/item/BakedPotato.php +++ b/src/pocketmine/item/BakedPotato.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class BakedPotato extends Food{ - public function __construct(){ - parent::__construct(self::BAKED_POTATO, 0, "Baked Potato"); - } public function getFoodRestore() : int{ return 5; diff --git a/src/pocketmine/item/Banner.php b/src/pocketmine/item/Banner.php index 473158f623..f6866880d3 100644 --- a/src/pocketmine/item/Banner.php +++ b/src/pocketmine/item/Banner.php @@ -41,8 +41,8 @@ class Banner extends Item{ /** @var DyeColor */ private $color; - public function __construct(int $variant, string $name, DyeColor $color){ - parent::__construct(self::BANNER, $variant, $name); + public function __construct(int $id, int $variant, string $name, DyeColor $color){ + parent::__construct($id, $variant, $name); $this->color = $color; } diff --git a/src/pocketmine/item/Bed.php b/src/pocketmine/item/Bed.php index 3b83cd19f2..cf1095ab60 100644 --- a/src/pocketmine/item/Bed.php +++ b/src/pocketmine/item/Bed.php @@ -33,8 +33,8 @@ class Bed extends Item{ /** @var DyeColor */ private $color; - public function __construct(int $variant, string $name, DyeColor $color){ - parent::__construct(self::BED, $variant, $name); + public function __construct(int $id, int $variant, string $name, DyeColor $color){ + parent::__construct($id, $variant, $name); $this->color = $color; } diff --git a/src/pocketmine/item/Beetroot.php b/src/pocketmine/item/Beetroot.php index aa6d2e7a36..63b990a159 100644 --- a/src/pocketmine/item/Beetroot.php +++ b/src/pocketmine/item/Beetroot.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class Beetroot extends Food{ - public function __construct(){ - parent::__construct(self::BEETROOT, 0, "Beetroot"); - } public function getFoodRestore() : int{ return 1; diff --git a/src/pocketmine/item/BeetrootSeeds.php b/src/pocketmine/item/BeetrootSeeds.php index a5f961f60a..216148a729 100644 --- a/src/pocketmine/item/BeetrootSeeds.php +++ b/src/pocketmine/item/BeetrootSeeds.php @@ -28,9 +28,6 @@ use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; class BeetrootSeeds extends Item{ - public function __construct(){ - parent::__construct(self::BEETROOT_SEEDS, 0, "Beetroot Seeds"); - } public function getBlock() : Block{ return BlockFactory::get(BlockLegacyIds::BEETROOT_BLOCK); diff --git a/src/pocketmine/item/BeetrootSoup.php b/src/pocketmine/item/BeetrootSoup.php index 0f805fb565..ab274c9259 100644 --- a/src/pocketmine/item/BeetrootSoup.php +++ b/src/pocketmine/item/BeetrootSoup.php @@ -25,9 +25,6 @@ namespace pocketmine\item; class BeetrootSoup extends Food{ - public function __construct(){ - parent::__construct(self::BEETROOT_SOUP, 0, "Beetroot Soup"); - } public function getMaxStackSize() : int{ return 1; diff --git a/src/pocketmine/item/BlazeRod.php b/src/pocketmine/item/BlazeRod.php index 98e55369b9..34a6e1e0d6 100644 --- a/src/pocketmine/item/BlazeRod.php +++ b/src/pocketmine/item/BlazeRod.php @@ -25,10 +25,6 @@ namespace pocketmine\item; class BlazeRod extends Item{ - public function __construct(){ - parent::__construct(self::BLAZE_ROD, 0, "Blaze Rod"); - } - public function getFuelTime() : int{ return 2400; } diff --git a/src/pocketmine/item/Boat.php b/src/pocketmine/item/Boat.php index 122e4fa0d4..55a521423c 100644 --- a/src/pocketmine/item/Boat.php +++ b/src/pocketmine/item/Boat.php @@ -29,8 +29,8 @@ class Boat extends Item{ /** @var TreeType */ private $woodType; - public function __construct(TreeType $woodType){ - parent::__construct(self::BOAT, $woodType->getMagicNumber(), $woodType->getDisplayName() . " Boat"); + public function __construct(int $id, int $variant, string $name, TreeType $woodType){ + parent::__construct($id, $variant, $name); $this->woodType = $woodType; } diff --git a/src/pocketmine/item/Book.php b/src/pocketmine/item/Book.php index 002fb5c84d..0020594dff 100644 --- a/src/pocketmine/item/Book.php +++ b/src/pocketmine/item/Book.php @@ -24,7 +24,5 @@ declare(strict_types=1); namespace pocketmine\item; class Book extends Item{ - public function __construct(){ - parent::__construct(self::BOOK, 0, "Book"); - } + } diff --git a/src/pocketmine/item/Bow.php b/src/pocketmine/item/Bow.php index 290a220d40..51ed4dcdaf 100644 --- a/src/pocketmine/item/Bow.php +++ b/src/pocketmine/item/Bow.php @@ -29,15 +29,12 @@ use pocketmine\entity\projectile\Projectile; use pocketmine\event\entity\EntityShootBowEvent; use pocketmine\event\entity\ProjectileLaunchEvent; use pocketmine\item\enchantment\Enchantment; -use pocketmine\world\sound\BowShootSound; use pocketmine\Player; +use pocketmine\world\sound\BowShootSound; use function intdiv; use function min; class Bow extends Tool{ - public function __construct(){ - parent::__construct(self::BOW, 0, "Bow"); - } public function getFuelTime() : int{ return 200; diff --git a/src/pocketmine/item/Bowl.php b/src/pocketmine/item/Bowl.php index e2b4a6bf5f..47b93a2a86 100644 --- a/src/pocketmine/item/Bowl.php +++ b/src/pocketmine/item/Bowl.php @@ -25,9 +25,6 @@ namespace pocketmine\item; class Bowl extends Item{ - public function __construct(){ - parent::__construct(self::BOWL, 0, "Bowl"); - } //TODO: check fuel } diff --git a/src/pocketmine/item/Bread.php b/src/pocketmine/item/Bread.php index ad6bd73c16..2687fccffd 100644 --- a/src/pocketmine/item/Bread.php +++ b/src/pocketmine/item/Bread.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class Bread extends Food{ - public function __construct(){ - parent::__construct(self::BREAD, 0, "Bread"); - } public function getFoodRestore() : int{ return 5; diff --git a/src/pocketmine/item/Carrot.php b/src/pocketmine/item/Carrot.php index e402f07eeb..92491c4322 100644 --- a/src/pocketmine/item/Carrot.php +++ b/src/pocketmine/item/Carrot.php @@ -28,9 +28,6 @@ use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; class Carrot extends Food{ - public function __construct(){ - parent::__construct(self::CARROT, 0, "Carrot"); - } public function getBlock() : Block{ return BlockFactory::get(BlockLegacyIds::CARROT_BLOCK); diff --git a/src/pocketmine/item/ChorusFruit.php b/src/pocketmine/item/ChorusFruit.php index 5bbb9dd10d..72a8b987b3 100644 --- a/src/pocketmine/item/ChorusFruit.php +++ b/src/pocketmine/item/ChorusFruit.php @@ -33,10 +33,6 @@ use function mt_rand; class ChorusFruit extends Food{ - public function __construct(){ - parent::__construct(self::CHORUS_FRUIT, 0, "Chorus Fruit"); - } - public function getFoodRestore() : int{ return 4; } diff --git a/src/pocketmine/item/Clock.php b/src/pocketmine/item/Clock.php index 0c32657282..78f9f3ccb4 100644 --- a/src/pocketmine/item/Clock.php +++ b/src/pocketmine/item/Clock.php @@ -24,7 +24,5 @@ declare(strict_types=1); namespace pocketmine\item; class Clock extends Item{ - public function __construct(){ - parent::__construct(self::CLOCK, 0, "Clock"); - } + } diff --git a/src/pocketmine/item/Clownfish.php b/src/pocketmine/item/Clownfish.php index e776dbcdfd..1dba40e748 100644 --- a/src/pocketmine/item/Clownfish.php +++ b/src/pocketmine/item/Clownfish.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class Clownfish extends Food{ - public function __construct(){ - parent::__construct(self::CLOWNFISH, 0, "Clownfish"); - } public function getFoodRestore() : int{ return 1; diff --git a/src/pocketmine/item/Compass.php b/src/pocketmine/item/Compass.php index 5eccdbfc47..12677ae9a3 100644 --- a/src/pocketmine/item/Compass.php +++ b/src/pocketmine/item/Compass.php @@ -24,7 +24,5 @@ declare(strict_types=1); namespace pocketmine\item; class Compass extends Item{ - public function __construct(){ - parent::__construct(self::COMPASS, 0, "Compass"); - } + } diff --git a/src/pocketmine/item/CookedChicken.php b/src/pocketmine/item/CookedChicken.php index d72fd01923..083f20b3ca 100644 --- a/src/pocketmine/item/CookedChicken.php +++ b/src/pocketmine/item/CookedChicken.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class CookedChicken extends Food{ - public function __construct(){ - parent::__construct(self::COOKED_CHICKEN, 0, "Cooked Chicken"); - } public function getFoodRestore() : int{ return 6; diff --git a/src/pocketmine/item/CookedFish.php b/src/pocketmine/item/CookedFish.php index bd28be171e..8722476394 100644 --- a/src/pocketmine/item/CookedFish.php +++ b/src/pocketmine/item/CookedFish.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class CookedFish extends Food{ - public function __construct(){ - parent::__construct(self::COOKED_FISH, 0, "Cooked Fish"); - } public function getFoodRestore() : int{ return 5; diff --git a/src/pocketmine/item/CookedMutton.php b/src/pocketmine/item/CookedMutton.php index 152cb75c6b..6e19853cce 100644 --- a/src/pocketmine/item/CookedMutton.php +++ b/src/pocketmine/item/CookedMutton.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class CookedMutton extends Food{ - public function __construct(){ - parent::__construct(self::COOKED_MUTTON, 0, "Cooked Mutton"); - } public function getFoodRestore() : int{ return 6; diff --git a/src/pocketmine/item/CookedPorkchop.php b/src/pocketmine/item/CookedPorkchop.php index 649551c8df..d75528001a 100644 --- a/src/pocketmine/item/CookedPorkchop.php +++ b/src/pocketmine/item/CookedPorkchop.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class CookedPorkchop extends Food{ - public function __construct(){ - parent::__construct(self::COOKED_PORKCHOP, 0, "Cooked Porkchop"); - } public function getFoodRestore() : int{ return 8; diff --git a/src/pocketmine/item/CookedRabbit.php b/src/pocketmine/item/CookedRabbit.php index 03e5077fb7..40d3830b45 100644 --- a/src/pocketmine/item/CookedRabbit.php +++ b/src/pocketmine/item/CookedRabbit.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class CookedRabbit extends Food{ - public function __construct(){ - parent::__construct(self::COOKED_RABBIT, 0, "Cooked Rabbit"); - } public function getFoodRestore() : int{ return 5; diff --git a/src/pocketmine/item/CookedSalmon.php b/src/pocketmine/item/CookedSalmon.php index f1e7013988..7413c382e3 100644 --- a/src/pocketmine/item/CookedSalmon.php +++ b/src/pocketmine/item/CookedSalmon.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class CookedSalmon extends Food{ - public function __construct(){ - parent::__construct(self::COOKED_SALMON, 0, "Cooked Salmon"); - } public function getFoodRestore() : int{ return 6; diff --git a/src/pocketmine/item/Cookie.php b/src/pocketmine/item/Cookie.php index 6dc546870b..a8082f3f0f 100644 --- a/src/pocketmine/item/Cookie.php +++ b/src/pocketmine/item/Cookie.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class Cookie extends Food{ - public function __construct(){ - parent::__construct(self::COOKIE, 0, "Cookie"); - } public function getFoodRestore() : int{ return 2; diff --git a/src/pocketmine/item/DriedKelp.php b/src/pocketmine/item/DriedKelp.php index 24b914db5d..935d99679e 100644 --- a/src/pocketmine/item/DriedKelp.php +++ b/src/pocketmine/item/DriedKelp.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class DriedKelp extends Food{ - public function __construct(){ - parent::__construct(self::DRIED_KELP, 0, "Dried Kelp"); - } public function getFoodRestore() : int{ return 1; diff --git a/src/pocketmine/item/Dye.php b/src/pocketmine/item/Dye.php index 94452d67b7..ba103b5193 100644 --- a/src/pocketmine/item/Dye.php +++ b/src/pocketmine/item/Dye.php @@ -30,8 +30,8 @@ class Dye extends Item{ /** @var DyeColor */ private $color; - public function __construct(int $variant, string $name, DyeColor $color){ - parent::__construct(self::DYE, $variant, $name); + public function __construct(int $id, int $variant, string $name, DyeColor $color){ + parent::__construct($id, $variant, $name); $this->color = $color; } diff --git a/src/pocketmine/item/Egg.php b/src/pocketmine/item/Egg.php index bf6d15482c..7d3bece760 100644 --- a/src/pocketmine/item/Egg.php +++ b/src/pocketmine/item/Egg.php @@ -26,9 +26,6 @@ namespace pocketmine\item; use pocketmine\entity\projectile\Egg as EggEntity; class Egg extends ProjectileItem{ - public function __construct(){ - parent::__construct(self::EGG, 0, "Egg"); - } public function getMaxStackSize() : int{ return 16; diff --git a/src/pocketmine/item/EnderPearl.php b/src/pocketmine/item/EnderPearl.php index 8417c58064..337b30a7f9 100644 --- a/src/pocketmine/item/EnderPearl.php +++ b/src/pocketmine/item/EnderPearl.php @@ -26,9 +26,6 @@ namespace pocketmine\item; use pocketmine\entity\projectile\EnderPearl as EnderPearlEntity; class EnderPearl extends ProjectileItem{ - public function __construct(){ - parent::__construct(self::ENDER_PEARL, 0, "Ender Pearl"); - } public function getMaxStackSize() : int{ return 16; diff --git a/src/pocketmine/item/ExperienceBottle.php b/src/pocketmine/item/ExperienceBottle.php index 21d07cb42b..191d932b87 100644 --- a/src/pocketmine/item/ExperienceBottle.php +++ b/src/pocketmine/item/ExperienceBottle.php @@ -26,9 +26,6 @@ namespace pocketmine\item; use pocketmine\entity\projectile\ExperienceBottle as ExperienceBottleEntity; class ExperienceBottle extends ProjectileItem{ - public function __construct(){ - parent::__construct(self::EXPERIENCE_BOTTLE, 0, "Bottle o' Enchanting"); - } public function getProjectileEntityClass() : string{ return ExperienceBottleEntity::class; diff --git a/src/pocketmine/item/FishingRod.php b/src/pocketmine/item/FishingRod.php index 8909de54ed..1e9c71e210 100644 --- a/src/pocketmine/item/FishingRod.php +++ b/src/pocketmine/item/FishingRod.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class FishingRod extends Item{ - public function __construct(){ - parent::__construct(self::FISHING_ROD, 0, "Fishing Rod"); - } //TODO } diff --git a/src/pocketmine/item/FlintSteel.php b/src/pocketmine/item/FlintSteel.php index e69df4d412..3478ce5a59 100644 --- a/src/pocketmine/item/FlintSteel.php +++ b/src/pocketmine/item/FlintSteel.php @@ -32,9 +32,6 @@ use pocketmine\world\sound\FlintSteelSound; use function assert; class FlintSteel extends Tool{ - public function __construct(){ - parent::__construct(self::FLINT_STEEL, 0, "Flint and Steel"); - } public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ if($blockReplace->getId() === BlockLegacyIds::AIR){ diff --git a/src/pocketmine/item/GlassBottle.php b/src/pocketmine/item/GlassBottle.php index 8957531426..d3ce86a581 100644 --- a/src/pocketmine/item/GlassBottle.php +++ b/src/pocketmine/item/GlassBottle.php @@ -24,7 +24,5 @@ declare(strict_types=1); namespace pocketmine\item; class GlassBottle extends Item{ - public function __construct(){ - parent::__construct(self::GLASS_BOTTLE, 0, "Glass Bottle"); - } + } diff --git a/src/pocketmine/item/GoldenApple.php b/src/pocketmine/item/GoldenApple.php index 3e4482b218..ba02205286 100644 --- a/src/pocketmine/item/GoldenApple.php +++ b/src/pocketmine/item/GoldenApple.php @@ -28,10 +28,6 @@ use pocketmine\entity\effect\EffectInstance; class GoldenApple extends Food{ - public function __construct(){ - parent::__construct(self::GOLDEN_APPLE, 0, "Golden Apple"); - } - public function requiresHunger() : bool{ return false; } diff --git a/src/pocketmine/item/GoldenAppleEnchanted.php b/src/pocketmine/item/GoldenAppleEnchanted.php index 13fe4ee4c1..1064373c27 100644 --- a/src/pocketmine/item/GoldenAppleEnchanted.php +++ b/src/pocketmine/item/GoldenAppleEnchanted.php @@ -28,10 +28,6 @@ use pocketmine\entity\effect\EffectInstance; class GoldenAppleEnchanted extends GoldenApple{ - public function __construct(){ - Food::__construct(self::ENCHANTED_GOLDEN_APPLE, 0, "Enchanted Golden Apple"); //skip parent constructor - } - public function getAdditionalEffects() : array{ return [ new EffectInstance(Effect::REGENERATION(), 600, 4), diff --git a/src/pocketmine/item/GoldenCarrot.php b/src/pocketmine/item/GoldenCarrot.php index 06d327bca4..9c2acdc891 100644 --- a/src/pocketmine/item/GoldenCarrot.php +++ b/src/pocketmine/item/GoldenCarrot.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class GoldenCarrot extends Food{ - public function __construct(){ - parent::__construct(self::GOLDEN_CARROT, 0, "Golden Carrot"); - } public function getFoodRestore() : int{ return 6; diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 119682ffe4..31e4725b83 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -54,59 +54,59 @@ class ItemFactory{ public static function init() : void{ self::$list = []; //in case of re-initializing - self::register(new Apple()); - self::register(new Arrow()); + self::register(new Apple(Item::APPLE, 0, "Apple")); + self::register(new Arrow(Item::ARROW, 0, "Arrow")); self::register(new Axe(Item::DIAMOND_AXE, "Diamond Axe", TieredTool::TIER_DIAMOND)); self::register(new Axe(Item::GOLDEN_AXE, "Gold Axe", TieredTool::TIER_GOLD)); self::register(new Axe(Item::IRON_AXE, "Iron Axe", TieredTool::TIER_IRON)); self::register(new Axe(Item::STONE_AXE, "Stone Axe", TieredTool::TIER_STONE)); self::register(new Axe(Item::WOODEN_AXE, "Wooden Axe", TieredTool::TIER_WOODEN)); - self::register(new BakedPotato()); - self::register(new Beetroot()); - self::register(new BeetrootSeeds()); - self::register(new BeetrootSoup()); - self::register(new BlazeRod()); - self::register(new Book()); + self::register(new BakedPotato(Item::BAKED_POTATO, 0, "Baked Potato")); + self::register(new Beetroot(Item::BEETROOT, 0, "Beetroot")); + self::register(new BeetrootSeeds(Item::BEETROOT_SEEDS, 0, "Beetroot Seeds")); + self::register(new BeetrootSoup(Item::BEETROOT_SOUP, 0, "Beetroot Soup")); + self::register(new BlazeRod(Item::BLAZE_ROD, 0, "Blaze Rod")); + self::register(new Book(Item::BOOK, 0, "Book")); self::register(new Boots(Item::CHAIN_BOOTS, 0, "Chainmail Boots", new ArmorTypeInfo(1, 196))); self::register(new Boots(Item::DIAMOND_BOOTS, 0, "Diamond Boots", new ArmorTypeInfo(3, 430))); self::register(new Boots(Item::GOLDEN_BOOTS, 0, "Gold Boots", new ArmorTypeInfo(1, 92))); self::register(new Boots(Item::IRON_BOOTS, 0, "Iron Boots", new ArmorTypeInfo(2, 196))); self::register(new Boots(Item::LEATHER_BOOTS, 0, "Leather Boots", new ArmorTypeInfo(1, 66))); - self::register(new Bow()); - self::register(new Bowl()); - self::register(new Bread()); + self::register(new Bow(Item::BOW, 0, "Bow")); + self::register(new Bowl(Item::BOWL, 0, "Bowl")); + self::register(new Bread(Item::BREAD, 0, "Bread")); self::register(new Bucket(Item::BUCKET, 0, "Bucket")); - self::register(new Carrot()); + self::register(new Carrot(Item::CARROT, 0, "Carrot")); self::register(new Chestplate(Item::CHAIN_CHESTPLATE, 0, "Chainmail Chestplate", new ArmorTypeInfo(5, 241))); self::register(new Chestplate(Item::DIAMOND_CHESTPLATE, 0, "Diamond Chestplate", new ArmorTypeInfo(8, 529))); self::register(new Chestplate(Item::GOLDEN_CHESTPLATE, 0, "Gold Chestplate", new ArmorTypeInfo(5, 113))); self::register(new Chestplate(Item::IRON_CHESTPLATE, 0, "Iron Chestplate", new ArmorTypeInfo(6, 241))); self::register(new Chestplate(Item::LEATHER_CHESTPLATE, 0, "Leather Tunic", new ArmorTypeInfo(3, 81))); - self::register(new ChorusFruit()); - self::register(new Clock()); - self::register(new Clownfish()); + self::register(new ChorusFruit(Item::CHORUS_FRUIT, 0, "Chorus Fruit")); + self::register(new Clock(Item::CLOCK, 0, "Clock")); + self::register(new Clownfish(Item::CLOWNFISH, 0, "Clownfish")); self::register(new Coal(Item::COAL, 0, "Coal")); self::register(new Coal(Item::COAL, 1, "Charcoal")); self::register(new CocoaBeans(Item::DYE, 3, "Cocoa Beans")); - self::register(new Compass()); - self::register(new CookedChicken()); - self::register(new CookedFish()); - self::register(new CookedMutton()); - self::register(new CookedPorkchop()); - self::register(new CookedRabbit()); - self::register(new CookedSalmon()); - self::register(new Cookie()); - self::register(new DriedKelp()); - self::register(new Egg()); - self::register(new EnderPearl()); - self::register(new ExperienceBottle()); + self::register(new Compass(Item::COMPASS, 0, "Compass")); + self::register(new CookedChicken(Item::COOKED_CHICKEN, 0, "Cooked Chicken")); + self::register(new CookedFish(Item::COOKED_FISH, 0, "Cooked Fish")); + self::register(new CookedMutton(Item::COOKED_MUTTON, 0, "Cooked Mutton")); + self::register(new CookedPorkchop(Item::COOKED_PORKCHOP, 0, "Cooked Porkchop")); + self::register(new CookedRabbit(Item::COOKED_RABBIT, 0, "Cooked Rabbit")); + self::register(new CookedSalmon(Item::COOKED_SALMON, 0, "Cooked Salmon")); + self::register(new Cookie(Item::COOKIE, 0, "Cookie")); + self::register(new DriedKelp(Item::DRIED_KELP, 0, "Dried Kelp")); + self::register(new Egg(Item::EGG, 0, "Egg")); + self::register(new EnderPearl(Item::ENDER_PEARL, 0, "Ender Pearl")); + self::register(new ExperienceBottle(Item::EXPERIENCE_BOTTLE, 0, "Bottle o' Enchanting")); self::register(new Fertilizer(Item::DYE, 15, "Bone Meal")); - self::register(new FishingRod()); - self::register(new FlintSteel()); - self::register(new GlassBottle()); - self::register(new GoldenApple()); - self::register(new GoldenAppleEnchanted()); - self::register(new GoldenCarrot()); + self::register(new FishingRod(Item::FISHING_ROD, 0, "Fishing Rod")); + self::register(new FlintSteel(Item::FLINT_STEEL, 0, "Flint and Steel")); + self::register(new GlassBottle(Item::GLASS_BOTTLE, 0, "Glass Bottle")); + self::register(new GoldenApple(Item::GOLDEN_APPLE, 0, "Golden Apple")); + self::register(new GoldenAppleEnchanted(Item::ENCHANTED_GOLDEN_APPLE, 0, "Enchanted Golden Apple")); + self::register(new GoldenCarrot(Item::GOLDEN_CARROT, 0, "Golden Carrot")); self::register(new Helmet(Item::CHAIN_HELMET, 0, "Chainmail Helmet", new ArmorTypeInfo(2, 166))); self::register(new Helmet(Item::DIAMOND_HELMET, 0, "Diamond Helmet", new ArmorTypeInfo(3, 364))); self::register(new Helmet(Item::GOLDEN_HELMET, 0, "Gold Helmet", new ArmorTypeInfo(2, 78))); @@ -220,33 +220,33 @@ class ItemFactory{ //the meta values are intentionally hardcoded because block IDs will change in the future self::register(new LiquidBucket(Item::BUCKET, 8, "Water Bucket", BlockLegacyIds::FLOWING_WATER)); self::register(new LiquidBucket(Item::BUCKET, 10, "Lava Bucket", BlockLegacyIds::FLOWING_LAVA)); - self::register(new Melon()); - self::register(new MelonSeeds()); + self::register(new Melon(Item::MELON, 0, "Melon")); + self::register(new MelonSeeds(Item::MELON_SEEDS, 0, "Melon Seeds")); self::register(new MilkBucket(Item::BUCKET, 1, "Milk Bucket")); - self::register(new Minecart()); - self::register(new MushroomStew()); - self::register(new PaintingItem()); + self::register(new Minecart(Item::MINECART, 0, "Minecart")); + self::register(new MushroomStew(Item::MUSHROOM_STEW, 0, "Mushroom Stew")); + self::register(new PaintingItem(Item::PAINTING, 0, "Painting")); self::register(new Pickaxe(Item::DIAMOND_PICKAXE, "Diamond Pickaxe", TieredTool::TIER_DIAMOND)); self::register(new Pickaxe(Item::GOLDEN_PICKAXE, "Gold Pickaxe", TieredTool::TIER_GOLD)); self::register(new Pickaxe(Item::IRON_PICKAXE, "Iron Pickaxe", TieredTool::TIER_IRON)); self::register(new Pickaxe(Item::STONE_PICKAXE, "Stone Pickaxe", TieredTool::TIER_STONE)); self::register(new Pickaxe(Item::WOODEN_PICKAXE, "Wooden Pickaxe", TieredTool::TIER_WOODEN)); - self::register(new PoisonousPotato()); - self::register(new Potato()); - self::register(new Pufferfish()); - self::register(new PumpkinPie()); - self::register(new PumpkinSeeds()); - self::register(new RabbitStew()); - self::register(new RawBeef()); - self::register(new RawChicken()); - self::register(new RawFish()); - self::register(new RawMutton()); - self::register(new RawPorkchop()); - self::register(new RawRabbit()); - self::register(new RawSalmon()); - self::register(new Redstone()); - self::register(new RottenFlesh()); - self::register(new Shears()); + self::register(new PoisonousPotato(Item::POISONOUS_POTATO, 0, "Poisonous Potato")); + self::register(new Potato(Item::POTATO, 0, "Potato")); + self::register(new Pufferfish(Item::PUFFERFISH, 0, "Pufferfish")); + self::register(new PumpkinPie(Item::PUMPKIN_PIE, 0, "Pumpkin Pie")); + self::register(new PumpkinSeeds(Item::PUMPKIN_SEEDS, 0, "Pumpkin Seeds")); + self::register(new RabbitStew(Item::RABBIT_STEW, 0, "Rabbit Stew")); + self::register(new RawBeef(Item::RAW_BEEF, 0, "Raw Beef")); + self::register(new RawChicken(Item::RAW_CHICKEN, 0, "Raw Chicken")); + self::register(new RawFish(Item::RAW_FISH, 0, "Raw Fish")); + self::register(new RawMutton(Item::RAW_MUTTON, 0, "Raw Mutton")); + self::register(new RawPorkchop(Item::RAW_PORKCHOP, 0, "Raw Porkchop")); + self::register(new RawRabbit(Item::RAW_RABBIT, 0, "Raw Rabbit")); + self::register(new RawSalmon(Item::RAW_SALMON, 0, "Raw Salmon")); + self::register(new Redstone(Item::REDSTONE, 0, "Redstone")); + self::register(new RottenFlesh(Item::ROTTEN_FLESH, 0, "Rotten Flesh")); + self::register(new Shears(Item::SHEARS, 0, "Shears")); self::register(new Shovel(Item::DIAMOND_SHOVEL, "Diamond Shovel", TieredTool::TIER_DIAMOND)); self::register(new Shovel(Item::GOLDEN_SHOVEL, "Gold Shovel", TieredTool::TIER_GOLD)); self::register(new Shovel(Item::IRON_SHOVEL, "Iron Shovel", TieredTool::TIER_IRON)); @@ -258,20 +258,20 @@ class ItemFactory{ self::register(new Sign(BlockLegacyIds::JUNGLE_STANDING_SIGN, 0, Item::JUNGLE_SIGN)); self::register(new Sign(BlockLegacyIds::ACACIA_STANDING_SIGN, 0, Item::ACACIA_SIGN)); self::register(new Sign(BlockLegacyIds::DARKOAK_STANDING_SIGN, 0, Item::DARKOAK_SIGN)); - self::register(new Snowball()); - self::register(new SpiderEye()); - self::register(new Steak()); - self::register(new Stick()); - self::register(new StringItem()); + self::register(new Snowball(Item::SNOWBALL, 0, "Snowball")); + self::register(new SpiderEye(Item::SPIDER_EYE, 0, "Spider Eye")); + self::register(new Steak(Item::STEAK, 0, "Steak")); + self::register(new Stick(Item::STICK, 0, "Stick")); + self::register(new StringItem(Item::STRING, 0, "String")); self::register(new Sword(Item::DIAMOND_SWORD, "Diamond Sword", TieredTool::TIER_DIAMOND)); self::register(new Sword(Item::GOLDEN_SWORD, "Gold Sword", TieredTool::TIER_GOLD)); self::register(new Sword(Item::IRON_SWORD, "Iron Sword", TieredTool::TIER_IRON)); self::register(new Sword(Item::STONE_SWORD, "Stone Sword", TieredTool::TIER_STONE)); self::register(new Sword(Item::WOODEN_SWORD, "Wooden Sword", TieredTool::TIER_WOODEN)); - self::register(new Totem()); - self::register(new WheatSeeds()); - self::register(new WritableBook()); - self::register(new WrittenBook()); + self::register(new Totem(Item::TOTEM, 0, "Totem of Undying")); + self::register(new WheatSeeds(Item::WHEAT_SEEDS, 0, "Wheat Seeds")); + self::register(new WritableBook(Item::WRITABLE_BOOK, 0, "Book & Quill")); + self::register(new WrittenBook(Item::WRITTEN_BOOK, 0, "Written Book")); foreach(SkullType::getAll() as $skullType){ self::register(new Skull(Item::SKULL, $skullType->getMagicNumber(), $skullType->getDisplayName(), $skullType)); @@ -286,25 +286,25 @@ class ItemFactory{ foreach(DyeColor::getAll() as $color){ //TODO: use colour object directly //TODO: add interface to dye-colour objects - self::register(new Dye($dyeMap[$color] ?? $color->getInvertedMagicNumber(), $color->getDisplayName() . " Dye", $color)); - self::register(new Bed($color->getMagicNumber(), $color->getDisplayName() . " Bed", $color)); - self::register(new Banner($color->getInvertedMagicNumber(), $color->getDisplayName() . " Banner", $color)); + self::register(new Dye(Item::DYE, $dyeMap[$color] ?? $color->getInvertedMagicNumber(), $color->getDisplayName() . " Dye", $color)); + self::register(new Bed(Item::BED, $color->getMagicNumber(), $color->getDisplayName() . " Bed", $color)); + self::register(new Banner(Item::BANNER, $color->getInvertedMagicNumber(), $color->getDisplayName() . " Banner", $color)); } foreach(Potion::ALL as $type){ - self::register(new Potion($type)); - self::register(new SplashPotion($type)); + self::register(new Potion(Item::POTION, $type, "Potion")); + self::register(new SplashPotion(Item::SPLASH_POTION, $type, "Splash Potion")); } foreach(EntityFactory::getKnownTypes() as $className){ /** @var Living|string $className */ if(is_a($className, Living::class, true) and $className::NETWORK_ID !== -1){ - self::register(new SpawnEgg(Item::SPAWN_EGG, $className::NETWORK_ID, $className, "Spawn Egg")); + self::register(new SpawnEgg(Item::SPAWN_EGG, $className::NETWORK_ID, "Spawn Egg", $className)); } } foreach(TreeType::getAll() as $type){ - self::register(new Boat($type)); + self::register(new Boat(Item::BOAT, $type->getMagicNumber(), $type->getDisplayName() . " Boat", $type)); } //TODO: minecraft:acacia_sign diff --git a/src/pocketmine/item/Melon.php b/src/pocketmine/item/Melon.php index 0a4c5cedc9..f1807296e7 100644 --- a/src/pocketmine/item/Melon.php +++ b/src/pocketmine/item/Melon.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class Melon extends Food{ - public function __construct(){ - parent::__construct(self::MELON, 0, "Melon"); - } public function getFoodRestore() : int{ return 2; diff --git a/src/pocketmine/item/MelonSeeds.php b/src/pocketmine/item/MelonSeeds.php index f7715ed6e0..f2d7820588 100644 --- a/src/pocketmine/item/MelonSeeds.php +++ b/src/pocketmine/item/MelonSeeds.php @@ -28,9 +28,6 @@ use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; class MelonSeeds extends Item{ - public function __construct(){ - parent::__construct(self::MELON_SEEDS, 0, "Melon Seeds"); - } public function getBlock() : Block{ return BlockFactory::get(BlockLegacyIds::MELON_STEM); diff --git a/src/pocketmine/item/Minecart.php b/src/pocketmine/item/Minecart.php index ec9bbcbe99..59e47b98a3 100644 --- a/src/pocketmine/item/Minecart.php +++ b/src/pocketmine/item/Minecart.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class Minecart extends Item{ - public function __construct(){ - parent::__construct(self::MINECART, 0, "Minecart"); - } //TODO } diff --git a/src/pocketmine/item/MushroomStew.php b/src/pocketmine/item/MushroomStew.php index abba737a54..b71dcc1b8a 100644 --- a/src/pocketmine/item/MushroomStew.php +++ b/src/pocketmine/item/MushroomStew.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class MushroomStew extends Food{ - public function __construct(){ - parent::__construct(self::MUSHROOM_STEW, 0, "Mushroom Stew"); - } public function getMaxStackSize() : int{ return 1; diff --git a/src/pocketmine/item/PaintingItem.php b/src/pocketmine/item/PaintingItem.php index 8d9642c49c..7018b181e5 100644 --- a/src/pocketmine/item/PaintingItem.php +++ b/src/pocketmine/item/PaintingItem.php @@ -34,9 +34,6 @@ use pocketmine\Player; use function array_rand; class PaintingItem extends Item{ - public function __construct(){ - parent::__construct(self::PAINTING, 0, "Painting"); - } public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ if(Facing::axis($face) === Facing::AXIS_Y){ diff --git a/src/pocketmine/item/PoisonousPotato.php b/src/pocketmine/item/PoisonousPotato.php index f869884f70..962e87a2c2 100644 --- a/src/pocketmine/item/PoisonousPotato.php +++ b/src/pocketmine/item/PoisonousPotato.php @@ -28,9 +28,6 @@ use pocketmine\entity\effect\EffectInstance; use function mt_rand; class PoisonousPotato extends Food{ - public function __construct(){ - parent::__construct(self::POISONOUS_POTATO, 0, "Poisonous Potato"); - } public function getFoodRestore() : int{ return 2; diff --git a/src/pocketmine/item/Potato.php b/src/pocketmine/item/Potato.php index b550a4f248..c9fbd32eba 100644 --- a/src/pocketmine/item/Potato.php +++ b/src/pocketmine/item/Potato.php @@ -28,9 +28,6 @@ use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; class Potato extends Food{ - public function __construct(){ - parent::__construct(self::POTATO, 0, "Potato"); - } public function getBlock() : Block{ return BlockFactory::get(BlockLegacyIds::POTATO_BLOCK); diff --git a/src/pocketmine/item/Potion.php b/src/pocketmine/item/Potion.php index 6e7acb06d3..9cb0ecd0cd 100644 --- a/src/pocketmine/item/Potion.php +++ b/src/pocketmine/item/Potion.php @@ -255,10 +255,6 @@ class Potion extends Item implements Consumable{ return []; } - public function __construct(int $variant){ - parent::__construct(self::POTION, $variant, "Potion"); - } - public function getMaxStackSize() : int{ return 1; } diff --git a/src/pocketmine/item/Pufferfish.php b/src/pocketmine/item/Pufferfish.php index 3d14512564..6e9826fb41 100644 --- a/src/pocketmine/item/Pufferfish.php +++ b/src/pocketmine/item/Pufferfish.php @@ -27,9 +27,6 @@ use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; class Pufferfish extends Food{ - public function __construct(){ - parent::__construct(self::PUFFERFISH, 0, "Pufferfish"); - } public function getFoodRestore() : int{ return 1; diff --git a/src/pocketmine/item/PumpkinPie.php b/src/pocketmine/item/PumpkinPie.php index 90628dd68a..ba4567358e 100644 --- a/src/pocketmine/item/PumpkinPie.php +++ b/src/pocketmine/item/PumpkinPie.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class PumpkinPie extends Food{ - public function __construct(){ - parent::__construct(self::PUMPKIN_PIE, 0, "Pumpkin Pie"); - } public function getFoodRestore() : int{ return 8; diff --git a/src/pocketmine/item/PumpkinSeeds.php b/src/pocketmine/item/PumpkinSeeds.php index 28ec69cbf2..048538090f 100644 --- a/src/pocketmine/item/PumpkinSeeds.php +++ b/src/pocketmine/item/PumpkinSeeds.php @@ -28,9 +28,6 @@ use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; class PumpkinSeeds extends Item{ - public function __construct(){ - parent::__construct(self::PUMPKIN_SEEDS, 0, "Pumpkin Seeds"); - } public function getBlock() : Block{ return BlockFactory::get(BlockLegacyIds::PUMPKIN_STEM); diff --git a/src/pocketmine/item/RabbitStew.php b/src/pocketmine/item/RabbitStew.php index 9161d888a6..239973d8a1 100644 --- a/src/pocketmine/item/RabbitStew.php +++ b/src/pocketmine/item/RabbitStew.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class RabbitStew extends Food{ - public function __construct(){ - parent::__construct(self::RABBIT_STEW, 0, "Rabbit Stew"); - } public function getMaxStackSize() : int{ return 1; diff --git a/src/pocketmine/item/RawBeef.php b/src/pocketmine/item/RawBeef.php index 59aa7e9c32..64f09701f9 100644 --- a/src/pocketmine/item/RawBeef.php +++ b/src/pocketmine/item/RawBeef.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class RawBeef extends Food{ - public function __construct(){ - parent::__construct(self::RAW_BEEF, 0, "Raw Beef"); - } public function getFoodRestore() : int{ return 3; diff --git a/src/pocketmine/item/RawChicken.php b/src/pocketmine/item/RawChicken.php index ef9fd3949a..0408a65524 100644 --- a/src/pocketmine/item/RawChicken.php +++ b/src/pocketmine/item/RawChicken.php @@ -28,9 +28,6 @@ use pocketmine\entity\effect\EffectInstance; use function mt_rand; class RawChicken extends Food{ - public function __construct(){ - parent::__construct(self::RAW_CHICKEN, 0, "Raw Chicken"); - } public function getFoodRestore() : int{ return 2; diff --git a/src/pocketmine/item/RawFish.php b/src/pocketmine/item/RawFish.php index 54da485c19..cbd0aef135 100644 --- a/src/pocketmine/item/RawFish.php +++ b/src/pocketmine/item/RawFish.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class RawFish extends Food{ - public function __construct(){ - parent::__construct(self::RAW_FISH, 0, "Raw Fish"); - } public function getFoodRestore() : int{ return 2; diff --git a/src/pocketmine/item/RawMutton.php b/src/pocketmine/item/RawMutton.php index 125f901a53..1fd389fbc3 100644 --- a/src/pocketmine/item/RawMutton.php +++ b/src/pocketmine/item/RawMutton.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class RawMutton extends Food{ - public function __construct(){ - parent::__construct(self::RAW_MUTTON, 0, "Raw Mutton"); - } public function getFoodRestore() : int{ return 2; diff --git a/src/pocketmine/item/RawPorkchop.php b/src/pocketmine/item/RawPorkchop.php index fa28f59298..ce2e12623f 100644 --- a/src/pocketmine/item/RawPorkchop.php +++ b/src/pocketmine/item/RawPorkchop.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class RawPorkchop extends Food{ - public function __construct(){ - parent::__construct(self::RAW_PORKCHOP, 0, "Raw Porkchop"); - } public function getFoodRestore() : int{ return 3; diff --git a/src/pocketmine/item/RawRabbit.php b/src/pocketmine/item/RawRabbit.php index 2234c60a2c..bd1111fe8e 100644 --- a/src/pocketmine/item/RawRabbit.php +++ b/src/pocketmine/item/RawRabbit.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class RawRabbit extends Food{ - public function __construct(){ - parent::__construct(self::RAW_RABBIT, 0, "Raw Rabbit"); - } public function getFoodRestore() : int{ return 3; diff --git a/src/pocketmine/item/RawSalmon.php b/src/pocketmine/item/RawSalmon.php index d8b2375f92..5e0de0e81a 100644 --- a/src/pocketmine/item/RawSalmon.php +++ b/src/pocketmine/item/RawSalmon.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class RawSalmon extends Food{ - public function __construct(){ - parent::__construct(self::RAW_SALMON, 0, "Raw Salmon"); - } public function getFoodRestore() : int{ return 2; diff --git a/src/pocketmine/item/Redstone.php b/src/pocketmine/item/Redstone.php index 2a08dda693..6e4e054b5d 100644 --- a/src/pocketmine/item/Redstone.php +++ b/src/pocketmine/item/Redstone.php @@ -28,9 +28,6 @@ use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; class Redstone extends Item{ - public function __construct(){ - parent::__construct(self::REDSTONE, 0, "Redstone"); - } public function getBlock() : Block{ return BlockFactory::get(BlockLegacyIds::REDSTONE_WIRE); diff --git a/src/pocketmine/item/RottenFlesh.php b/src/pocketmine/item/RottenFlesh.php index 3b4677478f..90f4c9050e 100644 --- a/src/pocketmine/item/RottenFlesh.php +++ b/src/pocketmine/item/RottenFlesh.php @@ -29,10 +29,6 @@ use function lcg_value; class RottenFlesh extends Food{ - public function __construct(){ - parent::__construct(self::ROTTEN_FLESH, 0, "Rotten Flesh"); - } - public function getFoodRestore() : int{ return 4; } diff --git a/src/pocketmine/item/Shears.php b/src/pocketmine/item/Shears.php index 811bb380f1..bc99b02b6c 100644 --- a/src/pocketmine/item/Shears.php +++ b/src/pocketmine/item/Shears.php @@ -27,9 +27,6 @@ use pocketmine\block\Block; use pocketmine\block\BlockToolType; class Shears extends Tool{ - public function __construct(){ - parent::__construct(self::SHEARS, 0, "Shears"); - } public function getMaxDurability() : int{ return 239; diff --git a/src/pocketmine/item/Snowball.php b/src/pocketmine/item/Snowball.php index 6f46dfcb4d..8da341c06e 100644 --- a/src/pocketmine/item/Snowball.php +++ b/src/pocketmine/item/Snowball.php @@ -26,9 +26,6 @@ namespace pocketmine\item; use pocketmine\entity\projectile\Snowball as SnowballEntity; class Snowball extends ProjectileItem{ - public function __construct(){ - parent::__construct(self::SNOWBALL, 0, "Snowball"); - } public function getMaxStackSize() : int{ return 16; diff --git a/src/pocketmine/item/SpawnEgg.php b/src/pocketmine/item/SpawnEgg.php index de42271d83..f1a52ef891 100644 --- a/src/pocketmine/item/SpawnEgg.php +++ b/src/pocketmine/item/SpawnEgg.php @@ -39,12 +39,13 @@ class SpawnEgg extends Item{ /** * @param int $id * @param int $variant - * @param string $entityClass instanceof Entity * @param string $name * + * @param string $entityClass instanceof Entity + * * @throws \InvalidArgumentException */ - public function __construct(int $id, int $variant, string $entityClass, string $name = "Unknown"){ + public function __construct(int $id, int $variant, string $name, string $entityClass){ parent::__construct($id, $variant, $name); Utils::testValidInstance($entityClass, Entity::class); $this->entityClass = $entityClass; diff --git a/src/pocketmine/item/SpiderEye.php b/src/pocketmine/item/SpiderEye.php index cc8c4c4aa4..b443a4fad6 100644 --- a/src/pocketmine/item/SpiderEye.php +++ b/src/pocketmine/item/SpiderEye.php @@ -27,9 +27,6 @@ use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; class SpiderEye extends Food{ - public function __construct(){ - parent::__construct(self::SPIDER_EYE, 0, "Spider Eye"); - } public function getFoodRestore() : int{ return 2; diff --git a/src/pocketmine/item/SplashPotion.php b/src/pocketmine/item/SplashPotion.php index 3f12c7b840..d29f5839b7 100644 --- a/src/pocketmine/item/SplashPotion.php +++ b/src/pocketmine/item/SplashPotion.php @@ -28,10 +28,6 @@ use pocketmine\nbt\tag\CompoundTag; class SplashPotion extends ProjectileItem{ - public function __construct(int $variant){ - parent::__construct(self::SPLASH_POTION, $variant, "Splash Potion"); - } - public function getMaxStackSize() : int{ return 1; } diff --git a/src/pocketmine/item/Steak.php b/src/pocketmine/item/Steak.php index 1e5ed99f05..baeee5e153 100644 --- a/src/pocketmine/item/Steak.php +++ b/src/pocketmine/item/Steak.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class Steak extends Food{ - public function __construct(){ - parent::__construct(self::STEAK, 0, "Steak"); - } public function getFoodRestore() : int{ return 8; diff --git a/src/pocketmine/item/Stick.php b/src/pocketmine/item/Stick.php index 4bbb63bf26..d7b749e05e 100644 --- a/src/pocketmine/item/Stick.php +++ b/src/pocketmine/item/Stick.php @@ -25,9 +25,6 @@ namespace pocketmine\item; class Stick extends Item{ - public function __construct(){ - parent::__construct(self::STICK, 0, "Stick"); - } public function getFuelTime() : int{ return 100; diff --git a/src/pocketmine/item/StringItem.php b/src/pocketmine/item/StringItem.php index 4253ba9809..9497e34ab4 100644 --- a/src/pocketmine/item/StringItem.php +++ b/src/pocketmine/item/StringItem.php @@ -28,9 +28,6 @@ use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; class StringItem extends Item{ - public function __construct(){ - parent::__construct(self::STRING, 0, "String"); - } public function getBlock() : Block{ return BlockFactory::get(BlockLegacyIds::TRIPWIRE); diff --git a/src/pocketmine/item/Totem.php b/src/pocketmine/item/Totem.php index e322de7f1f..8928dd139e 100644 --- a/src/pocketmine/item/Totem.php +++ b/src/pocketmine/item/Totem.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; class Totem extends Item{ - public function __construct(){ - parent::__construct(self::TOTEM, 0, "Totem of Undying"); - } public function getMaxStackSize() : int{ return 1; diff --git a/src/pocketmine/item/WheatSeeds.php b/src/pocketmine/item/WheatSeeds.php index 9679424927..d844aeea77 100644 --- a/src/pocketmine/item/WheatSeeds.php +++ b/src/pocketmine/item/WheatSeeds.php @@ -28,9 +28,6 @@ use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; class WheatSeeds extends Item{ - public function __construct(){ - parent::__construct(self::WHEAT_SEEDS, 0, "Wheat Seeds"); - } public function getBlock() : Block{ return BlockFactory::get(BlockLegacyIds::WHEAT_BLOCK); diff --git a/src/pocketmine/item/WritableBook.php b/src/pocketmine/item/WritableBook.php index d4ae343c16..fca4e1222a 100644 --- a/src/pocketmine/item/WritableBook.php +++ b/src/pocketmine/item/WritableBook.php @@ -25,7 +25,4 @@ namespace pocketmine\item; class WritableBook extends WritableBookBase{ - public function __construct(){ - parent::__construct(self::WRITABLE_BOOK, 0, "Book & Quill"); - } } diff --git a/src/pocketmine/item/WrittenBook.php b/src/pocketmine/item/WrittenBook.php index 7173816bae..dbccfa77d4 100644 --- a/src/pocketmine/item/WrittenBook.php +++ b/src/pocketmine/item/WrittenBook.php @@ -34,10 +34,6 @@ class WrittenBook extends WritableBookBase{ public const TAG_AUTHOR = "author"; //TAG_String public const TAG_TITLE = "title"; //TAG_String - public function __construct(){ - parent::__construct(self::WRITTEN_BOOK, 0, "Written Book"); - } - public function getMaxStackSize() : int{ return 16; } From 41d754de5ad61a2c4f2a4e11fb43910a05a05442 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 12 May 2019 15:03:44 +0100 Subject: [PATCH 0799/3224] Vine: fix bug when reading state multiple times --- src/pocketmine/block/Vine.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index 40f7278ed3..7eff6d7541 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -68,6 +68,8 @@ class Vine extends Flowable{ private function setFaceFromMeta(int $meta, int $flag, int $face) : void{ if(($meta & $flag) !== 0){ $this->faces[$face] = true; + }else{ + unset($this->faces[$face]); } } From 90e607320294ab13a34efc750efd2fb1bc350e9b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 12 May 2019 15:58:28 +0100 Subject: [PATCH 0800/3224] Vine: Clean up awful bounding-box calculation the logic here is deceptively simple, just obscured by a lot of really nasty code. --- src/pocketmine/block/Vine.php | 59 ++++++----------------------------- 1 file changed, 9 insertions(+), 50 deletions(-) diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index 7eff6d7541..2b437991f9 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -30,8 +30,8 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use function array_intersect_key; -use function max; -use function min; +use function array_keys; +use function count; class Vine extends Flowable{ private const FLAG_SOUTH = 0x01; @@ -90,55 +90,14 @@ class Vine extends Flowable{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - $minX = 1; - $minZ = 1; - $maxX = 0; - $maxZ = 0; - - $minY = 0; - $hasSide = false; - - if(isset($this->faces[Facing::WEST])){ - $maxX = max($maxX, 0.0625); - $minX = 0; - $minZ = 0; - $maxZ = 1; - $hasSide = true; + switch(count($this->faces)){ + case 0: + return AxisAlignedBB::one()->trim(Facing::DOWN, 15 / 16); + case 1: + return AxisAlignedBB::one()->trim(Facing::opposite(array_keys($this->faces)[0]), 15 / 16); + default: + return AxisAlignedBB::one(); } - - if(isset($this->faces[Facing::EAST])){ - $minX = min($minX, 0.9375); - $maxX = 1; - $minZ = 0; - $maxZ = 1; - $hasSide = true; - } - - if(isset($this->faces[Facing::SOUTH])){ - $minZ = min($minZ, 0.9375); - $maxZ = 1; - $minX = 0; - $maxX = 1; - $hasSide = true; - } - - if(isset($this->faces[Facing::NORTH])){ - $maxZ = max($maxZ, 0.0625); - $minZ = 0; - $minX = 0; - $maxX = 1; - $hasSide = true; - } - - if(!$hasSide){ - $minY = 0.9375; - $minX = 0; - $maxX = 1; - $minZ = 0; - $maxZ = 1; - } - - return new AxisAlignedBB($minX, $minY, $minZ, $maxX, 1, $maxZ); } protected function recalculateCollisionBoxes() : array{ From db4dac6d45d67db6bc995801b0cd9c49b3466d1f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 12 May 2019 16:00:38 +0100 Subject: [PATCH 0801/3224] World: Remove incorrect isSolid() check for placement collision check isSolid() != can be collided with. That's decided by the collision boxes provided, if any. --- src/pocketmine/world/World.php | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 48df73655d..92ff2b7640 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -1813,18 +1813,16 @@ class World implements ChunkManager, Metadatable{ return false; } - if($hand->isSolid()){ - foreach($hand->getCollisionBoxes() as $collisionBox){ - if(!empty($this->getCollidingEntities($collisionBox))){ - return false; //Entity in block - } + foreach($hand->getCollisionBoxes() as $collisionBox){ + if(!empty($this->getCollidingEntities($collisionBox))){ + return false; //Entity in block + } - if($player !== null){ - if(($diff = $player->getNextPosition()->subtract($player->getPosition())) and $diff->lengthSquared() > 0.00001){ - $bb = $player->getBoundingBox()->offsetCopy($diff->x, $diff->y, $diff->z); - if($collisionBox->intersectsWith($bb)){ - return false; //Inside player BB - } + if($player !== null){ + if(($diff = $player->getNextPosition()->subtract($player->getPosition())) and $diff->lengthSquared() > 0.00001){ + $bb = $player->getBoundingBox()->offsetCopy($diff->x, $diff->y, $diff->z); + if($collisionBox->intersectsWith($bb)){ + return false; //Inside player BB } } } From adf46396256593078afe6685df6338b3e435f5a8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 12 May 2019 16:10:51 +0100 Subject: [PATCH 0802/3224] Painting: Clean up painful BB calculation code --- src/pocketmine/entity/object/Painting.php | 49 ++++------------------- 1 file changed, 7 insertions(+), 42 deletions(-) diff --git a/src/pocketmine/entity/object/Painting.php b/src/pocketmine/entity/object/Painting.php index 44f545f892..705d80abc1 100644 --- a/src/pocketmine/entity/object/Painting.php +++ b/src/pocketmine/entity/object/Painting.php @@ -178,49 +178,14 @@ class Painting extends Entity{ $horizontalStart = (int) (ceil($width / 2) - 1); $verticalStart = (int) (ceil($height / 2) - 1); - $thickness = 1 / 16; + $bb = AxisAlignedBB::one() + ->trim($facing, 15 / 16) + ->extend(Facing::rotateY($facing, true), $horizontalStart) + ->extend(Facing::rotateY($facing, false), -$horizontalStart + $width - 1) + ->extend(Facing::DOWN, $verticalStart) + ->extend(Facing::UP, -$verticalStart + $height - 1); - $minX = $maxX = 0; - $minZ = $maxZ = 0; - - $minY = -$verticalStart; - $maxY = $minY + $height; - - switch($facing){ - case Facing::NORTH: - $minZ = 1 - $thickness; - $maxZ = 1; - $maxX = $horizontalStart + 1; - $minX = $maxX - $width; - break; - case Facing::SOUTH: - $minZ = 0; - $maxZ = $thickness; - $minX = -$horizontalStart; - $maxX = $minX + $width; - break; - case Facing::WEST: - $minX = 1 - $thickness; - $maxX = 1; - $minZ = -$horizontalStart; - $maxZ = $minZ + $width; - break; - case Facing::EAST: - $minX = 0; - $maxX = $thickness; - $maxZ = $horizontalStart + 1; - $minZ = $maxZ - $width; - break; - } - - return new AxisAlignedBB( - $blockIn->x + $minX, - $blockIn->y + $minY, - $blockIn->z + $minZ, - $blockIn->x + $maxX, - $blockIn->y + $maxY, - $blockIn->z + $maxZ - ); + return $bb->offset($blockIn->x, $blockIn->y, $blockIn->z); } /** From a19651a8dc82aa26def19b038e5f122c3d9cfa9a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 12 May 2019 16:15:31 +0100 Subject: [PATCH 0803/3224] Painting: reduce complexity of getPaintingBB() this makes it easier to unit-test. --- src/pocketmine/entity/object/Painting.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/entity/object/Painting.php b/src/pocketmine/entity/object/Painting.php index 705d80abc1..2b38a835c3 100644 --- a/src/pocketmine/entity/object/Painting.php +++ b/src/pocketmine/entity/object/Painting.php @@ -114,7 +114,8 @@ class Painting extends Entity{ protected function recalculateBoundingBox() : void{ $facing = Bearing::toFacing($this->direction); - $this->boundingBox->setBB(self::getPaintingBB($this->blockIn->getSide($facing), $facing, $this->getMotive())); + $side = $this->blockIn->getSide($facing); + $this->boundingBox->setBB(self::getPaintingBB($facing, $this->getMotive())->offset($side->x, $side->y, $side->z)); } public function onNearbyBlockChange() : void{ @@ -165,27 +166,24 @@ class Painting extends Entity{ /** * Returns the bounding-box a painting with the specified motive would have at the given position and direction. * - * @param Vector3 $blockIn * @param int $facing * @param PaintingMotive $motive * * @return AxisAlignedBB */ - private static function getPaintingBB(Vector3 $blockIn, int $facing, PaintingMotive $motive) : AxisAlignedBB{ + private static function getPaintingBB(int $facing, PaintingMotive $motive) : AxisAlignedBB{ $width = $motive->getWidth(); $height = $motive->getHeight(); $horizontalStart = (int) (ceil($width / 2) - 1); $verticalStart = (int) (ceil($height / 2) - 1); - $bb = AxisAlignedBB::one() + return AxisAlignedBB::one() ->trim($facing, 15 / 16) ->extend(Facing::rotateY($facing, true), $horizontalStart) ->extend(Facing::rotateY($facing, false), -$horizontalStart + $width - 1) ->extend(Facing::DOWN, $verticalStart) ->extend(Facing::UP, -$verticalStart + $height - 1); - - return $bb->offset($blockIn->x, $blockIn->y, $blockIn->z); } /** @@ -224,7 +222,7 @@ class Painting extends Entity{ } if($checkOverlap){ - $bb = self::getPaintingBB($blockIn, $facing, $motive); + $bb = self::getPaintingBB($facing, $motive)->offset($blockIn->x, $blockIn->y, $blockIn->z); foreach($world->getNearbyEntities($bb) as $entity){ if($entity instanceof self){ From d6b720b55db1ef94a76681015f49791680b39220 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 12 May 2019 16:21:52 +0100 Subject: [PATCH 0804/3224] Wall: minor BB calculation cleanup --- src/pocketmine/block/Wall.php | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/pocketmine/block/Wall.php b/src/pocketmine/block/Wall.php index c586fb1d7b..785140bdcd 100644 --- a/src/pocketmine/block/Wall.php +++ b/src/pocketmine/block/Wall.php @@ -87,13 +87,11 @@ class Wall extends Transparent{ $inset = 0.3125; } - return new AxisAlignedBB( - ($west ? 0 : $inset), - 0, - ($north ? 0 : $inset), - 1 - ($east ? 0 : $inset), - 1.5, - 1 - ($south ? 0 : $inset) - ); + return AxisAlignedBB::one() + ->extend(Facing::UP, 0.5) + ->trim(Facing::NORTH, $north ? 0 : $inset) + ->trim(Facing::SOUTH, $south ? 0 : $inset) + ->trim(Facing::WEST, $west ? 0 : $inset) + ->trim(Facing::EAST, $east ? 0 : $inset); } } From 166d821bcf2f1f611ac63e018fd641ecdd1440fe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 12 May 2019 16:22:20 +0100 Subject: [PATCH 0805/3224] Stair: some BB handling cleanup --- src/pocketmine/block/Stair.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index a66ef1d11d..392e5efd70 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -71,23 +71,21 @@ abstract class Stair extends Transparent{ } protected function recalculateCollisionBoxes() : array{ - $minYSlab = $this->upsideDown ? 0.5 : 0; - + $topStepFace = $this->upsideDown ? Facing::DOWN : Facing::UP; $bbs = [ - new AxisAlignedBB(0, $minYSlab, 0, 1, $minYSlab + 0.5, 1) + AxisAlignedBB::one()->trim($topStepFace, 0.5) ]; - $minY = $this->upsideDown ? 0 : 0.5; - - $topStep = new AxisAlignedBB(0, $minY, 0, 1, $minY + 0.5, 1); - $topStep->trim(Facing::opposite($this->facing), 0.5); + $topStep = AxisAlignedBB::one() + ->trim(Facing::opposite($topStepFace), 0.5) + ->trim(Facing::opposite($this->facing), 0.5); if($this->shape === self::SHAPE_OUTER_LEFT or $this->shape === self::SHAPE_OUTER_RIGHT){ $topStep->trim(Facing::rotateY($this->facing, $this->shape === self::SHAPE_OUTER_LEFT), 0.5); }elseif($this->shape === self::SHAPE_INNER_LEFT or $this->shape === self::SHAPE_INNER_RIGHT){ //add an extra cube - $extraCube = new AxisAlignedBB(0, $minY, 0, 1, $minY + 0.5, 1); - $bbs[] = $extraCube + $bbs[] = AxisAlignedBB::one() + ->trim(Facing::opposite($topStepFace), 0.5) ->trim($this->facing, 0.5) //avoid overlapping with main step ->trim(Facing::rotateY($this->facing, $this->shape === self::SHAPE_INNER_LEFT), 0.5); } From 85c6eb50031db1964ff0981e0968610b93d3ef50 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 12 May 2019 16:22:41 +0100 Subject: [PATCH 0806/3224] Fence: cleanup some BB handling --- src/pocketmine/block/Fence.php | 53 ++++++++++++++-------------------- 1 file changed, 21 insertions(+), 32 deletions(-) diff --git a/src/pocketmine/block/Fence.php b/src/pocketmine/block/Fence.php index caad4df8e6..31ec5e9bf3 100644 --- a/src/pocketmine/block/Fence.php +++ b/src/pocketmine/block/Fence.php @@ -50,14 +50,14 @@ abstract class Fence extends Transparent{ protected function recalculateBoundingBox() : ?AxisAlignedBB{ $width = 0.5 - $this->getThickness() / 2; - return new AxisAlignedBB( - (isset($this->connections[Facing::WEST]) ? 0 : $width), - 0, - (isset($this->connections[Facing::NORTH]) ? 0 : $width), - 1 - (isset($this->connections[Facing::EAST]) ? 0 : $width), - 1.5, - 1 - (isset($this->connections[Facing::WEST]) ? 0 : $width) - ); + $bb = AxisAlignedBB::one() + ->extend(Facing::UP, 0.5); + foreach(Facing::HORIZONTAL as $facing){ + if(!isset($this->connections[$facing])){ + $bb->trim($facing, $width); + } + } + return $bb; } protected function recalculateCollisionBoxes() : array{ @@ -71,14 +71,11 @@ abstract class Fence extends Transparent{ if($connectWest or $connectEast){ //X axis (west/east) - $bbs[] = new AxisAlignedBB( - ($connectWest ? 0 : $inset), - 0, - $inset, - 1 - ($connectEast ? 0 : $inset), - 1.5, - 1 - $inset - ); + $bbs[] = AxisAlignedBB::one() + ->squash(Facing::AXIS_Z, $inset) + ->extend(Facing::UP, 0.5) + ->trim(Facing::WEST, $connectWest ? 0 : $inset) + ->trim(Facing::EAST, $connectEast ? 0 : $inset); } $connectNorth = isset($this->connections[Facing::NORTH]); @@ -86,27 +83,19 @@ abstract class Fence extends Transparent{ if($connectNorth or $connectSouth){ //Z axis (north/south) - $bbs[] = new AxisAlignedBB( - $inset, - 0, - ($connectNorth ? 0 : $inset), - 1 - $inset, - 1.5, - 1 - ($connectSouth ? 0 : $inset) - ); + $bbs[] = AxisAlignedBB::one() + ->squash(Facing::AXIS_X, $inset) + ->extend(Facing::UP, 0.5) + ->trim(Facing::NORTH, $connectNorth ? 0 : $inset) + ->trim(Facing::SOUTH, $connectSouth ? 0 : $inset); } if(empty($bbs)){ //centre post AABB (only needed if not connected on any axis - other BBs overlapping will do this if any connections are made) return [ - new AxisAlignedBB( - $inset, - 0, - $inset, - 1 - $inset, - 1.5, - 1 - $inset - ) + AxisAlignedBB::one() + ->extend(Facing::UP, 0.5) + ->contract($inset, 0, $inset) ]; } From 10831821bea893ca28897135a6d596d45600b802 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 12 May 2019 17:58:45 +0100 Subject: [PATCH 0807/3224] Anvil: fix wrong visibility for recalculateBoundingBox() --- src/pocketmine/block/Anvil.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index 928a1b8e78..c0867968e5 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -61,7 +61,7 @@ class Anvil extends Transparent implements Fallable{ return 0b11; } - public function recalculateBoundingBox() : ?AxisAlignedBB{ + protected function recalculateBoundingBox() : ?AxisAlignedBB{ return AxisAlignedBB::one()->squash(Facing::axis(Facing::rotateY($this->facing, false)), 1 / 8); } From fd413b512e3572edfd83805e78f42cf747ac6874 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 12 May 2019 18:42:49 +0100 Subject: [PATCH 0808/3224] Remove useless Dandelion class this class is line-for-line identical to the Flower class. --- src/pocketmine/block/BlockFactory.php | 2 +- src/pocketmine/block/Dandelion.php | 59 --------------------------- src/pocketmine/block/FlowerPot.php | 1 - 3 files changed, 1 insertion(+), 61 deletions(-) delete mode 100644 src/pocketmine/block/Dandelion.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 8f922b5534..0fb38adfc6 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -95,7 +95,6 @@ class BlockFactory{ self::register(new Cobweb(new BID(BlockLegacyIds::COBWEB), "Cobweb")); self::register(new CocoaBlock(new BID(BlockLegacyIds::COCOA), "Cocoa Block")); self::register(new CraftingTable(new BID(BlockLegacyIds::CRAFTING_TABLE), "Crafting Table")); - self::register(new Dandelion(new BID(BlockLegacyIds::DANDELION), "Dandelion")); self::register(new DaylightSensor(new BlockIdentifierFlattened(BlockLegacyIds::DAYLIGHT_DETECTOR, BlockLegacyIds::DAYLIGHT_DETECTOR_INVERTED), "Daylight Sensor")); self::register(new DeadBush(new BID(BlockLegacyIds::DEADBUSH), "Dead Bush")); self::register(new DetectorRail(new BID(BlockLegacyIds::DETECTOR_RAIL), "Detector Rail")); @@ -119,6 +118,7 @@ class BlockFactory{ self::register(new EnderChest(new BID(BlockLegacyIds::ENDER_CHEST, 0, null, \pocketmine\tile\EnderChest::class), "Ender Chest")); self::register(new Farmland(new BID(BlockLegacyIds::FARMLAND), "Farmland")); self::register(new Fire(new BID(BlockLegacyIds::FIRE), "Fire Block")); + self::register(new Flower(new BID(BlockLegacyIds::DANDELION), "Dandelion")); self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_ALLIUM), "Allium")); self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_AZURE_BLUET), "Azure Bluet")); self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_BLUE_ORCHID), "Blue Orchid")); diff --git a/src/pocketmine/block/Dandelion.php b/src/pocketmine/block/Dandelion.php deleted file mode 100644 index d562afbd82..0000000000 --- a/src/pocketmine/block/Dandelion.php +++ /dev/null @@ -1,59 +0,0 @@ -getSide(Facing::DOWN); - if($down->getId() === BlockLegacyIds::GRASS or $down->getId() === BlockLegacyIds::DIRT or $down->getId() === BlockLegacyIds::FARMLAND){ - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); - } - - return false; - } - - public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->getWorld()->useBreakOn($this); - } - } - - public function getFlameEncouragement() : int{ - return 60; - } - - public function getFlammability() : int{ - return 100; - } -} diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 2cd993830f..50b44214af 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -102,7 +102,6 @@ class FlowerPot extends Flowable{ return $block instanceof Cactus or - $block instanceof Dandelion or $block instanceof DeadBush or $block instanceof Flower or $block instanceof RedMushroom or From 5024de38b8bff10aa9a4e3822b3e582740783123 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 15 May 2019 18:15:25 +0100 Subject: [PATCH 0809/3224] added more types of stone slab --- src/pocketmine/block/BlockFactory.php | 19 ++++++++++++++----- .../block_factory_consistency_check.json | 2 +- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 0fb38adfc6..b83c440314 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -268,7 +268,7 @@ class BlockFactory{ self::register(new StoneBricks(new BID(BlockLegacyIds::STONEBRICK, StoneBricks::NORMAL), "Stone Bricks")); self::register(new StoneButton(new BID(BlockLegacyIds::STONE_BUTTON), "Stone Button")); self::register(new StonePressurePlate(new BID(BlockLegacyIds::STONE_PRESSURE_PLATE), "Stone Pressure Plate")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 0), "Stone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 0), "Smooth Stone")); self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 1), "Sandstone")); self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 2), "Fake Wooden")); self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 3), "Cobblestone")); @@ -284,6 +284,19 @@ class BlockFactory{ self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, 5), "Mossy Cobblestone")); self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, 6), "Smooth Sandstone")); self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, 7), "Red Nether Brick")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, 0), "End Stone Brick")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, 1), "Smooth Red Sandstone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, 2), "Polished Andesite")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, 3), "Andesite")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, 4), "Diorite")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, 5), "Polished Diorite")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, 6), "Granite")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, 7), "Polished Granite")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB4, BlockLegacyIds::DOUBLE_STONE_SLAB4, 0), "Mossy Stone Brick")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB4, BlockLegacyIds::DOUBLE_STONE_SLAB4, 1), "Smooth Quartz")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB4, BlockLegacyIds::DOUBLE_STONE_SLAB4, 2), "Stone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB4, BlockLegacyIds::DOUBLE_STONE_SLAB4, 3), "Cut Sandstone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB4, BlockLegacyIds::DOUBLE_STONE_SLAB4, 4), "Cut Red Sandstone")); self::register(new Stonecutter(new BID(BlockLegacyIds::STONECUTTER), "Stonecutter")); self::register(new Sugarcane(new BID(BlockLegacyIds::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane")); self::register(new TNT(new BID(BlockLegacyIds::TNT), "TNT")); @@ -490,8 +503,6 @@ class BlockFactory{ //TODO: minecraft:dark_prismarine_stairs //TODO: minecraft:diorite_stairs //TODO: minecraft:dispenser - //TODO: minecraft:double_stone_slab3 - //TODO: minecraft:double_stone_slab4 //TODO: minecraft:dried_kelp_block //TODO: minecraft:dropper //TODO: minecraft:end_brick_stairs @@ -533,8 +544,6 @@ class BlockFactory{ //TODO: minecraft:smooth_sandstone_stairs //TODO: minecraft:smooth_stone //TODO: minecraft:sticky_piston - //TODO: minecraft:stone_slab3 - //TODO: minecraft:stone_slab4 //TODO: minecraft:stonecutter_block //TODO: minecraft:stripped_acacia_log //TODO: minecraft:stripped_birch_log diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 334fc33ea7..ff2d5f0f02 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Moss Stone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4256":"Blue Ice","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Moss Stone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4256":"Blue Ice","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From ff2600a0d070e3c8e4291cf6fdf560ad660b099f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 16 May 2019 14:20:51 +0100 Subject: [PATCH 0810/3224] Regenerated TODOs for BlockFactory and ItemFactory also added //region and //endregion for IDE collapsibility --- src/pocketmine/block/BlockFactory.php | 123 ++++++++++++++++++++++++++ src/pocketmine/item/ItemFactory.php | 12 +-- 2 files changed, 129 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index b83c440314..7001747cdd 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -473,6 +473,7 @@ class BlockFactory{ self::register(new Wall(new BID(BlockLegacyIds::COBBLESTONE_WALL, $magicNumber), $prefix . " Wall")); } + //region --- auto-generated TODOs --- //TODO: minecraft:andesite_stairs //TODO: minecraft:bamboo //TODO: minecraft:bamboo_sapling @@ -505,6 +506,125 @@ class BlockFactory{ //TODO: minecraft:dispenser //TODO: minecraft:dried_kelp_block //TODO: minecraft:dropper + //TODO: minecraft:element_0 + //TODO: minecraft:element_1 + //TODO: minecraft:element_10 + //TODO: minecraft:element_100 + //TODO: minecraft:element_101 + //TODO: minecraft:element_102 + //TODO: minecraft:element_103 + //TODO: minecraft:element_104 + //TODO: minecraft:element_105 + //TODO: minecraft:element_106 + //TODO: minecraft:element_107 + //TODO: minecraft:element_108 + //TODO: minecraft:element_109 + //TODO: minecraft:element_11 + //TODO: minecraft:element_110 + //TODO: minecraft:element_111 + //TODO: minecraft:element_112 + //TODO: minecraft:element_113 + //TODO: minecraft:element_114 + //TODO: minecraft:element_115 + //TODO: minecraft:element_116 + //TODO: minecraft:element_117 + //TODO: minecraft:element_118 + //TODO: minecraft:element_12 + //TODO: minecraft:element_13 + //TODO: minecraft:element_14 + //TODO: minecraft:element_15 + //TODO: minecraft:element_16 + //TODO: minecraft:element_17 + //TODO: minecraft:element_18 + //TODO: minecraft:element_19 + //TODO: minecraft:element_2 + //TODO: minecraft:element_20 + //TODO: minecraft:element_21 + //TODO: minecraft:element_22 + //TODO: minecraft:element_23 + //TODO: minecraft:element_24 + //TODO: minecraft:element_25 + //TODO: minecraft:element_26 + //TODO: minecraft:element_27 + //TODO: minecraft:element_28 + //TODO: minecraft:element_29 + //TODO: minecraft:element_3 + //TODO: minecraft:element_30 + //TODO: minecraft:element_31 + //TODO: minecraft:element_32 + //TODO: minecraft:element_33 + //TODO: minecraft:element_34 + //TODO: minecraft:element_35 + //TODO: minecraft:element_36 + //TODO: minecraft:element_37 + //TODO: minecraft:element_38 + //TODO: minecraft:element_39 + //TODO: minecraft:element_4 + //TODO: minecraft:element_40 + //TODO: minecraft:element_41 + //TODO: minecraft:element_42 + //TODO: minecraft:element_43 + //TODO: minecraft:element_44 + //TODO: minecraft:element_45 + //TODO: minecraft:element_46 + //TODO: minecraft:element_47 + //TODO: minecraft:element_48 + //TODO: minecraft:element_49 + //TODO: minecraft:element_5 + //TODO: minecraft:element_50 + //TODO: minecraft:element_51 + //TODO: minecraft:element_52 + //TODO: minecraft:element_53 + //TODO: minecraft:element_54 + //TODO: minecraft:element_55 + //TODO: minecraft:element_56 + //TODO: minecraft:element_57 + //TODO: minecraft:element_58 + //TODO: minecraft:element_59 + //TODO: minecraft:element_6 + //TODO: minecraft:element_60 + //TODO: minecraft:element_61 + //TODO: minecraft:element_62 + //TODO: minecraft:element_63 + //TODO: minecraft:element_64 + //TODO: minecraft:element_65 + //TODO: minecraft:element_66 + //TODO: minecraft:element_67 + //TODO: minecraft:element_68 + //TODO: minecraft:element_69 + //TODO: minecraft:element_7 + //TODO: minecraft:element_70 + //TODO: minecraft:element_71 + //TODO: minecraft:element_72 + //TODO: minecraft:element_73 + //TODO: minecraft:element_74 + //TODO: minecraft:element_75 + //TODO: minecraft:element_76 + //TODO: minecraft:element_77 + //TODO: minecraft:element_78 + //TODO: minecraft:element_79 + //TODO: minecraft:element_8 + //TODO: minecraft:element_80 + //TODO: minecraft:element_81 + //TODO: minecraft:element_82 + //TODO: minecraft:element_83 + //TODO: minecraft:element_84 + //TODO: minecraft:element_85 + //TODO: minecraft:element_86 + //TODO: minecraft:element_87 + //TODO: minecraft:element_88 + //TODO: minecraft:element_89 + //TODO: minecraft:element_9 + //TODO: minecraft:element_90 + //TODO: minecraft:element_91 + //TODO: minecraft:element_92 + //TODO: minecraft:element_93 + //TODO: minecraft:element_94 + //TODO: minecraft:element_95 + //TODO: minecraft:element_96 + //TODO: minecraft:element_97 + //TODO: minecraft:element_98 + //TODO: minecraft:element_99 //TODO: minecraft:end_brick_stairs //TODO: minecraft:end_gateway //TODO: minecraft:end_portal @@ -518,6 +638,8 @@ class BlockFactory{ //TODO: minecraft:lantern //TODO: minecraft:lava_cauldron //TODO: minecraft:lectern + //TODO: minecraft:lit_blast_furnace + //TODO: minecraft:lit_smoker //TODO: minecraft:loom //TODO: minecraft:mossy_cobblestone_stairs //TODO: minecraft:mossy_stone_brick_stairs @@ -555,6 +677,7 @@ class BlockFactory{ //TODO: minecraft:sweet_berry_bush //TODO: minecraft:turtle_egg //TODO: minecraft:undyed_shulker_box + //endregion } public static function isInit() : bool{ diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 31e4725b83..5ba12a9900 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -307,16 +307,15 @@ class ItemFactory{ self::register(new Boat(Item::BOAT, $type->getMagicNumber(), $type->getDisplayName() . " Boat", $type)); } - //TODO: minecraft:acacia_sign + //region --- auto-generated TODOs --- //TODO: minecraft:armor_stand //TODO: minecraft:balloon - //TODO: minecraft:birch_sign + //TODO: minecraft:banner_pattern + //TODO: minecraft:campfire //TODO: minecraft:carrotOnAStick //TODO: minecraft:chest_minecart //TODO: minecraft:command_block_minecart - //TODO: minecraft:compound //TODO: minecraft:crossbow - //TODO: minecraft:darkoak_sign //TODO: minecraft:elytra //TODO: minecraft:emptyMap //TODO: minecraft:enchanted_book @@ -332,7 +331,6 @@ class ItemFactory{ //TODO: minecraft:horsearmoriron //TODO: minecraft:horsearmorleather //TODO: minecraft:ice_bomb - //TODO: minecraft:jungle_sign //TODO: minecraft:kelp //TODO: minecraft:lead //TODO: minecraft:lingering_potion @@ -354,12 +352,14 @@ class ItemFactory{ //TODO: minecraft:record_wait //TODO: minecraft:record_ward //TODO: minecraft:saddle + //TODO: minecraft:shield //TODO: minecraft:sparkler //TODO: minecraft:spawn_egg - //TODO: minecraft:spruce_sign + //TODO: minecraft:sweet_berries //TODO: minecraft:tnt_minecart //TODO: minecraft:trident //TODO: minecraft:turtle_helmet + //endregion } /** From 642c16dfe7a2cbb4de9b4a66c746d8715f1ccb8c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 16 May 2019 14:35:34 +0100 Subject: [PATCH 0811/3224] added some //region ... //endregion --- src/pocketmine/entity/effect/Effect.php | 4 +++- src/pocketmine/item/enchantment/Enchantment.php | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/entity/effect/Effect.php b/src/pocketmine/entity/effect/Effect.php index 12f09d0a5f..5910e8eea7 100644 --- a/src/pocketmine/entity/effect/Effect.php +++ b/src/pocketmine/entity/effect/Effect.php @@ -92,7 +92,7 @@ class Effect{ self::register(new Effect(Effect::CONDUIT_POWER, "%potion.conduitPower", new Color(0x1d, 0xc2, 0xd1))); } - /* auto-generated code */ + //region --- auto-generated code --- public static function ABSORPTION() : Effect{ return self::get(Effect::ABSORPTION); @@ -198,6 +198,8 @@ class Effect{ return self::get(Effect::WITHER); } + //endregion + /** * @param Effect $effect */ diff --git a/src/pocketmine/item/enchantment/Enchantment.php b/src/pocketmine/item/enchantment/Enchantment.php index 5a8b643db5..14845b7ea5 100644 --- a/src/pocketmine/item/enchantment/Enchantment.php +++ b/src/pocketmine/item/enchantment/Enchantment.php @@ -140,6 +140,8 @@ class Enchantment{ self::register(new Enchantment(self::VANISHING, "%enchantment.curse.vanishing", self::RARITY_MYTHIC, self::SLOT_NONE, self::SLOT_ALL, 1)); } + //region --- auto-generated code --- + public static function BLAST_PROTECTION() : Enchantment{ return self::get(self::BLAST_PROTECTION); } @@ -216,6 +218,8 @@ class Enchantment{ return self::get(self::VANISHING); } + //endregion + /** * Registers an enchantment type. * From 1898db840d0d0a762022d48ca65227a61d73ed4f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 16 May 2019 14:36:02 +0100 Subject: [PATCH 0812/3224] BlockFactory: more collapsible region things --- src/pocketmine/block/BlockFactory.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 7001747cdd..057cf68221 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -320,6 +320,8 @@ class BlockFactory{ self::register(new WeightedPressurePlateLight(new BID(BlockLegacyIds::LIGHT_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Light")); self::register(new Wheat(new BID(BlockLegacyIds::WHEAT_BLOCK), "Wheat Block")); + + //region ugly treetype -> blockID mapping tables /** @var int[]|\SplObjectStorage $woodenStairIds */ $woodenStairIds = new \SplObjectStorage(); $woodenStairIds[TreeType::OAK()] = BlockLegacyIds::OAK_STAIRS; @@ -382,6 +384,7 @@ class BlockFactory{ $woodenSignIds[TreeType::JUNGLE()] = new BlockIdentifierFlattened(BlockLegacyIds::JUNGLE_STANDING_SIGN, BlockLegacyIds::JUNGLE_WALL_SIGN, 0, ItemIds::JUNGLE_SIGN, \pocketmine\tile\Sign::class); $woodenSignIds[TreeType::ACACIA()] = new BlockIdentifierFlattened(BlockLegacyIds::ACACIA_STANDING_SIGN, BlockLegacyIds::ACACIA_WALL_SIGN, 0, ItemIds::ACACIA_SIGN, \pocketmine\tile\Sign::class); $woodenSignIds[TreeType::DARK_OAK()] = new BlockIdentifierFlattened(BlockLegacyIds::DARKOAK_STANDING_SIGN, BlockLegacyIds::DARKOAK_WALL_SIGN, 0, ItemIds::DARKOAK_SIGN, \pocketmine\tile\Sign::class); + //endregion foreach(TreeType::getAll() as $treeType){ $magicNumber = $treeType->getMagicNumber(); @@ -421,6 +424,7 @@ class BlockFactory{ self::register(new Sandstone(new BID(BlockLegacyIds::RED_SANDSTONE, $variant), $prefix . "Red Sandstone")); } + //region ugly glazed-terracotta colour -> ID mapping table /** @var int[]|\SplObjectStorage $glazedTerracottaIds */ $glazedTerracottaIds = new \SplObjectStorage(); $glazedTerracottaIds[DyeColor::WHITE()] = BlockLegacyIds::WHITE_GLAZED_TERRACOTTA; @@ -439,6 +443,7 @@ class BlockFactory{ $glazedTerracottaIds[DyeColor::GREEN()] = BlockLegacyIds::GREEN_GLAZED_TERRACOTTA; $glazedTerracottaIds[DyeColor::RED()] = BlockLegacyIds::RED_GLAZED_TERRACOTTA; $glazedTerracottaIds[DyeColor::BLACK()] = BlockLegacyIds::BLACK_GLAZED_TERRACOTTA; + //endregion foreach(DyeColor::getAll() as $color){ self::register(new Carpet(new BID(BlockLegacyIds::CARPET, $color->getMagicNumber()), $color->getDisplayName() . " Carpet")); From dd914e07523c7038c868c9969d88fdd97b00b7cf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 16 May 2019 16:55:44 +0100 Subject: [PATCH 0813/3224] Block: move all legacy metadata constants into a dedicated class this makes it easier to see what is using metadata (and makes it easier to get rid of later). --- src/pocketmine/block/Anvil.php | 4 - src/pocketmine/block/BaseRail.php | 21 +- src/pocketmine/block/Bed.php | 10 +- src/pocketmine/block/Bedrock.php | 4 +- src/pocketmine/block/BlockFactory.php | 208 +++++++-------- src/pocketmine/block/BlockLegacyMetadata.php | 236 ++++++++++++++++++ src/pocketmine/block/BrewingStand.php | 10 +- src/pocketmine/block/Button.php | 4 +- src/pocketmine/block/Dirt.php | 2 - src/pocketmine/block/Door.php | 14 +- src/pocketmine/block/DoublePlant.php | 5 +- src/pocketmine/block/EndPortalFrame.php | 4 +- src/pocketmine/block/FenceGate.php | 8 +- src/pocketmine/block/Flower.php | 11 - src/pocketmine/block/FlowerPot.php | 6 +- src/pocketmine/block/ItemFrame.php | 4 +- src/pocketmine/block/Leaves.php | 6 +- src/pocketmine/block/Lever.php | 4 +- src/pocketmine/block/Liquid.php | 4 +- src/pocketmine/block/NetherPortal.php | 4 +- src/pocketmine/block/NetherReactor.php | 5 +- src/pocketmine/block/Prismarine.php | 4 - src/pocketmine/block/Quartz.php | 5 - src/pocketmine/block/Rail.php | 12 +- src/pocketmine/block/RedstoneComparator.php | 8 +- src/pocketmine/block/RedstoneRail.php | 7 +- src/pocketmine/block/Sandstone.php | 5 - src/pocketmine/block/Sapling.php | 4 +- src/pocketmine/block/SeaPickle.php | 4 +- src/pocketmine/block/SimplePressurePlate.php | 4 +- src/pocketmine/block/Slab.php | 4 +- src/pocketmine/block/Sponge.php | 4 +- src/pocketmine/block/Stair.php | 4 +- src/pocketmine/block/Stone.php | 7 - src/pocketmine/block/StoneBricks.php | 4 - src/pocketmine/block/TNT.php | 4 +- src/pocketmine/block/Trapdoor.php | 8 +- src/pocketmine/block/Tripwire.php | 13 +- src/pocketmine/block/TripwireHook.php | 8 +- src/pocketmine/block/Vine.php | 20 +- src/pocketmine/block/Wall.php | 14 -- .../level/format/io/SubChunkConverter.php | 38 --- 42 files changed, 443 insertions(+), 312 deletions(-) create mode 100644 src/pocketmine/block/BlockLegacyMetadata.php delete mode 100644 tests/phpunit/level/format/io/SubChunkConverter.php diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index c0867968e5..5ae46ae11e 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -38,10 +38,6 @@ use pocketmine\Player; class Anvil extends Transparent implements Fallable{ use FallableTrait; - public const TYPE_NORMAL = 0; - public const TYPE_SLIGHTLY_DAMAGED = 4; - public const TYPE_VERY_DAMAGED = 8; - /** @var int */ protected $facing = Facing::NORTH; diff --git a/src/pocketmine/block/BaseRail.php b/src/pocketmine/block/BaseRail.php index 8e157951a8..cca6821455 100644 --- a/src/pocketmine/block/BaseRail.php +++ b/src/pocketmine/block/BaseRail.php @@ -38,40 +38,33 @@ use function in_array; abstract class BaseRail extends Flowable{ - public const STRAIGHT_NORTH_SOUTH = 0; - public const STRAIGHT_EAST_WEST = 1; - public const ASCENDING_EAST = 2; - public const ASCENDING_WEST = 3; - public const ASCENDING_NORTH = 4; - public const ASCENDING_SOUTH = 5; - protected const FLAG_ASCEND = 1 << 24; //used to indicate direction-up protected const CONNECTIONS = [ //straights - self::STRAIGHT_NORTH_SOUTH => [ + BlockLegacyMetadata::RAIL_STRAIGHT_NORTH_SOUTH => [ Facing::NORTH, Facing::SOUTH ], - self::STRAIGHT_EAST_WEST => [ + BlockLegacyMetadata::RAIL_STRAIGHT_EAST_WEST => [ Facing::EAST, Facing::WEST ], //ascending - self::ASCENDING_EAST => [ + BlockLegacyMetadata::RAIL_ASCENDING_EAST => [ Facing::WEST, Facing::EAST | self::FLAG_ASCEND ], - self::ASCENDING_WEST => [ + BlockLegacyMetadata::RAIL_ASCENDING_WEST => [ Facing::EAST, Facing::WEST | self::FLAG_ASCEND ], - self::ASCENDING_NORTH => [ + BlockLegacyMetadata::RAIL_ASCENDING_NORTH => [ Facing::SOUTH, Facing::NORTH | self::FLAG_ASCEND ], - self::ASCENDING_SOUTH => [ + BlockLegacyMetadata::RAIL_ASCENDING_SOUTH => [ Facing::NORTH, Facing::SOUTH | self::FLAG_ASCEND ] @@ -86,7 +79,7 @@ abstract class BaseRail extends Flowable{ protected function writeStateToMeta() : int{ if(empty($this->connections)){ - return self::STRAIGHT_NORTH_SOUTH; + return BlockLegacyMetadata::RAIL_STRAIGHT_NORTH_SOUTH; } return $this->getMetaForState($this->connections); } diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index e9597552a4..bd7037402f 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -39,8 +39,6 @@ use pocketmine\utils\TextFormat; use pocketmine\world\World; class Bed extends Transparent{ - private const BITFLAG_OCCUPIED = 0x04; - private const BITFLAG_HEAD = 0x08; /** @var int */ protected $facing = Facing::NORTH; @@ -58,14 +56,14 @@ class Bed extends Transparent{ protected function writeStateToMeta() : int{ return Bearing::fromFacing($this->facing) | - ($this->occupied ? self::BITFLAG_OCCUPIED : 0) | - ($this->head ? self::BITFLAG_HEAD : 0); + ($this->occupied ? BlockLegacyMetadata::BED_FLAG_OCCUPIED : 0) | + ($this->head ? BlockLegacyMetadata::BED_FLAG_HEAD : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); - $this->occupied = ($stateMeta & self::BITFLAG_OCCUPIED) !== 0; - $this->head = ($stateMeta & self::BITFLAG_HEAD) !== 0; + $this->occupied = ($stateMeta & BlockLegacyMetadata::BED_FLAG_OCCUPIED) !== 0; + $this->head = ($stateMeta & BlockLegacyMetadata::BED_FLAG_HEAD) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Bedrock.php b/src/pocketmine/block/Bedrock.php index 1c40563a3f..127846c050 100644 --- a/src/pocketmine/block/Bedrock.php +++ b/src/pocketmine/block/Bedrock.php @@ -33,11 +33,11 @@ class Bedrock extends Solid{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->burnsForever = $stateMeta !== 0; + $this->burnsForever = ($stateMeta & BlockLegacyMetadata::BEDROCK_FLAG_INFINIBURN) !== 0; } protected function writeStateToMeta() : int{ - return $this->burnsForever ? 1 : 0; + return $this->burnsForever ? BlockLegacyMetadata::BEDROCK_FLAG_INFINIBURN : 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 057cf68221..9ecccb642d 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -63,11 +63,11 @@ class BlockFactory{ self::$diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 8192, false)); self::$blastResistance = \SplFixedArray::fromArray(array_fill(0, 8192, 0)); - self::register(new ActivatorRail(new BID(BlockLegacyIds::ACTIVATOR_RAIL, BaseRail::STRAIGHT_NORTH_SOUTH), "Activator Rail")); + self::register(new ActivatorRail(new BID(BlockLegacyIds::ACTIVATOR_RAIL), "Activator Rail")); self::register(new Air(new BID(BlockLegacyIds::AIR), "Air")); - self::register(new Anvil(new BID(BlockLegacyIds::ANVIL, Anvil::TYPE_NORMAL), "Anvil")); - self::register(new Anvil(new BID(BlockLegacyIds::ANVIL, Anvil::TYPE_SLIGHTLY_DAMAGED), "Slightly Damaged Anvil")); - self::register(new Anvil(new BID(BlockLegacyIds::ANVIL, Anvil::TYPE_VERY_DAMAGED), "Very Damaged Anvil")); + self::register(new Anvil(new BID(BlockLegacyIds::ANVIL, BlockLegacyMetadata::ANVIL_NORMAL), "Anvil")); + self::register(new Anvil(new BID(BlockLegacyIds::ANVIL, BlockLegacyMetadata::ANVIL_SLIGHTLY_DAMAGED), "Slightly Damaged Anvil")); + self::register(new Anvil(new BID(BlockLegacyIds::ANVIL, BlockLegacyMetadata::ANVIL_VERY_DAMAGED), "Very Damaged Anvil")); self::register(new Banner(new BlockIdentifierFlattened(BlockLegacyIds::STANDING_BANNER, BlockLegacyIds::WALL_BANNER, 0, ItemIds::BANNER, \pocketmine\tile\Banner::class), "Banner")); self::register(new Barrier(new BID(BlockLegacyIds::BARRIER), "Barrier")); self::register(new Bed(new BID(BlockLegacyIds::BED_BLOCK, 0, ItemIds::BED, \pocketmine\tile\Bed::class), "Bed Block")); @@ -88,7 +88,7 @@ class BlockFactory{ self::register(new Clay(new BID(BlockLegacyIds::CLAY_BLOCK), "Clay Block")); self::register(new Coal(new BID(BlockLegacyIds::COAL_BLOCK), "Coal Block")); self::register(new CoalOre(new BID(BlockLegacyIds::COAL_ORE), "Coal Ore")); - self::register(new CoarseDirt(new BID(BlockLegacyIds::DIRT, Dirt::COARSE), "Coarse Dirt")); + self::register(new CoarseDirt(new BID(BlockLegacyIds::DIRT, BlockLegacyMetadata::DIRT_COARSE), "Coarse Dirt")); self::register(new Cobblestone(new BID(BlockLegacyIds::COBBLESTONE), "Cobblestone")); self::register(new Cobblestone(new BID(BlockLegacyIds::MOSSY_COBBLESTONE), "Moss Stone")); self::register(new CobblestoneStairs(new BID(BlockLegacyIds::COBBLESTONE_STAIRS), "Cobblestone Stairs")); @@ -100,13 +100,13 @@ class BlockFactory{ self::register(new DetectorRail(new BID(BlockLegacyIds::DETECTOR_RAIL), "Detector Rail")); self::register(new Diamond(new BID(BlockLegacyIds::DIAMOND_BLOCK), "Diamond Block")); self::register(new DiamondOre(new BID(BlockLegacyIds::DIAMOND_ORE), "Diamond Ore")); - self::register(new Dirt(new BID(BlockLegacyIds::DIRT, Dirt::NORMAL), "Dirt")); - self::register(new DoublePlant(new BID(BlockLegacyIds::DOUBLE_PLANT, 0), "Sunflower")); - self::register(new DoublePlant(new BID(BlockLegacyIds::DOUBLE_PLANT, 1), "Lilac")); - self::register(new DoublePlant(new BID(BlockLegacyIds::DOUBLE_PLANT, 4), "Rose Bush")); - self::register(new DoublePlant(new BID(BlockLegacyIds::DOUBLE_PLANT, 5), "Peony")); - self::register(new DoubleTallGrass(new BID(BlockLegacyIds::DOUBLE_PLANT, 2), "Double Tallgrass")); - self::register(new DoubleTallGrass(new BID(BlockLegacyIds::DOUBLE_PLANT, 3), "Large Fern")); + self::register(new Dirt(new BID(BlockLegacyIds::DIRT, BlockLegacyMetadata::DIRT_NORMAL), "Dirt")); + self::register(new DoublePlant(new BID(BlockLegacyIds::DOUBLE_PLANT, BlockLegacyMetadata::DOUBLE_PLANT_SUNFLOWER), "Sunflower")); + self::register(new DoublePlant(new BID(BlockLegacyIds::DOUBLE_PLANT, BlockLegacyMetadata::DOUBLE_PLANT_LILAC), "Lilac")); + self::register(new DoublePlant(new BID(BlockLegacyIds::DOUBLE_PLANT, BlockLegacyMetadata::DOUBLE_PLANT_ROSE_BUSH), "Rose Bush")); + self::register(new DoublePlant(new BID(BlockLegacyIds::DOUBLE_PLANT, BlockLegacyMetadata::DOUBLE_PLANT_PEONY), "Peony")); + self::register(new DoubleTallGrass(new BID(BlockLegacyIds::DOUBLE_PLANT, BlockLegacyMetadata::DOUBLE_PLANT_TALLGRASS), "Double Tallgrass")); + self::register(new DoubleTallGrass(new BID(BlockLegacyIds::DOUBLE_PLANT, BlockLegacyMetadata::DOUBLE_PLANT_LARGE_FERN), "Large Fern")); self::register(new DragonEgg(new BID(BlockLegacyIds::DRAGON_EGG), "Dragon Egg")); self::register(new Emerald(new BID(BlockLegacyIds::EMERALD_BLOCK), "Emerald Block")); self::register(new EmeraldOre(new BID(BlockLegacyIds::EMERALD_ORE), "Emerald Ore")); @@ -119,17 +119,17 @@ class BlockFactory{ self::register(new Farmland(new BID(BlockLegacyIds::FARMLAND), "Farmland")); self::register(new Fire(new BID(BlockLegacyIds::FIRE), "Fire Block")); self::register(new Flower(new BID(BlockLegacyIds::DANDELION), "Dandelion")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_ALLIUM), "Allium")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_AZURE_BLUET), "Azure Bluet")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_BLUE_ORCHID), "Blue Orchid")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_CORNFLOWER), "Cornflower")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_LILY_OF_THE_VALLEY), "Lily of the Valley")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_ORANGE_TULIP), "Orange Tulip")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_OXEYE_DAISY), "Oxeye Daisy")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_PINK_TULIP), "Pink Tulip")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_POPPY), "Poppy")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_RED_TULIP), "Red Tulip")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, Flower::TYPE_WHITE_TULIP), "White Tulip")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_ALLIUM), "Allium")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_AZURE_BLUET), "Azure Bluet")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_BLUE_ORCHID), "Blue Orchid")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_CORNFLOWER), "Cornflower")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_LILY_OF_THE_VALLEY), "Lily of the Valley")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_ORANGE_TULIP), "Orange Tulip")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_OXEYE_DAISY), "Oxeye Daisy")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_PINK_TULIP), "Pink Tulip")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_POPPY), "Poppy")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_RED_TULIP), "Red Tulip")); + self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_WHITE_TULIP), "White Tulip")); self::register(new FlowerPot(new BID(BlockLegacyIds::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, \pocketmine\tile\FlowerPot::class), "Flower Pot")); self::register(new FrostedIce(new BID(BlockLegacyIds::FROSTED_ICE), "Frosted Ice")); self::register(new Furnace(new BlockIdentifierFlattened(BlockLegacyIds::FURNACE, BlockLegacyIds::LIT_FURNACE, 0, null, \pocketmine\tile\Furnace::class), "Furnace")); @@ -147,34 +147,34 @@ class BlockFactory{ self::register(new HardenedGlassPane(new BID(BlockLegacyIds::HARD_GLASS_PANE), "Hardened Glass Pane")); self::register(new HayBale(new BID(BlockLegacyIds::HAY_BALE), "Hay Bale")); self::register(new Ice(new BID(BlockLegacyIds::ICE), "Ice")); - self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG), "Infested Stone") extends InfestedStone{ + self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, BlockLegacyMetadata::INFESTED_STONE), "Infested Stone") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [ItemFactory::get(ItemIds::STONE)]; } }); - self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, 1), "Infested Cobblestone") extends InfestedStone{ + self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, BlockLegacyMetadata::INFESTED_COBBLESTONE), "Infested Cobblestone") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [ItemFactory::get(ItemIds::COBBLESTONE)]; } }); - self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, 2), "Infested Stone Brick") extends InfestedStone{ + self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, BlockLegacyMetadata::INFESTED_STONE_BRICK), "Infested Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [ItemFactory::get(ItemIds::STONE_BRICK)]; } }); - self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, 3), "Infested Mossy Stone Brick") extends InfestedStone{ + self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, BlockLegacyMetadata::INFESTED_STONE_BRICK_MOSSY), "Infested Mossy Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ - return [ItemFactory::get(ItemIds::STONE_BRICK, StoneBricks::MOSSY)]; + return [ItemFactory::get(ItemIds::STONE_BRICK, BlockLegacyMetadata::STONE_BRICK_MOSSY)]; } }); - self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, 4), "Infested Cracked Stone Brick") extends InfestedStone{ + self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, BlockLegacyMetadata::INFESTED_STONE_BRICK_CRACKED), "Infested Cracked Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ - return [ItemFactory::get(ItemIds::STONE_BRICK, StoneBricks::CRACKED)]; + return [ItemFactory::get(ItemIds::STONE_BRICK, BlockLegacyMetadata::STONE_BRICK_CRACKED)]; } }); - self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, 5), "Infested Chiseled Stone Brick") extends InfestedStone{ + self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, BlockLegacyMetadata::INFESTED_STONE_BRICK_CHISELED), "Infested Chiseled Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ - return [ItemFactory::get(ItemIds::STONE_BRICK, StoneBricks::CHISELED)]; + return [ItemFactory::get(ItemIds::STONE_BRICK, BlockLegacyMetadata::STONE_BRICK_CHISELED)]; } }); self::register(new InfoUpdate(new BID(BlockLegacyIds::INFO_UPDATE), "update!")); @@ -212,25 +212,25 @@ class BlockFactory{ self::register(new PackedIce(new BID(BlockLegacyIds::PACKED_ICE), "Packed Ice")); self::register(new Podzol(new BID(BlockLegacyIds::PODZOL), "Podzol")); self::register(new Potato(new BID(BlockLegacyIds::POTATOES), "Potato Block")); - self::register(new PoweredRail(new BID(BlockLegacyIds::GOLDEN_RAIL, BaseRail::STRAIGHT_NORTH_SOUTH), "Powered Rail")); - self::register(new Prismarine(new BID(BlockLegacyIds::PRISMARINE, Prismarine::BRICKS), "Prismarine Bricks")); - self::register(new Prismarine(new BID(BlockLegacyIds::PRISMARINE, Prismarine::DARK), "Dark Prismarine")); - self::register(new Prismarine(new BID(BlockLegacyIds::PRISMARINE, Prismarine::NORMAL), "Prismarine")); + self::register(new PoweredRail(new BID(BlockLegacyIds::GOLDEN_RAIL, BlockLegacyMetadata::RAIL_STRAIGHT_NORTH_SOUTH), "Powered Rail")); + self::register(new Prismarine(new BID(BlockLegacyIds::PRISMARINE, BlockLegacyMetadata::PRISMARINE_BRICKS), "Prismarine Bricks")); + self::register(new Prismarine(new BID(BlockLegacyIds::PRISMARINE, BlockLegacyMetadata::PRISMARINE_DARK), "Dark Prismarine")); + self::register(new Prismarine(new BID(BlockLegacyIds::PRISMARINE, BlockLegacyMetadata::PRISMARINE_NORMAL), "Prismarine")); self::register(new Pumpkin(new BID(BlockLegacyIds::PUMPKIN), "Pumpkin")); self::register(new PumpkinStem(new BID(BlockLegacyIds::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem")); - self::register(new Purpur(new BID(BlockLegacyIds::PURPUR_BLOCK), "Purpur Block")); - self::register(new class(new BID(BlockLegacyIds::PURPUR_BLOCK, 2), "Purpur Pillar") extends Purpur{ + self::register(new Purpur(new BID(BlockLegacyIds::PURPUR_BLOCK, BlockLegacyMetadata::PURPUR_NORMAL), "Purpur Block")); + self::register(new class(new BID(BlockLegacyIds::PURPUR_BLOCK, BlockLegacyMetadata::PURPUR_PILLAR), "Purpur Pillar") extends Purpur{ use PillarRotationTrait; }); self::register(new PurpurStairs(new BID(BlockLegacyIds::PURPUR_STAIRS), "Purpur Stairs")); - self::register(new Quartz(new BID(BlockLegacyIds::QUARTZ_BLOCK, Quartz::NORMAL), "Quartz Block")); - self::register(new class(new BID(BlockLegacyIds::QUARTZ_BLOCK, Quartz::CHISELED), "Chiseled Quartz Block") extends Quartz{ + self::register(new Quartz(new BID(BlockLegacyIds::QUARTZ_BLOCK, BlockLegacyMetadata::QUARTZ_NORMAL), "Quartz Block")); + self::register(new class(new BID(BlockLegacyIds::QUARTZ_BLOCK, BlockLegacyMetadata::QUARTZ_CHISELED), "Chiseled Quartz Block") extends Quartz{ use PillarRotationTrait; }); - self::register(new class(new BID(BlockLegacyIds::QUARTZ_BLOCK, Quartz::PILLAR), "Quartz Pillar") extends Quartz{ + self::register(new class(new BID(BlockLegacyIds::QUARTZ_BLOCK, BlockLegacyMetadata::QUARTZ_PILLAR), "Quartz Pillar") extends Quartz{ use PillarRotationTrait; }); - self::register(new Quartz(new BID(BlockLegacyIds::QUARTZ_BLOCK, Quartz::SMOOTH), "Smooth Quartz Block")); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) + self::register(new Quartz(new BID(BlockLegacyIds::QUARTZ_BLOCK, BlockLegacyMetadata::QUARTZ_SMOOTH), "Smooth Quartz Block")); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) self::register(new QuartzStairs(new BID(BlockLegacyIds::QUARTZ_STAIRS), "Quartz Stairs")); self::register(new Rail(new BID(BlockLegacyIds::RAIL), "Rail")); self::register(new RedMushroom(new BID(BlockLegacyIds::RED_MUSHROOM), "Red Mushroom")); @@ -250,60 +250,60 @@ class BlockFactory{ self::register(new SeaLantern(new BID(BlockLegacyIds::SEALANTERN), "Sea Lantern")); self::register(new SeaPickle(new BID(BlockLegacyIds::SEA_PICKLE), "Sea Pickle")); self::register(new Skull(new BID(BlockLegacyIds::MOB_HEAD_BLOCK, 0, null, \pocketmine\tile\Skull::class), "Mob Head")); - self::register(new SmoothStone(new BID(BlockLegacyIds::STONE, Stone::NORMAL), "Stone")); + self::register(new SmoothStone(new BID(BlockLegacyIds::STONE, BlockLegacyMetadata::STONE_NORMAL), "Stone")); self::register(new Snow(new BID(BlockLegacyIds::SNOW), "Snow Block")); self::register(new SnowLayer(new BID(BlockLegacyIds::SNOW_LAYER), "Snow Layer")); self::register(new SoulSand(new BID(BlockLegacyIds::SOUL_SAND), "Soul Sand")); self::register(new Sponge(new BID(BlockLegacyIds::SPONGE), "Sponge")); - self::register(new Stone(new BID(BlockLegacyIds::STONE, Stone::ANDESITE), "Andesite")); - self::register(new Stone(new BID(BlockLegacyIds::STONE, Stone::DIORITE), "Diorite")); - self::register(new Stone(new BID(BlockLegacyIds::STONE, Stone::GRANITE), "Granite")); - self::register(new Stone(new BID(BlockLegacyIds::STONE, Stone::POLISHED_ANDESITE), "Polished Andesite")); - self::register(new Stone(new BID(BlockLegacyIds::STONE, Stone::POLISHED_DIORITE), "Polished Diorite")); - self::register(new Stone(new BID(BlockLegacyIds::STONE, Stone::POLISHED_GRANITE), "Polished Granite")); + self::register(new Stone(new BID(BlockLegacyIds::STONE, BlockLegacyMetadata::STONE_ANDESITE), "Andesite")); + self::register(new Stone(new BID(BlockLegacyIds::STONE, BlockLegacyMetadata::STONE_DIORITE), "Diorite")); + self::register(new Stone(new BID(BlockLegacyIds::STONE, BlockLegacyMetadata::STONE_GRANITE), "Granite")); + self::register(new Stone(new BID(BlockLegacyIds::STONE, BlockLegacyMetadata::STONE_POLISHED_ANDESITE), "Polished Andesite")); + self::register(new Stone(new BID(BlockLegacyIds::STONE, BlockLegacyMetadata::STONE_POLISHED_DIORITE), "Polished Diorite")); + self::register(new Stone(new BID(BlockLegacyIds::STONE, BlockLegacyMetadata::STONE_POLISHED_GRANITE), "Polished Granite")); self::register(new StoneBrickStairs(new BID(BlockLegacyIds::STONE_BRICK_STAIRS), "Stone Brick Stairs")); - self::register(new StoneBricks(new BID(BlockLegacyIds::STONEBRICK, StoneBricks::CHISELED), "Chiseled Stone Bricks")); - self::register(new StoneBricks(new BID(BlockLegacyIds::STONEBRICK, StoneBricks::CRACKED), "Cracked Stone Bricks")); - self::register(new StoneBricks(new BID(BlockLegacyIds::STONEBRICK, StoneBricks::MOSSY), "Mossy Stone Bricks")); - self::register(new StoneBricks(new BID(BlockLegacyIds::STONEBRICK, StoneBricks::NORMAL), "Stone Bricks")); + self::register(new StoneBricks(new BID(BlockLegacyIds::STONEBRICK, BlockLegacyMetadata::STONE_BRICK_CHISELED), "Chiseled Stone Bricks")); + self::register(new StoneBricks(new BID(BlockLegacyIds::STONEBRICK, BlockLegacyMetadata::STONE_BRICK_CRACKED), "Cracked Stone Bricks")); + self::register(new StoneBricks(new BID(BlockLegacyIds::STONEBRICK, BlockLegacyMetadata::STONE_BRICK_MOSSY), "Mossy Stone Bricks")); + self::register(new StoneBricks(new BID(BlockLegacyIds::STONEBRICK, BlockLegacyMetadata::STONE_BRICK_NORMAL), "Stone Bricks")); self::register(new StoneButton(new BID(BlockLegacyIds::STONE_BUTTON), "Stone Button")); self::register(new StonePressurePlate(new BID(BlockLegacyIds::STONE_PRESSURE_PLATE), "Stone Pressure Plate")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 0), "Smooth Stone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 1), "Sandstone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 2), "Fake Wooden")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 3), "Cobblestone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 4), "Brick")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 5), "Stone Brick")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 6), "Quartz")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, 7), "Nether Brick")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, 0), "Red Sandstone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, 1), "Purpur")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, 2), "Prismarine")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, 3), "Dark Prismarine")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, 4), "Prismarine Bricks")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, 5), "Mossy Cobblestone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, 6), "Smooth Sandstone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, 7), "Red Nether Brick")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, 0), "End Stone Brick")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, 1), "Smooth Red Sandstone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, 2), "Polished Andesite")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, 3), "Andesite")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, 4), "Diorite")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, 5), "Polished Diorite")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, 6), "Granite")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, 7), "Polished Granite")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB4, BlockLegacyIds::DOUBLE_STONE_SLAB4, 0), "Mossy Stone Brick")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB4, BlockLegacyIds::DOUBLE_STONE_SLAB4, 1), "Smooth Quartz")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB4, BlockLegacyIds::DOUBLE_STONE_SLAB4, 2), "Stone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB4, BlockLegacyIds::DOUBLE_STONE_SLAB4, 3), "Cut Sandstone")); - self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB4, BlockLegacyIds::DOUBLE_STONE_SLAB4, 4), "Cut Red Sandstone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, BlockLegacyMetadata::STONE_SLAB_BRICK), "Brick")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, BlockLegacyMetadata::STONE_SLAB_COBBLESTONE), "Cobblestone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, BlockLegacyMetadata::STONE_SLAB_FAKE_WOODEN), "Fake Wooden")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, BlockLegacyMetadata::STONE_SLAB_NETHER_BRICK), "Nether Brick")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, BlockLegacyMetadata::STONE_SLAB_QUARTZ), "Quartz")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, BlockLegacyMetadata::STONE_SLAB_SANDSTONE), "Sandstone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, BlockLegacyMetadata::STONE_SLAB_SMOOTH_STONE), "Smooth Stone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, BlockLegacyMetadata::STONE_SLAB_STONE_BRICK), "Stone Brick")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, BlockLegacyMetadata::STONE_SLAB2_DARK_PRISMARINE), "Dark Prismarine")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, BlockLegacyMetadata::STONE_SLAB2_MOSSY_COBBLESTONE), "Mossy Cobblestone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, BlockLegacyMetadata::STONE_SLAB2_PRISMARINE), "Prismarine")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, BlockLegacyMetadata::STONE_SLAB2_PRISMARINE_BRICKS), "Prismarine Bricks")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, BlockLegacyMetadata::STONE_SLAB2_PURPUR), "Purpur")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, BlockLegacyMetadata::STONE_SLAB2_RED_NETHER_BRICK), "Red Nether Brick")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, BlockLegacyMetadata::STONE_SLAB2_RED_SANDSTONE), "Red Sandstone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, BlockLegacyMetadata::STONE_SLAB2_SMOOTH_SANDSTONE), "Smooth Sandstone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, BlockLegacyMetadata::STONE_SLAB3_ANDESITE), "Andesite")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, BlockLegacyMetadata::STONE_SLAB3_DIORITE), "Diorite")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, BlockLegacyMetadata::STONE_SLAB3_END_STONE_BRICK), "End Stone Brick")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, BlockLegacyMetadata::STONE_SLAB3_GRANITE), "Granite")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, BlockLegacyMetadata::STONE_SLAB3_POLISHED_ANDESITE), "Polished Andesite")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, BlockLegacyMetadata::STONE_SLAB3_POLISHED_DIORITE), "Polished Diorite")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, BlockLegacyMetadata::STONE_SLAB3_POLISHED_GRANITE), "Polished Granite")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, BlockLegacyMetadata::STONE_SLAB3_SMOOTH_RED_SANDSTONE), "Smooth Red Sandstone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB4, BlockLegacyIds::DOUBLE_STONE_SLAB4, BlockLegacyMetadata::STONE_SLAB4_CUT_RED_SANDSTONE), "Cut Red Sandstone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB4, BlockLegacyIds::DOUBLE_STONE_SLAB4, BlockLegacyMetadata::STONE_SLAB4_CUT_SANDSTONE), "Cut Sandstone")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB4, BlockLegacyIds::DOUBLE_STONE_SLAB4, BlockLegacyMetadata::STONE_SLAB4_MOSSY_STONE_BRICK), "Mossy Stone Brick")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB4, BlockLegacyIds::DOUBLE_STONE_SLAB4, BlockLegacyMetadata::STONE_SLAB4_SMOOTH_QUARTZ), "Smooth Quartz")); + self::register(new StoneSlab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB4, BlockLegacyIds::DOUBLE_STONE_SLAB4, BlockLegacyMetadata::STONE_SLAB4_STONE), "Stone")); self::register(new Stonecutter(new BID(BlockLegacyIds::STONECUTTER), "Stonecutter")); self::register(new Sugarcane(new BID(BlockLegacyIds::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane")); self::register(new TNT(new BID(BlockLegacyIds::TNT), "TNT")); - self::register(new TallGrass(new BID(BlockLegacyIds::TALLGRASS), "Fern")); - self::register(new TallGrass(new BID(BlockLegacyIds::TALLGRASS, 1), "Tall Grass")); - self::register(new TallGrass(new BID(BlockLegacyIds::TALLGRASS, 2), "Fern")); - self::register(new TallGrass(new BID(BlockLegacyIds::TALLGRASS, 3), "Fern")); + self::register(new TallGrass(new BID(BlockLegacyIds::TALLGRASS), "Fern")); //TODO: remap this to normal fern + self::register(new TallGrass(new BID(BlockLegacyIds::TALLGRASS, BlockLegacyMetadata::TALLGRASS_NORMAL), "Tall Grass")); + self::register(new TallGrass(new BID(BlockLegacyIds::TALLGRASS, BlockLegacyMetadata::TALLGRASS_FERN), "Fern")); + self::register(new TallGrass(new BID(BlockLegacyIds::TALLGRASS, 3), "Fern")); //TODO: remap this to normal fern self::register(new Torch(new BID(BlockLegacyIds::COLORED_TORCH_BP), "Blue Torch")); self::register(new Torch(new BID(BlockLegacyIds::COLORED_TORCH_BP, 8), "Purple Torch")); self::register(new Torch(new BID(BlockLegacyIds::COLORED_TORCH_RG), "Red Torch")); @@ -414,10 +414,10 @@ class BlockFactory{ } static $sandstoneTypes = [ - Sandstone::NORMAL => "", - Sandstone::CHISELED => "Chiseled ", - Sandstone::CUT => "Cut ", - Sandstone::SMOOTH => "Smooth " + BlockLegacyMetadata::SANDSTONE_NORMAL => "", + BlockLegacyMetadata::SANDSTONE_CHISELED => "Chiseled ", + BlockLegacyMetadata::SANDSTONE_CUT => "Cut ", + BlockLegacyMetadata::SANDSTONE_SMOOTH => "Smooth " ]; foreach($sandstoneTypes as $variant => $prefix){ self::register(new Sandstone(new BID(BlockLegacyIds::SANDSTONE, $variant), $prefix . "Sandstone")); @@ -459,20 +459,20 @@ class BlockFactory{ } static $wallTypes = [ - Wall::ANDESITE_WALL => "Andesite", - Wall::BRICK_WALL => "Brick", - Wall::DIORITE_WALL => "Diorite", - Wall::END_STONE_BRICK_WALL => "End Stone Brick", - Wall::GRANITE_WALL => "Granite", - Wall::MOSSY_STONE_BRICK_WALL => "Mossy Stone Brick", - Wall::MOSSY_WALL => "Mossy Cobblestone", - Wall::NETHER_BRICK_WALL => "Nether Brick", - Wall::NONE_MOSSY_WALL => "Cobblestone", - Wall::PRISMARINE_WALL => "Prismarine", - Wall::RED_NETHER_BRICK_WALL => "Red Nether Brick", - Wall::RED_SANDSTONE_WALL => "Red Sandstone", - Wall::SANDSTONE_WALL => "Sandstone", - Wall::STONE_BRICK_WALL => "Stone Brick" + BlockLegacyMetadata::WALL_ANDESITE => "Andesite", + BlockLegacyMetadata::WALL_BRICK => "Brick", + BlockLegacyMetadata::WALL_DIORITE => "Diorite", + BlockLegacyMetadata::WALL_END_STONE_BRICK => "End Stone Brick", + BlockLegacyMetadata::WALL_GRANITE => "Granite", + BlockLegacyMetadata::WALL_MOSSY_STONE_BRICK => "Mossy Stone Brick", + BlockLegacyMetadata::WALL_MOSSY_COBBLESTONE => "Mossy Cobblestone", + BlockLegacyMetadata::WALL_NETHER_BRICK => "Nether Brick", + BlockLegacyMetadata::WALL_COBBLESTONE => "Cobblestone", + BlockLegacyMetadata::WALL_PRISMARINE => "Prismarine", + BlockLegacyMetadata::WALL_RED_NETHER_BRICK => "Red Nether Brick", + BlockLegacyMetadata::WALL_RED_SANDSTONE => "Red Sandstone", + BlockLegacyMetadata::WALL_SANDSTONE => "Sandstone", + BlockLegacyMetadata::WALL_STONE_BRICK => "Stone Brick" ]; foreach($wallTypes as $magicNumber => $prefix){ self::register(new Wall(new BID(BlockLegacyIds::COBBLESTONE_WALL, $magicNumber), $prefix . " Wall")); diff --git a/src/pocketmine/block/BlockLegacyMetadata.php b/src/pocketmine/block/BlockLegacyMetadata.php new file mode 100644 index 0000000000..5bad764388 --- /dev/null +++ b/src/pocketmine/block/BlockLegacyMetadata.php @@ -0,0 +1,236 @@ +eastSlot ? 0x01 : 0) | ($this->southwestSlot ? 0x02 : 0) | ($this->northwestSlot ? 0x04 : 0); + return ($this->eastSlot ? BlockLegacyMetadata::BREWING_STAND_FLAG_EAST : 0) | + ($this->southwestSlot ? BlockLegacyMetadata::BREWING_STAND_FLAG_SOUTHWEST : 0) | + ($this->northwestSlot ? BlockLegacyMetadata::BREWING_STAND_FLAG_NORTHWEST : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->eastSlot = ($stateMeta & 0x01) !== 0; - $this->southwestSlot = ($stateMeta & 0x02) !== 0; - $this->northwestSlot = ($stateMeta & 0x04) !== 0; + $this->eastSlot = ($stateMeta & BlockLegacyMetadata::BREWING_STAND_FLAG_EAST) !== 0; + $this->southwestSlot = ($stateMeta & BlockLegacyMetadata::BREWING_STAND_FLAG_SOUTHWEST) !== 0; + $this->northwestSlot = ($stateMeta & BlockLegacyMetadata::BREWING_STAND_FLAG_NORTHWEST) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Button.php b/src/pocketmine/block/Button.php index 87247a9600..85815b7846 100644 --- a/src/pocketmine/block/Button.php +++ b/src/pocketmine/block/Button.php @@ -39,13 +39,13 @@ abstract class Button extends Flowable{ protected $powered = false; protected function writeStateToMeta() : int{ - return $this->facing | ($this->powered ? 0x08 : 0); + return $this->facing | ($this->powered ? BlockLegacyMetadata::BUTTON_FLAG_POWERED : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ //TODO: in PC it's (6 - facing) for every meta except 0 (down) $this->facing = BlockDataValidator::readFacing($stateMeta & 0x07); - $this->powered = ($stateMeta & 0x08) !== 0; + $this->powered = ($stateMeta & BlockLegacyMetadata::BUTTON_FLAG_POWERED) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Dirt.php b/src/pocketmine/block/Dirt.php index 2280a27124..9f502e1c12 100644 --- a/src/pocketmine/block/Dirt.php +++ b/src/pocketmine/block/Dirt.php @@ -30,8 +30,6 @@ use pocketmine\math\Vector3; use pocketmine\Player; class Dirt extends Solid{ - public const NORMAL = 0; - public const COARSE = 1; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_SHOVEL)); diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 4654b787d0..a5d0f480fd 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -50,20 +50,22 @@ abstract class Door extends Transparent{ protected function writeStateToMeta() : int{ if($this->top){ - return 0x08 | ($this->hingeRight ? 0x01 : 0) | ($this->powered ? 0x02 : 0); + return BlockLegacyMetadata::DOOR_FLAG_TOP | + ($this->hingeRight ? BlockLegacyMetadata::DOOR_TOP_FLAG_RIGHT : 0) | + ($this->powered ? BlockLegacyMetadata::DOOR_TOP_FLAG_POWERED : 0); } - return Bearing::fromFacing(Facing::rotateY($this->facing, true)) | ($this->open ? 0x04 : 0); + return Bearing::fromFacing(Facing::rotateY($this->facing, true)) | ($this->open ? BlockLegacyMetadata::DOOR_BOTTOM_FLAG_OPEN : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->top = $stateMeta & 0x08; + $this->top = $stateMeta & BlockLegacyMetadata::DOOR_FLAG_TOP; if($this->top){ - $this->hingeRight = ($stateMeta & 0x01) !== 0; - $this->powered = ($stateMeta & 0x02) !== 0; + $this->hingeRight = ($stateMeta & BlockLegacyMetadata::DOOR_TOP_FLAG_RIGHT) !== 0; + $this->powered = ($stateMeta & BlockLegacyMetadata::DOOR_TOP_FLAG_POWERED) !== 0; }else{ $this->facing = Facing::rotateY(BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03), false); - $this->open = ($stateMeta & 0x04) !== 0; + $this->open = ($stateMeta & BlockLegacyMetadata::DOOR_BOTTOM_FLAG_OPEN) !== 0; } } diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index 8b2562a94b..56162989de 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -30,7 +30,6 @@ use pocketmine\Player; use pocketmine\world\BlockTransaction; class DoublePlant extends Flowable{ - private const BITFLAG_TOP = 0x08; /** @var bool */ protected $top = false; @@ -40,11 +39,11 @@ class DoublePlant extends Flowable{ } protected function writeStateToMeta() : int{ - return ($this->top ? self::BITFLAG_TOP : 0); + return ($this->top ? BlockLegacyMetadata::DOUBLE_PLANT_FLAG_TOP : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->top = ($stateMeta & self::BITFLAG_TOP) !== 0; + $this->top = ($stateMeta & BlockLegacyMetadata::DOUBLE_PLANT_FLAG_TOP) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/EndPortalFrame.php b/src/pocketmine/block/EndPortalFrame.php index dd4561d489..cf06d374f7 100644 --- a/src/pocketmine/block/EndPortalFrame.php +++ b/src/pocketmine/block/EndPortalFrame.php @@ -43,12 +43,12 @@ class EndPortalFrame extends Solid{ } protected function writeStateToMeta() : int{ - return Bearing::fromFacing($this->facing) | ($this->eye ? 0x04 : 0); + return Bearing::fromFacing($this->facing) | ($this->eye ? BlockLegacyMetadata::END_PORTAL_FRAME_FLAG_EYE : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); - $this->eye = ($stateMeta & 0x04) !== 0; + $this->eye = ($stateMeta & BlockLegacyMetadata::END_PORTAL_FRAME_FLAG_EYE) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index db9d5c8159..db51a6fd23 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -45,13 +45,15 @@ class FenceGate extends Transparent{ } protected function writeStateToMeta() : int{ - return Bearing::fromFacing($this->facing) | ($this->open ? 0x04 : 0) | ($this->inWall ? 0x08 : 0); + return Bearing::fromFacing($this->facing) | + ($this->open ? BlockLegacyMetadata::FENCE_GATE_FLAG_OPEN : 0) | + ($this->inWall ? BlockLegacyMetadata::FENCE_GATE_FLAG_IN_WALL : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); - $this->open = ($stateMeta & 0x04) !== 0; - $this->inWall = ($stateMeta & 0x08) !== 0; + $this->open = ($stateMeta & BlockLegacyMetadata::FENCE_GATE_FLAG_OPEN) !== 0; + $this->inWall = ($stateMeta & BlockLegacyMetadata::FENCE_GATE_FLAG_IN_WALL) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Flower.php b/src/pocketmine/block/Flower.php index af4ff97ffd..b2487390bd 100644 --- a/src/pocketmine/block/Flower.php +++ b/src/pocketmine/block/Flower.php @@ -29,17 +29,6 @@ use pocketmine\math\Vector3; use pocketmine\Player; class Flower extends Flowable{ - public const TYPE_POPPY = 0; - public const TYPE_BLUE_ORCHID = 1; - public const TYPE_ALLIUM = 2; - public const TYPE_AZURE_BLUET = 3; - public const TYPE_RED_TULIP = 4; - public const TYPE_ORANGE_TULIP = 5; - public const TYPE_WHITE_TULIP = 6; - public const TYPE_PINK_TULIP = 7; - public const TYPE_OXEYE_DAISY = 8; - public const TYPE_CORNFLOWER = 9; - public const TYPE_LILY_OF_THE_VALLEY = 10; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 50b44214af..087bbf1a9f 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -47,11 +47,11 @@ class FlowerPot extends Flowable{ } protected function writeStateToMeta() : int{ - return $this->occupied ? 1 : 0; + return $this->occupied ? BlockLegacyMetadata::FLOWER_POT_FLAG_OCCUPIED : 0; } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->occupied = $stateMeta !== 0; + $this->occupied = ($stateMeta & BlockLegacyMetadata::FLOWER_POT_FLAG_OCCUPIED) !== 0; } public function getStateBitmask() : int{ @@ -106,7 +106,7 @@ class FlowerPot extends Flowable{ $block instanceof Flower or $block instanceof RedMushroom or $block instanceof Sapling or - ($block instanceof TallGrass and $block->getIdInfo()->getVariant() === 2); //fern - TODO: clean up + ($block instanceof TallGrass and $block->getIdInfo()->getVariant() === BlockLegacyMetadata::TALLGRASS_FERN); //TODO: clean up //TODO: bamboo } diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index a579c8785d..275d8dca21 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -50,12 +50,12 @@ class ItemFrame extends Flowable{ } protected function writeStateToMeta() : int{ - return (5 - $this->facing) | ($this->hasMap ? 0x04 : 0); + return (5 - $this->facing) | ($this->hasMap ? BlockLegacyMetadata::ITEM_FRAME_FLAG_HAS_MAP : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ $this->facing = BlockDataValidator::readHorizontalFacing(5 - ($stateMeta & 0x03)); - $this->hasMap = ($stateMeta & 0x04) !== 0; + $this->hasMap = ($stateMeta & BlockLegacyMetadata::ITEM_FRAME_FLAG_HAS_MAP) !== 0; } public function readStateFromWorld() : void{ diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index db1024b4bd..67e6ad4390 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -48,12 +48,12 @@ class Leaves extends Transparent{ } protected function writeStateToMeta() : int{ - return ($this->noDecay ? 0x04 : 0) | ($this->checkDecay ? 0x08 : 0); + return ($this->noDecay ? BlockLegacyMetadata::LEAVES_FLAG_NO_DECAY : 0) | ($this->checkDecay ? BlockLegacyMetadata::LEAVES_FLAG_CHECK_DECAY : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->noDecay = ($stateMeta & 0x04) !== 0; - $this->checkDecay = ($stateMeta & 0x08) !== 0; + $this->noDecay = ($stateMeta & BlockLegacyMetadata::LEAVES_FLAG_NO_DECAY) !== 0; + $this->checkDecay = ($stateMeta & BlockLegacyMetadata::LEAVES_FLAG_CHECK_DECAY) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index 7eaeb01bd1..e2eefe1fb4 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -55,7 +55,7 @@ class Lever extends Flowable{ }else{ $rotationMeta = 6 - $this->facing; } - return $rotationMeta | ($this->powered ? 0x08 : 0); + return $rotationMeta | ($this->powered ? BlockLegacyMetadata::LEVER_FLAG_POWERED : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ @@ -71,7 +71,7 @@ class Lever extends Flowable{ $this->facing = BlockDataValidator::readHorizontalFacing(6 - $rotationMeta); } - $this->powered = ($stateMeta & 0x08) !== 0; + $this->powered = ($stateMeta & BlockLegacyMetadata::LEVER_FLAG_POWERED) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index 532a2aeb5a..c631dcaf71 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -69,12 +69,12 @@ abstract class Liquid extends Transparent{ } protected function writeStateToMeta() : int{ - return $this->decay | ($this->falling ? 0x08 : 0); + return $this->decay | ($this->falling ? BlockLegacyMetadata::LIQUID_FLAG_FALLING : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ $this->decay = BlockDataValidator::readBoundedInt("decay", $stateMeta & 0x07, 0, 7); - $this->falling = ($stateMeta & 0x08) !== 0; + $this->falling = ($stateMeta & BlockLegacyMetadata::LIQUID_FLAG_FALLING) !== 0; $this->still = $id === $this->idInfo->getSecondId(); } diff --git a/src/pocketmine/block/NetherPortal.php b/src/pocketmine/block/NetherPortal.php index 63c17dbe67..acaca0ec3c 100644 --- a/src/pocketmine/block/NetherPortal.php +++ b/src/pocketmine/block/NetherPortal.php @@ -37,11 +37,11 @@ class NetherPortal extends Transparent{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->axis = $stateMeta === 2 ? Facing::AXIS_Z : Facing::AXIS_X; //mojang u dumb + $this->axis = $stateMeta === BlockLegacyMetadata::NETHER_PORTAL_AXIS_Z ? Facing::AXIS_Z : Facing::AXIS_X; //mojang u dumb } protected function writeStateToMeta() : int{ - return $this->axis === Facing::AXIS_Z ? 2 : 1; + return $this->axis === Facing::AXIS_Z ? BlockLegacyMetadata::NETHER_PORTAL_AXIS_Z : BlockLegacyMetadata::NETHER_PORTAL_AXIS_X; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/NetherReactor.php b/src/pocketmine/block/NetherReactor.php index c90289f30b..f144f1c28c 100644 --- a/src/pocketmine/block/NetherReactor.php +++ b/src/pocketmine/block/NetherReactor.php @@ -29,12 +29,9 @@ use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; class NetherReactor extends Solid{ - protected const STATE_INACTIVE = 0; - protected const STATE_ACTIVE = 1; - protected const STATE_USED = 2; /** @var int */ - protected $state = self::STATE_INACTIVE; + protected $state = BlockLegacyMetadata::NETHER_REACTOR_INACTIVE; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); diff --git a/src/pocketmine/block/Prismarine.php b/src/pocketmine/block/Prismarine.php index 514af27c63..e4b85871e9 100644 --- a/src/pocketmine/block/Prismarine.php +++ b/src/pocketmine/block/Prismarine.php @@ -27,10 +27,6 @@ use pocketmine\item\TieredTool; class Prismarine extends Solid{ - public const NORMAL = 0; - public const DARK = 1; - public const BRICKS = 2; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } diff --git a/src/pocketmine/block/Quartz.php b/src/pocketmine/block/Quartz.php index 7efdfa64f4..0569f40d60 100644 --- a/src/pocketmine/block/Quartz.php +++ b/src/pocketmine/block/Quartz.php @@ -27,11 +27,6 @@ use pocketmine\item\TieredTool; class Quartz extends Solid{ - public const NORMAL = 0; - public const CHISELED = 1; - public const PILLAR = 2; - public const SMOOTH = 3; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.8, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); } diff --git a/src/pocketmine/block/Rail.php b/src/pocketmine/block/Rail.php index 93b9a0f9f6..5e6bb6a4df 100644 --- a/src/pocketmine/block/Rail.php +++ b/src/pocketmine/block/Rail.php @@ -28,25 +28,21 @@ use pocketmine\math\Facing; class Rail extends BaseRail{ /* extended meta values for regular rails, to allow curving */ - public const CURVE_SOUTHEAST = 6; - public const CURVE_SOUTHWEST = 7; - public const CURVE_NORTHWEST = 8; - public const CURVE_NORTHEAST = 9; private const CURVE_CONNECTIONS = [ - self::CURVE_SOUTHEAST => [ + BlockLegacyMetadata::RAIL_CURVE_SOUTHEAST => [ Facing::SOUTH, Facing::EAST ], - self::CURVE_SOUTHWEST => [ + BlockLegacyMetadata::RAIL_CURVE_SOUTHWEST => [ Facing::SOUTH, Facing::WEST ], - self::CURVE_NORTHWEST => [ + BlockLegacyMetadata::RAIL_CURVE_NORTHWEST => [ Facing::NORTH, Facing::WEST ], - self::CURVE_NORTHEAST => [ + BlockLegacyMetadata::RAIL_CURVE_NORTHEAST => [ Facing::NORTH, Facing::EAST ] diff --git a/src/pocketmine/block/RedstoneComparator.php b/src/pocketmine/block/RedstoneComparator.php index 2ec142ea05..61f0b3c0dd 100644 --- a/src/pocketmine/block/RedstoneComparator.php +++ b/src/pocketmine/block/RedstoneComparator.php @@ -56,12 +56,14 @@ class RedstoneComparator extends Flowable{ public function readStateFromData(int $id, int $stateMeta) : void{ $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); - $this->isSubtractMode = ($stateMeta & 0x04) !== 0; - $this->powered = ($id === $this->idInfo->getSecondId() or ($stateMeta & 0x08) !== 0); + $this->isSubtractMode = ($stateMeta & BlockLegacyMetadata::REDSTONE_COMPARATOR_FLAG_SUBTRACT) !== 0; + $this->powered = ($id === $this->idInfo->getSecondId() or ($stateMeta & BlockLegacyMetadata::REDSTONE_COMPARATOR_FLAG_POWERED) !== 0); } public function writeStateToMeta() : int{ - return Bearing::fromFacing($this->facing) | ($this->isSubtractMode ? 0x04 : 0) | ($this->powered ? 0x08 : 0); + return Bearing::fromFacing($this->facing) | + ($this->isSubtractMode ? BlockLegacyMetadata::REDSTONE_COMPARATOR_FLAG_SUBTRACT : 0) | + ($this->powered ? BlockLegacyMetadata::REDSTONE_COMPARATOR_FLAG_POWERED : 0); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/RedstoneRail.php b/src/pocketmine/block/RedstoneRail.php index 3678a5f9fa..a9c1e5315b 100644 --- a/src/pocketmine/block/RedstoneRail.php +++ b/src/pocketmine/block/RedstoneRail.php @@ -24,21 +24,20 @@ declare(strict_types=1); namespace pocketmine\block; abstract class RedstoneRail extends BaseRail{ - protected const FLAG_POWERED = 0x08; /** @var bool */ protected $powered = false; protected function writeStateToMeta() : int{ - return parent::writeStateToMeta() | ($this->powered ? self::FLAG_POWERED : 0); + return parent::writeStateToMeta() | ($this->powered ? BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ parent::readStateFromData($id, $stateMeta); - $this->powered = ($stateMeta & self::FLAG_POWERED) !== 0; + $this->powered = ($stateMeta & BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED) !== 0; } protected function getConnectionsFromMeta(int $meta) : ?array{ - return self::CONNECTIONS[$meta & ~self::FLAG_POWERED] ?? null; + return self::CONNECTIONS[$meta & ~BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED] ?? null; } } diff --git a/src/pocketmine/block/Sandstone.php b/src/pocketmine/block/Sandstone.php index bb0de7b991..9d2f8ea44b 100644 --- a/src/pocketmine/block/Sandstone.php +++ b/src/pocketmine/block/Sandstone.php @@ -27,11 +27,6 @@ use pocketmine\item\TieredTool; class Sandstone extends Solid{ - public const NORMAL = 0; - public const CHISELED = 1; - public const CUT = 2; - public const SMOOTH = 3; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.8, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); } diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index a16cadb71b..72930d2abb 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -46,11 +46,11 @@ class Sapling extends Flowable{ } protected function writeStateToMeta() : int{ - return ($this->ready ? 0x08 : 0); + return ($this->ready ? BlockLegacyMetadata::SAPLING_FLAG_READY : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->ready = ($stateMeta & 0x08) !== 0; + $this->ready = ($stateMeta & BlockLegacyMetadata::SAPLING_FLAG_READY) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/SeaPickle.php b/src/pocketmine/block/SeaPickle.php index 5a40ce34e4..dbfbd5a34f 100644 --- a/src/pocketmine/block/SeaPickle.php +++ b/src/pocketmine/block/SeaPickle.php @@ -40,11 +40,11 @@ class SeaPickle extends Transparent{ public function readStateFromData(int $id, int $stateMeta) : void{ $this->count = ($stateMeta & 0x03) + 1; - $this->underwater = ($stateMeta & 0x04) === 0; + $this->underwater = ($stateMeta & BlockLegacyMetadata::SEA_PICKLE_FLAG_NOT_UNDERWATER) === 0; } protected function writeStateToMeta() : int{ - return ($this->count - 1) | ($this->underwater ? 0 : 0x04); + return ($this->count - 1) | ($this->underwater ? 0 : BlockLegacyMetadata::SEA_PICKLE_FLAG_NOT_UNDERWATER); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/SimplePressurePlate.php b/src/pocketmine/block/SimplePressurePlate.php index 7ffb9a7748..7a3cbfaa6a 100644 --- a/src/pocketmine/block/SimplePressurePlate.php +++ b/src/pocketmine/block/SimplePressurePlate.php @@ -29,11 +29,11 @@ abstract class SimplePressurePlate extends PressurePlate{ protected $powered = false; protected function writeStateToMeta() : int{ - return $this->powered ? 1 : 0; + return $this->powered ? BlockLegacyMetadata::PRESSURE_PLATE_FLAG_POWERED : 0; } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->powered = $stateMeta !== 0; + $this->powered = ($stateMeta & BlockLegacyMetadata::PRESSURE_PLATE_FLAG_POWERED) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index 1fee7d4252..57eab21840 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -48,7 +48,7 @@ abstract class Slab extends Transparent{ protected function writeStateToMeta() : int{ if($this->slabType !== SlabType::DOUBLE()){ - return ($this->slabType === SlabType::TOP() ? 0x08 : 0); + return ($this->slabType === SlabType::TOP() ? BlockLegacyMetadata::SLAB_FLAG_UPPER : 0); } return 0; } @@ -57,7 +57,7 @@ abstract class Slab extends Transparent{ if($id === $this->idInfo->getSecondId()){ $this->slabType = SlabType::DOUBLE(); }else{ - $this->slabType = ($stateMeta & 0x08) !== 0 ? SlabType::TOP() : SlabType::BOTTOM(); + $this->slabType = ($stateMeta & BlockLegacyMetadata::SLAB_FLAG_UPPER) !== 0 ? SlabType::TOP() : SlabType::BOTTOM(); } } diff --git a/src/pocketmine/block/Sponge.php b/src/pocketmine/block/Sponge.php index da1e15545a..1b78bac476 100644 --- a/src/pocketmine/block/Sponge.php +++ b/src/pocketmine/block/Sponge.php @@ -34,11 +34,11 @@ class Sponge extends Solid{ } protected function writeStateToMeta() : int{ - return $this->wet ? 1 : 0; + return $this->wet ? BlockLegacyMetadata::SPONGE_FLAG_WET : 0; } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->wet = $stateMeta !== 0; + $this->wet = ($stateMeta & BlockLegacyMetadata::SPONGE_FLAG_WET) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index 392e5efd70..1502d3d19c 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -45,12 +45,12 @@ abstract class Stair extends Transparent{ protected $shape = self::SHAPE_STRAIGHT; protected function writeStateToMeta() : int{ - return (5 - $this->facing) | ($this->upsideDown ? 0x04 : 0); + return (5 - $this->facing) | ($this->upsideDown ? BlockLegacyMetadata::STAIR_FLAG_UPSIDE_DOWN : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ $this->facing = BlockDataValidator::readHorizontalFacing(5 - ($stateMeta & 0x03)); - $this->upsideDown = ($stateMeta & 0x04) !== 0; + $this->upsideDown = ($stateMeta & BlockLegacyMetadata::STAIR_FLAG_UPSIDE_DOWN) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Stone.php b/src/pocketmine/block/Stone.php index e3255a2da9..e549d85010 100644 --- a/src/pocketmine/block/Stone.php +++ b/src/pocketmine/block/Stone.php @@ -26,13 +26,6 @@ namespace pocketmine\block; use pocketmine\item\TieredTool; class Stone extends Solid{ - public const NORMAL = 0; - public const GRANITE = 1; - public const POLISHED_GRANITE = 2; - public const DIORITE = 3; - public const POLISHED_DIORITE = 4; - public const ANDESITE = 5; - public const POLISHED_ANDESITE = 6; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); diff --git a/src/pocketmine/block/StoneBricks.php b/src/pocketmine/block/StoneBricks.php index 5677960c05..0dc110ae96 100644 --- a/src/pocketmine/block/StoneBricks.php +++ b/src/pocketmine/block/StoneBricks.php @@ -26,10 +26,6 @@ namespace pocketmine\block; use pocketmine\item\TieredTool; class StoneBricks extends Solid{ - public const NORMAL = 0; - public const MOSSY = 1; - public const CRACKED = 2; - public const CHISELED = 3; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index 23f5850767..b789b8ae46 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -48,11 +48,11 @@ class TNT extends Solid{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->unstable = $stateMeta !== 0; + $this->unstable = ($stateMeta & BlockLegacyMetadata::TNT_FLAG_UNSTABLE) !== 0; } protected function writeStateToMeta() : int{ - return $this->unstable ? 1 : 0; + return $this->unstable ? BlockLegacyMetadata::TNT_FLAG_UNSTABLE : 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index 0beee587ba..8729578606 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -32,8 +32,6 @@ use pocketmine\Player; use pocketmine\world\sound\DoorSound; abstract class Trapdoor extends Transparent{ - private const MASK_UPPER = 0x04; - private const MASK_OPENED = 0x08; /** @var int */ protected $facing = Facing::NORTH; @@ -43,15 +41,15 @@ abstract class Trapdoor extends Transparent{ protected $top = false; protected function writeStateToMeta() : int{ - return (5 - $this->facing) | ($this->top ? self::MASK_UPPER : 0) | ($this->open ? self::MASK_OPENED : 0); + return (5 - $this->facing) | ($this->top ? BlockLegacyMetadata::TRAPDOOR_FLAG_UPPER : 0) | ($this->open ? BlockLegacyMetadata::TRAPDOOR_FLAG_OPEN : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ //TODO: in PC the values are reversed (facing - 2) $this->facing = BlockDataValidator::readHorizontalFacing(5 - ($stateMeta & 0x03)); - $this->top = ($stateMeta & self::MASK_UPPER) !== 0; - $this->open = ($stateMeta & self::MASK_OPENED) !== 0; + $this->top = ($stateMeta & BlockLegacyMetadata::TRAPDOOR_FLAG_UPPER) !== 0; + $this->open = ($stateMeta & BlockLegacyMetadata::TRAPDOOR_FLAG_OPEN) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Tripwire.php b/src/pocketmine/block/Tripwire.php index d1a4732c47..f0d9f20947 100644 --- a/src/pocketmine/block/Tripwire.php +++ b/src/pocketmine/block/Tripwire.php @@ -39,14 +39,17 @@ class Tripwire extends Flowable{ } protected function writeStateToMeta() : int{ - return ($this->triggered ? 0x01 : 0) | ($this->suspended ? 0x02 : 0) | ($this->connected ? 0x04 : 0) | ($this->disarmed ? 0x08 : 0); + return ($this->triggered ? BlockLegacyMetadata::TRIPWIRE_FLAG_TRIGGERED : 0) | + ($this->suspended ? BlockLegacyMetadata::TRIPWIRE_FLAG_SUSPENDED : 0) | + ($this->connected ? BlockLegacyMetadata::TRIPWIRE_FLAG_CONNECTED : 0) | + ($this->disarmed ? BlockLegacyMetadata::TRIPWIRE_FLAG_DISARMED : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->triggered = ($stateMeta & 0x01) !== 0; - $this->suspended = ($stateMeta & 0x02) !== 0; - $this->connected = ($stateMeta & 0x04) !== 0; - $this->disarmed = ($stateMeta & 0x08) !== 0; + $this->triggered = ($stateMeta & BlockLegacyMetadata::TRIPWIRE_FLAG_TRIGGERED) !== 0; + $this->suspended = ($stateMeta & BlockLegacyMetadata::TRIPWIRE_FLAG_SUSPENDED) !== 0; + $this->connected = ($stateMeta & BlockLegacyMetadata::TRIPWIRE_FLAG_CONNECTED) !== 0; + $this->disarmed = ($stateMeta & BlockLegacyMetadata::TRIPWIRE_FLAG_DISARMED) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/TripwireHook.php b/src/pocketmine/block/TripwireHook.php index f54ed36aaf..72ac42f7a6 100644 --- a/src/pocketmine/block/TripwireHook.php +++ b/src/pocketmine/block/TripwireHook.php @@ -44,13 +44,15 @@ class TripwireHook extends Flowable{ } protected function writeStateToMeta() : int{ - return Bearing::fromFacing($this->facing) | ($this->connected ? 0x04 : 0) | ($this->powered ? 0x08 : 0); + return Bearing::fromFacing($this->facing) | + ($this->connected ? BlockLegacyMetadata::TRIPWIRE_HOOK_FLAG_CONNECTED : 0) | + ($this->powered ? BlockLegacyMetadata::TRIPWIRE_HOOK_FLAG_POWERED : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); - $this->connected = ($stateMeta & 0x04) !== 0; - $this->powered = ($stateMeta & 0x08) !== 0; + $this->connected = ($stateMeta & BlockLegacyMetadata::TRIPWIRE_HOOK_FLAG_CONNECTED) !== 0; + $this->powered = ($stateMeta & BlockLegacyMetadata::TRIPWIRE_HOOK_FLAG_POWERED) !== 0; } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index 2b437991f9..3ef3e29373 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -34,10 +34,6 @@ use function array_keys; use function count; class Vine extends Flowable{ - private const FLAG_SOUTH = 0x01; - private const FLAG_WEST = 0x02; - private const FLAG_NORTH = 0x04; - private const FLAG_EAST = 0x08; /** @var bool[] */ protected $faces = []; @@ -48,17 +44,17 @@ class Vine extends Flowable{ protected function writeStateToMeta() : int{ return - (isset($this->faces[Facing::SOUTH]) ? self::FLAG_SOUTH : 0) | - (isset($this->faces[Facing::WEST]) ? self::FLAG_WEST : 0) | - (isset($this->faces[Facing::NORTH]) ? self::FLAG_NORTH : 0) | - (isset($this->faces[Facing::EAST]) ? self::FLAG_EAST : 0); + (isset($this->faces[Facing::SOUTH]) ? BlockLegacyMetadata::VINE_FLAG_SOUTH : 0) | + (isset($this->faces[Facing::WEST]) ? BlockLegacyMetadata::VINE_FLAG_WEST : 0) | + (isset($this->faces[Facing::NORTH]) ? BlockLegacyMetadata::VINE_FLAG_NORTH : 0) | + (isset($this->faces[Facing::EAST]) ? BlockLegacyMetadata::VINE_FLAG_EAST : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->setFaceFromMeta($stateMeta, self::FLAG_SOUTH, Facing::SOUTH); - $this->setFaceFromMeta($stateMeta, self::FLAG_WEST, Facing::WEST); - $this->setFaceFromMeta($stateMeta, self::FLAG_NORTH, Facing::NORTH); - $this->setFaceFromMeta($stateMeta, self::FLAG_EAST, Facing::EAST); + $this->setFaceFromMeta($stateMeta, BlockLegacyMetadata::VINE_FLAG_SOUTH, Facing::SOUTH); + $this->setFaceFromMeta($stateMeta, BlockLegacyMetadata::VINE_FLAG_WEST, Facing::WEST); + $this->setFaceFromMeta($stateMeta, BlockLegacyMetadata::VINE_FLAG_NORTH, Facing::NORTH); + $this->setFaceFromMeta($stateMeta, BlockLegacyMetadata::VINE_FLAG_EAST, Facing::EAST); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Wall.php b/src/pocketmine/block/Wall.php index 785140bdcd..dd9ffdc656 100644 --- a/src/pocketmine/block/Wall.php +++ b/src/pocketmine/block/Wall.php @@ -28,20 +28,6 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; class Wall extends Transparent{ - public const NONE_MOSSY_WALL = 0; - public const MOSSY_WALL = 1; - public const GRANITE_WALL = 2; - public const DIORITE_WALL = 3; - public const ANDESITE_WALL = 4; - public const SANDSTONE_WALL = 5; - public const BRICK_WALL = 6; - public const STONE_BRICK_WALL = 7; - public const MOSSY_STONE_BRICK_WALL = 8; - public const NETHER_BRICK_WALL = 9; - public const END_STONE_BRICK_WALL = 10; - public const PRISMARINE_WALL = 11; - public const RED_SANDSTONE_WALL = 12; - public const RED_NETHER_BRICK_WALL = 13; /** @var bool[] facing => dummy */ protected $connections = []; diff --git a/tests/phpunit/level/format/io/SubChunkConverter.php b/tests/phpunit/level/format/io/SubChunkConverter.php deleted file mode 100644 index a5f6d4dfa5..0000000000 --- a/tests/phpunit/level/format/io/SubChunkConverter.php +++ /dev/null @@ -1,38 +0,0 @@ - Date: Thu, 16 May 2019 18:02:03 +0100 Subject: [PATCH 0814/3224] PillarRotationTrait: Allow axis shift to be defined by the includer --- src/pocketmine/block/utils/PillarRotationTrait.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/block/utils/PillarRotationTrait.php b/src/pocketmine/block/utils/PillarRotationTrait.php index 7113ae764e..8bec7c9645 100644 --- a/src/pocketmine/block/utils/PillarRotationTrait.php +++ b/src/pocketmine/block/utils/PillarRotationTrait.php @@ -34,6 +34,10 @@ trait PillarRotationTrait{ /** @var int */ protected $axis = Facing::AXIS_Y; + protected function getAxisMetaShift() : int{ + return 2; //default + } + /** * @see Block::writeStateToMeta() * @return int @@ -57,7 +61,7 @@ trait PillarRotationTrait{ * @return int */ public function getStateBitmask() : int{ - return 0b1100; + return 0b11 << $this->getAxisMetaShift(); } protected function readAxisFromMeta(int $meta) : void{ @@ -66,7 +70,7 @@ trait PillarRotationTrait{ 1 => Facing::AXIS_X, 2 => Facing::AXIS_Z ]; - $axis = $meta >> 2; + $axis = $meta >> $this->getAxisMetaShift(); if(!isset($map[$axis])){ throw new InvalidBlockStateException("Invalid axis meta $axis"); } @@ -79,7 +83,7 @@ trait PillarRotationTrait{ Facing::AXIS_Z => 2, Facing::AXIS_X => 1 ]; - return $bits[$this->axis] << 2; + return $bits[$this->axis] << $this->getAxisMetaShift(); } /** From 0f398bbe66233517ba88a8397616644b13b774cf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 17 May 2019 17:15:45 +0100 Subject: [PATCH 0815/3224] LevelDB: Added conversion of legacy extradata -> 4D subchunk block layers --- .../world/format/io/leveldb/LevelDB.php | 94 ++++++++++++++----- 1 file changed, 73 insertions(+), 21 deletions(-) diff --git a/src/pocketmine/world/format/io/leveldb/LevelDB.php b/src/pocketmine/world/format/io/leveldb/LevelDB.php index a7291751e7..0eae5a8c56 100644 --- a/src/pocketmine/world/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/world/format/io/leveldb/LevelDB.php @@ -183,6 +183,47 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ return PalettedBlockArray::fromData($bitsPerBlock, $words, $palette); } + protected static function deserializeExtraDataKey(int $chunkVersion, int $key, ?int &$x, ?int &$y, ?int &$z) : void{ + if($chunkVersion >= 3){ + $x = ($key >> 12) & 0xf; + $z = ($key >> 8) & 0xf; + $y = $key & 0xff; + }else{ //pre-1.0, 7 bits were used because the build height limit was lower + $x = ($key >> 11) & 0xf; + $z = ($key >> 7) & 0xf; + $y = $key & 0x7f; + } + } + + protected function deserializeLegacyExtraData(string $index, int $chunkVersion) : array{ + if(($extraRawData = $this->db->get($index . self::TAG_BLOCK_EXTRA_DATA)) === false or $extraRawData === ""){ + return []; + } + + /** @var PalettedBlockArray[] $extraDataLayers */ + $extraDataLayers = []; + $binaryStream = new BinaryStream($extraRawData); + $count = $binaryStream->getLInt(); + for($i = 0; $i < $count; ++$i){ + $key = $binaryStream->getLInt(); + $value = $binaryStream->getLShort(); + + self::deserializeExtraDataKey($chunkVersion, $key, $x, $fullY, $z); + + $ySub = ($fullY >> 4) & 0xf; + $y = $key & 0xf; + + $blockId = $value & 0xff; + $blockData = ($value >> 8) & 0xf; + if(!isset($extraDataLayers[$ySub])){ + $extraDataLayers[$ySub] = new PalettedBlockArray(BlockLegacyIds::AIR << 4); + } + $extraDataLayers[$ySub]->set($x, $y, $z, ($blockId << 4) | $blockData); + } + + return $extraDataLayers; + } + /** * @param int $chunkX * @param int $chunkZ @@ -216,6 +257,9 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ case 4: //MCPE 1.1 //TODO: check beds case 3: //MCPE 1.0 + /** @var PalettedBlockArray[] $convertedLegacyExtraData */ + $convertedLegacyExtraData = $this->deserializeLegacyExtraData($index, $chunkVersion); + for($y = 0; $y < Chunk::MAX_SUBCHUNKS; ++$y){ if(($data = $this->db->get($index . self::TAG_SUBCHUNK_PREFIX . chr($y))) === false){ continue; @@ -250,18 +294,32 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ throw new CorruptedChunkException($e->getMessage(), 0, $e); } - $subChunks[$y] = new SubChunk([SubChunkConverter::convertSubChunkXZY($blocks, $blockData)]); + $storages = [SubChunkConverter::convertSubChunkXZY($blocks, $blockData)]; + if(isset($convertedLegacyExtraData[$y])){ + $storages[] = $convertedLegacyExtraData[$y]; + } + + $subChunks[$y] = new SubChunk($storages); break; case 1: //paletted v1, has a single blockstorage - $subChunks[$y] = new SubChunk([$this->deserializePaletted($binaryStream)]); - break; - case 8: - $storages = []; - for($k = 0, $storageCount = $binaryStream->getByte(); $k < $storageCount; ++$k){ - $storages[] = $this->deserializePaletted($binaryStream); + $storages = [$this->deserializePaletted($binaryStream)]; + if(isset($convertedLegacyExtraData[$y])){ + $storages[] = $convertedLegacyExtraData[$y]; } $subChunks[$y] = new SubChunk($storages); break; + case 8: + //legacy extradata layers intentionally ignored because they aren't supposed to exist in v8 + $storageCount = $binaryStream->getByte(); + if($storageCount > 0){ + $storages = []; + + for($k = 0; $k < $storageCount; ++$k){ + $storages[] = $this->deserializePaletted($binaryStream); + } + $subChunks[$y] = new SubChunk($storages); + } + break; default: //TODO: set chunks read-only so the version on disk doesn't get overwritten throw new UnsupportedChunkFormatException("don't know how to decode LevelDB subchunk format version $subChunkVersion"); @@ -280,6 +338,9 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ } break; case 2: // < MCPE 1.0 + /** @var PalettedBlockArray[] $extraDataLayers */ + $convertedLegacyExtraData = $this->deserializeLegacyExtraData($index, $chunkVersion); + $legacyTerrain = $this->db->get($index . self::TAG_LEGACY_TERRAIN); if($legacyTerrain === false){ throw new CorruptedChunkException("Missing expected LEGACY_TERRAIN tag for format version $chunkVersion"); @@ -294,7 +355,11 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ } for($yy = 0; $yy < 8; ++$yy){ - $subChunks[$yy] = new SubChunk([SubChunkConverter::convertSubChunkFromLegacyColumn($fullIds, $fullData, $yy)]); + $storages = [SubChunkConverter::convertSubChunkFromLegacyColumn($fullIds, $fullData, $yy)]; + if(isset($convertedLegacyExtraData[$yy])){ + $storages[] = $convertedLegacyExtraData[$yy]; + } + $subChunks[$yy] = new SubChunk($storages); } try{ @@ -331,19 +396,6 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ } } - //TODO: extra data should be converted into blockstorage layers (first they need to be implemented!) - /* - $extraData = []; - if(($extraRawData = $this->db->get($index . self::TAG_BLOCK_EXTRA_DATA)) !== false and $extraRawData !== ""){ - $binaryStream->setBuffer($extraRawData, 0); - $count = $binaryStream->getLInt(); - for($i = 0; $i < $count; ++$i){ - $key = $binaryStream->getLInt(); - $value = $binaryStream->getLShort(); - $extraData[$key] = $value; - } - }*/ - $chunk = new Chunk( $chunkX, $chunkZ, From 6de0b48c1ff873d8ddfc46c9a4cd7f176b7d1f68 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 17 May 2019 18:04:51 +0100 Subject: [PATCH 0816/3224] PacketBatch: Always encode packets freshly, never reuse buffers this causes bugs when a packet is modified during events and then re-sent to a player. Since we can't control this, we can't allow this kind of buffer reuse. The only notable case where this will cause loss of performance is when broadcasting a series of packet(s) which accumulate to less than 256 bytes, which is reasonably cheap to encode anyway. In addition, removing this caching is one roadblock to moving this serialization to native code, which will make it vastly faster. --- src/pocketmine/network/mcpe/PacketBatch.php | 4 +--- src/pocketmine/network/mcpe/protocol/DataPacket.php | 8 -------- src/pocketmine/network/mcpe/protocol/Packet.php | 2 -- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/pocketmine/network/mcpe/PacketBatch.php b/src/pocketmine/network/mcpe/PacketBatch.php index 4f710c84d4..2e3d8e046e 100644 --- a/src/pocketmine/network/mcpe/PacketBatch.php +++ b/src/pocketmine/network/mcpe/PacketBatch.php @@ -30,9 +30,7 @@ use pocketmine\utils\BinaryDataException; class PacketBatch extends NetworkBinaryStream{ public function putPacket(Packet $packet) : void{ - if(!$packet->isEncoded()){ - $packet->encode(); - } + $packet->encode(); $this->putString($packet->getBuffer()); } diff --git a/src/pocketmine/network/mcpe/protocol/DataPacket.php b/src/pocketmine/network/mcpe/protocol/DataPacket.php index ffea84b634..e6563630f8 100644 --- a/src/pocketmine/network/mcpe/protocol/DataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/DataPacket.php @@ -39,9 +39,6 @@ abstract class DataPacket extends NetworkBinaryStream implements Packet{ public const NETWORK_ID = 0; - /** @var bool */ - private $isEncoded = false; - /** @var int */ public $senderSubId = 0; /** @var int */ @@ -104,11 +101,6 @@ abstract class DataPacket extends NetworkBinaryStream implements Packet{ $this->reset(); $this->encodeHeader(); $this->encodePayload(); - $this->isEncoded = true; - } - - final public function isEncoded() : bool{ - return $this->isEncoded; } protected function encodeHeader() : void{ diff --git a/src/pocketmine/network/mcpe/protocol/Packet.php b/src/pocketmine/network/mcpe/protocol/Packet.php index 959103fbca..5ca1ba074d 100644 --- a/src/pocketmine/network/mcpe/protocol/Packet.php +++ b/src/pocketmine/network/mcpe/protocol/Packet.php @@ -61,8 +61,6 @@ interface Packet{ public function encode() : void; - public function isEncoded() : bool; - /** * Performs handling for this packet. Usually you'll want an appropriately named method in the session handler for * this. From cd8645ff20c5b2676ee6f5d1d2c68fb9efca48e8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 May 2019 15:15:20 +0100 Subject: [PATCH 0817/3224] Removed PalettedBlockArray stub the SubChunkConverter stub was accidentally removed in dd914e07523c7038c868c9969d88fdd97b00b7cf, but no great harm done ... --- .../world/format/PalettedBlockArray.php | 54 ------------------- 1 file changed, 54 deletions(-) delete mode 100644 src/pocketmine/world/format/PalettedBlockArray.php diff --git a/src/pocketmine/world/format/PalettedBlockArray.php b/src/pocketmine/world/format/PalettedBlockArray.php deleted file mode 100644 index 622f1150be..0000000000 --- a/src/pocketmine/world/format/PalettedBlockArray.php +++ /dev/null @@ -1,54 +0,0 @@ - Date: Sat, 18 May 2019 17:19:44 +0100 Subject: [PATCH 0818/3224] CraftingDataPacket: Fixed uncaught exception in decode this is not exploitable because it's not a serverbound packet, but it should be fixed nonetheless. --- src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php b/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php index f33982ed9e..cfbcf8ddb4 100644 --- a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php @@ -110,7 +110,11 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{ $inputData = -1; } } - $entry["input"] = ItemFactory::get($inputId, $inputData); + try{ + $entry["input"] = ItemFactory::get($inputId, $inputData); + }catch(\InvalidArgumentException $e){ + throw new BadPacketException($e->getMessage(), 0, $e); + } $entry["output"] = $this->getSlot(); $entry["block"] = $this->getString(); From d44ec702b07ea33229fbad1c7e9de8a3c394b30b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 May 2019 17:42:03 +0100 Subject: [PATCH 0819/3224] Added BlockDataValidator::read5MinusHorizontalFacing() --- src/pocketmine/block/ItemFrame.php | 2 +- src/pocketmine/block/Stair.php | 2 +- src/pocketmine/block/Trapdoor.php | 2 +- src/pocketmine/block/utils/BlockDataValidator.php | 10 ++++++++++ 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 275d8dca21..63291e357a 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -54,7 +54,7 @@ class ItemFrame extends Flowable{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::readHorizontalFacing(5 - ($stateMeta & 0x03)); + $this->facing = BlockDataValidator::read5MinusHorizontalFacing($stateMeta); $this->hasMap = ($stateMeta & BlockLegacyMetadata::ITEM_FRAME_FLAG_HAS_MAP) !== 0; } diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index 1502d3d19c..40e2198f0a 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -49,7 +49,7 @@ abstract class Stair extends Transparent{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::readHorizontalFacing(5 - ($stateMeta & 0x03)); + $this->facing = BlockDataValidator::read5MinusHorizontalFacing($stateMeta); $this->upsideDown = ($stateMeta & BlockLegacyMetadata::STAIR_FLAG_UPSIDE_DOWN) !== 0; } diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index 8729578606..efc4e02821 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -47,7 +47,7 @@ abstract class Trapdoor extends Transparent{ public function readStateFromData(int $id, int $stateMeta) : void{ //TODO: in PC the values are reversed (facing - 2) - $this->facing = BlockDataValidator::readHorizontalFacing(5 - ($stateMeta & 0x03)); + $this->facing = BlockDataValidator::read5MinusHorizontalFacing($stateMeta); $this->top = ($stateMeta & BlockLegacyMetadata::TRAPDOOR_FLAG_UPPER) !== 0; $this->open = ($stateMeta & BlockLegacyMetadata::TRAPDOOR_FLAG_OPEN) !== 0; } diff --git a/src/pocketmine/block/utils/BlockDataValidator.php b/src/pocketmine/block/utils/BlockDataValidator.php index 1e92c400e7..476de738bf 100644 --- a/src/pocketmine/block/utils/BlockDataValidator.php +++ b/src/pocketmine/block/utils/BlockDataValidator.php @@ -76,6 +76,16 @@ final class BlockDataValidator{ return self::readHorizontalFacing($facing); } + /** + * @param int $value + * + * @return int + * @throws InvalidBlockStateException + */ + public static function read5MinusHorizontalFacing(int $value) : int{ + return self::readHorizontalFacing(5 - ($value & 0x03)); + } + public static function readBoundedInt(string $name, int $v, int $min, int $max) : int{ if($v < $min or $v > $max){ throw new InvalidBlockStateException("$name should be in range $min - $max, got $v"); From fa9fcea18926ce29e565f3af65c853006af95515 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 May 2019 19:11:23 +0100 Subject: [PATCH 0820/3224] SimpleSessionHandler: Do not read blocks from world in onFailedBlockAction() the world will do this anyway, so we can reduce our code burden here. --- .../network/mcpe/handler/SimpleSessionHandler.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php index 8ff6c6ae38..ea0cf0c9ce 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; -use pocketmine\block\Block; use pocketmine\block\ItemFrame; use pocketmine\block\Sign; use pocketmine\block\utils\SignText; @@ -298,16 +297,14 @@ class SimpleSessionHandler extends SessionHandler{ private function onFailedBlockAction(Vector3 $blockPos, ?int $face) : void{ $this->player->getInventory()->sendHeldItem($this->player); if($blockPos->distanceSquared($this->player) < 10000){ - $target = $this->player->getWorld()->getBlock($blockPos); - - $blocks = $target->getAllSides(); + $blocks = $blockPos->sidesArray(); if($face !== null){ - $sideBlock = $target->getSide($face); + $sidePos = $blockPos->getSide($face); - /** @var Block[] $blocks */ - array_push($blocks, ...$sideBlock->getAllSides()); //getAllSides() on each of these will include $target and $sideBlock because they are next to each other + /** @var Vector3[] $blocks */ + array_push($blocks, ...$sidePos->sidesArray()); //getAllSides() on each of these will include $blockPos and $sidePos because they are next to each other }else{ - $blocks[] = $target; + $blocks[] = $blockPos; } $this->player->getWorld()->sendBlocks([$this->player], $blocks); } From c3c2dd3988d3157354bc280c072777d4d991e8f5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 May 2019 19:13:41 +0100 Subject: [PATCH 0821/3224] Rename SimpleSessionHandler -> InGameSessionHandler the "simple" name comes from the early days of this refactor before I started splitting everything up into their own units. This handler is now in good enough condition to have a proper name. --- src/pocketmine/network/mcpe/NetworkSession.php | 6 +++--- .../{SimpleSessionHandler.php => InGameSessionHandler.php} | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) rename src/pocketmine/network/mcpe/handler/{SimpleSessionHandler.php => InGameSessionHandler.php} (99%) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index ba9e465b06..8f307bb28e 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -34,12 +34,12 @@ use pocketmine\math\Vector3; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\DeathSessionHandler; use pocketmine\network\mcpe\handler\HandshakeSessionHandler; +use pocketmine\network\mcpe\handler\InGameSessionHandler; use pocketmine\network\mcpe\handler\LoginSessionHandler; use pocketmine\network\mcpe\handler\NullSessionHandler; use pocketmine\network\mcpe\handler\PreSpawnSessionHandler; use pocketmine\network\mcpe\handler\ResourcePacksSessionHandler; use pocketmine\network\mcpe\handler\SessionHandler; -use pocketmine\network\mcpe\handler\SimpleSessionHandler; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; @@ -569,7 +569,7 @@ class NetworkSession{ } public function onSpawn() : void{ - $this->setHandler(new SimpleSessionHandler($this->player, $this)); + $this->setHandler(new InGameSessionHandler($this->player, $this)); } public function onDeath() : void{ @@ -577,7 +577,7 @@ class NetworkSession{ } public function onRespawn() : void{ - $this->setHandler(new SimpleSessionHandler($this->player, $this)); + $this->setHandler(new InGameSessionHandler($this->player, $this)); } public function syncMovement(Vector3 $pos, ?float $yaw = null, ?float $pitch = null, int $mode = MovePlayerPacket::MODE_NORMAL) : void{ diff --git a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php b/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php similarity index 99% rename from src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php rename to src/pocketmine/network/mcpe/handler/InGameSessionHandler.php index ea0cf0c9ce..df32be2176 100644 --- a/src/pocketmine/network/mcpe/handler/SimpleSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php @@ -91,10 +91,9 @@ use function preg_split; use function trim; /** - * Temporary session handler implementation - * TODO: split this up properly into different handlers + * This handler handles packets related to general gameplay. */ -class SimpleSessionHandler extends SessionHandler{ +class InGameSessionHandler extends SessionHandler{ /** @var Player */ private $player; From 57219abc9d8c0186338e2e1af92f6bb28b59a1f4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 May 2019 20:20:33 +0100 Subject: [PATCH 0822/3224] fix test failure --- tests/phpunit/network/mcpe/handler/StupidJsonDecodeTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/network/mcpe/handler/StupidJsonDecodeTest.php b/tests/phpunit/network/mcpe/handler/StupidJsonDecodeTest.php index 4082353a97..a18319a892 100644 --- a/tests/phpunit/network/mcpe/handler/StupidJsonDecodeTest.php +++ b/tests/phpunit/network/mcpe/handler/StupidJsonDecodeTest.php @@ -47,7 +47,7 @@ class StupidJsonDecodeTest extends TestCase{ * @throws \ReflectionException */ public function testStupidJsonDecode(string $brokenJson, $expect){ - $func = new \ReflectionMethod(SimpleSessionHandler::class, 'stupid_json_decode'); + $func = new \ReflectionMethod(InGameSessionHandler::class, 'stupid_json_decode'); $func->setAccessible(true); $decoded = $func->invoke(null, $brokenJson, true); From 67affcea32d3218b5168be9ad29ff21831ef7af7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 May 2019 20:00:05 +0100 Subject: [PATCH 0823/3224] move more packet logic to net session it seems like net session is turning into a giant dumping ground for sending API ... this needs to be cleaned up somehow. --- src/pocketmine/inventory/ArmorInventory.php | 15 +++-------- src/pocketmine/inventory/BaseInventory.php | 24 ++---------------- .../network/mcpe/NetworkSession.php | 25 +++++++++++++++++++ 3 files changed, 31 insertions(+), 33 deletions(-) diff --git a/src/pocketmine/inventory/ArmorInventory.php b/src/pocketmine/inventory/ArmorInventory.php index 744ccde8ba..39dff581a3 100644 --- a/src/pocketmine/inventory/ArmorInventory.php +++ b/src/pocketmine/inventory/ArmorInventory.php @@ -25,8 +25,6 @@ namespace pocketmine\inventory; use pocketmine\entity\Living; use pocketmine\item\Item; -use pocketmine\network\mcpe\protocol\InventoryContentPacket; -use pocketmine\network\mcpe\protocol\InventorySlotPacket; use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket; use pocketmine\Player; use function array_merge; @@ -90,14 +88,11 @@ class ArmorInventory extends BaseInventory{ /** @var Player[] $target */ if(($k = array_search($this->holder, $target, true)) !== false){ - $pk = new InventorySlotPacket(); - $pk->windowId = $target[$k]->getWindowId($this); - $pk->inventorySlot = $index; - $pk->item = $this->getItem($index); - $target[$k]->sendDataPacket($pk); + $target[$k]->getNetworkSession()->syncInventorySlot($this, $index); unset($target[$k]); } if(!empty($target)){ + //TODO: this should be handled by change listeners $pk = new MobArmorEquipmentPacket(); $pk->entityRuntimeId = $this->getHolder()->getId(); $pk->slots = $this->getContents(true); @@ -113,13 +108,11 @@ class ArmorInventory extends BaseInventory{ $armor = $this->getContents(true); if(($k = array_search($this->holder, $target, true)) !== false){ - $pk = new InventoryContentPacket(); - $pk->windowId = $target[$k]->getWindowId($this); - $pk->items = $armor; - $target[$k]->sendDataPacket($pk); + $target[$k]->getNetworkSession()->syncInventoryContents($this); unset($target[$k]); } if(!empty($target)){ + //TODO: this should be handled by change listeners $pk = new MobArmorEquipmentPacket(); $pk->entityRuntimeId = $this->getHolder()->getId(); $pk->slots = $armor; diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index 73e0798753..ba2967f29f 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -26,9 +26,6 @@ namespace pocketmine\inventory; use pocketmine\event\inventory\InventoryOpenEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\network\mcpe\protocol\InventoryContentPacket; -use pocketmine\network\mcpe\protocol\InventorySlotPacket; -use pocketmine\network\mcpe\protocol\types\ContainerIds; use pocketmine\Player; use pocketmine\utils\Utils; use function array_slice; @@ -414,16 +411,8 @@ abstract class BaseInventory implements Inventory{ $target = [$target]; } - $pk = new InventoryContentPacket(); - $pk->items = $this->getContents(true); - foreach($target as $player){ - if(($id = $player->getWindowId($this)) === ContainerIds::NONE){ - $this->close($player); - continue; - } - $pk->windowId = $id; - $player->sendDataPacket($pk); + $player->getNetworkSession()->syncInventoryContents($this); } } @@ -436,17 +425,8 @@ abstract class BaseInventory implements Inventory{ $target = [$target]; } - $pk = new InventorySlotPacket(); - $pk->inventorySlot = $index; - $pk->item = $this->getItem($index); - foreach($target as $player){ - if(($id = $player->getWindowId($this)) === ContainerIds::NONE){ - $this->close($player); - continue; - } - $pk->windowId = $id; - $player->sendDataPacket($pk); + $player->getNetworkSession()->syncInventorySlot($this, $index); } } diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 8f307bb28e..3cd7cac2fc 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -30,6 +30,7 @@ use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\event\server\DataPacketSendEvent; use pocketmine\form\Form; use pocketmine\GameMode; +use pocketmine\inventory\Inventory; use pocketmine\math\Vector3; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\DeathSessionHandler; @@ -45,6 +46,8 @@ use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\DisconnectPacket; +use pocketmine\network\mcpe\protocol\InventoryContentPacket; +use pocketmine\network\mcpe\protocol\InventorySlotPacket; use pocketmine\network\mcpe\protocol\MobEffectPacket; use pocketmine\network\mcpe\protocol\ModalFormRequestPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; @@ -60,6 +63,7 @@ use pocketmine\network\mcpe\protocol\TransferPacket; use pocketmine\network\mcpe\protocol\types\CommandData; use pocketmine\network\mcpe\protocol\types\CommandEnum; use pocketmine\network\mcpe\protocol\types\CommandParameter; +use pocketmine\network\mcpe\protocol\types\ContainerIds; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; use pocketmine\network\NetworkInterface; @@ -792,6 +796,27 @@ class NetworkSession{ } + public function syncInventorySlot(Inventory $inventory, int $slot) : void{ + $windowId = $this->player->getWindowId($inventory); + if($windowId !== ContainerIds::NONE){ + $pk = new InventorySlotPacket(); + $pk->inventorySlot = $slot; + $pk->item = $inventory->getItem($slot); + $pk->windowId = $windowId; + $this->sendDataPacket($pk); + } + } + + public function syncInventoryContents(Inventory $inventory) : void{ + $windowId = $this->player->getWindowId($inventory); + if($windowId !== ContainerIds::NONE){ + $pk = new InventoryContentPacket(); + $pk->items = $inventory->getContents(true); + $pk->windowId = $windowId; + $this->sendDataPacket($pk); + } + } + public function tick() : bool{ if($this->handler instanceof LoginSessionHandler){ if(time() >= $this->connectTime + 10){ From dec6c9f49b1af99320564ca504bb842e9ab02443 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 19 May 2019 16:02:03 +0100 Subject: [PATCH 0824/3224] Removed EntityInventoryChangeEvent and EntityArmorChangeEvent there is nothing that these events do that can't be fulfilled by transactions. They complicate the internal implementation and produce unexpected behaviour for plugins when cancelled. TL;DR: Use transactions. That's what they are there for. --- src/pocketmine/entity/Human.php | 12 --- src/pocketmine/entity/Living.php | 11 --- .../event/entity/EntityArmorChangeEvent.php | 28 ------- .../entity/EntityInventoryChangeEvent.php | 81 ------------------- src/pocketmine/inventory/BaseInventory.php | 16 ++-- src/pocketmine/tile/Furnace.php | 3 +- 6 files changed, 7 insertions(+), 144 deletions(-) delete mode 100644 src/pocketmine/event/entity/EntityArmorChangeEvent.php delete mode 100644 src/pocketmine/event/entity/EntityInventoryChangeEvent.php diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 9ef0df5ca0..240d51b04c 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -28,12 +28,10 @@ use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\projectile\ProjectileSource; use pocketmine\entity\utils\ExperienceUtils; use pocketmine\event\entity\EntityDamageEvent; -use pocketmine\event\entity\EntityInventoryChangeEvent; use pocketmine\event\entity\EntityRegainHealthEvent; use pocketmine\event\player\PlayerExhaustEvent; use pocketmine\event\player\PlayerExperienceChangeEvent; use pocketmine\inventory\EnderChestInventory; -use pocketmine\inventory\Inventory; use pocketmine\inventory\InventoryHolder; use pocketmine\inventory\PlayerInventory; use pocketmine\item\Consumable; @@ -648,16 +646,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $this->inventory->setHeldItemIndex($nbt->getInt("SelectedInventorySlot", 0), false); - $this->inventory->setSlotChangeListener(function(Inventory $inventory, int $slot, Item $oldItem, Item $newItem) : ?Item{ - $ev = new EntityInventoryChangeEvent($this, $oldItem, $newItem, $slot); - $ev->call(); - if($ev->isCancelled()){ - return null; - } - - return $ev->getNewItem(); - }); - $this->setFood((float) $nbt->getInt("foodLevel", (int) $this->getFood(), true)); $this->setExhaustion($nbt->getFloat("foodExhaustionLevel", $this->getExhaustion(), true)); $this->setSaturation($nbt->getFloat("foodSaturationLevel", $this->getSaturation(), true)); diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 6605bca068..a1072cab09 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -26,7 +26,6 @@ namespace pocketmine\entity; use pocketmine\block\Block; use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; -use pocketmine\event\entity\EntityArmorChangeEvent; use pocketmine\event\entity\EntityDamageByChildEntityEvent; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; @@ -34,7 +33,6 @@ use pocketmine\event\entity\EntityDeathEvent; use pocketmine\event\entity\EntityEffectAddEvent; use pocketmine\event\entity\EntityEffectRemoveEvent; use pocketmine\inventory\ArmorInventory; -use pocketmine\inventory\Inventory; use pocketmine\item\Armor; use pocketmine\item\Consumable; use pocketmine\item\Durable; @@ -96,15 +94,6 @@ abstract class Living extends Entity implements Damageable{ $this->armorInventory = new ArmorInventory($this); //TODO: load/save armor inventory contents - $this->armorInventory->setSlotChangeListener(function(Inventory $inventory, int $slot, Item $oldItem, Item $newItem) : ?Item{ - $ev = new EntityArmorChangeEvent($this, $oldItem, $newItem, $slot); - $ev->call(); - if($ev->isCancelled()){ - return null; - } - - return $ev->getNewItem(); - }); $health = $this->getMaxHealth(); diff --git a/src/pocketmine/event/entity/EntityArmorChangeEvent.php b/src/pocketmine/event/entity/EntityArmorChangeEvent.php deleted file mode 100644 index 8d53832aa3..0000000000 --- a/src/pocketmine/event/entity/EntityArmorChangeEvent.php +++ /dev/null @@ -1,28 +0,0 @@ -entity = $entity; - $this->oldItem = $oldItem; - $this->newItem = $newItem; - $this->slot = $slot; - } - - /** - * Returns the inventory slot number affected by the event. - * @return int - */ - public function getSlot() : int{ - return $this->slot; - } - - /** - * Returns the item which will be in the slot after the event. - * @return Item - */ - public function getNewItem() : Item{ - return $this->newItem; - } - - /** - * @param Item $item - */ - public function setNewItem(Item $item) : void{ - $this->newItem = $item; - } - - /** - * Returns the item currently in the slot. - * @return Item - */ - public function getOldItem() : Item{ - return $this->oldItem; - } -} diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index ba2967f29f..bb1b52ad0f 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -134,18 +134,14 @@ abstract class BaseInventory implements Inventory{ } $oldItem = $this->getItem($index); - if($this->slotChangeListener !== null){ - $newItem = ($this->slotChangeListener)($this, $index, $oldItem, $item); - if($newItem === null){ - return false; - } - }else{ - $newItem = $item; - } - $this->slots[$index] = $newItem->isNull() ? null : $newItem; + $this->slots[$index] = $item->isNull() ? null : $item; $this->onSlotChange($index, $oldItem, $send); + if($this->slotChangeListener !== null){ + ($this->slotChangeListener)($this, $index); + } + return true; } @@ -440,7 +436,7 @@ abstract class BaseInventory implements Inventory{ public function setSlotChangeListener(?\Closure $eventProcessor) : void{ if($eventProcessor !== null){ - Utils::validateCallableSignature(function(Inventory $inventory, int $slot, Item $oldItem, Item $newItem) : ?Item{}, $eventProcessor); + Utils::validateCallableSignature(function(Inventory $inventory, int $slot) : void{}, $eventProcessor); } $this->slotChangeListener = $eventProcessor; } diff --git a/src/pocketmine/tile/Furnace.php b/src/pocketmine/tile/Furnace.php index ebf281c80d..26ce225abc 100644 --- a/src/pocketmine/tile/Furnace.php +++ b/src/pocketmine/tile/Furnace.php @@ -60,9 +60,8 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ public function __construct(World $world, Vector3 $pos){ $this->inventory = new FurnaceInventory($this); - $this->inventory->setSlotChangeListener(function(Inventory $inventory, int $slot, Item $oldItem, Item $newItem) : ?Item{ + $this->inventory->setSlotChangeListener(function(Inventory $inventory, int $slot) : void{ $this->scheduleUpdate(); - return $newItem; }); parent::__construct($world, $pos); From cd103cefcc3aa94c41f4633a1a6daf68b8d1596b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 19 May 2019 16:36:38 +0100 Subject: [PATCH 0825/3224] Redesign inventory listening API given that inventory listeners are no longer allowed to fiddle with the outcome of changing contents, it's now possible to allow having multiple listeners receiving events. It's likely that this will be used for network inventory sync in the near future. --- src/pocketmine/entity/Human.php | 6 +- src/pocketmine/inventory/BaseInventory.php | 41 ++++++------ .../CallbackInventoryChangeListener.php | 65 +++++++++++++++++++ src/pocketmine/inventory/Inventory.php | 13 ++-- .../inventory/InventoryChangeListener.php | 38 +++++++++++ src/pocketmine/tile/ContainerTrait.php | 6 +- src/pocketmine/tile/Furnace.php | 9 ++- 7 files changed, 145 insertions(+), 33 deletions(-) create mode 100644 src/pocketmine/inventory/CallbackInventoryChangeListener.php create mode 100644 src/pocketmine/inventory/InventoryChangeListener.php diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 240d51b04c..74d099df00 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -618,8 +618,8 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $inventoryTag = $nbt->getListTag("Inventory"); if($inventoryTag !== null){ - $armorListener = $this->armorInventory->getSlotChangeListener(); - $this->armorInventory->setSlotChangeListener(null); + $armorListeners = $this->armorInventory->getChangeListeners(); + $this->armorInventory->removeChangeListeners(...$armorListeners); /** @var CompoundTag $item */ foreach($inventoryTag as $i => $item){ @@ -633,7 +633,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ } } - $this->armorInventory->setSlotChangeListener($armorListener); + $this->armorInventory->addChangeListeners(...$armorListeners); } $enderChestInventoryTag = $nbt->getListTag("EnderChestInventory"); diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index bb1b52ad0f..9be938cbf8 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -27,7 +27,6 @@ use pocketmine\event\inventory\InventoryOpenEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\Player; -use pocketmine\utils\Utils; use function array_slice; use function count; use function max; @@ -42,8 +41,8 @@ abstract class BaseInventory implements Inventory{ protected $slots = []; /** @var Player[] */ protected $viewers = []; - /** @var \Closure */ - protected $slotChangeListener; + /** @var InventoryChangeListener[] */ + protected $listeners = []; /** * @param int $size @@ -121,6 +120,10 @@ abstract class BaseInventory implements Inventory{ } } + foreach($this->listeners as $listener){ + $listener->onContentChange($this); + } + if($send){ $this->sendContents($this->getViewers()); } @@ -138,10 +141,6 @@ abstract class BaseInventory implements Inventory{ $this->slots[$index] = $item->isNull() ? null : $item; $this->onSlotChange($index, $oldItem, $send); - if($this->slotChangeListener !== null){ - ($this->slotChangeListener)($this, $index); - } - return true; } @@ -331,13 +330,7 @@ abstract class BaseInventory implements Inventory{ } public function clearAll(bool $send = true) : void{ - for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ - $this->clear($i, false); - } - - if($send){ - $this->sendContents($this->getViewers()); - } + $this->setContents([], $send); } public function swap(int $slot1, int $slot2) : void{ @@ -394,6 +387,9 @@ abstract class BaseInventory implements Inventory{ } protected function onSlotChange(int $index, Item $before, bool $send) : void{ + foreach($this->listeners as $listener){ + $listener->onSlotChange($this, $index); + } if($send){ $this->sendSlot($index, $this->getViewers()); } @@ -430,14 +426,19 @@ abstract class BaseInventory implements Inventory{ return $slot >= 0 and $slot < $this->slots->getSize(); } - public function getSlotChangeListener() : ?\Closure{ - return $this->slotChangeListener; + public function addChangeListeners(InventoryChangeListener ...$listeners) : void{ + foreach($listeners as $listener){ + $this->listeners[spl_object_id($listener)] = $listener; + } } - public function setSlotChangeListener(?\Closure $eventProcessor) : void{ - if($eventProcessor !== null){ - Utils::validateCallableSignature(function(Inventory $inventory, int $slot) : void{}, $eventProcessor); + public function removeChangeListeners(InventoryChangeListener ...$listeners) : void{ + foreach($listeners as $listener){ + unset($this->listeners[spl_object_id($listener)]); } - $this->slotChangeListener = $eventProcessor; + } + + public function getChangeListeners() : array{ + return $this->listeners; } } diff --git a/src/pocketmine/inventory/CallbackInventoryChangeListener.php b/src/pocketmine/inventory/CallbackInventoryChangeListener.php new file mode 100644 index 0000000000..b274997409 --- /dev/null +++ b/src/pocketmine/inventory/CallbackInventoryChangeListener.php @@ -0,0 +1,65 @@ +onSlotChangeCallback = $onSlotChange; + $this->onContentChangeCallback = $onContentChange; + } + + public static function onAnyChange(\Closure $onChange) : self{ + return new self( + static function(Inventory $inventory, int $unused) use($onChange) : void{ + $onChange($inventory); + }, + static function(Inventory $inventory) use($onChange) : void{ + $onChange($inventory); + } + ); + } + + public function onSlotChange(Inventory $inventory, int $slot) : void{ + ($this->onSlotChangeCallback)($inventory, $slot); + } + + public function onContentChange(Inventory $inventory) : void{ + ($this->onContentChangeCallback)($inventory); + } +} diff --git a/src/pocketmine/inventory/Inventory.php b/src/pocketmine/inventory/Inventory.php index c0fba1d2be..a27a8525cf 100644 --- a/src/pocketmine/inventory/Inventory.php +++ b/src/pocketmine/inventory/Inventory.php @@ -231,12 +231,17 @@ interface Inventory{ public function slotExists(int $slot) : bool; /** - * @return null|\Closure + * @param InventoryChangeListener ...$listeners */ - public function getSlotChangeListener() : ?\Closure; + public function addChangeListeners(InventoryChangeListener ...$listeners) : void; /** - * @param \Closure|null $eventProcessor + * @param InventoryChangeListener ...$listeners */ - public function setSlotChangeListener(?\Closure $eventProcessor) : void; + public function removeChangeListeners(InventoryChangeListener ...$listeners) : void; + + /** + * @return InventoryChangeListener[] + */ + public function getChangeListeners() : array; } diff --git a/src/pocketmine/inventory/InventoryChangeListener.php b/src/pocketmine/inventory/InventoryChangeListener.php new file mode 100644 index 0000000000..d13edf7f08 --- /dev/null +++ b/src/pocketmine/inventory/InventoryChangeListener.php @@ -0,0 +1,38 @@ +getListTag(Container::TAG_ITEMS); $inventory = $this->getRealInventory(); - $slotChangeListener = $inventory->getSlotChangeListener(); - $inventory->setSlotChangeListener(null); //prevent any events being fired by initialization + $listeners = $inventory->getChangeListeners(); + $inventory->removeChangeListeners(...$listeners); //prevent any events being fired by initialization $inventory->clearAll(); /** @var CompoundTag $itemNBT */ foreach($inventoryTag as $itemNBT){ $inventory->setItem($itemNBT->getByte("Slot"), Item::nbtDeserialize($itemNBT)); } - $inventory->setSlotChangeListener($slotChangeListener); + $inventory->addChangeListeners(...$listeners); } if($tag->hasTag(Container::TAG_LOCK, StringTag::class)){ diff --git a/src/pocketmine/tile/Furnace.php b/src/pocketmine/tile/Furnace.php index 26ce225abc..ad9337139e 100644 --- a/src/pocketmine/tile/Furnace.php +++ b/src/pocketmine/tile/Furnace.php @@ -26,6 +26,7 @@ namespace pocketmine\tile; use pocketmine\block\Furnace as BlockFurnace; use pocketmine\event\inventory\FurnaceBurnEvent; use pocketmine\event\inventory\FurnaceSmeltEvent; +use pocketmine\inventory\CallbackInventoryChangeListener; use pocketmine\inventory\FurnaceInventory; use pocketmine\inventory\FurnaceRecipe; use pocketmine\inventory\Inventory; @@ -60,9 +61,11 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ public function __construct(World $world, Vector3 $pos){ $this->inventory = new FurnaceInventory($this); - $this->inventory->setSlotChangeListener(function(Inventory $inventory, int $slot) : void{ - $this->scheduleUpdate(); - }); + $this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange( + function(Inventory $unused) : void{ + $this->scheduleUpdate(); + }) + ); parent::__construct($world, $pos); } From bca0833035129d2d5f7ce7c5a9e3f5ed4c6b5fb6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 19 May 2019 16:56:10 +0100 Subject: [PATCH 0826/3224] Clean up handling of armour sync --- src/pocketmine/entity/Living.php | 9 ++++ src/pocketmine/inventory/ArmorInventory.php | 51 ------------------- .../network/mcpe/NetworkSession.php | 8 +++ 3 files changed, 17 insertions(+), 51 deletions(-) diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index a1072cab09..f73a100920 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -33,6 +33,8 @@ use pocketmine\event\entity\EntityDeathEvent; use pocketmine\event\entity\EntityEffectAddEvent; use pocketmine\event\entity\EntityEffectRemoveEvent; use pocketmine\inventory\ArmorInventory; +use pocketmine\inventory\CallbackInventoryChangeListener; +use pocketmine\inventory\Inventory; use pocketmine\item\Armor; use pocketmine\item\Consumable; use pocketmine\item\Durable; @@ -94,6 +96,13 @@ abstract class Living extends Entity implements Damageable{ $this->armorInventory = new ArmorInventory($this); //TODO: load/save armor inventory contents + $this->armorInventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange( + function(Inventory $unused) : void{ + foreach($this->getViewers() as $viewer){ + $viewer->getNetworkSession()->onMobArmorChange($this); + } + } + )); $health = $this->getMaxHealth(); diff --git a/src/pocketmine/inventory/ArmorInventory.php b/src/pocketmine/inventory/ArmorInventory.php index 39dff581a3..3643f1d641 100644 --- a/src/pocketmine/inventory/ArmorInventory.php +++ b/src/pocketmine/inventory/ArmorInventory.php @@ -25,10 +25,6 @@ namespace pocketmine\inventory; use pocketmine\entity\Living; use pocketmine\item\Item; -use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket; -use pocketmine\Player; -use function array_merge; -use function array_search; class ArmorInventory extends BaseInventory{ public const SLOT_HEAD = 0; @@ -79,51 +75,4 @@ class ArmorInventory extends BaseInventory{ public function setBoots(Item $boots) : bool{ return $this->setItem(self::SLOT_FEET, $boots); } - - public function sendSlot(int $index, $target) : void{ - if($target instanceof Player){ - $target = [$target]; - } - - /** @var Player[] $target */ - - if(($k = array_search($this->holder, $target, true)) !== false){ - $target[$k]->getNetworkSession()->syncInventorySlot($this, $index); - unset($target[$k]); - } - if(!empty($target)){ - //TODO: this should be handled by change listeners - $pk = new MobArmorEquipmentPacket(); - $pk->entityRuntimeId = $this->getHolder()->getId(); - $pk->slots = $this->getContents(true); - $this->holder->getWorld()->getServer()->broadcastPacket($target, $pk); - } - } - - public function sendContents($target) : void{ - if($target instanceof Player){ - $target = [$target]; - } - - $armor = $this->getContents(true); - - if(($k = array_search($this->holder, $target, true)) !== false){ - $target[$k]->getNetworkSession()->syncInventoryContents($this); - unset($target[$k]); - } - if(!empty($target)){ - //TODO: this should be handled by change listeners - $pk = new MobArmorEquipmentPacket(); - $pk->entityRuntimeId = $this->getHolder()->getId(); - $pk->slots = $armor; - $this->holder->getWorld()->getServer()->broadcastPacket($target, $pk); - } - } - - /** - * @return Player[] - */ - public function getViewers() : array{ - return array_merge(parent::getViewers(), $this->holder->getViewers()); - } } diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 3cd7cac2fc..969c0ef526 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -48,6 +48,7 @@ use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\DisconnectPacket; use pocketmine\network\mcpe\protocol\InventoryContentPacket; use pocketmine\network\mcpe\protocol\InventorySlotPacket; +use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket; use pocketmine\network\mcpe\protocol\MobEffectPacket; use pocketmine\network\mcpe\protocol\ModalFormRequestPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; @@ -817,6 +818,13 @@ class NetworkSession{ } } + public function onMobArmorChange(Living $mob) : void{ + $pk = new MobArmorEquipmentPacket(); + $pk->entityRuntimeId = $mob->getId(); + $pk->slots = $mob->getArmorInventory()->getContents(true); //beware this order might change in the future + $this->sendDataPacket($pk); + } + public function tick() : bool{ if($this->handler instanceof LoginSessionHandler){ if(time() >= $this->connectTime + 10){ From d9bc48bb0112011a51d0002ca421bd194151a12f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 20 May 2019 15:15:20 +0100 Subject: [PATCH 0827/3224] CraftingGrid: Remove redundant overrides the network session knows not to send this stuff because it's not associated with any window ID. --- src/pocketmine/inventory/CraftingGrid.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/pocketmine/inventory/CraftingGrid.php b/src/pocketmine/inventory/CraftingGrid.php index b15ac65b09..8aa45a65d1 100644 --- a/src/pocketmine/inventory/CraftingGrid.php +++ b/src/pocketmine/inventory/CraftingGrid.php @@ -71,14 +71,6 @@ class CraftingGrid extends BaseInventory{ return false; } - public function sendSlot(int $index, $target) : void{ - //we can't send a slot of a client-sided inventory window - } - - public function sendContents($target) : void{ - //no way to do this - } - /** * @return Player */ From c13b352b7698ec98ba2105fbb745657b27435184 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 20 May 2019 15:31:23 +0100 Subject: [PATCH 0828/3224] fix armour not being set correctly on entity spawn --- src/pocketmine/entity/Human.php | 2 +- src/pocketmine/entity/Living.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 74d099df00..c17fc13385 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -866,7 +866,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ //TODO: Hack for MCPE 1.2.13: DATA_NAMETAG is useless in AddPlayerPacket, so it has to be sent separately $this->sendData($player, [EntityMetadataProperties::NAMETAG => [EntityMetadataTypes::STRING, $this->getNameTag()]]); - $this->armorInventory->sendContents($player); + $player->getNetworkSession()->onMobArmorChange($this); if(!($this instanceof Player)){ $pk = new PlayerListPacket(); diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index f73a100920..048434590b 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -923,7 +923,7 @@ abstract class Living extends Entity implements Damageable{ protected function sendSpawnPacket(Player $player) : void{ parent::sendSpawnPacket($player); - $this->armorInventory->sendContents($player); + $player->getNetworkSession()->onMobArmorChange($this); } protected function onDispose() : void{ From 04d0b6c0547daca6b97fa64d11f421a1ba2180a2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 20 May 2019 15:45:15 +0100 Subject: [PATCH 0829/3224] don't spam listeners with slot-change notifications when doing a content change --- src/pocketmine/inventory/BaseInventory.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index 9be938cbf8..a58001cb1b 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -108,6 +108,9 @@ abstract class BaseInventory implements Inventory{ $items = array_slice($items, 0, $this->getSize(), true); } + $listeners = $this->listeners; + $this->listeners = []; + for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ if(!isset($items[$i])){ if($this->slots[$i] !== null){ @@ -120,6 +123,8 @@ abstract class BaseInventory implements Inventory{ } } + $this->addChangeListeners(...$listeners); //don't directly write, in case listeners were added while operation was in progress + foreach($this->listeners as $listener){ $listener->onContentChange($this); } From c21a25efb951d42897da8bf686fa9992162b08d5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 20 May 2019 16:13:14 +0100 Subject: [PATCH 0830/3224] move more rollback handling to network handlers, out of Player --- src/pocketmine/Player.php | 60 +++++++------------ .../mcpe/handler/InGameSessionHandler.php | 31 +++++++--- 2 files changed, 46 insertions(+), 45 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 1af1e957ef..c9144f384b 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -74,7 +74,6 @@ use pocketmine\inventory\CraftingGrid; use pocketmine\inventory\Inventory; use pocketmine\inventory\PlayerCursorInventory; use pocketmine\item\Consumable; -use pocketmine\item\Durable; use pocketmine\item\enchantment\EnchantmentInstance; use pocketmine\item\enchantment\MeleeWeaponEnchantment; use pocketmine\item\Item; @@ -1723,15 +1722,13 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } public function equipItem(int $hotbarSlot) : bool{ - if(!$this->inventory->isHotbarSlot($hotbarSlot)){ - $this->inventory->sendContents($this); + if(!$this->inventory->isHotbarSlot($hotbarSlot)){ //TODO: exception here? return false; } $ev = new PlayerItemHeldEvent($this, $this->inventory->getItem($hotbarSlot), $hotbarSlot); $ev->call(); if($ev->isCancelled()){ - $this->inventory->sendHeldItem($this); return false; } @@ -1758,18 +1755,17 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $ev->call(); if($ev->isCancelled()){ - $this->inventory->sendHeldItem($this); return false; } $result = $item->onClickAir($this, $directionVector); - if($result === ItemUseResult::SUCCESS()){ - $this->resetItemCooldown($item); - if($this->hasFiniteResources()){ - $this->inventory->setItemInHand($item); - } - }elseif($result === ItemUseResult::FAIL()){ - $this->inventory->sendHeldItem($this); + if($result !== ItemUseResult::SUCCESS()){ + return false; + } + + $this->resetItemCooldown($item); + if($this->hasFiniteResources()){ + $this->inventory->setItemInHand($item); } //TODO: check if item has a release action - if it doesn't, this shouldn't be set @@ -1781,7 +1777,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Consumes the currently-held item. * - * @return bool + * @return bool if the consumption succeeded. */ public function consumeHeldItem() : bool{ $slot = $this->inventory->getItemInHand(); @@ -1793,8 +1789,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $ev->call(); if($ev->isCancelled() or !$this->consumeObject($slot)){ - $this->inventory->sendContents($this); - return true; + return false; } $this->resetItemCooldown($slot); @@ -1818,22 +1813,16 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, */ public function releaseHeldItem() : bool{ try{ - if($this->isUsingItem()){ - $item = $this->inventory->getItemInHand(); - if($this->hasItemCooldown($item)){ - $this->inventory->sendContents($this); - return false; - } - $result = $item->onReleaseUsing($this); - if($result === ItemUseResult::SUCCESS()){ - $this->resetItemCooldown($item); - $this->inventory->setItemInHand($item); - return true; - } - if($result === ItemUseResult::FAIL()){ - $this->inventory->sendContents($this); - return true; - } + $item = $this->inventory->getItemInHand(); + if(!$this->isUsingItem() or $this->hasItemCooldown($item)){ + return false; + } + + $result = $item->onReleaseUsing($this); + if($result === ItemUseResult::SUCCESS()){ + $this->resetItemCooldown($item); + $this->inventory->setItemInHand($item); + return true; } return false; @@ -1894,7 +1883,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @param Vector3 $pos * @param int $face * - * @return bool + * @return bool if an action took place successfully */ public function attackBlock(Vector3 $pos, int $face) : bool{ if($pos->distanceSquared($this) > 10000){ @@ -1906,9 +1895,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $ev = new PlayerInteractEvent($this, $this->inventory->getItemInHand(), $target, null, $face, PlayerInteractEvent::LEFT_CLICK_BLOCK); $ev->call(); if($ev->isCancelled()){ - $this->world->sendBlocks([$this], [$target]); - $this->inventory->sendHeldItem($this); - return true; + return false; } if($target->onAttack($this->inventory->getItemInHand(), $face, $this)){ return true; @@ -2037,9 +2024,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $entity->attack($ev); if($ev->isCancelled()){ - if($heldItem instanceof Durable and $this->hasFiniteResources()){ - $this->inventory->sendContents($this); - } return false; } diff --git a/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php b/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php index df32be2176..6194820375 100644 --- a/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php @@ -280,7 +280,9 @@ class InGameSessionHandler extends SessionHandler{ } return true; case UseItemTransactionData::ACTION_CLICK_AIR: - $this->player->useHeldItem(); + if(!$this->player->useHeldItem()){ + $this->player->getInventory()->sendHeldItem($this->player); + } return true; } @@ -315,12 +317,17 @@ class InGameSessionHandler extends SessionHandler{ return false; } + //TODO: use transactiondata for rollbacks here switch($data->getActionType()){ case UseItemOnEntityTransactionData::ACTION_INTERACT: - $this->player->interactEntity($target, $data->getClickPos()); + if(!$this->player->interactEntity($target, $data->getClickPos())){ + $this->player->getInventory()->sendHeldItem($this->player); + } return true; case UseItemOnEntityTransactionData::ACTION_ATTACK: - $this->player->attackEntity($target); + if(!$this->player->attackEntity($target)){ + $this->player->getInventory()->sendHeldItem($this->player); + } return true; } @@ -328,12 +335,17 @@ class InGameSessionHandler extends SessionHandler{ } private function handleReleaseItemTransaction(ReleaseItemTransactionData $data) : bool{ + //TODO: use transactiondata for rollbacks here (resending entire inventory is very wasteful) switch($data->getActionType()){ case ReleaseItemTransactionData::ACTION_RELEASE: - $this->player->releaseHeldItem(); + if(!$this->player->releaseHeldItem()){ + $this->player->getInventory()->sendContents($this->player); + } return true; case ReleaseItemTransactionData::ACTION_CONSUME: - $this->player->consumeHeldItem(); + if(!$this->player->consumeHeldItem()){ + $this->player->getInventory()->sendHeldItem($this->player); + } return true; } @@ -341,7 +353,10 @@ class InGameSessionHandler extends SessionHandler{ } public function handleMobEquipment(MobEquipmentPacket $packet) : bool{ - return $this->player->equipItem($packet->hotbarSlot); + if(!$this->player->equipItem($packet->hotbarSlot)){ + $this->player->getInventory()->sendHeldItem($this->player); + } + return true; } public function handleMobArmorEquipment(MobArmorEquipmentPacket $packet) : bool{ @@ -373,7 +388,9 @@ class InGameSessionHandler extends SessionHandler{ switch($packet->action){ case PlayerActionPacket::ACTION_START_BREAK: - $this->player->attackBlock($pos, $packet->face); + if(!$this->player->attackBlock($pos, $packet->face)){ + $this->onFailedBlockAction($pos, $packet->face); + } break; From d6ce3f82b1a7d75ceccc811e80d3dd76df58a345 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 20 May 2019 16:30:00 +0100 Subject: [PATCH 0831/3224] Inventory: remove redundant return values --- src/pocketmine/inventory/ArmorInventory.php | 16 ++++++++-------- src/pocketmine/inventory/BaseInventory.php | 12 ++++-------- src/pocketmine/inventory/CraftingGrid.php | 11 +++-------- .../inventory/DoubleChestInventory.php | 9 +++------ src/pocketmine/inventory/FurnaceInventory.php | 18 ++++++------------ src/pocketmine/inventory/Inventory.php | 9 ++------- src/pocketmine/inventory/PlayerInventory.php | 12 +++--------- 7 files changed, 29 insertions(+), 58 deletions(-) diff --git a/src/pocketmine/inventory/ArmorInventory.php b/src/pocketmine/inventory/ArmorInventory.php index 3643f1d641..82d8c2e144 100644 --- a/src/pocketmine/inventory/ArmorInventory.php +++ b/src/pocketmine/inventory/ArmorInventory.php @@ -60,19 +60,19 @@ class ArmorInventory extends BaseInventory{ return $this->getItem(self::SLOT_FEET); } - public function setHelmet(Item $helmet) : bool{ - return $this->setItem(self::SLOT_HEAD, $helmet); + public function setHelmet(Item $helmet) : void{ + $this->setItem(self::SLOT_HEAD, $helmet); } - public function setChestplate(Item $chestplate) : bool{ - return $this->setItem(self::SLOT_CHEST, $chestplate); + public function setChestplate(Item $chestplate) : void{ + $this->setItem(self::SLOT_CHEST, $chestplate); } - public function setLeggings(Item $leggings) : bool{ - return $this->setItem(self::SLOT_LEGS, $leggings); + public function setLeggings(Item $leggings) : void{ + $this->setItem(self::SLOT_LEGS, $leggings); } - public function setBoots(Item $boots) : bool{ - return $this->setItem(self::SLOT_FEET, $boots); + public function setBoots(Item $boots) : void{ + $this->setItem(self::SLOT_FEET, $boots); } } diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index a58001cb1b..9f46d8a054 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -117,9 +117,7 @@ abstract class BaseInventory implements Inventory{ $this->clear($i, false); } }else{ - if(!$this->setItem($i, $items[$i], false)){ - $this->clear($i, false); - } + $this->setItem($i, $items[$i], false); } } @@ -134,7 +132,7 @@ abstract class BaseInventory implements Inventory{ } } - public function setItem(int $index, Item $item, bool $send = true) : bool{ + public function setItem(int $index, Item $item, bool $send = true) : void{ if($item->isNull()){ $item = ItemFactory::air(); }else{ @@ -145,8 +143,6 @@ abstract class BaseInventory implements Inventory{ $this->slots[$index] = $item->isNull() ? null : $item; $this->onSlotChange($index, $oldItem, $send); - - return true; } public function contains(Item $item) : bool{ @@ -330,8 +326,8 @@ abstract class BaseInventory implements Inventory{ return $itemSlots; } - public function clear(int $index, bool $send = true) : bool{ - return $this->setItem($index, ItemFactory::air(), $send); + public function clear(int $index, bool $send = true) : void{ + $this->setItem($index, ItemFactory::air(), $send); } public function clearAll(bool $send = true) : void{ diff --git a/src/pocketmine/inventory/CraftingGrid.php b/src/pocketmine/inventory/CraftingGrid.php index 8aa45a65d1..2cdabff19a 100644 --- a/src/pocketmine/inventory/CraftingGrid.php +++ b/src/pocketmine/inventory/CraftingGrid.php @@ -61,14 +61,9 @@ class CraftingGrid extends BaseInventory{ throw new \BadMethodCallException("Cannot change the size of a crafting grid"); } - public function setItem(int $index, Item $item, bool $send = true) : bool{ - if(parent::setItem($index, $item, $send)){ - $this->seekRecipeBounds(); - - return true; - } - - return false; + public function setItem(int $index, Item $item, bool $send = true) : void{ + parent::setItem($index, $item, $send); + $this->seekRecipeBounds(); } /** diff --git a/src/pocketmine/inventory/DoubleChestInventory.php b/src/pocketmine/inventory/DoubleChestInventory.php index 51a46e8c44..2eb0a9f6fc 100644 --- a/src/pocketmine/inventory/DoubleChestInventory.php +++ b/src/pocketmine/inventory/DoubleChestInventory.php @@ -58,13 +58,10 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ return $index < $this->left->getSize() ? $this->left->getItem($index) : $this->right->getItem($index - $this->left->getSize()); } - public function setItem(int $index, Item $item, bool $send = true) : bool{ + public function setItem(int $index, Item $item, bool $send = true) : void{ $old = $this->getItem($index); - if($index < $this->left->getSize() ? $this->left->setItem($index, $item, $send) : $this->right->setItem($index - $this->left->getSize(), $item, $send)){ - $this->onSlotChange($index, $old, $send); - return true; - } - return false; + $index < $this->left->getSize() ? $this->left->setItem($index, $item, $send) : $this->right->setItem($index - $this->left->getSize(), $item, $send); + $this->onSlotChange($index, $old, $send); } public function getContents(bool $includeEmpty = false) : array{ diff --git a/src/pocketmine/inventory/FurnaceInventory.php b/src/pocketmine/inventory/FurnaceInventory.php index 79a400c066..24699a7f0c 100644 --- a/src/pocketmine/inventory/FurnaceInventory.php +++ b/src/pocketmine/inventory/FurnaceInventory.php @@ -70,28 +70,22 @@ class FurnaceInventory extends ContainerInventory{ /** * @param Item $item - * - * @return bool */ - public function setResult(Item $item) : bool{ - return $this->setItem(2, $item); + public function setResult(Item $item) : void{ + $this->setItem(2, $item); } /** * @param Item $item - * - * @return bool */ - public function setFuel(Item $item) : bool{ - return $this->setItem(1, $item); + public function setFuel(Item $item) : void{ + $this->setItem(1, $item); } /** * @param Item $item - * - * @return bool */ - public function setSmelting(Item $item) : bool{ - return $this->setItem(0, $item); + public function setSmelting(Item $item) : void{ + $this->setItem(0, $item); } } diff --git a/src/pocketmine/inventory/Inventory.php b/src/pocketmine/inventory/Inventory.php index a27a8525cf..8260b5943b 100644 --- a/src/pocketmine/inventory/Inventory.php +++ b/src/pocketmine/inventory/Inventory.php @@ -56,15 +56,12 @@ interface Inventory{ /** * Puts an Item in a slot. - * If a plugin refuses the update or $index is invalid, it'll return false * * @param int $index * @param Item $item * @param bool $send - * - * @return bool */ - public function setItem(int $index, Item $item, bool $send = true) : bool; + public function setItem(int $index, Item $item, bool $send = true) : void; /** * Stores the given Items in the inventory. This will try to fill @@ -182,10 +179,8 @@ interface Inventory{ * * @param int $index * @param bool $send - * - * @return bool */ - public function clear(int $index, bool $send = true) : bool; + public function clear(int $index, bool $send = true) : void; /** * Clears all the slots diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index e6b93a44c2..8d91a5c15c 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -119,16 +119,10 @@ class PlayerInventory extends BaseInventory{ * Sets the item in the currently-held slot to the specified item. * * @param Item $item - * - * @return bool */ - public function setItemInHand(Item $item) : bool{ - if($this->setItem($this->getHeldItemIndex(), $item)){ - $this->sendHeldItem($this->holder->getViewers()); - return true; - } - - return false; + public function setItemInHand(Item $item) : void{ + $this->setItem($this->getHeldItemIndex(), $item); + $this->sendHeldItem($this->holder->getViewers()); } /** From cd0f0cb66c70e5fca8dfaf007190065bce2dc5f9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 20 May 2019 16:45:00 +0100 Subject: [PATCH 0832/3224] missed this in previous commit --- .../inventory/transaction/action/SlotChangeAction.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/inventory/transaction/action/SlotChangeAction.php b/src/pocketmine/inventory/transaction/action/SlotChangeAction.php index 3bc8265484..670c4cdb51 100644 --- a/src/pocketmine/inventory/transaction/action/SlotChangeAction.php +++ b/src/pocketmine/inventory/transaction/action/SlotChangeAction.php @@ -100,7 +100,8 @@ class SlotChangeAction extends InventoryAction{ * @return bool */ public function execute(Player $source) : bool{ - return $this->inventory->setItem($this->inventorySlot, $this->targetItem, false); + $this->inventory->setItem($this->inventorySlot, $this->targetItem, false); + return true; } /** From 297ca25123ca785c7b1e42173f8442dbb65bb0b5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 20 May 2019 16:45:46 +0100 Subject: [PATCH 0833/3224] remove usage of inventory network IDs for marking permanent windows --- src/pocketmine/Player.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index c9144f384b..fbb2253fad 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2843,7 +2843,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->windows[spl_object_id($inventory)] = $cnt; if($inventory->open($this)){ if($isPermanent){ - $this->permanentWindows[$cnt] = true; + $this->permanentWindows[spl_object_id($inventory)] = true; } return $cnt; }else{ @@ -2862,15 +2862,15 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @throws \InvalidArgumentException if trying to remove a fixed inventory window without the `force` parameter as true */ public function removeWindow(Inventory $inventory, bool $force = false){ - $id = $this->windows[$hash = spl_object_id($inventory)] ?? null; - - if($id !== null and !$force and isset($this->permanentWindows[$id])){ - throw new \InvalidArgumentException("Cannot remove fixed window $id (" . get_class($inventory) . ") from " . $this->getName()); + $objectId = spl_object_id($inventory); + if(!$force and isset($this->permanentWindows[$objectId])){ + throw new \InvalidArgumentException("Cannot remove fixed window " . get_class($inventory) . " from " . $this->getName()); } + $id = $this->windows[$objectId] ?? null; if($id !== null){ $inventory->close($this); - unset($this->windows[$hash], $this->windowIndex[$id], $this->permanentWindows[$id]); + unset($this->windows[$objectId], $this->windowIndex[$id], $this->permanentWindows[$objectId]); } } @@ -2881,7 +2881,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, */ public function removeAllWindows(bool $removePermanentWindows = false){ foreach($this->windowIndex as $id => $window){ - if(!$removePermanentWindows and isset($this->permanentWindows[$id])){ + if(!$removePermanentWindows and isset($this->permanentWindows[spl_object_id($window)])){ continue; } From 1c99602a3fe8e197fb0e81458750728e5305af49 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 20 May 2019 19:38:53 +0100 Subject: [PATCH 0834/3224] Player: give some inventory vars clearer names --- src/pocketmine/Player.php | 40 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index fbb2253fad..7fc90cb87d 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -183,7 +183,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** @var PlayerInfo */ protected $playerInfo; - protected $windowCnt = 2; + protected $lastInventoryNetworkId = 2; /** @var int[] */ protected $windows = []; /** @var Inventory[] */ @@ -2810,7 +2810,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * player is already viewing the specified inventory. * * @param Inventory $inventory - * @param int|null $forceId Forces a special ID for the window + * @param int|null $forceNetworkId Forces a special ID for the window * @param bool $isPermanent Prevents the window being removed if true. * * @return int @@ -2818,34 +2818,34 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @throws \InvalidArgumentException if a forceID which is already in use is specified * @throws \InvalidStateException if trying to add a window without forceID when no slots are free */ - public function addWindow(Inventory $inventory, ?int $forceId = null, bool $isPermanent = false) : int{ + public function addWindow(Inventory $inventory, ?int $forceNetworkId = null, bool $isPermanent = false) : int{ if(($id = $this->getWindowId($inventory)) !== ContainerIds::NONE){ return $id; } - if($forceId === null){ - $cnt = $this->windowCnt; + if($forceNetworkId === null){ + $networkId = $this->lastInventoryNetworkId; do{ - $cnt = max(ContainerIds::FIRST, ($cnt + 1) % ContainerIds::LAST); - if($cnt === $this->windowCnt){ //wraparound, no free slots + $networkId = max(ContainerIds::FIRST, ($networkId + 1) % ContainerIds::LAST); + if($networkId === $this->lastInventoryNetworkId){ //wraparound, no free slots throw new \InvalidStateException("No free window IDs found"); } - }while(isset($this->windowIndex[$cnt])); - $this->windowCnt = $cnt; + }while(isset($this->windowIndex[$networkId])); + $this->lastInventoryNetworkId = $networkId; }else{ - $cnt = $forceId; - if(isset($this->windowIndex[$cnt])){ - throw new \InvalidArgumentException("Requested force ID $forceId already in use"); + $networkId = $forceNetworkId; + if(isset($this->windowIndex[$networkId])){ + throw new \InvalidArgumentException("Requested force ID $forceNetworkId already in use"); } } - $this->windowIndex[$cnt] = $inventory; - $this->windows[spl_object_id($inventory)] = $cnt; + $this->windowIndex[$networkId] = $inventory; + $this->windows[spl_object_id($inventory)] = $networkId; if($inventory->open($this)){ if($isPermanent){ $this->permanentWindows[spl_object_id($inventory)] = true; } - return $cnt; + return $networkId; }else{ $this->removeWindow($inventory); @@ -2867,10 +2867,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, throw new \InvalidArgumentException("Cannot remove fixed window " . get_class($inventory) . " from " . $this->getName()); } - $id = $this->windows[$objectId] ?? null; - if($id !== null){ + $networkId = $this->windows[$objectId] ?? null; + if($networkId !== null){ $inventory->close($this); - unset($this->windows[$objectId], $this->windowIndex[$id], $this->permanentWindows[$objectId]); + unset($this->windows[$objectId], $this->windowIndex[$networkId], $this->permanentWindows[$objectId]); } } @@ -2880,7 +2880,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @param bool $removePermanentWindows Whether to remove permanent windows. */ public function removeAllWindows(bool $removePermanentWindows = false){ - foreach($this->windowIndex as $id => $window){ + foreach($this->windowIndex as $networkId => $window){ if(!$removePermanentWindows and isset($this->permanentWindows[spl_object_id($window)])){ continue; } @@ -2890,7 +2890,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } public function sendAllInventories(){ - foreach($this->windowIndex as $id => $inventory){ + foreach($this->windowIndex as $networkId => $inventory){ $inventory->sendContents($this); } } From 9ce1e29a175803a3a37fcef6463a39f03f367fc6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 24 May 2019 15:58:00 +0100 Subject: [PATCH 0835/3224] Player: fixed bow shooting, closes #2931 --- src/pocketmine/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 7fc90cb87d..e586786b48 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1759,7 +1759,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $result = $item->onClickAir($this, $directionVector); - if($result !== ItemUseResult::SUCCESS()){ + if($result === ItemUseResult::FAIL()){ return false; } From 3ea8da2dd35490226e61ec9791e8a0809cb85e87 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 24 May 2019 17:21:44 +0100 Subject: [PATCH 0836/3224] Use EnumTrait->equals() instead of direct comparison It's not guaranteed that objects provided are the same as those in the enum registry, so they can't be directly compared. Implementing comparison with === would require some kind of __equals() implementation or an extension to hook into such functionality. --- src/pocketmine/Player.php | 14 +++++------ src/pocketmine/Server.php | 2 +- src/pocketmine/block/CocoaBlock.php | 4 ++-- src/pocketmine/block/Leaves.php | 2 +- src/pocketmine/block/Slab.php | 24 +++++++++---------- .../command/defaults/GamemodeCommand.php | 2 +- .../network/mcpe/NetworkSession.php | 2 +- src/pocketmine/world/World.php | 4 ++-- src/pocketmine/world/biome/ForestBiome.php | 2 +- .../world/generator/object/Tree.php | 8 +++---- 10 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index e586786b48..ba65598374 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1320,7 +1320,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool */ public function isSurvival(bool $literal = false) : bool{ - return $this->gamemode === GameMode::SURVIVAL() or (!$literal and $this->gamemode === GameMode::ADVENTURE()); + return $this->gamemode->equals(GameMode::SURVIVAL()) or (!$literal and $this->gamemode->equals(GameMode::ADVENTURE())); } /** @@ -1332,7 +1332,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool */ public function isCreative(bool $literal = false) : bool{ - return $this->gamemode === GameMode::CREATIVE() or (!$literal and $this->gamemode === GameMode::SPECTATOR()); + return $this->gamemode->equals(GameMode::CREATIVE()) or (!$literal and $this->gamemode->equals(GameMode::SPECTATOR())); } /** @@ -1344,14 +1344,14 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool */ public function isAdventure(bool $literal = false) : bool{ - return $this->gamemode === GameMode::ADVENTURE() or (!$literal and $this->gamemode === GameMode::SPECTATOR()); + return $this->gamemode->equals(GameMode::ADVENTURE()) or (!$literal and $this->gamemode->equals(GameMode::SPECTATOR())); } /** * @return bool */ public function isSpectator() : bool{ - return $this->gamemode === GameMode::SPECTATOR(); + return $this->gamemode->equals(GameMode::SPECTATOR()); } /** @@ -1360,7 +1360,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool */ public function hasFiniteResources() : bool{ - return $this->gamemode === GameMode::SURVIVAL() or $this->gamemode === GameMode::ADVENTURE(); + return $this->gamemode->equals(GameMode::SURVIVAL()) or $this->gamemode->equals(GameMode::ADVENTURE()); } public function isFireProof() : bool{ @@ -1759,7 +1759,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $result = $item->onClickAir($this, $directionVector); - if($result === ItemUseResult::FAIL()){ + if($result->equals(ItemUseResult::FAIL())){ return false; } @@ -1819,7 +1819,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $result = $item->onReleaseUsing($this); - if($result === ItemUseResult::SUCCESS()){ + if($result->equals(ItemUseResult::SUCCESS())){ $this->resetItemCooldown($item); $this->inventory->setItemInHand($item); return true; diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 3669ef713a..2a5a534f37 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1554,7 +1554,7 @@ class Server{ } } - if($type === PluginLoadOrder::POSTWORLD()){ + if($type->equals(PluginLoadOrder::POSTWORLD())){ $this->commandMap->registerServerAliases(); DefaultPermissions::registerCorePermissions(); } diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index b2ccd8816a..a7d5a876e2 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -73,7 +73,7 @@ class CocoaBlock extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(Facing::axis($face) !== Facing::AXIS_Y and $blockClicked instanceof Wood and $blockClicked->getTreeType() === TreeType::JUNGLE()){ + if(Facing::axis($face) !== Facing::AXIS_Y and $blockClicked instanceof Wood and $blockClicked->getTreeType()->equals(TreeType::JUNGLE())){ $this->facing = $face; return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -96,7 +96,7 @@ class CocoaBlock extends Transparent{ public function onNearbyBlockChange() : void{ $side = $this->getSide(Facing::opposite($this->facing)); - if(!($side instanceof Wood) or $side->getTreeType() !== TreeType::JUNGLE()){ + if(!($side instanceof Wood) or !$side->getTreeType()->equals(TreeType::JUNGLE())){ $this->world->useBreakOn($this); } } diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 67e6ad4390..55d48de5fc 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -125,7 +125,7 @@ class Leaves extends Transparent{ if(mt_rand(1, 20) === 1){ //Saplings $drops[] = ItemFactory::get(Item::SAPLING, $this->treeType->getMagicNumber()); } - if(($this->treeType === TreeType::OAK() or $this->treeType === TreeType::DARK_OAK()) and mt_rand(1, 200) === 1){ //Apples + if(($this->treeType->equals(TreeType::OAK()) or $this->treeType->equals(TreeType::DARK_OAK())) and mt_rand(1, 200) === 1){ //Apples $drops[] = ItemFactory::get(Item::APPLE); } diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index 57eab21840..598241f4b3 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -43,12 +43,12 @@ abstract class Slab extends Transparent{ } public function getId() : int{ - return $this->slabType === SlabType::DOUBLE() ? $this->idInfo->getSecondId() : parent::getId(); + return $this->slabType->equals(SlabType::DOUBLE()) ? $this->idInfo->getSecondId() : parent::getId(); } protected function writeStateToMeta() : int{ - if($this->slabType !== SlabType::DOUBLE()){ - return ($this->slabType === SlabType::TOP() ? BlockLegacyMetadata::SLAB_FLAG_UPPER : 0); + if(!$this->slabType->equals(SlabType::DOUBLE())){ + return ($this->slabType->equals(SlabType::TOP()) ? BlockLegacyMetadata::SLAB_FLAG_UPPER : 0); } return 0; } @@ -66,7 +66,7 @@ abstract class Slab extends Transparent{ } public function isTransparent() : bool{ - return $this->slabType !== SlabType::DOUBLE(); + return !$this->slabType->equals(SlabType::DOUBLE()); } /** @@ -93,8 +93,8 @@ abstract class Slab extends Transparent{ return true; } - if($blockReplace instanceof Slab and $blockReplace->slabType !== SlabType::DOUBLE() and $blockReplace->isSameType($this)){ - if($blockReplace->slabType === SlabType::TOP()){ //Trying to combine with top slab + if($blockReplace instanceof Slab and !$blockReplace->slabType->equals(SlabType::DOUBLE()) and $blockReplace->isSameType($this)){ + if($blockReplace->slabType->equals(SlabType::TOP())){ //Trying to combine with top slab return $clickVector->y <= 0.5 or (!$isClickedBlock and $face === Facing::UP); }else{ return $clickVector->y >= 0.5 or (!$isClickedBlock and $face === Facing::DOWN); @@ -105,9 +105,9 @@ abstract class Slab extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($blockReplace instanceof Slab and $blockReplace->slabType !== SlabType::DOUBLE() and $blockReplace->isSameType($this) and ( - ($blockReplace->slabType === SlabType::TOP() and ($clickVector->y <= 0.5 or $face === Facing::UP)) or - ($blockReplace->slabType === SlabType::BOTTOM() and ($clickVector->y >= 0.5 or $face === Facing::DOWN)) + if($blockReplace instanceof Slab and !$blockReplace->slabType->equals(SlabType::DOUBLE()) and $blockReplace->isSameType($this) and ( + ($blockReplace->slabType->equals(SlabType::TOP()) and ($clickVector->y <= 0.5 or $face === Facing::UP)) or + ($blockReplace->slabType->equals(SlabType::BOTTOM()) and ($clickVector->y >= 0.5 or $face === Facing::DOWN)) )){ //Clicked in empty half of existing slab $this->slabType = SlabType::DOUBLE(); @@ -119,13 +119,13 @@ abstract class Slab extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - if($this->slabType === SlabType::DOUBLE()){ + if($this->slabType->equals(SlabType::DOUBLE())){ return parent::recalculateBoundingBox(); } - return AxisAlignedBB::one()->trim($this->slabType === SlabType::TOP() ? Facing::DOWN : Facing::UP, 0.5); + return AxisAlignedBB::one()->trim($this->slabType->equals(SlabType::TOP()) ? Facing::DOWN : Facing::UP, 0.5); } public function getDropsForCompatibleTool(Item $item) : array{ - return [$this->asItem()->setCount($this->slabType === SlabType::DOUBLE() ? 2 : 1)]; + return [$this->asItem()->setCount($this->slabType->equals(SlabType::DOUBLE()) ? 2 : 1)]; } } diff --git a/src/pocketmine/command/defaults/GamemodeCommand.php b/src/pocketmine/command/defaults/GamemodeCommand.php index 6f13bab5b3..5a0aa01a8f 100644 --- a/src/pocketmine/command/defaults/GamemodeCommand.php +++ b/src/pocketmine/command/defaults/GamemodeCommand.php @@ -72,7 +72,7 @@ class GamemodeCommand extends VanillaCommand{ } $target->setGamemode($gameMode); - if($gameMode !== $target->getGamemode()){ + if(!$gameMode->equals($target->getGamemode())){ $sender->sendMessage("Game mode change for " . $target->getName() . " failed!"); }else{ if($target === $sender){ diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 969c0ef526..8eeafc2bc1 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -852,7 +852,7 @@ class NetworkSession{ * @return int */ public static function getClientFriendlyGamemode(GameMode $gamemode) : int{ - if($gamemode === GameMode::SPECTATOR()){ + if($gamemode->equals(GameMode::SPECTATOR())){ return GameMode::CREATIVE()->getMagicNumber(); } diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 92ff2b7640..136e266a7c 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -1788,8 +1788,8 @@ class World implements ChunkManager, Metadatable{ if(!$player->isSneaking()){ $result = $item->onActivate($player, $blockReplace, $blockClicked, $face, $clickVector); - if($result !== ItemUseResult::NONE()){ - return $result === ItemUseResult::SUCCESS(); + if(!$result->equals(ItemUseResult::NONE())){ + return $result->equals(ItemUseResult::SUCCESS()); } } }else{ diff --git a/src/pocketmine/world/biome/ForestBiome.php b/src/pocketmine/world/biome/ForestBiome.php index b3e45cdcc6..b791416a55 100644 --- a/src/pocketmine/world/biome/ForestBiome.php +++ b/src/pocketmine/world/biome/ForestBiome.php @@ -48,7 +48,7 @@ class ForestBiome extends GrassyBiome{ $this->setElevation(63, 81); - if($type === TreeType::BIRCH()){ + if($this->type->equals(TreeType::BIRCH())){ $this->temperature = 0.6; $this->rainfall = 0.5; }else{ diff --git a/src/pocketmine/world/generator/object/Tree.php b/src/pocketmine/world/generator/object/Tree.php index eaa9142366..c3f2b72aa9 100644 --- a/src/pocketmine/world/generator/object/Tree.php +++ b/src/pocketmine/world/generator/object/Tree.php @@ -64,17 +64,17 @@ abstract class Tree{ /** @var null|Tree $tree */ $tree = null; $type = $type ?? TreeType::OAK(); - if($type === TreeType::SPRUCE()){ + if($type->equals(TreeType::SPRUCE())){ $tree = new SpruceTree(); - }elseif($type === TreeType::BIRCH()){ + }elseif($type->equals(TreeType::BIRCH())){ if($random->nextBoundedInt(39) === 0){ $tree = new BirchTree(true); }else{ $tree = new BirchTree(); } - }elseif($type === TreeType::JUNGLE()){ + }elseif($type->equals(TreeType::JUNGLE())){ $tree = new JungleTree(); - }elseif($type === TreeType::OAK()){ //default + }elseif($type->equals(TreeType::OAK())){ //default $tree = new OakTree(); /*if($random->nextRange(0, 9) === 0){ $tree = new BigTree(); From 54216c2fee436a2d323618a2dcdd9d78272a1f45 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 24 May 2019 19:38:43 +0100 Subject: [PATCH 0837/3224] Block: Blow away a bunch of useless classes --- src/pocketmine/block/Barrier.php | 31 ---- src/pocketmine/block/BlockFactory.php | 201 ++++++++++++--------- src/pocketmine/block/BrickStairs.php | 33 ---- src/pocketmine/block/Bricks.php | 33 ---- src/pocketmine/block/Cobblestone.php | 33 ---- src/pocketmine/block/CobblestoneStairs.php | 33 ---- src/pocketmine/block/Diamond.php | 33 ---- src/pocketmine/block/Door.php | 2 +- src/pocketmine/block/Emerald.php | 33 ---- src/pocketmine/block/EndStone.php | 33 ---- src/pocketmine/block/EndStoneBricks.php | 33 ---- src/pocketmine/block/Fence.php | 2 +- src/pocketmine/block/Gold.php | 33 ---- src/pocketmine/block/GoldOre.php | 33 ---- src/pocketmine/block/InfoUpdate.php | 31 ---- src/pocketmine/block/InvisibleBedrock.php | 31 ---- src/pocketmine/block/Iron.php | 33 ---- src/pocketmine/block/IronBars.php | 33 ---- src/pocketmine/block/IronDoor.php | 33 ---- src/pocketmine/block/IronOre.php | 33 ---- src/pocketmine/block/IronTrapdoor.php | 33 ---- src/pocketmine/block/Lapis.php | 33 ---- src/pocketmine/block/NetherBrick.php | 33 ---- src/pocketmine/block/NetherBrickFence.php | 33 ---- src/pocketmine/block/NetherBrickStairs.php | 33 ---- src/pocketmine/block/NetherWartBlock.php | 31 ---- src/pocketmine/block/Obsidian.php | 33 ---- src/pocketmine/block/Prismarine.php | 33 ---- src/pocketmine/block/Purpur.php | 33 ---- src/pocketmine/block/PurpurStairs.php | 33 ---- src/pocketmine/block/Quartz.php | 33 ---- src/pocketmine/block/QuartzStairs.php | 33 ---- src/pocketmine/block/Sandstone.php | 33 ---- src/pocketmine/block/SandstoneStairs.php | 33 ---- src/pocketmine/block/Slab.php | 2 +- src/pocketmine/block/SmoothStone.php | 36 ---- src/pocketmine/block/Solid.php | 2 +- src/pocketmine/block/Stair.php | 2 +- src/pocketmine/block/Stone.php | 33 ---- src/pocketmine/block/StoneBrickStairs.php | 33 ---- src/pocketmine/block/StoneBricks.php | 33 ---- src/pocketmine/block/StoneSlab.php | 33 ---- src/pocketmine/block/Stonecutter.php | 33 ---- src/pocketmine/block/Thin.php | 2 +- src/pocketmine/block/Transparent.php | 2 +- src/pocketmine/block/Trapdoor.php | 2 +- tests/phpunit/block/BlockTest.php | 4 +- tests/phpunit/block/MyCustomBlock.php | 2 +- 48 files changed, 128 insertions(+), 1311 deletions(-) delete mode 100644 src/pocketmine/block/Barrier.php delete mode 100644 src/pocketmine/block/BrickStairs.php delete mode 100644 src/pocketmine/block/Bricks.php delete mode 100644 src/pocketmine/block/Cobblestone.php delete mode 100644 src/pocketmine/block/CobblestoneStairs.php delete mode 100644 src/pocketmine/block/Diamond.php delete mode 100644 src/pocketmine/block/Emerald.php delete mode 100644 src/pocketmine/block/EndStone.php delete mode 100644 src/pocketmine/block/EndStoneBricks.php delete mode 100644 src/pocketmine/block/Gold.php delete mode 100644 src/pocketmine/block/GoldOre.php delete mode 100644 src/pocketmine/block/InfoUpdate.php delete mode 100644 src/pocketmine/block/InvisibleBedrock.php delete mode 100644 src/pocketmine/block/Iron.php delete mode 100644 src/pocketmine/block/IronBars.php delete mode 100644 src/pocketmine/block/IronDoor.php delete mode 100644 src/pocketmine/block/IronOre.php delete mode 100644 src/pocketmine/block/IronTrapdoor.php delete mode 100644 src/pocketmine/block/Lapis.php delete mode 100644 src/pocketmine/block/NetherBrick.php delete mode 100644 src/pocketmine/block/NetherBrickFence.php delete mode 100644 src/pocketmine/block/NetherBrickStairs.php delete mode 100644 src/pocketmine/block/NetherWartBlock.php delete mode 100644 src/pocketmine/block/Obsidian.php delete mode 100644 src/pocketmine/block/Prismarine.php delete mode 100644 src/pocketmine/block/Purpur.php delete mode 100644 src/pocketmine/block/PurpurStairs.php delete mode 100644 src/pocketmine/block/Quartz.php delete mode 100644 src/pocketmine/block/QuartzStairs.php delete mode 100644 src/pocketmine/block/Sandstone.php delete mode 100644 src/pocketmine/block/SandstoneStairs.php delete mode 100644 src/pocketmine/block/SmoothStone.php delete mode 100644 src/pocketmine/block/Stone.php delete mode 100644 src/pocketmine/block/StoneBrickStairs.php delete mode 100644 src/pocketmine/block/StoneBricks.php delete mode 100644 src/pocketmine/block/StoneSlab.php delete mode 100644 src/pocketmine/block/Stonecutter.php diff --git a/src/pocketmine/block/Barrier.php b/src/pocketmine/block/Barrier.php deleted file mode 100644 index 6b5bee1a31..0000000000 --- a/src/pocketmine/block/Barrier.php +++ /dev/null @@ -1,31 +0,0 @@ - "Cut ", BlockLegacyMetadata::SANDSTONE_SMOOTH => "Smooth " ]; + $sandstoneBreakInfo = new BlockBreakInfo(0.8, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN); + self::register(new Stair(new BID(BlockLegacyIds::RED_SANDSTONE_STAIRS), "Red Sandstone Stairs", $sandstoneBreakInfo)); + self::register(new Stair(new BID(BlockLegacyIds::SANDSTONE_STAIRS), "Sandstone Stairs", $sandstoneBreakInfo)); foreach($sandstoneTypes as $variant => $prefix){ - self::register(new Sandstone(new BID(BlockLegacyIds::SANDSTONE, $variant), $prefix . "Sandstone")); - self::register(new Sandstone(new BID(BlockLegacyIds::RED_SANDSTONE, $variant), $prefix . "Red Sandstone")); + self::register(new Solid(new BID(BlockLegacyIds::SANDSTONE, $variant), $prefix . "Sandstone", $sandstoneBreakInfo)); + self::register(new Solid(new BID(BlockLegacyIds::RED_SANDSTONE, $variant), $prefix . "Red Sandstone", $sandstoneBreakInfo)); } //region ugly glazed-terracotta colour -> ID mapping table diff --git a/src/pocketmine/block/BrickStairs.php b/src/pocketmine/block/BrickStairs.php deleted file mode 100644 index 7d942c2fe1..0000000000 --- a/src/pocketmine/block/BrickStairs.php +++ /dev/null @@ -1,33 +0,0 @@ - dummy */ protected $connections = []; diff --git a/src/pocketmine/block/Gold.php b/src/pocketmine/block/Gold.php deleted file mode 100644 index 5fcda706b3..0000000000 --- a/src/pocketmine/block/Gold.php +++ /dev/null @@ -1,33 +0,0 @@ - dummy */ protected $connections = []; diff --git a/src/pocketmine/block/Transparent.php b/src/pocketmine/block/Transparent.php index d079f39f9f..3d501dd768 100644 --- a/src/pocketmine/block/Transparent.php +++ b/src/pocketmine/block/Transparent.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; -abstract class Transparent extends Block{ +class Transparent extends Block{ public function isTransparent() : bool{ return true; diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index efc4e02821..4b41837b1f 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -31,7 +31,7 @@ use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\world\sound\DoorSound; -abstract class Trapdoor extends Transparent{ +class Trapdoor extends Transparent{ /** @var int */ protected $facing = Facing::NORTH; diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index 8c3fbc6a06..b1d747da36 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -37,7 +37,7 @@ class BlockTest extends TestCase{ * Test registering a block which would overwrite another block, without forcing it */ public function testAccidentalOverrideBlock() : void{ - $block = new MyCustomBlock(new BlockIdentifier(BlockLegacyIds::COBBLESTONE), "Cobblestone"); + $block = new MyCustomBlock(new BlockIdentifier(BlockLegacyIds::COBBLESTONE), "Cobblestone", BlockBreakInfo::instant()); $this->expectException(\InvalidArgumentException::class); BlockFactory::register($block); } @@ -46,7 +46,7 @@ class BlockTest extends TestCase{ * Test registering a block deliberately overwriting another block works as expected */ public function testDeliberateOverrideBlock() : void{ - $block = new MyCustomBlock(new BlockIdentifier(BlockLegacyIds::COBBLESTONE), "Cobblestone"); + $block = new MyCustomBlock(new BlockIdentifier(BlockLegacyIds::COBBLESTONE), "Cobblestone", BlockBreakInfo::instant()); BlockFactory::register($block, true); self::assertInstanceOf(MyCustomBlock::class, BlockFactory::get($block->getId())); } diff --git a/tests/phpunit/block/MyCustomBlock.php b/tests/phpunit/block/MyCustomBlock.php index 45b8a00e1c..7d21c04048 100644 --- a/tests/phpunit/block/MyCustomBlock.php +++ b/tests/phpunit/block/MyCustomBlock.php @@ -23,6 +23,6 @@ declare(strict_types=1); namespace pocketmine\block; -class MyCustomBlock extends Cobblestone{ +class MyCustomBlock extends Solid{ } From c29523baf464f793c58ec872256dba528f238d8a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 24 May 2019 19:59:03 +0100 Subject: [PATCH 0838/3224] added a bunch of new blocks --- src/pocketmine/block/BlockFactory.php | 45 ++++++++++--------- .../block_factory_consistency_check.json | 2 +- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 9f6d1f51ca..ab7068e6a3 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -96,8 +96,9 @@ class BlockFactory{ $cobblestoneBreakInfo = new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0); self::register(new Solid(new BID(BlockLegacyIds::COBBLESTONE), "Cobblestone", $cobblestoneBreakInfo)); - self::register(new Solid(new BID(BlockLegacyIds::MOSSY_COBBLESTONE), "Moss Stone", $cobblestoneBreakInfo)); + self::register(new Solid(new BID(BlockLegacyIds::MOSSY_COBBLESTONE), "Mossy Cobblestone", $cobblestoneBreakInfo)); self::register(new Stair(new BID(BlockLegacyIds::COBBLESTONE_STAIRS), "Cobblestone Stairs", $cobblestoneBreakInfo)); + self::register(new Stair(new BID(BlockLegacyIds::MOSSY_COBBLESTONE_STAIRS), "Mossy Cobblestone Stairs", $cobblestoneBreakInfo)); self::register(new Cobweb(new BID(BlockLegacyIds::COBWEB), "Cobweb")); self::register(new CocoaBlock(new BID(BlockLegacyIds::COCOA), "Cocoa Block")); @@ -122,7 +123,11 @@ class BlockFactory{ self::register(new EndPortalFrame(new BID(BlockLegacyIds::END_PORTAL_FRAME), "End Portal Frame")); self::register(new EndRod(new BID(BlockLegacyIds::END_ROD), "End Rod")); self::register(new Solid(new BID(BlockLegacyIds::END_STONE), "End Stone", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 45.0))); - self::register(new Solid(new BID(BlockLegacyIds::END_BRICKS), "End Stone Bricks", new BlockBreakInfo(0.8, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 4.0))); + + $endBrickBreakInfo = new BlockBreakInfo(0.8, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 4.0); + self::register(new Solid(new BID(BlockLegacyIds::END_BRICKS), "End Stone Bricks", $endBrickBreakInfo)); + self::register(new Stair(new BID(BlockLegacyIds::END_BRICK_STAIRS), "End Stone Brick Stairs", $endBrickBreakInfo)); + self::register(new EnderChest(new BID(BlockLegacyIds::ENDER_CHEST, 0, null, \pocketmine\tile\EnderChest::class), "Ender Chest")); self::register(new Farmland(new BID(BlockLegacyIds::FARMLAND), "Farmland")); self::register(new Fire(new BID(BlockLegacyIds::FIRE), "Fire Block")); @@ -213,6 +218,7 @@ class BlockFactory{ self::register(new Solid(new BID(BlockLegacyIds::RED_NETHER_BRICK), "Red Nether Bricks", $netherBrickBreakInfo)); self::register(new Fence(new BID(BlockLegacyIds::NETHER_BRICK_FENCE), "Nether Brick Fence", $netherBrickBreakInfo)); self::register(new Stair(new BID(BlockLegacyIds::NETHER_BRICK_STAIRS), "Nether Brick Stairs", $netherBrickBreakInfo)); + self::register(new Stair(new BID(BlockLegacyIds::RED_NETHER_BRICK_STAIRS), "Red Nether Brick Stairs", $netherBrickBreakInfo)); self::register(new NetherPortal(new BID(BlockLegacyIds::PORTAL), "Nether Portal")); self::register(new NetherQuartzOre(new BID(BlockLegacyIds::NETHER_QUARTZ_ORE), "Nether Quartz Ore")); self::register(new NetherReactor(new BID(BlockLegacyIds::NETHERREACTOR), "Nether Reactor Core")); @@ -228,8 +234,11 @@ class BlockFactory{ $prismarineBreakInfo = new BlockBreakInfo(1.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0); self::register(new Solid(new BID(BlockLegacyIds::PRISMARINE, BlockLegacyMetadata::PRISMARINE_BRICKS), "Prismarine Bricks", $prismarineBreakInfo)); + self::register(new Stair(new BID(BlockLegacyIds::PRISMARINE_BRICKS_STAIRS), "Prismarine Bricks Stairs", $prismarineBreakInfo)); self::register(new Solid(new BID(BlockLegacyIds::PRISMARINE, BlockLegacyMetadata::PRISMARINE_DARK), "Dark Prismarine", $prismarineBreakInfo)); + self::register(new Stair(new BID(BlockLegacyIds::DARK_PRISMARINE_STAIRS), "Dark Prismarine Stairs", $prismarineBreakInfo)); self::register(new Solid(new BID(BlockLegacyIds::PRISMARINE, BlockLegacyMetadata::PRISMARINE_NORMAL), "Prismarine", $prismarineBreakInfo)); + self::register(new Stair(new BID(BlockLegacyIds::PRISMARINE_STAIRS), "Prismarine Stairs", $prismarineBreakInfo)); self::register(new Pumpkin(new BID(BlockLegacyIds::PUMPKIN), "Pumpkin")); self::register(new PumpkinStem(new BID(BlockLegacyIds::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem")); @@ -243,6 +252,7 @@ class BlockFactory{ $quartzBreakInfo = new BlockBreakInfo(0.8, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN); self::register(new Solid(new BID(BlockLegacyIds::QUARTZ_BLOCK, BlockLegacyMetadata::QUARTZ_NORMAL), "Quartz Block", $quartzBreakInfo)); + self::register(new Stair(new BID(BlockLegacyIds::QUARTZ_STAIRS), "Quartz Stairs", $quartzBreakInfo)); self::register(new class(new BID(BlockLegacyIds::QUARTZ_BLOCK, BlockLegacyMetadata::QUARTZ_CHISELED), "Chiseled Quartz Block", $quartzBreakInfo) extends Solid{ use PillarRotationTrait; }); @@ -250,7 +260,7 @@ class BlockFactory{ use PillarRotationTrait; }); self::register(new Solid(new BID(BlockLegacyIds::QUARTZ_BLOCK, BlockLegacyMetadata::QUARTZ_SMOOTH), "Smooth Quartz Block", $quartzBreakInfo)); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) - self::register(new Stair(new BID(BlockLegacyIds::QUARTZ_STAIRS), "Quartz Stairs", $quartzBreakInfo)); + self::register(new Stair(new BID(BlockLegacyIds::SMOOTH_QUARTZ_STAIRS), "Smooth Quartz Stairs", $quartzBreakInfo)); self::register(new Rail(new BID(BlockLegacyIds::RAIL), "Rail")); self::register(new RedMushroom(new BID(BlockLegacyIds::RED_MUSHROOM), "Red Mushroom")); @@ -282,16 +292,25 @@ class BlockFactory{ return [ItemFactory::get(Item::COBBLESTONE)]; } }); + self::register(new Stair(new BID(BlockLegacyIds::NORMAL_STONE_STAIRS), "Stone Stairs", $stoneBreakInfo)); + self::register(new Solid(new BID(BlockLegacyIds::SMOOTH_STONE), "Smooth Stone", $stoneBreakInfo)); self::register(new Solid(new BID(BlockLegacyIds::STONE, BlockLegacyMetadata::STONE_ANDESITE), "Andesite", $stoneBreakInfo)); + self::register(new Stair(new BID(BlockLegacyIds::ANDESITE_STAIRS), "Andesite Stairs", $stoneBreakInfo)); self::register(new Solid(new BID(BlockLegacyIds::STONE, BlockLegacyMetadata::STONE_DIORITE), "Diorite", $stoneBreakInfo)); + self::register(new Stair(new BID(BlockLegacyIds::DIORITE_STAIRS), "Diorite Stairs", $stoneBreakInfo)); self::register(new Solid(new BID(BlockLegacyIds::STONE, BlockLegacyMetadata::STONE_GRANITE), "Granite", $stoneBreakInfo)); + self::register(new Stair(new BID(BlockLegacyIds::GRANITE_STAIRS), "Granite Stairs", $stoneBreakInfo)); self::register(new Solid(new BID(BlockLegacyIds::STONE, BlockLegacyMetadata::STONE_POLISHED_ANDESITE), "Polished Andesite", $stoneBreakInfo)); + self::register(new Stair(new BID(BlockLegacyIds::POLISHED_ANDESITE_STAIRS), "Polished Andesite Stairs", $stoneBreakInfo)); self::register(new Solid(new BID(BlockLegacyIds::STONE, BlockLegacyMetadata::STONE_POLISHED_DIORITE), "Polished Diorite", $stoneBreakInfo)); + self::register(new Stair(new BID(BlockLegacyIds::POLISHED_DIORITE_STAIRS), "Polished Diorite Stairs", $stoneBreakInfo)); self::register(new Solid(new BID(BlockLegacyIds::STONE, BlockLegacyMetadata::STONE_POLISHED_GRANITE), "Polished Granite", $stoneBreakInfo)); + self::register(new Stair(new BID(BlockLegacyIds::POLISHED_GRANITE_STAIRS), "Polished Granite Stairs", $stoneBreakInfo)); self::register(new Stair(new BID(BlockLegacyIds::STONE_BRICK_STAIRS), "Stone Brick Stairs", $stoneBreakInfo)); self::register(new Solid(new BID(BlockLegacyIds::STONEBRICK, BlockLegacyMetadata::STONE_BRICK_CHISELED), "Chiseled Stone Bricks", $stoneBreakInfo)); self::register(new Solid(new BID(BlockLegacyIds::STONEBRICK, BlockLegacyMetadata::STONE_BRICK_CRACKED), "Cracked Stone Bricks", $stoneBreakInfo)); self::register(new Solid(new BID(BlockLegacyIds::STONEBRICK, BlockLegacyMetadata::STONE_BRICK_MOSSY), "Mossy Stone Bricks", $stoneBreakInfo)); + self::register(new Stair(new BID(BlockLegacyIds::MOSSY_STONE_BRICK_STAIRS), "Mossy Stone Brick Stairs", $stoneBreakInfo)); self::register(new Solid(new BID(BlockLegacyIds::STONEBRICK, BlockLegacyMetadata::STONE_BRICK_NORMAL), "Stone Bricks", $stoneBreakInfo)); self::register(new StoneButton(new BID(BlockLegacyIds::STONE_BUTTON), "Stone Button")); self::register(new StonePressurePlate(new BID(BlockLegacyIds::STONE_PRESSURE_PLATE), "Stone Pressure Plate")); @@ -451,7 +470,9 @@ class BlockFactory{ ]; $sandstoneBreakInfo = new BlockBreakInfo(0.8, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN); self::register(new Stair(new BID(BlockLegacyIds::RED_SANDSTONE_STAIRS), "Red Sandstone Stairs", $sandstoneBreakInfo)); + self::register(new Stair(new BID(BlockLegacyIds::SMOOTH_RED_SANDSTONE_STAIRS), "Smooth Red Sandstone Stairs", $sandstoneBreakInfo)); self::register(new Stair(new BID(BlockLegacyIds::SANDSTONE_STAIRS), "Sandstone Stairs", $sandstoneBreakInfo)); + self::register(new Stair(new BID(BlockLegacyIds::SMOOTH_SANDSTONE_STAIRS), "Smooth Sandstone Stairs", $sandstoneBreakInfo)); foreach($sandstoneTypes as $variant => $prefix){ self::register(new Solid(new BID(BlockLegacyIds::SANDSTONE, $variant), $prefix . "Sandstone", $sandstoneBreakInfo)); self::register(new Solid(new BID(BlockLegacyIds::RED_SANDSTONE, $variant), $prefix . "Red Sandstone", $sandstoneBreakInfo)); @@ -512,7 +533,6 @@ class BlockFactory{ } //region --- auto-generated TODOs --- - //TODO: minecraft:andesite_stairs //TODO: minecraft:bamboo //TODO: minecraft:bamboo_sapling //TODO: minecraft:barrel @@ -539,8 +559,6 @@ class BlockFactory{ //TODO: minecraft:coral_fan_hang //TODO: minecraft:coral_fan_hang2 //TODO: minecraft:coral_fan_hang3 - //TODO: minecraft:dark_prismarine_stairs - //TODO: minecraft:diorite_stairs //TODO: minecraft:dispenser //TODO: minecraft:dried_kelp_block //TODO: minecraft:dropper @@ -663,11 +681,9 @@ class BlockFactory{ //TODO: minecraft:element_97 //TODO: minecraft:element_98 //TODO: minecraft:element_99 - //TODO: minecraft:end_brick_stairs //TODO: minecraft:end_gateway //TODO: minecraft:end_portal //TODO: minecraft:fletching_table - //TODO: minecraft:granite_stairs //TODO: minecraft:grindstone //TODO: minecraft:hopper //TODO: minecraft:jigsaw @@ -679,19 +695,10 @@ class BlockFactory{ //TODO: minecraft:lit_blast_furnace //TODO: minecraft:lit_smoker //TODO: minecraft:loom - //TODO: minecraft:mossy_cobblestone_stairs - //TODO: minecraft:mossy_stone_brick_stairs //TODO: minecraft:movingBlock - //TODO: minecraft:normal_stone_stairs //TODO: minecraft:observer //TODO: minecraft:piston //TODO: minecraft:pistonArmCollision - //TODO: minecraft:polished_andesite_stairs - //TODO: minecraft:polished_diorite_stairs - //TODO: minecraft:polished_granite_stairs - //TODO: minecraft:prismarine_bricks_stairs - //TODO: minecraft:prismarine_stairs - //TODO: minecraft:red_nether_brick_stairs //TODO: minecraft:repeating_command_block //TODO: minecraft:scaffolding //TODO: minecraft:seagrass @@ -699,10 +706,6 @@ class BlockFactory{ //TODO: minecraft:slime //TODO: minecraft:smithing_table //TODO: minecraft:smoker - //TODO: minecraft:smooth_quartz_stairs - //TODO: minecraft:smooth_red_sandstone_stairs - //TODO: minecraft:smooth_sandstone_stairs - //TODO: minecraft:smooth_stone //TODO: minecraft:sticky_piston //TODO: minecraft:stonecutter_block //TODO: minecraft:stripped_acacia_log diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index ff2d5f0f02..f0c63c19b2 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Moss Stone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4256":"Blue Ice","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From 066eadd687f8312b11530c7b887f596b27a41cb7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 25 May 2019 19:00:11 +0100 Subject: [PATCH 0839/3224] Move responsibility of copying block-picked item NBT to Block instead of Player --- src/pocketmine/Player.php | 13 +------------ src/pocketmine/block/Beetroot.php | 2 +- src/pocketmine/block/Block.php | 20 ++++++++++++++++++-- src/pocketmine/block/Carrot.php | 2 +- src/pocketmine/block/CocoaBlock.php | 2 +- src/pocketmine/block/Farmland.php | 2 +- src/pocketmine/block/FlowerPot.php | 4 ++-- src/pocketmine/block/ItemFrame.php | 4 ++-- src/pocketmine/block/Potato.php | 2 +- src/pocketmine/block/Wheat.php | 2 +- 10 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index ba65598374..7d44ed42da 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -105,7 +105,6 @@ use pocketmine\permission\PermissionAttachment; use pocketmine\permission\PermissionAttachmentInfo; use pocketmine\permission\PermissionManager; use pocketmine\plugin\Plugin; -use pocketmine\tile\Tile; use pocketmine\timings\Timings; use pocketmine\utils\TextFormat; use pocketmine\utils\UUID; @@ -1837,17 +1836,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return true; } - $item = $block->getPickedItem(); - if($addTileNBT){ - $tile = $this->getWorld()->getTile($block); - if($tile instanceof Tile){ - $nbt = $tile->getCleanedNBT(); - if($nbt instanceof CompoundTag){ - $item->setCustomBlockData($nbt); - $item->setLore(["+(DATA)"]); - } - } - } + $item = $block->getPickedItem($addTileNBT); $ev = new PlayerBlockPickEvent($this, $block, $item); $ev->call(); diff --git a/src/pocketmine/block/Beetroot.php b/src/pocketmine/block/Beetroot.php index 5158c8fc4d..418f16a4ee 100644 --- a/src/pocketmine/block/Beetroot.php +++ b/src/pocketmine/block/Beetroot.php @@ -42,7 +42,7 @@ class Beetroot extends Crops{ ]; } - public function getPickedItem() : Item{ + public function getPickedItem(bool $addUserData = false) : Item{ return ItemFactory::get(Item::BEETROOT_SEEDS); } } diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 5d3f5b32ac..a050a12bfb 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -37,9 +37,11 @@ use pocketmine\math\RayTraceResult; use pocketmine\math\Vector3; use pocketmine\metadata\Metadatable; use pocketmine\metadata\MetadataValue; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; use pocketmine\Player; use pocketmine\plugin\Plugin; +use pocketmine\tile\Tile; use pocketmine\tile\TileFactory; use pocketmine\world\Position; use pocketmine\world\World; @@ -500,10 +502,24 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ /** * Returns the item that players will equip when middle-clicking on this block. + * + * @param bool $addUserData + * * @return Item */ - public function getPickedItem() : Item{ - return $this->asItem(); + public function getPickedItem(bool $addUserData = false) : Item{ + $item = $this->asItem(); + if($addUserData){ + $tile = $this->world->getTile($this); + if($tile instanceof Tile){ + $nbt = $tile->getCleanedNBT(); + if($nbt instanceof CompoundTag){ + $item->setCustomBlockData($nbt); + $item->setLore(["+(DATA)"]); + } + } + } + return $item; } /** diff --git a/src/pocketmine/block/Carrot.php b/src/pocketmine/block/Carrot.php index 1e2c8b4591..e344351116 100644 --- a/src/pocketmine/block/Carrot.php +++ b/src/pocketmine/block/Carrot.php @@ -35,7 +35,7 @@ class Carrot extends Crops{ ]; } - public function getPickedItem() : Item{ + public function getPickedItem(bool $addUserData = false) : Item{ return ItemFactory::get(Item::CARROT); } } diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index a7d5a876e2..7448074af0 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -118,7 +118,7 @@ class CocoaBlock extends Transparent{ ]; } - public function getPickedItem() : Item{ + public function getPickedItem(bool $addUserData = false) : Item{ return ItemFactory::get(Item::DYE, 3); //cocoa beans } } diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index bcff0c7731..70a5353305 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -105,7 +105,7 @@ class Farmland extends Transparent{ return false; } - public function getPickedItem() : Item{ + public function getPickedItem(bool $addUserData = false) : Item{ return ItemFactory::get(Item::DIRT); } } diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 087bbf1a9f..476e194ba0 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -150,8 +150,8 @@ class FlowerPot extends Flowable{ return $items; } - public function getPickedItem() : Item{ - return $this->plant !== null ? $this->plant->asItem() : parent::getPickedItem(); + public function getPickedItem(bool $addUserData = false) : Item{ + return $this->plant !== null ? $this->plant->asItem() : parent::getPickedItem($addUserData); } public function isAffectedBySilkTouch() : bool{ diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 63291e357a..16e7e90c4d 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -197,8 +197,8 @@ class ItemFrame extends Flowable{ return $drops; } - public function getPickedItem() : Item{ - return $this->framedItem !== null ? clone $this->framedItem : parent::getPickedItem(); + public function getPickedItem(bool $addUserData = false) : Item{ + return $this->framedItem !== null ? clone $this->framedItem : parent::getPickedItem($addUserData); } public function isAffectedBySilkTouch() : bool{ diff --git a/src/pocketmine/block/Potato.php b/src/pocketmine/block/Potato.php index 62aa45caf1..937c17ecae 100644 --- a/src/pocketmine/block/Potato.php +++ b/src/pocketmine/block/Potato.php @@ -35,7 +35,7 @@ class Potato extends Crops{ ]; } - public function getPickedItem() : Item{ + public function getPickedItem(bool $addUserData = false) : Item{ return ItemFactory::get(Item::POTATO); } } diff --git a/src/pocketmine/block/Wheat.php b/src/pocketmine/block/Wheat.php index 59bd52256c..664f565a67 100644 --- a/src/pocketmine/block/Wheat.php +++ b/src/pocketmine/block/Wheat.php @@ -42,7 +42,7 @@ class Wheat extends Crops{ } } - public function getPickedItem() : Item{ + public function getPickedItem(bool $addUserData = false) : Item{ return ItemFactory::get(Item::WHEAT_SEEDS); } } From b329cac3d26b39b279766a62a39b078a3da3a4fe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 25 May 2019 19:23:43 +0100 Subject: [PATCH 0840/3224] Move pocketmine\tile\* to pocketmine\block\tile\* --- src/pocketmine/Server.php | 2 - src/pocketmine/block/Banner.php | 2 +- src/pocketmine/block/Bed.php | 2 +- src/pocketmine/block/Block.php | 4 +- src/pocketmine/block/BlockFactory.php | 47 ++++++++++++------- src/pocketmine/block/Chest.php | 2 +- src/pocketmine/block/EnderChest.php | 2 +- src/pocketmine/block/FlowerPot.php | 2 +- src/pocketmine/block/Furnace.php | 2 +- src/pocketmine/block/ItemFrame.php | 2 +- src/pocketmine/block/RedstoneComparator.php | 2 +- src/pocketmine/block/Sign.php | 2 +- src/pocketmine/block/Skull.php | 2 +- src/pocketmine/{ => block}/tile/Banner.php | 2 +- src/pocketmine/{ => block}/tile/Bed.php | 2 +- src/pocketmine/{ => block}/tile/Chest.php | 2 +- .../{ => block}/tile/Comparator.php | 2 +- src/pocketmine/{ => block}/tile/Container.php | 2 +- .../{ => block}/tile/ContainerTrait.php | 2 +- .../{ => block}/tile/EnchantTable.php | 2 +- .../{ => block}/tile/EnderChest.php | 2 +- src/pocketmine/{ => block}/tile/FlowerPot.php | 2 +- src/pocketmine/{ => block}/tile/Furnace.php | 2 +- src/pocketmine/{ => block}/tile/ItemFrame.php | 2 +- src/pocketmine/{ => block}/tile/Nameable.php | 2 +- .../{ => block}/tile/NameableTrait.php | 2 +- src/pocketmine/{ => block}/tile/Sign.php | 2 +- src/pocketmine/{ => block}/tile/Skull.php | 2 +- src/pocketmine/{ => block}/tile/Spawnable.php | 2 +- src/pocketmine/{ => block}/tile/Tile.php | 2 +- .../{ => block}/tile/TileFactory.php | 2 +- .../event/inventory/FurnaceBurnEvent.php | 2 +- .../event/inventory/FurnaceSmeltEvent.php | 2 +- src/pocketmine/inventory/ChestInventory.php | 8 ++-- .../inventory/DoubleChestInventory.php | 2 +- .../inventory/EnderChestInventory.php | 2 +- src/pocketmine/inventory/FurnaceInventory.php | 2 +- src/pocketmine/item/Banner.php | 2 +- src/pocketmine/timings/Timings.php | 2 +- src/pocketmine/world/World.php | 4 +- src/pocketmine/world/format/Chunk.php | 6 +-- 41 files changed, 76 insertions(+), 65 deletions(-) rename src/pocketmine/{ => block}/tile/Banner.php (99%) rename src/pocketmine/{ => block}/tile/Bed.php (98%) rename src/pocketmine/{ => block}/tile/Chest.php (99%) rename src/pocketmine/{ => block}/tile/Comparator.php (97%) rename src/pocketmine/{ => block}/tile/Container.php (97%) rename src/pocketmine/{ => block}/tile/ContainerTrait.php (98%) rename src/pocketmine/{ => block}/tile/EnchantTable.php (96%) rename src/pocketmine/{ => block}/tile/EnderChest.php (96%) rename src/pocketmine/{ => block}/tile/FlowerPot.php (98%) rename src/pocketmine/{ => block}/tile/Furnace.php (99%) rename src/pocketmine/{ => block}/tile/ItemFrame.php (98%) rename src/pocketmine/{ => block}/tile/Nameable.php (97%) rename src/pocketmine/{ => block}/tile/NameableTrait.php (98%) rename src/pocketmine/{ => block}/tile/Sign.php (98%) rename src/pocketmine/{ => block}/tile/Skull.php (98%) rename src/pocketmine/{ => block}/tile/Spawnable.php (98%) rename src/pocketmine/{ => block}/tile/Tile.php (99%) rename src/pocketmine/{ => block}/tile/TileFactory.php (99%) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 2a5a534f37..c0dead837a 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -82,7 +82,6 @@ use pocketmine\scheduler\AsyncPool; use pocketmine\scheduler\SendUsageTask; use pocketmine\snooze\SleeperHandler; use pocketmine\snooze\SleeperNotifier; -use pocketmine\tile\TileFactory; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; use pocketmine\updater\AutoUpdater; @@ -1187,7 +1186,6 @@ class Server{ $this->commandMap = new SimpleCommandMap($this); EntityFactory::init(); - TileFactory::init(); BlockFactory::init(); Enchantment::init(); ItemFactory::init(); diff --git a/src/pocketmine/block/Banner.php b/src/pocketmine/block/Banner.php index cc810f3bf3..b5abb29f21 100644 --- a/src/pocketmine/block/Banner.php +++ b/src/pocketmine/block/Banner.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use Ds\Deque; +use pocketmine\block\tile\Banner as TileBanner; use pocketmine\block\utils\BannerPattern; use pocketmine\block\utils\BlockDataValidator; use pocketmine\block\utils\DyeColor; @@ -34,7 +35,6 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; -use pocketmine\tile\Banner as TileBanner; use function assert; use function floor; diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index bd7037402f..41fe42895e 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\tile\Bed as TileBed; use pocketmine\block\utils\BlockDataValidator; use pocketmine\block\utils\DyeColor; use pocketmine\item\Bed as ItemBed; @@ -34,7 +35,6 @@ use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; -use pocketmine\tile\Bed as TileBed; use pocketmine\utils\TextFormat; use pocketmine\world\World; diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index a050a12bfb..16b2428399 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -26,6 +26,8 @@ declare(strict_types=1); */ namespace pocketmine\block; +use pocketmine\block\tile\Tile; +use pocketmine\block\tile\TileFactory; use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\entity\Entity; use pocketmine\item\enchantment\Enchantment; @@ -41,8 +43,6 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; use pocketmine\Player; use pocketmine\plugin\Plugin; -use pocketmine\tile\Tile; -use pocketmine\tile\TileFactory; use pocketmine\world\Position; use pocketmine\world\World; use function array_merge; diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index ab7068e6a3..10b4588636 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -24,6 +24,18 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\BlockIdentifier as BID; +use pocketmine\block\tile\Banner as TileBanner; +use pocketmine\block\tile\Bed as TileBed; +use pocketmine\block\tile\Chest as TileChest; +use pocketmine\block\tile\Comparator; +use pocketmine\block\tile\EnchantTable as TileEnchantingTable; +use pocketmine\block\tile\EnderChest as TileEnderChest; +use pocketmine\block\tile\FlowerPot as TileFlowerPot; +use pocketmine\block\tile\Furnace as TileFurnace; +use pocketmine\block\tile\ItemFrame as TileItemFrame; +use pocketmine\block\tile\Sign as TileSign; +use pocketmine\block\tile\Skull as TileSkull; +use pocketmine\block\tile\TileFactory; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\block\utils\PillarRotationTrait; @@ -32,7 +44,6 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\ItemIds; use pocketmine\item\TieredTool; -use pocketmine\tile\Comparator; use pocketmine\world\Position; use function array_fill; use function array_filter; @@ -58,6 +69,8 @@ class BlockFactory{ * this if you need to reset the block factory back to its original defaults for whatever reason. */ public static function init() : void{ + TileFactory::init(); + self::$fullList = new \SplFixedArray(8192); self::$lightFilter = \SplFixedArray::fromArray(array_fill(0, 8192, 1)); @@ -69,9 +82,9 @@ class BlockFactory{ self::register(new Anvil(new BID(BlockLegacyIds::ANVIL, BlockLegacyMetadata::ANVIL_NORMAL), "Anvil")); self::register(new Anvil(new BID(BlockLegacyIds::ANVIL, BlockLegacyMetadata::ANVIL_SLIGHTLY_DAMAGED), "Slightly Damaged Anvil")); self::register(new Anvil(new BID(BlockLegacyIds::ANVIL, BlockLegacyMetadata::ANVIL_VERY_DAMAGED), "Very Damaged Anvil")); - self::register(new Banner(new BlockIdentifierFlattened(BlockLegacyIds::STANDING_BANNER, BlockLegacyIds::WALL_BANNER, 0, ItemIds::BANNER, \pocketmine\tile\Banner::class), "Banner")); + self::register(new Banner(new BlockIdentifierFlattened(BlockLegacyIds::STANDING_BANNER, BlockLegacyIds::WALL_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Banner")); self::register(new Transparent(new BID(BlockLegacyIds::BARRIER), "Barrier", BlockBreakInfo::indestructible())); - self::register(new Bed(new BID(BlockLegacyIds::BED_BLOCK, 0, ItemIds::BED, \pocketmine\tile\Bed::class), "Bed Block")); + self::register(new Bed(new BID(BlockLegacyIds::BED_BLOCK, 0, ItemIds::BED, TileBed::class), "Bed Block")); self::register(new Bedrock(new BID(BlockLegacyIds::BEDROCK), "Bedrock")); self::register(new Beetroot(new BID(BlockLegacyIds::BEETROOT_BLOCK), "Beetroot Block")); self::register(new BlueIce(new BID(BlockLegacyIds::BLUE_ICE), "Blue Ice")); @@ -88,7 +101,7 @@ class BlockFactory{ self::register(new Cactus(new BID(BlockLegacyIds::CACTUS), "Cactus")); self::register(new Cake(new BID(BlockLegacyIds::CAKE_BLOCK, 0, ItemIds::CAKE), "Cake")); self::register(new Carrot(new BID(BlockLegacyIds::CARROTS), "Carrot Block")); - self::register(new Chest(new BID(BlockLegacyIds::CHEST, 0, null, \pocketmine\tile\Chest::class), "Chest")); + self::register(new Chest(new BID(BlockLegacyIds::CHEST, 0, null, TileChest::class), "Chest")); self::register(new Clay(new BID(BlockLegacyIds::CLAY_BLOCK), "Clay Block")); self::register(new Coal(new BID(BlockLegacyIds::COAL_BLOCK), "Coal Block")); self::register(new CoalOre(new BID(BlockLegacyIds::COAL_ORE), "Coal Ore")); @@ -119,7 +132,7 @@ class BlockFactory{ self::register(new DragonEgg(new BID(BlockLegacyIds::DRAGON_EGG), "Dragon Egg")); self::register(new Solid(new BID(BlockLegacyIds::EMERALD_BLOCK), "Emerald Block", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON, 30.0))); self::register(new EmeraldOre(new BID(BlockLegacyIds::EMERALD_ORE), "Emerald Ore")); - self::register(new EnchantingTable(new BID(BlockLegacyIds::ENCHANTING_TABLE, 0, null, \pocketmine\tile\EnchantTable::class), "Enchanting Table")); + self::register(new EnchantingTable(new BID(BlockLegacyIds::ENCHANTING_TABLE, 0, null, TileEnchantingTable::class), "Enchanting Table")); self::register(new EndPortalFrame(new BID(BlockLegacyIds::END_PORTAL_FRAME), "End Portal Frame")); self::register(new EndRod(new BID(BlockLegacyIds::END_ROD), "End Rod")); self::register(new Solid(new BID(BlockLegacyIds::END_STONE), "End Stone", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 45.0))); @@ -128,7 +141,7 @@ class BlockFactory{ self::register(new Solid(new BID(BlockLegacyIds::END_BRICKS), "End Stone Bricks", $endBrickBreakInfo)); self::register(new Stair(new BID(BlockLegacyIds::END_BRICK_STAIRS), "End Stone Brick Stairs", $endBrickBreakInfo)); - self::register(new EnderChest(new BID(BlockLegacyIds::ENDER_CHEST, 0, null, \pocketmine\tile\EnderChest::class), "Ender Chest")); + self::register(new EnderChest(new BID(BlockLegacyIds::ENDER_CHEST, 0, null, TileEnderChest::class), "Ender Chest")); self::register(new Farmland(new BID(BlockLegacyIds::FARMLAND), "Farmland")); self::register(new Fire(new BID(BlockLegacyIds::FIRE), "Fire Block")); self::register(new Flower(new BID(BlockLegacyIds::DANDELION), "Dandelion")); @@ -143,9 +156,9 @@ class BlockFactory{ self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_POPPY), "Poppy")); self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_RED_TULIP), "Red Tulip")); self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_WHITE_TULIP), "White Tulip")); - self::register(new FlowerPot(new BID(BlockLegacyIds::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, \pocketmine\tile\FlowerPot::class), "Flower Pot")); + self::register(new FlowerPot(new BID(BlockLegacyIds::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, TileFlowerPot::class), "Flower Pot")); self::register(new FrostedIce(new BID(BlockLegacyIds::FROSTED_ICE), "Frosted Ice")); - self::register(new Furnace(new BlockIdentifierFlattened(BlockLegacyIds::FURNACE, BlockLegacyIds::LIT_FURNACE, 0, null, \pocketmine\tile\Furnace::class), "Furnace")); + self::register(new Furnace(new BlockIdentifierFlattened(BlockLegacyIds::FURNACE, BlockLegacyIds::LIT_FURNACE, 0, null, TileFurnace::class), "Furnace")); self::register(new Glass(new BID(BlockLegacyIds::GLASS), "Glass")); self::register(new GlassPane(new BID(BlockLegacyIds::GLASS_PANE), "Glass Pane")); self::register(new GlowingObsidian(new BID(BlockLegacyIds::GLOWINGOBSIDIAN), "Glowing Obsidian")); @@ -200,7 +213,7 @@ class BlockFactory{ self::register(new Door(new BID(BlockLegacyIds::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 25.0))); self::register(new Solid(new BID(BlockLegacyIds::IRON_ORE), "Iron Ore", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_STONE))); self::register(new Trapdoor(new BID(BlockLegacyIds::IRON_TRAPDOOR), "Iron Trapdoor", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 25.0))); - self::register(new ItemFrame(new BID(BlockLegacyIds::FRAME_BLOCK, 0, ItemIds::FRAME, \pocketmine\tile\ItemFrame::class), "Item Frame")); + self::register(new ItemFrame(new BID(BlockLegacyIds::FRAME_BLOCK, 0, ItemIds::FRAME, TileItemFrame::class), "Item Frame")); self::register(new Ladder(new BID(BlockLegacyIds::LADDER), "Ladder")); self::register(new Solid(new BID(BlockLegacyIds::LAPIS_BLOCK), "Lapis Lazuli Block", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_STONE))); self::register(new LapisOre(new BID(BlockLegacyIds::LAPIS_ORE), "Lapis Lazuli Ore")); @@ -277,7 +290,7 @@ class BlockFactory{ self::register(new Sand(new BID(BlockLegacyIds::SAND, 1), "Red Sand")); self::register(new SeaLantern(new BID(BlockLegacyIds::SEALANTERN), "Sea Lantern")); self::register(new SeaPickle(new BID(BlockLegacyIds::SEA_PICKLE), "Sea Pickle")); - self::register(new Skull(new BID(BlockLegacyIds::MOB_HEAD_BLOCK, 0, null, \pocketmine\tile\Skull::class), "Mob Head")); + self::register(new Skull(new BID(BlockLegacyIds::MOB_HEAD_BLOCK, 0, null, TileSkull::class), "Mob Head")); @@ -358,7 +371,7 @@ class BlockFactory{ self::register(new Torch(new BID(BlockLegacyIds::COLORED_TORCH_RG), "Red Torch")); self::register(new Torch(new BID(BlockLegacyIds::COLORED_TORCH_RG, 8), "Green Torch")); self::register(new Torch(new BID(BlockLegacyIds::TORCH), "Torch")); - self::register(new TrappedChest(new BID(BlockLegacyIds::TRAPPED_CHEST, 0, null, \pocketmine\tile\Chest::class), "Trapped Chest")); + self::register(new TrappedChest(new BID(BlockLegacyIds::TRAPPED_CHEST, 0, null, TileChest::class), "Trapped Chest")); self::register(new Tripwire(new BID(BlockLegacyIds::TRIPWIRE, 0, ItemIds::STRING), "Tripwire")); self::register(new TripwireHook(new BID(BlockLegacyIds::TRIPWIRE_HOOK), "Tripwire Hook")); self::register(new UnderwaterTorch(new BID(BlockLegacyIds::UNDERWATER_TORCH), "Underwater Torch")); @@ -427,12 +440,12 @@ class BlockFactory{ /** @var BlockIdentifierFlattened[]|\SplObjectStorage $woodenSignIds */ $woodenSignIds = new \SplObjectStorage(); - $woodenSignIds[TreeType::OAK()] = new BlockIdentifierFlattened(BlockLegacyIds::SIGN_POST, BlockLegacyIds::WALL_SIGN, 0, ItemIds::SIGN, \pocketmine\tile\Sign::class); - $woodenSignIds[TreeType::SPRUCE()] = new BlockIdentifierFlattened(BlockLegacyIds::SPRUCE_STANDING_SIGN, BlockLegacyIds::SPRUCE_WALL_SIGN, 0, ItemIds::SPRUCE_SIGN, \pocketmine\tile\Sign::class); - $woodenSignIds[TreeType::BIRCH()] = new BlockIdentifierFlattened(BlockLegacyIds::BIRCH_STANDING_SIGN, BlockLegacyIds::BIRCH_WALL_SIGN, 0, ItemIds::BIRCH_SIGN, \pocketmine\tile\Sign::class); - $woodenSignIds[TreeType::JUNGLE()] = new BlockIdentifierFlattened(BlockLegacyIds::JUNGLE_STANDING_SIGN, BlockLegacyIds::JUNGLE_WALL_SIGN, 0, ItemIds::JUNGLE_SIGN, \pocketmine\tile\Sign::class); - $woodenSignIds[TreeType::ACACIA()] = new BlockIdentifierFlattened(BlockLegacyIds::ACACIA_STANDING_SIGN, BlockLegacyIds::ACACIA_WALL_SIGN, 0, ItemIds::ACACIA_SIGN, \pocketmine\tile\Sign::class); - $woodenSignIds[TreeType::DARK_OAK()] = new BlockIdentifierFlattened(BlockLegacyIds::DARKOAK_STANDING_SIGN, BlockLegacyIds::DARKOAK_WALL_SIGN, 0, ItemIds::DARKOAK_SIGN, \pocketmine\tile\Sign::class); + $woodenSignIds[TreeType::OAK()] = new BlockIdentifierFlattened(BlockLegacyIds::SIGN_POST, BlockLegacyIds::WALL_SIGN, 0, ItemIds::SIGN, TileSign::class); + $woodenSignIds[TreeType::SPRUCE()] = new BlockIdentifierFlattened(BlockLegacyIds::SPRUCE_STANDING_SIGN, BlockLegacyIds::SPRUCE_WALL_SIGN, 0, ItemIds::SPRUCE_SIGN, TileSign::class); + $woodenSignIds[TreeType::BIRCH()] = new BlockIdentifierFlattened(BlockLegacyIds::BIRCH_STANDING_SIGN, BlockLegacyIds::BIRCH_WALL_SIGN, 0, ItemIds::BIRCH_SIGN, TileSign::class); + $woodenSignIds[TreeType::JUNGLE()] = new BlockIdentifierFlattened(BlockLegacyIds::JUNGLE_STANDING_SIGN, BlockLegacyIds::JUNGLE_WALL_SIGN, 0, ItemIds::JUNGLE_SIGN, TileSign::class); + $woodenSignIds[TreeType::ACACIA()] = new BlockIdentifierFlattened(BlockLegacyIds::ACACIA_STANDING_SIGN, BlockLegacyIds::ACACIA_WALL_SIGN, 0, ItemIds::ACACIA_SIGN, TileSign::class); + $woodenSignIds[TreeType::DARK_OAK()] = new BlockIdentifierFlattened(BlockLegacyIds::DARKOAK_STANDING_SIGN, BlockLegacyIds::DARKOAK_WALL_SIGN, 0, ItemIds::DARKOAK_SIGN, TileSign::class); //endregion foreach(TreeType::getAll() as $treeType){ diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index f2b41e89cb..6c72e61344 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -23,13 +23,13 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\tile\Chest as TileChest; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; -use pocketmine\tile\Chest as TileChest; class Chest extends Transparent{ diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index 9c697cba46..e5e294797c 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\tile\EnderChest as TileEnderChest; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\item\ItemFactory; @@ -31,7 +32,6 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; -use pocketmine\tile\EnderChest as TileEnderChest; class EnderChest extends Transparent{ diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 476e194ba0..3c54598ca6 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -23,12 +23,12 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\tile\FlowerPot as TileFlowerPot; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; -use pocketmine\tile\FlowerPot as TileFlowerPot; use function assert; class FlowerPot extends Flowable{ diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index 952d5ba331..fd0a4218f2 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -23,13 +23,13 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\tile\Furnace as TileFurnace; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\item\TieredTool; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; -use pocketmine\tile\Furnace as TileFurnace; class Furnace extends Solid{ /** @var BlockIdentifierFlattened */ diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 16e7e90c4d..d3dfc235c0 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -23,12 +23,12 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\tile\ItemFrame as TileItemFrame; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; -use pocketmine\tile\ItemFrame as TileItemFrame; use function lcg_value; class ItemFrame extends Flowable{ diff --git a/src/pocketmine/block/RedstoneComparator.php b/src/pocketmine/block/RedstoneComparator.php index 61f0b3c0dd..3090ee026b 100644 --- a/src/pocketmine/block/RedstoneComparator.php +++ b/src/pocketmine/block/RedstoneComparator.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\tile\Comparator; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; @@ -30,7 +31,6 @@ use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; -use pocketmine\tile\Comparator; use function assert; class RedstoneComparator extends Flowable{ diff --git a/src/pocketmine/block/Sign.php b/src/pocketmine/block/Sign.php index d61b700c15..3652b840a8 100644 --- a/src/pocketmine/block/Sign.php +++ b/src/pocketmine/block/Sign.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\tile\Sign as TileSign; use pocketmine\block\utils\BlockDataValidator; use pocketmine\block\utils\SignText; use pocketmine\event\block\SignChangeEvent; @@ -31,7 +32,6 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; -use pocketmine\tile\Sign as TileSign; use pocketmine\utils\TextFormat; use function array_map; use function assert; diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index ef450e7f1e..fcd242a923 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\tile\Skull as TileSkull; use pocketmine\block\utils\BlockDataValidator; use pocketmine\block\utils\SkullType; use pocketmine\item\Item; @@ -32,7 +33,6 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; -use pocketmine\tile\Skull as TileSkull; use function assert; use function floor; diff --git a/src/pocketmine/tile/Banner.php b/src/pocketmine/block/tile/Banner.php similarity index 99% rename from src/pocketmine/tile/Banner.php rename to src/pocketmine/block/tile/Banner.php index 0b8997f3d9..58163ebba2 100644 --- a/src/pocketmine/tile/Banner.php +++ b/src/pocketmine/block/tile/Banner.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\tile; +namespace pocketmine\block\tile; use Ds\Deque; use pocketmine\block\utils\BannerPattern; diff --git a/src/pocketmine/tile/Bed.php b/src/pocketmine/block/tile/Bed.php similarity index 98% rename from src/pocketmine/tile/Bed.php rename to src/pocketmine/block/tile/Bed.php index bc8f9b444b..2f8b3f2bdd 100644 --- a/src/pocketmine/tile/Bed.php +++ b/src/pocketmine/block/tile/Bed.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\tile; +namespace pocketmine\block\tile; use pocketmine\block\utils\DyeColor; use pocketmine\math\Vector3; diff --git a/src/pocketmine/tile/Chest.php b/src/pocketmine/block/tile/Chest.php similarity index 99% rename from src/pocketmine/tile/Chest.php rename to src/pocketmine/block/tile/Chest.php index b59fd3b5f0..c766ac9196 100644 --- a/src/pocketmine/tile/Chest.php +++ b/src/pocketmine/block/tile/Chest.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\tile; +namespace pocketmine\block\tile; use pocketmine\inventory\ChestInventory; use pocketmine\inventory\DoubleChestInventory; diff --git a/src/pocketmine/tile/Comparator.php b/src/pocketmine/block/tile/Comparator.php similarity index 97% rename from src/pocketmine/tile/Comparator.php rename to src/pocketmine/block/tile/Comparator.php index 4e66512707..c19383ab18 100644 --- a/src/pocketmine/tile/Comparator.php +++ b/src/pocketmine/block/tile/Comparator.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\tile; +namespace pocketmine\block\tile; use pocketmine\block\RedstoneComparator; use pocketmine\nbt\tag\CompoundTag; diff --git a/src/pocketmine/tile/Container.php b/src/pocketmine/block/tile/Container.php similarity index 97% rename from src/pocketmine/tile/Container.php rename to src/pocketmine/block/tile/Container.php index 1e98dc5a12..d10a376726 100644 --- a/src/pocketmine/tile/Container.php +++ b/src/pocketmine/block/tile/Container.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\tile; +namespace pocketmine\block\tile; use pocketmine\inventory\Inventory; diff --git a/src/pocketmine/tile/ContainerTrait.php b/src/pocketmine/block/tile/ContainerTrait.php similarity index 98% rename from src/pocketmine/tile/ContainerTrait.php rename to src/pocketmine/block/tile/ContainerTrait.php index 28cc6b04eb..00652b5cb3 100644 --- a/src/pocketmine/tile/ContainerTrait.php +++ b/src/pocketmine/block/tile/ContainerTrait.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\tile; +namespace pocketmine\block\tile; use pocketmine\inventory\Inventory; use pocketmine\item\Item; diff --git a/src/pocketmine/tile/EnchantTable.php b/src/pocketmine/block/tile/EnchantTable.php similarity index 96% rename from src/pocketmine/tile/EnchantTable.php rename to src/pocketmine/block/tile/EnchantTable.php index 00e64412b8..fe48a85185 100644 --- a/src/pocketmine/tile/EnchantTable.php +++ b/src/pocketmine/block/tile/EnchantTable.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\tile; +namespace pocketmine\block\tile; class EnchantTable extends Spawnable implements Nameable{ use NameableTrait { diff --git a/src/pocketmine/tile/EnderChest.php b/src/pocketmine/block/tile/EnderChest.php similarity index 96% rename from src/pocketmine/tile/EnderChest.php rename to src/pocketmine/block/tile/EnderChest.php index 9493c924e6..902bc79f8a 100644 --- a/src/pocketmine/tile/EnderChest.php +++ b/src/pocketmine/block/tile/EnderChest.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\tile; +namespace pocketmine\block\tile; use pocketmine\nbt\tag\CompoundTag; diff --git a/src/pocketmine/tile/FlowerPot.php b/src/pocketmine/block/tile/FlowerPot.php similarity index 98% rename from src/pocketmine/tile/FlowerPot.php rename to src/pocketmine/block/tile/FlowerPot.php index 4aeeceac05..0c626bb33d 100644 --- a/src/pocketmine/tile/FlowerPot.php +++ b/src/pocketmine/block/tile/FlowerPot.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\tile; +namespace pocketmine\block\tile; use pocketmine\block\Air; use pocketmine\block\Block; diff --git a/src/pocketmine/tile/Furnace.php b/src/pocketmine/block/tile/Furnace.php similarity index 99% rename from src/pocketmine/tile/Furnace.php rename to src/pocketmine/block/tile/Furnace.php index ad9337139e..c612e8213d 100644 --- a/src/pocketmine/tile/Furnace.php +++ b/src/pocketmine/block/tile/Furnace.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\tile; +namespace pocketmine\block\tile; use pocketmine\block\Furnace as BlockFurnace; use pocketmine\event\inventory\FurnaceBurnEvent; diff --git a/src/pocketmine/tile/ItemFrame.php b/src/pocketmine/block/tile/ItemFrame.php similarity index 98% rename from src/pocketmine/tile/ItemFrame.php rename to src/pocketmine/block/tile/ItemFrame.php index dd54ef6d6c..e042c049d7 100644 --- a/src/pocketmine/tile/ItemFrame.php +++ b/src/pocketmine/block/tile/ItemFrame.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\tile; +namespace pocketmine\block\tile; use pocketmine\item\Item; use pocketmine\item\ItemFactory; diff --git a/src/pocketmine/tile/Nameable.php b/src/pocketmine/block/tile/Nameable.php similarity index 97% rename from src/pocketmine/tile/Nameable.php rename to src/pocketmine/block/tile/Nameable.php index 9f407461ef..8e8683533f 100644 --- a/src/pocketmine/tile/Nameable.php +++ b/src/pocketmine/block/tile/Nameable.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\tile; +namespace pocketmine\block\tile; interface Nameable{ public const TAG_CUSTOM_NAME = "CustomName"; diff --git a/src/pocketmine/tile/NameableTrait.php b/src/pocketmine/block/tile/NameableTrait.php similarity index 98% rename from src/pocketmine/tile/NameableTrait.php rename to src/pocketmine/block/tile/NameableTrait.php index 8f9ad1070b..38b89897c9 100644 --- a/src/pocketmine/tile/NameableTrait.php +++ b/src/pocketmine/block/tile/NameableTrait.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\tile; +namespace pocketmine\block\tile; use pocketmine\item\Item; use pocketmine\nbt\tag\CompoundTag; diff --git a/src/pocketmine/tile/Sign.php b/src/pocketmine/block/tile/Sign.php similarity index 98% rename from src/pocketmine/tile/Sign.php rename to src/pocketmine/block/tile/Sign.php index 09ff5d44f6..a53f5cfa6c 100644 --- a/src/pocketmine/tile/Sign.php +++ b/src/pocketmine/block/tile/Sign.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\tile; +namespace pocketmine\block\tile; use pocketmine\block\utils\SignText; use pocketmine\math\Vector3; diff --git a/src/pocketmine/tile/Skull.php b/src/pocketmine/block/tile/Skull.php similarity index 98% rename from src/pocketmine/tile/Skull.php rename to src/pocketmine/block/tile/Skull.php index 10b330d8d6..d4ede3ba98 100644 --- a/src/pocketmine/tile/Skull.php +++ b/src/pocketmine/block/tile/Skull.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\tile; +namespace pocketmine\block\tile; use pocketmine\block\utils\SkullType; use pocketmine\math\Vector3; diff --git a/src/pocketmine/tile/Spawnable.php b/src/pocketmine/block/tile/Spawnable.php similarity index 98% rename from src/pocketmine/tile/Spawnable.php rename to src/pocketmine/block/tile/Spawnable.php index 6bb21cddbf..6568ad6c46 100644 --- a/src/pocketmine/tile/Spawnable.php +++ b/src/pocketmine/block/tile/Spawnable.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\tile; +namespace pocketmine\block\tile; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/block/tile/Tile.php similarity index 99% rename from src/pocketmine/tile/Tile.php rename to src/pocketmine/block/tile/Tile.php index ee041cc63b..fbdece662d 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/block/tile/Tile.php @@ -25,7 +25,7 @@ declare(strict_types=1); * All the Tile classes and related classes */ -namespace pocketmine\tile; +namespace pocketmine\block\tile; use pocketmine\block\Block; use pocketmine\item\Item; diff --git a/src/pocketmine/tile/TileFactory.php b/src/pocketmine/block/tile/TileFactory.php similarity index 99% rename from src/pocketmine/tile/TileFactory.php rename to src/pocketmine/block/tile/TileFactory.php index 35bab3e899..b87e0d4ef0 100644 --- a/src/pocketmine/tile/TileFactory.php +++ b/src/pocketmine/block/tile/TileFactory.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\tile; +namespace pocketmine\block\tile; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; diff --git a/src/pocketmine/event/inventory/FurnaceBurnEvent.php b/src/pocketmine/event/inventory/FurnaceBurnEvent.php index 1ace733297..31d69f8957 100644 --- a/src/pocketmine/event/inventory/FurnaceBurnEvent.php +++ b/src/pocketmine/event/inventory/FurnaceBurnEvent.php @@ -23,11 +23,11 @@ declare(strict_types=1); namespace pocketmine\event\inventory; +use pocketmine\block\tile\Furnace; use pocketmine\event\block\BlockEvent; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\item\Item; -use pocketmine\tile\Furnace; class FurnaceBurnEvent extends BlockEvent implements Cancellable{ use CancellableTrait; diff --git a/src/pocketmine/event/inventory/FurnaceSmeltEvent.php b/src/pocketmine/event/inventory/FurnaceSmeltEvent.php index b69f0115ae..5fb1f8be97 100644 --- a/src/pocketmine/event/inventory/FurnaceSmeltEvent.php +++ b/src/pocketmine/event/inventory/FurnaceSmeltEvent.php @@ -23,11 +23,11 @@ declare(strict_types=1); namespace pocketmine\event\inventory; +use pocketmine\block\tile\Furnace; use pocketmine\event\block\BlockEvent; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\item\Item; -use pocketmine\tile\Furnace; class FurnaceSmeltEvent extends BlockEvent implements Cancellable{ use CancellableTrait; diff --git a/src/pocketmine/inventory/ChestInventory.php b/src/pocketmine/inventory/ChestInventory.php index f9da8aea5a..04e93617d0 100644 --- a/src/pocketmine/inventory/ChestInventory.php +++ b/src/pocketmine/inventory/ChestInventory.php @@ -23,13 +23,13 @@ declare(strict_types=1); namespace pocketmine\inventory; -use pocketmine\world\sound\ChestCloseSound; -use pocketmine\world\sound\ChestOpenSound; -use pocketmine\world\sound\Sound; +use pocketmine\block\tile\Chest; use pocketmine\network\mcpe\protocol\BlockEventPacket; use pocketmine\network\mcpe\protocol\types\WindowTypes; use pocketmine\Player; -use pocketmine\tile\Chest; +use pocketmine\world\sound\ChestCloseSound; +use pocketmine\world\sound\ChestOpenSound; +use pocketmine\world\sound\Sound; use function count; class ChestInventory extends ContainerInventory{ diff --git a/src/pocketmine/inventory/DoubleChestInventory.php b/src/pocketmine/inventory/DoubleChestInventory.php index 2eb0a9f6fc..086fc7f4dc 100644 --- a/src/pocketmine/inventory/DoubleChestInventory.php +++ b/src/pocketmine/inventory/DoubleChestInventory.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace pocketmine\inventory; +use pocketmine\block\tile\Chest; use pocketmine\item\Item; use pocketmine\Player; -use pocketmine\tile\Chest; use function array_merge; use function array_slice; use function count; diff --git a/src/pocketmine/inventory/EnderChestInventory.php b/src/pocketmine/inventory/EnderChestInventory.php index 6395f4d30c..0dcd970c03 100644 --- a/src/pocketmine/inventory/EnderChestInventory.php +++ b/src/pocketmine/inventory/EnderChestInventory.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\inventory; +use pocketmine\block\tile\EnderChest; use pocketmine\network\mcpe\protocol\types\WindowTypes; -use pocketmine\tile\EnderChest; use pocketmine\world\Position; use pocketmine\world\sound\EnderChestCloseSound; use pocketmine\world\sound\EnderChestOpenSound; diff --git a/src/pocketmine/inventory/FurnaceInventory.php b/src/pocketmine/inventory/FurnaceInventory.php index 24699a7f0c..81820747bd 100644 --- a/src/pocketmine/inventory/FurnaceInventory.php +++ b/src/pocketmine/inventory/FurnaceInventory.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace pocketmine\inventory; +use pocketmine\block\tile\Furnace; use pocketmine\item\Item; use pocketmine\network\mcpe\protocol\types\WindowTypes; -use pocketmine\tile\Furnace; class FurnaceInventory extends ContainerInventory{ /** @var Furnace */ diff --git a/src/pocketmine/item/Banner.php b/src/pocketmine/item/Banner.php index f6866880d3..55a80ee61d 100644 --- a/src/pocketmine/item/Banner.php +++ b/src/pocketmine/item/Banner.php @@ -27,11 +27,11 @@ use Ds\Deque; use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; +use pocketmine\block\tile\Banner as TileBanner; use pocketmine\block\utils\BannerPattern; use pocketmine\block\utils\DyeColor; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; -use pocketmine\tile\Banner as TileBanner; class Banner extends Item{ public const TAG_PATTERNS = TileBanner::TAG_PATTERNS; diff --git a/src/pocketmine/timings/Timings.php b/src/pocketmine/timings/Timings.php index ee218952b3..d5b28a0ffa 100644 --- a/src/pocketmine/timings/Timings.php +++ b/src/pocketmine/timings/Timings.php @@ -23,12 +23,12 @@ declare(strict_types=1); namespace pocketmine\timings; +use pocketmine\block\tile\Tile; use pocketmine\entity\Entity; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\ServerboundPacket; use pocketmine\Player; use pocketmine\scheduler\TaskHandler; -use pocketmine\tile\Tile; use function dechex; abstract class Timings{ diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 136e266a7c..7f65df8f1f 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -30,6 +30,8 @@ use pocketmine\block\Air; use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; +use pocketmine\block\tile\Spawnable; +use pocketmine\block\tile\Tile; use pocketmine\block\UnknownBlock; use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; @@ -64,8 +66,6 @@ use pocketmine\network\mcpe\protocol\UpdateBlockPacket; use pocketmine\Player; use pocketmine\plugin\Plugin; use pocketmine\Server; -use pocketmine\tile\Spawnable; -use pocketmine\tile\Tile; use pocketmine\timings\Timings; use pocketmine\utils\ReversePriorityQueue; use pocketmine\world\biome\Biome; diff --git a/src/pocketmine/world/format/Chunk.php b/src/pocketmine/world/format/Chunk.php index 6346634278..18452a42f6 100644 --- a/src/pocketmine/world/format/Chunk.php +++ b/src/pocketmine/world/format/Chunk.php @@ -28,15 +28,15 @@ namespace pocketmine\world\format; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; +use pocketmine\block\tile\Spawnable; +use pocketmine\block\tile\Tile; +use pocketmine\block\tile\TileFactory; use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; use pocketmine\Player; -use pocketmine\tile\Spawnable; -use pocketmine\tile\Tile; -use pocketmine\tile\TileFactory; use pocketmine\utils\BinaryStream; use pocketmine\world\World; use function array_fill; From a44d47fd3c34c64d7807c539c22b33140f7cd1a7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 25 May 2019 19:25:42 +0100 Subject: [PATCH 0841/3224] BlockFactory: Consistently use aliases to refer to tiles --- src/pocketmine/block/BlockFactory.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 10b4588636..9c1c6b5bac 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -27,7 +27,7 @@ use pocketmine\block\BlockIdentifier as BID; use pocketmine\block\tile\Banner as TileBanner; use pocketmine\block\tile\Bed as TileBed; use pocketmine\block\tile\Chest as TileChest; -use pocketmine\block\tile\Comparator; +use pocketmine\block\tile\Comparator as TileComparator; use pocketmine\block\tile\EnchantTable as TileEnchantingTable; use pocketmine\block\tile\EnderChest as TileEnderChest; use pocketmine\block\tile\FlowerPot as TileFlowerPot; @@ -279,7 +279,7 @@ class BlockFactory{ self::register(new RedMushroom(new BID(BlockLegacyIds::RED_MUSHROOM), "Red Mushroom")); self::register(new RedMushroomBlock(new BID(BlockLegacyIds::RED_MUSHROOM_BLOCK), "Red Mushroom Block")); self::register(new Redstone(new BID(BlockLegacyIds::REDSTONE_BLOCK), "Redstone Block")); - self::register(new RedstoneComparator(new BlockIdentifierFlattened(BlockLegacyIds::UNPOWERED_COMPARATOR, BlockLegacyIds::POWERED_COMPARATOR, 0, ItemIds::COMPARATOR, Comparator::class), "Redstone Comparator")); + self::register(new RedstoneComparator(new BlockIdentifierFlattened(BlockLegacyIds::UNPOWERED_COMPARATOR, BlockLegacyIds::POWERED_COMPARATOR, 0, ItemIds::COMPARATOR, TileComparator::class), "Redstone Comparator")); self::register(new RedstoneLamp(new BlockIdentifierFlattened(BlockLegacyIds::REDSTONE_LAMP, BlockLegacyIds::LIT_REDSTONE_LAMP), "Redstone Lamp")); self::register(new RedstoneOre(new BlockIdentifierFlattened(BlockLegacyIds::REDSTONE_ORE, BlockLegacyIds::LIT_REDSTONE_ORE), "Redstone Ore")); self::register(new RedstoneRepeater(new BlockIdentifierFlattened(BlockLegacyIds::UNPOWERED_REPEATER, BlockLegacyIds::POWERED_REPEATER, 0, ItemIds::REPEATER), "Redstone Repeater")); From d23dbc69f1d06467886aebd50e89c57888bbe8c3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 25 May 2019 19:59:24 +0100 Subject: [PATCH 0842/3224] BlockFactory: Alias some classes to improve readability --- src/pocketmine/block/BlockFactory.php | 691 +++++++++++++------------- 1 file changed, 347 insertions(+), 344 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 9c1c6b5bac..0c9dfed791 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -24,6 +24,9 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\BlockIdentifier as BID; +use pocketmine\block\BlockIdentifierFlattened as BIDFlattened; +use pocketmine\block\BlockLegacyIds as Ids; +use pocketmine\block\BlockLegacyMetadata as Meta; use pocketmine\block\tile\Banner as TileBanner; use pocketmine\block\tile\Bed as TileBed; use pocketmine\block\tile\Chest as TileChest; @@ -77,392 +80,392 @@ class BlockFactory{ self::$diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 8192, false)); self::$blastResistance = \SplFixedArray::fromArray(array_fill(0, 8192, 0)); - self::register(new ActivatorRail(new BID(BlockLegacyIds::ACTIVATOR_RAIL), "Activator Rail")); - self::register(new Air(new BID(BlockLegacyIds::AIR), "Air")); - self::register(new Anvil(new BID(BlockLegacyIds::ANVIL, BlockLegacyMetadata::ANVIL_NORMAL), "Anvil")); - self::register(new Anvil(new BID(BlockLegacyIds::ANVIL, BlockLegacyMetadata::ANVIL_SLIGHTLY_DAMAGED), "Slightly Damaged Anvil")); - self::register(new Anvil(new BID(BlockLegacyIds::ANVIL, BlockLegacyMetadata::ANVIL_VERY_DAMAGED), "Very Damaged Anvil")); - self::register(new Banner(new BlockIdentifierFlattened(BlockLegacyIds::STANDING_BANNER, BlockLegacyIds::WALL_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Banner")); - self::register(new Transparent(new BID(BlockLegacyIds::BARRIER), "Barrier", BlockBreakInfo::indestructible())); - self::register(new Bed(new BID(BlockLegacyIds::BED_BLOCK, 0, ItemIds::BED, TileBed::class), "Bed Block")); - self::register(new Bedrock(new BID(BlockLegacyIds::BEDROCK), "Bedrock")); - self::register(new Beetroot(new BID(BlockLegacyIds::BEETROOT_BLOCK), "Beetroot Block")); - self::register(new BlueIce(new BID(BlockLegacyIds::BLUE_ICE), "Blue Ice")); - self::register(new BoneBlock(new BID(BlockLegacyIds::BONE_BLOCK), "Bone Block")); - self::register(new Bookshelf(new BID(BlockLegacyIds::BOOKSHELF), "Bookshelf")); - self::register(new BrewingStand(new BID(BlockLegacyIds::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND), "Brewing Stand")); + self::register(new ActivatorRail(new BID(Ids::ACTIVATOR_RAIL), "Activator Rail")); + self::register(new Air(new BID(Ids::AIR), "Air")); + self::register(new Anvil(new BID(Ids::ANVIL, Meta::ANVIL_NORMAL), "Anvil")); + self::register(new Anvil(new BID(Ids::ANVIL, Meta::ANVIL_SLIGHTLY_DAMAGED), "Slightly Damaged Anvil")); + self::register(new Anvil(new BID(Ids::ANVIL, Meta::ANVIL_VERY_DAMAGED), "Very Damaged Anvil")); + self::register(new Banner(new BIDFlattened(Ids::STANDING_BANNER, Ids::WALL_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Banner")); + self::register(new Transparent(new BID(Ids::BARRIER), "Barrier", BlockBreakInfo::indestructible())); + self::register(new Bed(new BID(Ids::BED_BLOCK, 0, ItemIds::BED, TileBed::class), "Bed Block")); + self::register(new Bedrock(new BID(Ids::BEDROCK), "Bedrock")); + self::register(new Beetroot(new BID(Ids::BEETROOT_BLOCK), "Beetroot Block")); + self::register(new BlueIce(new BID(Ids::BLUE_ICE), "Blue Ice")); + self::register(new BoneBlock(new BID(Ids::BONE_BLOCK), "Bone Block")); + self::register(new Bookshelf(new BID(Ids::BOOKSHELF), "Bookshelf")); + self::register(new BrewingStand(new BID(Ids::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND), "Brewing Stand")); $bricksBreakInfo = new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0); - self::register(new Stair(new BID(BlockLegacyIds::BRICK_STAIRS), "Brick Stairs", $bricksBreakInfo)); - self::register(new Solid(new BID(BlockLegacyIds::BRICK_BLOCK), "Bricks", $bricksBreakInfo)); + self::register(new Stair(new BID(Ids::BRICK_STAIRS), "Brick Stairs", $bricksBreakInfo)); + self::register(new Solid(new BID(Ids::BRICK_BLOCK), "Bricks", $bricksBreakInfo)); - self::register(new BrownMushroom(new BID(BlockLegacyIds::BROWN_MUSHROOM), "Brown Mushroom")); - self::register(new BrownMushroomBlock(new BID(BlockLegacyIds::BROWN_MUSHROOM_BLOCK), "Brown Mushroom Block")); - self::register(new Cactus(new BID(BlockLegacyIds::CACTUS), "Cactus")); - self::register(new Cake(new BID(BlockLegacyIds::CAKE_BLOCK, 0, ItemIds::CAKE), "Cake")); - self::register(new Carrot(new BID(BlockLegacyIds::CARROTS), "Carrot Block")); - self::register(new Chest(new BID(BlockLegacyIds::CHEST, 0, null, TileChest::class), "Chest")); - self::register(new Clay(new BID(BlockLegacyIds::CLAY_BLOCK), "Clay Block")); - self::register(new Coal(new BID(BlockLegacyIds::COAL_BLOCK), "Coal Block")); - self::register(new CoalOre(new BID(BlockLegacyIds::COAL_ORE), "Coal Ore")); - self::register(new CoarseDirt(new BID(BlockLegacyIds::DIRT, BlockLegacyMetadata::DIRT_COARSE), "Coarse Dirt")); + self::register(new BrownMushroom(new BID(Ids::BROWN_MUSHROOM), "Brown Mushroom")); + self::register(new BrownMushroomBlock(new BID(Ids::BROWN_MUSHROOM_BLOCK), "Brown Mushroom Block")); + self::register(new Cactus(new BID(Ids::CACTUS), "Cactus")); + self::register(new Cake(new BID(Ids::CAKE_BLOCK, 0, ItemIds::CAKE), "Cake")); + self::register(new Carrot(new BID(Ids::CARROTS), "Carrot Block")); + self::register(new Chest(new BID(Ids::CHEST, 0, null, TileChest::class), "Chest")); + self::register(new Clay(new BID(Ids::CLAY_BLOCK), "Clay Block")); + self::register(new Coal(new BID(Ids::COAL_BLOCK), "Coal Block")); + self::register(new CoalOre(new BID(Ids::COAL_ORE), "Coal Ore")); + self::register(new CoarseDirt(new BID(Ids::DIRT, Meta::DIRT_COARSE), "Coarse Dirt")); $cobblestoneBreakInfo = new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0); - self::register(new Solid(new BID(BlockLegacyIds::COBBLESTONE), "Cobblestone", $cobblestoneBreakInfo)); - self::register(new Solid(new BID(BlockLegacyIds::MOSSY_COBBLESTONE), "Mossy Cobblestone", $cobblestoneBreakInfo)); - self::register(new Stair(new BID(BlockLegacyIds::COBBLESTONE_STAIRS), "Cobblestone Stairs", $cobblestoneBreakInfo)); - self::register(new Stair(new BID(BlockLegacyIds::MOSSY_COBBLESTONE_STAIRS), "Mossy Cobblestone Stairs", $cobblestoneBreakInfo)); + self::register(new Solid(new BID(Ids::COBBLESTONE), "Cobblestone", $cobblestoneBreakInfo)); + self::register(new Solid(new BID(Ids::MOSSY_COBBLESTONE), "Mossy Cobblestone", $cobblestoneBreakInfo)); + self::register(new Stair(new BID(Ids::COBBLESTONE_STAIRS), "Cobblestone Stairs", $cobblestoneBreakInfo)); + self::register(new Stair(new BID(Ids::MOSSY_COBBLESTONE_STAIRS), "Mossy Cobblestone Stairs", $cobblestoneBreakInfo)); - self::register(new Cobweb(new BID(BlockLegacyIds::COBWEB), "Cobweb")); - self::register(new CocoaBlock(new BID(BlockLegacyIds::COCOA), "Cocoa Block")); - self::register(new CraftingTable(new BID(BlockLegacyIds::CRAFTING_TABLE), "Crafting Table")); - self::register(new DaylightSensor(new BlockIdentifierFlattened(BlockLegacyIds::DAYLIGHT_DETECTOR, BlockLegacyIds::DAYLIGHT_DETECTOR_INVERTED), "Daylight Sensor")); - self::register(new DeadBush(new BID(BlockLegacyIds::DEADBUSH), "Dead Bush")); - self::register(new DetectorRail(new BID(BlockLegacyIds::DETECTOR_RAIL), "Detector Rail")); + self::register(new Cobweb(new BID(Ids::COBWEB), "Cobweb")); + self::register(new CocoaBlock(new BID(Ids::COCOA), "Cocoa Block")); + self::register(new CraftingTable(new BID(Ids::CRAFTING_TABLE), "Crafting Table")); + self::register(new DaylightSensor(new BIDFlattened(Ids::DAYLIGHT_DETECTOR, Ids::DAYLIGHT_DETECTOR_INVERTED), "Daylight Sensor")); + self::register(new DeadBush(new BID(Ids::DEADBUSH), "Dead Bush")); + self::register(new DetectorRail(new BID(Ids::DETECTOR_RAIL), "Detector Rail")); - self::register(new Solid(new BID(BlockLegacyIds::DIAMOND_BLOCK), "Diamond Block", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON, 30.0))); - self::register(new DiamondOre(new BID(BlockLegacyIds::DIAMOND_ORE), "Diamond Ore")); - self::register(new Dirt(new BID(BlockLegacyIds::DIRT, BlockLegacyMetadata::DIRT_NORMAL), "Dirt")); - self::register(new DoublePlant(new BID(BlockLegacyIds::DOUBLE_PLANT, BlockLegacyMetadata::DOUBLE_PLANT_SUNFLOWER), "Sunflower")); - self::register(new DoublePlant(new BID(BlockLegacyIds::DOUBLE_PLANT, BlockLegacyMetadata::DOUBLE_PLANT_LILAC), "Lilac")); - self::register(new DoublePlant(new BID(BlockLegacyIds::DOUBLE_PLANT, BlockLegacyMetadata::DOUBLE_PLANT_ROSE_BUSH), "Rose Bush")); - self::register(new DoublePlant(new BID(BlockLegacyIds::DOUBLE_PLANT, BlockLegacyMetadata::DOUBLE_PLANT_PEONY), "Peony")); - self::register(new DoubleTallGrass(new BID(BlockLegacyIds::DOUBLE_PLANT, BlockLegacyMetadata::DOUBLE_PLANT_TALLGRASS), "Double Tallgrass")); - self::register(new DoubleTallGrass(new BID(BlockLegacyIds::DOUBLE_PLANT, BlockLegacyMetadata::DOUBLE_PLANT_LARGE_FERN), "Large Fern")); - self::register(new DragonEgg(new BID(BlockLegacyIds::DRAGON_EGG), "Dragon Egg")); - self::register(new Solid(new BID(BlockLegacyIds::EMERALD_BLOCK), "Emerald Block", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON, 30.0))); - self::register(new EmeraldOre(new BID(BlockLegacyIds::EMERALD_ORE), "Emerald Ore")); - self::register(new EnchantingTable(new BID(BlockLegacyIds::ENCHANTING_TABLE, 0, null, TileEnchantingTable::class), "Enchanting Table")); - self::register(new EndPortalFrame(new BID(BlockLegacyIds::END_PORTAL_FRAME), "End Portal Frame")); - self::register(new EndRod(new BID(BlockLegacyIds::END_ROD), "End Rod")); - self::register(new Solid(new BID(BlockLegacyIds::END_STONE), "End Stone", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 45.0))); + self::register(new Solid(new BID(Ids::DIAMOND_BLOCK), "Diamond Block", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON, 30.0))); + self::register(new DiamondOre(new BID(Ids::DIAMOND_ORE), "Diamond Ore")); + self::register(new Dirt(new BID(Ids::DIRT, Meta::DIRT_NORMAL), "Dirt")); + self::register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_SUNFLOWER), "Sunflower")); + self::register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LILAC), "Lilac")); + self::register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_ROSE_BUSH), "Rose Bush")); + self::register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_PEONY), "Peony")); + self::register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_TALLGRASS), "Double Tallgrass")); + self::register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LARGE_FERN), "Large Fern")); + self::register(new DragonEgg(new BID(Ids::DRAGON_EGG), "Dragon Egg")); + self::register(new Solid(new BID(Ids::EMERALD_BLOCK), "Emerald Block", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON, 30.0))); + self::register(new EmeraldOre(new BID(Ids::EMERALD_ORE), "Emerald Ore")); + self::register(new EnchantingTable(new BID(Ids::ENCHANTING_TABLE, 0, null, TileEnchantingTable::class), "Enchanting Table")); + self::register(new EndPortalFrame(new BID(Ids::END_PORTAL_FRAME), "End Portal Frame")); + self::register(new EndRod(new BID(Ids::END_ROD), "End Rod")); + self::register(new Solid(new BID(Ids::END_STONE), "End Stone", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 45.0))); $endBrickBreakInfo = new BlockBreakInfo(0.8, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 4.0); - self::register(new Solid(new BID(BlockLegacyIds::END_BRICKS), "End Stone Bricks", $endBrickBreakInfo)); - self::register(new Stair(new BID(BlockLegacyIds::END_BRICK_STAIRS), "End Stone Brick Stairs", $endBrickBreakInfo)); + self::register(new Solid(new BID(Ids::END_BRICKS), "End Stone Bricks", $endBrickBreakInfo)); + self::register(new Stair(new BID(Ids::END_BRICK_STAIRS), "End Stone Brick Stairs", $endBrickBreakInfo)); - self::register(new EnderChest(new BID(BlockLegacyIds::ENDER_CHEST, 0, null, TileEnderChest::class), "Ender Chest")); - self::register(new Farmland(new BID(BlockLegacyIds::FARMLAND), "Farmland")); - self::register(new Fire(new BID(BlockLegacyIds::FIRE), "Fire Block")); - self::register(new Flower(new BID(BlockLegacyIds::DANDELION), "Dandelion")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_ALLIUM), "Allium")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_AZURE_BLUET), "Azure Bluet")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_BLUE_ORCHID), "Blue Orchid")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_CORNFLOWER), "Cornflower")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_LILY_OF_THE_VALLEY), "Lily of the Valley")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_ORANGE_TULIP), "Orange Tulip")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_OXEYE_DAISY), "Oxeye Daisy")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_PINK_TULIP), "Pink Tulip")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_POPPY), "Poppy")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_RED_TULIP), "Red Tulip")); - self::register(new Flower(new BID(BlockLegacyIds::RED_FLOWER, BlockLegacyMetadata::FLOWER_WHITE_TULIP), "White Tulip")); - self::register(new FlowerPot(new BID(BlockLegacyIds::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, TileFlowerPot::class), "Flower Pot")); - self::register(new FrostedIce(new BID(BlockLegacyIds::FROSTED_ICE), "Frosted Ice")); - self::register(new Furnace(new BlockIdentifierFlattened(BlockLegacyIds::FURNACE, BlockLegacyIds::LIT_FURNACE, 0, null, TileFurnace::class), "Furnace")); - self::register(new Glass(new BID(BlockLegacyIds::GLASS), "Glass")); - self::register(new GlassPane(new BID(BlockLegacyIds::GLASS_PANE), "Glass Pane")); - self::register(new GlowingObsidian(new BID(BlockLegacyIds::GLOWINGOBSIDIAN), "Glowing Obsidian")); - self::register(new Glowstone(new BID(BlockLegacyIds::GLOWSTONE), "Glowstone")); - self::register(new Solid(new BID(BlockLegacyIds::GOLD_BLOCK), "Gold Block", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON, 30.0))); - self::register(new Solid(new BID(BlockLegacyIds::GOLD_ORE), "Gold Ore", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON))); - self::register(new Grass(new BID(BlockLegacyIds::GRASS), "Grass")); - self::register(new GrassPath(new BID(BlockLegacyIds::GRASS_PATH), "Grass Path")); - self::register(new Gravel(new BID(BlockLegacyIds::GRAVEL), "Gravel")); - self::register(new HardenedClay(new BID(BlockLegacyIds::HARDENED_CLAY), "Hardened Clay")); - self::register(new HardenedGlass(new BID(BlockLegacyIds::HARD_GLASS), "Hardened Glass")); - self::register(new HardenedGlassPane(new BID(BlockLegacyIds::HARD_GLASS_PANE), "Hardened Glass Pane")); - self::register(new HayBale(new BID(BlockLegacyIds::HAY_BALE), "Hay Bale")); - self::register(new Ice(new BID(BlockLegacyIds::ICE), "Ice")); - self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, BlockLegacyMetadata::INFESTED_STONE), "Infested Stone") extends InfestedStone{ + self::register(new EnderChest(new BID(Ids::ENDER_CHEST, 0, null, TileEnderChest::class), "Ender Chest")); + self::register(new Farmland(new BID(Ids::FARMLAND), "Farmland")); + self::register(new Fire(new BID(Ids::FIRE), "Fire Block")); + self::register(new Flower(new BID(Ids::DANDELION), "Dandelion")); + self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ALLIUM), "Allium")); + self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_AZURE_BLUET), "Azure Bluet")); + self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_BLUE_ORCHID), "Blue Orchid")); + self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_CORNFLOWER), "Cornflower")); + self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_LILY_OF_THE_VALLEY), "Lily of the Valley")); + self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ORANGE_TULIP), "Orange Tulip")); + self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_OXEYE_DAISY), "Oxeye Daisy")); + self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_PINK_TULIP), "Pink Tulip")); + self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_POPPY), "Poppy")); + self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_RED_TULIP), "Red Tulip")); + self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_WHITE_TULIP), "White Tulip")); + self::register(new FlowerPot(new BID(Ids::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, TileFlowerPot::class), "Flower Pot")); + self::register(new FrostedIce(new BID(Ids::FROSTED_ICE), "Frosted Ice")); + self::register(new Furnace(new BIDFlattened(Ids::FURNACE, Ids::LIT_FURNACE, 0, null, TileFurnace::class), "Furnace")); + self::register(new Glass(new BID(Ids::GLASS), "Glass")); + self::register(new GlassPane(new BID(Ids::GLASS_PANE), "Glass Pane")); + self::register(new GlowingObsidian(new BID(Ids::GLOWINGOBSIDIAN), "Glowing Obsidian")); + self::register(new Glowstone(new BID(Ids::GLOWSTONE), "Glowstone")); + self::register(new Solid(new BID(Ids::GOLD_BLOCK), "Gold Block", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON, 30.0))); + self::register(new Solid(new BID(Ids::GOLD_ORE), "Gold Ore", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON))); + self::register(new Grass(new BID(Ids::GRASS), "Grass")); + self::register(new GrassPath(new BID(Ids::GRASS_PATH), "Grass Path")); + self::register(new Gravel(new BID(Ids::GRAVEL), "Gravel")); + self::register(new HardenedClay(new BID(Ids::HARDENED_CLAY), "Hardened Clay")); + self::register(new HardenedGlass(new BID(Ids::HARD_GLASS), "Hardened Glass")); + self::register(new HardenedGlassPane(new BID(Ids::HARD_GLASS_PANE), "Hardened Glass Pane")); + self::register(new HayBale(new BID(Ids::HAY_BALE), "Hay Bale")); + self::register(new Ice(new BID(Ids::ICE), "Ice")); + self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE), "Infested Stone") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [ItemFactory::get(ItemIds::STONE)]; } }); - self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, BlockLegacyMetadata::INFESTED_COBBLESTONE), "Infested Cobblestone") extends InfestedStone{ + self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_COBBLESTONE), "Infested Cobblestone") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [ItemFactory::get(ItemIds::COBBLESTONE)]; } }); - self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, BlockLegacyMetadata::INFESTED_STONE_BRICK), "Infested Stone Brick") extends InfestedStone{ + self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK), "Infested Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [ItemFactory::get(ItemIds::STONE_BRICK)]; } }); - self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, BlockLegacyMetadata::INFESTED_STONE_BRICK_MOSSY), "Infested Mossy Stone Brick") extends InfestedStone{ + self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_MOSSY), "Infested Mossy Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ - return [ItemFactory::get(ItemIds::STONE_BRICK, BlockLegacyMetadata::STONE_BRICK_MOSSY)]; + return [ItemFactory::get(ItemIds::STONE_BRICK, Meta::STONE_BRICK_MOSSY)]; } }); - self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, BlockLegacyMetadata::INFESTED_STONE_BRICK_CRACKED), "Infested Cracked Stone Brick") extends InfestedStone{ + self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CRACKED), "Infested Cracked Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ - return [ItemFactory::get(ItemIds::STONE_BRICK, BlockLegacyMetadata::STONE_BRICK_CRACKED)]; + return [ItemFactory::get(ItemIds::STONE_BRICK, Meta::STONE_BRICK_CRACKED)]; } }); - self::register(new class(new BID(BlockLegacyIds::MONSTER_EGG, BlockLegacyMetadata::INFESTED_STONE_BRICK_CHISELED), "Infested Chiseled Stone Brick") extends InfestedStone{ + self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CHISELED), "Infested Chiseled Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ - return [ItemFactory::get(ItemIds::STONE_BRICK, BlockLegacyMetadata::STONE_BRICK_CHISELED)]; + return [ItemFactory::get(ItemIds::STONE_BRICK, Meta::STONE_BRICK_CHISELED)]; } }); $updateBlockBreakInfo = new BlockBreakInfo(1.0); - self::register(new Solid(new BID(BlockLegacyIds::INFO_UPDATE), "update!", $updateBlockBreakInfo)); - self::register(new Solid(new BID(BlockLegacyIds::INFO_UPDATE2), "ate!upd", $updateBlockBreakInfo)); - self::register(new Transparent(new BID(BlockLegacyIds::INVISIBLEBEDROCK), "Invisible Bedrock", BlockBreakInfo::indestructible())); - self::register(new Solid(new BID(BlockLegacyIds::IRON_BLOCK), "Iron Block", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_STONE, 30.0))); - self::register(new Thin(new BID(BlockLegacyIds::IRON_BARS), "Iron Bars", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0))); - self::register(new Door(new BID(BlockLegacyIds::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 25.0))); - self::register(new Solid(new BID(BlockLegacyIds::IRON_ORE), "Iron Ore", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_STONE))); - self::register(new Trapdoor(new BID(BlockLegacyIds::IRON_TRAPDOOR), "Iron Trapdoor", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 25.0))); - self::register(new ItemFrame(new BID(BlockLegacyIds::FRAME_BLOCK, 0, ItemIds::FRAME, TileItemFrame::class), "Item Frame")); - self::register(new Ladder(new BID(BlockLegacyIds::LADDER), "Ladder")); - self::register(new Solid(new BID(BlockLegacyIds::LAPIS_BLOCK), "Lapis Lazuli Block", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_STONE))); - self::register(new LapisOre(new BID(BlockLegacyIds::LAPIS_ORE), "Lapis Lazuli Ore")); - self::register(new Lava(new BlockIdentifierFlattened(BlockLegacyIds::FLOWING_LAVA, BlockLegacyIds::STILL_LAVA), "Lava")); - self::register(new Lever(new BID(BlockLegacyIds::LEVER), "Lever")); - self::register(new LitPumpkin(new BID(BlockLegacyIds::JACK_O_LANTERN), "Jack o'Lantern")); - self::register(new Magma(new BID(BlockLegacyIds::MAGMA), "Magma Block")); - self::register(new Melon(new BID(BlockLegacyIds::MELON_BLOCK), "Melon Block")); - self::register(new MelonStem(new BID(BlockLegacyIds::MELON_STEM, 0, ItemIds::MELON_SEEDS), "Melon Stem")); - self::register(new MonsterSpawner(new BID(BlockLegacyIds::MOB_SPAWNER), "Monster Spawner")); - self::register(new Mycelium(new BID(BlockLegacyIds::MYCELIUM), "Mycelium")); + self::register(new Solid(new BID(Ids::INFO_UPDATE), "update!", $updateBlockBreakInfo)); + self::register(new Solid(new BID(Ids::INFO_UPDATE2), "ate!upd", $updateBlockBreakInfo)); + self::register(new Transparent(new BID(Ids::INVISIBLEBEDROCK), "Invisible Bedrock", BlockBreakInfo::indestructible())); + self::register(new Solid(new BID(Ids::IRON_BLOCK), "Iron Block", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_STONE, 30.0))); + self::register(new Thin(new BID(Ids::IRON_BARS), "Iron Bars", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0))); + self::register(new Door(new BID(Ids::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 25.0))); + self::register(new Solid(new BID(Ids::IRON_ORE), "Iron Ore", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_STONE))); + self::register(new Trapdoor(new BID(Ids::IRON_TRAPDOOR), "Iron Trapdoor", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 25.0))); + self::register(new ItemFrame(new BID(Ids::FRAME_BLOCK, 0, ItemIds::FRAME, TileItemFrame::class), "Item Frame")); + self::register(new Ladder(new BID(Ids::LADDER), "Ladder")); + self::register(new Solid(new BID(Ids::LAPIS_BLOCK), "Lapis Lazuli Block", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_STONE))); + self::register(new LapisOre(new BID(Ids::LAPIS_ORE), "Lapis Lazuli Ore")); + self::register(new Lava(new BIDFlattened(Ids::FLOWING_LAVA, Ids::STILL_LAVA), "Lava")); + self::register(new Lever(new BID(Ids::LEVER), "Lever")); + self::register(new LitPumpkin(new BID(Ids::JACK_O_LANTERN), "Jack o'Lantern")); + self::register(new Magma(new BID(Ids::MAGMA), "Magma Block")); + self::register(new Melon(new BID(Ids::MELON_BLOCK), "Melon Block")); + self::register(new MelonStem(new BID(Ids::MELON_STEM, 0, ItemIds::MELON_SEEDS), "Melon Stem")); + self::register(new MonsterSpawner(new BID(Ids::MOB_SPAWNER), "Monster Spawner")); + self::register(new Mycelium(new BID(Ids::MYCELIUM), "Mycelium")); $netherBrickBreakInfo = new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0); - self::register(new Solid(new BID(BlockLegacyIds::NETHER_BRICK_BLOCK), "Nether Bricks", $netherBrickBreakInfo)); - self::register(new Solid(new BID(BlockLegacyIds::RED_NETHER_BRICK), "Red Nether Bricks", $netherBrickBreakInfo)); - self::register(new Fence(new BID(BlockLegacyIds::NETHER_BRICK_FENCE), "Nether Brick Fence", $netherBrickBreakInfo)); - self::register(new Stair(new BID(BlockLegacyIds::NETHER_BRICK_STAIRS), "Nether Brick Stairs", $netherBrickBreakInfo)); - self::register(new Stair(new BID(BlockLegacyIds::RED_NETHER_BRICK_STAIRS), "Red Nether Brick Stairs", $netherBrickBreakInfo)); - self::register(new NetherPortal(new BID(BlockLegacyIds::PORTAL), "Nether Portal")); - self::register(new NetherQuartzOre(new BID(BlockLegacyIds::NETHER_QUARTZ_ORE), "Nether Quartz Ore")); - self::register(new NetherReactor(new BID(BlockLegacyIds::NETHERREACTOR), "Nether Reactor Core")); - self::register(new Solid(new BID(BlockLegacyIds::NETHER_WART_BLOCK), "Nether Wart Block", new BlockBreakInfo(1.0))); - self::register(new NetherWartPlant(new BID(BlockLegacyIds::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART), "Nether Wart")); - self::register(new Netherrack(new BID(BlockLegacyIds::NETHERRACK), "Netherrack")); - self::register(new NoteBlock(new BID(BlockLegacyIds::NOTEBLOCK), "Note Block")); - self::register(new Solid(new BID(BlockLegacyIds::OBSIDIAN), "Obsidian", new BlockBreakInfo(35.0 /* 50 in PC */, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_DIAMOND, 6000.0))); - self::register(new PackedIce(new BID(BlockLegacyIds::PACKED_ICE), "Packed Ice")); - self::register(new Podzol(new BID(BlockLegacyIds::PODZOL), "Podzol")); - self::register(new Potato(new BID(BlockLegacyIds::POTATOES), "Potato Block")); - self::register(new PoweredRail(new BID(BlockLegacyIds::GOLDEN_RAIL, BlockLegacyMetadata::RAIL_STRAIGHT_NORTH_SOUTH), "Powered Rail")); + self::register(new Solid(new BID(Ids::NETHER_BRICK_BLOCK), "Nether Bricks", $netherBrickBreakInfo)); + self::register(new Solid(new BID(Ids::RED_NETHER_BRICK), "Red Nether Bricks", $netherBrickBreakInfo)); + self::register(new Fence(new BID(Ids::NETHER_BRICK_FENCE), "Nether Brick Fence", $netherBrickBreakInfo)); + self::register(new Stair(new BID(Ids::NETHER_BRICK_STAIRS), "Nether Brick Stairs", $netherBrickBreakInfo)); + self::register(new Stair(new BID(Ids::RED_NETHER_BRICK_STAIRS), "Red Nether Brick Stairs", $netherBrickBreakInfo)); + self::register(new NetherPortal(new BID(Ids::PORTAL), "Nether Portal")); + self::register(new NetherQuartzOre(new BID(Ids::NETHER_QUARTZ_ORE), "Nether Quartz Ore")); + self::register(new NetherReactor(new BID(Ids::NETHERREACTOR), "Nether Reactor Core")); + self::register(new Solid(new BID(Ids::NETHER_WART_BLOCK), "Nether Wart Block", new BlockBreakInfo(1.0))); + self::register(new NetherWartPlant(new BID(Ids::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART), "Nether Wart")); + self::register(new Netherrack(new BID(Ids::NETHERRACK), "Netherrack")); + self::register(new NoteBlock(new BID(Ids::NOTEBLOCK), "Note Block")); + self::register(new Solid(new BID(Ids::OBSIDIAN), "Obsidian", new BlockBreakInfo(35.0 /* 50 in PC */, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_DIAMOND, 6000.0))); + self::register(new PackedIce(new BID(Ids::PACKED_ICE), "Packed Ice")); + self::register(new Podzol(new BID(Ids::PODZOL), "Podzol")); + self::register(new Potato(new BID(Ids::POTATOES), "Potato Block")); + self::register(new PoweredRail(new BID(Ids::GOLDEN_RAIL, Meta::RAIL_STRAIGHT_NORTH_SOUTH), "Powered Rail")); $prismarineBreakInfo = new BlockBreakInfo(1.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0); - self::register(new Solid(new BID(BlockLegacyIds::PRISMARINE, BlockLegacyMetadata::PRISMARINE_BRICKS), "Prismarine Bricks", $prismarineBreakInfo)); - self::register(new Stair(new BID(BlockLegacyIds::PRISMARINE_BRICKS_STAIRS), "Prismarine Bricks Stairs", $prismarineBreakInfo)); - self::register(new Solid(new BID(BlockLegacyIds::PRISMARINE, BlockLegacyMetadata::PRISMARINE_DARK), "Dark Prismarine", $prismarineBreakInfo)); - self::register(new Stair(new BID(BlockLegacyIds::DARK_PRISMARINE_STAIRS), "Dark Prismarine Stairs", $prismarineBreakInfo)); - self::register(new Solid(new BID(BlockLegacyIds::PRISMARINE, BlockLegacyMetadata::PRISMARINE_NORMAL), "Prismarine", $prismarineBreakInfo)); - self::register(new Stair(new BID(BlockLegacyIds::PRISMARINE_STAIRS), "Prismarine Stairs", $prismarineBreakInfo)); + self::register(new Solid(new BID(Ids::PRISMARINE, Meta::PRISMARINE_BRICKS), "Prismarine Bricks", $prismarineBreakInfo)); + self::register(new Stair(new BID(Ids::PRISMARINE_BRICKS_STAIRS), "Prismarine Bricks Stairs", $prismarineBreakInfo)); + self::register(new Solid(new BID(Ids::PRISMARINE, Meta::PRISMARINE_DARK), "Dark Prismarine", $prismarineBreakInfo)); + self::register(new Stair(new BID(Ids::DARK_PRISMARINE_STAIRS), "Dark Prismarine Stairs", $prismarineBreakInfo)); + self::register(new Solid(new BID(Ids::PRISMARINE, Meta::PRISMARINE_NORMAL), "Prismarine", $prismarineBreakInfo)); + self::register(new Stair(new BID(Ids::PRISMARINE_STAIRS), "Prismarine Stairs", $prismarineBreakInfo)); - self::register(new Pumpkin(new BID(BlockLegacyIds::PUMPKIN), "Pumpkin")); - self::register(new PumpkinStem(new BID(BlockLegacyIds::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem")); + self::register(new Pumpkin(new BID(Ids::PUMPKIN), "Pumpkin")); + self::register(new PumpkinStem(new BID(Ids::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem")); $purpurBreakInfo = new BlockBreakInfo(1.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0); - self::register(new Solid(new BID(BlockLegacyIds::PURPUR_BLOCK, BlockLegacyMetadata::PURPUR_NORMAL), "Purpur Block", $purpurBreakInfo)); - self::register(new class(new BID(BlockLegacyIds::PURPUR_BLOCK, BlockLegacyMetadata::PURPUR_PILLAR), "Purpur Pillar", $purpurBreakInfo) extends Solid{ + self::register(new Solid(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_NORMAL), "Purpur Block", $purpurBreakInfo)); + self::register(new class(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_PILLAR), "Purpur Pillar", $purpurBreakInfo) extends Solid{ use PillarRotationTrait; }); - self::register(new Stair(new BID(BlockLegacyIds::PURPUR_STAIRS), "Purpur Stairs", $purpurBreakInfo)); + self::register(new Stair(new BID(Ids::PURPUR_STAIRS), "Purpur Stairs", $purpurBreakInfo)); $quartzBreakInfo = new BlockBreakInfo(0.8, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN); - self::register(new Solid(new BID(BlockLegacyIds::QUARTZ_BLOCK, BlockLegacyMetadata::QUARTZ_NORMAL), "Quartz Block", $quartzBreakInfo)); - self::register(new Stair(new BID(BlockLegacyIds::QUARTZ_STAIRS), "Quartz Stairs", $quartzBreakInfo)); - self::register(new class(new BID(BlockLegacyIds::QUARTZ_BLOCK, BlockLegacyMetadata::QUARTZ_CHISELED), "Chiseled Quartz Block", $quartzBreakInfo) extends Solid{ + self::register(new Solid(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_NORMAL), "Quartz Block", $quartzBreakInfo)); + self::register(new Stair(new BID(Ids::QUARTZ_STAIRS), "Quartz Stairs", $quartzBreakInfo)); + self::register(new class(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_CHISELED), "Chiseled Quartz Block", $quartzBreakInfo) extends Solid{ use PillarRotationTrait; }); - self::register(new class(new BID(BlockLegacyIds::QUARTZ_BLOCK, BlockLegacyMetadata::QUARTZ_PILLAR), "Quartz Pillar", $quartzBreakInfo) extends Solid{ + self::register(new class(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_PILLAR), "Quartz Pillar", $quartzBreakInfo) extends Solid{ use PillarRotationTrait; }); - self::register(new Solid(new BID(BlockLegacyIds::QUARTZ_BLOCK, BlockLegacyMetadata::QUARTZ_SMOOTH), "Smooth Quartz Block", $quartzBreakInfo)); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) - self::register(new Stair(new BID(BlockLegacyIds::SMOOTH_QUARTZ_STAIRS), "Smooth Quartz Stairs", $quartzBreakInfo)); + self::register(new Solid(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_SMOOTH), "Smooth Quartz Block", $quartzBreakInfo)); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) + self::register(new Stair(new BID(Ids::SMOOTH_QUARTZ_STAIRS), "Smooth Quartz Stairs", $quartzBreakInfo)); - self::register(new Rail(new BID(BlockLegacyIds::RAIL), "Rail")); - self::register(new RedMushroom(new BID(BlockLegacyIds::RED_MUSHROOM), "Red Mushroom")); - self::register(new RedMushroomBlock(new BID(BlockLegacyIds::RED_MUSHROOM_BLOCK), "Red Mushroom Block")); - self::register(new Redstone(new BID(BlockLegacyIds::REDSTONE_BLOCK), "Redstone Block")); - self::register(new RedstoneComparator(new BlockIdentifierFlattened(BlockLegacyIds::UNPOWERED_COMPARATOR, BlockLegacyIds::POWERED_COMPARATOR, 0, ItemIds::COMPARATOR, TileComparator::class), "Redstone Comparator")); - self::register(new RedstoneLamp(new BlockIdentifierFlattened(BlockLegacyIds::REDSTONE_LAMP, BlockLegacyIds::LIT_REDSTONE_LAMP), "Redstone Lamp")); - self::register(new RedstoneOre(new BlockIdentifierFlattened(BlockLegacyIds::REDSTONE_ORE, BlockLegacyIds::LIT_REDSTONE_ORE), "Redstone Ore")); - self::register(new RedstoneRepeater(new BlockIdentifierFlattened(BlockLegacyIds::UNPOWERED_REPEATER, BlockLegacyIds::POWERED_REPEATER, 0, ItemIds::REPEATER), "Redstone Repeater")); - self::register(new RedstoneTorch(new BlockIdentifierFlattened(BlockLegacyIds::REDSTONE_TORCH, BlockLegacyIds::UNLIT_REDSTONE_TORCH), "Redstone Torch")); - self::register(new RedstoneWire(new BID(BlockLegacyIds::REDSTONE_WIRE, 0, ItemIds::REDSTONE), "Redstone")); - self::register(new Reserved6(new BID(BlockLegacyIds::RESERVED6), "reserved6")); - self::register(new Sand(new BID(BlockLegacyIds::SAND), "Sand")); - self::register(new Sand(new BID(BlockLegacyIds::SAND, 1), "Red Sand")); - self::register(new SeaLantern(new BID(BlockLegacyIds::SEALANTERN), "Sea Lantern")); - self::register(new SeaPickle(new BID(BlockLegacyIds::SEA_PICKLE), "Sea Pickle")); - self::register(new Skull(new BID(BlockLegacyIds::MOB_HEAD_BLOCK, 0, null, TileSkull::class), "Mob Head")); + self::register(new Rail(new BID(Ids::RAIL), "Rail")); + self::register(new RedMushroom(new BID(Ids::RED_MUSHROOM), "Red Mushroom")); + self::register(new RedMushroomBlock(new BID(Ids::RED_MUSHROOM_BLOCK), "Red Mushroom Block")); + self::register(new Redstone(new BID(Ids::REDSTONE_BLOCK), "Redstone Block")); + self::register(new RedstoneComparator(new BIDFlattened(Ids::UNPOWERED_COMPARATOR, Ids::POWERED_COMPARATOR, 0, ItemIds::COMPARATOR, TileComparator::class), "Redstone Comparator")); + self::register(new RedstoneLamp(new BIDFlattened(Ids::REDSTONE_LAMP, Ids::LIT_REDSTONE_LAMP), "Redstone Lamp")); + self::register(new RedstoneOre(new BIDFlattened(Ids::REDSTONE_ORE, Ids::LIT_REDSTONE_ORE), "Redstone Ore")); + self::register(new RedstoneRepeater(new BIDFlattened(Ids::UNPOWERED_REPEATER, Ids::POWERED_REPEATER, 0, ItemIds::REPEATER), "Redstone Repeater")); + self::register(new RedstoneTorch(new BIDFlattened(Ids::REDSTONE_TORCH, Ids::UNLIT_REDSTONE_TORCH), "Redstone Torch")); + self::register(new RedstoneWire(new BID(Ids::REDSTONE_WIRE, 0, ItemIds::REDSTONE), "Redstone")); + self::register(new Reserved6(new BID(Ids::RESERVED6), "reserved6")); + self::register(new Sand(new BID(Ids::SAND), "Sand")); + self::register(new Sand(new BID(Ids::SAND, 1), "Red Sand")); + self::register(new SeaLantern(new BID(Ids::SEALANTERN), "Sea Lantern")); + self::register(new SeaPickle(new BID(Ids::SEA_PICKLE), "Sea Pickle")); + self::register(new Skull(new BID(Ids::MOB_HEAD_BLOCK, 0, null, TileSkull::class), "Mob Head")); - self::register(new Snow(new BID(BlockLegacyIds::SNOW), "Snow Block")); - self::register(new SnowLayer(new BID(BlockLegacyIds::SNOW_LAYER), "Snow Layer")); - self::register(new SoulSand(new BID(BlockLegacyIds::SOUL_SAND), "Soul Sand")); - self::register(new Sponge(new BID(BlockLegacyIds::SPONGE), "Sponge")); + self::register(new Snow(new BID(Ids::SNOW), "Snow Block")); + self::register(new SnowLayer(new BID(Ids::SNOW_LAYER), "Snow Layer")); + self::register(new SoulSand(new BID(Ids::SOUL_SAND), "Soul Sand")); + self::register(new Sponge(new BID(Ids::SPONGE), "Sponge")); $stoneBreakInfo = new BlockBreakInfo(1.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0); - self::register(new class(new BID(BlockLegacyIds::STONE, BlockLegacyMetadata::STONE_NORMAL), "Stone", $stoneBreakInfo) extends Solid{ + self::register(new class(new BID(Ids::STONE, Meta::STONE_NORMAL), "Stone", $stoneBreakInfo) extends Solid{ public function getDropsForCompatibleTool(Item $item) : array{ return [ItemFactory::get(Item::COBBLESTONE)]; } }); - self::register(new Stair(new BID(BlockLegacyIds::NORMAL_STONE_STAIRS), "Stone Stairs", $stoneBreakInfo)); - self::register(new Solid(new BID(BlockLegacyIds::SMOOTH_STONE), "Smooth Stone", $stoneBreakInfo)); - self::register(new Solid(new BID(BlockLegacyIds::STONE, BlockLegacyMetadata::STONE_ANDESITE), "Andesite", $stoneBreakInfo)); - self::register(new Stair(new BID(BlockLegacyIds::ANDESITE_STAIRS), "Andesite Stairs", $stoneBreakInfo)); - self::register(new Solid(new BID(BlockLegacyIds::STONE, BlockLegacyMetadata::STONE_DIORITE), "Diorite", $stoneBreakInfo)); - self::register(new Stair(new BID(BlockLegacyIds::DIORITE_STAIRS), "Diorite Stairs", $stoneBreakInfo)); - self::register(new Solid(new BID(BlockLegacyIds::STONE, BlockLegacyMetadata::STONE_GRANITE), "Granite", $stoneBreakInfo)); - self::register(new Stair(new BID(BlockLegacyIds::GRANITE_STAIRS), "Granite Stairs", $stoneBreakInfo)); - self::register(new Solid(new BID(BlockLegacyIds::STONE, BlockLegacyMetadata::STONE_POLISHED_ANDESITE), "Polished Andesite", $stoneBreakInfo)); - self::register(new Stair(new BID(BlockLegacyIds::POLISHED_ANDESITE_STAIRS), "Polished Andesite Stairs", $stoneBreakInfo)); - self::register(new Solid(new BID(BlockLegacyIds::STONE, BlockLegacyMetadata::STONE_POLISHED_DIORITE), "Polished Diorite", $stoneBreakInfo)); - self::register(new Stair(new BID(BlockLegacyIds::POLISHED_DIORITE_STAIRS), "Polished Diorite Stairs", $stoneBreakInfo)); - self::register(new Solid(new BID(BlockLegacyIds::STONE, BlockLegacyMetadata::STONE_POLISHED_GRANITE), "Polished Granite", $stoneBreakInfo)); - self::register(new Stair(new BID(BlockLegacyIds::POLISHED_GRANITE_STAIRS), "Polished Granite Stairs", $stoneBreakInfo)); - self::register(new Stair(new BID(BlockLegacyIds::STONE_BRICK_STAIRS), "Stone Brick Stairs", $stoneBreakInfo)); - self::register(new Solid(new BID(BlockLegacyIds::STONEBRICK, BlockLegacyMetadata::STONE_BRICK_CHISELED), "Chiseled Stone Bricks", $stoneBreakInfo)); - self::register(new Solid(new BID(BlockLegacyIds::STONEBRICK, BlockLegacyMetadata::STONE_BRICK_CRACKED), "Cracked Stone Bricks", $stoneBreakInfo)); - self::register(new Solid(new BID(BlockLegacyIds::STONEBRICK, BlockLegacyMetadata::STONE_BRICK_MOSSY), "Mossy Stone Bricks", $stoneBreakInfo)); - self::register(new Stair(new BID(BlockLegacyIds::MOSSY_STONE_BRICK_STAIRS), "Mossy Stone Brick Stairs", $stoneBreakInfo)); - self::register(new Solid(new BID(BlockLegacyIds::STONEBRICK, BlockLegacyMetadata::STONE_BRICK_NORMAL), "Stone Bricks", $stoneBreakInfo)); - self::register(new StoneButton(new BID(BlockLegacyIds::STONE_BUTTON), "Stone Button")); - self::register(new StonePressurePlate(new BID(BlockLegacyIds::STONE_PRESSURE_PLATE), "Stone Pressure Plate")); + self::register(new Stair(new BID(Ids::NORMAL_STONE_STAIRS), "Stone Stairs", $stoneBreakInfo)); + self::register(new Solid(new BID(Ids::SMOOTH_STONE), "Smooth Stone", $stoneBreakInfo)); + self::register(new Solid(new BID(Ids::STONE, Meta::STONE_ANDESITE), "Andesite", $stoneBreakInfo)); + self::register(new Stair(new BID(Ids::ANDESITE_STAIRS), "Andesite Stairs", $stoneBreakInfo)); + self::register(new Solid(new BID(Ids::STONE, Meta::STONE_DIORITE), "Diorite", $stoneBreakInfo)); + self::register(new Stair(new BID(Ids::DIORITE_STAIRS), "Diorite Stairs", $stoneBreakInfo)); + self::register(new Solid(new BID(Ids::STONE, Meta::STONE_GRANITE), "Granite", $stoneBreakInfo)); + self::register(new Stair(new BID(Ids::GRANITE_STAIRS), "Granite Stairs", $stoneBreakInfo)); + self::register(new Solid(new BID(Ids::STONE, Meta::STONE_POLISHED_ANDESITE), "Polished Andesite", $stoneBreakInfo)); + self::register(new Stair(new BID(Ids::POLISHED_ANDESITE_STAIRS), "Polished Andesite Stairs", $stoneBreakInfo)); + self::register(new Solid(new BID(Ids::STONE, Meta::STONE_POLISHED_DIORITE), "Polished Diorite", $stoneBreakInfo)); + self::register(new Stair(new BID(Ids::POLISHED_DIORITE_STAIRS), "Polished Diorite Stairs", $stoneBreakInfo)); + self::register(new Solid(new BID(Ids::STONE, Meta::STONE_POLISHED_GRANITE), "Polished Granite", $stoneBreakInfo)); + self::register(new Stair(new BID(Ids::POLISHED_GRANITE_STAIRS), "Polished Granite Stairs", $stoneBreakInfo)); + self::register(new Stair(new BID(Ids::STONE_BRICK_STAIRS), "Stone Brick Stairs", $stoneBreakInfo)); + self::register(new Solid(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CHISELED), "Chiseled Stone Bricks", $stoneBreakInfo)); + self::register(new Solid(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CRACKED), "Cracked Stone Bricks", $stoneBreakInfo)); + self::register(new Solid(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_MOSSY), "Mossy Stone Bricks", $stoneBreakInfo)); + self::register(new Stair(new BID(Ids::MOSSY_STONE_BRICK_STAIRS), "Mossy Stone Brick Stairs", $stoneBreakInfo)); + self::register(new Solid(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_NORMAL), "Stone Bricks", $stoneBreakInfo)); + self::register(new StoneButton(new BID(Ids::STONE_BUTTON), "Stone Button")); + self::register(new StonePressurePlate(new BID(Ids::STONE_PRESSURE_PLATE), "Stone Pressure Plate")); //TODO: in the future this won't be the same for all the types $stoneSlabBreakInfo = new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, BlockLegacyMetadata::STONE_SLAB_BRICK), "Brick", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, BlockLegacyMetadata::STONE_SLAB_COBBLESTONE), "Cobblestone", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, BlockLegacyMetadata::STONE_SLAB_FAKE_WOODEN), "Fake Wooden", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, BlockLegacyMetadata::STONE_SLAB_NETHER_BRICK), "Nether Brick", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, BlockLegacyMetadata::STONE_SLAB_QUARTZ), "Quartz", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, BlockLegacyMetadata::STONE_SLAB_SANDSTONE), "Sandstone", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, BlockLegacyMetadata::STONE_SLAB_SMOOTH_STONE), "Smooth Stone", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB, BlockLegacyIds::DOUBLE_STONE_SLAB, BlockLegacyMetadata::STONE_SLAB_STONE_BRICK), "Stone Brick", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, BlockLegacyMetadata::STONE_SLAB2_DARK_PRISMARINE), "Dark Prismarine", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, BlockLegacyMetadata::STONE_SLAB2_MOSSY_COBBLESTONE), "Mossy Cobblestone", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, BlockLegacyMetadata::STONE_SLAB2_PRISMARINE), "Prismarine", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, BlockLegacyMetadata::STONE_SLAB2_PRISMARINE_BRICKS), "Prismarine Bricks", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, BlockLegacyMetadata::STONE_SLAB2_PURPUR), "Purpur", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, BlockLegacyMetadata::STONE_SLAB2_RED_NETHER_BRICK), "Red Nether Brick", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, BlockLegacyMetadata::STONE_SLAB2_RED_SANDSTONE), "Red Sandstone", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB2, BlockLegacyIds::DOUBLE_STONE_SLAB2, BlockLegacyMetadata::STONE_SLAB2_SMOOTH_SANDSTONE), "Smooth Sandstone", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, BlockLegacyMetadata::STONE_SLAB3_ANDESITE), "Andesite", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, BlockLegacyMetadata::STONE_SLAB3_DIORITE), "Diorite", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, BlockLegacyMetadata::STONE_SLAB3_END_STONE_BRICK), "End Stone Brick", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, BlockLegacyMetadata::STONE_SLAB3_GRANITE), "Granite", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, BlockLegacyMetadata::STONE_SLAB3_POLISHED_ANDESITE), "Polished Andesite", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, BlockLegacyMetadata::STONE_SLAB3_POLISHED_DIORITE), "Polished Diorite", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, BlockLegacyMetadata::STONE_SLAB3_POLISHED_GRANITE), "Polished Granite", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB3, BlockLegacyIds::DOUBLE_STONE_SLAB3, BlockLegacyMetadata::STONE_SLAB3_SMOOTH_RED_SANDSTONE), "Smooth Red Sandstone", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB4, BlockLegacyIds::DOUBLE_STONE_SLAB4, BlockLegacyMetadata::STONE_SLAB4_CUT_RED_SANDSTONE), "Cut Red Sandstone", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB4, BlockLegacyIds::DOUBLE_STONE_SLAB4, BlockLegacyMetadata::STONE_SLAB4_CUT_SANDSTONE), "Cut Sandstone", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB4, BlockLegacyIds::DOUBLE_STONE_SLAB4, BlockLegacyMetadata::STONE_SLAB4_MOSSY_STONE_BRICK), "Mossy Stone Brick", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB4, BlockLegacyIds::DOUBLE_STONE_SLAB4, BlockLegacyMetadata::STONE_SLAB4_SMOOTH_QUARTZ), "Smooth Quartz", $stoneSlabBreakInfo)); - self::register(new Slab(new BlockIdentifierFlattened(BlockLegacyIds::STONE_SLAB4, BlockLegacyIds::DOUBLE_STONE_SLAB4, BlockLegacyMetadata::STONE_SLAB4_STONE), "Stone", $stoneSlabBreakInfo)); - self::register(new Solid(new BID(BlockLegacyIds::STONECUTTER), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN))); - self::register(new Sugarcane(new BID(BlockLegacyIds::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane")); - self::register(new TNT(new BID(BlockLegacyIds::TNT), "TNT")); - self::register(new TallGrass(new BID(BlockLegacyIds::TALLGRASS), "Fern")); //TODO: remap this to normal fern - self::register(new TallGrass(new BID(BlockLegacyIds::TALLGRASS, BlockLegacyMetadata::TALLGRASS_NORMAL), "Tall Grass")); - self::register(new TallGrass(new BID(BlockLegacyIds::TALLGRASS, BlockLegacyMetadata::TALLGRASS_FERN), "Fern")); - self::register(new TallGrass(new BID(BlockLegacyIds::TALLGRASS, 3), "Fern")); //TODO: remap this to normal fern - self::register(new Torch(new BID(BlockLegacyIds::COLORED_TORCH_BP), "Blue Torch")); - self::register(new Torch(new BID(BlockLegacyIds::COLORED_TORCH_BP, 8), "Purple Torch")); - self::register(new Torch(new BID(BlockLegacyIds::COLORED_TORCH_RG), "Red Torch")); - self::register(new Torch(new BID(BlockLegacyIds::COLORED_TORCH_RG, 8), "Green Torch")); - self::register(new Torch(new BID(BlockLegacyIds::TORCH), "Torch")); - self::register(new TrappedChest(new BID(BlockLegacyIds::TRAPPED_CHEST, 0, null, TileChest::class), "Trapped Chest")); - self::register(new Tripwire(new BID(BlockLegacyIds::TRIPWIRE, 0, ItemIds::STRING), "Tripwire")); - self::register(new TripwireHook(new BID(BlockLegacyIds::TRIPWIRE_HOOK), "Tripwire Hook")); - self::register(new UnderwaterTorch(new BID(BlockLegacyIds::UNDERWATER_TORCH), "Underwater Torch")); - self::register(new Vine(new BID(BlockLegacyIds::VINE), "Vines")); - self::register(new Water(new BlockIdentifierFlattened(BlockLegacyIds::FLOWING_WATER, BlockLegacyIds::STILL_WATER), "Water")); - self::register(new WaterLily(new BID(BlockLegacyIds::LILY_PAD), "Lily Pad")); - self::register(new WeightedPressurePlateHeavy(new BID(BlockLegacyIds::HEAVY_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Heavy")); - self::register(new WeightedPressurePlateLight(new BID(BlockLegacyIds::LIGHT_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Light")); - self::register(new Wheat(new BID(BlockLegacyIds::WHEAT_BLOCK), "Wheat Block")); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_BRICK), "Brick", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_COBBLESTONE), "Cobblestone", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_FAKE_WOODEN), "Fake Wooden", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_NETHER_BRICK), "Nether Brick", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_QUARTZ), "Quartz", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_SANDSTONE), "Sandstone", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_SMOOTH_STONE), "Smooth Stone", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_STONE_BRICK), "Stone Brick", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_DARK_PRISMARINE), "Dark Prismarine", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_MOSSY_COBBLESTONE), "Mossy Cobblestone", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_PRISMARINE), "Prismarine", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_PRISMARINE_BRICKS), "Prismarine Bricks", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_PURPUR), "Purpur", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_RED_NETHER_BRICK), "Red Nether Brick", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_RED_SANDSTONE), "Red Sandstone", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_SMOOTH_SANDSTONE), "Smooth Sandstone", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_ANDESITE), "Andesite", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_DIORITE), "Diorite", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_END_STONE_BRICK), "End Stone Brick", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_GRANITE), "Granite", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_POLISHED_ANDESITE), "Polished Andesite", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_POLISHED_DIORITE), "Polished Diorite", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_POLISHED_GRANITE), "Polished Granite", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_SMOOTH_RED_SANDSTONE), "Smooth Red Sandstone", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_CUT_RED_SANDSTONE), "Cut Red Sandstone", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_CUT_SANDSTONE), "Cut Sandstone", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_MOSSY_STONE_BRICK), "Mossy Stone Brick", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_SMOOTH_QUARTZ), "Smooth Quartz", $stoneSlabBreakInfo)); + self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_STONE), "Stone", $stoneSlabBreakInfo)); + self::register(new Solid(new BID(Ids::STONECUTTER), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN))); + self::register(new Sugarcane(new BID(Ids::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane")); + self::register(new TNT(new BID(Ids::TNT), "TNT")); + self::register(new TallGrass(new BID(Ids::TALLGRASS), "Fern")); //TODO: remap this to normal fern + self::register(new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_NORMAL), "Tall Grass")); + self::register(new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_FERN), "Fern")); + self::register(new TallGrass(new BID(Ids::TALLGRASS, 3), "Fern")); //TODO: remap this to normal fern + self::register(new Torch(new BID(Ids::COLORED_TORCH_BP), "Blue Torch")); + self::register(new Torch(new BID(Ids::COLORED_TORCH_BP, 8), "Purple Torch")); + self::register(new Torch(new BID(Ids::COLORED_TORCH_RG), "Red Torch")); + self::register(new Torch(new BID(Ids::COLORED_TORCH_RG, 8), "Green Torch")); + self::register(new Torch(new BID(Ids::TORCH), "Torch")); + self::register(new TrappedChest(new BID(Ids::TRAPPED_CHEST, 0, null, TileChest::class), "Trapped Chest")); + self::register(new Tripwire(new BID(Ids::TRIPWIRE, 0, ItemIds::STRING), "Tripwire")); + self::register(new TripwireHook(new BID(Ids::TRIPWIRE_HOOK), "Tripwire Hook")); + self::register(new UnderwaterTorch(new BID(Ids::UNDERWATER_TORCH), "Underwater Torch")); + self::register(new Vine(new BID(Ids::VINE), "Vines")); + self::register(new Water(new BIDFlattened(Ids::FLOWING_WATER, Ids::STILL_WATER), "Water")); + self::register(new WaterLily(new BID(Ids::LILY_PAD), "Lily Pad")); + self::register(new WeightedPressurePlateHeavy(new BID(Ids::HEAVY_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Heavy")); + self::register(new WeightedPressurePlateLight(new BID(Ids::LIGHT_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Light")); + self::register(new Wheat(new BID(Ids::WHEAT_BLOCK), "Wheat Block")); //region ugly treetype -> blockID mapping tables /** @var int[]|\SplObjectStorage $woodenStairIds */ $woodenStairIds = new \SplObjectStorage(); - $woodenStairIds[TreeType::OAK()] = BlockLegacyIds::OAK_STAIRS; - $woodenStairIds[TreeType::SPRUCE()] = BlockLegacyIds::SPRUCE_STAIRS; - $woodenStairIds[TreeType::BIRCH()] = BlockLegacyIds::BIRCH_STAIRS; - $woodenStairIds[TreeType::JUNGLE()] = BlockLegacyIds::JUNGLE_STAIRS; - $woodenStairIds[TreeType::ACACIA()] = BlockLegacyIds::ACACIA_STAIRS; - $woodenStairIds[TreeType::DARK_OAK()] = BlockLegacyIds::DARK_OAK_STAIRS; + $woodenStairIds[TreeType::OAK()] = Ids::OAK_STAIRS; + $woodenStairIds[TreeType::SPRUCE()] = Ids::SPRUCE_STAIRS; + $woodenStairIds[TreeType::BIRCH()] = Ids::BIRCH_STAIRS; + $woodenStairIds[TreeType::JUNGLE()] = Ids::JUNGLE_STAIRS; + $woodenStairIds[TreeType::ACACIA()] = Ids::ACACIA_STAIRS; + $woodenStairIds[TreeType::DARK_OAK()] = Ids::DARK_OAK_STAIRS; /** @var int[]|\SplObjectStorage $fenceGateIds */ $fenceGateIds = new \SplObjectStorage(); - $fenceGateIds[TreeType::OAK()] = BlockLegacyIds::OAK_FENCE_GATE; - $fenceGateIds[TreeType::SPRUCE()] = BlockLegacyIds::SPRUCE_FENCE_GATE; - $fenceGateIds[TreeType::BIRCH()] = BlockLegacyIds::BIRCH_FENCE_GATE; - $fenceGateIds[TreeType::JUNGLE()] = BlockLegacyIds::JUNGLE_FENCE_GATE; - $fenceGateIds[TreeType::ACACIA()] = BlockLegacyIds::ACACIA_FENCE_GATE; - $fenceGateIds[TreeType::DARK_OAK()] = BlockLegacyIds::DARK_OAK_FENCE_GATE; + $fenceGateIds[TreeType::OAK()] = Ids::OAK_FENCE_GATE; + $fenceGateIds[TreeType::SPRUCE()] = Ids::SPRUCE_FENCE_GATE; + $fenceGateIds[TreeType::BIRCH()] = Ids::BIRCH_FENCE_GATE; + $fenceGateIds[TreeType::JUNGLE()] = Ids::JUNGLE_FENCE_GATE; + $fenceGateIds[TreeType::ACACIA()] = Ids::ACACIA_FENCE_GATE; + $fenceGateIds[TreeType::DARK_OAK()] = Ids::DARK_OAK_FENCE_GATE; /** @var BID[]|\SplObjectStorage $woodenDoorIds */ $woodenDoorIds = new \SplObjectStorage(); - $woodenDoorIds[TreeType::OAK()] = new BID(BlockLegacyIds::OAK_DOOR_BLOCK, 0, ItemIds::OAK_DOOR); - $woodenDoorIds[TreeType::SPRUCE()] = new BID(BlockLegacyIds::SPRUCE_DOOR_BLOCK, 0, ItemIds::SPRUCE_DOOR); - $woodenDoorIds[TreeType::BIRCH()] = new BID(BlockLegacyIds::BIRCH_DOOR_BLOCK, 0, ItemIds::BIRCH_DOOR); - $woodenDoorIds[TreeType::JUNGLE()] = new BID(BlockLegacyIds::JUNGLE_DOOR_BLOCK, 0, ItemIds::JUNGLE_DOOR); - $woodenDoorIds[TreeType::ACACIA()] = new BID(BlockLegacyIds::ACACIA_DOOR_BLOCK, 0, ItemIds::ACACIA_DOOR); - $woodenDoorIds[TreeType::DARK_OAK()] = new BID(BlockLegacyIds::DARK_OAK_DOOR_BLOCK, 0, ItemIds::DARK_OAK_DOOR); + $woodenDoorIds[TreeType::OAK()] = new BID(Ids::OAK_DOOR_BLOCK, 0, ItemIds::OAK_DOOR); + $woodenDoorIds[TreeType::SPRUCE()] = new BID(Ids::SPRUCE_DOOR_BLOCK, 0, ItemIds::SPRUCE_DOOR); + $woodenDoorIds[TreeType::BIRCH()] = new BID(Ids::BIRCH_DOOR_BLOCK, 0, ItemIds::BIRCH_DOOR); + $woodenDoorIds[TreeType::JUNGLE()] = new BID(Ids::JUNGLE_DOOR_BLOCK, 0, ItemIds::JUNGLE_DOOR); + $woodenDoorIds[TreeType::ACACIA()] = new BID(Ids::ACACIA_DOOR_BLOCK, 0, ItemIds::ACACIA_DOOR); + $woodenDoorIds[TreeType::DARK_OAK()] = new BID(Ids::DARK_OAK_DOOR_BLOCK, 0, ItemIds::DARK_OAK_DOOR); /** @var int[]|\SplObjectStorage $woodenPressurePlateIds */ $woodenPressurePlateIds = new \SplObjectStorage(); - $woodenPressurePlateIds[TreeType::OAK()] = BlockLegacyIds::WOODEN_PRESSURE_PLATE; - $woodenPressurePlateIds[TreeType::SPRUCE()] = BlockLegacyIds::SPRUCE_PRESSURE_PLATE; - $woodenPressurePlateIds[TreeType::BIRCH()] = BlockLegacyIds::BIRCH_PRESSURE_PLATE; - $woodenPressurePlateIds[TreeType::JUNGLE()] = BlockLegacyIds::JUNGLE_PRESSURE_PLATE; - $woodenPressurePlateIds[TreeType::ACACIA()] = BlockLegacyIds::ACACIA_PRESSURE_PLATE; - $woodenPressurePlateIds[TreeType::DARK_OAK()] = BlockLegacyIds::DARK_OAK_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::OAK()] = Ids::WOODEN_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::SPRUCE()] = Ids::SPRUCE_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::BIRCH()] = Ids::BIRCH_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::JUNGLE()] = Ids::JUNGLE_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::ACACIA()] = Ids::ACACIA_PRESSURE_PLATE; + $woodenPressurePlateIds[TreeType::DARK_OAK()] = Ids::DARK_OAK_PRESSURE_PLATE; /** @var int[]|\SplObjectStorage $woodenButtonIds */ $woodenButtonIds = new \SplObjectStorage(); - $woodenButtonIds[TreeType::OAK()] = BlockLegacyIds::WOODEN_BUTTON; - $woodenButtonIds[TreeType::SPRUCE()] = BlockLegacyIds::SPRUCE_BUTTON; - $woodenButtonIds[TreeType::BIRCH()] = BlockLegacyIds::BIRCH_BUTTON; - $woodenButtonIds[TreeType::JUNGLE()] = BlockLegacyIds::JUNGLE_BUTTON; - $woodenButtonIds[TreeType::ACACIA()] = BlockLegacyIds::ACACIA_BUTTON; - $woodenButtonIds[TreeType::DARK_OAK()] = BlockLegacyIds::DARK_OAK_BUTTON; + $woodenButtonIds[TreeType::OAK()] = Ids::WOODEN_BUTTON; + $woodenButtonIds[TreeType::SPRUCE()] = Ids::SPRUCE_BUTTON; + $woodenButtonIds[TreeType::BIRCH()] = Ids::BIRCH_BUTTON; + $woodenButtonIds[TreeType::JUNGLE()] = Ids::JUNGLE_BUTTON; + $woodenButtonIds[TreeType::ACACIA()] = Ids::ACACIA_BUTTON; + $woodenButtonIds[TreeType::DARK_OAK()] = Ids::DARK_OAK_BUTTON; /** @var int[]|\SplObjectStorage $woodenTrapdoorIds */ $woodenTrapdoorIds = new \SplObjectStorage(); - $woodenTrapdoorIds[TreeType::OAK()] = BlockLegacyIds::WOODEN_TRAPDOOR; - $woodenTrapdoorIds[TreeType::SPRUCE()] = BlockLegacyIds::SPRUCE_TRAPDOOR; - $woodenTrapdoorIds[TreeType::BIRCH()] = BlockLegacyIds::BIRCH_TRAPDOOR; - $woodenTrapdoorIds[TreeType::JUNGLE()] = BlockLegacyIds::JUNGLE_TRAPDOOR; - $woodenTrapdoorIds[TreeType::ACACIA()] = BlockLegacyIds::ACACIA_TRAPDOOR; - $woodenTrapdoorIds[TreeType::DARK_OAK()] = BlockLegacyIds::DARK_OAK_TRAPDOOR; + $woodenTrapdoorIds[TreeType::OAK()] = Ids::WOODEN_TRAPDOOR; + $woodenTrapdoorIds[TreeType::SPRUCE()] = Ids::SPRUCE_TRAPDOOR; + $woodenTrapdoorIds[TreeType::BIRCH()] = Ids::BIRCH_TRAPDOOR; + $woodenTrapdoorIds[TreeType::JUNGLE()] = Ids::JUNGLE_TRAPDOOR; + $woodenTrapdoorIds[TreeType::ACACIA()] = Ids::ACACIA_TRAPDOOR; + $woodenTrapdoorIds[TreeType::DARK_OAK()] = Ids::DARK_OAK_TRAPDOOR; - /** @var BlockIdentifierFlattened[]|\SplObjectStorage $woodenSignIds */ + /** @var BIDFlattened[]|\SplObjectStorage $woodenSignIds */ $woodenSignIds = new \SplObjectStorage(); - $woodenSignIds[TreeType::OAK()] = new BlockIdentifierFlattened(BlockLegacyIds::SIGN_POST, BlockLegacyIds::WALL_SIGN, 0, ItemIds::SIGN, TileSign::class); - $woodenSignIds[TreeType::SPRUCE()] = new BlockIdentifierFlattened(BlockLegacyIds::SPRUCE_STANDING_SIGN, BlockLegacyIds::SPRUCE_WALL_SIGN, 0, ItemIds::SPRUCE_SIGN, TileSign::class); - $woodenSignIds[TreeType::BIRCH()] = new BlockIdentifierFlattened(BlockLegacyIds::BIRCH_STANDING_SIGN, BlockLegacyIds::BIRCH_WALL_SIGN, 0, ItemIds::BIRCH_SIGN, TileSign::class); - $woodenSignIds[TreeType::JUNGLE()] = new BlockIdentifierFlattened(BlockLegacyIds::JUNGLE_STANDING_SIGN, BlockLegacyIds::JUNGLE_WALL_SIGN, 0, ItemIds::JUNGLE_SIGN, TileSign::class); - $woodenSignIds[TreeType::ACACIA()] = new BlockIdentifierFlattened(BlockLegacyIds::ACACIA_STANDING_SIGN, BlockLegacyIds::ACACIA_WALL_SIGN, 0, ItemIds::ACACIA_SIGN, TileSign::class); - $woodenSignIds[TreeType::DARK_OAK()] = new BlockIdentifierFlattened(BlockLegacyIds::DARKOAK_STANDING_SIGN, BlockLegacyIds::DARKOAK_WALL_SIGN, 0, ItemIds::DARKOAK_SIGN, TileSign::class); + $woodenSignIds[TreeType::OAK()] = new BIDFlattened(Ids::SIGN_POST, Ids::WALL_SIGN, 0, ItemIds::SIGN, TileSign::class); + $woodenSignIds[TreeType::SPRUCE()] = new BIDFlattened(Ids::SPRUCE_STANDING_SIGN, Ids::SPRUCE_WALL_SIGN, 0, ItemIds::SPRUCE_SIGN, TileSign::class); + $woodenSignIds[TreeType::BIRCH()] = new BIDFlattened(Ids::BIRCH_STANDING_SIGN, Ids::BIRCH_WALL_SIGN, 0, ItemIds::BIRCH_SIGN, TileSign::class); + $woodenSignIds[TreeType::JUNGLE()] = new BIDFlattened(Ids::JUNGLE_STANDING_SIGN, Ids::JUNGLE_WALL_SIGN, 0, ItemIds::JUNGLE_SIGN, TileSign::class); + $woodenSignIds[TreeType::ACACIA()] = new BIDFlattened(Ids::ACACIA_STANDING_SIGN, Ids::ACACIA_WALL_SIGN, 0, ItemIds::ACACIA_SIGN, TileSign::class); + $woodenSignIds[TreeType::DARK_OAK()] = new BIDFlattened(Ids::DARKOAK_STANDING_SIGN, Ids::DARKOAK_WALL_SIGN, 0, ItemIds::DARKOAK_SIGN, TileSign::class); //endregion foreach(TreeType::getAll() as $treeType){ $magicNumber = $treeType->getMagicNumber(); $name = $treeType->getDisplayName(); - self::register(new Planks(new BID(BlockLegacyIds::PLANKS, $magicNumber), $name . " Planks")); - self::register(new Sapling(new BID(BlockLegacyIds::SAPLING, $magicNumber), $name . " Sapling", $treeType)); - self::register(new WoodenFence(new BID(BlockLegacyIds::FENCE, $magicNumber), $name . " Fence")); - self::register(new WoodenSlab(new BlockIdentifierFlattened(BlockLegacyIds::WOODEN_SLAB, BlockLegacyIds::DOUBLE_WOODEN_SLAB, $treeType->getMagicNumber()), $treeType->getDisplayName())); + self::register(new Planks(new BID(Ids::PLANKS, $magicNumber), $name . " Planks")); + self::register(new Sapling(new BID(Ids::SAPLING, $magicNumber), $name . " Sapling", $treeType)); + self::register(new WoodenFence(new BID(Ids::FENCE, $magicNumber), $name . " Fence")); + self::register(new WoodenSlab(new BIDFlattened(Ids::WOODEN_SLAB, Ids::DOUBLE_WOODEN_SLAB, $treeType->getMagicNumber()), $treeType->getDisplayName())); //TODO: find a better way to deal with this split - self::register(new Leaves(new BID($magicNumber >= 4 ? BlockLegacyIds::LEAVES2 : BlockLegacyIds::LEAVES, $magicNumber & 0x03), $name . " Leaves", $treeType)); - self::register(new Log(new BID($magicNumber >= 4 ? BlockLegacyIds::LOG2 : BlockLegacyIds::LOG, $magicNumber & 0x03), $name . " Log", $treeType)); + self::register(new Leaves(new BID($magicNumber >= 4 ? Ids::LEAVES2 : Ids::LEAVES, $magicNumber & 0x03), $name . " Leaves", $treeType)); + self::register(new Log(new BID($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, $magicNumber & 0x03), $name . " Log", $treeType)); //TODO: the old bug-block needs to be remapped to the new dedicated block - self::register(new Wood(new BID($magicNumber >= 4 ? BlockLegacyIds::LOG2 : BlockLegacyIds::LOG, ($magicNumber & 0x03) | 0b1100), $name . " Wood", $treeType)); - self::register(new Wood(new BID(BlockLegacyIds::WOOD, $magicNumber), $name . " Wood", $treeType)); + self::register(new Wood(new BID($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, ($magicNumber & 0x03) | 0b1100), $name . " Wood", $treeType)); + self::register(new Wood(new BID(Ids::WOOD, $magicNumber), $name . " Wood", $treeType)); self::register(new FenceGate(new BID($fenceGateIds[$treeType]), $treeType->getDisplayName() . " Fence Gate")); self::register(new WoodenStairs(new BID($woodenStairIds[$treeType]), $treeType->getDisplayName() . " Stairs")); @@ -476,73 +479,73 @@ class BlockFactory{ } static $sandstoneTypes = [ - BlockLegacyMetadata::SANDSTONE_NORMAL => "", - BlockLegacyMetadata::SANDSTONE_CHISELED => "Chiseled ", - BlockLegacyMetadata::SANDSTONE_CUT => "Cut ", - BlockLegacyMetadata::SANDSTONE_SMOOTH => "Smooth " + Meta::SANDSTONE_NORMAL => "", + Meta::SANDSTONE_CHISELED => "Chiseled ", + Meta::SANDSTONE_CUT => "Cut ", + Meta::SANDSTONE_SMOOTH => "Smooth " ]; $sandstoneBreakInfo = new BlockBreakInfo(0.8, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN); - self::register(new Stair(new BID(BlockLegacyIds::RED_SANDSTONE_STAIRS), "Red Sandstone Stairs", $sandstoneBreakInfo)); - self::register(new Stair(new BID(BlockLegacyIds::SMOOTH_RED_SANDSTONE_STAIRS), "Smooth Red Sandstone Stairs", $sandstoneBreakInfo)); - self::register(new Stair(new BID(BlockLegacyIds::SANDSTONE_STAIRS), "Sandstone Stairs", $sandstoneBreakInfo)); - self::register(new Stair(new BID(BlockLegacyIds::SMOOTH_SANDSTONE_STAIRS), "Smooth Sandstone Stairs", $sandstoneBreakInfo)); + self::register(new Stair(new BID(Ids::RED_SANDSTONE_STAIRS), "Red Sandstone Stairs", $sandstoneBreakInfo)); + self::register(new Stair(new BID(Ids::SMOOTH_RED_SANDSTONE_STAIRS), "Smooth Red Sandstone Stairs", $sandstoneBreakInfo)); + self::register(new Stair(new BID(Ids::SANDSTONE_STAIRS), "Sandstone Stairs", $sandstoneBreakInfo)); + self::register(new Stair(new BID(Ids::SMOOTH_SANDSTONE_STAIRS), "Smooth Sandstone Stairs", $sandstoneBreakInfo)); foreach($sandstoneTypes as $variant => $prefix){ - self::register(new Solid(new BID(BlockLegacyIds::SANDSTONE, $variant), $prefix . "Sandstone", $sandstoneBreakInfo)); - self::register(new Solid(new BID(BlockLegacyIds::RED_SANDSTONE, $variant), $prefix . "Red Sandstone", $sandstoneBreakInfo)); + self::register(new Solid(new BID(Ids::SANDSTONE, $variant), $prefix . "Sandstone", $sandstoneBreakInfo)); + self::register(new Solid(new BID(Ids::RED_SANDSTONE, $variant), $prefix . "Red Sandstone", $sandstoneBreakInfo)); } //region ugly glazed-terracotta colour -> ID mapping table /** @var int[]|\SplObjectStorage $glazedTerracottaIds */ $glazedTerracottaIds = new \SplObjectStorage(); - $glazedTerracottaIds[DyeColor::WHITE()] = BlockLegacyIds::WHITE_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::ORANGE()] = BlockLegacyIds::ORANGE_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::MAGENTA()] = BlockLegacyIds::MAGENTA_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::LIGHT_BLUE()] = BlockLegacyIds::LIGHT_BLUE_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::YELLOW()] = BlockLegacyIds::YELLOW_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::LIME()] = BlockLegacyIds::LIME_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::PINK()] = BlockLegacyIds::PINK_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::GRAY()] = BlockLegacyIds::GRAY_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::LIGHT_GRAY()] = BlockLegacyIds::SILVER_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::CYAN()] = BlockLegacyIds::CYAN_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::PURPLE()] = BlockLegacyIds::PURPLE_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::BLUE()] = BlockLegacyIds::BLUE_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::BROWN()] = BlockLegacyIds::BROWN_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::GREEN()] = BlockLegacyIds::GREEN_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::RED()] = BlockLegacyIds::RED_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::BLACK()] = BlockLegacyIds::BLACK_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::WHITE()] = Ids::WHITE_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::ORANGE()] = Ids::ORANGE_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::MAGENTA()] = Ids::MAGENTA_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::LIGHT_BLUE()] = Ids::LIGHT_BLUE_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::YELLOW()] = Ids::YELLOW_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::LIME()] = Ids::LIME_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::PINK()] = Ids::PINK_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::GRAY()] = Ids::GRAY_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::LIGHT_GRAY()] = Ids::SILVER_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::CYAN()] = Ids::CYAN_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::PURPLE()] = Ids::PURPLE_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::BLUE()] = Ids::BLUE_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::BROWN()] = Ids::BROWN_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::GREEN()] = Ids::GREEN_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::RED()] = Ids::RED_GLAZED_TERRACOTTA; + $glazedTerracottaIds[DyeColor::BLACK()] = Ids::BLACK_GLAZED_TERRACOTTA; //endregion foreach(DyeColor::getAll() as $color){ - self::register(new Carpet(new BID(BlockLegacyIds::CARPET, $color->getMagicNumber()), $color->getDisplayName() . " Carpet")); - self::register(new Concrete(new BID(BlockLegacyIds::CONCRETE, $color->getMagicNumber()), $color->getDisplayName() . " Concrete")); - self::register(new ConcretePowder(new BID(BlockLegacyIds::CONCRETE_POWDER, $color->getMagicNumber()), $color->getDisplayName() . " Concrete Powder")); - self::register(new Glass(new BID(BlockLegacyIds::STAINED_GLASS, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass")); - self::register(new GlassPane(new BID(BlockLegacyIds::STAINED_GLASS_PANE, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass Pane")); + self::register(new Carpet(new BID(Ids::CARPET, $color->getMagicNumber()), $color->getDisplayName() . " Carpet")); + self::register(new Concrete(new BID(Ids::CONCRETE, $color->getMagicNumber()), $color->getDisplayName() . " Concrete")); + self::register(new ConcretePowder(new BID(Ids::CONCRETE_POWDER, $color->getMagicNumber()), $color->getDisplayName() . " Concrete Powder")); + self::register(new Glass(new BID(Ids::STAINED_GLASS, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass")); + self::register(new GlassPane(new BID(Ids::STAINED_GLASS_PANE, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass Pane")); self::register(new GlazedTerracotta(new BID($glazedTerracottaIds[$color]), $color->getDisplayName() . " Glazed Terracotta")); - self::register(new HardenedClay(new BID(BlockLegacyIds::STAINED_CLAY, $color->getMagicNumber()), $color->getDisplayName() . " Stained Clay")); - self::register(new HardenedGlass(new BID(BlockLegacyIds::HARD_STAINED_GLASS, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass")); - self::register(new HardenedGlassPane(new BID(BlockLegacyIds::HARD_STAINED_GLASS_PANE, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass Pane")); - self::register(new Wool(new BID(BlockLegacyIds::WOOL, $color->getMagicNumber()), $color->getDisplayName() . " Wool")); + self::register(new HardenedClay(new BID(Ids::STAINED_CLAY, $color->getMagicNumber()), $color->getDisplayName() . " Stained Clay")); + self::register(new HardenedGlass(new BID(Ids::HARD_STAINED_GLASS, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass")); + self::register(new HardenedGlassPane(new BID(Ids::HARD_STAINED_GLASS_PANE, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass Pane")); + self::register(new Wool(new BID(Ids::WOOL, $color->getMagicNumber()), $color->getDisplayName() . " Wool")); } static $wallTypes = [ - BlockLegacyMetadata::WALL_ANDESITE => "Andesite", - BlockLegacyMetadata::WALL_BRICK => "Brick", - BlockLegacyMetadata::WALL_DIORITE => "Diorite", - BlockLegacyMetadata::WALL_END_STONE_BRICK => "End Stone Brick", - BlockLegacyMetadata::WALL_GRANITE => "Granite", - BlockLegacyMetadata::WALL_MOSSY_STONE_BRICK => "Mossy Stone Brick", - BlockLegacyMetadata::WALL_MOSSY_COBBLESTONE => "Mossy Cobblestone", - BlockLegacyMetadata::WALL_NETHER_BRICK => "Nether Brick", - BlockLegacyMetadata::WALL_COBBLESTONE => "Cobblestone", - BlockLegacyMetadata::WALL_PRISMARINE => "Prismarine", - BlockLegacyMetadata::WALL_RED_NETHER_BRICK => "Red Nether Brick", - BlockLegacyMetadata::WALL_RED_SANDSTONE => "Red Sandstone", - BlockLegacyMetadata::WALL_SANDSTONE => "Sandstone", - BlockLegacyMetadata::WALL_STONE_BRICK => "Stone Brick" + Meta::WALL_ANDESITE => "Andesite", + Meta::WALL_BRICK => "Brick", + Meta::WALL_DIORITE => "Diorite", + Meta::WALL_END_STONE_BRICK => "End Stone Brick", + Meta::WALL_GRANITE => "Granite", + Meta::WALL_MOSSY_STONE_BRICK => "Mossy Stone Brick", + Meta::WALL_MOSSY_COBBLESTONE => "Mossy Cobblestone", + Meta::WALL_NETHER_BRICK => "Nether Brick", + Meta::WALL_COBBLESTONE => "Cobblestone", + Meta::WALL_PRISMARINE => "Prismarine", + Meta::WALL_RED_NETHER_BRICK => "Red Nether Brick", + Meta::WALL_RED_SANDSTONE => "Red Sandstone", + Meta::WALL_SANDSTONE => "Sandstone", + Meta::WALL_STONE_BRICK => "Stone Brick" ]; foreach($wallTypes as $magicNumber => $prefix){ - self::register(new Wall(new BID(BlockLegacyIds::COBBLESTONE_WALL, $magicNumber), $prefix . " Wall")); + self::register(new Wall(new BID(Ids::COBBLESTONE_WALL, $magicNumber), $prefix . " Wall")); } //region --- auto-generated TODOs --- From 685f5d562b9c3418850fa38768090840fa76265f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 26 May 2019 14:48:52 +0100 Subject: [PATCH 0843/3224] DoubleChestInventory: fixed use of void result --- src/pocketmine/inventory/DoubleChestInventory.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/inventory/DoubleChestInventory.php b/src/pocketmine/inventory/DoubleChestInventory.php index 086fc7f4dc..9ae689fe2d 100644 --- a/src/pocketmine/inventory/DoubleChestInventory.php +++ b/src/pocketmine/inventory/DoubleChestInventory.php @@ -85,15 +85,11 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ $items = array_slice($items, 0, $size, true); } - $leftSize = $this->left->getSize(); - for($i = 0; $i < $size; ++$i){ if(!isset($items[$i])){ - if(($i < $leftSize and isset($this->left->slots[$i])) or isset($this->right->slots[$i - $leftSize])){ - $this->clear($i, false); - } - }elseif(!$this->setItem($i, $items[$i], false)){ $this->clear($i, false); + }else{ + $this->setItem($i, $items[$i], false); } } From 32e03cd92d4554d151fde6bf2f24f843c8a8e655 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 26 May 2019 15:01:32 +0100 Subject: [PATCH 0844/3224] DoubleChestInventory: remove duplicated code --- src/pocketmine/inventory/BaseInventory.php | 4 +--- .../inventory/DoubleChestInventory.php | 24 ------------------- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index 9f46d8a054..09dbd24c25 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -113,9 +113,7 @@ abstract class BaseInventory implements Inventory{ for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ if(!isset($items[$i])){ - if($this->slots[$i] !== null){ - $this->clear($i, false); - } + $this->clear($i, false); }else{ $this->setItem($i, $items[$i], false); } diff --git a/src/pocketmine/inventory/DoubleChestInventory.php b/src/pocketmine/inventory/DoubleChestInventory.php index 9ae689fe2d..afa9a39d69 100644 --- a/src/pocketmine/inventory/DoubleChestInventory.php +++ b/src/pocketmine/inventory/DoubleChestInventory.php @@ -27,7 +27,6 @@ use pocketmine\block\tile\Chest; use pocketmine\item\Item; use pocketmine\Player; use function array_merge; -use function array_slice; use function count; class DoubleChestInventory extends ChestInventory implements InventoryHolder{ @@ -75,29 +74,6 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ return $result; } - /** - * @param Item[] $items - * @param bool $send - */ - public function setContents(array $items, bool $send = true) : void{ - $size = $this->getSize(); - if(count($items) > $size){ - $items = array_slice($items, 0, $size, true); - } - - for($i = 0; $i < $size; ++$i){ - if(!isset($items[$i])){ - $this->clear($i, false); - }else{ - $this->setItem($i, $items[$i], false); - } - } - - if($send){ - $this->sendContents($this->getViewers()); - } - } - protected function onOpen(Player $who) : void{ parent::onOpen($who); From 85718e2750cef94d6ce20ff877c3fa40a987adb7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 26 May 2019 15:43:46 +0100 Subject: [PATCH 0845/3224] Clean up a bunch of garbage in Furnace --- src/pocketmine/block/tile/Furnace.php | 26 ++++--------------- .../network/mcpe/NetworkSession.php | 12 +++++++++ 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/pocketmine/block/tile/Furnace.php b/src/pocketmine/block/tile/Furnace.php index c612e8213d..d1324777d9 100644 --- a/src/pocketmine/block/tile/Furnace.php +++ b/src/pocketmine/block/tile/Furnace.php @@ -207,32 +207,16 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ $this->burnTime = $this->cookTime = $this->maxTime = 0; } - /** @var ContainerSetDataPacket[] $packets */ - $packets = []; if($prevCookTime !== $this->cookTime){ - $pk = new ContainerSetDataPacket(); - $pk->property = ContainerSetDataPacket::PROPERTY_FURNACE_TICK_COUNT; - $pk->value = $this->cookTime; - $packets[] = $pk; + foreach($this->inventory->getViewers() as $v){ + $v->getNetworkSession()->syncInventoryData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_TICK_COUNT, $this->cookTime); + } } $fuelTicksLeft = $this->getFuelTicksLeft(); if($prevFuelTicksLeft !== $fuelTicksLeft){ - $pk = new ContainerSetDataPacket(); - $pk->property = ContainerSetDataPacket::PROPERTY_FURNACE_LIT_TIME; - $pk->value = $fuelTicksLeft; - $packets[] = $pk; - } - - if(!empty($packets)){ - foreach($this->getInventory()->getViewers() as $player){ - $windowId = $player->getWindowId($this->getInventory()); - if($windowId > 0){ - foreach($packets as $pk){ - $pk->windowId = $windowId; - $player->sendDataPacket(clone $pk); - } - } + foreach($this->inventory->getViewers() as $v){ + $v->getNetworkSession()->syncInventoryData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_LIT_TIME, $fuelTicksLeft); } } diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 8eeafc2bc1..b2327c5871 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -45,6 +45,7 @@ use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; +use pocketmine\network\mcpe\protocol\ContainerSetDataPacket; use pocketmine\network\mcpe\protocol\DisconnectPacket; use pocketmine\network\mcpe\protocol\InventoryContentPacket; use pocketmine\network\mcpe\protocol\InventorySlotPacket; @@ -818,6 +819,17 @@ class NetworkSession{ } } + public function syncInventoryData(Inventory $inventory, int $propertyId, int $value) : void{ + $windowId = $this->player->getWindowId($inventory); + if($windowId !== ContainerIds::NONE){ + $pk = new ContainerSetDataPacket(); + $pk->property = $propertyId; + $pk->value = $value; + $pk->windowId = $windowId; + $this->sendDataPacket($pk); + } + } + public function onMobArmorChange(Living $mob) : void{ $pk = new MobArmorEquipmentPacket(); $pk->entityRuntimeId = $mob->getId(); From 33d1203bfd670f446e4c8a30f211aa1f673d422a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 26 May 2019 15:58:03 +0100 Subject: [PATCH 0846/3224] Player: move sendAllInventories() to network layer --- src/pocketmine/Player.php | 11 ++++++----- src/pocketmine/network/mcpe/NetworkSession.php | 6 ++++++ .../network/mcpe/handler/InGameSessionHandler.php | 6 +++--- .../network/mcpe/handler/PreSpawnSessionHandler.php | 2 +- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 7d44ed42da..82b4cb2215 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2594,7 +2594,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->sendData($this->getViewers()); $this->networkSession->syncAdventureSettings($this); - $this->sendAllInventories(); + $this->networkSession->syncAllInventoryContents(); $this->spawnToAll(); $this->scheduleUpdate(); @@ -2878,10 +2878,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } - public function sendAllInventories(){ - foreach($this->windowIndex as $networkId => $inventory){ - $inventory->sendContents($this); - } + /** + * @return Inventory[] + */ + public function getAllWindows() : array{ + return $this->windowIndex; } public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue) : void{ diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index b2327c5871..4b7ee563cf 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -819,6 +819,12 @@ class NetworkSession{ } } + public function syncAllInventoryContents() : void{ + foreach($this->player->getAllWindows() as $inventory){ + $this->syncInventoryContents($inventory); + } + } + public function syncInventoryData(Inventory $inventory, int $propertyId, int $value) : void{ $windowId = $this->player->getWindowId($inventory); if($windowId !== ContainerIds::NONE){ diff --git a/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php b/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php index 6194820375..6393e48e66 100644 --- a/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php @@ -158,7 +158,7 @@ class InGameSessionHandler extends SessionHandler{ public function handleInventoryTransaction(InventoryTransactionPacket $packet) : bool{ if($this->player->isSpectator()){ - $this->player->sendAllInventories(); + $this->session->syncAllInventoryContents(); return true; } @@ -167,7 +167,7 @@ class InGameSessionHandler extends SessionHandler{ if($packet->trData instanceof NormalTransactionData){ $result = $this->handleNormalTransaction($packet->trData); }elseif($packet->trData instanceof MismatchTransactionData){ - $this->player->sendAllInventories(); + $this->session->syncAllInventoryContents(); $result = true; }elseif($packet->trData instanceof UseItemTransactionData){ $result = $this->handleUseItemTransaction($packet->trData); @@ -178,7 +178,7 @@ class InGameSessionHandler extends SessionHandler{ } if(!$result){ - $this->player->sendAllInventories(); + $this->session->syncAllInventoryContents(); } return $result; } diff --git a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php index 1d69a38d07..3659a55b95 100644 --- a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php @@ -91,7 +91,7 @@ class PreSpawnSessionHandler extends SessionHandler{ $this->player->sendPotionEffects($this->player); $this->player->sendData($this->player); - $this->player->sendAllInventories(); + $this->session->syncAllInventoryContents(); $this->player->getInventory()->sendCreativeContents(); $this->player->getInventory()->sendHeldItem($this->player); $this->session->queueCompressed($this->server->getCraftingManager()->getCraftingDataPacket()); From 2c40fbfe11d7548e7a08df387c57c6f80ea2d15e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 26 May 2019 16:27:20 +0100 Subject: [PATCH 0847/3224] add some TODOs for tiles --- src/pocketmine/block/tile/TileFactory.php | 29 +++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/pocketmine/block/tile/TileFactory.php b/src/pocketmine/block/tile/TileFactory.php index b87e0d4ef0..a84912ad68 100644 --- a/src/pocketmine/block/tile/TileFactory.php +++ b/src/pocketmine/block/tile/TileFactory.php @@ -57,6 +57,35 @@ final class TileFactory{ self::register(ItemFrame::class, ["ItemFrame"]); //this is an entity in PC self::register(Sign::class, ["Sign", "minecraft:sign"]); self::register(Skull::class, ["Skull", "minecraft:skull"]); + + //TODO: Barrel + //TODO: Beacon + //TODO: Bell + //TODO: BlastFurnace + //TODO: BrewingStand + //TODO: Campfire + //TODO: Cauldron + //TODO: ChalkboardBlock + //TODO: ChemistryTable + //TODO: CommandBlock + //TODO: Conduit + //TODO: DaylightDetector + //TODO: Dispenser + //TODO: Dropper + //TODO: EndGateway + //TODO: EndPortal + //TODO: Hopper + //TODO: JigsawBlock + //TODO: Jukebox + //TODO: Lectern + //TODO: MobSpawner + //TODO: MovingBlock + //TODO: Music + //TODO: NetherReactor + //TODO: PistonArm + //TODO: ShulkerBox + //TODO: Smoker + //TODO: StructureBlock } /** From e6048e115e85587015a07775b67b6955729df332 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 26 May 2019 18:01:24 +0100 Subject: [PATCH 0848/3224] leveldb: add more chunk versions --- src/pocketmine/world/format/io/leveldb/LevelDB.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pocketmine/world/format/io/leveldb/LevelDB.php b/src/pocketmine/world/format/io/leveldb/LevelDB.php index 0eae5a8c56..dd4a1660a9 100644 --- a/src/pocketmine/world/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/world/format/io/leveldb/LevelDB.php @@ -251,6 +251,11 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $binaryStream = new BinaryStream(); switch($chunkVersion){ + case 15: //MCPE 1.12.0.4 beta (???) + case 14: //MCPE 1.11.1.2 (???) + case 13: //MCPE 1.11.0.4 beta (???) + case 12: //MCPE 1.11.0.3 beta (???) + case 11: //MCPE 1.11.0.1 beta (???) case 10: //MCPE 1.9 (???) case 9: //MCPE 1.8 (???) case 7: //MCPE 1.2 (???) From c1a7d8667099c51adcc06990a5970932aa073948 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 26 May 2019 19:35:18 +0100 Subject: [PATCH 0849/3224] leveldb: more historical versions --- src/pocketmine/world/format/io/leveldb/LevelDB.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pocketmine/world/format/io/leveldb/LevelDB.php b/src/pocketmine/world/format/io/leveldb/LevelDB.php index dd4a1660a9..4c7a901961 100644 --- a/src/pocketmine/world/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/world/format/io/leveldb/LevelDB.php @@ -259,6 +259,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ case 10: //MCPE 1.9 (???) case 9: //MCPE 1.8 (???) case 7: //MCPE 1.2 (???) + case 6: //MCPE 1.2.0.2 beta (???) case 4: //MCPE 1.1 //TODO: check beds case 3: //MCPE 1.0 @@ -343,6 +344,8 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ } break; case 2: // < MCPE 1.0 + case 1: + case 0: //MCPE 0.9.0.1 beta (first version) /** @var PalettedBlockArray[] $extraDataLayers */ $convertedLegacyExtraData = $this->deserializeLegacyExtraData($index, $chunkVersion); From 2eb498b84c91c2f4151b4af6bc47c194700eed12 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 26 May 2019 19:45:47 +0100 Subject: [PATCH 0850/3224] ItemFactory: add getAllRegistered() --- src/pocketmine/item/ItemFactory.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 5ba12a9900..a6d5ae2bd6 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -485,4 +485,8 @@ class ItemFactory{ } return (($id & 0xffff) << 16) | ($variant & 0xffff); } + + public static function getAllRegistered() : array{ + return self::$list; + } } From 3902a3c28c9c2348569e5a7d2272eafba0137fb1 Mon Sep 17 00:00:00 2001 From: SOFe Date: Mon, 27 May 2019 22:47:58 +0800 Subject: [PATCH 0851/3224] Require opting into receiving cancelled events instead of opting out (#2906) Warning for plugin developers: This is a silent BC break. It won't raise any errors. This alters the default behaviour of event handlers to **not** receive cancelled events by default. It is now required to opt into receiving cancelled events by using the @handleCancelled directive (or the handleCancelled parameter where it's appropriate). The ambiguous @ignoreCancelled directive is now ignored. Ramifications: - The majority of handlers with `if($event->isCancelled()) return;` no longer need such checks. - Handlers with `@ignoreCancelled true` or `@ignoreCancelled` annotations can have them removed. - Handlers which want to receive cancelled events need to use `@handleCancelled`. --- src/pocketmine/event/Listener.php | 2 +- src/pocketmine/plugin/PluginManager.php | 19 +++++++++---------- src/pocketmine/plugin/RegisteredListener.php | 14 +++++++------- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/pocketmine/event/Listener.php b/src/pocketmine/event/Listener.php index 0a3f84f508..00d12c3f59 100644 --- a/src/pocketmine/event/Listener.php +++ b/src/pocketmine/event/Listener.php @@ -46,7 +46,7 @@ use pocketmine\plugin\PluginManager; * - `@softDepend [PluginName]`: Handler WILL NOT be registered if its event doesn't exist. Useful for soft-depending * on plugin events. Plugin name is optional. * Example: `@softDepend SimpleAuth` - * - `@ignoreCancelled`: Cancelled events WILL NOT be passed to this handler. + * - `@handleCancelled`: Cancelled events will STILL invoke this handler. * - `@priority `: Sets the priority at which this event handler will receive events. * Example: `@priority HIGHEST` * @see EventPriority for a list of possible options. diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index 36d63f4773..d3ea246317 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -532,22 +532,21 @@ class PluginManager{ throw new PluginException("Event handler " . Utils::getNiceClosureName($handlerClosure) . "() declares invalid/unknown priority \"" . $tags["priority"] . "\""); } - $ignoreCancelled = false; - if(isset($tags["ignoreCancelled"])){ - switch(strtolower($tags["ignoreCancelled"])){ + $handleCancelled = false; + if(isset($tags["handleCancelled"])){ + switch(strtolower($tags["handleCancelled"])){ case "true": case "": - $ignoreCancelled = true; + $handleCancelled = true; break; case "false": - $ignoreCancelled = false; break; default: - throw new PluginException("Event handler " . Utils::getNiceClosureName($handlerClosure) . "() declares invalid @ignoreCancelled value \"" . $tags["ignoreCancelled"] . "\""); + throw new PluginException("Event handler " . Utils::getNiceClosureName($handlerClosure) . "() declares invalid @handleCancelled value \"" . $tags["handleCancelled"] . "\""); } } - $this->registerEvent($eventClass->getName(), $handlerClosure, $priority, $plugin, $ignoreCancelled); + $this->registerEvent($eventClass->getName(), $handlerClosure, $priority, $plugin, $handleCancelled); } } } @@ -557,11 +556,11 @@ class PluginManager{ * @param \Closure $handler * @param int $priority * @param Plugin $plugin - * @param bool $ignoreCancelled + * @param bool $handleCancelled * * @throws \ReflectionException */ - public function registerEvent(string $event, \Closure $handler, int $priority, Plugin $plugin, bool $ignoreCancelled = false) : void{ + public function registerEvent(string $event, \Closure $handler, int $priority, Plugin $plugin, bool $handleCancelled = false) : void{ if(!is_subclass_of($event, Event::class)){ throw new PluginException($event . " is not an Event"); } @@ -584,7 +583,7 @@ class PluginManager{ $timings = new TimingsHandler("Plugin: " . $plugin->getDescription()->getFullName() . " Event: " . $handlerName . "(" . (new \ReflectionClass($event))->getShortName() . ")"); - $this->getEventListeners($event)->register(new RegisteredListener($handler, $priority, $plugin, $ignoreCancelled, $timings)); + $this->getEventListeners($event)->register(new RegisteredListener($handler, $priority, $plugin, $handleCancelled, $timings)); } /** diff --git a/src/pocketmine/plugin/RegisteredListener.php b/src/pocketmine/plugin/RegisteredListener.php index 0cc684a59a..c4b7e04f6d 100644 --- a/src/pocketmine/plugin/RegisteredListener.php +++ b/src/pocketmine/plugin/RegisteredListener.php @@ -39,7 +39,7 @@ class RegisteredListener{ private $plugin; /** @var bool */ - private $ignoreCancelled; + private $handleCancelled; /** @var TimingsHandler */ private $timings; @@ -49,14 +49,14 @@ class RegisteredListener{ * @param \Closure $handler * @param int $priority * @param Plugin $plugin - * @param bool $ignoreCancelled + * @param bool $handleCancelled * @param TimingsHandler $timings */ - public function __construct(\Closure $handler, int $priority, Plugin $plugin, bool $ignoreCancelled, TimingsHandler $timings){ + public function __construct(\Closure $handler, int $priority, Plugin $plugin, bool $handleCancelled, TimingsHandler $timings){ $this->handler = $handler; $this->priority = $priority; $this->plugin = $plugin; - $this->ignoreCancelled = $ignoreCancelled; + $this->handleCancelled = $handleCancelled; $this->timings = $timings; } @@ -82,7 +82,7 @@ class RegisteredListener{ * @param Event $event */ public function callEvent(Event $event) : void{ - if($event instanceof Cancellable and $event->isCancelled() and $this->isIgnoringCancelled()){ + if($event instanceof Cancellable and $event->isCancelled() and !$this->isHandlingCancelled()){ return; } $this->timings->startTiming(); @@ -97,7 +97,7 @@ class RegisteredListener{ /** * @return bool */ - public function isIgnoringCancelled() : bool{ - return $this->ignoreCancelled; + public function isHandlingCancelled() : bool{ + return $this->handleCancelled; } } From 0a891f540836c4ca29af63050121851000d534c4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 27 May 2019 16:06:30 +0100 Subject: [PATCH 0852/3224] Move some things out of LoginPacket and into the handler --- .../mcpe/handler/LoginSessionHandler.php | 32 +++++++++++++++---- .../network/mcpe/protocol/LoginPacket.php | 22 ------------- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php index 909afed42c..d75d0d518e 100644 --- a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; +use pocketmine\entity\Skin; use pocketmine\event\player\PlayerPreLoginEvent; use pocketmine\network\mcpe\NetworkCipher; use pocketmine\network\mcpe\NetworkSession; @@ -31,7 +32,10 @@ use pocketmine\network\mcpe\protocol\LoginPacket; use pocketmine\network\mcpe\protocol\PlayStatusPacket; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\Player; +use pocketmine\PlayerInfo; use pocketmine\Server; +use pocketmine\utils\UUID; +use function base64_decode; /** * Handles the initial login phase of the session. This handler is used as the initial state. @@ -50,8 +54,6 @@ class LoginSessionHandler extends SessionHandler{ } public function handleLogin(LoginPacket $packet) : bool{ - $this->session->setPlayerInfo($packet->playerInfo); - if(!$this->isCompatibleProtocol($packet->protocol)){ $pk = new PlayStatusPacket(); $pk->status = $packet->protocol < ProtocolInfo::CURRENT_PROTOCOL ? @@ -67,20 +69,36 @@ class LoginSessionHandler extends SessionHandler{ return true; } - if(!Player::isValidUserName($packet->playerInfo->getUsername())){ + if(!Player::isValidUserName($packet->extraData[LoginPacket::I_USERNAME])){ $this->session->disconnect("disconnectionScreen.invalidName"); return true; } - if(!$packet->playerInfo->getSkin()->isValid()){ + $skin = new Skin( + $packet->clientData[LoginPacket::I_SKIN_ID], + base64_decode($packet->clientData[LoginPacket::I_SKIN_DATA]), + base64_decode($packet->clientData[LoginPacket::I_CAPE_DATA]), + $packet->clientData[LoginPacket::I_GEOMETRY_NAME], + base64_decode($packet->clientData[LoginPacket::I_GEOMETRY_DATA]) + ); + if(!$skin->isValid()){ $this->session->disconnect("disconnectionScreen.invalidSkin"); return true; } + $this->session->setPlayerInfo(new PlayerInfo( + $packet->extraData[LoginPacket::I_USERNAME], + UUID::fromString($packet->extraData[LoginPacket::I_UUID]), + $skin, + $packet->clientData[LoginPacket::I_LANGUAGE_CODE], + $packet->extraData[LoginPacket::I_XUID], + $packet->clientData[LoginPacket::I_CLIENT_RANDOM_ID] + )); + $ev = new PlayerPreLoginEvent( - $packet->playerInfo, + $this->session->getPlayerInfo(), $this->session->getIp(), $this->session->getPort(), $this->server->requiresAuthentication() @@ -88,10 +106,10 @@ class LoginSessionHandler extends SessionHandler{ if($this->server->getNetwork()->getConnectionCount() > $this->server->getMaxPlayers()){ $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_SERVER_FULL, "disconnectionScreen.serverFull"); } - if(!$this->server->isWhitelisted($packet->playerInfo->getUsername())){ + if(!$this->server->isWhitelisted($this->session->getPlayerInfo()->getUsername())){ $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_SERVER_WHITELISTED, "Server is whitelisted"); } - if($this->server->getNameBans()->isBanned($packet->playerInfo->getUsername()) or $this->server->getIPBans()->isBanned($this->session->getIp())){ + if($this->server->getNameBans()->isBanned($this->session->getPlayerInfo()->getUsername()) or $this->server->getIPBans()->isBanned($this->session->getIp())){ $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_BANNED, "You are banned"); } diff --git a/src/pocketmine/network/mcpe/protocol/LoginPacket.php b/src/pocketmine/network/mcpe/protocol/LoginPacket.php index 2f79362a23..694d8877f3 100644 --- a/src/pocketmine/network/mcpe/protocol/LoginPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LoginPacket.php @@ -27,16 +27,12 @@ namespace pocketmine\network\mcpe\protocol; use Particle\Validator\Validator; -use pocketmine\entity\Skin; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\SessionHandler; -use pocketmine\PlayerInfo; use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; use pocketmine\utils\Utils; -use pocketmine\utils\UUID; use function array_filter; -use function base64_decode; use function count; use function implode; use function is_array; @@ -65,9 +61,6 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $protocol; - /** @var PlayerInfo */ - public $playerInfo; - /** @var string[] array of encoded JWT */ public $chainDataJwt = []; /** @var array|null extraData index of whichever JWT has it */ @@ -183,21 +176,6 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ self::validate($v, 'clientData', $clientData); $this->clientData = $clientData; - - $this->playerInfo = new PlayerInfo( - $this->extraData[self::I_USERNAME], - UUID::fromString($this->extraData[self::I_UUID]), - new Skin( - $this->clientData[self::I_SKIN_ID], - base64_decode($this->clientData[self::I_SKIN_DATA]), - base64_decode($this->clientData[self::I_CAPE_DATA]), - $this->clientData[self::I_GEOMETRY_NAME], - base64_decode($this->clientData[self::I_GEOMETRY_DATA]) - ), - $this->clientData[self::I_LANGUAGE_CODE], - $this->extraData[self::I_XUID], - $this->clientData[self::I_CLIENT_RANDOM_ID] - ); } protected function encodePayload() : void{ From 89242543b914d579a2732875afdee7fc44546f91 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 27 May 2019 16:20:46 +0100 Subject: [PATCH 0853/3224] Clean up Skin error handling, close #2926 Skin->__construct() now does all the validation. --- src/pocketmine/Player.php | 4 -- src/pocketmine/entity/Human.php | 29 ++++--------- src/pocketmine/entity/Skin.php | 42 ++++++------------- .../event/player/PlayerChangeSkinEvent.php | 1 - .../mcpe/handler/LoginSessionHandler.php | 18 ++++---- .../mcpe/protocol/PlayerListPacket.php | 19 +++++---- .../mcpe/protocol/PlayerSkinPacket.php | 7 +++- 7 files changed, 47 insertions(+), 73 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 82b4cb2215..27495eaad6 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -820,10 +820,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool */ public function changeSkin(Skin $skin, string $newSkinName, string $oldSkinName) : bool{ - if(!$skin->isValid()){ - return false; - } - $ev = new PlayerChangeSkinEvent($this, $this->getSkin(), $skin); $ev->call(); diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index c17fc13385..bc744956ff 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -105,30 +105,18 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ if($skinTag === null){ throw new \InvalidStateException((new \ReflectionClass($this))->getShortName() . " must have a valid skin set"); } - $this->skin = self::deserializeSkinNBT($skinTag); //this throws if the skin is invalid + $this->skin = new Skin( //this throws if the skin is invalid + $skinTag->getString("Name"), + $skinTag->hasTag("Data", StringTag::class) ? $skinTag->getString("Data") : $skinTag->getByteArray("Data"), //old data (this used to be saved as a StringTag in older versions of PM) + $skinTag->getByteArray("CapeData", ""), + $skinTag->getString("GeometryName", ""), + $skinTag->getByteArray("GeometryData", "") + ); } parent::__construct($world, $nbt); } - /** - * @param CompoundTag $skinTag - * - * @return Skin - * @throws \InvalidArgumentException - */ - protected static function deserializeSkinNBT(CompoundTag $skinTag) : Skin{ - $skin = new Skin( - $skinTag->getString("Name"), - $skinTag->hasTag("Data", StringTag::class) ? $skinTag->getString("Data") : $skinTag->getByteArray("Data"), //old data (this used to be saved as a StringTag in older versions of PM) - $skinTag->getByteArray("CapeData", ""), - $skinTag->getString("GeometryName", ""), - $skinTag->getByteArray("GeometryData", "") - ); - $skin->validate(); - return $skin; - } - /** * @deprecated * @@ -171,7 +159,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ * @param Skin $skin */ public function setSkin(Skin $skin) : void{ - $skin->validate(); $this->skin = $skin; $this->skin->debloatGeometryData(); } @@ -841,8 +828,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ } protected function sendSpawnPacket(Player $player) : void{ - $this->skin->validate(); - if(!($this instanceof Player)){ /* we don't use Server->updatePlayerListData() because that uses batches, which could cause race conditions in async compression mode */ $pk = new PlayerListPacket(); diff --git a/src/pocketmine/entity/Skin.php b/src/pocketmine/entity/Skin.php index 2c66dfaeea..7192748622 100644 --- a/src/pocketmine/entity/Skin.php +++ b/src/pocketmine/entity/Skin.php @@ -48,6 +48,18 @@ class Skin{ private $geometryData; public function __construct(string $skinId, string $skinData, string $capeData = "", string $geometryName = "", string $geometryData = ""){ + if($skinId === ""){ + throw new \InvalidArgumentException("Skin ID must not be empty"); + } + $len = strlen($skinData); + if(!in_array($len, self::ACCEPTED_SKIN_SIZES, true)){ + throw new \InvalidArgumentException("Invalid skin data size $len bytes (allowed sizes: " . implode(", ", self::ACCEPTED_SKIN_SIZES) . ")"); + } + if($capeData !== "" and strlen($capeData) !== 8192){ + throw new \InvalidArgumentException("Invalid cape data size " . strlen($capeData) . " bytes (must be exactly 8192 bytes)"); + } + //TODO: validate geometry + $this->skinId = $skinId; $this->skinData = $skinData; $this->capeData = $capeData; @@ -55,36 +67,6 @@ class Skin{ $this->geometryData = $geometryData; } - /** - * @deprecated - * @return bool - */ - public function isValid() : bool{ - try{ - $this->validate(); - return true; - }catch(\InvalidArgumentException $e){ - return false; - } - } - - /** - * @throws \InvalidArgumentException - */ - public function validate() : void{ - if($this->skinId === ""){ - throw new \InvalidArgumentException("Skin ID must not be empty"); - } - $len = strlen($this->skinData); - if(!in_array($len, self::ACCEPTED_SKIN_SIZES, true)){ - throw new \InvalidArgumentException("Invalid skin data size $len bytes (allowed sizes: " . implode(", ", self::ACCEPTED_SKIN_SIZES) . ")"); - } - if($this->capeData !== "" and strlen($this->capeData) !== 8192){ - throw new \InvalidArgumentException("Invalid cape data size " . strlen($this->capeData) . " bytes (must be exactly 8192 bytes)"); - } - //TODO: validate geometry - } - /** * @return string */ diff --git a/src/pocketmine/event/player/PlayerChangeSkinEvent.php b/src/pocketmine/event/player/PlayerChangeSkinEvent.php index 912f06b472..5202ff974b 100644 --- a/src/pocketmine/event/player/PlayerChangeSkinEvent.php +++ b/src/pocketmine/event/player/PlayerChangeSkinEvent.php @@ -70,7 +70,6 @@ class PlayerChangeSkinEvent extends PlayerEvent implements Cancellable{ * @throws \InvalidArgumentException if the specified skin is not valid */ public function setNewSkin(Skin $skin) : void{ - $skin->validate(); $this->newSkin = $skin; } } diff --git a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php index d75d0d518e..e9416f68b4 100644 --- a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php @@ -75,14 +75,16 @@ class LoginSessionHandler extends SessionHandler{ return true; } - $skin = new Skin( - $packet->clientData[LoginPacket::I_SKIN_ID], - base64_decode($packet->clientData[LoginPacket::I_SKIN_DATA]), - base64_decode($packet->clientData[LoginPacket::I_CAPE_DATA]), - $packet->clientData[LoginPacket::I_GEOMETRY_NAME], - base64_decode($packet->clientData[LoginPacket::I_GEOMETRY_DATA]) - ); - if(!$skin->isValid()){ + try{ + $skin = new Skin( + $packet->clientData[LoginPacket::I_SKIN_ID], + base64_decode($packet->clientData[LoginPacket::I_SKIN_DATA]), + base64_decode($packet->clientData[LoginPacket::I_CAPE_DATA]), + $packet->clientData[LoginPacket::I_GEOMETRY_NAME], + base64_decode($packet->clientData[LoginPacket::I_GEOMETRY_DATA]) + ); + }catch(\InvalidArgumentException $e){ + $this->session->getLogger()->debug("Invalid skin: " . $e->getMessage()); $this->session->disconnect("disconnectionScreen.invalidSkin"); return true; diff --git a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php index 2d0eeb4e14..ec4f1af248 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\entity\Skin; +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use function count; @@ -59,13 +60,17 @@ class PlayerListPacket extends DataPacket implements ClientboundPacket{ $geometryName = $this->getString(); $geometryData = $this->getString(); - $entry->skin = new Skin( - $skinId, - $skinData, - $capeData, - $geometryName, - $geometryData - ); + try{ + $entry->skin = new Skin( + $skinId, + $skinData, + $capeData, + $geometryName, + $geometryData + ); + }catch(\InvalidArgumentException $e){ + throw new BadPacketException($e->getMessage(), 0, $e); + } $entry->xboxUserId = $this->getString(); $entry->platformChatId = $this->getString(); }else{ diff --git a/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php index 066ae58284..e6c56bf209 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\entity\Skin; +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\SessionHandler; use pocketmine\utils\UUID; @@ -54,7 +55,11 @@ class PlayerSkinPacket extends DataPacket implements ClientboundPacket, Serverbo $geometryModel = $this->getString(); $geometryData = $this->getString(); - $this->skin = new Skin($skinId, $skinData, $capeData, $geometryModel, $geometryData); + try{ + $this->skin = new Skin($skinId, $skinData, $capeData, $geometryModel, $geometryData); + }catch(\InvalidArgumentException $e){ + throw new BadPacketException($e->getMessage(), 0, $e); + } $this->premiumSkin = $this->getBool(); } From 2720ff96071402cad048067e933b54477128a6b9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 27 May 2019 16:45:55 +0100 Subject: [PATCH 0854/3224] Skin: debloat geometry in constructor directly --- src/pocketmine/entity/Human.php | 1 - src/pocketmine/entity/Skin.php | 31 +++++++++++++++++-------------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index bc744956ff..edca17db84 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -160,7 +160,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ */ public function setSkin(Skin $skin) : void{ $this->skin = $skin; - $this->skin->debloatGeometryData(); } /** diff --git a/src/pocketmine/entity/Skin.php b/src/pocketmine/entity/Skin.php index 7192748622..83d8eff395 100644 --- a/src/pocketmine/entity/Skin.php +++ b/src/pocketmine/entity/Skin.php @@ -27,6 +27,7 @@ use function implode; use function in_array; use function json_decode; use function json_encode; +use function json_last_error_msg; use function strlen; class Skin{ @@ -58,7 +59,22 @@ class Skin{ if($capeData !== "" and strlen($capeData) !== 8192){ throw new \InvalidArgumentException("Invalid cape data size " . strlen($capeData) . " bytes (must be exactly 8192 bytes)"); } - //TODO: validate geometry + + if($geometryData !== ""){ + $decodedGeometry = json_decode($geometryData); + if($decodedGeometry === false){ + throw new \InvalidArgumentException("Invalid geometry data (" . json_last_error_msg() . ")"); + } + + /* + * Hack to cut down on network overhead due to skins, by un-pretty-printing geometry JSON. + * + * Mojang, some stupid reason, send every single model for every single skin in the selected skin-pack. + * Not only that, they are pretty-printed. + * TODO: find out what model crap can be safely dropped from the packet (unless it gets fixed first) + */ + $geometryData = json_encode($decodedGeometry); + } $this->skinId = $skinId; $this->skinData = $skinData; @@ -101,17 +117,4 @@ class Skin{ public function getGeometryData() : string{ return $this->geometryData; } - - /** - * Hack to cut down on network overhead due to skins, by un-pretty-printing geometry JSON. - * - * Mojang, some stupid reason, send every single model for every single skin in the selected skin-pack. - * Not only that, they are pretty-printed. - * TODO: find out what model crap can be safely dropped from the packet (unless it gets fixed first) - */ - public function debloatGeometryData() : void{ - if($this->geometryData !== ""){ - $this->geometryData = (string) json_encode(json_decode($this->geometryData)); - } - } } From 7eb8d8e3669ae5ae6bd5641fc166455b0127bbb7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 27 May 2019 17:11:35 +0100 Subject: [PATCH 0855/3224] Require Closures in more places instead of callable Non-closure callables have strange context-dependent behaviour and are slower to call than a closure. It's possible to use Closure::fromCallable() in the origin scope, which guarantees that the callable will remain callable no matter where it's used. --- src/pocketmine/network/mcpe/CompressBatchPromise.php | 6 +++--- src/pocketmine/utils/Internet.php | 8 ++++---- src/pocketmine/world/BlockTransaction.php | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/pocketmine/network/mcpe/CompressBatchPromise.php b/src/pocketmine/network/mcpe/CompressBatchPromise.php index f58ef6ca06..fe4e8f864d 100644 --- a/src/pocketmine/network/mcpe/CompressBatchPromise.php +++ b/src/pocketmine/network/mcpe/CompressBatchPromise.php @@ -27,7 +27,7 @@ use pocketmine\utils\Utils; use function array_push; class CompressBatchPromise{ - /** @var callable[] */ + /** @var \Closure[] */ private $callbacks = []; /** @var string|null */ @@ -36,7 +36,7 @@ class CompressBatchPromise{ /** @var bool */ private $cancelled = false; - public function onResolve(callable ...$callbacks) : void{ + public function onResolve(\Closure ...$callbacks) : void{ $this->checkCancelled(); foreach($callbacks as $callback){ Utils::validateCallableSignature(function(CompressBatchPromise $promise){}, $callback); @@ -64,7 +64,7 @@ class CompressBatchPromise{ } /** - * @return callable[] + * @return \Closure[] */ public function getResolveCallbacks() : array{ return $this->callbacks; diff --git a/src/pocketmine/utils/Internet.php b/src/pocketmine/utils/Internet.php index 67035f5e6c..bd56cb9d47 100644 --- a/src/pocketmine/utils/Internet.php +++ b/src/pocketmine/utils/Internet.php @@ -184,16 +184,16 @@ class Internet{ * NOTE: This is a blocking operation and can take a significant amount of time. It is inadvisable to use this method on the main thread. * * @param string $page - * @param float|int $timeout The maximum connect timeout and timeout in seconds, correct to ms. + * @param float|int $timeout The maximum connect timeout and timeout in seconds, correct to ms. * @param string[] $extraHeaders extra headers to send as a plain string array - * @param array $extraOpts extra CURLOPT_* to set as an [opt => value] map - * @param callable|null $onSuccess function to be called if there is no error. Accepts a resource argument as the cURL handle. + * @param array $extraOpts extra CURLOPT_* to set as an [opt => value] map + * @param \Closure|null $onSuccess function to be called if there is no error. Accepts a resource argument as the cURL handle. * * @return array a plain array of three [result body : string, headers : array[], HTTP response code : int]. Headers are grouped by requests with strtolower(header name) as keys and header value as values * * @throws InternetException if a cURL error occurs */ - public static function simpleCurl(string $page, $timeout = 10, array $extraHeaders = [], array $extraOpts = [], ?callable $onSuccess = null) : array{ + public static function simpleCurl(string $page, $timeout = 10, array $extraHeaders = [], array $extraOpts = [], ?\Closure $onSuccess = null) : array{ if(!self::$online){ throw new InternetException("Cannot execute web request while offline"); } diff --git a/src/pocketmine/world/BlockTransaction.php b/src/pocketmine/world/BlockTransaction.php index 6232f44785..428daaf8d3 100644 --- a/src/pocketmine/world/BlockTransaction.php +++ b/src/pocketmine/world/BlockTransaction.php @@ -134,9 +134,9 @@ class BlockTransaction{ * The callable signature should be the same as the below dummy function. * @see BlockTransaction::dummyValidator() * - * @param callable $validator + * @param \Closure $validator */ - public function addValidator(callable $validator) : void{ + public function addValidator(\Closure $validator) : void{ Utils::validateCallableSignature([$this, 'dummyValidator'], $validator); $this->validators[] = $validator; } From 11d21448fc88e98f7b88f18d1ae543ada91020c5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 27 May 2019 17:12:33 +0100 Subject: [PATCH 0856/3224] Utils: remove dead function --- src/pocketmine/utils/Utils.php | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/pocketmine/utils/Utils.php b/src/pocketmine/utils/Utils.php index 25c3142e5f..542b1a79fe 100644 --- a/src/pocketmine/utils/Utils.php +++ b/src/pocketmine/utils/Utils.php @@ -70,15 +70,12 @@ use function preg_match_all; use function preg_replace; use function rmdir; use function scandir; -use function sha1; -use function spl_object_hash; use function str_pad; use function str_replace; use function str_split; use function stripos; use function strlen; use function strpos; -use function strtolower; use function strval; use function substr; use function sys_get_temp_dir; @@ -102,21 +99,6 @@ class Utils{ /** @var UUID|null */ private static $serverUniqueId = null; - /** - * Generates an unique identifier to a callable - * - * @param callable $variable - * - * @return string - */ - public static function getCallableIdentifier(callable $variable) : string{ - if(is_array($variable)){ - return sha1(strtolower(spl_object_hash($variable[0])) . "::" . strtolower($variable[1])); - }else{ - return sha1(strtolower($variable)); - } - } - /** * Returns a readable identifier for the given Closure, including file and line. * From 28f332233750f2fce12a60a6987224fb9c653e12 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 27 May 2019 17:30:57 +0100 Subject: [PATCH 0857/3224] Block: add onPostPlace() hook --- src/pocketmine/block/Block.php | 4 ++++ src/pocketmine/block/Chest.php | 36 ++++++++++++++++------------------ src/pocketmine/world/World.php | 1 + 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 16b2428399..c1b16ce089 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -253,6 +253,10 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ return $this->getWorld()->setBlock($blockReplace, $this); } + public function onPostPlace() : void{ + + } + /** * Returns an object containing information about the destruction requirements of this block. * diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index 6c72e61344..3e08722eef 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -62,29 +62,27 @@ class Chest extends Transparent{ $this->facing = Facing::opposite($player->getHorizontalFacing()); } - if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - $tile = $this->world->getTile($this); - if($tile instanceof TileChest){ - foreach([ - Facing::rotateY($this->facing, true), - Facing::rotateY($this->facing, false) - ] as $side){ - $c = $this->getSide($side); - if($c instanceof Chest and $c->isSameType($this) and $c->facing === $this->facing){ - $pair = $this->world->getTile($c); - if($pair instanceof TileChest and !$pair->isPaired()){ - $pair->pairWith($tile); - $tile->pairWith($pair); - break; - } + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + + public function onPostPlace() : void{ + $tile = $this->world->getTile($this); + if($tile instanceof TileChest){ + foreach([ + Facing::rotateY($this->facing, true), + Facing::rotateY($this->facing, false) + ] as $side){ + $c = $this->getSide($side); + if($c instanceof Chest and $c->isSameType($this) and $c->facing === $this->facing){ + $pair = $this->world->getTile($c); + if($pair instanceof TileChest and !$pair->isPaired()){ + $pair->pairWith($tile); + $tile->pairWith($pair); + break; } } } - - return true; } - - return false; } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 7f65df8f1f..44fecc67b7 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -1863,6 +1863,7 @@ class World implements ChunkManager, Metadatable{ //TODO: seal this up inside block placement $tile->copyDataFromItem($item); } + $hand->onPostPlace(); if($playSound){ $this->addSound($hand, new BlockPlaceSound($hand)); From bcff124953ea28b97729130c10e06002a325cbbd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 27 May 2019 17:55:19 +0100 Subject: [PATCH 0858/3224] BaseRail: move reconnect attempt to post-place hook --- src/pocketmine/block/BaseRail.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/block/BaseRail.php b/src/pocketmine/block/BaseRail.php index cca6821455..92fa0ca060 100644 --- a/src/pocketmine/block/BaseRail.php +++ b/src/pocketmine/block/BaseRail.php @@ -98,13 +98,16 @@ abstract class BaseRail extends Flowable{ public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$blockReplace->getSide(Facing::DOWN)->isTransparent()){ - $this->tryReconnect(); return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; } + public function onPostPlace() : void{ + $this->tryReconnect(); + } + protected static function searchState(array $connections, array $lookup) : int{ $meta = array_search($connections, $lookup, true); if($meta === false){ @@ -253,6 +256,7 @@ abstract class BaseRail extends Flowable{ if($changed){ $this->setConnections($thisConnections); + $this->world->setBlock($this, $this); } } From 3d8cd54f16059a1e0c036f271aab8206f6bad972 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 30 May 2019 04:26:06 -0400 Subject: [PATCH 0859/3224] Update composer dependencies --- composer.lock | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/composer.lock b/composer.lock index cbdae5d2d3..5c622c8c25 100644 --- a/composer.lock +++ b/composer.lock @@ -277,7 +277,7 @@ { "name": "Berry Langerak", "email": "berry@berryllium.nl", - "role": "Developer" + "role": "developer" }, { "name": "Rick van der Staaij", @@ -413,12 +413,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "3b075c62693824b44b50ea3787b88116c7c56926" + "reference": "b4799d6ecc0914b6d47ead8c70b50e53b043d828" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/3b075c62693824b44b50ea3787b88116c7c56926", - "reference": "3b075c62693824b44b50ea3787b88116c7c56926", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/b4799d6ecc0914b6d47ead8c70b50e53b043d828", + "reference": "b4799d6ecc0914b6d47ead8c70b50e53b043d828", "shasum": "" }, "require": { @@ -446,7 +446,7 @@ "source": "https://github.com/pmmp/RakLib/tree/master", "issues": "https://github.com/pmmp/RakLib/issues" }, - "time": "2019-05-02T15:09:56+00:00" + "time": "2019-05-13T17:14:39+00:00" }, { "name": "pocketmine/snooze", @@ -488,19 +488,16 @@ "source": { "type": "git", "url": "https://github.com/pmmp/SPL.git", - "reference": "463152d5d2ee052a89fe44dcc27b56663f891912" + "reference": "7b80cbebd90a320b109154a7ff594688c1e0efcf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/SPL/zipball/463152d5d2ee052a89fe44dcc27b56663f891912", - "reference": "463152d5d2ee052a89fe44dcc27b56663f891912", + "url": "https://api.github.com/repos/pmmp/SPL/zipball/7b80cbebd90a320b109154a7ff594688c1e0efcf", + "reference": "7b80cbebd90a320b109154a7ff594688c1e0efcf", "shasum": "" }, "type": "library", "autoload": { - "exclude-from-classmap": [ - "stubs" - ], "classmap": [ "./" ] @@ -512,7 +509,7 @@ "support": { "source": "https://github.com/pmmp/SPL/tree/master" }, - "time": "2019-03-31T16:30:20+00:00" + "time": "2019-05-18T14:07:32+00:00" } ], "packages-dev": [], From ece4d99c1efc8379f45d533839a8f6040e4cb176 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 30 May 2019 09:53:20 +0100 Subject: [PATCH 0860/3224] fix crash on invalid NBT during itemstack decoding --- src/pocketmine/network/mcpe/NetworkBinaryStream.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/NetworkBinaryStream.php b/src/pocketmine/network/mcpe/NetworkBinaryStream.php index cbc0d75ee5..746e1aa4c1 100644 --- a/src/pocketmine/network/mcpe/NetworkBinaryStream.php +++ b/src/pocketmine/network/mcpe/NetworkBinaryStream.php @@ -31,6 +31,7 @@ use pocketmine\item\ItemFactory; use pocketmine\item\ItemIds; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\NbtDataException; use pocketmine\nbt\TreeRoot; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\types\CommandOriginData; @@ -105,7 +106,11 @@ class NetworkBinaryStream extends BinaryStream{ if($c !== 1){ throw new BadPacketException("Unexpected NBT count $c"); } - $compound = (new NetworkNbtSerializer())->read($this->buffer, $this->offset, 512)->getTag(); + try{ + $compound = (new NetworkNbtSerializer())->read($this->buffer, $this->offset, 512)->getTag(); + }catch(NbtDataException $e){ + throw new BadPacketException($e->getMessage(), 0, $e); + } }elseif($nbtLen !== 0){ throw new BadPacketException("Unexpected fake NBT length $nbtLen"); } From f18da8d879d0066c4776320725cc7df369a0afb5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 30 May 2019 18:52:19 +0100 Subject: [PATCH 0861/3224] Added missing tile for Note Block this doesn't come with a full impl because that requires some further changes like adding materials, which is out of the scope of this commit. This is here to prevent additional data loss in imported worlds. --- src/pocketmine/block/BlockFactory.php | 3 +- .../block/{NoteBlock.php => Note.php} | 44 ++++++++++++- src/pocketmine/block/tile/Note.php | 62 +++++++++++++++++++ src/pocketmine/block/tile/TileFactory.php | 2 +- 4 files changed, 108 insertions(+), 3 deletions(-) rename src/pocketmine/block/{NoteBlock.php => Note.php} (50%) create mode 100644 src/pocketmine/block/tile/Note.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 0c9dfed791..b25ebd0f5b 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -36,6 +36,7 @@ use pocketmine\block\tile\EnderChest as TileEnderChest; use pocketmine\block\tile\FlowerPot as TileFlowerPot; use pocketmine\block\tile\Furnace as TileFurnace; use pocketmine\block\tile\ItemFrame as TileItemFrame; +use pocketmine\block\tile\Note as TileNote; use pocketmine\block\tile\Sign as TileSign; use pocketmine\block\tile\Skull as TileSkull; use pocketmine\block\tile\TileFactory; @@ -241,7 +242,7 @@ class BlockFactory{ self::register(new Solid(new BID(Ids::NETHER_WART_BLOCK), "Nether Wart Block", new BlockBreakInfo(1.0))); self::register(new NetherWartPlant(new BID(Ids::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART), "Nether Wart")); self::register(new Netherrack(new BID(Ids::NETHERRACK), "Netherrack")); - self::register(new NoteBlock(new BID(Ids::NOTEBLOCK), "Note Block")); + self::register(new Note(new BID(Ids::NOTEBLOCK, 0, null, TileNote::class), "Note Block")); self::register(new Solid(new BID(Ids::OBSIDIAN), "Obsidian", new BlockBreakInfo(35.0 /* 50 in PC */, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_DIAMOND, 6000.0))); self::register(new PackedIce(new BID(Ids::PACKED_ICE), "Packed Ice")); self::register(new Podzol(new BID(Ids::PODZOL), "Podzol")); diff --git a/src/pocketmine/block/NoteBlock.php b/src/pocketmine/block/Note.php similarity index 50% rename from src/pocketmine/block/NoteBlock.php rename to src/pocketmine/block/Note.php index 000c6889f0..d9be134765 100644 --- a/src/pocketmine/block/NoteBlock.php +++ b/src/pocketmine/block/Note.php @@ -23,15 +23,57 @@ declare(strict_types=1); namespace pocketmine\block; -class NoteBlock extends Solid{ +use pocketmine\block\tile\Note as TileNote; +use function assert; + +class Note extends Solid{ + public const MIN_PITCH = 0; + public const MAX_PITCH = 24; + + /** @var int */ + private $pitch = self::MIN_PITCH; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.8, BlockToolType::TYPE_AXE)); } + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); + $tile = $this->world->getTile($this); + if($tile instanceof TileNote){ + $this->pitch = $tile->getPitch(); + }else{ + $this->pitch = self::MIN_PITCH; + } + } + + public function writeStateToWorld() : void{ + parent::writeStateToWorld(); + $tile = $this->world->getTile($this); + assert($tile instanceof TileNote); + $tile->setPitch($this->pitch); + } + public function getFuelTime() : int{ return 300; } + /** + * @return int + */ + public function getPitch() : int{ + return $this->pitch; + } + + /** + * @param int $pitch + */ + public function setPitch(int $pitch) : void{ + if($pitch < self::MIN_PITCH or $pitch > self::MAX_PITCH){ + throw new \InvalidArgumentException("Pitch must be in range " . self::MIN_PITCH . " - " . self::MAX_PITCH); + } + $this->pitch = $pitch; + } + //TODO } diff --git a/src/pocketmine/block/tile/Note.php b/src/pocketmine/block/tile/Note.php new file mode 100644 index 0000000000..4d178d837a --- /dev/null +++ b/src/pocketmine/block/tile/Note.php @@ -0,0 +1,62 @@ +getByte("note", $this->pitch)) > BlockNote::MIN_PITCH and $pitch <= BlockNote::MAX_PITCH){ + $this->pitch = $pitch; + } + } + + protected function writeSaveData(CompoundTag $nbt) : void{ + $nbt->setByte("note", $this->pitch); + } + + /** + * @return int + */ + public function getPitch() : int{ + return $this->pitch; + } + + /** + * @param int $pitch + */ + public function setPitch(int $pitch) : void{ + if($pitch < BlockNote::MIN_PITCH or $pitch > BlockNote::MAX_PITCH){ + throw new \InvalidArgumentException("Pitch must be in range " . BlockNote::MIN_PITCH . " - " . BlockNote::MAX_PITCH); + } + $this->pitch = $pitch; + } +} diff --git a/src/pocketmine/block/tile/TileFactory.php b/src/pocketmine/block/tile/TileFactory.php index a84912ad68..3692606024 100644 --- a/src/pocketmine/block/tile/TileFactory.php +++ b/src/pocketmine/block/tile/TileFactory.php @@ -55,6 +55,7 @@ final class TileFactory{ self::register(FlowerPot::class, ["FlowerPot", "minecraft:flower_pot"]); self::register(Furnace::class, ["Furnace", "minecraft:furnace"]); self::register(ItemFrame::class, ["ItemFrame"]); //this is an entity in PC + self::register(Note::class, ["Music", "minecraft:noteblock"]); self::register(Sign::class, ["Sign", "minecraft:sign"]); self::register(Skull::class, ["Skull", "minecraft:skull"]); @@ -80,7 +81,6 @@ final class TileFactory{ //TODO: Lectern //TODO: MobSpawner //TODO: MovingBlock - //TODO: Music //TODO: NetherReactor //TODO: PistonArm //TODO: ShulkerBox From 1bf5c74053d09fb399d8bbdf629d653930bcb95a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 30 May 2019 19:00:38 +0100 Subject: [PATCH 0862/3224] added missing DaylightSensor tile --- src/pocketmine/block/BlockFactory.php | 3 +- src/pocketmine/block/tile/DaylightSensor.php | 48 ++++++++++++++++++++ src/pocketmine/block/tile/TileFactory.php | 2 +- 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 src/pocketmine/block/tile/DaylightSensor.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index b25ebd0f5b..86b5bccb7a 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -31,6 +31,7 @@ use pocketmine\block\tile\Banner as TileBanner; use pocketmine\block\tile\Bed as TileBed; use pocketmine\block\tile\Chest as TileChest; use pocketmine\block\tile\Comparator as TileComparator; +use pocketmine\block\tile\DaylightSensor as TileDaylightSensor; use pocketmine\block\tile\EnchantTable as TileEnchantingTable; use pocketmine\block\tile\EnderChest as TileEnderChest; use pocketmine\block\tile\FlowerPot as TileFlowerPot; @@ -120,7 +121,7 @@ class BlockFactory{ self::register(new Cobweb(new BID(Ids::COBWEB), "Cobweb")); self::register(new CocoaBlock(new BID(Ids::COCOA), "Cocoa Block")); self::register(new CraftingTable(new BID(Ids::CRAFTING_TABLE), "Crafting Table")); - self::register(new DaylightSensor(new BIDFlattened(Ids::DAYLIGHT_DETECTOR, Ids::DAYLIGHT_DETECTOR_INVERTED), "Daylight Sensor")); + self::register(new DaylightSensor(new BIDFlattened(Ids::DAYLIGHT_DETECTOR, Ids::DAYLIGHT_DETECTOR_INVERTED, 0, null, TileDaylightSensor::class), "Daylight Sensor")); self::register(new DeadBush(new BID(Ids::DEADBUSH), "Dead Bush")); self::register(new DetectorRail(new BID(Ids::DETECTOR_RAIL), "Detector Rail")); diff --git a/src/pocketmine/block/tile/DaylightSensor.php b/src/pocketmine/block/tile/DaylightSensor.php new file mode 100644 index 0000000000..d06201654d --- /dev/null +++ b/src/pocketmine/block/tile/DaylightSensor.php @@ -0,0 +1,48 @@ + Date: Thu, 30 May 2019 19:26:16 +0100 Subject: [PATCH 0863/3224] added missing Monster Spawner tile --- src/pocketmine/block/BlockFactory.php | 3 +- src/pocketmine/block/tile/MonsterSpawner.php | 156 +++++++++++++++++++ src/pocketmine/block/tile/TileFactory.php | 2 +- 3 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 src/pocketmine/block/tile/MonsterSpawner.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 86b5bccb7a..8881f923e5 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -37,6 +37,7 @@ use pocketmine\block\tile\EnderChest as TileEnderChest; use pocketmine\block\tile\FlowerPot as TileFlowerPot; use pocketmine\block\tile\Furnace as TileFurnace; use pocketmine\block\tile\ItemFrame as TileItemFrame; +use pocketmine\block\tile\MonsterSpawner as TileMonsterSpawner; use pocketmine\block\tile\Note as TileNote; use pocketmine\block\tile\Sign as TileSign; use pocketmine\block\tile\Skull as TileSkull; @@ -228,7 +229,7 @@ class BlockFactory{ self::register(new Magma(new BID(Ids::MAGMA), "Magma Block")); self::register(new Melon(new BID(Ids::MELON_BLOCK), "Melon Block")); self::register(new MelonStem(new BID(Ids::MELON_STEM, 0, ItemIds::MELON_SEEDS), "Melon Stem")); - self::register(new MonsterSpawner(new BID(Ids::MOB_SPAWNER), "Monster Spawner")); + self::register(new MonsterSpawner(new BID(Ids::MOB_SPAWNER, 0, null, TileMonsterSpawner::class), "Monster Spawner")); self::register(new Mycelium(new BID(Ids::MYCELIUM), "Mycelium")); $netherBrickBreakInfo = new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0); diff --git a/src/pocketmine/block/tile/MonsterSpawner.php b/src/pocketmine/block/tile/MonsterSpawner.php new file mode 100644 index 0000000000..e698b2c074 --- /dev/null +++ b/src/pocketmine/block/tile/MonsterSpawner.php @@ -0,0 +1,156 @@ + + private const TAG_SPAWN_DATA = "SpawnData"; //TAG_Compound + private const TAG_MIN_SPAWN_DELAY = "MinSpawnDelay"; //TAG_Short + private const TAG_MAX_SPAWN_DELAY = "MaxSpawnDelay"; //TAG_Short + private const TAG_SPAWN_PER_ATTEMPT = "SpawnCount"; //TAG_Short + private const TAG_MAX_NEARBY_ENTITIES = "MaxNearbyEntities"; //TAG_Short + private const TAG_REQUIRED_PLAYER_RANGE = "RequiredPlayerRange"; //TAG_Short + private const TAG_SPAWN_RANGE = "SpawnRange"; //TAG_Short + private const TAG_ENTITY_WIDTH = "DisplayEntityWidth"; //TAG_Float + private const TAG_ENTITY_HEIGHT = "DisplayEntityHeight"; //TAG_Float + private const TAG_ENTITY_SCALE = "DisplayEntityScale"; //TAG_Float + + public const DEFAULT_MIN_SPAWN_DELAY = 200; //ticks + public const DEFAULT_MAX_SPAWN_DELAY = 800; + + public const DEFAULT_MAX_NEARBY_ENTITIES = 6; + public const DEFAULT_SPAWN_RANGE = 4; //blocks + public const DEFAULT_REQUIRED_PLAYER_RANGE = 16; + + /** + * @var string + * TODO: replace this with a cached entity or something of that nature + */ + private $entityTypeId = ":"; + /** + * @var ListTag|null + * TODO: deserialize this properly and drop the NBT (PC and PE formats are different, just for fun) + */ + private $spawnPotentials = null; + /** + * @var CompoundTag|null + * TODO: deserialize this properly and drop the NBT (PC and PE formats are different, just for fun) + */ + private $spawnData = null; + + /** @var float */ + private $displayEntityWidth = 1; + /** @var float */ + private $displayEntityHeight = 1; + /** @var float */ + private $displayEntityScale = 1; + + /** @var int */ + private $spawnDelay = self::DEFAULT_MIN_SPAWN_DELAY; + /** @var int */ + private $minSpawnDelay = self::DEFAULT_MIN_SPAWN_DELAY; + /** @var int */ + private $maxSpawnDelay = self::DEFAULT_MAX_SPAWN_DELAY; + /** @var int */ + private $spawnPerAttempt = 1; + /** @var int */ + private $maxNearbyEntities = self::DEFAULT_MAX_NEARBY_ENTITIES; + /** @var int */ + private $spawnRange = self::DEFAULT_SPAWN_RANGE; + /** @var int */ + private $requiredPlayerRange = self::DEFAULT_REQUIRED_PLAYER_RANGE; + + public function readSaveData(CompoundTag $nbt) : void{ + if($nbt->hasTag(self::TAG_LEGACY_ENTITY_TYPE_ID, IntTag::class)){ + //TODO: this will cause unexpected results when there's no mapping for the entity + $this->entityTypeId = AddEntityPacket::LEGACY_ID_MAP_BC[$nbt->getInt(self::TAG_LEGACY_ENTITY_TYPE_ID)] ?? ":"; + }elseif($nbt->hasTag(self::TAG_ENTITY_TYPE_ID, StringTag::class)){ + $this->entityTypeId = $nbt->getString(self::TAG_ENTITY_TYPE_ID); + }else{ + $this->entityTypeId = ":"; //default - TODO: replace this with a constant + } + + $this->spawnData = $nbt->getCompoundTag(self::TAG_SPAWN_DATA); + $this->spawnPotentials = $nbt->getListTag(self::TAG_SPAWN_POTENTIALS); + + $this->spawnDelay = $nbt->getShort(self::TAG_SPAWN_DELAY, self::DEFAULT_MIN_SPAWN_DELAY); + $this->minSpawnDelay = $nbt->getShort(self::TAG_MIN_SPAWN_DELAY, self::DEFAULT_MIN_SPAWN_DELAY); + $this->maxSpawnDelay = $nbt->getShort(self::TAG_MAX_SPAWN_DELAY, self::DEFAULT_MAX_SPAWN_DELAY); + $this->spawnPerAttempt = $nbt->getShort(self::TAG_SPAWN_PER_ATTEMPT, 1); + $this->maxNearbyEntities = $nbt->getShort(self::TAG_MAX_NEARBY_ENTITIES, self::DEFAULT_MAX_NEARBY_ENTITIES); + $this->requiredPlayerRange = $nbt->getShort(self::TAG_REQUIRED_PLAYER_RANGE, self::DEFAULT_REQUIRED_PLAYER_RANGE); + $this->spawnRange = $nbt->getShort(self::TAG_SPAWN_RANGE, self::DEFAULT_SPAWN_RANGE); + + $this->displayEntityWidth = $nbt->getFloat(self::TAG_ENTITY_WIDTH, 1.0); + $this->displayEntityHeight = $nbt->getFloat(self::TAG_ENTITY_HEIGHT, 1.0); + $this->displayEntityScale = $nbt->getFloat(self::TAG_ENTITY_SCALE, 1.0); + } + + protected function writeSaveData(CompoundTag $nbt) : void{ + $nbt->setString(self::TAG_ENTITY_TYPE_ID, $this->entityTypeId); + if($this->spawnData !== null){ + $nbt->setTag(self::TAG_SPAWN_DATA, clone $this->spawnData); + } + if($this->spawnPotentials !== null){ + $nbt->setTag(self::TAG_SPAWN_POTENTIALS, clone $this->spawnPotentials); + } + + $nbt->setShort(self::TAG_SPAWN_DELAY, $this->spawnDelay); + $nbt->setShort(self::TAG_MIN_SPAWN_DELAY, $this->minSpawnDelay); + $nbt->setShort(self::TAG_MAX_SPAWN_DELAY, $this->maxSpawnDelay); + $nbt->setShort(self::TAG_SPAWN_PER_ATTEMPT, $this->spawnPerAttempt); + $nbt->setShort(self::TAG_MAX_NEARBY_ENTITIES, $this->maxNearbyEntities); + $nbt->setShort(self::TAG_REQUIRED_PLAYER_RANGE, $this->requiredPlayerRange); + $nbt->setShort(self::TAG_SPAWN_RANGE, $this->spawnRange); + + $nbt->setFloat(self::TAG_ENTITY_WIDTH, $this->displayEntityWidth); + $nbt->setFloat(self::TAG_ENTITY_HEIGHT, $this->displayEntityHeight); + $nbt->setFloat(self::TAG_ENTITY_SCALE, $this->displayEntityScale); + } + + protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ + $nbt->setString(self::TAG_ENTITY_TYPE_ID, $this->entityTypeId); + + //TODO: we can't set SpawnData here because it might crash the client if it's from a PC world (we need to implement full deserialization) + + $nbt->setFloat(self::TAG_ENTITY_SCALE, $this->displayEntityScale); + } + + public function onUpdate() : bool{ + return false; //TODO + } +} diff --git a/src/pocketmine/block/tile/TileFactory.php b/src/pocketmine/block/tile/TileFactory.php index 811dd719f4..a6c5217aa5 100644 --- a/src/pocketmine/block/tile/TileFactory.php +++ b/src/pocketmine/block/tile/TileFactory.php @@ -56,6 +56,7 @@ final class TileFactory{ self::register(FlowerPot::class, ["FlowerPot", "minecraft:flower_pot"]); self::register(Furnace::class, ["Furnace", "minecraft:furnace"]); self::register(ItemFrame::class, ["ItemFrame"]); //this is an entity in PC + self::register(MonsterSpawner::class, ["MobSpawner", "minecraft:mob_spawner"]); self::register(Note::class, ["Music", "minecraft:noteblock"]); self::register(Sign::class, ["Sign", "minecraft:sign"]); self::register(Skull::class, ["Skull", "minecraft:skull"]); @@ -79,7 +80,6 @@ final class TileFactory{ //TODO: JigsawBlock //TODO: Jukebox //TODO: Lectern - //TODO: MobSpawner //TODO: MovingBlock //TODO: NetherReactor //TODO: PistonArm From 77ace57985d8c03125a26d789432e22ff4cc1fdc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 30 May 2019 19:44:29 +0100 Subject: [PATCH 0864/3224] BlockEventPacket: added a ::create() method --- src/pocketmine/inventory/ChestInventory.php | 9 ++------- .../network/mcpe/protocol/BlockEventPacket.php | 11 +++++++++++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/inventory/ChestInventory.php b/src/pocketmine/inventory/ChestInventory.php index 04e93617d0..ae6850d83e 100644 --- a/src/pocketmine/inventory/ChestInventory.php +++ b/src/pocketmine/inventory/ChestInventory.php @@ -86,12 +86,7 @@ class ChestInventory extends ContainerInventory{ protected function broadcastBlockEventPacket(bool $isOpen) : void{ $holder = $this->getHolder(); - $pk = new BlockEventPacket(); - $pk->x = (int) $holder->x; - $pk->y = (int) $holder->y; - $pk->z = (int) $holder->z; - $pk->eventType = 1; //it's always 1 for a chest - $pk->eventData = $isOpen ? 1 : 0; - $holder->getWorld()->broadcastPacketToViewers($holder, $pk); + //event ID is always 1 for a chest + $holder->getWorld()->broadcastPacketToViewers($holder, BlockEventPacket::create(1, $isOpen ? 1 : 0, $holder->asVector3())); } } diff --git a/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php b/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php index 755b971e21..58dae3a629 100644 --- a/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\SessionHandler; class BlockEventPacket extends DataPacket implements ClientboundPacket{ @@ -42,6 +43,16 @@ class BlockEventPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $eventData; + public static function create(int $eventId, int $eventData, Vector3 $pos) : self{ + $pk = new self; + $pk->eventType = $eventId; + $pk->eventData = $eventData; + $pk->x = $pos->getFloorX(); + $pk->y = $pos->getFloorY(); + $pk->z = $pos->getFloorZ(); + return $pk; + } + protected function decodePayload() : void{ $this->getBlockPosition($this->x, $this->y, $this->z); $this->eventType = $this->getVarInt(); From 1049ffecc94097161cf0b6e6d53e4d25f03ccfa2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 30 May 2019 19:51:27 +0100 Subject: [PATCH 0865/3224] Sound->encode() now accepts Vector3|null this will be needed for proper no-relative sound support. --- src/pocketmine/world/sound/ArrowHitSound.php | 2 +- src/pocketmine/world/sound/BlockBreakSound.php | 2 +- src/pocketmine/world/sound/BlockPlaceSound.php | 2 +- src/pocketmine/world/sound/BowShootSound.php | 2 +- src/pocketmine/world/sound/BucketEmptyLavaSound.php | 2 +- src/pocketmine/world/sound/BucketEmptyWaterSound.php | 2 +- src/pocketmine/world/sound/BucketFillLavaSound.php | 2 +- src/pocketmine/world/sound/BucketFillWaterSound.php | 2 +- src/pocketmine/world/sound/ChestCloseSound.php | 2 +- src/pocketmine/world/sound/ChestOpenSound.php | 2 +- src/pocketmine/world/sound/EnderChestCloseSound.php | 2 +- src/pocketmine/world/sound/EnderChestOpenSound.php | 2 +- src/pocketmine/world/sound/ExplodeSound.php | 2 +- src/pocketmine/world/sound/FlintSteelSound.php | 2 +- src/pocketmine/world/sound/IgniteSound.php | 2 +- src/pocketmine/world/sound/ItemBreakSound.php | 2 +- src/pocketmine/world/sound/LevelEventSound.php | 2 +- src/pocketmine/world/sound/PotionSplashSound.php | 2 +- src/pocketmine/world/sound/RedstonePowerOffSound.php | 2 +- src/pocketmine/world/sound/RedstonePowerOnSound.php | 2 +- src/pocketmine/world/sound/Sound.php | 4 ++-- src/pocketmine/world/sound/ThrowSound.php | 2 +- src/pocketmine/world/sound/TotemUseSound.php | 2 +- src/pocketmine/world/sound/XpCollectSound.php | 2 +- src/pocketmine/world/sound/XpLevelUpSound.php | 2 +- 25 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/pocketmine/world/sound/ArrowHitSound.php b/src/pocketmine/world/sound/ArrowHitSound.php index 0490d5fa8d..84899ab594 100644 --- a/src/pocketmine/world/sound/ArrowHitSound.php +++ b/src/pocketmine/world/sound/ArrowHitSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ArrowHitSound implements Sound{ - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BOW_HIT, $pos); } } diff --git a/src/pocketmine/world/sound/BlockBreakSound.php b/src/pocketmine/world/sound/BlockBreakSound.php index 32ea532daa..8beed8cd7f 100644 --- a/src/pocketmine/world/sound/BlockBreakSound.php +++ b/src/pocketmine/world/sound/BlockBreakSound.php @@ -36,7 +36,7 @@ class BlockBreakSound implements Sound{ $this->block = $block; } - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BREAK, $pos, $this->block->getRuntimeId()); } } diff --git a/src/pocketmine/world/sound/BlockPlaceSound.php b/src/pocketmine/world/sound/BlockPlaceSound.php index 3f5427472a..ae8e2e277b 100644 --- a/src/pocketmine/world/sound/BlockPlaceSound.php +++ b/src/pocketmine/world/sound/BlockPlaceSound.php @@ -36,7 +36,7 @@ class BlockPlaceSound implements Sound{ $this->block = $block; } - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_PLACE, $pos, $this->block->getRuntimeId()); } } diff --git a/src/pocketmine/world/sound/BowShootSound.php b/src/pocketmine/world/sound/BowShootSound.php index 00355b17fd..ddbc310e90 100644 --- a/src/pocketmine/world/sound/BowShootSound.php +++ b/src/pocketmine/world/sound/BowShootSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BowShootSound implements Sound{ - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BOW, $pos); } } diff --git a/src/pocketmine/world/sound/BucketEmptyLavaSound.php b/src/pocketmine/world/sound/BucketEmptyLavaSound.php index d33fa5d156..da9f4a703b 100644 --- a/src/pocketmine/world/sound/BucketEmptyLavaSound.php +++ b/src/pocketmine/world/sound/BucketEmptyLavaSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BucketEmptyLavaSound implements Sound{ - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BUCKET_EMPTY_LAVA, $pos); } } diff --git a/src/pocketmine/world/sound/BucketEmptyWaterSound.php b/src/pocketmine/world/sound/BucketEmptyWaterSound.php index 47a4686d33..6c50d9ef7d 100644 --- a/src/pocketmine/world/sound/BucketEmptyWaterSound.php +++ b/src/pocketmine/world/sound/BucketEmptyWaterSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BucketEmptyWaterSound implements Sound{ - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BUCKET_EMPTY_WATER, $pos); } } diff --git a/src/pocketmine/world/sound/BucketFillLavaSound.php b/src/pocketmine/world/sound/BucketFillLavaSound.php index 83cebdc0f9..a20601ef7b 100644 --- a/src/pocketmine/world/sound/BucketFillLavaSound.php +++ b/src/pocketmine/world/sound/BucketFillLavaSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BucketFillLavaSound implements Sound{ - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BUCKET_FILL_LAVA, $pos); } } diff --git a/src/pocketmine/world/sound/BucketFillWaterSound.php b/src/pocketmine/world/sound/BucketFillWaterSound.php index 24bb709838..29e05e697e 100644 --- a/src/pocketmine/world/sound/BucketFillWaterSound.php +++ b/src/pocketmine/world/sound/BucketFillWaterSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BucketFillWaterSound implements Sound{ - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BUCKET_FILL_WATER, $pos); } } diff --git a/src/pocketmine/world/sound/ChestCloseSound.php b/src/pocketmine/world/sound/ChestCloseSound.php index 78fc5e740d..e3476e47d4 100644 --- a/src/pocketmine/world/sound/ChestCloseSound.php +++ b/src/pocketmine/world/sound/ChestCloseSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ChestCloseSound implements Sound{ - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_CHEST_CLOSED, $pos); } } diff --git a/src/pocketmine/world/sound/ChestOpenSound.php b/src/pocketmine/world/sound/ChestOpenSound.php index 33dde66272..2668b8e8d2 100644 --- a/src/pocketmine/world/sound/ChestOpenSound.php +++ b/src/pocketmine/world/sound/ChestOpenSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ChestOpenSound implements Sound{ - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_CHEST_OPEN, $pos); } } diff --git a/src/pocketmine/world/sound/EnderChestCloseSound.php b/src/pocketmine/world/sound/EnderChestCloseSound.php index d092646c20..021d6c3570 100644 --- a/src/pocketmine/world/sound/EnderChestCloseSound.php +++ b/src/pocketmine/world/sound/EnderChestCloseSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class EnderChestCloseSound implements Sound{ - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_ENDERCHEST_CLOSED, $pos); } } diff --git a/src/pocketmine/world/sound/EnderChestOpenSound.php b/src/pocketmine/world/sound/EnderChestOpenSound.php index e8b02367fd..13788a6e8a 100644 --- a/src/pocketmine/world/sound/EnderChestOpenSound.php +++ b/src/pocketmine/world/sound/EnderChestOpenSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class EnderChestOpenSound implements Sound{ - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_ENDERCHEST_OPEN, $pos); } } diff --git a/src/pocketmine/world/sound/ExplodeSound.php b/src/pocketmine/world/sound/ExplodeSound.php index 11849ef1f8..7e9ee4715d 100644 --- a/src/pocketmine/world/sound/ExplodeSound.php +++ b/src/pocketmine/world/sound/ExplodeSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ExplodeSound implements Sound{ - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_EXPLODE, $pos); } } diff --git a/src/pocketmine/world/sound/FlintSteelSound.php b/src/pocketmine/world/sound/FlintSteelSound.php index 94d130bdfa..eb4fe3e934 100644 --- a/src/pocketmine/world/sound/FlintSteelSound.php +++ b/src/pocketmine/world/sound/FlintSteelSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class FlintSteelSound implements Sound{ - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_IGNITE, $pos); } } diff --git a/src/pocketmine/world/sound/IgniteSound.php b/src/pocketmine/world/sound/IgniteSound.php index 4d70f65c5f..4066ef1894 100644 --- a/src/pocketmine/world/sound/IgniteSound.php +++ b/src/pocketmine/world/sound/IgniteSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class IgniteSound implements Sound{ - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_IGNITE, 0, $pos); } } diff --git a/src/pocketmine/world/sound/ItemBreakSound.php b/src/pocketmine/world/sound/ItemBreakSound.php index d1246c712c..7dd7de43b1 100644 --- a/src/pocketmine/world/sound/ItemBreakSound.php +++ b/src/pocketmine/world/sound/ItemBreakSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ItemBreakSound implements Sound{ - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BREAK, $pos); } } diff --git a/src/pocketmine/world/sound/LevelEventSound.php b/src/pocketmine/world/sound/LevelEventSound.php index 1e2d75b454..14c0fb7caf 100644 --- a/src/pocketmine/world/sound/LevelEventSound.php +++ b/src/pocketmine/world/sound/LevelEventSound.php @@ -48,7 +48,7 @@ abstract class LevelEventSound implements Sound{ $this->pitch = $pitch * 1000; } - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelEventPacket::create($this->getLevelEventId(), (int) $this->pitch, $pos); } } diff --git a/src/pocketmine/world/sound/PotionSplashSound.php b/src/pocketmine/world/sound/PotionSplashSound.php index 24ce0fcdf7..97c1dab083 100644 --- a/src/pocketmine/world/sound/PotionSplashSound.php +++ b/src/pocketmine/world/sound/PotionSplashSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class PotionSplashSound implements Sound{ - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_GLASS, $pos); } } diff --git a/src/pocketmine/world/sound/RedstonePowerOffSound.php b/src/pocketmine/world/sound/RedstonePowerOffSound.php index 5e2dcf16e6..f8ea474f3b 100644 --- a/src/pocketmine/world/sound/RedstonePowerOffSound.php +++ b/src/pocketmine/world/sound/RedstonePowerOffSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class RedstonePowerOffSound implements Sound{ - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_POWER_OFF, $pos); } } diff --git a/src/pocketmine/world/sound/RedstonePowerOnSound.php b/src/pocketmine/world/sound/RedstonePowerOnSound.php index bcd2389396..c01ee10b4b 100644 --- a/src/pocketmine/world/sound/RedstonePowerOnSound.php +++ b/src/pocketmine/world/sound/RedstonePowerOnSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class RedstonePowerOnSound implements Sound{ - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_POWER_ON, $pos); } } diff --git a/src/pocketmine/world/sound/Sound.php b/src/pocketmine/world/sound/Sound.php index 63f6739be4..ad486f0b6c 100644 --- a/src/pocketmine/world/sound/Sound.php +++ b/src/pocketmine/world/sound/Sound.php @@ -29,9 +29,9 @@ use pocketmine\network\mcpe\protocol\ClientboundPacket; interface Sound{ /** - * @param Vector3 $pos + * @param Vector3|null $pos * * @return ClientboundPacket|ClientboundPacket[] */ - public function encode(Vector3 $pos); + public function encode(?Vector3 $pos); } diff --git a/src/pocketmine/world/sound/ThrowSound.php b/src/pocketmine/world/sound/ThrowSound.php index bc387654a2..feb0ca7249 100644 --- a/src/pocketmine/world/sound/ThrowSound.php +++ b/src/pocketmine/world/sound/ThrowSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ThrowSound implements Sound{ - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_THROW, $pos, -1, "minecraft:player"); } } diff --git a/src/pocketmine/world/sound/TotemUseSound.php b/src/pocketmine/world/sound/TotemUseSound.php index 20d3810f2d..064008942d 100644 --- a/src/pocketmine/world/sound/TotemUseSound.php +++ b/src/pocketmine/world/sound/TotemUseSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class TotemUseSound implements Sound{ - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_TOTEM, 0, $pos); } } diff --git a/src/pocketmine/world/sound/XpCollectSound.php b/src/pocketmine/world/sound/XpCollectSound.php index 8b3994eccf..f87c2719ff 100644 --- a/src/pocketmine/world/sound/XpCollectSound.php +++ b/src/pocketmine/world/sound/XpCollectSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class XpCollectSound implements Sound{ - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ORB, 0, $pos); } } diff --git a/src/pocketmine/world/sound/XpLevelUpSound.php b/src/pocketmine/world/sound/XpLevelUpSound.php index e173ca7be0..6e41e96897 100644 --- a/src/pocketmine/world/sound/XpLevelUpSound.php +++ b/src/pocketmine/world/sound/XpLevelUpSound.php @@ -44,7 +44,7 @@ class XpLevelUpSound implements Sound{ return $this->xpLevel; } - public function encode(Vector3 $pos){ + public function encode(?Vector3 $pos){ //No idea why such odd numbers, but this works... //TODO: check arbitrary volume return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_LEVELUP, $pos, 0x10000000 * intdiv(min(30, $this->xpLevel), 5)); From e091cfe1debc94a0091658e7fdb2fc5e9019a4f1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 31 May 2019 18:59:18 +0100 Subject: [PATCH 0866/3224] interface Container extends InventoryHolder --- src/pocketmine/block/tile/Chest.php | 3 +-- src/pocketmine/block/tile/Container.php | 8 ++------ src/pocketmine/block/tile/Furnace.php | 3 +-- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/pocketmine/block/tile/Chest.php b/src/pocketmine/block/tile/Chest.php index c766ac9196..2654d8189d 100644 --- a/src/pocketmine/block/tile/Chest.php +++ b/src/pocketmine/block/tile/Chest.php @@ -25,13 +25,12 @@ namespace pocketmine\block\tile; use pocketmine\inventory\ChestInventory; use pocketmine\inventory\DoubleChestInventory; -use pocketmine\inventory\InventoryHolder; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\world\World; -class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ +class Chest extends Spawnable implements Container, Nameable{ use NameableTrait { addAdditionalSpawnData as addNameSpawnData; } diff --git a/src/pocketmine/block/tile/Container.php b/src/pocketmine/block/tile/Container.php index d10a376726..0587d22d56 100644 --- a/src/pocketmine/block/tile/Container.php +++ b/src/pocketmine/block/tile/Container.php @@ -24,16 +24,12 @@ declare(strict_types=1); namespace pocketmine\block\tile; use pocketmine\inventory\Inventory; +use pocketmine\inventory\InventoryHolder; -interface Container{ +interface Container extends InventoryHolder{ public const TAG_ITEMS = "Items"; public const TAG_LOCK = "Lock"; - /** - * @return Inventory - */ - public function getInventory(); - /** * @return Inventory */ diff --git a/src/pocketmine/block/tile/Furnace.php b/src/pocketmine/block/tile/Furnace.php index d1324777d9..73a4a2a9d3 100644 --- a/src/pocketmine/block/tile/Furnace.php +++ b/src/pocketmine/block/tile/Furnace.php @@ -30,7 +30,6 @@ use pocketmine\inventory\CallbackInventoryChangeListener; use pocketmine\inventory\FurnaceInventory; use pocketmine\inventory\FurnaceRecipe; use pocketmine\inventory\Inventory; -use pocketmine\inventory\InventoryHolder; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\Vector3; @@ -40,7 +39,7 @@ use pocketmine\world\World; use function ceil; use function max; -class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{ +class Furnace extends Spawnable implements Container, Nameable{ use NameableTrait { addAdditionalSpawnData as addNameSpawnData; } From ad79e6cd8e121ae3db02a10b7e86bc1bba8287f7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 31 May 2019 19:32:19 +0100 Subject: [PATCH 0867/3224] partial implementation of hopper (just enough to load/save all data) --- src/pocketmine/block/BlockFactory.php | 2 + src/pocketmine/block/BlockLegacyMetadata.php | 2 + src/pocketmine/block/Hopper.php | 88 ++++++++++++++++++++ src/pocketmine/block/tile/Hopper.php | 84 +++++++++++++++++++ src/pocketmine/block/tile/TileFactory.php | 2 +- src/pocketmine/inventory/HopperInventory.php | 38 +++++++++ 6 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 src/pocketmine/block/Hopper.php create mode 100644 src/pocketmine/block/tile/Hopper.php create mode 100644 src/pocketmine/inventory/HopperInventory.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 8881f923e5..80347af5f6 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -36,6 +36,7 @@ use pocketmine\block\tile\EnchantTable as TileEnchantingTable; use pocketmine\block\tile\EnderChest as TileEnderChest; use pocketmine\block\tile\FlowerPot as TileFlowerPot; use pocketmine\block\tile\Furnace as TileFurnace; +use pocketmine\block\tile\Hopper as TileHopper; use pocketmine\block\tile\ItemFrame as TileItemFrame; use pocketmine\block\tile\MonsterSpawner as TileMonsterSpawner; use pocketmine\block\tile\Note as TileNote; @@ -178,6 +179,7 @@ class BlockFactory{ self::register(new HardenedGlass(new BID(Ids::HARD_GLASS), "Hardened Glass")); self::register(new HardenedGlassPane(new BID(Ids::HARD_GLASS_PANE), "Hardened Glass Pane")); self::register(new HayBale(new BID(Ids::HAY_BALE), "Hay Bale")); + self::register(new Hopper(new BID(Ids::HOPPER_BLOCK, 0, ItemIds::HOPPER, TileHopper::class), "Hopper", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 15.0))); self::register(new Ice(new BID(Ids::ICE), "Ice")); self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE), "Infested Stone") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ diff --git a/src/pocketmine/block/BlockLegacyMetadata.php b/src/pocketmine/block/BlockLegacyMetadata.php index 5bad764388..899e93554e 100644 --- a/src/pocketmine/block/BlockLegacyMetadata.php +++ b/src/pocketmine/block/BlockLegacyMetadata.php @@ -84,6 +84,8 @@ interface BlockLegacyMetadata{ public const FLOWER_POT_FLAG_OCCUPIED = 0x01; + public const HOPPER_FLAG_POWERED = 0x08; + public const INFESTED_STONE = 0; public const INFESTED_COBBLESTONE = 1; public const INFESTED_STONE_BRICK = 2; diff --git a/src/pocketmine/block/Hopper.php b/src/pocketmine/block/Hopper.php new file mode 100644 index 0000000000..d626534f2f --- /dev/null +++ b/src/pocketmine/block/Hopper.php @@ -0,0 +1,88 @@ +facing = $facing; + $this->powered = ($stateMeta & BlockLegacyMetadata::HOPPER_FLAG_POWERED) !== 0; + } + + protected function writeStateToMeta() : int{ + return $this->facing | ($this->powered ? BlockLegacyMetadata::HOPPER_FLAG_POWERED : 0); + } + + public function getStateBitmask() : int{ + return 0b1111; + } + + protected function recalculateCollisionBoxes() : array{ + $result = [ + AxisAlignedBB::one()->trim(Facing::UP, 6 / 16) //the empty area around the bottom is currently considered solid + ]; + + foreach(Facing::HORIZONTAL as $f){ //add the frame parts around the bowl + $result[] = AxisAlignedBB::one()->trim($f, 14 / 16); + } + return $result; + } + + public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + $this->facing = $face === Facing::DOWN ? Facing::DOWN : Facing::opposite($face); + + return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($player !== null){ + $tile = $this->world->getTile($this); + if($tile instanceof TileHopper){ //TODO: find a way to have inventories open on click without this boilerplate in every block + $player->addWindow($tile->getInventory()); + } + return true; + } + return false; + } + + //TODO: redstone logic, sucking logic +} diff --git a/src/pocketmine/block/tile/Hopper.php b/src/pocketmine/block/tile/Hopper.php new file mode 100644 index 0000000000..496975a79d --- /dev/null +++ b/src/pocketmine/block/tile/Hopper.php @@ -0,0 +1,84 @@ +inventory = new HopperInventory($this); + parent::__construct($world, $pos); + } + + public function readSaveData(CompoundTag $nbt) : void{ + $this->loadItems($nbt); + $this->loadName($nbt); + + $this->transferCooldown = $nbt->getInt(self::TAG_TRANSFER_COOLDOWN, 0); + } + + protected function writeSaveData(CompoundTag $nbt) : void{ + $this->saveItems($nbt); + $this->saveName($nbt); + + $nbt->setInt(self::TAG_TRANSFER_COOLDOWN, $this->transferCooldown); + } + + public function getDefaultName() : string{ + return "Hopper"; + } + + /** + * @return HopperInventory + */ + public function getInventory(){ + return $this->inventory; + } + + /** + * @return HopperInventory + */ + public function getRealInventory(){ + return $this->inventory; + } + + public function onUpdate() : bool{ + return false; //TODO + } +} diff --git a/src/pocketmine/block/tile/TileFactory.php b/src/pocketmine/block/tile/TileFactory.php index a6c5217aa5..e804dbf0d6 100644 --- a/src/pocketmine/block/tile/TileFactory.php +++ b/src/pocketmine/block/tile/TileFactory.php @@ -55,6 +55,7 @@ final class TileFactory{ self::register(EnderChest::class, ["EnderChest", "minecraft:ender_chest"]); self::register(FlowerPot::class, ["FlowerPot", "minecraft:flower_pot"]); self::register(Furnace::class, ["Furnace", "minecraft:furnace"]); + self::register(Hopper::class, ["Hopper", "minecraft:hopper"]); self::register(ItemFrame::class, ["ItemFrame"]); //this is an entity in PC self::register(MonsterSpawner::class, ["MobSpawner", "minecraft:mob_spawner"]); self::register(Note::class, ["Music", "minecraft:noteblock"]); @@ -76,7 +77,6 @@ final class TileFactory{ //TODO: Dropper //TODO: EndGateway //TODO: EndPortal - //TODO: Hopper //TODO: JigsawBlock //TODO: Jukebox //TODO: Lectern diff --git a/src/pocketmine/inventory/HopperInventory.php b/src/pocketmine/inventory/HopperInventory.php new file mode 100644 index 0000000000..728453c9c7 --- /dev/null +++ b/src/pocketmine/inventory/HopperInventory.php @@ -0,0 +1,38 @@ + Date: Sat, 1 Jun 2019 12:11:19 +0100 Subject: [PATCH 0868/3224] updated consistency check for ad79e6cd8e121ae3db02a10b7e86bc1bba8287f7 --- tests/phpunit/block/block_factory_consistency_check.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index f0c63c19b2..b0f30de6ad 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From 087df45a3c4b4463bf0a6c0584645c6f652876cf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 3 Jun 2019 16:17:12 +0100 Subject: [PATCH 0869/3224] added some effect ID constants --- src/pocketmine/entity/effect/Effect.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pocketmine/entity/effect/Effect.php b/src/pocketmine/entity/effect/Effect.php index 5910e8eea7..28832b1758 100644 --- a/src/pocketmine/entity/effect/Effect.php +++ b/src/pocketmine/entity/effect/Effect.php @@ -59,6 +59,9 @@ class Effect{ public const LEVITATION = 24; //TODO public const FATAL_POISON = 25; public const CONDUIT_POWER = 26; + public const SLOW_FALLING = 27; + public const BAD_OMEN = 28; + public const VILLAGE_HERO = 29; /** @var Effect[] */ protected static $effects = []; From 56a4e8c032d5571e521cf679aecaca6d6b47bd1b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 3 Jun 2019 19:17:13 +0100 Subject: [PATCH 0870/3224] Hopper: add more boilerplate code to fix inventory leak --- src/pocketmine/block/tile/Hopper.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/pocketmine/block/tile/Hopper.php b/src/pocketmine/block/tile/Hopper.php index 496975a79d..bc8018ee46 100644 --- a/src/pocketmine/block/tile/Hopper.php +++ b/src/pocketmine/block/tile/Hopper.php @@ -60,6 +60,15 @@ class Hopper extends Spawnable implements Container, Nameable{ $nbt->setInt(self::TAG_TRANSFER_COOLDOWN, $this->transferCooldown); } + public function close() : void{ + if(!$this->closed){ + $this->inventory->removeAllViewers(true); + $this->inventory = null; + + parent::close(); + } + } + public function getDefaultName() : string{ return "Hopper"; } From df0acea2f4f4dd04d4ccb9d672faa7b1c782e6c4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 3 Jun 2019 19:30:26 +0100 Subject: [PATCH 0871/3224] Player: add a prefixed logger --- src/pocketmine/Player.php | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 27495eaad6..0ab87e1502 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -269,6 +269,9 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** @var Form[] */ protected $forms = []; + /** @var \Logger */ + protected $logger; + /** * @param Server $server * @param NetworkSession $session @@ -276,13 +279,16 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @param bool $authenticated */ public function __construct(Server $server, NetworkSession $session, PlayerInfo $playerInfo, bool $authenticated){ + $username = TextFormat::clean($playerInfo->getUsername()); + $this->logger = new \PrefixedLogger($server->getLogger(), "Player: $username"); + $this->server = $server; $this->networkSession = $session; $this->playerInfo = $playerInfo; $this->authenticated = $authenticated; $this->skin = $this->playerInfo->getSkin(); - $this->username = TextFormat::clean($this->playerInfo->getUsername()); + $this->username = $username; $this->displayName = $this->username; $this->iusername = strtolower($this->username); $this->locale = $this->playerInfo->getLocale(); @@ -648,7 +654,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->networkSession->syncViewAreaRadius($this->viewDistance); - $this->server->getLogger()->debug("Setting view distance for " . $this->getName() . " to " . $this->viewDistance . " (requested " . $distance . ")"); + $this->logger->debug("Setting view distance to " . $this->viewDistance . " (requested " . $distance . ")"); } /** @@ -1428,7 +1434,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $newPos = $newPos->asVector3(); if($this->isTeleporting and $newPos->distanceSquared($this) > 1){ //Tolerate up to 1 block to avoid problems with client-sided physics when spawning in blocks $this->sendPosition($this, null, null, MovePlayerPacket::MODE_RESET); - $this->server->getLogger()->debug("Got outdated pre-teleport movement from " . $this->getName() . ", received " . $newPos . ", expected " . $this->asVector3()); + $this->logger->debug("Got outdated pre-teleport movement, received " . $newPos . ", expected " . $this->asVector3()); //Still getting movements from before teleport, ignore them return false; } @@ -1470,8 +1476,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * If you must tamper with this code, be aware that this can cause very nasty results. Do not waste our time * asking for help if you suffer the consequences of messing with this. */ - $this->server->getLogger()->warning($this->getName() . " moved too fast, reverting movement"); - $this->server->getLogger()->debug("Old position: " . $this->asVector3() . ", new position: " . $this->newPosition); + $this->logger->warning("Moved too fast, reverting movement"); + $this->logger->debug("Old position: " . $this->asVector3() . ", new position: " . $this->newPosition); $revert = true; }elseif(!$this->world->isInLoadedTerrain($newPos) or !$this->world->isChunkGenerated($newPos->getFloorX() >> 4, $newPos->getFloorZ() >> 4)){ $revert = true; @@ -1495,8 +1501,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if(!$ev->isCancelled()){ $revert = true; - $this->server->getLogger()->warning($this->getServer()->getLanguage()->translateString("pocketmine.player.invalidMove", [$this->getName()])); - $this->server->getLogger()->debug("Old position: " . $this->asVector3() . ", new position: " . $this->newPosition); + $this->logger->warning($this->getServer()->getLanguage()->translateString("pocketmine.player.invalidMove", [$this->getName()])); + $this->logger->debug("Old position: " . $this->asVector3() . ", new position: " . $this->newPosition); } } @@ -1979,7 +1985,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } if($entity instanceof ItemEntity or $entity instanceof Arrow){ $this->kick("Attempting to attack an invalid entity"); - $this->server->getLogger()->warning($this->getServer()->getLanguage()->translateString("pocketmine.player.invalidEntity", [$this->getName()])); + $this->logger->warning($this->getServer()->getLanguage()->translateString("pocketmine.player.invalidEntity", [$this->getName()])); return false; } @@ -2308,15 +2314,15 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, */ public function onFormSubmit(int $formId, $responseData) : bool{ if(!isset($this->forms[$formId])){ - $this->server->getLogger()->debug("Got unexpected response for form $formId"); + $this->logger->debug("Got unexpected response for form $formId"); return false; } try{ $this->forms[$formId]->handleResponse($this, $responseData); }catch(FormValidationException $e){ - $this->server->getLogger()->critical("Failed to validate form " . get_class($this->forms[$formId]) . ": " . $e->getMessage()); - $this->server->getLogger()->logException($e); + $this->logger->critical("Failed to validate form " . get_class($this->forms[$formId]) . ": " . $e->getMessage()); + $this->logger->logException($e); }finally{ unset($this->forms[$formId]); } From 3569f8dfbe9c5f28a94d796cb6b217db580efe2a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 4 Jun 2019 13:44:35 +0100 Subject: [PATCH 0872/3224] QueryHandler: move to a prefixed logger --- src/pocketmine/network/query/QueryHandler.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/pocketmine/network/query/QueryHandler.php b/src/pocketmine/network/query/QueryHandler.php index 1bc42178e1..36d6bef556 100644 --- a/src/pocketmine/network/query/QueryHandler.php +++ b/src/pocketmine/network/query/QueryHandler.php @@ -47,11 +47,15 @@ class QueryHandler implements RawPacketHandler{ /** @var string */ private $token; + /** @var \Logger */ + private $logger; + public const HANDSHAKE = 9; public const STATISTICS = 0; public function __construct(){ $this->server = Server::getInstance(); + $this->logger = new \PrefixedLogger($this->server->getLogger(), "Query Handler"); $addr = $this->server->getIp(); $port = $this->server->getPort(); @@ -66,18 +70,13 @@ class QueryHandler implements RawPacketHandler{ $this->regenerateToken(); $this->lastToken = $this->token; - $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.server.query.running", [$addr, $port])); + $this->logger->info($this->server->getLanguage()->translateString("pocketmine.server.query.running", [$addr, $port])); } public function getPattern() : string{ return '/^\xfe\xfd.+$/s'; } - private function debug(string $message) : void{ - //TODO: replace this with a proper prefixed logger - $this->server->getLogger()->debug("[Query] $message"); - } - public function regenerateToken() : void{ $this->lastToken = $this->token; $this->token = random_bytes(16); @@ -117,7 +116,7 @@ class QueryHandler implements RawPacketHandler{ case self::STATISTICS: //Stat $token = $stream->getInt(); if($token !== ($t1 = self::getTokenString($this->token, $address)) and $token !== ($t2 = self::getTokenString($this->lastToken, $address))){ - $this->debug("Bad token $token from $address $port, expected $t1 or $t2"); + $this->logger->debug("Bad token $token from $address $port, expected $t1 or $t2"); return true; } @@ -137,7 +136,7 @@ class QueryHandler implements RawPacketHandler{ return false; } }catch(BinaryDataException $e){ - $this->debug("Bad packet from $address $port: " . $e->getMessage()); + $this->logger->debug("Bad packet from $address $port: " . $e->getMessage()); return false; } } From e69ab6003498903d1c94466e0ed8ee92ae45decd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 4 Jun 2019 13:49:07 +0100 Subject: [PATCH 0873/3224] MemoryManager: use prefixed loggers --- src/pocketmine/MemoryManager.php | 23 +++++++++++-------- .../scheduler/DumpWorkerMemoryTask.php | 2 +- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/pocketmine/MemoryManager.php b/src/pocketmine/MemoryManager.php index 79c31a95dd..658597d86f 100644 --- a/src/pocketmine/MemoryManager.php +++ b/src/pocketmine/MemoryManager.php @@ -110,8 +110,12 @@ class MemoryManager{ /** @var bool */ private $dumpWorkers = true; + /** @var \Logger */ + private $logger; + public function __construct(Server $server){ $this->server = $server; + $this->logger = new \PrefixedLogger($server->getLogger(), "Memory Manager"); $this->init(); } @@ -211,7 +215,7 @@ class MemoryManager{ * @param int $triggerCount */ public function trigger(int $memory, int $limit, bool $global = false, int $triggerCount = 0) : void{ - $this->server->getLogger()->debug(sprintf("[Memory Manager] %sLow memory triggered, limit %gMB, using %gMB", + $this->logger->debug(sprintf("%sLow memory triggered, limit %gMB, using %gMB", $global ? "Global " : "", round(($limit / 1024) / 1024, 2), round(($memory / 1024) / 1024, 2))); if($this->lowMemClearWorldCache){ foreach($this->server->getWorldManager()->getWorlds() as $world){ @@ -233,7 +237,7 @@ class MemoryManager{ $cycles = $this->triggerGarbageCollector(); } - $this->server->getLogger()->debug(sprintf("[Memory Manager] Freed %gMB, $cycles cycles", round(($ev->getMemoryFreed() / 1024) / 1024, 2))); + $this->logger->debug(sprintf("Freed %gMB, $cycles cycles", round(($ev->getMemoryFreed() / 1024) / 1024, 2))); } /** @@ -285,7 +289,7 @@ class MemoryManager{ if($this->garbageCollectionAsync){ $pool = $this->server->getAsyncPool(); if(($w = $pool->shutdownUnusedWorkers()) > 0){ - $this->server->getLogger()->debug("Shut down $w idle async pool workers"); + $this->logger->debug("Shut down $w idle async pool workers"); } foreach($pool->getRunningWorkers() as $i){ $pool->submitTaskToWorker(new GarbageCollectionTask(), $i); @@ -307,8 +311,9 @@ class MemoryManager{ * @param int $maxStringSize */ public function dumpServerMemory(string $outputFolder, int $maxNesting, int $maxStringSize) : void{ - $this->server->getLogger()->notice("[Dump] After the memory dump is done, the server might crash"); - self::dumpMemory($this->server, $outputFolder, $maxNesting, $maxStringSize, $this->server->getLogger()); + $logger = new \PrefixedLogger($this->server->getLogger(), "Memory Dump"); + $logger->notice("After the memory dump is done, the server might crash"); + self::dumpMemory($this->server, $outputFolder, $maxNesting, $maxStringSize, $logger); if($this->dumpWorkers){ $pool = $this->server->getAsyncPool(); @@ -373,7 +378,7 @@ class MemoryManager{ } file_put_contents($outputFolder . "/staticProperties.js", json_encode($staticProperties, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); - $logger->info("[Dump] Wrote $staticCount static properties"); + $logger->info("Wrote $staticCount static properties"); if(isset($GLOBALS)){ //This might be null if we're on a different thread $globalVariables = []; @@ -401,7 +406,7 @@ class MemoryManager{ } file_put_contents($outputFolder . "/globalVariables.js", json_encode($globalVariables, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); - $logger->info("[Dump] Wrote $globalCount global variables"); + $logger->info("Wrote $globalCount global variables"); } self::continueDump($startingObject, $data, $objects, $refCounts, 0, $maxNesting, $maxStringSize); @@ -462,7 +467,7 @@ class MemoryManager{ }while($continue); - $logger->info("[Dump] Wrote " . count($objects) . " objects"); + $logger->info("Wrote " . count($objects) . " objects"); fclose($obData); @@ -472,7 +477,7 @@ class MemoryManager{ arsort($instanceCounts, SORT_NUMERIC); file_put_contents($outputFolder . "/instanceCounts.js", json_encode($instanceCounts, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); - $logger->info("[Dump] Finished!"); + $logger->info("Finished!"); ini_set('memory_limit', $hardLimit); gc_enable(); diff --git a/src/pocketmine/scheduler/DumpWorkerMemoryTask.php b/src/pocketmine/scheduler/DumpWorkerMemoryTask.php index 3ecd2309ee..19cd248dee 100644 --- a/src/pocketmine/scheduler/DumpWorkerMemoryTask.php +++ b/src/pocketmine/scheduler/DumpWorkerMemoryTask.php @@ -54,7 +54,7 @@ class DumpWorkerMemoryTask extends AsyncTask{ $this->outputFolder . DIRECTORY_SEPARATOR . "AsyncWorker#" . $this->worker->getAsyncWorkerId(), $this->maxNesting, $this->maxStringSize, - $this->worker->getLogger() + new \PrefixedLogger($this->worker->getLogger(), "Memory Dump") ); } } From 67432344615c3be2155cb7c3cda48cad682b38eb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 4 Jun 2019 13:51:17 +0100 Subject: [PATCH 0874/3224] AutoUpdater: add a prefixed logger --- src/pocketmine/updater/AutoUpdater.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/updater/AutoUpdater.php b/src/pocketmine/updater/AutoUpdater.php index 4e6ad925af..15ad63ae57 100644 --- a/src/pocketmine/updater/AutoUpdater.php +++ b/src/pocketmine/updater/AutoUpdater.php @@ -46,12 +46,16 @@ class AutoUpdater{ /** @var VersionString|null */ protected $newVersion; + /** @var \Logger */ + private $logger; + /** * @param Server $server * @param string $endpoint */ public function __construct(Server $server, string $endpoint){ $this->server = $server; + $this->logger = new \PrefixedLogger($server->getLogger(), "Auto Updater"); $this->endpoint = "http://$endpoint/api/"; if($server->getProperty("auto-updater.enabled", true)){ @@ -60,7 +64,7 @@ class AutoUpdater{ } public function checkUpdateError(string $error) : void{ - $this->server->getLogger()->debug("[AutoUpdater] Async update check failed due to \"$error\""); + $this->logger->debug("Async update check failed due to \"$error\""); } /** @@ -134,14 +138,12 @@ class AutoUpdater{ } protected function printConsoleMessage(array $lines, string $logLevel = \LogLevel::INFO) : void{ - $logger = $this->server->getLogger(); - $title = $this->server->getName() . ' Auto Updater'; - $logger->log($logLevel, sprintf('----- %s -----', $title)); + $this->logger->log($logLevel, sprintf('----- %s -----', $title)); foreach($lines as $line){ - $logger->log($logLevel, $line); + $this->logger->log($logLevel, $line); } - $logger->log($logLevel, sprintf('----- %s -----', str_repeat('-', strlen($title)))); + $this->logger->log($logLevel, sprintf('----- %s -----', str_repeat('-', strlen($title)))); } /** @@ -172,7 +174,7 @@ class AutoUpdater{ $newVersion = new VersionString($this->updateInfo["base_version"], $this->updateInfo["is_dev"], $this->updateInfo["build"]); }catch(\InvalidArgumentException $e){ //Invalid version returned from API, assume there's no update - $this->server->getLogger()->debug("[AutoUpdater] Assuming no update because \"" . $e->getMessage() . "\""); + $this->logger->debug("Assuming no update because \"" . $e->getMessage() . "\""); return; } From f5b149a02275942c3100a957e48fa0d4f5c51d02 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 4 Jun 2019 13:56:52 +0100 Subject: [PATCH 0875/3224] RakLibInterface: Use the session's own logger to report handling errors --- src/pocketmine/network/mcpe/RakLibInterface.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 70b30033e7..56f942af63 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -158,8 +158,9 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $session->handleEncoded($buf); }catch(BadPacketException $e){ $errorId = bin2hex(random_bytes(6)); - $logger = $this->server->getLogger(); - $logger->error("Bad packet from $address $port (error ID $errorId): " . $e->getMessage()); + + $logger = $session->getLogger(); + $logger->error("Bad packet (error ID $errorId): " . $e->getMessage()); //intentionally doesn't use logException, we don't want spammy packet error traces to appear in release mode $logger->debug("Origin: " . Utils::cleanPath($e->getFile()) . "(" . $e->getLine() . ")"); From 0ae3c734eaa96d2f83edec44c4956c9fe314b78b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 4 Jun 2019 14:00:01 +0100 Subject: [PATCH 0876/3224] RakLibInterface: remove unused variable --- src/pocketmine/network/mcpe/RakLibInterface.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 56f942af63..b753cea37a 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -152,7 +152,6 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ //get this now for blocking in case the player was closed before the exception was raised $session = $this->sessions[$sessionId]; $address = $session->getIp(); - $port = $session->getPort(); $buf = substr($packet->buffer, 1); try{ $session->handleEncoded($buf); From 5d16a48361675cf0b40746efb92c48645b733557 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 4 Jun 2019 14:04:29 +0100 Subject: [PATCH 0877/3224] FormatConverter: Follow the standard format for log prefix --- src/pocketmine/world/format/io/FormatConverter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/world/format/io/FormatConverter.php b/src/pocketmine/world/format/io/FormatConverter.php index c86daa084d..ec3b4f8dd0 100644 --- a/src/pocketmine/world/format/io/FormatConverter.php +++ b/src/pocketmine/world/format/io/FormatConverter.php @@ -54,7 +54,7 @@ class FormatConverter{ $this->oldProvider = $oldProvider; Utils::testValidInstance($newProvider, WritableWorldProvider::class); $this->newProvider = $newProvider; - $this->logger = new \PrefixedLogger($logger, "World Converter - " . $this->oldProvider->getWorldData()->getName()); + $this->logger = new \PrefixedLogger($logger, "World Converter: " . $this->oldProvider->getWorldData()->getName()); if(!file_exists($backupPath)){ @mkdir($backupPath, 0777, true); From 3c3e5a98506878cf603409378b8446d0ef4acacb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 4 Jun 2019 14:06:45 +0100 Subject: [PATCH 0878/3224] ConsoleCommandSender: Do not hard-depend on MainLogger this dependency makes it impossible to swap out. --- src/pocketmine/command/ConsoleCommandSender.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/command/ConsoleCommandSender.php b/src/pocketmine/command/ConsoleCommandSender.php index 9f42a99f94..7834c43997 100644 --- a/src/pocketmine/command/ConsoleCommandSender.php +++ b/src/pocketmine/command/ConsoleCommandSender.php @@ -30,7 +30,6 @@ use pocketmine\permission\PermissionAttachment; use pocketmine\permission\PermissionAttachmentInfo; use pocketmine\plugin\Plugin; use pocketmine\Server; -use pocketmine\utils\MainLogger; use function explode; use function trim; use const PHP_INT_MAX; @@ -106,14 +105,15 @@ class ConsoleCommandSender implements CommandSender{ * @param TextContainer|string $message */ public function sendMessage($message) : void{ + $server = $this->getServer(); if($message instanceof TextContainer){ - $message = $this->getServer()->getLanguage()->translate($message); + $message = $server->getLanguage()->translate($message); }else{ - $message = $this->getServer()->getLanguage()->translateString($message); + $message = $server->getLanguage()->translateString($message); } foreach(explode("\n", trim($message)) as $line){ - MainLogger::getLogger()->info($line); + $server->getLogger()->info($line); } } From 89d4f596bdac8cc5792f9910e9e0bc418caaa37d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 4 Jun 2019 14:23:40 +0100 Subject: [PATCH 0879/3224] World: add and use a prefixed logger in some places --- src/pocketmine/network/mcpe/ChunkCache.php | 2 +- src/pocketmine/world/World.php | 14 +++++++++++--- src/pocketmine/world/format/Chunk.php | 6 +++--- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/network/mcpe/ChunkCache.php b/src/pocketmine/network/mcpe/ChunkCache.php index 52134e5d0c..44776857f5 100644 --- a/src/pocketmine/network/mcpe/ChunkCache.php +++ b/src/pocketmine/network/mcpe/ChunkCache.php @@ -99,7 +99,7 @@ class ChunkCache implements ChunkListener{ $this->world->getChunk($chunkX, $chunkZ), $this->caches[$chunkHash], function() use($chunkX, $chunkZ){ - $this->world->getServer()->getLogger()->error("Failed preparing chunk for " . $this->world->getDisplayName() . " chunk $chunkX $chunkZ, retrying"); + $this->world->getLogger()->error("Failed preparing chunk $chunkX $chunkZ, retrying"); $this->restartPendingRequest($chunkX, $chunkZ); } diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 44fecc67b7..f826650c1a 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -266,6 +266,9 @@ class World implements ChunkManager, Metadatable{ /** @var SkyLightUpdate|null */ private $skyLightUpdate = null; + /** @var \Logger */ + private $logger; + public static function chunkHash(int $x, int $z) : int{ return (($x & 0xFFFFFFFF) << 32) | ($z & 0xFFFFFFFF); } @@ -352,6 +355,8 @@ class World implements ChunkManager, Metadatable{ $this->provider = $provider; $this->displayName = $this->provider->getWorldData()->getName(); + $this->logger = new \PrefixedLogger($server->getLogger(), "World: $this->displayName"); + $this->worldHeight = $this->provider->getWorldHeight(); $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.level.preparing", [$this->displayName])); @@ -419,6 +424,10 @@ class World implements ChunkManager, Metadatable{ return $this->server; } + public function getLogger() : \Logger{ + return $this->logger; + } + final public function getProvider() : WritableWorldProvider{ return $this->provider; } @@ -2526,8 +2535,7 @@ class World implements ChunkManager, Metadatable{ try{ $chunk = $this->provider->loadChunk($x, $z); }catch(CorruptedChunkException | UnsupportedChunkFormatException $e){ - $logger = $this->server->getLogger(); - $logger->critical("Failed to load chunk x=$x z=$z: " . $e->getMessage()); + $this->logger->critical("Failed to load chunk x=$x z=$z: " . $e->getMessage()); } if($chunk === null and $create){ @@ -2553,7 +2561,7 @@ class World implements ChunkManager, Metadatable{ } if(!$this->isChunkInUse($x, $z)){ - $this->server->getLogger()->debug("Newly loaded chunk $x $z has no loaders registered, will be unloaded at next available opportunity"); + $this->logger->debug("Newly loaded chunk $x $z has no loaders registered, will be unloaded at next available opportunity"); $this->unloadChunkRequest($x, $z); } foreach($this->getChunkListeners($x, $z) as $listener){ diff --git a/src/pocketmine/world/format/Chunk.php b/src/pocketmine/world/format/Chunk.php index 18452a42f6..89c0c1eaf0 100644 --- a/src/pocketmine/world/format/Chunk.php +++ b/src/pocketmine/world/format/Chunk.php @@ -587,12 +587,12 @@ class Chunk{ try{ $entity = EntityFactory::createFromData($world, $nbt); if(!($entity instanceof Entity)){ - $world->getServer()->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown entity type " . $nbt->getString("id", $nbt->getString("identifier", "", true), true)); + $world->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown entity type " . $nbt->getString("id", $nbt->getString("identifier", "", true), true)); $changed = true; continue; } }catch(\Exception $t){ //TODO: this shouldn't be here - $world->getServer()->getLogger()->logException($t); + $world->getLogger()->logException($t); $changed = true; continue; } @@ -606,7 +606,7 @@ class Chunk{ if(($tile = TileFactory::createFromData($world, $nbt)) !== null){ $world->addTile($tile); }else{ - $world->getServer()->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown tile entity type " . $nbt->getString("id", "", true)); + $world->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown tile entity type " . $nbt->getString("id", "", true)); $changed = true; continue; } From 6f29fe063f15054829fda136664d1367322043b4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 4 Jun 2019 18:02:36 +0100 Subject: [PATCH 0880/3224] move PlayerListPacket sending responsibility to NetworkSession --- src/pocketmine/Player.php | 3 -- src/pocketmine/Server.php | 54 +++---------------- .../network/mcpe/NetworkSession.php | 28 ++++++++++ .../mcpe/handler/PreSpawnSessionHandler.php | 2 +- 4 files changed, 35 insertions(+), 52 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 0ab87e1502..f623927fa7 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -802,9 +802,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, */ public function setDisplayName(string $name){ $this->displayName = $name; - if($this->spawned){ - $this->server->updatePlayerListData($this->getUniqueId(), $this->getId(), $this->getDisplayName(), $this->getSkin(), $this->getXuid()); - } } /** diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index c0dead837a..26f76e0226 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -34,7 +34,6 @@ use pocketmine\command\ConsoleCommandSender; use pocketmine\command\PluginIdentifiableCommand; use pocketmine\command\SimpleCommandMap; use pocketmine\entity\EntityFactory; -use pocketmine\entity\Skin; use pocketmine\event\HandlerList; use pocketmine\event\player\PlayerDataSaveEvent; use pocketmine\event\server\CommandEvent; @@ -61,9 +60,7 @@ use pocketmine\network\mcpe\NetworkCompression; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\PacketBatch; use pocketmine\network\mcpe\protocol\ClientboundPacket; -use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\ProtocolInfo; -use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\network\mcpe\RakLibInterface; use pocketmine\network\Network; use pocketmine\network\query\QueryHandler; @@ -1813,8 +1810,9 @@ class Server{ } public function addOnlinePlayer(Player $player) : void{ - $this->updatePlayerListData($player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkin(), $player->getXuid()); - + foreach($this->playerList as $p){ + $p->getNetworkSession()->onPlayerAdded($player); + } $this->playerList[$player->getRawUniqueId()] = $player; if($this->sendUsageTicker > 0){ @@ -1825,52 +1823,12 @@ class Server{ public function removeOnlinePlayer(Player $player) : void{ if(isset($this->playerList[$player->getRawUniqueId()])){ unset($this->playerList[$player->getRawUniqueId()]); - - $this->removePlayerListData($player->getUniqueId()); + foreach($this->playerList as $p){ + $p->getNetworkSession()->onPlayerRemoved($player); + } } } - /** - * @param UUID $uuid - * @param int $entityId - * @param string $name - * @param Skin $skin - * @param string $xboxUserId - * @param Player[]|null $players - */ - public function updatePlayerListData(UUID $uuid, int $entityId, string $name, Skin $skin, string $xboxUserId = "", ?array $players = null) : void{ - $pk = new PlayerListPacket(); - $pk->type = PlayerListPacket::TYPE_ADD; - - $pk->entries[] = PlayerListEntry::createAdditionEntry($uuid, $entityId, $name, $skin, $xboxUserId); - - $this->broadcastPacket($players ?? $this->playerList, $pk); - } - - /** - * @param UUID $uuid - * @param Player[]|null $players - */ - public function removePlayerListData(UUID $uuid, ?array $players = null) : void{ - $pk = new PlayerListPacket(); - $pk->type = PlayerListPacket::TYPE_REMOVE; - $pk->entries[] = PlayerListEntry::createRemovalEntry($uuid); - $this->broadcastPacket($players ?? $this->playerList, $pk); - } - - /** - * @param Player $p - */ - public function sendFullPlayerListData(Player $p) : void{ - $pk = new PlayerListPacket(); - $pk->type = PlayerListPacket::TYPE_ADD; - foreach($this->playerList as $player){ - $pk->entries[] = PlayerListEntry::createAdditionEntry($player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkin(), $player->getXuid()); - } - - $p->sendDataPacket($pk); - } - public function sendUsage(int $type = SendUsageTask::TYPE_STATUS) : void{ if((bool) $this->getProperty("anonymous-statistics.enabled", true)){ $this->asyncPool->submitTask(new SendUsageTask($this, $type, $this->uniquePlayers)); diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 4b7ee563cf..da5440e89e 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -55,6 +55,7 @@ use pocketmine\network\mcpe\protocol\ModalFormRequestPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\NetworkChunkPublisherUpdatePacket; use pocketmine\network\mcpe\protocol\Packet; +use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\PlayStatusPacket; use pocketmine\network\mcpe\protocol\ServerboundPacket; use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket; @@ -66,6 +67,7 @@ use pocketmine\network\mcpe\protocol\types\CommandData; use pocketmine\network\mcpe\protocol\types\CommandEnum; use pocketmine\network\mcpe\protocol\types\CommandParameter; use pocketmine\network\mcpe\protocol\types\ContainerIds; +use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; use pocketmine\network\NetworkInterface; @@ -843,6 +845,32 @@ class NetworkSession{ $this->sendDataPacket($pk); } + public function syncPlayerList() : void{ + $pk = new PlayerListPacket(); + $pk->type = PlayerListPacket::TYPE_ADD; + foreach($this->server->getOnlinePlayers() as $player){ + $pk->entries[] = PlayerListEntry::createAdditionEntry($player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkin(), $player->getXuid()); + } + + $this->sendDataPacket($pk); + } + + public function onPlayerAdded(Player $p) : void{ + $pk = new PlayerListPacket(); + $pk->type = PlayerListPacket::TYPE_ADD; + $pk->entries[] = PlayerListEntry::createAdditionEntry($p->getUniqueId(), $p->getId(), $p->getName(), $p->getSkin(), $p->getXuid()); + $this->sendDataPacket($pk); + } + + public function onPlayerRemoved(Player $p) : void{ + if($p !== $this->player){ + $pk = new PlayerListPacket(); + $pk->type = PlayerListPacket::TYPE_REMOVE; + $pk->entries[] = PlayerListEntry::createRemovalEntry($p->getUniqueId()); + $this->sendDataPacket($pk); + } + } + public function tick() : bool{ if($this->handler instanceof LoginSessionHandler){ if(time() >= $this->connectTime + 10){ diff --git a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php index 3659a55b95..81a67f3df6 100644 --- a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php @@ -96,7 +96,7 @@ class PreSpawnSessionHandler extends SessionHandler{ $this->player->getInventory()->sendHeldItem($this->player); $this->session->queueCompressed($this->server->getCraftingManager()->getCraftingDataPacket()); - $this->server->sendFullPlayerListData($this->player); + $this->session->syncPlayerList(); } public function handleRequestChunkRadius(RequestChunkRadiusPacket $packet) : bool{ From 09afb8e772426ffd2e09f16673549c3ae6b98ce4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 4 Jun 2019 19:53:08 +0100 Subject: [PATCH 0881/3224] Living: don't create MobEffectPacket directly --- src/pocketmine/entity/Living.php | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 048434590b..5bf7c0ba8f 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -46,7 +46,6 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\protocol\EntityEventPacket; -use pocketmine\network\mcpe\protocol\MobEffectPacket; use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; use pocketmine\Player; @@ -356,15 +355,7 @@ abstract class Living extends Entity implements Damageable{ */ public function sendPotionEffects(Player $player) : void{ foreach($this->effects as $effect){ - $pk = new MobEffectPacket(); - $pk->entityRuntimeId = $this->id; - $pk->effectId = $effect->getId(); - $pk->amplifier = $effect->getAmplifier(); - $pk->particles = $effect->isVisible(); - $pk->duration = $effect->getDuration(); - $pk->eventId = MobEffectPacket::EVENT_ADD; - - $player->sendDataPacket($pk); + $player->getNetworkSession()->onEntityEffectAdded($this, $effect, false); } } From 287c8c2dd4c4692643c6c0b05cbc24925d39a53c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Jun 2019 15:00:08 +0100 Subject: [PATCH 0882/3224] Added static create() functions for many packets There are a few motivations here: 1) Less boilerplate code (this can be written inline) 2) It's possible to provide multiple constructors for different packet variations to reduce the chance of errors. 3) It makes things catch fire on updates in ways that static analysers can understand. --- src/pocketmine/entity/Entity.php | 26 +--- src/pocketmine/entity/Human.php | 10 +- src/pocketmine/entity/object/ItemEntity.php | 5 +- src/pocketmine/entity/projectile/Arrow.php | 5 +- .../inventory/ContainerInventory.php | 21 +-- src/pocketmine/inventory/PlayerInventory.php | 13 +- .../transaction/CraftingTransaction.php | 4 +- .../network/mcpe/ChunkRequestTask.php | 9 +- .../network/mcpe/NetworkSession.php | 143 ++++-------------- .../mcpe/handler/DeathSessionHandler.php | 4 +- .../mcpe/handler/LoginSessionHandler.php | 5 +- .../handler/ResourcePacksSessionHandler.php | 31 ++-- .../network/mcpe/protocol/AnimatePacket.php | 13 ++ .../mcpe/protocol/BlockEntityDataPacket.php | 7 + .../protocol/ChunkRadiusUpdatedPacket.php | 6 + .../mcpe/protocol/ContainerClosePacket.php | 6 + .../mcpe/protocol/ContainerOpenPacket.php | 16 ++ .../mcpe/protocol/ContainerSetDataPacket.php | 8 + .../mcpe/protocol/DisconnectPacket.php | 13 ++ .../mcpe/protocol/EntityEventPacket.php | 8 + .../network/mcpe/protocol/ExplodePacket.php | 16 ++ .../mcpe/protocol/FullChunkDataPacket.php | 8 + .../mcpe/protocol/InventoryContentPacket.php | 14 ++ .../mcpe/protocol/InventorySlotPacket.php | 8 + .../mcpe/protocol/MobArmorEquipmentPacket.php | 10 ++ .../network/mcpe/protocol/MobEffectPacket.php | 19 +++ .../mcpe/protocol/MobEquipmentPacket.php | 10 ++ .../mcpe/protocol/ModalFormRequestPacket.php | 7 + .../NetworkChunkPublisherUpdatePacket.php | 9 ++ .../mcpe/protocol/PlayStatusPacket.php | 6 + .../mcpe/protocol/PlayerListPacket.php | 16 ++ .../mcpe/protocol/RemoveEntityPacket.php | 6 + .../protocol/ResourcePackChunkDataPacket.php | 9 ++ .../protocol/ResourcePackDataInfoPacket.php | 10 ++ .../mcpe/protocol/ResourcePackStackPacket.php | 19 +++ .../mcpe/protocol/ResourcePacksInfoPacket.php | 19 +++ .../network/mcpe/protocol/RespawnPacket.php | 6 + .../ServerToClientHandshakePacket.php | 6 + .../mcpe/protocol/SetEntityDataPacket.php | 7 + .../mcpe/protocol/SetEntityMotionPacket.php | 7 + .../mcpe/protocol/SetPlayerGameTypePacket.php | 6 + .../mcpe/protocol/SetSpawnPositionPacket.php | 15 ++ .../network/mcpe/protocol/SetTimePacket.php | 6 + .../mcpe/protocol/TakeItemEntityPacket.php | 7 + .../network/mcpe/protocol/TextPacket.php | 59 ++++++++ .../network/mcpe/protocol/TransferPacket.php | 7 + .../mcpe/protocol/UpdateAttributesPacket.php | 14 ++ .../mcpe/protocol/UpdateBlockPacket.php | 8 + src/pocketmine/world/Explosion.php | 6 +- src/pocketmine/world/World.php | 20 +-- .../world/particle/FloatingTextParticle.php | 15 +- 51 files changed, 481 insertions(+), 247 deletions(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 6040a2abf5..ee58ad42e8 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -874,11 +874,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } protected function broadcastMotion() : void{ - $pk = new SetEntityMotionPacket(); - $pk->entityRuntimeId = $this->id; - $pk->motion = $this->getMotion(); - - $this->world->broadcastPacketToViewers($this, $pk); + $this->world->broadcastPacketToViewers($this, SetEntityMotionPacket::create($this->id, $this->getMotion())); } public function hasGravity() : bool{ @@ -1649,9 +1645,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $id = spl_object_id($player); if(isset($this->hasSpawned[$id])){ if($send){ - $pk = new RemoveEntityPacket(); - $pk->entityUniqueId = $this->id; - $player->sendDataPacket($pk); + $player->sendDataPacket(RemoveEntityPacket::create($this->id)); } unset($this->hasSpawned[$id]); } @@ -1778,9 +1772,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $player = [$player]; } - $pk = new SetEntityDataPacket(); - $pk->entityRuntimeId = $this->getId(); - $pk->metadata = $data ?? $this->propertyManager->getAll(); + $pk = SetEntityDataPacket::create($this->getId(), $data ?? $this->propertyManager->getAll()); foreach($player as $p){ if($p === $this){ @@ -1795,19 +1787,11 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } public function broadcastEntityEvent(int $eventId, ?int $eventData = null, ?array $players = null) : void{ - $pk = new EntityEventPacket(); - $pk->entityRuntimeId = $this->id; - $pk->event = $eventId; - $pk->data = $eventData ?? 0; - - $this->server->broadcastPacket($players ?? $this->getViewers(), $pk); + $this->server->broadcastPacket($players ?? $this->getViewers(), EntityEventPacket::create($this->id, $eventId, $eventData ?? 0)); } public function broadcastAnimation(?array $players, int $animationId) : void{ - $pk = new AnimatePacket(); - $pk->entityRuntimeId = $this->id; - $pk->action = $animationId; - $this->server->broadcastPacket($players ?? $this->getViewers(), $pk); + $this->server->broadcastPacket($players ?? $this->getViewers(), AnimatePacket::create($this->id, $animationId)); } public function __destruct(){ diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index edca17db84..03150df893 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -829,10 +829,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ protected function sendSpawnPacket(Player $player) : void{ if(!($this instanceof Player)){ /* we don't use Server->updatePlayerListData() because that uses batches, which could cause race conditions in async compression mode */ - $pk = new PlayerListPacket(); - $pk->type = PlayerListPacket::TYPE_ADD; - $pk->entries = [PlayerListEntry::createAdditionEntry($this->uuid, $this->id, $this->getName(), $this->skin)]; - $player->sendDataPacket($pk); + $player->sendDataPacket(PlayerListPacket::add([PlayerListEntry::createAdditionEntry($this->uuid, $this->id, $this->getName(), $this->skin)])); } $pk = new AddPlayerPacket(); @@ -853,10 +850,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $player->getNetworkSession()->onMobArmorChange($this); if(!($this instanceof Player)){ - $pk = new PlayerListPacket(); - $pk->type = PlayerListPacket::TYPE_REMOVE; - $pk->entries = [PlayerListEntry::createRemovalEntry($this->uuid)]; - $player->sendDataPacket($pk); + $player->sendDataPacket(PlayerListPacket::remove([PlayerListEntry::createRemovalEntry($this->uuid)])); } } diff --git a/src/pocketmine/entity/object/ItemEntity.php b/src/pocketmine/entity/object/ItemEntity.php index 0dadfdd232..d2a14732ac 100644 --- a/src/pocketmine/entity/object/ItemEntity.php +++ b/src/pocketmine/entity/object/ItemEntity.php @@ -268,10 +268,7 @@ class ItemEntity extends Entity{ $player->awardAchievement("diamond"); } - $pk = new TakeItemEntityPacket(); - $pk->eid = $player->getId(); - $pk->target = $this->getId(); - $this->server->broadcastPacket($this->getViewers(), $pk); + $this->server->broadcastPacket($this->getViewers(), TakeItemEntityPacket::create($player->getId(), $this->getId())); $playerInventory->addItem(clone $item); $this->flagForDespawn(); diff --git a/src/pocketmine/entity/projectile/Arrow.php b/src/pocketmine/entity/projectile/Arrow.php index 0dde2ed117..f3c6c6a2a7 100644 --- a/src/pocketmine/entity/projectile/Arrow.php +++ b/src/pocketmine/entity/projectile/Arrow.php @@ -194,10 +194,7 @@ class Arrow extends Projectile{ return; } - $pk = new TakeItemEntityPacket(); - $pk->eid = $player->getId(); - $pk->target = $this->getId(); - $this->server->broadcastPacket($this->getViewers(), $pk); + $this->server->broadcastPacket($this->getViewers(), TakeItemEntityPacket::create($player->getId(), $this->getId())); $playerInventory->addItem(clone $item); $this->flagForDespawn(); diff --git a/src/pocketmine/inventory/ContainerInventory.php b/src/pocketmine/inventory/ContainerInventory.php index 8a41a73a4a..bc827dd760 100644 --- a/src/pocketmine/inventory/ContainerInventory.php +++ b/src/pocketmine/inventory/ContainerInventory.php @@ -40,31 +40,20 @@ abstract class ContainerInventory extends BaseInventory{ protected function onOpen(Player $who) : void{ parent::onOpen($who); - $pk = new ContainerOpenPacket(); - $pk->windowId = $who->getWindowId($this); - $pk->type = $this->getNetworkType(); + + $windowId = $who->getWindowId($this); $holder = $this->getHolder(); - - $pk->x = $pk->y = $pk->z = 0; - $pk->entityUniqueId = -1; - if($holder instanceof Entity){ - $pk->entityUniqueId = $holder->getId(); + $who->sendDataPacket(ContainerOpenPacket::entityInv($windowId, $this->getNetworkType(), $holder->getId())); }elseif($holder instanceof Vector3){ - $pk->x = $holder->getFloorX(); - $pk->y = $holder->getFloorY(); - $pk->z = $holder->getFloorZ(); + $who->sendDataPacket(ContainerOpenPacket::blockInv($windowId, $this->getNetworkType(), $holder->getFloorX(), $holder->getFloorY(), $holder->getFloorZ())); } - $who->sendDataPacket($pk); - $this->sendContents($who); } protected function onClose(Player $who) : void{ - $pk = new ContainerClosePacket(); - $pk->windowId = $who->getWindowId($this); - $who->sendDataPacket($pk); + $who->sendDataPacket(ContainerClosePacket::create($who->getWindowId($this))); parent::onClose($who); } diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index 8d91a5c15c..4224923b7c 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -133,11 +133,7 @@ class PlayerInventory extends BaseInventory{ public function sendHeldItem($target) : void{ $item = $this->getItemInHand(); - $pk = new MobEquipmentPacket(); - $pk->entityRuntimeId = $this->getHolder()->getId(); - $pk->item = $item; - $pk->inventorySlot = $pk->hotbarSlot = $this->getHeldItemIndex(); - $pk->windowId = ContainerIds::INVENTORY; + $pk = MobEquipmentPacket::create($this->getHolder()->getId(), $item, $this->getHeldItemIndex(), ContainerIds::INVENTORY); if(!is_array($target)){ $target->sendDataPacket($pk); @@ -166,16 +162,15 @@ class PlayerInventory extends BaseInventory{ if(!($holder instanceof Player)){ throw new \LogicException("Cannot send creative inventory contents to non-player inventory holder"); } - $pk = new InventoryContentPacket(); - $pk->windowId = ContainerIds::CREATIVE; + $items = []; if(!$holder->isSpectator()){ //fill it for all gamemodes except spectator foreach(Item::getCreativeItems() as $i => $item){ - $pk->items[$i] = clone $item; + $items[$i] = clone $item; } } - $holder->sendDataPacket($pk); + $holder->sendDataPacket(InventoryContentPacket::create(ContainerIds::CREATIVE, $items)); } /** diff --git a/src/pocketmine/inventory/transaction/CraftingTransaction.php b/src/pocketmine/inventory/transaction/CraftingTransaction.php index e01926ad14..e208ae70d9 100644 --- a/src/pocketmine/inventory/transaction/CraftingTransaction.php +++ b/src/pocketmine/inventory/transaction/CraftingTransaction.php @@ -152,9 +152,7 @@ class CraftingTransaction extends InventoryTransaction{ * So people don't whine about messy desync issues when someone cancels CraftItemEvent, or when a crafting * transaction goes wrong. */ - $pk = new ContainerClosePacket(); - $pk->windowId = ContainerIds::NONE; - $this->source->sendDataPacket($pk); + $this->source->sendDataPacket(ContainerClosePacket::create(ContainerIds::NONE)); } public function execute() : bool{ diff --git a/src/pocketmine/network/mcpe/ChunkRequestTask.php b/src/pocketmine/network/mcpe/ChunkRequestTask.php index 635348367b..cc5ec7d7fc 100644 --- a/src/pocketmine/network/mcpe/ChunkRequestTask.php +++ b/src/pocketmine/network/mcpe/ChunkRequestTask.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; -use pocketmine\world\format\Chunk; use pocketmine\network\mcpe\protocol\FullChunkDataPacket; use pocketmine\scheduler\AsyncTask; +use pocketmine\world\format\Chunk; class ChunkRequestTask extends AsyncTask{ private const TLS_KEY_PROMISE = "promise"; @@ -52,12 +52,7 @@ class ChunkRequestTask extends AsyncTask{ } public function onRun() : void{ - $pk = new FullChunkDataPacket(); - $pk->chunkX = $this->chunkX; - $pk->chunkZ = $this->chunkZ; - $pk->data = $this->chunk; - - $this->setResult(NetworkCompression::compress(PacketBatch::fromPackets($pk)->getBuffer(), $this->compressionLevel)); + $this->setResult(NetworkCompression::compress(PacketBatch::fromPackets(FullChunkDataPacket::create($this->chunkX, $this->chunkZ, $this->chunk))->getBuffer(), $this->compressionLevel)); } public function onError() : void{ diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 064fb374c4..46dfd06f3b 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -79,6 +79,7 @@ use pocketmine\timings\Timings; use pocketmine\utils\BinaryDataException; use pocketmine\utils\Utils; use pocketmine\world\Position; +use function array_map; use function bin2hex; use function count; use function get_class; @@ -460,10 +461,7 @@ class NetworkSession{ */ public function transfer(string $ip, int $port, string $reason = "transfer") : void{ $this->tryDisconnect(function() use($ip, $port, $reason){ - $pk = new TransferPacket(); - $pk->address = $ip; - $pk->port = $port; - $this->sendDataPacket($pk, true); + $this->sendDataPacket(TransferPacket::create($ip, $port), true); $this->disconnect($reason, false); if($this->player !== null){ $this->player->disconnect($reason, null, false); @@ -492,10 +490,7 @@ class NetworkSession{ */ private function doServerDisconnect(string $reason, bool $notify = true) : void{ if($notify){ - $pk = new DisconnectPacket(); - $pk->message = $reason; - $pk->hideDisconnectionScreen = $reason === ""; - $this->sendDataPacket($pk, true); + $this->sendDataPacket($reason === "" ? DisconnectPacket::silent() : DisconnectPacket::message($reason), true); } $this->interface->close($this, $notify ? $reason : ""); @@ -544,9 +539,7 @@ class NetworkSession{ } public function enableEncryption(string $encryptionKey, string $handshakeJwt) : void{ - $pk = new ServerToClientHandshakePacket(); - $pk->jwt = $handshakeJwt; - $this->sendDataPacket($pk, true); //make sure this gets sent before encryption is enabled + $this->sendDataPacket(ServerToClientHandshakePacket::create($handshakeJwt), true); //make sure this gets sent before encryption is enabled $this->cipher = new NetworkCipher($encryptionKey); @@ -557,9 +550,7 @@ class NetworkSession{ public function onLoginSuccess() : void{ $this->loggedIn = true; - $pk = new PlayStatusPacket(); - $pk->status = PlayStatusPacket::LOGIN_SUCCESS; - $this->sendDataPacket($pk); + $this->sendDataPacket(PlayStatusPacket::create(PlayStatusPacket::LOGIN_SUCCESS)); $this->setHandler(new ResourcePacksSessionHandler($this, $this->server->getResourcePackManager())); } @@ -571,9 +562,7 @@ class NetworkSession{ } public function onTerrainReady() : void{ - $pk = new PlayStatusPacket(); - $pk->status = PlayStatusPacket::PLAYER_SPAWN; - $this->sendDataPacket($pk); + $this->sendDataPacket(PlayStatusPacket::create(PlayStatusPacket::PLAYER_SPAWN)); } public function onSpawn() : void{ @@ -604,34 +593,19 @@ class NetworkSession{ } public function syncViewAreaRadius(int $distance) : void{ - $pk = new ChunkRadiusUpdatedPacket(); - $pk->radius = $distance; - $this->sendDataPacket($pk); + $this->sendDataPacket(ChunkRadiusUpdatedPacket::create($distance)); } public function syncViewAreaCenterPoint(Vector3 $newPos, int $viewDistance) : void{ - $pk = new NetworkChunkPublisherUpdatePacket(); - $pk->x = $newPos->getFloorX(); - $pk->y = $newPos->getFloorY(); - $pk->z = $newPos->getFloorZ(); - $pk->radius = $viewDistance * 16; //blocks, not chunks >.> - $this->sendDataPacket($pk); + $this->sendDataPacket(NetworkChunkPublisherUpdatePacket::create($newPos->getFloorX(), $newPos->getFloorY(), $newPos->getFloorZ(), $viewDistance * 16)); //blocks, not chunks >.> } public function syncPlayerSpawnPoint(Position $newSpawn) : void{ - $pk = new SetSpawnPositionPacket(); - $pk->x = $newSpawn->getFloorX(); - $pk->y = $newSpawn->getFloorY(); - $pk->z = $newSpawn->getFloorZ(); - $pk->spawnType = SetSpawnPositionPacket::TYPE_PLAYER_SPAWN; - $pk->spawnForced = false; - $this->sendDataPacket($pk); + $this->sendDataPacket(SetSpawnPositionPacket::playerSpawn($newSpawn->getFloorX(), $newSpawn->getFloorY(), $newSpawn->getFloorZ(), false)); //TODO: spawn forced } public function syncGameMode(GameMode $mode) : void{ - $pk = new SetPlayerGameTypePacket(); - $pk->gamemode = self::getClientFriendlyGamemode($mode); - $this->sendDataPacket($pk); + $this->sendDataPacket(SetPlayerGameTypePacket::create(self::getClientFriendlyGamemode($mode))); } /** @@ -661,10 +635,7 @@ class NetworkSession{ public function syncAttributes(Living $entity, bool $sendAll = false){ $entries = $sendAll ? $entity->getAttributeMap()->getAll() : $entity->getAttributeMap()->needSend(); if(count($entries) > 0){ - $pk = new UpdateAttributesPacket(); - $pk->entityRuntimeId = $entity->getId(); - $pk->entries = $entries; - $this->sendDataPacket($pk); + $this->sendDataPacket(UpdateAttributesPacket::create($entity->getId(), $entries)); foreach($entries as $entry){ $entry->markSynchronized(); } @@ -672,24 +643,11 @@ class NetworkSession{ } public function onEntityEffectAdded(Living $entity, EffectInstance $effect, bool $replacesOldEffect) : void{ - $pk = new MobEffectPacket(); - $pk->entityRuntimeId = $entity->getId(); - $pk->eventId = $replacesOldEffect ? MobEffectPacket::EVENT_MODIFY : MobEffectPacket::EVENT_ADD; - $pk->effectId = $effect->getId(); - $pk->amplifier = $effect->getAmplifier(); - $pk->particles = $effect->isVisible(); - $pk->duration = $effect->getDuration(); - - $this->sendDataPacket($pk); + $this->sendDataPacket(MobEffectPacket::add($entity->getId(), $replacesOldEffect, $effect->getId(), $effect->getAmplifier(), $effect->isVisible(), $effect->getDuration())); } public function onEntityEffectRemoved(Living $entity, EffectInstance $effect) : void{ - $pk = new MobEffectPacket(); - $pk->entityRuntimeId = $entity->getId(); - $pk->eventId = MobEffectPacket::EVENT_REMOVE; - $pk->effectId = $effect->getId(); - - $this->sendDataPacket($pk); + $this->sendDataPacket(MobEffectPacket::remove($entity->getId(), $effect->getId())); } public function syncAvailableCommands() : void{ @@ -730,43 +688,27 @@ class NetworkSession{ } public function onRawChatMessage(string $message) : void{ - $pk = new TextPacket(); - $pk->type = TextPacket::TYPE_RAW; - $pk->message = $message; - $this->sendDataPacket($pk); + $this->sendDataPacket(TextPacket::raw($message)); } public function onTranslatedChatMessage(string $key, array $parameters) : void{ - $pk = new TextPacket(); - $pk->type = TextPacket::TYPE_TRANSLATION; - $pk->needsTranslation = true; - $pk->message = $key; - $pk->parameters = $parameters; - $this->sendDataPacket($pk); + $this->sendDataPacket(TextPacket::translation($key, $parameters)); } public function onPopup(string $message) : void{ - $pk = new TextPacket(); - $pk->type = TextPacket::TYPE_POPUP; - $pk->message = $message; - $this->sendDataPacket($pk); + $this->sendDataPacket(TextPacket::popup($message)); } public function onTip(string $message) : void{ - $pk = new TextPacket(); - $pk->type = TextPacket::TYPE_TIP; - $pk->message = $message; - $this->sendDataPacket($pk); + $this->sendDataPacket(TextPacket::tip($message)); } public function onFormSent(int $id, Form $form) : bool{ - $pk = new ModalFormRequestPacket(); - $pk->formId = $id; - $pk->formData = json_encode($form); - if($pk->formData === false){ + $formData = json_encode($form); + if($formData === false){ throw new \InvalidArgumentException("Failed to encode form JSON: " . json_last_error_msg()); } - return $this->sendDataPacket($pk); + return $this->sendDataPacket(ModalFormRequestPacket::create($id, $formData)); } /** @@ -803,21 +745,14 @@ class NetworkSession{ public function syncInventorySlot(Inventory $inventory, int $slot) : void{ $windowId = $this->player->getWindowId($inventory); if($windowId !== ContainerIds::NONE){ - $pk = new InventorySlotPacket(); - $pk->inventorySlot = $slot; - $pk->item = $inventory->getItem($slot); - $pk->windowId = $windowId; - $this->sendDataPacket($pk); + $this->sendDataPacket(InventorySlotPacket::create($windowId, $slot, $inventory->getItem($slot))); } } public function syncInventoryContents(Inventory $inventory) : void{ $windowId = $this->player->getWindowId($inventory); if($windowId !== ContainerIds::NONE){ - $pk = new InventoryContentPacket(); - $pk->items = $inventory->getContents(true); - $pk->windowId = $windowId; - $this->sendDataPacket($pk); + $this->sendDataPacket(InventoryContentPacket::create($windowId, $inventory->getContents(true))); } } @@ -830,48 +765,28 @@ class NetworkSession{ public function syncInventoryData(Inventory $inventory, int $propertyId, int $value) : void{ $windowId = $this->player->getWindowId($inventory); if($windowId !== ContainerIds::NONE){ - $pk = new ContainerSetDataPacket(); - $pk->property = $propertyId; - $pk->value = $value; - $pk->windowId = $windowId; - $this->sendDataPacket($pk); + $this->sendDataPacket(ContainerSetDataPacket::create($windowId, $propertyId, $value)); } } public function onMobArmorChange(Living $mob) : void{ - $pk = new MobArmorEquipmentPacket(); - $pk->entityRuntimeId = $mob->getId(); $inv = $mob->getArmorInventory(); - $pk->head = $inv->getHelmet(); - $pk->chest = $inv->getChestplate(); - $pk->legs = $inv->getLeggings(); - $pk->feet = $inv->getBoots(); - $this->sendDataPacket($pk); + $this->sendDataPacket(MobArmorEquipmentPacket::create($mob->getId(), $inv->getHelmet(), $inv->getChestplate(), $inv->getLeggings(), $inv->getBoots())); } public function syncPlayerList() : void{ - $pk = new PlayerListPacket(); - $pk->type = PlayerListPacket::TYPE_ADD; - foreach($this->server->getOnlinePlayers() as $player){ - $pk->entries[] = PlayerListEntry::createAdditionEntry($player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkin(), $player->getXuid()); - } - - $this->sendDataPacket($pk); + $this->sendDataPacket(PlayerListPacket::add(array_map(function(Player $player){ + return PlayerListEntry::createAdditionEntry($player->getUniqueId(), $player->getId(), $player->getDisplayName(), $player->getSkin(), $player->getXuid()); + }, $this->server->getOnlinePlayers()))); } public function onPlayerAdded(Player $p) : void{ - $pk = new PlayerListPacket(); - $pk->type = PlayerListPacket::TYPE_ADD; - $pk->entries[] = PlayerListEntry::createAdditionEntry($p->getUniqueId(), $p->getId(), $p->getName(), $p->getSkin(), $p->getXuid()); - $this->sendDataPacket($pk); + $this->sendDataPacket(PlayerListPacket::add([PlayerListEntry::createAdditionEntry($p->getUniqueId(), $p->getId(), $p->getName(), $p->getSkin(), $p->getXuid())])); } public function onPlayerRemoved(Player $p) : void{ if($p !== $this->player){ - $pk = new PlayerListPacket(); - $pk->type = PlayerListPacket::TYPE_REMOVE; - $pk->entries[] = PlayerListEntry::createRemovalEntry($p->getUniqueId()); - $this->sendDataPacket($pk); + $this->sendDataPacket(PlayerListPacket::remove([PlayerListEntry::createRemovalEntry($p->getUniqueId())])); } } diff --git a/src/pocketmine/network/mcpe/handler/DeathSessionHandler.php b/src/pocketmine/network/mcpe/handler/DeathSessionHandler.php index 0333fb7f17..e7096d0aca 100644 --- a/src/pocketmine/network/mcpe/handler/DeathSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/DeathSessionHandler.php @@ -41,9 +41,7 @@ class DeathSessionHandler extends SessionHandler{ } public function setUp() : void{ - $pk = new RespawnPacket(); - $pk->position = $this->player->getOffsetPosition($this->player->getSpawn()); - $this->session->sendDataPacket($pk); + $this->session->sendDataPacket(RespawnPacket::create($this->player->getOffsetPosition($this->player->getSpawn()))); } public function handlePlayerAction(PlayerActionPacket $packet) : bool{ diff --git a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php index e9416f68b4..203e0f77a5 100644 --- a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php @@ -55,10 +55,7 @@ class LoginSessionHandler extends SessionHandler{ public function handleLogin(LoginPacket $packet) : bool{ if(!$this->isCompatibleProtocol($packet->protocol)){ - $pk = new PlayStatusPacket(); - $pk->status = $packet->protocol < ProtocolInfo::CURRENT_PROTOCOL ? - PlayStatusPacket::LOGIN_FAILED_CLIENT : PlayStatusPacket::LOGIN_FAILED_SERVER; - $this->session->sendDataPacket($pk, true); + $this->session->sendDataPacket(PlayStatusPacket::create($packet->protocol < ProtocolInfo::CURRENT_PROTOCOL ? PlayStatusPacket::LOGIN_FAILED_CLIENT : PlayStatusPacket::LOGIN_FAILED_SERVER), true); //This pocketmine disconnect message will only be seen by the console (PlayStatusPacket causes the messages to be shown for the client) $this->session->disconnect( diff --git a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php index be6dd90e1e..877efcfc59 100644 --- a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php @@ -59,10 +59,7 @@ class ResourcePacksSessionHandler extends SessionHandler{ } public function setUp() : void{ - $pk = new ResourcePacksInfoPacket(); - $pk->resourcePackEntries = $this->resourcePackManager->getResourceStack(); - $pk->mustAccept = $this->resourcePackManager->resourcePacksRequired(); - $this->session->sendDataPacket($pk); + $this->session->sendDataPacket(ResourcePacksInfoPacket::create($this->resourcePackManager->getResourceStack(), [], $this->resourcePackManager->resourcePacksRequired(), false)); } private function disconnectWithError(string $error) : void{ @@ -91,21 +88,18 @@ class ResourcePacksSessionHandler extends SessionHandler{ return false; } - $pk = new ResourcePackDataInfoPacket(); - $pk->packId = $pack->getPackId(); - $pk->maxChunkSize = self::PACK_CHUNK_SIZE; //1MB - $pk->chunkCount = (int) ceil($pack->getPackSize() / self::PACK_CHUNK_SIZE); - $pk->compressedPackSize = $pack->getPackSize(); - $pk->sha256 = $pack->getSha256(); - $this->session->sendDataPacket($pk); + $this->session->sendDataPacket(ResourcePackDataInfoPacket::create( + $pack->getPackId(), + self::PACK_CHUNK_SIZE, + (int) ceil($pack->getPackSize() / self::PACK_CHUNK_SIZE), + $pack->getPackSize(), + $pack->getSha256() + )); } break; case ResourcePackClientResponsePacket::STATUS_HAVE_ALL_PACKS: - $pk = new ResourcePackStackPacket(); - $pk->resourcePackStack = $this->resourcePackManager->getResourceStack(); - $pk->mustAccept = $this->resourcePackManager->resourcePacksRequired(); - $this->session->sendDataPacket($pk); + $this->session->sendDataPacket(ResourcePackStackPacket::create($this->resourcePackManager->getResourceStack(), [], $this->resourcePackManager->resourcePacksRequired(), false)); break; case ResourcePackClientResponsePacket::STATUS_COMPLETED: $this->session->onResourcePacksDone(); @@ -143,12 +137,7 @@ class ResourcePacksSessionHandler extends SessionHandler{ $this->downloadedChunks[$packId][$packet->chunkIndex] = true; } - $pk = new ResourcePackChunkDataPacket(); - $pk->packId = $packId; - $pk->chunkIndex = $packet->chunkIndex; - $pk->data = $pack->getPackChunk($offset, self::PACK_CHUNK_SIZE); - $pk->progress = $offset; - $this->session->sendDataPacket($pk); + $this->session->sendDataPacket(ResourcePackChunkDataPacket::create($packId, $packet->chunkIndex, $offset, $pack->getPackChunk($offset, self::PACK_CHUNK_SIZE))); return true; } diff --git a/src/pocketmine/network/mcpe/protocol/AnimatePacket.php b/src/pocketmine/network/mcpe/protocol/AnimatePacket.php index 49f9c59bcd..86fc701247 100644 --- a/src/pocketmine/network/mcpe/protocol/AnimatePacket.php +++ b/src/pocketmine/network/mcpe/protocol/AnimatePacket.php @@ -43,6 +43,19 @@ class AnimatePacket extends DataPacket implements ClientboundPacket, Serverbound /** @var float */ public $float = 0.0; //TODO (Boat rowing time?) + public static function create(int $entityRuntimeId, int $actionId) : self{ + $result = new self; + $result->entityRuntimeId = $entityRuntimeId; + $result->action = $actionId; + return $result; + } + + public static function boatHack(int $entityRuntimeId, int $actionId, float $data) : self{ + $result = self::create($entityRuntimeId, $actionId); + $result->float = $data; + return $result; + } + protected function decodePayload() : void{ $this->action = $this->getVarInt(); $this->entityRuntimeId = $this->getEntityRuntimeId(); diff --git a/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php b/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php index 663c242270..c60faaca54 100644 --- a/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php @@ -40,6 +40,13 @@ class BlockEntityDataPacket extends DataPacket implements ClientboundPacket, Ser /** @var string */ public $namedtag; + public static function create(int $x, int $y, int $z, string $nbt) : self{ + $result = new self; + [$result->x, $result->y, $result->z] = [$x, $y, $z]; + $result->namedtag = $nbt; + return $result; + } + protected function decodePayload() : void{ $this->getBlockPosition($this->x, $this->y, $this->z); $this->namedtag = $this->getRemaining(); diff --git a/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php b/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php index 7fe8c056b7..8dfd370807 100644 --- a/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php @@ -34,6 +34,12 @@ class ChunkRadiusUpdatedPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $radius; + public static function create(int $radius) : self{ + $result = new self; + $result->radius = $radius; + return $result; + } + protected function decodePayload() : void{ $this->radius = $this->getVarInt(); } diff --git a/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php b/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php index 55132bf99a..5cc9351680 100644 --- a/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php @@ -34,6 +34,12 @@ class ContainerClosePacket extends DataPacket implements ClientboundPacket, Serv /** @var int */ public $windowId; + public static function create(int $windowId) : self{ + $result = new self; + $result->windowId = $windowId; + return $result; + } + protected function decodePayload() : void{ $this->windowId = $this->getByte(); } diff --git a/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php b/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php index eb7b893a49..de24c60556 100644 --- a/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php @@ -44,6 +44,22 @@ class ContainerOpenPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $entityUniqueId = -1; + public static function blockInv(int $windowId, int $windowType, int $x, int $y, int $z) : self{ + $result = new self; + $result->windowId = $windowId; + $result->type = $windowType; + [$result->x, $result->y, $result->z] = [$x, $y, $z]; + return $result; + } + + public static function entityInv(int $windowId, int $windowType, int $entityUniqueId) : self{ + $result = new self; + $result->windowId = $windowId; + $result->type = $windowType; + $result->entityUniqueId = $entityUniqueId; + return $result; + } + protected function decodePayload() : void{ $this->windowId = $this->getByte(); $this->type = $this->getByte(); diff --git a/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php b/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php index 54f9fcb348..93c5473e26 100644 --- a/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php @@ -48,6 +48,14 @@ class ContainerSetDataPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $value; + public static function create(int $windowId, int $propertyId, int $value) : self{ + $result = new self; + $result->property = $propertyId; + $result->value = $value; + $result->windowId = $windowId; + return $result; + } + protected function decodePayload() : void{ $this->windowId = $this->getByte(); $this->property = $this->getVarInt(); diff --git a/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php b/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php index 437ec6b907..513f8f8ec1 100644 --- a/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php +++ b/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php @@ -36,6 +36,19 @@ class DisconnectPacket extends DataPacket implements ClientboundPacket, Serverbo /** @var string */ public $message = ""; + public static function silent() : self{ + $result = new self; + $result->hideDisconnectionScreen = true; + return $result; + } + + public static function message(string $message) : self{ + $result = new self; + $result->hideDisconnectionScreen = false; + $result->message = $message; + return $result; + } + public function canBeSentBeforeLogin() : bool{ return true; } diff --git a/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php b/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php index 8a87b490af..86e33d3bec 100644 --- a/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php @@ -90,6 +90,14 @@ class EntityEventPacket extends DataPacket implements ClientboundPacket, Serverb /** @var int */ public $data = 0; + public static function create(int $entityRuntimeId, int $eventId, int $eventData) : self{ + $result = new self; + $result->entityRuntimeId = $entityRuntimeId; + $result->event = $eventId; + $result->data = $eventData; + return $result; + } + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->event = $this->getByte(); diff --git a/src/pocketmine/network/mcpe/protocol/ExplodePacket.php b/src/pocketmine/network/mcpe/protocol/ExplodePacket.php index 17a2141bec..fada687833 100644 --- a/src/pocketmine/network/mcpe/protocol/ExplodePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ExplodePacket.php @@ -40,6 +40,22 @@ class ExplodePacket extends DataPacket implements ClientboundPacket{ /** @var Vector3[] */ public $records = []; + /** + * @param Vector3 $center + * @param float $radius + * @param Vector3[] $records + * + * @return ExplodePacket + */ + public static function create(Vector3 $center, float $radius, array $records) : self{ + (function(Vector3 ...$_){})($records); + $result = new self; + $result->position = $center; + $result->radius = $radius; + $result->records = $records; + return $result; + } + protected function decodePayload() : void{ $this->position = $this->getVector3(); $this->radius = (float) ($this->getVarInt() / 32); diff --git a/src/pocketmine/network/mcpe/protocol/FullChunkDataPacket.php b/src/pocketmine/network/mcpe/protocol/FullChunkDataPacket.php index 2503772c8c..abe1c936ad 100644 --- a/src/pocketmine/network/mcpe/protocol/FullChunkDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/FullChunkDataPacket.php @@ -38,6 +38,14 @@ class FullChunkDataPacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $data; + public static function create(int $chunkX, int $chunkZ, string $payload) : self{ + $result = new self; + $result->chunkX = $chunkX; + $result->chunkZ = $chunkZ; + $result->data = $payload; + return $result; + } + protected function decodePayload() : void{ $this->chunkX = $this->getVarInt(); $this->chunkZ = $this->getVarInt(); diff --git a/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php b/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php index 4e82aaceac..bf5bab448d 100644 --- a/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php @@ -37,6 +37,20 @@ class InventoryContentPacket extends DataPacket implements ClientboundPacket{ /** @var Item[] */ public $items = []; + /** + * @param int $windowId + * @param Item[] $items + * + * @return InventoryContentPacket + */ + public static function create(int $windowId, array $items) : self{ + (function(Item ...$items){})(...$items); //type check + $result = new self; + $result->windowId = $windowId; + $result->items = $items; + return $result; + } + protected function decodePayload() : void{ $this->windowId = $this->getUnsignedVarInt(); $count = $this->getUnsignedVarInt(); diff --git a/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php b/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php index 4f21e75260..e34adbeba0 100644 --- a/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php @@ -38,6 +38,14 @@ class InventorySlotPacket extends DataPacket implements ClientboundPacket{ /** @var Item */ public $item; + public static function create(int $windowId, int $slot, Item $item) : self{ + $result = new self; + $result->inventorySlot = $slot; + $result->item = $item; + $result->windowId = $windowId; + return $result; + } + protected function decodePayload() : void{ $this->windowId = $this->getUnsignedVarInt(); $this->inventorySlot = $this->getUnsignedVarInt(); diff --git a/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php b/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php index 99b3923c50..0888c9f2fc 100644 --- a/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php @@ -46,6 +46,16 @@ class MobArmorEquipmentPacket extends DataPacket implements ClientboundPacket, S /** @var Item */ public $feet; + public static function create(int $entityRuntimeId, Item $head, Item $chest, Item $legs, Item $feet) : self{ + $result = new self; + $result->entityRuntimeId = $entityRuntimeId; + $result->head = $head; + $result->chest = $chest; + $result->legs = $legs; + $result->feet = $feet; + return $result; + } + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->head = $this->getSlot(); diff --git a/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php b/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php index c40509edbb..108b57ad70 100644 --- a/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php @@ -48,6 +48,25 @@ class MobEffectPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $duration = 0; + public static function add(int $entityRuntimeId, bool $replace, int $effectId, int $amplifier, bool $particles, int $duration) : self{ + $result = new self; + $result->eventId = $replace ? self::EVENT_MODIFY : self::EVENT_ADD; + $result->entityRuntimeId = $entityRuntimeId; + $result->effectId = $effectId; + $result->amplifier = $amplifier; + $result->particles = $particles; + $result->duration = $duration; + return $result; + } + + public static function remove(int $entityRuntimeId, int $effectId) : self{ + $pk = new self; + $pk->eventId = self::EVENT_REMOVE; + $pk->entityRuntimeId = $entityRuntimeId; + $pk->effectId = $effectId; + return $pk; + } + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->eventId = $this->getByte(); diff --git a/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php b/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php index 6ea86df845..9676e966f7 100644 --- a/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php @@ -43,6 +43,16 @@ class MobEquipmentPacket extends DataPacket implements ClientboundPacket, Server /** @var int */ public $windowId = 0; + public static function create(int $entityRuntimeId, Item $item, int $inventorySlot, int $windowId) : self{ + $result = new self; + $result->entityRuntimeId = $entityRuntimeId; + $result->item = $item; + $result->inventorySlot = $inventorySlot; + $result->hotbarSlot = $inventorySlot; + $result->windowId = $windowId; + return $result; + } + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->item = $this->getSlot(); diff --git a/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php b/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php index 09a65c4f1a..cd1c9d42a4 100644 --- a/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php @@ -35,6 +35,13 @@ class ModalFormRequestPacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $formData; //json + public static function create(int $formId, string $formData) : self{ + $result = new self; + $result->formId = $formId; + $result->formData = $formData; + return $result; + } + protected function decodePayload() : void{ $this->formId = $this->getUnsignedVarInt(); $this->formData = $this->getString(); diff --git a/src/pocketmine/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php b/src/pocketmine/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php index 7075d0dfad..1d39454d64 100644 --- a/src/pocketmine/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php +++ b/src/pocketmine/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php @@ -39,6 +39,15 @@ class NetworkChunkPublisherUpdatePacket extends DataPacket implements Clientboun /** @var int */ public $radius; + public static function create(int $x, int $y, int $z, int $blockRadius) : self{ + $result = new self; + $result->x = $x; + $result->y = $y; + $result->z = $z; + $result->radius = $blockRadius; + return $result; + } + protected function decodePayload() : void{ $this->getSignedBlockPosition($this->x, $this->y, $this->z); $this->radius = $this->getUnsignedVarInt(); diff --git a/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php b/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php index 83ca723c85..f2c435461a 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php @@ -43,6 +43,12 @@ class PlayStatusPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $status; + public static function create(int $status) : self{ + $result = new self; + $result->status = $status; + return $result; + } + protected function decodePayload() : void{ $this->status = $this->getInt(); } diff --git a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php index ec4f1af248..8910b73230 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php @@ -43,6 +43,22 @@ class PlayerListPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $type; + public static function add(array $entries) : self{ + (function(PlayerListEntry ...$_){})($entries); + $result = new self; + $result->type = self::TYPE_ADD; + $result->entries = $entries; + return $result; + } + + public static function remove(array $entries) : self{ + (function(PlayerListEntry ...$_){})($entries); + $result = new self; + $result->type = self::TYPE_REMOVE; + $result->entries = $entries; + return $result; + } + protected function decodePayload() : void{ $this->type = $this->getByte(); $count = $this->getUnsignedVarInt(); diff --git a/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php b/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php index 7aad4b7bc0..e9b1c32cc2 100644 --- a/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php @@ -34,6 +34,12 @@ class RemoveEntityPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $entityUniqueId; + public static function create(int $entityUniqueId) : self{ + $result = new self; + $result->entityUniqueId = $entityUniqueId; + return $result; + } + protected function decodePayload() : void{ $this->entityUniqueId = $this->getEntityUniqueId(); } diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php index 0e6c3ab01c..f51384d7f9 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php @@ -42,6 +42,15 @@ class ResourcePackChunkDataPacket extends DataPacket implements ClientboundPacke /** @var string */ public $data; + public static function create(string $packId, int $chunkIndex, int $chunkOffset, string $data) : self{ + $result = new self; + $result->packId = $packId; + $result->chunkIndex = $chunkIndex; + $result->progress = $chunkOffset; + $result->data = $data; + return $result; + } + protected function decodePayload() : void{ $this->packId = $this->getString(); $this->chunkIndex = $this->getLInt(); diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php index 26882732fd..e28abefb7e 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php @@ -43,6 +43,16 @@ class ResourcePackDataInfoPacket extends DataPacket implements ClientboundPacket /** @var string */ public $sha256; + public static function create(string $packId, int $maxChunkSize, int $chunkCount, int $compressedPackSize, string $sha256sum) : self{ + $result = new self; + $result->packId = $packId; + $result->maxChunkSize = $maxChunkSize; + $result->chunkCount = $chunkCount; + $result->compressedPackSize = $compressedPackSize; + $result->sha256 = $sha256sum; + return $result; + } + protected function decodePayload() : void{ $this->packId = $this->getString(); $this->maxChunkSize = $this->getLInt(); diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php index 95fe5078e2..eed28a9450 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php @@ -45,6 +45,25 @@ class ResourcePackStackPacket extends DataPacket implements ClientboundPacket{ /** @var bool */ public $isExperimental = false; + /** + * @param ResourcePack[] $resourcePacks + * @param ResourcePack[] $behaviorPacks + * @param bool $mustAccept + * @param bool $isExperimental + * + * @return ResourcePackStackPacket + */ + public static function create(array $resourcePacks, array $behaviorPacks, bool $mustAccept, bool $isExperimental = false) : self{ + (function(ResourcePack ...$_){})($resourcePacks); + (function(ResourcePack ...$_){})($behaviorPacks); + $result = new self; + $result->mustAccept = $mustAccept; + $result->resourcePackStack = $resourcePacks; + $result->behaviorPackStack = $behaviorPacks; + $result->isExperimental = $isExperimental; + return $result; + } + protected function decodePayload() : void{ $this->mustAccept = $this->getBool(); $behaviorPackCount = $this->getUnsignedVarInt(); diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php index ebd00b40bf..bf55daf458 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php @@ -42,6 +42,25 @@ class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ /** @var ResourcePack[] */ public $resourcePackEntries = []; + /** + * @param ResourcePack[] $resourcePacks + * @param ResourcePack[] $behaviorPacks + * @param bool $mustAccept + * @param bool $hasScripts + * + * @return ResourcePacksInfoPacket + */ + public static function create(array $resourcePacks, array $behaviorPacks, bool $mustAccept, bool $hasScripts = false) : self{ + (function(ResourcePack ...$_){})($resourcePacks); + (function(ResourcePack ...$_){})($behaviorPacks); + $result = new self; + $result->mustAccept = $mustAccept; + $result->hasScripts = $hasScripts; + $result->resourcePackEntries = $resourcePacks; + $result->behaviorPackEntries = $behaviorPacks; + return $result; + } + protected function decodePayload() : void{ $this->mustAccept = $this->getBool(); $this->hasScripts = $this->getBool(); diff --git a/src/pocketmine/network/mcpe/protocol/RespawnPacket.php b/src/pocketmine/network/mcpe/protocol/RespawnPacket.php index ad7b29540d..b4f79446ad 100644 --- a/src/pocketmine/network/mcpe/protocol/RespawnPacket.php +++ b/src/pocketmine/network/mcpe/protocol/RespawnPacket.php @@ -35,6 +35,12 @@ class RespawnPacket extends DataPacket implements ClientboundPacket{ /** @var Vector3 */ public $position; + public static function create(Vector3 $position) : self{ + $result = new self; + $result->position = $position->asVector3(); + return $result; + } + protected function decodePayload() : void{ $this->position = $this->getVector3(); } diff --git a/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php b/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php index 9a223f18ae..1759999ead 100644 --- a/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php @@ -37,6 +37,12 @@ class ServerToClientHandshakePacket extends DataPacket implements ClientboundPac */ public $jwt; + public static function create(string $jwt) : self{ + $result = new self; + $result->jwt = $jwt; + return $result; + } + public function canBeSentBeforeLogin() : bool{ return true; } diff --git a/src/pocketmine/network/mcpe/protocol/SetEntityDataPacket.php b/src/pocketmine/network/mcpe/protocol/SetEntityDataPacket.php index 5004539554..d92cb057a4 100644 --- a/src/pocketmine/network/mcpe/protocol/SetEntityDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetEntityDataPacket.php @@ -36,6 +36,13 @@ class SetEntityDataPacket extends DataPacket implements ClientboundPacket, Serve /** @var array */ public $metadata; + public static function create(int $entityRuntimeId, array $metadata) : self{ + $result = new self; + $result->entityRuntimeId = $entityRuntimeId; + $result->metadata = $metadata; + return $result; + } + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->metadata = $this->getEntityMetadata(); diff --git a/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php b/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php index d0576a0523..7f4a863c65 100644 --- a/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php @@ -37,6 +37,13 @@ class SetEntityMotionPacket extends DataPacket implements ClientboundPacket{ /** @var Vector3 */ public $motion; + public static function create(int $entityRuntimeId, Vector3 $motion) : self{ + $result = new self; + $result->entityRuntimeId = $entityRuntimeId; + $result->motion = $motion->asVector3(); + return $result; + } + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->motion = $this->getVector3(); diff --git a/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php b/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php index 6ca0858593..6e16527736 100644 --- a/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php @@ -34,6 +34,12 @@ class SetPlayerGameTypePacket extends DataPacket implements ClientboundPacket, S /** @var int */ public $gamemode; + public static function create(int $gamemode) : self{ + $pk = new self; + $pk->gamemode = $gamemode; + return $pk; + } + protected function decodePayload() : void{ $this->gamemode = $this->getVarInt(); } diff --git a/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php b/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php index 21240dd57b..8c1231cdff 100644 --- a/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php @@ -45,6 +45,21 @@ class SetSpawnPositionPacket extends DataPacket implements ClientboundPacket{ /** @var bool */ public $spawnForced; + public static function playerSpawn(int $x, int $y, int $z, bool $forced) : self{ + $result = new self; + $result->spawnType = self::TYPE_PLAYER_SPAWN; + [$result->x, $result->y, $result->z] = [$x, $y, $z]; + $result->spawnForced = $forced; + return $result; + } + + public static function worldSpawn(int $x, int $y, int $z) : self{ + $result = new self; + $result->spawnType = self::TYPE_WORLD_SPAWN; + [$result->x, $result->y, $result->z] = [$x, $y, $z]; + return $result; + } + protected function decodePayload() : void{ $this->spawnType = $this->getVarInt(); $this->getBlockPosition($this->x, $this->y, $this->z); diff --git a/src/pocketmine/network/mcpe/protocol/SetTimePacket.php b/src/pocketmine/network/mcpe/protocol/SetTimePacket.php index b3cd6845ae..80acfeebb5 100644 --- a/src/pocketmine/network/mcpe/protocol/SetTimePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetTimePacket.php @@ -33,6 +33,12 @@ class SetTimePacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $time; + public static function create(int $time) : self{ + $result = new self; + $result->time = $time; + return $result; + } + protected function decodePayload() : void{ $this->time = $this->getVarInt(); } diff --git a/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php b/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php index 05c14f4d37..27911c09b2 100644 --- a/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php @@ -36,6 +36,13 @@ class TakeItemEntityPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $eid; + public static function create(int $takerEntityRuntimeId, int $itemEntityRuntimeId) : self{ + $result = new self; + $result->target = $takerEntityRuntimeId; + $result->eid = $itemEntityRuntimeId; + return $result; + } + protected function decodePayload() : void{ $this->target = $this->getEntityRuntimeId(); $this->eid = $this->getEntityRuntimeId(); diff --git a/src/pocketmine/network/mcpe/protocol/TextPacket.php b/src/pocketmine/network/mcpe/protocol/TextPacket.php index 2d7ff0fb7d..6d372522a2 100644 --- a/src/pocketmine/network/mcpe/protocol/TextPacket.php +++ b/src/pocketmine/network/mcpe/protocol/TextPacket.php @@ -58,6 +58,65 @@ class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPac /** @var string */ public $platformChatId = ""; + private static function messageOnly(int $type, string $message) : self{ + $result = new self; + $result->type = $type; + $result->message = $message; + return $result; + } + + private static function baseTranslation(int $type, string $key, array $parameters) : self{ + (function(string ...$_){})(...$parameters); + $result = new self; + $result->type = $type; + $result->needsTranslation = true; + $result->message = $key; + $result->parameters = $parameters; + return $result; + } + + public static function raw(string $message) : self{ + return self::messageOnly(self::TYPE_RAW, $message); + } + + /** + * @param string $key + * @param string[] $parameters + * + * @return TextPacket + */ + public static function translation(string $key, array $parameters = []) : self{ + return self::baseTranslation(self::TYPE_TRANSLATION, $key, $parameters); + } + + public static function popup(string $message) : self{ + return self::messageOnly(self::TYPE_POPUP, $message); + } + + /** + * @param string $key + * @param string[] $parameters + * + * @return TextPacket + */ + public static function translatedPopup(string $key, array $parameters = []) : self{ + return self::baseTranslation(self::TYPE_POPUP, $key, $parameters); + } + + /** + * @param string $key + * @param string[] $parameters + * + * @return TextPacket + */ + public static function jukeboxPopup(string $key, array $parameters = []) : self{ + return self::baseTranslation(self::TYPE_JUKEBOX_POPUP, $key, $parameters); + } + + public static function tip(string $message) : self{ + return self::messageOnly(self::TYPE_TIP, $message); + } + protected function decodePayload() : void{ $this->type = $this->getByte(); $this->needsTranslation = $this->getBool(); diff --git a/src/pocketmine/network/mcpe/protocol/TransferPacket.php b/src/pocketmine/network/mcpe/protocol/TransferPacket.php index c32da8c9f5..c1cadb556c 100644 --- a/src/pocketmine/network/mcpe/protocol/TransferPacket.php +++ b/src/pocketmine/network/mcpe/protocol/TransferPacket.php @@ -35,6 +35,13 @@ class TransferPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $port = 19132; + public static function create(string $address, int $port) : self{ + $result = new self; + $result->address = $address; + $result->port = $port; + return $result; + } + protected function decodePayload() : void{ $this->address = $this->getString(); $this->port = $this->getLShort(); diff --git a/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php index 92ebc6b239..c40c992956 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php @@ -38,6 +38,20 @@ class UpdateAttributesPacket extends DataPacket implements ClientboundPacket{ /** @var Attribute[] */ public $entries = []; + /** + * @param int $entityRuntimeId + * @param Attribute[] $attributes + * + * @return UpdateAttributesPacket + */ + public static function create(int $entityRuntimeId, array $attributes) : self{ + (function(Attribute ...$attributes){})(...$attributes); + $result = new self; + $result->entityRuntimeId = $entityRuntimeId; + $result->entries = $attributes; + return $result; + } + protected function decodePayload() : void{ $this->entityRuntimeId = $this->getEntityRuntimeId(); $this->entries = $this->getAttributeList(); diff --git a/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php index 62e13f711f..dbad6185f0 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php @@ -51,6 +51,14 @@ class UpdateBlockPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $dataLayerId = self::DATA_LAYER_NORMAL; + public static function create(int $x, int $y, int $z, int $blockRuntimeId, int $dataLayerId = self::DATA_LAYER_NORMAL) : self{ + $result = new self; + [$result->x, $result->y, $result->z] = [$x, $y, $z]; + $result->blockRuntimeId = $blockRuntimeId; + $result->dataLayerId = $dataLayerId; + return $result; + } + protected function decodePayload() : void{ $this->getBlockPosition($this->x, $this->y, $this->z); $this->blockRuntimeId = $this->getUnsignedVarInt(); diff --git a/src/pocketmine/world/Explosion.php b/src/pocketmine/world/Explosion.php index ee0b86c9ed..a7d19bdb16 100644 --- a/src/pocketmine/world/Explosion.php +++ b/src/pocketmine/world/Explosion.php @@ -240,11 +240,7 @@ class Explosion{ $send[] = new Vector3($block->x - $source->x, $block->y - $source->y, $block->z - $source->z); } - $pk = new ExplodePacket(); - $pk->position = $this->source->asVector3(); - $pk->radius = $this->size; - $pk->records = $send; - $this->world->broadcastPacketToViewers($source, $pk); + $this->world->broadcastPacketToViewers($source, ExplodePacket::create($this->source->asVector3(), $this->size, $send)); $this->world->addParticle($source, new HugeExplodeSeedParticle()); $this->world->addSound($source, new ExplodeSound()); diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index f826650c1a..9183e525a8 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -715,8 +715,7 @@ class World implements ChunkManager, Metadatable{ * @param Player ...$targets If empty, will send to all players in the world. */ public function sendTime(Player ...$targets){ - $pk = new SetTimePacket(); - $pk->time = $this->time & 0xffffffff; //avoid overflowing the field, since the packet uses an int32 + $pk = SetTimePacket::create($this->time & 0xffffffff); //avoid overflowing the field, since the packet uses an int32 if(empty($targets)){ $this->broadcastGlobalPacket($pk); @@ -934,28 +933,17 @@ class World implements ChunkManager, Metadatable{ if(!($b instanceof Vector3)){ throw new \TypeError("Expected Vector3 in blocks array, got " . (is_object($b) ? get_class($b) : gettype($b))); } - $pk = new UpdateBlockPacket(); - - $pk->x = $b->x; - $pk->y = $b->y; - $pk->z = $b->z; if($b instanceof Block){ - $pk->blockRuntimeId = $b->getRuntimeId(); + $packets[] = UpdateBlockPacket::create($b->x, $b->y, $b->z, $b->getRuntimeId()); }else{ $fullBlock = $this->getFullBlock($b->x, $b->y, $b->z); - $pk->blockRuntimeId = RuntimeBlockMapping::toStaticRuntimeId($fullBlock >> 4, $fullBlock & 0xf); + $packets[] = UpdateBlockPacket::create($b->x, $b->y, $b->z, RuntimeBlockMapping::toStaticRuntimeId($fullBlock >> 4, $fullBlock & 0xf)); } - $packets[] = $pk; $tile = $this->getTileAt($b->x, $b->y, $b->z); if($tile instanceof Spawnable){ - $tilepk = new BlockEntityDataPacket(); - $tilepk->x = $tile->x; - $tilepk->y = $tile->y; - $tilepk->z = $tile->z; - $tilepk->namedtag = $tile->getSerializedSpawnCompound(); - $packets[] = $tilepk; + $packets[] = BlockEntityDataPacket::create($tile->x, $tile->y, $tile->z, $tile->getSerializedSpawnCompound()); } } diff --git a/src/pocketmine/world/particle/FloatingTextParticle.php b/src/pocketmine/world/particle/FloatingTextParticle.php index d8efe445bf..02ea68a3ff 100644 --- a/src/pocketmine/world/particle/FloatingTextParticle.php +++ b/src/pocketmine/world/particle/FloatingTextParticle.php @@ -84,20 +84,14 @@ class FloatingTextParticle implements Particle{ if($this->entityId === null){ $this->entityId = EntityFactory::nextRuntimeId(); }else{ - $pk0 = new RemoveEntityPacket(); - $pk0->entityUniqueId = $this->entityId; - - $p[] = $pk0; + $p[] = RemoveEntityPacket::create($this->entityId); } if(!$this->invisible){ $uuid = UUID::fromRandom(); $name = $this->title . ($this->text !== "" ? "\n" . $this->text : ""); - $add = new PlayerListPacket(); - $add->type = PlayerListPacket::TYPE_ADD; - $add->entries = [PlayerListEntry::createAdditionEntry($uuid, $this->entityId, $name, new Skin("Standard_Custom", str_repeat("\x00", 8192)))]; - $p[] = $add; + $p[] = PlayerListPacket::add([PlayerListEntry::createAdditionEntry($uuid, $this->entityId, $name, new Skin("Standard_Custom", str_repeat("\x00", 8192)))]); $pk = new AddPlayerPacket(); $pk->uuid = $uuid; @@ -116,10 +110,7 @@ class FloatingTextParticle implements Particle{ $p[] = $pk; - $remove = new PlayerListPacket(); - $remove->type = PlayerListPacket::TYPE_REMOVE; - $remove->entries = [PlayerListEntry::createRemovalEntry($uuid)]; - $p[] = $remove; + $p[] = PlayerListPacket::remove([PlayerListEntry::createRemovalEntry($uuid)]); } return $p; From 3b5df90b0b0b03c6a9272dd86a070039ef0683b6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Jun 2019 15:14:37 +0100 Subject: [PATCH 0883/3224] BossEventPacket: add some functions to ease creation --- .../network/mcpe/protocol/BossEventPacket.php | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/pocketmine/network/mcpe/protocol/BossEventPacket.php b/src/pocketmine/network/mcpe/protocol/BossEventPacket.php index 4a3c50eab1..3b58f3387f 100644 --- a/src/pocketmine/network/mcpe/protocol/BossEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BossEventPacket.php @@ -66,6 +66,57 @@ class BossEventPacket extends DataPacket implements ClientboundPacket, Serverbou /** @var int */ public $overlay; + private static function base(int $bossEntityUniqueId, int $eventId) : self{ + $result = new self; + $result->bossEid = $bossEntityUniqueId; + $result->eventType = $eventId; + return $result; + } + + public static function show(int $bossEntityUniqueId, string $title, float $healthPercent, int $unknownShort = 0) : self{ + $result = self::base($bossEntityUniqueId, self::TYPE_SHOW); + $result->title = $title; + $result->healthPercent = $healthPercent; + $result->unknownShort = $unknownShort; + $result->color = 0; //hardcoded due to being useless + $result->overlay = 0; + return $result; + } + + public static function hide(int $bossEntityUniqueId) : self{ + return self::base($bossEntityUniqueId, self::TYPE_HIDE); + } + + public static function registerPlayer(int $bossEntityUniqueId, int $playerEntityUniqueId) : self{ + $result = self::base($bossEntityUniqueId, self::TYPE_REGISTER_PLAYER); + $result->playerEid = $playerEntityUniqueId; + return $result; + } + + public static function unregisterPlayer(int $bossEntityUniqueId, int $playerEntityUniqueId) : self{ + $result = self::base($bossEntityUniqueId, self::TYPE_UNREGISTER_PLAYER); + $result->playerEid = $playerEntityUniqueId; + return $result; + } + + public static function healthPercent(int $bossEntityUniqueId, float $healthPercent) : self{ + $result = self::base($bossEntityUniqueId, self::TYPE_HEALTH_PERCENT); + $result->healthPercent = $healthPercent; + return $result; + } + + public static function title(int $bossEntityUniqueId, string $title) : self{ + $result = self::base($bossEntityUniqueId, self::TYPE_TITLE); + $result->title = $title; + return $result; + } + + public static function unknown6(int $bossEntityUniqueId, int $unknownShort) : self{ + $result = self::base($bossEntityUniqueId, self::TYPE_UNKNOWN_6); + $result->unknownShort = $unknownShort; + return $result; + } + protected function decodePayload() : void{ $this->bossEid = $this->getEntityUniqueId(); $this->eventType = $this->getUnsignedVarInt(); From 9f0a184a5dc7319b8f0857b867a9c375e6a975b0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Jun 2019 15:37:35 +0100 Subject: [PATCH 0884/3224] Packet: Remove mayHaveUnreadBytes() this was an old hack to prevent debug spam being emitted when we halted decoding of logins over breaking protocol changes. Since then, we've gone back to trying to decode the packet regardless, so this property is useless. --- src/pocketmine/network/mcpe/NetworkSession.php | 2 +- src/pocketmine/network/mcpe/protocol/DataPacket.php | 8 -------- src/pocketmine/network/mcpe/protocol/LoginPacket.php | 4 ---- src/pocketmine/network/mcpe/protocol/Packet.php | 6 ------ 4 files changed, 1 insertion(+), 19 deletions(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 46dfd06f3b..6afd121662 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -319,7 +319,7 @@ class NetworkSession{ try{ $packet->decode(); - if(!$packet->feof() and !$packet->mayHaveUnreadBytes()){ + if(!$packet->feof()){ $remains = substr($packet->getBuffer(), $packet->getOffset()); $this->logger->debug("Still " . strlen($remains) . " bytes unread in " . $packet->getName() . ": " . bin2hex($remains)); } diff --git a/src/pocketmine/network/mcpe/protocol/DataPacket.php b/src/pocketmine/network/mcpe/protocol/DataPacket.php index e6563630f8..9633f71137 100644 --- a/src/pocketmine/network/mcpe/protocol/DataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/DataPacket.php @@ -56,14 +56,6 @@ abstract class DataPacket extends NetworkBinaryStream implements Packet{ return false; } - /** - * Returns whether the packet may legally have unread bytes left in the buffer. - * @return bool - */ - public function mayHaveUnreadBytes() : bool{ - return false; - } - /** * @throws BadPacketException */ diff --git a/src/pocketmine/network/mcpe/protocol/LoginPacket.php b/src/pocketmine/network/mcpe/protocol/LoginPacket.php index 694d8877f3..9deef9bb43 100644 --- a/src/pocketmine/network/mcpe/protocol/LoginPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LoginPacket.php @@ -82,10 +82,6 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ return true; } - public function mayHaveUnreadBytes() : bool{ - return $this->protocol !== null and $this->protocol !== ProtocolInfo::CURRENT_PROTOCOL; - } - protected function decodePayload() : void{ $this->protocol = $this->getInt(); $this->decodeConnectionRequest(); diff --git a/src/pocketmine/network/mcpe/protocol/Packet.php b/src/pocketmine/network/mcpe/protocol/Packet.php index 5ca1ba074d..71bd3a5c4f 100644 --- a/src/pocketmine/network/mcpe/protocol/Packet.php +++ b/src/pocketmine/network/mcpe/protocol/Packet.php @@ -48,12 +48,6 @@ interface Packet{ public function canBeSentBeforeLogin() : bool; - /** - * Returns whether the packet may legally have unread bytes left in the buffer. - * @return bool - */ - public function mayHaveUnreadBytes() : bool; - /** * @throws BadPacketException */ From 61afc7b62c29ba8d749729b95ddf10e09df39ae8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Jun 2019 14:16:04 +0100 Subject: [PATCH 0885/3224] NetworkSession: report the zlib error that happened --- src/pocketmine/network/mcpe/NetworkSession.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 6afd121662..8f1cc66a5e 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -278,7 +278,7 @@ class NetworkSession{ }catch(\ErrorException $e){ $this->logger->debug("Failed to decompress packet: " . bin2hex($payload)); //TODO: this isn't incompatible game version if we already established protocol version - throw new BadPacketException("Compressed packet batch decode error (incompatible game version?)", 0, $e); + throw new BadPacketException("Compressed packet batch decode error: " . $e->getMessage(), 0, $e); }finally{ Timings::$playerNetworkReceiveDecompressTimer->stopTiming(); } From 5c5fbf9b78b56ebf7f93e7bd7f4ebbfcfdeae0da Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Jun 2019 15:09:35 +0100 Subject: [PATCH 0886/3224] fixed oopses in 287c8c2dd4c4692643c6c0b05cbc24925d39a53c --- src/pocketmine/network/mcpe/protocol/ExplodePacket.php | 2 +- src/pocketmine/network/mcpe/protocol/PlayerListPacket.php | 4 ++-- .../network/mcpe/protocol/ResourcePackStackPacket.php | 4 ++-- .../network/mcpe/protocol/ResourcePacksInfoPacket.php | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/ExplodePacket.php b/src/pocketmine/network/mcpe/protocol/ExplodePacket.php index fada687833..579c89629b 100644 --- a/src/pocketmine/network/mcpe/protocol/ExplodePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ExplodePacket.php @@ -48,7 +48,7 @@ class ExplodePacket extends DataPacket implements ClientboundPacket{ * @return ExplodePacket */ public static function create(Vector3 $center, float $radius, array $records) : self{ - (function(Vector3 ...$_){})($records); + (function(Vector3 ...$_){})(...$records); $result = new self; $result->position = $center; $result->radius = $radius; diff --git a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php index 8910b73230..653548fefe 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php @@ -44,7 +44,7 @@ class PlayerListPacket extends DataPacket implements ClientboundPacket{ public $type; public static function add(array $entries) : self{ - (function(PlayerListEntry ...$_){})($entries); + (function(PlayerListEntry ...$_){})(...$entries); $result = new self; $result->type = self::TYPE_ADD; $result->entries = $entries; @@ -52,7 +52,7 @@ class PlayerListPacket extends DataPacket implements ClientboundPacket{ } public static function remove(array $entries) : self{ - (function(PlayerListEntry ...$_){})($entries); + (function(PlayerListEntry ...$_){})(...$entries); $result = new self; $result->type = self::TYPE_REMOVE; $result->entries = $entries; diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php index eed28a9450..ae5cbac5d9 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php @@ -54,8 +54,8 @@ class ResourcePackStackPacket extends DataPacket implements ClientboundPacket{ * @return ResourcePackStackPacket */ public static function create(array $resourcePacks, array $behaviorPacks, bool $mustAccept, bool $isExperimental = false) : self{ - (function(ResourcePack ...$_){})($resourcePacks); - (function(ResourcePack ...$_){})($behaviorPacks); + (function(ResourcePack ...$_){})(...$resourcePacks); + (function(ResourcePack ...$_){})(...$behaviorPacks); $result = new self; $result->mustAccept = $mustAccept; $result->resourcePackStack = $resourcePacks; diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php index bf55daf458..a57e877acd 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php @@ -51,8 +51,8 @@ class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ * @return ResourcePacksInfoPacket */ public static function create(array $resourcePacks, array $behaviorPacks, bool $mustAccept, bool $hasScripts = false) : self{ - (function(ResourcePack ...$_){})($resourcePacks); - (function(ResourcePack ...$_){})($behaviorPacks); + (function(ResourcePack ...$_){})(...$resourcePacks); + (function(ResourcePack ...$_){})(...$behaviorPacks); $result = new self; $result->mustAccept = $mustAccept; $result->hasScripts = $hasScripts; From e07f3e8e65bddff09465b95eaa0eb14106b74620 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Jun 2019 15:12:46 +0100 Subject: [PATCH 0887/3224] fine, variadics are annoying and this is easy to break ... --- src/pocketmine/network/mcpe/protocol/ExplodePacket.php | 1 - src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php | 1 - src/pocketmine/network/mcpe/protocol/PlayerListPacket.php | 2 -- .../network/mcpe/protocol/ResourcePackStackPacket.php | 2 -- .../network/mcpe/protocol/ResourcePacksInfoPacket.php | 2 -- src/pocketmine/network/mcpe/protocol/TextPacket.php | 1 - src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php | 1 - 7 files changed, 10 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/ExplodePacket.php b/src/pocketmine/network/mcpe/protocol/ExplodePacket.php index 579c89629b..c1f4f813fd 100644 --- a/src/pocketmine/network/mcpe/protocol/ExplodePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ExplodePacket.php @@ -48,7 +48,6 @@ class ExplodePacket extends DataPacket implements ClientboundPacket{ * @return ExplodePacket */ public static function create(Vector3 $center, float $radius, array $records) : self{ - (function(Vector3 ...$_){})(...$records); $result = new self; $result->position = $center; $result->radius = $radius; diff --git a/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php b/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php index bf5bab448d..2db67c3cc8 100644 --- a/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php @@ -44,7 +44,6 @@ class InventoryContentPacket extends DataPacket implements ClientboundPacket{ * @return InventoryContentPacket */ public static function create(int $windowId, array $items) : self{ - (function(Item ...$items){})(...$items); //type check $result = new self; $result->windowId = $windowId; $result->items = $items; diff --git a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php index 653548fefe..1e8b781438 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php @@ -44,7 +44,6 @@ class PlayerListPacket extends DataPacket implements ClientboundPacket{ public $type; public static function add(array $entries) : self{ - (function(PlayerListEntry ...$_){})(...$entries); $result = new self; $result->type = self::TYPE_ADD; $result->entries = $entries; @@ -52,7 +51,6 @@ class PlayerListPacket extends DataPacket implements ClientboundPacket{ } public static function remove(array $entries) : self{ - (function(PlayerListEntry ...$_){})(...$entries); $result = new self; $result->type = self::TYPE_REMOVE; $result->entries = $entries; diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php index ae5cbac5d9..bc19caf011 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php @@ -54,8 +54,6 @@ class ResourcePackStackPacket extends DataPacket implements ClientboundPacket{ * @return ResourcePackStackPacket */ public static function create(array $resourcePacks, array $behaviorPacks, bool $mustAccept, bool $isExperimental = false) : self{ - (function(ResourcePack ...$_){})(...$resourcePacks); - (function(ResourcePack ...$_){})(...$behaviorPacks); $result = new self; $result->mustAccept = $mustAccept; $result->resourcePackStack = $resourcePacks; diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php index a57e877acd..4a305d259a 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php @@ -51,8 +51,6 @@ class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ * @return ResourcePacksInfoPacket */ public static function create(array $resourcePacks, array $behaviorPacks, bool $mustAccept, bool $hasScripts = false) : self{ - (function(ResourcePack ...$_){})(...$resourcePacks); - (function(ResourcePack ...$_){})(...$behaviorPacks); $result = new self; $result->mustAccept = $mustAccept; $result->hasScripts = $hasScripts; diff --git a/src/pocketmine/network/mcpe/protocol/TextPacket.php b/src/pocketmine/network/mcpe/protocol/TextPacket.php index 6d372522a2..b0f24fc974 100644 --- a/src/pocketmine/network/mcpe/protocol/TextPacket.php +++ b/src/pocketmine/network/mcpe/protocol/TextPacket.php @@ -66,7 +66,6 @@ class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPac } private static function baseTranslation(int $type, string $key, array $parameters) : self{ - (function(string ...$_){})(...$parameters); $result = new self; $result->type = $type; $result->needsTranslation = true; diff --git a/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php index c40c992956..0b1fffbef7 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php @@ -45,7 +45,6 @@ class UpdateAttributesPacket extends DataPacket implements ClientboundPacket{ * @return UpdateAttributesPacket */ public static function create(int $entityRuntimeId, array $attributes) : self{ - (function(Attribute ...$attributes){})(...$attributes); $result = new self; $result->entityRuntimeId = $entityRuntimeId; $result->entries = $attributes; From 44c791f03e8de0fd729c130a50ec80a1bf0779e3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Jun 2019 16:44:32 +0100 Subject: [PATCH 0888/3224] Thread/Worker run() are now final, to set up common environment things --- src/pocketmine/Thread.php | 15 +++++++++++++++ src/pocketmine/Worker.php | 13 +++++++++++++ src/pocketmine/command/CommandReader.php | 4 +--- src/pocketmine/scheduler/AsyncWorker.php | 10 +--------- src/pocketmine/utils/ServerKiller.php | 3 +-- 5 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/pocketmine/Thread.php b/src/pocketmine/Thread.php index ad20748813..350dae2b92 100644 --- a/src/pocketmine/Thread.php +++ b/src/pocketmine/Thread.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine; +use function error_reporting; + /** * This class must be extended by all custom threading classes */ @@ -73,6 +75,19 @@ abstract class Thread extends \Thread{ return parent::start($options); } + final public function run() : void{ + error_reporting(-1); + $this->registerClassLoader(); + //set this after the autoloader is registered + \ErrorUtils::setErrorExceptionHandler(); + $this->onRun(); + } + + /** + * Runs code on the thread. + */ + abstract protected function onRun() : void; + /** * Stops the thread using the best way possible. Try to stop it yourself before calling this. */ diff --git a/src/pocketmine/Worker.php b/src/pocketmine/Worker.php index e6859f41b2..0d67bd9eea 100644 --- a/src/pocketmine/Worker.php +++ b/src/pocketmine/Worker.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine; +use function error_reporting; + /** * This class must be extended by all custom threading classes */ @@ -73,6 +75,17 @@ abstract class Worker extends \Worker{ return parent::start($options); } + final public function run() : void{ + error_reporting(-1); + $this->registerClassLoader(); + $this->onRun(); + } + + /** + * Runs code on the thread. + */ + abstract protected function onRun() : void; + /** * Stops the thread using the best way possible. Try to stop it yourself before calling this. */ diff --git a/src/pocketmine/command/CommandReader.php b/src/pocketmine/command/CommandReader.php index 1f18dd0e97..bed67d6eca 100644 --- a/src/pocketmine/command/CommandReader.php +++ b/src/pocketmine/command/CommandReader.php @@ -184,9 +184,7 @@ class CommandReader extends Thread{ return null; } - public function run() : void{ - $this->registerClassLoader(); - + protected function onRun() : void{ if($this->type !== self::TYPE_READLINE){ $this->initStdin(); } diff --git a/src/pocketmine/scheduler/AsyncWorker.php b/src/pocketmine/scheduler/AsyncWorker.php index f4d98de4ee..c751a25291 100644 --- a/src/pocketmine/scheduler/AsyncWorker.php +++ b/src/pocketmine/scheduler/AsyncWorker.php @@ -25,7 +25,6 @@ namespace pocketmine\scheduler; use pocketmine\utils\MainLogger; use pocketmine\Worker; -use function error_reporting; use function gc_enable; use function ini_set; @@ -45,14 +44,7 @@ class AsyncWorker extends Worker{ $this->memoryLimit = $memoryLimit; } - public function run() : void{ - error_reporting(-1); - - $this->registerClassLoader(); - - //set this after the autoloader is registered - \ErrorUtils::setErrorExceptionHandler(); - + protected function onRun() : void{ \GlobalLogger::set($this->logger); if($this->logger instanceof MainLogger){ $this->logger->registerStatic(); diff --git a/src/pocketmine/utils/ServerKiller.php b/src/pocketmine/utils/ServerKiller.php index d8abd40d33..d49582397c 100644 --- a/src/pocketmine/utils/ServerKiller.php +++ b/src/pocketmine/utils/ServerKiller.php @@ -38,8 +38,7 @@ class ServerKiller extends Thread{ $this->time = $time; } - public function run() : void{ - $this->registerClassLoader(); + protected function onRun() : void{ $start = time(); $this->synchronized(function(){ if(!$this->stopped){ From f8a7766880967e13f20e839fdafdac8441c810a4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Jun 2019 18:22:20 +0100 Subject: [PATCH 0889/3224] PluginBase: remove useless function it's possible to check the loader instance instead of doing this, and we're gunning to get rid of the path from the plugin base. --- src/pocketmine/plugin/PluginBase.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/pocketmine/plugin/PluginBase.php b/src/pocketmine/plugin/PluginBase.php index 8c81ff6d1c..e5dd662961 100644 --- a/src/pocketmine/plugin/PluginBase.php +++ b/src/pocketmine/plugin/PluginBase.php @@ -254,13 +254,6 @@ abstract class PluginBase implements Plugin, CommandExecutor{ return false; } - /** - * @return bool - */ - protected function isPhar() : bool{ - return strpos($this->file, "phar://") === 0; - } - /** * Gets an embedded resource on the plugin file. * WARNING: You must close the resource given using fclose() From d176f6f1ca9edd162eba7884fdcee336e505f701 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Jun 2019 18:35:05 +0100 Subject: [PATCH 0890/3224] update DevTools submodule --- tests/plugins/PocketMine-DevTools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/plugins/PocketMine-DevTools b/tests/plugins/PocketMine-DevTools index 9a992364d4..00c6a455bb 160000 --- a/tests/plugins/PocketMine-DevTools +++ b/tests/plugins/PocketMine-DevTools @@ -1 +1 @@ -Subproject commit 9a992364d4458ccf09640befeb0e991b5d67ad8a +Subproject commit 00c6a455bb185bcf050726abbe250961d17607ce From 67321bb3f6724f22101aed772537cc10a4bad3ae Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Jun 2019 18:35:47 +0100 Subject: [PATCH 0891/3224] remove PluginBase->getFile() this is in preparation for opening the doors to more exotic kinds of plugin loaders, such as eval()d or web plugins. --- src/pocketmine/plugin/PluginBase.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/pocketmine/plugin/PluginBase.php b/src/pocketmine/plugin/PluginBase.php index e5dd662961..66a267abbb 100644 --- a/src/pocketmine/plugin/PluginBase.php +++ b/src/pocketmine/plugin/PluginBase.php @@ -370,13 +370,6 @@ abstract class PluginBase implements Plugin, CommandExecutor{ return $this->description->getFullName(); } - /** - * @return string - */ - protected function getFile() : string{ - return $this->file; - } - /** * @return PluginLoader */ From b5805c2d0a328d0af557318e31dd69bd5bf38230 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Jun 2019 19:32:23 +0100 Subject: [PATCH 0892/3224] Extract a ResourceLoader unit from PluginBase this will allow addressing the resource accessing crash issue for script plugins, once fully implemented. --- .../plugin/DiskResourceProvider.php | 83 +++++++++++++++++++ src/pocketmine/plugin/Plugin.php | 2 +- src/pocketmine/plugin/PluginBase.php | 31 ++----- src/pocketmine/plugin/PluginManager.php | 2 +- src/pocketmine/plugin/ResourceProvider.php | 43 ++++++++++ 5 files changed, 136 insertions(+), 25 deletions(-) create mode 100644 src/pocketmine/plugin/DiskResourceProvider.php create mode 100644 src/pocketmine/plugin/ResourceProvider.php diff --git a/src/pocketmine/plugin/DiskResourceProvider.php b/src/pocketmine/plugin/DiskResourceProvider.php new file mode 100644 index 0000000000..09a703f43f --- /dev/null +++ b/src/pocketmine/plugin/DiskResourceProvider.php @@ -0,0 +1,83 @@ +file = rtrim($path, "/\\") . "/"; + } + + /** + * Gets an embedded resource on the plugin file. + * WARNING: You must close the resource given using fclose() + * + * @param string $filename + * + * @return null|resource Resource data, or null + */ + public function getResource(string $filename){ + $filename = rtrim(str_replace("\\", "/", $filename), "/"); + if(file_exists($this->file . "/resources/" . $filename)){ + return fopen($this->file . "/resources/" . $filename, "rb"); + } + + return null; + } + + /** + * Returns all the resources packaged with the plugin in the form ["path/in/resources" => SplFileInfo] + * + * @return \SplFileInfo[] + */ + public function getResources() : array{ + $resources = []; + if(is_dir($this->file . "resources/")){ + foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->file . "resources/")) as $resource){ + if($resource->isFile()){ + $path = str_replace(DIRECTORY_SEPARATOR, "/", substr((string) $resource, strlen($this->file . "resources/"))); + $resources[$path] = $resource; + } + } + } + + return $resources; + } +} diff --git a/src/pocketmine/plugin/Plugin.php b/src/pocketmine/plugin/Plugin.php index a25a549cbb..9813061be8 100644 --- a/src/pocketmine/plugin/Plugin.php +++ b/src/pocketmine/plugin/Plugin.php @@ -34,7 +34,7 @@ use pocketmine\Server; */ interface Plugin{ - public function __construct(PluginLoader $loader, Server $server, PluginDescription $description, string $dataFolder, string $file); + public function __construct(PluginLoader $loader, Server $server, PluginDescription $description, string $dataFolder, string $file, ResourceProvider $resourceProvider); /** * @return bool diff --git a/src/pocketmine/plugin/PluginBase.php b/src/pocketmine/plugin/PluginBase.php index 66a267abbb..27819d4fc4 100644 --- a/src/pocketmine/plugin/PluginBase.php +++ b/src/pocketmine/plugin/PluginBase.php @@ -39,18 +39,13 @@ use function fopen; use function gettype; use function is_array; use function is_bool; -use function is_dir; use function is_string; use function mkdir; use function rtrim; -use function str_replace; use function stream_copy_to_stream; -use function strlen; use function strpos; use function strtolower; -use function substr; use function trim; -use const DIRECTORY_SEPARATOR; abstract class PluginBase implements Plugin, CommandExecutor{ @@ -81,15 +76,20 @@ abstract class PluginBase implements Plugin, CommandExecutor{ /** @var TaskScheduler */ private $scheduler; - public function __construct(PluginLoader $loader, Server $server, PluginDescription $description, string $dataFolder, string $file){ + /** @var ResourceProvider */ + private $resourceProvider; + + public function __construct(PluginLoader $loader, Server $server, PluginDescription $description, string $dataFolder, string $file, ResourceProvider $resourceProvider){ $this->loader = $loader; $this->server = $server; $this->description = $description; $this->dataFolder = rtrim($dataFolder, "\\/") . "/"; + //TODO: this is accessed externally via reflection, not unused $this->file = rtrim($file, "\\/") . "/"; $this->configFile = $this->dataFolder . "config.yml"; $this->logger = new PluginLogger($this); $this->scheduler = new TaskScheduler($this->getFullName()); + $this->resourceProvider = $resourceProvider; $this->onLoad(); @@ -263,12 +263,7 @@ abstract class PluginBase implements Plugin, CommandExecutor{ * @return null|resource Resource data, or null */ public function getResource(string $filename){ - $filename = rtrim(str_replace("\\", "/", $filename), "/"); - if(file_exists($this->file . "resources/" . $filename)){ - return fopen($this->file . "resources/" . $filename, "rb"); - } - - return null; + return $this->resourceProvider->getResource($filename); } /** @@ -309,17 +304,7 @@ abstract class PluginBase implements Plugin, CommandExecutor{ * @return \SplFileInfo[] */ public function getResources() : array{ - $resources = []; - if(is_dir($this->file . "resources/")){ - foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->file . "resources/")) as $resource){ - if($resource->isFile()){ - $path = str_replace(DIRECTORY_SEPARATOR, "/", substr((string) $resource, strlen($this->file . "resources/"))); - $resources[$path] = $resource; - } - } - } - - return $resources; + return $this->resourceProvider->getResources(); } /** diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index 8715df2a0c..2aeadc14b8 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -183,7 +183,7 @@ class PluginManager{ * @var Plugin $plugin * @see Plugin::__construct() */ - $plugin = new $mainClass($loader, $this->server, $description, $dataFolder, $prefixed); + $plugin = new $mainClass($loader, $this->server, $description, $dataFolder, $prefixed, new DiskResourceProvider($prefixed . "/")); $this->plugins[$plugin->getDescription()->getName()] = $plugin; return $plugin; diff --git a/src/pocketmine/plugin/ResourceProvider.php b/src/pocketmine/plugin/ResourceProvider.php new file mode 100644 index 0000000000..2e4a3e0f08 --- /dev/null +++ b/src/pocketmine/plugin/ResourceProvider.php @@ -0,0 +1,43 @@ + SplFileInfo] + * + * @return \SplFileInfo[] + */ + public function getResources() : array; +} From b0071ed7036c3764fa37f2efc954067ae0dacd25 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Jun 2019 10:44:52 +0100 Subject: [PATCH 0893/3224] Revert "remove PluginBase->getFile()" This reverts commit 67321bb3f6724f22101aed772537cc10a4bad3ae. --- src/pocketmine/plugin/PluginBase.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/pocketmine/plugin/PluginBase.php b/src/pocketmine/plugin/PluginBase.php index 27819d4fc4..4068599efc 100644 --- a/src/pocketmine/plugin/PluginBase.php +++ b/src/pocketmine/plugin/PluginBase.php @@ -355,6 +355,13 @@ abstract class PluginBase implements Plugin, CommandExecutor{ return $this->description->getFullName(); } + /** + * @return string + */ + protected function getFile() : string{ + return $this->file; + } + /** * @return PluginLoader */ From 741d2a738066d75acf7b97af3c5f557d4079b4e3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Jun 2019 10:49:58 +0100 Subject: [PATCH 0894/3224] devtools rollback --- tests/plugins/PocketMine-DevTools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/plugins/PocketMine-DevTools b/tests/plugins/PocketMine-DevTools index 00c6a455bb..a88839dc99 160000 --- a/tests/plugins/PocketMine-DevTools +++ b/tests/plugins/PocketMine-DevTools @@ -1 +1 @@ -Subproject commit 00c6a455bb185bcf050726abbe250961d17607ce +Subproject commit a88839dc99066d8812cdf5694dc8424d25006688 From 857092cf65affd25463406a5faf75398e58124bd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Jun 2019 14:05:56 +0100 Subject: [PATCH 0895/3224] Furnace: Use the correct method to sync furnace fuel max burn time to the client --- src/pocketmine/block/tile/Furnace.php | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/pocketmine/block/tile/Furnace.php b/src/pocketmine/block/tile/Furnace.php index 73a4a2a9d3..af974a4118 100644 --- a/src/pocketmine/block/tile/Furnace.php +++ b/src/pocketmine/block/tile/Furnace.php @@ -36,7 +36,6 @@ use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\ContainerSetDataPacket; use pocketmine\world\World; -use function ceil; use function max; class Furnace extends Spawnable implements Container, Nameable{ @@ -145,10 +144,6 @@ class Furnace extends Spawnable implements Container, Nameable{ } } - protected function getFuelTicksLeft() : int{ - return $this->maxTime > 0 ? (int) ceil($this->burnTime / $this->maxTime * 200) : 0; - } - public function onUpdate() : bool{ if($this->closed){ return false; @@ -157,7 +152,8 @@ class Furnace extends Spawnable implements Container, Nameable{ $this->timings->startTiming(); $prevCookTime = $this->cookTime; - $prevFuelTicksLeft = $this->getFuelTicksLeft(); + $prevBurnTime = $this->burnTime; + $prevMaxTime = $this->maxTime; $ret = false; @@ -211,11 +207,14 @@ class Furnace extends Spawnable implements Container, Nameable{ $v->getNetworkSession()->syncInventoryData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_TICK_COUNT, $this->cookTime); } } - - $fuelTicksLeft = $this->getFuelTicksLeft(); - if($prevFuelTicksLeft !== $fuelTicksLeft){ + if($prevBurnTime !== $this->burnTime){ foreach($this->inventory->getViewers() as $v){ - $v->getNetworkSession()->syncInventoryData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_LIT_TIME, $fuelTicksLeft); + $v->getNetworkSession()->syncInventoryData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_LIT_TIME, $this->burnTime); + } + } + if($prevMaxTime !== $this->maxTime){ + foreach($this->inventory->getViewers() as $v){ + $v->getNetworkSession()->syncInventoryData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_LIT_DURATION, $this->maxTime); } } From 41039cecc153dbc17cce473be32d54ad2dff73ac Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Jun 2019 14:15:47 +0100 Subject: [PATCH 0896/3224] Furnace: remove redundant network properties these properties are continuously updating when the furnace is active, but they never trigger cache destruction, which means this is sending outdated garbage over the network, which is entirely unnecessary anyway. --- src/pocketmine/block/tile/Furnace.php | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/pocketmine/block/tile/Furnace.php b/src/pocketmine/block/tile/Furnace.php index af974a4118..6548b28836 100644 --- a/src/pocketmine/block/tile/Furnace.php +++ b/src/pocketmine/block/tile/Furnace.php @@ -39,9 +39,7 @@ use pocketmine\world\World; use function max; class Furnace extends Spawnable implements Container, Nameable{ - use NameableTrait { - addAdditionalSpawnData as addNameSpawnData; - } + use NameableTrait; use ContainerTrait; public const TAG_BURN_TIME = "BurnTime"; @@ -222,11 +220,4 @@ class Furnace extends Spawnable implements Container, Nameable{ return $ret; } - - protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ - $nbt->setShort(self::TAG_BURN_TIME, $this->burnTime); - $nbt->setShort(self::TAG_COOK_TIME, $this->cookTime); - - $this->addNameSpawnData($nbt); - } } From 7eb9b33fd6f2766da41d63c440c6608718e07f09 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Jun 2019 14:24:03 +0100 Subject: [PATCH 0897/3224] Extract a CreativeInventory unit from Item this will probably undergo further changes, but I'm primarily interested in just encapsulating the existing functionality for now. --- src/pocketmine/Server.php | 4 +- .../inventory/CreativeInventory.php | 99 +++++++++++++++++++ src/pocketmine/inventory/PlayerInventory.php | 2 +- .../action/CreativeInventoryAction.php | 3 +- src/pocketmine/item/Item.php | 63 ------------ 5 files changed, 104 insertions(+), 67 deletions(-) create mode 100644 src/pocketmine/inventory/CreativeInventory.php diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 26f76e0226..1e407604cb 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -40,8 +40,8 @@ use pocketmine\event\server\CommandEvent; use pocketmine\event\server\DataPacketBroadcastEvent; use pocketmine\event\server\QueryRegenerateEvent; use pocketmine\inventory\CraftingManager; +use pocketmine\inventory\CreativeInventory; use pocketmine\item\enchantment\Enchantment; -use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\lang\Language; use pocketmine\lang\LanguageNotFoundException; @@ -1186,7 +1186,7 @@ class Server{ BlockFactory::init(); Enchantment::init(); ItemFactory::init(); - Item::initCreativeItems(); + CreativeInventory::init(); Biome::init(); $this->craftingManager = new CraftingManager(); diff --git a/src/pocketmine/inventory/CreativeInventory.php b/src/pocketmine/inventory/CreativeInventory.php new file mode 100644 index 0000000000..2c2597c11f --- /dev/null +++ b/src/pocketmine/inventory/CreativeInventory.php @@ -0,0 +1,99 @@ +getName() === "Unknown"){ + continue; + } + self::add($item); + } + } + + public static function clear(){ + self::$creative = []; + } + + /** + * @return Item[] + */ + public static function getAll() : array{ + return self::$creative; + } + + /** + * @param int $index + * + * @return Item|null + */ + public static function getItem(int $index) : ?Item{ + return self::$creative[$index] ?? null; + } + + public static function getItemIndex(Item $item) : int{ + foreach(self::$creative as $i => $d){ + if($item->equals($d, !($item instanceof Durable))){ + return $i; + } + } + + return -1; + } + + public static function add(Item $item){ + self::$creative[] = clone $item; + } + + public static function remove(Item $item){ + $index = self::getItemIndex($item); + if($index !== -1){ + unset(self::$creative[$index]); + } + } + + public static function contains(Item $item) : bool{ + return self::getItemIndex($item) !== -1; + } +} diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index 4224923b7c..5629a706e8 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -165,7 +165,7 @@ class PlayerInventory extends BaseInventory{ $items = []; if(!$holder->isSpectator()){ //fill it for all gamemodes except spectator - foreach(Item::getCreativeItems() as $i => $item){ + foreach(CreativeInventory::getAll() as $i => $item){ $items[$i] = clone $item; } } diff --git a/src/pocketmine/inventory/transaction/action/CreativeInventoryAction.php b/src/pocketmine/inventory/transaction/action/CreativeInventoryAction.php index 4b1f618031..7c399bc95a 100644 --- a/src/pocketmine/inventory/transaction/action/CreativeInventoryAction.php +++ b/src/pocketmine/inventory/transaction/action/CreativeInventoryAction.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\inventory\transaction\action; +use pocketmine\inventory\CreativeInventory; use pocketmine\item\Item; use pocketmine\Player; @@ -53,7 +54,7 @@ class CreativeInventoryAction extends InventoryAction{ */ public function isValid(Player $source) : bool{ return !$source->hasFiniteResources() and - ($this->actionType === self::TYPE_DELETE_ITEM or Item::getCreativeItemIndex($this->sourceItem) !== -1); + ($this->actionType === self::TYPE_DELETE_ITEM or CreativeInventory::getItemIndex($this->sourceItem) !== -1); } /** diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 39d03d4db9..3c551c9a27 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -48,11 +48,8 @@ use pocketmine\utils\Binary; use function array_map; use function base64_decode; use function base64_encode; -use function file_get_contents; use function get_class; use function hex2bin; -use function json_decode; -use const DIRECTORY_SEPARATOR; class Item implements ItemIds, \JsonSerializable{ public const TAG_ENCH = "ench"; @@ -92,66 +89,6 @@ class Item implements ItemIds, \JsonSerializable{ return ItemFactory::fromString($str); } - - /** @var Item[] */ - private static $creative = []; - - public static function initCreativeItems(){ - self::clearCreativeItems(); - - $creativeItems = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla" . DIRECTORY_SEPARATOR . "creativeitems.json"), true); - - foreach($creativeItems as $data){ - $item = Item::jsonDeserialize($data); - if($item->getName() === "Unknown"){ - continue; - } - self::addCreativeItem($item); - } - } - - public static function clearCreativeItems(){ - Item::$creative = []; - } - - public static function getCreativeItems() : array{ - return Item::$creative; - } - - public static function addCreativeItem(Item $item){ - Item::$creative[] = clone $item; - } - - public static function removeCreativeItem(Item $item){ - $index = self::getCreativeItemIndex($item); - if($index !== -1){ - unset(Item::$creative[$index]); - } - } - - public static function isCreativeItem(Item $item) : bool{ - return Item::getCreativeItemIndex($item) !== -1; - } - - /** - * @param int $index - * - * @return Item|null - */ - public static function getCreativeItem(int $index) : ?Item{ - return Item::$creative[$index] ?? null; - } - - public static function getCreativeItemIndex(Item $item) : int{ - foreach(Item::$creative as $i => $d){ - if($item->equals($d, !($item instanceof Durable))){ - return $i; - } - } - - return -1; - } - /** @var int */ protected $id; /** @var int */ From cc6296b0191d7457e866a513e83a4da01e328369 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Jun 2019 15:41:32 +0100 Subject: [PATCH 0898/3224] Furnace: give some properties clearer names --- src/pocketmine/block/tile/Furnace.php | 48 +++++++++---------- .../mcpe/protocol/ContainerSetDataPacket.php | 6 +-- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/pocketmine/block/tile/Furnace.php b/src/pocketmine/block/tile/Furnace.php index 6548b28836..5dd5b7feec 100644 --- a/src/pocketmine/block/tile/Furnace.php +++ b/src/pocketmine/block/tile/Furnace.php @@ -49,11 +49,11 @@ class Furnace extends Spawnable implements Container, Nameable{ /** @var FurnaceInventory */ protected $inventory; /** @var int */ - private $burnTime = 0; + private $remainingFuelTime = 0; /** @var int */ private $cookTime = 0; /** @var int */ - private $maxTime = 0; + private $maxFuelTime = 0; public function __construct(World $world, Vector3 $pos){ $this->inventory = new FurnaceInventory($this); @@ -67,16 +67,16 @@ class Furnace extends Spawnable implements Container, Nameable{ } public function readSaveData(CompoundTag $nbt) : void{ - $this->burnTime = max(0, $nbt->getShort(self::TAG_BURN_TIME, $this->burnTime, true)); + $this->remainingFuelTime = max(0, $nbt->getShort(self::TAG_BURN_TIME, $this->remainingFuelTime, true)); $this->cookTime = $nbt->getShort(self::TAG_COOK_TIME, $this->cookTime, true); - if($this->burnTime === 0){ + if($this->remainingFuelTime === 0){ $this->cookTime = 0; } - $this->maxTime = $nbt->getShort(self::TAG_MAX_TIME, $this->maxTime, true); - if($this->maxTime === 0){ - $this->maxTime = $this->burnTime; + $this->maxFuelTime = $nbt->getShort(self::TAG_MAX_TIME, $this->maxFuelTime, true); + if($this->maxFuelTime === 0){ + $this->maxFuelTime = $this->remainingFuelTime; } $this->loadName($nbt); @@ -84,9 +84,9 @@ class Furnace extends Spawnable implements Container, Nameable{ } protected function writeSaveData(CompoundTag $nbt) : void{ - $nbt->setShort(self::TAG_BURN_TIME, $this->burnTime); + $nbt->setShort(self::TAG_BURN_TIME, $this->remainingFuelTime); $nbt->setShort(self::TAG_COOK_TIME, $this->cookTime); - $nbt->setShort(self::TAG_MAX_TIME, $this->maxTime); + $nbt->setShort(self::TAG_MAX_TIME, $this->maxFuelTime); $this->saveName($nbt); $this->saveItems($nbt); } @@ -128,7 +128,7 @@ class Furnace extends Spawnable implements Container, Nameable{ return; } - $this->maxTime = $this->burnTime = $ev->getBurnTime(); + $this->maxFuelTime = $this->remainingFuelTime = $ev->getBurnTime(); $block = $this->getBlock(); if($block instanceof BlockFurnace and !$block->isLit()){ @@ -136,7 +136,7 @@ class Furnace extends Spawnable implements Container, Nameable{ $this->getWorld()->setBlock($block, $block); } - if($this->burnTime > 0 and $ev->isBurning()){ + if($this->remainingFuelTime > 0 and $ev->isBurning()){ $fuel->pop(); $this->inventory->setFuel($fuel); } @@ -150,8 +150,8 @@ class Furnace extends Spawnable implements Container, Nameable{ $this->timings->startTiming(); $prevCookTime = $this->cookTime; - $prevBurnTime = $this->burnTime; - $prevMaxTime = $this->maxTime; + $prevRemainingFuelTime = $this->remainingFuelTime; + $prevMaxFuelTime = $this->maxFuelTime; $ret = false; @@ -161,12 +161,12 @@ class Furnace extends Spawnable implements Container, Nameable{ $smelt = $this->world->getServer()->getCraftingManager()->matchFurnaceRecipe($raw); $canSmelt = ($smelt instanceof FurnaceRecipe and $raw->getCount() > 0 and (($smelt->getResult()->equals($product) and $product->getCount() < $product->getMaxStackSize()) or $product->isNull())); - if($this->burnTime <= 0 and $canSmelt and $fuel->getFuelTime() > 0 and $fuel->getCount() > 0){ + if($this->remainingFuelTime <= 0 and $canSmelt and $fuel->getFuelTime() > 0 and $fuel->getCount() > 0){ $this->checkFuel($fuel); } - if($this->burnTime > 0){ - --$this->burnTime; + if($this->remainingFuelTime > 0){ + --$this->remainingFuelTime; if($smelt instanceof FurnaceRecipe and $canSmelt){ ++$this->cookTime; @@ -185,8 +185,8 @@ class Furnace extends Spawnable implements Container, Nameable{ $this->cookTime -= 200; } - }elseif($this->burnTime <= 0){ - $this->burnTime = $this->cookTime = $this->maxTime = 0; + }elseif($this->remainingFuelTime <= 0){ + $this->remainingFuelTime = $this->cookTime = $this->maxFuelTime = 0; }else{ $this->cookTime = 0; } @@ -197,22 +197,22 @@ class Furnace extends Spawnable implements Container, Nameable{ $block->setLit(false); $this->getWorld()->setBlock($block, $block); } - $this->burnTime = $this->cookTime = $this->maxTime = 0; + $this->remainingFuelTime = $this->cookTime = $this->maxFuelTime = 0; } if($prevCookTime !== $this->cookTime){ foreach($this->inventory->getViewers() as $v){ - $v->getNetworkSession()->syncInventoryData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_TICK_COUNT, $this->cookTime); + $v->getNetworkSession()->syncInventoryData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_SMELT_PROGRESS, $this->cookTime); } } - if($prevBurnTime !== $this->burnTime){ + if($prevRemainingFuelTime !== $this->remainingFuelTime){ foreach($this->inventory->getViewers() as $v){ - $v->getNetworkSession()->syncInventoryData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_LIT_TIME, $this->burnTime); + $v->getNetworkSession()->syncInventoryData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_REMAINING_FUEL_TIME, $this->remainingFuelTime); } } - if($prevMaxTime !== $this->maxTime){ + if($prevMaxFuelTime !== $this->maxFuelTime){ foreach($this->inventory->getViewers() as $v){ - $v->getNetworkSession()->syncInventoryData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_LIT_DURATION, $this->maxTime); + $v->getNetworkSession()->syncInventoryData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_MAX_FUEL_TIME, $this->maxFuelTime); } } diff --git a/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php b/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php index 93c5473e26..46cb1b9206 100644 --- a/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php @@ -31,9 +31,9 @@ use pocketmine\network\mcpe\handler\SessionHandler; class ContainerSetDataPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CONTAINER_SET_DATA_PACKET; - public const PROPERTY_FURNACE_TICK_COUNT = 0; - public const PROPERTY_FURNACE_LIT_TIME = 1; - public const PROPERTY_FURNACE_LIT_DURATION = 2; + public const PROPERTY_FURNACE_SMELT_PROGRESS = 0; + public const PROPERTY_FURNACE_REMAINING_FUEL_TIME = 1; + public const PROPERTY_FURNACE_MAX_FUEL_TIME = 2; public const PROPERTY_FURNACE_STORED_XP = 3; public const PROPERTY_FURNACE_FUEL_AUX = 4; From a2274429abacf3fba878f04696a961f0777f6c7e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Jun 2019 17:24:59 +0100 Subject: [PATCH 0899/3224] Chest: constrain pair positions to immediately horizontally adjacent blocks under normal circumstances a chest will never pair with a chest which isn't directly next to it anyway. --- src/pocketmine/block/tile/Chest.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/block/tile/Chest.php b/src/pocketmine/block/tile/Chest.php index 2654d8189d..a8ca4dff0c 100644 --- a/src/pocketmine/block/tile/Chest.php +++ b/src/pocketmine/block/tile/Chest.php @@ -29,6 +29,7 @@ use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\world\World; +use function abs; class Chest extends Spawnable implements Container, Nameable{ use NameableTrait { @@ -59,8 +60,17 @@ class Chest extends Spawnable implements Container, Nameable{ public function readSaveData(CompoundTag $nbt) : void{ if($nbt->hasTag(self::TAG_PAIRX, IntTag::class) and $nbt->hasTag(self::TAG_PAIRZ, IntTag::class)){ - $this->pairX = $nbt->getInt(self::TAG_PAIRX); - $this->pairZ = $nbt->getInt(self::TAG_PAIRZ); + $pairX = $nbt->getInt(self::TAG_PAIRX); + $pairZ = $nbt->getInt(self::TAG_PAIRZ); + if( + ($this->x === $pairX and abs($this->z - $pairZ) === 1) or + ($this->z === $pairZ and abs($this->x - $pairX) === 1) + ){ + $this->pairX = $pairX; + $this->pairZ = $pairZ; + }else{ + $this->pairX = $this->pairZ = null; + } } $this->loadName($nbt); $this->loadItems($nbt); From f30cee15cab7337778103552eba8e091fcbc2d45 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Jun 2019 18:03:17 +0100 Subject: [PATCH 0900/3224] added Dried Kelp block --- src/pocketmine/block/BlockFactory.php | 1 + src/pocketmine/block/DriedKelp.php | 39 +++++++++++++++++++ .../block_factory_consistency_check.json | 2 +- 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/pocketmine/block/DriedKelp.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 80347af5f6..05e8086c47 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -137,6 +137,7 @@ class BlockFactory{ self::register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_TALLGRASS), "Double Tallgrass")); self::register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LARGE_FERN), "Large Fern")); self::register(new DragonEgg(new BID(Ids::DRAGON_EGG), "Dragon Egg")); + self::register(new DriedKelp(new BID(Ids::DRIED_KELP_BLOCK), "Dried Kelp Block", new BlockBreakInfo(0.5, BlockToolType::TYPE_NONE, 0, 12.5))); self::register(new Solid(new BID(Ids::EMERALD_BLOCK), "Emerald Block", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON, 30.0))); self::register(new EmeraldOre(new BID(Ids::EMERALD_ORE), "Emerald Ore")); self::register(new EnchantingTable(new BID(Ids::ENCHANTING_TABLE, 0, null, TileEnchantingTable::class), "Enchanting Table")); diff --git a/src/pocketmine/block/DriedKelp.php b/src/pocketmine/block/DriedKelp.php new file mode 100644 index 0000000000..fbc0411d73 --- /dev/null +++ b/src/pocketmine/block/DriedKelp.php @@ -0,0 +1,39 @@ + Date: Fri, 7 Jun 2019 18:31:37 +0100 Subject: [PATCH 0901/3224] BlockFactory: added a hacky method to allow block state remapping we need this for fixing old data in some cases --- src/pocketmine/block/BlockFactory.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 05e8086c47..85e7f3c71c 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -803,6 +803,13 @@ class BlockFactory{ } } + public static function remap(int $id, int $meta, Block $block) : void{ + if(self::isRegistered($id, $meta)){ + throw new \InvalidArgumentException("$id:$meta is already mapped"); + } + self::fillStaticArrays(($id << 4) | $meta, $block); + } + private static function fillStaticArrays(int $index, Block $block) : void{ self::$fullList[$index] = $block; self::$lightFilter[$index] = min(15, $block->getLightFilter() + 1); //opacity plus 1 standard light filter From 3bc824467309adb180f890d41d23135f27be86f6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Jun 2019 19:25:44 +0100 Subject: [PATCH 0902/3224] proper remapping for the old all-sided-log bug block --- src/pocketmine/block/BlockFactory.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 85e7f3c71c..f51383fce4 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -469,9 +469,9 @@ class BlockFactory{ self::register(new Leaves(new BID($magicNumber >= 4 ? Ids::LEAVES2 : Ids::LEAVES, $magicNumber & 0x03), $name . " Leaves", $treeType)); self::register(new Log(new BID($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, $magicNumber & 0x03), $name . " Log", $treeType)); - //TODO: the old bug-block needs to be remapped to the new dedicated block - self::register(new Wood(new BID($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, ($magicNumber & 0x03) | 0b1100), $name . " Wood", $treeType)); - self::register(new Wood(new BID(Ids::WOOD, $magicNumber), $name . " Wood", $treeType)); + $wood = new Wood(new BID(Ids::WOOD, $magicNumber), $name . " Wood", $treeType); + self::register($wood); + self::remap($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, ($magicNumber & 0x03) | 0b1100, $wood); self::register(new FenceGate(new BID($fenceGateIds[$treeType]), $treeType->getDisplayName() . " Fence Gate")); self::register(new WoodenStairs(new BID($woodenStairIds[$treeType]), $treeType->getDisplayName() . " Stairs")); From 5e88fda824cd71961ba0a4b1cf16c50228dd839d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Jun 2019 19:29:26 +0100 Subject: [PATCH 0903/3224] added BrewingStand tile (implementation incomplete) since we already have a partial implementation of brewing stand, we should also have the corresponding tile so that PM doesn't create any more busted blocks. --- src/pocketmine/block/BlockFactory.php | 3 ++- src/pocketmine/block/BrewingStand.php | 15 +++++++++++++++ src/pocketmine/block/tile/TileFactory.php | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index f51383fce4..d823f739ee 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -29,6 +29,7 @@ use pocketmine\block\BlockLegacyIds as Ids; use pocketmine\block\BlockLegacyMetadata as Meta; use pocketmine\block\tile\Banner as TileBanner; use pocketmine\block\tile\Bed as TileBed; +use pocketmine\block\tile\BrewingStand as TileBrewingStand; use pocketmine\block\tile\Chest as TileChest; use pocketmine\block\tile\Comparator as TileComparator; use pocketmine\block\tile\DaylightSensor as TileDaylightSensor; @@ -97,7 +98,7 @@ class BlockFactory{ self::register(new BlueIce(new BID(Ids::BLUE_ICE), "Blue Ice")); self::register(new BoneBlock(new BID(Ids::BONE_BLOCK), "Bone Block")); self::register(new Bookshelf(new BID(Ids::BOOKSHELF), "Bookshelf")); - self::register(new BrewingStand(new BID(Ids::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND), "Brewing Stand")); + self::register(new BrewingStand(new BID(Ids::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND, TileBrewingStand::class), "Brewing Stand")); $bricksBreakInfo = new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0); self::register(new Stair(new BID(Ids::BRICK_STAIRS), "Brick Stairs", $bricksBreakInfo)); diff --git a/src/pocketmine/block/BrewingStand.php b/src/pocketmine/block/BrewingStand.php index 984aec14c5..a4c47710a5 100644 --- a/src/pocketmine/block/BrewingStand.php +++ b/src/pocketmine/block/BrewingStand.php @@ -23,7 +23,11 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\tile\BrewingStand as TileBrewingStand; +use pocketmine\item\Item; use pocketmine\item\TieredTool; +use pocketmine\math\Vector3; +use pocketmine\Player; class BrewingStand extends Transparent{ @@ -54,5 +58,16 @@ class BrewingStand extends Transparent{ return 0b111; } + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($player instanceof Player){ + $stand = $this->getWorld()->getTile($this); + if($stand instanceof TileBrewingStand and $stand->canOpenWith($item->getCustomName())){ + $player->addWindow($stand->getInventory()); + } + } + + return true; + } + //TODO } diff --git a/src/pocketmine/block/tile/TileFactory.php b/src/pocketmine/block/tile/TileFactory.php index e804dbf0d6..c1e7d3c848 100644 --- a/src/pocketmine/block/tile/TileFactory.php +++ b/src/pocketmine/block/tile/TileFactory.php @@ -48,6 +48,7 @@ final class TileFactory{ public static function init() : void{ self::register(Banner::class, ["Banner", "minecraft:banner"]); self::register(Bed::class, ["Bed", "minecraft:bed"]); + self::register(BrewingStand::class, ["BrewingStand", "minecraft:brewing_stand"]); self::register(Chest::class, ["Chest", "minecraft:chest"]); self::register(Comparator::class, ["Comparator", "minecraft:comparator"]); self::register(DaylightSensor::class, ["DaylightDetector", "minecraft:daylight_detector"]); @@ -66,7 +67,6 @@ final class TileFactory{ //TODO: Beacon //TODO: Bell //TODO: BlastFurnace - //TODO: BrewingStand //TODO: Campfire //TODO: Cauldron //TODO: ChalkboardBlock From fefc9b5278471aca6b88743d9dfc53c09ba3a533 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Jun 2019 19:36:56 +0100 Subject: [PATCH 0904/3224] wtf PhpStorm --- src/pocketmine/block/tile/BrewingStand.php | 118 ++++++++++++++++++ .../inventory/BrewingStandInventory.php | 38 ++++++ 2 files changed, 156 insertions(+) create mode 100644 src/pocketmine/block/tile/BrewingStand.php create mode 100644 src/pocketmine/inventory/BrewingStandInventory.php diff --git a/src/pocketmine/block/tile/BrewingStand.php b/src/pocketmine/block/tile/BrewingStand.php new file mode 100644 index 0000000000..bf4de785c4 --- /dev/null +++ b/src/pocketmine/block/tile/BrewingStand.php @@ -0,0 +1,118 @@ +inventory = new BrewingStandInventory($this); + $this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange(function(Inventory $unused){ + $this->world->scheduleDelayedBlockUpdate($this->getBlock(), 0); + })); + parent::__construct($world, $pos); + } + + public function readSaveData(CompoundTag $nbt) : void{ + $this->loadName($nbt); + $this->loadItems($nbt); + + $this->brewTime = $nbt->getShort(self::TAG_BREW_TIME, $nbt->getShort(self::TAG_BREW_TIME_PE, 0)); + $this->maxFuelTime = $nbt->getShort(self::TAG_MAX_FUEL_TIME, 0); + $this->remainingFuelTime = $nbt->getShort(self::TAG_REMAINING_FUEL_TIME, $nbt->getShort(self::TAG_REMAINING_FUEL_TIME_PE, 0)); + if($this->maxFuelTime === 0){ + $this->maxFuelTime = $this->remainingFuelTime; + } + if($this->remainingFuelTime === 0){ + $this->maxFuelTime = $this->remainingFuelTime = $this->brewTime = 0; + } + } + + protected function writeSaveData(CompoundTag $nbt) : void{ + $this->saveName($nbt); + $this->saveItems($nbt); + + $nbt->setShort(self::TAG_BREW_TIME_PE, $this->brewTime); + $nbt->setShort(self::TAG_MAX_FUEL_TIME, $this->maxFuelTime); + $nbt->setShort(self::TAG_REMAINING_FUEL_TIME_PE, $this->remainingFuelTime); + } + + public function getDefaultName() : string{ + return "Brewing Stand"; + } + + public function close() : void{ + if(!$this->closed){ + $this->inventory->removeAllViewers(true); + $this->inventory = null; + + parent::close(); + } + } + + /** + * @return BrewingStandInventory + */ + public function getInventory(){ + return $this->inventory; + } + + /** + * @return BrewingStandInventory + */ + public function getRealInventory(){ + return $this->inventory; + } + + public function onUpdate() : bool{ + return false; //TODO + } + +} diff --git a/src/pocketmine/inventory/BrewingStandInventory.php b/src/pocketmine/inventory/BrewingStandInventory.php new file mode 100644 index 0000000000..a699ed184d --- /dev/null +++ b/src/pocketmine/inventory/BrewingStandInventory.php @@ -0,0 +1,38 @@ + Date: Sat, 8 Jun 2019 15:44:38 +0100 Subject: [PATCH 0905/3224] Remove update mechanism for tiles, delegate to block instead block handles triggering tile update on furnace for now. --- src/pocketmine/block/Block.php | 11 +++++--- src/pocketmine/block/BrewingStand.php | 4 ++- src/pocketmine/block/DaylightSensor.php | 4 ++- src/pocketmine/block/Furnace.php | 7 +++++ src/pocketmine/block/Hopper.php | 4 +++ src/pocketmine/block/MonsterSpawner.php | 4 +++ src/pocketmine/block/tile/Banner.php | 2 -- src/pocketmine/block/tile/Bed.php | 1 - src/pocketmine/block/tile/BrewingStand.php | 7 +---- src/pocketmine/block/tile/Chest.php | 8 +++--- src/pocketmine/block/tile/DaylightSensor.php | 4 --- src/pocketmine/block/tile/FlowerPot.php | 1 - src/pocketmine/block/tile/Furnace.php | 3 ++- src/pocketmine/block/tile/Hopper.php | 4 --- src/pocketmine/block/tile/ItemFrame.php | 3 --- src/pocketmine/block/tile/MonsterSpawner.php | 4 --- src/pocketmine/block/tile/Sign.php | 1 - src/pocketmine/block/tile/Skull.php | 2 -- src/pocketmine/block/tile/Spawnable.php | 13 +++------- src/pocketmine/block/tile/Tile.php | 14 ---------- src/pocketmine/world/World.php | 27 ++------------------ src/pocketmine/world/WorldTimings.php | 3 --- 22 files changed, 41 insertions(+), 90 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index c1b16ce089..fe8d53774d 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -26,6 +26,7 @@ declare(strict_types=1); */ namespace pocketmine\block; +use pocketmine\block\tile\Spawnable; use pocketmine\block\tile\Tile; use pocketmine\block\tile\TileFactory; use pocketmine\block\utils\InvalidBlockStateException; @@ -184,9 +185,13 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ $tileType = $this->idInfo->getTileClass(); $oldTile = $this->world->getTile($this); - if($oldTile !== null and ($tileType === null or !($oldTile instanceof $tileType))){ - $oldTile->close(); - $oldTile = null; + if($oldTile !== null){ + if($tileType === null or !($oldTile instanceof $tileType)){ + $oldTile->close(); + $oldTile = null; + }elseif($oldTile instanceof Spawnable){ + $oldTile->setDirty(); //destroy old network cache + } } if($oldTile === null and $tileType !== null){ $this->world->addTile(TileFactory::create($tileType, $this->world, $this->asVector3())); diff --git a/src/pocketmine/block/BrewingStand.php b/src/pocketmine/block/BrewingStand.php index a4c47710a5..67408f0b66 100644 --- a/src/pocketmine/block/BrewingStand.php +++ b/src/pocketmine/block/BrewingStand.php @@ -69,5 +69,7 @@ class BrewingStand extends Transparent{ return true; } - //TODO + public function onScheduledUpdate() : void{ + //TODO + } } diff --git a/src/pocketmine/block/DaylightSensor.php b/src/pocketmine/block/DaylightSensor.php index a936ec24e3..2d85e898b1 100644 --- a/src/pocketmine/block/DaylightSensor.php +++ b/src/pocketmine/block/DaylightSensor.php @@ -89,5 +89,7 @@ class DaylightSensor extends Transparent{ return true; } - //TODO + public function onScheduledUpdate() : void{ + //TODO + } } diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index fd0a4218f2..9e6e765078 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -97,4 +97,11 @@ class Furnace extends Solid{ return true; } + + public function onScheduledUpdate() : void{ + $furnace = $this->getWorld()->getTile($this); + if($furnace instanceof TileFurnace and $furnace->onUpdate()){ + $this->world->scheduleDelayedBlockUpdate($this, 1); //TODO: check this + } + } } diff --git a/src/pocketmine/block/Hopper.php b/src/pocketmine/block/Hopper.php index d626534f2f..8d5eb0bc46 100644 --- a/src/pocketmine/block/Hopper.php +++ b/src/pocketmine/block/Hopper.php @@ -84,5 +84,9 @@ class Hopper extends Transparent{ return false; } + public function onScheduledUpdate() : void{ + //TODO + } + //TODO: redstone logic, sucking logic } diff --git a/src/pocketmine/block/MonsterSpawner.php b/src/pocketmine/block/MonsterSpawner.php index e8b44b9dbb..ca38aae65d 100644 --- a/src/pocketmine/block/MonsterSpawner.php +++ b/src/pocketmine/block/MonsterSpawner.php @@ -44,4 +44,8 @@ class MonsterSpawner extends Transparent{ protected function getXpDropAmount() : int{ return mt_rand(15, 43); } + + public function onScheduledUpdate() : void{ + //TODO + } } diff --git a/src/pocketmine/block/tile/Banner.php b/src/pocketmine/block/tile/Banner.php index 58163ebba2..2c37928702 100644 --- a/src/pocketmine/block/tile/Banner.php +++ b/src/pocketmine/block/tile/Banner.php @@ -109,7 +109,6 @@ class Banner extends Spawnable{ */ public function setBaseColor(DyeColor $color) : void{ $this->baseColor = $color; - $this->onChanged(); } /** @@ -124,7 +123,6 @@ class Banner extends Spawnable{ */ public function setPatterns(Deque $patterns) : void{ $this->patterns = $patterns; - $this->onChanged(); } public function getDefaultName() : string{ diff --git a/src/pocketmine/block/tile/Bed.php b/src/pocketmine/block/tile/Bed.php index 2f8b3f2bdd..28b68ee623 100644 --- a/src/pocketmine/block/tile/Bed.php +++ b/src/pocketmine/block/tile/Bed.php @@ -45,7 +45,6 @@ class Bed extends Spawnable{ public function setColor(DyeColor $color) : void{ $this->color = $color; - $this->onChanged(); } public function readSaveData(CompoundTag $nbt) : void{ diff --git a/src/pocketmine/block/tile/BrewingStand.php b/src/pocketmine/block/tile/BrewingStand.php index bf4de785c4..2d336cad43 100644 --- a/src/pocketmine/block/tile/BrewingStand.php +++ b/src/pocketmine/block/tile/BrewingStand.php @@ -55,7 +55,7 @@ class BrewingStand extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ $this->inventory = new BrewingStandInventory($this); $this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange(function(Inventory $unused){ - $this->world->scheduleDelayedBlockUpdate($this->getBlock(), 0); + $this->world->scheduleDelayedBlockUpdate($this->getBlock(), 1); })); parent::__construct($world, $pos); } @@ -110,9 +110,4 @@ class BrewingStand extends Spawnable implements Container, Nameable{ public function getRealInventory(){ return $this->inventory; } - - public function onUpdate() : bool{ - return false; //TODO - } - } diff --git a/src/pocketmine/block/tile/Chest.php b/src/pocketmine/block/tile/Chest.php index a8ca4dff0c..98b6546140 100644 --- a/src/pocketmine/block/tile/Chest.php +++ b/src/pocketmine/block/tile/Chest.php @@ -196,8 +196,8 @@ class Chest extends Spawnable implements Container, Nameable{ $this->createPair($tile); - $this->onChanged(); - $tile->onChanged(); + $this->setDirty(); + $tile->setDirty(); $this->checkPairing(); return true; @@ -219,12 +219,12 @@ class Chest extends Spawnable implements Container, Nameable{ $tile = $this->getPair(); $this->pairX = $this->pairZ = null; - $this->onChanged(); + $this->setDirty(); if($tile instanceof Chest){ $tile->pairX = $tile->pairZ = null; $tile->checkPairing(); - $tile->onChanged(); + $tile->setDirty(); } $this->checkPairing(); diff --git a/src/pocketmine/block/tile/DaylightSensor.php b/src/pocketmine/block/tile/DaylightSensor.php index d06201654d..8776d1ca51 100644 --- a/src/pocketmine/block/tile/DaylightSensor.php +++ b/src/pocketmine/block/tile/DaylightSensor.php @@ -41,8 +41,4 @@ class DaylightSensor extends Tile{ protected function writeSaveData(CompoundTag $nbt) : void{ } - - public function onUpdate() : bool{ - return false; //TODO: we'll need this for implementing daylight sensor until https://github.com/pmmp/PocketMine-MP/issues/2099 is fixed - } } diff --git a/src/pocketmine/block/tile/FlowerPot.php b/src/pocketmine/block/tile/FlowerPot.php index 0c626bb33d..db9bb28eb2 100644 --- a/src/pocketmine/block/tile/FlowerPot.php +++ b/src/pocketmine/block/tile/FlowerPot.php @@ -69,7 +69,6 @@ class FlowerPot extends Spawnable{ }else{ $this->plant = clone $plant; } - $this->onChanged(); } protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ diff --git a/src/pocketmine/block/tile/Furnace.php b/src/pocketmine/block/tile/Furnace.php index 5dd5b7feec..7d7f402bd9 100644 --- a/src/pocketmine/block/tile/Furnace.php +++ b/src/pocketmine/block/tile/Furnace.php @@ -59,7 +59,7 @@ class Furnace extends Spawnable implements Container, Nameable{ $this->inventory = new FurnaceInventory($this); $this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange( function(Inventory $unused) : void{ - $this->scheduleUpdate(); + $this->world->scheduleDelayedBlockUpdate($this->asVector3(), 1); }) ); @@ -143,6 +143,7 @@ class Furnace extends Spawnable implements Container, Nameable{ } public function onUpdate() : bool{ + //TODO: move this to Block if($this->closed){ return false; } diff --git a/src/pocketmine/block/tile/Hopper.php b/src/pocketmine/block/tile/Hopper.php index bc8018ee46..4aa2d89e21 100644 --- a/src/pocketmine/block/tile/Hopper.php +++ b/src/pocketmine/block/tile/Hopper.php @@ -86,8 +86,4 @@ class Hopper extends Spawnable implements Container, Nameable{ public function getRealInventory(){ return $this->inventory; } - - public function onUpdate() : bool{ - return false; //TODO - } } diff --git a/src/pocketmine/block/tile/ItemFrame.php b/src/pocketmine/block/tile/ItemFrame.php index e042c049d7..a3910046f5 100644 --- a/src/pocketmine/block/tile/ItemFrame.php +++ b/src/pocketmine/block/tile/ItemFrame.php @@ -78,7 +78,6 @@ class ItemFrame extends Spawnable{ }else{ $this->item = ItemFactory::air(); } - $this->onChanged(); } public function getItemRotation() : int{ @@ -87,7 +86,6 @@ class ItemFrame extends Spawnable{ public function setItemRotation(int $rotation) : void{ $this->itemRotation = $rotation; - $this->onChanged(); } public function getItemDropChance() : float{ @@ -96,7 +94,6 @@ class ItemFrame extends Spawnable{ public function setItemDropChance(float $chance) : void{ $this->itemDropChance = $chance; - $this->onChanged(); } protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ diff --git a/src/pocketmine/block/tile/MonsterSpawner.php b/src/pocketmine/block/tile/MonsterSpawner.php index e698b2c074..dba2f29384 100644 --- a/src/pocketmine/block/tile/MonsterSpawner.php +++ b/src/pocketmine/block/tile/MonsterSpawner.php @@ -149,8 +149,4 @@ class MonsterSpawner extends Spawnable{ $nbt->setFloat(self::TAG_ENTITY_SCALE, $this->displayEntityScale); } - - public function onUpdate() : bool{ - return false; //TODO - } } diff --git a/src/pocketmine/block/tile/Sign.php b/src/pocketmine/block/tile/Sign.php index a53f5cfa6c..e625448c94 100644 --- a/src/pocketmine/block/tile/Sign.php +++ b/src/pocketmine/block/tile/Sign.php @@ -90,7 +90,6 @@ class Sign extends Spawnable{ */ public function setText(SignText $text) : void{ $this->text = $text; - $this->onChanged(); } protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ diff --git a/src/pocketmine/block/tile/Skull.php b/src/pocketmine/block/tile/Skull.php index d4ede3ba98..fe0fe062c2 100644 --- a/src/pocketmine/block/tile/Skull.php +++ b/src/pocketmine/block/tile/Skull.php @@ -71,7 +71,6 @@ class Skull extends Spawnable{ public function setSkullType(SkullType $type) : void{ $this->skullType = $type; - $this->onChanged(); } public function getSkullType() : SkullType{ @@ -84,7 +83,6 @@ class Skull extends Spawnable{ public function setRotation(int $rotation) : void{ $this->skullRotation = $rotation; - $this->onChanged(); } protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ diff --git a/src/pocketmine/block/tile/Spawnable.php b/src/pocketmine/block/tile/Spawnable.php index 6568ad6c46..226a15412f 100644 --- a/src/pocketmine/block/tile/Spawnable.php +++ b/src/pocketmine/block/tile/Spawnable.php @@ -37,16 +37,6 @@ abstract class Spawnable extends Tile{ /** @var NetworkNbtSerializer|null */ private static $nbtWriter = null; - /** - * Flags the tile as modified, so that updates will be broadcasted at the next available opportunity. - * This MUST be called any time a change is made that players must be able to see. - */ - protected function onChanged() : void{ - $this->spawnCompoundCache = null; - $this->dirty = true; - $this->scheduleUpdate(); - } - /** * Returns whether the tile needs to be respawned to viewers. * @@ -60,6 +50,9 @@ abstract class Spawnable extends Tile{ * @param bool $dirty */ public function setDirty(bool $dirty = true) : void{ + if($dirty){ + $this->spawnCompoundCache = null; + } $this->dirty = $dirty; } diff --git a/src/pocketmine/block/tile/Tile.php b/src/pocketmine/block/tile/Tile.php index fbdece662d..1ff97a6562 100644 --- a/src/pocketmine/block/tile/Tile.php +++ b/src/pocketmine/block/tile/Tile.php @@ -107,20 +107,6 @@ abstract class Tile extends Position{ return $this->world->getBlockAt($this->x, $this->y, $this->z); } - /** - * @return bool - */ - public function onUpdate() : bool{ - return false; - } - - final public function scheduleUpdate() : void{ - if($this->closed){ - throw new \InvalidStateException("Cannot schedule update on garbage tile " . get_class($this)); - } - $this->world->updateTiles[World::blockHash($this->x, $this->y, $this->z)] = $this; - } - public function isClosed() : bool{ return $this->closed; } diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 9183e525a8..58d273fb01 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -143,8 +143,6 @@ class World implements ChunkManager, Metadatable{ /** @var Entity[] */ public $updateEntities = []; - /** @var Tile[] */ - public $updateTiles = []; /** @var Block[][] */ private $blockCache = []; @@ -818,26 +816,6 @@ class World implements ChunkManager, Metadatable{ Timings::$tickEntityTimer->stopTiming(); $this->timings->entityTick->stopTiming(); - $this->timings->tileEntityTick->startTiming(); - Timings::$tickTileEntityTimer->startTiming(); - //Update tiles that need update - foreach($this->updateTiles as $blockHash => $tile){ - if(!$tile->onUpdate()){ - unset($this->updateTiles[$blockHash]); - } - if(!$tile->isClosed() and $tile instanceof Spawnable and $tile->isDirty()){ - $chunkHash = World::chunkHash($tile->getFloorX() >> 4, $tile->getFloorZ() >> 4); - if(!isset($this->changedBlocks[$chunkHash])){ - $this->changedBlocks[$chunkHash] = [$blockHash => $tile]; - }else{ - $this->changedBlocks[$chunkHash][$blockHash] = $tile; - } - $tile->setDirty(false); - } - } - Timings::$tickTileEntityTimer->stopTiming(); - $this->timings->tileEntityTick->stopTiming(); - $this->timings->doTickTiles->startTiming(); $this->tickChunks(); $this->timings->doTickTiles->stopTiming(); @@ -2460,7 +2438,8 @@ class World implements ChunkManager, Metadatable{ throw new \InvalidStateException("Attempted to create tile " . get_class($tile) . " in unloaded chunk $chunkX $chunkZ"); } - $tile->scheduleUpdate(); + //delegate tile ticking to the corresponding block + $this->scheduleDelayedBlockUpdate($tile->asVector3(), 1); } /** @@ -2473,8 +2452,6 @@ class World implements ChunkManager, Metadatable{ throw new \InvalidArgumentException("Invalid Tile world"); } - unset($this->updateTiles[World::blockHash($tile->x, $tile->y, $tile->z)]); - $chunkX = $tile->getFloorX() >> 4; $chunkZ = $tile->getFloorZ() >> 4; diff --git a/src/pocketmine/world/WorldTimings.php b/src/pocketmine/world/WorldTimings.php index c79f48d7ef..ab8c2d30c5 100644 --- a/src/pocketmine/world/WorldTimings.php +++ b/src/pocketmine/world/WorldTimings.php @@ -46,8 +46,6 @@ class WorldTimings{ /** @var TimingsHandler */ public $entityTick; /** @var TimingsHandler */ - public $tileEntityTick; - /** @var TimingsHandler */ public $doTick; /** @var TimingsHandler */ @@ -78,7 +76,6 @@ class WorldTimings{ $this->doTickTiles = new TimingsHandler("** " . $name . "doTickTiles"); $this->doChunkGC = new TimingsHandler("** " . $name . "doChunkGC"); $this->entityTick = new TimingsHandler("** " . $name . "entityTick"); - $this->tileEntityTick = new TimingsHandler("** " . $name . "tileEntityTick"); $this->syncChunkSendTimer = new TimingsHandler("** " . $name . "syncChunkSend"); $this->syncChunkSendPrepareTimer = new TimingsHandler("** " . $name . "syncChunkSendPrepare"); From ad1b9e5cdd2fb66f12b4a7f0f3486fa0b59b7532 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 8 Jun 2019 17:35:56 +0100 Subject: [PATCH 0906/3224] fix item pickup animation --- src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php b/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php index 27911c09b2..549ee4d284 100644 --- a/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php @@ -38,8 +38,8 @@ class TakeItemEntityPacket extends DataPacket implements ClientboundPacket{ public static function create(int $takerEntityRuntimeId, int $itemEntityRuntimeId) : self{ $result = new self; - $result->target = $takerEntityRuntimeId; - $result->eid = $itemEntityRuntimeId; + $result->target = $itemEntityRuntimeId; + $result->eid = $takerEntityRuntimeId; return $result; } From 73964e6e2f814d4cf1bf8ea5cb4ca4e637c95784 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 8 Jun 2019 17:47:55 +0100 Subject: [PATCH 0907/3224] Always do chunk relighting for unlit chunks on load this is necessary because we stopped saving light info some time ago, so it has to be calculated on load for things to work properly. --- resources/pocketmine.yml | 1 - src/pocketmine/world/World.php | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/pocketmine.yml b/resources/pocketmine.yml index c905880b7f..769b271a21 100644 --- a/resources/pocketmine.yml +++ b/resources/pocketmine.yml @@ -125,7 +125,6 @@ chunk-ticking: per-tick: 40 #Radius of chunks around a player to tick tick-radius: 3 - light-updates: false #IDs of blocks not to perform random ticking on. disable-block-ticking: #- 2 # grass diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 58d273fb01..019aff67e3 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -2521,7 +2521,7 @@ class World implements ChunkManager, Metadatable{ (new ChunkLoadEvent($this, $chunk, !$chunk->isGenerated()))->call(); - if($chunk->isPopulated() and $this->getServer()->getProperty("chunk-ticking.light-updates", false)){ + if(!$chunk->isLightPopulated() and $chunk->isPopulated()){ $this->getServer()->getAsyncPool()->submitTask(new LightPopulationTask($this, $chunk)); } From 1b629d7ac083cf833aa83b22f81b4e32495f8100 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 8 Jun 2019 17:52:47 +0100 Subject: [PATCH 0908/3224] implement daylight sensor power recalculation --- src/pocketmine/block/DaylightSensor.php | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/block/DaylightSensor.php b/src/pocketmine/block/DaylightSensor.php index 2d85e898b1..d066708591 100644 --- a/src/pocketmine/block/DaylightSensor.php +++ b/src/pocketmine/block/DaylightSensor.php @@ -29,6 +29,10 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use function cos; +use function max; +use function round; +use const M_PI; class DaylightSensor extends Transparent{ /** @var BlockIdentifierFlattened */ @@ -85,11 +89,26 @@ class DaylightSensor extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->inverted = !$this->inverted; + $this->power = $this->recalculatePower(); $this->world->setBlock($this, $this); return true; } public function onScheduledUpdate() : void{ - //TODO + $this->power = $this->recalculatePower(); + $this->world->setBlock($this, $this); + $this->world->scheduleDelayedBlockUpdate($this, 20); } + + private function recalculatePower() : int{ + $lightLevel = $this->world->getRealBlockSkyLightAt($this->x, $this->y, $this->z); + if($this->inverted){ + return 15 - $lightLevel; + } + + $sunAngle = $this->world->getSunAnglePercentage(); + return max(0, (int) round(15 * cos(($sunAngle + ((($sunAngle < 0.5 ? 0 : 1) - $sunAngle) / 5)) * 2 * M_PI))); + } + + //TODO } From f84040a7ad42c2e02cdfe9fb3a148b9e98e186c6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 8 Jun 2019 17:55:50 +0100 Subject: [PATCH 0909/3224] FlowerPot (tile): Allow BlockFactory to determine id/data validity --- src/pocketmine/block/tile/FlowerPot.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/block/tile/FlowerPot.php b/src/pocketmine/block/tile/FlowerPot.php index db9bb28eb2..d6641a1f3f 100644 --- a/src/pocketmine/block/tile/FlowerPot.php +++ b/src/pocketmine/block/tile/FlowerPot.php @@ -43,9 +43,10 @@ class FlowerPot extends Spawnable{ public function readSaveData(CompoundTag $nbt) : void{ if($nbt->hasTag(self::TAG_ITEM, ShortTag::class) and $nbt->hasTag(self::TAG_ITEM_DATA, IntTag::class)){ - //prevent stupidity with wrong items - if(($id = $nbt->getShort(self::TAG_ITEM)) >= 0 and $id <= 255 and ($data = $nbt->getInt(self::TAG_ITEM_DATA)) >= 0 and $data <= 15){ - $this->setPlant(BlockFactory::get($id, $data)); + try{ + $this->setPlant(BlockFactory::get($nbt->getShort(self::TAG_ITEM), $nbt->getInt(self::TAG_ITEM_DATA))); + }catch(\InvalidArgumentException $e){ + //noop } }else{ //TODO: new PlantBlock tag From c1f900ab1865999f035ed5693ea02bce8c2ced77 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 8 Jun 2019 18:56:27 +0100 Subject: [PATCH 0910/3224] Start using transactions for block placement --- src/pocketmine/block/Anvil.php | 5 +++-- src/pocketmine/block/Banner.php | 5 +++-- src/pocketmine/block/BaseRail.php | 5 +++-- src/pocketmine/block/Bed.php | 7 +++---- src/pocketmine/block/Block.php | 19 +++++++++++-------- src/pocketmine/block/Button.php | 5 +++-- src/pocketmine/block/Cactus.php | 5 +++-- src/pocketmine/block/Cake.php | 5 +++-- src/pocketmine/block/Carpet.php | 5 +++-- src/pocketmine/block/Chest.php | 5 +++-- src/pocketmine/block/CocoaBlock.php | 5 +++-- src/pocketmine/block/Crops.php | 5 +++-- src/pocketmine/block/DeadBush.php | 5 +++-- src/pocketmine/block/Door.php | 8 +++----- src/pocketmine/block/DoublePlant.php | 8 +++----- src/pocketmine/block/EndPortalFrame.php | 5 +++-- src/pocketmine/block/EndRod.php | 5 +++-- src/pocketmine/block/EnderChest.php | 5 +++-- src/pocketmine/block/FenceGate.php | 5 +++-- src/pocketmine/block/Flower.php | 5 +++-- src/pocketmine/block/FlowerPot.php | 5 +++-- src/pocketmine/block/Furnace.php | 5 +++-- src/pocketmine/block/GlazedTerracotta.php | 5 +++-- src/pocketmine/block/Hopper.php | 5 +++-- src/pocketmine/block/ItemFrame.php | 5 +++-- src/pocketmine/block/Ladder.php | 5 +++-- src/pocketmine/block/Leaves.php | 5 +++-- src/pocketmine/block/Lever.php | 5 +++-- src/pocketmine/block/NetherWartPlant.php | 5 +++-- src/pocketmine/block/Pumpkin.php | 5 +++-- src/pocketmine/block/RedMushroom.php | 5 +++-- src/pocketmine/block/RedstoneComparator.php | 5 +++-- src/pocketmine/block/RedstoneOre.php | 4 ---- src/pocketmine/block/RedstoneRepeater.php | 5 +++-- src/pocketmine/block/Sapling.php | 5 +++-- src/pocketmine/block/SeaPickle.php | 5 +++-- src/pocketmine/block/Sign.php | 5 +++-- src/pocketmine/block/Skull.php | 5 +++-- src/pocketmine/block/Slab.php | 5 +++-- src/pocketmine/block/SnowLayer.php | 5 +++-- src/pocketmine/block/Stair.php | 5 +++-- src/pocketmine/block/Sugarcane.php | 7 ++++--- src/pocketmine/block/TallGrass.php | 5 +++-- src/pocketmine/block/Torch.php | 9 +++++---- src/pocketmine/block/Trapdoor.php | 5 +++-- src/pocketmine/block/TripwireHook.php | 5 +++-- src/pocketmine/block/Vine.php | 5 +++-- src/pocketmine/block/WaterLily.php | 5 +++-- .../block/utils/PillarRotationTrait.php | 18 ++++++++++-------- src/pocketmine/world/World.php | 16 ++++++++++------ 50 files changed, 172 insertions(+), 129 deletions(-) diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index 5ae46ae11e..e705060572 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -34,6 +34,7 @@ use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class Anvil extends Transparent implements Fallable{ use FallableTrait; @@ -69,11 +70,11 @@ class Anvil extends Transparent implements Fallable{ return true; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = Facing::rotateY($player->getHorizontalFacing(), true); } - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function tickFalling() : ?Block{ diff --git a/src/pocketmine/block/Banner.php b/src/pocketmine/block/Banner.php index b5abb29f21..37d7734824 100644 --- a/src/pocketmine/block/Banner.php +++ b/src/pocketmine/block/Banner.php @@ -35,6 +35,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; use function assert; use function floor; @@ -141,7 +142,7 @@ class Banner extends Transparent{ return null; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof ItemBanner){ $this->baseColor = $item->getColor(); $this->setPatterns($item->getPatterns()); @@ -152,7 +153,7 @@ class Banner extends Transparent{ $this->rotation = $player !== null ? ((int) floor((($player->yaw + 180) * 16 / 360) + 0.5)) & 0x0f : 0; } - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/BaseRail.php b/src/pocketmine/block/BaseRail.php index 92fa0ca060..0a68f967ee 100644 --- a/src/pocketmine/block/BaseRail.php +++ b/src/pocketmine/block/BaseRail.php @@ -28,6 +28,7 @@ use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; use function array_map; use function array_reverse; use function array_search; @@ -96,9 +97,9 @@ abstract class BaseRail extends Flowable{ return 0b1111; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$blockReplace->getSide(Facing::DOWN)->isTransparent()){ - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 41fe42895e..08900ff04e 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -36,6 +36,7 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\utils\TextFormat; +use pocketmine\world\BlockTransaction; use pocketmine\world\World; class Bed extends Transparent{ @@ -169,7 +170,7 @@ class Bed extends Transparent{ } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof ItemBed){ //TODO: the item should do this $this->color = $item->getColor(); } @@ -179,11 +180,9 @@ class Bed extends Transparent{ $next = $this->getSide($this->getOtherHalfSide()); if($next->canBeReplaced() and !$next->getSide(Facing::DOWN)->isTransparent()){ - parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); $nextState = clone $this; $nextState->head = true; - $this->getWorld()->setBlock($next, $nextState); - + $tx->addBlock($blockReplace, $this)->addBlock($next, $nextState); return true; } } diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index fe8d53774d..1762bcad80 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -44,6 +44,7 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; use pocketmine\Player; use pocketmine\plugin\Plugin; +use pocketmine\world\BlockTransaction; use pocketmine\world\Position; use pocketmine\world\World; use function array_merge; @@ -245,17 +246,19 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ /** * Places the Block, using block space and block target, and side. Returns if the block has been placed. * - * @param Item $item - * @param Block $blockReplace - * @param Block $blockClicked - * @param int $face - * @param Vector3 $clickVector - * @param Player|null $player + * @param BlockTransaction $tx + * @param Item $item + * @param Block $blockReplace + * @param Block $blockClicked + * @param int $face + * @param Vector3 $clickVector + * @param Player|null $player * * @return bool */ - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - return $this->getWorld()->setBlock($blockReplace, $this); + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + $tx->addBlock($blockReplace, $this); + return true; } public function onPostPlace() : void{ diff --git a/src/pocketmine/block/Button.php b/src/pocketmine/block/Button.php index 85815b7846..d2ce43a17b 100644 --- a/src/pocketmine/block/Button.php +++ b/src/pocketmine/block/Button.php @@ -28,6 +28,7 @@ use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; use pocketmine\world\sound\RedstonePowerOffSound; use pocketmine\world\sound\RedstonePowerOnSound; @@ -52,10 +53,10 @@ abstract class Button extends Flowable{ return 0b1111; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ //TODO: check valid target block $this->facing = $face; - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } abstract protected function getActivationTime() : int; diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index 89a43c13c0..1b3895f9e7 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -33,6 +33,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class Cactus extends Transparent{ @@ -113,7 +114,7 @@ class Cactus extends Transparent{ } } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === BlockLegacyIds::SAND or $down->getId() === BlockLegacyIds::CACTUS){ foreach(Facing::HORIZONTAL as $side){ @@ -122,7 +123,7 @@ class Cactus extends Transparent{ } } - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index ced7195f62..2cc9057903 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -32,6 +32,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class Cake extends Transparent implements FoodSource{ @@ -61,10 +62,10 @@ class Cake extends Transparent implements FoodSource{ ->trim(Facing::WEST, $this->bites / 8); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() !== BlockLegacyIds::AIR){ - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Carpet.php b/src/pocketmine/block/Carpet.php index 3e95f9b237..7a90923da6 100644 --- a/src/pocketmine/block/Carpet.php +++ b/src/pocketmine/block/Carpet.php @@ -28,6 +28,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class Carpet extends Flowable{ @@ -43,10 +44,10 @@ class Carpet extends Flowable{ return AxisAlignedBB::one()->trim(Facing::UP, 15 / 16); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() !== BlockLegacyIds::AIR){ - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index 3e08722eef..1ef27fa6be 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -30,6 +30,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class Chest extends Transparent{ @@ -57,12 +58,12 @@ class Chest extends Transparent{ return AxisAlignedBB::one()->contract(0.025, 0, 0.025)->trim(Facing::UP, 0.05); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onPostPlace() : void{ diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index 7448074af0..15a504e8b7 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -33,6 +33,7 @@ use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; use function mt_rand; class CocoaBlock extends Transparent{ @@ -72,10 +73,10 @@ class CocoaBlock extends Transparent{ ->trim($this->facing, (11 - $this->age * 2) / 16); //outward face } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(Facing::axis($face) !== Facing::AXIS_Y and $blockClicked instanceof Wood and $blockClicked->getTreeType()->equals(TreeType::JUNGLE())){ $this->facing = $face; - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index 2609134d63..7e62e79e8f 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -30,6 +30,7 @@ use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; use function mt_rand; abstract class Crops extends Flowable{ @@ -52,9 +53,9 @@ abstract class Crops extends Flowable{ return 0b111; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($blockReplace->getSide(Facing::DOWN)->getId() === BlockLegacyIds::FARMLAND){ - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/DeadBush.php b/src/pocketmine/block/DeadBush.php index cfff53f3ae..6d03f4857b 100644 --- a/src/pocketmine/block/DeadBush.php +++ b/src/pocketmine/block/DeadBush.php @@ -28,6 +28,7 @@ use pocketmine\item\ItemFactory; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; use function mt_rand; class DeadBush extends Flowable{ @@ -36,9 +37,9 @@ class DeadBush extends Flowable{ parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant(BlockToolType::TYPE_SHEARS, 1)); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$this->getSide(Facing::DOWN)->isTransparent()){ - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 905bce98bf..1cd369998a 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -105,7 +105,7 @@ class Door extends Transparent{ } } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP){ $blockUp = $this->getSide(Facing::UP); $blockDown = $this->getSide(Facing::DOWN); @@ -127,10 +127,8 @@ class Door extends Transparent{ $topHalf = clone $this; $topHalf->top = true; - $transaction = new BlockTransaction($this->world); - $transaction->addBlock($blockReplace, $this)->addBlock($blockUp, $topHalf); - - return $transaction->apply(); + $tx->addBlock($blockReplace, $this)->addBlock($blockUp, $topHalf); + return true; } return false; diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index 56162989de..cfe827b3a1 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -50,15 +50,13 @@ class DoublePlant extends Flowable{ return 0b1000; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $id = $blockReplace->getSide(Facing::DOWN)->getId(); if(($id === BlockLegacyIds::GRASS or $id === BlockLegacyIds::DIRT) and $blockReplace->getSide(Facing::UP)->canBeReplaced()){ $top = clone $this; $top->top = true; - - $transaction = new BlockTransaction($this->world); - $transaction->addBlock($blockReplace, $this)->addBlock($blockReplace->getSide(Facing::UP), $top); - return $transaction->apply(); + $tx->addBlock($blockReplace, $this)->addBlock($blockReplace->getSide(Facing::UP), $top); + return true; } return false; diff --git a/src/pocketmine/block/EndPortalFrame.php b/src/pocketmine/block/EndPortalFrame.php index cf06d374f7..ae0f0217c8 100644 --- a/src/pocketmine/block/EndPortalFrame.php +++ b/src/pocketmine/block/EndPortalFrame.php @@ -30,6 +30,7 @@ use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class EndPortalFrame extends Solid{ @@ -63,10 +64,10 @@ class EndPortalFrame extends Solid{ return AxisAlignedBB::one()->trim(Facing::UP, 3 / 16); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } } diff --git a/src/pocketmine/block/EndRod.php b/src/pocketmine/block/EndRod.php index ecf7243022..8ff7a60853 100644 --- a/src/pocketmine/block/EndRod.php +++ b/src/pocketmine/block/EndRod.php @@ -29,6 +29,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class EndRod extends Flowable{ @@ -58,13 +59,13 @@ class EndRod extends Flowable{ return 0b111; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->facing = $face; if($blockClicked instanceof EndRod and $blockClicked->facing === $this->facing){ $this->facing = Facing::opposite($face); } - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function isSolid() : bool{ diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index e5e294797c..d0078625ee 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -32,6 +32,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class EnderChest extends Transparent{ @@ -63,11 +64,11 @@ class EnderChest extends Transparent{ return AxisAlignedBB::one()->contract(0.025, 0, 0.025)->trim(Facing::UP, 0.05); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index db51a6fd23..96399b5d83 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -30,6 +30,7 @@ use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; use pocketmine\world\sound\DoorSound; class FenceGate extends Transparent{ @@ -75,14 +76,14 @@ class FenceGate extends Transparent{ ); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = $player->getHorizontalFacing(); } $this->inWall = $this->checkInWall(); - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onNearbyBlockChange() : void{ diff --git a/src/pocketmine/block/Flower.php b/src/pocketmine/block/Flower.php index b2487390bd..7e8b2137be 100644 --- a/src/pocketmine/block/Flower.php +++ b/src/pocketmine/block/Flower.php @@ -27,6 +27,7 @@ use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class Flower extends Flowable{ @@ -34,10 +35,10 @@ class Flower extends Flowable{ parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === BlockLegacyIds::GRASS or $down->getId() === BlockLegacyIds::DIRT or $down->getId() === BlockLegacyIds::FARMLAND){ - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 3c54598ca6..0b4a06d949 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -29,6 +29,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; use function assert; class FlowerPot extends Flowable{ @@ -114,12 +115,12 @@ class FlowerPot extends Flowable{ return AxisAlignedBB::one()->contract(3 / 16, 0, 3 / 16)->trim(Facing::UP, 5 / 8); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($this->getSide(Facing::DOWN)->isTransparent()){ return false; } - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onNearbyBlockChange() : void{ diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index 9e6e765078..1a847f19ac 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -30,6 +30,7 @@ use pocketmine\item\TieredTool; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class Furnace extends Solid{ /** @var BlockIdentifierFlattened */ @@ -79,12 +80,12 @@ class Furnace extends Solid{ return $this; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/pocketmine/block/GlazedTerracotta.php b/src/pocketmine/block/GlazedTerracotta.php index c5b41331cc..881026a60d 100644 --- a/src/pocketmine/block/GlazedTerracotta.php +++ b/src/pocketmine/block/GlazedTerracotta.php @@ -30,6 +30,7 @@ use pocketmine\item\TieredTool; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class GlazedTerracotta extends Solid{ @@ -52,11 +53,11 @@ class GlazedTerracotta extends Solid{ return 0b111; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } } diff --git a/src/pocketmine/block/Hopper.php b/src/pocketmine/block/Hopper.php index 8d5eb0bc46..7f8f0a71a3 100644 --- a/src/pocketmine/block/Hopper.php +++ b/src/pocketmine/block/Hopper.php @@ -31,6 +31,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class Hopper extends Transparent{ @@ -67,10 +68,10 @@ class Hopper extends Transparent{ return $result; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->facing = $face === Facing::DOWN ? Facing::DOWN : Facing::opposite($face); - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index d3dfc235c0..aadd676a5d 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -29,6 +29,7 @@ use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; use function lcg_value; class ItemFrame extends Flowable{ @@ -178,14 +179,14 @@ class ItemFrame extends Flowable{ } } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::DOWN or $face === Facing::UP or !$blockClicked->isSolid()){ return false; } $this->facing = $face; - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/Ladder.php b/src/pocketmine/block/Ladder.php index 29846f3c4f..2477c33e8e 100644 --- a/src/pocketmine/block/Ladder.php +++ b/src/pocketmine/block/Ladder.php @@ -30,6 +30,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class Ladder extends Transparent{ @@ -76,10 +77,10 @@ class Ladder extends Transparent{ } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$blockClicked->isTransparent() and Facing::axis($face) !== Facing::AXIS_Y){ $this->facing = $face; - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 55d48de5fc..7c21d789c5 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -30,6 +30,7 @@ use pocketmine\item\ItemFactory; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; use pocketmine\world\World; use function mt_rand; @@ -111,9 +112,9 @@ class Leaves extends Transparent{ } } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->noDecay = true; //artificial leaves don't decay - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function getDrops(Item $item) : array{ diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index e2eefe1fb4..a0c1aced10 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -28,6 +28,7 @@ use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; use pocketmine\world\sound\RedstonePowerOffSound; use pocketmine\world\sound\RedstonePowerOnSound; @@ -78,7 +79,7 @@ class Lever extends Flowable{ return 0b1111; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$blockClicked->isSolid()){ return false; } @@ -93,7 +94,7 @@ class Lever extends Flowable{ $this->position = self::SIDE; } - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onNearbyBlockChange() : void{ diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index 8fd0a6a31c..2b2029e60f 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -30,6 +30,7 @@ use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; use function mt_rand; class NetherWartPlant extends Flowable{ @@ -53,10 +54,10 @@ class NetherWartPlant extends Flowable{ return 0b11; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === BlockLegacyIds::SOUL_SAND){ - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Pumpkin.php b/src/pocketmine/block/Pumpkin.php index f73396e247..31123bb9c6 100644 --- a/src/pocketmine/block/Pumpkin.php +++ b/src/pocketmine/block/Pumpkin.php @@ -29,6 +29,7 @@ use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class Pumpkin extends Solid{ @@ -51,10 +52,10 @@ class Pumpkin extends Solid{ return 0b11; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } } diff --git a/src/pocketmine/block/RedMushroom.php b/src/pocketmine/block/RedMushroom.php index 40c0652005..909cfd853e 100644 --- a/src/pocketmine/block/RedMushroom.php +++ b/src/pocketmine/block/RedMushroom.php @@ -27,6 +27,7 @@ use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class RedMushroom extends Flowable{ @@ -44,10 +45,10 @@ class RedMushroom extends Flowable{ } } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if(!$down->isTransparent()){ - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/RedstoneComparator.php b/src/pocketmine/block/RedstoneComparator.php index 3090ee026b..8ea7f9a761 100644 --- a/src/pocketmine/block/RedstoneComparator.php +++ b/src/pocketmine/block/RedstoneComparator.php @@ -31,6 +31,7 @@ use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; use function assert; class RedstoneComparator extends Flowable{ @@ -147,12 +148,12 @@ class RedstoneComparator extends Flowable{ return AxisAlignedBB::one()->trim(Facing::UP, 7 / 8); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$blockReplace->getSide(Facing::DOWN)->isTransparent()){ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/RedstoneOre.php b/src/pocketmine/block/RedstoneOre.php index 533859b883..d3b11d4c78 100644 --- a/src/pocketmine/block/RedstoneOre.php +++ b/src/pocketmine/block/RedstoneOre.php @@ -67,10 +67,6 @@ class RedstoneOre extends Solid{ return $this->lit ? 9 : 0; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - return $this->getWorld()->setBlock($this, $this, false); - } - public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$this->lit){ $this->lit = true; diff --git a/src/pocketmine/block/RedstoneRepeater.php b/src/pocketmine/block/RedstoneRepeater.php index 8c4dbec511..fad3f599db 100644 --- a/src/pocketmine/block/RedstoneRepeater.php +++ b/src/pocketmine/block/RedstoneRepeater.php @@ -30,6 +30,7 @@ use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class RedstoneRepeater extends Flowable{ /** @var BlockIdentifierFlattened */ @@ -82,13 +83,13 @@ class RedstoneRepeater extends Flowable{ return $this; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$blockReplace->getSide(Facing::DOWN)->isTransparent()){ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index 72930d2abb..e312c9ff78 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -30,6 +30,7 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\utils\Random; +use pocketmine\world\BlockTransaction; use pocketmine\world\generator\object\Tree; use function mt_rand; @@ -57,10 +58,10 @@ class Sapling extends Flowable{ return 0b1000; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === BlockLegacyIds::GRASS or $down->getId() === BlockLegacyIds::DIRT or $down->getId() === BlockLegacyIds::FARMLAND){ - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/SeaPickle.php b/src/pocketmine/block/SeaPickle.php index dbfbd5a34f..26dab94aa8 100644 --- a/src/pocketmine/block/SeaPickle.php +++ b/src/pocketmine/block/SeaPickle.php @@ -27,6 +27,7 @@ use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class SeaPickle extends Transparent{ /** @var int */ @@ -68,13 +69,13 @@ class SeaPickle extends Transparent{ return ($blockReplace instanceof SeaPickle and $blockReplace->count < 4) or parent::canBePlacedAt($blockReplace, $clickVector, $face, $isClickedBlock); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->underwater = false; //TODO: implement this once we have new water logic in place if($blockReplace instanceof SeaPickle and $blockReplace->count < 4){ $this->count = $blockReplace->count + 1; } - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/pocketmine/block/Sign.php b/src/pocketmine/block/Sign.php index 3652b840a8..58ca727735 100644 --- a/src/pocketmine/block/Sign.php +++ b/src/pocketmine/block/Sign.php @@ -33,6 +33,7 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; use pocketmine\utils\TextFormat; +use pocketmine\world\BlockTransaction; use function array_map; use function assert; use function floor; @@ -109,14 +110,14 @@ class Sign extends Transparent{ return null; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face !== Facing::DOWN){ $this->facing = $face; if($face === Facing::UP){ $this->rotation = $player !== null ? ((int) floor((($player->yaw + 180) * 16 / 360) + 0.5)) & 0x0f : 0; } - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index fcd242a923..e9aa86a187 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -33,6 +33,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; use function assert; use function floor; @@ -93,7 +94,7 @@ class Skull extends Flowable{ return AxisAlignedBB::one()->contract(0.25, 0, 0.25)->trim(Facing::UP, 0.5); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::DOWN){ return false; } @@ -105,7 +106,7 @@ class Skull extends Flowable{ if($player !== null and $face === Facing::UP){ $this->rotation = ((int) floor(($player->yaw * 16 / 360) + 0.5)) & 0xf; } - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function asItem() : Item{ diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index 59be315be8..975010f69e 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -29,6 +29,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class Slab extends Transparent{ /** @var BlockIdentifierFlattened */ @@ -104,7 +105,7 @@ class Slab extends Transparent{ return false; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($blockReplace instanceof Slab and !$blockReplace->slabType->equals(SlabType::DOUBLE()) and $blockReplace->isSameType($this) and ( ($blockReplace->slabType->equals(SlabType::TOP()) and ($clickVector->y <= 0.5 or $face === Facing::UP)) or ($blockReplace->slabType->equals(SlabType::BOTTOM()) and ($clickVector->y >= 0.5 or $face === Facing::DOWN)) @@ -115,7 +116,7 @@ class Slab extends Transparent{ $this->slabType = (($face !== Facing::UP && $clickVector->y > 0.5) || $face === Facing::DOWN) ? SlabType::TOP() : SlabType::BOTTOM(); } - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } protected function recalculateBoundingBox() : ?AxisAlignedBB{ diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index b7418125f1..a7ceacc5a3 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -33,6 +33,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; use function floor; use function max; @@ -67,7 +68,7 @@ class SnowLayer extends Flowable implements Fallable{ return AxisAlignedBB::one()->trim(Facing::UP, $this->layers >= 4 ? 0.5 : 1); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($blockReplace instanceof SnowLayer){ if($blockReplace->layers >= 8){ return false; @@ -76,7 +77,7 @@ class SnowLayer extends Flowable implements Fallable{ } if($blockReplace->getSide(Facing::DOWN)->isSolid()){ //TODO: fix placement - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index 52ca58c6d0..d904de9259 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -29,6 +29,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class Stair extends Transparent{ private const SHAPE_STRAIGHT = "straight"; @@ -104,12 +105,12 @@ class Stair extends Transparent{ ) ? $side->facing : null; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = $player->getHorizontalFacing(); } $this->upsideDown = (($clickVector->y > 0.5 and $face !== Facing::UP) or $face === Facing::DOWN); - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } } diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index 4f8c01c4cf..d60e1a5f3b 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -30,6 +30,7 @@ use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class Sugarcane extends Flowable{ @@ -110,14 +111,14 @@ class Sugarcane extends Flowable{ } } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === BlockLegacyIds::SUGARCANE_BLOCK){ - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); }elseif($down->getId() === BlockLegacyIds::GRASS or $down->getId() === BlockLegacyIds::DIRT or $down->getId() === BlockLegacyIds::SAND){ foreach(Facing::HORIZONTAL as $side){ if($down->getSide($side) instanceof Water){ - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } } } diff --git a/src/pocketmine/block/TallGrass.php b/src/pocketmine/block/TallGrass.php index 53fe1b9db7..7a6a8cc81a 100644 --- a/src/pocketmine/block/TallGrass.php +++ b/src/pocketmine/block/TallGrass.php @@ -28,6 +28,7 @@ use pocketmine\item\ItemFactory; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; use function mt_rand; class TallGrass extends Flowable{ @@ -40,10 +41,10 @@ class TallGrass extends Flowable{ return true; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN)->getId(); if($down === BlockLegacyIds::GRASS or $down === BlockLegacyIds::DIRT){ - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index 24e7e4573c..c9f09ec88e 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -28,6 +28,7 @@ use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class Torch extends Flowable{ @@ -63,13 +64,13 @@ class Torch extends Flowable{ } } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($blockClicked->canBeReplaced() and !$blockClicked->getSide(Facing::DOWN)->isTransparent()){ $this->facing = Facing::UP; - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); }elseif($face !== Facing::DOWN and (!$blockClicked->isTransparent() or ($face === Facing::UP and ($blockClicked->getId() === BlockLegacyIds::FENCE or $blockClicked->getId() === BlockLegacyIds::COBBLESTONE_WALL)))){ $this->facing = $face; - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); }else{ static $faces = [ Facing::SOUTH, @@ -82,7 +83,7 @@ class Torch extends Flowable{ $block = $this->getSide($side); if(!$block->isTransparent()){ $this->facing = Facing::opposite($side); - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } } } diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index 4b41837b1f..5b829ee0e8 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -29,6 +29,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; use pocketmine\world\sound\DoorSound; class Trapdoor extends Transparent{ @@ -60,7 +61,7 @@ class Trapdoor extends Transparent{ return AxisAlignedBB::one()->trim($this->open ? $this->facing : ($this->top ? Facing::DOWN : Facing::UP), 13 / 16); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } @@ -68,7 +69,7 @@ class Trapdoor extends Transparent{ $this->top = true; } - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/pocketmine/block/TripwireHook.php b/src/pocketmine/block/TripwireHook.php index 72ac42f7a6..b884900af7 100644 --- a/src/pocketmine/block/TripwireHook.php +++ b/src/pocketmine/block/TripwireHook.php @@ -29,6 +29,7 @@ use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class TripwireHook extends Flowable{ @@ -59,11 +60,11 @@ class TripwireHook extends Flowable{ return 0b1111; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(Facing::axis($face) !== Facing::AXIS_Y){ //TODO: check face is valid $this->facing = $face; - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; } diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index 3ef3e29373..4de77fadad 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -29,6 +29,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; use function array_intersect_key; use function array_keys; use function count; @@ -100,7 +101,7 @@ class Vine extends Flowable{ return []; } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$blockClicked->isSolid() or Facing::axis($face) === Facing::AXIS_Y){ return false; } @@ -108,7 +109,7 @@ class Vine extends Flowable{ $this->faces = $blockReplace instanceof Vine ? $blockReplace->faces : []; $this->faces[Facing::opposite($face)] = true; - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onNearbyBlockChange() : void{ diff --git a/src/pocketmine/block/WaterLily.php b/src/pocketmine/block/WaterLily.php index b93f6d9d38..73428917a1 100644 --- a/src/pocketmine/block/WaterLily.php +++ b/src/pocketmine/block/WaterLily.php @@ -28,6 +28,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; class WaterLily extends Flowable{ @@ -39,11 +40,11 @@ class WaterLily extends Flowable{ return AxisAlignedBB::one()->contract(1 / 16, 0, 1 / 16)->trim(Facing::UP, 63 / 64); } - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($blockClicked instanceof Water){ $up = $blockClicked->getSide(Facing::UP); if($up->canBeReplaced()){ - return parent::place($item, $up, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $up, $blockClicked, $face, $clickVector, $player); } } diff --git a/src/pocketmine/block/utils/PillarRotationTrait.php b/src/pocketmine/block/utils/PillarRotationTrait.php index 8bec7c9645..b84dd7b79d 100644 --- a/src/pocketmine/block/utils/PillarRotationTrait.php +++ b/src/pocketmine/block/utils/PillarRotationTrait.php @@ -28,6 +28,7 @@ use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\Player; +use pocketmine\world\BlockTransaction; trait PillarRotationTrait{ @@ -89,18 +90,19 @@ trait PillarRotationTrait{ /** * @see Block::place() * - * @param Item $item - * @param Block $blockReplace - * @param Block $blockClicked - * @param int $face - * @param Vector3 $clickVector - * @param Player|null $player + * @param BlockTransaction $tx + * @param Item $item + * @param Block $blockReplace + * @param Block $blockClicked + * @param int $face + * @param Vector3 $clickVector + * @param Player|null $player * * @return bool */ - public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->axis = Facing::axis($face); /** @see Block::place() */ - return parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } } diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 019aff67e3..77cbbab638 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -1830,15 +1830,19 @@ class World implements ChunkManager, Metadatable{ } } - if(!$hand->place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ + $tx = new BlockTransaction($this); + if(!$hand->place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player) or !$tx->apply()){ return false; } - $tile = $this->getTile($hand); - if($tile !== null){ - //TODO: seal this up inside block placement - $tile->copyDataFromItem($item); + foreach($tx->getBlocks() as [$x, $y, $z, $_]){ + $tile = $this->getTileAt($x, $y, $z); + if($tile !== null){ + //TODO: seal this up inside block placement + $tile->copyDataFromItem($item); + } + + $this->getBlockAt($x, $y, $z)->onPostPlace(); } - $hand->onPostPlace(); if($playSound){ $this->addSound($hand, new BlockPlaceSound($hand)); From 419fc418feef53988229f9642200bf924891f3d5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 10 Jun 2019 15:52:07 +0100 Subject: [PATCH 0911/3224] SubChunk: reduce memory usage on fast-deserialized chunks this saves about 25MB RAM on an idle server on HEAD commit with 856 chunks loaded. --- src/pocketmine/world/format/SubChunk.php | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/pocketmine/world/format/SubChunk.php b/src/pocketmine/world/format/SubChunk.php index e1b0c6f50d..e9c132145f 100644 --- a/src/pocketmine/world/format/SubChunk.php +++ b/src/pocketmine/world/format/SubChunk.php @@ -32,11 +32,13 @@ use function defined; use function ord; use function str_repeat; use function strlen; -use function substr_count; if(!defined(__NAMESPACE__ . '\ZERO_NIBBLE_ARRAY')){ define(__NAMESPACE__ . '\ZERO_NIBBLE_ARRAY', str_repeat("\x00", 2048)); } +if(!defined(__NAMESPACE__ . '\FIFTEEN_NIBBLE_ARRAY')){ + define(__NAMESPACE__ . '\FIFTEEN_NIBBLE_ARRAY', str_repeat("\xff", 2048)); +} class SubChunk implements SubChunkInterface{ /** @var PalettedBlockArray[] */ @@ -47,10 +49,12 @@ class SubChunk implements SubChunkInterface{ /** @var string */ protected $skyLight; - private static function assignData(&$target, string $data, int $length, string $value = "\x00") : void{ - if(strlen($data) !== $length){ - assert($data === "", "Invalid non-zero length given, expected $length, got " . strlen($data)); - $target = str_repeat($value, $length); + private static function assignData(&$target, string $data, string $default) : void{ + if($data === "" or $data === $default){ + $target = $default; + }elseif(strlen($data) !== 2048){ + assert(false, "Invalid length given, expected 2048, got " . strlen($data)); + $target = $default; }else{ $target = $data; } @@ -66,8 +70,8 @@ class SubChunk implements SubChunkInterface{ public function __construct(array $blocks, string $skyLight = "", string $blockLight = ""){ $this->blockLayers = $blocks; - self::assignData($this->skyLight, $skyLight, 2048, "\xff"); - self::assignData($this->blockLight, $blockLight, 2048); + self::assignData($this->skyLight, $skyLight, FIFTEEN_NIBBLE_ARRAY); + self::assignData($this->blockLight, $blockLight, ZERO_NIBBLE_ARRAY); } public function isEmpty(bool $checkLight = true) : bool{ @@ -81,7 +85,7 @@ class SubChunk implements SubChunkInterface{ } return (!$checkLight or ( - substr_count($this->skyLight, "\xff") === 2048 and + $this->skyLight === FIFTEEN_NIBBLE_ARRAY and $this->blockLight === ZERO_NIBBLE_ARRAY ) ); From 714393820f4c74a35f5a67925451dbedd1e36909 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 10 Jun 2019 19:14:08 +0100 Subject: [PATCH 0912/3224] MainLogger: Use millisecond precision on log timestamps --- src/pocketmine/utils/MainLogger.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/pocketmine/utils/MainLogger.php b/src/pocketmine/utils/MainLogger.php index a6a43da617..cdadf944e4 100644 --- a/src/pocketmine/utils/MainLogger.php +++ b/src/pocketmine/utils/MainLogger.php @@ -33,7 +33,6 @@ use function get_class; use function is_resource; use function preg_replace; use function sprintf; -use function time; use function touch; use function trim; use const PHP_EOL; @@ -250,12 +249,7 @@ class MainLogger extends \AttachableThreadedLogger{ } protected function send($message, $level, $prefix, $color) : void{ - /** @var \DateTime|null $time */ - static $time = null; - if($time === null){ //thread-local - $time = new \DateTime('now', new \DateTimeZone($this->timezone)); - } - $time->setTimestamp(time()); + $time = new \DateTime('now', new \DateTimeZone($this->timezone)); $thread = \Thread::getCurrentThread(); if($thread === null){ @@ -266,7 +260,7 @@ class MainLogger extends \AttachableThreadedLogger{ $threadName = (new \ReflectionClass($thread))->getShortName() . " thread"; } - $message = sprintf($this->format, $time->format("H:i:s"), $color, $threadName, $prefix, $message); + $message = sprintf($this->format, $time->format("H:i:s.v"), $color, $threadName, $prefix, $message); if(!Terminal::isInit()){ Terminal::init($this->mainThreadHasFormattingCodes); //lazy-init colour codes because we don't know if they've been registered on this thread From 3ac0c98199484abd08d6bb66fac5ef21c409d40d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 10 Jun 2019 19:31:54 +0100 Subject: [PATCH 0913/3224] De-spaghettify spawn notification handling --- src/pocketmine/Player.php | 2 -- src/pocketmine/network/mcpe/NetworkSession.php | 1 + src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index f623927fa7..559090fa08 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1001,8 +1001,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } public function doFirstSpawn(){ - $this->networkSession->onSpawn(); - if($this->hasPermission(Server::BROADCAST_CHANNEL_USERS)){ PermissionManager::getInstance()->subscribeToPermission(Server::BROADCAST_CHANNEL_USERS, $this); } diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 943b8584a3..49601d88ab 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -567,6 +567,7 @@ class NetworkSession{ } public function onSpawn() : void{ + $this->player->doFirstSpawn(); $this->setHandler(new InGameSessionHandler($this->player, $this)); } diff --git a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php index 81a67f3df6..ef8fd1f33d 100644 --- a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php @@ -108,7 +108,7 @@ class PreSpawnSessionHandler extends SessionHandler{ public function handleSetLocalPlayerAsInitialized(SetLocalPlayerAsInitializedPacket $packet) : bool{ $this->player->setImmobile(false); //HACK: this is set to prevent client-side falling before spawn - $this->player->doFirstSpawn(); + $this->session->onSpawn(); return true; } From dd45753fa9e0ef739e9ff6c2dece117717491906 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 10 Jun 2019 19:47:02 +0100 Subject: [PATCH 0914/3224] NetworkSession: add some more debug --- src/pocketmine/network/mcpe/NetworkSession.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 49601d88ab..c5ab78e39b 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -560,13 +560,16 @@ class NetworkSession{ $this->createPlayer(); $this->setHandler(new PreSpawnSessionHandler($this->server, $this->player, $this)); + $this->logger->debug("Waiting for spawn chunks"); } public function onTerrainReady() : void{ + $this->logger->debug("Sending spawn notification, waiting for spawn response"); $this->sendDataPacket(PlayStatusPacket::create(PlayStatusPacket::PLAYER_SPAWN)); } public function onSpawn() : void{ + $this->logger->debug("Received spawn response, entering in-game phase"); $this->player->doFirstSpawn(); $this->setHandler(new InGameSessionHandler($this->player, $this)); } From f0d56f25b6f52d5b25238699e0aeec39765302da Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 10 Jun 2019 19:54:24 +0100 Subject: [PATCH 0915/3224] Moved creative inventory sync to NetworkSession --- src/pocketmine/Player.php | 2 +- src/pocketmine/inventory/PlayerInventory.php | 18 ------------------ src/pocketmine/network/mcpe/NetworkSession.php | 12 ++++++++++++ .../mcpe/handler/PreSpawnSessionHandler.php | 2 +- 4 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 559090fa08..24b6aa22a2 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1302,7 +1302,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $this->networkSession->syncAdventureSettings($this); - $this->inventory->sendCreativeContents(); + $this->networkSession->syncCreativeInventoryContents(); return true; } diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index 5629a706e8..206ad8660a 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -25,7 +25,6 @@ namespace pocketmine\inventory; use pocketmine\entity\Human; use pocketmine\item\Item; -use pocketmine\network\mcpe\protocol\InventoryContentPacket; use pocketmine\network\mcpe\protocol\MobEquipmentPacket; use pocketmine\network\mcpe\protocol\types\ContainerIds; use pocketmine\Player; @@ -156,23 +155,6 @@ class PlayerInventory extends BaseInventory{ return 9; } - public function sendCreativeContents() : void{ - //TODO: this mess shouldn't be in here - $holder = $this->getHolder(); - if(!($holder instanceof Player)){ - throw new \LogicException("Cannot send creative inventory contents to non-player inventory holder"); - } - - $items = []; - if(!$holder->isSpectator()){ //fill it for all gamemodes except spectator - foreach(CreativeInventory::getAll() as $i => $item){ - $items[$i] = clone $item; - } - } - - $holder->sendDataPacket(InventoryContentPacket::create(ContainerIds::CREATIVE, $items)); - } - /** * This override is here for documentation and code completion purposes only. * @return Human|Player diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index c5ab78e39b..c6cd8a9c3d 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -30,6 +30,7 @@ use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\event\server\DataPacketSendEvent; use pocketmine\form\Form; use pocketmine\GameMode; +use pocketmine\inventory\CreativeInventory; use pocketmine\inventory\Inventory; use pocketmine\math\Vector3; use pocketmine\network\BadPacketException; @@ -774,6 +775,17 @@ class NetworkSession{ } } + public function syncCreativeInventoryContents() : void{ + $items = []; + if(!$this->player->isSpectator()){ //fill it for all gamemodes except spectator + foreach(CreativeInventory::getAll() as $i => $item){ + $items[$i] = clone $item; + } + } + + $this->sendDataPacket(InventoryContentPacket::create(ContainerIds::CREATIVE, $items)); + } + public function onMobArmorChange(Living $mob) : void{ $inv = $mob->getArmorInventory(); $this->sendDataPacket(MobArmorEquipmentPacket::create($mob->getId(), $inv->getHelmet(), $inv->getChestplate(), $inv->getLeggings(), $inv->getBoots())); diff --git a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php index ef8fd1f33d..63f8a11213 100644 --- a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php @@ -92,7 +92,7 @@ class PreSpawnSessionHandler extends SessionHandler{ $this->player->sendData($this->player); $this->session->syncAllInventoryContents(); - $this->player->getInventory()->sendCreativeContents(); + $this->session->syncCreativeInventoryContents(); $this->player->getInventory()->sendHeldItem($this->player); $this->session->queueCompressed($this->server->getCraftingManager()->getCraftingDataPacket()); From 8e6f21afad1f6ce6c3ca2496195107fbaefb3cd1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 10 Jun 2019 19:58:14 +0100 Subject: [PATCH 0916/3224] clean up gamemode net sync --- src/pocketmine/Player.php | 17 ++--------------- src/pocketmine/network/mcpe/NetworkSession.php | 6 +++++- .../mcpe/handler/InGameSessionHandler.php | 3 +-- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 24b6aa22a2..5a89d4a7de 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -27,7 +27,6 @@ use pocketmine\block\Bed; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\block\UnknownBlock; -use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; @@ -1262,11 +1261,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * Sets the gamemode, and if needed, kicks the Player. * * @param GameMode $gm - * @param bool $client if the client made this change in their GUI * * @return bool */ - public function setGamemode(GameMode $gm, bool $client = false) : bool{ + public function setGamemode(GameMode $gm) : bool{ if($this->gamemode === $gm){ return false; } @@ -1274,9 +1272,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $ev = new PlayerGameModeChangeEvent($this, $gm); $ev->call(); if($ev->isCancelled()){ - if($client){ //gamemode change by client in the GUI - $this->networkSession->syncGameMode($this->gamemode); - } return false; } @@ -1295,15 +1290,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->spawnToAll(); } - if(!$client){ //Gamemode changed by server, do not send for client changes - $this->networkSession->syncGameMode($this->gamemode); - }else{ - Command::broadcastCommandMessage($this, new TranslationContainer("commands.gamemode.success.self", [$gm->getTranslationKey()])); - } - - $this->networkSession->syncAdventureSettings($this); - $this->networkSession->syncCreativeInventoryContents(); - + $this->networkSession->syncGameMode($this->gamemode); return true; } diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index c6cd8a9c3d..adcb0f3d9d 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -610,8 +610,12 @@ class NetworkSession{ $this->sendDataPacket(SetSpawnPositionPacket::playerSpawn($newSpawn->getFloorX(), $newSpawn->getFloorY(), $newSpawn->getFloorZ(), false)); //TODO: spawn forced } - public function syncGameMode(GameMode $mode) : void{ + public function syncGameMode(GameMode $mode, bool $isRollback = false) : void{ $this->sendDataPacket(SetPlayerGameTypePacket::create(self::getClientFriendlyGamemode($mode))); + $this->syncAdventureSettings($this->player); + if(!$isRollback){ + $this->syncCreativeInventoryContents(); + } } /** diff --git a/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php b/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php index 6393e48e66..6e1bd11c31 100644 --- a/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php @@ -534,8 +534,7 @@ class InGameSessionHandler extends SessionHandler{ public function handleSetPlayerGameType(SetPlayerGameTypePacket $packet) : bool{ if($packet->gamemode !== $this->player->getGamemode()->getMagicNumber()){ //Set this back to default. TODO: handle this properly - $this->session->syncGameMode($this->player->getGamemode()); - $this->session->syncAdventureSettings($this->player); + $this->session->syncGameMode($this->player->getGamemode(), true); } return true; } From 1c6922618707ca56419ce970852bff0700bb050f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 11 Jun 2019 09:55:32 +0100 Subject: [PATCH 0917/3224] NetworkSession: add an extra debug --- src/pocketmine/network/mcpe/NetworkSession.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index adcb0f3d9d..818eb8a7ca 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -554,6 +554,7 @@ class NetworkSession{ $this->sendDataPacket(PlayStatusPacket::create(PlayStatusPacket::LOGIN_SUCCESS)); + $this->logger->debug("Initiating resource packs phase"); $this->setHandler(new ResourcePacksSessionHandler($this, $this->server->getResourcePackManager())); } From f349a58f2bb084a5be2b31cbb39d70d445f1fe2b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 11 Jun 2019 14:46:19 +0100 Subject: [PATCH 0918/3224] TimingsHandler: added time(Closure) function I find myself often using try/finally blocks to avoid accidentally forgetting to stop a timer. This allows a cleaner more concise way of doing it. --- src/pocketmine/timings/TimingsHandler.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pocketmine/timings/TimingsHandler.php b/src/pocketmine/timings/TimingsHandler.php index 11db46a3a8..43790b299f 100644 --- a/src/pocketmine/timings/TimingsHandler.php +++ b/src/pocketmine/timings/TimingsHandler.php @@ -184,6 +184,12 @@ class TimingsHandler{ } } + public function time(\Closure $closure) : void{ + $this->startTiming(); + $closure(); + $this->stopTiming(); + } + public function reset() : void{ $this->count = 0; $this->curCount = 0; From de6053de11d8064345b5dea852b268f5389cc507 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 11 Jun 2019 14:54:54 +0100 Subject: [PATCH 0919/3224] TimingsHandler: use a try/finally block in time() --- src/pocketmine/timings/TimingsHandler.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/timings/TimingsHandler.php b/src/pocketmine/timings/TimingsHandler.php index 43790b299f..9a35c338e2 100644 --- a/src/pocketmine/timings/TimingsHandler.php +++ b/src/pocketmine/timings/TimingsHandler.php @@ -186,8 +186,11 @@ class TimingsHandler{ public function time(\Closure $closure) : void{ $this->startTiming(); - $closure(); - $this->stopTiming(); + try{ + $closure(); + }finally{ + $this->stopTiming(); + } } public function reset() : void{ From 858f440bcf230403a0e9eda89ac9e462121529cf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 11 Jun 2019 15:04:30 +0100 Subject: [PATCH 0920/3224] TimingsHandler: return the result of $closure() for easier usage this isn't type safe, but it doesn't matter a whole lot, and there's nothing we can do about it without generics. --- src/pocketmine/timings/TimingsHandler.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/timings/TimingsHandler.php b/src/pocketmine/timings/TimingsHandler.php index 9a35c338e2..5e9e211f25 100644 --- a/src/pocketmine/timings/TimingsHandler.php +++ b/src/pocketmine/timings/TimingsHandler.php @@ -184,10 +184,15 @@ class TimingsHandler{ } } - public function time(\Closure $closure) : void{ + /** + * @param \Closure $closure + * + * @return mixed the result of the given closure + */ + public function time(\Closure $closure){ $this->startTiming(); try{ - $closure(); + return $closure(); }finally{ $this->stopTiming(); } From 4364d2a9425b260b7d13a0cb45aec8ceac5d31e9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 Jun 2019 16:54:30 +0100 Subject: [PATCH 0921/3224] AvailableCommandsPacket: Clean up internals this is still disgusting, but it's a little more bearable now. --- .../mcpe/protocol/AvailableCommandsPacket.php | 176 +++++++++--------- 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php index b44bb42ede..587541f11e 100644 --- a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php @@ -31,11 +31,6 @@ use pocketmine\network\mcpe\protocol\types\CommandData; use pocketmine\network\mcpe\protocol\types\CommandEnum; use pocketmine\network\mcpe\protocol\types\CommandParameter; use pocketmine\utils\BinaryDataException; -use function array_flip; -use function array_keys; -use function array_map; -use function array_search; -use function array_values; use function count; use function dechex; @@ -85,30 +80,6 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ */ public const ARG_FLAG_POSTFIX = 0x1000000; - /** - * @var string[] - * A list of every single enum value for every single command in the packet, including alias names. - */ - public $enumValues = []; - /** @var int */ - private $enumValuesCount = 0; - - /** - * @var string[] - * A list of argument postfixes. Used for the /xp command's L. - */ - public $postfixes = []; - - /** - * @var CommandEnum[] - * List of command enums, from command aliases to argument enums. - */ - public $enums = []; - /** - * @var int[] string => int map of enum name to index - */ - private $enumMap = []; - /** * @var CommandData[] * List of command data, including name, description, alias indexes and parameters. @@ -123,20 +94,26 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ public $softEnums = []; protected function decodePayload() : void{ - for($i = 0, $this->enumValuesCount = $this->getUnsignedVarInt(); $i < $this->enumValuesCount; ++$i){ - $this->enumValues[] = $this->getString(); + /** @var string[] $enumValues */ + $enumValues = []; + for($i = 0, $enumValuesCount = $this->getUnsignedVarInt(); $i < $enumValuesCount; ++$i){ + $enumValues[] = $this->getString(); + } + + /** @var string[] $postfixes */ + $postfixes = []; + for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ + $postfixes[] = $this->getString(); + } + + /** @var CommandEnum[] $enums */ + $enums = []; + for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ + $enums[] = $this->getEnum($enumValues); } for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ - $this->postfixes[] = $this->getString(); - } - - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ - $this->enums[] = $this->getEnum(); - } - - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ - $this->commandData[] = $this->getCommandData(); + $this->commandData[] = $this->getCommandData($enums, $postfixes); } for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ @@ -145,21 +122,25 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ } /** + * @param string[] $enumValueList + * * @return CommandEnum * @throws BadPacketException * @throws BinaryDataException */ - protected function getEnum() : CommandEnum{ + protected function getEnum(array $enumValueList) : CommandEnum{ $retval = new CommandEnum(); $retval->enumName = $this->getString(); + $listSize = count($enumValueList); + for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ - $index = $this->getEnumValueIndex(); - if(!isset($this->enumValues[$index])){ + $index = $this->getEnumValueIndex($listSize); + if(!isset($enumValueList[$index])){ throw new BadPacketException("Invalid enum value index $index"); } //Get the enum value from the initial pile of mess - $retval->enumValues[] = $this->enumValues[$index]; + $retval->enumValues[] = $enumValueList[$index]; } return $retval; @@ -181,17 +162,21 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ return $retval; } - protected function putEnum(CommandEnum $enum) : void{ + /** + * @param CommandEnum $enum + * @param string[] $enumValueMap + */ + protected function putEnum(CommandEnum $enum, array $enumValueMap) : void{ $this->putString($enum->enumName); $this->putUnsignedVarInt(count($enum->enumValues)); + $listSize = count($enumValueMap); foreach($enum->enumValues as $value){ - //Dumb bruteforce search. I hate this packet. - $index = array_search($value, $this->enumValues, true); - if($index === false){ + $index = $enumValueMap[$value] ?? -1; + if($index === -1){ throw new \InvalidStateException("Enum value '$value' not found"); } - $this->putEnumValueIndex($index); + $this->putEnumValueIndex($index, $listSize); } } @@ -205,23 +190,25 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ } /** + * @param int $valueCount + * * @return int * @throws BinaryDataException */ - protected function getEnumValueIndex() : int{ - if($this->enumValuesCount < 256){ + protected function getEnumValueIndex(int $valueCount) : int{ + if($valueCount < 256){ return $this->getByte(); - }elseif($this->enumValuesCount < 65536){ + }elseif($valueCount < 65536){ return $this->getLShort(); }else{ return $this->getLInt(); } } - protected function putEnumValueIndex(int $index) : void{ - if($this->enumValuesCount < 256){ + protected function putEnumValueIndex(int $index, int $valueCount) : void{ + if($valueCount < 256){ $this->putByte($index); - }elseif($this->enumValuesCount < 65536){ + }elseif($valueCount < 65536){ $this->putLShort($index); }else{ $this->putLInt($index); @@ -229,17 +216,20 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ } /** + * @param CommandEnum[] $enums + * @param string[] $postfixes + * * @return CommandData * @throws BadPacketException * @throws BinaryDataException */ - protected function getCommandData() : CommandData{ + protected function getCommandData(array $enums, array $postfixes) : CommandData{ $retval = new CommandData(); $retval->commandName = $this->getString(); $retval->commandDescription = $this->getString(); $retval->flags = $this->getByte(); $retval->permission = $this->getByte(); - $retval->aliases = $this->enums[$this->getLInt()] ?? null; + $retval->aliases = $enums[$this->getLInt()] ?? null; for($overloadIndex = 0, $overloadCount = $this->getUnsignedVarInt(); $overloadIndex < $overloadCount; ++$overloadIndex){ for($paramIndex = 0, $paramCount = $this->getUnsignedVarInt(); $paramIndex < $paramCount; ++$paramIndex){ @@ -251,13 +241,13 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ if($parameter->paramType & self::ARG_FLAG_ENUM){ $index = ($parameter->paramType & 0xffff); - $parameter->enum = $this->enums[$index] ?? null; + $parameter->enum = $enums[$index] ?? null; if($parameter->enum === null){ throw new BadPacketException("deserializing $retval->commandName parameter $parameter->paramName: expected enum at $index, but got none"); } }elseif($parameter->paramType & self::ARG_FLAG_POSTFIX){ $index = ($parameter->paramType & 0xffff); - $parameter->postfix = $this->postfixes[$index] ?? null; + $parameter->postfix = $postfixes[$index] ?? null; if($parameter->postfix === null){ throw new BadPacketException("deserializing $retval->commandName parameter $parameter->paramName: expected postfix at $index, but got none"); } @@ -272,14 +262,19 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ return $retval; } - protected function putCommandData(CommandData $data) : void{ + /** + * @param CommandData $data + * @param int[] $enumIndexes string enum name -> int index + * @param int[] $postfixIndexes + */ + protected function putCommandData(CommandData $data, array $enumIndexes, array $postfixIndexes) : void{ $this->putString($data->commandName); $this->putString($data->commandDescription); $this->putByte($data->flags); $this->putByte($data->permission); if($data->aliases !== null){ - $this->putLInt($this->enumMap[$data->aliases->enumName] ?? -1); + $this->putLInt($enumIndexes[$data->aliases->enumName] ?? -1); }else{ $this->putLInt(-1); } @@ -292,10 +287,10 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ $this->putString($parameter->paramName); if($parameter->enum !== null){ - $type = self::ARG_FLAG_ENUM | self::ARG_FLAG_VALID | ($this->enumMap[$parameter->enum->enumName] ?? -1); + $type = self::ARG_FLAG_ENUM | self::ARG_FLAG_VALID | ($enumIndexes[$parameter->enum->enumName] ?? -1); }elseif($parameter->postfix !== null){ - $key = array_search($parameter->postfix, $this->postfixes, true); - if($key === false){ + $key = $postfixIndexes[$parameter->postfix] ?? -1; + if($key === -1){ throw new \InvalidStateException("Postfix '$parameter->postfix' not in postfixes array"); } $type = self::ARG_FLAG_POSTFIX | $key; @@ -310,7 +305,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ } } - private function argTypeToString(int $argtype) : string{ + private function argTypeToString(int $argtype, array $postfixes) : string{ if($argtype & self::ARG_FLAG_VALID){ if($argtype & self::ARG_FLAG_ENUM){ return "stringenum (" . ($argtype & 0xffff) . ")"; @@ -339,7 +334,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ return "command"; } }elseif($argtype & self::ARG_FLAG_POSTFIX){ - $postfix = $this->postfixes[$argtype & 0xffff]; + $postfix = $postfixes[$argtype & 0xffff]; return "int (postfix $postfix)"; }else{ @@ -350,15 +345,22 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ } protected function encodePayload() : void{ - $enumValuesMap = []; - $postfixesMap = []; - $enumMap = []; + /** @var int[] $enumValueIndexes */ + $enumValueIndexes = []; + /** @var int[] $postfixIndexes */ + $postfixIndexes = []; + /** @var int[] $enumIndexes */ + $enumIndexes = []; + /** @var CommandEnum[] $enums */ + $enums = []; foreach($this->commandData as $commandData){ if($commandData->aliases !== null){ - $enumMap[$commandData->aliases->enumName] = $commandData->aliases; + if(!isset($enumIndexes[$commandData->aliases->enumName])){ + $enums[$enumIndexes[$commandData->aliases->enumName] = count($enumIndexes)] = $commandData->aliases; + } foreach($commandData->aliases->enumValues as $str){ - $enumValuesMap[$str] = true; + $enumValueIndexes[$str] = $enumValueIndexes[$str] ?? count($enumValueIndexes); //latest index } } @@ -369,41 +371,39 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ */ foreach($overload as $parameter){ if($parameter->enum !== null){ - $enumMap[$parameter->enum->enumName] = $parameter->enum; + if(!isset($enumIndexes[$parameter->enum->enumName])){ + $enums[$enumIndexes[$parameter->enum->enumName] = count($enumIndexes)] = $parameter->enum; + } foreach($parameter->enum->enumValues as $str){ - $enumValuesMap[$str] = true; + $enumValueIndexes[$str] = $enumValueIndexes[$str] ?? count($enumValueIndexes); } } if($parameter->postfix !== null){ - $postfixesMap[$parameter->postfix] = true; + $postfixIndexes[$parameter->postfix] = $postfixIndexes[$parameter->postfix] ?? count($postfixIndexes); } } } } - $this->enumValues = array_map('\strval', array_keys($enumValuesMap)); //stupid PHP key casting D: - $this->putUnsignedVarInt($this->enumValuesCount = count($this->enumValues)); - foreach($this->enumValues as $enumValue){ - $this->putString($enumValue); + $this->putUnsignedVarInt(count($enumValueIndexes)); + foreach($enumValueIndexes as $enumValue => $index){ + $this->putString((string) $enumValue); //stupid PHP key casting D: } - $this->postfixes = array_map('\strval', array_keys($postfixesMap)); - $this->putUnsignedVarInt(count($this->postfixes)); - foreach($this->postfixes as $postfix){ - $this->putString($postfix); + $this->putUnsignedVarInt(count($postfixIndexes)); + foreach($postfixIndexes as $postfix => $index){ + $this->putString((string) $postfix); //stupid PHP key casting D: } - $this->enums = array_values($enumMap); - $this->enumMap = array_flip(array_keys($enumMap)); - $this->putUnsignedVarInt(count($this->enums)); - foreach($this->enums as $enum){ - $this->putEnum($enum); + $this->putUnsignedVarInt(count($enums)); + foreach($enums as $enum){ + $this->putEnum($enum, $enumValueIndexes); } $this->putUnsignedVarInt(count($this->commandData)); foreach($this->commandData as $data){ - $this->putCommandData($data); + $this->putCommandData($data, $enumIndexes, $postfixIndexes); } $this->putUnsignedVarInt(count($this->softEnums)); From 8afea369191fe7568e3f3419420bde23e1436037 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 Jun 2019 19:35:14 +0100 Subject: [PATCH 0922/3224] Clean up some internal commands protocol handling --- .../network/mcpe/NetworkSession.php | 34 ++++---- .../mcpe/protocol/AvailableCommandsPacket.php | 84 +++++++++---------- .../mcpe/protocol/types/CommandData.php | 67 ++++++++++++++- .../mcpe/protocol/types/CommandEnum.php | 26 +++++- .../mcpe/protocol/types/CommandParameter.php | 27 ++++++ 5 files changed, 174 insertions(+), 64 deletions(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 818eb8a7ca..391944094e 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -668,30 +668,28 @@ class NetworkSession{ continue; } - $data = new CommandData(); - //TODO: commands containing uppercase letters in the name crash 1.9.0 client - $data->commandName = strtolower($command->getName()); - $data->commandDescription = $this->server->getLanguage()->translateString($command->getDescription()); - $data->flags = 0; - $data->permission = 0; - - $parameter = new CommandParameter(); - $parameter->paramName = "args"; - $parameter->paramType = AvailableCommandsPacket::ARG_FLAG_VALID | AvailableCommandsPacket::ARG_TYPE_RAWTEXT; - $parameter->isOptional = true; - $data->overloads[0][0] = $parameter; - + $lname = strtolower($command->getName()); $aliases = $command->getAliases(); + $aliasObj = null; if(!empty($aliases)){ - if(!in_array($data->commandName, $aliases, true)){ + if(!in_array($lname, $aliases, true)){ //work around a client bug which makes the original name not show when aliases are used - $aliases[] = $data->commandName; + $aliases[] = $lname; } - $data->aliases = new CommandEnum(); - $data->aliases->enumName = ucfirst($command->getName()) . "Aliases"; - $data->aliases->enumValues = $aliases; + $aliasObj = new CommandEnum(ucfirst($command->getName()) . "Aliases", $aliases); } + $data = new CommandData( + $lname, //TODO: commands containing uppercase letters in the name crash 1.9.0 client + $this->server->getLanguage()->translateString($command->getDescription()), + 0, + 0, + $aliasObj, + [ + [CommandParameter::standard("args", AvailableCommandsPacket::ARG_TYPE_RAWTEXT, true)] + ] + ); + $pk->commandData[$command->getName()] = $data; } diff --git a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php index 587541f11e..13f087feee 100644 --- a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php @@ -129,8 +129,8 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @throws BinaryDataException */ protected function getEnum(array $enumValueList) : CommandEnum{ - $retval = new CommandEnum(); - $retval->enumName = $this->getString(); + $enumName = $this->getString(); + $enumValues = []; $listSize = count($enumValueList); @@ -140,10 +140,10 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ throw new BadPacketException("Invalid enum value index $index"); } //Get the enum value from the initial pile of mess - $retval->enumValues[] = $enumValueList[$index]; + $enumValues[] = $enumValueList[$index]; } - return $retval; + return new CommandEnum($enumName, $enumValues); } /** @@ -151,15 +151,15 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @throws BinaryDataException */ protected function getSoftEnum() : CommandEnum{ - $retval = new CommandEnum(); - $retval->enumName = $this->getString(); + $enumName = $this->getString(); + $enumValues = []; for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ //Get the enum value from the initial pile of mess - $retval->enumValues[] = $this->getString(); + $enumValues[] = $this->getString(); } - return $retval; + return new CommandEnum($enumName, $enumValues); } /** @@ -167,11 +167,12 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @param string[] $enumValueMap */ protected function putEnum(CommandEnum $enum, array $enumValueMap) : void{ - $this->putString($enum->enumName); + $this->putString($enum->getName()); - $this->putUnsignedVarInt(count($enum->enumValues)); + $values = $enum->getValues(); + $this->putUnsignedVarInt(count($values)); $listSize = count($enumValueMap); - foreach($enum->enumValues as $value){ + foreach($values as $value){ $index = $enumValueMap[$value] ?? -1; if($index === -1){ throw new \InvalidStateException("Enum value '$value' not found"); @@ -181,10 +182,11 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ } protected function putSoftEnum(CommandEnum $enum) : void{ - $this->putString($enum->enumName); + $this->putString($enum->getName()); - $this->putUnsignedVarInt(count($enum->enumValues)); - foreach($enum->enumValues as $value){ + $values = $enum->getValues(); + $this->putUnsignedVarInt(count($values)); + foreach($values as $value){ $this->putString($value); } } @@ -224,12 +226,12 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @throws BinaryDataException */ protected function getCommandData(array $enums, array $postfixes) : CommandData{ - $retval = new CommandData(); - $retval->commandName = $this->getString(); - $retval->commandDescription = $this->getString(); - $retval->flags = $this->getByte(); - $retval->permission = $this->getByte(); - $retval->aliases = $enums[$this->getLInt()] ?? null; + $name = $this->getString(); + $description = $this->getString(); + $flags = $this->getByte(); + $permission = $this->getByte(); + $aliases = $enums[$this->getLInt()] ?? null; + $overloads = []; for($overloadIndex = 0, $overloadCount = $this->getUnsignedVarInt(); $overloadIndex < $overloadCount; ++$overloadIndex){ for($paramIndex = 0, $paramCount = $this->getUnsignedVarInt(); $paramIndex < $paramCount; ++$paramIndex){ @@ -243,23 +245,23 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ $index = ($parameter->paramType & 0xffff); $parameter->enum = $enums[$index] ?? null; if($parameter->enum === null){ - throw new BadPacketException("deserializing $retval->commandName parameter $parameter->paramName: expected enum at $index, but got none"); + throw new BadPacketException("deserializing $name parameter $parameter->paramName: expected enum at $index, but got none"); } }elseif($parameter->paramType & self::ARG_FLAG_POSTFIX){ $index = ($parameter->paramType & 0xffff); $parameter->postfix = $postfixes[$index] ?? null; if($parameter->postfix === null){ - throw new BadPacketException("deserializing $retval->commandName parameter $parameter->paramName: expected postfix at $index, but got none"); + throw new BadPacketException("deserializing $name parameter $parameter->paramName: expected postfix at $index, but got none"); } }elseif(($parameter->paramType & self::ARG_FLAG_VALID) === 0){ - throw new BadPacketException("deserializing $retval->commandName parameter $parameter->paramName: Invalid parameter type 0x" . dechex($parameter->paramType)); + throw new BadPacketException("deserializing $name parameter $parameter->paramName: Invalid parameter type 0x" . dechex($parameter->paramType)); } - $retval->overloads[$overloadIndex][$paramIndex] = $parameter; + $overloads[$overloadIndex][$paramIndex] = $parameter; } } - return $retval; + return new CommandData($name, $description, $flags, $permission, $aliases, $overloads); } /** @@ -268,13 +270,13 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @param int[] $postfixIndexes */ protected function putCommandData(CommandData $data, array $enumIndexes, array $postfixIndexes) : void{ - $this->putString($data->commandName); - $this->putString($data->commandDescription); + $this->putString($data->name); + $this->putString($data->description); $this->putByte($data->flags); $this->putByte($data->permission); if($data->aliases !== null){ - $this->putLInt($enumIndexes[$data->aliases->enumName] ?? -1); + $this->putLInt($enumIndexes[$data->aliases->getName()] ?? -1); }else{ $this->putLInt(-1); } @@ -287,7 +289,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ $this->putString($parameter->paramName); if($parameter->enum !== null){ - $type = self::ARG_FLAG_ENUM | self::ARG_FLAG_VALID | ($enumIndexes[$parameter->enum->enumName] ?? -1); + $type = self::ARG_FLAG_ENUM | self::ARG_FLAG_VALID | ($enumIndexes[$parameter->enum->getName()] ?? -1); }elseif($parameter->postfix !== null){ $key = $postfixIndexes[$parameter->postfix] ?? -1; if($key === -1){ @@ -353,15 +355,18 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ $enumIndexes = []; /** @var CommandEnum[] $enums */ $enums = []; + + $addEnumFn = static function(CommandEnum $enum) use(&$enums, &$enumIndexes, &$enumValueIndexes){ + if(!isset($enumIndexes[$enum->getName()])){ + $enums[$enumIndexes[$enum->getName()] = count($enumIndexes)] = $enum; + } + foreach($enum->getValues() as $str){ + $enumValueIndexes[$str] = $enumValueIndexes[$str] ?? count($enumValueIndexes); //latest index + } + }; foreach($this->commandData as $commandData){ if($commandData->aliases !== null){ - if(!isset($enumIndexes[$commandData->aliases->enumName])){ - $enums[$enumIndexes[$commandData->aliases->enumName] = count($enumIndexes)] = $commandData->aliases; - } - - foreach($commandData->aliases->enumValues as $str){ - $enumValueIndexes[$str] = $enumValueIndexes[$str] ?? count($enumValueIndexes); //latest index - } + $addEnumFn($commandData->aliases); } foreach($commandData->overloads as $overload){ @@ -371,12 +376,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ */ foreach($overload as $parameter){ if($parameter->enum !== null){ - if(!isset($enumIndexes[$parameter->enum->enumName])){ - $enums[$enumIndexes[$parameter->enum->enumName] = count($enumIndexes)] = $parameter->enum; - } - foreach($parameter->enum->enumValues as $str){ - $enumValueIndexes[$str] = $enumValueIndexes[$str] ?? count($enumValueIndexes); - } + $addEnumFn($parameter->enum); } if($parameter->postfix !== null){ diff --git a/src/pocketmine/network/mcpe/protocol/types/CommandData.php b/src/pocketmine/network/mcpe/protocol/types/CommandData.php index cf98b90fc3..95bab22534 100644 --- a/src/pocketmine/network/mcpe/protocol/types/CommandData.php +++ b/src/pocketmine/network/mcpe/protocol/types/CommandData.php @@ -25,9 +25,9 @@ namespace pocketmine\network\mcpe\protocol\types; class CommandData{ /** @var string */ - public $commandName; + public $name; /** @var string */ - public $commandDescription; + public $description; /** @var int */ public $flags; /** @var int */ @@ -37,4 +37,67 @@ class CommandData{ /** @var CommandParameter[][] */ public $overloads = []; + /** + * @param string $name + * @param string $description + * @param int $flags + * @param int $permission + * @param CommandEnum|null $aliases + * @param CommandParameter[][] $overloads + */ + public function __construct(string $name, string $description, int $flags, int $permission, ?CommandEnum $aliases, array $overloads){ + (function(array ...$overloads){ + foreach($overloads as $overload){ + (function(CommandParameter ...$parameters){})(...$overload); + } + })(...$overloads); + $this->name = $name; + $this->description = $description; + $this->flags = $flags; + $this->permission = $permission; + $this->aliases = $aliases; + $this->overloads = $overloads; + } + + /** + * @return string + */ + public function getName() : string{ + return $this->name; + } + + /** + * @return string + */ + public function getDescription() : string{ + return $this->description; + } + + /** + * @return int + */ + public function getFlags() : int{ + return $this->flags; + } + + /** + * @return int + */ + public function getPermission() : int{ + return $this->permission; + } + + /** + * @return CommandEnum|null + */ + public function getAliases() : ?CommandEnum{ + return $this->aliases; + } + + /** + * @return CommandParameter[][] + */ + public function getOverloads() : array{ + return $this->overloads; + } } diff --git a/src/pocketmine/network/mcpe/protocol/types/CommandEnum.php b/src/pocketmine/network/mcpe/protocol/types/CommandEnum.php index e6621c7a4d..02597e90e5 100644 --- a/src/pocketmine/network/mcpe/protocol/types/CommandEnum.php +++ b/src/pocketmine/network/mcpe/protocol/types/CommandEnum.php @@ -25,8 +25,30 @@ namespace pocketmine\network\mcpe\protocol\types; class CommandEnum{ /** @var string */ - public $enumName; + private $enumName; /** @var string[] */ - public $enumValues = []; + private $enumValues = []; + /** + * @param string $enumName + * @param string[] $enumValues + */ + public function __construct(string $enumName, array $enumValues){ + $this->enumName = $enumName; + $this->enumValues = $enumValues; + } + + /** + * @return string + */ + public function getName() : string{ + return $this->enumName; + } + + /** + * @return string[] + */ + public function getValues() : array{ + return $this->enumValues; + } } diff --git a/src/pocketmine/network/mcpe/protocol/types/CommandParameter.php b/src/pocketmine/network/mcpe/protocol/types/CommandParameter.php index 2c26ac9bf0..d19c7b9a81 100644 --- a/src/pocketmine/network/mcpe/protocol/types/CommandParameter.php +++ b/src/pocketmine/network/mcpe/protocol/types/CommandParameter.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types; +use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; + class CommandParameter{ /** @var string */ public $paramName; @@ -36,4 +38,29 @@ class CommandParameter{ public $enum; /** @var string|null */ public $postfix; + + private static function baseline(string $name, int $type, bool $optional) : self{ + $result = new self; + $result->paramName = $name; + $result->paramType = $type; + $result->isOptional = $optional; + return $result; + } + + public static function standard(string $name, int $type, bool $optional = false) : self{ + return self::baseline($name, AvailableCommandsPacket::ARG_FLAG_VALID | $type, $optional); + } + + public static function postfixed(string $name, string $postfix, bool $optional = false) : self{ + $result = self::baseline($name, AvailableCommandsPacket::ARG_FLAG_POSTFIX, $optional); + $result->postfix = $postfix; + return $result; + } + + public static function enum(string $name, CommandEnum $enum, int $flags, bool $optional = false) : self{ + $result = self::baseline($name, AvailableCommandsPacket::ARG_FLAG_ENUM | AvailableCommandsPacket::ARG_FLAG_VALID, $optional); + $result->enum = $enum; + $result->byte1 = $flags; + return $result; + } } From 31f0576725a114f73f2bdf4b86d623c03391b30d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 Jun 2019 19:47:51 +0100 Subject: [PATCH 0923/3224] Server: remove useless constructor assignment --- src/pocketmine/Server.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 1e407604cb..049ac2698a 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1309,8 +1309,6 @@ class Server{ $this->properties->save(); } - $this->tickCounter = 0; - $this->logger->info($this->getLanguage()->translateString("pocketmine.server.defaultGameMode", [$this->getGamemode()->getTranslationKey()])); $this->logger->info($this->getLanguage()->translateString("pocketmine.server.startFinished", [round(microtime(true) - \pocketmine\START_TIME, 3)])); From e95d81e04b8e0c015c85609db4196008a3792aa1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 Jun 2019 19:50:27 +0100 Subject: [PATCH 0924/3224] Server: fix possible comparison bug in load orders --- src/pocketmine/Server.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 049ac2698a..7184bc949a 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1542,7 +1542,7 @@ class Server{ */ public function enablePlugins(PluginLoadOrder $type) : void{ foreach($this->pluginManager->getPlugins() as $plugin){ - if(!$plugin->isEnabled() and $plugin->getDescription()->getOrder() === $type){ + if(!$plugin->isEnabled() and $plugin->getDescription()->getOrder()->equals($type)){ $this->pluginManager->enablePlugin($plugin); } } From 6bd67730eb9c2d7108baf88337caa4b1477ffac5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Jun 2019 14:00:26 +0100 Subject: [PATCH 0925/3224] AsyncWorker: use a shorter name on logs --- src/pocketmine/scheduler/AsyncWorker.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/scheduler/AsyncWorker.php b/src/pocketmine/scheduler/AsyncWorker.php index c751a25291..86c2a76935 100644 --- a/src/pocketmine/scheduler/AsyncWorker.php +++ b/src/pocketmine/scheduler/AsyncWorker.php @@ -70,7 +70,7 @@ class AsyncWorker extends Worker{ } public function getThreadName() : string{ - return "Asynchronous Worker #" . $this->id; + return "AsyncWorker#" . $this->id; } public function getAsyncWorkerId() : int{ From 7ba1dd32420b597307cac0de8b81675b35bd93ee Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Jun 2019 17:24:17 +0100 Subject: [PATCH 0926/3224] BaseInventory: remove setSize() no inventory is designed to deal with this. Changing this can break transactions, specialized logic like double chest / furnace and more. --- src/pocketmine/inventory/BaseInventory.php | 10 ---------- src/pocketmine/inventory/CraftingGrid.php | 4 ---- src/pocketmine/inventory/PlayerCursorInventory.php | 4 ---- 3 files changed, 18 deletions(-) diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index 09dbd24c25..6328360da3 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -62,16 +62,6 @@ abstract class BaseInventory implements Inventory{ return $this->slots->getSize(); } - /** - * Sets the new size of the inventory. - * WARNING: If the size is smaller, any items past the new size will be lost. - * - * @param int $size - */ - public function setSize(int $size) : void{ - $this->slots->setSize($size); - } - public function getMaxStackSize() : int{ return $this->maxStackSize; } diff --git a/src/pocketmine/inventory/CraftingGrid.php b/src/pocketmine/inventory/CraftingGrid.php index 2cdabff19a..bd29d8c8b4 100644 --- a/src/pocketmine/inventory/CraftingGrid.php +++ b/src/pocketmine/inventory/CraftingGrid.php @@ -57,10 +57,6 @@ class CraftingGrid extends BaseInventory{ return $this->gridWidth; } - public function setSize(int $size) : void{ - throw new \BadMethodCallException("Cannot change the size of a crafting grid"); - } - public function setItem(int $index, Item $item, bool $send = true) : void{ parent::setItem($index, $item, $send); $this->seekRecipeBounds(); diff --git a/src/pocketmine/inventory/PlayerCursorInventory.php b/src/pocketmine/inventory/PlayerCursorInventory.php index e760493f2f..a016d3b4f2 100644 --- a/src/pocketmine/inventory/PlayerCursorInventory.php +++ b/src/pocketmine/inventory/PlayerCursorInventory.php @@ -34,10 +34,6 @@ class PlayerCursorInventory extends BaseInventory{ parent::__construct(1); } - public function setSize(int $size) : void{ - throw new \BadMethodCallException("Cursor can only carry one item at a time"); - } - /** * This override is here for documentation and code completion purposes only. * @return Player From 8551d1e282c1747f2361efbdbd764c42627694a7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Jun 2019 18:14:11 +0100 Subject: [PATCH 0927/3224] Remove Inventory->sendSlot() and Inventory->sendContents() the plan is to remove this from inventory entirely and use listeners for this. --- src/pocketmine/inventory/BaseInventory.php | 35 ++++--------------- .../inventory/ContainerInventory.php | 2 +- src/pocketmine/inventory/Inventory.php | 11 ------ src/pocketmine/inventory/PlayerInventory.php | 4 +-- .../transaction/InventoryTransaction.php | 2 +- .../transaction/action/SlotChangeAction.php | 9 +++-- .../mcpe/handler/InGameSessionHandler.php | 2 +- 7 files changed, 15 insertions(+), 50 deletions(-) diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index 6328360da3..204361799a 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -116,7 +116,9 @@ abstract class BaseInventory implements Inventory{ } if($send){ - $this->sendContents($this->getViewers()); + foreach($this->getViewers() as $viewer){ + $viewer->getNetworkSession()->syncInventoryContents($this); + } } } @@ -380,34 +382,9 @@ abstract class BaseInventory implements Inventory{ $listener->onSlotChange($this, $index); } if($send){ - $this->sendSlot($index, $this->getViewers()); - } - } - - /** - * @param Player|Player[] $target - */ - public function sendContents($target) : void{ - if($target instanceof Player){ - $target = [$target]; - } - - foreach($target as $player){ - $player->getNetworkSession()->syncInventoryContents($this); - } - } - - /** - * @param int $index - * @param Player|Player[] $target - */ - public function sendSlot(int $index, $target) : void{ - if($target instanceof Player){ - $target = [$target]; - } - - foreach($target as $player){ - $player->getNetworkSession()->syncInventorySlot($this, $index); + foreach($this->viewers as $viewer){ + $viewer->getNetworkSession()->syncInventorySlot($this, $index); + } } } diff --git a/src/pocketmine/inventory/ContainerInventory.php b/src/pocketmine/inventory/ContainerInventory.php index bc827dd760..ee8dfe7e00 100644 --- a/src/pocketmine/inventory/ContainerInventory.php +++ b/src/pocketmine/inventory/ContainerInventory.php @@ -49,7 +49,7 @@ abstract class ContainerInventory extends BaseInventory{ $who->sendDataPacket(ContainerOpenPacket::blockInv($windowId, $this->getNetworkType(), $holder->getFloorX(), $holder->getFloorY(), $holder->getFloorZ())); } - $this->sendContents($who); + $who->getNetworkSession()->syncInventoryContents($this); } protected function onClose(Player $who) : void{ diff --git a/src/pocketmine/inventory/Inventory.php b/src/pocketmine/inventory/Inventory.php index 8260b5943b..d393a3e25f 100644 --- a/src/pocketmine/inventory/Inventory.php +++ b/src/pocketmine/inventory/Inventory.php @@ -107,17 +107,6 @@ interface Inventory{ */ public function setContents(array $items, bool $send = true) : void; - /** - * @param Player|Player[] $target - */ - public function sendContents($target) : void; - - /** - * @param int $index - * @param Player|Player[] $target - */ - public function sendSlot(int $index, $target) : void; - /** * Checks if the inventory contains any Item with the same material data. * It will check id, amount, and metadata (if not null) diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index 206ad8660a..909fd3ff2e 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -137,12 +137,12 @@ class PlayerInventory extends BaseInventory{ if(!is_array($target)){ $target->sendDataPacket($pk); if($target === $this->getHolder()){ - $this->sendSlot($this->getHeldItemIndex(), $target); + $target->getNetworkSession()->syncInventorySlot($this, $this->getHeldItemIndex()); } }else{ $this->getHolder()->getWorld()->getServer()->broadcastPacket($target, $pk); if(in_array($this->getHolder(), $target, true)){ - $this->sendSlot($this->getHeldItemIndex(), $this->getHolder()); + $target->getNetworkSession()->syncInventorySlot($this, $this->getHeldItemIndex()); } } } diff --git a/src/pocketmine/inventory/transaction/InventoryTransaction.php b/src/pocketmine/inventory/transaction/InventoryTransaction.php index d57a9fa1f0..02158c22b3 100644 --- a/src/pocketmine/inventory/transaction/InventoryTransaction.php +++ b/src/pocketmine/inventory/transaction/InventoryTransaction.php @@ -282,7 +282,7 @@ class InventoryTransaction{ protected function sendInventories() : void{ foreach($this->inventories as $inventory){ - $inventory->sendContents($this->source); + $this->source->getNetworkSession()->syncInventoryContents($inventory); } } diff --git a/src/pocketmine/inventory/transaction/action/SlotChangeAction.php b/src/pocketmine/inventory/transaction/action/SlotChangeAction.php index 670c4cdb51..8cf2f5f4e3 100644 --- a/src/pocketmine/inventory/transaction/action/SlotChangeAction.php +++ b/src/pocketmine/inventory/transaction/action/SlotChangeAction.php @@ -27,7 +27,6 @@ use pocketmine\inventory\Inventory; use pocketmine\inventory\transaction\InventoryTransaction; use pocketmine\item\Item; use pocketmine\Player; -use function spl_object_id; /** * Represents an action causing a change in an inventory slot. @@ -110,9 +109,9 @@ class SlotChangeAction extends InventoryAction{ * @param Player $source */ public function onExecuteSuccess(Player $source) : void{ - $viewers = $this->inventory->getViewers(); - unset($viewers[spl_object_id($source)]); - $this->inventory->sendSlot($this->inventorySlot, $viewers); + foreach($this->inventory->getViewers() as $viewer){ + $viewer->getNetworkSession()->syncInventorySlot($this->inventory, $this->inventorySlot); + } } /** @@ -121,6 +120,6 @@ class SlotChangeAction extends InventoryAction{ * @param Player $source */ public function onExecuteFail(Player $source) : void{ - $this->inventory->sendSlot($this->inventorySlot, $source); + $source->getNetworkSession()->syncInventorySlot($this->inventory, $this->inventorySlot); } } diff --git a/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php b/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php index 6e1bd11c31..9323ccb0d5 100644 --- a/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php @@ -339,7 +339,7 @@ class InGameSessionHandler extends SessionHandler{ switch($data->getActionType()){ case ReleaseItemTransactionData::ACTION_RELEASE: if(!$this->player->releaseHeldItem()){ - $this->player->getInventory()->sendContents($this->player); + $this->session->syncInventoryContents($this->player->getInventory()); } return true; case ReleaseItemTransactionData::ACTION_CONSUME: From 44be2179c404677a0dca288de7cc5a21dddcb15a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Jun 2019 18:31:25 +0100 Subject: [PATCH 0928/3224] SlotChangeAction: fix feedback loop --- .../inventory/transaction/action/SlotChangeAction.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/inventory/transaction/action/SlotChangeAction.php b/src/pocketmine/inventory/transaction/action/SlotChangeAction.php index 8cf2f5f4e3..9bb9d5f9c0 100644 --- a/src/pocketmine/inventory/transaction/action/SlotChangeAction.php +++ b/src/pocketmine/inventory/transaction/action/SlotChangeAction.php @@ -110,7 +110,9 @@ class SlotChangeAction extends InventoryAction{ */ public function onExecuteSuccess(Player $source) : void{ foreach($this->inventory->getViewers() as $viewer){ - $viewer->getNetworkSession()->syncInventorySlot($this->inventory, $this->inventorySlot); + if($viewer !== $source){ + $viewer->getNetworkSession()->syncInventorySlot($this->inventory, $this->inventorySlot); + } } } From da4c646d275e855290805ca6808a5fdc2a0c9f58 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Jun 2019 18:35:05 +0100 Subject: [PATCH 0929/3224] Simplify InventoryAction implementation none of these action types are able to fail now. --- .../transaction/InventoryTransaction.php | 6 +---- .../action/CreativeInventoryAction.php | 12 +--------- .../transaction/action/DropItemAction.php | 13 +--------- .../transaction/action/InventoryAction.php | 24 +++---------------- .../transaction/action/SlotChangeAction.php | 22 +---------------- 5 files changed, 7 insertions(+), 70 deletions(-) diff --git a/src/pocketmine/inventory/transaction/InventoryTransaction.php b/src/pocketmine/inventory/transaction/InventoryTransaction.php index 02158c22b3..199e8aa275 100644 --- a/src/pocketmine/inventory/transaction/InventoryTransaction.php +++ b/src/pocketmine/inventory/transaction/InventoryTransaction.php @@ -321,11 +321,7 @@ class InventoryTransaction{ } foreach($this->actions as $action){ - if($action->execute($this->source)){ - $action->onExecuteSuccess($this->source); - }else{ - $action->onExecuteFail($this->source); - } + $action->execute($this->source); } $this->hasExecuted = true; diff --git a/src/pocketmine/inventory/transaction/action/CreativeInventoryAction.php b/src/pocketmine/inventory/transaction/action/CreativeInventoryAction.php index 7c399bc95a..139dda1938 100644 --- a/src/pocketmine/inventory/transaction/action/CreativeInventoryAction.php +++ b/src/pocketmine/inventory/transaction/action/CreativeInventoryAction.php @@ -68,18 +68,8 @@ class CreativeInventoryAction extends InventoryAction{ * No need to do anything extra here: this type just provides a place for items to disappear or appear from. * * @param Player $source - * - * @return bool */ - public function execute(Player $source) : bool{ - return true; - } - - public function onExecuteSuccess(Player $source) : void{ - - } - - public function onExecuteFail(Player $source) : void{ + public function execute(Player $source) : void{ } } diff --git a/src/pocketmine/inventory/transaction/action/DropItemAction.php b/src/pocketmine/inventory/transaction/action/DropItemAction.php index 692af129f5..3ffab2a728 100644 --- a/src/pocketmine/inventory/transaction/action/DropItemAction.php +++ b/src/pocketmine/inventory/transaction/action/DropItemAction.php @@ -55,19 +55,8 @@ class DropItemAction extends InventoryAction{ * Drops the target item in front of the player. * * @param Player $source - * - * @return bool */ - public function execute(Player $source) : bool{ + public function execute(Player $source) : void{ $source->dropItem($this->targetItem); - return true; - } - - public function onExecuteSuccess(Player $source) : void{ - - } - - public function onExecuteFail(Player $source) : void{ - } } diff --git a/src/pocketmine/inventory/transaction/action/InventoryAction.php b/src/pocketmine/inventory/transaction/action/InventoryAction.php index 7ca2a2afaa..326dbe4400 100644 --- a/src/pocketmine/inventory/transaction/action/InventoryAction.php +++ b/src/pocketmine/inventory/transaction/action/InventoryAction.php @@ -88,28 +88,10 @@ abstract class InventoryAction{ } /** - * Performs actions needed to complete the inventory-action server-side. Returns if it was successful. Will return - * false if plugins cancelled events. This will only be called if the transaction which it is part of is considered - * valid. - * - * @param Player $source - * - * @return bool - */ - abstract public function execute(Player $source) : bool; - - /** - * Performs additional actions when this inventory-action completed successfully. + * Performs actions needed to complete the inventory-action server-side. This will only be called if the transaction + * which it is part of is considered valid. * * @param Player $source */ - abstract public function onExecuteSuccess(Player $source) : void; - - /** - * Performs additional actions when this inventory-action did not complete successfully. - * - * @param Player $source - */ - abstract public function onExecuteFail(Player $source) : void; - + abstract public function execute(Player $source) : void; } diff --git a/src/pocketmine/inventory/transaction/action/SlotChangeAction.php b/src/pocketmine/inventory/transaction/action/SlotChangeAction.php index 9bb9d5f9c0..8aaa70e158 100644 --- a/src/pocketmine/inventory/transaction/action/SlotChangeAction.php +++ b/src/pocketmine/inventory/transaction/action/SlotChangeAction.php @@ -95,33 +95,13 @@ class SlotChangeAction extends InventoryAction{ * Sets the item into the target inventory. * * @param Player $source - * - * @return bool */ - public function execute(Player $source) : bool{ + public function execute(Player $source) : void{ $this->inventory->setItem($this->inventorySlot, $this->targetItem, false); - return true; - } - - /** - * Sends slot changes to other viewers of the inventory. This will not send any change back to the source Player. - * - * @param Player $source - */ - public function onExecuteSuccess(Player $source) : void{ foreach($this->inventory->getViewers() as $viewer){ if($viewer !== $source){ $viewer->getNetworkSession()->syncInventorySlot($this->inventory, $this->inventorySlot); } } } - - /** - * Sends the original slot contents to the source player to revert the action. - * - * @param Player $source - */ - public function onExecuteFail(Player $source) : void{ - $source->getNetworkSession()->syncInventorySlot($this->inventory, $this->inventorySlot); - } } From 9e9de1e8ba05098b0106cae7d7e71046c4e7b2f7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 13 Jun 2019 19:52:53 +0100 Subject: [PATCH 0930/3224] Log a debug message when receiving a mismatch transaction --- src/pocketmine/network/mcpe/handler/InGameSessionHandler.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php b/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php index 9323ccb0d5..76eb636c4f 100644 --- a/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php @@ -167,6 +167,7 @@ class InGameSessionHandler extends SessionHandler{ if($packet->trData instanceof NormalTransactionData){ $result = $this->handleNormalTransaction($packet->trData); }elseif($packet->trData instanceof MismatchTransactionData){ + $this->session->getLogger()->debug("Mismatch transaction received"); $this->session->syncAllInventoryContents(); $result = true; }elseif($packet->trData instanceof UseItemTransactionData){ From 211836274f7008b83cab6f5ec40be539bff159d7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 14 Jun 2019 17:47:39 +0100 Subject: [PATCH 0931/3224] World: remove redundant checks when entities are added and removed which are savable, the dirty flag is set anyway, so these checks aren't needed. --- src/pocketmine/world/World.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 77cbbab638..4dd4088a21 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -1056,7 +1056,7 @@ class World implements ChunkManager, Metadatable{ $this->timings->syncChunkSaveTimer->startTiming(); try{ foreach($this->chunks as $chunk){ - if(($chunk->hasChanged() or count($chunk->getTiles()) > 0 or count($chunk->getSavableEntities()) > 0) and $chunk->isGenerated()){ + if($chunk->hasChanged() and $chunk->isGenerated()){ $this->provider->saveChunk($chunk); $chunk->setChanged(false); } @@ -2584,14 +2584,12 @@ class World implements ChunkManager, Metadatable{ return false; } - if($trySave and $this->getAutoSave() and $chunk->isGenerated()){ - if($chunk->hasChanged() or count($chunk->getTiles()) > 0 or count($chunk->getSavableEntities()) > 0){ - $this->timings->syncChunkSaveTimer->startTiming(); - try{ - $this->provider->saveChunk($chunk); - }finally{ - $this->timings->syncChunkSaveTimer->stopTiming(); - } + if($trySave and $this->getAutoSave() and $chunk->isGenerated() and $chunk->hasChanged()){ + $this->timings->syncChunkSaveTimer->startTiming(); + try{ + $this->provider->saveChunk($chunk); + }finally{ + $this->timings->syncChunkSaveTimer->stopTiming(); } } From c8eefddfc0d47f7bb9e02be2ea5ce5f09d0ee5a7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 14 Jun 2019 17:59:00 +0100 Subject: [PATCH 0932/3224] Chunk: fix tiles not being loaded from NBT in some cases --- src/pocketmine/world/format/Chunk.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/world/format/Chunk.php b/src/pocketmine/world/format/Chunk.php index 89c0c1eaf0..3adc91b74a 100644 --- a/src/pocketmine/world/format/Chunk.php +++ b/src/pocketmine/world/format/Chunk.php @@ -598,8 +598,11 @@ class Chunk{ } } } - $world->timings->syncChunkLoadEntitiesTimer->stopTiming(); + $this->NBTentities = null; + $world->timings->syncChunkLoadEntitiesTimer->stopTiming(); + } + if($this->NBTtiles !== null){ $world->timings->syncChunkLoadTileEntitiesTimer->startTiming(); foreach($this->NBTtiles as $nbt){ if($nbt instanceof CompoundTag){ @@ -613,10 +616,8 @@ class Chunk{ } } - $world->timings->syncChunkLoadTileEntitiesTimer->stopTiming(); - - $this->NBTentities = null; $this->NBTtiles = null; + $world->timings->syncChunkLoadTileEntitiesTimer->stopTiming(); } $this->hasChanged = $changed; From 722da5e88d626321efffc0d96926a285f700d7fe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 14 Jun 2019 18:00:37 +0100 Subject: [PATCH 0933/3224] Simplify hasChanged handling for chunk init we always want chunks to be saved if they have tiles or entities --- src/pocketmine/world/format/Chunk.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/world/format/Chunk.php b/src/pocketmine/world/format/Chunk.php index 3adc91b74a..5f78233d13 100644 --- a/src/pocketmine/world/format/Chunk.php +++ b/src/pocketmine/world/format/Chunk.php @@ -579,8 +579,8 @@ class Chunk{ */ public function initChunk(World $world) : void{ if(!$this->isInit){ - $changed = false; if($this->NBTentities !== null){ + $this->hasChanged = true; $world->timings->syncChunkLoadEntitiesTimer->startTiming(); foreach($this->NBTentities as $nbt){ if($nbt instanceof CompoundTag){ @@ -588,12 +588,10 @@ class Chunk{ $entity = EntityFactory::createFromData($world, $nbt); if(!($entity instanceof Entity)){ $world->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown entity type " . $nbt->getString("id", $nbt->getString("identifier", "", true), true)); - $changed = true; continue; } }catch(\Exception $t){ //TODO: this shouldn't be here $world->getLogger()->logException($t); - $changed = true; continue; } } @@ -603,6 +601,7 @@ class Chunk{ $world->timings->syncChunkLoadEntitiesTimer->stopTiming(); } if($this->NBTtiles !== null){ + $this->hasChanged = true; $world->timings->syncChunkLoadTileEntitiesTimer->startTiming(); foreach($this->NBTtiles as $nbt){ if($nbt instanceof CompoundTag){ @@ -610,7 +609,6 @@ class Chunk{ $world->addTile($tile); }else{ $world->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown tile entity type " . $nbt->getString("id", "", true)); - $changed = true; continue; } } @@ -620,8 +618,6 @@ class Chunk{ $world->timings->syncChunkLoadTileEntitiesTimer->stopTiming(); } - $this->hasChanged = $changed; - $this->isInit = true; } } From 92035ac2ec9d8c7ddc9fb8037cb6d7389eb0f445 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 14 Jun 2019 18:07:13 +0100 Subject: [PATCH 0934/3224] Chunk: drop premature optimizations --- src/pocketmine/world/format/Chunk.php | 75 ++++++++++++--------------- 1 file changed, 32 insertions(+), 43 deletions(-) diff --git a/src/pocketmine/world/format/Chunk.php b/src/pocketmine/world/format/Chunk.php index 5f78233d13..d7af0f3142 100644 --- a/src/pocketmine/world/format/Chunk.php +++ b/src/pocketmine/world/format/Chunk.php @@ -64,9 +64,6 @@ class Chunk{ /** @var bool */ protected $hasChanged = false; - /** @var bool */ - protected $isInit = false; - /** @var bool */ protected $lightPopulated = false; /** @var bool */ @@ -464,7 +461,7 @@ class Chunk{ throw new \InvalidArgumentException("Attempted to add a garbage closed Entity to a chunk"); } $this->entities[$entity->getId()] = $entity; - if(!($entity instanceof Player) and $this->isInit){ + if(!($entity instanceof Player)){ $this->hasChanged = true; } } @@ -474,7 +471,7 @@ class Chunk{ */ public function removeEntity(Entity $entity) : void{ unset($this->entities[$entity->getId()]); - if(!($entity instanceof Player) and $this->isInit){ + if(!($entity instanceof Player)){ $this->hasChanged = true; } } @@ -491,9 +488,7 @@ class Chunk{ $this->tiles[$index]->close(); } $this->tiles[$index] = $tile; - if($this->isInit){ - $this->hasChanged = true; - } + $this->hasChanged = true; } /** @@ -501,9 +496,7 @@ class Chunk{ */ public function removeTile(Tile $tile) : void{ unset($this->tiles[Chunk::blockHash($tile->x, $tile->y, $tile->z)]); - if($this->isInit){ - $this->hasChanged = true; - } + $this->hasChanged = true; } /** @@ -578,47 +571,43 @@ class Chunk{ * @param World $world */ public function initChunk(World $world) : void{ - if(!$this->isInit){ - if($this->NBTentities !== null){ - $this->hasChanged = true; - $world->timings->syncChunkLoadEntitiesTimer->startTiming(); - foreach($this->NBTentities as $nbt){ - if($nbt instanceof CompoundTag){ - try{ - $entity = EntityFactory::createFromData($world, $nbt); - if(!($entity instanceof Entity)){ - $world->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown entity type " . $nbt->getString("id", $nbt->getString("identifier", "", true), true)); - continue; - } - }catch(\Exception $t){ //TODO: this shouldn't be here - $world->getLogger()->logException($t); + if($this->NBTentities !== null){ + $this->hasChanged = true; + $world->timings->syncChunkLoadEntitiesTimer->startTiming(); + foreach($this->NBTentities as $nbt){ + if($nbt instanceof CompoundTag){ + try{ + $entity = EntityFactory::createFromData($world, $nbt); + if(!($entity instanceof Entity)){ + $world->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown entity type " . $nbt->getString("id", $nbt->getString("identifier", "", true), true)); continue; } + }catch(\Exception $t){ //TODO: this shouldn't be here + $world->getLogger()->logException($t); + continue; } } - - $this->NBTentities = null; - $world->timings->syncChunkLoadEntitiesTimer->stopTiming(); } - if($this->NBTtiles !== null){ - $this->hasChanged = true; - $world->timings->syncChunkLoadTileEntitiesTimer->startTiming(); - foreach($this->NBTtiles as $nbt){ - if($nbt instanceof CompoundTag){ - if(($tile = TileFactory::createFromData($world, $nbt)) !== null){ - $world->addTile($tile); - }else{ - $world->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown tile entity type " . $nbt->getString("id", "", true)); - continue; - } + + $this->NBTentities = null; + $world->timings->syncChunkLoadEntitiesTimer->stopTiming(); + } + if($this->NBTtiles !== null){ + $this->hasChanged = true; + $world->timings->syncChunkLoadTileEntitiesTimer->startTiming(); + foreach($this->NBTtiles as $nbt){ + if($nbt instanceof CompoundTag){ + if(($tile = TileFactory::createFromData($world, $nbt)) !== null){ + $world->addTile($tile); + }else{ + $world->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown tile entity type " . $nbt->getString("id", "", true)); + continue; } } - - $this->NBTtiles = null; - $world->timings->syncChunkLoadTileEntitiesTimer->stopTiming(); } - $this->isInit = true; + $this->NBTtiles = null; + $world->timings->syncChunkLoadTileEntitiesTimer->stopTiming(); } } From 08de657c8db5dc39006835abd78341b941a5b0b7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 14 Jun 2019 18:19:46 +0100 Subject: [PATCH 0935/3224] Extract FastChunkSerializer unit from Chunk this functionality doesn't directly pertain to Chunk functionality. --- src/pocketmine/world/format/Chunk.php | 113 ------------- .../world/format/io/FastChunkSerializer.php | 157 ++++++++++++++++++ .../world/generator/PopulationTask.php | 17 +- .../world/light/LightPopulationTask.php | 9 +- 4 files changed, 171 insertions(+), 125 deletions(-) create mode 100644 src/pocketmine/world/format/io/FastChunkSerializer.php diff --git a/src/pocketmine/world/format/Chunk.php b/src/pocketmine/world/format/Chunk.php index d7af0f3142..7fccb58edc 100644 --- a/src/pocketmine/world/format/Chunk.php +++ b/src/pocketmine/world/format/Chunk.php @@ -37,12 +37,10 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; use pocketmine\Player; -use pocketmine\utils\BinaryStream; use pocketmine\world\World; use function array_fill; use function array_filter; use function array_map; -use function array_values; use function assert; use function chr; use function count; @@ -50,7 +48,6 @@ use function ord; use function pack; use function str_repeat; use function strlen; -use function unpack; class Chunk{ @@ -766,116 +763,6 @@ class Chunk{ return $stream->getBuffer(); } - /** - * Fast-serializes the chunk for passing between threads - * TODO: tiles and entities - * - * @return string - */ - public function fastSerialize() : string{ - $stream = new BinaryStream(); - $stream->putInt($this->x); - $stream->putInt($this->z); - $stream->putByte(($this->lightPopulated ? 4 : 0) | ($this->terrainPopulated ? 2 : 0) | ($this->terrainGenerated ? 1 : 0)); - if($this->terrainGenerated){ - //subchunks - $count = 0; - $subStream = new BinaryStream(); - foreach($this->subChunks as $y => $subChunk){ - if($subChunk instanceof EmptySubChunk){ - continue; - } - ++$count; - - $subStream->putByte($y); - $layers = $subChunk->getBlockLayers(); - $subStream->putByte(count($subChunk->getBlockLayers())); - foreach($layers as $blocks){ - $wordArray = $blocks->getWordArray(); - $palette = $blocks->getPalette(); - - $subStream->putByte($blocks->getBitsPerBlock()); - $subStream->put($wordArray); - $subStream->putInt(count($palette)); - foreach($palette as $p){ - $subStream->putInt($p); - } - } - - if($this->lightPopulated){ - $subStream->put($subChunk->getBlockSkyLightArray()); - $subStream->put($subChunk->getBlockLightArray()); - } - } - $stream->putByte($count); - $stream->put($subStream->getBuffer()); - - //biomes - $stream->put($this->biomeIds); - if($this->lightPopulated){ - $stream->put(pack("v*", ...$this->heightMap)); - } - } - - return $stream->getBuffer(); - } - - /** - * Deserializes a fast-serialized chunk - * - * @param string $data - * - * @return Chunk - */ - public static function fastDeserialize(string $data) : Chunk{ - $stream = new BinaryStream($data); - - $x = $stream->getInt(); - $z = $stream->getInt(); - $flags = $stream->getByte(); - $lightPopulated = (bool) ($flags & 4); - $terrainPopulated = (bool) ($flags & 2); - $terrainGenerated = (bool) ($flags & 1); - - $subChunks = []; - $biomeIds = ""; - $heightMap = []; - if($terrainGenerated){ - $count = $stream->getByte(); - for($subCount = 0; $subCount < $count; ++$subCount){ - $y = $stream->getByte(); - - /** @var PalettedBlockArray[] $layers */ - $layers = []; - for($i = 0, $layerCount = $stream->getByte(); $i < $layerCount; ++$i){ - $bitsPerBlock = $stream->getByte(); - $words = $stream->get(PalettedBlockArray::getExpectedWordArraySize($bitsPerBlock)); - $palette = []; - for($k = 0, $paletteSize = $stream->getInt(); $k < $paletteSize; ++$k){ - $palette[] = $stream->getInt(); - } - - $layers[] = PalettedBlockArray::fromData($bitsPerBlock, $words, $palette); - } - $subChunks[$y] = new SubChunk( - $layers, $lightPopulated ? $stream->get(2048) : "", $lightPopulated ? $stream->get(2048) : "" //blocklight - ); - } - - $biomeIds = $stream->get(256); - if($lightPopulated){ - $heightMap = array_values(unpack("v*", $stream->get(512))); - } - } - - $chunk = new Chunk($x, $z, $subChunks, null, null, $biomeIds, $heightMap); - $chunk->setGenerated($terrainGenerated); - $chunk->setPopulated($terrainPopulated); - $chunk->setLightPopulated($lightPopulated); - - return $chunk; - } - /** * Hashes the given chunk block coordinates into a single integer. * diff --git a/src/pocketmine/world/format/io/FastChunkSerializer.php b/src/pocketmine/world/format/io/FastChunkSerializer.php new file mode 100644 index 0000000000..b86b054468 --- /dev/null +++ b/src/pocketmine/world/format/io/FastChunkSerializer.php @@ -0,0 +1,157 @@ +putInt($chunk->getX()); + $stream->putInt($chunk->getZ()); + $stream->putByte(($chunk->isLightPopulated() ? 4 : 0) | ($chunk->isPopulated() ? 2 : 0) | ($chunk->isGenerated() ? 1 : 0)); + if($chunk->isGenerated()){ + //subchunks + $count = 0; + $subStream = new BinaryStream(); + foreach($chunk->getSubChunks() as $y => $subChunk){ + if($subChunk instanceof EmptySubChunk){ + continue; + } + ++$count; + + $subStream->putByte($y); + $layers = $subChunk->getBlockLayers(); + $subStream->putByte(count($subChunk->getBlockLayers())); + foreach($layers as $blocks){ + $wordArray = $blocks->getWordArray(); + $palette = $blocks->getPalette(); + + $subStream->putByte($blocks->getBitsPerBlock()); + $subStream->put($wordArray); + $subStream->putInt(count($palette)); + foreach($palette as $p){ + $subStream->putInt($p); + } + } + + if($chunk->isLightPopulated()){ + $subStream->put($subChunk->getBlockSkyLightArray()); + $subStream->put($subChunk->getBlockLightArray()); + } + } + $stream->putByte($count); + $stream->put($subStream->getBuffer()); + + //biomes + $stream->put($chunk->getBiomeIdArray()); + if($chunk->isLightPopulated()){ + $stream->put(pack("v*", ...$chunk->getHeightMapArray())); + } + } + + return $stream->getBuffer(); + } + + /** + * Deserializes a fast-serialized chunk + * + * @param string $data + * + * @return Chunk + */ + public static function deserialize(string $data) : Chunk{ + $stream = new BinaryStream($data); + + $x = $stream->getInt(); + $z = $stream->getInt(); + $flags = $stream->getByte(); + $lightPopulated = (bool) ($flags & 4); + $terrainPopulated = (bool) ($flags & 2); + $terrainGenerated = (bool) ($flags & 1); + + $subChunks = []; + $biomeIds = ""; + $heightMap = []; + if($terrainGenerated){ + $count = $stream->getByte(); + for($subCount = 0; $subCount < $count; ++$subCount){ + $y = $stream->getByte(); + + /** @var PalettedBlockArray[] $layers */ + $layers = []; + for($i = 0, $layerCount = $stream->getByte(); $i < $layerCount; ++$i){ + $bitsPerBlock = $stream->getByte(); + $words = $stream->get(PalettedBlockArray::getExpectedWordArraySize($bitsPerBlock)); + $palette = []; + for($k = 0, $paletteSize = $stream->getInt(); $k < $paletteSize; ++$k){ + $palette[] = $stream->getInt(); + } + + $layers[] = PalettedBlockArray::fromData($bitsPerBlock, $words, $palette); + } + $subChunks[$y] = new SubChunk( + $layers, $lightPopulated ? $stream->get(2048) : "", $lightPopulated ? $stream->get(2048) : "" //blocklight + ); + } + + $biomeIds = $stream->get(256); + if($lightPopulated){ + $heightMap = array_values(unpack("v*", $stream->get(512))); + } + } + + $chunk = new Chunk($x, $z, $subChunks, null, null, $biomeIds, $heightMap); + $chunk->setGenerated($terrainGenerated); + $chunk->setPopulated($terrainPopulated); + $chunk->setLightPopulated($lightPopulated); + + return $chunk; + } +} diff --git a/src/pocketmine/world/generator/PopulationTask.php b/src/pocketmine/world/generator/PopulationTask.php index f599dce8e6..76b715e84f 100644 --- a/src/pocketmine/world/generator/PopulationTask.php +++ b/src/pocketmine/world/generator/PopulationTask.php @@ -25,6 +25,7 @@ namespace pocketmine\world\generator; use pocketmine\scheduler\AsyncTask; use pocketmine\world\format\Chunk; +use pocketmine\world\format\io\FastChunkSerializer; use pocketmine\world\SimpleChunkManager; use pocketmine\world\World; @@ -48,10 +49,10 @@ class PopulationTask extends AsyncTask{ public function __construct(World $world, Chunk $chunk){ $this->state = true; $this->worldId = $world->getId(); - $this->chunk = $chunk->fastSerialize(); + $this->chunk = FastChunkSerializer::serialize($chunk); foreach($world->getAdjacentChunks($chunk->getX(), $chunk->getZ()) as $i => $c){ - $this->{"chunk$i"} = $c !== null ? $c->fastSerialize() : null; + $this->{"chunk$i"} = $c !== null ? FastChunkSerializer::serialize($c) : null; } $this->storeLocal(self::TLS_KEY_WORLD, $world); @@ -70,7 +71,7 @@ class PopulationTask extends AsyncTask{ /** @var Chunk[] $chunks */ $chunks = []; - $chunk = Chunk::fastDeserialize($this->chunk); + $chunk = FastChunkSerializer::deserialize($this->chunk); for($i = 0; $i < 9; ++$i){ if($i === 4){ @@ -82,7 +83,7 @@ class PopulationTask extends AsyncTask{ if($ck === null){ $chunks[$i] = new Chunk($chunk->getX() + $xx, $chunk->getZ() + $zz); }else{ - $chunks[$i] = Chunk::fastDeserialize($ck); + $chunks[$i] = FastChunkSerializer::deserialize($ck); } } @@ -110,7 +111,7 @@ class PopulationTask extends AsyncTask{ $chunk->populateSkyLight(); $chunk->setLightPopulated(); $chunk->setPopulated(); - $this->chunk = $chunk->fastSerialize(); + $this->chunk = FastChunkSerializer::serialize($chunk); $manager->setChunk($chunk->getX(), $chunk->getZ(), null); @@ -133,7 +134,7 @@ class PopulationTask extends AsyncTask{ continue; } - $this->{"chunk$i"} = $chunks[$i] !== null ? $chunks[$i]->fastSerialize() : null; + $this->{"chunk$i"} = $chunks[$i] !== null ? FastChunkSerializer::serialize($chunks[$i]) : null; } } @@ -145,7 +146,7 @@ class PopulationTask extends AsyncTask{ $world->registerGeneratorToWorker($this->worker->getAsyncWorkerId()); } - $chunk = Chunk::fastDeserialize($this->chunk); + $chunk = FastChunkSerializer::deserialize($this->chunk); for($i = 0; $i < 9; ++$i){ if($i === 4){ @@ -153,7 +154,7 @@ class PopulationTask extends AsyncTask{ } $c = $this->{"chunk$i"}; if($c !== null){ - $c = Chunk::fastDeserialize($c); + $c = FastChunkSerializer::deserialize($c); $world->generateChunkCallback($c->getX(), $c->getZ(), $this->state ? $c : null); } } diff --git a/src/pocketmine/world/light/LightPopulationTask.php b/src/pocketmine/world/light/LightPopulationTask.php index 1c1e7c7e8a..2583f138d5 100644 --- a/src/pocketmine/world/light/LightPopulationTask.php +++ b/src/pocketmine/world/light/LightPopulationTask.php @@ -26,6 +26,7 @@ namespace pocketmine\world\light; use pocketmine\block\BlockFactory; use pocketmine\scheduler\AsyncTask; use pocketmine\world\format\Chunk; +use pocketmine\world\format\io\FastChunkSerializer; use pocketmine\world\World; class LightPopulationTask extends AsyncTask{ @@ -35,7 +36,7 @@ class LightPopulationTask extends AsyncTask{ public function __construct(World $world, Chunk $chunk){ $this->storeLocal(self::TLS_KEY_WORLD, $world); - $this->chunk = $chunk->fastSerialize(); + $this->chunk = FastChunkSerializer::serialize($chunk); } public function onRun() : void{ @@ -43,13 +44,13 @@ class LightPopulationTask extends AsyncTask{ BlockFactory::init(); } /** @var Chunk $chunk */ - $chunk = Chunk::fastDeserialize($this->chunk); + $chunk = FastChunkSerializer::deserialize($this->chunk); $chunk->recalculateHeightMap(); $chunk->populateSkyLight(); $chunk->setLightPopulated(); - $this->chunk = $chunk->fastSerialize(); + $this->chunk = FastChunkSerializer::serialize($chunk); } public function onCompletion() : void{ @@ -57,7 +58,7 @@ class LightPopulationTask extends AsyncTask{ $world = $this->fetchLocal(self::TLS_KEY_WORLD); if(!$world->isClosed()){ /** @var Chunk $chunk */ - $chunk = Chunk::fastDeserialize($this->chunk); + $chunk = FastChunkSerializer::deserialize($this->chunk); $world->generateChunkCallback($chunk->getX(), $chunk->getZ(), $chunk); } } From 2cb6fda28696cdceda66afe0e729700957489a2c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 14 Jun 2019 18:25:06 +0100 Subject: [PATCH 0936/3224] Moved network chunk serializing code to network\mcpe namespace --- .../network/mcpe/ChunkRequestTask.php | 2 +- .../network/mcpe/ChunkSerializer.php | 77 +++++++++++++++++++ src/pocketmine/world/format/Chunk.php | 44 ----------- 3 files changed, 78 insertions(+), 45 deletions(-) create mode 100644 src/pocketmine/network/mcpe/ChunkSerializer.php diff --git a/src/pocketmine/network/mcpe/ChunkRequestTask.php b/src/pocketmine/network/mcpe/ChunkRequestTask.php index cc5ec7d7fc..fe9a77a4ec 100644 --- a/src/pocketmine/network/mcpe/ChunkRequestTask.php +++ b/src/pocketmine/network/mcpe/ChunkRequestTask.php @@ -43,7 +43,7 @@ class ChunkRequestTask extends AsyncTask{ public function __construct(int $chunkX, int $chunkZ, Chunk $chunk, CompressBatchPromise $promise, ?\Closure $onError = null){ $this->compressionLevel = NetworkCompression::$LEVEL; - $this->chunk = $chunk->networkSerialize(); + $this->chunk = ChunkSerializer::serialize($chunk); $this->chunkX = $chunkX; $this->chunkZ = $chunkZ; diff --git a/src/pocketmine/network/mcpe/ChunkSerializer.php b/src/pocketmine/network/mcpe/ChunkSerializer.php new file mode 100644 index 0000000000..0939504eb0 --- /dev/null +++ b/src/pocketmine/network/mcpe/ChunkSerializer.php @@ -0,0 +1,77 @@ +getSubChunkSendCount(); + $stream->putByte($subChunkCount); + + for($y = 0; $y < $subChunkCount; ++$y){ + $layers = $chunk->getSubChunk($y)->getBlockLayers(); + $stream->putByte(8); //version + + $stream->putByte(count($layers)); + + foreach($layers as $blocks){ + $stream->putByte(($blocks->getBitsPerBlock() << 1) | 1); //last 1-bit means "network format", but seems pointless + $stream->put($blocks->getWordArray()); + $palette = $blocks->getPalette(); + $stream->putVarInt(count($palette)); //yes, this is intentionally zigzag + foreach($palette as $p){ + $stream->putVarInt(RuntimeBlockMapping::toStaticRuntimeId($p >> 4, $p & 0xf)); + } + } + } + $stream->put(pack("v*", ...$chunk->getHeightMapArray())); + $stream->put($chunk->getBiomeIdArray()); + $stream->putByte(0); //border block array count + //Border block entry format: 1 byte (4 bits X, 4 bits Z). These are however useless since they crash the regular client. + + foreach($chunk->getTiles() as $tile){ + if($tile instanceof Spawnable){ + $stream->put($tile->getSerializedSpawnCompound()); + } + } + + return $stream->getBuffer(); + } +} diff --git a/src/pocketmine/world/format/Chunk.php b/src/pocketmine/world/format/Chunk.php index 7fccb58edc..4a88fd261f 100644 --- a/src/pocketmine/world/format/Chunk.php +++ b/src/pocketmine/world/format/Chunk.php @@ -28,14 +28,11 @@ namespace pocketmine\world\format; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; -use pocketmine\block\tile\Spawnable; use pocketmine\block\tile\Tile; use pocketmine\block\tile\TileFactory; use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\NetworkBinaryStream; -use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; use pocketmine\Player; use pocketmine\world\World; use function array_fill; @@ -45,7 +42,6 @@ use function assert; use function chr; use function count; use function ord; -use function pack; use function str_repeat; use function strlen; @@ -723,46 +719,6 @@ class Chunk{ } } - /** - * Serializes the chunk for sending to players - * - * @return string - */ - public function networkSerialize() : string{ - $stream = new NetworkBinaryStream(); - $subChunkCount = $this->getSubChunkSendCount(); - $stream->putByte($subChunkCount); - - for($y = 0; $y < $subChunkCount; ++$y){ - $layers = $this->subChunks[$y]->getBlockLayers(); - $stream->putByte(8); //version - - $stream->putByte(count($layers)); - - foreach($layers as $blocks){ - $stream->putByte(($blocks->getBitsPerBlock() << 1) | 1); //last 1-bit means "network format", but seems pointless - $stream->put($blocks->getWordArray()); - $palette = $blocks->getPalette(); - $stream->putVarInt(count($palette)); //yes, this is intentionally zigzag - foreach($palette as $p){ - $stream->putVarInt(RuntimeBlockMapping::toStaticRuntimeId($p >> 4, $p & 0xf)); - } - } - } - $stream->put(pack("v*", ...$this->heightMap)); - $stream->put($this->biomeIds); - $stream->putByte(0); //border block array count - //Border block entry format: 1 byte (4 bits X, 4 bits Z). These are however useless since they crash the regular client. - - foreach($this->tiles as $tile){ - if($tile instanceof Spawnable){ - $stream->put($tile->getSerializedSpawnCompound()); - } - } - - return $stream->getBuffer(); - } - /** * Hashes the given chunk block coordinates into a single integer. * From 787d305c2a8975637b7add71a533a58f85304052 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 14 Jun 2019 19:31:33 +0100 Subject: [PATCH 0937/3224] Player: call InventoryOpenEvent consistently --- src/pocketmine/Player.php | 16 +++++++++------- src/pocketmine/inventory/BaseInventory.php | 10 +--------- src/pocketmine/inventory/Inventory.php | 4 +--- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 5a89d4a7de..8ccacf6e9e 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -39,6 +39,7 @@ use pocketmine\entity\Skin; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\inventory\InventoryCloseEvent; +use pocketmine\event\inventory\InventoryOpenEvent; use pocketmine\event\player\cheat\PlayerIllegalMoveEvent; use pocketmine\event\player\PlayerAchievementAwardedEvent; use pocketmine\event\player\PlayerAnimationEvent; @@ -2814,16 +2815,17 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->windowIndex[$networkId] = $inventory; $this->windows[spl_object_id($inventory)] = $networkId; - if($inventory->open($this)){ - if($isPermanent){ - $this->permanentWindows[spl_object_id($inventory)] = true; - } - return $networkId; - }else{ - $this->removeWindow($inventory); + $ev = new InventoryOpenEvent($inventory, $this); + $ev->call(); + if($ev->isCancelled()){ return -1; } + $inventory->open($this); + if($isPermanent){ + $this->permanentWindows[spl_object_id($inventory)] = true; + } + return $networkId; } /** diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index 204361799a..63b19c6a6b 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\inventory; -use pocketmine\event\inventory\InventoryOpenEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\Player; @@ -354,15 +353,8 @@ abstract class BaseInventory implements Inventory{ $this->maxStackSize = $size; } - public function open(Player $who) : bool{ - $ev = new InventoryOpenEvent($this, $who); - $ev->call(); - if($ev->isCancelled()){ - return false; - } + public function open(Player $who) : void{ $this->onOpen($who); - - return true; } public function close(Player $who) : void{ diff --git a/src/pocketmine/inventory/Inventory.php b/src/pocketmine/inventory/Inventory.php index d393a3e25f..f23a418155 100644 --- a/src/pocketmine/inventory/Inventory.php +++ b/src/pocketmine/inventory/Inventory.php @@ -198,10 +198,8 @@ interface Inventory{ * Tries to open the inventory to a player * * @param Player $who - * - * @return bool */ - public function open(Player $who) : bool; + public function open(Player $who) : void; public function close(Player $who) : void; From f671f2ebfa71c3beebaff0ff4a514e78c649550e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 14 Jun 2019 19:37:45 +0100 Subject: [PATCH 0938/3224] Inventory: drop useless proxy functions --- src/pocketmine/Player.php | 4 ++-- src/pocketmine/inventory/AnvilInventory.php | 4 ++-- src/pocketmine/inventory/BaseInventory.php | 12 ++---------- src/pocketmine/inventory/ChestInventory.php | 4 ++-- src/pocketmine/inventory/ContainerInventory.php | 4 ++-- src/pocketmine/inventory/DoubleChestInventory.php | 4 ++-- src/pocketmine/inventory/EnchantInventory.php | 4 ++-- src/pocketmine/inventory/Inventory.php | 6 +++--- 8 files changed, 17 insertions(+), 25 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 8ccacf6e9e..b6900e92c5 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2821,7 +2821,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($ev->isCancelled()){ return -1; } - $inventory->open($this); + $inventory->onOpen($this); if($isPermanent){ $this->permanentWindows[spl_object_id($inventory)] = true; } @@ -2844,7 +2844,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $networkId = $this->windows[$objectId] ?? null; if($networkId !== null){ - $inventory->close($this); + $inventory->onClose($this); unset($this->windows[$objectId], $this->windowIndex[$networkId], $this->permanentWindows[$objectId]); } } diff --git a/src/pocketmine/inventory/AnvilInventory.php b/src/pocketmine/inventory/AnvilInventory.php index b1891531be..94f327212c 100644 --- a/src/pocketmine/inventory/AnvilInventory.php +++ b/src/pocketmine/inventory/AnvilInventory.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace pocketmine\inventory; -use pocketmine\world\Position; use pocketmine\network\mcpe\protocol\types\WindowTypes; use pocketmine\Player; +use pocketmine\world\Position; class AnvilInventory extends ContainerInventory{ @@ -48,7 +48,7 @@ class AnvilInventory extends ContainerInventory{ return $this->holder; } - protected function onClose(Player $who) : void{ + public function onClose(Player $who) : void{ parent::onClose($who); foreach($this->getContents() as $item){ diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index 63b19c6a6b..0dc4cb9f29 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -353,19 +353,11 @@ abstract class BaseInventory implements Inventory{ $this->maxStackSize = $size; } - public function open(Player $who) : void{ - $this->onOpen($who); - } - - public function close(Player $who) : void{ - $this->onClose($who); - } - - protected function onOpen(Player $who) : void{ + public function onOpen(Player $who) : void{ $this->viewers[spl_object_id($who)] = $who; } - protected function onClose(Player $who) : void{ + public function onClose(Player $who) : void{ unset($this->viewers[spl_object_id($who)]); } diff --git a/src/pocketmine/inventory/ChestInventory.php b/src/pocketmine/inventory/ChestInventory.php index ae6850d83e..539e93bc95 100644 --- a/src/pocketmine/inventory/ChestInventory.php +++ b/src/pocketmine/inventory/ChestInventory.php @@ -64,7 +64,7 @@ class ChestInventory extends ContainerInventory{ return new ChestCloseSound(); } - protected function onOpen(Player $who) : void{ + public function onOpen(Player $who) : void{ parent::onOpen($who); if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){ @@ -74,7 +74,7 @@ class ChestInventory extends ContainerInventory{ } } - protected function onClose(Player $who) : void{ + public function onClose(Player $who) : void{ if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){ //TODO: this crap really shouldn't be managed by the inventory $this->broadcastBlockEventPacket(false); diff --git a/src/pocketmine/inventory/ContainerInventory.php b/src/pocketmine/inventory/ContainerInventory.php index ee8dfe7e00..cd4ad6ddd4 100644 --- a/src/pocketmine/inventory/ContainerInventory.php +++ b/src/pocketmine/inventory/ContainerInventory.php @@ -38,7 +38,7 @@ abstract class ContainerInventory extends BaseInventory{ parent::__construct($size, $items); } - protected function onOpen(Player $who) : void{ + public function onOpen(Player $who) : void{ parent::onOpen($who); $windowId = $who->getWindowId($this); @@ -52,7 +52,7 @@ abstract class ContainerInventory extends BaseInventory{ $who->getNetworkSession()->syncInventoryContents($this); } - protected function onClose(Player $who) : void{ + public function onClose(Player $who) : void{ $who->sendDataPacket(ContainerClosePacket::create($who->getWindowId($this))); parent::onClose($who); } diff --git a/src/pocketmine/inventory/DoubleChestInventory.php b/src/pocketmine/inventory/DoubleChestInventory.php index afa9a39d69..bab524746e 100644 --- a/src/pocketmine/inventory/DoubleChestInventory.php +++ b/src/pocketmine/inventory/DoubleChestInventory.php @@ -74,7 +74,7 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ return $result; } - protected function onOpen(Player $who) : void{ + public function onOpen(Player $who) : void{ parent::onOpen($who); if(count($this->getViewers()) === 1 and $this->right->getHolder()->isValid()){ @@ -82,7 +82,7 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ } } - protected function onClose(Player $who) : void{ + public function onClose(Player $who) : void{ if(count($this->getViewers()) === 1 and $this->right->getHolder()->isValid()){ $this->right->broadcastBlockEventPacket(false); } diff --git a/src/pocketmine/inventory/EnchantInventory.php b/src/pocketmine/inventory/EnchantInventory.php index d3e41cf436..30d4994b1f 100644 --- a/src/pocketmine/inventory/EnchantInventory.php +++ b/src/pocketmine/inventory/EnchantInventory.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace pocketmine\inventory; -use pocketmine\world\Position; use pocketmine\network\mcpe\protocol\types\WindowTypes; use pocketmine\Player; +use pocketmine\world\Position; class EnchantInventory extends ContainerInventory{ @@ -48,7 +48,7 @@ class EnchantInventory extends ContainerInventory{ return $this->holder; } - protected function onClose(Player $who) : void{ + public function onClose(Player $who) : void{ parent::onClose($who); foreach($this->getContents() as $item){ diff --git a/src/pocketmine/inventory/Inventory.php b/src/pocketmine/inventory/Inventory.php index f23a418155..e07318db2c 100644 --- a/src/pocketmine/inventory/Inventory.php +++ b/src/pocketmine/inventory/Inventory.php @@ -195,13 +195,13 @@ interface Inventory{ public function getViewers() : array; /** - * Tries to open the inventory to a player + * Called when a player opens this inventory. * * @param Player $who */ - public function open(Player $who) : void; + public function onOpen(Player $who) : void; - public function close(Player $who) : void; + public function onClose(Player $who) : void; /** * Returns whether the specified slot exists in the inventory. From 8356285b666cc2221c3dfb4e4f3d7268545ef093 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 14 Jun 2019 19:39:35 +0100 Subject: [PATCH 0939/3224] Consistently call InventoryCloseEvent this wasn't being fired when a plugin did the removal. --- src/pocketmine/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index b6900e92c5..c479598907 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2744,7 +2744,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->doCloseInventory(); if(isset($this->windowIndex[$windowId])){ - (new InventoryCloseEvent($this->windowIndex[$windowId], $this))->call(); $this->removeWindow($this->windowIndex[$windowId]); return true; } @@ -2844,6 +2843,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $networkId = $this->windows[$objectId] ?? null; if($networkId !== null){ + (new InventoryCloseEvent($inventory, $this))->call(); $inventory->onClose($this); unset($this->windows[$objectId], $this->windowIndex[$networkId], $this->permanentWindows[$objectId]); } From 468340d55b4b7301031fb184a5b1be6c900461df Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 14 Jun 2019 19:41:19 +0100 Subject: [PATCH 0940/3224] this was stupid --- src/pocketmine/Player.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index c479598907..c83efc73c7 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2812,14 +2812,14 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } - $this->windowIndex[$networkId] = $inventory; - $this->windows[spl_object_id($inventory)] = $networkId; - $ev = new InventoryOpenEvent($inventory, $this); $ev->call(); if($ev->isCancelled()){ return -1; } + + $this->windowIndex[$networkId] = $inventory; + $this->windows[spl_object_id($inventory)] = $networkId; $inventory->onOpen($this); if($isPermanent){ $this->permanentWindows[spl_object_id($inventory)] = true; From c77e75fa93e1b3b55a8731374ae0496b9699a4cb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 14 Jun 2019 19:42:50 +0100 Subject: [PATCH 0941/3224] FastChunkSerializer: fix typo --- src/pocketmine/world/format/io/FastChunkSerializer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/world/format/io/FastChunkSerializer.php b/src/pocketmine/world/format/io/FastChunkSerializer.php index b86b054468..0620cc40cd 100644 --- a/src/pocketmine/world/format/io/FastChunkSerializer.php +++ b/src/pocketmine/world/format/io/FastChunkSerializer.php @@ -34,7 +34,7 @@ use function pack; use function unpack; /** - * This class provides a serializer used for transmitting chunks between chunks. + * This class provides a serializer used for transmitting chunks between threads. * The serialization format **is not intended for permanent storage** and may change without warning. */ final class FastChunkSerializer{ From 50a7fc0ba387c6a806a76314643821e57be76597 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 15 Jun 2019 14:23:02 +0100 Subject: [PATCH 0942/3224] Rework inventory window open/close handling - This fixes InventoryOpenEvent and InventoryCloseEvent being fired for persistent windows. Close #2950 - The ability to specify a custom network ID to assign the inventory to in addWindow() has been removed. - The ability to assign a non-removable window in addWindow() has been removed. - The ability to remove non-removable windows in removeWindow() and removeAllWindows() has been removed. This was previously needed for internal purposes. --- src/pocketmine/Player.php | 102 +++++++++++---------- src/pocketmine/block/tile/BrewingStand.php | 2 +- src/pocketmine/block/tile/Chest.php | 4 +- src/pocketmine/block/tile/Furnace.php | 2 +- src/pocketmine/block/tile/Hopper.php | 2 +- src/pocketmine/entity/Human.php | 4 +- src/pocketmine/entity/Living.php | 2 +- src/pocketmine/inventory/BaseInventory.php | 6 +- 8 files changed, 65 insertions(+), 59 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index c83efc73c7..3babad4e9a 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2424,7 +2424,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->usedChunks = []; $this->loadQueue = []; - $this->removeAllWindows(true); + $this->removeAllWindows(); + foreach($this->permanentWindows as $networkId => $bool){ + $this->closeInventoryInternal($this->windowIndex[$networkId], true); + } + assert(empty($this->windowIndex) && empty($this->windows)); $this->windows = []; $this->windowIndex = []; @@ -2435,8 +2439,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, protected function onDispose() : void{ $this->disconnect("Player destroyed"); - $this->cursorInventory->removeAllViewers(true); - $this->craftingGrid->removeAllViewers(true); + $this->cursorInventory->removeAllViewers(); + $this->craftingGrid->removeAllViewers(); parent::onDispose(); } @@ -2678,12 +2682,12 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } protected function addDefaultWindows(){ - $this->addWindow($this->getInventory(), ContainerIds::INVENTORY, true); + $this->openInventoryInternal($this->getInventory(), ContainerIds::INVENTORY, true); - $this->addWindow($this->getArmorInventory(), ContainerIds::ARMOR, true); + $this->openInventoryInternal($this->getArmorInventory(), ContainerIds::ARMOR, true); $this->cursorInventory = new PlayerCursorInventory($this); - $this->addWindow($this->cursorInventory, ContainerIds::CURSOR, true); + $this->openInventoryInternal($this->cursorInventory, ContainerIds::CURSOR, true); $this->craftingGrid = new CraftingGrid($this, CraftingGrid::SIZE_SMALL); @@ -2778,39 +2782,58 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->windowIndex[$windowId] ?? null; } + protected function openInventoryInternal(Inventory $inventory, int $networkId, bool $permanent) : void{ + $this->windowIndex[$networkId] = $inventory; + $this->windows[spl_object_id($inventory)] = $networkId; + $inventory->onOpen($this); + if($permanent){ + $this->logger->debug("Opening permanent inventory " . get_class($inventory) . " with network ID $networkId"); + $this->permanentWindows[$networkId] = true; + } + } + + protected function closeInventoryInternal(Inventory $inventory, bool $force) : bool{ + $objectId = spl_object_id($inventory); + $networkId = $this->windows[$objectId] ?? null; + if($networkId !== null){ + if(isset($this->permanentWindows[$networkId])){ + if(!$force){ + throw new \InvalidArgumentException("Cannot remove fixed window " . get_class($inventory) . " from " . $this->getName()); + } + $this->logger->debug("Closing permanent inventory " . get_class($inventory) . " with network ID $networkId"); + } + + $inventory->onClose($this); + unset($this->windows[$objectId], $this->windowIndex[$networkId], $this->permanentWindows[$networkId]); + return true; + } + return false; + } + /** * Opens an inventory window to the player. Returns the ID of the created window, or the existing window ID if the * player is already viewing the specified inventory. * * @param Inventory $inventory - * @param int|null $forceNetworkId Forces a special ID for the window - * @param bool $isPermanent Prevents the window being removed if true. * * @return int * * @throws \InvalidArgumentException if a forceID which is already in use is specified * @throws \InvalidStateException if trying to add a window without forceID when no slots are free */ - public function addWindow(Inventory $inventory, ?int $forceNetworkId = null, bool $isPermanent = false) : int{ + public function addWindow(Inventory $inventory) : int{ if(($id = $this->getWindowId($inventory)) !== ContainerIds::NONE){ return $id; } - if($forceNetworkId === null){ - $networkId = $this->lastInventoryNetworkId; - do{ - $networkId = max(ContainerIds::FIRST, ($networkId + 1) % ContainerIds::LAST); - if($networkId === $this->lastInventoryNetworkId){ //wraparound, no free slots - throw new \InvalidStateException("No free window IDs found"); - } - }while(isset($this->windowIndex[$networkId])); - $this->lastInventoryNetworkId = $networkId; - }else{ - $networkId = $forceNetworkId; - if(isset($this->windowIndex[$networkId])){ - throw new \InvalidArgumentException("Requested force ID $forceNetworkId already in use"); + $networkId = $this->lastInventoryNetworkId; + do{ + $networkId = max(ContainerIds::FIRST, ($networkId + 1) % ContainerIds::LAST); + if($networkId === $this->lastInventoryNetworkId){ //wraparound, no free slots + throw new \InvalidStateException("No free window IDs found"); } - } + }while(isset($this->windowIndex[$networkId])); + $this->lastInventoryNetworkId = $networkId; $ev = new InventoryOpenEvent($inventory, $this); $ev->call(); @@ -2818,12 +2841,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return -1; } - $this->windowIndex[$networkId] = $inventory; - $this->windows[spl_object_id($inventory)] = $networkId; - $inventory->onOpen($this); - if($isPermanent){ - $this->permanentWindows[spl_object_id($inventory)] = true; - } + $this->openInventoryInternal($inventory, $networkId, false); return $networkId; } @@ -2831,36 +2849,26 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * Removes an inventory window from the player. * * @param Inventory $inventory - * @param bool $force Forces removal of permanent windows such as normal inventory, cursor * - * @throws \InvalidArgumentException if trying to remove a fixed inventory window without the `force` parameter as true + * @throws \InvalidArgumentException if trying to remove a fixed inventory window */ - public function removeWindow(Inventory $inventory, bool $force = false){ - $objectId = spl_object_id($inventory); - if(!$force and isset($this->permanentWindows[$objectId])){ - throw new \InvalidArgumentException("Cannot remove fixed window " . get_class($inventory) . " from " . $this->getName()); - } - - $networkId = $this->windows[$objectId] ?? null; - if($networkId !== null){ + public function removeWindow(Inventory $inventory){ + if($this->closeInventoryInternal($inventory, false)){ (new InventoryCloseEvent($inventory, $this))->call(); - $inventory->onClose($this); - unset($this->windows[$objectId], $this->windowIndex[$networkId], $this->permanentWindows[$objectId]); } } /** - * Removes all inventory windows from the player. By default this WILL NOT remove permanent windows. - * - * @param bool $removePermanentWindows Whether to remove permanent windows. + * Removes all inventory windows from the player. This WILL NOT remove permanent inventories such as the player's + * own inventory. */ - public function removeAllWindows(bool $removePermanentWindows = false){ + public function removeAllWindows(){ foreach($this->windowIndex as $networkId => $window){ - if(!$removePermanentWindows and isset($this->permanentWindows[spl_object_id($window)])){ + if(isset($this->permanentWindows[$networkId])){ continue; } - $this->removeWindow($window, $removePermanentWindows); + $this->removeWindow($window); } } diff --git a/src/pocketmine/block/tile/BrewingStand.php b/src/pocketmine/block/tile/BrewingStand.php index 2d336cad43..0fc0b5118b 100644 --- a/src/pocketmine/block/tile/BrewingStand.php +++ b/src/pocketmine/block/tile/BrewingStand.php @@ -90,7 +90,7 @@ class BrewingStand extends Spawnable implements Container, Nameable{ public function close() : void{ if(!$this->closed){ - $this->inventory->removeAllViewers(true); + $this->inventory->removeAllViewers(); $this->inventory = null; parent::close(); diff --git a/src/pocketmine/block/tile/Chest.php b/src/pocketmine/block/tile/Chest.php index 98b6546140..edcde8fe91 100644 --- a/src/pocketmine/block/tile/Chest.php +++ b/src/pocketmine/block/tile/Chest.php @@ -96,11 +96,11 @@ class Chest extends Spawnable implements Container, Nameable{ public function close() : void{ if(!$this->closed){ - $this->inventory->removeAllViewers(true); + $this->inventory->removeAllViewers(); if($this->doubleInventory !== null){ if($this->isPaired() and $this->world->isChunkLoaded($this->pairX >> 4, $this->pairZ >> 4)){ - $this->doubleInventory->removeAllViewers(true); + $this->doubleInventory->removeAllViewers(); $this->doubleInventory->invalidate(); if(($pair = $this->getPair()) !== null){ $pair->doubleInventory = null; diff --git a/src/pocketmine/block/tile/Furnace.php b/src/pocketmine/block/tile/Furnace.php index 7d7f402bd9..dcc21281e7 100644 --- a/src/pocketmine/block/tile/Furnace.php +++ b/src/pocketmine/block/tile/Furnace.php @@ -100,7 +100,7 @@ class Furnace extends Spawnable implements Container, Nameable{ public function close() : void{ if(!$this->closed){ - $this->inventory->removeAllViewers(true); + $this->inventory->removeAllViewers(); $this->inventory = null; parent::close(); diff --git a/src/pocketmine/block/tile/Hopper.php b/src/pocketmine/block/tile/Hopper.php index 4aa2d89e21..1d3f369bc5 100644 --- a/src/pocketmine/block/tile/Hopper.php +++ b/src/pocketmine/block/tile/Hopper.php @@ -62,7 +62,7 @@ class Hopper extends Spawnable implements Container, Nameable{ public function close() : void{ if(!$this->closed){ - $this->inventory->removeAllViewers(true); + $this->inventory->removeAllViewers(); $this->inventory = null; parent::close(); diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 03150df893..5f8f1bd46a 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -855,8 +855,8 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ } protected function onDispose() : void{ - $this->inventory->removeAllViewers(true); - $this->enderChestInventory->removeAllViewers(true); + $this->inventory->removeAllViewers(); + $this->enderChestInventory->removeAllViewers(); parent::onDispose(); } diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 5bf7c0ba8f..58df157811 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -918,7 +918,7 @@ abstract class Living extends Entity implements Damageable{ } protected function onDispose() : void{ - $this->armorInventory->removeAllViewers(true); + $this->armorInventory->removeAllViewers(); parent::onDispose(); } diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index 0dc4cb9f29..879712d56c 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -339,12 +339,10 @@ abstract class BaseInventory implements Inventory{ /** * Removes the inventory window from all players currently viewing it. - * - * @param bool $force Force removal of permanent windows such as the player's own inventory. Used internally. */ - public function removeAllViewers(bool $force = false) : void{ + public function removeAllViewers() : void{ foreach($this->viewers as $hash => $viewer){ - $viewer->removeWindow($this, $force); + $viewer->removeWindow($this); unset($this->viewers[$hash]); } } From 4bbf1d56dc62e914098793454f2307ce431e12c9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 15 Jun 2019 14:27:11 +0100 Subject: [PATCH 0943/3224] NetworkInventoryAction: shorten exception message This is logged with the network session's logger, which provides context information already. --- .../network/mcpe/protocol/types/NetworkInventoryAction.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php index c88b046e7f..78aae89d19 100644 --- a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php +++ b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php @@ -173,7 +173,7 @@ class NetworkInventoryAction{ return new SlotChangeAction($window, $this->inventorySlot, $this->oldItem, $this->newItem); } - throw new \UnexpectedValueException("Player " . $player->getName() . " has no open container with window ID $this->windowId"); + throw new \UnexpectedValueException("No open container with window ID $this->windowId"); case self::SOURCE_WORLD: if($this->inventorySlot !== self::ACTION_MAGIC_SLOT_DROP_ITEM){ throw new \UnexpectedValueException("Only expecting drop-item world actions from the client!"); @@ -208,7 +208,7 @@ class NetworkInventoryAction{ } //TODO: more stuff - throw new \UnexpectedValueException("Player " . $player->getName() . " has no open container with window ID $this->windowId"); + throw new \UnexpectedValueException("No open container with window ID $this->windowId"); default: throw new \UnexpectedValueException("Unknown inventory source type $this->sourceType"); } From a94541c531a1a48bb9c81f037dfbd8566a9e2970 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 15 Jun 2019 14:40:15 +0100 Subject: [PATCH 0944/3224] Split CreativeInventoryAction into two new action types --- .../transaction/action/CreateItemAction.php | 48 ++++++++++++ .../action/CreativeInventoryAction.php | 75 ------------------- .../transaction/action/DestroyItemAction.php | 47 ++++++++++++ .../protocol/types/NetworkInventoryAction.php | 11 +-- 4 files changed, 99 insertions(+), 82 deletions(-) create mode 100644 src/pocketmine/inventory/transaction/action/CreateItemAction.php delete mode 100644 src/pocketmine/inventory/transaction/action/CreativeInventoryAction.php create mode 100644 src/pocketmine/inventory/transaction/action/DestroyItemAction.php diff --git a/src/pocketmine/inventory/transaction/action/CreateItemAction.php b/src/pocketmine/inventory/transaction/action/CreateItemAction.php new file mode 100644 index 0000000000..62450dbbe4 --- /dev/null +++ b/src/pocketmine/inventory/transaction/action/CreateItemAction.php @@ -0,0 +1,48 @@ +hasFiniteResources() and CreativeInventory::contains($this->sourceItem); + } + + public function execute(Player $source) : void{ + //NOOP + } +} diff --git a/src/pocketmine/inventory/transaction/action/CreativeInventoryAction.php b/src/pocketmine/inventory/transaction/action/CreativeInventoryAction.php deleted file mode 100644 index 139dda1938..0000000000 --- a/src/pocketmine/inventory/transaction/action/CreativeInventoryAction.php +++ /dev/null @@ -1,75 +0,0 @@ -actionType = $actionType; - } - - /** - * Checks that the player is in creative, and (if creating an item) that the item exists in the creative inventory. - * - * @param Player $source - * - * @return bool - */ - public function isValid(Player $source) : bool{ - return !$source->hasFiniteResources() and - ($this->actionType === self::TYPE_DELETE_ITEM or CreativeInventory::getItemIndex($this->sourceItem) !== -1); - } - - /** - * Returns the type of the action. - */ - public function getActionType() : int{ - return $this->actionType; - } - - /** - * No need to do anything extra here: this type just provides a place for items to disappear or appear from. - * - * @param Player $source - */ - public function execute(Player $source) : void{ - - } -} diff --git a/src/pocketmine/inventory/transaction/action/DestroyItemAction.php b/src/pocketmine/inventory/transaction/action/DestroyItemAction.php new file mode 100644 index 0000000000..b97454e56e --- /dev/null +++ b/src/pocketmine/inventory/transaction/action/DestroyItemAction.php @@ -0,0 +1,47 @@ +hasFiniteResources(); + } + + public function execute(Player $source) : void{ + //NOOP + } +} diff --git a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php index 78aae89d19..49fa75622a 100644 --- a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php +++ b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php @@ -23,7 +23,8 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types; -use pocketmine\inventory\transaction\action\CreativeInventoryAction; +use pocketmine\inventory\transaction\action\CreateItemAction; +use pocketmine\inventory\transaction\action\DestroyItemAction; use pocketmine\inventory\transaction\action\DropItemAction; use pocketmine\inventory\transaction\action\InventoryAction; use pocketmine\inventory\transaction\action\SlotChangeAction; @@ -183,17 +184,13 @@ class NetworkInventoryAction{ case self::SOURCE_CREATIVE: switch($this->inventorySlot){ case self::ACTION_MAGIC_SLOT_CREATIVE_DELETE_ITEM: - $type = CreativeInventoryAction::TYPE_DELETE_ITEM; - break; + return new DestroyItemAction($this->newItem); case self::ACTION_MAGIC_SLOT_CREATIVE_CREATE_ITEM: - $type = CreativeInventoryAction::TYPE_CREATE_ITEM; - break; + return new CreateItemAction($this->oldItem); default: throw new \UnexpectedValueException("Unexpected creative action type $this->inventorySlot"); } - - return new CreativeInventoryAction($this->oldItem, $this->newItem, $type); case self::SOURCE_CRAFTING_GRID: case self::SOURCE_TODO: //These types need special handling. From 312a755a27315cbb495ab3318a5b7b54a2c0eea7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 15 Jun 2019 15:51:43 +0100 Subject: [PATCH 0945/3224] Player: rename $windows to $inventoryNetworkIdMap --- src/pocketmine/Player.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 3babad4e9a..8ef03daee1 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -183,8 +183,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, protected $playerInfo; protected $lastInventoryNetworkId = 2; - /** @var int[] */ - protected $windows = []; + /** @var int[] object ID => network ID */ + protected $inventoryNetworkIdMap = []; /** @var Inventory[] */ protected $windowIndex = []; /** @var bool[] */ @@ -2428,8 +2428,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, foreach($this->permanentWindows as $networkId => $bool){ $this->closeInventoryInternal($this->windowIndex[$networkId], true); } - assert(empty($this->windowIndex) && empty($this->windows)); - $this->windows = []; + assert(empty($this->windowIndex) && empty($this->inventoryNetworkIdMap)); + $this->inventoryNetworkIdMap = []; $this->windowIndex = []; $this->perm->clearPermissions(); @@ -2767,7 +2767,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return int */ public function getWindowId(Inventory $inventory) : int{ - return $this->windows[spl_object_id($inventory)] ?? ContainerIds::NONE; + return $this->inventoryNetworkIdMap[spl_object_id($inventory)] ?? ContainerIds::NONE; } /** @@ -2784,7 +2784,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, protected function openInventoryInternal(Inventory $inventory, int $networkId, bool $permanent) : void{ $this->windowIndex[$networkId] = $inventory; - $this->windows[spl_object_id($inventory)] = $networkId; + $this->inventoryNetworkIdMap[spl_object_id($inventory)] = $networkId; $inventory->onOpen($this); if($permanent){ $this->logger->debug("Opening permanent inventory " . get_class($inventory) . " with network ID $networkId"); @@ -2794,7 +2794,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, protected function closeInventoryInternal(Inventory $inventory, bool $force) : bool{ $objectId = spl_object_id($inventory); - $networkId = $this->windows[$objectId] ?? null; + $networkId = $this->inventoryNetworkIdMap[$objectId] ?? null; if($networkId !== null){ if(isset($this->permanentWindows[$networkId])){ if(!$force){ @@ -2804,7 +2804,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $inventory->onClose($this); - unset($this->windows[$objectId], $this->windowIndex[$networkId], $this->permanentWindows[$networkId]); + unset($this->inventoryNetworkIdMap[$objectId], $this->windowIndex[$networkId], $this->permanentWindows[$networkId]); return true; } return false; From 93b83b41893e3d351ba136c6d46e0291b4473499 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 15 Jun 2019 18:19:09 +0100 Subject: [PATCH 0946/3224] Player: Window system now only allows 1 window at a time --- src/pocketmine/Player.php | 182 ++++++++---------- src/pocketmine/block/Anvil.php | 2 +- src/pocketmine/block/BrewingStand.php | 2 +- src/pocketmine/block/Chest.php | 2 +- src/pocketmine/block/EnchantingTable.php | 2 +- src/pocketmine/block/EnderChest.php | 2 +- src/pocketmine/block/Furnace.php | 2 +- src/pocketmine/block/Hopper.php | 2 +- src/pocketmine/inventory/BaseInventory.php | 4 +- .../network/mcpe/NetworkSession.php | 6 +- 10 files changed, 96 insertions(+), 110 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 8ef03daee1..38ef47229e 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -115,6 +115,7 @@ use pocketmine\world\particle\PunchBlockParticle; use pocketmine\world\Position; use pocketmine\world\World; use function abs; +use function array_search; use function assert; use function ceil; use function count; @@ -182,12 +183,13 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** @var PlayerInfo */ protected $playerInfo; + /** @var int */ protected $lastInventoryNetworkId = 2; - /** @var int[] object ID => network ID */ - protected $inventoryNetworkIdMap = []; + /** @var Inventory[] network ID => inventory */ + protected $networkIdToInventoryMap = []; + /** @var Inventory|null */ + protected $currentWindow = null; /** @var Inventory[] */ - protected $windowIndex = []; - /** @var bool[] */ protected $permanentWindows = []; /** @var PlayerCursorInventory */ protected $cursorInventory; @@ -2424,13 +2426,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->usedChunks = []; $this->loadQueue = []; - $this->removeAllWindows(); - foreach($this->permanentWindows as $networkId => $bool){ - $this->closeInventoryInternal($this->windowIndex[$networkId], true); + $this->removeCurrentWindow(); + foreach($this->permanentWindows as $objectId => $inventory){ + $this->closeInventoryInternal($inventory, true); } - assert(empty($this->windowIndex) && empty($this->inventoryNetworkIdMap)); - $this->inventoryNetworkIdMap = []; - $this->windowIndex = []; + assert(empty($this->networkIdToInventoryMap)); $this->perm->clearPermissions(); @@ -2657,7 +2657,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, public function teleport(Vector3 $pos, ?float $yaw = null, ?float $pitch = null) : bool{ if(parent::teleport($pos, $yaw, $pitch)){ - $this->removeAllWindows(); + $this->removeCurrentWindow(); $this->sendPosition($this, $this->yaw, $this->pitch, MovePlayerPacket::MODE_TELEPORT); $this->broadcastMovement(true); @@ -2741,14 +2741,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool */ public function doCloseWindow(int $windowId) : bool{ - if($windowId === 0){ - return false; - } - $this->doCloseInventory(); - if(isset($this->windowIndex[$windowId])){ - $this->removeWindow($this->windowIndex[$windowId]); + if($windowId === $this->lastInventoryNetworkId and $this->currentWindow !== null){ + $this->removeCurrentWindow(); return true; } if($windowId === 255){ @@ -2756,18 +2752,62 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return true; } + $this->logger->debug("Attempted to close inventory with network ID $windowId, but current is $this->lastInventoryNetworkId"); return false; } + /** + * Returns the inventory the player is currently viewing. This might be a chest, furnace, or any other container. + * + * @return Inventory|null + */ + public function getCurrentWindow() : ?Inventory{ + return $this->currentWindow; + } + + /** + * Opens an inventory window to the player. Returns if it was successful. + * + * @param Inventory $inventory + * + * @return bool + */ + public function setCurrentWindow(Inventory $inventory) : bool{ + if($inventory === $this->currentWindow){ + return true; + } + $ev = new InventoryOpenEvent($inventory, $this); + $ev->call(); + if($ev->isCancelled()){ + return false; + } + + //TODO: client side race condition here makes the opening work incorrectly + $this->removeCurrentWindow(); + + $networkId = $this->lastInventoryNetworkId = max(ContainerIds::FIRST, ($this->lastInventoryNetworkId + 1) % ContainerIds::LAST); + + $this->openInventoryInternal($inventory, $networkId, false); + $this->currentWindow = $inventory; + return true; + } + + public function removeCurrentWindow() : void{ + if($this->currentWindow !== null){ + (new InventoryCloseEvent($this->craftingGrid, $this))->call(); + $this->closeInventoryInternal($this->currentWindow, false); + } + } + /** * Returns the window ID which the inventory has for this player, or -1 if the window is not open to the player. * * @param Inventory $inventory * - * @return int + * @return int|null */ - public function getWindowId(Inventory $inventory) : int{ - return $this->inventoryNetworkIdMap[spl_object_id($inventory)] ?? ContainerIds::NONE; + public function getWindowId(Inventory $inventory) : ?int{ + return ($id = array_search($inventory, $this->networkIdToInventoryMap, true)) !== false ? $id : null; } /** @@ -2779,104 +2819,48 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return Inventory|null */ public function getWindow(int $windowId) : ?Inventory{ - return $this->windowIndex[$windowId] ?? null; + return $this->networkIdToInventoryMap[$windowId] ?? null; } protected function openInventoryInternal(Inventory $inventory, int $networkId, bool $permanent) : void{ - $this->windowIndex[$networkId] = $inventory; - $this->inventoryNetworkIdMap[spl_object_id($inventory)] = $networkId; + $this->logger->debug("Opening inventory " . get_class($inventory) . "#" . spl_object_id($inventory) . " with network ID $networkId"); + $this->networkIdToInventoryMap[$networkId] = $inventory; $inventory->onOpen($this); if($permanent){ - $this->logger->debug("Opening permanent inventory " . get_class($inventory) . " with network ID $networkId"); - $this->permanentWindows[$networkId] = true; + $this->permanentWindows[spl_object_id($inventory)] = $inventory; } } protected function closeInventoryInternal(Inventory $inventory, bool $force) : bool{ + $this->logger->debug("Closing inventory " . get_class($inventory) . "#" . spl_object_id($inventory)); $objectId = spl_object_id($inventory); - $networkId = $this->inventoryNetworkIdMap[$objectId] ?? null; - if($networkId !== null){ - if(isset($this->permanentWindows[$networkId])){ - if(!$force){ - throw new \InvalidArgumentException("Cannot remove fixed window " . get_class($inventory) . " from " . $this->getName()); - } - $this->logger->debug("Closing permanent inventory " . get_class($inventory) . " with network ID $networkId"); + if($inventory === $this->currentWindow){ + $this->currentWindow = null; + }elseif(isset($this->permanentWindows[$objectId])){ + if(!$force){ + throw new \InvalidArgumentException("Cannot remove fixed window " . get_class($inventory) . " from " . $this->getName()); } - - $inventory->onClose($this); - unset($this->inventoryNetworkIdMap[$objectId], $this->windowIndex[$networkId], $this->permanentWindows[$networkId]); - return true; - } - return false; - } - - /** - * Opens an inventory window to the player. Returns the ID of the created window, or the existing window ID if the - * player is already viewing the specified inventory. - * - * @param Inventory $inventory - * - * @return int - * - * @throws \InvalidArgumentException if a forceID which is already in use is specified - * @throws \InvalidStateException if trying to add a window without forceID when no slots are free - */ - public function addWindow(Inventory $inventory) : int{ - if(($id = $this->getWindowId($inventory)) !== ContainerIds::NONE){ - return $id; + unset($this->permanentWindows[$objectId]); + }else{ + return false; } - $networkId = $this->lastInventoryNetworkId; - do{ - $networkId = max(ContainerIds::FIRST, ($networkId + 1) % ContainerIds::LAST); - if($networkId === $this->lastInventoryNetworkId){ //wraparound, no free slots - throw new \InvalidStateException("No free window IDs found"); - } - }while(isset($this->windowIndex[$networkId])); - $this->lastInventoryNetworkId = $networkId; - - $ev = new InventoryOpenEvent($inventory, $this); - $ev->call(); - if($ev->isCancelled()){ - return -1; - } - - $this->openInventoryInternal($inventory, $networkId, false); - return $networkId; - } - - /** - * Removes an inventory window from the player. - * - * @param Inventory $inventory - * - * @throws \InvalidArgumentException if trying to remove a fixed inventory window - */ - public function removeWindow(Inventory $inventory){ - if($this->closeInventoryInternal($inventory, false)){ - (new InventoryCloseEvent($inventory, $this))->call(); - } - } - - /** - * Removes all inventory windows from the player. This WILL NOT remove permanent inventories such as the player's - * own inventory. - */ - public function removeAllWindows(){ - foreach($this->windowIndex as $networkId => $window){ - if(isset($this->permanentWindows[$networkId])){ - continue; - } - - $this->removeWindow($window); - } + $inventory->onClose($this); + $networkId = $this->getWindowId($inventory); + assert($networkId !== null); + unset($this->networkIdToInventoryMap[$networkId]); + return true; } /** * @return Inventory[] */ public function getAllWindows() : array{ - return $this->windowIndex; + $windows = $this->permanentWindows; + if($this->currentWindow !== null){ + $windows[] = $this->currentWindow; + } + return $windows; } public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue) : void{ diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index e705060572..f03c9174c4 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -64,7 +64,7 @@ class Anvil extends Transparent implements Fallable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $player->addWindow(new AnvilInventory($this)); + $player->setCurrentWindow(new AnvilInventory($this)); } return true; diff --git a/src/pocketmine/block/BrewingStand.php b/src/pocketmine/block/BrewingStand.php index 67408f0b66..465934fab5 100644 --- a/src/pocketmine/block/BrewingStand.php +++ b/src/pocketmine/block/BrewingStand.php @@ -62,7 +62,7 @@ class BrewingStand extends Transparent{ if($player instanceof Player){ $stand = $this->getWorld()->getTile($this); if($stand instanceof TileBrewingStand and $stand->canOpenWith($item->getCustomName())){ - $player->addWindow($stand->getInventory()); + $player->setCurrentWindow($stand->getInventory()); } } diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index 1ef27fa6be..c56eeafac9 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -99,7 +99,7 @@ class Chest extends Transparent{ return true; } - $player->addWindow($chest->getInventory()); + $player->setCurrentWindow($chest->getInventory()); } } diff --git a/src/pocketmine/block/EnchantingTable.php b/src/pocketmine/block/EnchantingTable.php index 2e3db817ef..66ebae89d5 100644 --- a/src/pocketmine/block/EnchantingTable.php +++ b/src/pocketmine/block/EnchantingTable.php @@ -45,7 +45,7 @@ class EnchantingTable extends Transparent{ if($player instanceof Player){ //TODO lock - $player->addWindow(new EnchantInventory($this)); + $player->setCurrentWindow(new EnchantInventory($this)); } return true; diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index d0078625ee..d750b56dbb 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -76,7 +76,7 @@ class EnderChest extends Transparent{ $enderChest = $this->getWorld()->getTile($this); if($enderChest instanceof TileEnderChest and $this->getSide(Facing::UP)->isTransparent()){ $player->getEnderChestInventory()->setHolderPosition($enderChest); - $player->addWindow($player->getEnderChestInventory()); + $player->setCurrentWindow($player->getEnderChestInventory()); } } diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index 1a847f19ac..c2248ebf76 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -92,7 +92,7 @@ class Furnace extends Solid{ if($player instanceof Player){ $furnace = $this->getWorld()->getTile($this); if($furnace instanceof TileFurnace and $furnace->canOpenWith($item->getCustomName())){ - $player->addWindow($furnace->getInventory()); + $player->setCurrentWindow($furnace->getInventory()); } } diff --git a/src/pocketmine/block/Hopper.php b/src/pocketmine/block/Hopper.php index 7f8f0a71a3..6c997f350f 100644 --- a/src/pocketmine/block/Hopper.php +++ b/src/pocketmine/block/Hopper.php @@ -78,7 +78,7 @@ class Hopper extends Transparent{ if($player !== null){ $tile = $this->world->getTile($this); if($tile instanceof TileHopper){ //TODO: find a way to have inventories open on click without this boilerplate in every block - $player->addWindow($tile->getInventory()); + $player->setCurrentWindow($tile->getInventory()); } return true; } diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index 879712d56c..b71ac0453a 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -342,7 +342,9 @@ abstract class BaseInventory implements Inventory{ */ public function removeAllViewers() : void{ foreach($this->viewers as $hash => $viewer){ - $viewer->removeWindow($this); + if($viewer->getCurrentWindow() === $this){ //this might not be the case for the player's own inventory + $viewer->removeCurrentWindow(); + } unset($this->viewers[$hash]); } } diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 391944094e..1c731fd2e6 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -753,14 +753,14 @@ class NetworkSession{ public function syncInventorySlot(Inventory $inventory, int $slot) : void{ $windowId = $this->player->getWindowId($inventory); - if($windowId !== ContainerIds::NONE){ + if($windowId !== null){ $this->sendDataPacket(InventorySlotPacket::create($windowId, $slot, $inventory->getItem($slot))); } } public function syncInventoryContents(Inventory $inventory) : void{ $windowId = $this->player->getWindowId($inventory); - if($windowId !== ContainerIds::NONE){ + if($windowId !== null){ $this->sendDataPacket(InventoryContentPacket::create($windowId, $inventory->getContents(true))); } } @@ -773,7 +773,7 @@ class NetworkSession{ public function syncInventoryData(Inventory $inventory, int $propertyId, int $value) : void{ $windowId = $this->player->getWindowId($inventory); - if($windowId !== ContainerIds::NONE){ + if($windowId !== null){ $this->sendDataPacket(ContainerSetDataPacket::create($windowId, $propertyId, $value)); } } From 4e734989bccabac78164d6663dfa294d6974049b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 15 Jun 2019 18:56:42 +0100 Subject: [PATCH 0947/3224] fixing add/remove items from anvil & enchanting table the functionality of these don't work yet, but the inventories work more correctly now. --- .../protocol/types/NetworkInventoryAction.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php index 49fa75622a..8318d61593 100644 --- a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php +++ b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types; +use pocketmine\inventory\AnvilInventory; +use pocketmine\inventory\EnchantInventory; use pocketmine\inventory\transaction\action\CreateItemAction; use pocketmine\inventory\transaction\action\DestroyItemAction; use pocketmine\inventory\transaction\action\DropItemAction; @@ -202,6 +204,20 @@ class NetworkInventoryAction{ case self::SOURCE_TYPE_CRAFTING_RESULT: case self::SOURCE_TYPE_CRAFTING_USE_INGREDIENT: return null; + case self::SOURCE_TYPE_ANVIL_INPUT: + case self::SOURCE_TYPE_ANVIL_MATERIAL: + $window = $player->getCurrentWindow(); + if(!($window instanceof AnvilInventory)){ + throw new \UnexpectedValueException("Current open container is not an anvil"); + } + return new SlotChangeAction($window, $this->inventorySlot, $this->oldItem, $this->newItem); + case self::SOURCE_TYPE_ENCHANT_INPUT: + case self::SOURCE_TYPE_ENCHANT_MATERIAL: + $window = $player->getCurrentWindow(); + if(!($window instanceof EnchantInventory)){ + throw new \UnexpectedValueException("Current open container is not an enchanting table"); + } + return new SlotChangeAction($window, $this->inventorySlot, $this->oldItem, $this->newItem); } //TODO: more stuff From b71bb867f4e3a05ec9d6cdec6f7c24c0b946e76c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 16 Jun 2019 16:52:47 +0100 Subject: [PATCH 0948/3224] DefaultPermissions: remove pocketmine.command.reload --- src/pocketmine/permission/DefaultPermissions.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pocketmine/permission/DefaultPermissions.php b/src/pocketmine/permission/DefaultPermissions.php index 5f41e1805c..1ae419c3fb 100644 --- a/src/pocketmine/permission/DefaultPermissions.php +++ b/src/pocketmine/permission/DefaultPermissions.php @@ -110,7 +110,6 @@ abstract class DefaultPermissions{ self::registerPermission(new Permission(self::ROOT . ".command.list", "Allows the user to list all online players", Permission::DEFAULT_OP), $commands); self::registerPermission(new Permission(self::ROOT . ".command.help", "Allows the user to view the help menu", Permission::DEFAULT_TRUE), $commands); self::registerPermission(new Permission(self::ROOT . ".command.plugins", "Allows the user to view the list of plugins", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.reload", "Allows the user to reload the server settings", Permission::DEFAULT_OP), $commands); self::registerPermission(new Permission(self::ROOT . ".command.version", "Allows the user to view the version of the server", Permission::DEFAULT_TRUE), $commands); self::registerPermission(new Permission(self::ROOT . ".command.gamemode", "Allows the user to change the gamemode of players", Permission::DEFAULT_OP), $commands); self::registerPermission(new Permission(self::ROOT . ".command.defaultgamemode", "Allows the user to change the default gamemode", Permission::DEFAULT_OP), $commands); From 698193622adda852c5ae53c2b7d498d2001d99fe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 16 Jun 2019 18:23:13 +0100 Subject: [PATCH 0949/3224] WorldManager: rename get/setAutoSaveTicks() to get/setAutoSaveInterval() this is less ambiguous. --- src/pocketmine/world/WorldManager.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/world/WorldManager.php b/src/pocketmine/world/WorldManager.php index 55e0d1fbfd..c9e881ad4d 100644 --- a/src/pocketmine/world/WorldManager.php +++ b/src/pocketmine/world/WorldManager.php @@ -408,18 +408,18 @@ class WorldManager{ } /** - * Returns the period after which loaded worlds will be automatically saved to disk. + * Returns the period in ticks after which loaded worlds will be automatically saved to disk. * * @return int */ - public function getAutoSaveTicks() : int{ + public function getAutoSaveInterval() : int{ return $this->autoSaveTicks; } /** * @param int $autoSaveTicks */ - public function setAutoSaveTicks(int $autoSaveTicks) : void{ + public function setAutoSaveInterval(int $autoSaveTicks) : void{ if($autoSaveTicks <= 0){ throw new \InvalidArgumentException("Autosave ticks must be positive"); } From b344427a3038e07a8efefcc27f3b362c99272057 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 17 Jun 2019 14:20:29 +0100 Subject: [PATCH 0950/3224] Added a hack to allow dropping garbage serverbound packets sent by a buggy client --- .../network/mcpe/NetworkSession.php | 5 +++ .../protocol/GarbageServerboundPacket.php | 32 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 src/pocketmine/network/mcpe/protocol/GarbageServerboundPacket.php diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 1c731fd2e6..b30ad7fb34 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -48,6 +48,7 @@ use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\ContainerSetDataPacket; use pocketmine\network\mcpe\protocol\DisconnectPacket; +use pocketmine\network\mcpe\protocol\GarbageServerboundPacket; use pocketmine\network\mcpe\protocol\InventoryContentPacket; use pocketmine\network\mcpe\protocol\InventorySlotPacket; use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket; @@ -313,6 +314,10 @@ class NetworkSession{ */ public function handleDataPacket(Packet $packet) : void{ if(!($packet instanceof ServerboundPacket)){ + if($packet instanceof GarbageServerboundPacket){ + $this->logger->debug("Garbage serverbound " . $packet->getName() . ": " . base64_encode($packet->getBuffer())); + return; + } throw new BadPacketException("Unexpected non-serverbound packet"); } diff --git a/src/pocketmine/network/mcpe/protocol/GarbageServerboundPacket.php b/src/pocketmine/network/mcpe/protocol/GarbageServerboundPacket.php new file mode 100644 index 0000000000..04870b1252 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/GarbageServerboundPacket.php @@ -0,0 +1,32 @@ + Date: Mon, 17 Jun 2019 14:22:08 +0100 Subject: [PATCH 0951/3224] SetEntityMotionPacket: Mark as garbage serverbound --- .../network/mcpe/protocol/SetEntityMotionPacket.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php b/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php index 7f4a863c65..451483893b 100644 --- a/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php @@ -29,7 +29,10 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\SessionHandler; -class SetEntityMotionPacket extends DataPacket implements ClientboundPacket{ +/** + * TODO: This packet is (erroneously) sent to the server when the client is riding a vehicle. + */ +class SetEntityMotionPacket extends DataPacket implements ClientboundPacket, GarbageServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_ENTITY_MOTION_PACKET; /** @var int */ From fe98b6c765177c70689b1fef4be7ffbd2705cb58 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 17 Jun 2019 14:55:25 +0100 Subject: [PATCH 0952/3224] EnumTrait: rename getEnumName() -> name() this is more concise and brings it more in line with Java. --- src/pocketmine/CrashDump.php | 2 +- src/pocketmine/utils/EnumTrait.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/CrashDump.php b/src/pocketmine/CrashDump.php index 2948036d99..efb929a03f 100644 --- a/src/pocketmine/CrashDump.php +++ b/src/pocketmine/CrashDump.php @@ -158,7 +158,7 @@ class CrashDump{ "depends" => $d->getDepend(), "softDepends" => $d->getSoftDepend(), "main" => $d->getMain(), - "load" => strtoupper($d->getOrder()->getEnumName()), + "load" => strtoupper($d->getOrder()->name()), "website" => $d->getWebsite() ]; $this->addLine($d->getName() . " " . $d->getVersion() . " by " . implode(", ", $d->getAuthors()) . " for API(s) " . implode(", ", $d->getCompatibleApis())); diff --git a/src/pocketmine/utils/EnumTrait.php b/src/pocketmine/utils/EnumTrait.php index 518a84d618..994b05f9d4 100644 --- a/src/pocketmine/utils/EnumTrait.php +++ b/src/pocketmine/utils/EnumTrait.php @@ -42,11 +42,11 @@ trait EnumTrait{ * @throws \InvalidArgumentException */ protected static function register(self $member) : void{ - $name = strtoupper($member->getEnumName()); + $name = strtoupper($member->name()); if(isset(self::$members[$name])){ throw new \InvalidArgumentException("Enum member name \"$name\" is already reserved"); } - self::$members[strtoupper($member->getEnumName())] = $member; + self::$members[strtoupper($member->name())] = $member; } /** @@ -171,7 +171,7 @@ public static function %1$s() : self{ /** * @return string */ - public function getEnumName() : string{ + public function name() : string{ return $this->enumName; } From 20f092a685c93ebd2638f0774e0a3d13e20cd0be Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 17 Jun 2019 15:58:33 +0100 Subject: [PATCH 0953/3224] Living: Do not use spl_object_id() for identifying effects it's possible for these to have different IDs if they were cloned, serialized or copied between threads. --- src/pocketmine/entity/Living.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 58df157811..f01f4b7005 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -64,7 +64,6 @@ use function max; use function min; use function mt_getrandmax; use function mt_rand; -use function spl_object_id; use function sqrt; use const M_PI; @@ -219,7 +218,7 @@ abstract class Living extends Entity implements Damageable{ * @param Effect $effectType */ public function removeEffect(Effect $effectType) : void{ - $index = spl_object_id($effectType); + $index = $effectType->getId(); if(isset($this->effects[$index])){ $effect = $this->effects[$index]; $hasExpired = $effect->hasExpired(); @@ -249,7 +248,7 @@ abstract class Living extends Entity implements Damageable{ * @return EffectInstance|null */ public function getEffect(Effect $effect) : ?EffectInstance{ - return $this->effects[spl_object_id($effect)] ?? null; + return $this->effects[$effect->getId()] ?? null; } /** @@ -260,7 +259,7 @@ abstract class Living extends Entity implements Damageable{ * @return bool */ public function hasEffect(Effect $effect) : bool{ - return isset($this->effects[spl_object_id($effect)]); + return isset($this->effects[$effect->getId()]); } /** @@ -284,8 +283,7 @@ abstract class Living extends Entity implements Damageable{ $oldEffect = null; $cancelled = false; - $type = $effect->getType(); - $index = spl_object_id($type); + $index = $effect->getType()->getId(); if(isset($this->effects[$index])){ $oldEffect = $this->effects[$index]; if( From 3c677bd3ec3584572f84c4728d65179302705ea2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 17 Jun 2019 16:10:13 +0100 Subject: [PATCH 0954/3224] added PermissibleDelegateTrait to cut down boilerplate in Player and ConsoleCommandSender --- src/pocketmine/Player.php | 59 ++------------ .../command/ConsoleCommandSender.php | 57 +------------ .../permission/PermissibleDelegateTrait.php | 81 +++++++++++++++++++ 3 files changed, 88 insertions(+), 109 deletions(-) create mode 100644 src/pocketmine/permission/PermissibleDelegateTrait.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 38ef47229e..081e951988 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -101,8 +101,7 @@ use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\PlayerMetadataFlags; use pocketmine\permission\PermissibleBase; -use pocketmine\permission\PermissionAttachment; -use pocketmine\permission\PermissionAttachmentInfo; +use pocketmine\permission\PermissibleDelegateTrait; use pocketmine\permission\PermissionManager; use pocketmine\plugin\Plugin; use pocketmine\timings\Timings; @@ -144,6 +143,9 @@ use const PHP_INT_MAX; * Main class that handles networking, recovery, and packet sending to the server part */ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, IPlayer{ + use PermissibleDelegateTrait { + recalculatePermissions as private delegateRecalculatePermissions; + } /** * Checks a supplied username and checks it is valid. @@ -253,9 +255,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** @var bool */ protected $flying = false; - /** @var PermissibleBase */ - private $perm = null; - /** @var int|null */ protected $lineHeight = null; /** @var string */ @@ -690,47 +689,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->networkSession->syncAdventureSettings($this); } - /** - * @param permission\Permission|string $name - * - * @return bool - */ - public function isPermissionSet($name) : bool{ - return $this->perm->isPermissionSet($name); - } - - /** - * @param permission\Permission|string $name - * - * @return bool - * - * @throws \InvalidStateException if the player is closed - */ - public function hasPermission($name) : bool{ - if($this->closed){ - throw new \InvalidStateException("Trying to get permissions of closed player"); - } - return $this->perm->hasPermission($name); - } - - /** - * @param Plugin $plugin - * @param string $name - * @param bool $value - * - * @return PermissionAttachment - */ - public function addAttachment(Plugin $plugin, ?string $name = null, ?bool $value = null) : PermissionAttachment{ - return $this->perm->addAttachment($plugin, $name, $value); - } - - /** - * @param PermissionAttachment $attachment - */ - public function removeAttachment(PermissionAttachment $attachment) : void{ - $this->perm->removeAttachment($attachment); - } - public function recalculatePermissions() : void{ $permManager = PermissionManager::getInstance(); $permManager->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this); @@ -740,7 +698,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return; } - $this->perm->recalculatePermissions(); + $this->delegateRecalculatePermissions(); if($this->spawned){ if($this->hasPermission(Server::BROADCAST_CHANNEL_USERS)){ @@ -754,13 +712,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } - /** - * @return PermissionAttachmentInfo[] - */ - public function getEffectivePermissions() : array{ - return $this->perm->getEffectivePermissions(); - } - /** * @return bool */ diff --git a/src/pocketmine/command/ConsoleCommandSender.php b/src/pocketmine/command/ConsoleCommandSender.php index 7834c43997..a80a3c235f 100644 --- a/src/pocketmine/command/ConsoleCommandSender.php +++ b/src/pocketmine/command/ConsoleCommandSender.php @@ -25,18 +25,14 @@ namespace pocketmine\command; use pocketmine\lang\TextContainer; use pocketmine\permission\PermissibleBase; -use pocketmine\permission\Permission; -use pocketmine\permission\PermissionAttachment; -use pocketmine\permission\PermissionAttachmentInfo; -use pocketmine\plugin\Plugin; +use pocketmine\permission\PermissibleDelegateTrait; use pocketmine\Server; use function explode; use function trim; use const PHP_INT_MAX; class ConsoleCommandSender implements CommandSender{ - - private $perm; + use PermissibleDelegateTrait; /** @var int|null */ protected $lineHeight = null; @@ -45,55 +41,6 @@ class ConsoleCommandSender implements CommandSender{ $this->perm = new PermissibleBase($this); } - /** - * @param Permission|string $name - * - * @return bool - */ - public function isPermissionSet($name) : bool{ - return $this->perm->isPermissionSet($name); - } - - /** - * @param Permission|string $name - * - * @return bool - */ - public function hasPermission($name) : bool{ - return $this->perm->hasPermission($name); - } - - /** - * @param Plugin $plugin - * @param string $name - * @param bool $value - * - * @return PermissionAttachment - */ - public function addAttachment(Plugin $plugin, ?string $name = null, ?bool $value = null) : PermissionAttachment{ - return $this->perm->addAttachment($plugin, $name, $value); - } - - /** - * @param PermissionAttachment $attachment - * - * @return void - */ - public function removeAttachment(PermissionAttachment $attachment) : void{ - $this->perm->removeAttachment($attachment); - } - - public function recalculatePermissions() : void{ - $this->perm->recalculatePermissions(); - } - - /** - * @return PermissionAttachmentInfo[] - */ - public function getEffectivePermissions() : array{ - return $this->perm->getEffectivePermissions(); - } - /** * @return Server */ diff --git a/src/pocketmine/permission/PermissibleDelegateTrait.php b/src/pocketmine/permission/PermissibleDelegateTrait.php new file mode 100644 index 0000000000..a6bab9e4c4 --- /dev/null +++ b/src/pocketmine/permission/PermissibleDelegateTrait.php @@ -0,0 +1,81 @@ +perm->isPermissionSet($name); + } + + /** + * @param Permission|string $name + * + * @return bool + */ + public function hasPermission($name) : bool{ + return $this->perm->hasPermission($name); + } + + /** + * @param Plugin $plugin + * @param string $name + * @param bool $value + * + * @return PermissionAttachment + */ + public function addAttachment(Plugin $plugin, ?string $name = null, ?bool $value = null) : PermissionAttachment{ + return $this->perm->addAttachment($plugin, $name, $value); + } + + /** + * @param PermissionAttachment $attachment + */ + public function removeAttachment(PermissionAttachment $attachment) : void{ + $this->perm->removeAttachment($attachment); + } + + public function recalculatePermissions() : void{ + $this->perm->recalculatePermissions(); + } + + /** + * @return PermissionAttachmentInfo[] + */ + public function getEffectivePermissions() : array{ + return $this->perm->getEffectivePermissions(); + } + +} From 92e81e329815799f52fa01f0ad5ff5f5f8ae8900 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 17 Jun 2019 16:27:04 +0100 Subject: [PATCH 0955/3224] Player: move some respawn net sync logic to NetworkSession --- src/pocketmine/Player.php | 6 ------ src/pocketmine/network/mcpe/NetworkSession.php | 5 +++++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 081e951988..76fa81d6c9 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2530,12 +2530,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $attr->resetToDefault(); } - $this->sendData($this); - $this->sendData($this->getViewers()); - - $this->networkSession->syncAdventureSettings($this); - $this->networkSession->syncAllInventoryContents(); - $this->spawnToAll(); $this->scheduleUpdate(); diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index b30ad7fb34..c4aa229084 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -586,6 +586,11 @@ class NetworkSession{ } public function onRespawn() : void{ + $this->player->sendData($this->player); + $this->player->sendData($this->player->getViewers()); + + $this->syncAdventureSettings($this->player); + $this->syncAllInventoryContents(); $this->setHandler(new InGameSessionHandler($this->player, $this)); } From db3305cb1604de547b98951bc467f07b71979db5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 17 Jun 2019 16:39:46 +0100 Subject: [PATCH 0956/3224] Remove Entity->isClosed() checks from places where they don't make sense in all of these cases, this is just potentially concealing bugs. Closed entities should never appear at these points. --- src/pocketmine/Player.php | 2 +- src/pocketmine/world/World.php | 3 ++- src/pocketmine/world/format/Chunk.php | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 76fa81d6c9..a6f1af679a 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -894,7 +894,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, protected function spawnEntitiesOnChunk(int $chunkX, int $chunkZ) : void{ foreach($this->world->getChunkEntities($chunkX, $chunkZ) as $entity){ - if($entity !== $this and !$entity->isClosed() and !$entity->isFlaggedForDespawn()){ + if($entity !== $this and !$entity->isFlaggedForDespawn()){ $entity->spawnTo($this); } } diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 4dd4088a21..4b9d57e7c2 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -46,6 +46,7 @@ use pocketmine\event\world\ChunkPopulateEvent; use pocketmine\event\world\ChunkUnloadEvent; use pocketmine\event\world\SpawnChangeEvent; use pocketmine\event\world\WorldSaveEvent; +use pocketmine\GameMode; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\ItemUseResult; @@ -1958,7 +1959,7 @@ class World implements ChunkManager, Metadatable{ for($x = $minX; $x <= $maxX; ++$x){ for($z = $minZ; $z <= $maxZ; ++$z){ foreach($this->getChunkEntities($x, $z) as $entity){ - if(!($entity instanceof $entityType) or $entity->isClosed() or $entity->isFlaggedForDespawn() or (!$includeDead and !$entity->isAlive())){ + if(!($entity instanceof $entityType) or $entity->isFlaggedForDespawn() or (!$includeDead and !$entity->isAlive())){ continue; } $distSq = $entity->distanceSquared($pos); diff --git a/src/pocketmine/world/format/Chunk.php b/src/pocketmine/world/format/Chunk.php index 4a88fd261f..e6906a6c18 100644 --- a/src/pocketmine/world/format/Chunk.php +++ b/src/pocketmine/world/format/Chunk.php @@ -505,7 +505,7 @@ class Chunk{ * @return Entity[] */ public function getSavableEntities() : array{ - return array_filter($this->entities, function(Entity $entity) : bool{ return $entity->canSaveWithChunk() and !$entity->isClosed(); }); + return array_filter($this->entities, function(Entity $entity) : bool{ return $entity->canSaveWithChunk(); }); } /** From e0a9ea2573372ffac576105d2a26e248c9959223 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 17 Jun 2019 17:07:31 +0100 Subject: [PATCH 0957/3224] Player: clean up some crazy spawn logic in constructor this was probably a leftover from some old code, I guess --- src/pocketmine/Player.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index a6f1af679a..98e6c10b3f 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -315,7 +315,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $spawn = new Vector3($pos[0], $pos[1], $pos[2]); }else{ $world = $this->server->getWorldManager()->getDefaultWorld(); //TODO: default world might be null - $spawn = $world->getSpawnLocation(); + $spawn = $world->getSafeSpawn(); $spawnReset = true; } @@ -323,9 +323,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $world->registerChunkLoader($this, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4, true); $world->registerChunkListener($this, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4); $this->usedChunks[World::chunkHash($spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4)] = false; - if($spawnReset){ - $spawn = $world->getSafeSpawn($spawn); - } if($namedtag === null){ $namedtag = EntityFactory::createBaseNBT($spawn); From 7b049b6db1956da4556386dd99e36b38de3164b4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 17 Jun 2019 17:30:42 +0100 Subject: [PATCH 0958/3224] NetworkSession: use a better check for timeout --- src/pocketmine/network/mcpe/NetworkSession.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index c4aa229084..094f7414d9 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -821,7 +821,7 @@ class NetworkSession{ } public function tick() : bool{ - if($this->handler instanceof LoginSessionHandler){ + if($this->info === null){ if(time() >= $this->connectTime + 10){ $this->disconnect("Login timeout"); return false; From bb675ac99bd1791ceb57aa7633c6096eee392f7a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 18 Jun 2019 14:05:39 +0100 Subject: [PATCH 0959/3224] Set parallel bootstrap file if the extension is loaded --- src/pocketmine/PocketMine.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index 48910b6d3e..54ca6a307c 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -157,6 +157,9 @@ namespace pocketmine { if(\pocketmine\COMPOSER_AUTOLOADER_PATH !== false and is_file(\pocketmine\COMPOSER_AUTOLOADER_PATH)){ require_once(\pocketmine\COMPOSER_AUTOLOADER_PATH); + if(extension_loaded('parallel')){ + \parallel\bootstrap(\pocketmine\COMPOSER_AUTOLOADER_PATH); + } }else{ critical_error("Composer autoloader not found at " . $bootstrap); critical_error("Please install/update Composer dependencies or use provided builds."); From 9df2ca3655a327b953762deb90d21257af7d3802 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 18 Jun 2019 14:12:37 +0100 Subject: [PATCH 0960/3224] fixup some formatting issues --- .../inventory/CallbackInventoryChangeListener.php | 4 ++-- src/pocketmine/network/mcpe/ChunkCache.php | 2 +- src/pocketmine/network/mcpe/NetworkSession.php | 10 +++++----- .../network/mcpe/protocol/AvailableCommandsPacket.php | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/pocketmine/inventory/CallbackInventoryChangeListener.php b/src/pocketmine/inventory/CallbackInventoryChangeListener.php index b274997409..82c6b8ebb2 100644 --- a/src/pocketmine/inventory/CallbackInventoryChangeListener.php +++ b/src/pocketmine/inventory/CallbackInventoryChangeListener.php @@ -46,10 +46,10 @@ class CallbackInventoryChangeListener implements InventoryChangeListener{ public static function onAnyChange(\Closure $onChange) : self{ return new self( - static function(Inventory $inventory, int $unused) use($onChange) : void{ + static function(Inventory $inventory, int $unused) use ($onChange) : void{ $onChange($inventory); }, - static function(Inventory $inventory) use($onChange) : void{ + static function(Inventory $inventory) use ($onChange) : void{ $onChange($inventory); } ); diff --git a/src/pocketmine/network/mcpe/ChunkCache.php b/src/pocketmine/network/mcpe/ChunkCache.php index 44776857f5..8249175e0b 100644 --- a/src/pocketmine/network/mcpe/ChunkCache.php +++ b/src/pocketmine/network/mcpe/ChunkCache.php @@ -98,7 +98,7 @@ class ChunkCache implements ChunkListener{ $chunkZ, $this->world->getChunk($chunkX, $chunkZ), $this->caches[$chunkHash], - function() use($chunkX, $chunkZ){ + function() use ($chunkX, $chunkZ){ $this->world->getLogger()->error("Failed preparing chunk $chunkX $chunkZ, retrying"); $this->restartPendingRequest($chunkX, $chunkZ); diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 094f7414d9..9604f50aac 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -449,7 +449,7 @@ class NetworkSession{ * @param bool $notify */ public function disconnect(string $reason, bool $notify = true) : void{ - $this->tryDisconnect(function() use($reason, $notify){ + $this->tryDisconnect(function() use ($reason, $notify){ if($this->player !== null){ $this->player->disconnect($reason, null, $notify); } @@ -467,7 +467,7 @@ class NetworkSession{ * @throws \UnsupportedOperationException */ public function transfer(string $ip, int $port, string $reason = "transfer") : void{ - $this->tryDisconnect(function() use($ip, $port, $reason){ + $this->tryDisconnect(function() use ($ip, $port, $reason){ $this->sendDataPacket(TransferPacket::create($ip, $port), true); $this->disconnect($reason, false); if($this->player !== null){ @@ -484,7 +484,7 @@ class NetworkSession{ * @param bool $notify */ public function onPlayerDestroyed(string $reason, bool $notify = true) : void{ - $this->tryDisconnect(function() use($reason, $notify){ + $this->tryDisconnect(function() use ($reason, $notify){ $this->doServerDisconnect($reason, $notify); }); } @@ -510,7 +510,7 @@ class NetworkSession{ * @param string $reason */ public function onClientDisconnect(string $reason) : void{ - $this->tryDisconnect(function() use($reason){ + $this->tryDisconnect(function() use ($reason){ if($this->player !== null){ $this->player->disconnect($reason, null, false); } @@ -742,7 +742,7 @@ class NetworkSession{ ChunkCache::getInstance($this->player->getWorld())->request($chunkX, $chunkZ)->onResolve( //this callback may be called synchronously or asynchronously, depending on whether the promise is resolved yet - function(CompressBatchPromise $promise) use($chunkX, $chunkZ, $onCompletion){ + function(CompressBatchPromise $promise) use ($chunkX, $chunkZ, $onCompletion){ if(!$this->isConnected()){ return; } diff --git a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php index 13f087feee..f89697fbb8 100644 --- a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php @@ -356,7 +356,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ /** @var CommandEnum[] $enums */ $enums = []; - $addEnumFn = static function(CommandEnum $enum) use(&$enums, &$enumIndexes, &$enumValueIndexes){ + $addEnumFn = static function(CommandEnum $enum) use (&$enums, &$enumIndexes, &$enumValueIndexes){ if(!isset($enumIndexes[$enum->getName()])){ $enums[$enumIndexes[$enum->getName()] = count($enumIndexes)] = $enum; } From 94299534b3639c7382a6d5b51f6c0ba3e55babe5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 18 Jun 2019 15:01:44 +0100 Subject: [PATCH 0961/3224] NetworkSession: fix some blind spots on logging --- src/pocketmine/network/mcpe/NetworkSession.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 9604f50aac..72d114b7ce 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -79,6 +79,7 @@ use pocketmine\PlayerInfo; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\BinaryDataException; +use pocketmine\utils\TextFormat; use pocketmine\utils\Utils; use pocketmine\world\Position; use function array_map; @@ -154,6 +155,7 @@ class NetworkSession{ $this->setHandler(new LoginSessionHandler($this->server, $this)); $this->manager->add($this); + $this->logger->info("Session opened"); } private function getLogPrefix() : string{ @@ -195,6 +197,7 @@ class NetworkSession{ throw new \InvalidStateException("Player info has already been set"); } $this->info = $info; + $this->logger->info("Player: " . TextFormat::AQUA . $info->getUsername() . TextFormat::RESET); $this->logger->setPrefix($this->getLogPrefix()); } @@ -431,7 +434,7 @@ class NetworkSession{ $this->interface->putPacket($this, $payload, $immediate); } - private function tryDisconnect(\Closure $func) : void{ + private function tryDisconnect(\Closure $func, string $reason) : void{ if($this->connected and !$this->disconnectGuard){ $this->disconnectGuard = true; $func(); @@ -439,6 +442,7 @@ class NetworkSession{ $this->setHandler(NullSessionHandler::getInstance()); $this->connected = false; $this->manager->remove($this); + $this->logger->info("Session closed due to $reason"); } } @@ -454,7 +458,7 @@ class NetworkSession{ $this->player->disconnect($reason, null, $notify); } $this->doServerDisconnect($reason, $notify); - }); + }, $reason); } /** @@ -474,7 +478,7 @@ class NetworkSession{ $this->player->disconnect($reason, null, false); } $this->doServerDisconnect($reason, false); - }); + }, $reason); } /** @@ -486,7 +490,7 @@ class NetworkSession{ public function onPlayerDestroyed(string $reason, bool $notify = true) : void{ $this->tryDisconnect(function() use ($reason, $notify){ $this->doServerDisconnect($reason, $notify); - }); + }, $reason); } /** @@ -514,7 +518,7 @@ class NetworkSession{ if($this->player !== null){ $this->player->disconnect($reason, null, false); } - }); + }, $reason); } public function setAuthenticationStatus(bool $authenticated, bool $authRequired, ?string $error) : bool{ From 87c3636d44a55b717fe29634ad2090151d428871 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 18 Jun 2019 15:10:58 +0100 Subject: [PATCH 0962/3224] ResourcePacksSessionHandler: moar debug --- .../network/mcpe/handler/ResourcePacksSessionHandler.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php index 877efcfc59..d879f239b7 100644 --- a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; +use function count; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\ResourcePackChunkDataPacket; use pocketmine\network\mcpe\protocol\ResourcePackChunkRequestPacket; @@ -60,6 +61,7 @@ class ResourcePacksSessionHandler extends SessionHandler{ public function setUp() : void{ $this->session->sendDataPacket(ResourcePacksInfoPacket::create($this->resourcePackManager->getResourceStack(), [], $this->resourcePackManager->resourcePacksRequired(), false)); + $this->session->getLogger()->debug("Waiting for client to accept resource packs"); } private function disconnectWithError(string $error) : void{ @@ -96,12 +98,15 @@ class ResourcePacksSessionHandler extends SessionHandler{ $pack->getSha256() )); } + $this->session->getLogger()->debug("Player requested download of " . count($packet->packIds) . " resource packs"); break; case ResourcePackClientResponsePacket::STATUS_HAVE_ALL_PACKS: $this->session->sendDataPacket(ResourcePackStackPacket::create($this->resourcePackManager->getResourceStack(), [], $this->resourcePackManager->resourcePacksRequired(), false)); + $this->session->getLogger()->debug("Applying resource pack stack"); break; case ResourcePackClientResponsePacket::STATUS_COMPLETED: + $this->session->getLogger()->debug("Resource packs sequence completed"); $this->session->onResourcePacksDone(); break; default: From b18bd4f33ce606ad594b56dd4785b650d21cd695 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 18 Jun 2019 16:02:46 +0100 Subject: [PATCH 0963/3224] rename SessionHandler -> PacketHandler --- .../network/mcpe/NetworkSession.php | 38 +++++++++---------- ...sionHandler.php => DeathPacketHandler.php} | 2 +- ...Handler.php => HandshakePacketHandler.php} | 2 +- ...ionHandler.php => InGamePacketHandler.php} | 2 +- ...sionHandler.php => LoginPacketHandler.php} | 4 +- ...ssionHandler.php => NullPacketHandler.php} | 2 +- .../{SessionHandler.php => PacketHandler.php} | 2 +- ...nHandler.php => PreSpawnPacketHandler.php} | 2 +- ...ler.php => ResourcePacksPacketHandler.php} | 2 +- .../mcpe/protocol/AddBehaviorTreePacket.php | 4 +- .../network/mcpe/protocol/AddEntityPacket.php | 4 +- .../mcpe/protocol/AddItemEntityPacket.php | 4 +- .../mcpe/protocol/AddPaintingPacket.php | 4 +- .../network/mcpe/protocol/AddPlayerPacket.php | 4 +- .../mcpe/protocol/AdventureSettingsPacket.php | 4 +- .../network/mcpe/protocol/AnimatePacket.php | 4 +- .../AutomationClientConnectPacket.php | 4 +- .../mcpe/protocol/AvailableCommandsPacket.php | 4 +- .../AvailableEntityIdentifiersPacket.php | 4 +- .../protocol/BiomeDefinitionListPacket.php | 4 +- .../mcpe/protocol/BlockEntityDataPacket.php | 4 +- .../mcpe/protocol/BlockEventPacket.php | 4 +- .../mcpe/protocol/BlockPickRequestPacket.php | 4 +- .../network/mcpe/protocol/BookEditPacket.php | 4 +- .../network/mcpe/protocol/BossEventPacket.php | 4 +- .../network/mcpe/protocol/CameraPacket.php | 4 +- .../mcpe/protocol/ChangeDimensionPacket.php | 4 +- .../protocol/ChunkRadiusUpdatedPacket.php | 4 +- .../ClientToServerHandshakePacket.php | 4 +- .../protocol/ClientboundMapItemDataPacket.php | 4 +- .../protocol/CommandBlockUpdatePacket.php | 4 +- .../mcpe/protocol/CommandOutputPacket.php | 4 +- .../mcpe/protocol/CommandRequestPacket.php | 4 +- .../mcpe/protocol/ContainerClosePacket.php | 4 +- .../mcpe/protocol/ContainerOpenPacket.php | 4 +- .../mcpe/protocol/ContainerSetDataPacket.php | 4 +- .../mcpe/protocol/CraftingDataPacket.php | 4 +- .../mcpe/protocol/CraftingEventPacket.php | 4 +- .../mcpe/protocol/DisconnectPacket.php | 4 +- .../mcpe/protocol/EntityEventPacket.php | 4 +- .../mcpe/protocol/EntityFallPacket.php | 4 +- .../mcpe/protocol/EntityPickRequestPacket.php | 4 +- .../network/mcpe/protocol/EventPacket.php | 4 +- .../network/mcpe/protocol/ExplodePacket.php | 4 +- .../mcpe/protocol/FullChunkDataPacket.php | 4 +- .../mcpe/protocol/GameRulesChangedPacket.php | 4 +- .../mcpe/protocol/GuiDataPickItemPacket.php | 4 +- .../network/mcpe/protocol/HurtArmorPacket.php | 4 +- .../network/mcpe/protocol/InteractPacket.php | 4 +- .../mcpe/protocol/InventoryContentPacket.php | 4 +- .../mcpe/protocol/InventorySlotPacket.php | 4 +- .../protocol/InventoryTransactionPacket.php | 4 +- .../mcpe/protocol/ItemFrameDropItemPacket.php | 4 +- .../network/mcpe/protocol/LabTablePacket.php | 4 +- .../mcpe/protocol/LecternUpdatePacket.php | 4 +- .../mcpe/protocol/LevelEventPacket.php | 4 +- .../mcpe/protocol/LevelSoundEventPacket.php | 4 +- .../mcpe/protocol/LevelSoundEventPacketV1.php | 4 +- .../mcpe/protocol/LevelSoundEventPacketV2.php | 4 +- .../network/mcpe/protocol/LoginPacket.php | 4 +- .../protocol/MapCreateLockedCopyPacket.php | 4 +- .../mcpe/protocol/MapInfoRequestPacket.php | 4 +- .../mcpe/protocol/MobArmorEquipmentPacket.php | 4 +- .../network/mcpe/protocol/MobEffectPacket.php | 4 +- .../mcpe/protocol/MobEquipmentPacket.php | 4 +- .../mcpe/protocol/ModalFormRequestPacket.php | 4 +- .../mcpe/protocol/ModalFormResponsePacket.php | 4 +- .../protocol/MoveEntityAbsolutePacket.php | 4 +- .../mcpe/protocol/MoveEntityDeltaPacket.php | 4 +- .../mcpe/protocol/MovePlayerPacket.php | 4 +- .../NetworkChunkPublisherUpdatePacket.php | 4 +- .../protocol/NetworkStackLatencyPacket.php | 4 +- .../mcpe/protocol/NpcRequestPacket.php | 4 +- .../OnScreenTextureAnimationPacket.php | 4 +- .../network/mcpe/protocol/Packet.php | 8 ++-- .../mcpe/protocol/PhotoTransferPacket.php | 4 +- .../network/mcpe/protocol/PlaySoundPacket.php | 4 +- .../mcpe/protocol/PlayStatusPacket.php | 4 +- .../mcpe/protocol/PlayerActionPacket.php | 4 +- .../mcpe/protocol/PlayerHotbarPacket.php | 4 +- .../mcpe/protocol/PlayerInputPacket.php | 4 +- .../mcpe/protocol/PlayerListPacket.php | 4 +- .../mcpe/protocol/PlayerSkinPacket.php | 4 +- .../mcpe/protocol/PurchaseReceiptPacket.php | 4 +- .../mcpe/protocol/RemoveEntityPacket.php | 4 +- .../mcpe/protocol/RemoveObjectivePacket.php | 4 +- .../protocol/RequestChunkRadiusPacket.php | 4 +- .../protocol/ResourcePackChunkDataPacket.php | 4 +- .../ResourcePackChunkRequestPacket.php | 4 +- .../ResourcePackClientResponsePacket.php | 4 +- .../protocol/ResourcePackDataInfoPacket.php | 4 +- .../mcpe/protocol/ResourcePackStackPacket.php | 4 +- .../mcpe/protocol/ResourcePacksInfoPacket.php | 4 +- .../network/mcpe/protocol/RespawnPacket.php | 4 +- .../network/mcpe/protocol/RiderJumpPacket.php | 4 +- .../mcpe/protocol/ScriptCustomEventPacket.php | 4 +- .../protocol/ServerSettingsRequestPacket.php | 4 +- .../protocol/ServerSettingsResponsePacket.php | 4 +- .../ServerToClientHandshakePacket.php | 4 +- .../protocol/SetCommandsEnabledPacket.php | 4 +- .../protocol/SetDefaultGameTypePacket.php | 4 +- .../mcpe/protocol/SetDifficultyPacket.php | 4 +- .../protocol/SetDisplayObjectivePacket.php | 4 +- .../mcpe/protocol/SetEntityDataPacket.php | 4 +- .../mcpe/protocol/SetEntityLinkPacket.php | 4 +- .../mcpe/protocol/SetEntityMotionPacket.php | 4 +- .../network/mcpe/protocol/SetHealthPacket.php | 4 +- .../mcpe/protocol/SetLastHurtByPacket.php | 4 +- .../SetLocalPlayerAsInitializedPacket.php | 4 +- .../mcpe/protocol/SetPlayerGameTypePacket.php | 4 +- .../network/mcpe/protocol/SetScorePacket.php | 4 +- .../protocol/SetScoreboardIdentityPacket.php | 4 +- .../mcpe/protocol/SetSpawnPositionPacket.php | 4 +- .../network/mcpe/protocol/SetTimePacket.php | 4 +- .../network/mcpe/protocol/SetTitlePacket.php | 4 +- .../mcpe/protocol/ShowCreditsPacket.php | 4 +- .../mcpe/protocol/ShowProfilePacket.php | 4 +- .../mcpe/protocol/ShowStoreOfferPacket.php | 4 +- .../mcpe/protocol/SimpleEventPacket.php | 4 +- .../protocol/SpawnExperienceOrbPacket.php | 4 +- .../protocol/SpawnParticleEffectPacket.php | 4 +- .../network/mcpe/protocol/StartGamePacket.php | 4 +- .../network/mcpe/protocol/StopSoundPacket.php | 4 +- .../protocol/StructureBlockUpdatePacket.php | 4 +- .../mcpe/protocol/SubClientLoginPacket.php | 4 +- .../mcpe/protocol/TakeItemEntityPacket.php | 4 +- .../network/mcpe/protocol/TextPacket.php | 4 +- .../network/mcpe/protocol/TransferPacket.php | 4 +- .../network/mcpe/protocol/UnknownPacket.php | 4 +- .../mcpe/protocol/UpdateAttributesPacket.php | 4 +- .../mcpe/protocol/UpdateBlockPacket.php | 4 +- .../mcpe/protocol/UpdateBlockSyncedPacket.php | 4 +- .../mcpe/protocol/UpdateEquipPacket.php | 4 +- .../mcpe/protocol/UpdateSoftEnumPacket.php | 4 +- .../mcpe/protocol/UpdateTradePacket.php | 4 +- .../protocol/VideoStreamConnectPacket.php | 4 +- 136 files changed, 284 insertions(+), 284 deletions(-) rename src/pocketmine/network/mcpe/handler/{DeathSessionHandler.php => DeathPacketHandler.php} (97%) rename src/pocketmine/network/mcpe/handler/{HandshakeSessionHandler.php => HandshakePacketHandler.php} (95%) rename src/pocketmine/network/mcpe/handler/{InGameSessionHandler.php => InGamePacketHandler.php} (99%) rename src/pocketmine/network/mcpe/handler/{LoginSessionHandler.php => LoginPacketHandler.php} (96%) rename src/pocketmine/network/mcpe/handler/{NullSessionHandler.php => NullPacketHandler.php} (95%) rename src/pocketmine/network/mcpe/handler/{SessionHandler.php => PacketHandler.php} (99%) rename src/pocketmine/network/mcpe/handler/{PreSpawnSessionHandler.php => PreSpawnPacketHandler.php} (98%) rename src/pocketmine/network/mcpe/handler/{ResourcePacksSessionHandler.php => ResourcePacksPacketHandler.php} (99%) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 72d114b7ce..96e56d1db2 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -34,14 +34,14 @@ use pocketmine\inventory\CreativeInventory; use pocketmine\inventory\Inventory; use pocketmine\math\Vector3; use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\DeathSessionHandler; -use pocketmine\network\mcpe\handler\HandshakeSessionHandler; -use pocketmine\network\mcpe\handler\InGameSessionHandler; -use pocketmine\network\mcpe\handler\LoginSessionHandler; -use pocketmine\network\mcpe\handler\NullSessionHandler; -use pocketmine\network\mcpe\handler\PreSpawnSessionHandler; -use pocketmine\network\mcpe\handler\ResourcePacksSessionHandler; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\DeathPacketHandler; +use pocketmine\network\mcpe\handler\HandshakePacketHandler; +use pocketmine\network\mcpe\handler\InGamePacketHandler; +use pocketmine\network\mcpe\handler\LoginPacketHandler; +use pocketmine\network\mcpe\handler\NullPacketHandler; +use pocketmine\network\mcpe\handler\PreSpawnPacketHandler; +use pocketmine\network\mcpe\handler\ResourcePacksPacketHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; @@ -116,7 +116,7 @@ class NetworkSession{ /** @var int */ private $ping; - /** @var SessionHandler */ + /** @var PacketHandler */ private $handler; /** @var bool */ @@ -152,7 +152,7 @@ class NetworkSession{ $this->connectTime = time(); - $this->setHandler(new LoginSessionHandler($this->server, $this)); + $this->setHandler(new LoginPacketHandler($this->server, $this)); $this->manager->add($this); $this->logger->info("Session opened"); @@ -245,11 +245,11 @@ class NetworkSession{ $this->ping = $ping; } - public function getHandler() : SessionHandler{ + public function getHandler() : PacketHandler{ return $this->handler; } - public function setHandler(SessionHandler $handler) : void{ + public function setHandler(PacketHandler $handler) : void{ if($this->connected){ //TODO: this is fine since we can't handle anything from a disconnected session, but it might produce surprises in some cases $this->handler = $handler; $this->handler->setUp(); @@ -439,7 +439,7 @@ class NetworkSession{ $this->disconnectGuard = true; $func(); $this->disconnectGuard = false; - $this->setHandler(NullSessionHandler::getInstance()); + $this->setHandler(NullPacketHandler::getInstance()); $this->connected = false; $this->manager->remove($this); $this->logger->info("Session closed due to $reason"); @@ -554,7 +554,7 @@ class NetworkSession{ $this->cipher = new NetworkCipher($encryptionKey); - $this->setHandler(new HandshakeSessionHandler($this)); + $this->setHandler(new HandshakePacketHandler($this)); $this->logger->debug("Enabled encryption"); } @@ -564,13 +564,13 @@ class NetworkSession{ $this->sendDataPacket(PlayStatusPacket::create(PlayStatusPacket::LOGIN_SUCCESS)); $this->logger->debug("Initiating resource packs phase"); - $this->setHandler(new ResourcePacksSessionHandler($this, $this->server->getResourcePackManager())); + $this->setHandler(new ResourcePacksPacketHandler($this, $this->server->getResourcePackManager())); } public function onResourcePacksDone() : void{ $this->createPlayer(); - $this->setHandler(new PreSpawnSessionHandler($this->server, $this->player, $this)); + $this->setHandler(new PreSpawnPacketHandler($this->server, $this->player, $this)); $this->logger->debug("Waiting for spawn chunks"); } @@ -582,11 +582,11 @@ class NetworkSession{ public function onSpawn() : void{ $this->logger->debug("Received spawn response, entering in-game phase"); $this->player->doFirstSpawn(); - $this->setHandler(new InGameSessionHandler($this->player, $this)); + $this->setHandler(new InGamePacketHandler($this->player, $this)); } public function onDeath() : void{ - $this->setHandler(new DeathSessionHandler($this->player, $this)); + $this->setHandler(new DeathPacketHandler($this->player, $this)); } public function onRespawn() : void{ @@ -595,7 +595,7 @@ class NetworkSession{ $this->syncAdventureSettings($this->player); $this->syncAllInventoryContents(); - $this->setHandler(new InGameSessionHandler($this->player, $this)); + $this->setHandler(new InGamePacketHandler($this->player, $this)); } public function syncMovement(Vector3 $pos, ?float $yaw = null, ?float $pitch = null, int $mode = MovePlayerPacket::MODE_NORMAL) : void{ diff --git a/src/pocketmine/network/mcpe/handler/DeathSessionHandler.php b/src/pocketmine/network/mcpe/handler/DeathPacketHandler.php similarity index 97% rename from src/pocketmine/network/mcpe/handler/DeathSessionHandler.php rename to src/pocketmine/network/mcpe/handler/DeathPacketHandler.php index e7096d0aca..81b7e86ff3 100644 --- a/src/pocketmine/network/mcpe/handler/DeathSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/DeathPacketHandler.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\PlayerActionPacket; use pocketmine\network\mcpe\protocol\RespawnPacket; use pocketmine\Player; -class DeathSessionHandler extends SessionHandler{ +class DeathPacketHandler extends PacketHandler{ /** @var Player */ private $player; diff --git a/src/pocketmine/network/mcpe/handler/HandshakeSessionHandler.php b/src/pocketmine/network/mcpe/handler/HandshakePacketHandler.php similarity index 95% rename from src/pocketmine/network/mcpe/handler/HandshakeSessionHandler.php rename to src/pocketmine/network/mcpe/handler/HandshakePacketHandler.php index 8c2cb2be71..451351941a 100644 --- a/src/pocketmine/network/mcpe/handler/HandshakeSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/HandshakePacketHandler.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\ClientToServerHandshakePacket; /** * Handler responsible for awaiting client response from crypto handshake. */ -class HandshakeSessionHandler extends SessionHandler{ +class HandshakePacketHandler extends PacketHandler{ /** @var NetworkSession */ private $session; diff --git a/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php similarity index 99% rename from src/pocketmine/network/mcpe/handler/InGameSessionHandler.php rename to src/pocketmine/network/mcpe/handler/InGamePacketHandler.php index 76eb636c4f..25415d7590 100644 --- a/src/pocketmine/network/mcpe/handler/InGameSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php @@ -93,7 +93,7 @@ use function trim; /** * This handler handles packets related to general gameplay. */ -class InGameSessionHandler extends SessionHandler{ +class InGamePacketHandler extends PacketHandler{ /** @var Player */ private $player; diff --git a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php b/src/pocketmine/network/mcpe/handler/LoginPacketHandler.php similarity index 96% rename from src/pocketmine/network/mcpe/handler/LoginSessionHandler.php rename to src/pocketmine/network/mcpe/handler/LoginPacketHandler.php index 203e0f77a5..c9c4c19adb 100644 --- a/src/pocketmine/network/mcpe/handler/LoginSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/LoginPacketHandler.php @@ -40,7 +40,7 @@ use function base64_decode; /** * Handles the initial login phase of the session. This handler is used as the initial state. */ -class LoginSessionHandler extends SessionHandler{ +class LoginPacketHandler extends PacketHandler{ /** @var Server */ private $server; @@ -134,7 +134,7 @@ class LoginSessionHandler extends SessionHandler{ */ protected function processLogin(LoginPacket $packet, bool $authRequired) : void{ $this->server->getAsyncPool()->submitTask(new ProcessLoginTask($this->session, $packet, $authRequired, NetworkCipher::$ENABLED)); - $this->session->setHandler(NullSessionHandler::getInstance()); //drop packets received during login verification + $this->session->setHandler(NullPacketHandler::getInstance()); //drop packets received during login verification } protected function isCompatibleProtocol(int $protocolVersion) : bool{ diff --git a/src/pocketmine/network/mcpe/handler/NullSessionHandler.php b/src/pocketmine/network/mcpe/handler/NullPacketHandler.php similarity index 95% rename from src/pocketmine/network/mcpe/handler/NullSessionHandler.php rename to src/pocketmine/network/mcpe/handler/NullPacketHandler.php index ac61c359ef..17cbf200b3 100644 --- a/src/pocketmine/network/mcpe/handler/NullSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/NullPacketHandler.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\handler; /** * Handler which simply ignores all packets received. */ -final class NullSessionHandler extends SessionHandler{ +final class NullPacketHandler extends PacketHandler{ /** @var self|null */ private static $instance = null; diff --git a/src/pocketmine/network/mcpe/handler/SessionHandler.php b/src/pocketmine/network/mcpe/handler/PacketHandler.php similarity index 99% rename from src/pocketmine/network/mcpe/handler/SessionHandler.php rename to src/pocketmine/network/mcpe/handler/PacketHandler.php index d0c2053f9c..a552d73290 100644 --- a/src/pocketmine/network/mcpe/handler/SessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/PacketHandler.php @@ -155,7 +155,7 @@ use pocketmine\network\mcpe\protocol\VideoStreamConnectPacket; * * This class is an automatically generated stub. Do not edit it manually. */ -abstract class SessionHandler{ +abstract class PacketHandler{ public function setUp() : void{ diff --git a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php b/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php similarity index 98% rename from src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php rename to src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php index 63f8a11213..701c117b00 100644 --- a/src/pocketmine/network/mcpe/handler/PreSpawnSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php @@ -36,7 +36,7 @@ use pocketmine\Server; /** * Handler used for the pre-spawn phase of the session. */ -class PreSpawnSessionHandler extends SessionHandler{ +class PreSpawnPacketHandler extends PacketHandler{ /** @var Server */ private $server; diff --git a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php b/src/pocketmine/network/mcpe/handler/ResourcePacksPacketHandler.php similarity index 99% rename from src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php rename to src/pocketmine/network/mcpe/handler/ResourcePacksPacketHandler.php index d879f239b7..95ac7a2c6e 100644 --- a/src/pocketmine/network/mcpe/handler/ResourcePacksSessionHandler.php +++ b/src/pocketmine/network/mcpe/handler/ResourcePacksPacketHandler.php @@ -42,7 +42,7 @@ use function substr; * Handler used for the resource packs sequence phase of the session. This handler takes care of downloading resource * packs to the client. */ -class ResourcePacksSessionHandler extends SessionHandler{ +class ResourcePacksPacketHandler extends PacketHandler{ private const PACK_CHUNK_SIZE = 1048576; //1MB /** @var NetworkSession */ diff --git a/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php b/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php index 863880befa..0ce5e4dd4c 100644 --- a/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class AddBehaviorTreePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_BEHAVIOR_TREE_PACKET; @@ -41,7 +41,7 @@ class AddBehaviorTreePacket extends DataPacket implements ClientboundPacket{ $this->putString($this->behaviorTreeJson); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleAddBehaviorTree($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php b/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php index 56b95fcb23..3d2a170897 100644 --- a/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php @@ -29,7 +29,7 @@ use pocketmine\entity\Attribute; use pocketmine\entity\EntityIds; use pocketmine\math\Vector3; use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\EntityLink; use function array_search; use function count; @@ -239,7 +239,7 @@ class AddEntityPacket extends DataPacket implements ClientboundPacket{ } } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleAddEntity($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/AddItemEntityPacket.php b/src/pocketmine/network/mcpe/protocol/AddItemEntityPacket.php index 9ee9a2d10f..a42afad5b5 100644 --- a/src/pocketmine/network/mcpe/protocol/AddItemEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddItemEntityPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\item\Item; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class AddItemEntityPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_ITEM_ENTITY_PACKET; @@ -67,7 +67,7 @@ class AddItemEntityPacket extends DataPacket implements ClientboundPacket{ $this->putBool($this->isFromFishing); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleAddItemEntity($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/AddPaintingPacket.php b/src/pocketmine/network/mcpe/protocol/AddPaintingPacket.php index 53311713ca..4e28514749 100644 --- a/src/pocketmine/network/mcpe/protocol/AddPaintingPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddPaintingPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class AddPaintingPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_PAINTING_PACKET; @@ -62,7 +62,7 @@ class AddPaintingPacket extends DataPacket implements ClientboundPacket{ $this->putString($this->title); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleAddPainting($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php b/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php index 693009353f..cc2c172b50 100644 --- a/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\item\Item; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\EntityLink; use pocketmine\utils\UUID; use function count; @@ -135,7 +135,7 @@ class AddPlayerPacket extends DataPacket implements ClientboundPacket{ $this->putString($this->deviceId); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleAddPlayer($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php b/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php index 43eaa4e9f5..a1f76b5523 100644 --- a/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; class AdventureSettingsPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -116,7 +116,7 @@ class AdventureSettingsPacket extends DataPacket implements ClientboundPacket, S } } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleAdventureSettings($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/AnimatePacket.php b/src/pocketmine/network/mcpe/protocol/AnimatePacket.php index 86fc701247..a32ffe693a 100644 --- a/src/pocketmine/network/mcpe/protocol/AnimatePacket.php +++ b/src/pocketmine/network/mcpe/protocol/AnimatePacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class AnimatePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ANIMATE_PACKET; @@ -72,7 +72,7 @@ class AnimatePacket extends DataPacket implements ClientboundPacket, Serverbound } } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleAnimate($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/AutomationClientConnectPacket.php b/src/pocketmine/network/mcpe/protocol/AutomationClientConnectPacket.php index 518fc14298..ee968cff1c 100644 --- a/src/pocketmine/network/mcpe/protocol/AutomationClientConnectPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AutomationClientConnectPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class AutomationClientConnectPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::AUTOMATION_CLIENT_CONNECT_PACKET; @@ -41,7 +41,7 @@ class AutomationClientConnectPacket extends DataPacket implements ClientboundPac $this->putString($this->serverUri); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleAutomationClientConnect($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php index f89697fbb8..a1d165c21d 100644 --- a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\CommandData; use pocketmine\network\mcpe\protocol\types\CommandEnum; use pocketmine\network\mcpe\protocol\types\CommandParameter; @@ -412,7 +412,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ } } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleAvailableCommands($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/AvailableEntityIdentifiersPacket.php b/src/pocketmine/network/mcpe/protocol/AvailableEntityIdentifiersPacket.php index d84bef9fce..a95215d770 100644 --- a/src/pocketmine/network/mcpe/protocol/AvailableEntityIdentifiersPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AvailableEntityIdentifiersPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use function base64_decode; class AvailableEntityIdentifiersPacket extends DataPacket implements ClientboundPacket{ @@ -47,7 +47,7 @@ class AvailableEntityIdentifiersPacket extends DataPacket implements Clientbound $this->put($this->namedtag ?? base64_decode(self::HARDCODED_NBT_BLOB)); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleAvailableEntityIdentifiers($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/BiomeDefinitionListPacket.php b/src/pocketmine/network/mcpe/protocol/BiomeDefinitionListPacket.php index 8027548ec4..eac86fcdc8 100644 --- a/src/pocketmine/network/mcpe/protocol/BiomeDefinitionListPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BiomeDefinitionListPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class BiomeDefinitionListPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::BIOME_DEFINITION_LIST_PACKET; @@ -42,7 +42,7 @@ class BiomeDefinitionListPacket extends DataPacket implements ClientboundPacket{ $this->put($this->namedtag ?? self::HARDCODED_NBT_BLOB); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleBiomeDefinitionList($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php b/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php index c60faaca54..1024193239 100644 --- a/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BlockEntityDataPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class BlockEntityDataPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::BLOCK_ENTITY_DATA_PACKET; @@ -57,7 +57,7 @@ class BlockEntityDataPacket extends DataPacket implements ClientboundPacket, Ser $this->put($this->namedtag); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleBlockEntityData($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php b/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php index 58dae3a629..9badd3036e 100644 --- a/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class BlockEventPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::BLOCK_EVENT_PACKET; @@ -65,7 +65,7 @@ class BlockEventPacket extends DataPacket implements ClientboundPacket{ $this->putVarInt($this->eventData); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleBlockEvent($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php b/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php index 8bd44a7259..cc6ea483e3 100644 --- a/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class BlockPickRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::BLOCK_PICK_REQUEST_PACKET; @@ -55,7 +55,7 @@ class BlockPickRequestPacket extends DataPacket implements ServerboundPacket{ $this->putByte($this->hotbarSlot); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleBlockPickRequest($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/BookEditPacket.php b/src/pocketmine/network/mcpe/protocol/BookEditPacket.php index 38eed556a9..4d54cf8cb2 100644 --- a/src/pocketmine/network/mcpe/protocol/BookEditPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BookEditPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class BookEditPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::BOOK_EDIT_PACKET; @@ -114,7 +114,7 @@ class BookEditPacket extends DataPacket implements ServerboundPacket{ } } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleBookEdit($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/BossEventPacket.php b/src/pocketmine/network/mcpe/protocol/BossEventPacket.php index 3b58f3387f..dcd33587b5 100644 --- a/src/pocketmine/network/mcpe/protocol/BossEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BossEventPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class BossEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::BOSS_EVENT_PACKET; @@ -177,7 +177,7 @@ class BossEventPacket extends DataPacket implements ClientboundPacket, Serverbou } } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleBossEvent($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/CameraPacket.php b/src/pocketmine/network/mcpe/protocol/CameraPacket.php index ddca6dd15c..06ce1cd034 100644 --- a/src/pocketmine/network/mcpe/protocol/CameraPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CameraPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class CameraPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CAMERA_PACKET; @@ -45,7 +45,7 @@ class CameraPacket extends DataPacket implements ClientboundPacket{ $this->putEntityUniqueId($this->playerUniqueId); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleCamera($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ChangeDimensionPacket.php b/src/pocketmine/network/mcpe/protocol/ChangeDimensionPacket.php index 6e13a72967..95b66d4d40 100644 --- a/src/pocketmine/network/mcpe/protocol/ChangeDimensionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ChangeDimensionPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class ChangeDimensionPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CHANGE_DIMENSION_PACKET; @@ -51,7 +51,7 @@ class ChangeDimensionPacket extends DataPacket implements ClientboundPacket{ $this->putBool($this->respawn); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleChangeDimension($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php b/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php index 8dfd370807..3ff77d51ad 100644 --- a/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class ChunkRadiusUpdatedPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CHUNK_RADIUS_UPDATED_PACKET; @@ -48,7 +48,7 @@ class ChunkRadiusUpdatedPacket extends DataPacket implements ClientboundPacket{ $this->putVarInt($this->radius); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleChunkRadiusUpdated($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ClientToServerHandshakePacket.php b/src/pocketmine/network/mcpe/protocol/ClientToServerHandshakePacket.php index e744ff0ff5..99e2d0545d 100644 --- a/src/pocketmine/network/mcpe/protocol/ClientToServerHandshakePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ClientToServerHandshakePacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class ClientToServerHandshakePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::CLIENT_TO_SERVER_HANDSHAKE_PACKET; @@ -43,7 +43,7 @@ class ClientToServerHandshakePacket extends DataPacket implements ServerboundPac //No payload } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleClientToServerHandshake($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php b/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php index b7070cd639..503fec5307 100644 --- a/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php @@ -28,7 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\protocol\types\MapTrackedObject; use pocketmine\utils\Color; @@ -207,7 +207,7 @@ class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPack } } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleClientboundMapItemData($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php b/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php index bdb04ce4ae..818b312ade 100644 --- a/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php +++ b/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class CommandBlockUpdatePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::COMMAND_BLOCK_UPDATE_PACKET; @@ -99,7 +99,7 @@ class CommandBlockUpdatePacket extends DataPacket implements ServerboundPacket{ $this->putBool($this->shouldTrackOutput); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleCommandBlockUpdate($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php b/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php index e310b0ac0c..b05450d28e 100644 --- a/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\CommandOriginData; use pocketmine\network\mcpe\protocol\types\CommandOutputMessage; use pocketmine\utils\BinaryDataException; @@ -101,7 +101,7 @@ class CommandOutputPacket extends DataPacket implements ClientboundPacket{ } } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleCommandOutput($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/CommandRequestPacket.php b/src/pocketmine/network/mcpe/protocol/CommandRequestPacket.php index cdb5d7577e..a0d009a032 100644 --- a/src/pocketmine/network/mcpe/protocol/CommandRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CommandRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\CommandOriginData; class CommandRequestPacket extends DataPacket implements ServerboundPacket{ @@ -50,7 +50,7 @@ class CommandRequestPacket extends DataPacket implements ServerboundPacket{ $this->putBool($this->isInternal); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleCommandRequest($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php b/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php index 5cc9351680..d60ae79520 100644 --- a/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class ContainerClosePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::CONTAINER_CLOSE_PACKET; @@ -48,7 +48,7 @@ class ContainerClosePacket extends DataPacket implements ClientboundPacket, Serv $this->putByte($this->windowId); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleContainerClose($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php b/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php index de24c60556..3addd12bbe 100644 --- a/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class ContainerOpenPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CONTAINER_OPEN_PACKET; @@ -74,7 +74,7 @@ class ContainerOpenPacket extends DataPacket implements ClientboundPacket{ $this->putEntityUniqueId($this->entityUniqueId); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleContainerOpen($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php b/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php index 46cb1b9206..1782b66f54 100644 --- a/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class ContainerSetDataPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CONTAINER_SET_DATA_PACKET; @@ -68,7 +68,7 @@ class ContainerSetDataPacket extends DataPacket implements ClientboundPacket{ $this->putVarInt($this->value); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleContainerSetData($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php b/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php index cfbcf8ddb4..910c863dc5 100644 --- a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php @@ -32,7 +32,7 @@ use pocketmine\inventory\ShapelessRecipe; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\NetworkBinaryStream; use function count; use function str_repeat; @@ -226,7 +226,7 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{ $this->putBool($this->cleanRecipes); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleCraftingData($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/CraftingEventPacket.php b/src/pocketmine/network/mcpe/protocol/CraftingEventPacket.php index 62df967533..53371d75ed 100644 --- a/src/pocketmine/network/mcpe/protocol/CraftingEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CraftingEventPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\item\Item; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\utils\UUID; use function count; @@ -76,7 +76,7 @@ class CraftingEventPacket extends DataPacket implements ServerboundPacket{ } } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleCraftingEvent($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php b/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php index 513f8f8ec1..d026193417 100644 --- a/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php +++ b/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class DisconnectPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::DISCONNECT_PACKET; @@ -67,7 +67,7 @@ class DisconnectPacket extends DataPacket implements ClientboundPacket, Serverbo } } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleDisconnect($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php b/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php index 86e33d3bec..6e84401afb 100644 --- a/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/EntityEventPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class EntityEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ENTITY_EVENT_PACKET; @@ -110,7 +110,7 @@ class EntityEventPacket extends DataPacket implements ClientboundPacket, Serverb $this->putVarInt($this->data); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleEntityEvent($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/EntityFallPacket.php b/src/pocketmine/network/mcpe/protocol/EntityFallPacket.php index 0eede0be9c..d457d56c00 100644 --- a/src/pocketmine/network/mcpe/protocol/EntityFallPacket.php +++ b/src/pocketmine/network/mcpe/protocol/EntityFallPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class EntityFallPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ENTITY_FALL_PACKET; @@ -50,7 +50,7 @@ class EntityFallPacket extends DataPacket implements ServerboundPacket{ $this->putBool($this->isInVoid); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleEntityFall($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/EntityPickRequestPacket.php b/src/pocketmine/network/mcpe/protocol/EntityPickRequestPacket.php index bb167e3d05..8e43cd30a7 100644 --- a/src/pocketmine/network/mcpe/protocol/EntityPickRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/EntityPickRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class EntityPickRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ENTITY_PICK_REQUEST_PACKET; @@ -45,7 +45,7 @@ class EntityPickRequestPacket extends DataPacket implements ServerboundPacket{ $this->putByte($this->hotbarSlot); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleEntityPickRequest($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/EventPacket.php b/src/pocketmine/network/mcpe/protocol/EventPacket.php index 67a518af67..56786952d7 100644 --- a/src/pocketmine/network/mcpe/protocol/EventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/EventPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class EventPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::EVENT_PACKET; @@ -67,7 +67,7 @@ class EventPacket extends DataPacket implements ClientboundPacket{ //TODO: also nice confusing mess } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleEvent($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ExplodePacket.php b/src/pocketmine/network/mcpe/protocol/ExplodePacket.php index c1f4f813fd..189c9ff8c6 100644 --- a/src/pocketmine/network/mcpe/protocol/ExplodePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ExplodePacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use function count; class ExplodePacket extends DataPacket implements ClientboundPacket{ @@ -77,7 +77,7 @@ class ExplodePacket extends DataPacket implements ClientboundPacket{ } } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleExplode($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/FullChunkDataPacket.php b/src/pocketmine/network/mcpe/protocol/FullChunkDataPacket.php index abe1c936ad..f3f2300c21 100644 --- a/src/pocketmine/network/mcpe/protocol/FullChunkDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/FullChunkDataPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class FullChunkDataPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::FULL_CHUNK_DATA_PACKET; @@ -58,7 +58,7 @@ class FullChunkDataPacket extends DataPacket implements ClientboundPacket{ $this->putString($this->data); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleFullChunkData($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/GameRulesChangedPacket.php b/src/pocketmine/network/mcpe/protocol/GameRulesChangedPacket.php index c6d9ce4880..d53082b9d7 100644 --- a/src/pocketmine/network/mcpe/protocol/GameRulesChangedPacket.php +++ b/src/pocketmine/network/mcpe/protocol/GameRulesChangedPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class GameRulesChangedPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::GAME_RULES_CHANGED_PACKET; @@ -41,7 +41,7 @@ class GameRulesChangedPacket extends DataPacket implements ClientboundPacket{ $this->putGameRules($this->gameRules); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleGameRulesChanged($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/GuiDataPickItemPacket.php b/src/pocketmine/network/mcpe/protocol/GuiDataPickItemPacket.php index 58ddf7810a..cdba42aaef 100644 --- a/src/pocketmine/network/mcpe/protocol/GuiDataPickItemPacket.php +++ b/src/pocketmine/network/mcpe/protocol/GuiDataPickItemPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class GuiDataPickItemPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::GUI_DATA_PICK_ITEM_PACKET; @@ -49,7 +49,7 @@ class GuiDataPickItemPacket extends DataPacket implements ClientboundPacket{ $this->putLInt($this->hotbarSlot); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleGuiDataPickItem($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/HurtArmorPacket.php b/src/pocketmine/network/mcpe/protocol/HurtArmorPacket.php index a4d01bc453..6dbef6649c 100644 --- a/src/pocketmine/network/mcpe/protocol/HurtArmorPacket.php +++ b/src/pocketmine/network/mcpe/protocol/HurtArmorPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class HurtArmorPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::HURT_ARMOR_PACKET; @@ -42,7 +42,7 @@ class HurtArmorPacket extends DataPacket implements ClientboundPacket{ $this->putVarInt($this->health); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleHurtArmor($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/InteractPacket.php b/src/pocketmine/network/mcpe/protocol/InteractPacket.php index 10a87d787c..5ae4d1fe87 100644 --- a/src/pocketmine/network/mcpe/protocol/InteractPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InteractPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class InteractPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::INTERACT_PACKET; @@ -71,7 +71,7 @@ class InteractPacket extends DataPacket implements ServerboundPacket{ } } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleInteract($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php b/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php index 2db67c3cc8..5aaa29b15c 100644 --- a/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\item\Item; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use function count; class InventoryContentPacket extends DataPacket implements ClientboundPacket{ @@ -66,7 +66,7 @@ class InventoryContentPacket extends DataPacket implements ClientboundPacket{ } } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleInventoryContent($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php b/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php index e34adbeba0..5fc2f76c97 100644 --- a/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\item\Item; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class InventorySlotPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::INVENTORY_SLOT_PACKET; @@ -58,7 +58,7 @@ class InventorySlotPacket extends DataPacket implements ClientboundPacket{ $this->putSlot($this->item); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleInventorySlot($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php b/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php index 4e009d1c8e..9eed4cd8f9 100644 --- a/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\MismatchTransactionData; use pocketmine\network\mcpe\protocol\types\NormalTransactionData; use pocketmine\network\mcpe\protocol\types\ReleaseItemTransactionData; @@ -80,7 +80,7 @@ class InventoryTransactionPacket extends DataPacket implements ClientboundPacket $this->trData->encode($this); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleInventoryTransaction($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ItemFrameDropItemPacket.php b/src/pocketmine/network/mcpe/protocol/ItemFrameDropItemPacket.php index 8890149cda..c0a16b1eeb 100644 --- a/src/pocketmine/network/mcpe/protocol/ItemFrameDropItemPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ItemFrameDropItemPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class ItemFrameDropItemPacket extends DataPacket implements ServerboundPacket{ @@ -46,7 +46,7 @@ class ItemFrameDropItemPacket extends DataPacket implements ServerboundPacket{ $this->putBlockPosition($this->x, $this->y, $this->z); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleItemFrameDropItem($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/LabTablePacket.php b/src/pocketmine/network/mcpe/protocol/LabTablePacket.php index f873853111..70e0640cf9 100644 --- a/src/pocketmine/network/mcpe/protocol/LabTablePacket.php +++ b/src/pocketmine/network/mcpe/protocol/LabTablePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class LabTablePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::LAB_TABLE_PACKET; @@ -55,7 +55,7 @@ class LabTablePacket extends DataPacket implements ClientboundPacket, Serverboun $this->putByte($this->reactionType); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleLabTable($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/LecternUpdatePacket.php b/src/pocketmine/network/mcpe/protocol/LecternUpdatePacket.php index e6333142d7..a3ddf31d57 100644 --- a/src/pocketmine/network/mcpe/protocol/LecternUpdatePacket.php +++ b/src/pocketmine/network/mcpe/protocol/LecternUpdatePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class LecternUpdatePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::LECTERN_UPDATE_PACKET; @@ -57,7 +57,7 @@ class LecternUpdatePacket extends DataPacket implements ServerboundPacket{ $this->putBool($this->dropBook); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleLecternUpdate($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php b/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php index 9d22547263..d05402fe4c 100644 --- a/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class LevelEventPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::LEVEL_EVENT_PACKET; @@ -141,7 +141,7 @@ class LevelEventPacket extends DataPacket implements ClientboundPacket{ $this->putVarInt($this->data); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleLevelEvent($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacket.php b/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacket.php index 086069d91e..957e4da4b7 100644 --- a/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class LevelSoundEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::LEVEL_SOUND_EVENT_PACKET; @@ -346,7 +346,7 @@ class LevelSoundEventPacket extends DataPacket implements ClientboundPacket, Ser $this->putBool($this->disableRelativeVolume); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleLevelSoundEvent($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacketV1.php b/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacketV1.php index 28ad585bb4..ae45de3e4b 100644 --- a/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacketV1.php +++ b/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacketV1.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; /** * Useless leftover from a 1.8 refactor, does nothing @@ -65,7 +65,7 @@ class LevelSoundEventPacketV1 extends DataPacket{ $this->putBool($this->disableRelativeVolume); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleLevelSoundEventPacketV1($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacketV2.php b/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacketV2.php index c7a7d58e08..d540c4111f 100644 --- a/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacketV2.php +++ b/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacketV2.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; /** * Useless leftover from a 1.9 refactor, does nothing @@ -65,7 +65,7 @@ class LevelSoundEventPacketV2 extends DataPacket{ $this->putBool($this->disableRelativeVolume); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleLevelSoundEventPacketV2($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/LoginPacket.php b/src/pocketmine/network/mcpe/protocol/LoginPacket.php index 9deef9bb43..0031a20ea1 100644 --- a/src/pocketmine/network/mcpe/protocol/LoginPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LoginPacket.php @@ -28,7 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use Particle\Validator\Validator; use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; use pocketmine\utils\Utils; @@ -178,7 +178,7 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ //TODO } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleLogin($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/MapCreateLockedCopyPacket.php b/src/pocketmine/network/mcpe/protocol/MapCreateLockedCopyPacket.php index fd65e8f423..92b8e9d461 100644 --- a/src/pocketmine/network/mcpe/protocol/MapCreateLockedCopyPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MapCreateLockedCopyPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class MapCreateLockedCopyPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MAP_CREATE_LOCKED_COPY_PACKET; @@ -45,7 +45,7 @@ class MapCreateLockedCopyPacket extends DataPacket implements ServerboundPacket{ $this->putEntityUniqueId($this->newMapId); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleMapCreateLockedCopy($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/MapInfoRequestPacket.php b/src/pocketmine/network/mcpe/protocol/MapInfoRequestPacket.php index b6500c36ff..a1bc4144fe 100644 --- a/src/pocketmine/network/mcpe/protocol/MapInfoRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MapInfoRequestPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class MapInfoRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MAP_INFO_REQUEST_PACKET; @@ -43,7 +43,7 @@ class MapInfoRequestPacket extends DataPacket implements ServerboundPacket{ $this->putEntityUniqueId($this->mapId); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleMapInfoRequest($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php b/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php index 0888c9f2fc..38f9305c5a 100644 --- a/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\item\Item; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class MobArmorEquipmentPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MOB_ARMOR_EQUIPMENT_PACKET; @@ -72,7 +72,7 @@ class MobArmorEquipmentPacket extends DataPacket implements ClientboundPacket, S $this->putSlot($this->feet); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleMobArmorEquipment($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php b/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php index 108b57ad70..15c8c8a39c 100644 --- a/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class MobEffectPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::MOB_EFFECT_PACKET; @@ -85,7 +85,7 @@ class MobEffectPacket extends DataPacket implements ClientboundPacket{ $this->putVarInt($this->duration); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleMobEffect($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php b/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php index 9676e966f7..d4cad955de 100644 --- a/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\item\Item; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class MobEquipmentPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MOB_EQUIPMENT_PACKET; @@ -69,7 +69,7 @@ class MobEquipmentPacket extends DataPacket implements ClientboundPacket, Server $this->putByte($this->windowId); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleMobEquipment($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php b/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php index cd1c9d42a4..b60fb8cdf7 100644 --- a/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class ModalFormRequestPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::MODAL_FORM_REQUEST_PACKET; @@ -52,7 +52,7 @@ class ModalFormRequestPacket extends DataPacket implements ClientboundPacket{ $this->putString($this->formData); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleModalFormRequest($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ModalFormResponsePacket.php b/src/pocketmine/network/mcpe/protocol/ModalFormResponsePacket.php index 0ed1a2064a..f97a7c0c33 100644 --- a/src/pocketmine/network/mcpe/protocol/ModalFormResponsePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ModalFormResponsePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class ModalFormResponsePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MODAL_FORM_RESPONSE_PACKET; @@ -45,7 +45,7 @@ class ModalFormResponsePacket extends DataPacket implements ServerboundPacket{ $this->putString($this->formData); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleModalFormResponse($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/MoveEntityAbsolutePacket.php b/src/pocketmine/network/mcpe/protocol/MoveEntityAbsolutePacket.php index 63d550f16d..d0e220e8be 100644 --- a/src/pocketmine/network/mcpe/protocol/MoveEntityAbsolutePacket.php +++ b/src/pocketmine/network/mcpe/protocol/MoveEntityAbsolutePacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class MoveEntityAbsolutePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MOVE_ENTITY_ABSOLUTE_PACKET; @@ -66,7 +66,7 @@ class MoveEntityAbsolutePacket extends DataPacket implements ClientboundPacket, $this->putByteRotation($this->zRot); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleMoveEntityAbsolute($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/MoveEntityDeltaPacket.php b/src/pocketmine/network/mcpe/protocol/MoveEntityDeltaPacket.php index 929b9f8318..0b18512021 100644 --- a/src/pocketmine/network/mcpe/protocol/MoveEntityDeltaPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MoveEntityDeltaPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\utils\BinaryDataException; class MoveEntityDeltaPacket extends DataPacket implements ClientboundPacket{ @@ -115,7 +115,7 @@ class MoveEntityDeltaPacket extends DataPacket implements ClientboundPacket{ $this->maybeWriteRotation(self::FLAG_HAS_ROT_Z, $this->zRot); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleMoveEntityDelta($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/MovePlayerPacket.php b/src/pocketmine/network/mcpe/protocol/MovePlayerPacket.php index 801e6de923..6f6c6c06f7 100644 --- a/src/pocketmine/network/mcpe/protocol/MovePlayerPacket.php +++ b/src/pocketmine/network/mcpe/protocol/MovePlayerPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class MovePlayerPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MOVE_PLAYER_PACKET; @@ -88,7 +88,7 @@ class MovePlayerPacket extends DataPacket implements ClientboundPacket, Serverbo } } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleMovePlayer($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php b/src/pocketmine/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php index 1d39454d64..fc78a0b9f1 100644 --- a/src/pocketmine/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php +++ b/src/pocketmine/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class NetworkChunkPublisherUpdatePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::NETWORK_CHUNK_PUBLISHER_UPDATE_PACKET; @@ -58,7 +58,7 @@ class NetworkChunkPublisherUpdatePacket extends DataPacket implements Clientboun $this->putUnsignedVarInt($this->radius); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleNetworkChunkPublisherUpdate($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/NetworkStackLatencyPacket.php b/src/pocketmine/network/mcpe/protocol/NetworkStackLatencyPacket.php index 454b730550..27add3d3c2 100644 --- a/src/pocketmine/network/mcpe/protocol/NetworkStackLatencyPacket.php +++ b/src/pocketmine/network/mcpe/protocol/NetworkStackLatencyPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class NetworkStackLatencyPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::NETWORK_STACK_LATENCY_PACKET; @@ -45,7 +45,7 @@ class NetworkStackLatencyPacket extends DataPacket implements ClientboundPacket, $this->putBool($this->needResponse); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleNetworkStackLatency($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/NpcRequestPacket.php b/src/pocketmine/network/mcpe/protocol/NpcRequestPacket.php index d0a33b902a..7e9e6c69aa 100644 --- a/src/pocketmine/network/mcpe/protocol/NpcRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/NpcRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class NpcRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::NPC_REQUEST_PACKET; @@ -53,7 +53,7 @@ class NpcRequestPacket extends DataPacket implements ServerboundPacket{ $this->putByte($this->actionType); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleNpcRequest($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/OnScreenTextureAnimationPacket.php b/src/pocketmine/network/mcpe/protocol/OnScreenTextureAnimationPacket.php index e98fda2922..e4cf449404 100644 --- a/src/pocketmine/network/mcpe/protocol/OnScreenTextureAnimationPacket.php +++ b/src/pocketmine/network/mcpe/protocol/OnScreenTextureAnimationPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class OnScreenTextureAnimationPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ON_SCREEN_TEXTURE_ANIMATION_PACKET; @@ -41,7 +41,7 @@ class OnScreenTextureAnimationPacket extends DataPacket implements ClientboundPa $this->putLInt($this->effectId); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleOnScreenTextureAnimation($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/Packet.php b/src/pocketmine/network/mcpe/protocol/Packet.php index 71bd3a5c4f..2c754240ab 100644 --- a/src/pocketmine/network/mcpe/protocol/Packet.php +++ b/src/pocketmine/network/mcpe/protocol/Packet.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; interface Packet{ @@ -62,13 +62,13 @@ interface Packet{ * This method returns a bool to indicate whether the packet was handled or not. If the packet was unhandled, a * debug message will be logged with a hexdump of the packet. * - * Typically this method returns the return value of the handler in the supplied SessionHandler. See other packets + * Typically this method returns the return value of the handler in the supplied PacketHandler. See other packets * for examples how to implement this. * - * @param SessionHandler $handler + * @param PacketHandler $handler * * @return bool true if the packet was handled successfully, false if not. * @throws BadPacketException if broken data was found in the packet */ - public function handle(SessionHandler $handler) : bool; + public function handle(PacketHandler $handler) : bool; } diff --git a/src/pocketmine/network/mcpe/protocol/PhotoTransferPacket.php b/src/pocketmine/network/mcpe/protocol/PhotoTransferPacket.php index c278adc62d..cf32d1472e 100644 --- a/src/pocketmine/network/mcpe/protocol/PhotoTransferPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PhotoTransferPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class PhotoTransferPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::PHOTO_TRANSFER_PACKET; @@ -49,7 +49,7 @@ class PhotoTransferPacket extends DataPacket implements ClientboundPacket{ $this->putString($this->bookId); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handlePhotoTransfer($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/PlaySoundPacket.php b/src/pocketmine/network/mcpe/protocol/PlaySoundPacket.php index 4fe95ae5cd..952a97fb85 100644 --- a/src/pocketmine/network/mcpe/protocol/PlaySoundPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlaySoundPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class PlaySoundPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAY_SOUND_PACKET; @@ -62,7 +62,7 @@ class PlaySoundPacket extends DataPacket implements ClientboundPacket{ $this->putLFloat($this->pitch); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handlePlaySound($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php b/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php index f2c435461a..9084a3fa2c 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class PlayStatusPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAY_STATUS_PACKET; @@ -61,7 +61,7 @@ class PlayStatusPacket extends DataPacket implements ClientboundPacket{ $this->putInt($this->status); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handlePlayStatus($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/PlayerActionPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerActionPacket.php index a4d6af775c..2d9e662e4d 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerActionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerActionPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class PlayerActionPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAYER_ACTION_PACKET; @@ -84,7 +84,7 @@ class PlayerActionPacket extends DataPacket implements ServerboundPacket{ $this->putVarInt($this->face); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handlePlayerAction($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php index 2d6a310633..9cf8dc2f0c 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\ContainerIds; /** @@ -53,7 +53,7 @@ class PlayerHotbarPacket extends DataPacket implements ClientboundPacket, Server $this->putBool($this->selectHotbarSlot); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handlePlayerHotbar($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/PlayerInputPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerInputPacket.php index f2e4a69ea9..1d4fd0b97c 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerInputPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerInputPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class PlayerInputPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAYER_INPUT_PACKET; @@ -54,7 +54,7 @@ class PlayerInputPacket extends DataPacket implements ServerboundPacket{ $this->putBool($this->sneaking); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handlePlayerInput($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php index 1e8b781438..3d171d5ebc 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php @@ -28,7 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\entity\Skin; use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use function count; @@ -116,7 +116,7 @@ class PlayerListPacket extends DataPacket implements ClientboundPacket{ } } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handlePlayerList($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php index e6c56bf209..1912c2de88 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\entity\Skin; use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\utils\UUID; class PlayerSkinPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -78,7 +78,7 @@ class PlayerSkinPacket extends DataPacket implements ClientboundPacket, Serverbo $this->putBool($this->premiumSkin); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handlePlayerSkin($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php b/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php index f34a5535e6..8b6b02b868 100644 --- a/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use function count; class PurchaseReceiptPacket extends DataPacket implements ServerboundPacket{ @@ -48,7 +48,7 @@ class PurchaseReceiptPacket extends DataPacket implements ServerboundPacket{ } } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handlePurchaseReceipt($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php b/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php index e9b1c32cc2..956a9f0635 100644 --- a/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class RemoveEntityPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::REMOVE_ENTITY_PACKET; @@ -48,7 +48,7 @@ class RemoveEntityPacket extends DataPacket implements ClientboundPacket{ $this->putEntityUniqueId($this->entityUniqueId); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleRemoveEntity($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/RemoveObjectivePacket.php b/src/pocketmine/network/mcpe/protocol/RemoveObjectivePacket.php index 13872bfd82..e05e1ed33c 100644 --- a/src/pocketmine/network/mcpe/protocol/RemoveObjectivePacket.php +++ b/src/pocketmine/network/mcpe/protocol/RemoveObjectivePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class RemoveObjectivePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::REMOVE_OBJECTIVE_PACKET; @@ -41,7 +41,7 @@ class RemoveObjectivePacket extends DataPacket implements ClientboundPacket{ $this->putString($this->objectiveName); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleRemoveObjective($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/RequestChunkRadiusPacket.php b/src/pocketmine/network/mcpe/protocol/RequestChunkRadiusPacket.php index 25117c3d4b..cc3caa251f 100644 --- a/src/pocketmine/network/mcpe/protocol/RequestChunkRadiusPacket.php +++ b/src/pocketmine/network/mcpe/protocol/RequestChunkRadiusPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class RequestChunkRadiusPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::REQUEST_CHUNK_RADIUS_PACKET; @@ -42,7 +42,7 @@ class RequestChunkRadiusPacket extends DataPacket implements ServerboundPacket{ $this->putVarInt($this->radius); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleRequestChunkRadius($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php index f51384d7f9..eb7ab7268f 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use function strlen; class ResourcePackChunkDataPacket extends DataPacket implements ClientboundPacket{ @@ -66,7 +66,7 @@ class ResourcePackChunkDataPacket extends DataPacket implements ClientboundPacke $this->put($this->data); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleResourcePackChunkData($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackChunkRequestPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackChunkRequestPacket.php index a343768eab..d414ba1b40 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackChunkRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackChunkRequestPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class ResourcePackChunkRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_CHUNK_REQUEST_PACKET; @@ -47,7 +47,7 @@ class ResourcePackChunkRequestPacket extends DataPacket implements ServerboundPa $this->putLInt($this->chunkIndex); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleResourcePackChunkRequest($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackClientResponsePacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackClientResponsePacket.php index d757441b4b..833c3982c3 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackClientResponsePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackClientResponsePacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use function count; class ResourcePackClientResponsePacket extends DataPacket implements ServerboundPacket{ @@ -58,7 +58,7 @@ class ResourcePackClientResponsePacket extends DataPacket implements Serverbound } } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleResourcePackClientResponse($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php index e28abefb7e..d4f773830e 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class ResourcePackDataInfoPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_DATA_INFO_PACKET; @@ -69,7 +69,7 @@ class ResourcePackDataInfoPacket extends DataPacket implements ClientboundPacket $this->putString($this->sha256); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleResourcePackDataInfo($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php index bc19caf011..ec8e604ea0 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\resourcepacks\ResourcePack; use function count; @@ -101,7 +101,7 @@ class ResourcePackStackPacket extends DataPacket implements ClientboundPacket{ $this->putBool($this->isExperimental); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleResourcePackStack($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php b/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php index 4a305d259a..5da110a683 100644 --- a/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\resourcepacks\ResourcePack; use function count; @@ -110,7 +110,7 @@ class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ } } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleResourcePacksInfo($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/RespawnPacket.php b/src/pocketmine/network/mcpe/protocol/RespawnPacket.php index b4f79446ad..2c739c7635 100644 --- a/src/pocketmine/network/mcpe/protocol/RespawnPacket.php +++ b/src/pocketmine/network/mcpe/protocol/RespawnPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class RespawnPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::RESPAWN_PACKET; @@ -49,7 +49,7 @@ class RespawnPacket extends DataPacket implements ClientboundPacket{ $this->putVector3($this->position); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleRespawn($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/RiderJumpPacket.php b/src/pocketmine/network/mcpe/protocol/RiderJumpPacket.php index 8b5f922c9f..fad394c4f8 100644 --- a/src/pocketmine/network/mcpe/protocol/RiderJumpPacket.php +++ b/src/pocketmine/network/mcpe/protocol/RiderJumpPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class RiderJumpPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::RIDER_JUMP_PACKET; @@ -43,7 +43,7 @@ class RiderJumpPacket extends DataPacket implements ServerboundPacket{ $this->putVarInt($this->jumpStrength); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleRiderJump($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ScriptCustomEventPacket.php b/src/pocketmine/network/mcpe/protocol/ScriptCustomEventPacket.php index 64301aff8f..999dad4f9f 100644 --- a/src/pocketmine/network/mcpe/protocol/ScriptCustomEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ScriptCustomEventPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class ScriptCustomEventPacket extends DataPacket{ //TODO: this doesn't have handlers in either client or server in the game as of 1.8 public const NETWORK_ID = ProtocolInfo::SCRIPT_CUSTOM_EVENT_PACKET; @@ -45,7 +45,7 @@ class ScriptCustomEventPacket extends DataPacket{ //TODO: this doesn't have hand $this->putString($this->eventData); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleScriptCustomEvent($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ServerSettingsRequestPacket.php b/src/pocketmine/network/mcpe/protocol/ServerSettingsRequestPacket.php index 003c02b8e1..53243e44da 100644 --- a/src/pocketmine/network/mcpe/protocol/ServerSettingsRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ServerSettingsRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class ServerSettingsRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SERVER_SETTINGS_REQUEST_PACKET; @@ -38,7 +38,7 @@ class ServerSettingsRequestPacket extends DataPacket implements ServerboundPacke //No payload } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleServerSettingsRequest($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ServerSettingsResponsePacket.php b/src/pocketmine/network/mcpe/protocol/ServerSettingsResponsePacket.php index e05b02c138..9bff90f314 100644 --- a/src/pocketmine/network/mcpe/protocol/ServerSettingsResponsePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ServerSettingsResponsePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class ServerSettingsResponsePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SERVER_SETTINGS_RESPONSE_PACKET; @@ -45,7 +45,7 @@ class ServerSettingsResponsePacket extends DataPacket implements ClientboundPack $this->putString($this->formData); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleServerSettingsResponse($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php b/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php index 1759999ead..78ce6ad827 100644 --- a/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class ServerToClientHandshakePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SERVER_TO_CLIENT_HANDSHAKE_PACKET; @@ -55,7 +55,7 @@ class ServerToClientHandshakePacket extends DataPacket implements ClientboundPac $this->putString($this->jwt); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleServerToClientHandshake($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetCommandsEnabledPacket.php b/src/pocketmine/network/mcpe/protocol/SetCommandsEnabledPacket.php index 0f91d88cf3..986350d052 100644 --- a/src/pocketmine/network/mcpe/protocol/SetCommandsEnabledPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetCommandsEnabledPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class SetCommandsEnabledPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_COMMANDS_ENABLED_PACKET; @@ -42,7 +42,7 @@ class SetCommandsEnabledPacket extends DataPacket implements ClientboundPacket{ $this->putBool($this->enabled); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleSetCommandsEnabled($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetDefaultGameTypePacket.php b/src/pocketmine/network/mcpe/protocol/SetDefaultGameTypePacket.php index 3fb28d4649..de16f014b7 100644 --- a/src/pocketmine/network/mcpe/protocol/SetDefaultGameTypePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetDefaultGameTypePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class SetDefaultGameTypePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_DEFAULT_GAME_TYPE_PACKET; @@ -41,7 +41,7 @@ class SetDefaultGameTypePacket extends DataPacket implements ClientboundPacket, $this->putUnsignedVarInt($this->gamemode); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleSetDefaultGameType($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetDifficultyPacket.php b/src/pocketmine/network/mcpe/protocol/SetDifficultyPacket.php index 79f71b10a4..cec01b77d8 100644 --- a/src/pocketmine/network/mcpe/protocol/SetDifficultyPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetDifficultyPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class SetDifficultyPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_DIFFICULTY_PACKET; @@ -42,7 +42,7 @@ class SetDifficultyPacket extends DataPacket implements ClientboundPacket, Serve $this->putUnsignedVarInt($this->difficulty); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleSetDifficulty($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetDisplayObjectivePacket.php b/src/pocketmine/network/mcpe/protocol/SetDisplayObjectivePacket.php index ed9406f16e..9a0ba7bacf 100644 --- a/src/pocketmine/network/mcpe/protocol/SetDisplayObjectivePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetDisplayObjectivePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class SetDisplayObjectivePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_DISPLAY_OBJECTIVE_PACKET; @@ -57,7 +57,7 @@ class SetDisplayObjectivePacket extends DataPacket implements ClientboundPacket{ $this->putVarInt($this->sortOrder); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleSetDisplayObjective($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetEntityDataPacket.php b/src/pocketmine/network/mcpe/protocol/SetEntityDataPacket.php index d92cb057a4..8a329f4c3a 100644 --- a/src/pocketmine/network/mcpe/protocol/SetEntityDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetEntityDataPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class SetEntityDataPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ //TODO: check why this is serverbound public const NETWORK_ID = ProtocolInfo::SET_ENTITY_DATA_PACKET; @@ -53,7 +53,7 @@ class SetEntityDataPacket extends DataPacket implements ClientboundPacket, Serve $this->putEntityMetadata($this->metadata); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleSetEntityData($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetEntityLinkPacket.php b/src/pocketmine/network/mcpe/protocol/SetEntityLinkPacket.php index 58667275bf..d0ddf70540 100644 --- a/src/pocketmine/network/mcpe/protocol/SetEntityLinkPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetEntityLinkPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\EntityLink; class SetEntityLinkPacket extends DataPacket implements ClientboundPacket{ @@ -43,7 +43,7 @@ class SetEntityLinkPacket extends DataPacket implements ClientboundPacket{ $this->putEntityLink($this->link); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleSetEntityLink($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php b/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php index 451483893b..3901baeacd 100644 --- a/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetEntityMotionPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; /** * TODO: This packet is (erroneously) sent to the server when the client is riding a vehicle. @@ -57,7 +57,7 @@ class SetEntityMotionPacket extends DataPacket implements ClientboundPacket, Gar $this->putVector3($this->motion); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleSetEntityMotion($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetHealthPacket.php b/src/pocketmine/network/mcpe/protocol/SetHealthPacket.php index afb40982f4..e11b05a84c 100644 --- a/src/pocketmine/network/mcpe/protocol/SetHealthPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetHealthPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class SetHealthPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_HEALTH_PACKET; @@ -42,7 +42,7 @@ class SetHealthPacket extends DataPacket implements ClientboundPacket{ $this->putVarInt($this->health); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleSetHealth($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetLastHurtByPacket.php b/src/pocketmine/network/mcpe/protocol/SetLastHurtByPacket.php index e8fb632d30..ab2b703e01 100644 --- a/src/pocketmine/network/mcpe/protocol/SetLastHurtByPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetLastHurtByPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class SetLastHurtByPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_LAST_HURT_BY_PACKET; @@ -41,7 +41,7 @@ class SetLastHurtByPacket extends DataPacket implements ClientboundPacket{ $this->putVarInt($this->entityTypeId); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleSetLastHurtBy($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php b/src/pocketmine/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php index 5f278a286a..7b15c525ba 100644 --- a/src/pocketmine/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class SetLocalPlayerAsInitializedPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_LOCAL_PLAYER_AS_INITIALIZED_PACKET; @@ -41,7 +41,7 @@ class SetLocalPlayerAsInitializedPacket extends DataPacket implements Serverboun $this->putEntityRuntimeId($this->entityRuntimeId); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleSetLocalPlayerAsInitialized($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php b/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php index 6e16527736..5385ec6a53 100644 --- a/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class SetPlayerGameTypePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_PLAYER_GAME_TYPE_PACKET; @@ -48,7 +48,7 @@ class SetPlayerGameTypePacket extends DataPacket implements ClientboundPacket, S $this->putVarInt($this->gamemode); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleSetPlayerGameType($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetScorePacket.php b/src/pocketmine/network/mcpe/protocol/SetScorePacket.php index f0a912deef..9caa3e04e9 100644 --- a/src/pocketmine/network/mcpe/protocol/SetScorePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetScorePacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\ScorePacketEntry; use function count; @@ -89,7 +89,7 @@ class SetScorePacket extends DataPacket implements ClientboundPacket{ } } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleSetScore($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetScoreboardIdentityPacket.php b/src/pocketmine/network/mcpe/protocol/SetScoreboardIdentityPacket.php index 9a5f7f2198..2d8a39961e 100644 --- a/src/pocketmine/network/mcpe/protocol/SetScoreboardIdentityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetScoreboardIdentityPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\ScoreboardIdentityPacketEntry; use function count; @@ -64,7 +64,7 @@ class SetScoreboardIdentityPacket extends DataPacket implements ClientboundPacke } } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleSetScoreboardIdentity($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php b/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php index 8c1231cdff..41b2aeaf38 100644 --- a/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class SetSpawnPositionPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_SPAWN_POSITION_PACKET; @@ -72,7 +72,7 @@ class SetSpawnPositionPacket extends DataPacket implements ClientboundPacket{ $this->putBool($this->spawnForced); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleSetSpawnPosition($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetTimePacket.php b/src/pocketmine/network/mcpe/protocol/SetTimePacket.php index 80acfeebb5..afc7cd2dc7 100644 --- a/src/pocketmine/network/mcpe/protocol/SetTimePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetTimePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class SetTimePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_TIME_PACKET; @@ -47,7 +47,7 @@ class SetTimePacket extends DataPacket implements ClientboundPacket{ $this->putVarInt($this->time); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleSetTime($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php b/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php index d9227b8efe..f6afe5b6d1 100644 --- a/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class SetTitlePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_TITLE_PACKET; @@ -66,7 +66,7 @@ class SetTitlePacket extends DataPacket implements ClientboundPacket{ $this->putVarInt($this->fadeOutTime); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleSetTitle($this); } diff --git a/src/pocketmine/network/mcpe/protocol/ShowCreditsPacket.php b/src/pocketmine/network/mcpe/protocol/ShowCreditsPacket.php index b74e92ac23..959f88c8b0 100644 --- a/src/pocketmine/network/mcpe/protocol/ShowCreditsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ShowCreditsPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class ShowCreditsPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SHOW_CREDITS_PACKET; @@ -50,7 +50,7 @@ class ShowCreditsPacket extends DataPacket implements ClientboundPacket, Serverb $this->putVarInt($this->status); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleShowCredits($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ShowProfilePacket.php b/src/pocketmine/network/mcpe/protocol/ShowProfilePacket.php index b527e1c17f..e9e4a900cd 100644 --- a/src/pocketmine/network/mcpe/protocol/ShowProfilePacket.php +++ b/src/pocketmine/network/mcpe/protocol/ShowProfilePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class ShowProfilePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SHOW_PROFILE_PACKET; @@ -41,7 +41,7 @@ class ShowProfilePacket extends DataPacket implements ClientboundPacket{ $this->putString($this->xuid); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleShowProfile($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php b/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php index 2ba88fe2e7..7cf83dc08f 100644 --- a/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class ShowStoreOfferPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SHOW_STORE_OFFER_PACKET; @@ -45,7 +45,7 @@ class ShowStoreOfferPacket extends DataPacket implements ClientboundPacket{ $this->putBool($this->showAll); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleShowStoreOffer($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php b/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php index d801f0a4c0..94a43dac23 100644 --- a/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class SimpleEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SIMPLE_EVENT_PACKET; @@ -44,7 +44,7 @@ class SimpleEventPacket extends DataPacket implements ClientboundPacket, Serverb $this->putLShort($this->eventType); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleSimpleEvent($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SpawnExperienceOrbPacket.php b/src/pocketmine/network/mcpe/protocol/SpawnExperienceOrbPacket.php index 5a89838060..c7dcd25fbb 100644 --- a/src/pocketmine/network/mcpe/protocol/SpawnExperienceOrbPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SpawnExperienceOrbPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class SpawnExperienceOrbPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SPAWN_EXPERIENCE_ORB_PACKET; @@ -47,7 +47,7 @@ class SpawnExperienceOrbPacket extends DataPacket implements ServerboundPacket{ $this->putVarInt($this->amount); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleSpawnExperienceOrb($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SpawnParticleEffectPacket.php b/src/pocketmine/network/mcpe/protocol/SpawnParticleEffectPacket.php index 7f54705822..36374e5196 100644 --- a/src/pocketmine/network/mcpe/protocol/SpawnParticleEffectPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SpawnParticleEffectPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\DimensionIds; class SpawnParticleEffectPacket extends DataPacket implements ClientboundPacket{ @@ -55,7 +55,7 @@ class SpawnParticleEffectPacket extends DataPacket implements ClientboundPacket{ $this->putString($this->particleName); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleSpawnParticleEffect($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/StartGamePacket.php b/src/pocketmine/network/mcpe/protocol/StartGamePacket.php index 8f0ab85e96..c4bccc88e2 100644 --- a/src/pocketmine/network/mcpe/protocol/StartGamePacket.php +++ b/src/pocketmine/network/mcpe/protocol/StartGamePacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; @@ -277,7 +277,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{ return $stream->getBuffer(); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleStartGame($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/StopSoundPacket.php b/src/pocketmine/network/mcpe/protocol/StopSoundPacket.php index 117261386f..83d44d8066 100644 --- a/src/pocketmine/network/mcpe/protocol/StopSoundPacket.php +++ b/src/pocketmine/network/mcpe/protocol/StopSoundPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class StopSoundPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::STOP_SOUND_PACKET; @@ -47,7 +47,7 @@ class StopSoundPacket extends DataPacket implements ClientboundPacket{ $this->putBool($this->stopAll); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleStopSound($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php b/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php index 4af7f8c78f..422ad3a438 100644 --- a/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php +++ b/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class StructureBlockUpdatePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::STRUCTURE_BLOCK_UPDATE_PACKET; @@ -38,7 +38,7 @@ class StructureBlockUpdatePacket extends DataPacket implements ServerboundPacket //TODO } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleStructureBlockUpdate($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/SubClientLoginPacket.php b/src/pocketmine/network/mcpe/protocol/SubClientLoginPacket.php index 834c406822..8be6b0e985 100644 --- a/src/pocketmine/network/mcpe/protocol/SubClientLoginPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SubClientLoginPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class SubClientLoginPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SUB_CLIENT_LOGIN_PACKET; @@ -41,7 +41,7 @@ class SubClientLoginPacket extends DataPacket implements ServerboundPacket{ $this->putString($this->connectionRequestData); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleSubClientLogin($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php b/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php index 549ee4d284..bc1ff36aed 100644 --- a/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php +++ b/src/pocketmine/network/mcpe/protocol/TakeItemEntityPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class TakeItemEntityPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::TAKE_ITEM_ENTITY_PACKET; @@ -53,7 +53,7 @@ class TakeItemEntityPacket extends DataPacket implements ClientboundPacket{ $this->putEntityRuntimeId($this->eid); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleTakeItemEntity($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/TextPacket.php b/src/pocketmine/network/mcpe/protocol/TextPacket.php index b0f24fc974..de646852db 100644 --- a/src/pocketmine/network/mcpe/protocol/TextPacket.php +++ b/src/pocketmine/network/mcpe/protocol/TextPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use function count; class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -178,7 +178,7 @@ class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPac $this->putString($this->platformChatId); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleText($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/TransferPacket.php b/src/pocketmine/network/mcpe/protocol/TransferPacket.php index c1cadb556c..58170bd867 100644 --- a/src/pocketmine/network/mcpe/protocol/TransferPacket.php +++ b/src/pocketmine/network/mcpe/protocol/TransferPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class TransferPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::TRANSFER_PACKET; @@ -52,7 +52,7 @@ class TransferPacket extends DataPacket implements ClientboundPacket{ $this->putLShort($this->port); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleTransfer($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/UnknownPacket.php b/src/pocketmine/network/mcpe/protocol/UnknownPacket.php index a49d317bd8..129a29f84c 100644 --- a/src/pocketmine/network/mcpe/protocol/UnknownPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UnknownPacket.php @@ -25,7 +25,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use function ord; use function strlen; @@ -62,7 +62,7 @@ class UnknownPacket extends DataPacket{ $this->put($this->payload); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return false; } } diff --git a/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php index 0b1fffbef7..5766719031 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\entity\Attribute; -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use function array_values; class UpdateAttributesPacket extends DataPacket implements ClientboundPacket{ @@ -61,7 +61,7 @@ class UpdateAttributesPacket extends DataPacket implements ClientboundPacket{ $this->putAttributeList(...array_values($this->entries)); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleUpdateAttributes($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php index dbad6185f0..306d0ad257 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class UpdateBlockPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_BLOCK_PACKET; @@ -73,7 +73,7 @@ class UpdateBlockPacket extends DataPacket implements ClientboundPacket{ $this->putUnsignedVarInt($this->dataLayerId); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleUpdateBlock($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/UpdateBlockSyncedPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateBlockSyncedPacket.php index 0ac93c3bff..f5c6fdc225 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateBlockSyncedPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateBlockSyncedPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class UpdateBlockSyncedPacket extends UpdateBlockPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_BLOCK_SYNCED_PACKET; @@ -47,7 +47,7 @@ class UpdateBlockSyncedPacket extends UpdateBlockPacket{ $this->putUnsignedVarLong($this->uvarint64_2); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleUpdateBlockSynced($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php index 9cca5632c2..594a505166 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class UpdateEquipPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_EQUIP_PACKET; @@ -57,7 +57,7 @@ class UpdateEquipPacket extends DataPacket implements ClientboundPacket{ $this->put($this->namedtag); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleUpdateEquip($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/UpdateSoftEnumPacket.php b/src/pocketmine/network/mcpe/protocol/UpdateSoftEnumPacket.php index c1bee5e4e7..d20f186d76 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateSoftEnumPacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateSoftEnumPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use function count; class UpdateSoftEnumPacket extends DataPacket implements ClientboundPacket{ @@ -59,7 +59,7 @@ class UpdateSoftEnumPacket extends DataPacket implements ClientboundPacket{ $this->putByte($this->type); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleUpdateSoftEnum($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php b/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php index fecbd45ff7..28c65d2594 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\WindowTypes; class UpdateTradePacket extends DataPacket implements ClientboundPacket{ @@ -82,7 +82,7 @@ class UpdateTradePacket extends DataPacket implements ClientboundPacket{ $this->put($this->offers); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleUpdateTrade($this); } } diff --git a/src/pocketmine/network/mcpe/protocol/VideoStreamConnectPacket.php b/src/pocketmine/network/mcpe/protocol/VideoStreamConnectPacket.php index b0b817c4dc..4059579eed 100644 --- a/src/pocketmine/network/mcpe/protocol/VideoStreamConnectPacket.php +++ b/src/pocketmine/network/mcpe/protocol/VideoStreamConnectPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\SessionHandler; +use pocketmine\network\mcpe\handler\PacketHandler; class VideoStreamConnectPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::VIDEO_STREAM_CONNECT_PACKET; @@ -52,7 +52,7 @@ class VideoStreamConnectPacket extends DataPacket implements ClientboundPacket{ $this->putByte($this->action); } - public function handle(SessionHandler $handler) : bool{ + public function handle(PacketHandler $handler) : bool{ return $handler->handleVideoStreamConnect($this); } } From 709963f90a4b4e42ecea15e6913c4cf558919f12 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 18 Jun 2019 16:07:43 +0100 Subject: [PATCH 0964/3224] shut up PhpStorm --- src/pocketmine/network/mcpe/NetworkSession.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 96e56d1db2..5acdf3b48c 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -39,9 +39,9 @@ use pocketmine\network\mcpe\handler\HandshakePacketHandler; use pocketmine\network\mcpe\handler\InGamePacketHandler; use pocketmine\network\mcpe\handler\LoginPacketHandler; use pocketmine\network\mcpe\handler\NullPacketHandler; +use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\handler\PreSpawnPacketHandler; use pocketmine\network\mcpe\handler\ResourcePacksPacketHandler; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; From 075f49aef07b8c76aa82a8fa0b28793c32b15d8f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 18 Jun 2019 16:22:41 +0100 Subject: [PATCH 0965/3224] don't send double disconnect messages --- src/pocketmine/Player.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 98e6c10b3f..2522e5d16d 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2344,13 +2344,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $this->save(); - $this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logOut", [ - TextFormat::AQUA . $this->getName() . TextFormat::WHITE, - $this->networkSession->getIp(), - $this->networkSession->getPort(), - $this->getServer()->getLanguage()->translateString($reason) - ])); - $this->spawned = false; $this->stopSleep(); From c66af4648c3d6d63b427cd07f313ecc707f3e3e6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 18 Jun 2019 17:36:25 +0100 Subject: [PATCH 0966/3224] Move thread-related classes from pocketmine to pocketmine\thread namespace --- src/pocketmine/PocketMine.php | 1 + src/pocketmine/command/CommandReader.php | 2 +- src/pocketmine/scheduler/AsyncTask.php | 2 +- src/pocketmine/scheduler/AsyncWorker.php | 2 +- src/pocketmine/{ => thread}/Thread.php | 3 ++- src/pocketmine/{ => thread}/ThreadManager.php | 2 +- src/pocketmine/{ => thread}/Worker.php | 3 ++- src/pocketmine/utils/MainLogger.php | 4 ++-- src/pocketmine/utils/Process.php | 2 +- src/pocketmine/utils/ServerKiller.php | 2 +- 10 files changed, 13 insertions(+), 10 deletions(-) rename src/pocketmine/{ => thread}/Thread.php (98%) rename src/pocketmine/{ => thread}/ThreadManager.php (98%) rename src/pocketmine/{ => thread}/Worker.php (98%) diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index 54ca6a307c..c280019fc0 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -28,6 +28,7 @@ namespace { namespace pocketmine { + use pocketmine\thread\ThreadManager; use pocketmine\utils\MainLogger; use pocketmine\utils\Process; use pocketmine\utils\ServerKiller; diff --git a/src/pocketmine/command/CommandReader.php b/src/pocketmine/command/CommandReader.php index bed67d6eca..70660c8211 100644 --- a/src/pocketmine/command/CommandReader.php +++ b/src/pocketmine/command/CommandReader.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\command; use pocketmine\snooze\SleeperNotifier; -use pocketmine\Thread; +use pocketmine\thread\Thread; use pocketmine\utils\Utils; use function extension_loaded; use function fclose; diff --git a/src/pocketmine/scheduler/AsyncTask.php b/src/pocketmine/scheduler/AsyncTask.php index a6add8740c..d8dd45c5ec 100644 --- a/src/pocketmine/scheduler/AsyncTask.php +++ b/src/pocketmine/scheduler/AsyncTask.php @@ -33,7 +33,7 @@ use function unserialize; * * An AsyncTask does not have its own thread. It is queued into an AsyncPool and executed if there is an async worker * with no AsyncTask running. Therefore, an AsyncTask SHOULD NOT execute for more than a few seconds. For tasks that - * run for a long time or infinitely, start another {@link \pocketmine\Thread} instead. + * run for a long time or infinitely, start another {@link \pocketmine\thread\Thread} instead. * * WARNING: Any non-Threaded objects WILL BE SERIALIZED when assigned to members of AsyncTasks or other Threaded object. * If later accessed from said Threaded object, you will be operating on a COPY OF THE OBJECT, NOT THE ORIGINAL OBJECT. diff --git a/src/pocketmine/scheduler/AsyncWorker.php b/src/pocketmine/scheduler/AsyncWorker.php index 86c2a76935..3633983135 100644 --- a/src/pocketmine/scheduler/AsyncWorker.php +++ b/src/pocketmine/scheduler/AsyncWorker.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\scheduler; +use pocketmine\thread\Worker; use pocketmine\utils\MainLogger; -use pocketmine\Worker; use function gc_enable; use function ini_set; diff --git a/src/pocketmine/Thread.php b/src/pocketmine/thread/Thread.php similarity index 98% rename from src/pocketmine/Thread.php rename to src/pocketmine/thread/Thread.php index 350dae2b92..c69b01f118 100644 --- a/src/pocketmine/Thread.php +++ b/src/pocketmine/thread/Thread.php @@ -21,8 +21,9 @@ declare(strict_types=1); -namespace pocketmine; +namespace pocketmine\thread; +use pocketmine\Server; use function error_reporting; /** diff --git a/src/pocketmine/ThreadManager.php b/src/pocketmine/thread/ThreadManager.php similarity index 98% rename from src/pocketmine/ThreadManager.php rename to src/pocketmine/thread/ThreadManager.php index 027770920a..1387a8494d 100644 --- a/src/pocketmine/ThreadManager.php +++ b/src/pocketmine/thread/ThreadManager.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine; +namespace pocketmine\thread; use function spl_object_id; diff --git a/src/pocketmine/Worker.php b/src/pocketmine/thread/Worker.php similarity index 98% rename from src/pocketmine/Worker.php rename to src/pocketmine/thread/Worker.php index 0d67bd9eea..fc48fb2128 100644 --- a/src/pocketmine/Worker.php +++ b/src/pocketmine/thread/Worker.php @@ -21,8 +21,9 @@ declare(strict_types=1); -namespace pocketmine; +namespace pocketmine\thread; +use pocketmine\Server; use function error_reporting; /** diff --git a/src/pocketmine/utils/MainLogger.php b/src/pocketmine/utils/MainLogger.php index cdadf944e4..e98e9a8340 100644 --- a/src/pocketmine/utils/MainLogger.php +++ b/src/pocketmine/utils/MainLogger.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\utils; use LogLevel; -use pocketmine\Thread; -use pocketmine\Worker; +use pocketmine\thread\Thread; +use pocketmine\thread\Worker; use function fclose; use function fopen; use function fwrite; diff --git a/src/pocketmine/utils/Process.php b/src/pocketmine/utils/Process.php index 3bca4302ae..d34220c2dd 100644 --- a/src/pocketmine/utils/Process.php +++ b/src/pocketmine/utils/Process.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\utils; -use pocketmine\ThreadManager; +use pocketmine\thread\ThreadManager; use function count; use function exec; use function fclose; diff --git a/src/pocketmine/utils/ServerKiller.php b/src/pocketmine/utils/ServerKiller.php index d49582397c..993c41d2b9 100644 --- a/src/pocketmine/utils/ServerKiller.php +++ b/src/pocketmine/utils/ServerKiller.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\utils; -use pocketmine\Thread; +use pocketmine\thread\Thread; use function getmypid; use function time; From e82a40b2bab66c23acd1fc8ca27394f8f67f3ef8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 18 Jun 2019 17:37:38 +0100 Subject: [PATCH 0967/3224] forgot to stage this for b18bd4f33ce606ad594b56dd4785b650d21cd695 --- tests/phpunit/network/mcpe/handler/StupidJsonDecodeTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/network/mcpe/handler/StupidJsonDecodeTest.php b/tests/phpunit/network/mcpe/handler/StupidJsonDecodeTest.php index a18319a892..2c39003302 100644 --- a/tests/phpunit/network/mcpe/handler/StupidJsonDecodeTest.php +++ b/tests/phpunit/network/mcpe/handler/StupidJsonDecodeTest.php @@ -47,7 +47,7 @@ class StupidJsonDecodeTest extends TestCase{ * @throws \ReflectionException */ public function testStupidJsonDecode(string $brokenJson, $expect){ - $func = new \ReflectionMethod(InGameSessionHandler::class, 'stupid_json_decode'); + $func = new \ReflectionMethod(InGamePacketHandler::class, 'stupid_json_decode'); $func->setAccessible(true); $decoded = $func->invoke(null, $brokenJson, true); From 2559f5ec2be3a2536dc333d908ede46772d18285 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 18 Jun 2019 18:51:36 +0100 Subject: [PATCH 0968/3224] Moved Player-related classes to pocketmine\player namespace --- src/pocketmine/Server.php | 3 +++ src/pocketmine/block/Anvil.php | 2 +- src/pocketmine/block/Banner.php | 2 +- src/pocketmine/block/BaseRail.php | 2 +- src/pocketmine/block/Bed.php | 2 +- src/pocketmine/block/Block.php | 2 +- src/pocketmine/block/BrewingStand.php | 2 +- src/pocketmine/block/Button.php | 2 +- src/pocketmine/block/Cactus.php | 2 +- src/pocketmine/block/Cake.php | 2 +- src/pocketmine/block/Carpet.php | 2 +- src/pocketmine/block/Chest.php | 2 +- src/pocketmine/block/CoarseDirt.php | 2 +- src/pocketmine/block/CocoaBlock.php | 2 +- src/pocketmine/block/CraftingTable.php | 2 +- src/pocketmine/block/Crops.php | 2 +- src/pocketmine/block/DaylightSensor.php | 2 +- src/pocketmine/block/DeadBush.php | 2 +- src/pocketmine/block/Dirt.php | 2 +- src/pocketmine/block/Door.php | 2 +- src/pocketmine/block/DoublePlant.php | 2 +- src/pocketmine/block/DragonEgg.php | 2 +- src/pocketmine/block/EnchantingTable.php | 2 +- src/pocketmine/block/EndPortalFrame.php | 2 +- src/pocketmine/block/EndRod.php | 2 +- src/pocketmine/block/EnderChest.php | 2 +- src/pocketmine/block/FenceGate.php | 2 +- src/pocketmine/block/Flower.php | 2 +- src/pocketmine/block/FlowerPot.php | 2 +- src/pocketmine/block/Furnace.php | 2 +- src/pocketmine/block/GlazedTerracotta.php | 2 +- src/pocketmine/block/Grass.php | 2 +- src/pocketmine/block/Hopper.php | 2 +- src/pocketmine/block/Ice.php | 2 +- src/pocketmine/block/ItemFrame.php | 2 +- src/pocketmine/block/Ladder.php | 2 +- src/pocketmine/block/Leaves.php | 2 +- src/pocketmine/block/Lever.php | 2 +- src/pocketmine/block/NetherWartPlant.php | 2 +- src/pocketmine/block/Pumpkin.php | 2 +- src/pocketmine/block/RedMushroom.php | 2 +- src/pocketmine/block/RedstoneComparator.php | 2 +- src/pocketmine/block/RedstoneOre.php | 2 +- src/pocketmine/block/RedstoneRepeater.php | 2 +- src/pocketmine/block/Sapling.php | 2 +- src/pocketmine/block/SeaPickle.php | 2 +- src/pocketmine/block/Sign.php | 2 +- src/pocketmine/block/Skull.php | 2 +- src/pocketmine/block/Slab.php | 2 +- src/pocketmine/block/SnowLayer.php | 2 +- src/pocketmine/block/Stair.php | 2 +- src/pocketmine/block/Sugarcane.php | 2 +- src/pocketmine/block/TNT.php | 2 +- src/pocketmine/block/TallGrass.php | 2 +- src/pocketmine/block/Torch.php | 2 +- src/pocketmine/block/Trapdoor.php | 2 +- src/pocketmine/block/TripwireHook.php | 2 +- src/pocketmine/block/Vine.php | 2 +- src/pocketmine/block/WaterLily.php | 2 +- src/pocketmine/block/utils/PillarRotationTrait.php | 2 +- src/pocketmine/command/defaults/BanCommand.php | 2 +- src/pocketmine/command/defaults/BanIpCommand.php | 2 +- src/pocketmine/command/defaults/DefaultGamemodeCommand.php | 2 +- src/pocketmine/command/defaults/DeopCommand.php | 2 +- src/pocketmine/command/defaults/GamemodeCommand.php | 4 ++-- src/pocketmine/command/defaults/KickCommand.php | 2 +- src/pocketmine/command/defaults/KillCommand.php | 2 +- src/pocketmine/command/defaults/ListCommand.php | 2 +- src/pocketmine/command/defaults/MeCommand.php | 2 +- src/pocketmine/command/defaults/OpCommand.php | 2 +- src/pocketmine/command/defaults/ParticleCommand.php | 2 +- src/pocketmine/command/defaults/SayCommand.php | 2 +- src/pocketmine/command/defaults/SeedCommand.php | 2 +- src/pocketmine/command/defaults/SetWorldSpawnCommand.php | 2 +- src/pocketmine/command/defaults/SpawnpointCommand.php | 2 +- src/pocketmine/command/defaults/TeleportCommand.php | 2 +- src/pocketmine/command/defaults/TellCommand.php | 2 +- src/pocketmine/command/defaults/TimeCommand.php | 2 +- src/pocketmine/command/defaults/TimingsCommand.php | 2 +- src/pocketmine/command/defaults/TransferServerCommand.php | 2 +- src/pocketmine/command/defaults/WhitelistCommand.php | 2 +- src/pocketmine/entity/Entity.php | 2 +- src/pocketmine/entity/Human.php | 2 +- src/pocketmine/entity/Living.php | 2 +- src/pocketmine/entity/effect/LevitationEffect.php | 2 +- src/pocketmine/entity/object/ExperienceOrb.php | 2 +- src/pocketmine/entity/object/ItemEntity.php | 2 +- src/pocketmine/entity/object/Painting.php | 2 +- src/pocketmine/entity/projectile/Arrow.php | 2 +- src/pocketmine/event/block/BlockBreakEvent.php | 2 +- src/pocketmine/event/block/BlockPlaceEvent.php | 2 +- src/pocketmine/event/block/SignChangeEvent.php | 2 +- src/pocketmine/event/inventory/CraftItemEvent.php | 2 +- src/pocketmine/event/inventory/InventoryCloseEvent.php | 2 +- src/pocketmine/event/inventory/InventoryOpenEvent.php | 2 +- .../event/player/PlayerAchievementAwardedEvent.php | 2 +- src/pocketmine/event/player/PlayerAnimationEvent.php | 2 +- src/pocketmine/event/player/PlayerBedEnterEvent.php | 2 +- src/pocketmine/event/player/PlayerBedLeaveEvent.php | 2 +- src/pocketmine/event/player/PlayerBlockPickEvent.php | 2 +- src/pocketmine/event/player/PlayerBucketEvent.php | 2 +- src/pocketmine/event/player/PlayerChangeSkinEvent.php | 2 +- src/pocketmine/event/player/PlayerChatEvent.php | 2 +- .../event/player/PlayerCommandPreprocessEvent.php | 2 +- src/pocketmine/event/player/PlayerCreationEvent.php | 2 +- src/pocketmine/event/player/PlayerDataSaveEvent.php | 2 +- src/pocketmine/event/player/PlayerDeathEvent.php | 2 +- src/pocketmine/event/player/PlayerDropItemEvent.php | 2 +- src/pocketmine/event/player/PlayerEditBookEvent.php | 2 +- src/pocketmine/event/player/PlayerEvent.php | 2 +- src/pocketmine/event/player/PlayerGameModeChangeEvent.php | 4 ++-- src/pocketmine/event/player/PlayerInteractEvent.php | 2 +- src/pocketmine/event/player/PlayerItemConsumeEvent.php | 2 +- src/pocketmine/event/player/PlayerItemHeldEvent.php | 2 +- src/pocketmine/event/player/PlayerItemUseEvent.php | 2 +- src/pocketmine/event/player/PlayerJoinEvent.php | 2 +- src/pocketmine/event/player/PlayerJumpEvent.php | 2 +- src/pocketmine/event/player/PlayerKickEvent.php | 2 +- src/pocketmine/event/player/PlayerLoginEvent.php | 2 +- src/pocketmine/event/player/PlayerMoveEvent.php | 2 +- src/pocketmine/event/player/PlayerPreLoginEvent.php | 2 +- src/pocketmine/event/player/PlayerQuitEvent.php | 2 +- src/pocketmine/event/player/PlayerRespawnEvent.php | 2 +- src/pocketmine/event/player/PlayerToggleFlightEvent.php | 2 +- src/pocketmine/event/player/PlayerToggleSneakEvent.php | 2 +- src/pocketmine/event/player/PlayerToggleSprintEvent.php | 2 +- src/pocketmine/event/player/PlayerTransferEvent.php | 2 +- .../event/player/cheat/PlayerIllegalMoveEvent.php | 2 +- src/pocketmine/event/server/QueryRegenerateEvent.php | 2 +- src/pocketmine/form/Form.php | 2 +- src/pocketmine/inventory/AnvilInventory.php | 2 +- src/pocketmine/inventory/BaseInventory.php | 2 +- src/pocketmine/inventory/ChestInventory.php | 2 +- src/pocketmine/inventory/ContainerInventory.php | 2 +- src/pocketmine/inventory/CraftingGrid.php | 2 +- src/pocketmine/inventory/DoubleChestInventory.php | 2 +- src/pocketmine/inventory/EnchantInventory.php | 2 +- src/pocketmine/inventory/Inventory.php | 2 +- src/pocketmine/inventory/PlayerCursorInventory.php | 2 +- src/pocketmine/inventory/PlayerInventory.php | 2 +- .../inventory/transaction/InventoryTransaction.php | 2 +- .../inventory/transaction/action/CreateItemAction.php | 2 +- .../inventory/transaction/action/DestroyItemAction.php | 2 +- .../inventory/transaction/action/DropItemAction.php | 2 +- .../inventory/transaction/action/InventoryAction.php | 2 +- .../inventory/transaction/action/SlotChangeAction.php | 2 +- src/pocketmine/item/Armor.php | 2 +- src/pocketmine/item/Bow.php | 2 +- src/pocketmine/item/Bucket.php | 2 +- src/pocketmine/item/FlintSteel.php | 2 +- src/pocketmine/item/Item.php | 2 +- src/pocketmine/item/LiquidBucket.php | 2 +- src/pocketmine/item/PaintingItem.php | 2 +- src/pocketmine/item/ProjectileItem.php | 4 ++-- src/pocketmine/item/SpawnEgg.php | 2 +- src/pocketmine/metadata/PlayerMetadataStore.php | 2 +- src/pocketmine/network/mcpe/NetworkSession.php | 6 +++--- src/pocketmine/network/mcpe/handler/DeathPacketHandler.php | 2 +- src/pocketmine/network/mcpe/handler/InGamePacketHandler.php | 2 +- src/pocketmine/network/mcpe/handler/LoginPacketHandler.php | 4 ++-- .../network/mcpe/handler/PreSpawnPacketHandler.php | 2 +- .../network/mcpe/protocol/types/NetworkInventoryAction.php | 2 +- src/pocketmine/{ => player}/Achievement.php | 3 ++- src/pocketmine/{ => player}/GameMode.php | 2 +- src/pocketmine/{ => player}/IPlayer.php | 2 +- src/pocketmine/{ => player}/OfflinePlayer.php | 3 ++- src/pocketmine/{ => player}/Player.php | 3 ++- src/pocketmine/{ => player}/PlayerInfo.php | 2 +- src/pocketmine/scheduler/SendUsageTask.php | 2 +- src/pocketmine/timings/Timings.php | 2 +- src/pocketmine/updater/AutoUpdater.php | 2 +- src/pocketmine/world/World.php | 3 +-- src/pocketmine/world/format/Chunk.php | 2 +- 173 files changed, 184 insertions(+), 179 deletions(-) rename src/pocketmine/{ => player}/Achievement.php (98%) rename src/pocketmine/{ => player}/GameMode.php (99%) rename src/pocketmine/{ => player}/IPlayer.php (98%) rename src/pocketmine/{ => player}/OfflinePlayer.php (98%) rename src/pocketmine/{ => player}/Player.php (99%) rename src/pocketmine/{ => player}/PlayerInfo.php (98%) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index a48ea0ba1e..bcc93a2a2b 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -68,6 +68,9 @@ use pocketmine\network\upnp\UPnP; use pocketmine\permission\BanList; use pocketmine\permission\DefaultPermissions; use pocketmine\permission\PermissionManager; +use pocketmine\player\GameMode; +use pocketmine\player\OfflinePlayer; +use pocketmine\player\Player; use pocketmine\plugin\PharPluginLoader; use pocketmine\plugin\Plugin; use pocketmine\plugin\PluginGraylist; diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index f03c9174c4..f2c280fd4a 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -33,7 +33,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Anvil extends Transparent implements Fallable{ diff --git a/src/pocketmine/block/Banner.php b/src/pocketmine/block/Banner.php index 37d7734824..348d4843ef 100644 --- a/src/pocketmine/block/Banner.php +++ b/src/pocketmine/block/Banner.php @@ -34,7 +34,7 @@ use pocketmine\item\ItemFactory; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use function assert; use function floor; diff --git a/src/pocketmine/block/BaseRail.php b/src/pocketmine/block/BaseRail.php index 0a68f967ee..501f65365b 100644 --- a/src/pocketmine/block/BaseRail.php +++ b/src/pocketmine/block/BaseRail.php @@ -27,7 +27,7 @@ use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use function array_map; use function array_reverse; diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 08900ff04e..b1ee5582c4 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -34,7 +34,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; use pocketmine\world\BlockTransaction; use pocketmine\world\World; diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 1762bcad80..b3261209bf 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -42,7 +42,7 @@ use pocketmine\metadata\Metadatable; use pocketmine\metadata\MetadataValue; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\plugin\Plugin; use pocketmine\world\BlockTransaction; use pocketmine\world\Position; diff --git a/src/pocketmine/block/BrewingStand.php b/src/pocketmine/block/BrewingStand.php index 465934fab5..1cfe4125ab 100644 --- a/src/pocketmine/block/BrewingStand.php +++ b/src/pocketmine/block/BrewingStand.php @@ -27,7 +27,7 @@ use pocketmine\block\tile\BrewingStand as TileBrewingStand; use pocketmine\item\Item; use pocketmine\item\TieredTool; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; class BrewingStand extends Transparent{ diff --git a/src/pocketmine/block/Button.php b/src/pocketmine/block/Button.php index d2ce43a17b..a6ae2a1ffa 100644 --- a/src/pocketmine/block/Button.php +++ b/src/pocketmine/block/Button.php @@ -27,7 +27,7 @@ use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use pocketmine\world\sound\RedstonePowerOffSound; use pocketmine\world\sound\RedstonePowerOnSound; diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index 1b3895f9e7..ae66925171 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -32,7 +32,7 @@ use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Cactus extends Transparent{ diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index 2cc9057903..8d1cd4b8a3 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -31,7 +31,7 @@ use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Cake extends Transparent implements FoodSource{ diff --git a/src/pocketmine/block/Carpet.php b/src/pocketmine/block/Carpet.php index 7a90923da6..39b7d2ccb7 100644 --- a/src/pocketmine/block/Carpet.php +++ b/src/pocketmine/block/Carpet.php @@ -27,7 +27,7 @@ use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Carpet extends Flowable{ diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index c56eeafac9..baae80b328 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -29,7 +29,7 @@ use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Chest extends Transparent{ diff --git a/src/pocketmine/block/CoarseDirt.php b/src/pocketmine/block/CoarseDirt.php index ac26869a5a..91026cdc42 100644 --- a/src/pocketmine/block/CoarseDirt.php +++ b/src/pocketmine/block/CoarseDirt.php @@ -27,7 +27,7 @@ use pocketmine\item\Hoe; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; class CoarseDirt extends Dirt{ diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index 15a504e8b7..06e2dfac7a 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -32,7 +32,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use function mt_rand; diff --git a/src/pocketmine/block/CraftingTable.php b/src/pocketmine/block/CraftingTable.php index 67a38b5e01..2a9aec8b43 100644 --- a/src/pocketmine/block/CraftingTable.php +++ b/src/pocketmine/block/CraftingTable.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\inventory\CraftingGrid; use pocketmine\item\Item; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; class CraftingTable extends Solid{ diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index 7e62e79e8f..799f59fd5c 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -29,7 +29,7 @@ use pocketmine\item\Fertilizer; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use function mt_rand; diff --git a/src/pocketmine/block/DaylightSensor.php b/src/pocketmine/block/DaylightSensor.php index d066708591..596e71deee 100644 --- a/src/pocketmine/block/DaylightSensor.php +++ b/src/pocketmine/block/DaylightSensor.php @@ -28,7 +28,7 @@ use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use function cos; use function max; use function round; diff --git a/src/pocketmine/block/DeadBush.php b/src/pocketmine/block/DeadBush.php index 6d03f4857b..19ff078c09 100644 --- a/src/pocketmine/block/DeadBush.php +++ b/src/pocketmine/block/DeadBush.php @@ -27,7 +27,7 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use function mt_rand; diff --git a/src/pocketmine/block/Dirt.php b/src/pocketmine/block/Dirt.php index 9f502e1c12..f1db0380e8 100644 --- a/src/pocketmine/block/Dirt.php +++ b/src/pocketmine/block/Dirt.php @@ -27,7 +27,7 @@ use pocketmine\item\Hoe; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; class Dirt extends Solid{ diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index 1cd369998a..c244ddacc0 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -29,7 +29,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use pocketmine\world\sound\DoorSound; diff --git a/src/pocketmine/block/DoublePlant.php b/src/pocketmine/block/DoublePlant.php index cfe827b3a1..3c21947636 100644 --- a/src/pocketmine/block/DoublePlant.php +++ b/src/pocketmine/block/DoublePlant.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class DoublePlant extends Flowable{ diff --git a/src/pocketmine/block/DragonEgg.php b/src/pocketmine/block/DragonEgg.php index ffd1d549b2..0be7e15fe4 100644 --- a/src/pocketmine/block/DragonEgg.php +++ b/src/pocketmine/block/DragonEgg.php @@ -29,7 +29,7 @@ use pocketmine\event\block\BlockTeleportEvent; use pocketmine\item\Item; use pocketmine\item\TieredTool; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\particle\DragonEggTeleportParticle; use pocketmine\world\World; use function max; diff --git a/src/pocketmine/block/EnchantingTable.php b/src/pocketmine/block/EnchantingTable.php index 66ebae89d5..5afb805a51 100644 --- a/src/pocketmine/block/EnchantingTable.php +++ b/src/pocketmine/block/EnchantingTable.php @@ -29,7 +29,7 @@ use pocketmine\item\TieredTool; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; class EnchantingTable extends Transparent{ diff --git a/src/pocketmine/block/EndPortalFrame.php b/src/pocketmine/block/EndPortalFrame.php index ae0f0217c8..70e5f5aef2 100644 --- a/src/pocketmine/block/EndPortalFrame.php +++ b/src/pocketmine/block/EndPortalFrame.php @@ -29,7 +29,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class EndPortalFrame extends Solid{ diff --git a/src/pocketmine/block/EndRod.php b/src/pocketmine/block/EndRod.php index 8ff7a60853..7da1326657 100644 --- a/src/pocketmine/block/EndRod.php +++ b/src/pocketmine/block/EndRod.php @@ -28,7 +28,7 @@ use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class EndRod extends Flowable{ diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index d750b56dbb..17287b49c8 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -31,7 +31,7 @@ use pocketmine\item\TieredTool; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class EnderChest extends Transparent{ diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index 96399b5d83..41ae3543ba 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -29,7 +29,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use pocketmine\world\sound\DoorSound; diff --git a/src/pocketmine/block/Flower.php b/src/pocketmine/block/Flower.php index 7e8b2137be..c44fc68297 100644 --- a/src/pocketmine/block/Flower.php +++ b/src/pocketmine/block/Flower.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Flower extends Flowable{ diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 0b4a06d949..9d941546d2 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -28,7 +28,7 @@ use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use function assert; diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index c2248ebf76..404df7f19d 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -29,7 +29,7 @@ use pocketmine\item\Item; use pocketmine\item\TieredTool; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Furnace extends Solid{ diff --git a/src/pocketmine/block/GlazedTerracotta.php b/src/pocketmine/block/GlazedTerracotta.php index 881026a60d..196d6d10d6 100644 --- a/src/pocketmine/block/GlazedTerracotta.php +++ b/src/pocketmine/block/GlazedTerracotta.php @@ -29,7 +29,7 @@ use pocketmine\item\Item; use pocketmine\item\TieredTool; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class GlazedTerracotta extends Solid{ diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index 29eb1712ca..aa89356969 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -31,7 +31,7 @@ use pocketmine\item\ItemFactory; use pocketmine\item\Shovel; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\Random; use pocketmine\world\generator\object\TallGrass as TallGrassObject; use function mt_rand; diff --git a/src/pocketmine/block/Hopper.php b/src/pocketmine/block/Hopper.php index 6c997f350f..9318dc39a9 100644 --- a/src/pocketmine/block/Hopper.php +++ b/src/pocketmine/block/Hopper.php @@ -30,7 +30,7 @@ use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Hopper extends Transparent{ diff --git a/src/pocketmine/block/Ice.php b/src/pocketmine/block/Ice.php index 725aa0375b..d62193cc35 100644 --- a/src/pocketmine/block/Ice.php +++ b/src/pocketmine/block/Ice.php @@ -25,7 +25,7 @@ namespace pocketmine\block; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\Item; -use pocketmine\Player; +use pocketmine\player\Player; class Ice extends Transparent{ diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index aadd676a5d..0eaf1f3173 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -28,7 +28,7 @@ use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use function lcg_value; diff --git a/src/pocketmine/block/Ladder.php b/src/pocketmine/block/Ladder.php index 2477c33e8e..2440ac50a7 100644 --- a/src/pocketmine/block/Ladder.php +++ b/src/pocketmine/block/Ladder.php @@ -29,7 +29,7 @@ use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Ladder extends Transparent{ diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 7c21d789c5..a8c9d05375 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -29,7 +29,7 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use pocketmine\world\World; use function mt_rand; diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index a0c1aced10..6315df7243 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -27,7 +27,7 @@ use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use pocketmine\world\sound\RedstonePowerOffSound; use pocketmine\world\sound\RedstonePowerOnSound; diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index 2b2029e60f..6e47e77381 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -29,7 +29,7 @@ use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use function mt_rand; diff --git a/src/pocketmine/block/Pumpkin.php b/src/pocketmine/block/Pumpkin.php index 31123bb9c6..335835630a 100644 --- a/src/pocketmine/block/Pumpkin.php +++ b/src/pocketmine/block/Pumpkin.php @@ -28,7 +28,7 @@ use pocketmine\item\Item; use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Pumpkin extends Solid{ diff --git a/src/pocketmine/block/RedMushroom.php b/src/pocketmine/block/RedMushroom.php index 909cfd853e..d8b9bdca81 100644 --- a/src/pocketmine/block/RedMushroom.php +++ b/src/pocketmine/block/RedMushroom.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class RedMushroom extends Flowable{ diff --git a/src/pocketmine/block/RedstoneComparator.php b/src/pocketmine/block/RedstoneComparator.php index 8ea7f9a761..937f153aec 100644 --- a/src/pocketmine/block/RedstoneComparator.php +++ b/src/pocketmine/block/RedstoneComparator.php @@ -30,7 +30,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use function assert; diff --git a/src/pocketmine/block/RedstoneOre.php b/src/pocketmine/block/RedstoneOre.php index d3b11d4c78..863c4fea83 100644 --- a/src/pocketmine/block/RedstoneOre.php +++ b/src/pocketmine/block/RedstoneOre.php @@ -27,7 +27,7 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use function mt_rand; class RedstoneOre extends Solid{ diff --git a/src/pocketmine/block/RedstoneRepeater.php b/src/pocketmine/block/RedstoneRepeater.php index fad3f599db..f1f3ab18f0 100644 --- a/src/pocketmine/block/RedstoneRepeater.php +++ b/src/pocketmine/block/RedstoneRepeater.php @@ -29,7 +29,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class RedstoneRepeater extends Flowable{ diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index e312c9ff78..49a56fe338 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -28,7 +28,7 @@ use pocketmine\item\Fertilizer; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\Random; use pocketmine\world\BlockTransaction; use pocketmine\world\generator\object\Tree; diff --git a/src/pocketmine/block/SeaPickle.php b/src/pocketmine/block/SeaPickle.php index 26dab94aa8..0775d7e195 100644 --- a/src/pocketmine/block/SeaPickle.php +++ b/src/pocketmine/block/SeaPickle.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class SeaPickle extends Transparent{ diff --git a/src/pocketmine/block/Sign.php b/src/pocketmine/block/Sign.php index 58ca727735..a865d80ef0 100644 --- a/src/pocketmine/block/Sign.php +++ b/src/pocketmine/block/Sign.php @@ -31,7 +31,7 @@ use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; use pocketmine\world\BlockTransaction; use function array_map; diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index e9aa86a187..04806392eb 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -32,7 +32,7 @@ use pocketmine\item\Skull as ItemSkull; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use function assert; use function floor; diff --git a/src/pocketmine/block/Slab.php b/src/pocketmine/block/Slab.php index 975010f69e..7cceddba92 100644 --- a/src/pocketmine/block/Slab.php +++ b/src/pocketmine/block/Slab.php @@ -28,7 +28,7 @@ use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Slab extends Transparent{ diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index a7ceacc5a3..80c2827014 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -32,7 +32,7 @@ use pocketmine\item\TieredTool; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use function floor; use function max; diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index d904de9259..892c730457 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -28,7 +28,7 @@ use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Stair extends Transparent{ diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index d60e1a5f3b..92488993d2 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -29,7 +29,7 @@ use pocketmine\item\Fertilizer; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Sugarcane extends Flowable{ diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index b789b8ae46..882e1ff9da 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -32,7 +32,7 @@ use pocketmine\item\enchantment\Enchantment; use pocketmine\item\FlintSteel; use pocketmine\item\Item; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\Random; use function cos; use function sin; diff --git a/src/pocketmine/block/TallGrass.php b/src/pocketmine/block/TallGrass.php index 7a6a8cc81a..13c054410c 100644 --- a/src/pocketmine/block/TallGrass.php +++ b/src/pocketmine/block/TallGrass.php @@ -27,7 +27,7 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use function mt_rand; diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index c9f09ec88e..1af73c2af7 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -27,7 +27,7 @@ use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Torch extends Flowable{ diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index 5b829ee0e8..4fc3cbe99a 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -28,7 +28,7 @@ use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use pocketmine\world\sound\DoorSound; diff --git a/src/pocketmine/block/TripwireHook.php b/src/pocketmine/block/TripwireHook.php index b884900af7..1cd9be24b5 100644 --- a/src/pocketmine/block/TripwireHook.php +++ b/src/pocketmine/block/TripwireHook.php @@ -28,7 +28,7 @@ use pocketmine\item\Item; use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class TripwireHook extends Flowable{ diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index 4de77fadad..4c320540e0 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -28,7 +28,7 @@ use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use function array_intersect_key; use function array_keys; diff --git a/src/pocketmine/block/WaterLily.php b/src/pocketmine/block/WaterLily.php index 73428917a1..4b6bcaeb50 100644 --- a/src/pocketmine/block/WaterLily.php +++ b/src/pocketmine/block/WaterLily.php @@ -27,7 +27,7 @@ use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class WaterLily extends Flowable{ diff --git a/src/pocketmine/block/utils/PillarRotationTrait.php b/src/pocketmine/block/utils/PillarRotationTrait.php index b84dd7b79d..639dd3ed2a 100644 --- a/src/pocketmine/block/utils/PillarRotationTrait.php +++ b/src/pocketmine/block/utils/PillarRotationTrait.php @@ -27,7 +27,7 @@ use pocketmine\block\Block; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; trait PillarRotationTrait{ diff --git a/src/pocketmine/command/defaults/BanCommand.php b/src/pocketmine/command/defaults/BanCommand.php index 67ddff1edf..6823ba19cb 100644 --- a/src/pocketmine/command/defaults/BanCommand.php +++ b/src/pocketmine/command/defaults/BanCommand.php @@ -27,7 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; -use pocketmine\Player; +use pocketmine\player\Player; use function array_shift; use function count; use function implode; diff --git a/src/pocketmine/command/defaults/BanIpCommand.php b/src/pocketmine/command/defaults/BanIpCommand.php index 6f10b192d7..18f09efe3e 100644 --- a/src/pocketmine/command/defaults/BanIpCommand.php +++ b/src/pocketmine/command/defaults/BanIpCommand.php @@ -27,7 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; -use pocketmine\Player; +use pocketmine\player\Player; use function array_shift; use function count; use function implode; diff --git a/src/pocketmine/command/defaults/DefaultGamemodeCommand.php b/src/pocketmine/command/defaults/DefaultGamemodeCommand.php index 74a4f5c92b..6e3957ce9b 100644 --- a/src/pocketmine/command/defaults/DefaultGamemodeCommand.php +++ b/src/pocketmine/command/defaults/DefaultGamemodeCommand.php @@ -25,8 +25,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; -use pocketmine\GameMode; use pocketmine\lang\TranslationContainer; +use pocketmine\player\GameMode; use function count; class DefaultGamemodeCommand extends VanillaCommand{ diff --git a/src/pocketmine/command/defaults/DeopCommand.php b/src/pocketmine/command/defaults/DeopCommand.php index 0dc92755f3..c9f052f120 100644 --- a/src/pocketmine/command/defaults/DeopCommand.php +++ b/src/pocketmine/command/defaults/DeopCommand.php @@ -27,7 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function array_shift; use function count; diff --git a/src/pocketmine/command/defaults/GamemodeCommand.php b/src/pocketmine/command/defaults/GamemodeCommand.php index 5a0aa01a8f..d520f9879e 100644 --- a/src/pocketmine/command/defaults/GamemodeCommand.php +++ b/src/pocketmine/command/defaults/GamemodeCommand.php @@ -26,9 +26,9 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; -use pocketmine\GameMode; use pocketmine\lang\TranslationContainer; -use pocketmine\Player; +use pocketmine\player\GameMode; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function count; diff --git a/src/pocketmine/command/defaults/KickCommand.php b/src/pocketmine/command/defaults/KickCommand.php index 1d10cb2def..126215e410 100644 --- a/src/pocketmine/command/defaults/KickCommand.php +++ b/src/pocketmine/command/defaults/KickCommand.php @@ -27,7 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function array_shift; use function count; diff --git a/src/pocketmine/command/defaults/KillCommand.php b/src/pocketmine/command/defaults/KillCommand.php index b6326aedd7..ee5ed3ecfe 100644 --- a/src/pocketmine/command/defaults/KillCommand.php +++ b/src/pocketmine/command/defaults/KillCommand.php @@ -28,7 +28,7 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\lang\TranslationContainer; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function count; diff --git a/src/pocketmine/command/defaults/ListCommand.php b/src/pocketmine/command/defaults/ListCommand.php index 6fe084b1e1..7b7b4be55b 100644 --- a/src/pocketmine/command/defaults/ListCommand.php +++ b/src/pocketmine/command/defaults/ListCommand.php @@ -25,7 +25,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\lang\TranslationContainer; -use pocketmine\Player; +use pocketmine\player\Player; use function array_filter; use function array_map; use function count; diff --git a/src/pocketmine/command/defaults/MeCommand.php b/src/pocketmine/command/defaults/MeCommand.php index d9aadd7f44..8b6d9a7fb7 100644 --- a/src/pocketmine/command/defaults/MeCommand.php +++ b/src/pocketmine/command/defaults/MeCommand.php @@ -26,7 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function count; use function implode; diff --git a/src/pocketmine/command/defaults/OpCommand.php b/src/pocketmine/command/defaults/OpCommand.php index 5f677a4abe..fd711d98c2 100644 --- a/src/pocketmine/command/defaults/OpCommand.php +++ b/src/pocketmine/command/defaults/OpCommand.php @@ -27,7 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function array_shift; use function count; diff --git a/src/pocketmine/command/defaults/ParticleCommand.php b/src/pocketmine/command/defaults/ParticleCommand.php index ddec2514b1..9a04c845f9 100644 --- a/src/pocketmine/command/defaults/ParticleCommand.php +++ b/src/pocketmine/command/defaults/ParticleCommand.php @@ -30,7 +30,7 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\Random; use pocketmine\utils\TextFormat; use pocketmine\world\particle\AngryVillagerParticle; diff --git a/src/pocketmine/command/defaults/SayCommand.php b/src/pocketmine/command/defaults/SayCommand.php index 841b1bb041..709d68facf 100644 --- a/src/pocketmine/command/defaults/SayCommand.php +++ b/src/pocketmine/command/defaults/SayCommand.php @@ -27,7 +27,7 @@ use pocketmine\command\CommandSender; use pocketmine\command\ConsoleCommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function count; use function implode; diff --git a/src/pocketmine/command/defaults/SeedCommand.php b/src/pocketmine/command/defaults/SeedCommand.php index 9ea9fb26fd..1ce522ff6d 100644 --- a/src/pocketmine/command/defaults/SeedCommand.php +++ b/src/pocketmine/command/defaults/SeedCommand.php @@ -25,7 +25,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\lang\TranslationContainer; -use pocketmine\Player; +use pocketmine\player\Player; class SeedCommand extends VanillaCommand{ diff --git a/src/pocketmine/command/defaults/SetWorldSpawnCommand.php b/src/pocketmine/command/defaults/SetWorldSpawnCommand.php index f406b6a460..641de76b2e 100644 --- a/src/pocketmine/command/defaults/SetWorldSpawnCommand.php +++ b/src/pocketmine/command/defaults/SetWorldSpawnCommand.php @@ -28,7 +28,7 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function count; use function round; diff --git a/src/pocketmine/command/defaults/SpawnpointCommand.php b/src/pocketmine/command/defaults/SpawnpointCommand.php index eac5caafa7..a0f87ca618 100644 --- a/src/pocketmine/command/defaults/SpawnpointCommand.php +++ b/src/pocketmine/command/defaults/SpawnpointCommand.php @@ -27,7 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; use pocketmine\world\Position; use pocketmine\world\World; diff --git a/src/pocketmine/command/defaults/TeleportCommand.php b/src/pocketmine/command/defaults/TeleportCommand.php index 353a33f4fe..8170fbb6dd 100644 --- a/src/pocketmine/command/defaults/TeleportCommand.php +++ b/src/pocketmine/command/defaults/TeleportCommand.php @@ -28,7 +28,7 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function array_filter; use function array_values; diff --git a/src/pocketmine/command/defaults/TellCommand.php b/src/pocketmine/command/defaults/TellCommand.php index ed1c3f05ec..443d1e9794 100644 --- a/src/pocketmine/command/defaults/TellCommand.php +++ b/src/pocketmine/command/defaults/TellCommand.php @@ -27,7 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function array_shift; use function count; diff --git a/src/pocketmine/command/defaults/TimeCommand.php b/src/pocketmine/command/defaults/TimeCommand.php index 5b91adfa1f..91cc1cbc7f 100644 --- a/src/pocketmine/command/defaults/TimeCommand.php +++ b/src/pocketmine/command/defaults/TimeCommand.php @@ -27,7 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; use pocketmine\world\World; use function count; diff --git a/src/pocketmine/command/defaults/TimingsCommand.php b/src/pocketmine/command/defaults/TimingsCommand.php index 2c17170a4a..a926d554a5 100644 --- a/src/pocketmine/command/defaults/TimingsCommand.php +++ b/src/pocketmine/command/defaults/TimingsCommand.php @@ -26,7 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\scheduler\BulkCurlTask; use pocketmine\timings\TimingsHandler; use pocketmine\utils\InternetException; diff --git a/src/pocketmine/command/defaults/TransferServerCommand.php b/src/pocketmine/command/defaults/TransferServerCommand.php index ee58217066..ebf1a4af18 100644 --- a/src/pocketmine/command/defaults/TransferServerCommand.php +++ b/src/pocketmine/command/defaults/TransferServerCommand.php @@ -27,7 +27,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; -use pocketmine\Player; +use pocketmine\player\Player; use function count; class TransferServerCommand extends VanillaCommand{ diff --git a/src/pocketmine/command/defaults/WhitelistCommand.php b/src/pocketmine/command/defaults/WhitelistCommand.php index aed16e033e..e53c741646 100644 --- a/src/pocketmine/command/defaults/WhitelistCommand.php +++ b/src/pocketmine/command/defaults/WhitelistCommand.php @@ -27,7 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function count; use function implode; diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index ee58ad42e8..db768c7faf 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -57,7 +57,7 @@ use pocketmine\network\mcpe\protocol\types\DataPropertyManager; use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\EntityMetadataTypes; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\plugin\Plugin; use pocketmine\Server; use pocketmine\timings\Timings; diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 5f8f1bd46a..33339e7e14 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -53,7 +53,7 @@ use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\EntityMetadataTypes; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\network\mcpe\protocol\types\PlayerMetadataFlags; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\UUID; use pocketmine\world\sound\TotemUseSound; use pocketmine\world\sound\XpCollectSound; diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index f01f4b7005..cb24348181 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -48,7 +48,7 @@ use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\timings\Timings; use pocketmine\utils\Binary; use pocketmine\utils\Color; diff --git a/src/pocketmine/entity/effect/LevitationEffect.php b/src/pocketmine/entity/effect/LevitationEffect.php index 746ad49adf..44e9caccdf 100644 --- a/src/pocketmine/entity/effect/LevitationEffect.php +++ b/src/pocketmine/entity/effect/LevitationEffect.php @@ -25,7 +25,7 @@ namespace pocketmine\entity\effect; use pocketmine\entity\Entity; use pocketmine\entity\Living; -use pocketmine\Player; +use pocketmine\player\Player; class LevitationEffect extends Effect{ diff --git a/src/pocketmine/entity/object/ExperienceOrb.php b/src/pocketmine/entity/object/ExperienceOrb.php index 612f055f5b..17af49d89c 100644 --- a/src/pocketmine/entity/object/ExperienceOrb.php +++ b/src/pocketmine/entity/object/ExperienceOrb.php @@ -29,7 +29,7 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ShortTag; use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; -use pocketmine\Player; +use pocketmine\player\Player; use function sqrt; class ExperienceOrb extends Entity{ diff --git a/src/pocketmine/entity/object/ItemEntity.php b/src/pocketmine/entity/object/ItemEntity.php index d2a14732ac..fcb5727ffa 100644 --- a/src/pocketmine/entity/object/ItemEntity.php +++ b/src/pocketmine/entity/object/ItemEntity.php @@ -33,7 +33,7 @@ use pocketmine\item\ItemIds; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\AddItemEntityPacket; use pocketmine\network\mcpe\protocol\TakeItemEntityPacket; -use pocketmine\Player; +use pocketmine\player\Player; use function get_class; use function max; diff --git a/src/pocketmine/entity/object/Painting.php b/src/pocketmine/entity/object/Painting.php index 2b38a835c3..3f1b26a3f1 100644 --- a/src/pocketmine/entity/object/Painting.php +++ b/src/pocketmine/entity/object/Painting.php @@ -36,7 +36,7 @@ use pocketmine\math\Vector3; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\AddPaintingPacket; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\particle\DestroyBlockParticle; use pocketmine\world\World; use function ceil; diff --git a/src/pocketmine/entity/projectile/Arrow.php b/src/pocketmine/entity/projectile/Arrow.php index f3c6c6a2a7..ddc39e3a83 100644 --- a/src/pocketmine/entity/projectile/Arrow.php +++ b/src/pocketmine/entity/projectile/Arrow.php @@ -34,7 +34,7 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\TakeItemEntityPacket; use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\sound\ArrowHitSound; use pocketmine\world\World; use function mt_rand; diff --git a/src/pocketmine/event/block/BlockBreakEvent.php b/src/pocketmine/event/block/BlockBreakEvent.php index 16d97b7133..a01fc6ccbe 100644 --- a/src/pocketmine/event/block/BlockBreakEvent.php +++ b/src/pocketmine/event/block/BlockBreakEvent.php @@ -27,7 +27,7 @@ use pocketmine\block\Block; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\item\Item; -use pocketmine\Player; +use pocketmine\player\Player; /** * Called when a player destroys a block somewhere in the world. diff --git a/src/pocketmine/event/block/BlockPlaceEvent.php b/src/pocketmine/event/block/BlockPlaceEvent.php index d7c51cf671..57aaacc37d 100644 --- a/src/pocketmine/event/block/BlockPlaceEvent.php +++ b/src/pocketmine/event/block/BlockPlaceEvent.php @@ -27,7 +27,7 @@ use pocketmine\block\Block; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\item\Item; -use pocketmine\Player; +use pocketmine\player\Player; /** * Called when a player places a block diff --git a/src/pocketmine/event/block/SignChangeEvent.php b/src/pocketmine/event/block/SignChangeEvent.php index a695089425..70c7a789c1 100644 --- a/src/pocketmine/event/block/SignChangeEvent.php +++ b/src/pocketmine/event/block/SignChangeEvent.php @@ -27,7 +27,7 @@ use pocketmine\block\Sign; use pocketmine\block\utils\SignText; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\Player; +use pocketmine\player\Player; /** * Called when a sign's text is changed by a player. diff --git a/src/pocketmine/event/inventory/CraftItemEvent.php b/src/pocketmine/event/inventory/CraftItemEvent.php index 8630331b49..71ff4a1cb5 100644 --- a/src/pocketmine/event/inventory/CraftItemEvent.php +++ b/src/pocketmine/event/inventory/CraftItemEvent.php @@ -29,7 +29,7 @@ use pocketmine\event\Event; use pocketmine\inventory\CraftingRecipe; use pocketmine\inventory\transaction\CraftingTransaction; use pocketmine\item\Item; -use pocketmine\Player; +use pocketmine\player\Player; class CraftItemEvent extends Event implements Cancellable{ use CancellableTrait; diff --git a/src/pocketmine/event/inventory/InventoryCloseEvent.php b/src/pocketmine/event/inventory/InventoryCloseEvent.php index 929efb8d71..f123fc4974 100644 --- a/src/pocketmine/event/inventory/InventoryCloseEvent.php +++ b/src/pocketmine/event/inventory/InventoryCloseEvent.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\event\inventory; use pocketmine\inventory\Inventory; -use pocketmine\Player; +use pocketmine\player\Player; class InventoryCloseEvent extends InventoryEvent{ /** @var Player */ diff --git a/src/pocketmine/event/inventory/InventoryOpenEvent.php b/src/pocketmine/event/inventory/InventoryOpenEvent.php index 79ccb8ec26..1eb43eb746 100644 --- a/src/pocketmine/event/inventory/InventoryOpenEvent.php +++ b/src/pocketmine/event/inventory/InventoryOpenEvent.php @@ -26,7 +26,7 @@ namespace pocketmine\event\inventory; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\inventory\Inventory; -use pocketmine\Player; +use pocketmine\player\Player; class InventoryOpenEvent extends InventoryEvent implements Cancellable{ use CancellableTrait; diff --git a/src/pocketmine/event/player/PlayerAchievementAwardedEvent.php b/src/pocketmine/event/player/PlayerAchievementAwardedEvent.php index da9ebea5de..7edcb70190 100644 --- a/src/pocketmine/event/player/PlayerAchievementAwardedEvent.php +++ b/src/pocketmine/event/player/PlayerAchievementAwardedEvent.php @@ -25,7 +25,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\Player; +use pocketmine\player\Player; /** * Called when a player is awarded an achievement diff --git a/src/pocketmine/event/player/PlayerAnimationEvent.php b/src/pocketmine/event/player/PlayerAnimationEvent.php index af6ad556fc..fb965fe6c7 100644 --- a/src/pocketmine/event/player/PlayerAnimationEvent.php +++ b/src/pocketmine/event/player/PlayerAnimationEvent.php @@ -25,7 +25,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\Player; +use pocketmine\player\Player; /** * Called when a player does an animation diff --git a/src/pocketmine/event/player/PlayerBedEnterEvent.php b/src/pocketmine/event/player/PlayerBedEnterEvent.php index be2ee766c8..c25c28e268 100644 --- a/src/pocketmine/event/player/PlayerBedEnterEvent.php +++ b/src/pocketmine/event/player/PlayerBedEnterEvent.php @@ -26,7 +26,7 @@ namespace pocketmine\event\player; use pocketmine\block\Block; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\Player; +use pocketmine\player\Player; class PlayerBedEnterEvent extends PlayerEvent implements Cancellable{ use CancellableTrait; diff --git a/src/pocketmine/event/player/PlayerBedLeaveEvent.php b/src/pocketmine/event/player/PlayerBedLeaveEvent.php index 005bc750ce..0231edd362 100644 --- a/src/pocketmine/event/player/PlayerBedLeaveEvent.php +++ b/src/pocketmine/event/player/PlayerBedLeaveEvent.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\block\Block; -use pocketmine\Player; +use pocketmine\player\Player; class PlayerBedLeaveEvent extends PlayerEvent{ /** @var Block */ diff --git a/src/pocketmine/event/player/PlayerBlockPickEvent.php b/src/pocketmine/event/player/PlayerBlockPickEvent.php index 9cbb092219..c365cda167 100644 --- a/src/pocketmine/event/player/PlayerBlockPickEvent.php +++ b/src/pocketmine/event/player/PlayerBlockPickEvent.php @@ -27,7 +27,7 @@ use pocketmine\block\Block; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\item\Item; -use pocketmine\Player; +use pocketmine\player\Player; /** * Called when a player middle-clicks on a block to get an item in creative mode. diff --git a/src/pocketmine/event/player/PlayerBucketEvent.php b/src/pocketmine/event/player/PlayerBucketEvent.php index 8aba82ae52..1080b533fb 100644 --- a/src/pocketmine/event/player/PlayerBucketEvent.php +++ b/src/pocketmine/event/player/PlayerBucketEvent.php @@ -27,7 +27,7 @@ use pocketmine\block\Block; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\item\Item; -use pocketmine\Player; +use pocketmine\player\Player; /** * @allowHandle diff --git a/src/pocketmine/event/player/PlayerChangeSkinEvent.php b/src/pocketmine/event/player/PlayerChangeSkinEvent.php index 5202ff974b..0aa3802440 100644 --- a/src/pocketmine/event/player/PlayerChangeSkinEvent.php +++ b/src/pocketmine/event/player/PlayerChangeSkinEvent.php @@ -26,7 +26,7 @@ namespace pocketmine\event\player; use pocketmine\entity\Skin; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\Player; +use pocketmine\player\Player; /** * Called when a player changes their skin in-game. diff --git a/src/pocketmine/event/player/PlayerChatEvent.php b/src/pocketmine/event/player/PlayerChatEvent.php index ca54c1a5d1..9bafa319a4 100644 --- a/src/pocketmine/event/player/PlayerChatEvent.php +++ b/src/pocketmine/event/player/PlayerChatEvent.php @@ -26,7 +26,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\permission\PermissionManager; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\Server; /** diff --git a/src/pocketmine/event/player/PlayerCommandPreprocessEvent.php b/src/pocketmine/event/player/PlayerCommandPreprocessEvent.php index 2c8951c6fa..1831e1d19e 100644 --- a/src/pocketmine/event/player/PlayerCommandPreprocessEvent.php +++ b/src/pocketmine/event/player/PlayerCommandPreprocessEvent.php @@ -25,7 +25,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\Player; +use pocketmine\player\Player; /** * Called when a player runs a command or chats, early in the process diff --git a/src/pocketmine/event/player/PlayerCreationEvent.php b/src/pocketmine/event/player/PlayerCreationEvent.php index a1d8b2a58d..5976e0605d 100644 --- a/src/pocketmine/event/player/PlayerCreationEvent.php +++ b/src/pocketmine/event/player/PlayerCreationEvent.php @@ -26,7 +26,7 @@ namespace pocketmine\event\player; use pocketmine\event\Event; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\NetworkInterface; -use pocketmine\Player; +use pocketmine\player\Player; use function is_a; /** diff --git a/src/pocketmine/event/player/PlayerDataSaveEvent.php b/src/pocketmine/event/player/PlayerDataSaveEvent.php index cb23ad01dd..5f08d4fb4c 100644 --- a/src/pocketmine/event/player/PlayerDataSaveEvent.php +++ b/src/pocketmine/event/player/PlayerDataSaveEvent.php @@ -26,8 +26,8 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\event\Event; -use pocketmine\IPlayer; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\player\IPlayer; use pocketmine\Server; /** diff --git a/src/pocketmine/event/player/PlayerDeathEvent.php b/src/pocketmine/event/player/PlayerDeathEvent.php index 74f41cf37a..b9653d27d6 100644 --- a/src/pocketmine/event/player/PlayerDeathEvent.php +++ b/src/pocketmine/event/player/PlayerDeathEvent.php @@ -32,7 +32,7 @@ use pocketmine\event\entity\EntityDeathEvent; use pocketmine\item\Item; use pocketmine\lang\TextContainer; use pocketmine\lang\TranslationContainer; -use pocketmine\Player; +use pocketmine\player\Player; class PlayerDeathEvent extends EntityDeathEvent{ /** @var Player */ diff --git a/src/pocketmine/event/player/PlayerDropItemEvent.php b/src/pocketmine/event/player/PlayerDropItemEvent.php index 0cf50d995e..46a88ec9e9 100644 --- a/src/pocketmine/event/player/PlayerDropItemEvent.php +++ b/src/pocketmine/event/player/PlayerDropItemEvent.php @@ -26,7 +26,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\item\Item; -use pocketmine\Player; +use pocketmine\player\Player; /** * Called when a player tries to drop an item from its hotbar diff --git a/src/pocketmine/event/player/PlayerEditBookEvent.php b/src/pocketmine/event/player/PlayerEditBookEvent.php index ee0e0b252f..074bf3f132 100644 --- a/src/pocketmine/event/player/PlayerEditBookEvent.php +++ b/src/pocketmine/event/player/PlayerEditBookEvent.php @@ -26,7 +26,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\item\WritableBookBase; -use pocketmine\Player; +use pocketmine\player\Player; class PlayerEditBookEvent extends PlayerEvent implements Cancellable{ use CancellableTrait; diff --git a/src/pocketmine/event/player/PlayerEvent.php b/src/pocketmine/event/player/PlayerEvent.php index 77cce34441..8be23d3509 100644 --- a/src/pocketmine/event/player/PlayerEvent.php +++ b/src/pocketmine/event/player/PlayerEvent.php @@ -27,7 +27,7 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Event; -use pocketmine\Player; +use pocketmine\player\Player; abstract class PlayerEvent extends Event{ /** @var Player */ diff --git a/src/pocketmine/event/player/PlayerGameModeChangeEvent.php b/src/pocketmine/event/player/PlayerGameModeChangeEvent.php index 8e4415bd9e..926d17d2bc 100644 --- a/src/pocketmine/event/player/PlayerGameModeChangeEvent.php +++ b/src/pocketmine/event/player/PlayerGameModeChangeEvent.php @@ -25,8 +25,8 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\GameMode; -use pocketmine\Player; +use pocketmine\player\GameMode; +use pocketmine\player\Player; /** * Called when a player has its gamemode changed diff --git a/src/pocketmine/event/player/PlayerInteractEvent.php b/src/pocketmine/event/player/PlayerInteractEvent.php index 5b4a86cd38..3d01955fcc 100644 --- a/src/pocketmine/event/player/PlayerInteractEvent.php +++ b/src/pocketmine/event/player/PlayerInteractEvent.php @@ -28,7 +28,7 @@ use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\item\Item; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; /** * Called when a player interacts or touches a block (including air?) diff --git a/src/pocketmine/event/player/PlayerItemConsumeEvent.php b/src/pocketmine/event/player/PlayerItemConsumeEvent.php index aac350fd01..f08a5847fd 100644 --- a/src/pocketmine/event/player/PlayerItemConsumeEvent.php +++ b/src/pocketmine/event/player/PlayerItemConsumeEvent.php @@ -26,7 +26,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\item\Item; -use pocketmine\Player; +use pocketmine\player\Player; /** * Called when a player eats something diff --git a/src/pocketmine/event/player/PlayerItemHeldEvent.php b/src/pocketmine/event/player/PlayerItemHeldEvent.php index 6f81004178..7fbd3f4cc1 100644 --- a/src/pocketmine/event/player/PlayerItemHeldEvent.php +++ b/src/pocketmine/event/player/PlayerItemHeldEvent.php @@ -26,7 +26,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\item\Item; -use pocketmine\Player; +use pocketmine\player\Player; class PlayerItemHeldEvent extends PlayerEvent implements Cancellable{ use CancellableTrait; diff --git a/src/pocketmine/event/player/PlayerItemUseEvent.php b/src/pocketmine/event/player/PlayerItemUseEvent.php index c7aafd61ba..ec804115a8 100644 --- a/src/pocketmine/event/player/PlayerItemUseEvent.php +++ b/src/pocketmine/event/player/PlayerItemUseEvent.php @@ -27,7 +27,7 @@ use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\item\Item; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; /** * Called when a player uses its held item, for example when throwing a projectile. diff --git a/src/pocketmine/event/player/PlayerJoinEvent.php b/src/pocketmine/event/player/PlayerJoinEvent.php index 36609ec820..64b7a6c2d5 100644 --- a/src/pocketmine/event/player/PlayerJoinEvent.php +++ b/src/pocketmine/event/player/PlayerJoinEvent.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\lang\TextContainer; -use pocketmine\Player; +use pocketmine\player\Player; /** * Called when the player spawns in the world after logging in, when they first see the terrain. diff --git a/src/pocketmine/event/player/PlayerJumpEvent.php b/src/pocketmine/event/player/PlayerJumpEvent.php index 85d8b3a4d5..e3e67da383 100644 --- a/src/pocketmine/event/player/PlayerJumpEvent.php +++ b/src/pocketmine/event/player/PlayerJumpEvent.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\event\player; -use pocketmine\Player; +use pocketmine\player\Player; /** * Called when a player jumps diff --git a/src/pocketmine/event/player/PlayerKickEvent.php b/src/pocketmine/event/player/PlayerKickEvent.php index b199a9410c..971269c2c7 100644 --- a/src/pocketmine/event/player/PlayerKickEvent.php +++ b/src/pocketmine/event/player/PlayerKickEvent.php @@ -26,7 +26,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\lang\TextContainer; -use pocketmine\Player; +use pocketmine\player\Player; /** * Called when a player leaves the server diff --git a/src/pocketmine/event/player/PlayerLoginEvent.php b/src/pocketmine/event/player/PlayerLoginEvent.php index 298f2a1b2e..979750090c 100644 --- a/src/pocketmine/event/player/PlayerLoginEvent.php +++ b/src/pocketmine/event/player/PlayerLoginEvent.php @@ -25,7 +25,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\Player; +use pocketmine\player\Player; /** * Called after the player has successfully authenticated, before it spawns. The player is on the loading screen when diff --git a/src/pocketmine/event/player/PlayerMoveEvent.php b/src/pocketmine/event/player/PlayerMoveEvent.php index f949abd671..7678eed053 100644 --- a/src/pocketmine/event/player/PlayerMoveEvent.php +++ b/src/pocketmine/event/player/PlayerMoveEvent.php @@ -25,8 +25,8 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; +use pocketmine\player\Player; use pocketmine\world\Location; -use pocketmine\Player; class PlayerMoveEvent extends PlayerEvent implements Cancellable{ use CancellableTrait; diff --git a/src/pocketmine/event/player/PlayerPreLoginEvent.php b/src/pocketmine/event/player/PlayerPreLoginEvent.php index fef54b7f9a..9a566813ec 100644 --- a/src/pocketmine/event/player/PlayerPreLoginEvent.php +++ b/src/pocketmine/event/player/PlayerPreLoginEvent.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\event\Event; -use pocketmine\PlayerInfo; +use pocketmine\player\PlayerInfo; use function array_keys; /** diff --git a/src/pocketmine/event/player/PlayerQuitEvent.php b/src/pocketmine/event/player/PlayerQuitEvent.php index 24460db301..028548b153 100644 --- a/src/pocketmine/event/player/PlayerQuitEvent.php +++ b/src/pocketmine/event/player/PlayerQuitEvent.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\event\player; use pocketmine\lang\TranslationContainer; -use pocketmine\Player; +use pocketmine\player\Player; /** * Called when a player leaves the server diff --git a/src/pocketmine/event/player/PlayerRespawnEvent.php b/src/pocketmine/event/player/PlayerRespawnEvent.php index 1df9eac36b..926da5e178 100644 --- a/src/pocketmine/event/player/PlayerRespawnEvent.php +++ b/src/pocketmine/event/player/PlayerRespawnEvent.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\event\player; +use pocketmine\player\Player; use pocketmine\world\Position; -use pocketmine\Player; /** * Called when a player is respawned diff --git a/src/pocketmine/event/player/PlayerToggleFlightEvent.php b/src/pocketmine/event/player/PlayerToggleFlightEvent.php index 298947c423..1547e7ed2b 100644 --- a/src/pocketmine/event/player/PlayerToggleFlightEvent.php +++ b/src/pocketmine/event/player/PlayerToggleFlightEvent.php @@ -25,7 +25,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\Player; +use pocketmine\player\Player; class PlayerToggleFlightEvent extends PlayerEvent implements Cancellable{ use CancellableTrait; diff --git a/src/pocketmine/event/player/PlayerToggleSneakEvent.php b/src/pocketmine/event/player/PlayerToggleSneakEvent.php index 8ba0ac5990..14dd0d4fec 100644 --- a/src/pocketmine/event/player/PlayerToggleSneakEvent.php +++ b/src/pocketmine/event/player/PlayerToggleSneakEvent.php @@ -25,7 +25,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\Player; +use pocketmine\player\Player; class PlayerToggleSneakEvent extends PlayerEvent implements Cancellable{ use CancellableTrait; diff --git a/src/pocketmine/event/player/PlayerToggleSprintEvent.php b/src/pocketmine/event/player/PlayerToggleSprintEvent.php index 323df0120a..67bae14245 100644 --- a/src/pocketmine/event/player/PlayerToggleSprintEvent.php +++ b/src/pocketmine/event/player/PlayerToggleSprintEvent.php @@ -25,7 +25,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\Player; +use pocketmine\player\Player; class PlayerToggleSprintEvent extends PlayerEvent implements Cancellable{ use CancellableTrait; diff --git a/src/pocketmine/event/player/PlayerTransferEvent.php b/src/pocketmine/event/player/PlayerTransferEvent.php index 31baa90dc2..082dd619b4 100644 --- a/src/pocketmine/event/player/PlayerTransferEvent.php +++ b/src/pocketmine/event/player/PlayerTransferEvent.php @@ -25,7 +25,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\Player; +use pocketmine\player\Player; class PlayerTransferEvent extends PlayerEvent implements Cancellable{ use CancellableTrait; diff --git a/src/pocketmine/event/player/cheat/PlayerIllegalMoveEvent.php b/src/pocketmine/event/player/cheat/PlayerIllegalMoveEvent.php index 454cb7f385..3596f6d11d 100644 --- a/src/pocketmine/event/player/cheat/PlayerIllegalMoveEvent.php +++ b/src/pocketmine/event/player/cheat/PlayerIllegalMoveEvent.php @@ -27,7 +27,7 @@ namespace pocketmine\event\player\cheat; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; /** * Called when a player attempts to perform movement cheats such as clipping through blocks. diff --git a/src/pocketmine/event/server/QueryRegenerateEvent.php b/src/pocketmine/event/server/QueryRegenerateEvent.php index d7e49c22f3..fc007edcaf 100644 --- a/src/pocketmine/event/server/QueryRegenerateEvent.php +++ b/src/pocketmine/event/server/QueryRegenerateEvent.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\event\server; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\plugin\Plugin; use pocketmine\Server; use pocketmine\utils\Binary; diff --git a/src/pocketmine/form/Form.php b/src/pocketmine/form/Form.php index e4a2fcc5ad..1e6b43dd70 100644 --- a/src/pocketmine/form/Form.php +++ b/src/pocketmine/form/Form.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\form; -use pocketmine\Player; +use pocketmine\player\Player; /** * Form implementations must implement this interface to be able to utilize the Player form-sending mechanism. diff --git a/src/pocketmine/inventory/AnvilInventory.php b/src/pocketmine/inventory/AnvilInventory.php index 94f327212c..95b932d9c4 100644 --- a/src/pocketmine/inventory/AnvilInventory.php +++ b/src/pocketmine/inventory/AnvilInventory.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\inventory; use pocketmine\network\mcpe\protocol\types\WindowTypes; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\Position; class AnvilInventory extends ContainerInventory{ diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index b71ac0453a..dc29486627 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -25,7 +25,7 @@ namespace pocketmine\inventory; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\Player; +use pocketmine\player\Player; use function array_slice; use function count; use function max; diff --git a/src/pocketmine/inventory/ChestInventory.php b/src/pocketmine/inventory/ChestInventory.php index 539e93bc95..f19ec25178 100644 --- a/src/pocketmine/inventory/ChestInventory.php +++ b/src/pocketmine/inventory/ChestInventory.php @@ -26,7 +26,7 @@ namespace pocketmine\inventory; use pocketmine\block\tile\Chest; use pocketmine\network\mcpe\protocol\BlockEventPacket; use pocketmine\network\mcpe\protocol\types\WindowTypes; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\sound\ChestCloseSound; use pocketmine\world\sound\ChestOpenSound; use pocketmine\world\sound\Sound; diff --git a/src/pocketmine/inventory/ContainerInventory.php b/src/pocketmine/inventory/ContainerInventory.php index cd4ad6ddd4..48a4a2be51 100644 --- a/src/pocketmine/inventory/ContainerInventory.php +++ b/src/pocketmine/inventory/ContainerInventory.php @@ -27,7 +27,7 @@ use pocketmine\entity\Entity; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\ContainerClosePacket; use pocketmine\network\mcpe\protocol\ContainerOpenPacket; -use pocketmine\Player; +use pocketmine\player\Player; abstract class ContainerInventory extends BaseInventory{ /** @var Vector3 */ diff --git a/src/pocketmine/inventory/CraftingGrid.php b/src/pocketmine/inventory/CraftingGrid.php index bd29d8c8b4..ea8663dd9a 100644 --- a/src/pocketmine/inventory/CraftingGrid.php +++ b/src/pocketmine/inventory/CraftingGrid.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\inventory; use pocketmine\item\Item; -use pocketmine\Player; +use pocketmine\player\Player; use function max; use function min; use const PHP_INT_MAX; diff --git a/src/pocketmine/inventory/DoubleChestInventory.php b/src/pocketmine/inventory/DoubleChestInventory.php index bab524746e..a4861a2905 100644 --- a/src/pocketmine/inventory/DoubleChestInventory.php +++ b/src/pocketmine/inventory/DoubleChestInventory.php @@ -25,7 +25,7 @@ namespace pocketmine\inventory; use pocketmine\block\tile\Chest; use pocketmine\item\Item; -use pocketmine\Player; +use pocketmine\player\Player; use function array_merge; use function count; diff --git a/src/pocketmine/inventory/EnchantInventory.php b/src/pocketmine/inventory/EnchantInventory.php index 30d4994b1f..d4510767b6 100644 --- a/src/pocketmine/inventory/EnchantInventory.php +++ b/src/pocketmine/inventory/EnchantInventory.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\inventory; use pocketmine\network\mcpe\protocol\types\WindowTypes; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\Position; class EnchantInventory extends ContainerInventory{ diff --git a/src/pocketmine/inventory/Inventory.php b/src/pocketmine/inventory/Inventory.php index e07318db2c..0224ba4cfb 100644 --- a/src/pocketmine/inventory/Inventory.php +++ b/src/pocketmine/inventory/Inventory.php @@ -27,7 +27,7 @@ declare(strict_types=1); namespace pocketmine\inventory; use pocketmine\item\Item; -use pocketmine\Player; +use pocketmine\player\Player; interface Inventory{ public const MAX_STACK = 64; diff --git a/src/pocketmine/inventory/PlayerCursorInventory.php b/src/pocketmine/inventory/PlayerCursorInventory.php index a016d3b4f2..07ff443f77 100644 --- a/src/pocketmine/inventory/PlayerCursorInventory.php +++ b/src/pocketmine/inventory/PlayerCursorInventory.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\inventory; -use pocketmine\Player; +use pocketmine\player\Player; class PlayerCursorInventory extends BaseInventory{ /** @var Player */ diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index 909fd3ff2e..9c3f1f2c52 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -27,7 +27,7 @@ use pocketmine\entity\Human; use pocketmine\item\Item; use pocketmine\network\mcpe\protocol\MobEquipmentPacket; use pocketmine\network\mcpe\protocol\types\ContainerIds; -use pocketmine\Player; +use pocketmine\player\Player; use function in_array; use function is_array; diff --git a/src/pocketmine/inventory/transaction/InventoryTransaction.php b/src/pocketmine/inventory/transaction/InventoryTransaction.php index 199e8aa275..ea73c22fc2 100644 --- a/src/pocketmine/inventory/transaction/InventoryTransaction.php +++ b/src/pocketmine/inventory/transaction/InventoryTransaction.php @@ -28,7 +28,7 @@ use pocketmine\inventory\Inventory; use pocketmine\inventory\transaction\action\InventoryAction; use pocketmine\inventory\transaction\action\SlotChangeAction; use pocketmine\item\Item; -use pocketmine\Player; +use pocketmine\player\Player; use function array_keys; use function assert; use function count; diff --git a/src/pocketmine/inventory/transaction/action/CreateItemAction.php b/src/pocketmine/inventory/transaction/action/CreateItemAction.php index 62450dbbe4..2ecd868a63 100644 --- a/src/pocketmine/inventory/transaction/action/CreateItemAction.php +++ b/src/pocketmine/inventory/transaction/action/CreateItemAction.php @@ -26,7 +26,7 @@ namespace pocketmine\inventory\transaction\action; use pocketmine\inventory\CreativeInventory; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\Player; +use pocketmine\player\Player; /** * This action is used by creative players to balance transactions involving the creative inventory menu. diff --git a/src/pocketmine/inventory/transaction/action/DestroyItemAction.php b/src/pocketmine/inventory/transaction/action/DestroyItemAction.php index b97454e56e..d59485c072 100644 --- a/src/pocketmine/inventory/transaction/action/DestroyItemAction.php +++ b/src/pocketmine/inventory/transaction/action/DestroyItemAction.php @@ -25,7 +25,7 @@ namespace pocketmine\inventory\transaction\action; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\Player; +use pocketmine\player\Player; /** * This action type shows up when a creative player puts an item into the creative inventory menu to destroy it. diff --git a/src/pocketmine/inventory/transaction/action/DropItemAction.php b/src/pocketmine/inventory/transaction/action/DropItemAction.php index 3ffab2a728..6c8db64a0e 100644 --- a/src/pocketmine/inventory/transaction/action/DropItemAction.php +++ b/src/pocketmine/inventory/transaction/action/DropItemAction.php @@ -26,7 +26,7 @@ namespace pocketmine\inventory\transaction\action; use pocketmine\event\player\PlayerDropItemEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use pocketmine\Player; +use pocketmine\player\Player; /** * Represents an action involving dropping an item into the world. diff --git a/src/pocketmine/inventory/transaction/action/InventoryAction.php b/src/pocketmine/inventory/transaction/action/InventoryAction.php index 326dbe4400..e5b9c2dad1 100644 --- a/src/pocketmine/inventory/transaction/action/InventoryAction.php +++ b/src/pocketmine/inventory/transaction/action/InventoryAction.php @@ -25,7 +25,7 @@ namespace pocketmine\inventory\transaction\action; use pocketmine\inventory\transaction\InventoryTransaction; use pocketmine\item\Item; -use pocketmine\Player; +use pocketmine\player\Player; /** * Represents an action involving a change that applies in some way to an inventory or other item-source. diff --git a/src/pocketmine/inventory/transaction/action/SlotChangeAction.php b/src/pocketmine/inventory/transaction/action/SlotChangeAction.php index 8aaa70e158..1ec24af632 100644 --- a/src/pocketmine/inventory/transaction/action/SlotChangeAction.php +++ b/src/pocketmine/inventory/transaction/action/SlotChangeAction.php @@ -26,7 +26,7 @@ namespace pocketmine\inventory\transaction\action; use pocketmine\inventory\Inventory; use pocketmine\inventory\transaction\InventoryTransaction; use pocketmine\item\Item; -use pocketmine\Player; +use pocketmine\player\Player; /** * Represents an action causing a change in an inventory slot. diff --git a/src/pocketmine/item/Armor.php b/src/pocketmine/item/Armor.php index f2ceb5adfa..99454c8be3 100644 --- a/src/pocketmine/item/Armor.php +++ b/src/pocketmine/item/Armor.php @@ -31,7 +31,7 @@ use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\ProtectionEnchantment; use pocketmine\math\Vector3; use pocketmine\nbt\tag\IntTag; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\Binary; use pocketmine\utils\Color; use function lcg_value; diff --git a/src/pocketmine/item/Bow.php b/src/pocketmine/item/Bow.php index 51ed4dcdaf..5410844464 100644 --- a/src/pocketmine/item/Bow.php +++ b/src/pocketmine/item/Bow.php @@ -29,7 +29,7 @@ use pocketmine\entity\projectile\Projectile; use pocketmine\event\entity\EntityShootBowEvent; use pocketmine\event\entity\ProjectileLaunchEvent; use pocketmine\item\enchantment\Enchantment; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\sound\BowShootSound; use function intdiv; use function min; diff --git a/src/pocketmine/item/Bucket.php b/src/pocketmine/item/Bucket.php index 095ae7fd94..3497b9a4b9 100644 --- a/src/pocketmine/item/Bucket.php +++ b/src/pocketmine/item/Bucket.php @@ -29,7 +29,7 @@ use pocketmine\block\BlockLegacyIds; use pocketmine\block\Liquid; use pocketmine\event\player\PlayerBucketFillEvent; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; class Bucket extends Item{ diff --git a/src/pocketmine/item/FlintSteel.php b/src/pocketmine/item/FlintSteel.php index 3478ce5a59..7d8e071198 100644 --- a/src/pocketmine/item/FlintSteel.php +++ b/src/pocketmine/item/FlintSteel.php @@ -27,7 +27,7 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\sound\FlintSteelSound; use function assert; diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 3c551c9a27..0f6257b5fb 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -43,7 +43,7 @@ use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ShortTag; use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\TreeRoot; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\Binary; use function array_map; use function base64_decode; diff --git a/src/pocketmine/item/LiquidBucket.php b/src/pocketmine/item/LiquidBucket.php index 5ec0efe31d..1f2b74e3cf 100644 --- a/src/pocketmine/item/LiquidBucket.php +++ b/src/pocketmine/item/LiquidBucket.php @@ -29,7 +29,7 @@ use pocketmine\block\Lava; use pocketmine\block\Liquid; use pocketmine\event\player\PlayerBucketEmptyEvent; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; class LiquidBucket extends Item{ /** @var int|null */ diff --git a/src/pocketmine/item/PaintingItem.php b/src/pocketmine/item/PaintingItem.php index 7018b181e5..9396033373 100644 --- a/src/pocketmine/item/PaintingItem.php +++ b/src/pocketmine/item/PaintingItem.php @@ -30,7 +30,7 @@ use pocketmine\entity\object\PaintingMotive; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -use pocketmine\Player; +use pocketmine\player\Player; use function array_rand; class PaintingItem extends Item{ diff --git a/src/pocketmine/item/ProjectileItem.php b/src/pocketmine/item/ProjectileItem.php index 66adef0b06..b0a939a891 100644 --- a/src/pocketmine/item/ProjectileItem.php +++ b/src/pocketmine/item/ProjectileItem.php @@ -26,11 +26,11 @@ namespace pocketmine\item; use pocketmine\entity\EntityFactory; use pocketmine\entity\projectile\Throwable; use pocketmine\event\entity\ProjectileLaunchEvent; -use pocketmine\world\sound\ThrowSound; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\Utils; +use pocketmine\world\sound\ThrowSound; abstract class ProjectileItem extends Item{ diff --git a/src/pocketmine/item/SpawnEgg.php b/src/pocketmine/item/SpawnEgg.php index f1a52ef891..f09ceee099 100644 --- a/src/pocketmine/item/SpawnEgg.php +++ b/src/pocketmine/item/SpawnEgg.php @@ -27,7 +27,7 @@ use pocketmine\block\Block; use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; use pocketmine\math\Vector3; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\Utils; use function lcg_value; diff --git a/src/pocketmine/metadata/PlayerMetadataStore.php b/src/pocketmine/metadata/PlayerMetadataStore.php index 0c2a967989..3d68804444 100644 --- a/src/pocketmine/metadata/PlayerMetadataStore.php +++ b/src/pocketmine/metadata/PlayerMetadataStore.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\metadata; -use pocketmine\IPlayer; +use pocketmine\player\IPlayer; use pocketmine\plugin\Plugin; use function strtolower; diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 5acdf3b48c..97f952ef9f 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -29,7 +29,6 @@ use pocketmine\event\player\PlayerCreationEvent; use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\event\server\DataPacketSendEvent; use pocketmine\form\Form; -use pocketmine\GameMode; use pocketmine\inventory\CreativeInventory; use pocketmine\inventory\Inventory; use pocketmine\math\Vector3; @@ -74,8 +73,9 @@ use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; use pocketmine\network\NetworkInterface; use pocketmine\network\NetworkSessionManager; -use pocketmine\Player; -use pocketmine\PlayerInfo; +use pocketmine\player\GameMode; +use pocketmine\player\Player; +use pocketmine\player\PlayerInfo; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\BinaryDataException; diff --git a/src/pocketmine/network/mcpe/handler/DeathPacketHandler.php b/src/pocketmine/network/mcpe/handler/DeathPacketHandler.php index 81b7e86ff3..549b0f27d0 100644 --- a/src/pocketmine/network/mcpe/handler/DeathPacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/DeathPacketHandler.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\handler; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\PlayerActionPacket; use pocketmine\network\mcpe\protocol\RespawnPacket; -use pocketmine\Player; +use pocketmine\player\Player; class DeathPacketHandler extends PacketHandler{ diff --git a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php index 25415d7590..ffa4826807 100644 --- a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php @@ -77,7 +77,7 @@ use pocketmine\network\mcpe\protocol\types\NormalTransactionData; use pocketmine\network\mcpe\protocol\types\ReleaseItemTransactionData; use pocketmine\network\mcpe\protocol\types\UseItemOnEntityTransactionData; use pocketmine\network\mcpe\protocol\types\UseItemTransactionData; -use pocketmine\Player; +use pocketmine\player\Player; use function array_push; use function base64_encode; use function fmod; diff --git a/src/pocketmine/network/mcpe/handler/LoginPacketHandler.php b/src/pocketmine/network/mcpe/handler/LoginPacketHandler.php index c9c4c19adb..76bd38f467 100644 --- a/src/pocketmine/network/mcpe/handler/LoginPacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/LoginPacketHandler.php @@ -31,8 +31,8 @@ use pocketmine\network\mcpe\ProcessLoginTask; use pocketmine\network\mcpe\protocol\LoginPacket; use pocketmine\network\mcpe\protocol\PlayStatusPacket; use pocketmine\network\mcpe\protocol\ProtocolInfo; -use pocketmine\Player; -use pocketmine\PlayerInfo; +use pocketmine\player\Player; +use pocketmine\player\PlayerInfo; use pocketmine\Server; use pocketmine\utils\UUID; use function base64_decode; diff --git a/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php b/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php index 701c117b00..1cab9d63cf 100644 --- a/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php @@ -30,7 +30,7 @@ use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; use pocketmine\network\mcpe\protocol\SetLocalPlayerAsInitializedPacket; use pocketmine\network\mcpe\protocol\StartGamePacket; use pocketmine\network\mcpe\protocol\types\DimensionIds; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\Server; /** diff --git a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php index 8318d61593..7d689f73e0 100644 --- a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php +++ b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php @@ -33,7 +33,7 @@ use pocketmine\inventory\transaction\action\SlotChangeAction; use pocketmine\item\Item; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\NetworkBinaryStream; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\utils\BinaryDataException; class NetworkInventoryAction{ diff --git a/src/pocketmine/Achievement.php b/src/pocketmine/player/Achievement.php similarity index 98% rename from src/pocketmine/Achievement.php rename to src/pocketmine/player/Achievement.php index 41049f4c59..76414095a5 100644 --- a/src/pocketmine/Achievement.php +++ b/src/pocketmine/player/Achievement.php @@ -21,9 +21,10 @@ declare(strict_types=1); -namespace pocketmine; +namespace pocketmine\player; use pocketmine\lang\TranslationContainer; +use pocketmine\Server; use pocketmine\utils\TextFormat; /** diff --git a/src/pocketmine/GameMode.php b/src/pocketmine/player/GameMode.php similarity index 99% rename from src/pocketmine/GameMode.php rename to src/pocketmine/player/GameMode.php index 409ebe4b0a..33a37fc808 100644 --- a/src/pocketmine/GameMode.php +++ b/src/pocketmine/player/GameMode.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine; +namespace pocketmine\player; use pocketmine\utils\EnumTrait; diff --git a/src/pocketmine/IPlayer.php b/src/pocketmine/player/IPlayer.php similarity index 98% rename from src/pocketmine/IPlayer.php rename to src/pocketmine/player/IPlayer.php index 4d007a1888..5ba4168917 100644 --- a/src/pocketmine/IPlayer.php +++ b/src/pocketmine/player/IPlayer.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine; +namespace pocketmine\player; use pocketmine\permission\ServerOperator; diff --git a/src/pocketmine/OfflinePlayer.php b/src/pocketmine/player/OfflinePlayer.php similarity index 98% rename from src/pocketmine/OfflinePlayer.php rename to src/pocketmine/player/OfflinePlayer.php index 8de4013fec..81a77d2509 100644 --- a/src/pocketmine/OfflinePlayer.php +++ b/src/pocketmine/player/OfflinePlayer.php @@ -21,13 +21,14 @@ declare(strict_types=1); -namespace pocketmine; +namespace pocketmine\player; use pocketmine\metadata\Metadatable; use pocketmine\metadata\MetadataValue; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\LongTag; use pocketmine\plugin\Plugin; +use pocketmine\Server; class OfflinePlayer implements IPlayer, Metadatable{ diff --git a/src/pocketmine/Player.php b/src/pocketmine/player/Player.php similarity index 99% rename from src/pocketmine/Player.php rename to src/pocketmine/player/Player.php index 2522e5d16d..359966821c 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/player/Player.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine; +namespace pocketmine\player; use pocketmine\block\Bed; use pocketmine\block\BlockFactory; @@ -104,6 +104,7 @@ use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissibleDelegateTrait; use pocketmine\permission\PermissionManager; use pocketmine\plugin\Plugin; +use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\TextFormat; use pocketmine\utils\UUID; diff --git a/src/pocketmine/PlayerInfo.php b/src/pocketmine/player/PlayerInfo.php similarity index 98% rename from src/pocketmine/PlayerInfo.php rename to src/pocketmine/player/PlayerInfo.php index f0363bd2f8..423e784e19 100644 --- a/src/pocketmine/PlayerInfo.php +++ b/src/pocketmine/player/PlayerInfo.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine; +namespace pocketmine\player; use pocketmine\entity\Skin; use pocketmine\utils\TextFormat; diff --git a/src/pocketmine/scheduler/SendUsageTask.php b/src/pocketmine/scheduler/SendUsageTask.php index 3f66a0e073..1d00766c51 100644 --- a/src/pocketmine/scheduler/SendUsageTask.php +++ b/src/pocketmine/scheduler/SendUsageTask.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\scheduler; use pocketmine\network\mcpe\protocol\ProtocolInfo; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\Server; use pocketmine\utils\Internet; use pocketmine\utils\Process; diff --git a/src/pocketmine/timings/Timings.php b/src/pocketmine/timings/Timings.php index d5b28a0ffa..6fd1302793 100644 --- a/src/pocketmine/timings/Timings.php +++ b/src/pocketmine/timings/Timings.php @@ -27,7 +27,7 @@ use pocketmine\block\tile\Tile; use pocketmine\entity\Entity; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\ServerboundPacket; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\scheduler\TaskHandler; use function dechex; diff --git a/src/pocketmine/updater/AutoUpdater.php b/src/pocketmine/updater/AutoUpdater.php index 15ad63ae57..3b80d5cc50 100644 --- a/src/pocketmine/updater/AutoUpdater.php +++ b/src/pocketmine/updater/AutoUpdater.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\updater; use pocketmine\event\server\UpdateNotifyEvent; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\Server; use pocketmine\utils\TextFormat; use pocketmine\utils\VersionString; diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 4b9d57e7c2..908df2ef77 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -46,7 +46,6 @@ use pocketmine\event\world\ChunkPopulateEvent; use pocketmine\event\world\ChunkUnloadEvent; use pocketmine\event\world\SpawnChangeEvent; use pocketmine\event\world\WorldSaveEvent; -use pocketmine\GameMode; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\ItemUseResult; @@ -64,7 +63,7 @@ use pocketmine\network\mcpe\protocol\SetDifficultyPacket; use pocketmine\network\mcpe\protocol\SetTimePacket; use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\plugin\Plugin; use pocketmine\Server; use pocketmine\timings\Timings; diff --git a/src/pocketmine/world/format/Chunk.php b/src/pocketmine/world/format/Chunk.php index e6906a6c18..e6b2c2e6c6 100644 --- a/src/pocketmine/world/format/Chunk.php +++ b/src/pocketmine/world/format/Chunk.php @@ -33,7 +33,7 @@ use pocketmine\block\tile\TileFactory; use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\Player; +use pocketmine\player\Player; use pocketmine\world\World; use function array_fill; use function array_filter; From c5707f6174aeef3793039d4e0fac8ff4951c9e6e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 18 Jun 2019 18:58:53 +0100 Subject: [PATCH 0969/3224] update DevTools submodule --- tests/plugins/PocketMine-DevTools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/plugins/PocketMine-DevTools b/tests/plugins/PocketMine-DevTools index a88839dc99..37abf46440 160000 --- a/tests/plugins/PocketMine-DevTools +++ b/tests/plugins/PocketMine-DevTools @@ -1 +1 @@ -Subproject commit a88839dc99066d8812cdf5694dc8424d25006688 +Subproject commit 37abf464407ab08d9d458039290ba2a2d72b2c6f From ff8ca99c9fcb2ee3a518afb6b7dce84f22255acd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 18 Jun 2019 19:53:43 +0100 Subject: [PATCH 0970/3224] CrashDump: revert removal of RCON password redact in 738e310798f5a4742b2dc81a926bd0989e543ee5 there's guaranteed to be some plant pot who uses 4.0, leaks his RCON password, downgrades back to 3.x, and then gets hacked. --- src/pocketmine/CrashDump.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pocketmine/CrashDump.php b/src/pocketmine/CrashDump.php index efb929a03f..d666f78b0d 100644 --- a/src/pocketmine/CrashDump.php +++ b/src/pocketmine/CrashDump.php @@ -52,6 +52,7 @@ use function ob_start; use function php_uname; use function phpinfo; use function phpversion; +use function preg_replace; use function str_split; use function strpos; use function strtoupper; @@ -172,6 +173,7 @@ class CrashDump{ if($this->server->getProperty("auto-report.send-settings", true) !== false){ $this->data["parameters"] = (array) $argv; $this->data["server.properties"] = @file_get_contents($this->server->getDataPath() . "server.properties"); + $this->data["server.properties"] = preg_replace("#^rcon\\.password=(.*)$#m", "rcon.password=******", $this->data["server.properties"]); $this->data["pocketmine.yml"] = @file_get_contents($this->server->getDataPath() . "pocketmine.yml"); }else{ $this->data["pocketmine.yml"] = ""; From ce74549ba30f655a33894b8f1b5291bcb63b4c4e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 22 Jun 2019 15:53:56 +0100 Subject: [PATCH 0971/3224] Use 10 bits for Y coordinate in blockhash fixes #2553 --- build/preprocessor | 2 +- src/pocketmine/world/World.php | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/build/preprocessor b/build/preprocessor index 63e0092d62..4d4d2a74a6 160000 --- a/build/preprocessor +++ b/build/preprocessor @@ -1 +1 @@ -Subproject commit 63e0092d623d13e47f9083b3d65fdf431933a471 +Subproject commit 4d4d2a74a6ab9c77480b1eacbf69d0e92e65e1c2 diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 908df2ef77..6de6ffb3ef 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -123,6 +123,8 @@ class World implements ChunkManager, Metadatable{ public const Y_MASK = 0xFF; public const Y_MAX = 0x100; //256 + public const HALF_Y_MAX = self::Y_MAX / 2; + public const TIME_DAY = 0; public const TIME_SUNSET = 12000; public const TIME_NIGHT = 14000; @@ -272,10 +274,11 @@ class World implements ChunkManager, Metadatable{ } public static function blockHash(int $x, int $y, int $z) : int{ - if($y < 0 or $y >= World::Y_MAX){ + $shiftedY = $y - self::HALF_Y_MAX; + if($shiftedY < -512 or $shiftedY >= 512){ throw new \InvalidArgumentException("Y coordinate $y is out of range!"); } - return (($x & 0xFFFFFFF) << 36) | (($y & World::Y_MASK) << 28) | ($z & 0xFFFFFFF); + return (($x & 0x7ffffff) << 37) | (($shiftedY & 0x3ff) << 27) | ($z & 0x7ffffff); } /** @@ -292,9 +295,9 @@ class World implements ChunkManager, Metadatable{ } public static function getBlockXYZ(int $hash, ?int &$x, ?int &$y, ?int &$z) : void{ - $x = $hash >> 36; - $y = ($hash >> 28) & World::Y_MASK; //it's always positive - $z = ($hash & 0xFFFFFFF) << 36 >> 36; + $x = $hash >> 37; + $y = ($hash << 27 >> 54) + self::HALF_Y_MAX; + $z = $hash << 37 >> 37; } /** From 197a56e3e12f9fe16a8e9eb7c279703e9a8cd7ad Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 23 Jun 2019 19:22:58 +0100 Subject: [PATCH 0972/3224] move BookEditPacket handler out of Player --- .../mcpe/handler/InGamePacketHandler.php | 51 +++++++++++++++++- src/pocketmine/player/Player.php | 53 ------------------- 2 files changed, 50 insertions(+), 54 deletions(-) diff --git a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php index ffa4826807..2014968d49 100644 --- a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php @@ -26,10 +26,14 @@ namespace pocketmine\network\mcpe\handler; use pocketmine\block\ItemFrame; use pocketmine\block\Sign; use pocketmine\block\utils\SignText; +use pocketmine\event\player\PlayerEditBookEvent; use pocketmine\inventory\transaction\action\InventoryAction; use pocketmine\inventory\transaction\CraftingTransaction; use pocketmine\inventory\transaction\InventoryTransaction; use pocketmine\inventory\transaction\TransactionValidationException; +use pocketmine\item\Item; +use pocketmine\item\WritableBook; +use pocketmine\item\WrittenBook; use pocketmine\math\Vector3; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\StringTag; @@ -587,7 +591,52 @@ class InGamePacketHandler extends PacketHandler{ } public function handleBookEdit(BookEditPacket $packet) : bool{ - return $this->player->handleBookEdit($packet); + //TODO: break this up into book API things + $oldBook = $this->player->getInventory()->getItem($packet->inventorySlot); + if(!($oldBook instanceof WritableBook)){ + return false; + } + + $newBook = clone $oldBook; + $modifiedPages = []; + + switch($packet->type){ + case BookEditPacket::TYPE_REPLACE_PAGE: + $newBook->setPageText($packet->pageNumber, $packet->text); + $modifiedPages[] = $packet->pageNumber; + break; + case BookEditPacket::TYPE_ADD_PAGE: + $newBook->insertPage($packet->pageNumber, $packet->text); + $modifiedPages[] = $packet->pageNumber; + break; + case BookEditPacket::TYPE_DELETE_PAGE: + $newBook->deletePage($packet->pageNumber); + $modifiedPages[] = $packet->pageNumber; + break; + case BookEditPacket::TYPE_SWAP_PAGES: + $newBook->swapPages($packet->pageNumber, $packet->secondaryPageNumber); + $modifiedPages = [$packet->pageNumber, $packet->secondaryPageNumber]; + break; + case BookEditPacket::TYPE_SIGN_BOOK: + /** @var WrittenBook $newBook */ + $newBook = Item::get(Item::WRITTEN_BOOK, 0, 1, $newBook->getNamedTag()); + $newBook->setAuthor($packet->author); + $newBook->setTitle($packet->title); + $newBook->setGeneration(WrittenBook::GENERATION_ORIGINAL); + break; + default: + return false; + } + + $event = new PlayerEditBookEvent($this->player, $oldBook, $newBook, $packet->type, $modifiedPages); + $event->call(); + if($event->isCancelled()){ + return true; + } + + $this->player->getInventory()->setItem($packet->inventorySlot, $event->getNewBook()); + + return true; } public function handleModalFormResponse(ModalFormResponsePacket $packet) : bool{ diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 359966821c..ef588a0f23 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -50,7 +50,6 @@ use pocketmine\event\player\PlayerChangeSkinEvent; use pocketmine\event\player\PlayerChatEvent; use pocketmine\event\player\PlayerCommandPreprocessEvent; use pocketmine\event\player\PlayerDeathEvent; -use pocketmine\event\player\PlayerEditBookEvent; use pocketmine\event\player\PlayerExhaustEvent; use pocketmine\event\player\PlayerGameModeChangeEvent; use pocketmine\event\player\PlayerInteractEvent; @@ -78,8 +77,6 @@ use pocketmine\item\enchantment\EnchantmentInstance; use pocketmine\item\enchantment\MeleeWeaponEnchantment; use pocketmine\item\Item; use pocketmine\item\ItemUseResult; -use pocketmine\item\WritableBook; -use pocketmine\item\WrittenBook; use pocketmine\lang\TextContainer; use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; @@ -91,7 +88,6 @@ use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\AnimatePacket; -use pocketmine\network\mcpe\protocol\BookEditPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; @@ -2041,55 +2037,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->world->dropItem($this->add(0, 1.3, 0), $item, $this->getDirectionVector()->multiply(0.4), 40); } - public function handleBookEdit(BookEditPacket $packet) : bool{ - /** @var WritableBook $oldBook */ - $oldBook = $this->inventory->getItem($packet->inventorySlot); - if(!($oldBook instanceof WritableBook)){ - return false; - } - - $newBook = clone $oldBook; - $modifiedPages = []; - - switch($packet->type){ - case BookEditPacket::TYPE_REPLACE_PAGE: - $newBook->setPageText($packet->pageNumber, $packet->text); - $modifiedPages[] = $packet->pageNumber; - break; - case BookEditPacket::TYPE_ADD_PAGE: - $newBook->insertPage($packet->pageNumber, $packet->text); - $modifiedPages[] = $packet->pageNumber; - break; - case BookEditPacket::TYPE_DELETE_PAGE: - $newBook->deletePage($packet->pageNumber); - $modifiedPages[] = $packet->pageNumber; - break; - case BookEditPacket::TYPE_SWAP_PAGES: - $newBook->swapPages($packet->pageNumber, $packet->secondaryPageNumber); - $modifiedPages = [$packet->pageNumber, $packet->secondaryPageNumber]; - break; - case BookEditPacket::TYPE_SIGN_BOOK: - /** @var WrittenBook $newBook */ - $newBook = Item::get(Item::WRITTEN_BOOK, 0, 1, $newBook->getNamedTag()); - $newBook->setAuthor($packet->author); - $newBook->setTitle($packet->title); - $newBook->setGeneration(WrittenBook::GENERATION_ORIGINAL); - break; - default: - return false; - } - - $event = new PlayerEditBookEvent($this, $oldBook, $newBook, $packet->type, $modifiedPages); - $event->call(); - if($event->isCancelled()){ - return true; - } - - $this->getInventory()->setItem($packet->inventorySlot, $event->getNewBook()); - - return true; - } - /** * @param ClientboundPacket $packet * @param bool $immediate From 181cfef73161ef68db91d71cc18a484c6f2ad3cd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 23 Jun 2019 19:39:40 +0100 Subject: [PATCH 0973/3224] Remove a whole bunch of useless crap from PluginLogger this is pretty much just an implementation of a NTS attachable logger now. It should probably be converted into a trait. --- src/pocketmine/plugin/PluginBase.php | 4 +- src/pocketmine/plugin/PluginLogger.php | 52 +------------------------- 2 files changed, 5 insertions(+), 51 deletions(-) diff --git a/src/pocketmine/plugin/PluginBase.php b/src/pocketmine/plugin/PluginBase.php index 4068599efc..1f04c5b611 100644 --- a/src/pocketmine/plugin/PluginBase.php +++ b/src/pocketmine/plugin/PluginBase.php @@ -87,7 +87,9 @@ abstract class PluginBase implements Plugin, CommandExecutor{ //TODO: this is accessed externally via reflection, not unused $this->file = rtrim($file, "\\/") . "/"; $this->configFile = $this->dataFolder . "config.yml"; - $this->logger = new PluginLogger($this); + + $prefix = $this->getDescription()->getPrefix(); + $this->logger = new PluginLogger($server->getLogger(), $prefix !== "" ? $prefix : $this->getName()); $this->scheduler = new TaskScheduler($this->getFullName()); $this->resourceProvider = $resourceProvider; diff --git a/src/pocketmine/plugin/PluginLogger.php b/src/pocketmine/plugin/PluginLogger.php index 944533dcd7..ba310563bf 100644 --- a/src/pocketmine/plugin/PluginLogger.php +++ b/src/pocketmine/plugin/PluginLogger.php @@ -23,13 +23,9 @@ declare(strict_types=1); namespace pocketmine\plugin; -use LogLevel; -use pocketmine\Server; use function spl_object_id; -class PluginLogger implements \AttachableLogger{ - - private $pluginName; +class PluginLogger extends \PrefixedLogger implements \AttachableLogger{ /** @var \LoggerAttachment[] */ private $attachments = []; @@ -50,52 +46,8 @@ class PluginLogger implements \AttachableLogger{ return $this->attachments; } - /** - * @param Plugin $context - */ - public function __construct(Plugin $context){ - $prefix = $context->getDescription()->getPrefix(); - $this->pluginName = $prefix != null ? "[$prefix] " : "[" . $context->getDescription()->getName() . "] "; - } - - public function emergency($message){ - $this->log(LogLevel::EMERGENCY, $message); - } - - public function alert($message){ - $this->log(LogLevel::ALERT, $message); - } - - public function critical($message){ - $this->log(LogLevel::CRITICAL, $message); - } - - public function error($message){ - $this->log(LogLevel::ERROR, $message); - } - - public function warning($message){ - $this->log(LogLevel::WARNING, $message); - } - - public function notice($message){ - $this->log(LogLevel::NOTICE, $message); - } - - public function info($message){ - $this->log(LogLevel::INFO, $message); - } - - public function debug($message){ - $this->log(LogLevel::DEBUG, $message); - } - - public function logException(\Throwable $e, $trace = null){ - Server::getInstance()->getLogger()->logException($e, $trace); - } - public function log($level, $message){ - Server::getInstance()->getLogger()->log($level, $this->pluginName . $message); + parent::log($level, $message); foreach($this->attachments as $attachment){ $attachment->log($level, $message); } From 91580ce32164c6f588bc9d30868b87d08097c77f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 24 Jun 2019 17:27:12 +0100 Subject: [PATCH 0974/3224] fix bug in InventoryCloseEvent --- src/pocketmine/player/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index ef588a0f23..5f2b57d85f 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -2677,7 +2677,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, public function removeCurrentWindow() : void{ if($this->currentWindow !== null){ - (new InventoryCloseEvent($this->craftingGrid, $this))->call(); + (new InventoryCloseEvent($this->currentWindow, $this))->call(); $this->closeInventoryInternal($this->currentWindow, false); } } From 9f09dc3dd7491f711cbb6aacbafac16f4eb0c7e1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 24 Jun 2019 17:46:30 +0100 Subject: [PATCH 0975/3224] Player: Log a debug message when GC kicks in I use this frequently to identify leaks. This isn't expected to appear immediately after disconnect, but it shouldn't take long to appear. --- src/pocketmine/player/Player.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 5f2b57d85f..96b5e6ec70 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -2346,6 +2346,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return []; } + public function __destruct(){ + parent::__destruct(); + $this->logger->debug("Destroyed by garbage collector"); + } + public function canSaveWithChunk() : bool{ return false; } From d15284e638742c9747b45dd5c04ba36a5a80593b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 25 Jun 2019 13:28:01 +0100 Subject: [PATCH 0976/3224] work on moving inventory network functionality to network layer --- src/pocketmine/block/tile/Furnace.php | 6 +- src/pocketmine/inventory/AnvilInventory.php | 7 +- src/pocketmine/inventory/BaseInventory.php | 4 +- src/pocketmine/inventory/BlockInventory.php | 43 +++++ .../inventory/BrewingStandInventory.php | 7 +- src/pocketmine/inventory/ChestInventory.php | 7 +- .../inventory/ContainerInventory.php | 72 -------- src/pocketmine/inventory/EnchantInventory.php | 7 +- .../inventory/EnderChestInventory.php | 7 +- src/pocketmine/inventory/FurnaceInventory.php | 7 +- src/pocketmine/inventory/HopperInventory.php | 7 +- src/pocketmine/inventory/PlayerInventory.php | 4 +- .../transaction/InventoryTransaction.php | 2 +- .../transaction/action/SlotChangeAction.php | 2 +- .../network/mcpe/InventoryManager.php | 157 ++++++++++++++++++ .../network/mcpe/NetworkSession.php | 58 ++----- .../mcpe/handler/InGamePacketHandler.php | 24 ++- .../mcpe/handler/PreSpawnPacketHandler.php | 4 +- .../mcpe/protocol/ContainerOpenPacket.php | 5 + .../protocol/types/NetworkInventoryAction.php | 2 +- src/pocketmine/player/Player.php | 110 +++--------- 21 files changed, 277 insertions(+), 265 deletions(-) create mode 100644 src/pocketmine/inventory/BlockInventory.php delete mode 100644 src/pocketmine/inventory/ContainerInventory.php create mode 100644 src/pocketmine/network/mcpe/InventoryManager.php diff --git a/src/pocketmine/block/tile/Furnace.php b/src/pocketmine/block/tile/Furnace.php index dcc21281e7..a5c64d4e10 100644 --- a/src/pocketmine/block/tile/Furnace.php +++ b/src/pocketmine/block/tile/Furnace.php @@ -203,17 +203,17 @@ class Furnace extends Spawnable implements Container, Nameable{ if($prevCookTime !== $this->cookTime){ foreach($this->inventory->getViewers() as $v){ - $v->getNetworkSession()->syncInventoryData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_SMELT_PROGRESS, $this->cookTime); + $v->getNetworkSession()->getInvManager()->syncData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_SMELT_PROGRESS, $this->cookTime); } } if($prevRemainingFuelTime !== $this->remainingFuelTime){ foreach($this->inventory->getViewers() as $v){ - $v->getNetworkSession()->syncInventoryData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_REMAINING_FUEL_TIME, $this->remainingFuelTime); + $v->getNetworkSession()->getInvManager()->syncData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_REMAINING_FUEL_TIME, $this->remainingFuelTime); } } if($prevMaxFuelTime !== $this->maxFuelTime){ foreach($this->inventory->getViewers() as $v){ - $v->getNetworkSession()->syncInventoryData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_MAX_FUEL_TIME, $this->maxFuelTime); + $v->getNetworkSession()->getInvManager()->syncData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_MAX_FUEL_TIME, $this->maxFuelTime); } } diff --git a/src/pocketmine/inventory/AnvilInventory.php b/src/pocketmine/inventory/AnvilInventory.php index 95b932d9c4..c069816d0d 100644 --- a/src/pocketmine/inventory/AnvilInventory.php +++ b/src/pocketmine/inventory/AnvilInventory.php @@ -23,11 +23,10 @@ declare(strict_types=1); namespace pocketmine\inventory; -use pocketmine\network\mcpe\protocol\types\WindowTypes; use pocketmine\player\Player; use pocketmine\world\Position; -class AnvilInventory extends ContainerInventory{ +class AnvilInventory extends BlockInventory{ /** @var Position */ protected $holder; @@ -36,10 +35,6 @@ class AnvilInventory extends ContainerInventory{ parent::__construct($pos->asPosition(), 2); } - public function getNetworkType() : int{ - return WindowTypes::ANVIL; - } - /** * This override is here for documentation and code completion purposes only. * @return Position diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index dc29486627..d8d918ae48 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -116,7 +116,7 @@ abstract class BaseInventory implements Inventory{ if($send){ foreach($this->getViewers() as $viewer){ - $viewer->getNetworkSession()->syncInventoryContents($this); + $viewer->getNetworkSession()->getInvManager()->syncContents($this); } } } @@ -367,7 +367,7 @@ abstract class BaseInventory implements Inventory{ } if($send){ foreach($this->viewers as $viewer){ - $viewer->getNetworkSession()->syncInventorySlot($this, $index); + $viewer->getNetworkSession()->getInvManager()->syncSlot($this, $index); } } } diff --git a/src/pocketmine/inventory/BlockInventory.php b/src/pocketmine/inventory/BlockInventory.php new file mode 100644 index 0000000000..7c464ecdaa --- /dev/null +++ b/src/pocketmine/inventory/BlockInventory.php @@ -0,0 +1,43 @@ +holder = $holder; + parent::__construct($size, $items); + } + + /** + * @return Vector3 + */ + public function getHolder(){ + return $this->holder; + } +} diff --git a/src/pocketmine/inventory/BrewingStandInventory.php b/src/pocketmine/inventory/BrewingStandInventory.php index a699ed184d..e6a3e6b5b1 100644 --- a/src/pocketmine/inventory/BrewingStandInventory.php +++ b/src/pocketmine/inventory/BrewingStandInventory.php @@ -24,15 +24,10 @@ declare(strict_types=1); namespace pocketmine\inventory; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\types\WindowTypes; -class BrewingStandInventory extends ContainerInventory{ +class BrewingStandInventory extends BlockInventory{ public function __construct(Vector3 $holder, int $size = 5, array $items = []){ parent::__construct($holder, $size, $items); } - - public function getNetworkType() : int{ - return WindowTypes::BREWING_STAND; - } } diff --git a/src/pocketmine/inventory/ChestInventory.php b/src/pocketmine/inventory/ChestInventory.php index f19ec25178..db7a788cf8 100644 --- a/src/pocketmine/inventory/ChestInventory.php +++ b/src/pocketmine/inventory/ChestInventory.php @@ -25,14 +25,13 @@ namespace pocketmine\inventory; use pocketmine\block\tile\Chest; use pocketmine\network\mcpe\protocol\BlockEventPacket; -use pocketmine\network\mcpe\protocol\types\WindowTypes; use pocketmine\player\Player; use pocketmine\world\sound\ChestCloseSound; use pocketmine\world\sound\ChestOpenSound; use pocketmine\world\sound\Sound; use function count; -class ChestInventory extends ContainerInventory{ +class ChestInventory extends BlockInventory{ /** @var Chest */ protected $holder; @@ -44,10 +43,6 @@ class ChestInventory extends ContainerInventory{ parent::__construct($tile, 27); } - public function getNetworkType() : int{ - return WindowTypes::CONTAINER; - } - /** * This override is here for documentation and code completion purposes only. * @return Chest diff --git a/src/pocketmine/inventory/ContainerInventory.php b/src/pocketmine/inventory/ContainerInventory.php deleted file mode 100644 index 48a4a2be51..0000000000 --- a/src/pocketmine/inventory/ContainerInventory.php +++ /dev/null @@ -1,72 +0,0 @@ -holder = $holder; - parent::__construct($size, $items); - } - - public function onOpen(Player $who) : void{ - parent::onOpen($who); - - $windowId = $who->getWindowId($this); - $holder = $this->getHolder(); - if($holder instanceof Entity){ - $who->sendDataPacket(ContainerOpenPacket::entityInv($windowId, $this->getNetworkType(), $holder->getId())); - }elseif($holder instanceof Vector3){ - $who->sendDataPacket(ContainerOpenPacket::blockInv($windowId, $this->getNetworkType(), $holder->getFloorX(), $holder->getFloorY(), $holder->getFloorZ())); - } - - $who->getNetworkSession()->syncInventoryContents($this); - } - - public function onClose(Player $who) : void{ - $who->sendDataPacket(ContainerClosePacket::create($who->getWindowId($this))); - parent::onClose($who); - } - - /** - * Returns the Minecraft PE inventory type used to show the inventory window to clients. - * @return int - */ - abstract public function getNetworkType() : int; - - /** - * @return Vector3 - */ - public function getHolder(){ - return $this->holder; - } -} diff --git a/src/pocketmine/inventory/EnchantInventory.php b/src/pocketmine/inventory/EnchantInventory.php index d4510767b6..74d40d6877 100644 --- a/src/pocketmine/inventory/EnchantInventory.php +++ b/src/pocketmine/inventory/EnchantInventory.php @@ -23,11 +23,10 @@ declare(strict_types=1); namespace pocketmine\inventory; -use pocketmine\network\mcpe\protocol\types\WindowTypes; use pocketmine\player\Player; use pocketmine\world\Position; -class EnchantInventory extends ContainerInventory{ +class EnchantInventory extends BlockInventory{ /** @var Position */ protected $holder; @@ -36,10 +35,6 @@ class EnchantInventory extends ContainerInventory{ parent::__construct($pos->asPosition(), 2); } - public function getNetworkType() : int{ - return WindowTypes::ENCHANTMENT; - } - /** * This override is here for documentation and code completion purposes only. * @return Position diff --git a/src/pocketmine/inventory/EnderChestInventory.php b/src/pocketmine/inventory/EnderChestInventory.php index 0dcd970c03..1986ac7d09 100644 --- a/src/pocketmine/inventory/EnderChestInventory.php +++ b/src/pocketmine/inventory/EnderChestInventory.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\inventory; use pocketmine\block\tile\EnderChest; -use pocketmine\network\mcpe\protocol\types\WindowTypes; use pocketmine\world\Position; use pocketmine\world\sound\EnderChestCloseSound; use pocketmine\world\sound\EnderChestOpenSound; @@ -36,11 +35,7 @@ class EnderChestInventory extends ChestInventory{ protected $holder; public function __construct(){ - ContainerInventory::__construct(new Position(), 27); - } - - public function getNetworkType() : int{ - return WindowTypes::CONTAINER; + BlockInventory::__construct(new Position(), 27); } /** diff --git a/src/pocketmine/inventory/FurnaceInventory.php b/src/pocketmine/inventory/FurnaceInventory.php index 81820747bd..6a95c49aa7 100644 --- a/src/pocketmine/inventory/FurnaceInventory.php +++ b/src/pocketmine/inventory/FurnaceInventory.php @@ -25,9 +25,8 @@ namespace pocketmine\inventory; use pocketmine\block\tile\Furnace; use pocketmine\item\Item; -use pocketmine\network\mcpe\protocol\types\WindowTypes; -class FurnaceInventory extends ContainerInventory{ +class FurnaceInventory extends BlockInventory{ /** @var Furnace */ protected $holder; @@ -35,10 +34,6 @@ class FurnaceInventory extends ContainerInventory{ parent::__construct($tile, 3); } - public function getNetworkType() : int{ - return WindowTypes::FURNACE; - } - /** * This override is here for documentation and code completion purposes only. * @return Furnace diff --git a/src/pocketmine/inventory/HopperInventory.php b/src/pocketmine/inventory/HopperInventory.php index 728453c9c7..de9337645a 100644 --- a/src/pocketmine/inventory/HopperInventory.php +++ b/src/pocketmine/inventory/HopperInventory.php @@ -24,15 +24,10 @@ declare(strict_types=1); namespace pocketmine\inventory; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\types\WindowTypes; -class HopperInventory extends ContainerInventory{ +class HopperInventory extends BlockInventory{ public function __construct(Vector3 $holder, int $size = 5, array $items = []){ parent::__construct($holder, $size, $items); } - - public function getNetworkType() : int{ - return WindowTypes::HOPPER; - } } diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index 9c3f1f2c52..fbc2748d1e 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -137,12 +137,12 @@ class PlayerInventory extends BaseInventory{ if(!is_array($target)){ $target->sendDataPacket($pk); if($target === $this->getHolder()){ - $target->getNetworkSession()->syncInventorySlot($this, $this->getHeldItemIndex()); + $target->getNetworkSession()->getInvManager()->syncSlot($this, $this->getHeldItemIndex()); } }else{ $this->getHolder()->getWorld()->getServer()->broadcastPacket($target, $pk); if(in_array($this->getHolder(), $target, true)){ - $target->getNetworkSession()->syncInventorySlot($this, $this->getHeldItemIndex()); + $target->getNetworkSession()->getInvManager()->syncSlot($this, $this->getHeldItemIndex()); } } } diff --git a/src/pocketmine/inventory/transaction/InventoryTransaction.php b/src/pocketmine/inventory/transaction/InventoryTransaction.php index ea73c22fc2..9333ce4b9c 100644 --- a/src/pocketmine/inventory/transaction/InventoryTransaction.php +++ b/src/pocketmine/inventory/transaction/InventoryTransaction.php @@ -282,7 +282,7 @@ class InventoryTransaction{ protected function sendInventories() : void{ foreach($this->inventories as $inventory){ - $this->source->getNetworkSession()->syncInventoryContents($inventory); + $this->source->getNetworkSession()->getInvManager()->syncContents($inventory); } } diff --git a/src/pocketmine/inventory/transaction/action/SlotChangeAction.php b/src/pocketmine/inventory/transaction/action/SlotChangeAction.php index 1ec24af632..e1145022f8 100644 --- a/src/pocketmine/inventory/transaction/action/SlotChangeAction.php +++ b/src/pocketmine/inventory/transaction/action/SlotChangeAction.php @@ -100,7 +100,7 @@ class SlotChangeAction extends InventoryAction{ $this->inventory->setItem($this->inventorySlot, $this->targetItem, false); foreach($this->inventory->getViewers() as $viewer){ if($viewer !== $source){ - $viewer->getNetworkSession()->syncInventorySlot($this->inventory, $this->inventorySlot); + $viewer->getNetworkSession()->getInvManager()->syncSlot($this->inventory, $this->inventorySlot); } } } diff --git a/src/pocketmine/network/mcpe/InventoryManager.php b/src/pocketmine/network/mcpe/InventoryManager.php new file mode 100644 index 0000000000..097e55ee67 --- /dev/null +++ b/src/pocketmine/network/mcpe/InventoryManager.php @@ -0,0 +1,157 @@ +player = $player; + $this->session = $session; + + $this->windowMap[ContainerIds::INVENTORY] = $this->player->getInventory(); + $this->windowMap[ContainerIds::ARMOR] = $this->player->getArmorInventory(); + $this->windowMap[ContainerIds::CURSOR] = $this->player->getCursorInventory(); + } + + public function getWindowId(Inventory $inventory) : ?int{ + return ($id = array_search($inventory, $this->windowMap, true)) !== false ? $id : null; + } + + public function getCurrentWindowId() : int{ + return $this->lastInventoryNetworkId; + } + + public function getWindow(int $windowId) : ?Inventory{ + return $this->windowMap[$windowId] ?? null; + } + + public function onCurrentWindowChange(Inventory $inventory) : void{ + $this->onCurrentWindowRemove(); + $this->windowMap[$this->lastInventoryNetworkId = max(ContainerIds::FIRST, ($this->lastInventoryNetworkId + 1) % ContainerIds::LAST)] = $inventory; + + $pk = $this->createContainerOpen($this->lastInventoryNetworkId, $inventory); + if($pk !== null){ + $this->session->sendDataPacket($pk); + $this->syncContents($inventory); + }else{ + throw new \UnsupportedOperationException("Unsupported inventory type"); + } + } + + protected function createContainerOpen(int $id, Inventory $inv) : ?ContainerOpenPacket{ + //TODO: allow plugins to inject this + if($inv instanceof BlockInventory){ + switch(true){ + case $inv instanceof FurnaceInventory: + //TODO: specialized furnace types + return ContainerOpenPacket::blockInvVec3($id, WindowTypes::FURNACE, $inv->getHolder()); + case $inv instanceof EnchantInventory: + return ContainerOpenPacket::blockInvVec3($id, WindowTypes::ENCHANTMENT, $inv->getHolder()); + case $inv instanceof BrewingStandInventory: + return ContainerOpenPacket::blockInvVec3($id, WindowTypes::BREWING_STAND, $inv->getHolder()); + case $inv instanceof AnvilInventory: + return ContainerOpenPacket::blockInvVec3($id, WindowTypes::ANVIL, $inv->getHolder()); + case $inv instanceof HopperInventory: + return ContainerOpenPacket::blockInvVec3($id, WindowTypes::HOPPER, $inv->getHolder()); + default: + return ContainerOpenPacket::blockInvVec3($id, WindowTypes::CONTAINER, $inv->getHolder()); + } + } + return null; + } + + public function onCurrentWindowRemove() : void{ + if(isset($this->windowMap[$this->lastInventoryNetworkId])){ + unset($this->windowMap[$this->lastInventoryNetworkId]); + $this->session->sendDataPacket(ContainerClosePacket::create($this->lastInventoryNetworkId)); + } + } + + public function syncSlot(Inventory $inventory, int $slot) : void{ + $windowId = $this->getWindowId($inventory); + if($windowId !== null){ + $this->session->sendDataPacket(InventorySlotPacket::create($windowId, $slot, $inventory->getItem($slot))); + } + } + + public function syncContents(Inventory $inventory) : void{ + $windowId = $this->getWindowId($inventory); + if($windowId !== null){ + $this->session->sendDataPacket(InventoryContentPacket::create($windowId, $inventory->getContents(true))); + } + } + + public function syncAll() : void{ + foreach($this->player->getAllWindows() as $inventory){ + $this->syncContents($inventory); + } + } + + public function syncData(Inventory $inventory, int $propertyId, int $value) : void{ + $windowId = $this->getWindowId($inventory); + if($windowId !== null){ + $this->session->sendDataPacket(ContainerSetDataPacket::create($windowId, $propertyId, $value)); + } + } + + public function syncCreative() : void{ + $items = []; + if(!$this->player->isSpectator()){ //fill it for all gamemodes except spectator + foreach(CreativeInventory::getAll() as $i => $item){ + $items[$i] = clone $item; + } + } + + $this->session->sendDataPacket(InventoryContentPacket::create(ContainerIds::CREATIVE, $items)); + } +} diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 97f952ef9f..5e54db62a5 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -29,8 +29,6 @@ use pocketmine\event\player\PlayerCreationEvent; use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\event\server\DataPacketSendEvent; use pocketmine\form\Form; -use pocketmine\inventory\CreativeInventory; -use pocketmine\inventory\Inventory; use pocketmine\math\Vector3; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\DeathPacketHandler; @@ -45,11 +43,8 @@ use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; -use pocketmine\network\mcpe\protocol\ContainerSetDataPacket; use pocketmine\network\mcpe\protocol\DisconnectPacket; use pocketmine\network\mcpe\protocol\GarbageServerboundPacket; -use pocketmine\network\mcpe\protocol\InventoryContentPacket; -use pocketmine\network\mcpe\protocol\InventorySlotPacket; use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket; use pocketmine\network\mcpe\protocol\MobEffectPacket; use pocketmine\network\mcpe\protocol\ModalFormRequestPacket; @@ -67,7 +62,6 @@ use pocketmine\network\mcpe\protocol\TransferPacket; use pocketmine\network\mcpe\protocol\types\CommandData; use pocketmine\network\mcpe\protocol\types\CommandEnum; use pocketmine\network\mcpe\protocol\types\CommandParameter; -use pocketmine\network\mcpe\protocol\types\ContainerIds; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; @@ -139,6 +133,9 @@ class NetworkSession{ /** @var \SplQueue|CompressBatchPromise[] */ private $compressedQueue; + /** @var InventoryManager|null */ + private $invManager = null; + public function __construct(Server $server, NetworkSessionManager $manager, NetworkInterface $interface, string $ip, int $port){ $this->server = $server; $this->manager = $manager; @@ -176,6 +173,8 @@ class NetworkSession{ * @see Player::__construct() */ $this->player = new $class($this->server, $this, $this->info, $this->authenticated); + + $this->invManager = new InventoryManager($this->player, $this); } public function getPlayer() : ?Player{ @@ -443,6 +442,8 @@ class NetworkSession{ $this->connected = false; $this->manager->remove($this); $this->logger->info("Session closed due to $reason"); + + $this->invManager = null; //break cycles - TODO: this really ought to be deferred until it's safe } } @@ -594,7 +595,7 @@ class NetworkSession{ $this->player->sendData($this->player->getViewers()); $this->syncAdventureSettings($this->player); - $this->syncAllInventoryContents(); + $this->invManager->syncAll(); $this->setHandler(new InGamePacketHandler($this->player, $this)); } @@ -629,7 +630,7 @@ class NetworkSession{ $this->sendDataPacket(SetPlayerGameTypePacket::create(self::getClientFriendlyGamemode($mode))); $this->syncAdventureSettings($this->player); if(!$isRollback){ - $this->syncCreativeInventoryContents(); + $this->invManager->syncCreative(); } } @@ -765,42 +766,11 @@ class NetworkSession{ } - public function syncInventorySlot(Inventory $inventory, int $slot) : void{ - $windowId = $this->player->getWindowId($inventory); - if($windowId !== null){ - $this->sendDataPacket(InventorySlotPacket::create($windowId, $slot, $inventory->getItem($slot))); - } - } - - public function syncInventoryContents(Inventory $inventory) : void{ - $windowId = $this->player->getWindowId($inventory); - if($windowId !== null){ - $this->sendDataPacket(InventoryContentPacket::create($windowId, $inventory->getContents(true))); - } - } - - public function syncAllInventoryContents() : void{ - foreach($this->player->getAllWindows() as $inventory){ - $this->syncInventoryContents($inventory); - } - } - - public function syncInventoryData(Inventory $inventory, int $propertyId, int $value) : void{ - $windowId = $this->player->getWindowId($inventory); - if($windowId !== null){ - $this->sendDataPacket(ContainerSetDataPacket::create($windowId, $propertyId, $value)); - } - } - - public function syncCreativeInventoryContents() : void{ - $items = []; - if(!$this->player->isSpectator()){ //fill it for all gamemodes except spectator - foreach(CreativeInventory::getAll() as $i => $item){ - $items[$i] = clone $item; - } - } - - $this->sendDataPacket(InventoryContentPacket::create(ContainerIds::CREATIVE, $items)); + /** + * @return InventoryManager + */ + public function getInvManager() : InventoryManager{ + return $this->invManager; } public function onMobArmorChange(Living $mob) : void{ diff --git a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php index 2014968d49..7df975db13 100644 --- a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php @@ -162,7 +162,7 @@ class InGamePacketHandler extends PacketHandler{ public function handleInventoryTransaction(InventoryTransactionPacket $packet) : bool{ if($this->player->isSpectator()){ - $this->session->syncAllInventoryContents(); + $this->session->getInvManager()->syncAll(); return true; } @@ -172,7 +172,7 @@ class InGamePacketHandler extends PacketHandler{ $result = $this->handleNormalTransaction($packet->trData); }elseif($packet->trData instanceof MismatchTransactionData){ $this->session->getLogger()->debug("Mismatch transaction received"); - $this->session->syncAllInventoryContents(); + $this->session->getInvManager()->syncAll(); $result = true; }elseif($packet->trData instanceof UseItemTransactionData){ $result = $this->handleUseItemTransaction($packet->trData); @@ -183,7 +183,7 @@ class InGamePacketHandler extends PacketHandler{ } if(!$result){ - $this->session->syncAllInventoryContents(); + $this->session->getInvManager()->syncAll(); } return $result; } @@ -344,7 +344,7 @@ class InGamePacketHandler extends PacketHandler{ switch($data->getActionType()){ case ReleaseItemTransactionData::ACTION_RELEASE: if(!$this->player->releaseHeldItem()){ - $this->session->syncInventoryContents($this->player->getInventory()); + $this->session->getInvManager()->syncContents($this->player->getInventory()); } return true; case ReleaseItemTransactionData::ACTION_CONSUME: @@ -462,7 +462,21 @@ class InGamePacketHandler extends PacketHandler{ } public function handleContainerClose(ContainerClosePacket $packet) : bool{ - return $this->player->doCloseWindow($packet->windowId); + $this->player->doCloseInventory(); + + if($packet->windowId === 255){ + //Closed a fake window + return true; + } + + $window = $this->player->getCurrentWindow(); + if($window !== null and $packet->windowId === $this->session->getInvManager()->getCurrentWindowId()){ + $this->player->removeCurrentWindow(); + return true; + } + + $this->session->getLogger()->debug("Attempted to close inventory with network ID $packet->windowId, but current is " . $this->session->getInvManager()->getCurrentWindowId()); + return false; } public function handlePlayerHotbar(PlayerHotbarPacket $packet) : bool{ diff --git a/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php b/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php index 1cab9d63cf..5f7e3a8ae4 100644 --- a/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php @@ -91,8 +91,8 @@ class PreSpawnPacketHandler extends PacketHandler{ $this->player->sendPotionEffects($this->player); $this->player->sendData($this->player); - $this->session->syncAllInventoryContents(); - $this->session->syncCreativeInventoryContents(); + $this->session->getInvManager()->syncAll(); + $this->session->getInvManager()->syncCreative(); $this->player->getInventory()->sendHeldItem($this->player); $this->session->queueCompressed($this->server->getCraftingManager()->getCraftingDataPacket()); diff --git a/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php b/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php index 3addd12bbe..6b36f97820 100644 --- a/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php +++ b/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; class ContainerOpenPacket extends DataPacket implements ClientboundPacket{ @@ -52,6 +53,10 @@ class ContainerOpenPacket extends DataPacket implements ClientboundPacket{ return $result; } + public static function blockInvVec3(int $windowId, int $windowType, Vector3 $vector3) : self{ + return self::blockInv($windowId, $windowType, $vector3->getFloorX(), $vector3->getFloorY(), $vector3->getFloorZ()); + } + public static function entityInv(int $windowId, int $windowType, int $entityUniqueId) : self{ $result = new self; $result->windowId = $windowId; diff --git a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php index 7d689f73e0..2a5851a143 100644 --- a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php +++ b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php @@ -171,7 +171,7 @@ class NetworkInventoryAction{ public function createInventoryAction(Player $player) : ?InventoryAction{ switch($this->sourceType){ case self::SOURCE_CONTAINER: - $window = $player->getWindow($this->windowId); + $window = $player->getNetworkSession()->getInvManager()->getWindow($this->windowId); if($window !== null){ return new SlotChangeAction($window, $this->inventorySlot, $this->oldItem, $this->newItem); } diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 96b5e6ec70..0ba07f1e07 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -92,7 +92,6 @@ use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\SetTitlePacket; -use pocketmine\network\mcpe\protocol\types\ContainerIds; use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\PlayerMetadataFlags; @@ -111,7 +110,6 @@ use pocketmine\world\particle\PunchBlockParticle; use pocketmine\world\Position; use pocketmine\world\World; use function abs; -use function array_search; use function assert; use function ceil; use function count; @@ -119,7 +117,6 @@ use function explode; use function floor; use function get_class; use function is_int; -use function max; use function microtime; use function min; use function preg_match; @@ -182,10 +179,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** @var PlayerInfo */ protected $playerInfo; - /** @var int */ - protected $lastInventoryNetworkId = 2; - /** @var Inventory[] network ID => inventory */ - protected $networkIdToInventoryMap = []; /** @var Inventory|null */ protected $currentWindow = null; /** @var Inventory[] */ @@ -2316,10 +2309,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->loadQueue = []; $this->removeCurrentWindow(); - foreach($this->permanentWindows as $objectId => $inventory){ - $this->closeInventoryInternal($inventory, true); - } - assert(empty($this->networkIdToInventoryMap)); + $this->removePermanentInventories(); $this->perm->clearPermissions(); @@ -2570,15 +2560,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } protected function addDefaultWindows(){ - $this->openInventoryInternal($this->getInventory(), ContainerIds::INVENTORY, true); - - $this->openInventoryInternal($this->getArmorInventory(), ContainerIds::ARMOR, true); - $this->cursorInventory = new PlayerCursorInventory($this); - $this->openInventoryInternal($this->cursorInventory, ContainerIds::CURSOR, true); - $this->craftingGrid = new CraftingGrid($this, CraftingGrid::SIZE_SMALL); + $this->addPermanentInventories($this->inventory, $this->armorInventory, $this->cursorInventory); + //TODO: more windows } @@ -2621,29 +2607,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } - /** - * @internal Called by the network session when a player closes a window. - * - * @param int $windowId - * - * @return bool - */ - public function doCloseWindow(int $windowId) : bool{ - $this->doCloseInventory(); - - if($windowId === $this->lastInventoryNetworkId and $this->currentWindow !== null){ - $this->removeCurrentWindow(); - return true; - } - if($windowId === 255){ - //Closed a fake window - return true; - } - - $this->logger->debug("Attempted to close inventory with network ID $windowId, but current is $this->lastInventoryNetworkId"); - return false; - } - /** * Returns the inventory the player is currently viewing. This might be a chest, furnace, or any other container. * @@ -2673,9 +2636,9 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, //TODO: client side race condition here makes the opening work incorrectly $this->removeCurrentWindow(); - $networkId = $this->lastInventoryNetworkId = max(ContainerIds::FIRST, ($this->lastInventoryNetworkId + 1) % ContainerIds::LAST); - - $this->openInventoryInternal($inventory, $networkId, false); + $this->logger->debug("Opening inventory " . get_class($inventory) . "#" . spl_object_id($inventory)); + $this->networkSession->getInvManager()->onCurrentWindowChange($inventory); + $inventory->onOpen($this); $this->currentWindow = $inventory; return true; } @@ -2683,61 +2646,28 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, public function removeCurrentWindow() : void{ if($this->currentWindow !== null){ (new InventoryCloseEvent($this->currentWindow, $this))->call(); - $this->closeInventoryInternal($this->currentWindow, false); + + $this->logger->debug("Closing inventory " . get_class($this->currentWindow) . "#" . spl_object_id($this->currentWindow)); + $this->currentWindow->onClose($this); + if($this->isConnected()){ + $this->networkSession->getInvManager()->onCurrentWindowRemove(); + } + $this->currentWindow = null; } } - /** - * Returns the window ID which the inventory has for this player, or -1 if the window is not open to the player. - * - * @param Inventory $inventory - * - * @return int|null - */ - public function getWindowId(Inventory $inventory) : ?int{ - return ($id = array_search($inventory, $this->networkIdToInventoryMap, true)) !== false ? $id : null; - } - - /** - * Returns the inventory window open to the player with the specified window ID, or null if no window is open with - * that ID. - * - * @param int $windowId - * - * @return Inventory|null - */ - public function getWindow(int $windowId) : ?Inventory{ - return $this->networkIdToInventoryMap[$windowId] ?? null; - } - - protected function openInventoryInternal(Inventory $inventory, int $networkId, bool $permanent) : void{ - $this->logger->debug("Opening inventory " . get_class($inventory) . "#" . spl_object_id($inventory) . " with network ID $networkId"); - $this->networkIdToInventoryMap[$networkId] = $inventory; - $inventory->onOpen($this); - if($permanent){ + protected function addPermanentInventories(Inventory ...$inventories) : void{ + foreach($inventories as $inventory){ + $inventory->onOpen($this); $this->permanentWindows[spl_object_id($inventory)] = $inventory; } } - protected function closeInventoryInternal(Inventory $inventory, bool $force) : bool{ - $this->logger->debug("Closing inventory " . get_class($inventory) . "#" . spl_object_id($inventory)); - $objectId = spl_object_id($inventory); - if($inventory === $this->currentWindow){ - $this->currentWindow = null; - }elseif(isset($this->permanentWindows[$objectId])){ - if(!$force){ - throw new \InvalidArgumentException("Cannot remove fixed window " . get_class($inventory) . " from " . $this->getName()); - } - unset($this->permanentWindows[$objectId]); - }else{ - return false; + protected function removePermanentInventories() : void{ + foreach($this->permanentWindows as $inventory){ + $inventory->onClose($this); } - - $inventory->onClose($this); - $networkId = $this->getWindowId($inventory); - assert($networkId !== null); - unset($this->networkIdToInventoryMap[$networkId]); - return true; + $this->permanentWindows = []; } /** From de10e401bfb6e0866bdea1f860dbc3c02ee76cb6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 25 Jun 2019 13:41:03 +0100 Subject: [PATCH 0977/3224] Fixed wrong chunks being sent to players post-teleport or post-world-change --- src/pocketmine/network/mcpe/NetworkSession.php | 11 +++++++++-- src/pocketmine/player/Player.php | 4 ++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 5e54db62a5..6f91972d44 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -77,6 +77,7 @@ use pocketmine\utils\TextFormat; use pocketmine\utils\Utils; use pocketmine\world\Position; use function array_map; +use function assert; use function base64_encode; use function bin2hex; use function count; @@ -744,13 +745,19 @@ class NetworkSession{ public function startUsingChunk(int $chunkX, int $chunkZ, \Closure $onCompletion) : void{ Utils::validateCallableSignature(function(int $chunkX, int $chunkZ){}, $onCompletion); - ChunkCache::getInstance($this->player->getWorld())->request($chunkX, $chunkZ)->onResolve( + $world = $this->player->getWorld(); + assert($world !== null); + ChunkCache::getInstance($world)->request($chunkX, $chunkZ)->onResolve( //this callback may be called synchronously or asynchronously, depending on whether the promise is resolved yet - function(CompressBatchPromise $promise) use ($chunkX, $chunkZ, $onCompletion){ + function(CompressBatchPromise $promise) use ($world, $chunkX, $chunkZ, $onCompletion){ if(!$this->isConnected()){ return; } + if($world !== $this->player->getWorld() or !$this->player->isUsingChunk($chunkX, $chunkZ)){ + $this->logger->debug("Tried to send no-longer-active chunk $chunkX $chunkZ in world " . $world->getFolderName()); + return; + } $this->player->world->timings->syncChunkSendTimer->startTiming(); try{ $this->queueCompressed($promise); diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 0ba07f1e07..9429e51c50 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -1039,6 +1039,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, Timings::$playerChunkOrderTimer->stopTiming(); } + public function isUsingChunk(int $chunkX, int $chunkZ) : bool{ + return isset($this->usedChunks[World::chunkHash($chunkX, $chunkZ)]); + } + public function doChunkRequests(){ if($this->nextChunkOrderRun !== PHP_INT_MAX and $this->nextChunkOrderRun-- <= 0){ $this->nextChunkOrderRun = PHP_INT_MAX; From 75a4136ab2581c13c9cf2e538d758c978ff9e3b8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 25 Jun 2019 14:17:56 +0100 Subject: [PATCH 0978/3224] Player: fix bug in unloadChunk() causing entity artifacts on world change --- src/pocketmine/player/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 9429e51c50..066718122d 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -866,7 +866,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $world = $world ?? $this->world; $index = World::chunkHash($x, $z); if(isset($this->usedChunks[$index])){ - foreach($this->getWorld()->getChunkEntities($x, $z) as $entity){ + foreach($world->getChunkEntities($x, $z) as $entity){ if($entity !== $this){ $entity->despawnFrom($this); } From 94ee33e47bf3308afdd70cdd8ad3c6f51c28f870 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 25 Jun 2019 14:57:40 +0100 Subject: [PATCH 0979/3224] Moved common Thread parts to trait --- .../thread/CommonThreadPartsTrait.php | 82 +++++++++++++++++++ src/pocketmine/thread/Thread.php | 58 +------------ src/pocketmine/thread/Worker.php | 56 +------------ 3 files changed, 86 insertions(+), 110 deletions(-) create mode 100644 src/pocketmine/thread/CommonThreadPartsTrait.php diff --git a/src/pocketmine/thread/CommonThreadPartsTrait.php b/src/pocketmine/thread/CommonThreadPartsTrait.php new file mode 100644 index 0000000000..14fe40d0f1 --- /dev/null +++ b/src/pocketmine/thread/CommonThreadPartsTrait.php @@ -0,0 +1,82 @@ +classLoader; + } + + public function setClassLoader(?\ClassLoader $loader = null) : void{ + $this->composerAutoloaderPath = \pocketmine\COMPOSER_AUTOLOADER_PATH; + + if($loader === null){ + $loader = Server::getInstance()->getLoader(); + } + $this->classLoader = $loader; + } + + /** + * Registers the class loader for this thread. + * + * WARNING: This method MUST be called from any descendent threads' run() method to make autoloading usable. + * If you do not do this, you will not be able to use new classes that were not loaded when the thread was started + * (unless you are using a custom autoloader). + */ + public function registerClassLoader() : void{ + if($this->composerAutoloaderPath !== null){ + require $this->composerAutoloaderPath; + } + if($this->classLoader !== null){ + $this->classLoader->register(false); + } + } + + final public function run() : void{ + error_reporting(-1); + $this->registerClassLoader(); + //set this after the autoloader is registered + \ErrorUtils::setErrorExceptionHandler(); + $this->onRun(); + } + + /** + * Runs code on the thread. + */ + abstract protected function onRun() : void; + + public function getThreadName() : string{ + return (new \ReflectionClass($this))->getShortName(); + } +} diff --git a/src/pocketmine/thread/Thread.php b/src/pocketmine/thread/Thread.php index c69b01f118..aec708e23d 100644 --- a/src/pocketmine/thread/Thread.php +++ b/src/pocketmine/thread/Thread.php @@ -23,51 +23,14 @@ declare(strict_types=1); namespace pocketmine\thread; -use pocketmine\Server; -use function error_reporting; - /** * This class must be extended by all custom threading classes */ abstract class Thread extends \Thread{ - - /** @var \ClassLoader|null */ - protected $classLoader; - /** @var string|null */ - protected $composerAutoloaderPath; - - protected $isKilled = false; - - public function getClassLoader(){ - return $this->classLoader; - } - - public function setClassLoader(?\ClassLoader $loader = null) : void{ - $this->composerAutoloaderPath = \pocketmine\COMPOSER_AUTOLOADER_PATH; - - if($loader === null){ - $loader = Server::getInstance()->getLoader(); - } - $this->classLoader = $loader; - } - - /** - * Registers the class loader for this thread. - * - * WARNING: This method MUST be called from any descendent threads' run() method to make autoloading usable. - * If you do not do this, you will not be able to use new classes that were not loaded when the thread was started - * (unless you are using a custom autoloader). - */ - public function registerClassLoader() : void{ - if($this->composerAutoloaderPath !== null){ - require $this->composerAutoloaderPath; - } - if($this->classLoader !== null){ - $this->classLoader->register(false); - } - } + use CommonThreadPartsTrait; public function start(?int $options = \PTHREADS_INHERIT_ALL) : bool{ + //this is intentionally not traitified ThreadManager::getInstance()->add($this); if($this->getClassLoader() === null){ @@ -76,19 +39,6 @@ abstract class Thread extends \Thread{ return parent::start($options); } - final public function run() : void{ - error_reporting(-1); - $this->registerClassLoader(); - //set this after the autoloader is registered - \ErrorUtils::setErrorExceptionHandler(); - $this->onRun(); - } - - /** - * Runs code on the thread. - */ - abstract protected function onRun() : void; - /** * Stops the thread using the best way possible. Try to stop it yourself before calling this. */ @@ -102,8 +52,4 @@ abstract class Thread extends \Thread{ ThreadManager::getInstance()->remove($this); } - - public function getThreadName() : string{ - return (new \ReflectionClass($this))->getShortName(); - } } diff --git a/src/pocketmine/thread/Worker.php b/src/pocketmine/thread/Worker.php index fc48fb2128..75b106a82b 100644 --- a/src/pocketmine/thread/Worker.php +++ b/src/pocketmine/thread/Worker.php @@ -23,51 +23,14 @@ declare(strict_types=1); namespace pocketmine\thread; -use pocketmine\Server; -use function error_reporting; - /** * This class must be extended by all custom threading classes */ abstract class Worker extends \Worker{ - - /** @var \ClassLoader|null */ - protected $classLoader; - /** @var string|null */ - protected $composerAutoloaderPath; - - protected $isKilled = false; - - public function getClassLoader(){ - return $this->classLoader; - } - - public function setClassLoader(?\ClassLoader $loader = null) : void{ - $this->composerAutoloaderPath = \pocketmine\COMPOSER_AUTOLOADER_PATH; - - if($loader === null){ - $loader = Server::getInstance()->getLoader(); - } - $this->classLoader = $loader; - } - - /** - * Registers the class loader for this thread. - * - * WARNING: This method MUST be called from any descendent threads' run() method to make autoloading usable. - * If you do not do this, you will not be able to use new classes that were not loaded when the thread was started - * (unless you are using a custom autoloader). - */ - public function registerClassLoader() : void{ - if($this->composerAutoloaderPath !== null){ - require $this->composerAutoloaderPath; - } - if($this->classLoader !== null){ - $this->classLoader->register(false); - } - } + use CommonThreadPartsTrait; public function start(?int $options = \PTHREADS_INHERIT_ALL) : bool{ + //this is intentionally not traitified ThreadManager::getInstance()->add($this); if($this->getClassLoader() === null){ @@ -76,17 +39,6 @@ abstract class Worker extends \Worker{ return parent::start($options); } - final public function run() : void{ - error_reporting(-1); - $this->registerClassLoader(); - $this->onRun(); - } - - /** - * Runs code on the thread. - */ - abstract protected function onRun() : void; - /** * Stops the thread using the best way possible. Try to stop it yourself before calling this. */ @@ -101,8 +53,4 @@ abstract class Worker extends \Worker{ ThreadManager::getInstance()->remove($this); } - - public function getThreadName() : string{ - return (new \ReflectionClass($this))->getShortName(); - } } From 8ec25b59a361dca282375ab4413f9e67fe940062 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 25 Jun 2019 15:43:55 +0100 Subject: [PATCH 0980/3224] Remove useless $items parameter from inventory constructors --- src/pocketmine/inventory/BaseInventory.php | 7 ++----- src/pocketmine/inventory/BlockInventory.php | 4 ++-- src/pocketmine/inventory/BrewingStandInventory.php | 4 ++-- src/pocketmine/inventory/DoubleChestInventory.php | 4 +--- src/pocketmine/inventory/HopperInventory.php | 4 ++-- 5 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/pocketmine/inventory/BaseInventory.php index d8d918ae48..1b9e5d2986 100644 --- a/src/pocketmine/inventory/BaseInventory.php +++ b/src/pocketmine/inventory/BaseInventory.php @@ -44,13 +44,10 @@ abstract class BaseInventory implements Inventory{ protected $listeners = []; /** - * @param int $size - * @param Item[] $items + * @param int $size */ - public function __construct(int $size, array $items = []){ + public function __construct(int $size){ $this->slots = new \SplFixedArray($size); - - $this->setContents($items, false); } /** diff --git a/src/pocketmine/inventory/BlockInventory.php b/src/pocketmine/inventory/BlockInventory.php index 7c464ecdaa..7f420aca53 100644 --- a/src/pocketmine/inventory/BlockInventory.php +++ b/src/pocketmine/inventory/BlockInventory.php @@ -29,9 +29,9 @@ abstract class BlockInventory extends BaseInventory{ /** @var Vector3 */ protected $holder; - public function __construct(Vector3 $holder, int $size, array $items = []){ + public function __construct(Vector3 $holder, int $size){ $this->holder = $holder; - parent::__construct($size, $items); + parent::__construct($size); } /** diff --git a/src/pocketmine/inventory/BrewingStandInventory.php b/src/pocketmine/inventory/BrewingStandInventory.php index e6a3e6b5b1..238cf99d7f 100644 --- a/src/pocketmine/inventory/BrewingStandInventory.php +++ b/src/pocketmine/inventory/BrewingStandInventory.php @@ -27,7 +27,7 @@ use pocketmine\math\Vector3; class BrewingStandInventory extends BlockInventory{ - public function __construct(Vector3 $holder, int $size = 5, array $items = []){ - parent::__construct($holder, $size, $items); + public function __construct(Vector3 $holder, int $size = 5){ + parent::__construct($holder, $size); } } diff --git a/src/pocketmine/inventory/DoubleChestInventory.php b/src/pocketmine/inventory/DoubleChestInventory.php index a4861a2905..f600cf0b42 100644 --- a/src/pocketmine/inventory/DoubleChestInventory.php +++ b/src/pocketmine/inventory/DoubleChestInventory.php @@ -26,7 +26,6 @@ namespace pocketmine\inventory; use pocketmine\block\tile\Chest; use pocketmine\item\Item; use pocketmine\player\Player; -use function array_merge; use function count; class DoubleChestInventory extends ChestInventory implements InventoryHolder{ @@ -38,8 +37,7 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ public function __construct(Chest $left, Chest $right){ $this->left = $left->getRealInventory(); $this->right = $right->getRealInventory(); - $items = array_merge($this->left->getContents(true), $this->right->getContents(true)); - BaseInventory::__construct($this->left->getSize() + $this->right->getSize(), $items); + BaseInventory::__construct($this->left->getSize() + $this->right->getSize()); } public function getInventory(){ diff --git a/src/pocketmine/inventory/HopperInventory.php b/src/pocketmine/inventory/HopperInventory.php index de9337645a..af77a7a451 100644 --- a/src/pocketmine/inventory/HopperInventory.php +++ b/src/pocketmine/inventory/HopperInventory.php @@ -27,7 +27,7 @@ use pocketmine\math\Vector3; class HopperInventory extends BlockInventory{ - public function __construct(Vector3 $holder, int $size = 5, array $items = []){ - parent::__construct($holder, $size, $items); + public function __construct(Vector3 $holder, int $size = 5){ + parent::__construct($holder, $size); } } From d85a27c5b22e2c4a61a2fa24cfa3d980529c5b90 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 25 Jun 2019 15:54:26 +0100 Subject: [PATCH 0981/3224] BanList: remove useless Server dependency --- src/pocketmine/permission/BanList.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/pocketmine/permission/BanList.php b/src/pocketmine/permission/BanList.php index cc0b038c51..40837ef05f 100644 --- a/src/pocketmine/permission/BanList.php +++ b/src/pocketmine/permission/BanList.php @@ -23,15 +23,12 @@ declare(strict_types=1); namespace pocketmine\permission; -use pocketmine\Server; use function fclose; use function fgets; use function fopen; use function fwrite; use function is_resource; -use function strftime; use function strtolower; -use function time; use function trim; class BanList{ @@ -181,7 +178,6 @@ class BanList{ $fp = @fopen($this->file, "w"); if(is_resource($fp)){ if($writeHeader){ - fwrite($fp, "# Updated " . strftime("%x %H:%M", time()) . " by " . Server::getInstance()->getName() . " " . Server::getInstance()->getPocketMineVersion() . "\n"); fwrite($fp, "# victim name | ban date | banned by | banned until | reason\n\n"); } From edccce1419ef9185648090dd0d90297368628ee2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 25 Jun 2019 16:23:43 +0100 Subject: [PATCH 0982/3224] added ChunkListenerNoOpTrait to reduce chunklistener boilerplate --- src/pocketmine/network/mcpe/ChunkCache.php | 24 +++------ src/pocketmine/player/Player.php | 21 ++------ .../world/ChunkListenerNoOpTrait.php | 54 +++++++++++++++++++ 3 files changed, 67 insertions(+), 32 deletions(-) create mode 100644 src/pocketmine/world/ChunkListenerNoOpTrait.php diff --git a/src/pocketmine/network/mcpe/ChunkCache.php b/src/pocketmine/network/mcpe/ChunkCache.php index 8249175e0b..c648cd7bac 100644 --- a/src/pocketmine/network/mcpe/ChunkCache.php +++ b/src/pocketmine/network/mcpe/ChunkCache.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe; use pocketmine\math\Vector3; use pocketmine\world\ChunkListener; +use pocketmine\world\ChunkListenerNoOpTrait; use pocketmine\world\format\Chunk; use pocketmine\world\World; use function spl_object_id; @@ -159,6 +160,13 @@ class ChunkCache implements ChunkListener{ } } + use ChunkListenerNoOpTrait { + //force overriding of these + onChunkChanged as private; + onBlockChanged as private; + onChunkUnloaded as private; + } + /** * @see ChunkListener::onChunkChanged() * @param Chunk $chunk @@ -187,22 +195,6 @@ class ChunkCache implements ChunkListener{ $this->world->unregisterChunkListener($this, $chunk->getX(), $chunk->getZ()); } - /** - * @see ChunkListener::onChunkLoaded() - * @param Chunk $chunk - */ - public function onChunkLoaded(Chunk $chunk) : void{ - //NOOP - } - - /** - * @see ChunkListener::onChunkPopulated() - * @param Chunk $chunk - */ - public function onChunkPopulated(Chunk $chunk) : void{ - //NOOP - we also receive this in onChunkChanged, so we don't care here - } - /** * Returns the number of bytes occupied by the cache data in this cache. This does not include the size of any * promises referenced by the cache. diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 066718122d..8a8ff3ff90 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -104,6 +104,7 @@ use pocketmine\timings\Timings; use pocketmine\utils\TextFormat; use pocketmine\utils\UUID; use pocketmine\world\ChunkListener; +use pocketmine\world\ChunkListenerNoOpTrait; use pocketmine\world\ChunkLoader; use pocketmine\world\format\Chunk; use pocketmine\world\particle\PunchBlockParticle; @@ -2701,26 +2702,14 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->server->getPlayerMetadata()->removeMetadata($this, $metadataKey, $owningPlugin); } + use ChunkListenerNoOpTrait { + onChunkChanged as private; + } + public function onChunkChanged(Chunk $chunk) : void{ if(isset($this->usedChunks[$hash = World::chunkHash($chunk->getX(), $chunk->getZ())])){ $this->usedChunks[$hash] = false; $this->nextChunkOrderRun = 0; } } - - public function onChunkLoaded(Chunk $chunk) : void{ - - } - - public function onChunkPopulated(Chunk $chunk) : void{ - - } - - public function onChunkUnloaded(Chunk $chunk) : void{ - - } - - public function onBlockChanged(Vector3 $block) : void{ - - } } diff --git a/src/pocketmine/world/ChunkListenerNoOpTrait.php b/src/pocketmine/world/ChunkListenerNoOpTrait.php new file mode 100644 index 0000000000..1d7134bcbe --- /dev/null +++ b/src/pocketmine/world/ChunkListenerNoOpTrait.php @@ -0,0 +1,54 @@ + Date: Tue, 25 Jun 2019 16:30:07 +0100 Subject: [PATCH 0983/3224] PlayerBlockPickEvent: pre-cancel the event when picking would fail in survival --- src/pocketmine/player/Player.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 8a8ff3ff90..8cf322183a 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -1769,17 +1769,20 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $item = $block->getPickedItem($addTileNBT); $ev = new PlayerBlockPickEvent($this, $block, $item); + $existingSlot = $this->inventory->first($item); + if($existingSlot === -1 and $this->hasFiniteResources()){ + $ev->setCancelled(); + } $ev->call(); if(!$ev->isCancelled()){ - $existing = $this->inventory->first($item); - if($existing !== -1){ - if($existing < $this->inventory->getHotbarSize()){ - $this->inventory->setHeldItemIndex($existing); + if($existingSlot !== -1){ + if($existingSlot < $this->inventory->getHotbarSize()){ + $this->inventory->setHeldItemIndex($existingSlot); }else{ - $this->inventory->swap($this->inventory->getHeldItemIndex(), $existing); + $this->inventory->swap($this->inventory->getHeldItemIndex(), $existingSlot); } - }elseif(!$this->hasFiniteResources()){ //TODO: plugins won't know this isn't going to execute + }else{ $firstEmpty = $this->inventory->firstEmpty(); if($firstEmpty === -1){ //full inventory $this->inventory->setItemInHand($item); From f152ae9cbfeea196ededfa04433047f841e0fec5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 25 Jun 2019 17:23:41 +0100 Subject: [PATCH 0984/3224] EntityFactory: Allow registering entities without legacy numeric IDs associated this shit really ought to be broken up into factories for each world format. --- src/pocketmine/entity/EntityFactory.php | 43 ++++++++++++------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/src/pocketmine/entity/EntityFactory.php b/src/pocketmine/entity/EntityFactory.php index d14632908a..fcac6d759e 100644 --- a/src/pocketmine/entity/EntityFactory.php +++ b/src/pocketmine/entity/EntityFactory.php @@ -80,22 +80,22 @@ final class EntityFactory{ //define legacy save IDs first - use them for saving for maximum compatibility with Minecraft PC //TODO: index them by version to allow proper multi-save compatibility - self::register(Arrow::class, false, ['Arrow', 'minecraft:arrow']); - self::register(Egg::class, false, ['Egg', 'minecraft:egg']); - self::register(EnderPearl::class, false, ['ThrownEnderpearl', 'minecraft:ender_pearl']); - self::register(ExperienceBottle::class, false, ['ThrownExpBottle', 'minecraft:xp_bottle']); - self::register(ExperienceOrb::class, false, ['XPOrb', 'minecraft:xp_orb']); - self::register(FallingBlock::class, false, ['FallingSand', 'minecraft:falling_block']); - self::register(ItemEntity::class, false, ['Item', 'minecraft:item']); - self::register(Painting::class, false, ['Painting', 'minecraft:painting']); - self::register(PrimedTNT::class, false, ['PrimedTnt', 'PrimedTNT', 'minecraft:tnt']); - self::register(Snowball::class, false, ['Snowball', 'minecraft:snowball']); - self::register(SplashPotion::class, false, ['ThrownPotion', 'minecraft:potion', 'thrownpotion']); - self::register(Squid::class, false, ['Squid', 'minecraft:squid']); - self::register(Villager::class, false, ['Villager', 'minecraft:villager']); - self::register(Zombie::class, false, ['Zombie', 'minecraft:zombie']); + self::register(Arrow::class, ['Arrow', 'minecraft:arrow'], EntityIds::ARROW); + self::register(Egg::class, ['Egg', 'minecraft:egg'], EntityIds::EGG); + self::register(EnderPearl::class, ['ThrownEnderpearl', 'minecraft:ender_pearl'], EntityIds::ENDER_PEARL); + self::register(ExperienceBottle::class, ['ThrownExpBottle', 'minecraft:xp_bottle'], EntityIds::XP_BOTTLE); + self::register(ExperienceOrb::class, ['XPOrb', 'minecraft:xp_orb'], EntityIds::XP_ORB); + self::register(FallingBlock::class, ['FallingSand', 'minecraft:falling_block'], EntityIds::FALLING_BLOCK); + self::register(ItemEntity::class, ['Item', 'minecraft:item'], EntityIds::ITEM); + self::register(Painting::class, ['Painting', 'minecraft:painting'], EntityIds::PAINTING); + self::register(PrimedTNT::class, ['PrimedTnt', 'PrimedTNT', 'minecraft:tnt'], EntityIds::TNT); + self::register(Snowball::class, ['Snowball', 'minecraft:snowball'], EntityIds::SNOWBALL); + self::register(SplashPotion::class, ['ThrownPotion', 'minecraft:potion', 'thrownpotion'], EntityIds::SPLASH_POTION); + self::register(Squid::class, ['Squid', 'minecraft:squid'], EntityIds::SQUID); + self::register(Villager::class, ['Villager', 'minecraft:villager'], EntityIds::VILLAGER); + self::register(Zombie::class, ['Zombie', 'minecraft:zombie'], EntityIds::ZOMBIE); - self::register(Human::class, true); + self::register(Human::class, ['Human']); Attribute::init(); Effect::init(); @@ -106,23 +106,17 @@ final class EntityFactory{ * Registers an entity type into the index. * * @param string $className Class that extends Entity - * @param bool $force Force registration even if the entity does not have a valid network ID * @param string[] $saveNames An array of save names which this entity might be saved under. Defaults to the short name of the class itself if empty. + * @param int|null $legacyMcpeSaveId * * NOTE: The first save name in the $saveNames array will be used when saving the entity to disk. The reflection * name of the class will be appended to the end and only used if no other save names are specified. * * @throws \InvalidArgumentException */ - public static function register(string $className, bool $force = false, array $saveNames = []) : void{ + public static function register(string $className, array $saveNames, ?int $legacyMcpeSaveId = null) : void{ Utils::testValidInstance($className, Entity::class); - /** @var Entity $className */ - if($className::NETWORK_ID !== -1){ - self::$knownEntities[$className::NETWORK_ID] = $className; - }elseif(!$force){ - throw new \InvalidArgumentException("Class $className does not declare a valid NETWORK_ID and not force-registering"); - } self::$classMapping[$className] = $className; $shortName = (new \ReflectionClass($className))->getShortName(); @@ -133,6 +127,9 @@ final class EntityFactory{ foreach($saveNames as $name){ self::$knownEntities[$name] = $className; } + if($legacyMcpeSaveId !== null){ + self::$knownEntities[$legacyMcpeSaveId] = $className; + } self::$saveNames[$className] = $saveNames; } From 8c2ca098e138b0ea0c68900bde34be81e2a320d2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 25 Jun 2019 17:31:10 +0100 Subject: [PATCH 0985/3224] updated BedrockData submodule --- resources/vanilla | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/vanilla b/resources/vanilla index 7d9cec8861..6e2aaa6a16 160000 --- a/resources/vanilla +++ b/resources/vanilla @@ -1 +1 @@ -Subproject commit 7d9cec8861a9de033da78bb133f8159f2dfd41c5 +Subproject commit 6e2aaa6a169e3398c338d5bcc197137c2e159d88 From ff55f5e9aca8ca279061fa8ac644930151b4a213 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 25 Jun 2019 17:45:07 +0100 Subject: [PATCH 0986/3224] Make BlockInventory non-abstract --- src/pocketmine/inventory/BlockInventory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/inventory/BlockInventory.php b/src/pocketmine/inventory/BlockInventory.php index 7f420aca53..46d0193e01 100644 --- a/src/pocketmine/inventory/BlockInventory.php +++ b/src/pocketmine/inventory/BlockInventory.php @@ -25,7 +25,7 @@ namespace pocketmine\inventory; use pocketmine\math\Vector3; -abstract class BlockInventory extends BaseInventory{ +class BlockInventory extends BaseInventory{ /** @var Vector3 */ protected $holder; From 6bbae4b2df5a526ad216f479dd9ac2aa83a114bc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 25 Jun 2019 18:34:12 +0100 Subject: [PATCH 0987/3224] SetDifficultyPacket: added create() --- .../network/mcpe/protocol/SetDifficultyPacket.php | 6 ++++++ src/pocketmine/world/World.php | 3 +-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/SetDifficultyPacket.php b/src/pocketmine/network/mcpe/protocol/SetDifficultyPacket.php index cec01b77d8..9aa2df4f4e 100644 --- a/src/pocketmine/network/mcpe/protocol/SetDifficultyPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetDifficultyPacket.php @@ -34,6 +34,12 @@ class SetDifficultyPacket extends DataPacket implements ClientboundPacket, Serve /** @var int */ public $difficulty; + public static function create(int $difficulty) : self{ + $result = new self; + $result->difficulty = $difficulty; + return $result; + } + protected function decodePayload() : void{ $this->difficulty = $this->getUnsignedVarInt(); } diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 1f83e08ba5..215882257c 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -2772,8 +2772,7 @@ class World implements ChunkManager, Metadatable{ * @param Player ...$targets */ public function sendDifficulty(Player ...$targets){ - $pk = new SetDifficultyPacket(); - $pk->difficulty = $this->getDifficulty(); + $pk = SetDifficultyPacket::create($this->getDifficulty()); if(empty($targets)){ $this->broadcastGlobalPacket($pk); }else{ From 73938486fc1dd95a708620d7ef3f111b383b9c9e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 25 Jun 2019 18:39:02 +0100 Subject: [PATCH 0988/3224] added PaintingPlaceSound --- src/pocketmine/item/PaintingItem.php | 4 +-- .../world/sound/PaintingPlaceSound.php | 33 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 src/pocketmine/world/sound/PaintingPlaceSound.php diff --git a/src/pocketmine/item/PaintingItem.php b/src/pocketmine/item/PaintingItem.php index 9396033373..d8e139de9a 100644 --- a/src/pocketmine/item/PaintingItem.php +++ b/src/pocketmine/item/PaintingItem.php @@ -29,8 +29,8 @@ use pocketmine\entity\object\Painting; use pocketmine\entity\object\PaintingMotive; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\player\Player; +use pocketmine\world\sound\PaintingPlaceSound; use function array_rand; class PaintingItem extends Item{ @@ -95,7 +95,7 @@ class PaintingItem extends Item{ $this->pop(); $entity->spawnToAll(); - $player->getWorld()->broadcastLevelEvent($blockReplace->add(0.5, 0.5, 0.5), LevelEventPacket::EVENT_SOUND_ITEMFRAME_PLACE); //item frame and painting have the same sound + $player->getWorld()->addSound($blockReplace->add(0.5, 0.5, 0.5), new PaintingPlaceSound()); return ItemUseResult::SUCCESS(); } } diff --git a/src/pocketmine/world/sound/PaintingPlaceSound.php b/src/pocketmine/world/sound/PaintingPlaceSound.php new file mode 100644 index 0000000000..3f8792f3de --- /dev/null +++ b/src/pocketmine/world/sound/PaintingPlaceSound.php @@ -0,0 +1,33 @@ + Date: Tue, 25 Jun 2019 19:26:18 +0100 Subject: [PATCH 0989/3224] added NoteSound and NoteInstrument enum --- src/pocketmine/world/sound/NoteInstrument.php | 68 +++++++++++++++++++ src/pocketmine/world/sound/NoteSound.php | 47 +++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 src/pocketmine/world/sound/NoteInstrument.php create mode 100644 src/pocketmine/world/sound/NoteSound.php diff --git a/src/pocketmine/world/sound/NoteInstrument.php b/src/pocketmine/world/sound/NoteInstrument.php new file mode 100644 index 0000000000..a36c46f146 --- /dev/null +++ b/src/pocketmine/world/sound/NoteInstrument.php @@ -0,0 +1,68 @@ +Enum___construct($name); + $this->magicNumber = $magicNumber; + } + + /** + * @return int + */ + public function getMagicNumber() : int{ + return $this->magicNumber; + } +} diff --git a/src/pocketmine/world/sound/NoteSound.php b/src/pocketmine/world/sound/NoteSound.php new file mode 100644 index 0000000000..d81db980d9 --- /dev/null +++ b/src/pocketmine/world/sound/NoteSound.php @@ -0,0 +1,47 @@ + 255){ + throw new \InvalidArgumentException("Note $note is outside accepted range"); + } + $this->instrument = $instrument; + $this->note = $note; + } + + public function encode(?Vector3 $pos){ + return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_NOTE, $pos, ($this->instrument->getMagicNumber() << 8) | $this->note); + } +} From 44b723984716b8cf2d8d604fee859de329de9890 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 25 Jun 2019 19:28:30 +0100 Subject: [PATCH 0990/3224] SetDefaultGameTypePacket: added ::create() not using this yet, but it was in my workspace and it might come in useful --- .../network/mcpe/protocol/SetDefaultGameTypePacket.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pocketmine/network/mcpe/protocol/SetDefaultGameTypePacket.php b/src/pocketmine/network/mcpe/protocol/SetDefaultGameTypePacket.php index de16f014b7..383c91266e 100644 --- a/src/pocketmine/network/mcpe/protocol/SetDefaultGameTypePacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetDefaultGameTypePacket.php @@ -33,6 +33,12 @@ class SetDefaultGameTypePacket extends DataPacket implements ClientboundPacket, /** @var int */ public $gamemode; + public static function create(int $gameMode) : self{ + $result = new self; + $result->gamemode = $gameMode; + return $result; + } + protected function decodePayload() : void{ $this->gamemode = $this->getVarInt(); } From a6395c9ac7dd103d545a6010f09b743b96a0bc94 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 25 Jun 2019 19:37:31 +0100 Subject: [PATCH 0991/3224] allow use of any iterable for enum initialization this allows possible use of generators --- src/pocketmine/block/utils/DyeColor.php | 2 +- src/pocketmine/block/utils/SkullType.php | 2 +- src/pocketmine/block/utils/SlabType.php | 2 +- src/pocketmine/block/utils/TreeType.php | 2 +- src/pocketmine/item/ItemUseResult.php | 2 +- src/pocketmine/player/GameMode.php | 2 +- src/pocketmine/plugin/PluginLoadOrder.php | 2 +- src/pocketmine/utils/EnumTrait.php | 4 ++-- src/pocketmine/world/sound/NoteInstrument.php | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/pocketmine/block/utils/DyeColor.php b/src/pocketmine/block/utils/DyeColor.php index 122403e95b..3540d62a31 100644 --- a/src/pocketmine/block/utils/DyeColor.php +++ b/src/pocketmine/block/utils/DyeColor.php @@ -57,7 +57,7 @@ final class DyeColor{ /** @var DyeColor[] */ private static $numericIdMap = []; - protected static function setup() : array{ + protected static function setup() : iterable{ return [ new DyeColor("white", "White", 0, new Color(0xf0, 0xf0, 0xf0)), new DyeColor("orange", "Orange", 1, new Color(0xf9, 0x80, 0x1d)), diff --git a/src/pocketmine/block/utils/SkullType.php b/src/pocketmine/block/utils/SkullType.php index 3055737880..b53e974b7d 100644 --- a/src/pocketmine/block/utils/SkullType.php +++ b/src/pocketmine/block/utils/SkullType.php @@ -46,7 +46,7 @@ final class SkullType{ /** @var SkullType[] */ private static $numericIdMap = []; - protected static function setup() : array{ + protected static function setup() : iterable{ return [ new SkullType("skeleton", "Skeleton Skull", 0), new SkullType("wither_skeleton", "Wither Skeleton Skull", 1), diff --git a/src/pocketmine/block/utils/SlabType.php b/src/pocketmine/block/utils/SlabType.php index 53550520f8..15035637e0 100644 --- a/src/pocketmine/block/utils/SlabType.php +++ b/src/pocketmine/block/utils/SlabType.php @@ -37,7 +37,7 @@ use pocketmine\utils\EnumTrait; final class SlabType{ use EnumTrait; - protected static function setup() : array{ + protected static function setup() : iterable{ return [ new self("bottom"), new self("top"), diff --git a/src/pocketmine/block/utils/TreeType.php b/src/pocketmine/block/utils/TreeType.php index 36183d396f..8e0622dd6b 100644 --- a/src/pocketmine/block/utils/TreeType.php +++ b/src/pocketmine/block/utils/TreeType.php @@ -46,7 +46,7 @@ final class TreeType{ /** @var TreeType[] */ private static $numericIdMap = []; - protected static function setup() : array{ + protected static function setup() : iterable{ return [ new TreeType("oak", "Oak", 0), new TreeType("spruce", "Spruce", 1), diff --git a/src/pocketmine/item/ItemUseResult.php b/src/pocketmine/item/ItemUseResult.php index 3341d91619..7f8bdba017 100644 --- a/src/pocketmine/item/ItemUseResult.php +++ b/src/pocketmine/item/ItemUseResult.php @@ -37,7 +37,7 @@ use pocketmine\utils\EnumTrait; final class ItemUseResult{ use EnumTrait; - protected static function setup() : array{ + protected static function setup() : iterable{ return [ new self("none"), new self("fail"), diff --git a/src/pocketmine/player/GameMode.php b/src/pocketmine/player/GameMode.php index 33a37fc808..b294dd5ae1 100644 --- a/src/pocketmine/player/GameMode.php +++ b/src/pocketmine/player/GameMode.php @@ -47,7 +47,7 @@ final class GameMode{ /** @var self[] */ protected static $magicNumberMap = []; - protected static function setup() : array{ + protected static function setup() : iterable{ return [ new self("survival", 0, "Survival", "gameMode.survival", ["s", "0"]), new self("creative", 1, "Creative", "gameMode.creative", ["c", "1"]), diff --git a/src/pocketmine/plugin/PluginLoadOrder.php b/src/pocketmine/plugin/PluginLoadOrder.php index ebca6528ba..8e27befcf5 100644 --- a/src/pocketmine/plugin/PluginLoadOrder.php +++ b/src/pocketmine/plugin/PluginLoadOrder.php @@ -36,7 +36,7 @@ use pocketmine\utils\EnumTrait; final class PluginLoadOrder{ use EnumTrait; - protected static function setup() : array{ + protected static function setup() : iterable{ return [ new self("startup"), new self("postworld") diff --git a/src/pocketmine/utils/EnumTrait.php b/src/pocketmine/utils/EnumTrait.php index 994b05f9d4..a933580237 100644 --- a/src/pocketmine/utils/EnumTrait.php +++ b/src/pocketmine/utils/EnumTrait.php @@ -54,9 +54,9 @@ trait EnumTrait{ * * (This ought to be private, but traits suck too much for that.) * - * @return self[] + * @return self[]|iterable */ - abstract protected static function setup() : array; + abstract protected static function setup() : iterable; /** * @internal Lazy-inits the enum if necessary. diff --git a/src/pocketmine/world/sound/NoteInstrument.php b/src/pocketmine/world/sound/NoteInstrument.php index a36c46f146..6223333672 100644 --- a/src/pocketmine/world/sound/NoteInstrument.php +++ b/src/pocketmine/world/sound/NoteInstrument.php @@ -41,7 +41,7 @@ class NoteInstrument{ __construct as Enum___construct; } - protected static function setup() : array{ + protected static function setup() : iterable{ return [ new self("piano", 0), new self("bass_drum", 1), From 42b1c45fa553658f13a9cb4d0bced8e91aabedac Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 25 Jun 2019 19:41:00 +0100 Subject: [PATCH 0992/3224] Player: remove deprecated parameter from sendPopup() --- src/pocketmine/player/Player.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 8cf322183a..1941643c9a 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -2164,9 +2164,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * TODO: add translation type popups * * @param string $message - * @param string $subtitle @deprecated */ - public function sendPopup(string $message, string $subtitle = ""){ + public function sendPopup(string $message){ $this->networkSession->onPopup($message); } From 4448919a8b52c955dc7743813a0a945a50fee681 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 26 Jun 2019 13:22:45 +0100 Subject: [PATCH 0993/3224] Consider unknown chunk formats as corrupted the reasoning for this is that the world version number should have accounted for a chunk format change. If it didn't, then we assume any chunk with a wrong version number is corrupted, since the handling of unknown formats is the same as that of corrupted chunks. --- src/pocketmine/world/World.php | 3 +- .../world/format/io/BaseWorldProvider.php | 3 -- .../world/format/io/WorldProvider.php | 2 -- .../UnsupportedChunkFormatException.php | 30 ------------------- .../world/format/io/leveldb/LevelDB.php | 6 ++-- 5 files changed, 3 insertions(+), 41 deletions(-) delete mode 100644 src/pocketmine/world/format/io/exception/UnsupportedChunkFormatException.php diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 215882257c..2472868b6d 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -72,7 +72,6 @@ use pocketmine\world\biome\Biome; use pocketmine\world\format\Chunk; use pocketmine\world\format\EmptySubChunk; use pocketmine\world\format\io\exception\CorruptedChunkException; -use pocketmine\world\format\io\exception\UnsupportedChunkFormatException; use pocketmine\world\format\io\WritableWorldProvider; use pocketmine\world\generator\Generator; use pocketmine\world\generator\GeneratorManager; @@ -2506,7 +2505,7 @@ class World implements ChunkManager, Metadatable{ try{ $chunk = $this->provider->loadChunk($x, $z); - }catch(CorruptedChunkException | UnsupportedChunkFormatException $e){ + }catch(CorruptedChunkException $e){ $this->logger->critical("Failed to load chunk x=$x z=$z: " . $e->getMessage()); } diff --git a/src/pocketmine/world/format/io/BaseWorldProvider.php b/src/pocketmine/world/format/io/BaseWorldProvider.php index 890e78d81c..2689d0f6c6 100644 --- a/src/pocketmine/world/format/io/BaseWorldProvider.php +++ b/src/pocketmine/world/format/io/BaseWorldProvider.php @@ -26,7 +26,6 @@ namespace pocketmine\world\format\io; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\exception\CorruptedWorldException; -use pocketmine\world\format\io\exception\UnsupportedChunkFormatException; use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; use pocketmine\world\WorldException; use function file_exists; @@ -70,7 +69,6 @@ abstract class BaseWorldProvider implements WorldProvider{ * * @return Chunk|null * @throws CorruptedChunkException - * @throws UnsupportedChunkFormatException */ public function loadChunk(int $chunkX, int $chunkZ) : ?Chunk{ return $this->readChunk($chunkX, $chunkZ); @@ -88,7 +86,6 @@ abstract class BaseWorldProvider implements WorldProvider{ * @param int $chunkZ * * @return Chunk|null - * @throws UnsupportedChunkFormatException * @throws CorruptedChunkException */ abstract protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk; diff --git a/src/pocketmine/world/format/io/WorldProvider.php b/src/pocketmine/world/format/io/WorldProvider.php index 71cebcaae3..122aca55fa 100644 --- a/src/pocketmine/world/format/io/WorldProvider.php +++ b/src/pocketmine/world/format/io/WorldProvider.php @@ -26,7 +26,6 @@ namespace pocketmine\world\format\io; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\exception\CorruptedWorldException; -use pocketmine\world\format\io\exception\UnsupportedChunkFormatException; use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; interface WorldProvider{ @@ -69,7 +68,6 @@ interface WorldProvider{ * @return null|Chunk * * @throws CorruptedChunkException - * @throws UnsupportedChunkFormatException */ public function loadChunk(int $chunkX, int $chunkZ) : ?Chunk; diff --git a/src/pocketmine/world/format/io/exception/UnsupportedChunkFormatException.php b/src/pocketmine/world/format/io/exception/UnsupportedChunkFormatException.php deleted file mode 100644 index 3694c9f46d..0000000000 --- a/src/pocketmine/world/format/io/exception/UnsupportedChunkFormatException.php +++ /dev/null @@ -1,30 +0,0 @@ - Date: Wed, 26 Jun 2019 13:46:53 +0100 Subject: [PATCH 0994/3224] PreSpawnPacketHandler: drop useless sending time this is already sent in StartGamePacket. --- src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php b/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php index 5f7e3a8ae4..9effed61e0 100644 --- a/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php @@ -83,8 +83,6 @@ class PreSpawnPacketHandler extends PacketHandler{ $this->player->setImmobile(); //HACK: fix client-side falling pre-spawn - $this->player->getWorld()->sendTime($this->player); - $this->session->syncAttributes($this->player, true); $this->session->syncAvailableCommands(); $this->session->syncAdventureSettings($this->player); From 26178b443539c2c79925d1535aef78df2b7b4693 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 26 Jun 2019 13:57:52 +0100 Subject: [PATCH 0995/3224] InventoryManager: remove redundant cyclic dependency --- src/pocketmine/network/mcpe/InventoryManager.php | 2 +- src/pocketmine/player/Player.php | 11 ----------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/src/pocketmine/network/mcpe/InventoryManager.php b/src/pocketmine/network/mcpe/InventoryManager.php index 097e55ee67..da285bb87d 100644 --- a/src/pocketmine/network/mcpe/InventoryManager.php +++ b/src/pocketmine/network/mcpe/InventoryManager.php @@ -132,7 +132,7 @@ class InventoryManager{ } public function syncAll() : void{ - foreach($this->player->getAllWindows() as $inventory){ + foreach($this->windowMap as $inventory){ $this->syncContents($inventory); } } diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 1941643c9a..b9dd0d6556 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -2677,17 +2677,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->permanentWindows = []; } - /** - * @return Inventory[] - */ - public function getAllWindows() : array{ - $windows = $this->permanentWindows; - if($this->currentWindow !== null){ - $windows[] = $this->currentWindow; - } - return $windows; - } - public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue) : void{ $this->server->getPlayerMetadata()->setMetadata($this, $metadataKey, $newMetadataValue); } From ee72680f440c411ef488c88896fb6ffb3019920b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 26 Jun 2019 14:43:21 +0100 Subject: [PATCH 0996/3224] Removing "metadata": overengineered useless Bukkit copy-pasta the intentions of this are good, but the usability is terrible and it's not fit for purpose. Since there are a total of zero plugins on Poggit which use this garbage, it makes more sense to eliminate the technical debt. See #2766 for discussion about replacing this. --- src/pocketmine/Server.php | 37 ------ src/pocketmine/block/Block.php | 33 +----- src/pocketmine/entity/Entity.php | 21 +--- .../metadata/BlockMetadataStore.php | 60 ---------- .../metadata/EntityMetadataStore.php | 50 -------- src/pocketmine/metadata/MetadataStore.php | 110 ------------------ src/pocketmine/metadata/MetadataValue.php | 55 --------- src/pocketmine/metadata/Metadatable.php | 67 ----------- .../metadata/PlayerMetadataStore.php | 51 -------- .../metadata/WorldMetadataStore.php | 51 -------- src/pocketmine/player/OfflinePlayer.php | 21 +--- src/pocketmine/player/Player.php | 18 --- src/pocketmine/world/World.php | 31 +---- 13 files changed, 4 insertions(+), 601 deletions(-) delete mode 100644 src/pocketmine/metadata/BlockMetadataStore.php delete mode 100644 src/pocketmine/metadata/EntityMetadataStore.php delete mode 100644 src/pocketmine/metadata/MetadataStore.php delete mode 100644 src/pocketmine/metadata/MetadataValue.php delete mode 100644 src/pocketmine/metadata/Metadatable.php delete mode 100644 src/pocketmine/metadata/PlayerMetadataStore.php delete mode 100644 src/pocketmine/metadata/WorldMetadataStore.php diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index bcc93a2a2b..ac556a5504 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -46,9 +46,6 @@ use pocketmine\item\ItemFactory; use pocketmine\lang\Language; use pocketmine\lang\LanguageNotFoundException; use pocketmine\lang\TextContainer; -use pocketmine\metadata\EntityMetadataStore; -use pocketmine\metadata\PlayerMetadataStore; -use pocketmine\metadata\WorldMetadataStore; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; @@ -246,15 +243,6 @@ class Server{ /** @var bool */ private $onlineMode = true; - /** @var EntityMetadataStore */ - private $entityMetadata; - - /** @var PlayerMetadataStore */ - private $playerMetadata; - - /** @var WorldMetadataStore */ - private $worldMetadata; - /** @var Network */ private $network; /** @var bool */ @@ -477,27 +465,6 @@ class Server{ return $this->logger; } - /** - * @return EntityMetadataStore - */ - public function getEntityMetadata(){ - return $this->entityMetadata; - } - - /** - * @return PlayerMetadataStore - */ - public function getPlayerMetadata(){ - return $this->playerMetadata; - } - - /** - * @return WorldMetadataStore - */ - public function getWorldMetadata(){ - return $this->worldMetadata; - } - /** * @return AutoUpdater */ @@ -1138,10 +1105,6 @@ class Server{ $this->doTitleTick = ((bool) $this->getProperty("console.title-tick", true)) && Terminal::hasFormattingCodes(); - $this->entityMetadata = new EntityMetadataStore(); - $this->playerMetadata = new PlayerMetadataStore(); - $this->worldMetadata = new WorldMetadataStore(); - $this->operators = new Config($this->dataPath . "ops.txt", Config::ENUM); $this->whitelist = new Config($this->dataPath . "white-list.txt", Config::ENUM); if(file_exists($this->dataPath . "banned.txt") and !file_exists($this->dataPath . "banned-players.txt")){ diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index b3261209bf..4062d12356 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -38,12 +38,9 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\RayTraceResult; use pocketmine\math\Vector3; -use pocketmine\metadata\Metadatable; -use pocketmine\metadata\MetadataValue; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; use pocketmine\player\Player; -use pocketmine\plugin\Plugin; use pocketmine\world\BlockTransaction; use pocketmine\world\Position; use pocketmine\world\World; @@ -52,7 +49,7 @@ use function assert; use function dechex; use const PHP_INT_MAX; -class Block extends Position implements BlockLegacyIds, Metadatable{ +class Block extends Position implements BlockLegacyIds{ /** * Returns a new Block instance with the specified ID, meta and position. @@ -752,32 +749,4 @@ class Block extends Position implements BlockLegacyIds, Metadatable{ return $currentHit; } - - public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue) : void{ - if($this->isValid()){ - $this->world->getBlockMetadata()->setMetadata($this, $metadataKey, $newMetadataValue); - } - } - - public function getMetadata(string $metadataKey){ - if($this->isValid()){ - return $this->world->getBlockMetadata()->getMetadata($this, $metadataKey); - } - - return null; - } - - public function hasMetadata(string $metadataKey) : bool{ - if($this->isValid()){ - return $this->world->getBlockMetadata()->hasMetadata($this, $metadataKey); - } - - return false; - } - - public function removeMetadata(string $metadataKey, Plugin $owningPlugin) : void{ - if($this->isValid()){ - $this->world->getBlockMetadata()->removeMetadata($this, $metadataKey, $owningPlugin); - } - } } diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index db768c7faf..49bea4aa01 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -39,8 +39,6 @@ use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector2; use pocketmine\math\Vector3; -use pocketmine\metadata\Metadatable; -use pocketmine\metadata\MetadataValue; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\FloatTag; @@ -58,7 +56,6 @@ use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\EntityMetadataTypes; use pocketmine\player\Player; -use pocketmine\plugin\Plugin; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; @@ -81,7 +78,7 @@ use function sin; use function spl_object_id; use const M_PI_2; -abstract class Entity extends Location implements Metadatable, EntityIds{ +abstract class Entity extends Location implements EntityIds{ public const MOTION_THRESHOLD = 0.00001; @@ -1798,22 +1795,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->close(); } - public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue) : void{ - $this->server->getEntityMetadata()->setMetadata($this, $metadataKey, $newMetadataValue); - } - - public function getMetadata(string $metadataKey){ - return $this->server->getEntityMetadata()->getMetadata($this, $metadataKey); - } - - public function hasMetadata(string $metadataKey) : bool{ - return $this->server->getEntityMetadata()->hasMetadata($this, $metadataKey); - } - - public function removeMetadata(string $metadataKey, Plugin $owningPlugin) : void{ - $this->server->getEntityMetadata()->removeMetadata($this, $metadataKey, $owningPlugin); - } - public function __toString(){ return (new \ReflectionClass($this))->getShortName() . "(" . $this->getId() . ")"; } diff --git a/src/pocketmine/metadata/BlockMetadataStore.php b/src/pocketmine/metadata/BlockMetadataStore.php deleted file mode 100644 index 87cfd85f96..0000000000 --- a/src/pocketmine/metadata/BlockMetadataStore.php +++ /dev/null @@ -1,60 +0,0 @@ -owningLevel = $owningLevel; - } - - private function disambiguate(Block $block, string $metadataKey) : string{ - if($block->getWorld() !== $this->owningLevel){ - throw new \InvalidStateException("Block does not belong to world " . $this->owningLevel->getDisplayName()); - } - return $block->x . ":" . $block->y . ":" . $block->z . ":" . $metadataKey; - } - - public function getMetadata(Block $subject, string $metadataKey){ - return $this->getMetadataInternal($this->disambiguate($subject, $metadataKey)); - } - - public function hasMetadata(Block $subject, string $metadataKey) : bool{ - return $this->hasMetadataInternal($this->disambiguate($subject, $metadataKey)); - } - - public function removeMetadata(Block $subject, string $metadataKey, Plugin $owningPlugin) : void{ - $this->removeMetadataInternal($this->disambiguate($subject, $metadataKey), $owningPlugin); - } - - public function setMetadata(Block $subject, string $metadataKey, MetadataValue $newMetadataValue) : void{ - $this->setMetadataInternal($this->disambiguate($subject, $metadataKey), $newMetadataValue); - } -} diff --git a/src/pocketmine/metadata/EntityMetadataStore.php b/src/pocketmine/metadata/EntityMetadataStore.php deleted file mode 100644 index b7d1332617..0000000000 --- a/src/pocketmine/metadata/EntityMetadataStore.php +++ /dev/null @@ -1,50 +0,0 @@ -getId() . ":" . $metadataKey; - } - - public function getMetadata(Entity $subject, string $metadataKey){ - return $this->getMetadataInternal($this->disambiguate($subject, $metadataKey)); - } - - public function hasMetadata(Entity $subject, string $metadataKey) : bool{ - return $this->hasMetadataInternal($this->disambiguate($subject, $metadataKey)); - } - - public function removeMetadata(Entity $subject, string $metadataKey, Plugin $owningPlugin) : void{ - $this->removeMetadataInternal($this->disambiguate($subject, $metadataKey), $owningPlugin); - } - - public function setMetadata(Entity $subject, string $metadataKey, MetadataValue $newMetadataValue) : void{ - $this->setMetadataInternal($this->disambiguate($subject, $metadataKey), $newMetadataValue); - } -} diff --git a/src/pocketmine/metadata/MetadataStore.php b/src/pocketmine/metadata/MetadataStore.php deleted file mode 100644 index 99e21a25e6..0000000000 --- a/src/pocketmine/metadata/MetadataStore.php +++ /dev/null @@ -1,110 +0,0 @@ -getOwningPlugin(); - - if(!isset($this->metadataMap[$key])){ - $entry = new \SplObjectStorage(); - $this->metadataMap[$key] = $entry; - }else{ - $entry = $this->metadataMap[$key]; - } - $entry[$owningPlugin] = $newMetadataValue; - } - - /** - * Returns all metadata values attached to an object. If multiple - * have attached metadata, each will value will be included. - * - * @param string $key - * - * @return MetadataValue[] - */ - protected function getMetadataInternal(string $key){ - if(isset($this->metadataMap[$key])){ - return $this->metadataMap[$key]; - }else{ - return []; - } - } - - /** - * Tests to see if a metadata attribute has been set on an object. - * - * @param string $key - * - * @return bool - */ - protected function hasMetadataInternal(string $key) : bool{ - return isset($this->metadataMap[$key]); - } - - /** - * Removes a metadata item owned by a plugin from a subject. - * - * @param string $key - * @param Plugin $owningPlugin - */ - protected function removeMetadataInternal(string $key, Plugin $owningPlugin) : void{ - if(isset($this->metadataMap[$key])){ - unset($this->metadataMap[$key][$owningPlugin]); - if($this->metadataMap[$key]->count() === 0){ - unset($this->metadataMap[$key]); - } - } - } - - /** - * Invalidates all metadata in the metadata store that originates from the - * given plugin. Doing this will force each invalidated metadata item to - * be recalculated the next time it is accessed. - * - * @param Plugin $owningPlugin - */ - public function invalidateAll(Plugin $owningPlugin) : void{ - /** @var MetadataValue[] $values */ - foreach($this->metadataMap as $values){ - if(isset($values[$owningPlugin])){ - $values[$owningPlugin]->invalidate(); - } - } - } -} diff --git a/src/pocketmine/metadata/MetadataValue.php b/src/pocketmine/metadata/MetadataValue.php deleted file mode 100644 index 9f678df3aa..0000000000 --- a/src/pocketmine/metadata/MetadataValue.php +++ /dev/null @@ -1,55 +0,0 @@ -owningPlugin = $owningPlugin; - } - - /** - * @return Plugin - */ - public function getOwningPlugin() : Plugin{ - return $this->owningPlugin; - } - - /** - * Fetches the value of this metadata item. - * - * @return mixed - */ - abstract public function value(); - - /** - * Invalidates this metadata item, forcing it to recompute when next - * accessed. - */ - abstract public function invalidate() : void; -} diff --git a/src/pocketmine/metadata/Metadatable.php b/src/pocketmine/metadata/Metadatable.php deleted file mode 100644 index eadcbef734..0000000000 --- a/src/pocketmine/metadata/Metadatable.php +++ /dev/null @@ -1,67 +0,0 @@ -getName()) . ":" . $metadataKey; - } - - public function getMetadata(IPlayer $subject, string $metadataKey){ - return $this->getMetadataInternal($this->disambiguate($subject, $metadataKey)); - } - - public function hasMetadata(IPlayer $subject, string $metadataKey) : bool{ - return $this->hasMetadataInternal($this->disambiguate($subject, $metadataKey)); - } - - public function removeMetadata(IPlayer $subject, string $metadataKey, Plugin $owningPlugin) : void{ - $this->removeMetadataInternal($this->disambiguate($subject, $metadataKey), $owningPlugin); - } - - public function setMetadata(IPlayer $subject, string $metadataKey, MetadataValue $newMetadataValue) : void{ - $this->setMetadataInternal($this->disambiguate($subject, $metadataKey), $newMetadataValue); - } -} diff --git a/src/pocketmine/metadata/WorldMetadataStore.php b/src/pocketmine/metadata/WorldMetadataStore.php deleted file mode 100644 index 7893ba19aa..0000000000 --- a/src/pocketmine/metadata/WorldMetadataStore.php +++ /dev/null @@ -1,51 +0,0 @@ -getFolderName()) . ":" . $metadataKey; - } - - public function getMetadata(World $subject, string $metadataKey){ - return $this->getMetadataInternal($this->disambiguate($subject, $metadataKey)); - } - - public function hasMetadata(World $subject, string $metadataKey) : bool{ - return $this->hasMetadataInternal($this->disambiguate($subject, $metadataKey)); - } - - public function removeMetadata(World $subject, string $metadataKey, Plugin $owningPlugin) : void{ - $this->removeMetadataInternal($this->disambiguate($subject, $metadataKey), $owningPlugin); - } - - public function setMetadata(World $subject, string $metadataKey, MetadataValue $newMetadataValue) : void{ - $this->setMetadataInternal($this->disambiguate($subject, $metadataKey), $newMetadataValue); - } -} diff --git a/src/pocketmine/player/OfflinePlayer.php b/src/pocketmine/player/OfflinePlayer.php index 81a77d2509..f04b79eacd 100644 --- a/src/pocketmine/player/OfflinePlayer.php +++ b/src/pocketmine/player/OfflinePlayer.php @@ -23,14 +23,11 @@ declare(strict_types=1); namespace pocketmine\player; -use pocketmine\metadata\Metadatable; -use pocketmine\metadata\MetadataValue; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\LongTag; -use pocketmine\plugin\Plugin; use pocketmine\Server; -class OfflinePlayer implements IPlayer, Metadatable{ +class OfflinePlayer implements IPlayer{ /** @var string */ private $name; @@ -116,20 +113,4 @@ class OfflinePlayer implements IPlayer, Metadatable{ public function hasPlayedBefore() : bool{ return $this->namedtag !== null; } - - public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue) : void{ - $this->server->getPlayerMetadata()->setMetadata($this, $metadataKey, $newMetadataValue); - } - - public function getMetadata(string $metadataKey){ - return $this->server->getPlayerMetadata()->getMetadata($this, $metadataKey); - } - - public function hasMetadata(string $metadataKey) : bool{ - return $this->server->getPlayerMetadata()->hasMetadata($this, $metadataKey); - } - - public function removeMetadata(string $metadataKey, Plugin $owningPlugin) : void{ - $this->server->getPlayerMetadata()->removeMetadata($this, $metadataKey, $owningPlugin); - } } diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index b9dd0d6556..f62428432f 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -80,7 +80,6 @@ use pocketmine\item\ItemUseResult; use pocketmine\lang\TextContainer; use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; -use pocketmine\metadata\MetadataValue; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\DoubleTag; @@ -98,7 +97,6 @@ use pocketmine\network\mcpe\protocol\types\PlayerMetadataFlags; use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissibleDelegateTrait; use pocketmine\permission\PermissionManager; -use pocketmine\plugin\Plugin; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\TextFormat; @@ -2677,22 +2675,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->permanentWindows = []; } - public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue) : void{ - $this->server->getPlayerMetadata()->setMetadata($this, $metadataKey, $newMetadataValue); - } - - public function getMetadata(string $metadataKey){ - return $this->server->getPlayerMetadata()->getMetadata($this, $metadataKey); - } - - public function hasMetadata(string $metadataKey) : bool{ - return $this->server->getPlayerMetadata()->hasMetadata($this, $metadataKey); - } - - public function removeMetadata(string $metadataKey, Plugin $owningPlugin) : void{ - $this->server->getPlayerMetadata()->removeMetadata($this, $metadataKey, $owningPlugin); - } - use ChunkListenerNoOpTrait { onChunkChanged as private; } diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 2472868b6d..d622766399 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -51,9 +51,6 @@ use pocketmine\item\ItemFactory; use pocketmine\item\ItemUseResult; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; -use pocketmine\metadata\BlockMetadataStore; -use pocketmine\metadata\Metadatable; -use pocketmine\metadata\MetadataValue; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; @@ -64,7 +61,6 @@ use pocketmine\network\mcpe\protocol\SetTimePacket; use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; use pocketmine\player\Player; -use pocketmine\plugin\Plugin; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\ReversePriorityQueue; @@ -115,7 +111,7 @@ use const PHP_INT_MIN; #include -class World implements ChunkManager, Metadatable{ +class World implements ChunkManager{ private static $worldIdCounter = 1; @@ -227,9 +223,6 @@ class World implements ChunkManager, Metadatable{ /** @var bool */ private $autoSave = true; - /** @var BlockMetadataStore */ - private $blockMetadata; - /** @var Position */ private $temporalPosition; /** @var Vector3 */ @@ -349,7 +342,6 @@ class World implements ChunkManager, Metadatable{ */ public function __construct(Server $server, string $name, WritableWorldProvider $provider){ $this->worldId = static::$worldIdCounter++; - $this->blockMetadata = new BlockMetadataStore($this); $this->server = $server; $this->provider = $provider; @@ -416,10 +408,6 @@ class World implements ChunkManager, Metadatable{ $this->generatorRegisteredWorkers = []; } - public function getBlockMetadata() : BlockMetadataStore{ - return $this->blockMetadata; - } - public function getServer() : Server{ return $this->server; } @@ -461,7 +449,6 @@ class World implements ChunkManager, Metadatable{ $this->provider->close(); $this->provider = null; - $this->blockMetadata = null; $this->blockCache = []; $this->temporalPosition = null; @@ -2857,20 +2844,4 @@ class World implements ChunkManager, Metadatable{ } } } - - public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue) : void{ - $this->server->getWorldMetadata()->setMetadata($this, $metadataKey, $newMetadataValue); - } - - public function getMetadata(string $metadataKey){ - return $this->server->getWorldMetadata()->getMetadata($this, $metadataKey); - } - - public function hasMetadata(string $metadataKey) : bool{ - return $this->server->getWorldMetadata()->hasMetadata($this, $metadataKey); - } - - public function removeMetadata(string $metadataKey, Plugin $owningPlugin) : void{ - $this->server->getWorldMetadata()->removeMetadata($this, $metadataKey, $owningPlugin); - } } From eee039a4904f9aeb811a0e3a0fe4252caff2941b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 26 Jun 2019 15:32:57 +0100 Subject: [PATCH 0997/3224] Player: don't fire events on equipItem() when sending the same slot --- src/pocketmine/player/Player.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index f62428432f..2553c43bf6 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -1652,6 +1652,9 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if(!$this->inventory->isHotbarSlot($hotbarSlot)){ //TODO: exception here? return false; } + if($hotbarSlot === $this->inventory->getHeldItemIndex()){ + return true; + } $ev = new PlayerItemHeldEvent($this, $this->inventory->getItem($hotbarSlot), $hotbarSlot); $ev->call(); From 7bdb99ae8b2eb8dd3eab123fb48cd950dfa4d925 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 26 Jun 2019 15:47:16 +0100 Subject: [PATCH 0998/3224] Player: fixed consumable relying on undefined network behaviour to set using-item flags --- src/pocketmine/player/Player.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 2553c43bf6..780e60a9a1 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -1722,6 +1722,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return false; } + $this->setUsingItem(false); $this->resetItemCooldown($slot); if($this->hasFiniteResources()){ From f62d9cbb99c807278424f8fcdd8fe47831032036 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 26 Jun 2019 15:52:01 +0100 Subject: [PATCH 0999/3224] Player: rename equipItem() to selectHotbarSlot() --- src/pocketmine/network/mcpe/handler/InGamePacketHandler.php | 2 +- src/pocketmine/player/Player.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php index 7df975db13..df6b39d984 100644 --- a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php @@ -358,7 +358,7 @@ class InGamePacketHandler extends PacketHandler{ } public function handleMobEquipment(MobEquipmentPacket $packet) : bool{ - if(!$this->player->equipItem($packet->hotbarSlot)){ + if(!$this->player->selectHotbarSlot($packet->hotbarSlot)){ $this->player->getInventory()->sendHeldItem($this->player); } return true; diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 780e60a9a1..4c1f1e72fd 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -1648,7 +1648,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return true; } - public function equipItem(int $hotbarSlot) : bool{ + public function selectHotbarSlot(int $hotbarSlot) : bool{ if(!$this->inventory->isHotbarSlot($hotbarSlot)){ //TODO: exception here? return false; } From 9cedfeb2b2457755d0662660326d5bc9f33782b3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 26 Jun 2019 17:56:39 +0100 Subject: [PATCH 1000/3224] Use the appropriate synchronization for held item rollbacks --- .../network/mcpe/handler/InGamePacketHandler.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php index df6b39d984..2edcae7a74 100644 --- a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php @@ -286,7 +286,7 @@ class InGamePacketHandler extends PacketHandler{ return true; case UseItemTransactionData::ACTION_CLICK_AIR: if(!$this->player->useHeldItem()){ - $this->player->getInventory()->sendHeldItem($this->player); + $this->session->getInvManager()->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); } return true; } @@ -301,7 +301,7 @@ class InGamePacketHandler extends PacketHandler{ * @param int|null $face */ private function onFailedBlockAction(Vector3 $blockPos, ?int $face) : void{ - $this->player->getInventory()->sendHeldItem($this->player); + $this->session->getInvManager()->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); if($blockPos->distanceSquared($this->player) < 10000){ $blocks = $blockPos->sidesArray(); if($face !== null){ @@ -326,12 +326,12 @@ class InGamePacketHandler extends PacketHandler{ switch($data->getActionType()){ case UseItemOnEntityTransactionData::ACTION_INTERACT: if(!$this->player->interactEntity($target, $data->getClickPos())){ - $this->player->getInventory()->sendHeldItem($this->player); + $this->session->getInvManager()->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); } return true; case UseItemOnEntityTransactionData::ACTION_ATTACK: if(!$this->player->attackEntity($target)){ - $this->player->getInventory()->sendHeldItem($this->player); + $this->session->getInvManager()->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); } return true; } @@ -349,7 +349,7 @@ class InGamePacketHandler extends PacketHandler{ return true; case ReleaseItemTransactionData::ACTION_CONSUME: if(!$this->player->consumeHeldItem()){ - $this->player->getInventory()->sendHeldItem($this->player); + $this->session->getInvManager()->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); } return true; } From 7eaca6bbaa7b3f3eadb8243fb17bf21248a06eaf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 26 Jun 2019 18:19:29 +0100 Subject: [PATCH 1001/3224] Separate packet-sender functionality from NetworkInterface, break cyclic dependency between NetworkInterface and NetworkSession --- src/pocketmine/network/NetworkInterface.php | 19 ------- .../network/mcpe/NetworkSession.php | 10 ++-- src/pocketmine/network/mcpe/PacketSender.php | 42 +++++++++++++++ .../network/mcpe/RakLibInterface.php | 25 +++------ .../network/mcpe/RakLibPacketSender.php | 53 +++++++++++++++++++ 5 files changed, 110 insertions(+), 39 deletions(-) create mode 100644 src/pocketmine/network/mcpe/PacketSender.php create mode 100644 src/pocketmine/network/mcpe/RakLibPacketSender.php diff --git a/src/pocketmine/network/NetworkInterface.php b/src/pocketmine/network/NetworkInterface.php index 8ef8484637..47241c341f 100644 --- a/src/pocketmine/network/NetworkInterface.php +++ b/src/pocketmine/network/NetworkInterface.php @@ -26,8 +26,6 @@ declare(strict_types=1); */ namespace pocketmine\network; -use pocketmine\network\mcpe\NetworkSession; - /** * Network interfaces are transport layers which can be used to transmit packets between the server and clients. */ @@ -38,23 +36,6 @@ interface NetworkInterface{ */ public function start() : void; - /** - * Sends a packet to the interface, returns an unique identifier for the packet if $needACK is true - * - * @param NetworkSession $session - * @param string $payload - * @param bool $immediate - */ - public function putPacket(NetworkSession $session, string $payload, bool $immediate = true) : void; - - /** - * Terminates the connection - * - * @param NetworkSession $session - * @param string $reason - */ - public function close(NetworkSession $session, string $reason = "unknown reason") : void; - /** * @param string $name */ diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 6f91972d44..2ec17d0f63 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -137,10 +137,14 @@ class NetworkSession{ /** @var InventoryManager|null */ private $invManager = null; - public function __construct(Server $server, NetworkSessionManager $manager, NetworkInterface $interface, string $ip, int $port){ + /** @var PacketSender */ + private $sender; + + public function __construct(Server $server, NetworkSessionManager $manager, NetworkInterface $interface, PacketSender $sender, string $ip, int $port){ $this->server = $server; $this->manager = $manager; $this->interface = $interface; + $this->sender = $sender; $this->ip = $ip; $this->port = $port; @@ -431,7 +435,7 @@ class NetworkSession{ $payload = $this->cipher->encrypt($payload); Timings::$playerNetworkSendEncryptTimer->stopTiming(); } - $this->interface->putPacket($this, $payload, $immediate); + $this->sender->send($payload, $immediate); } private function tryDisconnect(\Closure $func, string $reason) : void{ @@ -506,7 +510,7 @@ class NetworkSession{ $this->sendDataPacket($reason === "" ? DisconnectPacket::silent() : DisconnectPacket::message($reason), true); } - $this->interface->close($this, $notify ? $reason : ""); + $this->sender->close($notify ? $reason : ""); } /** diff --git a/src/pocketmine/network/mcpe/PacketSender.php b/src/pocketmine/network/mcpe/PacketSender.php new file mode 100644 index 0000000000..857293ffb5 --- /dev/null +++ b/src/pocketmine/network/mcpe/PacketSender.php @@ -0,0 +1,42 @@ +sessions[$sessionId])){ $session = $this->sessions[$sessionId]; - unset($this->identifiers[spl_object_id($session)]); unset($this->sessions[$sessionId]); $session->onClientDisconnect($reason); } } - public function close(NetworkSession $session, string $reason = "unknown reason") : void{ - if(isset($this->identifiers[$h = spl_object_id($session)])){ - unset($this->sessions[$this->identifiers[$h]]); - $this->interface->closeSession($this->identifiers[$h], $reason); - unset($this->identifiers[$h]); + public function close(int $sessionId, string $reason = "unknown reason") : void{ + if(isset($this->sessions[$sessionId])){ + unset($this->sessions[$sessionId]); + $this->interface->closeSession($sessionId, $reason); } } @@ -139,9 +133,8 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ } public function openSession(int $sessionId, string $address, int $port, int $clientID) : void{ - $session = new NetworkSession($this->server, $this->network->getSessionManager(), $this, $address, $port); + $session = new NetworkSession($this->server, $this->network->getSessionManager(), $this, new RakLibPacketSender($sessionId, $this), $address, $port); $this->sessions[$sessionId] = $session; - $this->identifiers[spl_object_id($session)] = $sessionId; } public function handleEncapsulated(int $sessionId, EncapsulatedPacket $packet, int $flags) : void{ @@ -225,16 +218,14 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ } } - public function putPacket(NetworkSession $session, string $payload, bool $immediate = true) : void{ - if(isset($this->identifiers[$h = spl_object_id($session)])){ - $identifier = $this->identifiers[$h]; - + public function putPacket(int $sessionId, string $payload, bool $immediate = true) : void{ + if(isset($this->sessions[$sessionId])){ $pk = new EncapsulatedPacket(); $pk->buffer = self::MCPE_RAKNET_PACKET_ID . $payload; $pk->reliability = PacketReliability::RELIABLE_ORDERED; $pk->orderChannel = 0; - $this->interface->sendEncapsulated($identifier, $pk, ($immediate ? RakLib::PRIORITY_IMMEDIATE : RakLib::PRIORITY_NORMAL)); + $this->interface->sendEncapsulated($sessionId, $pk, ($immediate ? RakLib::PRIORITY_IMMEDIATE : RakLib::PRIORITY_NORMAL)); } } diff --git a/src/pocketmine/network/mcpe/RakLibPacketSender.php b/src/pocketmine/network/mcpe/RakLibPacketSender.php new file mode 100644 index 0000000000..90a8c3433e --- /dev/null +++ b/src/pocketmine/network/mcpe/RakLibPacketSender.php @@ -0,0 +1,53 @@ +sessionId = $sessionId; + $this->handler = $handler; + } + + public function send(string $payload, bool $immediate) : void{ + if(!$this->closed){ + $this->handler->putPacket($this->sessionId, $payload, $immediate); + } + } + + public function close(string $reason = "unknown reason") : void{ + if(!$this->closed){ + $this->closed = true; + $this->handler->closeSession($this->sessionId, $reason); + } + } +} From 3f9493bcd0af35063f495f366b31e36766120b4e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 26 Jun 2019 18:22:32 +0100 Subject: [PATCH 1002/3224] Remove another NetworkSession <-> NetworkInterface cyclic dependency --- src/pocketmine/event/player/PlayerCreationEvent.php | 8 -------- src/pocketmine/network/mcpe/NetworkSession.php | 10 +--------- src/pocketmine/network/mcpe/RakLibInterface.php | 2 +- 3 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/pocketmine/event/player/PlayerCreationEvent.php b/src/pocketmine/event/player/PlayerCreationEvent.php index 5976e0605d..f3318058ea 100644 --- a/src/pocketmine/event/player/PlayerCreationEvent.php +++ b/src/pocketmine/event/player/PlayerCreationEvent.php @@ -25,7 +25,6 @@ namespace pocketmine\event\player; use pocketmine\event\Event; use pocketmine\network\mcpe\NetworkSession; -use pocketmine\network\NetworkInterface; use pocketmine\player\Player; use function is_a; @@ -50,13 +49,6 @@ class PlayerCreationEvent extends Event{ $this->session = $session; } - /** - * @return NetworkInterface - */ - public function getInterface() : NetworkInterface{ - return $this->session->getInterface(); - } - /** * @return NetworkSession */ diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 2ec17d0f63..51be868584 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -65,7 +65,6 @@ use pocketmine\network\mcpe\protocol\types\CommandParameter; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; -use pocketmine\network\NetworkInterface; use pocketmine\network\NetworkSessionManager; use pocketmine\player\GameMode; use pocketmine\player\Player; @@ -100,8 +99,6 @@ class NetworkSession{ private $player = null; /** @var NetworkSessionManager */ private $manager; - /** @var NetworkInterface */ - private $interface; /** @var string */ private $ip; /** @var int */ @@ -140,10 +137,9 @@ class NetworkSession{ /** @var PacketSender */ private $sender; - public function __construct(Server $server, NetworkSessionManager $manager, NetworkInterface $interface, PacketSender $sender, string $ip, int $port){ + public function __construct(Server $server, NetworkSessionManager $manager, PacketSender $sender, string $ip, int $port){ $this->server = $server; $this->manager = $manager; - $this->interface = $interface; $this->sender = $sender; $this->ip = $ip; $this->port = $port; @@ -209,10 +205,6 @@ class NetworkSession{ return $this->connected; } - public function getInterface() : NetworkInterface{ - return $this->interface; - } - /** * @return string */ diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/RakLibInterface.php index 8b6a46d958..6a57bb7ff7 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/RakLibInterface.php @@ -133,7 +133,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ } public function openSession(int $sessionId, string $address, int $port, int $clientID) : void{ - $session = new NetworkSession($this->server, $this->network->getSessionManager(), $this, new RakLibPacketSender($sessionId, $this), $address, $port); + $session = new NetworkSession($this->server, $this->network->getSessionManager(), new RakLibPacketSender($sessionId, $this), $address, $port); $this->sessions[$sessionId] = $session; } From 9fe073fa73842aae9be69f42091b13e1882e93c3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 26 Jun 2019 18:36:42 +0100 Subject: [PATCH 1003/3224] move RakLib-specific components to mcpe\raklib namespace --- src/pocketmine/Server.php | 2 +- src/pocketmine/network/mcpe/{ => raklib}/RakLibInterface.php | 3 ++- .../network/mcpe/{ => raklib}/RakLibPacketSender.php | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) rename src/pocketmine/network/mcpe/{ => raklib}/RakLibInterface.php (98%) rename src/pocketmine/network/mcpe/{ => raklib}/RakLibPacketSender.php (94%) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index ac556a5504..9299bff8da 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -58,7 +58,7 @@ use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\PacketBatch; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\ProtocolInfo; -use pocketmine\network\mcpe\RakLibInterface; +use pocketmine\network\mcpe\raklib\RakLibInterface; use pocketmine\network\Network; use pocketmine\network\query\QueryHandler; use pocketmine\network\upnp\UPnP; diff --git a/src/pocketmine/network/mcpe/RakLibInterface.php b/src/pocketmine/network/mcpe/raklib/RakLibInterface.php similarity index 98% rename from src/pocketmine/network/mcpe/RakLibInterface.php rename to src/pocketmine/network/mcpe/raklib/RakLibInterface.php index 6a57bb7ff7..8c91b37f93 100644 --- a/src/pocketmine/network/mcpe/RakLibInterface.php +++ b/src/pocketmine/network/mcpe/raklib/RakLibInterface.php @@ -21,10 +21,11 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe; +namespace pocketmine\network\mcpe\raklib; use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\BadPacketException; +use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\Network; use pocketmine\Server; diff --git a/src/pocketmine/network/mcpe/RakLibPacketSender.php b/src/pocketmine/network/mcpe/raklib/RakLibPacketSender.php similarity index 94% rename from src/pocketmine/network/mcpe/RakLibPacketSender.php rename to src/pocketmine/network/mcpe/raklib/RakLibPacketSender.php index 90a8c3433e..29ee9b3861 100644 --- a/src/pocketmine/network/mcpe/RakLibPacketSender.php +++ b/src/pocketmine/network/mcpe/raklib/RakLibPacketSender.php @@ -21,7 +21,9 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe; +namespace pocketmine\network\mcpe\raklib; + +use pocketmine\network\mcpe\PacketSender; class RakLibPacketSender implements PacketSender{ From 61d443bf4eb8ac659b097fb6cbf5aba49a7b2a90 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 26 Jun 2019 19:17:38 +0100 Subject: [PATCH 1004/3224] Living: remove sendPotionEffects() network crap --- src/pocketmine/entity/Living.php | 11 ----------- .../network/mcpe/handler/PreSpawnPacketHandler.php | 4 +++- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index cb24348181..dd034f7044 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -346,17 +346,6 @@ abstract class Living extends Entity implements Damageable{ } } - /** - * Sends the mob's potion effects to the specified player. - * - * @param Player $player - */ - public function sendPotionEffects(Player $player) : void{ - foreach($this->effects as $effect){ - $player->getNetworkSession()->onEntityEffectAdded($this, $effect, false); - } - } - protected function onEffectAdded(EffectInstance $effect, bool $replacesOldEffect) : void{ } diff --git a/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php b/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php index 9effed61e0..6ff83c4928 100644 --- a/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php @@ -86,7 +86,9 @@ class PreSpawnPacketHandler extends PacketHandler{ $this->session->syncAttributes($this->player, true); $this->session->syncAvailableCommands(); $this->session->syncAdventureSettings($this->player); - $this->player->sendPotionEffects($this->player); + foreach($this->player->getEffects() as $effect){ + $this->session->onEntityEffectAdded($this->player, $effect, false); + } $this->player->sendData($this->player); $this->session->getInvManager()->syncAll(); From 7f56f27505d3716c7896d8a2e2bd9df5b05d8cdb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 26 Jun 2019 19:40:40 +0100 Subject: [PATCH 1005/3224] some cleanup to held item handling --- src/pocketmine/inventory/PlayerInventory.php | 38 ++++--------------- .../network/mcpe/InventoryManager.php | 5 +++ .../network/mcpe/NetworkSession.php | 15 ++++++++ .../mcpe/handler/InGamePacketHandler.php | 2 +- .../mcpe/handler/PreSpawnPacketHandler.php | 2 +- .../mcpe/protocol/PlayerHotbarPacket.php | 11 ++++-- 6 files changed, 37 insertions(+), 36 deletions(-) diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index fbc2748d1e..1ec534a29d 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -25,11 +25,7 @@ namespace pocketmine\inventory; use pocketmine\entity\Human; use pocketmine\item\Item; -use pocketmine\network\mcpe\protocol\MobEquipmentPacket; -use pocketmine\network\mcpe\protocol\types\ContainerIds; use pocketmine\player\Player; -use function in_array; -use function is_array; class PlayerInventory extends BaseInventory{ @@ -98,11 +94,12 @@ class PlayerInventory extends BaseInventory{ $this->itemInHandIndex = $hotbarSlot; - if($this->getHolder() instanceof Player and $send){ - $this->sendHeldItem($this->getHolder()); + if($this->holder instanceof Player and $send){ + $this->holder->getNetworkSession()->getInvManager()->syncSelectedHotbarSlot(); + } + foreach($this->holder->getViewers() as $viewer){ + $viewer->getNetworkSession()->onMobEquipmentChange($this->holder); } - - $this->sendHeldItem($this->getHolder()->getViewers()); } /** @@ -121,29 +118,8 @@ class PlayerInventory extends BaseInventory{ */ public function setItemInHand(Item $item) : void{ $this->setItem($this->getHeldItemIndex(), $item); - $this->sendHeldItem($this->holder->getViewers()); - } - - /** - * Sends the currently-held item to specified targets. - * - * @param Player|Player[] $target - */ - public function sendHeldItem($target) : void{ - $item = $this->getItemInHand(); - - $pk = MobEquipmentPacket::create($this->getHolder()->getId(), $item, $this->getHeldItemIndex(), ContainerIds::INVENTORY); - - if(!is_array($target)){ - $target->sendDataPacket($pk); - if($target === $this->getHolder()){ - $target->getNetworkSession()->getInvManager()->syncSlot($this, $this->getHeldItemIndex()); - } - }else{ - $this->getHolder()->getWorld()->getServer()->broadcastPacket($target, $pk); - if(in_array($this->getHolder(), $target, true)){ - $target->getNetworkSession()->getInvManager()->syncSlot($this, $this->getHeldItemIndex()); - } + foreach($this->holder->getViewers() as $viewer){ + $viewer->getNetworkSession()->onMobEquipmentChange($this->holder); } } diff --git a/src/pocketmine/network/mcpe/InventoryManager.php b/src/pocketmine/network/mcpe/InventoryManager.php index da285bb87d..b88e240ed1 100644 --- a/src/pocketmine/network/mcpe/InventoryManager.php +++ b/src/pocketmine/network/mcpe/InventoryManager.php @@ -36,6 +36,7 @@ use pocketmine\network\mcpe\protocol\ContainerOpenPacket; use pocketmine\network\mcpe\protocol\ContainerSetDataPacket; use pocketmine\network\mcpe\protocol\InventoryContentPacket; use pocketmine\network\mcpe\protocol\InventorySlotPacket; +use pocketmine\network\mcpe\protocol\PlayerHotbarPacket; use pocketmine\network\mcpe\protocol\types\ContainerIds; use pocketmine\network\mcpe\protocol\types\WindowTypes; use pocketmine\player\Player; @@ -144,6 +145,10 @@ class InventoryManager{ } } + public function syncSelectedHotbarSlot() : void{ + $this->session->sendDataPacket(PlayerHotbarPacket::create($this->player->getInventory()->getHeldItemIndex(), ContainerIds::INVENTORY)); + } + public function syncCreative() : void{ $items = []; if(!$this->player->isSpectator()){ //fill it for all gamemodes except spectator diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 51be868584..a1aa9819e0 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; use pocketmine\entity\effect\EffectInstance; +use pocketmine\entity\Human; use pocketmine\entity\Living; use pocketmine\event\player\PlayerCreationEvent; use pocketmine\event\server\DataPacketReceiveEvent; @@ -47,6 +48,7 @@ use pocketmine\network\mcpe\protocol\DisconnectPacket; use pocketmine\network\mcpe\protocol\GarbageServerboundPacket; use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket; use pocketmine\network\mcpe\protocol\MobEffectPacket; +use pocketmine\network\mcpe\protocol\MobEquipmentPacket; use pocketmine\network\mcpe\protocol\ModalFormRequestPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\NetworkChunkPublisherUpdatePacket; @@ -62,6 +64,7 @@ use pocketmine\network\mcpe\protocol\TransferPacket; use pocketmine\network\mcpe\protocol\types\CommandData; use pocketmine\network\mcpe\protocol\types\CommandEnum; use pocketmine\network\mcpe\protocol\types\CommandParameter; +use pocketmine\network\mcpe\protocol\types\ContainerIds; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; @@ -776,6 +779,18 @@ class NetworkSession{ return $this->invManager; } + /** + * TODO: expand this to more than just humans + * TODO: offhand + * + * @param Human $mob + */ + public function onMobEquipmentChange(Human $mob) : void{ + //TODO: we could send zero for slot here because remote players don't need to know which slot was selected + $inv = $mob->getInventory(); + $this->sendDataPacket(MobEquipmentPacket::create($mob->getId(), $inv->getItemInHand(), $inv->getHeldItemIndex(), ContainerIds::INVENTORY)); + } + public function onMobArmorChange(Living $mob) : void{ $inv = $mob->getArmorInventory(); $this->sendDataPacket(MobArmorEquipmentPacket::create($mob->getId(), $inv->getHelmet(), $inv->getChestplate(), $inv->getLeggings(), $inv->getBoots())); diff --git a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php index 2edcae7a74..97a8e94800 100644 --- a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php @@ -359,7 +359,7 @@ class InGamePacketHandler extends PacketHandler{ public function handleMobEquipment(MobEquipmentPacket $packet) : bool{ if(!$this->player->selectHotbarSlot($packet->hotbarSlot)){ - $this->player->getInventory()->sendHeldItem($this->player); + $this->session->getInvManager()->syncSelectedHotbarSlot(); } return true; } diff --git a/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php b/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php index 6ff83c4928..9aa3ac0a5e 100644 --- a/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php @@ -93,7 +93,7 @@ class PreSpawnPacketHandler extends PacketHandler{ $this->session->getInvManager()->syncAll(); $this->session->getInvManager()->syncCreative(); - $this->player->getInventory()->sendHeldItem($this->player); + $this->session->getInvManager()->syncSelectedHotbarSlot(); $this->session->queueCompressed($this->server->getCraftingManager()->getCraftingDataPacket()); $this->session->syncPlayerList(); diff --git a/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php index 9cf8dc2f0c..02a98a81ef 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php @@ -28,9 +28,6 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\ContainerIds; -/** - * One of the most useless packets. - */ class PlayerHotbarPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAYER_HOTBAR_PACKET; @@ -41,6 +38,14 @@ class PlayerHotbarPacket extends DataPacket implements ClientboundPacket, Server /** @var bool */ public $selectHotbarSlot = true; + public static function create(int $slot, int $windowId, bool $selectSlot = true) : self{ + $result = new self; + $result->selectedHotbarSlot = $slot; + $result->windowId = $windowId; + $result->selectHotbarSlot = $selectSlot; + return $result; + } + protected function decodePayload() : void{ $this->selectedHotbarSlot = $this->getUnsignedVarInt(); $this->windowId = $this->getByte(); From 2ba76bd97da84b0363bd6f56981e1117fb95fb04 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Jun 2019 13:41:58 +0100 Subject: [PATCH 1006/3224] Convert UPnP into network interface closes #2710, closes #2751 --- src/pocketmine/Server.php | 8 +--- src/pocketmine/network/upnp/UPnP.php | 70 +++++++++++++++------------- 2 files changed, 38 insertions(+), 40 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 9299bff8da..cdbbcc0af8 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1268,9 +1268,8 @@ class Server{ } if($this->getProperty("network.upnp-forwarding", false)){ - $this->logger->info("[UPnP] Trying to port forward..."); try{ - UPnP::PortForward($this->getPort()); + $this->network->registerInterface(new UPnP($this->logger, Internet::getInternalIP(), $this->getPort())); }catch(\RuntimeException $e){ $this->logger->alert("UPnP portforward failed: " . $e->getMessage()); } @@ -1584,11 +1583,6 @@ class Server{ $this->shutdown(); - if($this->getProperty("network.upnp-forwarding", false)){ - $this->logger->info("[UPnP] Removing port forward..."); - UPnP::RemovePortForward($this->getPort()); - } - if($this->pluginManager instanceof PluginManager){ $this->getLogger()->debug("Disabling all plugins"); $this->pluginManager->disablePlugins(); diff --git a/src/pocketmine/network/upnp/UPnP.php b/src/pocketmine/network/upnp/UPnP.php index 29c09b4f89..56702f882b 100644 --- a/src/pocketmine/network/upnp/UPnP.php +++ b/src/pocketmine/network/upnp/UPnP.php @@ -26,19 +26,25 @@ declare(strict_types=1); */ namespace pocketmine\network\upnp; +use pocketmine\network\NetworkInterface; use pocketmine\utils\Internet; use pocketmine\utils\Utils; use function class_exists; use function is_object; -abstract class UPnP{ +class UPnP implements NetworkInterface{ - /** - * @param int $port - * - * @throws \RuntimeException - */ - public static function PortForward(int $port) : void{ + /** @var string */ + private $ip; + /** @var int */ + private $port; + + /** @var object|null */ + private $staticPortMappingCollection = null; + /** @var \Logger */ + private $logger; + + public function __construct(\Logger $logger, string $ip, int $port){ if(!Internet::$online){ throw new \RuntimeException("Server is offline"); } @@ -48,48 +54,46 @@ abstract class UPnP{ if(!class_exists("COM")){ throw new \RuntimeException("UPnP requires the com_dotnet extension"); } + $this->ip = $ip; + $this->port = $port; + $this->logger = new \PrefixedLogger($logger, "UPnP Port Forwarder"); + } - $myLocalIP = Internet::getInternalIP(); - + public function start() : void{ /** @noinspection PhpUndefinedClassInspection */ $com = new \COM("HNetCfg.NATUPnP"); /** @noinspection PhpUndefinedFieldInspection */ if($com === false or !is_object($com->StaticPortMappingCollection)){ - throw new \RuntimeException("Failed to portforward using UPnP. Ensure that network discovery is enabled in Control Panel."); + throw new \RuntimeException("UPnP unsupported or network discovery is not enabled"); } + /** @noinspection PhpUndefinedFieldInspection */ + $this->staticPortMappingCollection = $com->StaticPortMappingCollection; try{ - /** @noinspection PhpUndefinedFieldInspection */ - $com->StaticPortMappingCollection->Add($port, "UDP", $port, $myLocalIP, true, "PocketMine-MP"); + $this->staticPortMappingCollection->Add($this->port, "UDP", $this->port, $this->ip, true, "PocketMine-MP"); }catch(\com_exception $e){ throw new \RuntimeException($e->getMessage(), 0, $e); } + $this->logger->info("Forwarded $this->ip:$this->port to external port $this->port"); } - public static function RemovePortForward(int $port) : bool{ - if(!Internet::$online){ - return false; - } - if(Utils::getOS() != "win" or !class_exists("COM")){ - return false; - } + public function setName(string $name) : void{ - /** @noinspection PhpUndefinedClassInspection */ - $com = new \COM("HNetCfg.NATUPnP"); - /** @noinspection PhpUndefinedFieldInspection */ - if($com === false or !is_object($com->StaticPortMappingCollection)){ - return false; - } + } - try{ - /** @noinspection PhpUndefinedFieldInspection */ - $com->StaticPortMappingCollection->Remove($port, "UDP"); - }catch(\com_exception $e){ - //TODO: should this really be silenced? - return false; - } + public function tick() : void{ - return true; + } + + public function shutdown() : void{ + if($this->staticPortMappingCollection !== null){ + try{ + /** @noinspection PhpUndefinedFieldInspection */ + $this->staticPortMappingCollection->Remove($this->port, "UDP"); + }catch(\com_exception $e){ + //TODO: should this really be silenced? + } + } } } From f3882dd65829dcd8c44bb39fbc285de8f2daa32e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Jun 2019 14:23:24 +0100 Subject: [PATCH 1007/3224] Entity: remove more useless classes these were slated for removal some time ago, but it never happened because they were used in the API. This is no longer the case on 4.0, so these classes are now entirely useless. --- src/pocketmine/entity/Animal.php | 2 +- src/pocketmine/entity/Creature.php | 29 --------------------------- src/pocketmine/entity/Damageable.php | 29 --------------------------- src/pocketmine/entity/Human.php | 2 +- src/pocketmine/entity/Living.php | 2 +- src/pocketmine/entity/Monster.php | 29 --------------------------- src/pocketmine/entity/NPC.php | 29 --------------------------- src/pocketmine/entity/Rideable.php | 29 --------------------------- src/pocketmine/entity/Vehicle.php | 29 --------------------------- src/pocketmine/entity/Villager.php | 2 +- src/pocketmine/entity/WaterAnimal.php | 2 +- src/pocketmine/entity/Zombie.php | 2 +- 12 files changed, 6 insertions(+), 180 deletions(-) delete mode 100644 src/pocketmine/entity/Creature.php delete mode 100644 src/pocketmine/entity/Damageable.php delete mode 100644 src/pocketmine/entity/Monster.php delete mode 100644 src/pocketmine/entity/NPC.php delete mode 100644 src/pocketmine/entity/Rideable.php delete mode 100644 src/pocketmine/entity/Vehicle.php diff --git a/src/pocketmine/entity/Animal.php b/src/pocketmine/entity/Animal.php index d651057e82..3d5b26384d 100644 --- a/src/pocketmine/entity/Animal.php +++ b/src/pocketmine/entity/Animal.php @@ -26,7 +26,7 @@ namespace pocketmine\entity; use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; -abstract class Animal extends Creature implements Ageable{ +abstract class Animal extends Living implements Ageable{ public function isBaby() : bool{ return $this->getGenericFlag(EntityMetadataFlags::BABY); diff --git a/src/pocketmine/entity/Creature.php b/src/pocketmine/entity/Creature.php deleted file mode 100644 index fbbd7dbf4c..0000000000 --- a/src/pocketmine/entity/Creature.php +++ /dev/null @@ -1,29 +0,0 @@ -getGenericFlag(EntityMetadataFlags::BABY); diff --git a/src/pocketmine/entity/Zombie.php b/src/pocketmine/entity/Zombie.php index 464892a343..1a0078d3f1 100644 --- a/src/pocketmine/entity/Zombie.php +++ b/src/pocketmine/entity/Zombie.php @@ -27,7 +27,7 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use function mt_rand; -class Zombie extends Monster{ +class Zombie extends Living{ public const NETWORK_ID = self::ZOMBIE; public $width = 0.6; From 6838a1e07a06c0e94d88beed44d0a75c4abae6ed Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Jun 2019 15:16:06 +0100 Subject: [PATCH 1008/3224] BossEventPacket: fix crash in ::unknown6() --- src/pocketmine/network/mcpe/protocol/BossEventPacket.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pocketmine/network/mcpe/protocol/BossEventPacket.php b/src/pocketmine/network/mcpe/protocol/BossEventPacket.php index dcd33587b5..01e9c2f735 100644 --- a/src/pocketmine/network/mcpe/protocol/BossEventPacket.php +++ b/src/pocketmine/network/mcpe/protocol/BossEventPacket.php @@ -114,6 +114,8 @@ class BossEventPacket extends DataPacket implements ClientboundPacket, Serverbou public static function unknown6(int $bossEntityUniqueId, int $unknownShort) : self{ $result = self::base($bossEntityUniqueId, self::TYPE_UNKNOWN_6); $result->unknownShort = $unknownShort; + $result->color = 0; //hardcoded due to being useless + $result->overlay = 0; return $result; } From a279648c68fef73ae9b89ec805fdd749e9515aac Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Jun 2019 15:42:10 +0100 Subject: [PATCH 1009/3224] FastChunkSerializer: optimize palette writing --- .../world/format/io/FastChunkSerializer.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/pocketmine/world/format/io/FastChunkSerializer.php b/src/pocketmine/world/format/io/FastChunkSerializer.php index 0620cc40cd..670d26afc4 100644 --- a/src/pocketmine/world/format/io/FastChunkSerializer.php +++ b/src/pocketmine/world/format/io/FastChunkSerializer.php @@ -31,6 +31,7 @@ use pocketmine\world\format\SubChunk; use function array_values; use function count; use function pack; +use function strlen; use function unpack; /** @@ -75,10 +76,9 @@ final class FastChunkSerializer{ $subStream->putByte($blocks->getBitsPerBlock()); $subStream->put($wordArray); - $subStream->putInt(count($palette)); - foreach($palette as $p){ - $subStream->putInt($p); - } + $serialPalette = pack("N*", ...$palette); + $subStream->putInt(strlen($serialPalette)); + $subStream->put($serialPalette); } if($chunk->isLightPopulated()){ @@ -129,10 +129,7 @@ final class FastChunkSerializer{ for($i = 0, $layerCount = $stream->getByte(); $i < $layerCount; ++$i){ $bitsPerBlock = $stream->getByte(); $words = $stream->get(PalettedBlockArray::getExpectedWordArraySize($bitsPerBlock)); - $palette = []; - for($k = 0, $paletteSize = $stream->getInt(); $k < $paletteSize; ++$k){ - $palette[] = $stream->getInt(); - } + $palette = array_values(unpack("N*", $stream->get($stream->getInt()))); $layers[] = PalettedBlockArray::fromData($bitsPerBlock, $words, $palette); } From 6f087190f4655cacfb19c75dfdf554fed6b80767 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Jun 2019 16:13:14 +0100 Subject: [PATCH 1010/3224] SimpleChunkManager: added $create parameter --- src/pocketmine/world/ChunkManager.php | 7 ++++--- src/pocketmine/world/SimpleChunkManager.php | 10 ++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/world/ChunkManager.php b/src/pocketmine/world/ChunkManager.php index b0153b3d21..7fb8524c6f 100644 --- a/src/pocketmine/world/ChunkManager.php +++ b/src/pocketmine/world/ChunkManager.php @@ -94,12 +94,13 @@ interface ChunkManager{ public function setBlockSkyLightAt(int $x, int $y, int $z, int $level) : void; /** - * @param int $chunkX - * @param int $chunkZ + * @param int $chunkX + * @param int $chunkZ + * @param bool $create * * @return Chunk|null */ - public function getChunk(int $chunkX, int $chunkZ) : ?Chunk; + public function getChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk; /** * @param int $chunkX diff --git a/src/pocketmine/world/SimpleChunkManager.php b/src/pocketmine/world/SimpleChunkManager.php index d9297ebac8..f2cee8527a 100644 --- a/src/pocketmine/world/SimpleChunkManager.php +++ b/src/pocketmine/world/SimpleChunkManager.php @@ -90,13 +90,15 @@ class SimpleChunkManager implements ChunkManager{ } /** - * @param int $chunkX - * @param int $chunkZ + * @param int $chunkX + * @param int $chunkZ + * @param bool $create * * @return Chunk|null */ - public function getChunk(int $chunkX, int $chunkZ) : ?Chunk{ - return $this->chunks[World::chunkHash($chunkX, $chunkZ)] ?? null; + public function getChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk{ + $hash = World::chunkHash($chunkX, $chunkZ); + return $this->chunks[$hash] ?? ($create ? $this->chunks[$hash] = new Chunk($chunkX, $chunkZ) : null); } /** From 45f5f112dd32711177f414f2944da360524b8ff7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Jun 2019 16:22:56 +0100 Subject: [PATCH 1011/3224] SubChunkIteratorManager now accepts $create as a moveTo() parameter instead of in the constructor --- src/pocketmine/world/Explosion.php | 4 ++-- src/pocketmine/world/light/LightUpdate.php | 8 ++++---- .../world/utils/SubChunkIteratorManager.php | 11 ++++------- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/pocketmine/world/Explosion.php b/src/pocketmine/world/Explosion.php index a7d19bdb16..71b20e981b 100644 --- a/src/pocketmine/world/Explosion.php +++ b/src/pocketmine/world/Explosion.php @@ -83,7 +83,7 @@ class Explosion{ $this->size = $size; $this->what = $what; - $this->subChunkHandler = new SubChunkIteratorManager($this->world, false); + $this->subChunkHandler = new SubChunkIteratorManager($this->world); } /** @@ -119,7 +119,7 @@ class Explosion{ $vBlock->y = $pointerY >= $y ? $y : $y - 1; $vBlock->z = $pointerZ >= $z ? $z : $z - 1; - if(!$this->subChunkHandler->moveTo($vBlock->x, $vBlock->y, $vBlock->z)){ + if(!$this->subChunkHandler->moveTo($vBlock->x, $vBlock->y, $vBlock->z, false)){ continue; } diff --git a/src/pocketmine/world/light/LightUpdate.php b/src/pocketmine/world/light/LightUpdate.php index fe0d153ae2..cf36908ac6 100644 --- a/src/pocketmine/world/light/LightUpdate.php +++ b/src/pocketmine/world/light/LightUpdate.php @@ -67,7 +67,7 @@ abstract class LightUpdate{ private function prepareNodes() : void{ foreach($this->updateNodes as $blockHash => [$x, $y, $z, $newLevel]){ - if($this->subChunkHandler->moveTo($x, $y, $z)){ + if($this->subChunkHandler->moveTo($x, $y, $z, false)){ $oldLevel = $this->getLight($x, $y, $z); if($oldLevel !== $newLevel){ @@ -100,7 +100,7 @@ abstract class LightUpdate{ ]; foreach($points as list($cx, $cy, $cz)){ - if($this->subChunkHandler->moveTo($cx, $cy, $cz)){ + if($this->subChunkHandler->moveTo($cx, $cy, $cz, true)){ $this->computeRemoveLight($cx, $cy, $cz, $oldAdjacentLight); } } @@ -111,7 +111,7 @@ abstract class LightUpdate{ unset($this->spreadVisited[World::blockHash($x, $y, $z)]); - if(!$this->subChunkHandler->moveTo($x, $y, $z)){ + if(!$this->subChunkHandler->moveTo($x, $y, $z, false)){ continue; } @@ -130,7 +130,7 @@ abstract class LightUpdate{ ]; foreach($points as list($cx, $cy, $cz)){ - if($this->subChunkHandler->moveTo($cx, $cy, $cz)){ + if($this->subChunkHandler->moveTo($cx, $cy, $cz, true)){ $this->computeSpreadLight($cx, $cy, $cz, $newAdjacentLight); } } diff --git a/src/pocketmine/world/utils/SubChunkIteratorManager.php b/src/pocketmine/world/utils/SubChunkIteratorManager.php index ef1e6cdee1..55e8bbf7d0 100644 --- a/src/pocketmine/world/utils/SubChunkIteratorManager.php +++ b/src/pocketmine/world/utils/SubChunkIteratorManager.php @@ -43,21 +43,18 @@ class SubChunkIteratorManager{ protected $currentY; /** @var int */ protected $currentZ; - /** @var bool */ - protected $allocateEmptySubs = true; - public function __construct(ChunkManager $world, bool $allocateEmptySubs = true){ + public function __construct(ChunkManager $world){ $this->world = $world; - $this->allocateEmptySubs = $allocateEmptySubs; } - public function moveTo(int $x, int $y, int $z) : bool{ + public function moveTo(int $x, int $y, int $z, bool $create) : bool{ if($this->currentChunk === null or $this->currentX !== ($x >> 4) or $this->currentZ !== ($z >> 4)){ $this->currentX = $x >> 4; $this->currentZ = $z >> 4; $this->currentSubChunk = null; - $this->currentChunk = $this->world->getChunk($this->currentX, $this->currentZ); + $this->currentChunk = $this->world->getChunk($this->currentX, $this->currentZ, $create); if($this->currentChunk === null){ return false; } @@ -66,7 +63,7 @@ class SubChunkIteratorManager{ if($this->currentSubChunk === null or $this->currentY !== ($y >> 4)){ $this->currentY = $y >> 4; - $this->currentSubChunk = $this->currentChunk->getSubChunk($y >> 4, $this->allocateEmptySubs); + $this->currentSubChunk = $this->currentChunk->getSubChunk($y >> 4, $create); if($this->currentSubChunk instanceof EmptySubChunk){ return false; } From 6da2bd4bb388651c807d77815a0db53384a3d9aa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Jun 2019 16:53:24 +0100 Subject: [PATCH 1012/3224] SimpleChunkManager: implement last-access performance optimization this improves performance of writing blocks by ~30%. --- src/pocketmine/world/SimpleChunkManager.php | 29 ++++++++++++--------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/pocketmine/world/SimpleChunkManager.php b/src/pocketmine/world/SimpleChunkManager.php index f2cee8527a..6705b0fe5b 100644 --- a/src/pocketmine/world/SimpleChunkManager.php +++ b/src/pocketmine/world/SimpleChunkManager.php @@ -27,6 +27,7 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\world\format\Chunk; +use pocketmine\world\utils\SubChunkIteratorManager; use const INT32_MAX; use const INT32_MIN; @@ -37,6 +38,9 @@ class SimpleChunkManager implements ChunkManager{ protected $worldHeight; + /** @var SubChunkIteratorManager */ + protected $terrainPointer; + /** * SimpleChunkManager constructor. * @@ -44,48 +48,49 @@ class SimpleChunkManager implements ChunkManager{ */ public function __construct(int $worldHeight = World::Y_MAX){ $this->worldHeight = $worldHeight; + $this->terrainPointer = new SubChunkIteratorManager($this); } public function getBlockAt(int $x, int $y, int $z) : Block{ - if($chunk = $this->getChunk($x >> 4, $z >> 4)){ - return BlockFactory::fromFullBlock($chunk->getFullBlock($x & 0xf, $y, $z & 0xf)); + if($this->terrainPointer->moveTo($x, $y, $z, false)){ + return BlockFactory::fromFullBlock($this->terrainPointer->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf)); } return BlockFactory::get(BlockLegacyIds::AIR); } public function setBlockAt(int $x, int $y, int $z, Block $block) : bool{ - if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ - $chunk->setFullBlock($x & 0xf, $y, $z & 0xf, $block->getFullId()); + if($this->terrainPointer->moveTo($x, $y, $z, false)){ + $this->terrainPointer->currentSubChunk->setFullBlock($x & 0xf, $y & 0xf, $z & 0xf, $block->getFullId()); return true; } return false; } public function getBlockLightAt(int $x, int $y, int $z) : int{ - if($chunk = $this->getChunk($x >> 4, $z >> 4)){ - return $chunk->getBlockLight($x & 0xf, $y, $z & 0xf); + if($this->terrainPointer->moveTo($x, $y, $z, false)){ + return $this->terrainPointer->currentSubChunk->getBlockLight($x & 0xf, $y & 0xf, $z & 0xf); } return 0; } public function setBlockLightAt(int $x, int $y, int $z, int $level) : void{ - if($chunk = $this->getChunk($x >> 4, $z >> 4)){ - $chunk->setBlockLight($x & 0xf, $y, $z & 0xf, $level); + if($this->terrainPointer->moveTo($x, $y, $z, false)){ + $this->terrainPointer->currentSubChunk->setBlockLight($x & 0xf, $y & 0xf, $z & 0xf, $level); } } public function getBlockSkyLightAt(int $x, int $y, int $z) : int{ - if($chunk = $this->getChunk($x >> 4, $z >> 4)){ - return $chunk->getBlockSkyLight($x & 0xf, $y, $z & 0xf); + if($this->terrainPointer->moveTo($x, $y, $z, false)){ + return $this->terrainPointer->currentSubChunk->getBlockSkyLight($x & 0xf, $y & 0xf, $z & 0xf); } return 0; } public function setBlockSkyLightAt(int $x, int $y, int $z, int $level) : void{ - if($chunk = $this->getChunk($x >> 4, $z >> 4)){ - $chunk->setBlockSkyLight($x & 0xf, $y, $z & 0xf, $level); + if($this->terrainPointer->moveTo($x, $y, $z, false)){ + $this->terrainPointer->currentSubChunk->setBlockSkyLight($x & 0xf, $y & 0xf, $z & 0xf, $level); } } From 1749b57a83db1b4aeea91aac86b7d4f47c83b4fd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Jun 2019 16:56:46 +0100 Subject: [PATCH 1013/3224] ChunkManager: drop light-related methods these were added in 2017 with the intent of async'ifying light updates. However, light updates now use an optimized code path which bypasses these functions completely, rendering them useless. --- src/pocketmine/world/ChunkManager.php | 42 --------------------- src/pocketmine/world/SimpleChunkManager.php | 28 -------------- 2 files changed, 70 deletions(-) diff --git a/src/pocketmine/world/ChunkManager.php b/src/pocketmine/world/ChunkManager.php index 7fb8524c6f..129cee286f 100644 --- a/src/pocketmine/world/ChunkManager.php +++ b/src/pocketmine/world/ChunkManager.php @@ -51,48 +51,6 @@ interface ChunkManager{ */ public function setBlockAt(int $x, int $y, int $z, Block $block) : bool; - /** - * Returns the raw block light level - * - * @param int $x - * @param int $y - * @param int $z - * - * @return int - */ - public function getBlockLightAt(int $x, int $y, int $z) : int; - - /** - * Sets the raw block light level - * - * @param int $x - * @param int $y - * @param int $z - * @param int $level - */ - public function setBlockLightAt(int $x, int $y, int $z, int $level) : void; - - /** - * Returns the highest amount of sky light can reach the specified coordinates. - * - * @param int $x - * @param int $y - * @param int $z - * - * @return int - */ - public function getBlockSkyLightAt(int $x, int $y, int $z) : int; - - /** - * Sets the raw block sky light level. - * - * @param int $x - * @param int $y - * @param int $z - * @param int $level - */ - public function setBlockSkyLightAt(int $x, int $y, int $z, int $level) : void; - /** * @param int $chunkX * @param int $chunkZ diff --git a/src/pocketmine/world/SimpleChunkManager.php b/src/pocketmine/world/SimpleChunkManager.php index 6705b0fe5b..67d06a8d8e 100644 --- a/src/pocketmine/world/SimpleChunkManager.php +++ b/src/pocketmine/world/SimpleChunkManager.php @@ -66,34 +66,6 @@ class SimpleChunkManager implements ChunkManager{ return false; } - public function getBlockLightAt(int $x, int $y, int $z) : int{ - if($this->terrainPointer->moveTo($x, $y, $z, false)){ - return $this->terrainPointer->currentSubChunk->getBlockLight($x & 0xf, $y & 0xf, $z & 0xf); - } - - return 0; - } - - public function setBlockLightAt(int $x, int $y, int $z, int $level) : void{ - if($this->terrainPointer->moveTo($x, $y, $z, false)){ - $this->terrainPointer->currentSubChunk->setBlockLight($x & 0xf, $y & 0xf, $z & 0xf, $level); - } - } - - public function getBlockSkyLightAt(int $x, int $y, int $z) : int{ - if($this->terrainPointer->moveTo($x, $y, $z, false)){ - return $this->terrainPointer->currentSubChunk->getBlockSkyLight($x & 0xf, $y & 0xf, $z & 0xf); - } - - return 0; - } - - public function setBlockSkyLightAt(int $x, int $y, int $z, int $level) : void{ - if($this->terrainPointer->moveTo($x, $y, $z, false)){ - $this->terrainPointer->currentSubChunk->setBlockSkyLight($x & 0xf, $y & 0xf, $z & 0xf, $level); - } - } - /** * @param int $chunkX * @param int $chunkZ From 193a41566db18bc1e270b19fb92b1f3589e55e29 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Jun 2019 17:04:36 +0100 Subject: [PATCH 1014/3224] NetworkSession: Show the correct name on the player list --- src/pocketmine/network/mcpe/NetworkSession.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index a1aa9819e0..84e8ae2b47 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -803,7 +803,7 @@ class NetworkSession{ } public function onPlayerAdded(Player $p) : void{ - $this->sendDataPacket(PlayerListPacket::add([PlayerListEntry::createAdditionEntry($p->getUniqueId(), $p->getId(), $p->getName(), $p->getSkin(), $p->getXuid())])); + $this->sendDataPacket(PlayerListPacket::add([PlayerListEntry::createAdditionEntry($p->getUniqueId(), $p->getId(), $p->getDisplayName(), $p->getSkin(), $p->getXuid())])); } public function onPlayerRemoved(Player $p) : void{ From 0e4966dfdf4f2e9e9f03ac78dc0d9a44b3c77c42 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Jun 2019 18:09:43 +0100 Subject: [PATCH 1015/3224] Split ProcessLoginTask into two tasks: 1) verify, 2) server handshake --- .../network/mcpe/NetworkSession.php | 21 +++- .../network/mcpe/PrepareEncryptionTask.php | 111 ++++++++++++++++++ .../network/mcpe/ProcessLoginTask.php | 92 +-------------- .../mcpe/handler/LoginPacketHandler.php | 3 +- 4 files changed, 135 insertions(+), 92 deletions(-) create mode 100644 src/pocketmine/network/mcpe/PrepareEncryptionTask.php diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 84e8ae2b47..d84336379c 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; +use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\Human; use pocketmine\entity\Living; @@ -522,7 +523,10 @@ class NetworkSession{ }, $reason); } - public function setAuthenticationStatus(bool $authenticated, bool $authRequired, ?string $error) : bool{ + public function setAuthenticationStatus(bool $authenticated, bool $authRequired, ?string $error, PublicKeyInterface $clientPubKey) : void{ + if(!$this->connected){ + return; + } if($authenticated and $this->info->getXuid() === ""){ $error = "Expected XUID but none found"; } @@ -530,7 +534,7 @@ class NetworkSession{ if($error !== null){ $this->disconnect($this->server->getLanguage()->translateString("pocketmine.disconnect.invalidSession", [$error])); - return false; + return; } $this->authenticated = $authenticated; @@ -538,7 +542,7 @@ class NetworkSession{ if(!$this->authenticated){ if($authRequired){ $this->disconnect("disconnectionScreen.notAuthenticated"); - return false; + return; } if($this->info->getXuid() !== ""){ @@ -547,10 +551,19 @@ class NetworkSession{ } $this->logger->debug("Xbox Live authenticated: " . ($this->authenticated ? "YES" : "NO")); - return $this->manager->kickDuplicates($this); + if($this->manager->kickDuplicates($this)){ + if(NetworkCipher::$ENABLED){ + $this->server->getAsyncPool()->submitTask(new PrepareEncryptionTask($this, $clientPubKey)); + }else{ + $this->onLoginSuccess(); + } + } } public function enableEncryption(string $encryptionKey, string $handshakeJwt) : void{ + if(!$this->connected){ + return; + } $this->sendDataPacket(ServerToClientHandshakePacket::create($handshakeJwt), true); //make sure this gets sent before encryption is enabled $this->cipher = new NetworkCipher($encryptionKey); diff --git a/src/pocketmine/network/mcpe/PrepareEncryptionTask.php b/src/pocketmine/network/mcpe/PrepareEncryptionTask.php new file mode 100644 index 0000000000..f67794ed7a --- /dev/null +++ b/src/pocketmine/network/mcpe/PrepareEncryptionTask.php @@ -0,0 +1,111 @@ +generator384()->createPrivateKey(); + } + + $this->serverPrivateKey = self::$SERVER_PRIVATE_KEY; + $this->clientPub = $clientPub; + $this->storeLocal(self::TLS_KEY_SESSION, $session); + } + + public function onRun() : void{ + $serverPriv = $this->serverPrivateKey; + $salt = random_bytes(16); + $sharedSecret = $serverPriv->createExchange($this->clientPub)->calculateSharedKey(); + + $this->aesKey = openssl_digest($salt . hex2bin(str_pad(gmp_strval($sharedSecret, 16), 96, "0", STR_PAD_LEFT)), 'sha256', true); + $this->handshakeJwt = $this->generateServerHandshakeJwt($serverPriv, $salt); + } + + private function generateServerHandshakeJwt(PrivateKeyInterface $serverPriv, string $salt) : string{ + $jwtBody = self::b64UrlEncode(json_encode([ + "x5u" => base64_encode((new DerPublicKeySerializer())->serialize($serverPriv->getPublicKey())), + "alg" => "ES384" + ]) + ) . "." . self::b64UrlEncode(json_encode([ + "salt" => base64_encode($salt) + ]) + ); + + openssl_sign($jwtBody, $sig, (new PemPrivateKeySerializer(new DerPrivateKeySerializer()))->serialize($serverPriv), OPENSSL_ALGO_SHA384); + + $decodedSig = (new DerSignatureSerializer())->parse($sig); + $jwtSig = self::b64UrlEncode( + hex2bin(str_pad(gmp_strval($decodedSig->getR(), 16), 96, "0", STR_PAD_LEFT)) . + hex2bin(str_pad(gmp_strval($decodedSig->getS(), 16), 96, "0", STR_PAD_LEFT)) + ); + + return "$jwtBody.$jwtSig"; + } + + private static function b64UrlEncode(string $str) : string{ + return rtrim(strtr(base64_encode($str), '+/', '-_'), '='); + } + + public function onCompletion() : void{ + /** @var NetworkSession $session */ + $session = $this->fetchLocal(self::TLS_KEY_SESSION); + $session->enableEncryption($this->aesKey, $this->handshakeJwt); + } +} diff --git a/src/pocketmine/network/mcpe/ProcessLoginTask.php b/src/pocketmine/network/mcpe/ProcessLoginTask.php index 909b5f5222..8dbe3e3147 100644 --- a/src/pocketmine/network/mcpe/ProcessLoginTask.php +++ b/src/pocketmine/network/mcpe/ProcessLoginTask.php @@ -23,12 +23,8 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; -use Mdanter\Ecc\Crypto\Key\PrivateKeyInterface; use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; use Mdanter\Ecc\Crypto\Signature\Signature; -use Mdanter\Ecc\EccFactory; -use Mdanter\Ecc\Serializer\PrivateKey\DerPrivateKeySerializer; -use Mdanter\Ecc\Serializer\PrivateKey\PemPrivateKeySerializer; use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; use Mdanter\Ecc\Serializer\PublicKey\PemPublicKeySerializer; use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer; @@ -36,26 +32,16 @@ use pocketmine\network\mcpe\protocol\LoginPacket; use pocketmine\scheduler\AsyncTask; use function assert; use function base64_decode; -use function base64_encode; use function bin2hex; use function explode; use function gmp_init; -use function gmp_strval; -use function hex2bin; use function json_decode; -use function json_encode; -use function openssl_digest; -use function openssl_sign; use function openssl_verify; -use function random_bytes; -use function rtrim; -use function str_pad; use function str_repeat; use function str_split; use function strlen; use function time; use const OPENSSL_ALGO_SHA384; -use const STR_PAD_LEFT; class ProcessLoginTask extends AsyncTask{ private const TLS_KEY_SESSION = "session"; @@ -64,9 +50,6 @@ class ProcessLoginTask extends AsyncTask{ private const CLOCK_DRIFT_MAX = 60; - /** @var PrivateKeyInterface|null */ - private static $SERVER_PRIVATE_KEY = null; - /** @var LoginPacket */ private $packet; @@ -86,52 +69,22 @@ class ProcessLoginTask extends AsyncTask{ /** @var bool */ private $authRequired; - /** - * @var bool - * Whether or not to enable encryption for the session that sent this login. - */ - private $useEncryption = true; + /** @var PublicKeyInterface|null */ + private $clientPublicKey = null; - /** @var PrivateKeyInterface|null */ - private $serverPrivateKey = null; - - /** @var string|null */ - private $aesKey = null; - /** @var string|null */ - private $handshakeJwt = null; - - public function __construct(NetworkSession $session, LoginPacket $packet, bool $authRequired, bool $useEncryption = true){ + public function __construct(NetworkSession $session, LoginPacket $packet, bool $authRequired){ $this->storeLocal(self::TLS_KEY_SESSION, $session); $this->packet = $packet; $this->authRequired = $authRequired; - $this->useEncryption = $useEncryption; - if($useEncryption){ - if(self::$SERVER_PRIVATE_KEY === null){ - self::$SERVER_PRIVATE_KEY = EccFactory::getNistCurves()->generator384()->createPrivateKey(); - } - - $this->serverPrivateKey = self::$SERVER_PRIVATE_KEY; - } } public function onRun() : void{ try{ - $clientPub = $this->validateChain(); + $this->clientPublicKey = $this->validateChain(); + $this->error = null; }catch(VerifyLoginException $e){ $this->error = $e->getMessage(); - return; } - - if($this->useEncryption){ - $serverPriv = $this->serverPrivateKey; - $salt = random_bytes(16); - $sharedSecret = $serverPriv->createExchange($clientPub)->calculateSharedKey(); - - $this->aesKey = openssl_digest($salt . hex2bin(str_pad(gmp_strval($sharedSecret, 16), 96, "0", STR_PAD_LEFT)), 'sha256', true); - $this->handshakeJwt = $this->generateServerHandshakeJwt($serverPriv, $salt); - } - - $this->error = null; } private function validateChain() : PublicKeyInterface{ @@ -210,27 +163,6 @@ class ProcessLoginTask extends AsyncTask{ $currentPublicKey = $claims["identityPublicKey"] ?? null; //if there are further links, the next link should be signed with this } - private function generateServerHandshakeJwt(PrivateKeyInterface $serverPriv, string $salt) : string{ - $jwtBody = self::b64UrlEncode(json_encode([ - "x5u" => base64_encode((new DerPublicKeySerializer())->serialize($serverPriv->getPublicKey())), - "alg" => "ES384" - ]) - ) . "." . self::b64UrlEncode(json_encode([ - "salt" => base64_encode($salt) - ]) - ); - - openssl_sign($jwtBody, $sig, (new PemPrivateKeySerializer(new DerPrivateKeySerializer()))->serialize($serverPriv), OPENSSL_ALGO_SHA384); - - $decodedSig = (new DerSignatureSerializer())->parse($sig); - $jwtSig = self::b64UrlEncode( - hex2bin(str_pad(gmp_strval($decodedSig->getR(), 16), 96, "0", STR_PAD_LEFT)) . - hex2bin(str_pad(gmp_strval($decodedSig->getS(), 16), 96, "0", STR_PAD_LEFT)) - ); - - return "$jwtBody.$jwtSig"; - } - private static function b64UrlDecode(string $str) : string{ if(($len = strlen($str) % 4) !== 0){ $str .= str_repeat('=', 4 - $len); @@ -238,21 +170,9 @@ class ProcessLoginTask extends AsyncTask{ return base64_decode(strtr($str, '-_', '+/'), true); } - private static function b64UrlEncode(string $str) : string{ - return rtrim(strtr(base64_encode($str), '+/', '-_'), '='); - } - public function onCompletion() : void{ /** @var NetworkSession $session */ $session = $this->fetchLocal(self::TLS_KEY_SESSION); - if(!$session->isConnected()){ - $session->getLogger()->debug("Disconnected before login could be verified"); - }elseif($session->setAuthenticationStatus($this->authenticated, $this->authRequired, $this->error)){ - if(!$this->useEncryption){ - $session->onLoginSuccess(); - }else{ - $session->enableEncryption($this->aesKey, $this->handshakeJwt); - } - } + $session->setAuthenticationStatus($this->authenticated, $this->authRequired, $this->error, $this->clientPublicKey); } } diff --git a/src/pocketmine/network/mcpe/handler/LoginPacketHandler.php b/src/pocketmine/network/mcpe/handler/LoginPacketHandler.php index 76bd38f467..d34db5126e 100644 --- a/src/pocketmine/network/mcpe/handler/LoginPacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/LoginPacketHandler.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\handler; use pocketmine\entity\Skin; use pocketmine\event\player\PlayerPreLoginEvent; -use pocketmine\network\mcpe\NetworkCipher; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\ProcessLoginTask; use pocketmine\network\mcpe\protocol\LoginPacket; @@ -133,7 +132,7 @@ class LoginPacketHandler extends PacketHandler{ * @throws \InvalidArgumentException */ protected function processLogin(LoginPacket $packet, bool $authRequired) : void{ - $this->server->getAsyncPool()->submitTask(new ProcessLoginTask($this->session, $packet, $authRequired, NetworkCipher::$ENABLED)); + $this->server->getAsyncPool()->submitTask(new ProcessLoginTask($this->session, $packet, $authRequired)); $this->session->setHandler(NullPacketHandler::getInstance()); //drop packets received during login verification } From 872b6ed708e172034d66e1d7891575eeedf3e77c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Jun 2019 19:28:47 +0100 Subject: [PATCH 1016/3224] Switch back to using fast-serialize for chunk send prepare network serialize on the main thread is 3-5x more expensive than fast-serialize right now. --- .../network/mcpe/ChunkRequestTask.php | 10 ++++++++-- src/pocketmine/network/mcpe/ChunkSerializer.php | 17 +++++++++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/network/mcpe/ChunkRequestTask.php b/src/pocketmine/network/mcpe/ChunkRequestTask.php index fe9a77a4ec..c1f04986c2 100644 --- a/src/pocketmine/network/mcpe/ChunkRequestTask.php +++ b/src/pocketmine/network/mcpe/ChunkRequestTask.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe; use pocketmine\network\mcpe\protocol\FullChunkDataPacket; use pocketmine\scheduler\AsyncTask; use pocketmine\world\format\Chunk; +use pocketmine\world\format\io\FastChunkSerializer; class ChunkRequestTask extends AsyncTask{ private const TLS_KEY_PROMISE = "promise"; @@ -40,19 +41,24 @@ class ChunkRequestTask extends AsyncTask{ protected $compressionLevel; + /** @var string */ + private $tiles = ""; + public function __construct(int $chunkX, int $chunkZ, Chunk $chunk, CompressBatchPromise $promise, ?\Closure $onError = null){ $this->compressionLevel = NetworkCompression::$LEVEL; - $this->chunk = ChunkSerializer::serialize($chunk); + $this->chunk = FastChunkSerializer::serialize($chunk); $this->chunkX = $chunkX; $this->chunkZ = $chunkZ; + $this->tiles = ChunkSerializer::serializeTiles($chunk); $this->storeLocal(self::TLS_KEY_PROMISE, $promise); $this->storeLocal(self::TLS_KEY_ERROR_HOOK, $onError); } public function onRun() : void{ - $this->setResult(NetworkCompression::compress(PacketBatch::fromPackets(FullChunkDataPacket::create($this->chunkX, $this->chunkZ, $this->chunk))->getBuffer(), $this->compressionLevel)); + $chunk = ChunkSerializer::serialize(FastChunkSerializer::deserialize($this->chunk), $this->tiles); + $this->setResult(NetworkCompression::compress(PacketBatch::fromPackets(FullChunkDataPacket::create($this->chunkX, $this->chunkZ, $chunk))->getBuffer(), $this->compressionLevel)); } public function onError() : void{ diff --git a/src/pocketmine/network/mcpe/ChunkSerializer.php b/src/pocketmine/network/mcpe/ChunkSerializer.php index 0939504eb0..b8f702285d 100644 --- a/src/pocketmine/network/mcpe/ChunkSerializer.php +++ b/src/pocketmine/network/mcpe/ChunkSerializer.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe; use pocketmine\block\tile\Spawnable; use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; +use pocketmine\utils\BinaryStream; use pocketmine\world\format\Chunk; use function count; use function pack; @@ -36,11 +37,13 @@ final class ChunkSerializer{ } /** - * @param Chunk $chunk + * @param Chunk $chunk + * + * @param string|null $tiles * * @return string */ - public static function serialize(Chunk $chunk) : string{ + public static function serialize(Chunk $chunk, ?string $tiles = null) : string{ $stream = new NetworkBinaryStream(); $subChunkCount = $chunk->getSubChunkSendCount(); $stream->putByte($subChunkCount); @@ -66,6 +69,16 @@ final class ChunkSerializer{ $stream->putByte(0); //border block array count //Border block entry format: 1 byte (4 bits X, 4 bits Z). These are however useless since they crash the regular client. + if($tiles !== null){ + $stream->put($tiles); + }else{ + $stream->put(self::serializeTiles($chunk)); + } + return $stream->getBuffer(); + } + + public static function serializeTiles(Chunk $chunk) : string{ + $stream = new BinaryStream(); foreach($chunk->getTiles() as $tile){ if($tile instanceof Spawnable){ $stream->put($tile->getSerializedSpawnCompound()); From e7733718b677ffff3a2d2035ab8ea0a08d5af547 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 27 Jun 2019 19:39:59 +0100 Subject: [PATCH 1017/3224] divide network\mcpe namespace into more subnamespaces --- src/pocketmine/Server.php | 28 +++++++++---------- src/pocketmine/block/tile/Spawnable.php | 2 +- src/pocketmine/inventory/CraftingManager.php | 6 ++-- src/pocketmine/network/mcpe/ChunkCache.php | 1 + .../network/mcpe/ChunkRequestTask.php | 7 +++-- .../network/mcpe/NetworkSession.php | 6 +++- src/pocketmine/network/mcpe/PacketBatch.php | 1 + .../mcpe/{ => auth}/ProcessLoginTask.php | 3 +- .../mcpe/{ => auth}/VerifyLoginException.php | 2 +- .../CompressBatchPromise.php | 2 +- .../{ => compression}/CompressBatchTask.php | 4 +-- .../Zlib.php} | 4 +-- .../mcpe/{ => encryption}/NetworkCipher.php | 2 +- .../PrepareEncryptionTask.php | 3 +- .../mcpe/handler/InGamePacketHandler.php | 2 +- .../mcpe/handler/LoginPacketHandler.php | 2 +- .../mcpe/protocol/CraftingDataPacket.php | 2 +- .../network/mcpe/protocol/DataPacket.php | 2 +- .../network/mcpe/protocol/StartGamePacket.php | 2 +- .../types/MismatchTransactionData.php | 2 +- .../protocol/types/NetworkInventoryAction.php | 6 ++-- .../protocol/types/NormalTransactionData.php | 2 +- .../types/ReleaseItemTransactionData.php | 2 +- .../mcpe/protocol/types/TransactionData.php | 6 ++-- .../types/UseItemOnEntityTransactionData.php | 2 +- .../protocol/types/UseItemTransactionData.php | 2 +- .../mcpe/{ => serializer}/ChunkSerializer.php | 2 +- .../{ => serializer}/NetworkBinaryStream.php | 4 +-- .../{ => serializer}/NetworkNbtSerializer.php | 2 +- 29 files changed, 61 insertions(+), 50 deletions(-) rename src/pocketmine/network/mcpe/{ => auth}/ProcessLoginTask.php (98%) rename src/pocketmine/network/mcpe/{ => auth}/VerifyLoginException.php (95%) rename src/pocketmine/network/mcpe/{ => compression}/CompressBatchPromise.php (98%) rename src/pocketmine/network/mcpe/{ => compression}/CompressBatchTask.php (92%) rename src/pocketmine/network/mcpe/{NetworkCompression.php => compression/Zlib.php} (95%) rename src/pocketmine/network/mcpe/{ => encryption}/NetworkCipher.php (98%) rename src/pocketmine/network/mcpe/{ => encryption}/PrepareEncryptionTask.php (97%) rename src/pocketmine/network/mcpe/{ => serializer}/ChunkSerializer.php (98%) rename src/pocketmine/network/mcpe/{ => serializer}/NetworkBinaryStream.php (99%) rename src/pocketmine/network/mcpe/{ => serializer}/NetworkNbtSerializer.php (97%) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index cdbbcc0af8..7d6b1287c7 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -50,10 +50,10 @@ use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; -use pocketmine\network\mcpe\CompressBatchPromise; -use pocketmine\network\mcpe\CompressBatchTask; -use pocketmine\network\mcpe\NetworkCipher; -use pocketmine\network\mcpe\NetworkCompression; +use pocketmine\network\mcpe\compression\CompressBatchPromise; +use pocketmine\network\mcpe\compression\CompressBatchTask; +use pocketmine\network\mcpe\compression\Zlib as ZlibNetworkCompression; +use pocketmine\network\mcpe\encryption\NetworkCipher; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\PacketBatch; use pocketmine\network\mcpe\protocol\ClientboundPacket; @@ -1089,15 +1089,15 @@ class Server{ $this->asyncPool = new AsyncPool($poolSize, (int) max(-1, (int) $this->getProperty("memory.async-worker-hard-limit", 256)), $this->autoloader, $this->logger); if($this->getProperty("network.batch-threshold", 256) >= 0){ - NetworkCompression::$THRESHOLD = (int) $this->getProperty("network.batch-threshold", 256); + ZlibNetworkCompression::$THRESHOLD = (int) $this->getProperty("network.batch-threshold", 256); }else{ - NetworkCompression::$THRESHOLD = -1; + ZlibNetworkCompression::$THRESHOLD = -1; } - NetworkCompression::$LEVEL = $this->getProperty("network.compression-level", 7); - if(NetworkCompression::$LEVEL < 1 or NetworkCompression::$LEVEL > 9){ - $this->logger->warning("Invalid network compression level " . NetworkCompression::$LEVEL . " set, setting to default 7"); - NetworkCompression::$LEVEL = 7; + ZlibNetworkCompression::$LEVEL = $this->getProperty("network.compression-level", 7); + if(ZlibNetworkCompression::$LEVEL < 1 or ZlibNetworkCompression::$LEVEL > 9){ + $this->logger->warning("Invalid network compression level " . ZlibNetworkCompression::$LEVEL . " set, setting to default 7"); + ZlibNetworkCompression::$LEVEL = 7; } $this->networkCompressionAsync = (bool) $this->getProperty("network.async-compression", true); @@ -1463,7 +1463,7 @@ class Server{ $stream = PacketBatch::fromPackets(...$ev->getPackets()); - if(NetworkCompression::$THRESHOLD < 0 or strlen($stream->getBuffer()) < NetworkCompression::$THRESHOLD){ + if(ZlibNetworkCompression::$THRESHOLD < 0 or strlen($stream->getBuffer()) < ZlibNetworkCompression::$THRESHOLD){ foreach($recipients as $target){ foreach($ev->getPackets() as $pk){ $target->addToSendBuffer($pk); @@ -1491,9 +1491,9 @@ class Server{ try{ Timings::$playerNetworkSendCompressTimer->startTiming(); - $compressionLevel = NetworkCompression::$LEVEL; + $compressionLevel = ZlibNetworkCompression::$LEVEL; $buffer = $stream->getBuffer(); - if(NetworkCompression::$THRESHOLD < 0 or strlen($buffer) < NetworkCompression::$THRESHOLD){ + if(ZlibNetworkCompression::$THRESHOLD < 0 or strlen($buffer) < ZlibNetworkCompression::$THRESHOLD){ $compressionLevel = 0; //Do not compress packets under the threshold $forceSync = true; } @@ -1503,7 +1503,7 @@ class Server{ $task = new CompressBatchTask($buffer, $compressionLevel, $promise); $this->asyncPool->submitTask($task); }else{ - $promise->resolve(NetworkCompression::compress($buffer, $compressionLevel)); + $promise->resolve(ZlibNetworkCompression::compress($buffer, $compressionLevel)); } return $promise; diff --git a/src/pocketmine/block/tile/Spawnable.php b/src/pocketmine/block/tile/Spawnable.php index 226a15412f..2e6e772a75 100644 --- a/src/pocketmine/block/tile/Spawnable.php +++ b/src/pocketmine/block/tile/Spawnable.php @@ -25,7 +25,7 @@ namespace pocketmine\block\tile; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; -use pocketmine\network\mcpe\NetworkNbtSerializer; +use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; use function get_class; abstract class Spawnable extends Tile{ diff --git a/src/pocketmine/inventory/CraftingManager.php b/src/pocketmine/inventory/CraftingManager.php index df0e614133..b643b80699 100644 --- a/src/pocketmine/inventory/CraftingManager.php +++ b/src/pocketmine/inventory/CraftingManager.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\inventory; use pocketmine\item\Item; -use pocketmine\network\mcpe\CompressBatchPromise; -use pocketmine\network\mcpe\NetworkCompression; +use pocketmine\network\mcpe\compression\CompressBatchPromise; +use pocketmine\network\mcpe\compression\Zlib; use pocketmine\network\mcpe\PacketBatch; use pocketmine\network\mcpe\protocol\CraftingDataPacket; use pocketmine\timings\Timings; @@ -117,7 +117,7 @@ class CraftingManager{ } $this->craftingDataCache = new CompressBatchPromise(); - $this->craftingDataCache->resolve(NetworkCompression::compress(PacketBatch::fromPackets($pk)->getBuffer())); + $this->craftingDataCache->resolve(Zlib::compress(PacketBatch::fromPackets($pk)->getBuffer())); Timings::$craftingDataCacheRebuildTimer->stopTiming(); } diff --git a/src/pocketmine/network/mcpe/ChunkCache.php b/src/pocketmine/network/mcpe/ChunkCache.php index c648cd7bac..c19c847c7c 100644 --- a/src/pocketmine/network/mcpe/ChunkCache.php +++ b/src/pocketmine/network/mcpe/ChunkCache.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; use pocketmine\math\Vector3; +use pocketmine\network\mcpe\compression\CompressBatchPromise; use pocketmine\world\ChunkListener; use pocketmine\world\ChunkListenerNoOpTrait; use pocketmine\world\format\Chunk; diff --git a/src/pocketmine/network/mcpe/ChunkRequestTask.php b/src/pocketmine/network/mcpe/ChunkRequestTask.php index c1f04986c2..9c31d7e162 100644 --- a/src/pocketmine/network/mcpe/ChunkRequestTask.php +++ b/src/pocketmine/network/mcpe/ChunkRequestTask.php @@ -23,7 +23,10 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; +use pocketmine\network\mcpe\compression\CompressBatchPromise; +use pocketmine\network\mcpe\compression\Zlib; use pocketmine\network\mcpe\protocol\FullChunkDataPacket; +use pocketmine\network\mcpe\serializer\ChunkSerializer; use pocketmine\scheduler\AsyncTask; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\FastChunkSerializer; @@ -45,7 +48,7 @@ class ChunkRequestTask extends AsyncTask{ private $tiles = ""; public function __construct(int $chunkX, int $chunkZ, Chunk $chunk, CompressBatchPromise $promise, ?\Closure $onError = null){ - $this->compressionLevel = NetworkCompression::$LEVEL; + $this->compressionLevel = Zlib::$LEVEL; $this->chunk = FastChunkSerializer::serialize($chunk); $this->chunkX = $chunkX; @@ -58,7 +61,7 @@ class ChunkRequestTask extends AsyncTask{ public function onRun() : void{ $chunk = ChunkSerializer::serialize(FastChunkSerializer::deserialize($this->chunk), $this->tiles); - $this->setResult(NetworkCompression::compress(PacketBatch::fromPackets(FullChunkDataPacket::create($this->chunkX, $this->chunkZ, $chunk))->getBuffer(), $this->compressionLevel)); + $this->setResult(Zlib::compress(PacketBatch::fromPackets(FullChunkDataPacket::create($this->chunkX, $this->chunkZ, $chunk))->getBuffer(), $this->compressionLevel)); } public function onError() : void{ diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index d84336379c..1ec213c833 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -33,6 +33,10 @@ use pocketmine\event\server\DataPacketSendEvent; use pocketmine\form\Form; use pocketmine\math\Vector3; use pocketmine\network\BadPacketException; +use pocketmine\network\mcpe\compression\CompressBatchPromise; +use pocketmine\network\mcpe\compression\Zlib; +use pocketmine\network\mcpe\encryption\NetworkCipher; +use pocketmine\network\mcpe\encryption\PrepareEncryptionTask; use pocketmine\network\mcpe\handler\DeathPacketHandler; use pocketmine\network\mcpe\handler\HandshakePacketHandler; use pocketmine\network\mcpe\handler\InGamePacketHandler; @@ -280,7 +284,7 @@ class NetworkSession{ Timings::$playerNetworkReceiveDecompressTimer->startTiming(); try{ - $stream = new PacketBatch(NetworkCompression::decompress($payload)); + $stream = new PacketBatch(Zlib::decompress($payload)); }catch(\ErrorException $e){ $this->logger->debug("Failed to decompress packet: " . base64_encode($payload)); //TODO: this isn't incompatible game version if we already established protocol version diff --git a/src/pocketmine/network/mcpe/PacketBatch.php b/src/pocketmine/network/mcpe/PacketBatch.php index 2e3d8e046e..31c081418c 100644 --- a/src/pocketmine/network/mcpe/PacketBatch.php +++ b/src/pocketmine/network/mcpe/PacketBatch.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe; use pocketmine\network\mcpe\protocol\Packet; use pocketmine\network\mcpe\protocol\PacketPool; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; class PacketBatch extends NetworkBinaryStream{ diff --git a/src/pocketmine/network/mcpe/ProcessLoginTask.php b/src/pocketmine/network/mcpe/auth/ProcessLoginTask.php similarity index 98% rename from src/pocketmine/network/mcpe/ProcessLoginTask.php rename to src/pocketmine/network/mcpe/auth/ProcessLoginTask.php index 8dbe3e3147..2d9d627c7b 100644 --- a/src/pocketmine/network/mcpe/ProcessLoginTask.php +++ b/src/pocketmine/network/mcpe/auth/ProcessLoginTask.php @@ -21,13 +21,14 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe; +namespace pocketmine\network\mcpe\auth; use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; use Mdanter\Ecc\Crypto\Signature\Signature; use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; use Mdanter\Ecc\Serializer\PublicKey\PemPublicKeySerializer; use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer; +use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\LoginPacket; use pocketmine\scheduler\AsyncTask; use function assert; diff --git a/src/pocketmine/network/mcpe/VerifyLoginException.php b/src/pocketmine/network/mcpe/auth/VerifyLoginException.php similarity index 95% rename from src/pocketmine/network/mcpe/VerifyLoginException.php rename to src/pocketmine/network/mcpe/auth/VerifyLoginException.php index ee2268a41c..fc5fbbacaa 100644 --- a/src/pocketmine/network/mcpe/VerifyLoginException.php +++ b/src/pocketmine/network/mcpe/auth/VerifyLoginException.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe; +namespace pocketmine\network\mcpe\auth; class VerifyLoginException extends \RuntimeException{ diff --git a/src/pocketmine/network/mcpe/CompressBatchPromise.php b/src/pocketmine/network/mcpe/compression/CompressBatchPromise.php similarity index 98% rename from src/pocketmine/network/mcpe/CompressBatchPromise.php rename to src/pocketmine/network/mcpe/compression/CompressBatchPromise.php index fe4e8f864d..709734f84a 100644 --- a/src/pocketmine/network/mcpe/CompressBatchPromise.php +++ b/src/pocketmine/network/mcpe/compression/CompressBatchPromise.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe; +namespace pocketmine\network\mcpe\compression; use pocketmine\utils\Utils; use function array_push; diff --git a/src/pocketmine/network/mcpe/CompressBatchTask.php b/src/pocketmine/network/mcpe/compression/CompressBatchTask.php similarity index 92% rename from src/pocketmine/network/mcpe/CompressBatchTask.php rename to src/pocketmine/network/mcpe/compression/CompressBatchTask.php index 2a64a63d1e..9ad39314d1 100644 --- a/src/pocketmine/network/mcpe/CompressBatchTask.php +++ b/src/pocketmine/network/mcpe/compression/CompressBatchTask.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe; +namespace pocketmine\network\mcpe\compression; use pocketmine\scheduler\AsyncTask; @@ -44,7 +44,7 @@ class CompressBatchTask extends AsyncTask{ } public function onRun() : void{ - $this->setResult(NetworkCompression::compress($this->data, $this->level)); + $this->setResult(Zlib::compress($this->data, $this->level)); } public function onCompletion() : void{ diff --git a/src/pocketmine/network/mcpe/NetworkCompression.php b/src/pocketmine/network/mcpe/compression/Zlib.php similarity index 95% rename from src/pocketmine/network/mcpe/NetworkCompression.php rename to src/pocketmine/network/mcpe/compression/Zlib.php index 4f44a6fd5a..9963126141 100644 --- a/src/pocketmine/network/mcpe/NetworkCompression.php +++ b/src/pocketmine/network/mcpe/compression/Zlib.php @@ -21,13 +21,13 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe; +namespace pocketmine\network\mcpe\compression; use function zlib_decode; use function zlib_encode; use const ZLIB_ENCODING_DEFLATE; -final class NetworkCompression{ +final class Zlib{ public static $LEVEL = 7; public static $THRESHOLD = 256; diff --git a/src/pocketmine/network/mcpe/NetworkCipher.php b/src/pocketmine/network/mcpe/encryption/NetworkCipher.php similarity index 98% rename from src/pocketmine/network/mcpe/NetworkCipher.php rename to src/pocketmine/network/mcpe/encryption/NetworkCipher.php index b243fb88b4..beb74b7955 100644 --- a/src/pocketmine/network/mcpe/NetworkCipher.php +++ b/src/pocketmine/network/mcpe/encryption/NetworkCipher.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe; +namespace pocketmine\network\mcpe\encryption; use Crypto\Cipher; use pocketmine\utils\Binary; diff --git a/src/pocketmine/network/mcpe/PrepareEncryptionTask.php b/src/pocketmine/network/mcpe/encryption/PrepareEncryptionTask.php similarity index 97% rename from src/pocketmine/network/mcpe/PrepareEncryptionTask.php rename to src/pocketmine/network/mcpe/encryption/PrepareEncryptionTask.php index f67794ed7a..e897bd6fb1 100644 --- a/src/pocketmine/network/mcpe/PrepareEncryptionTask.php +++ b/src/pocketmine/network/mcpe/encryption/PrepareEncryptionTask.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe; +namespace pocketmine\network\mcpe\encryption; use Mdanter\Ecc\Crypto\Key\PrivateKeyInterface; use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; @@ -30,6 +30,7 @@ use Mdanter\Ecc\Serializer\PrivateKey\DerPrivateKeySerializer; use Mdanter\Ecc\Serializer\PrivateKey\PemPrivateKeySerializer; use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer; +use pocketmine\network\mcpe\NetworkSession; use pocketmine\scheduler\AsyncTask; use function base64_encode; use function gmp_strval; diff --git a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php index 97a8e94800..09bc274e35 100644 --- a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php @@ -38,7 +38,6 @@ use pocketmine\math\Vector3; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\StringTag; use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\NetworkNbtSerializer; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; @@ -81,6 +80,7 @@ use pocketmine\network\mcpe\protocol\types\NormalTransactionData; use pocketmine\network\mcpe\protocol\types\ReleaseItemTransactionData; use pocketmine\network\mcpe\protocol\types\UseItemOnEntityTransactionData; use pocketmine\network\mcpe\protocol\types\UseItemTransactionData; +use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; use pocketmine\player\Player; use function array_push; use function base64_encode; diff --git a/src/pocketmine/network/mcpe/handler/LoginPacketHandler.php b/src/pocketmine/network/mcpe/handler/LoginPacketHandler.php index d34db5126e..34d168ddb4 100644 --- a/src/pocketmine/network/mcpe/handler/LoginPacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/LoginPacketHandler.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\handler; use pocketmine\entity\Skin; use pocketmine\event\player\PlayerPreLoginEvent; +use pocketmine\network\mcpe\auth\ProcessLoginTask; use pocketmine\network\mcpe\NetworkSession; -use pocketmine\network\mcpe\ProcessLoginTask; use pocketmine\network\mcpe\protocol\LoginPacket; use pocketmine\network\mcpe\protocol\PlayStatusPacket; use pocketmine\network\mcpe\protocol\ProtocolInfo; diff --git a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php b/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php index 910c863dc5..c001f28a7b 100644 --- a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php @@ -33,7 +33,7 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\PacketHandler; -use pocketmine\network\mcpe\NetworkBinaryStream; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; use function str_repeat; diff --git a/src/pocketmine/network/mcpe/protocol/DataPacket.php b/src/pocketmine/network/mcpe/protocol/DataPacket.php index 9633f71137..fdf8476883 100644 --- a/src/pocketmine/network/mcpe/protocol/DataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/DataPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\NetworkBinaryStream; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; use pocketmine\utils\Utils; use function bin2hex; diff --git a/src/pocketmine/network/mcpe/protocol/StartGamePacket.php b/src/pocketmine/network/mcpe/protocol/StartGamePacket.php index 86d39a6741..caa24d08c2 100644 --- a/src/pocketmine/network/mcpe/protocol/StartGamePacket.php +++ b/src/pocketmine/network/mcpe/protocol/StartGamePacket.php @@ -28,9 +28,9 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; -use pocketmine\network\mcpe\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class StartGamePacket extends DataPacket implements ClientboundPacket{ diff --git a/src/pocketmine/network/mcpe/protocol/types/MismatchTransactionData.php b/src/pocketmine/network/mcpe/protocol/types/MismatchTransactionData.php index 52bac3b315..3cf69f5c2e 100644 --- a/src/pocketmine/network/mcpe/protocol/types/MismatchTransactionData.php +++ b/src/pocketmine/network/mcpe/protocol/types/MismatchTransactionData.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types; use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class MismatchTransactionData extends TransactionData{ diff --git a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php index 2a5851a143..4a195f58c2 100644 --- a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php +++ b/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php @@ -32,7 +32,7 @@ use pocketmine\inventory\transaction\action\InventoryAction; use pocketmine\inventory\transaction\action\SlotChangeAction; use pocketmine\item\Item; use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\NetworkBinaryStream; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\player\Player; use pocketmine\utils\BinaryDataException; @@ -97,7 +97,7 @@ class NetworkInventoryAction{ public $newItem; /** - * @param NetworkBinaryStream $packet + * @param \pocketmine\network\mcpe\serializer\NetworkBinaryStream $packet * * @return $this * @@ -132,7 +132,7 @@ class NetworkInventoryAction{ } /** - * @param NetworkBinaryStream $packet + * @param \pocketmine\network\mcpe\serializer\NetworkBinaryStream $packet * * @throws \InvalidArgumentException */ diff --git a/src/pocketmine/network/mcpe/protocol/types/NormalTransactionData.php b/src/pocketmine/network/mcpe/protocol/types/NormalTransactionData.php index 500c80d912..cb4e8c3ba0 100644 --- a/src/pocketmine/network/mcpe/protocol/types/NormalTransactionData.php +++ b/src/pocketmine/network/mcpe/protocol/types/NormalTransactionData.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types; -use pocketmine\network\mcpe\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class NormalTransactionData extends TransactionData{ diff --git a/src/pocketmine/network/mcpe/protocol/types/ReleaseItemTransactionData.php b/src/pocketmine/network/mcpe/protocol/types/ReleaseItemTransactionData.php index 471801a839..9e5d374fa7 100644 --- a/src/pocketmine/network/mcpe/protocol/types/ReleaseItemTransactionData.php +++ b/src/pocketmine/network/mcpe/protocol/types/ReleaseItemTransactionData.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol\types; use pocketmine\item\Item; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ReleaseItemTransactionData extends TransactionData{ public const ACTION_RELEASE = 0; //bow shoot diff --git a/src/pocketmine/network/mcpe/protocol/types/TransactionData.php b/src/pocketmine/network/mcpe/protocol/types/TransactionData.php index 8cb0688e2d..b2e084cb8b 100644 --- a/src/pocketmine/network/mcpe/protocol/types/TransactionData.php +++ b/src/pocketmine/network/mcpe/protocol/types/TransactionData.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types; use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\NetworkBinaryStream; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; use function count; @@ -45,7 +45,7 @@ abstract class TransactionData{ abstract public function getTypeId() : int; /** - * @param NetworkBinaryStream $stream + * @param \pocketmine\network\mcpe\serializer\NetworkBinaryStream $stream * * @throws BinaryDataException * @throws BadPacketException @@ -59,7 +59,7 @@ abstract class TransactionData{ } /** - * @param NetworkBinaryStream $stream + * @param \pocketmine\network\mcpe\serializer\NetworkBinaryStream $stream * * @throws BinaryDataException * @throws BadPacketException diff --git a/src/pocketmine/network/mcpe/protocol/types/UseItemOnEntityTransactionData.php b/src/pocketmine/network/mcpe/protocol/types/UseItemOnEntityTransactionData.php index 560a5eb5e2..c3e7c61175 100644 --- a/src/pocketmine/network/mcpe/protocol/types/UseItemOnEntityTransactionData.php +++ b/src/pocketmine/network/mcpe/protocol/types/UseItemOnEntityTransactionData.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol\types; use pocketmine\item\Item; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class UseItemOnEntityTransactionData extends TransactionData{ public const ACTION_INTERACT = 0; diff --git a/src/pocketmine/network/mcpe/protocol/types/UseItemTransactionData.php b/src/pocketmine/network/mcpe/protocol/types/UseItemTransactionData.php index ff4bcbb6a5..0959687a35 100644 --- a/src/pocketmine/network/mcpe/protocol/types/UseItemTransactionData.php +++ b/src/pocketmine/network/mcpe/protocol/types/UseItemTransactionData.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol\types; use pocketmine\item\Item; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class UseItemTransactionData extends TransactionData{ public const ACTION_CLICK_BLOCK = 0; diff --git a/src/pocketmine/network/mcpe/ChunkSerializer.php b/src/pocketmine/network/mcpe/serializer/ChunkSerializer.php similarity index 98% rename from src/pocketmine/network/mcpe/ChunkSerializer.php rename to src/pocketmine/network/mcpe/serializer/ChunkSerializer.php index b8f702285d..e95f5b0c0b 100644 --- a/src/pocketmine/network/mcpe/ChunkSerializer.php +++ b/src/pocketmine/network/mcpe/serializer/ChunkSerializer.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe; +namespace pocketmine\network\mcpe\serializer; use pocketmine\block\tile\Spawnable; use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; diff --git a/src/pocketmine/network/mcpe/NetworkBinaryStream.php b/src/pocketmine/network/mcpe/serializer/NetworkBinaryStream.php similarity index 99% rename from src/pocketmine/network/mcpe/NetworkBinaryStream.php rename to src/pocketmine/network/mcpe/serializer/NetworkBinaryStream.php index 746e1aa4c1..725fcb23ec 100644 --- a/src/pocketmine/network/mcpe/NetworkBinaryStream.php +++ b/src/pocketmine/network/mcpe/serializer/NetworkBinaryStream.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe; +namespace pocketmine\network\mcpe\serializer; #include @@ -30,8 +30,8 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\ItemIds; use pocketmine\math\Vector3; -use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\NbtDataException; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\types\CommandOriginData; diff --git a/src/pocketmine/network/mcpe/NetworkNbtSerializer.php b/src/pocketmine/network/mcpe/serializer/NetworkNbtSerializer.php similarity index 97% rename from src/pocketmine/network/mcpe/NetworkNbtSerializer.php rename to src/pocketmine/network/mcpe/serializer/NetworkNbtSerializer.php index 776d3e9356..8d4a882634 100644 --- a/src/pocketmine/network/mcpe/NetworkNbtSerializer.php +++ b/src/pocketmine/network/mcpe/serializer/NetworkNbtSerializer.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe; +namespace pocketmine\network\mcpe\serializer; use pocketmine\nbt\LittleEndianNbtSerializer; use function count; From a4b50e57a4558eda72d512f23ac4387f13c6fb61 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 28 Jun 2019 15:08:51 +0100 Subject: [PATCH 1018/3224] move player arm swing processing to server side --- .../event/player/PlayerAnimationEvent.php | 54 ------------------- .../mcpe/handler/InGamePacketHandler.php | 2 +- src/pocketmine/player/Player.php | 19 +++---- 3 files changed, 8 insertions(+), 67 deletions(-) delete mode 100644 src/pocketmine/event/player/PlayerAnimationEvent.php diff --git a/src/pocketmine/event/player/PlayerAnimationEvent.php b/src/pocketmine/event/player/PlayerAnimationEvent.php deleted file mode 100644 index fb965fe6c7..0000000000 --- a/src/pocketmine/event/player/PlayerAnimationEvent.php +++ /dev/null @@ -1,54 +0,0 @@ -player = $player; - $this->animationType = $animation; - } - - /** - * @return int - */ - public function getAnimationType() : int{ - return $this->animationType; - } -} diff --git a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php index 09bc274e35..48129dd3e8 100644 --- a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php @@ -458,7 +458,7 @@ class InGamePacketHandler extends PacketHandler{ } public function handleAnimate(AnimatePacket $packet) : bool{ - return $this->player->animate($packet->action); + return true; //Not used } public function handleContainerClose(ContainerClosePacket $packet) : bool{ diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 4c1f1e72fd..a6cb3324cd 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -42,7 +42,6 @@ use pocketmine\event\inventory\InventoryCloseEvent; use pocketmine\event\inventory\InventoryOpenEvent; use pocketmine\event\player\cheat\PlayerIllegalMoveEvent; use pocketmine\event\player\PlayerAchievementAwardedEvent; -use pocketmine\event\player\PlayerAnimationEvent; use pocketmine\event\player\PlayerBedEnterEvent; use pocketmine\event\player\PlayerBedLeaveEvent; use pocketmine\event\player\PlayerBlockPickEvent; @@ -88,6 +87,7 @@ use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; +use pocketmine\network\mcpe\protocol\EntityEventPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\SetTitlePacket; @@ -1821,6 +1821,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($ev->isCancelled()){ return false; } + $this->broadcastEntityEvent(EntityEventPacket::ARM_SWING, null, $this->getViewers()); if($target->onAttack($this->inventory->getItemInHand(), $face, $this)){ return true; } @@ -1845,6 +1846,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, public function continueBreakBlock(Vector3 $pos, int $face) : void{ $block = $this->world->getBlock($pos); $this->world->addParticle($pos, new PunchBlockParticle($block, $face)); + $this->broadcastEntityEvent(EntityEventPacket::ARM_SWING, null, $this->getViewers()); //TODO: destroy-progress level event } @@ -1864,6 +1866,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->doCloseInventory(); if($this->canInteract($pos->add(0.5, 0.5, 0.5), $this->isCreative() ? 13 : 7) and !$this->isSpectator()){ + $this->broadcastEntityEvent(EntityEventPacket::ARM_SWING, null, $this->getViewers()); $item = $this->inventory->getItemInHand(); $oldItem = clone $item; if($this->world->useBreakOn($pos, $item, $this, true)){ @@ -1891,6 +1894,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->setUsingItem(false); if($this->canInteract($pos->add(0.5, 0.5, 0.5), 13) and !$this->isSpectator()){ + $this->broadcastEntityEvent(EntityEventPacket::ARM_SWING, null, $this->getViewers()); $item = $this->inventory->getItemInHand(); //this is a copy of the real item $oldItem = clone $item; if($this->world->useItemOn($pos, $item, $face, $clickOffset, $this, true)){ @@ -1950,6 +1954,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($ev->isCancelled()){ return false; } + $this->broadcastEntityEvent(EntityEventPacket::ARM_SWING, null, $this->getViewers()); if($ev->getModifier(EntityDamageEvent::MODIFIER_CRITICAL) > 0){ $entity->broadcastAnimation(null, AnimatePacket::ACTION_CRITICAL_HIT); @@ -2020,23 +2025,13 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return true; } - public function animate(int $action) : bool{ - $ev = new PlayerAnimationEvent($this, $action); - $ev->call(); - if($ev->isCancelled()){ - return true; - } - - $this->broadcastAnimation($this->getViewers(), $ev->getAnimationType()); - return true; - } - /** * Drops an item on the ground in front of the player. * * @param Item $item */ public function dropItem(Item $item) : void{ + $this->broadcastEntityEvent(EntityEventPacket::ARM_SWING, null, $this->getViewers()); $this->world->dropItem($this->add(0, 1.3, 0), $item, $this->getDirectionVector()->multiply(0.4), 40); } From 44a205b1ccde1c48983d0a809be482c07f659131 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 28 Jun 2019 16:36:17 +0100 Subject: [PATCH 1019/3224] Remove MainLogger singleton and remaining MainLogger hard-dependencies --- src/pocketmine/PocketMine.php | 1 - src/pocketmine/scheduler/AsyncWorker.php | 4 --- src/pocketmine/utils/MainLogger.php | 32 ------------------------ 3 files changed, 37 deletions(-) diff --git a/src/pocketmine/PocketMine.php b/src/pocketmine/PocketMine.php index c280019fc0..e138e7bf6a 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/pocketmine/PocketMine.php @@ -223,7 +223,6 @@ namespace pocketmine { } $logger = new MainLogger(\pocketmine\DATA . "server.log"); - $logger->registerStatic(); \GlobalLogger::set($logger); if(extension_loaded("xdebug")){ diff --git a/src/pocketmine/scheduler/AsyncWorker.php b/src/pocketmine/scheduler/AsyncWorker.php index 3633983135..7de763da8f 100644 --- a/src/pocketmine/scheduler/AsyncWorker.php +++ b/src/pocketmine/scheduler/AsyncWorker.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\scheduler; use pocketmine\thread\Worker; -use pocketmine\utils\MainLogger; use function gc_enable; use function ini_set; @@ -46,9 +45,6 @@ class AsyncWorker extends Worker{ protected function onRun() : void{ \GlobalLogger::set($this->logger); - if($this->logger instanceof MainLogger){ - $this->logger->registerStatic(); - } gc_enable(); diff --git a/src/pocketmine/utils/MainLogger.php b/src/pocketmine/utils/MainLogger.php index e98e9a8340..0160541c5d 100644 --- a/src/pocketmine/utils/MainLogger.php +++ b/src/pocketmine/utils/MainLogger.php @@ -48,8 +48,6 @@ class MainLogger extends \AttachableThreadedLogger{ protected $shutdown; /** @var bool */ protected $logDebug; - /** @var MainLogger */ - public static $logger = null; /** @var bool */ private $syncFlush = false; @@ -70,9 +68,6 @@ class MainLogger extends \AttachableThreadedLogger{ */ public function __construct(string $logFile, bool $logDebug = false){ parent::__construct(); - if(static::$logger instanceof MainLogger){ - throw new \RuntimeException("MainLogger has been already created"); - } touch($logFile); $this->logFile = $logFile; $this->logDebug = $logDebug; @@ -85,33 +80,6 @@ class MainLogger extends \AttachableThreadedLogger{ $this->start(PTHREADS_INHERIT_NONE); } - /** - * @return MainLogger - */ - public static function getLogger() : MainLogger{ - return static::$logger; - } - - /** - * Returns whether a MainLogger instance is statically registered on this thread. - * @return bool - */ - public static function isRegisteredStatic() : bool{ - return static::$logger !== null; - } - - /** - * Assigns the MainLogger instance to the {@link MainLogger#logger} static property. - * - * WARNING: Because static properties are thread-local, this MUST be called from the body of every Thread if you - * want the logger to be accessible via {@link MainLogger#getLogger}. - */ - public function registerStatic() : void{ - if(static::$logger === null){ - static::$logger = $this; - } - } - /** * Returns the current logger format used for console output. * From 0d769aab48e88e3e9803a5ea31a24085cde85e42 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 29 Jun 2019 11:10:20 +0100 Subject: [PATCH 1020/3224] Removed anti-noclip checks --- resources/pocketmine.yml | 3 - .../event/player/cheat/PlayerCheatEvent.php | 36 --------- .../player/cheat/PlayerIllegalMoveEvent.php | 79 ------------------- src/pocketmine/player/Player.php | 36 +-------- 4 files changed, 1 insertion(+), 153 deletions(-) delete mode 100644 src/pocketmine/event/player/cheat/PlayerCheatEvent.php delete mode 100644 src/pocketmine/event/player/cheat/PlayerIllegalMoveEvent.php diff --git a/resources/pocketmine.yml b/resources/pocketmine.yml index 769b271a21..6b4bbbd9d6 100644 --- a/resources/pocketmine.yml +++ b/resources/pocketmine.yml @@ -105,9 +105,6 @@ debug: player: #Choose whether to enable player data saving. save-player-data: true - anti-cheat: - #If false, will try to prevent speed and noclip cheats. May cause movement issues. - allow-movement-cheats: true level-settings: #The default format that levels will use when created diff --git a/src/pocketmine/event/player/cheat/PlayerCheatEvent.php b/src/pocketmine/event/player/cheat/PlayerCheatEvent.php deleted file mode 100644 index 508c24e124..0000000000 --- a/src/pocketmine/event/player/cheat/PlayerCheatEvent.php +++ /dev/null @@ -1,36 +0,0 @@ -player = $player; - $this->attemptedPosition = $attemptedPosition; - $this->originalPosition = $originalPosition; - $this->expectedPosition = $player->asVector3(); - } - - /** - * Returns the position the player attempted to move to. - * @return Vector3 - */ - public function getAttemptedPosition() : Vector3{ - return $this->attemptedPosition; - } - - /** - * @return Vector3 - */ - public function getOriginalPosition() : Vector3{ - return $this->originalPosition; - } - - /** - * @return Vector3 - */ - public function getExpectedPosition() : Vector3{ - return $this->expectedPosition; - } -} diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index a6cb3324cd..34316e2dd5 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -40,7 +40,6 @@ use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\inventory\InventoryCloseEvent; use pocketmine\event\inventory\InventoryOpenEvent; -use pocketmine\event\player\cheat\PlayerIllegalMoveEvent; use pocketmine\event\player\PlayerAchievementAwardedEvent; use pocketmine\event\player\PlayerBedEnterEvent; use pocketmine\event\player\PlayerBedLeaveEvent; @@ -228,8 +227,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, protected $inAirTicks = 0; /** @var float */ protected $stepHeight = 0.6; - /** @var bool */ - protected $allowMovementCheats = false; /** @var Vector3|null */ protected $sleeping = null; @@ -292,8 +289,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->chunksPerTick = (int) $this->server->getProperty("chunk-sending.per-tick", 4); $this->spawnThreshold = (int) (($this->server->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); - $this->allowMovementCheats = (bool) $this->server->getProperty("player.anti-cheat.allow-movement-cheats", false); - $namedtag = $this->server->getOfflinePlayerData($this->username); //TODO: make this async $spawnReset = false; @@ -369,7 +364,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $this->allowFlight = $this->isCreative(); - $this->keepMovement = $this->isSpectator() || $this->allowMovementCheats(); + $this->keepMovement = true; if($this->isOp()){ $this->setRemoveFormat(false); } @@ -533,14 +528,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->autoJump; } - public function allowMovementCheats() : bool{ - return $this->allowMovementCheats; - } - - public function setAllowMovementCheats(bool $value = true){ - $this->allowMovementCheats = $value; - } - /** * @param Player $player */ @@ -1224,10 +1211,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->allowFlight = $this->isCreative(); if($this->isSpectator()){ $this->setFlying(true); - $this->keepMovement = true; $this->despawnFromAll(); }else{ - $this->keepMovement = $this->allowMovementCheats; if($this->isSurvival()){ $this->setFlying(false); } @@ -1416,25 +1401,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $dz = $newPos->z - $this->z; $this->move($dx, $dy, $dz); - - $diff = $this->distanceSquared($newPos) / $tickDiff ** 2; - - if($this->isSurvival() and !$revert and $diff > 0.0625){ - $ev = new PlayerIllegalMoveEvent($this, $newPos, $this->lastLocation->asVector3()); - $ev->setCancelled($this->allowMovementCheats); - - $ev->call(); - - if(!$ev->isCancelled()){ - $revert = true; - $this->logger->warning($this->getServer()->getLanguage()->translateString("pocketmine.player.invalidMove", [$this->getName()])); - $this->logger->debug("Old position: " . $this->asVector3() . ", new position: " . $this->newPosition); - } - } - - if($diff > 0 and !$revert){ - $this->setPosition($newPos); - } } $from = clone $this->lastLocation; From 80d4eeaa3c7edbb4fb2c27784a341b0fbccfa2a6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 29 Jun 2019 11:14:34 +0100 Subject: [PATCH 1021/3224] fix some occurrences of terrain truncation during generation --- src/pocketmine/world/SimpleChunkManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/world/SimpleChunkManager.php b/src/pocketmine/world/SimpleChunkManager.php index 67d06a8d8e..35cab0f035 100644 --- a/src/pocketmine/world/SimpleChunkManager.php +++ b/src/pocketmine/world/SimpleChunkManager.php @@ -59,7 +59,7 @@ class SimpleChunkManager implements ChunkManager{ } public function setBlockAt(int $x, int $y, int $z, Block $block) : bool{ - if($this->terrainPointer->moveTo($x, $y, $z, false)){ + if($this->terrainPointer->moveTo($x, $y, $z, true)){ $this->terrainPointer->currentSubChunk->setFullBlock($x & 0xf, $y & 0xf, $z & 0xf, $block->getFullId()); return true; } From 68bff6cf69c0fcd6e7ce1b57588b5b11d01c0cfa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 30 Jun 2019 14:31:38 +0100 Subject: [PATCH 1022/3224] moved RegisteredListener to event namespace --- src/pocketmine/event/HandlerList.php | 1 - src/pocketmine/{plugin => event}/RegisteredListener.php | 5 ++--- src/pocketmine/plugin/PluginManager.php | 1 + 3 files changed, 3 insertions(+), 4 deletions(-) rename src/pocketmine/{plugin => event}/RegisteredListener.php (96%) diff --git a/src/pocketmine/event/HandlerList.php b/src/pocketmine/event/HandlerList.php index 60b3d4bac6..e5fbb81f8f 100644 --- a/src/pocketmine/event/HandlerList.php +++ b/src/pocketmine/event/HandlerList.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\event; use pocketmine\plugin\Plugin; -use pocketmine\plugin\RegisteredListener; use pocketmine\utils\Utils; use function array_fill_keys; use function in_array; diff --git a/src/pocketmine/plugin/RegisteredListener.php b/src/pocketmine/event/RegisteredListener.php similarity index 96% rename from src/pocketmine/plugin/RegisteredListener.php rename to src/pocketmine/event/RegisteredListener.php index c4b7e04f6d..0026063fe7 100644 --- a/src/pocketmine/plugin/RegisteredListener.php +++ b/src/pocketmine/event/RegisteredListener.php @@ -21,10 +21,9 @@ declare(strict_types=1); -namespace pocketmine\plugin; +namespace pocketmine\event; -use pocketmine\event\Cancellable; -use pocketmine\event\Event; +use pocketmine\plugin\Plugin; use pocketmine\timings\TimingsHandler; class RegisteredListener{ diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index 2aeadc14b8..7dabe5fd99 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -29,6 +29,7 @@ use pocketmine\event\HandlerList; use pocketmine\event\Listener; use pocketmine\event\plugin\PluginDisableEvent; use pocketmine\event\plugin\PluginEnableEvent; +use pocketmine\event\RegisteredListener; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\permission\PermissionManager; use pocketmine\Server; From 5e5f43242e3758fe99f51df3383b247a8e758b53 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 30 Jun 2019 14:49:09 +0100 Subject: [PATCH 1023/3224] Extract a HandlerListManager unit from HandlerList --- src/pocketmine/Server.php | 4 +- src/pocketmine/event/Event.php | 2 +- src/pocketmine/event/HandlerList.php | 71 +------------- src/pocketmine/event/HandlerListManager.php | 100 ++++++++++++++++++++ src/pocketmine/plugin/PluginManager.php | 5 +- 5 files changed, 110 insertions(+), 72 deletions(-) create mode 100644 src/pocketmine/event/HandlerListManager.php diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 7d6b1287c7..f8c673eee0 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -34,7 +34,7 @@ use pocketmine\command\ConsoleCommandSender; use pocketmine\command\PluginIdentifiableCommand; use pocketmine\command\SimpleCommandMap; use pocketmine\entity\EntityFactory; -use pocketmine\event\HandlerList; +use pocketmine\event\HandlerListManager; use pocketmine\event\player\PlayerDataSaveEvent; use pocketmine\event\server\CommandEvent; use pocketmine\event\server\DataPacketBroadcastEvent; @@ -1600,7 +1600,7 @@ class Server{ } $this->getLogger()->debug("Removing event handlers"); - HandlerList::unregisterAll(); + HandlerListManager::global()->unregisterAll(); if($this->asyncPool instanceof AsyncPool){ $this->getLogger()->debug("Shutting down async task worker pool"); diff --git a/src/pocketmine/event/Event.php b/src/pocketmine/event/Event.php index 9e96ccc175..7f1cc4bb5e 100644 --- a/src/pocketmine/event/Event.php +++ b/src/pocketmine/event/Event.php @@ -55,7 +55,7 @@ abstract class Event{ throw new \RuntimeException("Recursive event call detected (reached max depth of " . self::MAX_EVENT_CALL_DEPTH . " calls)"); } - $handlerList = HandlerList::getHandlerListFor(get_class($this)); + $handlerList = HandlerListManager::global()->getListFor(get_class($this)); assert($handlerList !== null, "Called event should have a valid HandlerList"); ++self::$eventCallDepth; diff --git a/src/pocketmine/event/HandlerList.php b/src/pocketmine/event/HandlerList.php index e5fbb81f8f..6d391215f9 100644 --- a/src/pocketmine/event/HandlerList.php +++ b/src/pocketmine/event/HandlerList.php @@ -24,77 +24,11 @@ declare(strict_types=1); namespace pocketmine\event; use pocketmine\plugin\Plugin; -use pocketmine\utils\Utils; use function array_fill_keys; use function in_array; use function spl_object_id; class HandlerList{ - /** - * @var HandlerList[] classname => HandlerList - */ - private static $allLists = []; - - /** - * Unregisters all the listeners - * If a Plugin or Listener is passed, all the listeners with that object will be removed - * - * @param Plugin|Listener|null $object - */ - public static function unregisterAll($object = null) : void{ - if($object instanceof Listener or $object instanceof Plugin){ - foreach(self::$allLists as $h){ - $h->unregister($object); - } - }else{ - foreach(self::$allLists as $h){ - foreach($h->handlerSlots as $key => $list){ - $h->handlerSlots[$key] = []; - } - } - } - } - - /** - * Returns the HandlerList for listeners that explicitly handle this event. - * - * Calling this method also lazily initializes the $classMap inheritance tree of handler lists. - * - * @param string $event - * - * @return null|HandlerList - * @throws \ReflectionException - */ - public static function getHandlerListFor(string $event) : ?HandlerList{ - if(isset(self::$allLists[$event])){ - return self::$allLists[$event]; - } - - $class = new \ReflectionClass($event); - $tags = Utils::parseDocComment((string) $class->getDocComment()); - - if($class->isAbstract() && !isset($tags["allowHandle"])){ - return null; - } - - $super = $class; - $parentList = null; - while($parentList === null && ($super = $super->getParentClass()) !== false){ - // skip $noHandle events in the inheritance tree to go to the nearest ancestor - // while loop to allow skipping $noHandle events in the inheritance tree - $parentList = self::getHandlerListFor($super->getName()); - } - - return new HandlerList($event, $parentList); - } - - /** - * @return HandlerList[] - */ - public static function getHandlerLists() : array{ - return self::$allLists; - } - /** @var string */ private $class; @@ -107,7 +41,6 @@ class HandlerList{ $this->class = $class; $this->handlerSlots = array_fill_keys(EventPriority::ALL, []); $this->parentList = $parentList; - self::$allLists[$this->class] = $this; } /** @@ -155,6 +88,10 @@ class HandlerList{ } } + public function clear() : void{ + $this->handlerSlots = array_fill_keys(EventPriority::ALL, []); + } + /** * @param int $priority * diff --git a/src/pocketmine/event/HandlerListManager.php b/src/pocketmine/event/HandlerListManager.php new file mode 100644 index 0000000000..0097d7a1c4 --- /dev/null +++ b/src/pocketmine/event/HandlerListManager.php @@ -0,0 +1,100 @@ + HandlerList + */ + private $allLists = []; + + /** + * Unregisters all the listeners + * If a Plugin or Listener is passed, all the listeners with that object will be removed + * + * @param Plugin|Listener|null $object + */ + public function unregisterAll($object = null) : void{ + if($object instanceof Listener or $object instanceof Plugin){ + foreach($this->allLists as $h){ + $h->unregister($object); + } + }else{ + foreach($this->allLists as $h){ + $h->clear(); + } + } + } + + /** + * Returns the HandlerList for listeners that explicitly handle this event. + * + * Calling this method also lazily initializes the $classMap inheritance tree of handler lists. + * + * @param string $event + * + * @return null|HandlerList + * @throws \ReflectionException + */ + public function getListFor(string $event) : ?HandlerList{ + if(isset($this->allLists[$event])){ + return $this->allLists[$event]; + } + + $class = new \ReflectionClass($event); + $tags = Utils::parseDocComment((string) $class->getDocComment()); + + if($class->isAbstract() && !isset($tags["allowHandle"])){ + return null; + } + + $super = $class; + $parentList = null; + while($parentList === null && ($super = $super->getParentClass()) !== false){ + // skip $noHandle events in the inheritance tree to go to the nearest ancestor + // while loop to allow skipping $noHandle events in the inheritance tree + $parentList = $this->getListFor($super->getName()); + } + + return $this->allLists[$event] = new HandlerList($event, $parentList); + } + + /** + * @return HandlerList[] + */ + public function getAll() : array{ + return $this->allLists; + } +} diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index 7dabe5fd99..8c65c98809 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -26,6 +26,7 @@ namespace pocketmine\plugin; use pocketmine\event\Event; use pocketmine\event\EventPriority; use pocketmine\event\HandlerList; +use pocketmine\event\HandlerListManager; use pocketmine\event\Listener; use pocketmine\event\plugin\PluginDisableEvent; use pocketmine\event\plugin\PluginEnableEvent; @@ -465,7 +466,7 @@ class PluginManager{ $plugin->onEnableStateChange(false); $plugin->getScheduler()->shutdown(); - HandlerList::unregisterAll($plugin); + HandlerListManager::global()->unregisterAll($plugin); $permManager = PermissionManager::getInstance(); foreach($plugin->getDescription()->getPermissions() as $perm){ $permManager->removePermission($perm); @@ -594,7 +595,7 @@ class PluginManager{ * @return HandlerList */ private function getEventListeners(string $event) : HandlerList{ - $list = HandlerList::getHandlerListFor($event); + $list = HandlerListManager::global()->getListFor($event); if($list === null){ throw new PluginException("Abstract events not declaring @allowHandle cannot be handled (tried to register listener for $event)"); } From 1156d5bdba46f118d9a8db7217080b89c53cf54d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 30 Jun 2019 14:51:44 +0100 Subject: [PATCH 1024/3224] batch optimize imports --- src/pocketmine/block/Lava.php | 2 +- .../network/mcpe/handler/ResourcePacksPacketHandler.php | 2 +- .../world/format/io/region/LegacyAnvilChunkTrait.php | 8 ++++---- src/pocketmine/world/format/io/region/RegionLoader.php | 2 +- src/pocketmine/world/generator/biome/BiomeSelector.php | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pocketmine/block/Lava.php b/src/pocketmine/block/Lava.php index 7b3a2a0745..48899e7efc 100644 --- a/src/pocketmine/block/Lava.php +++ b/src/pocketmine/block/Lava.php @@ -27,10 +27,10 @@ use pocketmine\entity\Entity; use pocketmine\event\entity\EntityCombustByBlockEvent; use pocketmine\event\entity\EntityDamageByBlockEvent; use pocketmine\event\entity\EntityDamageEvent; +use pocketmine\math\Facing; use pocketmine\world\sound\BucketEmptyLavaSound; use pocketmine\world\sound\BucketFillLavaSound; use pocketmine\world\sound\Sound; -use pocketmine\math\Facing; class Lava extends Liquid{ diff --git a/src/pocketmine/network/mcpe/handler/ResourcePacksPacketHandler.php b/src/pocketmine/network/mcpe/handler/ResourcePacksPacketHandler.php index 95ac7a2c6e..a6b3bd9ae9 100644 --- a/src/pocketmine/network/mcpe/handler/ResourcePacksPacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/ResourcePacksPacketHandler.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; -use function count; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\ResourcePackChunkDataPacket; use pocketmine\network\mcpe\protocol\ResourcePackChunkRequestPacket; @@ -34,6 +33,7 @@ use pocketmine\network\mcpe\protocol\ResourcePackStackPacket; use pocketmine\resourcepacks\ResourcePack; use pocketmine\resourcepacks\ResourcePackManager; use function ceil; +use function count; use function implode; use function strpos; use function substr; diff --git a/src/pocketmine/world/format/io/region/LegacyAnvilChunkTrait.php b/src/pocketmine/world/format/io/region/LegacyAnvilChunkTrait.php index 8a82aa8db7..18ae27719d 100644 --- a/src/pocketmine/world/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/pocketmine/world/format/io/region/LegacyAnvilChunkTrait.php @@ -23,15 +23,15 @@ declare(strict_types=1); namespace pocketmine\world\format\io\region; -use pocketmine\world\format\Chunk; -use pocketmine\world\format\io\ChunkUtils; -use pocketmine\world\format\io\exception\CorruptedChunkException; -use pocketmine\world\format\SubChunk; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntArrayTag; use pocketmine\nbt\tag\ListTag; +use pocketmine\world\format\Chunk; +use pocketmine\world\format\io\ChunkUtils; +use pocketmine\world\format\io\exception\CorruptedChunkException; +use pocketmine\world\format\SubChunk; /** * Trait containing I/O methods for handling legacy Anvil-style chunks. diff --git a/src/pocketmine/world/format/io/region/RegionLoader.php b/src/pocketmine/world/format/io/region/RegionLoader.php index 492a1110ad..c782b2e6ab 100644 --- a/src/pocketmine/world/format/io/region/RegionLoader.php +++ b/src/pocketmine/world/format/io/region/RegionLoader.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace pocketmine\world\format\io\region; +use pocketmine\utils\Binary; use pocketmine\world\format\ChunkException; use pocketmine\world\format\io\exception\CorruptedChunkException; -use pocketmine\utils\Binary; use function ceil; use function chr; use function fclose; diff --git a/src/pocketmine/world/generator/biome/BiomeSelector.php b/src/pocketmine/world/generator/biome/BiomeSelector.php index 28e2fff14c..843d520b2b 100644 --- a/src/pocketmine/world/generator/biome/BiomeSelector.php +++ b/src/pocketmine/world/generator/biome/BiomeSelector.php @@ -23,10 +23,10 @@ declare(strict_types=1); namespace pocketmine\world\generator\biome; +use pocketmine\utils\Random; use pocketmine\world\biome\Biome; use pocketmine\world\biome\UnknownBiome; use pocketmine\world\generator\noise\Simplex; -use pocketmine\utils\Random; abstract class BiomeSelector{ /** @var Simplex */ From b1ef1026eeaf6405e9179e8fa7622c296899fb2a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 1 Jul 2019 15:24:45 +0100 Subject: [PATCH 1025/3224] WorldManager: Use the world's own logger to report tick overload --- src/pocketmine/world/WorldManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/world/WorldManager.php b/src/pocketmine/world/WorldManager.php index c9e881ad4d..f7604dc592 100644 --- a/src/pocketmine/world/WorldManager.php +++ b/src/pocketmine/world/WorldManager.php @@ -375,7 +375,7 @@ class WorldManager{ $tickMs = (microtime(true) - $worldTime) * 1000; $world->tickRateTime = $tickMs; if($tickMs >= 50){ - $this->server->getLogger()->debug(sprintf("World \"%s\" took too long to tick: %gms (%g ticks)", $world->getDisplayName(), $tickMs, round($tickMs / 50, 2))); + $world->getLogger()->debug(sprintf("Tick took too long: %gms (%g ticks)", $tickMs, round($tickMs / 50, 2))); } } From 601ba4264d8302c02f16242803733129ba168963 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 1 Jul 2019 17:42:18 +0100 Subject: [PATCH 1026/3224] [ci skip] added incomplete changelog for 4.0 --- changelogs/4.0-snapshot.md | 602 +++++++++++++++++++++++++++++++++++++ 1 file changed, 602 insertions(+) create mode 100644 changelogs/4.0-snapshot.md diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md new file mode 100644 index 0000000000..5f03f02cd6 --- /dev/null +++ b/changelogs/4.0-snapshot.md @@ -0,0 +1,602 @@ +# 4.0.0-SNAPSHOT-1907XX (2019-07-XX) + +This major version features substantial changes throughout the core, including significant API changes, new world format support, performance improvements and a network revamp. + +## Core +### General +- A new "plugin greylist" feature has been introduced, which allows whitelisting or blacklisting plugins from loading. +- The `/reload` command has been removed. +- Remote console (RCON) has been removed. The [RconServer](https://github.com/pmmp/RconServer) plugin is provided as a substitute. +- Spawn protection has been removed. The [BasicSpawnProtection](https://github.com/pmmp/BasicSpawnProtection) plugin is provided as a substitute. +- CTRL+C signal handling has been removed. The [PcntlSignalHandler](https://github.com/pmmp/PcntlSignalHandler) plugin is provided as a substitute. +- Player movement anti-cheat has been removed. Its corresponding `pocketmine.yml` setting `player.anti-cheat.allow-movement-cheats` has been removed. +- The `pocketmine_chunkutils` PHP extension has been dropped. +- New PHP extensions are required by this version: + - [ds](https://github.com/php-ds/ext-ds) + - [chunkutils2](https://github.com/pmmp/ext-chunkutils2) + +### World format support +- Modern Minecraft Bedrock world formats are now supported. +- Automatic conversion of deprecated world formats is now implemented. +- The following world formats have been deprecated and will be **automatically converted on load to a new format**: + - `mcregion` + - `anvil` + - `pmanvil` +- 256 build-height is now supported in all worlds (facilitated by automatic conversion). +- Extended blocks are now supported (facilitated by automatic conversion). +- Unsupported world formats no longer causes a crash, but a graceful shutdown instead. +- World corruption no longer causes a crash. + +### Logger revamp +- Many components now have a dedicated logger which automatically adds [prefixes] to their messages. +- Main logger now includes milliseconds in timestamps. + +### Network +This version features substantial changes to the network system, improving coherency, reliability and modularity. + +#### Minecraft Bedrock packet encryption +- This fixes replay attacks where hackers steal and replay player logins. +- A new setting has been added to `pocketmine.yml`: `network.enable-encryption` which is `true` by default. + +#### Packet receive error handling has been overhauled +- Only `BadPacketException` is now caught during packet decode and handling. This requires that all decoding MUST perform proper data error checking. + - Throwing a `BadPacketException` from decoding will now cause players to be kicked with the message `Packet processing error`. + - The disconnect message includes a random hex ID to help server owners identify the problems reported by their players. +- Throwing any other exception will now cause a server crash. `Internal server error` has been removed. +- It is now illegal to send a clientbound packet to the server. Doing so will result in the client being kicked with the message `Unexpected non-serverbound packet`. + +#### New packet handler system +- Packet handlers have been separated from NetworkSession into a dedicated packet handler structure. +- A network session may have exactly 1 handler at a time, which is mutable and may be replaced at any time. This allows packet handling logic to be broken up into multiple stages: + - preventing undefined behaviour when sending wrong packets at the wrong time (they'll now be silently dropped) + - allowing the existence of ephemeral state-specific logic (for example stricter resource packs download checks) +- Packet handlers are now almost entirely absent from `Player` and instead appear in their own dedicated units. +- Almost all game logic that was previously locked up inside packet handlers in `Player` has been extracted into new API methods. See Player API changes for details. + +## API +### General +- Most places which previously allowed `callable` now only allow `\Closure`. This is because closures have more consistent behaviour and are more performant. +- `void` and `?nullable` parameter and return types have been applied in many places. +- Everything in the `pocketmine\metadata` namespace and related implementations have been removed. + +### Block +- Blocks with IDs >= 256 are now supported. +- Block state and variant metadata have been separated. + - Variant is considered an extension of ID and is immutable. + - `Block->setDamage()` has been removed. `Block->readStateFromData()` is now used for state deserialization. +- Tile entities are now created and deleted automatically when `World->setBlock()` is used with a block that requires a tile entity. +- Some tile entities' API has been exposed on their corresponding `Block` classes, with the tile entity classes being deprecated. +- The `pocketmine\tile` namespace has been relocated to `pocketmine\block\tile`. +- `Block->recalculateBoundingBox()` and `Block->recalculateCollisionBoxes()` are now expected to return AABBs relative to `0,0,0` instead of their own position. +- Block break-info has been extracted into a new dynamic `BlockBreakInfo` unit. The following methods have been moved: + - `Block->getBlastResistance()` -> `BlockBreakInfo->getBlastResistance()` + - `Block->getBreakTime()` -> `BlockBreakInfo->getBreakTime()` + - `Block->getHardness()` -> `BlockBreakInfo->getHardness()` + - `Block->getToolHarvestLevel()` -> `BlockBreakInfo->getToolHarvestLevel()` + - `Block->getToolType()` -> `BlockBreakInfo->getToolType()` + - `Block->isBreakable()` -> `BlockBreakInfo->isBreakable()` + - `Block->isCompatibleWithTool()` -> `BlockBreakInfo->isToolCompatible()` +- The following API methods have been added: + - `Block->asItem()`: returns an itemstack corresponding to the block + - `Block->isSameState()`: returns whether the block is the same as the parameter, including state information + - `Block->isSameType()`: returns whether the block is the same as the parameter, without state information +- The following hooks have been added: + - `Block->onAttack()`: called when a player in survival left-clicks the block to try to start breaking it + - `Block->onPostPlace()`: called directly after placement in the world, handles things like rail connections and chest pairing +- The following API methods have been renamed: + - `Block->getDamage()` -> `Block->getMeta()` + - `Block->onActivate()` -> `Block->onInteract()` + - `Block->onEntityCollide()` -> `Block->onEntityInside()` +- The following API methods have changed signatures: + - `Block->onInteract()` now has the signature `onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool` +- The following API methods have been removed: + - `Block->canPassThrough()` + - `Block->setDamage()` +- The following classes have been renamed: + - `BlockIds` -> `BlockLegacyIds` + - `CobblestoneWall` -> `Wall` + - `NoteBlock` -> `Note` + - `SignPost` -> `Sign` + - `StandingBanner` -> `Banner` +- The following classes have been removed: + - `Bricks` + - `BurningFurnace` + - `CobblestoneStairs` + - `Dandelion` + - `DoubleSlab` + - `DoubleStoneSlab` + - `EndStone` + - `GlowingRedstoneOre` + - `GoldOre` + - `Gold` + - `IronDoor` + - `IronOre` + - `IronTrapdoor` + - `Iron` + - `Lapis` + - `NetherBrickFence` + - `NetherBrickStairs` + - `Obsidian` + - `PurpurStairs` + - `Purpur` + - `QuartzStairs` + - `Quartz` + - `RedSandstoneStairs` + - `RedSandstone` + - `SandstoneStairs` + - `Sandstone` + - `StainedClay` + - `StainedGlassPane` + - `StainedGlass` + - `StoneBrickStairs` + - `StoneBricks` + - `StoneSlab2` + - `StoneSlab` + - `Stone` + - `WallBanner` + - `WallSign` + - `Wood2` + +### Command +- The following classes have been removed: + - `RemoteConsoleCommandSender` +- The following API methods have signature changes: + - `Command->setPermission()` argument is now mandatory (but still nullable). + - `CommandSender->setScreenLineHeight()` argument is now mandatory (but still nullable). + +### Entity +#### General +- The following API methods have been added: + - `ItemEntity->getDespawnDelay()` + - `ItemEntity->setDespawnDelay()` +- The following methods have signature changes: + - `Entity->entityBaseTick()` is now `protected`. + - `Entity->move()` is now `protected`. +- The following classes have been removed: + - `Creature` + - `Damageable` + - `Monster` + - `NPC` + - `Rideable` + - `Vehicle` +- `Skin` now throws exceptions on creation if given invalid data. + +#### Effect +- All `Effect` related classes have been moved to the `pocketmine\entity\effect` namespace. +- Effect functionality embedded in the `Effect` class has been separated out into several classes. The following classes have been added: + - `AbsorptionEffect` + - `HealthBoostEffect` + - `HungerEffect` + - `InstantDamageEffect` + - `InstantEffect` + - `InstantHealthEffect` + - `InvisibilityEffect` + - `LevitationEffect` + - `PoisonEffect` + - `RegenerationEffect` + - `SaturationEffect` + - `SlownessEffect` + - `SpeedEffect` + - `WitherEffect` +- Negative effect amplifiers are now explicitly disallowed due to undefined behaviour they created. +- The following API methods have been renamed: + - `Effect::registerEffect()` -> `Effect::register()` + - `Effect::getEffect()` -> `Effect::get()` + - `Effect::getEffectByName()` -> `Effect::fromString()` +- Static getter methods for all registered enchantment types have been added. `Effect::getEffect(Effect::WHATEVER)` should be replaced by `Effect::WHATEVER()`. + +#### Removal of runtime entity NBT +- Entities no longer keep their NBT alive at runtime. + - `Entity->namedtag` has been removed. + - `Entity->saveNBT()` now returns a newly created `CompoundTag` instead of modifying the previous one in-place. + - `Entity->initEntity()` now accepts a `CompoundTag` parameter. + +#### Entity creation +- Entity class overriding is now explicitly supported, without needing to touch save IDs. + - Entity classes can be overridden using `EntityFactory::override()`. The provided replacement class **must** be a subclass of the existing class. If the existing class isn't there, an exception will be thrown. + - Attempting to register an entity to a save ID that is already registered will now cause an exception to be thrown. +- Registering entities will now throw exceptions on error cases instead of returning `false`. +- Entity creation has now been split into two paths: + - `EntityFactory::create()`: Creates an entity by the given class. This accepts arguments to be passed to the entity constructor. This function is guaranteed to return an entity which is an instanceof the given class. + - `EntityFactory::createFromData()`: Creates an entity from save data. This may return any `Entity` class or `NULL`. This function is internal and shouldn't be used by plugins. +- It is no longer possible to directly create an entity by save ID. This is discouraged because save IDs are internal and format-dependent. +- The following API methods have been moved: + - `Entity::registerEntity()` -> `EntityFactory::register()` + - `Entity::createEntity()` -> `EntityFactory::create()` + - `Entity::getKnownEntityTypes()` -> `EntityFactory::getKnownTypes()` + - `Entity::createBaseNBT()` -> `EntityFactory::createBaseNBT()` +- The following API methods have been removed: + - `Entity->getSaveId()` + +#### WIP removal of entity network metadata +- All network metadata related constants have been removed from the `Entity` class and moved to the protocol layer. It is intended to remove network metadata from the API entirely, but this has not yet been completed. + - `Entity::DATA_FLAG_*` constants have been moved to `pocketmine\network\mcpe\protocol\types\EntityMetadataFlags`. + - `Entity::DATA_TYPE_*` constants have been moved to `pocketmine\network\mcpe\protocol\types\EntityMetadataTypes`. + - `Entity::DATA_*` constants have been moved to `pocketmine\network\mcpe\protocol\types\EntityMetadataProperties`. +- `DataPropertyManager` has been moved to the `pocketmine\network\mcpe\protocol\types` namespace, and as such isn't considered part of the API anymore. + +### Event +#### Internal event system no longer depends on `Listener`s +- The internal event processing system no longer depends on `Listener` objects. Arbitrary closures can now be used, provided that they satisfy the standard requirements to be a handler. + - This change improves performance of event handler calling by approximately 15%. This does not include anything plugins are doing. + - The following classes have been removed: + - `pocketmine\plugin\EventExecutor` + - `pocketmine\plugin\MethodEventExecutor` + - `RegisteredListener->__construct()` now requires `Closure` instead of `Listener, EventExecutor` as the leading parameters. + - `RegisteredListener->getListener()` has been removed. + +#### Default cancelled handling behaviour has changed +- Handler functions will now **not receive cancelled events by default**. This is a **silent BC break**, i.e. it won't raise errors, but it might cause bugs. +- `@ignoreCancelled` is now no longer respected. +- `@handleCancelled` has been added. This allows opting _into_ receiving cancelled events (it's the opposite of `@ignoreCancelled`). + +#### `PlayerPreLoginEvent` changes +- The `Player` object no longer exists at this phase of the login. Instead, a `PlayerInfo` object is provided, along with connection information. +- Ban, server-full and whitelist checks are now centralized to `PlayerPreLoginEvent`. It's no longer necessary (or possible) to intercept `PlayerKickEvent` to handle these types of disconnects. + - Multiple kick reasons may be set to ensure that the player is still removed if there are other reasons for them to be disconnected and one of them is cleared. For example, if a player is banned and the server is full, clearing the ban flag will still cause the player to be disconnected because the server is full. + - Plugins may set custom kick reasons. Any custom reason has absolute priority. + - If multiple flags are set, the kick message corresponding to the highest priority reason will be shown. The priority (as of this snapshot) is as follows: + - Custom (highest priority) + - Server full + - Whitelisted + - Banned + - The `PlayerPreLoginEvent::KICK_REASON_PRIORITY` constant contains a list of kick reason priorities, highest first. +- The following constants have been added: + - `PlayerPreLoginEvent::KICK_REASON_PLUGIN` + - `PlayerPreLoginEvent::KICK_REASON_SERVER_FULL` + - `PlayerPreLoginEvent::KICK_REASON_SERVER_WHITELISTED` + - `PlayerPreLoginEvent::KICK_REASON_BANNED` + - `PlayerPreLoginEvent::KICK_REASON_PRIORITY`: ordered list of kick reason priorities, highest first +- The following API methods have been added: + - `PlayerPreLoginEvent->clearAllKickReasons()` + - `PlayerPreLoginEvent->clearKickReason()` + - `PlayerPreLoginEvent->getFinalKickMessage()`: the message to be shown to the player with the current reason list in place + - `PlayerPreLoginEvent->getIp()` + - `PlayerPreLoginEvent->getKickReasons()`: returns an array of flags indicating kick reasons, must be empty to allow joining + - `PlayerPreLoginEvent->getPlayerInfo()` + - `PlayerPreLoginEvent->getPort()` + - `PlayerPreLoginEvent->isAllowed()` + - `PlayerPreLoginEvent->isAuthRequired()`: whether XBL authentication will be enforced + - `PlayerPreLoginEvent->isKickReasonSet()` + - `PlayerPreLoginEvent->setAuthRequired()` + - `PlayerPreLoginEvent->setKickReason()` +- The following API methods have been changed: + - `PlayerPreLoginEvent->getKickMessage()` now has the signature `getKickMessage(int $flag) : ?string` +- The following API methods have been removed: + - `PlayerPreLoginEvent->setKickMessage()` + - `PlayerPreLoginEvent->getPlayer()` + +#### Other changes +- Disconnecting players during events no longer crashes the server (although it might cause other side effects). +- `PlayerKickEvent` is no longer fired for disconnects that occur before the player completes the initial login sequence (i.e. completing downloading resource packs). +- Cancellable events must now implement `CancellableTrait` to get the cancellable components needed to satisfy interface requirements. +- `PlayerInteractEvent` is no longer fired when a player activates an item. This fixes the age-old complaint of `PlayerInteractEvent` firing multiple times when interacting once. The following constants have been removed: + - `PlayerInteractEvent::LEFT_CLICK_AIR` + - `PlayerInteractEvent::RIGHT_CLICK_AIR` + - `PlayerInteractEvent::PHYSICAL` +- The following events have been added: + - `PlayerItemUseEvent`: player activating their held item, for example to throw it. + - `BlockTeleportEvent`: block teleporting, for example dragon egg when attacked. +- The following events have been removed: + - `EntityArmorChangeEvent` + - `EntityInventoryChangeEvent` + - `EntityLevelChangeEvent` - `EntityTeleportEvent` with world checks should be used instead. + - `NetworkInterfaceCrashEvent` + - `PlayerCheatEvent` + - `PlayerIllegalMoveEvent` +- The following API methods have been added: + - `EntityDeathEvent->getXpDropAmount()` + - `EntityDeathEvent->setXpDropAmount()` + - `PlayerDeathEvent->getXpDropAmount()` + - `PlayerDeathEvent->setXpDropAmount()` +- The following API methods have been removed: + - `PlayerPreLoginEvent->getPlayer()` +- The following API methods have been moved: + - `Event->isCancelled()` -> `CancellableTrait->isCancelled()`: this was a stub which threw `BadMethodCallException` if the class didn't implement `Cancellable`; now this is simply not available on non-cancellable events + - `Event->setCancelled()` -> `CancellableTrait->setCancelled()` + - `HandlerList::unregisterAll()` -> `HandlerListManager->unregisterAll()` + - `HandlerList::getHandlerListFor()` -> `HandlerListManager->getListFor()` + - `HandlerList::getHandlerLists()` -> `HandlerListManager->getAll()` +- The following classes have been moved: + - `pocketmine\plugin\RegisteredListener` -> `pocketmine\event\RegisteredListener` + +### Inventory + +### Item +#### General +- `ProjectileItem->getProjectileEntityType()` now returns a ::class constant instead of an entity save ID. +- The following API methods have been removed: + - `Item->getNamedTagEntry()` + - `Item->removeNamedTagEntry()` + - `Item->setDamage()`: "Damage" is now immutable for all items except `Durable` descendents. + - `Item->setNamedTagEntry()` + +- The following methods have been moved to `pocketmine\inventory\CreativeInventory`: + - `Item::addCreativeItem()` -> `CreativeInventory::add()` + - `Item::clearCreativeItems()` -> `CreativeInventory::clear()` + - `Item::getCreativeItemIndex()` -> `CreativeInventory::getItemIndex()` + - `Item::getCreativeItems()` -> `CreativeInventory::getAll()` + - `Item::initCreativeItems()` -> `CreativeInventory::init()` + - `Item::isCreativeItem()` -> `CreativeInventory::contains()` + - `Item::removeCreativeItem()` -> `CreativeInventory::remove()` + +#### Enchantment +- The following API methods have been renamed: + - `Enchantment::registerEnchantment()` -> `Enchantment::register()` + - `Enchantment::getEnchantment()` -> `Enchantment::get()` + - `Enchantment::getEnchantmentByName()` -> `Enchantment::fromString()` +- Static getter methods for all registered enchantment types have been added. `Enchantment::getEnchantment(Enchantment::WHATEVER)` should be replaced by `Enchantment::WHATEVER()`. + +### Lang +- The following classes have been renamed: + - `BaseLang` -> `Language` +- `LanguageNotFoundException` has been added. This is thrown when trying to construct a `Language` which doesn't exist in the server files. + + +### Network +- The following fields have been removed: + - `Network::$BATCH_THRESHOLD` +- The following classes have been renamed: + - `SourceInterface` -> `NetworkInterface` + - `AdvancedSourceInterface` -> `AdvancedNetworkInterface` +- The following classes have been moved: + - `CompressBatchedTask` -> `mcpe\CompressBatchTask` + - `level\format\io\ChunkRequestTask` -> `mcpe\ChunkRequestTask` + - `mcpe\RakLibInterface` -> `mcpe\raklib\RakLibInterface` +- The following classes have been removed: + - `mcpe\PlayerNetworkSessionAdapter` +- The following methods have been removed: + - `NetworkInterface->putPacket()` + - `NetworkInterface->close()` + - `NetworkInterface->emergencyShutdown()` +- `NetworkInterface` now represents a more generic interface to be implemented by any network component, as opposed to specifically a player network interface. +- Everything under the `rcon` subnamespace has been removed. +- `upnp\UPnP` has significant changes. It's now a network component instead of a pair of static methods. + +### Permission +- Added `PermissibleDelegateTrait` to reduce boilerplate for users of `PermissibleBase`. This trait is used by `ConsoleCommandSender` and `Player`. +- The following API methods have been moved: + - `Permission::getByName()` -> `PermissionParser::defaultFromString()` + - `Permission::loadPermissions()` -> `PermissionParser::loadPermissions()` + - `Permission::loadPermission()` -> `PermissionParser::loadPermission()` +- The following API methods have been added: + - `PermissionParser::emitPermissions()` +- The following API methods have changes: + - `PermissionParser::defaultFromString()` now throws `InvalidArgumentException` on unknown values. + +### Player +- The following classes have moved to the new `pocketmine\player` namespace: + - `Achievement` + - `GameMode` + - `IPlayer` + - `OfflinePlayer` + - `PlayerInfo` + - `Player` +- The following constants have been removed: + - `Player::SURVIVAL` - use `GameMode::SURVIVAL()` + - `Player::CREATIVE` - use `GameMode::CREATIVE()` + - `Player::ADVENTURE` - use `GameMode::ADVENTURE()` + - `Player::SPECTATOR` - use `GameMode::SPECTATOR()` + - `Player::VIEW` - use `GameMode::SPECTATOR()` +- (almost) all packet handlers have been removed from `Player`. They are now encapsulated within the network layer. +- The following API methods have been added: + - `Player->attackBlock()`: attack (left click) the target block, e.g. to start destroying it (survival) + - `Player->attackEntity()`: melee-attack (left click) the target entity (if within range) + - `Player->breakBlock()`: destroy the target block in the current world (immediately) + - `Player->consumeHeldItem()`: consume the previously activated item, e.g. eating food + - `Player->continueBreakBlock()`: punch the target block during destruction in survival, advancing break animation and creating particles + - `Player->hasFiniteResources()` + - `Player->interactBlock()`: interact (right click) the target block in the current world + - `Player->interactEntity()`: interact (right click) the target entity, e.g. to apply a nametag (not implemented yet) + - `Player->pickBlock()`: picks (mousewheel click) the target block in the current world + - `Player->releaseHeldItem()`: release the previously activated item, e.g. shooting a bow + - `Player->selectHotbarSlot()`: select the specified hotbar slot + - `Player->stopBreakBlock()`: cease attacking a previously attacked block + - `Player->toggleFlight()`: tries to start / stop flying (fires events, may be cancelled) + - `Player->updateNextPosition()`: sets the player's next attempted move location (fires events, may be cancelled) + - `Player->useHeldItem()`: activate the held item, e.g. throwing a snowball +- The following API methods have been removed: + - `Player->addActionBarMessage()`: replaced by `sendActionBarMessage()` + - `Player->addSubTitle()`: replaced by `sendSubTitle()` + - `Player->addTitle()`: replaced by `sendTitle()` + - `Player->getAddress()`: replaced by `NetworkSession->getIp()` + - `Player->getPing()`: moved to `NetworkSession` + - `Player->getPort()`: moved to `NetworkSession` + - `Player->updatePing()`: moved to `NetworkSession` + + +### Plugin +- API version checks are now more strict. It is no longer legal to declare multiple minimum versions on the same major version. Doing so will now cause the plugin to fail to load with the message `Multiple minimum API versions found for some major versions`. +- `plugin.yml` YAML commands loading is now internalized inside `PluginBase`. +- `PluginManager->registerEvent()` now has a simpler signature: `registerEvent(string $event, \Closure $handler, int $priority, Plugin $plugin, bool $handleCancelled = false)`. The provided closure must accept the specified event class as its only parameter. See [Event API changes](#event) for more details. +- The following interface requirements have been removed: + - `Plugin->onEnable()`: this is now internalized inside `PluginBase` + - `Plugin->onDisable()`: same as above + - `Plugin->onLoad()`: same as above + - `Plugin` no longer extends `CommandExecutor`. This means that `Plugin` implementations don't need to implement `onCommand()` anymore. +- The following hook methods have changed visibility: + - `PluginBase->onEnable()` changed from `public` to `protected` + - `PluginBase->onDisable()` changed from `public` to `protected` + - `PluginBase->onLoad()` changed from `public` to `protected` +- The following hook methods have been renamed: + - `Plugin->setEnabled()` -> `Plugin->onEnableStateChange()`. This change was made to force plugin developers misusing this hook to stop, and to give it a name that better describes what it does. +- The following (deprecated) API methods have been removed: + - `PluginManager->callEvent()`: use `Event->call()` instead + - `PluginManager->addPermission()`: use `PermissionManager` instead + - `PluginManager->getDefaultPermSubscriptions()`: use `PermissionManager` instead + - `PluginManager->getDefaultPermissions()`: use `PermissionManager` instead + - `PluginManager->getPermission()`: use `PermissionManager` instead + - `PluginManager->getPermissionSubscriptions()`: use `PermissionManager` instead + - `PluginManager->getPermissions()`: use `PermissionManager` instead + - `PluginManager->recalculatePermissionDefaults()`: use `PermissionManager` instead + - `PluginManager->removePermission()`: use `PermissionManager` instead + - `PluginManager->subscribeToDefaultPerms()`: use `PermissionManager` instead + - `PluginManager->subscribeToPermission()`: use `PermissionManager` instead + - `PluginManager->unsubscribeFromDefaultPerms()`: use `PermissionManager` instead + - `PluginManager->unsubscribeFromPermission()`: use `PermissionManager` instead +- It is no longer permitted to throw exceptions from `PluginBase->onEnable()` or `PluginBase->onLoad()`. Doing so will now cause the server to crash. + +### Scheduler +#### Thread-local storage for AsyncTasks +- TLS has been completely rewritten in this release to be self contained, more robust and easier to use. +- Now behaves more like simple properties. `storeLocal()` writes, `fetchLocal()` reads. +- Self-contained and doesn't depend on the async pool to clean up after it. +- Values are automatically removed from storage when the `AsyncTask` is garbage-collected, just like a regular property. +- Supports storing multiple values, differentiated by string names. +- `fetchLocal()` can now be used multiple times. It no longer deletes the stored value. +- The following methods have been removed: + - `AsyncTask->peekLocal()`: use `fetchLocal()` instead +- The following methods have signature changes: + - `AsyncTask->storeLocal()` now has the signature `storeLocal(string $key, mixed $complexData) : void` + - `AsyncTask->fetchLocal()` now has the signature `fetchLocal(string $key) : mixed` + +#### Other changes +- `AsyncPool` uses a new, significantly more performant algorithm for task collection. +- `BulkCurlTask` has had the `$complexData` constructor parameter removed. +- `pocketmine\Collectable` has been removed, and is no longer extended by `AsyncTask`. +- The following hooks have been added: + - `AsyncTask->onError()`: called on the main thread when an uncontrolled error was detected in the async task, such as a memory failure +- The following hooks have signature changes: + - `AsyncTask->onCompletion()` no longer accepts a `Server` parameter, and has a `void` return type. + - `AsyncTask->onProgressUpdate()` no longer accepts a `Server` parameter, and has a `void` return type. +- The following API methods have been removed: + - `AsyncTask->getFromThreadStore()`: use `AsyncTask->worker->getFromThreadStore()` + - `AsyncTask->removeFromThreadStore()`: use `AsyncTask->worker->removeFromThreadStore()` + - `AsyncTask->saveToThreadStore()`: use `AsyncTask->worker->saveToThreadStore()` + +### Server +- The following API methods have been removed: + - `reloadWhitelist()` + - `getLevelMetadata()` + - `getPlayerMetadata()` + - `getEntityMetadata()` + - `getDefaultGamemode()` + - `getLoggedInPlayers()` + - `onPlayerLogout()` + - `addPlayer()` + - `removePlayer()` + - `reload()` + - `getSpawnRadius()` + - `enablePlugin()` + - `disablePlugin()` + - `getGamemodeString()` - replaced by `pocketmine\player\GameMode->getTranslationKey()` + - `getGamemodeName()` - replaced by `pocketmine\player\GameMode->name()` + - `getGamemodeFromString()` - replaced by `GameMode::fromString()` +- The following API methods have changed: + - `getOfflinePlayerData()` no longer creates data when it doesn't exist. + +### Level / World +#### General +- All references to `Level` in the context of "world" have been changed to `World`. + - The `pocketmine\level` namespace has been renamed to `pocketmine\world` + - All classes containing the world `Level` in the name in the "world" context have been changed to `World`. + - `Position->getLevel()` has been renamed to `Position->getWorld()`, and `Position->level` has been renamed to `Position->world`. +- Extracted a `WorldManager` unit from `Server` + - `Server->findEntity()` -> `WorldManager->findEntity()` + - `Server->generateLevel()` -> `WorldManager->generateWorld()` + - `Server->getAutoSave()` -> `WorldManager->getAutoSave()` + - `Server->getDefaultLevel()` -> `WorldManager->getDefaultWorld()` + - `Server->getLevel()` -> `WorldManager->getWorld()` + - `Server->getLevelByName()` -> `WorldManager->getWorldByName()` + - `Server->getLevels()` -> `WorldManager->getWorlds()` + - `Server->isLevelGenerated()` -> `WorldManager->isWorldGenerated()` + - `Server->isLevelLoaded()` -> `WorldManager->isWorldLoaded()` + - `Server->loadLevel()` -> `WorldManager->loadWorld()` + - `Server->setAutoSave()` -> `WorldManager->setAutoSave()` + - `Server->setDefaultLevel()` -> `WorldManager->setDefaultWorld()` + - `Server->unloadLevel()` -> `WorldManager->unloadWorld()` +- Added `WorldManager->getAutoSaveTicks()` and `WorldManager->setAutoSaveTicks()` to allow controlling the autosave interval. +- The following classes have been added: + - `BlockTransaction`: allows creating batch commits of block changes with validation conditions - if any block can't be applied, the whole transaction fails to apply. + - `ChunkListenerNoOpTrait`: contains default no-op stubs for chunk listener implementations + - `ChunkListener`: interface allowing subscribing to events happening on a given chunk +- The following API methods have been added: + - `World->registerChunkListener()` + - `World->unregisterChunkListener()` +- The following API methods have been removed: + - `ChunkLoader->getLoaderId()` (now object ID is used) + +- The following API methods have changed signatures: + - `World->addParticle()` now has the signature `addParticle(Vector3 $pos, Particle $particle, ?Player[] $players = null) : void` + - `World->addSound()` now has the signature `addSound(?Vector3 $pos, Sound $sound, ?Player[] $players = null) : void` +- The following API methods have been renamed / moved: + - `Level->getCollisionCubes()` -> `World->getCollisionBoxes()` +- Extracted a unit `pocketmine\world\format\io\FastChunkSerializer` from `Chunk`: + - `Chunk->fastDeserialize()` -> `FastChunkSerializer::deserialize()` + - `Chunk->fastSerialize()` -> `FastChunkSerializer::serialize()` +- A `ChunkListener` interface has been extracted from `ChunkLoader`. The following methods have been moved: + - `ChunkLoader->onBlockChanged()` -> `ChunkListener->onBlockChanged()` + - `ChunkLoader->onChunkChanged()` -> `ChunkListener->onChunkChanged()` + - `ChunkLoader->onChunkLoaded()` -> `ChunkListener->onChunkLoaded()` + - `ChunkLoader->onChunkPopulated()` -> `ChunkListener->onChunkPopulated()` + - `ChunkLoader->onChunkUnloaded()` -> `ChunkListener->onChunkUnloaded()` + +#### Particles +- `pocketmine\world\particle\Particle` no longer extends `pocketmine\math\Vector3`, and has been converted to an interface. +- Added the following `Particle` classes: + - `DragonEggTeleportParticle` + - `PunchBlockParticle` + +#### Sounds +- `pocketmine\world\sound\Sound` no longer extends `pocketmine\math\Vector3`, and has been converted to an interface. +- `Sound->encode()` now accepts `?\pocketmine\math\Vector3`. `NULL` may be passed for sounds which are global. +- Added the following classes: + - `ArrowHitSound` + - `BlockBreakSound` + - `BlockPlaceSound` + - `BowShootSound` + - `BucketEmptyLavaSound` + - `BucketEmptyWaterSound` + - `BucketFillLavaSound` + - `BucketFillWaterSound` + - `ChestCloseSound` + - `ChestOpenSound` + - `EnderChestCloseSound` + - `EnderChestOpenSound` + - `ExplodeSound` + - `FlintSteelSound` + - `ItemBreakSound` + - `NoteInstrument` + - `NoteSound` + - `PaintingPlaceSound` + - `PotionSplashSound` + - `RedstonePowerOffSound` + - `RedstonePowerOnSound` + - `ThrowSound` + - `XpCollectSound` + - `XpLevelUpSound` + +### Utils +- `Terminal::hasFormattingCodes()` no longer auto-detects the availability of formatting codes. Instead it's necessary to use `Terminal::init()` with no parameters to initialize, or `true` or `false` to override. +- `Config->save()` no longer catches exceptions thrown during emitting to disk. +- The following new classes have been added: + - `InternetException` + - `Internet` + - `Process` +- The following API methods have been added: + - `Color::fromRGBA()` + - `Config->getPath()`: returns the path to the config on disk + - `Terminal::write()`: emits a Minecraft-formatted text line without newline + - `Terminal::writeLine()`: emits a Minecraft-formatted text line with newline + - `Utils::recursiveUnlink()`: recursively deletes a directory and its contents +- The following deprecated API redirects have been removed: + - `Utils::execute()`: moved to `Process` + - `Utils::getIP()`: moved to `Internet` + - `Utils::getMemoryUsage()`: moved to `Process` + - `Utils::getRealMemoryUsage()`: moved to `Process` + - `Utils::getThreadCount()`: moved to `Process` + - `Utils::getURL()`: moved to `Internet` + - `Utils::kill()`: moved to `Process` + - `Utils::postURL()`: moved to `Internet` + - `Utils::simpleCurl()`: moved to `Internet` +- The following API fields have been removed / hidden: + - `Utils::$ip` + - `Utils::$online` + - `Utils::$os` +- The following API methods have signature changes: + - `Internet::simpleCurl()` now requires a `Closure` for its `onSuccess` parameter instead of `callable`. +- The following API methods have been removed: + - `Color->toABGR()` + - `Color->toBGRA()` + - `Color::fromABGR()` + - `Utils::getCallableIdentifier()` From 7aa4d974efa3fb00871c9949d98517533a5c671d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 1 Jul 2019 18:47:09 +0100 Subject: [PATCH 1027/3224] move crafting stuff to pocketmine\crafting namespace --- src/pocketmine/Server.php | 2 +- src/pocketmine/block/CraftingTable.php | 2 +- src/pocketmine/block/tile/Furnace.php | 2 +- .../{inventory => crafting}/CraftingGrid.php | 3 ++- .../CraftingManager.php | 2 +- .../CraftingRecipe.php | 2 +- .../{inventory => crafting}/FurnaceRecipe.php | 2 +- .../{inventory => crafting}/MultiRecipe.php | 2 +- .../{inventory => crafting}/ShapedRecipe.php | 2 +- .../ShapelessRecipe.php | 2 +- .../event/inventory/CraftItemEvent.php | 20 +++++++++---------- .../transaction/CraftingTransaction.php | 2 +- .../mcpe/protocol/CraftingDataPacket.php | 6 +++--- src/pocketmine/player/Player.php | 4 ++-- 14 files changed, 27 insertions(+), 26 deletions(-) rename src/pocketmine/{inventory => crafting}/CraftingGrid.php (97%) rename src/pocketmine/{inventory => crafting}/CraftingManager.php (99%) rename src/pocketmine/{inventory => crafting}/CraftingRecipe.php (97%) rename src/pocketmine/{inventory => crafting}/FurnaceRecipe.php (97%) rename src/pocketmine/{inventory => crafting}/MultiRecipe.php (98%) rename src/pocketmine/{inventory => crafting}/ShapedRecipe.php (99%) rename src/pocketmine/{inventory => crafting}/ShapelessRecipe.php (99%) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index f8c673eee0..5e9e96d9d1 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -33,13 +33,13 @@ use pocketmine\command\CommandSender; use pocketmine\command\ConsoleCommandSender; use pocketmine\command\PluginIdentifiableCommand; use pocketmine\command\SimpleCommandMap; +use pocketmine\crafting\CraftingManager; use pocketmine\entity\EntityFactory; use pocketmine\event\HandlerListManager; use pocketmine\event\player\PlayerDataSaveEvent; use pocketmine\event\server\CommandEvent; use pocketmine\event\server\DataPacketBroadcastEvent; use pocketmine\event\server\QueryRegenerateEvent; -use pocketmine\inventory\CraftingManager; use pocketmine\inventory\CreativeInventory; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\ItemFactory; diff --git a/src/pocketmine/block/CraftingTable.php b/src/pocketmine/block/CraftingTable.php index 2a9aec8b43..453483a1b0 100644 --- a/src/pocketmine/block/CraftingTable.php +++ b/src/pocketmine/block/CraftingTable.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\inventory\CraftingGrid; +use pocketmine\crafting\CraftingGrid; use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\player\Player; diff --git a/src/pocketmine/block/tile/Furnace.php b/src/pocketmine/block/tile/Furnace.php index a5c64d4e10..1189cc0454 100644 --- a/src/pocketmine/block/tile/Furnace.php +++ b/src/pocketmine/block/tile/Furnace.php @@ -24,11 +24,11 @@ declare(strict_types=1); namespace pocketmine\block\tile; use pocketmine\block\Furnace as BlockFurnace; +use pocketmine\crafting\FurnaceRecipe; use pocketmine\event\inventory\FurnaceBurnEvent; use pocketmine\event\inventory\FurnaceSmeltEvent; use pocketmine\inventory\CallbackInventoryChangeListener; use pocketmine\inventory\FurnaceInventory; -use pocketmine\inventory\FurnaceRecipe; use pocketmine\inventory\Inventory; use pocketmine\item\Item; use pocketmine\item\ItemFactory; diff --git a/src/pocketmine/inventory/CraftingGrid.php b/src/pocketmine/crafting/CraftingGrid.php similarity index 97% rename from src/pocketmine/inventory/CraftingGrid.php rename to src/pocketmine/crafting/CraftingGrid.php index ea8663dd9a..8812866bfa 100644 --- a/src/pocketmine/inventory/CraftingGrid.php +++ b/src/pocketmine/crafting/CraftingGrid.php @@ -21,8 +21,9 @@ declare(strict_types=1); -namespace pocketmine\inventory; +namespace pocketmine\crafting; +use pocketmine\inventory\BaseInventory; use pocketmine\item\Item; use pocketmine\player\Player; use function max; diff --git a/src/pocketmine/inventory/CraftingManager.php b/src/pocketmine/crafting/CraftingManager.php similarity index 99% rename from src/pocketmine/inventory/CraftingManager.php rename to src/pocketmine/crafting/CraftingManager.php index b643b80699..1196f6aa39 100644 --- a/src/pocketmine/inventory/CraftingManager.php +++ b/src/pocketmine/crafting/CraftingManager.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\inventory; +namespace pocketmine\crafting; use pocketmine\item\Item; use pocketmine\network\mcpe\compression\CompressBatchPromise; diff --git a/src/pocketmine/inventory/CraftingRecipe.php b/src/pocketmine/crafting/CraftingRecipe.php similarity index 97% rename from src/pocketmine/inventory/CraftingRecipe.php rename to src/pocketmine/crafting/CraftingRecipe.php index 1ea9d71e74..5a64c43090 100644 --- a/src/pocketmine/inventory/CraftingRecipe.php +++ b/src/pocketmine/crafting/CraftingRecipe.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\inventory; +namespace pocketmine\crafting; use pocketmine\item\Item; diff --git a/src/pocketmine/inventory/FurnaceRecipe.php b/src/pocketmine/crafting/FurnaceRecipe.php similarity index 97% rename from src/pocketmine/inventory/FurnaceRecipe.php rename to src/pocketmine/crafting/FurnaceRecipe.php index 038c885a1a..2fa65a4771 100644 --- a/src/pocketmine/inventory/FurnaceRecipe.php +++ b/src/pocketmine/crafting/FurnaceRecipe.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\inventory; +namespace pocketmine\crafting; use pocketmine\item\Item; diff --git a/src/pocketmine/inventory/MultiRecipe.php b/src/pocketmine/crafting/MultiRecipe.php similarity index 98% rename from src/pocketmine/inventory/MultiRecipe.php rename to src/pocketmine/crafting/MultiRecipe.php index d9e6674648..a44edad1e9 100644 --- a/src/pocketmine/inventory/MultiRecipe.php +++ b/src/pocketmine/crafting/MultiRecipe.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\inventory; +namespace pocketmine\crafting; use pocketmine\utils\UUID; diff --git a/src/pocketmine/inventory/ShapedRecipe.php b/src/pocketmine/crafting/ShapedRecipe.php similarity index 99% rename from src/pocketmine/inventory/ShapedRecipe.php rename to src/pocketmine/crafting/ShapedRecipe.php index 16e46d569b..6f48b3cfe1 100644 --- a/src/pocketmine/inventory/ShapedRecipe.php +++ b/src/pocketmine/crafting/ShapedRecipe.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\inventory; +namespace pocketmine\crafting; use pocketmine\item\Item; use pocketmine\item\ItemFactory; diff --git a/src/pocketmine/inventory/ShapelessRecipe.php b/src/pocketmine/crafting/ShapelessRecipe.php similarity index 99% rename from src/pocketmine/inventory/ShapelessRecipe.php rename to src/pocketmine/crafting/ShapelessRecipe.php index 29e5b3182b..9cecfdf1fe 100644 --- a/src/pocketmine/inventory/ShapelessRecipe.php +++ b/src/pocketmine/crafting/ShapelessRecipe.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\inventory; +namespace pocketmine\crafting; use pocketmine\item\Item; use function array_map; diff --git a/src/pocketmine/event/inventory/CraftItemEvent.php b/src/pocketmine/event/inventory/CraftItemEvent.php index 71ff4a1cb5..126e14a900 100644 --- a/src/pocketmine/event/inventory/CraftItemEvent.php +++ b/src/pocketmine/event/inventory/CraftItemEvent.php @@ -23,10 +23,10 @@ declare(strict_types=1); namespace pocketmine\event\inventory; +use pocketmine\crafting\CraftingRecipe; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\event\Event; -use pocketmine\inventory\CraftingRecipe; use pocketmine\inventory\transaction\CraftingTransaction; use pocketmine\item\Item; use pocketmine\player\Player; @@ -36,7 +36,7 @@ class CraftItemEvent extends Event implements Cancellable{ /** @var CraftingTransaction */ private $transaction; - /** @var CraftingRecipe */ + /** @var \pocketmine\crafting\CraftingRecipe */ private $recipe; /** @var int */ private $repetitions; @@ -46,13 +46,13 @@ class CraftItemEvent extends Event implements Cancellable{ private $outputs; /** - * @param CraftingTransaction $transaction - * @param CraftingRecipe $recipe - * @param int $repetitions - * @param Item[] $inputs - * @param Item[] $outputs + * @param CraftingTransaction $transaction + * @param \pocketmine\crafting\CraftingRecipe $recipe + * @param int $repetitions + * @param Item[] $inputs + * @param Item[] $outputs */ - public function __construct(CraftingTransaction $transaction, CraftingRecipe $recipe, int $repetitions, array $inputs, array $outputs){ + public function __construct(CraftingTransaction $transaction, \pocketmine\crafting\CraftingRecipe $recipe, int $repetitions, array $inputs, array $outputs){ $this->transaction = $transaction; $this->recipe = $recipe; $this->repetitions = $repetitions; @@ -72,9 +72,9 @@ class CraftItemEvent extends Event implements Cancellable{ /** * Returns the recipe crafted. * - * @return CraftingRecipe + * @return \pocketmine\crafting\CraftingRecipe */ - public function getRecipe() : CraftingRecipe{ + public function getRecipe() : \pocketmine\crafting\CraftingRecipe{ return $this->recipe; } diff --git a/src/pocketmine/inventory/transaction/CraftingTransaction.php b/src/pocketmine/inventory/transaction/CraftingTransaction.php index c414d23608..ab9545f9a8 100644 --- a/src/pocketmine/inventory/transaction/CraftingTransaction.php +++ b/src/pocketmine/inventory/transaction/CraftingTransaction.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\inventory\transaction; +use pocketmine\crafting\CraftingRecipe; use pocketmine\event\inventory\CraftItemEvent; -use pocketmine\inventory\CraftingRecipe; use pocketmine\item\Item; use pocketmine\network\mcpe\protocol\ContainerClosePacket; use pocketmine\network\mcpe\protocol\types\ContainerIds; diff --git a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php b/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php index c001f28a7b..eab5be2696 100644 --- a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php @@ -26,9 +26,9 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\inventory\FurnaceRecipe; -use pocketmine\inventory\ShapedRecipe; -use pocketmine\inventory\ShapelessRecipe; +use pocketmine\crafting\FurnaceRecipe; +use pocketmine\crafting\ShapedRecipe; +use pocketmine\crafting\ShapelessRecipe; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\network\BadPacketException; diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 34316e2dd5..39f992670a 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -28,6 +28,7 @@ use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\block\UnknownBlock; use pocketmine\command\CommandSender; +use pocketmine\crafting\CraftingGrid; use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\Entity; @@ -67,7 +68,6 @@ use pocketmine\event\player\PlayerToggleSprintEvent; use pocketmine\event\player\PlayerTransferEvent; use pocketmine\form\Form; use pocketmine\form\FormValidationException; -use pocketmine\inventory\CraftingGrid; use pocketmine\inventory\Inventory; use pocketmine\inventory\PlayerCursorInventory; use pocketmine\item\Consumable; @@ -183,7 +183,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, protected $permanentWindows = []; /** @var PlayerCursorInventory */ protected $cursorInventory; - /** @var CraftingGrid */ + /** @var \pocketmine\crafting\CraftingGrid */ protected $craftingGrid = null; /** @var int */ From b90be8dc5f9f19115ef1b135f2ad274fad09c747 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 1 Jul 2019 18:49:07 +0100 Subject: [PATCH 1028/3224] fix PhpStorm's screwups --- .../event/inventory/CraftItemEvent.php | 18 +++++++++--------- src/pocketmine/player/Player.php | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/pocketmine/event/inventory/CraftItemEvent.php b/src/pocketmine/event/inventory/CraftItemEvent.php index 126e14a900..54c6cb5e10 100644 --- a/src/pocketmine/event/inventory/CraftItemEvent.php +++ b/src/pocketmine/event/inventory/CraftItemEvent.php @@ -36,7 +36,7 @@ class CraftItemEvent extends Event implements Cancellable{ /** @var CraftingTransaction */ private $transaction; - /** @var \pocketmine\crafting\CraftingRecipe */ + /** @var CraftingRecipe */ private $recipe; /** @var int */ private $repetitions; @@ -46,13 +46,13 @@ class CraftItemEvent extends Event implements Cancellable{ private $outputs; /** - * @param CraftingTransaction $transaction - * @param \pocketmine\crafting\CraftingRecipe $recipe - * @param int $repetitions - * @param Item[] $inputs - * @param Item[] $outputs + * @param CraftingTransaction $transaction + * @param CraftingRecipe $recipe + * @param int $repetitions + * @param Item[] $inputs + * @param Item[] $outputs */ - public function __construct(CraftingTransaction $transaction, \pocketmine\crafting\CraftingRecipe $recipe, int $repetitions, array $inputs, array $outputs){ + public function __construct(CraftingTransaction $transaction, CraftingRecipe $recipe, int $repetitions, array $inputs, array $outputs){ $this->transaction = $transaction; $this->recipe = $recipe; $this->repetitions = $repetitions; @@ -72,9 +72,9 @@ class CraftItemEvent extends Event implements Cancellable{ /** * Returns the recipe crafted. * - * @return \pocketmine\crafting\CraftingRecipe + * @return CraftingRecipe */ - public function getRecipe() : \pocketmine\crafting\CraftingRecipe{ + public function getRecipe() : CraftingRecipe{ return $this->recipe; } diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 39f992670a..be51e4a860 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -183,7 +183,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, protected $permanentWindows = []; /** @var PlayerCursorInventory */ protected $cursorInventory; - /** @var \pocketmine\crafting\CraftingGrid */ + /** @var CraftingGrid */ protected $craftingGrid = null; /** @var int */ From b0a85155d7d653e5ae3676f25083f24a0ee85a90 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Jul 2019 14:06:11 +0100 Subject: [PATCH 1029/3224] [ci skip] add inventory changes to changelog --- changelogs/4.0-snapshot.md | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 5f03f02cd6..4ed0b3cfa0 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -301,6 +301,45 @@ This version features substantial changes to the network system, improving coher - `pocketmine\plugin\RegisteredListener` -> `pocketmine\event\RegisteredListener` ### Inventory +- All crafting and recipe related classes have been moved to the `pocketmine\crafting` namespace. +- The following classes have been added: + - `CallbackInventoryChangeListener` + - `CreativeInventory`: contains the creative functionality previously embedded in `pocketmine\item\Item`, see Item changes for details + - `InventoryChangeListener`: allows listening (but not interfering with) events in an inventory. + - `transaction\CreateItemAction` + - `transaction\DestroyItemAction` +- The following classes have been renamed: + - `ContainerInventory` -> `BlockInventory` +- The following classes have been removed: + - `CustomInventory` + - `InventoryEventProcessor` + - `Recipe` + - `transaction\CreativeInventoryAction` +- The following API methods have been added: + - `Inventory->addChangeListeners()` + - `Inventory->getChangeListeners()` + - `Inventory->removeChangeListeners()` + - `Inventory->swap()`: swaps the contents of two slots +- The following API methods have been removed: + - `BaseInventory->getDefaultSize()` + - `BaseInventory->setSize()` + - `Inventory->close()` + - `Inventory->dropContents()` + - `Inventory->getName()` + - `Inventory->getTitle()` + - `Inventory->onSlotChange()` + - `Inventory->open()` + - `Inventory->sendContents()` + - `Inventory->sendSlot()` + - `InventoryAction->onExecuteFail()` + - `InventoryAction->onExecuteSuccess()` + - `PlayerInventory->sendCreativeContents()` +- The following API methods have signature changes: + - `Inventory->clear()` now returns `void` instead of `bool`. + - `Inventory->setItem()` now returns `void` instead of `bool`. + - `InventoryAction->execute()` now returns `void` instead of `bool`. + - `BaseInventory->construct()` no longer accepts a list of items to initialize with. +- `PlayerInventory->setItemInHand()` now sends the update to viewers of the player. ### Item #### General From 206b397ee1443c6341427a2cd5fccd2296683035 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Jul 2019 19:52:51 +0100 Subject: [PATCH 1030/3224] Living: drop useless knockBack() parameters, closes #2634 --- changelogs/4.0-snapshot.md | 1 + src/pocketmine/entity/Living.php | 4 ++-- src/pocketmine/item/enchantment/KnockbackEnchantment.php | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 4ed0b3cfa0..3594ce7796 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -152,6 +152,7 @@ This version features substantial changes to the network system, improving coher - The following methods have signature changes: - `Entity->entityBaseTick()` is now `protected`. - `Entity->move()` is now `protected`. + - `Living->knockBack()` now accepts `float, float, float` (the first two parameters have been removed). - The following classes have been removed: - `Creature` - `Damageable` diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 2225f54ba1..c0fd5338bc 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -579,7 +579,7 @@ abstract class Living extends Entity{ $deltaX = $this->x - $e->x; $deltaZ = $this->z - $e->z; - $this->knockBack($e, $source->getBaseDamage(), $deltaX, $deltaZ, $source->getKnockBack()); + $this->knockBack($deltaX, $deltaZ, $source->getKnockBack()); } } @@ -593,7 +593,7 @@ abstract class Living extends Entity{ $this->broadcastEntityEvent(EntityEventPacket::HURT_ANIMATION); } - public function knockBack(Entity $attacker, float $damage, float $x, float $z, float $base = 0.4) : void{ + public function knockBack(float $x, float $z, float $base = 0.4) : void{ $f = sqrt($x * $x + $z * $z); if($f <= 0){ return; diff --git a/src/pocketmine/item/enchantment/KnockbackEnchantment.php b/src/pocketmine/item/enchantment/KnockbackEnchantment.php index 04cb92fe5b..da274a4090 100644 --- a/src/pocketmine/item/enchantment/KnockbackEnchantment.php +++ b/src/pocketmine/item/enchantment/KnockbackEnchantment.php @@ -38,7 +38,7 @@ class KnockbackEnchantment extends MeleeWeaponEnchantment{ public function onPostAttack(Entity $attacker, Entity $victim, int $enchantmentLevel) : void{ if($victim instanceof Living){ - $victim->knockBack($attacker, 0, $victim->x - $attacker->x, $victim->z - $attacker->z, $enchantmentLevel * 0.5); + $victim->knockBack($victim->x - $attacker->x, $victim->z - $attacker->z, $enchantmentLevel * 0.5); } } } From d23eeff8324e51ea1a902271603c50551e074c1b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Jul 2019 19:54:56 +0100 Subject: [PATCH 1031/3224] FallingBlock: remove useless check --- src/pocketmine/entity/object/FallingBlock.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/entity/object/FallingBlock.php b/src/pocketmine/entity/object/FallingBlock.php index c563b486ec..77940c0d18 100644 --- a/src/pocketmine/entity/object/FallingBlock.php +++ b/src/pocketmine/entity/object/FallingBlock.php @@ -109,7 +109,7 @@ class FallingBlock extends Entity{ $this->flagForDespawn(); $block = $this->world->getBlock($pos); - if($block->getId() > 0 and $block->isTransparent() and !$block->canBeReplaced()){ + if($block->isTransparent() and !$block->canBeReplaced()){ //FIXME: anvils are supposed to destroy torches $this->getWorld()->dropItem($this, $this->block->asItem()); }else{ From 720254f64f0c6b12e9415657e87c631e1c2a9435 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Jul 2019 19:56:26 +0100 Subject: [PATCH 1032/3224] fix crash on falling block above the height limit, closes #2803 --- src/pocketmine/entity/object/FallingBlock.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/entity/object/FallingBlock.php b/src/pocketmine/entity/object/FallingBlock.php index 77940c0d18..ae8cc7e921 100644 --- a/src/pocketmine/entity/object/FallingBlock.php +++ b/src/pocketmine/entity/object/FallingBlock.php @@ -109,7 +109,7 @@ class FallingBlock extends Entity{ $this->flagForDespawn(); $block = $this->world->getBlock($pos); - if($block->isTransparent() and !$block->canBeReplaced()){ + if(($block->isTransparent() and !$block->canBeReplaced()) or !$this->world->isInWorld($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ())){ //FIXME: anvils are supposed to destroy torches $this->getWorld()->dropItem($this, $this->block->asItem()); }else{ From 5b02ca8a642963c50b8b6d925b54cee0372487d1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 3 Jul 2019 14:34:22 +0100 Subject: [PATCH 1033/3224] InGamePacketHandler: return unhandled for command requests without a leading / some clients send things without the /, f.e. websocket stuff, and we aren't ready to handle that properly yet. The result is that the command gets dumped directly into the chat instead of being unhandled. --- .../network/mcpe/handler/InGamePacketHandler.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php index 48129dd3e8..3ef0dc5190 100644 --- a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php @@ -92,6 +92,7 @@ use function json_last_error_msg; use function microtime; use function preg_match; use function preg_split; +use function strpos; use function trim; /** @@ -589,7 +590,11 @@ class InGamePacketHandler extends PacketHandler{ } public function handleCommandRequest(CommandRequestPacket $packet) : bool{ - return $this->player->chat($packet->command); + if(strpos($packet->command, '/') === 0){ + $this->player->chat($packet->command); + return true; + } + return false; } public function handleCommandBlockUpdate(CommandBlockUpdatePacket $packet) : bool{ From 02bbf50dbeb9b276ae44dfbd6e72375884a348be Mon Sep 17 00:00:00 2001 From: Luke Date: Wed, 3 Jul 2019 15:04:17 +0100 Subject: [PATCH 1034/3224] Make DragonEgg::teleport public (#2992) --- src/pocketmine/block/DragonEgg.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/DragonEgg.php b/src/pocketmine/block/DragonEgg.php index 0be7e15fe4..f90fb3da74 100644 --- a/src/pocketmine/block/DragonEgg.php +++ b/src/pocketmine/block/DragonEgg.php @@ -61,7 +61,7 @@ class DragonEgg extends Transparent implements Fallable{ return true; } - protected function teleport() : void{ + public function teleport() : void{ for($tries = 0; $tries < 16; ++$tries){ $block = $this->world->getBlockAt( $this->x + mt_rand(-16, 16), From 80b29250c828ed78705f5b00b497a083a1986e8b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 3 Jul 2019 16:16:55 +0100 Subject: [PATCH 1035/3224] added all the element blocks --- src/pocketmine/block/BlockFactory.php | 244 +++++++++++++------------- src/pocketmine/block/Element.php | 62 +++++++ 2 files changed, 187 insertions(+), 119 deletions(-) create mode 100644 src/pocketmine/block/Element.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index d823f739ee..e9d784c52d 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -555,6 +555,8 @@ class BlockFactory{ self::register(new Wall(new BID(Ids::COBBLESTONE_WALL, $magicNumber), $prefix . " Wall")); } + self::registerElements(); + //region --- auto-generated TODOs --- //TODO: minecraft:bamboo //TODO: minecraft:bamboo_sapling @@ -585,125 +587,6 @@ class BlockFactory{ //TODO: minecraft:dispenser //TODO: minecraft:dried_kelp_block //TODO: minecraft:dropper - //TODO: minecraft:element_0 - //TODO: minecraft:element_1 - //TODO: minecraft:element_10 - //TODO: minecraft:element_100 - //TODO: minecraft:element_101 - //TODO: minecraft:element_102 - //TODO: minecraft:element_103 - //TODO: minecraft:element_104 - //TODO: minecraft:element_105 - //TODO: minecraft:element_106 - //TODO: minecraft:element_107 - //TODO: minecraft:element_108 - //TODO: minecraft:element_109 - //TODO: minecraft:element_11 - //TODO: minecraft:element_110 - //TODO: minecraft:element_111 - //TODO: minecraft:element_112 - //TODO: minecraft:element_113 - //TODO: minecraft:element_114 - //TODO: minecraft:element_115 - //TODO: minecraft:element_116 - //TODO: minecraft:element_117 - //TODO: minecraft:element_118 - //TODO: minecraft:element_12 - //TODO: minecraft:element_13 - //TODO: minecraft:element_14 - //TODO: minecraft:element_15 - //TODO: minecraft:element_16 - //TODO: minecraft:element_17 - //TODO: minecraft:element_18 - //TODO: minecraft:element_19 - //TODO: minecraft:element_2 - //TODO: minecraft:element_20 - //TODO: minecraft:element_21 - //TODO: minecraft:element_22 - //TODO: minecraft:element_23 - //TODO: minecraft:element_24 - //TODO: minecraft:element_25 - //TODO: minecraft:element_26 - //TODO: minecraft:element_27 - //TODO: minecraft:element_28 - //TODO: minecraft:element_29 - //TODO: minecraft:element_3 - //TODO: minecraft:element_30 - //TODO: minecraft:element_31 - //TODO: minecraft:element_32 - //TODO: minecraft:element_33 - //TODO: minecraft:element_34 - //TODO: minecraft:element_35 - //TODO: minecraft:element_36 - //TODO: minecraft:element_37 - //TODO: minecraft:element_38 - //TODO: minecraft:element_39 - //TODO: minecraft:element_4 - //TODO: minecraft:element_40 - //TODO: minecraft:element_41 - //TODO: minecraft:element_42 - //TODO: minecraft:element_43 - //TODO: minecraft:element_44 - //TODO: minecraft:element_45 - //TODO: minecraft:element_46 - //TODO: minecraft:element_47 - //TODO: minecraft:element_48 - //TODO: minecraft:element_49 - //TODO: minecraft:element_5 - //TODO: minecraft:element_50 - //TODO: minecraft:element_51 - //TODO: minecraft:element_52 - //TODO: minecraft:element_53 - //TODO: minecraft:element_54 - //TODO: minecraft:element_55 - //TODO: minecraft:element_56 - //TODO: minecraft:element_57 - //TODO: minecraft:element_58 - //TODO: minecraft:element_59 - //TODO: minecraft:element_6 - //TODO: minecraft:element_60 - //TODO: minecraft:element_61 - //TODO: minecraft:element_62 - //TODO: minecraft:element_63 - //TODO: minecraft:element_64 - //TODO: minecraft:element_65 - //TODO: minecraft:element_66 - //TODO: minecraft:element_67 - //TODO: minecraft:element_68 - //TODO: minecraft:element_69 - //TODO: minecraft:element_7 - //TODO: minecraft:element_70 - //TODO: minecraft:element_71 - //TODO: minecraft:element_72 - //TODO: minecraft:element_73 - //TODO: minecraft:element_74 - //TODO: minecraft:element_75 - //TODO: minecraft:element_76 - //TODO: minecraft:element_77 - //TODO: minecraft:element_78 - //TODO: minecraft:element_79 - //TODO: minecraft:element_8 - //TODO: minecraft:element_80 - //TODO: minecraft:element_81 - //TODO: minecraft:element_82 - //TODO: minecraft:element_83 - //TODO: minecraft:element_84 - //TODO: minecraft:element_85 - //TODO: minecraft:element_86 - //TODO: minecraft:element_87 - //TODO: minecraft:element_88 - //TODO: minecraft:element_89 - //TODO: minecraft:element_9 - //TODO: minecraft:element_90 - //TODO: minecraft:element_91 - //TODO: minecraft:element_92 - //TODO: minecraft:element_93 - //TODO: minecraft:element_94 - //TODO: minecraft:element_95 - //TODO: minecraft:element_96 - //TODO: minecraft:element_97 - //TODO: minecraft:element_98 - //TODO: minecraft:element_99 //TODO: minecraft:end_gateway //TODO: minecraft:end_portal //TODO: minecraft:fletching_table @@ -744,6 +627,129 @@ class BlockFactory{ //endregion } + private static function registerElements() : void{ + self::register(new Solid(new BID(Ids::ELEMENT_0), "???", BlockBreakInfo::instant())); + + self::register(new Element(new BID(Ids::ELEMENT_1), "Hydrogen", BlockBreakInfo::instant(), "h", 1, 5)); + self::register(new Element(new BID(Ids::ELEMENT_2), "Helium", BlockBreakInfo::instant(), "he", 2, 7)); + self::register(new Element(new BID(Ids::ELEMENT_3), "Lithium", BlockBreakInfo::instant(), "li", 3, 0)); + self::register(new Element(new BID(Ids::ELEMENT_4), "Beryllium", BlockBreakInfo::instant(), "be", 4, 1)); + self::register(new Element(new BID(Ids::ELEMENT_5), "Boron", BlockBreakInfo::instant(), "b", 5, 4)); + self::register(new Element(new BID(Ids::ELEMENT_6), "Carbon", BlockBreakInfo::instant(), "c", 6, 5)); + self::register(new Element(new BID(Ids::ELEMENT_7), "Nitrogen", BlockBreakInfo::instant(), "n", 7, 5)); + self::register(new Element(new BID(Ids::ELEMENT_8), "Oxygen", BlockBreakInfo::instant(), "o", 8, 5)); + self::register(new Element(new BID(Ids::ELEMENT_9), "Fluorine", BlockBreakInfo::instant(), "f", 9, 6)); + self::register(new Element(new BID(Ids::ELEMENT_10), "Neon", BlockBreakInfo::instant(), "ne", 10, 7)); + self::register(new Element(new BID(Ids::ELEMENT_11), "Sodium", BlockBreakInfo::instant(), "na", 11, 0)); + self::register(new Element(new BID(Ids::ELEMENT_12), "Magnesium", BlockBreakInfo::instant(), "mg", 12, 1)); + self::register(new Element(new BID(Ids::ELEMENT_13), "Aluminum", BlockBreakInfo::instant(), "al", 13, 3)); + self::register(new Element(new BID(Ids::ELEMENT_14), "Silicon", BlockBreakInfo::instant(), "si", 14, 4)); + self::register(new Element(new BID(Ids::ELEMENT_15), "Phosphorus", BlockBreakInfo::instant(), "p", 15, 5)); + self::register(new Element(new BID(Ids::ELEMENT_16), "Sulfur", BlockBreakInfo::instant(), "s", 16, 5)); + self::register(new Element(new BID(Ids::ELEMENT_17), "Chlorine", BlockBreakInfo::instant(), "cl", 17, 6)); + self::register(new Element(new BID(Ids::ELEMENT_18), "Argon", BlockBreakInfo::instant(), "ar", 18, 7)); + self::register(new Element(new BID(Ids::ELEMENT_19), "Potassium", BlockBreakInfo::instant(), "k", 19, 0)); + self::register(new Element(new BID(Ids::ELEMENT_20), "Calcium", BlockBreakInfo::instant(), "ca", 20, 1)); + self::register(new Element(new BID(Ids::ELEMENT_21), "Scandium", BlockBreakInfo::instant(), "sc", 21, 2)); + self::register(new Element(new BID(Ids::ELEMENT_22), "Titanium", BlockBreakInfo::instant(), "ti", 22, 2)); + self::register(new Element(new BID(Ids::ELEMENT_23), "Vanadium", BlockBreakInfo::instant(), "v", 23, 2)); + self::register(new Element(new BID(Ids::ELEMENT_24), "Chromium", BlockBreakInfo::instant(), "cr", 24, 2)); + self::register(new Element(new BID(Ids::ELEMENT_25), "Manganese", BlockBreakInfo::instant(), "mn", 25, 2)); + self::register(new Element(new BID(Ids::ELEMENT_26), "Iron", BlockBreakInfo::instant(), "fe", 26, 2)); + self::register(new Element(new BID(Ids::ELEMENT_27), "Cobalt", BlockBreakInfo::instant(), "co", 27, 2)); + self::register(new Element(new BID(Ids::ELEMENT_28), "Nickel", BlockBreakInfo::instant(), "ni", 28, 2)); + self::register(new Element(new BID(Ids::ELEMENT_29), "Copper", BlockBreakInfo::instant(), "cu", 29, 2)); + self::register(new Element(new BID(Ids::ELEMENT_30), "Zinc", BlockBreakInfo::instant(), "zn", 30, 2)); + self::register(new Element(new BID(Ids::ELEMENT_31), "Gallium", BlockBreakInfo::instant(), "ga", 31, 3)); + self::register(new Element(new BID(Ids::ELEMENT_32), "Germanium", BlockBreakInfo::instant(), "ge", 32, 4)); + self::register(new Element(new BID(Ids::ELEMENT_33), "Arsenic", BlockBreakInfo::instant(), "as", 33, 4)); + self::register(new Element(new BID(Ids::ELEMENT_34), "Selenium", BlockBreakInfo::instant(), "se", 34, 5)); + self::register(new Element(new BID(Ids::ELEMENT_35), "Bromine", BlockBreakInfo::instant(), "br", 35, 6)); + self::register(new Element(new BID(Ids::ELEMENT_36), "Krypton", BlockBreakInfo::instant(), "kr", 36, 7)); + self::register(new Element(new BID(Ids::ELEMENT_37), "Rubidium", BlockBreakInfo::instant(), "rb", 37, 0)); + self::register(new Element(new BID(Ids::ELEMENT_38), "Strontium", BlockBreakInfo::instant(), "sr", 38, 1)); + self::register(new Element(new BID(Ids::ELEMENT_39), "Yttrium", BlockBreakInfo::instant(), "y", 39, 2)); + self::register(new Element(new BID(Ids::ELEMENT_40), "Zirconium", BlockBreakInfo::instant(), "zr", 40, 2)); + self::register(new Element(new BID(Ids::ELEMENT_41), "Niobium", BlockBreakInfo::instant(), "nb", 41, 2)); + self::register(new Element(new BID(Ids::ELEMENT_42), "Molybdenum", BlockBreakInfo::instant(), "mo", 42, 2)); + self::register(new Element(new BID(Ids::ELEMENT_43), "Technetium", BlockBreakInfo::instant(), "tc", 43, 2)); + self::register(new Element(new BID(Ids::ELEMENT_44), "Ruthenium", BlockBreakInfo::instant(), "ru", 44, 2)); + self::register(new Element(new BID(Ids::ELEMENT_45), "Rhodium", BlockBreakInfo::instant(), "rh", 45, 2)); + self::register(new Element(new BID(Ids::ELEMENT_46), "Palladium", BlockBreakInfo::instant(), "pd", 46, 2)); + self::register(new Element(new BID(Ids::ELEMENT_47), "Silver", BlockBreakInfo::instant(), "ag", 47, 2)); + self::register(new Element(new BID(Ids::ELEMENT_48), "Cadmium", BlockBreakInfo::instant(), "cd", 48, 2)); + self::register(new Element(new BID(Ids::ELEMENT_49), "Indium", BlockBreakInfo::instant(), "in", 49, 3)); + self::register(new Element(new BID(Ids::ELEMENT_50), "Tin", BlockBreakInfo::instant(), "sn", 50, 3)); + self::register(new Element(new BID(Ids::ELEMENT_51), "Antimony", BlockBreakInfo::instant(), "sb", 51, 4)); + self::register(new Element(new BID(Ids::ELEMENT_52), "Tellurium", BlockBreakInfo::instant(), "te", 52, 4)); + self::register(new Element(new BID(Ids::ELEMENT_53), "Iodine", BlockBreakInfo::instant(), "i", 53, 6)); + self::register(new Element(new BID(Ids::ELEMENT_54), "Xenon", BlockBreakInfo::instant(), "xe", 54, 7)); + self::register(new Element(new BID(Ids::ELEMENT_55), "Cesium", BlockBreakInfo::instant(), "cs", 55, 0)); + self::register(new Element(new BID(Ids::ELEMENT_56), "Barium", BlockBreakInfo::instant(), "ba", 56, 1)); + self::register(new Element(new BID(Ids::ELEMENT_57), "Lanthanum", BlockBreakInfo::instant(), "la", 57, 8)); + self::register(new Element(new BID(Ids::ELEMENT_58), "Cerium", BlockBreakInfo::instant(), "ce", 58, 8)); + self::register(new Element(new BID(Ids::ELEMENT_59), "Praseodymium", BlockBreakInfo::instant(), "pr", 59, 8)); + self::register(new Element(new BID(Ids::ELEMENT_60), "Neodymium", BlockBreakInfo::instant(), "nd", 60, 8)); + self::register(new Element(new BID(Ids::ELEMENT_61), "Promethium", BlockBreakInfo::instant(), "pm", 61, 8)); + self::register(new Element(new BID(Ids::ELEMENT_62), "Samarium", BlockBreakInfo::instant(), "sm", 62, 8)); + self::register(new Element(new BID(Ids::ELEMENT_63), "Europium", BlockBreakInfo::instant(), "eu", 63, 8)); + self::register(new Element(new BID(Ids::ELEMENT_64), "Gadolinium", BlockBreakInfo::instant(), "gd", 64, 8)); + self::register(new Element(new BID(Ids::ELEMENT_65), "Terbium", BlockBreakInfo::instant(), "tb", 65, 8)); + self::register(new Element(new BID(Ids::ELEMENT_66), "Dysprosium", BlockBreakInfo::instant(), "dy", 66, 8)); + self::register(new Element(new BID(Ids::ELEMENT_67), "Holmium", BlockBreakInfo::instant(), "ho", 67, 8)); + self::register(new Element(new BID(Ids::ELEMENT_68), "Erbium", BlockBreakInfo::instant(), "er", 68, 8)); + self::register(new Element(new BID(Ids::ELEMENT_69), "Thulium", BlockBreakInfo::instant(), "tm", 69, 8)); + self::register(new Element(new BID(Ids::ELEMENT_70), "Ytterbium", BlockBreakInfo::instant(), "yb", 70, 8)); + self::register(new Element(new BID(Ids::ELEMENT_71), "Lutetium", BlockBreakInfo::instant(), "lu", 71, 8)); + self::register(new Element(new BID(Ids::ELEMENT_72), "Hafnium", BlockBreakInfo::instant(), "hf", 72, 2)); + self::register(new Element(new BID(Ids::ELEMENT_73), "Tantalum", BlockBreakInfo::instant(), "ta", 73, 2)); + self::register(new Element(new BID(Ids::ELEMENT_74), "Tungsten", BlockBreakInfo::instant(), "w", 74, 2)); + self::register(new Element(new BID(Ids::ELEMENT_75), "Rhenium", BlockBreakInfo::instant(), "re", 75, 2)); + self::register(new Element(new BID(Ids::ELEMENT_76), "Osmium", BlockBreakInfo::instant(), "os", 76, 2)); + self::register(new Element(new BID(Ids::ELEMENT_77), "Iridium", BlockBreakInfo::instant(), "ir", 77, 2)); + self::register(new Element(new BID(Ids::ELEMENT_78), "Platinum", BlockBreakInfo::instant(), "pt", 78, 2)); + self::register(new Element(new BID(Ids::ELEMENT_79), "Gold", BlockBreakInfo::instant(), "au", 79, 2)); + self::register(new Element(new BID(Ids::ELEMENT_80), "Mercury", BlockBreakInfo::instant(), "hg", 80, 2)); + self::register(new Element(new BID(Ids::ELEMENT_81), "Thallium", BlockBreakInfo::instant(), "tl", 81, 3)); + self::register(new Element(new BID(Ids::ELEMENT_82), "Lead", BlockBreakInfo::instant(), "pb", 82, 3)); + self::register(new Element(new BID(Ids::ELEMENT_83), "Bismuth", BlockBreakInfo::instant(), "bi", 83, 3)); + self::register(new Element(new BID(Ids::ELEMENT_84), "Polonium", BlockBreakInfo::instant(), "po", 84, 4)); + self::register(new Element(new BID(Ids::ELEMENT_85), "Astatine", BlockBreakInfo::instant(), "at", 85, 6)); + self::register(new Element(new BID(Ids::ELEMENT_86), "Radon", BlockBreakInfo::instant(), "rn", 86, 7)); + self::register(new Element(new BID(Ids::ELEMENT_87), "Francium", BlockBreakInfo::instant(), "fr", 87, 0)); + self::register(new Element(new BID(Ids::ELEMENT_88), "Radium", BlockBreakInfo::instant(), "ra", 88, 1)); + self::register(new Element(new BID(Ids::ELEMENT_89), "Actinium", BlockBreakInfo::instant(), "ac", 89, 9)); + self::register(new Element(new BID(Ids::ELEMENT_90), "Thorium", BlockBreakInfo::instant(), "th", 90, 9)); + self::register(new Element(new BID(Ids::ELEMENT_91), "Protactinium", BlockBreakInfo::instant(), "pa", 91, 9)); + self::register(new Element(new BID(Ids::ELEMENT_92), "Uranium", BlockBreakInfo::instant(), "u", 92, 9)); + self::register(new Element(new BID(Ids::ELEMENT_93), "Neptunium", BlockBreakInfo::instant(), "np", 93, 9)); + self::register(new Element(new BID(Ids::ELEMENT_94), "Plutonium", BlockBreakInfo::instant(), "pu", 94, 9)); + self::register(new Element(new BID(Ids::ELEMENT_95), "Americium", BlockBreakInfo::instant(), "am", 95, 9)); + self::register(new Element(new BID(Ids::ELEMENT_96), "Curium", BlockBreakInfo::instant(), "cm", 96, 9)); + self::register(new Element(new BID(Ids::ELEMENT_97), "Berkelium", BlockBreakInfo::instant(), "bk", 97, 9)); + self::register(new Element(new BID(Ids::ELEMENT_98), "Californium", BlockBreakInfo::instant(), "cf", 98, 9)); + self::register(new Element(new BID(Ids::ELEMENT_99), "Einsteinium", BlockBreakInfo::instant(), "es", 99, 9)); + self::register(new Element(new BID(Ids::ELEMENT_100), "Fermium", BlockBreakInfo::instant(), "fm", 100, 9)); + self::register(new Element(new BID(Ids::ELEMENT_101), "Mendelevium", BlockBreakInfo::instant(), "md", 101, 9)); + self::register(new Element(new BID(Ids::ELEMENT_102), "Nobelium", BlockBreakInfo::instant(), "no", 102, 9)); + self::register(new Element(new BID(Ids::ELEMENT_103), "Lawrencium", BlockBreakInfo::instant(), "lr", 103, 9)); + self::register(new Element(new BID(Ids::ELEMENT_104), "Rutherfordium", BlockBreakInfo::instant(), "rf", 104, 2)); + self::register(new Element(new BID(Ids::ELEMENT_105), "Dubnium", BlockBreakInfo::instant(), "db", 105, 2)); + self::register(new Element(new BID(Ids::ELEMENT_106), "Seaborgium", BlockBreakInfo::instant(), "sg", 106, 2)); + self::register(new Element(new BID(Ids::ELEMENT_107), "Bohrium", BlockBreakInfo::instant(), "bh", 107, 2)); + self::register(new Element(new BID(Ids::ELEMENT_108), "Hassium", BlockBreakInfo::instant(), "hs", 108, 2)); + self::register(new Element(new BID(Ids::ELEMENT_109), "Meitnerium", BlockBreakInfo::instant(), "mt", 109, 2)); + self::register(new Element(new BID(Ids::ELEMENT_110), "Darmstadtium", BlockBreakInfo::instant(), "ds", 110, 2)); + self::register(new Element(new BID(Ids::ELEMENT_111), "Roentgenium", BlockBreakInfo::instant(), "rg", 111, 2)); + self::register(new Element(new BID(Ids::ELEMENT_112), "Copernicium", BlockBreakInfo::instant(), "cn", 112, 2)); + self::register(new Element(new BID(Ids::ELEMENT_113), "Nihonium", BlockBreakInfo::instant(), "nh", 113, 3)); + self::register(new Element(new BID(Ids::ELEMENT_114), "Flerovium", BlockBreakInfo::instant(), "fl", 114, 3)); + self::register(new Element(new BID(Ids::ELEMENT_115), "Moscovium", BlockBreakInfo::instant(), "mc", 115, 3)); + self::register(new Element(new BID(Ids::ELEMENT_116), "Livermorium", BlockBreakInfo::instant(), "lv", 116, 3)); + self::register(new Element(new BID(Ids::ELEMENT_117), "Tennessine", BlockBreakInfo::instant(), "ts", 117, 6)); + self::register(new Element(new BID(Ids::ELEMENT_118), "Oganesson", BlockBreakInfo::instant(), "og", 118, 7)); + } + public static function isInit() : bool{ return self::$fullList !== null; } diff --git a/src/pocketmine/block/Element.php b/src/pocketmine/block/Element.php new file mode 100644 index 0000000000..fa0cd2d66e --- /dev/null +++ b/src/pocketmine/block/Element.php @@ -0,0 +1,62 @@ +atomicWeight = $atomicWeight; + $this->group = $group; + $this->symbol = $symbol; + } + + /** + * @return int + */ + public function getAtomicWeight() : int{ + return $this->atomicWeight; + } + + /** + * @return int + */ + public function getGroup() : int{ + return $this->group; + } + + /** + * @return string + */ + public function getSymbol() : string{ + return $this->symbol; + } +} From 4a6d4953f2bd34c3d01a645b334ede22a4c7c258 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 3 Jul 2019 16:19:24 +0100 Subject: [PATCH 1036/3224] updated consistency check for previous commit --- tests/phpunit/block/block_factory_consistency_check.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 66c3091094..8a0686ba9f 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From 85051554c4df2fb76a926cad3785a2ff04337312 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 3 Jul 2019 16:47:02 +0100 Subject: [PATCH 1037/3224] disallow logins from players with phony XUIDs this simplifies XUID handling. --- src/pocketmine/network/mcpe/NetworkSession.php | 14 +++++--------- src/pocketmine/player/Player.php | 2 +- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 1ec213c833..16a87b1f3f 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -533,6 +533,8 @@ class NetworkSession{ } if($authenticated and $this->info->getXuid() === ""){ $error = "Expected XUID but none found"; + }elseif(!$authenticated and $this->info->getXuid() !== ""){ + $error = "Unexpected XUID for non-XBOX-authenticated player"; } if($error !== null){ @@ -543,15 +545,9 @@ class NetworkSession{ $this->authenticated = $authenticated; - if(!$this->authenticated){ - if($authRequired){ - $this->disconnect("disconnectionScreen.notAuthenticated"); - return; - } - - if($this->info->getXuid() !== ""){ - $this->logger->warning("Found XUID, but login keychain is not signed by Mojang"); - } + if(!$this->authenticated and $authRequired){ + $this->disconnect("disconnectionScreen.notAuthenticated"); + return; } $this->logger->debug("Xbox Live authenticated: " . ($this->authenticated ? "YES" : "NO")); diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index be51e4a860..c4515c11cb 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -283,7 +283,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->uuid = $this->playerInfo->getUuid(); $this->rawUUID = $this->uuid->toBinary(); - $this->xuid = $authenticated ? $this->playerInfo->getXuid() : ""; + $this->xuid = $this->playerInfo->getXuid(); $this->perm = new PermissibleBase($this); $this->chunksPerTick = (int) $this->server->getProperty("chunk-sending.per-tick", 4); From ee885bb72516862eab5bb2adba7357c01983e5af Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 3 Jul 2019 17:57:11 +0100 Subject: [PATCH 1038/3224] shorten BlockToolType constants --- src/pocketmine/block/Anvil.php | 2 +- src/pocketmine/block/Banner.php | 2 +- src/pocketmine/block/BlockBreakInfo.php | 8 +-- src/pocketmine/block/BlockFactory.php | 50 +++++++++---------- src/pocketmine/block/BlockToolType.php | 12 ++--- src/pocketmine/block/BlueIce.php | 2 +- src/pocketmine/block/BoneBlock.php | 2 +- src/pocketmine/block/Bookshelf.php | 2 +- src/pocketmine/block/BrewingStand.php | 2 +- src/pocketmine/block/Chest.php | 2 +- src/pocketmine/block/Clay.php | 2 +- src/pocketmine/block/Coal.php | 2 +- src/pocketmine/block/CoalOre.php | 2 +- src/pocketmine/block/Cobweb.php | 2 +- src/pocketmine/block/CocoaBlock.php | 2 +- src/pocketmine/block/Concrete.php | 2 +- src/pocketmine/block/ConcretePowder.php | 2 +- src/pocketmine/block/CraftingTable.php | 2 +- src/pocketmine/block/DaylightSensor.php | 2 +- src/pocketmine/block/DeadBush.php | 2 +- src/pocketmine/block/DiamondOre.php | 2 +- src/pocketmine/block/Dirt.php | 2 +- src/pocketmine/block/DoubleTallGrass.php | 2 +- src/pocketmine/block/DragonEgg.php | 2 +- src/pocketmine/block/EmeraldOre.php | 2 +- src/pocketmine/block/EnchantingTable.php | 2 +- src/pocketmine/block/EnderChest.php | 2 +- src/pocketmine/block/Farmland.php | 2 +- src/pocketmine/block/FenceGate.php | 2 +- src/pocketmine/block/FrostedIce.php | 2 +- src/pocketmine/block/Furnace.php | 2 +- src/pocketmine/block/GlazedTerracotta.php | 2 +- src/pocketmine/block/GlowingObsidian.php | 2 +- src/pocketmine/block/Glowstone.php | 2 +- src/pocketmine/block/Grass.php | 2 +- src/pocketmine/block/GrassPath.php | 2 +- src/pocketmine/block/Gravel.php | 2 +- src/pocketmine/block/HardenedClay.php | 2 +- src/pocketmine/block/Ice.php | 2 +- src/pocketmine/block/Ladder.php | 2 +- src/pocketmine/block/LapisOre.php | 2 +- src/pocketmine/block/Leaves.php | 4 +- src/pocketmine/block/Magma.php | 2 +- src/pocketmine/block/Melon.php | 2 +- src/pocketmine/block/MonsterSpawner.php | 2 +- src/pocketmine/block/Mycelium.php | 2 +- src/pocketmine/block/NetherQuartzOre.php | 2 +- src/pocketmine/block/NetherReactor.php | 2 +- src/pocketmine/block/Netherrack.php | 2 +- src/pocketmine/block/Note.php | 2 +- src/pocketmine/block/PackedIce.php | 2 +- src/pocketmine/block/Planks.php | 2 +- src/pocketmine/block/Podzol.php | 2 +- src/pocketmine/block/Pumpkin.php | 2 +- src/pocketmine/block/RedMushroomBlock.php | 2 +- src/pocketmine/block/Redstone.php | 2 +- src/pocketmine/block/RedstoneOre.php | 2 +- src/pocketmine/block/Sand.php | 2 +- src/pocketmine/block/Sign.php | 2 +- src/pocketmine/block/Snow.php | 2 +- src/pocketmine/block/SnowLayer.php | 2 +- src/pocketmine/block/SoulSand.php | 2 +- src/pocketmine/block/StoneButton.php | 2 +- src/pocketmine/block/StonePressurePlate.php | 2 +- src/pocketmine/block/TallGrass.php | 2 +- src/pocketmine/block/Vine.php | 4 +- src/pocketmine/block/Wall.php | 2 +- .../block/WeightedPressurePlateHeavy.php | 2 +- .../block/WeightedPressurePlateLight.php | 2 +- src/pocketmine/block/Wood.php | 2 +- src/pocketmine/block/WoodenButton.php | 2 +- src/pocketmine/block/WoodenDoor.php | 2 +- src/pocketmine/block/WoodenFence.php | 2 +- src/pocketmine/block/WoodenPressurePlate.php | 2 +- src/pocketmine/block/WoodenSlab.php | 2 +- src/pocketmine/block/WoodenStairs.php | 2 +- src/pocketmine/block/WoodenTrapdoor.php | 2 +- src/pocketmine/block/Wool.php | 4 +- src/pocketmine/item/Axe.php | 2 +- src/pocketmine/item/Item.php | 2 +- src/pocketmine/item/Pickaxe.php | 2 +- src/pocketmine/item/Shears.php | 2 +- src/pocketmine/item/Shovel.php | 2 +- src/pocketmine/item/Sword.php | 2 +- 84 files changed, 119 insertions(+), 119 deletions(-) diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index f2c280fd4a..aecd4c9e58 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -43,7 +43,7 @@ class Anvil extends Transparent implements Fallable{ protected $facing = Facing::NORTH; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 6000.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 6000.0)); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/Banner.php b/src/pocketmine/block/Banner.php index 348d4843ef..85f499f6db 100644 --- a/src/pocketmine/block/Banner.php +++ b/src/pocketmine/block/Banner.php @@ -58,7 +58,7 @@ class Banner extends Transparent{ protected $patterns; public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0, BlockToolType::TYPE_AXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0, BlockToolType::AXE)); $this->baseColor = DyeColor::BLACK(); $this->patterns = new Deque(); } diff --git a/src/pocketmine/block/BlockBreakInfo.php b/src/pocketmine/block/BlockBreakInfo.php index e900b927f0..68e287bb69 100644 --- a/src/pocketmine/block/BlockBreakInfo.php +++ b/src/pocketmine/block/BlockBreakInfo.php @@ -43,19 +43,19 @@ class BlockBreakInfo{ * @param int $toolHarvestLevel * @param float|null $blastResistance default 5x hardness */ - public function __construct(float $hardness, int $toolType = BlockToolType::TYPE_NONE, int $toolHarvestLevel = 0, ?float $blastResistance = null){ + public function __construct(float $hardness, int $toolType = BlockToolType::NONE, int $toolHarvestLevel = 0, ?float $blastResistance = null){ $this->hardness = $hardness; $this->toolType = $toolType; $this->toolHarvestLevel = $toolHarvestLevel; $this->blastResistance = $blastResistance ?? $hardness * 5; } - public static function instant(int $toolType = BlockToolType::TYPE_NONE, int $toolHarvestLevel = 0) : self{ + public static function instant(int $toolType = BlockToolType::NONE, int $toolHarvestLevel = 0) : self{ return new self(0.0, $toolType, $toolHarvestLevel, 0.0); } public static function indestructible(float $blastResistance = 18000000.0) : self{ - return new self(-1.0, BlockToolType::TYPE_NONE, 0, $blastResistance); + return new self(-1.0, BlockToolType::NONE, 0, $blastResistance); } /** @@ -133,7 +133,7 @@ class BlockBreakInfo{ return false; } - return $this->toolType === BlockToolType::TYPE_NONE or $this->toolHarvestLevel === 0 or ( + return $this->toolType === BlockToolType::NONE or $this->toolHarvestLevel === 0 or ( ($this->toolType & $tool->getBlockToolType()) !== 0 and $tool->getBlockToolHarvestLevel() >= $this->toolHarvestLevel); } diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index e9d784c52d..555847800e 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -100,7 +100,7 @@ class BlockFactory{ self::register(new Bookshelf(new BID(Ids::BOOKSHELF), "Bookshelf")); self::register(new BrewingStand(new BID(Ids::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND, TileBrewingStand::class), "Brewing Stand")); - $bricksBreakInfo = new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0); + $bricksBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0); self::register(new Stair(new BID(Ids::BRICK_STAIRS), "Brick Stairs", $bricksBreakInfo)); self::register(new Solid(new BID(Ids::BRICK_BLOCK), "Bricks", $bricksBreakInfo)); @@ -115,7 +115,7 @@ class BlockFactory{ self::register(new CoalOre(new BID(Ids::COAL_ORE), "Coal Ore")); self::register(new CoarseDirt(new BID(Ids::DIRT, Meta::DIRT_COARSE), "Coarse Dirt")); - $cobblestoneBreakInfo = new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0); + $cobblestoneBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0); self::register(new Solid(new BID(Ids::COBBLESTONE), "Cobblestone", $cobblestoneBreakInfo)); self::register(new Solid(new BID(Ids::MOSSY_COBBLESTONE), "Mossy Cobblestone", $cobblestoneBreakInfo)); self::register(new Stair(new BID(Ids::COBBLESTONE_STAIRS), "Cobblestone Stairs", $cobblestoneBreakInfo)); @@ -128,7 +128,7 @@ class BlockFactory{ self::register(new DeadBush(new BID(Ids::DEADBUSH), "Dead Bush")); self::register(new DetectorRail(new BID(Ids::DETECTOR_RAIL), "Detector Rail")); - self::register(new Solid(new BID(Ids::DIAMOND_BLOCK), "Diamond Block", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON, 30.0))); + self::register(new Solid(new BID(Ids::DIAMOND_BLOCK), "Diamond Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_IRON, 30.0))); self::register(new DiamondOre(new BID(Ids::DIAMOND_ORE), "Diamond Ore")); self::register(new Dirt(new BID(Ids::DIRT, Meta::DIRT_NORMAL), "Dirt")); self::register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_SUNFLOWER), "Sunflower")); @@ -138,15 +138,15 @@ class BlockFactory{ self::register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_TALLGRASS), "Double Tallgrass")); self::register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LARGE_FERN), "Large Fern")); self::register(new DragonEgg(new BID(Ids::DRAGON_EGG), "Dragon Egg")); - self::register(new DriedKelp(new BID(Ids::DRIED_KELP_BLOCK), "Dried Kelp Block", new BlockBreakInfo(0.5, BlockToolType::TYPE_NONE, 0, 12.5))); - self::register(new Solid(new BID(Ids::EMERALD_BLOCK), "Emerald Block", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON, 30.0))); + self::register(new DriedKelp(new BID(Ids::DRIED_KELP_BLOCK), "Dried Kelp Block", new BlockBreakInfo(0.5, BlockToolType::NONE, 0, 12.5))); + self::register(new Solid(new BID(Ids::EMERALD_BLOCK), "Emerald Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_IRON, 30.0))); self::register(new EmeraldOre(new BID(Ids::EMERALD_ORE), "Emerald Ore")); self::register(new EnchantingTable(new BID(Ids::ENCHANTING_TABLE, 0, null, TileEnchantingTable::class), "Enchanting Table")); self::register(new EndPortalFrame(new BID(Ids::END_PORTAL_FRAME), "End Portal Frame")); self::register(new EndRod(new BID(Ids::END_ROD), "End Rod")); - self::register(new Solid(new BID(Ids::END_STONE), "End Stone", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 45.0))); + self::register(new Solid(new BID(Ids::END_STONE), "End Stone", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 45.0))); - $endBrickBreakInfo = new BlockBreakInfo(0.8, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 4.0); + $endBrickBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 4.0); self::register(new Solid(new BID(Ids::END_BRICKS), "End Stone Bricks", $endBrickBreakInfo)); self::register(new Stair(new BID(Ids::END_BRICK_STAIRS), "End Stone Brick Stairs", $endBrickBreakInfo)); @@ -172,8 +172,8 @@ class BlockFactory{ self::register(new GlassPane(new BID(Ids::GLASS_PANE), "Glass Pane")); self::register(new GlowingObsidian(new BID(Ids::GLOWINGOBSIDIAN), "Glowing Obsidian")); self::register(new Glowstone(new BID(Ids::GLOWSTONE), "Glowstone")); - self::register(new Solid(new BID(Ids::GOLD_BLOCK), "Gold Block", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON, 30.0))); - self::register(new Solid(new BID(Ids::GOLD_ORE), "Gold Ore", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON))); + self::register(new Solid(new BID(Ids::GOLD_BLOCK), "Gold Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_IRON, 30.0))); + self::register(new Solid(new BID(Ids::GOLD_ORE), "Gold Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_IRON))); self::register(new Grass(new BID(Ids::GRASS), "Grass")); self::register(new GrassPath(new BID(Ids::GRASS_PATH), "Grass Path")); self::register(new Gravel(new BID(Ids::GRAVEL), "Gravel")); @@ -181,7 +181,7 @@ class BlockFactory{ self::register(new HardenedGlass(new BID(Ids::HARD_GLASS), "Hardened Glass")); self::register(new HardenedGlassPane(new BID(Ids::HARD_GLASS_PANE), "Hardened Glass Pane")); self::register(new HayBale(new BID(Ids::HAY_BALE), "Hay Bale")); - self::register(new Hopper(new BID(Ids::HOPPER_BLOCK, 0, ItemIds::HOPPER, TileHopper::class), "Hopper", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 15.0))); + self::register(new Hopper(new BID(Ids::HOPPER_BLOCK, 0, ItemIds::HOPPER, TileHopper::class), "Hopper", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 15.0))); self::register(new Ice(new BID(Ids::ICE), "Ice")); self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE), "Infested Stone") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ @@ -218,14 +218,14 @@ class BlockFactory{ self::register(new Solid(new BID(Ids::INFO_UPDATE), "update!", $updateBlockBreakInfo)); self::register(new Solid(new BID(Ids::INFO_UPDATE2), "ate!upd", $updateBlockBreakInfo)); self::register(new Transparent(new BID(Ids::INVISIBLEBEDROCK), "Invisible Bedrock", BlockBreakInfo::indestructible())); - self::register(new Solid(new BID(Ids::IRON_BLOCK), "Iron Block", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_STONE, 30.0))); - self::register(new Thin(new BID(Ids::IRON_BARS), "Iron Bars", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0))); - self::register(new Door(new BID(Ids::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 25.0))); - self::register(new Solid(new BID(Ids::IRON_ORE), "Iron Ore", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_STONE))); - self::register(new Trapdoor(new BID(Ids::IRON_TRAPDOOR), "Iron Trapdoor", new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 25.0))); + self::register(new Solid(new BID(Ids::IRON_BLOCK), "Iron Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_STONE, 30.0))); + self::register(new Thin(new BID(Ids::IRON_BARS), "Iron Bars", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0))); + self::register(new Door(new BID(Ids::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 25.0))); + self::register(new Solid(new BID(Ids::IRON_ORE), "Iron Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_STONE))); + self::register(new Trapdoor(new BID(Ids::IRON_TRAPDOOR), "Iron Trapdoor", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 25.0))); self::register(new ItemFrame(new BID(Ids::FRAME_BLOCK, 0, ItemIds::FRAME, TileItemFrame::class), "Item Frame")); self::register(new Ladder(new BID(Ids::LADDER), "Ladder")); - self::register(new Solid(new BID(Ids::LAPIS_BLOCK), "Lapis Lazuli Block", new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_STONE))); + self::register(new Solid(new BID(Ids::LAPIS_BLOCK), "Lapis Lazuli Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_STONE))); self::register(new LapisOre(new BID(Ids::LAPIS_ORE), "Lapis Lazuli Ore")); self::register(new Lava(new BIDFlattened(Ids::FLOWING_LAVA, Ids::STILL_LAVA), "Lava")); self::register(new Lever(new BID(Ids::LEVER), "Lever")); @@ -236,7 +236,7 @@ class BlockFactory{ self::register(new MonsterSpawner(new BID(Ids::MOB_SPAWNER, 0, null, TileMonsterSpawner::class), "Monster Spawner")); self::register(new Mycelium(new BID(Ids::MYCELIUM), "Mycelium")); - $netherBrickBreakInfo = new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0); + $netherBrickBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0); self::register(new Solid(new BID(Ids::NETHER_BRICK_BLOCK), "Nether Bricks", $netherBrickBreakInfo)); self::register(new Solid(new BID(Ids::RED_NETHER_BRICK), "Red Nether Bricks", $netherBrickBreakInfo)); self::register(new Fence(new BID(Ids::NETHER_BRICK_FENCE), "Nether Brick Fence", $netherBrickBreakInfo)); @@ -249,13 +249,13 @@ class BlockFactory{ self::register(new NetherWartPlant(new BID(Ids::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART), "Nether Wart")); self::register(new Netherrack(new BID(Ids::NETHERRACK), "Netherrack")); self::register(new Note(new BID(Ids::NOTEBLOCK, 0, null, TileNote::class), "Note Block")); - self::register(new Solid(new BID(Ids::OBSIDIAN), "Obsidian", new BlockBreakInfo(35.0 /* 50 in PC */, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_DIAMOND, 6000.0))); + self::register(new Solid(new BID(Ids::OBSIDIAN), "Obsidian", new BlockBreakInfo(35.0 /* 50 in PC */, BlockToolType::PICKAXE, TieredTool::TIER_DIAMOND, 6000.0))); self::register(new PackedIce(new BID(Ids::PACKED_ICE), "Packed Ice")); self::register(new Podzol(new BID(Ids::PODZOL), "Podzol")); self::register(new Potato(new BID(Ids::POTATOES), "Potato Block")); self::register(new PoweredRail(new BID(Ids::GOLDEN_RAIL, Meta::RAIL_STRAIGHT_NORTH_SOUTH), "Powered Rail")); - $prismarineBreakInfo = new BlockBreakInfo(1.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0); + $prismarineBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0); self::register(new Solid(new BID(Ids::PRISMARINE, Meta::PRISMARINE_BRICKS), "Prismarine Bricks", $prismarineBreakInfo)); self::register(new Stair(new BID(Ids::PRISMARINE_BRICKS_STAIRS), "Prismarine Bricks Stairs", $prismarineBreakInfo)); self::register(new Solid(new BID(Ids::PRISMARINE, Meta::PRISMARINE_DARK), "Dark Prismarine", $prismarineBreakInfo)); @@ -266,14 +266,14 @@ class BlockFactory{ self::register(new Pumpkin(new BID(Ids::PUMPKIN), "Pumpkin")); self::register(new PumpkinStem(new BID(Ids::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem")); - $purpurBreakInfo = new BlockBreakInfo(1.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0); + $purpurBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0); self::register(new Solid(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_NORMAL), "Purpur Block", $purpurBreakInfo)); self::register(new class(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_PILLAR), "Purpur Pillar", $purpurBreakInfo) extends Solid{ use PillarRotationTrait; }); self::register(new Stair(new BID(Ids::PURPUR_STAIRS), "Purpur Stairs", $purpurBreakInfo)); - $quartzBreakInfo = new BlockBreakInfo(0.8, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN); + $quartzBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN); self::register(new Solid(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_NORMAL), "Quartz Block", $quartzBreakInfo)); self::register(new Stair(new BID(Ids::QUARTZ_STAIRS), "Quartz Stairs", $quartzBreakInfo)); self::register(new class(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_CHISELED), "Chiseled Quartz Block", $quartzBreakInfo) extends Solid{ @@ -309,7 +309,7 @@ class BlockFactory{ self::register(new SoulSand(new BID(Ids::SOUL_SAND), "Soul Sand")); self::register(new Sponge(new BID(Ids::SPONGE), "Sponge")); - $stoneBreakInfo = new BlockBreakInfo(1.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0); + $stoneBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0); self::register(new class(new BID(Ids::STONE, Meta::STONE_NORMAL), "Stone", $stoneBreakInfo) extends Solid{ public function getDropsForCompatibleTool(Item $item) : array{ return [ItemFactory::get(Item::COBBLESTONE)]; @@ -339,7 +339,7 @@ class BlockFactory{ self::register(new StonePressurePlate(new BID(Ids::STONE_PRESSURE_PLATE), "Stone Pressure Plate")); //TODO: in the future this won't be the same for all the types - $stoneSlabBreakInfo = new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0); + $stoneSlabBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0); self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_BRICK), "Brick", $stoneSlabBreakInfo)); self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_COBBLESTONE), "Cobblestone", $stoneSlabBreakInfo)); self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_FAKE_WOODEN), "Fake Wooden", $stoneSlabBreakInfo)); @@ -369,7 +369,7 @@ class BlockFactory{ self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_MOSSY_STONE_BRICK), "Mossy Stone Brick", $stoneSlabBreakInfo)); self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_SMOOTH_QUARTZ), "Smooth Quartz", $stoneSlabBreakInfo)); self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_STONE), "Stone", $stoneSlabBreakInfo)); - self::register(new Solid(new BID(Ids::STONECUTTER), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN))); + self::register(new Solid(new BID(Ids::STONECUTTER), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN))); self::register(new Sugarcane(new BID(Ids::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane")); self::register(new TNT(new BID(Ids::TNT), "TNT")); self::register(new TallGrass(new BID(Ids::TALLGRASS), "Fern")); //TODO: remap this to normal fern @@ -491,7 +491,7 @@ class BlockFactory{ Meta::SANDSTONE_CUT => "Cut ", Meta::SANDSTONE_SMOOTH => "Smooth " ]; - $sandstoneBreakInfo = new BlockBreakInfo(0.8, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN); + $sandstoneBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN); self::register(new Stair(new BID(Ids::RED_SANDSTONE_STAIRS), "Red Sandstone Stairs", $sandstoneBreakInfo)); self::register(new Stair(new BID(Ids::SMOOTH_RED_SANDSTONE_STAIRS), "Smooth Red Sandstone Stairs", $sandstoneBreakInfo)); self::register(new Stair(new BID(Ids::SANDSTONE_STAIRS), "Sandstone Stairs", $sandstoneBreakInfo)); diff --git a/src/pocketmine/block/BlockToolType.php b/src/pocketmine/block/BlockToolType.php index 17670e1c79..ca58763594 100644 --- a/src/pocketmine/block/BlockToolType.php +++ b/src/pocketmine/block/BlockToolType.php @@ -29,11 +29,11 @@ namespace pocketmine\block; */ interface BlockToolType{ - public const TYPE_NONE = 0; - public const TYPE_SWORD = 1 << 0; - public const TYPE_SHOVEL = 1 << 1; - public const TYPE_PICKAXE = 1 << 2; - public const TYPE_AXE = 1 << 3; - public const TYPE_SHEARS = 1 << 4; + public const NONE = 0; + public const SWORD = 1 << 0; + public const SHOVEL = 1 << 1; + public const PICKAXE = 1 << 2; + public const AXE = 1 << 3; + public const SHEARS = 1 << 4; } diff --git a/src/pocketmine/block/BlueIce.php b/src/pocketmine/block/BlueIce.php index 07fa1c6902..bb6c0b152c 100644 --- a/src/pocketmine/block/BlueIce.php +++ b/src/pocketmine/block/BlueIce.php @@ -28,7 +28,7 @@ use pocketmine\item\Item; class BlueIce extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.8, BlockToolType::TYPE_PICKAXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.8, BlockToolType::PICKAXE)); } public function getLightLevel() : int{ diff --git a/src/pocketmine/block/BoneBlock.php b/src/pocketmine/block/BoneBlock.php index 4b95c222b6..36f8f751e9 100644 --- a/src/pocketmine/block/BoneBlock.php +++ b/src/pocketmine/block/BoneBlock.php @@ -30,6 +30,6 @@ class BoneBlock extends Solid{ use PillarRotationTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); } } diff --git a/src/pocketmine/block/Bookshelf.php b/src/pocketmine/block/Bookshelf.php index 30729420c9..aa49940c39 100644 --- a/src/pocketmine/block/Bookshelf.php +++ b/src/pocketmine/block/Bookshelf.php @@ -29,7 +29,7 @@ use pocketmine\item\ItemFactory; class Bookshelf extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.5, BlockToolType::TYPE_AXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.5, BlockToolType::AXE)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/BrewingStand.php b/src/pocketmine/block/BrewingStand.php index 1cfe4125ab..13ef6f11d4 100644 --- a/src/pocketmine/block/BrewingStand.php +++ b/src/pocketmine/block/BrewingStand.php @@ -39,7 +39,7 @@ class BrewingStand extends Transparent{ protected $southwestSlot = false; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index baae80b328..e01ceae5df 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -38,7 +38,7 @@ class Chest extends Transparent{ protected $facing = Facing::NORTH; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.5, BlockToolType::TYPE_AXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.5, BlockToolType::AXE)); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/Clay.php b/src/pocketmine/block/Clay.php index f32f808ce7..277e700f74 100644 --- a/src/pocketmine/block/Clay.php +++ b/src/pocketmine/block/Clay.php @@ -29,7 +29,7 @@ use pocketmine\item\ItemFactory; class Clay extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::TYPE_SHOVEL)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::SHOVEL)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/Coal.php b/src/pocketmine/block/Coal.php index 097b883ff8..1b7fae1d51 100644 --- a/src/pocketmine/block/Coal.php +++ b/src/pocketmine/block/Coal.php @@ -28,7 +28,7 @@ use pocketmine\item\TieredTool; class Coal extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } public function getFuelTime() : int{ diff --git a/src/pocketmine/block/CoalOre.php b/src/pocketmine/block/CoalOre.php index 090509bbc3..45a693ee48 100644 --- a/src/pocketmine/block/CoalOre.php +++ b/src/pocketmine/block/CoalOre.php @@ -31,7 +31,7 @@ use function mt_rand; class CoalOre extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/Cobweb.php b/src/pocketmine/block/Cobweb.php index c3ea9447c5..012c2cf9d4 100644 --- a/src/pocketmine/block/Cobweb.php +++ b/src/pocketmine/block/Cobweb.php @@ -30,7 +30,7 @@ use pocketmine\item\ItemFactory; class Cobweb extends Flowable{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(4.0, BlockToolType::TYPE_SWORD | BlockToolType::TYPE_SHEARS, 1)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(4.0, BlockToolType::SWORD | BlockToolType::SHEARS, 1)); } public function hasEntityCollision() : bool{ diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index 06e2dfac7a..2995390d70 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -44,7 +44,7 @@ class CocoaBlock extends Transparent{ protected $age = 0; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::TYPE_AXE, 0, 15.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::AXE, 0, 15.0)); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/Concrete.php b/src/pocketmine/block/Concrete.php index 38af139761..1ef4806c6b 100644 --- a/src/pocketmine/block/Concrete.php +++ b/src/pocketmine/block/Concrete.php @@ -28,6 +28,6 @@ use pocketmine\item\TieredTool; class Concrete extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.8, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.8, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); } } diff --git a/src/pocketmine/block/ConcretePowder.php b/src/pocketmine/block/ConcretePowder.php index e18f1a9527..d4adec673e 100644 --- a/src/pocketmine/block/ConcretePowder.php +++ b/src/pocketmine/block/ConcretePowder.php @@ -33,7 +33,7 @@ class ConcretePowder extends Solid implements Fallable{ } public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_SHOVEL)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::SHOVEL)); } public function onNearbyBlockChange() : void{ diff --git a/src/pocketmine/block/CraftingTable.php b/src/pocketmine/block/CraftingTable.php index 453483a1b0..e63fd3f10f 100644 --- a/src/pocketmine/block/CraftingTable.php +++ b/src/pocketmine/block/CraftingTable.php @@ -31,7 +31,7 @@ use pocketmine\player\Player; class CraftingTable extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.5, BlockToolType::TYPE_AXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.5, BlockToolType::AXE)); } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/pocketmine/block/DaylightSensor.php b/src/pocketmine/block/DaylightSensor.php index 596e71deee..27ec0ee768 100644 --- a/src/pocketmine/block/DaylightSensor.php +++ b/src/pocketmine/block/DaylightSensor.php @@ -45,7 +45,7 @@ class DaylightSensor extends Transparent{ protected $inverted = false; public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::TYPE_AXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::AXE)); } public function getId() : int{ diff --git a/src/pocketmine/block/DeadBush.php b/src/pocketmine/block/DeadBush.php index 19ff078c09..0239a7afb0 100644 --- a/src/pocketmine/block/DeadBush.php +++ b/src/pocketmine/block/DeadBush.php @@ -34,7 +34,7 @@ use function mt_rand; class DeadBush extends Flowable{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant(BlockToolType::TYPE_SHEARS, 1)); + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant(BlockToolType::SHEARS, 1)); } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/pocketmine/block/DiamondOre.php b/src/pocketmine/block/DiamondOre.php index e872f78d8b..546e292542 100644 --- a/src/pocketmine/block/DiamondOre.php +++ b/src/pocketmine/block/DiamondOre.php @@ -31,7 +31,7 @@ use function mt_rand; class DiamondOre extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_IRON)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/Dirt.php b/src/pocketmine/block/Dirt.php index f1db0380e8..75ecc73eec 100644 --- a/src/pocketmine/block/Dirt.php +++ b/src/pocketmine/block/Dirt.php @@ -32,7 +32,7 @@ use pocketmine\player\Player; class Dirt extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_SHOVEL)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::SHOVEL)); } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/pocketmine/block/DoubleTallGrass.php b/src/pocketmine/block/DoubleTallGrass.php index c0b5d858fe..662b4ca269 100644 --- a/src/pocketmine/block/DoubleTallGrass.php +++ b/src/pocketmine/block/DoubleTallGrass.php @@ -30,7 +30,7 @@ use function mt_rand; class DoubleTallGrass extends DoublePlant{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant(BlockToolType::TYPE_SHEARS, 1)); + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant(BlockToolType::SHEARS, 1)); } public function canBeReplaced() : bool{ diff --git a/src/pocketmine/block/DragonEgg.php b/src/pocketmine/block/DragonEgg.php index f90fb3da74..b2bd03efed 100644 --- a/src/pocketmine/block/DragonEgg.php +++ b/src/pocketmine/block/DragonEgg.php @@ -40,7 +40,7 @@ class DragonEgg extends Transparent implements Fallable{ use FallableTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); } public function getLightLevel() : int{ diff --git a/src/pocketmine/block/EmeraldOre.php b/src/pocketmine/block/EmeraldOre.php index d9d48df4af..178b34e2e7 100644 --- a/src/pocketmine/block/EmeraldOre.php +++ b/src/pocketmine/block/EmeraldOre.php @@ -31,7 +31,7 @@ use function mt_rand; class EmeraldOre extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_IRON)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/EnchantingTable.php b/src/pocketmine/block/EnchantingTable.php index 5afb805a51..96af742a2d 100644 --- a/src/pocketmine/block/EnchantingTable.php +++ b/src/pocketmine/block/EnchantingTable.php @@ -34,7 +34,7 @@ use pocketmine\player\Player; class EnchantingTable extends Transparent{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 6000.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 6000.0)); } protected function recalculateBoundingBox() : ?AxisAlignedBB{ diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index 17287b49c8..4902b46f41 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -40,7 +40,7 @@ class EnderChest extends Transparent{ protected $facing = Facing::NORTH; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(22.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 3000.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(22.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 3000.0)); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index 70a5353305..95398761c1 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -35,7 +35,7 @@ class Farmland extends Transparent{ protected $wetness = 0; //"moisture" blockstate property in PC public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::TYPE_SHOVEL)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::SHOVEL)); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index 41ae3543ba..3146a9470c 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -42,7 +42,7 @@ class FenceGate extends Transparent{ protected $inWall = false; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_AXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::AXE)); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/FrostedIce.php b/src/pocketmine/block/FrostedIce.php index c1effff0ff..e3220ea9dc 100644 --- a/src/pocketmine/block/FrostedIce.php +++ b/src/pocketmine/block/FrostedIce.php @@ -33,7 +33,7 @@ class FrostedIce extends Ice{ protected $age = 0; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.5, BlockToolType::TYPE_PICKAXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.5, BlockToolType::PICKAXE)); } public function readStateFromData(int $id, int $stateMeta) : void{ diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index 404df7f19d..b242958ccc 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -42,7 +42,7 @@ class Furnace extends Solid{ protected $lit = false; //this is set based on the blockID public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); } public function getId() : int{ diff --git a/src/pocketmine/block/GlazedTerracotta.php b/src/pocketmine/block/GlazedTerracotta.php index 196d6d10d6..781492db79 100644 --- a/src/pocketmine/block/GlazedTerracotta.php +++ b/src/pocketmine/block/GlazedTerracotta.php @@ -38,7 +38,7 @@ class GlazedTerracotta extends Solid{ protected $facing = Facing::NORTH; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.4, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.4, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/GlowingObsidian.php b/src/pocketmine/block/GlowingObsidian.php index 4f63de52dd..9dfb73b300 100644 --- a/src/pocketmine/block/GlowingObsidian.php +++ b/src/pocketmine/block/GlowingObsidian.php @@ -29,7 +29,7 @@ use pocketmine\item\TieredTool; class GlowingObsidian extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(10.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_DIAMOND, 50.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(10.0, BlockToolType::PICKAXE, TieredTool::TIER_DIAMOND, 50.0)); } public function getLightLevel() : int{ diff --git a/src/pocketmine/block/Glowstone.php b/src/pocketmine/block/Glowstone.php index c09ab8437f..9b8501fdb2 100644 --- a/src/pocketmine/block/Glowstone.php +++ b/src/pocketmine/block/Glowstone.php @@ -30,7 +30,7 @@ use function mt_rand; class Glowstone extends Transparent{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.3, BlockToolType::TYPE_PICKAXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.3, BlockToolType::PICKAXE)); } public function getLightLevel() : int{ diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index aa89356969..cc0d6588fe 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -39,7 +39,7 @@ use function mt_rand; class Grass extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::TYPE_SHOVEL)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::SHOVEL)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/GrassPath.php b/src/pocketmine/block/GrassPath.php index de41bbf38f..640da5dafb 100644 --- a/src/pocketmine/block/GrassPath.php +++ b/src/pocketmine/block/GrassPath.php @@ -31,7 +31,7 @@ use pocketmine\math\Facing; class GrassPath extends Transparent{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::TYPE_SHOVEL)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::SHOVEL)); } protected function recalculateBoundingBox() : ?AxisAlignedBB{ diff --git a/src/pocketmine/block/Gravel.php b/src/pocketmine/block/Gravel.php index 01b3ddd6eb..2303883609 100644 --- a/src/pocketmine/block/Gravel.php +++ b/src/pocketmine/block/Gravel.php @@ -33,7 +33,7 @@ class Gravel extends Solid implements Fallable{ use FallableTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::TYPE_SHOVEL)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::SHOVEL)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/HardenedClay.php b/src/pocketmine/block/HardenedClay.php index 88902b756b..8c46c4ad1e 100644 --- a/src/pocketmine/block/HardenedClay.php +++ b/src/pocketmine/block/HardenedClay.php @@ -28,6 +28,6 @@ use pocketmine\item\TieredTool; class HardenedClay extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.25, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 21.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.25, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 21.0)); } } diff --git a/src/pocketmine/block/Ice.php b/src/pocketmine/block/Ice.php index d62193cc35..893a347824 100644 --- a/src/pocketmine/block/Ice.php +++ b/src/pocketmine/block/Ice.php @@ -30,7 +30,7 @@ use pocketmine\player\Player; class Ice extends Transparent{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_PICKAXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE)); } public function getLightFilter() : int{ diff --git a/src/pocketmine/block/Ladder.php b/src/pocketmine/block/Ladder.php index 2440ac50a7..632e712647 100644 --- a/src/pocketmine/block/Ladder.php +++ b/src/pocketmine/block/Ladder.php @@ -38,7 +38,7 @@ class Ladder extends Transparent{ protected $facing = Facing::NORTH; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.4, BlockToolType::TYPE_AXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.4, BlockToolType::AXE)); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/LapisOre.php b/src/pocketmine/block/LapisOre.php index a9554559d7..b401b9c6bf 100644 --- a/src/pocketmine/block/LapisOre.php +++ b/src/pocketmine/block/LapisOre.php @@ -31,7 +31,7 @@ use function mt_rand; class LapisOre extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_STONE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_STONE)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index a8c9d05375..864f0e3d3f 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -44,7 +44,7 @@ class Leaves extends Transparent{ protected $checkDecay = false; public function __construct(BlockIdentifier $idInfo, string $name, TreeType $treeType, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::TYPE_SHEARS)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::SHEARS)); $this->treeType = $treeType; } @@ -118,7 +118,7 @@ class Leaves extends Transparent{ } public function getDrops(Item $item) : array{ - if($item->getBlockToolType() & BlockToolType::TYPE_SHEARS){ + if($item->getBlockToolType() & BlockToolType::SHEARS){ return $this->getDropsForCompatibleTool($item); } diff --git a/src/pocketmine/block/Magma.php b/src/pocketmine/block/Magma.php index 266bd5fe9e..887dba1b37 100644 --- a/src/pocketmine/block/Magma.php +++ b/src/pocketmine/block/Magma.php @@ -31,7 +31,7 @@ use pocketmine\item\TieredTool; class Magma extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); } public function getLightLevel() : int{ diff --git a/src/pocketmine/block/Melon.php b/src/pocketmine/block/Melon.php index 3a08773fbb..ee5424ce8c 100644 --- a/src/pocketmine/block/Melon.php +++ b/src/pocketmine/block/Melon.php @@ -30,7 +30,7 @@ use function mt_rand; class Melon extends Transparent{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0, BlockToolType::TYPE_AXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0, BlockToolType::AXE)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/MonsterSpawner.php b/src/pocketmine/block/MonsterSpawner.php index ca38aae65d..d545b0427c 100644 --- a/src/pocketmine/block/MonsterSpawner.php +++ b/src/pocketmine/block/MonsterSpawner.php @@ -30,7 +30,7 @@ use function mt_rand; class MonsterSpawner extends Transparent{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/Mycelium.php b/src/pocketmine/block/Mycelium.php index 40027b93a8..ef5ac71c30 100644 --- a/src/pocketmine/block/Mycelium.php +++ b/src/pocketmine/block/Mycelium.php @@ -32,7 +32,7 @@ use function mt_rand; class Mycelium extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::TYPE_SHOVEL)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::SHOVEL)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/NetherQuartzOre.php b/src/pocketmine/block/NetherQuartzOre.php index a72851d1e2..f8d4ebdfe4 100644 --- a/src/pocketmine/block/NetherQuartzOre.php +++ b/src/pocketmine/block/NetherQuartzOre.php @@ -31,7 +31,7 @@ use function mt_rand; class NetherQuartzOre extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/NetherReactor.php b/src/pocketmine/block/NetherReactor.php index f144f1c28c..47f8048d24 100644 --- a/src/pocketmine/block/NetherReactor.php +++ b/src/pocketmine/block/NetherReactor.php @@ -34,7 +34,7 @@ class NetherReactor extends Solid{ protected $state = BlockLegacyMetadata::NETHER_REACTOR_INACTIVE; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/Netherrack.php b/src/pocketmine/block/Netherrack.php index e5e84dd113..a6a3f70e60 100644 --- a/src/pocketmine/block/Netherrack.php +++ b/src/pocketmine/block/Netherrack.php @@ -28,7 +28,7 @@ use pocketmine\item\TieredTool; class Netherrack extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.4, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.4, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); } public function burnsForever() : bool{ diff --git a/src/pocketmine/block/Note.php b/src/pocketmine/block/Note.php index d9be134765..ca298c5516 100644 --- a/src/pocketmine/block/Note.php +++ b/src/pocketmine/block/Note.php @@ -34,7 +34,7 @@ class Note extends Solid{ private $pitch = self::MIN_PITCH; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.8, BlockToolType::TYPE_AXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.8, BlockToolType::AXE)); } public function readStateFromWorld() : void{ diff --git a/src/pocketmine/block/PackedIce.php b/src/pocketmine/block/PackedIce.php index 298ce4bb3d..a5bca2726f 100644 --- a/src/pocketmine/block/PackedIce.php +++ b/src/pocketmine/block/PackedIce.php @@ -28,7 +28,7 @@ use pocketmine\item\Item; class PackedIce extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_PICKAXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE)); } public function getFrictionFactor() : float{ diff --git a/src/pocketmine/block/Planks.php b/src/pocketmine/block/Planks.php index 9da5889c79..593d21147a 100644 --- a/src/pocketmine/block/Planks.php +++ b/src/pocketmine/block/Planks.php @@ -26,7 +26,7 @@ namespace pocketmine\block; class Planks extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_AXE, 0, 15.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::AXE, 0, 15.0)); } public function getFuelTime() : int{ diff --git a/src/pocketmine/block/Podzol.php b/src/pocketmine/block/Podzol.php index df2f931dda..20e55c1b01 100644 --- a/src/pocketmine/block/Podzol.php +++ b/src/pocketmine/block/Podzol.php @@ -26,6 +26,6 @@ namespace pocketmine\block; class Podzol extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.5, BlockToolType::TYPE_SHOVEL)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.5, BlockToolType::SHOVEL)); } } diff --git a/src/pocketmine/block/Pumpkin.php b/src/pocketmine/block/Pumpkin.php index 335835630a..568b366f12 100644 --- a/src/pocketmine/block/Pumpkin.php +++ b/src/pocketmine/block/Pumpkin.php @@ -37,7 +37,7 @@ class Pumpkin extends Solid{ protected $facing = Facing::NORTH; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0, BlockToolType::TYPE_AXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0, BlockToolType::AXE)); } public function readStateFromData(int $id, int $stateMeta) : void{ diff --git a/src/pocketmine/block/RedMushroomBlock.php b/src/pocketmine/block/RedMushroomBlock.php index 409e946532..68786a7886 100644 --- a/src/pocketmine/block/RedMushroomBlock.php +++ b/src/pocketmine/block/RedMushroomBlock.php @@ -38,7 +38,7 @@ class RedMushroomBlock extends Solid{ protected $rotationData = 0; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::TYPE_AXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::AXE)); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/Redstone.php b/src/pocketmine/block/Redstone.php index 7195844bb6..b4400b0c14 100644 --- a/src/pocketmine/block/Redstone.php +++ b/src/pocketmine/block/Redstone.php @@ -28,6 +28,6 @@ use pocketmine\item\TieredTool; class Redstone extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } } diff --git a/src/pocketmine/block/RedstoneOre.php b/src/pocketmine/block/RedstoneOre.php index 863c4fea83..b4b42873c3 100644 --- a/src/pocketmine/block/RedstoneOre.php +++ b/src/pocketmine/block/RedstoneOre.php @@ -38,7 +38,7 @@ class RedstoneOre extends Solid{ protected $lit = false; public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_IRON)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_IRON)); } public function getId() : int{ diff --git a/src/pocketmine/block/Sand.php b/src/pocketmine/block/Sand.php index 1a5101921e..ce13cabcce 100644 --- a/src/pocketmine/block/Sand.php +++ b/src/pocketmine/block/Sand.php @@ -30,7 +30,7 @@ class Sand extends Solid implements Fallable{ use FallableTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_SHOVEL)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::SHOVEL)); } public function tickFalling() : ?Block{ diff --git a/src/pocketmine/block/Sign.php b/src/pocketmine/block/Sign.php index a865d80ef0..21639cea6d 100644 --- a/src/pocketmine/block/Sign.php +++ b/src/pocketmine/block/Sign.php @@ -55,7 +55,7 @@ class Sign extends Transparent{ protected $text; public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0, BlockToolType::TYPE_AXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0, BlockToolType::AXE)); $this->text = new SignText(); } diff --git a/src/pocketmine/block/Snow.php b/src/pocketmine/block/Snow.php index dea7b5d61e..b88474ce18 100644 --- a/src/pocketmine/block/Snow.php +++ b/src/pocketmine/block/Snow.php @@ -30,7 +30,7 @@ use pocketmine\item\TieredTool; class Snow extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::TYPE_SHOVEL, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::SHOVEL, TieredTool::TIER_WOODEN)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index 80c2827014..1960eea1b0 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -44,7 +44,7 @@ class SnowLayer extends Flowable implements Fallable{ protected $layers = 1; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.1, BlockToolType::TYPE_SHOVEL, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.1, BlockToolType::SHOVEL, TieredTool::TIER_WOODEN)); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/SoulSand.php b/src/pocketmine/block/SoulSand.php index bcf2fb4faf..b613a9f5ed 100644 --- a/src/pocketmine/block/SoulSand.php +++ b/src/pocketmine/block/SoulSand.php @@ -29,7 +29,7 @@ use pocketmine\math\Facing; class SoulSand extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_SHOVEL)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::SHOVEL)); } protected function recalculateBoundingBox() : ?AxisAlignedBB{ diff --git a/src/pocketmine/block/StoneButton.php b/src/pocketmine/block/StoneButton.php index 36bbefec79..d92a3552ff 100644 --- a/src/pocketmine/block/StoneButton.php +++ b/src/pocketmine/block/StoneButton.php @@ -26,7 +26,7 @@ namespace pocketmine\block; class StoneButton extends Button{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_PICKAXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE)); } protected function getActivationTime() : int{ diff --git a/src/pocketmine/block/StonePressurePlate.php b/src/pocketmine/block/StonePressurePlate.php index 411b5e0fa6..a6c1c0de63 100644 --- a/src/pocketmine/block/StonePressurePlate.php +++ b/src/pocketmine/block/StonePressurePlate.php @@ -28,6 +28,6 @@ use pocketmine\item\TieredTool; class StonePressurePlate extends SimplePressurePlate{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); } } diff --git a/src/pocketmine/block/TallGrass.php b/src/pocketmine/block/TallGrass.php index 13c054410c..bdc093688d 100644 --- a/src/pocketmine/block/TallGrass.php +++ b/src/pocketmine/block/TallGrass.php @@ -34,7 +34,7 @@ use function mt_rand; class TallGrass extends Flowable{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant(BlockToolType::TYPE_SHEARS, 1)); + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant(BlockToolType::SHEARS, 1)); } public function canBeReplaced() : bool{ diff --git a/src/pocketmine/block/Vine.php b/src/pocketmine/block/Vine.php index 4c320540e0..a3706442c0 100644 --- a/src/pocketmine/block/Vine.php +++ b/src/pocketmine/block/Vine.php @@ -40,7 +40,7 @@ class Vine extends Flowable{ protected $faces = []; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::TYPE_AXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::AXE)); } protected function writeStateToMeta() : int{ @@ -144,7 +144,7 @@ class Vine extends Flowable{ } public function getDrops(Item $item) : array{ - if($item->getBlockToolType() & BlockToolType::TYPE_SHEARS){ + if($item->getBlockToolType() & BlockToolType::SHEARS){ return $this->getDropsForCompatibleTool($item); } diff --git a/src/pocketmine/block/Wall.php b/src/pocketmine/block/Wall.php index dd9ffdc656..e4462767dc 100644 --- a/src/pocketmine/block/Wall.php +++ b/src/pocketmine/block/Wall.php @@ -35,7 +35,7 @@ class Wall extends Transparent{ protected $up = false; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN, 30.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0)); } public function readStateFromWorld() : void{ diff --git a/src/pocketmine/block/WeightedPressurePlateHeavy.php b/src/pocketmine/block/WeightedPressurePlateHeavy.php index 00220d80c8..40fd3c507b 100644 --- a/src/pocketmine/block/WeightedPressurePlateHeavy.php +++ b/src/pocketmine/block/WeightedPressurePlateHeavy.php @@ -28,6 +28,6 @@ use pocketmine\item\TieredTool; class WeightedPressurePlateHeavy extends WeightedPressurePlate{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); } } diff --git a/src/pocketmine/block/WeightedPressurePlateLight.php b/src/pocketmine/block/WeightedPressurePlateLight.php index 54cf57f5f8..44b2f41e28 100644 --- a/src/pocketmine/block/WeightedPressurePlateLight.php +++ b/src/pocketmine/block/WeightedPressurePlateLight.php @@ -28,6 +28,6 @@ use pocketmine\item\TieredTool; class WeightedPressurePlateLight extends WeightedPressurePlate{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); } } diff --git a/src/pocketmine/block/Wood.php b/src/pocketmine/block/Wood.php index 2882c002c1..31bbeb7df0 100644 --- a/src/pocketmine/block/Wood.php +++ b/src/pocketmine/block/Wood.php @@ -31,7 +31,7 @@ class Wood extends Solid{ private $treeType; public function __construct(BlockIdentifier $idInfo, string $name, TreeType $treeType, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_AXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::AXE)); $this->treeType = $treeType; } diff --git a/src/pocketmine/block/WoodenButton.php b/src/pocketmine/block/WoodenButton.php index 0cbec1f93b..9cfdb0dc71 100644 --- a/src/pocketmine/block/WoodenButton.php +++ b/src/pocketmine/block/WoodenButton.php @@ -26,7 +26,7 @@ namespace pocketmine\block; class WoodenButton extends Button{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_AXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::AXE)); } protected function getActivationTime() : int{ diff --git a/src/pocketmine/block/WoodenDoor.php b/src/pocketmine/block/WoodenDoor.php index 1686a7c820..4edd42a41b 100644 --- a/src/pocketmine/block/WoodenDoor.php +++ b/src/pocketmine/block/WoodenDoor.php @@ -26,6 +26,6 @@ namespace pocketmine\block; class WoodenDoor extends Door{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_AXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::AXE)); } } diff --git a/src/pocketmine/block/WoodenFence.php b/src/pocketmine/block/WoodenFence.php index eec484a7f1..070c36a1a8 100644 --- a/src/pocketmine/block/WoodenFence.php +++ b/src/pocketmine/block/WoodenFence.php @@ -26,7 +26,7 @@ namespace pocketmine\block; class WoodenFence extends Fence{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_AXE, 0, 15.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::AXE, 0, 15.0)); } public function getFuelTime() : int{ diff --git a/src/pocketmine/block/WoodenPressurePlate.php b/src/pocketmine/block/WoodenPressurePlate.php index 996ec27d1b..4e624d2812 100644 --- a/src/pocketmine/block/WoodenPressurePlate.php +++ b/src/pocketmine/block/WoodenPressurePlate.php @@ -26,7 +26,7 @@ namespace pocketmine\block; class WoodenPressurePlate extends SimplePressurePlate{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::TYPE_AXE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::AXE)); } public function getFuelTime() : int{ diff --git a/src/pocketmine/block/WoodenSlab.php b/src/pocketmine/block/WoodenSlab.php index 474036490a..9c713c2ac2 100644 --- a/src/pocketmine/block/WoodenSlab.php +++ b/src/pocketmine/block/WoodenSlab.php @@ -26,7 +26,7 @@ namespace pocketmine\block; class WoodenSlab extends Slab{ public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_AXE, 0, 15.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::AXE, 0, 15.0)); } public function getFuelTime() : int{ diff --git a/src/pocketmine/block/WoodenStairs.php b/src/pocketmine/block/WoodenStairs.php index 09d7ab2b25..2550d91a6d 100644 --- a/src/pocketmine/block/WoodenStairs.php +++ b/src/pocketmine/block/WoodenStairs.php @@ -26,7 +26,7 @@ namespace pocketmine\block; class WoodenStairs extends Stair{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::TYPE_AXE, 0, 15.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::AXE, 0, 15.0)); } public function getFlameEncouragement() : int{ diff --git a/src/pocketmine/block/WoodenTrapdoor.php b/src/pocketmine/block/WoodenTrapdoor.php index ace3a2baae..07a73872ca 100644 --- a/src/pocketmine/block/WoodenTrapdoor.php +++ b/src/pocketmine/block/WoodenTrapdoor.php @@ -26,7 +26,7 @@ namespace pocketmine\block; class WoodenTrapdoor extends Trapdoor{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::TYPE_AXE, 0, 15.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::AXE, 0, 15.0)); } public function getFuelTime() : int{ diff --git a/src/pocketmine/block/Wool.php b/src/pocketmine/block/Wool.php index c13ad3af0d..63f6bf531a 100644 --- a/src/pocketmine/block/Wool.php +++ b/src/pocketmine/block/Wool.php @@ -28,10 +28,10 @@ use pocketmine\item\Item; class Wool extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new class(0.8, BlockToolType::TYPE_SHEARS) extends BlockBreakInfo{ + parent::__construct($idInfo, $name, $breakInfo ?? new class(0.8, BlockToolType::SHEARS) extends BlockBreakInfo{ public function getBreakTime(Item $item) : float{ $time = parent::getBreakTime($item); - if($item->getBlockToolType() === BlockToolType::TYPE_SHEARS){ + if($item->getBlockToolType() === BlockToolType::SHEARS){ $time *= 3; //shears break compatible blocks 15x faster, but wool 5x } diff --git a/src/pocketmine/item/Axe.php b/src/pocketmine/item/Axe.php index 08c08f953f..816f464445 100644 --- a/src/pocketmine/item/Axe.php +++ b/src/pocketmine/item/Axe.php @@ -30,7 +30,7 @@ use pocketmine\entity\Entity; class Axe extends TieredTool{ public function getBlockToolType() : int{ - return BlockToolType::TYPE_AXE; + return BlockToolType::AXE; } public function getBlockToolHarvestLevel() : int{ diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 0f6257b5fb..7a4c2aca10 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -595,7 +595,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return int */ public function getBlockToolType() : int{ - return BlockToolType::TYPE_NONE; + return BlockToolType::NONE; } /** diff --git a/src/pocketmine/item/Pickaxe.php b/src/pocketmine/item/Pickaxe.php index d5b49c3fa2..76fbd49d1c 100644 --- a/src/pocketmine/item/Pickaxe.php +++ b/src/pocketmine/item/Pickaxe.php @@ -30,7 +30,7 @@ use pocketmine\entity\Entity; class Pickaxe extends TieredTool{ public function getBlockToolType() : int{ - return BlockToolType::TYPE_PICKAXE; + return BlockToolType::PICKAXE; } public function getBlockToolHarvestLevel() : int{ diff --git a/src/pocketmine/item/Shears.php b/src/pocketmine/item/Shears.php index bc99b02b6c..888b6ce759 100644 --- a/src/pocketmine/item/Shears.php +++ b/src/pocketmine/item/Shears.php @@ -33,7 +33,7 @@ class Shears extends Tool{ } public function getBlockToolType() : int{ - return BlockToolType::TYPE_SHEARS; + return BlockToolType::SHEARS; } public function getBlockToolHarvestLevel() : int{ diff --git a/src/pocketmine/item/Shovel.php b/src/pocketmine/item/Shovel.php index d9a1b0f500..f3afc9494e 100644 --- a/src/pocketmine/item/Shovel.php +++ b/src/pocketmine/item/Shovel.php @@ -30,7 +30,7 @@ use pocketmine\entity\Entity; class Shovel extends TieredTool{ public function getBlockToolType() : int{ - return BlockToolType::TYPE_SHOVEL; + return BlockToolType::SHOVEL; } public function getBlockToolHarvestLevel() : int{ diff --git a/src/pocketmine/item/Sword.php b/src/pocketmine/item/Sword.php index 5f801461d4..24c46a36e2 100644 --- a/src/pocketmine/item/Sword.php +++ b/src/pocketmine/item/Sword.php @@ -30,7 +30,7 @@ use pocketmine\entity\Entity; class Sword extends TieredTool{ public function getBlockToolType() : int{ - return BlockToolType::TYPE_SWORD; + return BlockToolType::SWORD; } public function getAttackPoints() : int{ From 134a87ec7d33f86cd4f00a6ca3142bca04a035fb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 3 Jul 2019 18:26:01 +0100 Subject: [PATCH 1039/3224] BlockFactory: regenerate TODOs --- src/pocketmine/block/BlockFactory.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 555847800e..079b7da713 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -585,13 +585,11 @@ class BlockFactory{ //TODO: minecraft:coral_fan_hang2 //TODO: minecraft:coral_fan_hang3 //TODO: minecraft:dispenser - //TODO: minecraft:dried_kelp_block //TODO: minecraft:dropper //TODO: minecraft:end_gateway //TODO: minecraft:end_portal //TODO: minecraft:fletching_table //TODO: minecraft:grindstone - //TODO: minecraft:hopper //TODO: minecraft:jigsaw //TODO: minecraft:jukebox //TODO: minecraft:kelp From 4c5d8c12dd472574dc3d4e1b49341b3e70c56da4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 3 Jul 2019 18:32:20 +0100 Subject: [PATCH 1040/3224] [ci skip] more updates to changelog --- changelogs/4.0-snapshot.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 3594ce7796..8bd9fe7bc0 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -136,6 +136,7 @@ This version features substantial changes to the network system, improving coher - `WallBanner` - `WallSign` - `Wood2` +- `BlockToolType` constants have been renamed to remove the `TYPE_` prefix. ### Command - The following classes have been removed: @@ -449,6 +450,8 @@ This version features substantial changes to the network system, improving coher - API version checks are now more strict. It is no longer legal to declare multiple minimum versions on the same major version. Doing so will now cause the plugin to fail to load with the message `Multiple minimum API versions found for some major versions`. - `plugin.yml` YAML commands loading is now internalized inside `PluginBase`. - `PluginManager->registerEvent()` now has a simpler signature: `registerEvent(string $event, \Closure $handler, int $priority, Plugin $plugin, bool $handleCancelled = false)`. The provided closure must accept the specified event class as its only parameter. See [Event API changes](#event) for more details. +- The following classes have been removed: + - `PluginLogger` - The following interface requirements have been removed: - `Plugin->onEnable()`: this is now internalized inside `PluginBase` - `Plugin->onDisable()`: same as above @@ -484,6 +487,8 @@ This version features substantial changes to the network system, improving coher - Values are automatically removed from storage when the `AsyncTask` is garbage-collected, just like a regular property. - Supports storing multiple values, differentiated by string names. - `fetchLocal()` can now be used multiple times. It no longer deletes the stored value. +- The following classes have been removed: + - `FileWriteTask` - The following methods have been removed: - `AsyncTask->peekLocal()`: use `fetchLocal()` instead - The following methods have signature changes: From 1d96c1810fac0abcf8ac2e326c7b525f9da2b990 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 3 Jul 2019 19:20:24 +0100 Subject: [PATCH 1041/3224] wtf PhpStorm --- src/pocketmine/block/Block.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 4062d12356..2c21657f21 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -49,7 +49,7 @@ use function assert; use function dechex; use const PHP_INT_MAX; -class Block extends Position implements BlockLegacyIds{ +class Block implements BlockLegacyIds{ /** * Returns a new Block instance with the specified ID, meta and position. @@ -419,13 +419,12 @@ class Block extends Position implements BlockLegacyIds{ } /** + * @internal + * * @param World $world * @param int $x * @param int $y * @param int $z - * - *@internal - * */ final public function position(World $world, int $x, int $y, int $z) : void{ $this->x = $x; From 062e6920699f3015a64490d5d98d15169fc365dc Mon Sep 17 00:00:00 2001 From: Dylan T Date: Wed, 3 Jul 2019 20:02:33 +0100 Subject: [PATCH 1042/3224] AAAAAAAAAAAAAAAAAAAA --- src/pocketmine/block/Block.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 2c21657f21..f095f70e28 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -49,7 +49,7 @@ use function assert; use function dechex; use const PHP_INT_MAX; -class Block implements BlockLegacyIds{ +class Block extends Position implements BlockLegacyIds{ /** * Returns a new Block instance with the specified ID, meta and position. From a125980ada8566f991aa2ea4f0bd02a4efba9cc7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Jul 2019 18:00:37 +0100 Subject: [PATCH 1043/3224] utils: Color is now immutable as is always the case with mutability, allowing this creates lots of complications that aren't worth the hassle. --- changelogs/4.0-snapshot.md | 4 ++++ src/pocketmine/utils/Color.php | 36 ---------------------------------- 2 files changed, 4 insertions(+), 36 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 8bd9fe7bc0..2e23e8c91f 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -641,6 +641,10 @@ This version features substantial changes to the network system, improving coher - The following API methods have signature changes: - `Internet::simpleCurl()` now requires a `Closure` for its `onSuccess` parameter instead of `callable`. - The following API methods have been removed: + - `Color->setA()` + - `Color->setR()` + - `Color->setG()` + - `Color->setB()` - `Color->toABGR()` - `Color->toBGRA()` - `Color::fromABGR()` diff --git a/src/pocketmine/utils/Color.php b/src/pocketmine/utils/Color.php index c860d05211..acb30b6fb1 100644 --- a/src/pocketmine/utils/Color.php +++ b/src/pocketmine/utils/Color.php @@ -53,15 +53,6 @@ class Color{ return $this->a; } - /** - * Sets the alpha (opacity) value of this colour, lower = more transparent - * - * @param int $a - */ - public function setA(int $a) : void{ - $this->a = $a & 0xff; - } - /** * Retuns the red value of this colour. * @return int @@ -70,15 +61,6 @@ class Color{ return $this->r; } - /** - * Sets the red value of this colour. - * - * @param int $r - */ - public function setR(int $r) : void{ - $this->r = $r & 0xff; - } - /** * Returns the green value of this colour. * @return int @@ -87,15 +69,6 @@ class Color{ return $this->g; } - /** - * Sets the green value of this colour. - * - * @param int $g - */ - public function setG(int $g) : void{ - $this->g = $g & 0xff; - } - /** * Returns the blue value of this colour. * @return int @@ -104,15 +77,6 @@ class Color{ return $this->b; } - /** - * Sets the blue value of this colour. - * - * @param int $b - */ - public function setB(int $b) : void{ - $this->b = $b & 0xff; - } - /** * Mixes the supplied list of colours together to produce a result colour. * From 9ed13bf112d54c645d6c3e2e9528da9cd670a4fe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Jul 2019 18:03:45 +0100 Subject: [PATCH 1044/3224] Color: make use of intdiv() --- src/pocketmine/utils/Color.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/utils/Color.php b/src/pocketmine/utils/Color.php index acb30b6fb1..dd5e279582 100644 --- a/src/pocketmine/utils/Color.php +++ b/src/pocketmine/utils/Color.php @@ -26,6 +26,7 @@ namespace pocketmine\utils; use function count; +use function intdiv; class Color{ @@ -99,7 +100,7 @@ class Color{ $b += $color->b; } - return new Color((int) ($r / $count), (int) ($g / $count), (int) ($b / $count), (int) ($a / $count)); + return new Color(intdiv($r, $count), intdiv($g, $count), intdiv($b, $count), intdiv($a, $count)); } /** From 3bdf740597dbe349dcde2fc5bed68e7d6193bb11 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Jul 2019 18:04:23 +0100 Subject: [PATCH 1045/3224] formatting --- src/pocketmine/utils/Color.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pocketmine/utils/Color.php b/src/pocketmine/utils/Color.php index dd5e279582..26846164ef 100644 --- a/src/pocketmine/utils/Color.php +++ b/src/pocketmine/utils/Color.php @@ -21,10 +21,8 @@ declare(strict_types=1); - namespace pocketmine\utils; - use function count; use function intdiv; From ceb6529ee39ec6de433bc7ecfdbeb98a3b707128 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Jul 2019 19:55:48 +0100 Subject: [PATCH 1046/3224] encapsulate light recalculation logic inside LightUpdate classes now we can do a standard light recalculation from anywhere. --- src/pocketmine/world/World.php | 36 +---------------- .../world/light/BlockLightUpdate.php | 8 ++++ src/pocketmine/world/light/LightUpdate.php | 20 ++++++++++ src/pocketmine/world/light/SkyLightUpdate.php | 39 +++++++++++++++++++ 4 files changed, 69 insertions(+), 34 deletions(-) diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index d622766399..c4bedd6736 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -1397,39 +1397,10 @@ class World implements ChunkManager{ public function updateBlockSkyLight(int $x, int $y, int $z){ $this->timings->doBlockSkyLightUpdates->startTiming(); - $oldHeightMap = $this->getHeightMap($x, $z); - $source = $this->getBlockAt($x, $y, $z); - - $yPlusOne = $y + 1; - - if($yPlusOne === $oldHeightMap){ //Block changed directly beneath the heightmap. Check if a block was removed or changed to a different light-filter. - $newHeightMap = $this->getChunk($x >> 4, $z >> 4)->recalculateHeightMapColumn($x & 0x0f, $z & 0x0f); - }elseif($yPlusOne > $oldHeightMap){ //Block changed above the heightmap. - if($source->getLightFilter() > 0 or $source->diffusesSkyLight()){ - $this->setHeightMap($x, $z, $yPlusOne); - $newHeightMap = $yPlusOne; - }else{ //Block changed which has no effect on direct sky light, for example placing or removing glass. - $this->timings->doBlockSkyLightUpdates->stopTiming(); - return; - } - }else{ //Block changed below heightmap - $newHeightMap = $oldHeightMap; - } - if($this->skyLightUpdate === null){ $this->skyLightUpdate = new SkyLightUpdate($this); } - if($newHeightMap > $oldHeightMap){ //Heightmap increase, block placed, remove sky light - for($i = $y; $i >= $oldHeightMap; --$i){ - $this->skyLightUpdate->setAndUpdateLight($x, $i, $z, 0); //Remove all light beneath, adjacent recalculation will handle the rest. - } - }elseif($newHeightMap < $oldHeightMap){ //Heightmap decrease, block changed or removed, add sky light - for($i = $y; $i >= $newHeightMap; --$i){ - $this->skyLightUpdate->setAndUpdateLight($x, $i, $z, 15); - } - }else{ //No heightmap change, block changed "underground" - $this->skyLightUpdate->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentBlockSkyLight($x, $y, $z) - BlockFactory::$lightFilter[($source->getId() << 4) | $source->getMeta()])); - } + $this->skyLightUpdate->recalculateNode($x, $y, $z); $this->timings->doBlockSkyLightUpdates->stopTiming(); } @@ -1457,13 +1428,10 @@ class World implements ChunkManager{ public function updateBlockLight(int $x, int $y, int $z){ $this->timings->doBlockLightUpdates->startTiming(); - $block = $this->getBlockAt($x, $y, $z); - $newLevel = max($block->getLightLevel(), $this->getHighestAdjacentBlockLight($x, $y, $z) - BlockFactory::$lightFilter[($block->getId() << 4) | $block->getMeta()]); - if($this->blockLightUpdate === null){ $this->blockLightUpdate = new BlockLightUpdate($this); } - $this->blockLightUpdate->setAndUpdateLight($x, $y, $z, $newLevel); + $this->blockLightUpdate->recalculateNode($x, $y, $z); $this->timings->doBlockLightUpdates->stopTiming(); } diff --git a/src/pocketmine/world/light/BlockLightUpdate.php b/src/pocketmine/world/light/BlockLightUpdate.php index bfc014fd40..1fbaf04c37 100644 --- a/src/pocketmine/world/light/BlockLightUpdate.php +++ b/src/pocketmine/world/light/BlockLightUpdate.php @@ -23,6 +23,9 @@ declare(strict_types=1); namespace pocketmine\world\light; +use pocketmine\block\BlockFactory; +use function max; + class BlockLightUpdate extends LightUpdate{ public function getLight(int $x, int $y, int $z) : int{ @@ -32,4 +35,9 @@ class BlockLightUpdate extends LightUpdate{ public function setLight(int $x, int $y, int $z, int $level) : void{ $this->subChunkHandler->currentSubChunk->setBlockLight($x & 0x0f, $y & 0x0f, $z & 0x0f, $level); } + + public function recalculateNode(int $x, int $y, int $z) : void{ + $block = $this->world->getBlockAt($x, $y, $z); + $this->setAndUpdateLight($x, $y, $z, max($block->getLightLevel(), $this->getHighestAdjacentLight($x, $y, $z) - BlockFactory::$lightFilter[$block->getFullId()])); + } } diff --git a/src/pocketmine/world/light/LightUpdate.php b/src/pocketmine/world/light/LightUpdate.php index cf36908ac6..cc3bee6afd 100644 --- a/src/pocketmine/world/light/LightUpdate.php +++ b/src/pocketmine/world/light/LightUpdate.php @@ -27,6 +27,7 @@ use pocketmine\block\BlockFactory; use pocketmine\world\ChunkManager; use pocketmine\world\utils\SubChunkIteratorManager; use pocketmine\world\World; +use function max; //TODO: make light updates asynchronous abstract class LightUpdate{ @@ -61,6 +62,25 @@ abstract class LightUpdate{ abstract protected function setLight(int $x, int $y, int $z, int $level) : void; + abstract public function recalculateNode(int $x, int $y, int $z) : void; + + protected function getHighestAdjacentLight(int $x, int $y, int $z) : int{ + $adjacent = 0; + foreach([ + [$x + 1, $y, $z], + [$x - 1, $y, $z], + [$x, $y + 1, $z], + [$x, $y - 1, $z], + [$x, $y, $z + 1], + [$x, $y, $z - 1] + ] as [$x1, $y1, $z1]){ + if($this->subChunkHandler->moveTo($x1, $y1, $z1, false) and ($adjacent = max($adjacent, $this->getLight($x1, $y1, $z1))) === 15){ + break; + } + } + return $adjacent; + } + public function setAndUpdateLight(int $x, int $y, int $z, int $newLevel) : void{ $this->updateNodes[World::blockHash($x, $y, $z)] = [$x, $y, $z, $newLevel]; } diff --git a/src/pocketmine/world/light/SkyLightUpdate.php b/src/pocketmine/world/light/SkyLightUpdate.php index 2241604192..8374c862d8 100644 --- a/src/pocketmine/world/light/SkyLightUpdate.php +++ b/src/pocketmine/world/light/SkyLightUpdate.php @@ -23,6 +23,9 @@ declare(strict_types=1); namespace pocketmine\world\light; +use pocketmine\block\BlockFactory; +use function max; + class SkyLightUpdate extends LightUpdate{ public function getLight(int $x, int $y, int $z) : int{ @@ -32,4 +35,40 @@ class SkyLightUpdate extends LightUpdate{ public function setLight(int $x, int $y, int $z, int $level) : void{ $this->subChunkHandler->currentSubChunk->setBlockSkyLight($x & 0x0f, $y & 0x0f, $z & 0x0f, $level); } + + public function recalculateNode(int $x, int $y, int $z) : void{ + $chunk = $this->world->getChunk($x >> 4, $z >> 4); + if($chunk === null){ + return; + } + $oldHeightMap = $chunk->getHeightMap($x & 0xf, $z & 0xf); + $source = $this->world->getBlockAt($x, $y, $z); + + $yPlusOne = $y + 1; + + if($yPlusOne === $oldHeightMap){ //Block changed directly beneath the heightmap. Check if a block was removed or changed to a different light-filter. + $newHeightMap = $chunk->recalculateHeightMapColumn($x & 0x0f, $z & 0x0f); + }elseif($yPlusOne > $oldHeightMap){ //Block changed above the heightmap. + if($source->getLightFilter() > 0 or $source->diffusesSkyLight()){ + $chunk->setHeightMap($x & 0xf, $z & 0xf, $yPlusOne); + $newHeightMap = $yPlusOne; + }else{ //Block changed which has no effect on direct sky light, for example placing or removing glass. + return; + } + }else{ //Block changed below heightmap + $newHeightMap = $oldHeightMap; + } + + if($newHeightMap > $oldHeightMap){ //Heightmap increase, block placed, remove sky light + for($i = $y; $i >= $oldHeightMap; --$i){ + $this->setAndUpdateLight($x, $i, $z, 0); //Remove all light beneath, adjacent recalculation will handle the rest. + } + }elseif($newHeightMap < $oldHeightMap){ //Heightmap decrease, block changed or removed, add sky light + for($i = $y; $i >= $newHeightMap; --$i){ + $this->setAndUpdateLight($x, $i, $z, 15); + } + }else{ //No heightmap change, block changed "underground" + $this->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentLight($x, $y, $z) - BlockFactory::$lightFilter[$source->getFullId()])); + } + } } From 453c5a329dc827123264d92f39b88c4fb5f25564 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 5 Jul 2019 13:41:18 +0100 Subject: [PATCH 1047/3224] Tile: remove useless code --- src/pocketmine/block/tile/Tile.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/pocketmine/block/tile/Tile.php b/src/pocketmine/block/tile/Tile.php index 1ff97a6562..3530cabc5b 100644 --- a/src/pocketmine/block/tile/Tile.php +++ b/src/pocketmine/block/tile/Tile.php @@ -44,8 +44,6 @@ abstract class Tile extends Position{ public const TAG_Y = "y"; public const TAG_Z = "z"; - /** @var string */ - public $name = ""; /** @var bool */ public $closed = false; /** @var TimingsHandler */ @@ -140,8 +138,4 @@ abstract class Tile extends Position{ } } } - - public function getName() : string{ - return $this->name; - } } From b021cc21388effcc039bdb7335bd3564d2b48161 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 5 Jul 2019 13:46:06 +0100 Subject: [PATCH 1048/3224] ItemFactory: add PhpDoc for getAllRegistered() --- src/pocketmine/item/ItemFactory.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index a6d5ae2bd6..b6b076f277 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -486,6 +486,9 @@ class ItemFactory{ return (($id & 0xffff) << 16) | ($variant & 0xffff); } + /** + * @return Item[] + */ public static function getAllRegistered() : array{ return self::$list; } From 2bd2e1125c2a36b94ae3bd0cd3be8eb322facbf3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 5 Jul 2019 14:22:20 +0100 Subject: [PATCH 1049/3224] Block: don't be stupid in getSide() --- src/pocketmine/block/Block.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index f095f70e28..5f5df3e8d3 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -595,7 +595,7 @@ class Block extends Position implements BlockLegacyIds{ return $this->getWorld()->getBlock(Vector3::getSide($side, $step)); } - return BlockFactory::get(BlockLegacyIds::AIR, 0, Position::fromObject(Vector3::getSide($side, $step))); + throw new \InvalidStateException("Block does not have a valid world"); } /** From fe850a184c7ce1c0679f352aa40f8458ee78dd0b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 5 Jul 2019 15:14:03 +0100 Subject: [PATCH 1050/3224] deal with fern mapping properly --- src/pocketmine/block/BlockFactory.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 079b7da713..456977150c 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -372,10 +372,12 @@ class BlockFactory{ self::register(new Solid(new BID(Ids::STONECUTTER), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN))); self::register(new Sugarcane(new BID(Ids::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane")); self::register(new TNT(new BID(Ids::TNT), "TNT")); - self::register(new TallGrass(new BID(Ids::TALLGRASS), "Fern")); //TODO: remap this to normal fern + + $fern = new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_FERN), "Fern"); + self::register($fern); + self::remap(Ids::TALLGRASS, 0, $fern); + self::remap(Ids::TALLGRASS, 3, $fern); self::register(new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_NORMAL), "Tall Grass")); - self::register(new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_FERN), "Fern")); - self::register(new TallGrass(new BID(Ids::TALLGRASS, 3), "Fern")); //TODO: remap this to normal fern self::register(new Torch(new BID(Ids::COLORED_TORCH_BP), "Blue Torch")); self::register(new Torch(new BID(Ids::COLORED_TORCH_BP, 8), "Purple Torch")); self::register(new Torch(new BID(Ids::COLORED_TORCH_RG), "Red Torch")); From f356bf0893959808ec65c39fd66f562bd7da4790 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 5 Jul 2019 16:15:58 +0100 Subject: [PATCH 1051/3224] Extracted an EffectManager unit from Living --- changelogs/4.0-snapshot.md | 11 + .../command/defaults/EffectCommand.php | 13 +- src/pocketmine/entity/Human.php | 8 +- src/pocketmine/entity/Living.php | 197 +++-------------- .../entity/effect/EffectManager.php | 203 ++++++++++++++++++ .../entity/projectile/SplashPotion.php | 2 +- .../entity/EntityDamageByEntityEvent.php | 9 +- src/pocketmine/item/MilkBucket.php | 2 +- .../mcpe/handler/PreSpawnPacketHandler.php | 2 +- src/pocketmine/player/Player.php | 8 +- 10 files changed, 260 insertions(+), 195 deletions(-) create mode 100644 src/pocketmine/entity/effect/EffectManager.php diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 2e23e8c91f..8dec8eac60 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -154,6 +154,17 @@ This version features substantial changes to the network system, improving coher - `Entity->entityBaseTick()` is now `protected`. - `Entity->move()` is now `protected`. - `Living->knockBack()` now accepts `float, float, float` (the first two parameters have been removed). + - `Living->getEffects()` now returns `EffectManager` instead of `Effect[]`. +- The following classes have been added: + - `effect\EffectManager`: contains effect-management functionality extracted from `Living` +- The following API methods have been moved / renamed: + - `Living->removeAllEffects()` -> `EffectManager->clear()` + - `Living->removeEffect()` -> `EffectManager->remove()` + - `Living->addEffect()` -> `EffectManager->add()` + - `Living->getEffect()` -> `EffectManager->get()` + - `Living->hasEffect()` -> `EffectManager->has()` + - `Living->hasEffects()` -> `EffectManager->hasEffects()` + - `Living->getEffects()` -> `EffectManager->all()` - The following classes have been removed: - `Creature` - `Damageable` diff --git a/src/pocketmine/command/defaults/EffectCommand.php b/src/pocketmine/command/defaults/EffectCommand.php index 373434c664..4eea21c743 100644 --- a/src/pocketmine/command/defaults/EffectCommand.php +++ b/src/pocketmine/command/defaults/EffectCommand.php @@ -59,11 +59,10 @@ class EffectCommand extends VanillaCommand{ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); return true; } + $effectManager = $player->getEffects(); if(strtolower($args[1]) === "clear"){ - foreach($player->getEffects() as $effect){ - $player->removeEffect($effect->getType()); - } + $effectManager->clear(); $sender->sendMessage(new TranslationContainer("commands.effect.success.removed.all", [$player->getDisplayName()])); return true; @@ -107,8 +106,8 @@ class EffectCommand extends VanillaCommand{ } if($duration === 0){ - if(!$player->hasEffect($effect)){ - if(count($player->getEffects()) === 0){ + if(!$effectManager->has($effect)){ + if(count($effectManager->all()) === 0){ $sender->sendMessage(new TranslationContainer("commands.effect.failure.notActive.all", [$player->getDisplayName()])); }else{ $sender->sendMessage(new TranslationContainer("commands.effect.failure.notActive", [$effect->getName(), $player->getDisplayName()])); @@ -116,11 +115,11 @@ class EffectCommand extends VanillaCommand{ return true; } - $player->removeEffect($effect); + $effectManager->remove($effect); $sender->sendMessage(new TranslationContainer("commands.effect.success.removed", [$effect->getName(), $player->getDisplayName()])); }else{ $instance = new EffectInstance($effect, $duration, $amplification, $visible); - $player->addEffect($instance); + $effectManager->add($instance); self::broadcastCommandMessage($sender, new TranslationContainer("%commands.effect.success", [$effect->getName(), $instance->getAmplifier(), $player->getDisplayName(), $instance->getDuration() / 20, $effect->getId()])); } diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 128b4ccda1..6364e72c85 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -732,11 +732,11 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ parent::applyPostDamageEffects($source); $totemModifier = $source->getModifier(EntityDamageEvent::MODIFIER_TOTEM); if($totemModifier < 0){ //Totem prevented death - $this->removeAllEffects(); + $this->effectManager->clear(); - $this->addEffect(new EffectInstance(Effect::REGENERATION(), 40 * 20, 1)); - $this->addEffect(new EffectInstance(Effect::FIRE_RESISTANCE(), 40 * 20, 1)); - $this->addEffect(new EffectInstance(Effect::ABSORPTION(), 5 * 20, 1)); + $this->effectManager->add(new EffectInstance(Effect::REGENERATION(), 40 * 20, 1)); + $this->effectManager->add(new EffectInstance(Effect::FIRE_RESISTANCE(), 40 * 20, 1)); + $this->effectManager->add(new EffectInstance(Effect::ABSORPTION(), 5 * 20, 1)); $this->broadcastEntityEvent(EntityEventPacket::CONSUME_TOTEM); $this->world->addSound($this->add(0, $this->eyeHeight, 0), new TotemUseSound()); diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index c0fd5338bc..c17a9c206d 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -26,6 +26,7 @@ namespace pocketmine\entity; use pocketmine\block\Block; use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; +use pocketmine\entity\effect\EffectManager; use pocketmine\event\entity\EntityDamageByChildEntityEvent; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; @@ -81,8 +82,8 @@ abstract class Living extends Entity{ protected $jumpVelocity = 0.42; - /** @var EffectInstance[] */ - protected $effects = []; + /** @var EffectManager */ + protected $effectManager; /** @var ArmorInventory */ protected $armorInventory; @@ -92,6 +93,8 @@ abstract class Living extends Entity{ protected function initEntity(CompoundTag $nbt) : void{ parent::initEntity($nbt); + $this->effectManager = new EffectManager($this); + $this->armorInventory = new ArmorInventory($this); //TODO: load/save armor inventory contents $this->armorInventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange( @@ -122,7 +125,7 @@ abstract class Living extends Entity{ continue; } - $this->addEffect(new EffectInstance( + $this->effectManager->add(new EffectInstance( $effect, $e->getInt("Duration"), Binary::unsignByte($e->getByte("Amplifier")), @@ -171,9 +174,9 @@ abstract class Living extends Entity{ $nbt = parent::saveNBT(); $nbt->setFloat("Health", $this->getHealth()); - if(count($this->effects) > 0){ + if(!empty($this->effectManager->all())){ $effects = []; - foreach($this->effects as $effect){ + foreach($this->effectManager->all() as $effect){ $effects[] = CompoundTag::create() ->setByte("Id", $effect->getId()) ->setByte("Amplifier", Binary::signByte($effect->getAmplifier())) @@ -195,162 +198,25 @@ abstract class Living extends Entity{ //return $this->getLevel()->rayTraceBlocks(Vector3::createVector($this->x, $this->y + $this->height, $this->z), Vector3::createVector($entity->x, $entity->y + $entity->height, $entity->z)) === null; } - /** - * Returns an array of Effects currently active on the mob. - * @return EffectInstance[] - */ - public function getEffects() : array{ - return $this->effects; + public function getEffects() : EffectManager{ + return $this->effectManager; } /** - * Removes all effects from the mob. - */ - public function removeAllEffects() : void{ - foreach($this->effects as $effect){ - $this->removeEffect($effect->getType()); - } - } - - /** - * Removes the effect with the specified ID from the mob. - * - * @param Effect $effectType - */ - public function removeEffect(Effect $effectType) : void{ - $index = $effectType->getId(); - if(isset($this->effects[$index])){ - $effect = $this->effects[$index]; - $hasExpired = $effect->hasExpired(); - $ev = new EntityEffectRemoveEvent($this, $effect); - $ev->call(); - if($ev->isCancelled()){ - if($hasExpired and !$ev->getEffect()->hasExpired()){ //altered duration of an expired effect to make it not get removed - $this->onEffectAdded($ev->getEffect(), true); - } - return; - } - - unset($this->effects[$index]); - $effect->getType()->remove($this, $effect); - $this->onEffectRemoved($effect); - - $this->recalculateEffectColor(); - } - } - - /** - * Returns the effect instance active on this entity with the specified ID, or null if the mob does not have the - * effect. - * - * @param Effect $effect - * - * @return EffectInstance|null - */ - public function getEffect(Effect $effect) : ?EffectInstance{ - return $this->effects[$effect->getId()] ?? null; - } - - /** - * Returns whether the specified effect is active on the mob. - * - * @param Effect $effect - * - * @return bool - */ - public function hasEffect(Effect $effect) : bool{ - return isset($this->effects[$effect->getId()]); - } - - /** - * Returns whether the mob has any active effects. - * @return bool - */ - public function hasEffects() : bool{ - return !empty($this->effects); - } - - /** - * Adds an effect to the mob. - * If a weaker effect of the same type is already applied, it will be replaced. - * If a weaker or equal-strength effect is already applied but has a shorter duration, it will be replaced. + * @internal * * @param EffectInstance $effect - * - * @return bool whether the effect has been successfully applied. + * @param bool $replacesOldEffect */ - public function addEffect(EffectInstance $effect) : bool{ - $oldEffect = null; - $cancelled = false; + public function onEffectAdded(EffectInstance $effect, bool $replacesOldEffect) : void{ - $index = $effect->getType()->getId(); - if(isset($this->effects[$index])){ - $oldEffect = $this->effects[$index]; - if( - abs($effect->getAmplifier()) < $oldEffect->getAmplifier() - or (abs($effect->getAmplifier()) === abs($oldEffect->getAmplifier()) and $effect->getDuration() < $oldEffect->getDuration()) - ){ - $cancelled = true; - } - } - - $ev = new EntityEffectAddEvent($this, $effect, $oldEffect); - $ev->setCancelled($cancelled); - - $ev->call(); - if($ev->isCancelled()){ - return false; - } - - if($oldEffect !== null){ - $oldEffect->getType()->remove($this, $oldEffect); - } - - $effect->getType()->add($this, $effect); - $this->onEffectAdded($effect, $oldEffect !== null); - - $this->effects[$index] = $effect; - - $this->recalculateEffectColor(); - - return true; } /** - * Recalculates the mob's potion bubbles colour based on the active effects. + * @internal + * @param EffectInstance $effect */ - protected function recalculateEffectColor() : void{ - /** @var Color[] $colors */ - $colors = []; - $ambient = true; - foreach($this->effects as $effect){ - if($effect->isVisible() and $effect->getType()->hasBubbles()){ - $level = $effect->getEffectLevel(); - $color = $effect->getColor(); - for($i = 0; $i < $level; ++$i){ - $colors[] = $color; - } - - if(!$effect->isAmbient()){ - $ambient = false; - } - } - } - - if(!empty($colors)){ - $this->propertyManager->setInt(EntityMetadataProperties::POTION_COLOR, Color::mix(...$colors)->toARGB()); - $this->propertyManager->setByte(EntityMetadataProperties::POTION_AMBIENT, $ambient ? 1 : 0); - }else{ - $this->propertyManager->setInt(EntityMetadataProperties::POTION_COLOR, 0); - $this->propertyManager->setByte(EntityMetadataProperties::POTION_AMBIENT, 0); - } - } - - protected function onEffectAdded(EffectInstance $effect, bool $replacesOldEffect) : void{ - - } - - protected function onEffectRemoved(EffectInstance $effect) : void{ + public function onEffectRemoved(EffectInstance $effect) : void{ } @@ -364,7 +230,7 @@ abstract class Living extends Entity{ */ public function consumeObject(Consumable $consumable) : bool{ foreach($consumable->getAdditionalEffects() as $effect){ - $this->addEffect($effect); + $this->effectManager->add($effect); } $consumable->onConsume($this); @@ -377,7 +243,7 @@ abstract class Living extends Entity{ * @return float */ public function getJumpVelocity() : float{ - return $this->jumpVelocity + ($this->hasEffect(Effect::JUMP_BOOST()) ? ($this->getEffect(Effect::JUMP_BOOST())->getEffectLevel() / 10) : 0); + return $this->jumpVelocity + ($this->effectManager->has(Effect::JUMP_BOOST()) ? ($this->effectManager->get(Effect::JUMP_BOOST())->getEffectLevel() / 10) : 0); } /** @@ -390,7 +256,7 @@ abstract class Living extends Entity{ } public function fall(float $fallDistance) : void{ - $damage = ceil($fallDistance - 3 - ($this->hasEffect(Effect::JUMP_BOOST()) ? $this->getEffect(Effect::JUMP_BOOST())->getEffectLevel() : 0)); + $damage = ceil($fallDistance - 3 - ($this->effectManager->has(Effect::JUMP_BOOST()) ? $this->effectManager->get(Effect::JUMP_BOOST())->getEffectLevel() : 0)); if($damage > 0){ $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FALL, $damage); $this->attack($ev); @@ -453,8 +319,8 @@ abstract class Living extends Entity{ } $cause = $source->getCause(); - if($this->hasEffect(Effect::RESISTANCE()) and $cause !== EntityDamageEvent::CAUSE_VOID and $cause !== EntityDamageEvent::CAUSE_SUICIDE){ - $source->setModifier(-$source->getFinalDamage() * min(1, 0.2 * $this->getEffect(Effect::RESISTANCE())->getEffectLevel()), EntityDamageEvent::MODIFIER_RESISTANCE); + if($this->effectManager->has(Effect::RESISTANCE()) and $cause !== EntityDamageEvent::CAUSE_VOID and $cause !== EntityDamageEvent::CAUSE_SUICIDE){ + $source->setModifier(-$source->getFinalDamage() * min(1, 0.2 * $this->effectManager->get(Effect::RESISTANCE())->getEffectLevel()), EntityDamageEvent::MODIFIER_RESISTANCE); } $totalEpf = 0; @@ -534,7 +400,7 @@ abstract class Living extends Entity{ } } - if($this->hasEffect(Effect::FIRE_RESISTANCE()) and ( + if($this->effectManager->has(Effect::FIRE_RESISTANCE()) and ( $source->getCause() === EntityDamageEvent::CAUSE_FIRE or $source->getCause() === EntityDamageEvent::CAUSE_FIRE_TICK or $source->getCause() === EntityDamageEvent::CAUSE_LAVA @@ -656,7 +522,7 @@ abstract class Living extends Entity{ $hasUpdate = parent::entityBaseTick($tickDiff); if($this->isAlive()){ - if($this->doEffectsTick($tickDiff)){ + if($this->effectManager->tick($tickDiff)){ $hasUpdate = true; } @@ -680,21 +546,6 @@ abstract class Living extends Entity{ return $hasUpdate; } - protected function doEffectsTick(int $tickDiff = 1) : bool{ - foreach($this->effects as $instance){ - $type = $instance->getType(); - if($type->canTick($instance)){ - $type->applyEffect($this, $instance); - } - $instance->decreaseDuration($tickDiff); - if($instance->hasExpired()){ - $this->removeEffect($instance->getType()); - } - } - - return !empty($this->effects); - } - /** * Ticks the entity's air supply, consuming it when underwater and regenerating it when out of water. * @@ -739,7 +590,7 @@ abstract class Living extends Entity{ * @return bool */ public function canBreathe() : bool{ - return $this->hasEffect(Effect::WATER_BREATHING()) or $this->hasEffect(Effect::CONDUIT_POWER()) or !$this->isUnderwater(); + return $this->effectManager->has(Effect::WATER_BREATHING()) or $this->effectManager->has(Effect::CONDUIT_POWER()) or !$this->isUnderwater(); } /** diff --git a/src/pocketmine/entity/effect/EffectManager.php b/src/pocketmine/entity/effect/EffectManager.php new file mode 100644 index 0000000000..906c0d2d09 --- /dev/null +++ b/src/pocketmine/entity/effect/EffectManager.php @@ -0,0 +1,203 @@ +entity = $entity; + } + + /** + * Returns an array of Effects currently active on the mob. + * @return EffectInstance[] + */ + public function all() : array{ + return $this->effects; + } + + /** + * Removes all effects from the mob. + */ + public function clear() : void{ + foreach($this->effects as $effect){ + $this->remove($effect->getType()); + } + } + + /** + * Removes the effect with the specified ID from the mob. + * + * @param Effect $effectType + */ + public function remove(Effect $effectType) : void{ + $index = $effectType->getId(); + if(isset($this->effects[$index])){ + $effect = $this->effects[$index]; + $hasExpired = $effect->hasExpired(); + $ev = new EntityEffectRemoveEvent($this->entity, $effect); + $ev->call(); + if($ev->isCancelled()){ + if($hasExpired and !$ev->getEffect()->hasExpired()){ //altered duration of an expired effect to make it not get removed + $this->entity->onEffectAdded($ev->getEffect(), true); + } + return; + } + + unset($this->effects[$index]); + $effect->getType()->remove($this->entity, $effect); + $this->entity->onEffectRemoved($effect); + + $this->recalculateEffectColor(); + } + } + + /** + * Returns the effect instance active on this entity with the specified ID, or null if the mob does not have the + * effect. + * + * @param Effect $effect + * + * @return EffectInstance|null + */ + public function get(Effect $effect) : ?EffectInstance{ + return $this->effects[$effect->getId()] ?? null; + } + + /** + * Returns whether the specified effect is active on the mob. + * + * @param Effect $effect + * + * @return bool + */ + public function has(Effect $effect) : bool{ + return isset($this->effects[$effect->getId()]); + } + + /** + * Adds an effect to the mob. + * If a weaker effect of the same type is already applied, it will be replaced. + * If a weaker or equal-strength effect is already applied but has a shorter duration, it will be replaced. + * + * @param EffectInstance $effect + * + * @return bool whether the effect has been successfully applied. + */ + public function add(EffectInstance $effect) : bool{ + $oldEffect = null; + $cancelled = false; + + $index = $effect->getType()->getId(); + if(isset($this->effects[$index])){ + $oldEffect = $this->effects[$index]; + if( + abs($effect->getAmplifier()) < $oldEffect->getAmplifier() + or (abs($effect->getAmplifier()) === abs($oldEffect->getAmplifier()) and $effect->getDuration() < $oldEffect->getDuration()) + ){ + $cancelled = true; + } + } + + $ev = new EntityEffectAddEvent($this->entity, $effect, $oldEffect); + $ev->setCancelled($cancelled); + + $ev->call(); + if($ev->isCancelled()){ + return false; + } + + if($oldEffect !== null){ + $oldEffect->getType()->remove($this->entity, $oldEffect); + } + + $effect->getType()->add($this->entity, $effect); + $this->entity->onEffectAdded($effect, $oldEffect !== null); + + $this->effects[$index] = $effect; + + $this->recalculateEffectColor(); + + return true; + } + + /** + * Recalculates the mob's potion bubbles colour based on the active effects. + */ + protected function recalculateEffectColor() : void{ + /** @var Color[] $colors */ + $colors = []; + $ambient = true; + foreach($this->effects as $effect){ + if($effect->isVisible() and $effect->getType()->hasBubbles()){ + $level = $effect->getEffectLevel(); + $color = $effect->getColor(); + for($i = 0; $i < $level; ++$i){ + $colors[] = $color; + } + + if(!$effect->isAmbient()){ + $ambient = false; + } + } + } + + $propManager = $this->entity->getDataPropertyManager(); + if(!empty($colors)){ + $propManager->setInt(EntityMetadataProperties::POTION_COLOR, Color::mix(...$colors)->toARGB()); + $propManager->setByte(EntityMetadataProperties::POTION_AMBIENT, $ambient ? 1 : 0); + }else{ + $propManager->setInt(EntityMetadataProperties::POTION_COLOR, 0); + $propManager->setByte(EntityMetadataProperties::POTION_AMBIENT, 0); + } + } + + public function tick(int $tickDiff = 1) : bool{ + foreach($this->effects as $instance){ + $type = $instance->getType(); + if($type->canTick($instance)){ + $type->applyEffect($this->entity, $instance); + } + $instance->decreaseDuration($tickDiff); + if($instance->hasExpired()){ + $this->remove($instance->getType()); + } + } + + return !empty($this->effects); + } +} diff --git a/src/pocketmine/entity/projectile/SplashPotion.php b/src/pocketmine/entity/projectile/SplashPotion.php index 40c8ef0baf..1b408978ce 100644 --- a/src/pocketmine/entity/projectile/SplashPotion.php +++ b/src/pocketmine/entity/projectile/SplashPotion.php @@ -109,7 +109,7 @@ class SplashPotion extends Throwable{ continue; } $effect->setDuration($newDuration); - $entity->addEffect($effect); + $entity->getEffects()->add($effect); }else{ $effect->getType()->applyEffect($entity, $effect, $distanceMultiplier, $this); } diff --git a/src/pocketmine/event/entity/EntityDamageByEntityEvent.php b/src/pocketmine/event/entity/EntityDamageByEntityEvent.php index ab0fdf8d70..2793f4673a 100644 --- a/src/pocketmine/event/entity/EntityDamageByEntityEvent.php +++ b/src/pocketmine/event/entity/EntityDamageByEntityEvent.php @@ -53,12 +53,13 @@ class EntityDamageByEntityEvent extends EntityDamageEvent{ protected function addAttackerModifiers(Entity $damager) : void{ if($damager instanceof Living){ //TODO: move this to entity classes - if($damager->hasEffect(Effect::STRENGTH())){ - $this->setModifier($this->getBaseDamage() * 0.3 * $damager->getEffect(Effect::STRENGTH())->getEffectLevel(), self::MODIFIER_STRENGTH); + $effects = $damager->getEffects(); + if($effects->has(Effect::STRENGTH())){ + $this->setModifier($this->getBaseDamage() * 0.3 * $effects->get(Effect::STRENGTH())->getEffectLevel(), self::MODIFIER_STRENGTH); } - if($damager->hasEffect(Effect::WEAKNESS())){ - $this->setModifier(-($this->getBaseDamage() * 0.2 * $damager->getEffect(Effect::WEAKNESS())->getEffectLevel()), self::MODIFIER_WEAKNESS); + if($effects->has(Effect::WEAKNESS())){ + $this->setModifier(-($this->getBaseDamage() * 0.2 * $effects->get(Effect::WEAKNESS())->getEffectLevel()), self::MODIFIER_WEAKNESS); } } } diff --git a/src/pocketmine/item/MilkBucket.php b/src/pocketmine/item/MilkBucket.php index d0851d2e9e..592308f634 100644 --- a/src/pocketmine/item/MilkBucket.php +++ b/src/pocketmine/item/MilkBucket.php @@ -40,6 +40,6 @@ class MilkBucket extends Item implements Consumable{ } public function onConsume(Living $consumer) : void{ - $consumer->removeAllEffects(); + $consumer->getEffects()->clear(); } } diff --git a/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php b/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php index 9aa3ac0a5e..066a37b36f 100644 --- a/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php @@ -86,7 +86,7 @@ class PreSpawnPacketHandler extends PacketHandler{ $this->session->syncAttributes($this->player, true); $this->session->syncAvailableCommands(); $this->session->syncAdventureSettings($this->player); - foreach($this->player->getEffects() as $effect){ + foreach($this->player->getEffects()->all() as $effect){ $this->session->onEntityEffectAdded($this->player, $effect, false); } $this->player->sendData($this->player); diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index c4515c11cb..570254d168 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -1543,11 +1543,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->isCreative() or parent::canBreathe(); } - protected function onEffectAdded(EffectInstance $effect, bool $replacesOldEffect) : void{ + public function onEffectAdded(EffectInstance $effect, bool $replacesOldEffect) : void{ $this->networkSession->onEntityEffectAdded($this, $effect, $replacesOldEffect); } - protected function onEffectRemoved(EffectInstance $effect) : void{ + public function onEffectRemoved(EffectInstance $effect) : void{ $this->networkSession->onEntityEffectRemoved($this, $effect); } @@ -1911,7 +1911,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $ev->setModifier($meleeEnchantmentDamage, EntityDamageEvent::MODIFIER_WEAPON_ENCHANTMENTS); - if(!$this->isSprinting() and !$this->isFlying() and $this->fallDistance > 0 and !$this->hasEffect(Effect::BLINDNESS()) and !$this->isUnderwater()){ + if(!$this->isSprinting() and !$this->isFlying() and $this->fallDistance > 0 and !$this->effectManager->has(Effect::BLINDNESS()) and !$this->isUnderwater()){ $ev->setModifier($ev->getFinalDamage() / 2, EntityDamageEvent::MODIFIER_CRITICAL); } @@ -2426,7 +2426,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->deadTicks = 0; $this->noDamageTicks = 60; - $this->removeAllEffects(); + $this->effectManager->clear(); $this->setHealth($this->getMaxHealth()); foreach($this->attributeMap->getAll() as $attr){ From 77919b70b2c6fb56f56912324a35d29f8c91c7d8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 5 Jul 2019 16:20:56 +0100 Subject: [PATCH 1052/3224] Stop cloning Color objects since these are now immutable, there's no need to clone them. --- src/pocketmine/entity/effect/Effect.php | 6 +----- src/pocketmine/entity/effect/EffectInstance.php | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/entity/effect/Effect.php b/src/pocketmine/entity/effect/Effect.php index 28832b1758..5774c338a7 100644 --- a/src/pocketmine/entity/effect/Effect.php +++ b/src/pocketmine/entity/effect/Effect.php @@ -279,7 +279,7 @@ class Effect{ * @return Color */ public function getColor() : Color{ - return clone $this->color; + return $this->color; } /** @@ -350,8 +350,4 @@ class Effect{ public function remove(Living $entity, EffectInstance $instance) : void{ } - - public function __clone(){ - $this->color = clone $this->color; - } } diff --git a/src/pocketmine/entity/effect/EffectInstance.php b/src/pocketmine/entity/effect/EffectInstance.php index 2619a73d12..4da94f6024 100644 --- a/src/pocketmine/entity/effect/EffectInstance.php +++ b/src/pocketmine/entity/effect/EffectInstance.php @@ -198,7 +198,7 @@ class EffectInstance{ * @return Color */ public function getColor() : Color{ - return clone $this->color; + return $this->color; } /** @@ -209,7 +209,7 @@ class EffectInstance{ * @return EffectInstance */ public function setColor(Color $color) : EffectInstance{ - $this->color = clone $color; + $this->color = $color; return $this; } From 2e01bd1029410c6c9f8ecef87e27fc838171a6ac Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 5 Jul 2019 16:34:22 +0100 Subject: [PATCH 1053/3224] cleanup imports from f356bf0893959808ec65c39fd66f562bd7da4790 --- src/pocketmine/entity/Living.php | 4 ---- src/pocketmine/entity/effect/EffectManager.php | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index c17a9c206d..ffaf7db2f9 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -31,8 +31,6 @@ use pocketmine\event\entity\EntityDamageByChildEntityEvent; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDeathEvent; -use pocketmine\event\entity\EntityEffectAddEvent; -use pocketmine\event\entity\EntityEffectRemoveEvent; use pocketmine\inventory\ArmorInventory; use pocketmine\inventory\CallbackInventoryChangeListener; use pocketmine\inventory\Inventory; @@ -52,9 +50,7 @@ use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; use pocketmine\player\Player; use pocketmine\timings\Timings; use pocketmine\utils\Binary; -use pocketmine\utils\Color; use pocketmine\world\sound\ItemBreakSound; -use function abs; use function array_shift; use function atan2; use function ceil; diff --git a/src/pocketmine/entity/effect/EffectManager.php b/src/pocketmine/entity/effect/EffectManager.php index 906c0d2d09..3885b2cef9 100644 --- a/src/pocketmine/entity/effect/EffectManager.php +++ b/src/pocketmine/entity/effect/EffectManager.php @@ -23,12 +23,12 @@ declare(strict_types=1); namespace pocketmine\entity\effect; -use function abs; use pocketmine\entity\Living; use pocketmine\event\entity\EntityEffectAddEvent; use pocketmine\event\entity\EntityEffectRemoveEvent; use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; use pocketmine\utils\Color; +use function abs; class EffectManager{ From 45b0cbc79689d08ac4a0fa9552a0594bf50fabda Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 5 Jul 2019 17:17:48 +0100 Subject: [PATCH 1054/3224] Human: remove getRawUniqueId() premature optimization this is never used in a hot path and presents a potential for inconsistency. --- changelogs/4.0-snapshot.md | 2 ++ src/pocketmine/Server.php | 9 +++++---- src/pocketmine/entity/Human.php | 8 -------- src/pocketmine/player/Player.php | 7 +++---- 4 files changed, 10 insertions(+), 16 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 8dec8eac60..4b13743949 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -165,6 +165,8 @@ This version features substantial changes to the network system, improving coher - `Living->hasEffect()` -> `EffectManager->has()` - `Living->hasEffects()` -> `EffectManager->hasEffects()` - `Living->getEffects()` -> `EffectManager->all()` +- The following API methods have been removed: + - `Human->getRawUniqueId()`: use `Human->getUniqueId()->toBinary()` instead - The following classes have been removed: - `Creature` - `Damageable` diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 5e9e96d9d1..ee18ea34b7 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1781,16 +1781,17 @@ class Server{ foreach($this->playerList as $p){ $p->getNetworkSession()->onPlayerAdded($player); } - $this->playerList[$player->getRawUniqueId()] = $player; + $rawUUID = $player->getUniqueId()->toBinary(); + $this->playerList[$rawUUID] = $player; if($this->sendUsageTicker > 0){ - $this->uniquePlayers[$player->getRawUniqueId()] = $player->getRawUniqueId(); + $this->uniquePlayers[$rawUUID] = $rawUUID; } } public function removeOnlinePlayer(Player $player) : void{ - if(isset($this->playerList[$player->getRawUniqueId()])){ - unset($this->playerList[$player->getRawUniqueId()]); + if(isset($this->playerList[$rawUUID = $player->getUniqueId()->toBinary()])){ + unset($this->playerList[$rawUUID]); foreach($this->playerList as $p){ $p->getNetworkSession()->onPlayerRemoved($player); } diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 6364e72c85..1dd906d995 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -82,7 +82,6 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ /** @var UUID */ protected $uuid; - protected $rawUUID; public $width = 0.6; public $height = 1.8; @@ -137,13 +136,6 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ return $this->uuid; } - /** - * @return string - */ - public function getRawUniqueId() : string{ - return $this->rawUUID; - } - /** * Returns a Skin object containing information about this human's skin. * @return Skin diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 570254d168..858a698348 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -282,7 +282,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->randomClientId = $this->playerInfo->getClientId(); $this->uuid = $this->playerInfo->getUuid(); - $this->rawUUID = $this->uuid->toBinary(); $this->xuid = $this->playerInfo->getXuid(); $this->perm = new PermissibleBase($this); @@ -575,7 +574,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool */ public function canSee(Player $player) : bool{ - return !isset($this->hiddenPlayers[$player->getRawUniqueId()]); + return !isset($this->hiddenPlayers[$player->getUniqueId()->toBinary()]); } /** @@ -585,7 +584,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($player === $this){ return; } - $this->hiddenPlayers[$player->getRawUniqueId()] = true; + $this->hiddenPlayers[$player->getUniqueId()->toBinary()] = true; $player->despawnFrom($this); } @@ -596,7 +595,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($player === $this){ return; } - unset($this->hiddenPlayers[$player->getRawUniqueId()]); + unset($this->hiddenPlayers[$player->getUniqueId()->toBinary()]); if($player->isOnline()){ $player->spawnTo($this); } From ceeed57118cf14b36082e4dfa1a7d96200b79ec4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 5 Jul 2019 17:28:37 +0100 Subject: [PATCH 1055/3224] Player: remove iusername premature optimization --- src/pocketmine/Server.php | 4 ++-- src/pocketmine/player/Player.php | 10 ---------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index ee18ea34b7..d42d0e9729 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -674,7 +674,7 @@ class Server{ public function getPlayerExact(string $name) : ?Player{ $name = strtolower($name); foreach($this->getOnlinePlayers() as $player){ - if($player->getLowerCaseName() === $name){ + if(strtolower($player->getName()) === $name){ return $player; } } @@ -694,7 +694,7 @@ class Server{ $partialName = strtolower($partialName); $matchedPlayers = []; foreach($this->getOnlinePlayers() as $player){ - if($player->getLowerCaseName() === $partialName){ + if(strtolower($player->getName()) === $partialName){ $matchedPlayers = [$player]; break; }elseif(stripos($player->getName(), $partialName) !== false){ diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 858a698348..e837ed4214 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -165,8 +165,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** @var string */ protected $username; /** @var string */ - protected $iusername; - /** @var string */ protected $displayName; /** @var int */ protected $randomClientId; @@ -277,7 +275,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->username = $username; $this->displayName = $this->username; - $this->iusername = strtolower($this->username); $this->locale = $this->playerInfo->getLocale(); $this->randomClientId = $this->playerInfo->getClientId(); @@ -706,13 +703,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->username; } - /** - * @return string - */ - public function getLowerCaseName() : string{ - return $this->iusername; - } - /** * Gets the "friendly" name to display of this player to use in the chat. * From 124640737a0a0dd2a7631fea440defd73457f8c8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 5 Jul 2019 17:58:15 +0100 Subject: [PATCH 1056/3224] Explosion: make use of fromFullBlock() this is in preparation for out-phasing legacy IDs. --- src/pocketmine/world/Explosion.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/world/Explosion.php b/src/pocketmine/world/Explosion.php index 71b20e981b..c70c66bf1e 100644 --- a/src/pocketmine/world/Explosion.php +++ b/src/pocketmine/world/Explosion.php @@ -129,7 +129,7 @@ class Explosion{ $blastForce -= (BlockFactory::$blastResistance[$state] / 5 + 0.3) * $this->stepLen; if($blastForce > 0){ if(!isset($this->affectedBlocks[$index = World::blockHash($vBlock->x, $vBlock->y, $vBlock->z)])){ - $this->affectedBlocks[$index] = BlockFactory::get($state >> 4, $state & 0xf, $vBlock); + $this->affectedBlocks[$index] = BlockFactory::fromFullBlock($state, $vBlock); } } } From 80747814fb769d5cbed2ea6a351ef218c9f9b0c9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 5 Jul 2019 19:40:33 +0100 Subject: [PATCH 1057/3224] fix race condition between chunk generation and light population --- src/pocketmine/world/World.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index c4bedd6736..f29102f3bf 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -2483,6 +2483,7 @@ class World implements ChunkManager{ (new ChunkLoadEvent($this, $chunk, !$chunk->isGenerated()))->call(); if(!$chunk->isLightPopulated() and $chunk->isPopulated()){ + $this->lockChunk($x, $z); $this->getServer()->getAsyncPool()->submitTask(new LightPopulationTask($this, $chunk)); } @@ -2738,18 +2739,20 @@ class World implements ChunkManager{ if(isset($this->chunkPopulationQueue[$index = World::chunkHash($x, $z)]) or (count($this->chunkPopulationQueue) >= $this->chunkPopulationQueueSize and !$force)){ return false; } - for($xx = -1; $xx <= 1; ++$xx){ - for($zz = -1; $zz <= 1; ++$zz){ - if($this->isChunkLocked($x + $xx, $z + $zz)){ - return false; - } - } - } + $chunk = $this->getChunk($x, $z, true); if(!$chunk->isPopulated()){ Timings::$populationTimer->startTiming(); + for($xx = -1; $xx <= 1; ++$xx){ + for($zz = -1; $zz <= 1; ++$zz){ + if($this->isChunkLocked($x + $xx, $z + $zz)){ + return false; + } + } + } + $this->chunkPopulationQueue[$index] = true; for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ From 13de99315bb099a4e59a55656ba19ec9607dcc82 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 5 Jul 2019 19:56:31 +0100 Subject: [PATCH 1058/3224] fixed some artifacts getting cut in half --- src/pocketmine/world/SimpleChunkManager.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pocketmine/world/SimpleChunkManager.php b/src/pocketmine/world/SimpleChunkManager.php index 35cab0f035..dd7bce34f5 100644 --- a/src/pocketmine/world/SimpleChunkManager.php +++ b/src/pocketmine/world/SimpleChunkManager.php @@ -61,6 +61,7 @@ class SimpleChunkManager implements ChunkManager{ public function setBlockAt(int $x, int $y, int $z, Block $block) : bool{ if($this->terrainPointer->moveTo($x, $y, $z, true)){ $this->terrainPointer->currentSubChunk->setFullBlock($x & 0xf, $y & 0xf, $z & 0xf, $block->getFullId()); + $this->terrainPointer->currentChunk->setChanged(true); return true; } return false; From ce77e283ab5bf1f2ecbe03a771691f156aca2e14 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 5 Jul 2019 19:56:58 +0100 Subject: [PATCH 1059/3224] Revert "fix race condition between chunk generation and light population" This reverts commit 80747814fb769d5cbed2ea6a351ef218c9f9b0c9. --- src/pocketmine/world/World.php | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index f29102f3bf..c4bedd6736 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -2483,7 +2483,6 @@ class World implements ChunkManager{ (new ChunkLoadEvent($this, $chunk, !$chunk->isGenerated()))->call(); if(!$chunk->isLightPopulated() and $chunk->isPopulated()){ - $this->lockChunk($x, $z); $this->getServer()->getAsyncPool()->submitTask(new LightPopulationTask($this, $chunk)); } @@ -2739,20 +2738,18 @@ class World implements ChunkManager{ if(isset($this->chunkPopulationQueue[$index = World::chunkHash($x, $z)]) or (count($this->chunkPopulationQueue) >= $this->chunkPopulationQueueSize and !$force)){ return false; } - + for($xx = -1; $xx <= 1; ++$xx){ + for($zz = -1; $zz <= 1; ++$zz){ + if($this->isChunkLocked($x + $xx, $z + $zz)){ + return false; + } + } + } $chunk = $this->getChunk($x, $z, true); if(!$chunk->isPopulated()){ Timings::$populationTimer->startTiming(); - for($xx = -1; $xx <= 1; ++$xx){ - for($zz = -1; $zz <= 1; ++$zz){ - if($this->isChunkLocked($x + $xx, $z + $zz)){ - return false; - } - } - } - $this->chunkPopulationQueue[$index] = true; for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ From a2bb6a41d9eea5fdf4f23045116e3def76494e0b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Jul 2019 15:16:03 +0100 Subject: [PATCH 1060/3224] World: some cleanup to random blocktick registry --- src/pocketmine/world/World.php | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index c4bedd6736..d0d93e5f3c 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -235,8 +235,8 @@ class World implements ChunkManager{ private $chunkTickRadius; /** @var int */ private $chunksPerTick; - /** @var \SplFixedArray */ - private $randomTickBlocks = null; + /** @var bool[] */ + private $randomTickBlocks = []; /** @var WorldTimings */ public $timings; @@ -370,17 +370,9 @@ class World implements ChunkManager{ $dontTickBlocks = array_fill_keys($this->server->getProperty("chunk-ticking.disable-block-ticking", []), true); - $this->randomTickBlocks = new \SplFixedArray(16384); - foreach($this->randomTickBlocks as $i => $null){ - $id = $i >> 4; - $meta = $i & 0xf; - try{ - $block = BlockFactory::get($id, $meta); //Make sure it's a copy - }catch(\InvalidArgumentException $e){ - continue; - } - if(!isset($dontTickBlocks[$id]) and $block->ticksRandomly()){ - $this->randomTickBlocks[($id << 4) | $meta] = true; + foreach(BlockFactory::getAllKnownStates() as $state){ + if(!isset($dontTickBlocks[$state->getId()]) and $state->ticksRandomly()){ + $this->randomTickBlocks[$state->getFullId()] = true; } } @@ -932,7 +924,10 @@ class World implements ChunkManager{ } } - public function getRandomTickedBlocks() : \SplFixedArray{ + /** + * @return bool[] fullID => bool + */ + public function getRandomTickedBlocks() : array{ return $this->randomTickBlocks; } @@ -945,7 +940,7 @@ class World implements ChunkManager{ } public function removeRandomTickedBlock(int $id, int $variant = 0){ - $this->randomTickBlocks[($id << 4) | $variant] = null; + unset($this->randomTickBlocks[($id << 4) | $variant]); } private function tickChunks(){ @@ -1002,7 +997,7 @@ class World implements ChunkManager{ $state = $subChunk->getFullBlock($x, $y, $z); - if($this->randomTickBlocks[$state]){ + if(isset($this->randomTickBlocks[$state])){ /** @var Block $block */ $block = BlockFactory::fromFullBlock($state, $this->temporalPosition->setComponents( $chunkX * 16 + $x, From f3995f7cb071248baf79358bb308b19e35a0b25e Mon Sep 17 00:00:00 2001 From: Frago9876543210 Date: Sat, 6 Jul 2019 17:18:09 +0300 Subject: [PATCH 1061/3224] Destroy EffectManager <-> Living cyclic reference on close (#2993) --- src/pocketmine/entity/Living.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index ffaf7db2f9..36ea6207d9 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -758,6 +758,7 @@ abstract class Living extends Entity{ protected function destroyCycles() : void{ $this->armorInventory = null; + $this->effectManager = null; parent::destroyCycles(); } } From 5c25f770c217a3f0b8b6ddab99f49ce425c13c50 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Jul 2019 15:21:30 +0100 Subject: [PATCH 1062/3224] World: reduce legacy id/meta dependencies --- src/pocketmine/world/World.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index d0d93e5f3c..d5417ee050 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -931,16 +931,15 @@ class World implements ChunkManager{ return $this->randomTickBlocks; } - public function addRandomTickedBlock(int $id, int $variant = 0){ - $block = BlockFactory::get($id, $variant); + public function addRandomTickedBlock(Block $block){ if($block instanceof UnknownBlock){ - throw new \InvalidArgumentException("ID $id variant $variant is unknown, cannot do random-tick"); + throw new \InvalidArgumentException("Cannot do random-tick on unknown block"); } - $this->randomTickBlocks[($id << 4) | $variant] = true; + $this->randomTickBlocks[$block->getFullId()] = true; } - public function removeRandomTickedBlock(int $id, int $variant = 0){ - unset($this->randomTickBlocks[($id << 4) | $variant]); + public function removeRandomTickedBlock(Block $block){ + unset($this->randomTickBlocks[$block->getFullId()]); } private function tickChunks(){ From 119cb083bfd58c7a6c2318d1744c488b8744fc86 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Jul 2019 15:22:27 +0100 Subject: [PATCH 1063/3224] [ci skip] update changelog --- changelogs/4.0-snapshot.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 4b13743949..25732e7831 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -577,6 +577,9 @@ This version features substantial changes to the network system, improving coher - The following API methods have changed signatures: - `World->addParticle()` now has the signature `addParticle(Vector3 $pos, Particle $particle, ?Player[] $players = null) : void` - `World->addSound()` now has the signature `addSound(?Vector3 $pos, Sound $sound, ?Player[] $players = null) : void` + - `World->getRandomTickedBlocks()` now returns `bool[]` instead of `SplFixedArray`. + - `World->addRandomTickedBlock()` now accepts `Block` instead of `int, int`. + - `World->removeRandomTickedBlock()` now accepts `Block` instead of `int, int`. - The following API methods have been renamed / moved: - `Level->getCollisionCubes()` -> `World->getCollisionBoxes()` - Extracted a unit `pocketmine\world\format\io\FastChunkSerializer` from `Chunk`: From 4d7c18f65b5296217a706af435ee02126bf058a6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Jul 2019 17:29:40 +0100 Subject: [PATCH 1064/3224] first look at a giant static interface for block fetching --- src/pocketmine/block/Block.php | 14 +- src/pocketmine/block/Cactus.php | 2 +- src/pocketmine/block/Cake.php | 4 +- src/pocketmine/block/CoarseDirt.php | 2 +- src/pocketmine/block/Dirt.php | 2 +- src/pocketmine/block/DragonEgg.php | 2 +- src/pocketmine/block/Farmland.php | 4 +- src/pocketmine/block/Fire.php | 8 +- src/pocketmine/block/Grass.php | 8 +- src/pocketmine/block/GrassPath.php | 2 +- src/pocketmine/block/Ice.php | 2 +- src/pocketmine/block/Lava.php | 6 +- src/pocketmine/block/Liquid.php | 2 +- src/pocketmine/block/MelonStem.php | 2 +- src/pocketmine/block/Mycelium.php | 2 +- src/pocketmine/block/PumpkinStem.php | 2 +- src/pocketmine/block/SnowLayer.php | 2 +- src/pocketmine/block/Sugarcane.php | 4 +- src/pocketmine/block/TNT.php | 2 +- src/pocketmine/block/VanillaBlocks.php | 2556 +++++++++++++++++ src/pocketmine/block/utils/FallableTrait.php | 4 +- src/pocketmine/entity/object/Painting.php | 5 +- .../entity/projectile/SplashPotion.php | 6 +- src/pocketmine/item/Banner.php | 5 +- src/pocketmine/item/Bed.php | 5 +- src/pocketmine/item/BeetrootSeeds.php | 5 +- src/pocketmine/item/Bucket.php | 5 +- src/pocketmine/item/Carrot.php | 5 +- src/pocketmine/item/CocoaBeans.php | 5 +- src/pocketmine/item/FlintSteel.php | 4 +- src/pocketmine/item/Item.php | 5 +- src/pocketmine/item/ItemFactory.php | 5 +- src/pocketmine/item/LiquidBucket.php | 37 +- src/pocketmine/item/MelonSeeds.php | 5 +- src/pocketmine/item/Potato.php | 5 +- src/pocketmine/item/PumpkinSeeds.php | 5 +- src/pocketmine/item/Redstone.php | 5 +- src/pocketmine/item/Skull.php | 5 +- src/pocketmine/item/StringItem.php | 5 +- src/pocketmine/item/WheatSeeds.php | 5 +- src/pocketmine/player/Player.php | 4 +- src/pocketmine/world/Explosion.php | 4 +- src/pocketmine/world/SimpleChunkManager.php | 4 +- src/pocketmine/world/biome/GrassyBiome.php | 13 +- src/pocketmine/world/biome/OceanBiome.php | 13 +- src/pocketmine/world/biome/RiverBiome.php | 13 +- src/pocketmine/world/biome/SandyBiome.php | 13 +- src/pocketmine/world/biome/SnowyBiome.php | 13 +- src/pocketmine/world/generator/Flat.php | 19 +- .../world/generator/hell/Nether.php | 9 +- .../world/generator/normal/Normal.php | 25 +- .../world/generator/object/BirchTree.php | 6 +- .../world/generator/object/JungleTree.php | 6 +- .../world/generator/object/OakTree.php | 6 +- .../world/generator/object/SpruceTree.php | 6 +- .../world/generator/object/TallGrass.php | 8 +- .../world/generator/object/Tree.php | 5 +- .../world/generator/populator/TallGrass.php | 4 +- 58 files changed, 2732 insertions(+), 198 deletions(-) create mode 100644 src/pocketmine/block/VanillaBlocks.php diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 5f5df3e8d3..13f4f43a20 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -283,7 +283,7 @@ class Block extends Position implements BlockLegacyIds{ if(($t = $this->world->getTile($this)) !== null){ $t->onBlockDestroyed(); } - return $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); + return $this->getWorld()->setBlock($this, VanillaBlocks::AIR()); } /** @@ -748,4 +748,16 @@ class Block extends Position implements BlockLegacyIds{ return $currentHit; } + + /** + * @param self $self + * + * @return static + */ + public static function cast(self $self){ + if(!($self instanceof static)){ + throw new \TypeError("Cannot cast from " . self::class . " to " . static::class); + } + return $self; + } } diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index ae66925171..d4ecc97814 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -95,7 +95,7 @@ class Cactus extends Transparent{ for($y = 1; $y < 3; ++$y){ $b = $this->getWorld()->getBlockAt($this->x, $this->y + $y, $this->z); if($b->getId() === BlockLegacyIds::AIR){ - $ev = new BlockGrowEvent($b, BlockFactory::get(BlockLegacyIds::CACTUS)); + $ev = new BlockGrowEvent($b, VanillaBlocks::CACTUS()); $ev->call(); if($ev->isCancelled()){ break; diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index 8d1cd4b8a3..51ea82f0f0 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -73,7 +73,7 @@ class Cake extends Transparent implements FoodSource{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ //Replace with common break method - $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); + $this->getWorld()->setBlock($this, VanillaBlocks::AIR()); } } @@ -113,7 +113,7 @@ class Cake extends Transparent implements FoodSource{ $clone = clone $this; $clone->bites++; if($clone->bites > 6){ - $clone = BlockFactory::get(BlockLegacyIds::AIR); + $clone = VanillaBlocks::AIR(); } return $clone; } diff --git a/src/pocketmine/block/CoarseDirt.php b/src/pocketmine/block/CoarseDirt.php index 91026cdc42..e26e1be74f 100644 --- a/src/pocketmine/block/CoarseDirt.php +++ b/src/pocketmine/block/CoarseDirt.php @@ -34,7 +34,7 @@ class CoarseDirt extends Dirt{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP and $item instanceof Hoe){ $item->applyDamage(1); - $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::DIRT)); + $this->getWorld()->setBlock($this, VanillaBlocks::DIRT()); return true; } diff --git a/src/pocketmine/block/Dirt.php b/src/pocketmine/block/Dirt.php index 75ecc73eec..5511d9b6db 100644 --- a/src/pocketmine/block/Dirt.php +++ b/src/pocketmine/block/Dirt.php @@ -38,7 +38,7 @@ class Dirt extends Solid{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP and $item instanceof Hoe){ $item->applyDamage(1); - $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::FARMLAND)); + $this->getWorld()->setBlock($this, VanillaBlocks::FARMLAND()); return true; } diff --git a/src/pocketmine/block/DragonEgg.php b/src/pocketmine/block/DragonEgg.php index b2bd03efed..0ede5a6be4 100644 --- a/src/pocketmine/block/DragonEgg.php +++ b/src/pocketmine/block/DragonEgg.php @@ -77,7 +77,7 @@ class DragonEgg extends Transparent implements Fallable{ $block = $ev->getTo(); } $this->world->addParticle($this, new DragonEggTeleportParticle($this->x - $block->x, $this->y - $block->y, $this->z - $block->z)); - $this->world->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); + $this->world->setBlock($this, VanillaBlocks::AIR()); $this->world->setBlock($block, $this); break; } diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index 95398761c1..2dfc1f8ab5 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -56,7 +56,7 @@ class Farmland extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::UP)->isSolid()){ - $this->world->setBlock($this, BlockFactory::get(BlockLegacyIds::DIRT)); + $this->world->setBlock($this, VanillaBlocks::DIRT()); } } @@ -70,7 +70,7 @@ class Farmland extends Transparent{ $this->wetness--; $this->world->setBlock($this, $this, false); }else{ - $this->world->setBlock($this, BlockFactory::get(BlockLegacyIds::DIRT)); + $this->world->setBlock($this, VanillaBlocks::DIRT()); } }elseif($this->wetness < 7){ $this->wetness = 7; diff --git a/src/pocketmine/block/Fire.php b/src/pocketmine/block/Fire.php index 68b96942b7..24fd42fe85 100644 --- a/src/pocketmine/block/Fire.php +++ b/src/pocketmine/block/Fire.php @@ -88,7 +88,7 @@ class Fire extends Flowable{ public function onNearbyBlockChange() : void{ if(!$this->getSide(Facing::DOWN)->isSolid() and !$this->hasAdjacentFlammableBlocks()){ - $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); + $this->getWorld()->setBlock($this, VanillaBlocks::AIR()); }else{ $this->world->scheduleDelayedBlockUpdate($this, mt_rand(30, 40)); } @@ -113,12 +113,12 @@ class Fire extends Flowable{ if($this->age === 15){ if(!$down->isFlammable() and mt_rand(0, 3) === 3){ //1/4 chance to extinguish $canSpread = false; - $result = BlockFactory::get(BlockLegacyIds::AIR); + $result = VanillaBlocks::AIR(); } }elseif(!$this->hasAdjacentFlammableBlocks()){ $canSpread = false; if(!$down->isSolid() or $this->age > 3){ - $result = BlockFactory::get(BlockLegacyIds::AIR); + $result = VanillaBlocks::AIR(); } } } @@ -170,7 +170,7 @@ class Fire extends Flowable{ $fire->age = min(15, $fire->age + (mt_rand(0, 4) >> 2)); $this->world->setBlock($block, $fire); }else{ - $this->world->setBlock($block, BlockFactory::get(BlockLegacyIds::AIR)); + $this->world->setBlock($block, VanillaBlocks::AIR()); } } } diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index cc0d6588fe..fe852a0129 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -56,7 +56,7 @@ class Grass extends Solid{ $lightAbove = $this->world->getFullLightAt($this->x, $this->y + 1, $this->z); if($lightAbove < 4 and $this->world->getBlockAt($this->x, $this->y + 1, $this->z)->getLightFilter() >= 2){ //grass dies - $ev = new BlockSpreadEvent($this, $this, BlockFactory::get(BlockLegacyIds::DIRT)); + $ev = new BlockSpreadEvent($this, $this, VanillaBlocks::DIRT()); $ev->call(); if(!$ev->isCancelled()){ $this->world->setBlock($this, $ev->getNewState(), false); @@ -78,7 +78,7 @@ class Grass extends Solid{ continue; } - $ev = new BlockSpreadEvent($b, $this, BlockFactory::get(BlockLegacyIds::GRASS)); + $ev = new BlockSpreadEvent($b, $this, VanillaBlocks::GRASS()); $ev->call(); if(!$ev->isCancelled()){ $this->world->setBlock($b, $ev->getNewState(), false); @@ -98,12 +98,12 @@ class Grass extends Solid{ return true; }elseif($item instanceof Hoe){ $item->applyDamage(1); - $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::FARMLAND)); + $this->getWorld()->setBlock($this, VanillaBlocks::FARMLAND()); return true; }elseif($item instanceof Shovel and $this->getSide(Facing::UP)->getId() === BlockLegacyIds::AIR){ $item->applyDamage(1); - $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::GRASS_PATH)); + $this->getWorld()->setBlock($this, VanillaBlocks::GRASS_PATH()); return true; } diff --git a/src/pocketmine/block/GrassPath.php b/src/pocketmine/block/GrassPath.php index 640da5dafb..e6e003429d 100644 --- a/src/pocketmine/block/GrassPath.php +++ b/src/pocketmine/block/GrassPath.php @@ -40,7 +40,7 @@ class GrassPath extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::UP)->isSolid()){ - $this->world->setBlock($this, BlockFactory::get(BlockLegacyIds::DIRT)); + $this->world->setBlock($this, VanillaBlocks::DIRT()); } } diff --git a/src/pocketmine/block/Ice.php b/src/pocketmine/block/Ice.php index 893a347824..eccf9dee51 100644 --- a/src/pocketmine/block/Ice.php +++ b/src/pocketmine/block/Ice.php @@ -43,7 +43,7 @@ class Ice extends Transparent{ public function onBreak(Item $item, ?Player $player = null) : bool{ if(($player === null or $player->isSurvival()) and !$item->hasEnchantment(Enchantment::SILK_TOUCH())){ - return $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::WATER)); + return $this->getWorld()->setBlock($this, VanillaBlocks::WATER()); } return parent::onBreak($item, $player); } diff --git a/src/pocketmine/block/Lava.php b/src/pocketmine/block/Lava.php index 48899e7efc..e897a606b3 100644 --- a/src/pocketmine/block/Lava.php +++ b/src/pocketmine/block/Lava.php @@ -69,16 +69,16 @@ class Lava extends Liquid{ if($colliding !== null){ if($this->decay === 0){ - $this->liquidCollide($colliding, BlockFactory::get(BlockLegacyIds::OBSIDIAN)); + $this->liquidCollide($colliding, VanillaBlocks::OBSIDIAN()); }elseif($this->decay <= 4){ - $this->liquidCollide($colliding, BlockFactory::get(BlockLegacyIds::COBBLESTONE)); + $this->liquidCollide($colliding, VanillaBlocks::COBBLESTONE()); } } } protected function flowIntoBlock(Block $block, int $newFlowDecay, bool $falling) : void{ if($block instanceof Water){ - $block->liquidCollide($this, BlockFactory::get(BlockLegacyIds::STONE)); + $block->liquidCollide($this, VanillaBlocks::STONE()); }else{ parent::flowIntoBlock($block, $newFlowDecay, $falling); } diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index c631dcaf71..3708f5cd45 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -282,7 +282,7 @@ abstract class Liquid extends Transparent{ if($falling !== $this->falling or (!$falling and $newDecay !== $this->decay)){ if(!$falling and $newDecay < 0){ - $this->world->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); + $this->world->setBlock($this, VanillaBlocks::AIR()); return; } diff --git a/src/pocketmine/block/MelonStem.php b/src/pocketmine/block/MelonStem.php index 9486b4df35..0684786c0f 100644 --- a/src/pocketmine/block/MelonStem.php +++ b/src/pocketmine/block/MelonStem.php @@ -26,6 +26,6 @@ namespace pocketmine\block; class MelonStem extends Stem{ protected function getPlant() : Block{ - return BlockFactory::get(BlockLegacyIds::MELON_BLOCK); + return VanillaBlocks::MELON(); } } diff --git a/src/pocketmine/block/Mycelium.php b/src/pocketmine/block/Mycelium.php index ef5ac71c30..1fb34909e9 100644 --- a/src/pocketmine/block/Mycelium.php +++ b/src/pocketmine/block/Mycelium.php @@ -53,7 +53,7 @@ class Mycelium extends Solid{ $block = $this->getWorld()->getBlockAt($x, $y, $z); if($block->getId() === BlockLegacyIds::DIRT){ if($block->getSide(Facing::UP) instanceof Transparent){ - $ev = new BlockSpreadEvent($block, $this, BlockFactory::get(BlockLegacyIds::MYCELIUM)); + $ev = new BlockSpreadEvent($block, $this, VanillaBlocks::MYCELIUM()); $ev->call(); if(!$ev->isCancelled()){ $this->getWorld()->setBlock($block, $ev->getNewState()); diff --git a/src/pocketmine/block/PumpkinStem.php b/src/pocketmine/block/PumpkinStem.php index 12ae62c161..fd909a7db0 100644 --- a/src/pocketmine/block/PumpkinStem.php +++ b/src/pocketmine/block/PumpkinStem.php @@ -26,6 +26,6 @@ namespace pocketmine\block; class PumpkinStem extends Stem{ protected function getPlant() : Block{ - return BlockFactory::get(BlockLegacyIds::PUMPKIN); + return VanillaBlocks::PUMPKIN(); } } diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index 1960eea1b0..7023691da3 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -89,7 +89,7 @@ class SnowLayer extends Flowable implements Fallable{ public function onRandomTick() : void{ if($this->world->getBlockLightAt($this->x, $this->y, $this->z) >= 12){ - $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR), false); + $this->getWorld()->setBlock($this, VanillaBlocks::AIR(), false); } } diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index 92488993d2..42fba2232a 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -59,7 +59,7 @@ class Sugarcane extends Flowable{ for($y = 1; $y < 3; ++$y){ $b = $this->getWorld()->getBlockAt($this->x, $this->y + $y, $this->z); if($b->getId() === BlockLegacyIds::AIR){ - $ev = new BlockGrowEvent($b, BlockFactory::get(BlockLegacyIds::SUGARCANE_BLOCK)); + $ev = new BlockGrowEvent($b, VanillaBlocks::SUGARCANE()); $ev->call(); if($ev->isCancelled()){ break; @@ -98,7 +98,7 @@ class Sugarcane extends Flowable{ for($y = 1; $y < 3; ++$y){ $b = $this->getWorld()->getBlockAt($this->x, $this->y + $y, $this->z); if($b->getId() === BlockLegacyIds::AIR){ - $this->getWorld()->setBlock($b, BlockFactory::get(BlockLegacyIds::SUGARCANE_BLOCK)); + $this->getWorld()->setBlock($b, VanillaBlocks::SUGARCANE()); break; } } diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index 882e1ff9da..4aa5fd2507 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -90,7 +90,7 @@ class TNT extends Solid{ } public function ignite(int $fuse = 80) : void{ - $this->getWorld()->setBlock($this, BlockFactory::get(BlockLegacyIds::AIR)); + $this->getWorld()->setBlock($this, VanillaBlocks::AIR()); $mot = (new Random())->nextSignedFloat() * M_PI * 2; $nbt = EntityFactory::createBaseNBT($this->add(0.5, 0, 0.5), new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02)); diff --git a/src/pocketmine/block/VanillaBlocks.php b/src/pocketmine/block/VanillaBlocks.php new file mode 100644 index 0000000000..930fd6c586 --- /dev/null +++ b/src/pocketmine/block/VanillaBlocks.php @@ -0,0 +1,2556 @@ +asPosition(); $down = $pos->world->getBlock($pos->getSide(Facing::DOWN)); if($down->getId() === BlockLegacyIds::AIR or $down instanceof Liquid or $down instanceof Fire){ - $pos->world->setBlock($pos, BlockFactory::get(BlockLegacyIds::AIR)); + $pos->world->setBlock($pos, VanillaBlocks::AIR()); $nbt = EntityFactory::createBaseNBT($pos->add(0.5, 0, 0.5)); $nbt->setInt("TileID", $this->getId()); diff --git a/src/pocketmine/entity/object/Painting.php b/src/pocketmine/entity/object/Painting.php index 3f1b26a3f1..9be7bc43d4 100644 --- a/src/pocketmine/entity/object/Painting.php +++ b/src/pocketmine/entity/object/Painting.php @@ -23,8 +23,7 @@ declare(strict_types=1); namespace pocketmine\entity\object; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; use pocketmine\entity\Entity; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\item\Item; @@ -109,7 +108,7 @@ class Painting extends Entity{ //non-living entities don't have a way to create drops generically yet $this->world->dropItem($this, ItemFactory::get(Item::PAINTING)); } - $this->world->addParticle($this->add(0.5, 0.5, 0.5), new DestroyBlockParticle(BlockFactory::get(BlockLegacyIds::PLANKS))); + $this->world->addParticle($this->add(0.5, 0.5, 0.5), new DestroyBlockParticle(VanillaBlocks::OAK_PLANKS())); } protected function recalculateBoundingBox() : void{ diff --git a/src/pocketmine/entity/projectile/SplashPotion.php b/src/pocketmine/entity/projectile/SplashPotion.php index 1b408978ce..a930cd37e4 100644 --- a/src/pocketmine/entity/projectile/SplashPotion.php +++ b/src/pocketmine/entity/projectile/SplashPotion.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\entity\projectile; -use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\InstantEffect; use pocketmine\entity\Living; @@ -123,11 +123,11 @@ class SplashPotion extends Throwable{ $blockIn = $event->getBlockHit()->getSide($event->getRayTraceResult()->getHitFace()); if($blockIn->getId() === BlockLegacyIds::FIRE){ - $this->world->setBlock($blockIn, BlockFactory::get(BlockLegacyIds::AIR)); + $this->world->setBlock($blockIn, VanillaBlocks::AIR()); } foreach($blockIn->getHorizontalSides() as $horizontalSide){ if($horizontalSide->getId() === BlockLegacyIds::FIRE){ - $this->world->setBlock($horizontalSide, BlockFactory::get(BlockLegacyIds::AIR)); + $this->world->setBlock($horizontalSide, VanillaBlocks::AIR()); } } } diff --git a/src/pocketmine/item/Banner.php b/src/pocketmine/item/Banner.php index 55a80ee61d..caf0dc8b51 100644 --- a/src/pocketmine/item/Banner.php +++ b/src/pocketmine/item/Banner.php @@ -25,11 +25,10 @@ namespace pocketmine\item; use Ds\Deque; use pocketmine\block\Block; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; use pocketmine\block\tile\Banner as TileBanner; use pocketmine\block\utils\BannerPattern; use pocketmine\block\utils\DyeColor; +use pocketmine\block\VanillaBlocks; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; @@ -54,7 +53,7 @@ class Banner extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(BlockLegacyIds::STANDING_BANNER); + return VanillaBlocks::BANNER(); } public function getMaxStackSize() : int{ diff --git a/src/pocketmine/item/Bed.php b/src/pocketmine/item/Bed.php index cf1095ab60..9212b80b0f 100644 --- a/src/pocketmine/item/Bed.php +++ b/src/pocketmine/item/Bed.php @@ -24,9 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\Block; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\DyeColor; +use pocketmine\block\VanillaBlocks; class Bed extends Item{ @@ -46,7 +45,7 @@ class Bed extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(BlockLegacyIds::BED_BLOCK); + return VanillaBlocks::BED(); } public function getMaxStackSize() : int{ diff --git a/src/pocketmine/item/BeetrootSeeds.php b/src/pocketmine/item/BeetrootSeeds.php index 216148a729..2ef2250da6 100644 --- a/src/pocketmine/item/BeetrootSeeds.php +++ b/src/pocketmine/item/BeetrootSeeds.php @@ -24,12 +24,11 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\Block; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; class BeetrootSeeds extends Item{ public function getBlock() : Block{ - return BlockFactory::get(BlockLegacyIds::BEETROOT_BLOCK); + return VanillaBlocks::BEETROOTS(); } } diff --git a/src/pocketmine/item/Bucket.php b/src/pocketmine/item/Bucket.php index 3497b9a4b9..d6f880a464 100644 --- a/src/pocketmine/item/Bucket.php +++ b/src/pocketmine/item/Bucket.php @@ -24,9 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\Block; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; use pocketmine\block\Liquid; +use pocketmine\block\VanillaBlocks; use pocketmine\event\player\PlayerBucketFillEvent; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -47,7 +46,7 @@ class Bucket extends Item{ $ev = new PlayerBucketFillEvent($player, $blockReplace, $face, $this, $resultItem); $ev->call(); if(!$ev->isCancelled()){ - $player->getWorld()->setBlock($blockClicked, BlockFactory::get(BlockLegacyIds::AIR)); + $player->getWorld()->setBlock($blockClicked, VanillaBlocks::AIR()); $player->getWorld()->addSound($blockClicked->add(0.5, 0.5, 0.5), $blockClicked->getBucketFillSound()); if($player->hasFiniteResources()){ if($stack->getCount() === 0){ diff --git a/src/pocketmine/item/Carrot.php b/src/pocketmine/item/Carrot.php index 92491c4322..ec5d476996 100644 --- a/src/pocketmine/item/Carrot.php +++ b/src/pocketmine/item/Carrot.php @@ -24,13 +24,12 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\Block; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; class Carrot extends Food{ public function getBlock() : Block{ - return BlockFactory::get(BlockLegacyIds::CARROT_BLOCK); + return VanillaBlocks::CARROTS(); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/CocoaBeans.php b/src/pocketmine/item/CocoaBeans.php index d1461e9846..bd6ac2d1c1 100644 --- a/src/pocketmine/item/CocoaBeans.php +++ b/src/pocketmine/item/CocoaBeans.php @@ -24,12 +24,11 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\Block; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; class CocoaBeans extends Item{ public function getBlock() : Block{ - return BlockFactory::get(BlockLegacyIds::COCOA); + return VanillaBlocks::COCOA_POD(); } } diff --git a/src/pocketmine/item/FlintSteel.php b/src/pocketmine/item/FlintSteel.php index 7d8e071198..18772a05fc 100644 --- a/src/pocketmine/item/FlintSteel.php +++ b/src/pocketmine/item/FlintSteel.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\Block; -use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\world\sound\FlintSteelSound; @@ -37,7 +37,7 @@ class FlintSteel extends Tool{ if($blockReplace->getId() === BlockLegacyIds::AIR){ $world = $player->getWorld(); assert($world !== null); - $world->setBlock($blockReplace, BlockFactory::get(BlockLegacyIds::FIRE)); + $world->setBlock($blockReplace, VanillaBlocks::FIRE()); $world->addSound($blockReplace->add(0.5, 0.5, 0.5), new FlintSteelSound()); $this->applyDamage(1); diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 7a4c2aca10..b7bd229ca7 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -28,9 +28,8 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockBreakInfo; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; use pocketmine\block\BlockToolType; +use pocketmine\block\VanillaBlocks; use pocketmine\entity\Entity; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\EnchantmentInstance; @@ -529,7 +528,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return Block */ public function getBlock() : Block{ - return BlockFactory::get(BlockLegacyIds::AIR); + return VanillaBlocks::AIR(); } /** diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index b6b076f277..b122778c89 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -28,6 +28,7 @@ use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\SkullType; use pocketmine\block\utils\TreeType; +use pocketmine\block\VanillaBlocks; use pocketmine\entity\EntityFactory; use pocketmine\entity\Living; use pocketmine\nbt\tag\CompoundTag; @@ -218,8 +219,8 @@ class ItemFactory{ self::register(new Leggings(Item::LEATHER_LEGGINGS, 0, "Leather Pants", new ArmorTypeInfo(2, 76))); //TODO: fix metadata for buckets with still liquid in them //the meta values are intentionally hardcoded because block IDs will change in the future - self::register(new LiquidBucket(Item::BUCKET, 8, "Water Bucket", BlockLegacyIds::FLOWING_WATER)); - self::register(new LiquidBucket(Item::BUCKET, 10, "Lava Bucket", BlockLegacyIds::FLOWING_LAVA)); + self::register(new LiquidBucket(Item::BUCKET, 8, "Water Bucket", VanillaBlocks::WATER())); + self::register(new LiquidBucket(Item::BUCKET, 10, "Lava Bucket", VanillaBlocks::LAVA())); self::register(new Melon(Item::MELON, 0, "Melon")); self::register(new MelonSeeds(Item::MELON_SEEDS, 0, "Melon Seeds")); self::register(new MilkBucket(Item::BUCKET, 1, "Milk Bucket")); diff --git a/src/pocketmine/item/LiquidBucket.php b/src/pocketmine/item/LiquidBucket.php index 1f2b74e3cf..4d2d7d7910 100644 --- a/src/pocketmine/item/LiquidBucket.php +++ b/src/pocketmine/item/LiquidBucket.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\Block; -use pocketmine\block\BlockFactory; use pocketmine\block\Lava; use pocketmine\block\Liquid; use pocketmine\event\player\PlayerBucketEmptyEvent; @@ -32,12 +31,13 @@ use pocketmine\math\Vector3; use pocketmine\player\Player; class LiquidBucket extends Item{ - /** @var int|null */ - protected $liquidId; - public function __construct(int $id, int $meta, string $name, int $liquidId){ + /** @var Liquid */ + private $liquid; + + public function __construct(int $id, int $meta, string $name, Liquid $liquid){ parent::__construct($id, $meta, $name); - $this->liquidId = $liquidId; + $this->liquid = $liquid; } public function getMaxStackSize() : int{ @@ -45,7 +45,7 @@ class LiquidBucket extends Item{ } public function getFuelTime() : int{ - if(BlockFactory::get($this->liquidId) instanceof Lava){ + if($this->liquid instanceof Lava){ return 20000; } @@ -58,23 +58,20 @@ class LiquidBucket extends Item{ } //TODO: move this to generic placement logic - $resultBlock = BlockFactory::get($this->liquidId); - if($resultBlock instanceof Liquid){ //TODO: this should never be false - $ev = new PlayerBucketEmptyEvent($player, $blockReplace, $face, $this, ItemFactory::get(Item::BUCKET)); - $ev->call(); - if(!$ev->isCancelled()){ - $player->getWorld()->setBlock($blockReplace, $resultBlock->getFlowingForm()); - $player->getWorld()->addSound($blockClicked->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound()); + $resultBlock = clone $this->liquid; - if($player->hasFiniteResources()){ - $player->getInventory()->setItemInHand($ev->getItem()); - } - return ItemUseResult::SUCCESS(); + $ev = new PlayerBucketEmptyEvent($player, $blockReplace, $face, $this, ItemFactory::get(Item::BUCKET)); + $ev->call(); + if(!$ev->isCancelled()){ + $player->getWorld()->setBlock($blockReplace, $resultBlock->getFlowingForm()); + $player->getWorld()->addSound($blockClicked->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound()); + + if($player->hasFiniteResources()){ + $player->getInventory()->setItemInHand($ev->getItem()); } - - return ItemUseResult::FAIL(); + return ItemUseResult::SUCCESS(); } - return ItemUseResult::NONE(); + return ItemUseResult::FAIL(); } } diff --git a/src/pocketmine/item/MelonSeeds.php b/src/pocketmine/item/MelonSeeds.php index f2d7820588..ee397fdba2 100644 --- a/src/pocketmine/item/MelonSeeds.php +++ b/src/pocketmine/item/MelonSeeds.php @@ -24,12 +24,11 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\Block; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; class MelonSeeds extends Item{ public function getBlock() : Block{ - return BlockFactory::get(BlockLegacyIds::MELON_STEM); + return VanillaBlocks::MELON_STEM(); } } diff --git a/src/pocketmine/item/Potato.php b/src/pocketmine/item/Potato.php index c9fbd32eba..f5bae0227d 100644 --- a/src/pocketmine/item/Potato.php +++ b/src/pocketmine/item/Potato.php @@ -24,13 +24,12 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\Block; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; class Potato extends Food{ public function getBlock() : Block{ - return BlockFactory::get(BlockLegacyIds::POTATO_BLOCK); + return VanillaBlocks::POTATOES(); } public function getFoodRestore() : int{ diff --git a/src/pocketmine/item/PumpkinSeeds.php b/src/pocketmine/item/PumpkinSeeds.php index 048538090f..f192ba90be 100644 --- a/src/pocketmine/item/PumpkinSeeds.php +++ b/src/pocketmine/item/PumpkinSeeds.php @@ -24,12 +24,11 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\Block; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; class PumpkinSeeds extends Item{ public function getBlock() : Block{ - return BlockFactory::get(BlockLegacyIds::PUMPKIN_STEM); + return VanillaBlocks::PUMPKIN_STEM(); } } diff --git a/src/pocketmine/item/Redstone.php b/src/pocketmine/item/Redstone.php index 6e4e054b5d..b4b5d0a975 100644 --- a/src/pocketmine/item/Redstone.php +++ b/src/pocketmine/item/Redstone.php @@ -24,12 +24,11 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\Block; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; class Redstone extends Item{ public function getBlock() : Block{ - return BlockFactory::get(BlockLegacyIds::REDSTONE_WIRE); + return VanillaBlocks::REDSTONE_WIRE(); } } diff --git a/src/pocketmine/item/Skull.php b/src/pocketmine/item/Skull.php index b5baae5045..62d008662b 100644 --- a/src/pocketmine/item/Skull.php +++ b/src/pocketmine/item/Skull.php @@ -24,9 +24,8 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\Block; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\SkullType; +use pocketmine\block\VanillaBlocks; class Skull extends Item{ @@ -39,7 +38,7 @@ class Skull extends Item{ } public function getBlock() : Block{ - return BlockFactory::get(BlockLegacyIds::SKULL_BLOCK); + return VanillaBlocks::MOB_HEAD(); } public function getSkullType() : SkullType{ diff --git a/src/pocketmine/item/StringItem.php b/src/pocketmine/item/StringItem.php index 9497e34ab4..366adfd12e 100644 --- a/src/pocketmine/item/StringItem.php +++ b/src/pocketmine/item/StringItem.php @@ -24,12 +24,11 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\Block; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; class StringItem extends Item{ public function getBlock() : Block{ - return BlockFactory::get(BlockLegacyIds::TRIPWIRE); + return VanillaBlocks::TRIPWIRE(); } } diff --git a/src/pocketmine/item/WheatSeeds.php b/src/pocketmine/item/WheatSeeds.php index d844aeea77..0a2478aeff 100644 --- a/src/pocketmine/item/WheatSeeds.php +++ b/src/pocketmine/item/WheatSeeds.php @@ -24,12 +24,11 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\Block; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; class WheatSeeds extends Item{ public function getBlock() : Block{ - return BlockFactory::get(BlockLegacyIds::WHEAT_BLOCK); + return VanillaBlocks::WHEAT(); } } diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index e837ed4214..750e22a1d5 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -24,9 +24,9 @@ declare(strict_types=1); namespace pocketmine\player; use pocketmine\block\Bed; -use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\block\UnknownBlock; +use pocketmine\block\VanillaBlocks; use pocketmine\command\CommandSender; use pocketmine\crafting\CraftingGrid; use pocketmine\entity\effect\Effect; @@ -1783,7 +1783,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $block = $target->getSide($face); if($block->getId() === BlockLegacyIds::FIRE){ - $this->world->setBlock($block, BlockFactory::get(BlockLegacyIds::AIR)); + $this->world->setBlock($block, VanillaBlocks::AIR()); return true; } diff --git a/src/pocketmine/world/Explosion.php b/src/pocketmine/world/Explosion.php index c70c66bf1e..3180b7caac 100644 --- a/src/pocketmine/world/Explosion.php +++ b/src/pocketmine/world/Explosion.php @@ -25,8 +25,8 @@ namespace pocketmine\world; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; use pocketmine\block\TNT; +use pocketmine\block\VanillaBlocks; use pocketmine\entity\Entity; use pocketmine\event\block\BlockUpdateEvent; use pocketmine\event\entity\EntityDamageByBlockEvent; @@ -200,7 +200,7 @@ class Explosion{ $air = ItemFactory::air(); - $airBlock = BlockFactory::get(BlockLegacyIds::AIR); + $airBlock = VanillaBlocks::AIR(); foreach($this->affectedBlocks as $block){ if($block instanceof TNT){ diff --git a/src/pocketmine/world/SimpleChunkManager.php b/src/pocketmine/world/SimpleChunkManager.php index dd7bce34f5..8869f41899 100644 --- a/src/pocketmine/world/SimpleChunkManager.php +++ b/src/pocketmine/world/SimpleChunkManager.php @@ -25,7 +25,7 @@ namespace pocketmine\world; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; use pocketmine\world\format\Chunk; use pocketmine\world\utils\SubChunkIteratorManager; use const INT32_MAX; @@ -55,7 +55,7 @@ class SimpleChunkManager implements ChunkManager{ if($this->terrainPointer->moveTo($x, $y, $z, false)){ return BlockFactory::fromFullBlock($this->terrainPointer->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf)); } - return BlockFactory::get(BlockLegacyIds::AIR); + return VanillaBlocks::AIR(); } public function setBlockAt(int $x, int $y, int $z, Block $block) : bool{ diff --git a/src/pocketmine/world/biome/GrassyBiome.php b/src/pocketmine/world/biome/GrassyBiome.php index 142b18b811..9520c1a2e0 100644 --- a/src/pocketmine/world/biome/GrassyBiome.php +++ b/src/pocketmine/world/biome/GrassyBiome.php @@ -23,18 +23,17 @@ declare(strict_types=1); namespace pocketmine\world\biome; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; abstract class GrassyBiome extends Biome{ public function __construct(){ $this->setGroundCover([ - BlockFactory::get(BlockLegacyIds::GRASS), - BlockFactory::get(BlockLegacyIds::DIRT), - BlockFactory::get(BlockLegacyIds::DIRT), - BlockFactory::get(BlockLegacyIds::DIRT), - BlockFactory::get(BlockLegacyIds::DIRT) + VanillaBlocks::GRASS(), + VanillaBlocks::DIRT(), + VanillaBlocks::DIRT(), + VanillaBlocks::DIRT(), + VanillaBlocks::DIRT() ]); } } diff --git a/src/pocketmine/world/biome/OceanBiome.php b/src/pocketmine/world/biome/OceanBiome.php index c3274c90db..e554ca7312 100644 --- a/src/pocketmine/world/biome/OceanBiome.php +++ b/src/pocketmine/world/biome/OceanBiome.php @@ -23,19 +23,18 @@ declare(strict_types=1); namespace pocketmine\world\biome; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; use pocketmine\world\generator\populator\TallGrass; class OceanBiome extends Biome{ public function __construct(){ $this->setGroundCover([ - BlockFactory::get(BlockLegacyIds::GRAVEL), - BlockFactory::get(BlockLegacyIds::GRAVEL), - BlockFactory::get(BlockLegacyIds::GRAVEL), - BlockFactory::get(BlockLegacyIds::GRAVEL), - BlockFactory::get(BlockLegacyIds::GRAVEL) + VanillaBlocks::GRAVEL(), + VanillaBlocks::GRAVEL(), + VanillaBlocks::GRAVEL(), + VanillaBlocks::GRAVEL(), + VanillaBlocks::GRAVEL() ]); $tallGrass = new TallGrass(); diff --git a/src/pocketmine/world/biome/RiverBiome.php b/src/pocketmine/world/biome/RiverBiome.php index 7752d5da8c..534107b8c1 100644 --- a/src/pocketmine/world/biome/RiverBiome.php +++ b/src/pocketmine/world/biome/RiverBiome.php @@ -23,19 +23,18 @@ declare(strict_types=1); namespace pocketmine\world\biome; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; use pocketmine\world\generator\populator\TallGrass; class RiverBiome extends Biome{ public function __construct(){ $this->setGroundCover([ - BlockFactory::get(BlockLegacyIds::DIRT), - BlockFactory::get(BlockLegacyIds::DIRT), - BlockFactory::get(BlockLegacyIds::DIRT), - BlockFactory::get(BlockLegacyIds::DIRT), - BlockFactory::get(BlockLegacyIds::DIRT) + VanillaBlocks::DIRT(), + VanillaBlocks::DIRT(), + VanillaBlocks::DIRT(), + VanillaBlocks::DIRT(), + VanillaBlocks::DIRT() ]); $tallGrass = new TallGrass(); diff --git a/src/pocketmine/world/biome/SandyBiome.php b/src/pocketmine/world/biome/SandyBiome.php index 3e45c709b2..e809c62016 100644 --- a/src/pocketmine/world/biome/SandyBiome.php +++ b/src/pocketmine/world/biome/SandyBiome.php @@ -23,18 +23,17 @@ declare(strict_types=1); namespace pocketmine\world\biome; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; abstract class SandyBiome extends Biome{ public function __construct(){ $this->setGroundCover([ - BlockFactory::get(BlockLegacyIds::SAND), - BlockFactory::get(BlockLegacyIds::SAND), - BlockFactory::get(BlockLegacyIds::SANDSTONE), - BlockFactory::get(BlockLegacyIds::SANDSTONE), - BlockFactory::get(BlockLegacyIds::SANDSTONE) + VanillaBlocks::SAND(), + VanillaBlocks::SAND(), + VanillaBlocks::SANDSTONE(), + VanillaBlocks::SANDSTONE(), + VanillaBlocks::SANDSTONE() ]); } } diff --git a/src/pocketmine/world/biome/SnowyBiome.php b/src/pocketmine/world/biome/SnowyBiome.php index 19d8ca0574..ed1061d639 100644 --- a/src/pocketmine/world/biome/SnowyBiome.php +++ b/src/pocketmine/world/biome/SnowyBiome.php @@ -23,18 +23,17 @@ declare(strict_types=1); namespace pocketmine\world\biome; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; abstract class SnowyBiome extends Biome{ public function __construct(){ $this->setGroundCover([ - BlockFactory::get(BlockLegacyIds::SNOW_LAYER), - BlockFactory::get(BlockLegacyIds::GRASS), - BlockFactory::get(BlockLegacyIds::DIRT), - BlockFactory::get(BlockLegacyIds::DIRT), - BlockFactory::get(BlockLegacyIds::DIRT) + VanillaBlocks::SNOW_LAYER(), + VanillaBlocks::GRASS(), + VanillaBlocks::DIRT(), + VanillaBlocks::DIRT(), + VanillaBlocks::DIRT() ]); } } diff --git a/src/pocketmine/world/generator/Flat.php b/src/pocketmine/world/generator/Flat.php index 1ea1b9b66a..85e103b59a 100644 --- a/src/pocketmine/world/generator/Flat.php +++ b/src/pocketmine/world/generator/Flat.php @@ -23,8 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\generator; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; use pocketmine\item\ItemFactory; use pocketmine\world\ChunkManager; use pocketmine\world\format\Chunk; @@ -73,14 +72,14 @@ class Flat extends Generator{ if(isset($this->options["decoration"])){ $ores = new Ore(); $ores->setOreTypes([ - new OreType(BlockFactory::get(BlockLegacyIds::COAL_ORE), 20, 16, 0, 128), - new OreType(BlockFactory::get(BlockLegacyIds::IRON_ORE), 20, 8, 0, 64), - new OreType(BlockFactory::get(BlockLegacyIds::REDSTONE_ORE), 8, 7, 0, 16), - new OreType(BlockFactory::get(BlockLegacyIds::LAPIS_ORE), 1, 6, 0, 32), - new OreType(BlockFactory::get(BlockLegacyIds::GOLD_ORE), 2, 8, 0, 32), - new OreType(BlockFactory::get(BlockLegacyIds::DIAMOND_ORE), 1, 7, 0, 16), - new OreType(BlockFactory::get(BlockLegacyIds::DIRT), 20, 32, 0, 128), - new OreType(BlockFactory::get(BlockLegacyIds::GRAVEL), 10, 16, 0, 128) + new OreType(VanillaBlocks::COAL_ORE(), 20, 16, 0, 128), + new OreType(VanillaBlocks::IRON_ORE(), 20, 8, 0, 64), + new OreType(VanillaBlocks::REDSTONE_ORE(), 8, 7, 0, 16), + new OreType(VanillaBlocks::LAPIS_LAZULI_ORE(), 1, 6, 0, 32), + new OreType(VanillaBlocks::GOLD_ORE(), 2, 8, 0, 32), + new OreType(VanillaBlocks::DIAMOND_ORE(), 1, 7, 0, 16), + new OreType(VanillaBlocks::DIRT(), 20, 32, 0, 128), + new OreType(VanillaBlocks::GRAVEL(), 10, 16, 0, 128) ]); $this->populators[] = $ores; } diff --git a/src/pocketmine/world/generator/hell/Nether.php b/src/pocketmine/world/generator/hell/Nether.php index da8bef88a2..efb11abed9 100644 --- a/src/pocketmine/world/generator/hell/Nether.php +++ b/src/pocketmine/world/generator/hell/Nether.php @@ -23,8 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\generator\hell; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; use pocketmine\world\biome\Biome; use pocketmine\world\ChunkManager; use pocketmine\world\generator\Generator; @@ -85,9 +84,9 @@ class Nether extends Generator{ $chunk = $this->world->getChunk($chunkX, $chunkZ); - $bedrock = BlockFactory::get(BlockLegacyIds::BEDROCK)->getFullId(); - $netherrack = BlockFactory::get(BlockLegacyIds::NETHERRACK)->getFullId(); - $stillLava = BlockFactory::get(BlockLegacyIds::STILL_LAVA)->getFullId(); + $bedrock = VanillaBlocks::BEDROCK()->getFullId(); + $netherrack = VanillaBlocks::NETHERRACK()->getFullId(); + $stillLava = VanillaBlocks::LAVA()->getFullId(); for($x = 0; $x < 16; ++$x){ for($z = 0; $z < 16; ++$z){ diff --git a/src/pocketmine/world/generator/normal/Normal.php b/src/pocketmine/world/generator/normal/Normal.php index dd96272837..4fc7250fdd 100644 --- a/src/pocketmine/world/generator/normal/Normal.php +++ b/src/pocketmine/world/generator/normal/Normal.php @@ -23,8 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\generator\normal; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; use pocketmine\world\biome\Biome; use pocketmine\world\ChunkManager; use pocketmine\world\generator\biome\BiomeSelector; @@ -120,14 +119,14 @@ class Normal extends Generator{ $ores = new Ore(); $ores->setOreTypes([ - new OreType(BlockFactory::get(BlockLegacyIds::COAL_ORE), 20, 16, 0, 128), - new OreType(BlockFactory::get(BlockLegacyIds::IRON_ORE), 20, 8, 0, 64), - new OreType(BlockFactory::get(BlockLegacyIds::REDSTONE_ORE), 8, 7, 0, 16), - new OreType(BlockFactory::get(BlockLegacyIds::LAPIS_ORE), 1, 6, 0, 32), - new OreType(BlockFactory::get(BlockLegacyIds::GOLD_ORE), 2, 8, 0, 32), - new OreType(BlockFactory::get(BlockLegacyIds::DIAMOND_ORE), 1, 7, 0, 16), - new OreType(BlockFactory::get(BlockLegacyIds::DIRT), 20, 32, 0, 128), - new OreType(BlockFactory::get(BlockLegacyIds::GRAVEL), 10, 16, 0, 128) + new OreType(VanillaBlocks::COAL_ORE(), 20, 16, 0, 128), + new OreType(VanillaBlocks::IRON_ORE(), 20, 8, 0, 64), + new OreType(VanillaBlocks::REDSTONE_ORE(), 8, 7, 0, 16), + new OreType(VanillaBlocks::LAPIS_LAZULI_ORE(), 1, 6, 0, 32), + new OreType(VanillaBlocks::GOLD_ORE(), 2, 8, 0, 32), + new OreType(VanillaBlocks::DIAMOND_ORE(), 1, 7, 0, 16), + new OreType(VanillaBlocks::DIRT(), 20, 32, 0, 128), + new OreType(VanillaBlocks::GRAVEL(), 10, 16, 0, 128) ]); $this->populators[] = $ores; } @@ -173,9 +172,9 @@ class Normal extends Generator{ $biomeCache = []; - $bedrock = BlockFactory::get(BlockLegacyIds::BEDROCK)->getFullId(); - $stillWater = BlockFactory::get(BlockLegacyIds::STILL_WATER)->getFullId(); - $stone = BlockFactory::get(BlockLegacyIds::STONE)->getFullId(); + $bedrock = VanillaBlocks::BEDROCK()->getFullId(); + $stillWater = VanillaBlocks::WATER()->getFullId(); + $stone = VanillaBlocks::STONE()->getFullId(); for($x = 0; $x < 16; ++$x){ for($z = 0; $z < 16; ++$z){ diff --git a/src/pocketmine/world/generator/object/BirchTree.php b/src/pocketmine/world/generator/object/BirchTree.php index 65c3365e77..c3fdc8de11 100644 --- a/src/pocketmine/world/generator/object/BirchTree.php +++ b/src/pocketmine/world/generator/object/BirchTree.php @@ -23,9 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\generator\object; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; -use pocketmine\block\utils\TreeType; +use pocketmine\block\VanillaBlocks; use pocketmine\utils\Random; use pocketmine\world\ChunkManager; @@ -34,7 +32,7 @@ class BirchTree extends Tree{ protected $superBirch = false; public function __construct(bool $superBirch = false){ - parent::__construct(BlockFactory::get(BlockLegacyIds::LOG, TreeType::BIRCH()->getMagicNumber()), BlockFactory::get(BlockLegacyIds::LEAVES, TreeType::BIRCH()->getMagicNumber())); + parent::__construct(VanillaBlocks::BIRCH_LOG(), VanillaBlocks::BIRCH_LEAVES()); $this->superBirch = $superBirch; } diff --git a/src/pocketmine/world/generator/object/JungleTree.php b/src/pocketmine/world/generator/object/JungleTree.php index 0daeaaa67f..de687b9200 100644 --- a/src/pocketmine/world/generator/object/JungleTree.php +++ b/src/pocketmine/world/generator/object/JungleTree.php @@ -23,13 +23,11 @@ declare(strict_types=1); namespace pocketmine\world\generator\object; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; -use pocketmine\block\utils\TreeType; +use pocketmine\block\VanillaBlocks; class JungleTree extends Tree{ public function __construct(){ - parent::__construct(BlockFactory::get(BlockLegacyIds::LOG, TreeType::JUNGLE()->getMagicNumber()), BlockFactory::get(BlockLegacyIds::LEAVES, TreeType::JUNGLE()->getMagicNumber()), 8); + parent::__construct(VanillaBlocks::JUNGLE_LOG(), VanillaBlocks::JUNGLE_LEAVES(), 8); } } diff --git a/src/pocketmine/world/generator/object/OakTree.php b/src/pocketmine/world/generator/object/OakTree.php index 01d06425ae..e66b7a0e2b 100644 --- a/src/pocketmine/world/generator/object/OakTree.php +++ b/src/pocketmine/world/generator/object/OakTree.php @@ -23,16 +23,14 @@ declare(strict_types=1); namespace pocketmine\world\generator\object; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; -use pocketmine\block\utils\TreeType; +use pocketmine\block\VanillaBlocks; use pocketmine\utils\Random; use pocketmine\world\ChunkManager; class OakTree extends Tree{ public function __construct(){ - parent::__construct(BlockFactory::get(BlockLegacyIds::LOG, TreeType::OAK()->getMagicNumber()), BlockFactory::get(BlockLegacyIds::LEAVES, TreeType::OAK()->getMagicNumber())); + parent::__construct(VanillaBlocks::OAK_LOG(), VanillaBlocks::OAK_LEAVES()); } public function placeObject(ChunkManager $world, int $x, int $y, int $z, Random $random) : void{ diff --git a/src/pocketmine/world/generator/object/SpruceTree.php b/src/pocketmine/world/generator/object/SpruceTree.php index 59f74e83d6..679b5fcc01 100644 --- a/src/pocketmine/world/generator/object/SpruceTree.php +++ b/src/pocketmine/world/generator/object/SpruceTree.php @@ -23,9 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\generator\object; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; -use pocketmine\block\utils\TreeType; +use pocketmine\block\VanillaBlocks; use pocketmine\utils\Random; use pocketmine\world\BlockTransaction; use pocketmine\world\ChunkManager; @@ -34,7 +32,7 @@ use function abs; class SpruceTree extends Tree{ public function __construct(){ - parent::__construct(BlockFactory::get(BlockLegacyIds::LOG, TreeType::SPRUCE()->getMagicNumber()), BlockFactory::get(BlockLegacyIds::LEAVES, TreeType::SPRUCE()->getMagicNumber()), 10); + parent::__construct(VanillaBlocks::SPRUCE_LOG(), VanillaBlocks::SPRUCE_LEAVES(), 10); } protected function generateChunkHeight(Random $random) : int{ diff --git a/src/pocketmine/world/generator/object/TallGrass.php b/src/pocketmine/world/generator/object/TallGrass.php index eb8fc38af1..80e75e5a1d 100644 --- a/src/pocketmine/world/generator/object/TallGrass.php +++ b/src/pocketmine/world/generator/object/TallGrass.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\world\generator\object; use pocketmine\block\Block; -use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; use pocketmine\math\Vector3; use pocketmine\utils\Random; use pocketmine\world\ChunkManager; @@ -36,9 +36,9 @@ class TallGrass{ public static function growGrass(ChunkManager $world, Vector3 $pos, Random $random, int $count = 15, int $radius = 10) : void{ /** @var Block[] $arr */ $arr = [ - BlockFactory::get(BlockLegacyIds::DANDELION), - BlockFactory::get(BlockLegacyIds::POPPY), - $tallGrass = BlockFactory::get(BlockLegacyIds::TALL_GRASS, 1), + VanillaBlocks::DANDELION(), + VanillaBlocks::POPPY(), + $tallGrass = VanillaBlocks::TALL_GRASS(), $tallGrass, $tallGrass, $tallGrass diff --git a/src/pocketmine/world/generator/object/Tree.php b/src/pocketmine/world/generator/object/Tree.php index c3f2b72aa9..be9a2adf64 100644 --- a/src/pocketmine/world/generator/object/Tree.php +++ b/src/pocketmine/world/generator/object/Tree.php @@ -24,11 +24,10 @@ declare(strict_types=1); namespace pocketmine\world\generator\object; use pocketmine\block\Block; -use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; use pocketmine\block\Leaves; use pocketmine\block\Sapling; use pocketmine\block\utils\TreeType; +use pocketmine\block\VanillaBlocks; use pocketmine\utils\Random; use pocketmine\world\BlockTransaction; use pocketmine\world\ChunkManager; @@ -121,7 +120,7 @@ abstract class Tree{ protected function placeTrunk(int $x, int $y, int $z, Random $random, int $trunkHeight, BlockTransaction $transaction) : void{ // The base dirt block - $transaction->addBlockAt($x, $y - 1, $z, BlockFactory::get(BlockLegacyIds::DIRT)); + $transaction->addBlockAt($x, $y - 1, $z, VanillaBlocks::DIRT()); for($yy = 0; $yy < $trunkHeight; ++$yy){ if($this->canOverride($transaction->fetchBlockAt($x, $y + $yy, $z))){ diff --git a/src/pocketmine/world/generator/populator/TallGrass.php b/src/pocketmine/world/generator/populator/TallGrass.php index d46026744c..4833fa6a5e 100644 --- a/src/pocketmine/world/generator/populator/TallGrass.php +++ b/src/pocketmine/world/generator/populator/TallGrass.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\world\generator\populator; -use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; +use pocketmine\block\VanillaBlocks; use pocketmine\utils\Random; use pocketmine\world\ChunkManager; @@ -46,7 +46,7 @@ class TallGrass extends Populator{ $this->world = $world; $amount = $random->nextRange(0, $this->randomAmount + 1) + $this->baseAmount; - $block = BlockFactory::get(BlockLegacyIds::TALL_GRASS, 1); + $block = VanillaBlocks::TALL_GRASS(); for($i = 0; $i < $amount; ++$i){ $x = $random->nextRange($chunkX * 16, $chunkX * 16 + 15); $z = $random->nextRange($chunkZ * 16, $chunkZ * 16 + 15); From da0358529a46f7fbad03a02143e44a73e6e9e241 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Jul 2019 18:50:34 +0100 Subject: [PATCH 1065/3224] Extract a HungerManager unit from Human --- changelogs/4.0-snapshot.md | 13 + src/pocketmine/entity/Human.php | 197 ++------------ src/pocketmine/entity/HungerManager.php | 254 ++++++++++++++++++ src/pocketmine/entity/effect/HungerEffect.php | 2 +- .../entity/effect/SaturationEffect.php | 5 +- src/pocketmine/player/Player.php | 30 +-- 6 files changed, 300 insertions(+), 201 deletions(-) create mode 100644 src/pocketmine/entity/HungerManager.php diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 25732e7831..44282db671 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -150,6 +150,7 @@ This version features substantial changes to the network system, improving coher - The following API methods have been added: - `ItemEntity->getDespawnDelay()` - `ItemEntity->setDespawnDelay()` + - `Human->getHungerManager()` - The following methods have signature changes: - `Entity->entityBaseTick()` is now `protected`. - `Entity->move()` is now `protected`. @@ -157,6 +158,7 @@ This version features substantial changes to the network system, improving coher - `Living->getEffects()` now returns `EffectManager` instead of `Effect[]`. - The following classes have been added: - `effect\EffectManager`: contains effect-management functionality extracted from `Living` + - `HungerManager`: contains hunger-management functionality extracted from `Human` - The following API methods have been moved / renamed: - `Living->removeAllEffects()` -> `EffectManager->clear()` - `Living->removeEffect()` -> `EffectManager->remove()` @@ -165,6 +167,17 @@ This version features substantial changes to the network system, improving coher - `Living->hasEffect()` -> `EffectManager->has()` - `Living->hasEffects()` -> `EffectManager->hasEffects()` - `Living->getEffects()` -> `EffectManager->all()` + - `Human->getFood()` -> `HungerManager->getFood()` + - `Human->setFood()` -> `HungerManager->setFood()` + - `Human->getMaxFood()` -> `HungerManager->getMaxFood()` + - `Human->addFood()` -> `HungerManager->addFood()` + - `Human->isHungry()` -> `HungerManager->isHungry()` + - `Human->getSaturation()` -> `HungerManager->getSaturation()` + - `Human->setSaturation()` -> `HungerManager->setSaturation()` + - `Human->addSaturation()` -> `HungerManager->addSaturation()` + - `Human->getExhaustion()` -> `HungerManager->getExhaustion()` + - `Human->setExhaustion()` -> `HungerManager->setExhaustion()` + - `Human->exhaust()` -> `HungerManager->exhaust()` - The following API methods have been removed: - `Human->getRawUniqueId()`: use `Human->getUniqueId()->toBinary()` instead - The following classes have been removed: diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 1dd906d995..fadef01aba 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -28,7 +28,6 @@ use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\projectile\ProjectileSource; use pocketmine\entity\utils\ExperienceUtils; use pocketmine\event\entity\EntityDamageEvent; -use pocketmine\event\entity\EntityRegainHealthEvent; use pocketmine\event\player\PlayerExhaustEvent; use pocketmine\event\player\PlayerExperienceChangeEvent; use pocketmine\inventory\EnderChestInventory; @@ -65,7 +64,6 @@ use function array_rand; use function array_values; use function ceil; use function in_array; -use function max; use function min; use function random_int; use function strlen; @@ -90,7 +88,8 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ /** @var Skin */ protected $skin; - protected $foodTickTimer = 0; + /** @var HungerManager */ + protected $hungerManager; protected $totalXp = 0; protected $xpSeed; @@ -170,139 +169,27 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ public function jump() : void{ parent::jump(); if($this->isSprinting()){ - $this->exhaust(0.8, PlayerExhaustEvent::CAUSE_SPRINT_JUMPING); + $this->hungerManager->exhaust(0.8, PlayerExhaustEvent::CAUSE_SPRINT_JUMPING); }else{ - $this->exhaust(0.2, PlayerExhaustEvent::CAUSE_JUMPING); + $this->hungerManager->exhaust(0.2, PlayerExhaustEvent::CAUSE_JUMPING); } } - public function getFood() : float{ - return $this->attributeMap->getAttribute(Attribute::HUNGER)->getValue(); - } - /** - * WARNING: This method does not check if full and may throw an exception if out of bounds. - * Use {@link Human::addFood()} for this purpose - * - * @param float $new - * - * @throws \InvalidArgumentException + * @return HungerManager */ - public function setFood(float $new) : void{ - $attr = $this->attributeMap->getAttribute(Attribute::HUNGER); - $old = $attr->getValue(); - $attr->setValue($new); - - // ranges: 18-20 (regen), 7-17 (none), 1-6 (no sprint), 0 (health depletion) - foreach([17, 6, 0] as $bound){ - if(($old > $bound) !== ($new > $bound)){ - $this->foodTickTimer = 0; - break; - } - } - } - - public function getMaxFood() : float{ - return $this->attributeMap->getAttribute(Attribute::HUNGER)->getMaxValue(); - } - - public function addFood(float $amount) : void{ - $attr = $this->attributeMap->getAttribute(Attribute::HUNGER); - $amount += $attr->getValue(); - $amount = max(min($amount, $attr->getMaxValue()), $attr->getMinValue()); - $this->setFood($amount); - } - - /** - * Returns whether this Human may consume objects requiring hunger. - * - * @return bool - */ - public function isHungry() : bool{ - return $this->getFood() < $this->getMaxFood(); - } - - public function getSaturation() : float{ - return $this->attributeMap->getAttribute(Attribute::SATURATION)->getValue(); - } - - /** - * WARNING: This method does not check if saturated and may throw an exception if out of bounds. - * Use {@link Human::addSaturation()} for this purpose - * - * @param float $saturation - * - * @throws \InvalidArgumentException - */ - public function setSaturation(float $saturation) : void{ - $this->attributeMap->getAttribute(Attribute::SATURATION)->setValue($saturation); - } - - public function addSaturation(float $amount) : void{ - $attr = $this->attributeMap->getAttribute(Attribute::SATURATION); - $attr->setValue($attr->getValue() + $amount, true); - } - - public function getExhaustion() : float{ - return $this->attributeMap->getAttribute(Attribute::EXHAUSTION)->getValue(); - } - - /** - * WARNING: This method does not check if exhausted and does not consume saturation/food. - * Use {@link Human::exhaust()} for this purpose. - * - * @param float $exhaustion - */ - public function setExhaustion(float $exhaustion) : void{ - $this->attributeMap->getAttribute(Attribute::EXHAUSTION)->setValue($exhaustion); - } - - /** - * Increases a human's exhaustion level. - * - * @param float $amount - * @param int $cause - * - * @return float the amount of exhaustion level increased - */ - public function exhaust(float $amount, int $cause = PlayerExhaustEvent::CAUSE_CUSTOM) : float{ - $ev = new PlayerExhaustEvent($this, $amount, $cause); - $ev->call(); - if($ev->isCancelled()){ - return 0.0; - } - - $exhaustion = $this->getExhaustion(); - $exhaustion += $ev->getAmount(); - - while($exhaustion >= 4.0){ - $exhaustion -= 4.0; - - $saturation = $this->getSaturation(); - if($saturation > 0){ - $saturation = max(0, $saturation - 1.0); - $this->setSaturation($saturation); - }else{ - $food = $this->getFood(); - if($food > 0){ - $food--; - $this->setFood(max($food, 0)); - } - } - } - $this->setExhaustion($exhaustion); - - return $ev->getAmount(); + public function getHungerManager() : HungerManager{ + return $this->hungerManager; } public function consumeObject(Consumable $consumable) : bool{ if($consumable instanceof FoodSource){ - if($consumable->requiresHunger() and !$this->isHungry()){ + if($consumable->requiresHunger() and !$this->hungerManager->isHungry()){ return false; } - $this->addFood($consumable->getFoodRestore()); - $this->addSaturation($consumable->getSaturationRestore()); + $this->hungerManager->addFood($consumable->getFoodRestore()); + $this->hungerManager->addSaturation($consumable->getSaturationRestore()); } return parent::consumeObject($consumable); @@ -587,6 +474,8 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ protected function initEntity(CompoundTag $nbt) : void{ parent::initEntity($nbt); + $this->hungerManager = new HungerManager($this); + $this->setPlayerFlag(PlayerMetadataFlags::SLEEP, false); $this->propertyManager->setBlockPos(EntityMetadataProperties::PLAYER_BED_POSITION, null); @@ -624,10 +513,10 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $this->inventory->setHeldItemIndex($nbt->getInt("SelectedInventorySlot", 0), false); - $this->setFood((float) $nbt->getInt("foodLevel", (int) $this->getFood(), true)); - $this->setExhaustion($nbt->getFloat("foodExhaustionLevel", $this->getExhaustion(), true)); - $this->setSaturation($nbt->getFloat("foodSaturationLevel", $this->getSaturation(), true)); - $this->foodTickTimer = $nbt->getInt("foodTickTimer", $this->foodTickTimer, true); + $this->hungerManager->setFood((float) $nbt->getInt("foodLevel", (int) $this->hungerManager->getFood(), true)); + $this->hungerManager->setExhaustion($nbt->getFloat("foodExhaustionLevel", $this->hungerManager->getExhaustion(), true)); + $this->hungerManager->setSaturation($nbt->getFloat("foodSaturationLevel", $this->hungerManager->getSaturation(), true)); + $this->hungerManager->setFoodTickTimer($nbt->getInt("foodTickTimer", $this->hungerManager->getFoodTickTimer(), true)); $this->setXpLevel($nbt->getInt("XpLevel", $this->getXpLevel(), true)); $this->setXpProgress($nbt->getFloat("XpP", $this->getXpProgress(), true)); @@ -643,9 +532,6 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ protected function addAttributes() : void{ parent::addAttributes(); - $this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::SATURATION)); - $this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::EXHAUSTION)); - $this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::HUNGER)); $this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::EXPERIENCE_LEVEL)); $this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::EXPERIENCE)); } @@ -653,7 +539,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ protected function entityBaseTick(int $tickDiff = 1) : bool{ $hasUpdate = parent::entityBaseTick($tickDiff); - $this->doFoodTick($tickDiff); + $this->hungerManager->tick($tickDiff); if($this->xpCooldown > 0){ $this->xpCooldown--; @@ -662,46 +548,6 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ return $hasUpdate; } - protected function doFoodTick(int $tickDiff = 1) : void{ - if($this->isAlive()){ - $food = $this->getFood(); - $health = $this->getHealth(); - $difficulty = $this->world->getDifficulty(); - - $this->foodTickTimer += $tickDiff; - if($this->foodTickTimer >= 80){ - $this->foodTickTimer = 0; - } - - if($difficulty === World::DIFFICULTY_PEACEFUL and $this->foodTickTimer % 10 === 0){ - if($food < $this->getMaxFood()){ - $this->addFood(1.0); - $food = $this->getFood(); - } - if($this->foodTickTimer % 20 === 0 and $health < $this->getMaxHealth()){ - $this->heal(new EntityRegainHealthEvent($this, 1, EntityRegainHealthEvent::CAUSE_SATURATION)); - } - } - - if($this->foodTickTimer === 0){ - if($food >= 18){ - if($health < $this->getMaxHealth()){ - $this->heal(new EntityRegainHealthEvent($this, 1, EntityRegainHealthEvent::CAUSE_SATURATION)); - $this->exhaust(3.0, PlayerExhaustEvent::CAUSE_HEALTH_REGEN); - } - }elseif($food <= 0){ - if(($difficulty === World::DIFFICULTY_EASY and $health > 10) or ($difficulty === World::DIFFICULTY_NORMAL and $health > 1) or $difficulty === World::DIFFICULTY_HARD){ - $this->attack(new EntityDamageEvent($this, EntityDamageEvent::CAUSE_STARVATION, 1)); - } - } - } - - if($food <= 6){ - $this->setSprinting(false); - } - } - } - public function getName() : string{ return $this->getNameTag(); } @@ -751,10 +597,10 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ public function saveNBT() : CompoundTag{ $nbt = parent::saveNBT(); - $nbt->setInt("foodLevel", (int) $this->getFood()); - $nbt->setFloat("foodExhaustionLevel", $this->getExhaustion()); - $nbt->setFloat("foodSaturationLevel", $this->getSaturation()); - $nbt->setInt("foodTickTimer", $this->foodTickTimer); + $nbt->setInt("foodLevel", (int) $this->hungerManager->getFood()); + $nbt->setFloat("foodExhaustionLevel", $this->hungerManager->getExhaustion()); + $nbt->setFloat("foodSaturationLevel", $this->hungerManager->getSaturation()); + $nbt->setInt("foodTickTimer", $this->hungerManager->getFoodTickTimer()); $nbt->setInt("XpLevel", $this->getXpLevel()); $nbt->setFloat("XpP", $this->getXpProgress()); @@ -855,6 +701,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ protected function destroyCycles() : void{ $this->inventory = null; $this->enderChestInventory = null; + $this->hungerManager = null; parent::destroyCycles(); } diff --git a/src/pocketmine/entity/HungerManager.php b/src/pocketmine/entity/HungerManager.php new file mode 100644 index 0000000000..f13e55afc6 --- /dev/null +++ b/src/pocketmine/entity/HungerManager.php @@ -0,0 +1,254 @@ +entity = $entity; + + $this->hungerAttr = self::fetchAttribute($entity, Attribute::HUNGER); + $this->saturationAttr = self::fetchAttribute($entity, Attribute::SATURATION); + $this->exhaustionAttr = self::fetchAttribute($entity, Attribute::EXHAUSTION); + } + + private static function fetchAttribute(Entity $entity, string $attributeId) : Attribute{ + $entity->getAttributeMap()->addAttribute(Attribute::getAttribute($attributeId)); + return $entity->getAttributeMap()->getAttribute($attributeId); + } + + public function getFood() : float{ + return $this->hungerAttr->getValue(); + } + + /** + * WARNING: This method does not check if full and may throw an exception if out of bounds. + * @see HungerManager::addFood() + * + * @param float $new + * + * @throws \InvalidArgumentException + */ + public function setFood(float $new) : void{ + $old = $this->hungerAttr->getValue(); + $this->hungerAttr->setValue($new); + + // ranges: 18-20 (regen), 7-17 (none), 1-6 (no sprint), 0 (health depletion) + foreach([17, 6, 0] as $bound){ + if(($old > $bound) !== ($new > $bound)){ + $this->foodTickTimer = 0; + break; + } + } + } + + public function getMaxFood() : float{ + return $this->hungerAttr->getMaxValue(); + } + + public function addFood(float $amount) : void{ + $amount += $this->hungerAttr->getValue(); + $amount = max(min($amount, $this->hungerAttr->getMaxValue()), $this->hungerAttr->getMinValue()); + $this->setFood($amount); + } + + /** + * Returns whether this Human may consume objects requiring hunger. + * + * @return bool + */ + public function isHungry() : bool{ + return $this->getFood() < $this->getMaxFood(); + } + + public function getSaturation() : float{ + return $this->saturationAttr->getValue(); + } + + /** + * WARNING: This method does not check if saturated and may throw an exception if out of bounds. + * @see HungerManager::addSaturation() + * + * @param float $saturation + * + * @throws \InvalidArgumentException + */ + public function setSaturation(float $saturation) : void{ + $this->saturationAttr->setValue($saturation); + } + + public function addSaturation(float $amount) : void{ + $this->saturationAttr->setValue($this->saturationAttr->getValue() + $amount, true); + } + + public function getExhaustion() : float{ + return $this->exhaustionAttr->getValue(); + } + + /** + * WARNING: This method does not check if exhausted and does not consume saturation/food. + * @see HungerManager::exhaust() + * + * @param float $exhaustion + */ + public function setExhaustion(float $exhaustion) : void{ + $this->exhaustionAttr->setValue($exhaustion); + } + + /** + * Increases exhaustion level. + * + * @param float $amount + * @param int $cause + * + * @return float the amount of exhaustion level increased + */ + public function exhaust(float $amount, int $cause = PlayerExhaustEvent::CAUSE_CUSTOM) : float{ + if(!$this->enabled){ + return 0; + } + $ev = new PlayerExhaustEvent($this->entity, $amount, $cause); + $ev->call(); + if($ev->isCancelled()){ + return 0.0; + } + + $exhaustion = $this->getExhaustion(); + $exhaustion += $ev->getAmount(); + + while($exhaustion >= 4.0){ + $exhaustion -= 4.0; + + $saturation = $this->getSaturation(); + if($saturation > 0){ + $saturation = max(0, $saturation - 1.0); + $this->setSaturation($saturation); + }else{ + $food = $this->getFood(); + if($food > 0){ + $food--; + $this->setFood(max($food, 0)); + } + } + } + $this->setExhaustion($exhaustion); + + return $ev->getAmount(); + } + + /** + * @return int + */ + public function getFoodTickTimer() : int{ + return $this->foodTickTimer; + } + + /** + * @param int $foodTickTimer + */ + public function setFoodTickTimer(int $foodTickTimer) : void{ + if($foodTickTimer < 0){ + throw new \InvalidArgumentException("Expected a non-negative value"); + } + $this->foodTickTimer = $foodTickTimer; + } + + public function tick(int $tickDiff = 1) : void{ + if(!$this->entity->isAlive() or !$this->enabled){ + return; + } + $food = $this->getFood(); + $health = $this->entity->getHealth(); + $difficulty = $this->entity->getWorld()->getDifficulty(); + + $this->foodTickTimer += $tickDiff; + if($this->foodTickTimer >= 80){ + $this->foodTickTimer = 0; + } + + if($difficulty === World::DIFFICULTY_PEACEFUL and $this->foodTickTimer % 10 === 0){ + if($food < $this->getMaxFood()){ + $this->addFood(1.0); + $food = $this->getFood(); + } + if($this->foodTickTimer % 20 === 0 and $health < $this->entity->getMaxHealth()){ + $this->entity->heal(new EntityRegainHealthEvent($this->entity, 1, EntityRegainHealthEvent::CAUSE_SATURATION)); + } + } + + if($this->foodTickTimer === 0){ + if($food >= 18){ + if($health < $this->entity->getMaxHealth()){ + $this->entity->heal(new EntityRegainHealthEvent($this->entity, 1, EntityRegainHealthEvent::CAUSE_SATURATION)); + $this->exhaust(3.0, PlayerExhaustEvent::CAUSE_HEALTH_REGEN); + } + }elseif($food <= 0){ + if(($difficulty === World::DIFFICULTY_EASY and $health > 10) or ($difficulty === World::DIFFICULTY_NORMAL and $health > 1) or $difficulty === World::DIFFICULTY_HARD){ + $this->entity->attack(new EntityDamageEvent($this->entity, EntityDamageEvent::CAUSE_STARVATION, 1)); + } + } + } + + if($food <= 6){ + $this->entity->setSprinting(false); + } + } + + /** + * @return bool + */ + public function isEnabled() : bool{ + return $this->enabled; + } + + /** + * @param bool $enabled + */ + public function setEnabled(bool $enabled) : void{ + $this->enabled = $enabled; + } +} diff --git a/src/pocketmine/entity/effect/HungerEffect.php b/src/pocketmine/entity/effect/HungerEffect.php index 25599c6b9e..022241be1b 100644 --- a/src/pocketmine/entity/effect/HungerEffect.php +++ b/src/pocketmine/entity/effect/HungerEffect.php @@ -36,7 +36,7 @@ class HungerEffect extends Effect{ public function applyEffect(Living $entity, EffectInstance $instance, float $potency = 1.0, ?Entity $source = null) : void{ if($entity instanceof Human){ - $entity->exhaust(0.025 * $instance->getEffectLevel(), PlayerExhaustEvent::CAUSE_POTION); + $entity->getHungerManager()->exhaust(0.025 * $instance->getEffectLevel(), PlayerExhaustEvent::CAUSE_POTION); } } } diff --git a/src/pocketmine/entity/effect/SaturationEffect.php b/src/pocketmine/entity/effect/SaturationEffect.php index e20eeec83a..638c781306 100644 --- a/src/pocketmine/entity/effect/SaturationEffect.php +++ b/src/pocketmine/entity/effect/SaturationEffect.php @@ -31,8 +31,9 @@ class SaturationEffect extends InstantEffect{ public function applyEffect(Living $entity, EffectInstance $instance, float $potency = 1.0, ?Entity $source = null) : void{ if($entity instanceof Human){ - $entity->addFood($instance->getEffectLevel()); - $entity->addSaturation($instance->getEffectLevel() * 2); + $manager = $entity->getHungerManager(); + $manager->addFood($instance->getEffectLevel()); + $manager->addSaturation($instance->getEffectLevel() * 2); } } } diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index e837ed4214..c85624ae21 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -1198,6 +1198,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->gamemode = $gm; $this->allowFlight = $this->isCreative(); + $this->hungerManager->setEnabled($this->isSurvival()); + if($this->isSpectator()){ $this->setFlying(true); $this->despawnFromAll(); @@ -1414,9 +1416,9 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $distance = sqrt((($from->x - $to->x) ** 2) + (($from->z - $to->z) ** 2)); //TODO: check swimming (adds 0.015 exhaustion in MCPE) if($this->isSprinting()){ - $this->exhaust(0.1 * $distance, PlayerExhaustEvent::CAUSE_SPRINTING); + $this->hungerManager->exhaust(0.1 * $distance, PlayerExhaustEvent::CAUSE_SPRINTING); }else{ - $this->exhaust(0.01 * $distance, PlayerExhaustEvent::CAUSE_WALKING); + $this->hungerManager->exhaust(0.01 * $distance, PlayerExhaustEvent::CAUSE_WALKING); } } } @@ -1510,24 +1512,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return true; } - protected function doFoodTick(int $tickDiff = 1) : void{ - if($this->isSurvival()){ - parent::doFoodTick($tickDiff); - } - } - - public function exhaust(float $amount, int $cause = PlayerExhaustEvent::CAUSE_CUSTOM) : float{ - if($this->isSurvival()){ - return parent::exhaust($amount, $cause); - } - - return 0.0; - } - - public function isHungry() : bool{ - return $this->isSurvival() and parent::isHungry(); - } - public function canBreathe() : bool{ return $this->isCreative() or parent::canBreathe(); } @@ -1828,7 +1812,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($this->hasFiniteResources() and !$item->equalsExact($oldItem)){ $this->inventory->setItemInHand($item); } - $this->exhaust(0.025, PlayerExhaustEvent::CAUSE_MINING); + $this->hungerManager->exhaust(0.025, PlayerExhaustEvent::CAUSE_MINING); return true; } } @@ -1928,7 +1912,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->inventory->setItemInHand($heldItem); } - $this->exhaust(0.3, PlayerExhaustEvent::CAUSE_ATTACK); + $this->hungerManager->exhaust(0.3, PlayerExhaustEvent::CAUSE_ATTACK); } return true; @@ -2431,7 +2415,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, protected function applyPostDamageEffects(EntityDamageEvent $source) : void{ parent::applyPostDamageEffects($source); - $this->exhaust(0.3, PlayerExhaustEvent::CAUSE_DAMAGE); + $this->hungerManager->exhaust(0.3, PlayerExhaustEvent::CAUSE_DAMAGE); } public function attack(EntityDamageEvent $source) : void{ From 5274a0fe3c44bffa6ccc047a6065f14817af8d18 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Jul 2019 19:31:39 +0100 Subject: [PATCH 1066/3224] Extract an ExperienceManager unit from Human --- changelogs/4.0-snapshot.md | 18 + src/pocketmine/entity/ExperienceManager.php | 329 ++++++++++++++++++ src/pocketmine/entity/Human.php | 288 +-------------- .../entity/object/ExperienceOrb.php | 4 +- src/pocketmine/player/Player.php | 2 +- 5 files changed, 366 insertions(+), 275 deletions(-) create mode 100644 src/pocketmine/entity/ExperienceManager.php diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 44282db671..7c3849d681 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -151,6 +151,7 @@ This version features substantial changes to the network system, improving coher - `ItemEntity->getDespawnDelay()` - `ItemEntity->setDespawnDelay()` - `Human->getHungerManager()` + - `Human->getXpManager()` - The following methods have signature changes: - `Entity->entityBaseTick()` is now `protected`. - `Entity->move()` is now `protected`. @@ -159,6 +160,7 @@ This version features substantial changes to the network system, improving coher - The following classes have been added: - `effect\EffectManager`: contains effect-management functionality extracted from `Living` - `HungerManager`: contains hunger-management functionality extracted from `Human` + - `ExperienceManager`: contains XP-management functionality extracted from `Human` - The following API methods have been moved / renamed: - `Living->removeAllEffects()` -> `EffectManager->clear()` - `Living->removeEffect()` -> `EffectManager->remove()` @@ -178,6 +180,22 @@ This version features substantial changes to the network system, improving coher - `Human->getExhaustion()` -> `HungerManager->getExhaustion()` - `Human->setExhaustion()` -> `HungerManager->setExhaustion()` - `Human->exhaust()` -> `HungerManager->exhaust()` + - `Human->getXpLevel()` -> `ExperienceManager->getXpLevel()` + - `Human->setXpLevel()` -> `ExperienceManager->setXpLevel()` + - `Human->addXpLevels()` -> `ExperienceManager->addXpLevels()` + - `Human->subtractXpLevels()` -> `ExperienceManager->subtractXpLevels()` + - `Human->getXpProgress()` -> `ExperienceManager->getXpProgress()` + - `Human->setXpProgress()` -> `ExperienceManager->setXpProgress()` + - `Human->getRemainderXp()` -> `ExperienceManager->getRemainderXp()` + - `Human->getCurrentTotalXp()` -> `ExperienceManager->getCurrentTotalXp()` + - `Human->setCurrentTotalXp()` -> `ExperienceManager->setCurrentTotalXp()` + - `Human->addXp()` -> `ExperienceManager->addXp()` + - `Human->subtractXp()` -> `ExperienceManager->subtractXp()` + - `Human->getLifetimeTotalXp()` -> `ExperienceManager->getLifetimeTotalXp()` + - `Human->setLifetimeTotalXp()` -> `ExperienceManager->setLifetimeTotalXp()` + - `Human->canPickupXp()` -> `ExperienceManager->canPickupXp()` + - `Human->onPickupXp()` -> `ExperienceManager->onPickupXp()` + - `Human->resetXpCooldown()` -> `ExperienceManager->resetXpCooldown()` - The following API methods have been removed: - `Human->getRawUniqueId()`: use `Human->getUniqueId()->toBinary()` instead - The following classes have been removed: diff --git a/src/pocketmine/entity/ExperienceManager.php b/src/pocketmine/entity/ExperienceManager.php new file mode 100644 index 0000000000..9699720479 --- /dev/null +++ b/src/pocketmine/entity/ExperienceManager.php @@ -0,0 +1,329 @@ +entity = $entity; + + $this->levelAttr = self::fetchAttribute($entity, Attribute::EXPERIENCE_LEVEL); + $this->progressAttr = self::fetchAttribute($entity, Attribute::EXPERIENCE); + } + + private static function fetchAttribute(Entity $entity, string $attributeId) : Attribute{ + $entity->getAttributeMap()->addAttribute(Attribute::getAttribute($attributeId)); + return $entity->getAttributeMap()->getAttribute($attributeId); + } + + /** + * Returns the player's experience level. + * @return int + */ + public function getXpLevel() : int{ + return (int) $this->levelAttr->getValue(); + } + + /** + * Sets the player's experience level. This does not affect their total XP or their XP progress. + * + * @param int $level + * + * @return bool + */ + public function setXpLevel(int $level) : bool{ + return $this->setXpAndProgress($level, null); + } + + /** + * Adds a number of XP levels to the player. + * + * @param int $amount + * @param bool $playSound + * + * @return bool + */ + public function addXpLevels(int $amount, bool $playSound = true) : bool{ + $oldLevel = $this->getXpLevel(); + if($this->setXpLevel($oldLevel + $amount)){ + if($playSound){ + $newLevel = $this->getXpLevel(); + if((int) ($newLevel / 5) > (int) ($oldLevel / 5)){ + $this->entity->getWorld()->addSound($this->entity->asVector3(), new XpLevelUpSound($newLevel)); + } + } + + return true; + } + + return false; + } + + /** + * Subtracts a number of XP levels from the player. + * + * @param int $amount + * + * @return bool + */ + public function subtractXpLevels(int $amount) : bool{ + return $this->addXpLevels(-$amount); + } + + /** + * Returns a value between 0.0 and 1.0 to indicate how far through the current level the player is. + * @return float + */ + public function getXpProgress() : float{ + return $this->progressAttr->getValue(); + } + + /** + * Sets the player's progress through the current level to a value between 0.0 and 1.0. + * + * @param float $progress + * + * @return bool + */ + public function setXpProgress(float $progress) : bool{ + return $this->setXpAndProgress(null, $progress); + } + + /** + * Returns the number of XP points the player has progressed into their current level. + * @return int + */ + public function getRemainderXp() : int{ + return (int) (ExperienceUtils::getXpToCompleteLevel($this->getXpLevel()) * $this->getXpProgress()); + } + + /** + * Returns the amount of XP points the player currently has, calculated from their current level and progress + * through their current level. This will be reduced by enchanting deducting levels and is used to calculate the + * amount of XP the player drops on death. + * + * @return int + */ + public function getCurrentTotalXp() : int{ + return ExperienceUtils::getXpToReachLevel($this->getXpLevel()) + $this->getRemainderXp(); + } + + /** + * Sets the current total of XP the player has, recalculating their XP level and progress. + * Note that this DOES NOT update the player's lifetime total XP. + * + * @param int $amount + * + * @return bool + */ + public function setCurrentTotalXp(int $amount) : bool{ + $newLevel = ExperienceUtils::getLevelFromXp($amount); + + return $this->setXpAndProgress((int) $newLevel, $newLevel - ((int) $newLevel)); + } + + /** + * Adds an amount of XP to the player, recalculating their XP level and progress. XP amount will be added to the + * player's lifetime XP. + * + * @param int $amount + * @param bool $playSound Whether to play level-up and XP gained sounds. + * + * @return bool + */ + public function addXp(int $amount, bool $playSound = true) : bool{ + $this->totalXp += $amount; + + $oldLevel = $this->getXpLevel(); + $oldTotal = $this->getCurrentTotalXp(); + + if($this->setCurrentTotalXp($oldTotal + $amount)){ + if($playSound){ + $newLevel = $this->getXpLevel(); + if((int) ($newLevel / 5) > (int) ($oldLevel / 5)){ + $this->entity->getWorld()->addSound($this->entity->asVector3(), new XpLevelUpSound($newLevel)); + }elseif($this->getCurrentTotalXp() > $oldTotal){ + $this->entity->getWorld()->addSound($this->entity->asVector3(), new XpCollectSound()); + } + } + + return true; + } + + return false; + } + + /** + * Takes an amount of XP from the player, recalculating their XP level and progress. + * + * @param int $amount + * + * @return bool + */ + public function subtractXp(int $amount) : bool{ + return $this->addXp(-$amount); + } + + public function setXpAndProgress(?int $level, ?float $progress) : bool{ + $ev = new PlayerExperienceChangeEvent($this->entity, $this->getXpLevel(), $this->getXpProgress(), $level, $progress); + $ev->call(); + + if($ev->isCancelled()){ + return false; + } + + $level = $ev->getNewLevel(); + $progress = $ev->getNewProgress(); + + if($level !== null){ + $this->levelAttr->setValue($level); + } + + if($progress !== null){ + $this->progressAttr->setValue($progress); + } + + return true; + } + + /** + * @internal + * + * @param int $level + * @param float $progress + */ + public function setXpAndProgressNoEvent(int $level, float $progress) : void{ + $this->levelAttr->setValue($level); + $this->progressAttr->setValue($progress); + } + + /** + * Returns the total XP the player has collected in their lifetime. Resets when the player dies. + * XP levels being removed in enchanting do not reduce this number. + * + * @return int + */ + public function getLifetimeTotalXp() : int{ + return $this->totalXp; + } + + /** + * Sets the lifetime total XP of the player. This does not recalculate their level or progress. Used for player + * score when they die. (TODO: add this when MCPE supports it) + * + * @param int $amount + */ + public function setLifetimeTotalXp(int $amount) : void{ + if($amount < 0){ + throw new \InvalidArgumentException("XP must be greater than 0"); + } + + $this->totalXp = $amount; + } + + + /** + * Returns whether the human can pickup XP orbs (checks cooldown time) + * @return bool + */ + public function canPickupXp() : bool{ + return $this->xpCooldown === 0; + } + + public function onPickupXp(int $xpValue) : void{ + static $mainHandIndex = -1; + + //TODO: replace this with a more generic equipment getting/setting interface + /** @var Durable[] $equipment */ + $equipment = []; + + if(($item = $this->entity->getInventory()->getItemInHand()) instanceof Durable and $item->hasEnchantment(Enchantment::MENDING())){ + $equipment[$mainHandIndex] = $item; + } + //TODO: check offhand + foreach($this->entity->getArmorInventory()->getContents() as $k => $item){ + if($item instanceof Durable and $item->hasEnchantment(Enchantment::MENDING())){ + $equipment[$k] = $item; + } + } + + if(!empty($equipment)){ + $repairItem = $equipment[$k = array_rand($equipment)]; + if($repairItem->getDamage() > 0){ + $repairAmount = min($repairItem->getDamage(), $xpValue * 2); + $repairItem->setDamage($repairItem->getDamage() - $repairAmount); + $xpValue -= (int) ceil($repairAmount / 2); + + if($k === $mainHandIndex){ + $this->entity->getInventory()->setItemInHand($repairItem); + }else{ + $this->entity->getArmorInventory()->setItem($k, $repairItem); + } + } + } + + $this->addXp($xpValue); //this will still get fired even if the value is 0 due to mending, to play sounds + $this->resetXpCooldown(); + } + + /** + * Sets the duration in ticks until the human can pick up another XP orb. + * + * @param int $value + */ + public function resetXpCooldown(int $value = 2) : void{ + $this->xpCooldown = $value; + } + + public function tick(int $tickDiff = 1) : void{ + if($this->xpCooldown > 0){ + $this->xpCooldown = max(0, $this->xpCooldown - $tickDiff); + } + } +} diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index fadef01aba..53247f6c5e 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -26,15 +26,12 @@ namespace pocketmine\entity; use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\projectile\ProjectileSource; -use pocketmine\entity\utils\ExperienceUtils; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\player\PlayerExhaustEvent; -use pocketmine\event\player\PlayerExperienceChangeEvent; use pocketmine\inventory\EnderChestInventory; use pocketmine\inventory\InventoryHolder; use pocketmine\inventory\PlayerInventory; use pocketmine\item\Consumable; -use pocketmine\item\Durable; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\FoodSource; use pocketmine\item\Item; @@ -55,14 +52,10 @@ use pocketmine\network\mcpe\protocol\types\PlayerMetadataFlags; use pocketmine\player\Player; use pocketmine\utils\UUID; use pocketmine\world\sound\TotemUseSound; -use pocketmine\world\sound\XpCollectSound; -use pocketmine\world\sound\XpLevelUpSound; use pocketmine\world\World; use function array_filter; use function array_merge; -use function array_rand; use function array_values; -use function ceil; use function in_array; use function min; use function random_int; @@ -90,10 +83,10 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ /** @var HungerManager */ protected $hungerManager; + /** @var ExperienceManager */ + protected $xpManager; - protected $totalXp = 0; protected $xpSeed; - protected $xpCooldown = 0; protected $baseOffset = 1.62; @@ -196,258 +189,16 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ } /** - * Returns the player's experience level. - * @return int + * @return ExperienceManager */ - public function getXpLevel() : int{ - return (int) $this->attributeMap->getAttribute(Attribute::EXPERIENCE_LEVEL)->getValue(); - } - - /** - * Sets the player's experience level. This does not affect their total XP or their XP progress. - * - * @param int $level - * - * @return bool - */ - public function setXpLevel(int $level) : bool{ - return $this->setXpAndProgress($level, null); - } - - /** - * Adds a number of XP levels to the player. - * - * @param int $amount - * @param bool $playSound - * - * @return bool - */ - public function addXpLevels(int $amount, bool $playSound = true) : bool{ - $oldLevel = $this->getXpLevel(); - if($this->setXpLevel($oldLevel + $amount)){ - if($playSound){ - $newLevel = $this->getXpLevel(); - if((int) ($newLevel / 5) > (int) ($oldLevel / 5)){ - $this->world->addSound($this, new XpLevelUpSound($newLevel)); - } - } - - return true; - } - - return false; - } - - /** - * Subtracts a number of XP levels from the player. - * - * @param int $amount - * - * @return bool - */ - public function subtractXpLevels(int $amount) : bool{ - return $this->addXpLevels(-$amount); - } - - /** - * Returns a value between 0.0 and 1.0 to indicate how far through the current level the player is. - * @return float - */ - public function getXpProgress() : float{ - return $this->attributeMap->getAttribute(Attribute::EXPERIENCE)->getValue(); - } - - /** - * Sets the player's progress through the current level to a value between 0.0 and 1.0. - * - * @param float $progress - * - * @return bool - */ - public function setXpProgress(float $progress) : bool{ - return $this->setXpAndProgress(null, $progress); - } - - /** - * Returns the number of XP points the player has progressed into their current level. - * @return int - */ - public function getRemainderXp() : int{ - return (int) (ExperienceUtils::getXpToCompleteLevel($this->getXpLevel()) * $this->getXpProgress()); - } - - /** - * Returns the amount of XP points the player currently has, calculated from their current level and progress - * through their current level. This will be reduced by enchanting deducting levels and is used to calculate the - * amount of XP the player drops on death. - * - * @return int - */ - public function getCurrentTotalXp() : int{ - return ExperienceUtils::getXpToReachLevel($this->getXpLevel()) + $this->getRemainderXp(); - } - - /** - * Sets the current total of XP the player has, recalculating their XP level and progress. - * Note that this DOES NOT update the player's lifetime total XP. - * - * @param int $amount - * - * @return bool - */ - public function setCurrentTotalXp(int $amount) : bool{ - $newLevel = ExperienceUtils::getLevelFromXp($amount); - - return $this->setXpAndProgress((int) $newLevel, $newLevel - ((int) $newLevel)); - } - - /** - * Adds an amount of XP to the player, recalculating their XP level and progress. XP amount will be added to the - * player's lifetime XP. - * - * @param int $amount - * @param bool $playSound Whether to play level-up and XP gained sounds. - * - * @return bool - */ - public function addXp(int $amount, bool $playSound = true) : bool{ - $this->totalXp += $amount; - - $oldLevel = $this->getXpLevel(); - $oldTotal = $this->getCurrentTotalXp(); - - if($this->setCurrentTotalXp($oldTotal + $amount)){ - if($playSound){ - $newLevel = $this->getXpLevel(); - if((int) ($newLevel / 5) > (int) ($oldLevel / 5)){ - $this->world->addSound($this, new XpLevelUpSound($newLevel)); - }elseif($this->getCurrentTotalXp() > $oldTotal){ - $this->world->addSound($this, new XpCollectSound()); - } - } - - return true; - } - - return false; - } - - /** - * Takes an amount of XP from the player, recalculating their XP level and progress. - * - * @param int $amount - * - * @return bool - */ - public function subtractXp(int $amount) : bool{ - return $this->addXp(-$amount); - } - - protected function setXpAndProgress(?int $level, ?float $progress) : bool{ - if(!$this->justCreated){ - $ev = new PlayerExperienceChangeEvent($this, $this->getXpLevel(), $this->getXpProgress(), $level, $progress); - $ev->call(); - - if($ev->isCancelled()){ - return false; - } - - $level = $ev->getNewLevel(); - $progress = $ev->getNewProgress(); - } - - if($level !== null){ - $this->getAttributeMap()->getAttribute(Attribute::EXPERIENCE_LEVEL)->setValue($level); - } - - if($progress !== null){ - $this->getAttributeMap()->getAttribute(Attribute::EXPERIENCE)->setValue($progress); - } - - return true; - } - - /** - * Returns the total XP the player has collected in their lifetime. Resets when the player dies. - * XP levels being removed in enchanting do not reduce this number. - * - * @return int - */ - public function getLifetimeTotalXp() : int{ - return $this->totalXp; - } - - /** - * Sets the lifetime total XP of the player. This does not recalculate their level or progress. Used for player - * score when they die. (TODO: add this when MCPE supports it) - * - * @param int $amount - */ - public function setLifetimeTotalXp(int $amount) : void{ - if($amount < 0){ - throw new \InvalidArgumentException("XP must be greater than 0"); - } - - $this->totalXp = $amount; - } - - /** - * Returns whether the human can pickup XP orbs (checks cooldown time) - * @return bool - */ - public function canPickupXp() : bool{ - return $this->xpCooldown === 0; - } - - public function onPickupXp(int $xpValue) : void{ - static $mainHandIndex = -1; - - //TODO: replace this with a more generic equipment getting/setting interface - /** @var Durable[] $equipment */ - $equipment = []; - - if(($item = $this->inventory->getItemInHand()) instanceof Durable and $item->hasEnchantment(Enchantment::MENDING())){ - $equipment[$mainHandIndex] = $item; - } - //TODO: check offhand - foreach($this->armorInventory->getContents() as $k => $item){ - if($item instanceof Durable and $item->hasEnchantment(Enchantment::MENDING())){ - $equipment[$k] = $item; - } - } - - if(!empty($equipment)){ - $repairItem = $equipment[$k = array_rand($equipment)]; - if($repairItem->getDamage() > 0){ - $repairAmount = min($repairItem->getDamage(), $xpValue * 2); - $repairItem->setDamage($repairItem->getDamage() - $repairAmount); - $xpValue -= (int) ceil($repairAmount / 2); - - if($k === $mainHandIndex){ - $this->inventory->setItemInHand($repairItem); - }else{ - $this->armorInventory->setItem($k, $repairItem); - } - } - } - - $this->addXp($xpValue); //this will still get fired even if the value is 0 due to mending, to play sounds - $this->resetXpCooldown(); - } - - /** - * Sets the duration in ticks until the human can pick up another XP orb. - * - * @param int $value - */ - public function resetXpCooldown(int $value = 2) : void{ - $this->xpCooldown = $value; + public function getXpManager() : ExperienceManager{ + return $this->xpManager; } public function getXpDropAmount() : int{ //this causes some XP to be lost on death when above level 1 (by design), dropping at most enough points for //about 7.5 levels of XP. - return (int) min(100, 7 * $this->getXpLevel()); + return (int) min(100, 7 * $this->xpManager->getXpLevel()); } public function getInventory(){ @@ -475,6 +226,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ parent::initEntity($nbt); $this->hungerManager = new HungerManager($this); + $this->xpManager = new ExperienceManager($this); $this->setPlayerFlag(PlayerMetadataFlags::SLEEP, false); $this->propertyManager->setBlockPos(EntityMetadataProperties::PLAYER_BED_POSITION, null); @@ -518,9 +270,10 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $this->hungerManager->setSaturation($nbt->getFloat("foodSaturationLevel", $this->hungerManager->getSaturation(), true)); $this->hungerManager->setFoodTickTimer($nbt->getInt("foodTickTimer", $this->hungerManager->getFoodTickTimer(), true)); - $this->setXpLevel($nbt->getInt("XpLevel", $this->getXpLevel(), true)); - $this->setXpProgress($nbt->getFloat("XpP", $this->getXpProgress(), true)); - $this->totalXp = $nbt->getInt("XpTotal", $this->totalXp, true); + $this->xpManager->setXpAndProgressNoEvent( + $nbt->getInt("XpLevel", 0, true), + $nbt->getFloat("XpP", 0.0, true)); + $this->xpManager->setLifetimeTotalXp($nbt->getInt("XpTotal", 0, true)); if($nbt->hasTag("XpSeed", IntTag::class)){ $this->xpSeed = $nbt->getInt("XpSeed"); @@ -529,21 +282,11 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ } } - protected function addAttributes() : void{ - parent::addAttributes(); - - $this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::EXPERIENCE_LEVEL)); - $this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::EXPERIENCE)); - } - protected function entityBaseTick(int $tickDiff = 1) : bool{ $hasUpdate = parent::entityBaseTick($tickDiff); $this->hungerManager->tick($tickDiff); - - if($this->xpCooldown > 0){ - $this->xpCooldown--; - } + $this->xpManager->tick($tickDiff); return $hasUpdate; } @@ -602,9 +345,9 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $nbt->setFloat("foodSaturationLevel", $this->hungerManager->getSaturation()); $nbt->setInt("foodTickTimer", $this->hungerManager->getFoodTickTimer()); - $nbt->setInt("XpLevel", $this->getXpLevel()); - $nbt->setFloat("XpP", $this->getXpProgress()); - $nbt->setInt("XpTotal", $this->totalXp); + $nbt->setInt("XpLevel", $this->xpManager->getXpLevel()); + $nbt->setFloat("XpP", $this->xpManager->getXpProgress()); + $nbt->setInt("XpTotal", $this->xpManager->getLifetimeTotalXp()); $nbt->setInt("XpSeed", $this->xpSeed); $inventoryTag = new ListTag([], NBT::TAG_Compound); @@ -702,6 +445,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $this->inventory = null; $this->enderChestInventory = null; $this->hungerManager = null; + $this->xpManager = null; parent::destroyCycles(); } diff --git a/src/pocketmine/entity/object/ExperienceOrb.php b/src/pocketmine/entity/object/ExperienceOrb.php index 17af49d89c..dc04c9392d 100644 --- a/src/pocketmine/entity/object/ExperienceOrb.php +++ b/src/pocketmine/entity/object/ExperienceOrb.php @@ -206,10 +206,10 @@ class ExperienceOrb extends Entity{ $this->motion->z += $diff->z; } - if($currentTarget->canPickupXp() and $this->boundingBox->intersectsWith($currentTarget->getBoundingBox())){ + if($currentTarget->getXpManager()->canPickupXp() and $this->boundingBox->intersectsWith($currentTarget->getBoundingBox())){ $this->flagForDespawn(); - $currentTarget->onPickupXp($this->getXpValue()); + $currentTarget->getXpManager()->onPickupXp($this->getXpValue()); } } diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index c85624ae21..cd1dd4a9ab 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -2363,7 +2363,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $this->world->dropExperience($this, $ev->getXpDropAmount()); - $this->setXpAndProgress(0, 0); + $this->xpManager->setXpAndProgress(0, 0.0); if($ev->getDeathMessage() != ""){ $this->server->broadcastMessage($ev->getDeathMessage()); From cdab3e967a36cb85ef10b91c3a39369e077164d4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Jul 2019 14:37:48 +0100 Subject: [PATCH 1067/3224] Extract a LightArray unit from SubChunk --- src/pocketmine/world/format/Chunk.php | 4 +- src/pocketmine/world/format/EmptySubChunk.php | 12 +-- src/pocketmine/world/format/LightArray.php | 85 +++++++++++++++++++ src/pocketmine/world/format/SubChunk.php | 84 +++++------------- .../world/format/SubChunkInterface.php | 16 ++-- .../world/format/io/FastChunkSerializer.php | 7 +- 6 files changed, 124 insertions(+), 84 deletions(-) create mode 100644 src/pocketmine/world/format/LightArray.php diff --git a/src/pocketmine/world/format/Chunk.php b/src/pocketmine/world/format/Chunk.php index e6b2c2e6c6..a0851eafb5 100644 --- a/src/pocketmine/world/format/Chunk.php +++ b/src/pocketmine/world/format/Chunk.php @@ -224,7 +224,7 @@ class Chunk{ $char = chr(($level & 0x0f) | ($level << 4)); $data = str_repeat($char, 2048); for($y = $this->getHighestSubChunkIndex(); $y >= 0; --$y){ - $this->getSubChunk($y, true)->setBlockSkyLightArray($data); + $this->getSubChunk($y, true)->setBlockSkyLightArray(new LightArray($data)); } } @@ -260,7 +260,7 @@ class Chunk{ $char = chr(($level & 0x0f) | ($level << 4)); $data = str_repeat($char, 2048); for($y = $this->getHighestSubChunkIndex(); $y >= 0; --$y){ - $this->getSubChunk($y, true)->setBlockLightArray($data); + $this->getSubChunk($y, true)->setBlockLightArray(new LightArray($data)); } } diff --git a/src/pocketmine/world/format/EmptySubChunk.php b/src/pocketmine/world/format/EmptySubChunk.php index 8606f1d390..7cc607e871 100644 --- a/src/pocketmine/world/format/EmptySubChunk.php +++ b/src/pocketmine/world/format/EmptySubChunk.php @@ -73,19 +73,19 @@ class EmptySubChunk implements SubChunkInterface{ return -1; } - public function getBlockLightArray() : string{ - return str_repeat("\x00", 2048); + public function getBlockLightArray() : LightArray{ + return new LightArray(str_repeat("\x00", 2048)); } - public function setBlockLightArray(string $data) : void{ + public function setBlockLightArray(LightArray $data) : void{ } - public function getBlockSkyLightArray() : string{ - return str_repeat("\xff", 2048); + public function getBlockSkyLightArray() : LightArray{ + return new LightArray(str_repeat("\xff", 2048)); } - public function setBlockSkyLightArray(string $data) : void{ + public function setBlockSkyLightArray(LightArray $data) : void{ } } diff --git a/src/pocketmine/world/format/LightArray.php b/src/pocketmine/world/format/LightArray.php new file mode 100644 index 0000000000..8822ddc12f --- /dev/null +++ b/src/pocketmine/world/format/LightArray.php @@ -0,0 +1,85 @@ +data = $payload ?? self::ZERO; + $this->collectGarbage(); + } + + public function get(int $x, int $y, int $z) : int{ + return (ord($this->data{($x << 7) | ($z << 3) | ($y >> 1)}) >> (($y & 1) << 2)) & 0xf; + } + + public function set(int $x, int $y, int $z, int $level) : void{ + $i = ($x << 7) | ($z << 3) | ($y >> 1); + + $shift = ($y & 1) << 2; + $byte = ord($this->data{$i}); + $this->data{$i} = chr(($byte & ~(0xf << $shift)) | (($level & 0xf) << $shift)); + } + + public function collectGarbage() : void{ + /* + * This strange looking code is designed to exploit PHP's copy-on-write behaviour. Assigning will copy a + * reference to the const instead of duplicating the whole string. The string will only be duplicated when + * modified, which is perfect for this purpose. + */ + if($this->data === ZERO_NIBBLE_ARRAY){ + $this->data = ZERO_NIBBLE_ARRAY; + }elseif($this->data === FIFTEEN_NIBBLE_ARRAY){ + $this->data = FIFTEEN_NIBBLE_ARRAY; + } + } + + public function getData() : string{ + return $this->data; + } +} diff --git a/src/pocketmine/world/format/SubChunk.php b/src/pocketmine/world/format/SubChunk.php index e9c132145f..19021fd77f 100644 --- a/src/pocketmine/world/format/SubChunk.php +++ b/src/pocketmine/world/format/SubChunk.php @@ -25,53 +25,28 @@ namespace pocketmine\world\format; use pocketmine\block\BlockLegacyIds; use function array_values; -use function assert; -use function chr; -use function define; -use function defined; -use function ord; -use function str_repeat; -use function strlen; - -if(!defined(__NAMESPACE__ . '\ZERO_NIBBLE_ARRAY')){ - define(__NAMESPACE__ . '\ZERO_NIBBLE_ARRAY', str_repeat("\x00", 2048)); -} -if(!defined(__NAMESPACE__ . '\FIFTEEN_NIBBLE_ARRAY')){ - define(__NAMESPACE__ . '\FIFTEEN_NIBBLE_ARRAY', str_repeat("\xff", 2048)); -} class SubChunk implements SubChunkInterface{ /** @var PalettedBlockArray[] */ private $blockLayers; - /** @var string */ + /** @var LightArray */ protected $blockLight; - /** @var string */ + /** @var LightArray */ protected $skyLight; - private static function assignData(&$target, string $data, string $default) : void{ - if($data === "" or $data === $default){ - $target = $default; - }elseif(strlen($data) !== 2048){ - assert(false, "Invalid length given, expected 2048, got " . strlen($data)); - $target = $default; - }else{ - $target = $data; - } - } - /** * SubChunk constructor. * * @param PalettedBlockArray[] $blocks - * @param string $skyLight - * @param string $blockLight + * @param LightArray|null $skyLight + * @param LightArray|null $blockLight */ - public function __construct(array $blocks, string $skyLight = "", string $blockLight = ""){ + public function __construct(array $blocks, ?LightArray $skyLight = null, ?LightArray $blockLight = null){ $this->blockLayers = $blocks; - self::assignData($this->skyLight, $skyLight, FIFTEEN_NIBBLE_ARRAY); - self::assignData($this->blockLight, $blockLight, ZERO_NIBBLE_ARRAY); + $this->skyLight = $skyLight ?? new LightArray(LightArray::FIFTEEN); + $this->blockLight = $blockLight ?? new LightArray(LightArray::ZERO); } public function isEmpty(bool $checkLight = true) : bool{ @@ -85,8 +60,8 @@ class SubChunk implements SubChunkInterface{ } return (!$checkLight or ( - $this->skyLight === FIFTEEN_NIBBLE_ARRAY and - $this->blockLight === ZERO_NIBBLE_ARRAY + $this->skyLight->getData() === LightArray::FIFTEEN and + $this->blockLight->getData() === LightArray::ZERO ) ); } @@ -113,29 +88,21 @@ class SubChunk implements SubChunkInterface{ } public function getBlockLight(int $x, int $y, int $z) : int{ - return (ord($this->blockLight{($x << 7) | ($z << 3) | ($y >> 1)}) >> (($y & 1) << 2)) & 0xf; + return $this->blockLight->get($x, $y, $z); } public function setBlockLight(int $x, int $y, int $z, int $level) : bool{ - $i = ($x << 7) | ($z << 3) | ($y >> 1); - - $shift = ($y & 1) << 2; - $byte = ord($this->blockLight{$i}); - $this->blockLight{$i} = chr(($byte & ~(0xf << $shift)) | (($level & 0xf) << $shift)); + $this->blockLight->set($x, $y, $z, $level); return true; } public function getBlockSkyLight(int $x, int $y, int $z) : int{ - return (ord($this->skyLight{($x << 7) | ($z << 3) | ($y >> 1)}) >> (($y & 1) << 2)) & 0xf; + return $this->skyLight->get($x, $y, $z); } public function setBlockSkyLight(int $x, int $y, int $z, int $level) : bool{ - $i = ($x << 7) | ($z << 3) | ($y >> 1); - - $shift = ($y & 1) << 2; - $byte = ord($this->skyLight{$i}); - $this->skyLight{$i} = chr(($byte & ~(0xf << $shift)) | (($level & 0xf) << $shift)); + $this->skyLight->set($x, $y, $z, $level); return true; } @@ -153,23 +120,19 @@ class SubChunk implements SubChunkInterface{ return -1; //highest block not in this subchunk } - public function getBlockSkyLightArray() : string{ - assert(strlen($this->skyLight) === 2048, "Wrong length of skylight array, expecting 2048 bytes, got " . strlen($this->skyLight)); + public function getBlockSkyLightArray() : LightArray{ return $this->skyLight; } - public function setBlockSkyLightArray(string $data) : void{ - assert(strlen($data) === 2048, "Wrong length of skylight array, expecting 2048 bytes, got " . strlen($data)); + public function setBlockSkyLightArray(LightArray $data) : void{ $this->skyLight = $data; } - public function getBlockLightArray() : string{ - assert(strlen($this->blockLight) === 2048, "Wrong length of light array, expecting 2048 bytes, got " . strlen($this->blockLight)); + public function getBlockLightArray() : LightArray{ return $this->blockLight; } - public function setBlockLightArray(string $data) : void{ - assert(strlen($data) === 2048, "Wrong length of light array, expecting 2048 bytes, got " . strlen($data)); + public function setBlockLightArray(LightArray $data) : void{ $this->blockLight = $data; } @@ -190,16 +153,7 @@ class SubChunk implements SubChunkInterface{ } $this->blockLayers = array_values($this->blockLayers); - /* - * This strange looking code is designed to exploit PHP's copy-on-write behaviour. Assigning will copy a - * reference to the const instead of duplicating the whole string. The string will only be duplicated when - * modified, which is perfect for this purpose. - */ - if($this->skyLight === ZERO_NIBBLE_ARRAY){ - $this->skyLight = ZERO_NIBBLE_ARRAY; - } - if($this->blockLight === ZERO_NIBBLE_ARRAY){ - $this->blockLight = ZERO_NIBBLE_ARRAY; - } + $this->skyLight->collectGarbage(); + $this->blockLight->collectGarbage(); } } diff --git a/src/pocketmine/world/format/SubChunkInterface.php b/src/pocketmine/world/format/SubChunkInterface.php index fff078c9b0..bb7c5f01d2 100644 --- a/src/pocketmine/world/format/SubChunkInterface.php +++ b/src/pocketmine/world/format/SubChunkInterface.php @@ -101,22 +101,22 @@ interface SubChunkInterface{ public function getHighestBlockAt(int $x, int $z) : int; /** - * @return string + * @return LightArray */ - public function getBlockSkyLightArray() : string; + public function getBlockSkyLightArray() : LightArray; /** - * @param string $data + * @param LightArray $data */ - public function setBlockSkyLightArray(string $data) : void; + public function setBlockSkyLightArray(LightArray $data) : void; /** - * @return string + * @return LightArray */ - public function getBlockLightArray() : string; + public function getBlockLightArray() : LightArray; /** - * @param string $data + * @param LightArray $data */ - public function setBlockLightArray(string $data) : void; + public function setBlockLightArray(LightArray $data) : void; } diff --git a/src/pocketmine/world/format/io/FastChunkSerializer.php b/src/pocketmine/world/format/io/FastChunkSerializer.php index 670d26afc4..a4ab01c5c3 100644 --- a/src/pocketmine/world/format/io/FastChunkSerializer.php +++ b/src/pocketmine/world/format/io/FastChunkSerializer.php @@ -26,6 +26,7 @@ namespace pocketmine\world\format\io; use pocketmine\utils\BinaryStream; use pocketmine\world\format\Chunk; use pocketmine\world\format\EmptySubChunk; +use pocketmine\world\format\LightArray; use pocketmine\world\format\PalettedBlockArray; use pocketmine\world\format\SubChunk; use function array_values; @@ -82,8 +83,8 @@ final class FastChunkSerializer{ } if($chunk->isLightPopulated()){ - $subStream->put($subChunk->getBlockSkyLightArray()); - $subStream->put($subChunk->getBlockLightArray()); + $subStream->put($subChunk->getBlockSkyLightArray()->getData()); + $subStream->put($subChunk->getBlockLightArray()->getData()); } } $stream->putByte($count); @@ -134,7 +135,7 @@ final class FastChunkSerializer{ $layers[] = PalettedBlockArray::fromData($bitsPerBlock, $words, $palette); } $subChunks[$y] = new SubChunk( - $layers, $lightPopulated ? $stream->get(2048) : "", $lightPopulated ? $stream->get(2048) : "" //blocklight + $layers, $lightPopulated ? new LightArray($stream->get(2048)) : null, $lightPopulated ? new LightArray($stream->get(2048)) : null ); } From 4e2f430f060f98affdd556ed521f3c64cf210119 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Jul 2019 14:53:19 +0100 Subject: [PATCH 1068/3224] shift default left instead of set value right don't remove metadata bits for block comparison, because they could be part of the ID. --- src/pocketmine/world/format/SubChunk.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/world/format/SubChunk.php b/src/pocketmine/world/format/SubChunk.php index 19021fd77f..c84976bf30 100644 --- a/src/pocketmine/world/format/SubChunk.php +++ b/src/pocketmine/world/format/SubChunk.php @@ -53,7 +53,7 @@ class SubChunk implements SubChunkInterface{ foreach($this->blockLayers as $layer){ $palette = $layer->getPalette(); foreach($palette as $p){ - if(($p >> 4) !== BlockLegacyIds::AIR){ + if($p !== (BlockLegacyIds::AIR << 4)){ return false; } } @@ -112,7 +112,7 @@ class SubChunk implements SubChunkInterface{ return -1; } for($y = 15; $y >= 0; --$y){ - if(($this->blockLayers[0]->get($x, $y, $z) >> 4) !== BlockLegacyIds::AIR){ + if($this->blockLayers[0]->get($x, $y, $z) !== (BlockLegacyIds::AIR << 4)){ return $y; } } @@ -145,7 +145,7 @@ class SubChunk implements SubChunkInterface{ $layer->collectGarbage(); foreach($layer->getPalette() as $p){ - if(($p >> 4) !== BlockLegacyIds::AIR){ + if($p !== (BlockLegacyIds::AIR << 4)){ continue 2; } } From 007aee72f848df4a064e9b72e236f1b483c40463 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Jul 2019 15:01:11 +0100 Subject: [PATCH 1069/3224] SubChunk: remove BlockLegacyIds dependency, allow parameterising default block --- src/pocketmine/world/format/Chunk.php | 2 +- src/pocketmine/world/format/SubChunk.php | 17 ++++++++++------- .../world/format/io/FastChunkSerializer.php | 3 ++- .../world/format/io/leveldb/LevelDB.php | 8 ++++---- src/pocketmine/world/format/io/region/Anvil.php | 3 ++- .../world/format/io/region/McRegion.php | 3 ++- .../world/format/io/region/PMAnvil.php | 3 ++- 7 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/pocketmine/world/format/Chunk.php b/src/pocketmine/world/format/Chunk.php index a0851eafb5..cf76026cf7 100644 --- a/src/pocketmine/world/format/Chunk.php +++ b/src/pocketmine/world/format/Chunk.php @@ -644,7 +644,7 @@ class Chunk{ if($y < 0 or $y >= $this->height){ return $this->emptySubChunk; }elseif($generateNew and $this->subChunks[$y] instanceof EmptySubChunk){ - $this->subChunks[$y] = new SubChunk([new PalettedBlockArray(BlockLegacyIds::AIR << 4)]); + $this->subChunks[$y] = new SubChunk(BlockLegacyIds::AIR << 4, []); } return $this->subChunks[$y]; diff --git a/src/pocketmine/world/format/SubChunk.php b/src/pocketmine/world/format/SubChunk.php index c84976bf30..dd7f228f1b 100644 --- a/src/pocketmine/world/format/SubChunk.php +++ b/src/pocketmine/world/format/SubChunk.php @@ -23,10 +23,11 @@ declare(strict_types=1); namespace pocketmine\world\format; -use pocketmine\block\BlockLegacyIds; use function array_values; class SubChunk implements SubChunkInterface{ + /** @var int */ + private $defaultBlock; /** @var PalettedBlockArray[] */ private $blockLayers; @@ -38,11 +39,13 @@ class SubChunk implements SubChunkInterface{ /** * SubChunk constructor. * + * @param int $default * @param PalettedBlockArray[] $blocks * @param LightArray|null $skyLight * @param LightArray|null $blockLight */ - public function __construct(array $blocks, ?LightArray $skyLight = null, ?LightArray $blockLight = null){ + public function __construct(int $default, array $blocks, ?LightArray $skyLight = null, ?LightArray $blockLight = null){ + $this->defaultBlock = $default; $this->blockLayers = $blocks; $this->skyLight = $skyLight ?? new LightArray(LightArray::FIFTEEN); @@ -53,7 +56,7 @@ class SubChunk implements SubChunkInterface{ foreach($this->blockLayers as $layer){ $palette = $layer->getPalette(); foreach($palette as $p){ - if($p !== (BlockLegacyIds::AIR << 4)){ + if($p !== $this->defaultBlock){ return false; } } @@ -68,14 +71,14 @@ class SubChunk implements SubChunkInterface{ public function getFullBlock(int $x, int $y, int $z) : int{ if(empty($this->blockLayers)){ - return BlockLegacyIds::AIR << 4; + return $this->defaultBlock; } return $this->blockLayers[0]->get($x, $y, $z); } public function setFullBlock(int $x, int $y, int $z, int $block) : void{ if(empty($this->blockLayers)){ - $this->blockLayers[] = new PalettedBlockArray(BlockLegacyIds::AIR << 4); + $this->blockLayers[] = new PalettedBlockArray($this->defaultBlock); } $this->blockLayers[0]->set($x, $y, $z, $block); } @@ -112,7 +115,7 @@ class SubChunk implements SubChunkInterface{ return -1; } for($y = 15; $y >= 0; --$y){ - if($this->blockLayers[0]->get($x, $y, $z) !== (BlockLegacyIds::AIR << 4)){ + if($this->blockLayers[0]->get($x, $y, $z) !== $this->defaultBlock){ return $y; } } @@ -145,7 +148,7 @@ class SubChunk implements SubChunkInterface{ $layer->collectGarbage(); foreach($layer->getPalette() as $p){ - if($p !== (BlockLegacyIds::AIR << 4)){ + if($p !== $this->defaultBlock){ continue 2; } } diff --git a/src/pocketmine/world/format/io/FastChunkSerializer.php b/src/pocketmine/world/format/io/FastChunkSerializer.php index a4ab01c5c3..20490c4def 100644 --- a/src/pocketmine/world/format/io/FastChunkSerializer.php +++ b/src/pocketmine/world/format/io/FastChunkSerializer.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\format\io; +use pocketmine\block\BlockLegacyIds; use pocketmine\utils\BinaryStream; use pocketmine\world\format\Chunk; use pocketmine\world\format\EmptySubChunk; @@ -135,7 +136,7 @@ final class FastChunkSerializer{ $layers[] = PalettedBlockArray::fromData($bitsPerBlock, $words, $palette); } $subChunks[$y] = new SubChunk( - $layers, $lightPopulated ? new LightArray($stream->get(2048)) : null, $lightPopulated ? new LightArray($stream->get(2048)) : null + BlockLegacyIds::AIR << 4, $layers, $lightPopulated ? new LightArray($stream->get(2048)) : null, $lightPopulated ? new LightArray($stream->get(2048)) : null ); } diff --git a/src/pocketmine/world/format/io/leveldb/LevelDB.php b/src/pocketmine/world/format/io/leveldb/LevelDB.php index c608e19e1b..9b9e0a06f6 100644 --- a/src/pocketmine/world/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/world/format/io/leveldb/LevelDB.php @@ -303,14 +303,14 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $storages[] = $convertedLegacyExtraData[$y]; } - $subChunks[$y] = new SubChunk($storages); + $subChunks[$y] = new SubChunk(BlockLegacyIds::AIR << 4, $storages); break; case 1: //paletted v1, has a single blockstorage $storages = [$this->deserializePaletted($binaryStream)]; if(isset($convertedLegacyExtraData[$y])){ $storages[] = $convertedLegacyExtraData[$y]; } - $subChunks[$y] = new SubChunk($storages); + $subChunks[$y] = new SubChunk(BlockLegacyIds::AIR << 4, $storages); break; case 8: //legacy extradata layers intentionally ignored because they aren't supposed to exist in v8 @@ -321,7 +321,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ for($k = 0; $k < $storageCount; ++$k){ $storages[] = $this->deserializePaletted($binaryStream); } - $subChunks[$y] = new SubChunk($storages); + $subChunks[$y] = new SubChunk(BlockLegacyIds::AIR << 4, $storages); } break; default: @@ -365,7 +365,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ if(isset($convertedLegacyExtraData[$yy])){ $storages[] = $convertedLegacyExtraData[$yy]; } - $subChunks[$yy] = new SubChunk($storages); + $subChunks[$yy] = new SubChunk(BlockLegacyIds::AIR << 4, $storages); } try{ diff --git a/src/pocketmine/world/format/io/region/Anvil.php b/src/pocketmine/world/format/io/region/Anvil.php index e66e2a3452..1bd9450f81 100644 --- a/src/pocketmine/world/format/io/region/Anvil.php +++ b/src/pocketmine/world/format/io/region/Anvil.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\format\io\region; +use pocketmine\block\BlockLegacyIds; use pocketmine\nbt\tag\CompoundTag; use pocketmine\world\format\io\SubChunkConverter; use pocketmine\world\format\SubChunk; @@ -35,7 +36,7 @@ class Anvil extends RegionWorldProvider{ } protected function deserializeSubChunk(CompoundTag $subChunk) : SubChunk{ - return new SubChunk([SubChunkConverter::convertSubChunkYZX($subChunk->getByteArray("Blocks"), $subChunk->getByteArray("Data"))]); + return new SubChunk(BlockLegacyIds::AIR << 4, [SubChunkConverter::convertSubChunkYZX($subChunk->getByteArray("Blocks"), $subChunk->getByteArray("Data"))]); //ignore legacy light information } diff --git a/src/pocketmine/world/format/io/region/McRegion.php b/src/pocketmine/world/format/io/region/McRegion.php index 46e2b9f387..a695a3372c 100644 --- a/src/pocketmine/world/format/io/region/McRegion.php +++ b/src/pocketmine/world/format/io/region/McRegion.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\format\io\region; +use pocketmine\block\BlockLegacyIds; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\ByteArrayTag; @@ -71,7 +72,7 @@ class McRegion extends RegionWorldProvider{ $fullData = $chunk->hasTag("Data", ByteArrayTag::class) ? $chunk->getByteArray("Data") : str_repeat("\x00", 16384); for($y = 0; $y < 8; ++$y){ - $subChunks[$y] = new SubChunk([SubChunkConverter::convertSubChunkFromLegacyColumn($fullIds, $fullData, $y)]); + $subChunks[$y] = new SubChunk(BlockLegacyIds::AIR << 4, [SubChunkConverter::convertSubChunkFromLegacyColumn($fullIds, $fullData, $y)]); } if($chunk->hasTag("BiomeColors", IntArrayTag::class)){ diff --git a/src/pocketmine/world/format/io/region/PMAnvil.php b/src/pocketmine/world/format/io/region/PMAnvil.php index 3842dff7d3..557026a9d3 100644 --- a/src/pocketmine/world/format/io/region/PMAnvil.php +++ b/src/pocketmine/world/format/io/region/PMAnvil.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\format\io\region; +use pocketmine\block\BlockLegacyIds; use pocketmine\nbt\tag\CompoundTag; use pocketmine\world\format\io\SubChunkConverter; use pocketmine\world\format\SubChunk; @@ -35,7 +36,7 @@ class PMAnvil extends RegionWorldProvider{ use LegacyAnvilChunkTrait; protected function deserializeSubChunk(CompoundTag $subChunk) : SubChunk{ - return new SubChunk([SubChunkConverter::convertSubChunkXZY($subChunk->getByteArray("Blocks"), $subChunk->getByteArray("Data"))]); + return new SubChunk(BlockLegacyIds::AIR << 4, [SubChunkConverter::convertSubChunkXZY($subChunk->getByteArray("Blocks"), $subChunk->getByteArray("Data"))]); } protected static function getRegionFileExtension() : string{ From c42817f02f6c55cc2c5e418955b8da5f7f950321 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Jul 2019 15:39:57 +0100 Subject: [PATCH 1070/3224] optimizing lighting performance a little --- .../world/light/BlockLightUpdate.php | 9 ++----- src/pocketmine/world/light/LightUpdate.php | 25 +++++++++++-------- src/pocketmine/world/light/SkyLightUpdate.php | 9 ++----- .../world/utils/SubChunkIteratorManager.php | 13 ++++++++++ 4 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/pocketmine/world/light/BlockLightUpdate.php b/src/pocketmine/world/light/BlockLightUpdate.php index 1fbaf04c37..9be3d6a370 100644 --- a/src/pocketmine/world/light/BlockLightUpdate.php +++ b/src/pocketmine/world/light/BlockLightUpdate.php @@ -27,13 +27,8 @@ use pocketmine\block\BlockFactory; use function max; class BlockLightUpdate extends LightUpdate{ - - public function getLight(int $x, int $y, int $z) : int{ - return $this->subChunkHandler->currentSubChunk->getBlockLight($x & 0x0f, $y & 0x0f, $z & 0x0f); - } - - public function setLight(int $x, int $y, int $z, int $level) : void{ - $this->subChunkHandler->currentSubChunk->setBlockLight($x & 0x0f, $y & 0x0f, $z & 0x0f, $level); + protected function updateLightArrayRef() : void{ + $this->currentLightArray = $this->subChunkHandler->currentSubChunk->getBlockLightArray(); } public function recalculateNode(int $x, int $y, int $z) : void{ diff --git a/src/pocketmine/world/light/LightUpdate.php b/src/pocketmine/world/light/LightUpdate.php index cc3bee6afd..26b0e86692 100644 --- a/src/pocketmine/world/light/LightUpdate.php +++ b/src/pocketmine/world/light/LightUpdate.php @@ -25,6 +25,7 @@ namespace pocketmine\world\light; use pocketmine\block\BlockFactory; use pocketmine\world\ChunkManager; +use pocketmine\world\format\LightArray; use pocketmine\world\utils\SubChunkIteratorManager; use pocketmine\world\World; use function max; @@ -50,17 +51,19 @@ abstract class LightUpdate{ /** @var SubChunkIteratorManager */ protected $subChunkHandler; + /** @var LightArray|null */ + protected $currentLightArray = null; + public function __construct(ChunkManager $world){ $this->world = $world; $this->removalQueue = new \SplQueue(); $this->spreadQueue = new \SplQueue(); $this->subChunkHandler = new SubChunkIteratorManager($this->world); + $this->subChunkHandler->onSubChunkChange(\Closure::fromCallable([$this, 'updateLightArrayRef'])); } - abstract protected function getLight(int $x, int $y, int $z) : int; - - abstract protected function setLight(int $x, int $y, int $z, int $level) : void; + abstract protected function updateLightArrayRef() : void; abstract public function recalculateNode(int $x, int $y, int $z) : void; @@ -74,7 +77,7 @@ abstract class LightUpdate{ [$x, $y, $z + 1], [$x, $y, $z - 1] ] as [$x1, $y1, $z1]){ - if($this->subChunkHandler->moveTo($x1, $y1, $z1, false) and ($adjacent = max($adjacent, $this->getLight($x1, $y1, $z1))) === 15){ + if($this->subChunkHandler->moveTo($x1, $y1, $z1, false) and ($adjacent = max($adjacent, $this->currentLightArray->get($x1 & 0xf, $y1 & 0xf, $z1 & 0xf))) === 15){ break; } } @@ -88,10 +91,10 @@ abstract class LightUpdate{ private function prepareNodes() : void{ foreach($this->updateNodes as $blockHash => [$x, $y, $z, $newLevel]){ if($this->subChunkHandler->moveTo($x, $y, $z, false)){ - $oldLevel = $this->getLight($x, $y, $z); + $oldLevel = $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); if($oldLevel !== $newLevel){ - $this->setLight($x, $y, $z, $newLevel); + $this->currentLightArray->set($x & 0xf, $y & 0xf, $z & 0xf, $newLevel); if($oldLevel < $newLevel){ //light increased $this->spreadVisited[$blockHash] = true; $this->spreadQueue->enqueue([$x, $y, $z]); @@ -135,7 +138,7 @@ abstract class LightUpdate{ continue; } - $newAdjacentLight = $this->getLight($x, $y, $z); + $newAdjacentLight = $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); if($newAdjacentLight <= 0){ continue; } @@ -158,10 +161,10 @@ abstract class LightUpdate{ } protected function computeRemoveLight(int $x, int $y, int $z, int $oldAdjacentLevel) : void{ - $current = $this->getLight($x, $y, $z); + $current = $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); if($current !== 0 and $current < $oldAdjacentLevel){ - $this->setLight($x, $y, $z, 0); + $this->currentLightArray->set($x & 0xf, $y & 0xf, $z & 0xf, 0); if(!isset($this->removalVisited[$index = World::blockHash($x, $y, $z)])){ $this->removalVisited[$index] = true; @@ -178,11 +181,11 @@ abstract class LightUpdate{ } protected function computeSpreadLight(int $x, int $y, int $z, int $newAdjacentLevel) : void{ - $current = $this->getLight($x, $y, $z); + $current = $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); $potentialLight = $newAdjacentLevel - BlockFactory::$lightFilter[$this->subChunkHandler->currentSubChunk->getFullBlock($x & 0x0f, $y & 0x0f, $z & 0x0f)]; if($current < $potentialLight){ - $this->setLight($x, $y, $z, $potentialLight); + $this->currentLightArray->set($x & 0xf, $y & 0xf, $z & 0xf, $potentialLight); if(!isset($this->spreadVisited[$index = World::blockHash($x, $y, $z)]) and $potentialLight > 1){ $this->spreadVisited[$index] = true; diff --git a/src/pocketmine/world/light/SkyLightUpdate.php b/src/pocketmine/world/light/SkyLightUpdate.php index 8374c862d8..59ab9e98c4 100644 --- a/src/pocketmine/world/light/SkyLightUpdate.php +++ b/src/pocketmine/world/light/SkyLightUpdate.php @@ -27,13 +27,8 @@ use pocketmine\block\BlockFactory; use function max; class SkyLightUpdate extends LightUpdate{ - - public function getLight(int $x, int $y, int $z) : int{ - return $this->subChunkHandler->currentSubChunk->getBlockSkyLight($x & 0x0f, $y & 0x0f, $z & 0x0f); - } - - public function setLight(int $x, int $y, int $z, int $level) : void{ - $this->subChunkHandler->currentSubChunk->setBlockSkyLight($x & 0x0f, $y & 0x0f, $z & 0x0f, $level); + protected function updateLightArrayRef() : void{ + $this->currentLightArray = $this->subChunkHandler->currentSubChunk->getBlockSkyLightArray(); } public function recalculateNode(int $x, int $y, int $z) : void{ diff --git a/src/pocketmine/world/utils/SubChunkIteratorManager.php b/src/pocketmine/world/utils/SubChunkIteratorManager.php index 55e8bbf7d0..e328445537 100644 --- a/src/pocketmine/world/utils/SubChunkIteratorManager.php +++ b/src/pocketmine/world/utils/SubChunkIteratorManager.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\utils; +use pocketmine\utils\Utils; use pocketmine\world\ChunkManager; use pocketmine\world\format\Chunk; use pocketmine\world\format\EmptySubChunk; @@ -44,6 +45,9 @@ class SubChunkIteratorManager{ /** @var int */ protected $currentZ; + /** @var \Closure|null */ + private $onSubChunkChangeFunc = null; + public function __construct(ChunkManager $world){ $this->world = $world; } @@ -65,13 +69,22 @@ class SubChunkIteratorManager{ $this->currentSubChunk = $this->currentChunk->getSubChunk($y >> 4, $create); if($this->currentSubChunk instanceof EmptySubChunk){ + $this->currentSubChunk = null; return false; } + if($this->onSubChunkChangeFunc !== null){ + ($this->onSubChunkChangeFunc)(); + } } return true; } + public function onSubChunkChange(\Closure $callback) : void{ + Utils::validateCallableSignature(function(){}, $callback); + $this->onSubChunkChangeFunc = $callback; + } + public function invalidate() : void{ $this->currentChunk = null; $this->currentSubChunk = null; From fe3a4baddb9a9aa8fbb11adc421eee444333a931 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Jul 2019 18:08:52 +0100 Subject: [PATCH 1071/3224] added StairShape enum this has no practical value to plugins yet, but it will in the future. --- src/pocketmine/block/Stair.php | 30 ++++++------- src/pocketmine/block/utils/StairShape.php | 51 +++++++++++++++++++++++ 2 files changed, 67 insertions(+), 14 deletions(-) create mode 100644 src/pocketmine/block/utils/StairShape.php diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index 892c730457..7b84afbc6a 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\StairShape; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -32,18 +33,19 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Stair extends Transparent{ - private const SHAPE_STRAIGHT = "straight"; - private const SHAPE_INNER_LEFT = "inner_left"; - private const SHAPE_INNER_RIGHT = "inner_right"; - private const SHAPE_OUTER_LEFT = "outer_left"; - private const SHAPE_OUTER_RIGHT = "outer_right"; /** @var int */ protected $facing = Facing::NORTH; /** @var bool */ protected $upsideDown = false; - /** @var string */ - protected $shape = self::SHAPE_STRAIGHT; + + /** @var StairShape */ + protected $shape; + + public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ + $this->shape = StairShape::STRAIGHT(); + parent::__construct($idInfo, $name, $breakInfo); + } protected function writeStateToMeta() : int{ return (5 - $this->facing) | ($this->upsideDown ? BlockLegacyMetadata::STAIR_FLAG_UPSIDE_DOWN : 0); @@ -63,11 +65,11 @@ class Stair extends Transparent{ $clockwise = Facing::rotateY($this->facing, true); if(($backFacing = $this->getPossibleCornerFacing(false)) !== null){ - $this->shape = $backFacing === $clockwise ? self::SHAPE_OUTER_RIGHT : self::SHAPE_OUTER_LEFT; + $this->shape = $backFacing === $clockwise ? StairShape::OUTER_RIGHT() : StairShape::OUTER_LEFT(); }elseif(($frontFacing = $this->getPossibleCornerFacing(true)) !== null){ - $this->shape = $frontFacing === $clockwise ? self::SHAPE_INNER_RIGHT : self::SHAPE_INNER_LEFT; + $this->shape = $frontFacing === $clockwise ? StairShape::INNER_RIGHT() : StairShape::INNER_LEFT(); }else{ - $this->shape = self::SHAPE_STRAIGHT; + $this->shape = StairShape::STRAIGHT(); } } @@ -81,14 +83,14 @@ class Stair extends Transparent{ ->trim(Facing::opposite($topStepFace), 0.5) ->trim(Facing::opposite($this->facing), 0.5); - if($this->shape === self::SHAPE_OUTER_LEFT or $this->shape === self::SHAPE_OUTER_RIGHT){ - $topStep->trim(Facing::rotateY($this->facing, $this->shape === self::SHAPE_OUTER_LEFT), 0.5); - }elseif($this->shape === self::SHAPE_INNER_LEFT or $this->shape === self::SHAPE_INNER_RIGHT){ + if($this->shape->equals(StairShape::OUTER_LEFT()) or $this->shape->equals(StairShape::OUTER_RIGHT())){ + $topStep->trim(Facing::rotateY($this->facing, $this->shape->equals(StairShape::OUTER_LEFT())), 0.5); + }elseif($this->shape->equals(StairShape::INNER_LEFT()) or $this->shape->equals(StairShape::INNER_RIGHT())){ //add an extra cube $bbs[] = AxisAlignedBB::one() ->trim(Facing::opposite($topStepFace), 0.5) ->trim($this->facing, 0.5) //avoid overlapping with main step - ->trim(Facing::rotateY($this->facing, $this->shape === self::SHAPE_INNER_LEFT), 0.5); + ->trim(Facing::rotateY($this->facing, $this->shape->equals(StairShape::INNER_LEFT())), 0.5); } $bbs[] = $topStep; diff --git a/src/pocketmine/block/utils/StairShape.php b/src/pocketmine/block/utils/StairShape.php new file mode 100644 index 0000000000..89f4c544a8 --- /dev/null +++ b/src/pocketmine/block/utils/StairShape.php @@ -0,0 +1,51 @@ + Date: Mon, 8 Jul 2019 18:29:19 +0100 Subject: [PATCH 1072/3224] generator: prevent access to chunks that don't exist on this thread the generator shouldn't be creating chunks that it wasn't given. --- .../world/generator/GeneratorChunkManager.php | 38 +++++++++++++++++++ .../world/generator/GeneratorRegisterTask.php | 3 +- 2 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 src/pocketmine/world/generator/GeneratorChunkManager.php diff --git a/src/pocketmine/world/generator/GeneratorChunkManager.php b/src/pocketmine/world/generator/GeneratorChunkManager.php new file mode 100644 index 0000000000..312bf182e0 --- /dev/null +++ b/src/pocketmine/world/generator/GeneratorChunkManager.php @@ -0,0 +1,38 @@ +chunks[World::chunkHash($chunkX, $chunkZ)])){ + throw new \InvalidArgumentException("Chunk does not exist"); + } + return parent::getChunk($chunkX, $chunkZ, $create); + } +} diff --git a/src/pocketmine/world/generator/GeneratorRegisterTask.php b/src/pocketmine/world/generator/GeneratorRegisterTask.php index 8dd110c66e..4904ca0386 100644 --- a/src/pocketmine/world/generator/GeneratorRegisterTask.php +++ b/src/pocketmine/world/generator/GeneratorRegisterTask.php @@ -26,7 +26,6 @@ namespace pocketmine\world\generator; use pocketmine\block\BlockFactory; use pocketmine\scheduler\AsyncTask; use pocketmine\world\biome\Biome; -use pocketmine\world\SimpleChunkManager; use pocketmine\world\World; use function serialize; use function unserialize; @@ -50,7 +49,7 @@ class GeneratorRegisterTask extends AsyncTask{ public function onRun() : void{ BlockFactory::init(); Biome::init(); - $manager = new SimpleChunkManager($this->worldHeight); + $manager = new GeneratorChunkManager($this->worldHeight); $this->worker->saveToThreadStore("generation.world{$this->worldId}.manager", $manager); /** From c1212eab8ec2a916f284fbda4e07f57c0c7f6a36 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 9 Jul 2019 13:38:26 +0100 Subject: [PATCH 1073/3224] EmptySubChunk: get rid of useless allocations --- src/pocketmine/world/format/EmptySubChunk.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/world/format/EmptySubChunk.php b/src/pocketmine/world/format/EmptySubChunk.php index 7cc607e871..2d5962b2c0 100644 --- a/src/pocketmine/world/format/EmptySubChunk.php +++ b/src/pocketmine/world/format/EmptySubChunk.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\world\format; -use function str_repeat; - class EmptySubChunk implements SubChunkInterface{ /** @var EmptySubChunk */ private static $instance; @@ -74,7 +72,7 @@ class EmptySubChunk implements SubChunkInterface{ } public function getBlockLightArray() : LightArray{ - return new LightArray(str_repeat("\x00", 2048)); + return new LightArray(LightArray::ZERO); } public function setBlockLightArray(LightArray $data) : void{ @@ -82,7 +80,7 @@ class EmptySubChunk implements SubChunkInterface{ } public function getBlockSkyLightArray() : LightArray{ - return new LightArray(str_repeat("\xff", 2048)); + return new LightArray(LightArray::FIFTEEN); } public function setBlockSkyLightArray(LightArray $data) : void{ From 4264923f4f72ec591464e3ed36665f4a431f6f67 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 9 Jul 2019 13:43:01 +0100 Subject: [PATCH 1074/3224] SubChunk: get rid of dead light getters and setters these were here for fast access, but that fast access path now goes through getBlock(Sky)LightArray() instead. --- src/pocketmine/world/format/Chunk.php | 8 ++-- src/pocketmine/world/format/EmptySubChunk.php | 16 -------- src/pocketmine/world/format/SubChunk.php | 20 ---------- .../world/format/SubChunkInterface.php | 38 ------------------- 4 files changed, 4 insertions(+), 78 deletions(-) diff --git a/src/pocketmine/world/format/Chunk.php b/src/pocketmine/world/format/Chunk.php index cf76026cf7..2c7b345407 100644 --- a/src/pocketmine/world/format/Chunk.php +++ b/src/pocketmine/world/format/Chunk.php @@ -202,7 +202,7 @@ class Chunk{ * @return int 0-15 */ public function getBlockSkyLight(int $x, int $y, int $z) : int{ - return $this->getSubChunk($y >> 4)->getBlockSkyLight($x, $y & 0x0f, $z); + return $this->getSubChunk($y >> 4)->getBlockSkyLightArray()->get($x & 0xf, $y & 0x0f, $z & 0xf); } /** @@ -214,7 +214,7 @@ class Chunk{ * @param int $level 0-15 */ public function setBlockSkyLight(int $x, int $y, int $z, int $level) : void{ - $this->getSubChunk($y >> 4, true)->setBlockSkyLight($x, $y & 0x0f, $z, $level); + $this->getSubChunk($y >> 4, true)->getBlockSkyLightArray()->set($x & 0xf, $y & 0x0f, $z & 0xf, $level); } /** @@ -238,7 +238,7 @@ class Chunk{ * @return int 0-15 */ public function getBlockLight(int $x, int $y, int $z) : int{ - return $this->getSubChunk($y >> 4)->getBlockLight($x, $y & 0x0f, $z); + return $this->getSubChunk($y >> 4)->getBlockLightArray()->get($x & 0xf, $y & 0x0f, $z & 0xf); } /** @@ -250,7 +250,7 @@ class Chunk{ * @param int $level 0-15 */ public function setBlockLight(int $x, int $y, int $z, int $level) : void{ - $this->getSubChunk($y >> 4, true)->setBlockLight($x, $y & 0x0f, $z, $level); + $this->getSubChunk($y >> 4, true)->getBlockLightArray()->set($x & 0xf, $y & 0x0f, $z & 0xf, $level); } /** diff --git a/src/pocketmine/world/format/EmptySubChunk.php b/src/pocketmine/world/format/EmptySubChunk.php index 2d5962b2c0..dae6048387 100644 --- a/src/pocketmine/world/format/EmptySubChunk.php +++ b/src/pocketmine/world/format/EmptySubChunk.php @@ -51,22 +51,6 @@ class EmptySubChunk implements SubChunkInterface{ return []; } - public function getBlockLight(int $x, int $y, int $z) : int{ - return 0; - } - - public function setBlockLight(int $x, int $y, int $z, int $level) : bool{ - return false; - } - - public function getBlockSkyLight(int $x, int $y, int $z) : int{ - return 15; - } - - public function setBlockSkyLight(int $x, int $y, int $z, int $level) : bool{ - return false; - } - public function getHighestBlockAt(int $x, int $z) : int{ return -1; } diff --git a/src/pocketmine/world/format/SubChunk.php b/src/pocketmine/world/format/SubChunk.php index dd7f228f1b..2f003ec8c0 100644 --- a/src/pocketmine/world/format/SubChunk.php +++ b/src/pocketmine/world/format/SubChunk.php @@ -90,26 +90,6 @@ class SubChunk implements SubChunkInterface{ return $this->blockLayers; } - public function getBlockLight(int $x, int $y, int $z) : int{ - return $this->blockLight->get($x, $y, $z); - } - - public function setBlockLight(int $x, int $y, int $z, int $level) : bool{ - $this->blockLight->set($x, $y, $z, $level); - - return true; - } - - public function getBlockSkyLight(int $x, int $y, int $z) : int{ - return $this->skyLight->get($x, $y, $z); - } - - public function setBlockSkyLight(int $x, int $y, int $z, int $level) : bool{ - $this->skyLight->set($x, $y, $z, $level); - - return true; - } - public function getHighestBlockAt(int $x, int $z) : int{ if(empty($this->blockLayers)){ return -1; diff --git a/src/pocketmine/world/format/SubChunkInterface.php b/src/pocketmine/world/format/SubChunkInterface.php index bb7c5f01d2..236a50aeb1 100644 --- a/src/pocketmine/world/format/SubChunkInterface.php +++ b/src/pocketmine/world/format/SubChunkInterface.php @@ -54,44 +54,6 @@ interface SubChunkInterface{ */ public function getBlockLayers() : array; - /** - * @param int $x - * @param int $y - * @param int $z - * - * @return int - */ - public function getBlockLight(int $x, int $y, int $z) : int; - - /** - * @param int $x - * @param int $y - * @param int $z - * @param int $level - * - * @return bool - */ - public function setBlockLight(int $x, int $y, int $z, int $level) : bool; - - /** - * @param int $x - * @param int $y - * @param int $z - * - * @return int - */ - public function getBlockSkyLight(int $x, int $y, int $z) : int; - - /** - * @param int $x - * @param int $y - * @param int $z - * @param int $level - * - * @return bool - */ - public function setBlockSkyLight(int $x, int $y, int $z, int $level) : bool; - /** * @param int $x * @param int $z From 5a2e84eb9f96b417a6775c96bc400cd9b21fdd75 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 9 Jul 2019 13:47:53 +0100 Subject: [PATCH 1075/3224] LightArray: added fill(), remove duplicated code --- src/pocketmine/world/format/Chunk.php | 8 ++------ src/pocketmine/world/format/LightArray.php | 10 ++++++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/world/format/Chunk.php b/src/pocketmine/world/format/Chunk.php index 2c7b345407..4973e98663 100644 --- a/src/pocketmine/world/format/Chunk.php +++ b/src/pocketmine/world/format/Chunk.php @@ -221,10 +221,8 @@ class Chunk{ * @param int $level */ public function setAllBlockSkyLight(int $level) : void{ - $char = chr(($level & 0x0f) | ($level << 4)); - $data = str_repeat($char, 2048); for($y = $this->getHighestSubChunkIndex(); $y >= 0; --$y){ - $this->getSubChunk($y, true)->setBlockSkyLightArray(new LightArray($data)); + $this->getSubChunk($y, true)->setBlockSkyLightArray(LightArray::fill($level)); } } @@ -257,10 +255,8 @@ class Chunk{ * @param int $level */ public function setAllBlockLight(int $level) : void{ - $char = chr(($level & 0x0f) | ($level << 4)); - $data = str_repeat($char, 2048); for($y = $this->getHighestSubChunkIndex(); $y >= 0; --$y){ - $this->getSubChunk($y, true)->setBlockLightArray(new LightArray($data)); + $this->getSubChunk($y, true)->setBlockLightArray(LightArray::fill($level)); } } diff --git a/src/pocketmine/world/format/LightArray.php b/src/pocketmine/world/format/LightArray.php index 8822ddc12f..dd3f1d7a05 100644 --- a/src/pocketmine/world/format/LightArray.php +++ b/src/pocketmine/world/format/LightArray.php @@ -54,6 +54,16 @@ final class LightArray{ $this->collectGarbage(); } + public static function fill(int $level) : self{ + if($level === 0){ + return new self(self::ZERO); + } + if($level === 15){ + return new self(self::FIFTEEN); + } + return new self(str_repeat(chr(($level & 0x0f) | ($level << 4)), 2048)); + } + public function get(int $x, int $y, int $z) : int{ return (ord($this->data{($x << 7) | ($z << 3) | ($y >> 1)}) >> (($y & 1) << 2)) & 0xf; } From 5f959a148f0260172e7a7e6717a06e1b7dec3f4e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 9 Jul 2019 14:44:01 +0100 Subject: [PATCH 1076/3224] chunkutils: remove dead legacy code --- src/pocketmine/world/format/io/ChunkUtils.php | 95 +++---------------- 1 file changed, 14 insertions(+), 81 deletions(-) diff --git a/src/pocketmine/world/format/io/ChunkUtils.php b/src/pocketmine/world/format/io/ChunkUtils.php index 2eb0d2ff13..27cd2b75e3 100644 --- a/src/pocketmine/world/format/io/ChunkUtils.php +++ b/src/pocketmine/world/format/io/ChunkUtils.php @@ -24,90 +24,23 @@ declare(strict_types=1); namespace pocketmine\world\format\io; use function chr; -use function extension_loaded; -use function ord; use function str_repeat; -if(!extension_loaded('pocketmine_chunkutils')){ - class ChunkUtils{ +class ChunkUtils{ - /** - * Re-orders a byte array (YZX -> XZY and vice versa) - * - * @param string $array length 4096 - * - * @return string length 4096 - */ - final public static function reorderByteArray(string $array) : string{ - $result = str_repeat("\x00", 4096); - if($array !== $result){ - $i = 0; - for($x = 0; $x < 16; ++$x){ - $zM = $x + 256; - for($z = $x; $z < $zM; $z += 16){ - $yM = $z + 4096; - for($y = $z; $y < $yM; $y += 256){ - $result{$i} = $array{$y}; - ++$i; - } - } - } - } - - return $result; + /** + * Converts pre-MCPE-1.0 biome color array to biome ID array. + * + * @param int[] $array of biome color values + * + * @return string + */ + public static function convertBiomeColors(array $array) : string{ + $result = str_repeat("\x00", 256); + foreach($array as $i => $color){ + $result{$i} = chr(($color >> 24) & 0xff); } - - /** - * Re-orders a nibble array (YZX -> XZY and vice versa) - * - * @param string $array length 2048 - * @param string $commonValue length 1 common value to fill the default array with and to expect, may improve sort time - * - * @return string length 2048 - */ - final public static function reorderNibbleArray(string $array, string $commonValue = "\x00") : string{ - $result = str_repeat($commonValue, 2048); - - if($array !== $result){ - $i = 0; - for($x = 0; $x < 8; ++$x){ - for($z = 0; $z < 16; ++$z){ - $zx = (($z << 3) | $x); - for($y = 0; $y < 8; ++$y){ - $j = (($y << 8) | $zx); - $j80 = ($j | 0x80); - if($array{$j} === $commonValue and $array{$j80} === $commonValue){ - //values are already filled - }else{ - $i1 = ord($array{$j}); - $i2 = ord($array{$j80}); - $result{$i} = chr(($i2 << 4) | ($i1 & 0x0f)); - $result{$i | 0x80} = chr(($i1 >> 4) | ($i2 & 0xf0)); - } - $i++; - } - } - $i += 128; - } - } - - return $result; - } - - /** - * Converts pre-MCPE-1.0 biome color array to biome ID array. - * - * @param int[] $array of biome color values - * - * @return string - */ - public static function convertBiomeColors(array $array) : string{ - $result = str_repeat("\x00", 256); - foreach($array as $i => $color){ - $result{$i} = chr(($color >> 24) & 0xff); - } - return $result; - } - + return $result; } + } From b6efb33b91bdf99e4e9bbe2e0d4fd8c49605c703 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 9 Jul 2019 17:33:00 +0100 Subject: [PATCH 1077/3224] improved VanillaBlocks registry --- src/pocketmine/block/VanillaBlocks.php | 3815 ++++++++---------------- src/pocketmine/utils/EnumTrait.php | 98 +- src/pocketmine/utils/RegistryTrait.php | 168 ++ 3 files changed, 1479 insertions(+), 2602 deletions(-) create mode 100644 src/pocketmine/utils/RegistryTrait.php diff --git a/src/pocketmine/block/VanillaBlocks.php b/src/pocketmine/block/VanillaBlocks.php index 930fd6c586..fa1d662095 100644 --- a/src/pocketmine/block/VanillaBlocks.php +++ b/src/pocketmine/block/VanillaBlocks.php @@ -23,2534 +23,1307 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\utils\RegistryTrait; +use function array_map; +use function assert; + /** - * This class provides a nice type-safe way to access vanilla blocks. - * The entire class is auto-generated based on the current contents of the block factory. - * Do not modify this class manually. + * This doc-block is generated automatically, do not modify it manually. + * This must be regenerated whenever registry members are added, removed or changed. + * @see RegistryTrait::_generateMethodAnnotations() + * + * @method static WoodenButton ACACIA_BUTTON() + * @method static WoodenDoor ACACIA_DOOR() + * @method static WoodenFence ACACIA_FENCE() + * @method static FenceGate ACACIA_FENCE_GATE() + * @method static Leaves ACACIA_LEAVES() + * @method static Log ACACIA_LOG() + * @method static Planks ACACIA_PLANKS() + * @method static WoodenPressurePlate ACACIA_PRESSURE_PLATE() + * @method static Sapling ACACIA_SAPLING() + * @method static Sign ACACIA_SIGN() + * @method static WoodenSlab ACACIA_SLAB() + * @method static WoodenStairs ACACIA_STAIRS() + * @method static WoodenTrapdoor ACACIA_TRAPDOOR() + * @method static Wood ACACIA_WOOD() + * @method static ActivatorRail ACTIVATOR_RAIL() + * @method static Air AIR() + * @method static Flower ALLIUM() + * @method static Solid ANDESITE() + * @method static Slab ANDESITE_SLAB() + * @method static Stair ANDESITE_STAIRS() + * @method static Wall ANDESITE_WALL() + * @method static Anvil ANVIL() + * @method static Flower AZURE_BLUET() + * @method static Banner BANNER() + * @method static Transparent BARRIER() + * @method static Bed BED() + * @method static Bedrock BEDROCK() + * @method static Beetroot BEETROOTS() + * @method static WoodenButton BIRCH_BUTTON() + * @method static WoodenDoor BIRCH_DOOR() + * @method static WoodenFence BIRCH_FENCE() + * @method static FenceGate BIRCH_FENCE_GATE() + * @method static Leaves BIRCH_LEAVES() + * @method static Log BIRCH_LOG() + * @method static Planks BIRCH_PLANKS() + * @method static WoodenPressurePlate BIRCH_PRESSURE_PLATE() + * @method static Sapling BIRCH_SAPLING() + * @method static Sign BIRCH_SIGN() + * @method static WoodenSlab BIRCH_SLAB() + * @method static WoodenStairs BIRCH_STAIRS() + * @method static WoodenTrapdoor BIRCH_TRAPDOOR() + * @method static Wood BIRCH_WOOD() + * @method static Carpet BLACK_CARPET() + * @method static Concrete BLACK_CONCRETE() + * @method static ConcretePowder BLACK_CONCRETE_POWDER() + * @method static GlazedTerracotta BLACK_GLAZED_TERRACOTTA() + * @method static HardenedClay BLACK_STAINED_CLAY() + * @method static Glass BLACK_STAINED_GLASS() + * @method static GlassPane BLACK_STAINED_GLASS_PANE() + * @method static Wool BLACK_WOOL() + * @method static Carpet BLUE_CARPET() + * @method static Concrete BLUE_CONCRETE() + * @method static ConcretePowder BLUE_CONCRETE_POWDER() + * @method static GlazedTerracotta BLUE_GLAZED_TERRACOTTA() + * @method static BlueIce BLUE_ICE() + * @method static Flower BLUE_ORCHID() + * @method static HardenedClay BLUE_STAINED_CLAY() + * @method static Glass BLUE_STAINED_GLASS() + * @method static GlassPane BLUE_STAINED_GLASS_PANE() + * @method static Torch BLUE_TORCH() + * @method static Wool BLUE_WOOL() + * @method static BoneBlock BONE_BLOCK() + * @method static Bookshelf BOOKSHELF() + * @method static BrewingStand BREWING_STAND() + * @method static Slab BRICK_SLAB() + * @method static Stair BRICK_STAIRS() + * @method static Wall BRICK_WALL() + * @method static Solid BRICKS() + * @method static Carpet BROWN_CARPET() + * @method static Concrete BROWN_CONCRETE() + * @method static ConcretePowder BROWN_CONCRETE_POWDER() + * @method static GlazedTerracotta BROWN_GLAZED_TERRACOTTA() + * @method static BrownMushroom BROWN_MUSHROOM() + * @method static BrownMushroomBlock BROWN_MUSHROOM_BLOCK() + * @method static HardenedClay BROWN_STAINED_CLAY() + * @method static Glass BROWN_STAINED_GLASS() + * @method static GlassPane BROWN_STAINED_GLASS_PANE() + * @method static Wool BROWN_WOOL() + * @method static Cactus CACTUS() + * @method static Cake CAKE() + * @method static Carrot CARROTS() + * @method static Chest CHEST() + * @method static Solid CHISELED_QUARTZ() + * @method static Solid CHISELED_RED_SANDSTONE() + * @method static Solid CHISELED_SANDSTONE() + * @method static Solid CHISELED_STONE_BRICKS() + * @method static Clay CLAY() + * @method static Coal COAL() + * @method static CoalOre COAL_ORE() + * @method static CoarseDirt COARSE_DIRT() + * @method static Solid COBBLESTONE() + * @method static Slab COBBLESTONE_SLAB() + * @method static Stair COBBLESTONE_STAIRS() + * @method static Wall COBBLESTONE_WALL() + * @method static Cobweb COBWEB() + * @method static CocoaBlock COCOA_POD() + * @method static Flower CORNFLOWER() + * @method static Solid CRACKED_STONE_BRICKS() + * @method static CraftingTable CRAFTING_TABLE() + * @method static Solid CUT_RED_SANDSTONE() + * @method static Slab CUT_RED_SANDSTONE_SLAB() + * @method static Solid CUT_SANDSTONE() + * @method static Slab CUT_SANDSTONE_SLAB() + * @method static Carpet CYAN_CARPET() + * @method static Concrete CYAN_CONCRETE() + * @method static ConcretePowder CYAN_CONCRETE_POWDER() + * @method static GlazedTerracotta CYAN_GLAZED_TERRACOTTA() + * @method static HardenedClay CYAN_STAINED_CLAY() + * @method static Glass CYAN_STAINED_GLASS() + * @method static GlassPane CYAN_STAINED_GLASS_PANE() + * @method static Wool CYAN_WOOL() + * @method static Flower DANDELION() + * @method static WoodenButton DARK_OAK_BUTTON() + * @method static WoodenDoor DARK_OAK_DOOR() + * @method static WoodenFence DARK_OAK_FENCE() + * @method static FenceGate DARK_OAK_FENCE_GATE() + * @method static Leaves DARK_OAK_LEAVES() + * @method static Log DARK_OAK_LOG() + * @method static Planks DARK_OAK_PLANKS() + * @method static WoodenPressurePlate DARK_OAK_PRESSURE_PLATE() + * @method static Sapling DARK_OAK_SAPLING() + * @method static Sign DARK_OAK_SIGN() + * @method static WoodenSlab DARK_OAK_SLAB() + * @method static WoodenStairs DARK_OAK_STAIRS() + * @method static WoodenTrapdoor DARK_OAK_TRAPDOOR() + * @method static Wood DARK_OAK_WOOD() + * @method static Solid DARK_PRISMARINE() + * @method static Slab DARK_PRISMARINE_SLAB() + * @method static Stair DARK_PRISMARINE_STAIRS() + * @method static DaylightSensor DAYLIGHT_SENSOR() + * @method static DeadBush DEAD_BUSH() + * @method static DetectorRail DETECTOR_RAIL() + * @method static Solid DIAMOND() + * @method static DiamondOre DIAMOND_ORE() + * @method static Solid DIORITE() + * @method static Slab DIORITE_SLAB() + * @method static Stair DIORITE_STAIRS() + * @method static Wall DIORITE_WALL() + * @method static Dirt DIRT() + * @method static DoubleTallGrass DOUBLE_TALLGRASS() + * @method static DragonEgg DRAGON_EGG() + * @method static DriedKelp DRIED_KELP() + * @method static Element ELEMENT_ACTINIUM() + * @method static Element ELEMENT_ALUMINUM() + * @method static Element ELEMENT_AMERICIUM() + * @method static Element ELEMENT_ANTIMONY() + * @method static Element ELEMENT_ARGON() + * @method static Element ELEMENT_ARSENIC() + * @method static Element ELEMENT_ASTATINE() + * @method static Element ELEMENT_BARIUM() + * @method static Element ELEMENT_BERKELIUM() + * @method static Element ELEMENT_BERYLLIUM() + * @method static Element ELEMENT_BISMUTH() + * @method static Element ELEMENT_BOHRIUM() + * @method static Element ELEMENT_BORON() + * @method static Element ELEMENT_BROMINE() + * @method static Element ELEMENT_CADMIUM() + * @method static Element ELEMENT_CALCIUM() + * @method static Element ELEMENT_CALIFORNIUM() + * @method static Element ELEMENT_CARBON() + * @method static Element ELEMENT_CERIUM() + * @method static Element ELEMENT_CESIUM() + * @method static Element ELEMENT_CHLORINE() + * @method static Element ELEMENT_CHROMIUM() + * @method static Element ELEMENT_COBALT() + * @method static Element ELEMENT_COPERNICIUM() + * @method static Element ELEMENT_COPPER() + * @method static Element ELEMENT_CURIUM() + * @method static Element ELEMENT_DARMSTADTIUM() + * @method static Element ELEMENT_DUBNIUM() + * @method static Element ELEMENT_DYSPROSIUM() + * @method static Element ELEMENT_EINSTEINIUM() + * @method static Element ELEMENT_ERBIUM() + * @method static Element ELEMENT_EUROPIUM() + * @method static Element ELEMENT_FERMIUM() + * @method static Element ELEMENT_FLEROVIUM() + * @method static Element ELEMENT_FLUORINE() + * @method static Element ELEMENT_FRANCIUM() + * @method static Element ELEMENT_GADOLINIUM() + * @method static Element ELEMENT_GALLIUM() + * @method static Element ELEMENT_GERMANIUM() + * @method static Element ELEMENT_GOLD() + * @method static Element ELEMENT_HAFNIUM() + * @method static Element ELEMENT_HASSIUM() + * @method static Element ELEMENT_HELIUM() + * @method static Element ELEMENT_HOLMIUM() + * @method static Element ELEMENT_HYDROGEN() + * @method static Element ELEMENT_INDIUM() + * @method static Element ELEMENT_IODINE() + * @method static Element ELEMENT_IRIDIUM() + * @method static Element ELEMENT_IRON() + * @method static Element ELEMENT_KRYPTON() + * @method static Element ELEMENT_LANTHANUM() + * @method static Element ELEMENT_LAWRENCIUM() + * @method static Element ELEMENT_LEAD() + * @method static Element ELEMENT_LITHIUM() + * @method static Element ELEMENT_LIVERMORIUM() + * @method static Element ELEMENT_LUTETIUM() + * @method static Element ELEMENT_MAGNESIUM() + * @method static Element ELEMENT_MANGANESE() + * @method static Element ELEMENT_MEITNERIUM() + * @method static Element ELEMENT_MENDELEVIUM() + * @method static Element ELEMENT_MERCURY() + * @method static Element ELEMENT_MOLYBDENUM() + * @method static Element ELEMENT_MOSCOVIUM() + * @method static Element ELEMENT_NEODYMIUM() + * @method static Element ELEMENT_NEON() + * @method static Element ELEMENT_NEPTUNIUM() + * @method static Element ELEMENT_NICKEL() + * @method static Element ELEMENT_NIHONIUM() + * @method static Element ELEMENT_NIOBIUM() + * @method static Element ELEMENT_NITROGEN() + * @method static Element ELEMENT_NOBELIUM() + * @method static Element ELEMENT_OGANESSON() + * @method static Element ELEMENT_OSMIUM() + * @method static Element ELEMENT_OXYGEN() + * @method static Element ELEMENT_PALLADIUM() + * @method static Element ELEMENT_PHOSPHORUS() + * @method static Element ELEMENT_PLATINUM() + * @method static Element ELEMENT_PLUTONIUM() + * @method static Element ELEMENT_POLONIUM() + * @method static Element ELEMENT_POTASSIUM() + * @method static Element ELEMENT_PRASEODYMIUM() + * @method static Element ELEMENT_PROMETHIUM() + * @method static Element ELEMENT_PROTACTINIUM() + * @method static Element ELEMENT_RADIUM() + * @method static Element ELEMENT_RADON() + * @method static Element ELEMENT_RHENIUM() + * @method static Element ELEMENT_RHODIUM() + * @method static Element ELEMENT_ROENTGENIUM() + * @method static Element ELEMENT_RUBIDIUM() + * @method static Element ELEMENT_RUTHENIUM() + * @method static Element ELEMENT_RUTHERFORDIUM() + * @method static Element ELEMENT_SAMARIUM() + * @method static Element ELEMENT_SCANDIUM() + * @method static Element ELEMENT_SEABORGIUM() + * @method static Element ELEMENT_SELENIUM() + * @method static Element ELEMENT_SILICON() + * @method static Element ELEMENT_SILVER() + * @method static Element ELEMENT_SODIUM() + * @method static Element ELEMENT_STRONTIUM() + * @method static Element ELEMENT_SULFUR() + * @method static Element ELEMENT_TANTALUM() + * @method static Element ELEMENT_TECHNETIUM() + * @method static Element ELEMENT_TELLURIUM() + * @method static Element ELEMENT_TENNESSINE() + * @method static Element ELEMENT_TERBIUM() + * @method static Element ELEMENT_THALLIUM() + * @method static Element ELEMENT_THORIUM() + * @method static Element ELEMENT_THULIUM() + * @method static Element ELEMENT_TIN() + * @method static Element ELEMENT_TITANIUM() + * @method static Element ELEMENT_TUNGSTEN() + * @method static Element ELEMENT_URANIUM() + * @method static Element ELEMENT_VANADIUM() + * @method static Element ELEMENT_XENON() + * @method static Element ELEMENT_YTTERBIUM() + * @method static Element ELEMENT_YTTRIUM() + * @method static Solid ELEMENT_ZERO() + * @method static Element ELEMENT_ZINC() + * @method static Element ELEMENT_ZIRCONIUM() + * @method static Solid EMERALD() + * @method static EmeraldOre EMERALD_ORE() + * @method static EnchantingTable ENCHANTING_TABLE() + * @method static EndPortalFrame END_PORTAL_FRAME() + * @method static EndRod END_ROD() + * @method static Solid END_STONE() + * @method static Slab END_STONE_BRICK_SLAB() + * @method static Stair END_STONE_BRICK_STAIRS() + * @method static Wall END_STONE_BRICK_WALL() + * @method static Solid END_STONE_BRICKS() + * @method static EnderChest ENDER_CHEST() + * @method static Slab FAKE_WOODEN_SLAB() + * @method static Farmland FARMLAND() + * @method static TallGrass FERN() + * @method static Fire FIRE() + * @method static FlowerPot FLOWER_POT() + * @method static FrostedIce FROSTED_ICE() + * @method static Furnace FURNACE() + * @method static Glass GLASS() + * @method static GlassPane GLASS_PANE() + * @method static GlowingObsidian GLOWING_OBSIDIAN() + * @method static Glowstone GLOWSTONE() + * @method static Solid GOLD() + * @method static Solid GOLD_ORE() + * @method static Solid GRANITE() + * @method static Slab GRANITE_SLAB() + * @method static Stair GRANITE_STAIRS() + * @method static Wall GRANITE_WALL() + * @method static Grass GRASS() + * @method static GrassPath GRASS_PATH() + * @method static Gravel GRAVEL() + * @method static Carpet GRAY_CARPET() + * @method static Concrete GRAY_CONCRETE() + * @method static ConcretePowder GRAY_CONCRETE_POWDER() + * @method static GlazedTerracotta GRAY_GLAZED_TERRACOTTA() + * @method static HardenedClay GRAY_STAINED_CLAY() + * @method static Glass GRAY_STAINED_GLASS() + * @method static GlassPane GRAY_STAINED_GLASS_PANE() + * @method static Wool GRAY_WOOL() + * @method static Carpet GREEN_CARPET() + * @method static Concrete GREEN_CONCRETE() + * @method static ConcretePowder GREEN_CONCRETE_POWDER() + * @method static GlazedTerracotta GREEN_GLAZED_TERRACOTTA() + * @method static HardenedClay GREEN_STAINED_CLAY() + * @method static Glass GREEN_STAINED_GLASS() + * @method static GlassPane GREEN_STAINED_GLASS_PANE() + * @method static Torch GREEN_TORCH() + * @method static Wool GREEN_WOOL() + * @method static HardenedGlass HARDENED_BLACK_STAINED_GLASS() + * @method static HardenedGlassPane HARDENED_BLACK_STAINED_GLASS_PANE() + * @method static HardenedGlass HARDENED_BLUE_STAINED_GLASS() + * @method static HardenedGlassPane HARDENED_BLUE_STAINED_GLASS_PANE() + * @method static HardenedGlass HARDENED_BROWN_STAINED_GLASS() + * @method static HardenedGlassPane HARDENED_BROWN_STAINED_GLASS_PANE() + * @method static HardenedClay HARDENED_CLAY() + * @method static HardenedGlass HARDENED_CYAN_STAINED_GLASS() + * @method static HardenedGlassPane HARDENED_CYAN_STAINED_GLASS_PANE() + * @method static HardenedGlass HARDENED_GLASS() + * @method static HardenedGlassPane HARDENED_GLASS_PANE() + * @method static HardenedGlass HARDENED_GRAY_STAINED_GLASS() + * @method static HardenedGlassPane HARDENED_GRAY_STAINED_GLASS_PANE() + * @method static HardenedGlass HARDENED_GREEN_STAINED_GLASS() + * @method static HardenedGlassPane HARDENED_GREEN_STAINED_GLASS_PANE() + * @method static HardenedGlass HARDENED_LIGHT_BLUE_STAINED_GLASS() + * @method static HardenedGlassPane HARDENED_LIGHT_BLUE_STAINED_GLASS_PANE() + * @method static HardenedGlass HARDENED_LIGHT_GRAY_STAINED_GLASS() + * @method static HardenedGlassPane HARDENED_LIGHT_GRAY_STAINED_GLASS_PANE() + * @method static HardenedGlass HARDENED_LIME_STAINED_GLASS() + * @method static HardenedGlassPane HARDENED_LIME_STAINED_GLASS_PANE() + * @method static HardenedGlass HARDENED_MAGENTA_STAINED_GLASS() + * @method static HardenedGlassPane HARDENED_MAGENTA_STAINED_GLASS_PANE() + * @method static HardenedGlass HARDENED_ORANGE_STAINED_GLASS() + * @method static HardenedGlassPane HARDENED_ORANGE_STAINED_GLASS_PANE() + * @method static HardenedGlass HARDENED_PINK_STAINED_GLASS() + * @method static HardenedGlassPane HARDENED_PINK_STAINED_GLASS_PANE() + * @method static HardenedGlass HARDENED_PURPLE_STAINED_GLASS() + * @method static HardenedGlassPane HARDENED_PURPLE_STAINED_GLASS_PANE() + * @method static HardenedGlass HARDENED_RED_STAINED_GLASS() + * @method static HardenedGlassPane HARDENED_RED_STAINED_GLASS_PANE() + * @method static HardenedGlass HARDENED_WHITE_STAINED_GLASS() + * @method static HardenedGlassPane HARDENED_WHITE_STAINED_GLASS_PANE() + * @method static HardenedGlass HARDENED_YELLOW_STAINED_GLASS() + * @method static HardenedGlassPane HARDENED_YELLOW_STAINED_GLASS_PANE() + * @method static HayBale HAY_BALE() + * @method static Hopper HOPPER() + * @method static Ice ICE() + * @method static InfestedStone INFESTED_CHISELED_STONE_BRICK() + * @method static InfestedStone INFESTED_COBBLESTONE() + * @method static InfestedStone INFESTED_CRACKED_STONE_BRICK() + * @method static InfestedStone INFESTED_MOSSY_STONE_BRICK() + * @method static InfestedStone INFESTED_STONE() + * @method static InfestedStone INFESTED_STONE_BRICK() + * @method static Solid INFO_UPDATE() + * @method static Solid INFO_UPDATE2() + * @method static Transparent INVISIBLE_BEDROCK() + * @method static Solid IRON() + * @method static Thin IRON_BARS() + * @method static Door IRON_DOOR() + * @method static Solid IRON_ORE() + * @method static Trapdoor IRON_TRAPDOOR() + * @method static ItemFrame ITEM_FRAME() + * @method static WoodenButton JUNGLE_BUTTON() + * @method static WoodenDoor JUNGLE_DOOR() + * @method static WoodenFence JUNGLE_FENCE() + * @method static FenceGate JUNGLE_FENCE_GATE() + * @method static Leaves JUNGLE_LEAVES() + * @method static Log JUNGLE_LOG() + * @method static Planks JUNGLE_PLANKS() + * @method static WoodenPressurePlate JUNGLE_PRESSURE_PLATE() + * @method static Sapling JUNGLE_SAPLING() + * @method static Sign JUNGLE_SIGN() + * @method static WoodenSlab JUNGLE_SLAB() + * @method static WoodenStairs JUNGLE_STAIRS() + * @method static WoodenTrapdoor JUNGLE_TRAPDOOR() + * @method static Wood JUNGLE_WOOD() + * @method static Ladder LADDER() + * @method static Solid LAPIS_LAZULI() + * @method static LapisOre LAPIS_LAZULI_ORE() + * @method static DoubleTallGrass LARGE_FERN() + * @method static Lava LAVA() + * @method static Solid LEGACY_STONECUTTER() + * @method static Lever LEVER() + * @method static Carpet LIGHT_BLUE_CARPET() + * @method static Concrete LIGHT_BLUE_CONCRETE() + * @method static ConcretePowder LIGHT_BLUE_CONCRETE_POWDER() + * @method static GlazedTerracotta LIGHT_BLUE_GLAZED_TERRACOTTA() + * @method static HardenedClay LIGHT_BLUE_STAINED_CLAY() + * @method static Glass LIGHT_BLUE_STAINED_GLASS() + * @method static GlassPane LIGHT_BLUE_STAINED_GLASS_PANE() + * @method static Wool LIGHT_BLUE_WOOL() + * @method static Carpet LIGHT_GRAY_CARPET() + * @method static Concrete LIGHT_GRAY_CONCRETE() + * @method static ConcretePowder LIGHT_GRAY_CONCRETE_POWDER() + * @method static GlazedTerracotta LIGHT_GRAY_GLAZED_TERRACOTTA() + * @method static HardenedClay LIGHT_GRAY_STAINED_CLAY() + * @method static Glass LIGHT_GRAY_STAINED_GLASS() + * @method static GlassPane LIGHT_GRAY_STAINED_GLASS_PANE() + * @method static Wool LIGHT_GRAY_WOOL() + * @method static DoublePlant LILAC() + * @method static Flower LILY_OF_THE_VALLEY() + * @method static WaterLily LILY_PAD() + * @method static Carpet LIME_CARPET() + * @method static Concrete LIME_CONCRETE() + * @method static ConcretePowder LIME_CONCRETE_POWDER() + * @method static GlazedTerracotta LIME_GLAZED_TERRACOTTA() + * @method static HardenedClay LIME_STAINED_CLAY() + * @method static Glass LIME_STAINED_GLASS() + * @method static GlassPane LIME_STAINED_GLASS_PANE() + * @method static Wool LIME_WOOL() + * @method static LitPumpkin LIT_PUMPKIN() + * @method static Carpet MAGENTA_CARPET() + * @method static Concrete MAGENTA_CONCRETE() + * @method static ConcretePowder MAGENTA_CONCRETE_POWDER() + * @method static GlazedTerracotta MAGENTA_GLAZED_TERRACOTTA() + * @method static HardenedClay MAGENTA_STAINED_CLAY() + * @method static Glass MAGENTA_STAINED_GLASS() + * @method static GlassPane MAGENTA_STAINED_GLASS_PANE() + * @method static Wool MAGENTA_WOOL() + * @method static Magma MAGMA() + * @method static Melon MELON() + * @method static MelonStem MELON_STEM() + * @method static Skull MOB_HEAD() + * @method static MonsterSpawner MONSTER_SPAWNER() + * @method static Solid MOSSY_COBBLESTONE() + * @method static Slab MOSSY_COBBLESTONE_SLAB() + * @method static Stair MOSSY_COBBLESTONE_STAIRS() + * @method static Wall MOSSY_COBBLESTONE_WALL() + * @method static Slab MOSSY_STONE_BRICK_SLAB() + * @method static Stair MOSSY_STONE_BRICK_STAIRS() + * @method static Wall MOSSY_STONE_BRICK_WALL() + * @method static Solid MOSSY_STONE_BRICKS() + * @method static Mycelium MYCELIUM() + * @method static Fence NETHER_BRICK_FENCE() + * @method static Slab NETHER_BRICK_SLAB() + * @method static Stair NETHER_BRICK_STAIRS() + * @method static Wall NETHER_BRICK_WALL() + * @method static Solid NETHER_BRICKS() + * @method static NetherPortal NETHER_PORTAL() + * @method static NetherQuartzOre NETHER_QUARTZ_ORE() + * @method static NetherReactor NETHER_REACTOR_CORE() + * @method static NetherWartPlant NETHER_WART() + * @method static Solid NETHER_WART_BLOCK() + * @method static Netherrack NETHERRACK() + * @method static Note NOTE_BLOCK() + * @method static WoodenButton OAK_BUTTON() + * @method static WoodenDoor OAK_DOOR() + * @method static WoodenFence OAK_FENCE() + * @method static FenceGate OAK_FENCE_GATE() + * @method static Leaves OAK_LEAVES() + * @method static Log OAK_LOG() + * @method static Planks OAK_PLANKS() + * @method static WoodenPressurePlate OAK_PRESSURE_PLATE() + * @method static Sapling OAK_SAPLING() + * @method static Sign OAK_SIGN() + * @method static WoodenSlab OAK_SLAB() + * @method static WoodenStairs OAK_STAIRS() + * @method static WoodenTrapdoor OAK_TRAPDOOR() + * @method static Wood OAK_WOOD() + * @method static Solid OBSIDIAN() + * @method static Carpet ORANGE_CARPET() + * @method static Concrete ORANGE_CONCRETE() + * @method static ConcretePowder ORANGE_CONCRETE_POWDER() + * @method static GlazedTerracotta ORANGE_GLAZED_TERRACOTTA() + * @method static HardenedClay ORANGE_STAINED_CLAY() + * @method static Glass ORANGE_STAINED_GLASS() + * @method static GlassPane ORANGE_STAINED_GLASS_PANE() + * @method static Flower ORANGE_TULIP() + * @method static Wool ORANGE_WOOL() + * @method static Flower OXEYE_DAISY() + * @method static PackedIce PACKED_ICE() + * @method static DoublePlant PEONY() + * @method static Carpet PINK_CARPET() + * @method static Concrete PINK_CONCRETE() + * @method static ConcretePowder PINK_CONCRETE_POWDER() + * @method static GlazedTerracotta PINK_GLAZED_TERRACOTTA() + * @method static HardenedClay PINK_STAINED_CLAY() + * @method static Glass PINK_STAINED_GLASS() + * @method static GlassPane PINK_STAINED_GLASS_PANE() + * @method static Flower PINK_TULIP() + * @method static Wool PINK_WOOL() + * @method static Podzol PODZOL() + * @method static Solid POLISHED_ANDESITE() + * @method static Slab POLISHED_ANDESITE_SLAB() + * @method static Stair POLISHED_ANDESITE_STAIRS() + * @method static Solid POLISHED_DIORITE() + * @method static Slab POLISHED_DIORITE_SLAB() + * @method static Stair POLISHED_DIORITE_STAIRS() + * @method static Solid POLISHED_GRANITE() + * @method static Slab POLISHED_GRANITE_SLAB() + * @method static Stair POLISHED_GRANITE_STAIRS() + * @method static Flower POPPY() + * @method static Potato POTATOES() + * @method static PoweredRail POWERED_RAIL() + * @method static Solid PRISMARINE() + * @method static Solid PRISMARINE_BRICKS() + * @method static Slab PRISMARINE_BRICKS_SLAB() + * @method static Stair PRISMARINE_BRICKS_STAIRS() + * @method static Slab PRISMARINE_SLAB() + * @method static Stair PRISMARINE_STAIRS() + * @method static Wall PRISMARINE_WALL() + * @method static Pumpkin PUMPKIN() + * @method static PumpkinStem PUMPKIN_STEM() + * @method static Carpet PURPLE_CARPET() + * @method static Concrete PURPLE_CONCRETE() + * @method static ConcretePowder PURPLE_CONCRETE_POWDER() + * @method static GlazedTerracotta PURPLE_GLAZED_TERRACOTTA() + * @method static HardenedClay PURPLE_STAINED_CLAY() + * @method static Glass PURPLE_STAINED_GLASS() + * @method static GlassPane PURPLE_STAINED_GLASS_PANE() + * @method static Torch PURPLE_TORCH() + * @method static Wool PURPLE_WOOL() + * @method static Solid PURPUR() + * @method static Solid PURPUR_PILLAR() + * @method static Slab PURPUR_SLAB() + * @method static Stair PURPUR_STAIRS() + * @method static Solid QUARTZ() + * @method static Solid QUARTZ_PILLAR() + * @method static Slab QUARTZ_SLAB() + * @method static Stair QUARTZ_STAIRS() + * @method static Rail RAIL() + * @method static Carpet RED_CARPET() + * @method static Concrete RED_CONCRETE() + * @method static ConcretePowder RED_CONCRETE_POWDER() + * @method static GlazedTerracotta RED_GLAZED_TERRACOTTA() + * @method static RedMushroom RED_MUSHROOM() + * @method static RedMushroomBlock RED_MUSHROOM_BLOCK() + * @method static Slab RED_NETHER_BRICK_SLAB() + * @method static Stair RED_NETHER_BRICK_STAIRS() + * @method static Wall RED_NETHER_BRICK_WALL() + * @method static Solid RED_NETHER_BRICKS() + * @method static Sand RED_SAND() + * @method static Solid RED_SANDSTONE() + * @method static Slab RED_SANDSTONE_SLAB() + * @method static Stair RED_SANDSTONE_STAIRS() + * @method static Wall RED_SANDSTONE_WALL() + * @method static HardenedClay RED_STAINED_CLAY() + * @method static Glass RED_STAINED_GLASS() + * @method static GlassPane RED_STAINED_GLASS_PANE() + * @method static Torch RED_TORCH() + * @method static Flower RED_TULIP() + * @method static Wool RED_WOOL() + * @method static Redstone REDSTONE() + * @method static RedstoneComparator REDSTONE_COMPARATOR() + * @method static RedstoneLamp REDSTONE_LAMP() + * @method static RedstoneOre REDSTONE_ORE() + * @method static RedstoneRepeater REDSTONE_REPEATER() + * @method static RedstoneTorch REDSTONE_TORCH() + * @method static RedstoneWire REDSTONE_WIRE() + * @method static Reserved6 RESERVED6() + * @method static DoublePlant ROSE_BUSH() + * @method static Sand SAND() + * @method static Solid SANDSTONE() + * @method static Slab SANDSTONE_SLAB() + * @method static Stair SANDSTONE_STAIRS() + * @method static Wall SANDSTONE_WALL() + * @method static SeaLantern SEA_LANTERN() + * @method static SeaPickle SEA_PICKLE() + * @method static Anvil SLIGHTLY_DAMAGED_ANVIL() + * @method static Solid SMOOTH_QUARTZ() + * @method static Slab SMOOTH_QUARTZ_SLAB() + * @method static Stair SMOOTH_QUARTZ_STAIRS() + * @method static Solid SMOOTH_RED_SANDSTONE() + * @method static Slab SMOOTH_RED_SANDSTONE_SLAB() + * @method static Stair SMOOTH_RED_SANDSTONE_STAIRS() + * @method static Solid SMOOTH_SANDSTONE() + * @method static Slab SMOOTH_SANDSTONE_SLAB() + * @method static Stair SMOOTH_SANDSTONE_STAIRS() + * @method static Solid SMOOTH_STONE() + * @method static Slab SMOOTH_STONE_SLAB() + * @method static Snow SNOW() + * @method static SnowLayer SNOW_LAYER() + * @method static SoulSand SOUL_SAND() + * @method static Sponge SPONGE() + * @method static WoodenButton SPRUCE_BUTTON() + * @method static WoodenDoor SPRUCE_DOOR() + * @method static WoodenFence SPRUCE_FENCE() + * @method static FenceGate SPRUCE_FENCE_GATE() + * @method static Leaves SPRUCE_LEAVES() + * @method static Log SPRUCE_LOG() + * @method static Planks SPRUCE_PLANKS() + * @method static WoodenPressurePlate SPRUCE_PRESSURE_PLATE() + * @method static Sapling SPRUCE_SAPLING() + * @method static Sign SPRUCE_SIGN() + * @method static WoodenSlab SPRUCE_SLAB() + * @method static WoodenStairs SPRUCE_STAIRS() + * @method static WoodenTrapdoor SPRUCE_TRAPDOOR() + * @method static Wood SPRUCE_WOOD() + * @method static Solid STONE() + * @method static Slab STONE_BRICK_SLAB() + * @method static Stair STONE_BRICK_STAIRS() + * @method static Wall STONE_BRICK_WALL() + * @method static Solid STONE_BRICKS() + * @method static StoneButton STONE_BUTTON() + * @method static StonePressurePlate STONE_PRESSURE_PLATE() + * @method static Slab STONE_SLAB() + * @method static Stair STONE_STAIRS() + * @method static Sugarcane SUGARCANE() + * @method static DoublePlant SUNFLOWER() + * @method static TallGrass TALL_GRASS() + * @method static TNT TNT() + * @method static Torch TORCH() + * @method static TrappedChest TRAPPED_CHEST() + * @method static Tripwire TRIPWIRE() + * @method static TripwireHook TRIPWIRE_HOOK() + * @method static UnderwaterTorch UNDERWATER_TORCH() + * @method static Anvil VERY_DAMAGED_ANVIL() + * @method static Vine VINES() + * @method static Water WATER() + * @method static WeightedPressurePlateHeavy WEIGHTED_PRESSURE_PLATE_HEAVY() + * @method static WeightedPressurePlateLight WEIGHTED_PRESSURE_PLATE_LIGHT() + * @method static Wheat WHEAT() + * @method static Carpet WHITE_CARPET() + * @method static Concrete WHITE_CONCRETE() + * @method static ConcretePowder WHITE_CONCRETE_POWDER() + * @method static GlazedTerracotta WHITE_GLAZED_TERRACOTTA() + * @method static HardenedClay WHITE_STAINED_CLAY() + * @method static Glass WHITE_STAINED_GLASS() + * @method static GlassPane WHITE_STAINED_GLASS_PANE() + * @method static Flower WHITE_TULIP() + * @method static Wool WHITE_WOOL() + * @method static Carpet YELLOW_CARPET() + * @method static Concrete YELLOW_CONCRETE() + * @method static ConcretePowder YELLOW_CONCRETE_POWDER() + * @method static GlazedTerracotta YELLOW_GLAZED_TERRACOTTA() + * @method static HardenedClay YELLOW_STAINED_CLAY() + * @method static Glass YELLOW_STAINED_GLASS() + * @method static GlassPane YELLOW_STAINED_GLASS_PANE() + * @method static Wool YELLOW_WOOL() */ final class VanillaBlocks{ + use RegistryTrait { + fromString as private Registry_fromString; + getAll as private Registry_getAll; + register as private Registry_register; + } private function __construct(){ //NOOP } - //region auto-generated code - - public static function ACACIA_BUTTON() : WoodenButton{ - return WoodenButton::cast(BlockFactory::get(395, 0)); - } - - public static function ACACIA_DOOR() : WoodenDoor{ - return WoodenDoor::cast(BlockFactory::get(196, 0)); - } - - public static function ACACIA_FENCE() : WoodenFence{ - return WoodenFence::cast(BlockFactory::get(85, 4)); - } - - public static function ACACIA_FENCE_GATE() : FenceGate{ - return FenceGate::cast(BlockFactory::get(187, 0)); - } - - public static function ACACIA_LEAVES() : Leaves{ - return Leaves::cast(BlockFactory::get(161, 0)); - } - - public static function ACACIA_LOG() : Log{ - return Log::cast(BlockFactory::get(162, 0)); - } - - public static function ACACIA_PLANKS() : Planks{ - return Planks::cast(BlockFactory::get(5, 4)); - } - - public static function ACACIA_PRESSURE_PLATE() : WoodenPressurePlate{ - return WoodenPressurePlate::cast(BlockFactory::get(405, 0)); - } - - public static function ACACIA_SAPLING() : Sapling{ - return Sapling::cast(BlockFactory::get(6, 4)); - } - - public static function ACACIA_SIGN() : Sign{ - return Sign::cast(BlockFactory::get(445, 0)); - } - - public static function ACACIA_SLAB() : WoodenSlab{ - return WoodenSlab::cast(BlockFactory::get(158, 4)); - } - - public static function ACACIA_STAIRS() : WoodenStairs{ - return WoodenStairs::cast(BlockFactory::get(163, 0)); - } - - public static function ACACIA_TRAPDOOR() : WoodenTrapdoor{ - return WoodenTrapdoor::cast(BlockFactory::get(400, 0)); - } - - public static function ACACIA_WOOD() : Wood{ - return Wood::cast(BlockFactory::get(467, 4)); - } - - public static function ACTIVATOR_RAIL() : ActivatorRail{ - return ActivatorRail::cast(BlockFactory::get(126, 0)); - } - - public static function AIR() : Air{ - return Air::cast(BlockFactory::get(0, 0)); - } - - public static function ALLIUM() : Flower{ - return Flower::cast(BlockFactory::get(38, 2)); - } - - public static function ANDESITE() : Solid{ - return Solid::cast(BlockFactory::get(1, 5)); - } - - public static function ANDESITE_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(417, 3)); - } - - public static function ANDESITE_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(426, 0)); - } - - public static function ANDESITE_WALL() : Wall{ - return Wall::cast(BlockFactory::get(139, 4)); - } - - public static function ANVIL() : Anvil{ - return Anvil::cast(BlockFactory::get(145, 0)); - } - - public static function AZURE_BLUET() : Flower{ - return Flower::cast(BlockFactory::get(38, 3)); - } - - public static function BANNER() : Banner{ - return Banner::cast(BlockFactory::get(176, 0)); - } - - public static function BARRIER() : Transparent{ - return Transparent::cast(BlockFactory::get(416, 0)); - } - - public static function BED() : Bed{ - return Bed::cast(BlockFactory::get(26, 0)); - } - - public static function BEDROCK() : Bedrock{ - return Bedrock::cast(BlockFactory::get(7, 0)); - } - - public static function BEETROOTS() : Beetroot{ - return Beetroot::cast(BlockFactory::get(244, 0)); - } - - public static function BIRCH_BUTTON() : WoodenButton{ - return WoodenButton::cast(BlockFactory::get(396, 0)); - } - - public static function BIRCH_DOOR() : WoodenDoor{ - return WoodenDoor::cast(BlockFactory::get(194, 0)); - } - - public static function BIRCH_FENCE() : WoodenFence{ - return WoodenFence::cast(BlockFactory::get(85, 2)); - } - - public static function BIRCH_FENCE_GATE() : FenceGate{ - return FenceGate::cast(BlockFactory::get(184, 0)); - } - - public static function BIRCH_LEAVES() : Leaves{ - return Leaves::cast(BlockFactory::get(18, 2)); - } - - public static function BIRCH_LOG() : Log{ - return Log::cast(BlockFactory::get(17, 2)); - } - - public static function BIRCH_PLANKS() : Planks{ - return Planks::cast(BlockFactory::get(5, 2)); - } - - public static function BIRCH_PRESSURE_PLATE() : WoodenPressurePlate{ - return WoodenPressurePlate::cast(BlockFactory::get(406, 0)); - } - - public static function BIRCH_SAPLING() : Sapling{ - return Sapling::cast(BlockFactory::get(6, 2)); - } - - public static function BIRCH_SIGN() : Sign{ - return Sign::cast(BlockFactory::get(441, 0)); - } - - public static function BIRCH_SLAB() : WoodenSlab{ - return WoodenSlab::cast(BlockFactory::get(158, 2)); - } - - public static function BIRCH_STAIRS() : WoodenStairs{ - return WoodenStairs::cast(BlockFactory::get(135, 0)); - } - - public static function BIRCH_TRAPDOOR() : WoodenTrapdoor{ - return WoodenTrapdoor::cast(BlockFactory::get(401, 0)); - } - - public static function BIRCH_WOOD() : Wood{ - return Wood::cast(BlockFactory::get(467, 2)); - } - - public static function BLACK_CARPET() : Carpet{ - return Carpet::cast(BlockFactory::get(171, 15)); - } - - public static function BLACK_CONCRETE() : Concrete{ - return Concrete::cast(BlockFactory::get(236, 15)); - } - - public static function BLACK_CONCRETE_POWDER() : ConcretePowder{ - return ConcretePowder::cast(BlockFactory::get(237, 15)); - } - - public static function BLACK_GLAZED_TERRACOTTA() : GlazedTerracotta{ - return GlazedTerracotta::cast(BlockFactory::get(235, 2)); - } - - public static function BLACK_STAINED_CLAY() : HardenedClay{ - return HardenedClay::cast(BlockFactory::get(159, 15)); - } - - public static function BLACK_STAINED_GLASS() : Glass{ - return Glass::cast(BlockFactory::get(241, 15)); - } - - public static function BLACK_STAINED_GLASS_PANE() : GlassPane{ - return GlassPane::cast(BlockFactory::get(160, 15)); - } - - public static function BLACK_WOOL() : Wool{ - return Wool::cast(BlockFactory::get(35, 15)); - } - - public static function BLUE_CARPET() : Carpet{ - return Carpet::cast(BlockFactory::get(171, 11)); - } - - public static function BLUE_CONCRETE() : Concrete{ - return Concrete::cast(BlockFactory::get(236, 11)); - } - - public static function BLUE_CONCRETE_POWDER() : ConcretePowder{ - return ConcretePowder::cast(BlockFactory::get(237, 11)); - } - - public static function BLUE_GLAZED_TERRACOTTA() : GlazedTerracotta{ - return GlazedTerracotta::cast(BlockFactory::get(231, 2)); - } - - public static function BLUE_ICE() : BlueIce{ - return BlueIce::cast(BlockFactory::get(266, 0)); - } - - public static function BLUE_ORCHID() : Flower{ - return Flower::cast(BlockFactory::get(38, 1)); - } - - public static function BLUE_STAINED_CLAY() : HardenedClay{ - return HardenedClay::cast(BlockFactory::get(159, 11)); - } - - public static function BLUE_STAINED_GLASS() : Glass{ - return Glass::cast(BlockFactory::get(241, 11)); - } - - public static function BLUE_STAINED_GLASS_PANE() : GlassPane{ - return GlassPane::cast(BlockFactory::get(160, 11)); - } - - public static function BLUE_TORCH() : Torch{ - return Torch::cast(BlockFactory::get(204, 5)); - } - - public static function BLUE_WOOL() : Wool{ - return Wool::cast(BlockFactory::get(35, 11)); - } - - public static function BONE_BLOCK() : BoneBlock{ - return BoneBlock::cast(BlockFactory::get(216, 0)); - } - - public static function BOOKSHELF() : Bookshelf{ - return Bookshelf::cast(BlockFactory::get(47, 0)); - } - - public static function BREWING_STAND() : BrewingStand{ - return BrewingStand::cast(BlockFactory::get(117, 0)); - } - - public static function BRICK_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(44, 4)); - } - - public static function BRICK_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(108, 0)); - } - - public static function BRICK_WALL() : Wall{ - return Wall::cast(BlockFactory::get(139, 6)); - } - - public static function BRICKS() : Solid{ - return Solid::cast(BlockFactory::get(45, 0)); - } - - public static function BROWN_CARPET() : Carpet{ - return Carpet::cast(BlockFactory::get(171, 12)); - } - - public static function BROWN_CONCRETE() : Concrete{ - return Concrete::cast(BlockFactory::get(236, 12)); - } - - public static function BROWN_CONCRETE_POWDER() : ConcretePowder{ - return ConcretePowder::cast(BlockFactory::get(237, 12)); - } - - public static function BROWN_GLAZED_TERRACOTTA() : GlazedTerracotta{ - return GlazedTerracotta::cast(BlockFactory::get(232, 2)); - } - - public static function BROWN_MUSHROOM() : BrownMushroom{ - return BrownMushroom::cast(BlockFactory::get(39, 0)); - } - - public static function BROWN_MUSHROOM_BLOCK() : BrownMushroomBlock{ - return BrownMushroomBlock::cast(BlockFactory::get(99, 0)); - } - - public static function BROWN_STAINED_CLAY() : HardenedClay{ - return HardenedClay::cast(BlockFactory::get(159, 12)); - } - - public static function BROWN_STAINED_GLASS() : Glass{ - return Glass::cast(BlockFactory::get(241, 12)); - } - - public static function BROWN_STAINED_GLASS_PANE() : GlassPane{ - return GlassPane::cast(BlockFactory::get(160, 12)); - } - - public static function BROWN_WOOL() : Wool{ - return Wool::cast(BlockFactory::get(35, 12)); - } - - public static function CACTUS() : Cactus{ - return Cactus::cast(BlockFactory::get(81, 0)); - } - - public static function CAKE() : Cake{ - return Cake::cast(BlockFactory::get(92, 0)); - } - - public static function CARROTS() : Carrot{ - return Carrot::cast(BlockFactory::get(141, 0)); - } - - public static function CHEST() : Chest{ - return Chest::cast(BlockFactory::get(54, 2)); - } - - public static function CHISELED_QUARTZ() : Solid{ - return Solid::cast(BlockFactory::get(155, 1)); - } - - public static function CHISELED_RED_SANDSTONE() : Solid{ - return Solid::cast(BlockFactory::get(179, 1)); - } - - public static function CHISELED_SANDSTONE() : Solid{ - return Solid::cast(BlockFactory::get(24, 1)); - } - - public static function CHISELED_STONE_BRICKS() : Solid{ - return Solid::cast(BlockFactory::get(98, 3)); - } - - public static function CLAY() : Clay{ - return Clay::cast(BlockFactory::get(82, 0)); - } - - public static function COAL() : Coal{ - return Coal::cast(BlockFactory::get(173, 0)); - } - - public static function COAL_ORE() : CoalOre{ - return CoalOre::cast(BlockFactory::get(16, 0)); - } - - public static function COARSE_DIRT() : CoarseDirt{ - return CoarseDirt::cast(BlockFactory::get(3, 1)); - } - - public static function COBBLESTONE() : Solid{ - return Solid::cast(BlockFactory::get(4, 0)); - } - - public static function COBBLESTONE_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(44, 3)); - } - - public static function COBBLESTONE_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(67, 0)); - } - - public static function COBBLESTONE_WALL() : Wall{ - return Wall::cast(BlockFactory::get(139, 0)); - } - - public static function COBWEB() : Cobweb{ - return Cobweb::cast(BlockFactory::get(30, 0)); - } - - public static function COCOA_POD() : CocoaBlock{ - return CocoaBlock::cast(BlockFactory::get(127, 0)); - } - - public static function CORNFLOWER() : Flower{ - return Flower::cast(BlockFactory::get(38, 9)); - } - - public static function CRACKED_STONE_BRICKS() : Solid{ - return Solid::cast(BlockFactory::get(98, 2)); - } - - public static function CRAFTING_TABLE() : CraftingTable{ - return CraftingTable::cast(BlockFactory::get(58, 0)); - } - - public static function CUT_RED_SANDSTONE() : Solid{ - return Solid::cast(BlockFactory::get(179, 2)); - } - - public static function CUT_RED_SANDSTONE_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(421, 4)); - } - - public static function CUT_SANDSTONE() : Solid{ - return Solid::cast(BlockFactory::get(24, 2)); - } - - public static function CUT_SANDSTONE_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(421, 3)); - } - - public static function CYAN_CARPET() : Carpet{ - return Carpet::cast(BlockFactory::get(171, 9)); - } - - public static function CYAN_CONCRETE() : Concrete{ - return Concrete::cast(BlockFactory::get(236, 9)); - } - - public static function CYAN_CONCRETE_POWDER() : ConcretePowder{ - return ConcretePowder::cast(BlockFactory::get(237, 9)); - } - - public static function CYAN_GLAZED_TERRACOTTA() : GlazedTerracotta{ - return GlazedTerracotta::cast(BlockFactory::get(229, 2)); - } - - public static function CYAN_STAINED_CLAY() : HardenedClay{ - return HardenedClay::cast(BlockFactory::get(159, 9)); - } - - public static function CYAN_STAINED_GLASS() : Glass{ - return Glass::cast(BlockFactory::get(241, 9)); - } - - public static function CYAN_STAINED_GLASS_PANE() : GlassPane{ - return GlassPane::cast(BlockFactory::get(160, 9)); - } - - public static function CYAN_WOOL() : Wool{ - return Wool::cast(BlockFactory::get(35, 9)); - } - - public static function DANDELION() : Flower{ - return Flower::cast(BlockFactory::get(37, 0)); - } - - public static function DARK_OAK_BUTTON() : WoodenButton{ - return WoodenButton::cast(BlockFactory::get(397, 0)); - } - - public static function DARK_OAK_DOOR() : WoodenDoor{ - return WoodenDoor::cast(BlockFactory::get(197, 0)); - } - - public static function DARK_OAK_FENCE() : WoodenFence{ - return WoodenFence::cast(BlockFactory::get(85, 5)); - } - - public static function DARK_OAK_FENCE_GATE() : FenceGate{ - return FenceGate::cast(BlockFactory::get(186, 0)); - } - - public static function DARK_OAK_LEAVES() : Leaves{ - return Leaves::cast(BlockFactory::get(161, 1)); - } - - public static function DARK_OAK_LOG() : Log{ - return Log::cast(BlockFactory::get(162, 1)); - } - - public static function DARK_OAK_PLANKS() : Planks{ - return Planks::cast(BlockFactory::get(5, 5)); - } - - public static function DARK_OAK_PRESSURE_PLATE() : WoodenPressurePlate{ - return WoodenPressurePlate::cast(BlockFactory::get(407, 0)); - } - - public static function DARK_OAK_SAPLING() : Sapling{ - return Sapling::cast(BlockFactory::get(6, 5)); - } - - public static function DARK_OAK_SIGN() : Sign{ - return Sign::cast(BlockFactory::get(447, 0)); - } - - public static function DARK_OAK_SLAB() : WoodenSlab{ - return WoodenSlab::cast(BlockFactory::get(158, 5)); - } - - public static function DARK_OAK_STAIRS() : WoodenStairs{ - return WoodenStairs::cast(BlockFactory::get(164, 0)); - } - - public static function DARK_OAK_TRAPDOOR() : WoodenTrapdoor{ - return WoodenTrapdoor::cast(BlockFactory::get(402, 0)); - } - - public static function DARK_OAK_WOOD() : Wood{ - return Wood::cast(BlockFactory::get(467, 5)); - } - - public static function DARK_PRISMARINE() : Solid{ - return Solid::cast(BlockFactory::get(168, 1)); - } - - public static function DARK_PRISMARINE_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(182, 3)); - } - - public static function DARK_PRISMARINE_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(258, 0)); - } - - public static function DAYLIGHT_SENSOR() : DaylightSensor{ - return DaylightSensor::cast(BlockFactory::get(151, 0)); - } - - public static function DEAD_BUSH() : DeadBush{ - return DeadBush::cast(BlockFactory::get(32, 0)); - } - - public static function DETECTOR_RAIL() : DetectorRail{ - return DetectorRail::cast(BlockFactory::get(28, 0)); - } - - public static function DIAMOND() : Solid{ - return Solid::cast(BlockFactory::get(57, 0)); - } - - public static function DIAMOND_ORE() : DiamondOre{ - return DiamondOre::cast(BlockFactory::get(56, 0)); - } - - public static function DIORITE() : Solid{ - return Solid::cast(BlockFactory::get(1, 3)); - } - - public static function DIORITE_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(417, 4)); - } - - public static function DIORITE_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(425, 0)); - } - - public static function DIORITE_WALL() : Wall{ - return Wall::cast(BlockFactory::get(139, 3)); - } - - public static function DIRT() : Dirt{ - return Dirt::cast(BlockFactory::get(3, 0)); - } - - public static function DOUBLE_TALLGRASS() : DoubleTallGrass{ - return DoubleTallGrass::cast(BlockFactory::get(175, 2)); - } - - public static function DRAGON_EGG() : DragonEgg{ - return DragonEgg::cast(BlockFactory::get(122, 0)); - } - - public static function DRIED_KELP() : DriedKelp{ - return DriedKelp::cast(BlockFactory::get(394, 0)); - } - - public static function ELEMENT_ACTINIUM() : Element{ - return Element::cast(BlockFactory::get(355, 0)); - } - - public static function ELEMENT_ALUMINUM() : Element{ - return Element::cast(BlockFactory::get(279, 0)); - } - - public static function ELEMENT_AMERICIUM() : Element{ - return Element::cast(BlockFactory::get(361, 0)); - } - - public static function ELEMENT_ANTIMONY() : Element{ - return Element::cast(BlockFactory::get(317, 0)); - } - - public static function ELEMENT_ARGON() : Element{ - return Element::cast(BlockFactory::get(284, 0)); - } - - public static function ELEMENT_ARSENIC() : Element{ - return Element::cast(BlockFactory::get(299, 0)); - } - - public static function ELEMENT_ASTATINE() : Element{ - return Element::cast(BlockFactory::get(351, 0)); - } - - public static function ELEMENT_BARIUM() : Element{ - return Element::cast(BlockFactory::get(322, 0)); - } - - public static function ELEMENT_BERKELIUM() : Element{ - return Element::cast(BlockFactory::get(363, 0)); - } - - public static function ELEMENT_BERYLLIUM() : Element{ - return Element::cast(BlockFactory::get(270, 0)); - } - - public static function ELEMENT_BISMUTH() : Element{ - return Element::cast(BlockFactory::get(349, 0)); - } - - public static function ELEMENT_BOHRIUM() : Element{ - return Element::cast(BlockFactory::get(373, 0)); - } - - public static function ELEMENT_BORON() : Element{ - return Element::cast(BlockFactory::get(271, 0)); - } - - public static function ELEMENT_BROMINE() : Element{ - return Element::cast(BlockFactory::get(301, 0)); - } - - public static function ELEMENT_CADMIUM() : Element{ - return Element::cast(BlockFactory::get(314, 0)); - } - - public static function ELEMENT_CALCIUM() : Element{ - return Element::cast(BlockFactory::get(286, 0)); - } - - public static function ELEMENT_CALIFORNIUM() : Element{ - return Element::cast(BlockFactory::get(364, 0)); - } - - public static function ELEMENT_CARBON() : Element{ - return Element::cast(BlockFactory::get(272, 0)); - } - - public static function ELEMENT_CERIUM() : Element{ - return Element::cast(BlockFactory::get(324, 0)); - } - - public static function ELEMENT_CESIUM() : Element{ - return Element::cast(BlockFactory::get(321, 0)); - } - - public static function ELEMENT_CHLORINE() : Element{ - return Element::cast(BlockFactory::get(283, 0)); - } - - public static function ELEMENT_CHROMIUM() : Element{ - return Element::cast(BlockFactory::get(290, 0)); - } - - public static function ELEMENT_COBALT() : Element{ - return Element::cast(BlockFactory::get(293, 0)); - } - - public static function ELEMENT_COPERNICIUM() : Element{ - return Element::cast(BlockFactory::get(378, 0)); - } - - public static function ELEMENT_COPPER() : Element{ - return Element::cast(BlockFactory::get(295, 0)); - } - - public static function ELEMENT_CURIUM() : Element{ - return Element::cast(BlockFactory::get(362, 0)); - } - - public static function ELEMENT_DARMSTADTIUM() : Element{ - return Element::cast(BlockFactory::get(376, 0)); - } - - public static function ELEMENT_DUBNIUM() : Element{ - return Element::cast(BlockFactory::get(371, 0)); - } - - public static function ELEMENT_DYSPROSIUM() : Element{ - return Element::cast(BlockFactory::get(332, 0)); - } - - public static function ELEMENT_EINSTEINIUM() : Element{ - return Element::cast(BlockFactory::get(365, 0)); - } - - public static function ELEMENT_ERBIUM() : Element{ - return Element::cast(BlockFactory::get(334, 0)); - } - - public static function ELEMENT_EUROPIUM() : Element{ - return Element::cast(BlockFactory::get(329, 0)); - } - - public static function ELEMENT_FERMIUM() : Element{ - return Element::cast(BlockFactory::get(366, 0)); - } - - public static function ELEMENT_FLEROVIUM() : Element{ - return Element::cast(BlockFactory::get(380, 0)); - } - - public static function ELEMENT_FLUORINE() : Element{ - return Element::cast(BlockFactory::get(275, 0)); - } - - public static function ELEMENT_FRANCIUM() : Element{ - return Element::cast(BlockFactory::get(353, 0)); - } - - public static function ELEMENT_GADOLINIUM() : Element{ - return Element::cast(BlockFactory::get(330, 0)); - } - - public static function ELEMENT_GALLIUM() : Element{ - return Element::cast(BlockFactory::get(297, 0)); - } - - public static function ELEMENT_GERMANIUM() : Element{ - return Element::cast(BlockFactory::get(298, 0)); - } - - public static function ELEMENT_GOLD() : Element{ - return Element::cast(BlockFactory::get(345, 0)); - } - - public static function ELEMENT_HAFNIUM() : Element{ - return Element::cast(BlockFactory::get(338, 0)); - } - - public static function ELEMENT_HASSIUM() : Element{ - return Element::cast(BlockFactory::get(374, 0)); - } - - public static function ELEMENT_HELIUM() : Element{ - return Element::cast(BlockFactory::get(268, 0)); - } - - public static function ELEMENT_HOLMIUM() : Element{ - return Element::cast(BlockFactory::get(333, 0)); - } - - public static function ELEMENT_HYDROGEN() : Element{ - return Element::cast(BlockFactory::get(267, 0)); - } - - public static function ELEMENT_INDIUM() : Element{ - return Element::cast(BlockFactory::get(315, 0)); - } - - public static function ELEMENT_IODINE() : Element{ - return Element::cast(BlockFactory::get(319, 0)); - } - - public static function ELEMENT_IRIDIUM() : Element{ - return Element::cast(BlockFactory::get(343, 0)); - } - - public static function ELEMENT_IRON() : Element{ - return Element::cast(BlockFactory::get(292, 0)); - } - - public static function ELEMENT_KRYPTON() : Element{ - return Element::cast(BlockFactory::get(302, 0)); - } - - public static function ELEMENT_LANTHANUM() : Element{ - return Element::cast(BlockFactory::get(323, 0)); - } - - public static function ELEMENT_LAWRENCIUM() : Element{ - return Element::cast(BlockFactory::get(369, 0)); - } - - public static function ELEMENT_LEAD() : Element{ - return Element::cast(BlockFactory::get(348, 0)); - } - - public static function ELEMENT_LITHIUM() : Element{ - return Element::cast(BlockFactory::get(269, 0)); - } - - public static function ELEMENT_LIVERMORIUM() : Element{ - return Element::cast(BlockFactory::get(382, 0)); - } - - public static function ELEMENT_LUTETIUM() : Element{ - return Element::cast(BlockFactory::get(337, 0)); - } - - public static function ELEMENT_MAGNESIUM() : Element{ - return Element::cast(BlockFactory::get(278, 0)); - } - - public static function ELEMENT_MANGANESE() : Element{ - return Element::cast(BlockFactory::get(291, 0)); - } - - public static function ELEMENT_MEITNERIUM() : Element{ - return Element::cast(BlockFactory::get(375, 0)); - } - - public static function ELEMENT_MENDELEVIUM() : Element{ - return Element::cast(BlockFactory::get(367, 0)); - } - - public static function ELEMENT_MERCURY() : Element{ - return Element::cast(BlockFactory::get(346, 0)); - } - - public static function ELEMENT_MOLYBDENUM() : Element{ - return Element::cast(BlockFactory::get(308, 0)); - } - - public static function ELEMENT_MOSCOVIUM() : Element{ - return Element::cast(BlockFactory::get(381, 0)); - } - - public static function ELEMENT_NEODYMIUM() : Element{ - return Element::cast(BlockFactory::get(326, 0)); - } - - public static function ELEMENT_NEON() : Element{ - return Element::cast(BlockFactory::get(276, 0)); - } - - public static function ELEMENT_NEPTUNIUM() : Element{ - return Element::cast(BlockFactory::get(359, 0)); - } - - public static function ELEMENT_NICKEL() : Element{ - return Element::cast(BlockFactory::get(294, 0)); - } - - public static function ELEMENT_NIHONIUM() : Element{ - return Element::cast(BlockFactory::get(379, 0)); - } - - public static function ELEMENT_NIOBIUM() : Element{ - return Element::cast(BlockFactory::get(307, 0)); - } - - public static function ELEMENT_NITROGEN() : Element{ - return Element::cast(BlockFactory::get(273, 0)); - } - - public static function ELEMENT_NOBELIUM() : Element{ - return Element::cast(BlockFactory::get(368, 0)); - } - - public static function ELEMENT_OGANESSON() : Element{ - return Element::cast(BlockFactory::get(384, 0)); - } - - public static function ELEMENT_OSMIUM() : Element{ - return Element::cast(BlockFactory::get(342, 0)); - } - - public static function ELEMENT_OXYGEN() : Element{ - return Element::cast(BlockFactory::get(274, 0)); - } - - public static function ELEMENT_PALLADIUM() : Element{ - return Element::cast(BlockFactory::get(312, 0)); - } - - public static function ELEMENT_PHOSPHORUS() : Element{ - return Element::cast(BlockFactory::get(281, 0)); - } - - public static function ELEMENT_PLATINUM() : Element{ - return Element::cast(BlockFactory::get(344, 0)); - } - - public static function ELEMENT_PLUTONIUM() : Element{ - return Element::cast(BlockFactory::get(360, 0)); - } - - public static function ELEMENT_POLONIUM() : Element{ - return Element::cast(BlockFactory::get(350, 0)); - } - - public static function ELEMENT_POTASSIUM() : Element{ - return Element::cast(BlockFactory::get(285, 0)); - } - - public static function ELEMENT_PRASEODYMIUM() : Element{ - return Element::cast(BlockFactory::get(325, 0)); - } - - public static function ELEMENT_PROMETHIUM() : Element{ - return Element::cast(BlockFactory::get(327, 0)); - } - - public static function ELEMENT_PROTACTINIUM() : Element{ - return Element::cast(BlockFactory::get(357, 0)); - } - - public static function ELEMENT_RADIUM() : Element{ - return Element::cast(BlockFactory::get(354, 0)); - } - - public static function ELEMENT_RADON() : Element{ - return Element::cast(BlockFactory::get(352, 0)); - } - - public static function ELEMENT_RHENIUM() : Element{ - return Element::cast(BlockFactory::get(341, 0)); - } - - public static function ELEMENT_RHODIUM() : Element{ - return Element::cast(BlockFactory::get(311, 0)); - } - - public static function ELEMENT_ROENTGENIUM() : Element{ - return Element::cast(BlockFactory::get(377, 0)); - } - - public static function ELEMENT_RUBIDIUM() : Element{ - return Element::cast(BlockFactory::get(303, 0)); - } - - public static function ELEMENT_RUTHENIUM() : Element{ - return Element::cast(BlockFactory::get(310, 0)); - } - - public static function ELEMENT_RUTHERFORDIUM() : Element{ - return Element::cast(BlockFactory::get(370, 0)); - } - - public static function ELEMENT_SAMARIUM() : Element{ - return Element::cast(BlockFactory::get(328, 0)); - } - - public static function ELEMENT_SCANDIUM() : Element{ - return Element::cast(BlockFactory::get(287, 0)); - } - - public static function ELEMENT_SEABORGIUM() : Element{ - return Element::cast(BlockFactory::get(372, 0)); - } - - public static function ELEMENT_SELENIUM() : Element{ - return Element::cast(BlockFactory::get(300, 0)); - } - - public static function ELEMENT_SILICON() : Element{ - return Element::cast(BlockFactory::get(280, 0)); - } - - public static function ELEMENT_SILVER() : Element{ - return Element::cast(BlockFactory::get(313, 0)); - } - - public static function ELEMENT_SODIUM() : Element{ - return Element::cast(BlockFactory::get(277, 0)); - } - - public static function ELEMENT_STRONTIUM() : Element{ - return Element::cast(BlockFactory::get(304, 0)); - } - - public static function ELEMENT_SULFUR() : Element{ - return Element::cast(BlockFactory::get(282, 0)); - } - - public static function ELEMENT_TANTALUM() : Element{ - return Element::cast(BlockFactory::get(339, 0)); - } - - public static function ELEMENT_TECHNETIUM() : Element{ - return Element::cast(BlockFactory::get(309, 0)); - } - - public static function ELEMENT_TELLURIUM() : Element{ - return Element::cast(BlockFactory::get(318, 0)); - } - - public static function ELEMENT_TENNESSINE() : Element{ - return Element::cast(BlockFactory::get(383, 0)); - } - - public static function ELEMENT_TERBIUM() : Element{ - return Element::cast(BlockFactory::get(331, 0)); - } - - public static function ELEMENT_THALLIUM() : Element{ - return Element::cast(BlockFactory::get(347, 0)); - } - - public static function ELEMENT_THORIUM() : Element{ - return Element::cast(BlockFactory::get(356, 0)); - } - - public static function ELEMENT_THULIUM() : Element{ - return Element::cast(BlockFactory::get(335, 0)); - } - - public static function ELEMENT_TIN() : Element{ - return Element::cast(BlockFactory::get(316, 0)); - } - - public static function ELEMENT_TITANIUM() : Element{ - return Element::cast(BlockFactory::get(288, 0)); - } - - public static function ELEMENT_TUNGSTEN() : Element{ - return Element::cast(BlockFactory::get(340, 0)); - } - - public static function ELEMENT_URANIUM() : Element{ - return Element::cast(BlockFactory::get(358, 0)); - } - - public static function ELEMENT_VANADIUM() : Element{ - return Element::cast(BlockFactory::get(289, 0)); - } - - public static function ELEMENT_XENON() : Element{ - return Element::cast(BlockFactory::get(320, 0)); - } - - public static function ELEMENT_YTTERBIUM() : Element{ - return Element::cast(BlockFactory::get(336, 0)); - } - - public static function ELEMENT_YTTRIUM() : Element{ - return Element::cast(BlockFactory::get(305, 0)); - } - - public static function ELEMENT_ZERO() : Solid{ - return Solid::cast(BlockFactory::get(36, 0)); - } - - public static function ELEMENT_ZINC() : Element{ - return Element::cast(BlockFactory::get(296, 0)); - } - - public static function ELEMENT_ZIRCONIUM() : Element{ - return Element::cast(BlockFactory::get(306, 0)); - } - - public static function EMERALD() : Solid{ - return Solid::cast(BlockFactory::get(133, 0)); - } - - public static function EMERALD_ORE() : EmeraldOre{ - return EmeraldOre::cast(BlockFactory::get(129, 0)); - } - - public static function ENCHANTING_TABLE() : EnchantingTable{ - return EnchantingTable::cast(BlockFactory::get(116, 0)); - } - - public static function END_PORTAL_FRAME() : EndPortalFrame{ - return EndPortalFrame::cast(BlockFactory::get(120, 0)); - } - - public static function END_ROD() : EndRod{ - return EndRod::cast(BlockFactory::get(208, 0)); - } - - public static function END_STONE() : Solid{ - return Solid::cast(BlockFactory::get(121, 0)); - } - - public static function END_STONE_BRICK_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(417, 0)); - } - - public static function END_STONE_BRICK_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(433, 0)); - } - - public static function END_STONE_BRICK_WALL() : Wall{ - return Wall::cast(BlockFactory::get(139, 10)); - } - - public static function END_STONE_BRICKS() : Solid{ - return Solid::cast(BlockFactory::get(206, 0)); - } - - public static function ENDER_CHEST() : EnderChest{ - return EnderChest::cast(BlockFactory::get(130, 2)); - } - - public static function FAKE_WOODEN_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(44, 2)); - } - - public static function FARMLAND() : Farmland{ - return Farmland::cast(BlockFactory::get(60, 0)); - } - - public static function FERN() : TallGrass{ - return TallGrass::cast(BlockFactory::get(31, 2)); - } - - public static function FIRE() : Fire{ - return Fire::cast(BlockFactory::get(51, 0)); - } - - public static function FLOWER_POT() : FlowerPot{ - return FlowerPot::cast(BlockFactory::get(140, 0)); - } - - public static function FROSTED_ICE() : FrostedIce{ - return FrostedIce::cast(BlockFactory::get(207, 0)); - } - - public static function FURNACE() : Furnace{ - return Furnace::cast(BlockFactory::get(61, 2)); - } - - public static function GLASS() : Glass{ - return Glass::cast(BlockFactory::get(20, 0)); - } - - public static function GLASS_PANE() : GlassPane{ - return GlassPane::cast(BlockFactory::get(102, 0)); - } - - public static function GLOWING_OBSIDIAN() : GlowingObsidian{ - return GlowingObsidian::cast(BlockFactory::get(246, 0)); - } - - public static function GLOWSTONE() : Glowstone{ - return Glowstone::cast(BlockFactory::get(89, 0)); - } - - public static function GOLD() : Solid{ - return Solid::cast(BlockFactory::get(41, 0)); - } - - public static function GOLD_ORE() : Solid{ - return Solid::cast(BlockFactory::get(14, 0)); - } - - public static function GRANITE() : Solid{ - return Solid::cast(BlockFactory::get(1, 1)); - } - - public static function GRANITE_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(417, 6)); - } - - public static function GRANITE_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(424, 0)); - } - - public static function GRANITE_WALL() : Wall{ - return Wall::cast(BlockFactory::get(139, 2)); - } - - public static function GRASS() : Grass{ - return Grass::cast(BlockFactory::get(2, 0)); - } - - public static function GRASS_PATH() : GrassPath{ - return GrassPath::cast(BlockFactory::get(198, 0)); - } - - public static function GRAVEL() : Gravel{ - return Gravel::cast(BlockFactory::get(13, 0)); - } - - public static function GRAY_CARPET() : Carpet{ - return Carpet::cast(BlockFactory::get(171, 7)); - } - - public static function GRAY_CONCRETE() : Concrete{ - return Concrete::cast(BlockFactory::get(236, 7)); - } - - public static function GRAY_CONCRETE_POWDER() : ConcretePowder{ - return ConcretePowder::cast(BlockFactory::get(237, 7)); - } - - public static function GRAY_GLAZED_TERRACOTTA() : GlazedTerracotta{ - return GlazedTerracotta::cast(BlockFactory::get(227, 2)); - } - - public static function GRAY_STAINED_CLAY() : HardenedClay{ - return HardenedClay::cast(BlockFactory::get(159, 7)); - } - - public static function GRAY_STAINED_GLASS() : Glass{ - return Glass::cast(BlockFactory::get(241, 7)); - } - - public static function GRAY_STAINED_GLASS_PANE() : GlassPane{ - return GlassPane::cast(BlockFactory::get(160, 7)); - } - - public static function GRAY_WOOL() : Wool{ - return Wool::cast(BlockFactory::get(35, 7)); - } - - public static function GREEN_CARPET() : Carpet{ - return Carpet::cast(BlockFactory::get(171, 13)); - } - - public static function GREEN_CONCRETE() : Concrete{ - return Concrete::cast(BlockFactory::get(236, 13)); - } - - public static function GREEN_CONCRETE_POWDER() : ConcretePowder{ - return ConcretePowder::cast(BlockFactory::get(237, 13)); - } - - public static function GREEN_GLAZED_TERRACOTTA() : GlazedTerracotta{ - return GlazedTerracotta::cast(BlockFactory::get(233, 2)); - } - - public static function GREEN_STAINED_CLAY() : HardenedClay{ - return HardenedClay::cast(BlockFactory::get(159, 13)); - } - - public static function GREEN_STAINED_GLASS() : Glass{ - return Glass::cast(BlockFactory::get(241, 13)); - } - - public static function GREEN_STAINED_GLASS_PANE() : GlassPane{ - return GlassPane::cast(BlockFactory::get(160, 13)); - } - - public static function GREEN_TORCH() : Torch{ - return Torch::cast(BlockFactory::get(202, 13)); - } - - public static function GREEN_WOOL() : Wool{ - return Wool::cast(BlockFactory::get(35, 13)); - } - - public static function HARDENED_BLACK_STAINED_GLASS() : HardenedGlass{ - return HardenedGlass::cast(BlockFactory::get(254, 15)); - } - - public static function HARDENED_BLACK_STAINED_GLASS_PANE() : HardenedGlassPane{ - return HardenedGlassPane::cast(BlockFactory::get(191, 15)); - } - - public static function HARDENED_BLUE_STAINED_GLASS() : HardenedGlass{ - return HardenedGlass::cast(BlockFactory::get(254, 11)); - } - - public static function HARDENED_BLUE_STAINED_GLASS_PANE() : HardenedGlassPane{ - return HardenedGlassPane::cast(BlockFactory::get(191, 11)); - } - - public static function HARDENED_BROWN_STAINED_GLASS() : HardenedGlass{ - return HardenedGlass::cast(BlockFactory::get(254, 12)); - } - - public static function HARDENED_BROWN_STAINED_GLASS_PANE() : HardenedGlassPane{ - return HardenedGlassPane::cast(BlockFactory::get(191, 12)); - } - - public static function HARDENED_CLAY() : HardenedClay{ - return HardenedClay::cast(BlockFactory::get(172, 0)); - } - - public static function HARDENED_CYAN_STAINED_GLASS() : HardenedGlass{ - return HardenedGlass::cast(BlockFactory::get(254, 9)); - } - - public static function HARDENED_CYAN_STAINED_GLASS_PANE() : HardenedGlassPane{ - return HardenedGlassPane::cast(BlockFactory::get(191, 9)); - } - - public static function HARDENED_GLASS() : HardenedGlass{ - return HardenedGlass::cast(BlockFactory::get(253, 0)); - } - - public static function HARDENED_GLASS_PANE() : HardenedGlassPane{ - return HardenedGlassPane::cast(BlockFactory::get(190, 0)); - } - - public static function HARDENED_GRAY_STAINED_GLASS() : HardenedGlass{ - return HardenedGlass::cast(BlockFactory::get(254, 7)); - } - - public static function HARDENED_GRAY_STAINED_GLASS_PANE() : HardenedGlassPane{ - return HardenedGlassPane::cast(BlockFactory::get(191, 7)); - } - - public static function HARDENED_GREEN_STAINED_GLASS() : HardenedGlass{ - return HardenedGlass::cast(BlockFactory::get(254, 13)); - } - - public static function HARDENED_GREEN_STAINED_GLASS_PANE() : HardenedGlassPane{ - return HardenedGlassPane::cast(BlockFactory::get(191, 13)); - } - - public static function HARDENED_LIGHT_BLUE_STAINED_GLASS() : HardenedGlass{ - return HardenedGlass::cast(BlockFactory::get(254, 3)); - } - - public static function HARDENED_LIGHT_BLUE_STAINED_GLASS_PANE() : HardenedGlassPane{ - return HardenedGlassPane::cast(BlockFactory::get(191, 3)); - } - - public static function HARDENED_LIGHT_GRAY_STAINED_GLASS() : HardenedGlass{ - return HardenedGlass::cast(BlockFactory::get(254, 8)); - } - - public static function HARDENED_LIGHT_GRAY_STAINED_GLASS_PANE() : HardenedGlassPane{ - return HardenedGlassPane::cast(BlockFactory::get(191, 8)); - } - - public static function HARDENED_LIME_STAINED_GLASS() : HardenedGlass{ - return HardenedGlass::cast(BlockFactory::get(254, 5)); - } - - public static function HARDENED_LIME_STAINED_GLASS_PANE() : HardenedGlassPane{ - return HardenedGlassPane::cast(BlockFactory::get(191, 5)); - } - - public static function HARDENED_MAGENTA_STAINED_GLASS() : HardenedGlass{ - return HardenedGlass::cast(BlockFactory::get(254, 2)); - } - - public static function HARDENED_MAGENTA_STAINED_GLASS_PANE() : HardenedGlassPane{ - return HardenedGlassPane::cast(BlockFactory::get(191, 2)); - } - - public static function HARDENED_ORANGE_STAINED_GLASS() : HardenedGlass{ - return HardenedGlass::cast(BlockFactory::get(254, 1)); - } - - public static function HARDENED_ORANGE_STAINED_GLASS_PANE() : HardenedGlassPane{ - return HardenedGlassPane::cast(BlockFactory::get(191, 1)); - } - - public static function HARDENED_PINK_STAINED_GLASS() : HardenedGlass{ - return HardenedGlass::cast(BlockFactory::get(254, 6)); - } - - public static function HARDENED_PINK_STAINED_GLASS_PANE() : HardenedGlassPane{ - return HardenedGlassPane::cast(BlockFactory::get(191, 6)); - } - - public static function HARDENED_PURPLE_STAINED_GLASS() : HardenedGlass{ - return HardenedGlass::cast(BlockFactory::get(254, 10)); - } - - public static function HARDENED_PURPLE_STAINED_GLASS_PANE() : HardenedGlassPane{ - return HardenedGlassPane::cast(BlockFactory::get(191, 10)); - } - - public static function HARDENED_RED_STAINED_GLASS() : HardenedGlass{ - return HardenedGlass::cast(BlockFactory::get(254, 14)); - } - - public static function HARDENED_RED_STAINED_GLASS_PANE() : HardenedGlassPane{ - return HardenedGlassPane::cast(BlockFactory::get(191, 14)); - } - - public static function HARDENED_WHITE_STAINED_GLASS() : HardenedGlass{ - return HardenedGlass::cast(BlockFactory::get(254, 0)); - } - - public static function HARDENED_WHITE_STAINED_GLASS_PANE() : HardenedGlassPane{ - return HardenedGlassPane::cast(BlockFactory::get(191, 0)); - } - - public static function HARDENED_YELLOW_STAINED_GLASS() : HardenedGlass{ - return HardenedGlass::cast(BlockFactory::get(254, 4)); - } - - public static function HARDENED_YELLOW_STAINED_GLASS_PANE() : HardenedGlassPane{ - return HardenedGlassPane::cast(BlockFactory::get(191, 4)); - } - - public static function HAY_BALE() : HayBale{ - return HayBale::cast(BlockFactory::get(170, 0)); - } - - public static function HOPPER() : Hopper{ - return Hopper::cast(BlockFactory::get(154, 0)); - } - - public static function ICE() : Ice{ - return Ice::cast(BlockFactory::get(79, 0)); - } - - public static function INFESTED_CHISELED_STONE_BRICK() : InfestedStone{ - return InfestedStone::cast(BlockFactory::get(97, 5)); - } - - public static function INFESTED_COBBLESTONE() : InfestedStone{ - return InfestedStone::cast(BlockFactory::get(97, 1)); - } - - public static function INFESTED_CRACKED_STONE_BRICK() : InfestedStone{ - return InfestedStone::cast(BlockFactory::get(97, 4)); - } - - public static function INFESTED_MOSSY_STONE_BRICK() : InfestedStone{ - return InfestedStone::cast(BlockFactory::get(97, 3)); - } - - public static function INFESTED_STONE() : InfestedStone{ - return InfestedStone::cast(BlockFactory::get(97, 0)); - } - - public static function INFESTED_STONE_BRICK() : InfestedStone{ - return InfestedStone::cast(BlockFactory::get(97, 2)); - } - - public static function INFO_UPDATE() : Solid{ - return Solid::cast(BlockFactory::get(248, 0)); - } - - public static function INFO_UPDATE2() : Solid{ - return Solid::cast(BlockFactory::get(249, 0)); - } - - public static function INVISIBLE_BEDROCK() : Transparent{ - return Transparent::cast(BlockFactory::get(95, 0)); - } - - public static function IRON() : Solid{ - return Solid::cast(BlockFactory::get(42, 0)); - } - - public static function IRON_BARS() : Thin{ - return Thin::cast(BlockFactory::get(101, 0)); - } - - public static function IRON_DOOR() : Door{ - return Door::cast(BlockFactory::get(71, 0)); - } - - public static function IRON_ORE() : Solid{ - return Solid::cast(BlockFactory::get(15, 0)); - } - - public static function IRON_TRAPDOOR() : Trapdoor{ - return Trapdoor::cast(BlockFactory::get(167, 0)); - } - - public static function ITEM_FRAME() : ItemFrame{ - return ItemFrame::cast(BlockFactory::get(199, 0)); - } - - public static function JUNGLE_BUTTON() : WoodenButton{ - return WoodenButton::cast(BlockFactory::get(398, 0)); - } - - public static function JUNGLE_DOOR() : WoodenDoor{ - return WoodenDoor::cast(BlockFactory::get(195, 0)); - } - - public static function JUNGLE_FENCE() : WoodenFence{ - return WoodenFence::cast(BlockFactory::get(85, 3)); - } - - public static function JUNGLE_FENCE_GATE() : FenceGate{ - return FenceGate::cast(BlockFactory::get(185, 0)); - } - - public static function JUNGLE_LEAVES() : Leaves{ - return Leaves::cast(BlockFactory::get(18, 3)); - } - - public static function JUNGLE_LOG() : Log{ - return Log::cast(BlockFactory::get(17, 3)); - } - - public static function JUNGLE_PLANKS() : Planks{ - return Planks::cast(BlockFactory::get(5, 3)); - } - - public static function JUNGLE_PRESSURE_PLATE() : WoodenPressurePlate{ - return WoodenPressurePlate::cast(BlockFactory::get(408, 0)); - } - - public static function JUNGLE_SAPLING() : Sapling{ - return Sapling::cast(BlockFactory::get(6, 3)); - } - - public static function JUNGLE_SIGN() : Sign{ - return Sign::cast(BlockFactory::get(443, 0)); - } - - public static function JUNGLE_SLAB() : WoodenSlab{ - return WoodenSlab::cast(BlockFactory::get(158, 3)); - } - - public static function JUNGLE_STAIRS() : WoodenStairs{ - return WoodenStairs::cast(BlockFactory::get(136, 0)); - } - - public static function JUNGLE_TRAPDOOR() : WoodenTrapdoor{ - return WoodenTrapdoor::cast(BlockFactory::get(403, 0)); - } - - public static function JUNGLE_WOOD() : Wood{ - return Wood::cast(BlockFactory::get(467, 3)); - } - - public static function LADDER() : Ladder{ - return Ladder::cast(BlockFactory::get(65, 2)); - } - - public static function LAPIS_LAZULI() : Solid{ - return Solid::cast(BlockFactory::get(22, 0)); - } - - public static function LAPIS_LAZULI_ORE() : LapisOre{ - return LapisOre::cast(BlockFactory::get(21, 0)); - } - - public static function LARGE_FERN() : DoubleTallGrass{ - return DoubleTallGrass::cast(BlockFactory::get(175, 3)); - } - - public static function LAVA() : Lava{ - return Lava::cast(BlockFactory::get(10, 0)); - } - - public static function LEGACY_STONECUTTER() : Solid{ - return Solid::cast(BlockFactory::get(245, 0)); - } - - public static function LEVER() : Lever{ - return Lever::cast(BlockFactory::get(69, 0)); - } - - public static function LIGHT_BLUE_CARPET() : Carpet{ - return Carpet::cast(BlockFactory::get(171, 3)); - } - - public static function LIGHT_BLUE_CONCRETE() : Concrete{ - return Concrete::cast(BlockFactory::get(236, 3)); - } - - public static function LIGHT_BLUE_CONCRETE_POWDER() : ConcretePowder{ - return ConcretePowder::cast(BlockFactory::get(237, 3)); - } - - public static function LIGHT_BLUE_GLAZED_TERRACOTTA() : GlazedTerracotta{ - return GlazedTerracotta::cast(BlockFactory::get(223, 2)); - } - - public static function LIGHT_BLUE_STAINED_CLAY() : HardenedClay{ - return HardenedClay::cast(BlockFactory::get(159, 3)); - } - - public static function LIGHT_BLUE_STAINED_GLASS() : Glass{ - return Glass::cast(BlockFactory::get(241, 3)); - } - - public static function LIGHT_BLUE_STAINED_GLASS_PANE() : GlassPane{ - return GlassPane::cast(BlockFactory::get(160, 3)); - } - - public static function LIGHT_BLUE_WOOL() : Wool{ - return Wool::cast(BlockFactory::get(35, 3)); - } - - public static function LIGHT_GRAY_CARPET() : Carpet{ - return Carpet::cast(BlockFactory::get(171, 8)); - } - - public static function LIGHT_GRAY_CONCRETE() : Concrete{ - return Concrete::cast(BlockFactory::get(236, 8)); - } - - public static function LIGHT_GRAY_CONCRETE_POWDER() : ConcretePowder{ - return ConcretePowder::cast(BlockFactory::get(237, 8)); - } - - public static function LIGHT_GRAY_GLAZED_TERRACOTTA() : GlazedTerracotta{ - return GlazedTerracotta::cast(BlockFactory::get(228, 2)); - } - - public static function LIGHT_GRAY_STAINED_CLAY() : HardenedClay{ - return HardenedClay::cast(BlockFactory::get(159, 8)); - } - - public static function LIGHT_GRAY_STAINED_GLASS() : Glass{ - return Glass::cast(BlockFactory::get(241, 8)); - } - - public static function LIGHT_GRAY_STAINED_GLASS_PANE() : GlassPane{ - return GlassPane::cast(BlockFactory::get(160, 8)); - } - - public static function LIGHT_GRAY_WOOL() : Wool{ - return Wool::cast(BlockFactory::get(35, 8)); - } - - public static function LILAC() : DoublePlant{ - return DoublePlant::cast(BlockFactory::get(175, 1)); - } - - public static function LILY_OF_THE_VALLEY() : Flower{ - return Flower::cast(BlockFactory::get(38, 10)); - } - - public static function LILY_PAD() : WaterLily{ - return WaterLily::cast(BlockFactory::get(111, 0)); - } - - public static function LIME_CARPET() : Carpet{ - return Carpet::cast(BlockFactory::get(171, 5)); - } - - public static function LIME_CONCRETE() : Concrete{ - return Concrete::cast(BlockFactory::get(236, 5)); - } - - public static function LIME_CONCRETE_POWDER() : ConcretePowder{ - return ConcretePowder::cast(BlockFactory::get(237, 5)); - } - - public static function LIME_GLAZED_TERRACOTTA() : GlazedTerracotta{ - return GlazedTerracotta::cast(BlockFactory::get(225, 2)); - } - - public static function LIME_STAINED_CLAY() : HardenedClay{ - return HardenedClay::cast(BlockFactory::get(159, 5)); - } - - public static function LIME_STAINED_GLASS() : Glass{ - return Glass::cast(BlockFactory::get(241, 5)); - } - - public static function LIME_STAINED_GLASS_PANE() : GlassPane{ - return GlassPane::cast(BlockFactory::get(160, 5)); - } - - public static function LIME_WOOL() : Wool{ - return Wool::cast(BlockFactory::get(35, 5)); - } - - public static function LIT_PUMPKIN() : LitPumpkin{ - return LitPumpkin::cast(BlockFactory::get(91, 0)); - } - - public static function MAGENTA_CARPET() : Carpet{ - return Carpet::cast(BlockFactory::get(171, 2)); - } - - public static function MAGENTA_CONCRETE() : Concrete{ - return Concrete::cast(BlockFactory::get(236, 2)); - } - - public static function MAGENTA_CONCRETE_POWDER() : ConcretePowder{ - return ConcretePowder::cast(BlockFactory::get(237, 2)); - } - - public static function MAGENTA_GLAZED_TERRACOTTA() : GlazedTerracotta{ - return GlazedTerracotta::cast(BlockFactory::get(222, 2)); - } - - public static function MAGENTA_STAINED_CLAY() : HardenedClay{ - return HardenedClay::cast(BlockFactory::get(159, 2)); - } - - public static function MAGENTA_STAINED_GLASS() : Glass{ - return Glass::cast(BlockFactory::get(241, 2)); - } - - public static function MAGENTA_STAINED_GLASS_PANE() : GlassPane{ - return GlassPane::cast(BlockFactory::get(160, 2)); - } - - public static function MAGENTA_WOOL() : Wool{ - return Wool::cast(BlockFactory::get(35, 2)); - } - - public static function MAGMA() : Magma{ - return Magma::cast(BlockFactory::get(213, 0)); - } - - public static function MELON() : Melon{ - return Melon::cast(BlockFactory::get(103, 0)); - } - - public static function MELON_STEM() : MelonStem{ - return MelonStem::cast(BlockFactory::get(105, 0)); - } - - public static function MOB_HEAD() : Skull{ - return Skull::cast(BlockFactory::get(144, 2)); - } - - public static function MONSTER_SPAWNER() : MonsterSpawner{ - return MonsterSpawner::cast(BlockFactory::get(52, 0)); - } - - public static function MOSSY_COBBLESTONE() : Solid{ - return Solid::cast(BlockFactory::get(48, 0)); - } - - public static function MOSSY_COBBLESTONE_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(182, 5)); - } - - public static function MOSSY_COBBLESTONE_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(434, 0)); - } - - public static function MOSSY_COBBLESTONE_WALL() : Wall{ - return Wall::cast(BlockFactory::get(139, 1)); - } - - public static function MOSSY_STONE_BRICK_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(421, 0)); - } - - public static function MOSSY_STONE_BRICK_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(430, 0)); - } - - public static function MOSSY_STONE_BRICK_WALL() : Wall{ - return Wall::cast(BlockFactory::get(139, 8)); - } - - public static function MOSSY_STONE_BRICKS() : Solid{ - return Solid::cast(BlockFactory::get(98, 1)); - } - - public static function MYCELIUM() : Mycelium{ - return Mycelium::cast(BlockFactory::get(110, 0)); - } - - public static function NETHER_BRICK_FENCE() : Fence{ - return Fence::cast(BlockFactory::get(113, 0)); - } - - public static function NETHER_BRICK_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(44, 7)); - } - - public static function NETHER_BRICK_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(114, 0)); - } - - public static function NETHER_BRICK_WALL() : Wall{ - return Wall::cast(BlockFactory::get(139, 9)); - } - - public static function NETHER_BRICKS() : Solid{ - return Solid::cast(BlockFactory::get(112, 0)); - } - - public static function NETHER_PORTAL() : NetherPortal{ - return NetherPortal::cast(BlockFactory::get(90, 1)); - } - - public static function NETHER_QUARTZ_ORE() : NetherQuartzOre{ - return NetherQuartzOre::cast(BlockFactory::get(153, 0)); - } - - public static function NETHER_REACTOR_CORE() : NetherReactor{ - return NetherReactor::cast(BlockFactory::get(247, 0)); - } - - public static function NETHER_WART() : NetherWartPlant{ - return NetherWartPlant::cast(BlockFactory::get(115, 0)); - } - - public static function NETHER_WART_BLOCK() : Solid{ - return Solid::cast(BlockFactory::get(214, 0)); - } - - public static function NETHERRACK() : Netherrack{ - return Netherrack::cast(BlockFactory::get(87, 0)); - } - - public static function NOTE_BLOCK() : Note{ - return Note::cast(BlockFactory::get(25, 0)); - } - - public static function OAK_BUTTON() : WoodenButton{ - return WoodenButton::cast(BlockFactory::get(143, 0)); - } - - public static function OAK_DOOR() : WoodenDoor{ - return WoodenDoor::cast(BlockFactory::get(64, 0)); - } - - public static function OAK_FENCE() : WoodenFence{ - return WoodenFence::cast(BlockFactory::get(85, 0)); - } - - public static function OAK_FENCE_GATE() : FenceGate{ - return FenceGate::cast(BlockFactory::get(107, 0)); - } - - public static function OAK_LEAVES() : Leaves{ - return Leaves::cast(BlockFactory::get(18, 0)); - } - - public static function OAK_LOG() : Log{ - return Log::cast(BlockFactory::get(17, 0)); - } - - public static function OAK_PLANKS() : Planks{ - return Planks::cast(BlockFactory::get(5, 0)); - } - - public static function OAK_PRESSURE_PLATE() : WoodenPressurePlate{ - return WoodenPressurePlate::cast(BlockFactory::get(72, 0)); - } - - public static function OAK_SAPLING() : Sapling{ - return Sapling::cast(BlockFactory::get(6, 0)); - } - - public static function OAK_SIGN() : Sign{ - return Sign::cast(BlockFactory::get(63, 0)); - } - - public static function OAK_SLAB() : WoodenSlab{ - return WoodenSlab::cast(BlockFactory::get(158, 0)); - } - - public static function OAK_STAIRS() : WoodenStairs{ - return WoodenStairs::cast(BlockFactory::get(53, 0)); - } - - public static function OAK_TRAPDOOR() : WoodenTrapdoor{ - return WoodenTrapdoor::cast(BlockFactory::get(96, 0)); - } - - public static function OAK_WOOD() : Wood{ - return Wood::cast(BlockFactory::get(467, 0)); - } - - public static function OBSIDIAN() : Solid{ - return Solid::cast(BlockFactory::get(49, 0)); - } - - public static function ORANGE_CARPET() : Carpet{ - return Carpet::cast(BlockFactory::get(171, 1)); - } - - public static function ORANGE_CONCRETE() : Concrete{ - return Concrete::cast(BlockFactory::get(236, 1)); - } - - public static function ORANGE_CONCRETE_POWDER() : ConcretePowder{ - return ConcretePowder::cast(BlockFactory::get(237, 1)); - } - - public static function ORANGE_GLAZED_TERRACOTTA() : GlazedTerracotta{ - return GlazedTerracotta::cast(BlockFactory::get(221, 2)); - } - - public static function ORANGE_STAINED_CLAY() : HardenedClay{ - return HardenedClay::cast(BlockFactory::get(159, 1)); - } - - public static function ORANGE_STAINED_GLASS() : Glass{ - return Glass::cast(BlockFactory::get(241, 1)); - } - - public static function ORANGE_STAINED_GLASS_PANE() : GlassPane{ - return GlassPane::cast(BlockFactory::get(160, 1)); - } - - public static function ORANGE_TULIP() : Flower{ - return Flower::cast(BlockFactory::get(38, 5)); - } - - public static function ORANGE_WOOL() : Wool{ - return Wool::cast(BlockFactory::get(35, 1)); - } - - public static function OXEYE_DAISY() : Flower{ - return Flower::cast(BlockFactory::get(38, 8)); - } - - public static function PACKED_ICE() : PackedIce{ - return PackedIce::cast(BlockFactory::get(174, 0)); - } - - public static function PEONY() : DoublePlant{ - return DoublePlant::cast(BlockFactory::get(175, 5)); - } - - public static function PINK_CARPET() : Carpet{ - return Carpet::cast(BlockFactory::get(171, 6)); - } - - public static function PINK_CONCRETE() : Concrete{ - return Concrete::cast(BlockFactory::get(236, 6)); - } - - public static function PINK_CONCRETE_POWDER() : ConcretePowder{ - return ConcretePowder::cast(BlockFactory::get(237, 6)); - } - - public static function PINK_GLAZED_TERRACOTTA() : GlazedTerracotta{ - return GlazedTerracotta::cast(BlockFactory::get(226, 2)); - } - - public static function PINK_STAINED_CLAY() : HardenedClay{ - return HardenedClay::cast(BlockFactory::get(159, 6)); - } - - public static function PINK_STAINED_GLASS() : Glass{ - return Glass::cast(BlockFactory::get(241, 6)); - } - - public static function PINK_STAINED_GLASS_PANE() : GlassPane{ - return GlassPane::cast(BlockFactory::get(160, 6)); - } - - public static function PINK_TULIP() : Flower{ - return Flower::cast(BlockFactory::get(38, 7)); - } - - public static function PINK_WOOL() : Wool{ - return Wool::cast(BlockFactory::get(35, 6)); - } - - public static function PODZOL() : Podzol{ - return Podzol::cast(BlockFactory::get(243, 0)); - } - - public static function POLISHED_ANDESITE() : Solid{ - return Solid::cast(BlockFactory::get(1, 6)); - } - - public static function POLISHED_ANDESITE_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(417, 2)); - } - - public static function POLISHED_ANDESITE_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(429, 0)); - } - - public static function POLISHED_DIORITE() : Solid{ - return Solid::cast(BlockFactory::get(1, 4)); - } - - public static function POLISHED_DIORITE_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(417, 5)); - } - - public static function POLISHED_DIORITE_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(428, 0)); - } - - public static function POLISHED_GRANITE() : Solid{ - return Solid::cast(BlockFactory::get(1, 2)); - } - - public static function POLISHED_GRANITE_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(417, 7)); - } - - public static function POLISHED_GRANITE_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(427, 0)); - } - - public static function POPPY() : Flower{ - return Flower::cast(BlockFactory::get(38, 0)); - } - - public static function POTATOES() : Potato{ - return Potato::cast(BlockFactory::get(142, 0)); - } - - public static function POWERED_RAIL() : PoweredRail{ - return PoweredRail::cast(BlockFactory::get(27, 0)); - } - - public static function PRISMARINE() : Solid{ - return Solid::cast(BlockFactory::get(168, 0)); - } - - public static function PRISMARINE_BRICKS() : Solid{ - return Solid::cast(BlockFactory::get(168, 2)); - } - - public static function PRISMARINE_BRICKS_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(182, 4)); - } - - public static function PRISMARINE_BRICKS_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(259, 0)); - } - - public static function PRISMARINE_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(182, 2)); - } - - public static function PRISMARINE_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(257, 0)); - } - - public static function PRISMARINE_WALL() : Wall{ - return Wall::cast(BlockFactory::get(139, 11)); - } - - public static function PUMPKIN() : Pumpkin{ - return Pumpkin::cast(BlockFactory::get(86, 0)); - } - - public static function PUMPKIN_STEM() : PumpkinStem{ - return PumpkinStem::cast(BlockFactory::get(104, 0)); - } - - public static function PURPLE_CARPET() : Carpet{ - return Carpet::cast(BlockFactory::get(171, 10)); - } - - public static function PURPLE_CONCRETE() : Concrete{ - return Concrete::cast(BlockFactory::get(236, 10)); - } - - public static function PURPLE_CONCRETE_POWDER() : ConcretePowder{ - return ConcretePowder::cast(BlockFactory::get(237, 10)); - } - - public static function PURPLE_GLAZED_TERRACOTTA() : GlazedTerracotta{ - return GlazedTerracotta::cast(BlockFactory::get(219, 2)); - } - - public static function PURPLE_STAINED_CLAY() : HardenedClay{ - return HardenedClay::cast(BlockFactory::get(159, 10)); - } - - public static function PURPLE_STAINED_GLASS() : Glass{ - return Glass::cast(BlockFactory::get(241, 10)); - } - - public static function PURPLE_STAINED_GLASS_PANE() : GlassPane{ - return GlassPane::cast(BlockFactory::get(160, 10)); - } - - public static function PURPLE_TORCH() : Torch{ - return Torch::cast(BlockFactory::get(204, 13)); - } - - public static function PURPLE_WOOL() : Wool{ - return Wool::cast(BlockFactory::get(35, 10)); - } - - public static function PURPUR() : Solid{ - return Solid::cast(BlockFactory::get(201, 0)); - } - - public static function PURPUR_PILLAR() : Solid{ - return Solid::cast(BlockFactory::get(201, 2)); - } - - public static function PURPUR_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(182, 1)); - } - - public static function PURPUR_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(203, 0)); - } - - public static function QUARTZ() : Solid{ - return Solid::cast(BlockFactory::get(155, 0)); - } - - public static function QUARTZ_PILLAR() : Solid{ - return Solid::cast(BlockFactory::get(155, 2)); - } - - public static function QUARTZ_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(44, 6)); - } - - public static function QUARTZ_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(156, 0)); - } - - public static function RAIL() : Rail{ - return Rail::cast(BlockFactory::get(66, 0)); - } - - public static function RED_CARPET() : Carpet{ - return Carpet::cast(BlockFactory::get(171, 14)); - } - - public static function RED_CONCRETE() : Concrete{ - return Concrete::cast(BlockFactory::get(236, 14)); - } - - public static function RED_CONCRETE_POWDER() : ConcretePowder{ - return ConcretePowder::cast(BlockFactory::get(237, 14)); - } - - public static function RED_GLAZED_TERRACOTTA() : GlazedTerracotta{ - return GlazedTerracotta::cast(BlockFactory::get(234, 2)); - } - - public static function RED_MUSHROOM() : RedMushroom{ - return RedMushroom::cast(BlockFactory::get(40, 0)); - } - - public static function RED_MUSHROOM_BLOCK() : RedMushroomBlock{ - return RedMushroomBlock::cast(BlockFactory::get(100, 0)); - } - - public static function RED_NETHER_BRICK_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(182, 7)); - } - - public static function RED_NETHER_BRICK_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(439, 0)); - } - - public static function RED_NETHER_BRICK_WALL() : Wall{ - return Wall::cast(BlockFactory::get(139, 13)); - } - - public static function RED_NETHER_BRICKS() : Solid{ - return Solid::cast(BlockFactory::get(215, 0)); - } - - public static function RED_SAND() : Sand{ - return Sand::cast(BlockFactory::get(12, 1)); - } - - public static function RED_SANDSTONE() : Solid{ - return Solid::cast(BlockFactory::get(179, 0)); - } - - public static function RED_SANDSTONE_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(182, 0)); - } - - public static function RED_SANDSTONE_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(180, 0)); - } - - public static function RED_SANDSTONE_WALL() : Wall{ - return Wall::cast(BlockFactory::get(139, 12)); - } - - public static function RED_STAINED_CLAY() : HardenedClay{ - return HardenedClay::cast(BlockFactory::get(159, 14)); - } - - public static function RED_STAINED_GLASS() : Glass{ - return Glass::cast(BlockFactory::get(241, 14)); - } - - public static function RED_STAINED_GLASS_PANE() : GlassPane{ - return GlassPane::cast(BlockFactory::get(160, 14)); - } - - public static function RED_TORCH() : Torch{ - return Torch::cast(BlockFactory::get(202, 5)); - } - - public static function RED_TULIP() : Flower{ - return Flower::cast(BlockFactory::get(38, 4)); - } - - public static function RED_WOOL() : Wool{ - return Wool::cast(BlockFactory::get(35, 14)); - } - - public static function REDSTONE() : Redstone{ - return Redstone::cast(BlockFactory::get(152, 0)); - } - - public static function REDSTONE_COMPARATOR() : RedstoneComparator{ - return RedstoneComparator::cast(BlockFactory::get(149, 0)); - } - - public static function REDSTONE_LAMP() : RedstoneLamp{ - return RedstoneLamp::cast(BlockFactory::get(123, 0)); - } - - public static function REDSTONE_ORE() : RedstoneOre{ - return RedstoneOre::cast(BlockFactory::get(73, 0)); - } - - public static function REDSTONE_REPEATER() : RedstoneRepeater{ - return RedstoneRepeater::cast(BlockFactory::get(93, 0)); - } - - public static function REDSTONE_TORCH() : RedstoneTorch{ - return RedstoneTorch::cast(BlockFactory::get(76, 5)); - } - - public static function REDSTONE_WIRE() : RedstoneWire{ - return RedstoneWire::cast(BlockFactory::get(55, 0)); - } - - public static function RESERVED6() : Reserved6{ - return Reserved6::cast(BlockFactory::get(255, 0)); - } - - public static function ROSE_BUSH() : DoublePlant{ - return DoublePlant::cast(BlockFactory::get(175, 4)); - } - - public static function SAND() : Sand{ - return Sand::cast(BlockFactory::get(12, 0)); - } - - public static function SANDSTONE() : Solid{ - return Solid::cast(BlockFactory::get(24, 0)); - } - - public static function SANDSTONE_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(44, 1)); - } - - public static function SANDSTONE_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(128, 0)); - } - - public static function SANDSTONE_WALL() : Wall{ - return Wall::cast(BlockFactory::get(139, 5)); - } - - public static function SEA_LANTERN() : SeaLantern{ - return SeaLantern::cast(BlockFactory::get(169, 0)); - } - - public static function SEA_PICKLE() : SeaPickle{ - return SeaPickle::cast(BlockFactory::get(411, 0)); - } - - public static function SLIGHTLY_DAMAGED_ANVIL() : Anvil{ - return Anvil::cast(BlockFactory::get(145, 4)); - } - - public static function SMOOTH_QUARTZ() : Solid{ - return Solid::cast(BlockFactory::get(155, 3)); - } - - public static function SMOOTH_QUARTZ_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(421, 1)); - } - - public static function SMOOTH_QUARTZ_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(440, 0)); - } - - public static function SMOOTH_RED_SANDSTONE() : Solid{ - return Solid::cast(BlockFactory::get(179, 3)); - } - - public static function SMOOTH_RED_SANDSTONE_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(417, 1)); - } - - public static function SMOOTH_RED_SANDSTONE_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(431, 0)); - } - - public static function SMOOTH_SANDSTONE() : Solid{ - return Solid::cast(BlockFactory::get(24, 3)); - } - - public static function SMOOTH_SANDSTONE_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(182, 6)); - } - - public static function SMOOTH_SANDSTONE_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(432, 0)); - } - - public static function SMOOTH_STONE() : Solid{ - return Solid::cast(BlockFactory::get(438, 0)); - } - - public static function SMOOTH_STONE_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(44, 0)); - } - - public static function SNOW() : Snow{ - return Snow::cast(BlockFactory::get(80, 0)); - } - - public static function SNOW_LAYER() : SnowLayer{ - return SnowLayer::cast(BlockFactory::get(78, 0)); - } - - public static function SOUL_SAND() : SoulSand{ - return SoulSand::cast(BlockFactory::get(88, 0)); - } - - public static function SPONGE() : Sponge{ - return Sponge::cast(BlockFactory::get(19, 0)); - } - - public static function SPRUCE_BUTTON() : WoodenButton{ - return WoodenButton::cast(BlockFactory::get(399, 0)); - } - - public static function SPRUCE_DOOR() : WoodenDoor{ - return WoodenDoor::cast(BlockFactory::get(193, 0)); - } - - public static function SPRUCE_FENCE() : WoodenFence{ - return WoodenFence::cast(BlockFactory::get(85, 1)); - } - - public static function SPRUCE_FENCE_GATE() : FenceGate{ - return FenceGate::cast(BlockFactory::get(183, 0)); - } - - public static function SPRUCE_LEAVES() : Leaves{ - return Leaves::cast(BlockFactory::get(18, 1)); - } - - public static function SPRUCE_LOG() : Log{ - return Log::cast(BlockFactory::get(17, 1)); - } - - public static function SPRUCE_PLANKS() : Planks{ - return Planks::cast(BlockFactory::get(5, 1)); - } - - public static function SPRUCE_PRESSURE_PLATE() : WoodenPressurePlate{ - return WoodenPressurePlate::cast(BlockFactory::get(409, 0)); - } - - public static function SPRUCE_SAPLING() : Sapling{ - return Sapling::cast(BlockFactory::get(6, 1)); - } - - public static function SPRUCE_SIGN() : Sign{ - return Sign::cast(BlockFactory::get(436, 0)); - } - - public static function SPRUCE_SLAB() : WoodenSlab{ - return WoodenSlab::cast(BlockFactory::get(158, 1)); - } - - public static function SPRUCE_STAIRS() : WoodenStairs{ - return WoodenStairs::cast(BlockFactory::get(134, 0)); - } - - public static function SPRUCE_TRAPDOOR() : WoodenTrapdoor{ - return WoodenTrapdoor::cast(BlockFactory::get(404, 0)); - } - - public static function SPRUCE_WOOD() : Wood{ - return Wood::cast(BlockFactory::get(467, 1)); - } - - public static function STONE() : Solid{ - return Solid::cast(BlockFactory::get(1, 0)); - } - - public static function STONE_BRICK_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(44, 5)); - } - - public static function STONE_BRICK_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(109, 0)); - } - - public static function STONE_BRICK_WALL() : Wall{ - return Wall::cast(BlockFactory::get(139, 7)); - } - - public static function STONE_BRICKS() : Solid{ - return Solid::cast(BlockFactory::get(98, 0)); - } - - public static function STONE_BUTTON() : StoneButton{ - return StoneButton::cast(BlockFactory::get(77, 0)); - } - - public static function STONE_PRESSURE_PLATE() : StonePressurePlate{ - return StonePressurePlate::cast(BlockFactory::get(70, 0)); - } - - public static function STONE_SLAB() : Slab{ - return Slab::cast(BlockFactory::get(421, 2)); - } - - public static function STONE_STAIRS() : Stair{ - return Stair::cast(BlockFactory::get(435, 0)); - } - - public static function SUGARCANE() : Sugarcane{ - return Sugarcane::cast(BlockFactory::get(83, 0)); - } - - public static function SUNFLOWER() : DoublePlant{ - return DoublePlant::cast(BlockFactory::get(175, 0)); - } - - public static function TALL_GRASS() : TallGrass{ - return TallGrass::cast(BlockFactory::get(31, 1)); - } - - public static function TNT() : TNT{ - return TNT::cast(BlockFactory::get(46, 0)); - } - - public static function TORCH() : Torch{ - return Torch::cast(BlockFactory::get(50, 5)); - } - - public static function TRAPPED_CHEST() : TrappedChest{ - return TrappedChest::cast(BlockFactory::get(146, 2)); - } - - public static function TRIPWIRE() : Tripwire{ - return Tripwire::cast(BlockFactory::get(132, 0)); - } - - public static function TRIPWIRE_HOOK() : TripwireHook{ - return TripwireHook::cast(BlockFactory::get(131, 0)); - } - - public static function UNDERWATER_TORCH() : UnderwaterTorch{ - return UnderwaterTorch::cast(BlockFactory::get(239, 5)); - } - - public static function VERY_DAMAGED_ANVIL() : Anvil{ - return Anvil::cast(BlockFactory::get(145, 8)); - } - - public static function VINES() : Vine{ - return Vine::cast(BlockFactory::get(106, 0)); - } - - public static function WATER() : Water{ - return Water::cast(BlockFactory::get(8, 0)); - } - - public static function WEIGHTED_PRESSURE_PLATE_HEAVY() : WeightedPressurePlateHeavy{ - return WeightedPressurePlateHeavy::cast(BlockFactory::get(148, 0)); - } - - public static function WEIGHTED_PRESSURE_PLATE_LIGHT() : WeightedPressurePlateLight{ - return WeightedPressurePlateLight::cast(BlockFactory::get(147, 0)); - } - - public static function WHEAT() : Wheat{ - return Wheat::cast(BlockFactory::get(59, 0)); - } - - public static function WHITE_CARPET() : Carpet{ - return Carpet::cast(BlockFactory::get(171, 0)); - } - - public static function WHITE_CONCRETE() : Concrete{ - return Concrete::cast(BlockFactory::get(236, 0)); - } - - public static function WHITE_CONCRETE_POWDER() : ConcretePowder{ - return ConcretePowder::cast(BlockFactory::get(237, 0)); - } - - public static function WHITE_GLAZED_TERRACOTTA() : GlazedTerracotta{ - return GlazedTerracotta::cast(BlockFactory::get(220, 2)); - } - - public static function WHITE_STAINED_CLAY() : HardenedClay{ - return HardenedClay::cast(BlockFactory::get(159, 0)); - } - - public static function WHITE_STAINED_GLASS() : Glass{ - return Glass::cast(BlockFactory::get(241, 0)); - } - - public static function WHITE_STAINED_GLASS_PANE() : GlassPane{ - return GlassPane::cast(BlockFactory::get(160, 0)); - } - - public static function WHITE_TULIP() : Flower{ - return Flower::cast(BlockFactory::get(38, 6)); - } - - public static function WHITE_WOOL() : Wool{ - return Wool::cast(BlockFactory::get(35, 0)); - } - - public static function YELLOW_CARPET() : Carpet{ - return Carpet::cast(BlockFactory::get(171, 4)); - } - - public static function YELLOW_CONCRETE() : Concrete{ - return Concrete::cast(BlockFactory::get(236, 4)); - } - - public static function YELLOW_CONCRETE_POWDER() : ConcretePowder{ - return ConcretePowder::cast(BlockFactory::get(237, 4)); - } - - public static function YELLOW_GLAZED_TERRACOTTA() : GlazedTerracotta{ - return GlazedTerracotta::cast(BlockFactory::get(224, 2)); - } - - public static function YELLOW_STAINED_CLAY() : HardenedClay{ - return HardenedClay::cast(BlockFactory::get(159, 4)); - } - - public static function YELLOW_STAINED_GLASS() : Glass{ - return Glass::cast(BlockFactory::get(241, 4)); - } - - public static function YELLOW_STAINED_GLASS_PANE() : GlassPane{ - return GlassPane::cast(BlockFactory::get(160, 4)); - } - - public static function YELLOW_WOOL() : Wool{ - return Wool::cast(BlockFactory::get(35, 4)); + protected static function register(string $name, Block $block) : void{ + self::Registry_register($name, $block); + } + + /** + * @param string $name + * + * @return Block + */ + public static function fromString(string $name) : Block{ + $result = self::Registry_fromString($name); + assert($result instanceof Block); + return clone $result; + } + + /** + * @return Block[] + */ + public static function getAll() : array{ + return array_map(function(Block $member){ return clone $member; }, self::Registry_getAll()); + } + + protected static function setup() : void{ + self::register("acacia_button", BlockFactory::get(395)); + self::register("acacia_door", BlockFactory::get(196)); + self::register("acacia_fence", BlockFactory::get(85, 4)); + self::register("acacia_fence_gate", BlockFactory::get(187)); + self::register("acacia_leaves", BlockFactory::get(161)); + self::register("acacia_log", BlockFactory::get(162)); + self::register("acacia_planks", BlockFactory::get(5, 4)); + self::register("acacia_pressure_plate", BlockFactory::get(405)); + self::register("acacia_sapling", BlockFactory::get(6, 4)); + self::register("acacia_sign", BlockFactory::get(445)); + self::register("acacia_slab", BlockFactory::get(158, 4)); + self::register("acacia_stairs", BlockFactory::get(163)); + self::register("acacia_trapdoor", BlockFactory::get(400)); + self::register("acacia_wood", BlockFactory::get(467, 4)); + self::register("activator_rail", BlockFactory::get(126)); + self::register("air", BlockFactory::get(0)); + self::register("allium", BlockFactory::get(38, 2)); + self::register("andesite", BlockFactory::get(1, 5)); + self::register("andesite_slab", BlockFactory::get(417, 3)); + self::register("andesite_stairs", BlockFactory::get(426)); + self::register("andesite_wall", BlockFactory::get(139, 4)); + self::register("anvil", BlockFactory::get(145)); + self::register("azure_bluet", BlockFactory::get(38, 3)); + self::register("banner", BlockFactory::get(176)); + self::register("barrier", BlockFactory::get(416)); + self::register("bed", BlockFactory::get(26)); + self::register("bedrock", BlockFactory::get(7)); + self::register("beetroots", BlockFactory::get(244)); + self::register("birch_button", BlockFactory::get(396)); + self::register("birch_door", BlockFactory::get(194)); + self::register("birch_fence", BlockFactory::get(85, 2)); + self::register("birch_fence_gate", BlockFactory::get(184)); + self::register("birch_leaves", BlockFactory::get(18, 2)); + self::register("birch_log", BlockFactory::get(17, 2)); + self::register("birch_planks", BlockFactory::get(5, 2)); + self::register("birch_pressure_plate", BlockFactory::get(406)); + self::register("birch_sapling", BlockFactory::get(6, 2)); + self::register("birch_sign", BlockFactory::get(441)); + self::register("birch_slab", BlockFactory::get(158, 2)); + self::register("birch_stairs", BlockFactory::get(135)); + self::register("birch_trapdoor", BlockFactory::get(401)); + self::register("birch_wood", BlockFactory::get(467, 2)); + self::register("black_carpet", BlockFactory::get(171, 15)); + self::register("black_concrete", BlockFactory::get(236, 15)); + self::register("black_concrete_powder", BlockFactory::get(237, 15)); + self::register("black_glazed_terracotta", BlockFactory::get(235, 2)); + self::register("black_stained_clay", BlockFactory::get(159, 15)); + self::register("black_stained_glass", BlockFactory::get(241, 15)); + self::register("black_stained_glass_pane", BlockFactory::get(160, 15)); + self::register("black_wool", BlockFactory::get(35, 15)); + self::register("blue_carpet", BlockFactory::get(171, 11)); + self::register("blue_concrete", BlockFactory::get(236, 11)); + self::register("blue_concrete_powder", BlockFactory::get(237, 11)); + self::register("blue_glazed_terracotta", BlockFactory::get(231, 2)); + self::register("blue_ice", BlockFactory::get(266)); + self::register("blue_orchid", BlockFactory::get(38, 1)); + self::register("blue_stained_clay", BlockFactory::get(159, 11)); + self::register("blue_stained_glass", BlockFactory::get(241, 11)); + self::register("blue_stained_glass_pane", BlockFactory::get(160, 11)); + self::register("blue_torch", BlockFactory::get(204, 5)); + self::register("blue_wool", BlockFactory::get(35, 11)); + self::register("bone_block", BlockFactory::get(216)); + self::register("bookshelf", BlockFactory::get(47)); + self::register("brewing_stand", BlockFactory::get(117)); + self::register("brick_slab", BlockFactory::get(44, 4)); + self::register("brick_stairs", BlockFactory::get(108)); + self::register("brick_wall", BlockFactory::get(139, 6)); + self::register("bricks", BlockFactory::get(45)); + self::register("brown_carpet", BlockFactory::get(171, 12)); + self::register("brown_concrete", BlockFactory::get(236, 12)); + self::register("brown_concrete_powder", BlockFactory::get(237, 12)); + self::register("brown_glazed_terracotta", BlockFactory::get(232, 2)); + self::register("brown_mushroom", BlockFactory::get(39)); + self::register("brown_mushroom_block", BlockFactory::get(99)); + self::register("brown_stained_clay", BlockFactory::get(159, 12)); + self::register("brown_stained_glass", BlockFactory::get(241, 12)); + self::register("brown_stained_glass_pane", BlockFactory::get(160, 12)); + self::register("brown_wool", BlockFactory::get(35, 12)); + self::register("cactus", BlockFactory::get(81)); + self::register("cake", BlockFactory::get(92)); + self::register("carrots", BlockFactory::get(141)); + self::register("chest", BlockFactory::get(54, 2)); + self::register("chiseled_quartz", BlockFactory::get(155, 1)); + self::register("chiseled_red_sandstone", BlockFactory::get(179, 1)); + self::register("chiseled_sandstone", BlockFactory::get(24, 1)); + self::register("chiseled_stone_bricks", BlockFactory::get(98, 3)); + self::register("clay", BlockFactory::get(82)); + self::register("coal", BlockFactory::get(173)); + self::register("coal_ore", BlockFactory::get(16)); + self::register("coarse_dirt", BlockFactory::get(3, 1)); + self::register("cobblestone", BlockFactory::get(4)); + self::register("cobblestone_slab", BlockFactory::get(44, 3)); + self::register("cobblestone_stairs", BlockFactory::get(67)); + self::register("cobblestone_wall", BlockFactory::get(139)); + self::register("cobweb", BlockFactory::get(30)); + self::register("cocoa_pod", BlockFactory::get(127)); + self::register("cornflower", BlockFactory::get(38, 9)); + self::register("cracked_stone_bricks", BlockFactory::get(98, 2)); + self::register("crafting_table", BlockFactory::get(58)); + self::register("cut_red_sandstone", BlockFactory::get(179, 2)); + self::register("cut_red_sandstone_slab", BlockFactory::get(421, 4)); + self::register("cut_sandstone", BlockFactory::get(24, 2)); + self::register("cut_sandstone_slab", BlockFactory::get(421, 3)); + self::register("cyan_carpet", BlockFactory::get(171, 9)); + self::register("cyan_concrete", BlockFactory::get(236, 9)); + self::register("cyan_concrete_powder", BlockFactory::get(237, 9)); + self::register("cyan_glazed_terracotta", BlockFactory::get(229, 2)); + self::register("cyan_stained_clay", BlockFactory::get(159, 9)); + self::register("cyan_stained_glass", BlockFactory::get(241, 9)); + self::register("cyan_stained_glass_pane", BlockFactory::get(160, 9)); + self::register("cyan_wool", BlockFactory::get(35, 9)); + self::register("dandelion", BlockFactory::get(37)); + self::register("dark_oak_button", BlockFactory::get(397)); + self::register("dark_oak_door", BlockFactory::get(197)); + self::register("dark_oak_fence", BlockFactory::get(85, 5)); + self::register("dark_oak_fence_gate", BlockFactory::get(186)); + self::register("dark_oak_leaves", BlockFactory::get(161, 1)); + self::register("dark_oak_log", BlockFactory::get(162, 1)); + self::register("dark_oak_planks", BlockFactory::get(5, 5)); + self::register("dark_oak_pressure_plate", BlockFactory::get(407)); + self::register("dark_oak_sapling", BlockFactory::get(6, 5)); + self::register("dark_oak_sign", BlockFactory::get(447)); + self::register("dark_oak_slab", BlockFactory::get(158, 5)); + self::register("dark_oak_stairs", BlockFactory::get(164)); + self::register("dark_oak_trapdoor", BlockFactory::get(402)); + self::register("dark_oak_wood", BlockFactory::get(467, 5)); + self::register("dark_prismarine", BlockFactory::get(168, 1)); + self::register("dark_prismarine_slab", BlockFactory::get(182, 3)); + self::register("dark_prismarine_stairs", BlockFactory::get(258)); + self::register("daylight_sensor", BlockFactory::get(151)); + self::register("dead_bush", BlockFactory::get(32)); + self::register("detector_rail", BlockFactory::get(28)); + self::register("diamond", BlockFactory::get(57)); + self::register("diamond_ore", BlockFactory::get(56)); + self::register("diorite", BlockFactory::get(1, 3)); + self::register("diorite_slab", BlockFactory::get(417, 4)); + self::register("diorite_stairs", BlockFactory::get(425)); + self::register("diorite_wall", BlockFactory::get(139, 3)); + self::register("dirt", BlockFactory::get(3)); + self::register("double_tallgrass", BlockFactory::get(175, 2)); + self::register("dragon_egg", BlockFactory::get(122)); + self::register("dried_kelp", BlockFactory::get(394)); + self::register("element_actinium", BlockFactory::get(355)); + self::register("element_aluminum", BlockFactory::get(279)); + self::register("element_americium", BlockFactory::get(361)); + self::register("element_antimony", BlockFactory::get(317)); + self::register("element_argon", BlockFactory::get(284)); + self::register("element_arsenic", BlockFactory::get(299)); + self::register("element_astatine", BlockFactory::get(351)); + self::register("element_barium", BlockFactory::get(322)); + self::register("element_berkelium", BlockFactory::get(363)); + self::register("element_beryllium", BlockFactory::get(270)); + self::register("element_bismuth", BlockFactory::get(349)); + self::register("element_bohrium", BlockFactory::get(373)); + self::register("element_boron", BlockFactory::get(271)); + self::register("element_bromine", BlockFactory::get(301)); + self::register("element_cadmium", BlockFactory::get(314)); + self::register("element_calcium", BlockFactory::get(286)); + self::register("element_californium", BlockFactory::get(364)); + self::register("element_carbon", BlockFactory::get(272)); + self::register("element_cerium", BlockFactory::get(324)); + self::register("element_cesium", BlockFactory::get(321)); + self::register("element_chlorine", BlockFactory::get(283)); + self::register("element_chromium", BlockFactory::get(290)); + self::register("element_cobalt", BlockFactory::get(293)); + self::register("element_copernicium", BlockFactory::get(378)); + self::register("element_copper", BlockFactory::get(295)); + self::register("element_curium", BlockFactory::get(362)); + self::register("element_darmstadtium", BlockFactory::get(376)); + self::register("element_dubnium", BlockFactory::get(371)); + self::register("element_dysprosium", BlockFactory::get(332)); + self::register("element_einsteinium", BlockFactory::get(365)); + self::register("element_erbium", BlockFactory::get(334)); + self::register("element_europium", BlockFactory::get(329)); + self::register("element_fermium", BlockFactory::get(366)); + self::register("element_flerovium", BlockFactory::get(380)); + self::register("element_fluorine", BlockFactory::get(275)); + self::register("element_francium", BlockFactory::get(353)); + self::register("element_gadolinium", BlockFactory::get(330)); + self::register("element_gallium", BlockFactory::get(297)); + self::register("element_germanium", BlockFactory::get(298)); + self::register("element_gold", BlockFactory::get(345)); + self::register("element_hafnium", BlockFactory::get(338)); + self::register("element_hassium", BlockFactory::get(374)); + self::register("element_helium", BlockFactory::get(268)); + self::register("element_holmium", BlockFactory::get(333)); + self::register("element_hydrogen", BlockFactory::get(267)); + self::register("element_indium", BlockFactory::get(315)); + self::register("element_iodine", BlockFactory::get(319)); + self::register("element_iridium", BlockFactory::get(343)); + self::register("element_iron", BlockFactory::get(292)); + self::register("element_krypton", BlockFactory::get(302)); + self::register("element_lanthanum", BlockFactory::get(323)); + self::register("element_lawrencium", BlockFactory::get(369)); + self::register("element_lead", BlockFactory::get(348)); + self::register("element_lithium", BlockFactory::get(269)); + self::register("element_livermorium", BlockFactory::get(382)); + self::register("element_lutetium", BlockFactory::get(337)); + self::register("element_magnesium", BlockFactory::get(278)); + self::register("element_manganese", BlockFactory::get(291)); + self::register("element_meitnerium", BlockFactory::get(375)); + self::register("element_mendelevium", BlockFactory::get(367)); + self::register("element_mercury", BlockFactory::get(346)); + self::register("element_molybdenum", BlockFactory::get(308)); + self::register("element_moscovium", BlockFactory::get(381)); + self::register("element_neodymium", BlockFactory::get(326)); + self::register("element_neon", BlockFactory::get(276)); + self::register("element_neptunium", BlockFactory::get(359)); + self::register("element_nickel", BlockFactory::get(294)); + self::register("element_nihonium", BlockFactory::get(379)); + self::register("element_niobium", BlockFactory::get(307)); + self::register("element_nitrogen", BlockFactory::get(273)); + self::register("element_nobelium", BlockFactory::get(368)); + self::register("element_oganesson", BlockFactory::get(384)); + self::register("element_osmium", BlockFactory::get(342)); + self::register("element_oxygen", BlockFactory::get(274)); + self::register("element_palladium", BlockFactory::get(312)); + self::register("element_phosphorus", BlockFactory::get(281)); + self::register("element_platinum", BlockFactory::get(344)); + self::register("element_plutonium", BlockFactory::get(360)); + self::register("element_polonium", BlockFactory::get(350)); + self::register("element_potassium", BlockFactory::get(285)); + self::register("element_praseodymium", BlockFactory::get(325)); + self::register("element_promethium", BlockFactory::get(327)); + self::register("element_protactinium", BlockFactory::get(357)); + self::register("element_radium", BlockFactory::get(354)); + self::register("element_radon", BlockFactory::get(352)); + self::register("element_rhenium", BlockFactory::get(341)); + self::register("element_rhodium", BlockFactory::get(311)); + self::register("element_roentgenium", BlockFactory::get(377)); + self::register("element_rubidium", BlockFactory::get(303)); + self::register("element_ruthenium", BlockFactory::get(310)); + self::register("element_rutherfordium", BlockFactory::get(370)); + self::register("element_samarium", BlockFactory::get(328)); + self::register("element_scandium", BlockFactory::get(287)); + self::register("element_seaborgium", BlockFactory::get(372)); + self::register("element_selenium", BlockFactory::get(300)); + self::register("element_silicon", BlockFactory::get(280)); + self::register("element_silver", BlockFactory::get(313)); + self::register("element_sodium", BlockFactory::get(277)); + self::register("element_strontium", BlockFactory::get(304)); + self::register("element_sulfur", BlockFactory::get(282)); + self::register("element_tantalum", BlockFactory::get(339)); + self::register("element_technetium", BlockFactory::get(309)); + self::register("element_tellurium", BlockFactory::get(318)); + self::register("element_tennessine", BlockFactory::get(383)); + self::register("element_terbium", BlockFactory::get(331)); + self::register("element_thallium", BlockFactory::get(347)); + self::register("element_thorium", BlockFactory::get(356)); + self::register("element_thulium", BlockFactory::get(335)); + self::register("element_tin", BlockFactory::get(316)); + self::register("element_titanium", BlockFactory::get(288)); + self::register("element_tungsten", BlockFactory::get(340)); + self::register("element_uranium", BlockFactory::get(358)); + self::register("element_vanadium", BlockFactory::get(289)); + self::register("element_xenon", BlockFactory::get(320)); + self::register("element_ytterbium", BlockFactory::get(336)); + self::register("element_yttrium", BlockFactory::get(305)); + self::register("element_zero", BlockFactory::get(36)); + self::register("element_zinc", BlockFactory::get(296)); + self::register("element_zirconium", BlockFactory::get(306)); + self::register("emerald", BlockFactory::get(133)); + self::register("emerald_ore", BlockFactory::get(129)); + self::register("enchanting_table", BlockFactory::get(116)); + self::register("end_portal_frame", BlockFactory::get(120)); + self::register("end_rod", BlockFactory::get(208)); + self::register("end_stone", BlockFactory::get(121)); + self::register("end_stone_brick_slab", BlockFactory::get(417)); + self::register("end_stone_brick_stairs", BlockFactory::get(433)); + self::register("end_stone_brick_wall", BlockFactory::get(139, 10)); + self::register("end_stone_bricks", BlockFactory::get(206)); + self::register("ender_chest", BlockFactory::get(130, 2)); + self::register("fake_wooden_slab", BlockFactory::get(44, 2)); + self::register("farmland", BlockFactory::get(60)); + self::register("fern", BlockFactory::get(31, 2)); + self::register("fire", BlockFactory::get(51)); + self::register("flower_pot", BlockFactory::get(140)); + self::register("frosted_ice", BlockFactory::get(207)); + self::register("furnace", BlockFactory::get(61, 2)); + self::register("glass", BlockFactory::get(20)); + self::register("glass_pane", BlockFactory::get(102)); + self::register("glowing_obsidian", BlockFactory::get(246)); + self::register("glowstone", BlockFactory::get(89)); + self::register("gold", BlockFactory::get(41)); + self::register("gold_ore", BlockFactory::get(14)); + self::register("granite", BlockFactory::get(1, 1)); + self::register("granite_slab", BlockFactory::get(417, 6)); + self::register("granite_stairs", BlockFactory::get(424)); + self::register("granite_wall", BlockFactory::get(139, 2)); + self::register("grass", BlockFactory::get(2)); + self::register("grass_path", BlockFactory::get(198)); + self::register("gravel", BlockFactory::get(13)); + self::register("gray_carpet", BlockFactory::get(171, 7)); + self::register("gray_concrete", BlockFactory::get(236, 7)); + self::register("gray_concrete_powder", BlockFactory::get(237, 7)); + self::register("gray_glazed_terracotta", BlockFactory::get(227, 2)); + self::register("gray_stained_clay", BlockFactory::get(159, 7)); + self::register("gray_stained_glass", BlockFactory::get(241, 7)); + self::register("gray_stained_glass_pane", BlockFactory::get(160, 7)); + self::register("gray_wool", BlockFactory::get(35, 7)); + self::register("green_carpet", BlockFactory::get(171, 13)); + self::register("green_concrete", BlockFactory::get(236, 13)); + self::register("green_concrete_powder", BlockFactory::get(237, 13)); + self::register("green_glazed_terracotta", BlockFactory::get(233, 2)); + self::register("green_stained_clay", BlockFactory::get(159, 13)); + self::register("green_stained_glass", BlockFactory::get(241, 13)); + self::register("green_stained_glass_pane", BlockFactory::get(160, 13)); + self::register("green_torch", BlockFactory::get(202, 13)); + self::register("green_wool", BlockFactory::get(35, 13)); + self::register("hardened_black_stained_glass", BlockFactory::get(254, 15)); + self::register("hardened_black_stained_glass_pane", BlockFactory::get(191, 15)); + self::register("hardened_blue_stained_glass", BlockFactory::get(254, 11)); + self::register("hardened_blue_stained_glass_pane", BlockFactory::get(191, 11)); + self::register("hardened_brown_stained_glass", BlockFactory::get(254, 12)); + self::register("hardened_brown_stained_glass_pane", BlockFactory::get(191, 12)); + self::register("hardened_clay", BlockFactory::get(172)); + self::register("hardened_cyan_stained_glass", BlockFactory::get(254, 9)); + self::register("hardened_cyan_stained_glass_pane", BlockFactory::get(191, 9)); + self::register("hardened_glass", BlockFactory::get(253)); + self::register("hardened_glass_pane", BlockFactory::get(190)); + self::register("hardened_gray_stained_glass", BlockFactory::get(254, 7)); + self::register("hardened_gray_stained_glass_pane", BlockFactory::get(191, 7)); + self::register("hardened_green_stained_glass", BlockFactory::get(254, 13)); + self::register("hardened_green_stained_glass_pane", BlockFactory::get(191, 13)); + self::register("hardened_light_blue_stained_glass", BlockFactory::get(254, 3)); + self::register("hardened_light_blue_stained_glass_pane", BlockFactory::get(191, 3)); + self::register("hardened_light_gray_stained_glass", BlockFactory::get(254, 8)); + self::register("hardened_light_gray_stained_glass_pane", BlockFactory::get(191, 8)); + self::register("hardened_lime_stained_glass", BlockFactory::get(254, 5)); + self::register("hardened_lime_stained_glass_pane", BlockFactory::get(191, 5)); + self::register("hardened_magenta_stained_glass", BlockFactory::get(254, 2)); + self::register("hardened_magenta_stained_glass_pane", BlockFactory::get(191, 2)); + self::register("hardened_orange_stained_glass", BlockFactory::get(254, 1)); + self::register("hardened_orange_stained_glass_pane", BlockFactory::get(191, 1)); + self::register("hardened_pink_stained_glass", BlockFactory::get(254, 6)); + self::register("hardened_pink_stained_glass_pane", BlockFactory::get(191, 6)); + self::register("hardened_purple_stained_glass", BlockFactory::get(254, 10)); + self::register("hardened_purple_stained_glass_pane", BlockFactory::get(191, 10)); + self::register("hardened_red_stained_glass", BlockFactory::get(254, 14)); + self::register("hardened_red_stained_glass_pane", BlockFactory::get(191, 14)); + self::register("hardened_white_stained_glass", BlockFactory::get(254)); + self::register("hardened_white_stained_glass_pane", BlockFactory::get(191)); + self::register("hardened_yellow_stained_glass", BlockFactory::get(254, 4)); + self::register("hardened_yellow_stained_glass_pane", BlockFactory::get(191, 4)); + self::register("hay_bale", BlockFactory::get(170)); + self::register("hopper", BlockFactory::get(154)); + self::register("ice", BlockFactory::get(79)); + self::register("infested_chiseled_stone_brick", BlockFactory::get(97, 5)); + self::register("infested_cobblestone", BlockFactory::get(97, 1)); + self::register("infested_cracked_stone_brick", BlockFactory::get(97, 4)); + self::register("infested_mossy_stone_brick", BlockFactory::get(97, 3)); + self::register("infested_stone", BlockFactory::get(97)); + self::register("infested_stone_brick", BlockFactory::get(97, 2)); + self::register("info_update", BlockFactory::get(248)); + self::register("info_update2", BlockFactory::get(249)); + self::register("invisible_bedrock", BlockFactory::get(95)); + self::register("iron", BlockFactory::get(42)); + self::register("iron_bars", BlockFactory::get(101)); + self::register("iron_door", BlockFactory::get(71)); + self::register("iron_ore", BlockFactory::get(15)); + self::register("iron_trapdoor", BlockFactory::get(167)); + self::register("item_frame", BlockFactory::get(199)); + self::register("jungle_button", BlockFactory::get(398)); + self::register("jungle_door", BlockFactory::get(195)); + self::register("jungle_fence", BlockFactory::get(85, 3)); + self::register("jungle_fence_gate", BlockFactory::get(185)); + self::register("jungle_leaves", BlockFactory::get(18, 3)); + self::register("jungle_log", BlockFactory::get(17, 3)); + self::register("jungle_planks", BlockFactory::get(5, 3)); + self::register("jungle_pressure_plate", BlockFactory::get(408)); + self::register("jungle_sapling", BlockFactory::get(6, 3)); + self::register("jungle_sign", BlockFactory::get(443)); + self::register("jungle_slab", BlockFactory::get(158, 3)); + self::register("jungle_stairs", BlockFactory::get(136)); + self::register("jungle_trapdoor", BlockFactory::get(403)); + self::register("jungle_wood", BlockFactory::get(467, 3)); + self::register("ladder", BlockFactory::get(65, 2)); + self::register("lapis_lazuli", BlockFactory::get(22)); + self::register("lapis_lazuli_ore", BlockFactory::get(21)); + self::register("large_fern", BlockFactory::get(175, 3)); + self::register("lava", BlockFactory::get(10)); + self::register("legacy_stonecutter", BlockFactory::get(245)); + self::register("lever", BlockFactory::get(69)); + self::register("light_blue_carpet", BlockFactory::get(171, 3)); + self::register("light_blue_concrete", BlockFactory::get(236, 3)); + self::register("light_blue_concrete_powder", BlockFactory::get(237, 3)); + self::register("light_blue_glazed_terracotta", BlockFactory::get(223, 2)); + self::register("light_blue_stained_clay", BlockFactory::get(159, 3)); + self::register("light_blue_stained_glass", BlockFactory::get(241, 3)); + self::register("light_blue_stained_glass_pane", BlockFactory::get(160, 3)); + self::register("light_blue_wool", BlockFactory::get(35, 3)); + self::register("light_gray_carpet", BlockFactory::get(171, 8)); + self::register("light_gray_concrete", BlockFactory::get(236, 8)); + self::register("light_gray_concrete_powder", BlockFactory::get(237, 8)); + self::register("light_gray_glazed_terracotta", BlockFactory::get(228, 2)); + self::register("light_gray_stained_clay", BlockFactory::get(159, 8)); + self::register("light_gray_stained_glass", BlockFactory::get(241, 8)); + self::register("light_gray_stained_glass_pane", BlockFactory::get(160, 8)); + self::register("light_gray_wool", BlockFactory::get(35, 8)); + self::register("lilac", BlockFactory::get(175, 1)); + self::register("lily_of_the_valley", BlockFactory::get(38, 10)); + self::register("lily_pad", BlockFactory::get(111)); + self::register("lime_carpet", BlockFactory::get(171, 5)); + self::register("lime_concrete", BlockFactory::get(236, 5)); + self::register("lime_concrete_powder", BlockFactory::get(237, 5)); + self::register("lime_glazed_terracotta", BlockFactory::get(225, 2)); + self::register("lime_stained_clay", BlockFactory::get(159, 5)); + self::register("lime_stained_glass", BlockFactory::get(241, 5)); + self::register("lime_stained_glass_pane", BlockFactory::get(160, 5)); + self::register("lime_wool", BlockFactory::get(35, 5)); + self::register("lit_pumpkin", BlockFactory::get(91)); + self::register("magenta_carpet", BlockFactory::get(171, 2)); + self::register("magenta_concrete", BlockFactory::get(236, 2)); + self::register("magenta_concrete_powder", BlockFactory::get(237, 2)); + self::register("magenta_glazed_terracotta", BlockFactory::get(222, 2)); + self::register("magenta_stained_clay", BlockFactory::get(159, 2)); + self::register("magenta_stained_glass", BlockFactory::get(241, 2)); + self::register("magenta_stained_glass_pane", BlockFactory::get(160, 2)); + self::register("magenta_wool", BlockFactory::get(35, 2)); + self::register("magma", BlockFactory::get(213)); + self::register("melon", BlockFactory::get(103)); + self::register("melon_stem", BlockFactory::get(105)); + self::register("mob_head", BlockFactory::get(144, 2)); + self::register("monster_spawner", BlockFactory::get(52)); + self::register("mossy_cobblestone", BlockFactory::get(48)); + self::register("mossy_cobblestone_slab", BlockFactory::get(182, 5)); + self::register("mossy_cobblestone_stairs", BlockFactory::get(434)); + self::register("mossy_cobblestone_wall", BlockFactory::get(139, 1)); + self::register("mossy_stone_brick_slab", BlockFactory::get(421)); + self::register("mossy_stone_brick_stairs", BlockFactory::get(430)); + self::register("mossy_stone_brick_wall", BlockFactory::get(139, 8)); + self::register("mossy_stone_bricks", BlockFactory::get(98, 1)); + self::register("mycelium", BlockFactory::get(110)); + self::register("nether_brick_fence", BlockFactory::get(113)); + self::register("nether_brick_slab", BlockFactory::get(44, 7)); + self::register("nether_brick_stairs", BlockFactory::get(114)); + self::register("nether_brick_wall", BlockFactory::get(139, 9)); + self::register("nether_bricks", BlockFactory::get(112)); + self::register("nether_portal", BlockFactory::get(90, 1)); + self::register("nether_quartz_ore", BlockFactory::get(153)); + self::register("nether_reactor_core", BlockFactory::get(247)); + self::register("nether_wart", BlockFactory::get(115)); + self::register("nether_wart_block", BlockFactory::get(214)); + self::register("netherrack", BlockFactory::get(87)); + self::register("note_block", BlockFactory::get(25)); + self::register("oak_button", BlockFactory::get(143)); + self::register("oak_door", BlockFactory::get(64)); + self::register("oak_fence", BlockFactory::get(85)); + self::register("oak_fence_gate", BlockFactory::get(107)); + self::register("oak_leaves", BlockFactory::get(18)); + self::register("oak_log", BlockFactory::get(17)); + self::register("oak_planks", BlockFactory::get(5)); + self::register("oak_pressure_plate", BlockFactory::get(72)); + self::register("oak_sapling", BlockFactory::get(6)); + self::register("oak_sign", BlockFactory::get(63)); + self::register("oak_slab", BlockFactory::get(158)); + self::register("oak_stairs", BlockFactory::get(53)); + self::register("oak_trapdoor", BlockFactory::get(96)); + self::register("oak_wood", BlockFactory::get(467)); + self::register("obsidian", BlockFactory::get(49)); + self::register("orange_carpet", BlockFactory::get(171, 1)); + self::register("orange_concrete", BlockFactory::get(236, 1)); + self::register("orange_concrete_powder", BlockFactory::get(237, 1)); + self::register("orange_glazed_terracotta", BlockFactory::get(221, 2)); + self::register("orange_stained_clay", BlockFactory::get(159, 1)); + self::register("orange_stained_glass", BlockFactory::get(241, 1)); + self::register("orange_stained_glass_pane", BlockFactory::get(160, 1)); + self::register("orange_tulip", BlockFactory::get(38, 5)); + self::register("orange_wool", BlockFactory::get(35, 1)); + self::register("oxeye_daisy", BlockFactory::get(38, 8)); + self::register("packed_ice", BlockFactory::get(174)); + self::register("peony", BlockFactory::get(175, 5)); + self::register("pink_carpet", BlockFactory::get(171, 6)); + self::register("pink_concrete", BlockFactory::get(236, 6)); + self::register("pink_concrete_powder", BlockFactory::get(237, 6)); + self::register("pink_glazed_terracotta", BlockFactory::get(226, 2)); + self::register("pink_stained_clay", BlockFactory::get(159, 6)); + self::register("pink_stained_glass", BlockFactory::get(241, 6)); + self::register("pink_stained_glass_pane", BlockFactory::get(160, 6)); + self::register("pink_tulip", BlockFactory::get(38, 7)); + self::register("pink_wool", BlockFactory::get(35, 6)); + self::register("podzol", BlockFactory::get(243)); + self::register("polished_andesite", BlockFactory::get(1, 6)); + self::register("polished_andesite_slab", BlockFactory::get(417, 2)); + self::register("polished_andesite_stairs", BlockFactory::get(429)); + self::register("polished_diorite", BlockFactory::get(1, 4)); + self::register("polished_diorite_slab", BlockFactory::get(417, 5)); + self::register("polished_diorite_stairs", BlockFactory::get(428)); + self::register("polished_granite", BlockFactory::get(1, 2)); + self::register("polished_granite_slab", BlockFactory::get(417, 7)); + self::register("polished_granite_stairs", BlockFactory::get(427)); + self::register("poppy", BlockFactory::get(38)); + self::register("potatoes", BlockFactory::get(142)); + self::register("powered_rail", BlockFactory::get(27)); + self::register("prismarine", BlockFactory::get(168)); + self::register("prismarine_bricks", BlockFactory::get(168, 2)); + self::register("prismarine_bricks_slab", BlockFactory::get(182, 4)); + self::register("prismarine_bricks_stairs", BlockFactory::get(259)); + self::register("prismarine_slab", BlockFactory::get(182, 2)); + self::register("prismarine_stairs", BlockFactory::get(257)); + self::register("prismarine_wall", BlockFactory::get(139, 11)); + self::register("pumpkin", BlockFactory::get(86)); + self::register("pumpkin_stem", BlockFactory::get(104)); + self::register("purple_carpet", BlockFactory::get(171, 10)); + self::register("purple_concrete", BlockFactory::get(236, 10)); + self::register("purple_concrete_powder", BlockFactory::get(237, 10)); + self::register("purple_glazed_terracotta", BlockFactory::get(219, 2)); + self::register("purple_stained_clay", BlockFactory::get(159, 10)); + self::register("purple_stained_glass", BlockFactory::get(241, 10)); + self::register("purple_stained_glass_pane", BlockFactory::get(160, 10)); + self::register("purple_torch", BlockFactory::get(204, 13)); + self::register("purple_wool", BlockFactory::get(35, 10)); + self::register("purpur", BlockFactory::get(201)); + self::register("purpur_pillar", BlockFactory::get(201, 2)); + self::register("purpur_slab", BlockFactory::get(182, 1)); + self::register("purpur_stairs", BlockFactory::get(203)); + self::register("quartz", BlockFactory::get(155)); + self::register("quartz_pillar", BlockFactory::get(155, 2)); + self::register("quartz_slab", BlockFactory::get(44, 6)); + self::register("quartz_stairs", BlockFactory::get(156)); + self::register("rail", BlockFactory::get(66)); + self::register("red_carpet", BlockFactory::get(171, 14)); + self::register("red_concrete", BlockFactory::get(236, 14)); + self::register("red_concrete_powder", BlockFactory::get(237, 14)); + self::register("red_glazed_terracotta", BlockFactory::get(234, 2)); + self::register("red_mushroom", BlockFactory::get(40)); + self::register("red_mushroom_block", BlockFactory::get(100)); + self::register("red_nether_brick_slab", BlockFactory::get(182, 7)); + self::register("red_nether_brick_stairs", BlockFactory::get(439)); + self::register("red_nether_brick_wall", BlockFactory::get(139, 13)); + self::register("red_nether_bricks", BlockFactory::get(215)); + self::register("red_sand", BlockFactory::get(12, 1)); + self::register("red_sandstone", BlockFactory::get(179)); + self::register("red_sandstone_slab", BlockFactory::get(182)); + self::register("red_sandstone_stairs", BlockFactory::get(180)); + self::register("red_sandstone_wall", BlockFactory::get(139, 12)); + self::register("red_stained_clay", BlockFactory::get(159, 14)); + self::register("red_stained_glass", BlockFactory::get(241, 14)); + self::register("red_stained_glass_pane", BlockFactory::get(160, 14)); + self::register("red_torch", BlockFactory::get(202, 5)); + self::register("red_tulip", BlockFactory::get(38, 4)); + self::register("red_wool", BlockFactory::get(35, 14)); + self::register("redstone", BlockFactory::get(152)); + self::register("redstone_comparator", BlockFactory::get(149)); + self::register("redstone_lamp", BlockFactory::get(123)); + self::register("redstone_ore", BlockFactory::get(73)); + self::register("redstone_repeater", BlockFactory::get(93)); + self::register("redstone_torch", BlockFactory::get(76, 5)); + self::register("redstone_wire", BlockFactory::get(55)); + self::register("reserved6", BlockFactory::get(255)); + self::register("rose_bush", BlockFactory::get(175, 4)); + self::register("sand", BlockFactory::get(12)); + self::register("sandstone", BlockFactory::get(24)); + self::register("sandstone_slab", BlockFactory::get(44, 1)); + self::register("sandstone_stairs", BlockFactory::get(128)); + self::register("sandstone_wall", BlockFactory::get(139, 5)); + self::register("sea_lantern", BlockFactory::get(169)); + self::register("sea_pickle", BlockFactory::get(411)); + self::register("slightly_damaged_anvil", BlockFactory::get(145, 4)); + self::register("smooth_quartz", BlockFactory::get(155, 3)); + self::register("smooth_quartz_slab", BlockFactory::get(421, 1)); + self::register("smooth_quartz_stairs", BlockFactory::get(440)); + self::register("smooth_red_sandstone", BlockFactory::get(179, 3)); + self::register("smooth_red_sandstone_slab", BlockFactory::get(417, 1)); + self::register("smooth_red_sandstone_stairs", BlockFactory::get(431)); + self::register("smooth_sandstone", BlockFactory::get(24, 3)); + self::register("smooth_sandstone_slab", BlockFactory::get(182, 6)); + self::register("smooth_sandstone_stairs", BlockFactory::get(432)); + self::register("smooth_stone", BlockFactory::get(438)); + self::register("smooth_stone_slab", BlockFactory::get(44)); + self::register("snow", BlockFactory::get(80)); + self::register("snow_layer", BlockFactory::get(78)); + self::register("soul_sand", BlockFactory::get(88)); + self::register("sponge", BlockFactory::get(19)); + self::register("spruce_button", BlockFactory::get(399)); + self::register("spruce_door", BlockFactory::get(193)); + self::register("spruce_fence", BlockFactory::get(85, 1)); + self::register("spruce_fence_gate", BlockFactory::get(183)); + self::register("spruce_leaves", BlockFactory::get(18, 1)); + self::register("spruce_log", BlockFactory::get(17, 1)); + self::register("spruce_planks", BlockFactory::get(5, 1)); + self::register("spruce_pressure_plate", BlockFactory::get(409)); + self::register("spruce_sapling", BlockFactory::get(6, 1)); + self::register("spruce_sign", BlockFactory::get(436)); + self::register("spruce_slab", BlockFactory::get(158, 1)); + self::register("spruce_stairs", BlockFactory::get(134)); + self::register("spruce_trapdoor", BlockFactory::get(404)); + self::register("spruce_wood", BlockFactory::get(467, 1)); + self::register("stone", BlockFactory::get(1)); + self::register("stone_brick_slab", BlockFactory::get(44, 5)); + self::register("stone_brick_stairs", BlockFactory::get(109)); + self::register("stone_brick_wall", BlockFactory::get(139, 7)); + self::register("stone_bricks", BlockFactory::get(98)); + self::register("stone_button", BlockFactory::get(77)); + self::register("stone_pressure_plate", BlockFactory::get(70)); + self::register("stone_slab", BlockFactory::get(421, 2)); + self::register("stone_stairs", BlockFactory::get(435)); + self::register("sugarcane", BlockFactory::get(83)); + self::register("sunflower", BlockFactory::get(175)); + self::register("tall_grass", BlockFactory::get(31, 1)); + self::register("tnt", BlockFactory::get(46)); + self::register("torch", BlockFactory::get(50, 5)); + self::register("trapped_chest", BlockFactory::get(146, 2)); + self::register("tripwire", BlockFactory::get(132)); + self::register("tripwire_hook", BlockFactory::get(131)); + self::register("underwater_torch", BlockFactory::get(239, 5)); + self::register("very_damaged_anvil", BlockFactory::get(145, 8)); + self::register("vines", BlockFactory::get(106)); + self::register("water", BlockFactory::get(8)); + self::register("weighted_pressure_plate_heavy", BlockFactory::get(148)); + self::register("weighted_pressure_plate_light", BlockFactory::get(147)); + self::register("wheat", BlockFactory::get(59)); + self::register("white_carpet", BlockFactory::get(171)); + self::register("white_concrete", BlockFactory::get(236)); + self::register("white_concrete_powder", BlockFactory::get(237)); + self::register("white_glazed_terracotta", BlockFactory::get(220, 2)); + self::register("white_stained_clay", BlockFactory::get(159)); + self::register("white_stained_glass", BlockFactory::get(241)); + self::register("white_stained_glass_pane", BlockFactory::get(160)); + self::register("white_tulip", BlockFactory::get(38, 6)); + self::register("white_wool", BlockFactory::get(35)); + self::register("yellow_carpet", BlockFactory::get(171, 4)); + self::register("yellow_concrete", BlockFactory::get(236, 4)); + self::register("yellow_concrete_powder", BlockFactory::get(237, 4)); + self::register("yellow_glazed_terracotta", BlockFactory::get(224, 2)); + self::register("yellow_stained_clay", BlockFactory::get(159, 4)); + self::register("yellow_stained_glass", BlockFactory::get(241, 4)); + self::register("yellow_stained_glass_pane", BlockFactory::get(160, 4)); + self::register("yellow_wool", BlockFactory::get(35, 4)); } - - //endregion } diff --git a/src/pocketmine/utils/EnumTrait.php b/src/pocketmine/utils/EnumTrait.php index a933580237..9563225f97 100644 --- a/src/pocketmine/utils/EnumTrait.php +++ b/src/pocketmine/utils/EnumTrait.php @@ -23,16 +23,14 @@ declare(strict_types=1); namespace pocketmine\utils; -use function count; -use function implode; use function preg_match; -use function sprintf; -use function strtoupper; trait EnumTrait{ - - /** @var self[] */ - private static $members = null; + use RegistryTrait { + fromString as private Registry_fromString; + getAll as private Registry_getAll; + register as private Registry_register; + } /** * Registers the given object as an enum member. @@ -42,11 +40,7 @@ trait EnumTrait{ * @throws \InvalidArgumentException */ protected static function register(self $member) : void{ - $name = strtoupper($member->name()); - if(isset(self::$members[$name])){ - throw new \InvalidArgumentException("Enum member name \"$name\" is already reserved"); - } - self::$members[strtoupper($member->name())] = $member; + self::Registry_register($member->name(), $member); } /** @@ -63,7 +57,7 @@ trait EnumTrait{ * * @throws \InvalidArgumentException */ - private static function checkInit() : void{ + protected static function checkInit() : void{ if(self::$members === null){ self::$members = []; foreach(self::setup() as $item){ @@ -73,84 +67,26 @@ trait EnumTrait{ } /** - * @param string $name + * Returns all members of the enum. + * This is overridden to change the return typehint. * - * @return self - * @throws \InvalidArgumentException - */ - public static function fromString(string $name) : self{ - self::checkInit(); - $name = strtoupper($name); - if(!isset(self::$members[$name])){ - throw new \InvalidArgumentException("Undefined enum member: " . self::class . "::" . $name); - } - return self::$members[$name]; - } - - /** - * @param string $name - * @param array $arguments - * - * @return self - */ - public static function __callStatic($name, $arguments){ - if(!empty($arguments)){ - throw new \ArgumentCountError("Expected exactly 0 arguments, " . count($arguments) . " passed"); - } - try{ - return self::fromString($name); - }catch(\InvalidArgumentException $e){ - throw new \Error($e->getMessage(), 0, $e); - } - } - - /** * @return self[] */ public static function getAll() : array{ - self::checkInit(); - return self::$members; + return self::Registry_getAll(); } /** - * Generates code for static methods for all known enum members. + * Returns the enum member matching the given name. + * This is overridden to change the return typehint. * - * @return string - */ - public static function _generateGetters() : string{ - $lines = []; - - static $fnTmpl = ' -public static function %1$s() : self{ - return self::fromString("%1$s"); -}'; - - foreach(self::getAll() as $name => $member){ - $lines[] = sprintf($fnTmpl, $name); - } - return "/* --- auto-generated code start --- */\n" . implode("\n", $lines) . "\n\n/* --- auto-generated code end --- */\n"; - } - - /** - * Generates a block of @ method annotations for accessors for this enum's known members. + * @param string $name * - * @return string + * @return self + * @throws \InvalidArgumentException if no member matches. */ - public static function _generateMethodAnnotations() : string{ - $traitName = (new \ReflectionClass(__TRAIT__))->getShortName(); - $fnName = (new \ReflectionMethod(__METHOD__))->getShortName(); - $lines = ["/**"]; - $lines[] = " * This doc-block is generated automatically, do not modify it manually."; - $lines[] = " * This must be regenerated whenever enum members are added, removed or changed."; - $lines[] = " * @see $traitName::$fnName()"; - $lines[] = " *"; - static $lineTmpl = " * @method static self %s()"; - - foreach(self::getAll() as $name => $member){ - $lines[] = sprintf($lineTmpl, $name); - } - $lines[] = " */\n"; - return implode("\n", $lines); + public static function fromString(string $name) : self{ + return self::Registry_fromString($name); } /** @var string */ diff --git a/src/pocketmine/utils/RegistryTrait.php b/src/pocketmine/utils/RegistryTrait.php new file mode 100644 index 0000000000..d1e57e521f --- /dev/null +++ b/src/pocketmine/utils/RegistryTrait.php @@ -0,0 +1,168 @@ +getMessage(), 0, $e); + } + } + + /** + * @return object[] + */ + public static function getAll() : array{ + self::checkInit(); + return self::$members; + } + + /** + * Generates code for static methods for all known registry members. + * + * @return string + */ + public static function _generateGetters() : string{ + $lines = []; + + static $fnTmpl = ' +public static function %1$s() : %2$s{ + return self::fromString("%1$s"); +}'; + + foreach(self::getAll() as $name => $member){ + $lines[] = sprintf($fnTmpl, $name, '\\' . get_class($member)); + } + return "//region auto-generated code\n" . implode("\n", $lines) . "\n\n//endregion\n"; + } + + /** + * Generates a block of @ method annotations for accessors for this registry's known members. + * + * @return string + */ + public static function _generateMethodAnnotations() : string{ + $traitName = (new \ReflectionClass(__TRAIT__))->getShortName(); + $fnName = (new \ReflectionMethod(__METHOD__))->getShortName(); + $lines = ["/**"]; + $lines[] = " * This doc-block is generated automatically, do not modify it manually."; + $lines[] = " * This must be regenerated whenever registry members are added, removed or changed."; + $lines[] = " * @see $traitName::$fnName()"; + $lines[] = " *"; + static $lineTmpl = " * @method static %2\$s %s()"; + + $thisNamespace = (new \ReflectionClass(__CLASS__))->getNamespaceName(); + foreach(self::getAll() as $name => $member){ + $reflect = new \ReflectionClass($member); + while($reflect !== false and $reflect->isAnonymous()){ + $reflect = $reflect->getParentClass(); + } + if($reflect === false){ + $typehint = "object"; + }elseif($reflect->getName() === __CLASS__){ + $typehint = "self"; + }elseif(strpos($reflect->getName(), $thisNamespace) === 0){ + $typehint = substr($reflect->getName(), strlen($thisNamespace . '\\')); + }else{ + $typehint = '\\' . $reflect->getName(); + } + $lines[] = sprintf($lineTmpl, $name, $typehint); + } + $lines[] = " */\n"; + return implode("\n", $lines); + } +} From 08e1f6405cebb25fa3a4756b174a3ef982dee5dd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 9 Jul 2019 17:56:09 +0100 Subject: [PATCH 1078/3224] implemented Carved Pumpkin --- src/pocketmine/block/BlockFactory.php | 11 ++++++++--- .../block/{Pumpkin.php => CarvedPumpkin.php} | 6 +----- src/pocketmine/block/LitPumpkin.php | 2 +- src/pocketmine/block/VanillaBlocks.php | 4 +++- .../block/block_factory_consistency_check.json | 2 +- 5 files changed, 14 insertions(+), 11 deletions(-) rename src/pocketmine/block/{Pumpkin.php => CarvedPumpkin.php} (87%) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 456977150c..9fa8ebd31e 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -229,7 +229,6 @@ class BlockFactory{ self::register(new LapisOre(new BID(Ids::LAPIS_ORE), "Lapis Lazuli Ore")); self::register(new Lava(new BIDFlattened(Ids::FLOWING_LAVA, Ids::STILL_LAVA), "Lava")); self::register(new Lever(new BID(Ids::LEVER), "Lever")); - self::register(new LitPumpkin(new BID(Ids::JACK_O_LANTERN), "Jack o'Lantern")); self::register(new Magma(new BID(Ids::MAGMA), "Magma Block")); self::register(new Melon(new BID(Ids::MELON_BLOCK), "Melon Block")); self::register(new MelonStem(new BID(Ids::MELON_STEM, 0, ItemIds::MELON_SEEDS), "Melon Stem")); @@ -263,7 +262,14 @@ class BlockFactory{ self::register(new Solid(new BID(Ids::PRISMARINE, Meta::PRISMARINE_NORMAL), "Prismarine", $prismarineBreakInfo)); self::register(new Stair(new BID(Ids::PRISMARINE_STAIRS), "Prismarine Stairs", $prismarineBreakInfo)); - self::register(new Pumpkin(new BID(Ids::PUMPKIN), "Pumpkin")); + $pumpkinBreakInfo = new BlockBreakInfo(1.0, BlockToolType::AXE); + self::register($pumpkin = new Solid(new BID(Ids::PUMPKIN), "Pumpkin", $pumpkinBreakInfo)); + for($i = 1; $i <= 3; ++$i){ + self::remap(Ids::PUMPKIN, $i, $pumpkin); + } + self::register(new CarvedPumpkin(new BID(Ids::CARVED_PUMPKIN), "Carved Pumpkin", $pumpkinBreakInfo)); + self::register(new LitPumpkin(new BID(Ids::JACK_O_LANTERN), "Jack o'Lantern", $pumpkinBreakInfo)); + self::register(new PumpkinStem(new BID(Ids::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem")); $purpurBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0); @@ -569,7 +575,6 @@ class BlockFactory{ //TODO: minecraft:bubble_column //TODO: minecraft:campfire //TODO: minecraft:cartography_table - //TODO: minecraft:carved_pumpkin //TODO: minecraft:cauldron //TODO: minecraft:chain_command_block //TODO: minecraft:chemical_heat diff --git a/src/pocketmine/block/Pumpkin.php b/src/pocketmine/block/CarvedPumpkin.php similarity index 87% rename from src/pocketmine/block/Pumpkin.php rename to src/pocketmine/block/CarvedPumpkin.php index 568b366f12..8c3f66a72e 100644 --- a/src/pocketmine/block/Pumpkin.php +++ b/src/pocketmine/block/CarvedPumpkin.php @@ -31,15 +31,11 @@ use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\world\BlockTransaction; -class Pumpkin extends Solid{ +class CarvedPumpkin extends Solid{ /** @var int */ protected $facing = Facing::NORTH; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0, BlockToolType::AXE)); - } - public function readStateFromData(int $id, int $stateMeta) : void{ $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); } diff --git a/src/pocketmine/block/LitPumpkin.php b/src/pocketmine/block/LitPumpkin.php index dbc173bf93..5f555402a6 100644 --- a/src/pocketmine/block/LitPumpkin.php +++ b/src/pocketmine/block/LitPumpkin.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -class LitPumpkin extends Pumpkin{ +class LitPumpkin extends CarvedPumpkin{ public function getLightLevel() : int{ return 15; diff --git a/src/pocketmine/block/VanillaBlocks.php b/src/pocketmine/block/VanillaBlocks.php index fa1d662095..1b595551c0 100644 --- a/src/pocketmine/block/VanillaBlocks.php +++ b/src/pocketmine/block/VanillaBlocks.php @@ -113,6 +113,7 @@ use function assert; * @method static Cactus CACTUS() * @method static Cake CAKE() * @method static Carrot CARROTS() + * @method static CarvedPumpkin CARVED_PUMPKIN() * @method static Chest CHEST() * @method static Solid CHISELED_QUARTZ() * @method static Solid CHISELED_RED_SANDSTONE() @@ -533,7 +534,7 @@ use function assert; * @method static Slab PRISMARINE_SLAB() * @method static Stair PRISMARINE_STAIRS() * @method static Wall PRISMARINE_WALL() - * @method static Pumpkin PUMPKIN() + * @method static Solid PUMPKIN() * @method static PumpkinStem PUMPKIN_STEM() * @method static Carpet PURPLE_CARPET() * @method static Concrete PURPLE_CONCRETE() @@ -777,6 +778,7 @@ final class VanillaBlocks{ self::register("cactus", BlockFactory::get(81)); self::register("cake", BlockFactory::get(92)); self::register("carrots", BlockFactory::get(141)); + self::register("carved_pumpkin", BlockFactory::get(410)); self::register("chest", BlockFactory::get(54, 2)); self::register("chiseled_quartz", BlockFactory::get(155, 1)); self::register("chiseled_red_sandstone", BlockFactory::get(179, 1)); diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 8a0686ba9f..ff32e629c2 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From 41705db68753cd7299c12be6821054d14ba59f49 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 9 Jul 2019 18:21:08 +0100 Subject: [PATCH 1079/3224] fix banner block picking --- src/pocketmine/block/Banner.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/block/Banner.php b/src/pocketmine/block/Banner.php index 85f499f6db..89d28a2ec6 100644 --- a/src/pocketmine/block/Banner.php +++ b/src/pocketmine/block/Banner.php @@ -31,6 +31,7 @@ use pocketmine\block\utils\DyeColor; use pocketmine\item\Banner as ItemBanner; use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\item\ItemIds; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -165,8 +166,12 @@ class Banner extends Transparent{ } } + public function asItem() : Item{ + return ItemFactory::get(ItemIds::BANNER, $this->baseColor->getInvertedMagicNumber()); + } + public function getDropsForCompatibleTool(Item $item) : array{ - $drop = ItemFactory::get(Item::BANNER, $this->baseColor->getInvertedMagicNumber()); + $drop = $this->asItem(); if($drop instanceof ItemBanner and !$this->patterns->isEmpty()){ $drop->setPatterns($this->patterns); } @@ -174,6 +179,14 @@ class Banner extends Transparent{ return [$drop]; } + public function getPickedItem(bool $addUserData = false) : Item{ + $result = $this->asItem(); + if($addUserData and $result instanceof ItemBanner and !$this->patterns->isEmpty()){ + $result->setPatterns($this->patterns); + } + return $result; + } + public function isAffectedBySilkTouch() : bool{ return false; } From e8fe3d066443ab60c344e6e67ad19d5103daace5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 9 Jul 2019 18:30:02 +0100 Subject: [PATCH 1080/3224] Replace some ItemFactory blockitem fetches with VanillaBlocks::THING()->asItem() --- src/pocketmine/block/BlockFactory.php | 15 +++++++-------- src/pocketmine/block/EnderChest.php | 3 +-- src/pocketmine/block/Farmland.php | 5 ++--- src/pocketmine/block/Grass.php | 3 +-- src/pocketmine/block/GrassPath.php | 3 +-- src/pocketmine/block/Mycelium.php | 3 +-- 6 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 9fa8ebd31e..c757bad175 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -49,7 +49,6 @@ use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\block\utils\PillarRotationTrait; use pocketmine\block\utils\TreeType; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\item\ItemIds; use pocketmine\item\TieredTool; use pocketmine\world\Position; @@ -185,32 +184,32 @@ class BlockFactory{ self::register(new Ice(new BID(Ids::ICE), "Ice")); self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE), "Infested Stone") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ - return [ItemFactory::get(ItemIds::STONE)]; + return [VanillaBlocks::STONE()->asItem()]; } }); self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_COBBLESTONE), "Infested Cobblestone") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ - return [ItemFactory::get(ItemIds::COBBLESTONE)]; + return [VanillaBlocks::COBBLESTONE()->asItem()]; } }); self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK), "Infested Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ - return [ItemFactory::get(ItemIds::STONE_BRICK)]; + return [VanillaBlocks::STONE_BRICKS()->asItem()]; } }); self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_MOSSY), "Infested Mossy Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ - return [ItemFactory::get(ItemIds::STONE_BRICK, Meta::STONE_BRICK_MOSSY)]; + return [VanillaBlocks::MOSSY_STONE_BRICKS()->asItem()]; } }); self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CRACKED), "Infested Cracked Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ - return [ItemFactory::get(ItemIds::STONE_BRICK, Meta::STONE_BRICK_CRACKED)]; + return [VanillaBlocks::CRACKED_STONE_BRICKS()->asItem()]; } }); self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CHISELED), "Infested Chiseled Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ - return [ItemFactory::get(ItemIds::STONE_BRICK, Meta::STONE_BRICK_CHISELED)]; + return [VanillaBlocks::CHISELED_STONE_BRICKS()->asItem()]; } }); @@ -318,7 +317,7 @@ class BlockFactory{ $stoneBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0); self::register(new class(new BID(Ids::STONE, Meta::STONE_NORMAL), "Stone", $stoneBreakInfo) extends Solid{ public function getDropsForCompatibleTool(Item $item) : array{ - return [ItemFactory::get(Item::COBBLESTONE)]; + return [VanillaBlocks::COBBLESTONE()->asItem()]; } }); self::register(new Stair(new BID(Ids::NORMAL_STONE_STAIRS), "Stone Stairs", $stoneBreakInfo)); diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index 4902b46f41..e68c11ef46 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -26,7 +26,6 @@ namespace pocketmine\block; use pocketmine\block\tile\EnderChest as TileEnderChest; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -85,7 +84,7 @@ class EnderChest extends Transparent{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::OBSIDIAN, 0, 8) + VanillaBlocks::OBSIDIAN()->asItem()->setCount(8) ]; } } diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index 2dfc1f8ab5..67dafa0efa 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -25,7 +25,6 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -97,7 +96,7 @@ class Farmland extends Transparent{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::DIRT) + VanillaBlocks::DIRT()->asItem() ]; } @@ -106,6 +105,6 @@ class Farmland extends Transparent{ } public function getPickedItem(bool $addUserData = false) : Item{ - return ItemFactory::get(Item::DIRT); + return VanillaBlocks::DIRT()->asItem(); } } diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index fe852a0129..25b9188e46 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -27,7 +27,6 @@ use pocketmine\event\block\BlockSpreadEvent; use pocketmine\item\Fertilizer; use pocketmine\item\Hoe; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\item\Shovel; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -44,7 +43,7 @@ class Grass extends Solid{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::DIRT) + VanillaBlocks::DIRT()->asItem() ]; } diff --git a/src/pocketmine/block/GrassPath.php b/src/pocketmine/block/GrassPath.php index e6e003429d..4861cc1f61 100644 --- a/src/pocketmine/block/GrassPath.php +++ b/src/pocketmine/block/GrassPath.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -46,7 +45,7 @@ class GrassPath extends Transparent{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::DIRT) + VanillaBlocks::DIRT()->asItem() ]; } } diff --git a/src/pocketmine/block/Mycelium.php b/src/pocketmine/block/Mycelium.php index 1fb34909e9..fa1a4e12e8 100644 --- a/src/pocketmine/block/Mycelium.php +++ b/src/pocketmine/block/Mycelium.php @@ -25,7 +25,6 @@ namespace pocketmine\block; use pocketmine\event\block\BlockSpreadEvent; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\math\Facing; use function mt_rand; @@ -37,7 +36,7 @@ class Mycelium extends Solid{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::DIRT) + VanillaBlocks::DIRT()->asItem() ]; } From 39bcd2ec3d441588ca4053fe21f7b6ed4b1b50f7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 10 Jul 2019 14:44:55 +0100 Subject: [PATCH 1081/3224] added VanillaItems static interface and start using it where possible --- src/pocketmine/block/Beetroot.php | 10 +- src/pocketmine/block/Bookshelf.php | 4 +- src/pocketmine/block/Carrot.php | 6 +- src/pocketmine/block/Clay.php | 4 +- src/pocketmine/block/CoalOre.php | 4 +- src/pocketmine/block/Cobweb.php | 4 +- src/pocketmine/block/CocoaBlock.php | 6 +- src/pocketmine/block/DeadBush.php | 4 +- src/pocketmine/block/DiamondOre.php | 4 +- src/pocketmine/block/DoubleTallGrass.php | 4 +- src/pocketmine/block/EmeraldOre.php | 4 +- src/pocketmine/block/Glowstone.php | 4 +- src/pocketmine/block/Gravel.php | 4 +- src/pocketmine/block/LapisOre.php | 4 +- src/pocketmine/block/Leaves.php | 3 +- src/pocketmine/block/Melon.php | 4 +- src/pocketmine/block/NetherQuartzOre.php | 4 +- src/pocketmine/block/NetherReactor.php | 6 +- src/pocketmine/block/Potato.php | 6 +- src/pocketmine/block/RedstoneOre.php | 4 +- src/pocketmine/block/SeaLantern.php | 4 +- src/pocketmine/block/Snow.php | 4 +- src/pocketmine/block/SnowLayer.php | 4 +- src/pocketmine/block/TallGrass.php | 4 +- src/pocketmine/block/Wheat.php | 10 +- .../command/defaults/ParticleCommand.php | 6 +- src/pocketmine/entity/Squid.php | 5 +- src/pocketmine/entity/Zombie.php | 11 +- src/pocketmine/entity/object/Painting.php | 5 +- src/pocketmine/entity/projectile/Arrow.php | 5 +- src/pocketmine/entity/projectile/Egg.php | 5 +- src/pocketmine/item/BeetrootSoup.php | 2 +- src/pocketmine/item/Bow.php | 5 +- src/pocketmine/item/LiquidBucket.php | 2 +- src/pocketmine/item/MilkBucket.php | 2 +- src/pocketmine/item/MushroomStew.php | 2 +- src/pocketmine/item/Potion.php | 2 +- src/pocketmine/item/RabbitStew.php | 2 +- src/pocketmine/item/VanillaItems.php | 587 ++++++++++++++++++ 39 files changed, 672 insertions(+), 88 deletions(-) create mode 100644 src/pocketmine/item/VanillaItems.php diff --git a/src/pocketmine/block/Beetroot.php b/src/pocketmine/block/Beetroot.php index 418f16a4ee..51d05688e8 100644 --- a/src/pocketmine/block/Beetroot.php +++ b/src/pocketmine/block/Beetroot.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; use function mt_rand; class Beetroot extends Crops{ @@ -32,17 +32,17 @@ class Beetroot extends Crops{ public function getDropsForCompatibleTool(Item $item) : array{ if($this->age >= 7){ return [ - ItemFactory::get(Item::BEETROOT), - ItemFactory::get(Item::BEETROOT_SEEDS, 0, mt_rand(0, 3)) + VanillaItems::BEETROOT(), + VanillaItems::BEETROOT_SEEDS()->setCount(mt_rand(0, 3)) ]; } return [ - ItemFactory::get(Item::BEETROOT_SEEDS) + VanillaItems::BEETROOT_SEEDS() ]; } public function getPickedItem(bool $addUserData = false) : Item{ - return ItemFactory::get(Item::BEETROOT_SEEDS); + return VanillaItems::BEETROOT_SEEDS(); } } diff --git a/src/pocketmine/block/Bookshelf.php b/src/pocketmine/block/Bookshelf.php index aa49940c39..64844f5d6a 100644 --- a/src/pocketmine/block/Bookshelf.php +++ b/src/pocketmine/block/Bookshelf.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; class Bookshelf extends Solid{ @@ -34,7 +34,7 @@ class Bookshelf extends Solid{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::BOOK, 0, 3) + VanillaItems::BOOK() ]; } diff --git a/src/pocketmine/block/Carrot.php b/src/pocketmine/block/Carrot.php index e344351116..612b967f60 100644 --- a/src/pocketmine/block/Carrot.php +++ b/src/pocketmine/block/Carrot.php @@ -24,18 +24,18 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; use function mt_rand; class Carrot extends Crops{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::CARROT, 0, $this->age >= 7 ? mt_rand(1, 4) : 1) + VanillaItems::CARROT()->setCount($this->age >= 7 ? mt_rand(1, 4) : 1) ]; } public function getPickedItem(bool $addUserData = false) : Item{ - return ItemFactory::get(Item::CARROT); + return VanillaItems::CARROT(); } } diff --git a/src/pocketmine/block/Clay.php b/src/pocketmine/block/Clay.php index 277e700f74..41560db3ba 100644 --- a/src/pocketmine/block/Clay.php +++ b/src/pocketmine/block/Clay.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; class Clay extends Solid{ @@ -34,7 +34,7 @@ class Clay extends Solid{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::CLAY_BALL, 0, 4) + VanillaItems::CLAY()->setCount(4) ]; } } diff --git a/src/pocketmine/block/CoalOre.php b/src/pocketmine/block/CoalOre.php index 45a693ee48..b1e58e177c 100644 --- a/src/pocketmine/block/CoalOre.php +++ b/src/pocketmine/block/CoalOre.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; +use pocketmine\item\VanillaItems; use function mt_rand; class CoalOre extends Solid{ @@ -36,7 +36,7 @@ class CoalOre extends Solid{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::COAL) + VanillaItems::COAL() ]; } diff --git a/src/pocketmine/block/Cobweb.php b/src/pocketmine/block/Cobweb.php index 012c2cf9d4..82c42422de 100644 --- a/src/pocketmine/block/Cobweb.php +++ b/src/pocketmine/block/Cobweb.php @@ -25,7 +25,7 @@ namespace pocketmine\block; use pocketmine\entity\Entity; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; class Cobweb extends Flowable{ @@ -43,7 +43,7 @@ class Cobweb extends Flowable{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::STRING) + VanillaItems::STRING() ]; } diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index 2995390d70..f1ae2a808e 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -27,7 +27,7 @@ use pocketmine\block\utils\BlockDataValidator; use pocketmine\block\utils\TreeType; use pocketmine\item\Fertilizer; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; use pocketmine\math\Facing; @@ -115,11 +115,11 @@ class CocoaBlock extends Transparent{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::DYE, 3, $this->age === 2 ? mt_rand(2, 3) : 1) + VanillaItems::COCOA_BEANS()->setCount($this->age === 2 ? mt_rand(2, 3) : 1) ]; } public function getPickedItem(bool $addUserData = false) : Item{ - return ItemFactory::get(Item::DYE, 3); //cocoa beans + return VanillaItems::COCOA_BEANS(); } } diff --git a/src/pocketmine/block/DeadBush.php b/src/pocketmine/block/DeadBush.php index 0239a7afb0..49a6c809e7 100644 --- a/src/pocketmine/block/DeadBush.php +++ b/src/pocketmine/block/DeadBush.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -54,7 +54,7 @@ class DeadBush extends Flowable{ public function getDrops(Item $item) : array{ if(!$this->breakInfo->isToolCompatible($item)){ return [ - ItemFactory::get(Item::STICK, 0, mt_rand(0, 2)) + VanillaItems::STICK()->setCount(mt_rand(0, 2)) ]; } diff --git a/src/pocketmine/block/DiamondOre.php b/src/pocketmine/block/DiamondOre.php index 546e292542..1a03923df3 100644 --- a/src/pocketmine/block/DiamondOre.php +++ b/src/pocketmine/block/DiamondOre.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; +use pocketmine\item\VanillaItems; use function mt_rand; class DiamondOre extends Solid{ @@ -36,7 +36,7 @@ class DiamondOre extends Solid{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::DIAMOND) + VanillaItems::DIAMOND() ]; } diff --git a/src/pocketmine/block/DoubleTallGrass.php b/src/pocketmine/block/DoubleTallGrass.php index 662b4ca269..dedf3dc5f7 100644 --- a/src/pocketmine/block/DoubleTallGrass.php +++ b/src/pocketmine/block/DoubleTallGrass.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; use function mt_rand; class DoubleTallGrass extends DoublePlant{ @@ -40,7 +40,7 @@ class DoubleTallGrass extends DoublePlant{ public function getDrops(Item $item) : array{ if($this->top and !$this->breakInfo->isToolCompatible($item) and mt_rand(0, 7) === 0){ return [ - ItemFactory::get(Item::SEEDS) + VanillaItems::WHEAT_SEEDS() ]; } return parent::getDrops($item); diff --git a/src/pocketmine/block/EmeraldOre.php b/src/pocketmine/block/EmeraldOre.php index 178b34e2e7..0170efc313 100644 --- a/src/pocketmine/block/EmeraldOre.php +++ b/src/pocketmine/block/EmeraldOre.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; +use pocketmine\item\VanillaItems; use function mt_rand; class EmeraldOre extends Solid{ @@ -36,7 +36,7 @@ class EmeraldOre extends Solid{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::EMERALD) + VanillaItems::EMERALD() ]; } diff --git a/src/pocketmine/block/Glowstone.php b/src/pocketmine/block/Glowstone.php index 9b8501fdb2..47785dd722 100644 --- a/src/pocketmine/block/Glowstone.php +++ b/src/pocketmine/block/Glowstone.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; use function mt_rand; class Glowstone extends Transparent{ @@ -39,7 +39,7 @@ class Glowstone extends Transparent{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::GLOWSTONE_DUST, 0, mt_rand(2, 4)) + VanillaItems::GLOWSTONE_DUST()->setCount(mt_rand(2, 4)) ]; } } diff --git a/src/pocketmine/block/Gravel.php b/src/pocketmine/block/Gravel.php index 2303883609..a93173ffbd 100644 --- a/src/pocketmine/block/Gravel.php +++ b/src/pocketmine/block/Gravel.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\block\utils\Fallable; use pocketmine\block\utils\FallableTrait; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; use function mt_rand; class Gravel extends Solid implements Fallable{ @@ -39,7 +39,7 @@ class Gravel extends Solid implements Fallable{ public function getDropsForCompatibleTool(Item $item) : array{ if(mt_rand(1, 10) === 1){ return [ - ItemFactory::get(Item::FLINT) + VanillaItems::FLINT() ]; } diff --git a/src/pocketmine/block/LapisOre.php b/src/pocketmine/block/LapisOre.php index b401b9c6bf..97a5666b6b 100644 --- a/src/pocketmine/block/LapisOre.php +++ b/src/pocketmine/block/LapisOre.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; +use pocketmine\item\VanillaItems; use function mt_rand; class LapisOre extends Solid{ @@ -36,7 +36,7 @@ class LapisOre extends Solid{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::DYE, 4, mt_rand(4, 8)) + VanillaItems::LAPIS_LAZULI()->setCount(mt_rand(4, 8)) ]; } diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 864f0e3d3f..7f0a871ab4 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -27,6 +27,7 @@ use pocketmine\block\utils\TreeType; use pocketmine\event\block\LeavesDecayEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -127,7 +128,7 @@ class Leaves extends Transparent{ $drops[] = ItemFactory::get(Item::SAPLING, $this->treeType->getMagicNumber()); } if(($this->treeType->equals(TreeType::OAK()) or $this->treeType->equals(TreeType::DARK_OAK())) and mt_rand(1, 200) === 1){ //Apples - $drops[] = ItemFactory::get(Item::APPLE); + $drops[] = VanillaItems::APPLE(); } return $drops; diff --git a/src/pocketmine/block/Melon.php b/src/pocketmine/block/Melon.php index ee5424ce8c..40bc3a8777 100644 --- a/src/pocketmine/block/Melon.php +++ b/src/pocketmine/block/Melon.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; use function mt_rand; class Melon extends Transparent{ @@ -35,7 +35,7 @@ class Melon extends Transparent{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::MELON_SLICE, 0, mt_rand(3, 7)) + VanillaItems::MELON()->setCount(mt_rand(3, 7)) ]; } } diff --git a/src/pocketmine/block/NetherQuartzOre.php b/src/pocketmine/block/NetherQuartzOre.php index f8d4ebdfe4..54efd1a336 100644 --- a/src/pocketmine/block/NetherQuartzOre.php +++ b/src/pocketmine/block/NetherQuartzOre.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; +use pocketmine\item\VanillaItems; use function mt_rand; class NetherQuartzOre extends Solid{ @@ -36,7 +36,7 @@ class NetherQuartzOre extends Solid{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::QUARTZ) + VanillaItems::NETHER_QUARTZ() ]; } diff --git a/src/pocketmine/block/NetherReactor.php b/src/pocketmine/block/NetherReactor.php index 47f8048d24..a18907e94e 100644 --- a/src/pocketmine/block/NetherReactor.php +++ b/src/pocketmine/block/NetherReactor.php @@ -25,8 +25,8 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; +use pocketmine\item\VanillaItems; class NetherReactor extends Solid{ @@ -51,8 +51,8 @@ class NetherReactor extends Solid{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::IRON_INGOT, 0, 6), - ItemFactory::get(Item::DIAMOND, 0, 3) + VanillaItems::IRON_INGOT()->setCount(6), + VanillaItems::DIAMOND()->setCount(3) ]; } } diff --git a/src/pocketmine/block/Potato.php b/src/pocketmine/block/Potato.php index 937c17ecae..06ac93f81f 100644 --- a/src/pocketmine/block/Potato.php +++ b/src/pocketmine/block/Potato.php @@ -24,18 +24,18 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; use function mt_rand; class Potato extends Crops{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::POTATO, 0, $this->age >= 7 ? mt_rand(1, 4) : 1) + VanillaItems::POTATO()->setCount($this->age >= 7 ? mt_rand(1, 4) : 1) ]; } public function getPickedItem(bool $addUserData = false) : Item{ - return ItemFactory::get(Item::POTATO); + return VanillaItems::POTATO(); } } diff --git a/src/pocketmine/block/RedstoneOre.php b/src/pocketmine/block/RedstoneOre.php index b4b42873c3..11b8664240 100644 --- a/src/pocketmine/block/RedstoneOre.php +++ b/src/pocketmine/block/RedstoneOre.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; +use pocketmine\item\VanillaItems; use pocketmine\math\Vector3; use pocketmine\player\Player; use function mt_rand; @@ -95,7 +95,7 @@ class RedstoneOre extends Solid{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::REDSTONE_DUST, 0, mt_rand(4, 5)) + VanillaItems::REDSTONE_DUST()->setCount(mt_rand(4, 5)) ]; } diff --git a/src/pocketmine/block/SeaLantern.php b/src/pocketmine/block/SeaLantern.php index bd0c068731..a076fc02d4 100644 --- a/src/pocketmine/block/SeaLantern.php +++ b/src/pocketmine/block/SeaLantern.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; class SeaLantern extends Transparent{ @@ -38,7 +38,7 @@ class SeaLantern extends Transparent{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::PRISMARINE_CRYSTALS, 0, 3) + VanillaItems::PRISMARINE_CRYSTALS()->setCount(3) ]; } } diff --git a/src/pocketmine/block/Snow.php b/src/pocketmine/block/Snow.php index b88474ce18..22279086c0 100644 --- a/src/pocketmine/block/Snow.php +++ b/src/pocketmine/block/Snow.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; +use pocketmine\item\VanillaItems; class Snow extends Solid{ @@ -35,7 +35,7 @@ class Snow extends Solid{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::SNOWBALL, 0, 4) + VanillaItems::SNOWBALL()->setCount(4) ]; } } diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index 7023691da3..d861c02971 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -27,8 +27,8 @@ use pocketmine\block\utils\BlockDataValidator; use pocketmine\block\utils\Fallable; use pocketmine\block\utils\FallableTrait; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\item\TieredTool; +use pocketmine\item\VanillaItems; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -99,7 +99,7 @@ class SnowLayer extends Flowable implements Fallable{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::SNOWBALL, 0, max(1, (int) floor($this->layers / 2))) + VanillaItems::SNOWBALL()->setCount(max(1, (int) floor($this->layers / 2))) ]; } diff --git a/src/pocketmine/block/TallGrass.php b/src/pocketmine/block/TallGrass.php index bdc093688d..9e984c1c41 100644 --- a/src/pocketmine/block/TallGrass.php +++ b/src/pocketmine/block/TallGrass.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -63,7 +63,7 @@ class TallGrass extends Flowable{ if(mt_rand(0, 15) === 0){ return [ - ItemFactory::get(Item::WHEAT_SEEDS) + VanillaItems::WHEAT_SEEDS() ]; } diff --git a/src/pocketmine/block/Wheat.php b/src/pocketmine/block/Wheat.php index 664f565a67..5261e38ecd 100644 --- a/src/pocketmine/block/Wheat.php +++ b/src/pocketmine/block/Wheat.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; use function mt_rand; class Wheat extends Crops{ @@ -32,17 +32,17 @@ class Wheat extends Crops{ public function getDropsForCompatibleTool(Item $item) : array{ if($this->age >= 7){ return [ - ItemFactory::get(Item::WHEAT), - ItemFactory::get(Item::WHEAT_SEEDS, 0, mt_rand(0, 3)) + VanillaItems::WHEAT(), + VanillaItems::WHEAT_SEEDS()->setCount(mt_rand(0, 3)) ]; }else{ return [ - ItemFactory::get(Item::WHEAT_SEEDS) + VanillaItems::WHEAT_SEEDS() ]; } } public function getPickedItem(bool $addUserData = false) : Item{ - return ItemFactory::get(Item::WHEAT_SEEDS); + return VanillaItems::WHEAT_SEEDS(); } } diff --git a/src/pocketmine/command/defaults/ParticleCommand.php b/src/pocketmine/command/defaults/ParticleCommand.php index 9a04c845f9..22afc6dc67 100644 --- a/src/pocketmine/command/defaults/ParticleCommand.php +++ b/src/pocketmine/command/defaults/ParticleCommand.php @@ -26,8 +26,8 @@ namespace pocketmine\command\defaults; use pocketmine\block\BlockFactory; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; -use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -180,9 +180,9 @@ class ParticleCommand extends VanillaCommand{ case "reddust": return new RedstoneParticle($data ?? 1); case "snowballpoof": - return new ItemBreakParticle(ItemFactory::get(Item::SNOWBALL)); + return new ItemBreakParticle(VanillaItems::SNOWBALL()); case "slime": - return new ItemBreakParticle(ItemFactory::get(Item::SLIMEBALL)); + return new ItemBreakParticle(VanillaItems::SLIMEBALL()); case "itembreak": if($data !== null and $data !== 0){ return new ItemBreakParticle(ItemFactory::get($data)); diff --git a/src/pocketmine/entity/Squid.php b/src/pocketmine/entity/Squid.php index 465975f54d..4fb95b268b 100644 --- a/src/pocketmine/entity/Squid.php +++ b/src/pocketmine/entity/Squid.php @@ -25,8 +25,7 @@ namespace pocketmine\entity; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; -use pocketmine\item\Item; -use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\EntityEventPacket; @@ -121,7 +120,7 @@ class Squid extends WaterAnimal{ public function getDrops() : array{ return [ - ItemFactory::get(Item::DYE, 0, mt_rand(1, 3)) + VanillaItems::INK_SAC()->setCount(mt_rand(1, 3)) ]; } } diff --git a/src/pocketmine/entity/Zombie.php b/src/pocketmine/entity/Zombie.php index 1a0078d3f1..3eb7f391be 100644 --- a/src/pocketmine/entity/Zombie.php +++ b/src/pocketmine/entity/Zombie.php @@ -23,8 +23,7 @@ declare(strict_types=1); namespace pocketmine\entity; -use pocketmine\item\Item; -use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; use function mt_rand; class Zombie extends Living{ @@ -39,19 +38,19 @@ class Zombie extends Living{ public function getDrops() : array{ $drops = [ - ItemFactory::get(Item::ROTTEN_FLESH, 0, mt_rand(0, 2)) + VanillaItems::ROTTEN_FLESH()->setCount(mt_rand(0, 2)) ]; if(mt_rand(0, 199) < 5){ switch(mt_rand(0, 2)){ case 0: - $drops[] = ItemFactory::get(Item::IRON_INGOT, 0, 1); + $drops[] = VanillaItems::IRON_INGOT(); break; case 1: - $drops[] = ItemFactory::get(Item::CARROT, 0, 1); + $drops[] = VanillaItems::CARROT(); break; case 2: - $drops[] = ItemFactory::get(Item::POTATO, 0, 1); + $drops[] = VanillaItems::POTATO(); break; } } diff --git a/src/pocketmine/entity/object/Painting.php b/src/pocketmine/entity/object/Painting.php index 9be7bc43d4..0f734a4c1c 100644 --- a/src/pocketmine/entity/object/Painting.php +++ b/src/pocketmine/entity/object/Painting.php @@ -26,8 +26,7 @@ namespace pocketmine\entity\object; use pocketmine\block\VanillaBlocks; use pocketmine\entity\Entity; use pocketmine\event\entity\EntityDamageByEntityEvent; -use pocketmine\item\Item; -use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; use pocketmine\math\Facing; @@ -106,7 +105,7 @@ class Painting extends Entity{ if($drops){ //non-living entities don't have a way to create drops generically yet - $this->world->dropItem($this, ItemFactory::get(Item::PAINTING)); + $this->world->dropItem($this, VanillaItems::PAINTING()); } $this->world->addParticle($this->add(0.5, 0.5, 0.5), new DestroyBlockParticle(VanillaBlocks::OAK_PLANKS())); } diff --git a/src/pocketmine/entity/projectile/Arrow.php b/src/pocketmine/entity/projectile/Arrow.php index ddc39e3a83..b9c55dc795 100644 --- a/src/pocketmine/entity/projectile/Arrow.php +++ b/src/pocketmine/entity/projectile/Arrow.php @@ -27,8 +27,7 @@ use pocketmine\block\Block; use pocketmine\entity\Entity; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\event\inventory\InventoryPickupArrowEvent; -use pocketmine\item\Item; -use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; use pocketmine\math\RayTraceResult; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\EntityEventPacket; @@ -177,7 +176,7 @@ class Arrow extends Projectile{ return; } - $item = ItemFactory::get(Item::ARROW, 0, 1); + $item = VanillaItems::ARROW(); $playerInventory = $player->getInventory(); if($player->hasFiniteResources() and !$playerInventory->canAddItem($item)){ diff --git a/src/pocketmine/entity/projectile/Egg.php b/src/pocketmine/entity/projectile/Egg.php index f643220b25..91d8019787 100644 --- a/src/pocketmine/entity/projectile/Egg.php +++ b/src/pocketmine/entity/projectile/Egg.php @@ -24,8 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity\projectile; use pocketmine\event\entity\ProjectileHitEvent; -use pocketmine\item\Item; -use pocketmine\item\ItemFactory; +use pocketmine\item\VanillaItems; use pocketmine\world\particle\ItemBreakParticle; class Egg extends Throwable{ @@ -35,7 +34,7 @@ class Egg extends Throwable{ protected function onHit(ProjectileHitEvent $event) : void{ for($i = 0; $i < 6; ++$i){ - $this->world->addParticle($this, new ItemBreakParticle(ItemFactory::get(Item::EGG))); + $this->world->addParticle($this, new ItemBreakParticle(VanillaItems::EGG())); } } } diff --git a/src/pocketmine/item/BeetrootSoup.php b/src/pocketmine/item/BeetrootSoup.php index ab274c9259..8f8e5bed1e 100644 --- a/src/pocketmine/item/BeetrootSoup.php +++ b/src/pocketmine/item/BeetrootSoup.php @@ -39,6 +39,6 @@ class BeetrootSoup extends Food{ } public function getResidue(){ - return ItemFactory::get(Item::BOWL); + return VanillaItems::BOWL(); } } diff --git a/src/pocketmine/item/Bow.php b/src/pocketmine/item/Bow.php index 5410844464..0cc6b4f9a4 100644 --- a/src/pocketmine/item/Bow.php +++ b/src/pocketmine/item/Bow.php @@ -45,7 +45,8 @@ class Bow extends Tool{ } public function onReleaseUsing(Player $player) : ItemUseResult{ - if($player->hasFiniteResources() and !$player->getInventory()->contains(ItemFactory::get(Item::ARROW, 0, 1))){ + $arrow = VanillaItems::ARROW(); + if($player->hasFiniteResources() and !$player->getInventory()->contains($arrow)){ return ItemUseResult::FAIL(); } @@ -110,7 +111,7 @@ class Bow extends Tool{ if($player->hasFiniteResources()){ if(!$infinity){ //TODO: tipped arrows are still consumed when Infinity is applied - $player->getInventory()->removeItem(ItemFactory::get(Item::ARROW, 0, 1)); + $player->getInventory()->removeItem($arrow); } $this->applyDamage(1); } diff --git a/src/pocketmine/item/LiquidBucket.php b/src/pocketmine/item/LiquidBucket.php index 4d2d7d7910..8c466f1573 100644 --- a/src/pocketmine/item/LiquidBucket.php +++ b/src/pocketmine/item/LiquidBucket.php @@ -60,7 +60,7 @@ class LiquidBucket extends Item{ //TODO: move this to generic placement logic $resultBlock = clone $this->liquid; - $ev = new PlayerBucketEmptyEvent($player, $blockReplace, $face, $this, ItemFactory::get(Item::BUCKET)); + $ev = new PlayerBucketEmptyEvent($player, $blockReplace, $face, $this, VanillaItems::BUCKET()); $ev->call(); if(!$ev->isCancelled()){ $player->getWorld()->setBlock($blockReplace, $resultBlock->getFlowingForm()); diff --git a/src/pocketmine/item/MilkBucket.php b/src/pocketmine/item/MilkBucket.php index 592308f634..dbdedab937 100644 --- a/src/pocketmine/item/MilkBucket.php +++ b/src/pocketmine/item/MilkBucket.php @@ -32,7 +32,7 @@ class MilkBucket extends Item implements Consumable{ } public function getResidue(){ - return ItemFactory::get(Item::BUCKET, 0, 1); + return VanillaItems::BUCKET(); } public function getAdditionalEffects() : array{ diff --git a/src/pocketmine/item/MushroomStew.php b/src/pocketmine/item/MushroomStew.php index b71dcc1b8a..08a3220628 100644 --- a/src/pocketmine/item/MushroomStew.php +++ b/src/pocketmine/item/MushroomStew.php @@ -38,6 +38,6 @@ class MushroomStew extends Food{ } public function getResidue(){ - return ItemFactory::get(Item::BOWL); + return VanillaItems::BOWL(); } } diff --git a/src/pocketmine/item/Potion.php b/src/pocketmine/item/Potion.php index 9cb0ecd0cd..c45ac84ea3 100644 --- a/src/pocketmine/item/Potion.php +++ b/src/pocketmine/item/Potion.php @@ -269,6 +269,6 @@ class Potion extends Item implements Consumable{ } public function getResidue(){ - return ItemFactory::get(Item::GLASS_BOTTLE); + return VanillaItems::GLASS_BOTTLE(); } } diff --git a/src/pocketmine/item/RabbitStew.php b/src/pocketmine/item/RabbitStew.php index 239973d8a1..6117a0be14 100644 --- a/src/pocketmine/item/RabbitStew.php +++ b/src/pocketmine/item/RabbitStew.php @@ -38,6 +38,6 @@ class RabbitStew extends Food{ } public function getResidue(){ - return ItemFactory::get(Item::BOWL); + return VanillaItems::BOWL(); } } diff --git a/src/pocketmine/item/VanillaItems.php b/src/pocketmine/item/VanillaItems.php new file mode 100644 index 0000000000..2a5f44e24f --- /dev/null +++ b/src/pocketmine/item/VanillaItems.php @@ -0,0 +1,587 @@ + Date: Thu, 11 Jul 2019 14:14:01 +0100 Subject: [PATCH 1082/3224] Bookshelf: fix drop count --- src/pocketmine/block/Bookshelf.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/Bookshelf.php b/src/pocketmine/block/Bookshelf.php index 64844f5d6a..fba6053e36 100644 --- a/src/pocketmine/block/Bookshelf.php +++ b/src/pocketmine/block/Bookshelf.php @@ -34,7 +34,7 @@ class Bookshelf extends Solid{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::BOOK() + VanillaItems::BOOK()->setCount(3) ]; } From 1391e4826fb8f49705c7893c629d71787c5bc3c3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 13 Jul 2019 19:21:00 +0100 Subject: [PATCH 1083/3224] ItemFactory: fix name consistency gold -> golden, close #3020 --- src/pocketmine/item/ItemFactory.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index b122778c89..22199d7bcc 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -58,7 +58,7 @@ class ItemFactory{ self::register(new Apple(Item::APPLE, 0, "Apple")); self::register(new Arrow(Item::ARROW, 0, "Arrow")); self::register(new Axe(Item::DIAMOND_AXE, "Diamond Axe", TieredTool::TIER_DIAMOND)); - self::register(new Axe(Item::GOLDEN_AXE, "Gold Axe", TieredTool::TIER_GOLD)); + self::register(new Axe(Item::GOLDEN_AXE, "Golden Axe", TieredTool::TIER_GOLD)); self::register(new Axe(Item::IRON_AXE, "Iron Axe", TieredTool::TIER_IRON)); self::register(new Axe(Item::STONE_AXE, "Stone Axe", TieredTool::TIER_STONE)); self::register(new Axe(Item::WOODEN_AXE, "Wooden Axe", TieredTool::TIER_WOODEN)); @@ -70,7 +70,7 @@ class ItemFactory{ self::register(new Book(Item::BOOK, 0, "Book")); self::register(new Boots(Item::CHAIN_BOOTS, 0, "Chainmail Boots", new ArmorTypeInfo(1, 196))); self::register(new Boots(Item::DIAMOND_BOOTS, 0, "Diamond Boots", new ArmorTypeInfo(3, 430))); - self::register(new Boots(Item::GOLDEN_BOOTS, 0, "Gold Boots", new ArmorTypeInfo(1, 92))); + self::register(new Boots(Item::GOLDEN_BOOTS, 0, "Golden Boots", new ArmorTypeInfo(1, 92))); self::register(new Boots(Item::IRON_BOOTS, 0, "Iron Boots", new ArmorTypeInfo(2, 196))); self::register(new Boots(Item::LEATHER_BOOTS, 0, "Leather Boots", new ArmorTypeInfo(1, 66))); self::register(new Bow(Item::BOW, 0, "Bow")); @@ -80,7 +80,7 @@ class ItemFactory{ self::register(new Carrot(Item::CARROT, 0, "Carrot")); self::register(new Chestplate(Item::CHAIN_CHESTPLATE, 0, "Chainmail Chestplate", new ArmorTypeInfo(5, 241))); self::register(new Chestplate(Item::DIAMOND_CHESTPLATE, 0, "Diamond Chestplate", new ArmorTypeInfo(8, 529))); - self::register(new Chestplate(Item::GOLDEN_CHESTPLATE, 0, "Gold Chestplate", new ArmorTypeInfo(5, 113))); + self::register(new Chestplate(Item::GOLDEN_CHESTPLATE, 0, "Golden Chestplate", new ArmorTypeInfo(5, 113))); self::register(new Chestplate(Item::IRON_CHESTPLATE, 0, "Iron Chestplate", new ArmorTypeInfo(6, 241))); self::register(new Chestplate(Item::LEATHER_CHESTPLATE, 0, "Leather Tunic", new ArmorTypeInfo(3, 81))); self::register(new ChorusFruit(Item::CHORUS_FRUIT, 0, "Chorus Fruit")); @@ -110,7 +110,7 @@ class ItemFactory{ self::register(new GoldenCarrot(Item::GOLDEN_CARROT, 0, "Golden Carrot")); self::register(new Helmet(Item::CHAIN_HELMET, 0, "Chainmail Helmet", new ArmorTypeInfo(2, 166))); self::register(new Helmet(Item::DIAMOND_HELMET, 0, "Diamond Helmet", new ArmorTypeInfo(3, 364))); - self::register(new Helmet(Item::GOLDEN_HELMET, 0, "Gold Helmet", new ArmorTypeInfo(2, 78))); + self::register(new Helmet(Item::GOLDEN_HELMET, 0, "Golden Helmet", new ArmorTypeInfo(2, 78))); self::register(new Helmet(Item::IRON_HELMET, 0, "Iron Helmet", new ArmorTypeInfo(2, 166))); self::register(new Helmet(Item::LEATHER_HELMET, 0, "Leather Cap", new ArmorTypeInfo(1, 56))); self::register(new Hoe(Item::DIAMOND_HOE, "Diamond Hoe", TieredTool::TIER_DIAMOND)); @@ -214,7 +214,7 @@ class ItemFactory{ self::register(new ItemBlock(BlockLegacyIds::SUGARCANE_BLOCK, 0, Item::SUGARCANE)); self::register(new Leggings(Item::CHAIN_LEGGINGS, 0, "Chainmail Leggings", new ArmorTypeInfo(4, 226))); self::register(new Leggings(Item::DIAMOND_LEGGINGS, 0, "Diamond Leggings", new ArmorTypeInfo(6, 496))); - self::register(new Leggings(Item::GOLDEN_LEGGINGS, 0, "Gold Leggings", new ArmorTypeInfo(3, 106))); + self::register(new Leggings(Item::GOLDEN_LEGGINGS, 0, "Golden Leggings", new ArmorTypeInfo(3, 106))); self::register(new Leggings(Item::IRON_LEGGINGS, 0, "Iron Leggings", new ArmorTypeInfo(5, 226))); self::register(new Leggings(Item::LEATHER_LEGGINGS, 0, "Leather Pants", new ArmorTypeInfo(2, 76))); //TODO: fix metadata for buckets with still liquid in them @@ -228,7 +228,7 @@ class ItemFactory{ self::register(new MushroomStew(Item::MUSHROOM_STEW, 0, "Mushroom Stew")); self::register(new PaintingItem(Item::PAINTING, 0, "Painting")); self::register(new Pickaxe(Item::DIAMOND_PICKAXE, "Diamond Pickaxe", TieredTool::TIER_DIAMOND)); - self::register(new Pickaxe(Item::GOLDEN_PICKAXE, "Gold Pickaxe", TieredTool::TIER_GOLD)); + self::register(new Pickaxe(Item::GOLDEN_PICKAXE, "Golden Pickaxe", TieredTool::TIER_GOLD)); self::register(new Pickaxe(Item::IRON_PICKAXE, "Iron Pickaxe", TieredTool::TIER_IRON)); self::register(new Pickaxe(Item::STONE_PICKAXE, "Stone Pickaxe", TieredTool::TIER_STONE)); self::register(new Pickaxe(Item::WOODEN_PICKAXE, "Wooden Pickaxe", TieredTool::TIER_WOODEN)); @@ -249,7 +249,7 @@ class ItemFactory{ self::register(new RottenFlesh(Item::ROTTEN_FLESH, 0, "Rotten Flesh")); self::register(new Shears(Item::SHEARS, 0, "Shears")); self::register(new Shovel(Item::DIAMOND_SHOVEL, "Diamond Shovel", TieredTool::TIER_DIAMOND)); - self::register(new Shovel(Item::GOLDEN_SHOVEL, "Gold Shovel", TieredTool::TIER_GOLD)); + self::register(new Shovel(Item::GOLDEN_SHOVEL, "Golden Shovel", TieredTool::TIER_GOLD)); self::register(new Shovel(Item::IRON_SHOVEL, "Iron Shovel", TieredTool::TIER_IRON)); self::register(new Shovel(Item::STONE_SHOVEL, "Stone Shovel", TieredTool::TIER_STONE)); self::register(new Shovel(Item::WOODEN_SHOVEL, "Wooden Shovel", TieredTool::TIER_WOODEN)); @@ -265,7 +265,7 @@ class ItemFactory{ self::register(new Stick(Item::STICK, 0, "Stick")); self::register(new StringItem(Item::STRING, 0, "String")); self::register(new Sword(Item::DIAMOND_SWORD, "Diamond Sword", TieredTool::TIER_DIAMOND)); - self::register(new Sword(Item::GOLDEN_SWORD, "Gold Sword", TieredTool::TIER_GOLD)); + self::register(new Sword(Item::GOLDEN_SWORD, "Golden Sword", TieredTool::TIER_GOLD)); self::register(new Sword(Item::IRON_SWORD, "Iron Sword", TieredTool::TIER_IRON)); self::register(new Sword(Item::STONE_SWORD, "Stone Sword", TieredTool::TIER_STONE)); self::register(new Sword(Item::WOODEN_SWORD, "Wooden Sword", TieredTool::TIER_WOODEN)); From f637f14e4af8d649bfb712ede06149a21a7f7326 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 13 Jul 2019 19:24:17 +0100 Subject: [PATCH 1084/3224] VanillaItems: fixing gold -> golden --- src/pocketmine/item/VanillaItems.php | 32 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/pocketmine/item/VanillaItems.php b/src/pocketmine/item/VanillaItems.php index 2a5f44e24f..aed8749ddd 100644 --- a/src/pocketmine/item/VanillaItems.php +++ b/src/pocketmine/item/VanillaItems.php @@ -151,19 +151,19 @@ use function assert; * @method static GlassBottle GLASS_BOTTLE() * @method static Item GLISTERING_MELON() * @method static Item GLOWSTONE_DUST() - * @method static Axe GOLD_AXE() - * @method static Boots GOLD_BOOTS() - * @method static Chestplate GOLD_CHESTPLATE() - * @method static Helmet GOLD_HELMET() * @method static Item GOLD_INGOT() - * @method static Leggings GOLD_LEGGINGS() * @method static Item GOLD_NUGGET() - * @method static Pickaxe GOLD_PICKAXE() - * @method static Shovel GOLD_SHOVEL() - * @method static Sword GOLD_SWORD() * @method static GoldenApple GOLDEN_APPLE() + * @method static Axe GOLDEN_AXE() + * @method static Boots GOLDEN_BOOTS() * @method static GoldenCarrot GOLDEN_CARROT() + * @method static Chestplate GOLDEN_CHESTPLATE() + * @method static Helmet GOLDEN_HELMET() * @method static Hoe GOLDEN_HOE() + * @method static Leggings GOLDEN_LEGGINGS() + * @method static Pickaxe GOLDEN_PICKAXE() + * @method static Shovel GOLDEN_SHOVEL() + * @method static Sword GOLDEN_SWORD() * @method static Banner GRAY_BANNER() * @method static Bed GRAY_BED() * @method static Dye GRAY_DYE() @@ -444,19 +444,19 @@ final class VanillaItems{ self::register("glass_bottle", ItemFactory::get(374)); self::register("glistering_melon", ItemFactory::get(382)); self::register("glowstone_dust", ItemFactory::get(348)); - self::register("gold_axe", ItemFactory::get(286)); - self::register("gold_boots", ItemFactory::get(317)); - self::register("gold_chestplate", ItemFactory::get(315)); - self::register("gold_helmet", ItemFactory::get(314)); self::register("gold_ingot", ItemFactory::get(266)); - self::register("gold_leggings", ItemFactory::get(316)); self::register("gold_nugget", ItemFactory::get(371)); - self::register("gold_pickaxe", ItemFactory::get(285)); - self::register("gold_shovel", ItemFactory::get(284)); - self::register("gold_sword", ItemFactory::get(283)); self::register("golden_apple", ItemFactory::get(322)); + self::register("golden_axe", ItemFactory::get(286)); + self::register("golden_boots", ItemFactory::get(317)); self::register("golden_carrot", ItemFactory::get(396)); + self::register("golden_chestplate", ItemFactory::get(315)); + self::register("golden_helmet", ItemFactory::get(314)); self::register("golden_hoe", ItemFactory::get(294)); + self::register("golden_leggings", ItemFactory::get(316)); + self::register("golden_pickaxe", ItemFactory::get(285)); + self::register("golden_shovel", ItemFactory::get(284)); + self::register("golden_sword", ItemFactory::get(283)); self::register("gray_banner", ItemFactory::get(446, 8)); self::register("gray_bed", ItemFactory::get(355, 7)); self::register("gray_dye", ItemFactory::get(351, 8)); From 484f2f43c0437acdf38d87097691be9eef206d40 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 14 Jul 2019 19:29:16 +0100 Subject: [PATCH 1085/3224] fixed merge error, close #3030 --- src/pocketmine/network/mcpe/protocol/AddActorPacket.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/network/mcpe/protocol/AddActorPacket.php b/src/pocketmine/network/mcpe/protocol/AddActorPacket.php index c97a93590d..d5686658a5 100644 --- a/src/pocketmine/network/mcpe/protocol/AddActorPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddActorPacket.php @@ -35,7 +35,7 @@ use function array_search; use function count; class AddActorPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::ADD_ENTITY_PACKET; + public const NETWORK_ID = ProtocolInfo::ADD_ACTOR_PACKET; /* * Really really really really really nasty hack, to preserve backwards compatibility. From 52de5a6e49fa18a44049e04453204f2e65a92f55 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 16 Jul 2019 14:27:32 +0100 Subject: [PATCH 1086/3224] Removed remaining usages of Item::get() --- src/pocketmine/block/BrownMushroomBlock.php | 2 +- src/pocketmine/block/RedMushroomBlock.php | 2 +- src/pocketmine/network/mcpe/handler/InGamePacketHandler.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/block/BrownMushroomBlock.php b/src/pocketmine/block/BrownMushroomBlock.php index ac94d565ca..09b183491b 100644 --- a/src/pocketmine/block/BrownMushroomBlock.php +++ b/src/pocketmine/block/BrownMushroomBlock.php @@ -30,7 +30,7 @@ class BrownMushroomBlock extends RedMushroomBlock{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - Item::get(Item::BROWN_MUSHROOM, 0, mt_rand(0, 2)) + VanillaBlocks::BROWN_MUSHROOM()->asItem()->setCount(mt_rand(0, 2)) ]; } } diff --git a/src/pocketmine/block/RedMushroomBlock.php b/src/pocketmine/block/RedMushroomBlock.php index 68786a7886..c1bbada6a9 100644 --- a/src/pocketmine/block/RedMushroomBlock.php +++ b/src/pocketmine/block/RedMushroomBlock.php @@ -55,7 +55,7 @@ class RedMushroomBlock extends Solid{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - Item::get(Item::RED_MUSHROOM, 0, mt_rand(0, 2)) + VanillaBlocks::RED_MUSHROOM()->asItem()->setCount(mt_rand(0, 2)) ]; } } diff --git a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php index 7a21f2b9ea..f6bc0d5579 100644 --- a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php @@ -31,7 +31,7 @@ use pocketmine\inventory\transaction\action\InventoryAction; use pocketmine\inventory\transaction\CraftingTransaction; use pocketmine\inventory\transaction\InventoryTransaction; use pocketmine\inventory\transaction\TransactionValidationException; -use pocketmine\item\Item; +use pocketmine\item\VanillaItems; use pocketmine\item\WritableBook; use pocketmine\item\WrittenBook; use pocketmine\math\Vector3; @@ -640,7 +640,7 @@ class InGamePacketHandler extends PacketHandler{ break; case BookEditPacket::TYPE_SIGN_BOOK: /** @var WrittenBook $newBook */ - $newBook = Item::get(Item::WRITTEN_BOOK, 0, 1, $newBook->getNamedTag()); + $newBook = VanillaItems::WRITTEN_BOOK()->setNamedTag($oldBook->getNamedTag()); $newBook->setAuthor($packet->author); $newBook->setTitle($packet->title); $newBook->setGeneration(WrittenBook::GENERATION_ORIGINAL); From d624c38ab1faee568e768566619a19a724ad2803 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 16 Jul 2019 14:31:04 +0100 Subject: [PATCH 1087/3224] Remove dead proxy functions Item::get(), Block::get() and Item::fromString() with the introduction of the VanillaBlocks and VanillaItems API, it's expected that plugins will no longer need these methods. --- src/pocketmine/block/Block.php | 15 --------------- src/pocketmine/item/Item.php | 30 ------------------------------ 2 files changed, 45 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 13f4f43a20..f4882508ad 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -51,21 +51,6 @@ use const PHP_INT_MAX; class Block extends Position implements BlockLegacyIds{ - /** - * Returns a new Block instance with the specified ID, meta and position. - * - * This function redirects to {@link BlockFactory#get}. - * - * @param int $id - * @param int $meta - * @param Position|null $pos - * - * @return Block - */ - public static function get(int $id, int $meta = 0, ?Position $pos = null) : Block{ - return BlockFactory::get($id, $meta, $pos); - } - /** @var BlockIdentifier */ protected $idInfo; diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index b7bd229ca7..7c9ca68977 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -58,36 +58,6 @@ class Item implements ItemIds, \JsonSerializable{ public const TAG_DISPLAY_NAME = "Name"; public const TAG_DISPLAY_LORE = "Lore"; - /** - * Returns a new Item instance with the specified ID, damage, count and NBT. - * - * This function redirects to {@link ItemFactory#get}. - * - * @param int $id - * @param int $meta - * @param int $count - * @param CompoundTag $tags - * - * @return Item - */ - public static function get(int $id, int $meta = 0, int $count = 1, ?CompoundTag $tags = null) : Item{ - return ItemFactory::get($id, $meta, $count, $tags); - } - - /** - * Tries to parse the specified string into Item types. - * - * This function redirects to {@link ItemFactory#fromString}. - * - * @param string $str - * - * @return Item - * @throws \InvalidArgumentException - */ - public static function fromString(string $str) : Item{ - return ItemFactory::fromString($str); - } - /** @var int */ protected $id; /** @var int */ From 27352486a08ec3bd258469eece3875501a33a848 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 16 Jul 2019 16:51:45 +0100 Subject: [PATCH 1088/3224] Remove item NBT runtime usage, marginalize to serialize/deserialize this is a more tame version of my initial attempt to firehose item NBT. It marginalizes the use of item NBT to the places where it's needed on interfaces, leaving the internals clean to operate on whatever they like. --- src/pocketmine/item/Armor.php | 28 +- src/pocketmine/item/Banner.php | 65 ++-- src/pocketmine/item/Durable.php | 17 +- src/pocketmine/item/Item.php | 382 +++++++++++++---------- src/pocketmine/item/WritableBookBase.php | 130 ++++---- src/pocketmine/item/WritableBookPage.php | 52 +++ src/pocketmine/item/WrittenBook.php | 42 ++- src/pocketmine/world/World.php | 32 +- 8 files changed, 450 insertions(+), 298 deletions(-) create mode 100644 src/pocketmine/item/WritableBookPage.php diff --git a/src/pocketmine/item/Armor.php b/src/pocketmine/item/Armor.php index 99454c8be3..afd880e049 100644 --- a/src/pocketmine/item/Armor.php +++ b/src/pocketmine/item/Armor.php @@ -30,6 +30,7 @@ use pocketmine\inventory\ArmorInventory; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\ProtectionEnchantment; use pocketmine\math\Vector3; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\player\Player; use pocketmine\utils\Binary; @@ -44,6 +45,9 @@ abstract class Armor extends Durable{ /** @var ArmorTypeInfo */ private $armorInfo; + /** @var Color|null */ + protected $customColor = null; + public function __construct(int $id, int $variant, string $name, ArmorTypeInfo $info){ parent::__construct($id, $variant, $name); $this->armorInfo = $info; @@ -72,11 +76,7 @@ abstract class Armor extends Durable{ * @return Color|null */ public function getCustomColor() : ?Color{ - if($this->getNamedTag()->hasTag(self::TAG_CUSTOM_COLOR, IntTag::class)){ - return Color::fromARGB(Binary::unsignInt($this->getNamedTag()->getInt(self::TAG_CUSTOM_COLOR))); - } - - return null; + return $this->customColor; } /** @@ -87,7 +87,7 @@ abstract class Armor extends Durable{ * @return $this */ public function setCustomColor(Color $color) : self{ - $this->getNamedTag()->setInt(self::TAG_CUSTOM_COLOR, Binary::signInt($color->toARGB())); + $this->customColor = $color; return $this; } @@ -137,4 +137,20 @@ abstract class Armor extends Durable{ $player->getArmorInventory()->setItem($this->getArmorSlot(), $this->pop()); return ItemUseResult::SUCCESS(); } + + protected function deserializeCompoundTag(CompoundTag $tag) : void{ + parent::deserializeCompoundTag($tag); + if($tag->hasTag(self::TAG_CUSTOM_COLOR, IntTag::class)){ + $this->customColor = Color::fromARGB(Binary::unsignInt($tag->getInt(self::TAG_CUSTOM_COLOR))); + }else{ + $this->customColor = null; + } + } + + protected function serializeCompoundTag(CompoundTag $tag) : void{ + parent::serializeCompoundTag($tag); + $this->customColor !== null ? + $tag->setInt(self::TAG_CUSTOM_COLOR, Binary::signInt($this->customColor->toARGB())) : + $tag->removeTag(self::TAG_CUSTOM_COLOR); + } } diff --git a/src/pocketmine/item/Banner.php b/src/pocketmine/item/Banner.php index caf0dc8b51..b079844828 100644 --- a/src/pocketmine/item/Banner.php +++ b/src/pocketmine/item/Banner.php @@ -40,9 +40,14 @@ class Banner extends Item{ /** @var DyeColor */ private $color; + /** @var BannerPattern[]|Deque */ + private $patterns; + public function __construct(int $id, int $variant, string $name, DyeColor $color){ parent::__construct($id, $variant, $name); $this->color = $color; + + $this->patterns = new Deque(); } /** @@ -64,15 +69,7 @@ class Banner extends Item{ * @return Deque|BannerPattern[] */ public function getPatterns() : Deque{ - $result = new Deque(); - $tag = $this->getNamedTag()->getListTag(self::TAG_PATTERNS); - if($tag !== null){ - /** @var CompoundTag $t */ - foreach($tag as $t){ - $result->push(new BannerPattern($t->getString(self::TAG_PATTERN_NAME), DyeColor::fromMagicNumber($t->getInt(self::TAG_PATTERN_COLOR), true))); - } - } - return $result; + return $this->patterns; } /** @@ -81,19 +78,51 @@ class Banner extends Item{ * @return $this */ public function setPatterns(Deque $patterns) : self{ - $tag = new ListTag(); - /** @var BannerPattern $pattern */ - foreach($patterns as $pattern){ - $tag->push(CompoundTag::create() - ->setString(self::TAG_PATTERN_NAME, $pattern->getId()) - ->setInt(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) - ); - } - $this->getNamedTag()->setTag(self::TAG_PATTERNS, $tag); + $this->patterns = $patterns; return $this; } public function getFuelTime() : int{ return 300; } + + protected function deserializeCompoundTag(CompoundTag $tag) : void{ + parent::deserializeCompoundTag($tag); + + $this->patterns = new Deque(); + + $patterns = $tag->getListTag(self::TAG_PATTERNS); + if($patterns !== null){ + /** @var CompoundTag $t */ + foreach($patterns as $t){ + $this->patterns->push(new BannerPattern($t->getString(self::TAG_PATTERN_NAME), DyeColor::fromMagicNumber($t->getInt(self::TAG_PATTERN_COLOR), true))); + } + } + } + + protected function serializeCompoundTag(CompoundTag $tag) : void{ + parent::serializeCompoundTag($tag); + + if(!$this->patterns->isEmpty()){ + $patterns = new ListTag(); + /** @var BannerPattern $pattern */ + foreach($this->patterns as $pattern){ + $patterns->push(CompoundTag::create() + ->setString(self::TAG_PATTERN_NAME, $pattern->getId()) + ->setInt(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) + ); + } + + + $tag->setTag(self::TAG_PATTERNS, $patterns); + }else{ + $tag->removeTag(self::TAG_PATTERNS); + } + } + + public function __clone(){ + parent::__clone(); + //we don't need to duplicate the individual patterns because they are immutable + $this->patterns = $this->patterns->copy(); + } } diff --git a/src/pocketmine/item/Durable.php b/src/pocketmine/item/Durable.php index 68e40e87d7..8462e25b21 100644 --- a/src/pocketmine/item/Durable.php +++ b/src/pocketmine/item/Durable.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\item\enchantment\Enchantment; +use pocketmine\nbt\tag\CompoundTag; use function lcg_value; use function min; @@ -31,6 +32,8 @@ abstract class Durable extends Item{ /** @var int */ protected $damage = 0; + /** @var bool */ + private $unbreakable = false; public function getMeta() : int{ return $this->damage; @@ -41,7 +44,7 @@ abstract class Durable extends Item{ * @return bool */ public function isUnbreakable() : bool{ - return $this->getNamedTag()->getByte("Unbreakable", 0) !== 0; + return $this->unbreakable; } /** @@ -52,7 +55,7 @@ abstract class Durable extends Item{ * @return $this */ public function setUnbreakable(bool $value = true) : self{ - $this->getNamedTag()->setByte("Unbreakable", $value ? 1 : 0); + $this->unbreakable = $value; return $this; } @@ -128,4 +131,14 @@ abstract class Durable extends Item{ public function isBroken() : bool{ return $this->damage >= $this->getMaxDurability(); } + + protected function deserializeCompoundTag(CompoundTag $tag) : void{ + parent::deserializeCompoundTag($tag); + $this->unbreakable = $tag->getByte("Unbreakable", 0) !== 0; + } + + protected function serializeCompoundTag(CompoundTag $tag) : void{ + parent::serializeCompoundTag($tag); + $this->unbreakable ? $tag->setByte("Unbreakable", 1) : $tag->removeTag("Unbreakable"); + } } diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 7c9ca68977..31dee6c667 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -26,6 +26,8 @@ declare(strict_types=1); */ namespace pocketmine\item; +use function array_map; +use Ds\Set; use pocketmine\block\Block; use pocketmine\block\BlockBreakInfo; use pocketmine\block\BlockToolType; @@ -44,11 +46,12 @@ use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\TreeRoot; use pocketmine\player\Player; use pocketmine\utils\Binary; -use function array_map; use function base64_decode; use function base64_encode; use function get_class; +use function gettype; use function hex2bin; +use function is_string; class Item implements ItemIds, \JsonSerializable{ public const TAG_ENCH = "ench"; @@ -69,6 +72,25 @@ class Item implements ItemIds, \JsonSerializable{ /** @var string */ protected $name; + //TODO: this stuff should be moved to itemstack properties, not mushed in with type properties + + /** @var EnchantmentInstance[] */ + protected $enchantments = []; + /** @var string */ + protected $customName = ""; + /** @var string[] */ + protected $lore = []; + /** + * TODO: this needs to die in a fire + * @var CompoundTag|null + */ + protected $blockEntityTag = null; + + /** @var Set|string[] */ + protected $canPlaceOn; + /** @var Set|string[] */ + protected $canDestroy; + /** * Constructs a new Item type. This constructor should ONLY be used when constructing a new item TYPE to register * into the index. @@ -87,17 +109,20 @@ class Item implements ItemIds, \JsonSerializable{ $this->id = $id; $this->meta = $variant !== -1 ? $variant & 0x7FFF : -1; $this->name = $name; + + $this->canPlaceOn = new Set(); + $this->canDestroy = new Set(); } /** * @return bool */ public function hasCustomBlockData() : bool{ - return $this->getNamedTag()->hasTag(self::TAG_BLOCK_ENTITY_TAG, CompoundTag::class); + return $this->blockEntityTag !== null; } public function clearCustomBlockData(){ - $this->getNamedTag()->removeTag(self::TAG_BLOCK_ENTITY_TAG); + $this->blockEntityTag = null; return $this; } @@ -107,7 +132,8 @@ class Item implements ItemIds, \JsonSerializable{ * @return Item */ public function setCustomBlockData(CompoundTag $compound) : Item{ - $this->getNamedTag()->setTag(self::TAG_BLOCK_ENTITY_TAG, clone $compound); + $this->blockEntityTag = clone $compound; + return $this; } @@ -115,14 +141,14 @@ class Item implements ItemIds, \JsonSerializable{ * @return CompoundTag|null */ public function getCustomBlockData() : ?CompoundTag{ - return $this->getNamedTag()->getCompoundTag(self::TAG_BLOCK_ENTITY_TAG); + return $this->blockEntityTag; } /** * @return bool */ public function hasEnchantments() : bool{ - return $this->getNamedTag()->hasTag(self::TAG_ENCH, ListTag::class); + return !empty($this->enchantments); } /** @@ -132,20 +158,8 @@ class Item implements ItemIds, \JsonSerializable{ * @return bool */ public function hasEnchantment(Enchantment $enchantment, int $level = -1) : bool{ - $ench = $this->getNamedTag()->getListTag(self::TAG_ENCH); - if(!($ench instanceof ListTag)){ - return false; - } $id = $enchantment->getId(); - - /** @var CompoundTag $entry */ - foreach($ench as $entry){ - if($entry->getShort("id") === $id and ($level === -1 or $entry->getShort("lvl") === $level)){ - return true; - } - } - - return false; + return isset($this->enchantments[$id]) and ($level === -1 or $this->enchantments[$id]->getLevel() === $level); } /** @@ -154,23 +168,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return EnchantmentInstance|null */ public function getEnchantment(Enchantment $enchantment) : ?EnchantmentInstance{ - $ench = $this->getNamedTag()->getListTag(self::TAG_ENCH); - if(!($ench instanceof ListTag)){ - return null; - } - - $id = $enchantment->getId(); - /** @var CompoundTag $entry */ - foreach($ench as $entry){ - if($entry->getShort("id") === $id){ - $e = Enchantment::get($entry->getShort("id")); - if($e !== null){ - return new EnchantmentInstance($e, $entry->getShort("lvl")); - } - } - } - - return null; + return $this->enchantments[$enchantment->getId()] ?? null; } /** @@ -180,18 +178,9 @@ class Item implements ItemIds, \JsonSerializable{ * @return Item */ public function removeEnchantment(Enchantment $enchantment, int $level = -1) : Item{ - $ench = $this->getNamedTag()->getListTag(self::TAG_ENCH); - if(!($ench instanceof ListTag)){ - return $this; - } - - $id = $enchantment->getId(); - /** @var CompoundTag $entry */ - foreach($ench as $k => $entry){ - if($entry->getShort("id") === $id and ($level === -1 or $entry->getShort("lvl") === $level)){ - $ench->remove($k); - break; - } + $instance = $this->getEnchantment($enchantment); + if($instance !== null and ($level === -1 or $instance->getLevel() === $level)){ + unset($this->enchantments[$enchantment->getId()]); } return $this; @@ -201,8 +190,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return Item */ public function removeEnchantments() : Item{ - $this->getNamedTag()->removeTag(self::TAG_ENCH); - + $this->enchantments = []; return $this; } @@ -212,34 +200,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return Item */ public function addEnchantment(EnchantmentInstance $enchantment) : Item{ - $found = false; - - $ench = $this->getNamedTag()->getListTag(self::TAG_ENCH); - if(!($ench instanceof ListTag)){ - $ench = new ListTag([], NBT::TAG_Compound); - }else{ - /** @var CompoundTag $entry */ - foreach($ench as $k => $entry){ - if($entry->getShort("id") === $enchantment->getId()){ - $ench->set($k, CompoundTag::create() - ->setShort("id", $enchantment->getId()) - ->setShort("lvl", $enchantment->getLevel()) - ); - $found = true; - break; - } - } - } - - if(!$found){ - $ench->push(CompoundTag::create() - ->setShort("id", $enchantment->getId()) - ->setShort("lvl", $enchantment->getLevel()) - ); - } - - $this->getNamedTag()->setTag(self::TAG_ENCH, $ench); - + $this->enchantments[$enchantment->getId()] = $enchantment; return $this; } @@ -247,21 +208,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return EnchantmentInstance[] */ public function getEnchantments() : array{ - /** @var EnchantmentInstance[] $enchantments */ - $enchantments = []; - - $ench = $this->getNamedTag()->getListTag(self::TAG_ENCH); - if($ench instanceof ListTag){ - /** @var CompoundTag $entry */ - foreach($ench as $entry){ - $e = Enchantment::get($entry->getShort("id")); - if($e !== null){ - $enchantments[] = new EnchantmentInstance($e, $entry->getShort("lvl")); - } - } - } - - return $enchantments; + return $this->enchantments; } /** @@ -273,42 +220,21 @@ class Item implements ItemIds, \JsonSerializable{ * @return int */ public function getEnchantmentLevel(Enchantment $enchantment) : int{ - $ench = $this->getNamedTag()->getListTag(self::TAG_ENCH); - if($ench !== null){ - /** @var CompoundTag $entry */ - $enchantmentId = $enchantment->getId(); - foreach($ench as $entry){ - if($entry->getShort("id") === $enchantmentId){ - return $entry->getShort("lvl"); - } - } - } - - return 0; + return ($instance = $this->getEnchantment($enchantment)) !== null ? $instance->getLevel() : 0; } /** * @return bool */ public function hasCustomName() : bool{ - $display = $this->getNamedTag()->getCompoundTag(self::TAG_DISPLAY); - if($display instanceof CompoundTag){ - return $display->hasTag(self::TAG_DISPLAY_NAME); - } - - return false; + return $this->customName !== ""; } /** * @return string */ public function getCustomName() : string{ - $display = $this->getNamedTag()->getCompoundTag(self::TAG_DISPLAY); - if($display instanceof CompoundTag){ - return $display->getString(self::TAG_DISPLAY_NAME, ""); - } - - return ""; + return $this->customName; } /** @@ -317,19 +243,8 @@ class Item implements ItemIds, \JsonSerializable{ * @return Item */ public function setCustomName(string $name) : Item{ - if($name === ""){ - $this->clearCustomName(); - } - - /** @var CompoundTag $display */ - $display = $this->getNamedTag()->getCompoundTag(self::TAG_DISPLAY); - if($display === null){ - $display = new CompoundTag(); - } - - $display->setString(self::TAG_DISPLAY_NAME, $name); - $this->getNamedTag()->setTag(self::TAG_DISPLAY, $display); - + //TODO: encoding might need to be checked here + $this->customName = $name; return $this; } @@ -337,17 +252,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return Item */ public function clearCustomName() : Item{ - $display = $this->getNamedTag()->getCompoundTag(self::TAG_DISPLAY); - if($display instanceof CompoundTag){ - $display->removeTag(self::TAG_DISPLAY_NAME); - - if($display->getCount() === 0){ - $this->getNamedTag()->removeTag(self::TAG_DISPLAY); - }else{ - $this->getNamedTag()->setTag(self::TAG_DISPLAY, $display); - } - } - + $this->setCustomName(""); return $this; } @@ -355,12 +260,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return string[] */ public function getLore() : array{ - $display = $this->getNamedTag()->getCompoundTag(self::TAG_DISPLAY); - if($display instanceof CompoundTag and ($lore = $display->getListTag(self::TAG_DISPLAY_LORE)) !== null){ - return $lore->getAllValues(); - } - - return []; + return $this->lore; } /** @@ -369,26 +269,49 @@ class Item implements ItemIds, \JsonSerializable{ * @return Item */ public function setLore(array $lines) : Item{ - $display = $this->getNamedTag()->getCompoundTag(self::TAG_DISPLAY); - if(!($display instanceof CompoundTag)){ - $display = new CompoundTag(); + foreach($lines as $line){ + if(!is_string($line)){ + throw new \TypeError("Expected string[], but found " . gettype($line) . " in given array"); + } } - - $display->setTag(self::TAG_DISPLAY_LORE, new ListTag(array_map(function(string $str) : StringTag{ - return new StringTag($str); - }, $lines), NBT::TAG_String)); - - $this->getNamedTag()->setTag(self::TAG_DISPLAY, $display); - + $this->lore = $lines; return $this; } + /** + * @return Set|string[] + */ + public function getCanPlaceOn() : Set{ + return $this->canPlaceOn; + } + + /** + * @param Set|string[] $canPlaceOn + */ + public function setCanPlaceOn(Set $canPlaceOn) : void{ + $this->canPlaceOn = $canPlaceOn; + } + + /** + * @return Set|string[] + */ + public function getCanDestroy() : Set{ + return $this->canDestroy; + } + + /** + * @param Set|string[] $canDestroy + */ + public function setCanDestroy(Set $canDestroy) : void{ + $this->canDestroy = $canDestroy; + } + /** * Returns whether this Item has a non-empty NBT. * @return bool */ public function hasNamedTag() : bool{ - return $this->nbt !== null and $this->nbt->count() > 0; + return $this->getNamedTag()->count() > 0; } /** @@ -398,7 +321,11 @@ class Item implements ItemIds, \JsonSerializable{ * @return CompoundTag */ public function getNamedTag() : CompoundTag{ - return $this->nbt ?? ($this->nbt = new CompoundTag()); + if($this->nbt === null){ + $this->nbt = new CompoundTag(); + } + $this->serializeCompoundTag($this->nbt); + return $this->nbt; } /** @@ -414,6 +341,7 @@ class Item implements ItemIds, \JsonSerializable{ } $this->nbt = clone $tag; + $this->deserializeCompoundTag($this->nbt); return $this; } @@ -423,10 +351,121 @@ class Item implements ItemIds, \JsonSerializable{ * @return Item */ public function clearNamedTag() : Item{ - $this->nbt = null; + $this->nbt = new CompoundTag(); + $this->deserializeCompoundTag($this->nbt); return $this; } + protected function deserializeCompoundTag(CompoundTag $tag) : void{ + $this->customName = ""; + $this->lore = []; + + $display = $tag->getCompoundTag(self::TAG_DISPLAY); + if($display !== null){ + $this->customName = $display->getString(self::TAG_DISPLAY_NAME, $this->customName, true); + $lore = $tag->getListTag(self::TAG_DISPLAY_LORE); + if($lore !== null and $lore->getTagType() === NBT::TAG_String){ + /** @var StringTag $t */ + foreach($lore as $t){ + $this->lore[] = $t->getValue(); + } + } + } + + $this->removeEnchantments(); + $enchantments = $tag->getListTag(self::TAG_ENCH); + if($enchantments !== null and $enchantments->getTagType() === NBT::TAG_Compound){ + /** @var CompoundTag $enchantment */ + foreach($enchantments as $enchantment){ + $magicNumber = $enchantment->getShort("id", 0, true); + $level = $enchantment->getShort("lvl", 0, true); + if($magicNumber <= 0 or $level <= 0){ + continue; + } + $type = Enchantment::get($magicNumber); + if($type !== null){ + $this->addEnchantment(new EnchantmentInstance($type, $level)); + } + } + } + + $this->blockEntityTag = $tag->getCompoundTag(self::TAG_BLOCK_ENTITY_TAG); + + $this->canPlaceOn = new Set(); + $canPlaceOn = $tag->getListTag("CanPlaceOn"); + if($canPlaceOn !== null){ + /** @var StringTag $tag */ + foreach($canPlaceOn as $entry){ + $this->canPlaceOn->add($entry->getValue()); + } + } + $this->canDestroy = new Set(); + $canDestroy = $tag->getListTag("CanDestroy"); + if($canDestroy !== null){ + /** @var StringTag $entry */ + foreach($canDestroy as $entry){ + $this->canDestroy->add($entry->getValue()); + } + } + } + + protected function serializeCompoundTag(CompoundTag $tag) : void{ + $display = $tag->getCompoundTag(self::TAG_DISPLAY) ?? new CompoundTag(); + + $this->hasCustomName() ? + $display->setString(self::TAG_DISPLAY_NAME, $this->getCustomName()) : + $display->removeTag(self::TAG_DISPLAY); + + if(!empty($this->lore)){ + $loreTag = new ListTag(); + foreach($this->lore as $line){ + $loreTag->push(new StringTag($line)); + } + $display->setTag(self::TAG_DISPLAY_LORE, $loreTag); + }else{ + $display->removeTag(self::TAG_DISPLAY_LORE); + } + $display->count() > 0 ? + $tag->setTag(self::TAG_DISPLAY, $display) : + $tag->removeTag(self::TAG_DISPLAY); + + if($this->hasEnchantments()){ + $ench = new ListTag(); + foreach($this->getEnchantments() as $enchantmentInstance){ + $ench->push(CompoundTag::create() + ->setShort("id", $enchantmentInstance->getType()->getId()) + ->setShort("lvl", $enchantmentInstance->getLevel()) + ); + } + $tag->setTag(self::TAG_ENCH, $ench); + }else{ + $tag->removeTag(self::TAG_ENCH); + } + + $this->hasCustomBlockData() ? + $tag->setTag(self::TAG_BLOCK_ENTITY_TAG, clone $this->getCustomBlockData()) : + $tag->removeTag(self::TAG_BLOCK_ENTITY_TAG); + + if(!$this->canPlaceOn->isEmpty()){ + $canPlaceOn = new ListTag(); + foreach($this->canPlaceOn as $item){ + $canPlaceOn->push(new StringTag($item)); + } + $tag->setTag("CanPlaceOn", $canPlaceOn); + }else{ + $tag->removeTag("CanPlaceOn"); + } + if(!$this->canDestroy->isEmpty()){ + $canDestroy = new ListTag(); + foreach($this->canDestroy as $item){ + $canDestroy->push(new StringTag($item)); + } + $tag->setTag("CanDestroy", $canDestroy); + }else{ + $tag->removeTag("CanDestroy"); + } + } + /** * @return int */ @@ -667,11 +706,10 @@ class Item implements ItemIds, \JsonSerializable{ final public function equals(Item $item, bool $checkDamage = true, bool $checkCompound = true) : bool{ if($this->id === $item->getId() and (!$checkDamage or $this->getMeta() === $item->getMeta())){ if($checkCompound){ - if($this->hasNamedTag() and $item->hasNamedTag()){ //both items have NBT - return $this->getNamedTag()->equals($item->getNamedTag()); - } + $tag1 = $this->getNamedTag(); + $tag2 = $item->getNamedTag(); - return (!$this->hasNamedTag() and !$item->hasNamedTag()); //both items must have no NBT + return ($tag1 === null and $tag2 === null) or ($tag1 !== null and $tag2 !== null and $tag1->equals($tag2)); }else{ return true; } @@ -695,7 +733,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return string */ final public function __toString() : string{ - return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->getMeta()) . ")x" . $this->count . ($this->hasNamedTag() ? " tags:" . base64_encode((new LittleEndianNbtSerializer())->write(new TreeRoot($this->nbt))) : ""); + return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->getMeta()) . ")x" . $this->count . (($tag = $this->getNamedTag()) !== null ? " tags:0x" . base64_encode((new LittleEndianNbtSerializer())->write(new TreeRoot($tag))) : ""); } /** @@ -716,8 +754,8 @@ class Item implements ItemIds, \JsonSerializable{ $data["count"] = $this->getCount(); } - if($this->hasNamedTag()){ - $data["nbt_b64"] = base64_encode((new LittleEndianNbtSerializer())->write(new TreeRoot($this->getNamedTag()))); + if(($tag = $this->getNamedTag()) !== null){ + $data["nbt_b64"] = base64_encode((new LittleEndianNbtSerializer())->write(new TreeRoot($tag))); } return $data; @@ -761,8 +799,8 @@ class Item implements ItemIds, \JsonSerializable{ ->setByte("Count", Binary::signByte($this->count)) ->setShort("Damage", $this->getMeta()); - if($this->hasNamedTag()){ - $result->setTag("tag", clone $this->getNamedTag()); + if(($itemNBT = $this->getNamedTag()) !== null){ + $result->setTag("tag", $itemNBT); } if($slot !== -1){ @@ -814,5 +852,11 @@ class Item implements ItemIds, \JsonSerializable{ if($this->nbt !== null){ $this->nbt = clone $this->nbt; } + if($this->blockEntityTag !== null){ + $this->blockEntityTag = clone $this->blockEntityTag; + } + $this->canPlaceOn = $this->canPlaceOn->copy(); + $this->canDestroy = $this->canDestroy->copy(); + $this->enchantments = array_map(function(EnchantmentInstance $i){ return clone $i; }, $this->enchantments); } } diff --git a/src/pocketmine/item/WritableBookBase.php b/src/pocketmine/item/WritableBookBase.php index defe4189cf..3d0a75b6ea 100644 --- a/src/pocketmine/item/WritableBookBase.php +++ b/src/pocketmine/item/WritableBookBase.php @@ -23,16 +23,23 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\nbt\NBT; +use Ds\Deque; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; abstract class WritableBookBase extends Item{ - public const TAG_PAGES = "pages"; //TAG_List public const TAG_PAGE_TEXT = "text"; //TAG_String public const TAG_PAGE_PHOTONAME = "photoname"; //TAG_String - TODO + /** @var WritableBookPage[]|Deque */ + private $pages; + + public function __construct(int $id, int $variant, string $name){ + parent::__construct($id, $variant, $name); + $this->pages = new Deque(); + } + /** * Returns whether the given page exists in this book. * @@ -41,7 +48,7 @@ abstract class WritableBookBase extends Item{ * @return bool */ public function pageExists(int $pageId) : bool{ - return $this->getPagesTag()->isset($pageId); + return isset($this->pages[$pageId]); } /** @@ -49,20 +56,11 @@ abstract class WritableBookBase extends Item{ * * @param int $pageId * - * @return string|null + * @return string + * @throws \OutOfRangeException if requesting a nonexisting page */ - public function getPageText(int $pageId) : ?string{ - $pages = $this->getNamedTag()->getListTag(self::TAG_PAGES); - if($pages === null){ - return null; - } - - $page = $pages->get($pageId); - if($page instanceof CompoundTag){ - return $page->getString(self::TAG_PAGE_TEXT, ""); - } - - return null; + public function getPageText(int $pageId) : string{ + return $this->pages[$pageId]->getText(); } /** @@ -78,14 +76,7 @@ abstract class WritableBookBase extends Item{ $this->addPage($pageId); } - /** @var CompoundTag[]|ListTag $pagesTag */ - $pagesTag = $this->getPagesTag(); - /** @var CompoundTag $page */ - $page = $pagesTag->get($pageId); - $page->setString(self::TAG_PAGE_TEXT, $pageText); - - $this->getNamedTag()->setTag(self::TAG_PAGES, $pagesTag); - + $this->pages->set($pageId, new WritableBookPage($pageText)); return $this; } @@ -102,16 +93,9 @@ abstract class WritableBookBase extends Item{ throw new \InvalidArgumentException("Page number \"$pageId\" is out of range"); } - $pagesTag = $this->getPagesTag(); - - for($current = $pagesTag->count(); $current <= $pageId; $current++){ - $pagesTag->push(CompoundTag::create() - ->setString(self::TAG_PAGE_TEXT, "") - ->setString(self::TAG_PAGE_PHOTONAME, "") - ); + for($current = $this->pages->count(); $current <= $pageId; $current++){ + $this->pages->push(new WritableBookPage("")); } - - $this->getNamedTag()->setTag(self::TAG_PAGES, $pagesTag); return $this; } @@ -123,9 +107,7 @@ abstract class WritableBookBase extends Item{ * @return $this */ public function deletePage(int $pageId) : self{ - $pagesTag = $this->getPagesTag(); - $pagesTag->remove($pageId); - + $this->pages->remove($pageId); return $this; } @@ -138,15 +120,7 @@ abstract class WritableBookBase extends Item{ * @return $this */ public function insertPage(int $pageId, string $pageText = "") : self{ - $pagesTag = $this->getPagesTag(); - - $pagesTag->insert($pageId, CompoundTag::create() - ->setString(self::TAG_PAGE_TEXT, $pageText) - ->setString(self::TAG_PAGE_PHOTONAME, "") - ); - - $this->getNamedTag()->setTag(self::TAG_PAGES, $pagesTag); - + $this->pages->insert($pageId, new WritableBookPage($pageText)); return $this; } @@ -157,12 +131,9 @@ abstract class WritableBookBase extends Item{ * @param int $pageId2 * * @return bool indicating success + * @throws \OutOfRangeException if either of the pages does not exist */ public function swapPages(int $pageId1, int $pageId2) : bool{ - if(!$this->pageExists($pageId1) or !$this->pageExists($pageId2)){ - return false; - } - $pageContents1 = $this->getPageText($pageId1); $pageContents2 = $this->getPageText($pageId2); $this->setPageText($pageId1, $pageContents2); @@ -178,30 +149,51 @@ abstract class WritableBookBase extends Item{ /** * Returns an array containing all pages of this book. * - * @return CompoundTag[] + * @return WritableBookPage[]|Deque */ - public function getPages() : array{ - $pages = $this->getNamedTag()->getListTag(self::TAG_PAGES); - if($pages === null){ - return []; - } - - return $pages->getValue(); - } - - protected function getPagesTag() : ListTag{ - return $this->getNamedTag()->getListTag(self::TAG_PAGES) ?? new ListTag([], NBT::TAG_Compound); + public function getPages() : Deque{ + return $this->pages; } /** - * @param CompoundTag[] $pages - * - * @return $this + * @param WritableBookPage[]|Deque $pages */ - public function setPages(array $pages) : self{ - $nbt = $this->getNamedTag(); - $nbt->setTag(self::TAG_PAGES, new ListTag($pages, NBT::TAG_Compound)); - $this->setNamedTag($nbt); - return $this; + public function setPages(Deque $pages) : void{ + $this->pages = $pages; + } + + protected function deserializeCompoundTag(CompoundTag $tag) : void{ + parent::deserializeCompoundTag($tag); + $this->pages = new Deque(); + + $pages = $tag->getListTag(self::TAG_PAGES); + if($pages !== null){ + /** @var CompoundTag $page */ + foreach($pages as $page){ + $this->pages->push(new WritableBookPage($page->getString(self::TAG_PAGE_TEXT), $page->getString(self::TAG_PAGE_PHOTONAME, ""))); + } + } + } + + protected function serializeCompoundTag(CompoundTag $tag) : void{ + parent::serializeCompoundTag($tag); + if(!$this->pages->isEmpty()){ + $pages = new ListTag(); + foreach($this->pages as $page){ + $pages->push(CompoundTag::create() + ->setString(self::TAG_PAGE_TEXT, $page->getText()) + ->setString(self::TAG_PAGE_PHOTONAME, $page->getPhotoName()) + ); + } + $tag->setTag(self::TAG_PAGES, $pages); + }else{ + $tag->removeTag(self::TAG_PAGES); + } + } + + public function __clone(){ + parent::__clone(); + //no need to deep-copy each page, the objects are immutable + $this->pages = $this->pages->copy(); } } diff --git a/src/pocketmine/item/WritableBookPage.php b/src/pocketmine/item/WritableBookPage.php new file mode 100644 index 0000000000..5f82898e5b --- /dev/null +++ b/src/pocketmine/item/WritableBookPage.php @@ -0,0 +1,52 @@ +text = $text; + $this->photoName = $photoName; + } + + /** + * @return string + */ + public function getText() : string{ + return $this->text; + } + + /** + * @return string + */ + public function getPhotoName() : string{ + return $this->photoName; + } +} \ No newline at end of file diff --git a/src/pocketmine/item/WrittenBook.php b/src/pocketmine/item/WrittenBook.php index dbccfa77d4..683d904563 100644 --- a/src/pocketmine/item/WrittenBook.php +++ b/src/pocketmine/item/WrittenBook.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\nbt\tag\CompoundTag; + class WrittenBook extends WritableBookBase{ public const GENERATION_ORIGINAL = 0; @@ -34,6 +36,13 @@ class WrittenBook extends WritableBookBase{ public const TAG_AUTHOR = "author"; //TAG_String public const TAG_TITLE = "title"; //TAG_String + /** @var int */ + private $generation = self::GENERATION_ORIGINAL; + /** @var string */ + private $author = ""; + /** @var string */ + private $title = ""; + public function getMaxStackSize() : int{ return 16; } @@ -45,7 +54,7 @@ class WrittenBook extends WritableBookBase{ * @return int */ public function getGeneration() : int{ - return $this->getNamedTag()->getInt(self::TAG_GENERATION, self::GENERATION_ORIGINAL); + return $this->generation; } /** @@ -59,9 +68,8 @@ class WrittenBook extends WritableBookBase{ if($generation < 0 or $generation > 3){ throw new \InvalidArgumentException("Generation \"$generation\" is out of range"); } - $namedTag = $this->getNamedTag(); - $namedTag->setInt(self::TAG_GENERATION, $generation); - $this->setNamedTag($namedTag); + + $this->generation = $generation; return $this; } @@ -73,7 +81,7 @@ class WrittenBook extends WritableBookBase{ * @return string */ public function getAuthor() : string{ - return $this->getNamedTag()->getString(self::TAG_AUTHOR, ""); + return $this->author; } /** @@ -84,9 +92,7 @@ class WrittenBook extends WritableBookBase{ * @return $this */ public function setAuthor(string $authorName) : self{ - $namedTag = $this->getNamedTag(); - $namedTag->setString(self::TAG_AUTHOR, $authorName); - $this->setNamedTag($namedTag); + $this->author = $authorName; return $this; } @@ -96,7 +102,7 @@ class WrittenBook extends WritableBookBase{ * @return string */ public function getTitle() : string{ - return $this->getNamedTag()->getString(self::TAG_TITLE, ""); + return $this->title; } /** @@ -107,9 +113,21 @@ class WrittenBook extends WritableBookBase{ * @return $this */ public function setTitle(string $title) : self{ - $namedTag = $this->getNamedTag(); - $namedTag->setString(self::TAG_TITLE, $title); - $this->setNamedTag($namedTag); + $this->title = $title; return $this; } + + protected function deserializeCompoundTag(CompoundTag $tag) : void{ + parent::deserializeCompoundTag($tag); + $this->generation = $tag->getInt(self::TAG_GENERATION, $this->generation); + $this->author = $tag->getString(self::TAG_AUTHOR, $this->author); + $this->title = $tag->getString(self::TAG_TITLE, $this->title); + } + + protected function serializeCompoundTag(CompoundTag $tag) : void{ + parent::serializeCompoundTag($tag); + $tag->setInt(self::TAG_GENERATION, $this->generation); + $tag->setString(self::TAG_AUTHOR, $this->author); + $tag->setString(self::TAG_TITLE, $this->title); + } } diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index cfcc15f6a3..54289f06fc 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -51,8 +51,6 @@ use pocketmine\item\ItemFactory; use pocketmine\item\ItemUseResult; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; -use pocketmine\nbt\tag\ListTag; -use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\protocol\BlockActorDataPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; @@ -1611,17 +1609,12 @@ class World implements ChunkManager{ } if($player->isAdventure(true) and !$ev->isCancelled()){ - $tag = $item->getNamedTag()->getListTag("CanDestroy"); $canBreak = false; - if($tag instanceof ListTag){ - foreach($tag as $v){ - if($v instanceof StringTag){ - $entry = ItemFactory::fromString($v->getValue()); - if($entry->getBlock()->isSameType($target)){ - $canBreak = true; - break; - } - } + foreach($item->getCanDestroy() as $v){ + $entry = ItemFactory::fromString($v); + if($entry->getBlock()->isSameType($target)){ + $canBreak = true; + break; } } @@ -1759,16 +1752,11 @@ class World implements ChunkManager{ $ev = new BlockPlaceEvent($player, $hand, $blockReplace, $blockClicked, $item); if($player->isAdventure(true) and !$ev->isCancelled()){ $canPlace = false; - $tag = $item->getNamedTag()->getListTag("CanPlaceOn"); - if($tag instanceof ListTag){ - foreach($tag as $v){ - if($v instanceof StringTag){ - $entry = ItemFactory::fromString($v->getValue()); - if($entry->getBlock()->isSameType($blockClicked)){ - $canPlace = true; - break; - } - } + foreach($item->getCanPlaceOn() as $v){ + $entry = ItemFactory::fromString($v); + if($entry->getBlock()->isSameType($blockClicked)){ + $canPlace = true; + break; } } From 3d0e47ba14af2ee009cb0e783656d783ba337419 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 16 Jul 2019 17:52:58 +0100 Subject: [PATCH 1089/3224] WritableBookBase: Don't expose page deque on the API putting this stuff on the API creates a nightmare because DS structures are both mutable and by-reference, so they have to be manually copied everywhere. --- src/pocketmine/item/WritableBookBase.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pocketmine/item/WritableBookBase.php b/src/pocketmine/item/WritableBookBase.php index 3d0a75b6ea..365766973d 100644 --- a/src/pocketmine/item/WritableBookBase.php +++ b/src/pocketmine/item/WritableBookBase.php @@ -149,17 +149,17 @@ abstract class WritableBookBase extends Item{ /** * Returns an array containing all pages of this book. * - * @return WritableBookPage[]|Deque + * @return WritableBookPage[] */ - public function getPages() : Deque{ - return $this->pages; + public function getPages() : array{ + return $this->pages->toArray(); } /** - * @param WritableBookPage[]|Deque $pages + * @param WritableBookPage[] $pages */ - public function setPages(Deque $pages) : void{ - $this->pages = $pages; + public function setPages(array $pages) : void{ + $this->pages = new Deque($pages); } protected function deserializeCompoundTag(CompoundTag $tag) : void{ From 73a847123bdf890d755d3ca1fa6c106a0b610c76 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 16 Jul 2019 17:59:01 +0100 Subject: [PATCH 1090/3224] WritableBookBase: Make setPages() fluent --- src/pocketmine/item/WritableBookBase.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/item/WritableBookBase.php b/src/pocketmine/item/WritableBookBase.php index 365766973d..ef44dbf6a4 100644 --- a/src/pocketmine/item/WritableBookBase.php +++ b/src/pocketmine/item/WritableBookBase.php @@ -157,9 +157,12 @@ abstract class WritableBookBase extends Item{ /** * @param WritableBookPage[] $pages + * + * @return $this */ - public function setPages(array $pages) : void{ + public function setPages(array $pages) : self{ $this->pages = new Deque($pages); + return $this; } protected function deserializeCompoundTag(CompoundTag $tag) : void{ From 8f64d6b053bc5687d44e8ba3a42ddb5999f9d701 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 16 Jul 2019 17:59:39 +0100 Subject: [PATCH 1091/3224] Don't mess with NBT when creating signed books --- .../network/mcpe/handler/InGamePacketHandler.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php index f6bc0d5579..8eeb715149 100644 --- a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php @@ -640,10 +640,11 @@ class InGamePacketHandler extends PacketHandler{ break; case BookEditPacket::TYPE_SIGN_BOOK: /** @var WrittenBook $newBook */ - $newBook = VanillaItems::WRITTEN_BOOK()->setNamedTag($oldBook->getNamedTag()); - $newBook->setAuthor($packet->author); - $newBook->setTitle($packet->title); - $newBook->setGeneration(WrittenBook::GENERATION_ORIGINAL); + $newBook = VanillaItems::WRITTEN_BOOK() + ->setPages($oldBook->getPages()) + ->setAuthor($packet->author) + ->setTitle($packet->title) + ->setGeneration(WrittenBook::GENERATION_ORIGINAL); break; default: return false; From 49a68211951316cd86e6d6529729db928d025e33 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 16 Jul 2019 18:06:21 +0100 Subject: [PATCH 1092/3224] fix @return hints on Item fluent methods --- src/pocketmine/item/Item.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 31dee6c667..d8da5af2ef 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -26,7 +26,6 @@ declare(strict_types=1); */ namespace pocketmine\item; -use function array_map; use Ds\Set; use pocketmine\block\Block; use pocketmine\block\BlockBreakInfo; @@ -46,6 +45,7 @@ use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\TreeRoot; use pocketmine\player\Player; use pocketmine\utils\Binary; +use function array_map; use function base64_decode; use function base64_encode; use function get_class; @@ -129,7 +129,7 @@ class Item implements ItemIds, \JsonSerializable{ /** * @param CompoundTag $compound * - * @return Item + * @return $this */ public function setCustomBlockData(CompoundTag $compound) : Item{ $this->blockEntityTag = clone $compound; @@ -175,7 +175,7 @@ class Item implements ItemIds, \JsonSerializable{ * @param Enchantment $enchantment * @param int $level * - * @return Item + * @return $this */ public function removeEnchantment(Enchantment $enchantment, int $level = -1) : Item{ $instance = $this->getEnchantment($enchantment); @@ -187,7 +187,7 @@ class Item implements ItemIds, \JsonSerializable{ } /** - * @return Item + * @return $this */ public function removeEnchantments() : Item{ $this->enchantments = []; @@ -197,7 +197,7 @@ class Item implements ItemIds, \JsonSerializable{ /** * @param EnchantmentInstance $enchantment * - * @return Item + * @return $this */ public function addEnchantment(EnchantmentInstance $enchantment) : Item{ $this->enchantments[$enchantment->getId()] = $enchantment; @@ -240,7 +240,7 @@ class Item implements ItemIds, \JsonSerializable{ /** * @param string $name * - * @return Item + * @return $this */ public function setCustomName(string $name) : Item{ //TODO: encoding might need to be checked here @@ -249,7 +249,7 @@ class Item implements ItemIds, \JsonSerializable{ } /** - * @return Item + * @return $this */ public function clearCustomName() : Item{ $this->setCustomName(""); @@ -266,7 +266,7 @@ class Item implements ItemIds, \JsonSerializable{ /** * @param string[] $lines * - * @return Item + * @return $this */ public function setLore(array $lines) : Item{ foreach($lines as $line){ @@ -333,7 +333,7 @@ class Item implements ItemIds, \JsonSerializable{ * * @param CompoundTag $tag * - * @return Item + * @return $this */ public function setNamedTag(CompoundTag $tag) : Item{ if($tag->getCount() === 0){ @@ -348,7 +348,7 @@ class Item implements ItemIds, \JsonSerializable{ /** * Removes the Item's NBT. - * @return Item + * @return $this */ public function clearNamedTag() : Item{ $this->nbt = new CompoundTag(); @@ -476,7 +476,7 @@ class Item implements ItemIds, \JsonSerializable{ /** * @param int $count * - * @return Item + * @return $this */ public function setCount(int $count) : Item{ $this->count = $count; From ff219774618124c5dd85544cd6f6965e89f0b126 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 16 Jul 2019 18:11:09 +0100 Subject: [PATCH 1093/3224] Item: simplify equals() getNamedTag() can't return null anymore. --- src/pocketmine/item/Item.php | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index d8da5af2ef..ab833b6eeb 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -704,18 +704,9 @@ class Item implements ItemIds, \JsonSerializable{ * @return bool */ final public function equals(Item $item, bool $checkDamage = true, bool $checkCompound = true) : bool{ - if($this->id === $item->getId() and (!$checkDamage or $this->getMeta() === $item->getMeta())){ - if($checkCompound){ - $tag1 = $this->getNamedTag(); - $tag2 = $item->getNamedTag(); - - return ($tag1 === null and $tag2 === null) or ($tag1 !== null and $tag2 !== null and $tag1->equals($tag2)); - }else{ - return true; - } - } - - return false; + return $this->id === $item->getId() and + (!$checkDamage or $this->getMeta() === $item->getMeta()) and + (!$checkCompound or $this->getNamedTag()->equals($item->getNamedTag())); } /** From 711ea3185db830740aca03f500f77bbde2e71103 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 16 Jul 2019 19:53:47 +0100 Subject: [PATCH 1094/3224] update composer dependencies --- composer.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.lock b/composer.lock index 5c622c8c25..606cd6003b 100644 --- a/composer.lock +++ b/composer.lock @@ -333,12 +333,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "52a92d6d5c665528a9fc597b1f10d6e15e7d861a" + "reference": "b0380415d0b60833b664e2756ad5b25d445109a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/52a92d6d5c665528a9fc597b1f10d6e15e7d861a", - "reference": "52a92d6d5c665528a9fc597b1f10d6e15e7d861a", + "url": "https://api.github.com/repos/pmmp/Math/zipball/b0380415d0b60833b664e2756ad5b25d445109a7", + "reference": "b0380415d0b60833b664e2756ad5b25d445109a7", "shasum": "" }, "require": { @@ -364,7 +364,7 @@ "source": "https://github.com/pmmp/Math/tree/master", "issues": "https://github.com/pmmp/Math/issues" }, - "time": "2019-04-18T18:03:11+00:00" + "time": "2019-06-06T14:58:02+00:00" }, { "name": "pocketmine/nbt", @@ -372,12 +372,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "359149d516a042ef366f3bf234c0a9daa4d5ea2e" + "reference": "ddbc9909228c6fcedc13809a650ced2a0c432cf0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/359149d516a042ef366f3bf234c0a9daa4d5ea2e", - "reference": "359149d516a042ef366f3bf234c0a9daa4d5ea2e", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/ddbc9909228c6fcedc13809a650ced2a0c432cf0", + "reference": "ddbc9909228c6fcedc13809a650ced2a0c432cf0", "shasum": "" }, "require": { @@ -405,7 +405,7 @@ "source": "https://github.com/pmmp/NBT/tree/master", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2019-04-25T18:53:18+00:00" + "time": "2019-07-16T18:51:45+00:00" }, { "name": "pocketmine/raklib", From b57dcebb6fc8c20ef11591c8db7a2e0f41255c4c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 16 Jul 2019 19:59:15 +0100 Subject: [PATCH 1095/3224] Living: tighten validity checks on health NBT, don't use generic getValue() (it could return anything) --- src/pocketmine/entity/Living.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index a8eda74610..853cb9fc64 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -44,6 +44,7 @@ use pocketmine\math\VoxelRayTrace; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\ListTag; +use pocketmine\nbt\tag\ShortTag; use pocketmine\network\mcpe\protocol\ActorEventPacket; use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; @@ -105,9 +106,10 @@ abstract class Living extends Entity{ if($nbt->hasTag("HealF", FloatTag::class)){ $health = $nbt->getFloat("HealF"); - }elseif($nbt->hasTag("Health")){ - $healthTag = $nbt->getTag("Health"); - $health = (float) $healthTag->getValue(); //Older versions of PocketMine-MP incorrectly saved this as a short instead of a float + }elseif($nbt->hasTag("Health", ShortTag::class)){ + $health = $nbt->getShort("Health"); //Older versions of PocketMine-MP incorrectly saved this as a short instead of a float + }elseif($nbt->hasTag("Health", FloatTag::class)){ + $health = $nbt->getFloat("Health"); } $this->setHealth($health); From ad4ed1c95c7df88a6be80a9216ddd7eb5bddf7d4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jul 2019 14:46:43 +0100 Subject: [PATCH 1096/3224] [ci skip] expand changelog on item changes --- changelogs/4.0-snapshot.md | 60 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 7c3849d681..ed2606f2d0 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -389,13 +389,34 @@ This version features substantial changes to the network system, improving coher ### Item #### General -- `ProjectileItem->getProjectileEntityType()` now returns a ::class constant instead of an entity save ID. +- `Item->count` is no longer public. +- The hierarchy of writable books has been changed: `WritableBook` and `WrittenBook` now extend `WritableBookBase`. +- The following API methods have signature changes: + - `WritableBookBase->setPages()` now accepts `WritableBookPage[]` instead of `CompoundTag[]`. + - `ItemFactory::get()` no longer accepts `string` for the `tags` parameter. + - `ItemFactory::fromString()` no longer accepts a `$multiple` parameter and now only returns `Item`, not `Item|Item[]`. +- The following methods are now fluent: + - `WritableBookBase->setPages()` + - `Item->addEnchantment()` + - `Item->removeEnchantment()` + - `Item->removeEnchantments()` + - `Armor->setCustomColor()` + - `WrittenBook->setTitle()` + - `WrittenBook->setAuthor()` + - `WrittenBook->setGeneration()` - The following API methods have been removed: - `Item->getNamedTagEntry()` - `Item->removeNamedTagEntry()` - `Item->setDamage()`: "Damage" is now immutable for all items except `Durable` descendents. - `Item->setNamedTagEntry()` - + - `Item::get()`: this was superseded by `ItemFactory::get()` a long time ago + - `Item::fromString()`: this was superseded by `ItemFactory::fromString()` a long time ago + - `Item->setCompoundTag()` + - `Item->getCompoundTag()` + - `Item->hasCompoundTag()` + - `ProjectileItem->getProjectileEntityType()` +- The following methods have been renamed: + - `Item->getDamage()` -> `Item->getMeta()` - The following methods have been moved to `pocketmine\inventory\CreativeInventory`: - `Item::addCreativeItem()` -> `CreativeInventory::add()` - `Item::clearCreativeItems()` -> `CreativeInventory::clear()` @@ -404,6 +425,41 @@ This version features substantial changes to the network system, improving coher - `Item::initCreativeItems()` -> `CreativeInventory::init()` - `Item::isCreativeItem()` -> `CreativeInventory::contains()` - `Item::removeCreativeItem()` -> `CreativeInventory::remove()` +- The following classes have been added: + - `ArmorTypeInfo` + - `Boots` + - `Chestplate` + - `Fertilizer` + - `Helmet` + - `Leggings` + - `LiquidBucket` + - `MilkBucket` + - `WritableBookBase` + - `WritableBookPage` +- The following API methods have been added: + - `Armor->getArmorSlot()` + - `ProjectileItem->getProjectileEntityClass()`: returns the class of projectile to be created when thrown +- The following classes have been removed: + - `ChainBoots` + - `ChainChestplate` + - `ChainHelmet` + - `ChainLeggings` + - `DiamondBoots` + - `DiamondChestplate` + - `DiamondHelmet` + - `DiamondLeggings` + - `GoldBoots` + - `GoldChestplate` + - `GoldHelmet` + - `GoldLeggings` + - `IronBoots` + - `IronChesplate` + - `IronHelmet` + - `IronLeggings` + - `LeatherBoots` + - `LeatherCap` + - `LeatherPants` + - `LeatherTunic` #### Enchantment - The following API methods have been renamed: From 74572fde08757fe824c9a3aa06e87a254716c028 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jul 2019 15:52:52 +0100 Subject: [PATCH 1097/3224] [ci skip] changelog: add some information about NBT handling changes --- changelogs/4.0-snapshot.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index ed2606f2d0..9d7539981f 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -461,6 +461,13 @@ This version features substantial changes to the network system, improving coher - `LeatherPants` - `LeatherTunic` +#### NBT handling +- Serialized NBT byte array caches are no longer stored on itemstacks. These caches were a premature optimization used for network layer serialization and as such were dependent on the network NBT format. +- Internal NBT usage has been marginalized. It's no longer necessary to immediately write changes to NBT. The following hooks have been added: + - `Item->serializeCompoundTag()` + - `Item->deserializeCompoundTag()` +- It's planned to remove runtime NBT from items completely, but this currently presents unresolved backwards-compatibility problems. + #### Enchantment - The following API methods have been renamed: - `Enchantment::registerEnchantment()` -> `Enchantment::register()` From fec8c75fd873b9111ca552401af383eaebe1bfc5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jul 2019 15:55:28 +0100 Subject: [PATCH 1098/3224] [ci skip] changelog: document more misc API changes --- changelogs/4.0-snapshot.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 9d7539981f..632cf44204 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -92,6 +92,7 @@ This version features substantial changes to the network system, improving coher - The following API methods have been removed: - `Block->canPassThrough()` - `Block->setDamage()` + - `Block::get()`: this was superseded by `BlockFactory::get()` a long time ago - The following classes have been renamed: - `BlockIds` -> `BlockLegacyIds` - `CobblestoneWall` -> `Wall` @@ -674,6 +675,7 @@ This version features substantial changes to the network system, improving coher - `World->getRandomTickedBlocks()` now returns `bool[]` instead of `SplFixedArray`. - `World->addRandomTickedBlock()` now accepts `Block` instead of `int, int`. - `World->removeRandomTickedBlock()` now accepts `Block` instead of `int, int`. + - `World->setBlock()` has had the `$direct` parameter removed. - The following API methods have been renamed / moved: - `Level->getCollisionCubes()` -> `World->getCollisionBoxes()` - Extracted a unit `pocketmine\world\format\io\FastChunkSerializer` from `Chunk`: From af73c5f2b1dc426fa117efe9ddd76e2dd2f6cde1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jul 2019 16:03:08 +0100 Subject: [PATCH 1099/3224] Make EnchantmentInstance immutable, remove enchantment clone from Item it doesn't make sense to set the level of an existing enchantment instance because under the old API it would have no effect anyway (if it was returned from an itemstack) or you had access to the constructor (if applying a new enchantment). Allowing this to be mutable creates needless complexity and performance headaches. --- src/pocketmine/item/Item.php | 2 -- .../item/enchantment/EnchantmentInstance.php | 17 +++-------------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index ab833b6eeb..e4da378725 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -45,7 +45,6 @@ use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\TreeRoot; use pocketmine\player\Player; use pocketmine\utils\Binary; -use function array_map; use function base64_decode; use function base64_encode; use function get_class; @@ -848,6 +847,5 @@ class Item implements ItemIds, \JsonSerializable{ } $this->canPlaceOn = $this->canPlaceOn->copy(); $this->canDestroy = $this->canDestroy->copy(); - $this->enchantments = array_map(function(EnchantmentInstance $i){ return clone $i; }, $this->enchantments); } } diff --git a/src/pocketmine/item/enchantment/EnchantmentInstance.php b/src/pocketmine/item/enchantment/EnchantmentInstance.php index 2434ba5b87..4dadc77c13 100644 --- a/src/pocketmine/item/enchantment/EnchantmentInstance.php +++ b/src/pocketmine/item/enchantment/EnchantmentInstance.php @@ -25,8 +25,10 @@ namespace pocketmine\item\enchantment; /** * Container for enchantment data applied to items. + * + * Note: This class is assumed to be immutable. Consider this before making alterations. */ -class EnchantmentInstance{ +final class EnchantmentInstance{ /** @var Enchantment */ private $enchantment; /** @var int */ @@ -66,17 +68,4 @@ class EnchantmentInstance{ public function getLevel() : int{ return $this->level; } - - /** - * Sets the level of the enchantment. - * - * @param int $level - * - * @return $this - */ - public function setLevel(int $level){ - $this->level = $level; - - return $this; - } } From 6aba9fadfc8fa4c56ffc712209f698da88cdb441 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jul 2019 16:12:13 +0100 Subject: [PATCH 1100/3224] Encapsulate Item enchantment handling parts within a trait for scope isolation as a happy side effect, this makes the Item class smaller, makes the code easier to read, and also makes the code more easily testable. --- src/pocketmine/item/Item.php | 83 +------------ .../item/ItemEnchantmentHandlingTrait.php | 116 ++++++++++++++++++ 2 files changed, 118 insertions(+), 81 deletions(-) create mode 100644 src/pocketmine/item/ItemEnchantmentHandlingTrait.php diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index e4da378725..833e6e1546 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -53,6 +53,8 @@ use function hex2bin; use function is_string; class Item implements ItemIds, \JsonSerializable{ + use ItemEnchantmentHandlingTrait; + public const TAG_ENCH = "ench"; public const TAG_DISPLAY = "display"; public const TAG_BLOCK_ENTITY_TAG = "BlockEntityTag"; @@ -73,8 +75,6 @@ class Item implements ItemIds, \JsonSerializable{ //TODO: this stuff should be moved to itemstack properties, not mushed in with type properties - /** @var EnchantmentInstance[] */ - protected $enchantments = []; /** @var string */ protected $customName = ""; /** @var string[] */ @@ -143,85 +143,6 @@ class Item implements ItemIds, \JsonSerializable{ return $this->blockEntityTag; } - /** - * @return bool - */ - public function hasEnchantments() : bool{ - return !empty($this->enchantments); - } - - /** - * @param Enchantment $enchantment - * @param int $level - * - * @return bool - */ - public function hasEnchantment(Enchantment $enchantment, int $level = -1) : bool{ - $id = $enchantment->getId(); - return isset($this->enchantments[$id]) and ($level === -1 or $this->enchantments[$id]->getLevel() === $level); - } - - /** - * @param Enchantment $enchantment - * - * @return EnchantmentInstance|null - */ - public function getEnchantment(Enchantment $enchantment) : ?EnchantmentInstance{ - return $this->enchantments[$enchantment->getId()] ?? null; - } - - /** - * @param Enchantment $enchantment - * @param int $level - * - * @return $this - */ - public function removeEnchantment(Enchantment $enchantment, int $level = -1) : Item{ - $instance = $this->getEnchantment($enchantment); - if($instance !== null and ($level === -1 or $instance->getLevel() === $level)){ - unset($this->enchantments[$enchantment->getId()]); - } - - return $this; - } - - /** - * @return $this - */ - public function removeEnchantments() : Item{ - $this->enchantments = []; - return $this; - } - - /** - * @param EnchantmentInstance $enchantment - * - * @return $this - */ - public function addEnchantment(EnchantmentInstance $enchantment) : Item{ - $this->enchantments[$enchantment->getId()] = $enchantment; - return $this; - } - - /** - * @return EnchantmentInstance[] - */ - public function getEnchantments() : array{ - return $this->enchantments; - } - - /** - * Returns the level of the enchantment on this item with the specified ID, or 0 if the item does not have the - * enchantment. - * - * @param Enchantment $enchantment - * - * @return int - */ - public function getEnchantmentLevel(Enchantment $enchantment) : int{ - return ($instance = $this->getEnchantment($enchantment)) !== null ? $instance->getLevel() : 0; - } - /** * @return bool */ diff --git a/src/pocketmine/item/ItemEnchantmentHandlingTrait.php b/src/pocketmine/item/ItemEnchantmentHandlingTrait.php new file mode 100644 index 0000000000..20fdb83727 --- /dev/null +++ b/src/pocketmine/item/ItemEnchantmentHandlingTrait.php @@ -0,0 +1,116 @@ +enchantments); + } + + /** + * @param Enchantment $enchantment + * @param int $level + * + * @return bool + */ + public function hasEnchantment(Enchantment $enchantment, int $level = -1) : bool{ + $id = $enchantment->getId(); + return isset($this->enchantments[$id]) and ($level === -1 or $this->enchantments[$id]->getLevel() === $level); + } + + /** + * @param Enchantment $enchantment + * + * @return EnchantmentInstance|null + */ + public function getEnchantment(Enchantment $enchantment) : ?EnchantmentInstance{ + return $this->enchantments[$enchantment->getId()] ?? null; + } + + /** + * @param Enchantment $enchantment + * @param int $level + * + * @return $this + */ + public function removeEnchantment(Enchantment $enchantment, int $level = -1) : self{ + $instance = $this->getEnchantment($enchantment); + if($instance !== null and ($level === -1 or $instance->getLevel() === $level)){ + unset($this->enchantments[$enchantment->getId()]); + } + + return $this; + } + + /** + * @return $this + */ + public function removeEnchantments() : self{ + $this->enchantments = []; + return $this; + } + + /** + * @param EnchantmentInstance $enchantment + * + * @return $this + */ + public function addEnchantment(EnchantmentInstance $enchantment) : self{ + $this->enchantments[$enchantment->getId()] = $enchantment; + return $this; + } + + /** + * @return EnchantmentInstance[] + */ + public function getEnchantments() : array{ + return $this->enchantments; + } + + /** + * Returns the level of the enchantment on this item with the specified ID, or 0 if the item does not have the + * enchantment. + * + * @param Enchantment $enchantment + * + * @return int + */ + public function getEnchantmentLevel(Enchantment $enchantment) : int{ + return ($instance = $this->getEnchantment($enchantment)) !== null ? $instance->getLevel() : 0; + } +} From ccf165b1075843ef67abe7bcb39ce245e2026839 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jul 2019 16:24:29 +0100 Subject: [PATCH 1101/3224] mark some assumed-immutable classes as final --- src/pocketmine/entity/Skin.php | 2 +- src/pocketmine/utils/Color.php | 2 +- src/pocketmine/utils/UUID.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/entity/Skin.php b/src/pocketmine/entity/Skin.php index 83d8eff395..76e7884df8 100644 --- a/src/pocketmine/entity/Skin.php +++ b/src/pocketmine/entity/Skin.php @@ -30,7 +30,7 @@ use function json_encode; use function json_last_error_msg; use function strlen; -class Skin{ +final class Skin{ public const ACCEPTED_SKIN_SIZES = [ 64 * 32 * 4, 64 * 64 * 4, diff --git a/src/pocketmine/utils/Color.php b/src/pocketmine/utils/Color.php index 26846164ef..833f158948 100644 --- a/src/pocketmine/utils/Color.php +++ b/src/pocketmine/utils/Color.php @@ -26,7 +26,7 @@ namespace pocketmine\utils; use function count; use function intdiv; -class Color{ +final class Color{ /** @var int */ protected $a; diff --git a/src/pocketmine/utils/UUID.php b/src/pocketmine/utils/UUID.php index b522f43d15..6f318a9ae7 100644 --- a/src/pocketmine/utils/UUID.php +++ b/src/pocketmine/utils/UUID.php @@ -36,7 +36,7 @@ use function substr; use function time; use function trim; -class UUID{ +final class UUID{ /** @var int[] */ private $parts; From 7954a816025c328b3276729b8b65c15464e00e19 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jul 2019 18:04:15 +0100 Subject: [PATCH 1102/3224] fixing finality and constructor visibility on some enums --- src/pocketmine/block/utils/SkullType.php | 2 +- src/pocketmine/world/sound/NoteInstrument.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/block/utils/SkullType.php b/src/pocketmine/block/utils/SkullType.php index b53e974b7d..38bdc20f61 100644 --- a/src/pocketmine/block/utils/SkullType.php +++ b/src/pocketmine/block/utils/SkullType.php @@ -81,7 +81,7 @@ final class SkullType{ /** @var int */ private $magicNumber; - public function __construct(string $enumName, string $displayName, int $magicNumber){ + private function __construct(string $enumName, string $displayName, int $magicNumber){ $this->Enum___construct($enumName); $this->displayName = $displayName; $this->magicNumber = $magicNumber; diff --git a/src/pocketmine/world/sound/NoteInstrument.php b/src/pocketmine/world/sound/NoteInstrument.php index 6223333672..255bfe1f85 100644 --- a/src/pocketmine/world/sound/NoteInstrument.php +++ b/src/pocketmine/world/sound/NoteInstrument.php @@ -36,7 +36,7 @@ use pocketmine\utils\EnumTrait; * @method static self CLICKS_AND_STICKS() * @method static self DOUBLE_BASS() */ -class NoteInstrument{ +final class NoteInstrument{ use EnumTrait { __construct as Enum___construct; } @@ -54,7 +54,7 @@ class NoteInstrument{ /** @var int */ private $magicNumber; - public function __construct(string $name, int $magicNumber){ + private function __construct(string $name, int $magicNumber){ $this->Enum___construct($name); $this->magicNumber = $magicNumber; } From 1a1feefd3ee910288bbfef4fd7494cc081b3a3e7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jul 2019 18:06:49 +0100 Subject: [PATCH 1103/3224] Pull tier info out of TieredTool, create ToolTier enum --- src/pocketmine/block/Anvil.php | 4 +- src/pocketmine/block/BlockFactory.php | 50 +++++----- src/pocketmine/block/BoneBlock.php | 4 +- src/pocketmine/block/BrewingStand.php | 4 +- src/pocketmine/block/Coal.php | 4 +- src/pocketmine/block/CoalOre.php | 4 +- src/pocketmine/block/Concrete.php | 4 +- src/pocketmine/block/DiamondOre.php | 4 +- src/pocketmine/block/DragonEgg.php | 4 +- src/pocketmine/block/EmeraldOre.php | 4 +- src/pocketmine/block/EnchantingTable.php | 4 +- src/pocketmine/block/EnderChest.php | 4 +- src/pocketmine/block/Furnace.php | 4 +- src/pocketmine/block/GlazedTerracotta.php | 4 +- src/pocketmine/block/GlowingObsidian.php | 4 +- src/pocketmine/block/HardenedClay.php | 4 +- src/pocketmine/block/LapisOre.php | 4 +- src/pocketmine/block/Magma.php | 4 +- src/pocketmine/block/MonsterSpawner.php | 4 +- src/pocketmine/block/NetherQuartzOre.php | 4 +- src/pocketmine/block/NetherReactor.php | 4 +- src/pocketmine/block/Netherrack.php | 4 +- src/pocketmine/block/Redstone.php | 4 +- src/pocketmine/block/RedstoneOre.php | 4 +- src/pocketmine/block/Snow.php | 4 +- src/pocketmine/block/SnowLayer.php | 4 +- src/pocketmine/block/StonePressurePlate.php | 4 +- src/pocketmine/block/Wall.php | 4 +- .../block/WeightedPressurePlateHeavy.php | 4 +- .../block/WeightedPressurePlateLight.php | 4 +- src/pocketmine/item/Axe.php | 4 +- src/pocketmine/item/ItemFactory.php | 50 +++++----- src/pocketmine/item/Pickaxe.php | 4 +- src/pocketmine/item/Shovel.php | 4 +- src/pocketmine/item/Sword.php | 2 +- src/pocketmine/item/TieredTool.php | 65 ++---------- src/pocketmine/item/ToolTier.php | 99 +++++++++++++++++++ 37 files changed, 220 insertions(+), 174 deletions(-) create mode 100644 src/pocketmine/item/ToolTier.php diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index aecd4c9e58..34cdf10035 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -28,7 +28,7 @@ use pocketmine\block\utils\Fallable; use pocketmine\block\utils\FallableTrait; use pocketmine\inventory\AnvilInventory; use pocketmine\item\Item; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Bearing; use pocketmine\math\Facing; @@ -43,7 +43,7 @@ class Anvil extends Transparent implements Fallable{ protected $facing = Facing::NORTH; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 6000.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 6000.0)); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index c757bad175..e67b2b6468 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -50,7 +50,7 @@ use pocketmine\block\utils\PillarRotationTrait; use pocketmine\block\utils\TreeType; use pocketmine\item\Item; use pocketmine\item\ItemIds; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; use pocketmine\world\Position; use function array_fill; use function array_filter; @@ -99,7 +99,7 @@ class BlockFactory{ self::register(new Bookshelf(new BID(Ids::BOOKSHELF), "Bookshelf")); self::register(new BrewingStand(new BID(Ids::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND, TileBrewingStand::class), "Brewing Stand")); - $bricksBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0); + $bricksBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); self::register(new Stair(new BID(Ids::BRICK_STAIRS), "Brick Stairs", $bricksBreakInfo)); self::register(new Solid(new BID(Ids::BRICK_BLOCK), "Bricks", $bricksBreakInfo)); @@ -114,7 +114,7 @@ class BlockFactory{ self::register(new CoalOre(new BID(Ids::COAL_ORE), "Coal Ore")); self::register(new CoarseDirt(new BID(Ids::DIRT, Meta::DIRT_COARSE), "Coarse Dirt")); - $cobblestoneBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0); + $cobblestoneBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); self::register(new Solid(new BID(Ids::COBBLESTONE), "Cobblestone", $cobblestoneBreakInfo)); self::register(new Solid(new BID(Ids::MOSSY_COBBLESTONE), "Mossy Cobblestone", $cobblestoneBreakInfo)); self::register(new Stair(new BID(Ids::COBBLESTONE_STAIRS), "Cobblestone Stairs", $cobblestoneBreakInfo)); @@ -127,7 +127,7 @@ class BlockFactory{ self::register(new DeadBush(new BID(Ids::DEADBUSH), "Dead Bush")); self::register(new DetectorRail(new BID(Ids::DETECTOR_RAIL), "Detector Rail")); - self::register(new Solid(new BID(Ids::DIAMOND_BLOCK), "Diamond Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_IRON, 30.0))); + self::register(new Solid(new BID(Ids::DIAMOND_BLOCK), "Diamond Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); self::register(new DiamondOre(new BID(Ids::DIAMOND_ORE), "Diamond Ore")); self::register(new Dirt(new BID(Ids::DIRT, Meta::DIRT_NORMAL), "Dirt")); self::register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_SUNFLOWER), "Sunflower")); @@ -138,14 +138,14 @@ class BlockFactory{ self::register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LARGE_FERN), "Large Fern")); self::register(new DragonEgg(new BID(Ids::DRAGON_EGG), "Dragon Egg")); self::register(new DriedKelp(new BID(Ids::DRIED_KELP_BLOCK), "Dried Kelp Block", new BlockBreakInfo(0.5, BlockToolType::NONE, 0, 12.5))); - self::register(new Solid(new BID(Ids::EMERALD_BLOCK), "Emerald Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_IRON, 30.0))); + self::register(new Solid(new BID(Ids::EMERALD_BLOCK), "Emerald Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); self::register(new EmeraldOre(new BID(Ids::EMERALD_ORE), "Emerald Ore")); self::register(new EnchantingTable(new BID(Ids::ENCHANTING_TABLE, 0, null, TileEnchantingTable::class), "Enchanting Table")); self::register(new EndPortalFrame(new BID(Ids::END_PORTAL_FRAME), "End Portal Frame")); self::register(new EndRod(new BID(Ids::END_ROD), "End Rod")); - self::register(new Solid(new BID(Ids::END_STONE), "End Stone", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 45.0))); + self::register(new Solid(new BID(Ids::END_STONE), "End Stone", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 45.0))); - $endBrickBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 4.0); + $endBrickBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 4.0); self::register(new Solid(new BID(Ids::END_BRICKS), "End Stone Bricks", $endBrickBreakInfo)); self::register(new Stair(new BID(Ids::END_BRICK_STAIRS), "End Stone Brick Stairs", $endBrickBreakInfo)); @@ -171,8 +171,8 @@ class BlockFactory{ self::register(new GlassPane(new BID(Ids::GLASS_PANE), "Glass Pane")); self::register(new GlowingObsidian(new BID(Ids::GLOWINGOBSIDIAN), "Glowing Obsidian")); self::register(new Glowstone(new BID(Ids::GLOWSTONE), "Glowstone")); - self::register(new Solid(new BID(Ids::GOLD_BLOCK), "Gold Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_IRON, 30.0))); - self::register(new Solid(new BID(Ids::GOLD_ORE), "Gold Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_IRON))); + self::register(new Solid(new BID(Ids::GOLD_BLOCK), "Gold Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); + self::register(new Solid(new BID(Ids::GOLD_ORE), "Gold Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); self::register(new Grass(new BID(Ids::GRASS), "Grass")); self::register(new GrassPath(new BID(Ids::GRASS_PATH), "Grass Path")); self::register(new Gravel(new BID(Ids::GRAVEL), "Gravel")); @@ -180,7 +180,7 @@ class BlockFactory{ self::register(new HardenedGlass(new BID(Ids::HARD_GLASS), "Hardened Glass")); self::register(new HardenedGlassPane(new BID(Ids::HARD_GLASS_PANE), "Hardened Glass Pane")); self::register(new HayBale(new BID(Ids::HAY_BALE), "Hay Bale")); - self::register(new Hopper(new BID(Ids::HOPPER_BLOCK, 0, ItemIds::HOPPER, TileHopper::class), "Hopper", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 15.0))); + self::register(new Hopper(new BID(Ids::HOPPER_BLOCK, 0, ItemIds::HOPPER, TileHopper::class), "Hopper", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 15.0))); self::register(new Ice(new BID(Ids::ICE), "Ice")); self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE), "Infested Stone") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ @@ -217,14 +217,14 @@ class BlockFactory{ self::register(new Solid(new BID(Ids::INFO_UPDATE), "update!", $updateBlockBreakInfo)); self::register(new Solid(new BID(Ids::INFO_UPDATE2), "ate!upd", $updateBlockBreakInfo)); self::register(new Transparent(new BID(Ids::INVISIBLEBEDROCK), "Invisible Bedrock", BlockBreakInfo::indestructible())); - self::register(new Solid(new BID(Ids::IRON_BLOCK), "Iron Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_STONE, 30.0))); - self::register(new Thin(new BID(Ids::IRON_BARS), "Iron Bars", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0))); - self::register(new Door(new BID(Ids::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 25.0))); - self::register(new Solid(new BID(Ids::IRON_ORE), "Iron Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_STONE))); - self::register(new Trapdoor(new BID(Ids::IRON_TRAPDOOR), "Iron Trapdoor", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 25.0))); + self::register(new Solid(new BID(Ids::IRON_BLOCK), "Iron Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel(), 30.0))); + self::register(new Thin(new BID(Ids::IRON_BARS), "Iron Bars", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0))); + self::register(new Door(new BID(Ids::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0))); + self::register(new Solid(new BID(Ids::IRON_ORE), "Iron Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); + self::register(new Trapdoor(new BID(Ids::IRON_TRAPDOOR), "Iron Trapdoor", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0))); self::register(new ItemFrame(new BID(Ids::FRAME_BLOCK, 0, ItemIds::FRAME, TileItemFrame::class), "Item Frame")); self::register(new Ladder(new BID(Ids::LADDER), "Ladder")); - self::register(new Solid(new BID(Ids::LAPIS_BLOCK), "Lapis Lazuli Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_STONE))); + self::register(new Solid(new BID(Ids::LAPIS_BLOCK), "Lapis Lazuli Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); self::register(new LapisOre(new BID(Ids::LAPIS_ORE), "Lapis Lazuli Ore")); self::register(new Lava(new BIDFlattened(Ids::FLOWING_LAVA, Ids::STILL_LAVA), "Lava")); self::register(new Lever(new BID(Ids::LEVER), "Lever")); @@ -234,7 +234,7 @@ class BlockFactory{ self::register(new MonsterSpawner(new BID(Ids::MOB_SPAWNER, 0, null, TileMonsterSpawner::class), "Monster Spawner")); self::register(new Mycelium(new BID(Ids::MYCELIUM), "Mycelium")); - $netherBrickBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0); + $netherBrickBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); self::register(new Solid(new BID(Ids::NETHER_BRICK_BLOCK), "Nether Bricks", $netherBrickBreakInfo)); self::register(new Solid(new BID(Ids::RED_NETHER_BRICK), "Red Nether Bricks", $netherBrickBreakInfo)); self::register(new Fence(new BID(Ids::NETHER_BRICK_FENCE), "Nether Brick Fence", $netherBrickBreakInfo)); @@ -247,13 +247,13 @@ class BlockFactory{ self::register(new NetherWartPlant(new BID(Ids::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART), "Nether Wart")); self::register(new Netherrack(new BID(Ids::NETHERRACK), "Netherrack")); self::register(new Note(new BID(Ids::NOTEBLOCK, 0, null, TileNote::class), "Note Block")); - self::register(new Solid(new BID(Ids::OBSIDIAN), "Obsidian", new BlockBreakInfo(35.0 /* 50 in PC */, BlockToolType::PICKAXE, TieredTool::TIER_DIAMOND, 6000.0))); + self::register(new Solid(new BID(Ids::OBSIDIAN), "Obsidian", new BlockBreakInfo(35.0 /* 50 in PC */, BlockToolType::PICKAXE, ToolTier::DIAMOND()->getHarvestLevel(), 6000.0))); self::register(new PackedIce(new BID(Ids::PACKED_ICE), "Packed Ice")); self::register(new Podzol(new BID(Ids::PODZOL), "Podzol")); self::register(new Potato(new BID(Ids::POTATOES), "Potato Block")); self::register(new PoweredRail(new BID(Ids::GOLDEN_RAIL, Meta::RAIL_STRAIGHT_NORTH_SOUTH), "Powered Rail")); - $prismarineBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0); + $prismarineBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); self::register(new Solid(new BID(Ids::PRISMARINE, Meta::PRISMARINE_BRICKS), "Prismarine Bricks", $prismarineBreakInfo)); self::register(new Stair(new BID(Ids::PRISMARINE_BRICKS_STAIRS), "Prismarine Bricks Stairs", $prismarineBreakInfo)); self::register(new Solid(new BID(Ids::PRISMARINE, Meta::PRISMARINE_DARK), "Dark Prismarine", $prismarineBreakInfo)); @@ -271,14 +271,14 @@ class BlockFactory{ self::register(new PumpkinStem(new BID(Ids::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem")); - $purpurBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0); + $purpurBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); self::register(new Solid(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_NORMAL), "Purpur Block", $purpurBreakInfo)); self::register(new class(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_PILLAR), "Purpur Pillar", $purpurBreakInfo) extends Solid{ use PillarRotationTrait; }); self::register(new Stair(new BID(Ids::PURPUR_STAIRS), "Purpur Stairs", $purpurBreakInfo)); - $quartzBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN); + $quartzBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()); self::register(new Solid(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_NORMAL), "Quartz Block", $quartzBreakInfo)); self::register(new Stair(new BID(Ids::QUARTZ_STAIRS), "Quartz Stairs", $quartzBreakInfo)); self::register(new class(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_CHISELED), "Chiseled Quartz Block", $quartzBreakInfo) extends Solid{ @@ -314,7 +314,7 @@ class BlockFactory{ self::register(new SoulSand(new BID(Ids::SOUL_SAND), "Soul Sand")); self::register(new Sponge(new BID(Ids::SPONGE), "Sponge")); - $stoneBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0); + $stoneBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); self::register(new class(new BID(Ids::STONE, Meta::STONE_NORMAL), "Stone", $stoneBreakInfo) extends Solid{ public function getDropsForCompatibleTool(Item $item) : array{ return [VanillaBlocks::COBBLESTONE()->asItem()]; @@ -344,7 +344,7 @@ class BlockFactory{ self::register(new StonePressurePlate(new BID(Ids::STONE_PRESSURE_PLATE), "Stone Pressure Plate")); //TODO: in the future this won't be the same for all the types - $stoneSlabBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0); + $stoneSlabBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_BRICK), "Brick", $stoneSlabBreakInfo)); self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_COBBLESTONE), "Cobblestone", $stoneSlabBreakInfo)); self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_FAKE_WOODEN), "Fake Wooden", $stoneSlabBreakInfo)); @@ -374,7 +374,7 @@ class BlockFactory{ self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_MOSSY_STONE_BRICK), "Mossy Stone Brick", $stoneSlabBreakInfo)); self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_SMOOTH_QUARTZ), "Smooth Quartz", $stoneSlabBreakInfo)); self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_STONE), "Stone", $stoneSlabBreakInfo)); - self::register(new Solid(new BID(Ids::STONECUTTER), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN))); + self::register(new Solid(new BID(Ids::STONECUTTER), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); self::register(new Sugarcane(new BID(Ids::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane")); self::register(new TNT(new BID(Ids::TNT), "TNT")); @@ -498,7 +498,7 @@ class BlockFactory{ Meta::SANDSTONE_CUT => "Cut ", Meta::SANDSTONE_SMOOTH => "Smooth " ]; - $sandstoneBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN); + $sandstoneBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()); self::register(new Stair(new BID(Ids::RED_SANDSTONE_STAIRS), "Red Sandstone Stairs", $sandstoneBreakInfo)); self::register(new Stair(new BID(Ids::SMOOTH_RED_SANDSTONE_STAIRS), "Smooth Red Sandstone Stairs", $sandstoneBreakInfo)); self::register(new Stair(new BID(Ids::SANDSTONE_STAIRS), "Sandstone Stairs", $sandstoneBreakInfo)); diff --git a/src/pocketmine/block/BoneBlock.php b/src/pocketmine/block/BoneBlock.php index 36f8f751e9..35d1f7bce7 100644 --- a/src/pocketmine/block/BoneBlock.php +++ b/src/pocketmine/block/BoneBlock.php @@ -24,12 +24,12 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\PillarRotationTrait; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; class BoneBlock extends Solid{ use PillarRotationTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); } } diff --git a/src/pocketmine/block/BrewingStand.php b/src/pocketmine/block/BrewingStand.php index 13ef6f11d4..bfb820e941 100644 --- a/src/pocketmine/block/BrewingStand.php +++ b/src/pocketmine/block/BrewingStand.php @@ -25,7 +25,7 @@ namespace pocketmine\block; use pocketmine\block\tile\BrewingStand as TileBrewingStand; use pocketmine\item\Item; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -39,7 +39,7 @@ class BrewingStand extends Transparent{ protected $southwestSlot = false; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/Coal.php b/src/pocketmine/block/Coal.php index 1b7fae1d51..8b3d4257e4 100644 --- a/src/pocketmine/block/Coal.php +++ b/src/pocketmine/block/Coal.php @@ -23,12 +23,12 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; class Coal extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0)); } public function getFuelTime() : int{ diff --git a/src/pocketmine/block/CoalOre.php b/src/pocketmine/block/CoalOre.php index b1e58e177c..5643d8d546 100644 --- a/src/pocketmine/block/CoalOre.php +++ b/src/pocketmine/block/CoalOre.php @@ -24,14 +24,14 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; use function mt_rand; class CoalOre extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/Concrete.php b/src/pocketmine/block/Concrete.php index 1ef4806c6b..93243fee17 100644 --- a/src/pocketmine/block/Concrete.php +++ b/src/pocketmine/block/Concrete.php @@ -23,11 +23,11 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; class Concrete extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.8, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); } } diff --git a/src/pocketmine/block/DiamondOre.php b/src/pocketmine/block/DiamondOre.php index 1a03923df3..ff0ea297e0 100644 --- a/src/pocketmine/block/DiamondOre.php +++ b/src/pocketmine/block/DiamondOre.php @@ -24,14 +24,14 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; use function mt_rand; class DiamondOre extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_IRON)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel())); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/DragonEgg.php b/src/pocketmine/block/DragonEgg.php index 0ede5a6be4..97bc0683cc 100644 --- a/src/pocketmine/block/DragonEgg.php +++ b/src/pocketmine/block/DragonEgg.php @@ -27,7 +27,7 @@ use pocketmine\block\utils\Fallable; use pocketmine\block\utils\FallableTrait; use pocketmine\event\block\BlockTeleportEvent; use pocketmine\item\Item; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\world\particle\DragonEggTeleportParticle; @@ -40,7 +40,7 @@ class DragonEgg extends Transparent implements Fallable{ use FallableTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); } public function getLightLevel() : int{ diff --git a/src/pocketmine/block/EmeraldOre.php b/src/pocketmine/block/EmeraldOre.php index 0170efc313..4345ada463 100644 --- a/src/pocketmine/block/EmeraldOre.php +++ b/src/pocketmine/block/EmeraldOre.php @@ -24,14 +24,14 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; use function mt_rand; class EmeraldOre extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_IRON)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel())); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/EnchantingTable.php b/src/pocketmine/block/EnchantingTable.php index 96af742a2d..2edbf70870 100644 --- a/src/pocketmine/block/EnchantingTable.php +++ b/src/pocketmine/block/EnchantingTable.php @@ -25,7 +25,7 @@ namespace pocketmine\block; use pocketmine\inventory\EnchantInventory; use pocketmine\item\Item; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -34,7 +34,7 @@ use pocketmine\player\Player; class EnchantingTable extends Transparent{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 6000.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 6000.0)); } protected function recalculateBoundingBox() : ?AxisAlignedBB{ diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index e68c11ef46..1c01cf398d 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\block\tile\EnderChest as TileEnderChest; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -39,7 +39,7 @@ class EnderChest extends Transparent{ protected $facing = Facing::NORTH; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(22.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 3000.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(22.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 3000.0)); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index b242958ccc..3864118c8f 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\block\tile\Furnace as TileFurnace; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -42,7 +42,7 @@ class Furnace extends Solid{ protected $lit = false; //this is set based on the blockID public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); } public function getId() : int{ diff --git a/src/pocketmine/block/GlazedTerracotta.php b/src/pocketmine/block/GlazedTerracotta.php index 781492db79..5f680e0368 100644 --- a/src/pocketmine/block/GlazedTerracotta.php +++ b/src/pocketmine/block/GlazedTerracotta.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -38,7 +38,7 @@ class GlazedTerracotta extends Solid{ protected $facing = Facing::NORTH; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.4, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.4, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/GlowingObsidian.php b/src/pocketmine/block/GlowingObsidian.php index 9dfb73b300..74f5ba694a 100644 --- a/src/pocketmine/block/GlowingObsidian.php +++ b/src/pocketmine/block/GlowingObsidian.php @@ -24,12 +24,12 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; class GlowingObsidian extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(10.0, BlockToolType::PICKAXE, TieredTool::TIER_DIAMOND, 50.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(10.0, BlockToolType::PICKAXE, ToolTier::DIAMOND()->getHarvestLevel(), 50.0)); } public function getLightLevel() : int{ diff --git a/src/pocketmine/block/HardenedClay.php b/src/pocketmine/block/HardenedClay.php index 8c46c4ad1e..293d2f4ecd 100644 --- a/src/pocketmine/block/HardenedClay.php +++ b/src/pocketmine/block/HardenedClay.php @@ -23,11 +23,11 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; class HardenedClay extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.25, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 21.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.25, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 21.0)); } } diff --git a/src/pocketmine/block/LapisOre.php b/src/pocketmine/block/LapisOre.php index 97a5666b6b..a1e49f227d 100644 --- a/src/pocketmine/block/LapisOre.php +++ b/src/pocketmine/block/LapisOre.php @@ -24,14 +24,14 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; use function mt_rand; class LapisOre extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_STONE)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel())); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/Magma.php b/src/pocketmine/block/Magma.php index 887dba1b37..16f1e4435c 100644 --- a/src/pocketmine/block/Magma.php +++ b/src/pocketmine/block/Magma.php @@ -26,12 +26,12 @@ namespace pocketmine\block; use pocketmine\entity\Entity; use pocketmine\event\entity\EntityDamageByBlockEvent; use pocketmine\event\entity\EntityDamageEvent; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; class Magma extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); } public function getLightLevel() : int{ diff --git a/src/pocketmine/block/MonsterSpawner.php b/src/pocketmine/block/MonsterSpawner.php index d545b0427c..b27f6c0d8d 100644 --- a/src/pocketmine/block/MonsterSpawner.php +++ b/src/pocketmine/block/MonsterSpawner.php @@ -24,13 +24,13 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; use function mt_rand; class MonsterSpawner extends Transparent{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/NetherQuartzOre.php b/src/pocketmine/block/NetherQuartzOre.php index 54efd1a336..7c55be08fa 100644 --- a/src/pocketmine/block/NetherQuartzOre.php +++ b/src/pocketmine/block/NetherQuartzOre.php @@ -24,14 +24,14 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; use function mt_rand; class NetherQuartzOre extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/NetherReactor.php b/src/pocketmine/block/NetherReactor.php index a18907e94e..800ac583d8 100644 --- a/src/pocketmine/block/NetherReactor.php +++ b/src/pocketmine/block/NetherReactor.php @@ -25,7 +25,7 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataValidator; use pocketmine\item\Item; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; class NetherReactor extends Solid{ @@ -34,7 +34,7 @@ class NetherReactor extends Solid{ protected $state = BlockLegacyMetadata::NETHER_REACTOR_INACTIVE; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/Netherrack.php b/src/pocketmine/block/Netherrack.php index a6a3f70e60..f1db4323f7 100644 --- a/src/pocketmine/block/Netherrack.php +++ b/src/pocketmine/block/Netherrack.php @@ -23,12 +23,12 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; class Netherrack extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.4, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.4, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); } public function burnsForever() : bool{ diff --git a/src/pocketmine/block/Redstone.php b/src/pocketmine/block/Redstone.php index b4400b0c14..6c22fbc56d 100644 --- a/src/pocketmine/block/Redstone.php +++ b/src/pocketmine/block/Redstone.php @@ -23,11 +23,11 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; class Redstone extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0)); } } diff --git a/src/pocketmine/block/RedstoneOre.php b/src/pocketmine/block/RedstoneOre.php index 11b8664240..8fe05ed25c 100644 --- a/src/pocketmine/block/RedstoneOre.php +++ b/src/pocketmine/block/RedstoneOre.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -38,7 +38,7 @@ class RedstoneOre extends Solid{ protected $lit = false; public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, TieredTool::TIER_IRON)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel())); } public function getId() : int{ diff --git a/src/pocketmine/block/Snow.php b/src/pocketmine/block/Snow.php index 22279086c0..02e98af2ed 100644 --- a/src/pocketmine/block/Snow.php +++ b/src/pocketmine/block/Snow.php @@ -24,13 +24,13 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; class Snow extends Solid{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::SHOVEL, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::SHOVEL, ToolTier::WOOD()->getHarvestLevel())); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index d861c02971..8c917d86cc 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -27,7 +27,7 @@ use pocketmine\block\utils\BlockDataValidator; use pocketmine\block\utils\Fallable; use pocketmine\block\utils\FallableTrait; use pocketmine\item\Item; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -44,7 +44,7 @@ class SnowLayer extends Flowable implements Fallable{ protected $layers = 1; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.1, BlockToolType::SHOVEL, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.1, BlockToolType::SHOVEL, ToolTier::WOOD()->getHarvestLevel())); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/StonePressurePlate.php b/src/pocketmine/block/StonePressurePlate.php index a6c1c0de63..7635d98c6a 100644 --- a/src/pocketmine/block/StonePressurePlate.php +++ b/src/pocketmine/block/StonePressurePlate.php @@ -23,11 +23,11 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; class StonePressurePlate extends SimplePressurePlate{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); } } diff --git a/src/pocketmine/block/Wall.php b/src/pocketmine/block/Wall.php index e4462767dc..c2af8d1b16 100644 --- a/src/pocketmine/block/Wall.php +++ b/src/pocketmine/block/Wall.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -35,7 +35,7 @@ class Wall extends Transparent{ protected $up = false; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN, 30.0)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0)); } public function readStateFromWorld() : void{ diff --git a/src/pocketmine/block/WeightedPressurePlateHeavy.php b/src/pocketmine/block/WeightedPressurePlateHeavy.php index 40fd3c507b..33b7fe08c2 100644 --- a/src/pocketmine/block/WeightedPressurePlateHeavy.php +++ b/src/pocketmine/block/WeightedPressurePlateHeavy.php @@ -23,11 +23,11 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; class WeightedPressurePlateHeavy extends WeightedPressurePlate{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); } } diff --git a/src/pocketmine/block/WeightedPressurePlateLight.php b/src/pocketmine/block/WeightedPressurePlateLight.php index 44b2f41e28..15ea238bf8 100644 --- a/src/pocketmine/block/WeightedPressurePlateLight.php +++ b/src/pocketmine/block/WeightedPressurePlateLight.php @@ -23,11 +23,11 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\TieredTool; +use pocketmine\item\ToolTier; class WeightedPressurePlateLight extends WeightedPressurePlate{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, TieredTool::TIER_WOODEN)); + parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); } } diff --git a/src/pocketmine/item/Axe.php b/src/pocketmine/item/Axe.php index 816f464445..15305d05ff 100644 --- a/src/pocketmine/item/Axe.php +++ b/src/pocketmine/item/Axe.php @@ -34,11 +34,11 @@ class Axe extends TieredTool{ } public function getBlockToolHarvestLevel() : int{ - return $this->tier; + return $this->tier->getHarvestLevel(); } public function getAttackPoints() : int{ - return self::getBaseDamageFromTier($this->tier) - 1; + return $this->tier->getBaseAttackPoints() - 1; } public function onDestroyBlock(Block $block) : bool{ diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index 22199d7bcc..b341fa3701 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -57,11 +57,11 @@ class ItemFactory{ self::register(new Apple(Item::APPLE, 0, "Apple")); self::register(new Arrow(Item::ARROW, 0, "Arrow")); - self::register(new Axe(Item::DIAMOND_AXE, "Diamond Axe", TieredTool::TIER_DIAMOND)); - self::register(new Axe(Item::GOLDEN_AXE, "Golden Axe", TieredTool::TIER_GOLD)); - self::register(new Axe(Item::IRON_AXE, "Iron Axe", TieredTool::TIER_IRON)); - self::register(new Axe(Item::STONE_AXE, "Stone Axe", TieredTool::TIER_STONE)); - self::register(new Axe(Item::WOODEN_AXE, "Wooden Axe", TieredTool::TIER_WOODEN)); + self::register(new Axe(Item::DIAMOND_AXE, "Diamond Axe", ToolTier::DIAMOND())); + self::register(new Axe(Item::GOLDEN_AXE, "Golden Axe", ToolTier::GOLD())); + self::register(new Axe(Item::IRON_AXE, "Iron Axe", ToolTier::IRON())); + self::register(new Axe(Item::STONE_AXE, "Stone Axe", ToolTier::STONE())); + self::register(new Axe(Item::WOODEN_AXE, "Wooden Axe", ToolTier::WOOD())); self::register(new BakedPotato(Item::BAKED_POTATO, 0, "Baked Potato")); self::register(new Beetroot(Item::BEETROOT, 0, "Beetroot")); self::register(new BeetrootSeeds(Item::BEETROOT_SEEDS, 0, "Beetroot Seeds")); @@ -113,11 +113,11 @@ class ItemFactory{ self::register(new Helmet(Item::GOLDEN_HELMET, 0, "Golden Helmet", new ArmorTypeInfo(2, 78))); self::register(new Helmet(Item::IRON_HELMET, 0, "Iron Helmet", new ArmorTypeInfo(2, 166))); self::register(new Helmet(Item::LEATHER_HELMET, 0, "Leather Cap", new ArmorTypeInfo(1, 56))); - self::register(new Hoe(Item::DIAMOND_HOE, "Diamond Hoe", TieredTool::TIER_DIAMOND)); - self::register(new Hoe(Item::GOLDEN_HOE, "Golden Hoe", TieredTool::TIER_GOLD)); - self::register(new Hoe(Item::IRON_HOE, "Iron Hoe", TieredTool::TIER_IRON)); - self::register(new Hoe(Item::STONE_HOE, "Stone Hoe", TieredTool::TIER_STONE)); - self::register(new Hoe(Item::WOODEN_HOE, "Wooden Hoe", TieredTool::TIER_WOODEN)); + self::register(new Hoe(Item::DIAMOND_HOE, "Diamond Hoe", ToolTier::DIAMOND())); + self::register(new Hoe(Item::GOLDEN_HOE, "Golden Hoe", ToolTier::GOLD())); + self::register(new Hoe(Item::IRON_HOE, "Iron Hoe", ToolTier::IRON())); + self::register(new Hoe(Item::STONE_HOE, "Stone Hoe", ToolTier::STONE())); + self::register(new Hoe(Item::WOODEN_HOE, "Wooden Hoe", ToolTier::WOOD())); self::register(new Item(Item::BLAZE_POWDER, 0, "Blaze Powder")); self::register(new Item(Item::BLEACH, 0, "Bleach")); //EDU self::register(new Item(Item::BONE, 0, "Bone")); @@ -227,11 +227,11 @@ class ItemFactory{ self::register(new Minecart(Item::MINECART, 0, "Minecart")); self::register(new MushroomStew(Item::MUSHROOM_STEW, 0, "Mushroom Stew")); self::register(new PaintingItem(Item::PAINTING, 0, "Painting")); - self::register(new Pickaxe(Item::DIAMOND_PICKAXE, "Diamond Pickaxe", TieredTool::TIER_DIAMOND)); - self::register(new Pickaxe(Item::GOLDEN_PICKAXE, "Golden Pickaxe", TieredTool::TIER_GOLD)); - self::register(new Pickaxe(Item::IRON_PICKAXE, "Iron Pickaxe", TieredTool::TIER_IRON)); - self::register(new Pickaxe(Item::STONE_PICKAXE, "Stone Pickaxe", TieredTool::TIER_STONE)); - self::register(new Pickaxe(Item::WOODEN_PICKAXE, "Wooden Pickaxe", TieredTool::TIER_WOODEN)); + self::register(new Pickaxe(Item::DIAMOND_PICKAXE, "Diamond Pickaxe", ToolTier::DIAMOND())); + self::register(new Pickaxe(Item::GOLDEN_PICKAXE, "Golden Pickaxe", ToolTier::GOLD())); + self::register(new Pickaxe(Item::IRON_PICKAXE, "Iron Pickaxe", ToolTier::IRON())); + self::register(new Pickaxe(Item::STONE_PICKAXE, "Stone Pickaxe", ToolTier::STONE())); + self::register(new Pickaxe(Item::WOODEN_PICKAXE, "Wooden Pickaxe", ToolTier::WOOD())); self::register(new PoisonousPotato(Item::POISONOUS_POTATO, 0, "Poisonous Potato")); self::register(new Potato(Item::POTATO, 0, "Potato")); self::register(new Pufferfish(Item::PUFFERFISH, 0, "Pufferfish")); @@ -248,11 +248,11 @@ class ItemFactory{ self::register(new Redstone(Item::REDSTONE, 0, "Redstone")); self::register(new RottenFlesh(Item::ROTTEN_FLESH, 0, "Rotten Flesh")); self::register(new Shears(Item::SHEARS, 0, "Shears")); - self::register(new Shovel(Item::DIAMOND_SHOVEL, "Diamond Shovel", TieredTool::TIER_DIAMOND)); - self::register(new Shovel(Item::GOLDEN_SHOVEL, "Golden Shovel", TieredTool::TIER_GOLD)); - self::register(new Shovel(Item::IRON_SHOVEL, "Iron Shovel", TieredTool::TIER_IRON)); - self::register(new Shovel(Item::STONE_SHOVEL, "Stone Shovel", TieredTool::TIER_STONE)); - self::register(new Shovel(Item::WOODEN_SHOVEL, "Wooden Shovel", TieredTool::TIER_WOODEN)); + self::register(new Shovel(Item::DIAMOND_SHOVEL, "Diamond Shovel", ToolTier::DIAMOND())); + self::register(new Shovel(Item::GOLDEN_SHOVEL, "Golden Shovel", ToolTier::GOLD())); + self::register(new Shovel(Item::IRON_SHOVEL, "Iron Shovel", ToolTier::IRON())); + self::register(new Shovel(Item::STONE_SHOVEL, "Stone Shovel", ToolTier::STONE())); + self::register(new Shovel(Item::WOODEN_SHOVEL, "Wooden Shovel", ToolTier::WOOD())); self::register(new Sign(BlockLegacyIds::STANDING_SIGN, 0, Item::SIGN)); self::register(new Sign(BlockLegacyIds::SPRUCE_STANDING_SIGN, 0, Item::SPRUCE_SIGN)); self::register(new Sign(BlockLegacyIds::BIRCH_STANDING_SIGN, 0, Item::BIRCH_SIGN)); @@ -264,11 +264,11 @@ class ItemFactory{ self::register(new Steak(Item::STEAK, 0, "Steak")); self::register(new Stick(Item::STICK, 0, "Stick")); self::register(new StringItem(Item::STRING, 0, "String")); - self::register(new Sword(Item::DIAMOND_SWORD, "Diamond Sword", TieredTool::TIER_DIAMOND)); - self::register(new Sword(Item::GOLDEN_SWORD, "Golden Sword", TieredTool::TIER_GOLD)); - self::register(new Sword(Item::IRON_SWORD, "Iron Sword", TieredTool::TIER_IRON)); - self::register(new Sword(Item::STONE_SWORD, "Stone Sword", TieredTool::TIER_STONE)); - self::register(new Sword(Item::WOODEN_SWORD, "Wooden Sword", TieredTool::TIER_WOODEN)); + self::register(new Sword(Item::DIAMOND_SWORD, "Diamond Sword", ToolTier::DIAMOND())); + self::register(new Sword(Item::GOLDEN_SWORD, "Golden Sword", ToolTier::GOLD())); + self::register(new Sword(Item::IRON_SWORD, "Iron Sword", ToolTier::IRON())); + self::register(new Sword(Item::STONE_SWORD, "Stone Sword", ToolTier::STONE())); + self::register(new Sword(Item::WOODEN_SWORD, "Wooden Sword", ToolTier::WOOD())); self::register(new Totem(Item::TOTEM, 0, "Totem of Undying")); self::register(new WheatSeeds(Item::WHEAT_SEEDS, 0, "Wheat Seeds")); self::register(new WritableBook(Item::WRITABLE_BOOK, 0, "Book & Quill")); diff --git a/src/pocketmine/item/Pickaxe.php b/src/pocketmine/item/Pickaxe.php index 76fbd49d1c..4e1a7693e8 100644 --- a/src/pocketmine/item/Pickaxe.php +++ b/src/pocketmine/item/Pickaxe.php @@ -34,11 +34,11 @@ class Pickaxe extends TieredTool{ } public function getBlockToolHarvestLevel() : int{ - return $this->tier; + return $this->tier->getHarvestLevel(); } public function getAttackPoints() : int{ - return self::getBaseDamageFromTier($this->tier) - 2; + return $this->tier->getBaseAttackPoints() - 2; } public function onDestroyBlock(Block $block) : bool{ diff --git a/src/pocketmine/item/Shovel.php b/src/pocketmine/item/Shovel.php index f3afc9494e..c167bd2ba7 100644 --- a/src/pocketmine/item/Shovel.php +++ b/src/pocketmine/item/Shovel.php @@ -34,11 +34,11 @@ class Shovel extends TieredTool{ } public function getBlockToolHarvestLevel() : int{ - return $this->tier; + return $this->tier->getHarvestLevel(); } public function getAttackPoints() : int{ - return self::getBaseDamageFromTier($this->tier) - 3; + return $this->tier->getBaseAttackPoints() - 3; } public function onDestroyBlock(Block $block) : bool{ diff --git a/src/pocketmine/item/Sword.php b/src/pocketmine/item/Sword.php index 24c46a36e2..99ffc82ba2 100644 --- a/src/pocketmine/item/Sword.php +++ b/src/pocketmine/item/Sword.php @@ -34,7 +34,7 @@ class Sword extends TieredTool{ } public function getAttackPoints() : int{ - return self::getBaseDamageFromTier($this->tier); + return $this->tier->getBaseAttackPoints(); } public function getBlockToolHarvestLevel() : int{ diff --git a/src/pocketmine/item/TieredTool.php b/src/pocketmine/item/TieredTool.php index ac276f5e24..eb1998fe38 100644 --- a/src/pocketmine/item/TieredTool.php +++ b/src/pocketmine/item/TieredTool.php @@ -24,82 +24,29 @@ declare(strict_types=1); namespace pocketmine\item; abstract class TieredTool extends Tool{ - public const TIER_WOODEN = 1; - public const TIER_GOLD = 2; - public const TIER_STONE = 3; - public const TIER_IRON = 4; - public const TIER_DIAMOND = 5; - /** @var int */ + /** @var ToolTier */ protected $tier; - public function __construct(int $id, string $name, int $tier){ + public function __construct(int $id, string $name, ToolTier $tier){ parent::__construct($id, 0, $name); $this->tier = $tier; } public function getMaxDurability() : int{ - return self::getDurabilityFromTier($this->tier); + return $this->tier->getMaxDurability(); } - public function getTier() : int{ + public function getTier() : ToolTier{ return $this->tier; } - public static function getDurabilityFromTier(int $tier) : int{ - static $levels = [ - self::TIER_GOLD => 33, - self::TIER_WOODEN => 60, - self::TIER_STONE => 132, - self::TIER_IRON => 251, - self::TIER_DIAMOND => 1562 - ]; - - if(!isset($levels[$tier])){ - throw new \InvalidArgumentException("Unknown tier '$tier'"); - } - - return $levels[$tier]; - } - - protected static function getBaseDamageFromTier(int $tier) : int{ - static $levels = [ - self::TIER_WOODEN => 5, - self::TIER_GOLD => 5, - self::TIER_STONE => 6, - self::TIER_IRON => 7, - self::TIER_DIAMOND => 8 - ]; - - if(!isset($levels[$tier])){ - throw new \InvalidArgumentException("Unknown tier '$tier'"); - } - - return $levels[$tier]; - } - - public static function getBaseMiningEfficiencyFromTier(int $tier) : float{ - static $levels = [ - self::TIER_WOODEN => 2, - self::TIER_STONE => 4, - self::TIER_IRON => 6, - self::TIER_DIAMOND => 8, - self::TIER_GOLD => 12 - ]; - - if(!isset($levels[$tier])){ - throw new \InvalidArgumentException("Unknown tier '$tier'"); - } - - return $levels[$tier]; - } - protected function getBaseMiningEfficiency() : float{ - return self::getBaseMiningEfficiencyFromTier($this->tier); + return $this->tier->getBaseEfficiency(); } public function getFuelTime() : int{ - if($this->tier === self::TIER_WOODEN){ + if($this->tier->equals(ToolTier::WOOD())){ return 200; } diff --git a/src/pocketmine/item/ToolTier.php b/src/pocketmine/item/ToolTier.php new file mode 100644 index 0000000000..129da6bb22 --- /dev/null +++ b/src/pocketmine/item/ToolTier.php @@ -0,0 +1,99 @@ +Enum___construct($name); + $this->harvestLevel = $harvestLevel; + $this->maxDurability = $maxDurability; + $this->baseAttackPoints = $baseAttackPoints; + $this->baseEfficiency = $baseEfficiency; + } + + /** + * @return int + */ + public function getHarvestLevel() : int{ + return $this->harvestLevel; + } + + /** + * @return int + */ + public function getMaxDurability() : int{ + return $this->maxDurability; + } + + /** + * @return int + */ + public function getBaseAttackPoints() : int{ + return $this->baseAttackPoints; + } + + /** + * @return int + */ + public function getBaseEfficiency() : int{ + return $this->baseEfficiency; + } +} From 728aa8aae722f4c59a5ae57b102a54c5f503b7b5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jul 2019 19:59:28 +0100 Subject: [PATCH 1104/3224] RegistryTrait: Alias internal methods by default it's always necessary to wrap these methods with the appropriate typehints. --- src/pocketmine/block/VanillaBlocks.php | 12 ++++-------- src/pocketmine/item/VanillaItems.php | 12 ++++-------- src/pocketmine/utils/EnumTrait.php | 12 ++++-------- src/pocketmine/utils/RegistryTrait.php | 6 +++--- 4 files changed, 15 insertions(+), 27 deletions(-) diff --git a/src/pocketmine/block/VanillaBlocks.php b/src/pocketmine/block/VanillaBlocks.php index 1b595551c0..8a2398167e 100644 --- a/src/pocketmine/block/VanillaBlocks.php +++ b/src/pocketmine/block/VanillaBlocks.php @@ -664,18 +664,14 @@ use function assert; * @method static Wool YELLOW_WOOL() */ final class VanillaBlocks{ - use RegistryTrait { - fromString as private Registry_fromString; - getAll as private Registry_getAll; - register as private Registry_register; - } + use RegistryTrait; private function __construct(){ //NOOP } protected static function register(string $name, Block $block) : void{ - self::Registry_register($name, $block); + self::_registryRegister($name, $block); } /** @@ -684,7 +680,7 @@ final class VanillaBlocks{ * @return Block */ public static function fromString(string $name) : Block{ - $result = self::Registry_fromString($name); + $result = self::_registryFromString($name); assert($result instanceof Block); return clone $result; } @@ -693,7 +689,7 @@ final class VanillaBlocks{ * @return Block[] */ public static function getAll() : array{ - return array_map(function(Block $member){ return clone $member; }, self::Registry_getAll()); + return array_map(function(Block $member){ return clone $member; }, self::_registryGetAll()); } protected static function setup() : void{ diff --git a/src/pocketmine/item/VanillaItems.php b/src/pocketmine/item/VanillaItems.php index aed8749ddd..b1c0decda7 100644 --- a/src/pocketmine/item/VanillaItems.php +++ b/src/pocketmine/item/VanillaItems.php @@ -292,18 +292,14 @@ use function assert; * @method static Skull ZOMBIE_HEAD() */ final class VanillaItems{ - use RegistryTrait { - fromString as private Registry_fromString; - getAll as private Registry_getAll; - register as private Registry_register; - } + use RegistryTrait; private function __construct(){ //NOOP } protected static function register(string $name, Item $item) : void{ - self::Registry_register($name, $item); + self::_registryRegister($name, $item); } /** @@ -312,7 +308,7 @@ final class VanillaItems{ * @return Item */ public static function fromString(string $name) : Item{ - $result = self::Registry_fromString($name); + $result = self::_registryFromString($name); assert($result instanceof Item); return clone $result; } @@ -321,7 +317,7 @@ final class VanillaItems{ * @return Item[] */ public static function getAll() : array{ - return array_map(function(Item $member){ return clone $member; }, self::Registry_getAll()); + return array_map(function(Item $member){ return clone $member; }, self::_registryGetAll()); } protected static function setup() : void{ diff --git a/src/pocketmine/utils/EnumTrait.php b/src/pocketmine/utils/EnumTrait.php index 9563225f97..351e8d5b1e 100644 --- a/src/pocketmine/utils/EnumTrait.php +++ b/src/pocketmine/utils/EnumTrait.php @@ -26,11 +26,7 @@ namespace pocketmine\utils; use function preg_match; trait EnumTrait{ - use RegistryTrait { - fromString as private Registry_fromString; - getAll as private Registry_getAll; - register as private Registry_register; - } + use RegistryTrait; /** * Registers the given object as an enum member. @@ -40,7 +36,7 @@ trait EnumTrait{ * @throws \InvalidArgumentException */ protected static function register(self $member) : void{ - self::Registry_register($member->name(), $member); + self::_registryRegister($member->name(), $member); } /** @@ -73,7 +69,7 @@ trait EnumTrait{ * @return self[] */ public static function getAll() : array{ - return self::Registry_getAll(); + return self::_registryGetAll(); } /** @@ -86,7 +82,7 @@ trait EnumTrait{ * @throws \InvalidArgumentException if no member matches. */ public static function fromString(string $name) : self{ - return self::Registry_fromString($name); + return self::_registryFromString($name); } /** @var string */ diff --git a/src/pocketmine/utils/RegistryTrait.php b/src/pocketmine/utils/RegistryTrait.php index d1e57e521f..f905ad7ac6 100644 --- a/src/pocketmine/utils/RegistryTrait.php +++ b/src/pocketmine/utils/RegistryTrait.php @@ -44,7 +44,7 @@ trait RegistryTrait{ * * @throws \InvalidArgumentException */ - protected static function register(string $name, object $member) : void{ + private static function _registryRegister(string $name, object $member) : void{ $name = strtoupper($name); if(isset(self::$members[$name])){ throw new \InvalidArgumentException("\"$name\" is already reserved"); @@ -77,7 +77,7 @@ trait RegistryTrait{ * @return object * @throws \InvalidArgumentException */ - public static function fromString(string $name) : object{ + private static function _registryFromString(string $name) : object{ self::checkInit(); $name = strtoupper($name); if(!isset(self::$members[$name])){ @@ -106,7 +106,7 @@ trait RegistryTrait{ /** * @return object[] */ - public static function getAll() : array{ + private static function _registryGetAll() : array{ self::checkInit(); return self::$members; } From 64948f38d019eab56e34fdb40b59c357ef593684 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Jul 2019 15:49:58 +0100 Subject: [PATCH 1105/3224] Separate effect registry from base Effect class --- .../command/defaults/EffectCommand.php | 6 +- src/pocketmine/entity/EntityFactory.php | 2 - src/pocketmine/entity/Human.php | 8 +- src/pocketmine/entity/Living.php | 16 +- src/pocketmine/entity/effect/Effect.php | 203 ------------------ .../entity/effect/VanillaEffects.php | 134 ++++++++++++ .../entity/EntityDamageByEntityEvent.php | 10 +- src/pocketmine/item/GoldenApple.php | 6 +- src/pocketmine/item/GoldenAppleEnchanted.php | 10 +- src/pocketmine/item/PoisonousPotato.php | 4 +- src/pocketmine/item/Potion.php | 66 +++--- src/pocketmine/item/Pufferfish.php | 8 +- src/pocketmine/item/RawChicken.php | 4 +- src/pocketmine/item/RottenFlesh.php | 4 +- src/pocketmine/item/SpiderEye.php | 4 +- src/pocketmine/player/Player.php | 4 +- 16 files changed, 209 insertions(+), 280 deletions(-) create mode 100644 src/pocketmine/entity/effect/VanillaEffects.php diff --git a/src/pocketmine/command/defaults/EffectCommand.php b/src/pocketmine/command/defaults/EffectCommand.php index 4eea21c743..6f95a1b130 100644 --- a/src/pocketmine/command/defaults/EffectCommand.php +++ b/src/pocketmine/command/defaults/EffectCommand.php @@ -25,8 +25,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; -use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; +use pocketmine\entity\effect\VanillaEffects; use pocketmine\lang\TranslationContainer; use pocketmine\utils\TextFormat; use function count; @@ -68,10 +68,10 @@ class EffectCommand extends VanillaCommand{ return true; } - $effect = Effect::fromString($args[1]); + $effect = VanillaEffects::fromString($args[1]); if($effect === null){ - $effect = Effect::get((int) $args[1]); + $effect = VanillaEffects::byMcpeId((int) $args[1]); } if($effect === null){ diff --git a/src/pocketmine/entity/EntityFactory.php b/src/pocketmine/entity/EntityFactory.php index fcac6d759e..d3a71f367a 100644 --- a/src/pocketmine/entity/EntityFactory.php +++ b/src/pocketmine/entity/EntityFactory.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\entity; -use pocketmine\entity\effect\Effect; use pocketmine\entity\object\ExperienceOrb; use pocketmine\entity\object\FallingBlock; use pocketmine\entity\object\ItemEntity; @@ -98,7 +97,6 @@ final class EntityFactory{ self::register(Human::class, ['Human']); Attribute::init(); - Effect::init(); PaintingMotive::init(); } diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 472435348a..e72a5b494b 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\entity; -use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; +use pocketmine\entity\effect\VanillaEffects; use pocketmine\entity\projectile\ProjectileSource; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\player\PlayerExhaustEvent; @@ -315,9 +315,9 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ if($totemModifier < 0){ //Totem prevented death $this->effectManager->clear(); - $this->effectManager->add(new EffectInstance(Effect::REGENERATION(), 40 * 20, 1)); - $this->effectManager->add(new EffectInstance(Effect::FIRE_RESISTANCE(), 40 * 20, 1)); - $this->effectManager->add(new EffectInstance(Effect::ABSORPTION(), 5 * 20, 1)); + $this->effectManager->add(new EffectInstance(VanillaEffects::REGENERATION(), 40 * 20, 1)); + $this->effectManager->add(new EffectInstance(VanillaEffects::FIRE_RESISTANCE(), 40 * 20, 1)); + $this->effectManager->add(new EffectInstance(VanillaEffects::ABSORPTION(), 5 * 20, 1)); $this->broadcastEntityEvent(ActorEventPacket::CONSUME_TOTEM); $this->world->addSound($this->add(0, $this->eyeHeight, 0), new TotemUseSound()); diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 853cb9fc64..b56b484b70 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -24,9 +24,9 @@ declare(strict_types=1); namespace pocketmine\entity; use pocketmine\block\Block; -use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\EffectManager; +use pocketmine\entity\effect\VanillaEffects; use pocketmine\event\entity\EntityDamageByChildEntityEvent; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; @@ -118,7 +118,7 @@ abstract class Living extends Entity{ $activeEffectsTag = $nbt->getListTag("ActiveEffects"); if($activeEffectsTag !== null){ foreach($activeEffectsTag as $e){ - $effect = Effect::get($e->getByte("Id")); + $effect = VanillaEffects::byMcpeId($e->getByte("Id")); if($effect === null){ continue; } @@ -241,7 +241,7 @@ abstract class Living extends Entity{ * @return float */ public function getJumpVelocity() : float{ - return $this->jumpVelocity + ($this->effectManager->has(Effect::JUMP_BOOST()) ? ($this->effectManager->get(Effect::JUMP_BOOST())->getEffectLevel() / 10) : 0); + return $this->jumpVelocity + ($this->effectManager->has(VanillaEffects::JUMP_BOOST()) ? ($this->effectManager->get(VanillaEffects::JUMP_BOOST())->getEffectLevel() / 10) : 0); } /** @@ -254,7 +254,7 @@ abstract class Living extends Entity{ } public function fall(float $fallDistance) : void{ - $damage = ceil($fallDistance - 3 - ($this->effectManager->has(Effect::JUMP_BOOST()) ? $this->effectManager->get(Effect::JUMP_BOOST())->getEffectLevel() : 0)); + $damage = ceil($fallDistance - 3 - ($this->effectManager->has(VanillaEffects::JUMP_BOOST()) ? $this->effectManager->get(VanillaEffects::JUMP_BOOST())->getEffectLevel() : 0)); if($damage > 0){ $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FALL, $damage); $this->attack($ev); @@ -317,8 +317,8 @@ abstract class Living extends Entity{ } $cause = $source->getCause(); - if($this->effectManager->has(Effect::RESISTANCE()) and $cause !== EntityDamageEvent::CAUSE_VOID and $cause !== EntityDamageEvent::CAUSE_SUICIDE){ - $source->setModifier(-$source->getFinalDamage() * min(1, 0.2 * $this->effectManager->get(Effect::RESISTANCE())->getEffectLevel()), EntityDamageEvent::MODIFIER_RESISTANCE); + if($this->effectManager->has(VanillaEffects::RESISTANCE()) and $cause !== EntityDamageEvent::CAUSE_VOID and $cause !== EntityDamageEvent::CAUSE_SUICIDE){ + $source->setModifier(-$source->getFinalDamage() * min(1, 0.2 * $this->effectManager->get(VanillaEffects::RESISTANCE())->getEffectLevel()), EntityDamageEvent::MODIFIER_RESISTANCE); } $totalEpf = 0; @@ -400,7 +400,7 @@ abstract class Living extends Entity{ } } - if($this->effectManager->has(Effect::FIRE_RESISTANCE()) and ( + if($this->effectManager->has(VanillaEffects::FIRE_RESISTANCE()) and ( $source->getCause() === EntityDamageEvent::CAUSE_FIRE or $source->getCause() === EntityDamageEvent::CAUSE_FIRE_TICK or $source->getCause() === EntityDamageEvent::CAUSE_LAVA @@ -590,7 +590,7 @@ abstract class Living extends Entity{ * @return bool */ public function canBreathe() : bool{ - return $this->effectManager->has(Effect::WATER_BREATHING()) or $this->effectManager->has(Effect::CONDUIT_POWER()) or !$this->isUnderwater(); + return $this->effectManager->has(VanillaEffects::WATER_BREATHING()) or $this->effectManager->has(VanillaEffects::CONDUIT_POWER()) or !$this->isUnderwater(); } /** diff --git a/src/pocketmine/entity/effect/Effect.php b/src/pocketmine/entity/effect/Effect.php index 5774c338a7..6e7192e2e4 100644 --- a/src/pocketmine/entity/effect/Effect.php +++ b/src/pocketmine/entity/effect/Effect.php @@ -26,212 +26,9 @@ namespace pocketmine\entity\effect; use pocketmine\entity\Entity; use pocketmine\entity\Living; use pocketmine\utils\Color; -use function constant; -use function defined; -use function strtoupper; class Effect{ - //TODO: remove our dependence on these magic numbers - public const SPEED = 1; - public const SLOWNESS = 2; - public const HASTE = 3; - public const FATIGUE = 4, MINING_FATIGUE = 4; - public const STRENGTH = 5; - public const INSTANT_HEALTH = 6, HEALING = 6; - public const INSTANT_DAMAGE = 7, HARMING = 7; - public const JUMP_BOOST = 8, JUMP = 8; - public const NAUSEA = 9, CONFUSION = 9; - public const REGENERATION = 10; - public const RESISTANCE = 11, DAMAGE_RESISTANCE = 11; - public const FIRE_RESISTANCE = 12; - public const WATER_BREATHING = 13; - public const INVISIBILITY = 14; - public const BLINDNESS = 15; - public const NIGHT_VISION = 16; - public const HUNGER = 17; - public const WEAKNESS = 18; - public const POISON = 19; - public const WITHER = 20; - public const HEALTH_BOOST = 21; - public const ABSORPTION = 22; - public const SATURATION = 23; - public const LEVITATION = 24; //TODO - public const FATAL_POISON = 25; - public const CONDUIT_POWER = 26; - public const SLOW_FALLING = 27; - public const BAD_OMEN = 28; - public const VILLAGE_HERO = 29; - - /** @var Effect[] */ - protected static $effects = []; - - public static function init() : void{ - self::register(new SpeedEffect(Effect::SPEED, "%potion.moveSpeed", new Color(0x7c, 0xaf, 0xc6))); - self::register(new SlownessEffect(Effect::SLOWNESS, "%potion.moveSlowdown", new Color(0x5a, 0x6c, 0x81), true)); - self::register(new Effect(Effect::HASTE, "%potion.digSpeed", new Color(0xd9, 0xc0, 0x43))); - self::register(new Effect(Effect::MINING_FATIGUE, "%potion.digSlowDown", new Color(0x4a, 0x42, 0x17), true)); - self::register(new Effect(Effect::STRENGTH, "%potion.damageBoost", new Color(0x93, 0x24, 0x23))); - self::register(new InstantHealthEffect(Effect::INSTANT_HEALTH, "%potion.heal", new Color(0xf8, 0x24, 0x23), false, false)); - self::register(new InstantDamageEffect(Effect::INSTANT_DAMAGE, "%potion.harm", new Color(0x43, 0x0a, 0x09), true, false)); - self::register(new Effect(Effect::JUMP_BOOST, "%potion.jump", new Color(0x22, 0xff, 0x4c))); - self::register(new Effect(Effect::NAUSEA, "%potion.confusion", new Color(0x55, 0x1d, 0x4a), true)); - self::register(new RegenerationEffect(Effect::REGENERATION, "%potion.regeneration", new Color(0xcd, 0x5c, 0xab))); - self::register(new Effect(Effect::RESISTANCE, "%potion.resistance", new Color(0x99, 0x45, 0x3a))); - self::register(new Effect(Effect::FIRE_RESISTANCE, "%potion.fireResistance", new Color(0xe4, 0x9a, 0x3a))); - self::register(new Effect(Effect::WATER_BREATHING, "%potion.waterBreathing", new Color(0x2e, 0x52, 0x99))); - self::register(new InvisibilityEffect(Effect::INVISIBILITY, "%potion.invisibility", new Color(0x7f, 0x83, 0x92))); - self::register(new Effect(Effect::BLINDNESS, "%potion.blindness", new Color(0x1f, 0x1f, 0x23), true)); - self::register(new Effect(Effect::NIGHT_VISION, "%potion.nightVision", new Color(0x1f, 0x1f, 0xa1))); - self::register(new HungerEffect(Effect::HUNGER, "%potion.hunger", new Color(0x58, 0x76, 0x53), true)); - self::register(new Effect(Effect::WEAKNESS, "%potion.weakness", new Color(0x48, 0x4d, 0x48), true)); - self::register(new PoisonEffect(Effect::POISON, "%potion.poison", new Color(0x4e, 0x93, 0x31), true)); - self::register(new WitherEffect(Effect::WITHER, "%potion.wither", new Color(0x35, 0x2a, 0x27), true)); - self::register(new HealthBoostEffect(Effect::HEALTH_BOOST, "%potion.healthBoost", new Color(0xf8, 0x7d, 0x23))); - self::register(new AbsorptionEffect(Effect::ABSORPTION, "%potion.absorption", new Color(0x25, 0x52, 0xa5))); - self::register(new SaturationEffect(Effect::SATURATION, "%potion.saturation", new Color(0xf8, 0x24, 0x23), false)); - self::register(new LevitationEffect(Effect::LEVITATION, "%potion.levitation", new Color(0xce, 0xff, 0xff))); - self::register(new PoisonEffect(Effect::FATAL_POISON, "%potion.poison", new Color(0x4e, 0x93, 0x31), true, true, true)); - self::register(new Effect(Effect::CONDUIT_POWER, "%potion.conduitPower", new Color(0x1d, 0xc2, 0xd1))); - } - - //region --- auto-generated code --- - - public static function ABSORPTION() : Effect{ - return self::get(Effect::ABSORPTION); - } - - public static function BLINDNESS() : Effect{ - return self::get(Effect::BLINDNESS); - } - - public static function CONDUIT_POWER() : Effect{ - return self::get(Effect::CONDUIT_POWER); - } - - public static function FATAL_POISON() : Effect{ - return self::get(Effect::FATAL_POISON); - } - - public static function FIRE_RESISTANCE() : Effect{ - return self::get(Effect::FIRE_RESISTANCE); - } - - public static function HASTE() : Effect{ - return self::get(Effect::HASTE); - } - - public static function HEALTH_BOOST() : Effect{ - return self::get(Effect::HEALTH_BOOST); - } - - public static function HUNGER() : Effect{ - return self::get(Effect::HUNGER); - } - - public static function INSTANT_DAMAGE() : Effect{ - return self::get(Effect::INSTANT_DAMAGE); - } - - public static function INSTANT_HEALTH() : Effect{ - return self::get(Effect::INSTANT_HEALTH); - } - - public static function INVISIBILITY() : Effect{ - return self::get(Effect::INVISIBILITY); - } - - public static function JUMP_BOOST() : Effect{ - return self::get(Effect::JUMP_BOOST); - } - - public static function LEVITATION() : Effect{ - return self::get(Effect::LEVITATION); - } - - public static function MINING_FATIGUE() : Effect{ - return self::get(Effect::MINING_FATIGUE); - } - - public static function NAUSEA() : Effect{ - return self::get(Effect::NAUSEA); - } - - public static function NIGHT_VISION() : Effect{ - return self::get(Effect::NIGHT_VISION); - } - - public static function POISON() : Effect{ - return self::get(Effect::POISON); - } - - public static function REGENERATION() : Effect{ - return self::get(Effect::REGENERATION); - } - - public static function RESISTANCE() : Effect{ - return self::get(Effect::RESISTANCE); - } - - public static function SATURATION() : Effect{ - return self::get(Effect::SATURATION); - } - - public static function SLOWNESS() : Effect{ - return self::get(Effect::SLOWNESS); - } - - public static function SPEED() : Effect{ - return self::get(Effect::SPEED); - } - - public static function STRENGTH() : Effect{ - return self::get(Effect::STRENGTH); - } - - public static function WATER_BREATHING() : Effect{ - return self::get(Effect::WATER_BREATHING); - } - - public static function WEAKNESS() : Effect{ - return self::get(Effect::WEAKNESS); - } - - public static function WITHER() : Effect{ - return self::get(Effect::WITHER); - } - - //endregion - - /** - * @param Effect $effect - */ - public static function register(Effect $effect) : void{ - self::$effects[$effect->getId()] = $effect; - } - - /** - * @param int $id - * - * @return Effect|null - */ - public static function get(int $id) : ?Effect{ - return self::$effects[$id] ?? null; - } - - /** - * @param string $name - * - * @return Effect|null - */ - public static function fromString(string $name) : ?Effect{ - $const = self::class . "::" . strtoupper($name); - if(defined($const)){ - return self::get(constant($const)); - } - return null; - } - /** @var int */ protected $id; /** @var string */ diff --git a/src/pocketmine/entity/effect/VanillaEffects.php b/src/pocketmine/entity/effect/VanillaEffects.php new file mode 100644 index 0000000000..9b81e2b22a --- /dev/null +++ b/src/pocketmine/entity/effect/VanillaEffects.php @@ -0,0 +1,134 @@ +getId()])); + self::$mcpeIdMap[$member->getId()] = $member; + } + + /** + * @param int $id + * + * @return Effect + */ + public static function byMcpeId(int $id) : Effect{ + self::checkInit(); + if(!isset(self::$mcpeIdMap[$id])){ + throw new \InvalidArgumentException("No such effect with MCPE ID $id"); + } + return self::$mcpeIdMap[$id]; + } + + /** + * @return Effect[] + */ + public static function getAll() : array{ + return self::_registryGetAll(); + } + + /** + * @param string $name + * + * @return Effect + */ + public static function fromString(string $name) : Effect{ + $result = self::_registryFromString($name); + assert($result instanceof Effect); + return $result; + } +} diff --git a/src/pocketmine/event/entity/EntityDamageByEntityEvent.php b/src/pocketmine/event/entity/EntityDamageByEntityEvent.php index 2793f4673a..755e4e0884 100644 --- a/src/pocketmine/event/entity/EntityDamageByEntityEvent.php +++ b/src/pocketmine/event/entity/EntityDamageByEntityEvent.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\event\entity; -use pocketmine\entity\effect\Effect; +use pocketmine\entity\effect\VanillaEffects; use pocketmine\entity\Entity; use pocketmine\entity\Living; @@ -54,12 +54,12 @@ class EntityDamageByEntityEvent extends EntityDamageEvent{ protected function addAttackerModifiers(Entity $damager) : void{ if($damager instanceof Living){ //TODO: move this to entity classes $effects = $damager->getEffects(); - if($effects->has(Effect::STRENGTH())){ - $this->setModifier($this->getBaseDamage() * 0.3 * $effects->get(Effect::STRENGTH())->getEffectLevel(), self::MODIFIER_STRENGTH); + if($effects->has(VanillaEffects::STRENGTH())){ + $this->setModifier($this->getBaseDamage() * 0.3 * $effects->get(VanillaEffects::STRENGTH())->getEffectLevel(), self::MODIFIER_STRENGTH); } - if($effects->has(Effect::WEAKNESS())){ - $this->setModifier(-($this->getBaseDamage() * 0.2 * $effects->get(Effect::WEAKNESS())->getEffectLevel()), self::MODIFIER_WEAKNESS); + if($effects->has(VanillaEffects::WEAKNESS())){ + $this->setModifier(-($this->getBaseDamage() * 0.2 * $effects->get(VanillaEffects::WEAKNESS())->getEffectLevel()), self::MODIFIER_WEAKNESS); } } } diff --git a/src/pocketmine/item/GoldenApple.php b/src/pocketmine/item/GoldenApple.php index ba02205286..76487fdd67 100644 --- a/src/pocketmine/item/GoldenApple.php +++ b/src/pocketmine/item/GoldenApple.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; +use pocketmine\entity\effect\VanillaEffects; class GoldenApple extends Food{ @@ -42,8 +42,8 @@ class GoldenApple extends Food{ public function getAdditionalEffects() : array{ return [ - new EffectInstance(Effect::REGENERATION(), 100, 1), - new EffectInstance(Effect::ABSORPTION(), 2400) + new EffectInstance(VanillaEffects::REGENERATION(), 100, 1), + new EffectInstance(VanillaEffects::ABSORPTION(), 2400) ]; } } diff --git a/src/pocketmine/item/GoldenAppleEnchanted.php b/src/pocketmine/item/GoldenAppleEnchanted.php index 1064373c27..c807ac897d 100644 --- a/src/pocketmine/item/GoldenAppleEnchanted.php +++ b/src/pocketmine/item/GoldenAppleEnchanted.php @@ -23,17 +23,17 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; +use pocketmine\entity\effect\VanillaEffects; class GoldenAppleEnchanted extends GoldenApple{ public function getAdditionalEffects() : array{ return [ - new EffectInstance(Effect::REGENERATION(), 600, 4), - new EffectInstance(Effect::ABSORPTION(), 2400, 3), - new EffectInstance(Effect::RESISTANCE(), 6000), - new EffectInstance(Effect::FIRE_RESISTANCE(), 6000) + new EffectInstance(VanillaEffects::REGENERATION(), 600, 4), + new EffectInstance(VanillaEffects::ABSORPTION(), 2400, 3), + new EffectInstance(VanillaEffects::RESISTANCE(), 6000), + new EffectInstance(VanillaEffects::FIRE_RESISTANCE(), 6000) ]; } } diff --git a/src/pocketmine/item/PoisonousPotato.php b/src/pocketmine/item/PoisonousPotato.php index 962e87a2c2..fb997d48ef 100644 --- a/src/pocketmine/item/PoisonousPotato.php +++ b/src/pocketmine/item/PoisonousPotato.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; +use pocketmine\entity\effect\VanillaEffects; use function mt_rand; class PoisonousPotato extends Food{ @@ -40,7 +40,7 @@ class PoisonousPotato extends Food{ public function getAdditionalEffects() : array{ if(mt_rand(0, 100) > 40){ return [ - new EffectInstance(Effect::POISON(), 100) + new EffectInstance(VanillaEffects::POISON(), 100) ]; } return []; diff --git a/src/pocketmine/item/Potion.php b/src/pocketmine/item/Potion.php index c45ac84ea3..619882a569 100644 --- a/src/pocketmine/item/Potion.php +++ b/src/pocketmine/item/Potion.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; +use pocketmine\entity\effect\VanillaEffects; use pocketmine\entity\Living; class Potion extends Item implements Consumable{ @@ -124,131 +124,131 @@ class Potion extends Item implements Consumable{ return []; case self::NIGHT_VISION: return [ - new EffectInstance(Effect::NIGHT_VISION(), 3600) + new EffectInstance(VanillaEffects::NIGHT_VISION(), 3600) ]; case self::LONG_NIGHT_VISION: return [ - new EffectInstance(Effect::NIGHT_VISION(), 9600) + new EffectInstance(VanillaEffects::NIGHT_VISION(), 9600) ]; case self::INVISIBILITY: return [ - new EffectInstance(Effect::INVISIBILITY(), 3600) + new EffectInstance(VanillaEffects::INVISIBILITY(), 3600) ]; case self::LONG_INVISIBILITY: return [ - new EffectInstance(Effect::INVISIBILITY(), 9600) + new EffectInstance(VanillaEffects::INVISIBILITY(), 9600) ]; case self::LEAPING: return [ - new EffectInstance(Effect::JUMP_BOOST(), 3600) + new EffectInstance(VanillaEffects::JUMP_BOOST(), 3600) ]; case self::LONG_LEAPING: return [ - new EffectInstance(Effect::JUMP_BOOST(), 9600) + new EffectInstance(VanillaEffects::JUMP_BOOST(), 9600) ]; case self::STRONG_LEAPING: return [ - new EffectInstance(Effect::JUMP_BOOST(), 1800, 1) + new EffectInstance(VanillaEffects::JUMP_BOOST(), 1800, 1) ]; case self::FIRE_RESISTANCE: return [ - new EffectInstance(Effect::FIRE_RESISTANCE(), 3600) + new EffectInstance(VanillaEffects::FIRE_RESISTANCE(), 3600) ]; case self::LONG_FIRE_RESISTANCE: return [ - new EffectInstance(Effect::FIRE_RESISTANCE(), 9600) + new EffectInstance(VanillaEffects::FIRE_RESISTANCE(), 9600) ]; case self::SWIFTNESS: return [ - new EffectInstance(Effect::SPEED(), 3600) + new EffectInstance(VanillaEffects::SPEED(), 3600) ]; case self::LONG_SWIFTNESS: return [ - new EffectInstance(Effect::SPEED(), 9600) + new EffectInstance(VanillaEffects::SPEED(), 9600) ]; case self::STRONG_SWIFTNESS: return [ - new EffectInstance(Effect::SPEED(), 1800, 1) + new EffectInstance(VanillaEffects::SPEED(), 1800, 1) ]; case self::SLOWNESS: return [ - new EffectInstance(Effect::SLOWNESS(), 1800) + new EffectInstance(VanillaEffects::SLOWNESS(), 1800) ]; case self::LONG_SLOWNESS: return [ - new EffectInstance(Effect::SLOWNESS(), 4800) + new EffectInstance(VanillaEffects::SLOWNESS(), 4800) ]; case self::WATER_BREATHING: return [ - new EffectInstance(Effect::WATER_BREATHING(), 3600) + new EffectInstance(VanillaEffects::WATER_BREATHING(), 3600) ]; case self::LONG_WATER_BREATHING: return [ - new EffectInstance(Effect::WATER_BREATHING(), 9600) + new EffectInstance(VanillaEffects::WATER_BREATHING(), 9600) ]; case self::HEALING: return [ - new EffectInstance(Effect::INSTANT_HEALTH()) + new EffectInstance(VanillaEffects::INSTANT_HEALTH()) ]; case self::STRONG_HEALING: return [ - new EffectInstance(Effect::INSTANT_HEALTH(), null, 1) + new EffectInstance(VanillaEffects::INSTANT_HEALTH(), null, 1) ]; case self::HARMING: return [ - new EffectInstance(Effect::INSTANT_DAMAGE()) + new EffectInstance(VanillaEffects::INSTANT_DAMAGE()) ]; case self::STRONG_HARMING: return [ - new EffectInstance(Effect::INSTANT_DAMAGE(), null, 1) + new EffectInstance(VanillaEffects::INSTANT_DAMAGE(), null, 1) ]; case self::POISON: return [ - new EffectInstance(Effect::POISON(), 900) + new EffectInstance(VanillaEffects::POISON(), 900) ]; case self::LONG_POISON: return [ - new EffectInstance(Effect::POISON(), 2400) + new EffectInstance(VanillaEffects::POISON(), 2400) ]; case self::STRONG_POISON: return [ - new EffectInstance(Effect::POISON(), 440, 1) + new EffectInstance(VanillaEffects::POISON(), 440, 1) ]; case self::REGENERATION: return [ - new EffectInstance(Effect::REGENERATION(), 900) + new EffectInstance(VanillaEffects::REGENERATION(), 900) ]; case self::LONG_REGENERATION: return [ - new EffectInstance(Effect::REGENERATION(), 2400) + new EffectInstance(VanillaEffects::REGENERATION(), 2400) ]; case self::STRONG_REGENERATION: return [ - new EffectInstance(Effect::REGENERATION(), 440, 1) + new EffectInstance(VanillaEffects::REGENERATION(), 440, 1) ]; case self::STRENGTH: return [ - new EffectInstance(Effect::STRENGTH(), 3600) + new EffectInstance(VanillaEffects::STRENGTH(), 3600) ]; case self::LONG_STRENGTH: return [ - new EffectInstance(Effect::STRENGTH(), 9600) + new EffectInstance(VanillaEffects::STRENGTH(), 9600) ]; case self::STRONG_STRENGTH: return [ - new EffectInstance(Effect::STRENGTH(), 1800, 1) + new EffectInstance(VanillaEffects::STRENGTH(), 1800, 1) ]; case self::WEAKNESS: return [ - new EffectInstance(Effect::WEAKNESS(), 1800) + new EffectInstance(VanillaEffects::WEAKNESS(), 1800) ]; case self::LONG_WEAKNESS: return [ - new EffectInstance(Effect::WEAKNESS(), 4800) + new EffectInstance(VanillaEffects::WEAKNESS(), 4800) ]; case self::WITHER: return [ - new EffectInstance(Effect::WITHER(), 800, 1) + new EffectInstance(VanillaEffects::WITHER(), 800, 1) ]; } diff --git a/src/pocketmine/item/Pufferfish.php b/src/pocketmine/item/Pufferfish.php index 6e9826fb41..d657ae8ad7 100644 --- a/src/pocketmine/item/Pufferfish.php +++ b/src/pocketmine/item/Pufferfish.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; +use pocketmine\entity\effect\VanillaEffects; class Pufferfish extends Food{ @@ -38,9 +38,9 @@ class Pufferfish extends Food{ public function getAdditionalEffects() : array{ return [ - new EffectInstance(Effect::HUNGER(), 300, 2), - new EffectInstance(Effect::POISON(), 1200, 3), - new EffectInstance(Effect::NAUSEA(), 300, 1) + new EffectInstance(VanillaEffects::HUNGER(), 300, 2), + new EffectInstance(VanillaEffects::POISON(), 1200, 3), + new EffectInstance(VanillaEffects::NAUSEA(), 300, 1) ]; } } diff --git a/src/pocketmine/item/RawChicken.php b/src/pocketmine/item/RawChicken.php index 0408a65524..16a795203f 100644 --- a/src/pocketmine/item/RawChicken.php +++ b/src/pocketmine/item/RawChicken.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; +use pocketmine\entity\effect\VanillaEffects; use function mt_rand; class RawChicken extends Food{ @@ -38,6 +38,6 @@ class RawChicken extends Food{ } public function getAdditionalEffects() : array{ - return mt_rand(0, 9) < 3 ? [new EffectInstance(Effect::HUNGER(), 600)] : []; + return mt_rand(0, 9) < 3 ? [new EffectInstance(VanillaEffects::HUNGER(), 600)] : []; } } diff --git a/src/pocketmine/item/RottenFlesh.php b/src/pocketmine/item/RottenFlesh.php index 90f4c9050e..401149a4a8 100644 --- a/src/pocketmine/item/RottenFlesh.php +++ b/src/pocketmine/item/RottenFlesh.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; +use pocketmine\entity\effect\VanillaEffects; use function lcg_value; class RottenFlesh extends Food{ @@ -40,7 +40,7 @@ class RottenFlesh extends Food{ public function getAdditionalEffects() : array{ if(lcg_value() <= 0.8){ return [ - new EffectInstance(Effect::HUNGER(), 600) + new EffectInstance(VanillaEffects::HUNGER(), 600) ]; } diff --git a/src/pocketmine/item/SpiderEye.php b/src/pocketmine/item/SpiderEye.php index b443a4fad6..22e5ecab1c 100644 --- a/src/pocketmine/item/SpiderEye.php +++ b/src/pocketmine/item/SpiderEye.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; +use pocketmine\entity\effect\VanillaEffects; class SpiderEye extends Food{ @@ -37,6 +37,6 @@ class SpiderEye extends Food{ } public function getAdditionalEffects() : array{ - return [new EffectInstance(Effect::POISON(), 80)]; + return [new EffectInstance(VanillaEffects::POISON(), 80)]; } } diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index a01aa65499..a883016e4b 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -29,8 +29,8 @@ use pocketmine\block\UnknownBlock; use pocketmine\block\VanillaBlocks; use pocketmine\command\CommandSender; use pocketmine\crafting\CraftingGrid; -use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; +use pocketmine\entity\effect\VanillaEffects; use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; use pocketmine\entity\Human; @@ -1884,7 +1884,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $ev->setModifier($meleeEnchantmentDamage, EntityDamageEvent::MODIFIER_WEAPON_ENCHANTMENTS); - if(!$this->isSprinting() and !$this->isFlying() and $this->fallDistance > 0 and !$this->effectManager->has(Effect::BLINDNESS()) and !$this->isUnderwater()){ + if(!$this->isSprinting() and !$this->isFlying() and $this->fallDistance > 0 and !$this->effectManager->has(VanillaEffects::BLINDNESS()) and !$this->isUnderwater()){ $ev->setModifier($ev->getFinalDamage() / 2, EntityDamageEvent::MODIFIER_CRITICAL); } From 3632e07cdb443ff4afe68f120856bd2f1f2cf1db Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Jul 2019 19:29:43 +0100 Subject: [PATCH 1106/3224] EffectCommand: Remove internal ID from translated message --- resources/locale | 2 +- src/pocketmine/command/defaults/EffectCommand.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/locale b/resources/locale index 64844b7b6b..8718542e62 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 64844b7b6b94a866367831f998281801a86f07a1 +Subproject commit 8718542e622014fa81e6c178a3c83202c86ef921 diff --git a/src/pocketmine/command/defaults/EffectCommand.php b/src/pocketmine/command/defaults/EffectCommand.php index 6f95a1b130..66c250b130 100644 --- a/src/pocketmine/command/defaults/EffectCommand.php +++ b/src/pocketmine/command/defaults/EffectCommand.php @@ -120,7 +120,7 @@ class EffectCommand extends VanillaCommand{ }else{ $instance = new EffectInstance($effect, $duration, $amplification, $visible); $effectManager->add($instance); - self::broadcastCommandMessage($sender, new TranslationContainer("%commands.effect.success", [$effect->getName(), $instance->getAmplifier(), $player->getDisplayName(), $instance->getDuration() / 20, $effect->getId()])); + self::broadcastCommandMessage($sender, new TranslationContainer("%commands.effect.success", [$effect->getName(), $instance->getAmplifier(), $player->getDisplayName(), $instance->getDuration() / 20])); } From e22986f065f113eae2d90a6d26a5893e375ce734 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Jul 2019 19:30:20 +0100 Subject: [PATCH 1107/3224] EffectCommand: Remove support for internal MCPE effect IDs --- src/pocketmine/command/defaults/EffectCommand.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/pocketmine/command/defaults/EffectCommand.php b/src/pocketmine/command/defaults/EffectCommand.php index 66c250b130..ef8a0c1b16 100644 --- a/src/pocketmine/command/defaults/EffectCommand.php +++ b/src/pocketmine/command/defaults/EffectCommand.php @@ -69,11 +69,6 @@ class EffectCommand extends VanillaCommand{ } $effect = VanillaEffects::fromString($args[1]); - - if($effect === null){ - $effect = VanillaEffects::byMcpeId((int) $args[1]); - } - if($effect === null){ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.effect.notFound", [(string) $args[1]])); return true; From b5b4133c5d0763284fcd9a0e432b2eb26c4f7114 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Jul 2019 19:45:59 +0100 Subject: [PATCH 1108/3224] Item: fixed always-false null checks on getNamedTag() result --- src/pocketmine/item/Item.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 833e6e1546..402f0dce73 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -644,7 +644,7 @@ class Item implements ItemIds, \JsonSerializable{ * @return string */ final public function __toString() : string{ - return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->getMeta()) . ")x" . $this->count . (($tag = $this->getNamedTag()) !== null ? " tags:0x" . base64_encode((new LittleEndianNbtSerializer())->write(new TreeRoot($tag))) : ""); + return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->getMeta()) . ")x" . $this->count . ($this->hasNamedTag() ? " tags:0x" . base64_encode((new LittleEndianNbtSerializer())->write(new TreeRoot($this->getNamedTag()))) : ""); } /** @@ -665,8 +665,8 @@ class Item implements ItemIds, \JsonSerializable{ $data["count"] = $this->getCount(); } - if(($tag = $this->getNamedTag()) !== null){ - $data["nbt_b64"] = base64_encode((new LittleEndianNbtSerializer())->write(new TreeRoot($tag))); + if($this->hasNamedTag()){ + $data["nbt_b64"] = base64_encode((new LittleEndianNbtSerializer())->write(new TreeRoot($this->getNamedTag()))); } return $data; @@ -710,8 +710,8 @@ class Item implements ItemIds, \JsonSerializable{ ->setByte("Count", Binary::signByte($this->count)) ->setShort("Damage", $this->getMeta()); - if(($itemNBT = $this->getNamedTag()) !== null){ - $result->setTag("tag", $itemNBT); + if($this->hasNamedTag()){ + $result->setTag("tag", $this->getNamedTag()); } if($slot !== -1){ From a8fa3ba43445bb404d2ecd06db9748d1e1377291 Mon Sep 17 00:00:00 2001 From: Muqsit Date: Fri, 19 Jul 2019 16:06:07 +0400 Subject: [PATCH 1109/3224] Add test for whether item retains it's display properties after deserialization (#3047) --- tests/phpunit/item/ItemTest.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/phpunit/item/ItemTest.php b/tests/phpunit/item/ItemTest.php index 9b164e88fc..8adc8c9a32 100644 --- a/tests/phpunit/item/ItemTest.php +++ b/tests/phpunit/item/ItemTest.php @@ -62,6 +62,21 @@ class ItemTest extends TestCase{ self::assertTrue($item1->equals($item2)); } + /** + * Tests whether items retain their display properties + * after being deserialized + */ + public function testItemPersistsDisplayProperties() : void{ + $lore = ["Line A", "Line B"]; + $name = "HI"; + $item = ItemFactory::get(Item::DIAMOND_SWORD); + $item->setCustomName($name); + $item->setLore($lore); + $item = Item::nbtDeserialize($item->nbtSerialize()); + self::assertTrue($item->getCustomName() === $name); + self::assertTrue($item->getLore() === $lore); + } + public function testHasEnchantment() : void{ $this->item->addEnchantment(new EnchantmentInstance(Enchantment::EFFICIENCY(), 5)); self::assertTrue($this->item->hasEnchantment(Enchantment::EFFICIENCY())); From 5e8c92b1dabf5349bce1c48bea880850972e142f Mon Sep 17 00:00:00 2001 From: Muqsit Date: Fri, 19 Jul 2019 12:26:00 +0000 Subject: [PATCH 1110/3224] Fix test failure #3047 --- src/pocketmine/item/Item.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 402f0dce73..2dfaec9858 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -283,7 +283,7 @@ class Item implements ItemIds, \JsonSerializable{ $display = $tag->getCompoundTag(self::TAG_DISPLAY); if($display !== null){ $this->customName = $display->getString(self::TAG_DISPLAY_NAME, $this->customName, true); - $lore = $tag->getListTag(self::TAG_DISPLAY_LORE); + $lore = $display->getListTag(self::TAG_DISPLAY_LORE); if($lore !== null and $lore->getTagType() === NBT::TAG_String){ /** @var StringTag $t */ foreach($lore as $t){ From a4c7744188e38a8476838a660e5636dc6d2f97d8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jul 2019 13:53:44 +0100 Subject: [PATCH 1111/3224] [ci skip] changelog updates --- changelogs/4.0-snapshot.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 632cf44204..203bb054bb 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -6,6 +6,7 @@ This major version features substantial changes throughout the core, including s ### General - A new "plugin greylist" feature has been introduced, which allows whitelisting or blacklisting plugins from loading. - The `/reload` command has been removed. +- The `/effect` command no longer supports numeric IDs - it's now required to use names. - Remote console (RCON) has been removed. The [RconServer](https://github.com/pmmp/RconServer) plugin is provided as a substitute. - Spawn protection has been removed. The [BasicSpawnProtection](https://github.com/pmmp/BasicSpawnProtection) plugin is provided as a substitute. - CTRL+C signal handling has been removed. The [PcntlSignalHandler](https://github.com/pmmp/PcntlSignalHandler) plugin is provided as a substitute. @@ -230,7 +231,8 @@ This version features substantial changes to the network system, improving coher - `Effect::registerEffect()` -> `Effect::register()` - `Effect::getEffect()` -> `Effect::get()` - `Effect::getEffectByName()` -> `Effect::fromString()` -- Static getter methods for all registered enchantment types have been added. `Effect::getEffect(Effect::WHATEVER)` should be replaced by `Effect::WHATEVER()`. +- Static getter methods for all registered enchantment types have been added. `Effect::getEffect(Effect::WHATEVER)` should be replaced by `VanillaEffects::WHATEVER()`. +- All effect registry functionality has been removed from the `Effect` base class and migrated to the `VanillaEffects` class. #### Removal of runtime entity NBT - Entities no longer keep their NBT alive at runtime. From 5a5ce84ebc07c106daeb74bd668fc7d996343c5a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jul 2019 14:01:21 +0100 Subject: [PATCH 1112/3224] yucky fix for crash on invalid keychain --- src/pocketmine/network/mcpe/NetworkSession.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 16a87b1f3f..048d2e7789 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -527,14 +527,18 @@ class NetworkSession{ }, $reason); } - public function setAuthenticationStatus(bool $authenticated, bool $authRequired, ?string $error, PublicKeyInterface $clientPubKey) : void{ + public function setAuthenticationStatus(bool $authenticated, bool $authRequired, ?string $error, ?PublicKeyInterface $clientPubKey) : void{ if(!$this->connected){ return; } - if($authenticated and $this->info->getXuid() === ""){ - $error = "Expected XUID but none found"; - }elseif(!$authenticated and $this->info->getXuid() !== ""){ - $error = "Unexpected XUID for non-XBOX-authenticated player"; + if($error === null){ + if($authenticated and $this->info->getXuid() === ""){ + $error = "Expected XUID but none found"; + }elseif(!$authenticated and $this->info->getXuid() !== ""){ + $error = "Unexpected XUID for non-XBOX-authenticated player"; + }elseif($clientPubKey === null){ + $error = "Missing client public key"; //failsafe + } } if($error !== null){ From 0ebd3e6ca296427079c5ae34c77e7e9e6c12cba0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jul 2019 14:10:19 +0100 Subject: [PATCH 1113/3224] fix /effect crash --- src/pocketmine/command/defaults/EffectCommand.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/command/defaults/EffectCommand.php b/src/pocketmine/command/defaults/EffectCommand.php index ef8a0c1b16..d78b5cc04b 100644 --- a/src/pocketmine/command/defaults/EffectCommand.php +++ b/src/pocketmine/command/defaults/EffectCommand.php @@ -68,8 +68,9 @@ class EffectCommand extends VanillaCommand{ return true; } - $effect = VanillaEffects::fromString($args[1]); - if($effect === null){ + try{ + $effect = VanillaEffects::fromString($args[1]); + }catch(\InvalidArgumentException $e){ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.effect.notFound", [(string) $args[1]])); return true; } From ac12911561e2de2eb73fe3ceec8a2abc88a865ef Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jul 2019 15:33:30 +0100 Subject: [PATCH 1114/3224] move network entity IDs to network namespace we're going to need a dedicated data package, because this stuff isn't just network-specific. --- src/pocketmine/entity/Entity.php | 14 +- src/pocketmine/entity/EntityFactory.php | 29 +-- src/pocketmine/entity/Squid.php | 3 +- src/pocketmine/entity/Villager.php | 3 +- src/pocketmine/entity/Zombie.php | 3 +- .../entity/object/ExperienceOrb.php | 3 +- src/pocketmine/entity/object/FallingBlock.php | 3 +- src/pocketmine/entity/object/ItemEntity.php | 5 +- src/pocketmine/entity/object/Painting.php | 3 +- src/pocketmine/entity/object/PrimedTNT.php | 3 +- src/pocketmine/entity/projectile/Arrow.php | 3 +- src/pocketmine/entity/projectile/Egg.php | 3 +- .../entity/projectile/EnderPearl.php | 3 +- .../entity/projectile/ExperienceBottle.php | 3 +- src/pocketmine/entity/projectile/Snowball.php | 3 +- .../entity/projectile/SplashPotion.php | 3 +- .../network/mcpe/protocol/AddActorPacket.php | 198 +++++++++--------- .../mcpe/protocol/types/EntityLegacyIds.php} | 9 +- 18 files changed, 157 insertions(+), 137 deletions(-) rename src/pocketmine/{entity/EntityIds.php => network/mcpe/protocol/types/EntityLegacyIds.php} (96%) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index d1cb95802c..0155feedd0 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -44,18 +44,18 @@ use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; +use pocketmine\network\mcpe\protocol\ActorEventPacket; +use pocketmine\network\mcpe\protocol\AddActorPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; +use pocketmine\network\mcpe\protocol\MoveActorAbsolutePacket; +use pocketmine\network\mcpe\protocol\RemoveActorPacket; +use pocketmine\network\mcpe\protocol\SetActorDataPacket; +use pocketmine\network\mcpe\protocol\SetActorMotionPacket; use pocketmine\network\mcpe\protocol\types\DataPropertyManager; use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\EntityMetadataTypes; use pocketmine\player\Player; -use pocketmine\network\mcpe\protocol\AddActorPacket; -use pocketmine\network\mcpe\protocol\ActorEventPacket; -use pocketmine\network\mcpe\protocol\MoveActorAbsolutePacket; -use pocketmine\network\mcpe\protocol\RemoveActorPacket; -use pocketmine\network\mcpe\protocol\SetActorDataPacket; -use pocketmine\network\mcpe\protocol\SetActorMotionPacket; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; @@ -78,7 +78,7 @@ use function sin; use function spl_object_id; use const M_PI_2; -abstract class Entity extends Location implements EntityIds{ +abstract class Entity extends Location{ public const MOTION_THRESHOLD = 0.00001; diff --git a/src/pocketmine/entity/EntityFactory.php b/src/pocketmine/entity/EntityFactory.php index d3a71f367a..4441ed2741 100644 --- a/src/pocketmine/entity/EntityFactory.php +++ b/src/pocketmine/entity/EntityFactory.php @@ -42,6 +42,7 @@ use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; +use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; use pocketmine\utils\Utils; use pocketmine\world\World; use function array_keys; @@ -79,20 +80,20 @@ final class EntityFactory{ //define legacy save IDs first - use them for saving for maximum compatibility with Minecraft PC //TODO: index them by version to allow proper multi-save compatibility - self::register(Arrow::class, ['Arrow', 'minecraft:arrow'], EntityIds::ARROW); - self::register(Egg::class, ['Egg', 'minecraft:egg'], EntityIds::EGG); - self::register(EnderPearl::class, ['ThrownEnderpearl', 'minecraft:ender_pearl'], EntityIds::ENDER_PEARL); - self::register(ExperienceBottle::class, ['ThrownExpBottle', 'minecraft:xp_bottle'], EntityIds::XP_BOTTLE); - self::register(ExperienceOrb::class, ['XPOrb', 'minecraft:xp_orb'], EntityIds::XP_ORB); - self::register(FallingBlock::class, ['FallingSand', 'minecraft:falling_block'], EntityIds::FALLING_BLOCK); - self::register(ItemEntity::class, ['Item', 'minecraft:item'], EntityIds::ITEM); - self::register(Painting::class, ['Painting', 'minecraft:painting'], EntityIds::PAINTING); - self::register(PrimedTNT::class, ['PrimedTnt', 'PrimedTNT', 'minecraft:tnt'], EntityIds::TNT); - self::register(Snowball::class, ['Snowball', 'minecraft:snowball'], EntityIds::SNOWBALL); - self::register(SplashPotion::class, ['ThrownPotion', 'minecraft:potion', 'thrownpotion'], EntityIds::SPLASH_POTION); - self::register(Squid::class, ['Squid', 'minecraft:squid'], EntityIds::SQUID); - self::register(Villager::class, ['Villager', 'minecraft:villager'], EntityIds::VILLAGER); - self::register(Zombie::class, ['Zombie', 'minecraft:zombie'], EntityIds::ZOMBIE); + self::register(Arrow::class, ['Arrow', 'minecraft:arrow'], EntityLegacyIds::ARROW); + self::register(Egg::class, ['Egg', 'minecraft:egg'], EntityLegacyIds::EGG); + self::register(EnderPearl::class, ['ThrownEnderpearl', 'minecraft:ender_pearl'], EntityLegacyIds::ENDER_PEARL); + self::register(ExperienceBottle::class, ['ThrownExpBottle', 'minecraft:xp_bottle'], EntityLegacyIds::XP_BOTTLE); + self::register(ExperienceOrb::class, ['XPOrb', 'minecraft:xp_orb'], EntityLegacyIds::XP_ORB); + self::register(FallingBlock::class, ['FallingSand', 'minecraft:falling_block'], EntityLegacyIds::FALLING_BLOCK); + self::register(ItemEntity::class, ['Item', 'minecraft:item'], EntityLegacyIds::ITEM); + self::register(Painting::class, ['Painting', 'minecraft:painting'], EntityLegacyIds::PAINTING); + self::register(PrimedTNT::class, ['PrimedTnt', 'PrimedTNT', 'minecraft:tnt'], EntityLegacyIds::TNT); + self::register(Snowball::class, ['Snowball', 'minecraft:snowball'], EntityLegacyIds::SNOWBALL); + self::register(SplashPotion::class, ['ThrownPotion', 'minecraft:potion', 'thrownpotion'], EntityLegacyIds::SPLASH_POTION); + self::register(Squid::class, ['Squid', 'minecraft:squid'], EntityLegacyIds::SQUID); + self::register(Villager::class, ['Villager', 'minecraft:villager'], EntityLegacyIds::VILLAGER); + self::register(Zombie::class, ['Zombie', 'minecraft:zombie'], EntityLegacyIds::ZOMBIE); self::register(Human::class, ['Human']); diff --git a/src/pocketmine/entity/Squid.php b/src/pocketmine/entity/Squid.php index 6db85a3730..dd6935d570 100644 --- a/src/pocketmine/entity/Squid.php +++ b/src/pocketmine/entity/Squid.php @@ -29,13 +29,14 @@ use pocketmine\item\VanillaItems; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\ActorEventPacket; +use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; use function atan2; use function mt_rand; use function sqrt; use const M_PI; class Squid extends WaterAnimal{ - public const NETWORK_ID = self::SQUID; + public const NETWORK_ID = EntityLegacyIds::SQUID; public $width = 0.95; public $height = 0.95; diff --git a/src/pocketmine/entity/Villager.php b/src/pocketmine/entity/Villager.php index 85906b14d5..9d684c8355 100644 --- a/src/pocketmine/entity/Villager.php +++ b/src/pocketmine/entity/Villager.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; @@ -34,7 +35,7 @@ class Villager extends Living implements Ageable{ public const PROFESSION_BLACKSMITH = 3; public const PROFESSION_BUTCHER = 4; - public const NETWORK_ID = self::VILLAGER; + public const NETWORK_ID = EntityLegacyIds::VILLAGER; public $width = 0.6; public $height = 1.8; diff --git a/src/pocketmine/entity/Zombie.php b/src/pocketmine/entity/Zombie.php index 3eb7f391be..b1cf5cd470 100644 --- a/src/pocketmine/entity/Zombie.php +++ b/src/pocketmine/entity/Zombie.php @@ -24,10 +24,11 @@ declare(strict_types=1); namespace pocketmine\entity; use pocketmine\item\VanillaItems; +use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; use function mt_rand; class Zombie extends Living{ - public const NETWORK_ID = self::ZOMBIE; + public const NETWORK_ID = EntityLegacyIds::ZOMBIE; public $width = 0.6; public $height = 1.8; diff --git a/src/pocketmine/entity/object/ExperienceOrb.php b/src/pocketmine/entity/object/ExperienceOrb.php index dc04c9392d..9c7e830209 100644 --- a/src/pocketmine/entity/object/ExperienceOrb.php +++ b/src/pocketmine/entity/object/ExperienceOrb.php @@ -28,12 +28,13 @@ use pocketmine\entity\Human; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ShortTag; +use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; use pocketmine\player\Player; use function sqrt; class ExperienceOrb extends Entity{ - public const NETWORK_ID = self::XP_ORB; + public const NETWORK_ID = EntityLegacyIds::XP_ORB; public const TAG_VALUE_PC = "Value"; //short public const TAG_VALUE_PE = "experience value"; //int (WTF?) diff --git a/src/pocketmine/entity/object/FallingBlock.php b/src/pocketmine/entity/object/FallingBlock.php index ae8cc7e921..7f6debc0aa 100644 --- a/src/pocketmine/entity/object/FallingBlock.php +++ b/src/pocketmine/entity/object/FallingBlock.php @@ -32,11 +32,12 @@ use pocketmine\event\entity\EntityDamageEvent; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; +use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; use function get_class; class FallingBlock extends Entity{ - public const NETWORK_ID = self::FALLING_BLOCK; + public const NETWORK_ID = EntityLegacyIds::FALLING_BLOCK; public $width = 0.98; public $height = 0.98; diff --git a/src/pocketmine/entity/object/ItemEntity.php b/src/pocketmine/entity/object/ItemEntity.php index dcf250aefb..5c2d2e039a 100644 --- a/src/pocketmine/entity/object/ItemEntity.php +++ b/src/pocketmine/entity/object/ItemEntity.php @@ -31,14 +31,15 @@ use pocketmine\event\inventory\InventoryPickupItemEvent; use pocketmine\item\Item; use pocketmine\item\ItemIds; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\player\Player; use pocketmine\network\mcpe\protocol\AddItemActorPacket; use pocketmine\network\mcpe\protocol\TakeItemActorPacket; +use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; +use pocketmine\player\Player; use function get_class; use function max; class ItemEntity extends Entity{ - public const NETWORK_ID = self::ITEM; + public const NETWORK_ID = EntityLegacyIds::ITEM; public const DEFAULT_DESPAWN_DELAY = 6000; //5 minutes public const NEVER_DESPAWN = -1; diff --git a/src/pocketmine/entity/object/Painting.php b/src/pocketmine/entity/object/Painting.php index ae81183504..eb0318a1df 100644 --- a/src/pocketmine/entity/object/Painting.php +++ b/src/pocketmine/entity/object/Painting.php @@ -34,13 +34,14 @@ use pocketmine\math\Vector3; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\AddPaintingPacket; +use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; use pocketmine\player\Player; use pocketmine\world\particle\DestroyBlockParticle; use pocketmine\world\World; use function ceil; class Painting extends Entity{ - public const NETWORK_ID = self::PAINTING; + public const NETWORK_ID = EntityLegacyIds::PAINTING; /** @var float */ protected $gravity = 0.0; diff --git a/src/pocketmine/entity/object/PrimedTNT.php b/src/pocketmine/entity/object/PrimedTNT.php index 26467869d9..0a4f8364c7 100644 --- a/src/pocketmine/entity/object/PrimedTNT.php +++ b/src/pocketmine/entity/object/PrimedTNT.php @@ -29,6 +29,7 @@ use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\ExplosionPrimeEvent; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ShortTag; +use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; use pocketmine\world\Explosion; @@ -36,7 +37,7 @@ use pocketmine\world\Position; use pocketmine\world\sound\IgniteSound; class PrimedTNT extends Entity implements Explosive{ - public const NETWORK_ID = self::TNT; + public const NETWORK_ID = EntityLegacyIds::TNT; public $width = 0.98; public $height = 0.98; diff --git a/src/pocketmine/entity/projectile/Arrow.php b/src/pocketmine/entity/projectile/Arrow.php index 51926dc4fd..f38551b9e2 100644 --- a/src/pocketmine/entity/projectile/Arrow.php +++ b/src/pocketmine/entity/projectile/Arrow.php @@ -32,6 +32,7 @@ use pocketmine\math\RayTraceResult; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\ActorEventPacket; use pocketmine\network\mcpe\protocol\TakeItemActorPacket; +use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; use pocketmine\player\Player; use pocketmine\world\sound\ArrowHitSound; @@ -40,7 +41,7 @@ use function mt_rand; use function sqrt; class Arrow extends Projectile{ - public const NETWORK_ID = self::ARROW; + public const NETWORK_ID = EntityLegacyIds::ARROW; public const PICKUP_NONE = 0; public const PICKUP_ANY = 1; diff --git a/src/pocketmine/entity/projectile/Egg.php b/src/pocketmine/entity/projectile/Egg.php index 91d8019787..c736bf2885 100644 --- a/src/pocketmine/entity/projectile/Egg.php +++ b/src/pocketmine/entity/projectile/Egg.php @@ -25,10 +25,11 @@ namespace pocketmine\entity\projectile; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\item\VanillaItems; +use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; use pocketmine\world\particle\ItemBreakParticle; class Egg extends Throwable{ - public const NETWORK_ID = self::EGG; + public const NETWORK_ID = EntityLegacyIds::EGG; //TODO: spawn chickens on collision diff --git a/src/pocketmine/entity/projectile/EnderPearl.php b/src/pocketmine/entity/projectile/EnderPearl.php index 9293219bab..c438903dcc 100644 --- a/src/pocketmine/entity/projectile/EnderPearl.php +++ b/src/pocketmine/entity/projectile/EnderPearl.php @@ -30,11 +30,12 @@ use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\math\AxisAlignedBB; use pocketmine\math\RayTraceResult; use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; use pocketmine\world\particle\EndermanTeleportParticle; use pocketmine\world\sound\EndermanTeleportSound; class EnderPearl extends Throwable{ - public const NETWORK_ID = self::ENDER_PEARL; + public const NETWORK_ID = EntityLegacyIds::ENDER_PEARL; protected function calculateInterceptWithBlock(Block $block, Vector3 $start, Vector3 $end) : ?RayTraceResult{ if($block->getId() !== BlockLegacyIds::AIR and empty($block->getCollisionBoxes())){ diff --git a/src/pocketmine/entity/projectile/ExperienceBottle.php b/src/pocketmine/entity/projectile/ExperienceBottle.php index 103ce1c03d..879eb627d3 100644 --- a/src/pocketmine/entity/projectile/ExperienceBottle.php +++ b/src/pocketmine/entity/projectile/ExperienceBottle.php @@ -24,12 +24,13 @@ declare(strict_types=1); namespace pocketmine\entity\projectile; use pocketmine\event\entity\ProjectileHitEvent; +use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; use pocketmine\world\particle\PotionSplashParticle; use pocketmine\world\sound\PotionSplashSound; use function mt_rand; class ExperienceBottle extends Throwable{ - public const NETWORK_ID = self::XP_BOTTLE; + public const NETWORK_ID = EntityLegacyIds::XP_BOTTLE; protected $gravity = 0.07; diff --git a/src/pocketmine/entity/projectile/Snowball.php b/src/pocketmine/entity/projectile/Snowball.php index 1ff3fc2f67..ccaab45982 100644 --- a/src/pocketmine/entity/projectile/Snowball.php +++ b/src/pocketmine/entity/projectile/Snowball.php @@ -24,10 +24,11 @@ declare(strict_types=1); namespace pocketmine\entity\projectile; use pocketmine\event\entity\ProjectileHitEvent; +use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; use pocketmine\world\particle\SnowballPoofParticle; class Snowball extends Throwable{ - public const NETWORK_ID = self::SNOWBALL; + public const NETWORK_ID = EntityLegacyIds::SNOWBALL; protected function onHit(ProjectileHitEvent $event) : void{ for($i = 0; $i < 6; ++$i){ diff --git a/src/pocketmine/entity/projectile/SplashPotion.php b/src/pocketmine/entity/projectile/SplashPotion.php index a930cd37e4..343037f017 100644 --- a/src/pocketmine/entity/projectile/SplashPotion.php +++ b/src/pocketmine/entity/projectile/SplashPotion.php @@ -33,6 +33,7 @@ use pocketmine\event\entity\ProjectileHitEntityEvent; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\item\Potion; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; use pocketmine\utils\Color; @@ -43,7 +44,7 @@ use function sqrt; class SplashPotion extends Throwable{ - public const NETWORK_ID = self::SPLASH_POTION; + public const NETWORK_ID = EntityLegacyIds::SPLASH_POTION; protected $gravity = 0.05; protected $drag = 0.01; diff --git a/src/pocketmine/network/mcpe/protocol/AddActorPacket.php b/src/pocketmine/network/mcpe/protocol/AddActorPacket.php index d5686658a5..6a875d3368 100644 --- a/src/pocketmine/network/mcpe/protocol/AddActorPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddActorPacket.php @@ -26,10 +26,10 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\entity\Attribute; -use pocketmine\entity\EntityIds; use pocketmine\math\Vector3; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\EntityLink; use function array_search; use function count; @@ -45,104 +45,104 @@ class AddActorPacket extends DataPacket implements ClientboundPacket{ * TODO: remove this on 4.0 */ public const LEGACY_ID_MAP_BC = [ - EntityIds::NPC => "minecraft:npc", - EntityIds::PLAYER => "minecraft:player", - EntityIds::WITHER_SKELETON => "minecraft:wither_skeleton", - EntityIds::HUSK => "minecraft:husk", - EntityIds::STRAY => "minecraft:stray", - EntityIds::WITCH => "minecraft:witch", - EntityIds::ZOMBIE_VILLAGER => "minecraft:zombie_villager", - EntityIds::BLAZE => "minecraft:blaze", - EntityIds::MAGMA_CUBE => "minecraft:magma_cube", - EntityIds::GHAST => "minecraft:ghast", - EntityIds::CAVE_SPIDER => "minecraft:cave_spider", - EntityIds::SILVERFISH => "minecraft:silverfish", - EntityIds::ENDERMAN => "minecraft:enderman", - EntityIds::SLIME => "minecraft:slime", - EntityIds::ZOMBIE_PIGMAN => "minecraft:zombie_pigman", - EntityIds::SPIDER => "minecraft:spider", - EntityIds::SKELETON => "minecraft:skeleton", - EntityIds::CREEPER => "minecraft:creeper", - EntityIds::ZOMBIE => "minecraft:zombie", - EntityIds::SKELETON_HORSE => "minecraft:skeleton_horse", - EntityIds::MULE => "minecraft:mule", - EntityIds::DONKEY => "minecraft:donkey", - EntityIds::DOLPHIN => "minecraft:dolphin", - EntityIds::TROPICALFISH => "minecraft:tropicalfish", - EntityIds::WOLF => "minecraft:wolf", - EntityIds::SQUID => "minecraft:squid", - EntityIds::DROWNED => "minecraft:drowned", - EntityIds::SHEEP => "minecraft:sheep", - EntityIds::MOOSHROOM => "minecraft:mooshroom", - EntityIds::PANDA => "minecraft:panda", - EntityIds::SALMON => "minecraft:salmon", - EntityIds::PIG => "minecraft:pig", - EntityIds::VILLAGER => "minecraft:villager", - EntityIds::COD => "minecraft:cod", - EntityIds::PUFFERFISH => "minecraft:pufferfish", - EntityIds::COW => "minecraft:cow", - EntityIds::CHICKEN => "minecraft:chicken", - EntityIds::BALLOON => "minecraft:balloon", - EntityIds::LLAMA => "minecraft:llama", - EntityIds::IRON_GOLEM => "minecraft:iron_golem", - EntityIds::RABBIT => "minecraft:rabbit", - EntityIds::SNOW_GOLEM => "minecraft:snow_golem", - EntityIds::BAT => "minecraft:bat", - EntityIds::OCELOT => "minecraft:ocelot", - EntityIds::HORSE => "minecraft:horse", - EntityIds::CAT => "minecraft:cat", - EntityIds::POLAR_BEAR => "minecraft:polar_bear", - EntityIds::ZOMBIE_HORSE => "minecraft:zombie_horse", - EntityIds::TURTLE => "minecraft:turtle", - EntityIds::PARROT => "minecraft:parrot", - EntityIds::GUARDIAN => "minecraft:guardian", - EntityIds::ELDER_GUARDIAN => "minecraft:elder_guardian", - EntityIds::VINDICATOR => "minecraft:vindicator", - EntityIds::WITHER => "minecraft:wither", - EntityIds::ENDER_DRAGON => "minecraft:ender_dragon", - EntityIds::SHULKER => "minecraft:shulker", - EntityIds::ENDERMITE => "minecraft:endermite", - EntityIds::MINECART => "minecraft:minecart", - EntityIds::HOPPER_MINECART => "minecraft:hopper_minecart", - EntityIds::TNT_MINECART => "minecraft:tnt_minecart", - EntityIds::CHEST_MINECART => "minecraft:chest_minecart", - EntityIds::COMMAND_BLOCK_MINECART => "minecraft:command_block_minecart", - EntityIds::ARMOR_STAND => "minecraft:armor_stand", - EntityIds::ITEM => "minecraft:item", - EntityIds::TNT => "minecraft:tnt", - EntityIds::FALLING_BLOCK => "minecraft:falling_block", - EntityIds::XP_BOTTLE => "minecraft:xp_bottle", - EntityIds::XP_ORB => "minecraft:xp_orb", - EntityIds::EYE_OF_ENDER_SIGNAL => "minecraft:eye_of_ender_signal", - EntityIds::ENDER_CRYSTAL => "minecraft:ender_crystal", - EntityIds::SHULKER_BULLET => "minecraft:shulker_bullet", - EntityIds::FISHING_HOOK => "minecraft:fishing_hook", - EntityIds::DRAGON_FIREBALL => "minecraft:dragon_fireball", - EntityIds::ARROW => "minecraft:arrow", - EntityIds::SNOWBALL => "minecraft:snowball", - EntityIds::EGG => "minecraft:egg", - EntityIds::PAINTING => "minecraft:painting", - EntityIds::THROWN_TRIDENT => "minecraft:thrown_trident", - EntityIds::FIREBALL => "minecraft:fireball", - EntityIds::SPLASH_POTION => "minecraft:splash_potion", - EntityIds::ENDER_PEARL => "minecraft:ender_pearl", - EntityIds::LEASH_KNOT => "minecraft:leash_knot", - EntityIds::WITHER_SKULL => "minecraft:wither_skull", - EntityIds::WITHER_SKULL_DANGEROUS => "minecraft:wither_skull_dangerous", - EntityIds::BOAT => "minecraft:boat", - EntityIds::LIGHTNING_BOLT => "minecraft:lightning_bolt", - EntityIds::SMALL_FIREBALL => "minecraft:small_fireball", - EntityIds::LLAMA_SPIT => "minecraft:llama_spit", - EntityIds::AREA_EFFECT_CLOUD => "minecraft:area_effect_cloud", - EntityIds::LINGERING_POTION => "minecraft:lingering_potion", - EntityIds::FIREWORKS_ROCKET => "minecraft:fireworks_rocket", - EntityIds::EVOCATION_FANG => "minecraft:evocation_fang", - EntityIds::EVOCATION_ILLAGER => "minecraft:evocation_illager", - EntityIds::VEX => "minecraft:vex", - EntityIds::AGENT => "minecraft:agent", - EntityIds::ICE_BOMB => "minecraft:ice_bomb", - EntityIds::PHANTOM => "minecraft:phantom", - EntityIds::TRIPOD_CAMERA => "minecraft:tripod_camera" + EntityLegacyIds::NPC => "minecraft:npc", + EntityLegacyIds::PLAYER => "minecraft:player", + EntityLegacyIds::WITHER_SKELETON => "minecraft:wither_skeleton", + EntityLegacyIds::HUSK => "minecraft:husk", + EntityLegacyIds::STRAY => "minecraft:stray", + EntityLegacyIds::WITCH => "minecraft:witch", + EntityLegacyIds::ZOMBIE_VILLAGER => "minecraft:zombie_villager", + EntityLegacyIds::BLAZE => "minecraft:blaze", + EntityLegacyIds::MAGMA_CUBE => "minecraft:magma_cube", + EntityLegacyIds::GHAST => "minecraft:ghast", + EntityLegacyIds::CAVE_SPIDER => "minecraft:cave_spider", + EntityLegacyIds::SILVERFISH => "minecraft:silverfish", + EntityLegacyIds::ENDERMAN => "minecraft:enderman", + EntityLegacyIds::SLIME => "minecraft:slime", + EntityLegacyIds::ZOMBIE_PIGMAN => "minecraft:zombie_pigman", + EntityLegacyIds::SPIDER => "minecraft:spider", + EntityLegacyIds::SKELETON => "minecraft:skeleton", + EntityLegacyIds::CREEPER => "minecraft:creeper", + EntityLegacyIds::ZOMBIE => "minecraft:zombie", + EntityLegacyIds::SKELETON_HORSE => "minecraft:skeleton_horse", + EntityLegacyIds::MULE => "minecraft:mule", + EntityLegacyIds::DONKEY => "minecraft:donkey", + EntityLegacyIds::DOLPHIN => "minecraft:dolphin", + EntityLegacyIds::TROPICALFISH => "minecraft:tropicalfish", + EntityLegacyIds::WOLF => "minecraft:wolf", + EntityLegacyIds::SQUID => "minecraft:squid", + EntityLegacyIds::DROWNED => "minecraft:drowned", + EntityLegacyIds::SHEEP => "minecraft:sheep", + EntityLegacyIds::MOOSHROOM => "minecraft:mooshroom", + EntityLegacyIds::PANDA => "minecraft:panda", + EntityLegacyIds::SALMON => "minecraft:salmon", + EntityLegacyIds::PIG => "minecraft:pig", + EntityLegacyIds::VILLAGER => "minecraft:villager", + EntityLegacyIds::COD => "minecraft:cod", + EntityLegacyIds::PUFFERFISH => "minecraft:pufferfish", + EntityLegacyIds::COW => "minecraft:cow", + EntityLegacyIds::CHICKEN => "minecraft:chicken", + EntityLegacyIds::BALLOON => "minecraft:balloon", + EntityLegacyIds::LLAMA => "minecraft:llama", + EntityLegacyIds::IRON_GOLEM => "minecraft:iron_golem", + EntityLegacyIds::RABBIT => "minecraft:rabbit", + EntityLegacyIds::SNOW_GOLEM => "minecraft:snow_golem", + EntityLegacyIds::BAT => "minecraft:bat", + EntityLegacyIds::OCELOT => "minecraft:ocelot", + EntityLegacyIds::HORSE => "minecraft:horse", + EntityLegacyIds::CAT => "minecraft:cat", + EntityLegacyIds::POLAR_BEAR => "minecraft:polar_bear", + EntityLegacyIds::ZOMBIE_HORSE => "minecraft:zombie_horse", + EntityLegacyIds::TURTLE => "minecraft:turtle", + EntityLegacyIds::PARROT => "minecraft:parrot", + EntityLegacyIds::GUARDIAN => "minecraft:guardian", + EntityLegacyIds::ELDER_GUARDIAN => "minecraft:elder_guardian", + EntityLegacyIds::VINDICATOR => "minecraft:vindicator", + EntityLegacyIds::WITHER => "minecraft:wither", + EntityLegacyIds::ENDER_DRAGON => "minecraft:ender_dragon", + EntityLegacyIds::SHULKER => "minecraft:shulker", + EntityLegacyIds::ENDERMITE => "minecraft:endermite", + EntityLegacyIds::MINECART => "minecraft:minecart", + EntityLegacyIds::HOPPER_MINECART => "minecraft:hopper_minecart", + EntityLegacyIds::TNT_MINECART => "minecraft:tnt_minecart", + EntityLegacyIds::CHEST_MINECART => "minecraft:chest_minecart", + EntityLegacyIds::COMMAND_BLOCK_MINECART => "minecraft:command_block_minecart", + EntityLegacyIds::ARMOR_STAND => "minecraft:armor_stand", + EntityLegacyIds::ITEM => "minecraft:item", + EntityLegacyIds::TNT => "minecraft:tnt", + EntityLegacyIds::FALLING_BLOCK => "minecraft:falling_block", + EntityLegacyIds::XP_BOTTLE => "minecraft:xp_bottle", + EntityLegacyIds::XP_ORB => "minecraft:xp_orb", + EntityLegacyIds::EYE_OF_ENDER_SIGNAL => "minecraft:eye_of_ender_signal", + EntityLegacyIds::ENDER_CRYSTAL => "minecraft:ender_crystal", + EntityLegacyIds::SHULKER_BULLET => "minecraft:shulker_bullet", + EntityLegacyIds::FISHING_HOOK => "minecraft:fishing_hook", + EntityLegacyIds::DRAGON_FIREBALL => "minecraft:dragon_fireball", + EntityLegacyIds::ARROW => "minecraft:arrow", + EntityLegacyIds::SNOWBALL => "minecraft:snowball", + EntityLegacyIds::EGG => "minecraft:egg", + EntityLegacyIds::PAINTING => "minecraft:painting", + EntityLegacyIds::THROWN_TRIDENT => "minecraft:thrown_trident", + EntityLegacyIds::FIREBALL => "minecraft:fireball", + EntityLegacyIds::SPLASH_POTION => "minecraft:splash_potion", + EntityLegacyIds::ENDER_PEARL => "minecraft:ender_pearl", + EntityLegacyIds::LEASH_KNOT => "minecraft:leash_knot", + EntityLegacyIds::WITHER_SKULL => "minecraft:wither_skull", + EntityLegacyIds::WITHER_SKULL_DANGEROUS => "minecraft:wither_skull_dangerous", + EntityLegacyIds::BOAT => "minecraft:boat", + EntityLegacyIds::LIGHTNING_BOLT => "minecraft:lightning_bolt", + EntityLegacyIds::SMALL_FIREBALL => "minecraft:small_fireball", + EntityLegacyIds::LLAMA_SPIT => "minecraft:llama_spit", + EntityLegacyIds::AREA_EFFECT_CLOUD => "minecraft:area_effect_cloud", + EntityLegacyIds::LINGERING_POTION => "minecraft:lingering_potion", + EntityLegacyIds::FIREWORKS_ROCKET => "minecraft:fireworks_rocket", + EntityLegacyIds::EVOCATION_FANG => "minecraft:evocation_fang", + EntityLegacyIds::EVOCATION_ILLAGER => "minecraft:evocation_illager", + EntityLegacyIds::VEX => "minecraft:vex", + EntityLegacyIds::AGENT => "minecraft:agent", + EntityLegacyIds::ICE_BOMB => "minecraft:ice_bomb", + EntityLegacyIds::PHANTOM => "minecraft:phantom", + EntityLegacyIds::TRIPOD_CAMERA => "minecraft:tripod_camera" ]; /** @var int|null */ diff --git a/src/pocketmine/entity/EntityIds.php b/src/pocketmine/network/mcpe/protocol/types/EntityLegacyIds.php similarity index 96% rename from src/pocketmine/entity/EntityIds.php rename to src/pocketmine/network/mcpe/protocol/types/EntityLegacyIds.php index 9ec904717a..caa93bb2ac 100644 --- a/src/pocketmine/entity/EntityIds.php +++ b/src/pocketmine/network/mcpe/protocol/types/EntityLegacyIds.php @@ -21,9 +21,10 @@ declare(strict_types=1); -namespace pocketmine\entity; +namespace pocketmine\network\mcpe\protocol\types; -interface EntityIds{ + +final class EntityLegacyIds{ public const CHICKEN = 10; public const COW = 11; @@ -127,4 +128,8 @@ interface EntityIds{ public const TROPICALFISH = 111, TROPICAL_FISH = 111; public const COD = 112, FISH = 112; public const PANDA = 113; + + private function __construct(){ + //NOOP + } } From 1fee70abfb8b86c2ce1e1986f88ae1fa4a48a6e7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jul 2019 17:43:06 +0100 Subject: [PATCH 1115/3224] Item no longer implements ItemIds --- src/pocketmine/block/Leaves.php | 3 +- src/pocketmine/block/Skull.php | 3 +- .../transaction/CraftingTransaction.php | 25 +- src/pocketmine/item/Bucket.php | 2 +- src/pocketmine/item/Item.php | 4 +- src/pocketmine/item/ItemFactory.php | 448 +++++++++--------- tests/phpunit/inventory/BaseInventoryTest.php | 6 +- tests/phpunit/item/ItemFactoryTest.php | 4 +- tests/phpunit/item/ItemTest.php | 8 +- 9 files changed, 253 insertions(+), 250 deletions(-) diff --git a/src/pocketmine/block/Leaves.php b/src/pocketmine/block/Leaves.php index 7f0a871ab4..2b4091acf9 100644 --- a/src/pocketmine/block/Leaves.php +++ b/src/pocketmine/block/Leaves.php @@ -27,6 +27,7 @@ use pocketmine\block\utils\TreeType; use pocketmine\event\block\LeavesDecayEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\item\ItemIds; use pocketmine\item\VanillaItems; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -125,7 +126,7 @@ class Leaves extends Transparent{ $drops = []; if(mt_rand(1, 20) === 1){ //Saplings - $drops[] = ItemFactory::get(Item::SAPLING, $this->treeType->getMagicNumber()); + $drops[] = ItemFactory::get(ItemIds::SAPLING, $this->treeType->getMagicNumber()); } if(($this->treeType->equals(TreeType::OAK()) or $this->treeType->equals(TreeType::DARK_OAK())) and mt_rand(1, 200) === 1){ //Apples $drops[] = VanillaItems::APPLE(); diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index 04806392eb..f0796b583d 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -28,6 +28,7 @@ use pocketmine\block\utils\BlockDataValidator; use pocketmine\block\utils\SkullType; use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\item\ItemIds; use pocketmine\item\Skull as ItemSkull; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -110,6 +111,6 @@ class Skull extends Flowable{ } public function asItem() : Item{ - return ItemFactory::get(Item::SKULL, $this->skullType->getMagicNumber()); + return ItemFactory::get(ItemIds::SKULL, $this->skullType->getMagicNumber()); } } diff --git a/src/pocketmine/inventory/transaction/CraftingTransaction.php b/src/pocketmine/inventory/transaction/CraftingTransaction.php index ab9545f9a8..623b101ff0 100644 --- a/src/pocketmine/inventory/transaction/CraftingTransaction.php +++ b/src/pocketmine/inventory/transaction/CraftingTransaction.php @@ -26,6 +26,7 @@ namespace pocketmine\inventory\transaction; use pocketmine\crafting\CraftingRecipe; use pocketmine\event\inventory\CraftItemEvent; use pocketmine\item\Item; +use pocketmine\item\ItemIds; use pocketmine\network\mcpe\protocol\ContainerClosePacket; use pocketmine\network\mcpe\protocol\types\ContainerIds; use function array_pop; @@ -174,34 +175,34 @@ class CraftingTransaction extends InventoryTransaction{ if(parent::execute()){ foreach($this->outputs as $item){ switch($item->getId()){ - case Item::CRAFTING_TABLE: + case ItemIds::CRAFTING_TABLE: $this->source->awardAchievement("buildWorkBench"); break; - case Item::WOODEN_PICKAXE: + case ItemIds::WOODEN_PICKAXE: $this->source->awardAchievement("buildPickaxe"); break; - case Item::FURNACE: + case ItemIds::FURNACE: $this->source->awardAchievement("buildFurnace"); break; - case Item::WOODEN_HOE: + case ItemIds::WOODEN_HOE: $this->source->awardAchievement("buildHoe"); break; - case Item::BREAD: + case ItemIds::BREAD: $this->source->awardAchievement("makeBread"); break; - case Item::CAKE: + case ItemIds::CAKE: $this->source->awardAchievement("bakeCake"); break; - case Item::STONE_PICKAXE: - case Item::GOLDEN_PICKAXE: - case Item::IRON_PICKAXE: - case Item::DIAMOND_PICKAXE: + case ItemIds::STONE_PICKAXE: + case ItemIds::GOLDEN_PICKAXE: + case ItemIds::IRON_PICKAXE: + case ItemIds::DIAMOND_PICKAXE: $this->source->awardAchievement("buildBetterPickaxe"); break; - case Item::WOODEN_SWORD: + case ItemIds::WOODEN_SWORD: $this->source->awardAchievement("buildSword"); break; - case Item::DIAMOND: + case ItemIds::DIAMOND: $this->source->awardAchievement("diamond"); break; } diff --git a/src/pocketmine/item/Bucket.php b/src/pocketmine/item/Bucket.php index d6f880a464..fdcb8ec895 100644 --- a/src/pocketmine/item/Bucket.php +++ b/src/pocketmine/item/Bucket.php @@ -42,7 +42,7 @@ class Bucket extends Item{ $stack = clone $this; $stack->pop(); - $resultItem = ItemFactory::get(Item::BUCKET, $blockClicked->getFlowingForm()->getId()); + $resultItem = ItemFactory::get(ItemIds::BUCKET, $blockClicked->getFlowingForm()->getId()); $ev = new PlayerBucketFillEvent($player, $blockReplace, $face, $this, $resultItem); $ev->call(); if(!$ev->isCancelled()){ diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 2dfaec9858..0df0388e8b 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -52,7 +52,7 @@ use function gettype; use function hex2bin; use function is_string; -class Item implements ItemIds, \JsonSerializable{ +class Item implements \JsonSerializable{ use ItemEnchantmentHandlingTrait; public const TAG_ENCH = "ench"; @@ -426,7 +426,7 @@ class Item implements ItemIds, \JsonSerializable{ } public function isNull() : bool{ - return $this->count <= 0 or $this->id === Item::AIR; + return $this->count <= 0 or $this->id === ItemIds::AIR; } /** diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index b341fa3701..a243cf0d21 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -55,227 +55,227 @@ class ItemFactory{ public static function init() : void{ self::$list = []; //in case of re-initializing - self::register(new Apple(Item::APPLE, 0, "Apple")); - self::register(new Arrow(Item::ARROW, 0, "Arrow")); - self::register(new Axe(Item::DIAMOND_AXE, "Diamond Axe", ToolTier::DIAMOND())); - self::register(new Axe(Item::GOLDEN_AXE, "Golden Axe", ToolTier::GOLD())); - self::register(new Axe(Item::IRON_AXE, "Iron Axe", ToolTier::IRON())); - self::register(new Axe(Item::STONE_AXE, "Stone Axe", ToolTier::STONE())); - self::register(new Axe(Item::WOODEN_AXE, "Wooden Axe", ToolTier::WOOD())); - self::register(new BakedPotato(Item::BAKED_POTATO, 0, "Baked Potato")); - self::register(new Beetroot(Item::BEETROOT, 0, "Beetroot")); - self::register(new BeetrootSeeds(Item::BEETROOT_SEEDS, 0, "Beetroot Seeds")); - self::register(new BeetrootSoup(Item::BEETROOT_SOUP, 0, "Beetroot Soup")); - self::register(new BlazeRod(Item::BLAZE_ROD, 0, "Blaze Rod")); - self::register(new Book(Item::BOOK, 0, "Book")); - self::register(new Boots(Item::CHAIN_BOOTS, 0, "Chainmail Boots", new ArmorTypeInfo(1, 196))); - self::register(new Boots(Item::DIAMOND_BOOTS, 0, "Diamond Boots", new ArmorTypeInfo(3, 430))); - self::register(new Boots(Item::GOLDEN_BOOTS, 0, "Golden Boots", new ArmorTypeInfo(1, 92))); - self::register(new Boots(Item::IRON_BOOTS, 0, "Iron Boots", new ArmorTypeInfo(2, 196))); - self::register(new Boots(Item::LEATHER_BOOTS, 0, "Leather Boots", new ArmorTypeInfo(1, 66))); - self::register(new Bow(Item::BOW, 0, "Bow")); - self::register(new Bowl(Item::BOWL, 0, "Bowl")); - self::register(new Bread(Item::BREAD, 0, "Bread")); - self::register(new Bucket(Item::BUCKET, 0, "Bucket")); - self::register(new Carrot(Item::CARROT, 0, "Carrot")); - self::register(new Chestplate(Item::CHAIN_CHESTPLATE, 0, "Chainmail Chestplate", new ArmorTypeInfo(5, 241))); - self::register(new Chestplate(Item::DIAMOND_CHESTPLATE, 0, "Diamond Chestplate", new ArmorTypeInfo(8, 529))); - self::register(new Chestplate(Item::GOLDEN_CHESTPLATE, 0, "Golden Chestplate", new ArmorTypeInfo(5, 113))); - self::register(new Chestplate(Item::IRON_CHESTPLATE, 0, "Iron Chestplate", new ArmorTypeInfo(6, 241))); - self::register(new Chestplate(Item::LEATHER_CHESTPLATE, 0, "Leather Tunic", new ArmorTypeInfo(3, 81))); - self::register(new ChorusFruit(Item::CHORUS_FRUIT, 0, "Chorus Fruit")); - self::register(new Clock(Item::CLOCK, 0, "Clock")); - self::register(new Clownfish(Item::CLOWNFISH, 0, "Clownfish")); - self::register(new Coal(Item::COAL, 0, "Coal")); - self::register(new Coal(Item::COAL, 1, "Charcoal")); - self::register(new CocoaBeans(Item::DYE, 3, "Cocoa Beans")); - self::register(new Compass(Item::COMPASS, 0, "Compass")); - self::register(new CookedChicken(Item::COOKED_CHICKEN, 0, "Cooked Chicken")); - self::register(new CookedFish(Item::COOKED_FISH, 0, "Cooked Fish")); - self::register(new CookedMutton(Item::COOKED_MUTTON, 0, "Cooked Mutton")); - self::register(new CookedPorkchop(Item::COOKED_PORKCHOP, 0, "Cooked Porkchop")); - self::register(new CookedRabbit(Item::COOKED_RABBIT, 0, "Cooked Rabbit")); - self::register(new CookedSalmon(Item::COOKED_SALMON, 0, "Cooked Salmon")); - self::register(new Cookie(Item::COOKIE, 0, "Cookie")); - self::register(new DriedKelp(Item::DRIED_KELP, 0, "Dried Kelp")); - self::register(new Egg(Item::EGG, 0, "Egg")); - self::register(new EnderPearl(Item::ENDER_PEARL, 0, "Ender Pearl")); - self::register(new ExperienceBottle(Item::EXPERIENCE_BOTTLE, 0, "Bottle o' Enchanting")); - self::register(new Fertilizer(Item::DYE, 15, "Bone Meal")); - self::register(new FishingRod(Item::FISHING_ROD, 0, "Fishing Rod")); - self::register(new FlintSteel(Item::FLINT_STEEL, 0, "Flint and Steel")); - self::register(new GlassBottle(Item::GLASS_BOTTLE, 0, "Glass Bottle")); - self::register(new GoldenApple(Item::GOLDEN_APPLE, 0, "Golden Apple")); - self::register(new GoldenAppleEnchanted(Item::ENCHANTED_GOLDEN_APPLE, 0, "Enchanted Golden Apple")); - self::register(new GoldenCarrot(Item::GOLDEN_CARROT, 0, "Golden Carrot")); - self::register(new Helmet(Item::CHAIN_HELMET, 0, "Chainmail Helmet", new ArmorTypeInfo(2, 166))); - self::register(new Helmet(Item::DIAMOND_HELMET, 0, "Diamond Helmet", new ArmorTypeInfo(3, 364))); - self::register(new Helmet(Item::GOLDEN_HELMET, 0, "Golden Helmet", new ArmorTypeInfo(2, 78))); - self::register(new Helmet(Item::IRON_HELMET, 0, "Iron Helmet", new ArmorTypeInfo(2, 166))); - self::register(new Helmet(Item::LEATHER_HELMET, 0, "Leather Cap", new ArmorTypeInfo(1, 56))); - self::register(new Hoe(Item::DIAMOND_HOE, "Diamond Hoe", ToolTier::DIAMOND())); - self::register(new Hoe(Item::GOLDEN_HOE, "Golden Hoe", ToolTier::GOLD())); - self::register(new Hoe(Item::IRON_HOE, "Iron Hoe", ToolTier::IRON())); - self::register(new Hoe(Item::STONE_HOE, "Stone Hoe", ToolTier::STONE())); - self::register(new Hoe(Item::WOODEN_HOE, "Wooden Hoe", ToolTier::WOOD())); - self::register(new Item(Item::BLAZE_POWDER, 0, "Blaze Powder")); - self::register(new Item(Item::BLEACH, 0, "Bleach")); //EDU - self::register(new Item(Item::BONE, 0, "Bone")); - self::register(new Item(Item::BRICK, 0, "Brick")); - self::register(new Item(Item::CHORUS_FRUIT_POPPED, 0, "Popped Chorus Fruit")); - self::register(new Item(Item::CLAY_BALL, 0, "Clay")); - self::register(new Item(Item::COMPOUND, 0, "Salt")); - self::register(new Item(Item::COMPOUND, 1, "Sodium Oxide")); - self::register(new Item(Item::COMPOUND, 2, "Sodium Hydroxide")); - self::register(new Item(Item::COMPOUND, 3, "Magnesium Nitrate")); - self::register(new Item(Item::COMPOUND, 4, "Iron Sulphide")); - self::register(new Item(Item::COMPOUND, 5, "Lithium Hydride")); - self::register(new Item(Item::COMPOUND, 6, "Sodium Hydride")); - self::register(new Item(Item::COMPOUND, 7, "Calcium Bromide")); - self::register(new Item(Item::COMPOUND, 8, "Magnesium Oxide")); - self::register(new Item(Item::COMPOUND, 9, "Sodium Acetate")); - self::register(new Item(Item::COMPOUND, 10, "Luminol")); - self::register(new Item(Item::COMPOUND, 11, "Charcoal")); //??? maybe bug - self::register(new Item(Item::COMPOUND, 12, "Sugar")); //??? maybe bug - self::register(new Item(Item::COMPOUND, 13, "Aluminium Oxide")); - self::register(new Item(Item::COMPOUND, 14, "Boron Trioxide")); - self::register(new Item(Item::COMPOUND, 15, "Soap")); - self::register(new Item(Item::COMPOUND, 16, "Polyethylene")); - self::register(new Item(Item::COMPOUND, 17, "Rubbish")); - self::register(new Item(Item::COMPOUND, 18, "Magnesium Salts")); - self::register(new Item(Item::COMPOUND, 19, "Sulphate")); - self::register(new Item(Item::COMPOUND, 20, "Barium Sulphate")); - self::register(new Item(Item::COMPOUND, 21, "Potassium Chloride")); - self::register(new Item(Item::COMPOUND, 22, "Mercuric Chloride")); - self::register(new Item(Item::COMPOUND, 23, "Cerium Chloride")); - self::register(new Item(Item::COMPOUND, 24, "Tungsten Chloride")); - self::register(new Item(Item::COMPOUND, 25, "Calcium Chloride")); - self::register(new Item(Item::COMPOUND, 26, "Water")); //??? - self::register(new Item(Item::COMPOUND, 27, "Glue")); - self::register(new Item(Item::COMPOUND, 28, "Hypochlorite")); - self::register(new Item(Item::COMPOUND, 29, "Crude Oil")); - self::register(new Item(Item::COMPOUND, 30, "Latex")); - self::register(new Item(Item::COMPOUND, 31, "Potassium Iodide")); - self::register(new Item(Item::COMPOUND, 32, "Sodium Fluoride")); - self::register(new Item(Item::COMPOUND, 33, "Benzene")); - self::register(new Item(Item::COMPOUND, 34, "Ink")); - self::register(new Item(Item::COMPOUND, 35, "Hydrogen Peroxide")); - self::register(new Item(Item::COMPOUND, 36, "Ammonia")); - self::register(new Item(Item::COMPOUND, 37, "Sodium Hypochlorite")); - self::register(new Item(Item::DIAMOND, 0, "Diamond")); - self::register(new Item(Item::DRAGON_BREATH, 0, "Dragon's Breath")); - self::register(new Item(Item::DYE, 0, "Ink Sac")); - self::register(new Item(Item::DYE, 4, "Lapis Lazuli")); - self::register(new Item(Item::EMERALD, 0, "Emerald")); - self::register(new Item(Item::FEATHER, 0, "Feather")); - self::register(new Item(Item::FERMENTED_SPIDER_EYE, 0, "Fermented Spider Eye")); - self::register(new Item(Item::FLINT, 0, "Flint")); - self::register(new Item(Item::GHAST_TEAR, 0, "Ghast Tear")); - self::register(new Item(Item::GLISTERING_MELON, 0, "Glistering Melon")); - self::register(new Item(Item::GLOWSTONE_DUST, 0, "Glowstone Dust")); - self::register(new Item(Item::GOLD_INGOT, 0, "Gold Ingot")); - self::register(new Item(Item::GOLD_NUGGET, 0, "Gold Nugget")); - self::register(new Item(Item::GUNPOWDER, 0, "Gunpowder")); - self::register(new Item(Item::HEART_OF_THE_SEA, 0, "Heart of the Sea")); - self::register(new Item(Item::IRON_INGOT, 0, "Iron Ingot")); - self::register(new Item(Item::IRON_NUGGET, 0, "Iron Nugget")); - self::register(new Item(Item::LEATHER, 0, "Leather")); - self::register(new Item(Item::MAGMA_CREAM, 0, "Magma Cream")); - self::register(new Item(Item::NAUTILUS_SHELL, 0, "Nautilus Shell")); - self::register(new Item(Item::NETHER_BRICK, 0, "Nether Brick")); - self::register(new Item(Item::NETHER_QUARTZ, 0, "Nether Quartz")); - self::register(new Item(Item::NETHER_STAR, 0, "Nether Star")); - self::register(new Item(Item::PAPER, 0, "Paper")); - self::register(new Item(Item::PRISMARINE_CRYSTALS, 0, "Prismarine Crystals")); - self::register(new Item(Item::PRISMARINE_SHARD, 0, "Prismarine Shard")); - self::register(new Item(Item::RABBIT_FOOT, 0, "Rabbit's Foot")); - self::register(new Item(Item::RABBIT_HIDE, 0, "Rabbit Hide")); - self::register(new Item(Item::SHULKER_SHELL, 0, "Shulker Shell")); - self::register(new Item(Item::SLIME_BALL, 0, "Slimeball")); - self::register(new Item(Item::SUGAR, 0, "Sugar")); - self::register(new Item(Item::TURTLE_SHELL_PIECE, 0, "Scute")); - self::register(new Item(Item::WHEAT, 0, "Wheat")); - self::register(new ItemBlock(BlockLegacyIds::ACACIA_DOOR_BLOCK, 0, Item::ACACIA_DOOR)); - self::register(new ItemBlock(BlockLegacyIds::BIRCH_DOOR_BLOCK, 0, Item::BIRCH_DOOR)); - self::register(new ItemBlock(BlockLegacyIds::BREWING_STAND_BLOCK, 0, Item::BREWING_STAND)); - self::register(new ItemBlock(BlockLegacyIds::CAKE_BLOCK, 0, Item::CAKE)); - self::register(new ItemBlock(BlockLegacyIds::CAULDRON_BLOCK, 0, Item::CAULDRON)); - self::register(new ItemBlock(BlockLegacyIds::COMPARATOR_BLOCK, 0, Item::COMPARATOR)); - self::register(new ItemBlock(BlockLegacyIds::DARK_OAK_DOOR_BLOCK, 0, Item::DARK_OAK_DOOR)); - self::register(new ItemBlock(BlockLegacyIds::FLOWER_POT_BLOCK, 0, Item::FLOWER_POT)); - self::register(new ItemBlock(BlockLegacyIds::HOPPER_BLOCK, 0, Item::HOPPER)); - self::register(new ItemBlock(BlockLegacyIds::IRON_DOOR_BLOCK, 0, Item::IRON_DOOR)); - self::register(new ItemBlock(BlockLegacyIds::ITEM_FRAME_BLOCK, 0, Item::ITEM_FRAME)); - self::register(new ItemBlock(BlockLegacyIds::JUNGLE_DOOR_BLOCK, 0, Item::JUNGLE_DOOR)); - self::register(new ItemBlock(BlockLegacyIds::NETHER_WART_PLANT, 0, Item::NETHER_WART)); - self::register(new ItemBlock(BlockLegacyIds::OAK_DOOR_BLOCK, 0, Item::OAK_DOOR)); - self::register(new ItemBlock(BlockLegacyIds::REPEATER_BLOCK, 0, Item::REPEATER)); - self::register(new ItemBlock(BlockLegacyIds::SPRUCE_DOOR_BLOCK, 0, Item::SPRUCE_DOOR)); - self::register(new ItemBlock(BlockLegacyIds::SUGARCANE_BLOCK, 0, Item::SUGARCANE)); - self::register(new Leggings(Item::CHAIN_LEGGINGS, 0, "Chainmail Leggings", new ArmorTypeInfo(4, 226))); - self::register(new Leggings(Item::DIAMOND_LEGGINGS, 0, "Diamond Leggings", new ArmorTypeInfo(6, 496))); - self::register(new Leggings(Item::GOLDEN_LEGGINGS, 0, "Golden Leggings", new ArmorTypeInfo(3, 106))); - self::register(new Leggings(Item::IRON_LEGGINGS, 0, "Iron Leggings", new ArmorTypeInfo(5, 226))); - self::register(new Leggings(Item::LEATHER_LEGGINGS, 0, "Leather Pants", new ArmorTypeInfo(2, 76))); + self::register(new Apple(ItemIds::APPLE, 0, "Apple")); + self::register(new Arrow(ItemIds::ARROW, 0, "Arrow")); + self::register(new Axe(ItemIds::DIAMOND_AXE, "Diamond Axe", ToolTier::DIAMOND())); + self::register(new Axe(ItemIds::GOLDEN_AXE, "Golden Axe", ToolTier::GOLD())); + self::register(new Axe(ItemIds::IRON_AXE, "Iron Axe", ToolTier::IRON())); + self::register(new Axe(ItemIds::STONE_AXE, "Stone Axe", ToolTier::STONE())); + self::register(new Axe(ItemIds::WOODEN_AXE, "Wooden Axe", ToolTier::WOOD())); + self::register(new BakedPotato(ItemIds::BAKED_POTATO, 0, "Baked Potato")); + self::register(new Beetroot(ItemIds::BEETROOT, 0, "Beetroot")); + self::register(new BeetrootSeeds(ItemIds::BEETROOT_SEEDS, 0, "Beetroot Seeds")); + self::register(new BeetrootSoup(ItemIds::BEETROOT_SOUP, 0, "Beetroot Soup")); + self::register(new BlazeRod(ItemIds::BLAZE_ROD, 0, "Blaze Rod")); + self::register(new Book(ItemIds::BOOK, 0, "Book")); + self::register(new Boots(ItemIds::CHAIN_BOOTS, 0, "Chainmail Boots", new ArmorTypeInfo(1, 196))); + self::register(new Boots(ItemIds::DIAMOND_BOOTS, 0, "Diamond Boots", new ArmorTypeInfo(3, 430))); + self::register(new Boots(ItemIds::GOLDEN_BOOTS, 0, "Golden Boots", new ArmorTypeInfo(1, 92))); + self::register(new Boots(ItemIds::IRON_BOOTS, 0, "Iron Boots", new ArmorTypeInfo(2, 196))); + self::register(new Boots(ItemIds::LEATHER_BOOTS, 0, "Leather Boots", new ArmorTypeInfo(1, 66))); + self::register(new Bow(ItemIds::BOW, 0, "Bow")); + self::register(new Bowl(ItemIds::BOWL, 0, "Bowl")); + self::register(new Bread(ItemIds::BREAD, 0, "Bread")); + self::register(new Bucket(ItemIds::BUCKET, 0, "Bucket")); + self::register(new Carrot(ItemIds::CARROT, 0, "Carrot")); + self::register(new Chestplate(ItemIds::CHAIN_CHESTPLATE, 0, "Chainmail Chestplate", new ArmorTypeInfo(5, 241))); + self::register(new Chestplate(ItemIds::DIAMOND_CHESTPLATE, 0, "Diamond Chestplate", new ArmorTypeInfo(8, 529))); + self::register(new Chestplate(ItemIds::GOLDEN_CHESTPLATE, 0, "Golden Chestplate", new ArmorTypeInfo(5, 113))); + self::register(new Chestplate(ItemIds::IRON_CHESTPLATE, 0, "Iron Chestplate", new ArmorTypeInfo(6, 241))); + self::register(new Chestplate(ItemIds::LEATHER_CHESTPLATE, 0, "Leather Tunic", new ArmorTypeInfo(3, 81))); + self::register(new ChorusFruit(ItemIds::CHORUS_FRUIT, 0, "Chorus Fruit")); + self::register(new Clock(ItemIds::CLOCK, 0, "Clock")); + self::register(new Clownfish(ItemIds::CLOWNFISH, 0, "Clownfish")); + self::register(new Coal(ItemIds::COAL, 0, "Coal")); + self::register(new Coal(ItemIds::COAL, 1, "Charcoal")); + self::register(new CocoaBeans(ItemIds::DYE, 3, "Cocoa Beans")); + self::register(new Compass(ItemIds::COMPASS, 0, "Compass")); + self::register(new CookedChicken(ItemIds::COOKED_CHICKEN, 0, "Cooked Chicken")); + self::register(new CookedFish(ItemIds::COOKED_FISH, 0, "Cooked Fish")); + self::register(new CookedMutton(ItemIds::COOKED_MUTTON, 0, "Cooked Mutton")); + self::register(new CookedPorkchop(ItemIds::COOKED_PORKCHOP, 0, "Cooked Porkchop")); + self::register(new CookedRabbit(ItemIds::COOKED_RABBIT, 0, "Cooked Rabbit")); + self::register(new CookedSalmon(ItemIds::COOKED_SALMON, 0, "Cooked Salmon")); + self::register(new Cookie(ItemIds::COOKIE, 0, "Cookie")); + self::register(new DriedKelp(ItemIds::DRIED_KELP, 0, "Dried Kelp")); + self::register(new Egg(ItemIds::EGG, 0, "Egg")); + self::register(new EnderPearl(ItemIds::ENDER_PEARL, 0, "Ender Pearl")); + self::register(new ExperienceBottle(ItemIds::EXPERIENCE_BOTTLE, 0, "Bottle o' Enchanting")); + self::register(new Fertilizer(ItemIds::DYE, 15, "Bone Meal")); + self::register(new FishingRod(ItemIds::FISHING_ROD, 0, "Fishing Rod")); + self::register(new FlintSteel(ItemIds::FLINT_STEEL, 0, "Flint and Steel")); + self::register(new GlassBottle(ItemIds::GLASS_BOTTLE, 0, "Glass Bottle")); + self::register(new GoldenApple(ItemIds::GOLDEN_APPLE, 0, "Golden Apple")); + self::register(new GoldenAppleEnchanted(ItemIds::ENCHANTED_GOLDEN_APPLE, 0, "Enchanted Golden Apple")); + self::register(new GoldenCarrot(ItemIds::GOLDEN_CARROT, 0, "Golden Carrot")); + self::register(new Helmet(ItemIds::CHAIN_HELMET, 0, "Chainmail Helmet", new ArmorTypeInfo(2, 166))); + self::register(new Helmet(ItemIds::DIAMOND_HELMET, 0, "Diamond Helmet", new ArmorTypeInfo(3, 364))); + self::register(new Helmet(ItemIds::GOLDEN_HELMET, 0, "Golden Helmet", new ArmorTypeInfo(2, 78))); + self::register(new Helmet(ItemIds::IRON_HELMET, 0, "Iron Helmet", new ArmorTypeInfo(2, 166))); + self::register(new Helmet(ItemIds::LEATHER_HELMET, 0, "Leather Cap", new ArmorTypeInfo(1, 56))); + self::register(new Hoe(ItemIds::DIAMOND_HOE, "Diamond Hoe", ToolTier::DIAMOND())); + self::register(new Hoe(ItemIds::GOLDEN_HOE, "Golden Hoe", ToolTier::GOLD())); + self::register(new Hoe(ItemIds::IRON_HOE, "Iron Hoe", ToolTier::IRON())); + self::register(new Hoe(ItemIds::STONE_HOE, "Stone Hoe", ToolTier::STONE())); + self::register(new Hoe(ItemIds::WOODEN_HOE, "Wooden Hoe", ToolTier::WOOD())); + self::register(new Item(ItemIds::BLAZE_POWDER, 0, "Blaze Powder")); + self::register(new Item(ItemIds::BLEACH, 0, "Bleach")); //EDU + self::register(new Item(ItemIds::BONE, 0, "Bone")); + self::register(new Item(ItemIds::BRICK, 0, "Brick")); + self::register(new Item(ItemIds::CHORUS_FRUIT_POPPED, 0, "Popped Chorus Fruit")); + self::register(new Item(ItemIds::CLAY_BALL, 0, "Clay")); + self::register(new Item(ItemIds::COMPOUND, 0, "Salt")); + self::register(new Item(ItemIds::COMPOUND, 1, "Sodium Oxide")); + self::register(new Item(ItemIds::COMPOUND, 2, "Sodium Hydroxide")); + self::register(new Item(ItemIds::COMPOUND, 3, "Magnesium Nitrate")); + self::register(new Item(ItemIds::COMPOUND, 4, "Iron Sulphide")); + self::register(new Item(ItemIds::COMPOUND, 5, "Lithium Hydride")); + self::register(new Item(ItemIds::COMPOUND, 6, "Sodium Hydride")); + self::register(new Item(ItemIds::COMPOUND, 7, "Calcium Bromide")); + self::register(new Item(ItemIds::COMPOUND, 8, "Magnesium Oxide")); + self::register(new Item(ItemIds::COMPOUND, 9, "Sodium Acetate")); + self::register(new Item(ItemIds::COMPOUND, 10, "Luminol")); + self::register(new Item(ItemIds::COMPOUND, 11, "Charcoal")); //??? maybe bug + self::register(new Item(ItemIds::COMPOUND, 12, "Sugar")); //??? maybe bug + self::register(new Item(ItemIds::COMPOUND, 13, "Aluminium Oxide")); + self::register(new Item(ItemIds::COMPOUND, 14, "Boron Trioxide")); + self::register(new Item(ItemIds::COMPOUND, 15, "Soap")); + self::register(new Item(ItemIds::COMPOUND, 16, "Polyethylene")); + self::register(new Item(ItemIds::COMPOUND, 17, "Rubbish")); + self::register(new Item(ItemIds::COMPOUND, 18, "Magnesium Salts")); + self::register(new Item(ItemIds::COMPOUND, 19, "Sulphate")); + self::register(new Item(ItemIds::COMPOUND, 20, "Barium Sulphate")); + self::register(new Item(ItemIds::COMPOUND, 21, "Potassium Chloride")); + self::register(new Item(ItemIds::COMPOUND, 22, "Mercuric Chloride")); + self::register(new Item(ItemIds::COMPOUND, 23, "Cerium Chloride")); + self::register(new Item(ItemIds::COMPOUND, 24, "Tungsten Chloride")); + self::register(new Item(ItemIds::COMPOUND, 25, "Calcium Chloride")); + self::register(new Item(ItemIds::COMPOUND, 26, "Water")); //??? + self::register(new Item(ItemIds::COMPOUND, 27, "Glue")); + self::register(new Item(ItemIds::COMPOUND, 28, "Hypochlorite")); + self::register(new Item(ItemIds::COMPOUND, 29, "Crude Oil")); + self::register(new Item(ItemIds::COMPOUND, 30, "Latex")); + self::register(new Item(ItemIds::COMPOUND, 31, "Potassium Iodide")); + self::register(new Item(ItemIds::COMPOUND, 32, "Sodium Fluoride")); + self::register(new Item(ItemIds::COMPOUND, 33, "Benzene")); + self::register(new Item(ItemIds::COMPOUND, 34, "Ink")); + self::register(new Item(ItemIds::COMPOUND, 35, "Hydrogen Peroxide")); + self::register(new Item(ItemIds::COMPOUND, 36, "Ammonia")); + self::register(new Item(ItemIds::COMPOUND, 37, "Sodium Hypochlorite")); + self::register(new Item(ItemIds::DIAMOND, 0, "Diamond")); + self::register(new Item(ItemIds::DRAGON_BREATH, 0, "Dragon's Breath")); + self::register(new Item(ItemIds::DYE, 0, "Ink Sac")); + self::register(new Item(ItemIds::DYE, 4, "Lapis Lazuli")); + self::register(new Item(ItemIds::EMERALD, 0, "Emerald")); + self::register(new Item(ItemIds::FEATHER, 0, "Feather")); + self::register(new Item(ItemIds::FERMENTED_SPIDER_EYE, 0, "Fermented Spider Eye")); + self::register(new Item(ItemIds::FLINT, 0, "Flint")); + self::register(new Item(ItemIds::GHAST_TEAR, 0, "Ghast Tear")); + self::register(new Item(ItemIds::GLISTERING_MELON, 0, "Glistering Melon")); + self::register(new Item(ItemIds::GLOWSTONE_DUST, 0, "Glowstone Dust")); + self::register(new Item(ItemIds::GOLD_INGOT, 0, "Gold Ingot")); + self::register(new Item(ItemIds::GOLD_NUGGET, 0, "Gold Nugget")); + self::register(new Item(ItemIds::GUNPOWDER, 0, "Gunpowder")); + self::register(new Item(ItemIds::HEART_OF_THE_SEA, 0, "Heart of the Sea")); + self::register(new Item(ItemIds::IRON_INGOT, 0, "Iron Ingot")); + self::register(new Item(ItemIds::IRON_NUGGET, 0, "Iron Nugget")); + self::register(new Item(ItemIds::LEATHER, 0, "Leather")); + self::register(new Item(ItemIds::MAGMA_CREAM, 0, "Magma Cream")); + self::register(new Item(ItemIds::NAUTILUS_SHELL, 0, "Nautilus Shell")); + self::register(new Item(ItemIds::NETHER_BRICK, 0, "Nether Brick")); + self::register(new Item(ItemIds::NETHER_QUARTZ, 0, "Nether Quartz")); + self::register(new Item(ItemIds::NETHER_STAR, 0, "Nether Star")); + self::register(new Item(ItemIds::PAPER, 0, "Paper")); + self::register(new Item(ItemIds::PRISMARINE_CRYSTALS, 0, "Prismarine Crystals")); + self::register(new Item(ItemIds::PRISMARINE_SHARD, 0, "Prismarine Shard")); + self::register(new Item(ItemIds::RABBIT_FOOT, 0, "Rabbit's Foot")); + self::register(new Item(ItemIds::RABBIT_HIDE, 0, "Rabbit Hide")); + self::register(new Item(ItemIds::SHULKER_SHELL, 0, "Shulker Shell")); + self::register(new Item(ItemIds::SLIME_BALL, 0, "Slimeball")); + self::register(new Item(ItemIds::SUGAR, 0, "Sugar")); + self::register(new Item(ItemIds::TURTLE_SHELL_PIECE, 0, "Scute")); + self::register(new Item(ItemIds::WHEAT, 0, "Wheat")); + self::register(new ItemBlock(BlockLegacyIds::ACACIA_DOOR_BLOCK, 0, ItemIds::ACACIA_DOOR)); + self::register(new ItemBlock(BlockLegacyIds::BIRCH_DOOR_BLOCK, 0, ItemIds::BIRCH_DOOR)); + self::register(new ItemBlock(BlockLegacyIds::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND)); + self::register(new ItemBlock(BlockLegacyIds::CAKE_BLOCK, 0, ItemIds::CAKE)); + self::register(new ItemBlock(BlockLegacyIds::CAULDRON_BLOCK, 0, ItemIds::CAULDRON)); + self::register(new ItemBlock(BlockLegacyIds::COMPARATOR_BLOCK, 0, ItemIds::COMPARATOR)); + self::register(new ItemBlock(BlockLegacyIds::DARK_OAK_DOOR_BLOCK, 0, ItemIds::DARK_OAK_DOOR)); + self::register(new ItemBlock(BlockLegacyIds::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT)); + self::register(new ItemBlock(BlockLegacyIds::HOPPER_BLOCK, 0, ItemIds::HOPPER)); + self::register(new ItemBlock(BlockLegacyIds::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR)); + self::register(new ItemBlock(BlockLegacyIds::ITEM_FRAME_BLOCK, 0, ItemIds::ITEM_FRAME)); + self::register(new ItemBlock(BlockLegacyIds::JUNGLE_DOOR_BLOCK, 0, ItemIds::JUNGLE_DOOR)); + self::register(new ItemBlock(BlockLegacyIds::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART)); + self::register(new ItemBlock(BlockLegacyIds::OAK_DOOR_BLOCK, 0, ItemIds::OAK_DOOR)); + self::register(new ItemBlock(BlockLegacyIds::REPEATER_BLOCK, 0, ItemIds::REPEATER)); + self::register(new ItemBlock(BlockLegacyIds::SPRUCE_DOOR_BLOCK, 0, ItemIds::SPRUCE_DOOR)); + self::register(new ItemBlock(BlockLegacyIds::SUGARCANE_BLOCK, 0, ItemIds::SUGARCANE)); + self::register(new Leggings(ItemIds::CHAIN_LEGGINGS, 0, "Chainmail Leggings", new ArmorTypeInfo(4, 226))); + self::register(new Leggings(ItemIds::DIAMOND_LEGGINGS, 0, "Diamond Leggings", new ArmorTypeInfo(6, 496))); + self::register(new Leggings(ItemIds::GOLDEN_LEGGINGS, 0, "Golden Leggings", new ArmorTypeInfo(3, 106))); + self::register(new Leggings(ItemIds::IRON_LEGGINGS, 0, "Iron Leggings", new ArmorTypeInfo(5, 226))); + self::register(new Leggings(ItemIds::LEATHER_LEGGINGS, 0, "Leather Pants", new ArmorTypeInfo(2, 76))); //TODO: fix metadata for buckets with still liquid in them //the meta values are intentionally hardcoded because block IDs will change in the future - self::register(new LiquidBucket(Item::BUCKET, 8, "Water Bucket", VanillaBlocks::WATER())); - self::register(new LiquidBucket(Item::BUCKET, 10, "Lava Bucket", VanillaBlocks::LAVA())); - self::register(new Melon(Item::MELON, 0, "Melon")); - self::register(new MelonSeeds(Item::MELON_SEEDS, 0, "Melon Seeds")); - self::register(new MilkBucket(Item::BUCKET, 1, "Milk Bucket")); - self::register(new Minecart(Item::MINECART, 0, "Minecart")); - self::register(new MushroomStew(Item::MUSHROOM_STEW, 0, "Mushroom Stew")); - self::register(new PaintingItem(Item::PAINTING, 0, "Painting")); - self::register(new Pickaxe(Item::DIAMOND_PICKAXE, "Diamond Pickaxe", ToolTier::DIAMOND())); - self::register(new Pickaxe(Item::GOLDEN_PICKAXE, "Golden Pickaxe", ToolTier::GOLD())); - self::register(new Pickaxe(Item::IRON_PICKAXE, "Iron Pickaxe", ToolTier::IRON())); - self::register(new Pickaxe(Item::STONE_PICKAXE, "Stone Pickaxe", ToolTier::STONE())); - self::register(new Pickaxe(Item::WOODEN_PICKAXE, "Wooden Pickaxe", ToolTier::WOOD())); - self::register(new PoisonousPotato(Item::POISONOUS_POTATO, 0, "Poisonous Potato")); - self::register(new Potato(Item::POTATO, 0, "Potato")); - self::register(new Pufferfish(Item::PUFFERFISH, 0, "Pufferfish")); - self::register(new PumpkinPie(Item::PUMPKIN_PIE, 0, "Pumpkin Pie")); - self::register(new PumpkinSeeds(Item::PUMPKIN_SEEDS, 0, "Pumpkin Seeds")); - self::register(new RabbitStew(Item::RABBIT_STEW, 0, "Rabbit Stew")); - self::register(new RawBeef(Item::RAW_BEEF, 0, "Raw Beef")); - self::register(new RawChicken(Item::RAW_CHICKEN, 0, "Raw Chicken")); - self::register(new RawFish(Item::RAW_FISH, 0, "Raw Fish")); - self::register(new RawMutton(Item::RAW_MUTTON, 0, "Raw Mutton")); - self::register(new RawPorkchop(Item::RAW_PORKCHOP, 0, "Raw Porkchop")); - self::register(new RawRabbit(Item::RAW_RABBIT, 0, "Raw Rabbit")); - self::register(new RawSalmon(Item::RAW_SALMON, 0, "Raw Salmon")); - self::register(new Redstone(Item::REDSTONE, 0, "Redstone")); - self::register(new RottenFlesh(Item::ROTTEN_FLESH, 0, "Rotten Flesh")); - self::register(new Shears(Item::SHEARS, 0, "Shears")); - self::register(new Shovel(Item::DIAMOND_SHOVEL, "Diamond Shovel", ToolTier::DIAMOND())); - self::register(new Shovel(Item::GOLDEN_SHOVEL, "Golden Shovel", ToolTier::GOLD())); - self::register(new Shovel(Item::IRON_SHOVEL, "Iron Shovel", ToolTier::IRON())); - self::register(new Shovel(Item::STONE_SHOVEL, "Stone Shovel", ToolTier::STONE())); - self::register(new Shovel(Item::WOODEN_SHOVEL, "Wooden Shovel", ToolTier::WOOD())); - self::register(new Sign(BlockLegacyIds::STANDING_SIGN, 0, Item::SIGN)); - self::register(new Sign(BlockLegacyIds::SPRUCE_STANDING_SIGN, 0, Item::SPRUCE_SIGN)); - self::register(new Sign(BlockLegacyIds::BIRCH_STANDING_SIGN, 0, Item::BIRCH_SIGN)); - self::register(new Sign(BlockLegacyIds::JUNGLE_STANDING_SIGN, 0, Item::JUNGLE_SIGN)); - self::register(new Sign(BlockLegacyIds::ACACIA_STANDING_SIGN, 0, Item::ACACIA_SIGN)); - self::register(new Sign(BlockLegacyIds::DARKOAK_STANDING_SIGN, 0, Item::DARKOAK_SIGN)); - self::register(new Snowball(Item::SNOWBALL, 0, "Snowball")); - self::register(new SpiderEye(Item::SPIDER_EYE, 0, "Spider Eye")); - self::register(new Steak(Item::STEAK, 0, "Steak")); - self::register(new Stick(Item::STICK, 0, "Stick")); - self::register(new StringItem(Item::STRING, 0, "String")); - self::register(new Sword(Item::DIAMOND_SWORD, "Diamond Sword", ToolTier::DIAMOND())); - self::register(new Sword(Item::GOLDEN_SWORD, "Golden Sword", ToolTier::GOLD())); - self::register(new Sword(Item::IRON_SWORD, "Iron Sword", ToolTier::IRON())); - self::register(new Sword(Item::STONE_SWORD, "Stone Sword", ToolTier::STONE())); - self::register(new Sword(Item::WOODEN_SWORD, "Wooden Sword", ToolTier::WOOD())); - self::register(new Totem(Item::TOTEM, 0, "Totem of Undying")); - self::register(new WheatSeeds(Item::WHEAT_SEEDS, 0, "Wheat Seeds")); - self::register(new WritableBook(Item::WRITABLE_BOOK, 0, "Book & Quill")); - self::register(new WrittenBook(Item::WRITTEN_BOOK, 0, "Written Book")); + self::register(new LiquidBucket(ItemIds::BUCKET, 8, "Water Bucket", VanillaBlocks::WATER())); + self::register(new LiquidBucket(ItemIds::BUCKET, 10, "Lava Bucket", VanillaBlocks::LAVA())); + self::register(new Melon(ItemIds::MELON, 0, "Melon")); + self::register(new MelonSeeds(ItemIds::MELON_SEEDS, 0, "Melon Seeds")); + self::register(new MilkBucket(ItemIds::BUCKET, 1, "Milk Bucket")); + self::register(new Minecart(ItemIds::MINECART, 0, "Minecart")); + self::register(new MushroomStew(ItemIds::MUSHROOM_STEW, 0, "Mushroom Stew")); + self::register(new PaintingItem(ItemIds::PAINTING, 0, "Painting")); + self::register(new Pickaxe(ItemIds::DIAMOND_PICKAXE, "Diamond Pickaxe", ToolTier::DIAMOND())); + self::register(new Pickaxe(ItemIds::GOLDEN_PICKAXE, "Golden Pickaxe", ToolTier::GOLD())); + self::register(new Pickaxe(ItemIds::IRON_PICKAXE, "Iron Pickaxe", ToolTier::IRON())); + self::register(new Pickaxe(ItemIds::STONE_PICKAXE, "Stone Pickaxe", ToolTier::STONE())); + self::register(new Pickaxe(ItemIds::WOODEN_PICKAXE, "Wooden Pickaxe", ToolTier::WOOD())); + self::register(new PoisonousPotato(ItemIds::POISONOUS_POTATO, 0, "Poisonous Potato")); + self::register(new Potato(ItemIds::POTATO, 0, "Potato")); + self::register(new Pufferfish(ItemIds::PUFFERFISH, 0, "Pufferfish")); + self::register(new PumpkinPie(ItemIds::PUMPKIN_PIE, 0, "Pumpkin Pie")); + self::register(new PumpkinSeeds(ItemIds::PUMPKIN_SEEDS, 0, "Pumpkin Seeds")); + self::register(new RabbitStew(ItemIds::RABBIT_STEW, 0, "Rabbit Stew")); + self::register(new RawBeef(ItemIds::RAW_BEEF, 0, "Raw Beef")); + self::register(new RawChicken(ItemIds::RAW_CHICKEN, 0, "Raw Chicken")); + self::register(new RawFish(ItemIds::RAW_FISH, 0, "Raw Fish")); + self::register(new RawMutton(ItemIds::RAW_MUTTON, 0, "Raw Mutton")); + self::register(new RawPorkchop(ItemIds::RAW_PORKCHOP, 0, "Raw Porkchop")); + self::register(new RawRabbit(ItemIds::RAW_RABBIT, 0, "Raw Rabbit")); + self::register(new RawSalmon(ItemIds::RAW_SALMON, 0, "Raw Salmon")); + self::register(new Redstone(ItemIds::REDSTONE, 0, "Redstone")); + self::register(new RottenFlesh(ItemIds::ROTTEN_FLESH, 0, "Rotten Flesh")); + self::register(new Shears(ItemIds::SHEARS, 0, "Shears")); + self::register(new Shovel(ItemIds::DIAMOND_SHOVEL, "Diamond Shovel", ToolTier::DIAMOND())); + self::register(new Shovel(ItemIds::GOLDEN_SHOVEL, "Golden Shovel", ToolTier::GOLD())); + self::register(new Shovel(ItemIds::IRON_SHOVEL, "Iron Shovel", ToolTier::IRON())); + self::register(new Shovel(ItemIds::STONE_SHOVEL, "Stone Shovel", ToolTier::STONE())); + self::register(new Shovel(ItemIds::WOODEN_SHOVEL, "Wooden Shovel", ToolTier::WOOD())); + self::register(new Sign(BlockLegacyIds::STANDING_SIGN, 0, ItemIds::SIGN)); + self::register(new Sign(BlockLegacyIds::SPRUCE_STANDING_SIGN, 0, ItemIds::SPRUCE_SIGN)); + self::register(new Sign(BlockLegacyIds::BIRCH_STANDING_SIGN, 0, ItemIds::BIRCH_SIGN)); + self::register(new Sign(BlockLegacyIds::JUNGLE_STANDING_SIGN, 0, ItemIds::JUNGLE_SIGN)); + self::register(new Sign(BlockLegacyIds::ACACIA_STANDING_SIGN, 0, ItemIds::ACACIA_SIGN)); + self::register(new Sign(BlockLegacyIds::DARKOAK_STANDING_SIGN, 0, ItemIds::DARKOAK_SIGN)); + self::register(new Snowball(ItemIds::SNOWBALL, 0, "Snowball")); + self::register(new SpiderEye(ItemIds::SPIDER_EYE, 0, "Spider Eye")); + self::register(new Steak(ItemIds::STEAK, 0, "Steak")); + self::register(new Stick(ItemIds::STICK, 0, "Stick")); + self::register(new StringItem(ItemIds::STRING, 0, "String")); + self::register(new Sword(ItemIds::DIAMOND_SWORD, "Diamond Sword", ToolTier::DIAMOND())); + self::register(new Sword(ItemIds::GOLDEN_SWORD, "Golden Sword", ToolTier::GOLD())); + self::register(new Sword(ItemIds::IRON_SWORD, "Iron Sword", ToolTier::IRON())); + self::register(new Sword(ItemIds::STONE_SWORD, "Stone Sword", ToolTier::STONE())); + self::register(new Sword(ItemIds::WOODEN_SWORD, "Wooden Sword", ToolTier::WOOD())); + self::register(new Totem(ItemIds::TOTEM, 0, "Totem of Undying")); + self::register(new WheatSeeds(ItemIds::WHEAT_SEEDS, 0, "Wheat Seeds")); + self::register(new WritableBook(ItemIds::WRITABLE_BOOK, 0, "Book & Quill")); + self::register(new WrittenBook(ItemIds::WRITTEN_BOOK, 0, "Written Book")); foreach(SkullType::getAll() as $skullType){ - self::register(new Skull(Item::SKULL, $skullType->getMagicNumber(), $skullType->getDisplayName(), $skullType)); + self::register(new Skull(ItemIds::SKULL, $skullType->getMagicNumber(), $skullType->getDisplayName(), $skullType)); } /** @var int[]|\SplObjectStorage $dyeMap */ @@ -287,25 +287,25 @@ class ItemFactory{ foreach(DyeColor::getAll() as $color){ //TODO: use colour object directly //TODO: add interface to dye-colour objects - self::register(new Dye(Item::DYE, $dyeMap[$color] ?? $color->getInvertedMagicNumber(), $color->getDisplayName() . " Dye", $color)); - self::register(new Bed(Item::BED, $color->getMagicNumber(), $color->getDisplayName() . " Bed", $color)); - self::register(new Banner(Item::BANNER, $color->getInvertedMagicNumber(), $color->getDisplayName() . " Banner", $color)); + self::register(new Dye(ItemIds::DYE, $dyeMap[$color] ?? $color->getInvertedMagicNumber(), $color->getDisplayName() . " Dye", $color)); + self::register(new Bed(ItemIds::BED, $color->getMagicNumber(), $color->getDisplayName() . " Bed", $color)); + self::register(new Banner(ItemIds::BANNER, $color->getInvertedMagicNumber(), $color->getDisplayName() . " Banner", $color)); } foreach(Potion::ALL as $type){ - self::register(new Potion(Item::POTION, $type, "Potion")); - self::register(new SplashPotion(Item::SPLASH_POTION, $type, "Splash Potion")); + self::register(new Potion(ItemIds::POTION, $type, "Potion")); + self::register(new SplashPotion(ItemIds::SPLASH_POTION, $type, "Splash Potion")); } foreach(EntityFactory::getKnownTypes() as $className){ /** @var Living|string $className */ if(is_a($className, Living::class, true) and $className::NETWORK_ID !== -1){ - self::register(new SpawnEgg(Item::SPAWN_EGG, $className::NETWORK_ID, "Spawn Egg", $className)); + self::register(new SpawnEgg(ItemIds::SPAWN_EGG, $className::NETWORK_ID, "Spawn Egg", $className)); } } foreach(TreeType::getAll() as $type){ - self::register(new Boat(Item::BOAT, $type->getMagicNumber(), $type->getDisplayName() . " Boat", $type)); + self::register(new Boat(ItemIds::BOAT, $type->getMagicNumber(), $type->getDisplayName() . " Boat", $type)); } //region --- auto-generated TODOs --- diff --git a/tests/phpunit/inventory/BaseInventoryTest.php b/tests/phpunit/inventory/BaseInventoryTest.php index a00bbc1b13..282e46a453 100644 --- a/tests/phpunit/inventory/BaseInventoryTest.php +++ b/tests/phpunit/inventory/BaseInventoryTest.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\inventory; use PHPUnit\Framework\TestCase; -use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\item\ItemIds; class BaseInventoryTest extends TestCase{ @@ -37,8 +37,8 @@ class BaseInventoryTest extends TestCase{ $inv = new class(1) extends BaseInventory{ }; - $item1 = ItemFactory::get(Item::ARROW, 0, 1); - $item2 = ItemFactory::get(Item::ARROW, 0, 1)->setCustomName("TEST"); + $item1 = ItemFactory::get(ItemIds::ARROW, 0, 1); + $item2 = ItemFactory::get(ItemIds::ARROW, 0, 1)->setCustomName("TEST"); $inv->addItem(clone $item1); self::assertFalse($inv->canAddItem($item2), "Item WITHOUT userdata should not stack with item WITH userdata"); diff --git a/tests/phpunit/item/ItemFactoryTest.php b/tests/phpunit/item/ItemFactoryTest.php index 5676f7b837..1d96a34544 100644 --- a/tests/phpunit/item/ItemFactoryTest.php +++ b/tests/phpunit/item/ItemFactoryTest.php @@ -71,10 +71,10 @@ class ItemFactoryTest extends TestCase{ * Test that durable items are correctly created by the item factory */ public function testGetDurableItem() : void{ - self::assertInstanceOf(Sword::class, $i1 = ItemFactory::get(Item::WOODEN_SWORD)); + self::assertInstanceOf(Sword::class, $i1 = ItemFactory::get(ItemIds::WOODEN_SWORD)); /** @var Sword $i1 */ self::assertSame(0, $i1->getDamage()); - self::assertInstanceOf(Sword::class, $i2 = ItemFactory::get(Item::WOODEN_SWORD, 1)); + self::assertInstanceOf(Sword::class, $i2 = ItemFactory::get(ItemIds::WOODEN_SWORD, 1)); /** @var Sword $i2 */ self::assertSame(1, $i2->getDamage()); } diff --git a/tests/phpunit/item/ItemTest.php b/tests/phpunit/item/ItemTest.php index 8adc8c9a32..42c358ddf0 100644 --- a/tests/phpunit/item/ItemTest.php +++ b/tests/phpunit/item/ItemTest.php @@ -40,14 +40,14 @@ class ItemTest extends TestCase{ private $item; public function setUp() : void{ - $this->item = ItemFactory::get(Item::DIAMOND_SWORD); + $this->item = ItemFactory::get(ItemIds::DIAMOND_SWORD); } /** * Test for issue #1145 (items aren't considered equal after NBT serializing and deserializing */ public function testItemEquals() : void{ - $item = ItemFactory::get(Item::STONE)->setCustomName("HI"); + $item = ItemFactory::get(ItemIds::STONE)->setCustomName("HI"); $item2 = Item::nbtDeserialize($item->nbtSerialize()); self::assertTrue($item2->equals($item)); self::assertTrue($item->equals($item2)); @@ -57,7 +57,7 @@ class ItemTest extends TestCase{ * Test that same items without NBT are considered equal */ public function testItemEqualsNoNbt() : void{ - $item1 = ItemFactory::get(Item::DIAMOND_SWORD); + $item1 = ItemFactory::get(ItemIds::DIAMOND_SWORD); $item2 = clone $item1; self::assertTrue($item1->equals($item2)); } @@ -69,7 +69,7 @@ class ItemTest extends TestCase{ public function testItemPersistsDisplayProperties() : void{ $lore = ["Line A", "Line B"]; $name = "HI"; - $item = ItemFactory::get(Item::DIAMOND_SWORD); + $item = ItemFactory::get(ItemIds::DIAMOND_SWORD); $item->setCustomName($name); $item->setLore($lore); $item = Item::nbtDeserialize($item->nbtSerialize()); From 99bba66f13fb39be5805ebc5e0069d51cc0b9c05 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jul 2019 17:49:59 +0100 Subject: [PATCH 1116/3224] Block no longer implements BlockLegacyIds --- src/pocketmine/block/Block.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index f4882508ad..afe6e7917d 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -49,7 +49,7 @@ use function assert; use function dechex; use const PHP_INT_MAX; -class Block extends Position implements BlockLegacyIds{ +class Block extends Position{ /** @var BlockIdentifier */ protected $idInfo; From 14d79c205b4f8e62c78a1a22a3fba225d0fd5cdd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jul 2019 18:09:00 +0100 Subject: [PATCH 1117/3224] TranslationContainer: remove redundant setters i'd like to make this completely immutable, but there are some problems to solve first. --- src/pocketmine/lang/TranslationContainer.php | 33 ++++---------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/src/pocketmine/lang/TranslationContainer.php b/src/pocketmine/lang/TranslationContainer.php index 1c4f34d21f..59af23c1cf 100644 --- a/src/pocketmine/lang/TranslationContainer.php +++ b/src/pocketmine/lang/TranslationContainer.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\lang; -use function count; - class TranslationContainer extends TextContainer{ /** @var string[] $params */ @@ -37,7 +35,12 @@ class TranslationContainer extends TextContainer{ public function __construct(string $text, array $params = []){ parent::__construct($text); - $this->setParameters($params); + $i = 0; + foreach($params as $str){ + $this->params[$i] = (string) $str; + + ++$i; + } } /** @@ -55,28 +58,4 @@ class TranslationContainer extends TextContainer{ public function getParameter(int $i) : ?string{ return $this->params[$i] ?? null; } - - /** - * @param int $i - * @param string $str - */ - public function setParameter(int $i, string $str) : void{ - if($i < 0 or $i > count($this->params)){ //Intended, allow to set the last - throw new \InvalidArgumentException("Invalid index $i, have " . count($this->params)); - } - - $this->params[$i] = $str; - } - - /** - * @param string[] $params - */ - public function setParameters(array $params) : void{ - $i = 0; - foreach($params as $str){ - $this->params[$i] = (string) $str; - - ++$i; - } - } } From b4df1ac54784b609f0a0cf564e398f3fc778ddbe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jul 2019 18:47:18 +0100 Subject: [PATCH 1118/3224] Remove Achievement::broadcast(), remove cyclic dependency, inline code in Player --- src/pocketmine/player/Achievement.php | 26 -------------------------- src/pocketmine/player/Player.php | 7 ++++++- 2 files changed, 6 insertions(+), 27 deletions(-) diff --git a/src/pocketmine/player/Achievement.php b/src/pocketmine/player/Achievement.php index 76414095a5..5e51468202 100644 --- a/src/pocketmine/player/Achievement.php +++ b/src/pocketmine/player/Achievement.php @@ -23,10 +23,6 @@ declare(strict_types=1); namespace pocketmine\player; -use pocketmine\lang\TranslationContainer; -use pocketmine\Server; -use pocketmine\utils\TextFormat; - /** * Handles the achievement list and a bit more */ @@ -107,28 +103,6 @@ abstract class Achievement{ ]; - - /** - * @param Player $player - * @param string $achievementId - * - * @return bool - */ - public static function broadcast(Player $player, string $achievementId) : bool{ - if(isset(Achievement::$list[$achievementId])){ - $translation = new TranslationContainer("chat.type.achievement", [$player->getDisplayName(), TextFormat::GREEN . Achievement::$list[$achievementId]["name"] . TextFormat::RESET]); - if(Server::getInstance()->getConfigBool("announce-player-achievements", true)){ - Server::getInstance()->broadcastMessage($translation); - }else{ - $player->sendMessage($translation); - } - - return true; - } - - return false; - } - /** * @param string $achievementId * @param string $achievementName diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 8292fdbc88..2d2a22e17d 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -1150,7 +1150,12 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $ev->call(); if(!$ev->isCancelled()){ $this->achievements[$achievementId] = true; - Achievement::broadcast($this, $achievementId); + $translation = new TranslationContainer("chat.type.achievement", [$this->getDisplayName(), TextFormat::GREEN . Achievement::$list[$achievementId]["name"] . TextFormat::RESET]); + if($this->server->getConfigBool("announce-player-achievements", true)){ + $this->server->broadcastMessage($translation); + }else{ + $this->sendMessage($translation); + } return true; }else{ From 556beacdbfaf1c6cf92cb938a1c219ebd2284169 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jul 2019 18:59:06 +0100 Subject: [PATCH 1119/3224] make PlayerAchievementAwardedEvent less useless --- .../player/PlayerAchievementAwardedEvent.php | 44 +++++++++++++++++-- src/pocketmine/player/Player.php | 17 ++++--- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/src/pocketmine/event/player/PlayerAchievementAwardedEvent.php b/src/pocketmine/event/player/PlayerAchievementAwardedEvent.php index 7edcb70190..dfab7b9cef 100644 --- a/src/pocketmine/event/player/PlayerAchievementAwardedEvent.php +++ b/src/pocketmine/event/player/PlayerAchievementAwardedEvent.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\event\player; +use pocketmine\command\CommandSender; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; +use pocketmine\lang\TextContainer; use pocketmine\player\Player; /** @@ -35,14 +37,22 @@ class PlayerAchievementAwardedEvent extends PlayerEvent implements Cancellable{ /** @var string */ protected $achievement; + /** @var TextContainer|null */ + private $message; + /** @var CommandSender[] */ + private $broadcastRecipients; /** - * @param Player $player - * @param string $achievementId + * @param Player $player + * @param string $achievementId + * @param TextContainer|null $message + * @param CommandSender[] $messageRecipients */ - public function __construct(Player $player, string $achievementId){ + public function __construct(Player $player, string $achievementId, ?TextContainer $message, array $messageRecipients){ $this->player = $player; $this->achievement = $achievementId; + $this->message = $message; + $this->broadcastRecipients = $messageRecipients; } /** @@ -51,4 +61,32 @@ class PlayerAchievementAwardedEvent extends PlayerEvent implements Cancellable{ public function getAchievement() : string{ return $this->achievement; } + + /** + * @return TextContainer|null + */ + public function getMessage() : ?TextContainer{ + return $this->message; + } + + /** + * @param TextContainer|null $message + */ + public function setMessage(?TextContainer $message) : void{ + $this->message = $message; + } + + /** + * @return CommandSender[] + */ + public function getBroadcastRecipients() : array{ + return $this->broadcastRecipients; + } + + /** + * @param CommandSender[] $broadcastRecipients + */ + public function setBroadcastRecipients(array $broadcastRecipients) : void{ + $this->broadcastRecipients = $broadcastRecipients; + } } diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 2d2a22e17d..2de37e60b2 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -108,6 +108,7 @@ use pocketmine\world\particle\PunchBlockParticle; use pocketmine\world\Position; use pocketmine\world\World; use function abs; +use function array_filter; use function assert; use function ceil; use function count; @@ -1146,15 +1147,19 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return false; } } - $ev = new PlayerAchievementAwardedEvent($this, $achievementId); + $ev = new PlayerAchievementAwardedEvent( + $this, + $achievementId, + new TranslationContainer("chat.type.achievement", [$this->getDisplayName(), TextFormat::GREEN . Achievement::$list[$achievementId]["name"] . TextFormat::RESET]), + $this->server->getConfigBool("announce-player-achievements", true) ? array_filter(PermissionManager::getInstance()->getPermissionSubscriptions(Server::BROADCAST_CHANNEL_USERS), function($v){ + return $v instanceof CommandSender; + }) : [$this] + ); $ev->call(); if(!$ev->isCancelled()){ $this->achievements[$achievementId] = true; - $translation = new TranslationContainer("chat.type.achievement", [$this->getDisplayName(), TextFormat::GREEN . Achievement::$list[$achievementId]["name"] . TextFormat::RESET]); - if($this->server->getConfigBool("announce-player-achievements", true)){ - $this->server->broadcastMessage($translation); - }else{ - $this->sendMessage($translation); + if(($message = $ev->getMessage()) !== null){ + $this->server->broadcastMessage($message, $ev->getBroadcastRecipients()); } return true; From 47b120fa0e66cba2bb50a0fe2a326c1df5dae364 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jul 2019 19:11:36 +0100 Subject: [PATCH 1120/3224] crafting: avoid unnecessary recipe mutability --- src/pocketmine/crafting/FurnaceRecipe.php | 7 ---- src/pocketmine/crafting/ShapedRecipe.php | 23 +++-------- src/pocketmine/crafting/ShapelessRecipe.php | 46 ++++----------------- 3 files changed, 12 insertions(+), 64 deletions(-) diff --git a/src/pocketmine/crafting/FurnaceRecipe.php b/src/pocketmine/crafting/FurnaceRecipe.php index 2fa65a4771..cc1a4bf6ed 100644 --- a/src/pocketmine/crafting/FurnaceRecipe.php +++ b/src/pocketmine/crafting/FurnaceRecipe.php @@ -42,13 +42,6 @@ class FurnaceRecipe{ $this->ingredient = clone $ingredient; } - /** - * @param Item $item - */ - public function setInput(Item $item) : void{ - $this->ingredient = clone $item; - } - /** * @return Item */ diff --git a/src/pocketmine/crafting/ShapedRecipe.php b/src/pocketmine/crafting/ShapedRecipe.php index 6f48b3cfe1..9c6be8f49b 100644 --- a/src/pocketmine/crafting/ShapedRecipe.php +++ b/src/pocketmine/crafting/ShapedRecipe.php @@ -88,7 +88,11 @@ class ShapedRecipe implements CraftingRecipe{ $this->shape = $shape; foreach($ingredients as $char => $i){ - $this->setIngredient($char, $i); + if(strpos(implode($this->shape), $char) === false){ + throw new \InvalidArgumentException("Symbol '$char' does not appear in the recipe shape"); + } + + $this->ingredientList[$char] = clone $i; } $this->results = array_map(function(Item $item) : Item{ return clone $item; }, $results); @@ -118,23 +122,6 @@ class ShapedRecipe implements CraftingRecipe{ return $this->getResults(); } - /** - * @param string $key - * @param Item $item - * - * @return $this - * @throws \InvalidArgumentException - */ - public function setIngredient(string $key, Item $item){ - if(strpos(implode($this->shape), $key) === false){ - throw new \InvalidArgumentException("Symbol '$key' does not appear in the recipe shape"); - } - - $this->ingredientList[$key] = clone $item; - - return $this; - } - /** * @return Item[][] */ diff --git a/src/pocketmine/crafting/ShapelessRecipe.php b/src/pocketmine/crafting/ShapelessRecipe.php index 9cecfdf1fe..4bf7d2af07 100644 --- a/src/pocketmine/crafting/ShapelessRecipe.php +++ b/src/pocketmine/crafting/ShapelessRecipe.php @@ -40,7 +40,13 @@ class ShapelessRecipe implements CraftingRecipe{ public function __construct(array $ingredients, array $results){ foreach($ingredients as $item){ //Ensure they get split up properly - $this->addIngredient($item); + if(count($this->ingredients) + $item->getCount() > 9){ + throw new \InvalidArgumentException("Shapeless recipes cannot have more than 9 ingredients"); + } + + while($item->getCount() > 0){ + $this->ingredients[] = $item->pop(); + } } $this->results = array_map(function(Item $item) : Item{ return clone $item; }, $results); @@ -54,44 +60,6 @@ class ShapelessRecipe implements CraftingRecipe{ return $this->getResults(); } - /** - * @param Item $item - * - * @return ShapelessRecipe - * - * @throws \InvalidArgumentException - */ - public function addIngredient(Item $item) : ShapelessRecipe{ - if(count($this->ingredients) + $item->getCount() > 9){ - throw new \InvalidArgumentException("Shapeless recipes cannot have more than 9 ingredients"); - } - - while($item->getCount() > 0){ - $this->ingredients[] = $item->pop(); - } - - return $this; - } - - /** - * @param Item $item - * - * @return $this - */ - public function removeIngredient(Item $item){ - foreach($this->ingredients as $index => $ingredient){ - if($item->getCount() <= 0){ - break; - } - if($ingredient->equals($item, !$item->hasAnyDamageValue(), $item->hasNamedTag())){ - unset($this->ingredients[$index]); - $item->pop(); - } - } - - return $this; - } - /** * @return Item[] */ From 1e057394c09f58d747728ebb960fbf691d62f985 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jul 2019 19:19:04 +0100 Subject: [PATCH 1121/3224] Utils: added cloneCallback() and cloneObjectArray() to reduce list copying boilerplate --- src/pocketmine/block/Banner.php | 3 ++- src/pocketmine/block/VanillaBlocks.php | 4 ++-- src/pocketmine/crafting/ShapedRecipe.php | 6 +++--- src/pocketmine/crafting/ShapelessRecipe.php | 8 ++++---- src/pocketmine/item/VanillaItems.php | 4 ++-- src/pocketmine/utils/Utils.php | 10 ++++++++++ 6 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/pocketmine/block/Banner.php b/src/pocketmine/block/Banner.php index 89d28a2ec6..98dfb4b61b 100644 --- a/src/pocketmine/block/Banner.php +++ b/src/pocketmine/block/Banner.php @@ -36,6 +36,7 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; +use pocketmine\utils\Utils; use pocketmine\world\BlockTransaction; use function assert; use function floor; @@ -65,7 +66,7 @@ class Banner extends Transparent{ } public function __clone(){ - $this->patterns = $this->patterns->map(function(BannerPattern $pattern) : BannerPattern{ return clone $pattern; }); + $this->patterns = $this->patterns->map(Utils::cloneCallback()); } public function getId() : int{ diff --git a/src/pocketmine/block/VanillaBlocks.php b/src/pocketmine/block/VanillaBlocks.php index 8a2398167e..5423d458cb 100644 --- a/src/pocketmine/block/VanillaBlocks.php +++ b/src/pocketmine/block/VanillaBlocks.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\utils\RegistryTrait; -use function array_map; +use pocketmine\utils\Utils; use function assert; /** @@ -689,7 +689,7 @@ final class VanillaBlocks{ * @return Block[] */ public static function getAll() : array{ - return array_map(function(Block $member){ return clone $member; }, self::_registryGetAll()); + return Utils::cloneObjectArray(self::_registryGetAll()); } protected static function setup() : void{ diff --git a/src/pocketmine/crafting/ShapedRecipe.php b/src/pocketmine/crafting/ShapedRecipe.php index 9c6be8f49b..a4802f11db 100644 --- a/src/pocketmine/crafting/ShapedRecipe.php +++ b/src/pocketmine/crafting/ShapedRecipe.php @@ -25,7 +25,7 @@ namespace pocketmine\crafting; use pocketmine\item\Item; use pocketmine\item\ItemFactory; -use function array_map; +use pocketmine\utils\Utils; use function array_values; use function count; use function implode; @@ -95,7 +95,7 @@ class ShapedRecipe implements CraftingRecipe{ $this->ingredientList[$char] = clone $i; } - $this->results = array_map(function(Item $item) : Item{ return clone $item; }, $results); + $this->results = Utils::cloneObjectArray($results); } public function getWidth() : int{ @@ -110,7 +110,7 @@ class ShapedRecipe implements CraftingRecipe{ * @return Item[] */ public function getResults() : array{ - return array_map(function(Item $item) : Item{ return clone $item; }, $this->results); + return Utils::cloneObjectArray($this->results); } /** diff --git a/src/pocketmine/crafting/ShapelessRecipe.php b/src/pocketmine/crafting/ShapelessRecipe.php index 4bf7d2af07..dfc11eace6 100644 --- a/src/pocketmine/crafting/ShapelessRecipe.php +++ b/src/pocketmine/crafting/ShapelessRecipe.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\crafting; use pocketmine\item\Item; -use function array_map; +use pocketmine\utils\Utils; use function count; class ShapelessRecipe implements CraftingRecipe{ @@ -49,11 +49,11 @@ class ShapelessRecipe implements CraftingRecipe{ } } - $this->results = array_map(function(Item $item) : Item{ return clone $item; }, $results); + $this->results = Utils::cloneObjectArray($results); } public function getResults() : array{ - return array_map(function(Item $item) : Item{ return clone $item; }, $this->results); + return Utils::cloneObjectArray($this->results); } public function getResultsFor(CraftingGrid $grid) : array{ @@ -64,7 +64,7 @@ class ShapelessRecipe implements CraftingRecipe{ * @return Item[] */ public function getIngredientList() : array{ - return array_map(function(Item $item) : Item{ return clone $item; }, $this->ingredients); + return Utils::cloneObjectArray($this->ingredients); } /** diff --git a/src/pocketmine/item/VanillaItems.php b/src/pocketmine/item/VanillaItems.php index b1c0decda7..135a65c288 100644 --- a/src/pocketmine/item/VanillaItems.php +++ b/src/pocketmine/item/VanillaItems.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\utils\RegistryTrait; -use function array_map; +use pocketmine\utils\Utils; use function assert; /** @@ -317,7 +317,7 @@ final class VanillaItems{ * @return Item[] */ public static function getAll() : array{ - return array_map(function(Item $member){ return clone $member; }, self::_registryGetAll()); + return Utils::cloneObjectArray(self::_registryGetAll()); } protected static function setup() : void{ diff --git a/src/pocketmine/utils/Utils.php b/src/pocketmine/utils/Utils.php index 08e824fd25..14a94dd309 100644 --- a/src/pocketmine/utils/Utils.php +++ b/src/pocketmine/utils/Utils.php @@ -142,6 +142,16 @@ class Utils{ return $reflect->getName(); } + public static function cloneCallback() : \Closure{ + return static function(object $o){ + return clone $o; + }; + } + + public static function cloneObjectArray(array $array) : array{ + return array_map(self::cloneCallback(), $array); + } + /** * Gets this machine / server instance unique ID * Returns a hash, the first 32 characters (or 16 if raw) From 08a654760c6ae0a40d605cf752874609dc0ed74b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Jul 2019 15:19:17 +0100 Subject: [PATCH 1122/3224] Allow PlayerInfo to contain additional metadata --- .../mcpe/handler/LoginPacketHandler.php | 3 ++- src/pocketmine/player/PlayerInfo.php | 21 ++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/network/mcpe/handler/LoginPacketHandler.php b/src/pocketmine/network/mcpe/handler/LoginPacketHandler.php index 34d168ddb4..ebb04ee9c3 100644 --- a/src/pocketmine/network/mcpe/handler/LoginPacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/LoginPacketHandler.php @@ -92,7 +92,8 @@ class LoginPacketHandler extends PacketHandler{ $skin, $packet->clientData[LoginPacket::I_LANGUAGE_CODE], $packet->extraData[LoginPacket::I_XUID], - $packet->clientData[LoginPacket::I_CLIENT_RANDOM_ID] + $packet->clientData[LoginPacket::I_CLIENT_RANDOM_ID], + $packet->extraData )); $ev = new PlayerPreLoginEvent( diff --git a/src/pocketmine/player/PlayerInfo.php b/src/pocketmine/player/PlayerInfo.php index 423e784e19..a6cd03a98b 100644 --- a/src/pocketmine/player/PlayerInfo.php +++ b/src/pocketmine/player/PlayerInfo.php @@ -44,14 +44,26 @@ class PlayerInfo{ private $xuid; /** @var int */ private $clientId; + /** @var array */ + private $extraData; - public function __construct(string $username, UUID $uuid, Skin $skin, string $locale, string $xuid, int $clientId){ + /** + * @param string $username + * @param UUID $uuid + * @param Skin $skin + * @param string $locale + * @param string $xuid + * @param int $clientId + * @param array $extraData + */ + public function __construct(string $username, UUID $uuid, Skin $skin, string $locale, string $xuid, int $clientId, array $extraData = []){ $this->username = TextFormat::clean($username); $this->uuid = $uuid; $this->skin = $skin; $this->locale = $locale; $this->xuid = $xuid; $this->clientId = $clientId; + $this->extraData = $extraData; } /** @@ -95,4 +107,11 @@ class PlayerInfo{ public function getClientId() : int{ return $this->clientId; } + + /** + * @return array + */ + public function getExtraData() : array{ + return $this->extraData; + } } From e388ac9c8b133fbf0382ef56f6ab75f04249a670 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Jul 2019 17:48:09 +0100 Subject: [PATCH 1123/3224] implemented lantern --- src/pocketmine/block/BlockFactory.php | 2 +- src/pocketmine/block/BlockLegacyMetadata.php | 2 + src/pocketmine/block/Lantern.php | 80 ++++++++++++++++++++ src/pocketmine/block/VanillaBlocks.php | 2 + 4 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 src/pocketmine/block/Lantern.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index e67b2b6468..839e393457 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -224,6 +224,7 @@ class BlockFactory{ self::register(new Trapdoor(new BID(Ids::IRON_TRAPDOOR), "Iron Trapdoor", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0))); self::register(new ItemFrame(new BID(Ids::FRAME_BLOCK, 0, ItemIds::FRAME, TileItemFrame::class), "Item Frame")); self::register(new Ladder(new BID(Ids::LADDER), "Ladder")); + self::register(new Lantern(new BID(Ids::LANTERN), "Lantern", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); self::register(new Solid(new BID(Ids::LAPIS_BLOCK), "Lapis Lazuli Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); self::register(new LapisOre(new BID(Ids::LAPIS_ORE), "Lapis Lazuli Ore")); self::register(new Lava(new BIDFlattened(Ids::FLOWING_LAVA, Ids::STILL_LAVA), "Lava")); @@ -599,7 +600,6 @@ class BlockFactory{ //TODO: minecraft:jigsaw //TODO: minecraft:jukebox //TODO: minecraft:kelp - //TODO: minecraft:lantern //TODO: minecraft:lava_cauldron //TODO: minecraft:lectern //TODO: minecraft:lit_blast_furnace diff --git a/src/pocketmine/block/BlockLegacyMetadata.php b/src/pocketmine/block/BlockLegacyMetadata.php index 899e93554e..60a336c4da 100644 --- a/src/pocketmine/block/BlockLegacyMetadata.php +++ b/src/pocketmine/block/BlockLegacyMetadata.php @@ -95,6 +95,8 @@ interface BlockLegacyMetadata{ public const ITEM_FRAME_FLAG_HAS_MAP = 0x04; + public const LANTERN_FLAG_HANGING = 0x01; + public const LEAVES_FLAG_NO_DECAY = 0x04; public const LEAVES_FLAG_CHECK_DECAY = 0x08; diff --git a/src/pocketmine/block/Lantern.php b/src/pocketmine/block/Lantern.php new file mode 100644 index 0000000000..98ca830ee3 --- /dev/null +++ b/src/pocketmine/block/Lantern.php @@ -0,0 +1,80 @@ +hanging = ($stateMeta & BlockLegacyMetadata::LANTERN_FLAG_HANGING) !== 0; + } + + protected function writeStateToMeta() : int{ + return $this->hanging ? BlockLegacyMetadata::LANTERN_FLAG_HANGING : 0; + } + + public function getStateBitmask() : int{ + return 0b1; + } + + public function getLightLevel() : int{ + return 15; + } + + protected function recalculateBoundingBox() : ?AxisAlignedBB{ + return AxisAlignedBB::one() + ->trim(Facing::UP, $this->hanging ? 6 / 16 : 8 / 16) + ->trim(Facing::DOWN, $this->hanging ? 2 / 16 : 0) + ->squash(Facing::AXIS_X, 5 / 16) + ->squash(Facing::AXIS_Z, 5 / 16); + } + + protected function canAttachTo(Block $b) : bool{ + return !$b->isTransparent(); + } + + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if(!$this->canAttachTo($this->world->getBlock($blockReplace->up())) and !$this->canAttachTo($this->world->getBlock($blockReplace->down()))){ + return false; + } + + $this->hanging = ($face === Facing::DOWN or !$this->canAttachTo($this->world->getBlock($blockReplace->down()))); + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + + public function onNearbyBlockChange() : void{ + if(!$this->canAttachTo($this->world->getBlock($this->hanging ? $this->up() : $this->down()))){ + $this->world->useBreakOn($this); + } + } +} diff --git a/src/pocketmine/block/VanillaBlocks.php b/src/pocketmine/block/VanillaBlocks.php index 5423d458cb..d14c05149f 100644 --- a/src/pocketmine/block/VanillaBlocks.php +++ b/src/pocketmine/block/VanillaBlocks.php @@ -410,6 +410,7 @@ use function assert; * @method static WoodenTrapdoor JUNGLE_TRAPDOOR() * @method static Wood JUNGLE_WOOD() * @method static Ladder LADDER() + * @method static Lantern LANTERN() * @method static Solid LAPIS_LAZULI() * @method static LapisOre LAPIS_LAZULI_ORE() * @method static DoubleTallGrass LARGE_FERN() @@ -1071,6 +1072,7 @@ final class VanillaBlocks{ self::register("jungle_trapdoor", BlockFactory::get(403)); self::register("jungle_wood", BlockFactory::get(467, 3)); self::register("ladder", BlockFactory::get(65, 2)); + self::register("lantern", BlockFactory::get(463)); self::register("lapis_lazuli", BlockFactory::get(22)); self::register("lapis_lazuli_ore", BlockFactory::get(21)); self::register("large_fern", BlockFactory::get(175, 3)); From a9c6489e082e20b6576114eed951127f66a1eab5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 21 Jul 2019 13:11:59 +0100 Subject: [PATCH 1124/3224] updated consistency check for e388ac9c8b133fbf0382ef56f6ab75f04249a670 --- tests/phpunit/block/block_factory_consistency_check.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index ff32e629c2..c7cf034a7a 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From 6fdcb098918174410be662525d2fb86ed1daf0cd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 21 Jul 2019 18:52:33 +0100 Subject: [PATCH 1125/3224] fix PhpStorm's screwup with World->setBlock() doc comment it's not the first time i've seen it do this, and i still have no idea why it does this. --- src/pocketmine/world/World.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 54289f06fc..b4d7034b74 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -1446,6 +1446,7 @@ class World implements ChunkManager{ /** * Sets the block at the given Vector3 coordinates. + * @see World::setBlockAt() * * @param Vector3 $pos * @param Block $block @@ -1454,8 +1455,6 @@ class World implements ChunkManager{ * @return bool Whether the block has been updated or not * * @throws \InvalidArgumentException if the position is out of the world bounds - *@see World::setBlockAt() - * */ public function setBlock(Vector3 $pos, Block $block, bool $update = true) : bool{ return $this->setBlockAt((int) floor($pos->x), (int) floor($pos->y), (int) floor($pos->z), $block, $update); From 80d277f1b575db66435df31d45e93c20a8c88020 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 21 Jul 2019 18:55:22 +0100 Subject: [PATCH 1126/3224] removed return value of ChunkManager->setBlockAt() and World->setBlock() --- src/pocketmine/block/Block.php | 3 ++- src/pocketmine/block/Ice.php | 3 ++- src/pocketmine/world/ChunkManager.php | 4 ++-- src/pocketmine/world/SimpleChunkManager.php | 6 +++--- src/pocketmine/world/World.php | 13 +++---------- 5 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index afe6e7917d..b9d048afc9 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -268,7 +268,8 @@ class Block extends Position{ if(($t = $this->world->getTile($this)) !== null){ $t->onBlockDestroyed(); } - return $this->getWorld()->setBlock($this, VanillaBlocks::AIR()); + $this->getWorld()->setBlock($this, VanillaBlocks::AIR()); + return true; } /** diff --git a/src/pocketmine/block/Ice.php b/src/pocketmine/block/Ice.php index eccf9dee51..71429e0a13 100644 --- a/src/pocketmine/block/Ice.php +++ b/src/pocketmine/block/Ice.php @@ -43,7 +43,8 @@ class Ice extends Transparent{ public function onBreak(Item $item, ?Player $player = null) : bool{ if(($player === null or $player->isSurvival()) and !$item->hasEnchantment(Enchantment::SILK_TOUCH())){ - return $this->getWorld()->setBlock($this, VanillaBlocks::WATER()); + $this->getWorld()->setBlock($this, VanillaBlocks::WATER()); + return true; } return parent::onBreak($item, $player); } diff --git a/src/pocketmine/world/ChunkManager.php b/src/pocketmine/world/ChunkManager.php index 129cee286f..eeac6332f9 100644 --- a/src/pocketmine/world/ChunkManager.php +++ b/src/pocketmine/world/ChunkManager.php @@ -47,9 +47,9 @@ interface ChunkManager{ * @param int $z * @param Block $block * - * @return bool TODO: remove + * @throws \InvalidArgumentException */ - public function setBlockAt(int $x, int $y, int $z, Block $block) : bool; + public function setBlockAt(int $x, int $y, int $z, Block $block) : void; /** * @param int $chunkX diff --git a/src/pocketmine/world/SimpleChunkManager.php b/src/pocketmine/world/SimpleChunkManager.php index 8869f41899..6baaa51669 100644 --- a/src/pocketmine/world/SimpleChunkManager.php +++ b/src/pocketmine/world/SimpleChunkManager.php @@ -58,13 +58,13 @@ class SimpleChunkManager implements ChunkManager{ return VanillaBlocks::AIR(); } - public function setBlockAt(int $x, int $y, int $z, Block $block) : bool{ + public function setBlockAt(int $x, int $y, int $z, Block $block) : void{ if($this->terrainPointer->moveTo($x, $y, $z, true)){ $this->terrainPointer->currentSubChunk->setFullBlock($x & 0xf, $y & 0xf, $z & 0xf, $block->getFullId()); $this->terrainPointer->currentChunk->setChanged(true); - return true; + }else{ + throw new \InvalidArgumentException("Cannot set block at coordinates x=$x,y=$y,z=$z, terrain is not loaded or out of bounds"); } - return false; } /** diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index b4d7034b74..3f0a725003 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -1446,18 +1446,15 @@ class World implements ChunkManager{ /** * Sets the block at the given Vector3 coordinates. - * @see World::setBlockAt() * * @param Vector3 $pos * @param Block $block * @param bool $update * - * @return bool Whether the block has been updated or not - * * @throws \InvalidArgumentException if the position is out of the world bounds */ - public function setBlock(Vector3 $pos, Block $block, bool $update = true) : bool{ - return $this->setBlockAt((int) floor($pos->x), (int) floor($pos->y), (int) floor($pos->z), $block, $update); + public function setBlock(Vector3 $pos, Block $block, bool $update = true) : void{ + $this->setBlockAt((int) floor($pos->x), (int) floor($pos->y), (int) floor($pos->z), $block, $update); } /** @@ -1472,11 +1469,9 @@ class World implements ChunkManager{ * @param Block $block * @param bool $update * - * @return bool Whether the block has been updated or not - * * @throws \InvalidArgumentException if the position is out of the world bounds */ - public function setBlockAt(int $x, int $y, int $z, Block $block, bool $update = true) : bool{ + public function setBlockAt(int $x, int $y, int $z, Block $block, bool $update = true) : void{ if(!$this->isInWorld($x, $y, $z)){ throw new \InvalidArgumentException("Pos x=$x,y=$y,z=$z is outside of the world bounds"); } @@ -1511,8 +1506,6 @@ class World implements ChunkManager{ } $this->timings->setBlock->stopTiming(); - - return true; } /** From e95b9fa432d55674c6a28cc03ad11c2728c1ec45 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 22 Jul 2019 19:23:28 +0100 Subject: [PATCH 1127/3224] Block: use isSameType() in some places --- src/pocketmine/block/Cactus.php | 6 +++--- src/pocketmine/block/Sugarcane.php | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index d4ecc97814..1c768c830f 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -72,7 +72,7 @@ class Cactus extends Transparent{ public function onNearbyBlockChange() : void{ $down = $this->getSide(Facing::DOWN); - if($down->getId() !== BlockLegacyIds::SAND and $down->getId() !== BlockLegacyIds::CACTUS){ + if($down->getId() !== BlockLegacyIds::SAND and !$down->isSameType($this)){ $this->getWorld()->useBreakOn($this); }else{ foreach(Facing::HORIZONTAL as $side){ @@ -90,7 +90,7 @@ class Cactus extends Transparent{ } public function onRandomTick() : void{ - if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::CACTUS){ + if(!$this->getSide(Facing::DOWN)->isSameType($this)){ if($this->age === 15){ for($y = 1; $y < 3; ++$y){ $b = $this->getWorld()->getBlockAt($this->x, $this->y + $y, $this->z); @@ -116,7 +116,7 @@ class Cactus extends Transparent{ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); - if($down->getId() === BlockLegacyIds::SAND or $down->getId() === BlockLegacyIds::CACTUS){ + if($down->getId() === BlockLegacyIds::SAND or $down->isSameType($this)){ foreach(Facing::HORIZONTAL as $side){ if($this->getSide($side)->isSolid()){ return false; diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index 42fba2232a..ef30093656 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -55,7 +55,7 @@ class Sugarcane extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof Fertilizer){ - if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::SUGARCANE_BLOCK){ + if(!$this->getSide(Facing::DOWN)->isSameType($this)){ for($y = 1; $y < 3; ++$y){ $b = $this->getWorld()->getBlockAt($this->x, $this->y + $y, $this->z); if($b->getId() === BlockLegacyIds::AIR){ @@ -83,7 +83,7 @@ class Sugarcane extends Flowable{ public function onNearbyBlockChange() : void{ $down = $this->getSide(Facing::DOWN); - if($down->isTransparent() and $down->getId() !== BlockLegacyIds::SUGARCANE_BLOCK){ + if($down->isTransparent() and !$down->isSameType($this)){ $this->getWorld()->useBreakOn($this); } } @@ -93,7 +93,7 @@ class Sugarcane extends Flowable{ } public function onRandomTick() : void{ - if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::SUGARCANE_BLOCK){ + if(!$this->getSide(Facing::DOWN)->isSameType($this)){ if($this->age === 15){ for($y = 1; $y < 3; ++$y){ $b = $this->getWorld()->getBlockAt($this->x, $this->y + $y, $this->z); @@ -113,7 +113,7 @@ class Sugarcane extends Flowable{ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); - if($down->getId() === BlockLegacyIds::SUGARCANE_BLOCK){ + if($down->isSameType($this)){ return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); }elseif($down->getId() === BlockLegacyIds::GRASS or $down->getId() === BlockLegacyIds::DIRT or $down->getId() === BlockLegacyIds::SAND){ foreach(Facing::HORIZONTAL as $side){ From b5437445346fefb56ad77f2ed2b4f654bbbe23e3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 22 Jul 2019 19:56:01 +0100 Subject: [PATCH 1128/3224] Rename Solid -> Opaque the old naming was misleading, particularly in conjunction with isSolid(). --- src/pocketmine/block/Bedrock.php | 2 +- src/pocketmine/block/BlockFactory.php | 88 +++++++-------- src/pocketmine/block/BlueIce.php | 2 +- src/pocketmine/block/BoneBlock.php | 2 +- src/pocketmine/block/Bookshelf.php | 2 +- src/pocketmine/block/CarvedPumpkin.php | 2 +- src/pocketmine/block/Clay.php | 2 +- src/pocketmine/block/Coal.php | 2 +- src/pocketmine/block/CoalOre.php | 2 +- src/pocketmine/block/Concrete.php | 2 +- src/pocketmine/block/ConcretePowder.php | 2 +- src/pocketmine/block/CraftingTable.php | 2 +- src/pocketmine/block/DiamondOre.php | 2 +- src/pocketmine/block/Dirt.php | 2 +- src/pocketmine/block/DriedKelp.php | 2 +- src/pocketmine/block/Element.php | 2 +- src/pocketmine/block/EmeraldOre.php | 2 +- src/pocketmine/block/EndPortalFrame.php | 2 +- src/pocketmine/block/Furnace.php | 2 +- src/pocketmine/block/GlazedTerracotta.php | 2 +- src/pocketmine/block/GlowingObsidian.php | 2 +- src/pocketmine/block/Grass.php | 2 +- src/pocketmine/block/Gravel.php | 2 +- src/pocketmine/block/HardenedClay.php | 2 +- src/pocketmine/block/HayBale.php | 2 +- src/pocketmine/block/InfestedStone.php | 2 +- src/pocketmine/block/LapisOre.php | 2 +- src/pocketmine/block/Magma.php | 2 +- src/pocketmine/block/Mycelium.php | 2 +- src/pocketmine/block/NetherQuartzOre.php | 2 +- src/pocketmine/block/NetherReactor.php | 2 +- src/pocketmine/block/Netherrack.php | 2 +- src/pocketmine/block/Note.php | 2 +- .../block/{Solid.php => Opaque.php} | 2 +- src/pocketmine/block/PackedIce.php | 2 +- src/pocketmine/block/Planks.php | 2 +- src/pocketmine/block/Podzol.php | 2 +- src/pocketmine/block/RedMushroomBlock.php | 2 +- src/pocketmine/block/Redstone.php | 2 +- src/pocketmine/block/RedstoneLamp.php | 2 +- src/pocketmine/block/RedstoneOre.php | 2 +- src/pocketmine/block/Reserved6.php | 2 +- src/pocketmine/block/Sand.php | 2 +- src/pocketmine/block/Snow.php | 2 +- src/pocketmine/block/SoulSand.php | 2 +- src/pocketmine/block/Sponge.php | 2 +- src/pocketmine/block/TNT.php | 2 +- src/pocketmine/block/VanillaBlocks.php | 100 +++++++++--------- src/pocketmine/block/Wood.php | 2 +- src/pocketmine/block/Wool.php | 2 +- tests/phpunit/block/MyCustomBlock.php | 2 +- tests/phpunit/block/StrangeNewBlock.php | 2 +- 52 files changed, 144 insertions(+), 144 deletions(-) rename src/pocketmine/block/{Solid.php => Opaque.php} (96%) diff --git a/src/pocketmine/block/Bedrock.php b/src/pocketmine/block/Bedrock.php index 127846c050..b7765bcb20 100644 --- a/src/pocketmine/block/Bedrock.php +++ b/src/pocketmine/block/Bedrock.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -class Bedrock extends Solid{ +class Bedrock extends Opaque{ /** @var bool */ private $burnsForever = false; diff --git a/src/pocketmine/block/BlockFactory.php b/src/pocketmine/block/BlockFactory.php index 839e393457..59e5aafaaf 100644 --- a/src/pocketmine/block/BlockFactory.php +++ b/src/pocketmine/block/BlockFactory.php @@ -101,7 +101,7 @@ class BlockFactory{ $bricksBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); self::register(new Stair(new BID(Ids::BRICK_STAIRS), "Brick Stairs", $bricksBreakInfo)); - self::register(new Solid(new BID(Ids::BRICK_BLOCK), "Bricks", $bricksBreakInfo)); + self::register(new Opaque(new BID(Ids::BRICK_BLOCK), "Bricks", $bricksBreakInfo)); self::register(new BrownMushroom(new BID(Ids::BROWN_MUSHROOM), "Brown Mushroom")); self::register(new BrownMushroomBlock(new BID(Ids::BROWN_MUSHROOM_BLOCK), "Brown Mushroom Block")); @@ -115,8 +115,8 @@ class BlockFactory{ self::register(new CoarseDirt(new BID(Ids::DIRT, Meta::DIRT_COARSE), "Coarse Dirt")); $cobblestoneBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - self::register(new Solid(new BID(Ids::COBBLESTONE), "Cobblestone", $cobblestoneBreakInfo)); - self::register(new Solid(new BID(Ids::MOSSY_COBBLESTONE), "Mossy Cobblestone", $cobblestoneBreakInfo)); + self::register(new Opaque(new BID(Ids::COBBLESTONE), "Cobblestone", $cobblestoneBreakInfo)); + self::register(new Opaque(new BID(Ids::MOSSY_COBBLESTONE), "Mossy Cobblestone", $cobblestoneBreakInfo)); self::register(new Stair(new BID(Ids::COBBLESTONE_STAIRS), "Cobblestone Stairs", $cobblestoneBreakInfo)); self::register(new Stair(new BID(Ids::MOSSY_COBBLESTONE_STAIRS), "Mossy Cobblestone Stairs", $cobblestoneBreakInfo)); @@ -127,7 +127,7 @@ class BlockFactory{ self::register(new DeadBush(new BID(Ids::DEADBUSH), "Dead Bush")); self::register(new DetectorRail(new BID(Ids::DETECTOR_RAIL), "Detector Rail")); - self::register(new Solid(new BID(Ids::DIAMOND_BLOCK), "Diamond Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); + self::register(new Opaque(new BID(Ids::DIAMOND_BLOCK), "Diamond Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); self::register(new DiamondOre(new BID(Ids::DIAMOND_ORE), "Diamond Ore")); self::register(new Dirt(new BID(Ids::DIRT, Meta::DIRT_NORMAL), "Dirt")); self::register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_SUNFLOWER), "Sunflower")); @@ -138,15 +138,15 @@ class BlockFactory{ self::register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LARGE_FERN), "Large Fern")); self::register(new DragonEgg(new BID(Ids::DRAGON_EGG), "Dragon Egg")); self::register(new DriedKelp(new BID(Ids::DRIED_KELP_BLOCK), "Dried Kelp Block", new BlockBreakInfo(0.5, BlockToolType::NONE, 0, 12.5))); - self::register(new Solid(new BID(Ids::EMERALD_BLOCK), "Emerald Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); + self::register(new Opaque(new BID(Ids::EMERALD_BLOCK), "Emerald Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); self::register(new EmeraldOre(new BID(Ids::EMERALD_ORE), "Emerald Ore")); self::register(new EnchantingTable(new BID(Ids::ENCHANTING_TABLE, 0, null, TileEnchantingTable::class), "Enchanting Table")); self::register(new EndPortalFrame(new BID(Ids::END_PORTAL_FRAME), "End Portal Frame")); self::register(new EndRod(new BID(Ids::END_ROD), "End Rod")); - self::register(new Solid(new BID(Ids::END_STONE), "End Stone", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 45.0))); + self::register(new Opaque(new BID(Ids::END_STONE), "End Stone", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 45.0))); $endBrickBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 4.0); - self::register(new Solid(new BID(Ids::END_BRICKS), "End Stone Bricks", $endBrickBreakInfo)); + self::register(new Opaque(new BID(Ids::END_BRICKS), "End Stone Bricks", $endBrickBreakInfo)); self::register(new Stair(new BID(Ids::END_BRICK_STAIRS), "End Stone Brick Stairs", $endBrickBreakInfo)); self::register(new EnderChest(new BID(Ids::ENDER_CHEST, 0, null, TileEnderChest::class), "Ender Chest")); @@ -171,8 +171,8 @@ class BlockFactory{ self::register(new GlassPane(new BID(Ids::GLASS_PANE), "Glass Pane")); self::register(new GlowingObsidian(new BID(Ids::GLOWINGOBSIDIAN), "Glowing Obsidian")); self::register(new Glowstone(new BID(Ids::GLOWSTONE), "Glowstone")); - self::register(new Solid(new BID(Ids::GOLD_BLOCK), "Gold Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); - self::register(new Solid(new BID(Ids::GOLD_ORE), "Gold Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); + self::register(new Opaque(new BID(Ids::GOLD_BLOCK), "Gold Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); + self::register(new Opaque(new BID(Ids::GOLD_ORE), "Gold Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); self::register(new Grass(new BID(Ids::GRASS), "Grass")); self::register(new GrassPath(new BID(Ids::GRASS_PATH), "Grass Path")); self::register(new Gravel(new BID(Ids::GRAVEL), "Gravel")); @@ -214,18 +214,18 @@ class BlockFactory{ }); $updateBlockBreakInfo = new BlockBreakInfo(1.0); - self::register(new Solid(new BID(Ids::INFO_UPDATE), "update!", $updateBlockBreakInfo)); - self::register(new Solid(new BID(Ids::INFO_UPDATE2), "ate!upd", $updateBlockBreakInfo)); + self::register(new Opaque(new BID(Ids::INFO_UPDATE), "update!", $updateBlockBreakInfo)); + self::register(new Opaque(new BID(Ids::INFO_UPDATE2), "ate!upd", $updateBlockBreakInfo)); self::register(new Transparent(new BID(Ids::INVISIBLEBEDROCK), "Invisible Bedrock", BlockBreakInfo::indestructible())); - self::register(new Solid(new BID(Ids::IRON_BLOCK), "Iron Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel(), 30.0))); + self::register(new Opaque(new BID(Ids::IRON_BLOCK), "Iron Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel(), 30.0))); self::register(new Thin(new BID(Ids::IRON_BARS), "Iron Bars", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0))); self::register(new Door(new BID(Ids::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0))); - self::register(new Solid(new BID(Ids::IRON_ORE), "Iron Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); + self::register(new Opaque(new BID(Ids::IRON_ORE), "Iron Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); self::register(new Trapdoor(new BID(Ids::IRON_TRAPDOOR), "Iron Trapdoor", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0))); self::register(new ItemFrame(new BID(Ids::FRAME_BLOCK, 0, ItemIds::FRAME, TileItemFrame::class), "Item Frame")); self::register(new Ladder(new BID(Ids::LADDER), "Ladder")); self::register(new Lantern(new BID(Ids::LANTERN), "Lantern", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - self::register(new Solid(new BID(Ids::LAPIS_BLOCK), "Lapis Lazuli Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); + self::register(new Opaque(new BID(Ids::LAPIS_BLOCK), "Lapis Lazuli Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); self::register(new LapisOre(new BID(Ids::LAPIS_ORE), "Lapis Lazuli Ore")); self::register(new Lava(new BIDFlattened(Ids::FLOWING_LAVA, Ids::STILL_LAVA), "Lava")); self::register(new Lever(new BID(Ids::LEVER), "Lever")); @@ -236,34 +236,34 @@ class BlockFactory{ self::register(new Mycelium(new BID(Ids::MYCELIUM), "Mycelium")); $netherBrickBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - self::register(new Solid(new BID(Ids::NETHER_BRICK_BLOCK), "Nether Bricks", $netherBrickBreakInfo)); - self::register(new Solid(new BID(Ids::RED_NETHER_BRICK), "Red Nether Bricks", $netherBrickBreakInfo)); + self::register(new Opaque(new BID(Ids::NETHER_BRICK_BLOCK), "Nether Bricks", $netherBrickBreakInfo)); + self::register(new Opaque(new BID(Ids::RED_NETHER_BRICK), "Red Nether Bricks", $netherBrickBreakInfo)); self::register(new Fence(new BID(Ids::NETHER_BRICK_FENCE), "Nether Brick Fence", $netherBrickBreakInfo)); self::register(new Stair(new BID(Ids::NETHER_BRICK_STAIRS), "Nether Brick Stairs", $netherBrickBreakInfo)); self::register(new Stair(new BID(Ids::RED_NETHER_BRICK_STAIRS), "Red Nether Brick Stairs", $netherBrickBreakInfo)); self::register(new NetherPortal(new BID(Ids::PORTAL), "Nether Portal")); self::register(new NetherQuartzOre(new BID(Ids::NETHER_QUARTZ_ORE), "Nether Quartz Ore")); self::register(new NetherReactor(new BID(Ids::NETHERREACTOR), "Nether Reactor Core")); - self::register(new Solid(new BID(Ids::NETHER_WART_BLOCK), "Nether Wart Block", new BlockBreakInfo(1.0))); + self::register(new Opaque(new BID(Ids::NETHER_WART_BLOCK), "Nether Wart Block", new BlockBreakInfo(1.0))); self::register(new NetherWartPlant(new BID(Ids::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART), "Nether Wart")); self::register(new Netherrack(new BID(Ids::NETHERRACK), "Netherrack")); self::register(new Note(new BID(Ids::NOTEBLOCK, 0, null, TileNote::class), "Note Block")); - self::register(new Solid(new BID(Ids::OBSIDIAN), "Obsidian", new BlockBreakInfo(35.0 /* 50 in PC */, BlockToolType::PICKAXE, ToolTier::DIAMOND()->getHarvestLevel(), 6000.0))); + self::register(new Opaque(new BID(Ids::OBSIDIAN), "Obsidian", new BlockBreakInfo(35.0 /* 50 in PC */, BlockToolType::PICKAXE, ToolTier::DIAMOND()->getHarvestLevel(), 6000.0))); self::register(new PackedIce(new BID(Ids::PACKED_ICE), "Packed Ice")); self::register(new Podzol(new BID(Ids::PODZOL), "Podzol")); self::register(new Potato(new BID(Ids::POTATOES), "Potato Block")); self::register(new PoweredRail(new BID(Ids::GOLDEN_RAIL, Meta::RAIL_STRAIGHT_NORTH_SOUTH), "Powered Rail")); $prismarineBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - self::register(new Solid(new BID(Ids::PRISMARINE, Meta::PRISMARINE_BRICKS), "Prismarine Bricks", $prismarineBreakInfo)); + self::register(new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_BRICKS), "Prismarine Bricks", $prismarineBreakInfo)); self::register(new Stair(new BID(Ids::PRISMARINE_BRICKS_STAIRS), "Prismarine Bricks Stairs", $prismarineBreakInfo)); - self::register(new Solid(new BID(Ids::PRISMARINE, Meta::PRISMARINE_DARK), "Dark Prismarine", $prismarineBreakInfo)); + self::register(new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_DARK), "Dark Prismarine", $prismarineBreakInfo)); self::register(new Stair(new BID(Ids::DARK_PRISMARINE_STAIRS), "Dark Prismarine Stairs", $prismarineBreakInfo)); - self::register(new Solid(new BID(Ids::PRISMARINE, Meta::PRISMARINE_NORMAL), "Prismarine", $prismarineBreakInfo)); + self::register(new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_NORMAL), "Prismarine", $prismarineBreakInfo)); self::register(new Stair(new BID(Ids::PRISMARINE_STAIRS), "Prismarine Stairs", $prismarineBreakInfo)); $pumpkinBreakInfo = new BlockBreakInfo(1.0, BlockToolType::AXE); - self::register($pumpkin = new Solid(new BID(Ids::PUMPKIN), "Pumpkin", $pumpkinBreakInfo)); + self::register($pumpkin = new Opaque(new BID(Ids::PUMPKIN), "Pumpkin", $pumpkinBreakInfo)); for($i = 1; $i <= 3; ++$i){ self::remap(Ids::PUMPKIN, $i, $pumpkin); } @@ -273,22 +273,22 @@ class BlockFactory{ self::register(new PumpkinStem(new BID(Ids::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem")); $purpurBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - self::register(new Solid(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_NORMAL), "Purpur Block", $purpurBreakInfo)); - self::register(new class(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_PILLAR), "Purpur Pillar", $purpurBreakInfo) extends Solid{ + self::register(new Opaque(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_NORMAL), "Purpur Block", $purpurBreakInfo)); + self::register(new class(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_PILLAR), "Purpur Pillar", $purpurBreakInfo) extends Opaque{ use PillarRotationTrait; }); self::register(new Stair(new BID(Ids::PURPUR_STAIRS), "Purpur Stairs", $purpurBreakInfo)); $quartzBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()); - self::register(new Solid(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_NORMAL), "Quartz Block", $quartzBreakInfo)); + self::register(new Opaque(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_NORMAL), "Quartz Block", $quartzBreakInfo)); self::register(new Stair(new BID(Ids::QUARTZ_STAIRS), "Quartz Stairs", $quartzBreakInfo)); - self::register(new class(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_CHISELED), "Chiseled Quartz Block", $quartzBreakInfo) extends Solid{ + self::register(new class(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_CHISELED), "Chiseled Quartz Block", $quartzBreakInfo) extends Opaque{ use PillarRotationTrait; }); - self::register(new class(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_PILLAR), "Quartz Pillar", $quartzBreakInfo) extends Solid{ + self::register(new class(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_PILLAR), "Quartz Pillar", $quartzBreakInfo) extends Opaque{ use PillarRotationTrait; }); - self::register(new Solid(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_SMOOTH), "Smooth Quartz Block", $quartzBreakInfo)); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) + self::register(new Opaque(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_SMOOTH), "Smooth Quartz Block", $quartzBreakInfo)); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) self::register(new Stair(new BID(Ids::SMOOTH_QUARTZ_STAIRS), "Smooth Quartz Stairs", $quartzBreakInfo)); self::register(new Rail(new BID(Ids::RAIL), "Rail")); @@ -316,31 +316,31 @@ class BlockFactory{ self::register(new Sponge(new BID(Ids::SPONGE), "Sponge")); $stoneBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - self::register(new class(new BID(Ids::STONE, Meta::STONE_NORMAL), "Stone", $stoneBreakInfo) extends Solid{ + self::register(new class(new BID(Ids::STONE, Meta::STONE_NORMAL), "Stone", $stoneBreakInfo) extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ return [VanillaBlocks::COBBLESTONE()->asItem()]; } }); self::register(new Stair(new BID(Ids::NORMAL_STONE_STAIRS), "Stone Stairs", $stoneBreakInfo)); - self::register(new Solid(new BID(Ids::SMOOTH_STONE), "Smooth Stone", $stoneBreakInfo)); - self::register(new Solid(new BID(Ids::STONE, Meta::STONE_ANDESITE), "Andesite", $stoneBreakInfo)); + self::register(new Opaque(new BID(Ids::SMOOTH_STONE), "Smooth Stone", $stoneBreakInfo)); + self::register(new Opaque(new BID(Ids::STONE, Meta::STONE_ANDESITE), "Andesite", $stoneBreakInfo)); self::register(new Stair(new BID(Ids::ANDESITE_STAIRS), "Andesite Stairs", $stoneBreakInfo)); - self::register(new Solid(new BID(Ids::STONE, Meta::STONE_DIORITE), "Diorite", $stoneBreakInfo)); + self::register(new Opaque(new BID(Ids::STONE, Meta::STONE_DIORITE), "Diorite", $stoneBreakInfo)); self::register(new Stair(new BID(Ids::DIORITE_STAIRS), "Diorite Stairs", $stoneBreakInfo)); - self::register(new Solid(new BID(Ids::STONE, Meta::STONE_GRANITE), "Granite", $stoneBreakInfo)); + self::register(new Opaque(new BID(Ids::STONE, Meta::STONE_GRANITE), "Granite", $stoneBreakInfo)); self::register(new Stair(new BID(Ids::GRANITE_STAIRS), "Granite Stairs", $stoneBreakInfo)); - self::register(new Solid(new BID(Ids::STONE, Meta::STONE_POLISHED_ANDESITE), "Polished Andesite", $stoneBreakInfo)); + self::register(new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_ANDESITE), "Polished Andesite", $stoneBreakInfo)); self::register(new Stair(new BID(Ids::POLISHED_ANDESITE_STAIRS), "Polished Andesite Stairs", $stoneBreakInfo)); - self::register(new Solid(new BID(Ids::STONE, Meta::STONE_POLISHED_DIORITE), "Polished Diorite", $stoneBreakInfo)); + self::register(new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_DIORITE), "Polished Diorite", $stoneBreakInfo)); self::register(new Stair(new BID(Ids::POLISHED_DIORITE_STAIRS), "Polished Diorite Stairs", $stoneBreakInfo)); - self::register(new Solid(new BID(Ids::STONE, Meta::STONE_POLISHED_GRANITE), "Polished Granite", $stoneBreakInfo)); + self::register(new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_GRANITE), "Polished Granite", $stoneBreakInfo)); self::register(new Stair(new BID(Ids::POLISHED_GRANITE_STAIRS), "Polished Granite Stairs", $stoneBreakInfo)); self::register(new Stair(new BID(Ids::STONE_BRICK_STAIRS), "Stone Brick Stairs", $stoneBreakInfo)); - self::register(new Solid(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CHISELED), "Chiseled Stone Bricks", $stoneBreakInfo)); - self::register(new Solid(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CRACKED), "Cracked Stone Bricks", $stoneBreakInfo)); - self::register(new Solid(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_MOSSY), "Mossy Stone Bricks", $stoneBreakInfo)); + self::register(new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CHISELED), "Chiseled Stone Bricks", $stoneBreakInfo)); + self::register(new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CRACKED), "Cracked Stone Bricks", $stoneBreakInfo)); + self::register(new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_MOSSY), "Mossy Stone Bricks", $stoneBreakInfo)); self::register(new Stair(new BID(Ids::MOSSY_STONE_BRICK_STAIRS), "Mossy Stone Brick Stairs", $stoneBreakInfo)); - self::register(new Solid(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_NORMAL), "Stone Bricks", $stoneBreakInfo)); + self::register(new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_NORMAL), "Stone Bricks", $stoneBreakInfo)); self::register(new StoneButton(new BID(Ids::STONE_BUTTON), "Stone Button")); self::register(new StonePressurePlate(new BID(Ids::STONE_PRESSURE_PLATE), "Stone Pressure Plate")); @@ -375,7 +375,7 @@ class BlockFactory{ self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_MOSSY_STONE_BRICK), "Mossy Stone Brick", $stoneSlabBreakInfo)); self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_SMOOTH_QUARTZ), "Smooth Quartz", $stoneSlabBreakInfo)); self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_STONE), "Stone", $stoneSlabBreakInfo)); - self::register(new Solid(new BID(Ids::STONECUTTER), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + self::register(new Opaque(new BID(Ids::STONECUTTER), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); self::register(new Sugarcane(new BID(Ids::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane")); self::register(new TNT(new BID(Ids::TNT), "TNT")); @@ -505,8 +505,8 @@ class BlockFactory{ self::register(new Stair(new BID(Ids::SANDSTONE_STAIRS), "Sandstone Stairs", $sandstoneBreakInfo)); self::register(new Stair(new BID(Ids::SMOOTH_SANDSTONE_STAIRS), "Smooth Sandstone Stairs", $sandstoneBreakInfo)); foreach($sandstoneTypes as $variant => $prefix){ - self::register(new Solid(new BID(Ids::SANDSTONE, $variant), $prefix . "Sandstone", $sandstoneBreakInfo)); - self::register(new Solid(new BID(Ids::RED_SANDSTONE, $variant), $prefix . "Red Sandstone", $sandstoneBreakInfo)); + self::register(new Opaque(new BID(Ids::SANDSTONE, $variant), $prefix . "Sandstone", $sandstoneBreakInfo)); + self::register(new Opaque(new BID(Ids::RED_SANDSTONE, $variant), $prefix . "Red Sandstone", $sandstoneBreakInfo)); } //region ugly glazed-terracotta colour -> ID mapping table @@ -632,7 +632,7 @@ class BlockFactory{ } private static function registerElements() : void{ - self::register(new Solid(new BID(Ids::ELEMENT_0), "???", BlockBreakInfo::instant())); + self::register(new Opaque(new BID(Ids::ELEMENT_0), "???", BlockBreakInfo::instant())); self::register(new Element(new BID(Ids::ELEMENT_1), "Hydrogen", BlockBreakInfo::instant(), "h", 1, 5)); self::register(new Element(new BID(Ids::ELEMENT_2), "Helium", BlockBreakInfo::instant(), "he", 2, 7)); diff --git a/src/pocketmine/block/BlueIce.php b/src/pocketmine/block/BlueIce.php index bb6c0b152c..7339f8271f 100644 --- a/src/pocketmine/block/BlueIce.php +++ b/src/pocketmine/block/BlueIce.php @@ -25,7 +25,7 @@ namespace pocketmine\block; use pocketmine\item\Item; -class BlueIce extends Solid{ +class BlueIce extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.8, BlockToolType::PICKAXE)); diff --git a/src/pocketmine/block/BoneBlock.php b/src/pocketmine/block/BoneBlock.php index 35d1f7bce7..4581038529 100644 --- a/src/pocketmine/block/BoneBlock.php +++ b/src/pocketmine/block/BoneBlock.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\block\utils\PillarRotationTrait; use pocketmine\item\ToolTier; -class BoneBlock extends Solid{ +class BoneBlock extends Opaque{ use PillarRotationTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ diff --git a/src/pocketmine/block/Bookshelf.php b/src/pocketmine/block/Bookshelf.php index fba6053e36..f4af2e1116 100644 --- a/src/pocketmine/block/Bookshelf.php +++ b/src/pocketmine/block/Bookshelf.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\item\VanillaItems; -class Bookshelf extends Solid{ +class Bookshelf extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.5, BlockToolType::AXE)); diff --git a/src/pocketmine/block/CarvedPumpkin.php b/src/pocketmine/block/CarvedPumpkin.php index 8c3f66a72e..621ae9c3fb 100644 --- a/src/pocketmine/block/CarvedPumpkin.php +++ b/src/pocketmine/block/CarvedPumpkin.php @@ -31,7 +31,7 @@ use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\world\BlockTransaction; -class CarvedPumpkin extends Solid{ +class CarvedPumpkin extends Opaque{ /** @var int */ protected $facing = Facing::NORTH; diff --git a/src/pocketmine/block/Clay.php b/src/pocketmine/block/Clay.php index 41560db3ba..b3b51e2dd5 100644 --- a/src/pocketmine/block/Clay.php +++ b/src/pocketmine/block/Clay.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use pocketmine\item\VanillaItems; -class Clay extends Solid{ +class Clay extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::SHOVEL)); diff --git a/src/pocketmine/block/Coal.php b/src/pocketmine/block/Coal.php index 8b3d4257e4..27e86bc036 100644 --- a/src/pocketmine/block/Coal.php +++ b/src/pocketmine/block/Coal.php @@ -25,7 +25,7 @@ namespace pocketmine\block; use pocketmine\item\ToolTier; -class Coal extends Solid{ +class Coal extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0)); diff --git a/src/pocketmine/block/CoalOre.php b/src/pocketmine/block/CoalOre.php index 5643d8d546..434e5ee0bf 100644 --- a/src/pocketmine/block/CoalOre.php +++ b/src/pocketmine/block/CoalOre.php @@ -28,7 +28,7 @@ use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; use function mt_rand; -class CoalOre extends Solid{ +class CoalOre extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); diff --git a/src/pocketmine/block/Concrete.php b/src/pocketmine/block/Concrete.php index 93243fee17..67c18a4c85 100644 --- a/src/pocketmine/block/Concrete.php +++ b/src/pocketmine/block/Concrete.php @@ -25,7 +25,7 @@ namespace pocketmine\block; use pocketmine\item\ToolTier; -class Concrete extends Solid{ +class Concrete extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); diff --git a/src/pocketmine/block/ConcretePowder.php b/src/pocketmine/block/ConcretePowder.php index d4adec673e..881b864ba8 100644 --- a/src/pocketmine/block/ConcretePowder.php +++ b/src/pocketmine/block/ConcretePowder.php @@ -27,7 +27,7 @@ use pocketmine\block\utils\Fallable; use pocketmine\block\utils\FallableTrait; use pocketmine\math\Facing; -class ConcretePowder extends Solid implements Fallable{ +class ConcretePowder extends Opaque implements Fallable{ use FallableTrait { onNearbyBlockChange as protected startFalling; } diff --git a/src/pocketmine/block/CraftingTable.php b/src/pocketmine/block/CraftingTable.php index e63fd3f10f..d4f0259ed7 100644 --- a/src/pocketmine/block/CraftingTable.php +++ b/src/pocketmine/block/CraftingTable.php @@ -28,7 +28,7 @@ use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\player\Player; -class CraftingTable extends Solid{ +class CraftingTable extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.5, BlockToolType::AXE)); diff --git a/src/pocketmine/block/DiamondOre.php b/src/pocketmine/block/DiamondOre.php index ff0ea297e0..44d89c9667 100644 --- a/src/pocketmine/block/DiamondOre.php +++ b/src/pocketmine/block/DiamondOre.php @@ -28,7 +28,7 @@ use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; use function mt_rand; -class DiamondOre extends Solid{ +class DiamondOre extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel())); diff --git a/src/pocketmine/block/Dirt.php b/src/pocketmine/block/Dirt.php index 5511d9b6db..5d035b318e 100644 --- a/src/pocketmine/block/Dirt.php +++ b/src/pocketmine/block/Dirt.php @@ -29,7 +29,7 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; -class Dirt extends Solid{ +class Dirt extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::SHOVEL)); diff --git a/src/pocketmine/block/DriedKelp.php b/src/pocketmine/block/DriedKelp.php index fbc0411d73..b5a05efa51 100644 --- a/src/pocketmine/block/DriedKelp.php +++ b/src/pocketmine/block/DriedKelp.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -class DriedKelp extends Solid{ +class DriedKelp extends Opaque{ public function getFlameEncouragement() : int{ return 30; diff --git a/src/pocketmine/block/Element.php b/src/pocketmine/block/Element.php index fa0cd2d66e..16234b3087 100644 --- a/src/pocketmine/block/Element.php +++ b/src/pocketmine/block/Element.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -class Element extends Solid{ +class Element extends Opaque{ /** @var int */ private $atomicWeight; diff --git a/src/pocketmine/block/EmeraldOre.php b/src/pocketmine/block/EmeraldOre.php index 4345ada463..aa9b95c27b 100644 --- a/src/pocketmine/block/EmeraldOre.php +++ b/src/pocketmine/block/EmeraldOre.php @@ -28,7 +28,7 @@ use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; use function mt_rand; -class EmeraldOre extends Solid{ +class EmeraldOre extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel())); diff --git a/src/pocketmine/block/EndPortalFrame.php b/src/pocketmine/block/EndPortalFrame.php index 70e5f5aef2..9f031e33a0 100644 --- a/src/pocketmine/block/EndPortalFrame.php +++ b/src/pocketmine/block/EndPortalFrame.php @@ -32,7 +32,7 @@ use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\world\BlockTransaction; -class EndPortalFrame extends Solid{ +class EndPortalFrame extends Opaque{ /** @var int */ protected $facing = Facing::NORTH; diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index 3864118c8f..1d3af756ef 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -32,7 +32,7 @@ use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\world\BlockTransaction; -class Furnace extends Solid{ +class Furnace extends Opaque{ /** @var BlockIdentifierFlattened */ protected $idInfo; diff --git a/src/pocketmine/block/GlazedTerracotta.php b/src/pocketmine/block/GlazedTerracotta.php index 5f680e0368..9efb9c347d 100644 --- a/src/pocketmine/block/GlazedTerracotta.php +++ b/src/pocketmine/block/GlazedTerracotta.php @@ -32,7 +32,7 @@ use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\world\BlockTransaction; -class GlazedTerracotta extends Solid{ +class GlazedTerracotta extends Opaque{ /** @var int */ protected $facing = Facing::NORTH; diff --git a/src/pocketmine/block/GlowingObsidian.php b/src/pocketmine/block/GlowingObsidian.php index 74f5ba694a..036459eae9 100644 --- a/src/pocketmine/block/GlowingObsidian.php +++ b/src/pocketmine/block/GlowingObsidian.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\item\ToolTier; -class GlowingObsidian extends Solid{ +class GlowingObsidian extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(10.0, BlockToolType::PICKAXE, ToolTier::DIAMOND()->getHarvestLevel(), 50.0)); diff --git a/src/pocketmine/block/Grass.php b/src/pocketmine/block/Grass.php index 25b9188e46..2e1485a3ee 100644 --- a/src/pocketmine/block/Grass.php +++ b/src/pocketmine/block/Grass.php @@ -35,7 +35,7 @@ use pocketmine\utils\Random; use pocketmine\world\generator\object\TallGrass as TallGrassObject; use function mt_rand; -class Grass extends Solid{ +class Grass extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::SHOVEL)); diff --git a/src/pocketmine/block/Gravel.php b/src/pocketmine/block/Gravel.php index a93173ffbd..1089b58933 100644 --- a/src/pocketmine/block/Gravel.php +++ b/src/pocketmine/block/Gravel.php @@ -29,7 +29,7 @@ use pocketmine\item\Item; use pocketmine\item\VanillaItems; use function mt_rand; -class Gravel extends Solid implements Fallable{ +class Gravel extends Opaque implements Fallable{ use FallableTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ diff --git a/src/pocketmine/block/HardenedClay.php b/src/pocketmine/block/HardenedClay.php index 293d2f4ecd..1617a738c4 100644 --- a/src/pocketmine/block/HardenedClay.php +++ b/src/pocketmine/block/HardenedClay.php @@ -25,7 +25,7 @@ namespace pocketmine\block; use pocketmine\item\ToolTier; -class HardenedClay extends Solid{ +class HardenedClay extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.25, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 21.0)); diff --git a/src/pocketmine/block/HayBale.php b/src/pocketmine/block/HayBale.php index 38e480a9e6..d6c1be2860 100644 --- a/src/pocketmine/block/HayBale.php +++ b/src/pocketmine/block/HayBale.php @@ -25,7 +25,7 @@ namespace pocketmine\block; use pocketmine\block\utils\PillarRotationTrait; -class HayBale extends Solid{ +class HayBale extends Opaque{ use PillarRotationTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ diff --git a/src/pocketmine/block/InfestedStone.php b/src/pocketmine/block/InfestedStone.php index c08a0c5c76..1457daf4c6 100644 --- a/src/pocketmine/block/InfestedStone.php +++ b/src/pocketmine/block/InfestedStone.php @@ -25,7 +25,7 @@ namespace pocketmine\block; use pocketmine\item\Item; -abstract class InfestedStone extends Solid{ +abstract class InfestedStone extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.75)); diff --git a/src/pocketmine/block/LapisOre.php b/src/pocketmine/block/LapisOre.php index a1e49f227d..f79a952398 100644 --- a/src/pocketmine/block/LapisOre.php +++ b/src/pocketmine/block/LapisOre.php @@ -28,7 +28,7 @@ use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; use function mt_rand; -class LapisOre extends Solid{ +class LapisOre extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel())); diff --git a/src/pocketmine/block/Magma.php b/src/pocketmine/block/Magma.php index 16f1e4435c..fd3437bc4d 100644 --- a/src/pocketmine/block/Magma.php +++ b/src/pocketmine/block/Magma.php @@ -28,7 +28,7 @@ use pocketmine\event\entity\EntityDamageByBlockEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\item\ToolTier; -class Magma extends Solid{ +class Magma extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); diff --git a/src/pocketmine/block/Mycelium.php b/src/pocketmine/block/Mycelium.php index fa1a4e12e8..93a7c11b14 100644 --- a/src/pocketmine/block/Mycelium.php +++ b/src/pocketmine/block/Mycelium.php @@ -28,7 +28,7 @@ use pocketmine\item\Item; use pocketmine\math\Facing; use function mt_rand; -class Mycelium extends Solid{ +class Mycelium extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::SHOVEL)); diff --git a/src/pocketmine/block/NetherQuartzOre.php b/src/pocketmine/block/NetherQuartzOre.php index 7c55be08fa..598ded41d0 100644 --- a/src/pocketmine/block/NetherQuartzOre.php +++ b/src/pocketmine/block/NetherQuartzOre.php @@ -28,7 +28,7 @@ use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; use function mt_rand; -class NetherQuartzOre extends Solid{ +class NetherQuartzOre extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); diff --git a/src/pocketmine/block/NetherReactor.php b/src/pocketmine/block/NetherReactor.php index 800ac583d8..90045427da 100644 --- a/src/pocketmine/block/NetherReactor.php +++ b/src/pocketmine/block/NetherReactor.php @@ -28,7 +28,7 @@ use pocketmine\item\Item; use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; -class NetherReactor extends Solid{ +class NetherReactor extends Opaque{ /** @var int */ protected $state = BlockLegacyMetadata::NETHER_REACTOR_INACTIVE; diff --git a/src/pocketmine/block/Netherrack.php b/src/pocketmine/block/Netherrack.php index f1db4323f7..895a078021 100644 --- a/src/pocketmine/block/Netherrack.php +++ b/src/pocketmine/block/Netherrack.php @@ -25,7 +25,7 @@ namespace pocketmine\block; use pocketmine\item\ToolTier; -class Netherrack extends Solid{ +class Netherrack extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.4, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); diff --git a/src/pocketmine/block/Note.php b/src/pocketmine/block/Note.php index ca298c5516..da65aab21b 100644 --- a/src/pocketmine/block/Note.php +++ b/src/pocketmine/block/Note.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\block\tile\Note as TileNote; use function assert; -class Note extends Solid{ +class Note extends Opaque{ public const MIN_PITCH = 0; public const MAX_PITCH = 24; diff --git a/src/pocketmine/block/Solid.php b/src/pocketmine/block/Opaque.php similarity index 96% rename from src/pocketmine/block/Solid.php rename to src/pocketmine/block/Opaque.php index 1184022aa5..19e16292e6 100644 --- a/src/pocketmine/block/Solid.php +++ b/src/pocketmine/block/Opaque.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -class Solid extends Block{ +class Opaque extends Block{ public function isSolid() : bool{ return true; diff --git a/src/pocketmine/block/PackedIce.php b/src/pocketmine/block/PackedIce.php index a5bca2726f..852b07e3c9 100644 --- a/src/pocketmine/block/PackedIce.php +++ b/src/pocketmine/block/PackedIce.php @@ -25,7 +25,7 @@ namespace pocketmine\block; use pocketmine\item\Item; -class PackedIce extends Solid{ +class PackedIce extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE)); diff --git a/src/pocketmine/block/Planks.php b/src/pocketmine/block/Planks.php index 593d21147a..e7632f87ad 100644 --- a/src/pocketmine/block/Planks.php +++ b/src/pocketmine/block/Planks.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -class Planks extends Solid{ +class Planks extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::AXE, 0, 15.0)); diff --git a/src/pocketmine/block/Podzol.php b/src/pocketmine/block/Podzol.php index 20e55c1b01..48edfec507 100644 --- a/src/pocketmine/block/Podzol.php +++ b/src/pocketmine/block/Podzol.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -class Podzol extends Solid{ +class Podzol extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.5, BlockToolType::SHOVEL)); diff --git a/src/pocketmine/block/RedMushroomBlock.php b/src/pocketmine/block/RedMushroomBlock.php index c1bbada6a9..2e9a43fa70 100644 --- a/src/pocketmine/block/RedMushroomBlock.php +++ b/src/pocketmine/block/RedMushroomBlock.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\item\Item; use function mt_rand; -class RedMushroomBlock extends Solid{ +class RedMushroomBlock extends Opaque{ /** * @var int diff --git a/src/pocketmine/block/Redstone.php b/src/pocketmine/block/Redstone.php index 6c22fbc56d..7f06a706cb 100644 --- a/src/pocketmine/block/Redstone.php +++ b/src/pocketmine/block/Redstone.php @@ -25,7 +25,7 @@ namespace pocketmine\block; use pocketmine\item\ToolTier; -class Redstone extends Solid{ +class Redstone extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0)); diff --git a/src/pocketmine/block/RedstoneLamp.php b/src/pocketmine/block/RedstoneLamp.php index b896ad03de..d16ca52e8c 100644 --- a/src/pocketmine/block/RedstoneLamp.php +++ b/src/pocketmine/block/RedstoneLamp.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -class RedstoneLamp extends Solid{ +class RedstoneLamp extends Opaque{ /** @var BlockIdentifierFlattened */ protected $idInfo; diff --git a/src/pocketmine/block/RedstoneOre.php b/src/pocketmine/block/RedstoneOre.php index 8fe05ed25c..92cfc0577b 100644 --- a/src/pocketmine/block/RedstoneOre.php +++ b/src/pocketmine/block/RedstoneOre.php @@ -30,7 +30,7 @@ use pocketmine\math\Vector3; use pocketmine\player\Player; use function mt_rand; -class RedstoneOre extends Solid{ +class RedstoneOre extends Opaque{ /** @var BlockIdentifierFlattened */ protected $idInfo; diff --git a/src/pocketmine/block/Reserved6.php b/src/pocketmine/block/Reserved6.php index 85d6b6b479..940fbf33e3 100644 --- a/src/pocketmine/block/Reserved6.php +++ b/src/pocketmine/block/Reserved6.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -class Reserved6 extends Solid{ +class Reserved6 extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); diff --git a/src/pocketmine/block/Sand.php b/src/pocketmine/block/Sand.php index ce13cabcce..8516fdca9e 100644 --- a/src/pocketmine/block/Sand.php +++ b/src/pocketmine/block/Sand.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\block\utils\Fallable; use pocketmine\block\utils\FallableTrait; -class Sand extends Solid implements Fallable{ +class Sand extends Opaque implements Fallable{ use FallableTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ diff --git a/src/pocketmine/block/Snow.php b/src/pocketmine/block/Snow.php index 02e98af2ed..9d227333a4 100644 --- a/src/pocketmine/block/Snow.php +++ b/src/pocketmine/block/Snow.php @@ -27,7 +27,7 @@ use pocketmine\item\Item; use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; -class Snow extends Solid{ +class Snow extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::SHOVEL, ToolTier::WOOD()->getHarvestLevel())); diff --git a/src/pocketmine/block/SoulSand.php b/src/pocketmine/block/SoulSand.php index b613a9f5ed..bc60ad9ec5 100644 --- a/src/pocketmine/block/SoulSand.php +++ b/src/pocketmine/block/SoulSand.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; -class SoulSand extends Solid{ +class SoulSand extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::SHOVEL)); diff --git a/src/pocketmine/block/Sponge.php b/src/pocketmine/block/Sponge.php index 1b78bac476..f95a7128ce 100644 --- a/src/pocketmine/block/Sponge.php +++ b/src/pocketmine/block/Sponge.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; -class Sponge extends Solid{ +class Sponge extends Opaque{ /** @var bool */ protected $wet = false; diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index 4aa5fd2507..e263d7cba1 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -38,7 +38,7 @@ use function cos; use function sin; use const M_PI; -class TNT extends Solid{ +class TNT extends Opaque{ /** @var bool */ protected $unstable = false; //TODO: Usage unclear, seems to be a weird hack in vanilla diff --git a/src/pocketmine/block/VanillaBlocks.php b/src/pocketmine/block/VanillaBlocks.php index d14c05149f..605c629d68 100644 --- a/src/pocketmine/block/VanillaBlocks.php +++ b/src/pocketmine/block/VanillaBlocks.php @@ -49,7 +49,7 @@ use function assert; * @method static ActivatorRail ACTIVATOR_RAIL() * @method static Air AIR() * @method static Flower ALLIUM() - * @method static Solid ANDESITE() + * @method static Opaque ANDESITE() * @method static Slab ANDESITE_SLAB() * @method static Stair ANDESITE_STAIRS() * @method static Wall ANDESITE_WALL() @@ -99,7 +99,7 @@ use function assert; * @method static Slab BRICK_SLAB() * @method static Stair BRICK_STAIRS() * @method static Wall BRICK_WALL() - * @method static Solid BRICKS() + * @method static Opaque BRICKS() * @method static Carpet BROWN_CARPET() * @method static Concrete BROWN_CONCRETE() * @method static ConcretePowder BROWN_CONCRETE_POWDER() @@ -115,26 +115,26 @@ use function assert; * @method static Carrot CARROTS() * @method static CarvedPumpkin CARVED_PUMPKIN() * @method static Chest CHEST() - * @method static Solid CHISELED_QUARTZ() - * @method static Solid CHISELED_RED_SANDSTONE() - * @method static Solid CHISELED_SANDSTONE() - * @method static Solid CHISELED_STONE_BRICKS() + * @method static Opaque CHISELED_QUARTZ() + * @method static Opaque CHISELED_RED_SANDSTONE() + * @method static Opaque CHISELED_SANDSTONE() + * @method static Opaque CHISELED_STONE_BRICKS() * @method static Clay CLAY() * @method static Coal COAL() * @method static CoalOre COAL_ORE() * @method static CoarseDirt COARSE_DIRT() - * @method static Solid COBBLESTONE() + * @method static Opaque COBBLESTONE() * @method static Slab COBBLESTONE_SLAB() * @method static Stair COBBLESTONE_STAIRS() * @method static Wall COBBLESTONE_WALL() * @method static Cobweb COBWEB() * @method static CocoaBlock COCOA_POD() * @method static Flower CORNFLOWER() - * @method static Solid CRACKED_STONE_BRICKS() + * @method static Opaque CRACKED_STONE_BRICKS() * @method static CraftingTable CRAFTING_TABLE() - * @method static Solid CUT_RED_SANDSTONE() + * @method static Opaque CUT_RED_SANDSTONE() * @method static Slab CUT_RED_SANDSTONE_SLAB() - * @method static Solid CUT_SANDSTONE() + * @method static Opaque CUT_SANDSTONE() * @method static Slab CUT_SANDSTONE_SLAB() * @method static Carpet CYAN_CARPET() * @method static Concrete CYAN_CONCRETE() @@ -159,15 +159,15 @@ use function assert; * @method static WoodenStairs DARK_OAK_STAIRS() * @method static WoodenTrapdoor DARK_OAK_TRAPDOOR() * @method static Wood DARK_OAK_WOOD() - * @method static Solid DARK_PRISMARINE() + * @method static Opaque DARK_PRISMARINE() * @method static Slab DARK_PRISMARINE_SLAB() * @method static Stair DARK_PRISMARINE_STAIRS() * @method static DaylightSensor DAYLIGHT_SENSOR() * @method static DeadBush DEAD_BUSH() * @method static DetectorRail DETECTOR_RAIL() - * @method static Solid DIAMOND() + * @method static Opaque DIAMOND() * @method static DiamondOre DIAMOND_ORE() - * @method static Solid DIORITE() + * @method static Opaque DIORITE() * @method static Slab DIORITE_SLAB() * @method static Stair DIORITE_STAIRS() * @method static Wall DIORITE_WALL() @@ -291,19 +291,19 @@ use function assert; * @method static Element ELEMENT_XENON() * @method static Element ELEMENT_YTTERBIUM() * @method static Element ELEMENT_YTTRIUM() - * @method static Solid ELEMENT_ZERO() + * @method static Opaque ELEMENT_ZERO() * @method static Element ELEMENT_ZINC() * @method static Element ELEMENT_ZIRCONIUM() - * @method static Solid EMERALD() + * @method static Opaque EMERALD() * @method static EmeraldOre EMERALD_ORE() * @method static EnchantingTable ENCHANTING_TABLE() * @method static EndPortalFrame END_PORTAL_FRAME() * @method static EndRod END_ROD() - * @method static Solid END_STONE() + * @method static Opaque END_STONE() * @method static Slab END_STONE_BRICK_SLAB() * @method static Stair END_STONE_BRICK_STAIRS() * @method static Wall END_STONE_BRICK_WALL() - * @method static Solid END_STONE_BRICKS() + * @method static Opaque END_STONE_BRICKS() * @method static EnderChest ENDER_CHEST() * @method static Slab FAKE_WOODEN_SLAB() * @method static Farmland FARMLAND() @@ -316,9 +316,9 @@ use function assert; * @method static GlassPane GLASS_PANE() * @method static GlowingObsidian GLOWING_OBSIDIAN() * @method static Glowstone GLOWSTONE() - * @method static Solid GOLD() - * @method static Solid GOLD_ORE() - * @method static Solid GRANITE() + * @method static Opaque GOLD() + * @method static Opaque GOLD_ORE() + * @method static Opaque GRANITE() * @method static Slab GRANITE_SLAB() * @method static Stair GRANITE_STAIRS() * @method static Wall GRANITE_WALL() @@ -386,13 +386,13 @@ use function assert; * @method static InfestedStone INFESTED_MOSSY_STONE_BRICK() * @method static InfestedStone INFESTED_STONE() * @method static InfestedStone INFESTED_STONE_BRICK() - * @method static Solid INFO_UPDATE() - * @method static Solid INFO_UPDATE2() + * @method static Opaque INFO_UPDATE() + * @method static Opaque INFO_UPDATE2() * @method static Transparent INVISIBLE_BEDROCK() - * @method static Solid IRON() + * @method static Opaque IRON() * @method static Thin IRON_BARS() * @method static Door IRON_DOOR() - * @method static Solid IRON_ORE() + * @method static Opaque IRON_ORE() * @method static Trapdoor IRON_TRAPDOOR() * @method static ItemFrame ITEM_FRAME() * @method static WoodenButton JUNGLE_BUTTON() @@ -411,11 +411,11 @@ use function assert; * @method static Wood JUNGLE_WOOD() * @method static Ladder LADDER() * @method static Lantern LANTERN() - * @method static Solid LAPIS_LAZULI() + * @method static Opaque LAPIS_LAZULI() * @method static LapisOre LAPIS_LAZULI_ORE() * @method static DoubleTallGrass LARGE_FERN() * @method static Lava LAVA() - * @method static Solid LEGACY_STONECUTTER() + * @method static Opaque LEGACY_STONECUTTER() * @method static Lever LEVER() * @method static Carpet LIGHT_BLUE_CARPET() * @method static Concrete LIGHT_BLUE_CONCRETE() @@ -458,25 +458,25 @@ use function assert; * @method static MelonStem MELON_STEM() * @method static Skull MOB_HEAD() * @method static MonsterSpawner MONSTER_SPAWNER() - * @method static Solid MOSSY_COBBLESTONE() + * @method static Opaque MOSSY_COBBLESTONE() * @method static Slab MOSSY_COBBLESTONE_SLAB() * @method static Stair MOSSY_COBBLESTONE_STAIRS() * @method static Wall MOSSY_COBBLESTONE_WALL() * @method static Slab MOSSY_STONE_BRICK_SLAB() * @method static Stair MOSSY_STONE_BRICK_STAIRS() * @method static Wall MOSSY_STONE_BRICK_WALL() - * @method static Solid MOSSY_STONE_BRICKS() + * @method static Opaque MOSSY_STONE_BRICKS() * @method static Mycelium MYCELIUM() * @method static Fence NETHER_BRICK_FENCE() * @method static Slab NETHER_BRICK_SLAB() * @method static Stair NETHER_BRICK_STAIRS() * @method static Wall NETHER_BRICK_WALL() - * @method static Solid NETHER_BRICKS() + * @method static Opaque NETHER_BRICKS() * @method static NetherPortal NETHER_PORTAL() * @method static NetherQuartzOre NETHER_QUARTZ_ORE() * @method static NetherReactor NETHER_REACTOR_CORE() * @method static NetherWartPlant NETHER_WART() - * @method static Solid NETHER_WART_BLOCK() + * @method static Opaque NETHER_WART_BLOCK() * @method static Netherrack NETHERRACK() * @method static Note NOTE_BLOCK() * @method static WoodenButton OAK_BUTTON() @@ -493,7 +493,7 @@ use function assert; * @method static WoodenStairs OAK_STAIRS() * @method static WoodenTrapdoor OAK_TRAPDOOR() * @method static Wood OAK_WOOD() - * @method static Solid OBSIDIAN() + * @method static Opaque OBSIDIAN() * @method static Carpet ORANGE_CARPET() * @method static Concrete ORANGE_CONCRETE() * @method static ConcretePowder ORANGE_CONCRETE_POWDER() @@ -516,26 +516,26 @@ use function assert; * @method static Flower PINK_TULIP() * @method static Wool PINK_WOOL() * @method static Podzol PODZOL() - * @method static Solid POLISHED_ANDESITE() + * @method static Opaque POLISHED_ANDESITE() * @method static Slab POLISHED_ANDESITE_SLAB() * @method static Stair POLISHED_ANDESITE_STAIRS() - * @method static Solid POLISHED_DIORITE() + * @method static Opaque POLISHED_DIORITE() * @method static Slab POLISHED_DIORITE_SLAB() * @method static Stair POLISHED_DIORITE_STAIRS() - * @method static Solid POLISHED_GRANITE() + * @method static Opaque POLISHED_GRANITE() * @method static Slab POLISHED_GRANITE_SLAB() * @method static Stair POLISHED_GRANITE_STAIRS() * @method static Flower POPPY() * @method static Potato POTATOES() * @method static PoweredRail POWERED_RAIL() - * @method static Solid PRISMARINE() - * @method static Solid PRISMARINE_BRICKS() + * @method static Opaque PRISMARINE() + * @method static Opaque PRISMARINE_BRICKS() * @method static Slab PRISMARINE_BRICKS_SLAB() * @method static Stair PRISMARINE_BRICKS_STAIRS() * @method static Slab PRISMARINE_SLAB() * @method static Stair PRISMARINE_STAIRS() * @method static Wall PRISMARINE_WALL() - * @method static Solid PUMPKIN() + * @method static Opaque PUMPKIN() * @method static PumpkinStem PUMPKIN_STEM() * @method static Carpet PURPLE_CARPET() * @method static Concrete PURPLE_CONCRETE() @@ -546,12 +546,12 @@ use function assert; * @method static GlassPane PURPLE_STAINED_GLASS_PANE() * @method static Torch PURPLE_TORCH() * @method static Wool PURPLE_WOOL() - * @method static Solid PURPUR() - * @method static Solid PURPUR_PILLAR() + * @method static Opaque PURPUR() + * @method static Opaque PURPUR_PILLAR() * @method static Slab PURPUR_SLAB() * @method static Stair PURPUR_STAIRS() - * @method static Solid QUARTZ() - * @method static Solid QUARTZ_PILLAR() + * @method static Opaque QUARTZ() + * @method static Opaque QUARTZ_PILLAR() * @method static Slab QUARTZ_SLAB() * @method static Stair QUARTZ_STAIRS() * @method static Rail RAIL() @@ -564,9 +564,9 @@ use function assert; * @method static Slab RED_NETHER_BRICK_SLAB() * @method static Stair RED_NETHER_BRICK_STAIRS() * @method static Wall RED_NETHER_BRICK_WALL() - * @method static Solid RED_NETHER_BRICKS() + * @method static Opaque RED_NETHER_BRICKS() * @method static Sand RED_SAND() - * @method static Solid RED_SANDSTONE() + * @method static Opaque RED_SANDSTONE() * @method static Slab RED_SANDSTONE_SLAB() * @method static Stair RED_SANDSTONE_STAIRS() * @method static Wall RED_SANDSTONE_WALL() @@ -586,23 +586,23 @@ use function assert; * @method static Reserved6 RESERVED6() * @method static DoublePlant ROSE_BUSH() * @method static Sand SAND() - * @method static Solid SANDSTONE() + * @method static Opaque SANDSTONE() * @method static Slab SANDSTONE_SLAB() * @method static Stair SANDSTONE_STAIRS() * @method static Wall SANDSTONE_WALL() * @method static SeaLantern SEA_LANTERN() * @method static SeaPickle SEA_PICKLE() * @method static Anvil SLIGHTLY_DAMAGED_ANVIL() - * @method static Solid SMOOTH_QUARTZ() + * @method static Opaque SMOOTH_QUARTZ() * @method static Slab SMOOTH_QUARTZ_SLAB() * @method static Stair SMOOTH_QUARTZ_STAIRS() - * @method static Solid SMOOTH_RED_SANDSTONE() + * @method static Opaque SMOOTH_RED_SANDSTONE() * @method static Slab SMOOTH_RED_SANDSTONE_SLAB() * @method static Stair SMOOTH_RED_SANDSTONE_STAIRS() - * @method static Solid SMOOTH_SANDSTONE() + * @method static Opaque SMOOTH_SANDSTONE() * @method static Slab SMOOTH_SANDSTONE_SLAB() * @method static Stair SMOOTH_SANDSTONE_STAIRS() - * @method static Solid SMOOTH_STONE() + * @method static Opaque SMOOTH_STONE() * @method static Slab SMOOTH_STONE_SLAB() * @method static Snow SNOW() * @method static SnowLayer SNOW_LAYER() @@ -622,11 +622,11 @@ use function assert; * @method static WoodenStairs SPRUCE_STAIRS() * @method static WoodenTrapdoor SPRUCE_TRAPDOOR() * @method static Wood SPRUCE_WOOD() - * @method static Solid STONE() + * @method static Opaque STONE() * @method static Slab STONE_BRICK_SLAB() * @method static Stair STONE_BRICK_STAIRS() * @method static Wall STONE_BRICK_WALL() - * @method static Solid STONE_BRICKS() + * @method static Opaque STONE_BRICKS() * @method static StoneButton STONE_BUTTON() * @method static StonePressurePlate STONE_PRESSURE_PLATE() * @method static Slab STONE_SLAB() diff --git a/src/pocketmine/block/Wood.php b/src/pocketmine/block/Wood.php index 31bbeb7df0..a4650749b3 100644 --- a/src/pocketmine/block/Wood.php +++ b/src/pocketmine/block/Wood.php @@ -25,7 +25,7 @@ namespace pocketmine\block; use pocketmine\block\utils\TreeType; -class Wood extends Solid{ +class Wood extends Opaque{ /** @var TreeType */ private $treeType; diff --git a/src/pocketmine/block/Wool.php b/src/pocketmine/block/Wool.php index 63f6bf531a..0154424842 100644 --- a/src/pocketmine/block/Wool.php +++ b/src/pocketmine/block/Wool.php @@ -25,7 +25,7 @@ namespace pocketmine\block; use pocketmine\item\Item; -class Wool extends Solid{ +class Wool extends Opaque{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new class(0.8, BlockToolType::SHEARS) extends BlockBreakInfo{ diff --git a/tests/phpunit/block/MyCustomBlock.php b/tests/phpunit/block/MyCustomBlock.php index 7d21c04048..d0df0261d4 100644 --- a/tests/phpunit/block/MyCustomBlock.php +++ b/tests/phpunit/block/MyCustomBlock.php @@ -23,6 +23,6 @@ declare(strict_types=1); namespace pocketmine\block; -class MyCustomBlock extends Solid{ +class MyCustomBlock extends Opaque{ } diff --git a/tests/phpunit/block/StrangeNewBlock.php b/tests/phpunit/block/StrangeNewBlock.php index 3ffa820202..c505184d08 100644 --- a/tests/phpunit/block/StrangeNewBlock.php +++ b/tests/phpunit/block/StrangeNewBlock.php @@ -23,6 +23,6 @@ declare(strict_types=1); namespace pocketmine\block; -class StrangeNewBlock extends Solid{ +class StrangeNewBlock extends Opaque{ } From a91a86bf1da51628a063dfb367e03443824258c5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Jul 2019 18:07:31 +0100 Subject: [PATCH 1129/3224] Removing achievements --- src/pocketmine/Server.php | 1 - src/pocketmine/entity/object/ItemEntity.php | 8 -- .../player/PlayerAchievementAwardedEvent.php | 92 ------------- .../transaction/CraftingTransaction.php | 44 ------ .../mcpe/handler/InGamePacketHandler.php | 2 - src/pocketmine/player/Achievement.php | 125 ------------------ src/pocketmine/player/Player.php | 78 ----------- 7 files changed, 350 deletions(-) delete mode 100644 src/pocketmine/event/player/PlayerAchievementAwardedEvent.php delete mode 100644 src/pocketmine/player/Achievement.php diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index d42d0e9729..fe5e3ad973 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1006,7 +1006,6 @@ class Server{ "motd" => \pocketmine\NAME . " Server", "server-port" => 19132, "white-list" => false, - "announce-player-achievements" => true, "max-players" => 20, "gamemode" => 0, "force-gamemode" => false, diff --git a/src/pocketmine/entity/object/ItemEntity.php b/src/pocketmine/entity/object/ItemEntity.php index 5c2d2e039a..9aa18233ba 100644 --- a/src/pocketmine/entity/object/ItemEntity.php +++ b/src/pocketmine/entity/object/ItemEntity.php @@ -23,13 +23,11 @@ declare(strict_types=1); namespace pocketmine\entity\object; -use pocketmine\block\Wood; use pocketmine\entity\Entity; use pocketmine\event\entity\ItemDespawnEvent; use pocketmine\event\entity\ItemSpawnEvent; use pocketmine\event\inventory\InventoryPickupItemEvent; use pocketmine\item\Item; -use pocketmine\item\ItemIds; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\AddItemActorPacket; use pocketmine\network\mcpe\protocol\TakeItemActorPacket; @@ -263,12 +261,6 @@ class ItemEntity extends Entity{ return; } - if($item->getBlock() instanceof Wood){ - $player->awardAchievement("mineWood"); - }elseif($item->getId() === ItemIds::DIAMOND){ - $player->awardAchievement("diamond"); - } - $this->server->broadcastPacket($this->getViewers(), TakeItemActorPacket::create($player->getId(), $this->getId())); $playerInventory->addItem(clone $item); diff --git a/src/pocketmine/event/player/PlayerAchievementAwardedEvent.php b/src/pocketmine/event/player/PlayerAchievementAwardedEvent.php deleted file mode 100644 index dfab7b9cef..0000000000 --- a/src/pocketmine/event/player/PlayerAchievementAwardedEvent.php +++ /dev/null @@ -1,92 +0,0 @@ -player = $player; - $this->achievement = $achievementId; - $this->message = $message; - $this->broadcastRecipients = $messageRecipients; - } - - /** - * @return string - */ - public function getAchievement() : string{ - return $this->achievement; - } - - /** - * @return TextContainer|null - */ - public function getMessage() : ?TextContainer{ - return $this->message; - } - - /** - * @param TextContainer|null $message - */ - public function setMessage(?TextContainer $message) : void{ - $this->message = $message; - } - - /** - * @return CommandSender[] - */ - public function getBroadcastRecipients() : array{ - return $this->broadcastRecipients; - } - - /** - * @param CommandSender[] $broadcastRecipients - */ - public function setBroadcastRecipients(array $broadcastRecipients) : void{ - $this->broadcastRecipients = $broadcastRecipients; - } -} diff --git a/src/pocketmine/inventory/transaction/CraftingTransaction.php b/src/pocketmine/inventory/transaction/CraftingTransaction.php index 623b101ff0..6ea0a36400 100644 --- a/src/pocketmine/inventory/transaction/CraftingTransaction.php +++ b/src/pocketmine/inventory/transaction/CraftingTransaction.php @@ -26,7 +26,6 @@ namespace pocketmine\inventory\transaction; use pocketmine\crafting\CraftingRecipe; use pocketmine\event\inventory\CraftItemEvent; use pocketmine\item\Item; -use pocketmine\item\ItemIds; use pocketmine\network\mcpe\protocol\ContainerClosePacket; use pocketmine\network\mcpe\protocol\types\ContainerIds; use function array_pop; @@ -170,47 +169,4 @@ class CraftingTransaction extends InventoryTransaction{ */ $this->source->sendDataPacket(ContainerClosePacket::create(ContainerIds::NONE)); } - - public function execute() : bool{ - if(parent::execute()){ - foreach($this->outputs as $item){ - switch($item->getId()){ - case ItemIds::CRAFTING_TABLE: - $this->source->awardAchievement("buildWorkBench"); - break; - case ItemIds::WOODEN_PICKAXE: - $this->source->awardAchievement("buildPickaxe"); - break; - case ItemIds::FURNACE: - $this->source->awardAchievement("buildFurnace"); - break; - case ItemIds::WOODEN_HOE: - $this->source->awardAchievement("buildHoe"); - break; - case ItemIds::BREAD: - $this->source->awardAchievement("makeBread"); - break; - case ItemIds::CAKE: - $this->source->awardAchievement("bakeCake"); - break; - case ItemIds::STONE_PICKAXE: - case ItemIds::GOLDEN_PICKAXE: - case ItemIds::IRON_PICKAXE: - case ItemIds::DIAMOND_PICKAXE: - $this->source->awardAchievement("buildBetterPickaxe"); - break; - case ItemIds::WOODEN_SWORD: - $this->source->awardAchievement("buildSword"); - break; - case ItemIds::DIAMOND: - $this->source->awardAchievement("diamond"); - break; - } - } - - return true; - } - - return false; - } } diff --git a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php index 8eeb715149..a9ea0ac491 100644 --- a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php @@ -250,8 +250,6 @@ class InGamePacketHandler extends PacketHandler{ return false; } - - //TODO: fix achievement for getting iron from furnace } return true; diff --git a/src/pocketmine/player/Achievement.php b/src/pocketmine/player/Achievement.php deleted file mode 100644 index 5e51468202..0000000000 --- a/src/pocketmine/player/Achievement.php +++ /dev/null @@ -1,125 +0,0 @@ - array( - "name" => "Taking Inventory", - "requires" => [], - ),*/ - "mineWood" => [ - "name" => "Getting Wood", - "requires" => [ //"openInventory", - ] - ], - "buildWorkBench" => [ - "name" => "Benchmarking", - "requires" => [ - "mineWood" - ] - ], - "buildPickaxe" => [ - "name" => "Time to Mine!", - "requires" => [ - "buildWorkBench" - ] - ], - "buildFurnace" => [ - "name" => "Hot Topic", - "requires" => [ - "buildPickaxe" - ] - ], - "acquireIron" => [ - "name" => "Acquire hardware", - "requires" => [ - "buildFurnace" - ] - ], - "buildHoe" => [ - "name" => "Time to Farm!", - "requires" => [ - "buildWorkBench" - ] - ], - "makeBread" => [ - "name" => "Bake Bread", - "requires" => [ - "buildHoe" - ] - ], - "bakeCake" => [ - "name" => "The Lie", - "requires" => [ - "buildHoe" - ] - ], - "buildBetterPickaxe" => [ - "name" => "Getting an Upgrade", - "requires" => [ - "buildPickaxe" - ] - ], - "buildSword" => [ - "name" => "Time to Strike!", - "requires" => [ - "buildWorkBench" - ] - ], - "diamonds" => [ - "name" => "DIAMONDS!", - "requires" => [ - "acquireIron" - ] - ] - - ]; - - /** - * @param string $achievementId - * @param string $achievementName - * @param array $requires - * - * @return bool - */ - public static function add(string $achievementId, string $achievementName, array $requires = []) : bool{ - if(!isset(Achievement::$list[$achievementId])){ - Achievement::$list[$achievementId] = [ - "name" => $achievementName, - "requires" => $requires - ]; - - return true; - } - - return false; - } -} diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 2de37e60b2..3f9d189a99 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -41,7 +41,6 @@ use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\inventory\InventoryCloseEvent; use pocketmine\event\inventory\InventoryOpenEvent; -use pocketmine\event\player\PlayerAchievementAwardedEvent; use pocketmine\event\player\PlayerBedEnterEvent; use pocketmine\event\player\PlayerBedLeaveEvent; use pocketmine\event\player\PlayerBlockPickEvent; @@ -78,7 +77,6 @@ use pocketmine\item\ItemUseResult; use pocketmine\lang\TextContainer; use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; -use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\IntTag; @@ -108,7 +106,6 @@ use pocketmine\world\particle\PunchBlockParticle; use pocketmine\world\Position; use pocketmine\world\World; use function abs; -use function array_filter; use function assert; use function ceil; use function count; @@ -190,8 +187,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** @var bool */ protected $removeFormat = true; - /** @var bool[] name of achievement => bool */ - protected $achievements = []; /** @var int */ protected $firstPlayed; /** @var int */ @@ -370,15 +365,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->setNameTagAlwaysVisible(); $this->setCanClimb(); - $this->achievements = []; - $achievements = $nbt->getCompoundTag("Achievements"); - if($achievements !== null){ - /** @var ByteTag $tag */ - foreach($achievements as $name => $tag){ - $this->achievements[$name] = $tag->getValue() !== 0; - } - } - if(!$this->hasValidSpawnPosition()){ if(($world = $this->server->getWorldManager()->getWorldByName($nbt->getString("SpawnLevel", ""))) instanceof World){ $this->spawnPosition = new Position($nbt->getInt("SpawnX"), $nbt->getInt("SpawnY"), $nbt->getInt("SpawnZ"), $world); @@ -1122,64 +1108,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } - /** - * @param string $achievementId - * - * @return bool - */ - public function hasAchievement(string $achievementId) : bool{ - if(!isset(Achievement::$list[$achievementId])){ - return false; - } - - return $this->achievements[$achievementId] ?? false; - } - - /** - * @param string $achievementId - * - * @return bool - */ - public function awardAchievement(string $achievementId) : bool{ - if(isset(Achievement::$list[$achievementId]) and !$this->hasAchievement($achievementId)){ - foreach(Achievement::$list[$achievementId]["requires"] as $requirementId){ - if(!$this->hasAchievement($requirementId)){ - return false; - } - } - $ev = new PlayerAchievementAwardedEvent( - $this, - $achievementId, - new TranslationContainer("chat.type.achievement", [$this->getDisplayName(), TextFormat::GREEN . Achievement::$list[$achievementId]["name"] . TextFormat::RESET]), - $this->server->getConfigBool("announce-player-achievements", true) ? array_filter(PermissionManager::getInstance()->getPermissionSubscriptions(Server::BROADCAST_CHANNEL_USERS), function($v){ - return $v instanceof CommandSender; - }) : [$this] - ); - $ev->call(); - if(!$ev->isCancelled()){ - $this->achievements[$achievementId] = true; - if(($message = $ev->getMessage()) !== null){ - $this->server->broadcastMessage($message, $ev->getBroadcastRecipients()); - } - - return true; - }else{ - return false; - } - } - - return false; - } - - /** - * @param string $achievementId - */ - public function removeAchievement(string $achievementId){ - if($this->hasAchievement($achievementId)){ - $this->achievements[$achievementId] = false; - } - } - /** * @return GameMode */ @@ -2334,12 +2262,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } - $achievements = new CompoundTag(); - foreach($this->achievements as $achievement => $status){ - $achievements->setByte($achievement, $status ? 1 : 0); - } - $nbt->setTag("Achievements", $achievements); - $nbt->setInt("playerGameType", $this->gamemode->getMagicNumber()); $nbt->setLong("firstPlayed", $this->firstPlayed); $nbt->setLong("lastPlayed", (int) floor(microtime(true) * 1000)); From 7275952fc21a71c13adf86fcc9626de6995eb87a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Jul 2019 19:08:50 +0100 Subject: [PATCH 1130/3224] added some missing legacy ID constants i'm not sure why my script missed these --- src/pocketmine/block/BlockLegacyIds.php | 3 ++- src/pocketmine/item/ItemIds.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/block/BlockLegacyIds.php b/src/pocketmine/block/BlockLegacyIds.php index 67e110a60a..4a1d521c00 100644 --- a/src/pocketmine/block/BlockLegacyIds.php +++ b/src/pocketmine/block/BlockLegacyIds.php @@ -477,7 +477,7 @@ interface BlockLegacyIds{ public const BLAST_FURNACE = 451; public const STONECUTTER_BLOCK = 452; public const SMOKER = 453; - + public const LIT_SMOKER = 454; public const CARTOGRAPHY_TABLE = 455; public const FLETCHING_TABLE = 456; public const SMITHING_TABLE = 457; @@ -492,5 +492,6 @@ interface BlockLegacyIds{ public const JIGSAW = 466; public const WOOD = 467; public const COMPOSTER = 468; + public const LIT_BLAST_FURNACE = 469; } diff --git a/src/pocketmine/item/ItemIds.php b/src/pocketmine/item/ItemIds.php index 01c999e2da..0aadcf4e0a 100644 --- a/src/pocketmine/item/ItemIds.php +++ b/src/pocketmine/item/ItemIds.php @@ -25,6 +25,7 @@ namespace pocketmine\item; interface ItemIds{ + public const LIT_BLAST_FURNACE = -214; public const COMPOSTER = -213; public const WOOD = -212; public const JIGSAW = -211; @@ -39,7 +40,7 @@ interface ItemIds{ public const SMITHING_TABLE = -202; public const FLETCHING_TABLE = -201; public const CARTOGRAPHY_TABLE = -200; - + public const LIT_SMOKER = -199; public const SMOKER = -198; public const STONECUTTER_BLOCK = -197; public const BLAST_FURNACE = -196; From c9ecd0435346be779bca58bdf89a3356b3cf0ff5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Jul 2019 19:10:18 +0100 Subject: [PATCH 1131/3224] rename DataPropertyManager -> EntityMetadataCollection --- src/pocketmine/entity/Entity.php | 8 ++++---- ...taPropertyManager.php => EntityMetadataCollection.php} | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) rename src/pocketmine/network/mcpe/protocol/types/{DataPropertyManager.php => EntityMetadataCollection.php} (99%) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 0155feedd0..3aafc2b0b7 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -51,7 +51,7 @@ use pocketmine\network\mcpe\protocol\MoveActorAbsolutePacket; use pocketmine\network\mcpe\protocol\RemoveActorPacket; use pocketmine\network\mcpe\protocol\SetActorDataPacket; use pocketmine\network\mcpe\protocol\SetActorMotionPacket; -use pocketmine\network\mcpe\protocol\types\DataPropertyManager; +use pocketmine\network\mcpe\protocol\types\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\EntityMetadataTypes; @@ -92,7 +92,7 @@ abstract class Entity extends Location{ /** @var int */ protected $id; - /** @var DataPropertyManager */ + /** @var EntityMetadataCollection */ protected $propertyManager; /** @var Chunk|null */ @@ -232,7 +232,7 @@ abstract class Entity extends Location{ $this->resetLastMovements(); - $this->propertyManager = new DataPropertyManager(); + $this->propertyManager = new EntityMetadataCollection(); $this->propertyManager->setLong(EntityMetadataProperties::FLAGS, 0); $this->propertyManager->setShort(EntityMetadataProperties::MAX_AIR, 400); @@ -708,7 +708,7 @@ abstract class Entity extends Location{ return $this->attributeMap; } - public function getDataPropertyManager() : DataPropertyManager{ + public function getDataPropertyManager() : EntityMetadataCollection{ return $this->propertyManager; } diff --git a/src/pocketmine/network/mcpe/protocol/types/DataPropertyManager.php b/src/pocketmine/network/mcpe/protocol/types/EntityMetadataCollection.php similarity index 99% rename from src/pocketmine/network/mcpe/protocol/types/DataPropertyManager.php rename to src/pocketmine/network/mcpe/protocol/types/EntityMetadataCollection.php index 8a24c5869a..1fca87d66d 100644 --- a/src/pocketmine/network/mcpe/protocol/types/DataPropertyManager.php +++ b/src/pocketmine/network/mcpe/protocol/types/EntityMetadataCollection.php @@ -30,7 +30,7 @@ use function is_float; use function is_int; use function is_string; -class DataPropertyManager{ +class EntityMetadataCollection{ private $properties = []; From 379a40c13af95163bb42de9c6bf011db2d70a09d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Jul 2019 19:18:36 +0100 Subject: [PATCH 1132/3224] break up the pocketmine\network\mcpe\protocol\types namespace this namespace nesting is getting out of hand, but it's more manageable this way. --- src/pocketmine/entity/Animal.php | 2 +- src/pocketmine/entity/Entity.php | 8 ++++---- src/pocketmine/entity/EntityFactory.php | 2 +- src/pocketmine/entity/Human.php | 6 +++--- src/pocketmine/entity/Living.php | 4 ++-- src/pocketmine/entity/Squid.php | 2 +- src/pocketmine/entity/Villager.php | 6 +++--- src/pocketmine/entity/WaterAnimal.php | 2 +- src/pocketmine/entity/Zombie.php | 2 +- src/pocketmine/entity/effect/EffectManager.php | 2 +- src/pocketmine/entity/object/ExperienceOrb.php | 4 ++-- src/pocketmine/entity/object/FallingBlock.php | 4 ++-- src/pocketmine/entity/object/ItemEntity.php | 2 +- src/pocketmine/entity/object/Painting.php | 2 +- src/pocketmine/entity/object/PrimedTNT.php | 6 +++--- src/pocketmine/entity/projectile/Arrow.php | 4 ++-- src/pocketmine/entity/projectile/Egg.php | 2 +- src/pocketmine/entity/projectile/EnderPearl.php | 2 +- .../entity/projectile/ExperienceBottle.php | 2 +- src/pocketmine/entity/projectile/Snowball.php | 2 +- src/pocketmine/entity/projectile/SplashPotion.php | 6 +++--- .../inventory/transaction/CraftingTransaction.php | 2 +- src/pocketmine/network/mcpe/InventoryManager.php | 4 ++-- src/pocketmine/network/mcpe/NetworkSession.php | 8 ++++---- .../network/mcpe/handler/InGamePacketHandler.php | 10 +++++----- .../network/mcpe/protocol/AddActorPacket.php | 4 ++-- .../network/mcpe/protocol/AddPlayerPacket.php | 2 +- .../mcpe/protocol/AvailableCommandsPacket.php | 6 +++--- .../network/mcpe/protocol/CommandOutputPacket.php | 4 ++-- .../network/mcpe/protocol/CommandRequestPacket.php | 2 +- .../mcpe/protocol/InventoryTransactionPacket.php | 12 ++++++------ .../network/mcpe/protocol/PlayerHotbarPacket.php | 2 +- .../network/mcpe/protocol/SetActorLinkPacket.php | 2 +- .../network/mcpe/protocol/UpdateTradePacket.php | 2 +- .../protocol/types/{ => command}/CommandData.php | 5 ++++- .../protocol/types/{ => command}/CommandEnum.php | 2 +- .../types/{ => command}/CommandOriginData.php | 2 +- .../types/{ => command}/CommandOutputMessage.php | 2 +- .../types/{ => command}/CommandParameter.php | 3 ++- .../protocol/types/{ => entity}/EntityLegacyIds.php | 2 +- .../mcpe/protocol/types/{ => entity}/EntityLink.php | 2 +- .../types/{ => entity}/EntityMetadataCollection.php | 3 ++- .../types/{ => entity}/EntityMetadataFlags.php | 2 +- .../types/{ => entity}/EntityMetadataProperties.php | 2 +- .../types/{ => entity}/EntityMetadataTypes.php | 2 +- .../types/{ => entity}/PlayerMetadataFlags.php | 2 +- .../protocol/types/{ => inventory}/ContainerIds.php | 2 +- .../{ => inventory}/MismatchTransactionData.php | 3 ++- .../types/{ => inventory}/NetworkInventoryAction.php | 2 +- .../types/{ => inventory}/NormalTransactionData.php | 4 +++- .../{ => inventory}/ReleaseItemTransactionData.php | 3 ++- .../types/{ => inventory}/TransactionData.php | 3 ++- .../UseItemOnEntityTransactionData.php | 3 ++- .../types/{ => inventory}/UseItemTransactionData.php | 3 ++- .../protocol/types/{ => inventory}/WindowTypes.php | 2 +- .../network/mcpe/serializer/NetworkBinaryStream.php | 12 ++++++------ src/pocketmine/player/Player.php | 6 +++--- .../world/particle/FloatingTextParticle.php | 6 +++--- 58 files changed, 111 insertions(+), 99 deletions(-) rename src/pocketmine/network/mcpe/protocol/types/{ => command}/CommandData.php (92%) rename src/pocketmine/network/mcpe/protocol/types/{ => command}/CommandEnum.php (95%) rename src/pocketmine/network/mcpe/protocol/types/{ => command}/CommandOriginData.php (96%) rename src/pocketmine/network/mcpe/protocol/types/{ => command}/CommandOutputMessage.php (93%) rename src/pocketmine/network/mcpe/protocol/types/{ => command}/CommandParameter.php (94%) rename src/pocketmine/network/mcpe/protocol/types/{ => entity}/EntityLegacyIds.php (98%) rename src/pocketmine/network/mcpe/protocol/types/{ => entity}/EntityLink.php (95%) rename src/pocketmine/network/mcpe/protocol/types/{ => entity}/EntityMetadataCollection.php (98%) rename src/pocketmine/network/mcpe/protocol/types/{ => entity}/EntityMetadataFlags.php (98%) rename src/pocketmine/network/mcpe/protocol/types/{ => entity}/EntityMetadataProperties.php (99%) rename src/pocketmine/network/mcpe/protocol/types/{ => entity}/EntityMetadataTypes.php (94%) rename src/pocketmine/network/mcpe/protocol/types/{ => entity}/PlayerMetadataFlags.php (93%) rename src/pocketmine/network/mcpe/protocol/types/{ => inventory}/ContainerIds.php (94%) rename src/pocketmine/network/mcpe/protocol/types/{ => inventory}/MismatchTransactionData.php (91%) rename src/pocketmine/network/mcpe/protocol/types/{ => inventory}/NetworkInventoryAction.php (99%) rename src/pocketmine/network/mcpe/protocol/types/{ => inventory}/NormalTransactionData.php (86%) rename src/pocketmine/network/mcpe/protocol/types/{ => inventory}/ReleaseItemTransactionData.php (95%) rename src/pocketmine/network/mcpe/protocol/types/{ => inventory}/TransactionData.php (93%) rename src/pocketmine/network/mcpe/protocol/types/{ => inventory}/UseItemOnEntityTransactionData.php (96%) rename src/pocketmine/network/mcpe/protocol/types/{ => inventory}/UseItemTransactionData.php (96%) rename src/pocketmine/network/mcpe/protocol/types/{ => inventory}/WindowTypes.php (96%) diff --git a/src/pocketmine/entity/Animal.php b/src/pocketmine/entity/Animal.php index 3d5b26384d..28ee08417c 100644 --- a/src/pocketmine/entity/Animal.php +++ b/src/pocketmine/entity/Animal.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity; -use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; abstract class Animal extends Living implements Ageable{ diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 3aafc2b0b7..8bd71020ab 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -51,10 +51,10 @@ use pocketmine\network\mcpe\protocol\MoveActorAbsolutePacket; use pocketmine\network\mcpe\protocol\RemoveActorPacket; use pocketmine\network\mcpe\protocol\SetActorDataPacket; use pocketmine\network\mcpe\protocol\SetActorMotionPacket; -use pocketmine\network\mcpe\protocol\types\EntityMetadataCollection; -use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; -use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; -use pocketmine\network\mcpe\protocol\types\EntityMetadataTypes; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataTypes; use pocketmine\player\Player; use pocketmine\Server; use pocketmine\timings\Timings; diff --git a/src/pocketmine/entity/EntityFactory.php b/src/pocketmine/entity/EntityFactory.php index 4441ed2741..b4b17fafb0 100644 --- a/src/pocketmine/entity/EntityFactory.php +++ b/src/pocketmine/entity/EntityFactory.php @@ -42,7 +42,7 @@ use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; -use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\utils\Utils; use pocketmine\world\World; use function array_keys; diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index e72a5b494b..daacc7264a 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -45,10 +45,10 @@ use pocketmine\network\mcpe\protocol\ActorEventPacket; use pocketmine\network\mcpe\protocol\AddPlayerPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\PlayerSkinPacket; -use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; -use pocketmine\network\mcpe\protocol\types\EntityMetadataTypes; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataTypes; +use pocketmine\network\mcpe\protocol\types\entity\PlayerMetadataFlags; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; -use pocketmine\network\mcpe\protocol\types\PlayerMetadataFlags; use pocketmine\player\Player; use pocketmine\utils\UUID; use pocketmine\world\sound\TotemUseSound; diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index b56b484b70..b10231c12a 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -46,8 +46,8 @@ use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ShortTag; use pocketmine\network\mcpe\protocol\ActorEventPacket; -use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; -use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\player\Player; use pocketmine\timings\Timings; use pocketmine\utils\Binary; diff --git a/src/pocketmine/entity/Squid.php b/src/pocketmine/entity/Squid.php index dd6935d570..d2e5cc00e4 100644 --- a/src/pocketmine/entity/Squid.php +++ b/src/pocketmine/entity/Squid.php @@ -29,7 +29,7 @@ use pocketmine\item\VanillaItems; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\ActorEventPacket; -use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use function atan2; use function mt_rand; use function sqrt; diff --git a/src/pocketmine/entity/Villager.php b/src/pocketmine/entity/Villager.php index 9d684c8355..417964eba0 100644 --- a/src/pocketmine/entity/Villager.php +++ b/src/pocketmine/entity/Villager.php @@ -24,9 +24,9 @@ declare(strict_types=1); namespace pocketmine\entity; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; -use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; -use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; +use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; class Villager extends Living implements Ageable{ public const PROFESSION_FARMER = 0; diff --git a/src/pocketmine/entity/WaterAnimal.php b/src/pocketmine/entity/WaterAnimal.php index fc724462e8..a98f8b1923 100644 --- a/src/pocketmine/entity/WaterAnimal.php +++ b/src/pocketmine/entity/WaterAnimal.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity; use pocketmine\event\entity\EntityDamageEvent; -use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; abstract class WaterAnimal extends Living implements Ageable{ diff --git a/src/pocketmine/entity/Zombie.php b/src/pocketmine/entity/Zombie.php index b1cf5cd470..a33b191d77 100644 --- a/src/pocketmine/entity/Zombie.php +++ b/src/pocketmine/entity/Zombie.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity; use pocketmine\item\VanillaItems; -use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use function mt_rand; class Zombie extends Living{ diff --git a/src/pocketmine/entity/effect/EffectManager.php b/src/pocketmine/entity/effect/EffectManager.php index 3885b2cef9..b8f88ac294 100644 --- a/src/pocketmine/entity/effect/EffectManager.php +++ b/src/pocketmine/entity/effect/EffectManager.php @@ -26,7 +26,7 @@ namespace pocketmine\entity\effect; use pocketmine\entity\Living; use pocketmine\event\entity\EntityEffectAddEvent; use pocketmine\event\entity\EntityEffectRemoveEvent; -use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\utils\Color; use function abs; diff --git a/src/pocketmine/entity/object/ExperienceOrb.php b/src/pocketmine/entity/object/ExperienceOrb.php index 9c7e830209..6d89b372e9 100644 --- a/src/pocketmine/entity/object/ExperienceOrb.php +++ b/src/pocketmine/entity/object/ExperienceOrb.php @@ -28,8 +28,8 @@ use pocketmine\entity\Human; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ShortTag; -use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; -use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; +use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\player\Player; use function sqrt; diff --git a/src/pocketmine/entity/object/FallingBlock.php b/src/pocketmine/entity/object/FallingBlock.php index 7f6debc0aa..db7ef94b62 100644 --- a/src/pocketmine/entity/object/FallingBlock.php +++ b/src/pocketmine/entity/object/FallingBlock.php @@ -32,8 +32,8 @@ use pocketmine\event\entity\EntityDamageEvent; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; -use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; -use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; +use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use function get_class; class FallingBlock extends Entity{ diff --git a/src/pocketmine/entity/object/ItemEntity.php b/src/pocketmine/entity/object/ItemEntity.php index 9aa18233ba..085c5a754a 100644 --- a/src/pocketmine/entity/object/ItemEntity.php +++ b/src/pocketmine/entity/object/ItemEntity.php @@ -31,7 +31,7 @@ use pocketmine\item\Item; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\AddItemActorPacket; use pocketmine\network\mcpe\protocol\TakeItemActorPacket; -use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\player\Player; use function get_class; use function max; diff --git a/src/pocketmine/entity/object/Painting.php b/src/pocketmine/entity/object/Painting.php index eb0318a1df..a678040697 100644 --- a/src/pocketmine/entity/object/Painting.php +++ b/src/pocketmine/entity/object/Painting.php @@ -34,7 +34,7 @@ use pocketmine\math\Vector3; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\AddPaintingPacket; -use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\player\Player; use pocketmine\world\particle\DestroyBlockParticle; use pocketmine\world\World; diff --git a/src/pocketmine/entity/object/PrimedTNT.php b/src/pocketmine/entity/object/PrimedTNT.php index 0a4f8364c7..755325c587 100644 --- a/src/pocketmine/entity/object/PrimedTNT.php +++ b/src/pocketmine/entity/object/PrimedTNT.php @@ -29,9 +29,9 @@ use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\ExplosionPrimeEvent; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ShortTag; -use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; -use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; -use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; +use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\world\Explosion; use pocketmine\world\Position; use pocketmine\world\sound\IgniteSound; diff --git a/src/pocketmine/entity/projectile/Arrow.php b/src/pocketmine/entity/projectile/Arrow.php index f38551b9e2..25a32e35a3 100644 --- a/src/pocketmine/entity/projectile/Arrow.php +++ b/src/pocketmine/entity/projectile/Arrow.php @@ -32,8 +32,8 @@ use pocketmine\math\RayTraceResult; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\ActorEventPacket; use pocketmine\network\mcpe\protocol\TakeItemActorPacket; -use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; -use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; +use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\player\Player; use pocketmine\world\sound\ArrowHitSound; use pocketmine\world\World; diff --git a/src/pocketmine/entity/projectile/Egg.php b/src/pocketmine/entity/projectile/Egg.php index c736bf2885..367dc2e7b7 100644 --- a/src/pocketmine/entity/projectile/Egg.php +++ b/src/pocketmine/entity/projectile/Egg.php @@ -25,7 +25,7 @@ namespace pocketmine\entity\projectile; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\item\VanillaItems; -use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\world\particle\ItemBreakParticle; class Egg extends Throwable{ diff --git a/src/pocketmine/entity/projectile/EnderPearl.php b/src/pocketmine/entity/projectile/EnderPearl.php index c438903dcc..bf7d6d2f7c 100644 --- a/src/pocketmine/entity/projectile/EnderPearl.php +++ b/src/pocketmine/entity/projectile/EnderPearl.php @@ -30,7 +30,7 @@ use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\math\AxisAlignedBB; use pocketmine\math\RayTraceResult; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\world\particle\EndermanTeleportParticle; use pocketmine\world\sound\EndermanTeleportSound; diff --git a/src/pocketmine/entity/projectile/ExperienceBottle.php b/src/pocketmine/entity/projectile/ExperienceBottle.php index 879eb627d3..95c0a9465b 100644 --- a/src/pocketmine/entity/projectile/ExperienceBottle.php +++ b/src/pocketmine/entity/projectile/ExperienceBottle.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity\projectile; use pocketmine\event\entity\ProjectileHitEvent; -use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\world\particle\PotionSplashParticle; use pocketmine\world\sound\PotionSplashSound; use function mt_rand; diff --git a/src/pocketmine/entity/projectile/Snowball.php b/src/pocketmine/entity/projectile/Snowball.php index ccaab45982..6e7d090840 100644 --- a/src/pocketmine/entity/projectile/Snowball.php +++ b/src/pocketmine/entity/projectile/Snowball.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity\projectile; use pocketmine\event\entity\ProjectileHitEvent; -use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\world\particle\SnowballPoofParticle; class Snowball extends Throwable{ diff --git a/src/pocketmine/entity/projectile/SplashPotion.php b/src/pocketmine/entity/projectile/SplashPotion.php index 343037f017..7d589dd201 100644 --- a/src/pocketmine/entity/projectile/SplashPotion.php +++ b/src/pocketmine/entity/projectile/SplashPotion.php @@ -33,9 +33,9 @@ use pocketmine\event\entity\ProjectileHitEntityEvent; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\item\Potion; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; -use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; -use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; +use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\utils\Color; use pocketmine\world\particle\PotionSplashParticle; use pocketmine\world\sound\PotionSplashSound; diff --git a/src/pocketmine/inventory/transaction/CraftingTransaction.php b/src/pocketmine/inventory/transaction/CraftingTransaction.php index 6ea0a36400..8b710278fe 100644 --- a/src/pocketmine/inventory/transaction/CraftingTransaction.php +++ b/src/pocketmine/inventory/transaction/CraftingTransaction.php @@ -27,7 +27,7 @@ use pocketmine\crafting\CraftingRecipe; use pocketmine\event\inventory\CraftItemEvent; use pocketmine\item\Item; use pocketmine\network\mcpe\protocol\ContainerClosePacket; -use pocketmine\network\mcpe\protocol\types\ContainerIds; +use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; use function array_pop; use function count; use function intdiv; diff --git a/src/pocketmine/network/mcpe/InventoryManager.php b/src/pocketmine/network/mcpe/InventoryManager.php index b88e240ed1..f98a46b5af 100644 --- a/src/pocketmine/network/mcpe/InventoryManager.php +++ b/src/pocketmine/network/mcpe/InventoryManager.php @@ -37,8 +37,8 @@ use pocketmine\network\mcpe\protocol\ContainerSetDataPacket; use pocketmine\network\mcpe\protocol\InventoryContentPacket; use pocketmine\network\mcpe\protocol\InventorySlotPacket; use pocketmine\network\mcpe\protocol\PlayerHotbarPacket; -use pocketmine\network\mcpe\protocol\types\ContainerIds; -use pocketmine\network\mcpe\protocol\types\WindowTypes; +use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; +use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes; use pocketmine\player\Player; use function array_search; use function max; diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/pocketmine/network/mcpe/NetworkSession.php index 048d2e7789..5acf0394b5 100644 --- a/src/pocketmine/network/mcpe/NetworkSession.php +++ b/src/pocketmine/network/mcpe/NetworkSession.php @@ -66,10 +66,10 @@ use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket; use pocketmine\network\mcpe\protocol\TextPacket; use pocketmine\network\mcpe\protocol\TransferPacket; -use pocketmine\network\mcpe\protocol\types\CommandData; -use pocketmine\network\mcpe\protocol\types\CommandEnum; -use pocketmine\network\mcpe\protocol\types\CommandParameter; -use pocketmine\network\mcpe\protocol\types\ContainerIds; +use pocketmine\network\mcpe\protocol\types\command\CommandData; +use pocketmine\network\mcpe\protocol\types\command\CommandEnum; +use pocketmine\network\mcpe\protocol\types\command\CommandParameter; +use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; diff --git a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php index a9ea0ac491..7478472ae6 100644 --- a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php @@ -75,11 +75,11 @@ use pocketmine\network\mcpe\protocol\ShowCreditsPacket; use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket; use pocketmine\network\mcpe\protocol\SubClientLoginPacket; use pocketmine\network\mcpe\protocol\TextPacket; -use pocketmine\network\mcpe\protocol\types\MismatchTransactionData; -use pocketmine\network\mcpe\protocol\types\NormalTransactionData; -use pocketmine\network\mcpe\protocol\types\ReleaseItemTransactionData; -use pocketmine\network\mcpe\protocol\types\UseItemOnEntityTransactionData; -use pocketmine\network\mcpe\protocol\types\UseItemTransactionData; +use pocketmine\network\mcpe\protocol\types\inventory\MismatchTransactionData; +use pocketmine\network\mcpe\protocol\types\inventory\NormalTransactionData; +use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData; +use pocketmine\network\mcpe\protocol\types\inventory\UseItemOnEntityTransactionData; +use pocketmine\network\mcpe\protocol\types\inventory\UseItemTransactionData; use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; use pocketmine\player\Player; use function array_push; diff --git a/src/pocketmine/network/mcpe/protocol/AddActorPacket.php b/src/pocketmine/network/mcpe/protocol/AddActorPacket.php index 6a875d3368..e854484f29 100644 --- a/src/pocketmine/network/mcpe/protocol/AddActorPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddActorPacket.php @@ -29,8 +29,8 @@ use pocketmine\entity\Attribute; use pocketmine\math\Vector3; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\PacketHandler; -use pocketmine\network\mcpe\protocol\types\EntityLegacyIds; -use pocketmine\network\mcpe\protocol\types\EntityLink; +use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityLink; use function array_search; use function count; diff --git a/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php b/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php index cc2c172b50..10a5964c39 100644 --- a/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php @@ -28,7 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; -use pocketmine\network\mcpe\protocol\types\EntityLink; +use pocketmine\network\mcpe\protocol\types\entity\EntityLink; use pocketmine\utils\UUID; use function count; diff --git a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php index a1d165c21d..efcda29ed5 100644 --- a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php @@ -27,9 +27,9 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\PacketHandler; -use pocketmine\network\mcpe\protocol\types\CommandData; -use pocketmine\network\mcpe\protocol\types\CommandEnum; -use pocketmine\network\mcpe\protocol\types\CommandParameter; +use pocketmine\network\mcpe\protocol\types\command\CommandData; +use pocketmine\network\mcpe\protocol\types\command\CommandEnum; +use pocketmine\network\mcpe\protocol\types\command\CommandParameter; use pocketmine\utils\BinaryDataException; use function count; use function dechex; diff --git a/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php b/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php index b05450d28e..36ac89a2c8 100644 --- a/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php @@ -26,8 +26,8 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; -use pocketmine\network\mcpe\protocol\types\CommandOriginData; -use pocketmine\network\mcpe\protocol\types\CommandOutputMessage; +use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; +use pocketmine\network\mcpe\protocol\types\command\CommandOutputMessage; use pocketmine\utils\BinaryDataException; use function count; diff --git a/src/pocketmine/network/mcpe/protocol/CommandRequestPacket.php b/src/pocketmine/network/mcpe/protocol/CommandRequestPacket.php index a0d009a032..293acb1dbb 100644 --- a/src/pocketmine/network/mcpe/protocol/CommandRequestPacket.php +++ b/src/pocketmine/network/mcpe/protocol/CommandRequestPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; -use pocketmine\network\mcpe\protocol\types\CommandOriginData; +use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; class CommandRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::COMMAND_REQUEST_PACKET; diff --git a/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php b/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php index 9eed4cd8f9..a4cb59f834 100644 --- a/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php +++ b/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php @@ -27,12 +27,12 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\PacketHandler; -use pocketmine\network\mcpe\protocol\types\MismatchTransactionData; -use pocketmine\network\mcpe\protocol\types\NormalTransactionData; -use pocketmine\network\mcpe\protocol\types\ReleaseItemTransactionData; -use pocketmine\network\mcpe\protocol\types\TransactionData; -use pocketmine\network\mcpe\protocol\types\UseItemOnEntityTransactionData; -use pocketmine\network\mcpe\protocol\types\UseItemTransactionData; +use pocketmine\network\mcpe\protocol\types\inventory\MismatchTransactionData; +use pocketmine\network\mcpe\protocol\types\inventory\NormalTransactionData; +use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData; +use pocketmine\network\mcpe\protocol\types\inventory\TransactionData; +use pocketmine\network\mcpe\protocol\types\inventory\UseItemOnEntityTransactionData; +use pocketmine\network\mcpe\protocol\types\inventory\UseItemTransactionData; /** * This packet effectively crams multiple packets into one. diff --git a/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php b/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php index 02a98a81ef..e0c9e53fb0 100644 --- a/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php +++ b/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; -use pocketmine\network\mcpe\protocol\types\ContainerIds; +use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; class PlayerHotbarPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAYER_HOTBAR_PACKET; diff --git a/src/pocketmine/network/mcpe/protocol/SetActorLinkPacket.php b/src/pocketmine/network/mcpe/protocol/SetActorLinkPacket.php index 91b3a91eee..a8cfbb4210 100644 --- a/src/pocketmine/network/mcpe/protocol/SetActorLinkPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetActorLinkPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; -use pocketmine\network\mcpe\protocol\types\EntityLink; +use pocketmine\network\mcpe\protocol\types\entity\EntityLink; class SetActorLinkPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_ACTOR_LINK_PACKET; diff --git a/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php b/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php index 28c65d2594..bfb0537f0b 100644 --- a/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php +++ b/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php @@ -28,7 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; -use pocketmine\network\mcpe\protocol\types\WindowTypes; +use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes; class UpdateTradePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_TRADE_PACKET; diff --git a/src/pocketmine/network/mcpe/protocol/types/CommandData.php b/src/pocketmine/network/mcpe/protocol/types/command/CommandData.php similarity index 92% rename from src/pocketmine/network/mcpe/protocol/types/CommandData.php rename to src/pocketmine/network/mcpe/protocol/types/command/CommandData.php index 95bab22534..5cb462813b 100644 --- a/src/pocketmine/network/mcpe/protocol/types/CommandData.php +++ b/src/pocketmine/network/mcpe/protocol/types/command/CommandData.php @@ -21,7 +21,10 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\command; + +use pocketmine\network\mcpe\protocol\types\command\CommandEnum; +use pocketmine\network\mcpe\protocol\types\command\CommandParameter; class CommandData{ /** @var string */ diff --git a/src/pocketmine/network/mcpe/protocol/types/CommandEnum.php b/src/pocketmine/network/mcpe/protocol/types/command/CommandEnum.php similarity index 95% rename from src/pocketmine/network/mcpe/protocol/types/CommandEnum.php rename to src/pocketmine/network/mcpe/protocol/types/command/CommandEnum.php index 02597e90e5..2a46c260bd 100644 --- a/src/pocketmine/network/mcpe/protocol/types/CommandEnum.php +++ b/src/pocketmine/network/mcpe/protocol/types/command/CommandEnum.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\command; class CommandEnum{ /** @var string */ diff --git a/src/pocketmine/network/mcpe/protocol/types/CommandOriginData.php b/src/pocketmine/network/mcpe/protocol/types/command/CommandOriginData.php similarity index 96% rename from src/pocketmine/network/mcpe/protocol/types/CommandOriginData.php rename to src/pocketmine/network/mcpe/protocol/types/command/CommandOriginData.php index ca35b39f76..4214f8a0e5 100644 --- a/src/pocketmine/network/mcpe/protocol/types/CommandOriginData.php +++ b/src/pocketmine/network/mcpe/protocol/types/command/CommandOriginData.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\command; use pocketmine\utils\UUID; diff --git a/src/pocketmine/network/mcpe/protocol/types/CommandOutputMessage.php b/src/pocketmine/network/mcpe/protocol/types/command/CommandOutputMessage.php similarity index 93% rename from src/pocketmine/network/mcpe/protocol/types/CommandOutputMessage.php rename to src/pocketmine/network/mcpe/protocol/types/command/CommandOutputMessage.php index a2434f9905..1bb18c2a3a 100644 --- a/src/pocketmine/network/mcpe/protocol/types/CommandOutputMessage.php +++ b/src/pocketmine/network/mcpe/protocol/types/command/CommandOutputMessage.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\command; class CommandOutputMessage{ /** @var bool */ diff --git a/src/pocketmine/network/mcpe/protocol/types/CommandParameter.php b/src/pocketmine/network/mcpe/protocol/types/command/CommandParameter.php similarity index 94% rename from src/pocketmine/network/mcpe/protocol/types/CommandParameter.php rename to src/pocketmine/network/mcpe/protocol/types/command/CommandParameter.php index d19c7b9a81..8234e099bc 100644 --- a/src/pocketmine/network/mcpe/protocol/types/CommandParameter.php +++ b/src/pocketmine/network/mcpe/protocol/types/command/CommandParameter.php @@ -21,9 +21,10 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\command; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; +use pocketmine\network\mcpe\protocol\types\command\CommandEnum; class CommandParameter{ /** @var string */ diff --git a/src/pocketmine/network/mcpe/protocol/types/EntityLegacyIds.php b/src/pocketmine/network/mcpe/protocol/types/entity/EntityLegacyIds.php similarity index 98% rename from src/pocketmine/network/mcpe/protocol/types/EntityLegacyIds.php rename to src/pocketmine/network/mcpe/protocol/types/entity/EntityLegacyIds.php index caa93bb2ac..a59e0a628a 100644 --- a/src/pocketmine/network/mcpe/protocol/types/EntityLegacyIds.php +++ b/src/pocketmine/network/mcpe/protocol/types/entity/EntityLegacyIds.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\entity; final class EntityLegacyIds{ diff --git a/src/pocketmine/network/mcpe/protocol/types/EntityLink.php b/src/pocketmine/network/mcpe/protocol/types/entity/EntityLink.php similarity index 95% rename from src/pocketmine/network/mcpe/protocol/types/EntityLink.php rename to src/pocketmine/network/mcpe/protocol/types/entity/EntityLink.php index c5386e682d..1f35615b00 100644 --- a/src/pocketmine/network/mcpe/protocol/types/EntityLink.php +++ b/src/pocketmine/network/mcpe/protocol/types/entity/EntityLink.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\entity; class EntityLink{ diff --git a/src/pocketmine/network/mcpe/protocol/types/EntityMetadataCollection.php b/src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataCollection.php similarity index 98% rename from src/pocketmine/network/mcpe/protocol/types/EntityMetadataCollection.php rename to src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataCollection.php index 1fca87d66d..c56f5be5ca 100644 --- a/src/pocketmine/network/mcpe/protocol/types/EntityMetadataCollection.php +++ b/src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataCollection.php @@ -21,10 +21,11 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\entity; use pocketmine\item\Item; use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataTypes; use function assert; use function is_float; use function is_int; diff --git a/src/pocketmine/network/mcpe/protocol/types/EntityMetadataFlags.php b/src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataFlags.php similarity index 98% rename from src/pocketmine/network/mcpe/protocol/types/EntityMetadataFlags.php rename to src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataFlags.php index 566cf5ae1e..906ab32525 100644 --- a/src/pocketmine/network/mcpe/protocol/types/EntityMetadataFlags.php +++ b/src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataFlags.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\entity; final class EntityMetadataFlags{ diff --git a/src/pocketmine/network/mcpe/protocol/types/EntityMetadataProperties.php b/src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataProperties.php similarity index 99% rename from src/pocketmine/network/mcpe/protocol/types/EntityMetadataProperties.php rename to src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataProperties.php index 7318f118f1..67b4e6e010 100644 --- a/src/pocketmine/network/mcpe/protocol/types/EntityMetadataProperties.php +++ b/src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataProperties.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\entity; final class EntityMetadataProperties{ diff --git a/src/pocketmine/network/mcpe/protocol/types/EntityMetadataTypes.php b/src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataTypes.php similarity index 94% rename from src/pocketmine/network/mcpe/protocol/types/EntityMetadataTypes.php rename to src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataTypes.php index d3d9f1569e..5aeaccf783 100644 --- a/src/pocketmine/network/mcpe/protocol/types/EntityMetadataTypes.php +++ b/src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataTypes.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\entity; final class EntityMetadataTypes{ diff --git a/src/pocketmine/network/mcpe/protocol/types/PlayerMetadataFlags.php b/src/pocketmine/network/mcpe/protocol/types/entity/PlayerMetadataFlags.php similarity index 93% rename from src/pocketmine/network/mcpe/protocol/types/PlayerMetadataFlags.php rename to src/pocketmine/network/mcpe/protocol/types/entity/PlayerMetadataFlags.php index 015229ecca..65f73abc3f 100644 --- a/src/pocketmine/network/mcpe/protocol/types/PlayerMetadataFlags.php +++ b/src/pocketmine/network/mcpe/protocol/types/entity/PlayerMetadataFlags.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\entity; final class PlayerMetadataFlags{ diff --git a/src/pocketmine/network/mcpe/protocol/types/ContainerIds.php b/src/pocketmine/network/mcpe/protocol/types/inventory/ContainerIds.php similarity index 94% rename from src/pocketmine/network/mcpe/protocol/types/ContainerIds.php rename to src/pocketmine/network/mcpe/protocol/types/inventory/ContainerIds.php index 3b55065e51..6a9e70ba34 100644 --- a/src/pocketmine/network/mcpe/protocol/types/ContainerIds.php +++ b/src/pocketmine/network/mcpe/protocol/types/inventory/ContainerIds.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\inventory; interface ContainerIds{ diff --git a/src/pocketmine/network/mcpe/protocol/types/MismatchTransactionData.php b/src/pocketmine/network/mcpe/protocol/types/inventory/MismatchTransactionData.php similarity index 91% rename from src/pocketmine/network/mcpe/protocol/types/MismatchTransactionData.php rename to src/pocketmine/network/mcpe/protocol/types/inventory/MismatchTransactionData.php index 3cf69f5c2e..d34d6c4b0b 100644 --- a/src/pocketmine/network/mcpe/protocol/types/MismatchTransactionData.php +++ b/src/pocketmine/network/mcpe/protocol/types/inventory/MismatchTransactionData.php @@ -21,10 +21,11 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; +use pocketmine\network\mcpe\protocol\types\inventory\TransactionData; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; diff --git a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php b/src/pocketmine/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php similarity index 99% rename from src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php rename to src/pocketmine/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php index 4a195f58c2..00b05f4f32 100644 --- a/src/pocketmine/network/mcpe/protocol/types/NetworkInventoryAction.php +++ b/src/pocketmine/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\inventory\AnvilInventory; use pocketmine\inventory\EnchantInventory; diff --git a/src/pocketmine/network/mcpe/protocol/types/NormalTransactionData.php b/src/pocketmine/network/mcpe/protocol/types/inventory/NormalTransactionData.php similarity index 86% rename from src/pocketmine/network/mcpe/protocol/types/NormalTransactionData.php rename to src/pocketmine/network/mcpe/protocol/types/inventory/NormalTransactionData.php index cb4e8c3ba0..70cc893050 100644 --- a/src/pocketmine/network/mcpe/protocol/types/NormalTransactionData.php +++ b/src/pocketmine/network/mcpe/protocol/types/inventory/NormalTransactionData.php @@ -21,9 +21,11 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; +use pocketmine\network\mcpe\protocol\types\inventory\TransactionData; +use pocketmine\network\mcpe\protocol\types\inventory\NetworkInventoryAction; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class NormalTransactionData extends TransactionData{ diff --git a/src/pocketmine/network/mcpe/protocol/types/ReleaseItemTransactionData.php b/src/pocketmine/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php similarity index 95% rename from src/pocketmine/network/mcpe/protocol/types/ReleaseItemTransactionData.php rename to src/pocketmine/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php index 9e5d374fa7..70e081c1d4 100644 --- a/src/pocketmine/network/mcpe/protocol/types/ReleaseItemTransactionData.php +++ b/src/pocketmine/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php @@ -21,11 +21,12 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; +use pocketmine\network\mcpe\protocol\types\inventory\TransactionData; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ReleaseItemTransactionData extends TransactionData{ diff --git a/src/pocketmine/network/mcpe/protocol/types/TransactionData.php b/src/pocketmine/network/mcpe/protocol/types/inventory/TransactionData.php similarity index 93% rename from src/pocketmine/network/mcpe/protocol/types/TransactionData.php rename to src/pocketmine/network/mcpe/protocol/types/inventory/TransactionData.php index b2e084cb8b..2f37b629c5 100644 --- a/src/pocketmine/network/mcpe/protocol/types/TransactionData.php +++ b/src/pocketmine/network/mcpe/protocol/types/inventory/TransactionData.php @@ -21,9 +21,10 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\network\BadPacketException; +use pocketmine\network\mcpe\protocol\types\inventory\NetworkInventoryAction; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; use function count; diff --git a/src/pocketmine/network/mcpe/protocol/types/UseItemOnEntityTransactionData.php b/src/pocketmine/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php similarity index 96% rename from src/pocketmine/network/mcpe/protocol/types/UseItemOnEntityTransactionData.php rename to src/pocketmine/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php index c3e7c61175..7cd1c3d830 100644 --- a/src/pocketmine/network/mcpe/protocol/types/UseItemOnEntityTransactionData.php +++ b/src/pocketmine/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php @@ -21,11 +21,12 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; +use pocketmine\network\mcpe\protocol\types\inventory\TransactionData; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class UseItemOnEntityTransactionData extends TransactionData{ diff --git a/src/pocketmine/network/mcpe/protocol/types/UseItemTransactionData.php b/src/pocketmine/network/mcpe/protocol/types/inventory/UseItemTransactionData.php similarity index 96% rename from src/pocketmine/network/mcpe/protocol/types/UseItemTransactionData.php rename to src/pocketmine/network/mcpe/protocol/types/inventory/UseItemTransactionData.php index 0959687a35..893ea25058 100644 --- a/src/pocketmine/network/mcpe/protocol/types/UseItemTransactionData.php +++ b/src/pocketmine/network/mcpe/protocol/types/inventory/UseItemTransactionData.php @@ -21,11 +21,12 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; +use pocketmine\network\mcpe\protocol\types\inventory\TransactionData; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class UseItemTransactionData extends TransactionData{ diff --git a/src/pocketmine/network/mcpe/protocol/types/WindowTypes.php b/src/pocketmine/network/mcpe/protocol/types/inventory/WindowTypes.php similarity index 96% rename from src/pocketmine/network/mcpe/protocol/types/WindowTypes.php rename to src/pocketmine/network/mcpe/protocol/types/inventory/WindowTypes.php index b13fd191f5..1f1edbdf77 100644 --- a/src/pocketmine/network/mcpe/protocol/types/WindowTypes.php +++ b/src/pocketmine/network/mcpe/protocol/types/inventory/WindowTypes.php @@ -22,7 +22,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\inventory; interface WindowTypes{ diff --git a/src/pocketmine/network/mcpe/serializer/NetworkBinaryStream.php b/src/pocketmine/network/mcpe/serializer/NetworkBinaryStream.php index a9eabe378d..7a4cd1318b 100644 --- a/src/pocketmine/network/mcpe/serializer/NetworkBinaryStream.php +++ b/src/pocketmine/network/mcpe/serializer/NetworkBinaryStream.php @@ -36,9 +36,9 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\TreeRoot; use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\protocol\types\CommandOriginData; -use pocketmine\network\mcpe\protocol\types\EntityLink; -use pocketmine\network\mcpe\protocol\types\EntityMetadataTypes; +use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; +use pocketmine\network\mcpe\protocol\types\entity\EntityLink; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataTypes; use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; use pocketmine\utils\UUID; @@ -595,7 +595,7 @@ class NetworkBinaryStream extends BinaryStream{ } /** - * @return EntityLink + * @return \pocketmine\network\mcpe\protocol\types\entity\EntityLink * * @throws BinaryDataException */ @@ -611,7 +611,7 @@ class NetworkBinaryStream extends BinaryStream{ } /** - * @param EntityLink $link + * @param \pocketmine\network\mcpe\protocol\types\entity\EntityLink $link */ protected function putEntityLink(EntityLink $link) : void{ $this->putEntityUniqueId($link->fromEntityUniqueId); @@ -621,7 +621,7 @@ class NetworkBinaryStream extends BinaryStream{ } /** - * @return CommandOriginData + * @return \pocketmine\network\mcpe\protocol\types\command\CommandOriginData * @throws BinaryDataException */ protected function getCommandOriginData() : CommandOriginData{ diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 3f9d189a99..1e883c137b 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -88,9 +88,9 @@ use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\SetTitlePacket; -use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; -use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; -use pocketmine\network\mcpe\protocol\types\PlayerMetadataFlags; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; +use pocketmine\network\mcpe\protocol\types\entity\PlayerMetadataFlags; use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissibleDelegateTrait; use pocketmine\permission\PermissionManager; diff --git a/src/pocketmine/world/particle/FloatingTextParticle.php b/src/pocketmine/world/particle/FloatingTextParticle.php index 5ad9d78d32..6deb6b6ac4 100644 --- a/src/pocketmine/world/particle/FloatingTextParticle.php +++ b/src/pocketmine/world/particle/FloatingTextParticle.php @@ -30,9 +30,9 @@ use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\AddPlayerPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\RemoveActorPacket; -use pocketmine\network\mcpe\protocol\types\EntityMetadataFlags; -use pocketmine\network\mcpe\protocol\types\EntityMetadataProperties; -use pocketmine\network\mcpe\protocol\types\EntityMetadataTypes; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataTypes; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\utils\UUID; use function str_repeat; From 6c0ae6bf0bf848d507a0f3823f0e59efec0d818d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Jul 2019 19:22:33 +0100 Subject: [PATCH 1133/3224] fuck off PhpStorm --- .../protocol/types/inventory/NetworkInventoryAction.php | 4 ++-- .../mcpe/protocol/types/inventory/TransactionData.php | 5 ++--- .../network/mcpe/serializer/NetworkBinaryStream.php | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/pocketmine/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php b/src/pocketmine/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php index 00b05f4f32..213e2c3ec8 100644 --- a/src/pocketmine/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php +++ b/src/pocketmine/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php @@ -97,7 +97,7 @@ class NetworkInventoryAction{ public $newItem; /** - * @param \pocketmine\network\mcpe\serializer\NetworkBinaryStream $packet + * @param NetworkBinaryStream $packet * * @return $this * @@ -132,7 +132,7 @@ class NetworkInventoryAction{ } /** - * @param \pocketmine\network\mcpe\serializer\NetworkBinaryStream $packet + * @param NetworkBinaryStream $packet * * @throws \InvalidArgumentException */ diff --git a/src/pocketmine/network/mcpe/protocol/types/inventory/TransactionData.php b/src/pocketmine/network/mcpe/protocol/types/inventory/TransactionData.php index 2f37b629c5..a58d037809 100644 --- a/src/pocketmine/network/mcpe/protocol/types/inventory/TransactionData.php +++ b/src/pocketmine/network/mcpe/protocol/types/inventory/TransactionData.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\protocol\types\inventory\NetworkInventoryAction; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; use function count; @@ -46,7 +45,7 @@ abstract class TransactionData{ abstract public function getTypeId() : int; /** - * @param \pocketmine\network\mcpe\serializer\NetworkBinaryStream $stream + * @param NetworkBinaryStream $stream * * @throws BinaryDataException * @throws BadPacketException @@ -60,7 +59,7 @@ abstract class TransactionData{ } /** - * @param \pocketmine\network\mcpe\serializer\NetworkBinaryStream $stream + * @param NetworkBinaryStream $stream * * @throws BinaryDataException * @throws BadPacketException diff --git a/src/pocketmine/network/mcpe/serializer/NetworkBinaryStream.php b/src/pocketmine/network/mcpe/serializer/NetworkBinaryStream.php index 7a4cd1318b..173b99f2df 100644 --- a/src/pocketmine/network/mcpe/serializer/NetworkBinaryStream.php +++ b/src/pocketmine/network/mcpe/serializer/NetworkBinaryStream.php @@ -595,7 +595,7 @@ class NetworkBinaryStream extends BinaryStream{ } /** - * @return \pocketmine\network\mcpe\protocol\types\entity\EntityLink + * @return EntityLink * * @throws BinaryDataException */ @@ -611,7 +611,7 @@ class NetworkBinaryStream extends BinaryStream{ } /** - * @param \pocketmine\network\mcpe\protocol\types\entity\EntityLink $link + * @param EntityLink $link */ protected function putEntityLink(EntityLink $link) : void{ $this->putEntityUniqueId($link->fromEntityUniqueId); @@ -621,7 +621,7 @@ class NetworkBinaryStream extends BinaryStream{ } /** - * @return \pocketmine\network\mcpe\protocol\types\command\CommandOriginData + * @return CommandOriginData * @throws BinaryDataException */ protected function getCommandOriginData() : CommandOriginData{ From e06ab0869a9f8c26f71c529b21f7659cc3f7c2fb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 28 Jul 2019 19:40:47 +0100 Subject: [PATCH 1134/3224] mostly rewrite internal entity metadata handling - Only sync the metadata set when needed for sending - Don't use metadata set for storing data, add properties instead - Use objects inside metadata sets instead of arrays --- src/pocketmine/entity/Animal.php | 9 +- src/pocketmine/entity/Entity.php | 212 ++++++++--------- src/pocketmine/entity/Human.php | 31 +-- src/pocketmine/entity/Living.php | 35 ++- src/pocketmine/entity/Villager.php | 18 +- src/pocketmine/entity/WaterAnimal.php | 9 +- .../entity/effect/EffectManager.php | 30 ++- .../entity/object/ExperienceOrb.php | 15 +- src/pocketmine/entity/object/FallingBlock.php | 8 +- src/pocketmine/entity/object/ItemEntity.php | 2 +- src/pocketmine/entity/object/PrimedTNT.php | 21 +- src/pocketmine/entity/projectile/Arrow.php | 13 +- .../entity/projectile/SplashPotion.php | 22 +- .../network/mcpe/protocol/AddActorPacket.php | 3 +- .../mcpe/protocol/AddItemActorPacket.php | 3 +- .../network/mcpe/protocol/AddPlayerPacket.php | 3 +- .../mcpe/protocol/SetActorDataPacket.php | 4 +- .../types/entity/BlockPosMetadataProperty.php | 65 +++++ .../types/entity/ByteMetadataProperty.php | 50 ++++ .../types/entity/EntityMetadataCollection.php | 222 +++++------------- .../types/entity/FloatMetadataProperty.php | 62 +++++ .../types/entity/IntMetadataProperty.php | 50 ++++ .../entity/IntegerishMetadataProperty.php | 64 +++++ .../entity/ItemStackMetadataProperty.php | 62 +++++ .../types/entity/LongMetadataProperty.php | 52 ++++ .../types/entity/MetadataProperty.php | 35 +++ .../types/entity/ShortMetadataProperty.php | 50 ++++ .../types/entity/StringMetadataProperty.php | 54 +++++ .../types/entity/Vec3MetadataProperty.php | 62 +++++ .../mcpe/serializer/NetworkBinaryStream.php | 116 +++------ src/pocketmine/player/Player.php | 19 +- .../world/particle/FloatingTextParticle.php | 7 +- 32 files changed, 958 insertions(+), 450 deletions(-) create mode 100644 src/pocketmine/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/entity/ByteMetadataProperty.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/entity/FloatMetadataProperty.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/entity/IntMetadataProperty.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/entity/ItemStackMetadataProperty.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/entity/LongMetadataProperty.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/entity/MetadataProperty.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/entity/ShortMetadataProperty.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/entity/StringMetadataProperty.php create mode 100644 src/pocketmine/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php diff --git a/src/pocketmine/entity/Animal.php b/src/pocketmine/entity/Animal.php index 28ee08417c..09fd1c685f 100644 --- a/src/pocketmine/entity/Animal.php +++ b/src/pocketmine/entity/Animal.php @@ -27,8 +27,15 @@ namespace pocketmine\entity; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; abstract class Animal extends Living implements Ageable{ + /** @var bool */ + protected $baby = false; public function isBaby() : bool{ - return $this->getGenericFlag(EntityMetadataFlags::BABY); + return $this->baby; + } + + protected function syncNetworkData() : void{ + parent::syncNetworkData(); + $this->propertyManager->setGenericFlag(EntityMetadataFlags::BABY, $this->baby); } } diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 8bd71020ab..0cbeb014a2 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -54,7 +54,7 @@ use pocketmine\network\mcpe\protocol\SetActorMotionPacket; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; -use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataTypes; +use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; use pocketmine\player\Player; use pocketmine\Server; use pocketmine\timings\Timings; @@ -195,6 +195,35 @@ abstract class Entity extends Location{ /** @var TimingsHandler */ protected $timings; + /** @var string */ + protected $nameTag = ""; + /** @var bool */ + protected $nameTagVisible = true; + /** @var bool */ + protected $alwaysShowNameTag = false; + /** @var string */ + protected $scoreTag = ""; + /** @var float */ + protected $scale = 1.0; + + /** @var bool */ + protected $canClimb = false; + /** @var bool */ + protected $canClimbWalls = false; + /** @var bool */ + protected $immobile = false; + /** @var bool */ + protected $invisible = false; + /** @var bool */ + protected $sneaking = false; + /** @var bool */ + protected $sprinting = false; + + /** @var int|null */ + protected $ownerId = null; + /** @var int|null */ + protected $targetId = null; + public function __construct(World $world, CompoundTag $nbt){ $this->timings = Timings::getEntityTimings($this); @@ -234,22 +263,10 @@ abstract class Entity extends Location{ $this->propertyManager = new EntityMetadataCollection(); - $this->propertyManager->setLong(EntityMetadataProperties::FLAGS, 0); - $this->propertyManager->setShort(EntityMetadataProperties::MAX_AIR, 400); - $this->propertyManager->setString(EntityMetadataProperties::NAMETAG, ""); - $this->propertyManager->setLong(EntityMetadataProperties::LEAD_HOLDER_EID, -1); - $this->propertyManager->setFloat(EntityMetadataProperties::SCALE, 1); - $this->propertyManager->setFloat(EntityMetadataProperties::BOUNDING_BOX_WIDTH, $this->width); - $this->propertyManager->setFloat(EntityMetadataProperties::BOUNDING_BOX_HEIGHT, $this->height); - $this->attributeMap = new AttributeMap(); $this->addAttributes(); - $this->setGenericFlag(EntityMetadataFlags::AFFECTED_BY_GRAVITY, true); - $this->setGenericFlag(EntityMetadataFlags::HAS_COLLISION, true); - $this->initEntity($nbt); - $this->propertyManager->clearDirtyProperties(); //Prevents resending properties that were set during construction $this->chunk->addEntity($this); $this->world->addEntity($this); @@ -265,64 +282,63 @@ abstract class Entity extends Location{ * @return string */ public function getNameTag() : string{ - return $this->propertyManager->getString(EntityMetadataProperties::NAMETAG); + return $this->nameTag; } /** * @return bool */ public function isNameTagVisible() : bool{ - return $this->getGenericFlag(EntityMetadataFlags::CAN_SHOW_NAMETAG); + return $this->nameTagVisible; } /** * @return bool */ public function isNameTagAlwaysVisible() : bool{ - return $this->propertyManager->getByte(EntityMetadataProperties::ALWAYS_SHOW_NAMETAG) === 1; + return $this->alwaysShowNameTag; } - /** * @param string $name */ public function setNameTag(string $name) : void{ - $this->propertyManager->setString(EntityMetadataProperties::NAMETAG, $name); + $this->nameTag = $name; } /** * @param bool $value */ public function setNameTagVisible(bool $value = true) : void{ - $this->setGenericFlag(EntityMetadataFlags::CAN_SHOW_NAMETAG, $value); + $this->nameTagVisible = $value; } /** * @param bool $value */ public function setNameTagAlwaysVisible(bool $value = true) : void{ - $this->propertyManager->setByte(EntityMetadataProperties::ALWAYS_SHOW_NAMETAG, $value ? 1 : 0); + $this->alwaysShowNameTag = $value; } /** * @return string|null */ public function getScoreTag() : ?string{ - return $this->propertyManager->getString(EntityMetadataProperties::SCORE_TAG); + return $this->scoreTag; //TODO: maybe this shouldn't be nullable? } /** * @param string $score */ public function setScoreTag(string $score) : void{ - $this->propertyManager->setString(EntityMetadataProperties::SCORE_TAG, $score); + $this->scoreTag = $score; } /** * @return float */ public function getScale() : float{ - return $this->propertyManager->getFloat(EntityMetadataProperties::SCALE); + return $this->scale; } /** @@ -338,9 +354,9 @@ abstract class Entity extends Location{ $this->height *= $multiplier; $this->eyeHeight *= $multiplier; - $this->recalculateBoundingBox(); + $this->scale = $value; - $this->propertyManager->setFloat(EntityMetadataProperties::SCALE, $value); + $this->recalculateBoundingBox(); } public function getBoundingBox() : AxisAlignedBB{ @@ -361,39 +377,39 @@ abstract class Entity extends Location{ } public function isSneaking() : bool{ - return $this->getGenericFlag(EntityMetadataFlags::SNEAKING); + return $this->sneaking; } public function setSneaking(bool $value = true) : void{ - $this->setGenericFlag(EntityMetadataFlags::SNEAKING, $value); + $this->sneaking = $value; } public function isSprinting() : bool{ - return $this->getGenericFlag(EntityMetadataFlags::SPRINTING); + return $this->sprinting; } public function setSprinting(bool $value = true) : void{ if($value !== $this->isSprinting()){ - $this->setGenericFlag(EntityMetadataFlags::SPRINTING, $value); + $this->sprinting = $value; $attr = $this->attributeMap->getAttribute(Attribute::MOVEMENT_SPEED); $attr->setValue($value ? ($attr->getValue() * 1.3) : ($attr->getValue() / 1.3), false, true); } } public function isImmobile() : bool{ - return $this->getGenericFlag(EntityMetadataFlags::IMMOBILE); + return $this->immobile; } public function setImmobile(bool $value = true) : void{ - $this->setGenericFlag(EntityMetadataFlags::IMMOBILE, $value); + $this->immobile = $value; } public function isInvisible() : bool{ - return $this->getGenericFlag(EntityMetadataFlags::INVISIBLE); + return $this->invisible; } public function setInvisible(bool $value = true) : void{ - $this->setGenericFlag(EntityMetadataFlags::INVISIBLE, $value); + $this->invisible = $value; } /** @@ -401,7 +417,7 @@ abstract class Entity extends Location{ * @return bool */ public function canClimb() : bool{ - return $this->getGenericFlag(EntityMetadataFlags::CAN_CLIMB); + return $this->canClimb; } /** @@ -410,7 +426,7 @@ abstract class Entity extends Location{ * @param bool $value */ public function setCanClimb(bool $value = true) : void{ - $this->setGenericFlag(EntityMetadataFlags::CAN_CLIMB, $value); + $this->canClimb = $value; } /** @@ -419,7 +435,7 @@ abstract class Entity extends Location{ * @return bool */ public function canClimbWalls() : bool{ - return $this->getGenericFlag(EntityMetadataFlags::WALLCLIMBING); + return $this->canClimbWalls; } /** @@ -428,7 +444,7 @@ abstract class Entity extends Location{ * @param bool $value */ public function setCanClimbWalls(bool $value = true) : void{ - $this->setGenericFlag(EntityMetadataFlags::WALLCLIMBING, $value); + $this->canClimbWalls = $value; } /** @@ -436,7 +452,7 @@ abstract class Entity extends Location{ * @return int|null */ public function getOwningEntityId() : ?int{ - return $this->propertyManager->getLong(EntityMetadataProperties::OWNER_EID); + return $this->ownerId; } /** @@ -444,12 +460,7 @@ abstract class Entity extends Location{ * @return Entity|null */ public function getOwningEntity() : ?Entity{ - $eid = $this->getOwningEntityId(); - if($eid !== null){ - return $this->server->getWorldManager()->findEntity($eid); - } - - return null; + return $this->ownerId !== null ? $this->server->getWorldManager()->findEntity($this->ownerId) : null; } /** @@ -461,11 +472,11 @@ abstract class Entity extends Location{ */ public function setOwningEntity(?Entity $owner) : void{ if($owner === null){ - $this->propertyManager->removeProperty(EntityMetadataProperties::OWNER_EID); + $this->ownerId = null; }elseif($owner->closed){ throw new \InvalidArgumentException("Supplied owning entity is garbage and cannot be used"); }else{ - $this->propertyManager->setLong(EntityMetadataProperties::OWNER_EID, $owner->getId()); + $this->ownerId = $owner->getId(); } } @@ -474,7 +485,7 @@ abstract class Entity extends Location{ * @return int|null */ public function getTargetEntityId() : ?int{ - return $this->propertyManager->getLong(EntityMetadataProperties::TARGET_EID); + return $this->targetId; } /** @@ -484,12 +495,7 @@ abstract class Entity extends Location{ * @return Entity|null */ public function getTargetEntity() : ?Entity{ - $eid = $this->getTargetEntityId(); - if($eid !== null){ - return $this->server->getWorldManager()->findEntity($eid); - } - - return null; + return $this->targetId !== null ? $this->server->getWorldManager()->findEntity($eid) : null; } /** @@ -501,11 +507,11 @@ abstract class Entity extends Location{ */ public function setTargetEntity(?Entity $target) : void{ if($target === null){ - $this->propertyManager->removeProperty(EntityMetadataProperties::TARGET_EID); + $this->targetId = null; }elseif($target->closed){ throw new \InvalidArgumentException("Supplied target entity is garbage and cannot be used"); }else{ - $this->propertyManager->setLong(EntityMetadataProperties::TARGET_EID, $target->getId()); + $this->targetId = $target->getId(); } } @@ -557,7 +563,6 @@ abstract class Entity extends Location{ $nbt->setFloat("FallDistance", $this->fallDistance); $nbt->setShort("Fire", $this->fireTicks); - $nbt->setShort("Air", $this->propertyManager->getShort(EntityMetadataProperties::AIR)); $nbt->setByte("OnGround", $this->onGround ? 1 : 0); $nbt->setByte("Invulnerable", $this->invulnerable ? 1 : 0); @@ -566,11 +571,7 @@ abstract class Entity extends Location{ protected function initEntity(CompoundTag $nbt) : void{ $this->fireTicks = $nbt->getShort("Fire", 0); - if($this->isOnFire()){ - $this->setGenericFlag(EntityMetadataFlags::ONFIRE); - } - $this->propertyManager->setShort(EntityMetadataProperties::AIR, $nbt->getShort("Air", 300)); $this->onGround = $nbt->getByte("OnGround", 0) !== 0; $this->invulnerable = $nbt->getByte("Invulnerable", 0) !== 0; @@ -717,7 +718,7 @@ abstract class Entity extends Location{ $this->justCreated = false; - $changedProperties = $this->propertyManager->getDirty(); + $changedProperties = $this->getSyncedNetworkData(true); if(!empty($changedProperties)){ $this->sendData($this->hasSpawned, $changedProperties); $this->propertyManager->clearDirtyProperties(); @@ -758,8 +759,6 @@ abstract class Entity extends Location{ if($ticks > $this->getFireTicks()){ $this->setFireTicks($ticks); } - - $this->setGenericFlag(EntityMetadataFlags::ONFIRE, $this->isOnFire()); } /** @@ -782,7 +781,6 @@ abstract class Entity extends Location{ public function extinguish() : void{ $this->fireTicks = 0; - $this->setGenericFlag(EntityMetadataFlags::ONFIRE, false); } public function isFireProof() : bool{ @@ -1601,7 +1599,7 @@ abstract class Entity extends Location{ $pk->headYaw = $this->yaw; //TODO $pk->pitch = $this->pitch; $pk->attributes = $this->attributeMap->getAll(); - $pk->metadata = $this->propertyManager->getAll(); + $pk->metadata = $this->getSyncedNetworkData(false); $player->sendDataPacket($pk); } @@ -1716,60 +1714,15 @@ abstract class Entity extends Location{ } /** - * @param int $propertyId - * @param int $flagId - * @param bool $value - * @param int $propertyType - */ - public function setDataFlag(int $propertyId, int $flagId, bool $value = true, int $propertyType = EntityMetadataTypes::LONG) : void{ - if($this->getDataFlag($propertyId, $flagId) !== $value){ - $flags = (int) $this->propertyManager->getPropertyValue($propertyId, $propertyType); - $flags ^= 1 << $flagId; - $this->propertyManager->setPropertyValue($propertyId, $propertyType, $flags); - } - } - - /** - * @param int $propertyId - * @param int $flagId - * - * @return bool - */ - public function getDataFlag(int $propertyId, int $flagId) : bool{ - return (((int) $this->propertyManager->getPropertyValue($propertyId, -1)) & (1 << $flagId)) > 0; - } - - /** - * Wrapper around {@link Entity#getDataFlag} for generic data flag reading. - * - * @param int $flagId - * - * @return bool - */ - public function getGenericFlag(int $flagId) : bool{ - return $this->getDataFlag($flagId >= 64 ? EntityMetadataProperties::FLAGS2 : EntityMetadataProperties::FLAGS, $flagId % 64); - } - - /** - * Wrapper around {@link Entity#setDataFlag} for generic data flag setting. - * - * @param int $flagId - * @param bool $value - */ - public function setGenericFlag(int $flagId, bool $value = true) : void{ - $this->setDataFlag($flagId >= 64 ? EntityMetadataProperties::FLAGS2 : EntityMetadataProperties::FLAGS, $flagId % 64, $value, EntityMetadataTypes::LONG); - } - - /** - * @param Player[]|Player $player - * @param array $data Properly formatted entity data, defaults to everything + * @param Player[]|Player $player + * @param MetadataProperty[] $data Properly formatted entity data, defaults to everything */ public function sendData($player, ?array $data = null) : void{ if(!is_array($player)){ $player = [$player]; } - $pk = SetActorDataPacket::create($this->getId(), $data ?? $this->propertyManager->getAll()); + $pk = SetActorDataPacket::create($this->getId(), $data ?? $this->getSyncedNetworkData(false)); foreach($player as $p){ if($p === $this){ @@ -1783,6 +1736,39 @@ abstract class Entity extends Location{ } } + /** + * @param bool $dirtyOnly + * + * @return MetadataProperty[] + */ + final protected function getSyncedNetworkData(bool $dirtyOnly) : array{ + $this->syncNetworkData(); + + return $dirtyOnly ? $this->propertyManager->getDirty() : $this->propertyManager->getAll(); + } + + protected function syncNetworkData() : void{ + $this->propertyManager->setByte(EntityMetadataProperties::ALWAYS_SHOW_NAMETAG, $this->alwaysShowNameTag ? 1 : 0); + $this->propertyManager->setFloat(EntityMetadataProperties::BOUNDING_BOX_HEIGHT, $this->height); + $this->propertyManager->setFloat(EntityMetadataProperties::BOUNDING_BOX_WIDTH, $this->width); + $this->propertyManager->setFloat(EntityMetadataProperties::SCALE, $this->scale); + $this->propertyManager->setLong(EntityMetadataProperties::LEAD_HOLDER_EID, -1); + $this->propertyManager->setLong(EntityMetadataProperties::OWNER_EID, $this->ownerId ?? -1); + $this->propertyManager->setLong(EntityMetadataProperties::TARGET_EID, $this->targetId ?? -1); + $this->propertyManager->setString(EntityMetadataProperties::NAMETAG, $this->nameTag); + $this->propertyManager->setString(EntityMetadataProperties::SCORE_TAG, $this->scoreTag); + + $this->propertyManager->setGenericFlag(EntityMetadataFlags::AFFECTED_BY_GRAVITY, true); + $this->propertyManager->setGenericFlag(EntityMetadataFlags::CAN_CLIMB, $this->canClimb); + $this->propertyManager->setGenericFlag(EntityMetadataFlags::CAN_SHOW_NAMETAG, $this->nameTagVisible); + $this->propertyManager->setGenericFlag(EntityMetadataFlags::HAS_COLLISION, true); + $this->propertyManager->setGenericFlag(EntityMetadataFlags::IMMOBILE, $this->immobile); + $this->propertyManager->setGenericFlag(EntityMetadataFlags::INVISIBLE, $this->invisible); + $this->propertyManager->setGenericFlag(EntityMetadataFlags::ONFIRE, $this->isOnFire()); + $this->propertyManager->setGenericFlag(EntityMetadataFlags::SNEAKING, $this->sneaking); + $this->propertyManager->setGenericFlag(EntityMetadataFlags::WALLCLIMBING, $this->canClimbWalls); + } + public function broadcastEntityEvent(int $eventId, ?int $eventData = null, ?array $players = null) : void{ $this->server->broadcastPacket($players ?? $this->getViewers(), ActorEventPacket::create($this->id, $eventId, $eventData ?? 0)); } diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index daacc7264a..c17d1d2bc5 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -46,8 +46,7 @@ use pocketmine\network\mcpe\protocol\AddPlayerPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\PlayerSkinPacket; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; -use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataTypes; -use pocketmine\network\mcpe\protocol\types\entity\PlayerMetadataFlags; +use pocketmine\network\mcpe\protocol\types\entity\StringMetadataProperty; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\player\Player; use pocketmine\utils\UUID; @@ -228,9 +227,6 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $this->hungerManager = new HungerManager($this); $this->xpManager = new ExperienceManager($this); - $this->setPlayerFlag(PlayerMetadataFlags::SLEEP, false); - $this->propertyManager->setBlockPos(EntityMetadataProperties::PLAYER_BED_POSITION, null); - $this->inventory = new PlayerInventory($this); $this->enderChestInventory = new EnderChestInventory(); $this->initHumanData($nbt); @@ -422,11 +418,11 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $pk->yaw = $this->yaw; $pk->pitch = $this->pitch; $pk->item = $this->getInventory()->getItemInHand(); - $pk->metadata = $this->propertyManager->getAll(); + $pk->metadata = $this->getSyncedNetworkData(false); $player->sendDataPacket($pk); //TODO: Hack for MCPE 1.2.13: DATA_NAMETAG is useless in AddPlayerPacket, so it has to be sent separately - $this->sendData($player, [EntityMetadataProperties::NAMETAG => [EntityMetadataTypes::STRING, $this->getNameTag()]]); + $this->sendData($player, [EntityMetadataProperties::NAMETAG => new StringMetadataProperty($this->getNameTag())]); $player->getNetworkSession()->onMobArmorChange($this); @@ -448,25 +444,4 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $this->xpManager = null; parent::destroyCycles(); } - - /** - * Wrapper around {@link Entity#getDataFlag} for player-specific data flag reading. - * - * @param int $flagId - * - * @return bool - */ - public function getPlayerFlag(int $flagId) : bool{ - return $this->getDataFlag(EntityMetadataProperties::PLAYER_FLAGS, $flagId); - } - - /** - * Wrapper around {@link Entity#setDataFlag} for player-specific data flag setting. - * - * @param int $flagId - * @param bool $value - */ - public function setPlayerFlag(int $flagId, bool $value = true) : void{ - $this->setDataFlag(EntityMetadataProperties::PLAYER_FLAGS, $flagId, $value, EntityMetadataTypes::BYTE); - } } diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index b10231c12a..7a922b5157 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -66,6 +66,7 @@ use function sqrt; use const M_PI; abstract class Living extends Entity{ + protected const DEFAULT_BREATH_TICKS = 300; protected $gravity = 0.08; protected $drag = 0.02; @@ -85,6 +86,13 @@ abstract class Living extends Entity{ /** @var ArmorInventory */ protected $armorInventory; + /** @var bool */ + protected $breathing = true; + /** @var int */ + protected $breathTicks = self::DEFAULT_BREATH_TICKS; + /** @var int */ + protected $maxBreathTicks = self::DEFAULT_BREATH_TICKS; + abstract public function getName() : string; protected function initEntity(CompoundTag $nbt) : void{ @@ -114,6 +122,8 @@ abstract class Living extends Entity{ $this->setHealth($health); + $this->setAirSupplyTicks($nbt->getShort("Air", self::DEFAULT_BREATH_TICKS)); + /** @var CompoundTag[]|ListTag $activeEffectsTag */ $activeEffectsTag = $nbt->getListTag("ActiveEffects"); if($activeEffectsTag !== null){ @@ -172,6 +182,8 @@ abstract class Living extends Entity{ $nbt = parent::saveNBT(); $nbt->setFloat("Health", $this->getHealth()); + $nbt->setShort("Air", $this->getAirSupplyTicks()); + if(!empty($this->effectManager->all())){ $effects = []; foreach($this->effectManager->all() as $effect){ @@ -598,7 +610,7 @@ abstract class Living extends Entity{ * @return bool */ public function isBreathing() : bool{ - return $this->getGenericFlag(EntityMetadataFlags::BREATHING); + return $this->breathing; } /** @@ -608,7 +620,7 @@ abstract class Living extends Entity{ * @param bool $value */ public function setBreathing(bool $value = true) : void{ - $this->setGenericFlag(EntityMetadataFlags::BREATHING, $value); + $this->breathing = $value; } /** @@ -618,7 +630,7 @@ abstract class Living extends Entity{ * @return int */ public function getAirSupplyTicks() : int{ - return $this->propertyManager->getShort(EntityMetadataProperties::AIR); + return $this->breathTicks; } /** @@ -627,7 +639,7 @@ abstract class Living extends Entity{ * @param int $ticks */ public function setAirSupplyTicks(int $ticks) : void{ - $this->propertyManager->setShort(EntityMetadataProperties::AIR, $ticks); + $this->breathTicks = $ticks; } /** @@ -635,7 +647,7 @@ abstract class Living extends Entity{ * @return int */ public function getMaxAirSupplyTicks() : int{ - return $this->propertyManager->getShort(EntityMetadataProperties::MAX_AIR); + return $this->maxBreathTicks; } /** @@ -644,7 +656,7 @@ abstract class Living extends Entity{ * @param int $ticks */ public function setMaxAirSupplyTicks(int $ticks) : void{ - $this->propertyManager->setShort(EntityMetadataProperties::MAX_AIR, $ticks); + $this->maxBreathTicks = $ticks; } /** @@ -755,6 +767,17 @@ abstract class Living extends Entity{ $player->getNetworkSession()->onMobArmorChange($this); } + protected function syncNetworkData() : void{ + parent::syncNetworkData(); + + $this->propertyManager->setByte(EntityMetadataProperties::POTION_AMBIENT, $this->effectManager->hasOnlyAmbientEffects() ? 1 : 0); + $this->propertyManager->setInt(EntityMetadataProperties::POTION_COLOR, Binary::signInt($this->effectManager->getBubbleColor()->toARGB())); + $this->propertyManager->setShort(EntityMetadataProperties::AIR, $this->breathTicks); + $this->propertyManager->setShort(EntityMetadataProperties::MAX_AIR, $this->maxBreathTicks); + + $this->propertyManager->setGenericFlag(EntityMetadataFlags::BREATHING, $this->breathing); + } + protected function onDispose() : void{ $this->armorInventory->removeAllViewers(); parent::onDispose(); diff --git a/src/pocketmine/entity/Villager.php b/src/pocketmine/entity/Villager.php index 417964eba0..9172a94775 100644 --- a/src/pocketmine/entity/Villager.php +++ b/src/pocketmine/entity/Villager.php @@ -40,6 +40,11 @@ class Villager extends Living implements Ageable{ public $width = 0.6; public $height = 1.8; + /** @var bool */ + private $baby = false; + /** @var int */ + private $profession = self::PROFESSION_FARMER; + public function getName() : string{ return "Villager"; } @@ -70,14 +75,21 @@ class Villager extends Living implements Ageable{ * @param int $profession */ public function setProfession(int $profession) : void{ - $this->propertyManager->setInt(EntityMetadataProperties::VARIANT, $profession); + $this->profession = $profession; //TODO: validation } public function getProfession() : int{ - return $this->propertyManager->getInt(EntityMetadataProperties::VARIANT); + return $this->profession; } public function isBaby() : bool{ - return $this->getGenericFlag(EntityMetadataFlags::BABY); + return $this->baby; + } + + protected function syncNetworkData() : void{ + parent::syncNetworkData(); + $this->propertyManager->setGenericFlag(EntityMetadataFlags::BABY, $this->baby); + + $this->propertyManager->setInt(EntityMetadataProperties::VARIANT, $this->profession); } } diff --git a/src/pocketmine/entity/WaterAnimal.php b/src/pocketmine/entity/WaterAnimal.php index a98f8b1923..a6aeb6a8f8 100644 --- a/src/pocketmine/entity/WaterAnimal.php +++ b/src/pocketmine/entity/WaterAnimal.php @@ -27,9 +27,11 @@ use pocketmine\event\entity\EntityDamageEvent; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; abstract class WaterAnimal extends Living implements Ageable{ + /** @var bool */ + protected $baby = false; public function isBaby() : bool{ - return $this->getGenericFlag(EntityMetadataFlags::BABY); + return $this->baby; } public function canBreathe() : bool{ @@ -40,4 +42,9 @@ abstract class WaterAnimal extends Living implements Ageable{ $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_SUFFOCATION, 2); $this->attack($ev); } + + protected function syncNetworkData() : void{ + parent::syncNetworkData(); + $this->propertyManager->setGenericFlag(EntityMetadataFlags::BABY, $this->baby); + } } diff --git a/src/pocketmine/entity/effect/EffectManager.php b/src/pocketmine/entity/effect/EffectManager.php index b8f88ac294..797b90500c 100644 --- a/src/pocketmine/entity/effect/EffectManager.php +++ b/src/pocketmine/entity/effect/EffectManager.php @@ -26,7 +26,6 @@ namespace pocketmine\entity\effect; use pocketmine\entity\Living; use pocketmine\event\entity\EntityEffectAddEvent; use pocketmine\event\entity\EntityEffectRemoveEvent; -use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\utils\Color; use function abs; @@ -38,8 +37,14 @@ class EffectManager{ /** @var EffectInstance[] */ protected $effects = []; + /** @var Color */ + protected $bubbleColor; + /** @var bool */ + protected $onlyAmbientEffects = false; + public function __construct(Living $entity){ $this->entity = $entity; + $this->bubbleColor = new Color(0, 0, 0, 0); } /** @@ -176,16 +181,29 @@ class EffectManager{ } } - $propManager = $this->entity->getDataPropertyManager(); if(!empty($colors)){ - $propManager->setInt(EntityMetadataProperties::POTION_COLOR, Color::mix(...$colors)->toARGB()); - $propManager->setByte(EntityMetadataProperties::POTION_AMBIENT, $ambient ? 1 : 0); + $this->bubbleColor = Color::mix(...$colors); + $this->onlyAmbientEffects = $ambient; }else{ - $propManager->setInt(EntityMetadataProperties::POTION_COLOR, 0); - $propManager->setByte(EntityMetadataProperties::POTION_AMBIENT, 0); + $this->bubbleColor = new Color(0, 0, 0, 0); + $this->onlyAmbientEffects = false; } } + /** + * @return Color + */ + public function getBubbleColor() : Color{ + return $this->bubbleColor; + } + + /** + * @return bool + */ + public function hasOnlyAmbientEffects() : bool{ + return $this->onlyAmbientEffects; + } + public function tick(int $tickDiff = 1) : bool{ foreach($this->effects as $instance){ $type = $instance->getType(); diff --git a/src/pocketmine/entity/object/ExperienceOrb.php b/src/pocketmine/entity/object/ExperienceOrb.php index 6d89b372e9..ce4baaded6 100644 --- a/src/pocketmine/entity/object/ExperienceOrb.php +++ b/src/pocketmine/entity/object/ExperienceOrb.php @@ -107,12 +107,15 @@ class ExperienceOrb extends Entity{ */ protected $targetPlayerRuntimeId = null; + /** @var int */ + protected $xpValue = 1; + protected function initEntity(CompoundTag $nbt) : void{ parent::initEntity($nbt); $this->age = $nbt->getShort("Age", 0); - $value = 0; + $value = 1; if($nbt->hasTag(self::TAG_VALUE_PC, ShortTag::class)){ //PC $value = $nbt->getShort(self::TAG_VALUE_PC); }elseif($nbt->hasTag(self::TAG_VALUE_PE, IntTag::class)){ //PE save format @@ -134,14 +137,14 @@ class ExperienceOrb extends Entity{ } public function getXpValue() : int{ - return $this->propertyManager->getInt(EntityMetadataProperties::EXPERIENCE_VALUE) ?? 0; + return $this->xpValue; } public function setXpValue(int $amount) : void{ if($amount <= 0){ throw new \InvalidArgumentException("XP amount must be greater than 0, got $amount"); } - $this->propertyManager->setInt(EntityMetadataProperties::EXPERIENCE_VALUE, $amount); + $this->xpValue = $amount; } public function hasTargetPlayer() : bool{ @@ -225,4 +228,10 @@ class ExperienceOrb extends Entity{ public function canBeCollidedWith() : bool{ return false; } + + protected function syncNetworkData() : void{ + parent::syncNetworkData(); + + $this->propertyManager->setInt(EntityMetadataProperties::EXPERIENCE_VALUE, $this->xpValue); + } } diff --git a/src/pocketmine/entity/object/FallingBlock.php b/src/pocketmine/entity/object/FallingBlock.php index db7ef94b62..99e2b8ea81 100644 --- a/src/pocketmine/entity/object/FallingBlock.php +++ b/src/pocketmine/entity/object/FallingBlock.php @@ -71,8 +71,6 @@ class FallingBlock extends Entity{ $damage = $nbt->getByte("Data", 0); $this->block = BlockFactory::get($blockId, $damage); - - $this->propertyManager->setInt(EntityMetadataProperties::VARIANT, $this->block->getRuntimeId()); } public function canCollideWith(Entity $entity) : bool{ @@ -138,4 +136,10 @@ class FallingBlock extends Entity{ return $nbt; } + + protected function syncNetworkData() : void{ + parent::syncNetworkData(); + + $this->propertyManager->setInt(EntityMetadataProperties::VARIANT, $this->block->getRuntimeId()); + } } diff --git a/src/pocketmine/entity/object/ItemEntity.php b/src/pocketmine/entity/object/ItemEntity.php index 085c5a754a..421db601af 100644 --- a/src/pocketmine/entity/object/ItemEntity.php +++ b/src/pocketmine/entity/object/ItemEntity.php @@ -238,7 +238,7 @@ class ItemEntity extends Entity{ $pk->position = $this->asVector3(); $pk->motion = $this->getMotion(); $pk->item = $this->getItem(); - $pk->metadata = $this->propertyManager->getAll(); + $pk->metadata = $this->getSyncedNetworkData(false); $player->sendDataPacket($pk); } diff --git a/src/pocketmine/entity/object/PrimedTNT.php b/src/pocketmine/entity/object/PrimedTNT.php index 755325c587..23f6deaea0 100644 --- a/src/pocketmine/entity/object/PrimedTNT.php +++ b/src/pocketmine/entity/object/PrimedTNT.php @@ -28,7 +28,6 @@ use pocketmine\entity\Explosive; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\ExplosionPrimeEvent; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\ShortTag; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; @@ -61,14 +60,7 @@ class PrimedTNT extends Entity implements Explosive{ protected function initEntity(CompoundTag $nbt) : void{ parent::initEntity($nbt); - if($nbt->hasTag("Fuse", ShortTag::class)){ - $this->fuse = $nbt->getShort("Fuse"); - }else{ - $this->fuse = 80; - } - - $this->setGenericFlag(EntityMetadataFlags::IGNITED, true); - $this->propertyManager->setInt(EntityMetadataProperties::FUSE_LENGTH, $this->fuse); + $this->fuse = $nbt->getShort("Fuse", 80, true); $this->world->addSound($this, new IgniteSound()); } @@ -92,10 +84,6 @@ class PrimedTNT extends Entity implements Explosive{ $hasUpdate = parent::entityBaseTick($tickDiff); - if($this->fuse % 5 === 0){ //don't spam it every tick, it's not necessary - $this->propertyManager->setInt(EntityMetadataProperties::FUSE_LENGTH, $this->fuse); - } - if(!$this->isFlaggedForDespawn()){ $this->fuse -= $tickDiff; @@ -119,4 +107,11 @@ class PrimedTNT extends Entity implements Explosive{ $explosion->explodeB(); } } + + protected function syncNetworkData() : void{ + parent::syncNetworkData(); + + $this->propertyManager->setGenericFlag(EntityMetadataFlags::IGNITED, true); + $this->propertyManager->setInt(EntityMetadataProperties::FUSE_LENGTH, $this->fuse); + } } diff --git a/src/pocketmine/entity/projectile/Arrow.php b/src/pocketmine/entity/projectile/Arrow.php index 25a32e35a3..91f4de3d1b 100644 --- a/src/pocketmine/entity/projectile/Arrow.php +++ b/src/pocketmine/entity/projectile/Arrow.php @@ -67,6 +67,9 @@ class Arrow extends Projectile{ /** @var int */ protected $collideTicks = 0; + /** @var bool */ + protected $critical = false; + public function __construct(World $world, CompoundTag $nbt, ?Entity $shootingEntity = null, bool $critical = false){ parent::__construct($world, $nbt, $shootingEntity); $this->setCritical($critical); @@ -87,11 +90,11 @@ class Arrow extends Projectile{ } public function isCritical() : bool{ - return $this->getGenericFlag(EntityMetadataFlags::CRITICAL); + return $this->critical; } public function setCritical(bool $value = true) : void{ - $this->setGenericFlag(EntityMetadataFlags::CRITICAL, $value); + $this->critical = $value; } public function getResultDamage() : int{ @@ -199,4 +202,10 @@ class Arrow extends Projectile{ $playerInventory->addItem(clone $item); $this->flagForDespawn(); } + + protected function syncNetworkData() : void{ + parent::syncNetworkData(); + + $this->propertyManager->setGenericFlag(EntityMetadataFlags::CRITICAL, $this->critical); + } } diff --git a/src/pocketmine/entity/projectile/SplashPotion.php b/src/pocketmine/entity/projectile/SplashPotion.php index 7d589dd201..bed33146a8 100644 --- a/src/pocketmine/entity/projectile/SplashPotion.php +++ b/src/pocketmine/entity/projectile/SplashPotion.php @@ -49,10 +49,15 @@ class SplashPotion extends Throwable{ protected $gravity = 0.05; protected $drag = 0.01; + /** @var bool */ + protected $linger = false; + /** @var int */ + protected $potionId = Potion::WATER; + protected function initEntity(CompoundTag $nbt) : void{ parent::initEntity($nbt); - $this->setPotionId($nbt->getShort("PotionId", 0)); + $this->setPotionId($nbt->getShort("PotionId", Potion::WATER)); } public function saveNBT() : CompoundTag{ @@ -139,14 +144,14 @@ class SplashPotion extends Throwable{ * @return int */ public function getPotionId() : int{ - return $this->propertyManager->getShort(EntityMetadataProperties::POTION_AUX_VALUE) ?? 0; + return $this->potionId; } /** * @param int $id */ public function setPotionId(int $id) : void{ - $this->propertyManager->setShort(EntityMetadataProperties::POTION_AUX_VALUE, $id); + $this->potionId = $id; //TODO: validation } /** @@ -154,7 +159,7 @@ class SplashPotion extends Throwable{ * @return bool */ public function willLinger() : bool{ - return $this->getDataFlag(EntityMetadataProperties::FLAGS, EntityMetadataFlags::LINGER); + return $this->linger; } /** @@ -163,7 +168,7 @@ class SplashPotion extends Throwable{ * @param bool $value */ public function setLinger(bool $value = true) : void{ - $this->setDataFlag(EntityMetadataProperties::FLAGS, EntityMetadataFlags::LINGER, $value); + $this->linger = $value; } /** @@ -172,4 +177,11 @@ class SplashPotion extends Throwable{ public function getPotionEffects() : array{ return Potion::getPotionEffectsById($this->getPotionId()); } + + protected function syncNetworkData() : void{ + parent::syncNetworkData(); + + $this->propertyManager->setShort(EntityMetadataProperties::POTION_AUX_VALUE, $this->potionId); + $this->propertyManager->setGenericFlag(EntityMetadataFlags::LINGER, $this->linger); + } } diff --git a/src/pocketmine/network/mcpe/protocol/AddActorPacket.php b/src/pocketmine/network/mcpe/protocol/AddActorPacket.php index e854484f29..cea94a3015 100644 --- a/src/pocketmine/network/mcpe/protocol/AddActorPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddActorPacket.php @@ -31,6 +31,7 @@ use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; +use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; use function array_search; use function count; @@ -164,7 +165,7 @@ class AddActorPacket extends DataPacket implements ClientboundPacket{ /** @var Attribute[] */ public $attributes = []; - /** @var array */ + /** @var MetadataProperty[] */ public $metadata = []; /** @var EntityLink[] */ public $links = []; diff --git a/src/pocketmine/network/mcpe/protocol/AddItemActorPacket.php b/src/pocketmine/network/mcpe/protocol/AddItemActorPacket.php index 5fb28f0f4f..ded9268cb2 100644 --- a/src/pocketmine/network/mcpe/protocol/AddItemActorPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddItemActorPacket.php @@ -28,6 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; class AddItemActorPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_ITEM_ACTOR_PACKET; @@ -42,7 +43,7 @@ class AddItemActorPacket extends DataPacket implements ClientboundPacket{ public $position; /** @var Vector3|null */ public $motion; - /** @var array */ + /** @var MetadataProperty[] */ public $metadata = []; /** @var bool */ public $isFromFishing = false; diff --git a/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php b/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php index 10a5964c39..a33476f509 100644 --- a/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php +++ b/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php @@ -29,6 +29,7 @@ use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; +use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; use pocketmine\utils\UUID; use function count; @@ -57,7 +58,7 @@ class AddPlayerPacket extends DataPacket implements ClientboundPacket{ public $headYaw = null; //TODO /** @var Item */ public $item; - /** @var array */ + /** @var MetadataProperty[] */ public $metadata = []; //TODO: adventure settings stuff diff --git a/src/pocketmine/network/mcpe/protocol/SetActorDataPacket.php b/src/pocketmine/network/mcpe/protocol/SetActorDataPacket.php index 308454f573..cb9a603395 100644 --- a/src/pocketmine/network/mcpe/protocol/SetActorDataPacket.php +++ b/src/pocketmine/network/mcpe/protocol/SetActorDataPacket.php @@ -27,16 +27,18 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; class SetActorDataPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ //TODO: check why this is serverbound public const NETWORK_ID = ProtocolInfo::SET_ACTOR_DATA_PACKET; /** @var int */ public $entityRuntimeId; - /** @var array */ + /** @var MetadataProperty[] */ public $metadata; public static function create(int $entityRuntimeId, array $metadata) : self{ + $result = new self; $result->entityRuntimeId = $entityRuntimeId; $result->metadata = $metadata; diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php b/src/pocketmine/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php new file mode 100644 index 0000000000..5bf56214f1 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php @@ -0,0 +1,65 @@ +value = $value->floor(); + } + + /** + * @return Vector3 + */ + public function getValue() : Vector3{ + return $this->value; + } + + public static function id() : int{ + return EntityMetadataTypes::POS; + } + + public static function read(NetworkBinaryStream $in) : self{ + $vec = new Vector3(0, 0, 0); + $in->getSignedBlockPosition($vec->x, $vec->y, $vec->z); + return new self($vec); + } + + public function write(NetworkBinaryStream $out) : void{ + $out->putSignedBlockPosition($this->value->x, $this->value->y, $this->value->z); + } + + public function equals(MetadataProperty $other) : bool{ + return $other instanceof $this and $other->value->equals($this->value); + } +} diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/ByteMetadataProperty.php b/src/pocketmine/network/mcpe/protocol/types/entity/ByteMetadataProperty.php new file mode 100644 index 0000000000..1945b316d4 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/entity/ByteMetadataProperty.php @@ -0,0 +1,50 @@ +getByte()); + } + + public function write(NetworkBinaryStream $out) : void{ + $out->putByte($this->value); + } +} diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataCollection.php b/src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataCollection.php index c56f5be5ca..61bc933bf4 100644 --- a/src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataCollection.php +++ b/src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataCollection.php @@ -25,51 +25,27 @@ namespace pocketmine\network\mcpe\protocol\types\entity; use pocketmine\item\Item; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataTypes; -use function assert; -use function is_float; -use function is_int; -use function is_string; +use function get_class; class EntityMetadataCollection{ + /** @var MetadataProperty[] */ private $properties = []; - + /** @var MetadataProperty[] */ private $dirtyProperties = []; public function __construct(){ } - /** - * @param int $key - * - * @return int|null - */ - public function getByte(int $key) : ?int{ - $value = $this->getPropertyValue($key, EntityMetadataTypes::BYTE); - assert(is_int($value) or $value === null); - return $value; - } - /** * @param int $key * @param int $value * @param bool $force */ public function setByte(int $key, int $value, bool $force = false) : void{ - $this->setPropertyValue($key, EntityMetadataTypes::BYTE, $value, $force); - } - /** - * @param int $key - * - * @return int|null - */ - public function getShort(int $key) : ?int{ - $value = $this->getPropertyValue($key, EntityMetadataTypes::SHORT); - assert(is_int($value) or $value === null); - return $value; + $this->set($key, new ByteMetadataProperty($value), $force); } /** @@ -78,18 +54,7 @@ class EntityMetadataCollection{ * @param bool $force */ public function setShort(int $key, int $value, bool $force = false) : void{ - $this->setPropertyValue($key, EntityMetadataTypes::SHORT, $value, $force); - } - - /** - * @param int $key - * - * @return int|null - */ - public function getInt(int $key) : ?int{ - $value = $this->getPropertyValue($key, EntityMetadataTypes::INT); - assert(is_int($value) or $value === null); - return $value; + $this->set($key, new ShortMetadataProperty($value), $force); } /** @@ -98,18 +63,7 @@ class EntityMetadataCollection{ * @param bool $force */ public function setInt(int $key, int $value, bool $force = false) : void{ - $this->setPropertyValue($key, EntityMetadataTypes::INT, $value, $force); - } - - /** - * @param int $key - * - * @return float|null - */ - public function getFloat(int $key) : ?float{ - $value = $this->getPropertyValue($key, EntityMetadataTypes::FLOAT); - assert(is_float($value) or $value === null); - return $value; + $this->set($key, new IntMetadataProperty($value), $force); } /** @@ -118,18 +72,7 @@ class EntityMetadataCollection{ * @param bool $force */ public function setFloat(int $key, float $value, bool $force = false) : void{ - $this->setPropertyValue($key, EntityMetadataTypes::FLOAT, $value, $force); - } - - /** - * @param int $key - * - * @return null|string - */ - public function getString(int $key) : ?string{ - $value = $this->getPropertyValue($key, EntityMetadataTypes::STRING); - assert(is_string($value) or $value === null); - return $value; + $this->set($key, new FloatMetadataProperty($value), $force); } /** @@ -138,19 +81,7 @@ class EntityMetadataCollection{ * @param bool $force */ public function setString(int $key, string $value, bool $force = false) : void{ - $this->setPropertyValue($key, EntityMetadataTypes::STRING, $value, $force); - } - - /** - * @param int $key - * - * @return null|Item - */ - public function getItem(int $key) : ?Item{ - $value = $this->getPropertyValue($key, EntityMetadataTypes::SLOT); - assert($value instanceof Item or $value === null); - - return $value; + $this->set($key, new StringMetadataProperty($value), $force); } /** @@ -159,18 +90,7 @@ class EntityMetadataCollection{ * @param bool $force */ public function setItem(int $key, Item $value, bool $force = false) : void{ - $this->setPropertyValue($key, EntityMetadataTypes::SLOT, $value, $force); - } - - /** - * @param int $key - * - * @return null|Vector3 - */ - public function getBlockPos(int $key) : ?Vector3{ - $value = $this->getPropertyValue($key, EntityMetadataTypes::POS); - assert($value instanceof Vector3 or $value === null); - return $value; + $this->set($key, new ItemStackMetadataProperty($value), $force); } /** @@ -179,18 +99,7 @@ class EntityMetadataCollection{ * @param bool $force */ public function setBlockPos(int $key, ?Vector3 $value, bool $force = false) : void{ - $this->setPropertyValue($key, EntityMetadataTypes::POS, $value ? $value->floor() : null, $force); - } - - /** - * @param int $key - * - * @return int|null - */ - public function getLong(int $key) : ?int{ - $value = $this->getPropertyValue($key, EntityMetadataTypes::LONG); - assert(is_int($value) or $value === null); - return $value; + $this->set($key, new BlockPosMetadataProperty($value ?? new Vector3(0, 0, 0)), $force); } /** @@ -199,18 +108,7 @@ class EntityMetadataCollection{ * @param bool $force */ public function setLong(int $key, int $value, bool $force = false) : void{ - $this->setPropertyValue($key, EntityMetadataTypes::LONG, $value, $force); - } - - /** - * @param int $key - * - * @return null|Vector3 - */ - public function getVector3(int $key) : ?Vector3{ - $value = $this->getPropertyValue($key, EntityMetadataTypes::VECTOR3F); - assert($value instanceof Vector3 or $value === null); - return $value; + $this->set($key, new LongMetadataProperty($value), $force); } /** @@ -219,74 +117,60 @@ class EntityMetadataCollection{ * @param bool $force */ public function setVector3(int $key, ?Vector3 $value, bool $force = false) : void{ - $this->setPropertyValue($key, EntityMetadataTypes::VECTOR3F, $value ? $value->asVector3() : null, $force); - } - - /** - * @param int $key - */ - public function removeProperty(int $key) : void{ - unset($this->properties[$key]); - } - - /** - * @param int $key - * - * @return bool - */ - public function hasProperty(int $key) : bool{ - return isset($this->properties[$key]); - } - - /** - * @param int $key - * - * @return int - */ - public function getPropertyType(int $key) : int{ - if(isset($this->properties[$key])){ - return $this->properties[$key][0]; - } - - return -1; - } - - private function checkType(int $key, int $type) : void{ - if(isset($this->properties[$key]) and $this->properties[$key][0] !== $type){ - throw new \RuntimeException("Expected type $type, but have " . $this->properties[$key][0]); - } - } - - /** - * @param int $key - * @param int $type - * - * @return mixed - */ - public function getPropertyValue(int $key, int $type){ - if($type !== -1){ - $this->checkType($key, $type); - } - return isset($this->properties[$key]) ? $this->properties[$key][1] : null; + $this->set($key, new Vec3MetadataProperty($value ?? new Vector3(0, 0, 0)), $force); } /** * @param int $key - * @param int $type * @param mixed $value * @param bool $force */ - public function setPropertyValue(int $key, int $type, $value, bool $force = false) : void{ - if(!$force){ - $this->checkType($key, $type); + public function set(int $key, MetadataProperty $value, bool $force = false) : void{ + if(!$force and isset($this->properties[$key]) and !($this->properties[$key] instanceof $value)){ + throw new \InvalidArgumentException("Can't overwrite property with mismatching types (have " . get_class($this->properties[$key]) . ")"); + } + if(!isset($this->properties[$key]) or !$this->properties[$key]->equals($value)){ + $this->properties[$key] = $this->dirtyProperties[$key] = $value; + } + } + + public function setGenericFlag(int $flagId, bool $value) : void{ + $propertyId = $flagId >= 64 ? EntityMetadataProperties::FLAGS2 : EntityMetadataProperties::FLAGS; + $realFlagId = $flagId % 64; + $flagSetProp = $this->properties[$propertyId] ?? null; + if($flagSetProp === null){ + $flagSet = 0; + }elseif($flagSetProp instanceof LongMetadataProperty){ + $flagSet = $flagSetProp->getValue(); + }else{ + throw new \InvalidArgumentException("Wrong type found for flags, want long, but have " . get_class($flagSetProp)); + } + + if((($flagSet >> $realFlagId) & 1) !== ($value ? 1 : 0)){ + $flagSet ^= (1 << $realFlagId); + $this->setLong($propertyId, $flagSet); + } + } + + public function setPlayerFlag(int $flagId, bool $value) : void{ + $flagSetProp = $this->properties[EntityMetadataProperties::PLAYER_FLAGS] ?? null; + if($flagSetProp === null){ + $flagSet = 0; + }elseif($flagSetProp instanceof ByteMetadataProperty){ + $flagSet = $flagSetProp->getValue(); + }else{ + throw new \InvalidArgumentException("Wrong type found for flags, want byte, but have " . get_class($flagSetProp)); + } + if((($flagSet >> $flagId) & 1) !== ($value ? 1 : 0)){ + $flagSet ^= (1 << $flagId); + $this->setByte(EntityMetadataProperties::PLAYER_FLAGS, $flagSet); } - $this->properties[$key] = $this->dirtyProperties[$key] = [$type, $value]; } /** * Returns all properties. * - * @return array + * @return MetadataProperty[] */ public function getAll() : array{ return $this->properties; @@ -295,7 +179,7 @@ class EntityMetadataCollection{ /** * Returns properties that have changed and need to be broadcasted. * - * @return array + * @return MetadataProperty[] */ public function getDirty() : array{ return $this->dirtyProperties; diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/FloatMetadataProperty.php b/src/pocketmine/network/mcpe/protocol/types/entity/FloatMetadataProperty.php new file mode 100644 index 0000000000..6554af0a0a --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/entity/FloatMetadataProperty.php @@ -0,0 +1,62 @@ +value = $value; + } + + /** + * @return float + */ + public function getValue() : float{ + return $this->value; + } + + public static function id() : int{ + return EntityMetadataTypes::FLOAT; + } + + public function equals(MetadataProperty $other) : bool{ + return $other instanceof $this and $other->value === $this->value; + } + + public static function read(NetworkBinaryStream $in) : self{ + return new self($in->getLFloat()); + } + + public function write(NetworkBinaryStream $out) : void{ + $out->putLFloat($this->value); + } +} diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/IntMetadataProperty.php b/src/pocketmine/network/mcpe/protocol/types/entity/IntMetadataProperty.php new file mode 100644 index 0000000000..1bdcbb888f --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/entity/IntMetadataProperty.php @@ -0,0 +1,50 @@ +getVarInt()); + } + + public function write(NetworkBinaryStream $out) : void{ + $out->putVarInt($this->value); + } +} diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php b/src/pocketmine/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php new file mode 100644 index 0000000000..a36f3c7dd0 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php @@ -0,0 +1,64 @@ +min() or $value > $this->max()){ + throw new \InvalidArgumentException("Value is out of range " . $this->min() . " - " . $this->max()); + } + $this->value = $value; + } + + abstract protected function min() : int; + + abstract protected function max() : int; + + /** + * @return int + */ + public function getValue() : int{ + return $this->value; + } + + public function equals(MetadataProperty $other) : bool{ + return $other instanceof $this and $other->value === $this->value; + } + + public static function buildFromFlags(array $flags) : self{ + $value = 0; + foreach($flags as $flag => $v){ + if($v){ + $value |= 1 << $flag; + } + } + return new self($value); + } +} diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/ItemStackMetadataProperty.php b/src/pocketmine/network/mcpe/protocol/types/entity/ItemStackMetadataProperty.php new file mode 100644 index 0000000000..0d2cea4750 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/entity/ItemStackMetadataProperty.php @@ -0,0 +1,62 @@ +value = clone $value; + } + + /** + * @return Item + */ + public function getValue() : Item{ + return clone $this->value; + } + + public static function id() : int{ + return EntityMetadataTypes::SLOT; + } + + public function equals(MetadataProperty $other) : bool{ + return $other instanceof $this and $other->value->equalsExact($this->value); + } + + public static function read(NetworkBinaryStream $in) : self{ + return new self($in->getSlot()); + } + + public function write(NetworkBinaryStream $out) : void{ + $out->putSlot($this->value); + } +} diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/LongMetadataProperty.php b/src/pocketmine/network/mcpe/protocol/types/entity/LongMetadataProperty.php new file mode 100644 index 0000000000..463014d5aa --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/entity/LongMetadataProperty.php @@ -0,0 +1,52 @@ +getVarLong()); + } + + public function write(NetworkBinaryStream $out) : void{ + $out->putVarLong($this->value); + } +} diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/MetadataProperty.php b/src/pocketmine/network/mcpe/protocol/types/entity/MetadataProperty.php new file mode 100644 index 0000000000..9a920d70b4 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/entity/MetadataProperty.php @@ -0,0 +1,35 @@ +getSignedLShort()); + } + + public function write(NetworkBinaryStream $out) : void{ + $out->putLShort($this->value); + } +} diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/StringMetadataProperty.php b/src/pocketmine/network/mcpe/protocol/types/entity/StringMetadataProperty.php new file mode 100644 index 0000000000..daf781c3c8 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/entity/StringMetadataProperty.php @@ -0,0 +1,54 @@ +value = $value; + } + + public static function id() : int{ + return EntityMetadataTypes::STRING; + } + + public static function read(NetworkBinaryStream $in) : self{ + return new self($in->getString()); + } + + public function write(NetworkBinaryStream $out) : void{ + $out->putString($this->value); + } + + public function equals(MetadataProperty $other) : bool{ + return $other instanceof $this and $other->value === $this->value; + } +} diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php b/src/pocketmine/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php new file mode 100644 index 0000000000..33fee71624 --- /dev/null +++ b/src/pocketmine/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php @@ -0,0 +1,62 @@ +value = $value->asVector3(); + } + + /** + * @return Vector3 + */ + public function getValue() : Vector3{ + return clone $this->value; + } + + public static function id() : int{ + return EntityMetadataTypes::VECTOR3F; + } + + public static function read(NetworkBinaryStream $in) : self{ + return new self($in->getVector3()); + } + + public function write(NetworkBinaryStream $out) : void{ + $out->putVector3($this->value); + } + + public function equals(MetadataProperty $other) : bool{ + return $other instanceof $this and $other->value->equals($this->value); + } +} diff --git a/src/pocketmine/network/mcpe/serializer/NetworkBinaryStream.php b/src/pocketmine/network/mcpe/serializer/NetworkBinaryStream.php index 173b99f2df..42919c621c 100644 --- a/src/pocketmine/network/mcpe/serializer/NetworkBinaryStream.php +++ b/src/pocketmine/network/mcpe/serializer/NetworkBinaryStream.php @@ -37,8 +37,17 @@ use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\TreeRoot; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; +use pocketmine\network\mcpe\protocol\types\entity\BlockPosMetadataProperty; +use pocketmine\network\mcpe\protocol\types\entity\ByteMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; -use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataTypes; +use pocketmine\network\mcpe\protocol\types\entity\FloatMetadataProperty; +use pocketmine\network\mcpe\protocol\types\entity\IntMetadataProperty; +use pocketmine\network\mcpe\protocol\types\entity\ItemStackMetadataProperty; +use pocketmine\network\mcpe\protocol\types\entity\LongMetadataProperty; +use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; +use pocketmine\network\mcpe\protocol\types\entity\ShortMetadataProperty; +use pocketmine\network\mcpe\protocol\types\entity\StringMetadataProperty; +use pocketmine\network\mcpe\protocol\types\entity\Vec3MetadataProperty; use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; use pocketmine\utils\UUID; @@ -224,108 +233,51 @@ class NetworkBinaryStream extends BinaryStream{ /** * Decodes entity metadata from the stream. * - * @param bool $types Whether to include metadata types along with values in the returned array - * - * @return array + * @return MetadataProperty[] * * @throws BadPacketException * @throws BinaryDataException */ - public function getEntityMetadata(bool $types = true) : array{ + public function getEntityMetadata() : array{ $count = $this->getUnsignedVarInt(); $data = []; for($i = 0; $i < $count; ++$i){ $key = $this->getUnsignedVarInt(); $type = $this->getUnsignedVarInt(); - $value = null; - switch($type){ - case EntityMetadataTypes::BYTE: - $value = $this->getByte(); - break; - case EntityMetadataTypes::SHORT: - $value = $this->getSignedLShort(); - break; - case EntityMetadataTypes::INT: - $value = $this->getVarInt(); - break; - case EntityMetadataTypes::FLOAT: - $value = $this->getLFloat(); - break; - case EntityMetadataTypes::STRING: - $value = $this->getString(); - break; - case EntityMetadataTypes::SLOT: - $value = $this->getSlot(); - break; - case EntityMetadataTypes::POS: - $value = new Vector3(); - $this->getSignedBlockPosition($value->x, $value->y, $value->z); - break; - case EntityMetadataTypes::LONG: - $value = $this->getVarLong(); - break; - case EntityMetadataTypes::VECTOR3F: - $value = $this->getVector3(); - break; - default: - throw new BadPacketException("Unknown entity metadata type " . $type); - } - if($types){ - $data[$key] = [$type, $value]; - }else{ - $data[$key] = $value; - } + + $data[$key] = $this->readMetadataProperty($type); } return $data; } + private function readMetadataProperty(int $type) : MetadataProperty{ + switch($type){ + case ByteMetadataProperty::id(): return ByteMetadataProperty::read($this); + case ShortMetadataProperty::id(): return ShortMetadataProperty::read($this); + case IntMetadataProperty::id(): return IntMetadataProperty::read($this); + case FloatMetadataProperty::id(): return FloatMetadataProperty::read($this); + case StringMetadataProperty::id(): return StringMetadataProperty::read($this); + case ItemStackMetadataProperty::id(): return ItemStackMetadataProperty::read($this); + case BlockPosMetadataProperty::id(): return BlockPosMetadataProperty::read($this); + case LongMetadataProperty::id(): return LongMetadataProperty::read($this); + case Vec3MetadataProperty::id(): return Vec3MetadataProperty::read($this); + default: + throw new BadPacketException("Unknown entity metadata type " . $type); + } + } + /** * Writes entity metadata to the packet buffer. * - * @param array $metadata + * @param MetadataProperty[] $metadata */ public function putEntityMetadata(array $metadata) : void{ $this->putUnsignedVarInt(count($metadata)); foreach($metadata as $key => $d){ - $this->putUnsignedVarInt($key); //data key - $this->putUnsignedVarInt($d[0]); //data type - switch($d[0]){ - case EntityMetadataTypes::BYTE: - $this->putByte($d[1]); - break; - case EntityMetadataTypes::SHORT: - $this->putLShort($d[1]); //SIGNED short! - break; - case EntityMetadataTypes::INT: - $this->putVarInt($d[1]); - break; - case EntityMetadataTypes::FLOAT: - $this->putLFloat($d[1]); - break; - case EntityMetadataTypes::STRING: - $this->putString($d[1]); - break; - case EntityMetadataTypes::SLOT: - $this->putSlot($d[1]); - break; - case EntityMetadataTypes::POS: - $v = $d[1]; - if($v !== null){ - $this->putSignedBlockPosition($v->x, $v->y, $v->z); - }else{ - $this->putSignedBlockPosition(0, 0, 0); - } - break; - case EntityMetadataTypes::LONG: - $this->putVarLong($d[1]); - break; - case EntityMetadataTypes::VECTOR3F: - $this->putVector3Nullable($d[1]); - break; - default: - throw new \InvalidArgumentException("Invalid data type " . $d[0]); - } + $this->putUnsignedVarInt($key); + $this->putUnsignedVarInt($d::id()); + $d->write($this); } } diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 1e883c137b..e364d11bee 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -752,12 +752,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool */ public function isUsingItem() : bool{ - return $this->getGenericFlag(EntityMetadataFlags::ACTION) and $this->startAction > -1; + return $this->startAction > -1; } public function setUsingItem(bool $value){ $this->startAction = $value ? $this->server->getTick() : -1; - $this->setGenericFlag(EntityMetadataFlags::ACTION, $value); } /** @@ -1078,10 +1077,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $b->setOccupied(); } - $this->sleeping = clone $pos; - - $this->propertyManager->setBlockPos(EntityMetadataProperties::PLAYER_BED_POSITION, $pos); - $this->setPlayerFlag(PlayerMetadataFlags::SLEEP, true); + $this->sleeping = $pos; $this->setSpawn($pos); @@ -1099,8 +1095,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, (new PlayerBedLeaveEvent($this, $b))->call(); $this->sleeping = null; - $this->propertyManager->setBlockPos(EntityMetadataProperties::PLAYER_BED_POSITION, null); - $this->setPlayerFlag(PlayerMetadataFlags::SLEEP, false); $this->world->setSleepTicks(0); @@ -2367,6 +2361,15 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, parent::attack($source); } + protected function syncNetworkData() : void{ + parent::syncNetworkData(); + + $this->propertyManager->setGenericFlag(EntityMetadataFlags::ACTION, $this->startAction > -1); + + $this->propertyManager->setPlayerFlag(PlayerMetadataFlags::SLEEP, $this->sleeping !== null); + $this->propertyManager->setBlockPos(EntityMetadataProperties::PLAYER_BED_POSITION, $this->sleeping ?? new Vector3(0, 0, 0)); + } + public function broadcastEntityEvent(int $eventId, ?int $eventData = null, ?array $players = null) : void{ if($this->spawned and $players === null){ $players = $this->getViewers(); diff --git a/src/pocketmine/world/particle/FloatingTextParticle.php b/src/pocketmine/world/particle/FloatingTextParticle.php index 6deb6b6ac4..96ca19efae 100644 --- a/src/pocketmine/world/particle/FloatingTextParticle.php +++ b/src/pocketmine/world/particle/FloatingTextParticle.php @@ -32,7 +32,8 @@ use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\RemoveActorPacket; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; -use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataTypes; +use pocketmine\network\mcpe\protocol\types\entity\FloatMetadataProperty; +use pocketmine\network\mcpe\protocol\types\entity\LongMetadataProperty; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\utils\UUID; use function str_repeat; @@ -104,8 +105,8 @@ class FloatingTextParticle implements Particle{ 1 << EntityMetadataFlags::IMMOBILE ); $pk->metadata = [ - EntityMetadataProperties::FLAGS => [EntityMetadataTypes::LONG, $flags], - EntityMetadataProperties::SCALE => [EntityMetadataTypes::FLOAT, 0.01] //zero causes problems on debug builds + EntityMetadataProperties::FLAGS => new LongMetadataProperty($flags), + EntityMetadataProperties::SCALE => new FloatMetadataProperty(0.01) //zero causes problems on debug builds ]; $p[] = $pk; From b98dad6f638926f0a1d6175b6978736856e418cb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jul 2019 16:37:40 +0100 Subject: [PATCH 1135/3224] Fixed WritableBook PC format deserialization --- src/pocketmine/item/WritableBookBase.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/item/WritableBookBase.php b/src/pocketmine/item/WritableBookBase.php index ef44dbf6a4..c29c4f97d0 100644 --- a/src/pocketmine/item/WritableBookBase.php +++ b/src/pocketmine/item/WritableBookBase.php @@ -24,8 +24,10 @@ declare(strict_types=1); namespace pocketmine\item; use Ds\Deque; +use pocketmine\nbt\NBT; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; +use pocketmine\nbt\tag\StringTag; abstract class WritableBookBase extends Item{ public const TAG_PAGES = "pages"; //TAG_List @@ -171,9 +173,16 @@ abstract class WritableBookBase extends Item{ $pages = $tag->getListTag(self::TAG_PAGES); if($pages !== null){ - /** @var CompoundTag $page */ - foreach($pages as $page){ - $this->pages->push(new WritableBookPage($page->getString(self::TAG_PAGE_TEXT), $page->getString(self::TAG_PAGE_PHOTONAME, ""))); + if($pages->getTagType() === NBT::TAG_Compound){ //PE format + /** @var CompoundTag $page */ + foreach($pages as $page){ + $this->pages->push(new WritableBookPage($page->getString(self::TAG_PAGE_TEXT), $page->getString(self::TAG_PAGE_PHOTONAME, ""))); + } + }elseif($pages->getTagType() === NBT::TAG_String){ //PC format + /** @var StringTag $page */ + foreach($pages as $page){ + $this->pages->push(new WritableBookPage($page->getValue())); + } } } } From f3f8cd98de0bf6878acdd73fcef435ae0378ea8a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jul 2019 17:17:05 +0100 Subject: [PATCH 1136/3224] World: fixed scheduled updates causing chunk loading this probably needs to be backported. --- src/pocketmine/world/World.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 3f0a725003..b1f233bbec 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -755,7 +755,12 @@ class World implements ChunkManager{ //Delayed updates while($this->scheduledBlockUpdateQueue->count() > 0 and $this->scheduledBlockUpdateQueue->current()["priority"] <= $currentTick){ - $block = $this->getBlock($this->scheduledBlockUpdateQueue->extract()["data"]); + /** @var Vector3 $vec */ + $vec = $this->scheduledBlockUpdateQueue->extract()["data"]; + if(!$this->isInLoadedTerrain($vec)){ + continue; + } + $block = $this->getBlock($vec); unset($this->scheduledBlockUpdateQueueIndex[World::blockHash($block->x, $block->y, $block->z)]); $block->onScheduledUpdate(); } From a621bf66ffb5b7e8c47bbbfd5efce7b688b36641 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jul 2019 17:43:36 +0100 Subject: [PATCH 1137/3224] Remove implied dependence on Facing/Bearing constant values this introduces mapping tables for redundancy for when those things change or disappear. --- src/pocketmine/block/Anvil.php | 7 +- src/pocketmine/block/Banner.php | 6 +- src/pocketmine/block/Bed.php | 7 +- src/pocketmine/block/Button.php | 6 +- src/pocketmine/block/Cactus.php | 4 +- src/pocketmine/block/Cake.php | 4 +- src/pocketmine/block/CarvedPumpkin.php | 7 +- src/pocketmine/block/Chest.php | 6 +- src/pocketmine/block/CocoaBlock.php | 9 +-- src/pocketmine/block/Crops.php | 4 +- src/pocketmine/block/DaylightSensor.php | 4 +- src/pocketmine/block/Door.php | 7 +- src/pocketmine/block/EndPortalFrame.php | 7 +- src/pocketmine/block/EndRod.php | 12 +-- src/pocketmine/block/EnderChest.php | 6 +- src/pocketmine/block/Farmland.php | 4 +- src/pocketmine/block/FenceGate.php | 7 +- src/pocketmine/block/Fire.php | 4 +- src/pocketmine/block/FrostedIce.php | 4 +- src/pocketmine/block/Furnace.php | 6 +- src/pocketmine/block/GlazedTerracotta.php | 6 +- src/pocketmine/block/Hopper.php | 6 +- src/pocketmine/block/ItemFrame.php | 6 +- src/pocketmine/block/Ladder.php | 6 +- src/pocketmine/block/Lever.php | 6 +- src/pocketmine/block/Liquid.php | 4 +- src/pocketmine/block/NetherReactor.php | 4 +- src/pocketmine/block/NetherWartPlant.php | 4 +- src/pocketmine/block/RedstoneComparator.php | 7 +- src/pocketmine/block/RedstoneRepeater.php | 9 +-- src/pocketmine/block/RedstoneWire.php | 4 +- src/pocketmine/block/Sign.php | 6 +- src/pocketmine/block/Skull.php | 6 +- src/pocketmine/block/SnowLayer.php | 4 +- src/pocketmine/block/Stair.php | 6 +- src/pocketmine/block/Sugarcane.php | 4 +- src/pocketmine/block/Torch.php | 6 +- src/pocketmine/block/Trapdoor.php | 6 +- src/pocketmine/block/TripwireHook.php | 7 +- .../block/WeightedPressurePlate.php | 4 +- ...aValidator.php => BlockDataSerializer.php} | 80 +++++++++++++++---- 41 files changed, 176 insertions(+), 136 deletions(-) rename src/pocketmine/block/utils/{BlockDataValidator.php => BlockDataSerializer.php} (51%) diff --git a/src/pocketmine/block/Anvil.php b/src/pocketmine/block/Anvil.php index 34cdf10035..bdd79597cd 100644 --- a/src/pocketmine/block/Anvil.php +++ b/src/pocketmine/block/Anvil.php @@ -23,14 +23,13 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\Fallable; use pocketmine\block\utils\FallableTrait; use pocketmine\inventory\AnvilInventory; use pocketmine\item\Item; use pocketmine\item\ToolTier; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -47,11 +46,11 @@ class Anvil extends Transparent implements Fallable{ } protected function writeStateToMeta() : int{ - return Bearing::fromFacing($this->facing); + return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta); + $this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Banner.php b/src/pocketmine/block/Banner.php index 98dfb4b61b..e001d582cf 100644 --- a/src/pocketmine/block/Banner.php +++ b/src/pocketmine/block/Banner.php @@ -26,7 +26,7 @@ namespace pocketmine\block; use Ds\Deque; use pocketmine\block\tile\Banner as TileBanner; use pocketmine\block\utils\BannerPattern; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\DyeColor; use pocketmine\item\Banner as ItemBanner; use pocketmine\item\Item; @@ -77,12 +77,12 @@ class Banner extends Transparent{ if($this->facing === Facing::UP){ return $this->rotation; } - return $this->facing; + return BlockDataSerializer::writeHorizontalFacing($this->facing); } public function readStateFromData(int $id, int $stateMeta) : void{ if($id === $this->idInfo->getSecondId()){ - $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); + $this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta); }else{ $this->facing = Facing::UP; $this->rotation = $stateMeta; diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index dd26f3950b..0f6a5963da 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -24,14 +24,13 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\tile\Bed as TileBed; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\DyeColor; use pocketmine\item\Bed as ItemBed; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\lang\TranslationContainer; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -56,13 +55,13 @@ class Bed extends Transparent{ } protected function writeStateToMeta() : int{ - return Bearing::fromFacing($this->facing) | + return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) | ($this->occupied ? BlockLegacyMetadata::BED_FLAG_OCCUPIED : 0) | ($this->head ? BlockLegacyMetadata::BED_FLAG_HEAD : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); + $this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03); $this->occupied = ($stateMeta & BlockLegacyMetadata::BED_FLAG_OCCUPIED) !== 0; $this->head = ($stateMeta & BlockLegacyMetadata::BED_FLAG_HEAD) !== 0; } diff --git a/src/pocketmine/block/Button.php b/src/pocketmine/block/Button.php index a6ae2a1ffa..ed29cb587b 100644 --- a/src/pocketmine/block/Button.php +++ b/src/pocketmine/block/Button.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -40,12 +40,12 @@ abstract class Button extends Flowable{ protected $powered = false; protected function writeStateToMeta() : int{ - return $this->facing | ($this->powered ? BlockLegacyMetadata::BUTTON_FLAG_POWERED : 0); + return BlockDataSerializer::writeFacing($this->facing) | ($this->powered ? BlockLegacyMetadata::BUTTON_FLAG_POWERED : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ //TODO: in PC it's (6 - facing) for every meta except 0 (down) - $this->facing = BlockDataValidator::readFacing($stateMeta & 0x07); + $this->facing = BlockDataSerializer::readFacing($stateMeta & 0x07); $this->powered = ($stateMeta & BlockLegacyMetadata::BUTTON_FLAG_POWERED) !== 0; } diff --git a/src/pocketmine/block/Cactus.php b/src/pocketmine/block/Cactus.php index 1c768c830f..b7b6df815a 100644 --- a/src/pocketmine/block/Cactus.php +++ b/src/pocketmine/block/Cactus.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\entity\Entity; use pocketmine\event\block\BlockGrowEvent; use pocketmine\event\entity\EntityDamageByBlockEvent; @@ -49,7 +49,7 @@ class Cactus extends Transparent{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 15); + $this->age = BlockDataSerializer::readBoundedInt("age", $stateMeta, 0, 15); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index 51ea82f0f0..5f417927e1 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\Living; use pocketmine\item\FoodSource; @@ -48,7 +48,7 @@ class Cake extends Transparent implements FoodSource{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->bites = BlockDataValidator::readBoundedInt("bites", $stateMeta, 0, 6); + $this->bites = BlockDataSerializer::readBoundedInt("bites", $stateMeta, 0, 6); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/CarvedPumpkin.php b/src/pocketmine/block/CarvedPumpkin.php index 621ae9c3fb..9219c32332 100644 --- a/src/pocketmine/block/CarvedPumpkin.php +++ b/src/pocketmine/block/CarvedPumpkin.php @@ -23,9 +23,8 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; -use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -37,11 +36,11 @@ class CarvedPumpkin extends Opaque{ protected $facing = Facing::NORTH; public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); + $this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03); } protected function writeStateToMeta() : int{ - return Bearing::fromFacing($this->facing); + return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index e01ceae5df..68d6e29de4 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\tile\Chest as TileChest; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -42,11 +42,11 @@ class Chest extends Transparent{ } protected function writeStateToMeta() : int{ - return $this->facing; + return BlockDataSerializer::writeHorizontalFacing($this->facing); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); + $this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/CocoaBlock.php b/src/pocketmine/block/CocoaBlock.php index f1ae2a808e..2b487077e3 100644 --- a/src/pocketmine/block/CocoaBlock.php +++ b/src/pocketmine/block/CocoaBlock.php @@ -23,13 +23,12 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\TreeType; use pocketmine\item\Fertilizer; use pocketmine\item\Item; use pocketmine\item\VanillaItems; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -48,12 +47,12 @@ class CocoaBlock extends Transparent{ } protected function writeStateToMeta() : int{ - return Bearing::fromFacing(Facing::opposite($this->facing)) | ($this->age << 2); + return BlockDataSerializer::writeLegacyHorizontalFacing(Facing::opposite($this->facing)) | ($this->age << 2); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = Facing::opposite(BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03)); - $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta >> 2, 0, 2); + $this->facing = Facing::opposite(BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03)); + $this->age = BlockDataSerializer::readBoundedInt("age", $stateMeta >> 2, 0, 2); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Crops.php b/src/pocketmine/block/Crops.php index 799f59fd5c..3a1829ea8e 100644 --- a/src/pocketmine/block/Crops.php +++ b/src/pocketmine/block/Crops.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Fertilizer; use pocketmine\item\Item; @@ -46,7 +46,7 @@ abstract class Crops extends Flowable{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 7); + $this->age = BlockDataSerializer::readBoundedInt("age", $stateMeta, 0, 7); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/DaylightSensor.php b/src/pocketmine/block/DaylightSensor.php index 27ec0ee768..af05390a52 100644 --- a/src/pocketmine/block/DaylightSensor.php +++ b/src/pocketmine/block/DaylightSensor.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -57,7 +57,7 @@ class DaylightSensor extends Transparent{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->power = BlockDataValidator::readBoundedInt("power", $stateMeta, 0, 15); + $this->power = BlockDataSerializer::readBoundedInt("power", $stateMeta, 0, 15); $this->inverted = $id === $this->idInfo->getSecondId(); } diff --git a/src/pocketmine/block/Door.php b/src/pocketmine/block/Door.php index c244ddacc0..eecb1c2760 100644 --- a/src/pocketmine/block/Door.php +++ b/src/pocketmine/block/Door.php @@ -23,10 +23,9 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -55,7 +54,7 @@ class Door extends Transparent{ ($this->powered ? BlockLegacyMetadata::DOOR_TOP_FLAG_POWERED : 0); } - return Bearing::fromFacing(Facing::rotateY($this->facing, true)) | ($this->open ? BlockLegacyMetadata::DOOR_BOTTOM_FLAG_OPEN : 0); + return BlockDataSerializer::writeLegacyHorizontalFacing(Facing::rotateY($this->facing, true)) | ($this->open ? BlockLegacyMetadata::DOOR_BOTTOM_FLAG_OPEN : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ @@ -64,7 +63,7 @@ class Door extends Transparent{ $this->hingeRight = ($stateMeta & BlockLegacyMetadata::DOOR_TOP_FLAG_RIGHT) !== 0; $this->powered = ($stateMeta & BlockLegacyMetadata::DOOR_TOP_FLAG_POWERED) !== 0; }else{ - $this->facing = Facing::rotateY(BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03), false); + $this->facing = Facing::rotateY(BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03), false); $this->open = ($stateMeta & BlockLegacyMetadata::DOOR_BOTTOM_FLAG_OPEN) !== 0; } } diff --git a/src/pocketmine/block/EndPortalFrame.php b/src/pocketmine/block/EndPortalFrame.php index 9f031e33a0..ae354bdaad 100644 --- a/src/pocketmine/block/EndPortalFrame.php +++ b/src/pocketmine/block/EndPortalFrame.php @@ -23,10 +23,9 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -44,11 +43,11 @@ class EndPortalFrame extends Opaque{ } protected function writeStateToMeta() : int{ - return Bearing::fromFacing($this->facing) | ($this->eye ? BlockLegacyMetadata::END_PORTAL_FRAME_FLAG_EYE : 0); + return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) | ($this->eye ? BlockLegacyMetadata::END_PORTAL_FRAME_FLAG_EYE : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); + $this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03); $this->eye = ($stateMeta & BlockLegacyMetadata::END_PORTAL_FRAME_FLAG_EYE) !== 0; } diff --git a/src/pocketmine/block/EndRod.php b/src/pocketmine/block/EndRod.php index 7da1326657..3f0a925429 100644 --- a/src/pocketmine/block/EndRod.php +++ b/src/pocketmine/block/EndRod.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -41,10 +41,12 @@ class EndRod extends Flowable{ } protected function writeStateToMeta() : int{ - if(Facing::axis($this->facing) === Facing::AXIS_Y){ - return $this->facing; + $result = BlockDataSerializer::writeFacing($this->facing); + if(Facing::axis($this->facing) !== Facing::AXIS_Y){ + $result ^= 1; //TODO: in PC this is always the same as facing, just PE is stupid } - return $this->facing ^ 1; //TODO: in PC this is always the same as facing, just PE is stupid + + return $result; } public function readStateFromData(int $id, int $stateMeta) : void{ @@ -52,7 +54,7 @@ class EndRod extends Flowable{ $stateMeta ^= 1; } - $this->facing = BlockDataValidator::readFacing($stateMeta); + $this->facing = BlockDataSerializer::readFacing($stateMeta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index 1c01cf398d..1144a025e1 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\tile\EnderChest as TileEnderChest; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\item\ToolTier; use pocketmine\math\AxisAlignedBB; @@ -43,11 +43,11 @@ class EnderChest extends Transparent{ } protected function writeStateToMeta() : int{ - return $this->facing; + return BlockDataSerializer::writeHorizontalFacing($this->facing); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); + $this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Farmland.php b/src/pocketmine/block/Farmland.php index 67dafa0efa..96ae4c970b 100644 --- a/src/pocketmine/block/Farmland.php +++ b/src/pocketmine/block/Farmland.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -42,7 +42,7 @@ class Farmland extends Transparent{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->wetness = BlockDataValidator::readBoundedInt("wetness", $stateMeta, 0, 7); + $this->wetness = BlockDataSerializer::readBoundedInt("wetness", $stateMeta, 0, 7); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/FenceGate.php b/src/pocketmine/block/FenceGate.php index 3146a9470c..0991a977c7 100644 --- a/src/pocketmine/block/FenceGate.php +++ b/src/pocketmine/block/FenceGate.php @@ -23,10 +23,9 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -46,13 +45,13 @@ class FenceGate extends Transparent{ } protected function writeStateToMeta() : int{ - return Bearing::fromFacing($this->facing) | + return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) | ($this->open ? BlockLegacyMetadata::FENCE_GATE_FLAG_OPEN : 0) | ($this->inWall ? BlockLegacyMetadata::FENCE_GATE_FLAG_IN_WALL : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); + $this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03); $this->open = ($stateMeta & BlockLegacyMetadata::FENCE_GATE_FLAG_OPEN) !== 0; $this->inWall = ($stateMeta & BlockLegacyMetadata::FENCE_GATE_FLAG_IN_WALL) !== 0; } diff --git a/src/pocketmine/block/Fire.php b/src/pocketmine/block/Fire.php index 24fd42fe85..2d499f1037 100644 --- a/src/pocketmine/block/Fire.php +++ b/src/pocketmine/block/Fire.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\entity\Entity; use pocketmine\entity\projectile\Arrow; use pocketmine\event\block\BlockBurnEvent; @@ -49,7 +49,7 @@ class Fire extends Flowable{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 15); + $this->age = BlockDataSerializer::readBoundedInt("age", $stateMeta, 0, 15); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/FrostedIce.php b/src/pocketmine/block/FrostedIce.php index e3220ea9dc..32c46a6119 100644 --- a/src/pocketmine/block/FrostedIce.php +++ b/src/pocketmine/block/FrostedIce.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use function max; use function mt_rand; @@ -37,7 +37,7 @@ class FrostedIce extends Ice{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 3); + $this->age = BlockDataSerializer::readBoundedInt("age", $stateMeta, 0, 3); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index 1d3af756ef..f04756d792 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\tile\Furnace as TileFurnace; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\item\ToolTier; use pocketmine\math\Facing; @@ -50,11 +50,11 @@ class Furnace extends Opaque{ } protected function writeStateToMeta() : int{ - return $this->facing; + return BlockDataSerializer::writeHorizontalFacing($this->facing); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); + $this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta); $this->lit = $id === $this->idInfo->getSecondId(); } diff --git a/src/pocketmine/block/GlazedTerracotta.php b/src/pocketmine/block/GlazedTerracotta.php index 9efb9c347d..b4d6baebb8 100644 --- a/src/pocketmine/block/GlazedTerracotta.php +++ b/src/pocketmine/block/GlazedTerracotta.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\item\ToolTier; use pocketmine\math\Facing; @@ -42,11 +42,11 @@ class GlazedTerracotta extends Opaque{ } protected function writeStateToMeta() : int{ - return $this->facing; + return BlockDataSerializer::writeHorizontalFacing($this->facing); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); + $this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Hopper.php b/src/pocketmine/block/Hopper.php index 9318dc39a9..26b8e6e12e 100644 --- a/src/pocketmine/block/Hopper.php +++ b/src/pocketmine/block/Hopper.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\tile\Hopper as TileHopper; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; @@ -41,7 +41,7 @@ class Hopper extends Transparent{ private $powered = false; public function readStateFromData(int $id, int $stateMeta) : void{ - $facing = BlockDataValidator::readFacing($stateMeta & 0x07); + $facing = BlockDataSerializer::readFacing($stateMeta & 0x07); if($facing === Facing::UP){ throw new InvalidBlockStateException("Hopper may not face upward"); } @@ -50,7 +50,7 @@ class Hopper extends Transparent{ } protected function writeStateToMeta() : int{ - return $this->facing | ($this->powered ? BlockLegacyMetadata::HOPPER_FLAG_POWERED : 0); + return BlockDataSerializer::writeFacing($this->facing) | ($this->powered ? BlockLegacyMetadata::HOPPER_FLAG_POWERED : 0); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 0eaf1f3173..e082668a63 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\tile\ItemFrame as TileItemFrame; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -51,11 +51,11 @@ class ItemFrame extends Flowable{ } protected function writeStateToMeta() : int{ - return (5 - $this->facing) | ($this->hasMap ? BlockLegacyMetadata::ITEM_FRAME_FLAG_HAS_MAP : 0); + return BlockDataSerializer::write5MinusHorizontalFacing($this->facing) | ($this->hasMap ? BlockLegacyMetadata::ITEM_FRAME_FLAG_HAS_MAP : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::read5MinusHorizontalFacing($stateMeta); + $this->facing = BlockDataSerializer::read5MinusHorizontalFacing($stateMeta); $this->hasMap = ($stateMeta & BlockLegacyMetadata::ITEM_FRAME_FLAG_HAS_MAP) !== 0; } diff --git a/src/pocketmine/block/Ladder.php b/src/pocketmine/block/Ladder.php index 632e712647..9acba0e25b 100644 --- a/src/pocketmine/block/Ladder.php +++ b/src/pocketmine/block/Ladder.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\entity\Entity; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; @@ -42,11 +42,11 @@ class Ladder extends Transparent{ } protected function writeStateToMeta() : int{ - return $this->facing; + return BlockDataSerializer::writeHorizontalFacing($this->facing); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); + $this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Lever.php b/src/pocketmine/block/Lever.php index 6315df7243..6053f80b3b 100644 --- a/src/pocketmine/block/Lever.php +++ b/src/pocketmine/block/Lever.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -54,7 +54,7 @@ class Lever extends Flowable{ }elseif($this->position === self::TOP){ $rotationMeta = Facing::axis($this->facing) === Facing::AXIS_Z ? 5 : 6; }else{ - $rotationMeta = 6 - $this->facing; + $rotationMeta = 6 - BlockDataSerializer::writeHorizontalFacing($this->facing); } return $rotationMeta | ($this->powered ? BlockLegacyMetadata::LEVER_FLAG_POWERED : 0); } @@ -69,7 +69,7 @@ class Lever extends Flowable{ $this->facing = $rotationMeta === 7 ? Facing::SOUTH : Facing::EAST; }else{ $this->position = self::SIDE; - $this->facing = BlockDataValidator::readHorizontalFacing(6 - $rotationMeta); + $this->facing = BlockDataSerializer::readHorizontalFacing(6 - $rotationMeta); } $this->powered = ($stateMeta & BlockLegacyMetadata::LEVER_FLAG_POWERED) !== 0; diff --git a/src/pocketmine/block/Liquid.php b/src/pocketmine/block/Liquid.php index c5005148c5..857a1cfc5d 100644 --- a/src/pocketmine/block/Liquid.php +++ b/src/pocketmine/block/Liquid.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\entity\Entity; use pocketmine\event\block\BlockFormEvent; use pocketmine\event\block\BlockSpreadEvent; @@ -74,7 +74,7 @@ abstract class Liquid extends Transparent{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->decay = BlockDataValidator::readBoundedInt("decay", $stateMeta & 0x07, 0, 7); + $this->decay = BlockDataSerializer::readBoundedInt("decay", $stateMeta & 0x07, 0, 7); $this->falling = ($stateMeta & BlockLegacyMetadata::LIQUID_FLAG_FALLING) !== 0; $this->still = $id === $this->idInfo->getSecondId(); } diff --git a/src/pocketmine/block/NetherReactor.php b/src/pocketmine/block/NetherReactor.php index 90045427da..632ac39333 100644 --- a/src/pocketmine/block/NetherReactor.php +++ b/src/pocketmine/block/NetherReactor.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; @@ -42,7 +42,7 @@ class NetherReactor extends Opaque{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->state = BlockDataValidator::readBoundedInt("state", $stateMeta, 0, 2); + $this->state = BlockDataSerializer::readBoundedInt("state", $stateMeta, 0, 2); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/pocketmine/block/NetherWartPlant.php index 6e47e77381..a678f5c018 100644 --- a/src/pocketmine/block/NetherWartPlant.php +++ b/src/pocketmine/block/NetherWartPlant.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Item; use pocketmine\math\Facing; @@ -47,7 +47,7 @@ class NetherWartPlant extends Flowable{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 3); + $this->age = BlockDataSerializer::readBoundedInt("age", $stateMeta, 0, 3); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/RedstoneComparator.php b/src/pocketmine/block/RedstoneComparator.php index 937f153aec..521a342cdb 100644 --- a/src/pocketmine/block/RedstoneComparator.php +++ b/src/pocketmine/block/RedstoneComparator.php @@ -24,10 +24,9 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\tile\Comparator; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -56,13 +55,13 @@ class RedstoneComparator extends Flowable{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); + $this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03); $this->isSubtractMode = ($stateMeta & BlockLegacyMetadata::REDSTONE_COMPARATOR_FLAG_SUBTRACT) !== 0; $this->powered = ($id === $this->idInfo->getSecondId() or ($stateMeta & BlockLegacyMetadata::REDSTONE_COMPARATOR_FLAG_POWERED) !== 0); } public function writeStateToMeta() : int{ - return Bearing::fromFacing($this->facing) | + return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) | ($this->isSubtractMode ? BlockLegacyMetadata::REDSTONE_COMPARATOR_FLAG_SUBTRACT : 0) | ($this->powered ? BlockLegacyMetadata::REDSTONE_COMPARATOR_FLAG_POWERED : 0); } diff --git a/src/pocketmine/block/RedstoneRepeater.php b/src/pocketmine/block/RedstoneRepeater.php index f1f3ab18f0..e57ead9af4 100644 --- a/src/pocketmine/block/RedstoneRepeater.php +++ b/src/pocketmine/block/RedstoneRepeater.php @@ -23,10 +23,9 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -52,13 +51,13 @@ class RedstoneRepeater extends Flowable{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); - $this->delay = BlockDataValidator::readBoundedInt("delay", ($stateMeta >> 2) + 1, 1, 4); + $this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03); + $this->delay = BlockDataSerializer::readBoundedInt("delay", ($stateMeta >> 2) + 1, 1, 4); $this->powered = $id === $this->idInfo->getSecondId(); } public function writeStateToMeta() : int{ - return Bearing::fromFacing($this->facing) | (($this->delay - 1) << 2); + return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) | (($this->delay - 1) << 2); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/RedstoneWire.php b/src/pocketmine/block/RedstoneWire.php index a665db097c..a59fe563b1 100644 --- a/src/pocketmine/block/RedstoneWire.php +++ b/src/pocketmine/block/RedstoneWire.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; class RedstoneWire extends Flowable{ @@ -35,7 +35,7 @@ class RedstoneWire extends Flowable{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->power = BlockDataValidator::readBoundedInt("power", $stateMeta, 0, 15); + $this->power = BlockDataSerializer::readBoundedInt("power", $stateMeta, 0, 15); } protected function writeStateToMeta() : int{ diff --git a/src/pocketmine/block/Sign.php b/src/pocketmine/block/Sign.php index 21639cea6d..34dc1f75d2 100644 --- a/src/pocketmine/block/Sign.php +++ b/src/pocketmine/block/Sign.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\tile\Sign as TileSign; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\SignText; use pocketmine\event\block\SignChangeEvent; use pocketmine\item\Item; @@ -71,12 +71,12 @@ class Sign extends Transparent{ if($this->facing === Facing::UP){ return $this->rotation; } - return $this->facing; + return BlockDataSerializer::writeHorizontalFacing($this->facing); } public function readStateFromData(int $id, int $stateMeta) : void{ if($id === $this->idInfo->getSecondId()){ - $this->facing = BlockDataValidator::readHorizontalFacing($stateMeta); + $this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta); }else{ $this->facing = Facing::UP; $this->rotation = $stateMeta; diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index f0796b583d..8bf7e454a1 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\tile\Skull as TileSkull; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\SkullType; use pocketmine\item\Item; use pocketmine\item\ItemFactory; @@ -54,11 +54,11 @@ class Skull extends Flowable{ } protected function writeStateToMeta() : int{ - return $this->facing; + return $this->facing === Facing::UP ? 1 : BlockDataSerializer::writeHorizontalFacing($this->facing); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = $stateMeta === 1 ? Facing::UP : BlockDataValidator::readHorizontalFacing($stateMeta); + $this->facing = $stateMeta === 1 ? Facing::UP : BlockDataSerializer::readHorizontalFacing($stateMeta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/SnowLayer.php b/src/pocketmine/block/SnowLayer.php index 8c917d86cc..cbf0e583cc 100644 --- a/src/pocketmine/block/SnowLayer.php +++ b/src/pocketmine/block/SnowLayer.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\Fallable; use pocketmine\block\utils\FallableTrait; use pocketmine\item\Item; @@ -52,7 +52,7 @@ class SnowLayer extends Flowable implements Fallable{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->layers = BlockDataValidator::readBoundedInt("layers", $stateMeta + 1, 1, 8); + $this->layers = BlockDataSerializer::readBoundedInt("layers", $stateMeta + 1, 1, 8); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Stair.php b/src/pocketmine/block/Stair.php index 7b84afbc6a..efd6b8a3b4 100644 --- a/src/pocketmine/block/Stair.php +++ b/src/pocketmine/block/Stair.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\StairShape; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; @@ -48,11 +48,11 @@ class Stair extends Transparent{ } protected function writeStateToMeta() : int{ - return (5 - $this->facing) | ($this->upsideDown ? BlockLegacyMetadata::STAIR_FLAG_UPSIDE_DOWN : 0); + return BlockDataSerializer::write5MinusHorizontalFacing($this->facing) | ($this->upsideDown ? BlockLegacyMetadata::STAIR_FLAG_UPSIDE_DOWN : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::read5MinusHorizontalFacing($stateMeta); + $this->facing = BlockDataSerializer::read5MinusHorizontalFacing($stateMeta); $this->upsideDown = ($stateMeta & BlockLegacyMetadata::STAIR_FLAG_UPSIDE_DOWN) !== 0; } diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index ef30093656..ecdbdb3e9a 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Fertilizer; use pocketmine\item\Item; @@ -46,7 +46,7 @@ class Sugarcane extends Flowable{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->age = BlockDataValidator::readBoundedInt("age", $stateMeta, 0, 15); + $this->age = BlockDataSerializer::readBoundedInt("age", $stateMeta, 0, 15); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Torch.php b/src/pocketmine/block/Torch.php index 1af73c2af7..bbbd5b4dd0 100644 --- a/src/pocketmine/block/Torch.php +++ b/src/pocketmine/block/Torch.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -40,11 +40,11 @@ class Torch extends Flowable{ } protected function writeStateToMeta() : int{ - return 6 - $this->facing; + return $this->facing === Facing::UP ? 5 : 6 - BlockDataSerializer::writeHorizontalFacing($this->facing); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = $stateMeta === 5 ? Facing::UP : BlockDataValidator::readHorizontalFacing(6 - $stateMeta); + $this->facing = $stateMeta === 5 ? Facing::UP : BlockDataSerializer::readHorizontalFacing(6 - $stateMeta); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/Trapdoor.php b/src/pocketmine/block/Trapdoor.php index 4fc3cbe99a..b465f6c72d 100644 --- a/src/pocketmine/block/Trapdoor.php +++ b/src/pocketmine/block/Trapdoor.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -42,13 +42,13 @@ class Trapdoor extends Transparent{ protected $top = false; protected function writeStateToMeta() : int{ - return (5 - $this->facing) | ($this->top ? BlockLegacyMetadata::TRAPDOOR_FLAG_UPPER : 0) | ($this->open ? BlockLegacyMetadata::TRAPDOOR_FLAG_OPEN : 0); + return BlockDataSerializer::write5MinusHorizontalFacing($this->facing) | ($this->top ? BlockLegacyMetadata::TRAPDOOR_FLAG_UPPER : 0) | ($this->open ? BlockLegacyMetadata::TRAPDOOR_FLAG_OPEN : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ //TODO: in PC the values are reversed (facing - 2) - $this->facing = BlockDataValidator::read5MinusHorizontalFacing($stateMeta); + $this->facing = BlockDataSerializer::read5MinusHorizontalFacing($stateMeta); $this->top = ($stateMeta & BlockLegacyMetadata::TRAPDOOR_FLAG_UPPER) !== 0; $this->open = ($stateMeta & BlockLegacyMetadata::TRAPDOOR_FLAG_OPEN) !== 0; } diff --git a/src/pocketmine/block/TripwireHook.php b/src/pocketmine/block/TripwireHook.php index 1cd9be24b5..69eb116b2d 100644 --- a/src/pocketmine/block/TripwireHook.php +++ b/src/pocketmine/block/TripwireHook.php @@ -23,9 +23,8 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; -use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -45,13 +44,13 @@ class TripwireHook extends Flowable{ } protected function writeStateToMeta() : int{ - return Bearing::fromFacing($this->facing) | + return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) | ($this->connected ? BlockLegacyMetadata::TRIPWIRE_HOOK_FLAG_CONNECTED : 0) | ($this->powered ? BlockLegacyMetadata::TRIPWIRE_HOOK_FLAG_POWERED : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataValidator::readLegacyHorizontalFacing($stateMeta & 0x03); + $this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03); $this->connected = ($stateMeta & BlockLegacyMetadata::TRIPWIRE_HOOK_FLAG_CONNECTED) !== 0; $this->powered = ($stateMeta & BlockLegacyMetadata::TRIPWIRE_HOOK_FLAG_POWERED) !== 0; } diff --git a/src/pocketmine/block/WeightedPressurePlate.php b/src/pocketmine/block/WeightedPressurePlate.php index fb3c00051b..a959bf9adc 100644 --- a/src/pocketmine/block/WeightedPressurePlate.php +++ b/src/pocketmine/block/WeightedPressurePlate.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataValidator; +use pocketmine\block\utils\BlockDataSerializer; abstract class WeightedPressurePlate extends PressurePlate{ @@ -35,7 +35,7 @@ abstract class WeightedPressurePlate extends PressurePlate{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->power = BlockDataValidator::readBoundedInt("power", $stateMeta, 0, 15); + $this->power = BlockDataSerializer::readBoundedInt("power", $stateMeta, 0, 15); } public function getStateBitmask() : int{ diff --git a/src/pocketmine/block/utils/BlockDataValidator.php b/src/pocketmine/block/utils/BlockDataSerializer.php similarity index 51% rename from src/pocketmine/block/utils/BlockDataValidator.php rename to src/pocketmine/block/utils/BlockDataSerializer.php index 476de738bf..db0ae9ead4 100644 --- a/src/pocketmine/block/utils/BlockDataValidator.php +++ b/src/pocketmine/block/utils/BlockDataSerializer.php @@ -23,28 +23,48 @@ declare(strict_types=1); namespace pocketmine\block\utils; -use pocketmine\math\Bearing; use pocketmine\math\Facing; -final class BlockDataValidator{ +final class BlockDataSerializer{ private function __construct(){ } /** - * @param int $facing + * @param int $raw * * @return int * @throws InvalidBlockStateException */ - public static function readFacing(int $facing) : int{ - try{ - Facing::validate($facing); - }catch(\InvalidArgumentException $e){ - throw new InvalidBlockStateException("Invalid facing $facing", 0, $e); + public static function readFacing(int $raw) : int{ + static $map = [ //this is for redundancy, for when/if the FACING constant values change + 0 => Facing::DOWN, + 1 => Facing::UP, + 2 => Facing::NORTH, + 3 => Facing::SOUTH, + 4 => Facing::WEST, + 5 => Facing::EAST + ]; + if(!isset($map[$raw])){ + throw new InvalidBlockStateException("Invalid facing $raw"); } - return $facing; + return $map[$raw]; + } + + public static function writeFacing(int $facing) : int{ + static $map = [ //again, for redundancy + Facing::DOWN => 0, + Facing::UP => 1, + Facing::NORTH => 2, + Facing::SOUTH => 3, + Facing::WEST => 4, + Facing::EAST => 5 + ]; + if(!isset($map[$facing])){ + throw new \InvalidArgumentException("Invalid facing $facing"); + } + return $map[$facing]; } /** @@ -61,19 +81,43 @@ final class BlockDataValidator{ return $facing; } + public static function writeHorizontalFacing(int $facing) : int{ + if(Facing::axis($facing) === Facing::AXIS_Y){ + throw new \InvalidArgumentException("Invalid Y-axis facing"); + } + return self::writeFacing($facing); + } + /** - * @param int $facing + * @param int $raw * * @return int * @throws InvalidBlockStateException */ - public static function readLegacyHorizontalFacing(int $facing) : int{ - try{ - $facing = Bearing::toFacing($facing); - }catch(\InvalidArgumentException $e){ - throw new InvalidBlockStateException("Invalid legacy facing $facing"); + public static function readLegacyHorizontalFacing(int $raw) : int{ + static $map = [ //again, for redundancy + 0 => Facing::SOUTH, + 1 => Facing::WEST, + 2 => Facing::NORTH, + 3 => Facing::EAST + ]; + if(!isset($map[$raw])){ + throw new InvalidBlockStateException("Invalid legacy facing $raw"); } - return self::readHorizontalFacing($facing); + return $map[$raw]; + } + + public static function writeLegacyHorizontalFacing(int $facing) : int{ + static $map = [ + Facing::SOUTH => 0, + Facing::WEST => 1, + Facing::NORTH => 2, + Facing::EAST => 3 + ]; + if(!isset($map[$facing])){ + throw new \InvalidArgumentException("Invalid Y-axis facing"); + } + return $map[$facing]; } /** @@ -86,6 +130,10 @@ final class BlockDataValidator{ return self::readHorizontalFacing(5 - ($value & 0x03)); } + public static function write5MinusHorizontalFacing(int $value) : int{ + return 5 - self::writeHorizontalFacing($value); + } + public static function readBoundedInt(string $name, int $v, int $min, int $max) : int{ if($v < $min or $v > $max){ throw new InvalidBlockStateException("$name should be in range $min - $max, got $v"); From 52412e9c21a0c6c502af1eed6e5cda386a40320d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jul 2019 17:45:23 +0100 Subject: [PATCH 1138/3224] remove remaining dependencies on Bearing --- src/pocketmine/entity/Entity.php | 21 ++++++++++--- src/pocketmine/entity/object/Painting.php | 38 ++++++++++++++--------- 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 0cbeb014a2..c52f1cb59f 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -1006,12 +1006,23 @@ abstract class Entity extends Location{ return false; } - public function getDirection() : int{ - return Bearing::fromAngle($this->yaw); - } - public function getHorizontalFacing() : int{ - return Bearing::toFacing($this->getDirection()); + $angle = $this->yaw % 360; + if($angle < 0){ + $angle += 360.0; + } + + if((0 <= $angle and $angle < 45) or (315 <= $angle and $angle < 360)){ + return Facing::SOUTH; + } + if(45 <= $angle and $angle < 135){ + return Facing::WEST; + } + if(135 <= $angle and $angle < 225){ + return Facing::NORTH; + } + + return Facing::EAST; } /** diff --git a/src/pocketmine/entity/object/Painting.php b/src/pocketmine/entity/object/Painting.php index a678040697..546d6ff27b 100644 --- a/src/pocketmine/entity/object/Painting.php +++ b/src/pocketmine/entity/object/Painting.php @@ -28,7 +28,6 @@ use pocketmine\entity\Entity; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\item\VanillaItems; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\nbt\tag\ByteTag; @@ -43,6 +42,19 @@ use function ceil; class Painting extends Entity{ public const NETWORK_ID = EntityLegacyIds::PAINTING; + private const DATA_TO_FACING = [ + 0 => Facing::SOUTH, + 1 => Facing::WEST, + 2 => Facing::NORTH, + 3 => Facing::EAST + ]; + private const FACING_TO_DATA = [ + Facing::SOUTH => 0, + Facing::WEST => 1, + Facing::NORTH => 2, + Facing::EAST => 3 + ]; + /** @var float */ protected $gravity = 0.0; /** @var float */ @@ -57,7 +69,7 @@ class Painting extends Entity{ /** @var Vector3 */ protected $blockIn; /** @var int */ - protected $direction = 0; + protected $facing = Facing::NORTH; /** @var string */ protected $motive; @@ -65,9 +77,9 @@ class Painting extends Entity{ $this->motive = $nbt->getString("Motive"); $this->blockIn = new Vector3($nbt->getInt("TileX"), $nbt->getInt("TileY"), $nbt->getInt("TileZ")); if($nbt->hasTag("Direction", ByteTag::class)){ - $this->direction = $nbt->getByte("Direction"); + $this->facing = self::DATA_TO_FACING[$nbt->getByte("Direction")] ?? Facing::NORTH; }elseif($nbt->hasTag("Facing", ByteTag::class)){ - $this->direction = $nbt->getByte("Facing"); + $this->facing = self::DATA_TO_FACING[$nbt->getByte("Facing")] ?? Facing::NORTH; } parent::__construct($world, $nbt); } @@ -84,8 +96,8 @@ class Painting extends Entity{ $nbt->setInt("TileY", (int) $this->blockIn->y); $nbt->setInt("TileZ", (int) $this->blockIn->z); - $nbt->setByte("Facing", (int) $this->direction); - $nbt->setByte("Direction", (int) $this->direction); //Save both for full compatibility + $nbt->setByte("Facing", self::FACING_TO_DATA[$this->facing]); + $nbt->setByte("Direction", self::FACING_TO_DATA[$this->facing]); //Save both for full compatibility $nbt->setString("Motive", $this->motive); @@ -112,16 +124,14 @@ class Painting extends Entity{ } protected function recalculateBoundingBox() : void{ - $facing = Bearing::toFacing($this->direction); - $side = $this->blockIn->getSide($facing); - $this->boundingBox->setBB(self::getPaintingBB($facing, $this->getMotive())->offset($side->x, $side->y, $side->z)); + $side = $this->blockIn->getSide($this->facing); + $this->boundingBox->setBB(self::getPaintingBB($this->facing, $this->getMotive())->offset($side->x, $side->y, $side->z)); } public function onNearbyBlockChange() : void{ parent::onNearbyBlockChange(); - $face = Bearing::toFacing($this->direction); - if(!self::canFit($this->world, $this->blockIn->getSide($face), $face, false, $this->getMotive())){ + if(!self::canFit($this->world, $this->blockIn->getSide($this->facing), $this->facing, false, $this->getMotive())){ $this->kill(); } } @@ -146,7 +156,7 @@ class Painting extends Entity{ ($this->boundingBox->minY + $this->boundingBox->maxY) / 2, ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2 ); - $pk->direction = $this->direction; + $pk->direction = self::FACING_TO_DATA[$this->facing]; $pk->title = $this->motive; $player->sendDataPacket($pk); @@ -160,8 +170,8 @@ class Painting extends Entity{ return PaintingMotive::getMotiveByName($this->motive); } - public function getDirection() : int{ - return $this->direction; + public function getFacing() : int{ + return $this->facing; } /** From 17a3ca066eab806a79add2fed0f3240251d83103 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jul 2019 17:50:02 +0100 Subject: [PATCH 1139/3224] fix wrong type for Fuel tag on brewing stand --- src/pocketmine/block/tile/BrewingStand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/block/tile/BrewingStand.php b/src/pocketmine/block/tile/BrewingStand.php index 0fc0b5118b..6c4a02c84a 100644 --- a/src/pocketmine/block/tile/BrewingStand.php +++ b/src/pocketmine/block/tile/BrewingStand.php @@ -38,7 +38,7 @@ class BrewingStand extends Spawnable implements Container, Nameable{ private const TAG_BREW_TIME = "BrewTime"; //TAG_Short private const TAG_BREW_TIME_PE = "CookTime"; //TAG_Short private const TAG_MAX_FUEL_TIME = "FuelTotal"; //TAG_Short - private const TAG_REMAINING_FUEL_TIME = "Fuel"; //TAG_Short + private const TAG_REMAINING_FUEL_TIME = "Fuel"; //TAG_Byte private const TAG_REMAINING_FUEL_TIME_PE = "FuelAmount"; //TAG_Short /** @var BrewingStandInventory */ @@ -66,7 +66,7 @@ class BrewingStand extends Spawnable implements Container, Nameable{ $this->brewTime = $nbt->getShort(self::TAG_BREW_TIME, $nbt->getShort(self::TAG_BREW_TIME_PE, 0)); $this->maxFuelTime = $nbt->getShort(self::TAG_MAX_FUEL_TIME, 0); - $this->remainingFuelTime = $nbt->getShort(self::TAG_REMAINING_FUEL_TIME, $nbt->getShort(self::TAG_REMAINING_FUEL_TIME_PE, 0)); + $this->remainingFuelTime = $nbt->getByte(self::TAG_REMAINING_FUEL_TIME, $nbt->getShort(self::TAG_REMAINING_FUEL_TIME_PE, 0)); if($this->maxFuelTime === 0){ $this->maxFuelTime = $this->remainingFuelTime; } From 1111d0d4c7f4e4fbe0f71415db017da3d54ad547 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jul 2019 18:00:23 +0100 Subject: [PATCH 1140/3224] World: remove dead function getChunkTiles() --- src/pocketmine/world/World.php | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index b1f233bbec..50a0be869e 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -1964,18 +1964,6 @@ class World implements ChunkManager{ return ($chunk = $this->getChunk($X, $Z)) !== null ? $chunk->getEntities() : []; } - /** - * Gives a list of the Tile entities on a given chunk - * - * @param int $X - * @param int $Z - * - * @return Tile[] - */ - public function getChunkTiles(int $X, int $Z) : array{ - return ($chunk = $this->getChunk($X, $Z)) !== null ? $chunk->getTiles() : []; - } - /** * Gets the raw block skylight level * From a4042e5d1828336b147b34ae6e330ddd8c7ddb39 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jul 2019 18:07:17 +0100 Subject: [PATCH 1141/3224] World: fix more implicit chunk loading bugs (getCollidingEntities(), getNearbyEntities(), getNearestEntity()) --- src/pocketmine/world/World.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 50a0be869e..97aa5132bd 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -1826,6 +1826,9 @@ class World implements ChunkManager{ for($x = $minX; $x <= $maxX; ++$x){ for($z = $minZ; $z <= $maxZ; ++$z){ + if(!$this->isChunkLoaded($x, $z)){ + continue; + } foreach($this->getChunkEntities($x, $z) as $ent){ /** @var Entity|null $entity */ if($ent->canBeCollidedWith() and ($entity === null or ($ent !== $entity and $entity->canCollideWith($ent))) and $ent->boundingBox->intersectsWith($bb)){ @@ -1857,6 +1860,9 @@ class World implements ChunkManager{ for($x = $minX; $x <= $maxX; ++$x){ for($z = $minZ; $z <= $maxZ; ++$z){ + if(!$this->isChunkLoaded($x, $z)){ + continue; + } foreach($this->getChunkEntities($x, $z) as $ent){ if($ent !== $entity and $ent->boundingBox->intersectsWith($bb)){ $nearby[] = $ent; @@ -1893,6 +1899,9 @@ class World implements ChunkManager{ for($x = $minX; $x <= $maxX; ++$x){ for($z = $minZ; $z <= $maxZ; ++$z){ + if(!$this->isChunkLoaded($x, $z)){ + continue; + } foreach($this->getChunkEntities($x, $z) as $entity){ if(!($entity instanceof $entityType) or $entity->isFlaggedForDespawn() or (!$includeDead and !$entity->isAlive())){ continue; From 452cfe2f5999df2206746f8d0fae683feab32d8b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jul 2019 18:20:33 +0100 Subject: [PATCH 1142/3224] World: drop getChunkEntities(), use getChunk()->getEntities() everywhere this function is used, it should be assumed/expected that the chunk in question is already present and loaded. --- src/pocketmine/player/Player.php | 4 ++-- src/pocketmine/world/World.php | 18 +++--------------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index e364d11bee..8d231406c0 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -827,7 +827,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $world = $world ?? $this->world; $index = World::chunkHash($x, $z); if(isset($this->usedChunks[$index])){ - foreach($world->getChunkEntities($x, $z) as $entity){ + foreach($world->getChunk($x, $z)->getEntities() as $entity){ if($entity !== $this){ $entity->despawnFrom($this); } @@ -841,7 +841,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } protected function spawnEntitiesOnChunk(int $chunkX, int $chunkZ) : void{ - foreach($this->world->getChunkEntities($chunkX, $chunkZ) as $entity){ + foreach($this->world->getChunk($chunkX, $chunkZ)->getEntities() as $entity){ if($entity !== $this and !$entity->isFlaggedForDespawn()){ $entity->spawnTo($this); } diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index 97aa5132bd..c40b55a0ad 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -1829,7 +1829,7 @@ class World implements ChunkManager{ if(!$this->isChunkLoaded($x, $z)){ continue; } - foreach($this->getChunkEntities($x, $z) as $ent){ + foreach($this->getChunk($x, $z)->getEntities() as $ent){ /** @var Entity|null $entity */ if($ent->canBeCollidedWith() and ($entity === null or ($ent !== $entity and $entity->canCollideWith($ent))) and $ent->boundingBox->intersectsWith($bb)){ $nearby[] = $ent; @@ -1863,7 +1863,7 @@ class World implements ChunkManager{ if(!$this->isChunkLoaded($x, $z)){ continue; } - foreach($this->getChunkEntities($x, $z) as $ent){ + foreach($this->getChunk($x, $z)->getEntities() as $ent){ if($ent !== $entity and $ent->boundingBox->intersectsWith($bb)){ $nearby[] = $ent; } @@ -1902,7 +1902,7 @@ class World implements ChunkManager{ if(!$this->isChunkLoaded($x, $z)){ continue; } - foreach($this->getChunkEntities($x, $z) as $entity){ + foreach($this->getChunk($x, $z)->getEntities() as $entity){ if(!($entity instanceof $entityType) or $entity->isFlaggedForDespawn() or (!$includeDead and !$entity->isAlive())){ continue; } @@ -1961,18 +1961,6 @@ class World implements ChunkManager{ return ($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null ? $chunk->getTile($x & 0x0f, $y, $z & 0x0f) : null; } - /** - * Returns a list of the entities on a given chunk - * - * @param int $X - * @param int $Z - * - * @return Entity[] - */ - public function getChunkEntities(int $X, int $Z) : array{ - return ($chunk = $this->getChunk($X, $Z)) !== null ? $chunk->getEntities() : []; - } - /** * Gets the raw block skylight level * From 96d879002843360daee014abc68b607901a35bac Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jul 2019 18:24:29 +0100 Subject: [PATCH 1143/3224] rename Entity->propertyManager -> Entity->networkProperties --- src/pocketmine/entity/Animal.php | 2 +- src/pocketmine/entity/Entity.php | 48 +++++++++---------- src/pocketmine/entity/Living.php | 10 ++-- src/pocketmine/entity/Villager.php | 4 +- src/pocketmine/entity/WaterAnimal.php | 2 +- .../entity/object/ExperienceOrb.php | 2 +- src/pocketmine/entity/object/FallingBlock.php | 2 +- src/pocketmine/entity/object/PrimedTNT.php | 4 +- src/pocketmine/entity/projectile/Arrow.php | 2 +- .../entity/projectile/SplashPotion.php | 4 +- src/pocketmine/player/Player.php | 6 +-- 11 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/pocketmine/entity/Animal.php b/src/pocketmine/entity/Animal.php index 09fd1c685f..b3116653f0 100644 --- a/src/pocketmine/entity/Animal.php +++ b/src/pocketmine/entity/Animal.php @@ -36,6 +36,6 @@ abstract class Animal extends Living implements Ageable{ protected function syncNetworkData() : void{ parent::syncNetworkData(); - $this->propertyManager->setGenericFlag(EntityMetadataFlags::BABY, $this->baby); + $this->networkProperties->setGenericFlag(EntityMetadataFlags::BABY, $this->baby); } } diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index c52f1cb59f..77886ef45c 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -93,7 +93,7 @@ abstract class Entity extends Location{ protected $id; /** @var EntityMetadataCollection */ - protected $propertyManager; + protected $networkProperties; /** @var Chunk|null */ public $chunk; @@ -261,7 +261,7 @@ abstract class Entity extends Location{ $this->resetLastMovements(); - $this->propertyManager = new EntityMetadataCollection(); + $this->networkProperties = new EntityMetadataCollection(); $this->attributeMap = new AttributeMap(); $this->addAttributes(); @@ -709,8 +709,8 @@ abstract class Entity extends Location{ return $this->attributeMap; } - public function getDataPropertyManager() : EntityMetadataCollection{ - return $this->propertyManager; + public function getNetworkProperties() : EntityMetadataCollection{ + return $this->networkProperties; } protected function entityBaseTick(int $tickDiff = 1) : bool{ @@ -721,7 +721,7 @@ abstract class Entity extends Location{ $changedProperties = $this->getSyncedNetworkData(true); if(!empty($changedProperties)){ $this->sendData($this->hasSpawned, $changedProperties); - $this->propertyManager->clearDirtyProperties(); + $this->networkProperties->clearDirtyProperties(); } $hasUpdate = false; @@ -1755,29 +1755,29 @@ abstract class Entity extends Location{ final protected function getSyncedNetworkData(bool $dirtyOnly) : array{ $this->syncNetworkData(); - return $dirtyOnly ? $this->propertyManager->getDirty() : $this->propertyManager->getAll(); + return $dirtyOnly ? $this->networkProperties->getDirty() : $this->networkProperties->getAll(); } protected function syncNetworkData() : void{ - $this->propertyManager->setByte(EntityMetadataProperties::ALWAYS_SHOW_NAMETAG, $this->alwaysShowNameTag ? 1 : 0); - $this->propertyManager->setFloat(EntityMetadataProperties::BOUNDING_BOX_HEIGHT, $this->height); - $this->propertyManager->setFloat(EntityMetadataProperties::BOUNDING_BOX_WIDTH, $this->width); - $this->propertyManager->setFloat(EntityMetadataProperties::SCALE, $this->scale); - $this->propertyManager->setLong(EntityMetadataProperties::LEAD_HOLDER_EID, -1); - $this->propertyManager->setLong(EntityMetadataProperties::OWNER_EID, $this->ownerId ?? -1); - $this->propertyManager->setLong(EntityMetadataProperties::TARGET_EID, $this->targetId ?? -1); - $this->propertyManager->setString(EntityMetadataProperties::NAMETAG, $this->nameTag); - $this->propertyManager->setString(EntityMetadataProperties::SCORE_TAG, $this->scoreTag); + $this->networkProperties->setByte(EntityMetadataProperties::ALWAYS_SHOW_NAMETAG, $this->alwaysShowNameTag ? 1 : 0); + $this->networkProperties->setFloat(EntityMetadataProperties::BOUNDING_BOX_HEIGHT, $this->height); + $this->networkProperties->setFloat(EntityMetadataProperties::BOUNDING_BOX_WIDTH, $this->width); + $this->networkProperties->setFloat(EntityMetadataProperties::SCALE, $this->scale); + $this->networkProperties->setLong(EntityMetadataProperties::LEAD_HOLDER_EID, -1); + $this->networkProperties->setLong(EntityMetadataProperties::OWNER_EID, $this->ownerId ?? -1); + $this->networkProperties->setLong(EntityMetadataProperties::TARGET_EID, $this->targetId ?? -1); + $this->networkProperties->setString(EntityMetadataProperties::NAMETAG, $this->nameTag); + $this->networkProperties->setString(EntityMetadataProperties::SCORE_TAG, $this->scoreTag); - $this->propertyManager->setGenericFlag(EntityMetadataFlags::AFFECTED_BY_GRAVITY, true); - $this->propertyManager->setGenericFlag(EntityMetadataFlags::CAN_CLIMB, $this->canClimb); - $this->propertyManager->setGenericFlag(EntityMetadataFlags::CAN_SHOW_NAMETAG, $this->nameTagVisible); - $this->propertyManager->setGenericFlag(EntityMetadataFlags::HAS_COLLISION, true); - $this->propertyManager->setGenericFlag(EntityMetadataFlags::IMMOBILE, $this->immobile); - $this->propertyManager->setGenericFlag(EntityMetadataFlags::INVISIBLE, $this->invisible); - $this->propertyManager->setGenericFlag(EntityMetadataFlags::ONFIRE, $this->isOnFire()); - $this->propertyManager->setGenericFlag(EntityMetadataFlags::SNEAKING, $this->sneaking); - $this->propertyManager->setGenericFlag(EntityMetadataFlags::WALLCLIMBING, $this->canClimbWalls); + $this->networkProperties->setGenericFlag(EntityMetadataFlags::AFFECTED_BY_GRAVITY, true); + $this->networkProperties->setGenericFlag(EntityMetadataFlags::CAN_CLIMB, $this->canClimb); + $this->networkProperties->setGenericFlag(EntityMetadataFlags::CAN_SHOW_NAMETAG, $this->nameTagVisible); + $this->networkProperties->setGenericFlag(EntityMetadataFlags::HAS_COLLISION, true); + $this->networkProperties->setGenericFlag(EntityMetadataFlags::IMMOBILE, $this->immobile); + $this->networkProperties->setGenericFlag(EntityMetadataFlags::INVISIBLE, $this->invisible); + $this->networkProperties->setGenericFlag(EntityMetadataFlags::ONFIRE, $this->isOnFire()); + $this->networkProperties->setGenericFlag(EntityMetadataFlags::SNEAKING, $this->sneaking); + $this->networkProperties->setGenericFlag(EntityMetadataFlags::WALLCLIMBING, $this->canClimbWalls); } public function broadcastEntityEvent(int $eventId, ?int $eventData = null, ?array $players = null) : void{ diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 7a922b5157..d7be4444ee 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -770,12 +770,12 @@ abstract class Living extends Entity{ protected function syncNetworkData() : void{ parent::syncNetworkData(); - $this->propertyManager->setByte(EntityMetadataProperties::POTION_AMBIENT, $this->effectManager->hasOnlyAmbientEffects() ? 1 : 0); - $this->propertyManager->setInt(EntityMetadataProperties::POTION_COLOR, Binary::signInt($this->effectManager->getBubbleColor()->toARGB())); - $this->propertyManager->setShort(EntityMetadataProperties::AIR, $this->breathTicks); - $this->propertyManager->setShort(EntityMetadataProperties::MAX_AIR, $this->maxBreathTicks); + $this->networkProperties->setByte(EntityMetadataProperties::POTION_AMBIENT, $this->effectManager->hasOnlyAmbientEffects() ? 1 : 0); + $this->networkProperties->setInt(EntityMetadataProperties::POTION_COLOR, Binary::signInt($this->effectManager->getBubbleColor()->toARGB())); + $this->networkProperties->setShort(EntityMetadataProperties::AIR, $this->breathTicks); + $this->networkProperties->setShort(EntityMetadataProperties::MAX_AIR, $this->maxBreathTicks); - $this->propertyManager->setGenericFlag(EntityMetadataFlags::BREATHING, $this->breathing); + $this->networkProperties->setGenericFlag(EntityMetadataFlags::BREATHING, $this->breathing); } protected function onDispose() : void{ diff --git a/src/pocketmine/entity/Villager.php b/src/pocketmine/entity/Villager.php index 9172a94775..cfe07247d3 100644 --- a/src/pocketmine/entity/Villager.php +++ b/src/pocketmine/entity/Villager.php @@ -88,8 +88,8 @@ class Villager extends Living implements Ageable{ protected function syncNetworkData() : void{ parent::syncNetworkData(); - $this->propertyManager->setGenericFlag(EntityMetadataFlags::BABY, $this->baby); + $this->networkProperties->setGenericFlag(EntityMetadataFlags::BABY, $this->baby); - $this->propertyManager->setInt(EntityMetadataProperties::VARIANT, $this->profession); + $this->networkProperties->setInt(EntityMetadataProperties::VARIANT, $this->profession); } } diff --git a/src/pocketmine/entity/WaterAnimal.php b/src/pocketmine/entity/WaterAnimal.php index a6aeb6a8f8..9217667115 100644 --- a/src/pocketmine/entity/WaterAnimal.php +++ b/src/pocketmine/entity/WaterAnimal.php @@ -45,6 +45,6 @@ abstract class WaterAnimal extends Living implements Ageable{ protected function syncNetworkData() : void{ parent::syncNetworkData(); - $this->propertyManager->setGenericFlag(EntityMetadataFlags::BABY, $this->baby); + $this->networkProperties->setGenericFlag(EntityMetadataFlags::BABY, $this->baby); } } diff --git a/src/pocketmine/entity/object/ExperienceOrb.php b/src/pocketmine/entity/object/ExperienceOrb.php index ce4baaded6..391a3351f5 100644 --- a/src/pocketmine/entity/object/ExperienceOrb.php +++ b/src/pocketmine/entity/object/ExperienceOrb.php @@ -232,6 +232,6 @@ class ExperienceOrb extends Entity{ protected function syncNetworkData() : void{ parent::syncNetworkData(); - $this->propertyManager->setInt(EntityMetadataProperties::EXPERIENCE_VALUE, $this->xpValue); + $this->networkProperties->setInt(EntityMetadataProperties::EXPERIENCE_VALUE, $this->xpValue); } } diff --git a/src/pocketmine/entity/object/FallingBlock.php b/src/pocketmine/entity/object/FallingBlock.php index 99e2b8ea81..1cc0770303 100644 --- a/src/pocketmine/entity/object/FallingBlock.php +++ b/src/pocketmine/entity/object/FallingBlock.php @@ -140,6 +140,6 @@ class FallingBlock extends Entity{ protected function syncNetworkData() : void{ parent::syncNetworkData(); - $this->propertyManager->setInt(EntityMetadataProperties::VARIANT, $this->block->getRuntimeId()); + $this->networkProperties->setInt(EntityMetadataProperties::VARIANT, $this->block->getRuntimeId()); } } diff --git a/src/pocketmine/entity/object/PrimedTNT.php b/src/pocketmine/entity/object/PrimedTNT.php index 23f6deaea0..6375dd3ba2 100644 --- a/src/pocketmine/entity/object/PrimedTNT.php +++ b/src/pocketmine/entity/object/PrimedTNT.php @@ -111,7 +111,7 @@ class PrimedTNT extends Entity implements Explosive{ protected function syncNetworkData() : void{ parent::syncNetworkData(); - $this->propertyManager->setGenericFlag(EntityMetadataFlags::IGNITED, true); - $this->propertyManager->setInt(EntityMetadataProperties::FUSE_LENGTH, $this->fuse); + $this->networkProperties->setGenericFlag(EntityMetadataFlags::IGNITED, true); + $this->networkProperties->setInt(EntityMetadataProperties::FUSE_LENGTH, $this->fuse); } } diff --git a/src/pocketmine/entity/projectile/Arrow.php b/src/pocketmine/entity/projectile/Arrow.php index 91f4de3d1b..496670382d 100644 --- a/src/pocketmine/entity/projectile/Arrow.php +++ b/src/pocketmine/entity/projectile/Arrow.php @@ -206,6 +206,6 @@ class Arrow extends Projectile{ protected function syncNetworkData() : void{ parent::syncNetworkData(); - $this->propertyManager->setGenericFlag(EntityMetadataFlags::CRITICAL, $this->critical); + $this->networkProperties->setGenericFlag(EntityMetadataFlags::CRITICAL, $this->critical); } } diff --git a/src/pocketmine/entity/projectile/SplashPotion.php b/src/pocketmine/entity/projectile/SplashPotion.php index bed33146a8..5c4aff1fd1 100644 --- a/src/pocketmine/entity/projectile/SplashPotion.php +++ b/src/pocketmine/entity/projectile/SplashPotion.php @@ -181,7 +181,7 @@ class SplashPotion extends Throwable{ protected function syncNetworkData() : void{ parent::syncNetworkData(); - $this->propertyManager->setShort(EntityMetadataProperties::POTION_AUX_VALUE, $this->potionId); - $this->propertyManager->setGenericFlag(EntityMetadataFlags::LINGER, $this->linger); + $this->networkProperties->setShort(EntityMetadataProperties::POTION_AUX_VALUE, $this->potionId); + $this->networkProperties->setGenericFlag(EntityMetadataFlags::LINGER, $this->linger); } } diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index 8d231406c0..61167c4c7d 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -2364,10 +2364,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, protected function syncNetworkData() : void{ parent::syncNetworkData(); - $this->propertyManager->setGenericFlag(EntityMetadataFlags::ACTION, $this->startAction > -1); + $this->networkProperties->setGenericFlag(EntityMetadataFlags::ACTION, $this->startAction > -1); - $this->propertyManager->setPlayerFlag(PlayerMetadataFlags::SLEEP, $this->sleeping !== null); - $this->propertyManager->setBlockPos(EntityMetadataProperties::PLAYER_BED_POSITION, $this->sleeping ?? new Vector3(0, 0, 0)); + $this->networkProperties->setPlayerFlag(PlayerMetadataFlags::SLEEP, $this->sleeping !== null); + $this->networkProperties->setBlockPos(EntityMetadataProperties::PLAYER_BED_POSITION, $this->sleeping ?? new Vector3(0, 0, 0)); } public function broadcastEntityEvent(int $eventId, ?int $eventData = null, ?array $players = null) : void{ From c40074d0bf6fa0cbb38573a9e8372865950001a4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jul 2019 18:25:05 +0100 Subject: [PATCH 1144/3224] Entity: remove unused import --- src/pocketmine/entity/Entity.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 77886ef45c..c046d64330 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -35,7 +35,6 @@ use pocketmine\event\entity\EntityRegainHealthEvent; use pocketmine\event\entity\EntitySpawnEvent; use pocketmine\event\entity\EntityTeleportEvent; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Bearing; use pocketmine\math\Facing; use pocketmine\math\Vector2; use pocketmine\math\Vector3; From 334d15339f2948d8f4dce71e13be459f37b19646 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jul 2019 18:25:32 +0100 Subject: [PATCH 1145/3224] updated Math dependency --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index c4713cfb7c..df0667b0d7 100644 --- a/composer.lock +++ b/composer.lock @@ -333,12 +333,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "b0380415d0b60833b664e2756ad5b25d445109a7" + "reference": "d436a98b85edd18d7b1542fab66827b1e6fc8d68" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/b0380415d0b60833b664e2756ad5b25d445109a7", - "reference": "b0380415d0b60833b664e2756ad5b25d445109a7", + "url": "https://api.github.com/repos/pmmp/Math/zipball/d436a98b85edd18d7b1542fab66827b1e6fc8d68", + "reference": "d436a98b85edd18d7b1542fab66827b1e6fc8d68", "shasum": "" }, "require": { @@ -364,7 +364,7 @@ "source": "https://github.com/pmmp/Math/tree/master", "issues": "https://github.com/pmmp/Math/issues" }, - "time": "2019-06-06T14:58:02+00:00" + "time": "2019-07-29T16:46:11+00:00" }, { "name": "pocketmine/nbt", From 2ecdea2cc69983198008835ebbe39d2397d21f16 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jul 2019 18:54:27 +0100 Subject: [PATCH 1146/3224] LevelDB: increase default block size to 64KB this might be a little too big, but it's definitely better than the leveldb default 4KB, since most of our data is bigger than 4KB. --- src/pocketmine/world/format/io/leveldb/LevelDB.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/world/format/io/leveldb/LevelDB.php b/src/pocketmine/world/format/io/leveldb/LevelDB.php index 9b9e0a06f6..c3ffe5bf8a 100644 --- a/src/pocketmine/world/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/world/format/io/leveldb/LevelDB.php @@ -114,7 +114,8 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ */ private static function createDB(string $path) : \LevelDB{ return new \LevelDB($path . "/db", [ - "compression" => LEVELDB_ZLIB_RAW_COMPRESSION + "compression" => LEVELDB_ZLIB_RAW_COMPRESSION, + "block_size" => 64 * 1024 //64KB, big enough for most chunks ]); } From cf1b140d5747037167b085784a0145dc10c85b6b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jul 2019 19:38:47 +0100 Subject: [PATCH 1147/3224] fix chunks with entities & tiles not being saved after first autosave this bug was introduced by 211836274f7008b83cab6f5ec40be539bff159d7, which did not take into consideration that the dirty flag is cleared after the first time the chunk is saved, meaning that later entity and tile changes wouldn't be saved. I considered this fix more elegant than reverting the bug commit. --- src/pocketmine/world/format/Chunk.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/world/format/Chunk.php b/src/pocketmine/world/format/Chunk.php index 4d3df4e0ad..d083a61e25 100644 --- a/src/pocketmine/world/format/Chunk.php +++ b/src/pocketmine/world/format/Chunk.php @@ -618,7 +618,7 @@ class Chunk{ * @return bool */ public function hasChanged() : bool{ - return $this->hasChanged; + return $this->hasChanged or !empty($this->tiles) or !empty($this->getSavableEntities()); } /** From ece28e5d7b0d4c8d12a9477cdd1d3337277e892d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 30 Jul 2019 18:01:23 +0100 Subject: [PATCH 1148/3224] World: avoid triggering light updates when the target block light level/filter haven't changed --- src/pocketmine/world/World.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/world/World.php b/src/pocketmine/world/World.php index afb04043a1..32edf71eef 100644 --- a/src/pocketmine/world/World.php +++ b/src/pocketmine/world/World.php @@ -1483,6 +1483,8 @@ class World implements ChunkManager{ $this->timings->setBlock->startTiming(); + $oldBlock = $this->getBlockAt($x, $y, $z, true, false); + $block = clone $block; $block->position($this, $x, $y, $z); @@ -1503,7 +1505,9 @@ class World implements ChunkManager{ } if($update){ - $this->updateAllLight($block); + if($oldBlock->getLightFilter() !== $block->getLightFilter() or $oldBlock->getLightLevel() !== $block->getLightLevel()){ + $this->updateAllLight($block); + } $this->tryAddToNeighbourUpdateQueue($block); foreach($block->sides() as $side){ $this->tryAddToNeighbourUpdateQueue($side); From 5499ac620c61ea335c2151a2750b7f6cc6dc7e75 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 30 Jul 2019 19:14:57 +0100 Subject: [PATCH 1149/3224] Removed pocketmine subdirectory, map PSR-4 style --- composer.json | 2 +- src/{pocketmine => }/CrashDump.php | 0 src/{pocketmine => }/MemoryManager.php | 0 src/{pocketmine => }/PocketMine.php | 2 +- src/{pocketmine => }/Server.php | 0 src/{pocketmine => }/VersionInfo.php | 0 src/{pocketmine => }/block/ActivatorRail.php | 0 src/{pocketmine => }/block/Air.php | 0 src/{pocketmine => }/block/Anvil.php | 0 src/{pocketmine => }/block/Banner.php | 0 src/{pocketmine => }/block/BaseRail.php | 0 src/{pocketmine => }/block/Bed.php | 0 src/{pocketmine => }/block/Bedrock.php | 0 src/{pocketmine => }/block/Beetroot.php | 0 src/{pocketmine => }/block/Block.php | 0 src/{pocketmine => }/block/BlockBreakInfo.php | 0 src/{pocketmine => }/block/BlockFactory.php | 0 src/{pocketmine => }/block/BlockIdentifier.php | 0 src/{pocketmine => }/block/BlockIdentifierFlattened.php | 0 src/{pocketmine => }/block/BlockLegacyIds.php | 0 src/{pocketmine => }/block/BlockLegacyMetadata.php | 0 src/{pocketmine => }/block/BlockToolType.php | 0 src/{pocketmine => }/block/BlueIce.php | 0 src/{pocketmine => }/block/BoneBlock.php | 0 src/{pocketmine => }/block/Bookshelf.php | 0 src/{pocketmine => }/block/BrewingStand.php | 0 src/{pocketmine => }/block/BrownMushroom.php | 0 src/{pocketmine => }/block/BrownMushroomBlock.php | 0 src/{pocketmine => }/block/Button.php | 0 src/{pocketmine => }/block/Cactus.php | 0 src/{pocketmine => }/block/Cake.php | 0 src/{pocketmine => }/block/Carpet.php | 0 src/{pocketmine => }/block/Carrot.php | 0 src/{pocketmine => }/block/CarvedPumpkin.php | 0 src/{pocketmine => }/block/Chest.php | 0 src/{pocketmine => }/block/Clay.php | 0 src/{pocketmine => }/block/Coal.php | 0 src/{pocketmine => }/block/CoalOre.php | 0 src/{pocketmine => }/block/CoarseDirt.php | 0 src/{pocketmine => }/block/Cobweb.php | 0 src/{pocketmine => }/block/CocoaBlock.php | 0 src/{pocketmine => }/block/Concrete.php | 0 src/{pocketmine => }/block/ConcretePowder.php | 0 src/{pocketmine => }/block/CraftingTable.php | 0 src/{pocketmine => }/block/Crops.php | 0 src/{pocketmine => }/block/DaylightSensor.php | 0 src/{pocketmine => }/block/DeadBush.php | 0 src/{pocketmine => }/block/DetectorRail.php | 0 src/{pocketmine => }/block/DiamondOre.php | 0 src/{pocketmine => }/block/Dirt.php | 0 src/{pocketmine => }/block/Door.php | 0 src/{pocketmine => }/block/DoublePlant.php | 0 src/{pocketmine => }/block/DoubleTallGrass.php | 0 src/{pocketmine => }/block/DragonEgg.php | 0 src/{pocketmine => }/block/DriedKelp.php | 0 src/{pocketmine => }/block/Element.php | 0 src/{pocketmine => }/block/EmeraldOre.php | 0 src/{pocketmine => }/block/EnchantingTable.php | 0 src/{pocketmine => }/block/EndPortalFrame.php | 0 src/{pocketmine => }/block/EndRod.php | 0 src/{pocketmine => }/block/EnderChest.php | 0 src/{pocketmine => }/block/Farmland.php | 0 src/{pocketmine => }/block/Fence.php | 0 src/{pocketmine => }/block/FenceGate.php | 0 src/{pocketmine => }/block/Fire.php | 0 src/{pocketmine => }/block/Flowable.php | 0 src/{pocketmine => }/block/Flower.php | 0 src/{pocketmine => }/block/FlowerPot.php | 0 src/{pocketmine => }/block/FrostedIce.php | 0 src/{pocketmine => }/block/Furnace.php | 0 src/{pocketmine => }/block/Glass.php | 0 src/{pocketmine => }/block/GlassPane.php | 0 src/{pocketmine => }/block/GlazedTerracotta.php | 0 src/{pocketmine => }/block/GlowingObsidian.php | 0 src/{pocketmine => }/block/Glowstone.php | 0 src/{pocketmine => }/block/Grass.php | 0 src/{pocketmine => }/block/GrassPath.php | 0 src/{pocketmine => }/block/Gravel.php | 0 src/{pocketmine => }/block/HardenedClay.php | 0 src/{pocketmine => }/block/HardenedGlass.php | 0 src/{pocketmine => }/block/HardenedGlassPane.php | 0 src/{pocketmine => }/block/HayBale.php | 0 src/{pocketmine => }/block/Hopper.php | 0 src/{pocketmine => }/block/Ice.php | 0 src/{pocketmine => }/block/InfestedStone.php | 0 src/{pocketmine => }/block/ItemFrame.php | 0 src/{pocketmine => }/block/Ladder.php | 0 src/{pocketmine => }/block/Lantern.php | 0 src/{pocketmine => }/block/LapisOre.php | 0 src/{pocketmine => }/block/Lava.php | 0 src/{pocketmine => }/block/Leaves.php | 0 src/{pocketmine => }/block/Lever.php | 0 src/{pocketmine => }/block/Liquid.php | 0 src/{pocketmine => }/block/LitPumpkin.php | 0 src/{pocketmine => }/block/Log.php | 0 src/{pocketmine => }/block/Magma.php | 0 src/{pocketmine => }/block/Melon.php | 0 src/{pocketmine => }/block/MelonStem.php | 0 src/{pocketmine => }/block/MonsterSpawner.php | 0 src/{pocketmine => }/block/Mycelium.php | 0 src/{pocketmine => }/block/NetherPortal.php | 0 src/{pocketmine => }/block/NetherQuartzOre.php | 0 src/{pocketmine => }/block/NetherReactor.php | 0 src/{pocketmine => }/block/NetherWartPlant.php | 0 src/{pocketmine => }/block/Netherrack.php | 0 src/{pocketmine => }/block/Note.php | 0 src/{pocketmine => }/block/Opaque.php | 0 src/{pocketmine => }/block/PackedIce.php | 0 src/{pocketmine => }/block/Planks.php | 0 src/{pocketmine => }/block/Podzol.php | 0 src/{pocketmine => }/block/Potato.php | 0 src/{pocketmine => }/block/PoweredRail.php | 0 src/{pocketmine => }/block/PressurePlate.php | 0 src/{pocketmine => }/block/PumpkinStem.php | 0 src/{pocketmine => }/block/Rail.php | 0 src/{pocketmine => }/block/RedMushroom.php | 0 src/{pocketmine => }/block/RedMushroomBlock.php | 0 src/{pocketmine => }/block/Redstone.php | 0 src/{pocketmine => }/block/RedstoneComparator.php | 0 src/{pocketmine => }/block/RedstoneLamp.php | 0 src/{pocketmine => }/block/RedstoneOre.php | 0 src/{pocketmine => }/block/RedstoneRail.php | 0 src/{pocketmine => }/block/RedstoneRepeater.php | 0 src/{pocketmine => }/block/RedstoneTorch.php | 0 src/{pocketmine => }/block/RedstoneWire.php | 0 src/{pocketmine => }/block/Reserved6.php | 0 src/{pocketmine => }/block/Sand.php | 0 src/{pocketmine => }/block/Sapling.php | 0 src/{pocketmine => }/block/SeaLantern.php | 0 src/{pocketmine => }/block/SeaPickle.php | 0 src/{pocketmine => }/block/Sign.php | 0 src/{pocketmine => }/block/SimplePressurePlate.php | 0 src/{pocketmine => }/block/Skull.php | 0 src/{pocketmine => }/block/Slab.php | 0 src/{pocketmine => }/block/Snow.php | 0 src/{pocketmine => }/block/SnowLayer.php | 0 src/{pocketmine => }/block/SoulSand.php | 0 src/{pocketmine => }/block/Sponge.php | 0 src/{pocketmine => }/block/Stair.php | 0 src/{pocketmine => }/block/Stem.php | 0 src/{pocketmine => }/block/StoneButton.php | 0 src/{pocketmine => }/block/StonePressurePlate.php | 0 src/{pocketmine => }/block/Sugarcane.php | 0 src/{pocketmine => }/block/TNT.php | 0 src/{pocketmine => }/block/TallGrass.php | 0 src/{pocketmine => }/block/Thin.php | 0 src/{pocketmine => }/block/Torch.php | 0 src/{pocketmine => }/block/Transparent.php | 0 src/{pocketmine => }/block/Trapdoor.php | 0 src/{pocketmine => }/block/TrappedChest.php | 0 src/{pocketmine => }/block/Tripwire.php | 0 src/{pocketmine => }/block/TripwireHook.php | 0 src/{pocketmine => }/block/UnderwaterTorch.php | 0 src/{pocketmine => }/block/UnknownBlock.php | 0 src/{pocketmine => }/block/VanillaBlocks.php | 0 src/{pocketmine => }/block/Vine.php | 0 src/{pocketmine => }/block/Wall.php | 0 src/{pocketmine => }/block/Water.php | 0 src/{pocketmine => }/block/WaterLily.php | 0 src/{pocketmine => }/block/WeightedPressurePlate.php | 0 src/{pocketmine => }/block/WeightedPressurePlateHeavy.php | 0 src/{pocketmine => }/block/WeightedPressurePlateLight.php | 0 src/{pocketmine => }/block/Wheat.php | 0 src/{pocketmine => }/block/Wood.php | 0 src/{pocketmine => }/block/WoodenButton.php | 0 src/{pocketmine => }/block/WoodenDoor.php | 0 src/{pocketmine => }/block/WoodenFence.php | 0 src/{pocketmine => }/block/WoodenPressurePlate.php | 0 src/{pocketmine => }/block/WoodenSlab.php | 0 src/{pocketmine => }/block/WoodenStairs.php | 0 src/{pocketmine => }/block/WoodenTrapdoor.php | 0 src/{pocketmine => }/block/Wool.php | 0 src/{pocketmine => }/block/tile/Banner.php | 0 src/{pocketmine => }/block/tile/Bed.php | 0 src/{pocketmine => }/block/tile/BrewingStand.php | 0 src/{pocketmine => }/block/tile/Chest.php | 0 src/{pocketmine => }/block/tile/Comparator.php | 0 src/{pocketmine => }/block/tile/Container.php | 0 src/{pocketmine => }/block/tile/ContainerTrait.php | 0 src/{pocketmine => }/block/tile/DaylightSensor.php | 0 src/{pocketmine => }/block/tile/EnchantTable.php | 0 src/{pocketmine => }/block/tile/EnderChest.php | 0 src/{pocketmine => }/block/tile/FlowerPot.php | 0 src/{pocketmine => }/block/tile/Furnace.php | 0 src/{pocketmine => }/block/tile/Hopper.php | 0 src/{pocketmine => }/block/tile/ItemFrame.php | 0 src/{pocketmine => }/block/tile/MonsterSpawner.php | 0 src/{pocketmine => }/block/tile/Nameable.php | 0 src/{pocketmine => }/block/tile/NameableTrait.php | 0 src/{pocketmine => }/block/tile/Note.php | 0 src/{pocketmine => }/block/tile/Sign.php | 0 src/{pocketmine => }/block/tile/Skull.php | 0 src/{pocketmine => }/block/tile/Spawnable.php | 0 src/{pocketmine => }/block/tile/Tile.php | 0 src/{pocketmine => }/block/tile/TileFactory.php | 0 src/{pocketmine => }/block/utils/BannerPattern.php | 0 src/{pocketmine => }/block/utils/BlockDataSerializer.php | 0 src/{pocketmine => }/block/utils/DyeColor.php | 0 src/{pocketmine => }/block/utils/Fallable.php | 0 src/{pocketmine => }/block/utils/FallableTrait.php | 0 src/{pocketmine => }/block/utils/InvalidBlockStateException.php | 0 src/{pocketmine => }/block/utils/PillarRotationTrait.php | 0 src/{pocketmine => }/block/utils/SignText.php | 0 src/{pocketmine => }/block/utils/SkullType.php | 0 src/{pocketmine => }/block/utils/SlabType.php | 0 src/{pocketmine => }/block/utils/StairShape.php | 0 src/{pocketmine => }/block/utils/TreeType.php | 0 src/{pocketmine => }/command/Command.php | 0 src/{pocketmine => }/command/CommandExecutor.php | 0 src/{pocketmine => }/command/CommandMap.php | 0 src/{pocketmine => }/command/CommandReader.php | 0 src/{pocketmine => }/command/CommandSender.php | 0 src/{pocketmine => }/command/ConsoleCommandSender.php | 0 src/{pocketmine => }/command/FormattedCommandAlias.php | 0 src/{pocketmine => }/command/PluginCommand.php | 0 src/{pocketmine => }/command/PluginIdentifiableCommand.php | 0 src/{pocketmine => }/command/SimpleCommandMap.php | 0 src/{pocketmine => }/command/defaults/BanCommand.php | 0 src/{pocketmine => }/command/defaults/BanIpCommand.php | 0 src/{pocketmine => }/command/defaults/BanListCommand.php | 0 .../command/defaults/DefaultGamemodeCommand.php | 0 src/{pocketmine => }/command/defaults/DeopCommand.php | 0 src/{pocketmine => }/command/defaults/DifficultyCommand.php | 0 src/{pocketmine => }/command/defaults/DumpMemoryCommand.php | 0 src/{pocketmine => }/command/defaults/EffectCommand.php | 0 src/{pocketmine => }/command/defaults/EnchantCommand.php | 0 src/{pocketmine => }/command/defaults/GamemodeCommand.php | 0 .../command/defaults/GarbageCollectorCommand.php | 0 src/{pocketmine => }/command/defaults/GiveCommand.php | 0 src/{pocketmine => }/command/defaults/HelpCommand.php | 0 src/{pocketmine => }/command/defaults/KickCommand.php | 0 src/{pocketmine => }/command/defaults/KillCommand.php | 0 src/{pocketmine => }/command/defaults/ListCommand.php | 0 src/{pocketmine => }/command/defaults/MeCommand.php | 0 src/{pocketmine => }/command/defaults/OpCommand.php | 0 src/{pocketmine => }/command/defaults/PardonCommand.php | 0 src/{pocketmine => }/command/defaults/PardonIpCommand.php | 0 src/{pocketmine => }/command/defaults/ParticleCommand.php | 0 src/{pocketmine => }/command/defaults/PluginsCommand.php | 0 src/{pocketmine => }/command/defaults/SaveCommand.php | 0 src/{pocketmine => }/command/defaults/SaveOffCommand.php | 0 src/{pocketmine => }/command/defaults/SaveOnCommand.php | 0 src/{pocketmine => }/command/defaults/SayCommand.php | 0 src/{pocketmine => }/command/defaults/SeedCommand.php | 0 src/{pocketmine => }/command/defaults/SetWorldSpawnCommand.php | 0 src/{pocketmine => }/command/defaults/SpawnpointCommand.php | 0 src/{pocketmine => }/command/defaults/StatusCommand.php | 0 src/{pocketmine => }/command/defaults/StopCommand.php | 0 src/{pocketmine => }/command/defaults/TeleportCommand.php | 0 src/{pocketmine => }/command/defaults/TellCommand.php | 0 src/{pocketmine => }/command/defaults/TimeCommand.php | 0 src/{pocketmine => }/command/defaults/TimingsCommand.php | 0 src/{pocketmine => }/command/defaults/TitleCommand.php | 0 src/{pocketmine => }/command/defaults/TransferServerCommand.php | 0 src/{pocketmine => }/command/defaults/VanillaCommand.php | 0 src/{pocketmine => }/command/defaults/VersionCommand.php | 0 src/{pocketmine => }/command/defaults/WhitelistCommand.php | 0 src/{pocketmine => }/command/utils/CommandException.php | 0 .../command/utils/InvalidCommandSyntaxException.php | 0 src/{pocketmine => }/crafting/CraftingGrid.php | 0 src/{pocketmine => }/crafting/CraftingManager.php | 0 src/{pocketmine => }/crafting/CraftingRecipe.php | 0 src/{pocketmine => }/crafting/FurnaceRecipe.php | 0 src/{pocketmine => }/crafting/MultiRecipe.php | 0 src/{pocketmine => }/crafting/ShapedRecipe.php | 0 src/{pocketmine => }/crafting/ShapelessRecipe.php | 0 src/{pocketmine => }/entity/Ageable.php | 0 src/{pocketmine => }/entity/Animal.php | 0 src/{pocketmine => }/entity/Attribute.php | 0 src/{pocketmine => }/entity/AttributeMap.php | 0 src/{pocketmine => }/entity/Entity.php | 0 src/{pocketmine => }/entity/EntityFactory.php | 0 src/{pocketmine => }/entity/ExperienceManager.php | 0 src/{pocketmine => }/entity/Explosive.php | 0 src/{pocketmine => }/entity/Human.php | 0 src/{pocketmine => }/entity/HungerManager.php | 0 src/{pocketmine => }/entity/Living.php | 0 src/{pocketmine => }/entity/Skin.php | 0 src/{pocketmine => }/entity/Squid.php | 0 src/{pocketmine => }/entity/Villager.php | 0 src/{pocketmine => }/entity/WaterAnimal.php | 0 src/{pocketmine => }/entity/Zombie.php | 0 src/{pocketmine => }/entity/effect/AbsorptionEffect.php | 0 src/{pocketmine => }/entity/effect/Effect.php | 0 src/{pocketmine => }/entity/effect/EffectInstance.php | 0 src/{pocketmine => }/entity/effect/EffectManager.php | 0 src/{pocketmine => }/entity/effect/HealthBoostEffect.php | 0 src/{pocketmine => }/entity/effect/HungerEffect.php | 0 src/{pocketmine => }/entity/effect/InstantDamageEffect.php | 0 src/{pocketmine => }/entity/effect/InstantEffect.php | 0 src/{pocketmine => }/entity/effect/InstantHealthEffect.php | 0 src/{pocketmine => }/entity/effect/InvisibilityEffect.php | 0 src/{pocketmine => }/entity/effect/LevitationEffect.php | 0 src/{pocketmine => }/entity/effect/PoisonEffect.php | 0 src/{pocketmine => }/entity/effect/RegenerationEffect.php | 0 src/{pocketmine => }/entity/effect/SaturationEffect.php | 0 src/{pocketmine => }/entity/effect/SlownessEffect.php | 0 src/{pocketmine => }/entity/effect/SpeedEffect.php | 0 src/{pocketmine => }/entity/effect/VanillaEffects.php | 0 src/{pocketmine => }/entity/effect/WitherEffect.php | 0 src/{pocketmine => }/entity/object/ExperienceOrb.php | 0 src/{pocketmine => }/entity/object/FallingBlock.php | 0 src/{pocketmine => }/entity/object/ItemEntity.php | 0 src/{pocketmine => }/entity/object/Painting.php | 0 src/{pocketmine => }/entity/object/PaintingMotive.php | 0 src/{pocketmine => }/entity/object/PrimedTNT.php | 0 src/{pocketmine => }/entity/projectile/Arrow.php | 0 src/{pocketmine => }/entity/projectile/Egg.php | 0 src/{pocketmine => }/entity/projectile/EnderPearl.php | 0 src/{pocketmine => }/entity/projectile/ExperienceBottle.php | 0 src/{pocketmine => }/entity/projectile/Projectile.php | 0 src/{pocketmine => }/entity/projectile/ProjectileSource.php | 0 src/{pocketmine => }/entity/projectile/Snowball.php | 0 src/{pocketmine => }/entity/projectile/SplashPotion.php | 0 src/{pocketmine => }/entity/projectile/Throwable.php | 0 src/{pocketmine => }/entity/utils/ExperienceUtils.php | 0 src/{pocketmine => }/event/Cancellable.php | 0 src/{pocketmine => }/event/CancellableTrait.php | 0 src/{pocketmine => }/event/Event.php | 0 src/{pocketmine => }/event/EventPriority.php | 0 src/{pocketmine => }/event/HandlerList.php | 0 src/{pocketmine => }/event/HandlerListManager.php | 0 src/{pocketmine => }/event/Listener.php | 0 src/{pocketmine => }/event/RegisteredListener.php | 0 src/{pocketmine => }/event/block/BlockBreakEvent.php | 0 src/{pocketmine => }/event/block/BlockBurnEvent.php | 0 src/{pocketmine => }/event/block/BlockEvent.php | 0 src/{pocketmine => }/event/block/BlockFormEvent.php | 0 src/{pocketmine => }/event/block/BlockGrowEvent.php | 0 src/{pocketmine => }/event/block/BlockPlaceEvent.php | 0 src/{pocketmine => }/event/block/BlockSpreadEvent.php | 0 src/{pocketmine => }/event/block/BlockTeleportEvent.php | 0 src/{pocketmine => }/event/block/BlockUpdateEvent.php | 0 src/{pocketmine => }/event/block/LeavesDecayEvent.php | 0 src/{pocketmine => }/event/block/SignChangeEvent.php | 0 src/{pocketmine => }/event/entity/EntityBlockChangeEvent.php | 0 src/{pocketmine => }/event/entity/EntityCombustByBlockEvent.php | 0 .../event/entity/EntityCombustByEntityEvent.php | 0 src/{pocketmine => }/event/entity/EntityCombustEvent.php | 0 src/{pocketmine => }/event/entity/EntityDamageByBlockEvent.php | 0 .../event/entity/EntityDamageByChildEntityEvent.php | 0 src/{pocketmine => }/event/entity/EntityDamageByEntityEvent.php | 0 src/{pocketmine => }/event/entity/EntityDamageEvent.php | 0 src/{pocketmine => }/event/entity/EntityDeathEvent.php | 0 src/{pocketmine => }/event/entity/EntityDespawnEvent.php | 0 src/{pocketmine => }/event/entity/EntityEffectAddEvent.php | 0 src/{pocketmine => }/event/entity/EntityEffectEvent.php | 0 src/{pocketmine => }/event/entity/EntityEffectRemoveEvent.php | 0 src/{pocketmine => }/event/entity/EntityEvent.php | 0 src/{pocketmine => }/event/entity/EntityExplodeEvent.php | 0 src/{pocketmine => }/event/entity/EntityMotionEvent.php | 0 src/{pocketmine => }/event/entity/EntityRegainHealthEvent.php | 0 src/{pocketmine => }/event/entity/EntityShootBowEvent.php | 0 src/{pocketmine => }/event/entity/EntitySpawnEvent.php | 0 src/{pocketmine => }/event/entity/EntityTeleportEvent.php | 0 src/{pocketmine => }/event/entity/ExplosionPrimeEvent.php | 0 src/{pocketmine => }/event/entity/ItemDespawnEvent.php | 0 src/{pocketmine => }/event/entity/ItemSpawnEvent.php | 0 src/{pocketmine => }/event/entity/ProjectileHitBlockEvent.php | 0 src/{pocketmine => }/event/entity/ProjectileHitEntityEvent.php | 0 src/{pocketmine => }/event/entity/ProjectileHitEvent.php | 0 src/{pocketmine => }/event/entity/ProjectileLaunchEvent.php | 0 src/{pocketmine => }/event/inventory/CraftItemEvent.php | 0 src/{pocketmine => }/event/inventory/FurnaceBurnEvent.php | 0 src/{pocketmine => }/event/inventory/FurnaceSmeltEvent.php | 0 src/{pocketmine => }/event/inventory/InventoryCloseEvent.php | 0 src/{pocketmine => }/event/inventory/InventoryEvent.php | 0 src/{pocketmine => }/event/inventory/InventoryOpenEvent.php | 0 .../event/inventory/InventoryPickupArrowEvent.php | 0 .../event/inventory/InventoryPickupItemEvent.php | 0 .../event/inventory/InventoryTransactionEvent.php | 0 src/{pocketmine => }/event/player/PlayerBedEnterEvent.php | 0 src/{pocketmine => }/event/player/PlayerBedLeaveEvent.php | 0 src/{pocketmine => }/event/player/PlayerBlockPickEvent.php | 0 src/{pocketmine => }/event/player/PlayerBucketEmptyEvent.php | 0 src/{pocketmine => }/event/player/PlayerBucketEvent.php | 0 src/{pocketmine => }/event/player/PlayerBucketFillEvent.php | 0 src/{pocketmine => }/event/player/PlayerChangeSkinEvent.php | 0 src/{pocketmine => }/event/player/PlayerChatEvent.php | 0 .../event/player/PlayerCommandPreprocessEvent.php | 0 src/{pocketmine => }/event/player/PlayerCreationEvent.php | 0 src/{pocketmine => }/event/player/PlayerDataSaveEvent.php | 0 src/{pocketmine => }/event/player/PlayerDeathEvent.php | 0 src/{pocketmine => }/event/player/PlayerDropItemEvent.php | 0 src/{pocketmine => }/event/player/PlayerDuplicateLoginEvent.php | 0 src/{pocketmine => }/event/player/PlayerEditBookEvent.php | 0 src/{pocketmine => }/event/player/PlayerEvent.php | 0 src/{pocketmine => }/event/player/PlayerExhaustEvent.php | 0 .../event/player/PlayerExperienceChangeEvent.php | 0 src/{pocketmine => }/event/player/PlayerGameModeChangeEvent.php | 0 src/{pocketmine => }/event/player/PlayerInteractEvent.php | 0 src/{pocketmine => }/event/player/PlayerItemConsumeEvent.php | 0 src/{pocketmine => }/event/player/PlayerItemHeldEvent.php | 0 src/{pocketmine => }/event/player/PlayerItemUseEvent.php | 0 src/{pocketmine => }/event/player/PlayerJoinEvent.php | 0 src/{pocketmine => }/event/player/PlayerJumpEvent.php | 0 src/{pocketmine => }/event/player/PlayerKickEvent.php | 0 src/{pocketmine => }/event/player/PlayerLoginEvent.php | 0 src/{pocketmine => }/event/player/PlayerMoveEvent.php | 0 src/{pocketmine => }/event/player/PlayerPreLoginEvent.php | 0 src/{pocketmine => }/event/player/PlayerQuitEvent.php | 0 src/{pocketmine => }/event/player/PlayerRespawnEvent.php | 0 src/{pocketmine => }/event/player/PlayerToggleFlightEvent.php | 0 src/{pocketmine => }/event/player/PlayerToggleSneakEvent.php | 0 src/{pocketmine => }/event/player/PlayerToggleSprintEvent.php | 0 src/{pocketmine => }/event/player/PlayerTransferEvent.php | 0 src/{pocketmine => }/event/plugin/PluginDisableEvent.php | 0 src/{pocketmine => }/event/plugin/PluginEnableEvent.php | 0 src/{pocketmine => }/event/plugin/PluginEvent.php | 0 src/{pocketmine => }/event/server/CommandEvent.php | 0 src/{pocketmine => }/event/server/DataPacketBroadcastEvent.php | 0 src/{pocketmine => }/event/server/DataPacketReceiveEvent.php | 0 src/{pocketmine => }/event/server/DataPacketSendEvent.php | 0 src/{pocketmine => }/event/server/LowMemoryEvent.php | 0 src/{pocketmine => }/event/server/NetworkInterfaceEvent.php | 0 .../event/server/NetworkInterfaceRegisterEvent.php | 0 .../event/server/NetworkInterfaceUnregisterEvent.php | 0 src/{pocketmine => }/event/server/QueryRegenerateEvent.php | 0 src/{pocketmine => }/event/server/ServerEvent.php | 0 src/{pocketmine => }/event/server/UpdateNotifyEvent.php | 0 src/{pocketmine => }/event/world/ChunkEvent.php | 0 src/{pocketmine => }/event/world/ChunkLoadEvent.php | 0 src/{pocketmine => }/event/world/ChunkPopulateEvent.php | 0 src/{pocketmine => }/event/world/ChunkUnloadEvent.php | 0 src/{pocketmine => }/event/world/SpawnChangeEvent.php | 0 src/{pocketmine => }/event/world/WorldEvent.php | 0 src/{pocketmine => }/event/world/WorldInitEvent.php | 0 src/{pocketmine => }/event/world/WorldLoadEvent.php | 0 src/{pocketmine => }/event/world/WorldSaveEvent.php | 0 src/{pocketmine => }/event/world/WorldUnloadEvent.php | 0 src/{pocketmine => }/form/Form.php | 0 src/{pocketmine => }/form/FormValidationException.php | 0 src/{pocketmine => }/inventory/AnvilInventory.php | 0 src/{pocketmine => }/inventory/ArmorInventory.php | 0 src/{pocketmine => }/inventory/BaseInventory.php | 0 src/{pocketmine => }/inventory/BlockInventory.php | 0 src/{pocketmine => }/inventory/BrewingStandInventory.php | 0 .../inventory/CallbackInventoryChangeListener.php | 0 src/{pocketmine => }/inventory/ChestInventory.php | 0 src/{pocketmine => }/inventory/CreativeInventory.php | 0 src/{pocketmine => }/inventory/DoubleChestInventory.php | 0 src/{pocketmine => }/inventory/EnchantInventory.php | 0 src/{pocketmine => }/inventory/EnderChestInventory.php | 0 src/{pocketmine => }/inventory/FurnaceInventory.php | 0 src/{pocketmine => }/inventory/HopperInventory.php | 0 src/{pocketmine => }/inventory/Inventory.php | 0 src/{pocketmine => }/inventory/InventoryChangeListener.php | 0 src/{pocketmine => }/inventory/InventoryHolder.php | 0 src/{pocketmine => }/inventory/PlayerCursorInventory.php | 0 src/{pocketmine => }/inventory/PlayerInventory.php | 0 .../inventory/transaction/CraftingTransaction.php | 0 .../inventory/transaction/InventoryTransaction.php | 0 .../inventory/transaction/TransactionValidationException.php | 0 .../inventory/transaction/action/CreateItemAction.php | 0 .../inventory/transaction/action/DestroyItemAction.php | 0 .../inventory/transaction/action/DropItemAction.php | 0 .../inventory/transaction/action/InventoryAction.php | 0 .../inventory/transaction/action/SlotChangeAction.php | 0 src/{pocketmine => }/item/Apple.php | 0 src/{pocketmine => }/item/Armor.php | 0 src/{pocketmine => }/item/ArmorTypeInfo.php | 0 src/{pocketmine => }/item/Arrow.php | 0 src/{pocketmine => }/item/Axe.php | 0 src/{pocketmine => }/item/BakedPotato.php | 0 src/{pocketmine => }/item/Banner.php | 0 src/{pocketmine => }/item/Bed.php | 0 src/{pocketmine => }/item/Beetroot.php | 0 src/{pocketmine => }/item/BeetrootSeeds.php | 0 src/{pocketmine => }/item/BeetrootSoup.php | 0 src/{pocketmine => }/item/BlazeRod.php | 0 src/{pocketmine => }/item/Boat.php | 0 src/{pocketmine => }/item/Book.php | 0 src/{pocketmine => }/item/Boots.php | 0 src/{pocketmine => }/item/Bow.php | 0 src/{pocketmine => }/item/Bowl.php | 0 src/{pocketmine => }/item/Bread.php | 0 src/{pocketmine => }/item/Bucket.php | 0 src/{pocketmine => }/item/Carrot.php | 0 src/{pocketmine => }/item/Chestplate.php | 0 src/{pocketmine => }/item/ChorusFruit.php | 0 src/{pocketmine => }/item/Clock.php | 0 src/{pocketmine => }/item/Clownfish.php | 0 src/{pocketmine => }/item/Coal.php | 0 src/{pocketmine => }/item/CocoaBeans.php | 0 src/{pocketmine => }/item/Compass.php | 0 src/{pocketmine => }/item/Consumable.php | 0 src/{pocketmine => }/item/CookedChicken.php | 0 src/{pocketmine => }/item/CookedFish.php | 0 src/{pocketmine => }/item/CookedMutton.php | 0 src/{pocketmine => }/item/CookedPorkchop.php | 0 src/{pocketmine => }/item/CookedRabbit.php | 0 src/{pocketmine => }/item/CookedSalmon.php | 0 src/{pocketmine => }/item/Cookie.php | 0 src/{pocketmine => }/item/DriedKelp.php | 0 src/{pocketmine => }/item/Durable.php | 0 src/{pocketmine => }/item/Dye.php | 0 src/{pocketmine => }/item/Egg.php | 0 src/{pocketmine => }/item/EnderPearl.php | 0 src/{pocketmine => }/item/ExperienceBottle.php | 0 src/{pocketmine => }/item/Fertilizer.php | 0 src/{pocketmine => }/item/FishingRod.php | 0 src/{pocketmine => }/item/FlintSteel.php | 0 src/{pocketmine => }/item/Food.php | 0 src/{pocketmine => }/item/FoodSource.php | 0 src/{pocketmine => }/item/GlassBottle.php | 0 src/{pocketmine => }/item/GoldenApple.php | 0 src/{pocketmine => }/item/GoldenAppleEnchanted.php | 0 src/{pocketmine => }/item/GoldenCarrot.php | 0 src/{pocketmine => }/item/Helmet.php | 0 src/{pocketmine => }/item/Hoe.php | 0 src/{pocketmine => }/item/Item.php | 0 src/{pocketmine => }/item/ItemBlock.php | 0 src/{pocketmine => }/item/ItemEnchantmentHandlingTrait.php | 0 src/{pocketmine => }/item/ItemFactory.php | 0 src/{pocketmine => }/item/ItemIds.php | 0 src/{pocketmine => }/item/ItemUseResult.php | 0 src/{pocketmine => }/item/Leggings.php | 0 src/{pocketmine => }/item/LiquidBucket.php | 0 src/{pocketmine => }/item/Melon.php | 0 src/{pocketmine => }/item/MelonSeeds.php | 0 src/{pocketmine => }/item/MilkBucket.php | 0 src/{pocketmine => }/item/Minecart.php | 0 src/{pocketmine => }/item/MushroomStew.php | 0 src/{pocketmine => }/item/PaintingItem.php | 0 src/{pocketmine => }/item/Pickaxe.php | 0 src/{pocketmine => }/item/PoisonousPotato.php | 0 src/{pocketmine => }/item/Potato.php | 0 src/{pocketmine => }/item/Potion.php | 0 src/{pocketmine => }/item/ProjectileItem.php | 0 src/{pocketmine => }/item/Pufferfish.php | 0 src/{pocketmine => }/item/PumpkinPie.php | 0 src/{pocketmine => }/item/PumpkinSeeds.php | 0 src/{pocketmine => }/item/RabbitStew.php | 0 src/{pocketmine => }/item/RawBeef.php | 0 src/{pocketmine => }/item/RawChicken.php | 0 src/{pocketmine => }/item/RawFish.php | 0 src/{pocketmine => }/item/RawMutton.php | 0 src/{pocketmine => }/item/RawPorkchop.php | 0 src/{pocketmine => }/item/RawRabbit.php | 0 src/{pocketmine => }/item/RawSalmon.php | 0 src/{pocketmine => }/item/Redstone.php | 0 src/{pocketmine => }/item/RottenFlesh.php | 0 src/{pocketmine => }/item/Shears.php | 0 src/{pocketmine => }/item/Shovel.php | 0 src/{pocketmine => }/item/Sign.php | 0 src/{pocketmine => }/item/Skull.php | 0 src/{pocketmine => }/item/Snowball.php | 0 src/{pocketmine => }/item/SpawnEgg.php | 0 src/{pocketmine => }/item/SpiderEye.php | 0 src/{pocketmine => }/item/SplashPotion.php | 0 src/{pocketmine => }/item/Steak.php | 0 src/{pocketmine => }/item/Stick.php | 0 src/{pocketmine => }/item/StringItem.php | 0 src/{pocketmine => }/item/Sword.php | 0 src/{pocketmine => }/item/TieredTool.php | 0 src/{pocketmine => }/item/Tool.php | 0 src/{pocketmine => }/item/ToolTier.php | 0 src/{pocketmine => }/item/Totem.php | 0 src/{pocketmine => }/item/VanillaItems.php | 0 src/{pocketmine => }/item/WheatSeeds.php | 0 src/{pocketmine => }/item/WritableBook.php | 0 src/{pocketmine => }/item/WritableBookBase.php | 0 src/{pocketmine => }/item/WritableBookPage.php | 0 src/{pocketmine => }/item/WrittenBook.php | 0 src/{pocketmine => }/item/enchantment/Enchantment.php | 0 src/{pocketmine => }/item/enchantment/EnchantmentEntry.php | 0 src/{pocketmine => }/item/enchantment/EnchantmentInstance.php | 0 src/{pocketmine => }/item/enchantment/EnchantmentList.php | 0 src/{pocketmine => }/item/enchantment/FireAspectEnchantment.php | 0 src/{pocketmine => }/item/enchantment/KnockbackEnchantment.php | 0 .../item/enchantment/MeleeWeaponEnchantment.php | 0 src/{pocketmine => }/item/enchantment/ProtectionEnchantment.php | 0 src/{pocketmine => }/item/enchantment/SharpnessEnchantment.php | 0 src/{pocketmine => }/lang/Language.php | 0 src/{pocketmine => }/lang/LanguageNotFoundException.php | 0 src/{pocketmine => }/lang/TextContainer.php | 0 src/{pocketmine => }/lang/TranslationContainer.php | 0 src/{pocketmine => }/network/AdvancedNetworkInterface.php | 0 src/{pocketmine => }/network/BadPacketException.php | 0 src/{pocketmine => }/network/Network.php | 0 src/{pocketmine => }/network/NetworkInterface.php | 0 src/{pocketmine => }/network/NetworkSessionManager.php | 0 src/{pocketmine => }/network/RawPacketHandler.php | 0 src/{pocketmine => }/network/mcpe/ChunkCache.php | 0 src/{pocketmine => }/network/mcpe/ChunkRequestTask.php | 0 src/{pocketmine => }/network/mcpe/InventoryManager.php | 0 src/{pocketmine => }/network/mcpe/NetworkSession.php | 0 src/{pocketmine => }/network/mcpe/PacketBatch.php | 0 src/{pocketmine => }/network/mcpe/PacketSender.php | 0 src/{pocketmine => }/network/mcpe/README.md | 0 src/{pocketmine => }/network/mcpe/auth/ProcessLoginTask.php | 0 src/{pocketmine => }/network/mcpe/auth/VerifyLoginException.php | 0 .../network/mcpe/compression/CompressBatchPromise.php | 0 .../network/mcpe/compression/CompressBatchTask.php | 0 src/{pocketmine => }/network/mcpe/compression/Zlib.php | 0 src/{pocketmine => }/network/mcpe/encryption/NetworkCipher.php | 0 .../network/mcpe/encryption/PrepareEncryptionTask.php | 0 .../network/mcpe/handler/DeathPacketHandler.php | 0 .../network/mcpe/handler/HandshakePacketHandler.php | 0 .../network/mcpe/handler/InGamePacketHandler.php | 0 .../network/mcpe/handler/LoginPacketHandler.php | 0 src/{pocketmine => }/network/mcpe/handler/NullPacketHandler.php | 0 src/{pocketmine => }/network/mcpe/handler/PacketHandler.php | 0 .../network/mcpe/handler/PreSpawnPacketHandler.php | 0 .../network/mcpe/handler/ResourcePacksPacketHandler.php | 0 src/{pocketmine => }/network/mcpe/protocol/ActorEventPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/ActorFallPacket.php | 0 .../network/mcpe/protocol/ActorPickRequestPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/AddActorPacket.php | 0 .../network/mcpe/protocol/AddBehaviorTreePacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/AddEntityPacket.php | 0 .../network/mcpe/protocol/AddItemActorPacket.php | 0 .../network/mcpe/protocol/AddPaintingPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/AddPlayerPacket.php | 0 .../network/mcpe/protocol/AdventureSettingsPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/AnimatePacket.php | 0 .../network/mcpe/protocol/AutomationClientConnectPacket.php | 0 .../network/mcpe/protocol/AvailableActorIdentifiersPacket.php | 0 .../network/mcpe/protocol/AvailableCommandsPacket.php | 0 .../network/mcpe/protocol/BiomeDefinitionListPacket.php | 0 .../network/mcpe/protocol/BlockActorDataPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/BlockEventPacket.php | 0 .../network/mcpe/protocol/BlockPickRequestPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/BookEditPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/BossEventPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/CameraPacket.php | 0 .../network/mcpe/protocol/ChangeDimensionPacket.php | 0 .../network/mcpe/protocol/ChunkRadiusUpdatedPacket.php | 0 .../network/mcpe/protocol/ClientCacheBlobStatusPacket.php | 0 .../network/mcpe/protocol/ClientCacheMissResponsePacket.php | 0 .../network/mcpe/protocol/ClientCacheStatusPacket.php | 0 .../network/mcpe/protocol/ClientToServerHandshakePacket.php | 0 .../network/mcpe/protocol/ClientboundMapItemDataPacket.php | 0 .../network/mcpe/protocol/ClientboundPacket.php | 0 .../network/mcpe/protocol/CommandBlockUpdatePacket.php | 0 .../network/mcpe/protocol/CommandOutputPacket.php | 0 .../network/mcpe/protocol/CommandRequestPacket.php | 0 .../network/mcpe/protocol/ContainerClosePacket.php | 0 .../network/mcpe/protocol/ContainerOpenPacket.php | 0 .../network/mcpe/protocol/ContainerSetDataPacket.php | 0 .../network/mcpe/protocol/CraftingDataPacket.php | 0 .../network/mcpe/protocol/CraftingEventPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/DataPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/DisconnectPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/EventPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/ExplodePacket.php | 0 .../network/mcpe/protocol/GameRulesChangedPacket.php | 0 .../network/mcpe/protocol/GarbageServerboundPacket.php | 0 .../network/mcpe/protocol/GuiDataPickItemPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/HurtArmorPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/InteractPacket.php | 0 .../network/mcpe/protocol/InventoryContentPacket.php | 0 .../network/mcpe/protocol/InventorySlotPacket.php | 0 .../network/mcpe/protocol/InventoryTransactionPacket.php | 0 .../network/mcpe/protocol/ItemFrameDropItemPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/LabTablePacket.php | 0 .../network/mcpe/protocol/LecternUpdatePacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/LevelChunkPacket.php | 0 .../network/mcpe/protocol/LevelEventGenericPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/LevelEventPacket.php | 0 .../network/mcpe/protocol/LevelSoundEventPacket.php | 0 .../network/mcpe/protocol/LevelSoundEventPacketV1.php | 0 .../network/mcpe/protocol/LevelSoundEventPacketV2.php | 0 src/{pocketmine => }/network/mcpe/protocol/LoginPacket.php | 0 .../network/mcpe/protocol/MapCreateLockedCopyPacket.php | 0 .../network/mcpe/protocol/MapInfoRequestPacket.php | 0 .../network/mcpe/protocol/MobArmorEquipmentPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/MobEffectPacket.php | 0 .../network/mcpe/protocol/MobEquipmentPacket.php | 0 .../network/mcpe/protocol/ModalFormRequestPacket.php | 0 .../network/mcpe/protocol/ModalFormResponsePacket.php | 0 .../network/mcpe/protocol/MoveActorAbsolutePacket.php | 0 .../network/mcpe/protocol/MoveActorDeltaPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/MovePlayerPacket.php | 0 .../network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php | 0 .../network/mcpe/protocol/NetworkStackLatencyPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/NpcRequestPacket.php | 0 .../network/mcpe/protocol/OnScreenTextureAnimationPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/Packet.php | 0 src/{pocketmine => }/network/mcpe/protocol/PacketPool.php | 0 .../network/mcpe/protocol/PhotoTransferPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/PlaySoundPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/PlayStatusPacket.php | 0 .../network/mcpe/protocol/PlayerActionPacket.php | 0 .../network/mcpe/protocol/PlayerHotbarPacket.php | 0 .../network/mcpe/protocol/PlayerInputPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/PlayerListPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/PlayerSkinPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/ProtocolInfo.php | 0 .../network/mcpe/protocol/PurchaseReceiptPacket.php | 0 .../network/mcpe/protocol/RemoveActorPacket.php | 0 .../network/mcpe/protocol/RemoveEntityPacket.php | 0 .../network/mcpe/protocol/RemoveObjectivePacket.php | 0 .../network/mcpe/protocol/RequestChunkRadiusPacket.php | 0 .../network/mcpe/protocol/ResourcePackChunkDataPacket.php | 0 .../network/mcpe/protocol/ResourcePackChunkRequestPacket.php | 0 .../network/mcpe/protocol/ResourcePackClientResponsePacket.php | 0 .../network/mcpe/protocol/ResourcePackDataInfoPacket.php | 0 .../network/mcpe/protocol/ResourcePackStackPacket.php | 0 .../network/mcpe/protocol/ResourcePacksInfoPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/RespawnPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/RiderJumpPacket.php | 0 .../network/mcpe/protocol/ScriptCustomEventPacket.php | 0 .../network/mcpe/protocol/ServerSettingsRequestPacket.php | 0 .../network/mcpe/protocol/ServerSettingsResponsePacket.php | 0 .../network/mcpe/protocol/ServerToClientHandshakePacket.php | 0 .../network/mcpe/protocol/ServerboundPacket.php | 0 .../network/mcpe/protocol/SetActorDataPacket.php | 0 .../network/mcpe/protocol/SetActorLinkPacket.php | 0 .../network/mcpe/protocol/SetActorMotionPacket.php | 0 .../network/mcpe/protocol/SetCommandsEnabledPacket.php | 0 .../network/mcpe/protocol/SetDefaultGameTypePacket.php | 0 .../network/mcpe/protocol/SetDifficultyPacket.php | 0 .../network/mcpe/protocol/SetDisplayObjectivePacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/SetHealthPacket.php | 0 .../network/mcpe/protocol/SetLastHurtByPacket.php | 0 .../network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php | 0 .../network/mcpe/protocol/SetPlayerGameTypePacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/SetScorePacket.php | 0 .../network/mcpe/protocol/SetScoreboardIdentityPacket.php | 0 .../network/mcpe/protocol/SetSpawnPositionPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/SetTimePacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/SetTitlePacket.php | 0 .../network/mcpe/protocol/ShowCreditsPacket.php | 0 .../network/mcpe/protocol/ShowProfilePacket.php | 0 .../network/mcpe/protocol/ShowStoreOfferPacket.php | 0 .../network/mcpe/protocol/SimpleEventPacket.php | 0 .../network/mcpe/protocol/SpawnExperienceOrbPacket.php | 0 .../network/mcpe/protocol/SpawnParticleEffectPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/StartGamePacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/StopSoundPacket.php | 0 .../network/mcpe/protocol/StructureBlockUpdatePacket.php | 0 .../mcpe/protocol/StructureTemplateDataExportRequestPacket.php | 0 .../mcpe/protocol/StructureTemplateDataExportResponsePacket.php | 0 .../network/mcpe/protocol/SubClientLoginPacket.php | 0 .../network/mcpe/protocol/TakeItemActorPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/TextPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/TransferPacket.php | 0 src/{pocketmine => }/network/mcpe/protocol/UnknownPacket.php | 0 .../network/mcpe/protocol/UpdateAttributesPacket.php | 0 .../network/mcpe/protocol/UpdateBlockPacket.php | 0 .../network/mcpe/protocol/UpdateBlockPropertiesPacket.php | 0 .../network/mcpe/protocol/UpdateBlockSyncedPacket.php | 0 .../network/mcpe/protocol/UpdateEquipPacket.php | 0 .../network/mcpe/protocol/UpdateSoftEnumPacket.php | 0 .../network/mcpe/protocol/UpdateTradePacket.php | 0 .../network/mcpe/protocol/VideoStreamConnectPacket.php | 0 .../network/mcpe/protocol/types/ChunkCacheBlob.php | 0 .../network/mcpe/protocol/types/DimensionIds.php | 0 .../network/mcpe/protocol/types/MapTrackedObject.php | 0 .../network/mcpe/protocol/types/ParticleIds.php | 0 .../network/mcpe/protocol/types/PlayerListEntry.php | 0 .../network/mcpe/protocol/types/PlayerPermissions.php | 0 .../network/mcpe/protocol/types/ResourcePackType.php | 0 .../network/mcpe/protocol/types/RuntimeBlockMapping.php | 0 .../network/mcpe/protocol/types/ScorePacketEntry.php | 0 .../mcpe/protocol/types/ScoreboardIdentityPacketEntry.php | 0 .../network/mcpe/protocol/types/command/CommandData.php | 0 .../network/mcpe/protocol/types/command/CommandEnum.php | 0 .../network/mcpe/protocol/types/command/CommandOriginData.php | 0 .../mcpe/protocol/types/command/CommandOutputMessage.php | 0 .../network/mcpe/protocol/types/command/CommandParameter.php | 0 .../mcpe/protocol/types/entity/BlockPosMetadataProperty.php | 0 .../network/mcpe/protocol/types/entity/ByteMetadataProperty.php | 0 .../network/mcpe/protocol/types/entity/EntityLegacyIds.php | 0 .../network/mcpe/protocol/types/entity/EntityLink.php | 0 .../mcpe/protocol/types/entity/EntityMetadataCollection.php | 0 .../network/mcpe/protocol/types/entity/EntityMetadataFlags.php | 0 .../mcpe/protocol/types/entity/EntityMetadataProperties.php | 0 .../network/mcpe/protocol/types/entity/EntityMetadataTypes.php | 0 .../mcpe/protocol/types/entity/FloatMetadataProperty.php | 0 .../network/mcpe/protocol/types/entity/IntMetadataProperty.php | 0 .../mcpe/protocol/types/entity/IntegerishMetadataProperty.php | 0 .../mcpe/protocol/types/entity/ItemStackMetadataProperty.php | 0 .../network/mcpe/protocol/types/entity/LongMetadataProperty.php | 0 .../network/mcpe/protocol/types/entity/MetadataProperty.php | 0 .../network/mcpe/protocol/types/entity/PlayerMetadataFlags.php | 0 .../mcpe/protocol/types/entity/ShortMetadataProperty.php | 0 .../mcpe/protocol/types/entity/StringMetadataProperty.php | 0 .../network/mcpe/protocol/types/entity/Vec3MetadataProperty.php | 0 .../network/mcpe/protocol/types/inventory/ContainerIds.php | 0 .../mcpe/protocol/types/inventory/MismatchTransactionData.php | 0 .../mcpe/protocol/types/inventory/NetworkInventoryAction.php | 0 .../mcpe/protocol/types/inventory/NormalTransactionData.php | 0 .../protocol/types/inventory/ReleaseItemTransactionData.php | 0 .../network/mcpe/protocol/types/inventory/TransactionData.php | 0 .../protocol/types/inventory/UseItemOnEntityTransactionData.php | 0 .../mcpe/protocol/types/inventory/UseItemTransactionData.php | 0 .../network/mcpe/protocol/types/inventory/WindowTypes.php | 0 src/{pocketmine => }/network/mcpe/raklib/RakLibInterface.php | 0 src/{pocketmine => }/network/mcpe/raklib/RakLibPacketSender.php | 0 .../network/mcpe/serializer/ChunkSerializer.php | 0 .../network/mcpe/serializer/NetworkBinaryStream.php | 0 .../network/mcpe/serializer/NetworkNbtSerializer.php | 0 src/{pocketmine => }/network/query/QueryHandler.php | 0 src/{pocketmine => }/network/upnp/UPnP.php | 0 src/{pocketmine => }/permission/BanEntry.php | 0 src/{pocketmine => }/permission/BanList.php | 0 src/{pocketmine => }/permission/DefaultPermissions.php | 0 src/{pocketmine => }/permission/Permissible.php | 0 src/{pocketmine => }/permission/PermissibleBase.php | 0 src/{pocketmine => }/permission/PermissibleDelegateTrait.php | 0 src/{pocketmine => }/permission/Permission.php | 0 src/{pocketmine => }/permission/PermissionAttachment.php | 0 src/{pocketmine => }/permission/PermissionAttachmentInfo.php | 0 src/{pocketmine => }/permission/PermissionManager.php | 0 src/{pocketmine => }/permission/PermissionParser.php | 0 src/{pocketmine => }/permission/PermissionRemovedExecutor.php | 0 src/{pocketmine => }/permission/ServerOperator.php | 0 src/{pocketmine => }/player/GameMode.php | 0 src/{pocketmine => }/player/IPlayer.php | 0 src/{pocketmine => }/player/OfflinePlayer.php | 0 src/{pocketmine => }/player/Player.php | 0 src/{pocketmine => }/player/PlayerInfo.php | 0 src/{pocketmine => }/plugin/ApiVersion.php | 0 src/{pocketmine => }/plugin/DiskResourceProvider.php | 0 src/{pocketmine => }/plugin/PharPluginLoader.php | 0 src/{pocketmine => }/plugin/Plugin.php | 0 src/{pocketmine => }/plugin/PluginBase.php | 0 src/{pocketmine => }/plugin/PluginDescription.php | 0 src/{pocketmine => }/plugin/PluginException.php | 0 src/{pocketmine => }/plugin/PluginGraylist.php | 0 src/{pocketmine => }/plugin/PluginLoadOrder.php | 0 src/{pocketmine => }/plugin/PluginLoader.php | 0 src/{pocketmine => }/plugin/PluginLogger.php | 0 src/{pocketmine => }/plugin/PluginManager.php | 0 src/{pocketmine => }/plugin/ResourceProvider.php | 0 src/{pocketmine => }/plugin/ScriptPluginLoader.php | 0 src/{pocketmine => }/resourcepacks/ResourcePack.php | 0 src/{pocketmine => }/resourcepacks/ResourcePackException.php | 0 src/{pocketmine => }/resourcepacks/ResourcePackInfoEntry.php | 0 src/{pocketmine => }/resourcepacks/ResourcePackManager.php | 0 src/{pocketmine => }/resourcepacks/ZippedResourcePack.php | 0 src/{pocketmine => }/scheduler/AsyncPool.php | 0 src/{pocketmine => }/scheduler/AsyncTask.php | 0 src/{pocketmine => }/scheduler/AsyncWorker.php | 0 src/{pocketmine => }/scheduler/BulkCurlTask.php | 0 src/{pocketmine => }/scheduler/CancellableClosureTask.php | 0 src/{pocketmine => }/scheduler/ClosureTask.php | 0 src/{pocketmine => }/scheduler/DumpWorkerMemoryTask.php | 0 src/{pocketmine => }/scheduler/FileWriteTask.php | 0 src/{pocketmine => }/scheduler/GarbageCollectionTask.php | 0 src/{pocketmine => }/scheduler/SendUsageTask.php | 0 src/{pocketmine => }/scheduler/Task.php | 0 src/{pocketmine => }/scheduler/TaskHandler.php | 0 src/{pocketmine => }/scheduler/TaskScheduler.php | 0 src/{pocketmine => }/thread/CommonThreadPartsTrait.php | 0 src/{pocketmine => }/thread/Thread.php | 0 src/{pocketmine => }/thread/ThreadManager.php | 0 src/{pocketmine => }/thread/Worker.php | 0 src/{pocketmine => }/timings/Timings.php | 0 src/{pocketmine => }/timings/TimingsHandler.php | 0 src/{pocketmine => }/updater/AutoUpdater.php | 0 src/{pocketmine => }/updater/UpdateCheckTask.php | 0 src/{pocketmine => }/utils/Color.php | 0 src/{pocketmine => }/utils/Config.php | 0 src/{pocketmine => }/utils/EnumTrait.php | 0 src/{pocketmine => }/utils/Internet.php | 0 src/{pocketmine => }/utils/InternetException.php | 0 src/{pocketmine => }/utils/MainLogger.php | 0 src/{pocketmine => }/utils/Process.php | 0 src/{pocketmine => }/utils/Random.php | 0 src/{pocketmine => }/utils/RegistryTrait.php | 0 src/{pocketmine => }/utils/ReversePriorityQueue.php | 0 src/{pocketmine => }/utils/ServerException.php | 0 src/{pocketmine => }/utils/ServerKiller.php | 0 src/{pocketmine => }/utils/Terminal.php | 0 src/{pocketmine => }/utils/TextFormat.php | 0 src/{pocketmine => }/utils/Timezone.php | 0 src/{pocketmine => }/utils/UUID.php | 0 src/{pocketmine => }/utils/Utils.php | 0 src/{pocketmine => }/utils/VersionString.php | 0 src/{pocketmine => }/wizard/SetupWizard.php | 0 src/{pocketmine => }/world/BlockTransaction.php | 0 src/{pocketmine => }/world/ChunkListener.php | 0 src/{pocketmine => }/world/ChunkListenerNoOpTrait.php | 0 src/{pocketmine => }/world/ChunkLoader.php | 0 src/{pocketmine => }/world/ChunkManager.php | 0 src/{pocketmine => }/world/Explosion.php | 0 src/{pocketmine => }/world/Location.php | 0 src/{pocketmine => }/world/Position.php | 0 src/{pocketmine => }/world/SimpleChunkManager.php | 0 src/{pocketmine => }/world/World.php | 0 src/{pocketmine => }/world/WorldException.php | 0 src/{pocketmine => }/world/WorldManager.php | 0 src/{pocketmine => }/world/WorldTimings.php | 0 src/{pocketmine => }/world/biome/Biome.php | 0 src/{pocketmine => }/world/biome/DesertBiome.php | 0 src/{pocketmine => }/world/biome/ForestBiome.php | 0 src/{pocketmine => }/world/biome/GrassyBiome.php | 0 src/{pocketmine => }/world/biome/HellBiome.php | 0 src/{pocketmine => }/world/biome/IcePlainsBiome.php | 0 src/{pocketmine => }/world/biome/MountainsBiome.php | 0 src/{pocketmine => }/world/biome/OceanBiome.php | 0 src/{pocketmine => }/world/biome/PlainBiome.php | 0 src/{pocketmine => }/world/biome/RiverBiome.php | 0 src/{pocketmine => }/world/biome/SandyBiome.php | 0 src/{pocketmine => }/world/biome/SmallMountainsBiome.php | 0 src/{pocketmine => }/world/biome/SnowyBiome.php | 0 src/{pocketmine => }/world/biome/SwampBiome.php | 0 src/{pocketmine => }/world/biome/TaigaBiome.php | 0 src/{pocketmine => }/world/biome/UnknownBiome.php | 0 src/{pocketmine => }/world/format/Chunk.php | 0 src/{pocketmine => }/world/format/ChunkException.php | 0 src/{pocketmine => }/world/format/EmptySubChunk.php | 0 src/{pocketmine => }/world/format/LightArray.php | 0 src/{pocketmine => }/world/format/SubChunk.php | 0 src/{pocketmine => }/world/format/SubChunkInterface.php | 0 src/{pocketmine => }/world/format/io/BaseWorldProvider.php | 0 src/{pocketmine => }/world/format/io/ChunkUtils.php | 0 src/{pocketmine => }/world/format/io/FastChunkSerializer.php | 0 src/{pocketmine => }/world/format/io/FormatConverter.php | 0 src/{pocketmine => }/world/format/io/WorldData.php | 0 src/{pocketmine => }/world/format/io/WorldProvider.php | 0 src/{pocketmine => }/world/format/io/WorldProviderManager.php | 0 src/{pocketmine => }/world/format/io/WritableWorldProvider.php | 0 src/{pocketmine => }/world/format/io/data/BaseNbtWorldData.php | 0 src/{pocketmine => }/world/format/io/data/BedrockWorldData.php | 0 src/{pocketmine => }/world/format/io/data/JavaWorldData.php | 0 .../world/format/io/exception/CorruptedChunkException.php | 0 .../world/format/io/exception/CorruptedWorldException.php | 0 .../format/io/exception/UnsupportedWorldFormatException.php | 0 src/{pocketmine => }/world/format/io/leveldb/LevelDB.php | 0 src/{pocketmine => }/world/format/io/region/Anvil.php | 0 .../world/format/io/region/CorruptedRegionException.php | 0 .../world/format/io/region/LegacyAnvilChunkTrait.php | 0 src/{pocketmine => }/world/format/io/region/McRegion.php | 0 src/{pocketmine => }/world/format/io/region/PMAnvil.php | 0 src/{pocketmine => }/world/format/io/region/RegionException.php | 0 src/{pocketmine => }/world/format/io/region/RegionLoader.php | 0 .../world/format/io/region/RegionLocationTableEntry.php | 0 .../world/format/io/region/RegionWorldProvider.php | 0 src/{pocketmine => }/world/generator/Flat.php | 0 src/{pocketmine => }/world/generator/Generator.php | 0 src/{pocketmine => }/world/generator/GeneratorChunkManager.php | 0 src/{pocketmine => }/world/generator/GeneratorManager.php | 0 src/{pocketmine => }/world/generator/GeneratorRegisterTask.php | 0 .../world/generator/GeneratorUnregisterTask.php | 0 .../world/generator/InvalidGeneratorOptionsException.php | 0 src/{pocketmine => }/world/generator/PopulationTask.php | 0 src/{pocketmine => }/world/generator/biome/BiomeSelector.php | 0 src/{pocketmine => }/world/generator/hell/Nether.php | 0 src/{pocketmine => }/world/generator/noise/Noise.php | 0 src/{pocketmine => }/world/generator/noise/Simplex.php | 0 src/{pocketmine => }/world/generator/normal/Normal.php | 0 src/{pocketmine => }/world/generator/object/BirchTree.php | 0 src/{pocketmine => }/world/generator/object/JungleTree.php | 0 src/{pocketmine => }/world/generator/object/OakTree.php | 0 src/{pocketmine => }/world/generator/object/Ore.php | 0 src/{pocketmine => }/world/generator/object/OreType.php | 0 src/{pocketmine => }/world/generator/object/SpruceTree.php | 0 src/{pocketmine => }/world/generator/object/TallGrass.php | 0 src/{pocketmine => }/world/generator/object/Tree.php | 0 src/{pocketmine => }/world/generator/populator/GroundCover.php | 0 src/{pocketmine => }/world/generator/populator/Ore.php | 0 src/{pocketmine => }/world/generator/populator/Populator.php | 0 src/{pocketmine => }/world/generator/populator/TallGrass.php | 0 src/{pocketmine => }/world/generator/populator/Tree.php | 0 src/{pocketmine => }/world/light/BlockLightUpdate.php | 0 src/{pocketmine => }/world/light/LightPopulationTask.php | 0 src/{pocketmine => }/world/light/LightUpdate.php | 0 src/{pocketmine => }/world/light/SkyLightUpdate.php | 0 src/{pocketmine => }/world/particle/AngryVillagerParticle.php | 0 src/{pocketmine => }/world/particle/BlockForceFieldParticle.php | 0 src/{pocketmine => }/world/particle/BubbleParticle.php | 0 src/{pocketmine => }/world/particle/CriticalParticle.php | 0 src/{pocketmine => }/world/particle/DestroyBlockParticle.php | 0 .../world/particle/DragonEggTeleportParticle.php | 0 src/{pocketmine => }/world/particle/DustParticle.php | 0 src/{pocketmine => }/world/particle/EnchantParticle.php | 0 .../world/particle/EnchantmentTableParticle.php | 0 .../world/particle/EndermanTeleportParticle.php | 0 src/{pocketmine => }/world/particle/EntityFlameParticle.php | 0 src/{pocketmine => }/world/particle/ExplodeParticle.php | 0 src/{pocketmine => }/world/particle/FlameParticle.php | 0 src/{pocketmine => }/world/particle/FloatingTextParticle.php | 0 src/{pocketmine => }/world/particle/GenericParticle.php | 0 src/{pocketmine => }/world/particle/HappyVillagerParticle.php | 0 src/{pocketmine => }/world/particle/HeartParticle.php | 0 src/{pocketmine => }/world/particle/HugeExplodeParticle.php | 0 src/{pocketmine => }/world/particle/HugeExplodeSeedParticle.php | 0 src/{pocketmine => }/world/particle/InkParticle.php | 0 src/{pocketmine => }/world/particle/InstantEnchantParticle.php | 0 src/{pocketmine => }/world/particle/ItemBreakParticle.php | 0 src/{pocketmine => }/world/particle/LavaDripParticle.php | 0 src/{pocketmine => }/world/particle/LavaParticle.php | 0 src/{pocketmine => }/world/particle/MobSpawnParticle.php | 0 src/{pocketmine => }/world/particle/Particle.php | 0 src/{pocketmine => }/world/particle/PortalParticle.php | 0 src/{pocketmine => }/world/particle/PotionSplashParticle.php | 0 src/{pocketmine => }/world/particle/PunchBlockParticle.php | 0 src/{pocketmine => }/world/particle/RainSplashParticle.php | 0 src/{pocketmine => }/world/particle/RedstoneParticle.php | 0 src/{pocketmine => }/world/particle/SmokeParticle.php | 0 src/{pocketmine => }/world/particle/SnowballPoofParticle.php | 0 src/{pocketmine => }/world/particle/SplashParticle.php | 0 src/{pocketmine => }/world/particle/SporeParticle.php | 0 src/{pocketmine => }/world/particle/TerrainParticle.php | 0 src/{pocketmine => }/world/particle/WaterDripParticle.php | 0 src/{pocketmine => }/world/particle/WaterParticle.php | 0 src/{pocketmine => }/world/sound/AnvilBreakSound.php | 0 src/{pocketmine => }/world/sound/AnvilFallSound.php | 0 src/{pocketmine => }/world/sound/AnvilUseSound.php | 0 src/{pocketmine => }/world/sound/ArrowHitSound.php | 0 src/{pocketmine => }/world/sound/BlazeShootSound.php | 0 src/{pocketmine => }/world/sound/BlockBreakSound.php | 0 src/{pocketmine => }/world/sound/BlockPlaceSound.php | 0 src/{pocketmine => }/world/sound/BowShootSound.php | 0 src/{pocketmine => }/world/sound/BucketEmptyLavaSound.php | 0 src/{pocketmine => }/world/sound/BucketEmptyWaterSound.php | 0 src/{pocketmine => }/world/sound/BucketFillLavaSound.php | 0 src/{pocketmine => }/world/sound/BucketFillWaterSound.php | 0 src/{pocketmine => }/world/sound/ChestCloseSound.php | 0 src/{pocketmine => }/world/sound/ChestOpenSound.php | 0 src/{pocketmine => }/world/sound/ClickSound.php | 0 src/{pocketmine => }/world/sound/DoorBumpSound.php | 0 src/{pocketmine => }/world/sound/DoorCrashSound.php | 0 src/{pocketmine => }/world/sound/DoorSound.php | 0 src/{pocketmine => }/world/sound/EnderChestCloseSound.php | 0 src/{pocketmine => }/world/sound/EnderChestOpenSound.php | 0 src/{pocketmine => }/world/sound/EndermanTeleportSound.php | 0 src/{pocketmine => }/world/sound/ExplodeSound.php | 0 src/{pocketmine => }/world/sound/FizzSound.php | 0 src/{pocketmine => }/world/sound/FlintSteelSound.php | 0 src/{pocketmine => }/world/sound/GhastShootSound.php | 0 src/{pocketmine => }/world/sound/GhastSound.php | 0 src/{pocketmine => }/world/sound/IgniteSound.php | 0 src/{pocketmine => }/world/sound/ItemBreakSound.php | 0 src/{pocketmine => }/world/sound/LaunchSound.php | 0 src/{pocketmine => }/world/sound/LevelEventSound.php | 0 src/{pocketmine => }/world/sound/NoteInstrument.php | 0 src/{pocketmine => }/world/sound/NoteSound.php | 0 src/{pocketmine => }/world/sound/PaintingPlaceSound.php | 0 src/{pocketmine => }/world/sound/PopSound.php | 0 src/{pocketmine => }/world/sound/PotionSplashSound.php | 0 src/{pocketmine => }/world/sound/RedstonePowerOffSound.php | 0 src/{pocketmine => }/world/sound/RedstonePowerOnSound.php | 0 src/{pocketmine => }/world/sound/Sound.php | 0 src/{pocketmine => }/world/sound/ThrowSound.php | 0 src/{pocketmine => }/world/sound/TotemUseSound.php | 0 src/{pocketmine => }/world/sound/XpCollectSound.php | 0 src/{pocketmine => }/world/sound/XpLevelUpSound.php | 0 src/{pocketmine => }/world/utils/SubChunkIteratorManager.php | 0 tests/plugins/PocketMine-DevTools | 2 +- 1044 files changed, 3 insertions(+), 3 deletions(-) rename src/{pocketmine => }/CrashDump.php (100%) rename src/{pocketmine => }/MemoryManager.php (100%) rename src/{pocketmine => }/PocketMine.php (99%) rename src/{pocketmine => }/Server.php (100%) rename src/{pocketmine => }/VersionInfo.php (100%) rename src/{pocketmine => }/block/ActivatorRail.php (100%) rename src/{pocketmine => }/block/Air.php (100%) rename src/{pocketmine => }/block/Anvil.php (100%) rename src/{pocketmine => }/block/Banner.php (100%) rename src/{pocketmine => }/block/BaseRail.php (100%) rename src/{pocketmine => }/block/Bed.php (100%) rename src/{pocketmine => }/block/Bedrock.php (100%) rename src/{pocketmine => }/block/Beetroot.php (100%) rename src/{pocketmine => }/block/Block.php (100%) rename src/{pocketmine => }/block/BlockBreakInfo.php (100%) rename src/{pocketmine => }/block/BlockFactory.php (100%) rename src/{pocketmine => }/block/BlockIdentifier.php (100%) rename src/{pocketmine => }/block/BlockIdentifierFlattened.php (100%) rename src/{pocketmine => }/block/BlockLegacyIds.php (100%) rename src/{pocketmine => }/block/BlockLegacyMetadata.php (100%) rename src/{pocketmine => }/block/BlockToolType.php (100%) rename src/{pocketmine => }/block/BlueIce.php (100%) rename src/{pocketmine => }/block/BoneBlock.php (100%) rename src/{pocketmine => }/block/Bookshelf.php (100%) rename src/{pocketmine => }/block/BrewingStand.php (100%) rename src/{pocketmine => }/block/BrownMushroom.php (100%) rename src/{pocketmine => }/block/BrownMushroomBlock.php (100%) rename src/{pocketmine => }/block/Button.php (100%) rename src/{pocketmine => }/block/Cactus.php (100%) rename src/{pocketmine => }/block/Cake.php (100%) rename src/{pocketmine => }/block/Carpet.php (100%) rename src/{pocketmine => }/block/Carrot.php (100%) rename src/{pocketmine => }/block/CarvedPumpkin.php (100%) rename src/{pocketmine => }/block/Chest.php (100%) rename src/{pocketmine => }/block/Clay.php (100%) rename src/{pocketmine => }/block/Coal.php (100%) rename src/{pocketmine => }/block/CoalOre.php (100%) rename src/{pocketmine => }/block/CoarseDirt.php (100%) rename src/{pocketmine => }/block/Cobweb.php (100%) rename src/{pocketmine => }/block/CocoaBlock.php (100%) rename src/{pocketmine => }/block/Concrete.php (100%) rename src/{pocketmine => }/block/ConcretePowder.php (100%) rename src/{pocketmine => }/block/CraftingTable.php (100%) rename src/{pocketmine => }/block/Crops.php (100%) rename src/{pocketmine => }/block/DaylightSensor.php (100%) rename src/{pocketmine => }/block/DeadBush.php (100%) rename src/{pocketmine => }/block/DetectorRail.php (100%) rename src/{pocketmine => }/block/DiamondOre.php (100%) rename src/{pocketmine => }/block/Dirt.php (100%) rename src/{pocketmine => }/block/Door.php (100%) rename src/{pocketmine => }/block/DoublePlant.php (100%) rename src/{pocketmine => }/block/DoubleTallGrass.php (100%) rename src/{pocketmine => }/block/DragonEgg.php (100%) rename src/{pocketmine => }/block/DriedKelp.php (100%) rename src/{pocketmine => }/block/Element.php (100%) rename src/{pocketmine => }/block/EmeraldOre.php (100%) rename src/{pocketmine => }/block/EnchantingTable.php (100%) rename src/{pocketmine => }/block/EndPortalFrame.php (100%) rename src/{pocketmine => }/block/EndRod.php (100%) rename src/{pocketmine => }/block/EnderChest.php (100%) rename src/{pocketmine => }/block/Farmland.php (100%) rename src/{pocketmine => }/block/Fence.php (100%) rename src/{pocketmine => }/block/FenceGate.php (100%) rename src/{pocketmine => }/block/Fire.php (100%) rename src/{pocketmine => }/block/Flowable.php (100%) rename src/{pocketmine => }/block/Flower.php (100%) rename src/{pocketmine => }/block/FlowerPot.php (100%) rename src/{pocketmine => }/block/FrostedIce.php (100%) rename src/{pocketmine => }/block/Furnace.php (100%) rename src/{pocketmine => }/block/Glass.php (100%) rename src/{pocketmine => }/block/GlassPane.php (100%) rename src/{pocketmine => }/block/GlazedTerracotta.php (100%) rename src/{pocketmine => }/block/GlowingObsidian.php (100%) rename src/{pocketmine => }/block/Glowstone.php (100%) rename src/{pocketmine => }/block/Grass.php (100%) rename src/{pocketmine => }/block/GrassPath.php (100%) rename src/{pocketmine => }/block/Gravel.php (100%) rename src/{pocketmine => }/block/HardenedClay.php (100%) rename src/{pocketmine => }/block/HardenedGlass.php (100%) rename src/{pocketmine => }/block/HardenedGlassPane.php (100%) rename src/{pocketmine => }/block/HayBale.php (100%) rename src/{pocketmine => }/block/Hopper.php (100%) rename src/{pocketmine => }/block/Ice.php (100%) rename src/{pocketmine => }/block/InfestedStone.php (100%) rename src/{pocketmine => }/block/ItemFrame.php (100%) rename src/{pocketmine => }/block/Ladder.php (100%) rename src/{pocketmine => }/block/Lantern.php (100%) rename src/{pocketmine => }/block/LapisOre.php (100%) rename src/{pocketmine => }/block/Lava.php (100%) rename src/{pocketmine => }/block/Leaves.php (100%) rename src/{pocketmine => }/block/Lever.php (100%) rename src/{pocketmine => }/block/Liquid.php (100%) rename src/{pocketmine => }/block/LitPumpkin.php (100%) rename src/{pocketmine => }/block/Log.php (100%) rename src/{pocketmine => }/block/Magma.php (100%) rename src/{pocketmine => }/block/Melon.php (100%) rename src/{pocketmine => }/block/MelonStem.php (100%) rename src/{pocketmine => }/block/MonsterSpawner.php (100%) rename src/{pocketmine => }/block/Mycelium.php (100%) rename src/{pocketmine => }/block/NetherPortal.php (100%) rename src/{pocketmine => }/block/NetherQuartzOre.php (100%) rename src/{pocketmine => }/block/NetherReactor.php (100%) rename src/{pocketmine => }/block/NetherWartPlant.php (100%) rename src/{pocketmine => }/block/Netherrack.php (100%) rename src/{pocketmine => }/block/Note.php (100%) rename src/{pocketmine => }/block/Opaque.php (100%) rename src/{pocketmine => }/block/PackedIce.php (100%) rename src/{pocketmine => }/block/Planks.php (100%) rename src/{pocketmine => }/block/Podzol.php (100%) rename src/{pocketmine => }/block/Potato.php (100%) rename src/{pocketmine => }/block/PoweredRail.php (100%) rename src/{pocketmine => }/block/PressurePlate.php (100%) rename src/{pocketmine => }/block/PumpkinStem.php (100%) rename src/{pocketmine => }/block/Rail.php (100%) rename src/{pocketmine => }/block/RedMushroom.php (100%) rename src/{pocketmine => }/block/RedMushroomBlock.php (100%) rename src/{pocketmine => }/block/Redstone.php (100%) rename src/{pocketmine => }/block/RedstoneComparator.php (100%) rename src/{pocketmine => }/block/RedstoneLamp.php (100%) rename src/{pocketmine => }/block/RedstoneOre.php (100%) rename src/{pocketmine => }/block/RedstoneRail.php (100%) rename src/{pocketmine => }/block/RedstoneRepeater.php (100%) rename src/{pocketmine => }/block/RedstoneTorch.php (100%) rename src/{pocketmine => }/block/RedstoneWire.php (100%) rename src/{pocketmine => }/block/Reserved6.php (100%) rename src/{pocketmine => }/block/Sand.php (100%) rename src/{pocketmine => }/block/Sapling.php (100%) rename src/{pocketmine => }/block/SeaLantern.php (100%) rename src/{pocketmine => }/block/SeaPickle.php (100%) rename src/{pocketmine => }/block/Sign.php (100%) rename src/{pocketmine => }/block/SimplePressurePlate.php (100%) rename src/{pocketmine => }/block/Skull.php (100%) rename src/{pocketmine => }/block/Slab.php (100%) rename src/{pocketmine => }/block/Snow.php (100%) rename src/{pocketmine => }/block/SnowLayer.php (100%) rename src/{pocketmine => }/block/SoulSand.php (100%) rename src/{pocketmine => }/block/Sponge.php (100%) rename src/{pocketmine => }/block/Stair.php (100%) rename src/{pocketmine => }/block/Stem.php (100%) rename src/{pocketmine => }/block/StoneButton.php (100%) rename src/{pocketmine => }/block/StonePressurePlate.php (100%) rename src/{pocketmine => }/block/Sugarcane.php (100%) rename src/{pocketmine => }/block/TNT.php (100%) rename src/{pocketmine => }/block/TallGrass.php (100%) rename src/{pocketmine => }/block/Thin.php (100%) rename src/{pocketmine => }/block/Torch.php (100%) rename src/{pocketmine => }/block/Transparent.php (100%) rename src/{pocketmine => }/block/Trapdoor.php (100%) rename src/{pocketmine => }/block/TrappedChest.php (100%) rename src/{pocketmine => }/block/Tripwire.php (100%) rename src/{pocketmine => }/block/TripwireHook.php (100%) rename src/{pocketmine => }/block/UnderwaterTorch.php (100%) rename src/{pocketmine => }/block/UnknownBlock.php (100%) rename src/{pocketmine => }/block/VanillaBlocks.php (100%) rename src/{pocketmine => }/block/Vine.php (100%) rename src/{pocketmine => }/block/Wall.php (100%) rename src/{pocketmine => }/block/Water.php (100%) rename src/{pocketmine => }/block/WaterLily.php (100%) rename src/{pocketmine => }/block/WeightedPressurePlate.php (100%) rename src/{pocketmine => }/block/WeightedPressurePlateHeavy.php (100%) rename src/{pocketmine => }/block/WeightedPressurePlateLight.php (100%) rename src/{pocketmine => }/block/Wheat.php (100%) rename src/{pocketmine => }/block/Wood.php (100%) rename src/{pocketmine => }/block/WoodenButton.php (100%) rename src/{pocketmine => }/block/WoodenDoor.php (100%) rename src/{pocketmine => }/block/WoodenFence.php (100%) rename src/{pocketmine => }/block/WoodenPressurePlate.php (100%) rename src/{pocketmine => }/block/WoodenSlab.php (100%) rename src/{pocketmine => }/block/WoodenStairs.php (100%) rename src/{pocketmine => }/block/WoodenTrapdoor.php (100%) rename src/{pocketmine => }/block/Wool.php (100%) rename src/{pocketmine => }/block/tile/Banner.php (100%) rename src/{pocketmine => }/block/tile/Bed.php (100%) rename src/{pocketmine => }/block/tile/BrewingStand.php (100%) rename src/{pocketmine => }/block/tile/Chest.php (100%) rename src/{pocketmine => }/block/tile/Comparator.php (100%) rename src/{pocketmine => }/block/tile/Container.php (100%) rename src/{pocketmine => }/block/tile/ContainerTrait.php (100%) rename src/{pocketmine => }/block/tile/DaylightSensor.php (100%) rename src/{pocketmine => }/block/tile/EnchantTable.php (100%) rename src/{pocketmine => }/block/tile/EnderChest.php (100%) rename src/{pocketmine => }/block/tile/FlowerPot.php (100%) rename src/{pocketmine => }/block/tile/Furnace.php (100%) rename src/{pocketmine => }/block/tile/Hopper.php (100%) rename src/{pocketmine => }/block/tile/ItemFrame.php (100%) rename src/{pocketmine => }/block/tile/MonsterSpawner.php (100%) rename src/{pocketmine => }/block/tile/Nameable.php (100%) rename src/{pocketmine => }/block/tile/NameableTrait.php (100%) rename src/{pocketmine => }/block/tile/Note.php (100%) rename src/{pocketmine => }/block/tile/Sign.php (100%) rename src/{pocketmine => }/block/tile/Skull.php (100%) rename src/{pocketmine => }/block/tile/Spawnable.php (100%) rename src/{pocketmine => }/block/tile/Tile.php (100%) rename src/{pocketmine => }/block/tile/TileFactory.php (100%) rename src/{pocketmine => }/block/utils/BannerPattern.php (100%) rename src/{pocketmine => }/block/utils/BlockDataSerializer.php (100%) rename src/{pocketmine => }/block/utils/DyeColor.php (100%) rename src/{pocketmine => }/block/utils/Fallable.php (100%) rename src/{pocketmine => }/block/utils/FallableTrait.php (100%) rename src/{pocketmine => }/block/utils/InvalidBlockStateException.php (100%) rename src/{pocketmine => }/block/utils/PillarRotationTrait.php (100%) rename src/{pocketmine => }/block/utils/SignText.php (100%) rename src/{pocketmine => }/block/utils/SkullType.php (100%) rename src/{pocketmine => }/block/utils/SlabType.php (100%) rename src/{pocketmine => }/block/utils/StairShape.php (100%) rename src/{pocketmine => }/block/utils/TreeType.php (100%) rename src/{pocketmine => }/command/Command.php (100%) rename src/{pocketmine => }/command/CommandExecutor.php (100%) rename src/{pocketmine => }/command/CommandMap.php (100%) rename src/{pocketmine => }/command/CommandReader.php (100%) rename src/{pocketmine => }/command/CommandSender.php (100%) rename src/{pocketmine => }/command/ConsoleCommandSender.php (100%) rename src/{pocketmine => }/command/FormattedCommandAlias.php (100%) rename src/{pocketmine => }/command/PluginCommand.php (100%) rename src/{pocketmine => }/command/PluginIdentifiableCommand.php (100%) rename src/{pocketmine => }/command/SimpleCommandMap.php (100%) rename src/{pocketmine => }/command/defaults/BanCommand.php (100%) rename src/{pocketmine => }/command/defaults/BanIpCommand.php (100%) rename src/{pocketmine => }/command/defaults/BanListCommand.php (100%) rename src/{pocketmine => }/command/defaults/DefaultGamemodeCommand.php (100%) rename src/{pocketmine => }/command/defaults/DeopCommand.php (100%) rename src/{pocketmine => }/command/defaults/DifficultyCommand.php (100%) rename src/{pocketmine => }/command/defaults/DumpMemoryCommand.php (100%) rename src/{pocketmine => }/command/defaults/EffectCommand.php (100%) rename src/{pocketmine => }/command/defaults/EnchantCommand.php (100%) rename src/{pocketmine => }/command/defaults/GamemodeCommand.php (100%) rename src/{pocketmine => }/command/defaults/GarbageCollectorCommand.php (100%) rename src/{pocketmine => }/command/defaults/GiveCommand.php (100%) rename src/{pocketmine => }/command/defaults/HelpCommand.php (100%) rename src/{pocketmine => }/command/defaults/KickCommand.php (100%) rename src/{pocketmine => }/command/defaults/KillCommand.php (100%) rename src/{pocketmine => }/command/defaults/ListCommand.php (100%) rename src/{pocketmine => }/command/defaults/MeCommand.php (100%) rename src/{pocketmine => }/command/defaults/OpCommand.php (100%) rename src/{pocketmine => }/command/defaults/PardonCommand.php (100%) rename src/{pocketmine => }/command/defaults/PardonIpCommand.php (100%) rename src/{pocketmine => }/command/defaults/ParticleCommand.php (100%) rename src/{pocketmine => }/command/defaults/PluginsCommand.php (100%) rename src/{pocketmine => }/command/defaults/SaveCommand.php (100%) rename src/{pocketmine => }/command/defaults/SaveOffCommand.php (100%) rename src/{pocketmine => }/command/defaults/SaveOnCommand.php (100%) rename src/{pocketmine => }/command/defaults/SayCommand.php (100%) rename src/{pocketmine => }/command/defaults/SeedCommand.php (100%) rename src/{pocketmine => }/command/defaults/SetWorldSpawnCommand.php (100%) rename src/{pocketmine => }/command/defaults/SpawnpointCommand.php (100%) rename src/{pocketmine => }/command/defaults/StatusCommand.php (100%) rename src/{pocketmine => }/command/defaults/StopCommand.php (100%) rename src/{pocketmine => }/command/defaults/TeleportCommand.php (100%) rename src/{pocketmine => }/command/defaults/TellCommand.php (100%) rename src/{pocketmine => }/command/defaults/TimeCommand.php (100%) rename src/{pocketmine => }/command/defaults/TimingsCommand.php (100%) rename src/{pocketmine => }/command/defaults/TitleCommand.php (100%) rename src/{pocketmine => }/command/defaults/TransferServerCommand.php (100%) rename src/{pocketmine => }/command/defaults/VanillaCommand.php (100%) rename src/{pocketmine => }/command/defaults/VersionCommand.php (100%) rename src/{pocketmine => }/command/defaults/WhitelistCommand.php (100%) rename src/{pocketmine => }/command/utils/CommandException.php (100%) rename src/{pocketmine => }/command/utils/InvalidCommandSyntaxException.php (100%) rename src/{pocketmine => }/crafting/CraftingGrid.php (100%) rename src/{pocketmine => }/crafting/CraftingManager.php (100%) rename src/{pocketmine => }/crafting/CraftingRecipe.php (100%) rename src/{pocketmine => }/crafting/FurnaceRecipe.php (100%) rename src/{pocketmine => }/crafting/MultiRecipe.php (100%) rename src/{pocketmine => }/crafting/ShapedRecipe.php (100%) rename src/{pocketmine => }/crafting/ShapelessRecipe.php (100%) rename src/{pocketmine => }/entity/Ageable.php (100%) rename src/{pocketmine => }/entity/Animal.php (100%) rename src/{pocketmine => }/entity/Attribute.php (100%) rename src/{pocketmine => }/entity/AttributeMap.php (100%) rename src/{pocketmine => }/entity/Entity.php (100%) rename src/{pocketmine => }/entity/EntityFactory.php (100%) rename src/{pocketmine => }/entity/ExperienceManager.php (100%) rename src/{pocketmine => }/entity/Explosive.php (100%) rename src/{pocketmine => }/entity/Human.php (100%) rename src/{pocketmine => }/entity/HungerManager.php (100%) rename src/{pocketmine => }/entity/Living.php (100%) rename src/{pocketmine => }/entity/Skin.php (100%) rename src/{pocketmine => }/entity/Squid.php (100%) rename src/{pocketmine => }/entity/Villager.php (100%) rename src/{pocketmine => }/entity/WaterAnimal.php (100%) rename src/{pocketmine => }/entity/Zombie.php (100%) rename src/{pocketmine => }/entity/effect/AbsorptionEffect.php (100%) rename src/{pocketmine => }/entity/effect/Effect.php (100%) rename src/{pocketmine => }/entity/effect/EffectInstance.php (100%) rename src/{pocketmine => }/entity/effect/EffectManager.php (100%) rename src/{pocketmine => }/entity/effect/HealthBoostEffect.php (100%) rename src/{pocketmine => }/entity/effect/HungerEffect.php (100%) rename src/{pocketmine => }/entity/effect/InstantDamageEffect.php (100%) rename src/{pocketmine => }/entity/effect/InstantEffect.php (100%) rename src/{pocketmine => }/entity/effect/InstantHealthEffect.php (100%) rename src/{pocketmine => }/entity/effect/InvisibilityEffect.php (100%) rename src/{pocketmine => }/entity/effect/LevitationEffect.php (100%) rename src/{pocketmine => }/entity/effect/PoisonEffect.php (100%) rename src/{pocketmine => }/entity/effect/RegenerationEffect.php (100%) rename src/{pocketmine => }/entity/effect/SaturationEffect.php (100%) rename src/{pocketmine => }/entity/effect/SlownessEffect.php (100%) rename src/{pocketmine => }/entity/effect/SpeedEffect.php (100%) rename src/{pocketmine => }/entity/effect/VanillaEffects.php (100%) rename src/{pocketmine => }/entity/effect/WitherEffect.php (100%) rename src/{pocketmine => }/entity/object/ExperienceOrb.php (100%) rename src/{pocketmine => }/entity/object/FallingBlock.php (100%) rename src/{pocketmine => }/entity/object/ItemEntity.php (100%) rename src/{pocketmine => }/entity/object/Painting.php (100%) rename src/{pocketmine => }/entity/object/PaintingMotive.php (100%) rename src/{pocketmine => }/entity/object/PrimedTNT.php (100%) rename src/{pocketmine => }/entity/projectile/Arrow.php (100%) rename src/{pocketmine => }/entity/projectile/Egg.php (100%) rename src/{pocketmine => }/entity/projectile/EnderPearl.php (100%) rename src/{pocketmine => }/entity/projectile/ExperienceBottle.php (100%) rename src/{pocketmine => }/entity/projectile/Projectile.php (100%) rename src/{pocketmine => }/entity/projectile/ProjectileSource.php (100%) rename src/{pocketmine => }/entity/projectile/Snowball.php (100%) rename src/{pocketmine => }/entity/projectile/SplashPotion.php (100%) rename src/{pocketmine => }/entity/projectile/Throwable.php (100%) rename src/{pocketmine => }/entity/utils/ExperienceUtils.php (100%) rename src/{pocketmine => }/event/Cancellable.php (100%) rename src/{pocketmine => }/event/CancellableTrait.php (100%) rename src/{pocketmine => }/event/Event.php (100%) rename src/{pocketmine => }/event/EventPriority.php (100%) rename src/{pocketmine => }/event/HandlerList.php (100%) rename src/{pocketmine => }/event/HandlerListManager.php (100%) rename src/{pocketmine => }/event/Listener.php (100%) rename src/{pocketmine => }/event/RegisteredListener.php (100%) rename src/{pocketmine => }/event/block/BlockBreakEvent.php (100%) rename src/{pocketmine => }/event/block/BlockBurnEvent.php (100%) rename src/{pocketmine => }/event/block/BlockEvent.php (100%) rename src/{pocketmine => }/event/block/BlockFormEvent.php (100%) rename src/{pocketmine => }/event/block/BlockGrowEvent.php (100%) rename src/{pocketmine => }/event/block/BlockPlaceEvent.php (100%) rename src/{pocketmine => }/event/block/BlockSpreadEvent.php (100%) rename src/{pocketmine => }/event/block/BlockTeleportEvent.php (100%) rename src/{pocketmine => }/event/block/BlockUpdateEvent.php (100%) rename src/{pocketmine => }/event/block/LeavesDecayEvent.php (100%) rename src/{pocketmine => }/event/block/SignChangeEvent.php (100%) rename src/{pocketmine => }/event/entity/EntityBlockChangeEvent.php (100%) rename src/{pocketmine => }/event/entity/EntityCombustByBlockEvent.php (100%) rename src/{pocketmine => }/event/entity/EntityCombustByEntityEvent.php (100%) rename src/{pocketmine => }/event/entity/EntityCombustEvent.php (100%) rename src/{pocketmine => }/event/entity/EntityDamageByBlockEvent.php (100%) rename src/{pocketmine => }/event/entity/EntityDamageByChildEntityEvent.php (100%) rename src/{pocketmine => }/event/entity/EntityDamageByEntityEvent.php (100%) rename src/{pocketmine => }/event/entity/EntityDamageEvent.php (100%) rename src/{pocketmine => }/event/entity/EntityDeathEvent.php (100%) rename src/{pocketmine => }/event/entity/EntityDespawnEvent.php (100%) rename src/{pocketmine => }/event/entity/EntityEffectAddEvent.php (100%) rename src/{pocketmine => }/event/entity/EntityEffectEvent.php (100%) rename src/{pocketmine => }/event/entity/EntityEffectRemoveEvent.php (100%) rename src/{pocketmine => }/event/entity/EntityEvent.php (100%) rename src/{pocketmine => }/event/entity/EntityExplodeEvent.php (100%) rename src/{pocketmine => }/event/entity/EntityMotionEvent.php (100%) rename src/{pocketmine => }/event/entity/EntityRegainHealthEvent.php (100%) rename src/{pocketmine => }/event/entity/EntityShootBowEvent.php (100%) rename src/{pocketmine => }/event/entity/EntitySpawnEvent.php (100%) rename src/{pocketmine => }/event/entity/EntityTeleportEvent.php (100%) rename src/{pocketmine => }/event/entity/ExplosionPrimeEvent.php (100%) rename src/{pocketmine => }/event/entity/ItemDespawnEvent.php (100%) rename src/{pocketmine => }/event/entity/ItemSpawnEvent.php (100%) rename src/{pocketmine => }/event/entity/ProjectileHitBlockEvent.php (100%) rename src/{pocketmine => }/event/entity/ProjectileHitEntityEvent.php (100%) rename src/{pocketmine => }/event/entity/ProjectileHitEvent.php (100%) rename src/{pocketmine => }/event/entity/ProjectileLaunchEvent.php (100%) rename src/{pocketmine => }/event/inventory/CraftItemEvent.php (100%) rename src/{pocketmine => }/event/inventory/FurnaceBurnEvent.php (100%) rename src/{pocketmine => }/event/inventory/FurnaceSmeltEvent.php (100%) rename src/{pocketmine => }/event/inventory/InventoryCloseEvent.php (100%) rename src/{pocketmine => }/event/inventory/InventoryEvent.php (100%) rename src/{pocketmine => }/event/inventory/InventoryOpenEvent.php (100%) rename src/{pocketmine => }/event/inventory/InventoryPickupArrowEvent.php (100%) rename src/{pocketmine => }/event/inventory/InventoryPickupItemEvent.php (100%) rename src/{pocketmine => }/event/inventory/InventoryTransactionEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerBedEnterEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerBedLeaveEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerBlockPickEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerBucketEmptyEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerBucketEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerBucketFillEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerChangeSkinEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerChatEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerCommandPreprocessEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerCreationEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerDataSaveEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerDeathEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerDropItemEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerDuplicateLoginEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerEditBookEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerExhaustEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerExperienceChangeEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerGameModeChangeEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerInteractEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerItemConsumeEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerItemHeldEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerItemUseEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerJoinEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerJumpEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerKickEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerLoginEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerMoveEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerPreLoginEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerQuitEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerRespawnEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerToggleFlightEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerToggleSneakEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerToggleSprintEvent.php (100%) rename src/{pocketmine => }/event/player/PlayerTransferEvent.php (100%) rename src/{pocketmine => }/event/plugin/PluginDisableEvent.php (100%) rename src/{pocketmine => }/event/plugin/PluginEnableEvent.php (100%) rename src/{pocketmine => }/event/plugin/PluginEvent.php (100%) rename src/{pocketmine => }/event/server/CommandEvent.php (100%) rename src/{pocketmine => }/event/server/DataPacketBroadcastEvent.php (100%) rename src/{pocketmine => }/event/server/DataPacketReceiveEvent.php (100%) rename src/{pocketmine => }/event/server/DataPacketSendEvent.php (100%) rename src/{pocketmine => }/event/server/LowMemoryEvent.php (100%) rename src/{pocketmine => }/event/server/NetworkInterfaceEvent.php (100%) rename src/{pocketmine => }/event/server/NetworkInterfaceRegisterEvent.php (100%) rename src/{pocketmine => }/event/server/NetworkInterfaceUnregisterEvent.php (100%) rename src/{pocketmine => }/event/server/QueryRegenerateEvent.php (100%) rename src/{pocketmine => }/event/server/ServerEvent.php (100%) rename src/{pocketmine => }/event/server/UpdateNotifyEvent.php (100%) rename src/{pocketmine => }/event/world/ChunkEvent.php (100%) rename src/{pocketmine => }/event/world/ChunkLoadEvent.php (100%) rename src/{pocketmine => }/event/world/ChunkPopulateEvent.php (100%) rename src/{pocketmine => }/event/world/ChunkUnloadEvent.php (100%) rename src/{pocketmine => }/event/world/SpawnChangeEvent.php (100%) rename src/{pocketmine => }/event/world/WorldEvent.php (100%) rename src/{pocketmine => }/event/world/WorldInitEvent.php (100%) rename src/{pocketmine => }/event/world/WorldLoadEvent.php (100%) rename src/{pocketmine => }/event/world/WorldSaveEvent.php (100%) rename src/{pocketmine => }/event/world/WorldUnloadEvent.php (100%) rename src/{pocketmine => }/form/Form.php (100%) rename src/{pocketmine => }/form/FormValidationException.php (100%) rename src/{pocketmine => }/inventory/AnvilInventory.php (100%) rename src/{pocketmine => }/inventory/ArmorInventory.php (100%) rename src/{pocketmine => }/inventory/BaseInventory.php (100%) rename src/{pocketmine => }/inventory/BlockInventory.php (100%) rename src/{pocketmine => }/inventory/BrewingStandInventory.php (100%) rename src/{pocketmine => }/inventory/CallbackInventoryChangeListener.php (100%) rename src/{pocketmine => }/inventory/ChestInventory.php (100%) rename src/{pocketmine => }/inventory/CreativeInventory.php (100%) rename src/{pocketmine => }/inventory/DoubleChestInventory.php (100%) rename src/{pocketmine => }/inventory/EnchantInventory.php (100%) rename src/{pocketmine => }/inventory/EnderChestInventory.php (100%) rename src/{pocketmine => }/inventory/FurnaceInventory.php (100%) rename src/{pocketmine => }/inventory/HopperInventory.php (100%) rename src/{pocketmine => }/inventory/Inventory.php (100%) rename src/{pocketmine => }/inventory/InventoryChangeListener.php (100%) rename src/{pocketmine => }/inventory/InventoryHolder.php (100%) rename src/{pocketmine => }/inventory/PlayerCursorInventory.php (100%) rename src/{pocketmine => }/inventory/PlayerInventory.php (100%) rename src/{pocketmine => }/inventory/transaction/CraftingTransaction.php (100%) rename src/{pocketmine => }/inventory/transaction/InventoryTransaction.php (100%) rename src/{pocketmine => }/inventory/transaction/TransactionValidationException.php (100%) rename src/{pocketmine => }/inventory/transaction/action/CreateItemAction.php (100%) rename src/{pocketmine => }/inventory/transaction/action/DestroyItemAction.php (100%) rename src/{pocketmine => }/inventory/transaction/action/DropItemAction.php (100%) rename src/{pocketmine => }/inventory/transaction/action/InventoryAction.php (100%) rename src/{pocketmine => }/inventory/transaction/action/SlotChangeAction.php (100%) rename src/{pocketmine => }/item/Apple.php (100%) rename src/{pocketmine => }/item/Armor.php (100%) rename src/{pocketmine => }/item/ArmorTypeInfo.php (100%) rename src/{pocketmine => }/item/Arrow.php (100%) rename src/{pocketmine => }/item/Axe.php (100%) rename src/{pocketmine => }/item/BakedPotato.php (100%) rename src/{pocketmine => }/item/Banner.php (100%) rename src/{pocketmine => }/item/Bed.php (100%) rename src/{pocketmine => }/item/Beetroot.php (100%) rename src/{pocketmine => }/item/BeetrootSeeds.php (100%) rename src/{pocketmine => }/item/BeetrootSoup.php (100%) rename src/{pocketmine => }/item/BlazeRod.php (100%) rename src/{pocketmine => }/item/Boat.php (100%) rename src/{pocketmine => }/item/Book.php (100%) rename src/{pocketmine => }/item/Boots.php (100%) rename src/{pocketmine => }/item/Bow.php (100%) rename src/{pocketmine => }/item/Bowl.php (100%) rename src/{pocketmine => }/item/Bread.php (100%) rename src/{pocketmine => }/item/Bucket.php (100%) rename src/{pocketmine => }/item/Carrot.php (100%) rename src/{pocketmine => }/item/Chestplate.php (100%) rename src/{pocketmine => }/item/ChorusFruit.php (100%) rename src/{pocketmine => }/item/Clock.php (100%) rename src/{pocketmine => }/item/Clownfish.php (100%) rename src/{pocketmine => }/item/Coal.php (100%) rename src/{pocketmine => }/item/CocoaBeans.php (100%) rename src/{pocketmine => }/item/Compass.php (100%) rename src/{pocketmine => }/item/Consumable.php (100%) rename src/{pocketmine => }/item/CookedChicken.php (100%) rename src/{pocketmine => }/item/CookedFish.php (100%) rename src/{pocketmine => }/item/CookedMutton.php (100%) rename src/{pocketmine => }/item/CookedPorkchop.php (100%) rename src/{pocketmine => }/item/CookedRabbit.php (100%) rename src/{pocketmine => }/item/CookedSalmon.php (100%) rename src/{pocketmine => }/item/Cookie.php (100%) rename src/{pocketmine => }/item/DriedKelp.php (100%) rename src/{pocketmine => }/item/Durable.php (100%) rename src/{pocketmine => }/item/Dye.php (100%) rename src/{pocketmine => }/item/Egg.php (100%) rename src/{pocketmine => }/item/EnderPearl.php (100%) rename src/{pocketmine => }/item/ExperienceBottle.php (100%) rename src/{pocketmine => }/item/Fertilizer.php (100%) rename src/{pocketmine => }/item/FishingRod.php (100%) rename src/{pocketmine => }/item/FlintSteel.php (100%) rename src/{pocketmine => }/item/Food.php (100%) rename src/{pocketmine => }/item/FoodSource.php (100%) rename src/{pocketmine => }/item/GlassBottle.php (100%) rename src/{pocketmine => }/item/GoldenApple.php (100%) rename src/{pocketmine => }/item/GoldenAppleEnchanted.php (100%) rename src/{pocketmine => }/item/GoldenCarrot.php (100%) rename src/{pocketmine => }/item/Helmet.php (100%) rename src/{pocketmine => }/item/Hoe.php (100%) rename src/{pocketmine => }/item/Item.php (100%) rename src/{pocketmine => }/item/ItemBlock.php (100%) rename src/{pocketmine => }/item/ItemEnchantmentHandlingTrait.php (100%) rename src/{pocketmine => }/item/ItemFactory.php (100%) rename src/{pocketmine => }/item/ItemIds.php (100%) rename src/{pocketmine => }/item/ItemUseResult.php (100%) rename src/{pocketmine => }/item/Leggings.php (100%) rename src/{pocketmine => }/item/LiquidBucket.php (100%) rename src/{pocketmine => }/item/Melon.php (100%) rename src/{pocketmine => }/item/MelonSeeds.php (100%) rename src/{pocketmine => }/item/MilkBucket.php (100%) rename src/{pocketmine => }/item/Minecart.php (100%) rename src/{pocketmine => }/item/MushroomStew.php (100%) rename src/{pocketmine => }/item/PaintingItem.php (100%) rename src/{pocketmine => }/item/Pickaxe.php (100%) rename src/{pocketmine => }/item/PoisonousPotato.php (100%) rename src/{pocketmine => }/item/Potato.php (100%) rename src/{pocketmine => }/item/Potion.php (100%) rename src/{pocketmine => }/item/ProjectileItem.php (100%) rename src/{pocketmine => }/item/Pufferfish.php (100%) rename src/{pocketmine => }/item/PumpkinPie.php (100%) rename src/{pocketmine => }/item/PumpkinSeeds.php (100%) rename src/{pocketmine => }/item/RabbitStew.php (100%) rename src/{pocketmine => }/item/RawBeef.php (100%) rename src/{pocketmine => }/item/RawChicken.php (100%) rename src/{pocketmine => }/item/RawFish.php (100%) rename src/{pocketmine => }/item/RawMutton.php (100%) rename src/{pocketmine => }/item/RawPorkchop.php (100%) rename src/{pocketmine => }/item/RawRabbit.php (100%) rename src/{pocketmine => }/item/RawSalmon.php (100%) rename src/{pocketmine => }/item/Redstone.php (100%) rename src/{pocketmine => }/item/RottenFlesh.php (100%) rename src/{pocketmine => }/item/Shears.php (100%) rename src/{pocketmine => }/item/Shovel.php (100%) rename src/{pocketmine => }/item/Sign.php (100%) rename src/{pocketmine => }/item/Skull.php (100%) rename src/{pocketmine => }/item/Snowball.php (100%) rename src/{pocketmine => }/item/SpawnEgg.php (100%) rename src/{pocketmine => }/item/SpiderEye.php (100%) rename src/{pocketmine => }/item/SplashPotion.php (100%) rename src/{pocketmine => }/item/Steak.php (100%) rename src/{pocketmine => }/item/Stick.php (100%) rename src/{pocketmine => }/item/StringItem.php (100%) rename src/{pocketmine => }/item/Sword.php (100%) rename src/{pocketmine => }/item/TieredTool.php (100%) rename src/{pocketmine => }/item/Tool.php (100%) rename src/{pocketmine => }/item/ToolTier.php (100%) rename src/{pocketmine => }/item/Totem.php (100%) rename src/{pocketmine => }/item/VanillaItems.php (100%) rename src/{pocketmine => }/item/WheatSeeds.php (100%) rename src/{pocketmine => }/item/WritableBook.php (100%) rename src/{pocketmine => }/item/WritableBookBase.php (100%) rename src/{pocketmine => }/item/WritableBookPage.php (100%) rename src/{pocketmine => }/item/WrittenBook.php (100%) rename src/{pocketmine => }/item/enchantment/Enchantment.php (100%) rename src/{pocketmine => }/item/enchantment/EnchantmentEntry.php (100%) rename src/{pocketmine => }/item/enchantment/EnchantmentInstance.php (100%) rename src/{pocketmine => }/item/enchantment/EnchantmentList.php (100%) rename src/{pocketmine => }/item/enchantment/FireAspectEnchantment.php (100%) rename src/{pocketmine => }/item/enchantment/KnockbackEnchantment.php (100%) rename src/{pocketmine => }/item/enchantment/MeleeWeaponEnchantment.php (100%) rename src/{pocketmine => }/item/enchantment/ProtectionEnchantment.php (100%) rename src/{pocketmine => }/item/enchantment/SharpnessEnchantment.php (100%) rename src/{pocketmine => }/lang/Language.php (100%) rename src/{pocketmine => }/lang/LanguageNotFoundException.php (100%) rename src/{pocketmine => }/lang/TextContainer.php (100%) rename src/{pocketmine => }/lang/TranslationContainer.php (100%) rename src/{pocketmine => }/network/AdvancedNetworkInterface.php (100%) rename src/{pocketmine => }/network/BadPacketException.php (100%) rename src/{pocketmine => }/network/Network.php (100%) rename src/{pocketmine => }/network/NetworkInterface.php (100%) rename src/{pocketmine => }/network/NetworkSessionManager.php (100%) rename src/{pocketmine => }/network/RawPacketHandler.php (100%) rename src/{pocketmine => }/network/mcpe/ChunkCache.php (100%) rename src/{pocketmine => }/network/mcpe/ChunkRequestTask.php (100%) rename src/{pocketmine => }/network/mcpe/InventoryManager.php (100%) rename src/{pocketmine => }/network/mcpe/NetworkSession.php (100%) rename src/{pocketmine => }/network/mcpe/PacketBatch.php (100%) rename src/{pocketmine => }/network/mcpe/PacketSender.php (100%) rename src/{pocketmine => }/network/mcpe/README.md (100%) rename src/{pocketmine => }/network/mcpe/auth/ProcessLoginTask.php (100%) rename src/{pocketmine => }/network/mcpe/auth/VerifyLoginException.php (100%) rename src/{pocketmine => }/network/mcpe/compression/CompressBatchPromise.php (100%) rename src/{pocketmine => }/network/mcpe/compression/CompressBatchTask.php (100%) rename src/{pocketmine => }/network/mcpe/compression/Zlib.php (100%) rename src/{pocketmine => }/network/mcpe/encryption/NetworkCipher.php (100%) rename src/{pocketmine => }/network/mcpe/encryption/PrepareEncryptionTask.php (100%) rename src/{pocketmine => }/network/mcpe/handler/DeathPacketHandler.php (100%) rename src/{pocketmine => }/network/mcpe/handler/HandshakePacketHandler.php (100%) rename src/{pocketmine => }/network/mcpe/handler/InGamePacketHandler.php (100%) rename src/{pocketmine => }/network/mcpe/handler/LoginPacketHandler.php (100%) rename src/{pocketmine => }/network/mcpe/handler/NullPacketHandler.php (100%) rename src/{pocketmine => }/network/mcpe/handler/PacketHandler.php (100%) rename src/{pocketmine => }/network/mcpe/handler/PreSpawnPacketHandler.php (100%) rename src/{pocketmine => }/network/mcpe/handler/ResourcePacksPacketHandler.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ActorEventPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ActorFallPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ActorPickRequestPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/AddActorPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/AddBehaviorTreePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/AddEntityPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/AddItemActorPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/AddPaintingPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/AddPlayerPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/AdventureSettingsPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/AnimatePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/AutomationClientConnectPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/AvailableActorIdentifiersPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/AvailableCommandsPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/BiomeDefinitionListPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/BlockActorDataPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/BlockEventPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/BlockPickRequestPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/BookEditPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/BossEventPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/CameraPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ChangeDimensionPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ClientCacheBlobStatusPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ClientCacheMissResponsePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ClientCacheStatusPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ClientToServerHandshakePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ClientboundMapItemDataPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ClientboundPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/CommandBlockUpdatePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/CommandOutputPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/CommandRequestPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ContainerClosePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ContainerOpenPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ContainerSetDataPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/CraftingDataPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/CraftingEventPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/DataPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/DisconnectPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/EventPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ExplodePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/GameRulesChangedPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/GarbageServerboundPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/GuiDataPickItemPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/HurtArmorPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/InteractPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/InventoryContentPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/InventorySlotPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/InventoryTransactionPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ItemFrameDropItemPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/LabTablePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/LecternUpdatePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/LevelChunkPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/LevelEventGenericPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/LevelEventPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/LevelSoundEventPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/LevelSoundEventPacketV1.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/LevelSoundEventPacketV2.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/LoginPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/MapCreateLockedCopyPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/MapInfoRequestPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/MobArmorEquipmentPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/MobEffectPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/MobEquipmentPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ModalFormRequestPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ModalFormResponsePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/MoveActorAbsolutePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/MoveActorDeltaPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/MovePlayerPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/NetworkStackLatencyPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/NpcRequestPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/OnScreenTextureAnimationPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/Packet.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/PacketPool.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/PhotoTransferPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/PlaySoundPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/PlayStatusPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/PlayerActionPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/PlayerHotbarPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/PlayerInputPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/PlayerListPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/PlayerSkinPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ProtocolInfo.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/PurchaseReceiptPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/RemoveActorPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/RemoveEntityPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/RemoveObjectivePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/RequestChunkRadiusPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ResourcePackChunkDataPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ResourcePackChunkRequestPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ResourcePackClientResponsePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ResourcePackDataInfoPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ResourcePackStackPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ResourcePacksInfoPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/RespawnPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/RiderJumpPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ScriptCustomEventPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ServerSettingsRequestPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ServerSettingsResponsePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ServerToClientHandshakePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ServerboundPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/SetActorDataPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/SetActorLinkPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/SetActorMotionPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/SetCommandsEnabledPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/SetDefaultGameTypePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/SetDifficultyPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/SetDisplayObjectivePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/SetHealthPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/SetLastHurtByPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/SetPlayerGameTypePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/SetScorePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/SetScoreboardIdentityPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/SetSpawnPositionPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/SetTimePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/SetTitlePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ShowCreditsPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ShowProfilePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/ShowStoreOfferPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/SimpleEventPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/SpawnExperienceOrbPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/SpawnParticleEffectPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/StartGamePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/StopSoundPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/StructureBlockUpdatePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/StructureTemplateDataExportRequestPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/StructureTemplateDataExportResponsePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/SubClientLoginPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/TakeItemActorPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/TextPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/TransferPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/UnknownPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/UpdateAttributesPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/UpdateBlockPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/UpdateBlockPropertiesPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/UpdateBlockSyncedPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/UpdateEquipPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/UpdateSoftEnumPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/UpdateTradePacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/VideoStreamConnectPacket.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/ChunkCacheBlob.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/DimensionIds.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/MapTrackedObject.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/ParticleIds.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/PlayerListEntry.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/PlayerPermissions.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/ResourcePackType.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/RuntimeBlockMapping.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/ScorePacketEntry.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/ScoreboardIdentityPacketEntry.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/command/CommandData.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/command/CommandEnum.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/command/CommandOriginData.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/command/CommandOutputMessage.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/command/CommandParameter.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/entity/ByteMetadataProperty.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/entity/EntityLegacyIds.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/entity/EntityLink.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/entity/EntityMetadataCollection.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/entity/EntityMetadataFlags.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/entity/EntityMetadataProperties.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/entity/EntityMetadataTypes.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/entity/FloatMetadataProperty.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/entity/IntMetadataProperty.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/entity/ItemStackMetadataProperty.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/entity/LongMetadataProperty.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/entity/MetadataProperty.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/entity/PlayerMetadataFlags.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/entity/ShortMetadataProperty.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/entity/StringMetadataProperty.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/inventory/ContainerIds.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/inventory/MismatchTransactionData.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/inventory/NormalTransactionData.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/inventory/TransactionData.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/inventory/UseItemTransactionData.php (100%) rename src/{pocketmine => }/network/mcpe/protocol/types/inventory/WindowTypes.php (100%) rename src/{pocketmine => }/network/mcpe/raklib/RakLibInterface.php (100%) rename src/{pocketmine => }/network/mcpe/raklib/RakLibPacketSender.php (100%) rename src/{pocketmine => }/network/mcpe/serializer/ChunkSerializer.php (100%) rename src/{pocketmine => }/network/mcpe/serializer/NetworkBinaryStream.php (100%) rename src/{pocketmine => }/network/mcpe/serializer/NetworkNbtSerializer.php (100%) rename src/{pocketmine => }/network/query/QueryHandler.php (100%) rename src/{pocketmine => }/network/upnp/UPnP.php (100%) rename src/{pocketmine => }/permission/BanEntry.php (100%) rename src/{pocketmine => }/permission/BanList.php (100%) rename src/{pocketmine => }/permission/DefaultPermissions.php (100%) rename src/{pocketmine => }/permission/Permissible.php (100%) rename src/{pocketmine => }/permission/PermissibleBase.php (100%) rename src/{pocketmine => }/permission/PermissibleDelegateTrait.php (100%) rename src/{pocketmine => }/permission/Permission.php (100%) rename src/{pocketmine => }/permission/PermissionAttachment.php (100%) rename src/{pocketmine => }/permission/PermissionAttachmentInfo.php (100%) rename src/{pocketmine => }/permission/PermissionManager.php (100%) rename src/{pocketmine => }/permission/PermissionParser.php (100%) rename src/{pocketmine => }/permission/PermissionRemovedExecutor.php (100%) rename src/{pocketmine => }/permission/ServerOperator.php (100%) rename src/{pocketmine => }/player/GameMode.php (100%) rename src/{pocketmine => }/player/IPlayer.php (100%) rename src/{pocketmine => }/player/OfflinePlayer.php (100%) rename src/{pocketmine => }/player/Player.php (100%) rename src/{pocketmine => }/player/PlayerInfo.php (100%) rename src/{pocketmine => }/plugin/ApiVersion.php (100%) rename src/{pocketmine => }/plugin/DiskResourceProvider.php (100%) rename src/{pocketmine => }/plugin/PharPluginLoader.php (100%) rename src/{pocketmine => }/plugin/Plugin.php (100%) rename src/{pocketmine => }/plugin/PluginBase.php (100%) rename src/{pocketmine => }/plugin/PluginDescription.php (100%) rename src/{pocketmine => }/plugin/PluginException.php (100%) rename src/{pocketmine => }/plugin/PluginGraylist.php (100%) rename src/{pocketmine => }/plugin/PluginLoadOrder.php (100%) rename src/{pocketmine => }/plugin/PluginLoader.php (100%) rename src/{pocketmine => }/plugin/PluginLogger.php (100%) rename src/{pocketmine => }/plugin/PluginManager.php (100%) rename src/{pocketmine => }/plugin/ResourceProvider.php (100%) rename src/{pocketmine => }/plugin/ScriptPluginLoader.php (100%) rename src/{pocketmine => }/resourcepacks/ResourcePack.php (100%) rename src/{pocketmine => }/resourcepacks/ResourcePackException.php (100%) rename src/{pocketmine => }/resourcepacks/ResourcePackInfoEntry.php (100%) rename src/{pocketmine => }/resourcepacks/ResourcePackManager.php (100%) rename src/{pocketmine => }/resourcepacks/ZippedResourcePack.php (100%) rename src/{pocketmine => }/scheduler/AsyncPool.php (100%) rename src/{pocketmine => }/scheduler/AsyncTask.php (100%) rename src/{pocketmine => }/scheduler/AsyncWorker.php (100%) rename src/{pocketmine => }/scheduler/BulkCurlTask.php (100%) rename src/{pocketmine => }/scheduler/CancellableClosureTask.php (100%) rename src/{pocketmine => }/scheduler/ClosureTask.php (100%) rename src/{pocketmine => }/scheduler/DumpWorkerMemoryTask.php (100%) rename src/{pocketmine => }/scheduler/FileWriteTask.php (100%) rename src/{pocketmine => }/scheduler/GarbageCollectionTask.php (100%) rename src/{pocketmine => }/scheduler/SendUsageTask.php (100%) rename src/{pocketmine => }/scheduler/Task.php (100%) rename src/{pocketmine => }/scheduler/TaskHandler.php (100%) rename src/{pocketmine => }/scheduler/TaskScheduler.php (100%) rename src/{pocketmine => }/thread/CommonThreadPartsTrait.php (100%) rename src/{pocketmine => }/thread/Thread.php (100%) rename src/{pocketmine => }/thread/ThreadManager.php (100%) rename src/{pocketmine => }/thread/Worker.php (100%) rename src/{pocketmine => }/timings/Timings.php (100%) rename src/{pocketmine => }/timings/TimingsHandler.php (100%) rename src/{pocketmine => }/updater/AutoUpdater.php (100%) rename src/{pocketmine => }/updater/UpdateCheckTask.php (100%) rename src/{pocketmine => }/utils/Color.php (100%) rename src/{pocketmine => }/utils/Config.php (100%) rename src/{pocketmine => }/utils/EnumTrait.php (100%) rename src/{pocketmine => }/utils/Internet.php (100%) rename src/{pocketmine => }/utils/InternetException.php (100%) rename src/{pocketmine => }/utils/MainLogger.php (100%) rename src/{pocketmine => }/utils/Process.php (100%) rename src/{pocketmine => }/utils/Random.php (100%) rename src/{pocketmine => }/utils/RegistryTrait.php (100%) rename src/{pocketmine => }/utils/ReversePriorityQueue.php (100%) rename src/{pocketmine => }/utils/ServerException.php (100%) rename src/{pocketmine => }/utils/ServerKiller.php (100%) rename src/{pocketmine => }/utils/Terminal.php (100%) rename src/{pocketmine => }/utils/TextFormat.php (100%) rename src/{pocketmine => }/utils/Timezone.php (100%) rename src/{pocketmine => }/utils/UUID.php (100%) rename src/{pocketmine => }/utils/Utils.php (100%) rename src/{pocketmine => }/utils/VersionString.php (100%) rename src/{pocketmine => }/wizard/SetupWizard.php (100%) rename src/{pocketmine => }/world/BlockTransaction.php (100%) rename src/{pocketmine => }/world/ChunkListener.php (100%) rename src/{pocketmine => }/world/ChunkListenerNoOpTrait.php (100%) rename src/{pocketmine => }/world/ChunkLoader.php (100%) rename src/{pocketmine => }/world/ChunkManager.php (100%) rename src/{pocketmine => }/world/Explosion.php (100%) rename src/{pocketmine => }/world/Location.php (100%) rename src/{pocketmine => }/world/Position.php (100%) rename src/{pocketmine => }/world/SimpleChunkManager.php (100%) rename src/{pocketmine => }/world/World.php (100%) rename src/{pocketmine => }/world/WorldException.php (100%) rename src/{pocketmine => }/world/WorldManager.php (100%) rename src/{pocketmine => }/world/WorldTimings.php (100%) rename src/{pocketmine => }/world/biome/Biome.php (100%) rename src/{pocketmine => }/world/biome/DesertBiome.php (100%) rename src/{pocketmine => }/world/biome/ForestBiome.php (100%) rename src/{pocketmine => }/world/biome/GrassyBiome.php (100%) rename src/{pocketmine => }/world/biome/HellBiome.php (100%) rename src/{pocketmine => }/world/biome/IcePlainsBiome.php (100%) rename src/{pocketmine => }/world/biome/MountainsBiome.php (100%) rename src/{pocketmine => }/world/biome/OceanBiome.php (100%) rename src/{pocketmine => }/world/biome/PlainBiome.php (100%) rename src/{pocketmine => }/world/biome/RiverBiome.php (100%) rename src/{pocketmine => }/world/biome/SandyBiome.php (100%) rename src/{pocketmine => }/world/biome/SmallMountainsBiome.php (100%) rename src/{pocketmine => }/world/biome/SnowyBiome.php (100%) rename src/{pocketmine => }/world/biome/SwampBiome.php (100%) rename src/{pocketmine => }/world/biome/TaigaBiome.php (100%) rename src/{pocketmine => }/world/biome/UnknownBiome.php (100%) rename src/{pocketmine => }/world/format/Chunk.php (100%) rename src/{pocketmine => }/world/format/ChunkException.php (100%) rename src/{pocketmine => }/world/format/EmptySubChunk.php (100%) rename src/{pocketmine => }/world/format/LightArray.php (100%) rename src/{pocketmine => }/world/format/SubChunk.php (100%) rename src/{pocketmine => }/world/format/SubChunkInterface.php (100%) rename src/{pocketmine => }/world/format/io/BaseWorldProvider.php (100%) rename src/{pocketmine => }/world/format/io/ChunkUtils.php (100%) rename src/{pocketmine => }/world/format/io/FastChunkSerializer.php (100%) rename src/{pocketmine => }/world/format/io/FormatConverter.php (100%) rename src/{pocketmine => }/world/format/io/WorldData.php (100%) rename src/{pocketmine => }/world/format/io/WorldProvider.php (100%) rename src/{pocketmine => }/world/format/io/WorldProviderManager.php (100%) rename src/{pocketmine => }/world/format/io/WritableWorldProvider.php (100%) rename src/{pocketmine => }/world/format/io/data/BaseNbtWorldData.php (100%) rename src/{pocketmine => }/world/format/io/data/BedrockWorldData.php (100%) rename src/{pocketmine => }/world/format/io/data/JavaWorldData.php (100%) rename src/{pocketmine => }/world/format/io/exception/CorruptedChunkException.php (100%) rename src/{pocketmine => }/world/format/io/exception/CorruptedWorldException.php (100%) rename src/{pocketmine => }/world/format/io/exception/UnsupportedWorldFormatException.php (100%) rename src/{pocketmine => }/world/format/io/leveldb/LevelDB.php (100%) rename src/{pocketmine => }/world/format/io/region/Anvil.php (100%) rename src/{pocketmine => }/world/format/io/region/CorruptedRegionException.php (100%) rename src/{pocketmine => }/world/format/io/region/LegacyAnvilChunkTrait.php (100%) rename src/{pocketmine => }/world/format/io/region/McRegion.php (100%) rename src/{pocketmine => }/world/format/io/region/PMAnvil.php (100%) rename src/{pocketmine => }/world/format/io/region/RegionException.php (100%) rename src/{pocketmine => }/world/format/io/region/RegionLoader.php (100%) rename src/{pocketmine => }/world/format/io/region/RegionLocationTableEntry.php (100%) rename src/{pocketmine => }/world/format/io/region/RegionWorldProvider.php (100%) rename src/{pocketmine => }/world/generator/Flat.php (100%) rename src/{pocketmine => }/world/generator/Generator.php (100%) rename src/{pocketmine => }/world/generator/GeneratorChunkManager.php (100%) rename src/{pocketmine => }/world/generator/GeneratorManager.php (100%) rename src/{pocketmine => }/world/generator/GeneratorRegisterTask.php (100%) rename src/{pocketmine => }/world/generator/GeneratorUnregisterTask.php (100%) rename src/{pocketmine => }/world/generator/InvalidGeneratorOptionsException.php (100%) rename src/{pocketmine => }/world/generator/PopulationTask.php (100%) rename src/{pocketmine => }/world/generator/biome/BiomeSelector.php (100%) rename src/{pocketmine => }/world/generator/hell/Nether.php (100%) rename src/{pocketmine => }/world/generator/noise/Noise.php (100%) rename src/{pocketmine => }/world/generator/noise/Simplex.php (100%) rename src/{pocketmine => }/world/generator/normal/Normal.php (100%) rename src/{pocketmine => }/world/generator/object/BirchTree.php (100%) rename src/{pocketmine => }/world/generator/object/JungleTree.php (100%) rename src/{pocketmine => }/world/generator/object/OakTree.php (100%) rename src/{pocketmine => }/world/generator/object/Ore.php (100%) rename src/{pocketmine => }/world/generator/object/OreType.php (100%) rename src/{pocketmine => }/world/generator/object/SpruceTree.php (100%) rename src/{pocketmine => }/world/generator/object/TallGrass.php (100%) rename src/{pocketmine => }/world/generator/object/Tree.php (100%) rename src/{pocketmine => }/world/generator/populator/GroundCover.php (100%) rename src/{pocketmine => }/world/generator/populator/Ore.php (100%) rename src/{pocketmine => }/world/generator/populator/Populator.php (100%) rename src/{pocketmine => }/world/generator/populator/TallGrass.php (100%) rename src/{pocketmine => }/world/generator/populator/Tree.php (100%) rename src/{pocketmine => }/world/light/BlockLightUpdate.php (100%) rename src/{pocketmine => }/world/light/LightPopulationTask.php (100%) rename src/{pocketmine => }/world/light/LightUpdate.php (100%) rename src/{pocketmine => }/world/light/SkyLightUpdate.php (100%) rename src/{pocketmine => }/world/particle/AngryVillagerParticle.php (100%) rename src/{pocketmine => }/world/particle/BlockForceFieldParticle.php (100%) rename src/{pocketmine => }/world/particle/BubbleParticle.php (100%) rename src/{pocketmine => }/world/particle/CriticalParticle.php (100%) rename src/{pocketmine => }/world/particle/DestroyBlockParticle.php (100%) rename src/{pocketmine => }/world/particle/DragonEggTeleportParticle.php (100%) rename src/{pocketmine => }/world/particle/DustParticle.php (100%) rename src/{pocketmine => }/world/particle/EnchantParticle.php (100%) rename src/{pocketmine => }/world/particle/EnchantmentTableParticle.php (100%) rename src/{pocketmine => }/world/particle/EndermanTeleportParticle.php (100%) rename src/{pocketmine => }/world/particle/EntityFlameParticle.php (100%) rename src/{pocketmine => }/world/particle/ExplodeParticle.php (100%) rename src/{pocketmine => }/world/particle/FlameParticle.php (100%) rename src/{pocketmine => }/world/particle/FloatingTextParticle.php (100%) rename src/{pocketmine => }/world/particle/GenericParticle.php (100%) rename src/{pocketmine => }/world/particle/HappyVillagerParticle.php (100%) rename src/{pocketmine => }/world/particle/HeartParticle.php (100%) rename src/{pocketmine => }/world/particle/HugeExplodeParticle.php (100%) rename src/{pocketmine => }/world/particle/HugeExplodeSeedParticle.php (100%) rename src/{pocketmine => }/world/particle/InkParticle.php (100%) rename src/{pocketmine => }/world/particle/InstantEnchantParticle.php (100%) rename src/{pocketmine => }/world/particle/ItemBreakParticle.php (100%) rename src/{pocketmine => }/world/particle/LavaDripParticle.php (100%) rename src/{pocketmine => }/world/particle/LavaParticle.php (100%) rename src/{pocketmine => }/world/particle/MobSpawnParticle.php (100%) rename src/{pocketmine => }/world/particle/Particle.php (100%) rename src/{pocketmine => }/world/particle/PortalParticle.php (100%) rename src/{pocketmine => }/world/particle/PotionSplashParticle.php (100%) rename src/{pocketmine => }/world/particle/PunchBlockParticle.php (100%) rename src/{pocketmine => }/world/particle/RainSplashParticle.php (100%) rename src/{pocketmine => }/world/particle/RedstoneParticle.php (100%) rename src/{pocketmine => }/world/particle/SmokeParticle.php (100%) rename src/{pocketmine => }/world/particle/SnowballPoofParticle.php (100%) rename src/{pocketmine => }/world/particle/SplashParticle.php (100%) rename src/{pocketmine => }/world/particle/SporeParticle.php (100%) rename src/{pocketmine => }/world/particle/TerrainParticle.php (100%) rename src/{pocketmine => }/world/particle/WaterDripParticle.php (100%) rename src/{pocketmine => }/world/particle/WaterParticle.php (100%) rename src/{pocketmine => }/world/sound/AnvilBreakSound.php (100%) rename src/{pocketmine => }/world/sound/AnvilFallSound.php (100%) rename src/{pocketmine => }/world/sound/AnvilUseSound.php (100%) rename src/{pocketmine => }/world/sound/ArrowHitSound.php (100%) rename src/{pocketmine => }/world/sound/BlazeShootSound.php (100%) rename src/{pocketmine => }/world/sound/BlockBreakSound.php (100%) rename src/{pocketmine => }/world/sound/BlockPlaceSound.php (100%) rename src/{pocketmine => }/world/sound/BowShootSound.php (100%) rename src/{pocketmine => }/world/sound/BucketEmptyLavaSound.php (100%) rename src/{pocketmine => }/world/sound/BucketEmptyWaterSound.php (100%) rename src/{pocketmine => }/world/sound/BucketFillLavaSound.php (100%) rename src/{pocketmine => }/world/sound/BucketFillWaterSound.php (100%) rename src/{pocketmine => }/world/sound/ChestCloseSound.php (100%) rename src/{pocketmine => }/world/sound/ChestOpenSound.php (100%) rename src/{pocketmine => }/world/sound/ClickSound.php (100%) rename src/{pocketmine => }/world/sound/DoorBumpSound.php (100%) rename src/{pocketmine => }/world/sound/DoorCrashSound.php (100%) rename src/{pocketmine => }/world/sound/DoorSound.php (100%) rename src/{pocketmine => }/world/sound/EnderChestCloseSound.php (100%) rename src/{pocketmine => }/world/sound/EnderChestOpenSound.php (100%) rename src/{pocketmine => }/world/sound/EndermanTeleportSound.php (100%) rename src/{pocketmine => }/world/sound/ExplodeSound.php (100%) rename src/{pocketmine => }/world/sound/FizzSound.php (100%) rename src/{pocketmine => }/world/sound/FlintSteelSound.php (100%) rename src/{pocketmine => }/world/sound/GhastShootSound.php (100%) rename src/{pocketmine => }/world/sound/GhastSound.php (100%) rename src/{pocketmine => }/world/sound/IgniteSound.php (100%) rename src/{pocketmine => }/world/sound/ItemBreakSound.php (100%) rename src/{pocketmine => }/world/sound/LaunchSound.php (100%) rename src/{pocketmine => }/world/sound/LevelEventSound.php (100%) rename src/{pocketmine => }/world/sound/NoteInstrument.php (100%) rename src/{pocketmine => }/world/sound/NoteSound.php (100%) rename src/{pocketmine => }/world/sound/PaintingPlaceSound.php (100%) rename src/{pocketmine => }/world/sound/PopSound.php (100%) rename src/{pocketmine => }/world/sound/PotionSplashSound.php (100%) rename src/{pocketmine => }/world/sound/RedstonePowerOffSound.php (100%) rename src/{pocketmine => }/world/sound/RedstonePowerOnSound.php (100%) rename src/{pocketmine => }/world/sound/Sound.php (100%) rename src/{pocketmine => }/world/sound/ThrowSound.php (100%) rename src/{pocketmine => }/world/sound/TotemUseSound.php (100%) rename src/{pocketmine => }/world/sound/XpCollectSound.php (100%) rename src/{pocketmine => }/world/sound/XpLevelUpSound.php (100%) rename src/{pocketmine => }/world/utils/SubChunkIteratorManager.php (100%) diff --git a/composer.json b/composer.json index a70304af53..d6820458cc 100644 --- a/composer.json +++ b/composer.json @@ -42,7 +42,7 @@ }, "autoload": { "psr-4": { - "": ["src"] + "pocketmine\\": "src/" } }, "autoload-dev": { diff --git a/src/pocketmine/CrashDump.php b/src/CrashDump.php similarity index 100% rename from src/pocketmine/CrashDump.php rename to src/CrashDump.php diff --git a/src/pocketmine/MemoryManager.php b/src/MemoryManager.php similarity index 100% rename from src/pocketmine/MemoryManager.php rename to src/MemoryManager.php diff --git a/src/pocketmine/PocketMine.php b/src/PocketMine.php similarity index 99% rename from src/pocketmine/PocketMine.php rename to src/PocketMine.php index 42219905ea..6f38f9ec93 100644 --- a/src/pocketmine/PocketMine.php +++ b/src/PocketMine.php @@ -146,7 +146,7 @@ namespace pocketmine { if(\Phar::running(true) !== ""){ define('pocketmine\PATH', \Phar::running(true) . "/"); }else{ - define('pocketmine\PATH', dirname(__FILE__, 3) . DIRECTORY_SEPARATOR); + define('pocketmine\PATH', dirname(__FILE__, 2) . DIRECTORY_SEPARATOR); } $opts = getopt("", ["bootstrap:"]); diff --git a/src/pocketmine/Server.php b/src/Server.php similarity index 100% rename from src/pocketmine/Server.php rename to src/Server.php diff --git a/src/pocketmine/VersionInfo.php b/src/VersionInfo.php similarity index 100% rename from src/pocketmine/VersionInfo.php rename to src/VersionInfo.php diff --git a/src/pocketmine/block/ActivatorRail.php b/src/block/ActivatorRail.php similarity index 100% rename from src/pocketmine/block/ActivatorRail.php rename to src/block/ActivatorRail.php diff --git a/src/pocketmine/block/Air.php b/src/block/Air.php similarity index 100% rename from src/pocketmine/block/Air.php rename to src/block/Air.php diff --git a/src/pocketmine/block/Anvil.php b/src/block/Anvil.php similarity index 100% rename from src/pocketmine/block/Anvil.php rename to src/block/Anvil.php diff --git a/src/pocketmine/block/Banner.php b/src/block/Banner.php similarity index 100% rename from src/pocketmine/block/Banner.php rename to src/block/Banner.php diff --git a/src/pocketmine/block/BaseRail.php b/src/block/BaseRail.php similarity index 100% rename from src/pocketmine/block/BaseRail.php rename to src/block/BaseRail.php diff --git a/src/pocketmine/block/Bed.php b/src/block/Bed.php similarity index 100% rename from src/pocketmine/block/Bed.php rename to src/block/Bed.php diff --git a/src/pocketmine/block/Bedrock.php b/src/block/Bedrock.php similarity index 100% rename from src/pocketmine/block/Bedrock.php rename to src/block/Bedrock.php diff --git a/src/pocketmine/block/Beetroot.php b/src/block/Beetroot.php similarity index 100% rename from src/pocketmine/block/Beetroot.php rename to src/block/Beetroot.php diff --git a/src/pocketmine/block/Block.php b/src/block/Block.php similarity index 100% rename from src/pocketmine/block/Block.php rename to src/block/Block.php diff --git a/src/pocketmine/block/BlockBreakInfo.php b/src/block/BlockBreakInfo.php similarity index 100% rename from src/pocketmine/block/BlockBreakInfo.php rename to src/block/BlockBreakInfo.php diff --git a/src/pocketmine/block/BlockFactory.php b/src/block/BlockFactory.php similarity index 100% rename from src/pocketmine/block/BlockFactory.php rename to src/block/BlockFactory.php diff --git a/src/pocketmine/block/BlockIdentifier.php b/src/block/BlockIdentifier.php similarity index 100% rename from src/pocketmine/block/BlockIdentifier.php rename to src/block/BlockIdentifier.php diff --git a/src/pocketmine/block/BlockIdentifierFlattened.php b/src/block/BlockIdentifierFlattened.php similarity index 100% rename from src/pocketmine/block/BlockIdentifierFlattened.php rename to src/block/BlockIdentifierFlattened.php diff --git a/src/pocketmine/block/BlockLegacyIds.php b/src/block/BlockLegacyIds.php similarity index 100% rename from src/pocketmine/block/BlockLegacyIds.php rename to src/block/BlockLegacyIds.php diff --git a/src/pocketmine/block/BlockLegacyMetadata.php b/src/block/BlockLegacyMetadata.php similarity index 100% rename from src/pocketmine/block/BlockLegacyMetadata.php rename to src/block/BlockLegacyMetadata.php diff --git a/src/pocketmine/block/BlockToolType.php b/src/block/BlockToolType.php similarity index 100% rename from src/pocketmine/block/BlockToolType.php rename to src/block/BlockToolType.php diff --git a/src/pocketmine/block/BlueIce.php b/src/block/BlueIce.php similarity index 100% rename from src/pocketmine/block/BlueIce.php rename to src/block/BlueIce.php diff --git a/src/pocketmine/block/BoneBlock.php b/src/block/BoneBlock.php similarity index 100% rename from src/pocketmine/block/BoneBlock.php rename to src/block/BoneBlock.php diff --git a/src/pocketmine/block/Bookshelf.php b/src/block/Bookshelf.php similarity index 100% rename from src/pocketmine/block/Bookshelf.php rename to src/block/Bookshelf.php diff --git a/src/pocketmine/block/BrewingStand.php b/src/block/BrewingStand.php similarity index 100% rename from src/pocketmine/block/BrewingStand.php rename to src/block/BrewingStand.php diff --git a/src/pocketmine/block/BrownMushroom.php b/src/block/BrownMushroom.php similarity index 100% rename from src/pocketmine/block/BrownMushroom.php rename to src/block/BrownMushroom.php diff --git a/src/pocketmine/block/BrownMushroomBlock.php b/src/block/BrownMushroomBlock.php similarity index 100% rename from src/pocketmine/block/BrownMushroomBlock.php rename to src/block/BrownMushroomBlock.php diff --git a/src/pocketmine/block/Button.php b/src/block/Button.php similarity index 100% rename from src/pocketmine/block/Button.php rename to src/block/Button.php diff --git a/src/pocketmine/block/Cactus.php b/src/block/Cactus.php similarity index 100% rename from src/pocketmine/block/Cactus.php rename to src/block/Cactus.php diff --git a/src/pocketmine/block/Cake.php b/src/block/Cake.php similarity index 100% rename from src/pocketmine/block/Cake.php rename to src/block/Cake.php diff --git a/src/pocketmine/block/Carpet.php b/src/block/Carpet.php similarity index 100% rename from src/pocketmine/block/Carpet.php rename to src/block/Carpet.php diff --git a/src/pocketmine/block/Carrot.php b/src/block/Carrot.php similarity index 100% rename from src/pocketmine/block/Carrot.php rename to src/block/Carrot.php diff --git a/src/pocketmine/block/CarvedPumpkin.php b/src/block/CarvedPumpkin.php similarity index 100% rename from src/pocketmine/block/CarvedPumpkin.php rename to src/block/CarvedPumpkin.php diff --git a/src/pocketmine/block/Chest.php b/src/block/Chest.php similarity index 100% rename from src/pocketmine/block/Chest.php rename to src/block/Chest.php diff --git a/src/pocketmine/block/Clay.php b/src/block/Clay.php similarity index 100% rename from src/pocketmine/block/Clay.php rename to src/block/Clay.php diff --git a/src/pocketmine/block/Coal.php b/src/block/Coal.php similarity index 100% rename from src/pocketmine/block/Coal.php rename to src/block/Coal.php diff --git a/src/pocketmine/block/CoalOre.php b/src/block/CoalOre.php similarity index 100% rename from src/pocketmine/block/CoalOre.php rename to src/block/CoalOre.php diff --git a/src/pocketmine/block/CoarseDirt.php b/src/block/CoarseDirt.php similarity index 100% rename from src/pocketmine/block/CoarseDirt.php rename to src/block/CoarseDirt.php diff --git a/src/pocketmine/block/Cobweb.php b/src/block/Cobweb.php similarity index 100% rename from src/pocketmine/block/Cobweb.php rename to src/block/Cobweb.php diff --git a/src/pocketmine/block/CocoaBlock.php b/src/block/CocoaBlock.php similarity index 100% rename from src/pocketmine/block/CocoaBlock.php rename to src/block/CocoaBlock.php diff --git a/src/pocketmine/block/Concrete.php b/src/block/Concrete.php similarity index 100% rename from src/pocketmine/block/Concrete.php rename to src/block/Concrete.php diff --git a/src/pocketmine/block/ConcretePowder.php b/src/block/ConcretePowder.php similarity index 100% rename from src/pocketmine/block/ConcretePowder.php rename to src/block/ConcretePowder.php diff --git a/src/pocketmine/block/CraftingTable.php b/src/block/CraftingTable.php similarity index 100% rename from src/pocketmine/block/CraftingTable.php rename to src/block/CraftingTable.php diff --git a/src/pocketmine/block/Crops.php b/src/block/Crops.php similarity index 100% rename from src/pocketmine/block/Crops.php rename to src/block/Crops.php diff --git a/src/pocketmine/block/DaylightSensor.php b/src/block/DaylightSensor.php similarity index 100% rename from src/pocketmine/block/DaylightSensor.php rename to src/block/DaylightSensor.php diff --git a/src/pocketmine/block/DeadBush.php b/src/block/DeadBush.php similarity index 100% rename from src/pocketmine/block/DeadBush.php rename to src/block/DeadBush.php diff --git a/src/pocketmine/block/DetectorRail.php b/src/block/DetectorRail.php similarity index 100% rename from src/pocketmine/block/DetectorRail.php rename to src/block/DetectorRail.php diff --git a/src/pocketmine/block/DiamondOre.php b/src/block/DiamondOre.php similarity index 100% rename from src/pocketmine/block/DiamondOre.php rename to src/block/DiamondOre.php diff --git a/src/pocketmine/block/Dirt.php b/src/block/Dirt.php similarity index 100% rename from src/pocketmine/block/Dirt.php rename to src/block/Dirt.php diff --git a/src/pocketmine/block/Door.php b/src/block/Door.php similarity index 100% rename from src/pocketmine/block/Door.php rename to src/block/Door.php diff --git a/src/pocketmine/block/DoublePlant.php b/src/block/DoublePlant.php similarity index 100% rename from src/pocketmine/block/DoublePlant.php rename to src/block/DoublePlant.php diff --git a/src/pocketmine/block/DoubleTallGrass.php b/src/block/DoubleTallGrass.php similarity index 100% rename from src/pocketmine/block/DoubleTallGrass.php rename to src/block/DoubleTallGrass.php diff --git a/src/pocketmine/block/DragonEgg.php b/src/block/DragonEgg.php similarity index 100% rename from src/pocketmine/block/DragonEgg.php rename to src/block/DragonEgg.php diff --git a/src/pocketmine/block/DriedKelp.php b/src/block/DriedKelp.php similarity index 100% rename from src/pocketmine/block/DriedKelp.php rename to src/block/DriedKelp.php diff --git a/src/pocketmine/block/Element.php b/src/block/Element.php similarity index 100% rename from src/pocketmine/block/Element.php rename to src/block/Element.php diff --git a/src/pocketmine/block/EmeraldOre.php b/src/block/EmeraldOre.php similarity index 100% rename from src/pocketmine/block/EmeraldOre.php rename to src/block/EmeraldOre.php diff --git a/src/pocketmine/block/EnchantingTable.php b/src/block/EnchantingTable.php similarity index 100% rename from src/pocketmine/block/EnchantingTable.php rename to src/block/EnchantingTable.php diff --git a/src/pocketmine/block/EndPortalFrame.php b/src/block/EndPortalFrame.php similarity index 100% rename from src/pocketmine/block/EndPortalFrame.php rename to src/block/EndPortalFrame.php diff --git a/src/pocketmine/block/EndRod.php b/src/block/EndRod.php similarity index 100% rename from src/pocketmine/block/EndRod.php rename to src/block/EndRod.php diff --git a/src/pocketmine/block/EnderChest.php b/src/block/EnderChest.php similarity index 100% rename from src/pocketmine/block/EnderChest.php rename to src/block/EnderChest.php diff --git a/src/pocketmine/block/Farmland.php b/src/block/Farmland.php similarity index 100% rename from src/pocketmine/block/Farmland.php rename to src/block/Farmland.php diff --git a/src/pocketmine/block/Fence.php b/src/block/Fence.php similarity index 100% rename from src/pocketmine/block/Fence.php rename to src/block/Fence.php diff --git a/src/pocketmine/block/FenceGate.php b/src/block/FenceGate.php similarity index 100% rename from src/pocketmine/block/FenceGate.php rename to src/block/FenceGate.php diff --git a/src/pocketmine/block/Fire.php b/src/block/Fire.php similarity index 100% rename from src/pocketmine/block/Fire.php rename to src/block/Fire.php diff --git a/src/pocketmine/block/Flowable.php b/src/block/Flowable.php similarity index 100% rename from src/pocketmine/block/Flowable.php rename to src/block/Flowable.php diff --git a/src/pocketmine/block/Flower.php b/src/block/Flower.php similarity index 100% rename from src/pocketmine/block/Flower.php rename to src/block/Flower.php diff --git a/src/pocketmine/block/FlowerPot.php b/src/block/FlowerPot.php similarity index 100% rename from src/pocketmine/block/FlowerPot.php rename to src/block/FlowerPot.php diff --git a/src/pocketmine/block/FrostedIce.php b/src/block/FrostedIce.php similarity index 100% rename from src/pocketmine/block/FrostedIce.php rename to src/block/FrostedIce.php diff --git a/src/pocketmine/block/Furnace.php b/src/block/Furnace.php similarity index 100% rename from src/pocketmine/block/Furnace.php rename to src/block/Furnace.php diff --git a/src/pocketmine/block/Glass.php b/src/block/Glass.php similarity index 100% rename from src/pocketmine/block/Glass.php rename to src/block/Glass.php diff --git a/src/pocketmine/block/GlassPane.php b/src/block/GlassPane.php similarity index 100% rename from src/pocketmine/block/GlassPane.php rename to src/block/GlassPane.php diff --git a/src/pocketmine/block/GlazedTerracotta.php b/src/block/GlazedTerracotta.php similarity index 100% rename from src/pocketmine/block/GlazedTerracotta.php rename to src/block/GlazedTerracotta.php diff --git a/src/pocketmine/block/GlowingObsidian.php b/src/block/GlowingObsidian.php similarity index 100% rename from src/pocketmine/block/GlowingObsidian.php rename to src/block/GlowingObsidian.php diff --git a/src/pocketmine/block/Glowstone.php b/src/block/Glowstone.php similarity index 100% rename from src/pocketmine/block/Glowstone.php rename to src/block/Glowstone.php diff --git a/src/pocketmine/block/Grass.php b/src/block/Grass.php similarity index 100% rename from src/pocketmine/block/Grass.php rename to src/block/Grass.php diff --git a/src/pocketmine/block/GrassPath.php b/src/block/GrassPath.php similarity index 100% rename from src/pocketmine/block/GrassPath.php rename to src/block/GrassPath.php diff --git a/src/pocketmine/block/Gravel.php b/src/block/Gravel.php similarity index 100% rename from src/pocketmine/block/Gravel.php rename to src/block/Gravel.php diff --git a/src/pocketmine/block/HardenedClay.php b/src/block/HardenedClay.php similarity index 100% rename from src/pocketmine/block/HardenedClay.php rename to src/block/HardenedClay.php diff --git a/src/pocketmine/block/HardenedGlass.php b/src/block/HardenedGlass.php similarity index 100% rename from src/pocketmine/block/HardenedGlass.php rename to src/block/HardenedGlass.php diff --git a/src/pocketmine/block/HardenedGlassPane.php b/src/block/HardenedGlassPane.php similarity index 100% rename from src/pocketmine/block/HardenedGlassPane.php rename to src/block/HardenedGlassPane.php diff --git a/src/pocketmine/block/HayBale.php b/src/block/HayBale.php similarity index 100% rename from src/pocketmine/block/HayBale.php rename to src/block/HayBale.php diff --git a/src/pocketmine/block/Hopper.php b/src/block/Hopper.php similarity index 100% rename from src/pocketmine/block/Hopper.php rename to src/block/Hopper.php diff --git a/src/pocketmine/block/Ice.php b/src/block/Ice.php similarity index 100% rename from src/pocketmine/block/Ice.php rename to src/block/Ice.php diff --git a/src/pocketmine/block/InfestedStone.php b/src/block/InfestedStone.php similarity index 100% rename from src/pocketmine/block/InfestedStone.php rename to src/block/InfestedStone.php diff --git a/src/pocketmine/block/ItemFrame.php b/src/block/ItemFrame.php similarity index 100% rename from src/pocketmine/block/ItemFrame.php rename to src/block/ItemFrame.php diff --git a/src/pocketmine/block/Ladder.php b/src/block/Ladder.php similarity index 100% rename from src/pocketmine/block/Ladder.php rename to src/block/Ladder.php diff --git a/src/pocketmine/block/Lantern.php b/src/block/Lantern.php similarity index 100% rename from src/pocketmine/block/Lantern.php rename to src/block/Lantern.php diff --git a/src/pocketmine/block/LapisOre.php b/src/block/LapisOre.php similarity index 100% rename from src/pocketmine/block/LapisOre.php rename to src/block/LapisOre.php diff --git a/src/pocketmine/block/Lava.php b/src/block/Lava.php similarity index 100% rename from src/pocketmine/block/Lava.php rename to src/block/Lava.php diff --git a/src/pocketmine/block/Leaves.php b/src/block/Leaves.php similarity index 100% rename from src/pocketmine/block/Leaves.php rename to src/block/Leaves.php diff --git a/src/pocketmine/block/Lever.php b/src/block/Lever.php similarity index 100% rename from src/pocketmine/block/Lever.php rename to src/block/Lever.php diff --git a/src/pocketmine/block/Liquid.php b/src/block/Liquid.php similarity index 100% rename from src/pocketmine/block/Liquid.php rename to src/block/Liquid.php diff --git a/src/pocketmine/block/LitPumpkin.php b/src/block/LitPumpkin.php similarity index 100% rename from src/pocketmine/block/LitPumpkin.php rename to src/block/LitPumpkin.php diff --git a/src/pocketmine/block/Log.php b/src/block/Log.php similarity index 100% rename from src/pocketmine/block/Log.php rename to src/block/Log.php diff --git a/src/pocketmine/block/Magma.php b/src/block/Magma.php similarity index 100% rename from src/pocketmine/block/Magma.php rename to src/block/Magma.php diff --git a/src/pocketmine/block/Melon.php b/src/block/Melon.php similarity index 100% rename from src/pocketmine/block/Melon.php rename to src/block/Melon.php diff --git a/src/pocketmine/block/MelonStem.php b/src/block/MelonStem.php similarity index 100% rename from src/pocketmine/block/MelonStem.php rename to src/block/MelonStem.php diff --git a/src/pocketmine/block/MonsterSpawner.php b/src/block/MonsterSpawner.php similarity index 100% rename from src/pocketmine/block/MonsterSpawner.php rename to src/block/MonsterSpawner.php diff --git a/src/pocketmine/block/Mycelium.php b/src/block/Mycelium.php similarity index 100% rename from src/pocketmine/block/Mycelium.php rename to src/block/Mycelium.php diff --git a/src/pocketmine/block/NetherPortal.php b/src/block/NetherPortal.php similarity index 100% rename from src/pocketmine/block/NetherPortal.php rename to src/block/NetherPortal.php diff --git a/src/pocketmine/block/NetherQuartzOre.php b/src/block/NetherQuartzOre.php similarity index 100% rename from src/pocketmine/block/NetherQuartzOre.php rename to src/block/NetherQuartzOre.php diff --git a/src/pocketmine/block/NetherReactor.php b/src/block/NetherReactor.php similarity index 100% rename from src/pocketmine/block/NetherReactor.php rename to src/block/NetherReactor.php diff --git a/src/pocketmine/block/NetherWartPlant.php b/src/block/NetherWartPlant.php similarity index 100% rename from src/pocketmine/block/NetherWartPlant.php rename to src/block/NetherWartPlant.php diff --git a/src/pocketmine/block/Netherrack.php b/src/block/Netherrack.php similarity index 100% rename from src/pocketmine/block/Netherrack.php rename to src/block/Netherrack.php diff --git a/src/pocketmine/block/Note.php b/src/block/Note.php similarity index 100% rename from src/pocketmine/block/Note.php rename to src/block/Note.php diff --git a/src/pocketmine/block/Opaque.php b/src/block/Opaque.php similarity index 100% rename from src/pocketmine/block/Opaque.php rename to src/block/Opaque.php diff --git a/src/pocketmine/block/PackedIce.php b/src/block/PackedIce.php similarity index 100% rename from src/pocketmine/block/PackedIce.php rename to src/block/PackedIce.php diff --git a/src/pocketmine/block/Planks.php b/src/block/Planks.php similarity index 100% rename from src/pocketmine/block/Planks.php rename to src/block/Planks.php diff --git a/src/pocketmine/block/Podzol.php b/src/block/Podzol.php similarity index 100% rename from src/pocketmine/block/Podzol.php rename to src/block/Podzol.php diff --git a/src/pocketmine/block/Potato.php b/src/block/Potato.php similarity index 100% rename from src/pocketmine/block/Potato.php rename to src/block/Potato.php diff --git a/src/pocketmine/block/PoweredRail.php b/src/block/PoweredRail.php similarity index 100% rename from src/pocketmine/block/PoweredRail.php rename to src/block/PoweredRail.php diff --git a/src/pocketmine/block/PressurePlate.php b/src/block/PressurePlate.php similarity index 100% rename from src/pocketmine/block/PressurePlate.php rename to src/block/PressurePlate.php diff --git a/src/pocketmine/block/PumpkinStem.php b/src/block/PumpkinStem.php similarity index 100% rename from src/pocketmine/block/PumpkinStem.php rename to src/block/PumpkinStem.php diff --git a/src/pocketmine/block/Rail.php b/src/block/Rail.php similarity index 100% rename from src/pocketmine/block/Rail.php rename to src/block/Rail.php diff --git a/src/pocketmine/block/RedMushroom.php b/src/block/RedMushroom.php similarity index 100% rename from src/pocketmine/block/RedMushroom.php rename to src/block/RedMushroom.php diff --git a/src/pocketmine/block/RedMushroomBlock.php b/src/block/RedMushroomBlock.php similarity index 100% rename from src/pocketmine/block/RedMushroomBlock.php rename to src/block/RedMushroomBlock.php diff --git a/src/pocketmine/block/Redstone.php b/src/block/Redstone.php similarity index 100% rename from src/pocketmine/block/Redstone.php rename to src/block/Redstone.php diff --git a/src/pocketmine/block/RedstoneComparator.php b/src/block/RedstoneComparator.php similarity index 100% rename from src/pocketmine/block/RedstoneComparator.php rename to src/block/RedstoneComparator.php diff --git a/src/pocketmine/block/RedstoneLamp.php b/src/block/RedstoneLamp.php similarity index 100% rename from src/pocketmine/block/RedstoneLamp.php rename to src/block/RedstoneLamp.php diff --git a/src/pocketmine/block/RedstoneOre.php b/src/block/RedstoneOre.php similarity index 100% rename from src/pocketmine/block/RedstoneOre.php rename to src/block/RedstoneOre.php diff --git a/src/pocketmine/block/RedstoneRail.php b/src/block/RedstoneRail.php similarity index 100% rename from src/pocketmine/block/RedstoneRail.php rename to src/block/RedstoneRail.php diff --git a/src/pocketmine/block/RedstoneRepeater.php b/src/block/RedstoneRepeater.php similarity index 100% rename from src/pocketmine/block/RedstoneRepeater.php rename to src/block/RedstoneRepeater.php diff --git a/src/pocketmine/block/RedstoneTorch.php b/src/block/RedstoneTorch.php similarity index 100% rename from src/pocketmine/block/RedstoneTorch.php rename to src/block/RedstoneTorch.php diff --git a/src/pocketmine/block/RedstoneWire.php b/src/block/RedstoneWire.php similarity index 100% rename from src/pocketmine/block/RedstoneWire.php rename to src/block/RedstoneWire.php diff --git a/src/pocketmine/block/Reserved6.php b/src/block/Reserved6.php similarity index 100% rename from src/pocketmine/block/Reserved6.php rename to src/block/Reserved6.php diff --git a/src/pocketmine/block/Sand.php b/src/block/Sand.php similarity index 100% rename from src/pocketmine/block/Sand.php rename to src/block/Sand.php diff --git a/src/pocketmine/block/Sapling.php b/src/block/Sapling.php similarity index 100% rename from src/pocketmine/block/Sapling.php rename to src/block/Sapling.php diff --git a/src/pocketmine/block/SeaLantern.php b/src/block/SeaLantern.php similarity index 100% rename from src/pocketmine/block/SeaLantern.php rename to src/block/SeaLantern.php diff --git a/src/pocketmine/block/SeaPickle.php b/src/block/SeaPickle.php similarity index 100% rename from src/pocketmine/block/SeaPickle.php rename to src/block/SeaPickle.php diff --git a/src/pocketmine/block/Sign.php b/src/block/Sign.php similarity index 100% rename from src/pocketmine/block/Sign.php rename to src/block/Sign.php diff --git a/src/pocketmine/block/SimplePressurePlate.php b/src/block/SimplePressurePlate.php similarity index 100% rename from src/pocketmine/block/SimplePressurePlate.php rename to src/block/SimplePressurePlate.php diff --git a/src/pocketmine/block/Skull.php b/src/block/Skull.php similarity index 100% rename from src/pocketmine/block/Skull.php rename to src/block/Skull.php diff --git a/src/pocketmine/block/Slab.php b/src/block/Slab.php similarity index 100% rename from src/pocketmine/block/Slab.php rename to src/block/Slab.php diff --git a/src/pocketmine/block/Snow.php b/src/block/Snow.php similarity index 100% rename from src/pocketmine/block/Snow.php rename to src/block/Snow.php diff --git a/src/pocketmine/block/SnowLayer.php b/src/block/SnowLayer.php similarity index 100% rename from src/pocketmine/block/SnowLayer.php rename to src/block/SnowLayer.php diff --git a/src/pocketmine/block/SoulSand.php b/src/block/SoulSand.php similarity index 100% rename from src/pocketmine/block/SoulSand.php rename to src/block/SoulSand.php diff --git a/src/pocketmine/block/Sponge.php b/src/block/Sponge.php similarity index 100% rename from src/pocketmine/block/Sponge.php rename to src/block/Sponge.php diff --git a/src/pocketmine/block/Stair.php b/src/block/Stair.php similarity index 100% rename from src/pocketmine/block/Stair.php rename to src/block/Stair.php diff --git a/src/pocketmine/block/Stem.php b/src/block/Stem.php similarity index 100% rename from src/pocketmine/block/Stem.php rename to src/block/Stem.php diff --git a/src/pocketmine/block/StoneButton.php b/src/block/StoneButton.php similarity index 100% rename from src/pocketmine/block/StoneButton.php rename to src/block/StoneButton.php diff --git a/src/pocketmine/block/StonePressurePlate.php b/src/block/StonePressurePlate.php similarity index 100% rename from src/pocketmine/block/StonePressurePlate.php rename to src/block/StonePressurePlate.php diff --git a/src/pocketmine/block/Sugarcane.php b/src/block/Sugarcane.php similarity index 100% rename from src/pocketmine/block/Sugarcane.php rename to src/block/Sugarcane.php diff --git a/src/pocketmine/block/TNT.php b/src/block/TNT.php similarity index 100% rename from src/pocketmine/block/TNT.php rename to src/block/TNT.php diff --git a/src/pocketmine/block/TallGrass.php b/src/block/TallGrass.php similarity index 100% rename from src/pocketmine/block/TallGrass.php rename to src/block/TallGrass.php diff --git a/src/pocketmine/block/Thin.php b/src/block/Thin.php similarity index 100% rename from src/pocketmine/block/Thin.php rename to src/block/Thin.php diff --git a/src/pocketmine/block/Torch.php b/src/block/Torch.php similarity index 100% rename from src/pocketmine/block/Torch.php rename to src/block/Torch.php diff --git a/src/pocketmine/block/Transparent.php b/src/block/Transparent.php similarity index 100% rename from src/pocketmine/block/Transparent.php rename to src/block/Transparent.php diff --git a/src/pocketmine/block/Trapdoor.php b/src/block/Trapdoor.php similarity index 100% rename from src/pocketmine/block/Trapdoor.php rename to src/block/Trapdoor.php diff --git a/src/pocketmine/block/TrappedChest.php b/src/block/TrappedChest.php similarity index 100% rename from src/pocketmine/block/TrappedChest.php rename to src/block/TrappedChest.php diff --git a/src/pocketmine/block/Tripwire.php b/src/block/Tripwire.php similarity index 100% rename from src/pocketmine/block/Tripwire.php rename to src/block/Tripwire.php diff --git a/src/pocketmine/block/TripwireHook.php b/src/block/TripwireHook.php similarity index 100% rename from src/pocketmine/block/TripwireHook.php rename to src/block/TripwireHook.php diff --git a/src/pocketmine/block/UnderwaterTorch.php b/src/block/UnderwaterTorch.php similarity index 100% rename from src/pocketmine/block/UnderwaterTorch.php rename to src/block/UnderwaterTorch.php diff --git a/src/pocketmine/block/UnknownBlock.php b/src/block/UnknownBlock.php similarity index 100% rename from src/pocketmine/block/UnknownBlock.php rename to src/block/UnknownBlock.php diff --git a/src/pocketmine/block/VanillaBlocks.php b/src/block/VanillaBlocks.php similarity index 100% rename from src/pocketmine/block/VanillaBlocks.php rename to src/block/VanillaBlocks.php diff --git a/src/pocketmine/block/Vine.php b/src/block/Vine.php similarity index 100% rename from src/pocketmine/block/Vine.php rename to src/block/Vine.php diff --git a/src/pocketmine/block/Wall.php b/src/block/Wall.php similarity index 100% rename from src/pocketmine/block/Wall.php rename to src/block/Wall.php diff --git a/src/pocketmine/block/Water.php b/src/block/Water.php similarity index 100% rename from src/pocketmine/block/Water.php rename to src/block/Water.php diff --git a/src/pocketmine/block/WaterLily.php b/src/block/WaterLily.php similarity index 100% rename from src/pocketmine/block/WaterLily.php rename to src/block/WaterLily.php diff --git a/src/pocketmine/block/WeightedPressurePlate.php b/src/block/WeightedPressurePlate.php similarity index 100% rename from src/pocketmine/block/WeightedPressurePlate.php rename to src/block/WeightedPressurePlate.php diff --git a/src/pocketmine/block/WeightedPressurePlateHeavy.php b/src/block/WeightedPressurePlateHeavy.php similarity index 100% rename from src/pocketmine/block/WeightedPressurePlateHeavy.php rename to src/block/WeightedPressurePlateHeavy.php diff --git a/src/pocketmine/block/WeightedPressurePlateLight.php b/src/block/WeightedPressurePlateLight.php similarity index 100% rename from src/pocketmine/block/WeightedPressurePlateLight.php rename to src/block/WeightedPressurePlateLight.php diff --git a/src/pocketmine/block/Wheat.php b/src/block/Wheat.php similarity index 100% rename from src/pocketmine/block/Wheat.php rename to src/block/Wheat.php diff --git a/src/pocketmine/block/Wood.php b/src/block/Wood.php similarity index 100% rename from src/pocketmine/block/Wood.php rename to src/block/Wood.php diff --git a/src/pocketmine/block/WoodenButton.php b/src/block/WoodenButton.php similarity index 100% rename from src/pocketmine/block/WoodenButton.php rename to src/block/WoodenButton.php diff --git a/src/pocketmine/block/WoodenDoor.php b/src/block/WoodenDoor.php similarity index 100% rename from src/pocketmine/block/WoodenDoor.php rename to src/block/WoodenDoor.php diff --git a/src/pocketmine/block/WoodenFence.php b/src/block/WoodenFence.php similarity index 100% rename from src/pocketmine/block/WoodenFence.php rename to src/block/WoodenFence.php diff --git a/src/pocketmine/block/WoodenPressurePlate.php b/src/block/WoodenPressurePlate.php similarity index 100% rename from src/pocketmine/block/WoodenPressurePlate.php rename to src/block/WoodenPressurePlate.php diff --git a/src/pocketmine/block/WoodenSlab.php b/src/block/WoodenSlab.php similarity index 100% rename from src/pocketmine/block/WoodenSlab.php rename to src/block/WoodenSlab.php diff --git a/src/pocketmine/block/WoodenStairs.php b/src/block/WoodenStairs.php similarity index 100% rename from src/pocketmine/block/WoodenStairs.php rename to src/block/WoodenStairs.php diff --git a/src/pocketmine/block/WoodenTrapdoor.php b/src/block/WoodenTrapdoor.php similarity index 100% rename from src/pocketmine/block/WoodenTrapdoor.php rename to src/block/WoodenTrapdoor.php diff --git a/src/pocketmine/block/Wool.php b/src/block/Wool.php similarity index 100% rename from src/pocketmine/block/Wool.php rename to src/block/Wool.php diff --git a/src/pocketmine/block/tile/Banner.php b/src/block/tile/Banner.php similarity index 100% rename from src/pocketmine/block/tile/Banner.php rename to src/block/tile/Banner.php diff --git a/src/pocketmine/block/tile/Bed.php b/src/block/tile/Bed.php similarity index 100% rename from src/pocketmine/block/tile/Bed.php rename to src/block/tile/Bed.php diff --git a/src/pocketmine/block/tile/BrewingStand.php b/src/block/tile/BrewingStand.php similarity index 100% rename from src/pocketmine/block/tile/BrewingStand.php rename to src/block/tile/BrewingStand.php diff --git a/src/pocketmine/block/tile/Chest.php b/src/block/tile/Chest.php similarity index 100% rename from src/pocketmine/block/tile/Chest.php rename to src/block/tile/Chest.php diff --git a/src/pocketmine/block/tile/Comparator.php b/src/block/tile/Comparator.php similarity index 100% rename from src/pocketmine/block/tile/Comparator.php rename to src/block/tile/Comparator.php diff --git a/src/pocketmine/block/tile/Container.php b/src/block/tile/Container.php similarity index 100% rename from src/pocketmine/block/tile/Container.php rename to src/block/tile/Container.php diff --git a/src/pocketmine/block/tile/ContainerTrait.php b/src/block/tile/ContainerTrait.php similarity index 100% rename from src/pocketmine/block/tile/ContainerTrait.php rename to src/block/tile/ContainerTrait.php diff --git a/src/pocketmine/block/tile/DaylightSensor.php b/src/block/tile/DaylightSensor.php similarity index 100% rename from src/pocketmine/block/tile/DaylightSensor.php rename to src/block/tile/DaylightSensor.php diff --git a/src/pocketmine/block/tile/EnchantTable.php b/src/block/tile/EnchantTable.php similarity index 100% rename from src/pocketmine/block/tile/EnchantTable.php rename to src/block/tile/EnchantTable.php diff --git a/src/pocketmine/block/tile/EnderChest.php b/src/block/tile/EnderChest.php similarity index 100% rename from src/pocketmine/block/tile/EnderChest.php rename to src/block/tile/EnderChest.php diff --git a/src/pocketmine/block/tile/FlowerPot.php b/src/block/tile/FlowerPot.php similarity index 100% rename from src/pocketmine/block/tile/FlowerPot.php rename to src/block/tile/FlowerPot.php diff --git a/src/pocketmine/block/tile/Furnace.php b/src/block/tile/Furnace.php similarity index 100% rename from src/pocketmine/block/tile/Furnace.php rename to src/block/tile/Furnace.php diff --git a/src/pocketmine/block/tile/Hopper.php b/src/block/tile/Hopper.php similarity index 100% rename from src/pocketmine/block/tile/Hopper.php rename to src/block/tile/Hopper.php diff --git a/src/pocketmine/block/tile/ItemFrame.php b/src/block/tile/ItemFrame.php similarity index 100% rename from src/pocketmine/block/tile/ItemFrame.php rename to src/block/tile/ItemFrame.php diff --git a/src/pocketmine/block/tile/MonsterSpawner.php b/src/block/tile/MonsterSpawner.php similarity index 100% rename from src/pocketmine/block/tile/MonsterSpawner.php rename to src/block/tile/MonsterSpawner.php diff --git a/src/pocketmine/block/tile/Nameable.php b/src/block/tile/Nameable.php similarity index 100% rename from src/pocketmine/block/tile/Nameable.php rename to src/block/tile/Nameable.php diff --git a/src/pocketmine/block/tile/NameableTrait.php b/src/block/tile/NameableTrait.php similarity index 100% rename from src/pocketmine/block/tile/NameableTrait.php rename to src/block/tile/NameableTrait.php diff --git a/src/pocketmine/block/tile/Note.php b/src/block/tile/Note.php similarity index 100% rename from src/pocketmine/block/tile/Note.php rename to src/block/tile/Note.php diff --git a/src/pocketmine/block/tile/Sign.php b/src/block/tile/Sign.php similarity index 100% rename from src/pocketmine/block/tile/Sign.php rename to src/block/tile/Sign.php diff --git a/src/pocketmine/block/tile/Skull.php b/src/block/tile/Skull.php similarity index 100% rename from src/pocketmine/block/tile/Skull.php rename to src/block/tile/Skull.php diff --git a/src/pocketmine/block/tile/Spawnable.php b/src/block/tile/Spawnable.php similarity index 100% rename from src/pocketmine/block/tile/Spawnable.php rename to src/block/tile/Spawnable.php diff --git a/src/pocketmine/block/tile/Tile.php b/src/block/tile/Tile.php similarity index 100% rename from src/pocketmine/block/tile/Tile.php rename to src/block/tile/Tile.php diff --git a/src/pocketmine/block/tile/TileFactory.php b/src/block/tile/TileFactory.php similarity index 100% rename from src/pocketmine/block/tile/TileFactory.php rename to src/block/tile/TileFactory.php diff --git a/src/pocketmine/block/utils/BannerPattern.php b/src/block/utils/BannerPattern.php similarity index 100% rename from src/pocketmine/block/utils/BannerPattern.php rename to src/block/utils/BannerPattern.php diff --git a/src/pocketmine/block/utils/BlockDataSerializer.php b/src/block/utils/BlockDataSerializer.php similarity index 100% rename from src/pocketmine/block/utils/BlockDataSerializer.php rename to src/block/utils/BlockDataSerializer.php diff --git a/src/pocketmine/block/utils/DyeColor.php b/src/block/utils/DyeColor.php similarity index 100% rename from src/pocketmine/block/utils/DyeColor.php rename to src/block/utils/DyeColor.php diff --git a/src/pocketmine/block/utils/Fallable.php b/src/block/utils/Fallable.php similarity index 100% rename from src/pocketmine/block/utils/Fallable.php rename to src/block/utils/Fallable.php diff --git a/src/pocketmine/block/utils/FallableTrait.php b/src/block/utils/FallableTrait.php similarity index 100% rename from src/pocketmine/block/utils/FallableTrait.php rename to src/block/utils/FallableTrait.php diff --git a/src/pocketmine/block/utils/InvalidBlockStateException.php b/src/block/utils/InvalidBlockStateException.php similarity index 100% rename from src/pocketmine/block/utils/InvalidBlockStateException.php rename to src/block/utils/InvalidBlockStateException.php diff --git a/src/pocketmine/block/utils/PillarRotationTrait.php b/src/block/utils/PillarRotationTrait.php similarity index 100% rename from src/pocketmine/block/utils/PillarRotationTrait.php rename to src/block/utils/PillarRotationTrait.php diff --git a/src/pocketmine/block/utils/SignText.php b/src/block/utils/SignText.php similarity index 100% rename from src/pocketmine/block/utils/SignText.php rename to src/block/utils/SignText.php diff --git a/src/pocketmine/block/utils/SkullType.php b/src/block/utils/SkullType.php similarity index 100% rename from src/pocketmine/block/utils/SkullType.php rename to src/block/utils/SkullType.php diff --git a/src/pocketmine/block/utils/SlabType.php b/src/block/utils/SlabType.php similarity index 100% rename from src/pocketmine/block/utils/SlabType.php rename to src/block/utils/SlabType.php diff --git a/src/pocketmine/block/utils/StairShape.php b/src/block/utils/StairShape.php similarity index 100% rename from src/pocketmine/block/utils/StairShape.php rename to src/block/utils/StairShape.php diff --git a/src/pocketmine/block/utils/TreeType.php b/src/block/utils/TreeType.php similarity index 100% rename from src/pocketmine/block/utils/TreeType.php rename to src/block/utils/TreeType.php diff --git a/src/pocketmine/command/Command.php b/src/command/Command.php similarity index 100% rename from src/pocketmine/command/Command.php rename to src/command/Command.php diff --git a/src/pocketmine/command/CommandExecutor.php b/src/command/CommandExecutor.php similarity index 100% rename from src/pocketmine/command/CommandExecutor.php rename to src/command/CommandExecutor.php diff --git a/src/pocketmine/command/CommandMap.php b/src/command/CommandMap.php similarity index 100% rename from src/pocketmine/command/CommandMap.php rename to src/command/CommandMap.php diff --git a/src/pocketmine/command/CommandReader.php b/src/command/CommandReader.php similarity index 100% rename from src/pocketmine/command/CommandReader.php rename to src/command/CommandReader.php diff --git a/src/pocketmine/command/CommandSender.php b/src/command/CommandSender.php similarity index 100% rename from src/pocketmine/command/CommandSender.php rename to src/command/CommandSender.php diff --git a/src/pocketmine/command/ConsoleCommandSender.php b/src/command/ConsoleCommandSender.php similarity index 100% rename from src/pocketmine/command/ConsoleCommandSender.php rename to src/command/ConsoleCommandSender.php diff --git a/src/pocketmine/command/FormattedCommandAlias.php b/src/command/FormattedCommandAlias.php similarity index 100% rename from src/pocketmine/command/FormattedCommandAlias.php rename to src/command/FormattedCommandAlias.php diff --git a/src/pocketmine/command/PluginCommand.php b/src/command/PluginCommand.php similarity index 100% rename from src/pocketmine/command/PluginCommand.php rename to src/command/PluginCommand.php diff --git a/src/pocketmine/command/PluginIdentifiableCommand.php b/src/command/PluginIdentifiableCommand.php similarity index 100% rename from src/pocketmine/command/PluginIdentifiableCommand.php rename to src/command/PluginIdentifiableCommand.php diff --git a/src/pocketmine/command/SimpleCommandMap.php b/src/command/SimpleCommandMap.php similarity index 100% rename from src/pocketmine/command/SimpleCommandMap.php rename to src/command/SimpleCommandMap.php diff --git a/src/pocketmine/command/defaults/BanCommand.php b/src/command/defaults/BanCommand.php similarity index 100% rename from src/pocketmine/command/defaults/BanCommand.php rename to src/command/defaults/BanCommand.php diff --git a/src/pocketmine/command/defaults/BanIpCommand.php b/src/command/defaults/BanIpCommand.php similarity index 100% rename from src/pocketmine/command/defaults/BanIpCommand.php rename to src/command/defaults/BanIpCommand.php diff --git a/src/pocketmine/command/defaults/BanListCommand.php b/src/command/defaults/BanListCommand.php similarity index 100% rename from src/pocketmine/command/defaults/BanListCommand.php rename to src/command/defaults/BanListCommand.php diff --git a/src/pocketmine/command/defaults/DefaultGamemodeCommand.php b/src/command/defaults/DefaultGamemodeCommand.php similarity index 100% rename from src/pocketmine/command/defaults/DefaultGamemodeCommand.php rename to src/command/defaults/DefaultGamemodeCommand.php diff --git a/src/pocketmine/command/defaults/DeopCommand.php b/src/command/defaults/DeopCommand.php similarity index 100% rename from src/pocketmine/command/defaults/DeopCommand.php rename to src/command/defaults/DeopCommand.php diff --git a/src/pocketmine/command/defaults/DifficultyCommand.php b/src/command/defaults/DifficultyCommand.php similarity index 100% rename from src/pocketmine/command/defaults/DifficultyCommand.php rename to src/command/defaults/DifficultyCommand.php diff --git a/src/pocketmine/command/defaults/DumpMemoryCommand.php b/src/command/defaults/DumpMemoryCommand.php similarity index 100% rename from src/pocketmine/command/defaults/DumpMemoryCommand.php rename to src/command/defaults/DumpMemoryCommand.php diff --git a/src/pocketmine/command/defaults/EffectCommand.php b/src/command/defaults/EffectCommand.php similarity index 100% rename from src/pocketmine/command/defaults/EffectCommand.php rename to src/command/defaults/EffectCommand.php diff --git a/src/pocketmine/command/defaults/EnchantCommand.php b/src/command/defaults/EnchantCommand.php similarity index 100% rename from src/pocketmine/command/defaults/EnchantCommand.php rename to src/command/defaults/EnchantCommand.php diff --git a/src/pocketmine/command/defaults/GamemodeCommand.php b/src/command/defaults/GamemodeCommand.php similarity index 100% rename from src/pocketmine/command/defaults/GamemodeCommand.php rename to src/command/defaults/GamemodeCommand.php diff --git a/src/pocketmine/command/defaults/GarbageCollectorCommand.php b/src/command/defaults/GarbageCollectorCommand.php similarity index 100% rename from src/pocketmine/command/defaults/GarbageCollectorCommand.php rename to src/command/defaults/GarbageCollectorCommand.php diff --git a/src/pocketmine/command/defaults/GiveCommand.php b/src/command/defaults/GiveCommand.php similarity index 100% rename from src/pocketmine/command/defaults/GiveCommand.php rename to src/command/defaults/GiveCommand.php diff --git a/src/pocketmine/command/defaults/HelpCommand.php b/src/command/defaults/HelpCommand.php similarity index 100% rename from src/pocketmine/command/defaults/HelpCommand.php rename to src/command/defaults/HelpCommand.php diff --git a/src/pocketmine/command/defaults/KickCommand.php b/src/command/defaults/KickCommand.php similarity index 100% rename from src/pocketmine/command/defaults/KickCommand.php rename to src/command/defaults/KickCommand.php diff --git a/src/pocketmine/command/defaults/KillCommand.php b/src/command/defaults/KillCommand.php similarity index 100% rename from src/pocketmine/command/defaults/KillCommand.php rename to src/command/defaults/KillCommand.php diff --git a/src/pocketmine/command/defaults/ListCommand.php b/src/command/defaults/ListCommand.php similarity index 100% rename from src/pocketmine/command/defaults/ListCommand.php rename to src/command/defaults/ListCommand.php diff --git a/src/pocketmine/command/defaults/MeCommand.php b/src/command/defaults/MeCommand.php similarity index 100% rename from src/pocketmine/command/defaults/MeCommand.php rename to src/command/defaults/MeCommand.php diff --git a/src/pocketmine/command/defaults/OpCommand.php b/src/command/defaults/OpCommand.php similarity index 100% rename from src/pocketmine/command/defaults/OpCommand.php rename to src/command/defaults/OpCommand.php diff --git a/src/pocketmine/command/defaults/PardonCommand.php b/src/command/defaults/PardonCommand.php similarity index 100% rename from src/pocketmine/command/defaults/PardonCommand.php rename to src/command/defaults/PardonCommand.php diff --git a/src/pocketmine/command/defaults/PardonIpCommand.php b/src/command/defaults/PardonIpCommand.php similarity index 100% rename from src/pocketmine/command/defaults/PardonIpCommand.php rename to src/command/defaults/PardonIpCommand.php diff --git a/src/pocketmine/command/defaults/ParticleCommand.php b/src/command/defaults/ParticleCommand.php similarity index 100% rename from src/pocketmine/command/defaults/ParticleCommand.php rename to src/command/defaults/ParticleCommand.php diff --git a/src/pocketmine/command/defaults/PluginsCommand.php b/src/command/defaults/PluginsCommand.php similarity index 100% rename from src/pocketmine/command/defaults/PluginsCommand.php rename to src/command/defaults/PluginsCommand.php diff --git a/src/pocketmine/command/defaults/SaveCommand.php b/src/command/defaults/SaveCommand.php similarity index 100% rename from src/pocketmine/command/defaults/SaveCommand.php rename to src/command/defaults/SaveCommand.php diff --git a/src/pocketmine/command/defaults/SaveOffCommand.php b/src/command/defaults/SaveOffCommand.php similarity index 100% rename from src/pocketmine/command/defaults/SaveOffCommand.php rename to src/command/defaults/SaveOffCommand.php diff --git a/src/pocketmine/command/defaults/SaveOnCommand.php b/src/command/defaults/SaveOnCommand.php similarity index 100% rename from src/pocketmine/command/defaults/SaveOnCommand.php rename to src/command/defaults/SaveOnCommand.php diff --git a/src/pocketmine/command/defaults/SayCommand.php b/src/command/defaults/SayCommand.php similarity index 100% rename from src/pocketmine/command/defaults/SayCommand.php rename to src/command/defaults/SayCommand.php diff --git a/src/pocketmine/command/defaults/SeedCommand.php b/src/command/defaults/SeedCommand.php similarity index 100% rename from src/pocketmine/command/defaults/SeedCommand.php rename to src/command/defaults/SeedCommand.php diff --git a/src/pocketmine/command/defaults/SetWorldSpawnCommand.php b/src/command/defaults/SetWorldSpawnCommand.php similarity index 100% rename from src/pocketmine/command/defaults/SetWorldSpawnCommand.php rename to src/command/defaults/SetWorldSpawnCommand.php diff --git a/src/pocketmine/command/defaults/SpawnpointCommand.php b/src/command/defaults/SpawnpointCommand.php similarity index 100% rename from src/pocketmine/command/defaults/SpawnpointCommand.php rename to src/command/defaults/SpawnpointCommand.php diff --git a/src/pocketmine/command/defaults/StatusCommand.php b/src/command/defaults/StatusCommand.php similarity index 100% rename from src/pocketmine/command/defaults/StatusCommand.php rename to src/command/defaults/StatusCommand.php diff --git a/src/pocketmine/command/defaults/StopCommand.php b/src/command/defaults/StopCommand.php similarity index 100% rename from src/pocketmine/command/defaults/StopCommand.php rename to src/command/defaults/StopCommand.php diff --git a/src/pocketmine/command/defaults/TeleportCommand.php b/src/command/defaults/TeleportCommand.php similarity index 100% rename from src/pocketmine/command/defaults/TeleportCommand.php rename to src/command/defaults/TeleportCommand.php diff --git a/src/pocketmine/command/defaults/TellCommand.php b/src/command/defaults/TellCommand.php similarity index 100% rename from src/pocketmine/command/defaults/TellCommand.php rename to src/command/defaults/TellCommand.php diff --git a/src/pocketmine/command/defaults/TimeCommand.php b/src/command/defaults/TimeCommand.php similarity index 100% rename from src/pocketmine/command/defaults/TimeCommand.php rename to src/command/defaults/TimeCommand.php diff --git a/src/pocketmine/command/defaults/TimingsCommand.php b/src/command/defaults/TimingsCommand.php similarity index 100% rename from src/pocketmine/command/defaults/TimingsCommand.php rename to src/command/defaults/TimingsCommand.php diff --git a/src/pocketmine/command/defaults/TitleCommand.php b/src/command/defaults/TitleCommand.php similarity index 100% rename from src/pocketmine/command/defaults/TitleCommand.php rename to src/command/defaults/TitleCommand.php diff --git a/src/pocketmine/command/defaults/TransferServerCommand.php b/src/command/defaults/TransferServerCommand.php similarity index 100% rename from src/pocketmine/command/defaults/TransferServerCommand.php rename to src/command/defaults/TransferServerCommand.php diff --git a/src/pocketmine/command/defaults/VanillaCommand.php b/src/command/defaults/VanillaCommand.php similarity index 100% rename from src/pocketmine/command/defaults/VanillaCommand.php rename to src/command/defaults/VanillaCommand.php diff --git a/src/pocketmine/command/defaults/VersionCommand.php b/src/command/defaults/VersionCommand.php similarity index 100% rename from src/pocketmine/command/defaults/VersionCommand.php rename to src/command/defaults/VersionCommand.php diff --git a/src/pocketmine/command/defaults/WhitelistCommand.php b/src/command/defaults/WhitelistCommand.php similarity index 100% rename from src/pocketmine/command/defaults/WhitelistCommand.php rename to src/command/defaults/WhitelistCommand.php diff --git a/src/pocketmine/command/utils/CommandException.php b/src/command/utils/CommandException.php similarity index 100% rename from src/pocketmine/command/utils/CommandException.php rename to src/command/utils/CommandException.php diff --git a/src/pocketmine/command/utils/InvalidCommandSyntaxException.php b/src/command/utils/InvalidCommandSyntaxException.php similarity index 100% rename from src/pocketmine/command/utils/InvalidCommandSyntaxException.php rename to src/command/utils/InvalidCommandSyntaxException.php diff --git a/src/pocketmine/crafting/CraftingGrid.php b/src/crafting/CraftingGrid.php similarity index 100% rename from src/pocketmine/crafting/CraftingGrid.php rename to src/crafting/CraftingGrid.php diff --git a/src/pocketmine/crafting/CraftingManager.php b/src/crafting/CraftingManager.php similarity index 100% rename from src/pocketmine/crafting/CraftingManager.php rename to src/crafting/CraftingManager.php diff --git a/src/pocketmine/crafting/CraftingRecipe.php b/src/crafting/CraftingRecipe.php similarity index 100% rename from src/pocketmine/crafting/CraftingRecipe.php rename to src/crafting/CraftingRecipe.php diff --git a/src/pocketmine/crafting/FurnaceRecipe.php b/src/crafting/FurnaceRecipe.php similarity index 100% rename from src/pocketmine/crafting/FurnaceRecipe.php rename to src/crafting/FurnaceRecipe.php diff --git a/src/pocketmine/crafting/MultiRecipe.php b/src/crafting/MultiRecipe.php similarity index 100% rename from src/pocketmine/crafting/MultiRecipe.php rename to src/crafting/MultiRecipe.php diff --git a/src/pocketmine/crafting/ShapedRecipe.php b/src/crafting/ShapedRecipe.php similarity index 100% rename from src/pocketmine/crafting/ShapedRecipe.php rename to src/crafting/ShapedRecipe.php diff --git a/src/pocketmine/crafting/ShapelessRecipe.php b/src/crafting/ShapelessRecipe.php similarity index 100% rename from src/pocketmine/crafting/ShapelessRecipe.php rename to src/crafting/ShapelessRecipe.php diff --git a/src/pocketmine/entity/Ageable.php b/src/entity/Ageable.php similarity index 100% rename from src/pocketmine/entity/Ageable.php rename to src/entity/Ageable.php diff --git a/src/pocketmine/entity/Animal.php b/src/entity/Animal.php similarity index 100% rename from src/pocketmine/entity/Animal.php rename to src/entity/Animal.php diff --git a/src/pocketmine/entity/Attribute.php b/src/entity/Attribute.php similarity index 100% rename from src/pocketmine/entity/Attribute.php rename to src/entity/Attribute.php diff --git a/src/pocketmine/entity/AttributeMap.php b/src/entity/AttributeMap.php similarity index 100% rename from src/pocketmine/entity/AttributeMap.php rename to src/entity/AttributeMap.php diff --git a/src/pocketmine/entity/Entity.php b/src/entity/Entity.php similarity index 100% rename from src/pocketmine/entity/Entity.php rename to src/entity/Entity.php diff --git a/src/pocketmine/entity/EntityFactory.php b/src/entity/EntityFactory.php similarity index 100% rename from src/pocketmine/entity/EntityFactory.php rename to src/entity/EntityFactory.php diff --git a/src/pocketmine/entity/ExperienceManager.php b/src/entity/ExperienceManager.php similarity index 100% rename from src/pocketmine/entity/ExperienceManager.php rename to src/entity/ExperienceManager.php diff --git a/src/pocketmine/entity/Explosive.php b/src/entity/Explosive.php similarity index 100% rename from src/pocketmine/entity/Explosive.php rename to src/entity/Explosive.php diff --git a/src/pocketmine/entity/Human.php b/src/entity/Human.php similarity index 100% rename from src/pocketmine/entity/Human.php rename to src/entity/Human.php diff --git a/src/pocketmine/entity/HungerManager.php b/src/entity/HungerManager.php similarity index 100% rename from src/pocketmine/entity/HungerManager.php rename to src/entity/HungerManager.php diff --git a/src/pocketmine/entity/Living.php b/src/entity/Living.php similarity index 100% rename from src/pocketmine/entity/Living.php rename to src/entity/Living.php diff --git a/src/pocketmine/entity/Skin.php b/src/entity/Skin.php similarity index 100% rename from src/pocketmine/entity/Skin.php rename to src/entity/Skin.php diff --git a/src/pocketmine/entity/Squid.php b/src/entity/Squid.php similarity index 100% rename from src/pocketmine/entity/Squid.php rename to src/entity/Squid.php diff --git a/src/pocketmine/entity/Villager.php b/src/entity/Villager.php similarity index 100% rename from src/pocketmine/entity/Villager.php rename to src/entity/Villager.php diff --git a/src/pocketmine/entity/WaterAnimal.php b/src/entity/WaterAnimal.php similarity index 100% rename from src/pocketmine/entity/WaterAnimal.php rename to src/entity/WaterAnimal.php diff --git a/src/pocketmine/entity/Zombie.php b/src/entity/Zombie.php similarity index 100% rename from src/pocketmine/entity/Zombie.php rename to src/entity/Zombie.php diff --git a/src/pocketmine/entity/effect/AbsorptionEffect.php b/src/entity/effect/AbsorptionEffect.php similarity index 100% rename from src/pocketmine/entity/effect/AbsorptionEffect.php rename to src/entity/effect/AbsorptionEffect.php diff --git a/src/pocketmine/entity/effect/Effect.php b/src/entity/effect/Effect.php similarity index 100% rename from src/pocketmine/entity/effect/Effect.php rename to src/entity/effect/Effect.php diff --git a/src/pocketmine/entity/effect/EffectInstance.php b/src/entity/effect/EffectInstance.php similarity index 100% rename from src/pocketmine/entity/effect/EffectInstance.php rename to src/entity/effect/EffectInstance.php diff --git a/src/pocketmine/entity/effect/EffectManager.php b/src/entity/effect/EffectManager.php similarity index 100% rename from src/pocketmine/entity/effect/EffectManager.php rename to src/entity/effect/EffectManager.php diff --git a/src/pocketmine/entity/effect/HealthBoostEffect.php b/src/entity/effect/HealthBoostEffect.php similarity index 100% rename from src/pocketmine/entity/effect/HealthBoostEffect.php rename to src/entity/effect/HealthBoostEffect.php diff --git a/src/pocketmine/entity/effect/HungerEffect.php b/src/entity/effect/HungerEffect.php similarity index 100% rename from src/pocketmine/entity/effect/HungerEffect.php rename to src/entity/effect/HungerEffect.php diff --git a/src/pocketmine/entity/effect/InstantDamageEffect.php b/src/entity/effect/InstantDamageEffect.php similarity index 100% rename from src/pocketmine/entity/effect/InstantDamageEffect.php rename to src/entity/effect/InstantDamageEffect.php diff --git a/src/pocketmine/entity/effect/InstantEffect.php b/src/entity/effect/InstantEffect.php similarity index 100% rename from src/pocketmine/entity/effect/InstantEffect.php rename to src/entity/effect/InstantEffect.php diff --git a/src/pocketmine/entity/effect/InstantHealthEffect.php b/src/entity/effect/InstantHealthEffect.php similarity index 100% rename from src/pocketmine/entity/effect/InstantHealthEffect.php rename to src/entity/effect/InstantHealthEffect.php diff --git a/src/pocketmine/entity/effect/InvisibilityEffect.php b/src/entity/effect/InvisibilityEffect.php similarity index 100% rename from src/pocketmine/entity/effect/InvisibilityEffect.php rename to src/entity/effect/InvisibilityEffect.php diff --git a/src/pocketmine/entity/effect/LevitationEffect.php b/src/entity/effect/LevitationEffect.php similarity index 100% rename from src/pocketmine/entity/effect/LevitationEffect.php rename to src/entity/effect/LevitationEffect.php diff --git a/src/pocketmine/entity/effect/PoisonEffect.php b/src/entity/effect/PoisonEffect.php similarity index 100% rename from src/pocketmine/entity/effect/PoisonEffect.php rename to src/entity/effect/PoisonEffect.php diff --git a/src/pocketmine/entity/effect/RegenerationEffect.php b/src/entity/effect/RegenerationEffect.php similarity index 100% rename from src/pocketmine/entity/effect/RegenerationEffect.php rename to src/entity/effect/RegenerationEffect.php diff --git a/src/pocketmine/entity/effect/SaturationEffect.php b/src/entity/effect/SaturationEffect.php similarity index 100% rename from src/pocketmine/entity/effect/SaturationEffect.php rename to src/entity/effect/SaturationEffect.php diff --git a/src/pocketmine/entity/effect/SlownessEffect.php b/src/entity/effect/SlownessEffect.php similarity index 100% rename from src/pocketmine/entity/effect/SlownessEffect.php rename to src/entity/effect/SlownessEffect.php diff --git a/src/pocketmine/entity/effect/SpeedEffect.php b/src/entity/effect/SpeedEffect.php similarity index 100% rename from src/pocketmine/entity/effect/SpeedEffect.php rename to src/entity/effect/SpeedEffect.php diff --git a/src/pocketmine/entity/effect/VanillaEffects.php b/src/entity/effect/VanillaEffects.php similarity index 100% rename from src/pocketmine/entity/effect/VanillaEffects.php rename to src/entity/effect/VanillaEffects.php diff --git a/src/pocketmine/entity/effect/WitherEffect.php b/src/entity/effect/WitherEffect.php similarity index 100% rename from src/pocketmine/entity/effect/WitherEffect.php rename to src/entity/effect/WitherEffect.php diff --git a/src/pocketmine/entity/object/ExperienceOrb.php b/src/entity/object/ExperienceOrb.php similarity index 100% rename from src/pocketmine/entity/object/ExperienceOrb.php rename to src/entity/object/ExperienceOrb.php diff --git a/src/pocketmine/entity/object/FallingBlock.php b/src/entity/object/FallingBlock.php similarity index 100% rename from src/pocketmine/entity/object/FallingBlock.php rename to src/entity/object/FallingBlock.php diff --git a/src/pocketmine/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php similarity index 100% rename from src/pocketmine/entity/object/ItemEntity.php rename to src/entity/object/ItemEntity.php diff --git a/src/pocketmine/entity/object/Painting.php b/src/entity/object/Painting.php similarity index 100% rename from src/pocketmine/entity/object/Painting.php rename to src/entity/object/Painting.php diff --git a/src/pocketmine/entity/object/PaintingMotive.php b/src/entity/object/PaintingMotive.php similarity index 100% rename from src/pocketmine/entity/object/PaintingMotive.php rename to src/entity/object/PaintingMotive.php diff --git a/src/pocketmine/entity/object/PrimedTNT.php b/src/entity/object/PrimedTNT.php similarity index 100% rename from src/pocketmine/entity/object/PrimedTNT.php rename to src/entity/object/PrimedTNT.php diff --git a/src/pocketmine/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php similarity index 100% rename from src/pocketmine/entity/projectile/Arrow.php rename to src/entity/projectile/Arrow.php diff --git a/src/pocketmine/entity/projectile/Egg.php b/src/entity/projectile/Egg.php similarity index 100% rename from src/pocketmine/entity/projectile/Egg.php rename to src/entity/projectile/Egg.php diff --git a/src/pocketmine/entity/projectile/EnderPearl.php b/src/entity/projectile/EnderPearl.php similarity index 100% rename from src/pocketmine/entity/projectile/EnderPearl.php rename to src/entity/projectile/EnderPearl.php diff --git a/src/pocketmine/entity/projectile/ExperienceBottle.php b/src/entity/projectile/ExperienceBottle.php similarity index 100% rename from src/pocketmine/entity/projectile/ExperienceBottle.php rename to src/entity/projectile/ExperienceBottle.php diff --git a/src/pocketmine/entity/projectile/Projectile.php b/src/entity/projectile/Projectile.php similarity index 100% rename from src/pocketmine/entity/projectile/Projectile.php rename to src/entity/projectile/Projectile.php diff --git a/src/pocketmine/entity/projectile/ProjectileSource.php b/src/entity/projectile/ProjectileSource.php similarity index 100% rename from src/pocketmine/entity/projectile/ProjectileSource.php rename to src/entity/projectile/ProjectileSource.php diff --git a/src/pocketmine/entity/projectile/Snowball.php b/src/entity/projectile/Snowball.php similarity index 100% rename from src/pocketmine/entity/projectile/Snowball.php rename to src/entity/projectile/Snowball.php diff --git a/src/pocketmine/entity/projectile/SplashPotion.php b/src/entity/projectile/SplashPotion.php similarity index 100% rename from src/pocketmine/entity/projectile/SplashPotion.php rename to src/entity/projectile/SplashPotion.php diff --git a/src/pocketmine/entity/projectile/Throwable.php b/src/entity/projectile/Throwable.php similarity index 100% rename from src/pocketmine/entity/projectile/Throwable.php rename to src/entity/projectile/Throwable.php diff --git a/src/pocketmine/entity/utils/ExperienceUtils.php b/src/entity/utils/ExperienceUtils.php similarity index 100% rename from src/pocketmine/entity/utils/ExperienceUtils.php rename to src/entity/utils/ExperienceUtils.php diff --git a/src/pocketmine/event/Cancellable.php b/src/event/Cancellable.php similarity index 100% rename from src/pocketmine/event/Cancellable.php rename to src/event/Cancellable.php diff --git a/src/pocketmine/event/CancellableTrait.php b/src/event/CancellableTrait.php similarity index 100% rename from src/pocketmine/event/CancellableTrait.php rename to src/event/CancellableTrait.php diff --git a/src/pocketmine/event/Event.php b/src/event/Event.php similarity index 100% rename from src/pocketmine/event/Event.php rename to src/event/Event.php diff --git a/src/pocketmine/event/EventPriority.php b/src/event/EventPriority.php similarity index 100% rename from src/pocketmine/event/EventPriority.php rename to src/event/EventPriority.php diff --git a/src/pocketmine/event/HandlerList.php b/src/event/HandlerList.php similarity index 100% rename from src/pocketmine/event/HandlerList.php rename to src/event/HandlerList.php diff --git a/src/pocketmine/event/HandlerListManager.php b/src/event/HandlerListManager.php similarity index 100% rename from src/pocketmine/event/HandlerListManager.php rename to src/event/HandlerListManager.php diff --git a/src/pocketmine/event/Listener.php b/src/event/Listener.php similarity index 100% rename from src/pocketmine/event/Listener.php rename to src/event/Listener.php diff --git a/src/pocketmine/event/RegisteredListener.php b/src/event/RegisteredListener.php similarity index 100% rename from src/pocketmine/event/RegisteredListener.php rename to src/event/RegisteredListener.php diff --git a/src/pocketmine/event/block/BlockBreakEvent.php b/src/event/block/BlockBreakEvent.php similarity index 100% rename from src/pocketmine/event/block/BlockBreakEvent.php rename to src/event/block/BlockBreakEvent.php diff --git a/src/pocketmine/event/block/BlockBurnEvent.php b/src/event/block/BlockBurnEvent.php similarity index 100% rename from src/pocketmine/event/block/BlockBurnEvent.php rename to src/event/block/BlockBurnEvent.php diff --git a/src/pocketmine/event/block/BlockEvent.php b/src/event/block/BlockEvent.php similarity index 100% rename from src/pocketmine/event/block/BlockEvent.php rename to src/event/block/BlockEvent.php diff --git a/src/pocketmine/event/block/BlockFormEvent.php b/src/event/block/BlockFormEvent.php similarity index 100% rename from src/pocketmine/event/block/BlockFormEvent.php rename to src/event/block/BlockFormEvent.php diff --git a/src/pocketmine/event/block/BlockGrowEvent.php b/src/event/block/BlockGrowEvent.php similarity index 100% rename from src/pocketmine/event/block/BlockGrowEvent.php rename to src/event/block/BlockGrowEvent.php diff --git a/src/pocketmine/event/block/BlockPlaceEvent.php b/src/event/block/BlockPlaceEvent.php similarity index 100% rename from src/pocketmine/event/block/BlockPlaceEvent.php rename to src/event/block/BlockPlaceEvent.php diff --git a/src/pocketmine/event/block/BlockSpreadEvent.php b/src/event/block/BlockSpreadEvent.php similarity index 100% rename from src/pocketmine/event/block/BlockSpreadEvent.php rename to src/event/block/BlockSpreadEvent.php diff --git a/src/pocketmine/event/block/BlockTeleportEvent.php b/src/event/block/BlockTeleportEvent.php similarity index 100% rename from src/pocketmine/event/block/BlockTeleportEvent.php rename to src/event/block/BlockTeleportEvent.php diff --git a/src/pocketmine/event/block/BlockUpdateEvent.php b/src/event/block/BlockUpdateEvent.php similarity index 100% rename from src/pocketmine/event/block/BlockUpdateEvent.php rename to src/event/block/BlockUpdateEvent.php diff --git a/src/pocketmine/event/block/LeavesDecayEvent.php b/src/event/block/LeavesDecayEvent.php similarity index 100% rename from src/pocketmine/event/block/LeavesDecayEvent.php rename to src/event/block/LeavesDecayEvent.php diff --git a/src/pocketmine/event/block/SignChangeEvent.php b/src/event/block/SignChangeEvent.php similarity index 100% rename from src/pocketmine/event/block/SignChangeEvent.php rename to src/event/block/SignChangeEvent.php diff --git a/src/pocketmine/event/entity/EntityBlockChangeEvent.php b/src/event/entity/EntityBlockChangeEvent.php similarity index 100% rename from src/pocketmine/event/entity/EntityBlockChangeEvent.php rename to src/event/entity/EntityBlockChangeEvent.php diff --git a/src/pocketmine/event/entity/EntityCombustByBlockEvent.php b/src/event/entity/EntityCombustByBlockEvent.php similarity index 100% rename from src/pocketmine/event/entity/EntityCombustByBlockEvent.php rename to src/event/entity/EntityCombustByBlockEvent.php diff --git a/src/pocketmine/event/entity/EntityCombustByEntityEvent.php b/src/event/entity/EntityCombustByEntityEvent.php similarity index 100% rename from src/pocketmine/event/entity/EntityCombustByEntityEvent.php rename to src/event/entity/EntityCombustByEntityEvent.php diff --git a/src/pocketmine/event/entity/EntityCombustEvent.php b/src/event/entity/EntityCombustEvent.php similarity index 100% rename from src/pocketmine/event/entity/EntityCombustEvent.php rename to src/event/entity/EntityCombustEvent.php diff --git a/src/pocketmine/event/entity/EntityDamageByBlockEvent.php b/src/event/entity/EntityDamageByBlockEvent.php similarity index 100% rename from src/pocketmine/event/entity/EntityDamageByBlockEvent.php rename to src/event/entity/EntityDamageByBlockEvent.php diff --git a/src/pocketmine/event/entity/EntityDamageByChildEntityEvent.php b/src/event/entity/EntityDamageByChildEntityEvent.php similarity index 100% rename from src/pocketmine/event/entity/EntityDamageByChildEntityEvent.php rename to src/event/entity/EntityDamageByChildEntityEvent.php diff --git a/src/pocketmine/event/entity/EntityDamageByEntityEvent.php b/src/event/entity/EntityDamageByEntityEvent.php similarity index 100% rename from src/pocketmine/event/entity/EntityDamageByEntityEvent.php rename to src/event/entity/EntityDamageByEntityEvent.php diff --git a/src/pocketmine/event/entity/EntityDamageEvent.php b/src/event/entity/EntityDamageEvent.php similarity index 100% rename from src/pocketmine/event/entity/EntityDamageEvent.php rename to src/event/entity/EntityDamageEvent.php diff --git a/src/pocketmine/event/entity/EntityDeathEvent.php b/src/event/entity/EntityDeathEvent.php similarity index 100% rename from src/pocketmine/event/entity/EntityDeathEvent.php rename to src/event/entity/EntityDeathEvent.php diff --git a/src/pocketmine/event/entity/EntityDespawnEvent.php b/src/event/entity/EntityDespawnEvent.php similarity index 100% rename from src/pocketmine/event/entity/EntityDespawnEvent.php rename to src/event/entity/EntityDespawnEvent.php diff --git a/src/pocketmine/event/entity/EntityEffectAddEvent.php b/src/event/entity/EntityEffectAddEvent.php similarity index 100% rename from src/pocketmine/event/entity/EntityEffectAddEvent.php rename to src/event/entity/EntityEffectAddEvent.php diff --git a/src/pocketmine/event/entity/EntityEffectEvent.php b/src/event/entity/EntityEffectEvent.php similarity index 100% rename from src/pocketmine/event/entity/EntityEffectEvent.php rename to src/event/entity/EntityEffectEvent.php diff --git a/src/pocketmine/event/entity/EntityEffectRemoveEvent.php b/src/event/entity/EntityEffectRemoveEvent.php similarity index 100% rename from src/pocketmine/event/entity/EntityEffectRemoveEvent.php rename to src/event/entity/EntityEffectRemoveEvent.php diff --git a/src/pocketmine/event/entity/EntityEvent.php b/src/event/entity/EntityEvent.php similarity index 100% rename from src/pocketmine/event/entity/EntityEvent.php rename to src/event/entity/EntityEvent.php diff --git a/src/pocketmine/event/entity/EntityExplodeEvent.php b/src/event/entity/EntityExplodeEvent.php similarity index 100% rename from src/pocketmine/event/entity/EntityExplodeEvent.php rename to src/event/entity/EntityExplodeEvent.php diff --git a/src/pocketmine/event/entity/EntityMotionEvent.php b/src/event/entity/EntityMotionEvent.php similarity index 100% rename from src/pocketmine/event/entity/EntityMotionEvent.php rename to src/event/entity/EntityMotionEvent.php diff --git a/src/pocketmine/event/entity/EntityRegainHealthEvent.php b/src/event/entity/EntityRegainHealthEvent.php similarity index 100% rename from src/pocketmine/event/entity/EntityRegainHealthEvent.php rename to src/event/entity/EntityRegainHealthEvent.php diff --git a/src/pocketmine/event/entity/EntityShootBowEvent.php b/src/event/entity/EntityShootBowEvent.php similarity index 100% rename from src/pocketmine/event/entity/EntityShootBowEvent.php rename to src/event/entity/EntityShootBowEvent.php diff --git a/src/pocketmine/event/entity/EntitySpawnEvent.php b/src/event/entity/EntitySpawnEvent.php similarity index 100% rename from src/pocketmine/event/entity/EntitySpawnEvent.php rename to src/event/entity/EntitySpawnEvent.php diff --git a/src/pocketmine/event/entity/EntityTeleportEvent.php b/src/event/entity/EntityTeleportEvent.php similarity index 100% rename from src/pocketmine/event/entity/EntityTeleportEvent.php rename to src/event/entity/EntityTeleportEvent.php diff --git a/src/pocketmine/event/entity/ExplosionPrimeEvent.php b/src/event/entity/ExplosionPrimeEvent.php similarity index 100% rename from src/pocketmine/event/entity/ExplosionPrimeEvent.php rename to src/event/entity/ExplosionPrimeEvent.php diff --git a/src/pocketmine/event/entity/ItemDespawnEvent.php b/src/event/entity/ItemDespawnEvent.php similarity index 100% rename from src/pocketmine/event/entity/ItemDespawnEvent.php rename to src/event/entity/ItemDespawnEvent.php diff --git a/src/pocketmine/event/entity/ItemSpawnEvent.php b/src/event/entity/ItemSpawnEvent.php similarity index 100% rename from src/pocketmine/event/entity/ItemSpawnEvent.php rename to src/event/entity/ItemSpawnEvent.php diff --git a/src/pocketmine/event/entity/ProjectileHitBlockEvent.php b/src/event/entity/ProjectileHitBlockEvent.php similarity index 100% rename from src/pocketmine/event/entity/ProjectileHitBlockEvent.php rename to src/event/entity/ProjectileHitBlockEvent.php diff --git a/src/pocketmine/event/entity/ProjectileHitEntityEvent.php b/src/event/entity/ProjectileHitEntityEvent.php similarity index 100% rename from src/pocketmine/event/entity/ProjectileHitEntityEvent.php rename to src/event/entity/ProjectileHitEntityEvent.php diff --git a/src/pocketmine/event/entity/ProjectileHitEvent.php b/src/event/entity/ProjectileHitEvent.php similarity index 100% rename from src/pocketmine/event/entity/ProjectileHitEvent.php rename to src/event/entity/ProjectileHitEvent.php diff --git a/src/pocketmine/event/entity/ProjectileLaunchEvent.php b/src/event/entity/ProjectileLaunchEvent.php similarity index 100% rename from src/pocketmine/event/entity/ProjectileLaunchEvent.php rename to src/event/entity/ProjectileLaunchEvent.php diff --git a/src/pocketmine/event/inventory/CraftItemEvent.php b/src/event/inventory/CraftItemEvent.php similarity index 100% rename from src/pocketmine/event/inventory/CraftItemEvent.php rename to src/event/inventory/CraftItemEvent.php diff --git a/src/pocketmine/event/inventory/FurnaceBurnEvent.php b/src/event/inventory/FurnaceBurnEvent.php similarity index 100% rename from src/pocketmine/event/inventory/FurnaceBurnEvent.php rename to src/event/inventory/FurnaceBurnEvent.php diff --git a/src/pocketmine/event/inventory/FurnaceSmeltEvent.php b/src/event/inventory/FurnaceSmeltEvent.php similarity index 100% rename from src/pocketmine/event/inventory/FurnaceSmeltEvent.php rename to src/event/inventory/FurnaceSmeltEvent.php diff --git a/src/pocketmine/event/inventory/InventoryCloseEvent.php b/src/event/inventory/InventoryCloseEvent.php similarity index 100% rename from src/pocketmine/event/inventory/InventoryCloseEvent.php rename to src/event/inventory/InventoryCloseEvent.php diff --git a/src/pocketmine/event/inventory/InventoryEvent.php b/src/event/inventory/InventoryEvent.php similarity index 100% rename from src/pocketmine/event/inventory/InventoryEvent.php rename to src/event/inventory/InventoryEvent.php diff --git a/src/pocketmine/event/inventory/InventoryOpenEvent.php b/src/event/inventory/InventoryOpenEvent.php similarity index 100% rename from src/pocketmine/event/inventory/InventoryOpenEvent.php rename to src/event/inventory/InventoryOpenEvent.php diff --git a/src/pocketmine/event/inventory/InventoryPickupArrowEvent.php b/src/event/inventory/InventoryPickupArrowEvent.php similarity index 100% rename from src/pocketmine/event/inventory/InventoryPickupArrowEvent.php rename to src/event/inventory/InventoryPickupArrowEvent.php diff --git a/src/pocketmine/event/inventory/InventoryPickupItemEvent.php b/src/event/inventory/InventoryPickupItemEvent.php similarity index 100% rename from src/pocketmine/event/inventory/InventoryPickupItemEvent.php rename to src/event/inventory/InventoryPickupItemEvent.php diff --git a/src/pocketmine/event/inventory/InventoryTransactionEvent.php b/src/event/inventory/InventoryTransactionEvent.php similarity index 100% rename from src/pocketmine/event/inventory/InventoryTransactionEvent.php rename to src/event/inventory/InventoryTransactionEvent.php diff --git a/src/pocketmine/event/player/PlayerBedEnterEvent.php b/src/event/player/PlayerBedEnterEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerBedEnterEvent.php rename to src/event/player/PlayerBedEnterEvent.php diff --git a/src/pocketmine/event/player/PlayerBedLeaveEvent.php b/src/event/player/PlayerBedLeaveEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerBedLeaveEvent.php rename to src/event/player/PlayerBedLeaveEvent.php diff --git a/src/pocketmine/event/player/PlayerBlockPickEvent.php b/src/event/player/PlayerBlockPickEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerBlockPickEvent.php rename to src/event/player/PlayerBlockPickEvent.php diff --git a/src/pocketmine/event/player/PlayerBucketEmptyEvent.php b/src/event/player/PlayerBucketEmptyEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerBucketEmptyEvent.php rename to src/event/player/PlayerBucketEmptyEvent.php diff --git a/src/pocketmine/event/player/PlayerBucketEvent.php b/src/event/player/PlayerBucketEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerBucketEvent.php rename to src/event/player/PlayerBucketEvent.php diff --git a/src/pocketmine/event/player/PlayerBucketFillEvent.php b/src/event/player/PlayerBucketFillEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerBucketFillEvent.php rename to src/event/player/PlayerBucketFillEvent.php diff --git a/src/pocketmine/event/player/PlayerChangeSkinEvent.php b/src/event/player/PlayerChangeSkinEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerChangeSkinEvent.php rename to src/event/player/PlayerChangeSkinEvent.php diff --git a/src/pocketmine/event/player/PlayerChatEvent.php b/src/event/player/PlayerChatEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerChatEvent.php rename to src/event/player/PlayerChatEvent.php diff --git a/src/pocketmine/event/player/PlayerCommandPreprocessEvent.php b/src/event/player/PlayerCommandPreprocessEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerCommandPreprocessEvent.php rename to src/event/player/PlayerCommandPreprocessEvent.php diff --git a/src/pocketmine/event/player/PlayerCreationEvent.php b/src/event/player/PlayerCreationEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerCreationEvent.php rename to src/event/player/PlayerCreationEvent.php diff --git a/src/pocketmine/event/player/PlayerDataSaveEvent.php b/src/event/player/PlayerDataSaveEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerDataSaveEvent.php rename to src/event/player/PlayerDataSaveEvent.php diff --git a/src/pocketmine/event/player/PlayerDeathEvent.php b/src/event/player/PlayerDeathEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerDeathEvent.php rename to src/event/player/PlayerDeathEvent.php diff --git a/src/pocketmine/event/player/PlayerDropItemEvent.php b/src/event/player/PlayerDropItemEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerDropItemEvent.php rename to src/event/player/PlayerDropItemEvent.php diff --git a/src/pocketmine/event/player/PlayerDuplicateLoginEvent.php b/src/event/player/PlayerDuplicateLoginEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerDuplicateLoginEvent.php rename to src/event/player/PlayerDuplicateLoginEvent.php diff --git a/src/pocketmine/event/player/PlayerEditBookEvent.php b/src/event/player/PlayerEditBookEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerEditBookEvent.php rename to src/event/player/PlayerEditBookEvent.php diff --git a/src/pocketmine/event/player/PlayerEvent.php b/src/event/player/PlayerEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerEvent.php rename to src/event/player/PlayerEvent.php diff --git a/src/pocketmine/event/player/PlayerExhaustEvent.php b/src/event/player/PlayerExhaustEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerExhaustEvent.php rename to src/event/player/PlayerExhaustEvent.php diff --git a/src/pocketmine/event/player/PlayerExperienceChangeEvent.php b/src/event/player/PlayerExperienceChangeEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerExperienceChangeEvent.php rename to src/event/player/PlayerExperienceChangeEvent.php diff --git a/src/pocketmine/event/player/PlayerGameModeChangeEvent.php b/src/event/player/PlayerGameModeChangeEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerGameModeChangeEvent.php rename to src/event/player/PlayerGameModeChangeEvent.php diff --git a/src/pocketmine/event/player/PlayerInteractEvent.php b/src/event/player/PlayerInteractEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerInteractEvent.php rename to src/event/player/PlayerInteractEvent.php diff --git a/src/pocketmine/event/player/PlayerItemConsumeEvent.php b/src/event/player/PlayerItemConsumeEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerItemConsumeEvent.php rename to src/event/player/PlayerItemConsumeEvent.php diff --git a/src/pocketmine/event/player/PlayerItemHeldEvent.php b/src/event/player/PlayerItemHeldEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerItemHeldEvent.php rename to src/event/player/PlayerItemHeldEvent.php diff --git a/src/pocketmine/event/player/PlayerItemUseEvent.php b/src/event/player/PlayerItemUseEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerItemUseEvent.php rename to src/event/player/PlayerItemUseEvent.php diff --git a/src/pocketmine/event/player/PlayerJoinEvent.php b/src/event/player/PlayerJoinEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerJoinEvent.php rename to src/event/player/PlayerJoinEvent.php diff --git a/src/pocketmine/event/player/PlayerJumpEvent.php b/src/event/player/PlayerJumpEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerJumpEvent.php rename to src/event/player/PlayerJumpEvent.php diff --git a/src/pocketmine/event/player/PlayerKickEvent.php b/src/event/player/PlayerKickEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerKickEvent.php rename to src/event/player/PlayerKickEvent.php diff --git a/src/pocketmine/event/player/PlayerLoginEvent.php b/src/event/player/PlayerLoginEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerLoginEvent.php rename to src/event/player/PlayerLoginEvent.php diff --git a/src/pocketmine/event/player/PlayerMoveEvent.php b/src/event/player/PlayerMoveEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerMoveEvent.php rename to src/event/player/PlayerMoveEvent.php diff --git a/src/pocketmine/event/player/PlayerPreLoginEvent.php b/src/event/player/PlayerPreLoginEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerPreLoginEvent.php rename to src/event/player/PlayerPreLoginEvent.php diff --git a/src/pocketmine/event/player/PlayerQuitEvent.php b/src/event/player/PlayerQuitEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerQuitEvent.php rename to src/event/player/PlayerQuitEvent.php diff --git a/src/pocketmine/event/player/PlayerRespawnEvent.php b/src/event/player/PlayerRespawnEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerRespawnEvent.php rename to src/event/player/PlayerRespawnEvent.php diff --git a/src/pocketmine/event/player/PlayerToggleFlightEvent.php b/src/event/player/PlayerToggleFlightEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerToggleFlightEvent.php rename to src/event/player/PlayerToggleFlightEvent.php diff --git a/src/pocketmine/event/player/PlayerToggleSneakEvent.php b/src/event/player/PlayerToggleSneakEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerToggleSneakEvent.php rename to src/event/player/PlayerToggleSneakEvent.php diff --git a/src/pocketmine/event/player/PlayerToggleSprintEvent.php b/src/event/player/PlayerToggleSprintEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerToggleSprintEvent.php rename to src/event/player/PlayerToggleSprintEvent.php diff --git a/src/pocketmine/event/player/PlayerTransferEvent.php b/src/event/player/PlayerTransferEvent.php similarity index 100% rename from src/pocketmine/event/player/PlayerTransferEvent.php rename to src/event/player/PlayerTransferEvent.php diff --git a/src/pocketmine/event/plugin/PluginDisableEvent.php b/src/event/plugin/PluginDisableEvent.php similarity index 100% rename from src/pocketmine/event/plugin/PluginDisableEvent.php rename to src/event/plugin/PluginDisableEvent.php diff --git a/src/pocketmine/event/plugin/PluginEnableEvent.php b/src/event/plugin/PluginEnableEvent.php similarity index 100% rename from src/pocketmine/event/plugin/PluginEnableEvent.php rename to src/event/plugin/PluginEnableEvent.php diff --git a/src/pocketmine/event/plugin/PluginEvent.php b/src/event/plugin/PluginEvent.php similarity index 100% rename from src/pocketmine/event/plugin/PluginEvent.php rename to src/event/plugin/PluginEvent.php diff --git a/src/pocketmine/event/server/CommandEvent.php b/src/event/server/CommandEvent.php similarity index 100% rename from src/pocketmine/event/server/CommandEvent.php rename to src/event/server/CommandEvent.php diff --git a/src/pocketmine/event/server/DataPacketBroadcastEvent.php b/src/event/server/DataPacketBroadcastEvent.php similarity index 100% rename from src/pocketmine/event/server/DataPacketBroadcastEvent.php rename to src/event/server/DataPacketBroadcastEvent.php diff --git a/src/pocketmine/event/server/DataPacketReceiveEvent.php b/src/event/server/DataPacketReceiveEvent.php similarity index 100% rename from src/pocketmine/event/server/DataPacketReceiveEvent.php rename to src/event/server/DataPacketReceiveEvent.php diff --git a/src/pocketmine/event/server/DataPacketSendEvent.php b/src/event/server/DataPacketSendEvent.php similarity index 100% rename from src/pocketmine/event/server/DataPacketSendEvent.php rename to src/event/server/DataPacketSendEvent.php diff --git a/src/pocketmine/event/server/LowMemoryEvent.php b/src/event/server/LowMemoryEvent.php similarity index 100% rename from src/pocketmine/event/server/LowMemoryEvent.php rename to src/event/server/LowMemoryEvent.php diff --git a/src/pocketmine/event/server/NetworkInterfaceEvent.php b/src/event/server/NetworkInterfaceEvent.php similarity index 100% rename from src/pocketmine/event/server/NetworkInterfaceEvent.php rename to src/event/server/NetworkInterfaceEvent.php diff --git a/src/pocketmine/event/server/NetworkInterfaceRegisterEvent.php b/src/event/server/NetworkInterfaceRegisterEvent.php similarity index 100% rename from src/pocketmine/event/server/NetworkInterfaceRegisterEvent.php rename to src/event/server/NetworkInterfaceRegisterEvent.php diff --git a/src/pocketmine/event/server/NetworkInterfaceUnregisterEvent.php b/src/event/server/NetworkInterfaceUnregisterEvent.php similarity index 100% rename from src/pocketmine/event/server/NetworkInterfaceUnregisterEvent.php rename to src/event/server/NetworkInterfaceUnregisterEvent.php diff --git a/src/pocketmine/event/server/QueryRegenerateEvent.php b/src/event/server/QueryRegenerateEvent.php similarity index 100% rename from src/pocketmine/event/server/QueryRegenerateEvent.php rename to src/event/server/QueryRegenerateEvent.php diff --git a/src/pocketmine/event/server/ServerEvent.php b/src/event/server/ServerEvent.php similarity index 100% rename from src/pocketmine/event/server/ServerEvent.php rename to src/event/server/ServerEvent.php diff --git a/src/pocketmine/event/server/UpdateNotifyEvent.php b/src/event/server/UpdateNotifyEvent.php similarity index 100% rename from src/pocketmine/event/server/UpdateNotifyEvent.php rename to src/event/server/UpdateNotifyEvent.php diff --git a/src/pocketmine/event/world/ChunkEvent.php b/src/event/world/ChunkEvent.php similarity index 100% rename from src/pocketmine/event/world/ChunkEvent.php rename to src/event/world/ChunkEvent.php diff --git a/src/pocketmine/event/world/ChunkLoadEvent.php b/src/event/world/ChunkLoadEvent.php similarity index 100% rename from src/pocketmine/event/world/ChunkLoadEvent.php rename to src/event/world/ChunkLoadEvent.php diff --git a/src/pocketmine/event/world/ChunkPopulateEvent.php b/src/event/world/ChunkPopulateEvent.php similarity index 100% rename from src/pocketmine/event/world/ChunkPopulateEvent.php rename to src/event/world/ChunkPopulateEvent.php diff --git a/src/pocketmine/event/world/ChunkUnloadEvent.php b/src/event/world/ChunkUnloadEvent.php similarity index 100% rename from src/pocketmine/event/world/ChunkUnloadEvent.php rename to src/event/world/ChunkUnloadEvent.php diff --git a/src/pocketmine/event/world/SpawnChangeEvent.php b/src/event/world/SpawnChangeEvent.php similarity index 100% rename from src/pocketmine/event/world/SpawnChangeEvent.php rename to src/event/world/SpawnChangeEvent.php diff --git a/src/pocketmine/event/world/WorldEvent.php b/src/event/world/WorldEvent.php similarity index 100% rename from src/pocketmine/event/world/WorldEvent.php rename to src/event/world/WorldEvent.php diff --git a/src/pocketmine/event/world/WorldInitEvent.php b/src/event/world/WorldInitEvent.php similarity index 100% rename from src/pocketmine/event/world/WorldInitEvent.php rename to src/event/world/WorldInitEvent.php diff --git a/src/pocketmine/event/world/WorldLoadEvent.php b/src/event/world/WorldLoadEvent.php similarity index 100% rename from src/pocketmine/event/world/WorldLoadEvent.php rename to src/event/world/WorldLoadEvent.php diff --git a/src/pocketmine/event/world/WorldSaveEvent.php b/src/event/world/WorldSaveEvent.php similarity index 100% rename from src/pocketmine/event/world/WorldSaveEvent.php rename to src/event/world/WorldSaveEvent.php diff --git a/src/pocketmine/event/world/WorldUnloadEvent.php b/src/event/world/WorldUnloadEvent.php similarity index 100% rename from src/pocketmine/event/world/WorldUnloadEvent.php rename to src/event/world/WorldUnloadEvent.php diff --git a/src/pocketmine/form/Form.php b/src/form/Form.php similarity index 100% rename from src/pocketmine/form/Form.php rename to src/form/Form.php diff --git a/src/pocketmine/form/FormValidationException.php b/src/form/FormValidationException.php similarity index 100% rename from src/pocketmine/form/FormValidationException.php rename to src/form/FormValidationException.php diff --git a/src/pocketmine/inventory/AnvilInventory.php b/src/inventory/AnvilInventory.php similarity index 100% rename from src/pocketmine/inventory/AnvilInventory.php rename to src/inventory/AnvilInventory.php diff --git a/src/pocketmine/inventory/ArmorInventory.php b/src/inventory/ArmorInventory.php similarity index 100% rename from src/pocketmine/inventory/ArmorInventory.php rename to src/inventory/ArmorInventory.php diff --git a/src/pocketmine/inventory/BaseInventory.php b/src/inventory/BaseInventory.php similarity index 100% rename from src/pocketmine/inventory/BaseInventory.php rename to src/inventory/BaseInventory.php diff --git a/src/pocketmine/inventory/BlockInventory.php b/src/inventory/BlockInventory.php similarity index 100% rename from src/pocketmine/inventory/BlockInventory.php rename to src/inventory/BlockInventory.php diff --git a/src/pocketmine/inventory/BrewingStandInventory.php b/src/inventory/BrewingStandInventory.php similarity index 100% rename from src/pocketmine/inventory/BrewingStandInventory.php rename to src/inventory/BrewingStandInventory.php diff --git a/src/pocketmine/inventory/CallbackInventoryChangeListener.php b/src/inventory/CallbackInventoryChangeListener.php similarity index 100% rename from src/pocketmine/inventory/CallbackInventoryChangeListener.php rename to src/inventory/CallbackInventoryChangeListener.php diff --git a/src/pocketmine/inventory/ChestInventory.php b/src/inventory/ChestInventory.php similarity index 100% rename from src/pocketmine/inventory/ChestInventory.php rename to src/inventory/ChestInventory.php diff --git a/src/pocketmine/inventory/CreativeInventory.php b/src/inventory/CreativeInventory.php similarity index 100% rename from src/pocketmine/inventory/CreativeInventory.php rename to src/inventory/CreativeInventory.php diff --git a/src/pocketmine/inventory/DoubleChestInventory.php b/src/inventory/DoubleChestInventory.php similarity index 100% rename from src/pocketmine/inventory/DoubleChestInventory.php rename to src/inventory/DoubleChestInventory.php diff --git a/src/pocketmine/inventory/EnchantInventory.php b/src/inventory/EnchantInventory.php similarity index 100% rename from src/pocketmine/inventory/EnchantInventory.php rename to src/inventory/EnchantInventory.php diff --git a/src/pocketmine/inventory/EnderChestInventory.php b/src/inventory/EnderChestInventory.php similarity index 100% rename from src/pocketmine/inventory/EnderChestInventory.php rename to src/inventory/EnderChestInventory.php diff --git a/src/pocketmine/inventory/FurnaceInventory.php b/src/inventory/FurnaceInventory.php similarity index 100% rename from src/pocketmine/inventory/FurnaceInventory.php rename to src/inventory/FurnaceInventory.php diff --git a/src/pocketmine/inventory/HopperInventory.php b/src/inventory/HopperInventory.php similarity index 100% rename from src/pocketmine/inventory/HopperInventory.php rename to src/inventory/HopperInventory.php diff --git a/src/pocketmine/inventory/Inventory.php b/src/inventory/Inventory.php similarity index 100% rename from src/pocketmine/inventory/Inventory.php rename to src/inventory/Inventory.php diff --git a/src/pocketmine/inventory/InventoryChangeListener.php b/src/inventory/InventoryChangeListener.php similarity index 100% rename from src/pocketmine/inventory/InventoryChangeListener.php rename to src/inventory/InventoryChangeListener.php diff --git a/src/pocketmine/inventory/InventoryHolder.php b/src/inventory/InventoryHolder.php similarity index 100% rename from src/pocketmine/inventory/InventoryHolder.php rename to src/inventory/InventoryHolder.php diff --git a/src/pocketmine/inventory/PlayerCursorInventory.php b/src/inventory/PlayerCursorInventory.php similarity index 100% rename from src/pocketmine/inventory/PlayerCursorInventory.php rename to src/inventory/PlayerCursorInventory.php diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/inventory/PlayerInventory.php similarity index 100% rename from src/pocketmine/inventory/PlayerInventory.php rename to src/inventory/PlayerInventory.php diff --git a/src/pocketmine/inventory/transaction/CraftingTransaction.php b/src/inventory/transaction/CraftingTransaction.php similarity index 100% rename from src/pocketmine/inventory/transaction/CraftingTransaction.php rename to src/inventory/transaction/CraftingTransaction.php diff --git a/src/pocketmine/inventory/transaction/InventoryTransaction.php b/src/inventory/transaction/InventoryTransaction.php similarity index 100% rename from src/pocketmine/inventory/transaction/InventoryTransaction.php rename to src/inventory/transaction/InventoryTransaction.php diff --git a/src/pocketmine/inventory/transaction/TransactionValidationException.php b/src/inventory/transaction/TransactionValidationException.php similarity index 100% rename from src/pocketmine/inventory/transaction/TransactionValidationException.php rename to src/inventory/transaction/TransactionValidationException.php diff --git a/src/pocketmine/inventory/transaction/action/CreateItemAction.php b/src/inventory/transaction/action/CreateItemAction.php similarity index 100% rename from src/pocketmine/inventory/transaction/action/CreateItemAction.php rename to src/inventory/transaction/action/CreateItemAction.php diff --git a/src/pocketmine/inventory/transaction/action/DestroyItemAction.php b/src/inventory/transaction/action/DestroyItemAction.php similarity index 100% rename from src/pocketmine/inventory/transaction/action/DestroyItemAction.php rename to src/inventory/transaction/action/DestroyItemAction.php diff --git a/src/pocketmine/inventory/transaction/action/DropItemAction.php b/src/inventory/transaction/action/DropItemAction.php similarity index 100% rename from src/pocketmine/inventory/transaction/action/DropItemAction.php rename to src/inventory/transaction/action/DropItemAction.php diff --git a/src/pocketmine/inventory/transaction/action/InventoryAction.php b/src/inventory/transaction/action/InventoryAction.php similarity index 100% rename from src/pocketmine/inventory/transaction/action/InventoryAction.php rename to src/inventory/transaction/action/InventoryAction.php diff --git a/src/pocketmine/inventory/transaction/action/SlotChangeAction.php b/src/inventory/transaction/action/SlotChangeAction.php similarity index 100% rename from src/pocketmine/inventory/transaction/action/SlotChangeAction.php rename to src/inventory/transaction/action/SlotChangeAction.php diff --git a/src/pocketmine/item/Apple.php b/src/item/Apple.php similarity index 100% rename from src/pocketmine/item/Apple.php rename to src/item/Apple.php diff --git a/src/pocketmine/item/Armor.php b/src/item/Armor.php similarity index 100% rename from src/pocketmine/item/Armor.php rename to src/item/Armor.php diff --git a/src/pocketmine/item/ArmorTypeInfo.php b/src/item/ArmorTypeInfo.php similarity index 100% rename from src/pocketmine/item/ArmorTypeInfo.php rename to src/item/ArmorTypeInfo.php diff --git a/src/pocketmine/item/Arrow.php b/src/item/Arrow.php similarity index 100% rename from src/pocketmine/item/Arrow.php rename to src/item/Arrow.php diff --git a/src/pocketmine/item/Axe.php b/src/item/Axe.php similarity index 100% rename from src/pocketmine/item/Axe.php rename to src/item/Axe.php diff --git a/src/pocketmine/item/BakedPotato.php b/src/item/BakedPotato.php similarity index 100% rename from src/pocketmine/item/BakedPotato.php rename to src/item/BakedPotato.php diff --git a/src/pocketmine/item/Banner.php b/src/item/Banner.php similarity index 100% rename from src/pocketmine/item/Banner.php rename to src/item/Banner.php diff --git a/src/pocketmine/item/Bed.php b/src/item/Bed.php similarity index 100% rename from src/pocketmine/item/Bed.php rename to src/item/Bed.php diff --git a/src/pocketmine/item/Beetroot.php b/src/item/Beetroot.php similarity index 100% rename from src/pocketmine/item/Beetroot.php rename to src/item/Beetroot.php diff --git a/src/pocketmine/item/BeetrootSeeds.php b/src/item/BeetrootSeeds.php similarity index 100% rename from src/pocketmine/item/BeetrootSeeds.php rename to src/item/BeetrootSeeds.php diff --git a/src/pocketmine/item/BeetrootSoup.php b/src/item/BeetrootSoup.php similarity index 100% rename from src/pocketmine/item/BeetrootSoup.php rename to src/item/BeetrootSoup.php diff --git a/src/pocketmine/item/BlazeRod.php b/src/item/BlazeRod.php similarity index 100% rename from src/pocketmine/item/BlazeRod.php rename to src/item/BlazeRod.php diff --git a/src/pocketmine/item/Boat.php b/src/item/Boat.php similarity index 100% rename from src/pocketmine/item/Boat.php rename to src/item/Boat.php diff --git a/src/pocketmine/item/Book.php b/src/item/Book.php similarity index 100% rename from src/pocketmine/item/Book.php rename to src/item/Book.php diff --git a/src/pocketmine/item/Boots.php b/src/item/Boots.php similarity index 100% rename from src/pocketmine/item/Boots.php rename to src/item/Boots.php diff --git a/src/pocketmine/item/Bow.php b/src/item/Bow.php similarity index 100% rename from src/pocketmine/item/Bow.php rename to src/item/Bow.php diff --git a/src/pocketmine/item/Bowl.php b/src/item/Bowl.php similarity index 100% rename from src/pocketmine/item/Bowl.php rename to src/item/Bowl.php diff --git a/src/pocketmine/item/Bread.php b/src/item/Bread.php similarity index 100% rename from src/pocketmine/item/Bread.php rename to src/item/Bread.php diff --git a/src/pocketmine/item/Bucket.php b/src/item/Bucket.php similarity index 100% rename from src/pocketmine/item/Bucket.php rename to src/item/Bucket.php diff --git a/src/pocketmine/item/Carrot.php b/src/item/Carrot.php similarity index 100% rename from src/pocketmine/item/Carrot.php rename to src/item/Carrot.php diff --git a/src/pocketmine/item/Chestplate.php b/src/item/Chestplate.php similarity index 100% rename from src/pocketmine/item/Chestplate.php rename to src/item/Chestplate.php diff --git a/src/pocketmine/item/ChorusFruit.php b/src/item/ChorusFruit.php similarity index 100% rename from src/pocketmine/item/ChorusFruit.php rename to src/item/ChorusFruit.php diff --git a/src/pocketmine/item/Clock.php b/src/item/Clock.php similarity index 100% rename from src/pocketmine/item/Clock.php rename to src/item/Clock.php diff --git a/src/pocketmine/item/Clownfish.php b/src/item/Clownfish.php similarity index 100% rename from src/pocketmine/item/Clownfish.php rename to src/item/Clownfish.php diff --git a/src/pocketmine/item/Coal.php b/src/item/Coal.php similarity index 100% rename from src/pocketmine/item/Coal.php rename to src/item/Coal.php diff --git a/src/pocketmine/item/CocoaBeans.php b/src/item/CocoaBeans.php similarity index 100% rename from src/pocketmine/item/CocoaBeans.php rename to src/item/CocoaBeans.php diff --git a/src/pocketmine/item/Compass.php b/src/item/Compass.php similarity index 100% rename from src/pocketmine/item/Compass.php rename to src/item/Compass.php diff --git a/src/pocketmine/item/Consumable.php b/src/item/Consumable.php similarity index 100% rename from src/pocketmine/item/Consumable.php rename to src/item/Consumable.php diff --git a/src/pocketmine/item/CookedChicken.php b/src/item/CookedChicken.php similarity index 100% rename from src/pocketmine/item/CookedChicken.php rename to src/item/CookedChicken.php diff --git a/src/pocketmine/item/CookedFish.php b/src/item/CookedFish.php similarity index 100% rename from src/pocketmine/item/CookedFish.php rename to src/item/CookedFish.php diff --git a/src/pocketmine/item/CookedMutton.php b/src/item/CookedMutton.php similarity index 100% rename from src/pocketmine/item/CookedMutton.php rename to src/item/CookedMutton.php diff --git a/src/pocketmine/item/CookedPorkchop.php b/src/item/CookedPorkchop.php similarity index 100% rename from src/pocketmine/item/CookedPorkchop.php rename to src/item/CookedPorkchop.php diff --git a/src/pocketmine/item/CookedRabbit.php b/src/item/CookedRabbit.php similarity index 100% rename from src/pocketmine/item/CookedRabbit.php rename to src/item/CookedRabbit.php diff --git a/src/pocketmine/item/CookedSalmon.php b/src/item/CookedSalmon.php similarity index 100% rename from src/pocketmine/item/CookedSalmon.php rename to src/item/CookedSalmon.php diff --git a/src/pocketmine/item/Cookie.php b/src/item/Cookie.php similarity index 100% rename from src/pocketmine/item/Cookie.php rename to src/item/Cookie.php diff --git a/src/pocketmine/item/DriedKelp.php b/src/item/DriedKelp.php similarity index 100% rename from src/pocketmine/item/DriedKelp.php rename to src/item/DriedKelp.php diff --git a/src/pocketmine/item/Durable.php b/src/item/Durable.php similarity index 100% rename from src/pocketmine/item/Durable.php rename to src/item/Durable.php diff --git a/src/pocketmine/item/Dye.php b/src/item/Dye.php similarity index 100% rename from src/pocketmine/item/Dye.php rename to src/item/Dye.php diff --git a/src/pocketmine/item/Egg.php b/src/item/Egg.php similarity index 100% rename from src/pocketmine/item/Egg.php rename to src/item/Egg.php diff --git a/src/pocketmine/item/EnderPearl.php b/src/item/EnderPearl.php similarity index 100% rename from src/pocketmine/item/EnderPearl.php rename to src/item/EnderPearl.php diff --git a/src/pocketmine/item/ExperienceBottle.php b/src/item/ExperienceBottle.php similarity index 100% rename from src/pocketmine/item/ExperienceBottle.php rename to src/item/ExperienceBottle.php diff --git a/src/pocketmine/item/Fertilizer.php b/src/item/Fertilizer.php similarity index 100% rename from src/pocketmine/item/Fertilizer.php rename to src/item/Fertilizer.php diff --git a/src/pocketmine/item/FishingRod.php b/src/item/FishingRod.php similarity index 100% rename from src/pocketmine/item/FishingRod.php rename to src/item/FishingRod.php diff --git a/src/pocketmine/item/FlintSteel.php b/src/item/FlintSteel.php similarity index 100% rename from src/pocketmine/item/FlintSteel.php rename to src/item/FlintSteel.php diff --git a/src/pocketmine/item/Food.php b/src/item/Food.php similarity index 100% rename from src/pocketmine/item/Food.php rename to src/item/Food.php diff --git a/src/pocketmine/item/FoodSource.php b/src/item/FoodSource.php similarity index 100% rename from src/pocketmine/item/FoodSource.php rename to src/item/FoodSource.php diff --git a/src/pocketmine/item/GlassBottle.php b/src/item/GlassBottle.php similarity index 100% rename from src/pocketmine/item/GlassBottle.php rename to src/item/GlassBottle.php diff --git a/src/pocketmine/item/GoldenApple.php b/src/item/GoldenApple.php similarity index 100% rename from src/pocketmine/item/GoldenApple.php rename to src/item/GoldenApple.php diff --git a/src/pocketmine/item/GoldenAppleEnchanted.php b/src/item/GoldenAppleEnchanted.php similarity index 100% rename from src/pocketmine/item/GoldenAppleEnchanted.php rename to src/item/GoldenAppleEnchanted.php diff --git a/src/pocketmine/item/GoldenCarrot.php b/src/item/GoldenCarrot.php similarity index 100% rename from src/pocketmine/item/GoldenCarrot.php rename to src/item/GoldenCarrot.php diff --git a/src/pocketmine/item/Helmet.php b/src/item/Helmet.php similarity index 100% rename from src/pocketmine/item/Helmet.php rename to src/item/Helmet.php diff --git a/src/pocketmine/item/Hoe.php b/src/item/Hoe.php similarity index 100% rename from src/pocketmine/item/Hoe.php rename to src/item/Hoe.php diff --git a/src/pocketmine/item/Item.php b/src/item/Item.php similarity index 100% rename from src/pocketmine/item/Item.php rename to src/item/Item.php diff --git a/src/pocketmine/item/ItemBlock.php b/src/item/ItemBlock.php similarity index 100% rename from src/pocketmine/item/ItemBlock.php rename to src/item/ItemBlock.php diff --git a/src/pocketmine/item/ItemEnchantmentHandlingTrait.php b/src/item/ItemEnchantmentHandlingTrait.php similarity index 100% rename from src/pocketmine/item/ItemEnchantmentHandlingTrait.php rename to src/item/ItemEnchantmentHandlingTrait.php diff --git a/src/pocketmine/item/ItemFactory.php b/src/item/ItemFactory.php similarity index 100% rename from src/pocketmine/item/ItemFactory.php rename to src/item/ItemFactory.php diff --git a/src/pocketmine/item/ItemIds.php b/src/item/ItemIds.php similarity index 100% rename from src/pocketmine/item/ItemIds.php rename to src/item/ItemIds.php diff --git a/src/pocketmine/item/ItemUseResult.php b/src/item/ItemUseResult.php similarity index 100% rename from src/pocketmine/item/ItemUseResult.php rename to src/item/ItemUseResult.php diff --git a/src/pocketmine/item/Leggings.php b/src/item/Leggings.php similarity index 100% rename from src/pocketmine/item/Leggings.php rename to src/item/Leggings.php diff --git a/src/pocketmine/item/LiquidBucket.php b/src/item/LiquidBucket.php similarity index 100% rename from src/pocketmine/item/LiquidBucket.php rename to src/item/LiquidBucket.php diff --git a/src/pocketmine/item/Melon.php b/src/item/Melon.php similarity index 100% rename from src/pocketmine/item/Melon.php rename to src/item/Melon.php diff --git a/src/pocketmine/item/MelonSeeds.php b/src/item/MelonSeeds.php similarity index 100% rename from src/pocketmine/item/MelonSeeds.php rename to src/item/MelonSeeds.php diff --git a/src/pocketmine/item/MilkBucket.php b/src/item/MilkBucket.php similarity index 100% rename from src/pocketmine/item/MilkBucket.php rename to src/item/MilkBucket.php diff --git a/src/pocketmine/item/Minecart.php b/src/item/Minecart.php similarity index 100% rename from src/pocketmine/item/Minecart.php rename to src/item/Minecart.php diff --git a/src/pocketmine/item/MushroomStew.php b/src/item/MushroomStew.php similarity index 100% rename from src/pocketmine/item/MushroomStew.php rename to src/item/MushroomStew.php diff --git a/src/pocketmine/item/PaintingItem.php b/src/item/PaintingItem.php similarity index 100% rename from src/pocketmine/item/PaintingItem.php rename to src/item/PaintingItem.php diff --git a/src/pocketmine/item/Pickaxe.php b/src/item/Pickaxe.php similarity index 100% rename from src/pocketmine/item/Pickaxe.php rename to src/item/Pickaxe.php diff --git a/src/pocketmine/item/PoisonousPotato.php b/src/item/PoisonousPotato.php similarity index 100% rename from src/pocketmine/item/PoisonousPotato.php rename to src/item/PoisonousPotato.php diff --git a/src/pocketmine/item/Potato.php b/src/item/Potato.php similarity index 100% rename from src/pocketmine/item/Potato.php rename to src/item/Potato.php diff --git a/src/pocketmine/item/Potion.php b/src/item/Potion.php similarity index 100% rename from src/pocketmine/item/Potion.php rename to src/item/Potion.php diff --git a/src/pocketmine/item/ProjectileItem.php b/src/item/ProjectileItem.php similarity index 100% rename from src/pocketmine/item/ProjectileItem.php rename to src/item/ProjectileItem.php diff --git a/src/pocketmine/item/Pufferfish.php b/src/item/Pufferfish.php similarity index 100% rename from src/pocketmine/item/Pufferfish.php rename to src/item/Pufferfish.php diff --git a/src/pocketmine/item/PumpkinPie.php b/src/item/PumpkinPie.php similarity index 100% rename from src/pocketmine/item/PumpkinPie.php rename to src/item/PumpkinPie.php diff --git a/src/pocketmine/item/PumpkinSeeds.php b/src/item/PumpkinSeeds.php similarity index 100% rename from src/pocketmine/item/PumpkinSeeds.php rename to src/item/PumpkinSeeds.php diff --git a/src/pocketmine/item/RabbitStew.php b/src/item/RabbitStew.php similarity index 100% rename from src/pocketmine/item/RabbitStew.php rename to src/item/RabbitStew.php diff --git a/src/pocketmine/item/RawBeef.php b/src/item/RawBeef.php similarity index 100% rename from src/pocketmine/item/RawBeef.php rename to src/item/RawBeef.php diff --git a/src/pocketmine/item/RawChicken.php b/src/item/RawChicken.php similarity index 100% rename from src/pocketmine/item/RawChicken.php rename to src/item/RawChicken.php diff --git a/src/pocketmine/item/RawFish.php b/src/item/RawFish.php similarity index 100% rename from src/pocketmine/item/RawFish.php rename to src/item/RawFish.php diff --git a/src/pocketmine/item/RawMutton.php b/src/item/RawMutton.php similarity index 100% rename from src/pocketmine/item/RawMutton.php rename to src/item/RawMutton.php diff --git a/src/pocketmine/item/RawPorkchop.php b/src/item/RawPorkchop.php similarity index 100% rename from src/pocketmine/item/RawPorkchop.php rename to src/item/RawPorkchop.php diff --git a/src/pocketmine/item/RawRabbit.php b/src/item/RawRabbit.php similarity index 100% rename from src/pocketmine/item/RawRabbit.php rename to src/item/RawRabbit.php diff --git a/src/pocketmine/item/RawSalmon.php b/src/item/RawSalmon.php similarity index 100% rename from src/pocketmine/item/RawSalmon.php rename to src/item/RawSalmon.php diff --git a/src/pocketmine/item/Redstone.php b/src/item/Redstone.php similarity index 100% rename from src/pocketmine/item/Redstone.php rename to src/item/Redstone.php diff --git a/src/pocketmine/item/RottenFlesh.php b/src/item/RottenFlesh.php similarity index 100% rename from src/pocketmine/item/RottenFlesh.php rename to src/item/RottenFlesh.php diff --git a/src/pocketmine/item/Shears.php b/src/item/Shears.php similarity index 100% rename from src/pocketmine/item/Shears.php rename to src/item/Shears.php diff --git a/src/pocketmine/item/Shovel.php b/src/item/Shovel.php similarity index 100% rename from src/pocketmine/item/Shovel.php rename to src/item/Shovel.php diff --git a/src/pocketmine/item/Sign.php b/src/item/Sign.php similarity index 100% rename from src/pocketmine/item/Sign.php rename to src/item/Sign.php diff --git a/src/pocketmine/item/Skull.php b/src/item/Skull.php similarity index 100% rename from src/pocketmine/item/Skull.php rename to src/item/Skull.php diff --git a/src/pocketmine/item/Snowball.php b/src/item/Snowball.php similarity index 100% rename from src/pocketmine/item/Snowball.php rename to src/item/Snowball.php diff --git a/src/pocketmine/item/SpawnEgg.php b/src/item/SpawnEgg.php similarity index 100% rename from src/pocketmine/item/SpawnEgg.php rename to src/item/SpawnEgg.php diff --git a/src/pocketmine/item/SpiderEye.php b/src/item/SpiderEye.php similarity index 100% rename from src/pocketmine/item/SpiderEye.php rename to src/item/SpiderEye.php diff --git a/src/pocketmine/item/SplashPotion.php b/src/item/SplashPotion.php similarity index 100% rename from src/pocketmine/item/SplashPotion.php rename to src/item/SplashPotion.php diff --git a/src/pocketmine/item/Steak.php b/src/item/Steak.php similarity index 100% rename from src/pocketmine/item/Steak.php rename to src/item/Steak.php diff --git a/src/pocketmine/item/Stick.php b/src/item/Stick.php similarity index 100% rename from src/pocketmine/item/Stick.php rename to src/item/Stick.php diff --git a/src/pocketmine/item/StringItem.php b/src/item/StringItem.php similarity index 100% rename from src/pocketmine/item/StringItem.php rename to src/item/StringItem.php diff --git a/src/pocketmine/item/Sword.php b/src/item/Sword.php similarity index 100% rename from src/pocketmine/item/Sword.php rename to src/item/Sword.php diff --git a/src/pocketmine/item/TieredTool.php b/src/item/TieredTool.php similarity index 100% rename from src/pocketmine/item/TieredTool.php rename to src/item/TieredTool.php diff --git a/src/pocketmine/item/Tool.php b/src/item/Tool.php similarity index 100% rename from src/pocketmine/item/Tool.php rename to src/item/Tool.php diff --git a/src/pocketmine/item/ToolTier.php b/src/item/ToolTier.php similarity index 100% rename from src/pocketmine/item/ToolTier.php rename to src/item/ToolTier.php diff --git a/src/pocketmine/item/Totem.php b/src/item/Totem.php similarity index 100% rename from src/pocketmine/item/Totem.php rename to src/item/Totem.php diff --git a/src/pocketmine/item/VanillaItems.php b/src/item/VanillaItems.php similarity index 100% rename from src/pocketmine/item/VanillaItems.php rename to src/item/VanillaItems.php diff --git a/src/pocketmine/item/WheatSeeds.php b/src/item/WheatSeeds.php similarity index 100% rename from src/pocketmine/item/WheatSeeds.php rename to src/item/WheatSeeds.php diff --git a/src/pocketmine/item/WritableBook.php b/src/item/WritableBook.php similarity index 100% rename from src/pocketmine/item/WritableBook.php rename to src/item/WritableBook.php diff --git a/src/pocketmine/item/WritableBookBase.php b/src/item/WritableBookBase.php similarity index 100% rename from src/pocketmine/item/WritableBookBase.php rename to src/item/WritableBookBase.php diff --git a/src/pocketmine/item/WritableBookPage.php b/src/item/WritableBookPage.php similarity index 100% rename from src/pocketmine/item/WritableBookPage.php rename to src/item/WritableBookPage.php diff --git a/src/pocketmine/item/WrittenBook.php b/src/item/WrittenBook.php similarity index 100% rename from src/pocketmine/item/WrittenBook.php rename to src/item/WrittenBook.php diff --git a/src/pocketmine/item/enchantment/Enchantment.php b/src/item/enchantment/Enchantment.php similarity index 100% rename from src/pocketmine/item/enchantment/Enchantment.php rename to src/item/enchantment/Enchantment.php diff --git a/src/pocketmine/item/enchantment/EnchantmentEntry.php b/src/item/enchantment/EnchantmentEntry.php similarity index 100% rename from src/pocketmine/item/enchantment/EnchantmentEntry.php rename to src/item/enchantment/EnchantmentEntry.php diff --git a/src/pocketmine/item/enchantment/EnchantmentInstance.php b/src/item/enchantment/EnchantmentInstance.php similarity index 100% rename from src/pocketmine/item/enchantment/EnchantmentInstance.php rename to src/item/enchantment/EnchantmentInstance.php diff --git a/src/pocketmine/item/enchantment/EnchantmentList.php b/src/item/enchantment/EnchantmentList.php similarity index 100% rename from src/pocketmine/item/enchantment/EnchantmentList.php rename to src/item/enchantment/EnchantmentList.php diff --git a/src/pocketmine/item/enchantment/FireAspectEnchantment.php b/src/item/enchantment/FireAspectEnchantment.php similarity index 100% rename from src/pocketmine/item/enchantment/FireAspectEnchantment.php rename to src/item/enchantment/FireAspectEnchantment.php diff --git a/src/pocketmine/item/enchantment/KnockbackEnchantment.php b/src/item/enchantment/KnockbackEnchantment.php similarity index 100% rename from src/pocketmine/item/enchantment/KnockbackEnchantment.php rename to src/item/enchantment/KnockbackEnchantment.php diff --git a/src/pocketmine/item/enchantment/MeleeWeaponEnchantment.php b/src/item/enchantment/MeleeWeaponEnchantment.php similarity index 100% rename from src/pocketmine/item/enchantment/MeleeWeaponEnchantment.php rename to src/item/enchantment/MeleeWeaponEnchantment.php diff --git a/src/pocketmine/item/enchantment/ProtectionEnchantment.php b/src/item/enchantment/ProtectionEnchantment.php similarity index 100% rename from src/pocketmine/item/enchantment/ProtectionEnchantment.php rename to src/item/enchantment/ProtectionEnchantment.php diff --git a/src/pocketmine/item/enchantment/SharpnessEnchantment.php b/src/item/enchantment/SharpnessEnchantment.php similarity index 100% rename from src/pocketmine/item/enchantment/SharpnessEnchantment.php rename to src/item/enchantment/SharpnessEnchantment.php diff --git a/src/pocketmine/lang/Language.php b/src/lang/Language.php similarity index 100% rename from src/pocketmine/lang/Language.php rename to src/lang/Language.php diff --git a/src/pocketmine/lang/LanguageNotFoundException.php b/src/lang/LanguageNotFoundException.php similarity index 100% rename from src/pocketmine/lang/LanguageNotFoundException.php rename to src/lang/LanguageNotFoundException.php diff --git a/src/pocketmine/lang/TextContainer.php b/src/lang/TextContainer.php similarity index 100% rename from src/pocketmine/lang/TextContainer.php rename to src/lang/TextContainer.php diff --git a/src/pocketmine/lang/TranslationContainer.php b/src/lang/TranslationContainer.php similarity index 100% rename from src/pocketmine/lang/TranslationContainer.php rename to src/lang/TranslationContainer.php diff --git a/src/pocketmine/network/AdvancedNetworkInterface.php b/src/network/AdvancedNetworkInterface.php similarity index 100% rename from src/pocketmine/network/AdvancedNetworkInterface.php rename to src/network/AdvancedNetworkInterface.php diff --git a/src/pocketmine/network/BadPacketException.php b/src/network/BadPacketException.php similarity index 100% rename from src/pocketmine/network/BadPacketException.php rename to src/network/BadPacketException.php diff --git a/src/pocketmine/network/Network.php b/src/network/Network.php similarity index 100% rename from src/pocketmine/network/Network.php rename to src/network/Network.php diff --git a/src/pocketmine/network/NetworkInterface.php b/src/network/NetworkInterface.php similarity index 100% rename from src/pocketmine/network/NetworkInterface.php rename to src/network/NetworkInterface.php diff --git a/src/pocketmine/network/NetworkSessionManager.php b/src/network/NetworkSessionManager.php similarity index 100% rename from src/pocketmine/network/NetworkSessionManager.php rename to src/network/NetworkSessionManager.php diff --git a/src/pocketmine/network/RawPacketHandler.php b/src/network/RawPacketHandler.php similarity index 100% rename from src/pocketmine/network/RawPacketHandler.php rename to src/network/RawPacketHandler.php diff --git a/src/pocketmine/network/mcpe/ChunkCache.php b/src/network/mcpe/ChunkCache.php similarity index 100% rename from src/pocketmine/network/mcpe/ChunkCache.php rename to src/network/mcpe/ChunkCache.php diff --git a/src/pocketmine/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php similarity index 100% rename from src/pocketmine/network/mcpe/ChunkRequestTask.php rename to src/network/mcpe/ChunkRequestTask.php diff --git a/src/pocketmine/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php similarity index 100% rename from src/pocketmine/network/mcpe/InventoryManager.php rename to src/network/mcpe/InventoryManager.php diff --git a/src/pocketmine/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php similarity index 100% rename from src/pocketmine/network/mcpe/NetworkSession.php rename to src/network/mcpe/NetworkSession.php diff --git a/src/pocketmine/network/mcpe/PacketBatch.php b/src/network/mcpe/PacketBatch.php similarity index 100% rename from src/pocketmine/network/mcpe/PacketBatch.php rename to src/network/mcpe/PacketBatch.php diff --git a/src/pocketmine/network/mcpe/PacketSender.php b/src/network/mcpe/PacketSender.php similarity index 100% rename from src/pocketmine/network/mcpe/PacketSender.php rename to src/network/mcpe/PacketSender.php diff --git a/src/pocketmine/network/mcpe/README.md b/src/network/mcpe/README.md similarity index 100% rename from src/pocketmine/network/mcpe/README.md rename to src/network/mcpe/README.md diff --git a/src/pocketmine/network/mcpe/auth/ProcessLoginTask.php b/src/network/mcpe/auth/ProcessLoginTask.php similarity index 100% rename from src/pocketmine/network/mcpe/auth/ProcessLoginTask.php rename to src/network/mcpe/auth/ProcessLoginTask.php diff --git a/src/pocketmine/network/mcpe/auth/VerifyLoginException.php b/src/network/mcpe/auth/VerifyLoginException.php similarity index 100% rename from src/pocketmine/network/mcpe/auth/VerifyLoginException.php rename to src/network/mcpe/auth/VerifyLoginException.php diff --git a/src/pocketmine/network/mcpe/compression/CompressBatchPromise.php b/src/network/mcpe/compression/CompressBatchPromise.php similarity index 100% rename from src/pocketmine/network/mcpe/compression/CompressBatchPromise.php rename to src/network/mcpe/compression/CompressBatchPromise.php diff --git a/src/pocketmine/network/mcpe/compression/CompressBatchTask.php b/src/network/mcpe/compression/CompressBatchTask.php similarity index 100% rename from src/pocketmine/network/mcpe/compression/CompressBatchTask.php rename to src/network/mcpe/compression/CompressBatchTask.php diff --git a/src/pocketmine/network/mcpe/compression/Zlib.php b/src/network/mcpe/compression/Zlib.php similarity index 100% rename from src/pocketmine/network/mcpe/compression/Zlib.php rename to src/network/mcpe/compression/Zlib.php diff --git a/src/pocketmine/network/mcpe/encryption/NetworkCipher.php b/src/network/mcpe/encryption/NetworkCipher.php similarity index 100% rename from src/pocketmine/network/mcpe/encryption/NetworkCipher.php rename to src/network/mcpe/encryption/NetworkCipher.php diff --git a/src/pocketmine/network/mcpe/encryption/PrepareEncryptionTask.php b/src/network/mcpe/encryption/PrepareEncryptionTask.php similarity index 100% rename from src/pocketmine/network/mcpe/encryption/PrepareEncryptionTask.php rename to src/network/mcpe/encryption/PrepareEncryptionTask.php diff --git a/src/pocketmine/network/mcpe/handler/DeathPacketHandler.php b/src/network/mcpe/handler/DeathPacketHandler.php similarity index 100% rename from src/pocketmine/network/mcpe/handler/DeathPacketHandler.php rename to src/network/mcpe/handler/DeathPacketHandler.php diff --git a/src/pocketmine/network/mcpe/handler/HandshakePacketHandler.php b/src/network/mcpe/handler/HandshakePacketHandler.php similarity index 100% rename from src/pocketmine/network/mcpe/handler/HandshakePacketHandler.php rename to src/network/mcpe/handler/HandshakePacketHandler.php diff --git a/src/pocketmine/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php similarity index 100% rename from src/pocketmine/network/mcpe/handler/InGamePacketHandler.php rename to src/network/mcpe/handler/InGamePacketHandler.php diff --git a/src/pocketmine/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php similarity index 100% rename from src/pocketmine/network/mcpe/handler/LoginPacketHandler.php rename to src/network/mcpe/handler/LoginPacketHandler.php diff --git a/src/pocketmine/network/mcpe/handler/NullPacketHandler.php b/src/network/mcpe/handler/NullPacketHandler.php similarity index 100% rename from src/pocketmine/network/mcpe/handler/NullPacketHandler.php rename to src/network/mcpe/handler/NullPacketHandler.php diff --git a/src/pocketmine/network/mcpe/handler/PacketHandler.php b/src/network/mcpe/handler/PacketHandler.php similarity index 100% rename from src/pocketmine/network/mcpe/handler/PacketHandler.php rename to src/network/mcpe/handler/PacketHandler.php diff --git a/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php similarity index 100% rename from src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php rename to src/network/mcpe/handler/PreSpawnPacketHandler.php diff --git a/src/pocketmine/network/mcpe/handler/ResourcePacksPacketHandler.php b/src/network/mcpe/handler/ResourcePacksPacketHandler.php similarity index 100% rename from src/pocketmine/network/mcpe/handler/ResourcePacksPacketHandler.php rename to src/network/mcpe/handler/ResourcePacksPacketHandler.php diff --git a/src/pocketmine/network/mcpe/protocol/ActorEventPacket.php b/src/network/mcpe/protocol/ActorEventPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ActorEventPacket.php rename to src/network/mcpe/protocol/ActorEventPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ActorFallPacket.php b/src/network/mcpe/protocol/ActorFallPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ActorFallPacket.php rename to src/network/mcpe/protocol/ActorFallPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ActorPickRequestPacket.php b/src/network/mcpe/protocol/ActorPickRequestPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ActorPickRequestPacket.php rename to src/network/mcpe/protocol/ActorPickRequestPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/AddActorPacket.php b/src/network/mcpe/protocol/AddActorPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/AddActorPacket.php rename to src/network/mcpe/protocol/AddActorPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php b/src/network/mcpe/protocol/AddBehaviorTreePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/AddBehaviorTreePacket.php rename to src/network/mcpe/protocol/AddBehaviorTreePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/AddEntityPacket.php b/src/network/mcpe/protocol/AddEntityPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/AddEntityPacket.php rename to src/network/mcpe/protocol/AddEntityPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/AddItemActorPacket.php b/src/network/mcpe/protocol/AddItemActorPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/AddItemActorPacket.php rename to src/network/mcpe/protocol/AddItemActorPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/AddPaintingPacket.php b/src/network/mcpe/protocol/AddPaintingPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/AddPaintingPacket.php rename to src/network/mcpe/protocol/AddPaintingPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php b/src/network/mcpe/protocol/AddPlayerPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/AddPlayerPacket.php rename to src/network/mcpe/protocol/AddPlayerPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php b/src/network/mcpe/protocol/AdventureSettingsPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/AdventureSettingsPacket.php rename to src/network/mcpe/protocol/AdventureSettingsPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/AnimatePacket.php b/src/network/mcpe/protocol/AnimatePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/AnimatePacket.php rename to src/network/mcpe/protocol/AnimatePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/AutomationClientConnectPacket.php b/src/network/mcpe/protocol/AutomationClientConnectPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/AutomationClientConnectPacket.php rename to src/network/mcpe/protocol/AutomationClientConnectPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/AvailableActorIdentifiersPacket.php b/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/AvailableActorIdentifiersPacket.php rename to src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php b/src/network/mcpe/protocol/AvailableCommandsPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/AvailableCommandsPacket.php rename to src/network/mcpe/protocol/AvailableCommandsPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/BiomeDefinitionListPacket.php b/src/network/mcpe/protocol/BiomeDefinitionListPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/BiomeDefinitionListPacket.php rename to src/network/mcpe/protocol/BiomeDefinitionListPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/BlockActorDataPacket.php b/src/network/mcpe/protocol/BlockActorDataPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/BlockActorDataPacket.php rename to src/network/mcpe/protocol/BlockActorDataPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/BlockEventPacket.php b/src/network/mcpe/protocol/BlockEventPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/BlockEventPacket.php rename to src/network/mcpe/protocol/BlockEventPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php b/src/network/mcpe/protocol/BlockPickRequestPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/BlockPickRequestPacket.php rename to src/network/mcpe/protocol/BlockPickRequestPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/BookEditPacket.php b/src/network/mcpe/protocol/BookEditPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/BookEditPacket.php rename to src/network/mcpe/protocol/BookEditPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/BossEventPacket.php b/src/network/mcpe/protocol/BossEventPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/BossEventPacket.php rename to src/network/mcpe/protocol/BossEventPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/CameraPacket.php b/src/network/mcpe/protocol/CameraPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/CameraPacket.php rename to src/network/mcpe/protocol/CameraPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ChangeDimensionPacket.php b/src/network/mcpe/protocol/ChangeDimensionPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ChangeDimensionPacket.php rename to src/network/mcpe/protocol/ChangeDimensionPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php b/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php rename to src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ClientCacheBlobStatusPacket.php b/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ClientCacheBlobStatusPacket.php rename to src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ClientCacheMissResponsePacket.php b/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ClientCacheMissResponsePacket.php rename to src/network/mcpe/protocol/ClientCacheMissResponsePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ClientCacheStatusPacket.php b/src/network/mcpe/protocol/ClientCacheStatusPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ClientCacheStatusPacket.php rename to src/network/mcpe/protocol/ClientCacheStatusPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ClientToServerHandshakePacket.php b/src/network/mcpe/protocol/ClientToServerHandshakePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ClientToServerHandshakePacket.php rename to src/network/mcpe/protocol/ClientToServerHandshakePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ClientboundMapItemDataPacket.php rename to src/network/mcpe/protocol/ClientboundMapItemDataPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ClientboundPacket.php b/src/network/mcpe/protocol/ClientboundPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ClientboundPacket.php rename to src/network/mcpe/protocol/ClientboundPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php b/src/network/mcpe/protocol/CommandBlockUpdatePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/CommandBlockUpdatePacket.php rename to src/network/mcpe/protocol/CommandBlockUpdatePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php b/src/network/mcpe/protocol/CommandOutputPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/CommandOutputPacket.php rename to src/network/mcpe/protocol/CommandOutputPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/CommandRequestPacket.php b/src/network/mcpe/protocol/CommandRequestPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/CommandRequestPacket.php rename to src/network/mcpe/protocol/CommandRequestPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php b/src/network/mcpe/protocol/ContainerClosePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ContainerClosePacket.php rename to src/network/mcpe/protocol/ContainerClosePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php b/src/network/mcpe/protocol/ContainerOpenPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ContainerOpenPacket.php rename to src/network/mcpe/protocol/ContainerOpenPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php b/src/network/mcpe/protocol/ContainerSetDataPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ContainerSetDataPacket.php rename to src/network/mcpe/protocol/ContainerSetDataPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php b/src/network/mcpe/protocol/CraftingDataPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/CraftingDataPacket.php rename to src/network/mcpe/protocol/CraftingDataPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/CraftingEventPacket.php b/src/network/mcpe/protocol/CraftingEventPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/CraftingEventPacket.php rename to src/network/mcpe/protocol/CraftingEventPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/DataPacket.php b/src/network/mcpe/protocol/DataPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/DataPacket.php rename to src/network/mcpe/protocol/DataPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/DisconnectPacket.php b/src/network/mcpe/protocol/DisconnectPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/DisconnectPacket.php rename to src/network/mcpe/protocol/DisconnectPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/EventPacket.php b/src/network/mcpe/protocol/EventPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/EventPacket.php rename to src/network/mcpe/protocol/EventPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ExplodePacket.php b/src/network/mcpe/protocol/ExplodePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ExplodePacket.php rename to src/network/mcpe/protocol/ExplodePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/GameRulesChangedPacket.php b/src/network/mcpe/protocol/GameRulesChangedPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/GameRulesChangedPacket.php rename to src/network/mcpe/protocol/GameRulesChangedPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/GarbageServerboundPacket.php b/src/network/mcpe/protocol/GarbageServerboundPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/GarbageServerboundPacket.php rename to src/network/mcpe/protocol/GarbageServerboundPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/GuiDataPickItemPacket.php b/src/network/mcpe/protocol/GuiDataPickItemPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/GuiDataPickItemPacket.php rename to src/network/mcpe/protocol/GuiDataPickItemPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/HurtArmorPacket.php b/src/network/mcpe/protocol/HurtArmorPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/HurtArmorPacket.php rename to src/network/mcpe/protocol/HurtArmorPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/InteractPacket.php b/src/network/mcpe/protocol/InteractPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/InteractPacket.php rename to src/network/mcpe/protocol/InteractPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php b/src/network/mcpe/protocol/InventoryContentPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/InventoryContentPacket.php rename to src/network/mcpe/protocol/InventoryContentPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php b/src/network/mcpe/protocol/InventorySlotPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/InventorySlotPacket.php rename to src/network/mcpe/protocol/InventorySlotPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php b/src/network/mcpe/protocol/InventoryTransactionPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/InventoryTransactionPacket.php rename to src/network/mcpe/protocol/InventoryTransactionPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ItemFrameDropItemPacket.php b/src/network/mcpe/protocol/ItemFrameDropItemPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ItemFrameDropItemPacket.php rename to src/network/mcpe/protocol/ItemFrameDropItemPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/LabTablePacket.php b/src/network/mcpe/protocol/LabTablePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/LabTablePacket.php rename to src/network/mcpe/protocol/LabTablePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/LecternUpdatePacket.php b/src/network/mcpe/protocol/LecternUpdatePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/LecternUpdatePacket.php rename to src/network/mcpe/protocol/LecternUpdatePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/LevelChunkPacket.php b/src/network/mcpe/protocol/LevelChunkPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/LevelChunkPacket.php rename to src/network/mcpe/protocol/LevelChunkPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/LevelEventGenericPacket.php b/src/network/mcpe/protocol/LevelEventGenericPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/LevelEventGenericPacket.php rename to src/network/mcpe/protocol/LevelEventGenericPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/LevelEventPacket.php b/src/network/mcpe/protocol/LevelEventPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/LevelEventPacket.php rename to src/network/mcpe/protocol/LevelEventPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacket.php b/src/network/mcpe/protocol/LevelSoundEventPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/LevelSoundEventPacket.php rename to src/network/mcpe/protocol/LevelSoundEventPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacketV1.php b/src/network/mcpe/protocol/LevelSoundEventPacketV1.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/LevelSoundEventPacketV1.php rename to src/network/mcpe/protocol/LevelSoundEventPacketV1.php diff --git a/src/pocketmine/network/mcpe/protocol/LevelSoundEventPacketV2.php b/src/network/mcpe/protocol/LevelSoundEventPacketV2.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/LevelSoundEventPacketV2.php rename to src/network/mcpe/protocol/LevelSoundEventPacketV2.php diff --git a/src/pocketmine/network/mcpe/protocol/LoginPacket.php b/src/network/mcpe/protocol/LoginPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/LoginPacket.php rename to src/network/mcpe/protocol/LoginPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/MapCreateLockedCopyPacket.php b/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/MapCreateLockedCopyPacket.php rename to src/network/mcpe/protocol/MapCreateLockedCopyPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/MapInfoRequestPacket.php b/src/network/mcpe/protocol/MapInfoRequestPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/MapInfoRequestPacket.php rename to src/network/mcpe/protocol/MapInfoRequestPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php b/src/network/mcpe/protocol/MobArmorEquipmentPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/MobArmorEquipmentPacket.php rename to src/network/mcpe/protocol/MobArmorEquipmentPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/MobEffectPacket.php b/src/network/mcpe/protocol/MobEffectPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/MobEffectPacket.php rename to src/network/mcpe/protocol/MobEffectPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php b/src/network/mcpe/protocol/MobEquipmentPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/MobEquipmentPacket.php rename to src/network/mcpe/protocol/MobEquipmentPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php b/src/network/mcpe/protocol/ModalFormRequestPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ModalFormRequestPacket.php rename to src/network/mcpe/protocol/ModalFormRequestPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ModalFormResponsePacket.php b/src/network/mcpe/protocol/ModalFormResponsePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ModalFormResponsePacket.php rename to src/network/mcpe/protocol/ModalFormResponsePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/MoveActorAbsolutePacket.php b/src/network/mcpe/protocol/MoveActorAbsolutePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/MoveActorAbsolutePacket.php rename to src/network/mcpe/protocol/MoveActorAbsolutePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/MoveActorDeltaPacket.php b/src/network/mcpe/protocol/MoveActorDeltaPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/MoveActorDeltaPacket.php rename to src/network/mcpe/protocol/MoveActorDeltaPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/MovePlayerPacket.php b/src/network/mcpe/protocol/MovePlayerPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/MovePlayerPacket.php rename to src/network/mcpe/protocol/MovePlayerPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php b/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php rename to src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/NetworkStackLatencyPacket.php b/src/network/mcpe/protocol/NetworkStackLatencyPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/NetworkStackLatencyPacket.php rename to src/network/mcpe/protocol/NetworkStackLatencyPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/NpcRequestPacket.php b/src/network/mcpe/protocol/NpcRequestPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/NpcRequestPacket.php rename to src/network/mcpe/protocol/NpcRequestPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/OnScreenTextureAnimationPacket.php b/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/OnScreenTextureAnimationPacket.php rename to src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/Packet.php b/src/network/mcpe/protocol/Packet.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/Packet.php rename to src/network/mcpe/protocol/Packet.php diff --git a/src/pocketmine/network/mcpe/protocol/PacketPool.php b/src/network/mcpe/protocol/PacketPool.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/PacketPool.php rename to src/network/mcpe/protocol/PacketPool.php diff --git a/src/pocketmine/network/mcpe/protocol/PhotoTransferPacket.php b/src/network/mcpe/protocol/PhotoTransferPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/PhotoTransferPacket.php rename to src/network/mcpe/protocol/PhotoTransferPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/PlaySoundPacket.php b/src/network/mcpe/protocol/PlaySoundPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/PlaySoundPacket.php rename to src/network/mcpe/protocol/PlaySoundPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php b/src/network/mcpe/protocol/PlayStatusPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/PlayStatusPacket.php rename to src/network/mcpe/protocol/PlayStatusPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/PlayerActionPacket.php b/src/network/mcpe/protocol/PlayerActionPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/PlayerActionPacket.php rename to src/network/mcpe/protocol/PlayerActionPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php b/src/network/mcpe/protocol/PlayerHotbarPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/PlayerHotbarPacket.php rename to src/network/mcpe/protocol/PlayerHotbarPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/PlayerInputPacket.php b/src/network/mcpe/protocol/PlayerInputPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/PlayerInputPacket.php rename to src/network/mcpe/protocol/PlayerInputPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/PlayerListPacket.php b/src/network/mcpe/protocol/PlayerListPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/PlayerListPacket.php rename to src/network/mcpe/protocol/PlayerListPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php b/src/network/mcpe/protocol/PlayerSkinPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/PlayerSkinPacket.php rename to src/network/mcpe/protocol/PlayerSkinPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ProtocolInfo.php b/src/network/mcpe/protocol/ProtocolInfo.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ProtocolInfo.php rename to src/network/mcpe/protocol/ProtocolInfo.php diff --git a/src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php b/src/network/mcpe/protocol/PurchaseReceiptPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/PurchaseReceiptPacket.php rename to src/network/mcpe/protocol/PurchaseReceiptPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/RemoveActorPacket.php b/src/network/mcpe/protocol/RemoveActorPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/RemoveActorPacket.php rename to src/network/mcpe/protocol/RemoveActorPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php b/src/network/mcpe/protocol/RemoveEntityPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/RemoveEntityPacket.php rename to src/network/mcpe/protocol/RemoveEntityPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/RemoveObjectivePacket.php b/src/network/mcpe/protocol/RemoveObjectivePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/RemoveObjectivePacket.php rename to src/network/mcpe/protocol/RemoveObjectivePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/RequestChunkRadiusPacket.php b/src/network/mcpe/protocol/RequestChunkRadiusPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/RequestChunkRadiusPacket.php rename to src/network/mcpe/protocol/RequestChunkRadiusPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php b/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ResourcePackChunkDataPacket.php rename to src/network/mcpe/protocol/ResourcePackChunkDataPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackChunkRequestPacket.php b/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ResourcePackChunkRequestPacket.php rename to src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackClientResponsePacket.php b/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ResourcePackClientResponsePacket.php rename to src/network/mcpe/protocol/ResourcePackClientResponsePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php b/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ResourcePackDataInfoPacket.php rename to src/network/mcpe/protocol/ResourcePackDataInfoPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php b/src/network/mcpe/protocol/ResourcePackStackPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ResourcePackStackPacket.php rename to src/network/mcpe/protocol/ResourcePackStackPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ResourcePacksInfoPacket.php rename to src/network/mcpe/protocol/ResourcePacksInfoPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/RespawnPacket.php b/src/network/mcpe/protocol/RespawnPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/RespawnPacket.php rename to src/network/mcpe/protocol/RespawnPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/RiderJumpPacket.php b/src/network/mcpe/protocol/RiderJumpPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/RiderJumpPacket.php rename to src/network/mcpe/protocol/RiderJumpPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ScriptCustomEventPacket.php b/src/network/mcpe/protocol/ScriptCustomEventPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ScriptCustomEventPacket.php rename to src/network/mcpe/protocol/ScriptCustomEventPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ServerSettingsRequestPacket.php b/src/network/mcpe/protocol/ServerSettingsRequestPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ServerSettingsRequestPacket.php rename to src/network/mcpe/protocol/ServerSettingsRequestPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ServerSettingsResponsePacket.php b/src/network/mcpe/protocol/ServerSettingsResponsePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ServerSettingsResponsePacket.php rename to src/network/mcpe/protocol/ServerSettingsResponsePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php b/src/network/mcpe/protocol/ServerToClientHandshakePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ServerToClientHandshakePacket.php rename to src/network/mcpe/protocol/ServerToClientHandshakePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ServerboundPacket.php b/src/network/mcpe/protocol/ServerboundPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ServerboundPacket.php rename to src/network/mcpe/protocol/ServerboundPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/SetActorDataPacket.php b/src/network/mcpe/protocol/SetActorDataPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/SetActorDataPacket.php rename to src/network/mcpe/protocol/SetActorDataPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/SetActorLinkPacket.php b/src/network/mcpe/protocol/SetActorLinkPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/SetActorLinkPacket.php rename to src/network/mcpe/protocol/SetActorLinkPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/SetActorMotionPacket.php b/src/network/mcpe/protocol/SetActorMotionPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/SetActorMotionPacket.php rename to src/network/mcpe/protocol/SetActorMotionPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/SetCommandsEnabledPacket.php b/src/network/mcpe/protocol/SetCommandsEnabledPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/SetCommandsEnabledPacket.php rename to src/network/mcpe/protocol/SetCommandsEnabledPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/SetDefaultGameTypePacket.php b/src/network/mcpe/protocol/SetDefaultGameTypePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/SetDefaultGameTypePacket.php rename to src/network/mcpe/protocol/SetDefaultGameTypePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/SetDifficultyPacket.php b/src/network/mcpe/protocol/SetDifficultyPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/SetDifficultyPacket.php rename to src/network/mcpe/protocol/SetDifficultyPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/SetDisplayObjectivePacket.php b/src/network/mcpe/protocol/SetDisplayObjectivePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/SetDisplayObjectivePacket.php rename to src/network/mcpe/protocol/SetDisplayObjectivePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/SetHealthPacket.php b/src/network/mcpe/protocol/SetHealthPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/SetHealthPacket.php rename to src/network/mcpe/protocol/SetHealthPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/SetLastHurtByPacket.php b/src/network/mcpe/protocol/SetLastHurtByPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/SetLastHurtByPacket.php rename to src/network/mcpe/protocol/SetLastHurtByPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php b/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php rename to src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php b/src/network/mcpe/protocol/SetPlayerGameTypePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/SetPlayerGameTypePacket.php rename to src/network/mcpe/protocol/SetPlayerGameTypePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/SetScorePacket.php b/src/network/mcpe/protocol/SetScorePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/SetScorePacket.php rename to src/network/mcpe/protocol/SetScorePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/SetScoreboardIdentityPacket.php b/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/SetScoreboardIdentityPacket.php rename to src/network/mcpe/protocol/SetScoreboardIdentityPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php b/src/network/mcpe/protocol/SetSpawnPositionPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/SetSpawnPositionPacket.php rename to src/network/mcpe/protocol/SetSpawnPositionPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/SetTimePacket.php b/src/network/mcpe/protocol/SetTimePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/SetTimePacket.php rename to src/network/mcpe/protocol/SetTimePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/SetTitlePacket.php b/src/network/mcpe/protocol/SetTitlePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/SetTitlePacket.php rename to src/network/mcpe/protocol/SetTitlePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ShowCreditsPacket.php b/src/network/mcpe/protocol/ShowCreditsPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ShowCreditsPacket.php rename to src/network/mcpe/protocol/ShowCreditsPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ShowProfilePacket.php b/src/network/mcpe/protocol/ShowProfilePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ShowProfilePacket.php rename to src/network/mcpe/protocol/ShowProfilePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php b/src/network/mcpe/protocol/ShowStoreOfferPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/ShowStoreOfferPacket.php rename to src/network/mcpe/protocol/ShowStoreOfferPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php b/src/network/mcpe/protocol/SimpleEventPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/SimpleEventPacket.php rename to src/network/mcpe/protocol/SimpleEventPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/SpawnExperienceOrbPacket.php b/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/SpawnExperienceOrbPacket.php rename to src/network/mcpe/protocol/SpawnExperienceOrbPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/SpawnParticleEffectPacket.php b/src/network/mcpe/protocol/SpawnParticleEffectPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/SpawnParticleEffectPacket.php rename to src/network/mcpe/protocol/SpawnParticleEffectPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/StartGamePacket.php b/src/network/mcpe/protocol/StartGamePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/StartGamePacket.php rename to src/network/mcpe/protocol/StartGamePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/StopSoundPacket.php b/src/network/mcpe/protocol/StopSoundPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/StopSoundPacket.php rename to src/network/mcpe/protocol/StopSoundPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php b/src/network/mcpe/protocol/StructureBlockUpdatePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/StructureBlockUpdatePacket.php rename to src/network/mcpe/protocol/StructureBlockUpdatePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/StructureTemplateDataExportRequestPacket.php b/src/network/mcpe/protocol/StructureTemplateDataExportRequestPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/StructureTemplateDataExportRequestPacket.php rename to src/network/mcpe/protocol/StructureTemplateDataExportRequestPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/StructureTemplateDataExportResponsePacket.php b/src/network/mcpe/protocol/StructureTemplateDataExportResponsePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/StructureTemplateDataExportResponsePacket.php rename to src/network/mcpe/protocol/StructureTemplateDataExportResponsePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/SubClientLoginPacket.php b/src/network/mcpe/protocol/SubClientLoginPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/SubClientLoginPacket.php rename to src/network/mcpe/protocol/SubClientLoginPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/TakeItemActorPacket.php b/src/network/mcpe/protocol/TakeItemActorPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/TakeItemActorPacket.php rename to src/network/mcpe/protocol/TakeItemActorPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/TextPacket.php b/src/network/mcpe/protocol/TextPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/TextPacket.php rename to src/network/mcpe/protocol/TextPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/TransferPacket.php b/src/network/mcpe/protocol/TransferPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/TransferPacket.php rename to src/network/mcpe/protocol/TransferPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/UnknownPacket.php b/src/network/mcpe/protocol/UnknownPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/UnknownPacket.php rename to src/network/mcpe/protocol/UnknownPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php b/src/network/mcpe/protocol/UpdateAttributesPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/UpdateAttributesPacket.php rename to src/network/mcpe/protocol/UpdateAttributesPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php b/src/network/mcpe/protocol/UpdateBlockPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/UpdateBlockPacket.php rename to src/network/mcpe/protocol/UpdateBlockPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/UpdateBlockPropertiesPacket.php b/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/UpdateBlockPropertiesPacket.php rename to src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/UpdateBlockSyncedPacket.php b/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/UpdateBlockSyncedPacket.php rename to src/network/mcpe/protocol/UpdateBlockSyncedPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php b/src/network/mcpe/protocol/UpdateEquipPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/UpdateEquipPacket.php rename to src/network/mcpe/protocol/UpdateEquipPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/UpdateSoftEnumPacket.php b/src/network/mcpe/protocol/UpdateSoftEnumPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/UpdateSoftEnumPacket.php rename to src/network/mcpe/protocol/UpdateSoftEnumPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php b/src/network/mcpe/protocol/UpdateTradePacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/UpdateTradePacket.php rename to src/network/mcpe/protocol/UpdateTradePacket.php diff --git a/src/pocketmine/network/mcpe/protocol/VideoStreamConnectPacket.php b/src/network/mcpe/protocol/VideoStreamConnectPacket.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/VideoStreamConnectPacket.php rename to src/network/mcpe/protocol/VideoStreamConnectPacket.php diff --git a/src/pocketmine/network/mcpe/protocol/types/ChunkCacheBlob.php b/src/network/mcpe/protocol/types/ChunkCacheBlob.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/ChunkCacheBlob.php rename to src/network/mcpe/protocol/types/ChunkCacheBlob.php diff --git a/src/pocketmine/network/mcpe/protocol/types/DimensionIds.php b/src/network/mcpe/protocol/types/DimensionIds.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/DimensionIds.php rename to src/network/mcpe/protocol/types/DimensionIds.php diff --git a/src/pocketmine/network/mcpe/protocol/types/MapTrackedObject.php b/src/network/mcpe/protocol/types/MapTrackedObject.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/MapTrackedObject.php rename to src/network/mcpe/protocol/types/MapTrackedObject.php diff --git a/src/pocketmine/network/mcpe/protocol/types/ParticleIds.php b/src/network/mcpe/protocol/types/ParticleIds.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/ParticleIds.php rename to src/network/mcpe/protocol/types/ParticleIds.php diff --git a/src/pocketmine/network/mcpe/protocol/types/PlayerListEntry.php b/src/network/mcpe/protocol/types/PlayerListEntry.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/PlayerListEntry.php rename to src/network/mcpe/protocol/types/PlayerListEntry.php diff --git a/src/pocketmine/network/mcpe/protocol/types/PlayerPermissions.php b/src/network/mcpe/protocol/types/PlayerPermissions.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/PlayerPermissions.php rename to src/network/mcpe/protocol/types/PlayerPermissions.php diff --git a/src/pocketmine/network/mcpe/protocol/types/ResourcePackType.php b/src/network/mcpe/protocol/types/ResourcePackType.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/ResourcePackType.php rename to src/network/mcpe/protocol/types/ResourcePackType.php diff --git a/src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php b/src/network/mcpe/protocol/types/RuntimeBlockMapping.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php rename to src/network/mcpe/protocol/types/RuntimeBlockMapping.php diff --git a/src/pocketmine/network/mcpe/protocol/types/ScorePacketEntry.php b/src/network/mcpe/protocol/types/ScorePacketEntry.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/ScorePacketEntry.php rename to src/network/mcpe/protocol/types/ScorePacketEntry.php diff --git a/src/pocketmine/network/mcpe/protocol/types/ScoreboardIdentityPacketEntry.php b/src/network/mcpe/protocol/types/ScoreboardIdentityPacketEntry.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/ScoreboardIdentityPacketEntry.php rename to src/network/mcpe/protocol/types/ScoreboardIdentityPacketEntry.php diff --git a/src/pocketmine/network/mcpe/protocol/types/command/CommandData.php b/src/network/mcpe/protocol/types/command/CommandData.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/command/CommandData.php rename to src/network/mcpe/protocol/types/command/CommandData.php diff --git a/src/pocketmine/network/mcpe/protocol/types/command/CommandEnum.php b/src/network/mcpe/protocol/types/command/CommandEnum.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/command/CommandEnum.php rename to src/network/mcpe/protocol/types/command/CommandEnum.php diff --git a/src/pocketmine/network/mcpe/protocol/types/command/CommandOriginData.php b/src/network/mcpe/protocol/types/command/CommandOriginData.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/command/CommandOriginData.php rename to src/network/mcpe/protocol/types/command/CommandOriginData.php diff --git a/src/pocketmine/network/mcpe/protocol/types/command/CommandOutputMessage.php b/src/network/mcpe/protocol/types/command/CommandOutputMessage.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/command/CommandOutputMessage.php rename to src/network/mcpe/protocol/types/command/CommandOutputMessage.php diff --git a/src/pocketmine/network/mcpe/protocol/types/command/CommandParameter.php b/src/network/mcpe/protocol/types/command/CommandParameter.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/command/CommandParameter.php rename to src/network/mcpe/protocol/types/command/CommandParameter.php diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php b/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php rename to src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/ByteMetadataProperty.php b/src/network/mcpe/protocol/types/entity/ByteMetadataProperty.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/entity/ByteMetadataProperty.php rename to src/network/mcpe/protocol/types/entity/ByteMetadataProperty.php diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/EntityLegacyIds.php b/src/network/mcpe/protocol/types/entity/EntityLegacyIds.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/entity/EntityLegacyIds.php rename to src/network/mcpe/protocol/types/entity/EntityLegacyIds.php diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/EntityLink.php b/src/network/mcpe/protocol/types/entity/EntityLink.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/entity/EntityLink.php rename to src/network/mcpe/protocol/types/entity/EntityLink.php diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataCollection.php b/src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataCollection.php rename to src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataFlags.php b/src/network/mcpe/protocol/types/entity/EntityMetadataFlags.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataFlags.php rename to src/network/mcpe/protocol/types/entity/EntityMetadataFlags.php diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataProperties.php b/src/network/mcpe/protocol/types/entity/EntityMetadataProperties.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataProperties.php rename to src/network/mcpe/protocol/types/entity/EntityMetadataProperties.php diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataTypes.php b/src/network/mcpe/protocol/types/entity/EntityMetadataTypes.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/entity/EntityMetadataTypes.php rename to src/network/mcpe/protocol/types/entity/EntityMetadataTypes.php diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/FloatMetadataProperty.php b/src/network/mcpe/protocol/types/entity/FloatMetadataProperty.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/entity/FloatMetadataProperty.php rename to src/network/mcpe/protocol/types/entity/FloatMetadataProperty.php diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/IntMetadataProperty.php b/src/network/mcpe/protocol/types/entity/IntMetadataProperty.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/entity/IntMetadataProperty.php rename to src/network/mcpe/protocol/types/entity/IntMetadataProperty.php diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php b/src/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php rename to src/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/ItemStackMetadataProperty.php b/src/network/mcpe/protocol/types/entity/ItemStackMetadataProperty.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/entity/ItemStackMetadataProperty.php rename to src/network/mcpe/protocol/types/entity/ItemStackMetadataProperty.php diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/LongMetadataProperty.php b/src/network/mcpe/protocol/types/entity/LongMetadataProperty.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/entity/LongMetadataProperty.php rename to src/network/mcpe/protocol/types/entity/LongMetadataProperty.php diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/MetadataProperty.php b/src/network/mcpe/protocol/types/entity/MetadataProperty.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/entity/MetadataProperty.php rename to src/network/mcpe/protocol/types/entity/MetadataProperty.php diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/PlayerMetadataFlags.php b/src/network/mcpe/protocol/types/entity/PlayerMetadataFlags.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/entity/PlayerMetadataFlags.php rename to src/network/mcpe/protocol/types/entity/PlayerMetadataFlags.php diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/ShortMetadataProperty.php b/src/network/mcpe/protocol/types/entity/ShortMetadataProperty.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/entity/ShortMetadataProperty.php rename to src/network/mcpe/protocol/types/entity/ShortMetadataProperty.php diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/StringMetadataProperty.php b/src/network/mcpe/protocol/types/entity/StringMetadataProperty.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/entity/StringMetadataProperty.php rename to src/network/mcpe/protocol/types/entity/StringMetadataProperty.php diff --git a/src/pocketmine/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php b/src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php rename to src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php diff --git a/src/pocketmine/network/mcpe/protocol/types/inventory/ContainerIds.php b/src/network/mcpe/protocol/types/inventory/ContainerIds.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/inventory/ContainerIds.php rename to src/network/mcpe/protocol/types/inventory/ContainerIds.php diff --git a/src/pocketmine/network/mcpe/protocol/types/inventory/MismatchTransactionData.php b/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/inventory/MismatchTransactionData.php rename to src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php diff --git a/src/pocketmine/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php b/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php rename to src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php diff --git a/src/pocketmine/network/mcpe/protocol/types/inventory/NormalTransactionData.php b/src/network/mcpe/protocol/types/inventory/NormalTransactionData.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/inventory/NormalTransactionData.php rename to src/network/mcpe/protocol/types/inventory/NormalTransactionData.php diff --git a/src/pocketmine/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php b/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php rename to src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php diff --git a/src/pocketmine/network/mcpe/protocol/types/inventory/TransactionData.php b/src/network/mcpe/protocol/types/inventory/TransactionData.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/inventory/TransactionData.php rename to src/network/mcpe/protocol/types/inventory/TransactionData.php diff --git a/src/pocketmine/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php b/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php rename to src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php diff --git a/src/pocketmine/network/mcpe/protocol/types/inventory/UseItemTransactionData.php b/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/inventory/UseItemTransactionData.php rename to src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php diff --git a/src/pocketmine/network/mcpe/protocol/types/inventory/WindowTypes.php b/src/network/mcpe/protocol/types/inventory/WindowTypes.php similarity index 100% rename from src/pocketmine/network/mcpe/protocol/types/inventory/WindowTypes.php rename to src/network/mcpe/protocol/types/inventory/WindowTypes.php diff --git a/src/pocketmine/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php similarity index 100% rename from src/pocketmine/network/mcpe/raklib/RakLibInterface.php rename to src/network/mcpe/raklib/RakLibInterface.php diff --git a/src/pocketmine/network/mcpe/raklib/RakLibPacketSender.php b/src/network/mcpe/raklib/RakLibPacketSender.php similarity index 100% rename from src/pocketmine/network/mcpe/raklib/RakLibPacketSender.php rename to src/network/mcpe/raklib/RakLibPacketSender.php diff --git a/src/pocketmine/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php similarity index 100% rename from src/pocketmine/network/mcpe/serializer/ChunkSerializer.php rename to src/network/mcpe/serializer/ChunkSerializer.php diff --git a/src/pocketmine/network/mcpe/serializer/NetworkBinaryStream.php b/src/network/mcpe/serializer/NetworkBinaryStream.php similarity index 100% rename from src/pocketmine/network/mcpe/serializer/NetworkBinaryStream.php rename to src/network/mcpe/serializer/NetworkBinaryStream.php diff --git a/src/pocketmine/network/mcpe/serializer/NetworkNbtSerializer.php b/src/network/mcpe/serializer/NetworkNbtSerializer.php similarity index 100% rename from src/pocketmine/network/mcpe/serializer/NetworkNbtSerializer.php rename to src/network/mcpe/serializer/NetworkNbtSerializer.php diff --git a/src/pocketmine/network/query/QueryHandler.php b/src/network/query/QueryHandler.php similarity index 100% rename from src/pocketmine/network/query/QueryHandler.php rename to src/network/query/QueryHandler.php diff --git a/src/pocketmine/network/upnp/UPnP.php b/src/network/upnp/UPnP.php similarity index 100% rename from src/pocketmine/network/upnp/UPnP.php rename to src/network/upnp/UPnP.php diff --git a/src/pocketmine/permission/BanEntry.php b/src/permission/BanEntry.php similarity index 100% rename from src/pocketmine/permission/BanEntry.php rename to src/permission/BanEntry.php diff --git a/src/pocketmine/permission/BanList.php b/src/permission/BanList.php similarity index 100% rename from src/pocketmine/permission/BanList.php rename to src/permission/BanList.php diff --git a/src/pocketmine/permission/DefaultPermissions.php b/src/permission/DefaultPermissions.php similarity index 100% rename from src/pocketmine/permission/DefaultPermissions.php rename to src/permission/DefaultPermissions.php diff --git a/src/pocketmine/permission/Permissible.php b/src/permission/Permissible.php similarity index 100% rename from src/pocketmine/permission/Permissible.php rename to src/permission/Permissible.php diff --git a/src/pocketmine/permission/PermissibleBase.php b/src/permission/PermissibleBase.php similarity index 100% rename from src/pocketmine/permission/PermissibleBase.php rename to src/permission/PermissibleBase.php diff --git a/src/pocketmine/permission/PermissibleDelegateTrait.php b/src/permission/PermissibleDelegateTrait.php similarity index 100% rename from src/pocketmine/permission/PermissibleDelegateTrait.php rename to src/permission/PermissibleDelegateTrait.php diff --git a/src/pocketmine/permission/Permission.php b/src/permission/Permission.php similarity index 100% rename from src/pocketmine/permission/Permission.php rename to src/permission/Permission.php diff --git a/src/pocketmine/permission/PermissionAttachment.php b/src/permission/PermissionAttachment.php similarity index 100% rename from src/pocketmine/permission/PermissionAttachment.php rename to src/permission/PermissionAttachment.php diff --git a/src/pocketmine/permission/PermissionAttachmentInfo.php b/src/permission/PermissionAttachmentInfo.php similarity index 100% rename from src/pocketmine/permission/PermissionAttachmentInfo.php rename to src/permission/PermissionAttachmentInfo.php diff --git a/src/pocketmine/permission/PermissionManager.php b/src/permission/PermissionManager.php similarity index 100% rename from src/pocketmine/permission/PermissionManager.php rename to src/permission/PermissionManager.php diff --git a/src/pocketmine/permission/PermissionParser.php b/src/permission/PermissionParser.php similarity index 100% rename from src/pocketmine/permission/PermissionParser.php rename to src/permission/PermissionParser.php diff --git a/src/pocketmine/permission/PermissionRemovedExecutor.php b/src/permission/PermissionRemovedExecutor.php similarity index 100% rename from src/pocketmine/permission/PermissionRemovedExecutor.php rename to src/permission/PermissionRemovedExecutor.php diff --git a/src/pocketmine/permission/ServerOperator.php b/src/permission/ServerOperator.php similarity index 100% rename from src/pocketmine/permission/ServerOperator.php rename to src/permission/ServerOperator.php diff --git a/src/pocketmine/player/GameMode.php b/src/player/GameMode.php similarity index 100% rename from src/pocketmine/player/GameMode.php rename to src/player/GameMode.php diff --git a/src/pocketmine/player/IPlayer.php b/src/player/IPlayer.php similarity index 100% rename from src/pocketmine/player/IPlayer.php rename to src/player/IPlayer.php diff --git a/src/pocketmine/player/OfflinePlayer.php b/src/player/OfflinePlayer.php similarity index 100% rename from src/pocketmine/player/OfflinePlayer.php rename to src/player/OfflinePlayer.php diff --git a/src/pocketmine/player/Player.php b/src/player/Player.php similarity index 100% rename from src/pocketmine/player/Player.php rename to src/player/Player.php diff --git a/src/pocketmine/player/PlayerInfo.php b/src/player/PlayerInfo.php similarity index 100% rename from src/pocketmine/player/PlayerInfo.php rename to src/player/PlayerInfo.php diff --git a/src/pocketmine/plugin/ApiVersion.php b/src/plugin/ApiVersion.php similarity index 100% rename from src/pocketmine/plugin/ApiVersion.php rename to src/plugin/ApiVersion.php diff --git a/src/pocketmine/plugin/DiskResourceProvider.php b/src/plugin/DiskResourceProvider.php similarity index 100% rename from src/pocketmine/plugin/DiskResourceProvider.php rename to src/plugin/DiskResourceProvider.php diff --git a/src/pocketmine/plugin/PharPluginLoader.php b/src/plugin/PharPluginLoader.php similarity index 100% rename from src/pocketmine/plugin/PharPluginLoader.php rename to src/plugin/PharPluginLoader.php diff --git a/src/pocketmine/plugin/Plugin.php b/src/plugin/Plugin.php similarity index 100% rename from src/pocketmine/plugin/Plugin.php rename to src/plugin/Plugin.php diff --git a/src/pocketmine/plugin/PluginBase.php b/src/plugin/PluginBase.php similarity index 100% rename from src/pocketmine/plugin/PluginBase.php rename to src/plugin/PluginBase.php diff --git a/src/pocketmine/plugin/PluginDescription.php b/src/plugin/PluginDescription.php similarity index 100% rename from src/pocketmine/plugin/PluginDescription.php rename to src/plugin/PluginDescription.php diff --git a/src/pocketmine/plugin/PluginException.php b/src/plugin/PluginException.php similarity index 100% rename from src/pocketmine/plugin/PluginException.php rename to src/plugin/PluginException.php diff --git a/src/pocketmine/plugin/PluginGraylist.php b/src/plugin/PluginGraylist.php similarity index 100% rename from src/pocketmine/plugin/PluginGraylist.php rename to src/plugin/PluginGraylist.php diff --git a/src/pocketmine/plugin/PluginLoadOrder.php b/src/plugin/PluginLoadOrder.php similarity index 100% rename from src/pocketmine/plugin/PluginLoadOrder.php rename to src/plugin/PluginLoadOrder.php diff --git a/src/pocketmine/plugin/PluginLoader.php b/src/plugin/PluginLoader.php similarity index 100% rename from src/pocketmine/plugin/PluginLoader.php rename to src/plugin/PluginLoader.php diff --git a/src/pocketmine/plugin/PluginLogger.php b/src/plugin/PluginLogger.php similarity index 100% rename from src/pocketmine/plugin/PluginLogger.php rename to src/plugin/PluginLogger.php diff --git a/src/pocketmine/plugin/PluginManager.php b/src/plugin/PluginManager.php similarity index 100% rename from src/pocketmine/plugin/PluginManager.php rename to src/plugin/PluginManager.php diff --git a/src/pocketmine/plugin/ResourceProvider.php b/src/plugin/ResourceProvider.php similarity index 100% rename from src/pocketmine/plugin/ResourceProvider.php rename to src/plugin/ResourceProvider.php diff --git a/src/pocketmine/plugin/ScriptPluginLoader.php b/src/plugin/ScriptPluginLoader.php similarity index 100% rename from src/pocketmine/plugin/ScriptPluginLoader.php rename to src/plugin/ScriptPluginLoader.php diff --git a/src/pocketmine/resourcepacks/ResourcePack.php b/src/resourcepacks/ResourcePack.php similarity index 100% rename from src/pocketmine/resourcepacks/ResourcePack.php rename to src/resourcepacks/ResourcePack.php diff --git a/src/pocketmine/resourcepacks/ResourcePackException.php b/src/resourcepacks/ResourcePackException.php similarity index 100% rename from src/pocketmine/resourcepacks/ResourcePackException.php rename to src/resourcepacks/ResourcePackException.php diff --git a/src/pocketmine/resourcepacks/ResourcePackInfoEntry.php b/src/resourcepacks/ResourcePackInfoEntry.php similarity index 100% rename from src/pocketmine/resourcepacks/ResourcePackInfoEntry.php rename to src/resourcepacks/ResourcePackInfoEntry.php diff --git a/src/pocketmine/resourcepacks/ResourcePackManager.php b/src/resourcepacks/ResourcePackManager.php similarity index 100% rename from src/pocketmine/resourcepacks/ResourcePackManager.php rename to src/resourcepacks/ResourcePackManager.php diff --git a/src/pocketmine/resourcepacks/ZippedResourcePack.php b/src/resourcepacks/ZippedResourcePack.php similarity index 100% rename from src/pocketmine/resourcepacks/ZippedResourcePack.php rename to src/resourcepacks/ZippedResourcePack.php diff --git a/src/pocketmine/scheduler/AsyncPool.php b/src/scheduler/AsyncPool.php similarity index 100% rename from src/pocketmine/scheduler/AsyncPool.php rename to src/scheduler/AsyncPool.php diff --git a/src/pocketmine/scheduler/AsyncTask.php b/src/scheduler/AsyncTask.php similarity index 100% rename from src/pocketmine/scheduler/AsyncTask.php rename to src/scheduler/AsyncTask.php diff --git a/src/pocketmine/scheduler/AsyncWorker.php b/src/scheduler/AsyncWorker.php similarity index 100% rename from src/pocketmine/scheduler/AsyncWorker.php rename to src/scheduler/AsyncWorker.php diff --git a/src/pocketmine/scheduler/BulkCurlTask.php b/src/scheduler/BulkCurlTask.php similarity index 100% rename from src/pocketmine/scheduler/BulkCurlTask.php rename to src/scheduler/BulkCurlTask.php diff --git a/src/pocketmine/scheduler/CancellableClosureTask.php b/src/scheduler/CancellableClosureTask.php similarity index 100% rename from src/pocketmine/scheduler/CancellableClosureTask.php rename to src/scheduler/CancellableClosureTask.php diff --git a/src/pocketmine/scheduler/ClosureTask.php b/src/scheduler/ClosureTask.php similarity index 100% rename from src/pocketmine/scheduler/ClosureTask.php rename to src/scheduler/ClosureTask.php diff --git a/src/pocketmine/scheduler/DumpWorkerMemoryTask.php b/src/scheduler/DumpWorkerMemoryTask.php similarity index 100% rename from src/pocketmine/scheduler/DumpWorkerMemoryTask.php rename to src/scheduler/DumpWorkerMemoryTask.php diff --git a/src/pocketmine/scheduler/FileWriteTask.php b/src/scheduler/FileWriteTask.php similarity index 100% rename from src/pocketmine/scheduler/FileWriteTask.php rename to src/scheduler/FileWriteTask.php diff --git a/src/pocketmine/scheduler/GarbageCollectionTask.php b/src/scheduler/GarbageCollectionTask.php similarity index 100% rename from src/pocketmine/scheduler/GarbageCollectionTask.php rename to src/scheduler/GarbageCollectionTask.php diff --git a/src/pocketmine/scheduler/SendUsageTask.php b/src/scheduler/SendUsageTask.php similarity index 100% rename from src/pocketmine/scheduler/SendUsageTask.php rename to src/scheduler/SendUsageTask.php diff --git a/src/pocketmine/scheduler/Task.php b/src/scheduler/Task.php similarity index 100% rename from src/pocketmine/scheduler/Task.php rename to src/scheduler/Task.php diff --git a/src/pocketmine/scheduler/TaskHandler.php b/src/scheduler/TaskHandler.php similarity index 100% rename from src/pocketmine/scheduler/TaskHandler.php rename to src/scheduler/TaskHandler.php diff --git a/src/pocketmine/scheduler/TaskScheduler.php b/src/scheduler/TaskScheduler.php similarity index 100% rename from src/pocketmine/scheduler/TaskScheduler.php rename to src/scheduler/TaskScheduler.php diff --git a/src/pocketmine/thread/CommonThreadPartsTrait.php b/src/thread/CommonThreadPartsTrait.php similarity index 100% rename from src/pocketmine/thread/CommonThreadPartsTrait.php rename to src/thread/CommonThreadPartsTrait.php diff --git a/src/pocketmine/thread/Thread.php b/src/thread/Thread.php similarity index 100% rename from src/pocketmine/thread/Thread.php rename to src/thread/Thread.php diff --git a/src/pocketmine/thread/ThreadManager.php b/src/thread/ThreadManager.php similarity index 100% rename from src/pocketmine/thread/ThreadManager.php rename to src/thread/ThreadManager.php diff --git a/src/pocketmine/thread/Worker.php b/src/thread/Worker.php similarity index 100% rename from src/pocketmine/thread/Worker.php rename to src/thread/Worker.php diff --git a/src/pocketmine/timings/Timings.php b/src/timings/Timings.php similarity index 100% rename from src/pocketmine/timings/Timings.php rename to src/timings/Timings.php diff --git a/src/pocketmine/timings/TimingsHandler.php b/src/timings/TimingsHandler.php similarity index 100% rename from src/pocketmine/timings/TimingsHandler.php rename to src/timings/TimingsHandler.php diff --git a/src/pocketmine/updater/AutoUpdater.php b/src/updater/AutoUpdater.php similarity index 100% rename from src/pocketmine/updater/AutoUpdater.php rename to src/updater/AutoUpdater.php diff --git a/src/pocketmine/updater/UpdateCheckTask.php b/src/updater/UpdateCheckTask.php similarity index 100% rename from src/pocketmine/updater/UpdateCheckTask.php rename to src/updater/UpdateCheckTask.php diff --git a/src/pocketmine/utils/Color.php b/src/utils/Color.php similarity index 100% rename from src/pocketmine/utils/Color.php rename to src/utils/Color.php diff --git a/src/pocketmine/utils/Config.php b/src/utils/Config.php similarity index 100% rename from src/pocketmine/utils/Config.php rename to src/utils/Config.php diff --git a/src/pocketmine/utils/EnumTrait.php b/src/utils/EnumTrait.php similarity index 100% rename from src/pocketmine/utils/EnumTrait.php rename to src/utils/EnumTrait.php diff --git a/src/pocketmine/utils/Internet.php b/src/utils/Internet.php similarity index 100% rename from src/pocketmine/utils/Internet.php rename to src/utils/Internet.php diff --git a/src/pocketmine/utils/InternetException.php b/src/utils/InternetException.php similarity index 100% rename from src/pocketmine/utils/InternetException.php rename to src/utils/InternetException.php diff --git a/src/pocketmine/utils/MainLogger.php b/src/utils/MainLogger.php similarity index 100% rename from src/pocketmine/utils/MainLogger.php rename to src/utils/MainLogger.php diff --git a/src/pocketmine/utils/Process.php b/src/utils/Process.php similarity index 100% rename from src/pocketmine/utils/Process.php rename to src/utils/Process.php diff --git a/src/pocketmine/utils/Random.php b/src/utils/Random.php similarity index 100% rename from src/pocketmine/utils/Random.php rename to src/utils/Random.php diff --git a/src/pocketmine/utils/RegistryTrait.php b/src/utils/RegistryTrait.php similarity index 100% rename from src/pocketmine/utils/RegistryTrait.php rename to src/utils/RegistryTrait.php diff --git a/src/pocketmine/utils/ReversePriorityQueue.php b/src/utils/ReversePriorityQueue.php similarity index 100% rename from src/pocketmine/utils/ReversePriorityQueue.php rename to src/utils/ReversePriorityQueue.php diff --git a/src/pocketmine/utils/ServerException.php b/src/utils/ServerException.php similarity index 100% rename from src/pocketmine/utils/ServerException.php rename to src/utils/ServerException.php diff --git a/src/pocketmine/utils/ServerKiller.php b/src/utils/ServerKiller.php similarity index 100% rename from src/pocketmine/utils/ServerKiller.php rename to src/utils/ServerKiller.php diff --git a/src/pocketmine/utils/Terminal.php b/src/utils/Terminal.php similarity index 100% rename from src/pocketmine/utils/Terminal.php rename to src/utils/Terminal.php diff --git a/src/pocketmine/utils/TextFormat.php b/src/utils/TextFormat.php similarity index 100% rename from src/pocketmine/utils/TextFormat.php rename to src/utils/TextFormat.php diff --git a/src/pocketmine/utils/Timezone.php b/src/utils/Timezone.php similarity index 100% rename from src/pocketmine/utils/Timezone.php rename to src/utils/Timezone.php diff --git a/src/pocketmine/utils/UUID.php b/src/utils/UUID.php similarity index 100% rename from src/pocketmine/utils/UUID.php rename to src/utils/UUID.php diff --git a/src/pocketmine/utils/Utils.php b/src/utils/Utils.php similarity index 100% rename from src/pocketmine/utils/Utils.php rename to src/utils/Utils.php diff --git a/src/pocketmine/utils/VersionString.php b/src/utils/VersionString.php similarity index 100% rename from src/pocketmine/utils/VersionString.php rename to src/utils/VersionString.php diff --git a/src/pocketmine/wizard/SetupWizard.php b/src/wizard/SetupWizard.php similarity index 100% rename from src/pocketmine/wizard/SetupWizard.php rename to src/wizard/SetupWizard.php diff --git a/src/pocketmine/world/BlockTransaction.php b/src/world/BlockTransaction.php similarity index 100% rename from src/pocketmine/world/BlockTransaction.php rename to src/world/BlockTransaction.php diff --git a/src/pocketmine/world/ChunkListener.php b/src/world/ChunkListener.php similarity index 100% rename from src/pocketmine/world/ChunkListener.php rename to src/world/ChunkListener.php diff --git a/src/pocketmine/world/ChunkListenerNoOpTrait.php b/src/world/ChunkListenerNoOpTrait.php similarity index 100% rename from src/pocketmine/world/ChunkListenerNoOpTrait.php rename to src/world/ChunkListenerNoOpTrait.php diff --git a/src/pocketmine/world/ChunkLoader.php b/src/world/ChunkLoader.php similarity index 100% rename from src/pocketmine/world/ChunkLoader.php rename to src/world/ChunkLoader.php diff --git a/src/pocketmine/world/ChunkManager.php b/src/world/ChunkManager.php similarity index 100% rename from src/pocketmine/world/ChunkManager.php rename to src/world/ChunkManager.php diff --git a/src/pocketmine/world/Explosion.php b/src/world/Explosion.php similarity index 100% rename from src/pocketmine/world/Explosion.php rename to src/world/Explosion.php diff --git a/src/pocketmine/world/Location.php b/src/world/Location.php similarity index 100% rename from src/pocketmine/world/Location.php rename to src/world/Location.php diff --git a/src/pocketmine/world/Position.php b/src/world/Position.php similarity index 100% rename from src/pocketmine/world/Position.php rename to src/world/Position.php diff --git a/src/pocketmine/world/SimpleChunkManager.php b/src/world/SimpleChunkManager.php similarity index 100% rename from src/pocketmine/world/SimpleChunkManager.php rename to src/world/SimpleChunkManager.php diff --git a/src/pocketmine/world/World.php b/src/world/World.php similarity index 100% rename from src/pocketmine/world/World.php rename to src/world/World.php diff --git a/src/pocketmine/world/WorldException.php b/src/world/WorldException.php similarity index 100% rename from src/pocketmine/world/WorldException.php rename to src/world/WorldException.php diff --git a/src/pocketmine/world/WorldManager.php b/src/world/WorldManager.php similarity index 100% rename from src/pocketmine/world/WorldManager.php rename to src/world/WorldManager.php diff --git a/src/pocketmine/world/WorldTimings.php b/src/world/WorldTimings.php similarity index 100% rename from src/pocketmine/world/WorldTimings.php rename to src/world/WorldTimings.php diff --git a/src/pocketmine/world/biome/Biome.php b/src/world/biome/Biome.php similarity index 100% rename from src/pocketmine/world/biome/Biome.php rename to src/world/biome/Biome.php diff --git a/src/pocketmine/world/biome/DesertBiome.php b/src/world/biome/DesertBiome.php similarity index 100% rename from src/pocketmine/world/biome/DesertBiome.php rename to src/world/biome/DesertBiome.php diff --git a/src/pocketmine/world/biome/ForestBiome.php b/src/world/biome/ForestBiome.php similarity index 100% rename from src/pocketmine/world/biome/ForestBiome.php rename to src/world/biome/ForestBiome.php diff --git a/src/pocketmine/world/biome/GrassyBiome.php b/src/world/biome/GrassyBiome.php similarity index 100% rename from src/pocketmine/world/biome/GrassyBiome.php rename to src/world/biome/GrassyBiome.php diff --git a/src/pocketmine/world/biome/HellBiome.php b/src/world/biome/HellBiome.php similarity index 100% rename from src/pocketmine/world/biome/HellBiome.php rename to src/world/biome/HellBiome.php diff --git a/src/pocketmine/world/biome/IcePlainsBiome.php b/src/world/biome/IcePlainsBiome.php similarity index 100% rename from src/pocketmine/world/biome/IcePlainsBiome.php rename to src/world/biome/IcePlainsBiome.php diff --git a/src/pocketmine/world/biome/MountainsBiome.php b/src/world/biome/MountainsBiome.php similarity index 100% rename from src/pocketmine/world/biome/MountainsBiome.php rename to src/world/biome/MountainsBiome.php diff --git a/src/pocketmine/world/biome/OceanBiome.php b/src/world/biome/OceanBiome.php similarity index 100% rename from src/pocketmine/world/biome/OceanBiome.php rename to src/world/biome/OceanBiome.php diff --git a/src/pocketmine/world/biome/PlainBiome.php b/src/world/biome/PlainBiome.php similarity index 100% rename from src/pocketmine/world/biome/PlainBiome.php rename to src/world/biome/PlainBiome.php diff --git a/src/pocketmine/world/biome/RiverBiome.php b/src/world/biome/RiverBiome.php similarity index 100% rename from src/pocketmine/world/biome/RiverBiome.php rename to src/world/biome/RiverBiome.php diff --git a/src/pocketmine/world/biome/SandyBiome.php b/src/world/biome/SandyBiome.php similarity index 100% rename from src/pocketmine/world/biome/SandyBiome.php rename to src/world/biome/SandyBiome.php diff --git a/src/pocketmine/world/biome/SmallMountainsBiome.php b/src/world/biome/SmallMountainsBiome.php similarity index 100% rename from src/pocketmine/world/biome/SmallMountainsBiome.php rename to src/world/biome/SmallMountainsBiome.php diff --git a/src/pocketmine/world/biome/SnowyBiome.php b/src/world/biome/SnowyBiome.php similarity index 100% rename from src/pocketmine/world/biome/SnowyBiome.php rename to src/world/biome/SnowyBiome.php diff --git a/src/pocketmine/world/biome/SwampBiome.php b/src/world/biome/SwampBiome.php similarity index 100% rename from src/pocketmine/world/biome/SwampBiome.php rename to src/world/biome/SwampBiome.php diff --git a/src/pocketmine/world/biome/TaigaBiome.php b/src/world/biome/TaigaBiome.php similarity index 100% rename from src/pocketmine/world/biome/TaigaBiome.php rename to src/world/biome/TaigaBiome.php diff --git a/src/pocketmine/world/biome/UnknownBiome.php b/src/world/biome/UnknownBiome.php similarity index 100% rename from src/pocketmine/world/biome/UnknownBiome.php rename to src/world/biome/UnknownBiome.php diff --git a/src/pocketmine/world/format/Chunk.php b/src/world/format/Chunk.php similarity index 100% rename from src/pocketmine/world/format/Chunk.php rename to src/world/format/Chunk.php diff --git a/src/pocketmine/world/format/ChunkException.php b/src/world/format/ChunkException.php similarity index 100% rename from src/pocketmine/world/format/ChunkException.php rename to src/world/format/ChunkException.php diff --git a/src/pocketmine/world/format/EmptySubChunk.php b/src/world/format/EmptySubChunk.php similarity index 100% rename from src/pocketmine/world/format/EmptySubChunk.php rename to src/world/format/EmptySubChunk.php diff --git a/src/pocketmine/world/format/LightArray.php b/src/world/format/LightArray.php similarity index 100% rename from src/pocketmine/world/format/LightArray.php rename to src/world/format/LightArray.php diff --git a/src/pocketmine/world/format/SubChunk.php b/src/world/format/SubChunk.php similarity index 100% rename from src/pocketmine/world/format/SubChunk.php rename to src/world/format/SubChunk.php diff --git a/src/pocketmine/world/format/SubChunkInterface.php b/src/world/format/SubChunkInterface.php similarity index 100% rename from src/pocketmine/world/format/SubChunkInterface.php rename to src/world/format/SubChunkInterface.php diff --git a/src/pocketmine/world/format/io/BaseWorldProvider.php b/src/world/format/io/BaseWorldProvider.php similarity index 100% rename from src/pocketmine/world/format/io/BaseWorldProvider.php rename to src/world/format/io/BaseWorldProvider.php diff --git a/src/pocketmine/world/format/io/ChunkUtils.php b/src/world/format/io/ChunkUtils.php similarity index 100% rename from src/pocketmine/world/format/io/ChunkUtils.php rename to src/world/format/io/ChunkUtils.php diff --git a/src/pocketmine/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php similarity index 100% rename from src/pocketmine/world/format/io/FastChunkSerializer.php rename to src/world/format/io/FastChunkSerializer.php diff --git a/src/pocketmine/world/format/io/FormatConverter.php b/src/world/format/io/FormatConverter.php similarity index 100% rename from src/pocketmine/world/format/io/FormatConverter.php rename to src/world/format/io/FormatConverter.php diff --git a/src/pocketmine/world/format/io/WorldData.php b/src/world/format/io/WorldData.php similarity index 100% rename from src/pocketmine/world/format/io/WorldData.php rename to src/world/format/io/WorldData.php diff --git a/src/pocketmine/world/format/io/WorldProvider.php b/src/world/format/io/WorldProvider.php similarity index 100% rename from src/pocketmine/world/format/io/WorldProvider.php rename to src/world/format/io/WorldProvider.php diff --git a/src/pocketmine/world/format/io/WorldProviderManager.php b/src/world/format/io/WorldProviderManager.php similarity index 100% rename from src/pocketmine/world/format/io/WorldProviderManager.php rename to src/world/format/io/WorldProviderManager.php diff --git a/src/pocketmine/world/format/io/WritableWorldProvider.php b/src/world/format/io/WritableWorldProvider.php similarity index 100% rename from src/pocketmine/world/format/io/WritableWorldProvider.php rename to src/world/format/io/WritableWorldProvider.php diff --git a/src/pocketmine/world/format/io/data/BaseNbtWorldData.php b/src/world/format/io/data/BaseNbtWorldData.php similarity index 100% rename from src/pocketmine/world/format/io/data/BaseNbtWorldData.php rename to src/world/format/io/data/BaseNbtWorldData.php diff --git a/src/pocketmine/world/format/io/data/BedrockWorldData.php b/src/world/format/io/data/BedrockWorldData.php similarity index 100% rename from src/pocketmine/world/format/io/data/BedrockWorldData.php rename to src/world/format/io/data/BedrockWorldData.php diff --git a/src/pocketmine/world/format/io/data/JavaWorldData.php b/src/world/format/io/data/JavaWorldData.php similarity index 100% rename from src/pocketmine/world/format/io/data/JavaWorldData.php rename to src/world/format/io/data/JavaWorldData.php diff --git a/src/pocketmine/world/format/io/exception/CorruptedChunkException.php b/src/world/format/io/exception/CorruptedChunkException.php similarity index 100% rename from src/pocketmine/world/format/io/exception/CorruptedChunkException.php rename to src/world/format/io/exception/CorruptedChunkException.php diff --git a/src/pocketmine/world/format/io/exception/CorruptedWorldException.php b/src/world/format/io/exception/CorruptedWorldException.php similarity index 100% rename from src/pocketmine/world/format/io/exception/CorruptedWorldException.php rename to src/world/format/io/exception/CorruptedWorldException.php diff --git a/src/pocketmine/world/format/io/exception/UnsupportedWorldFormatException.php b/src/world/format/io/exception/UnsupportedWorldFormatException.php similarity index 100% rename from src/pocketmine/world/format/io/exception/UnsupportedWorldFormatException.php rename to src/world/format/io/exception/UnsupportedWorldFormatException.php diff --git a/src/pocketmine/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php similarity index 100% rename from src/pocketmine/world/format/io/leveldb/LevelDB.php rename to src/world/format/io/leveldb/LevelDB.php diff --git a/src/pocketmine/world/format/io/region/Anvil.php b/src/world/format/io/region/Anvil.php similarity index 100% rename from src/pocketmine/world/format/io/region/Anvil.php rename to src/world/format/io/region/Anvil.php diff --git a/src/pocketmine/world/format/io/region/CorruptedRegionException.php b/src/world/format/io/region/CorruptedRegionException.php similarity index 100% rename from src/pocketmine/world/format/io/region/CorruptedRegionException.php rename to src/world/format/io/region/CorruptedRegionException.php diff --git a/src/pocketmine/world/format/io/region/LegacyAnvilChunkTrait.php b/src/world/format/io/region/LegacyAnvilChunkTrait.php similarity index 100% rename from src/pocketmine/world/format/io/region/LegacyAnvilChunkTrait.php rename to src/world/format/io/region/LegacyAnvilChunkTrait.php diff --git a/src/pocketmine/world/format/io/region/McRegion.php b/src/world/format/io/region/McRegion.php similarity index 100% rename from src/pocketmine/world/format/io/region/McRegion.php rename to src/world/format/io/region/McRegion.php diff --git a/src/pocketmine/world/format/io/region/PMAnvil.php b/src/world/format/io/region/PMAnvil.php similarity index 100% rename from src/pocketmine/world/format/io/region/PMAnvil.php rename to src/world/format/io/region/PMAnvil.php diff --git a/src/pocketmine/world/format/io/region/RegionException.php b/src/world/format/io/region/RegionException.php similarity index 100% rename from src/pocketmine/world/format/io/region/RegionException.php rename to src/world/format/io/region/RegionException.php diff --git a/src/pocketmine/world/format/io/region/RegionLoader.php b/src/world/format/io/region/RegionLoader.php similarity index 100% rename from src/pocketmine/world/format/io/region/RegionLoader.php rename to src/world/format/io/region/RegionLoader.php diff --git a/src/pocketmine/world/format/io/region/RegionLocationTableEntry.php b/src/world/format/io/region/RegionLocationTableEntry.php similarity index 100% rename from src/pocketmine/world/format/io/region/RegionLocationTableEntry.php rename to src/world/format/io/region/RegionLocationTableEntry.php diff --git a/src/pocketmine/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php similarity index 100% rename from src/pocketmine/world/format/io/region/RegionWorldProvider.php rename to src/world/format/io/region/RegionWorldProvider.php diff --git a/src/pocketmine/world/generator/Flat.php b/src/world/generator/Flat.php similarity index 100% rename from src/pocketmine/world/generator/Flat.php rename to src/world/generator/Flat.php diff --git a/src/pocketmine/world/generator/Generator.php b/src/world/generator/Generator.php similarity index 100% rename from src/pocketmine/world/generator/Generator.php rename to src/world/generator/Generator.php diff --git a/src/pocketmine/world/generator/GeneratorChunkManager.php b/src/world/generator/GeneratorChunkManager.php similarity index 100% rename from src/pocketmine/world/generator/GeneratorChunkManager.php rename to src/world/generator/GeneratorChunkManager.php diff --git a/src/pocketmine/world/generator/GeneratorManager.php b/src/world/generator/GeneratorManager.php similarity index 100% rename from src/pocketmine/world/generator/GeneratorManager.php rename to src/world/generator/GeneratorManager.php diff --git a/src/pocketmine/world/generator/GeneratorRegisterTask.php b/src/world/generator/GeneratorRegisterTask.php similarity index 100% rename from src/pocketmine/world/generator/GeneratorRegisterTask.php rename to src/world/generator/GeneratorRegisterTask.php diff --git a/src/pocketmine/world/generator/GeneratorUnregisterTask.php b/src/world/generator/GeneratorUnregisterTask.php similarity index 100% rename from src/pocketmine/world/generator/GeneratorUnregisterTask.php rename to src/world/generator/GeneratorUnregisterTask.php diff --git a/src/pocketmine/world/generator/InvalidGeneratorOptionsException.php b/src/world/generator/InvalidGeneratorOptionsException.php similarity index 100% rename from src/pocketmine/world/generator/InvalidGeneratorOptionsException.php rename to src/world/generator/InvalidGeneratorOptionsException.php diff --git a/src/pocketmine/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php similarity index 100% rename from src/pocketmine/world/generator/PopulationTask.php rename to src/world/generator/PopulationTask.php diff --git a/src/pocketmine/world/generator/biome/BiomeSelector.php b/src/world/generator/biome/BiomeSelector.php similarity index 100% rename from src/pocketmine/world/generator/biome/BiomeSelector.php rename to src/world/generator/biome/BiomeSelector.php diff --git a/src/pocketmine/world/generator/hell/Nether.php b/src/world/generator/hell/Nether.php similarity index 100% rename from src/pocketmine/world/generator/hell/Nether.php rename to src/world/generator/hell/Nether.php diff --git a/src/pocketmine/world/generator/noise/Noise.php b/src/world/generator/noise/Noise.php similarity index 100% rename from src/pocketmine/world/generator/noise/Noise.php rename to src/world/generator/noise/Noise.php diff --git a/src/pocketmine/world/generator/noise/Simplex.php b/src/world/generator/noise/Simplex.php similarity index 100% rename from src/pocketmine/world/generator/noise/Simplex.php rename to src/world/generator/noise/Simplex.php diff --git a/src/pocketmine/world/generator/normal/Normal.php b/src/world/generator/normal/Normal.php similarity index 100% rename from src/pocketmine/world/generator/normal/Normal.php rename to src/world/generator/normal/Normal.php diff --git a/src/pocketmine/world/generator/object/BirchTree.php b/src/world/generator/object/BirchTree.php similarity index 100% rename from src/pocketmine/world/generator/object/BirchTree.php rename to src/world/generator/object/BirchTree.php diff --git a/src/pocketmine/world/generator/object/JungleTree.php b/src/world/generator/object/JungleTree.php similarity index 100% rename from src/pocketmine/world/generator/object/JungleTree.php rename to src/world/generator/object/JungleTree.php diff --git a/src/pocketmine/world/generator/object/OakTree.php b/src/world/generator/object/OakTree.php similarity index 100% rename from src/pocketmine/world/generator/object/OakTree.php rename to src/world/generator/object/OakTree.php diff --git a/src/pocketmine/world/generator/object/Ore.php b/src/world/generator/object/Ore.php similarity index 100% rename from src/pocketmine/world/generator/object/Ore.php rename to src/world/generator/object/Ore.php diff --git a/src/pocketmine/world/generator/object/OreType.php b/src/world/generator/object/OreType.php similarity index 100% rename from src/pocketmine/world/generator/object/OreType.php rename to src/world/generator/object/OreType.php diff --git a/src/pocketmine/world/generator/object/SpruceTree.php b/src/world/generator/object/SpruceTree.php similarity index 100% rename from src/pocketmine/world/generator/object/SpruceTree.php rename to src/world/generator/object/SpruceTree.php diff --git a/src/pocketmine/world/generator/object/TallGrass.php b/src/world/generator/object/TallGrass.php similarity index 100% rename from src/pocketmine/world/generator/object/TallGrass.php rename to src/world/generator/object/TallGrass.php diff --git a/src/pocketmine/world/generator/object/Tree.php b/src/world/generator/object/Tree.php similarity index 100% rename from src/pocketmine/world/generator/object/Tree.php rename to src/world/generator/object/Tree.php diff --git a/src/pocketmine/world/generator/populator/GroundCover.php b/src/world/generator/populator/GroundCover.php similarity index 100% rename from src/pocketmine/world/generator/populator/GroundCover.php rename to src/world/generator/populator/GroundCover.php diff --git a/src/pocketmine/world/generator/populator/Ore.php b/src/world/generator/populator/Ore.php similarity index 100% rename from src/pocketmine/world/generator/populator/Ore.php rename to src/world/generator/populator/Ore.php diff --git a/src/pocketmine/world/generator/populator/Populator.php b/src/world/generator/populator/Populator.php similarity index 100% rename from src/pocketmine/world/generator/populator/Populator.php rename to src/world/generator/populator/Populator.php diff --git a/src/pocketmine/world/generator/populator/TallGrass.php b/src/world/generator/populator/TallGrass.php similarity index 100% rename from src/pocketmine/world/generator/populator/TallGrass.php rename to src/world/generator/populator/TallGrass.php diff --git a/src/pocketmine/world/generator/populator/Tree.php b/src/world/generator/populator/Tree.php similarity index 100% rename from src/pocketmine/world/generator/populator/Tree.php rename to src/world/generator/populator/Tree.php diff --git a/src/pocketmine/world/light/BlockLightUpdate.php b/src/world/light/BlockLightUpdate.php similarity index 100% rename from src/pocketmine/world/light/BlockLightUpdate.php rename to src/world/light/BlockLightUpdate.php diff --git a/src/pocketmine/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php similarity index 100% rename from src/pocketmine/world/light/LightPopulationTask.php rename to src/world/light/LightPopulationTask.php diff --git a/src/pocketmine/world/light/LightUpdate.php b/src/world/light/LightUpdate.php similarity index 100% rename from src/pocketmine/world/light/LightUpdate.php rename to src/world/light/LightUpdate.php diff --git a/src/pocketmine/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php similarity index 100% rename from src/pocketmine/world/light/SkyLightUpdate.php rename to src/world/light/SkyLightUpdate.php diff --git a/src/pocketmine/world/particle/AngryVillagerParticle.php b/src/world/particle/AngryVillagerParticle.php similarity index 100% rename from src/pocketmine/world/particle/AngryVillagerParticle.php rename to src/world/particle/AngryVillagerParticle.php diff --git a/src/pocketmine/world/particle/BlockForceFieldParticle.php b/src/world/particle/BlockForceFieldParticle.php similarity index 100% rename from src/pocketmine/world/particle/BlockForceFieldParticle.php rename to src/world/particle/BlockForceFieldParticle.php diff --git a/src/pocketmine/world/particle/BubbleParticle.php b/src/world/particle/BubbleParticle.php similarity index 100% rename from src/pocketmine/world/particle/BubbleParticle.php rename to src/world/particle/BubbleParticle.php diff --git a/src/pocketmine/world/particle/CriticalParticle.php b/src/world/particle/CriticalParticle.php similarity index 100% rename from src/pocketmine/world/particle/CriticalParticle.php rename to src/world/particle/CriticalParticle.php diff --git a/src/pocketmine/world/particle/DestroyBlockParticle.php b/src/world/particle/DestroyBlockParticle.php similarity index 100% rename from src/pocketmine/world/particle/DestroyBlockParticle.php rename to src/world/particle/DestroyBlockParticle.php diff --git a/src/pocketmine/world/particle/DragonEggTeleportParticle.php b/src/world/particle/DragonEggTeleportParticle.php similarity index 100% rename from src/pocketmine/world/particle/DragonEggTeleportParticle.php rename to src/world/particle/DragonEggTeleportParticle.php diff --git a/src/pocketmine/world/particle/DustParticle.php b/src/world/particle/DustParticle.php similarity index 100% rename from src/pocketmine/world/particle/DustParticle.php rename to src/world/particle/DustParticle.php diff --git a/src/pocketmine/world/particle/EnchantParticle.php b/src/world/particle/EnchantParticle.php similarity index 100% rename from src/pocketmine/world/particle/EnchantParticle.php rename to src/world/particle/EnchantParticle.php diff --git a/src/pocketmine/world/particle/EnchantmentTableParticle.php b/src/world/particle/EnchantmentTableParticle.php similarity index 100% rename from src/pocketmine/world/particle/EnchantmentTableParticle.php rename to src/world/particle/EnchantmentTableParticle.php diff --git a/src/pocketmine/world/particle/EndermanTeleportParticle.php b/src/world/particle/EndermanTeleportParticle.php similarity index 100% rename from src/pocketmine/world/particle/EndermanTeleportParticle.php rename to src/world/particle/EndermanTeleportParticle.php diff --git a/src/pocketmine/world/particle/EntityFlameParticle.php b/src/world/particle/EntityFlameParticle.php similarity index 100% rename from src/pocketmine/world/particle/EntityFlameParticle.php rename to src/world/particle/EntityFlameParticle.php diff --git a/src/pocketmine/world/particle/ExplodeParticle.php b/src/world/particle/ExplodeParticle.php similarity index 100% rename from src/pocketmine/world/particle/ExplodeParticle.php rename to src/world/particle/ExplodeParticle.php diff --git a/src/pocketmine/world/particle/FlameParticle.php b/src/world/particle/FlameParticle.php similarity index 100% rename from src/pocketmine/world/particle/FlameParticle.php rename to src/world/particle/FlameParticle.php diff --git a/src/pocketmine/world/particle/FloatingTextParticle.php b/src/world/particle/FloatingTextParticle.php similarity index 100% rename from src/pocketmine/world/particle/FloatingTextParticle.php rename to src/world/particle/FloatingTextParticle.php diff --git a/src/pocketmine/world/particle/GenericParticle.php b/src/world/particle/GenericParticle.php similarity index 100% rename from src/pocketmine/world/particle/GenericParticle.php rename to src/world/particle/GenericParticle.php diff --git a/src/pocketmine/world/particle/HappyVillagerParticle.php b/src/world/particle/HappyVillagerParticle.php similarity index 100% rename from src/pocketmine/world/particle/HappyVillagerParticle.php rename to src/world/particle/HappyVillagerParticle.php diff --git a/src/pocketmine/world/particle/HeartParticle.php b/src/world/particle/HeartParticle.php similarity index 100% rename from src/pocketmine/world/particle/HeartParticle.php rename to src/world/particle/HeartParticle.php diff --git a/src/pocketmine/world/particle/HugeExplodeParticle.php b/src/world/particle/HugeExplodeParticle.php similarity index 100% rename from src/pocketmine/world/particle/HugeExplodeParticle.php rename to src/world/particle/HugeExplodeParticle.php diff --git a/src/pocketmine/world/particle/HugeExplodeSeedParticle.php b/src/world/particle/HugeExplodeSeedParticle.php similarity index 100% rename from src/pocketmine/world/particle/HugeExplodeSeedParticle.php rename to src/world/particle/HugeExplodeSeedParticle.php diff --git a/src/pocketmine/world/particle/InkParticle.php b/src/world/particle/InkParticle.php similarity index 100% rename from src/pocketmine/world/particle/InkParticle.php rename to src/world/particle/InkParticle.php diff --git a/src/pocketmine/world/particle/InstantEnchantParticle.php b/src/world/particle/InstantEnchantParticle.php similarity index 100% rename from src/pocketmine/world/particle/InstantEnchantParticle.php rename to src/world/particle/InstantEnchantParticle.php diff --git a/src/pocketmine/world/particle/ItemBreakParticle.php b/src/world/particle/ItemBreakParticle.php similarity index 100% rename from src/pocketmine/world/particle/ItemBreakParticle.php rename to src/world/particle/ItemBreakParticle.php diff --git a/src/pocketmine/world/particle/LavaDripParticle.php b/src/world/particle/LavaDripParticle.php similarity index 100% rename from src/pocketmine/world/particle/LavaDripParticle.php rename to src/world/particle/LavaDripParticle.php diff --git a/src/pocketmine/world/particle/LavaParticle.php b/src/world/particle/LavaParticle.php similarity index 100% rename from src/pocketmine/world/particle/LavaParticle.php rename to src/world/particle/LavaParticle.php diff --git a/src/pocketmine/world/particle/MobSpawnParticle.php b/src/world/particle/MobSpawnParticle.php similarity index 100% rename from src/pocketmine/world/particle/MobSpawnParticle.php rename to src/world/particle/MobSpawnParticle.php diff --git a/src/pocketmine/world/particle/Particle.php b/src/world/particle/Particle.php similarity index 100% rename from src/pocketmine/world/particle/Particle.php rename to src/world/particle/Particle.php diff --git a/src/pocketmine/world/particle/PortalParticle.php b/src/world/particle/PortalParticle.php similarity index 100% rename from src/pocketmine/world/particle/PortalParticle.php rename to src/world/particle/PortalParticle.php diff --git a/src/pocketmine/world/particle/PotionSplashParticle.php b/src/world/particle/PotionSplashParticle.php similarity index 100% rename from src/pocketmine/world/particle/PotionSplashParticle.php rename to src/world/particle/PotionSplashParticle.php diff --git a/src/pocketmine/world/particle/PunchBlockParticle.php b/src/world/particle/PunchBlockParticle.php similarity index 100% rename from src/pocketmine/world/particle/PunchBlockParticle.php rename to src/world/particle/PunchBlockParticle.php diff --git a/src/pocketmine/world/particle/RainSplashParticle.php b/src/world/particle/RainSplashParticle.php similarity index 100% rename from src/pocketmine/world/particle/RainSplashParticle.php rename to src/world/particle/RainSplashParticle.php diff --git a/src/pocketmine/world/particle/RedstoneParticle.php b/src/world/particle/RedstoneParticle.php similarity index 100% rename from src/pocketmine/world/particle/RedstoneParticle.php rename to src/world/particle/RedstoneParticle.php diff --git a/src/pocketmine/world/particle/SmokeParticle.php b/src/world/particle/SmokeParticle.php similarity index 100% rename from src/pocketmine/world/particle/SmokeParticle.php rename to src/world/particle/SmokeParticle.php diff --git a/src/pocketmine/world/particle/SnowballPoofParticle.php b/src/world/particle/SnowballPoofParticle.php similarity index 100% rename from src/pocketmine/world/particle/SnowballPoofParticle.php rename to src/world/particle/SnowballPoofParticle.php diff --git a/src/pocketmine/world/particle/SplashParticle.php b/src/world/particle/SplashParticle.php similarity index 100% rename from src/pocketmine/world/particle/SplashParticle.php rename to src/world/particle/SplashParticle.php diff --git a/src/pocketmine/world/particle/SporeParticle.php b/src/world/particle/SporeParticle.php similarity index 100% rename from src/pocketmine/world/particle/SporeParticle.php rename to src/world/particle/SporeParticle.php diff --git a/src/pocketmine/world/particle/TerrainParticle.php b/src/world/particle/TerrainParticle.php similarity index 100% rename from src/pocketmine/world/particle/TerrainParticle.php rename to src/world/particle/TerrainParticle.php diff --git a/src/pocketmine/world/particle/WaterDripParticle.php b/src/world/particle/WaterDripParticle.php similarity index 100% rename from src/pocketmine/world/particle/WaterDripParticle.php rename to src/world/particle/WaterDripParticle.php diff --git a/src/pocketmine/world/particle/WaterParticle.php b/src/world/particle/WaterParticle.php similarity index 100% rename from src/pocketmine/world/particle/WaterParticle.php rename to src/world/particle/WaterParticle.php diff --git a/src/pocketmine/world/sound/AnvilBreakSound.php b/src/world/sound/AnvilBreakSound.php similarity index 100% rename from src/pocketmine/world/sound/AnvilBreakSound.php rename to src/world/sound/AnvilBreakSound.php diff --git a/src/pocketmine/world/sound/AnvilFallSound.php b/src/world/sound/AnvilFallSound.php similarity index 100% rename from src/pocketmine/world/sound/AnvilFallSound.php rename to src/world/sound/AnvilFallSound.php diff --git a/src/pocketmine/world/sound/AnvilUseSound.php b/src/world/sound/AnvilUseSound.php similarity index 100% rename from src/pocketmine/world/sound/AnvilUseSound.php rename to src/world/sound/AnvilUseSound.php diff --git a/src/pocketmine/world/sound/ArrowHitSound.php b/src/world/sound/ArrowHitSound.php similarity index 100% rename from src/pocketmine/world/sound/ArrowHitSound.php rename to src/world/sound/ArrowHitSound.php diff --git a/src/pocketmine/world/sound/BlazeShootSound.php b/src/world/sound/BlazeShootSound.php similarity index 100% rename from src/pocketmine/world/sound/BlazeShootSound.php rename to src/world/sound/BlazeShootSound.php diff --git a/src/pocketmine/world/sound/BlockBreakSound.php b/src/world/sound/BlockBreakSound.php similarity index 100% rename from src/pocketmine/world/sound/BlockBreakSound.php rename to src/world/sound/BlockBreakSound.php diff --git a/src/pocketmine/world/sound/BlockPlaceSound.php b/src/world/sound/BlockPlaceSound.php similarity index 100% rename from src/pocketmine/world/sound/BlockPlaceSound.php rename to src/world/sound/BlockPlaceSound.php diff --git a/src/pocketmine/world/sound/BowShootSound.php b/src/world/sound/BowShootSound.php similarity index 100% rename from src/pocketmine/world/sound/BowShootSound.php rename to src/world/sound/BowShootSound.php diff --git a/src/pocketmine/world/sound/BucketEmptyLavaSound.php b/src/world/sound/BucketEmptyLavaSound.php similarity index 100% rename from src/pocketmine/world/sound/BucketEmptyLavaSound.php rename to src/world/sound/BucketEmptyLavaSound.php diff --git a/src/pocketmine/world/sound/BucketEmptyWaterSound.php b/src/world/sound/BucketEmptyWaterSound.php similarity index 100% rename from src/pocketmine/world/sound/BucketEmptyWaterSound.php rename to src/world/sound/BucketEmptyWaterSound.php diff --git a/src/pocketmine/world/sound/BucketFillLavaSound.php b/src/world/sound/BucketFillLavaSound.php similarity index 100% rename from src/pocketmine/world/sound/BucketFillLavaSound.php rename to src/world/sound/BucketFillLavaSound.php diff --git a/src/pocketmine/world/sound/BucketFillWaterSound.php b/src/world/sound/BucketFillWaterSound.php similarity index 100% rename from src/pocketmine/world/sound/BucketFillWaterSound.php rename to src/world/sound/BucketFillWaterSound.php diff --git a/src/pocketmine/world/sound/ChestCloseSound.php b/src/world/sound/ChestCloseSound.php similarity index 100% rename from src/pocketmine/world/sound/ChestCloseSound.php rename to src/world/sound/ChestCloseSound.php diff --git a/src/pocketmine/world/sound/ChestOpenSound.php b/src/world/sound/ChestOpenSound.php similarity index 100% rename from src/pocketmine/world/sound/ChestOpenSound.php rename to src/world/sound/ChestOpenSound.php diff --git a/src/pocketmine/world/sound/ClickSound.php b/src/world/sound/ClickSound.php similarity index 100% rename from src/pocketmine/world/sound/ClickSound.php rename to src/world/sound/ClickSound.php diff --git a/src/pocketmine/world/sound/DoorBumpSound.php b/src/world/sound/DoorBumpSound.php similarity index 100% rename from src/pocketmine/world/sound/DoorBumpSound.php rename to src/world/sound/DoorBumpSound.php diff --git a/src/pocketmine/world/sound/DoorCrashSound.php b/src/world/sound/DoorCrashSound.php similarity index 100% rename from src/pocketmine/world/sound/DoorCrashSound.php rename to src/world/sound/DoorCrashSound.php diff --git a/src/pocketmine/world/sound/DoorSound.php b/src/world/sound/DoorSound.php similarity index 100% rename from src/pocketmine/world/sound/DoorSound.php rename to src/world/sound/DoorSound.php diff --git a/src/pocketmine/world/sound/EnderChestCloseSound.php b/src/world/sound/EnderChestCloseSound.php similarity index 100% rename from src/pocketmine/world/sound/EnderChestCloseSound.php rename to src/world/sound/EnderChestCloseSound.php diff --git a/src/pocketmine/world/sound/EnderChestOpenSound.php b/src/world/sound/EnderChestOpenSound.php similarity index 100% rename from src/pocketmine/world/sound/EnderChestOpenSound.php rename to src/world/sound/EnderChestOpenSound.php diff --git a/src/pocketmine/world/sound/EndermanTeleportSound.php b/src/world/sound/EndermanTeleportSound.php similarity index 100% rename from src/pocketmine/world/sound/EndermanTeleportSound.php rename to src/world/sound/EndermanTeleportSound.php diff --git a/src/pocketmine/world/sound/ExplodeSound.php b/src/world/sound/ExplodeSound.php similarity index 100% rename from src/pocketmine/world/sound/ExplodeSound.php rename to src/world/sound/ExplodeSound.php diff --git a/src/pocketmine/world/sound/FizzSound.php b/src/world/sound/FizzSound.php similarity index 100% rename from src/pocketmine/world/sound/FizzSound.php rename to src/world/sound/FizzSound.php diff --git a/src/pocketmine/world/sound/FlintSteelSound.php b/src/world/sound/FlintSteelSound.php similarity index 100% rename from src/pocketmine/world/sound/FlintSteelSound.php rename to src/world/sound/FlintSteelSound.php diff --git a/src/pocketmine/world/sound/GhastShootSound.php b/src/world/sound/GhastShootSound.php similarity index 100% rename from src/pocketmine/world/sound/GhastShootSound.php rename to src/world/sound/GhastShootSound.php diff --git a/src/pocketmine/world/sound/GhastSound.php b/src/world/sound/GhastSound.php similarity index 100% rename from src/pocketmine/world/sound/GhastSound.php rename to src/world/sound/GhastSound.php diff --git a/src/pocketmine/world/sound/IgniteSound.php b/src/world/sound/IgniteSound.php similarity index 100% rename from src/pocketmine/world/sound/IgniteSound.php rename to src/world/sound/IgniteSound.php diff --git a/src/pocketmine/world/sound/ItemBreakSound.php b/src/world/sound/ItemBreakSound.php similarity index 100% rename from src/pocketmine/world/sound/ItemBreakSound.php rename to src/world/sound/ItemBreakSound.php diff --git a/src/pocketmine/world/sound/LaunchSound.php b/src/world/sound/LaunchSound.php similarity index 100% rename from src/pocketmine/world/sound/LaunchSound.php rename to src/world/sound/LaunchSound.php diff --git a/src/pocketmine/world/sound/LevelEventSound.php b/src/world/sound/LevelEventSound.php similarity index 100% rename from src/pocketmine/world/sound/LevelEventSound.php rename to src/world/sound/LevelEventSound.php diff --git a/src/pocketmine/world/sound/NoteInstrument.php b/src/world/sound/NoteInstrument.php similarity index 100% rename from src/pocketmine/world/sound/NoteInstrument.php rename to src/world/sound/NoteInstrument.php diff --git a/src/pocketmine/world/sound/NoteSound.php b/src/world/sound/NoteSound.php similarity index 100% rename from src/pocketmine/world/sound/NoteSound.php rename to src/world/sound/NoteSound.php diff --git a/src/pocketmine/world/sound/PaintingPlaceSound.php b/src/world/sound/PaintingPlaceSound.php similarity index 100% rename from src/pocketmine/world/sound/PaintingPlaceSound.php rename to src/world/sound/PaintingPlaceSound.php diff --git a/src/pocketmine/world/sound/PopSound.php b/src/world/sound/PopSound.php similarity index 100% rename from src/pocketmine/world/sound/PopSound.php rename to src/world/sound/PopSound.php diff --git a/src/pocketmine/world/sound/PotionSplashSound.php b/src/world/sound/PotionSplashSound.php similarity index 100% rename from src/pocketmine/world/sound/PotionSplashSound.php rename to src/world/sound/PotionSplashSound.php diff --git a/src/pocketmine/world/sound/RedstonePowerOffSound.php b/src/world/sound/RedstonePowerOffSound.php similarity index 100% rename from src/pocketmine/world/sound/RedstonePowerOffSound.php rename to src/world/sound/RedstonePowerOffSound.php diff --git a/src/pocketmine/world/sound/RedstonePowerOnSound.php b/src/world/sound/RedstonePowerOnSound.php similarity index 100% rename from src/pocketmine/world/sound/RedstonePowerOnSound.php rename to src/world/sound/RedstonePowerOnSound.php diff --git a/src/pocketmine/world/sound/Sound.php b/src/world/sound/Sound.php similarity index 100% rename from src/pocketmine/world/sound/Sound.php rename to src/world/sound/Sound.php diff --git a/src/pocketmine/world/sound/ThrowSound.php b/src/world/sound/ThrowSound.php similarity index 100% rename from src/pocketmine/world/sound/ThrowSound.php rename to src/world/sound/ThrowSound.php diff --git a/src/pocketmine/world/sound/TotemUseSound.php b/src/world/sound/TotemUseSound.php similarity index 100% rename from src/pocketmine/world/sound/TotemUseSound.php rename to src/world/sound/TotemUseSound.php diff --git a/src/pocketmine/world/sound/XpCollectSound.php b/src/world/sound/XpCollectSound.php similarity index 100% rename from src/pocketmine/world/sound/XpCollectSound.php rename to src/world/sound/XpCollectSound.php diff --git a/src/pocketmine/world/sound/XpLevelUpSound.php b/src/world/sound/XpLevelUpSound.php similarity index 100% rename from src/pocketmine/world/sound/XpLevelUpSound.php rename to src/world/sound/XpLevelUpSound.php diff --git a/src/pocketmine/world/utils/SubChunkIteratorManager.php b/src/world/utils/SubChunkIteratorManager.php similarity index 100% rename from src/pocketmine/world/utils/SubChunkIteratorManager.php rename to src/world/utils/SubChunkIteratorManager.php diff --git a/tests/plugins/PocketMine-DevTools b/tests/plugins/PocketMine-DevTools index 37abf46440..27fc9126b4 160000 --- a/tests/plugins/PocketMine-DevTools +++ b/tests/plugins/PocketMine-DevTools @@ -1 +1 @@ -Subproject commit 37abf464407ab08d9d458039290ba2a2d72b2c6f +Subproject commit 27fc9126b486c6d8bb208ee613d5626463a546e7 From bf5519b0cf0f646cf466dfd22a8e40e826b538ae Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 30 Jul 2019 19:40:27 +0100 Subject: [PATCH 1150/3224] fix travis --- tests/travis.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/travis.sh b/tests/travis.sh index 6183127bcd..5314995876 100755 --- a/tests/travis.sh +++ b/tests/travis.sh @@ -14,7 +14,7 @@ while getopts "p:t:" OPTION 2> /dev/null; do esac done -./tests/lint.sh -p "$PHP_BINARY" -d ./src/pocketmine +./tests/lint.sh -p "$PHP_BINARY" -d ./src if [ $? -ne 0 ]; then echo Lint scan failed! @@ -37,7 +37,7 @@ cd tests/plugins/PocketMine-DevTools "$PHP_BINARY" -dphar.readonly=0 ./src/DevTools/ConsoleScript.php --make ./ --relative ./ --out ../../../DevTools.phar cd ../../.. -"$PHP_BINARY" -dphar.readonly=0 DevTools.phar --make src,vendor,resources --relative ./ --entry src/pocketmine/PocketMine.php --out PocketMine-MP.phar +"$PHP_BINARY" -dphar.readonly=0 DevTools.phar --make src,vendor,resources --relative ./ --entry src/PocketMine.php --out PocketMine-MP.phar if [ -f PocketMine-MP.phar ]; then echo Server phar created successfully. else From b4c55a8c370c2b00336c98f9fc10e8ffeec22c77 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 31 Jul 2019 15:44:53 +0100 Subject: [PATCH 1151/3224] fix incorrect power calculation of daylight sensor --- src/block/DaylightSensor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/DaylightSensor.php b/src/block/DaylightSensor.php index af05390a52..8f4ad501b0 100644 --- a/src/block/DaylightSensor.php +++ b/src/block/DaylightSensor.php @@ -107,7 +107,7 @@ class DaylightSensor extends Transparent{ } $sunAngle = $this->world->getSunAnglePercentage(); - return max(0, (int) round(15 * cos(($sunAngle + ((($sunAngle < 0.5 ? 0 : 1) - $sunAngle) / 5)) * 2 * M_PI))); + return max(0, (int) round($lightLevel * cos(($sunAngle + ((($sunAngle < 0.5 ? 0 : 1) - $sunAngle) / 5)) * 2 * M_PI))); } //TODO From dc33b9e57385263b846bc09d23a0925a25675c16 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 31 Jul 2019 16:37:25 +0100 Subject: [PATCH 1152/3224] VanillaEffects: add some TODOs --- src/entity/effect/VanillaEffects.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/entity/effect/VanillaEffects.php b/src/entity/effect/VanillaEffects.php index 9b81e2b22a..de8784f573 100644 --- a/src/entity/effect/VanillaEffects.php +++ b/src/entity/effect/VanillaEffects.php @@ -68,6 +68,7 @@ final class VanillaEffects{ protected static function setup() : void{ self::register("absorption", new AbsorptionEffect(22, "%potion.absorption", new Color(0x25, 0x52, 0xa5))); + //TODO: bad_omen self::register("blindness", new Effect(15, "%potion.blindness", new Color(0x1f, 0x1f, 0x23), true)); self::register("conduit_power", new Effect(26, "%potion.conduitPower", new Color(0x1d, 0xc2, 0xd1))); self::register("fatal_poison", new PoisonEffect(25, "%potion.poison", new Color(0x4e, 0x93, 0x31), true, true, true)); @@ -87,9 +88,11 @@ final class VanillaEffects{ self::register("regeneration", new RegenerationEffect(10, "%potion.regeneration", new Color(0xcd, 0x5c, 0xab))); self::register("resistance", new Effect(11, "%potion.resistance", new Color(0x99, 0x45, 0x3a))); self::register("saturation", new SaturationEffect(23, "%potion.saturation", new Color(0xf8, 0x24, 0x23), false)); + //TODO: slow_falling self::register("slowness", new SlownessEffect(2, "%potion.moveSlowdown", new Color(0x5a, 0x6c, 0x81), true)); self::register("speed", new SpeedEffect(1, "%potion.moveSpeed", new Color(0x7c, 0xaf, 0xc6))); self::register("strength", new Effect(5, "%potion.damageBoost", new Color(0x93, 0x24, 0x23))); + //TODO: village_hero self::register("water_breathing", new Effect(13, "%potion.waterBreathing", new Color(0x2e, 0x52, 0x99))); self::register("weakness", new Effect(18, "%potion.weakness", new Color(0x48, 0x4d, 0x48), true)); self::register("wither", new WitherEffect(20, "%potion.wither", new Color(0x35, 0x2a, 0x27), true)); From 296061d25d8a4d61f51e0fab6a4e1ed51fcfc0cc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 31 Jul 2019 16:41:09 +0100 Subject: [PATCH 1153/3224] reduce boilerplate around attribute handling --- src/entity/Attribute.php | 36 +++++++++---------- src/entity/AttributeMap.php | 4 +-- src/entity/Entity.php | 2 +- src/entity/ExperienceManager.php | 4 +-- src/entity/HungerManager.php | 4 +-- src/entity/Living.php | 24 ++++++------- src/entity/effect/SlownessEffect.php | 4 +-- src/entity/effect/SpeedEffect.php | 4 +-- src/network/mcpe/protocol/AddActorPacket.php | 2 +- .../mcpe/serializer/NetworkBinaryStream.php | 2 +- 10 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/entity/Attribute.php b/src/entity/Attribute.php index e65c1fed56..7ce9af10b0 100644 --- a/src/entity/Attribute.php +++ b/src/entity/Attribute.php @@ -60,22 +60,22 @@ class Attribute{ protected static $attributes = []; public static function init() : void{ - self::addAttribute(self::ABSORPTION, 0.00, 340282346638528859811704183484516925440.00, 0.00); - self::addAttribute(self::SATURATION, 0.00, 20.00, 20.00); - self::addAttribute(self::EXHAUSTION, 0.00, 5.00, 0.0, false); - self::addAttribute(self::KNOCKBACK_RESISTANCE, 0.00, 1.00, 0.00); - self::addAttribute(self::HEALTH, 0.00, 20.00, 20.00); - self::addAttribute(self::MOVEMENT_SPEED, 0.00, 340282346638528859811704183484516925440.00, 0.10); - self::addAttribute(self::FOLLOW_RANGE, 0.00, 2048.00, 16.00, false); - self::addAttribute(self::HUNGER, 0.00, 20.00, 20.00); - self::addAttribute(self::ATTACK_DAMAGE, 0.00, 340282346638528859811704183484516925440.00, 1.00, false); - self::addAttribute(self::EXPERIENCE_LEVEL, 0.00, 24791.00, 0.00); - self::addAttribute(self::EXPERIENCE, 0.00, 1.00, 0.00); - self::addAttribute(self::UNDERWATER_MOVEMENT, 0.0, 340282346638528859811704183484516925440.0, 0.02); - self::addAttribute(self::LUCK, -1024.0, 1024.0, 0.0); - self::addAttribute(self::FALL_DAMAGE, 0.0, 340282346638528859811704183484516925440.0, 1.0); - self::addAttribute(self::HORSE_JUMP_STRENGTH, 0.0, 2.0, 0.7); - self::addAttribute(self::ZOMBIE_SPAWN_REINFORCEMENTS, 0.0, 1.0, 0.0); + self::register(self::ABSORPTION, 0.00, 340282346638528859811704183484516925440.00, 0.00); + self::register(self::SATURATION, 0.00, 20.00, 20.00); + self::register(self::EXHAUSTION, 0.00, 5.00, 0.0, false); + self::register(self::KNOCKBACK_RESISTANCE, 0.00, 1.00, 0.00); + self::register(self::HEALTH, 0.00, 20.00, 20.00); + self::register(self::MOVEMENT_SPEED, 0.00, 340282346638528859811704183484516925440.00, 0.10); + self::register(self::FOLLOW_RANGE, 0.00, 2048.00, 16.00, false); + self::register(self::HUNGER, 0.00, 20.00, 20.00); + self::register(self::ATTACK_DAMAGE, 0.00, 340282346638528859811704183484516925440.00, 1.00, false); + self::register(self::EXPERIENCE_LEVEL, 0.00, 24791.00, 0.00); + self::register(self::EXPERIENCE, 0.00, 1.00, 0.00); + self::register(self::UNDERWATER_MOVEMENT, 0.0, 340282346638528859811704183484516925440.0, 0.02); + self::register(self::LUCK, -1024.0, 1024.0, 0.0); + self::register(self::FALL_DAMAGE, 0.0, 340282346638528859811704183484516925440.0, 1.0); + self::register(self::HORSE_JUMP_STRENGTH, 0.0, 2.0, 0.7); + self::register(self::ZOMBIE_SPAWN_REINFORCEMENTS, 0.0, 1.0, 0.0); } /** @@ -89,7 +89,7 @@ class Attribute{ * * @throws \InvalidArgumentException */ - public static function addAttribute(string $id, float $minValue, float $maxValue, float $defaultValue, bool $shouldSend = true) : Attribute{ + public static function register(string $id, float $minValue, float $maxValue, float $defaultValue, bool $shouldSend = true) : Attribute{ if($minValue > $maxValue or $defaultValue > $maxValue or $defaultValue < $minValue){ throw new \InvalidArgumentException("Invalid ranges: min value: $minValue, max value: $maxValue, $defaultValue: $defaultValue"); } @@ -102,7 +102,7 @@ class Attribute{ * * @return Attribute|null */ - public static function getAttribute(string $id) : ?Attribute{ + public static function get(string $id) : ?Attribute{ return isset(self::$attributes[$id]) ? clone self::$attributes[$id] : null; } diff --git a/src/entity/AttributeMap.php b/src/entity/AttributeMap.php index 725db5069c..c042239384 100644 --- a/src/entity/AttributeMap.php +++ b/src/entity/AttributeMap.php @@ -29,7 +29,7 @@ class AttributeMap implements \ArrayAccess{ /** @var Attribute[] */ private $attributes = []; - public function addAttribute(Attribute $attribute) : void{ + public function add(Attribute $attribute) : void{ $this->attributes[$attribute->getId()] = $attribute; } @@ -38,7 +38,7 @@ class AttributeMap implements \ArrayAccess{ * * @return Attribute|null */ - public function getAttribute(string $id) : ?Attribute{ + public function get(string $id) : ?Attribute{ return $this->attributes[$id] ?? null; } diff --git a/src/entity/Entity.php b/src/entity/Entity.php index c046d64330..38f12a6926 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -390,7 +390,7 @@ abstract class Entity extends Location{ public function setSprinting(bool $value = true) : void{ if($value !== $this->isSprinting()){ $this->sprinting = $value; - $attr = $this->attributeMap->getAttribute(Attribute::MOVEMENT_SPEED); + $attr = $this->attributeMap->get(Attribute::MOVEMENT_SPEED); $attr->setValue($value ? ($attr->getValue() * 1.3) : ($attr->getValue() / 1.3), false, true); } } diff --git a/src/entity/ExperienceManager.php b/src/entity/ExperienceManager.php index 9699720479..1c963c43c7 100644 --- a/src/entity/ExperienceManager.php +++ b/src/entity/ExperienceManager.php @@ -58,8 +58,8 @@ class ExperienceManager{ } private static function fetchAttribute(Entity $entity, string $attributeId) : Attribute{ - $entity->getAttributeMap()->addAttribute(Attribute::getAttribute($attributeId)); - return $entity->getAttributeMap()->getAttribute($attributeId); + $entity->getAttributeMap()->add(Attribute::get($attributeId)); + return $entity->getAttributeMap()->get($attributeId); } /** diff --git a/src/entity/HungerManager.php b/src/entity/HungerManager.php index f13e55afc6..77e162c9be 100644 --- a/src/entity/HungerManager.php +++ b/src/entity/HungerManager.php @@ -57,8 +57,8 @@ class HungerManager{ } private static function fetchAttribute(Entity $entity, string $attributeId) : Attribute{ - $entity->getAttributeMap()->addAttribute(Attribute::getAttribute($attributeId)); - return $entity->getAttributeMap()->getAttribute($attributeId); + $entity->getAttributeMap()->add(Attribute::get($attributeId)); + return $entity->getAttributeMap()->get($attributeId); } public function getFood() : float{ diff --git a/src/entity/Living.php b/src/entity/Living.php index d7be4444ee..df48366992 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -145,37 +145,37 @@ abstract class Living extends Entity{ } protected function addAttributes() : void{ - $this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::HEALTH)); - $this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::FOLLOW_RANGE)); - $this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::KNOCKBACK_RESISTANCE)); - $this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::MOVEMENT_SPEED)); - $this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::ATTACK_DAMAGE)); - $this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::ABSORPTION)); + $this->attributeMap->add(Attribute::get(Attribute::HEALTH)); + $this->attributeMap->add(Attribute::get(Attribute::FOLLOW_RANGE)); + $this->attributeMap->add(Attribute::get(Attribute::KNOCKBACK_RESISTANCE)); + $this->attributeMap->add(Attribute::get(Attribute::MOVEMENT_SPEED)); + $this->attributeMap->add(Attribute::get(Attribute::ATTACK_DAMAGE)); + $this->attributeMap->add(Attribute::get(Attribute::ABSORPTION)); } public function setHealth(float $amount) : void{ $wasAlive = $this->isAlive(); parent::setHealth($amount); - $this->attributeMap->getAttribute(Attribute::HEALTH)->setValue(ceil($this->getHealth()), true); + $this->attributeMap->get(Attribute::HEALTH)->setValue(ceil($this->getHealth()), true); if($this->isAlive() and !$wasAlive){ $this->broadcastEntityEvent(ActorEventPacket::RESPAWN); } } public function getMaxHealth() : int{ - return (int) $this->attributeMap->getAttribute(Attribute::HEALTH)->getMaxValue(); + return (int) $this->attributeMap->get(Attribute::HEALTH)->getMaxValue(); } public function setMaxHealth(int $amount) : void{ - $this->attributeMap->getAttribute(Attribute::HEALTH)->setMaxValue($amount)->setDefaultValue($amount); + $this->attributeMap->get(Attribute::HEALTH)->setMaxValue($amount)->setDefaultValue($amount); } public function getAbsorption() : float{ - return $this->attributeMap->getAttribute(Attribute::ABSORPTION)->getValue(); + return $this->attributeMap->get(Attribute::ABSORPTION)->getValue(); } public function setAbsorption(float $absorption) : void{ - $this->attributeMap->getAttribute(Attribute::ABSORPTION)->setValue($absorption); + $this->attributeMap->get(Attribute::ABSORPTION)->setValue($absorption); } public function saveNBT() : CompoundTag{ @@ -476,7 +476,7 @@ abstract class Living extends Entity{ if($f <= 0){ return; } - if(mt_rand() / mt_getrandmax() > $this->getAttributeMap()->getAttribute(Attribute::KNOCKBACK_RESISTANCE)->getValue()){ + if(mt_rand() / mt_getrandmax() > $this->getAttributeMap()->get(Attribute::KNOCKBACK_RESISTANCE)->getValue()){ $f = 1 / $f; $motion = clone $this->motion; diff --git a/src/entity/effect/SlownessEffect.php b/src/entity/effect/SlownessEffect.php index 8fbbc9912b..a2604a1ba0 100644 --- a/src/entity/effect/SlownessEffect.php +++ b/src/entity/effect/SlownessEffect.php @@ -29,12 +29,12 @@ use pocketmine\entity\Living; class SlownessEffect extends Effect{ public function add(Living $entity, EffectInstance $instance) : void{ - $attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED); + $attr = $entity->getAttributeMap()->get(Attribute::MOVEMENT_SPEED); $attr->setValue($attr->getValue() * (1 - 0.15 * $instance->getEffectLevel()), true); } public function remove(Living $entity, EffectInstance $instance) : void{ - $attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED); + $attr = $entity->getAttributeMap()->get(Attribute::MOVEMENT_SPEED); $attr->setValue($attr->getValue() / (1 - 0.15 * $instance->getEffectLevel())); } } diff --git a/src/entity/effect/SpeedEffect.php b/src/entity/effect/SpeedEffect.php index 5f0cc29f52..caafe0b745 100644 --- a/src/entity/effect/SpeedEffect.php +++ b/src/entity/effect/SpeedEffect.php @@ -29,12 +29,12 @@ use pocketmine\entity\Living; class SpeedEffect extends Effect{ public function add(Living $entity, EffectInstance $instance) : void{ - $attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED); + $attr = $entity->getAttributeMap()->get(Attribute::MOVEMENT_SPEED); $attr->setValue($attr->getValue() * (1 + 0.2 * $instance->getEffectLevel())); } public function remove(Living $entity, EffectInstance $instance) : void{ - $attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED); + $attr = $entity->getAttributeMap()->get(Attribute::MOVEMENT_SPEED); $attr->setValue($attr->getValue() / (1 + 0.2 * $instance->getEffectLevel())); } } diff --git a/src/network/mcpe/protocol/AddActorPacket.php b/src/network/mcpe/protocol/AddActorPacket.php index cea94a3015..ecc4f09c02 100644 --- a/src/network/mcpe/protocol/AddActorPacket.php +++ b/src/network/mcpe/protocol/AddActorPacket.php @@ -189,7 +189,7 @@ class AddActorPacket extends DataPacket implements ClientboundPacket{ $min = $this->getLFloat(); $current = $this->getLFloat(); $max = $this->getLFloat(); - $attr = Attribute::getAttribute($id); + $attr = Attribute::get($id); if($attr !== null){ try{ diff --git a/src/network/mcpe/serializer/NetworkBinaryStream.php b/src/network/mcpe/serializer/NetworkBinaryStream.php index 42919c621c..2aa9e12dee 100644 --- a/src/network/mcpe/serializer/NetworkBinaryStream.php +++ b/src/network/mcpe/serializer/NetworkBinaryStream.php @@ -299,7 +299,7 @@ class NetworkBinaryStream extends BinaryStream{ $default = $this->getLFloat(); $id = $this->getString(); - $attr = Attribute::getAttribute($id); + $attr = Attribute::get($id); if($attr !== null){ $attr->setMinValue($min); $attr->setMaxValue($max); From 28c9a2c0cd033d85ee6f948b1719bce7cd9a9c4d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 1 Aug 2019 16:02:05 +0100 Subject: [PATCH 1154/3224] fixed Protection enchantments being dropped from items, closes #3066 --- src/item/Item.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/item/Item.php b/src/item/Item.php index 0df0388e8b..f5896fa3fd 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -297,9 +297,9 @@ class Item implements \JsonSerializable{ if($enchantments !== null and $enchantments->getTagType() === NBT::TAG_Compound){ /** @var CompoundTag $enchantment */ foreach($enchantments as $enchantment){ - $magicNumber = $enchantment->getShort("id", 0, true); + $magicNumber = $enchantment->getShort("id", -1, true); $level = $enchantment->getShort("lvl", 0, true); - if($magicNumber <= 0 or $level <= 0){ + if($level <= 0){ continue; } $type = Enchantment::get($magicNumber); From 5c95e253267cc426c92dbb4fb0114791ecd0aeb8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 1 Aug 2019 16:03:08 +0100 Subject: [PATCH 1155/3224] Enchantment: use a simple array instead of SplFixedArray --- src/item/enchantment/Enchantment.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/item/enchantment/Enchantment.php b/src/item/enchantment/Enchantment.php index 14845b7ea5..e737c962ab 100644 --- a/src/item/enchantment/Enchantment.php +++ b/src/item/enchantment/Enchantment.php @@ -95,11 +95,9 @@ class Enchantment{ public const SLOT_TRIDENT = 0x8000; /** @var Enchantment[] */ - protected static $enchantments; + protected static $enchantments = []; public static function init() : void{ - self::$enchantments = new \SplFixedArray(256); - self::register(new ProtectionEnchantment(self::PROTECTION, "%enchantment.protect.all", self::RARITY_COMMON, self::SLOT_ARMOR, self::SLOT_NONE, 4, 0.75, null)); self::register(new ProtectionEnchantment(self::FIRE_PROTECTION, "%enchantment.protect.fire", self::RARITY_UNCOMMON, self::SLOT_ARMOR, self::SLOT_NONE, 4, 1.25, [ EntityDamageEvent::CAUSE_FIRE, From eaf5226f081642eef80884800cd8c5e7aa676c47 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 1 Aug 2019 17:53:42 +0100 Subject: [PATCH 1156/3224] [ci skip] update changelog --- changelogs/4.0-snapshot.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 203bb054bb..602f1d5018 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -259,10 +259,14 @@ This version features substantial changes to the network system, improving coher #### WIP removal of entity network metadata - All network metadata related constants have been removed from the `Entity` class and moved to the protocol layer. It is intended to remove network metadata from the API entirely, but this has not yet been completed. - - `Entity::DATA_FLAG_*` constants have been moved to `pocketmine\network\mcpe\protocol\types\EntityMetadataFlags`. - - `Entity::DATA_TYPE_*` constants have been moved to `pocketmine\network\mcpe\protocol\types\EntityMetadataTypes`. - - `Entity::DATA_*` constants have been moved to `pocketmine\network\mcpe\protocol\types\EntityMetadataProperties`. -- `DataPropertyManager` has been moved to the `pocketmine\network\mcpe\protocol\types` namespace, and as such isn't considered part of the API anymore. + - `Entity::DATA_FLAG_*` constants have been moved to `pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags`. + - `Entity::DATA_TYPE_*` constants have been moved to `pocketmine\network\mcpe\protocol\types\entity\EntityMetadataTypes`. + - `Entity::DATA_*` constants have been moved to `pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties`. +- `DataPropertyManager` has been moved to the `pocketmine\network\mcpe\protocol\types\entity` namespace, and as such isn't considered part of the API anymore. +- Introduced internal `Entity` hook `syncNetworkData()`. This function is expected to synchronize entity properties with the entity's network data set. +- Internal usage of network metadata sets to store internal entity properties has been removed. Entities are now expected to use regular class properties and synchronize with the network data set as-asked. +- `Entity->propertyManager` has been renamed to `Entity->networkProperties`. +- `Entity->getDataPropertyManager()` has been renamed to `Entity->getNetworkProperties()`. ### Event #### Internal event system no longer depends on `Listener`s From 4818e04540726e72e28f5c3f8099a1fd417c58d4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 1 Aug 2019 18:57:47 +0100 Subject: [PATCH 1157/3224] Player: fix possible comparison bug in setGamemode() --- src/player/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index 61167c4c7d..cfbdddb078 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1117,7 +1117,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool */ public function setGamemode(GameMode $gm) : bool{ - if($this->gamemode === $gm){ + if($this->gamemode->equals($gm)){ return false; } From d09e79e682912dfc1f1f9b7ed040bc816273dc59 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 1 Aug 2019 19:02:06 +0100 Subject: [PATCH 1158/3224] Player: update properties when assigning game mode, fixes #3005 --- src/player/Player.php | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index cfbdddb078..0b4756b104 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -350,12 +350,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->lastPlayed = $nbt->getLong("lastPlayed", $now); if($this->server->getForceGamemode() or !$nbt->hasTag("playerGameType", IntTag::class)){ - $this->gamemode = $this->server->getGamemode(); + $this->internalSetGameMode($this->server->getGamemode()); }else{ - $this->gamemode = GameMode::fromMagicNumber($nbt->getInt("playerGameType") & 0x03); //TODO: bad hack here to avoid crashes on corrupted data + $this->internalSetGameMode(GameMode::fromMagicNumber($nbt->getInt("playerGameType") & 0x03)); //TODO: bad hack here to avoid crashes on corrupted data } - $this->allowFlight = $this->isCreative(); $this->keepMovement = true; if($this->isOp()){ $this->setRemoveFormat(false); @@ -1109,6 +1108,19 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->gamemode; } + protected function internalSetGameMode(GameMode $gameMode) : void{ + $this->gamemode = $gameMode; + + $this->allowFlight = $this->isCreative(); + $this->hungerManager->setEnabled($this->isSurvival()); + + if($this->isSpectator()){ + $this->setFlying(true); + }elseif($this->isSurvival()){ + $this->setFlying(false); + } + } + /** * Sets the gamemode, and if needed, kicks the Player. * @@ -1127,18 +1139,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return false; } - $this->gamemode = $gm; - - $this->allowFlight = $this->isCreative(); - $this->hungerManager->setEnabled($this->isSurvival()); + $this->internalSetGameMode($gm); if($this->isSpectator()){ - $this->setFlying(true); $this->despawnFromAll(); }else{ - if($this->isSurvival()){ - $this->setFlying(false); - } $this->spawnToAll(); } From 7e4236a3ecea46f80e62f5f915eaa5742b5857c8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 1 Aug 2019 19:36:13 +0100 Subject: [PATCH 1159/3224] add a more flexible hook system to EffectManager --- src/entity/Living.php | 18 ------------------ src/entity/effect/EffectManager.php | 29 ++++++++++++++++++++++++++--- src/network/mcpe/NetworkSession.php | 6 ++++++ src/player/Player.php | 8 -------- 4 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/entity/Living.php b/src/entity/Living.php index df48366992..7770bd5f39 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -212,24 +212,6 @@ abstract class Living extends Entity{ return $this->effectManager; } - /** - * @internal - * - * @param EffectInstance $effect - * @param bool $replacesOldEffect - */ - public function onEffectAdded(EffectInstance $effect, bool $replacesOldEffect) : void{ - - } - - /** - * @internal - * @param EffectInstance $effect - */ - public function onEffectRemoved(EffectInstance $effect) : void{ - - } - /** * Causes the mob to consume the given Consumable object, applying applicable effects, health bonuses, food bonuses, * etc. diff --git a/src/entity/effect/EffectManager.php b/src/entity/effect/EffectManager.php index 797b90500c..ab3cef6560 100644 --- a/src/entity/effect/EffectManager.php +++ b/src/entity/effect/EffectManager.php @@ -27,7 +27,9 @@ use pocketmine\entity\Living; use pocketmine\event\entity\EntityEffectAddEvent; use pocketmine\event\entity\EntityEffectRemoveEvent; use pocketmine\utils\Color; +use pocketmine\utils\Utils; use function abs; +use function spl_object_id; class EffectManager{ @@ -42,6 +44,11 @@ class EffectManager{ /** @var bool */ protected $onlyAmbientEffects = false; + /** @var \Closure[] */ + protected $effectAddHooks = []; + /** @var \Closure[] */ + protected $effectRemoveHooks = []; + public function __construct(Living $entity){ $this->entity = $entity; $this->bubbleColor = new Color(0, 0, 0, 0); @@ -78,14 +85,18 @@ class EffectManager{ $ev->call(); if($ev->isCancelled()){ if($hasExpired and !$ev->getEffect()->hasExpired()){ //altered duration of an expired effect to make it not get removed - $this->entity->onEffectAdded($ev->getEffect(), true); + foreach($this->effectAddHooks as $hook){ + $hook($ev->getEffect(), true); + } } return; } unset($this->effects[$index]); $effect->getType()->remove($this->entity, $effect); - $this->entity->onEffectRemoved($effect); + foreach($this->effectRemoveHooks as $hook){ + $hook($effect); + } $this->recalculateEffectColor(); } @@ -151,7 +162,9 @@ class EffectManager{ } $effect->getType()->add($this->entity, $effect); - $this->entity->onEffectAdded($effect, $oldEffect !== null); + foreach($this->effectAddHooks as $hook){ + $hook($effect, $oldEffect !== null); + } $this->effects[$index] = $effect; @@ -218,4 +231,14 @@ class EffectManager{ return !empty($this->effects); } + + public function onEffectAdd(\Closure $closure) : void{ + Utils::validateCallableSignature(function(EffectInstance $effect, bool $replacesOldEffect) : void{}, $closure); + $this->effectAddHooks[spl_object_id($closure)] = $closure; + } + + public function onEffectRemove(\Closure $closure) : void{ + Utils::validateCallableSignature(function(EffectInstance $effect) : void{}, $closure); + $this->effectRemoveHooks[spl_object_id($closure)] = $closure; + } } diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 5acf0394b5..1c1e051553 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -184,6 +184,12 @@ class NetworkSession{ $this->player = new $class($this->server, $this, $this->info, $this->authenticated); $this->invManager = new InventoryManager($this->player, $this); + $this->player->getEffects()->onEffectAdd(function(EffectInstance $effect, bool $replacesOldEffect) : void{ + $this->onEntityEffectAdded($this->player, $effect, $replacesOldEffect); + }); + $this->player->getEffects()->onEffectRemove(function(EffectInstance $effect) : void{ + $this->onEntityEffectRemoved($this->player, $effect); + }); } public function getPlayer() : ?Player{ diff --git a/src/player/Player.php b/src/player/Player.php index 0b4756b104..b6f27f644f 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1453,14 +1453,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->isCreative() or parent::canBreathe(); } - public function onEffectAdded(EffectInstance $effect, bool $replacesOldEffect) : void{ - $this->networkSession->onEntityEffectAdded($this, $effect, $replacesOldEffect); - } - - public function onEffectRemoved(EffectInstance $effect) : void{ - $this->networkSession->onEntityEffectRemoved($this, $effect); - } - /** * Returns whether the player can interact with the specified position. This checks distance and direction. * From 399ef13069cf516881e4a8e39d68d593b97847d9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 1 Aug 2019 19:39:32 +0100 Subject: [PATCH 1160/3224] WritableBookPage: add missing EOF newline --- src/item/WritableBookPage.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/item/WritableBookPage.php b/src/item/WritableBookPage.php index 5f82898e5b..1723db4189 100644 --- a/src/item/WritableBookPage.php +++ b/src/item/WritableBookPage.php @@ -49,4 +49,4 @@ class WritableBookPage{ public function getPhotoName() : string{ return $this->photoName; } -} \ No newline at end of file +} From 135a2f520ca28830415f120dafcf444d47db4ca1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 1 Aug 2019 19:51:31 +0100 Subject: [PATCH 1161/3224] add some UTF-8 validation --- src/block/utils/SignText.php | 5 ++--- src/item/Item.php | 4 +++- src/item/WritableBookPage.php | 5 ++++- src/item/WrittenBook.php | 3 +++ src/utils/Utils.php | 7 +++++++ 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/block/utils/SignText.php b/src/block/utils/SignText.php index 74aea044ba..adefba3070 100644 --- a/src/block/utils/SignText.php +++ b/src/block/utils/SignText.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block\utils; +use pocketmine\utils\Utils; use function array_fill; use function array_pad; use function array_slice; @@ -118,9 +119,7 @@ class SignText{ */ public function setLine(int $index, string $line) : void{ $this->checkLineIndex($index); - if(!mb_check_encoding($line, 'UTF-8')){ - throw new \InvalidArgumentException("Line must be valid UTF-8 text"); - } + Utils::checkUTF8($line); if(strpos($line, "\n") !== false){ throw new \InvalidArgumentException("Line must not contain newlines"); } diff --git a/src/item/Item.php b/src/item/Item.php index f5896fa3fd..3b564bb97b 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -45,6 +45,7 @@ use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\TreeRoot; use pocketmine\player\Player; use pocketmine\utils\Binary; +use pocketmine\utils\Utils; use function base64_decode; use function base64_encode; use function get_class; @@ -163,7 +164,7 @@ class Item implements \JsonSerializable{ * @return $this */ public function setCustomName(string $name) : Item{ - //TODO: encoding might need to be checked here + Utils::checkUTF8($name); $this->customName = $name; return $this; } @@ -193,6 +194,7 @@ class Item implements \JsonSerializable{ if(!is_string($line)){ throw new \TypeError("Expected string[], but found " . gettype($line) . " in given array"); } + Utils::checkUTF8($line); } $this->lore = $lines; return $this; diff --git a/src/item/WritableBookPage.php b/src/item/WritableBookPage.php index 1723db4189..20ce682cba 100644 --- a/src/item/WritableBookPage.php +++ b/src/item/WritableBookPage.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\utils\Utils; + class WritableBookPage{ /** @var string */ @@ -31,7 +33,8 @@ class WritableBookPage{ private $photoName; public function __construct(string $text, string $photoName = ""){ - //TODO: data validation, encoding checks + //TODO: data validation + Utils::checkUTF8($text); $this->text = $text; $this->photoName = $photoName; } diff --git a/src/item/WrittenBook.php b/src/item/WrittenBook.php index 683d904563..e0d5c0fad2 100644 --- a/src/item/WrittenBook.php +++ b/src/item/WrittenBook.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\utils\Utils; class WrittenBook extends WritableBookBase{ @@ -92,6 +93,7 @@ class WrittenBook extends WritableBookBase{ * @return $this */ public function setAuthor(string $authorName) : self{ + Utils::checkUTF8($authorName); $this->author = $authorName; return $this; } @@ -113,6 +115,7 @@ class WrittenBook extends WritableBookBase{ * @return $this */ public function setTitle(string $title) : self{ + Utils::checkUTF8($title); $this->title = $title; return $this; } diff --git a/src/utils/Utils.php b/src/utils/Utils.php index c9eef9d8c8..d6cabe1187 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -57,6 +57,7 @@ use function is_readable; use function is_string; use function json_decode; use function json_last_error_msg; +use function mb_check_encoding; use function ob_end_clean; use function ob_get_contents; use function ob_start; @@ -559,4 +560,10 @@ class Utils{ unlink($dir); } } + + public static function checkUTF8(string $string) : void{ + if(!mb_check_encoding($string, 'UTF-8')){ + throw new \InvalidArgumentException("Text must be valid UTF-8"); + } + } } From 056c5ed6cd0e59160c85f9ca6788f70210bac007 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 1 Aug 2019 20:01:29 +0100 Subject: [PATCH 1162/3224] ItemFactory: break down init() a little --- src/item/ItemFactory.php | 100 +++++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 45 deletions(-) diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index a243cf0d21..21ab8e4ca1 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -55,34 +55,23 @@ class ItemFactory{ public static function init() : void{ self::$list = []; //in case of re-initializing + self::registerArmorItems(); + self::registerTierToolItems(); + self::register(new Apple(ItemIds::APPLE, 0, "Apple")); self::register(new Arrow(ItemIds::ARROW, 0, "Arrow")); - self::register(new Axe(ItemIds::DIAMOND_AXE, "Diamond Axe", ToolTier::DIAMOND())); - self::register(new Axe(ItemIds::GOLDEN_AXE, "Golden Axe", ToolTier::GOLD())); - self::register(new Axe(ItemIds::IRON_AXE, "Iron Axe", ToolTier::IRON())); - self::register(new Axe(ItemIds::STONE_AXE, "Stone Axe", ToolTier::STONE())); - self::register(new Axe(ItemIds::WOODEN_AXE, "Wooden Axe", ToolTier::WOOD())); + self::register(new BakedPotato(ItemIds::BAKED_POTATO, 0, "Baked Potato")); self::register(new Beetroot(ItemIds::BEETROOT, 0, "Beetroot")); self::register(new BeetrootSeeds(ItemIds::BEETROOT_SEEDS, 0, "Beetroot Seeds")); self::register(new BeetrootSoup(ItemIds::BEETROOT_SOUP, 0, "Beetroot Soup")); self::register(new BlazeRod(ItemIds::BLAZE_ROD, 0, "Blaze Rod")); self::register(new Book(ItemIds::BOOK, 0, "Book")); - self::register(new Boots(ItemIds::CHAIN_BOOTS, 0, "Chainmail Boots", new ArmorTypeInfo(1, 196))); - self::register(new Boots(ItemIds::DIAMOND_BOOTS, 0, "Diamond Boots", new ArmorTypeInfo(3, 430))); - self::register(new Boots(ItemIds::GOLDEN_BOOTS, 0, "Golden Boots", new ArmorTypeInfo(1, 92))); - self::register(new Boots(ItemIds::IRON_BOOTS, 0, "Iron Boots", new ArmorTypeInfo(2, 196))); - self::register(new Boots(ItemIds::LEATHER_BOOTS, 0, "Leather Boots", new ArmorTypeInfo(1, 66))); self::register(new Bow(ItemIds::BOW, 0, "Bow")); self::register(new Bowl(ItemIds::BOWL, 0, "Bowl")); self::register(new Bread(ItemIds::BREAD, 0, "Bread")); self::register(new Bucket(ItemIds::BUCKET, 0, "Bucket")); self::register(new Carrot(ItemIds::CARROT, 0, "Carrot")); - self::register(new Chestplate(ItemIds::CHAIN_CHESTPLATE, 0, "Chainmail Chestplate", new ArmorTypeInfo(5, 241))); - self::register(new Chestplate(ItemIds::DIAMOND_CHESTPLATE, 0, "Diamond Chestplate", new ArmorTypeInfo(8, 529))); - self::register(new Chestplate(ItemIds::GOLDEN_CHESTPLATE, 0, "Golden Chestplate", new ArmorTypeInfo(5, 113))); - self::register(new Chestplate(ItemIds::IRON_CHESTPLATE, 0, "Iron Chestplate", new ArmorTypeInfo(6, 241))); - self::register(new Chestplate(ItemIds::LEATHER_CHESTPLATE, 0, "Leather Tunic", new ArmorTypeInfo(3, 81))); self::register(new ChorusFruit(ItemIds::CHORUS_FRUIT, 0, "Chorus Fruit")); self::register(new Clock(ItemIds::CLOCK, 0, "Clock")); self::register(new Clownfish(ItemIds::CLOWNFISH, 0, "Clownfish")); @@ -108,16 +97,6 @@ class ItemFactory{ self::register(new GoldenApple(ItemIds::GOLDEN_APPLE, 0, "Golden Apple")); self::register(new GoldenAppleEnchanted(ItemIds::ENCHANTED_GOLDEN_APPLE, 0, "Enchanted Golden Apple")); self::register(new GoldenCarrot(ItemIds::GOLDEN_CARROT, 0, "Golden Carrot")); - self::register(new Helmet(ItemIds::CHAIN_HELMET, 0, "Chainmail Helmet", new ArmorTypeInfo(2, 166))); - self::register(new Helmet(ItemIds::DIAMOND_HELMET, 0, "Diamond Helmet", new ArmorTypeInfo(3, 364))); - self::register(new Helmet(ItemIds::GOLDEN_HELMET, 0, "Golden Helmet", new ArmorTypeInfo(2, 78))); - self::register(new Helmet(ItemIds::IRON_HELMET, 0, "Iron Helmet", new ArmorTypeInfo(2, 166))); - self::register(new Helmet(ItemIds::LEATHER_HELMET, 0, "Leather Cap", new ArmorTypeInfo(1, 56))); - self::register(new Hoe(ItemIds::DIAMOND_HOE, "Diamond Hoe", ToolTier::DIAMOND())); - self::register(new Hoe(ItemIds::GOLDEN_HOE, "Golden Hoe", ToolTier::GOLD())); - self::register(new Hoe(ItemIds::IRON_HOE, "Iron Hoe", ToolTier::IRON())); - self::register(new Hoe(ItemIds::STONE_HOE, "Stone Hoe", ToolTier::STONE())); - self::register(new Hoe(ItemIds::WOODEN_HOE, "Wooden Hoe", ToolTier::WOOD())); self::register(new Item(ItemIds::BLAZE_POWDER, 0, "Blaze Powder")); self::register(new Item(ItemIds::BLEACH, 0, "Bleach")); //EDU self::register(new Item(ItemIds::BONE, 0, "Bone")); @@ -212,11 +191,6 @@ class ItemFactory{ self::register(new ItemBlock(BlockLegacyIds::REPEATER_BLOCK, 0, ItemIds::REPEATER)); self::register(new ItemBlock(BlockLegacyIds::SPRUCE_DOOR_BLOCK, 0, ItemIds::SPRUCE_DOOR)); self::register(new ItemBlock(BlockLegacyIds::SUGARCANE_BLOCK, 0, ItemIds::SUGARCANE)); - self::register(new Leggings(ItemIds::CHAIN_LEGGINGS, 0, "Chainmail Leggings", new ArmorTypeInfo(4, 226))); - self::register(new Leggings(ItemIds::DIAMOND_LEGGINGS, 0, "Diamond Leggings", new ArmorTypeInfo(6, 496))); - self::register(new Leggings(ItemIds::GOLDEN_LEGGINGS, 0, "Golden Leggings", new ArmorTypeInfo(3, 106))); - self::register(new Leggings(ItemIds::IRON_LEGGINGS, 0, "Iron Leggings", new ArmorTypeInfo(5, 226))); - self::register(new Leggings(ItemIds::LEATHER_LEGGINGS, 0, "Leather Pants", new ArmorTypeInfo(2, 76))); //TODO: fix metadata for buckets with still liquid in them //the meta values are intentionally hardcoded because block IDs will change in the future self::register(new LiquidBucket(ItemIds::BUCKET, 8, "Water Bucket", VanillaBlocks::WATER())); @@ -227,11 +201,6 @@ class ItemFactory{ self::register(new Minecart(ItemIds::MINECART, 0, "Minecart")); self::register(new MushroomStew(ItemIds::MUSHROOM_STEW, 0, "Mushroom Stew")); self::register(new PaintingItem(ItemIds::PAINTING, 0, "Painting")); - self::register(new Pickaxe(ItemIds::DIAMOND_PICKAXE, "Diamond Pickaxe", ToolTier::DIAMOND())); - self::register(new Pickaxe(ItemIds::GOLDEN_PICKAXE, "Golden Pickaxe", ToolTier::GOLD())); - self::register(new Pickaxe(ItemIds::IRON_PICKAXE, "Iron Pickaxe", ToolTier::IRON())); - self::register(new Pickaxe(ItemIds::STONE_PICKAXE, "Stone Pickaxe", ToolTier::STONE())); - self::register(new Pickaxe(ItemIds::WOODEN_PICKAXE, "Wooden Pickaxe", ToolTier::WOOD())); self::register(new PoisonousPotato(ItemIds::POISONOUS_POTATO, 0, "Poisonous Potato")); self::register(new Potato(ItemIds::POTATO, 0, "Potato")); self::register(new Pufferfish(ItemIds::PUFFERFISH, 0, "Pufferfish")); @@ -248,11 +217,6 @@ class ItemFactory{ self::register(new Redstone(ItemIds::REDSTONE, 0, "Redstone")); self::register(new RottenFlesh(ItemIds::ROTTEN_FLESH, 0, "Rotten Flesh")); self::register(new Shears(ItemIds::SHEARS, 0, "Shears")); - self::register(new Shovel(ItemIds::DIAMOND_SHOVEL, "Diamond Shovel", ToolTier::DIAMOND())); - self::register(new Shovel(ItemIds::GOLDEN_SHOVEL, "Golden Shovel", ToolTier::GOLD())); - self::register(new Shovel(ItemIds::IRON_SHOVEL, "Iron Shovel", ToolTier::IRON())); - self::register(new Shovel(ItemIds::STONE_SHOVEL, "Stone Shovel", ToolTier::STONE())); - self::register(new Shovel(ItemIds::WOODEN_SHOVEL, "Wooden Shovel", ToolTier::WOOD())); self::register(new Sign(BlockLegacyIds::STANDING_SIGN, 0, ItemIds::SIGN)); self::register(new Sign(BlockLegacyIds::SPRUCE_STANDING_SIGN, 0, ItemIds::SPRUCE_SIGN)); self::register(new Sign(BlockLegacyIds::BIRCH_STANDING_SIGN, 0, ItemIds::BIRCH_SIGN)); @@ -264,11 +228,6 @@ class ItemFactory{ self::register(new Steak(ItemIds::STEAK, 0, "Steak")); self::register(new Stick(ItemIds::STICK, 0, "Stick")); self::register(new StringItem(ItemIds::STRING, 0, "String")); - self::register(new Sword(ItemIds::DIAMOND_SWORD, "Diamond Sword", ToolTier::DIAMOND())); - self::register(new Sword(ItemIds::GOLDEN_SWORD, "Golden Sword", ToolTier::GOLD())); - self::register(new Sword(ItemIds::IRON_SWORD, "Iron Sword", ToolTier::IRON())); - self::register(new Sword(ItemIds::STONE_SWORD, "Stone Sword", ToolTier::STONE())); - self::register(new Sword(ItemIds::WOODEN_SWORD, "Wooden Sword", ToolTier::WOOD())); self::register(new Totem(ItemIds::TOTEM, 0, "Totem of Undying")); self::register(new WheatSeeds(ItemIds::WHEAT_SEEDS, 0, "Wheat Seeds")); self::register(new WritableBook(ItemIds::WRITABLE_BOOK, 0, "Book & Quill")); @@ -363,6 +322,57 @@ class ItemFactory{ //endregion } + private static function registerTierToolItems() : void{ + self::register(new Axe(ItemIds::DIAMOND_AXE, "Diamond Axe", ToolTier::DIAMOND())); + self::register(new Axe(ItemIds::GOLDEN_AXE, "Golden Axe", ToolTier::GOLD())); + self::register(new Axe(ItemIds::IRON_AXE, "Iron Axe", ToolTier::IRON())); + self::register(new Axe(ItemIds::STONE_AXE, "Stone Axe", ToolTier::STONE())); + self::register(new Axe(ItemIds::WOODEN_AXE, "Wooden Axe", ToolTier::WOOD())); + self::register(new Hoe(ItemIds::DIAMOND_HOE, "Diamond Hoe", ToolTier::DIAMOND())); + self::register(new Hoe(ItemIds::GOLDEN_HOE, "Golden Hoe", ToolTier::GOLD())); + self::register(new Hoe(ItemIds::IRON_HOE, "Iron Hoe", ToolTier::IRON())); + self::register(new Hoe(ItemIds::STONE_HOE, "Stone Hoe", ToolTier::STONE())); + self::register(new Hoe(ItemIds::WOODEN_HOE, "Wooden Hoe", ToolTier::WOOD())); + self::register(new Pickaxe(ItemIds::DIAMOND_PICKAXE, "Diamond Pickaxe", ToolTier::DIAMOND())); + self::register(new Pickaxe(ItemIds::GOLDEN_PICKAXE, "Golden Pickaxe", ToolTier::GOLD())); + self::register(new Pickaxe(ItemIds::IRON_PICKAXE, "Iron Pickaxe", ToolTier::IRON())); + self::register(new Pickaxe(ItemIds::STONE_PICKAXE, "Stone Pickaxe", ToolTier::STONE())); + self::register(new Pickaxe(ItemIds::WOODEN_PICKAXE, "Wooden Pickaxe", ToolTier::WOOD())); + self::register(new Shovel(ItemIds::DIAMOND_SHOVEL, "Diamond Shovel", ToolTier::DIAMOND())); + self::register(new Shovel(ItemIds::GOLDEN_SHOVEL, "Golden Shovel", ToolTier::GOLD())); + self::register(new Shovel(ItemIds::IRON_SHOVEL, "Iron Shovel", ToolTier::IRON())); + self::register(new Shovel(ItemIds::STONE_SHOVEL, "Stone Shovel", ToolTier::STONE())); + self::register(new Shovel(ItemIds::WOODEN_SHOVEL, "Wooden Shovel", ToolTier::WOOD())); + self::register(new Sword(ItemIds::DIAMOND_SWORD, "Diamond Sword", ToolTier::DIAMOND())); + self::register(new Sword(ItemIds::GOLDEN_SWORD, "Golden Sword", ToolTier::GOLD())); + self::register(new Sword(ItemIds::IRON_SWORD, "Iron Sword", ToolTier::IRON())); + self::register(new Sword(ItemIds::STONE_SWORD, "Stone Sword", ToolTier::STONE())); + self::register(new Sword(ItemIds::WOODEN_SWORD, "Wooden Sword", ToolTier::WOOD())); + } + + private static function registerArmorItems() : void{ + self::register(new Boots(ItemIds::CHAIN_BOOTS, 0, "Chainmail Boots", new ArmorTypeInfo(1, 196))); + self::register(new Boots(ItemIds::DIAMOND_BOOTS, 0, "Diamond Boots", new ArmorTypeInfo(3, 430))); + self::register(new Boots(ItemIds::GOLDEN_BOOTS, 0, "Golden Boots", new ArmorTypeInfo(1, 92))); + self::register(new Boots(ItemIds::IRON_BOOTS, 0, "Iron Boots", new ArmorTypeInfo(2, 196))); + self::register(new Boots(ItemIds::LEATHER_BOOTS, 0, "Leather Boots", new ArmorTypeInfo(1, 66))); + self::register(new Chestplate(ItemIds::CHAIN_CHESTPLATE, 0, "Chainmail Chestplate", new ArmorTypeInfo(5, 241))); + self::register(new Chestplate(ItemIds::DIAMOND_CHESTPLATE, 0, "Diamond Chestplate", new ArmorTypeInfo(8, 529))); + self::register(new Chestplate(ItemIds::GOLDEN_CHESTPLATE, 0, "Golden Chestplate", new ArmorTypeInfo(5, 113))); + self::register(new Chestplate(ItemIds::IRON_CHESTPLATE, 0, "Iron Chestplate", new ArmorTypeInfo(6, 241))); + self::register(new Chestplate(ItemIds::LEATHER_CHESTPLATE, 0, "Leather Tunic", new ArmorTypeInfo(3, 81))); + self::register(new Helmet(ItemIds::CHAIN_HELMET, 0, "Chainmail Helmet", new ArmorTypeInfo(2, 166))); + self::register(new Helmet(ItemIds::DIAMOND_HELMET, 0, "Diamond Helmet", new ArmorTypeInfo(3, 364))); + self::register(new Helmet(ItemIds::GOLDEN_HELMET, 0, "Golden Helmet", new ArmorTypeInfo(2, 78))); + self::register(new Helmet(ItemIds::IRON_HELMET, 0, "Iron Helmet", new ArmorTypeInfo(2, 166))); + self::register(new Helmet(ItemIds::LEATHER_HELMET, 0, "Leather Cap", new ArmorTypeInfo(1, 56))); + self::register(new Leggings(ItemIds::CHAIN_LEGGINGS, 0, "Chainmail Leggings", new ArmorTypeInfo(4, 226))); + self::register(new Leggings(ItemIds::DIAMOND_LEGGINGS, 0, "Diamond Leggings", new ArmorTypeInfo(6, 496))); + self::register(new Leggings(ItemIds::GOLDEN_LEGGINGS, 0, "Golden Leggings", new ArmorTypeInfo(3, 106))); + self::register(new Leggings(ItemIds::IRON_LEGGINGS, 0, "Iron Leggings", new ArmorTypeInfo(5, 226))); + self::register(new Leggings(ItemIds::LEATHER_LEGGINGS, 0, "Leather Pants", new ArmorTypeInfo(2, 76))); + } + /** * Registers an item type into the index. Plugins may use this method to register new item types or override existing * ones. From 58e9728710ff945dd7c5705a66668c95143463a2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 2 Aug 2019 16:17:04 +0100 Subject: [PATCH 1163/3224] Removing useless armour descendent classes, move armour slot to ArmorTypeInfo --- changelogs/4.0-snapshot.md | 4 ---- src/item/Armor.php | 6 ++++-- src/item/ArmorTypeInfo.php | 12 ++++++++++- src/item/Boots.php | 33 ------------------------------ src/item/Chestplate.php | 33 ------------------------------ src/item/Helmet.php | 33 ------------------------------ src/item/ItemFactory.php | 41 +++++++++++++++++++------------------- src/item/Leggings.php | 33 ------------------------------ src/item/VanillaItems.php | 40 ++++++++++++++++++------------------- 9 files changed, 56 insertions(+), 179 deletions(-) delete mode 100644 src/item/Boots.php delete mode 100644 src/item/Chestplate.php delete mode 100644 src/item/Helmet.php delete mode 100644 src/item/Leggings.php diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 602f1d5018..4299cf2105 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -434,11 +434,7 @@ This version features substantial changes to the network system, improving coher - `Item::removeCreativeItem()` -> `CreativeInventory::remove()` - The following classes have been added: - `ArmorTypeInfo` - - `Boots` - - `Chestplate` - `Fertilizer` - - `Helmet` - - `Leggings` - `LiquidBucket` - `MilkBucket` - `WritableBookBase` diff --git a/src/item/Armor.php b/src/item/Armor.php index afd880e049..d2b5759ea1 100644 --- a/src/item/Armor.php +++ b/src/item/Armor.php @@ -38,7 +38,7 @@ use pocketmine\utils\Color; use function lcg_value; use function mt_rand; -abstract class Armor extends Durable{ +class Armor extends Durable{ public const TAG_CUSTOM_COLOR = "customColor"; //TAG_Int @@ -65,7 +65,9 @@ abstract class Armor extends Durable{ * @see ArmorInventory * @return int */ - abstract public function getArmorSlot() : int; + public function getArmorSlot() : int{ + return $this->armorInfo->getArmorSlot(); + } public function getMaxStackSize() : int{ return 1; diff --git a/src/item/ArmorTypeInfo.php b/src/item/ArmorTypeInfo.php index 9a89a0c5df..172a590b86 100644 --- a/src/item/ArmorTypeInfo.php +++ b/src/item/ArmorTypeInfo.php @@ -29,10 +29,13 @@ class ArmorTypeInfo{ private $defensePoints; /** @var int */ private $maxDurability; + /** @var int */ + private $armorSlot; - public function __construct(int $defensePoints, int $maxDurability){ + public function __construct(int $defensePoints, int $maxDurability, int $armorSlot){ $this->defensePoints = $defensePoints; $this->maxDurability = $maxDurability; + $this->armorSlot = $armorSlot; } /** @@ -48,4 +51,11 @@ class ArmorTypeInfo{ public function getMaxDurability() : int{ return $this->maxDurability; } + + /** + * @return int + */ + public function getArmorSlot() : int{ + return $this->armorSlot; + } } diff --git a/src/item/Boots.php b/src/item/Boots.php deleted file mode 100644 index 13753328dd..0000000000 --- a/src/item/Boots.php +++ /dev/null @@ -1,33 +0,0 @@ - Date: Fri, 2 Aug 2019 16:26:04 +0100 Subject: [PATCH 1164/3224] [ci skip] changelog update --- changelogs/4.0-snapshot.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 4299cf2105..c0b2568074 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -61,6 +61,7 @@ This version features substantial changes to the network system, improving coher - Everything in the `pocketmine\metadata` namespace and related implementations have been removed. ### Block +- A new `VanillaBlocks` class has been added, which contains static methods for creating any currently-known block type. This should be preferred instead of use of `BlockFactory::get()` where constants were used. - Blocks with IDs >= 256 are now supported. - Block state and variant metadata have been separated. - Variant is considered an extension of ID and is immutable. @@ -396,6 +397,7 @@ This version features substantial changes to the network system, improving coher ### Item #### General +- A new `VanillaItems` class has been added, which contains static methods for creating any currently-known item type. This should be preferred instead of use of `ItemFactory::get()` where constants were used. - `Item->count` is no longer public. - The hierarchy of writable books has been changed: `WritableBook` and `WrittenBook` now extend `WritableBookBase`. - The following API methods have signature changes: From 56dc3ce6ee29c263188ad538184eea5d5cee0d48 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 2 Aug 2019 16:41:30 +0100 Subject: [PATCH 1165/3224] Human: remove obsolete comment from sendSpawnPacket() the referenced function doesn't exist anymore. --- src/entity/Human.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/entity/Human.php b/src/entity/Human.php index c17d1d2bc5..838b0c6bb8 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -405,7 +405,6 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ protected function sendSpawnPacket(Player $player) : void{ if(!($this instanceof Player)){ - /* we don't use Server->updatePlayerListData() because that uses batches, which could cause race conditions in async compression mode */ $player->sendDataPacket(PlayerListPacket::add([PlayerListEntry::createAdditionEntry($this->uuid, $this->id, $this->getName(), $this->skin)])); } From cc4b2959a7c57e3f28dd81815e3764458bed1880 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 2 Aug 2019 16:43:45 +0100 Subject: [PATCH 1166/3224] Player: ditch deprecated dataPacket() it doesn't make sense to deprecate this on a major version, particularly given all the other changes that plugin devs will have to accommodate. --- src/player/Player.php | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index b6f27f644f..0c66e50c10 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1917,18 +1917,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->networkSession->sendDataPacket($packet, $immediate); } - /** - * @deprecated This is a proxy for sendDataPacket() and will be removed in the next major release. - * @see Player::sendDataPacket() - * - * @param ClientboundPacket $packet - * - * @return bool - */ - public function dataPacket(ClientboundPacket $packet) : bool{ - return $this->sendDataPacket($packet, false); - } - /** * Adds a title text to the user's screen, with an optional subtitle. * From c1ef5ba8ab0f1799bbf49d86fd7f56370ff87b0c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 2 Aug 2019 17:10:58 +0100 Subject: [PATCH 1167/3224] Entity: remove redundant check from spawnToAll() --- src/entity/Entity.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 38f12a6926..8f19b3151b 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1627,7 +1627,7 @@ abstract class Entity extends Location{ } public function spawnToAll() : void{ - if($this->chunk === null or $this->closed){ + if($this->closed){ return; } foreach($this->world->getViewersForPosition($this) as $player){ From e03f918806354d1fd18523a6fbd98c6c409d3038 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 2 Aug 2019 17:19:14 +0100 Subject: [PATCH 1168/3224] AttributeMap: drop ArrayAccess interface this makes no sense because it isn't type safe and isn't used anywhere. It's just extra maintenance cost for no good reason. --- src/entity/AttributeMap.php | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/src/entity/AttributeMap.php b/src/entity/AttributeMap.php index c042239384..70575c869e 100644 --- a/src/entity/AttributeMap.php +++ b/src/entity/AttributeMap.php @@ -25,7 +25,7 @@ namespace pocketmine\entity; use function array_filter; -class AttributeMap implements \ArrayAccess{ +class AttributeMap{ /** @var Attribute[] */ private $attributes = []; @@ -57,29 +57,4 @@ class AttributeMap implements \ArrayAccess{ return $attribute->isSyncable() and $attribute->isDesynchronized(); }); } - - public function offsetExists($offset) : bool{ - return isset($this->attributes[$offset]); - } - - /** - * @param string $offset - * - * @return float - */ - public function offsetGet($offset) : float{ - return $this->attributes[$offset]->getValue(); - } - - /** - * @param string $offset - * @param float $value - */ - public function offsetSet($offset, $value) : void{ - $this->attributes[$offset]->setValue($value); - } - - public function offsetUnset($offset) : void{ - throw new \RuntimeException("Could not unset an attribute from an attribute map"); - } } From 1cd955c216dee303976248451a1f87db140787ed Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 2 Aug 2019 17:29:32 +0100 Subject: [PATCH 1169/3224] Entity: added getEyePos() --- src/entity/Entity.php | 4 ++++ src/entity/projectile/SplashPotion.php | 2 +- src/item/Bow.php | 2 +- src/item/ProjectileItem.php | 2 +- src/player/Player.php | 2 +- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 8f19b3151b..f1df172285 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1171,6 +1171,10 @@ abstract class Entity extends Location{ return $this->eyeHeight; } + public function getEyePos() : Vector3{ + return new Vector3($this->x, $this->y + $this->getEyeHeight(), $this->z); + } + public function onCollideWithPlayer(Player $player) : void{ } diff --git a/src/entity/projectile/SplashPotion.php b/src/entity/projectile/SplashPotion.php index 5c4aff1fd1..fccc8f02e7 100644 --- a/src/entity/projectile/SplashPotion.php +++ b/src/entity/projectile/SplashPotion.php @@ -96,7 +96,7 @@ class SplashPotion extends Throwable{ if(!$this->willLinger()){ foreach($this->world->getNearbyEntities($this->boundingBox->expandedCopy(4.125, 2.125, 4.125), $this) as $entity){ if($entity instanceof Living and $entity->isAlive()){ - $distanceSquared = $entity->add(0, $entity->getEyeHeight(), 0)->distanceSquared($this); + $distanceSquared = $entity->getEyePos()->distanceSquared($this); if($distanceSquared > 16){ //4 blocks continue; } diff --git a/src/item/Bow.php b/src/item/Bow.php index 0cc6b4f9a4..9aabc9a87a 100644 --- a/src/item/Bow.php +++ b/src/item/Bow.php @@ -51,7 +51,7 @@ class Bow extends Tool{ } $nbt = EntityFactory::createBaseNBT( - $player->add(0, $player->getEyeHeight(), 0), + $player->getEyePos(), $player->getDirectionVector(), ($player->yaw > 180 ? 360 : 0) - $player->yaw, -$player->pitch diff --git a/src/item/ProjectileItem.php b/src/item/ProjectileItem.php index b0a939a891..ecbc0fdc64 100644 --- a/src/item/ProjectileItem.php +++ b/src/item/ProjectileItem.php @@ -53,7 +53,7 @@ abstract class ProjectileItem extends Item{ } public function onClickAir(Player $player, Vector3 $directionVector) : ItemUseResult{ - $nbt = EntityFactory::createBaseNBT($player->add(0, $player->getEyeHeight(), 0), $directionVector, $player->yaw, $player->pitch); + $nbt = EntityFactory::createBaseNBT($player->getEyePos(), $directionVector, $player->yaw, $player->pitch); $this->addExtraTags($nbt); $class = $this->getProjectileEntityClass(); diff --git a/src/player/Player.php b/src/player/Player.php index 0c66e50c10..85d03c506d 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1463,7 +1463,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool */ public function canInteract(Vector3 $pos, float $maxDistance, float $maxDiff = M_SQRT3 / 2) : bool{ - $eyePos = $this->getPosition()->add(0, $this->getEyeHeight(), 0); + $eyePos = $this->getEyePos(); if($eyePos->distanceSquared($pos) > $maxDistance ** 2){ return false; } From 1fcec87b98c093c41c3245aea840c0d25948f41d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 3 Aug 2019 17:13:02 +0100 Subject: [PATCH 1170/3224] Block: remove unused function --- src/block/Block.php | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/block/Block.php b/src/block/Block.php index b9d048afc9..03c820e3f5 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -734,16 +734,4 @@ class Block extends Position{ return $currentHit; } - - /** - * @param self $self - * - * @return static - */ - public static function cast(self $self){ - if(!($self instanceof static)){ - throw new \TypeError("Cannot cast from " . self::class . " to " . static::class); - } - return $self; - } } From cf271dab2bd151131200dbb96e46ac0e3878ac74 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 5 Aug 2019 16:19:49 +0100 Subject: [PATCH 1171/3224] Entity: fixed undefined variable in getTargetEntity() --- src/entity/Entity.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index f1df172285..d38e571de0 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -494,7 +494,7 @@ abstract class Entity extends Location{ * @return Entity|null */ public function getTargetEntity() : ?Entity{ - return $this->targetId !== null ? $this->server->getWorldManager()->findEntity($eid) : null; + return $this->targetId !== null ? $this->server->getWorldManager()->findEntity($this->targetId) : null; } /** From 53ab860db514cad5c5e37bb4d2efb29825d0871a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 5 Aug 2019 16:44:09 +0100 Subject: [PATCH 1172/3224] first shot making Block not extend Position this makes some stuff a lot less pretty, but this seems to be the bare minimum necessary to do this task. It can be enhanced later. --- src/block/Anvil.php | 2 +- src/block/Banner.php | 6 +- src/block/BaseRail.php | 9 +- src/block/Bed.php | 16 ++-- src/block/Block.php | 43 +++++---- src/block/BrewingStand.php | 2 +- src/block/Button.php | 10 +- src/block/Cactus.php | 12 +-- src/block/Cake.php | 4 +- src/block/Carpet.php | 2 +- src/block/Chest.php | 6 +- src/block/CoarseDirt.php | 2 +- src/block/CocoaBlock.php | 6 +- src/block/ConcretePowder.php | 2 +- src/block/Crops.php | 6 +- src/block/DaylightSensor.php | 10 +- src/block/DeadBush.php | 2 +- src/block/Dirt.php | 2 +- src/block/Door.php | 10 +- src/block/DoublePlant.php | 4 +- src/block/DragonEgg.php | 20 ++-- src/block/EnchantingTable.php | 2 +- src/block/EnderChest.php | 2 +- src/block/Farmland.php | 14 +-- src/block/FenceGate.php | 6 +- src/block/Fire.php | 12 +-- src/block/Flower.php | 2 +- src/block/FlowerPot.php | 8 +- src/block/FrostedIce.php | 18 ++-- src/block/Furnace.php | 6 +- src/block/Grass.php | 26 +++--- src/block/GrassPath.php | 2 +- src/block/Hopper.php | 2 +- src/block/Ice.php | 6 +- src/block/ItemFrame.php | 12 +-- src/block/Ladder.php | 4 +- src/block/Lantern.php | 8 +- src/block/Leaves.php | 13 +-- src/block/Lever.php | 28 +++--- src/block/Liquid.php | 91 ++++++++++--------- src/block/Mycelium.php | 11 ++- src/block/NetherWartPlant.php | 4 +- src/block/Note.php | 4 +- src/block/RedMushroom.php | 2 +- src/block/RedstoneComparator.php | 8 +- src/block/RedstoneOre.php | 6 +- src/block/RedstoneRepeater.php | 4 +- src/block/Sapling.php | 10 +- src/block/Sign.php | 8 +- src/block/Skull.php | 4 +- src/block/SnowLayer.php | 4 +- src/block/Stem.php | 4 +- src/block/Sugarcane.php | 16 ++-- src/block/TNT.php | 6 +- src/block/TallGrass.php | 2 +- src/block/Torch.php | 2 +- src/block/Trapdoor.php | 4 +- src/block/Vine.php | 4 +- src/block/WaterLily.php | 2 +- src/block/tile/BrewingStand.php | 2 +- src/block/tile/Furnace.php | 4 +- src/block/utils/FallableTrait.php | 4 +- src/entity/Entity.php | 4 +- src/entity/projectile/EnderPearl.php | 3 +- src/entity/projectile/Projectile.php | 9 +- src/entity/projectile/SplashPotion.php | 4 +- src/item/Bucket.php | 4 +- src/item/FlintSteel.php | 4 +- src/item/LiquidBucket.php | 4 +- src/item/PaintingItem.php | 16 ++-- src/item/SpawnEgg.php | 2 +- .../mcpe/handler/InGamePacketHandler.php | 2 +- src/player/Player.php | 2 +- src/world/ChunkListener.php | 3 +- src/world/World.php | 52 +++++------ 75 files changed, 337 insertions(+), 325 deletions(-) diff --git a/src/block/Anvil.php b/src/block/Anvil.php index bdd79597cd..311dee1a5d 100644 --- a/src/block/Anvil.php +++ b/src/block/Anvil.php @@ -63,7 +63,7 @@ class Anvil extends Transparent implements Fallable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $player->setCurrentWindow(new AnvilInventory($this)); + $player->setCurrentWindow(new AnvilInventory($this->pos)); } return true; diff --git a/src/block/Banner.php b/src/block/Banner.php index e001d582cf..7f6f62b8a9 100644 --- a/src/block/Banner.php +++ b/src/block/Banner.php @@ -95,7 +95,7 @@ class Banner extends Transparent{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->world->getTile($this); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileBanner){ $this->baseColor = $tile->getBaseColor(); $this->setPatterns($tile->getPatterns()); @@ -104,7 +104,7 @@ class Banner extends Transparent{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->world->getTile($this); + $tile = $this->pos->getWorld()->getTile($this->pos); assert($tile instanceof TileBanner); $tile->setBaseColor($this->baseColor); $tile->setPatterns($this->patterns); @@ -163,7 +163,7 @@ class Banner extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::opposite($this->facing))->getId() === BlockLegacyIds::AIR){ - $this->getWorld()->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/BaseRail.php b/src/block/BaseRail.php index 501f65365b..55105edc44 100644 --- a/src/block/BaseRail.php +++ b/src/block/BaseRail.php @@ -36,6 +36,7 @@ use function array_shift; use function count; use function implode; use function in_array; +use pocketmine\world\Position; abstract class BaseRail extends Flowable{ @@ -244,7 +245,7 @@ abstract class BaseRail extends Flowable{ if(isset($otherPossible[$otherSide])){ $otherConnections[] = $otherSide; $other->setConnections($otherConnections); - $other->world->setBlock($other, $other); + $this->pos->getWorld()->setBlock($other->pos, $other); $changed = true; $thisConnections[] = $thisSide; @@ -257,7 +258,7 @@ abstract class BaseRail extends Flowable{ if($changed){ $this->setConnections($thisConnections); - $this->world->setBlock($this, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } } @@ -273,11 +274,11 @@ abstract class BaseRail extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->world->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); }else{ foreach($this->connections as $connection){ if(($connection & self::FLAG_ASCEND) !== 0 and $this->getSide($connection & ~self::FLAG_ASCEND)->isTransparent()){ - $this->world->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); break; } } diff --git a/src/block/Bed.php b/src/block/Bed.php index 0f6a5963da..3a7ab99783 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -73,7 +73,7 @@ class Bed extends Transparent{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); //read extra state information from the tile - this is an ugly hack - $tile = $this->world->getTile($this); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileBed){ $this->color = $tile->getColor(); } @@ -82,7 +82,7 @@ class Bed extends Transparent{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); //extra block properties storage hack - $tile = $this->world->getTile($this); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileBed){ $tile->setColor($this->color); } @@ -105,11 +105,11 @@ class Bed extends Transparent{ public function setOccupied(bool $occupied = true) : void{ $this->occupied = $occupied; - $this->world->setBlock($this, $this, false); + $this->pos->getWorld()->setBlock($this->pos, $this, false); if(($other = $this->getOtherHalf()) !== null){ $other->occupied = $occupied; - $this->world->setBlock($other, $other, false); + $this->pos->getWorld()->setBlock($other->pos, $other, false); } } @@ -139,12 +139,12 @@ class Bed extends Transparent{ $player->sendMessage(TextFormat::GRAY . "This bed is incomplete"); return true; - }elseif($player->distanceSquared($this) > 4 and $player->distanceSquared($other) > 4){ + }elseif($player->distanceSquared($this->pos) > 4 and $player->distanceSquared($other->pos) > 4){ $player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.tooFar")); return true; } - $time = $this->getWorld()->getTimeOfDay(); + $time = $this->pos->getWorld()->getTimeOfDay(); $isNight = ($time >= World::TIME_NIGHT and $time < World::TIME_SUNRISE); @@ -162,7 +162,7 @@ class Bed extends Transparent{ return true; } - $player->sleepOn($b); + $player->sleepOn($b->pos); } return true; @@ -181,7 +181,7 @@ class Bed extends Transparent{ if($next->canBeReplaced() and !$next->getSide(Facing::DOWN)->isTransparent()){ $nextState = clone $this; $nextState->head = true; - $tx->addBlock($blockReplace, $this)->addBlock($next, $nextState); + $tx->addBlock($blockReplace->pos, $this)->addBlock($next->pos, $nextState); return true; } } diff --git a/src/block/Block.php b/src/block/Block.php index 03c820e3f5..d5f1841804 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -49,7 +49,7 @@ use function assert; use function dechex; use const PHP_INT_MAX; -class Block extends Position{ +class Block{ /** @var BlockIdentifier */ protected $idInfo; @@ -60,6 +60,8 @@ class Block extends Position{ /** @var BlockBreakInfo */ protected $breakInfo; + /** @var Position */ + protected $pos; /** @var AxisAlignedBB */ protected $boundingBox = null; @@ -78,6 +80,11 @@ class Block extends Position{ $this->idInfo = $idInfo; $this->fallbackName = $name; $this->breakInfo = $breakInfo; + $this->pos = new Position(0, 0, 0, null); + } + + public function __clone(){ + $this->pos = Position::fromObject($this->pos, $this->pos->getWorld()); } public function getIdInfo() : BlockIdentifier{ @@ -164,10 +171,10 @@ class Block extends Position{ } public function writeStateToWorld() : void{ - $this->world->getChunkAtPosition($this)->setFullBlock($this->x & 0xf, $this->y, $this->z & 0xf, $this->getFullId()); + $this->pos->getWorld()->getChunkAtPosition($this->pos)->setFullBlock($this->pos->x & 0xf, $this->pos->y, $this->pos->z & 0xf, $this->getFullId()); $tileType = $this->idInfo->getTileClass(); - $oldTile = $this->world->getTile($this); + $oldTile = $this->pos->getWorld()->getTile($this->pos); if($oldTile !== null){ if($tileType === null or !($oldTile instanceof $tileType)){ $oldTile->close(); @@ -177,7 +184,7 @@ class Block extends Position{ } } if($oldTile === null and $tileType !== null){ - $this->world->addTile(TileFactory::create($tileType, $this->world, $this->asVector3())); + $this->pos->getWorld()->addTile(TileFactory::create($tileType, $this->pos->getWorld(), $this->pos->asVector3())); } } @@ -239,7 +246,7 @@ class Block extends Position{ * @return bool */ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - $tx->addBlock($blockReplace, $this); + $tx->addBlock($blockReplace->pos, $this); return true; } @@ -265,10 +272,10 @@ class Block extends Position{ * @return bool */ public function onBreak(Item $item, ?Player $player = null) : bool{ - if(($t = $this->world->getTile($this)) !== null){ + if(($t = $this->pos->getWorld()->getTile($this->pos)) !== null){ $t->onBlockDestroyed(); } - $this->getWorld()->setBlock($this, VanillaBlocks::AIR()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); return true; } @@ -404,6 +411,10 @@ class Block extends Position{ } + final public function getPos() : Position{ + return $this->pos; + } + /** * @internal * @@ -413,10 +424,10 @@ class Block extends Position{ * @param int $z */ final public function position(World $world, int $x, int $y, int $z) : void{ - $this->x = $x; - $this->y = $y; - $this->z = $z; - $this->world = $world; + $this->pos->x = $x; + $this->pos->y = $y; + $this->pos->z = $z; + $this->pos->world = $world; } /** @@ -504,7 +515,7 @@ class Block extends Position{ public function getPickedItem(bool $addUserData = false) : Item{ $item = $this->asItem(); if($addUserData){ - $tile = $this->world->getTile($this); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof Tile){ $nbt = $tile->getCleanedNBT(); if($nbt instanceof CompoundTag){ @@ -577,8 +588,8 @@ class Block extends Position{ * @return Block */ public function getSide(int $side, int $step = 1){ - if($this->isValid()){ - return $this->getWorld()->getBlock(Vector3::getSide($side, $step)); + if($this->pos->isValid()){ + return $this->pos->getWorld()->getBlock($this->pos->getSide($side, $step)); } throw new \InvalidStateException("Block does not have a valid world"); @@ -664,7 +675,7 @@ class Block extends Position{ if($this->collisionBoxes === null){ $this->collisionBoxes = $this->recalculateCollisionBoxes(); foreach($this->collisionBoxes as $bb){ - $bb->offset($this->x, $this->y, $this->z); + $bb->offset($this->pos->x, $this->pos->y, $this->pos->z); } } @@ -689,7 +700,7 @@ class Block extends Position{ if($this->boundingBox === null){ $this->boundingBox = $this->recalculateBoundingBox(); if($this->boundingBox !== null){ - $this->boundingBox->offset($this->x, $this->y, $this->z); + $this->boundingBox->offset($this->pos->x, $this->pos->y, $this->pos->z); } } return $this->boundingBox; diff --git a/src/block/BrewingStand.php b/src/block/BrewingStand.php index bfb820e941..f4ae81b2b8 100644 --- a/src/block/BrewingStand.php +++ b/src/block/BrewingStand.php @@ -60,7 +60,7 @@ class BrewingStand extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $stand = $this->getWorld()->getTile($this); + $stand = $this->pos->getWorld()->getTile($this->pos); if($stand instanceof TileBrewingStand and $stand->canOpenWith($item->getCustomName())){ $player->setCurrentWindow($stand->getInventory()); } diff --git a/src/block/Button.php b/src/block/Button.php index ed29cb587b..23657d7646 100644 --- a/src/block/Button.php +++ b/src/block/Button.php @@ -64,9 +64,9 @@ abstract class Button extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$this->powered){ $this->powered = true; - $this->world->setBlock($this, $this); - $this->world->scheduleDelayedBlockUpdate($this, $this->getActivationTime()); - $this->world->addSound($this->add(0.5, 0.5, 0.5), new RedstonePowerOnSound()); + $this->pos->getWorld()->setBlock($this->pos, $this); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, $this->getActivationTime()); + $this->pos->getWorld()->addSound($this->pos->add(0.5, 0.5, 0.5), new RedstonePowerOnSound()); } return true; @@ -75,8 +75,8 @@ abstract class Button extends Flowable{ public function onScheduledUpdate() : void{ if($this->powered){ $this->powered = false; - $this->world->setBlock($this, $this); - $this->world->addSound($this->add(0.5, 0.5, 0.5), new RedstonePowerOffSound()); + $this->pos->getWorld()->setBlock($this->pos, $this); + $this->pos->getWorld()->addSound($this->pos->add(0.5, 0.5, 0.5), new RedstonePowerOffSound()); } } } diff --git a/src/block/Cactus.php b/src/block/Cactus.php index b7b6df815a..ab3f5fd05b 100644 --- a/src/block/Cactus.php +++ b/src/block/Cactus.php @@ -73,12 +73,12 @@ class Cactus extends Transparent{ public function onNearbyBlockChange() : void{ $down = $this->getSide(Facing::DOWN); if($down->getId() !== BlockLegacyIds::SAND and !$down->isSameType($this)){ - $this->getWorld()->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); }else{ foreach(Facing::HORIZONTAL as $side){ $b = $this->getSide($side); if($b->isSolid()){ - $this->getWorld()->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); break; } } @@ -93,23 +93,23 @@ class Cactus extends Transparent{ if(!$this->getSide(Facing::DOWN)->isSameType($this)){ if($this->age === 15){ for($y = 1; $y < 3; ++$y){ - $b = $this->getWorld()->getBlockAt($this->x, $this->y + $y, $this->z); + $b = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z); if($b->getId() === BlockLegacyIds::AIR){ $ev = new BlockGrowEvent($b, VanillaBlocks::CACTUS()); $ev->call(); if($ev->isCancelled()){ break; } - $this->getWorld()->setBlock($b, $ev->getNewState()); + $this->pos->getWorld()->setBlock($b->pos, $ev->getNewState()); }else{ break; } } $this->age = 0; - $this->getWorld()->setBlock($this, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); }else{ ++$this->age; - $this->getWorld()->setBlock($this, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } } } diff --git a/src/block/Cake.php b/src/block/Cake.php index 5f417927e1..1cf4a45610 100644 --- a/src/block/Cake.php +++ b/src/block/Cake.php @@ -73,7 +73,7 @@ class Cake extends Transparent implements FoodSource{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ //Replace with common break method - $this->getWorld()->setBlock($this, VanillaBlocks::AIR()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); } } @@ -126,6 +126,6 @@ class Cake extends Transparent implements FoodSource{ } public function onConsume(Living $consumer) : void{ - $this->world->setBlock($this, $this->getResidue()); + $this->pos->getWorld()->setBlock($this->pos, $this->getResidue()); } } diff --git a/src/block/Carpet.php b/src/block/Carpet.php index 39b7d2ccb7..74fd068f28 100644 --- a/src/block/Carpet.php +++ b/src/block/Carpet.php @@ -55,7 +55,7 @@ class Carpet extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ - $this->getWorld()->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/Chest.php b/src/block/Chest.php index 68d6e29de4..6a3042ddf2 100644 --- a/src/block/Chest.php +++ b/src/block/Chest.php @@ -67,7 +67,7 @@ class Chest extends Transparent{ } public function onPostPlace() : void{ - $tile = $this->world->getTile($this); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileChest){ foreach([ Facing::rotateY($this->facing, true), @@ -75,7 +75,7 @@ class Chest extends Transparent{ ] as $side){ $c = $this->getSide($side); if($c instanceof Chest and $c->isSameType($this) and $c->facing === $this->facing){ - $pair = $this->world->getTile($c); + $pair = $this->pos->getWorld()->getTile($c->pos); if($pair instanceof TileChest and !$pair->isPaired()){ $pair->pairWith($tile); $tile->pairWith($pair); @@ -89,7 +89,7 @@ class Chest extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $chest = $this->getWorld()->getTile($this); + $chest = $this->pos->getWorld()->getTile($this->pos); if($chest instanceof TileChest){ if( !$this->getSide(Facing::UP)->isTransparent() or diff --git a/src/block/CoarseDirt.php b/src/block/CoarseDirt.php index e26e1be74f..d6e6630a5d 100644 --- a/src/block/CoarseDirt.php +++ b/src/block/CoarseDirt.php @@ -34,7 +34,7 @@ class CoarseDirt extends Dirt{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP and $item instanceof Hoe){ $item->applyDamage(1); - $this->getWorld()->setBlock($this, VanillaBlocks::DIRT()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::DIRT()); return true; } diff --git a/src/block/CocoaBlock.php b/src/block/CocoaBlock.php index 2b487077e3..627bc89f3c 100644 --- a/src/block/CocoaBlock.php +++ b/src/block/CocoaBlock.php @@ -84,7 +84,7 @@ class CocoaBlock extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($this->age < 2 and $item instanceof Fertilizer){ $this->age++; - $this->world->setBlock($this, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); $item->pop(); @@ -97,7 +97,7 @@ class CocoaBlock extends Transparent{ public function onNearbyBlockChange() : void{ $side = $this->getSide(Facing::opposite($this->facing)); if(!($side instanceof Wood) or !$side->getTreeType()->equals(TreeType::JUNGLE())){ - $this->world->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } @@ -108,7 +108,7 @@ class CocoaBlock extends Transparent{ public function onRandomTick() : void{ if($this->age < 2 and mt_rand(1, 5) === 1){ $this->age++; - $this->world->setBlock($this, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } } diff --git a/src/block/ConcretePowder.php b/src/block/ConcretePowder.php index 881b864ba8..5261ddc7bc 100644 --- a/src/block/ConcretePowder.php +++ b/src/block/ConcretePowder.php @@ -38,7 +38,7 @@ class ConcretePowder extends Opaque implements Fallable{ public function onNearbyBlockChange() : void{ if(($block = $this->checkAdjacentWater()) !== null){ - $this->world->setBlock($this, $block); + $this->pos->getWorld()->setBlock($this->pos, $block); }else{ $this->startFalling(); } diff --git a/src/block/Crops.php b/src/block/Crops.php index 3a1829ea8e..0d1b461e23 100644 --- a/src/block/Crops.php +++ b/src/block/Crops.php @@ -73,7 +73,7 @@ abstract class Crops extends Flowable{ $ev = new BlockGrowEvent($this, $block); $ev->call(); if(!$ev->isCancelled()){ - $this->getWorld()->setBlock($this, $ev->getNewState()); + $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); } $item->pop(); @@ -86,7 +86,7 @@ abstract class Crops extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::FARMLAND){ - $this->getWorld()->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } @@ -101,7 +101,7 @@ abstract class Crops extends Flowable{ $ev = new BlockGrowEvent($this, $block); $ev->call(); if(!$ev->isCancelled()){ - $this->getWorld()->setBlock($this, $ev->getNewState()); + $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); } } } diff --git a/src/block/DaylightSensor.php b/src/block/DaylightSensor.php index 8f4ad501b0..36af835a94 100644 --- a/src/block/DaylightSensor.php +++ b/src/block/DaylightSensor.php @@ -90,23 +90,23 @@ class DaylightSensor extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->inverted = !$this->inverted; $this->power = $this->recalculatePower(); - $this->world->setBlock($this, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); return true; } public function onScheduledUpdate() : void{ $this->power = $this->recalculatePower(); - $this->world->setBlock($this, $this); - $this->world->scheduleDelayedBlockUpdate($this, 20); + $this->pos->getWorld()->setBlock($this->pos, $this); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 20); } private function recalculatePower() : int{ - $lightLevel = $this->world->getRealBlockSkyLightAt($this->x, $this->y, $this->z); + $lightLevel = $this->pos->getWorld()->getRealBlockSkyLightAt($this->pos->x, $this->pos->y, $this->pos->z); if($this->inverted){ return 15 - $lightLevel; } - $sunAngle = $this->world->getSunAnglePercentage(); + $sunAngle = $this->pos->getWorld()->getSunAnglePercentage(); return max(0, (int) round($lightLevel * cos(($sunAngle + ((($sunAngle < 0.5 ? 0 : 1) - $sunAngle) / 5)) * 2 * M_PI))); } diff --git a/src/block/DeadBush.php b/src/block/DeadBush.php index 49a6c809e7..988e57665d 100644 --- a/src/block/DeadBush.php +++ b/src/block/DeadBush.php @@ -47,7 +47,7 @@ class DeadBush extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->getWorld()->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/Dirt.php b/src/block/Dirt.php index 5d035b318e..7dab9b0093 100644 --- a/src/block/Dirt.php +++ b/src/block/Dirt.php @@ -38,7 +38,7 @@ class Dirt extends Opaque{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP and $item instanceof Hoe){ $item->applyDamage(1); - $this->getWorld()->setBlock($this, VanillaBlocks::FARMLAND()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::FARMLAND()); return true; } diff --git a/src/block/Door.php b/src/block/Door.php index eecb1c2760..7c7dd98c3b 100644 --- a/src/block/Door.php +++ b/src/block/Door.php @@ -100,7 +100,7 @@ class Door extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ //Replace with common break method - $this->getWorld()->useBreakOn($this); //this will delete both halves if they exist + $this->pos->getWorld()->useBreakOn($this->pos); //this will delete both halves if they exist } } @@ -126,7 +126,7 @@ class Door extends Transparent{ $topHalf = clone $this; $topHalf->top = true; - $tx->addBlock($blockReplace, $this)->addBlock($blockUp, $topHalf); + $tx->addBlock($blockReplace->pos, $this)->addBlock($blockUp->pos, $topHalf); return true; } @@ -139,11 +139,11 @@ class Door extends Transparent{ $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); if($other instanceof Door and $other->isSameType($this)){ $other->open = $this->open; - $this->world->setBlock($other, $other); + $this->pos->getWorld()->setBlock($other->pos, $other); } - $this->world->setBlock($this, $this); - $this->world->addSound($this, new DoorSound()); + $this->pos->getWorld()->setBlock($this->pos, $this); + $this->pos->getWorld()->addSound($this->pos, new DoorSound()); return true; } diff --git a/src/block/DoublePlant.php b/src/block/DoublePlant.php index 3c21947636..2e1a891115 100644 --- a/src/block/DoublePlant.php +++ b/src/block/DoublePlant.php @@ -55,7 +55,7 @@ class DoublePlant extends Flowable{ if(($id === BlockLegacyIds::GRASS or $id === BlockLegacyIds::DIRT) and $blockReplace->getSide(Facing::UP)->canBeReplaced()){ $top = clone $this; $top->top = true; - $tx->addBlock($blockReplace, $this)->addBlock($blockReplace->getSide(Facing::UP), $top); + $tx->addBlock($blockReplace->pos, $this)->addBlock($blockReplace->pos->getSide(Facing::UP), $top); return true; } @@ -78,7 +78,7 @@ class DoublePlant extends Flowable{ public function onNearbyBlockChange() : void{ if(!$this->isValidHalfPlant() or (!$this->top and $this->getSide(Facing::DOWN)->isTransparent())){ - $this->getWorld()->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/DragonEgg.php b/src/block/DragonEgg.php index 97bc0683cc..17546b3f2a 100644 --- a/src/block/DragonEgg.php +++ b/src/block/DragonEgg.php @@ -63,22 +63,22 @@ class DragonEgg extends Transparent implements Fallable{ public function teleport() : void{ for($tries = 0; $tries < 16; ++$tries){ - $block = $this->world->getBlockAt( - $this->x + mt_rand(-16, 16), - max(0, min(World::Y_MAX - 1, $this->y + mt_rand(-8, 8))), - $this->z + mt_rand(-16, 16) + $block = $this->pos->getWorld()->getBlockAt( + $this->pos->x + mt_rand(-16, 16), + max(0, min(World::Y_MAX - 1, $this->pos->y + mt_rand(-8, 8))), + $this->pos->z + mt_rand(-16, 16) ); if($block instanceof Air){ - $ev = new BlockTeleportEvent($this, $block); + $ev = new BlockTeleportEvent($this, $block->pos); $ev->call(); if($ev->isCancelled()){ break; - }else{ - $block = $ev->getTo(); } - $this->world->addParticle($this, new DragonEggTeleportParticle($this->x - $block->x, $this->y - $block->y, $this->z - $block->z)); - $this->world->setBlock($this, VanillaBlocks::AIR()); - $this->world->setBlock($block, $this); + + $blockPos = $ev->getTo(); + $this->pos->getWorld()->addParticle($this->pos, new DragonEggTeleportParticle($this->pos->x - $blockPos->x, $this->pos->y - $blockPos->y, $this->pos->z - $blockPos->z)); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); + $this->pos->getWorld()->setBlock($blockPos, $this); break; } } diff --git a/src/block/EnchantingTable.php b/src/block/EnchantingTable.php index 2edbf70870..34d2c44206 100644 --- a/src/block/EnchantingTable.php +++ b/src/block/EnchantingTable.php @@ -45,7 +45,7 @@ class EnchantingTable extends Transparent{ if($player instanceof Player){ //TODO lock - $player->setCurrentWindow(new EnchantInventory($this)); + $player->setCurrentWindow(new EnchantInventory($this->pos)); } return true; diff --git a/src/block/EnderChest.php b/src/block/EnderChest.php index 1144a025e1..40ae928a08 100644 --- a/src/block/EnderChest.php +++ b/src/block/EnderChest.php @@ -72,7 +72,7 @@ class EnderChest extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $enderChest = $this->getWorld()->getTile($this); + $enderChest = $this->pos->getWorld()->getTile($this->pos); if($enderChest instanceof TileEnderChest and $this->getSide(Facing::UP)->isTransparent()){ $player->getEnderChestInventory()->setHolderPosition($enderChest); $player->setCurrentWindow($player->getEnderChestInventory()); diff --git a/src/block/Farmland.php b/src/block/Farmland.php index 96ae4c970b..da1b100c4b 100644 --- a/src/block/Farmland.php +++ b/src/block/Farmland.php @@ -55,7 +55,7 @@ class Farmland extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::UP)->isSolid()){ - $this->world->setBlock($this, VanillaBlocks::DIRT()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::DIRT()); } } @@ -67,24 +67,24 @@ class Farmland extends Transparent{ if(!$this->canHydrate()){ if($this->wetness > 0){ $this->wetness--; - $this->world->setBlock($this, $this, false); + $this->pos->getWorld()->setBlock($this->pos, $this, false); }else{ - $this->world->setBlock($this, VanillaBlocks::DIRT()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::DIRT()); } }elseif($this->wetness < 7){ $this->wetness = 7; - $this->world->setBlock($this, $this, false); + $this->pos->getWorld()->setBlock($this->pos, $this, false); } } protected function canHydrate() : bool{ //TODO: check rain - $start = $this->add(-4, 0, -4); - $end = $this->add(4, 1, 4); + $start = $this->pos->add(-4, 0, -4); + $end = $this->pos->add(4, 1, 4); for($y = $start->y; $y <= $end->y; ++$y){ for($z = $start->z; $z <= $end->z; ++$z){ for($x = $start->x; $x <= $end->x; ++$x){ - if($this->world->getBlockAt($x, $y, $z) instanceof Water){ + if($this->pos->getWorld()->getBlockAt($x, $y, $z) instanceof Water){ return true; } } diff --git a/src/block/FenceGate.php b/src/block/FenceGate.php index 0991a977c7..ea00e71a8a 100644 --- a/src/block/FenceGate.php +++ b/src/block/FenceGate.php @@ -89,7 +89,7 @@ class FenceGate extends Transparent{ $inWall = $this->checkInWall(); if($inWall !== $this->inWall){ $this->inWall = $inWall; - $this->world->setBlock($this, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } } @@ -102,8 +102,8 @@ class FenceGate extends Transparent{ } } - $this->getWorld()->setBlock($this, $this); - $this->world->addSound($this, new DoorSound()); + $this->pos->getWorld()->setBlock($this->pos, $this); + $this->pos->getWorld()->addSound($this->pos, new DoorSound()); return true; } diff --git a/src/block/Fire.php b/src/block/Fire.php index 2d499f1037..c1b019a483 100644 --- a/src/block/Fire.php +++ b/src/block/Fire.php @@ -88,9 +88,9 @@ class Fire extends Flowable{ public function onNearbyBlockChange() : void{ if(!$this->getSide(Facing::DOWN)->isSolid() and !$this->hasAdjacentFlammableBlocks()){ - $this->getWorld()->setBlock($this, VanillaBlocks::AIR()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); }else{ - $this->world->scheduleDelayedBlockUpdate($this, mt_rand(30, 40)); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(30, 40)); } } @@ -124,10 +124,10 @@ class Fire extends Flowable{ } if($result !== null){ - $this->world->setBlock($this, $result); + $this->pos->getWorld()->setBlock($this->pos, $result); } - $this->world->scheduleDelayedBlockUpdate($this, mt_rand(30, 40)); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(30, 40)); if($canSpread){ //TODO: raise upper bound for chance in humid biomes @@ -168,9 +168,9 @@ class Fire extends Flowable{ if(mt_rand(0, $this->age + 9) < 5){ //TODO: check rain $fire = clone $this; $fire->age = min(15, $fire->age + (mt_rand(0, 4) >> 2)); - $this->world->setBlock($block, $fire); + $this->pos->getWorld()->setBlock($block->pos, $fire); }else{ - $this->world->setBlock($block, VanillaBlocks::AIR()); + $this->pos->getWorld()->setBlock($block->pos, VanillaBlocks::AIR()); } } } diff --git a/src/block/Flower.php b/src/block/Flower.php index c44fc68297..5640085855 100644 --- a/src/block/Flower.php +++ b/src/block/Flower.php @@ -46,7 +46,7 @@ class Flower extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->getWorld()->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/FlowerPot.php b/src/block/FlowerPot.php index 9d941546d2..3fb8735f70 100644 --- a/src/block/FlowerPot.php +++ b/src/block/FlowerPot.php @@ -61,7 +61,7 @@ class FlowerPot extends Flowable{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->world->getTile($this); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileFlowerPot){ $this->setPlant($tile->getPlant()); }else{ @@ -72,7 +72,7 @@ class FlowerPot extends Flowable{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->world->getTile($this); + $tile = $this->pos->getWorld()->getTile($this->pos); assert($tile instanceof TileFlowerPot); $tile->setPlant($this->plant); } @@ -125,7 +125,7 @@ class FlowerPot extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->getWorld()->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } @@ -137,7 +137,7 @@ class FlowerPot extends Flowable{ $this->setPlant($plant); $item->pop(); - $this->world->setBlock($this, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); return true; } diff --git a/src/block/FrostedIce.php b/src/block/FrostedIce.php index 32c46a6119..9d957d5fcf 100644 --- a/src/block/FrostedIce.php +++ b/src/block/FrostedIce.php @@ -50,17 +50,17 @@ class FrostedIce extends Ice{ public function onNearbyBlockChange() : void{ if(!$this->checkAdjacentBlocks(2)){ - $this->world->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); }else{ - $this->world->scheduleDelayedBlockUpdate($this, mt_rand(20, 40)); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(20, 40)); } } public function onRandomTick() : void{ if((!$this->checkAdjacentBlocks(4) or mt_rand(0, 2) === 0) and max( //TODO: move this to World - $this->world->getHighestAdjacentBlockLight($this->x, $this->y, $this->z), - $this->world->getHighestAdjacentBlockSkyLight($this->x, $this->y, $this->z) - $this->world->getSkyLightReduction() + $this->pos->getWorld()->getHighestAdjacentBlockLight($this->pos->x, $this->pos->y, $this->pos->z), + $this->pos->getWorld()->getHighestAdjacentBlockSkyLight($this->pos->x, $this->pos->y, $this->pos->z) - $this->pos->getWorld()->getSkyLightReduction() ) >= 12 - $this->age){ if($this->tryMelt()){ foreach($this->getAllSides() as $block){ @@ -70,7 +70,7 @@ class FrostedIce extends Ice{ } } }else{ - $this->world->scheduleDelayedBlockUpdate($this, mt_rand(20, 40)); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(20, 40)); } } @@ -86,7 +86,7 @@ class FrostedIce extends Ice{ continue; } if( - $this->world->getBlockAt($this->x + $x, $this->y, $this->z + $z) instanceof FrostedIce and + $this->pos->getWorld()->getBlockAt($this->pos->x + $x, $this->pos->y, $this->pos->z + $z) instanceof FrostedIce and ++$found >= $requirement ){ return true; @@ -103,13 +103,13 @@ class FrostedIce extends Ice{ */ private function tryMelt() : bool{ if($this->age >= 3){ - $this->world->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); return true; } $this->age++; - $this->world->setBlock($this, $this); - $this->world->scheduleDelayedBlockUpdate($this, mt_rand(20, 40)); + $this->pos->getWorld()->setBlock($this->pos, $this); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(20, 40)); return false; } } diff --git a/src/block/Furnace.php b/src/block/Furnace.php index f04756d792..736de20c7d 100644 --- a/src/block/Furnace.php +++ b/src/block/Furnace.php @@ -90,7 +90,7 @@ class Furnace extends Opaque{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $furnace = $this->getWorld()->getTile($this); + $furnace = $this->pos->getWorld()->getTile($this->pos); if($furnace instanceof TileFurnace and $furnace->canOpenWith($item->getCustomName())){ $player->setCurrentWindow($furnace->getInventory()); } @@ -100,9 +100,9 @@ class Furnace extends Opaque{ } public function onScheduledUpdate() : void{ - $furnace = $this->getWorld()->getTile($this); + $furnace = $this->pos->getWorld()->getTile($this->pos); if($furnace instanceof TileFurnace and $furnace->onUpdate()){ - $this->world->scheduleDelayedBlockUpdate($this, 1); //TODO: check this + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 1); //TODO: check this } } } diff --git a/src/block/Grass.php b/src/block/Grass.php index 2e1485a3ee..e42f5a7d59 100644 --- a/src/block/Grass.php +++ b/src/block/Grass.php @@ -52,27 +52,27 @@ class Grass extends Opaque{ } public function onRandomTick() : void{ - $lightAbove = $this->world->getFullLightAt($this->x, $this->y + 1, $this->z); - if($lightAbove < 4 and $this->world->getBlockAt($this->x, $this->y + 1, $this->z)->getLightFilter() >= 2){ + $lightAbove = $this->pos->getWorld()->getFullLightAt($this->pos->x, $this->pos->y + 1, $this->pos->z); + if($lightAbove < 4 and $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z)->getLightFilter() >= 2){ //grass dies $ev = new BlockSpreadEvent($this, $this, VanillaBlocks::DIRT()); $ev->call(); if(!$ev->isCancelled()){ - $this->world->setBlock($this, $ev->getNewState(), false); + $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState(), false); } }elseif($lightAbove >= 9){ //try grass spread for($i = 0; $i < 4; ++$i){ - $x = mt_rand($this->x - 1, $this->x + 1); - $y = mt_rand($this->y - 3, $this->y + 1); - $z = mt_rand($this->z - 1, $this->z + 1); + $x = mt_rand($this->pos->x - 1, $this->pos->x + 1); + $y = mt_rand($this->pos->y - 3, $this->pos->y + 1); + $z = mt_rand($this->pos->z - 1, $this->pos->z + 1); - $b = $this->world->getBlockAt($x, $y, $z); + $b = $this->pos->getWorld()->getBlockAt($x, $y, $z); if( !($b instanceof Dirt) or $b instanceof CoarseDirt or - $this->world->getFullLightAt($x, $y + 1, $z) < 4 or - $this->world->getBlockAt($x, $y + 1, $z)->getLightFilter() >= 2 + $this->pos->getWorld()->getFullLightAt($x, $y + 1, $z) < 4 or + $this->pos->getWorld()->getBlockAt($x, $y + 1, $z)->getLightFilter() >= 2 ){ continue; } @@ -80,7 +80,7 @@ class Grass extends Opaque{ $ev = new BlockSpreadEvent($b, $this, VanillaBlocks::GRASS()); $ev->call(); if(!$ev->isCancelled()){ - $this->world->setBlock($b, $ev->getNewState(), false); + $this->pos->getWorld()->setBlock($b->pos, $ev->getNewState(), false); } } } @@ -92,17 +92,17 @@ class Grass extends Opaque{ } if($item instanceof Fertilizer){ $item->pop(); - TallGrassObject::growGrass($this->getWorld(), $this, new Random(mt_rand()), 8, 2); + TallGrassObject::growGrass($this->pos->getWorld(), $this->pos, new Random(mt_rand()), 8, 2); return true; }elseif($item instanceof Hoe){ $item->applyDamage(1); - $this->getWorld()->setBlock($this, VanillaBlocks::FARMLAND()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::FARMLAND()); return true; }elseif($item instanceof Shovel and $this->getSide(Facing::UP)->getId() === BlockLegacyIds::AIR){ $item->applyDamage(1); - $this->getWorld()->setBlock($this, VanillaBlocks::GRASS_PATH()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::GRASS_PATH()); return true; } diff --git a/src/block/GrassPath.php b/src/block/GrassPath.php index 4861cc1f61..d2b7ef5cc3 100644 --- a/src/block/GrassPath.php +++ b/src/block/GrassPath.php @@ -39,7 +39,7 @@ class GrassPath extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::UP)->isSolid()){ - $this->world->setBlock($this, VanillaBlocks::DIRT()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::DIRT()); } } diff --git a/src/block/Hopper.php b/src/block/Hopper.php index 26b8e6e12e..be6a4b6de2 100644 --- a/src/block/Hopper.php +++ b/src/block/Hopper.php @@ -76,7 +76,7 @@ class Hopper extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ - $tile = $this->world->getTile($this); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileHopper){ //TODO: find a way to have inventories open on click without this boilerplate in every block $player->setCurrentWindow($tile->getInventory()); } diff --git a/src/block/Ice.php b/src/block/Ice.php index 71429e0a13..2fd60d9f6e 100644 --- a/src/block/Ice.php +++ b/src/block/Ice.php @@ -43,7 +43,7 @@ class Ice extends Transparent{ public function onBreak(Item $item, ?Player $player = null) : bool{ if(($player === null or $player->isSurvival()) and !$item->hasEnchantment(Enchantment::SILK_TOUCH())){ - $this->getWorld()->setBlock($this, VanillaBlocks::WATER()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::WATER()); return true; } return parent::onBreak($item, $player); @@ -54,8 +54,8 @@ class Ice extends Transparent{ } public function onRandomTick() : void{ - if($this->world->getHighestAdjacentBlockLight($this->x, $this->y, $this->z) >= 12){ - $this->world->useBreakOn($this); + if($this->pos->getWorld()->getHighestAdjacentBlockLight($this->pos->x, $this->pos->y, $this->pos->z) >= 12){ + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/ItemFrame.php b/src/block/ItemFrame.php index e082668a63..f0a181637a 100644 --- a/src/block/ItemFrame.php +++ b/src/block/ItemFrame.php @@ -61,7 +61,7 @@ class ItemFrame extends Flowable{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->world->getTile($this); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileItemFrame){ $this->framedItem = $tile->getItem(); if($this->framedItem->isNull()){ @@ -74,7 +74,7 @@ class ItemFrame extends Flowable{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->world->getTile($this); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileItemFrame){ $tile->setItem($this->framedItem); $tile->setItemRotation($this->itemRotation); @@ -156,7 +156,7 @@ class ItemFrame extends Flowable{ return true; } - $this->world->setBlock($this, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); return true; } @@ -166,16 +166,16 @@ class ItemFrame extends Flowable{ return false; } if(lcg_value() <= $this->itemDropChance){ - $this->world->dropItem($this->add(0.5, 0.5, 0.5), $this->getFramedItem()); + $this->pos->getWorld()->dropItem($this->pos->add(0.5, 0.5, 0.5), $this->getFramedItem()); } $this->setFramedItem(null); - $this->world->setBlock($this, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); return true; } public function onNearbyBlockChange() : void{ if(!$this->getSide(Facing::opposite($this->facing))->isSolid()){ - $this->world->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/Ladder.php b/src/block/Ladder.php index 9acba0e25b..927bfe8b80 100644 --- a/src/block/Ladder.php +++ b/src/block/Ladder.php @@ -66,7 +66,7 @@ class Ladder extends Transparent{ } public function onEntityInside(Entity $entity) : void{ - if($entity->asVector3()->floor()->distanceSquared($this) < 1){ //entity coordinates must be inside block + if($entity->asVector3()->floor()->distanceSquared($this->pos) < 1){ //entity coordinates must be inside block $entity->resetFallDistance(); $entity->onGround = true; } @@ -88,7 +88,7 @@ class Ladder extends Transparent{ public function onNearbyBlockChange() : void{ if(!$this->getSide(Facing::opposite($this->facing))->isSolid()){ //Replace with common break method - $this->world->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } } diff --git a/src/block/Lantern.php b/src/block/Lantern.php index 98ca830ee3..d4334ba2ac 100644 --- a/src/block/Lantern.php +++ b/src/block/Lantern.php @@ -64,17 +64,17 @@ class Lantern extends Transparent{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canAttachTo($this->world->getBlock($blockReplace->up())) and !$this->canAttachTo($this->world->getBlock($blockReplace->down()))){ + if(!$this->canAttachTo($this->pos->getWorld()->getBlock($blockReplace->getPos()->up())) and !$this->canAttachTo($this->pos->getWorld()->getBlock($blockReplace->getPos()->down()))){ return false; } - $this->hanging = ($face === Facing::DOWN or !$this->canAttachTo($this->world->getBlock($blockReplace->down()))); + $this->hanging = ($face === Facing::DOWN or !$this->canAttachTo($this->pos->getWorld()->getBlock($blockReplace->getPos()->down()))); return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onNearbyBlockChange() : void{ - if(!$this->canAttachTo($this->world->getBlock($this->hanging ? $this->up() : $this->down()))){ - $this->world->useBreakOn($this); + if(!$this->canAttachTo($this->pos->getWorld()->getBlock($this->hanging ? $this->pos->up() : $this->pos->down()))){ + $this->pos->getWorld()->useBreakOn($this->pos); } } } diff --git a/src/block/Leaves.php b/src/block/Leaves.php index 2b4091acf9..f57ea1e74e 100644 --- a/src/block/Leaves.php +++ b/src/block/Leaves.php @@ -68,18 +68,19 @@ class Leaves extends Transparent{ } - protected function findLog(Block $pos, array &$visited = [], int $distance = 0) : bool{ + protected function findLog(Vector3 $pos, array &$visited = [], int $distance = 0) : bool{ $index = World::blockHash($pos->x, $pos->y, $pos->z); if(isset($visited[$index])){ return false; } $visited[$index] = true; + $block = $this->pos->getWorld()->getBlock($pos); if($pos instanceof Wood){ //type doesn't matter return true; } - if($pos->getId() === $this->getId() and $distance <= 4){ + if($block->getId() === $this->getId() and $distance <= 4){ foreach(Facing::ALL as $side){ if($this->findLog($pos->getSide($side), $visited, $distance + 1)){ return true; @@ -93,7 +94,7 @@ class Leaves extends Transparent{ public function onNearbyBlockChange() : void{ if(!$this->noDecay and !$this->checkDecay){ $this->checkDecay = true; - $this->getWorld()->setBlock($this, $this, false); + $this->pos->getWorld()->setBlock($this->pos, $this, false); } } @@ -105,11 +106,11 @@ class Leaves extends Transparent{ if(!$this->noDecay and $this->checkDecay){ $ev = new LeavesDecayEvent($this); $ev->call(); - if($ev->isCancelled() or $this->findLog($this)){ + if($ev->isCancelled() or $this->findLog($this->pos)){ $this->checkDecay = false; - $this->getWorld()->setBlock($this, $this, false); + $this->pos->getWorld()->setBlock($this->pos, $this, false); }else{ - $this->getWorld()->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } } diff --git a/src/block/Lever.php b/src/block/Lever.php index 6053f80b3b..d4d7bf6f50 100644 --- a/src/block/Lever.php +++ b/src/block/Lever.php @@ -38,7 +38,7 @@ class Lever extends Flowable{ protected const TOP = 2; /** @var int */ - protected $position = self::BOTTOM; + protected $leverPos = self::BOTTOM; /** @var int */ protected $facing = Facing::NORTH; /** @var bool */ @@ -49,9 +49,9 @@ class Lever extends Flowable{ } protected function writeStateToMeta() : int{ - if($this->position === self::BOTTOM){ + if($this->leverPos === self::BOTTOM){ $rotationMeta = Facing::axis($this->facing) === Facing::AXIS_Z ? 7 : 0; - }elseif($this->position === self::TOP){ + }elseif($this->leverPos === self::TOP){ $rotationMeta = Facing::axis($this->facing) === Facing::AXIS_Z ? 5 : 6; }else{ $rotationMeta = 6 - BlockDataSerializer::writeHorizontalFacing($this->facing); @@ -62,13 +62,13 @@ class Lever extends Flowable{ public function readStateFromData(int $id, int $stateMeta) : void{ $rotationMeta = $stateMeta & 0x07; if($rotationMeta === 5 or $rotationMeta === 6){ - $this->position = self::TOP; + $this->leverPos = self::TOP; $this->facing = $rotationMeta === 5 ? Facing::SOUTH : Facing::EAST; }elseif($rotationMeta === 7 or $rotationMeta === 0){ - $this->position = self::BOTTOM; + $this->leverPos = self::BOTTOM; $this->facing = $rotationMeta === 7 ? Facing::SOUTH : Facing::EAST; }else{ - $this->position = self::SIDE; + $this->leverPos = self::SIDE; $this->facing = BlockDataSerializer::readHorizontalFacing(6 - $rotationMeta); } @@ -88,34 +88,34 @@ class Lever extends Flowable{ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } - $this->position = $face === Facing::DOWN ? self::BOTTOM : self::TOP; + $this->leverPos = $face === Facing::DOWN ? self::BOTTOM : self::TOP; }else{ $this->facing = $face; - $this->position = self::SIDE; + $this->leverPos = self::SIDE; } return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onNearbyBlockChange() : void{ - if($this->position === self::BOTTOM){ + if($this->leverPos === self::BOTTOM){ $face = Facing::UP; - }elseif($this->position === self::TOP){ + }elseif($this->leverPos === self::TOP){ $face = Facing::DOWN; }else{ $face = Facing::opposite($this->facing); } if(!$this->getSide($face)->isSolid()){ - $this->world->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->powered = !$this->powered; - $this->world->setBlock($this, $this); - $this->world->addSound( - $this->add(0.5, 0.5, 0.5), + $this->pos->getWorld()->setBlock($this->pos, $this); + $this->pos->getWorld()->addSound( + $this->pos->add(0.5, 0.5, 0.5), $this->powered ? new RedstonePowerOnSound() : new RedstonePowerOffSound() ); return true; diff --git a/src/block/Liquid.php b/src/block/Liquid.php index 857a1cfc5d..b946cdd043 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -169,9 +169,9 @@ abstract class Liquid extends Transparent{ for($j = 0; $j < 4; ++$j){ - $x = $this->x; - $y = $this->y; - $z = $this->z; + $x = $this->pos->x; + $y = $this->pos->y; + $z = $this->pos->z; if($j === 0){ --$x; @@ -182,7 +182,8 @@ abstract class Liquid extends Transparent{ }elseif($j === 3){ ++$z; } - $sideBlock = $this->world->getBlockAt($x, $y, $z); + + $sideBlock = $this->pos->getWorld()->getBlockAt($x, $y, $z); $blockDecay = $this->getEffectiveFlowDecay($sideBlock); if($blockDecay < 0){ @@ -190,34 +191,34 @@ abstract class Liquid extends Transparent{ continue; } - $blockDecay = $this->getEffectiveFlowDecay($this->world->getBlockAt($x, $y - 1, $z)); + $blockDecay = $this->getEffectiveFlowDecay($this->pos->getWorld()->getBlockAt($x, $y - 1, $z)); if($blockDecay >= 0){ $realDecay = $blockDecay - ($decay - 8); - $vector->x += ($sideBlock->x - $this->x) * $realDecay; - $vector->y += ($sideBlock->y - $this->y) * $realDecay; - $vector->z += ($sideBlock->z - $this->z) * $realDecay; + $vector->x += ($x - $this->pos->x) * $realDecay; + $vector->y += ($y - $this->pos->y) * $realDecay; + $vector->z += ($z - $this->pos->z) * $realDecay; } continue; }else{ $realDecay = $blockDecay - $decay; - $vector->x += ($sideBlock->x - $this->x) * $realDecay; - $vector->y += ($sideBlock->y - $this->y) * $realDecay; - $vector->z += ($sideBlock->z - $this->z) * $realDecay; + $vector->x += ($x - $this->pos->x) * $realDecay; + $vector->y += ($y - $this->pos->y) * $realDecay; + $vector->z += ($z - $this->pos->z) * $realDecay; } } if($this->falling){ if( - !$this->canFlowInto($this->world->getBlockAt($this->x, $this->y, $this->z - 1)) or - !$this->canFlowInto($this->world->getBlockAt($this->x, $this->y, $this->z + 1)) or - !$this->canFlowInto($this->world->getBlockAt($this->x - 1, $this->y, $this->z)) or - !$this->canFlowInto($this->world->getBlockAt($this->x + 1, $this->y, $this->z)) or - !$this->canFlowInto($this->world->getBlockAt($this->x, $this->y + 1, $this->z - 1)) or - !$this->canFlowInto($this->world->getBlockAt($this->x, $this->y + 1, $this->z + 1)) or - !$this->canFlowInto($this->world->getBlockAt($this->x - 1, $this->y + 1, $this->z)) or - !$this->canFlowInto($this->world->getBlockAt($this->x + 1, $this->y + 1, $this->z)) + !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1)) or + !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z + 1)) or + !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x - 1, $this->pos->y, $this->pos->z)) or + !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x + 1, $this->pos->y, $this->pos->z)) or + !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z - 1)) or + !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z + 1)) or + !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x - 1, $this->pos->y + 1, $this->pos->z)) or + !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x + 1, $this->pos->y + 1, $this->pos->z)) ){ $vector = $vector->normalize()->add(0, -6, 0); } @@ -248,7 +249,7 @@ abstract class Liquid extends Transparent{ public function onNearbyBlockChange() : void{ $this->checkForHarden(); - $this->world->scheduleDelayedBlockUpdate($this, $this->tickRate()); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, $this->tickRate()); } public function onScheduledUpdate() : void{ @@ -257,10 +258,10 @@ abstract class Liquid extends Transparent{ if(!$this->isSource()){ $smallestFlowDecay = -100; $this->adjacentSources = 0; - $smallestFlowDecay = $this->getSmallestFlowDecay($this->world->getBlockAt($this->x, $this->y, $this->z - 1), $smallestFlowDecay); - $smallestFlowDecay = $this->getSmallestFlowDecay($this->world->getBlockAt($this->x, $this->y, $this->z + 1), $smallestFlowDecay); - $smallestFlowDecay = $this->getSmallestFlowDecay($this->world->getBlockAt($this->x - 1, $this->y, $this->z), $smallestFlowDecay); - $smallestFlowDecay = $this->getSmallestFlowDecay($this->world->getBlockAt($this->x + 1, $this->y, $this->z), $smallestFlowDecay); + $smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1), $smallestFlowDecay); + $smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z + 1), $smallestFlowDecay); + $smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorld()->getBlockAt($this->pos->x - 1, $this->pos->y, $this->pos->z), $smallestFlowDecay); + $smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorld()->getBlockAt($this->pos->x + 1, $this->pos->y, $this->pos->z), $smallestFlowDecay); $newDecay = $smallestFlowDecay + $multiplier; $falling = false; @@ -269,12 +270,12 @@ abstract class Liquid extends Transparent{ $newDecay = -1; } - if($this->getEffectiveFlowDecay($this->world->getBlockAt($this->x, $this->y + 1, $this->z)) >= 0){ + if($this->getEffectiveFlowDecay($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z)) >= 0){ $falling = true; } if($this->adjacentSources >= 2 and $this instanceof Water){ - $bottomBlock = $this->world->getBlockAt($this->x, $this->y - 1, $this->z); + $bottomBlock = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y - 1, $this->pos->z); if($bottomBlock->isSolid() or ($bottomBlock instanceof Water and $bottomBlock->isSource())){ $newDecay = 0; $falling = false; @@ -283,17 +284,17 @@ abstract class Liquid extends Transparent{ if($falling !== $this->falling or (!$falling and $newDecay !== $this->decay)){ if(!$falling and $newDecay < 0){ - $this->world->setBlock($this, VanillaBlocks::AIR()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); return; } $this->falling = $falling; $this->decay = $falling ? 0 : $newDecay; - $this->world->setBlock($this, $this); //local block update will cause an update to be scheduled + $this->pos->getWorld()->setBlock($this->pos, $this); //local block update will cause an update to be scheduled } } - $bottomBlock = $this->world->getBlockAt($this->x, $this->y - 1, $this->z); + $bottomBlock = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y - 1, $this->pos->z); $this->flowIntoBlock($bottomBlock, 0, true); @@ -308,19 +309,19 @@ abstract class Liquid extends Transparent{ $flags = $this->getOptimalFlowDirections(); if($flags[0]){ - $this->flowIntoBlock($this->world->getBlockAt($this->x - 1, $this->y, $this->z), $adjacentDecay, false); + $this->flowIntoBlock($this->pos->getWorld()->getBlockAt($this->pos->x - 1, $this->pos->y, $this->pos->z), $adjacentDecay, false); } if($flags[1]){ - $this->flowIntoBlock($this->world->getBlockAt($this->x + 1, $this->y, $this->z), $adjacentDecay, false); + $this->flowIntoBlock($this->pos->getWorld()->getBlockAt($this->pos->x + 1, $this->pos->y, $this->pos->z), $adjacentDecay, false); } if($flags[2]){ - $this->flowIntoBlock($this->world->getBlockAt($this->x, $this->y, $this->z - 1), $adjacentDecay, false); + $this->flowIntoBlock($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1), $adjacentDecay, false); } if($flags[3]){ - $this->flowIntoBlock($this->world->getBlockAt($this->x, $this->y, $this->z + 1), $adjacentDecay, false); + $this->flowIntoBlock($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z + 1), $adjacentDecay, false); } } } @@ -338,10 +339,10 @@ abstract class Liquid extends Transparent{ $ev->call(); if(!$ev->isCancelled()){ if($block->getId() > 0){ - $this->world->useBreakOn($block); + $this->pos->getWorld()->useBreakOn($block->pos); } - $this->world->setBlock($block, $ev->getNewState()); + $this->pos->getWorld()->setBlock($block->pos, $ev->getNewState()); } } } @@ -369,10 +370,10 @@ abstract class Liquid extends Transparent{ } if(!isset($this->flowCostVisited[$hash = World::blockHash($x, $y, $z)])){ - $blockSide = $this->world->getBlockAt($x, $y, $z); + $blockSide = $this->pos->getWorld()->getBlockAt($x, $y, $z); if(!$this->canFlowInto($blockSide)){ $this->flowCostVisited[$hash] = self::BLOCKED; - }elseif($this->world->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ + }elseif($this->pos->getWorld()->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ $this->flowCostVisited[$hash] = self::CAN_FLOW_DOWN; }else{ $this->flowCostVisited[$hash] = self::CAN_FLOW; @@ -408,9 +409,9 @@ abstract class Liquid extends Transparent{ $flowCost = array_fill(0, 4, 1000); $maxCost = intdiv(4, $this->getFlowDecayPerBlock()); for($j = 0; $j < 4; ++$j){ - $x = $this->x; - $y = $this->y; - $z = $this->z; + $x = $this->pos->x; + $y = $this->pos->y; + $z = $this->pos->z; if($j === 0){ --$x; @@ -421,12 +422,12 @@ abstract class Liquid extends Transparent{ }elseif($j === 3){ ++$z; } - $block = $this->world->getBlockAt($x, $y, $z); + $block = $this->pos->getWorld()->getBlockAt($x, $y, $z); if(!$this->canFlowInto($block)){ $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::BLOCKED; continue; - }elseif($this->world->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ + }elseif($this->pos->getWorld()->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::CAN_FLOW_DOWN; $flowCost[$j] = $maxCost = 0; }elseif($maxCost > 0){ @@ -473,13 +474,13 @@ abstract class Liquid extends Transparent{ $ev = new BlockFormEvent($this, $result); $ev->call(); if(!$ev->isCancelled()){ - $this->world->setBlock($this, $ev->getNewState()); - $this->world->addSound($this->add(0.5, 0.5, 0.5), new FizzSound(2.6 + (lcg_value() - lcg_value()) * 0.8)); + $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); + $this->pos->getWorld()->addSound($this->pos->add(0.5, 0.5, 0.5), new FizzSound(2.6 + (lcg_value() - lcg_value()) * 0.8)); } return true; } protected function canFlowInto(Block $block) : bool{ - return $this->world->isInWorld($block->x, $block->y, $block->z) and $block->canBeFlowedInto() and !($block instanceof Liquid and $block->isSource()); //TODO: I think this should only be liquids of the same type + return $this->pos->getWorld()->isInWorld($block->pos->x, $block->pos->y, $block->pos->z) and $block->canBeFlowedInto() and !($block instanceof Liquid and $block->isSource()); //TODO: I think this should only be liquids of the same type } } diff --git a/src/block/Mycelium.php b/src/block/Mycelium.php index 93a7c11b14..f7b82e1b42 100644 --- a/src/block/Mycelium.php +++ b/src/block/Mycelium.php @@ -27,6 +27,7 @@ use pocketmine\event\block\BlockSpreadEvent; use pocketmine\item\Item; use pocketmine\math\Facing; use function mt_rand; +use pocketmine\world\Position; class Mycelium extends Opaque{ @@ -46,16 +47,16 @@ class Mycelium extends Opaque{ public function onRandomTick() : void{ //TODO: light levels - $x = mt_rand($this->x - 1, $this->x + 1); - $y = mt_rand($this->y - 2, $this->y + 2); - $z = mt_rand($this->z - 1, $this->z + 1); - $block = $this->getWorld()->getBlockAt($x, $y, $z); + $x = mt_rand($this->pos->x - 1, $this->pos->x + 1); + $y = mt_rand($this->pos->y - 2, $this->pos->y + 2); + $z = mt_rand($this->pos->z - 1, $this->pos->z + 1); + $block = $this->pos->getWorld()->getBlockAt($x, $y, $z); if($block->getId() === BlockLegacyIds::DIRT){ if($block->getSide(Facing::UP) instanceof Transparent){ $ev = new BlockSpreadEvent($block, $this, VanillaBlocks::MYCELIUM()); $ev->call(); if(!$ev->isCancelled()){ - $this->getWorld()->setBlock($block, $ev->getNewState()); + $this->pos->getWorld()->setBlock($block->pos, $ev->getNewState()); } } } diff --git a/src/block/NetherWartPlant.php b/src/block/NetherWartPlant.php index a678f5c018..0b72bb0a08 100644 --- a/src/block/NetherWartPlant.php +++ b/src/block/NetherWartPlant.php @@ -65,7 +65,7 @@ class NetherWartPlant extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::SOUL_SAND){ - $this->getWorld()->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } @@ -80,7 +80,7 @@ class NetherWartPlant extends Flowable{ $ev = new BlockGrowEvent($this, $block); $ev->call(); if(!$ev->isCancelled()){ - $this->getWorld()->setBlock($this, $ev->getNewState()); + $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); } } } diff --git a/src/block/Note.php b/src/block/Note.php index da65aab21b..2edd5b316a 100644 --- a/src/block/Note.php +++ b/src/block/Note.php @@ -39,7 +39,7 @@ class Note extends Opaque{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->world->getTile($this); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileNote){ $this->pitch = $tile->getPitch(); }else{ @@ -49,7 +49,7 @@ class Note extends Opaque{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->world->getTile($this); + $tile = $this->pos->getWorld()->getTile($this->pos); assert($tile instanceof TileNote); $tile->setPitch($this->pitch); } diff --git a/src/block/RedMushroom.php b/src/block/RedMushroom.php index d8b9bdca81..72d3bb5ec7 100644 --- a/src/block/RedMushroom.php +++ b/src/block/RedMushroom.php @@ -41,7 +41,7 @@ class RedMushroom extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->getWorld()->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/RedstoneComparator.php b/src/block/RedstoneComparator.php index 521a342cdb..37834b44be 100644 --- a/src/block/RedstoneComparator.php +++ b/src/block/RedstoneComparator.php @@ -72,7 +72,7 @@ class RedstoneComparator extends Flowable{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->world->getTile($this); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof Comparator){ $this->signalStrength = $tile->getSignalStrength(); } @@ -80,7 +80,7 @@ class RedstoneComparator extends Flowable{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->world->getTile($this); + $tile = $this->pos->getWorld()->getTile($this->pos); assert($tile instanceof Comparator); $tile->setSignalStrength($this->signalStrength); } @@ -160,13 +160,13 @@ class RedstoneComparator extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->isSubtractMode = !$this->isSubtractMode; - $this->world->setBlock($this, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); return true; } public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->world->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/RedstoneOre.php b/src/block/RedstoneOre.php index 92cfc0577b..c3e2cbe11a 100644 --- a/src/block/RedstoneOre.php +++ b/src/block/RedstoneOre.php @@ -70,7 +70,7 @@ class RedstoneOre extends Opaque{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$this->lit){ $this->lit = true; - $this->getWorld()->setBlock($this, $this); //no return here - this shouldn't prevent block placement + $this->pos->getWorld()->setBlock($this->pos, $this); //no return here - this shouldn't prevent block placement } return false; } @@ -78,7 +78,7 @@ class RedstoneOre extends Opaque{ public function onNearbyBlockChange() : void{ if(!$this->lit){ $this->lit = true; - $this->getWorld()->setBlock($this, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } } @@ -89,7 +89,7 @@ class RedstoneOre extends Opaque{ public function onRandomTick() : void{ if($this->lit){ $this->lit = false; - $this->world->setBlock($this, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } } diff --git a/src/block/RedstoneRepeater.php b/src/block/RedstoneRepeater.php index e57ead9af4..2c87dd97f0 100644 --- a/src/block/RedstoneRepeater.php +++ b/src/block/RedstoneRepeater.php @@ -98,13 +98,13 @@ class RedstoneRepeater extends Flowable{ if(++$this->delay > 4){ $this->delay = 1; } - $this->world->setBlock($this, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); return true; } public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->world->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/Sapling.php b/src/block/Sapling.php index 49a56fe338..8b0e74f542 100644 --- a/src/block/Sapling.php +++ b/src/block/Sapling.php @@ -69,7 +69,7 @@ class Sapling extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof Fertilizer){ - Tree::growTree($this->getWorld(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->treeType); + Tree::growTree($this->pos->getWorld(), $this->pos->x, $this->pos->y, $this->pos->z, new Random(mt_rand()), $this->treeType); $item->pop(); @@ -81,7 +81,7 @@ class Sapling extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->getWorld()->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } @@ -90,12 +90,12 @@ class Sapling extends Flowable{ } public function onRandomTick() : void{ - if($this->world->getFullLightAt($this->x, $this->y, $this->z) >= 8 and mt_rand(1, 7) === 1){ + if($this->pos->getWorld()->getFullLightAt($this->pos->x, $this->pos->y, $this->pos->z) >= 8 and mt_rand(1, 7) === 1){ if($this->ready){ - Tree::growTree($this->getWorld(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->treeType); + Tree::growTree($this->pos->getWorld(), $this->pos->x, $this->pos->y, $this->pos->z, new Random(mt_rand()), $this->treeType); }else{ $this->ready = true; - $this->getWorld()->setBlock($this, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } } } diff --git a/src/block/Sign.php b/src/block/Sign.php index 34dc1f75d2..d8a7094101 100644 --- a/src/block/Sign.php +++ b/src/block/Sign.php @@ -85,7 +85,7 @@ class Sign extends Transparent{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->world->getTile($this); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileSign){ $this->text = $tile->getText(); } @@ -93,7 +93,7 @@ class Sign extends Transparent{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->world->getTile($this); + $tile = $this->pos->getWorld()->getTile($this->pos); assert($tile instanceof TileSign); $tile->setText($this->text); } @@ -125,7 +125,7 @@ class Sign extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::opposite($this->facing))->getId() === BlockLegacyIds::AIR){ - $this->getWorld()->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } @@ -162,7 +162,7 @@ class Sign extends Transparent{ $ev->call(); if(!$ev->isCancelled()){ $this->text = clone $ev->getNewText(); - $this->world->setBlock($this, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); return true; } diff --git a/src/block/Skull.php b/src/block/Skull.php index 8bf7e454a1..a31b39caaa 100644 --- a/src/block/Skull.php +++ b/src/block/Skull.php @@ -67,7 +67,7 @@ class Skull extends Flowable{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->world->getTile($this); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileSkull){ $this->skullType = $tile->getSkullType(); $this->rotation = $tile->getRotation(); @@ -77,7 +77,7 @@ class Skull extends Flowable{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); //extra block properties storage hack - $tile = $this->world->getTile($this); + $tile = $this->pos->getWorld()->getTile($this->pos); assert($tile instanceof TileSkull); $tile->setRotation($this->rotation); $tile->setSkullType($this->skullType); diff --git a/src/block/SnowLayer.php b/src/block/SnowLayer.php index cbf0e583cc..bad9b5437a 100644 --- a/src/block/SnowLayer.php +++ b/src/block/SnowLayer.php @@ -88,8 +88,8 @@ class SnowLayer extends Flowable implements Fallable{ } public function onRandomTick() : void{ - if($this->world->getBlockLightAt($this->x, $this->y, $this->z) >= 12){ - $this->getWorld()->setBlock($this, VanillaBlocks::AIR(), false); + if($this->pos->getWorld()->getBlockLightAt($this->pos->x, $this->pos->y, $this->pos->z) >= 12){ + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR(), false); } } diff --git a/src/block/Stem.php b/src/block/Stem.php index 4d0dbf8490..6ef52f1658 100644 --- a/src/block/Stem.php +++ b/src/block/Stem.php @@ -45,7 +45,7 @@ abstract class Stem extends Crops{ $ev = new BlockGrowEvent($this, $block); $ev->call(); if(!$ev->isCancelled()){ - $this->getWorld()->setBlock($this, $ev->getNewState()); + $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); } }else{ $grow = $this->getPlant(); @@ -61,7 +61,7 @@ abstract class Stem extends Crops{ $ev = new BlockGrowEvent($side, $grow); $ev->call(); if(!$ev->isCancelled()){ - $this->getWorld()->setBlock($side, $ev->getNewState()); + $this->pos->getWorld()->setBlock($side->pos, $ev->getNewState()); } } } diff --git a/src/block/Sugarcane.php b/src/block/Sugarcane.php index ecdbdb3e9a..d3444052f3 100644 --- a/src/block/Sugarcane.php +++ b/src/block/Sugarcane.php @@ -57,20 +57,20 @@ class Sugarcane extends Flowable{ if($item instanceof Fertilizer){ if(!$this->getSide(Facing::DOWN)->isSameType($this)){ for($y = 1; $y < 3; ++$y){ - $b = $this->getWorld()->getBlockAt($this->x, $this->y + $y, $this->z); + $b = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z); if($b->getId() === BlockLegacyIds::AIR){ $ev = new BlockGrowEvent($b, VanillaBlocks::SUGARCANE()); $ev->call(); if($ev->isCancelled()){ break; } - $this->getWorld()->setBlock($b, $ev->getNewState()); + $this->pos->getWorld()->setBlock($b->pos, $ev->getNewState()); }else{ break; } } $this->age = 0; - $this->getWorld()->setBlock($this, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } $item->pop(); @@ -84,7 +84,7 @@ class Sugarcane extends Flowable{ public function onNearbyBlockChange() : void{ $down = $this->getSide(Facing::DOWN); if($down->isTransparent() and !$down->isSameType($this)){ - $this->getWorld()->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } @@ -96,17 +96,17 @@ class Sugarcane extends Flowable{ if(!$this->getSide(Facing::DOWN)->isSameType($this)){ if($this->age === 15){ for($y = 1; $y < 3; ++$y){ - $b = $this->getWorld()->getBlockAt($this->x, $this->y + $y, $this->z); + $b = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z); if($b->getId() === BlockLegacyIds::AIR){ - $this->getWorld()->setBlock($b, VanillaBlocks::SUGARCANE()); + $this->pos->getWorld()->setBlock($b->pos, VanillaBlocks::SUGARCANE()); break; } } $this->age = 0; - $this->getWorld()->setBlock($this, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); }else{ ++$this->age; - $this->getWorld()->setBlock($this, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } } } diff --git a/src/block/TNT.php b/src/block/TNT.php index e263d7cba1..8a9e9a44f4 100644 --- a/src/block/TNT.php +++ b/src/block/TNT.php @@ -90,14 +90,14 @@ class TNT extends Opaque{ } public function ignite(int $fuse = 80) : void{ - $this->getWorld()->setBlock($this, VanillaBlocks::AIR()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); $mot = (new Random())->nextSignedFloat() * M_PI * 2; - $nbt = EntityFactory::createBaseNBT($this->add(0.5, 0, 0.5), new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02)); + $nbt = EntityFactory::createBaseNBT($this->pos->add(0.5, 0, 0.5), new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02)); $nbt->setShort("Fuse", $fuse); /** @var PrimedTNT $tnt */ - $tnt = EntityFactory::create(PrimedTNT::class, $this->getWorld(), $nbt); + $tnt = EntityFactory::create(PrimedTNT::class, $this->pos->getWorld(), $nbt); $tnt->spawnToAll(); } diff --git a/src/block/TallGrass.php b/src/block/TallGrass.php index 9e984c1c41..88b3ac6cee 100644 --- a/src/block/TallGrass.php +++ b/src/block/TallGrass.php @@ -52,7 +52,7 @@ class TallGrass extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ //Replace with common break method - $this->world->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/Torch.php b/src/block/Torch.php index bbbd5b4dd0..001fbba6f4 100644 --- a/src/block/Torch.php +++ b/src/block/Torch.php @@ -60,7 +60,7 @@ class Torch extends Flowable{ $face = Facing::opposite($this->facing); if($this->getSide($face)->isTransparent() and !($face === Facing::DOWN and ($below->getId() === BlockLegacyIds::FENCE or $below->getId() === BlockLegacyIds::COBBLESTONE_WALL))){ - $this->getWorld()->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/Trapdoor.php b/src/block/Trapdoor.php index b465f6c72d..ff37fb48e4 100644 --- a/src/block/Trapdoor.php +++ b/src/block/Trapdoor.php @@ -74,8 +74,8 @@ class Trapdoor extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->open = !$this->open; - $this->world->setBlock($this, $this); - $this->world->addSound($this, new DoorSound()); + $this->pos->getWorld()->setBlock($this->pos, $this); + $this->pos->getWorld()->addSound($this->pos, new DoorSound()); return true; } } diff --git a/src/block/Vine.php b/src/block/Vine.php index a3706442c0..c84308c8fd 100644 --- a/src/block/Vine.php +++ b/src/block/Vine.php @@ -128,9 +128,9 @@ class Vine extends Flowable{ if($changed){ if(empty($this->faces)){ - $this->world->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); }else{ - $this->world->setBlock($this, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } } } diff --git a/src/block/WaterLily.php b/src/block/WaterLily.php index 4b6bcaeb50..0ee0b299c5 100644 --- a/src/block/WaterLily.php +++ b/src/block/WaterLily.php @@ -53,7 +53,7 @@ class WaterLily extends Flowable{ public function onNearbyBlockChange() : void{ if(!($this->getSide(Facing::DOWN) instanceof Water)){ - $this->getWorld()->useBreakOn($this); + $this->pos->getWorld()->useBreakOn($this->pos); } } } diff --git a/src/block/tile/BrewingStand.php b/src/block/tile/BrewingStand.php index 6c4a02c84a..0046916bef 100644 --- a/src/block/tile/BrewingStand.php +++ b/src/block/tile/BrewingStand.php @@ -55,7 +55,7 @@ class BrewingStand extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ $this->inventory = new BrewingStandInventory($this); $this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange(function(Inventory $unused){ - $this->world->scheduleDelayedBlockUpdate($this->getBlock(), 1); + $this->world->scheduleDelayedBlockUpdate($this->getBlock()->getPos(), 1); })); parent::__construct($world, $pos); } diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index 1189cc0454..9db38e306a 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -133,7 +133,7 @@ class Furnace extends Spawnable implements Container, Nameable{ $block = $this->getBlock(); if($block instanceof BlockFurnace and !$block->isLit()){ $block->setLit(true); - $this->getWorld()->setBlock($block, $block); + $this->getWorld()->setBlock($block->getPos(), $block); } if($this->remainingFuelTime > 0 and $ev->isBurning()){ @@ -196,7 +196,7 @@ class Furnace extends Spawnable implements Container, Nameable{ $block = $this->getBlock(); if($block instanceof BlockFurnace and $block->isLit()){ $block->setLit(false); - $this->getWorld()->setBlock($block, $block); + $this->getWorld()->setBlock($block->getPos(), $block); } $this->remainingFuelTime = $this->cookTime = $this->maxFuelTime = 0; } diff --git a/src/block/utils/FallableTrait.php b/src/block/utils/FallableTrait.php index 2ee53fd879..90b52b18ee 100644 --- a/src/block/utils/FallableTrait.php +++ b/src/block/utils/FallableTrait.php @@ -39,14 +39,14 @@ use pocketmine\world\Position; */ trait FallableTrait{ - abstract protected function asPosition() : Position; + abstract protected function getPos() : Position; abstract protected function getId() : int; abstract protected function getMeta() : int; public function onNearbyBlockChange() : void{ - $pos = $this->asPosition(); + $pos = $this->getPos(); $down = $pos->world->getBlock($pos->getSide(Facing::DOWN)); if($down->getId() === BlockLegacyIds::AIR or $down instanceof Liquid or $down instanceof Fire){ $pos->world->setBlock($pos, VanillaBlocks::AIR()); diff --git a/src/entity/Entity.php b/src/entity/Entity.php index d38e571de0..804500b679 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1180,10 +1180,10 @@ abstract class Entity extends Location{ } public function isUnderwater() : bool{ - $block = $this->world->getBlockAt((int) floor($this->x), (int) floor($y = ($this->y + $this->getEyeHeight())), (int) floor($this->z)); + $block = $this->world->getBlockAt((int) floor($this->x), $blockY = (int) floor($y = ($this->y + $this->getEyeHeight())), (int) floor($this->z)); if($block instanceof Water){ - $f = ($block->y + 1) - ($block->getFluidHeightPercent() - 0.1111111); + $f = ($blockY + 1) - ($block->getFluidHeightPercent() - 0.1111111); return $y < $f; } diff --git a/src/entity/projectile/EnderPearl.php b/src/entity/projectile/EnderPearl.php index bf7d6d2f7c..e13cbddc61 100644 --- a/src/entity/projectile/EnderPearl.php +++ b/src/entity/projectile/EnderPearl.php @@ -40,7 +40,8 @@ class EnderPearl extends Throwable{ protected function calculateInterceptWithBlock(Block $block, Vector3 $start, Vector3 $end) : ?RayTraceResult{ if($block->getId() !== BlockLegacyIds::AIR and empty($block->getCollisionBoxes())){ //TODO: remove this once block collision boxes are fixed properly - return AxisAlignedBB::one()->offset($block->x, $block->y, $block->z)->calculateIntercept($start, $end); + $pos = $block->getPos(); + return AxisAlignedBB::one()->offset($pos->x, $pos->y, $pos->z)->calculateIntercept($start, $end); } return parent::calculateInterceptWithBlock($block, $start, $end); diff --git a/src/entity/projectile/Projectile.php b/src/entity/projectile/Projectile.php index 1079046af2..72eaa7db0e 100644 --- a/src/entity/projectile/Projectile.php +++ b/src/entity/projectile/Projectile.php @@ -146,9 +146,10 @@ abstract class Projectile extends Entity{ $nbt->setDouble("damage", $this->damage); if($this->blockHit !== null){ - $nbt->setInt("tileX", $this->blockHit->x); - $nbt->setInt("tileY", $this->blockHit->y); - $nbt->setInt("tileZ", $this->blockHit->z); + $pos = $this->blockHit->getPos(); + $nbt->setInt("tileX", $pos->x); + $nbt->setInt("tileY", $pos->y); + $nbt->setInt("tileZ", $pos->z); //we intentionally use different ones to PC because we don't have stringy IDs $nbt->setInt("blockId", $this->blockHit->getId()); @@ -163,7 +164,7 @@ abstract class Projectile extends Entity{ } public function onNearbyBlockChange() : void{ - if($this->blockHit !== null and $this->world->isInLoadedTerrain($this->blockHit) and !$this->blockHit->isSameState($this->world->getBlock($this->blockHit))){ + if($this->blockHit !== null and $this->world->isInLoadedTerrain($this->blockHit->getPos()) and !$this->blockHit->isSameState($this->world->getBlock($this->blockHit->getPos()))){ $this->blockHit = null; } diff --git a/src/entity/projectile/SplashPotion.php b/src/entity/projectile/SplashPotion.php index fccc8f02e7..53b892670f 100644 --- a/src/entity/projectile/SplashPotion.php +++ b/src/entity/projectile/SplashPotion.php @@ -129,11 +129,11 @@ class SplashPotion extends Throwable{ $blockIn = $event->getBlockHit()->getSide($event->getRayTraceResult()->getHitFace()); if($blockIn->getId() === BlockLegacyIds::FIRE){ - $this->world->setBlock($blockIn, VanillaBlocks::AIR()); + $this->world->setBlock($blockIn->getPos(), VanillaBlocks::AIR()); } foreach($blockIn->getHorizontalSides() as $horizontalSide){ if($horizontalSide->getId() === BlockLegacyIds::FIRE){ - $this->world->setBlock($horizontalSide, VanillaBlocks::AIR()); + $this->world->setBlock($horizontalSide->getPos(), VanillaBlocks::AIR()); } } } diff --git a/src/item/Bucket.php b/src/item/Bucket.php index fdcb8ec895..c9b23ac1ff 100644 --- a/src/item/Bucket.php +++ b/src/item/Bucket.php @@ -46,8 +46,8 @@ class Bucket extends Item{ $ev = new PlayerBucketFillEvent($player, $blockReplace, $face, $this, $resultItem); $ev->call(); if(!$ev->isCancelled()){ - $player->getWorld()->setBlock($blockClicked, VanillaBlocks::AIR()); - $player->getWorld()->addSound($blockClicked->add(0.5, 0.5, 0.5), $blockClicked->getBucketFillSound()); + $player->getWorld()->setBlock($blockClicked->getPos(), VanillaBlocks::AIR()); + $player->getWorld()->addSound($blockClicked->getPos()->add(0.5, 0.5, 0.5), $blockClicked->getBucketFillSound()); if($player->hasFiniteResources()){ if($stack->getCount() === 0){ $player->getInventory()->setItemInHand($ev->getItem()); diff --git a/src/item/FlintSteel.php b/src/item/FlintSteel.php index 18772a05fc..04c3150904 100644 --- a/src/item/FlintSteel.php +++ b/src/item/FlintSteel.php @@ -37,8 +37,8 @@ class FlintSteel extends Tool{ if($blockReplace->getId() === BlockLegacyIds::AIR){ $world = $player->getWorld(); assert($world !== null); - $world->setBlock($blockReplace, VanillaBlocks::FIRE()); - $world->addSound($blockReplace->add(0.5, 0.5, 0.5), new FlintSteelSound()); + $world->setBlock($blockReplace->getPos(), VanillaBlocks::FIRE()); + $world->addSound($blockReplace->getPos()->add(0.5, 0.5, 0.5), new FlintSteelSound()); $this->applyDamage(1); diff --git a/src/item/LiquidBucket.php b/src/item/LiquidBucket.php index 0186c45b66..095de17347 100644 --- a/src/item/LiquidBucket.php +++ b/src/item/LiquidBucket.php @@ -63,8 +63,8 @@ class LiquidBucket extends Item{ $ev = new PlayerBucketEmptyEvent($player, $blockReplace, $face, $this, VanillaItems::BUCKET()); $ev->call(); if(!$ev->isCancelled()){ - $player->getWorld()->setBlock($blockReplace, $resultBlock->getFlowingForm()); - $player->getWorld()->addSound($blockReplace->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound()); + $player->getWorld()->setBlock($blockReplace->getPos(), $resultBlock->getFlowingForm()); + $player->getWorld()->addSound($blockReplace->getPos()->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound()); if($player->hasFiniteResources()){ $player->getInventory()->setItemInHand($ev->getItem()); diff --git a/src/item/PaintingItem.php b/src/item/PaintingItem.php index d8e139de9a..88d394d2f9 100644 --- a/src/item/PaintingItem.php +++ b/src/item/PaintingItem.php @@ -49,7 +49,7 @@ class PaintingItem extends Item{ continue; } - if(Painting::canFit($player->getWorld(), $blockReplace, $face, true, $motive)){ + if(Painting::canFit($player->getWorld(), $blockReplace->getPos(), $face, true, $motive)){ if($currentTotalDimension > $totalDimension){ $totalDimension = $currentTotalDimension; /* @@ -83,19 +83,21 @@ class PaintingItem extends Item{ return ItemUseResult::NONE(); } - $nbt = EntityFactory::createBaseNBT($blockReplace, null, $direction * 90, 0); + $replacePos = $blockReplace->getPos(); + $clickedPos = $blockClicked->getPos(); + $nbt = EntityFactory::createBaseNBT($replacePos, null, $direction * 90, 0); $nbt->setByte("Direction", $direction); $nbt->setString("Motive", $motive->getName()); - $nbt->setInt("TileX", $blockClicked->getFloorX()); - $nbt->setInt("TileY", $blockClicked->getFloorY()); - $nbt->setInt("TileZ", $blockClicked->getFloorZ()); + $nbt->setInt("TileX", $clickedPos->getFloorX()); + $nbt->setInt("TileY", $clickedPos->getFloorY()); + $nbt->setInt("TileZ", $clickedPos->getFloorZ()); /** @var Painting $entity */ - $entity = EntityFactory::create(Painting::class, $blockReplace->getWorld(), $nbt); + $entity = EntityFactory::create(Painting::class, $replacePos->getWorld(), $nbt); $this->pop(); $entity->spawnToAll(); - $player->getWorld()->addSound($blockReplace->add(0.5, 0.5, 0.5), new PaintingPlaceSound()); + $player->getWorld()->addSound($replacePos->add(0.5, 0.5, 0.5), new PaintingPlaceSound()); return ItemUseResult::SUCCESS(); } } diff --git a/src/item/SpawnEgg.php b/src/item/SpawnEgg.php index f09ceee099..ac3fd5b3ee 100644 --- a/src/item/SpawnEgg.php +++ b/src/item/SpawnEgg.php @@ -52,7 +52,7 @@ class SpawnEgg extends Item{ } public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ - $nbt = EntityFactory::createBaseNBT($blockReplace->add(0.5, 0, 0.5), null, lcg_value() * 360, 0); + $nbt = EntityFactory::createBaseNBT($blockReplace->getPos()->add(0.5, 0, 0.5), null, lcg_value() * 360, 0); if($this->hasCustomName()){ $nbt->setString("CustomName", $this->getCustomName()); diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 7478472ae6..62d2660bb9 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -532,7 +532,7 @@ class InGamePacketHandler extends PacketHandler{ try{ if(!$block->updateText($this->player, $text)){ - $this->player->getWorld()->sendBlocks([$this->player], [$block]); + $this->player->getWorld()->sendBlocks([$this->player], [$pos]); } }catch(\UnexpectedValueException $e){ throw new BadPacketException($e->getMessage(), 0, $e); diff --git a/src/player/Player.php b/src/player/Player.php index 85d03c506d..ed8380d446 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1696,7 +1696,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $block = $target->getSide($face); if($block->getId() === BlockLegacyIds::FIRE){ - $this->world->setBlock($block, VanillaBlocks::AIR()); + $this->world->setBlock($block->getPos(), VanillaBlocks::AIR()); return true; } diff --git a/src/world/ChunkListener.php b/src/world/ChunkListener.php index 3685d6dfa9..c88f31f76d 100644 --- a/src/world/ChunkListener.php +++ b/src/world/ChunkListener.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\world; -use pocketmine\block\Block; use pocketmine\math\Vector3; use pocketmine\world\format\Chunk; @@ -74,7 +73,7 @@ interface ChunkListener{ /** * This method will be called when a block changes in a registered chunk * - * @param Block|Vector3 $block + * @param Vector3 $block */ public function onBlockChanged(Vector3 $block) : void; } diff --git a/src/world/World.php b/src/world/World.php index 32edf71eef..fa4ee82575 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -776,7 +776,7 @@ class World implements ChunkManager{ $ev = new BlockUpdateEvent($block); $ev->call(); if(!$ev->isCancelled()){ - foreach($this->getNearbyEntities(AxisAlignedBB::one()->offset($block->x, $block->y, $block->z)) as $entity){ + foreach($this->getNearbyEntities(AxisAlignedBB::one()->offset($x, $y, $z)) as $entity){ $entity->onNearbyBlockChange(); } $block->onNearbyBlockChange(); @@ -896,12 +896,8 @@ class World implements ChunkManager{ throw new \TypeError("Expected Vector3 in blocks array, got " . (is_object($b) ? get_class($b) : gettype($b))); } - if($b instanceof Block){ - $packets[] = UpdateBlockPacket::create($b->x, $b->y, $b->z, $b->getRuntimeId()); - }else{ - $fullBlock = $this->getFullBlock($b->x, $b->y, $b->z); - $packets[] = UpdateBlockPacket::create($b->x, $b->y, $b->z, RuntimeBlockMapping::toStaticRuntimeId($fullBlock >> 4, $fullBlock & 0xf)); - } + $fullBlock = $this->getBlockAt($b->x, $b->y, $b->z); + $packets[] = UpdateBlockPacket::create($b->x, $b->y, $b->z, $fullBlock->getRuntimeId()); $tile = $this->getTileAt($b->x, $b->y, $b->z); if($tile instanceof Spawnable){ @@ -1125,19 +1121,15 @@ class World implements ChunkManager{ } /** - * @param Vector3 $pos + * @param Block $pos * * @return bool */ - public function isFullBlock(Vector3 $pos) : bool{ - if($pos instanceof Block){ - if($pos->isSolid()){ - return true; - } - $bb = $pos->getBoundingBox(); - }else{ - $bb = $this->getBlock($pos)->getBoundingBox(); + public function isFullBlock(Block $pos) : bool{ + if($pos->isSolid()){ + return true; } + $bb = $pos->getBoundingBox(); return $bb !== null and $bb->getAverageEdgeLength() >= 1; } @@ -1489,6 +1481,7 @@ class World implements ChunkManager{ $block->position($this, $x, $y, $z); $block->writeStateToWorld(); + $pos = $block->getPos(); $chunkHash = World::chunkHash($x >> 4, $z >> 4); $relativeBlockHash = World::chunkBlockHash($x, $y, $z); @@ -1498,18 +1491,18 @@ class World implements ChunkManager{ if(!isset($this->changedBlocks[$chunkHash])){ $this->changedBlocks[$chunkHash] = []; } - $this->changedBlocks[$chunkHash][$relativeBlockHash] = $block; + $this->changedBlocks[$chunkHash][$relativeBlockHash] = $pos; foreach($this->getChunkListeners($x >> 4, $z >> 4) as $listener){ - $listener->onBlockChanged($block); + $listener->onBlockChanged($pos); } if($update){ if($oldBlock->getLightFilter() !== $block->getLightFilter() or $oldBlock->getLightLevel() !== $block->getLightLevel()){ - $this->updateAllLight($block); + $this->updateAllLight($pos); } - $this->tryAddToNeighbourUpdateQueue($block); - foreach($block->sides() as $side){ + $this->tryAddToNeighbourUpdateQueue($pos); + foreach($pos->sides() as $side){ $this->tryAddToNeighbourUpdateQueue($side); } } @@ -1585,6 +1578,7 @@ class World implements ChunkManager{ * @return bool */ public function useBreakOn(Vector3 $vector, Item &$item = null, ?Player $player = null, bool $createParticles = false) : bool{ + $vector = $vector->floor(); $target = $this->getBlock($vector); $affectedBlocks = $target->getAffectedBlocks(); @@ -1641,7 +1635,7 @@ class World implements ChunkManager{ $item->onDestroyBlock($target); if(!empty($drops)){ - $dropPos = $target->add(0.5, 0.5, 0.5); + $dropPos = $vector->add(0.5, 0.5, 0.5); foreach($drops as $drop){ if(!$drop->isNull()){ $this->dropItem($dropPos, $drop); @@ -1650,7 +1644,7 @@ class World implements ChunkManager{ } if($xpDrop > 0){ - $this->dropExperience($target->add(0.5, 0.5, 0.5), $xpDrop); + $this->dropExperience($vector->add(0.5, 0.5, 0.5), $xpDrop); } return true; @@ -1658,12 +1652,12 @@ class World implements ChunkManager{ private function destroyBlockInternal(Block $target, Item $item, ?Player $player = null, bool $createParticles = false) : void{ if($createParticles){ - $this->addParticle($target->add(0.5, 0.5, 0.5), new DestroyBlockParticle($target)); + $this->addParticle($target->getPos()->add(0.5, 0.5, 0.5), new DestroyBlockParticle($target)); } $target->onBreak($item, $player); - $tile = $this->getTile($target); + $tile = $this->getTile($target->getPos()); if($tile !== null){ $tile->onBlockDestroyed(); } @@ -1689,7 +1683,7 @@ class World implements ChunkManager{ $clickVector = new Vector3(0.0, 0.0, 0.0); } - if(!$this->isInWorld($blockReplace->x, $blockReplace->y, $blockReplace->z)){ + if(!$this->isInWorld($blockReplace->getPos()->x, $blockReplace->getPos()->y, $blockReplace->getPos()->z)){ //TODO: build height limit messages for custom world heights and mcregion cap return false; } @@ -1721,14 +1715,14 @@ class World implements ChunkManager{ if($item->canBePlaced()){ $hand = $item->getBlock(); - $hand->position($this, $blockReplace->x, $blockReplace->y, $blockReplace->z); + $hand->position($this, $blockReplace->getPos()->x, $blockReplace->getPos()->y, $blockReplace->getPos()->z); }else{ return false; } if($hand->canBePlacedAt($blockClicked, $clickVector, $face, true)){ $blockReplace = $blockClicked; - $hand->position($this, $blockReplace->x, $blockReplace->y, $blockReplace->z); + $hand->position($this, $blockReplace->getPos()->x, $blockReplace->getPos()->y, $blockReplace->getPos()->z); }elseif(!$hand->canBePlacedAt($blockReplace, $clickVector, $face, false)){ return false; } @@ -1785,7 +1779,7 @@ class World implements ChunkManager{ } if($playSound){ - $this->addSound($hand, new BlockPlaceSound($hand)); + $this->addSound($hand->getPos(), new BlockPlaceSound($hand)); } $item->pop(); From 927e05d038cfc086a4fe8f287c68a71e745a45de Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 5 Aug 2019 17:15:10 +0100 Subject: [PATCH 1173/3224] [ci skip] update changelog --- changelogs/4.0-snapshot.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index c0b2568074..5fed11267b 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -62,6 +62,7 @@ This version features substantial changes to the network system, improving coher ### Block - A new `VanillaBlocks` class has been added, which contains static methods for creating any currently-known block type. This should be preferred instead of use of `BlockFactory::get()` where constants were used. +- Blocks now contain their positions instead of extending `Position`. `Block->getPos()` has been added. - Blocks with IDs >= 256 are now supported. - Block state and variant metadata have been separated. - Variant is considered an extension of ID and is immutable. From 358fea9645eb24fb7d120ede8b33f6dac2ed85bd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 5 Aug 2019 17:20:48 +0100 Subject: [PATCH 1174/3224] Move Location to Entity namespace --- changelogs/4.0-snapshot.md | 1 + src/entity/Entity.php | 2 +- src/{world => entity}/Location.php | 4 +++- src/event/player/PlayerMoveEvent.php | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) rename src/{world => entity}/Location.php (96%) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 5fed11267b..f7bd51f923 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -692,6 +692,7 @@ This version features substantial changes to the network system, improving coher - `ChunkLoader->onChunkLoaded()` -> `ChunkListener->onChunkLoaded()` - `ChunkLoader->onChunkPopulated()` -> `ChunkListener->onChunkPopulated()` - `ChunkLoader->onChunkUnloaded()` -> `ChunkListener->onChunkUnloaded()` +- `Location` has been moved to `pocketmine\entity\Location`. #### Particles - `pocketmine\world\particle\Particle` no longer extends `pocketmine\math\Vector3`, and has been converted to an interface. diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 804500b679..757408644e 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -59,7 +59,7 @@ use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; use pocketmine\world\format\Chunk; -use pocketmine\world\Location; +use pocketmine\entity\Location; use pocketmine\world\Position; use pocketmine\world\World; use function abs; diff --git a/src/world/Location.php b/src/entity/Location.php similarity index 96% rename from src/world/Location.php rename to src/entity/Location.php index 96349af866..c9e8703b88 100644 --- a/src/world/Location.php +++ b/src/entity/Location.php @@ -21,9 +21,11 @@ declare(strict_types=1); -namespace pocketmine\world; +namespace pocketmine\entity; use pocketmine\math\Vector3; +use pocketmine\world\Position; +use pocketmine\world\World; class Location extends Position{ diff --git a/src/event/player/PlayerMoveEvent.php b/src/event/player/PlayerMoveEvent.php index 7678eed053..86e152a513 100644 --- a/src/event/player/PlayerMoveEvent.php +++ b/src/event/player/PlayerMoveEvent.php @@ -26,7 +26,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\player\Player; -use pocketmine\world\Location; +use pocketmine\entity\Location; class PlayerMoveEvent extends PlayerEvent implements Cancellable{ use CancellableTrait; From 9353f616a290368ceb21e09a9bb30f23919d8011 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 5 Aug 2019 18:50:29 +0100 Subject: [PATCH 1175/3224] All BlockInventory descendents now have a Position as holder this allows multiple problems to be solved: 1) Cycle between tile and inventory is now removed. 2) BlockInventory now provides a consistent API for plugins to get the block holding an inventory. --- src/block/tile/BrewingStand.php | 2 +- src/block/tile/Chest.php | 6 +++--- src/block/tile/Furnace.php | 3 +-- src/block/tile/Hopper.php | 2 +- src/block/tile/Tile.php | 2 +- src/inventory/AnvilInventory.php | 15 ++------------- src/inventory/BlockInventory.php | 10 +++++----- src/inventory/BrewingStandInventory.php | 4 ++-- src/inventory/ChestInventory.php | 19 ++++--------------- src/inventory/DoubleChestInventory.php | 10 +++++----- src/inventory/EnchantInventory.php | 15 ++------------- src/inventory/EnderChestInventory.php | 23 ++++------------------- src/inventory/FurnaceInventory.php | 16 +++------------- src/inventory/HopperInventory.php | 4 ++-- 14 files changed, 36 insertions(+), 95 deletions(-) diff --git a/src/block/tile/BrewingStand.php b/src/block/tile/BrewingStand.php index 0046916bef..21663d69cf 100644 --- a/src/block/tile/BrewingStand.php +++ b/src/block/tile/BrewingStand.php @@ -53,11 +53,11 @@ class BrewingStand extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ + parent::__construct($world, $pos); $this->inventory = new BrewingStandInventory($this); $this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange(function(Inventory $unused){ $this->world->scheduleDelayedBlockUpdate($this->getBlock()->getPos(), 1); })); - parent::__construct($world, $pos); } public function readSaveData(CompoundTag $nbt) : void{ diff --git a/src/block/tile/Chest.php b/src/block/tile/Chest.php index edcde8fe91..6479c46285 100644 --- a/src/block/tile/Chest.php +++ b/src/block/tile/Chest.php @@ -54,8 +54,8 @@ class Chest extends Spawnable implements Container, Nameable{ private $pairZ; public function __construct(World $world, Vector3 $pos){ - $this->inventory = new ChestInventory($this); parent::__construct($world, $pos); + $this->inventory = new ChestInventory($this); } public function readSaveData(CompoundTag $nbt) : void{ @@ -152,9 +152,9 @@ class Chest extends Spawnable implements Container, Nameable{ $this->doubleInventory = $pair->doubleInventory; }else{ if(($pair->x + ($pair->z << 15)) > ($this->x + ($this->z << 15))){ //Order them correctly - $this->doubleInventory = $pair->doubleInventory = new DoubleChestInventory($pair, $this); + $this->doubleInventory = $pair->doubleInventory = new DoubleChestInventory($pair->inventory, $this->inventory); }else{ - $this->doubleInventory = $pair->doubleInventory = new DoubleChestInventory($this, $pair); + $this->doubleInventory = $pair->doubleInventory = new DoubleChestInventory($this->inventory, $pair->inventory); } } } diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index 9db38e306a..0cd82cfaa3 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -56,14 +56,13 @@ class Furnace extends Spawnable implements Container, Nameable{ private $maxFuelTime = 0; public function __construct(World $world, Vector3 $pos){ + parent::__construct($world, $pos); $this->inventory = new FurnaceInventory($this); $this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange( function(Inventory $unused) : void{ $this->world->scheduleDelayedBlockUpdate($this->asVector3(), 1); }) ); - - parent::__construct($world, $pos); } public function readSaveData(CompoundTag $nbt) : void{ diff --git a/src/block/tile/Hopper.php b/src/block/tile/Hopper.php index 1d3f369bc5..ee620b5c48 100644 --- a/src/block/tile/Hopper.php +++ b/src/block/tile/Hopper.php @@ -42,8 +42,8 @@ class Hopper extends Spawnable implements Container, Nameable{ private $transferCooldown = 0; public function __construct(World $world, Vector3 $pos){ - $this->inventory = new HopperInventory($this); parent::__construct($world, $pos); + $this->inventory = new HopperInventory($this); } public function readSaveData(CompoundTag $nbt) : void{ diff --git a/src/block/tile/Tile.php b/src/block/tile/Tile.php index 3530cabc5b..3eaeaaed49 100644 --- a/src/block/tile/Tile.php +++ b/src/block/tile/Tile.php @@ -50,8 +50,8 @@ abstract class Tile extends Position{ protected $timings; public function __construct(World $world, Vector3 $pos){ - $this->timings = Timings::getTileEntityTimings($this); parent::__construct($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ(), $world); + $this->timings = Timings::getTileEntityTimings($this); } /** diff --git a/src/inventory/AnvilInventory.php b/src/inventory/AnvilInventory.php index c069816d0d..e07ff965e9 100644 --- a/src/inventory/AnvilInventory.php +++ b/src/inventory/AnvilInventory.php @@ -28,19 +28,8 @@ use pocketmine\world\Position; class AnvilInventory extends BlockInventory{ - /** @var Position */ - protected $holder; - - public function __construct(Position $pos){ - parent::__construct($pos->asPosition(), 2); - } - - /** - * This override is here for documentation and code completion purposes only. - * @return Position - */ - public function getHolder(){ - return $this->holder; + public function __construct(Position $holder){ + parent::__construct($holder, 2); } public function onClose(Player $who) : void{ diff --git a/src/inventory/BlockInventory.php b/src/inventory/BlockInventory.php index 46d0193e01..5e4267b61f 100644 --- a/src/inventory/BlockInventory.php +++ b/src/inventory/BlockInventory.php @@ -23,19 +23,19 @@ declare(strict_types=1); namespace pocketmine\inventory; -use pocketmine\math\Vector3; +use pocketmine\world\Position; class BlockInventory extends BaseInventory{ - /** @var Vector3 */ + /** @var Position */ protected $holder; - public function __construct(Vector3 $holder, int $size){ - $this->holder = $holder; + public function __construct(Position $holder, int $size){ + $this->holder = $holder->asPosition(); parent::__construct($size); } /** - * @return Vector3 + * @return Position */ public function getHolder(){ return $this->holder; diff --git a/src/inventory/BrewingStandInventory.php b/src/inventory/BrewingStandInventory.php index 238cf99d7f..48aaaa6b37 100644 --- a/src/inventory/BrewingStandInventory.php +++ b/src/inventory/BrewingStandInventory.php @@ -23,11 +23,11 @@ declare(strict_types=1); namespace pocketmine\inventory; -use pocketmine\math\Vector3; +use pocketmine\world\Position; class BrewingStandInventory extends BlockInventory{ - public function __construct(Vector3 $holder, int $size = 5){ + public function __construct(Position $holder, int $size = 5){ parent::__construct($holder, $size); } } diff --git a/src/inventory/ChestInventory.php b/src/inventory/ChestInventory.php index db7a788cf8..49235d4446 100644 --- a/src/inventory/ChestInventory.php +++ b/src/inventory/ChestInventory.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace pocketmine\inventory; -use pocketmine\block\tile\Chest; use pocketmine\network\mcpe\protocol\BlockEventPacket; use pocketmine\player\Player; +use pocketmine\world\Position; use pocketmine\world\sound\ChestCloseSound; use pocketmine\world\sound\ChestOpenSound; use pocketmine\world\sound\Sound; @@ -33,22 +33,11 @@ use function count; class ChestInventory extends BlockInventory{ - /** @var Chest */ - protected $holder; - /** - * @param Chest $tile + * @param Position $holder */ - public function __construct(Chest $tile){ - parent::__construct($tile, 27); - } - - /** - * This override is here for documentation and code completion purposes only. - * @return Chest - */ - public function getHolder(){ - return $this->holder; + public function __construct(Position $holder){ + parent::__construct($holder, 27); } protected function getOpenSound() : Sound{ diff --git a/src/inventory/DoubleChestInventory.php b/src/inventory/DoubleChestInventory.php index f600cf0b42..451ddc7a7a 100644 --- a/src/inventory/DoubleChestInventory.php +++ b/src/inventory/DoubleChestInventory.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace pocketmine\inventory; -use pocketmine\block\tile\Chest; use pocketmine\item\Item; use pocketmine\player\Player; +use pocketmine\world\Position; use function count; class DoubleChestInventory extends ChestInventory implements InventoryHolder{ @@ -34,9 +34,9 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ /** @var ChestInventory */ private $right; - public function __construct(Chest $left, Chest $right){ - $this->left = $left->getRealInventory(); - $this->right = $right->getRealInventory(); + public function __construct(ChestInventory $left, ChestInventory $right){ + $this->left = $left; + $this->right = $right; BaseInventory::__construct($this->left->getSize() + $this->right->getSize()); } @@ -45,7 +45,7 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ } /** - * @return Chest + * @return Position */ public function getHolder(){ return $this->left->getHolder(); diff --git a/src/inventory/EnchantInventory.php b/src/inventory/EnchantInventory.php index 74d40d6877..06d7f651ca 100644 --- a/src/inventory/EnchantInventory.php +++ b/src/inventory/EnchantInventory.php @@ -28,19 +28,8 @@ use pocketmine\world\Position; class EnchantInventory extends BlockInventory{ - /** @var Position */ - protected $holder; - - public function __construct(Position $pos){ - parent::__construct($pos->asPosition(), 2); - } - - /** - * This override is here for documentation and code completion purposes only. - * @return Position - */ - public function getHolder(){ - return $this->holder; + public function __construct(Position $holder){ + parent::__construct($holder, 2); } public function onClose(Player $who) : void{ diff --git a/src/inventory/EnderChestInventory.php b/src/inventory/EnderChestInventory.php index 1986ac7d09..935ee7fe79 100644 --- a/src/inventory/EnderChestInventory.php +++ b/src/inventory/EnderChestInventory.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\inventory; -use pocketmine\block\tile\EnderChest; use pocketmine\world\Position; use pocketmine\world\sound\EnderChestCloseSound; use pocketmine\world\sound\EnderChestOpenSound; @@ -31,21 +30,15 @@ use pocketmine\world\sound\Sound; class EnderChestInventory extends ChestInventory{ - /** @var Position */ - protected $holder; - public function __construct(){ - BlockInventory::__construct(new Position(), 27); + parent::__construct(new Position(0, 0, 0, null)); } /** - * Set the holder's position to that of a tile - * - * @param EnderChest $enderChest + * @param Position $pos */ - public function setHolderPosition(EnderChest $enderChest) : void{ - $this->holder->setComponents($enderChest->getFloorX(), $enderChest->getFloorY(), $enderChest->getFloorZ()); - $this->holder->setWorld($enderChest->getWorld()); + public function setHolderPosition(Position $pos) : void{ + $this->holder = $pos->asPosition(); } protected function getOpenSound() : Sound{ @@ -55,12 +48,4 @@ class EnderChestInventory extends ChestInventory{ protected function getCloseSound() : Sound{ return new EnderChestCloseSound(); } - - /** - * This override is here for documentation and code completion purposes only. - * @return Position - */ - public function getHolder(){ - return $this->holder; - } } diff --git a/src/inventory/FurnaceInventory.php b/src/inventory/FurnaceInventory.php index 6a95c49aa7..b04620dd94 100644 --- a/src/inventory/FurnaceInventory.php +++ b/src/inventory/FurnaceInventory.php @@ -23,23 +23,13 @@ declare(strict_types=1); namespace pocketmine\inventory; -use pocketmine\block\tile\Furnace; use pocketmine\item\Item; +use pocketmine\world\Position; class FurnaceInventory extends BlockInventory{ - /** @var Furnace */ - protected $holder; - public function __construct(Furnace $tile){ - parent::__construct($tile, 3); - } - - /** - * This override is here for documentation and code completion purposes only. - * @return Furnace - */ - public function getHolder(){ - return $this->holder; + public function __construct(Position $holder){ + parent::__construct($holder, 3); } /** diff --git a/src/inventory/HopperInventory.php b/src/inventory/HopperInventory.php index af77a7a451..8378458ce0 100644 --- a/src/inventory/HopperInventory.php +++ b/src/inventory/HopperInventory.php @@ -23,11 +23,11 @@ declare(strict_types=1); namespace pocketmine\inventory; -use pocketmine\math\Vector3; +use pocketmine\world\Position; class HopperInventory extends BlockInventory{ - public function __construct(Vector3 $holder, int $size = 5){ + public function __construct(Position $holder, int $size = 5){ parent::__construct($holder, $size); } } From f0505c028487378afad5123549f2b050f5dd3bc2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 5 Aug 2019 18:53:46 +0100 Subject: [PATCH 1176/3224] Remove dead comments from PlayerInventory and PlayerCursorInventory these aren't overrides anymore. --- src/inventory/PlayerCursorInventory.php | 1 - src/inventory/PlayerInventory.php | 1 - 2 files changed, 2 deletions(-) diff --git a/src/inventory/PlayerCursorInventory.php b/src/inventory/PlayerCursorInventory.php index 07ff443f77..e7d35f6141 100644 --- a/src/inventory/PlayerCursorInventory.php +++ b/src/inventory/PlayerCursorInventory.php @@ -35,7 +35,6 @@ class PlayerCursorInventory extends BaseInventory{ } /** - * This override is here for documentation and code completion purposes only. * @return Player */ public function getHolder(){ diff --git a/src/inventory/PlayerInventory.php b/src/inventory/PlayerInventory.php index 1ec534a29d..493d4d8a93 100644 --- a/src/inventory/PlayerInventory.php +++ b/src/inventory/PlayerInventory.php @@ -132,7 +132,6 @@ class PlayerInventory extends BaseInventory{ } /** - * This override is here for documentation and code completion purposes only. * @return Human|Player */ public function getHolder(){ From d355d5b5b50186998de645b5944028fcdd052a96 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 5 Aug 2019 19:01:21 +0100 Subject: [PATCH 1177/3224] Remove hack to break cyclic dependency on double chests Since these now reference positions instead of tiles, the cyclic dependency is removed. --- src/block/tile/Chest.php | 1 - src/inventory/DoubleChestInventory.php | 5 ----- 2 files changed, 6 deletions(-) diff --git a/src/block/tile/Chest.php b/src/block/tile/Chest.php index 6479c46285..fe77aa9791 100644 --- a/src/block/tile/Chest.php +++ b/src/block/tile/Chest.php @@ -101,7 +101,6 @@ class Chest extends Spawnable implements Container, Nameable{ if($this->doubleInventory !== null){ if($this->isPaired() and $this->world->isChunkLoaded($this->pairX >> 4, $this->pairZ >> 4)){ $this->doubleInventory->removeAllViewers(); - $this->doubleInventory->invalidate(); if(($pair = $this->getPair()) !== null){ $pair->doubleInventory = null; } diff --git a/src/inventory/DoubleChestInventory.php b/src/inventory/DoubleChestInventory.php index 451ddc7a7a..273e04c2a9 100644 --- a/src/inventory/DoubleChestInventory.php +++ b/src/inventory/DoubleChestInventory.php @@ -100,9 +100,4 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ public function getRightSide() : ChestInventory{ return $this->right; } - - public function invalidate(){ - $this->left = null; - $this->right = null; - } } From 4e5b296c8c59bc36706098ce519344072b04ea0d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 5 Aug 2019 19:33:34 +0100 Subject: [PATCH 1178/3224] Tiles now encapsulate positions instead of extending them --- src/block/EnderChest.php | 2 +- src/block/tile/BrewingStand.php | 4 ++-- src/block/tile/Chest.php | 22 +++++++++++----------- src/block/tile/ContainerTrait.php | 4 ++-- src/block/tile/Furnace.php | 10 +++++----- src/block/tile/Hopper.php | 2 +- src/block/tile/Spawnable.php | 6 +++--- src/block/tile/Tile.php | 27 ++++++++++++++++++--------- src/world/World.php | 20 +++++++++++--------- src/world/format/Chunk.php | 6 ++++-- 10 files changed, 58 insertions(+), 45 deletions(-) diff --git a/src/block/EnderChest.php b/src/block/EnderChest.php index 40ae928a08..0dad1888f5 100644 --- a/src/block/EnderChest.php +++ b/src/block/EnderChest.php @@ -74,7 +74,7 @@ class EnderChest extends Transparent{ if($player instanceof Player){ $enderChest = $this->pos->getWorld()->getTile($this->pos); if($enderChest instanceof TileEnderChest and $this->getSide(Facing::UP)->isTransparent()){ - $player->getEnderChestInventory()->setHolderPosition($enderChest); + $player->getEnderChestInventory()->setHolderPosition($this->pos); $player->setCurrentWindow($player->getEnderChestInventory()); } } diff --git a/src/block/tile/BrewingStand.php b/src/block/tile/BrewingStand.php index 21663d69cf..535a4180e5 100644 --- a/src/block/tile/BrewingStand.php +++ b/src/block/tile/BrewingStand.php @@ -54,9 +54,9 @@ class BrewingStand extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); - $this->inventory = new BrewingStandInventory($this); + $this->inventory = new BrewingStandInventory($this->pos); $this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange(function(Inventory $unused){ - $this->world->scheduleDelayedBlockUpdate($this->getBlock()->getPos(), 1); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 1); })); } diff --git a/src/block/tile/Chest.php b/src/block/tile/Chest.php index fe77aa9791..f05f189e71 100644 --- a/src/block/tile/Chest.php +++ b/src/block/tile/Chest.php @@ -55,7 +55,7 @@ class Chest extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); - $this->inventory = new ChestInventory($this); + $this->inventory = new ChestInventory($this->pos); } public function readSaveData(CompoundTag $nbt) : void{ @@ -63,8 +63,8 @@ class Chest extends Spawnable implements Container, Nameable{ $pairX = $nbt->getInt(self::TAG_PAIRX); $pairZ = $nbt->getInt(self::TAG_PAIRZ); if( - ($this->x === $pairX and abs($this->z - $pairZ) === 1) or - ($this->z === $pairZ and abs($this->x - $pairX) === 1) + ($this->pos->x === $pairX and abs($this->pos->z - $pairZ) === 1) or + ($this->pos->z === $pairZ and abs($this->pos->x - $pairX) === 1) ){ $this->pairX = $pairX; $this->pairZ = $pairZ; @@ -99,7 +99,7 @@ class Chest extends Spawnable implements Container, Nameable{ $this->inventory->removeAllViewers(); if($this->doubleInventory !== null){ - if($this->isPaired() and $this->world->isChunkLoaded($this->pairX >> 4, $this->pairZ >> 4)){ + if($this->isPaired() and $this->pos->getWorld()->isChunkLoaded($this->pairX >> 4, $this->pairZ >> 4)){ $this->doubleInventory->removeAllViewers(); if(($pair = $this->getPair()) !== null){ $pair->doubleInventory = null; @@ -137,7 +137,7 @@ class Chest extends Spawnable implements Container, Nameable{ } protected function checkPairing(){ - if($this->isPaired() and !$this->getWorld()->isInLoadedTerrain(new Vector3($this->pairX, $this->y, $this->pairZ))){ + if($this->isPaired() and !$this->pos->getWorld()->isInLoadedTerrain(new Vector3($this->pairX, $this->pos->y, $this->pairZ))){ //paired to a tile in an unloaded chunk $this->doubleInventory = null; @@ -150,7 +150,7 @@ class Chest extends Spawnable implements Container, Nameable{ if($pair->doubleInventory !== null){ $this->doubleInventory = $pair->doubleInventory; }else{ - if(($pair->x + ($pair->z << 15)) > ($this->x + ($this->z << 15))){ //Order them correctly + if(($pair->getPos()->x + ($pair->getPos()->z << 15)) > ($this->pos->x + ($this->pos->z << 15))){ //Order them correctly $this->doubleInventory = $pair->doubleInventory = new DoubleChestInventory($pair->inventory, $this->inventory); }else{ $this->doubleInventory = $pair->doubleInventory = new DoubleChestInventory($this->inventory, $pair->inventory); @@ -179,7 +179,7 @@ class Chest extends Spawnable implements Container, Nameable{ */ public function getPair() : ?Chest{ if($this->isPaired()){ - $tile = $this->getWorld()->getTileAt($this->pairX, $this->y, $this->pairZ); + $tile = $this->pos->getWorld()->getTileAt($this->pairX, $this->pos->y, $this->pairZ); if($tile instanceof Chest){ return $tile; } @@ -203,11 +203,11 @@ class Chest extends Spawnable implements Container, Nameable{ } private function createPair(Chest $tile){ - $this->pairX = $tile->x; - $this->pairZ = $tile->z; + $this->pairX = $tile->getPos()->x; + $this->pairZ = $tile->getPos()->z; - $tile->pairX = $this->x; - $tile->pairZ = $this->z; + $tile->pairX = $this->getPos()->x; + $tile->pairZ = $this->getPos()->z; } public function unpair(){ diff --git a/src/block/tile/ContainerTrait.php b/src/block/tile/ContainerTrait.php index 00652b5cb3..6217b2f70b 100644 --- a/src/block/tile/ContainerTrait.php +++ b/src/block/tile/ContainerTrait.php @@ -91,14 +91,14 @@ trait ContainerTrait{ * @see Position::asPosition() * @return Position */ - abstract protected function asPosition() : Position; + abstract protected function getPos() : Position; /** * @see Tile::onBlockDestroyedHook() */ protected function onBlockDestroyedHook() : void{ $inv = $this->getRealInventory(); - $pos = $this->asPosition(); + $pos = $this->getPos(); foreach($inv->getContents() as $k => $item){ $pos->world->dropItem($pos->add(0.5, 0.5, 0.5), $item); diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index 0cd82cfaa3..2dc9b4fb37 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -57,10 +57,10 @@ class Furnace extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); - $this->inventory = new FurnaceInventory($this); + $this->inventory = new FurnaceInventory($this->pos); $this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange( function(Inventory $unused) : void{ - $this->world->scheduleDelayedBlockUpdate($this->asVector3(), 1); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 1); }) ); } @@ -132,7 +132,7 @@ class Furnace extends Spawnable implements Container, Nameable{ $block = $this->getBlock(); if($block instanceof BlockFurnace and !$block->isLit()){ $block->setLit(true); - $this->getWorld()->setBlock($block->getPos(), $block); + $this->pos->getWorld()->setBlock($block->getPos(), $block); } if($this->remainingFuelTime > 0 and $ev->isBurning()){ @@ -158,7 +158,7 @@ class Furnace extends Spawnable implements Container, Nameable{ $fuel = $this->inventory->getFuel(); $raw = $this->inventory->getSmelting(); $product = $this->inventory->getResult(); - $smelt = $this->world->getServer()->getCraftingManager()->matchFurnaceRecipe($raw); + $smelt = $this->pos->getWorld()->getServer()->getCraftingManager()->matchFurnaceRecipe($raw); $canSmelt = ($smelt instanceof FurnaceRecipe and $raw->getCount() > 0 and (($smelt->getResult()->equals($product) and $product->getCount() < $product->getMaxStackSize()) or $product->isNull())); if($this->remainingFuelTime <= 0 and $canSmelt and $fuel->getFuelTime() > 0 and $fuel->getCount() > 0){ @@ -195,7 +195,7 @@ class Furnace extends Spawnable implements Container, Nameable{ $block = $this->getBlock(); if($block instanceof BlockFurnace and $block->isLit()){ $block->setLit(false); - $this->getWorld()->setBlock($block->getPos(), $block); + $this->pos->getWorld()->setBlock($block->getPos(), $block); } $this->remainingFuelTime = $this->cookTime = $this->maxFuelTime = 0; } diff --git a/src/block/tile/Hopper.php b/src/block/tile/Hopper.php index ee620b5c48..838cc2f345 100644 --- a/src/block/tile/Hopper.php +++ b/src/block/tile/Hopper.php @@ -43,7 +43,7 @@ class Hopper extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); - $this->inventory = new HopperInventory($this); + $this->inventory = new HopperInventory($this->pos); } public function readSaveData(CompoundTag $nbt) : void{ diff --git a/src/block/tile/Spawnable.php b/src/block/tile/Spawnable.php index 2e6e772a75..c0d911fbc3 100644 --- a/src/block/tile/Spawnable.php +++ b/src/block/tile/Spawnable.php @@ -80,9 +80,9 @@ abstract class Spawnable extends Tile{ final public function getSpawnCompound() : CompoundTag{ $nbt = CompoundTag::create() ->setString(self::TAG_ID, TileFactory::getSaveId(get_class($this))) //TODO: disassociate network ID from save ID - ->setInt(self::TAG_X, $this->x) - ->setInt(self::TAG_Y, $this->y) - ->setInt(self::TAG_Z, $this->z); + ->setInt(self::TAG_X, $this->pos->x) + ->setInt(self::TAG_Y, $this->pos->y) + ->setInt(self::TAG_Z, $this->pos->z); $this->addAdditionalSpawnData($nbt); return $nbt; } diff --git a/src/block/tile/Tile.php b/src/block/tile/Tile.php index 3eaeaaed49..734162544d 100644 --- a/src/block/tile/Tile.php +++ b/src/block/tile/Tile.php @@ -37,20 +37,22 @@ use pocketmine\world\Position; use pocketmine\world\World; use function get_class; -abstract class Tile extends Position{ +abstract class Tile{ public const TAG_ID = "id"; public const TAG_X = "x"; public const TAG_Y = "y"; public const TAG_Z = "z"; + /** @var Position */ + protected $pos; /** @var bool */ public $closed = false; /** @var TimingsHandler */ protected $timings; public function __construct(World $world, Vector3 $pos){ - parent::__construct($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ(), $world); + $this->pos = Position::fromObject($pos, $world); $this->timings = Timings::getTileEntityTimings($this); } @@ -72,9 +74,9 @@ abstract class Tile extends Position{ public function saveNBT() : CompoundTag{ $nbt = CompoundTag::create() ->setString(self::TAG_ID, TileFactory::getSaveId(get_class($this))) - ->setInt(self::TAG_X, $this->x) - ->setInt(self::TAG_Y, $this->y) - ->setInt(self::TAG_Z, $this->z); + ->setInt(self::TAG_X, $this->pos->getFloorX()) + ->setInt(self::TAG_Y, $this->pos->getFloorY()) + ->setInt(self::TAG_Z, $this->pos->getFloorZ()); $this->writeSaveData($nbt); return $nbt; @@ -102,7 +104,14 @@ abstract class Tile extends Position{ * @return Block */ public function getBlock() : Block{ - return $this->world->getBlockAt($this->x, $this->y, $this->z); + return $this->pos->getWorld()->getBlock($this->pos); + } + + /** + * @return Position + */ + public function getPos() : Position{ + return $this->pos; } public function isClosed() : bool{ @@ -132,9 +141,9 @@ abstract class Tile extends Position{ if(!$this->closed){ $this->closed = true; - if($this->isValid()){ - $this->world->removeTile($this); - $this->setWorld(null); + if($this->pos->isValid()){ + $this->pos->getWorld()->removeTile($this); + $this->pos->setWorld(null); } } } diff --git a/src/world/World.php b/src/world/World.php index fa4ee82575..bca106405a 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -901,7 +901,7 @@ class World implements ChunkManager{ $tile = $this->getTileAt($b->x, $b->y, $b->z); if($tile instanceof Spawnable){ - $packets[] = BlockActorDataPacket::create($tile->x, $tile->y, $tile->z, $tile->getSerializedSpawnCompound()); + $packets[] = BlockActorDataPacket::create($b->x, $b->y, $b->z, $tile->getSerializedSpawnCompound()); } } @@ -2348,12 +2348,13 @@ class World implements ChunkManager{ if($tile->isClosed()){ throw new \InvalidArgumentException("Attempted to add a garbage closed Tile to world"); } - if($tile->getWorld() !== $this){ + $pos = $tile->getPos(); + if($pos->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Tile world"); } - $chunkX = $tile->getFloorX() >> 4; - $chunkZ = $tile->getFloorZ() >> 4; + $chunkX = $pos->getFloorX() >> 4; + $chunkZ = $pos->getFloorZ() >> 4; if(isset($this->chunks[$hash = World::chunkHash($chunkX, $chunkZ)])){ $this->chunks[$hash]->addTile($tile); @@ -2362,7 +2363,7 @@ class World implements ChunkManager{ } //delegate tile ticking to the corresponding block - $this->scheduleDelayedBlockUpdate($tile->asVector3(), 1); + $this->scheduleDelayedBlockUpdate($pos->asVector3(), 1); } /** @@ -2371,18 +2372,19 @@ class World implements ChunkManager{ * @throws \InvalidArgumentException */ public function removeTile(Tile $tile){ - if($tile->getWorld() !== $this){ + $pos = $tile->getPos(); + if($pos->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Tile world"); } - $chunkX = $tile->getFloorX() >> 4; - $chunkZ = $tile->getFloorZ() >> 4; + $chunkX = $pos->getFloorX() >> 4; + $chunkZ = $pos->getFloorZ() >> 4; if(isset($this->chunks[$hash = World::chunkHash($chunkX, $chunkZ)])){ $this->chunks[$hash]->removeTile($tile); } foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){ - $listener->onBlockChanged($tile); + $listener->onBlockChanged($pos->asVector3()); } } diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index d083a61e25..138b4d0748 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -473,7 +473,8 @@ class Chunk{ throw new \InvalidArgumentException("Attempted to add a garbage closed Tile to a chunk"); } - if(isset($this->tiles[$index = Chunk::blockHash($tile->x, $tile->y, $tile->z)]) and $this->tiles[$index] !== $tile){ + $pos = $tile->getPos(); + if(isset($this->tiles[$index = Chunk::blockHash($pos->x, $pos->y, $pos->z)]) and $this->tiles[$index] !== $tile){ $this->tiles[$index]->close(); } $this->tiles[$index] = $tile; @@ -484,7 +485,8 @@ class Chunk{ * @param Tile $tile */ public function removeTile(Tile $tile) : void{ - unset($this->tiles[Chunk::blockHash($tile->x, $tile->y, $tile->z)]); + $pos = $tile->getPos(); + unset($this->tiles[Chunk::blockHash($pos->x, $pos->y, $pos->z)]); $this->hasChanged = true; } From 9671b4d5cbe8e10ca5920596f61f7abd9c16ad15 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 6 Aug 2019 10:07:16 +0100 Subject: [PATCH 1179/3224] fix improper cloning of some blocks, closes #3079 --- src/block/Banner.php | 1 + src/block/Sign.php | 1 + 2 files changed, 2 insertions(+) diff --git a/src/block/Banner.php b/src/block/Banner.php index 7f6f62b8a9..96151917df 100644 --- a/src/block/Banner.php +++ b/src/block/Banner.php @@ -66,6 +66,7 @@ class Banner extends Transparent{ } public function __clone(){ + parent::__clone(); $this->patterns = $this->patterns->map(Utils::cloneCallback()); } diff --git a/src/block/Sign.php b/src/block/Sign.php index d8a7094101..19a6ef29e5 100644 --- a/src/block/Sign.php +++ b/src/block/Sign.php @@ -60,6 +60,7 @@ class Sign extends Transparent{ } public function __clone(){ + parent::__clone(); $this->text = clone $this->text; } From dec6f73f2f9abc08c5b51133599a5d1edff2d0b2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 6 Aug 2019 10:18:02 +0100 Subject: [PATCH 1180/3224] Remove unnecessary BannerPattern copying on block clone --- src/block/Banner.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/block/Banner.php b/src/block/Banner.php index 96151917df..32728041ae 100644 --- a/src/block/Banner.php +++ b/src/block/Banner.php @@ -36,7 +36,6 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; -use pocketmine\utils\Utils; use pocketmine\world\BlockTransaction; use function assert; use function floor; @@ -67,7 +66,8 @@ class Banner extends Transparent{ public function __clone(){ parent::__clone(); - $this->patterns = $this->patterns->map(Utils::cloneCallback()); + //pattern objects are considered immutable, so they don't need to be copied + $this->patterns = $this->patterns->copy(); } public function getId() : int{ From 9598af76834216296659f0e9eea3a266d57f9ce8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 6 Aug 2019 15:42:01 +0100 Subject: [PATCH 1181/3224] commands: remove some nonsensical isValid() checks a player who doesn't have a valid world has no business sending commands anyway. --- src/command/defaults/SpawnpointCommand.php | 18 ++++++++---------- src/command/defaults/TeleportCommand.php | 4 +--- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/command/defaults/SpawnpointCommand.php b/src/command/defaults/SpawnpointCommand.php index a0f87ca618..071433b3b4 100644 --- a/src/command/defaults/SpawnpointCommand.php +++ b/src/command/defaults/SpawnpointCommand.php @@ -70,18 +70,16 @@ class SpawnpointCommand extends VanillaCommand{ } if(count($args) === 4){ - if($target->isValid()){ - $world = $target->getWorld(); - $pos = $sender instanceof Player ? $sender->getPosition() : $world->getSpawnLocation(); - $x = $this->getRelativeDouble($pos->x, $sender, $args[1]); - $y = $this->getRelativeDouble($pos->y, $sender, $args[2], 0, World::Y_MAX); - $z = $this->getRelativeDouble($pos->z, $sender, $args[3]); - $target->setSpawn(new Position($x, $y, $z, $world)); + $world = $target->getWorld(); + $pos = $sender instanceof Player ? $sender->getPosition() : $world->getSpawnLocation(); + $x = $this->getRelativeDouble($pos->x, $sender, $args[1]); + $y = $this->getRelativeDouble($pos->y, $sender, $args[2], 0, World::Y_MAX); + $z = $this->getRelativeDouble($pos->z, $sender, $args[3]); + $target->setSpawn(new Position($x, $y, $z, $world)); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.spawnpoint.success", [$target->getName(), round($x, 2), round($y, 2), round($z, 2)])); + Command::broadcastCommandMessage($sender, new TranslationContainer("commands.spawnpoint.success", [$target->getName(), round($x, 2), round($y, 2), round($z, 2)])); - return true; - } + return true; }elseif(count($args) <= 1){ if($sender instanceof Player){ $pos = new Position($sender->getFloorX(), $sender->getFloorY(), $sender->getFloorZ(), $sender->getWorld()); diff --git a/src/command/defaults/TeleportCommand.php b/src/command/defaults/TeleportCommand.php index 8170fbb6dd..512ce095da 100644 --- a/src/command/defaults/TeleportCommand.php +++ b/src/command/defaults/TeleportCommand.php @@ -101,7 +101,7 @@ class TeleportCommand extends VanillaCommand{ Command::broadcastCommandMessage($sender, new TranslationContainer("commands.tp.success", [$origin->getName(), $target->getName()])); return true; - }elseif($target->isValid()){ + }else{ if(count($args) === 4 or count($args) === 6){ $pos = 1; }else{ @@ -124,7 +124,5 @@ class TeleportCommand extends VanillaCommand{ return true; } - - throw new InvalidCommandSyntaxException(); } } From c533f6a0bdf1b382ffe1bb64ac73fdba717e209e Mon Sep 17 00:00:00 2001 From: Dylan T Date: Wed, 7 Aug 2019 17:39:36 +0100 Subject: [PATCH 1182/3224] Implemented partial chunk saving on LevelDB (#3078) --- src/world/SimpleChunkManager.php | 2 +- src/world/World.php | 8 ++-- src/world/format/Chunk.php | 56 +++++++++++++++++------- src/world/format/io/FormatConverter.php | 1 + src/world/format/io/leveldb/LevelDB.php | 58 ++++++++++++++----------- src/world/generator/PopulationTask.php | 2 +- 6 files changed, 79 insertions(+), 48 deletions(-) diff --git a/src/world/SimpleChunkManager.php b/src/world/SimpleChunkManager.php index 6baaa51669..928f033ba3 100644 --- a/src/world/SimpleChunkManager.php +++ b/src/world/SimpleChunkManager.php @@ -61,7 +61,7 @@ class SimpleChunkManager implements ChunkManager{ public function setBlockAt(int $x, int $y, int $z, Block $block) : void{ if($this->terrainPointer->moveTo($x, $y, $z, true)){ $this->terrainPointer->currentSubChunk->setFullBlock($x & 0xf, $y & 0xf, $z & 0xf, $block->getFullId()); - $this->terrainPointer->currentChunk->setChanged(true); + $this->terrainPointer->currentChunk->setDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN, true); }else{ throw new \InvalidArgumentException("Cannot set block at coordinates x=$x,y=$y,z=$z, terrain is not loaded or out of bounds"); } diff --git a/src/world/World.php b/src/world/World.php index bca106405a..3851d52bb2 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1038,9 +1038,9 @@ class World implements ChunkManager{ $this->timings->syncChunkSaveTimer->startTiming(); try{ foreach($this->chunks as $chunk){ - if($chunk->hasChanged() and $chunk->isGenerated()){ + if($chunk->isDirty() and $chunk->isGenerated()){ $this->provider->saveChunk($chunk); - $chunk->setChanged(false); + $chunk->clearDirtyFlags(); } } }finally{ @@ -2213,7 +2213,7 @@ class World implements ChunkManager{ unset($this->blockCache[$chunkHash]); unset($this->changedBlocks[$chunkHash]); - $chunk->setChanged(); + $chunk->setDirty(); if(!$this->isChunkInUse($chunkX, $chunkZ)){ $this->unloadChunkRequest($chunkX, $chunkZ); @@ -2505,7 +2505,7 @@ class World implements ChunkManager{ return false; } - if($trySave and $this->getAutoSave() and $chunk->isGenerated() and $chunk->hasChanged()){ + if($trySave and $this->getAutoSave() and $chunk->isGenerated() and $chunk->isDirty()){ $this->timings->syncChunkSaveTimer->startTiming(); try{ $this->provider->saveChunk($chunk); diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 138b4d0748..d9b8d1996c 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -46,6 +46,10 @@ use function str_repeat; use function strlen; class Chunk{ + public const DIRTY_FLAG_TERRAIN = 1 << 0; + public const DIRTY_FLAG_ENTITIES = 1 << 1; + public const DIRTY_FLAG_TILES = 1 << 2; + public const DIRTY_FLAG_BIOMES = 1 << 3; public const MAX_SUBCHUNKS = 16; @@ -54,8 +58,8 @@ class Chunk{ /** @var int */ protected $z; - /** @var bool */ - protected $hasChanged = false; + /** @var int */ + private $dirtyFlags = 0; /** @var bool */ protected $lightPopulated = false; @@ -189,7 +193,7 @@ class Chunk{ */ public function setFullBlock(int $x, int $y, int $z, int $block) : void{ $this->getSubChunk($y >> 4, true)->setFullBlock($x, $y & 0xf, $z, $block); - $this->hasChanged = true; + $this->dirtyFlags |= self::DIRTY_FLAG_TERRAIN; } /** @@ -396,8 +400,8 @@ class Chunk{ * @param int $biomeId 0-255 */ public function setBiomeId(int $x, int $z, int $biomeId) : void{ - $this->hasChanged = true; $this->biomeIds[($z << 4) | $x] = chr($biomeId & 0xff); + $this->dirtyFlags |= self::DIRTY_FLAG_BIOMES; } /** @@ -451,7 +455,7 @@ class Chunk{ } $this->entities[$entity->getId()] = $entity; if(!($entity instanceof Player)){ - $this->hasChanged = true; + $this->dirtyFlags |= self::DIRTY_FLAG_ENTITIES; } } @@ -461,7 +465,7 @@ class Chunk{ public function removeEntity(Entity $entity) : void{ unset($this->entities[$entity->getId()]); if(!($entity instanceof Player)){ - $this->hasChanged = true; + $this->dirtyFlags |= self::DIRTY_FLAG_ENTITIES; } } @@ -478,7 +482,7 @@ class Chunk{ $this->tiles[$index]->close(); } $this->tiles[$index] = $tile; - $this->hasChanged = true; + $this->dirtyFlags |= self::DIRTY_FLAG_TILES; } /** @@ -487,7 +491,7 @@ class Chunk{ public function removeTile(Tile $tile) : void{ $pos = $tile->getPos(); unset($this->tiles[Chunk::blockHash($pos->x, $pos->y, $pos->z)]); - $this->hasChanged = true; + $this->dirtyFlags |= self::DIRTY_FLAG_TILES; } /** @@ -563,7 +567,7 @@ class Chunk{ */ public function initChunk(World $world) : void{ if($this->NBTentities !== null){ - $this->hasChanged = true; + $this->dirtyFlags |= self::DIRTY_FLAG_ENTITIES; $world->timings->syncChunkLoadEntitiesTimer->startTiming(); foreach($this->NBTentities as $nbt){ if($nbt instanceof CompoundTag){ @@ -584,7 +588,7 @@ class Chunk{ $world->timings->syncChunkLoadEntitiesTimer->stopTiming(); } if($this->NBTtiles !== null){ - $this->hasChanged = true; + $this->dirtyFlags |= self::DIRTY_FLAG_TILES; $world->timings->syncChunkLoadTileEntitiesTimer->startTiming(); foreach($this->NBTtiles as $nbt){ if($nbt instanceof CompoundTag){ @@ -619,15 +623,35 @@ class Chunk{ /** * @return bool */ - public function hasChanged() : bool{ - return $this->hasChanged or !empty($this->tiles) or !empty($this->getSavableEntities()); + public function isDirty() : bool{ + return $this->dirtyFlags !== 0 or !empty($this->tiles) or !empty($this->getSavableEntities()); + } + + public function getDirtyFlag(int $flag) : bool{ + return ($this->dirtyFlags & $flag) !== 0; } /** - * @param bool $value + * @return int */ - public function setChanged(bool $value = true) : void{ - $this->hasChanged = $value; + public function getDirtyFlags() : int{ + return $this->dirtyFlags; + } + + public function setDirtyFlag(int $flag, bool $value) : void{ + if($value){ + $this->dirtyFlags |= $flag; + }else{ + $this->dirtyFlags &= ~$flag; + } + } + + public function setDirty() : void{ + $this->dirtyFlags = ~0; + } + + public function clearDirtyFlags() : void{ + $this->dirtyFlags = 0; } /** @@ -666,7 +690,7 @@ class Chunk{ }else{ $this->subChunks[$y] = $subChunk; } - $this->hasChanged = true; + $this->setDirtyFlag(self::DIRTY_FLAG_TERRAIN, true); return true; } diff --git a/src/world/format/io/FormatConverter.php b/src/world/format/io/FormatConverter.php index ec3b4f8dd0..70bceab366 100644 --- a/src/world/format/io/FormatConverter.php +++ b/src/world/format/io/FormatConverter.php @@ -135,6 +135,7 @@ class FormatConverter{ $thisRound = $start; static $reportInterval = 256; foreach($this->oldProvider->getAllChunks(true, $this->logger) as $chunk){ + $chunk->setDirty(); $new->saveChunk($chunk); $counter++; if(($counter % $reportInterval) === 0){ diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index c3ffe5bf8a..3e61de8a0d 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -416,7 +416,9 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $chunk->setGenerated(); $chunk->setPopulated(); - $chunk->setChanged($hasBeenUpgraded); //trigger rewriting chunk to disk if it was converted from an older format + if($hasBeenUpgraded){ + $chunk->setDirty(); //trigger rewriting chunk to disk if it was converted from an older format + } return $chunk; } @@ -431,39 +433,43 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $write = new \LevelDBWriteBatch(); $write->put($index . self::TAG_VERSION, chr(self::CURRENT_LEVEL_CHUNK_VERSION)); - $subChunks = $chunk->getSubChunks(); - foreach($subChunks as $y => $subChunk){ - $key = $index . self::TAG_SUBCHUNK_PREFIX . chr($y); - if($subChunk->isEmpty(false)){ //MCPE doesn't save light anymore as of 1.1 - $write->delete($key); - }else{ - $subStream = new BinaryStream(); - $subStream->putByte(self::CURRENT_LEVEL_SUBCHUNK_VERSION); + if($chunk->getDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN)){ + $subChunks = $chunk->getSubChunks(); + foreach($subChunks as $y => $subChunk){ + $key = $index . self::TAG_SUBCHUNK_PREFIX . chr($y); + if($subChunk->isEmpty(false)){ //MCPE doesn't save light anymore as of 1.1 + $write->delete($key); + }else{ + $subStream = new BinaryStream(); + $subStream->putByte(self::CURRENT_LEVEL_SUBCHUNK_VERSION); - $layers = $subChunk->getBlockLayers(); - $subStream->putByte(count($layers)); - foreach($layers as $blocks){ - $subStream->putByte($blocks->getBitsPerBlock() << 1); - $subStream->put($blocks->getWordArray()); + $layers = $subChunk->getBlockLayers(); + $subStream->putByte(count($layers)); + foreach($layers as $blocks){ + $subStream->putByte($blocks->getBitsPerBlock() << 1); + $subStream->put($blocks->getWordArray()); - $palette = $blocks->getPalette(); - $subStream->putLInt(count($palette)); - $tags = []; - foreach($palette as $p){ - $tags[] = new TreeRoot(CompoundTag::create() - ->setString("name", $idMap[$p >> 4] ?? "minecraft:info_update") - ->setInt("oldid", $p >> 4) //PM only (debugging), vanilla doesn't have this - ->setShort("val", $p & 0xf)); + $palette = $blocks->getPalette(); + $subStream->putLInt(count($palette)); + $tags = []; + foreach($palette as $p){ + $tags[] = new TreeRoot(CompoundTag::create() + ->setString("name", $idMap[$p >> 4] ?? "minecraft:info_update") + ->setInt("oldid", $p >> 4) //PM only (debugging), vanilla doesn't have this + ->setShort("val", $p & 0xf)); + } + + $subStream->put((new LittleEndianNbtSerializer())->writeMultiple($tags)); } - $subStream->put((new LittleEndianNbtSerializer())->writeMultiple($tags)); + $write->put($key, $subStream->getBuffer()); } - - $write->put($key, $subStream->getBuffer()); } } - $write->put($index . self::TAG_DATA_2D, str_repeat("\x00", 512) . $chunk->getBiomeIdArray()); + if($chunk->getDirtyFlag(Chunk::DIRTY_FLAG_BIOMES)){ + $write->put($index . self::TAG_DATA_2D, str_repeat("\x00", 512) . $chunk->getBiomeIdArray()); + } //TODO: use this properly $write->put($index . self::TAG_STATE_FINALISATION, chr(self::FINALISATION_DONE)); diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 76b715e84f..3ba868254f 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -118,7 +118,7 @@ class PopulationTask extends AsyncTask{ foreach($chunks as $i => $c){ if($c !== null){ $c = $chunks[$i] = $manager->getChunk($c->getX(), $c->getZ()); - if(!$c->hasChanged()){ + if(!$c->isDirty()){ $chunks[$i] = null; } }else{ From bce126b6d048bb335d7694010e11e2f23c38d835 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 7 Aug 2019 19:51:31 +0100 Subject: [PATCH 1183/3224] fix BB of daylight sensor --- src/block/DaylightSensor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/DaylightSensor.php b/src/block/DaylightSensor.php index 36af835a94..271aa8016c 100644 --- a/src/block/DaylightSensor.php +++ b/src/block/DaylightSensor.php @@ -84,7 +84,7 @@ class DaylightSensor extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one()->trim(Facing::UP, 0.5); + return AxisAlignedBB::one()->trim(Facing::UP, 10 / 16); } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ From a52e4f03928dab740bc1016493067899d43dd600 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 8 Aug 2019 18:48:58 +0100 Subject: [PATCH 1184/3224] AsyncPool: Return whether there are tasks left to be collected from collectTasks() this allows a while($pool->collectTasks()); style code. --- src/scheduler/AsyncPool.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/scheduler/AsyncPool.php b/src/scheduler/AsyncPool.php index 838a49dc91..403703d419 100644 --- a/src/scheduler/AsyncPool.php +++ b/src/scheduler/AsyncPool.php @@ -225,8 +225,10 @@ class AsyncPool{ * Collects finished and/or crashed tasks from the workers, firing their on-completion hooks where appropriate. * * @throws \ReflectionException + * @return bool whether there are tasks left to be collected */ - public function collectTasks() : void{ + public function collectTasks() : bool{ + $more = false; foreach($this->taskQueues as $worker => $queue){ $doGC = false; while(!$queue->isEmpty()){ @@ -254,6 +256,7 @@ class AsyncPool{ $task->onCompletion(); } }else{ + $more = true; break; //current task is still running, skip to next worker } } @@ -261,6 +264,7 @@ class AsyncPool{ $this->workers[$worker]->collect(); } } + return $more; } public function shutdownUnusedWorkers() : int{ From d87b6f9ff76ed0d3052770a35a204eecdc5512e6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 8 Aug 2019 19:36:54 +0100 Subject: [PATCH 1185/3224] Remove resource pack packets dependency on ResourcePack, now supports decoding --- .../handler/ResourcePacksPacketHandler.php | 14 +- .../mcpe/protocol/ResourcePackStackPacket.php | 30 ++--- .../mcpe/protocol/ResourcePacksInfoPacket.php | 46 ++----- .../protocol/types/ResourcePackInfoEntry.php | 125 ++++++++++++++++++ .../types/ResourcePackStackEntry.php} | 47 +++++-- 5 files changed, 197 insertions(+), 65 deletions(-) create mode 100644 src/network/mcpe/protocol/types/ResourcePackInfoEntry.php rename src/{resourcepacks/ResourcePackInfoEntry.php => network/mcpe/protocol/types/ResourcePackStackEntry.php} (51%) diff --git a/src/network/mcpe/handler/ResourcePacksPacketHandler.php b/src/network/mcpe/handler/ResourcePacksPacketHandler.php index a6b3bd9ae9..5fe682fc0e 100644 --- a/src/network/mcpe/handler/ResourcePacksPacketHandler.php +++ b/src/network/mcpe/handler/ResourcePacksPacketHandler.php @@ -30,8 +30,11 @@ use pocketmine\network\mcpe\protocol\ResourcePackClientResponsePacket; use pocketmine\network\mcpe\protocol\ResourcePackDataInfoPacket; use pocketmine\network\mcpe\protocol\ResourcePacksInfoPacket; use pocketmine\network\mcpe\protocol\ResourcePackStackPacket; +use pocketmine\network\mcpe\protocol\types\ResourcePackInfoEntry; +use pocketmine\network\mcpe\protocol\types\ResourcePackStackEntry; use pocketmine\resourcepacks\ResourcePack; use pocketmine\resourcepacks\ResourcePackManager; +use function array_map; use function ceil; use function count; use function implode; @@ -60,7 +63,11 @@ class ResourcePacksPacketHandler extends PacketHandler{ } public function setUp() : void{ - $this->session->sendDataPacket(ResourcePacksInfoPacket::create($this->resourcePackManager->getResourceStack(), [], $this->resourcePackManager->resourcePacksRequired(), false)); + $resourcePackEntries = array_map(static function(ResourcePack $pack){ + //TODO: more stuff + return new ResourcePackInfoEntry($pack->getPackId(), $pack->getPackVersion(), $pack->getPackSize(), "", "", "", false); + }, $this->resourcePackManager->getResourceStack()); + $this->session->sendDataPacket(ResourcePacksInfoPacket::create($resourcePackEntries, [], $this->resourcePackManager->resourcePacksRequired(), false)); $this->session->getLogger()->debug("Waiting for client to accept resource packs"); } @@ -102,7 +109,10 @@ class ResourcePacksPacketHandler extends PacketHandler{ break; case ResourcePackClientResponsePacket::STATUS_HAVE_ALL_PACKS: - $this->session->sendDataPacket(ResourcePackStackPacket::create($this->resourcePackManager->getResourceStack(), [], $this->resourcePackManager->resourcePacksRequired(), false)); + $stack = array_map(static function(ResourcePack $pack){ + return new ResourcePackStackEntry($pack->getPackId(), $pack->getPackVersion(), ""); //TODO: subpacks + }, $this->resourcePackManager->getResourceStack()); + $this->session->sendDataPacket(ResourcePackStackPacket::create($stack, [], $this->resourcePackManager->resourcePacksRequired(), false)); $this->session->getLogger()->debug("Applying resource pack stack"); break; case ResourcePackClientResponsePacket::STATUS_COMPLETED: diff --git a/src/network/mcpe/protocol/ResourcePackStackPacket.php b/src/network/mcpe/protocol/ResourcePackStackPacket.php index ec8e604ea0..958bdc75f5 100644 --- a/src/network/mcpe/protocol/ResourcePackStackPacket.php +++ b/src/network/mcpe/protocol/ResourcePackStackPacket.php @@ -28,7 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; -use pocketmine\resourcepacks\ResourcePack; +use pocketmine\network\mcpe\protocol\types\ResourcePackStackEntry; use function count; class ResourcePackStackPacket extends DataPacket implements ClientboundPacket{ @@ -37,19 +37,19 @@ class ResourcePackStackPacket extends DataPacket implements ClientboundPacket{ /** @var bool */ public $mustAccept = false; - /** @var ResourcePack[] */ + /** @var ResourcePackStackEntry[] */ public $behaviorPackStack = []; - /** @var ResourcePack[] */ + /** @var ResourcePackStackEntry[] */ public $resourcePackStack = []; /** @var bool */ public $isExperimental = false; /** - * @param ResourcePack[] $resourcePacks - * @param ResourcePack[] $behaviorPacks - * @param bool $mustAccept - * @param bool $isExperimental + * @param ResourcePackStackEntry[] $resourcePacks + * @param ResourcePackStackEntry[] $behaviorPacks + * @param bool $mustAccept + * @param bool $isExperimental * * @return ResourcePackStackPacket */ @@ -66,16 +66,12 @@ class ResourcePackStackPacket extends DataPacket implements ClientboundPacket{ $this->mustAccept = $this->getBool(); $behaviorPackCount = $this->getUnsignedVarInt(); while($behaviorPackCount-- > 0){ - $this->getString(); - $this->getString(); - $this->getString(); + $this->behaviorPackStack[] = ResourcePackStackEntry::read($this); } $resourcePackCount = $this->getUnsignedVarInt(); while($resourcePackCount-- > 0){ - $this->getString(); - $this->getString(); - $this->getString(); + $this->resourcePackStack[] = ResourcePackStackEntry::read($this); } $this->isExperimental = $this->getBool(); @@ -86,16 +82,12 @@ class ResourcePackStackPacket extends DataPacket implements ClientboundPacket{ $this->putUnsignedVarInt(count($this->behaviorPackStack)); foreach($this->behaviorPackStack as $entry){ - $this->putString($entry->getPackId()); - $this->putString($entry->getPackVersion()); - $this->putString(""); //TODO: subpack name + $entry->write($this); } $this->putUnsignedVarInt(count($this->resourcePackStack)); foreach($this->resourcePackStack as $entry){ - $this->putString($entry->getPackId()); - $this->putString($entry->getPackVersion()); - $this->putString(""); //TODO: subpack name + $entry->write($this); } $this->putBool($this->isExperimental); diff --git a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php index 5da110a683..6724d0b897 100644 --- a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php +++ b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; -use pocketmine\resourcepacks\ResourcePack; +use pocketmine\network\mcpe\protocol\types\ResourcePackInfoEntry; use function count; class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ @@ -37,16 +37,16 @@ class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ public $mustAccept = false; //if true, forces client to use selected resource packs /** @var bool */ public $hasScripts = false; //if true, causes disconnect for any platform that doesn't support scripts yet - /** @var ResourcePack[] */ + /** @var ResourcePackInfoEntry[] */ public $behaviorPackEntries = []; - /** @var ResourcePack[] */ + /** @var ResourcePackInfoEntry[] */ public $resourcePackEntries = []; /** - * @param ResourcePack[] $resourcePacks - * @param ResourcePack[] $behaviorPacks - * @param bool $mustAccept - * @param bool $hasScripts + * @param ResourcePackInfoEntry[] $resourcePacks + * @param ResourcePackInfoEntry[] $behaviorPacks + * @param bool $mustAccept + * @param bool $hasScripts * * @return ResourcePacksInfoPacket */ @@ -64,24 +64,12 @@ class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ $this->hasScripts = $this->getBool(); $behaviorPackCount = $this->getLShort(); while($behaviorPackCount-- > 0){ - $this->getString(); - $this->getString(); - $this->getLLong(); - $this->getString(); - $this->getString(); - $this->getString(); - $this->getBool(); + $this->behaviorPackEntries[] = ResourcePackInfoEntry::read($this); } $resourcePackCount = $this->getLShort(); while($resourcePackCount-- > 0){ - $this->getString(); - $this->getString(); - $this->getLLong(); - $this->getString(); - $this->getString(); - $this->getString(); - $this->getBool(); + $this->resourcePackEntries[] = ResourcePackInfoEntry::read($this); } } @@ -90,23 +78,11 @@ class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ $this->putBool($this->hasScripts); $this->putLShort(count($this->behaviorPackEntries)); foreach($this->behaviorPackEntries as $entry){ - $this->putString($entry->getPackId()); - $this->putString($entry->getPackVersion()); - $this->putLLong($entry->getPackSize()); - $this->putString(""); //TODO: encryption key - $this->putString(""); //TODO: subpack name - $this->putString(""); //TODO: content identity - $this->putBool(false); //TODO: has scripts (?) + $entry->write($this); } $this->putLShort(count($this->resourcePackEntries)); foreach($this->resourcePackEntries as $entry){ - $this->putString($entry->getPackId()); - $this->putString($entry->getPackVersion()); - $this->putLLong($entry->getPackSize()); - $this->putString(""); //TODO: encryption key - $this->putString(""); //TODO: subpack name - $this->putString(""); //TODO: content identity - $this->putBool(false); //TODO: seems useless for resource packs + $entry->write($this); } } diff --git a/src/network/mcpe/protocol/types/ResourcePackInfoEntry.php b/src/network/mcpe/protocol/types/ResourcePackInfoEntry.php new file mode 100644 index 0000000000..f091b651f5 --- /dev/null +++ b/src/network/mcpe/protocol/types/ResourcePackInfoEntry.php @@ -0,0 +1,125 @@ +packId = $packId; + $this->version = $version; + $this->sizeBytes = $sizeBytes; + $this->encryptionKey = $encryptionKey; + $this->subPackName = $subPackName; + $this->contentId = $contentId; + $this->hasScripts = $hasScripts; + } + + /** + * @return string + */ + public function getPackId() : string{ + return $this->packId; + } + + /** + * @return string + */ + public function getVersion() : string{ + return $this->version; + } + + /** + * @return int + */ + public function getSizeBytes() : int{ + return $this->sizeBytes; + } + + /** + * @return string + */ + public function getEncryptionKey() : string{ + return $this->encryptionKey; + } + + /** + * @return string + */ + public function getSubPackName() : string{ + return $this->subPackName; + } + + /** + * @return string + */ + public function getContentId() : string{ + return $this->contentId; + } + + /** + * @return bool + */ + public function hasScripts() : bool{ + return $this->hasScripts; + } + + public function write(NetworkBinaryStream $out) : void{ + $out->putString($this->packId); + $out->putString($this->version); + $out->putLLong($this->sizeBytes); + $out->putString($this->encryptionKey ?? ""); + $out->putString($this->subPackName ?? ""); + $out->putString($this->contentId ?? ""); + $out->putBool($this->hasScripts); + } + + public static function read(NetworkBinaryStream $in) : self{ + return new self( + $uuid = $in->getString(), + $version = $in->getString(), + $sizeBytes = $in->getLLong(), + $encryptionKey = $in->getString(), + $subPackName = $in->getString(), + $contentId = $in->getString(), + $hasScripts = $in->getBool() + ); + } +} diff --git a/src/resourcepacks/ResourcePackInfoEntry.php b/src/network/mcpe/protocol/types/ResourcePackStackEntry.php similarity index 51% rename from src/resourcepacks/ResourcePackInfoEntry.php rename to src/network/mcpe/protocol/types/ResourcePackStackEntry.php index 3b6e7a3e97..689a698c13 100644 --- a/src/resourcepacks/ResourcePackInfoEntry.php +++ b/src/network/mcpe/protocol/types/ResourcePackStackEntry.php @@ -21,28 +21,57 @@ declare(strict_types=1); -namespace pocketmine\resourcepacks; +namespace pocketmine\network\mcpe\protocol\types; -class ResourcePackInfoEntry{ - protected $packId; //UUID - protected $version; - protected $packSize; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; - public function __construct(string $packId, string $version, int $packSize = 0){ +class ResourcePackStackEntry{ + + /** @var string */ + private $packId; + /** @var string */ + private $version; + /** @var string */ + private $subPackName; + + public function __construct(string $packId, string $version, string $subPackName){ $this->packId = $packId; $this->version = $version; - $this->packSize = $packSize; + $this->subPackName = $subPackName; } + /** + * @return string + */ public function getPackId() : string{ return $this->packId; } + /** + * @return string + */ public function getVersion() : string{ return $this->version; } - public function getPackSize() : int{ - return $this->packSize; + /** + * @return string + */ + public function getSubPackName() : string{ + return $this->subPackName; + } + + public function write(NetworkBinaryStream $out) : void{ + $out->putString($this->packId); + $out->putString($this->version); + $out->putString($this->subPackName); + } + + public static function read(NetworkBinaryStream $in) : self{ + return new self( + $packId = $in->getString(), + $version = $in->getString(), + $subPackName = $in->getString() + ); } } From fae6289eb845cfc486b301488b97fbacc3c220c1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 8 Aug 2019 19:58:24 +0100 Subject: [PATCH 1186/3224] protocol: move resource-pack related types to their own subnamespace --- src/network/mcpe/handler/ResourcePacksPacketHandler.php | 4 ++-- src/network/mcpe/protocol/ResourcePackDataInfoPacket.php | 2 +- src/network/mcpe/protocol/ResourcePackStackPacket.php | 2 +- src/network/mcpe/protocol/ResourcePacksInfoPacket.php | 2 +- .../types/{ => resourcepacks}/ResourcePackInfoEntry.php | 2 +- .../types/{ => resourcepacks}/ResourcePackStackEntry.php | 2 +- .../protocol/types/{ => resourcepacks}/ResourcePackType.php | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) rename src/network/mcpe/protocol/types/{ => resourcepacks}/ResourcePackInfoEntry.php (97%) rename src/network/mcpe/protocol/types/{ => resourcepacks}/ResourcePackStackEntry.php (96%) rename src/network/mcpe/protocol/types/{ => resourcepacks}/ResourcePackType.php (93%) diff --git a/src/network/mcpe/handler/ResourcePacksPacketHandler.php b/src/network/mcpe/handler/ResourcePacksPacketHandler.php index 5fe682fc0e..91e389e025 100644 --- a/src/network/mcpe/handler/ResourcePacksPacketHandler.php +++ b/src/network/mcpe/handler/ResourcePacksPacketHandler.php @@ -30,8 +30,8 @@ use pocketmine\network\mcpe\protocol\ResourcePackClientResponsePacket; use pocketmine\network\mcpe\protocol\ResourcePackDataInfoPacket; use pocketmine\network\mcpe\protocol\ResourcePacksInfoPacket; use pocketmine\network\mcpe\protocol\ResourcePackStackPacket; -use pocketmine\network\mcpe\protocol\types\ResourcePackInfoEntry; -use pocketmine\network\mcpe\protocol\types\ResourcePackStackEntry; +use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackInfoEntry; +use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackStackEntry; use pocketmine\resourcepacks\ResourcePack; use pocketmine\resourcepacks\ResourcePackManager; use function array_map; diff --git a/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php b/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php index a9e824d47f..c0bc3ad8eb 100644 --- a/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php +++ b/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php @@ -28,7 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; -use pocketmine\network\mcpe\protocol\types\ResourcePackType; +use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackType; class ResourcePackDataInfoPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_DATA_INFO_PACKET; diff --git a/src/network/mcpe/protocol/ResourcePackStackPacket.php b/src/network/mcpe/protocol/ResourcePackStackPacket.php index 958bdc75f5..ec8fd2081f 100644 --- a/src/network/mcpe/protocol/ResourcePackStackPacket.php +++ b/src/network/mcpe/protocol/ResourcePackStackPacket.php @@ -28,7 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; -use pocketmine\network\mcpe\protocol\types\ResourcePackStackEntry; +use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackStackEntry; use function count; class ResourcePackStackPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php index 6724d0b897..16113b7d71 100644 --- a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php +++ b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; -use pocketmine\network\mcpe\protocol\types\ResourcePackInfoEntry; +use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackInfoEntry; use function count; class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/types/ResourcePackInfoEntry.php b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php similarity index 97% rename from src/network/mcpe/protocol/types/ResourcePackInfoEntry.php rename to src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php index f091b651f5..e8331fbd3d 100644 --- a/src/network/mcpe/protocol/types/ResourcePackInfoEntry.php +++ b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\resourcepacks; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; diff --git a/src/network/mcpe/protocol/types/ResourcePackStackEntry.php b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php similarity index 96% rename from src/network/mcpe/protocol/types/ResourcePackStackEntry.php rename to src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php index 689a698c13..843a87ce53 100644 --- a/src/network/mcpe/protocol/types/ResourcePackStackEntry.php +++ b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\resourcepacks; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; diff --git a/src/network/mcpe/protocol/types/ResourcePackType.php b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackType.php similarity index 93% rename from src/network/mcpe/protocol/types/ResourcePackType.php rename to src/network/mcpe/protocol/types/resourcepacks/ResourcePackType.php index 9efaced081..69556de60f 100644 --- a/src/network/mcpe/protocol/types/ResourcePackType.php +++ b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackType.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\resourcepacks; final class ResourcePackType{ From 774e6fe8a3cc509c987aaa394a3959aa19347e1d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 10 Aug 2019 17:38:00 +0100 Subject: [PATCH 1187/3224] Make chemistry textures always enabled --- src/network/mcpe/handler/ResourcePacksPacketHandler.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/network/mcpe/handler/ResourcePacksPacketHandler.php b/src/network/mcpe/handler/ResourcePacksPacketHandler.php index 91e389e025..cbcaa45612 100644 --- a/src/network/mcpe/handler/ResourcePacksPacketHandler.php +++ b/src/network/mcpe/handler/ResourcePacksPacketHandler.php @@ -35,6 +35,7 @@ use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackStackEntry; use pocketmine\resourcepacks\ResourcePack; use pocketmine\resourcepacks\ResourcePackManager; use function array_map; +use function array_unshift; use function ceil; use function count; use function implode; @@ -112,6 +113,10 @@ class ResourcePacksPacketHandler extends PacketHandler{ $stack = array_map(static function(ResourcePack $pack){ return new ResourcePackStackEntry($pack->getPackId(), $pack->getPackVersion(), ""); //TODO: subpacks }, $this->resourcePackManager->getResourceStack()); + + //we support chemistry blocks by default, the client should already have this installed + array_unshift($stack, new ResourcePackStackEntry("0fba4063-dba1-4281-9b89-ff9390653530", "1.0.0", "")); + $this->session->sendDataPacket(ResourcePackStackPacket::create($stack, [], $this->resourcePackManager->resourcePacksRequired(), false)); $this->session->getLogger()->debug("Applying resource pack stack"); break; From 4c694c57f4d73b6ae33113869fcf997dc8e24343 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 10 Aug 2019 17:49:31 +0100 Subject: [PATCH 1188/3224] DaylightSensor: Avoid triggering useless block updates if calculated power is unchanged --- src/block/DaylightSensor.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/block/DaylightSensor.php b/src/block/DaylightSensor.php index 271aa8016c..803ad5fe01 100644 --- a/src/block/DaylightSensor.php +++ b/src/block/DaylightSensor.php @@ -95,8 +95,11 @@ class DaylightSensor extends Transparent{ } public function onScheduledUpdate() : void{ - $this->power = $this->recalculatePower(); - $this->pos->getWorld()->setBlock($this->pos, $this); + $newPower = $this->recalculatePower(); + if($this->power !== $newPower){ + $this->power = $newPower; + $this->pos->getWorld()->setBlock($this->pos, $this); + } $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 20); } From d1775030c3d9a3d02a5ed42ecd5b25b8c3c5c763 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 10 Aug 2019 17:59:02 +0100 Subject: [PATCH 1189/3224] Remove DataPacketBroadcastEvent, DataPacketSendEvent now supports multiple recipients & packets in one swoop this makes it simpler to consistently process outbound packets from a plugin. Previously it was necessary to handle 2 events to do 1 job. --- src/Server.php | 4 +- src/event/server/DataPacketBroadcastEvent.php | 78 ------------------- src/event/server/DataPacketSendEvent.php | 47 +++++++---- src/network/mcpe/NetworkSession.php | 4 +- 4 files changed, 36 insertions(+), 97 deletions(-) delete mode 100644 src/event/server/DataPacketBroadcastEvent.php diff --git a/src/Server.php b/src/Server.php index fe5e3ad973..f70a774853 100644 --- a/src/Server.php +++ b/src/Server.php @@ -38,7 +38,7 @@ use pocketmine\entity\EntityFactory; use pocketmine\event\HandlerListManager; use pocketmine\event\player\PlayerDataSaveEvent; use pocketmine\event\server\CommandEvent; -use pocketmine\event\server\DataPacketBroadcastEvent; +use pocketmine\event\server\DataPacketSendEvent; use pocketmine\event\server\QueryRegenerateEvent; use pocketmine\inventory\CreativeInventory; use pocketmine\item\enchantment\Enchantment; @@ -1453,7 +1453,7 @@ class Server{ return false; } - $ev = new DataPacketBroadcastEvent($recipients, $packets); + $ev = new DataPacketSendEvent($recipients, $packets); $ev->call(); if($ev->isCancelled()){ return false; diff --git a/src/event/server/DataPacketBroadcastEvent.php b/src/event/server/DataPacketBroadcastEvent.php deleted file mode 100644 index 46bb4ea57c..0000000000 --- a/src/event/server/DataPacketBroadcastEvent.php +++ /dev/null @@ -1,78 +0,0 @@ -targets = $targets; - $this->packets = $packets; - } - - /** - * @return NetworkSession[] - */ - public function getTargets() : array{ - return $this->targets; - } - - /** - * @param NetworkSession[] $targets - */ - public function setTargets(array $targets) : void{ - $this->targets = $targets; - } - - /** - * @return ClientboundPacket[] - */ - public function getPackets() : array{ - return $this->packets; - } - - /** - * @param ClientboundPacket[] $packets - */ - public function setPackets(array $packets) : void{ - $this->packets = $packets; - } -} diff --git a/src/event/server/DataPacketSendEvent.php b/src/event/server/DataPacketSendEvent.php index 6de229482c..aea7b98000 100644 --- a/src/event/server/DataPacketSendEvent.php +++ b/src/event/server/DataPacketSendEvent.php @@ -28,34 +28,51 @@ use pocketmine\event\CancellableTrait; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\ClientboundPacket; +/** + * Called when packets are sent to network sessions. + */ class DataPacketSendEvent extends ServerEvent implements Cancellable{ use CancellableTrait; - /** @var ClientboundPacket */ - private $packet; - /** @var NetworkSession */ - private $target; + /** @var NetworkSession[] */ + private $targets; + /** @var ClientboundPacket[] */ + private $packets; /** - * @param NetworkSession $target - * @param ClientboundPacket $packet + * @param NetworkSession[] $targets + * @param ClientboundPacket[] $packets */ - public function __construct(NetworkSession $target, ClientboundPacket $packet){ - $this->packet = $packet; - $this->target = $target; + public function __construct(array $targets, array $packets){ + $this->targets = $targets; + $this->packets = $packets; } /** - * @return ClientboundPacket + * @return NetworkSession[] */ - public function getPacket() : ClientboundPacket{ - return $this->packet; + public function getTargets() : array{ + return $this->targets; } /** - * @return NetworkSession + * @param NetworkSession[] $targets */ - public function getTarget() : NetworkSession{ - return $this->target; + public function setTargets(array $targets) : void{ + $this->targets = $targets; + } + + /** + * @return ClientboundPacket[] + */ + public function getPackets() : array{ + return $this->packets; + } + + /** + * @param ClientboundPacket[] $packets + */ + public function setPackets(array $packets) : void{ + $this->packets = $packets; } } diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 1c1e051553..7d94ffe762 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -28,8 +28,8 @@ use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\Human; use pocketmine\entity\Living; use pocketmine\event\player\PlayerCreationEvent; -use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\event\server\DataPacketSendEvent; +use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\form\Form; use pocketmine\math\Vector3; use pocketmine\network\BadPacketException; @@ -363,7 +363,7 @@ class NetworkSession{ $timings = Timings::getSendDataPacketTimings($packet); $timings->startTiming(); try{ - $ev = new DataPacketSendEvent($this, $packet); + $ev = new DataPacketSendEvent([$this], [$packet]); $ev->call(); if($ev->isCancelled()){ return false; From 85ad78dda8f0aa383e6d6fbeafffd41bdc03f848 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 10 Aug 2019 18:00:46 +0100 Subject: [PATCH 1190/3224] DataPacketSendEvent: remove setters these create unnecessary complexities in the internals. --- src/event/server/DataPacketSendEvent.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/event/server/DataPacketSendEvent.php b/src/event/server/DataPacketSendEvent.php index aea7b98000..dac9ac8195 100644 --- a/src/event/server/DataPacketSendEvent.php +++ b/src/event/server/DataPacketSendEvent.php @@ -55,24 +55,10 @@ class DataPacketSendEvent extends ServerEvent implements Cancellable{ return $this->targets; } - /** - * @param NetworkSession[] $targets - */ - public function setTargets(array $targets) : void{ - $this->targets = $targets; - } - /** * @return ClientboundPacket[] */ public function getPackets() : array{ return $this->packets; } - - /** - * @param ClientboundPacket[] $packets - */ - public function setPackets(array $packets) : void{ - $this->packets = $packets; - } } From 399f9242e065688457824ad174d0fa986ef24200 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 10 Aug 2019 18:09:38 +0100 Subject: [PATCH 1191/3224] InventoryManager: avoid use of PlayerHotbarPacket it doesn't work so well when the selected slot is empty. --- src/network/mcpe/InventoryManager.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index f98a46b5af..fe9f6267e9 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -36,7 +36,7 @@ use pocketmine\network\mcpe\protocol\ContainerOpenPacket; use pocketmine\network\mcpe\protocol\ContainerSetDataPacket; use pocketmine\network\mcpe\protocol\InventoryContentPacket; use pocketmine\network\mcpe\protocol\InventorySlotPacket; -use pocketmine\network\mcpe\protocol\PlayerHotbarPacket; +use pocketmine\network\mcpe\protocol\MobEquipmentPacket; use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes; use pocketmine\player\Player; @@ -146,7 +146,12 @@ class InventoryManager{ } public function syncSelectedHotbarSlot() : void{ - $this->session->sendDataPacket(PlayerHotbarPacket::create($this->player->getInventory()->getHeldItemIndex(), ContainerIds::INVENTORY)); + $this->session->sendDataPacket(MobEquipmentPacket::create( + $this->player->getId(), + $this->player->getInventory()->getItemInHand(), + $this->player->getInventory()->getHeldItemIndex(), + ContainerIds::INVENTORY + )); } public function syncCreative() : void{ From 514f395280309722625812797bccf954cec5dba8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 10 Aug 2019 19:47:41 +0100 Subject: [PATCH 1192/3224] SubChunk: reduce visibility of blockLight and skyLight fields --- src/world/format/SubChunk.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/format/SubChunk.php b/src/world/format/SubChunk.php index 2f003ec8c0..026c26dcf8 100644 --- a/src/world/format/SubChunk.php +++ b/src/world/format/SubChunk.php @@ -32,9 +32,9 @@ class SubChunk implements SubChunkInterface{ private $blockLayers; /** @var LightArray */ - protected $blockLight; + private $blockLight; /** @var LightArray */ - protected $skyLight; + private $skyLight; /** * SubChunk constructor. From 2b38098243b220756faa5a190325511f9f02eb4f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 12 Aug 2019 19:05:21 +0100 Subject: [PATCH 1193/3224] Explosion: fix pos refactor mess --- src/world/Explosion.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/world/Explosion.php b/src/world/Explosion.php index 3180b7caac..aa7df40b25 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -203,23 +203,22 @@ class Explosion{ $airBlock = VanillaBlocks::AIR(); foreach($this->affectedBlocks as $block){ + $pos = $block->getPos(); if($block instanceof TNT){ $block->ignite(mt_rand(10, 30)); }else{ if(mt_rand(0, 100) < $yield){ foreach($block->getDrops($air) as $drop){ - $this->world->dropItem($block->add(0.5, 0.5, 0.5), $drop); + $this->world->dropItem($pos->add(0.5, 0.5, 0.5), $drop); } } - if(($t = $this->world->getTileAt($block->x, $block->y, $block->z)) !== null){ + if(($t = $this->world->getTileAt($pos->x, $pos->y, $pos->z)) !== null){ $t->onBlockDestroyed(); //needed to create drops for inventories } - $this->world->setBlockAt($block->x, $block->y, $block->z, $airBlock, false); //TODO: should updating really be disabled here? - $this->world->updateAllLight($block); + $this->world->setBlockAt($pos->x, $pos->y, $pos->z, $airBlock, false); //TODO: should updating really be disabled here? + $this->world->updateAllLight($pos); } - $pos = new Vector3($block->x, $block->y, $block->z); - foreach(Facing::ALL as $side){ $sideBlock = $pos->getSide($side); if(!$this->world->isInWorld($sideBlock->x, $sideBlock->y, $sideBlock->z)){ @@ -237,7 +236,7 @@ class Explosion{ $updateBlocks[$index] = true; } } - $send[] = new Vector3($block->x - $source->x, $block->y - $source->y, $block->z - $source->z); + $send[] = $pos->subtract($source); } $this->world->broadcastPacketToViewers($source, ExplodePacket::create($this->source->asVector3(), $this->size, $send)); From 47b905007e5daed5e3bffcc4265aa10923e48d25 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 13 Aug 2019 18:01:24 +0100 Subject: [PATCH 1194/3224] add more legacy metadata constants --- src/block/BlockLegacyMetadata.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/block/BlockLegacyMetadata.php b/src/block/BlockLegacyMetadata.php index 60a336c4da..904f4efc04 100644 --- a/src/block/BlockLegacyMetadata.php +++ b/src/block/BlockLegacyMetadata.php @@ -32,6 +32,12 @@ interface BlockLegacyMetadata{ public const ANVIL_SLIGHTLY_DAMAGED = 4; public const ANVIL_VERY_DAMAGED = 8; + public const BAMBOO_FLAG_THICK = 0x01; + public const BAMBOO_FLAG_READY = 0x08; + + public const BAMBOO_LEAF_SIZE_SHIFT = 1; + public const BAMBOO_LEAF_SIZE_MASK = 0x03; + public const BED_FLAG_HEAD = 0x08; public const BED_FLAG_OCCUPIED = 0x04; From e9ed46a9c7ce8b0d1efdba75b9e84be871c22c13 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 13 Aug 2019 18:08:56 +0100 Subject: [PATCH 1195/3224] Entity: avoid bad hack on high load which causes bugs on entity move --- src/entity/Entity.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 757408644e..7d484a318c 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1252,8 +1252,7 @@ abstract class Entity extends Location{ assert(abs($dx) <= 20 and abs($dy) <= 20 and abs($dz) <= 20, "Movement distance is excessive: dx=$dx, dy=$dy, dz=$dz"); - //TODO: bad hack here will cause unexpected behaviour under heavy lag - $list = $this->world->getCollisionBoxes($this, $this->world->getTickRateTime() > 50 ? $this->boundingBox->offsetCopy($dx, $dy, $dz) : $this->boundingBox->addCoord($dx, $dy, $dz), false); + $list = $this->world->getCollisionBoxes($this, $this->boundingBox->addCoord($dx, $dy, $dz), false); foreach($list as $bb){ $dy = $bb->calculateYOffset($this->boundingBox, $dy); From d04793145cf22f8e569bac7c34598d2e2a1fcf62 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 14 Aug 2019 17:28:06 +0100 Subject: [PATCH 1196/3224] Remove usages of AxisAlignedBB->setBounds() and AxisAlignedBB->setBB() these usages make no sense in the contexts they are used in, because their uses require another BB to be created anyway. It makes more sense to simply destroy the old one instead of having it mutable. --- src/entity/Entity.php | 40 +++++++++++++++++----------------- src/entity/object/Painting.php | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 7d484a318c..f12b04ecda 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -365,7 +365,7 @@ abstract class Entity extends Location{ protected function recalculateBoundingBox() : void{ $halfWidth = $this->width / 2; - $this->boundingBox->setBounds( + $this->boundingBox = new AxisAlignedBB( $this->x - $halfWidth, $this->y, $this->z - $halfWidth, @@ -1222,7 +1222,7 @@ abstract class Entity extends Location{ } */ - $axisalignedbb = clone $this->boundingBox; + $moveBB = clone $this->boundingBox; /*$sneakFlag = $this->onGround and $this instanceof Player; @@ -1252,27 +1252,27 @@ abstract class Entity extends Location{ assert(abs($dx) <= 20 and abs($dy) <= 20 and abs($dz) <= 20, "Movement distance is excessive: dx=$dx, dy=$dy, dz=$dz"); - $list = $this->world->getCollisionBoxes($this, $this->boundingBox->addCoord($dx, $dy, $dz), false); + $list = $this->world->getCollisionBoxes($this, $moveBB->addCoord($dx, $dy, $dz), false); foreach($list as $bb){ - $dy = $bb->calculateYOffset($this->boundingBox, $dy); + $dy = $bb->calculateYOffset($moveBB, $dy); } - $this->boundingBox->offset(0, $dy, 0); + $moveBB->offset(0, $dy, 0); $fallingFlag = ($this->onGround or ($dy != $movY and $movY < 0)); foreach($list as $bb){ - $dx = $bb->calculateXOffset($this->boundingBox, $dx); + $dx = $bb->calculateXOffset($moveBB, $dx); } - $this->boundingBox->offset($dx, 0, 0); + $moveBB->offset($dx, 0, 0); foreach($list as $bb){ - $dz = $bb->calculateZOffset($this->boundingBox, $dz); + $dz = $bb->calculateZOffset($moveBB, $dz); } - $this->boundingBox->offset(0, 0, $dz); + $moveBB->offset(0, 0, $dz); if($this->stepHeight > 0 and $fallingFlag and $this->ySize < 0.05 and ($movX != $dx or $movZ != $dz)){ @@ -1283,39 +1283,39 @@ abstract class Entity extends Location{ $dy = $this->stepHeight; $dz = $movZ; - $axisalignedbb1 = clone $this->boundingBox; + $stepBB = clone $this->boundingBox; - $this->boundingBox->setBB($axisalignedbb); - - $list = $this->world->getCollisionBoxes($this, $this->boundingBox->addCoord($dx, $dy, $dz), false); + $list = $this->world->getCollisionBoxes($this, $stepBB->addCoord($dx, $dy, $dz), false); foreach($list as $bb){ - $dy = $bb->calculateYOffset($this->boundingBox, $dy); + $dy = $bb->calculateYOffset($stepBB, $dy); } - $this->boundingBox->offset(0, $dy, 0); + $stepBB->offset(0, $dy, 0); foreach($list as $bb){ - $dx = $bb->calculateXOffset($this->boundingBox, $dx); + $dx = $bb->calculateXOffset($stepBB, $dx); } - $this->boundingBox->offset($dx, 0, 0); + $stepBB->offset($dx, 0, 0); foreach($list as $bb){ - $dz = $bb->calculateZOffset($this->boundingBox, $dz); + $dz = $bb->calculateZOffset($stepBB, $dz); } - $this->boundingBox->offset(0, 0, $dz); + $stepBB->offset(0, 0, $dz); if(($cx ** 2 + $cz ** 2) >= ($dx ** 2 + $dz ** 2)){ $dx = $cx; $dy = $cy; $dz = $cz; - $this->boundingBox->setBB($axisalignedbb1); }else{ + $moveBB = $stepBB; $this->ySize += 0.5; //FIXME: this should be the height of the block it walked up, not fixed 0.5 } } + + $this->boundingBox = $moveBB; } $this->x = ($this->boundingBox->minX + $this->boundingBox->maxX) / 2; diff --git a/src/entity/object/Painting.php b/src/entity/object/Painting.php index 546d6ff27b..01a07d9f6a 100644 --- a/src/entity/object/Painting.php +++ b/src/entity/object/Painting.php @@ -125,7 +125,7 @@ class Painting extends Entity{ protected function recalculateBoundingBox() : void{ $side = $this->blockIn->getSide($this->facing); - $this->boundingBox->setBB(self::getPaintingBB($this->facing, $this->getMotive())->offset($side->x, $side->y, $side->z)); + $this->boundingBox = self::getPaintingBB($this->facing, $this->getMotive())->offset($side->x, $side->y, $side->z); } public function onNearbyBlockChange() : void{ From 6dd1cdc4136e3efe281c432a9c47c39791abecbe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 14 Aug 2019 18:22:08 +0100 Subject: [PATCH 1197/3224] sync php submodule version --- build/php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/php b/build/php index ffc465f4f8..ad55054ce2 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit ffc465f4f806269138fc210832500c51fdecd471 +Subproject commit ad55054ce2b416346a43f4aa993a8d46bc86d7f5 From e29ac514d7d8e4fb6d3985652b7762e0f281c82b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Aug 2019 16:16:08 +0100 Subject: [PATCH 1198/3224] Block->getBoundingBox() and Block->getCollisionBoxes() are now final Force usage of Block->recalculateBoundingBox() and Block->recalculateCollisionBoxes() --- src/block/Air.php | 4 ++-- src/block/Block.php | 4 ++-- src/block/NetherPortal.php | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/block/Air.php b/src/block/Air.php index 88f4063f09..13b15513f8 100644 --- a/src/block/Air.php +++ b/src/block/Air.php @@ -50,11 +50,11 @@ class Air extends Transparent{ return false; } - public function getBoundingBox() : ?AxisAlignedBB{ + protected function recalculateBoundingBox() : ?AxisAlignedBB{ return null; } - public function getCollisionBoxes() : array{ + protected function recalculateCollisionBoxes() : array{ return []; } } diff --git a/src/block/Block.php b/src/block/Block.php index d5f1841804..b0a2f91427 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -671,7 +671,7 @@ class Block{ /** * @return AxisAlignedBB[] */ - public function getCollisionBoxes() : array{ + final public function getCollisionBoxes() : array{ if($this->collisionBoxes === null){ $this->collisionBoxes = $this->recalculateCollisionBoxes(); foreach($this->collisionBoxes as $bb){ @@ -696,7 +696,7 @@ class Block{ /** * @return AxisAlignedBB|null */ - public function getBoundingBox() : ?AxisAlignedBB{ + final public function getBoundingBox() : ?AxisAlignedBB{ if($this->boundingBox === null){ $this->boundingBox = $this->recalculateBoundingBox(); if($this->boundingBox !== null){ diff --git a/src/block/NetherPortal.php b/src/block/NetherPortal.php index acaca0ec3c..93f13bc274 100644 --- a/src/block/NetherPortal.php +++ b/src/block/NetherPortal.php @@ -74,7 +74,7 @@ class NetherPortal extends Transparent{ return false; } - public function getBoundingBox() : ?AxisAlignedBB{ + protected function recalculateBoundingBox() : ?AxisAlignedBB{ return null; } From 73b266971287e1f7dd09e6c34ddc7e55b8eef0e5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Aug 2019 16:22:54 +0100 Subject: [PATCH 1199/3224] remove World->isFullBlock(), add Block->isFullCube(), clean up some BB mess --- changelogs/4.0-snapshot.md | 3 ++- src/block/Block.php | 10 ++++++++++ src/block/Thin.php | 3 +-- src/world/World.php | 20 +++----------------- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index f7bd51f923..56734e97d1 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -83,6 +83,7 @@ This version features substantial changes to the network system, improving coher - `Block->asItem()`: returns an itemstack corresponding to the block - `Block->isSameState()`: returns whether the block is the same as the parameter, including state information - `Block->isSameType()`: returns whether the block is the same as the parameter, without state information + - `Block->isFullCube()` - The following hooks have been added: - `Block->onAttack()`: called when a player in survival left-clicks the block to try to start breaking it - `Block->onPostPlace()`: called directly after placement in the world, handles things like rail connections and chest pairing @@ -673,7 +674,7 @@ This version features substantial changes to the network system, improving coher - `World->unregisterChunkListener()` - The following API methods have been removed: - `ChunkLoader->getLoaderId()` (now object ID is used) - + - `World->isFullBlock()` - The following API methods have changed signatures: - `World->addParticle()` now has the signature `addParticle(Vector3 $pos, Particle $particle, ?Player[] $players = null) : void` - `World->addSound()` now has the signature `addSound(?Vector3 $pos, Sound $sound, ?Player[] $players = null) : void` diff --git a/src/block/Block.php b/src/block/Block.php index b0a2f91427..347e06455a 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -46,6 +46,7 @@ use pocketmine\world\Position; use pocketmine\world\World; use function array_merge; use function assert; +use function count; use function dechex; use const PHP_INT_MAX; @@ -713,6 +714,15 @@ class Block{ return AxisAlignedBB::one(); } + /** + * @return bool + */ + public function isFullCube() : bool{ + $bb = $this->getCollisionBoxes(); + + return count($bb) === 1 and $bb[0]->getAverageEdgeLength() >= 1; //TODO: average length 1 != cube + } + /** * @param Vector3 $pos1 * @param Vector3 $pos2 diff --git a/src/block/Thin.php b/src/block/Thin.php index 361200377c..90ff8803f2 100644 --- a/src/block/Thin.php +++ b/src/block/Thin.php @@ -35,8 +35,7 @@ class Thin extends Transparent{ foreach(Facing::HORIZONTAL as $facing){ $side = $this->getSide($facing); - //FIXME: currently there's no proper way to tell if a block is a full-block, so we check the bounding box size - if($side instanceof Thin or ($bb = $side->getBoundingBox()) !== null and $bb->getAverageEdgeLength() >= 1){ + if($side instanceof Thin or $side->isFullCube()){ $this->connections[$facing] = true; }else{ unset($this->connections[$facing]); diff --git a/src/world/World.php b/src/world/World.php index 3851d52bb2..4227b6ad79 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1120,20 +1120,6 @@ class World implements ChunkManager{ return $collides; } - /** - * @param Block $pos - * - * @return bool - */ - public function isFullBlock(Block $pos) : bool{ - if($pos->isSolid()){ - return true; - } - $bb = $pos->getBoundingBox(); - - return $bb !== null and $bb->getAverageEdgeLength() >= 1; - } - /** * @param Entity $entity * @param AxisAlignedBB $bb @@ -2565,7 +2551,7 @@ class World implements ChunkManager{ $y = (int) min($max - 2, $v->y); $wasAir = $this->getBlockAt($x, $y - 1, $z)->getId() === BlockLegacyIds::AIR; //TODO: bad hack, clean up for(; $y > 0; --$y){ - if($this->isFullBlock($this->getBlockAt($x, $y, $z))){ + if($this->getBlockAt($x, $y, $z)->isFullCube()){ if($wasAir){ $y++; break; @@ -2576,8 +2562,8 @@ class World implements ChunkManager{ } for(; $y >= 0 and $y < $max; ++$y){ - if(!$this->isFullBlock($this->getBlockAt($x, $y + 1, $z))){ - if(!$this->isFullBlock($this->getBlockAt($x, $y, $z))){ + if(!$this->getBlockAt($x, $y + 1, $z)->isFullCube()){ + if(!$this->getBlockAt($x, $y, $z)->isFullCube()){ return new Position($spawn->x, $y === (int) $spawn->y ? $spawn->y : $y, $spawn->z, $this); } }else{ From d58339b2fd3d4aec643770506423cdde0977324e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Aug 2019 16:54:14 +0100 Subject: [PATCH 1200/3224] fix doors being considered 3 blocks tall by collision detection in some cases --- src/block/Door.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/block/Door.php b/src/block/Door.php index 7c7dd98c3b..fa5f482194 100644 --- a/src/block/Door.php +++ b/src/block/Door.php @@ -93,9 +93,7 @@ class Door extends Transparent{ } protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one() - ->extend(Facing::UP, 1) - ->trim($this->open ? Facing::rotateY($this->facing, !$this->hingeRight) : $this->facing, 13 / 16); + return AxisAlignedBB::one()->trim($this->open ? Facing::rotateY($this->facing, !$this->hingeRight) : $this->facing, 13 / 16); } public function onNearbyBlockChange() : void{ From 4898a35613257887d1d46dc8aab1d4b2409c2862 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Aug 2019 17:23:55 +0100 Subject: [PATCH 1201/3224] cleanup block dual bounding box clusterfuck "bounding box" serves no tangible purpose, only collision boxes do right now. --- changelogs/4.0-snapshot.md | 2 ++ src/block/Air.php | 7 +++---- src/block/Anvil.php | 7 +++++-- src/block/Banner.php | 7 +++++-- src/block/Bed.php | 7 +++++-- src/block/Block.php | 29 +---------------------------- src/block/Cactus.php | 7 +++++-- src/block/Cake.php | 15 ++++++++++----- src/block/Carpet.php | 7 +++++-- src/block/Chest.php | 7 +++++-- src/block/CocoaBlock.php | 19 ++++++++++++------- src/block/DaylightSensor.php | 7 +++++-- src/block/Door.php | 7 +++++-- src/block/EnchantingTable.php | 7 +++++-- src/block/EndPortalFrame.php | 7 +++++-- src/block/EndRod.php | 7 +++++-- src/block/EnderChest.php | 7 +++++-- src/block/Farmland.php | 7 +++++-- src/block/Fence.php | 16 +++------------- src/block/FenceGate.php | 11 +++++------ src/block/Flowable.php | 7 +++++-- src/block/FlowerPot.php | 7 +++++-- src/block/GrassPath.php | 7 +++++-- src/block/Ladder.php | 8 +++++--- src/block/Lantern.php | 17 +++++++++++------ src/block/Liquid.php | 7 +++++-- src/block/NetherPortal.php | 7 +++++-- src/block/RedstoneComparator.php | 7 +++++-- src/block/RedstoneRepeater.php | 7 +++++-- src/block/SeaPickle.php | 7 +++++-- src/block/Sign.php | 7 +++++-- src/block/Skull.php | 7 +++++-- src/block/Slab.php | 9 ++++++--- src/block/SnowLayer.php | 7 +++++-- src/block/SoulSand.php | 7 +++++-- src/block/Thin.php | 10 ---------- src/block/Trapdoor.php | 7 +++++-- src/block/Vine.php | 11 ----------- src/block/Wall.php | 16 +++++++++------- src/block/WaterLily.php | 7 +++++-- 40 files changed, 202 insertions(+), 157 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 56734e97d1..6bf61bcc05 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -93,10 +93,12 @@ This version features substantial changes to the network system, improving coher - `Block->onEntityCollide()` -> `Block->onEntityInside()` - The following API methods have changed signatures: - `Block->onInteract()` now has the signature `onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool` + - `Block->getCollisionBoxes()` is now final. Classes should override `recalculateCollisionBoxes()`. - The following API methods have been removed: - `Block->canPassThrough()` - `Block->setDamage()` - `Block::get()`: this was superseded by `BlockFactory::get()` a long time ago + - `Block->getBoundingBox()` - The following classes have been renamed: - `BlockIds` -> `BlockLegacyIds` - `CobblestoneWall` -> `Wall` diff --git a/src/block/Air.php b/src/block/Air.php index 13b15513f8..f5408c00bf 100644 --- a/src/block/Air.php +++ b/src/block/Air.php @@ -50,10 +50,9 @@ class Air extends Transparent{ return false; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return null; - } - + /** + * @return AxisAlignedBB[] + */ protected function recalculateCollisionBoxes() : array{ return []; } diff --git a/src/block/Anvil.php b/src/block/Anvil.php index 311dee1a5d..99ab726eb9 100644 --- a/src/block/Anvil.php +++ b/src/block/Anvil.php @@ -57,8 +57,11 @@ class Anvil extends Transparent implements Fallable{ return 0b11; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one()->squash(Facing::axis(Facing::rotateY($this->facing, false)), 1 / 8); + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return [AxisAlignedBB::one()->squash(Facing::axis(Facing::rotateY($this->facing, false)), 1 / 8)]; } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/block/Banner.php b/src/block/Banner.php index 32728041ae..2163356153 100644 --- a/src/block/Banner.php +++ b/src/block/Banner.php @@ -141,8 +141,11 @@ class Banner extends Transparent{ $this->patterns = $checked; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return null; + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return []; } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/block/Bed.php b/src/block/Bed.php index 3a7ab99783..e8f07dc27c 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -88,8 +88,11 @@ class Bed extends Transparent{ } } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one()->trim(Facing::UP, 7 / 16); + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return [AxisAlignedBB::one()->trim(Facing::UP, 7 / 16)]; } public function isHeadPart() : bool{ diff --git a/src/block/Block.php b/src/block/Block.php index 347e06455a..b80dca25d8 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -64,8 +64,6 @@ class Block{ /** @var Position */ protected $pos; - /** @var AxisAlignedBB */ - protected $boundingBox = null; /** @var AxisAlignedBB[]|null */ protected $collisionBoxes = null; @@ -167,7 +165,6 @@ class Block{ * AABBs and force recalculation. */ public function readStateFromWorld() : void{ - $this->boundingBox = null; $this->collisionBoxes = null; } @@ -687,31 +684,7 @@ class Block{ * @return AxisAlignedBB[] */ protected function recalculateCollisionBoxes() : array{ - if($bb = $this->recalculateBoundingBox()){ - return [$bb]; - } - - return []; - } - - /** - * @return AxisAlignedBB|null - */ - final public function getBoundingBox() : ?AxisAlignedBB{ - if($this->boundingBox === null){ - $this->boundingBox = $this->recalculateBoundingBox(); - if($this->boundingBox !== null){ - $this->boundingBox->offset($this->pos->x, $this->pos->y, $this->pos->z); - } - } - return $this->boundingBox; - } - - /** - * @return AxisAlignedBB|null - */ - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one(); + return [AxisAlignedBB::one()]; } /** diff --git a/src/block/Cactus.php b/src/block/Cactus.php index ab3f5fd05b..9516666237 100644 --- a/src/block/Cactus.php +++ b/src/block/Cactus.php @@ -60,9 +60,12 @@ class Cactus extends Transparent{ return true; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ static $shrinkSize = 1 / 16; - return AxisAlignedBB::one()->contract($shrinkSize, 0, $shrinkSize)->trim(Facing::UP, $shrinkSize); + return [AxisAlignedBB::one()->contract($shrinkSize, 0, $shrinkSize)->trim(Facing::UP, $shrinkSize)]; } public function onEntityInside(Entity $entity) : void{ diff --git a/src/block/Cake.php b/src/block/Cake.php index 1cf4a45610..e0ef735a47 100644 --- a/src/block/Cake.php +++ b/src/block/Cake.php @@ -55,11 +55,16 @@ class Cake extends Transparent implements FoodSource{ return 0b111; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one() - ->contract(1 / 16, 0, 1 / 16) - ->trim(Facing::UP, 0.5) - ->trim(Facing::WEST, $this->bites / 8); + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return [ + AxisAlignedBB::one() + ->contract(1 / 16, 0, 1 / 16) + ->trim(Facing::UP, 0.5) + ->trim(Facing::WEST, $this->bites / 8) + ]; } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/block/Carpet.php b/src/block/Carpet.php index 74fd068f28..0a430b023e 100644 --- a/src/block/Carpet.php +++ b/src/block/Carpet.php @@ -40,8 +40,11 @@ class Carpet extends Flowable{ return true; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one()->trim(Facing::UP, 15 / 16); + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return [AxisAlignedBB::one()->trim(Facing::UP, 15 / 16)]; } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/block/Chest.php b/src/block/Chest.php index 6a3042ddf2..b6d09431de 100644 --- a/src/block/Chest.php +++ b/src/block/Chest.php @@ -53,9 +53,12 @@ class Chest extends Transparent{ return 0b111; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ //these are slightly bigger than in PC - return AxisAlignedBB::one()->contract(0.025, 0, 0.025)->trim(Facing::UP, 0.05); + return [AxisAlignedBB::one()->contract(0.025, 0, 0.025)->trim(Facing::UP, 0.05)]; } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/block/CocoaBlock.php b/src/block/CocoaBlock.php index 627bc89f3c..2d315f6bac 100644 --- a/src/block/CocoaBlock.php +++ b/src/block/CocoaBlock.php @@ -63,13 +63,18 @@ class CocoaBlock extends Transparent{ return false; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one() - ->squash(Facing::axis(Facing::rotateY($this->facing, true)), (6 - $this->age) / 16) //sides - ->trim(Facing::DOWN, (7 - $this->age * 2) / 16) - ->trim(Facing::UP, 0.25) - ->trim(Facing::opposite($this->facing), 1 / 16) //gap between log and pod - ->trim($this->facing, (11 - $this->age * 2) / 16); //outward face + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return [ + AxisAlignedBB::one() + ->squash(Facing::axis(Facing::rotateY($this->facing, true)), (6 - $this->age) / 16) //sides + ->trim(Facing::DOWN, (7 - $this->age * 2) / 16) + ->trim(Facing::UP, 0.25) + ->trim(Facing::opposite($this->facing), 1 / 16) //gap between log and pod + ->trim($this->facing, (11 - $this->age * 2) / 16) //outward face + ]; } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/block/DaylightSensor.php b/src/block/DaylightSensor.php index 803ad5fe01..ad16340cf2 100644 --- a/src/block/DaylightSensor.php +++ b/src/block/DaylightSensor.php @@ -83,8 +83,11 @@ class DaylightSensor extends Transparent{ return 300; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one()->trim(Facing::UP, 10 / 16); + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return [AxisAlignedBB::one()->trim(Facing::UP, 10 / 16)]; } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/block/Door.php b/src/block/Door.php index fa5f482194..de7e120818 100644 --- a/src/block/Door.php +++ b/src/block/Door.php @@ -92,8 +92,11 @@ class Door extends Transparent{ return false; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one()->trim($this->open ? Facing::rotateY($this->facing, !$this->hingeRight) : $this->facing, 13 / 16); + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return [AxisAlignedBB::one()->trim($this->open ? Facing::rotateY($this->facing, !$this->hingeRight) : $this->facing, 13 / 16)]; } public function onNearbyBlockChange() : void{ diff --git a/src/block/EnchantingTable.php b/src/block/EnchantingTable.php index 34d2c44206..9507433d4b 100644 --- a/src/block/EnchantingTable.php +++ b/src/block/EnchantingTable.php @@ -37,8 +37,11 @@ class EnchantingTable extends Transparent{ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 6000.0)); } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one()->trim(Facing::UP, 0.25); + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return [AxisAlignedBB::one()->trim(Facing::UP, 0.25)]; } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/block/EndPortalFrame.php b/src/block/EndPortalFrame.php index ae354bdaad..7c94e419dc 100644 --- a/src/block/EndPortalFrame.php +++ b/src/block/EndPortalFrame.php @@ -59,8 +59,11 @@ class EndPortalFrame extends Opaque{ return 1; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one()->trim(Facing::UP, 3 / 16); + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return [AxisAlignedBB::one()->trim(Facing::UP, 3 / 16)]; } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/block/EndRod.php b/src/block/EndRod.php index 3f0a925429..6e5fd32c0d 100644 --- a/src/block/EndRod.php +++ b/src/block/EndRod.php @@ -78,7 +78,10 @@ class EndRod extends Flowable{ return 14; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ $myAxis = Facing::axis($this->facing); $bb = AxisAlignedBB::one(); @@ -88,6 +91,6 @@ class EndRod extends Flowable{ } $bb->squash($axis, 6 / 16); } - return $bb; + return [$bb]; } } diff --git a/src/block/EnderChest.php b/src/block/EnderChest.php index 0dad1888f5..fbb498f9a6 100644 --- a/src/block/EnderChest.php +++ b/src/block/EnderChest.php @@ -58,9 +58,12 @@ class EnderChest extends Transparent{ return 7; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ //these are slightly bigger than in PC - return AxisAlignedBB::one()->contract(0.025, 0, 0.025)->trim(Facing::UP, 0.05); + return [AxisAlignedBB::one()->contract(0.025, 0, 0.025)->trim(Facing::UP, 0.05)]; } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/block/Farmland.php b/src/block/Farmland.php index da1b100c4b..e04917e92b 100644 --- a/src/block/Farmland.php +++ b/src/block/Farmland.php @@ -49,8 +49,11 @@ class Farmland extends Transparent{ return 0b111; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one(); //TODO: this should be trimmed at the top by 1/16, but MCPE currently treats them as a full block (https://bugs.mojang.com/browse/MCPE-12109) + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return [AxisAlignedBB::one()]; //TODO: this should be trimmed at the top by 1/16, but MCPE currently treats them as a full block (https://bugs.mojang.com/browse/MCPE-12109) } public function onNearbyBlockChange() : void{ diff --git a/src/block/Fence.php b/src/block/Fence.php index fda69d6d68..2a9d02d54f 100644 --- a/src/block/Fence.php +++ b/src/block/Fence.php @@ -47,19 +47,9 @@ class Fence extends Transparent{ } } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - $width = 0.5 - $this->getThickness() / 2; - - $bb = AxisAlignedBB::one() - ->extend(Facing::UP, 0.5); - foreach(Facing::HORIZONTAL as $facing){ - if(!isset($this->connections[$facing])){ - $bb->trim($facing, $width); - } - } - return $bb; - } - + /** + * @return AxisAlignedBB[] + */ protected function recalculateCollisionBoxes() : array{ $inset = 0.5 - $this->getThickness() / 2; diff --git a/src/block/FenceGate.php b/src/block/FenceGate.php index ea00e71a8a..8fc695e7cb 100644 --- a/src/block/FenceGate.php +++ b/src/block/FenceGate.php @@ -60,12 +60,11 @@ class FenceGate extends Transparent{ return 0b1111; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - if($this->open){ - return null; - } - - return AxisAlignedBB::one()->extend(Facing::UP, 0.5)->squash(Facing::axis($this->facing), 6 / 16); + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return $this->open ? [] : [AxisAlignedBB::one()->extend(Facing::UP, 0.5)->squash(Facing::axis($this->facing), 6 / 16)]; } private function checkInWall() : bool{ diff --git a/src/block/Flowable.php b/src/block/Flowable.php index fd98e057f9..60f737e1d7 100644 --- a/src/block/Flowable.php +++ b/src/block/Flowable.php @@ -35,7 +35,10 @@ abstract class Flowable extends Transparent{ return false; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return null; + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return []; } } diff --git a/src/block/FlowerPot.php b/src/block/FlowerPot.php index 3fb8735f70..5f19a75756 100644 --- a/src/block/FlowerPot.php +++ b/src/block/FlowerPot.php @@ -111,8 +111,11 @@ class FlowerPot extends Flowable{ //TODO: bamboo } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one()->contract(3 / 16, 0, 3 / 16)->trim(Facing::UP, 5 / 8); + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return [AxisAlignedBB::one()->contract(3 / 16, 0, 3 / 16)->trim(Facing::UP, 5 / 8)]; } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/block/GrassPath.php b/src/block/GrassPath.php index d2b7ef5cc3..e4cf5b274a 100644 --- a/src/block/GrassPath.php +++ b/src/block/GrassPath.php @@ -33,8 +33,11 @@ class GrassPath extends Transparent{ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::SHOVEL)); } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one(); //TODO: this should be trimmed at the top by 1/16, but MCPE currently treats them as a full block (https://bugs.mojang.com/browse/MCPE-12109) + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return [AxisAlignedBB::one()]; //TODO: this should be trimmed at the top by 1/16, but MCPE currently treats them as a full block (https://bugs.mojang.com/browse/MCPE-12109) } public function onNearbyBlockChange() : void{ diff --git a/src/block/Ladder.php b/src/block/Ladder.php index 927bfe8b80..9478bf5bb0 100644 --- a/src/block/Ladder.php +++ b/src/block/Ladder.php @@ -72,11 +72,13 @@ class Ladder extends Transparent{ } } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one()->trim($this->facing, 13 / 16); + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return [AxisAlignedBB::one()->trim($this->facing, 13 / 16)]; } - public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$blockClicked->isTransparent() and Facing::axis($face) !== Facing::AXIS_Y){ $this->facing = $face; diff --git a/src/block/Lantern.php b/src/block/Lantern.php index d4334ba2ac..7f5d790c58 100644 --- a/src/block/Lantern.php +++ b/src/block/Lantern.php @@ -51,12 +51,17 @@ class Lantern extends Transparent{ return 15; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one() - ->trim(Facing::UP, $this->hanging ? 6 / 16 : 8 / 16) - ->trim(Facing::DOWN, $this->hanging ? 2 / 16 : 0) - ->squash(Facing::AXIS_X, 5 / 16) - ->squash(Facing::AXIS_Z, 5 / 16); + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return [ + AxisAlignedBB::one() + ->trim(Facing::UP, $this->hanging ? 6 / 16 : 8 / 16) + ->trim(Facing::DOWN, $this->hanging ? 2 / 16 : 0) + ->squash(Facing::AXIS_X, 5 / 16) + ->squash(Facing::AXIS_Z, 5 / 16) + ]; } protected function canAttachTo(Block $b) : bool{ diff --git a/src/block/Liquid.php b/src/block/Liquid.php index b946cdd043..9f4435e46b 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -99,8 +99,11 @@ abstract class Liquid extends Transparent{ return false; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return null; + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return []; } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/block/NetherPortal.php b/src/block/NetherPortal.php index 93f13bc274..e68c65e325 100644 --- a/src/block/NetherPortal.php +++ b/src/block/NetherPortal.php @@ -74,8 +74,11 @@ class NetherPortal extends Transparent{ return false; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return null; + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return []; } public function getDrops(Item $item) : array{ diff --git a/src/block/RedstoneComparator.php b/src/block/RedstoneComparator.php index 37834b44be..7554e1e7c9 100644 --- a/src/block/RedstoneComparator.php +++ b/src/block/RedstoneComparator.php @@ -143,8 +143,11 @@ class RedstoneComparator extends Flowable{ $this->signalStrength = $signalStrength; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one()->trim(Facing::UP, 7 / 8); + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return [AxisAlignedBB::one()->trim(Facing::UP, 7 / 8)]; } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/block/RedstoneRepeater.php b/src/block/RedstoneRepeater.php index 2c87dd97f0..c1e7a7af05 100644 --- a/src/block/RedstoneRepeater.php +++ b/src/block/RedstoneRepeater.php @@ -64,8 +64,11 @@ class RedstoneRepeater extends Flowable{ return 0b1111; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one()->trim(Facing::UP, 7 / 8); + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return [AxisAlignedBB::one()->trim(Facing::UP, 7 / 8)]; } public function isPowered() : bool{ diff --git a/src/block/SeaPickle.php b/src/block/SeaPickle.php index 0775d7e195..87edd0cf53 100644 --- a/src/block/SeaPickle.php +++ b/src/block/SeaPickle.php @@ -60,8 +60,11 @@ class SeaPickle extends Transparent{ return $this->underwater ? ($this->count + 1) * 3 : 0; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return null; + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return []; } public function canBePlacedAt(Block $blockReplace, Vector3 $clickVector, int $face, bool $isClickedBlock) : bool{ diff --git a/src/block/Sign.php b/src/block/Sign.php index 19a6ef29e5..c8c35f5986 100644 --- a/src/block/Sign.php +++ b/src/block/Sign.php @@ -107,8 +107,11 @@ class Sign extends Transparent{ return false; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return null; + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return []; } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/block/Skull.php b/src/block/Skull.php index a31b39caaa..3d33758b36 100644 --- a/src/block/Skull.php +++ b/src/block/Skull.php @@ -90,9 +90,12 @@ class Skull extends Flowable{ return $this->skullType; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ //TODO: different bounds depending on attached face - return AxisAlignedBB::one()->contract(0.25, 0, 0.25)->trim(Facing::UP, 0.5); + return [AxisAlignedBB::one()->contract(0.25, 0, 0.25)->trim(Facing::UP, 0.5)]; } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/block/Slab.php b/src/block/Slab.php index 7cceddba92..4c8c701c1d 100644 --- a/src/block/Slab.php +++ b/src/block/Slab.php @@ -119,11 +119,14 @@ class Slab extends Transparent{ return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ if($this->slabType->equals(SlabType::DOUBLE())){ - return parent::recalculateBoundingBox(); + return [AxisAlignedBB::one()]; } - return AxisAlignedBB::one()->trim($this->slabType->equals(SlabType::TOP()) ? Facing::DOWN : Facing::UP, 0.5); + return [AxisAlignedBB::one()->trim($this->slabType->equals(SlabType::TOP()) ? Facing::DOWN : Facing::UP, 0.5)]; } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/block/SnowLayer.php b/src/block/SnowLayer.php index bad9b5437a..9eb43c33ca 100644 --- a/src/block/SnowLayer.php +++ b/src/block/SnowLayer.php @@ -63,9 +63,12 @@ class SnowLayer extends Flowable implements Fallable{ return $this->layers < 8; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ //TODO: this zero-height BB is intended to stay in lockstep with a MCPE bug - return AxisAlignedBB::one()->trim(Facing::UP, $this->layers >= 4 ? 0.5 : 1); + return [AxisAlignedBB::one()->trim(Facing::UP, $this->layers >= 4 ? 0.5 : 1)]; } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/block/SoulSand.php b/src/block/SoulSand.php index bc60ad9ec5..465b79784e 100644 --- a/src/block/SoulSand.php +++ b/src/block/SoulSand.php @@ -32,7 +32,10 @@ class SoulSand extends Opaque{ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::SHOVEL)); } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one()->trim(Facing::UP, 1 / 8); + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return [AxisAlignedBB::one()->trim(Facing::UP, 1 / 8)]; } } diff --git a/src/block/Thin.php b/src/block/Thin.php index 90ff8803f2..e98cc84653 100644 --- a/src/block/Thin.php +++ b/src/block/Thin.php @@ -43,16 +43,6 @@ class Thin extends Transparent{ } } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - $bb = AxisAlignedBB::one(); - foreach(Facing::HORIZONTAL as $facing){ - if(!isset($this->connections[$facing])){ - $bb->trim($facing, 7 / 16); - } - } - return $bb; - } - protected function recalculateCollisionBoxes() : array{ $inset = 7 / 16; diff --git a/src/block/Trapdoor.php b/src/block/Trapdoor.php index ff37fb48e4..ab1d75f538 100644 --- a/src/block/Trapdoor.php +++ b/src/block/Trapdoor.php @@ -57,8 +57,11 @@ class Trapdoor extends Transparent{ return 0b1111; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one()->trim($this->open ? $this->facing : ($this->top ? Facing::DOWN : Facing::UP), 13 / 16); + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return [AxisAlignedBB::one()->trim($this->open ? $this->facing : ($this->top ? Facing::DOWN : Facing::UP), 13 / 16)]; } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/block/Vine.php b/src/block/Vine.php index c84308c8fd..a46ce59413 100644 --- a/src/block/Vine.php +++ b/src/block/Vine.php @@ -86,17 +86,6 @@ class Vine extends Flowable{ $entity->resetFallDistance(); } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - switch(count($this->faces)){ - case 0: - return AxisAlignedBB::one()->trim(Facing::DOWN, 15 / 16); - case 1: - return AxisAlignedBB::one()->trim(Facing::opposite(array_keys($this->faces)[0]), 15 / 16); - default: - return AxisAlignedBB::one(); - } - } - protected function recalculateCollisionBoxes() : array{ return []; } diff --git a/src/block/Wall.php b/src/block/Wall.php index c2af8d1b16..073a6a2702 100644 --- a/src/block/Wall.php +++ b/src/block/Wall.php @@ -53,7 +53,7 @@ class Wall extends Transparent{ $this->up = $this->getSide(Facing::UP)->getId() !== BlockLegacyIds::AIR; } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ + protected function recalculateCollisionBoxes() : array{ //walls don't have any special collision boxes like fences do $north = isset($this->connections[Facing::NORTH]); @@ -73,11 +73,13 @@ class Wall extends Transparent{ $inset = 0.3125; } - return AxisAlignedBB::one() - ->extend(Facing::UP, 0.5) - ->trim(Facing::NORTH, $north ? 0 : $inset) - ->trim(Facing::SOUTH, $south ? 0 : $inset) - ->trim(Facing::WEST, $west ? 0 : $inset) - ->trim(Facing::EAST, $east ? 0 : $inset); + return [ + AxisAlignedBB::one() + ->extend(Facing::UP, 0.5) + ->trim(Facing::NORTH, $north ? 0 : $inset) + ->trim(Facing::SOUTH, $south ? 0 : $inset) + ->trim(Facing::WEST, $west ? 0 : $inset) + ->trim(Facing::EAST, $east ? 0 : $inset) + ]; } } diff --git a/src/block/WaterLily.php b/src/block/WaterLily.php index 0ee0b299c5..e4648d3781 100644 --- a/src/block/WaterLily.php +++ b/src/block/WaterLily.php @@ -36,8 +36,11 @@ class WaterLily extends Flowable{ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6)); } - protected function recalculateBoundingBox() : ?AxisAlignedBB{ - return AxisAlignedBB::one()->contract(1 / 16, 0, 1 / 16)->trim(Facing::UP, 63 / 64); + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + return [AxisAlignedBB::one()->contract(1 / 16, 0, 1 / 16)->trim(Facing::UP, 63 / 64)]; } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ From a7d51a273d165d97cb0e7aa28e3b939704a8338b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 17 Aug 2019 16:36:05 +0100 Subject: [PATCH 1202/3224] EnumTrait: add a numeric runtimeID field for arrays and switches --- src/utils/EnumTrait.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/utils/EnumTrait.php b/src/utils/EnumTrait.php index 351e8d5b1e..c3c23bd829 100644 --- a/src/utils/EnumTrait.php +++ b/src/utils/EnumTrait.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\utils; +use function getmypid; use function preg_match; trait EnumTrait{ @@ -85,8 +86,13 @@ trait EnumTrait{ return self::_registryFromString($name); } + /** @var int|null */ + private static $nextId = null; + /** @var string */ private $enumName; + /** @var int */ + private $runtimeId; /** * @param string $enumName @@ -98,6 +104,10 @@ trait EnumTrait{ throw new \InvalidArgumentException("Invalid enum member name \"$enumName\", should only contain letters, numbers and underscores, and must not start with a number"); } $this->enumName = $enumName; + if(self::$nextId === null){ + self::$nextId = getmypid(); //this provides enough base entropy to prevent hardcoding + } + $this->runtimeId = self::$nextId++; } /** @@ -107,6 +117,17 @@ trait EnumTrait{ return $this->enumName; } + /** + * Returns a runtime-only identifier for this enum member. This will be different with each run, so don't try to + * hardcode it. + * This can be useful for switches or array indexing. + * + * @return int + */ + public function id() : int{ + return $this->runtimeId; + } + /** * Returns whether the two objects are equivalent. * From 591d35889edd998786b827e57c92b6540c50299f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 17 Aug 2019 16:37:36 +0100 Subject: [PATCH 1203/3224] make use of EnumTrait->id() --- src/block/BlockFactory.php | 171 ++++++++++++++++++------------------- src/item/ItemFactory.php | 14 +-- 2 files changed, 92 insertions(+), 93 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 59e5aafaaf..847c8b8440 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -402,68 +402,66 @@ class BlockFactory{ //region ugly treetype -> blockID mapping tables - /** @var int[]|\SplObjectStorage $woodenStairIds */ - $woodenStairIds = new \SplObjectStorage(); - $woodenStairIds[TreeType::OAK()] = Ids::OAK_STAIRS; - $woodenStairIds[TreeType::SPRUCE()] = Ids::SPRUCE_STAIRS; - $woodenStairIds[TreeType::BIRCH()] = Ids::BIRCH_STAIRS; - $woodenStairIds[TreeType::JUNGLE()] = Ids::JUNGLE_STAIRS; - $woodenStairIds[TreeType::ACACIA()] = Ids::ACACIA_STAIRS; - $woodenStairIds[TreeType::DARK_OAK()] = Ids::DARK_OAK_STAIRS; + $woodenStairIds = [ + TreeType::OAK()->id() => Ids::OAK_STAIRS, + TreeType::SPRUCE()->id() => Ids::SPRUCE_STAIRS, + TreeType::BIRCH()->id() => Ids::BIRCH_STAIRS, + TreeType::JUNGLE()->id() => Ids::JUNGLE_STAIRS, + TreeType::ACACIA()->id() => Ids::ACACIA_STAIRS, + TreeType::DARK_OAK()->id() => Ids::DARK_OAK_STAIRS + ]; + $fenceGateIds = [ + TreeType::OAK()->id() => Ids::OAK_FENCE_GATE, + TreeType::SPRUCE()->id() => Ids::SPRUCE_FENCE_GATE, + TreeType::BIRCH()->id() => Ids::BIRCH_FENCE_GATE, + TreeType::JUNGLE()->id() => Ids::JUNGLE_FENCE_GATE, + TreeType::ACACIA()->id() => Ids::ACACIA_FENCE_GATE, + TreeType::DARK_OAK()->id() => Ids::DARK_OAK_FENCE_GATE + ]; - /** @var int[]|\SplObjectStorage $fenceGateIds */ - $fenceGateIds = new \SplObjectStorage(); - $fenceGateIds[TreeType::OAK()] = Ids::OAK_FENCE_GATE; - $fenceGateIds[TreeType::SPRUCE()] = Ids::SPRUCE_FENCE_GATE; - $fenceGateIds[TreeType::BIRCH()] = Ids::BIRCH_FENCE_GATE; - $fenceGateIds[TreeType::JUNGLE()] = Ids::JUNGLE_FENCE_GATE; - $fenceGateIds[TreeType::ACACIA()] = Ids::ACACIA_FENCE_GATE; - $fenceGateIds[TreeType::DARK_OAK()] = Ids::DARK_OAK_FENCE_GATE; + /** @var BID[] $woodenDoorIds */ + $woodenDoorIds = [ + TreeType::OAK()->id() => new BID(Ids::OAK_DOOR_BLOCK, 0, ItemIds::OAK_DOOR), + TreeType::SPRUCE()->id() => new BID(Ids::SPRUCE_DOOR_BLOCK, 0, ItemIds::SPRUCE_DOOR), + TreeType::BIRCH()->id() => new BID(Ids::BIRCH_DOOR_BLOCK, 0, ItemIds::BIRCH_DOOR), + TreeType::JUNGLE()->id() => new BID(Ids::JUNGLE_DOOR_BLOCK, 0, ItemIds::JUNGLE_DOOR), + TreeType::ACACIA()->id() => new BID(Ids::ACACIA_DOOR_BLOCK, 0, ItemIds::ACACIA_DOOR), + TreeType::DARK_OAK()->id() => new BID(Ids::DARK_OAK_DOOR_BLOCK, 0, ItemIds::DARK_OAK_DOOR) + ]; + $woodenPressurePlateIds = [ + TreeType::OAK()->id() => Ids::WOODEN_PRESSURE_PLATE, + TreeType::SPRUCE()->id() => Ids::SPRUCE_PRESSURE_PLATE, + TreeType::BIRCH()->id() => Ids::BIRCH_PRESSURE_PLATE, + TreeType::JUNGLE()->id() => Ids::JUNGLE_PRESSURE_PLATE, + TreeType::ACACIA()->id() => Ids::ACACIA_PRESSURE_PLATE, + TreeType::DARK_OAK()->id() => Ids::DARK_OAK_PRESSURE_PLATE + ]; + $woodenButtonIds = [ + TreeType::OAK()->id() => Ids::WOODEN_BUTTON, + TreeType::SPRUCE()->id() => Ids::SPRUCE_BUTTON, + TreeType::BIRCH()->id() => Ids::BIRCH_BUTTON, + TreeType::JUNGLE()->id() => Ids::JUNGLE_BUTTON, + TreeType::ACACIA()->id() => Ids::ACACIA_BUTTON, + TreeType::DARK_OAK()->id() => Ids::DARK_OAK_BUTTON + ]; + $woodenTrapdoorIds = [ + TreeType::OAK()->id() => Ids::WOODEN_TRAPDOOR, + TreeType::SPRUCE()->id() => Ids::SPRUCE_TRAPDOOR, + TreeType::BIRCH()->id() => Ids::BIRCH_TRAPDOOR, + TreeType::JUNGLE()->id() => Ids::JUNGLE_TRAPDOOR, + TreeType::ACACIA()->id() => Ids::ACACIA_TRAPDOOR, + TreeType::DARK_OAK()->id() => Ids::DARK_OAK_TRAPDOOR + ]; - /** @var BID[]|\SplObjectStorage $woodenDoorIds */ - $woodenDoorIds = new \SplObjectStorage(); - $woodenDoorIds[TreeType::OAK()] = new BID(Ids::OAK_DOOR_BLOCK, 0, ItemIds::OAK_DOOR); - $woodenDoorIds[TreeType::SPRUCE()] = new BID(Ids::SPRUCE_DOOR_BLOCK, 0, ItemIds::SPRUCE_DOOR); - $woodenDoorIds[TreeType::BIRCH()] = new BID(Ids::BIRCH_DOOR_BLOCK, 0, ItemIds::BIRCH_DOOR); - $woodenDoorIds[TreeType::JUNGLE()] = new BID(Ids::JUNGLE_DOOR_BLOCK, 0, ItemIds::JUNGLE_DOOR); - $woodenDoorIds[TreeType::ACACIA()] = new BID(Ids::ACACIA_DOOR_BLOCK, 0, ItemIds::ACACIA_DOOR); - $woodenDoorIds[TreeType::DARK_OAK()] = new BID(Ids::DARK_OAK_DOOR_BLOCK, 0, ItemIds::DARK_OAK_DOOR); - - /** @var int[]|\SplObjectStorage $woodenPressurePlateIds */ - $woodenPressurePlateIds = new \SplObjectStorage(); - $woodenPressurePlateIds[TreeType::OAK()] = Ids::WOODEN_PRESSURE_PLATE; - $woodenPressurePlateIds[TreeType::SPRUCE()] = Ids::SPRUCE_PRESSURE_PLATE; - $woodenPressurePlateIds[TreeType::BIRCH()] = Ids::BIRCH_PRESSURE_PLATE; - $woodenPressurePlateIds[TreeType::JUNGLE()] = Ids::JUNGLE_PRESSURE_PLATE; - $woodenPressurePlateIds[TreeType::ACACIA()] = Ids::ACACIA_PRESSURE_PLATE; - $woodenPressurePlateIds[TreeType::DARK_OAK()] = Ids::DARK_OAK_PRESSURE_PLATE; - - /** @var int[]|\SplObjectStorage $woodenButtonIds */ - $woodenButtonIds = new \SplObjectStorage(); - $woodenButtonIds[TreeType::OAK()] = Ids::WOODEN_BUTTON; - $woodenButtonIds[TreeType::SPRUCE()] = Ids::SPRUCE_BUTTON; - $woodenButtonIds[TreeType::BIRCH()] = Ids::BIRCH_BUTTON; - $woodenButtonIds[TreeType::JUNGLE()] = Ids::JUNGLE_BUTTON; - $woodenButtonIds[TreeType::ACACIA()] = Ids::ACACIA_BUTTON; - $woodenButtonIds[TreeType::DARK_OAK()] = Ids::DARK_OAK_BUTTON; - - /** @var int[]|\SplObjectStorage $woodenTrapdoorIds */ - $woodenTrapdoorIds = new \SplObjectStorage(); - $woodenTrapdoorIds[TreeType::OAK()] = Ids::WOODEN_TRAPDOOR; - $woodenTrapdoorIds[TreeType::SPRUCE()] = Ids::SPRUCE_TRAPDOOR; - $woodenTrapdoorIds[TreeType::BIRCH()] = Ids::BIRCH_TRAPDOOR; - $woodenTrapdoorIds[TreeType::JUNGLE()] = Ids::JUNGLE_TRAPDOOR; - $woodenTrapdoorIds[TreeType::ACACIA()] = Ids::ACACIA_TRAPDOOR; - $woodenTrapdoorIds[TreeType::DARK_OAK()] = Ids::DARK_OAK_TRAPDOOR; - - /** @var BIDFlattened[]|\SplObjectStorage $woodenSignIds */ - $woodenSignIds = new \SplObjectStorage(); - $woodenSignIds[TreeType::OAK()] = new BIDFlattened(Ids::SIGN_POST, Ids::WALL_SIGN, 0, ItemIds::SIGN, TileSign::class); - $woodenSignIds[TreeType::SPRUCE()] = new BIDFlattened(Ids::SPRUCE_STANDING_SIGN, Ids::SPRUCE_WALL_SIGN, 0, ItemIds::SPRUCE_SIGN, TileSign::class); - $woodenSignIds[TreeType::BIRCH()] = new BIDFlattened(Ids::BIRCH_STANDING_SIGN, Ids::BIRCH_WALL_SIGN, 0, ItemIds::BIRCH_SIGN, TileSign::class); - $woodenSignIds[TreeType::JUNGLE()] = new BIDFlattened(Ids::JUNGLE_STANDING_SIGN, Ids::JUNGLE_WALL_SIGN, 0, ItemIds::JUNGLE_SIGN, TileSign::class); - $woodenSignIds[TreeType::ACACIA()] = new BIDFlattened(Ids::ACACIA_STANDING_SIGN, Ids::ACACIA_WALL_SIGN, 0, ItemIds::ACACIA_SIGN, TileSign::class); - $woodenSignIds[TreeType::DARK_OAK()] = new BIDFlattened(Ids::DARKOAK_STANDING_SIGN, Ids::DARKOAK_WALL_SIGN, 0, ItemIds::DARKOAK_SIGN, TileSign::class); + /** @var BIDFlattened[] $woodenSignIds */ + $woodenSignIds = [ + TreeType::OAK()->id() => new BIDFlattened(Ids::SIGN_POST, Ids::WALL_SIGN, 0, ItemIds::SIGN, TileSign::class), + TreeType::SPRUCE()->id() => new BIDFlattened(Ids::SPRUCE_STANDING_SIGN, Ids::SPRUCE_WALL_SIGN, 0, ItemIds::SPRUCE_SIGN, TileSign::class), + TreeType::BIRCH()->id() => new BIDFlattened(Ids::BIRCH_STANDING_SIGN, Ids::BIRCH_WALL_SIGN, 0, ItemIds::BIRCH_SIGN, TileSign::class), + TreeType::JUNGLE()->id() => new BIDFlattened(Ids::JUNGLE_STANDING_SIGN, Ids::JUNGLE_WALL_SIGN, 0, ItemIds::JUNGLE_SIGN, TileSign::class), + TreeType::ACACIA()->id() => new BIDFlattened(Ids::ACACIA_STANDING_SIGN, Ids::ACACIA_WALL_SIGN, 0, ItemIds::ACACIA_SIGN, TileSign::class), + TreeType::DARK_OAK()->id() => new BIDFlattened(Ids::DARKOAK_STANDING_SIGN, Ids::DARKOAK_WALL_SIGN, 0, ItemIds::DARKOAK_SIGN, TileSign::class) + ]; //endregion foreach(TreeType::getAll() as $treeType){ @@ -482,15 +480,15 @@ class BlockFactory{ self::register($wood); self::remap($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, ($magicNumber & 0x03) | 0b1100, $wood); - self::register(new FenceGate(new BID($fenceGateIds[$treeType]), $treeType->getDisplayName() . " Fence Gate")); - self::register(new WoodenStairs(new BID($woodenStairIds[$treeType]), $treeType->getDisplayName() . " Stairs")); - self::register(new WoodenDoor($woodenDoorIds[$treeType], $treeType->getDisplayName() . " Door")); + self::register(new FenceGate(new BID($fenceGateIds[$treeType->id()]), $treeType->getDisplayName() . " Fence Gate")); + self::register(new WoodenStairs(new BID($woodenStairIds[$treeType->id()]), $treeType->getDisplayName() . " Stairs")); + self::register(new WoodenDoor($woodenDoorIds[$treeType->id()], $treeType->getDisplayName() . " Door")); - self::register(new WoodenButton(new BID($woodenButtonIds[$treeType]), $treeType->getDisplayName() . " Button")); - self::register(new WoodenPressurePlate(new BID($woodenPressurePlateIds[$treeType]), $treeType->getDisplayName() . " Pressure Plate")); - self::register(new WoodenTrapdoor(new BID($woodenTrapdoorIds[$treeType]), $treeType->getDisplayName() . " Trapdoor")); + self::register(new WoodenButton(new BID($woodenButtonIds[$treeType->id()]), $treeType->getDisplayName() . " Button")); + self::register(new WoodenPressurePlate(new BID($woodenPressurePlateIds[$treeType->id()]), $treeType->getDisplayName() . " Pressure Plate")); + self::register(new WoodenTrapdoor(new BID($woodenTrapdoorIds[$treeType->id()]), $treeType->getDisplayName() . " Trapdoor")); - self::register(new Sign($woodenSignIds[$treeType], $treeType->getDisplayName() . " Sign")); + self::register(new Sign($woodenSignIds[$treeType->id()], $treeType->getDisplayName() . " Sign")); } static $sandstoneTypes = [ @@ -510,24 +508,25 @@ class BlockFactory{ } //region ugly glazed-terracotta colour -> ID mapping table - /** @var int[]|\SplObjectStorage $glazedTerracottaIds */ - $glazedTerracottaIds = new \SplObjectStorage(); - $glazedTerracottaIds[DyeColor::WHITE()] = Ids::WHITE_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::ORANGE()] = Ids::ORANGE_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::MAGENTA()] = Ids::MAGENTA_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::LIGHT_BLUE()] = Ids::LIGHT_BLUE_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::YELLOW()] = Ids::YELLOW_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::LIME()] = Ids::LIME_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::PINK()] = Ids::PINK_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::GRAY()] = Ids::GRAY_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::LIGHT_GRAY()] = Ids::SILVER_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::CYAN()] = Ids::CYAN_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::PURPLE()] = Ids::PURPLE_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::BLUE()] = Ids::BLUE_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::BROWN()] = Ids::BROWN_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::GREEN()] = Ids::GREEN_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::RED()] = Ids::RED_GLAZED_TERRACOTTA; - $glazedTerracottaIds[DyeColor::BLACK()] = Ids::BLACK_GLAZED_TERRACOTTA; + /** @var int[] */ + $glazedTerracottaIds = [ + DyeColor::WHITE()->id() => Ids::WHITE_GLAZED_TERRACOTTA, + DyeColor::ORANGE()->id() => Ids::ORANGE_GLAZED_TERRACOTTA, + DyeColor::MAGENTA()->id() => Ids::MAGENTA_GLAZED_TERRACOTTA, + DyeColor::LIGHT_BLUE()->id() => Ids::LIGHT_BLUE_GLAZED_TERRACOTTA, + DyeColor::YELLOW()->id() => Ids::YELLOW_GLAZED_TERRACOTTA, + DyeColor::LIME()->id() => Ids::LIME_GLAZED_TERRACOTTA, + DyeColor::PINK()->id() => Ids::PINK_GLAZED_TERRACOTTA, + DyeColor::GRAY()->id() => Ids::GRAY_GLAZED_TERRACOTTA, + DyeColor::LIGHT_GRAY()->id() => Ids::SILVER_GLAZED_TERRACOTTA, + DyeColor::CYAN()->id() => Ids::CYAN_GLAZED_TERRACOTTA, + DyeColor::PURPLE()->id() => Ids::PURPLE_GLAZED_TERRACOTTA, + DyeColor::BLUE()->id() => Ids::BLUE_GLAZED_TERRACOTTA, + DyeColor::BROWN()->id() => Ids::BROWN_GLAZED_TERRACOTTA, + DyeColor::GREEN()->id() => Ids::GREEN_GLAZED_TERRACOTTA, + DyeColor::RED()->id() => Ids::RED_GLAZED_TERRACOTTA, + DyeColor::BLACK()->id() => Ids::BLACK_GLAZED_TERRACOTTA + ]; //endregion foreach(DyeColor::getAll() as $color){ @@ -536,7 +535,7 @@ class BlockFactory{ self::register(new ConcretePowder(new BID(Ids::CONCRETE_POWDER, $color->getMagicNumber()), $color->getDisplayName() . " Concrete Powder")); self::register(new Glass(new BID(Ids::STAINED_GLASS, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass")); self::register(new GlassPane(new BID(Ids::STAINED_GLASS_PANE, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass Pane")); - self::register(new GlazedTerracotta(new BID($glazedTerracottaIds[$color]), $color->getDisplayName() . " Glazed Terracotta")); + self::register(new GlazedTerracotta(new BID($glazedTerracottaIds[$color->id()]), $color->getDisplayName() . " Glazed Terracotta")); self::register(new HardenedClay(new BID(Ids::STAINED_CLAY, $color->getMagicNumber()), $color->getDisplayName() . " Stained Clay")); self::register(new HardenedGlass(new BID(Ids::HARD_STAINED_GLASS, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass")); self::register(new HardenedGlassPane(new BID(Ids::HARD_STAINED_GLASS_PANE, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass Pane")); diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 6132fccbfe..3198d2ec38 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -238,16 +238,16 @@ class ItemFactory{ self::register(new Skull(ItemIds::SKULL, $skullType->getMagicNumber(), $skullType->getDisplayName(), $skullType)); } - /** @var int[]|\SplObjectStorage $dyeMap */ - $dyeMap = new \SplObjectStorage(); - $dyeMap[DyeColor::BLACK()] = 16; - $dyeMap[DyeColor::BROWN()] = 17; - $dyeMap[DyeColor::BLUE()] = 18; - $dyeMap[DyeColor::WHITE()] = 19; + $dyeMap = [ + DyeColor::BLACK()->id() => 16, + DyeColor::BROWN()->id() => 17, + DyeColor::BLUE()->id() => 18, + DyeColor::WHITE()->id() => 19 + ]; foreach(DyeColor::getAll() as $color){ //TODO: use colour object directly //TODO: add interface to dye-colour objects - self::register(new Dye(ItemIds::DYE, $dyeMap[$color] ?? $color->getInvertedMagicNumber(), $color->getDisplayName() . " Dye", $color)); + self::register(new Dye(ItemIds::DYE, $dyeMap[$color->id()] ?? $color->getInvertedMagicNumber(), $color->getDisplayName() . " Dye", $color)); self::register(new Bed(ItemIds::BED, $color->getMagicNumber(), $color->getDisplayName() . " Bed", $color)); self::register(new Banner(ItemIds::BANNER, $color->getInvertedMagicNumber(), $color->getDisplayName() . " Banner", $color)); } From 2d4a32fc77c89909bb6bb623ee271f565b93493f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Aug 2019 17:20:34 +0100 Subject: [PATCH 1204/3224] first look at separating Entity and Location --- src/block/Banner.php | 2 +- src/block/Bed.php | 3 +- src/block/Ladder.php | 2 +- src/block/Sign.php | 2 +- src/block/Skull.php | 2 +- src/command/defaults/ParticleCommand.php | 9 +- src/command/defaults/SeedCommand.php | 2 +- src/command/defaults/SetWorldSpawnCommand.php | 5 +- src/command/defaults/SpawnpointCommand.php | 3 +- src/command/defaults/TeleportCommand.php | 14 +- src/entity/Entity.php | 173 ++++++++++-------- src/entity/ExperienceManager.php | 6 +- src/entity/Human.php | 8 +- src/entity/Living.php | 32 ++-- src/entity/Squid.php | 8 +- src/entity/object/ExperienceOrb.php | 10 +- src/entity/object/FallingBlock.php | 13 +- src/entity/object/ItemEntity.php | 4 +- src/entity/object/Painting.php | 6 +- src/entity/object/PrimedTNT.php | 4 +- src/entity/projectile/Arrow.php | 2 +- src/entity/projectile/Egg.php | 2 +- src/entity/projectile/EnderPearl.php | 7 +- src/entity/projectile/ExperienceBottle.php | 6 +- src/entity/projectile/Projectile.php | 22 +-- src/entity/projectile/Snowball.php | 2 +- src/entity/projectile/SplashPotion.php | 12 +- src/item/Bow.php | 9 +- src/item/ChorusFruit.php | 9 +- src/item/ProjectileItem.php | 7 +- src/item/enchantment/KnockbackEnchantment.php | 3 +- src/network/mcpe/NetworkSession.php | 14 +- .../mcpe/handler/InGamePacketHandler.php | 10 +- .../mcpe/handler/PreSpawnPacketHandler.php | 11 +- src/player/Player.php | 129 +++++++------ src/world/Explosion.php | 6 +- 36 files changed, 302 insertions(+), 257 deletions(-) diff --git a/src/block/Banner.php b/src/block/Banner.php index 2163356153..23f0a026a6 100644 --- a/src/block/Banner.php +++ b/src/block/Banner.php @@ -156,7 +156,7 @@ class Banner extends Transparent{ if($face !== Facing::DOWN){ $this->facing = $face; if($face === Facing::UP){ - $this->rotation = $player !== null ? ((int) floor((($player->yaw + 180) * 16 / 360) + 0.5)) & 0x0f : 0; + $this->rotation = $player !== null ? ((int) floor((($player->getLocation()->getYaw() + 180) * 16 / 360) + 0.5)) & 0x0f : 0; } return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/block/Bed.php b/src/block/Bed.php index e8f07dc27c..a8f4cdf47e 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -138,11 +138,12 @@ class Bed extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $other = $this->getOtherHalf(); + $playerPos = $player->getPosition(); if($other === null){ $player->sendMessage(TextFormat::GRAY . "This bed is incomplete"); return true; - }elseif($player->distanceSquared($this->pos) > 4 and $player->distanceSquared($other->pos) > 4){ + }elseif($playerPos->distanceSquared($this->pos) > 4 and $playerPos->distanceSquared($other->pos) > 4){ $player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.tooFar")); return true; } diff --git a/src/block/Ladder.php b/src/block/Ladder.php index 9478bf5bb0..8ff08707e1 100644 --- a/src/block/Ladder.php +++ b/src/block/Ladder.php @@ -66,7 +66,7 @@ class Ladder extends Transparent{ } public function onEntityInside(Entity $entity) : void{ - if($entity->asVector3()->floor()->distanceSquared($this->pos) < 1){ //entity coordinates must be inside block + if($entity->getPosition()->floor()->distanceSquared($this->pos) < 1){ //entity coordinates must be inside block $entity->resetFallDistance(); $entity->onGround = true; } diff --git a/src/block/Sign.php b/src/block/Sign.php index c8c35f5986..88bd8f784c 100644 --- a/src/block/Sign.php +++ b/src/block/Sign.php @@ -118,7 +118,7 @@ class Sign extends Transparent{ if($face !== Facing::DOWN){ $this->facing = $face; if($face === Facing::UP){ - $this->rotation = $player !== null ? ((int) floor((($player->yaw + 180) * 16 / 360) + 0.5)) & 0x0f : 0; + $this->rotation = $player !== null ? ((int) floor((($player->getLocation()->getYaw() + 180) * 16 / 360) + 0.5)) & 0x0f : 0; } return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/block/Skull.php b/src/block/Skull.php index 3d33758b36..e5cd481e91 100644 --- a/src/block/Skull.php +++ b/src/block/Skull.php @@ -108,7 +108,7 @@ class Skull extends Flowable{ $this->skullType = $item->getSkullType(); //TODO: the item should handle this, but this hack is currently needed because of tile mess } if($player !== null and $face === Facing::UP){ - $this->rotation = ((int) floor(($player->yaw * 16 / 360) + 0.5)) & 0xf; + $this->rotation = ((int) floor(($player->getLocation()->getYaw() * 16 / 360) + 0.5)) & 0xf; } return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/command/defaults/ParticleCommand.php b/src/command/defaults/ParticleCommand.php index 22afc6dc67..6a2c380f97 100644 --- a/src/command/defaults/ParticleCommand.php +++ b/src/command/defaults/ParticleCommand.php @@ -91,11 +91,12 @@ class ParticleCommand extends VanillaCommand{ } if($sender instanceof Player){ - $world = $sender->getWorld(); + $senderPos = $sender->getPosition(); + $world = $senderPos->getWorld(); $pos = new Vector3( - $this->getRelativeDouble($sender->getX(), $sender, $args[1]), - $this->getRelativeDouble($sender->getY(), $sender, $args[2], 0, World::Y_MAX), - $this->getRelativeDouble($sender->getZ(), $sender, $args[3]) + $this->getRelativeDouble($senderPos->getX(), $sender, $args[1]), + $this->getRelativeDouble($senderPos->getY(), $sender, $args[2], 0, World::Y_MAX), + $this->getRelativeDouble($senderPos->getZ(), $sender, $args[3]) ); }else{ $world = $sender->getServer()->getWorldManager()->getDefaultWorld(); diff --git a/src/command/defaults/SeedCommand.php b/src/command/defaults/SeedCommand.php index 1ce522ff6d..29017edb51 100644 --- a/src/command/defaults/SeedCommand.php +++ b/src/command/defaults/SeedCommand.php @@ -44,7 +44,7 @@ class SeedCommand extends VanillaCommand{ } if($sender instanceof Player){ - $seed = $sender->getWorld()->getSeed(); + $seed = $sender->getPosition()->getWorld()->getSeed(); }else{ $seed = $sender->getServer()->getWorldManager()->getDefaultWorld()->getSeed(); } diff --git a/src/command/defaults/SetWorldSpawnCommand.php b/src/command/defaults/SetWorldSpawnCommand.php index 641de76b2e..45534184ac 100644 --- a/src/command/defaults/SetWorldSpawnCommand.php +++ b/src/command/defaults/SetWorldSpawnCommand.php @@ -51,8 +51,9 @@ class SetWorldSpawnCommand extends VanillaCommand{ if(count($args) === 0){ if($sender instanceof Player){ - $world = $sender->getWorld(); - $pos = (new Vector3($sender->x, $sender->y, $sender->z))->round(); + $location = $sender->getPosition(); + $world = $location->getWorld(); + $pos = $location->asVector3()->round(); }else{ $sender->sendMessage(TextFormat::RED . "You can only perform this command as a player"); diff --git a/src/command/defaults/SpawnpointCommand.php b/src/command/defaults/SpawnpointCommand.php index 071433b3b4..91813c24c8 100644 --- a/src/command/defaults/SpawnpointCommand.php +++ b/src/command/defaults/SpawnpointCommand.php @@ -82,7 +82,8 @@ class SpawnpointCommand extends VanillaCommand{ return true; }elseif(count($args) <= 1){ if($sender instanceof Player){ - $pos = new Position($sender->getFloorX(), $sender->getFloorY(), $sender->getFloorZ(), $sender->getWorld()); + $cpos = $sender->getPosition(); + $pos = Position::fromObject($cpos->floor(), $cpos->getWorld()); $target->setSpawn($pos); Command::broadcastCommandMessage($sender, new TranslationContainer("commands.spawnpoint.success", [$target->getName(), round($pos->x, 2), round($pos->y, 2), round($pos->z, 2)])); diff --git a/src/command/defaults/TeleportCommand.php b/src/command/defaults/TeleportCommand.php index 512ce095da..9494546d42 100644 --- a/src/command/defaults/TeleportCommand.php +++ b/src/command/defaults/TeleportCommand.php @@ -96,8 +96,10 @@ class TeleportCommand extends VanillaCommand{ } } + $targetLocation = $target->getLocation(); + if(count($args) < 3){ - $origin->teleport($target); + $origin->teleport($targetLocation); Command::broadcastCommandMessage($sender, new TranslationContainer("commands.tp.success", [$origin->getName(), $target->getName()])); return true; @@ -108,11 +110,11 @@ class TeleportCommand extends VanillaCommand{ $pos = 0; } - $x = $this->getRelativeDouble($target->x, $sender, $args[$pos++]); - $y = $this->getRelativeDouble($target->y, $sender, $args[$pos++], 0, 256); - $z = $this->getRelativeDouble($target->z, $sender, $args[$pos++]); - $yaw = $target->getYaw(); - $pitch = $target->getPitch(); + $x = $this->getRelativeDouble($targetLocation->x, $sender, $args[$pos++]); + $y = $this->getRelativeDouble($targetLocation->y, $sender, $args[$pos++], 0, 256); + $z = $this->getRelativeDouble($targetLocation->z, $sender, $args[$pos++]); + $yaw = $targetLocation->getYaw(); + $pitch = $targetLocation->getPitch(); if(count($args) === 6 or (count($args) === 5 and $pos === 3)){ $yaw = (float) $args[$pos++]; diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 9ef45a078d..d2e54ed58e 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -59,7 +59,6 @@ use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; use pocketmine\world\format\Chunk; -use pocketmine\entity\Location; use pocketmine\world\Position; use pocketmine\world\World; use function abs; @@ -77,7 +76,7 @@ use function sin; use function spl_object_id; use const M_PI_2; -abstract class Entity extends Location{ +abstract class Entity{ public const MOTION_THRESHOLD = 0.00001; @@ -103,6 +102,8 @@ abstract class Entity extends Location{ /** @var Block[] */ protected $blocksAround = []; + /** @var Location */ + protected $location; /** @var Location */ protected $lastLocation; /** @var Vector3 */ @@ -240,13 +241,17 @@ abstract class Entity extends Location{ /** @var float[] $rotation */ $rotation = $nbt->getListTag("Rotation")->getAllValues(); - parent::__construct($pos[0], $pos[1], $pos[2], $rotation[0], $rotation[1], $world); - assert(!is_nan($this->x) and !is_infinite($this->x) and !is_nan($this->y) and !is_infinite($this->y) and !is_nan($this->z) and !is_infinite($this->z)); + $this->location = new Location($pos[0], $pos[1], $pos[2], $rotation[0], $rotation[1], $world); + assert( + !is_nan($this->location->x) and !is_infinite($this->location->x) and + !is_nan($this->location->y) and !is_infinite($this->location->y) and + !is_nan($this->location->z) and !is_infinite($this->location->z) + ); $this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0); $this->recalculateBoundingBox(); - $this->chunk = $this->world->getChunkAtPosition($this, false); + $this->chunk = $this->getWorld()->getChunkAtPosition($this->location, false); if($this->chunk === null){ throw new \InvalidStateException("Cannot create entities in unloaded chunks"); } @@ -268,7 +273,7 @@ abstract class Entity extends Location{ $this->initEntity($nbt); $this->chunk->addEntity($this); - $this->world->addEntity($this); + $this->getWorld()->addEntity($this); $this->lastUpdate = $this->server->getTick(); (new EntitySpawnEvent($this))->call(); @@ -366,12 +371,12 @@ abstract class Entity extends Location{ $halfWidth = $this->width / 2; $this->boundingBox = new AxisAlignedBB( - $this->x - $halfWidth, - $this->y, - $this->z - $halfWidth, - $this->x + $halfWidth, - $this->y + $this->height, - $this->z + $halfWidth + $this->location->x - $halfWidth, + $this->location->y, + $this->location->z - $halfWidth, + $this->location->x + $halfWidth, + $this->location->y + $this->height, + $this->location->z + $halfWidth ); } @@ -544,9 +549,9 @@ abstract class Entity extends Location{ } $nbt->setTag("Pos", new ListTag([ - new DoubleTag($this->x), - new DoubleTag($this->y), - new DoubleTag($this->z) + new DoubleTag($this->location->x), + new DoubleTag($this->location->y), + new DoubleTag($this->location->z) ])); $nbt->setTag("Motion", new ListTag([ @@ -556,8 +561,8 @@ abstract class Entity extends Location{ ])); $nbt->setTag("Rotation", new ListTag([ - new FloatTag($this->yaw), - new FloatTag($this->pitch) + new FloatTag($this->location->yaw), + new FloatTag($this->location->pitch) ])); $nbt->setFloat("FallDistance", $this->fallDistance); @@ -727,7 +732,7 @@ abstract class Entity extends Location{ $this->checkBlockCollision(); - if($this->y <= -16 and $this->isAlive()){ + if($this->location->y <= -16 and $this->isAlive()){ $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_VOID, 10); $this->attack($ev); $hasUpdate = true; @@ -826,13 +831,13 @@ abstract class Entity extends Location{ //TODO: hack for client-side AI interference: prevent client sided movement when motion is 0 $this->setImmobile($this->motion->x == 0 and $this->motion->y == 0 and $this->motion->z == 0); - $diffPosition = $this->distanceSquared($this->lastLocation); - $diffRotation = ($this->yaw - $this->lastLocation->yaw) ** 2 + ($this->pitch - $this->lastLocation->pitch) ** 2; + $diffPosition = $this->location->distanceSquared($this->lastLocation); + $diffRotation = ($this->location->yaw - $this->lastLocation->yaw) ** 2 + ($this->location->pitch - $this->lastLocation->pitch) ** 2; $diffMotion = $this->motion->subtract($this->lastMotion)->lengthSquared(); if($teleport or $diffPosition > 0.0001 or $diffRotation > 1.0){ - $this->lastLocation = $this->asLocation(); + $this->lastLocation = $this->location->asLocation(); $this->broadcastMovement($teleport); } @@ -851,24 +856,24 @@ abstract class Entity extends Location{ protected function broadcastMovement(bool $teleport = false) : void{ $pk = new MoveActorAbsolutePacket(); $pk->entityRuntimeId = $this->id; - $pk->position = $this->getOffsetPosition($this); + $pk->position = $this->getOffsetPosition($this->location); //this looks very odd but is correct as of 1.5.0.7 //for arrows this is actually x/y/z rotation //for mobs x and z are used for pitch and yaw, and y is used for headyaw - $pk->xRot = $this->pitch; - $pk->yRot = $this->yaw; //TODO: head yaw - $pk->zRot = $this->yaw; + $pk->xRot = $this->location->pitch; + $pk->yRot = $this->location->yaw; //TODO: head yaw + $pk->zRot = $this->location->yaw; if($teleport){ $pk->flags |= MoveActorAbsolutePacket::FLAG_TELEPORT; } - $this->world->broadcastPacketToViewers($this, $pk); + $this->getWorld()->broadcastPacketToViewers($this->location, $pk); } protected function broadcastMotion() : void{ - $this->world->broadcastPacketToViewers($this, SetActorMotionPacket::create($this->id, $this->getMotion())); + $this->getWorld()->broadcastPacketToViewers($this->location, SetActorMotionPacket::create($this->id, $this->getMotion())); } public function hasGravity() : bool{ @@ -903,7 +908,7 @@ abstract class Entity extends Location{ } if($this->onGround){ - $friction *= $this->world->getBlockAt((int) floor($this->x), (int) floor($this->y - 1), (int) floor($this->z))->getFrictionFactor(); + $friction *= $this->getWorld()->getBlockAt((int) floor($this->location->x), (int) floor($this->location->y - 1), (int) floor($this->location->z))->getFrictionFactor(); } $this->motion->x *= $friction; @@ -911,7 +916,8 @@ abstract class Entity extends Location{ } protected function checkObstruction(float $x, float $y, float $z) : bool{ - if(count($this->world->getCollisionBoxes($this, $this->getBoundingBox(), false)) === 0){ + $world = $this->getWorld(); + if(count($world->getCollisionBoxes($this, $this->getBoundingBox(), false)) === 0){ return false; } @@ -923,13 +929,13 @@ abstract class Entity extends Location{ $diffY = $y - $floorY; $diffZ = $z - $floorZ; - if($this->world->getBlockAt($floorX, $floorY, $floorZ)->isSolid()){ - $westNonSolid = !$this->world->getBlockAt($floorX - 1, $floorY, $floorZ)->isSolid(); - $eastNonSolid = !$this->world->getBlockAt($floorX + 1, $floorY, $floorZ)->isSolid(); - $downNonSolid = !$this->world->getBlockAt($floorX, $floorY - 1, $floorZ)->isSolid(); - $upNonSolid = !$this->world->getBlockAt($floorX, $floorY + 1, $floorZ)->isSolid(); - $northNonSolid = !$this->world->getBlockAt($floorX, $floorY, $floorZ - 1)->isSolid(); - $southNonSolid = !$this->world->getBlockAt($floorX, $floorY, $floorZ + 1)->isSolid(); + if($world->getBlockAt($floorX, $floorY, $floorZ)->isSolid()){ + $westNonSolid = !$world->getBlockAt($floorX - 1, $floorY, $floorZ)->isSolid(); + $eastNonSolid = !$world->getBlockAt($floorX + 1, $floorY, $floorZ)->isSolid(); + $downNonSolid = !$world->getBlockAt($floorX, $floorY - 1, $floorZ)->isSolid(); + $upNonSolid = !$world->getBlockAt($floorX, $floorY + 1, $floorZ)->isSolid(); + $northNonSolid = !$world->getBlockAt($floorX, $floorY, $floorZ - 1)->isSolid(); + $southNonSolid = !$world->getBlockAt($floorX, $floorY, $floorZ + 1)->isSolid(); $direction = -1; $limit = 9999; @@ -1006,7 +1012,7 @@ abstract class Entity extends Location{ } public function getHorizontalFacing() : int{ - $angle = $this->yaw % 360; + $angle = $this->location->yaw % 360; if($angle < 0){ $angle += 360.0; } @@ -1028,16 +1034,16 @@ abstract class Entity extends Location{ * @return Vector3 */ public function getDirectionVector() : Vector3{ - $y = -sin(deg2rad($this->pitch)); - $xz = cos(deg2rad($this->pitch)); - $x = -$xz * sin(deg2rad($this->yaw)); - $z = $xz * cos(deg2rad($this->yaw)); + $y = -sin(deg2rad($this->location->pitch)); + $xz = cos(deg2rad($this->location->pitch)); + $x = -$xz * sin(deg2rad($this->location->yaw)); + $z = $xz * cos(deg2rad($this->location->yaw)); return $this->temporalVector->setComponents($x, $y, $z)->normalize(); } public function getDirectionPlane() : Vector2{ - return (new Vector2(-cos(deg2rad($this->yaw) - M_PI_2), -sin(deg2rad($this->yaw) - M_PI_2)))->normalize(); + return (new Vector2(-cos(deg2rad($this->location->yaw) - M_PI_2), -sin(deg2rad($this->location->yaw) - M_PI_2)))->normalize(); } public function onUpdate(int $currentTick) : bool{ @@ -1105,7 +1111,7 @@ abstract class Entity extends Location{ if($this->closed){ throw new \InvalidStateException("Cannot schedule update on garbage entity " . get_class($this)); } - $this->world->updateEntities[$this->id] = $this; + $this->getWorld()->updateEntities[$this->id] = $this; } public function onNearbyBlockChange() : void{ @@ -1172,7 +1178,7 @@ abstract class Entity extends Location{ } public function getEyePos() : Vector3{ - return new Vector3($this->x, $this->y + $this->getEyeHeight(), $this->z); + return new Vector3($this->location->x, $this->location->y + $this->getEyeHeight(), $this->location->z); } public function onCollideWithPlayer(Player $player) : void{ @@ -1180,7 +1186,7 @@ abstract class Entity extends Location{ } public function isUnderwater() : bool{ - $block = $this->world->getBlockAt((int) floor($this->x), $blockY = (int) floor($y = ($this->y + $this->getEyeHeight())), (int) floor($this->z)); + $block = $this->getWorld()->getBlockAt((int) floor($this->location->x), $blockY = (int) floor($y = ($this->location->y + $this->getEyeHeight())), (int) floor($this->location->z)); if($block instanceof Water){ $f = ($blockY + 1) - ($block->getFluidHeightPercent() - 0.1111111); @@ -1191,7 +1197,7 @@ abstract class Entity extends Location{ } public function isInsideOfSolid() : bool{ - $block = $this->world->getBlockAt((int) floor($this->x), (int) floor($y = ($this->y + $this->getEyeHeight())), (int) floor($this->z)); + $block = $this->getWorld()->getBlockAt((int) floor($this->location->x), (int) floor($y = ($this->location->y + $this->getEyeHeight())), (int) floor($this->location->z)); return $block->isSolid() and !$block->isTransparent() and $block->collidesWithBB($this->getBoundingBox()); } @@ -1252,7 +1258,7 @@ abstract class Entity extends Location{ assert(abs($dx) <= 20 and abs($dy) <= 20 and abs($dz) <= 20, "Movement distance is excessive: dx=$dx, dy=$dy, dz=$dz"); - $list = $this->world->getCollisionBoxes($this, $moveBB->addCoord($dx, $dy, $dz), false); + $list = $this->getWorld()->getCollisionBoxes($this, $moveBB->addCoord($dx, $dy, $dz), false); foreach($list as $bb){ $dy = $bb->calculateYOffset($moveBB, $dy); @@ -1285,8 +1291,7 @@ abstract class Entity extends Location{ $stepBB = clone $this->boundingBox; - $list = $this->world->getCollisionBoxes($this, $stepBB->addCoord($dx, $dy, $dz), false); - + $list = $this->getWorld()->getCollisionBoxes($this, $stepBB->addCoord($dx, $dy, $dz), false); foreach($list as $bb){ $dy = $bb->calculateYOffset($stepBB, $dy); } @@ -1318,9 +1323,9 @@ abstract class Entity extends Location{ $this->boundingBox = $moveBB; } - $this->x = ($this->boundingBox->minX + $this->boundingBox->maxX) / 2; - $this->y = $this->boundingBox->minY - $this->ySize; - $this->z = ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2; + $this->location->x = ($this->boundingBox->minX + $this->boundingBox->maxX) / 2; + $this->location->y = $this->boundingBox->minY - $this->ySize; + $this->location->z = ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2; $this->checkChunks(); $this->checkBlockCollision(); @@ -1370,10 +1375,12 @@ abstract class Entity extends Location{ $this->blocksAround = []; + $world = $this->getWorld(); + for($z = $minZ; $z <= $maxZ; ++$z){ for($x = $minX; $x <= $maxX; ++$x){ for($y = $minY; $y <= $maxY; ++$y){ - $block = $this->world->getBlockAt($x, $y, $z); + $block = $world->getBlockAt($x, $y, $z); if($block->hasEntityCollision()){ $this->blocksAround[] = $block; } @@ -1412,11 +1419,15 @@ abstract class Entity extends Location{ } public function getPosition() : Position{ - return $this->asPosition(); + return $this->location->asPosition(); } public function getLocation() : Location{ - return $this->asLocation(); + return $this->location->asLocation(); + } + + public function getWorld() : World{ + return $this->location->getWorld(); } protected function setPosition(Vector3 $pos) : bool{ @@ -1424,15 +1435,15 @@ abstract class Entity extends Location{ return false; } - if($pos instanceof Position and $pos->world !== null and $pos->world !== $this->world){ + if($pos instanceof Position and $pos->world !== null and $pos->world !== $this->getWorld()){ if(!$this->switchWorld($pos->getWorld())){ return false; } } - $this->x = $pos->x; - $this->y = $pos->y; - $this->z = $pos->z; + $this->location->x = $pos->x; + $this->location->y = $pos->y; + $this->location->z = $pos->z; $this->recalculateBoundingBox(); @@ -1444,8 +1455,8 @@ abstract class Entity extends Location{ } public function setRotation(float $yaw, float $pitch) : void{ - $this->yaw = $yaw; - $this->pitch = $pitch; + $this->location->yaw = $yaw; + $this->location->pitch = $pitch; $this->scheduleUpdate(); } @@ -1460,16 +1471,16 @@ abstract class Entity extends Location{ } protected function checkChunks() : void{ - $chunkX = $this->getFloorX() >> 4; - $chunkZ = $this->getFloorZ() >> 4; + $chunkX = $this->location->getFloorX() >> 4; + $chunkZ = $this->location->getFloorZ() >> 4; if($this->chunk === null or ($this->chunk->getX() !== $chunkX or $this->chunk->getZ() !== $chunkZ)){ if($this->chunk !== null){ $this->chunk->removeEntity($this); } - $this->chunk = $this->world->getChunk($chunkX, $chunkZ, true); + $this->chunk = $this->getWorld()->getChunk($chunkX, $chunkZ, true); if(!$this->justCreated){ - $newChunk = $this->world->getViewersForPosition($this); + $newChunk = $this->getWorld()->getViewersForPosition($this->location); foreach($this->hasSpawned as $player){ if(!isset($newChunk[spl_object_id($player)])){ $this->despawnFrom($player); @@ -1491,7 +1502,7 @@ abstract class Entity extends Location{ } protected function resetLastMovements() : void{ - $this->lastLocation = $this->asLocation(); + $this->lastLocation = $this->location->asLocation(); $this->lastMotion = clone $this->motion; } @@ -1546,8 +1557,8 @@ abstract class Entity extends Location{ $yaw = $yaw ?? $pos->yaw; $pitch = $pitch ?? $pos->pitch; } - $from = Position::fromObject($this, $this->world); - $to = Position::fromObject($pos, $pos instanceof Position ? $pos->getWorld() : $this->world); + $from = $this->location->asPosition(); + $to = Position::fromObject($pos, $pos instanceof Position ? $pos->getWorld() : $this->getWorld()); $ev = new EntityTeleportEvent($this, $from, $to); $ev->call(); if($ev->isCancelled()){ @@ -1557,7 +1568,7 @@ abstract class Entity extends Location{ $pos = $ev->getTo(); $this->setMotion($this->temporalVector->setComponents(0, 0, 0)); - if($this->setPositionAndRotation($pos, $yaw ?? $this->yaw, $pitch ?? $this->pitch)){ + if($this->setPositionAndRotation($pos, $yaw ?? $this->location->yaw, $pitch ?? $this->location->pitch)){ $this->resetFallDistance(); $this->onGround = true; @@ -1574,16 +1585,16 @@ abstract class Entity extends Location{ return false; } - if($this->isValid()){ - $this->world->removeEntity($this); + if($this->location->isValid()){ + $this->getWorld()->removeEntity($this); if($this->chunk !== null){ $this->chunk->removeEntity($this); } $this->despawnFromAll(); } - $this->setWorld($targetWorld); - $this->world->addEntity($this); + $this->location->setWorld($targetWorld); + $this->getWorld()->addEntity($this); $this->chunk = null; return true; @@ -1609,11 +1620,11 @@ abstract class Entity extends Location{ $pk = new AddActorPacket(); $pk->entityRuntimeId = $this->getId(); $pk->type = static::NETWORK_ID; - $pk->position = $this->asVector3(); + $pk->position = $this->location->asVector3(); $pk->motion = $this->getMotion(); - $pk->yaw = $this->yaw; - $pk->headYaw = $this->yaw; //TODO - $pk->pitch = $this->pitch; + $pk->yaw = $this->location->yaw; + $pk->headYaw = $this->location->yaw; //TODO + $pk->pitch = $this->location->pitch; $pk->attributes = $this->attributeMap->getAll(); $pk->metadata = $this->getSyncedNetworkData(false); @@ -1636,7 +1647,7 @@ abstract class Entity extends Location{ if($this->closed){ return; } - foreach($this->world->getViewersForPosition($this) as $player){ + foreach($this->getWorld()->getViewersForPosition($this->location) as $player){ $this->spawnTo($player); } } @@ -1719,8 +1730,8 @@ abstract class Entity extends Location{ if($this->chunk !== null){ $this->chunk->removeEntity($this); } - if($this->isValid()){ - $this->world->removeEntity($this); + if($this->location->isValid()){ + $this->getWorld()->removeEntity($this); } } @@ -1732,7 +1743,7 @@ abstract class Entity extends Location{ */ protected function destroyCycles() : void{ $this->chunk = null; - $this->setWorld(null); + $this->location->setWorld(null); $this->lastDamageCause = null; } diff --git a/src/entity/ExperienceManager.php b/src/entity/ExperienceManager.php index 1c963c43c7..1d280812dd 100644 --- a/src/entity/ExperienceManager.php +++ b/src/entity/ExperienceManager.php @@ -95,7 +95,7 @@ class ExperienceManager{ if($playSound){ $newLevel = $this->getXpLevel(); if((int) ($newLevel / 5) > (int) ($oldLevel / 5)){ - $this->entity->getWorld()->addSound($this->entity->asVector3(), new XpLevelUpSound($newLevel)); + $this->entity->getWorld()->addSound($this->entity->getPosition(), new XpLevelUpSound($newLevel)); } } @@ -187,9 +187,9 @@ class ExperienceManager{ if($playSound){ $newLevel = $this->getXpLevel(); if((int) ($newLevel / 5) > (int) ($oldLevel / 5)){ - $this->entity->getWorld()->addSound($this->entity->asVector3(), new XpLevelUpSound($newLevel)); + $this->entity->getWorld()->addSound($this->entity->getPosition(), new XpLevelUpSound($newLevel)); }elseif($this->getCurrentTotalXp() > $oldTotal){ - $this->entity->getWorld()->addSound($this->entity->asVector3(), new XpCollectSound()); + $this->entity->getWorld()->addSound($this->entity->getPosition(), new XpCollectSound()); } } diff --git a/src/entity/Human.php b/src/entity/Human.php index 838b0c6bb8..8a7eca6e3f 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -316,7 +316,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $this->effectManager->add(new EffectInstance(VanillaEffects::ABSORPTION(), 5 * 20, 1)); $this->broadcastEntityEvent(ActorEventPacket::CONSUME_TOTEM); - $this->world->addSound($this->add(0, $this->eyeHeight, 0), new TotemUseSound()); + $this->getWorld()->addSound($this->location->add(0, $this->eyeHeight, 0), new TotemUseSound()); $hand = $this->inventory->getItemInHand(); if($hand instanceof Totem){ @@ -412,10 +412,10 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $pk->uuid = $this->getUniqueId(); $pk->username = $this->getName(); $pk->entityRuntimeId = $this->getId(); - $pk->position = $this->asVector3(); + $pk->position = $this->location->asVector3(); $pk->motion = $this->getMotion(); - $pk->yaw = $this->yaw; - $pk->pitch = $this->pitch; + $pk->yaw = $this->location->yaw; + $pk->pitch = $this->location->pitch; $pk->item = $this->getInventory()->getItemInHand(); $pk->metadata = $this->getSyncedNetworkData(false); $player->sendDataPacket($pk); diff --git a/src/entity/Living.php b/src/entity/Living.php index 7770bd5f39..269f242a7b 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -380,7 +380,7 @@ abstract class Living extends Entity{ private function damageItem(Durable $item, int $durabilityRemoved) : void{ $item->applyDamage($durabilityRemoved); if($item->isBroken()){ - $this->world->addSound($this, new ItemBreakSound()); + $this->getWorld()->addSound($this->location, new ItemBreakSound()); } } @@ -434,11 +434,11 @@ abstract class Living extends Entity{ $source->getCause() === EntityDamageEvent::CAUSE_PROJECTILE or $source->getCause() === EntityDamageEvent::CAUSE_ENTITY_ATTACK ) and $e->isOnFire()){ - $this->setOnFire(2 * $this->world->getDifficulty()); + $this->setOnFire(2 * $this->getWorld()->getDifficulty()); } - $deltaX = $this->x - $e->x; - $deltaZ = $this->z - $e->z; + $deltaX = $this->location->x - $e->location->x; + $deltaZ = $this->location->z - $e->location->z; $this->knockBack($deltaX, $deltaZ, $source->getKnockBack()); } } @@ -482,11 +482,11 @@ abstract class Living extends Entity{ $ev = new EntityDeathEvent($this, $this->getDrops(), $this->getXpDropAmount()); $ev->call(); foreach($ev->getDrops() as $item){ - $this->getWorld()->dropItem($this, $item); + $this->getWorld()->dropItem($this->location, $item); } //TODO: check death conditions (must have been damaged by player < 5 seconds from death) - $this->world->dropExperience($this, $ev->getXpDropAmount()); + $this->getWorld()->dropExperience($this->location, $ev->getXpDropAmount()); $this->startDeathAnimation(); } @@ -684,8 +684,8 @@ abstract class Living extends Entity{ $blocks = []; $nextIndex = 0; - foreach(VoxelRayTrace::inDirection($this->add(0, $this->eyeHeight, 0), $this->getDirectionVector(), $maxDistance) as $vector3){ - $block = $this->world->getBlockAt($vector3->x, $vector3->y, $vector3->z); + foreach(VoxelRayTrace::inDirection($this->location->add(0, $this->eyeHeight, 0), $this->getDirectionVector(), $maxDistance) as $vector3){ + $block = $this->getWorld()->getBlockAt($vector3->x, $vector3->y, $vector3->z); $blocks[$nextIndex++] = $block; if($maxLength !== 0 and count($blocks) > $maxLength){ @@ -731,15 +731,15 @@ abstract class Living extends Entity{ * @param Vector3 $target */ public function lookAt(Vector3 $target) : void{ - $horizontal = sqrt(($target->x - $this->x) ** 2 + ($target->z - $this->z) ** 2); - $vertical = $target->y - $this->y; - $this->pitch = -atan2($vertical, $horizontal) / M_PI * 180; //negative is up, positive is down + $horizontal = sqrt(($target->x - $this->location->x) ** 2 + ($target->z - $this->location->z) ** 2); + $vertical = $target->y - $this->location->y; + $this->location->pitch = -atan2($vertical, $horizontal) / M_PI * 180; //negative is up, positive is down - $xDist = $target->x - $this->x; - $zDist = $target->z - $this->z; - $this->yaw = atan2($zDist, $xDist) / M_PI * 180 - 90; - if($this->yaw < 0){ - $this->yaw += 360.0; + $xDist = $target->x - $this->location->x; + $zDist = $target->z - $this->location->z; + $this->location->yaw = atan2($zDist, $xDist) / M_PI * 180 - 90; + if($this->location->yaw < 0){ + $this->location->yaw += 360.0; } } diff --git a/src/entity/Squid.php b/src/entity/Squid.php index d2e5cc00e4..e428868c9b 100644 --- a/src/entity/Squid.php +++ b/src/entity/Squid.php @@ -66,7 +66,7 @@ class Squid extends WaterAnimal{ $this->swimSpeed = mt_rand(150, 350) / 2000; $e = $source->getDamager(); if($e !== null){ - $this->swimDirection = (new Vector3($this->x - $e->x, $this->y - $e->y, $this->z - $e->z))->normalize(); + $this->swimDirection = $this->location->subtract($e->location)->normalize(); } $this->broadcastEntityEvent(ActorEventPacket::SQUID_INK_CLOUD); @@ -94,7 +94,7 @@ class Squid extends WaterAnimal{ if($this->isAlive()){ - if($this->y > 62 and $this->swimDirection !== null){ + if($this->location->y > 62 and $this->swimDirection !== null){ $this->swimDirection->y = -0.5; } @@ -112,8 +112,8 @@ class Squid extends WaterAnimal{ } $f = sqrt(($this->motion->x ** 2) + ($this->motion->z ** 2)); - $this->yaw = (-atan2($this->motion->x, $this->motion->z) * 180 / M_PI); - $this->pitch = (-atan2($f, $this->motion->y) * 180 / M_PI); + $this->location->yaw = (-atan2($this->motion->x, $this->motion->z) * 180 / M_PI); + $this->location->pitch = (-atan2($f, $this->motion->y) * 180 / M_PI); } return $hasUpdate; diff --git a/src/entity/object/ExperienceOrb.php b/src/entity/object/ExperienceOrb.php index 391a3351f5..0fce9180db 100644 --- a/src/entity/object/ExperienceOrb.php +++ b/src/entity/object/ExperienceOrb.php @@ -156,7 +156,7 @@ class ExperienceOrb extends Entity{ return null; } - $entity = $this->world->getEntity($this->targetPlayerRuntimeId); + $entity = $this->getWorld()->getEntity($this->targetPlayerRuntimeId); if($entity instanceof Human){ return $entity; } @@ -178,13 +178,13 @@ class ExperienceOrb extends Entity{ } $currentTarget = $this->getTargetPlayer(); - if($currentTarget !== null and (!$currentTarget->isAlive() or $currentTarget->distanceSquared($this) > self::MAX_TARGET_DISTANCE ** 2)){ + if($currentTarget !== null and (!$currentTarget->isAlive() or $currentTarget->location->distanceSquared($this->location) > self::MAX_TARGET_DISTANCE ** 2)){ $currentTarget = null; } if($this->lookForTargetTime >= 20){ if($currentTarget === null){ - $newTarget = $this->world->getNearestEntity($this, self::MAX_TARGET_DISTANCE, Human::class); + $newTarget = $this->getWorld()->getNearestEntity($this->location, self::MAX_TARGET_DISTANCE, Human::class); if($newTarget instanceof Human and !($newTarget instanceof Player and $newTarget->isSpectator())){ $currentTarget = $newTarget; @@ -199,7 +199,7 @@ class ExperienceOrb extends Entity{ $this->setTargetPlayer($currentTarget); if($currentTarget !== null){ - $vector = $currentTarget->add(0, $currentTarget->getEyeHeight() / 2, 0)->subtract($this)->divide(self::MAX_TARGET_DISTANCE); + $vector = $currentTarget->getPosition()->add(0, $currentTarget->getEyeHeight() / 2, 0)->subtract($this)->divide(self::MAX_TARGET_DISTANCE); $distance = $vector->lengthSquared(); if($distance < 1){ @@ -221,7 +221,7 @@ class ExperienceOrb extends Entity{ } protected function tryChangeMovement() : void{ - $this->checkObstruction($this->x, $this->y, $this->z); + $this->checkObstruction($this->location->x, $this->location->y, $this->location->z); parent::tryChangeMovement(); } diff --git a/src/entity/object/FallingBlock.php b/src/entity/object/FallingBlock.php index 4fad1c482a..fe23efbcf9 100644 --- a/src/entity/object/FallingBlock.php +++ b/src/entity/object/FallingBlock.php @@ -96,9 +96,10 @@ class FallingBlock extends Entity{ $hasUpdate = parent::entityBaseTick($tickDiff); if(!$this->isFlaggedForDespawn()){ - $pos = $this->add(-$this->width / 2, $this->height, -$this->width / 2)->floor(); + $world = $this->getWorld(); + $pos = $this->location->add(-$this->width / 2, $this->height, -$this->width / 2)->floor(); - $this->block->position($this->world, $pos->x, $pos->y, $pos->z); + $this->block->position($world, $pos->x, $pos->y, $pos->z); $blockTarget = null; if($this->block instanceof Fallable){ @@ -108,15 +109,15 @@ class FallingBlock extends Entity{ if($this->onGround or $blockTarget !== null){ $this->flagForDespawn(); - $block = $this->world->getBlock($pos); - if(($block->isTransparent() and !$block->canBeReplaced()) or !$this->world->isInWorld($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ()) or ($this->onGround and abs($this->y - $this->getFloorY()) > 0.001)){ + $block = $world->getBlock($pos); + if(($block->isTransparent() and !$block->canBeReplaced()) or !$world->isInWorld($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ()) or ($this->onGround and abs($this->location->y - $this->location->getFloorY()) > 0.001)){ //FIXME: anvils are supposed to destroy torches - $this->getWorld()->dropItem($this, $this->block->asItem()); + $world->dropItem($this->location, $this->block->asItem()); }else{ $ev = new EntityBlockChangeEvent($this, $block, $blockTarget ?? $this->block); $ev->call(); if(!$ev->isCancelled()){ - $this->getWorld()->setBlock($pos, $ev->getTo()); + $world->setBlock($pos, $ev->getTo()); } } $hasUpdate = true; diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index 421db601af..2cda0ca329 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -125,7 +125,7 @@ class ItemEntity extends Entity{ } protected function tryChangeMovement() : void{ - $this->checkObstruction($this->x, $this->y, $this->z); + $this->checkObstruction($this->location->x, $this->location->y, $this->location->z); parent::tryChangeMovement(); } @@ -235,7 +235,7 @@ class ItemEntity extends Entity{ protected function sendSpawnPacket(Player $player) : void{ $pk = new AddItemActorPacket(); $pk->entityRuntimeId = $this->getId(); - $pk->position = $this->asVector3(); + $pk->position = $this->location->asVector3(); $pk->motion = $this->getMotion(); $pk->item = $this->getItem(); $pk->metadata = $this->getSyncedNetworkData(false); diff --git a/src/entity/object/Painting.php b/src/entity/object/Painting.php index 01a07d9f6a..8e96e3982d 100644 --- a/src/entity/object/Painting.php +++ b/src/entity/object/Painting.php @@ -118,9 +118,9 @@ class Painting extends Entity{ if($drops){ //non-living entities don't have a way to create drops generically yet - $this->world->dropItem($this, VanillaItems::PAINTING()); + $this->getWorld()->dropItem($this->location, VanillaItems::PAINTING()); } - $this->world->addParticle($this->add(0.5, 0.5, 0.5), new DestroyBlockParticle(VanillaBlocks::OAK_PLANKS())); + $this->getWorld()->addParticle($this->location->add(0.5, 0.5, 0.5), new DestroyBlockParticle(VanillaBlocks::OAK_PLANKS())); } protected function recalculateBoundingBox() : void{ @@ -131,7 +131,7 @@ class Painting extends Entity{ public function onNearbyBlockChange() : void{ parent::onNearbyBlockChange(); - if(!self::canFit($this->world, $this->blockIn->getSide($this->facing), $this->facing, false, $this->getMotive())){ + if(!self::canFit($this->getWorld(), $this->blockIn->getSide($this->facing), $this->facing, false, $this->getMotive())){ $this->kill(); } } diff --git a/src/entity/object/PrimedTNT.php b/src/entity/object/PrimedTNT.php index 6375dd3ba2..09cc708612 100644 --- a/src/entity/object/PrimedTNT.php +++ b/src/entity/object/PrimedTNT.php @@ -62,7 +62,7 @@ class PrimedTNT extends Entity implements Explosive{ $this->fuse = $nbt->getShort("Fuse", 80, true); - $this->world->addSound($this, new IgniteSound()); + $this->getWorld()->addSound($this->location, new IgniteSound()); } @@ -100,7 +100,7 @@ class PrimedTNT extends Entity implements Explosive{ $ev = new ExplosionPrimeEvent($this, 4); $ev->call(); if(!$ev->isCancelled()){ - $explosion = new Explosion(Position::fromObject($this->add(0, $this->height / 2, 0), $this->world), $ev->getForce(), $this); + $explosion = new Explosion(Position::fromObject($this->location->add(0, $this->height / 2, 0), $this->getWorld()), $ev->getForce(), $this); if($ev->isBlockBreaking()){ $explosion->explodeA(); } diff --git a/src/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php index 496670382d..01478eacd3 100644 --- a/src/entity/projectile/Arrow.php +++ b/src/entity/projectile/Arrow.php @@ -142,7 +142,7 @@ class Arrow extends Projectile{ protected function onHit(ProjectileHitEvent $event) : void{ $this->setCritical(false); - $this->world->addSound($this, new ArrowHitSound()); + $this->getWorld()->addSound($this->location, new ArrowHitSound()); } protected function onHitBlock(Block $blockHit, RayTraceResult $hitResult) : void{ diff --git a/src/entity/projectile/Egg.php b/src/entity/projectile/Egg.php index 367dc2e7b7..d16f11d9c6 100644 --- a/src/entity/projectile/Egg.php +++ b/src/entity/projectile/Egg.php @@ -35,7 +35,7 @@ class Egg extends Throwable{ protected function onHit(ProjectileHitEvent $event) : void{ for($i = 0; $i < 6; ++$i){ - $this->world->addParticle($this, new ItemBreakParticle(VanillaItems::EGG())); + $this->getWorld()->addParticle($this->location, new ItemBreakParticle(VanillaItems::EGG())); } } } diff --git a/src/entity/projectile/EnderPearl.php b/src/entity/projectile/EnderPearl.php index e13cbddc61..536cbbdd62 100644 --- a/src/entity/projectile/EnderPearl.php +++ b/src/entity/projectile/EnderPearl.php @@ -33,6 +33,7 @@ use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\world\particle\EndermanTeleportParticle; use pocketmine\world\sound\EndermanTeleportSound; +use function get_class; class EnderPearl extends Throwable{ public const NETWORK_ID = EntityLegacyIds::ENDER_PEARL; @@ -53,10 +54,10 @@ class EnderPearl extends Throwable{ //TODO: check end gateways (when they are added) //TODO: spawn endermites at origin - $this->world->addParticle($owner, new EndermanTeleportParticle()); - $this->world->addSound($owner, new EndermanTeleportSound()); + $this->getWorld()->addParticle($origin = $owner->getPosition(), new EndermanTeleportParticle()); + $this->getWorld()->addSound($origin, new EndermanTeleportSound()); $owner->teleport($target = $event->getRayTraceResult()->getHitVector()); - $this->world->addSound($target, new EndermanTeleportSound()); + $this->getWorld()->addSound($target, new EndermanTeleportSound()); $owner->attack(new EntityDamageEvent($owner, EntityDamageEvent::CAUSE_FALL, 5)); } diff --git a/src/entity/projectile/ExperienceBottle.php b/src/entity/projectile/ExperienceBottle.php index 95c0a9465b..fbb3666bf8 100644 --- a/src/entity/projectile/ExperienceBottle.php +++ b/src/entity/projectile/ExperienceBottle.php @@ -39,9 +39,9 @@ class ExperienceBottle extends Throwable{ } public function onHit(ProjectileHitEvent $event) : void{ - $this->world->addParticle($this, new PotionSplashParticle(PotionSplashParticle::DEFAULT_COLOR())); - $this->world->addSound($this, new PotionSplashSound()); + $this->getWorld()->addParticle($this->location, new PotionSplashParticle(PotionSplashParticle::DEFAULT_COLOR())); + $this->getWorld()->addSound($this->location, new PotionSplashSound()); - $this->world->dropExperience($this, mt_rand(3, 11)); + $this->getWorld()->dropExperience($this->location, mt_rand(3, 11)); } } diff --git a/src/entity/projectile/Projectile.php b/src/entity/projectile/Projectile.php index 72eaa7db0e..52376fbc11 100644 --- a/src/entity/projectile/Projectile.php +++ b/src/entity/projectile/Projectile.php @@ -84,7 +84,7 @@ abstract class Projectile extends Entity{ $blockData = null; if($nbt->hasTag("tileX", IntTag::class) and $nbt->hasTag("tileY", IntTag::class) and $nbt->hasTag("tileZ", IntTag::class)){ - $blockPos = new Position($nbt->getInt("tileX"), $nbt->getInt("tileY"), $nbt->getInt("tileZ"), $this->world); + $blockPos = new Position($nbt->getInt("tileX"), $nbt->getInt("tileY"), $nbt->getInt("tileZ"), $this->getWorld()); }else{ break; } @@ -164,7 +164,7 @@ abstract class Projectile extends Entity{ } public function onNearbyBlockChange() : void{ - if($this->blockHit !== null and $this->world->isInLoadedTerrain($this->blockHit->getPos()) and !$this->blockHit->isSameState($this->world->getBlock($this->blockHit->getPos()))){ + if($this->blockHit !== null and $this->getWorld()->isInLoadedTerrain($this->blockHit->getPos()) and !$this->blockHit->isSameState($this->getWorld()->getBlock($this->blockHit->getPos()))){ $this->blockHit = null; } @@ -180,7 +180,7 @@ abstract class Projectile extends Entity{ Timings::$entityMoveTimer->startTiming(); - $start = $this->asVector3(); + $start = $this->location->asVector3(); $end = $start->add($this->motion); $blockHit = null; @@ -188,7 +188,7 @@ abstract class Projectile extends Entity{ $hitResult = null; foreach(VoxelRayTrace::betweenPoints($start, $end) as $vector3){ - $block = $this->world->getBlockAt($vector3->x, $vector3->y, $vector3->z); + $block = $this->getWorld()->getBlockAt($vector3->x, $vector3->y, $vector3->z); $blockHitResult = $this->calculateInterceptWithBlock($block, $start, $end); if($blockHitResult !== null){ @@ -202,7 +202,7 @@ abstract class Projectile extends Entity{ $entityDistance = PHP_INT_MAX; $newDiff = $end->subtract($start); - foreach($this->world->getCollidingEntities($this->boundingBox->addCoord($newDiff->x, $newDiff->y, $newDiff->z)->expand(1, 1, 1), $this) as $entity){ + foreach($this->getWorld()->getCollidingEntities($this->boundingBox->addCoord($newDiff->x, $newDiff->y, $newDiff->z)->expand(1, 1, 1), $this) as $entity){ if($entity->getId() === $this->getOwningEntityId() and $this->ticksLived < 5){ continue; } @@ -214,7 +214,7 @@ abstract class Projectile extends Entity{ continue; } - $distance = $this->distanceSquared($entityHitResult->hitVector); + $distance = $this->location->distanceSquared($entityHitResult->hitVector); if($distance < $entityDistance){ $entityDistance = $distance; @@ -224,9 +224,9 @@ abstract class Projectile extends Entity{ } } - $this->x = $end->x; - $this->y = $end->y; - $this->z = $end->z; + $this->location->x = $end->x; + $this->location->y = $end->y; + $this->location->z = $end->z; $this->recalculateBoundingBox(); if($hitResult !== null){ @@ -259,8 +259,8 @@ abstract class Projectile extends Entity{ //recompute angles... $f = sqrt(($this->motion->x ** 2) + ($this->motion->z ** 2)); - $this->yaw = (atan2($this->motion->x, $this->motion->z) * 180 / M_PI); - $this->pitch = (atan2($this->motion->y, $f) * 180 / M_PI); + $this->location->yaw = (atan2($this->motion->x, $this->motion->z) * 180 / M_PI); + $this->location->pitch = (atan2($this->motion->y, $f) * 180 / M_PI); } $this->checkChunks(); diff --git a/src/entity/projectile/Snowball.php b/src/entity/projectile/Snowball.php index 6e7d090840..88fcc42234 100644 --- a/src/entity/projectile/Snowball.php +++ b/src/entity/projectile/Snowball.php @@ -32,7 +32,7 @@ class Snowball extends Throwable{ protected function onHit(ProjectileHitEvent $event) : void{ for($i = 0; $i < 6; ++$i){ - $this->world->addParticle($this, new SnowballPoofParticle()); + $this->getWorld()->addParticle($this->location, new SnowballPoofParticle()); } } } diff --git a/src/entity/projectile/SplashPotion.php b/src/entity/projectile/SplashPotion.php index 53b892670f..2b40123469 100644 --- a/src/entity/projectile/SplashPotion.php +++ b/src/entity/projectile/SplashPotion.php @@ -89,14 +89,14 @@ class SplashPotion extends Throwable{ $particle = new PotionSplashParticle(Color::mix(...$colors)); } - $this->world->addParticle($this, $particle); - $this->world->addSound($this, new PotionSplashSound()); + $this->getWorld()->addParticle($this->location, $particle); + $this->getWorld()->addSound($this->location, new PotionSplashSound()); if($hasEffects){ if(!$this->willLinger()){ - foreach($this->world->getNearbyEntities($this->boundingBox->expandedCopy(4.125, 2.125, 4.125), $this) as $entity){ + foreach($this->getWorld()->getNearbyEntities($this->boundingBox->expandedCopy(4.125, 2.125, 4.125), $this) as $entity){ if($entity instanceof Living and $entity->isAlive()){ - $distanceSquared = $entity->getEyePos()->distanceSquared($this); + $distanceSquared = $entity->getEyePos()->distanceSquared($this->location); if($distanceSquared > 16){ //4 blocks continue; } @@ -129,11 +129,11 @@ class SplashPotion extends Throwable{ $blockIn = $event->getBlockHit()->getSide($event->getRayTraceResult()->getHitFace()); if($blockIn->getId() === BlockLegacyIds::FIRE){ - $this->world->setBlock($blockIn->getPos(), VanillaBlocks::AIR()); + $this->getWorld()->setBlock($blockIn->getPos(), VanillaBlocks::AIR()); } foreach($blockIn->getHorizontalSides() as $horizontalSide){ if($horizontalSide->getId() === BlockLegacyIds::FIRE){ - $this->world->setBlock($horizontalSide->getPos(), VanillaBlocks::AIR()); + $this->getWorld()->setBlock($horizontalSide->getPos(), VanillaBlocks::AIR()); } } } diff --git a/src/item/Bow.php b/src/item/Bow.php index 9aabc9a87a..ec1b7e9e74 100644 --- a/src/item/Bow.php +++ b/src/item/Bow.php @@ -50,11 +50,12 @@ class Bow extends Tool{ return ItemUseResult::FAIL(); } + $location = $player->getLocation(); $nbt = EntityFactory::createBaseNBT( $player->getEyePos(), $player->getDirectionVector(), - ($player->yaw > 180 ? 360 : 0) - $player->yaw, - -$player->pitch + ($location->yaw > 180 ? 360 : 0) - $location->yaw, + -$location->pitch ); $nbt->setShort("Fire", $player->isOnFire() ? 45 * 60 : 0); @@ -63,7 +64,7 @@ class Bow extends Tool{ $baseForce = min((($p ** 2) + $p * 2) / 3, 1); /** @var ArrowEntity $entity */ - $entity = EntityFactory::create(ArrowEntity::class, $player->getWorld(), $nbt, $player, $baseForce >= 1); + $entity = EntityFactory::create(ArrowEntity::class, $location->getWorld(), $nbt, $player, $baseForce >= 1); $infinity = $this->hasEnchantment(Enchantment::INFINITY()); if($infinity){ @@ -104,7 +105,7 @@ class Bow extends Tool{ } $ev->getProjectile()->spawnToAll(); - $player->getWorld()->addSound($player, new BowShootSound()); + $location->getWorld()->addSound($location, new BowShootSound()); }else{ $entity->spawnToAll(); } diff --git a/src/item/ChorusFruit.php b/src/item/ChorusFruit.php index 72a8b987b3..5bca292084 100644 --- a/src/item/ChorusFruit.php +++ b/src/item/ChorusFruit.php @@ -49,9 +49,10 @@ class ChorusFruit extends Food{ $world = $consumer->getWorld(); assert($world !== null); - $minX = $consumer->getFloorX() - 8; - $minY = min($consumer->getFloorY(), $consumer->getWorld()->getWorldHeight()) - 8; - $minZ = $consumer->getFloorZ() - 8; + $origin = $consumer->getPosition(); + $minX = $origin->getFloorX() - 8; + $minY = min($origin->getFloorY(), $consumer->getWorld()->getWorldHeight()) - 8; + $minZ = $origin->getFloorZ() - 8; $maxX = $minX + 16; $maxY = $minY + 16; @@ -76,7 +77,7 @@ class ChorusFruit extends Food{ } //Sounds are broadcasted at both source and destination - $world->addSound($consumer->asVector3(), new EndermanTeleportSound()); + $world->addSound($origin, new EndermanTeleportSound()); $consumer->teleport($target = new Vector3($x + 0.5, $y + 1, $z + 0.5)); $world->addSound($target, new EndermanTeleportSound()); diff --git a/src/item/ProjectileItem.php b/src/item/ProjectileItem.php index ecbc0fdc64..cd3461bd19 100644 --- a/src/item/ProjectileItem.php +++ b/src/item/ProjectileItem.php @@ -53,14 +53,15 @@ abstract class ProjectileItem extends Item{ } public function onClickAir(Player $player, Vector3 $directionVector) : ItemUseResult{ - $nbt = EntityFactory::createBaseNBT($player->getEyePos(), $directionVector, $player->yaw, $player->pitch); + $location = $player->getLocation(); + $nbt = EntityFactory::createBaseNBT($player->getEyePos(), $directionVector, $location->yaw, $location->pitch); $this->addExtraTags($nbt); $class = $this->getProjectileEntityClass(); Utils::testValidInstance($class, Throwable::class); /** @var Throwable $projectile */ - $projectile = EntityFactory::create($class, $player->getWorld(), $nbt, $player); + $projectile = EntityFactory::create($class, $location->getWorld(), $nbt, $player); $projectile->setMotion($projectile->getMotion()->multiply($this->getThrowForce())); $projectileEv = new ProjectileLaunchEvent($projectile); @@ -72,7 +73,7 @@ abstract class ProjectileItem extends Item{ $projectile->spawnToAll(); - $player->getWorld()->addSound($player, new ThrowSound()); + $location->getWorld()->addSound($location, new ThrowSound()); $this->pop(); diff --git a/src/item/enchantment/KnockbackEnchantment.php b/src/item/enchantment/KnockbackEnchantment.php index da274a4090..d504700036 100644 --- a/src/item/enchantment/KnockbackEnchantment.php +++ b/src/item/enchantment/KnockbackEnchantment.php @@ -38,7 +38,8 @@ class KnockbackEnchantment extends MeleeWeaponEnchantment{ public function onPostAttack(Entity $attacker, Entity $victim, int $enchantmentLevel) : void{ if($victim instanceof Living){ - $victim->knockBack($victim->x - $attacker->x, $victim->z - $attacker->z, $enchantmentLevel * 0.5); + $diff = $victim->getPosition()->subtract($attacker->getPosition()); + $victim->knockBack($diff->x, $diff->z, $enchantmentLevel * 0.5); } } } diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 7d94ffe762..8c983df52f 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -623,8 +623,9 @@ class NetworkSession{ } public function syncMovement(Vector3 $pos, ?float $yaw = null, ?float $pitch = null, int $mode = MovePlayerPacket::MODE_NORMAL) : void{ - $yaw = $yaw ?? $this->player->getYaw(); - $pitch = $pitch ?? $this->player->getPitch(); + $location = $this->player->getLocation(); + $yaw = $yaw ?? $location->getYaw(); + $pitch = $pitch ?? $location->getPitch(); $pk = new MovePlayerPacket(); $pk->entityRuntimeId = $this->player->getId(); @@ -767,7 +768,7 @@ class NetworkSession{ public function startUsingChunk(int $chunkX, int $chunkZ, \Closure $onCompletion) : void{ Utils::validateCallableSignature(function(int $chunkX, int $chunkZ){}, $onCompletion); - $world = $this->player->getWorld(); + $world = $this->player->getLocation()->getWorld(); assert($world !== null); ChunkCache::getInstance($world)->request($chunkX, $chunkZ)->onResolve( @@ -776,16 +777,17 @@ class NetworkSession{ if(!$this->isConnected()){ return; } - if($world !== $this->player->getWorld() or !$this->player->isUsingChunk($chunkX, $chunkZ)){ + $currentWorld = $this->player->getLocation()->getWorld(); + if($world !== $currentWorld or !$this->player->isUsingChunk($chunkX, $chunkZ)){ $this->logger->debug("Tried to send no-longer-active chunk $chunkX $chunkZ in world " . $world->getFolderName()); return; } - $this->player->world->timings->syncChunkSendTimer->startTiming(); + $currentWorld->timings->syncChunkSendTimer->startTiming(); try{ $this->queueCompressed($promise); $onCompletion($chunkX, $chunkZ); }finally{ - $this->player->world->timings->syncChunkSendTimer->stopTiming(); + $currentWorld->timings->syncChunkSendTimer->stopTiming(); } } ); diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 62d2660bb9..774bc4d1ec 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -301,7 +301,7 @@ class InGamePacketHandler extends PacketHandler{ */ private function onFailedBlockAction(Vector3 $blockPos, ?int $face) : void{ $this->session->getInvManager()->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); - if($blockPos->distanceSquared($this->player) < 10000){ + if($blockPos->distanceSquared($this->player->getLocation()) < 10000){ $blocks = $blockPos->sidesArray(); if($face !== null){ $sidePos = $blockPos->getSide($face); @@ -311,7 +311,7 @@ class InGamePacketHandler extends PacketHandler{ }else{ $blocks[] = $blockPos; } - $this->player->getWorld()->sendBlocks([$this->player], $blocks); + $this->player->getLocation()->getWorld()->sendBlocks([$this->player], $blocks); } } @@ -510,11 +510,11 @@ class InGamePacketHandler extends PacketHandler{ public function handleBlockActorData(BlockActorDataPacket $packet) : bool{ $pos = new Vector3($packet->x, $packet->y, $packet->z); - if($pos->distanceSquared($this->player) > 10000){ + if($pos->distanceSquared($this->player->getLocation()) > 10000){ return false; } - $block = $this->player->getWorld()->getBlock($pos); + $block = $this->player->getLocation()->getWorld()->getBlock($pos); try{ $offset = 0; $nbt = (new NetworkNbtSerializer())->read($packet->namedtag, $offset, 512)->getTag(); @@ -703,7 +703,7 @@ class InGamePacketHandler extends PacketHandler{ } public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{ - $this->player->getWorld()->broadcastPacketToViewers($this->player->asVector3(), $packet); + $this->player->getWorld()->broadcastPacketToViewers($this->player->getPosition(), $packet); return true; } diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index b643f00d91..f6a76867ee 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -53,23 +53,24 @@ class PreSpawnPacketHandler extends PacketHandler{ public function setUp() : void{ $spawnPosition = $this->player->getSpawn(); + $location = $this->player->getLocation(); $pk = new StartGamePacket(); $pk->entityUniqueId = $this->player->getId(); $pk->entityRuntimeId = $this->player->getId(); $pk->playerGamemode = NetworkSession::getClientFriendlyGamemode($this->player->getGamemode()); - $pk->playerPosition = $this->player->getOffsetPosition($this->player); - $pk->pitch = $this->player->pitch; - $pk->yaw = $this->player->yaw; + $pk->playerPosition = $this->player->getOffsetPosition($location); + $pk->pitch = $location->pitch; + $pk->yaw = $location->yaw; $pk->seed = -1; $pk->dimension = DimensionIds::OVERWORLD; //TODO: implement this properly $pk->worldGamemode = NetworkSession::getClientFriendlyGamemode($this->server->getGamemode()); - $pk->difficulty = $this->player->getWorld()->getDifficulty(); + $pk->difficulty = $location->getWorld()->getDifficulty(); $pk->spawnX = $spawnPosition->getFloorX(); $pk->spawnY = $spawnPosition->getFloorY(); $pk->spawnZ = $spawnPosition->getFloorZ(); $pk->hasAchievementsDisabled = true; - $pk->time = $this->player->getWorld()->getTime(); + $pk->time = $location->getWorld()->getTime(); $pk->eduMode = false; $pk->rainLevel = 0; //TODO: implement these properly $pk->lightningLevel = 0; diff --git a/src/player/Player.php b/src/player/Player.php index ed8380d446..566118ea66 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -329,10 +329,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->networkSession->getIp(), $this->networkSession->getPort(), $this->id, - $this->world->getDisplayName(), - round($this->x, 4), - round($this->y, 4), - round($this->z, 4) + $this->getWorld()->getDisplayName(), + round($this->location->x, 4), + round($this->location->y, 4), + round($this->location->z, 4) ])); $this->server->addOnlinePlayer($this); @@ -368,7 +368,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if(($world = $this->server->getWorldManager()->getWorldByName($nbt->getString("SpawnLevel", ""))) instanceof World){ $this->spawnPosition = new Position($nbt->getInt("SpawnX"), $nbt->getInt("SpawnY"), $nbt->getInt("SpawnZ"), $world); }else{ - $this->spawnPosition = $this->world->getSafeSpawn(); + $this->spawnPosition = $this->getWorld()->getSafeSpawn(); } } } @@ -514,7 +514,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @param Player $player */ public function spawnTo(Player $player) : void{ - if($this->isAlive() and $player->isAlive() and $player->getWorld() === $this->world and $player->canSee($this) and !$this->isSpectator()){ + if($this->isAlive() and $player->isAlive() and $player->getWorld() === $this->getWorld() and $player->canSee($this) and !$this->isSpectator()){ parent::spawnTo($player); } } @@ -802,7 +802,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } protected function switchWorld(World $targetWorld) : bool{ - $oldWorld = $this->world; + $oldWorld = $this->getWorld(); if(parent::switchWorld($targetWorld)){ if($oldWorld !== null){ foreach($this->usedChunks as $index => $d){ @@ -813,8 +813,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->usedChunks = []; $this->loadQueue = []; - $this->world->sendTime($this); - $this->world->sendDifficulty($this); + $this->getWorld()->sendTime($this); + $this->getWorld()->sendDifficulty($this); return true; } @@ -823,7 +823,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } protected function unloadChunk(int $x, int $z, ?World $world = null){ - $world = $world ?? $this->world; + $world = $world ?? $this->getWorld(); $index = World::chunkHash($x, $z); if(isset($this->usedChunks[$index])){ foreach($world->getChunk($x, $z)->getEntities() as $entity){ @@ -840,7 +840,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } protected function spawnEntitiesOnChunk(int $chunkX, int $chunkZ) : void{ - foreach($this->world->getChunk($chunkX, $chunkZ)->getEntities() as $entity){ + foreach($this->getWorld()->getChunk($chunkX, $chunkZ)->getEntities() as $entity){ if($entity !== $this and !$entity->isFlaggedForDespawn()){ $entity->spawnTo($this); } @@ -868,10 +868,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, ++$count; $this->usedChunks[$index] = false; - $this->world->registerChunkLoader($this, $X, $Z, true); - $this->world->registerChunkListener($this, $X, $Z); + $this->getWorld()->registerChunkLoader($this, $X, $Z, true); + $this->getWorld()->registerChunkListener($this, $X, $Z); - if(!$this->world->populateChunk($X, $Z)){ + if(!$this->getWorld()->populateChunk($X, $Z)){ continue; } @@ -935,8 +935,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $radius = $this->server->getAllowedViewDistance($this->viewDistance); $radiusSquared = $radius ** 2; - $centerX = $this->getFloorX() >> 4; - $centerZ = $this->getFloorZ() >> 4; + $centerX = $this->location->getFloorX() >> 4; + $centerZ = $this->location->getFloorZ() >> 4; for($x = 0; $x < $radius; ++$x){ for($z = 0; $z <= $x; ++$z){ @@ -993,7 +993,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->loadQueue = $newOrder; if(!empty($this->loadQueue) or !empty($unloadChunks)){ - $this->networkSession->syncViewAreaCenterPoint($this, $this->viewDistance); + $this->networkSession->syncViewAreaCenterPoint($this->location, $this->viewDistance); } Timings::$playerChunkOrderTimer->stopTiming(); @@ -1042,7 +1042,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, */ public function setSpawn(Vector3 $pos){ if(!($pos instanceof Position)){ - $world = $this->world; + $world = $this->getWorld(); }else{ $world = $pos->getWorld(); } @@ -1064,7 +1064,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, */ public function sleepOn(Vector3 $pos) : bool{ $pos = $pos->floor(); - $b = $this->world->getBlock($pos); + $b = $this->getWorld()->getBlock($pos); $ev = new PlayerBedEnterEvent($this, $b); $ev->call(); @@ -1080,14 +1080,14 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->setSpawn($pos); - $this->world->setSleepTicks(60); + $this->getWorld()->setSleepTicks(60); return true; } public function stopSleep(){ if($this->sleeping instanceof Vector3){ - $b = $this->world->getBlock($this->sleeping); + $b = $this->getWorld()->getBlock($this->sleeping); if($b instanceof Bed){ $b->setOccupied(false); } @@ -1095,7 +1095,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->sleeping = null; - $this->world->setSleepTicks(0); + $this->getWorld()->setSleepTicks(0); $this->broadcastAnimation([$this], AnimatePacket::ACTION_STOP_SLEEP); } @@ -1225,10 +1225,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, protected function checkGroundState(float $movX, float $movY, float $movZ, float $dx, float $dy, float $dz) : void{ $bb = clone $this->boundingBox; - $bb->minY = $this->y - 0.2; - $bb->maxY = $this->y + 0.2; + $bb->minY = $this->location->y - 0.2; + $bb->maxY = $this->location->y + 0.2; - $this->onGround = $this->isCollided = count($this->world->getCollisionBlocks($bb, true)) > 0; + $this->onGround = $this->isCollided = count($this->getWorld()->getCollisionBlocks($bb, true)) > 0; } public function canBeMovedByCurrents() : bool{ @@ -1236,7 +1236,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } protected function checkNearEntities(){ - foreach($this->world->getNearbyEntities($this->boundingBox->expandedCopy(1, 0.5, 1), $this) as $entity){ + foreach($this->getWorld()->getNearbyEntities($this->boundingBox->expandedCopy(1, 0.5, 1), $this) as $entity){ $entity->scheduleUpdate(); if(!$entity->isAlive() or $entity->isFlaggedForDespawn()){ @@ -1254,7 +1254,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return Vector3 */ public function getNextPosition() : Vector3{ - return $this->newPosition !== null ? clone $this->newPosition : $this->asVector3(); + return $this->newPosition !== null ? clone $this->newPosition : $this->location->asVector3(); } /** @@ -1271,9 +1271,9 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, //TODO: teleport acks are a network specific thing and shouldn't be here $newPos = $newPos->asVector3(); - if($this->isTeleporting and $newPos->distanceSquared($this) > 1){ //Tolerate up to 1 block to avoid problems with client-sided physics when spawning in blocks - $this->sendPosition($this, null, null, MovePlayerPacket::MODE_RESET); - $this->logger->debug("Got outdated pre-teleport movement, received " . $newPos . ", expected " . $this->asVector3()); + if($this->isTeleporting and $newPos->distanceSquared($this->location) > 1){ //Tolerate up to 1 block to avoid problems with client-sided physics when spawning in blocks + $this->sendPosition($this->location, null, null, MovePlayerPacket::MODE_RESET); + $this->logger->debug("Got outdated pre-teleport movement, received " . $newPos . ", expected " . $this->location->asVector3()); //Still getting movements from before teleport, ignore them return false; } @@ -1296,11 +1296,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return; } - assert($this->x !== null and $this->y !== null and $this->z !== null); assert($this->newPosition->x !== null and $this->newPosition->y !== null and $this->newPosition->z !== null); $newPos = $this->newPosition; - $distanceSquared = $newPos->distanceSquared($this); + $distanceSquared = $newPos->distanceSquared($this->location); $revert = false; @@ -1316,23 +1315,23 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * asking for help if you suffer the consequences of messing with this. */ $this->logger->debug("Moved too fast, reverting movement"); - $this->logger->debug("Old position: " . $this->asVector3() . ", new position: " . $this->newPosition); + $this->logger->debug("Old position: " . $this->location->asVector3() . ", new position: " . $this->newPosition); $revert = true; - }elseif(!$this->world->isInLoadedTerrain($newPos) or !$this->world->isChunkGenerated($newPos->getFloorX() >> 4, $newPos->getFloorZ() >> 4)){ + }elseif(!$this->getWorld()->isInLoadedTerrain($newPos) or !$this->getWorld()->isChunkGenerated($newPos->getFloorX() >> 4, $newPos->getFloorZ() >> 4)){ $revert = true; $this->nextChunkOrderRun = 0; } if(!$revert and $distanceSquared != 0){ - $dx = $newPos->x - $this->x; - $dy = $newPos->y - $this->y; - $dz = $newPos->z - $this->z; + $dx = $newPos->x - $this->location->x; + $dy = $newPos->y - $this->location->y; + $dz = $newPos->z - $this->location->z; $this->move($dx, $dy, $dz); } $from = clone $this->lastLocation; - $to = $this->asLocation(); + $to = clone $this->location; $delta = $to->distanceSquared($from); $deltaAngle = abs($this->lastLocation->yaw - $to->yaw) + abs($this->lastLocation->pitch - $to->pitch); @@ -1631,7 +1630,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } public function pickBlock(Vector3 $pos, bool $addTileNBT) : bool{ - $block = $this->world->getBlock($pos); + $block = $this->getWorld()->getBlock($pos); if($block instanceof UnknownBlock){ return true; } @@ -1678,11 +1677,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return bool if an action took place successfully */ public function attackBlock(Vector3 $pos, int $face) : bool{ - if($pos->distanceSquared($this) > 10000){ + if($pos->distanceSquared($this->location) > 10000){ return false; //TODO: maybe this should throw an exception instead? } - $target = $this->world->getBlock($pos); + $target = $this->getWorld()->getBlock($pos); $ev = new PlayerInteractEvent($this, $this->inventory->getItemInHand(), $target, null, $face, PlayerInteractEvent::LEFT_CLICK_BLOCK); $ev->call(); @@ -1696,7 +1695,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $block = $target->getSide($face); if($block->getId() === BlockLegacyIds::FIRE){ - $this->world->setBlock($block->getPos(), VanillaBlocks::AIR()); + $this->getWorld()->setBlock($block->getPos(), VanillaBlocks::AIR()); return true; } @@ -1704,7 +1703,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, //TODO: improve this to take stuff like swimming, ladders, enchanted tools into account, fix wrong tool break time calculations for bad tools (pmmp/PocketMine-MP#211) $breakTime = ceil($target->getBreakInfo()->getBreakTime($this->inventory->getItemInHand()) * 20); if($breakTime > 0){ - $this->world->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_START_BREAK, (int) (65535 / $breakTime)); + $this->getWorld()->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_START_BREAK, (int) (65535 / $breakTime)); } } @@ -1712,15 +1711,15 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } public function continueBreakBlock(Vector3 $pos, int $face) : void{ - $block = $this->world->getBlock($pos); - $this->world->addParticle($pos, new PunchBlockParticle($block, $face)); + $block = $this->getWorld()->getBlock($pos); + $this->getWorld()->addParticle($pos, new PunchBlockParticle($block, $face)); $this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers()); //TODO: destroy-progress level event } public function stopBreakBlock(Vector3 $pos) : void{ - $this->world->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_STOP_BREAK); + $this->getWorld()->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_STOP_BREAK); } /** @@ -1737,7 +1736,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers()); $item = $this->inventory->getItemInHand(); $oldItem = clone $item; - if($this->world->useBreakOn($pos, $item, $this, true)){ + if($this->getWorld()->useBreakOn($pos, $item, $this, true)){ if($this->hasFiniteResources() and !$item->equalsExact($oldItem)){ $this->inventory->setItemInHand($item); } @@ -1765,7 +1764,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers()); $item = $this->inventory->getItemInHand(); //this is a copy of the real item $oldItem = clone $item; - if($this->world->useItemOn($pos, $item, $face, $clickOffset, $this, true)){ + if($this->getWorld()->useItemOn($pos, $item, $face, $clickOffset, $this, true)){ if($this->hasFiniteResources() and !$item->equalsExact($oldItem)){ $this->inventory->setItemInHand($item); } @@ -1797,7 +1796,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $heldItem = $this->inventory->getItemInHand(); $ev = new EntityDamageByEntityEvent($this, $entity, EntityDamageEvent::CAUSE_ENTITY_ATTACK, $heldItem->getAttackPoints()); - if(!$this->canInteract($entity, 8) or ($entity instanceof Player and !$this->server->getConfigBool("pvp"))){ + if(!$this->canInteract($entity->getLocation(), 8) or ($entity instanceof Player and !$this->server->getConfigBool("pvp"))){ $ev->setCancelled(); } @@ -1900,7 +1899,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, */ public function dropItem(Item $item) : void{ $this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers()); - $this->world->dropItem($this->add(0, 1.3, 0), $item, $this->getDirectionVector()->multiply(0.4), 40); + $this->getWorld()->dropItem($this->location->add(0, 1.3, 0), $item, $this->getDirectionVector()->multiply(0.4), 40); } /** @@ -2159,7 +2158,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $this->hiddenPlayers = []; - if($this->isValid()){ + if($this->location->isValid()){ foreach($this->usedChunks as $index => $d){ World::getXZ($index, $chunkX, $chunkZ); $this->unloadChunk($chunkX, $chunkZ); @@ -2221,8 +2220,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $nbt = $this->saveNBT(); - if($this->isValid()){ - $nbt->setString("Level", $this->world->getFolderName()); + if($this->location->isValid()){ + $nbt->setString("Level", $this->getWorld()->getFolderName()); } if($this->hasValidSpawnPosition()){ @@ -2261,7 +2260,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if(!$ev->getKeepInventory()){ foreach($ev->getDrops() as $item){ - $this->world->dropItem($this, $item); + $this->getWorld()->dropItem($this->location, $item); } if($this->inventory !== null){ @@ -2273,7 +2272,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } - $this->world->dropExperience($this, $ev->getXpDropAmount()); + $this->getWorld()->dropExperience($this->location, $ev->getXpDropAmount()); $this->xpManager->setXpAndProgress(0, 0.0); if($ev->getDeathMessage() != ""){ @@ -2400,7 +2399,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->removeCurrentWindow(); - $this->sendPosition($this, $this->yaw, $this->pitch, MovePlayerPacket::MODE_TELEPORT); + $this->sendPosition($this->location, $this->location->yaw, $this->location->pitch, MovePlayerPacket::MODE_TELEPORT); $this->broadcastMovement(true); $this->spawnToAll(); @@ -2543,4 +2542,22 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->nextChunkOrderRun = 0; } } + + /** + * @see ChunkLoader::getX() + * @return float + */ + public function getX(){ + return $this->location->getX(); + } + + /** + * @see ChunkLoader::getZ() + * @return float + */ + public function getZ(){ + return $this->location->getZ(); + } + + } diff --git a/src/world/Explosion.php b/src/world/Explosion.php index aa7df40b25..8a9f57ba96 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -174,12 +174,14 @@ class Explosion{ $explosionBB = new AxisAlignedBB($minX, $minY, $minZ, $maxX, $maxY, $maxZ); + /** @var Entity[] $list */ $list = $this->world->getNearbyEntities($explosionBB, $this->what instanceof Entity ? $this->what : null); foreach($list as $entity){ - $distance = $entity->distance($this->source) / $explosionSize; + $entityPos = $entity->getPosition(); + $distance = $entityPos->distance($this->source) / $explosionSize; if($distance <= 1){ - $motion = $entity->subtract($this->source)->normalize(); + $motion = $entityPos->subtract($this->source)->normalize(); $impact = (1 - $distance) * ($exposure = 1); From 1262b067974ebebad844d63a943bca2bdfbe163b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Aug 2019 17:22:22 +0100 Subject: [PATCH 1205/3224] [ci skip] update changelog --- changelogs/4.0-snapshot.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 6bf61bcc05..09ada3c52a 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -154,6 +154,7 @@ This version features substantial changes to the network system, improving coher ### Entity #### General +- `Entity` no longer extends from `Location`. `Entity->getLocation()` and `Entity->getPosition()` should be used instead. - The following API methods have been added: - `ItemEntity->getDespawnDelay()` - `ItemEntity->setDespawnDelay()` From 3274db3ddcf02d2cda20a5a6107d826248e2d62a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Aug 2019 18:57:26 +0100 Subject: [PATCH 1206/3224] DustParticle constructor now uses Color object --- changelogs/4.0-snapshot.md | 1 + src/command/defaults/ParticleCommand.php | 3 ++- src/world/particle/DustParticle.php | 5 +++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 09ada3c52a..d8d617fa1d 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -699,6 +699,7 @@ This version features substantial changes to the network system, improving coher - `Location` has been moved to `pocketmine\entity\Location`. #### Particles +- `DustParticle->__construct()` now accepts a `pocketmine\utils\Color` object instead of `r, g, b, a`. - `pocketmine\world\particle\Particle` no longer extends `pocketmine\math\Vector3`, and has been converted to an interface. - Added the following `Particle` classes: - `DragonEggTeleportParticle` diff --git a/src/command/defaults/ParticleCommand.php b/src/command/defaults/ParticleCommand.php index 6a2c380f97..f3974d3217 100644 --- a/src/command/defaults/ParticleCommand.php +++ b/src/command/defaults/ParticleCommand.php @@ -31,6 +31,7 @@ use pocketmine\item\VanillaItems; use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; use pocketmine\player\Player; +use pocketmine\utils\Color; use pocketmine\utils\Random; use pocketmine\utils\TextFormat; use pocketmine\world\particle\AngryVillagerParticle; @@ -224,7 +225,7 @@ class ParticleCommand extends VanillaCommand{ }elseif(strpos($name, "blockdust_") === 0){ $d = explode("_", $name); if(count($d) >= 4){ - return new DustParticle(((int) $d[1]) & 0xff, ((int) $d[2]) & 0xff, ((int) $d[3]) & 0xff, isset($d[4]) ? ((int) $d[4]) & 0xff : 255); + return new DustParticle(new Color(((int) $d[1]) & 0xff, ((int) $d[2]) & 0xff, ((int) $d[3]) & 0xff, isset($d[4]) ? ((int) $d[4]) & 0xff : 255)); } } diff --git a/src/world/particle/DustParticle.php b/src/world/particle/DustParticle.php index 483e87cd80..c698062396 100644 --- a/src/world/particle/DustParticle.php +++ b/src/world/particle/DustParticle.php @@ -24,9 +24,10 @@ declare(strict_types=1); namespace pocketmine\world\particle; use pocketmine\network\mcpe\protocol\types\ParticleIds; +use pocketmine\utils\Color; class DustParticle extends GenericParticle{ - public function __construct(int $r, int $g, int $b, int $a = 255){ - parent::__construct(ParticleIds::DUST, (($a & 0xff) << 24) | (($r & 0xff) << 16) | (($g & 0xff) << 8) | ($b & 0xff)); + public function __construct(Color $color){ + parent::__construct(ParticleIds::DUST, $color->toARGB()); } } From e52ba7201c22334907da39a8492ff651b0f126cd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Aug 2019 19:01:09 +0100 Subject: [PATCH 1207/3224] add LevelEventPacket::standardParticle() sugar --- src/network/mcpe/protocol/LevelEventPacket.php | 4 ++++ src/world/particle/GenericParticle.php | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/network/mcpe/protocol/LevelEventPacket.php b/src/network/mcpe/protocol/LevelEventPacket.php index d05402fe4c..99a3231d30 100644 --- a/src/network/mcpe/protocol/LevelEventPacket.php +++ b/src/network/mcpe/protocol/LevelEventPacket.php @@ -129,6 +129,10 @@ class LevelEventPacket extends DataPacket implements ClientboundPacket{ return $pk; } + public static function standardParticle(int $particleId, int $data, Vector3 $pos) : self{ + return self::create(self::EVENT_ADD_PARTICLE_MASK | $particleId, $data, $pos); + } + protected function decodePayload() : void{ $this->evid = $this->getVarInt(); $this->position = $this->getVector3(); diff --git a/src/world/particle/GenericParticle.php b/src/world/particle/GenericParticle.php index 778a184414..570292ddd5 100644 --- a/src/world/particle/GenericParticle.php +++ b/src/world/particle/GenericParticle.php @@ -38,6 +38,6 @@ class GenericParticle implements Particle{ } public function encode(Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_ADD_PARTICLE_MASK | $this->id, $this->data, $pos); + return LevelEventPacket::standardParticle($this->id, $this->data, $pos); } } From 4dfa335ae7891ed26454809a42abc44a66b8b723 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Aug 2019 19:05:59 +0100 Subject: [PATCH 1208/3224] convert ParticleIds to final class with private constructor I got tired of auto complete suggesting this shit every time I typed `implements Particle` --- src/network/mcpe/protocol/types/ParticleIds.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/network/mcpe/protocol/types/ParticleIds.php b/src/network/mcpe/protocol/types/ParticleIds.php index 6c0e1a6e48..7cd6f8a083 100644 --- a/src/network/mcpe/protocol/types/ParticleIds.php +++ b/src/network/mcpe/protocol/types/ParticleIds.php @@ -23,7 +23,12 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types; -interface ParticleIds{ +final class ParticleIds{ + + private function __construct(){ + //NOOP + } + public const BUBBLE = 1; //2 same as 1 public const CRITICAL = 3; From 8557c93f049f55ab685c77a885e1bf988b1c7065 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Aug 2019 19:26:26 +0100 Subject: [PATCH 1209/3224] remove GenericParticle, work on isolating network crap in particles --- src/world/particle/AngryVillagerParticle.php | 9 ++-- .../particle/BlockForceFieldParticle.php | 14 +++++- src/world/particle/BubbleParticle.php | 9 ++-- src/world/particle/CriticalParticle.php | 13 +++++- src/world/particle/DustParticle.php | 13 +++++- src/world/particle/EnchantParticle.php | 9 ++-- .../particle/EnchantmentTableParticle.php | 9 ++-- src/world/particle/EntityFlameParticle.php | 9 ++-- src/world/particle/ExplodeParticle.php | 9 ++-- src/world/particle/FlameParticle.php | 9 ++-- src/world/particle/GenericParticle.php | 43 ------------------- src/world/particle/HappyVillagerParticle.php | 9 ++-- src/world/particle/HeartParticle.php | 13 +++++- src/world/particle/HugeExplodeParticle.php | 9 ++-- .../particle/HugeExplodeSeedParticle.php | 9 ++-- src/world/particle/InkParticle.php | 13 +++++- src/world/particle/InstantEnchantParticle.php | 9 ++-- src/world/particle/ItemBreakParticle.php | 13 +++++- src/world/particle/LavaDripParticle.php | 9 ++-- src/world/particle/LavaParticle.php | 9 ++-- src/world/particle/PortalParticle.php | 9 ++-- src/world/particle/RainSplashParticle.php | 9 ++-- src/world/particle/RedstoneParticle.php | 13 +++++- src/world/particle/SmokeParticle.php | 13 +++++- src/world/particle/SnowballPoofParticle.php | 9 ++-- src/world/particle/SplashParticle.php | 9 ++-- src/world/particle/SporeParticle.php | 9 ++-- src/world/particle/TerrainParticle.php | 13 +++++- src/world/particle/WaterDripParticle.php | 9 ++-- src/world/particle/WaterParticle.php | 9 ++-- 30 files changed, 220 insertions(+), 121 deletions(-) delete mode 100644 src/world/particle/GenericParticle.php diff --git a/src/world/particle/AngryVillagerParticle.php b/src/world/particle/AngryVillagerParticle.php index c265c34f17..5ea0ea2041 100644 --- a/src/world/particle/AngryVillagerParticle.php +++ b/src/world/particle/AngryVillagerParticle.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class AngryVillagerParticle extends GenericParticle{ - public function __construct(){ - parent::__construct(ParticleIds::VILLAGER_ANGRY); +class AngryVillagerParticle implements Particle{ + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::VILLAGER_ANGRY, 0, $pos); } } diff --git a/src/world/particle/BlockForceFieldParticle.php b/src/world/particle/BlockForceFieldParticle.php index 2ea6e5e185..24d07d30fb 100644 --- a/src/world/particle/BlockForceFieldParticle.php +++ b/src/world/particle/BlockForceFieldParticle.php @@ -23,10 +23,20 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class BlockForceFieldParticle extends GenericParticle{ +class BlockForceFieldParticle implements Particle{ + + /** @var int */ + private $data; + public function __construct(int $data = 0){ - parent::__construct(ParticleIds::BLOCK_FORCE_FIELD, $data); //TODO: proper encode/decode of data + $this->data = $data; //TODO: proper encode/decode of data + } + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::BLOCK_FORCE_FIELD, $this->data, $pos); } } diff --git a/src/world/particle/BubbleParticle.php b/src/world/particle/BubbleParticle.php index 47e9618ad3..62deede8a2 100644 --- a/src/world/particle/BubbleParticle.php +++ b/src/world/particle/BubbleParticle.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class BubbleParticle extends GenericParticle{ - public function __construct(){ - parent::__construct(ParticleIds::BUBBLE); +class BubbleParticle implements Particle{ + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::BUBBLE, 0, $pos); } } diff --git a/src/world/particle/CriticalParticle.php b/src/world/particle/CriticalParticle.php index b35ca50751..9705645852 100644 --- a/src/world/particle/CriticalParticle.php +++ b/src/world/particle/CriticalParticle.php @@ -23,10 +23,19 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class CriticalParticle extends GenericParticle{ +class CriticalParticle implements Particle{ + /** @var int */ + private $scale; + public function __construct(int $scale = 2){ - parent::__construct(ParticleIds::CRITICAL, $scale); + $this->scale = $scale; + } + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::CRITICAL, $this->scale, $pos); } } diff --git a/src/world/particle/DustParticle.php b/src/world/particle/DustParticle.php index c698062396..de9aa13359 100644 --- a/src/world/particle/DustParticle.php +++ b/src/world/particle/DustParticle.php @@ -23,11 +23,20 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; use pocketmine\utils\Color; -class DustParticle extends GenericParticle{ +class DustParticle implements Particle{ + /** @var Color */ + private $color; + public function __construct(Color $color){ - parent::__construct(ParticleIds::DUST, $color->toARGB()); + $this->color = $color; + } + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::DUST, $this->color->toARGB(), $pos); } } diff --git a/src/world/particle/EnchantParticle.php b/src/world/particle/EnchantParticle.php index abe6a151ca..8925f7a08e 100644 --- a/src/world/particle/EnchantParticle.php +++ b/src/world/particle/EnchantParticle.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class EnchantParticle extends GenericParticle{ - public function __construct(){ - parent::__construct(ParticleIds::MOB_SPELL); +class EnchantParticle implements Particle{ + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::MOB_SPELL, 0, $pos); } } diff --git a/src/world/particle/EnchantmentTableParticle.php b/src/world/particle/EnchantmentTableParticle.php index 2ccf221663..15ac7d14b5 100644 --- a/src/world/particle/EnchantmentTableParticle.php +++ b/src/world/particle/EnchantmentTableParticle.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class EnchantmentTableParticle extends GenericParticle{ - public function __construct(){ - parent::__construct(ParticleIds::ENCHANTMENT_TABLE); +class EnchantmentTableParticle implements Particle{ + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::ENCHANTMENT_TABLE, 0, $pos); } } diff --git a/src/world/particle/EntityFlameParticle.php b/src/world/particle/EntityFlameParticle.php index 7274a73767..66c4ba4c29 100644 --- a/src/world/particle/EntityFlameParticle.php +++ b/src/world/particle/EntityFlameParticle.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class EntityFlameParticle extends GenericParticle{ - public function __construct(){ - parent::__construct(ParticleIds::MOB_FLAME); +class EntityFlameParticle implements Particle{ + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::MOB_FLAME, 0, $pos); } } diff --git a/src/world/particle/ExplodeParticle.php b/src/world/particle/ExplodeParticle.php index 239459f722..8a51a13de0 100644 --- a/src/world/particle/ExplodeParticle.php +++ b/src/world/particle/ExplodeParticle.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class ExplodeParticle extends GenericParticle{ - public function __construct(){ - parent::__construct(ParticleIds::EXPLODE); +class ExplodeParticle implements Particle{ + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::EXPLODE, 0, $pos); } } diff --git a/src/world/particle/FlameParticle.php b/src/world/particle/FlameParticle.php index e117192f36..f78681c8ec 100644 --- a/src/world/particle/FlameParticle.php +++ b/src/world/particle/FlameParticle.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class FlameParticle extends GenericParticle{ - public function __construct(){ - parent::__construct(ParticleIds::FLAME); +class FlameParticle implements Particle{ + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::FLAME, 0, $pos); } } diff --git a/src/world/particle/GenericParticle.php b/src/world/particle/GenericParticle.php deleted file mode 100644 index 570292ddd5..0000000000 --- a/src/world/particle/GenericParticle.php +++ /dev/null @@ -1,43 +0,0 @@ -id = $id & 0xFFF; - $this->data = $data; - } - - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle($this->id, $this->data, $pos); - } -} diff --git a/src/world/particle/HappyVillagerParticle.php b/src/world/particle/HappyVillagerParticle.php index bb452744ee..d6e03881be 100644 --- a/src/world/particle/HappyVillagerParticle.php +++ b/src/world/particle/HappyVillagerParticle.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class HappyVillagerParticle extends GenericParticle{ - public function __construct(){ - parent::__construct(ParticleIds::VILLAGER_HAPPY); +class HappyVillagerParticle implements Particle{ + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::VILLAGER_HAPPY, 0, $pos); } } diff --git a/src/world/particle/HeartParticle.php b/src/world/particle/HeartParticle.php index e115976d48..b3a76baa5e 100644 --- a/src/world/particle/HeartParticle.php +++ b/src/world/particle/HeartParticle.php @@ -23,10 +23,19 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class HeartParticle extends GenericParticle{ +class HeartParticle implements Particle{ + /** @var int */ + private $scale; + public function __construct(int $scale = 0){ - parent::__construct(ParticleIds::HEART, $scale); + $this->scale = $scale; + } + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::HEART, $this->scale, $pos); } } diff --git a/src/world/particle/HugeExplodeParticle.php b/src/world/particle/HugeExplodeParticle.php index fe0d67ecc6..5f9b0c6e72 100644 --- a/src/world/particle/HugeExplodeParticle.php +++ b/src/world/particle/HugeExplodeParticle.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class HugeExplodeParticle extends GenericParticle{ - public function __construct(){ - parent::__construct(ParticleIds::HUGE_EXPLODE); +class HugeExplodeParticle implements Particle{ + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::HUGE_EXPLODE, 0, $pos); } } diff --git a/src/world/particle/HugeExplodeSeedParticle.php b/src/world/particle/HugeExplodeSeedParticle.php index 153d05f738..d27db88750 100644 --- a/src/world/particle/HugeExplodeSeedParticle.php +++ b/src/world/particle/HugeExplodeSeedParticle.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class HugeExplodeSeedParticle extends GenericParticle{ - public function __construct(){ - parent::__construct(ParticleIds::HUGE_EXPLODE_SEED); +class HugeExplodeSeedParticle implements Particle{ + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::HUGE_EXPLODE_SEED, 0, $pos); } } diff --git a/src/world/particle/InkParticle.php b/src/world/particle/InkParticle.php index b7e88531af..c99c07ce8e 100644 --- a/src/world/particle/InkParticle.php +++ b/src/world/particle/InkParticle.php @@ -23,10 +23,19 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class InkParticle extends GenericParticle{ +class InkParticle implements Particle{ + /** @var int */ + private $scale; + public function __construct(int $scale = 0){ - parent::__construct(ParticleIds::INK, $scale); + $this->scale = $scale; + } + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::INK, $this->scale, $pos); } } diff --git a/src/world/particle/InstantEnchantParticle.php b/src/world/particle/InstantEnchantParticle.php index 4a49833a2b..b569600c42 100644 --- a/src/world/particle/InstantEnchantParticle.php +++ b/src/world/particle/InstantEnchantParticle.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class InstantEnchantParticle extends GenericParticle{ - public function __construct(){ - parent::__construct(ParticleIds::MOB_SPELL_INSTANTANEOUS); +class InstantEnchantParticle implements Particle{ + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::MOB_SPELL_INSTANTANEOUS, 0, $pos); } } diff --git a/src/world/particle/ItemBreakParticle.php b/src/world/particle/ItemBreakParticle.php index 574c3dcdaa..7ebee7b0e3 100644 --- a/src/world/particle/ItemBreakParticle.php +++ b/src/world/particle/ItemBreakParticle.php @@ -24,10 +24,19 @@ declare(strict_types=1); namespace pocketmine\world\particle; use pocketmine\item\Item; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class ItemBreakParticle extends GenericParticle{ +class ItemBreakParticle implements Particle{ + /** @var Item */ + private $item; + public function __construct(Item $item){ - parent::__construct(ParticleIds::ITEM_BREAK, ($item->getId() << 16) | $item->getMeta()); + $this->item = $item; + } + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::ITEM_BREAK, ($this->item->getId() << 16) | $this->item->getMeta(), $pos); } } diff --git a/src/world/particle/LavaDripParticle.php b/src/world/particle/LavaDripParticle.php index adf6d7163e..485c8004bf 100644 --- a/src/world/particle/LavaDripParticle.php +++ b/src/world/particle/LavaDripParticle.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class LavaDripParticle extends GenericParticle{ - public function __construct(){ - parent::__construct(ParticleIds::DRIP_LAVA); +class LavaDripParticle implements Particle{ + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::DRIP_LAVA, 0, $pos); } } diff --git a/src/world/particle/LavaParticle.php b/src/world/particle/LavaParticle.php index c9eafc2dcc..fede3825e4 100644 --- a/src/world/particle/LavaParticle.php +++ b/src/world/particle/LavaParticle.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class LavaParticle extends GenericParticle{ - public function __construct(){ - parent::__construct(ParticleIds::LAVA); +class LavaParticle implements Particle{ + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::LAVA, 0, $pos); } } diff --git a/src/world/particle/PortalParticle.php b/src/world/particle/PortalParticle.php index fa511145e7..c45c8eaa38 100644 --- a/src/world/particle/PortalParticle.php +++ b/src/world/particle/PortalParticle.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class PortalParticle extends GenericParticle{ - public function __construct(){ - parent::__construct(ParticleIds::PORTAL); +class PortalParticle implements Particle{ + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::PORTAL, 0, $pos); } } diff --git a/src/world/particle/RainSplashParticle.php b/src/world/particle/RainSplashParticle.php index cafa5b3243..1178557d61 100644 --- a/src/world/particle/RainSplashParticle.php +++ b/src/world/particle/RainSplashParticle.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class RainSplashParticle extends GenericParticle{ - public function __construct(){ - parent::__construct(ParticleIds::RAIN_SPLASH); +class RainSplashParticle implements Particle{ + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::RAIN_SPLASH, 0, $pos); } } diff --git a/src/world/particle/RedstoneParticle.php b/src/world/particle/RedstoneParticle.php index 13fbacba78..4336f01f96 100644 --- a/src/world/particle/RedstoneParticle.php +++ b/src/world/particle/RedstoneParticle.php @@ -23,10 +23,19 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class RedstoneParticle extends GenericParticle{ +class RedstoneParticle implements Particle{ + /** @var int */ + private $lifetime; + public function __construct(int $lifetime = 1){ - parent::__construct(ParticleIds::REDSTONE, $lifetime); + $this->lifetime = $lifetime; + } + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::REDSTONE, $this->lifetime, $pos); } } diff --git a/src/world/particle/SmokeParticle.php b/src/world/particle/SmokeParticle.php index 501e373e1d..3d9f3f9fae 100644 --- a/src/world/particle/SmokeParticle.php +++ b/src/world/particle/SmokeParticle.php @@ -23,10 +23,19 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class SmokeParticle extends GenericParticle{ +class SmokeParticle implements Particle{ + /** @var int */ + private $scale; + public function __construct(int $scale = 0){ - parent::__construct(ParticleIds::SMOKE, $scale); + $this->scale = $scale; + } + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::SMOKE, $this->scale, $pos); } } diff --git a/src/world/particle/SnowballPoofParticle.php b/src/world/particle/SnowballPoofParticle.php index b5b4f1fc15..e82726d1c0 100644 --- a/src/world/particle/SnowballPoofParticle.php +++ b/src/world/particle/SnowballPoofParticle.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class SnowballPoofParticle extends GenericParticle{ - public function __construct(){ - parent::__construct(ParticleIds::SNOWBALL_POOF, 0); +class SnowballPoofParticle implements Particle{ + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::SNOWBALL_POOF, 0, $pos); } } diff --git a/src/world/particle/SplashParticle.php b/src/world/particle/SplashParticle.php index 8d9e965960..171e1b3cbf 100644 --- a/src/world/particle/SplashParticle.php +++ b/src/world/particle/SplashParticle.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class SplashParticle extends GenericParticle{ - public function __construct(){ - parent::__construct(ParticleIds::WATER_SPLASH); +class SplashParticle implements Particle{ + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::WATER_SPLASH, 0, $pos); } } diff --git a/src/world/particle/SporeParticle.php b/src/world/particle/SporeParticle.php index 23e2b3e0a8..d8ef499c8b 100644 --- a/src/world/particle/SporeParticle.php +++ b/src/world/particle/SporeParticle.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class SporeParticle extends GenericParticle{ - public function __construct(){ - parent::__construct(ParticleIds::TOWN_AURA); +class SporeParticle implements Particle{ + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::TOWN_AURA, 0, $pos); } } diff --git a/src/world/particle/TerrainParticle.php b/src/world/particle/TerrainParticle.php index 2514cc66a8..997c2e76b2 100644 --- a/src/world/particle/TerrainParticle.php +++ b/src/world/particle/TerrainParticle.php @@ -24,10 +24,19 @@ declare(strict_types=1); namespace pocketmine\world\particle; use pocketmine\block\Block; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class TerrainParticle extends GenericParticle{ +class TerrainParticle implements Particle{ + /** @var Block */ + private $block; + public function __construct(Block $b){ - parent::__construct(ParticleIds::TERRAIN, $b->getRuntimeId()); + $this->block = $b; + } + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::TERRAIN, $this->block->getRuntimeId(), $pos); } } diff --git a/src/world/particle/WaterDripParticle.php b/src/world/particle/WaterDripParticle.php index 65b2f12e21..71677252a2 100644 --- a/src/world/particle/WaterDripParticle.php +++ b/src/world/particle/WaterDripParticle.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class WaterDripParticle extends GenericParticle{ - public function __construct(){ - parent::__construct(ParticleIds::DRIP_WATER); +class WaterDripParticle implements Particle{ + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::DRIP_WATER, 0, $pos); } } diff --git a/src/world/particle/WaterParticle.php b/src/world/particle/WaterParticle.php index 473a226e09..71beaaab3b 100644 --- a/src/world/particle/WaterParticle.php +++ b/src/world/particle/WaterParticle.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -class WaterParticle extends GenericParticle{ - public function __construct(){ - parent::__construct(ParticleIds::WATER_WAKE); +class WaterParticle implements Particle{ + + public function encode(Vector3 $pos){ + return LevelEventPacket::standardParticle(ParticleIds::WATER_WAKE, 0, $pos); } } From 965177fb743485c9d82342e563925376830d876b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Aug 2019 19:30:57 +0100 Subject: [PATCH 1210/3224] Server: drop redundant proxy function broadcastPacket() this is just making it harder to search for broadcast usages, and we want to get rid of all packet broadcasting shit from Server anyway. --- src/Server.php | 12 ------------ src/entity/Entity.php | 4 ++-- src/entity/Human.php | 2 +- src/entity/object/ItemEntity.php | 2 +- src/entity/projectile/Arrow.php | 2 +- src/world/World.php | 4 ++-- 6 files changed, 7 insertions(+), 19 deletions(-) diff --git a/src/Server.php b/src/Server.php index f70a774853..aebf14bb3f 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1419,18 +1419,6 @@ class Server{ return count($recipients); } - /** - * Broadcasts a Minecraft packet to a list of players - * - * @param Player[] $players - * @param ClientboundPacket $packet - * - * @return bool - */ - public function broadcastPacket(array $players, ClientboundPacket $packet) : bool{ - return $this->broadcastPackets($players, [$packet]); - } - /** * @param Player[] $players * @param ClientboundPacket[] $packets diff --git a/src/entity/Entity.php b/src/entity/Entity.php index d2e54ed58e..47c6f95bcf 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1804,11 +1804,11 @@ abstract class Entity{ } public function broadcastEntityEvent(int $eventId, ?int $eventData = null, ?array $players = null) : void{ - $this->server->broadcastPacket($players ?? $this->getViewers(), ActorEventPacket::create($this->id, $eventId, $eventData ?? 0)); + $this->server->broadcastPackets($players ?? $this->getViewers(), [ActorEventPacket::create($this->id, $eventId, $eventData ?? 0)]); } public function broadcastAnimation(?array $players, int $animationId) : void{ - $this->server->broadcastPacket($players ?? $this->getViewers(), AnimatePacket::create($this->id, $animationId)); + $this->server->broadcastPackets($players ?? $this->getViewers(), [AnimatePacket::create($this->id, $animationId)]); } public function __destruct(){ diff --git a/src/entity/Human.php b/src/entity/Human.php index 8a7eca6e3f..203a85b6bc 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -155,7 +155,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $pk = new PlayerSkinPacket(); $pk->uuid = $this->getUniqueId(); $pk->skin = $this->skin; - $this->server->broadcastPacket($targets ?? $this->hasSpawned, $pk); + $this->server->broadcastPackets($targets ?? $this->hasSpawned, [$pk]); } public function jump() : void{ diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index 2cda0ca329..354819eeca 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -261,7 +261,7 @@ class ItemEntity extends Entity{ return; } - $this->server->broadcastPacket($this->getViewers(), TakeItemActorPacket::create($player->getId(), $this->getId())); + $this->server->broadcastPackets($this->getViewers(), [TakeItemActorPacket::create($player->getId(), $this->getId())]); $playerInventory->addItem(clone $item); $this->flagForDespawn(); diff --git a/src/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php index 01478eacd3..f5bfeeabf4 100644 --- a/src/entity/projectile/Arrow.php +++ b/src/entity/projectile/Arrow.php @@ -197,7 +197,7 @@ class Arrow extends Projectile{ return; } - $this->server->broadcastPacket($this->getViewers(), TakeItemActorPacket::create($player->getId(), $this->getId())); + $this->server->broadcastPackets($this->getViewers(), [TakeItemActorPacket::create($player->getId(), $this->getId())]); $playerInventory->addItem(clone $item); $this->flagForDespawn(); diff --git a/src/world/World.php b/src/world/World.php index 4227b6ad79..b801a3cd5f 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -697,7 +697,7 @@ class World implements ChunkManager{ if(empty($targets)){ $this->broadcastGlobalPacket($pk); }else{ - $this->server->broadcastPacket($targets, $pk); + $this->server->broadcastPackets($targets, [$pk]); } } @@ -2680,7 +2680,7 @@ class World implements ChunkManager{ if(empty($targets)){ $this->broadcastGlobalPacket($pk); }else{ - $this->server->broadcastPacket($targets, $pk); + $this->server->broadcastPackets($targets, [$pk]); } } From 6b22f6867464084a5ebd9607557cbbe517c0e347 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 20 Aug 2019 15:50:34 +0100 Subject: [PATCH 1211/3224] Player: remove sendDataPacket() --- src/entity/Entity.php | 8 +++--- src/entity/Human.php | 6 ++--- src/entity/object/ItemEntity.php | 2 +- src/entity/object/Painting.php | 2 +- .../transaction/CraftingTransaction.php | 2 +- src/player/Player.php | 27 +++++-------------- 6 files changed, 16 insertions(+), 31 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 47c6f95bcf..6ee2f6ff59 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1628,7 +1628,7 @@ abstract class Entity{ $pk->attributes = $this->attributeMap->getAll(); $pk->metadata = $this->getSyncedNetworkData(false); - $player->sendDataPacket($pk); + $player->getNetworkSession()->sendDataPacket($pk); } /** @@ -1670,7 +1670,7 @@ abstract class Entity{ $id = spl_object_id($player); if(isset($this->hasSpawned[$id])){ if($send){ - $player->sendDataPacket(RemoveActorPacket::create($this->id)); + $player->getNetworkSession()->sendDataPacket(RemoveActorPacket::create($this->id)); } unset($this->hasSpawned[$id]); } @@ -1762,11 +1762,11 @@ abstract class Entity{ if($p === $this){ continue; } - $p->sendDataPacket(clone $pk); + $p->getNetworkSession()->sendDataPacket(clone $pk); } if($this instanceof Player){ - $this->sendDataPacket($pk); + $this->getNetworkSession()->sendDataPacket($pk); } } diff --git a/src/entity/Human.php b/src/entity/Human.php index 203a85b6bc..5876e1fd78 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -405,7 +405,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ protected function sendSpawnPacket(Player $player) : void{ if(!($this instanceof Player)){ - $player->sendDataPacket(PlayerListPacket::add([PlayerListEntry::createAdditionEntry($this->uuid, $this->id, $this->getName(), $this->skin)])); + $player->getNetworkSession()->sendDataPacket(PlayerListPacket::add([PlayerListEntry::createAdditionEntry($this->uuid, $this->id, $this->getName(), $this->skin)])); } $pk = new AddPlayerPacket(); @@ -418,7 +418,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $pk->pitch = $this->location->pitch; $pk->item = $this->getInventory()->getItemInHand(); $pk->metadata = $this->getSyncedNetworkData(false); - $player->sendDataPacket($pk); + $player->getNetworkSession()->sendDataPacket($pk); //TODO: Hack for MCPE 1.2.13: DATA_NAMETAG is useless in AddPlayerPacket, so it has to be sent separately $this->sendData($player, [EntityMetadataProperties::NAMETAG => new StringMetadataProperty($this->getNameTag())]); @@ -426,7 +426,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $player->getNetworkSession()->onMobArmorChange($this); if(!($this instanceof Player)){ - $player->sendDataPacket(PlayerListPacket::remove([PlayerListEntry::createRemovalEntry($this->uuid)])); + $player->getNetworkSession()->sendDataPacket(PlayerListPacket::remove([PlayerListEntry::createRemovalEntry($this->uuid)])); } } diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index 354819eeca..698c21d905 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -240,7 +240,7 @@ class ItemEntity extends Entity{ $pk->item = $this->getItem(); $pk->metadata = $this->getSyncedNetworkData(false); - $player->sendDataPacket($pk); + $player->getNetworkSession()->sendDataPacket($pk); } public function onCollideWithPlayer(Player $player) : void{ diff --git a/src/entity/object/Painting.php b/src/entity/object/Painting.php index 8e96e3982d..b9276755b1 100644 --- a/src/entity/object/Painting.php +++ b/src/entity/object/Painting.php @@ -159,7 +159,7 @@ class Painting extends Entity{ $pk->direction = self::FACING_TO_DATA[$this->facing]; $pk->title = $this->motive; - $player->sendDataPacket($pk); + $player->getNetworkSession()->sendDataPacket($pk); } /** diff --git a/src/inventory/transaction/CraftingTransaction.php b/src/inventory/transaction/CraftingTransaction.php index 8b710278fe..26694e16b7 100644 --- a/src/inventory/transaction/CraftingTransaction.php +++ b/src/inventory/transaction/CraftingTransaction.php @@ -167,6 +167,6 @@ class CraftingTransaction extends InventoryTransaction{ * So people don't whine about messy desync issues when someone cancels CraftItemEvent, or when a crafting * transaction goes wrong. */ - $this->source->sendDataPacket(ContainerClosePacket::create(ContainerIds::NONE)); + $this->source->getNetworkSession()->sendDataPacket(ContainerClosePacket::create(ContainerIds::NONE)); } } diff --git a/src/player/Player.php b/src/player/Player.php index 566118ea66..7b010146d4 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -84,7 +84,6 @@ use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\ActorEventPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; -use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\SetTitlePacket; @@ -1902,20 +1901,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->getWorld()->dropItem($this->location->add(0, 1.3, 0), $item, $this->getDirectionVector()->multiply(0.4), 40); } - /** - * @param ClientboundPacket $packet - * @param bool $immediate - * - * @return bool - */ - public function sendDataPacket(ClientboundPacket $packet, bool $immediate = false) : bool{ - if(!$this->isConnected()){ - return false; - } - - return $this->networkSession->sendDataPacket($packet, $immediate); - } - /** * Adds a title text to the user's screen, with an optional subtitle. * @@ -1930,7 +1915,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($subtitle !== ""){ $this->sendSubTitle($subtitle); } - $this->sendDataPacket(SetTitlePacket::title($title)); + $this->networkSession->sendDataPacket(SetTitlePacket::title($title)); } /** @@ -1939,7 +1924,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @param string $subtitle */ public function sendSubTitle(string $subtitle) : void{ - $this->sendDataPacket(SetTitlePacket::subtitle($subtitle)); + $this->networkSession->sendDataPacket(SetTitlePacket::subtitle($subtitle)); } /** @@ -1948,21 +1933,21 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @param string $message */ public function sendActionBarMessage(string $message) : void{ - $this->sendDataPacket(SetTitlePacket::actionBarMessage($message)); + $this->networkSession->sendDataPacket(SetTitlePacket::actionBarMessage($message)); } /** * Removes the title from the client's screen. */ public function removeTitles(){ - $this->sendDataPacket(SetTitlePacket::clearTitle()); + $this->networkSession->sendDataPacket(SetTitlePacket::clearTitle()); } /** * Resets the title duration settings to defaults and removes any existing titles. */ public function resetTitles(){ - $this->sendDataPacket(SetTitlePacket::resetTitleOptions()); + $this->networkSession->sendDataPacket(SetTitlePacket::resetTitleOptions()); } /** @@ -1974,7 +1959,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, */ public function setTitleDuration(int $fadeIn, int $stay, int $fadeOut){ if($fadeIn >= 0 and $stay >= 0 and $fadeOut >= 0){ - $this->sendDataPacket(SetTitlePacket::setAnimationTimes($fadeIn, $stay, $fadeOut)); + $this->networkSession->sendDataPacket(SetTitlePacket::setAnimationTimes($fadeIn, $stay, $fadeOut)); } } From ea374f5c37334aaf82ceed98ce3619d195a56d4d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 20 Aug 2019 15:52:50 +0100 Subject: [PATCH 1212/3224] [ci skip] update changelog --- changelogs/4.0-snapshot.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index d8d617fa1d..d7e32b613f 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -561,6 +561,8 @@ This version features substantial changes to the network system, improving coher - `Player->getPing()`: moved to `NetworkSession` - `Player->getPort()`: moved to `NetworkSession` - `Player->updatePing()`: moved to `NetworkSession` + - `Player->dataPacket()`: replaced by `NetworkSession->sendDataPacket()` + - `Player->sendDataPacket()`: replaced by `NetworkSession->sendDataPacket()` ### Plugin From 794c7b246913f50fdbad1ba61fdd0a452a3c832f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 20 Aug 2019 15:59:27 +0100 Subject: [PATCH 1213/3224] clean up imports --- src/block/BaseRail.php | 1 - src/block/Mycelium.php | 1 - src/block/Vine.php | 3 --- src/entity/projectile/EnderPearl.php | 1 - src/event/player/PlayerMoveEvent.php | 2 +- src/network/mcpe/NetworkSession.php | 2 +- src/network/mcpe/protocol/types/command/CommandData.php | 3 --- src/network/mcpe/protocol/types/command/CommandParameter.php | 1 - .../mcpe/protocol/types/inventory/MismatchTransactionData.php | 1 - .../mcpe/protocol/types/inventory/NormalTransactionData.php | 2 -- .../protocol/types/inventory/ReleaseItemTransactionData.php | 1 - .../types/inventory/UseItemOnEntityTransactionData.php | 1 - .../mcpe/protocol/types/inventory/UseItemTransactionData.php | 1 - src/network/mcpe/serializer/NetworkBinaryStream.php | 2 +- src/player/Player.php | 1 - src/world/World.php | 1 - 16 files changed, 3 insertions(+), 21 deletions(-) diff --git a/src/block/BaseRail.php b/src/block/BaseRail.php index 55105edc44..8bcd22e4b4 100644 --- a/src/block/BaseRail.php +++ b/src/block/BaseRail.php @@ -36,7 +36,6 @@ use function array_shift; use function count; use function implode; use function in_array; -use pocketmine\world\Position; abstract class BaseRail extends Flowable{ diff --git a/src/block/Mycelium.php b/src/block/Mycelium.php index f7b82e1b42..47b40364e3 100644 --- a/src/block/Mycelium.php +++ b/src/block/Mycelium.php @@ -27,7 +27,6 @@ use pocketmine\event\block\BlockSpreadEvent; use pocketmine\item\Item; use pocketmine\math\Facing; use function mt_rand; -use pocketmine\world\Position; class Mycelium extends Opaque{ diff --git a/src/block/Vine.php b/src/block/Vine.php index a46ce59413..8eccf6daaf 100644 --- a/src/block/Vine.php +++ b/src/block/Vine.php @@ -25,14 +25,11 @@ namespace pocketmine\block; use pocketmine\entity\Entity; use pocketmine\item\Item; -use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use function array_intersect_key; -use function array_keys; -use function count; class Vine extends Flowable{ diff --git a/src/entity/projectile/EnderPearl.php b/src/entity/projectile/EnderPearl.php index 536cbbdd62..7a93d1bc95 100644 --- a/src/entity/projectile/EnderPearl.php +++ b/src/entity/projectile/EnderPearl.php @@ -33,7 +33,6 @@ use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\world\particle\EndermanTeleportParticle; use pocketmine\world\sound\EndermanTeleportSound; -use function get_class; class EnderPearl extends Throwable{ public const NETWORK_ID = EntityLegacyIds::ENDER_PEARL; diff --git a/src/event/player/PlayerMoveEvent.php b/src/event/player/PlayerMoveEvent.php index 86e152a513..dbcf92bcf3 100644 --- a/src/event/player/PlayerMoveEvent.php +++ b/src/event/player/PlayerMoveEvent.php @@ -23,10 +23,10 @@ declare(strict_types=1); namespace pocketmine\event\player; +use pocketmine\entity\Location; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\player\Player; -use pocketmine\entity\Location; class PlayerMoveEvent extends PlayerEvent implements Cancellable{ use CancellableTrait; diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 8c983df52f..01f7697003 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -28,8 +28,8 @@ use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\Human; use pocketmine\entity\Living; use pocketmine\event\player\PlayerCreationEvent; -use pocketmine\event\server\DataPacketSendEvent; use pocketmine\event\server\DataPacketReceiveEvent; +use pocketmine\event\server\DataPacketSendEvent; use pocketmine\form\Form; use pocketmine\math\Vector3; use pocketmine\network\BadPacketException; diff --git a/src/network/mcpe/protocol/types/command/CommandData.php b/src/network/mcpe/protocol/types/command/CommandData.php index 5cb462813b..7bfc70354a 100644 --- a/src/network/mcpe/protocol/types/command/CommandData.php +++ b/src/network/mcpe/protocol/types/command/CommandData.php @@ -23,9 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\command; -use pocketmine\network\mcpe\protocol\types\command\CommandEnum; -use pocketmine\network\mcpe\protocol\types\command\CommandParameter; - class CommandData{ /** @var string */ public $name; diff --git a/src/network/mcpe/protocol/types/command/CommandParameter.php b/src/network/mcpe/protocol/types/command/CommandParameter.php index 8234e099bc..1610a59fee 100644 --- a/src/network/mcpe/protocol/types/command/CommandParameter.php +++ b/src/network/mcpe/protocol/types/command/CommandParameter.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\command; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; -use pocketmine\network\mcpe\protocol\types\command\CommandEnum; class CommandParameter{ /** @var string */ diff --git a/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php b/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php index d34d6c4b0b..bd69eb2442 100644 --- a/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; -use pocketmine\network\mcpe\protocol\types\inventory\TransactionData; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; diff --git a/src/network/mcpe/protocol/types/inventory/NormalTransactionData.php b/src/network/mcpe/protocol/types/inventory/NormalTransactionData.php index 70cc893050..ea889f9793 100644 --- a/src/network/mcpe/protocol/types/inventory/NormalTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/NormalTransactionData.php @@ -24,8 +24,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; -use pocketmine\network\mcpe\protocol\types\inventory\TransactionData; -use pocketmine\network\mcpe\protocol\types\inventory\NetworkInventoryAction; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class NormalTransactionData extends TransactionData{ diff --git a/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php b/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php index 70e081c1d4..48f45312bf 100644 --- a/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; -use pocketmine\network\mcpe\protocol\types\inventory\TransactionData; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ReleaseItemTransactionData extends TransactionData{ diff --git a/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php b/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php index 7cd1c3d830..cf1aac04fd 100644 --- a/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; -use pocketmine\network\mcpe\protocol\types\inventory\TransactionData; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class UseItemOnEntityTransactionData extends TransactionData{ diff --git a/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php b/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php index 893ea25058..06edaf8097 100644 --- a/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; -use pocketmine\network\mcpe\protocol\types\inventory\TransactionData; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class UseItemTransactionData extends TransactionData{ diff --git a/src/network/mcpe/serializer/NetworkBinaryStream.php b/src/network/mcpe/serializer/NetworkBinaryStream.php index 77de2a0af5..8af2792e22 100644 --- a/src/network/mcpe/serializer/NetworkBinaryStream.php +++ b/src/network/mcpe/serializer/NetworkBinaryStream.php @@ -39,10 +39,10 @@ use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; use pocketmine\network\mcpe\protocol\types\entity\BlockPosMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\ByteMetadataProperty; +use pocketmine\network\mcpe\protocol\types\entity\CompoundTagMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; use pocketmine\network\mcpe\protocol\types\entity\FloatMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\IntMetadataProperty; -use pocketmine\network\mcpe\protocol\types\entity\CompoundTagMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\LongMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\ShortMetadataProperty; diff --git a/src/player/Player.php b/src/player/Player.php index 7b010146d4..e6a20fac99 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -29,7 +29,6 @@ use pocketmine\block\UnknownBlock; use pocketmine\block\VanillaBlocks; use pocketmine\command\CommandSender; use pocketmine\crafting\CraftingGrid; -use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\VanillaEffects; use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; diff --git a/src/world/World.php b/src/world/World.php index b801a3cd5f..c1c3c61c6a 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -56,7 +56,6 @@ use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\SetDifficultyPacket; use pocketmine\network\mcpe\protocol\SetTimePacket; -use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; use pocketmine\player\Player; use pocketmine\Server; From 3a41a798ad52b6d1c8b7caaa152b8055f7b9ce31 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 20 Aug 2019 16:24:47 +0100 Subject: [PATCH 1214/3224] move forced overflow of SetTimePacket to SetTimePacket::create() --- src/network/mcpe/protocol/SetTimePacket.php | 2 +- src/world/World.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/mcpe/protocol/SetTimePacket.php b/src/network/mcpe/protocol/SetTimePacket.php index afc7cd2dc7..a86d87046b 100644 --- a/src/network/mcpe/protocol/SetTimePacket.php +++ b/src/network/mcpe/protocol/SetTimePacket.php @@ -35,7 +35,7 @@ class SetTimePacket extends DataPacket implements ClientboundPacket{ public static function create(int $time) : self{ $result = new self; - $result->time = $time; + $result->time = $time & 0xffffffff; //avoid overflowing the field, since the packet uses an int32 return $result; } diff --git a/src/world/World.php b/src/world/World.php index c1c3c61c6a..b697d3711f 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -691,7 +691,7 @@ class World implements ChunkManager{ * @param Player ...$targets If empty, will send to all players in the world. */ public function sendTime(Player ...$targets){ - $pk = SetTimePacket::create($this->time & 0xffffffff); //avoid overflowing the field, since the packet uses an int32 + $pk = SetTimePacket::create($this->time); if(empty($targets)){ $this->broadcastGlobalPacket($pk); From 122238d57ef0f0c8da6cbf1b350b82c531fe52b4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 20 Aug 2019 16:25:20 +0100 Subject: [PATCH 1215/3224] add NetworkSession->onEnterWorld() hook --- src/network/mcpe/NetworkSession.php | 6 ++++++ src/player/Player.php | 3 +-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 01f7697003..b326dab4c6 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -797,6 +797,12 @@ class NetworkSession{ } + public function onEnterWorld() : void{ + $world = $this->player->getWorld(); + $world->sendTime($this->player); + $world->sendDifficulty($this->player); + } + /** * @return InventoryManager */ diff --git a/src/player/Player.php b/src/player/Player.php index e6a20fac99..c2c83d16f4 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -811,8 +811,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->usedChunks = []; $this->loadQueue = []; - $this->getWorld()->sendTime($this); - $this->getWorld()->sendDifficulty($this); + $this->networkSession->onEnterWorld(); return true; } From ea2c418a7722b7985e527551d60bd61ea0175892 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 20 Aug 2019 19:48:06 +0100 Subject: [PATCH 1216/3224] update dependency versions --- composer.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/composer.lock b/composer.lock index df0667b0d7..e084f6420e 100644 --- a/composer.lock +++ b/composer.lock @@ -333,12 +333,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "d436a98b85edd18d7b1542fab66827b1e6fc8d68" + "reference": "d7fda7a3abb078f6c709f02ddbb79444efa8cbe2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/d436a98b85edd18d7b1542fab66827b1e6fc8d68", - "reference": "d436a98b85edd18d7b1542fab66827b1e6fc8d68", + "url": "https://api.github.com/repos/pmmp/Math/zipball/d7fda7a3abb078f6c709f02ddbb79444efa8cbe2", + "reference": "d7fda7a3abb078f6c709f02ddbb79444efa8cbe2", "shasum": "" }, "require": { @@ -364,7 +364,7 @@ "source": "https://github.com/pmmp/Math/tree/master", "issues": "https://github.com/pmmp/Math/issues" }, - "time": "2019-07-29T16:46:11+00:00" + "time": "2019-08-14T16:30:00+00:00" }, { "name": "pocketmine/nbt", @@ -372,12 +372,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "0976fcea814978c4ca7e53f5c19e459ae8e341e5" + "reference": "54b907d01272020c96e6f203220ffdf6ca06f1f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/0976fcea814978c4ca7e53f5c19e459ae8e341e5", - "reference": "0976fcea814978c4ca7e53f5c19e459ae8e341e5", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/54b907d01272020c96e6f203220ffdf6ca06f1f6", + "reference": "54b907d01272020c96e6f203220ffdf6ca06f1f6", "shasum": "" }, "require": { @@ -405,7 +405,7 @@ "source": "https://github.com/pmmp/NBT/tree/master", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2019-07-22T15:30:11+00:00" + "time": "2019-07-30T15:46:15+00:00" }, { "name": "pocketmine/raklib", @@ -413,12 +413,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "df98f7e1a67629ee743939318810d3d2bafc5ba3" + "reference": "fc5f701501fc4bc2010b07b06d3d712ffba94060" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/df98f7e1a67629ee743939318810d3d2bafc5ba3", - "reference": "df98f7e1a67629ee743939318810d3d2bafc5ba3", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/fc5f701501fc4bc2010b07b06d3d712ffba94060", + "reference": "fc5f701501fc4bc2010b07b06d3d712ffba94060", "shasum": "" }, "require": { @@ -446,7 +446,7 @@ "source": "https://github.com/pmmp/RakLib/tree/master", "issues": "https://github.com/pmmp/RakLib/issues" }, - "time": "2019-07-22T15:27:51+00:00" + "time": "2019-08-20T18:32:22+00:00" }, { "name": "pocketmine/snooze", From e9fd57275ac90176c33466ddb857d5f824cc4a05 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 21 Aug 2019 17:59:00 +0100 Subject: [PATCH 1217/3224] remove LevelEventSound, remove pitch from sounds that don't support it (most of them) --- src/world/sound/AnvilBreakSound.php | 7 +-- src/world/sound/AnvilFallSound.php | 7 +-- src/world/sound/AnvilUseSound.php | 7 +-- src/world/sound/BlazeShootSound.php | 7 +-- src/world/sound/ClickSound.php | 21 +++++++-- src/world/sound/DoorBumpSound.php | 7 +-- src/world/sound/DoorCrashSound.php | 7 +-- src/world/sound/DoorSound.php | 21 +++++++-- src/world/sound/EndermanTeleportSound.php | 10 ++--- src/world/sound/FizzSound.php | 21 +++++++-- src/world/sound/GhastShootSound.php | 7 +-- src/world/sound/GhastSound.php | 7 +-- src/world/sound/LaunchSound.php | 21 +++++++-- src/world/sound/LevelEventSound.php | 54 ----------------------- src/world/sound/PaintingPlaceSound.php | 8 ++-- src/world/sound/PopSound.php | 21 +++++++-- 16 files changed, 131 insertions(+), 102 deletions(-) delete mode 100644 src/world/sound/LevelEventSound.php diff --git a/src/world/sound/AnvilBreakSound.php b/src/world/sound/AnvilBreakSound.php index 7a75dd415d..0e12bdc355 100644 --- a/src/world/sound/AnvilBreakSound.php +++ b/src/world/sound/AnvilBreakSound.php @@ -23,11 +23,12 @@ declare(strict_types=1); namespace pocketmine\world\sound; +use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class AnvilBreakSound extends LevelEventSound{ +class AnvilBreakSound implements Sound{ - protected function getLevelEventId() : int{ - return LevelEventPacket::EVENT_SOUND_ANVIL_BREAK; + public function encode(?Vector3 $pos){ + return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ANVIL_BREAK, 0, $pos); } } diff --git a/src/world/sound/AnvilFallSound.php b/src/world/sound/AnvilFallSound.php index 08aebde71e..338b5e0f9c 100644 --- a/src/world/sound/AnvilFallSound.php +++ b/src/world/sound/AnvilFallSound.php @@ -23,11 +23,12 @@ declare(strict_types=1); namespace pocketmine\world\sound; +use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class AnvilFallSound extends LevelEventSound{ +class AnvilFallSound implements Sound{ - protected function getLevelEventId() : int{ - return LevelEventPacket::EVENT_SOUND_ANVIL_FALL; + public function encode(?Vector3 $pos){ + return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ANVIL_FALL, 0, $pos); } } diff --git a/src/world/sound/AnvilUseSound.php b/src/world/sound/AnvilUseSound.php index 090289a3d4..cb9c9841db 100644 --- a/src/world/sound/AnvilUseSound.php +++ b/src/world/sound/AnvilUseSound.php @@ -23,11 +23,12 @@ declare(strict_types=1); namespace pocketmine\world\sound; +use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class AnvilUseSound extends LevelEventSound{ +class AnvilUseSound implements Sound{ - protected function getLevelEventId() : int{ - return LevelEventPacket::EVENT_SOUND_ANVIL_USE; + public function encode(?Vector3 $pos){ + return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ANVIL_USE, 0, $pos); } } diff --git a/src/world/sound/BlazeShootSound.php b/src/world/sound/BlazeShootSound.php index 97ac023ccb..ed9335e3b4 100644 --- a/src/world/sound/BlazeShootSound.php +++ b/src/world/sound/BlazeShootSound.php @@ -23,11 +23,12 @@ declare(strict_types=1); namespace pocketmine\world\sound; +use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class BlazeShootSound extends LevelEventSound{ +class BlazeShootSound implements Sound{ - protected function getLevelEventId() : int{ - return LevelEventPacket::EVENT_SOUND_BLAZE_SHOOT; + public function encode(?Vector3 $pos){ + return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_BLAZE_SHOOT, 0, $pos); } } diff --git a/src/world/sound/ClickSound.php b/src/world/sound/ClickSound.php index cec95842de..7fcb02fcea 100644 --- a/src/world/sound/ClickSound.php +++ b/src/world/sound/ClickSound.php @@ -23,11 +23,26 @@ declare(strict_types=1); namespace pocketmine\world\sound; +use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class ClickSound extends LevelEventSound{ +class ClickSound implements Sound{ - protected function getLevelEventId() : int{ - return LevelEventPacket::EVENT_SOUND_CLICK; + /** @var float */ + private $pitch; + + public function __construct(float $pitch = 0){ + $this->pitch = $pitch; + } + + /** + * @return float + */ + public function getPitch() : float{ + return $this->pitch; + } + + public function encode(?Vector3 $pos){ + return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_CLICK, (int) ($this->pitch * 1000), $pos); } } diff --git a/src/world/sound/DoorBumpSound.php b/src/world/sound/DoorBumpSound.php index 7ae4e0c923..3d03176f2f 100644 --- a/src/world/sound/DoorBumpSound.php +++ b/src/world/sound/DoorBumpSound.php @@ -23,11 +23,12 @@ declare(strict_types=1); namespace pocketmine\world\sound; +use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class DoorBumpSound extends LevelEventSound{ +class DoorBumpSound implements Sound{ - protected function getLevelEventId() : int{ - return LevelEventPacket::EVENT_SOUND_DOOR_BUMP; + public function encode(?Vector3 $pos){ + return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_DOOR_BUMP, 0, $pos); } } diff --git a/src/world/sound/DoorCrashSound.php b/src/world/sound/DoorCrashSound.php index d702e83f53..833d4e9e3c 100644 --- a/src/world/sound/DoorCrashSound.php +++ b/src/world/sound/DoorCrashSound.php @@ -23,11 +23,12 @@ declare(strict_types=1); namespace pocketmine\world\sound; +use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class DoorCrashSound extends LevelEventSound{ +class DoorCrashSound implements Sound{ - protected function getLevelEventId() : int{ - return LevelEventPacket::EVENT_SOUND_DOOR_CRASH; + public function encode(?Vector3 $pos){ + return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_DOOR_CRASH, 0, $pos); } } diff --git a/src/world/sound/DoorSound.php b/src/world/sound/DoorSound.php index 7799422581..e457e086da 100644 --- a/src/world/sound/DoorSound.php +++ b/src/world/sound/DoorSound.php @@ -23,11 +23,26 @@ declare(strict_types=1); namespace pocketmine\world\sound; +use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class DoorSound extends LevelEventSound{ +class DoorSound implements Sound{ - protected function getLevelEventId() : int{ - return LevelEventPacket::EVENT_SOUND_DOOR; + /** @var float */ + private $pitch; + + public function __construct(float $pitch = 0){ + $this->pitch = $pitch; + } + + /** + * @return float + */ + public function getPitch() : float{ + return $this->pitch; + } + + public function encode(?Vector3 $pos){ + return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_DOOR, (int) ($this->pitch * 1000), $pos); } } diff --git a/src/world/sound/EndermanTeleportSound.php b/src/world/sound/EndermanTeleportSound.php index d29787a4eb..5f6b2372d0 100644 --- a/src/world/sound/EndermanTeleportSound.php +++ b/src/world/sound/EndermanTeleportSound.php @@ -23,14 +23,12 @@ declare(strict_types=1); namespace pocketmine\world\sound; +use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class EndermanTeleportSound extends LevelEventSound{ - public function __construct(){ //don't allow specifying a pitch - TODO: remove pitch from sounds that don't have it - parent::__construct(); - } +class EndermanTeleportSound implements Sound{ - protected function getLevelEventId() : int{ - return LevelEventPacket::EVENT_SOUND_ENDERMAN_TELEPORT; + public function encode(?Vector3 $pos){ + return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ENDERMAN_TELEPORT, 0, $pos); } } diff --git a/src/world/sound/FizzSound.php b/src/world/sound/FizzSound.php index 52d525620f..d572d7c711 100644 --- a/src/world/sound/FizzSound.php +++ b/src/world/sound/FizzSound.php @@ -23,11 +23,26 @@ declare(strict_types=1); namespace pocketmine\world\sound; +use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class FizzSound extends LevelEventSound{ +class FizzSound implements Sound{ - protected function getLevelEventId() : int{ - return LevelEventPacket::EVENT_SOUND_FIZZ; + /** @var float */ + private $pitch; + + public function __construct(float $pitch = 0){ + $this->pitch = $pitch; + } + + /** + * @return float + */ + public function getPitch() : float{ + return $this->pitch; + } + + public function encode(?Vector3 $pos){ + return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_FIZZ, (int) ($this->pitch * 1000), $pos); } } diff --git a/src/world/sound/GhastShootSound.php b/src/world/sound/GhastShootSound.php index c376afbf55..0029553ef6 100644 --- a/src/world/sound/GhastShootSound.php +++ b/src/world/sound/GhastShootSound.php @@ -23,11 +23,12 @@ declare(strict_types=1); namespace pocketmine\world\sound; +use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class GhastShootSound extends LevelEventSound{ +class GhastShootSound implements Sound{ - protected function getLevelEventId() : int{ - return LevelEventPacket::EVENT_SOUND_GHAST_SHOOT; + public function encode(?Vector3 $pos){ + return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_GHAST_SHOOT, 0, $pos); } } diff --git a/src/world/sound/GhastSound.php b/src/world/sound/GhastSound.php index 3b29b1d79f..484080397f 100644 --- a/src/world/sound/GhastSound.php +++ b/src/world/sound/GhastSound.php @@ -23,11 +23,12 @@ declare(strict_types=1); namespace pocketmine\world\sound; +use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class GhastSound extends LevelEventSound{ +class GhastSound implements Sound{ - protected function getLevelEventId() : int{ - return LevelEventPacket::EVENT_SOUND_GHAST; + public function encode(?Vector3 $pos){ + return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_GHAST, 0, $pos); } } diff --git a/src/world/sound/LaunchSound.php b/src/world/sound/LaunchSound.php index 7b02daff6f..423289b14a 100644 --- a/src/world/sound/LaunchSound.php +++ b/src/world/sound/LaunchSound.php @@ -23,11 +23,26 @@ declare(strict_types=1); namespace pocketmine\world\sound; +use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class LaunchSound extends LevelEventSound{ +class LaunchSound implements Sound{ - protected function getLevelEventId() : int{ - return LevelEventPacket::EVENT_SOUND_SHOOT; + /** @var float */ + private $pitch; + + public function __construct(float $pitch = 0){ + $this->pitch = $pitch; + } + + /** + * @return float + */ + public function getPitch() : float{ + return $this->pitch; + } + + public function encode(?Vector3 $pos){ + return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_SHOOT, (int) ($this->pitch * 1000), $pos); } } diff --git a/src/world/sound/LevelEventSound.php b/src/world/sound/LevelEventSound.php deleted file mode 100644 index 14c0fb7caf..0000000000 --- a/src/world/sound/LevelEventSound.php +++ /dev/null @@ -1,54 +0,0 @@ -pitch = $pitch * 1000; - } - - abstract protected function getLevelEventId() : int; - - public function getPitch() : float{ - return $this->pitch / 1000; - } - - public function setPitch(float $pitch) : void{ - $this->pitch = $pitch * 1000; - } - - public function encode(?Vector3 $pos){ - return LevelEventPacket::create($this->getLevelEventId(), (int) $this->pitch, $pos); - } -} diff --git a/src/world/sound/PaintingPlaceSound.php b/src/world/sound/PaintingPlaceSound.php index 3f8792f3de..cf64b248b9 100644 --- a/src/world/sound/PaintingPlaceSound.php +++ b/src/world/sound/PaintingPlaceSound.php @@ -23,11 +23,13 @@ declare(strict_types=1); namespace pocketmine\world\sound; +use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class PaintingPlaceSound extends LevelEventSound{ +class PaintingPlaceSound implements Sound{ - protected function getLevelEventId() : int{ - return LevelEventPacket::EVENT_SOUND_ITEMFRAME_PLACE; //item frame and painting have the same sound + public function encode(?Vector3 $pos){ + //item frame and painting have the same sound + return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ITEMFRAME_PLACE, 0, $pos); } } diff --git a/src/world/sound/PopSound.php b/src/world/sound/PopSound.php index e74a253523..d38b6473cf 100644 --- a/src/world/sound/PopSound.php +++ b/src/world/sound/PopSound.php @@ -23,11 +23,26 @@ declare(strict_types=1); namespace pocketmine\world\sound; +use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class PopSound extends LevelEventSound{ +class PopSound implements Sound{ - protected function getLevelEventId() : int{ - return LevelEventPacket::EVENT_SOUND_POP; + /** @var float */ + private $pitch; + + public function __construct(float $pitch = 0){ + $this->pitch = $pitch; + } + + /** + * @return float + */ + public function getPitch() : float{ + return $this->pitch; + } + + public function encode(?Vector3 $pos){ + return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_POP, (int) ($this->pitch * 1000), $pos); } } From 018a4467bfd498ece7dbd0536d1933d0f4c52e65 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 21 Aug 2019 18:06:18 +0100 Subject: [PATCH 1218/3224] fix bug in LoginPacketHandler (incorrect metadata array in PlayerInfo) this was intended to make available things like the deviceOS, input method etc without placing an API requirement for custom implementations to provide such information. --- src/network/mcpe/handler/LoginPacketHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index ebb04ee9c3..77468a7ed4 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -93,7 +93,7 @@ class LoginPacketHandler extends PacketHandler{ $packet->clientData[LoginPacket::I_LANGUAGE_CODE], $packet->extraData[LoginPacket::I_XUID], $packet->clientData[LoginPacket::I_CLIENT_RANDOM_ID], - $packet->extraData + $packet->clientData )); $ev = new PlayerPreLoginEvent( From dbdcabcc567a7dd8e510582f5d9ada621bf0142d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 21 Aug 2019 18:17:31 +0100 Subject: [PATCH 1219/3224] Player: get rid of CID requirement from player info, CID is still available via extradata if supported by client impl this is useless for PM and it doesn't have any fit purpose for plugin use either, so it doesn't make sense to expose it to the API. --- src/network/mcpe/handler/LoginPacketHandler.php | 1 - src/player/Player.php | 13 ------------- src/player/PlayerInfo.php | 13 +------------ 3 files changed, 1 insertion(+), 26 deletions(-) diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index 77468a7ed4..f188e2252a 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -92,7 +92,6 @@ class LoginPacketHandler extends PacketHandler{ $skin, $packet->clientData[LoginPacket::I_LANGUAGE_CODE], $packet->extraData[LoginPacket::I_XUID], - $packet->clientData[LoginPacket::I_CLIENT_RANDOM_ID], $packet->clientData )); diff --git a/src/player/Player.php b/src/player/Player.php index c2c83d16f4..2a75966242 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -162,8 +162,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, protected $username; /** @var string */ protected $displayName; - /** @var int */ - protected $randomClientId; /** @var string */ protected $xuid = ""; /** @var bool */ @@ -270,7 +268,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->username = $username; $this->displayName = $this->username; $this->locale = $this->playerInfo->getLocale(); - $this->randomClientId = $this->playerInfo->getClientId(); $this->uuid = $this->playerInfo->getUuid(); $this->xuid = $this->playerInfo->getXuid(); @@ -384,16 +381,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return ""; } - /** - * This might disappear in the future. Please use getUniqueId() instead. - * @deprecated - * - * @return int - */ - public function getClientId(){ - return $this->randomClientId; - } - public function isBanned() : bool{ return $this->server->getNameBans()->isBanned($this->username); } diff --git a/src/player/PlayerInfo.php b/src/player/PlayerInfo.php index a6cd03a98b..e25b50e317 100644 --- a/src/player/PlayerInfo.php +++ b/src/player/PlayerInfo.php @@ -42,8 +42,6 @@ class PlayerInfo{ private $locale; /** @var string */ private $xuid; - /** @var int */ - private $clientId; /** @var array */ private $extraData; @@ -53,16 +51,14 @@ class PlayerInfo{ * @param Skin $skin * @param string $locale * @param string $xuid - * @param int $clientId * @param array $extraData */ - public function __construct(string $username, UUID $uuid, Skin $skin, string $locale, string $xuid, int $clientId, array $extraData = []){ + public function __construct(string $username, UUID $uuid, Skin $skin, string $locale, string $xuid, array $extraData = []){ $this->username = TextFormat::clean($username); $this->uuid = $uuid; $this->skin = $skin; $this->locale = $locale; $this->xuid = $xuid; - $this->clientId = $clientId; $this->extraData = $extraData; } @@ -101,13 +97,6 @@ class PlayerInfo{ return $this->xuid; } - /** - * @return int - */ - public function getClientId() : int{ - return $this->clientId; - } - /** * @return array */ From 7e5193355e6af8828ae6713d700abf0e3b088902 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 21 Aug 2019 18:46:39 +0100 Subject: [PATCH 1220/3224] Remove old entity movement hack This was intended to try and mitigate player movement clipping through blocks triggering anti cheat. Now that the anti cheat is gone, this code is no longer needed. --- src/entity/Entity.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 6ee2f6ff59..cb387ef06c 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -136,8 +136,6 @@ abstract class Entity{ private $health = 20.0; private $maxHealth = 20; - /** @var float */ - protected $ySize = 0.0; /** @var float */ protected $stepHeight = 0.0; /** @var bool */ @@ -1214,7 +1212,6 @@ abstract class Entity{ if($this->keepMovement){ $this->boundingBox->offset($dx, $dy, $dz); }else{ - $this->ySize *= 0.4; /* if($this->isColliding){ //With cobweb? @@ -1281,7 +1278,7 @@ abstract class Entity{ $moveBB->offset(0, 0, $dz); - if($this->stepHeight > 0 and $fallingFlag and $this->ySize < 0.05 and ($movX != $dx or $movZ != $dz)){ + if($this->stepHeight > 0 and $fallingFlag and ($movX != $dx or $movZ != $dz)){ $cx = $dx; $cy = $dy; $cz = $dz; @@ -1310,13 +1307,14 @@ abstract class Entity{ $stepBB->offset(0, 0, $dz); + //TODO: here we need to shift back down on the Y-axis to the top of the target block (we don't want to jump into the air when walking onto carpet) + if(($cx ** 2 + $cz ** 2) >= ($dx ** 2 + $dz ** 2)){ $dx = $cx; $dy = $cy; $dz = $cz; }else{ $moveBB = $stepBB; - $this->ySize += 0.5; //FIXME: this should be the height of the block it walked up, not fixed 0.5 } } @@ -1324,7 +1322,7 @@ abstract class Entity{ } $this->location->x = ($this->boundingBox->minX + $this->boundingBox->maxX) / 2; - $this->location->y = $this->boundingBox->minY - $this->ySize; + $this->location->y = $this->boundingBox->minY; $this->location->z = ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2; $this->checkChunks(); @@ -1564,7 +1562,6 @@ abstract class Entity{ if($ev->isCancelled()){ return false; } - $this->ySize = 0; $pos = $ev->getTo(); $this->setMotion($this->temporalVector->setComponents(0, 0, 0)); From aa60aa69ee505b5d12d308c63a0959d66d0b0a90 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 21 Aug 2019 18:51:08 -0400 Subject: [PATCH 1221/3224] World: fix bug in getNearestEntity() fuck you PhpStorm --- src/world/World.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index b697d3711f..91455bf5ca 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1889,7 +1889,7 @@ class World implements ChunkManager{ if(!($entity instanceof $entityType) or $entity->isFlaggedForDespawn() or (!$includeDead and !$entity->isAlive())){ continue; } - $distSq = $entity->distanceSquared($pos); + $distSq = $entity->getPosition()->distanceSquared($pos); if($distSq < $currentTargetDistSq){ $currentTargetDistSq = $distSq; $currentTarget = $entity; From e5b02ee5e0bbe3beda1ae519f8f73d2639f8a2b6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 23 Aug 2019 17:16:07 +0100 Subject: [PATCH 1222/3224] make logic for fetching handler lists more consistent --- src/event/Event.php | 1 - src/event/HandlerListManager.php | 34 ++++---- src/plugin/PluginManager.php | 15 +--- .../phpunit/event/HandlerListManagerTest.php | 81 +++++++++++++++++++ .../event/TestAbstractAllowHandleEvent.php | 31 +++++++ tests/phpunit/event/TestAbstractEvent.php | 28 +++++++ tests/phpunit/event/TestConcreteEvent.php | 28 +++++++ .../TestConcreteExtendsAbstractEvent.php | 28 +++++++ .../TestConcreteExtendsAllowHandleEvent.php | 28 +++++++ .../TestConcreteExtendsConcreteEvent.php | 28 +++++++ 10 files changed, 272 insertions(+), 30 deletions(-) create mode 100644 tests/phpunit/event/HandlerListManagerTest.php create mode 100644 tests/phpunit/event/TestAbstractAllowHandleEvent.php create mode 100644 tests/phpunit/event/TestAbstractEvent.php create mode 100644 tests/phpunit/event/TestConcreteEvent.php create mode 100644 tests/phpunit/event/TestConcreteExtendsAbstractEvent.php create mode 100644 tests/phpunit/event/TestConcreteExtendsAllowHandleEvent.php create mode 100644 tests/phpunit/event/TestConcreteExtendsConcreteEvent.php diff --git a/src/event/Event.php b/src/event/Event.php index 7f1cc4bb5e..f5ecd17e9a 100644 --- a/src/event/Event.php +++ b/src/event/Event.php @@ -56,7 +56,6 @@ abstract class Event{ } $handlerList = HandlerListManager::global()->getListFor(get_class($this)); - assert($handlerList !== null, "Called event should have a valid HandlerList"); ++self::$eventCallDepth; try{ diff --git a/src/event/HandlerListManager.php b/src/event/HandlerListManager.php index 0097d7a1c4..a21e7a49c0 100644 --- a/src/event/HandlerListManager.php +++ b/src/event/HandlerListManager.php @@ -58,6 +58,18 @@ class HandlerListManager{ } } + private static function isValidClass(\ReflectionClass $class) : bool{ + $tags = Utils::parseDocComment((string) $class->getDocComment()); + return !$class->isAbstract() || isset($tags["allowHandle"]); + } + + private static function resolveNearestHandleableParent(\ReflectionClass $class) : ?\ReflectionClass{ + for($parent = $class->getParentClass(); $parent !== false && !self::isValidClass($parent); $parent = $parent->getParentClass()){ + //NOOP + } + return $parent ?: null; + } + /** * Returns the HandlerList for listeners that explicitly handle this event. * @@ -65,30 +77,22 @@ class HandlerListManager{ * * @param string $event * - * @return null|HandlerList + * @return HandlerList * @throws \ReflectionException + * @throws \InvalidArgumentException */ - public function getListFor(string $event) : ?HandlerList{ + public function getListFor(string $event) : HandlerList{ if(isset($this->allLists[$event])){ return $this->allLists[$event]; } $class = new \ReflectionClass($event); - $tags = Utils::parseDocComment((string) $class->getDocComment()); - - if($class->isAbstract() && !isset($tags["allowHandle"])){ - return null; + if(!self::isValidClass($class)){ + throw new \InvalidArgumentException("Event must be non-abstract or have the @allowHandle annotation"); } - $super = $class; - $parentList = null; - while($parentList === null && ($super = $super->getParentClass()) !== false){ - // skip $noHandle events in the inheritance tree to go to the nearest ancestor - // while loop to allow skipping $noHandle events in the inheritance tree - $parentList = $this->getListFor($super->getName()); - } - - return $this->allLists[$event] = new HandlerList($event, $parentList); + $parent = self::resolveNearestHandleableParent($class); + return $this->allLists[$event] = new HandlerList($event, $parent !== null ? $this->getListFor($parent->getName()) : null); } /** diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 76325d469c..87714d6287 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -568,19 +568,6 @@ class PluginManager{ $timings = new TimingsHandler("Plugin: " . $plugin->getDescription()->getFullName() . " Event: " . $handlerName . "(" . (new \ReflectionClass($event))->getShortName() . ")"); - $this->getEventListeners($event)->register(new RegisteredListener($handler, $priority, $plugin, $handleCancelled, $timings)); - } - - /** - * @param string $event - * - * @return HandlerList - */ - private function getEventListeners(string $event) : HandlerList{ - $list = HandlerListManager::global()->getListFor($event); - if($list === null){ - throw new PluginException("Abstract events not declaring @allowHandle cannot be handled (tried to register listener for $event)"); - } - return $list; + HandlerListManager::global()->getListFor($event)->register(new RegisteredListener($handler, $priority, $plugin, $handleCancelled, $timings)); } } diff --git a/tests/phpunit/event/HandlerListManagerTest.php b/tests/phpunit/event/HandlerListManagerTest.php new file mode 100644 index 0000000000..a15456d9e4 --- /dev/null +++ b/tests/phpunit/event/HandlerListManagerTest.php @@ -0,0 +1,81 @@ +isValidFunc = (new \ReflectionMethod(HandlerListManager::class, 'isValidClass'))->getClosure(); + /** @see HandlerListManager::resolveNearestHandleableParent() */ + $this->resolveParentFunc = (new \ReflectionMethod(HandlerListManager::class, 'resolveNearestHandleableParent'))->getClosure(); + } + + public function isValidClassProvider() : \Generator{ + yield [new \ReflectionClass(Event::class), false, "event base should not be handleable"]; + yield [new \ReflectionClass(TestConcreteEvent::class), true, ""]; + yield [new \ReflectionClass(TestAbstractEvent::class), false, "abstract event cannot be handled"]; + yield [new \ReflectionClass(TestAbstractAllowHandleEvent::class), true, "abstract event declaring @allowHandle should be handleable"]; + } + + /** + * @dataProvider isValidClassProvider + * + * @param \ReflectionClass $class + * @param bool $isValid + * @param string $reason + */ + public function testIsValidClass(\ReflectionClass $class, bool $isValid, string $reason) : void{ + self::assertSame($isValid, ($this->isValidFunc)($class), $reason); + } + + public function resolveParentClassProvider() : \Generator{ + yield [new \ReflectionClass(TestConcreteExtendsAllowHandleEvent::class), new \ReflectionClass(TestAbstractAllowHandleEvent::class)]; + yield [new \ReflectionClass(TestConcreteEvent::class), null]; + yield [new \ReflectionClass(TestConcreteExtendsAbstractEvent::class), null]; + yield [new \ReflectionClass(TestConcreteExtendsConcreteEvent::class), new \ReflectionClass(TestConcreteEvent::class)]; + } + + /** + * @dataProvider resolveParentClassProvider + * + * @param \ReflectionClass $class + * @param \ReflectionClass|null $expect + */ + public function testResolveParentClass(\ReflectionClass $class, ?\ReflectionClass $expect) : void{ + if($expect === null){ + self::assertNull(($this->resolveParentFunc)($class)); + }else{ + self::assertSame(($this->resolveParentFunc)($class)->getName(), $expect->getName()); + } + } +} diff --git a/tests/phpunit/event/TestAbstractAllowHandleEvent.php b/tests/phpunit/event/TestAbstractAllowHandleEvent.php new file mode 100644 index 0000000000..382660714b --- /dev/null +++ b/tests/phpunit/event/TestAbstractAllowHandleEvent.php @@ -0,0 +1,31 @@ + Date: Fri, 23 Aug 2019 19:12:55 +0100 Subject: [PATCH 1223/3224] turn EventPriority into final class instead of abstract class --- src/event/EventPriority.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/event/EventPriority.php b/src/event/EventPriority.php index 71d52f1c1d..c7a788518e 100644 --- a/src/event/EventPriority.php +++ b/src/event/EventPriority.php @@ -35,7 +35,12 @@ use function strtoupper; * * MONITOR events should not change the event outcome or contents */ -abstract class EventPriority{ +final class EventPriority{ + + private function __construct(){ + //NOOP + } + public const ALL = [ self::LOWEST, self::LOW, From ef8eba43d7e5dad0fe1d08f87a5eb1a78f25ffa7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 23 Aug 2019 19:54:41 +0100 Subject: [PATCH 1224/3224] RegisteredListener: validate priority at a more sensible time --- src/event/HandlerList.php | 3 --- src/event/RegisteredListener.php | 4 ++++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/event/HandlerList.php b/src/event/HandlerList.php index 6d391215f9..c6ffbaac68 100644 --- a/src/event/HandlerList.php +++ b/src/event/HandlerList.php @@ -49,9 +49,6 @@ class HandlerList{ * @throws \Exception */ public function register(RegisteredListener $listener) : void{ - if(!in_array($listener->getPriority(), EventPriority::ALL, true)){ - return; - } if(isset($this->handlerSlots[$listener->getPriority()][spl_object_id($listener)])){ throw new \InvalidStateException("This listener is already registered to priority {$listener->getPriority()} of event {$this->class}"); } diff --git a/src/event/RegisteredListener.php b/src/event/RegisteredListener.php index 0026063fe7..ac06cd6520 100644 --- a/src/event/RegisteredListener.php +++ b/src/event/RegisteredListener.php @@ -25,6 +25,7 @@ namespace pocketmine\event; use pocketmine\plugin\Plugin; use pocketmine\timings\TimingsHandler; +use function in_array; class RegisteredListener{ @@ -52,6 +53,9 @@ class RegisteredListener{ * @param TimingsHandler $timings */ public function __construct(\Closure $handler, int $priority, Plugin $plugin, bool $handleCancelled, TimingsHandler $timings){ + if(!in_array($priority, EventPriority::ALL, true)){ + throw new \InvalidArgumentException("Invalid priority number $priority"); + } $this->handler = $handler; $this->priority = $priority; $this->plugin = $plugin; From 75a2d796715d0d2830b7f3f1d2645b7cecad4bcf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 24 Aug 2019 15:39:23 +0100 Subject: [PATCH 1225/3224] convert more constant interfaces to final classes, close #2885 --- src/block/BlockLegacyIds.php | 6 +++++- src/block/BlockLegacyMetadata.php | 6 +++++- src/block/BlockToolType.php | 6 +++++- src/item/ItemIds.php | 6 +++++- src/network/mcpe/protocol/ProtocolInfo.php | 6 +++++- src/network/mcpe/protocol/types/DimensionIds.php | 6 +++++- src/network/mcpe/protocol/types/PlayerPermissions.php | 6 +++++- src/network/mcpe/protocol/types/inventory/ContainerIds.php | 6 +++++- src/network/mcpe/protocol/types/inventory/WindowTypes.php | 6 +++++- 9 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/block/BlockLegacyIds.php b/src/block/BlockLegacyIds.php index 4a1d521c00..c846c74fc2 100644 --- a/src/block/BlockLegacyIds.php +++ b/src/block/BlockLegacyIds.php @@ -23,7 +23,11 @@ declare(strict_types=1); namespace pocketmine\block; -interface BlockLegacyIds{ +final class BlockLegacyIds{ + + private function __construct(){ + //NOOP + } public const AIR = 0; public const STONE = 1; diff --git a/src/block/BlockLegacyMetadata.php b/src/block/BlockLegacyMetadata.php index 904f4efc04..016057c4e1 100644 --- a/src/block/BlockLegacyMetadata.php +++ b/src/block/BlockLegacyMetadata.php @@ -26,7 +26,11 @@ namespace pocketmine\block; /** * Constants for legacy metadata for various blocks. */ -interface BlockLegacyMetadata{ +final class BlockLegacyMetadata{ + + private function __construct(){ + //NOOP + } public const ANVIL_NORMAL = 0; public const ANVIL_SLIGHTLY_DAMAGED = 4; diff --git a/src/block/BlockToolType.php b/src/block/BlockToolType.php index ca58763594..e7046bd879 100644 --- a/src/block/BlockToolType.php +++ b/src/block/BlockToolType.php @@ -27,7 +27,11 @@ namespace pocketmine\block; * Types of tools that can be used to break blocks * Blocks may allow multiple tool types by combining these bitflags */ -interface BlockToolType{ +final class BlockToolType{ + + private function __construct(){ + //NOOP + } public const NONE = 0; public const SWORD = 1 << 0; diff --git a/src/item/ItemIds.php b/src/item/ItemIds.php index 0aadcf4e0a..a38e53171a 100644 --- a/src/item/ItemIds.php +++ b/src/item/ItemIds.php @@ -23,7 +23,11 @@ declare(strict_types=1); namespace pocketmine\item; -interface ItemIds{ +final class ItemIds{ + + private function __construct(){ + //NOOP + } public const LIT_BLAST_FURNACE = -214; public const COMPOSTER = -213; diff --git a/src/network/mcpe/protocol/ProtocolInfo.php b/src/network/mcpe/protocol/ProtocolInfo.php index 152dd44639..c6fd511644 100644 --- a/src/network/mcpe/protocol/ProtocolInfo.php +++ b/src/network/mcpe/protocol/ProtocolInfo.php @@ -26,7 +26,11 @@ namespace pocketmine\network\mcpe\protocol; /** * Version numbers and packet IDs for the current Minecraft PE protocol */ -interface ProtocolInfo{ +final class ProtocolInfo{ + + private function __construct(){ + //NOOP + } /** * NOTE TO DEVELOPERS diff --git a/src/network/mcpe/protocol/types/DimensionIds.php b/src/network/mcpe/protocol/types/DimensionIds.php index 2777a03280..855bc94be2 100644 --- a/src/network/mcpe/protocol/types/DimensionIds.php +++ b/src/network/mcpe/protocol/types/DimensionIds.php @@ -23,7 +23,11 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types; -interface DimensionIds{ +final class DimensionIds{ + + private function __construct(){ + //NOOP + } public const OVERWORLD = 0; public const NETHER = 1; diff --git a/src/network/mcpe/protocol/types/PlayerPermissions.php b/src/network/mcpe/protocol/types/PlayerPermissions.php index 6c9cd376d2..04668e4fe0 100644 --- a/src/network/mcpe/protocol/types/PlayerPermissions.php +++ b/src/network/mcpe/protocol/types/PlayerPermissions.php @@ -23,7 +23,11 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types; -interface PlayerPermissions{ +final class PlayerPermissions{ + + private function __construct(){ + //NOOP + } public const CUSTOM = 3; public const OPERATOR = 2; diff --git a/src/network/mcpe/protocol/types/inventory/ContainerIds.php b/src/network/mcpe/protocol/types/inventory/ContainerIds.php index 6a9e70ba34..2a60e6b29d 100644 --- a/src/network/mcpe/protocol/types/inventory/ContainerIds.php +++ b/src/network/mcpe/protocol/types/inventory/ContainerIds.php @@ -23,7 +23,11 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\inventory; -interface ContainerIds{ +final class ContainerIds{ + + private function __construct(){ + //NOOP + } public const NONE = -1; public const INVENTORY = 0; diff --git a/src/network/mcpe/protocol/types/inventory/WindowTypes.php b/src/network/mcpe/protocol/types/inventory/WindowTypes.php index 1f1edbdf77..6ee75daa1e 100644 --- a/src/network/mcpe/protocol/types/inventory/WindowTypes.php +++ b/src/network/mcpe/protocol/types/inventory/WindowTypes.php @@ -25,7 +25,11 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\inventory; -interface WindowTypes{ +final class WindowTypes{ + + private function __construct(){ + //NOOP + } public const NONE = -9; From c9cd6ee038f476fb261635651a422059cfb38c28 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 24 Aug 2019 15:58:06 +0100 Subject: [PATCH 1226/3224] ExperienceOrb: fix passing invalid argument to multi-signature Vector3::subtract() I knew I should have scrapped these multi-signature functions years ago... --- src/entity/object/ExperienceOrb.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entity/object/ExperienceOrb.php b/src/entity/object/ExperienceOrb.php index 0fce9180db..31528fbb19 100644 --- a/src/entity/object/ExperienceOrb.php +++ b/src/entity/object/ExperienceOrb.php @@ -199,7 +199,7 @@ class ExperienceOrb extends Entity{ $this->setTargetPlayer($currentTarget); if($currentTarget !== null){ - $vector = $currentTarget->getPosition()->add(0, $currentTarget->getEyeHeight() / 2, 0)->subtract($this)->divide(self::MAX_TARGET_DISTANCE); + $vector = $currentTarget->getPosition()->add(0, $currentTarget->getEyeHeight() / 2, 0)->subtract($this->location)->divide(self::MAX_TARGET_DISTANCE); $distance = $vector->lengthSquared(); if($distance < 1){ From 6a4ae4cb94232bf7dbd3896f42a689bfae691191 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 24 Aug 2019 17:19:27 +0100 Subject: [PATCH 1227/3224] remove position parameters from BlockFactory::get() and BlockFactory::fromFullBlock() --- src/block/BlockFactory.php | 16 +++++----------- src/entity/projectile/Projectile.php | 6 +++--- src/world/Explosion.php | 17 +++++++++-------- src/world/World.php | 7 ++----- 4 files changed, 19 insertions(+), 27 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 847c8b8440..065f34eacb 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -51,7 +51,6 @@ use pocketmine\block\utils\TreeType; use pocketmine\item\Item; use pocketmine\item\ItemIds; use pocketmine\item\ToolTier; -use pocketmine\world\Position; use function array_fill; use function array_filter; use function get_class; @@ -830,13 +829,12 @@ class BlockFactory{ /** * Returns a new Block instance with the specified ID, meta and position. * - * @param int $id - * @param int $meta - * @param Position $pos + * @param int $id + * @param int $meta * * @return Block */ - public static function get(int $id, int $meta = 0, ?Position $pos = null) : Block{ + public static function get(int $id, int $meta = 0) : Block{ if($meta < 0 or $meta > 0xf){ throw new \InvalidArgumentException("Block meta value $meta is out of bounds"); } @@ -856,15 +854,11 @@ class BlockFactory{ $block = new UnknownBlock(new BID($id, $meta)); } - if($pos !== null){ - $block->position($pos->getWorld(), $pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ()); - } - return $block; } - public static function fromFullBlock(int $fullState, ?Position $pos = null) : Block{ - return self::get($fullState >> 4, $fullState & 0xf, $pos); + public static function fromFullBlock(int $fullState) : Block{ + return self::get($fullState >> 4, $fullState & 0xf); } /** diff --git a/src/entity/projectile/Projectile.php b/src/entity/projectile/Projectile.php index 52376fbc11..62b00af9cd 100644 --- a/src/entity/projectile/Projectile.php +++ b/src/entity/projectile/Projectile.php @@ -41,7 +41,6 @@ use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\timings\Timings; -use pocketmine\world\Position; use pocketmine\world\World; use function assert; use function atan2; @@ -84,7 +83,7 @@ abstract class Projectile extends Entity{ $blockData = null; if($nbt->hasTag("tileX", IntTag::class) and $nbt->hasTag("tileY", IntTag::class) and $nbt->hasTag("tileZ", IntTag::class)){ - $blockPos = new Position($nbt->getInt("tileX"), $nbt->getInt("tileY"), $nbt->getInt("tileZ"), $this->getWorld()); + $blockPos = new Vector3($nbt->getInt("tileX"), $nbt->getInt("tileY"), $nbt->getInt("tileZ")); }else{ break; } @@ -101,7 +100,8 @@ abstract class Projectile extends Entity{ break; } - $this->blockHit = BlockFactory::get($blockId, $blockData, $blockPos); + $this->blockHit = BlockFactory::get($blockId, $blockData); + $this->blockHit->position($this->getWorld(), $blockPos->getFloorX(), $blockPos->getFloorY(), $blockPos->getFloorZ()); }while(false); } diff --git a/src/world/Explosion.php b/src/world/Explosion.php index 8a9f57ba96..5805c6d461 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -95,7 +95,6 @@ class Explosion{ } $vector = new Vector3(0, 0, 0); - $vBlock = new Position(0, 0, 0, $this->world); $currentChunk = null; $currentSubChunk = null; @@ -115,21 +114,23 @@ class Explosion{ $x = (int) $pointerX; $y = (int) $pointerY; $z = (int) $pointerZ; - $vBlock->x = $pointerX >= $x ? $x : $x - 1; - $vBlock->y = $pointerY >= $y ? $y : $y - 1; - $vBlock->z = $pointerZ >= $z ? $z : $z - 1; + $vBlockX = $pointerX >= $x ? $x : $x - 1; + $vBlockY = $pointerY >= $y ? $y : $y - 1; + $vBlockZ = $pointerZ >= $z ? $z : $z - 1; - if(!$this->subChunkHandler->moveTo($vBlock->x, $vBlock->y, $vBlock->z, false)){ + if(!$this->subChunkHandler->moveTo($vBlockX, $vBlockY, $vBlockZ, false)){ continue; } - $state = $this->subChunkHandler->currentSubChunk->getFullBlock($vBlock->x & 0x0f, $vBlock->y & 0x0f, $vBlock->z & 0x0f); + $state = $this->subChunkHandler->currentSubChunk->getFullBlock($vBlockX & 0x0f, $vBlockY & 0x0f, $vBlockZ & 0x0f); if($state !== 0){ $blastForce -= (BlockFactory::$blastResistance[$state] / 5 + 0.3) * $this->stepLen; if($blastForce > 0){ - if(!isset($this->affectedBlocks[$index = World::blockHash($vBlock->x, $vBlock->y, $vBlock->z)])){ - $this->affectedBlocks[$index] = BlockFactory::fromFullBlock($state, $vBlock); + if(!isset($this->affectedBlocks[$index = World::blockHash($vBlockX, $vBlockY, $vBlockZ)])){ + $_block = BlockFactory::fromFullBlock($state); + $_block->position($this->world, $vBlockX, $vBlockY, $vBlockZ); + $this->affectedBlocks[$index] = $_block; } } } diff --git a/src/world/World.php b/src/world/World.php index 91455bf5ca..27c29472b1 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -996,11 +996,8 @@ class World implements ChunkManager{ if(isset($this->randomTickBlocks[$state])){ /** @var Block $block */ - $block = BlockFactory::fromFullBlock($state, $this->temporalPosition->setComponents( - $chunkX * 16 + $x, - ($Y << 4) + $y, - $chunkZ * 16 + $z - )); + $block = BlockFactory::fromFullBlock($state); + $block->position($this, $chunkX * 16 + $x, ($Y << 4) + $y, $chunkZ * 16 + $z); $block->onRandomTick(); } } From aa006cca0ebb6b7df048aa9684fef725b7a995fa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 24 Aug 2019 19:59:57 +0100 Subject: [PATCH 1228/3224] WorldProviderManager: added getAvailableProviders() this will be used by standalone CLI conversion tool --- src/world/format/io/WorldProviderManager.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/world/format/io/WorldProviderManager.php b/src/world/format/io/WorldProviderManager.php index cdd655653e..ddc92cde43 100644 --- a/src/world/format/io/WorldProviderManager.php +++ b/src/world/format/io/WorldProviderManager.php @@ -102,6 +102,13 @@ abstract class WorldProviderManager{ return $result; } + /** + * @return string[]|WorldProvider[] + */ + public static function getAvailableProviders() : array{ + return self::$providers; + } + /** * Returns a WorldProvider by name, or null if not found * From 42ffc45c1cb830939f8d695363ce14d9e8f3c306 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Aug 2019 15:45:40 +0100 Subject: [PATCH 1229/3224] world providers: don't assume that getPath() has a trailing directory separator --- src/world/format/io/leveldb/LevelDB.php | 3 ++- src/world/format/io/region/RegionWorldProvider.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 3e61de8a0d..04a1fd8650 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -63,6 +63,7 @@ use function strlen; use function substr; use function trim; use function unpack; +use const DIRECTORY_SEPARATOR; use const LEVELDB_ZLIB_RAW_COMPRESSION; class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ @@ -132,7 +133,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ } protected function loadLevelData() : WorldData{ - return new BedrockWorldData($this->getPath() . "level.dat"); + return new BedrockWorldData($this->getPath() . DIRECTORY_SEPARATOR . "level.dat"); } public function getWorldHeight() : int{ diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index 0fc1aed406..735904d6eb 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -41,6 +41,7 @@ use function scandir; use function strrpos; use function substr; use function time; +use const DIRECTORY_SEPARATOR; use const SCANDIR_SORT_NONE; abstract class RegionWorldProvider extends BaseWorldProvider{ @@ -87,7 +88,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ protected $regions = []; protected function loadLevelData() : WorldData{ - return new JavaWorldData($this->getPath() . "level.dat"); + return new JavaWorldData($this->getPath() . DIRECTORY_SEPARATOR . "level.dat"); } public function doGarbageCollection() : void{ From 95a4081d24d81e8e0506321b4fccce32a6097507 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Aug 2019 16:04:51 +0100 Subject: [PATCH 1230/3224] update composer dependencies --- composer.json | 2 +- composer.lock | 35 ++++++++++++++++++----------------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/composer.json b/composer.json index d6820458cc..594e625a91 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "mdanter/ecc": "^0.5.0", "pocketmine/raklib": "dev-master", "pocketmine/spl": "dev-master", - "pocketmine/binaryutils": "^0.1.9", + "pocketmine/binaryutils": "dev-master", "pocketmine/nbt": "dev-master", "pocketmine/math": "dev-master", "pocketmine/snooze": "^0.1.0", diff --git a/composer.lock b/composer.lock index e084f6420e..e2b04a9b27 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3f4e9e3e4dfdd48390caf564839e8b46", + "content-hash": "eedc6357547d912c1cc4d47477573086", "packages": [ { "name": "adhocore/json-comment", @@ -295,16 +295,16 @@ }, { "name": "pocketmine/binaryutils", - "version": "0.1.9", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/pmmp/BinaryUtils.git", - "reference": "8b3b1160679398387cb896fd5d06018413437dfa" + "reference": "ea71180bb494217abdb8867f4a0f1c353551b425" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/8b3b1160679398387cb896fd5d06018413437dfa", - "reference": "8b3b1160679398387cb896fd5d06018413437dfa", + "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/ea71180bb494217abdb8867f4a0f1c353551b425", + "reference": "ea71180bb494217abdb8867f4a0f1c353551b425", "shasum": "" }, "require": { @@ -322,10 +322,10 @@ ], "description": "Classes and methods for conveniently handling binary data", "support": { - "source": "https://github.com/pmmp/BinaryUtils/tree/0.1.9", + "source": "https://github.com/pmmp/BinaryUtils/tree/master", "issues": "https://github.com/pmmp/BinaryUtils/issues" }, - "time": "2019-07-22T13:15:53+00:00" + "time": "2019-08-25T14:54:25+00:00" }, { "name": "pocketmine/math", @@ -372,19 +372,19 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "54b907d01272020c96e6f203220ffdf6ca06f1f6" + "reference": "56cb637f904d8cce05d45ff275ee1634bb52e9c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/54b907d01272020c96e6f203220ffdf6ca06f1f6", - "reference": "54b907d01272020c96e6f203220ffdf6ca06f1f6", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/56cb637f904d8cce05d45ff275ee1634bb52e9c3", + "reference": "56cb637f904d8cce05d45ff275ee1634bb52e9c3", "shasum": "" }, "require": { "ext-zlib": "*", "php": ">=7.2.0", "php-64bit": "*", - "pocketmine/binaryutils": "^0.1.9" + "pocketmine/binaryutils": "dev-master" }, "type": "library", "autoload": { @@ -405,7 +405,7 @@ "source": "https://github.com/pmmp/NBT/tree/master", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2019-07-30T15:46:15+00:00" + "time": "2019-08-25T15:00:08+00:00" }, { "name": "pocketmine/raklib", @@ -413,12 +413,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "fc5f701501fc4bc2010b07b06d3d712ffba94060" + "reference": "9b6e021dcecd6ac3e0fa11655d6b42c13c541e54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/fc5f701501fc4bc2010b07b06d3d712ffba94060", - "reference": "fc5f701501fc4bc2010b07b06d3d712ffba94060", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/9b6e021dcecd6ac3e0fa11655d6b42c13c541e54", + "reference": "9b6e021dcecd6ac3e0fa11655d6b42c13c541e54", "shasum": "" }, "require": { @@ -428,7 +428,7 @@ "php": ">=7.2.0", "php-64bit": "*", "php-ipv6": "*", - "pocketmine/binaryutils": "^0.1.9", + "pocketmine/binaryutils": "dev-master", "pocketmine/snooze": "^0.1.0", "pocketmine/spl": "dev-master" }, @@ -446,7 +446,7 @@ "source": "https://github.com/pmmp/RakLib/tree/master", "issues": "https://github.com/pmmp/RakLib/issues" }, - "time": "2019-08-20T18:32:22+00:00" + "time": "2019-08-25T15:01:01+00:00" }, { "name": "pocketmine/snooze", @@ -518,6 +518,7 @@ "stability-flags": { "pocketmine/raklib": 20, "pocketmine/spl": 20, + "pocketmine/binaryutils": 20, "pocketmine/nbt": 20, "pocketmine/math": 20, "daverandom/callback-validator": 20 From 39d5903c3edb23125aa33cd2c87a5d792dd156ac Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Aug 2019 16:09:51 +0100 Subject: [PATCH 1231/3224] Remove INT32_MIN and INT32_MAX global constants --- src/PocketMine.php | 5 ----- src/command/defaults/EffectCommand.php | 4 ++-- src/entity/Human.php | 5 ++--- src/entity/effect/EffectInstance.php | 6 +++--- src/world/SimpleChunkManager.php | 7 +++---- src/world/World.php | 7 +++---- src/world/WorldManager.php | 5 ++--- src/world/format/io/data/BedrockWorldData.php | 3 ++- 8 files changed, 17 insertions(+), 25 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index 6f38f9ec93..f54bea1581 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -21,11 +21,6 @@ declare(strict_types=1); -namespace { - const INT32_MIN = -0x80000000; - const INT32_MAX = 0x7fffffff; -} - namespace pocketmine { use pocketmine\thread\ThreadManager; diff --git a/src/command/defaults/EffectCommand.php b/src/command/defaults/EffectCommand.php index d78b5cc04b..b7ec3760bf 100644 --- a/src/command/defaults/EffectCommand.php +++ b/src/command/defaults/EffectCommand.php @@ -28,10 +28,10 @@ use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\VanillaEffects; use pocketmine\lang\TranslationContainer; +use pocketmine\utils\Limits; use pocketmine\utils\TextFormat; use function count; use function strtolower; -use const INT32_MAX; class EffectCommand extends VanillaCommand{ @@ -78,7 +78,7 @@ class EffectCommand extends VanillaCommand{ $amplification = 0; if(count($args) >= 3){ - if(($d = $this->getBoundedInt($sender, $args[2], 0, (int) (INT32_MAX / 20))) === null){ + if(($d = $this->getBoundedInt($sender, $args[2], 0, (int) (Limits::INT32_MAX / 20))) === null){ return false; } $duration = $d * 20; //ticks diff --git a/src/entity/Human.php b/src/entity/Human.php index 5876e1fd78..955db74c7f 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -49,6 +49,7 @@ use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\entity\StringMetadataProperty; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\player\Player; +use pocketmine\utils\Limits; use pocketmine\utils\UUID; use pocketmine\world\sound\TotemUseSound; use pocketmine\world\World; @@ -59,8 +60,6 @@ use function in_array; use function min; use function random_int; use function strlen; -use const INT32_MAX; -use const INT32_MIN; class Human extends Living implements ProjectileSource, InventoryHolder{ @@ -274,7 +273,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ if($nbt->hasTag("XpSeed", IntTag::class)){ $this->xpSeed = $nbt->getInt("XpSeed"); }else{ - $this->xpSeed = random_int(INT32_MIN, INT32_MAX); + $this->xpSeed = random_int(Limits::INT32_MIN, Limits::INT32_MAX); } } diff --git a/src/entity/effect/EffectInstance.php b/src/entity/effect/EffectInstance.php index 4da94f6024..ee7665d385 100644 --- a/src/entity/effect/EffectInstance.php +++ b/src/entity/effect/EffectInstance.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\entity\effect; use pocketmine\utils\Color; +use pocketmine\utils\Limits; use function max; -use const INT32_MAX; class EffectInstance{ /** @var Effect */ @@ -89,8 +89,8 @@ class EffectInstance{ * @return $this */ public function setDuration(int $duration) : EffectInstance{ - if($duration < 0 or $duration > INT32_MAX){ - throw new \InvalidArgumentException("Effect duration must be in range 0 - " . INT32_MAX . ", got $duration"); + if($duration < 0 or $duration > Limits::INT32_MAX){ + throw new \InvalidArgumentException("Effect duration must be in range 0 - " . Limits::INT32_MAX . ", got $duration"); } $this->duration = $duration; diff --git a/src/world/SimpleChunkManager.php b/src/world/SimpleChunkManager.php index 928f033ba3..14673fe5f1 100644 --- a/src/world/SimpleChunkManager.php +++ b/src/world/SimpleChunkManager.php @@ -26,10 +26,9 @@ namespace pocketmine\world; use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\VanillaBlocks; +use pocketmine\utils\Limits; use pocketmine\world\format\Chunk; use pocketmine\world\utils\SubChunkIteratorManager; -use const INT32_MAX; -use const INT32_MIN; class SimpleChunkManager implements ChunkManager{ @@ -102,9 +101,9 @@ class SimpleChunkManager implements ChunkManager{ public function isInWorld(int $x, int $y, int $z) : bool{ return ( - $x <= INT32_MAX and $x >= INT32_MIN and + $x <= Limits::INT32_MAX and $x >= Limits::INT32_MIN and $y < $this->worldHeight and $y >= 0 and - $z <= INT32_MAX and $z >= INT32_MIN + $z <= Limits::INT32_MAX and $z >= Limits::INT32_MIN ); } } diff --git a/src/world/World.php b/src/world/World.php index 27c29472b1..caf1c73440 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -60,6 +60,7 @@ use pocketmine\network\mcpe\protocol\UpdateBlockPacket; use pocketmine\player\Player; use pocketmine\Server; use pocketmine\timings\Timings; +use pocketmine\utils\Limits; use pocketmine\utils\ReversePriorityQueue; use pocketmine\world\biome\Biome; use pocketmine\world\format\Chunk; @@ -100,8 +101,6 @@ use function mt_rand; use function spl_object_id; use function strtolower; use function trim; -use const INT32_MAX; -use const INT32_MIN; use const M_PI; use const PHP_INT_MAX; use const PHP_INT_MIN; @@ -1260,9 +1259,9 @@ class World implements ChunkManager{ public function isInWorld(int $x, int $y, int $z) : bool{ return ( - $x <= INT32_MAX and $x >= INT32_MIN and + $x <= Limits::INT32_MAX and $x >= Limits::INT32_MIN and $y < $this->worldHeight and $y >= 0 and - $z <= INT32_MAX and $z >= INT32_MIN + $z <= Limits::INT32_MAX and $z >= Limits::INT32_MIN ); } diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index f7604dc592..f8059aaa83 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -29,6 +29,7 @@ use pocketmine\event\world\WorldLoadEvent; use pocketmine\event\world\WorldUnloadEvent; use pocketmine\Server; use pocketmine\timings\Timings; +use pocketmine\utils\Limits; use pocketmine\utils\Utils; use pocketmine\world\format\io\exception\CorruptedWorldException; use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; @@ -50,8 +51,6 @@ use function random_int; use function round; use function sprintf; use function trim; -use const INT32_MAX; -use const INT32_MIN; class WorldManager{ /** @var World[] */ @@ -276,7 +275,7 @@ class WorldManager{ return false; } - $seed = $seed ?? random_int(INT32_MIN, INT32_MAX); + $seed = $seed ?? random_int(Limits::INT32_MIN, Limits::INT32_MAX); Utils::testValidInstance($generator, Generator::class); diff --git a/src/world/format/io/data/BedrockWorldData.php b/src/world/format/io/data/BedrockWorldData.php index b38c5fa839..6e04c434d4 100644 --- a/src/world/format/io/data/BedrockWorldData.php +++ b/src/world/format/io/data/BedrockWorldData.php @@ -31,6 +31,7 @@ use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\utils\Binary; +use pocketmine\utils\Limits; use pocketmine\utils\Utils; use pocketmine\world\format\io\exception\CorruptedWorldException; use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; @@ -112,7 +113,7 @@ class BedrockWorldData extends BaseNbtWorldData{ throw new CorruptedWorldException($e->getMessage(), 0, $e); } - $version = $worldData->getInt("StorageVersion", INT32_MAX, true); + $version = $worldData->getInt("StorageVersion", Limits::INT32_MAX, true); if($version > self::CURRENT_STORAGE_VERSION){ throw new UnsupportedWorldFormatException("LevelDB world format version $version is currently unsupported"); } From 647f86a5b818c308e7fd690178c20099a836cfe9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Aug 2019 16:14:35 +0100 Subject: [PATCH 1232/3224] PocketMine.php: remove redundant ini_set() this is overridden later on by MemoryManager. --- src/PocketMine.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index f54bea1581..7ccaabf1a1 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -178,8 +178,6 @@ namespace pocketmine { ini_set("display_startup_errors", '1'); ini_set("default_charset", "utf-8"); - ini_set("memory_limit", '-1'); - define('pocketmine\RESOURCE_PATH', \pocketmine\PATH . 'resources' . DIRECTORY_SEPARATOR); $opts = getopt("", ["data:", "plugins:", "no-wizard", "enable-ansi", "disable-ansi"]); From ad0f100f8e3b3450d022dce0753aac33c4d958cb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Aug 2019 16:25:27 +0100 Subject: [PATCH 1233/3224] remove \pocketmine\START_TIME, add Server->getStartTime() --- src/PocketMine.php | 2 -- src/Server.php | 14 ++++++++++++-- src/command/defaults/StatusCommand.php | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index 7ccaabf1a1..eaa0def364 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -263,8 +263,6 @@ namespace pocketmine { } } - //TODO: move this to a Server field - define('pocketmine\START_TIME', microtime(true)); ThreadManager::init(); new Server($autoloader, $logger, \pocketmine\DATA, \pocketmine\PLUGIN_PATH); diff --git a/src/Server.php b/src/Server.php index aebf14bb3f..edeed2f7dc 100644 --- a/src/Server.php +++ b/src/Server.php @@ -209,6 +209,8 @@ class Server{ private $currentTPS = 20; /** @var float */ private $currentUse = 0; + /** @var float */ + private $startTime; /** @var bool */ private $doTitleTick = true; @@ -547,6 +549,13 @@ class Server{ return round((array_sum($this->useAverage) / count($this->useAverage)) * 100, 2); } + /** + * @return float + */ + public function getStartTime() : float{ + return $this->startTime; + } + /** * @return SimpleCommandMap */ @@ -970,6 +979,7 @@ class Server{ throw new \InvalidStateException("Only one server instance can exist at once"); } self::$instance = $this; + $this->startTime = microtime(true); $this->tickSleeper = new SleeperHandler(); $this->autoloader = $autoloader; @@ -1285,7 +1295,7 @@ class Server{ $this->logger->info($this->getLanguage()->translateString("pocketmine.server.defaultGameMode", [$this->getGamemode()->getTranslationKey()])); - $this->logger->info($this->getLanguage()->translateString("pocketmine.server.startFinished", [round(microtime(true) - \pocketmine\START_TIME, 3)])); + $this->logger->info($this->getLanguage()->translateString("pocketmine.server.startFinished", [round(microtime(true) - $this->startTime, 3)])); //TODO: move console parts to a separate component $consoleSender = new ConsoleCommandSender(); @@ -1736,7 +1746,7 @@ class Server{ $this->isRunning = false; //Force minimum uptime to be >= 120 seconds, to reduce the impact of spammy crash loops - $spacing = ((int) \pocketmine\START_TIME) - time() + 120; + $spacing = ((int) $this->startTime) - time() + 120; if($spacing > 0){ echo "--- Waiting $spacing seconds to throttle automatic restart (you can kill the process safely now) ---" . PHP_EOL; sleep($spacing); diff --git a/src/command/defaults/StatusCommand.php b/src/command/defaults/StatusCommand.php index 74d22076ea..82a5d1f603 100644 --- a/src/command/defaults/StatusCommand.php +++ b/src/command/defaults/StatusCommand.php @@ -54,7 +54,7 @@ class StatusCommand extends VanillaCommand{ $server = $sender->getServer(); $sender->sendMessage(TextFormat::GREEN . "---- " . TextFormat::WHITE . "Server status" . TextFormat::GREEN . " ----"); - $time = microtime(true) - \pocketmine\START_TIME; + $time = microtime(true) - $server->getStartTime(); $seconds = floor($time % 60); $minutes = null; From fdfbaf4e95d9760199b363005cca71b852d5eee5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Aug 2019 16:34:26 +0100 Subject: [PATCH 1234/3224] make startup performance warnings a little more coherent --- src/PocketMine.php | 20 +++++++++++++------- src/Server.php | 4 ---- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index eaa0def364..b8d5a7773a 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -122,6 +122,18 @@ namespace pocketmine { return $messages; } + function emit_performance_warnings(\Logger $logger){ + if(extension_loaded("xdebug")){ + $logger->warning("Xdebug extension is enabled. This has a major impact on performance."); + } + if(((int) ini_get('zend.assertions')) !== -1){ + $logger->warning("Debugging assertions are enabled. This may degrade performance. To disable them, set `zend.assertions = -1` in php.ini."); + } + if(\Phar::running(true) === ""){ + $logger->warning("Non-packaged installation detected. This will degrade autoloading speed and make startup times longer."); + } + } + function server(){ if(!empty($messages = check_platform_dependencies())){ echo PHP_EOL; @@ -219,13 +231,7 @@ namespace pocketmine { $logger = new MainLogger(\pocketmine\DATA . "server.log"); \GlobalLogger::set($logger); - if(extension_loaded("xdebug")){ - $logger->warning(PHP_EOL . PHP_EOL . PHP_EOL . "\tYou are running " . \pocketmine\NAME . " with xdebug enabled. This has a major impact on performance." . PHP_EOL . PHP_EOL); - } - - if(\Phar::running(true) === ""){ - $logger->warning("Non-packaged " . \pocketmine\NAME . " installation detected. Consider using a phar in production for better performance."); - } + emit_performance_warnings($logger); $version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER); define('pocketmine\VERSION', $version->getFullVersion(true)); diff --git a/src/Server.php b/src/Server.php index edeed2f7dc..621cf95109 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1070,10 +1070,6 @@ class Server{ $this->logger->warning(str_repeat("-", 40)); } - if(((int) ini_get('zend.assertions')) !== -1){ - $this->logger->warning("Debugging assertions are enabled, this may impact on performance. To disable them, set `zend.assertions = -1` in php.ini."); - } - ini_set('assert.exception', '1'); if($this->logger instanceof MainLogger){ From 51ed564c5ea1b5909a53cfd64dc217f292080630 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Aug 2019 16:46:01 +0100 Subject: [PATCH 1235/3224] SetupWizard: remove non-obvious dependencies on dynamic constants, require path in constructor --- src/PocketMine.php | 2 +- src/wizard/SetupWizard.php | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index b8d5a7773a..65d1999273 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -262,7 +262,7 @@ namespace pocketmine { $exitCode = 0; do{ if(!file_exists(\pocketmine\DATA . "server.properties") and !isset($opts["no-wizard"])){ - $installer = new SetupWizard(); + $installer = new SetupWizard(\pocketmine\DATA); if(!$installer->run()){ $exitCode = -1; break; diff --git a/src/wizard/SetupWizard.php b/src/wizard/SetupWizard.php index 3ecc9de05b..a0c6f67beb 100644 --- a/src/wizard/SetupWizard.php +++ b/src/wizard/SetupWizard.php @@ -47,9 +47,11 @@ class SetupWizard{ /** @var Language */ private $lang; + /** @var string */ + private $dataPath; - public function __construct(){ - + public function __construct(string $dataPath){ + $this->dataPath = $dataPath; } public function run() : bool{ @@ -84,7 +86,7 @@ class SetupWizard{ } //this has to happen here to prevent user avoiding agreeing to license - $config = new Config(\pocketmine\DATA . "server.properties", Config::PROPERTIES); + $config = new Config($this->dataPath . "/server.properties", Config::PROPERTIES); $config->set("language", $lang); $config->save(); @@ -132,7 +134,7 @@ LICENSE; } private function generateBaseConfig() : void{ - $config = new Config(\pocketmine\DATA . "server.properties", Config::PROPERTIES); + $config = new Config($this->dataPath . "/server.properties", Config::PROPERTIES); $config->set("motd", ($name = $this->getInput($this->lang->get("name_your_server"), self::DEFAULT_NAME))); $config->set("server-name", $name); @@ -169,14 +171,14 @@ LICENSE; if($op === ""){ $this->error($this->lang->get("op_warning")); }else{ - $ops = new Config(\pocketmine\DATA . "ops.txt", Config::ENUM); + $ops = new Config($this->dataPath . "/ops.txt", Config::ENUM); $ops->set($op, true); $ops->save(); } $this->message($this->lang->get("whitelist_info")); - $config = new Config(\pocketmine\DATA . "server.properties", Config::PROPERTIES); + $config = new Config($this->dataPath . "/server.properties", Config::PROPERTIES); if(strtolower($this->getInput($this->lang->get("whitelist_enable"), "n", "y/N")) === "y"){ $this->error($this->lang->get("whitelist_warning")); $config->set("white-list", true); @@ -187,7 +189,7 @@ LICENSE; } private function networkFunctions() : void{ - $config = new Config(\pocketmine\DATA . "server.properties", Config::PROPERTIES); + $config = new Config($this->dataPath . "/server.properties", Config::PROPERTIES); $this->error($this->lang->get("query_warning1")); $this->error($this->lang->get("query_warning2")); if(strtolower($this->getInput($this->lang->get("query_disable"), "n", "y/N")) === "y"){ From 40da5059c9a0f3de91b8a439f56def6cd8bd8706 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Aug 2019 16:55:24 +0100 Subject: [PATCH 1236/3224] PocketMine.php: remove \pocketmine\DATA dynamic constant --- src/PocketMine.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index 65d1999273..ee17bd72af 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -194,21 +194,21 @@ namespace pocketmine { $opts = getopt("", ["data:", "plugins:", "no-wizard", "enable-ansi", "disable-ansi"]); - define('pocketmine\DATA', isset($opts["data"]) ? $opts["data"] . DIRECTORY_SEPARATOR : realpath(getcwd()) . DIRECTORY_SEPARATOR); + $dataPath = isset($opts["data"]) ? $opts["data"] . DIRECTORY_SEPARATOR : realpath(getcwd()) . DIRECTORY_SEPARATOR; define('pocketmine\PLUGIN_PATH', isset($opts["plugins"]) ? $opts["plugins"] . DIRECTORY_SEPARATOR : realpath(getcwd()) . DIRECTORY_SEPARATOR . "plugins" . DIRECTORY_SEPARATOR); - if(!file_exists(\pocketmine\DATA)){ - mkdir(\pocketmine\DATA, 0777, true); + if(!file_exists($dataPath)){ + mkdir($dataPath, 0777, true); } - define('pocketmine\LOCK_FILE_PATH', \pocketmine\DATA . 'server.lock'); + define('pocketmine\LOCK_FILE_PATH', $dataPath . 'server.lock'); define('pocketmine\LOCK_FILE', fopen(\pocketmine\LOCK_FILE_PATH, "a+b")); if(!flock(\pocketmine\LOCK_FILE, LOCK_EX | LOCK_NB)){ //wait for a shared lock to avoid race conditions if two servers started at the same time - this makes sure the //other server wrote its PID and released exclusive lock before we get our lock flock(\pocketmine\LOCK_FILE, LOCK_SH); $pid = stream_get_contents(\pocketmine\LOCK_FILE); - critical_error("Another " . \pocketmine\NAME . " instance (PID $pid) is already using this folder (" . realpath(\pocketmine\DATA) . ")."); + critical_error("Another " . \pocketmine\NAME . " instance (PID $pid) is already using this folder (" . realpath($dataPath) . ")."); critical_error("Please stop the other server first before running a new one."); exit(1); } @@ -228,7 +228,7 @@ namespace pocketmine { Terminal::init(); } - $logger = new MainLogger(\pocketmine\DATA . "server.log"); + $logger = new MainLogger($dataPath . "server.log"); \GlobalLogger::set($logger); emit_performance_warnings($logger); @@ -261,8 +261,8 @@ namespace pocketmine { $exitCode = 0; do{ - if(!file_exists(\pocketmine\DATA . "server.properties") and !isset($opts["no-wizard"])){ - $installer = new SetupWizard(\pocketmine\DATA); + if(!file_exists($dataPath . "server.properties") and !isset($opts["no-wizard"])){ + $installer = new SetupWizard($dataPath); if(!$installer->run()){ $exitCode = -1; break; @@ -270,7 +270,7 @@ namespace pocketmine { } ThreadManager::init(); - new Server($autoloader, $logger, \pocketmine\DATA, \pocketmine\PLUGIN_PATH); + new Server($autoloader, $logger, $dataPath, \pocketmine\PLUGIN_PATH); $logger->info("Stopping other threads"); From 3eea2442a7bd8a5ee355746e37842d417c16a80a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Aug 2019 17:36:50 +0100 Subject: [PATCH 1237/3224] move filesystem-related functions to pocketmine\utils\Filesystem --- src/CrashDump.php | 7 +- src/Server.php | 3 +- src/network/mcpe/raklib/RakLibInterface.php | 3 +- src/utils/Filesystem.php | 78 +++++++++++++++++++++ src/utils/MainLogger.php | 2 +- src/utils/Utils.php | 49 +------------ src/world/format/io/FormatConverter.php | 3 +- 7 files changed, 92 insertions(+), 53 deletions(-) create mode 100644 src/utils/Filesystem.php diff --git a/src/CrashDump.php b/src/CrashDump.php index 9f0d0f5b6c..8645e0af45 100644 --- a/src/CrashDump.php +++ b/src/CrashDump.php @@ -26,6 +26,7 @@ namespace pocketmine; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\plugin\PluginBase; use pocketmine\plugin\PluginManager; +use pocketmine\utils\Filesystem; use pocketmine\utils\Utils; use pocketmine\utils\VersionString; use raklib\RakLib; @@ -203,7 +204,7 @@ class CrashDump{ $error = (array) error_get_last(); $error["trace"] = Utils::currentTrace(3); //Skipping CrashDump->baseCrash, CrashDump->construct, Server->crashDump $error["fullFile"] = $error["file"]; - $error["file"] = Utils::cleanPath($error["file"]); + $error["file"] = Filesystem::cleanPath($error["file"]); try{ $error["type"] = \ErrorUtils::errorTypeToString($error["type"]); }catch(\InvalidArgumentException $e){ @@ -262,7 +263,7 @@ class CrashDump{ } private function determinePluginFromFile(string $filePath, bool $crashFrame) : bool{ - $frameCleanPath = Utils::cleanPath($filePath); //this will be empty in phar stub + $frameCleanPath = Filesystem::cleanPath($filePath); //this will be empty in phar stub if(strpos($frameCleanPath, "plugins") === 0 and file_exists($filePath)){ $this->addLine(); if($crashFrame){ @@ -277,7 +278,7 @@ class CrashDump{ $file = $reflection->getProperty("file"); $file->setAccessible(true); foreach($this->server->getPluginManager()->getPlugins() as $plugin){ - $filePath = Utils::cleanPath($file->getValue($plugin)); + $filePath = Filesystem::cleanPath($file->getValue($plugin)); if(strpos($frameCleanPath, $filePath) === 0){ $this->data["plugin"] = $plugin->getName(); $this->addLine("BAD PLUGIN: " . $plugin->getDescription()->getFullName()); diff --git a/src/Server.php b/src/Server.php index 621cf95109..3c3b1348fa 100644 --- a/src/Server.php +++ b/src/Server.php @@ -83,6 +83,7 @@ use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; use pocketmine\updater\AutoUpdater; use pocketmine\utils\Config; +use pocketmine\utils\Filesystem; use pocketmine\utils\Internet; use pocketmine\utils\MainLogger; use pocketmine\utils\Process; @@ -1651,7 +1652,7 @@ class Server{ $errstr = preg_replace('/\s+/', ' ', trim($errstr)); - $errfile = Utils::cleanPath($errfile); + $errfile = Filesystem::cleanPath($errfile); $this->logger->logException($e, $trace); diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 8c91b37f93..fa53227cf7 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -30,6 +30,7 @@ use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\Network; use pocketmine\Server; use pocketmine\snooze\SleeperNotifier; +use pocketmine\utils\Filesystem; use pocketmine\utils\Utils; use raklib\protocol\EncapsulatedPacket; use raklib\protocol\PacketReliability; @@ -156,7 +157,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $logger->error("Bad packet (error ID $errorId): " . $e->getMessage()); //intentionally doesn't use logException, we don't want spammy packet error traces to appear in release mode - $logger->debug("Origin: " . Utils::cleanPath($e->getFile()) . "(" . $e->getLine() . ")"); + $logger->debug("Origin: " . Filesystem::cleanPath($e->getFile()) . "(" . $e->getLine() . ")"); foreach(Utils::printableTrace($e->getTrace()) as $frame){ $logger->debug($frame); } diff --git a/src/utils/Filesystem.php b/src/utils/Filesystem.php new file mode 100644 index 0000000000..4ccf01a30d --- /dev/null +++ b/src/utils/Filesystem.php @@ -0,0 +1,78 @@ + "plugins", //this has to come BEFORE \pocketmine\PATH because it's inside that by default on src installations + \pocketmine\PATH => "" + ]; + foreach($cleanPaths as $cleanPath => $replacement){ + $cleanPath = rtrim(str_replace(["\\", "phar://"], ["/", ""], $cleanPath), "/"); + if(strpos($result, $cleanPath) === 0){ + $result = ltrim(str_replace($cleanPath, $replacement, $result), "/"); + } + } + return $result; + } +} diff --git a/src/utils/MainLogger.php b/src/utils/MainLogger.php index b370ddbcfd..e33af84f5e 100644 --- a/src/utils/MainLogger.php +++ b/src/utils/MainLogger.php @@ -167,7 +167,7 @@ class MainLogger extends \AttachableThreadedLogger{ //pass } $errstr = preg_replace('/\s+/', ' ', trim($errstr)); - $errfile = Utils::cleanPath($errfile); + $errfile = Filesystem::cleanPath($errfile); $message = get_class($e) . ": \"$errstr\" ($errno) in \"$errfile\" at line $errline"; $stack = Utils::printableTrace($trace); diff --git a/src/utils/Utils.php b/src/utils/Utils.php index d6cabe1187..df0a9ccbf3 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -50,8 +50,6 @@ use function getenv; use function gettype; use function implode; use function is_array; -use function is_dir; -use function is_file; use function is_object; use function is_readable; use function is_string; @@ -68,10 +66,7 @@ use function preg_grep; use function preg_match; use function preg_match_all; use function preg_replace; -use function rmdir; -use function scandir; use function str_pad; -use function str_replace; use function str_split; use function stripos; use function strlen; @@ -79,13 +74,11 @@ use function strpos; use function substr; use function sys_get_temp_dir; use function trim; -use function unlink; use function xdebug_get_function_stack; use const PHP_EOL; use const PHP_INT_MAX; use const PHP_INT_SIZE; use const PHP_MAXPATHLEN; -use const SCANDIR_SORT_NONE; use const STR_PAD_LEFT; use const STR_PAD_RIGHT; @@ -123,7 +116,7 @@ class Utils{ //non-class function return $func->getName(); } - return "closure@" . self::cleanPath($func->getFileName()) . "#L" . $func->getStartLine(); + return "closure@" . Filesystem::cleanPath($func->getFileName()) . "#L" . $func->getStartLine(); } /** @@ -137,7 +130,7 @@ class Utils{ public static function getNiceClassName(object $obj) : string{ $reflect = new \ReflectionClass($obj); if($reflect->isAnonymous()){ - return "anonymous@" . self::cleanPath($reflect->getFileName()) . "#L" . $reflect->getStartLine(); + return "anonymous@" . Filesystem::cleanPath($reflect->getFileName()) . "#L" . $reflect->getStartLine(); } return $reflect->getName(); @@ -442,7 +435,7 @@ class Utils{ return gettype($value) . " " . Utils::printable((string) $value); }, $args)); } - $messages[] = "#$i " . (isset($trace[$i]["file"]) ? self::cleanPath($trace[$i]["file"]) : "") . "(" . (isset($trace[$i]["line"]) ? $trace[$i]["line"] : "") . "): " . (isset($trace[$i]["class"]) ? $trace[$i]["class"] . (($trace[$i]["type"] === "dynamic" or $trace[$i]["type"] === "->") ? "->" : "::") : "") . $trace[$i]["function"] . "(" . Utils::printable($params) . ")"; + $messages[] = "#$i " . (isset($trace[$i]["file"]) ? Filesystem::cleanPath($trace[$i]["file"]) : "") . "(" . (isset($trace[$i]["line"]) ? $trace[$i]["line"] : "") . "): " . (isset($trace[$i]["class"]) ? $trace[$i]["class"] . (($trace[$i]["type"] === "dynamic" or $trace[$i]["type"] === "->") ? "->" : "::") : "") . $trace[$i]["function"] . "(" . Utils::printable($params) . ")"; } return $messages; } @@ -475,24 +468,6 @@ class Utils{ return self::printableTrace(self::currentTrace(++$skipFrames)); } - public static function cleanPath($path){ - $result = str_replace(["\\", ".php", "phar://"], ["/", "", ""], $path); - - //remove relative paths - //TODO: make these paths dynamic so they can be unit-tested against - static $cleanPaths = [ - \pocketmine\PLUGIN_PATH => "plugins", //this has to come BEFORE \pocketmine\PATH because it's inside that by default on src installations - \pocketmine\PATH => "" - ]; - foreach($cleanPaths as $cleanPath => $replacement){ - $cleanPath = rtrim(str_replace(["\\", "phar://"], ["/", ""], $cleanPath), "/"); - if(strpos($result, $cleanPath) === 0){ - $result = ltrim(str_replace($cleanPath, $replacement, $result), "/"); - } - } - return $result; - } - /** * Extracts one-line tags from the doc-comment * @@ -543,24 +518,6 @@ class Utils{ } } - public static function recursiveUnlink(string $dir) : void{ - if(is_dir($dir)){ - $objects = scandir($dir, SCANDIR_SORT_NONE); - foreach($objects as $object){ - if($object !== "." and $object !== ".."){ - if(is_dir($dir . "/" . $object)){ - self::recursiveUnlink($dir . "/" . $object); - }else{ - unlink($dir . "/" . $object); - } - } - } - rmdir($dir); - }elseif(is_file($dir)){ - unlink($dir); - } - } - public static function checkUTF8(string $string) : void{ if(!mb_check_encoding($string, 'UTF-8')){ throw new \InvalidArgumentException("Text must be valid UTF-8"); diff --git a/src/world/format/io/FormatConverter.php b/src/world/format/io/FormatConverter.php index 70bceab366..cc01bd1611 100644 --- a/src/world/format/io/FormatConverter.php +++ b/src/world/format/io/FormatConverter.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\format\io; +use pocketmine\utils\Filesystem; use pocketmine\utils\Utils; use pocketmine\world\generator\GeneratorManager; use function basename; @@ -98,7 +99,7 @@ class FormatConverter{ $convertedOutput = rtrim($this->oldProvider->getPath(), "/\\") . "_converted" . DIRECTORY_SEPARATOR; if(file_exists($convertedOutput)){ $this->logger->info("Found previous conversion attempt, deleting..."); - Utils::recursiveUnlink($convertedOutput); + Filesystem::recursiveUnlink($convertedOutput); } $this->newProvider::generate($convertedOutput, $data->getName(), $data->getSeed(), GeneratorManager::getGenerator($data->getGenerator()), $data->getGeneratorOptions()); From 9d1239ed672d896347e5f2918ff68735a38bb973 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Aug 2019 17:39:57 +0100 Subject: [PATCH 1238/3224] PocketMine.php: get rid of redundant LOCK_FILE_PATH constant --- src/PocketMine.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index ee17bd72af..4de10cf17d 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -201,8 +201,7 @@ namespace pocketmine { mkdir($dataPath, 0777, true); } - define('pocketmine\LOCK_FILE_PATH', $dataPath . 'server.lock'); - define('pocketmine\LOCK_FILE', fopen(\pocketmine\LOCK_FILE_PATH, "a+b")); + define('pocketmine\LOCK_FILE', fopen($dataPath . 'server.lock', "a+b")); if(!flock(\pocketmine\LOCK_FILE, LOCK_EX | LOCK_NB)){ //wait for a shared lock to avoid race conditions if two servers started at the same time - this makes sure the //other server wrote its PID and released exclusive lock before we get our lock From 0c31b8731fe68bd56dbbfcc5eed77dedef914664 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Aug 2019 17:48:13 +0100 Subject: [PATCH 1239/3224] PocketMine.php: use main logger to emit force-kill debug --- src/PocketMine.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index 4de10cf17d..a8abf7841c 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -278,9 +278,7 @@ namespace pocketmine { usleep(10000); //Fixes ServerKiller not being able to start on single-core machines if(ThreadManager::getInstance()->stopAll() > 0){ - if(\pocketmine\DEBUG > 1){ - echo "Some threads could not be stopped, performing a force-kill" . PHP_EOL . PHP_EOL; - } + $logger->debug("Some threads could not be stopped, performing a force-kill"); Process::kill(getmypid()); } }while(false); From 8b40a8f21764008aa7b2a64788af2c77f238e219 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Aug 2019 17:50:45 +0100 Subject: [PATCH 1240/3224] PocketMine.php: move INI entry setting to a separate function --- src/PocketMine.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index a8abf7841c..e3751967f0 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -134,6 +134,14 @@ namespace pocketmine { } } + function set_ini_entries(){ + ini_set("allow_url_fopen", '1'); + ini_set("display_errors", '1'); + ini_set("display_startup_errors", '1'); + ini_set("default_charset", "utf-8"); + @ini_set("opcache.mmap_base", bin2hex(random_bytes(8))); //Fix OPCache address errors + } + function server(){ if(!empty($messages = check_platform_dependencies())){ echo PHP_EOL; @@ -185,10 +193,7 @@ namespace pocketmine { set_time_limit(0); //Who set it to 30 seconds?!?! - ini_set("allow_url_fopen", '1'); - ini_set("display_errors", '1'); - ini_set("display_startup_errors", '1'); - ini_set("default_charset", "utf-8"); + set_ini_entries(); define('pocketmine\RESOURCE_PATH', \pocketmine\PATH . 'resources' . DIRECTORY_SEPARATOR); @@ -256,7 +261,6 @@ namespace pocketmine { @define("INT32_MASK", is_int(0xffffffff) ? 0xffffffff : -1); - @ini_set("opcache.mmap_base", bin2hex(random_bytes(8))); //Fix OPCache address errors $exitCode = 0; do{ From d1a8bef1e6baaa905db69830cb5fa2f40f46fec2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Aug 2019 17:52:39 +0100 Subject: [PATCH 1241/3224] fix test --- tests/phpunit/utils/UtilsTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/utils/UtilsTest.php b/tests/phpunit/utils/UtilsTest.php index ae7844c449..27f7e0092b 100644 --- a/tests/phpunit/utils/UtilsTest.php +++ b/tests/phpunit/utils/UtilsTest.php @@ -61,6 +61,6 @@ class UtilsTest extends TestCase{ public function testNamespacedNiceClosureName() : void{ //be careful with this test. The closure has to be declared on the same line as the assertion. - self::assertSame('closure@' . Utils::cleanPath(__FILE__) . '#L' . __LINE__, Utils::getNiceClosureName(function(){})); + self::assertSame('closure@' . Filesystem::cleanPath(__FILE__) . '#L' . __LINE__, Utils::getNiceClosureName(function(){})); } } From 2bcb720668e9df102ecec9e6a2a0d10eb1d3bff3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Aug 2019 18:11:10 +0100 Subject: [PATCH 1242/3224] Server: get rid of \pocketmine\DEBUG --- src/Server.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/Server.php b/src/Server.php index 3c3b1348fa..6b90fd7f4d 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1034,7 +1034,10 @@ class Server{ "language" => "eng" ]); - define('pocketmine\DEBUG', (int) $this->getProperty("debug.level", 1)); + $debugLogLevel = (int) $this->getProperty("debug.level", 1); + if($this->logger instanceof MainLogger){ + $this->logger->setLogDebug($debugLogLevel > 1); + } $this->forceLanguage = (bool) $this->getProperty("settings.force-language", false); $selectedLang = $this->getConfigString("language", $this->getProperty("settings.language", Language::FALLBACK_LANGUAGE)); @@ -1073,10 +1076,6 @@ class Server{ ini_set('assert.exception', '1'); - if($this->logger instanceof MainLogger){ - $this->logger->setLogDebug(\pocketmine\DEBUG > 1); - } - $this->memoryManager = new MemoryManager($this); $this->logger->info($this->getLanguage()->translateString("pocketmine.server.start", [TextFormat::AQUA . $this->getVersion() . TextFormat::RESET])); @@ -1139,9 +1138,7 @@ class Server{ $this->setConfigInt("difficulty", World::DIFFICULTY_HARD); } - if(\pocketmine\DEBUG >= 0){ - @cli_set_process_title($this->getName() . " " . $this->getPocketMineVersion()); - } + @cli_set_process_title($this->getName() . " " . $this->getPocketMineVersion()); define("BOOTUP_RANDOM", random_bytes(16)); $this->serverID = Utils::getMachineUniqueId($this->getIp() . $this->getPort()); From 5c1f1f00cbbcc6460927b922f993f1de8e1e046c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Aug 2019 18:18:14 +0100 Subject: [PATCH 1243/3224] move assert.exception to PocketMine.php with the other stuff --- src/PocketMine.php | 1 + src/Server.php | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index e3751967f0..5b36d2a159 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -140,6 +140,7 @@ namespace pocketmine { ini_set("display_startup_errors", '1'); ini_set("default_charset", "utf-8"); @ini_set("opcache.mmap_base", bin2hex(random_bytes(8))); //Fix OPCache address errors + ini_set('assert.exception', '1'); } function server(){ diff --git a/src/Server.php b/src/Server.php index 6b90fd7f4d..43613dd600 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1074,8 +1074,6 @@ class Server{ $this->logger->warning(str_repeat("-", 40)); } - ini_set('assert.exception', '1'); - $this->memoryManager = new MemoryManager($this); $this->logger->info($this->getLanguage()->translateString("pocketmine.server.start", [TextFormat::AQUA . $this->getVersion() . TextFormat::RESET])); From 6e692d76d5db9da8c87df8b1ee3dc22dc4b7e3ae Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Aug 2019 18:50:33 +0100 Subject: [PATCH 1244/3224] make lock-file code more reusable --- src/PocketMine.php | 13 +++-------- src/utils/Filesystem.php | 50 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index 5b36d2a159..c48c524989 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine { use pocketmine\thread\ThreadManager; + use pocketmine\utils\Filesystem; use pocketmine\utils\MainLogger; use pocketmine\utils\Process; use pocketmine\utils\ServerKiller; @@ -207,20 +208,12 @@ namespace pocketmine { mkdir($dataPath, 0777, true); } - define('pocketmine\LOCK_FILE', fopen($dataPath . 'server.lock', "a+b")); - if(!flock(\pocketmine\LOCK_FILE, LOCK_EX | LOCK_NB)){ - //wait for a shared lock to avoid race conditions if two servers started at the same time - this makes sure the - //other server wrote its PID and released exclusive lock before we get our lock - flock(\pocketmine\LOCK_FILE, LOCK_SH); - $pid = stream_get_contents(\pocketmine\LOCK_FILE); + $lockFilePath = $dataPath . '/server.lock'; + if(($pid = Filesystem::createLockFile($lockFilePath)) !== null){ critical_error("Another " . \pocketmine\NAME . " instance (PID $pid) is already using this folder (" . realpath($dataPath) . ")."); critical_error("Please stop the other server first before running a new one."); exit(1); } - ftruncate(\pocketmine\LOCK_FILE, 0); - fwrite(\pocketmine\LOCK_FILE, (string) getmypid()); - fflush(\pocketmine\LOCK_FILE); - flock(\pocketmine\LOCK_FILE, LOCK_SH); //prevent acquiring an exclusive lock from another process, but allow reading //Logger has a dependency on timezone Timezone::init(); diff --git a/src/utils/Filesystem.php b/src/utils/Filesystem.php index 4ccf01a30d..27a2224310 100644 --- a/src/utils/Filesystem.php +++ b/src/utils/Filesystem.php @@ -23,18 +23,33 @@ declare(strict_types=1); namespace pocketmine\utils; +use function fclose; +use function fflush; +use function flock; +use function fopen; +use function ftruncate; +use function fwrite; +use function getmypid; use function is_dir; use function is_file; use function ltrim; +use function preg_match; +use function realpath; use function rmdir; use function rtrim; use function scandir; use function str_replace; +use function stream_get_contents; use function strpos; use function unlink; +use const LOCK_EX; +use const LOCK_NB; +use const LOCK_SH; use const SCANDIR_SORT_NONE; final class Filesystem{ + /** @var resource[] */ + private static $lockFileHandles = []; private function __construct(){ //NOOP @@ -75,4 +90,39 @@ final class Filesystem{ } return $result; } + + public static function createLockFile(string $lockFilePath) : ?int{ + $resource = fopen($lockFilePath, "a+b"); + if($resource === false){ + throw new \InvalidArgumentException("Invalid lock file path"); + } + if(!flock($resource, LOCK_EX | LOCK_NB)){ + //wait for a shared lock to avoid race conditions if two servers started at the same time - this makes sure the + //other server wrote its PID and released exclusive lock before we get our lock + flock($resource, LOCK_SH); + $pid = stream_get_contents($resource); + if(preg_match('/^\d+$/', $pid) === 1){ + return (int) $pid; + } + return -1; + } + ftruncate($resource, 0); + fwrite($resource, (string) getmypid()); + fflush($resource); + flock($resource, LOCK_SH); //prevent acquiring an exclusive lock from another process, but allow reading + self::$lockFileHandles[realpath($lockFilePath)] = $resource; //keep the resource alive to preserve the lock + return null; + } + + public static function releaseLockFile(string $lockFilePath) : void{ + $lockFilePath = realpath($lockFilePath); + if($lockFilePath === false){ + throw new \InvalidArgumentException("Invalid lock file path"); + } + if(isset(self::$lockFileHandles[$lockFilePath])){ + fclose(self::$lockFileHandles[$lockFilePath]); + unset(self::$lockFileHandles[$lockFilePath]); + @unlink($lockFilePath); + } + } } From c4376d13aef9508f4c7548410a180bcca4506958 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Aug 2019 19:32:20 +0100 Subject: [PATCH 1245/3224] update to latest SPL --- composer.lock | 8 ++++---- src/plugin/PharPluginLoader.php | 4 ++-- tests/plugins/PocketMine-DevTools | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.lock b/composer.lock index e2b04a9b27..083c2360d9 100644 --- a/composer.lock +++ b/composer.lock @@ -488,12 +488,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/SPL.git", - "reference": "49a4b0187f2aa9daa1a9457aefa1f4cbcc5ead92" + "reference": "6fee4ae7d2b4b0463702cb427626bc9def32fb61" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/SPL/zipball/49a4b0187f2aa9daa1a9457aefa1f4cbcc5ead92", - "reference": "49a4b0187f2aa9daa1a9457aefa1f4cbcc5ead92", + "url": "https://api.github.com/repos/pmmp/SPL/zipball/6fee4ae7d2b4b0463702cb427626bc9def32fb61", + "reference": "6fee4ae7d2b4b0463702cb427626bc9def32fb61", "shasum": "" }, "type": "library", @@ -509,7 +509,7 @@ "support": { "source": "https://github.com/pmmp/SPL/tree/master" }, - "time": "2019-07-20T14:32:24+00:00" + "time": "2019-08-25T18:29:14+00:00" } ], "packages-dev": [], diff --git a/src/plugin/PharPluginLoader.php b/src/plugin/PharPluginLoader.php index 3f594ace77..c0220a714e 100644 --- a/src/plugin/PharPluginLoader.php +++ b/src/plugin/PharPluginLoader.php @@ -32,10 +32,10 @@ use function substr; */ class PharPluginLoader implements PluginLoader{ - /** @var \ClassLoader */ + /** @var \DynamicClassLoader */ private $loader; - public function __construct(\ClassLoader $loader){ + public function __construct(\DynamicClassLoader $loader){ $this->loader = $loader; } diff --git a/tests/plugins/PocketMine-DevTools b/tests/plugins/PocketMine-DevTools index 27fc9126b4..e16a36e7da 160000 --- a/tests/plugins/PocketMine-DevTools +++ b/tests/plugins/PocketMine-DevTools @@ -1 +1 @@ -Subproject commit 27fc9126b486c6d8bb208ee613d5626463a546e7 +Subproject commit e16a36e7dad4230f0e3a9492e17c50357d3d5553 From a53f698d383fd06efe4fab516314fa22ad0f4ab0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Aug 2019 19:41:53 +0100 Subject: [PATCH 1246/3224] PocketMine.php: remove useless set_time_limit() call this is hardcoded to zero in the PHP core anyway. --- src/PocketMine.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index c48c524989..04ab444909 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -193,8 +193,6 @@ namespace pocketmine { $autoloader = new \BaseClassLoader(); $autoloader->register(false); - set_time_limit(0); //Who set it to 30 seconds?!?! - set_ini_entries(); define('pocketmine\RESOURCE_PATH', \pocketmine\PATH . 'resources' . DIRECTORY_SEPARATOR); From f720a580135d830e871d194ee1ed3a2e11db6cf7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 25 Aug 2019 19:50:51 +0100 Subject: [PATCH 1247/3224] RegionWorldProvider: don't assume that path has a trailing directory separator --- src/world/format/io/region/RegionWorldProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index 735904d6eb..2f09a0b2f4 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -131,7 +131,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ * @return string */ protected function pathToRegion(int $regionX, int $regionZ) : string{ - return $this->path . "region/r.$regionX.$regionZ." . static::getRegionFileExtension(); + return $this->path . "/region/r.$regionX.$regionZ." . static::getRegionFileExtension(); } /** From 1de5d35dfc86c73a191b60640c1a20132710da65 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 26 Aug 2019 19:03:48 +0100 Subject: [PATCH 1248/3224] add a CLI tool for conversion --- tools/convert-world.php | 80 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 tools/convert-world.php diff --git a/tools/convert-world.php b/tools/convert-world.php new file mode 100644 index 0000000000..c61d8651d5 --- /dev/null +++ b/tools/convert-world.php @@ -0,0 +1,80 @@ + "path to the input world for conversion", + "backup" => "path to back up the original files", + "format" => "desired output format (can be one of: " . implode(",", array_keys($writableFormats)) . ")" +]; +$usageMessage = "Options:\n"; +foreach($requiredOpts as $_opt => $_desc){ + $usageMessage .= "\t--$_opt : $_desc\n"; +} +$args = getopt("", array_map(function(string $str){ return "$str:"; }, array_keys($requiredOpts))); +foreach($requiredOpts as $opt => $desc){ + if(!isset($args[$opt])){ + die($usageMessage); + } +} +if(!array_key_exists($args["format"], $writableFormats)){ + die($usageMessage); +} + +$inputPath = realpath($args["world"]); +if($inputPath === false){ + die("Cannot find input world at location: " . $args["world"]); +} +$backupPath = $args["backup"]; +if((!@mkdir($backupPath, 0777, true) and !is_dir($backupPath)) or !is_writable($backupPath)){ + die("Backup file path " . $backupPath . " is not writable (permission error or doesn't exist), aborting"); +} + +$oldProviderClasses = WorldProviderManager::getMatchingProviders($inputPath); +if(count($oldProviderClasses) === 0){ + die("Unknown input world format"); +} +if(count($oldProviderClasses) > 1){ + die("Ambiguous input world format: matched " . count($oldProviderClasses) . " (" . implode(array_keys($oldProviderClasses)) . ")"); +} +$oldProviderClass = array_shift($oldProviderClasses); +/** @var WorldProvider $oldProvider */ +$oldProvider = new $oldProviderClass($inputPath); + +$converter = new FormatConverter($oldProvider, $writableFormats[$args["format"]], realpath($backupPath), GlobalLogger::get()); +$converter->execute(); From f755ea6043d7bf5f23093f780bb30157ddcc0054 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 27 Aug 2019 19:25:55 +0100 Subject: [PATCH 1249/3224] DestroyBlockParticle: keep block reference around instead of runtimeID we'll need this for protocol abstraction --- src/world/particle/DestroyBlockParticle.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/world/particle/DestroyBlockParticle.php b/src/world/particle/DestroyBlockParticle.php index 71fe7075d8..3039fbe408 100644 --- a/src/world/particle/DestroyBlockParticle.php +++ b/src/world/particle/DestroyBlockParticle.php @@ -29,14 +29,14 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class DestroyBlockParticle implements Particle{ - /** @var int */ - protected $data; + /** @var Block */ + private $block; public function __construct(Block $b){ - $this->data = $b->getRuntimeId(); + $this->block = $b; } public function encode(Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_DESTROY, $this->data, $pos); + return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_DESTROY, $this->block->getRuntimeId(), $pos); } } From 1866de269bfd0f1e1f070c1fdc4fe49d42ea7ae9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Sep 2019 07:58:58 +0100 Subject: [PATCH 1250/3224] OfflinePlayer: fix reading wrong NBT type in getFirstPlayed(), close #3112 This bug was introduced by 65927e69651652917c928990fb8643cfa33f0096. --- src/player/OfflinePlayer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player/OfflinePlayer.php b/src/player/OfflinePlayer.php index f04b79eacd..7768bf62f8 100644 --- a/src/player/OfflinePlayer.php +++ b/src/player/OfflinePlayer.php @@ -103,7 +103,7 @@ class OfflinePlayer implements IPlayer{ } public function getFirstPlayed() : ?int{ - return ($this->namedtag !== null and $this->namedtag->hasTag("firstPlayed", LongTag::class)) ? $this->namedtag->getInt("firstPlayed") : null; + return ($this->namedtag !== null and $this->namedtag->hasTag("firstPlayed", LongTag::class)) ? $this->namedtag->getLong("firstPlayed") : null; } public function getLastPlayed() : ?int{ From ec0558597b6ca948228846b25751c2b1863cbf3f Mon Sep 17 00:00:00 2001 From: Frago9876543210 Date: Wed, 18 Sep 2019 13:10:42 +0300 Subject: [PATCH 1251/3224] CommandParameter: change byte1 field to "flags" (#3115) --- src/network/mcpe/protocol/AvailableCommandsPacket.php | 4 ++-- src/network/mcpe/protocol/types/command/CommandParameter.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/network/mcpe/protocol/AvailableCommandsPacket.php b/src/network/mcpe/protocol/AvailableCommandsPacket.php index efcda29ed5..03c62ee114 100644 --- a/src/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/network/mcpe/protocol/AvailableCommandsPacket.php @@ -239,7 +239,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ $parameter->paramName = $this->getString(); $parameter->paramType = $this->getLInt(); $parameter->isOptional = $this->getBool(); - $parameter->byte1 = $this->getByte(); + $parameter->flags = $this->getByte(); if($parameter->paramType & self::ARG_FLAG_ENUM){ $index = ($parameter->paramType & 0xffff); @@ -302,7 +302,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ $this->putLInt($type); $this->putBool($parameter->isOptional); - $this->putByte($parameter->byte1); + $this->putByte($parameter->flags); } } } diff --git a/src/network/mcpe/protocol/types/command/CommandParameter.php b/src/network/mcpe/protocol/types/command/CommandParameter.php index 1610a59fee..842902f18a 100644 --- a/src/network/mcpe/protocol/types/command/CommandParameter.php +++ b/src/network/mcpe/protocol/types/command/CommandParameter.php @@ -33,7 +33,7 @@ class CommandParameter{ /** @var bool */ public $isOptional; /** @var int */ - public $byte1 = 0; //unknown, always zero except for in /gamerule command + public $flags = 0; //shows enum name if 1, always zero except for in /gamerule command /** @var CommandEnum|null */ public $enum; /** @var string|null */ @@ -60,7 +60,7 @@ class CommandParameter{ public static function enum(string $name, CommandEnum $enum, int $flags, bool $optional = false) : self{ $result = self::baseline($name, AvailableCommandsPacket::ARG_FLAG_ENUM | AvailableCommandsPacket::ARG_FLAG_VALID, $optional); $result->enum = $enum; - $result->byte1 = $flags; + $result->flags = $flags; return $result; } } From 6e9d2e1c8af7d9debc6ed14f98e4f54d29753625 Mon Sep 17 00:00:00 2001 From: Frago9876543210 Date: Mon, 23 Sep 2019 13:43:06 +0300 Subject: [PATCH 1252/3224] InstantEnchantParticle: add Color into constructor (#3118) --- src/world/particle/InstantEnchantParticle.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/world/particle/InstantEnchantParticle.php b/src/world/particle/InstantEnchantParticle.php index b569600c42..1f48004e6d 100644 --- a/src/world/particle/InstantEnchantParticle.php +++ b/src/world/particle/InstantEnchantParticle.php @@ -26,10 +26,17 @@ namespace pocketmine\world\particle; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; +use pocketmine\utils\Color; class InstantEnchantParticle implements Particle{ + /** @var Color */ + private $color; + + public function __construct(Color $color){ + $this->color = $color; + } public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::MOB_SPELL_INSTANTANEOUS, 0, $pos); + return LevelEventPacket::standardParticle(ParticleIds::MOB_SPELL_INSTANTANEOUS, $this->color->toARGB(), $pos); } } From 262dbc0346b464ce3e728eb09649ecd4d4b0be14 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 23 Sep 2019 11:54:17 +0100 Subject: [PATCH 1253/3224] ParticleCommand: fixup for 6e9d2e1c8af7d9debc6ed14f98e4f54d29753625 --- src/command/defaults/ParticleCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command/defaults/ParticleCommand.php b/src/command/defaults/ParticleCommand.php index f3974d3217..904c4ebe05 100644 --- a/src/command/defaults/ParticleCommand.php +++ b/src/command/defaults/ParticleCommand.php @@ -165,7 +165,7 @@ class ParticleCommand extends VanillaCommand{ case "spell": return new EnchantParticle(); case "instantspell": - return new InstantEnchantParticle(); + return new InstantEnchantParticle(new Color(0, 0, 0, 255)); //TODO: colour support case "dripwater": return new WaterDripParticle(); case "driplava": From b1de973d96da982f4082327ebb95ff39f0f74e97 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Thu, 3 Oct 2019 10:51:33 +0100 Subject: [PATCH 1254/3224] changelog: world save performance is improved [ci skip] --- changelogs/4.0-snapshot.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index d7e32b613f..6aa84f48c8 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -16,17 +16,22 @@ This major version features substantial changes throughout the core, including s - [ds](https://github.com/php-ds/ext-ds) - [chunkutils2](https://github.com/pmmp/ext-chunkutils2) -### World format support +### World handling +#### Functional - Modern Minecraft Bedrock world formats are now supported. - Automatic conversion of deprecated world formats is now implemented. -- The following world formats have been deprecated and will be **automatically converted on load to a new format**: +- All formats except `leveldb` have been deprecated. The following world formats will be **automatically converted on load to a new format**: - `mcregion` - `anvil` - `pmanvil` - 256 build-height is now supported in all worlds (facilitated by automatic conversion). - Extended blocks are now supported (facilitated by automatic conversion). - Unsupported world formats no longer causes a crash, but a graceful shutdown instead. -- World corruption no longer causes a crash. +- World corruption no longer causes a crash, but a graceful shutdown instead. + +#### Performance +- `leveldb` is now the primary supported world format. It is inherently faster than region-based formats thanks to better design. +- Partial chunk saves (only saving modified subcomponents of chunks) has been implemented. This drastically reduces the amount of data that is usually necessary to write on chunk save, which in turn **drastically reduces the time to complete world saves**. This is possible thanks to the modular design of the `leveldb` world format - this enhancement is not possible with region-based formats. ### Logger revamp - Many components now have a dedicated logger which automatically adds [prefixes] to their messages. From 37763685aa4244535414d77240f29d42a045a490 Mon Sep 17 00:00:00 2001 From: Frago9876543210 Date: Fri, 4 Oct 2019 11:34:14 +0300 Subject: [PATCH 1255/3224] LiquidBucket: add getLiquid() (#3123) --- src/item/LiquidBucket.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/item/LiquidBucket.php b/src/item/LiquidBucket.php index 095de17347..69e3e0ef39 100644 --- a/src/item/LiquidBucket.php +++ b/src/item/LiquidBucket.php @@ -74,4 +74,11 @@ class LiquidBucket extends Item{ return ItemUseResult::FAIL(); } + + /** + * @return Liquid + */ + public function getLiquid() : Liquid{ + return $this->liquid; + } } From d456cb24196b5bffe595de5a12dff0b45709f528 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Mon, 7 Oct 2019 10:03:29 +0100 Subject: [PATCH 1256/3224] Filesystem: added some documentation for createLockFile() and releaseLockFile() [ci skip] --- src/utils/Filesystem.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/utils/Filesystem.php b/src/utils/Filesystem.php index 27a2224310..094f7e45f4 100644 --- a/src/utils/Filesystem.php +++ b/src/utils/Filesystem.php @@ -91,6 +91,16 @@ final class Filesystem{ return $result; } + /** + * Attempts to get a lock on the specified file, creating it if it does not exist. This is typically used for IPC to + * inform other processes that some file or folder is already in use, to avoid data corruption. + * If this function succeeds in gaining a lock on the file, it writes the current PID to the file. + * + * @param string $lockFilePath + * + * @return int|null process ID of the process currently holding the lock failure, null on success. + * @throws \InvalidArgumentException if the lock file path is invalid (e.g. parent directory doesn't exist, permission denied) + */ public static function createLockFile(string $lockFilePath) : ?int{ $resource = fopen($lockFilePath, "a+b"); if($resource === false){ @@ -114,6 +124,12 @@ final class Filesystem{ return null; } + /** + * Releases a file lock previously acquired by createLockFile() and deletes the lock file. + * + * @param string $lockFilePath + * @throws \InvalidArgumentException if the lock file path is invalid (e.g. parent directory doesn't exist, permission denied) + */ public static function releaseLockFile(string $lockFilePath) : void{ $lockFilePath = realpath($lockFilePath); if($lockFilePath === false){ From b7665fd906c4e4abb5f9c54b49affb00468fc872 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 20 Oct 2019 21:26:22 +0100 Subject: [PATCH 1257/3224] remove unused imports --- src/event/Event.php | 1 - src/event/HandlerList.php | 1 - src/plugin/PluginManager.php | 1 - 3 files changed, 3 deletions(-) diff --git a/src/event/Event.php b/src/event/Event.php index f5ecd17e9a..5977516f35 100644 --- a/src/event/Event.php +++ b/src/event/Event.php @@ -26,7 +26,6 @@ declare(strict_types=1); */ namespace pocketmine\event; -use function assert; use function get_class; abstract class Event{ diff --git a/src/event/HandlerList.php b/src/event/HandlerList.php index c6ffbaac68..80bc844486 100644 --- a/src/event/HandlerList.php +++ b/src/event/HandlerList.php @@ -25,7 +25,6 @@ namespace pocketmine\event; use pocketmine\plugin\Plugin; use function array_fill_keys; -use function in_array; use function spl_object_id; class HandlerList{ diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 87714d6287..0c109b4a3d 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -25,7 +25,6 @@ namespace pocketmine\plugin; use pocketmine\event\Event; use pocketmine\event\EventPriority; -use pocketmine\event\HandlerList; use pocketmine\event\HandlerListManager; use pocketmine\event\Listener; use pocketmine\event\plugin\PluginDisableEvent; From bf0e855a9b29e0fc41fe3ba9862ee2cfbeeade59 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 22 Oct 2019 19:07:42 +0100 Subject: [PATCH 1258/3224] updated composer dependencies --- composer.lock | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/composer.lock b/composer.lock index 083c2360d9..fed61c555b 100644 --- a/composer.lock +++ b/composer.lock @@ -299,12 +299,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/BinaryUtils.git", - "reference": "ea71180bb494217abdb8867f4a0f1c353551b425" + "reference": "7b50fa2b212c54e2a280217c84955b23e90cf5a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/ea71180bb494217abdb8867f4a0f1c353551b425", - "reference": "ea71180bb494217abdb8867f4a0f1c353551b425", + "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/7b50fa2b212c54e2a280217c84955b23e90cf5a1", + "reference": "7b50fa2b212c54e2a280217c84955b23e90cf5a1", "shasum": "" }, "require": { @@ -325,7 +325,7 @@ "source": "https://github.com/pmmp/BinaryUtils/tree/master", "issues": "https://github.com/pmmp/BinaryUtils/issues" }, - "time": "2019-08-25T14:54:25+00:00" + "time": "2019-10-21T14:41:23+00:00" }, { "name": "pocketmine/math", @@ -333,12 +333,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "d7fda7a3abb078f6c709f02ddbb79444efa8cbe2" + "reference": "68009b5202142ef5e83d271aebfd4d721efdb3b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/d7fda7a3abb078f6c709f02ddbb79444efa8cbe2", - "reference": "d7fda7a3abb078f6c709f02ddbb79444efa8cbe2", + "url": "https://api.github.com/repos/pmmp/Math/zipball/68009b5202142ef5e83d271aebfd4d721efdb3b9", + "reference": "68009b5202142ef5e83d271aebfd4d721efdb3b9", "shasum": "" }, "require": { @@ -364,7 +364,7 @@ "source": "https://github.com/pmmp/Math/tree/master", "issues": "https://github.com/pmmp/Math/issues" }, - "time": "2019-08-14T16:30:00+00:00" + "time": "2019-10-21T14:35:51+00:00" }, { "name": "pocketmine/nbt", @@ -372,12 +372,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "56cb637f904d8cce05d45ff275ee1634bb52e9c3" + "reference": "5736b9e36283116caca51640d9e9a905155f1b7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/56cb637f904d8cce05d45ff275ee1634bb52e9c3", - "reference": "56cb637f904d8cce05d45ff275ee1634bb52e9c3", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/5736b9e36283116caca51640d9e9a905155f1b7a", + "reference": "5736b9e36283116caca51640d9e9a905155f1b7a", "shasum": "" }, "require": { @@ -405,7 +405,7 @@ "source": "https://github.com/pmmp/NBT/tree/master", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2019-08-25T15:00:08+00:00" + "time": "2019-10-21T15:06:42+00:00" }, { "name": "pocketmine/raklib", @@ -413,12 +413,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "9b6e021dcecd6ac3e0fa11655d6b42c13c541e54" + "reference": "3652dbc4b49225149b7d2fbd5c380fc39b6aff24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/9b6e021dcecd6ac3e0fa11655d6b42c13c541e54", - "reference": "9b6e021dcecd6ac3e0fa11655d6b42c13c541e54", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/3652dbc4b49225149b7d2fbd5c380fc39b6aff24", + "reference": "3652dbc4b49225149b7d2fbd5c380fc39b6aff24", "shasum": "" }, "require": { @@ -446,7 +446,7 @@ "source": "https://github.com/pmmp/RakLib/tree/master", "issues": "https://github.com/pmmp/RakLib/issues" }, - "time": "2019-08-25T15:01:01+00:00" + "time": "2019-08-30T17:40:14+00:00" }, { "name": "pocketmine/snooze", From 296825b87ee412842b139125a5dccb9a04798cf9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 22 Oct 2019 20:09:51 +0100 Subject: [PATCH 1259/3224] LightArray: collect garbage on unserialize serialize/unserialize don't preserve const refs, so this is necessary to reassign global refs post-unserialize --- src/world/format/LightArray.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/world/format/LightArray.php b/src/world/format/LightArray.php index 1b10eb4895..cbe7cd25f7 100644 --- a/src/world/format/LightArray.php +++ b/src/world/format/LightArray.php @@ -92,4 +92,9 @@ final class LightArray{ public function getData() : string{ return $this->data; } + + public function __wakeup(){ + //const refs aren't preserved when unserializing + $this->collectGarbage(); + } } From e1352668d1bfc9d6638afc4c7c43cf17b87430c5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 22 Oct 2019 20:13:46 +0100 Subject: [PATCH 1260/3224] LightPopulationTask: Don't overwrite the whole chunk on completion this is more efficient (less data copied for ITC), fixes #2873, and also fixes terrain changes during task run getting overwritten. This still leaves the problem that the light information provided may be out of date by the time the task completes, but this is nonetheless a step forward. --- src/world/format/Chunk.php | 11 ++++++ src/world/light/LightPopulationTask.php | 49 +++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index d9b8d1996c..0c048832fe 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -620,6 +620,17 @@ class Chunk{ return $this->heightMap->toArray(); } + /** + * @param int[] $values + * @throws \InvalidArgumentException + */ + public function setHeightMapArray(array $values) : void{ + if(count($values) !== 256){ + throw new \InvalidArgumentException("Expected exactly 256 values"); + } + $this->heightMap = \SplFixedArray::fromArray($values); + } + /** * @return bool */ diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index 2583f138d5..cf1b604207 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -27,15 +27,31 @@ use pocketmine\block\BlockFactory; use pocketmine\scheduler\AsyncTask; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\FastChunkSerializer; +use pocketmine\world\format\LightArray; use pocketmine\world\World; +use function igbinary_serialize; +use function igbinary_unserialize; class LightPopulationTask extends AsyncTask{ private const TLS_KEY_WORLD = "world"; public $chunk; + /** @var int */ + private $chunkX; + /** @var int */ + private $chunkZ; + + /** @var string */ + private $resultHeightMap; + /** @var string */ + private $resultSkyLightArrays; + /** @var string */ + private $resultBlockLightArrays; + public function __construct(World $world, Chunk $chunk){ $this->storeLocal(self::TLS_KEY_WORLD, $world); + [$this->chunkX, $this->chunkZ] = [$chunk->getX(), $chunk->getZ()]; $this->chunk = FastChunkSerializer::serialize($chunk); } @@ -50,16 +66,41 @@ class LightPopulationTask extends AsyncTask{ $chunk->populateSkyLight(); $chunk->setLightPopulated(); - $this->chunk = FastChunkSerializer::serialize($chunk); + $this->resultHeightMap = igbinary_serialize($chunk->getHeightMapArray()); + $skyLightArrays = []; + $blockLightArrays = []; + foreach($chunk->getSubChunks() as $y => $subChunk){ + $skyLightArrays[$y] = $subChunk->getBlockSkyLightArray(); + $blockLightArrays[$y] = $subChunk->getBlockLightArray(); + } + $this->resultSkyLightArrays = igbinary_serialize($skyLightArrays); + $this->resultBlockLightArrays = igbinary_serialize($blockLightArrays); } public function onCompletion() : void{ /** @var World $world */ $world = $this->fetchLocal(self::TLS_KEY_WORLD); - if(!$world->isClosed()){ + if(!$world->isClosed() and $world->isChunkLoaded($this->chunkX, $this->chunkZ)){ /** @var Chunk $chunk */ - $chunk = FastChunkSerializer::deserialize($this->chunk); - $world->generateChunkCallback($chunk->getX(), $chunk->getZ(), $chunk); + $chunk = $world->getChunk($this->chunkX, $this->chunkZ); + //TODO: calculated light information might not be valid if the terrain changed during light calculation + + /** @var int[] $heightMapArray */ + $heightMapArray = igbinary_unserialize($this->resultHeightMap); + $chunk->setHeightMapArray($heightMapArray); + + /** @var LightArray[] $skyLightArrays */ + $skyLightArrays = igbinary_unserialize($this->resultSkyLightArrays); + /** @var LightArray[] $blockLightArrays */ + $blockLightArrays = igbinary_unserialize($this->resultBlockLightArrays); + + foreach($skyLightArrays as $y => $array){ + $chunk->getSubChunk($y, true)->setBlockSkyLightArray($array); + } + foreach($blockLightArrays as $y => $array){ + $chunk->getSubChunk($y, true)->setBlockLightArray($array); + } + $chunk->setLightPopulated(); } } } From 9d3637c999cc91b0b431c53990be796befa52328 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 22 Oct 2019 20:24:26 +0100 Subject: [PATCH 1261/3224] Chunk: remove useless proxy field emptySubChunk --- src/world/format/Chunk.php | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 0c048832fe..8c35c192c6 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -74,9 +74,6 @@ class Chunk{ /** @var \SplFixedArray|SubChunkInterface[] */ protected $subChunks; - /** @var EmptySubChunk */ - protected $emptySubChunk; - /** @var Tile[] */ protected $tiles = []; @@ -111,10 +108,9 @@ class Chunk{ $this->height = Chunk::MAX_SUBCHUNKS; //TODO: add a way of changing this $this->subChunks = new \SplFixedArray($this->height); - $this->emptySubChunk = EmptySubChunk::getInstance(); foreach($this->subChunks as $y => $null){ - $this->subChunks[$y] = $subChunks[$y] ?? $this->emptySubChunk; + $this->subChunks[$y] = $subChunks[$y] ?? EmptySubChunk::getInstance(); } if(count($heightMap) === 256){ @@ -675,7 +671,7 @@ class Chunk{ */ public function getSubChunk(int $y, bool $generateNew = false) : SubChunkInterface{ if($y < 0 or $y >= $this->height){ - return $this->emptySubChunk; + return EmptySubChunk::getInstance(); }elseif($generateNew and $this->subChunks[$y] instanceof EmptySubChunk){ $this->subChunks[$y] = new SubChunk(BlockLegacyIds::AIR << 4, []); } @@ -697,7 +693,7 @@ class Chunk{ return false; } if($subChunk === null or ($subChunk->isEmpty() and !$allowEmpty)){ - $this->subChunks[$y] = $this->emptySubChunk; + $this->subChunks[$y] = EmptySubChunk::getInstance(); }else{ $this->subChunks[$y] = $subChunk; } @@ -746,7 +742,7 @@ class Chunk{ if($subChunk instanceof SubChunk){ $subChunk->collectGarbage(); if($subChunk->isEmpty()){ - $this->subChunks[$y] = $this->emptySubChunk; + $this->subChunks[$y] = EmptySubChunk::getInstance(); } } } From b8c857df648b60cbb8f77a5ffc3a075b64eb1faa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 22 Oct 2019 20:54:54 +0100 Subject: [PATCH 1262/3224] World: prevent getHighestAdjacentBlockLight() and getHighestAdjacentBlockSkyLight() trying to exceed world bounds this creates a problem for sky light above y=256, but this problem exists in lots of other places already anyway. --- src/world/World.php | 46 +++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index caf1c73440..1bff93bfac 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1354,14 +1354,21 @@ class World implements ChunkManager{ * @return int */ public function getHighestAdjacentBlockSkyLight(int $x, int $y, int $z) : int{ - return max([ - $this->getBlockSkyLightAt($x + 1, $y, $z), - $this->getBlockSkyLightAt($x - 1, $y, $z), - $this->getBlockSkyLightAt($x, $y + 1, $z), - $this->getBlockSkyLightAt($x, $y - 1, $z), - $this->getBlockSkyLightAt($x, $y, $z + 1), - $this->getBlockSkyLightAt($x, $y, $z - 1) - ]); + $max = 0; + foreach([ + [$x + 1, $y, $z], + [$x - 1, $y, $z], + [$x, $y + 1, $z], + [$x, $y - 1, $z], + [$x, $y, $z + 1], + [$x, $y, $z - 1] + ] as [$x1, $y1, $z1]){ + if(!$this->isInWorld($x1, $y1, $z1)){ + continue; + } + $max = max($max, $this->getBlockSkyLightAt($x1, $y1, $z1)); + } + return $max; } public function updateBlockSkyLight(int $x, int $y, int $z){ @@ -1385,14 +1392,21 @@ class World implements ChunkManager{ * @return int */ public function getHighestAdjacentBlockLight(int $x, int $y, int $z) : int{ - return max([ - $this->getBlockLightAt($x + 1, $y, $z), - $this->getBlockLightAt($x - 1, $y, $z), - $this->getBlockLightAt($x, $y + 1, $z), - $this->getBlockLightAt($x, $y - 1, $z), - $this->getBlockLightAt($x, $y, $z + 1), - $this->getBlockLightAt($x, $y, $z - 1) - ]); + $max = 0; + foreach([ + [$x + 1, $y, $z], + [$x - 1, $y, $z], + [$x, $y + 1, $z], + [$x, $y - 1, $z], + [$x, $y, $z + 1], + [$x, $y, $z - 1] + ] as [$x1, $y1, $z1]){ + if(!$this->isInWorld($x1, $y1, $z1)){ + continue; + } + $max = max($max, $this->getBlockLightAt($x1, $y1, $z1)); + } + return $max; } public function updateBlockLight(int $x, int $y, int $z){ From 295d14e0d929f068f220c03a618136dfbb5472a5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 22 Oct 2019 21:13:08 +0100 Subject: [PATCH 1263/3224] Chunk: make setSubChunk() throw exception on invalid Y instead of returning false --- src/world/format/Chunk.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 8c35c192c6..94e1824edd 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -685,12 +685,10 @@ class Chunk{ * @param int $y * @param SubChunkInterface|null $subChunk * @param bool $allowEmpty Whether to check if the chunk is empty, and if so replace it with an empty stub - * - * @return bool */ - public function setSubChunk(int $y, ?SubChunkInterface $subChunk, bool $allowEmpty = false) : bool{ + public function setSubChunk(int $y, ?SubChunkInterface $subChunk, bool $allowEmpty = false) : void{ if($y < 0 or $y >= $this->height){ - return false; + throw new \InvalidArgumentException("Invalid subchunk Y coordinate $y"); } if($subChunk === null or ($subChunk->isEmpty() and !$allowEmpty)){ $this->subChunks[$y] = EmptySubChunk::getInstance(); @@ -698,7 +696,6 @@ class Chunk{ $this->subChunks[$y] = $subChunk; } $this->setDirtyFlag(self::DIRTY_FLAG_TERRAIN, true); - return true; } /** From b7d1d11eb4d3e21a070a26eaefd77ce4382f3ef1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 22 Oct 2019 21:15:46 +0100 Subject: [PATCH 1264/3224] Chunk: remove useless field "height" --- src/world/format/Chunk.php | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 94e1824edd..a0b1745829 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -68,9 +68,6 @@ class Chunk{ /** @var bool */ protected $terrainPopulated = false; - /** @var int */ - protected $height = Chunk::MAX_SUBCHUNKS; - /** @var \SplFixedArray|SubChunkInterface[] */ protected $subChunks; @@ -105,9 +102,7 @@ class Chunk{ $this->x = $chunkX; $this->z = $chunkZ; - $this->height = Chunk::MAX_SUBCHUNKS; //TODO: add a way of changing this - - $this->subChunks = new \SplFixedArray($this->height); + $this->subChunks = new \SplFixedArray(Chunk::MAX_SUBCHUNKS); foreach($this->subChunks as $y => $null){ $this->subChunks[$y] = $subChunks[$y] ?? EmptySubChunk::getInstance(); @@ -117,7 +112,7 @@ class Chunk{ $this->heightMap = \SplFixedArray::fromArray($heightMap); }else{ assert(count($heightMap) === 0, "Wrong HeightMap value count, expected 256, got " . count($heightMap)); - $val = ($this->height * 16); + $val = ($this->subChunks->getSize() * 16); $this->heightMap = \SplFixedArray::fromArray(array_fill(0, 256, $val)); } @@ -163,7 +158,7 @@ class Chunk{ * @return int */ public function getHeight() : int{ - return $this->height; + return $this->subChunks->getSize(); } /** @@ -670,7 +665,7 @@ class Chunk{ * @return SubChunkInterface */ public function getSubChunk(int $y, bool $generateNew = false) : SubChunkInterface{ - if($y < 0 or $y >= $this->height){ + if($y < 0 or $y >= $this->subChunks->getSize()){ return EmptySubChunk::getInstance(); }elseif($generateNew and $this->subChunks[$y] instanceof EmptySubChunk){ $this->subChunks[$y] = new SubChunk(BlockLegacyIds::AIR << 4, []); @@ -687,7 +682,7 @@ class Chunk{ * @param bool $allowEmpty Whether to check if the chunk is empty, and if so replace it with an empty stub */ public function setSubChunk(int $y, ?SubChunkInterface $subChunk, bool $allowEmpty = false) : void{ - if($y < 0 or $y >= $this->height){ + if($y < 0 or $y >= $this->subChunks->getSize()){ throw new \InvalidArgumentException("Invalid subchunk Y coordinate $y"); } if($subChunk === null or ($subChunk->isEmpty() and !$allowEmpty)){ From 02ff8d671b93ec5911576643e9b03f2049f31c81 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 22 Oct 2019 21:40:13 +0100 Subject: [PATCH 1265/3224] Mostly phase out EmptySubChunk copy-on-write and zero-layer SubChunk objects are much easier to manage and have less cognitive overhead. obviously, the goal is to get rid of EmptySubChunk completely, but right now it does still serve a purpose (filling in dummy values for reading out-of-bounds on chunks), and that's a problem that takes a little more work to fix. --- src/world/World.php | 3 +- src/world/format/Chunk.php | 59 +++++++++------------ src/world/format/EmptySubChunk.php | 6 ++- src/world/format/SubChunk.php | 22 +++----- src/world/format/SubChunkInterface.php | 14 ++++- src/world/format/io/FastChunkSerializer.php | 4 -- src/world/format/io/leveldb/LevelDB.php | 2 +- src/world/generator/Flat.php | 2 +- src/world/light/LightPopulationTask.php | 4 +- src/world/utils/SubChunkIteratorManager.php | 10 ++-- 10 files changed, 58 insertions(+), 68 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 1bff93bfac..34d54a8fd8 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -64,7 +64,6 @@ use pocketmine\utils\Limits; use pocketmine\utils\ReversePriorityQueue; use pocketmine\world\biome\Biome; use pocketmine\world\format\Chunk; -use pocketmine\world\format\EmptySubChunk; use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\WritableWorldProvider; use pocketmine\world\generator\Generator; @@ -983,7 +982,7 @@ class World implements ChunkManager{ foreach($chunk->getSubChunks() as $Y => $subChunk){ - if(!($subChunk instanceof EmptySubChunk)){ + if(!$subChunk->isEmptyFast()){ $k = mt_rand(0, 0xfffffffff); //36 bits for($i = 0; $i < 3; ++$i){ $x = $k & 0x0f; diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index a0b1745829..40e0d27b62 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -68,7 +68,7 @@ class Chunk{ /** @var bool */ protected $terrainPopulated = false; - /** @var \SplFixedArray|SubChunkInterface[] */ + /** @var \SplFixedArray|SubChunk[] */ protected $subChunks; /** @var Tile[] */ @@ -90,13 +90,13 @@ class Chunk{ protected $NBTentities = []; /** - * @param int $chunkX - * @param int $chunkZ - * @param SubChunkInterface[] $subChunks - * @param CompoundTag[] $entities - * @param CompoundTag[] $tiles - * @param string $biomeIds - * @param int[] $heightMap + * @param int $chunkX + * @param int $chunkZ + * @param SubChunk[] $subChunks + * @param CompoundTag[] $entities + * @param CompoundTag[] $tiles + * @param string $biomeIds + * @param int[] $heightMap */ public function __construct(int $chunkX, int $chunkZ, array $subChunks = [], ?array $entities = null, ?array $tiles = null, string $biomeIds = "", array $heightMap = []){ $this->x = $chunkX; @@ -105,7 +105,7 @@ class Chunk{ $this->subChunks = new \SplFixedArray(Chunk::MAX_SUBCHUNKS); foreach($this->subChunks as $y => $null){ - $this->subChunks[$y] = $subChunks[$y] ?? EmptySubChunk::getInstance(); + $this->subChunks[$y] = $subChunks[$y] ?? new SubChunk(BlockLegacyIds::AIR << 4, []); } if(count($heightMap) === 256){ @@ -183,7 +183,7 @@ class Chunk{ * @param int $block */ public function setFullBlock(int $x, int $y, int $z, int $block) : void{ - $this->getSubChunk($y >> 4, true)->setFullBlock($x, $y & 0xf, $z, $block); + $this->getSubChunk($y >> 4)->setFullBlock($x, $y & 0xf, $z, $block); $this->dirtyFlags |= self::DIRTY_FLAG_TERRAIN; } @@ -209,7 +209,7 @@ class Chunk{ * @param int $level 0-15 */ public function setBlockSkyLight(int $x, int $y, int $z, int $level) : void{ - $this->getSubChunk($y >> 4, true)->getBlockSkyLightArray()->set($x & 0xf, $y & 0x0f, $z & 0xf, $level); + $this->getSubChunk($y >> 4)->getBlockSkyLightArray()->set($x & 0xf, $y & 0x0f, $z & 0xf, $level); } /** @@ -217,7 +217,7 @@ class Chunk{ */ public function setAllBlockSkyLight(int $level) : void{ for($y = $this->getHighestSubChunkIndex(); $y >= 0; --$y){ - $this->getSubChunk($y, true)->setBlockSkyLightArray(LightArray::fill($level)); + $this->getSubChunk($y)->setBlockSkyLightArray(LightArray::fill($level)); } } @@ -243,7 +243,7 @@ class Chunk{ * @param int $level 0-15 */ public function setBlockLight(int $x, int $y, int $z, int $level) : void{ - $this->getSubChunk($y >> 4, true)->getBlockLightArray()->set($x & 0xf, $y & 0x0f, $z & 0xf, $level); + $this->getSubChunk($y >> 4)->getBlockLightArray()->set($x & 0xf, $y & 0x0f, $z & 0xf, $level); } /** @@ -251,7 +251,7 @@ class Chunk{ */ public function setAllBlockLight(int $level) : void{ for($y = $this->getHighestSubChunkIndex(); $y >= 0; --$y){ - $this->getSubChunk($y, true)->setBlockLightArray(LightArray::fill($level)); + $this->getSubChunk($y)->setBlockLightArray(LightArray::fill($level)); } } @@ -659,16 +659,13 @@ class Chunk{ /** * Returns the subchunk at the specified subchunk Y coordinate, or an empty, unmodifiable stub if it does not exist or the coordinate is out of range. * - * @param int $y - * @param bool $generateNew Whether to create a new, modifiable subchunk if there is not one in place + * @param int $y * * @return SubChunkInterface */ - public function getSubChunk(int $y, bool $generateNew = false) : SubChunkInterface{ + public function getSubChunk(int $y) : SubChunkInterface{ if($y < 0 or $y >= $this->subChunks->getSize()){ - return EmptySubChunk::getInstance(); - }elseif($generateNew and $this->subChunks[$y] instanceof EmptySubChunk){ - $this->subChunks[$y] = new SubChunk(BlockLegacyIds::AIR << 4, []); + return EmptySubChunk::getInstance(); //TODO: drop this and throw an exception here } return $this->subChunks[$y]; @@ -677,24 +674,20 @@ class Chunk{ /** * Sets a subchunk in the chunk index * - * @param int $y - * @param SubChunkInterface|null $subChunk - * @param bool $allowEmpty Whether to check if the chunk is empty, and if so replace it with an empty stub + * @param int $y + * @param SubChunk|null $subChunk */ - public function setSubChunk(int $y, ?SubChunkInterface $subChunk, bool $allowEmpty = false) : void{ + public function setSubChunk(int $y, ?SubChunk $subChunk) : void{ if($y < 0 or $y >= $this->subChunks->getSize()){ throw new \InvalidArgumentException("Invalid subchunk Y coordinate $y"); } - if($subChunk === null or ($subChunk->isEmpty() and !$allowEmpty)){ - $this->subChunks[$y] = EmptySubChunk::getInstance(); - }else{ - $this->subChunks[$y] = $subChunk; - } + + $this->subChunks[$y] = $subChunk ?? new SubChunk(BlockLegacyIds::AIR << 4, []); $this->setDirtyFlag(self::DIRTY_FLAG_TERRAIN, true); } /** - * @return \SplFixedArray|SubChunkInterface[] + * @return \SplFixedArray|SubChunk[] */ public function getSubChunks() : \SplFixedArray{ return $this->subChunks; @@ -707,8 +700,7 @@ class Chunk{ */ public function getHighestSubChunkIndex() : int{ for($y = $this->subChunks->count() - 1; $y >= 0; --$y){ - if($this->subChunks[$y] instanceof EmptySubChunk){ - //No need to thoroughly prune empties at runtime, this will just reduce performance. + if($this->subChunks[$y]->isEmptyFast()){ continue; } break; @@ -733,9 +725,6 @@ class Chunk{ foreach($this->subChunks as $y => $subChunk){ if($subChunk instanceof SubChunk){ $subChunk->collectGarbage(); - if($subChunk->isEmpty()){ - $this->subChunks[$y] = EmptySubChunk::getInstance(); - } } } } diff --git a/src/world/format/EmptySubChunk.php b/src/world/format/EmptySubChunk.php index dae6048387..d4beb19312 100644 --- a/src/world/format/EmptySubChunk.php +++ b/src/world/format/EmptySubChunk.php @@ -35,7 +35,11 @@ class EmptySubChunk implements SubChunkInterface{ return self::$instance; } - public function isEmpty(bool $checkLight = true) : bool{ + public function isEmptyAuthoritative() : bool{ + return true; + } + + public function isEmptyFast() : bool{ return true; } diff --git a/src/world/format/SubChunk.php b/src/world/format/SubChunk.php index 026c26dcf8..d0e1c2f181 100644 --- a/src/world/format/SubChunk.php +++ b/src/world/format/SubChunk.php @@ -52,21 +52,13 @@ class SubChunk implements SubChunkInterface{ $this->blockLight = $blockLight ?? new LightArray(LightArray::ZERO); } - public function isEmpty(bool $checkLight = true) : bool{ - foreach($this->blockLayers as $layer){ - $palette = $layer->getPalette(); - foreach($palette as $p){ - if($p !== $this->defaultBlock){ - return false; - } - } - } - return - (!$checkLight or ( - $this->skyLight->getData() === LightArray::FIFTEEN and - $this->blockLight->getData() === LightArray::ZERO - ) - ); + public function isEmptyAuthoritative() : bool{ + $this->collectGarbage(); + return $this->isEmptyFast(); + } + + public function isEmptyFast() : bool{ + return empty($this->blockLayers); } public function getFullBlock(int $x, int $y, int $z) : int{ diff --git a/src/world/format/SubChunkInterface.php b/src/world/format/SubChunkInterface.php index 236a50aeb1..670fac321c 100644 --- a/src/world/format/SubChunkInterface.php +++ b/src/world/format/SubChunkInterface.php @@ -26,11 +26,21 @@ namespace pocketmine\world\format; interface SubChunkInterface{ /** - * @param bool $checkLight + * Returns whether this subchunk contains any non-air blocks. + * This function will do a slow check, usually by garbage collecting first. + * This is typically useful for disk saving. * * @return bool */ - public function isEmpty(bool $checkLight = true) : bool; + public function isEmptyAuthoritative() : bool; + + /** + * Returns a non-authoritative bool to indicate whether the chunk contains any blocks. + * This is a fast check, but may be inaccurate if the chunk has been modified and not garbage-collected. + * + * @return bool + */ + public function isEmptyFast() : bool; /** * @param int $x diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index 20490c4def..66de12c807 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -26,7 +26,6 @@ namespace pocketmine\world\format\io; use pocketmine\block\BlockLegacyIds; use pocketmine\utils\BinaryStream; use pocketmine\world\format\Chunk; -use pocketmine\world\format\EmptySubChunk; use pocketmine\world\format\LightArray; use pocketmine\world\format\PalettedBlockArray; use pocketmine\world\format\SubChunk; @@ -64,9 +63,6 @@ final class FastChunkSerializer{ $count = 0; $subStream = new BinaryStream(); foreach($chunk->getSubChunks() as $y => $subChunk){ - if($subChunk instanceof EmptySubChunk){ - continue; - } ++$count; $subStream->putByte($y); diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 04a1fd8650..329e68c8c0 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -438,7 +438,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $subChunks = $chunk->getSubChunks(); foreach($subChunks as $y => $subChunk){ $key = $index . self::TAG_SUBCHUNK_PREFIX . chr($y); - if($subChunk->isEmpty(false)){ //MCPE doesn't save light anymore as of 1.1 + if($subChunk->isEmptyAuthoritative()){ $write->delete($key); }else{ $subStream = new BinaryStream(); diff --git a/src/world/generator/Flat.php b/src/world/generator/Flat.php index 85e103b59a..e284ac137a 100644 --- a/src/world/generator/Flat.php +++ b/src/world/generator/Flat.php @@ -156,7 +156,7 @@ class Flat extends Generator{ $count = count($this->structure); for($sy = 0; $sy < $count; $sy += 16){ - $subchunk = $this->chunk->getSubChunk($sy >> 4, true); + $subchunk = $this->chunk->getSubChunk($sy >> 4); for($y = 0; $y < 16 and isset($this->structure[$y | $sy]); ++$y){ $id = $this->structure[$y | $sy]; diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index cf1b604207..25e41bd4b0 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -95,10 +95,10 @@ class LightPopulationTask extends AsyncTask{ $blockLightArrays = igbinary_unserialize($this->resultBlockLightArrays); foreach($skyLightArrays as $y => $array){ - $chunk->getSubChunk($y, true)->setBlockSkyLightArray($array); + $chunk->getSubChunk($y)->setBlockSkyLightArray($array); } foreach($blockLightArrays as $y => $array){ - $chunk->getSubChunk($y, true)->setBlockLightArray($array); + $chunk->getSubChunk($y)->setBlockLightArray($array); } $chunk->setLightPopulated(); } diff --git a/src/world/utils/SubChunkIteratorManager.php b/src/world/utils/SubChunkIteratorManager.php index e328445537..4840e0098d 100644 --- a/src/world/utils/SubChunkIteratorManager.php +++ b/src/world/utils/SubChunkIteratorManager.php @@ -26,8 +26,7 @@ namespace pocketmine\world\utils; use pocketmine\utils\Utils; use pocketmine\world\ChunkManager; use pocketmine\world\format\Chunk; -use pocketmine\world\format\EmptySubChunk; -use pocketmine\world\format\SubChunkInterface; +use pocketmine\world\format\SubChunk; class SubChunkIteratorManager{ /** @var ChunkManager */ @@ -35,7 +34,7 @@ class SubChunkIteratorManager{ /** @var Chunk|null */ public $currentChunk; - /** @var SubChunkInterface|null */ + /** @var SubChunk|null */ public $currentSubChunk; /** @var int */ @@ -67,11 +66,12 @@ class SubChunkIteratorManager{ if($this->currentSubChunk === null or $this->currentY !== ($y >> 4)){ $this->currentY = $y >> 4; - $this->currentSubChunk = $this->currentChunk->getSubChunk($y >> 4, $create); - if($this->currentSubChunk instanceof EmptySubChunk){ + if($this->currentY < 0 or $this->currentY >= $this->currentChunk->getHeight()){ $this->currentSubChunk = null; return false; } + + $this->currentSubChunk = $this->currentChunk->getSubChunk($y >> 4); if($this->onSubChunkChangeFunc !== null){ ($this->onSubChunkChangeFunc)(); } From dddc3e8407f021a37220c3f8076b75624c0c3e76 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 22 Oct 2019 21:55:18 +0100 Subject: [PATCH 1266/3224] FastChunkSerializer: remove legacy code, simplify encoding this is also faster than the old technique (theoretically). --- src/world/format/io/FastChunkSerializer.php | 26 ++++++++++----------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index 66de12c807..0ab45ff763 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -60,32 +60,30 @@ final class FastChunkSerializer{ $stream->putByte(($chunk->isLightPopulated() ? 4 : 0) | ($chunk->isPopulated() ? 2 : 0) | ($chunk->isGenerated() ? 1 : 0)); if($chunk->isGenerated()){ //subchunks - $count = 0; - $subStream = new BinaryStream(); - foreach($chunk->getSubChunks() as $y => $subChunk){ - ++$count; + $subChunks = $chunk->getSubChunks(); + $count = $subChunks->count(); + $stream->putByte($count); - $subStream->putByte($y); + foreach($subChunks as $y => $subChunk){ + $stream->putByte($y); $layers = $subChunk->getBlockLayers(); - $subStream->putByte(count($subChunk->getBlockLayers())); + $stream->putByte(count($layers)); foreach($layers as $blocks){ $wordArray = $blocks->getWordArray(); $palette = $blocks->getPalette(); - $subStream->putByte($blocks->getBitsPerBlock()); - $subStream->put($wordArray); + $stream->putByte($blocks->getBitsPerBlock()); + $stream->put($wordArray); $serialPalette = pack("N*", ...$palette); - $subStream->putInt(strlen($serialPalette)); - $subStream->put($serialPalette); + $stream->putInt(strlen($serialPalette)); + $stream->put($serialPalette); } if($chunk->isLightPopulated()){ - $subStream->put($subChunk->getBlockSkyLightArray()->getData()); - $subStream->put($subChunk->getBlockLightArray()->getData()); + $stream->put($subChunk->getBlockSkyLightArray()->getData()); + $stream->put($subChunk->getBlockLightArray()->getData()); } } - $stream->putByte($count); - $stream->put($subStream->getBuffer()); //biomes $stream->put($chunk->getBiomeIdArray()); From f71eecfe564ad541f9f1e3a8436d424bc9c3b151 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 23 Oct 2019 18:25:42 +0100 Subject: [PATCH 1267/3224] Chunk: clean up internals that were designed for variable subchunk stack size this exposed a few bugs in lighting updates too. --- src/world/format/Chunk.php | 44 +++++++++++--------------------------- 1 file changed, 12 insertions(+), 32 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 40e0d27b62..27cbb85a64 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -216,7 +216,7 @@ class Chunk{ * @param int $level */ public function setAllBlockSkyLight(int $level) : void{ - for($y = $this->getHighestSubChunkIndex(); $y >= 0; --$y){ + for($y = $this->subChunks->count() - 1; $y >= 0; --$y){ $this->getSubChunk($y)->setBlockSkyLightArray(LightArray::fill($level)); } } @@ -250,7 +250,7 @@ class Chunk{ * @param int $level */ public function setAllBlockLight(int $level) : void{ - for($y = $this->getHighestSubChunkIndex(); $y >= 0; --$y){ + for($y = $this->subChunks->count() - 1; $y >= 0; --$y){ $this->getSubChunk($y)->setBlockLightArray(LightArray::fill($level)); } } @@ -264,12 +264,7 @@ class Chunk{ * @return int 0-255, or -1 if there are no blocks in the column */ public function getHighestBlockAt(int $x, int $z) : int{ - $index = $this->getHighestSubChunkIndex(); - if($index === -1){ - return -1; - } - - for($y = $index; $y >= 0; --$y){ + for($y = $this->subChunks->count() - 1; $y >= 0; --$y){ $height = $this->getSubChunk($y)->getHighestBlockAt($x, $z) | ($y << 4); if($height !== -1){ return $height; @@ -279,10 +274,6 @@ class Chunk{ return -1; } - public function getMaxY() : int{ - return ($this->getHighestSubChunkIndex() << 4) | 0x0f; - } - /** * Returns the heightmap value at the specified X/Z chunk block coordinates * @@ -345,15 +336,13 @@ class Chunk{ * TODO: fast adjacent light spread */ public function populateSkyLight() : void{ - $maxY = $this->getMaxY(); - $this->setAllBlockSkyLight(0); for($x = 0; $x < 16; ++$x){ for($z = 0; $z < 16; ++$z){ $heightMap = $this->getHeightMap($x, $z); - for($y = $maxY; $y >= $heightMap; --$y){ + for($y = ($this->subChunks->count() * 16) - 1; $y >= $heightMap; --$y){ $this->setBlockSkyLight($x, $y, $z, 15); } @@ -693,29 +682,20 @@ class Chunk{ return $this->subChunks; } - /** - * Returns the Y coordinate of the highest non-empty subchunk in this chunk. - * - * @return int - */ - public function getHighestSubChunkIndex() : int{ - for($y = $this->subChunks->count() - 1; $y >= 0; --$y){ - if($this->subChunks[$y]->isEmptyFast()){ - continue; - } - break; - } - - return $y; - } - /** * Returns the count of subchunks that need sending to players * * @return int */ public function getSubChunkSendCount() : int{ - return $this->getHighestSubChunkIndex() + 1; + for($count = $this->subChunks->count(); $count > 0; --$count){ + if($this->subChunks[$count - 1]->isEmptyFast()){ + continue; + } + break; + } + + return $count; } /** From 23e2e7c320e60d09fa7681b92af49937faec9888 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 23 Oct 2019 18:29:01 +0100 Subject: [PATCH 1268/3224] Chunk: remove useless instanceof check from collectGarbage() --- src/world/format/Chunk.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 27cbb85a64..f7fbf4be1a 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -703,9 +703,7 @@ class Chunk{ */ public function collectGarbage() : void{ foreach($this->subChunks as $y => $subChunk){ - if($subChunk instanceof SubChunk){ - $subChunk->collectGarbage(); - } + $subChunk->collectGarbage(); } } From eedc9eaee1b4e838d6e2e8976ecb77616db1f347 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 23 Oct 2019 18:34:47 +0100 Subject: [PATCH 1269/3224] Chunk: move protocol-specific getSubChunkSendCount() to network chunk serializer --- src/network/mcpe/ChunkRequestTask.php | 2 +- .../mcpe/serializer/ChunkSerializer.php | 20 ++++++++++++++++++- src/world/format/Chunk.php | 16 --------------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php index 1ac04e511c..f95d669ab7 100644 --- a/src/network/mcpe/ChunkRequestTask.php +++ b/src/network/mcpe/ChunkRequestTask.php @@ -61,7 +61,7 @@ class ChunkRequestTask extends AsyncTask{ public function onRun() : void{ $chunk = FastChunkSerializer::deserialize($this->chunk); - $subCount = $chunk->getSubChunkSendCount(); + $subCount = ChunkSerializer::getSubChunkCount($chunk); $payload = ChunkSerializer::serialize($chunk, $this->tiles); $this->setResult(Zlib::compress(PacketBatch::fromPackets(LevelChunkPacket::withoutCache($this->chunkX, $this->chunkZ, $subCount, $payload))->getBuffer(), $this->compressionLevel)); } diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index db4258bdf5..d7c17a92b9 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -35,6 +35,24 @@ final class ChunkSerializer{ //NOOP } + /** + * Returns the number of subchunks that will be sent from the given chunk. + * Chunks are sent in a stack, so every chunk below the top non-empty one must be sent. + * @param Chunk $chunk + * + * @return int + */ + public static function getSubChunkCount(Chunk $chunk) : int{ + for($count = $chunk->getSubChunks()->count(); $count > 0; --$count){ + if($chunk->getSubChunk($count - 1)->isEmptyFast()){ + continue; + } + break; + } + + return $count; + } + /** * @param Chunk $chunk * @@ -44,7 +62,7 @@ final class ChunkSerializer{ */ public static function serialize(Chunk $chunk, ?string $tiles = null) : string{ $stream = new NetworkBinaryStream(); - $subChunkCount = $chunk->getSubChunkSendCount(); + $subChunkCount = self::getSubChunkCount($chunk); for($y = 0; $y < $subChunkCount; ++$y){ $layers = $chunk->getSubChunk($y)->getBlockLayers(); $stream->putByte(8); //version diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index f7fbf4be1a..b91263130d 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -682,22 +682,6 @@ class Chunk{ return $this->subChunks; } - /** - * Returns the count of subchunks that need sending to players - * - * @return int - */ - public function getSubChunkSendCount() : int{ - for($count = $this->subChunks->count(); $count > 0; --$count){ - if($this->subChunks[$count - 1]->isEmptyFast()){ - continue; - } - break; - } - - return $count; - } - /** * Disposes of empty subchunks and frees data where possible */ From 21e9bca64aa2ca6d4f27e82081fc45835ce89451 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 23 Oct 2019 19:30:06 +0100 Subject: [PATCH 1270/3224] World: remove getHeightMap() and setHeightMap() these are too specialized to be of any use to plugin developers, and they are also misleading - plugin devs often think this refers to the highest block Y coordinate, but it doesn't. --- src/world/World.php | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 34d54a8fd8..a220efa396 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2032,25 +2032,6 @@ class World implements ChunkManager{ $this->getChunk($x >> 4, $z >> 4, true)->setBiomeId($x & 0x0f, $z & 0x0f, $biomeId); } - /** - * @param int $x - * @param int $z - * - * @return int - */ - public function getHeightMap(int $x, int $z) : int{ - return $this->getChunk($x >> 4, $z >> 4, true)->getHeightMap($x & 0x0f, $z & 0x0f); - } - - /** - * @param int $x - * @param int $z - * @param int $value - */ - public function setHeightMap(int $x, int $z, int $value){ - $this->getChunk($x >> 4, $z >> 4, true)->setHeightMap($x & 0x0f, $z & 0x0f, $value); - } - /** * @return Chunk[] */ From f3f9ebf3128720fed6a3bf5118c26720dacec72f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 23 Oct 2019 20:21:09 +0100 Subject: [PATCH 1271/3224] SubChunkIteratorManager: added isValid() --- src/world/utils/SubChunkIteratorManager.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/world/utils/SubChunkIteratorManager.php b/src/world/utils/SubChunkIteratorManager.php index 4840e0098d..6a54ccb8dc 100644 --- a/src/world/utils/SubChunkIteratorManager.php +++ b/src/world/utils/SubChunkIteratorManager.php @@ -85,6 +85,15 @@ class SubChunkIteratorManager{ $this->onSubChunkChangeFunc = $callback; } + /** + * Returns whether we currently have a valid terrain pointer. + * + * @return bool + */ + public function isValid() : bool{ + return $this->currentSubChunk !== null; + } + public function invalidate() : void{ $this->currentChunk = null; $this->currentSubChunk = null; From a3b73d95a755ea9615b9eae5f47aba2311c1af96 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 23 Oct 2019 21:01:19 +0100 Subject: [PATCH 1272/3224] LightUpdate: allow providing effective light levels for propagation, fix #2999 --- src/world/light/LightUpdate.php | 18 ++++++++++++------ src/world/light/SkyLightUpdate.php | 9 +++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/world/light/LightUpdate.php b/src/world/light/LightUpdate.php index b608f475a0..c91a68ac47 100644 --- a/src/world/light/LightUpdate.php +++ b/src/world/light/LightUpdate.php @@ -67,6 +67,13 @@ abstract class LightUpdate{ abstract public function recalculateNode(int $x, int $y, int $z) : void; + protected function getEffectiveLight(int $x, int $y, int $z) : int{ + if($this->subChunkHandler->moveTo($x, $y, $z, false)){ + return $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); + } + return 0; + } + protected function getHighestAdjacentLight(int $x, int $y, int $z) : int{ $adjacent = 0; foreach([ @@ -77,7 +84,7 @@ abstract class LightUpdate{ [$x, $y, $z + 1], [$x, $y, $z - 1] ] as [$x1, $y1, $z1]){ - if($this->subChunkHandler->moveTo($x1, $y1, $z1, false) and ($adjacent = max($adjacent, $this->currentLightArray->get($x1 & 0xf, $y1 & 0xf, $z1 & 0xf))) === 15){ + if(($adjacent = max($adjacent, $this->getEffectiveLight($x1, $y1, $z1))) === 15){ break; } } @@ -125,6 +132,9 @@ abstract class LightUpdate{ foreach($points as list($cx, $cy, $cz)){ if($this->subChunkHandler->moveTo($cx, $cy, $cz, true)){ $this->computeRemoveLight($cx, $cy, $cz, $oldAdjacentLight); + }elseif($this->getEffectiveLight($cx, $cy, $cz) > 0 and !isset($this->spreadVisited[$index = World::blockHash($cx, $cy, $cz)])){ + $this->spreadVisited[$index] = true; + $this->spreadQueue->enqueue([$cx, $cy, $cz]); } } } @@ -134,11 +144,7 @@ abstract class LightUpdate{ unset($this->spreadVisited[World::blockHash($x, $y, $z)]); - if(!$this->subChunkHandler->moveTo($x, $y, $z, false)){ - continue; - } - - $newAdjacentLight = $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); + $newAdjacentLight = $this->getEffectiveLight($x, $y, $z); if($newAdjacentLight <= 0){ continue; } diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index 59ab9e98c4..f06b2b3c88 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\world\light; use pocketmine\block\BlockFactory; +use pocketmine\world\World; use function max; class SkyLightUpdate extends LightUpdate{ @@ -31,6 +32,14 @@ class SkyLightUpdate extends LightUpdate{ $this->currentLightArray = $this->subChunkHandler->currentSubChunk->getBlockSkyLightArray(); } + protected function getEffectiveLight(int $x, int $y, int $z) : int{ + if($y >= World::Y_MAX){ + $this->subChunkHandler->invalidate(); + return 15; + } + return parent::getEffectiveLight($x, $y, $z); + } + public function recalculateNode(int $x, int $y, int $z) : void{ $chunk = $this->world->getChunk($x >> 4, $z >> 4); if($chunk === null){ From f01b7b74ba21729ffaddb3972daf598e7024cdea Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 23 Oct 2019 21:25:29 +0100 Subject: [PATCH 1273/3224] World: remove setBlockLightAt() and setBlockSkyLightAt() --- src/world/World.php | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index a220efa396..b9af3ad5b6 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1966,18 +1966,6 @@ class World implements ChunkManager{ return $this->getChunk($x >> 4, $z >> 4, true)->getBlockSkyLight($x & 0x0f, $y, $z & 0x0f); } - /** - * Sets the raw block skylight level. - * - * @param int $x - * @param int $y - * @param int $z - * @param int $level 0-15 - */ - public function setBlockSkyLightAt(int $x, int $y, int $z, int $level) : void{ - $this->getChunk($x >> 4, $z >> 4, true)->setBlockSkyLight($x & 0x0f, $y, $z & 0x0f, $level & 0x0f); - } - /** * Gets the raw block light level * @@ -1991,18 +1979,6 @@ class World implements ChunkManager{ return $this->getChunk($x >> 4, $z >> 4, true)->getBlockLight($x & 0x0f, $y, $z & 0x0f); } - /** - * Sets the raw block light level. - * - * @param int $x - * @param int $y - * @param int $z - * @param int $level 0-15 - */ - public function setBlockLightAt(int $x, int $y, int $z, int $level) : void{ - $this->getChunk($x >> 4, $z >> 4, true)->setBlockLight($x & 0x0f, $y, $z & 0x0f, $level & 0x0f); - } - /** * @param int $x * @param int $z From 3768f3008ed4461d501c1d03255aa44dd50c707d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 23 Oct 2019 21:29:00 +0100 Subject: [PATCH 1274/3224] World: group light-related functions i don't know why these were dumped between getBlock() and setBlock() to begin with. --- src/world/World.php | 186 ++++++++++++++++++++++---------------------- 1 file changed, 93 insertions(+), 93 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index b9af3ad5b6..b4555ef057 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1245,99 +1245,6 @@ class World implements ChunkManager{ return $light < 0 ? 0 : $light; } - /** - * @param int $x - * @param int $y - * @param int $z - * - * @return int bitmap, (id << 4) | data - */ - public function getFullBlock(int $x, int $y, int $z) : int{ - return $this->getChunk($x >> 4, $z >> 4, false)->getFullBlock($x & 0x0f, $y, $z & 0x0f); - } - - public function isInWorld(int $x, int $y, int $z) : bool{ - return ( - $x <= Limits::INT32_MAX and $x >= Limits::INT32_MIN and - $y < $this->worldHeight and $y >= 0 and - $z <= Limits::INT32_MAX and $z >= Limits::INT32_MIN - ); - } - - /** - * Gets the Block object at the Vector3 location. This method wraps around {@link getBlockAt}, converting the - * vector components to integers. - * - * Note: If you're using this for performance-sensitive code, and you're guaranteed to be supplying ints in the - * specified vector, consider using {@link getBlockAt} instead for better performance. - * - * @param Vector3 $pos - * @param bool $cached Whether to use the block cache for getting the block (faster, but may be inaccurate) - * @param bool $addToCache Whether to cache the block object created by this method call. - * - * @return Block - */ - public function getBlock(Vector3 $pos, bool $cached = true, bool $addToCache = true) : Block{ - return $this->getBlockAt((int) floor($pos->x), (int) floor($pos->y), (int) floor($pos->z), $cached, $addToCache); - } - - /** - * Gets the Block object at the specified coordinates. - * - * Note for plugin developers: If you are using this method a lot (thousands of times for many positions for - * example), you may want to set addToCache to false to avoid using excessive amounts of memory. - * - * @param int $x - * @param int $y - * @param int $z - * @param bool $cached Whether to use the block cache for getting the block (faster, but may be inaccurate) - * @param bool $addToCache Whether to cache the block object created by this method call. - * - * @return Block - */ - public function getBlockAt(int $x, int $y, int $z, bool $cached = true, bool $addToCache = true) : Block{ - $fullState = 0; - $relativeBlockHash = null; - $chunkHash = World::chunkHash($x >> 4, $z >> 4); - - if($this->isInWorld($x, $y, $z)){ - $relativeBlockHash = World::chunkBlockHash($x, $y, $z); - - if($cached and isset($this->blockCache[$chunkHash][$relativeBlockHash])){ - return $this->blockCache[$chunkHash][$relativeBlockHash]; - } - - $chunk = $this->chunks[$chunkHash] ?? null; - if($chunk !== null){ - $fullState = $chunk->getFullBlock($x & 0x0f, $y, $z & 0x0f); - }else{ - $addToCache = false; - } - } - - $block = BlockFactory::fromFullBlock($fullState); - $block->position($this, $x, $y, $z); - - static $dynamicStateRead = false; - - if($dynamicStateRead){ - //this call was generated by a parent getBlock() call calculating dynamic stateinfo - //don't calculate dynamic state and don't add to block cache (since it won't have dynamic state calculated). - //this ensures that it's impossible for dynamic state properties to recursively depend on each other. - $addToCache = false; - }else{ - $dynamicStateRead = true; - $block->readStateFromWorld(); - $dynamicStateRead = false; - } - - if($addToCache and $relativeBlockHash !== null){ - $this->blockCache[$chunkHash][$relativeBlockHash] = $block; - } - - return $block; - } - public function updateAllLight(Vector3 $pos){ $this->updateBlockSkyLight($pos->x, $pos->y, $pos->z); $this->updateBlockLight($pos->x, $pos->y, $pos->z); @@ -1435,6 +1342,99 @@ class World implements ChunkManager{ } } + /** + * @param int $x + * @param int $y + * @param int $z + * + * @return int bitmap, (id << 4) | data + */ + public function getFullBlock(int $x, int $y, int $z) : int{ + return $this->getChunk($x >> 4, $z >> 4, false)->getFullBlock($x & 0x0f, $y, $z & 0x0f); + } + + public function isInWorld(int $x, int $y, int $z) : bool{ + return ( + $x <= Limits::INT32_MAX and $x >= Limits::INT32_MIN and + $y < $this->worldHeight and $y >= 0 and + $z <= Limits::INT32_MAX and $z >= Limits::INT32_MIN + ); + } + + /** + * Gets the Block object at the Vector3 location. This method wraps around {@link getBlockAt}, converting the + * vector components to integers. + * + * Note: If you're using this for performance-sensitive code, and you're guaranteed to be supplying ints in the + * specified vector, consider using {@link getBlockAt} instead for better performance. + * + * @param Vector3 $pos + * @param bool $cached Whether to use the block cache for getting the block (faster, but may be inaccurate) + * @param bool $addToCache Whether to cache the block object created by this method call. + * + * @return Block + */ + public function getBlock(Vector3 $pos, bool $cached = true, bool $addToCache = true) : Block{ + return $this->getBlockAt((int) floor($pos->x), (int) floor($pos->y), (int) floor($pos->z), $cached, $addToCache); + } + + /** + * Gets the Block object at the specified coordinates. + * + * Note for plugin developers: If you are using this method a lot (thousands of times for many positions for + * example), you may want to set addToCache to false to avoid using excessive amounts of memory. + * + * @param int $x + * @param int $y + * @param int $z + * @param bool $cached Whether to use the block cache for getting the block (faster, but may be inaccurate) + * @param bool $addToCache Whether to cache the block object created by this method call. + * + * @return Block + */ + public function getBlockAt(int $x, int $y, int $z, bool $cached = true, bool $addToCache = true) : Block{ + $fullState = 0; + $relativeBlockHash = null; + $chunkHash = World::chunkHash($x >> 4, $z >> 4); + + if($this->isInWorld($x, $y, $z)){ + $relativeBlockHash = World::chunkBlockHash($x, $y, $z); + + if($cached and isset($this->blockCache[$chunkHash][$relativeBlockHash])){ + return $this->blockCache[$chunkHash][$relativeBlockHash]; + } + + $chunk = $this->chunks[$chunkHash] ?? null; + if($chunk !== null){ + $fullState = $chunk->getFullBlock($x & 0x0f, $y, $z & 0x0f); + }else{ + $addToCache = false; + } + } + + $block = BlockFactory::fromFullBlock($fullState); + $block->position($this, $x, $y, $z); + + static $dynamicStateRead = false; + + if($dynamicStateRead){ + //this call was generated by a parent getBlock() call calculating dynamic stateinfo + //don't calculate dynamic state and don't add to block cache (since it won't have dynamic state calculated). + //this ensures that it's impossible for dynamic state properties to recursively depend on each other. + $addToCache = false; + }else{ + $dynamicStateRead = true; + $block->readStateFromWorld(); + $dynamicStateRead = false; + } + + if($addToCache and $relativeBlockHash !== null){ + $this->blockCache[$chunkHash][$relativeBlockHash] = $block; + } + + return $block; + } + /** * Sets the block at the given Vector3 coordinates. * From 9aab97578b01b550e8571cd82a23e973fd45b775 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 23 Oct 2019 21:52:39 +0100 Subject: [PATCH 1275/3224] World: clean up lighting update API --- src/world/Explosion.php | 2 +- src/world/World.php | 43 +++++++++++++++-------------------------- 2 files changed, 17 insertions(+), 28 deletions(-) diff --git a/src/world/Explosion.php b/src/world/Explosion.php index 3e3a95a689..47eb6475ff 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -228,7 +228,7 @@ class Explosion{ $t->onBlockDestroyed(); //needed to create drops for inventories } $this->world->setBlockAt($pos->x, $pos->y, $pos->z, $airBlock, false); //TODO: should updating really be disabled here? - $this->world->updateAllLight($pos); + $this->world->updateAllLight($pos->x, $pos->y, $pos->z); } foreach(Facing::ALL as $side){ diff --git a/src/world/World.php b/src/world/World.php index b4555ef057..f88fd4c5fc 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1245,9 +1245,20 @@ class World implements ChunkManager{ return $light < 0 ? 0 : $light; } - public function updateAllLight(Vector3 $pos){ - $this->updateBlockSkyLight($pos->x, $pos->y, $pos->z); - $this->updateBlockLight($pos->x, $pos->y, $pos->z); + public function updateAllLight(int $x, int $y, int $z) : void{ + $this->timings->doBlockSkyLightUpdates->startTiming(); + if($this->skyLightUpdate === null){ + $this->skyLightUpdate = new SkyLightUpdate($this); + } + $this->skyLightUpdate->recalculateNode($x, $y, $z); + $this->timings->doBlockSkyLightUpdates->stopTiming(); + + $this->timings->doBlockLightUpdates->startTiming(); + if($this->blockLightUpdate === null){ + $this->blockLightUpdate = new BlockLightUpdate($this); + } + $this->blockLightUpdate->recalculateNode($x, $y, $z); + $this->timings->doBlockLightUpdates->stopTiming(); } /** @@ -1277,17 +1288,6 @@ class World implements ChunkManager{ return $max; } - public function updateBlockSkyLight(int $x, int $y, int $z){ - $this->timings->doBlockSkyLightUpdates->startTiming(); - - if($this->skyLightUpdate === null){ - $this->skyLightUpdate = new SkyLightUpdate($this); - } - $this->skyLightUpdate->recalculateNode($x, $y, $z); - - $this->timings->doBlockSkyLightUpdates->stopTiming(); - } - /** * Returns the highest block light level available in the positions adjacent to the specified block coordinates. * @@ -1315,18 +1315,7 @@ class World implements ChunkManager{ return $max; } - public function updateBlockLight(int $x, int $y, int $z){ - $this->timings->doBlockLightUpdates->startTiming(); - - if($this->blockLightUpdate === null){ - $this->blockLightUpdate = new BlockLightUpdate($this); - } - $this->blockLightUpdate->recalculateNode($x, $y, $z); - - $this->timings->doBlockLightUpdates->stopTiming(); - } - - public function executeQueuedLightUpdates() : void{ + private function executeQueuedLightUpdates() : void{ if($this->blockLightUpdate !== null){ $this->timings->doBlockLightUpdates->startTiming(); $this->blockLightUpdate->execute(); @@ -1493,7 +1482,7 @@ class World implements ChunkManager{ if($update){ if($oldBlock->getLightFilter() !== $block->getLightFilter() or $oldBlock->getLightLevel() !== $block->getLightLevel()){ - $this->updateAllLight($pos); + $this->updateAllLight($x, $y, $z); } $this->tryAddToNeighbourUpdateQueue($pos); foreach($pos->sides() as $side){ From acdcb99566402251b46b4122fbbbd5ed374689f5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 24 Oct 2019 11:46:47 +0100 Subject: [PATCH 1276/3224] fixed 2cac7331f5f4922fba3eeb1c98ce1fbe45541cec merge error --- src/PocketMine.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index 5c0d6b42f1..cb403fa842 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -201,9 +201,9 @@ namespace pocketmine { $gitHash = str_repeat("00", 20); if(\Phar::running(true) === ""){ - if(Utils::execute("git rev-parse HEAD", $out) === 0 and $out !== false and strlen($out = trim($out)) === 40){ + if(Process::execute("git rev-parse HEAD", $out) === 0 and $out !== false and strlen($out = trim($out)) === 40){ $gitHash = trim($out); - if(Utils::execute("git diff --quiet") === 1 or Utils::execute("git diff --cached --quiet") === 1){ //Locally-modified + if(Process::execute("git diff --quiet") === 1 or Process::execute("git diff --cached --quiet") === 1){ //Locally-modified $gitHash .= "-dirty"; } } From 043f1a55772ac525a7609575091250bdf423953e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 24 Oct 2019 13:17:04 +0100 Subject: [PATCH 1277/3224] ext-igbinary is mandatory since e1352668d1bfc9d6638afc4c7c43cf17b87430c5 --- composer.json | 1 + composer.lock | 3 ++- src/PocketMine.php | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 594e625a91..2ca20c9b9c 100644 --- a/composer.json +++ b/composer.json @@ -16,6 +16,7 @@ "ext-ds": "^1.2.7", "ext-gmp": "*", "ext-hash": "*", + "ext-igbinary": "^3.0.1", "ext-json": "*", "ext-leveldb": "^0.2.1", "ext-mbstring": "*", diff --git a/composer.lock b/composer.lock index fed61c555b..60ef9d64a5 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "eedc6357547d912c1cc4d47477573086", + "content-hash": "64291f2e02aeadac88f4f205e8ec76e5", "packages": [ { "name": "adhocore/json-comment", @@ -537,6 +537,7 @@ "ext-ds": "^1.2.7", "ext-gmp": "*", "ext-hash": "*", + "ext-igbinary": "^3.0.1", "ext-json": "*", "ext-leveldb": "^0.2.1", "ext-mbstring": "*", diff --git a/src/PocketMine.php b/src/PocketMine.php index cb403fa842..12325c7ffd 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -78,6 +78,7 @@ namespace pocketmine { "ds" => "Data Structures", "gmp" => "GMP", "hash" => "Hash", + "igbinary" => "igbinary", "json" => "JSON", "leveldb" => "LevelDB", "mbstring" => "Multibyte String", From dbc4f84bcbeb2f6fbc7bd65751bd99d8e3027645 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 24 Oct 2019 13:18:42 +0100 Subject: [PATCH 1278/3224] travis: add igbinary --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 79aab78362..404b76e593 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,6 +26,7 @@ before_script: - echo | pecl install channel://pecl.php.net/yaml-2.0.4 - pecl install channel://pecl.php.net/crypto-0.3.1 - pecl install channel://pecl.php.net/ds-1.2.8 + - pecl install channel://pecl.php.net/igbinary-3.0.1 - git clone https://github.com/pmmp/pthreads.git - cd pthreads - git checkout 6ca019c58b4fa09ee2ff490f2444e34bef0773d0 From ec13cd695d190a1b7c5aa782fd56d2ac2a21b166 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 24 Oct 2019 13:19:29 +0100 Subject: [PATCH 1279/3224] travis: use ds 1.2.9 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 404b76e593..39ed3f49f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ before_script: # - pecl install channel://pecl.php.net/pthreads-3.1.6 - echo | pecl install channel://pecl.php.net/yaml-2.0.4 - pecl install channel://pecl.php.net/crypto-0.3.1 - - pecl install channel://pecl.php.net/ds-1.2.8 + - pecl install channel://pecl.php.net/ds-1.2.9 - pecl install channel://pecl.php.net/igbinary-3.0.1 - git clone https://github.com/pmmp/pthreads.git - cd pthreads From 15762b03f87e5d31f87d99c2518b9dc8601ef23f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 24 Oct 2019 13:27:38 +0100 Subject: [PATCH 1280/3224] EntityMetadataCollection: fixed wrong parameter doc type on set() --- .../mcpe/protocol/types/entity/EntityMetadataCollection.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php b/src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php index a98f592c62..3fa0ea9dd3 100644 --- a/src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php +++ b/src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php @@ -121,9 +121,9 @@ class EntityMetadataCollection{ } /** - * @param int $key - * @param mixed $value - * @param bool $force + * @param int $key + * @param MetadataProperty $value + * @param bool $force */ public function set(int $key, MetadataProperty $value, bool $force = false) : void{ if(!$force and isset($this->properties[$key]) and !($this->properties[$key] instanceof $value)){ From e4d2a4d9112466284a7ec28044d024c3f5182c54 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 24 Oct 2019 13:30:05 +0100 Subject: [PATCH 1281/3224] canary: update build/php submodule --- build/php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/php b/build/php index ad55054ce2..09362df531 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit ad55054ce2b416346a43f4aa993a8d46bc86d7f5 +Subproject commit 09362df531490e12997a7f3f84564572614f22d8 From 0a751857ccf7a8d1b6e8624d9ab9da93d5d5ec80 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 24 Oct 2019 19:39:58 +0100 Subject: [PATCH 1282/3224] added pocketmine/log dependency --- composer.json | 5 +++++ composer.lock | 53 +++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/composer.json b/composer.json index 2ca20c9b9c..54becd0f61 100644 --- a/composer.json +++ b/composer.json @@ -34,6 +34,7 @@ "pocketmine/raklib": "dev-master", "pocketmine/spl": "dev-master", "pocketmine/binaryutils": "dev-master", + "pocketmine/log": "dev-master", "pocketmine/nbt": "dev-master", "pocketmine/math": "dev-master", "pocketmine/snooze": "^0.1.0", @@ -75,6 +76,10 @@ { "type": "vcs", "url": "https://github.com/pmmp/Snooze" + }, + { + "type": "vcs", + "url": "https://github.com/pmmp/Log" } ] } diff --git a/composer.lock b/composer.lock index 60ef9d64a5..2f5a95a5d9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "64291f2e02aeadac88f4f205e8ec76e5", + "content-hash": "0837e139f1183b1aee7c4294fe63a179", "packages": [ { "name": "adhocore/json-comment", @@ -327,6 +327,36 @@ }, "time": "2019-10-21T14:41:23+00:00" }, + { + "name": "pocketmine/log", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/pmmp/Log.git", + "reference": "c3fd1932cc721d66b8d5a1a340d679e22fab1f87" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pmmp/Log/zipball/c3fd1932cc721d66b8d5a1a340d679e22fab1f87", + "reference": "c3fd1932cc721d66b8d5a1a340d679e22fab1f87", + "shasum": "" + }, + "type": "library", + "autoload": { + "classmap": [ + "./" + ] + }, + "license": [ + "LGPL-3.0" + ], + "description": "Logging components used by PocketMine-MP and related projects", + "support": { + "source": "https://github.com/pmmp/Log/tree/master", + "issues": "https://github.com/pmmp/Log/issues" + }, + "time": "2019-10-24T18:24:06+00:00" + }, { "name": "pocketmine/math", "version": "dev-master", @@ -413,12 +443,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "3652dbc4b49225149b7d2fbd5c380fc39b6aff24" + "reference": "cf55a18aebd149c6ca23b0643ad2f5a6e48a05cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/3652dbc4b49225149b7d2fbd5c380fc39b6aff24", - "reference": "3652dbc4b49225149b7d2fbd5c380fc39b6aff24", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/cf55a18aebd149c6ca23b0643ad2f5a6e48a05cf", + "reference": "cf55a18aebd149c6ca23b0643ad2f5a6e48a05cf", "shasum": "" }, "require": { @@ -429,6 +459,7 @@ "php-64bit": "*", "php-ipv6": "*", "pocketmine/binaryutils": "dev-master", + "pocketmine/log": "dev-master", "pocketmine/snooze": "^0.1.0", "pocketmine/spl": "dev-master" }, @@ -446,7 +477,7 @@ "source": "https://github.com/pmmp/RakLib/tree/master", "issues": "https://github.com/pmmp/RakLib/issues" }, - "time": "2019-08-30T17:40:14+00:00" + "time": "2019-10-24T18:35:05+00:00" }, { "name": "pocketmine/snooze", @@ -488,12 +519,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/SPL.git", - "reference": "6fee4ae7d2b4b0463702cb427626bc9def32fb61" + "reference": "e2f72340aefa1a5802a7096a720d3ecede9f8f4a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/SPL/zipball/6fee4ae7d2b4b0463702cb427626bc9def32fb61", - "reference": "6fee4ae7d2b4b0463702cb427626bc9def32fb61", + "url": "https://api.github.com/repos/pmmp/SPL/zipball/e2f72340aefa1a5802a7096a720d3ecede9f8f4a", + "reference": "e2f72340aefa1a5802a7096a720d3ecede9f8f4a", "shasum": "" }, "type": "library", @@ -507,9 +538,10 @@ ], "description": "Standard library files required by PocketMine-MP and related projects", "support": { - "source": "https://github.com/pmmp/SPL/tree/master" + "source": "https://github.com/pmmp/SPL/tree/master", + "issues": "https://github.com/pmmp/SPL/issues" }, - "time": "2019-08-25T18:29:14+00:00" + "time": "2019-10-24T18:37:23+00:00" } ], "packages-dev": [], @@ -519,6 +551,7 @@ "pocketmine/raklib": 20, "pocketmine/spl": 20, "pocketmine/binaryutils": 20, + "pocketmine/log": 20, "pocketmine/nbt": 20, "pocketmine/math": 20, "daverandom/callback-validator": 20 From 46e005543f0ac96211018a412833665f84ba67aa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 24 Oct 2019 19:49:53 +0100 Subject: [PATCH 1283/3224] update pocketmine/log --- composer.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.lock b/composer.lock index 2f5a95a5d9..5fc7a12f3b 100644 --- a/composer.lock +++ b/composer.lock @@ -333,18 +333,18 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Log.git", - "reference": "c3fd1932cc721d66b8d5a1a340d679e22fab1f87" + "reference": "27a5f5cf5bfeddec4231470a7b803c7bf8df6fbe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Log/zipball/c3fd1932cc721d66b8d5a1a340d679e22fab1f87", - "reference": "c3fd1932cc721d66b8d5a1a340d679e22fab1f87", + "url": "https://api.github.com/repos/pmmp/Log/zipball/27a5f5cf5bfeddec4231470a7b803c7bf8df6fbe", + "reference": "27a5f5cf5bfeddec4231470a7b803c7bf8df6fbe", "shasum": "" }, "type": "library", "autoload": { "classmap": [ - "./" + "./src" ] }, "license": [ @@ -355,7 +355,7 @@ "source": "https://github.com/pmmp/Log/tree/master", "issues": "https://github.com/pmmp/Log/issues" }, - "time": "2019-10-24T18:24:06+00:00" + "time": "2019-10-24T18:48:08+00:00" }, { "name": "pocketmine/math", From c8cf329c94ac469c4b7e5f62de4b838488b093da Mon Sep 17 00:00:00 2001 From: Jack Noordhuis Date: Fri, 25 Oct 2019 06:26:42 +1100 Subject: [PATCH 1284/3224] Plugin::getLogger() interface no longer depends on PluginLogger (#3160) The Plugin contract now typehints the relied on AttachableLogger contract rather than the concrete PluginLogger implementation. --- src/plugin/Plugin.php | 4 ++-- src/plugin/PluginBase.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugin/Plugin.php b/src/plugin/Plugin.php index 9813061be8..7b6328e414 100644 --- a/src/plugin/Plugin.php +++ b/src/plugin/Plugin.php @@ -81,9 +81,9 @@ interface Plugin{ public function getName() : string; /** - * @return PluginLogger + * @return \AttachableLogger */ - public function getLogger() : PluginLogger; + public function getLogger() : \AttachableLogger; /** * @return PluginLoader diff --git a/src/plugin/PluginBase.php b/src/plugin/PluginBase.php index 1f04c5b611..a3a16f3d36 100644 --- a/src/plugin/PluginBase.php +++ b/src/plugin/PluginBase.php @@ -163,9 +163,9 @@ abstract class PluginBase implements Plugin, CommandExecutor{ } /** - * @return PluginLogger + * @return \AttachableLogger */ - public function getLogger() : PluginLogger{ + public function getLogger() : \AttachableLogger{ return $this->logger; } From 2e446e4df3fead6804c4c3420ff5c733563de634 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 28 Oct 2019 12:29:48 +0000 Subject: [PATCH 1285/3224] added pocketmine/classloader dependency (extracted from pocketmine/spl) --- composer.json | 5 +++++ composer.lock | 46 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 54becd0f61..0276e03de2 100644 --- a/composer.json +++ b/composer.json @@ -38,6 +38,7 @@ "pocketmine/nbt": "dev-master", "pocketmine/math": "dev-master", "pocketmine/snooze": "^0.1.0", + "pocketmine/classloader": "dev-master", "daverandom/callback-validator": "dev-master", "adhocore/json-comment": "^0.0.7", "particle/validator": "^2.3" @@ -80,6 +81,10 @@ { "type": "vcs", "url": "https://github.com/pmmp/Log" + }, + { + "type": "vcs", + "url": "https://github.com/pmmp/ClassLoader" } ] } diff --git a/composer.lock b/composer.lock index 5fc7a12f3b..f2fb5efac0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0837e139f1183b1aee7c4294fe63a179", + "content-hash": "730b9ef97624239c1bd013478b5f64e8", "packages": [ { "name": "adhocore/json-comment", @@ -327,6 +327,41 @@ }, "time": "2019-10-21T14:41:23+00:00" }, + { + "name": "pocketmine/classloader", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/pmmp/ClassLoader.git", + "reference": "e7d1e7701374760752a23c093ba925f3a518d88d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/e7d1e7701374760752a23c093ba925f3a518d88d", + "reference": "e7d1e7701374760752a23c093ba925f3a518d88d", + "shasum": "" + }, + "require": { + "ext-pthreads": "~3.2.0", + "ext-reflection": "*", + "php": ">=7.2.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "./" + ] + }, + "license": [ + "LGPL-3.0" + ], + "description": "Ad-hoc autoloading components used by PocketMine-MP", + "support": { + "source": "https://github.com/pmmp/ClassLoader/tree/master", + "issues": "https://github.com/pmmp/ClassLoader/issues" + }, + "time": "2019-10-28T12:24:55+00:00" + }, { "name": "pocketmine/log", "version": "dev-master", @@ -519,12 +554,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/SPL.git", - "reference": "e2f72340aefa1a5802a7096a720d3ecede9f8f4a" + "reference": "4a94ec60efd514ef98e84a064fe1a4b8ee73bbad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/SPL/zipball/e2f72340aefa1a5802a7096a720d3ecede9f8f4a", - "reference": "e2f72340aefa1a5802a7096a720d3ecede9f8f4a", + "url": "https://api.github.com/repos/pmmp/SPL/zipball/4a94ec60efd514ef98e84a064fe1a4b8ee73bbad", + "reference": "4a94ec60efd514ef98e84a064fe1a4b8ee73bbad", "shasum": "" }, "type": "library", @@ -541,7 +576,7 @@ "source": "https://github.com/pmmp/SPL/tree/master", "issues": "https://github.com/pmmp/SPL/issues" }, - "time": "2019-10-24T18:37:23+00:00" + "time": "2019-10-28T12:26:23+00:00" } ], "packages-dev": [], @@ -554,6 +589,7 @@ "pocketmine/log": 20, "pocketmine/nbt": 20, "pocketmine/math": 20, + "pocketmine/classloader": 20, "daverandom/callback-validator": 20 }, "prefer-stable": false, From cbef2bbc5134845bae87dbf8a98b62502f2a0578 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 29 Oct 2019 12:42:38 +0000 Subject: [PATCH 1286/3224] move ThreadException to pocketmine\thread namespace --- composer.lock | 8 ++++---- src/command/CommandReader.php | 3 ++- src/thread/ThreadException.php | 28 ++++++++++++++++++++++++++++ src/thread/ThreadManager.php | 2 +- 4 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 src/thread/ThreadException.php diff --git a/composer.lock b/composer.lock index f2fb5efac0..57bea41721 100644 --- a/composer.lock +++ b/composer.lock @@ -554,12 +554,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/SPL.git", - "reference": "4a94ec60efd514ef98e84a064fe1a4b8ee73bbad" + "reference": "091acb66c7927f2abe8960081d222142b1e6d17b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/SPL/zipball/4a94ec60efd514ef98e84a064fe1a4b8ee73bbad", - "reference": "4a94ec60efd514ef98e84a064fe1a4b8ee73bbad", + "url": "https://api.github.com/repos/pmmp/SPL/zipball/091acb66c7927f2abe8960081d222142b1e6d17b", + "reference": "091acb66c7927f2abe8960081d222142b1e6d17b", "shasum": "" }, "type": "library", @@ -576,7 +576,7 @@ "source": "https://github.com/pmmp/SPL/tree/master", "issues": "https://github.com/pmmp/SPL/issues" }, - "time": "2019-10-28T12:26:23+00:00" + "time": "2019-10-29T11:57:45+00:00" } ], "packages-dev": [], diff --git a/src/command/CommandReader.php b/src/command/CommandReader.php index 70660c8211..2143ad3c00 100644 --- a/src/command/CommandReader.php +++ b/src/command/CommandReader.php @@ -25,6 +25,7 @@ namespace pocketmine\command; use pocketmine\snooze\SleeperNotifier; use pocketmine\thread\Thread; +use pocketmine\thread\ThreadException; use pocketmine\utils\Utils; use function extension_loaded; use function fclose; @@ -91,7 +92,7 @@ class CommandReader extends Thread{ $message = "STDIN is being piped from another location and the pipe is blocked, cannot stop safely"; } - throw new \ThreadException($message); + throw new ThreadException($message); } private function initStdin() : void{ diff --git a/src/thread/ThreadException.php b/src/thread/ThreadException.php new file mode 100644 index 0000000000..2779c1795b --- /dev/null +++ b/src/thread/ThreadException.php @@ -0,0 +1,28 @@ +quit(); $logger->debug($thread->getThreadName() . " thread stopped successfully."); - }catch(\ThreadException $e){ + }catch(ThreadException $e){ ++$erroredThreads; $logger->debug("Could not stop " . $thread->getThreadName() . " thread: " . $e->getMessage()); } From 92700b2e18ac601fe8ed3d0c4c4f159a499cf7b0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 9 Nov 2019 18:10:53 +0000 Subject: [PATCH 1287/3224] phpstan.neon: remove error patterns that don't occur on 4.0 --- phpstan.neon | 71 +--------------------------------------------------- 1 file changed, 1 insertion(+), 70 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 25ee04e9f3..fc850f1006 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -14,49 +14,11 @@ parameters: count: 1 path: src/PocketMine.php - - - message: "#^pocketmine\\\\Player\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\entity\\\\Human\\.$#" - path: src/Player.php - - - - message: "#^pocketmine\\\\block\\\\[A-Za-z\\d]+\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\block\\\\Block\\.$#" - path: src/block - - - - message: "#^pocketmine\\\\block\\\\Block\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\level\\\\Position\\.$#" - count: 1 - path: src/block/Block.php - - message: "#^pocketmine\\\\inventory\\\\DoubleChestInventory\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\inventory\\\\ChestInventory\\.$#" count: 1 path: src/inventory/DoubleChestInventory.php - - - message: "#^pocketmine\\\\inventory\\\\EnderChestInventory\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\inventory\\\\ChestInventory\\.$#" - count: 1 - path: src/inventory/EnderChestInventory.php - - - - message: "#^pocketmine\\\\item\\\\GoldenAppleEnchanted\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\item\\\\GoldenApple\\.$#" - count: 1 - path: src/item/GoldenAppleEnchanted.php - - - - message: "#^pocketmine\\\\item\\\\WrittenBook\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\item\\\\WritableBook\\.$#" - count: 1 - path: src/item/WrittenBook.php - - - - message: "#^Constructor of class pocketmine\\\\level\\\\generator\\\\hell\\\\Nether has an unused parameter \\$options\\.$#" - count: 1 - path: src/level/generator/hell/Nether.php - - - - message: "#^Constructor of class pocketmine\\\\level\\\\generator\\\\normal\\\\Normal has an unused parameter \\$options\\.$#" - count: 1 - path: src/level/generator/normal/Normal.php - - message: "#^Used constant pocketmine\\\\RESOURCE_PATH not found\\.$#" count: 1 @@ -64,7 +26,7 @@ parameters: - message: "#^Instantiated class COM not found\\.$#" - count: 2 + count: 1 path: src/network/upnp/UPnP.php comment: "only available on Windows" @@ -74,11 +36,6 @@ parameters: path: src/network/upnp/UPnP.php comment: "only available on Windows" - - - message: "#^Constructor of class pocketmine\\\\scheduler\\\\TaskScheduler has an unused parameter \\$logger\\.$#" - count: 1 - path: src/scheduler/TaskScheduler.php - - message: "#^Variable \\$GLOBALS in isset\\(\\) always exists and is not nullable\\.$#" path: src/MemoryManager.php @@ -88,10 +45,6 @@ parameters: message: "#^Constant pocketmine\\\\COMPOSER_AUTOLOADER_PATH not found\\.$#" path: src - - - message: "#^Constant pocketmine\\\\DATA not found\\.$#" - path: src - - message: "#^Constant pocketmine\\\\GIT_COMMIT not found\\.$#" path: src @@ -108,28 +61,6 @@ parameters: message: "#^Constant pocketmine\\\\RESOURCE_PATH not found\\.$#" path: src - - - message: "#^Constant pocketmine\\\\START_TIME not found\\.$#" - path: src - - message: "#^Constant pocketmine\\\\VERSION not found\\.$#" path: src - - - message: "#^Used constant LEVELDB_ZLIB_RAW_COMPRESSION not found\\.$#" - path: src/level/format/io/leveldb/LevelDB.php - comment: "explicitly checked" - - - message: "#^Constant LEVELDB_ZLIB_RAW_COMPRESSION not found\\.$#" - path: src/level/format/io/leveldb/LevelDB.php - comment: "explicitly checked" - - - message: "#^Instantiated class LevelDB not found\\.$#" - path: src/level/format/io/leveldb/LevelDB.php - comment: "leveldb extension currently optional" - - - message: "#^Return typehint of method pocketmine\\\\level\\\\format\\\\io\\\\leveldb\\\\LevelDB\\:\\:createDB\\(\\) has invalid type LevelDB\\.$#" - path: src/level/format/io/leveldb/LevelDB.php - - - message: "#^Return typehint of method pocketmine\\\\level\\\\format\\\\io\\\\leveldb\\\\LevelDB\\:\\:getDatabase\\(\\) has invalid type LevelDB\\.$#" - path: src/level/format/io/leveldb/LevelDB.php From 7276eda0e5464811ac966aa2a10248e7657720b7 Mon Sep 17 00:00:00 2001 From: Encritary Date: Sun, 10 Nov 2019 00:56:06 +0500 Subject: [PATCH 1288/3224] Moved SetTitlePacket usage to NetworkSession (#3186) --- src/network/mcpe/NetworkSession.php | 25 +++++++++++++++++++++++++ src/player/Player.php | 13 ++++++------- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index b326dab4c6..89fdefbb70 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -64,6 +64,7 @@ use pocketmine\network\mcpe\protocol\ServerboundPacket; use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket; use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket; +use pocketmine\network\mcpe\protocol\SetTitlePacket; use pocketmine\network\mcpe\protocol\TextPacket; use pocketmine\network\mcpe\protocol\TransferPacket; use pocketmine\network\mcpe\protocol\types\command\CommandData; @@ -843,6 +844,30 @@ class NetworkSession{ } } + public function onTitle(string $title) : void{ + $this->sendDataPacket(SetTitlePacket::title($title)); + } + + public function onSubTitle(string $subtitle) : void{ + $this->sendDataPacket(SetTitlePacket::subtitle($subtitle)); + } + + public function onActionBar(string $actionBar) : void{ + $this->sendDataPacket(SetTitlePacket::actionBarMessage($actionBar)); + } + + public function onClearTitle() : void{ + $this->sendDataPacket(SetTitlePacket::clearTitle()); + } + + public function onResetTitleOptions() : void{ + $this->sendDataPacket(SetTitlePacket::resetTitleOptions()); + } + + public function onTitleDuration(int $fadeIn, int $stay, int $fadeOut) : void{ + $this->sendDataPacket(SetTitlePacket::setAnimationTimes($fadeIn, $stay, $fadeOut)); + } + public function tick() : bool{ if($this->info === null){ if(time() >= $this->connectTime + 10){ diff --git a/src/player/Player.php b/src/player/Player.php index 2a75966242..7adac45d1a 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -85,7 +85,6 @@ use pocketmine\network\mcpe\protocol\ActorEventPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; -use pocketmine\network\mcpe\protocol\SetTitlePacket; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\entity\PlayerMetadataFlags; @@ -1900,7 +1899,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($subtitle !== ""){ $this->sendSubTitle($subtitle); } - $this->networkSession->sendDataPacket(SetTitlePacket::title($title)); + $this->networkSession->onTitle($title); } /** @@ -1909,7 +1908,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @param string $subtitle */ public function sendSubTitle(string $subtitle) : void{ - $this->networkSession->sendDataPacket(SetTitlePacket::subtitle($subtitle)); + $this->networkSession->onSubTitle($subtitle); } /** @@ -1918,21 +1917,21 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @param string $message */ public function sendActionBarMessage(string $message) : void{ - $this->networkSession->sendDataPacket(SetTitlePacket::actionBarMessage($message)); + $this->networkSession->onActionBar($message); } /** * Removes the title from the client's screen. */ public function removeTitles(){ - $this->networkSession->sendDataPacket(SetTitlePacket::clearTitle()); + $this->networkSession->onClearTitle(); } /** * Resets the title duration settings to defaults and removes any existing titles. */ public function resetTitles(){ - $this->networkSession->sendDataPacket(SetTitlePacket::resetTitleOptions()); + $this->networkSession->onResetTitleOptions(); } /** @@ -1944,7 +1943,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, */ public function setTitleDuration(int $fadeIn, int $stay, int $fadeOut){ if($fadeIn >= 0 and $stay >= 0 and $fadeOut >= 0){ - $this->networkSession->sendDataPacket(SetTitlePacket::setAnimationTimes($fadeIn, $stay, $fadeOut)); + $this->networkSession->onTitleDuration($fadeIn, $stay, $fadeOut); } } From 8ee3d4486afd3a5079595df4b4138e1e733a1c59 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 29 Nov 2019 11:56:36 +0000 Subject: [PATCH 1289/3224] update build/php submodule to pmmp/php-build-scripts@7e985c932a5e1a2c3ba22175cb1fab338facd64f --- build/php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/php b/build/php index bdcc3af3d0..7e985c932a 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit bdcc3af3d038c7ac9881f05da88ea28f19e881be +Subproject commit 7e985c932a5e1a2c3ba22175cb1fab338facd64f From 0bff5d9bffd24a12b64c546da27aa0e4aaf6f5cc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 29 Nov 2019 20:20:13 +0000 Subject: [PATCH 1290/3224] sync composer deps --- composer.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/composer.lock b/composer.lock index 57bea41721..171d363810 100644 --- a/composer.lock +++ b/composer.lock @@ -333,12 +333,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/ClassLoader.git", - "reference": "e7d1e7701374760752a23c093ba925f3a518d88d" + "reference": "f0d947debe366890206fc1d8f3fc7bef6bee6335" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/e7d1e7701374760752a23c093ba925f3a518d88d", - "reference": "e7d1e7701374760752a23c093ba925f3a518d88d", + "url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/f0d947debe366890206fc1d8f3fc7bef6bee6335", + "reference": "f0d947debe366890206fc1d8f3fc7bef6bee6335", "shasum": "" }, "require": { @@ -349,7 +349,7 @@ "type": "library", "autoload": { "classmap": [ - "./" + "./src" ] }, "license": [ @@ -360,7 +360,7 @@ "source": "https://github.com/pmmp/ClassLoader/tree/master", "issues": "https://github.com/pmmp/ClassLoader/issues" }, - "time": "2019-10-28T12:24:55+00:00" + "time": "2019-11-04T11:25:46+00:00" }, { "name": "pocketmine/log", @@ -398,12 +398,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "68009b5202142ef5e83d271aebfd4d721efdb3b9" + "reference": "45f5156bf41083523568ec08f22bd52f31dcd109" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/68009b5202142ef5e83d271aebfd4d721efdb3b9", - "reference": "68009b5202142ef5e83d271aebfd4d721efdb3b9", + "url": "https://api.github.com/repos/pmmp/Math/zipball/45f5156bf41083523568ec08f22bd52f31dcd109", + "reference": "45f5156bf41083523568ec08f22bd52f31dcd109", "shasum": "" }, "require": { @@ -429,7 +429,7 @@ "source": "https://github.com/pmmp/Math/tree/master", "issues": "https://github.com/pmmp/Math/issues" }, - "time": "2019-10-21T14:35:51+00:00" + "time": "2019-11-27T06:54:09+00:00" }, { "name": "pocketmine/nbt", From 02c1dabc3d745baa24e7e78ae9c9cc0a5a67b847 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 2 Dec 2019 19:24:00 +0000 Subject: [PATCH 1291/3224] update pocketmine/nbt dependency --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 171d363810..eda54ceca4 100644 --- a/composer.lock +++ b/composer.lock @@ -437,12 +437,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "5736b9e36283116caca51640d9e9a905155f1b7a" + "reference": "b4746c1d3c0f465dc4406754018f96b113ec4170" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/5736b9e36283116caca51640d9e9a905155f1b7a", - "reference": "5736b9e36283116caca51640d9e9a905155f1b7a", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/b4746c1d3c0f465dc4406754018f96b113ec4170", + "reference": "b4746c1d3c0f465dc4406754018f96b113ec4170", "shasum": "" }, "require": { @@ -470,7 +470,7 @@ "source": "https://github.com/pmmp/NBT/tree/master", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2019-10-21T15:06:42+00:00" + "time": "2019-11-29T21:29:01+00:00" }, { "name": "pocketmine/raklib", From e110ea5aea025ea77c09efca1951eb9667742145 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Dec 2019 11:59:28 +0000 Subject: [PATCH 1292/3224] LoginPacket: fixed param doc for validate() --- src/network/mcpe/protocol/LoginPacket.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/protocol/LoginPacket.php b/src/network/mcpe/protocol/LoginPacket.php index 0031a20ea1..86af08dbe9 100644 --- a/src/network/mcpe/protocol/LoginPacket.php +++ b/src/network/mcpe/protocol/LoginPacket.php @@ -90,7 +90,7 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ /** * @param Validator $v * @param string $name - * @param $data + * @param mixed $data * * @throws BadPacketException */ From fede6b8234b067946bcb2f3774f4b090c566ac2c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Dec 2019 12:06:57 +0000 Subject: [PATCH 1293/3224] protocol: fixed static analysis warnings in MetadataProperty::equals() implementations --- .../mcpe/protocol/types/entity/BlockPosMetadataProperty.php | 2 +- .../mcpe/protocol/types/entity/CompoundTagMetadataProperty.php | 2 +- .../mcpe/protocol/types/entity/FloatMetadataProperty.php | 2 +- .../mcpe/protocol/types/entity/IntegerishMetadataProperty.php | 2 +- .../mcpe/protocol/types/entity/StringMetadataProperty.php | 2 +- src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php b/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php index 5bf56214f1..ebf88b1103 100644 --- a/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php @@ -60,6 +60,6 @@ final class BlockPosMetadataProperty implements MetadataProperty{ } public function equals(MetadataProperty $other) : bool{ - return $other instanceof $this and $other->value->equals($this->value); + return $other instanceof self and $other->value->equals($this->value); } } diff --git a/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php b/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php index 5bd0ec22d7..705779fd88 100644 --- a/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php @@ -51,7 +51,7 @@ final class CompoundTagMetadataProperty implements MetadataProperty{ } public function equals(MetadataProperty $other) : bool{ - return $other instanceof $this and $other->value->equals($this->value); + return $other instanceof self and $other->value->equals($this->value); } public static function read(NetworkBinaryStream $in) : self{ diff --git a/src/network/mcpe/protocol/types/entity/FloatMetadataProperty.php b/src/network/mcpe/protocol/types/entity/FloatMetadataProperty.php index 6554af0a0a..faf2561118 100644 --- a/src/network/mcpe/protocol/types/entity/FloatMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/FloatMetadataProperty.php @@ -49,7 +49,7 @@ final class FloatMetadataProperty implements MetadataProperty{ } public function equals(MetadataProperty $other) : bool{ - return $other instanceof $this and $other->value === $this->value; + return $other instanceof self and $other->value === $this->value; } public static function read(NetworkBinaryStream $in) : self{ diff --git a/src/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php b/src/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php index a36f3c7dd0..dad794140d 100644 --- a/src/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php @@ -49,7 +49,7 @@ trait IntegerishMetadataProperty{ } public function equals(MetadataProperty $other) : bool{ - return $other instanceof $this and $other->value === $this->value; + return $other instanceof self and $other->value === $this->value; } public static function buildFromFlags(array $flags) : self{ diff --git a/src/network/mcpe/protocol/types/entity/StringMetadataProperty.php b/src/network/mcpe/protocol/types/entity/StringMetadataProperty.php index daf781c3c8..846410a006 100644 --- a/src/network/mcpe/protocol/types/entity/StringMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/StringMetadataProperty.php @@ -49,6 +49,6 @@ final class StringMetadataProperty implements MetadataProperty{ } public function equals(MetadataProperty $other) : bool{ - return $other instanceof $this and $other->value === $this->value; + return $other instanceof self and $other->value === $this->value; } } diff --git a/src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php b/src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php index 33fee71624..7115d42c50 100644 --- a/src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php @@ -57,6 +57,6 @@ class Vec3MetadataProperty implements MetadataProperty{ } public function equals(MetadataProperty $other) : bool{ - return $other instanceof $this and $other->value->equals($this->value); + return $other instanceof self and $other->value->equals($this->value); } } From 5f9ce78814453de92cb117d37e723e2d09ed4209 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Dec 2019 12:08:04 +0000 Subject: [PATCH 1294/3224] WorldProviderManager: removed incorrect param doc this was used to trick phpstorm, but PHPStan doesn't like it, and it isn't consistently used anyway. --- src/world/format/io/WorldProviderManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/format/io/WorldProviderManager.php b/src/world/format/io/WorldProviderManager.php index ddc92cde43..cd25847498 100644 --- a/src/world/format/io/WorldProviderManager.php +++ b/src/world/format/io/WorldProviderManager.php @@ -47,7 +47,7 @@ abstract class WorldProviderManager{ /** * Returns the default format used to generate new worlds. * - * @return string|WritableWorldProvider + * @return string */ public static function getDefault() : string{ return self::$default; From 54c2778e56d95dcb8cb35ffdba41bc7ce33267b5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Dec 2019 12:08:56 +0000 Subject: [PATCH 1295/3224] phpstan: update split configs for master branch --- tests/phpstan/configs/optional-com-dotnet.neon | 13 +++++++++++-- tests/phpstan/configs/phpstan-bugs.neon | 8 ++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/tests/phpstan/configs/optional-com-dotnet.neon b/tests/phpstan/configs/optional-com-dotnet.neon index efa2d82ab6..6d7edb2d3b 100644 --- a/tests/phpstan/configs/optional-com-dotnet.neon +++ b/tests/phpstan/configs/optional-com-dotnet.neon @@ -3,10 +3,19 @@ parameters: - message: "#^Instantiated class COM not found\\.$#" count: 2 - path: src/pocketmine/network/upnp/UPnP.php + path: src/network/upnp/UPnP.php - message: "#^Access to property \\$StaticPortMappingCollection on an unknown class COM\\.$#" count: 4 - path: src/pocketmine/network/upnp/UPnP.php + path: src/network/upnp/UPnP.php + - + message: "#^Caught class com_exception not found\\.$#" + count: 2 + path: src/network/upnp/UPnP.php + + - + message: "#^Call to method getMessage\\(\\) on an unknown class com_exception\\.$#" + count: 1 + path: src/network/upnp/UPnP.php diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 90fef5cea0..b281726585 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -2,9 +2,13 @@ parameters: ignoreErrors: - message: "#^PHPDoc tag @param has invalid value \\(.+\\)\\: Unexpected token \"&\", expected TOKEN_VARIABLE at offset \\d+$#" - path: src/pocketmine + path: src - message: "#^Default value of the parameter \\#\\d+ \\$[A-Za-z\\d_]+ \\(\\-?\\d+\\) of method .+\\(\\) is incompatible with type float\\.$#" - path: src/pocketmine + path: src + - + message: "#^Call to method count\\(\\) on an unknown class _HumbugBoxbfaeed0746fa\\\\Ds\\\\Deque\\.$#" + count: 1 + path: src/block/Banner.php From 5b91be81cc670199b5e7dad3a5fca387c58029b1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Dec 2019 12:16:10 +0000 Subject: [PATCH 1296/3224] Entity: rewrite dbbe1f2d5c04059ee9ddad12a0d33fbaea933683 for master --- src/entity/Entity.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index c053aa161e..ef32fb6da1 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1633,7 +1633,7 @@ abstract class Entity{ */ public function spawnTo(Player $player) : void{ $id = spl_object_id($player); - if(!isset($this->hasSpawned[$id])){ + if(!isset($this->hasSpawned[$id]) and $player->isUsingChunk($this->location->getFloorX() >> 4, $this->location->getFloorZ() >> 4)){ $this->hasSpawned[$id] = $player; $this->sendSpawnPacket($player); From 29ce829247192867fcac9d880c57d96f26b67395 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Dec 2019 17:45:23 +0000 Subject: [PATCH 1297/3224] fix error counts for UPnP --- tests/phpstan/configs/optional-com-dotnet.neon | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/phpstan/configs/optional-com-dotnet.neon b/tests/phpstan/configs/optional-com-dotnet.neon index 6d7edb2d3b..a666443450 100644 --- a/tests/phpstan/configs/optional-com-dotnet.neon +++ b/tests/phpstan/configs/optional-com-dotnet.neon @@ -2,12 +2,12 @@ parameters: ignoreErrors: - message: "#^Instantiated class COM not found\\.$#" - count: 2 + count: 1 path: src/network/upnp/UPnP.php - message: "#^Access to property \\$StaticPortMappingCollection on an unknown class COM\\.$#" - count: 4 + count: 2 path: src/network/upnp/UPnP.php - From f302517a2db73d3e2ad6d3b08f4969b2f4dd9ce1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Dec 2019 21:04:04 +0000 Subject: [PATCH 1298/3224] Door: fix deserialization of top flag it's not clear what bugs this caused, if any, but nonetheless it is incorrect. --- src/block/Door.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/Door.php b/src/block/Door.php index de7e120818..84f2cb1313 100644 --- a/src/block/Door.php +++ b/src/block/Door.php @@ -58,7 +58,7 @@ class Door extends Transparent{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->top = $stateMeta & BlockLegacyMetadata::DOOR_FLAG_TOP; + $this->top = ($stateMeta & BlockLegacyMetadata::DOOR_FLAG_TOP) !== 0; if($this->top){ $this->hingeRight = ($stateMeta & BlockLegacyMetadata::DOOR_TOP_FLAG_RIGHT) !== 0; $this->powered = ($stateMeta & BlockLegacyMetadata::DOOR_TOP_FLAG_POWERED) !== 0; From 66aa940ed1333cf9fa061d1f3671bd7a36385da6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 11:28:59 +0000 Subject: [PATCH 1299/3224] Item: fixed foreach doc comment in deserializeCompoundTag() detected by PHPStan 0.12.0 --- src/item/Item.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/item/Item.php b/src/item/Item.php index 3b564bb97b..1803d93f32 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -316,7 +316,7 @@ class Item implements \JsonSerializable{ $this->canPlaceOn = new Set(); $canPlaceOn = $tag->getListTag("CanPlaceOn"); if($canPlaceOn !== null){ - /** @var StringTag $tag */ + /** @var StringTag $entry */ foreach($canPlaceOn as $entry){ $this->canPlaceOn->add($entry->getValue()); } From 117e46f639911b02632e5860693b6c3648068d74 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 11:29:41 +0000 Subject: [PATCH 1300/3224] LevelDB: fix doc comment handling for deserializeLegacyExtraData() --- src/world/format/io/leveldb/LevelDB.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 329e68c8c0..0c7c06db31 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -196,6 +196,12 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ } } + /** + * @param string $index + * @param int $chunkVersion + * + * @return PalettedBlockArray[] + */ protected function deserializeLegacyExtraData(string $index, int $chunkVersion) : array{ if(($extraRawData = $this->db->get($index . self::TAG_BLOCK_EXTRA_DATA)) === false or $extraRawData === ""){ return []; @@ -263,7 +269,6 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ case 4: //MCPE 1.1 //TODO: check beds case 3: //MCPE 1.0 - /** @var PalettedBlockArray[] $convertedLegacyExtraData */ $convertedLegacyExtraData = $this->deserializeLegacyExtraData($index, $chunkVersion); for($y = 0; $y < Chunk::MAX_SUBCHUNKS; ++$y){ @@ -346,7 +351,6 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ case 2: // < MCPE 1.0 case 1: case 0: //MCPE 0.9.0.1 beta (first version) - /** @var PalettedBlockArray[] $extraDataLayers */ $convertedLegacyExtraData = $this->deserializeLegacyExtraData($index, $chunkVersion); $legacyTerrain = $this->db->get($index . self::TAG_LEGACY_TERRAIN); From c0ea8715992c53dc6748fcaeb43496c9c2c58cd7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 11:35:57 +0000 Subject: [PATCH 1301/3224] updated rules for master on PHPStan 0.12 --- phpstan.neon.dist | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index d8da5a4e37..e57353c65a 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -17,16 +17,26 @@ parameters: count: 1 path: src/PocketMine.php - - - message: "#^Cannot instantiate interface pocketmine\\\\level\\\\format\\\\io\\\\LevelProvider\\.$#" - count: 1 - path: src/pocketmine/Server.php - - message: "#^Used constant pocketmine\\\\RESOURCE_PATH not found\\.$#" count: 1 path: src/network/mcpe/protocol/StartGamePacket.php + - + message: "#^Cannot instantiate interface pocketmine\\\\world\\\\format\\\\io\\\\WorldProvider\\.$#" + count: 1 + path: src/world/WorldManager.php + + - + message: "#^Cannot instantiate interface pocketmine\\\\world\\\\format\\\\io\\\\WritableWorldProvider\\.$#" + count: 1 + path: src/world/WorldManager.php + + - + message: "#^Cannot instantiate interface pocketmine\\\\world\\\\format\\\\io\\\\WritableWorldProvider\\.$#" + count: 2 + path: src/world/format/io/FormatConverter.php + - message: "#^Constant pocketmine\\\\COMPOSER_AUTOLOADER_PATH not found\\.$#" path: src From 850dbb38c6ec758c5700c01c34568f867a9a7106 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 11:38:01 +0000 Subject: [PATCH 1302/3224] phpstan-bugs: remove false positive that is fixed in 0.12.0 --- tests/phpstan/configs/phpstan-bugs.neon | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 0366bd6a56..89defd52a9 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -8,7 +8,3 @@ parameters: message: "#^Default value of the parameter \\#\\d+ \\$[A-Za-z\\d_]+ \\(\\-?\\d+\\) of method .+\\(\\) is incompatible with type float\\.$#" path: ../../../src - - - message: "#^Call to method count\\(\\) on an unknown class _HumbugBoxbfaeed0746fa\\\\Ds\\\\Deque\\.$#" - count: 1 - path: src/block/Banner.php From e35a92d8e8605765afcb056876033665d518d9be Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 18:25:08 +0000 Subject: [PATCH 1303/3224] tile\Banner: fixed bad default value for patterns field detected by PHPStan on level 3 --- src/block/tile/Banner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/tile/Banner.php b/src/block/tile/Banner.php index 2c37928702..aed147de49 100644 --- a/src/block/tile/Banner.php +++ b/src/block/tile/Banner.php @@ -47,7 +47,7 @@ class Banner extends Spawnable{ private $baseColor; /** @var BannerPattern[]|Deque */ - private $patterns = []; + private $patterns; public function __construct(World $world, Vector3 $pos){ $this->baseColor = DyeColor::BLACK(); From 60154d81278533bde2f2bc6b8232ec06b5cda424 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 18:26:18 +0000 Subject: [PATCH 1304/3224] SubChunkIteratorManager: assert type of subchunk to make PHPStan happy we know this should be a SubChunk, even though it doesn't. --- src/world/utils/SubChunkIteratorManager.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/world/utils/SubChunkIteratorManager.php b/src/world/utils/SubChunkIteratorManager.php index 6a54ccb8dc..c791996589 100644 --- a/src/world/utils/SubChunkIteratorManager.php +++ b/src/world/utils/SubChunkIteratorManager.php @@ -71,7 +71,9 @@ class SubChunkIteratorManager{ return false; } - $this->currentSubChunk = $this->currentChunk->getSubChunk($y >> 4); + $newSubChunk = $this->currentChunk->getSubChunk($y >> 4); + assert($newSubChunk instanceof SubChunk, "chunk inside valid bounds should always be a SubChunk instance"); + $this->currentSubChunk = $newSubChunk; if($this->onSubChunkChangeFunc !== null){ ($this->onSubChunkChangeFunc)(); } From 2ff25dfbd266d4f23541c06199c57fdeafb1e064 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 18:39:14 +0000 Subject: [PATCH 1305/3224] Color: make mix() first parameter mandatory, closes #3204 --- changelogs/4.0-snapshot.md | 1 + src/utils/Color.php | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 6aa84f48c8..ffac9f1389 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -769,6 +769,7 @@ This version features substantial changes to the network system, improving coher - `Utils::$online` - `Utils::$os` - The following API methods have signature changes: + - `Color::mix()` now requires the first parameter. Previously, it was possible to pass zero arguments, which would raise an `ArgumentCountError` (not static analysis friendly). - `Internet::simpleCurl()` now requires a `Closure` for its `onSuccess` parameter instead of `callable`. - The following API methods have been removed: - `Color->setA()` diff --git a/src/utils/Color.php b/src/utils/Color.php index 833f158948..12d679a498 100644 --- a/src/utils/Color.php +++ b/src/utils/Color.php @@ -79,15 +79,14 @@ final class Color{ /** * Mixes the supplied list of colours together to produce a result colour. * + * @param Color $color1 * @param Color ...$colors * * @return Color */ - public static function mix(Color ...$colors) : Color{ + public static function mix(Color $color1, Color ...$colors) : Color{ + $colors[] = $color1; $count = count($colors); - if($count < 1){ - throw new \ArgumentCountError("No colors given"); - } $a = $r = $g = $b = 0; From b43bd5fb672c832c209e19686cf2e84a5a95e36d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 19:14:45 +0000 Subject: [PATCH 1306/3224] PluginCommand: separate CommandExecutor param looking at the code now it's clear that this class combines two jobs into the same class. closes #3203 --- src/command/PluginCommand.php | 9 +++++---- src/plugin/PluginBase.php | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/command/PluginCommand.php b/src/command/PluginCommand.php index 4c7757b590..a6cce85551 100644 --- a/src/command/PluginCommand.php +++ b/src/command/PluginCommand.php @@ -35,13 +35,14 @@ class PluginCommand extends Command implements PluginIdentifiableCommand{ private $executor; /** - * @param string $name - * @param Plugin $owner + * @param string $name + * @param Plugin $owner + * @param CommandExecutor $executor */ - public function __construct(string $name, Plugin $owner){ + public function __construct(string $name, Plugin $owner, CommandExecutor $executor){ parent::__construct($name); $this->owningPlugin = $owner; - $this->executor = $owner; + $this->executor = $executor; $this->usageMessage = ""; } diff --git a/src/plugin/PluginBase.php b/src/plugin/PluginBase.php index a3a16f3d36..eb1f56a809 100644 --- a/src/plugin/PluginBase.php +++ b/src/plugin/PluginBase.php @@ -181,7 +181,7 @@ abstract class PluginBase implements Plugin, CommandExecutor{ continue; } if(is_array($data)){ //TODO: error out if it isn't - $newCmd = new PluginCommand($key, $this); + $newCmd = new PluginCommand($key, $this, $this); if(isset($data["description"])){ $newCmd->setDescription($data["description"]); } From 908aa20effef1920b33044888127b1b2db9025fa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 22:49:25 +0000 Subject: [PATCH 1307/3224] EntityFactory: fixed type doc of knownEntities --- src/entity/EntityFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index b4b17fafb0..8290f45159 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -64,7 +64,7 @@ final class EntityFactory{ private static $entityCount = 1; /** @var string[] base class => currently used class for construction */ private static $classMapping = []; - /** @var Entity[] */ + /** @var string[] */ private static $knownEntities = []; /** @var string[][] */ private static $saveNames = []; From fb78ec1f62ec29f537c7f11bdfbbb74260c196b1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 22:50:30 +0000 Subject: [PATCH 1308/3224] AsyncTask: mark threadLocalStorage static field as nullable --- src/scheduler/AsyncTask.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scheduler/AsyncTask.php b/src/scheduler/AsyncTask.php index 3ba47f3cb1..98f4d2a384 100644 --- a/src/scheduler/AsyncTask.php +++ b/src/scheduler/AsyncTask.php @@ -47,7 +47,7 @@ use function unserialize; */ abstract class AsyncTask extends \Threaded{ /** - * @var \ArrayObject|mixed[] object hash => mixed data + * @var \ArrayObject|mixed[]|null object hash => mixed data * * Used to store objects which are only needed on one thread and should not be serialized. */ From 59793d4b68c021a87cff996f40d02fa011944915 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 22:54:04 +0000 Subject: [PATCH 1309/3224] Player: mark networkSession field as nullable while we do null this to break cycles, we also null it for other purposes, and it's null-checked in a few places. --- src/player/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index 7adac45d1a..a10c280696 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -151,7 +151,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $lname !== "rcon" and $lname !== "console" and $len >= 1 and $len <= 16 and preg_match("/[^A-Za-z0-9_ ]/", $name) === 0; } - /** @var NetworkSession */ + /** @var NetworkSession|null */ protected $networkSession; /** @var bool */ From 48e2473696d0febf5662ca11d3184afa5e6014e1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 22:58:55 +0000 Subject: [PATCH 1310/3224] Position: mark world field as nullable (equivalent to 39c607cbd5e134a47fa338628d54eea4e45d6bc3) --- src/world/Position.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/Position.php b/src/world/Position.php index 58c8fbcf24..736cd87b9f 100644 --- a/src/world/Position.php +++ b/src/world/Position.php @@ -28,7 +28,7 @@ use function assert; class Position extends Vector3{ - /** @var World */ + /** @var World|null */ public $world = null; /** From 7d89f91feaa46904aa14c90bb8520a5879577bd2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Dec 2019 23:21:01 +0000 Subject: [PATCH 1311/3224] Leaves: fixed decay detected by phpstan level 4 --- src/block/Leaves.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/Leaves.php b/src/block/Leaves.php index f57ea1e74e..6b1edc9241 100644 --- a/src/block/Leaves.php +++ b/src/block/Leaves.php @@ -76,7 +76,7 @@ class Leaves extends Transparent{ $visited[$index] = true; $block = $this->pos->getWorld()->getBlock($pos); - if($pos instanceof Wood){ //type doesn't matter + if($block instanceof Wood){ //type doesn't matter return true; } From ff5aedaf6b6b28684717fbffe20fd77503bb636e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 5 Dec 2019 14:35:02 +0000 Subject: [PATCH 1312/3224] master: green on phpstan level 3 --- phpstan.neon.dist | 24 +++----- tests/phpstan/configs/gc-hacks.neon | 79 ++++++++++++------------- tests/phpstan/configs/phpstan-bugs.neon | 20 ++++++- 3 files changed, 63 insertions(+), 60 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 87103270c4..9a0dfa2584 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -24,50 +24,40 @@ parameters: path: src/command/defaults/TeleportCommand.php # comment: "not actually possible, but high cost to fix warning" - - - message: "#^Array \\(array\\\\) does not accept pocketmine\\\\entity\\\\Entity\\.$#" - count: 2 - path: src/pocketmine/entity/Entity.php - - - - message: "#^Invalid array key type pocketmine\\\\entity\\\\Entity\\.$#" - count: 1 - path: src/pocketmine/entity/Entity.php - - message: "#^Method pocketmine\\\\event\\\\entity\\\\EntityDeathEvent\\:\\:getEntity\\(\\) should return pocketmine\\\\entity\\\\Living but returns pocketmine\\\\entity\\\\Entity\\.$#" count: 1 - path: src/pocketmine/event/entity/EntityDeathEvent.php + path: src/event/entity/EntityDeathEvent.php - message: "#^Method pocketmine\\\\event\\\\entity\\\\EntityShootBowEvent\\:\\:getEntity\\(\\) should return pocketmine\\\\entity\\\\Living but returns pocketmine\\\\entity\\\\Entity\\.$#" count: 1 - path: src/pocketmine/event/entity/EntityShootBowEvent.php + path: src/event/entity/EntityShootBowEvent.php - message: "#^Property pocketmine\\\\event\\\\entity\\\\EntityShootBowEvent\\:\\:\\$projectile \\(pocketmine\\\\entity\\\\projectile\\\\Projectile\\) does not accept pocketmine\\\\entity\\\\Entity\\.$#" count: 1 - path: src/pocketmine/event/entity/EntityShootBowEvent.php + path: src/event/entity/EntityShootBowEvent.php - message: "#^Method pocketmine\\\\event\\\\entity\\\\ItemDespawnEvent\\:\\:getEntity\\(\\) should return pocketmine\\\\entity\\\\object\\\\ItemEntity but returns pocketmine\\\\entity\\\\Entity\\.$#" count: 1 - path: src/pocketmine/event/entity/ItemDespawnEvent.php + path: src/event/entity/ItemDespawnEvent.php - message: "#^Method pocketmine\\\\event\\\\entity\\\\ItemSpawnEvent\\:\\:getEntity\\(\\) should return pocketmine\\\\entity\\\\object\\\\ItemEntity but returns pocketmine\\\\entity\\\\Entity\\.$#" count: 1 - path: src/pocketmine/event/entity/ItemSpawnEvent.php + path: src/event/entity/ItemSpawnEvent.php - message: "#^Method pocketmine\\\\event\\\\entity\\\\ProjectileHitEvent\\:\\:getEntity\\(\\) should return pocketmine\\\\entity\\\\projectile\\\\Projectile but returns pocketmine\\\\entity\\\\Entity\\.$#" count: 1 - path: src/pocketmine/event/entity/ProjectileHitEvent.php + path: src/event/entity/ProjectileHitEvent.php - message: "#^Method pocketmine\\\\event\\\\entity\\\\ProjectileLaunchEvent\\:\\:getEntity\\(\\) should return pocketmine\\\\entity\\\\projectile\\\\Projectile but returns pocketmine\\\\entity\\\\Entity\\.$#" count: 1 - path: src/pocketmine/event/entity/ProjectileLaunchEvent.php + path: src/event/entity/ProjectileLaunchEvent.php - message: "#^Used constant pocketmine\\\\RESOURCE_PATH not found\\.$#" diff --git a/tests/phpstan/configs/gc-hacks.neon b/tests/phpstan/configs/gc-hacks.neon index 14267631dc..331553ce03 100644 --- a/tests/phpstan/configs/gc-hacks.neon +++ b/tests/phpstan/configs/gc-hacks.neon @@ -4,77 +4,76 @@ parameters: ignoreErrors: - - message: "#^Property pocketmine\\\\Player\\:\\:\\$sessionAdapter \\(pocketmine\\\\network\\\\mcpe\\\\PlayerNetworkSessionAdapter\\) does not accept null\\.$#" + message: "#^Property pocketmine\\\\block\\\\tile\\\\BrewingStand\\:\\:\\$inventory \\(pocketmine\\\\inventory\\\\BrewingStandInventory\\) does not accept null\\.$#" count: 1 - path: ../../../src/pocketmine/Player.php + path: ../../../src/block/tile/BrewingStand.php - - message: "#^Property pocketmine\\\\Player\\:\\:\\$cursorInventory \\(pocketmine\\\\inventory\\\\PlayerCursorInventory\\) does not accept null\\.$#" + message: "#^Property pocketmine\\\\block\\\\tile\\\\Chest\\:\\:\\$inventory \\(pocketmine\\\\inventory\\\\ChestInventory\\) does not accept null\\.$#" count: 1 - path: ../../../src/pocketmine/Player.php + path: ../../../src/block/tile/Chest.php - - message: "#^Property pocketmine\\\\Player\\:\\:\\$craftingGrid \\(pocketmine\\\\inventory\\\\CraftingGrid\\) does not accept null\\.$#" + message: "#^Property pocketmine\\\\block\\\\tile\\\\Furnace\\:\\:\\$inventory \\(pocketmine\\\\inventory\\\\FurnaceInventory\\) does not accept null\\.$#" count: 1 - path: ../../../src/pocketmine/Player.php + path: ../../../src/block/tile/Furnace.php - - message: "#^Property pocketmine\\\\Player\\:\\:\\$perm \\(pocketmine\\\\permission\\\\PermissibleBase\\) does not accept null\\.$#" + message: "#^Property pocketmine\\\\block\\\\tile\\\\Hopper\\:\\:\\$inventory \\(pocketmine\\\\inventory\\\\HopperInventory\\) does not accept null\\.$#" count: 1 - path: ../../../src/pocketmine/Player.php + path: ../../../src/block/tile/Hopper.php - - message: "#^Property pocketmine\\\\entity\\\\Entity\\:\\:\\$namedtag \\(pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\) does not accept null\\.$#" + message: "#^Property pocketmine\\\\player\\\\Player\\:\\:\\$cursorInventory \\(pocketmine\\\\inventory\\\\PlayerCursorInventory\\) does not accept null\\.$#" count: 1 - path: ../../../src/pocketmine/entity/Entity.php + path: ../../../src/player/Player.php + + - + message: "#^Property pocketmine\\\\player\\\\Player\\:\\:\\$craftingGrid \\(pocketmine\\\\crafting\\\\CraftingGrid\\) does not accept null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Property pocketmine\\\\player\\\\Player\\:\\:\\$perm \\(pocketmine\\\\permission\\\\PermissibleBase\\) does not accept null\\.$#" + count: 1 + path: ../../../src/player/Player.php - message: "#^Property pocketmine\\\\entity\\\\Human\\:\\:\\$inventory \\(pocketmine\\\\inventory\\\\PlayerInventory\\) does not accept null\\.$#" count: 1 - path: ../../../src/pocketmine/entity/Human.php + path: ../../../src/entity/Human.php - message: "#^Property pocketmine\\\\entity\\\\Human\\:\\:\\$enderChestInventory \\(pocketmine\\\\inventory\\\\EnderChestInventory\\) does not accept null\\.$#" count: 1 - path: ../../../src/pocketmine/entity/Human.php + path: ../../../src/entity/Human.php + + - + message: "#^Property pocketmine\\\\entity\\\\Human\\:\\:\\$hungerManager \\(pocketmine\\\\entity\\\\HungerManager\\) does not accept null\\.$#" + count: 1 + path: ../../../src/entity/Human.php + + - + message: "#^Property pocketmine\\\\entity\\\\Human\\:\\:\\$xpManager \\(pocketmine\\\\entity\\\\ExperienceManager\\) does not accept null\\.$#" + count: 1 + path: ../../../src/entity/Human.php - message: "#^Property pocketmine\\\\entity\\\\Living\\:\\:\\$armorInventory \\(pocketmine\\\\inventory\\\\ArmorInventory\\) does not accept null\\.$#" count: 1 - path: ../../../src/pocketmine/entity/Living.php + path: ../../../src/entity/Living.php - - message: "#^Property pocketmine\\\\inventory\\\\DoubleChestInventory\\:\\:\\$left \\(pocketmine\\\\inventory\\\\ChestInventory\\) does not accept null\\.$#" + message: "#^Property pocketmine\\\\entity\\\\Living\\:\\:\\$effectManager \\(pocketmine\\\\entity\\\\effect\\\\EffectManager\\) does not accept null\\.$#" count: 1 - path: ../../../src/pocketmine/inventory/DoubleChestInventory.php + path: ../../../src/entity/Living.php - - message: "#^Property pocketmine\\\\inventory\\\\DoubleChestInventory\\:\\:\\$right \\(pocketmine\\\\inventory\\\\ChestInventory\\) does not accept null\\.$#" + message: "#^Property pocketmine\\\\world\\\\World\\:\\:\\$provider \\(pocketmine\\\\world\\\\format\\\\io\\\\WritableWorldProvider\\) does not accept null\\.$#" count: 1 - path: ../../../src/pocketmine/inventory/DoubleChestInventory.php + path: ../../../src/world/World.php - - message: "#^Property pocketmine\\\\level\\\\Level\\:\\:\\$provider \\(pocketmine\\\\level\\\\format\\\\io\\\\LevelProvider\\) does not accept null\\.$#" + message: "#^Property pocketmine\\\\world\\\\World\\:\\:\\$temporalPosition \\(pocketmine\\\\world\\\\Position\\) does not accept null\\.$#" count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Property pocketmine\\\\level\\\\Level\\:\\:\\$blockMetadata \\(pocketmine\\\\metadata\\\\BlockMetadataStore\\) does not accept null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Property pocketmine\\\\level\\\\Level\\:\\:\\$temporalPosition \\(pocketmine\\\\level\\\\Position\\) does not accept null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Property pocketmine\\\\tile\\\\Chest\\:\\:\\$inventory \\(pocketmine\\\\inventory\\\\ChestInventory\\) does not accept null\\.$#" - count: 1 - path: ../../../src/pocketmine/tile/Chest.php - - - - message: "#^Property pocketmine\\\\tile\\\\Furnace\\:\\:\\$inventory \\(pocketmine\\\\inventory\\\\FurnaceInventory\\) does not accept null\\.$#" - count: 1 - path: ../../../src/pocketmine/tile/Furnace.php - + path: ../../../src/world/World.php diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 696fcc8ab1..16b88cb201 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -19,15 +19,29 @@ parameters: - message: "#^Offset string does not exist on array\\(\\)\\.$#" count: 3 - path: ../../../src/pocketmine/MemoryManager.php + path: ../../../src/MemoryManager.php - message: "#^Offset \\(int\\|string\\) does not exist on array\\(\\)\\.$#" count: 1 - path: ../../../src/pocketmine/MemoryManager.php + path: ../../../src/MemoryManager.php + + - + message: "#^Cannot access an offset on Ds\\\\Deque&iterable\\\\.$#" + count: 1 + path: ../../../src/block/tile/Banner.php + + - + message: "#^Cannot access offset int on Ds\\\\Deque&iterable\\\\.$#" + count: 2 + path: ../../../src/item/WritableBookBase.php - message: "#^Array \\(array\\) does not accept key int\\.$#" count: 1 - path: ../../../src/pocketmine/plugin/PluginDescription.php + path: ../../../src/plugin/PluginDescription.php + - + message: "#^Array \\(array\\) does not accept key int\\.$#" + count: 1 + path: ../../../src/world/format/SubChunk.php From af6cb605c5d5399f31061fecbe9c809a43622e8e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 8 Dec 2019 11:02:40 +0000 Subject: [PATCH 1313/3224] Chunk: fix data loss caused by d3d7709ead3203c189f2ac3b79224b3e5e2bf902 --- src/world/format/Chunk.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 63a92c27ce..b91263130d 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -546,7 +546,7 @@ class Chunk{ * @param World $world */ public function initChunk(World $world) : void{ - if(!empty($this->NBTentities)){ + if($this->NBTentities !== null){ $this->dirtyFlags |= self::DIRTY_FLAG_ENTITIES; $world->timings->syncChunkLoadEntitiesTimer->startTiming(); foreach($this->NBTentities as $nbt){ @@ -564,10 +564,10 @@ class Chunk{ } } - $this->NBTentities = []; + $this->NBTentities = null; $world->timings->syncChunkLoadEntitiesTimer->stopTiming(); } - if(!empty($this->NBTtiles)){ + if($this->NBTtiles !== null){ $this->dirtyFlags |= self::DIRTY_FLAG_TILES; $world->timings->syncChunkLoadTileEntitiesTimer->startTiming(); foreach($this->NBTtiles as $nbt){ @@ -581,7 +581,7 @@ class Chunk{ } } - $this->NBTtiles = []; + $this->NBTtiles = null; $world->timings->syncChunkLoadTileEntitiesTimer->stopTiming(); } } From 6b21f160bd3a97300935be8499e6739eacbd1ce1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 8 Dec 2019 11:07:14 +0000 Subject: [PATCH 1314/3224] Chunk: fix type docs for NBTentities and NBTtiles --- src/world/format/Chunk.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index b91263130d..fad5d13937 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -83,10 +83,10 @@ class Chunk{ /** @var string */ protected $biomeIds; - /** @var CompoundTag[] */ + /** @var CompoundTag[]|null */ protected $NBTtiles = []; - /** @var CompoundTag[] */ + /** @var CompoundTag[]|null */ protected $NBTentities = []; /** From 705228f42762b34e2a9e506fe9ee3cd242bf03df Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 8 Dec 2019 11:08:07 +0000 Subject: [PATCH 1315/3224] Chunk: remove useless field defaults --- src/world/format/Chunk.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index fad5d13937..7733fd36f6 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -84,10 +84,10 @@ class Chunk{ protected $biomeIds; /** @var CompoundTag[]|null */ - protected $NBTtiles = []; + protected $NBTtiles; /** @var CompoundTag[]|null */ - protected $NBTentities = []; + protected $NBTentities; /** * @param int $chunkX From 3fa628f259b95299db7c92981b6b7bd1e2f76f51 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 9 Dec 2019 11:26:43 +0000 Subject: [PATCH 1316/3224] updated NBT dependency --- composer.lock | 8 ++++---- src/Server.php | 2 +- src/network/mcpe/handler/InGamePacketHandler.php | 2 +- src/network/mcpe/serializer/NetworkBinaryStream.php | 2 +- src/world/format/io/data/BedrockWorldData.php | 2 +- src/world/format/io/data/JavaWorldData.php | 2 +- src/world/format/io/leveldb/LevelDB.php | 6 +++--- src/world/format/io/region/LegacyAnvilChunkTrait.php | 2 +- src/world/format/io/region/McRegion.php | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/composer.lock b/composer.lock index eda54ceca4..77276aac68 100644 --- a/composer.lock +++ b/composer.lock @@ -437,12 +437,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "b4746c1d3c0f465dc4406754018f96b113ec4170" + "reference": "221212bd1991430a74374295261795a9a13875bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/b4746c1d3c0f465dc4406754018f96b113ec4170", - "reference": "b4746c1d3c0f465dc4406754018f96b113ec4170", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/221212bd1991430a74374295261795a9a13875bb", + "reference": "221212bd1991430a74374295261795a9a13875bb", "shasum": "" }, "require": { @@ -470,7 +470,7 @@ "source": "https://github.com/pmmp/NBT/tree/master", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2019-11-29T21:29:01+00:00" + "time": "2019-12-09T11:21:10+00:00" }, { "name": "pocketmine/raklib", diff --git a/src/Server.php b/src/Server.php index 0cdb5ec8c2..bb0f07ee94 100644 --- a/src/Server.php +++ b/src/Server.php @@ -614,7 +614,7 @@ class Server{ if(file_exists($path . "$name.dat")){ try{ - return (new BigEndianNbtSerializer())->readCompressed(file_get_contents($path . "$name.dat"))->getTag(); + return (new BigEndianNbtSerializer())->readCompressed(file_get_contents($path . "$name.dat"))->mustGetCompoundTag(); }catch(NbtDataException $e){ //zlib decode error / corrupt data rename($path . "$name.dat", $path . "$name.dat.bak"); $this->logger->error($this->getLanguage()->translateString("pocketmine.data.playerCorrupted", [$name])); diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index f45cdab1e4..a69d3f7bff 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -518,7 +518,7 @@ class InGamePacketHandler extends PacketHandler{ $block = $this->player->getLocation()->getWorld()->getBlock($pos); try{ $offset = 0; - $nbt = (new NetworkNbtSerializer())->read($packet->namedtag, $offset, 512)->getTag(); + $nbt = (new NetworkNbtSerializer())->read($packet->namedtag, $offset, 512)->mustGetCompoundTag(); }catch(NbtDataException $e){ throw new BadPacketException($e->getMessage(), 0, $e); } diff --git a/src/network/mcpe/serializer/NetworkBinaryStream.php b/src/network/mcpe/serializer/NetworkBinaryStream.php index 27b4c51534..aca0d1b75d 100644 --- a/src/network/mcpe/serializer/NetworkBinaryStream.php +++ b/src/network/mcpe/serializer/NetworkBinaryStream.php @@ -120,7 +120,7 @@ class NetworkBinaryStream extends BinaryStream{ throw new BadPacketException("Unexpected NBT count $c"); } try{ - $compound = (new NetworkNbtSerializer())->read($this->buffer, $this->offset, 512)->getTag(); + $compound = (new NetworkNbtSerializer())->read($this->buffer, $this->offset, 512)->mustGetCompoundTag(); }catch(NbtDataException $e){ throw new BadPacketException($e->getMessage(), 0, $e); } diff --git a/src/world/format/io/data/BedrockWorldData.php b/src/world/format/io/data/BedrockWorldData.php index 6e04c434d4..a20dd2cc44 100644 --- a/src/world/format/io/data/BedrockWorldData.php +++ b/src/world/format/io/data/BedrockWorldData.php @@ -108,7 +108,7 @@ class BedrockWorldData extends BaseNbtWorldData{ protected function load() : CompoundTag{ $nbt = new LittleEndianNbtSerializer(); try{ - $worldData = $nbt->read(substr(file_get_contents($this->dataPath), 8))->getTag(); + $worldData = $nbt->read(substr(file_get_contents($this->dataPath), 8))->mustGetCompoundTag(); }catch(NbtDataException $e){ throw new CorruptedWorldException($e->getMessage(), 0, $e); } diff --git a/src/world/format/io/data/JavaWorldData.php b/src/world/format/io/data/JavaWorldData.php index 2b142a6484..f3b509604a 100644 --- a/src/world/format/io/data/JavaWorldData.php +++ b/src/world/format/io/data/JavaWorldData.php @@ -72,7 +72,7 @@ class JavaWorldData extends BaseNbtWorldData{ protected function load() : CompoundTag{ $nbt = new BigEndianNbtSerializer(); try{ - $worldData = $nbt->readCompressed(file_get_contents($this->dataPath))->getTag(); + $worldData = $nbt->readCompressed(file_get_contents($this->dataPath))->mustGetCompoundTag(); }catch(NbtDataException $e){ throw new CorruptedWorldException($e->getMessage(), 0, $e); } diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 0c7c06db31..96690ae0d8 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -172,7 +172,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $palette = []; for($i = 0, $paletteSize = $stream->getLInt(); $i < $paletteSize; ++$i){ $offset = $stream->getOffset(); - $tag = $nbt->read($stream->getBuffer(), $offset)->getTag(); + $tag = $nbt->read($stream->getBuffer(), $offset)->mustGetCompoundTag(); $stream->setOffset($offset); $id = $stringToLegacyId[$tag->getString("name")] ?? BlockLegacyIds::INFO_UPDATE; @@ -392,7 +392,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $entities = []; if(($entityData = $this->db->get($index . self::TAG_ENTITY)) !== false and $entityData !== ""){ try{ - $entities = array_map(function(TreeRoot $root) : CompoundTag{ return $root->getTag(); }, $nbt->readMultiple($entityData)); + $entities = array_map(function(TreeRoot $root) : CompoundTag{ return $root->mustGetCompoundTag(); }, $nbt->readMultiple($entityData)); }catch(NbtDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } @@ -402,7 +402,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $tiles = []; if(($tileData = $this->db->get($index . self::TAG_BLOCK_ENTITY)) !== false and $tileData !== ""){ try{ - $tiles = array_map(function(TreeRoot $root) : CompoundTag{ return $root->getTag(); }, $nbt->readMultiple($tileData)); + $tiles = array_map(function(TreeRoot $root) : CompoundTag{ return $root->mustGetCompoundTag(); }, $nbt->readMultiple($tileData)); }catch(NbtDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } diff --git a/src/world/format/io/region/LegacyAnvilChunkTrait.php b/src/world/format/io/region/LegacyAnvilChunkTrait.php index 18ae27719d..0266c0bb12 100644 --- a/src/world/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/world/format/io/region/LegacyAnvilChunkTrait.php @@ -57,7 +57,7 @@ trait LegacyAnvilChunkTrait{ protected function deserializeChunk(string $data) : Chunk{ $nbt = new BigEndianNbtSerializer(); try{ - $chunk = $nbt->readCompressed($data)->getTag(); + $chunk = $nbt->readCompressed($data)->mustGetCompoundTag(); }catch(NbtDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } diff --git a/src/world/format/io/region/McRegion.php b/src/world/format/io/region/McRegion.php index a695a3372c..34e18cfada 100644 --- a/src/world/format/io/region/McRegion.php +++ b/src/world/format/io/region/McRegion.php @@ -57,7 +57,7 @@ class McRegion extends RegionWorldProvider{ protected function deserializeChunk(string $data) : Chunk{ $nbt = new BigEndianNbtSerializer(); try{ - $chunk = $nbt->readCompressed($data)->getTag(); + $chunk = $nbt->readCompressed($data)->mustGetCompoundTag(); }catch(NbtDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } From 97866cd8f6ecad0cdd8eb798eea43a3dcdea7f30 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 9 Dec 2019 11:27:00 +0000 Subject: [PATCH 1317/3224] updated RakLib dependency --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 77276aac68..e31a9fd629 100644 --- a/composer.lock +++ b/composer.lock @@ -478,12 +478,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "cf55a18aebd149c6ca23b0643ad2f5a6e48a05cf" + "reference": "d14954442c6fce65d55b97b4bef5b793852333f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/cf55a18aebd149c6ca23b0643ad2f5a6e48a05cf", - "reference": "cf55a18aebd149c6ca23b0643ad2f5a6e48a05cf", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/d14954442c6fce65d55b97b4bef5b793852333f1", + "reference": "d14954442c6fce65d55b97b4bef5b793852333f1", "shasum": "" }, "require": { @@ -512,7 +512,7 @@ "source": "https://github.com/pmmp/RakLib/tree/master", "issues": "https://github.com/pmmp/RakLib/issues" }, - "time": "2019-10-24T18:35:05+00:00" + "time": "2019-12-07T13:52:52+00:00" }, { "name": "pocketmine/snooze", From 0e1321933fb730d76d1defc00d3a4c6e03cbfee6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 10 Dec 2019 10:41:36 +0000 Subject: [PATCH 1318/3224] ScriptCustomEventPacket: added missing interfaces --- src/network/mcpe/protocol/ScriptCustomEventPacket.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/protocol/ScriptCustomEventPacket.php b/src/network/mcpe/protocol/ScriptCustomEventPacket.php index 999dad4f9f..ad5946f1bd 100644 --- a/src/network/mcpe/protocol/ScriptCustomEventPacket.php +++ b/src/network/mcpe/protocol/ScriptCustomEventPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; -class ScriptCustomEventPacket extends DataPacket{ //TODO: this doesn't have handlers in either client or server in the game as of 1.8 +class ScriptCustomEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SCRIPT_CUSTOM_EVENT_PACKET; /** @var string */ From 4651bcf8c3b9679cebe8ca949bb35ad64ec6f64e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 11 Dec 2019 23:23:03 +0000 Subject: [PATCH 1319/3224] master: imports cleanup it was easier to make an empty merge and re-run php-cs-fixer afterwards. --- src/Server.php | 1 + src/network/mcpe/auth/ProcessLoginTask.php | 1 + src/network/mcpe/encryption/PrepareEncryptionTask.php | 2 ++ src/network/mcpe/handler/InGamePacketHandler.php | 2 +- src/network/mcpe/protocol/AvailableCommandsPacket.php | 1 + src/network/mcpe/protocol/StartGamePacket.php | 2 +- src/network/mcpe/protocol/types/LegacySkinAdapter.php | 4 ++++ src/network/mcpe/protocol/types/SkinImage.php | 2 ++ src/network/mcpe/serializer/NetworkBinaryStream.php | 2 +- src/permission/PermissionParser.php | 5 +++++ src/plugin/PluginDescription.php | 1 + src/plugin/PluginManager.php | 1 + src/resourcepacks/ZippedResourcePack.php | 1 + src/utils/Process.php | 1 + src/utils/Utils.php | 1 + src/world/utils/SubChunkIteratorManager.php | 1 + 16 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/Server.php b/src/Server.php index bb0f07ee94..7e22fd8e21 100644 --- a/src/Server.php +++ b/src/Server.php @@ -103,6 +103,7 @@ use function array_key_exists; use function array_shift; use function array_sum; use function base64_encode; +use function cli_set_process_title; use function copy; use function count; use function define; diff --git a/src/network/mcpe/auth/ProcessLoginTask.php b/src/network/mcpe/auth/ProcessLoginTask.php index 2d9d627c7b..1cf855d2f5 100644 --- a/src/network/mcpe/auth/ProcessLoginTask.php +++ b/src/network/mcpe/auth/ProcessLoginTask.php @@ -41,6 +41,7 @@ use function openssl_verify; use function str_repeat; use function str_split; use function strlen; +use function strtr; use function time; use const OPENSSL_ALGO_SHA384; diff --git a/src/network/mcpe/encryption/PrepareEncryptionTask.php b/src/network/mcpe/encryption/PrepareEncryptionTask.php index e897bd6fb1..05a3b16234 100644 --- a/src/network/mcpe/encryption/PrepareEncryptionTask.php +++ b/src/network/mcpe/encryption/PrepareEncryptionTask.php @@ -38,8 +38,10 @@ use function hex2bin; use function json_encode; use function openssl_digest; use function openssl_sign; +use function random_bytes; use function rtrim; use function str_pad; +use function strtr; use const OPENSSL_ALGO_SHA384; use const STR_PAD_LEFT; diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index e02f7b27c9..ffffc526dc 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -75,7 +75,6 @@ use pocketmine\network\mcpe\protocol\ShowCreditsPacket; use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket; use pocketmine\network\mcpe\protocol\SubClientLoginPacket; use pocketmine\network\mcpe\protocol\TextPacket; -use pocketmine\network\mcpe\protocol\types\SkinAdapterSingleton; use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; use pocketmine\network\mcpe\protocol\types\inventory\MismatchTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\NetworkInventoryAction; @@ -83,6 +82,7 @@ use pocketmine\network\mcpe\protocol\types\inventory\NormalTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\UseItemOnEntityTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\UseItemTransactionData; +use pocketmine\network\mcpe\protocol\types\SkinAdapterSingleton; use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; use pocketmine\player\Player; use function array_push; diff --git a/src/network/mcpe/protocol/AvailableCommandsPacket.php b/src/network/mcpe/protocol/AvailableCommandsPacket.php index a0456e30e9..5705fee0ea 100644 --- a/src/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/network/mcpe/protocol/AvailableCommandsPacket.php @@ -32,6 +32,7 @@ use pocketmine\network\mcpe\protocol\types\command\CommandEnum; use pocketmine\network\mcpe\protocol\types\command\CommandEnumConstraint; use pocketmine\network\mcpe\protocol\types\command\CommandParameter; use pocketmine\utils\BinaryDataException; +use function array_search; use function count; use function dechex; diff --git a/src/network/mcpe/protocol/StartGamePacket.php b/src/network/mcpe/protocol/StartGamePacket.php index a77c465567..8e95ad56e3 100644 --- a/src/network/mcpe/protocol/StartGamePacket.php +++ b/src/network/mcpe/protocol/StartGamePacket.php @@ -27,8 +27,8 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; -use pocketmine\nbt\TreeRoot; use pocketmine\nbt\tag\ListTag; +use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; diff --git a/src/network/mcpe/protocol/types/LegacySkinAdapter.php b/src/network/mcpe/protocol/types/LegacySkinAdapter.php index 639e1adcf4..e36a9493b9 100644 --- a/src/network/mcpe/protocol/types/LegacySkinAdapter.php +++ b/src/network/mcpe/protocol/types/LegacySkinAdapter.php @@ -27,6 +27,10 @@ use pocketmine\entity\Skin; use function is_array; use function is_string; +use function json_decode; +use function json_encode; +use function random_bytes; +use function str_repeat; class LegacySkinAdapter implements SkinAdapter{ diff --git a/src/network/mcpe/protocol/types/SkinImage.php b/src/network/mcpe/protocol/types/SkinImage.php index 0c0dea6df7..a82b0c3098 100644 --- a/src/network/mcpe/protocol/types/SkinImage.php +++ b/src/network/mcpe/protocol/types/SkinImage.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types; +use function strlen; + class SkinImage{ /** @var int */ diff --git a/src/network/mcpe/serializer/NetworkBinaryStream.php b/src/network/mcpe/serializer/NetworkBinaryStream.php index d3b3313f14..80fd846549 100644 --- a/src/network/mcpe/serializer/NetworkBinaryStream.php +++ b/src/network/mcpe/serializer/NetworkBinaryStream.php @@ -48,9 +48,9 @@ use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\ShortMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\StringMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\Vec3MetadataProperty; +use pocketmine\network\mcpe\protocol\types\SkinAnimation; use pocketmine\network\mcpe\protocol\types\SkinData; use pocketmine\network\mcpe\protocol\types\SkinImage; -use pocketmine\network\mcpe\protocol\types\SkinAnimation; use pocketmine\network\mcpe\protocol\types\StructureSettings; use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; diff --git a/src/permission/PermissionParser.php b/src/permission/PermissionParser.php index 7c64d37f0b..bf9d83840d 100644 --- a/src/permission/PermissionParser.php +++ b/src/permission/PermissionParser.php @@ -23,6 +23,11 @@ declare(strict_types=1); namespace pocketmine\permission; +use function is_array; +use function is_bool; +use function ksort; +use function strtolower; + class PermissionParser{ /** diff --git a/src/plugin/PluginDescription.php b/src/plugin/PluginDescription.php index eea1e213d7..8eabcae27d 100644 --- a/src/plugin/PluginDescription.php +++ b/src/plugin/PluginDescription.php @@ -36,6 +36,7 @@ use function stripos; use function strlen; use function substr; use function version_compare; +use function yaml_parse; class PluginDescription{ private $map; diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 08b2ecfdf1..10716f9aa9 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -37,6 +37,7 @@ use pocketmine\timings\TimingsHandler; use pocketmine\utils\Utils; use function array_intersect; use function array_map; +use function array_merge; use function array_pad; use function class_exists; use function count; diff --git a/src/resourcepacks/ZippedResourcePack.php b/src/resourcepacks/ZippedResourcePack.php index 0364ccd371..6a12ad12b0 100644 --- a/src/resourcepacks/ZippedResourcePack.php +++ b/src/resourcepacks/ZippedResourcePack.php @@ -34,6 +34,7 @@ use function filesize; use function fopen; use function fread; use function fseek; +use function gettype; use function hash_file; use function implode; diff --git a/src/utils/Process.php b/src/utils/Process.php index d34220c2dd..69a40f85bd 100644 --- a/src/utils/Process.php +++ b/src/utils/Process.php @@ -32,6 +32,7 @@ use function file_get_contents; use function function_exists; use function hexdec; use function memory_get_usage; +use function posix_kill; use function preg_match; use function proc_close; use function proc_open; diff --git a/src/utils/Utils.php b/src/utils/Utils.php index df0a9ccbf3..fff19b5353 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -71,6 +71,7 @@ use function str_split; use function stripos; use function strlen; use function strpos; +use function strtr; use function substr; use function sys_get_temp_dir; use function trim; diff --git a/src/world/utils/SubChunkIteratorManager.php b/src/world/utils/SubChunkIteratorManager.php index c791996589..a8fcf07940 100644 --- a/src/world/utils/SubChunkIteratorManager.php +++ b/src/world/utils/SubChunkIteratorManager.php @@ -27,6 +27,7 @@ use pocketmine\utils\Utils; use pocketmine\world\ChunkManager; use pocketmine\world\format\Chunk; use pocketmine\world\format\SubChunk; +use function assert; class SubChunkIteratorManager{ /** @var ChunkManager */ From 6935030e0c7d76afb4250b2a3ecdf6d8fc69c394 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Dec 2019 00:20:09 +0000 Subject: [PATCH 1320/3224] entity: use 0 for no-target a la vanilla 1.13, fix player arms bug I have no idea why this was changed, -1 is still used for every other property, but packet traces confirm this is correct. --- src/entity/Entity.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index ef32fb6da1..1d0fc39374 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1785,7 +1785,7 @@ abstract class Entity{ $this->networkProperties->setFloat(EntityMetadataProperties::SCALE, $this->scale); $this->networkProperties->setLong(EntityMetadataProperties::LEAD_HOLDER_EID, -1); $this->networkProperties->setLong(EntityMetadataProperties::OWNER_EID, $this->ownerId ?? -1); - $this->networkProperties->setLong(EntityMetadataProperties::TARGET_EID, $this->targetId ?? -1); + $this->networkProperties->setLong(EntityMetadataProperties::TARGET_EID, $this->targetId ?? 0); $this->networkProperties->setString(EntityMetadataProperties::NAMETAG, $this->nameTag); $this->networkProperties->setString(EntityMetadataProperties::SCORE_TAG, $this->scoreTag); From 89458660cf77d4b328ebe1ce579b11e5ba5cfd35 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Dec 2019 13:54:05 +0000 Subject: [PATCH 1321/3224] VanillaEffects: return null instead of throwing on invalid effect ID we don't expect plugin devs to be using this any more, and it doesn't make sense to throw on data deserialize. This throw was unchecked and a potential server crash might have occurred in Living on data load. --- src/entity/effect/VanillaEffects.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/entity/effect/VanillaEffects.php b/src/entity/effect/VanillaEffects.php index de8784f573..1f82926c51 100644 --- a/src/entity/effect/VanillaEffects.php +++ b/src/entity/effect/VanillaEffects.php @@ -107,14 +107,11 @@ final class VanillaEffects{ /** * @param int $id * - * @return Effect + * @return Effect|null */ - public static function byMcpeId(int $id) : Effect{ + public static function byMcpeId(int $id) : ?Effect{ self::checkInit(); - if(!isset(self::$mcpeIdMap[$id])){ - throw new \InvalidArgumentException("No such effect with MCPE ID $id"); - } - return self::$mcpeIdMap[$id]; + return self::$mcpeIdMap[$id] ?? null; } /** From 137245ed7bd3b54c6d07c5b949f8b6c2863e64d2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Dec 2019 13:54:44 +0000 Subject: [PATCH 1322/3224] ItemFactory: fix var type doc in get() --- src/item/ItemFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 3198d2ec38..eb64616c45 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -410,7 +410,7 @@ class ItemFactory{ * @throws \InvalidArgumentException */ public static function get(int $id, int $meta = 0, int $count = 1, ?CompoundTag $tags = null) : Item{ - /** @var Item $item */ + /** @var Item|null $item */ $item = null; if($meta !== -1){ if(isset(self::$list[$offset = self::getListOffset($id, $meta)])){ From 9a31cbf5eff78300c42aa10c7e9757f35d1a1a86 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Dec 2019 13:55:30 +0000 Subject: [PATCH 1323/3224] ChunkCache: fixed possible undefined offset crash in restartPendingRequest() --- src/network/mcpe/ChunkCache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/ChunkCache.php b/src/network/mcpe/ChunkCache.php index c19c847c7c..e204b1b283 100644 --- a/src/network/mcpe/ChunkCache.php +++ b/src/network/mcpe/ChunkCache.php @@ -132,7 +132,7 @@ class ChunkCache implements ChunkListener{ */ private function restartPendingRequest(int $chunkX, int $chunkZ) : void{ $chunkHash = World::chunkHash($chunkX, $chunkZ); - $existing = $this->caches[$chunkHash]; + $existing = $this->caches[$chunkHash] ?? null; if($existing === null or $existing->hasResult()){ throw new \InvalidArgumentException("Restart can only be applied to unresolved promises"); } From 6ace4733ced2e804fc5e5aa1131d9f9ec5fe2a5d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Dec 2019 15:02:42 +0000 Subject: [PATCH 1324/3224] DataPacket: fixed var_dump() buffer bin2hex not working in BinaryUtils new versions, BinaryStream->buffer is private. detected by phpstan level 4 --- src/network/mcpe/protocol/DataPacket.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/protocol/DataPacket.php b/src/network/mcpe/protocol/DataPacket.php index b5cca01bda..678409e27f 100644 --- a/src/network/mcpe/protocol/DataPacket.php +++ b/src/network/mcpe/protocol/DataPacket.php @@ -107,7 +107,7 @@ abstract class DataPacket extends NetworkBinaryStream implements Packet{ public function __debugInfo(){ $data = []; foreach((array) $this as $k => $v){ - if($k === "buffer" and is_string($v)){ + if($v === $this->getBuffer()){ $data[$k] = bin2hex($v); }elseif(is_string($v) or (is_object($v) and method_exists($v, "__toString"))){ $data[$k] = Utils::printable((string) $v); From 1c6d3cd580f0dc0e4f48cf230e448848ef36d2d7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Dec 2019 15:25:15 +0000 Subject: [PATCH 1325/3224] master: green on phpstan level 4 --- tests/phpstan/configs/phpstan-bugs.neon | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index c7bb5a26d8..80e555e31e 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -47,11 +47,28 @@ parameters: count: 1 path: ../../../src/entity/projectile/Projectile.php + - + #dynamic Entity class access of ::ID constant + message: "#^Strict comparison using \\!\\=\\= between \\-1 and \\-1 will always evaluate to false\\.$#" + count: 1 + path: ../../../src/item/ItemFactory.php + - message: "#^Cannot access offset int on Ds\\\\Deque&iterable\\\\.$#" count: 2 path: ../../../src/item/WritableBookBase.php + - + #object to array cast analysis bug + message: "#^Call to function is_object\\(\\) with int will always evaluate to false\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/DataPacket.php + + - + message: "#^If condition is always false\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php + - message: "#^Instanceof between int and PharFileInfo will always evaluate to false\\.$#" count: 1 From 771ccbb7276094135e227028c5022c00075e48ce Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Dec 2019 20:13:51 +0000 Subject: [PATCH 1326/3224] Server: require a DynamicClassLoader instance --- src/Server.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Server.php b/src/Server.php index 7e22fd8e21..620bf1ce2e 100644 --- a/src/Server.php +++ b/src/Server.php @@ -260,7 +260,7 @@ class Server{ /** @var UUID */ private $serverID; - /** @var \ClassLoader */ + /** @var \DynamicClassLoader */ private $autoloader; /** @var string */ private $dataPath; @@ -456,7 +456,7 @@ class Server{ } /** - * @return \ClassLoader + * @return \DynamicClassLoader */ public function getLoader(){ return $this->autoloader; @@ -971,12 +971,12 @@ class Server{ } /** - * @param \ClassLoader $autoloader + * @param \DynamicClassLoader $autoloader * @param \AttachableThreadedLogger $logger * @param string $dataPath * @param string $pluginPath */ - public function __construct(\ClassLoader $autoloader, \AttachableThreadedLogger $logger, string $dataPath, string $pluginPath){ + public function __construct(\DynamicClassLoader $autoloader, \AttachableThreadedLogger $logger, string $dataPath, string $pluginPath){ if(self::$instance !== null){ throw new \InvalidStateException("Only one server instance can exist at once"); } From 0a4a1f634f1c5222727ce3891c7cc856b5f8ef05 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Dec 2019 20:26:26 +0000 Subject: [PATCH 1327/3224] Item: fixed possible type violation in jsonDeserialize() --- src/item/Item.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/item/Item.php b/src/item/Item.php index 1803d93f32..cf22eb13f8 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -695,7 +695,7 @@ class Item implements \JsonSerializable{ $nbt = base64_decode($data["nbt_b64"], true); } return ItemFactory::get( - (int) $data["id"], (int) ($data["damage"] ?? 0), (int) ($data["count"] ?? 1), $nbt !== "" ? (new LittleEndianNbtSerializer())->read($nbt)->getTag() : null + (int) $data["id"], (int) ($data["damage"] ?? 0), (int) ($data["count"] ?? 1), $nbt !== "" ? (new LittleEndianNbtSerializer())->read($nbt)->mustGetCompoundTag() : null ); } From 81620441a45ba4b945e305c62454e651de475d2a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Dec 2019 20:27:40 +0000 Subject: [PATCH 1328/3224] CompoundTagMetadataProperty: fix unhandled exception when decoding --- .../types/entity/CompoundTagMetadataProperty.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php b/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php index 705779fd88..4c1c738410 100644 --- a/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; +use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; @@ -54,11 +56,21 @@ final class CompoundTagMetadataProperty implements MetadataProperty{ return $other instanceof self and $other->value->equals($this->value); } + /** + * @param NetworkBinaryStream $in + * + * @return self + * @throws BadPacketException + */ public static function read(NetworkBinaryStream $in) : self{ $offset = $in->getOffset(); - $result = new self((new NetworkNbtSerializer())->read($in->getBuffer(), $offset, 512)->getTag()); + try{ + $tag = (new NetworkNbtSerializer())->read($in->getBuffer(), $offset, 512)->mustGetCompoundTag(); + }catch(NbtDataException $e){ + throw new BadPacketException($e->getMessage(), 0, $e); + } $in->setOffset($offset); - return $result; + return new self($tag); } public function write(NetworkBinaryStream $out) : void{ From bcc3e20c3134a8c12ee3f916a827ee58d7f07341 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 13 Dec 2019 17:58:53 +0000 Subject: [PATCH 1329/3224] DiskResourceProvider: do not arbitrarily suffix /resources/ --- src/plugin/DiskResourceProvider.php | 10 +++++----- src/plugin/PluginManager.php | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/plugin/DiskResourceProvider.php b/src/plugin/DiskResourceProvider.php index 09a703f43f..c3487bb396 100644 --- a/src/plugin/DiskResourceProvider.php +++ b/src/plugin/DiskResourceProvider.php @@ -55,8 +55,8 @@ class DiskResourceProvider implements ResourceProvider{ */ public function getResource(string $filename){ $filename = rtrim(str_replace("\\", "/", $filename), "/"); - if(file_exists($this->file . "/resources/" . $filename)){ - return fopen($this->file . "/resources/" . $filename, "rb"); + if(file_exists($this->file . "/" . $filename)){ + return fopen($this->file . "/" . $filename, "rb"); } return null; @@ -69,10 +69,10 @@ class DiskResourceProvider implements ResourceProvider{ */ public function getResources() : array{ $resources = []; - if(is_dir($this->file . "resources/")){ - foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->file . "resources/")) as $resource){ + if(is_dir($this->file)){ + foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->file)) as $resource){ if($resource->isFile()){ - $path = str_replace(DIRECTORY_SEPARATOR, "/", substr((string) $resource, strlen($this->file . "resources/"))); + $path = str_replace(DIRECTORY_SEPARATOR, "/", substr((string) $resource, strlen($this->file))); $resources[$path] = $resource; } } diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 10716f9aa9..e30a275342 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -185,7 +185,7 @@ class PluginManager{ * @var Plugin $plugin * @see Plugin::__construct() */ - $plugin = new $mainClass($loader, $this->server, $description, $dataFolder, $prefixed, new DiskResourceProvider($prefixed . "/")); + $plugin = new $mainClass($loader, $this->server, $description, $dataFolder, $prefixed, new DiskResourceProvider($prefixed . "/resources/")); $this->plugins[$plugin->getDescription()->getName()] = $plugin; return $plugin; From 9204b119480e57d8d0bd4564fa7e69fa4e900430 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 29 Dec 2019 17:55:03 +0000 Subject: [PATCH 1330/3224] phpstan: 0.12.3 fixes for master --- tests/phpstan/configs/phpstan-bugs.neon | 27 +++++-------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 41e6f8bb3f..6d2c8eb049 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -53,6 +53,11 @@ parameters: count: 1 path: ../../../src/item/ItemFactory.php + - + message: "#^If condition is always false\\.$#" + count: 1 + path: ../../../src/item/ItemFactory.php + - message: "#^Cannot access offset int on Ds\\\\Deque&iterable\\\\.$#" count: 2 @@ -69,29 +74,7 @@ parameters: count: 1 path: ../../../src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php - - - message: "#^Instanceof between int and PharFileInfo will always evaluate to false\\.$#" - count: 1 - path: ../../../src/plugin/PharPluginLoader.php - - message: "#^Strict comparison using \\=\\=\\= between int\\<1, max\\> and 0 will always evaluate to false\\.$#" count: 1 path: ../../../src/utils/Config.php - - - - #ReflectionFunction::getClosureThis() should be nullable - message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#" - count: 1 - path: ../../../src/utils/Utils.php - - - - #ReflectionFunction::getClosureScopeClass() should be nullable - message: "#^Unreachable statement \\- code above always terminates\\.$#" - count: 1 - path: ../../../src/utils/Utils.php - - - - message: "#^Strict comparison using \\=\\=\\= between int\\ and 4 will always evaluate to false\\.$#" - count: 1 - path: ../../../src/world/World.php From e76cc8eb333aed816f6856d54efaaf5810a3a1ab Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Jan 2020 11:32:23 +0000 Subject: [PATCH 1331/3224] RakLibPacketSender: fixed session leak on server-side disconnect --- src/network/mcpe/raklib/RakLibPacketSender.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/raklib/RakLibPacketSender.php b/src/network/mcpe/raklib/RakLibPacketSender.php index 29ee9b3861..8c1e33782e 100644 --- a/src/network/mcpe/raklib/RakLibPacketSender.php +++ b/src/network/mcpe/raklib/RakLibPacketSender.php @@ -49,7 +49,7 @@ class RakLibPacketSender implements PacketSender{ public function close(string $reason = "unknown reason") : void{ if(!$this->closed){ $this->closed = true; - $this->handler->closeSession($this->sessionId, $reason); + $this->handler->close($this->sessionId, $reason); } } } From a733f094ac6994cafed3e0577bac103ee7c87926 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 8 Jan 2020 19:45:05 +0000 Subject: [PATCH 1332/3224] phpstan: added a custom rule to disallow strict equality operators on enum members comparing enums with equality operators is unreliable because there is no guarantee that the enum objects won't be somehow duplicated, through serialization, cloning or ext-parallel dumb object copying. This means that two equal enum objects may not be thw same object. --- composer.json | 3 +- phpstan.neon.dist | 1 + .../rules/DisallowEnumComparisonRule.php | 67 +++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 tests/phpstan/rules/DisallowEnumComparisonRule.php diff --git a/composer.json b/composer.json index 174f5cf52f..fd32dd01a7 100644 --- a/composer.json +++ b/composer.json @@ -54,7 +54,8 @@ }, "autoload-dev": { "psr-4": { - "pocketmine\\": "tests/phpunit/" + "pocketmine\\": "tests/phpunit/", + "pocketmine\\phpstan\\rules\\": "tests/phpstan/rules" } }, "repositories": [ diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 76ae2d5b02..a5e8645a52 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -13,6 +13,7 @@ parameters: - build/server-phar.php paths: - src + - tests/phpstan/rules - build/server-phar.php dynamicConstantNames: - pocketmine\IS_DEVELOPMENT_BUILD diff --git a/tests/phpstan/rules/DisallowEnumComparisonRule.php b/tests/phpstan/rules/DisallowEnumComparisonRule.php new file mode 100644 index 0000000000..0e62fc96b2 --- /dev/null +++ b/tests/phpstan/rules/DisallowEnumComparisonRule.php @@ -0,0 +1,67 @@ +left, $node->right] as $n){ + $type = $scope->getType($n); + if(!($type instanceof ObjectType)){ + continue; + } + $class = $type->getClassReflection(); + if($class === null or !$class->hasTraitUse(EnumTrait::class)){ + continue; + } + $result[] = RuleErrorBuilder::message(sprintf( + 'Strict comparison using %s involving enum %s is not reliable.', + $node instanceof Identical ? '===' : '!==', + $type->describe(VerbosityLevel::value()) + ))->build(); + } + return $result; + } +} \ No newline at end of file From aba71762e92200328f496d664fd2f7bd7b43dba4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 Jan 2020 17:50:01 +0000 Subject: [PATCH 1333/3224] master-specific @var annotations --- src/block/Liquid.php | 1 + src/entity/Entity.php | 1 + src/entity/EntityFactory.php | 1 + src/entity/Human.php | 1 + src/network/Network.php | 2 ++ src/network/mcpe/ChunkRequestTask.php | 1 + src/network/mcpe/compression/CompressBatchTask.php | 2 ++ src/network/mcpe/compression/Zlib.php | 2 ++ src/network/mcpe/encryption/NetworkCipher.php | 1 + src/plugin/PluginDescription.php | 8 ++++++++ src/scheduler/AsyncTask.php | 4 ++++ src/world/SimpleChunkManager.php | 1 + src/world/format/io/WorldProviderManager.php | 1 + src/world/light/LightPopulationTask.php | 1 + 14 files changed, 27 insertions(+) diff --git a/src/block/Liquid.php b/src/block/Liquid.php index 9f4435e46b..6ff6647824 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -42,6 +42,7 @@ abstract class Liquid extends Transparent{ /** @var BlockIdentifierFlattened */ protected $idInfo; + /** @var int */ public $adjacentSources = 0; /** @var Vector3|null */ diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 1d0fc39374..165343a580 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -134,6 +134,7 @@ abstract class Entity{ /** @var float */ private $health = 20.0; + /** @var int */ private $maxHealth = 20; /** @var float */ diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index 8290f45159..a4de128fdb 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -61,6 +61,7 @@ use function reset; */ final class EntityFactory{ + /** @var int */ private static $entityCount = 1; /** @var string[] base class => currently used class for construction */ private static $classMapping = []; diff --git a/src/entity/Human.php b/src/entity/Human.php index bbc7869daa..bdf7969e0a 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -85,6 +85,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ /** @var ExperienceManager */ protected $xpManager; + /** @var int */ protected $xpSeed; protected $baseOffset = 1.62; diff --git a/src/network/Network.php b/src/network/Network.php index beff79f6a5..7f14e8149f 100644 --- a/src/network/Network.php +++ b/src/network/Network.php @@ -49,7 +49,9 @@ class Network{ /** @var int[] */ private $bannedIps = []; + /** @var float */ private $upload = 0; + /** @var float */ private $download = 0; /** @var string */ diff --git a/src/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php index f95d669ab7..55dd1e48d0 100644 --- a/src/network/mcpe/ChunkRequestTask.php +++ b/src/network/mcpe/ChunkRequestTask.php @@ -42,6 +42,7 @@ class ChunkRequestTask extends AsyncTask{ /** @var int */ protected $chunkZ; + /** @var int */ protected $compressionLevel; /** @var string */ diff --git a/src/network/mcpe/compression/CompressBatchTask.php b/src/network/mcpe/compression/CompressBatchTask.php index 9ad39314d1..62aa9a0371 100644 --- a/src/network/mcpe/compression/CompressBatchTask.php +++ b/src/network/mcpe/compression/CompressBatchTask.php @@ -29,7 +29,9 @@ class CompressBatchTask extends AsyncTask{ private const TLS_KEY_PROMISE = "promise"; + /** @var int */ private $level; + /** @var string */ private $data; /** diff --git a/src/network/mcpe/compression/Zlib.php b/src/network/mcpe/compression/Zlib.php index 9963126141..05a44987f4 100644 --- a/src/network/mcpe/compression/Zlib.php +++ b/src/network/mcpe/compression/Zlib.php @@ -28,7 +28,9 @@ use function zlib_encode; use const ZLIB_ENCODING_DEFLATE; final class Zlib{ + /** @var int */ public static $LEVEL = 7; + /** @var int */ public static $THRESHOLD = 256; private function __construct(){ diff --git a/src/network/mcpe/encryption/NetworkCipher.php b/src/network/mcpe/encryption/NetworkCipher.php index beb74b7955..0b9c25a0fa 100644 --- a/src/network/mcpe/encryption/NetworkCipher.php +++ b/src/network/mcpe/encryption/NetworkCipher.php @@ -34,6 +34,7 @@ class NetworkCipher{ private const ENCRYPTION_SCHEME = "AES-256-CFB8"; private const CHECKSUM_ALGO = "sha256"; + /** @var bool */ public static $ENABLED = true; /** @var string */ diff --git a/src/plugin/PluginDescription.php b/src/plugin/PluginDescription.php index 55d0fb77a9..0a6fe602a8 100644 --- a/src/plugin/PluginDescription.php +++ b/src/plugin/PluginDescription.php @@ -39,20 +39,28 @@ use function version_compare; use function yaml_parse; class PluginDescription{ + /** @var mixed[] */ private $map; + /** @var string */ private $name; + /** @var string */ private $main; + /** @var string[] */ private $api; /** @var int[] */ private $compatibleMcpeProtocols = []; /** @var string[][] */ private $extensions = []; + /** @var string[] */ private $depend = []; + /** @var string[] */ private $softDepend = []; + /** @var string[] */ private $loadBefore = []; /** @var string */ private $version; + /** @var mixed[][] */ private $commands = []; /** @var string */ private $description = ""; diff --git a/src/scheduler/AsyncTask.php b/src/scheduler/AsyncTask.php index 98f4d2a384..0135dd4ce9 100644 --- a/src/scheduler/AsyncTask.php +++ b/src/scheduler/AsyncTask.php @@ -59,12 +59,16 @@ abstract class AsyncTask extends \Threaded{ /** @var \Threaded */ public $progressUpdates; + /** @var scalar|null */ private $result = null; + /** @var bool */ private $serialized = false; + /** @var bool */ private $cancelRun = false; /** @var bool */ private $submitted = false; + /** @var bool */ private $crashed = false; /** @var bool */ private $finished = false; diff --git a/src/world/SimpleChunkManager.php b/src/world/SimpleChunkManager.php index 14673fe5f1..2c04e85a6e 100644 --- a/src/world/SimpleChunkManager.php +++ b/src/world/SimpleChunkManager.php @@ -35,6 +35,7 @@ class SimpleChunkManager implements ChunkManager{ /** @var Chunk[] */ protected $chunks = []; + /** @var int */ protected $worldHeight; /** @var SubChunkIteratorManager */ diff --git a/src/world/format/io/WorldProviderManager.php b/src/world/format/io/WorldProviderManager.php index cd25847498..d5f8bd48f9 100644 --- a/src/world/format/io/WorldProviderManager.php +++ b/src/world/format/io/WorldProviderManager.php @@ -32,6 +32,7 @@ use function strtolower; use function trim; abstract class WorldProviderManager{ + /** @var string[] */ protected static $providers = []; /** @var string|WorldProvider */ diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index 25e41bd4b0..37989dd250 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -35,6 +35,7 @@ use function igbinary_unserialize; class LightPopulationTask extends AsyncTask{ private const TLS_KEY_WORLD = "world"; + /** @var string */ public $chunk; /** @var int */ From 16bab02b13b10133237db589dc891dd4228a35bb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 Jan 2020 17:54:52 +0000 Subject: [PATCH 1334/3224] actually use the DisallowEnumComparisonRule (derp) --- phpstan.neon.dist | 3 +++ 1 file changed, 3 insertions(+) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index a5e8645a52..8d8f193bea 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -5,6 +5,9 @@ includes: - tests/phpstan/configs/pthreads-bugs.neon - tests/phpstan/configs/runtime-type-checks.neon +rules: + - pocketmine\phpstan\rules\DisallowEnumComparisonRule + parameters: level: 5 autoload_files: From 56a459ccee19a33824a4379b47abf84b7b660759 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 11 Jan 2020 22:13:07 +0000 Subject: [PATCH 1335/3224] updated composer dependencies --- composer.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.lock b/composer.lock index e31a9fd629..82a8079a20 100644 --- a/composer.lock +++ b/composer.lock @@ -368,12 +368,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Log.git", - "reference": "27a5f5cf5bfeddec4231470a7b803c7bf8df6fbe" + "reference": "48af0e1c9ca7b256c21ae995e83e5755587d233d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Log/zipball/27a5f5cf5bfeddec4231470a7b803c7bf8df6fbe", - "reference": "27a5f5cf5bfeddec4231470a7b803c7bf8df6fbe", + "url": "https://api.github.com/repos/pmmp/Log/zipball/48af0e1c9ca7b256c21ae995e83e5755587d233d", + "reference": "48af0e1c9ca7b256c21ae995e83e5755587d233d", "shasum": "" }, "type": "library", @@ -390,7 +390,7 @@ "source": "https://github.com/pmmp/Log/tree/master", "issues": "https://github.com/pmmp/Log/issues" }, - "time": "2019-10-24T18:48:08+00:00" + "time": "2020-01-11T22:03:44+00:00" }, { "name": "pocketmine/math", @@ -437,12 +437,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "221212bd1991430a74374295261795a9a13875bb" + "reference": "c1d440cccb0be90f8ef519f231de7e91bb8db28f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/221212bd1991430a74374295261795a9a13875bb", - "reference": "221212bd1991430a74374295261795a9a13875bb", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/c1d440cccb0be90f8ef519f231de7e91bb8db28f", + "reference": "c1d440cccb0be90f8ef519f231de7e91bb8db28f", "shasum": "" }, "require": { @@ -470,7 +470,7 @@ "source": "https://github.com/pmmp/NBT/tree/master", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2019-12-09T11:21:10+00:00" + "time": "2020-01-01T10:09:55+00:00" }, { "name": "pocketmine/raklib", From eba246eab30391c69f7d5391cd5326f80fe4cda3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 11 Jan 2020 22:39:42 +0000 Subject: [PATCH 1336/3224] SignText: provide typeinfo for checkLineIndex --- src/block/utils/SignText.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/block/utils/SignText.php b/src/block/utils/SignText.php index adefba3070..364b0ebea4 100644 --- a/src/block/utils/SignText.php +++ b/src/block/utils/SignText.php @@ -86,6 +86,9 @@ class SignText{ } } + /** + * @param int|string $index + */ private function checkLineIndex($index) : void{ if(!is_int($index)){ throw new \InvalidArgumentException("Index must be an integer"); From 0e1cea043af3a2e1b816c1192fec2a5c936a964c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 13 Jan 2020 15:05:02 +0000 Subject: [PATCH 1337/3224] added some phpstan-specific generic type annotations --- phpstan.neon.dist | 1 + src/block/Banner.php | 7 ++++++- src/block/tile/Banner.php | 7 ++++++- src/event/HandlerListManager.php | 13 +++++++++++++ src/item/Banner.php | 7 ++++++- src/item/Item.php | 14 ++++++++++++-- src/item/WritableBookBase.php | 5 ++++- src/scheduler/AsyncTask.php | 1 + tests/phpstan/configs/ds-bugs.neon | 9 +++++++++ tests/phpstan/configs/phpstan-bugs.neon | 10 ---------- tests/phpstan/rules/DisallowEnumComparisonRule.php | 3 +++ 11 files changed, 61 insertions(+), 16 deletions(-) create mode 100644 tests/phpstan/configs/ds-bugs.neon diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 2672e074c0..09063dfeec 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,4 +1,5 @@ includes: + - tests/phpstan/configs/ds-bugs.neon - tests/phpstan/configs/gc-hacks.neon - tests/phpstan/configs/gradual-level6.neon - tests/phpstan/configs/optional-com-dotnet.neon diff --git a/src/block/Banner.php b/src/block/Banner.php index 23f0a026a6..cf32d486b4 100644 --- a/src/block/Banner.php +++ b/src/block/Banner.php @@ -55,7 +55,10 @@ class Banner extends Transparent{ /** @var DyeColor */ protected $baseColor; - /** @var Deque|BannerPattern[] */ + /** + * @var Deque|BannerPattern[] + * @phpstan-var Deque + */ protected $patterns; public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ @@ -125,6 +128,7 @@ class Banner extends Transparent{ /** * @return Deque|BannerPattern[] + * @phpstan-return Deque */ public function getPatterns() : Deque{ return $this->patterns; @@ -132,6 +136,7 @@ class Banner extends Transparent{ /** * @param Deque|BannerPattern[] $patterns + * @phpstan-param Deque $patterns */ public function setPatterns(Deque $patterns) : void{ $checked = $patterns->filter(function($v){ return $v instanceof BannerPattern; }); diff --git a/src/block/tile/Banner.php b/src/block/tile/Banner.php index aed147de49..1860997e1e 100644 --- a/src/block/tile/Banner.php +++ b/src/block/tile/Banner.php @@ -46,7 +46,10 @@ class Banner extends Spawnable{ /** @var DyeColor */ private $baseColor; - /** @var BannerPattern[]|Deque */ + /** + * @var BannerPattern[]|Deque + * @phpstan-var Deque + */ private $patterns; public function __construct(World $world, Vector3 $pos){ @@ -113,6 +116,7 @@ class Banner extends Spawnable{ /** * @return BannerPattern[]|Deque + * @phpstan-return Deque */ public function getPatterns() : Deque{ return $this->patterns; @@ -120,6 +124,7 @@ class Banner extends Spawnable{ /** * @param BannerPattern[]|Deque $patterns + * @phpstan-param Deque $patterns */ public function setPatterns(Deque $patterns) : void{ $this->patterns = $patterns; diff --git a/src/event/HandlerListManager.php b/src/event/HandlerListManager.php index a21e7a49c0..ed1c2713b5 100644 --- a/src/event/HandlerListManager.php +++ b/src/event/HandlerListManager.php @@ -58,11 +58,24 @@ class HandlerListManager{ } } + /** + * @param ReflectionClass $class + * @phpstan-param \ReflectionClass $class + * + * @return bool + */ private static function isValidClass(\ReflectionClass $class) : bool{ $tags = Utils::parseDocComment((string) $class->getDocComment()); return !$class->isAbstract() || isset($tags["allowHandle"]); } + /** + * @param \ReflectionClass $class + * @phpstan-param \ReflectionClass $class + * + * @return \ReflectionClass|null + * @phpstan-return \ReflectionClass|null + */ private static function resolveNearestHandleableParent(\ReflectionClass $class) : ?\ReflectionClass{ for($parent = $class->getParentClass(); $parent !== false && !self::isValidClass($parent); $parent = $parent->getParentClass()){ //NOOP diff --git a/src/item/Banner.php b/src/item/Banner.php index b079844828..7b0950c644 100644 --- a/src/item/Banner.php +++ b/src/item/Banner.php @@ -40,7 +40,10 @@ class Banner extends Item{ /** @var DyeColor */ private $color; - /** @var BannerPattern[]|Deque */ + /** + * @var BannerPattern[]|Deque + * @phpstan-var Deque + */ private $patterns; public function __construct(int $id, int $variant, string $name, DyeColor $color){ @@ -67,6 +70,7 @@ class Banner extends Item{ /** * @return Deque|BannerPattern[] + * @phpstan-return Deque */ public function getPatterns() : Deque{ return $this->patterns; @@ -74,6 +78,7 @@ class Banner extends Item{ /** * @param Deque|BannerPattern[] $patterns + * @phpstan-param Deque $patterns * * @return $this */ diff --git a/src/item/Item.php b/src/item/Item.php index cf22eb13f8..cac81cf2d2 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -86,9 +86,15 @@ class Item implements \JsonSerializable{ */ protected $blockEntityTag = null; - /** @var Set|string[] */ + /** + * @var Set|string[] + * @phpstan-var Set + */ protected $canPlaceOn; - /** @var Set|string[] */ + /** + * @var Set|string[] + * @phpstan-var Set + */ protected $canDestroy; /** @@ -202,6 +208,7 @@ class Item implements \JsonSerializable{ /** * @return Set|string[] + * @phpstan-return Set */ public function getCanPlaceOn() : Set{ return $this->canPlaceOn; @@ -209,6 +216,7 @@ class Item implements \JsonSerializable{ /** * @param Set|string[] $canPlaceOn + * @phpstan-param Set $canPlaceOn */ public function setCanPlaceOn(Set $canPlaceOn) : void{ $this->canPlaceOn = $canPlaceOn; @@ -216,6 +224,7 @@ class Item implements \JsonSerializable{ /** * @return Set|string[] + * @phpstan-return Set */ public function getCanDestroy() : Set{ return $this->canDestroy; @@ -223,6 +232,7 @@ class Item implements \JsonSerializable{ /** * @param Set|string[] $canDestroy + * @phpstan-param Set $canDestroy */ public function setCanDestroy(Set $canDestroy) : void{ $this->canDestroy = $canDestroy; diff --git a/src/item/WritableBookBase.php b/src/item/WritableBookBase.php index c29c4f97d0..b822ab0325 100644 --- a/src/item/WritableBookBase.php +++ b/src/item/WritableBookBase.php @@ -34,7 +34,10 @@ abstract class WritableBookBase extends Item{ public const TAG_PAGE_TEXT = "text"; //TAG_String public const TAG_PAGE_PHOTONAME = "photoname"; //TAG_String - TODO - /** @var WritableBookPage[]|Deque */ + /** + * @var WritableBookPage[]|Deque + * @phpstan-var Deque + */ private $pages; public function __construct(int $id, int $variant, string $name){ diff --git a/src/scheduler/AsyncTask.php b/src/scheduler/AsyncTask.php index 0135dd4ce9..f59949192a 100644 --- a/src/scheduler/AsyncTask.php +++ b/src/scheduler/AsyncTask.php @@ -48,6 +48,7 @@ use function unserialize; abstract class AsyncTask extends \Threaded{ /** * @var \ArrayObject|mixed[]|null object hash => mixed data + * @phpstan-var \ArrayObject>|null * * Used to store objects which are only needed on one thread and should not be serialized. */ diff --git a/tests/phpstan/configs/ds-bugs.neon b/tests/phpstan/configs/ds-bugs.neon new file mode 100644 index 0000000000..93eddec8bc --- /dev/null +++ b/tests/phpstan/configs/ds-bugs.neon @@ -0,0 +1,9 @@ +parameters: + ignoreErrors: + - + message: "#^Cannot (access an|assign new) offset (on|to) Ds\\\\Deque\\<.+\\>\\.$#" + path: ../../../src + + - + message: "#^Cannot (access|assign) offset (int|-?\\d+) (on|to) Ds\\\\Deque\\<.+\\>\\.$#" + path: ../../../src \ No newline at end of file diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 219cfb2b88..0e617c3603 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -33,11 +33,6 @@ parameters: count: 1 path: ../../../src/block/Liquid.php - - - message: "#^Cannot access an offset on Ds\\\\Deque&iterable\\\\.$#" - count: 1 - path: ../../../src/block/tile/Banner.php - - message: "#^Call to function assert\\(\\) with false and 'unknown hit type' will always evaluate to false\\.$#" count: 1 @@ -54,11 +49,6 @@ parameters: count: 1 path: ../../../src/item/ItemFactory.php - - - message: "#^Cannot access offset int on Ds\\\\Deque&iterable\\\\.$#" - count: 2 - path: ../../../src/item/WritableBookBase.php - - #object to array cast analysis bug message: "#^Call to function is_object\\(\\) with int will always evaluate to false\\.$#" diff --git a/tests/phpstan/rules/DisallowEnumComparisonRule.php b/tests/phpstan/rules/DisallowEnumComparisonRule.php index 0e62fc96b2..5370d158dc 100644 --- a/tests/phpstan/rules/DisallowEnumComparisonRule.php +++ b/tests/phpstan/rules/DisallowEnumComparisonRule.php @@ -35,6 +35,9 @@ use PHPStan\Type\VerbosityLevel; use pocketmine\utils\EnumTrait; use function sprintf; +/** + * @phpstan-implements Rule + */ class DisallowEnumComparisonRule implements Rule{ public function getNodeType() : string{ From 00869e81ba440a90227be64ddd0097e044c78800 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 15 Jan 2020 19:48:25 +0000 Subject: [PATCH 1338/3224] NetworkBinaryStream: fix server crash on wrong skindata size, close #3276 --- src/network/mcpe/serializer/NetworkBinaryStream.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/network/mcpe/serializer/NetworkBinaryStream.php b/src/network/mcpe/serializer/NetworkBinaryStream.php index e4dbbf3f9b..80cf982661 100644 --- a/src/network/mcpe/serializer/NetworkBinaryStream.php +++ b/src/network/mcpe/serializer/NetworkBinaryStream.php @@ -148,7 +148,11 @@ class NetworkBinaryStream extends BinaryStream{ $width = $this->getLInt(); $height = $this->getLInt(); $data = $this->getString(); - return new SkinImage($height, $width, $data); + try{ + return new SkinImage($height, $width, $data); + }catch(\InvalidArgumentException $e){ + throw new BadPacketException($e->getMessage(), 0, $e); + } } private function putSkinImage(SkinImage $image) : void{ From c0a45083b6e2656322042f3f88c92df55fedf75a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 Jan 2020 19:58:14 +0000 Subject: [PATCH 1339/3224] Packet: specify void return type in phpdoc (native return type not possible yet) --- src/network/mcpe/protocol/Packet.php | 9 +++++++++ src/network/mcpe/serializer/NetworkBinaryStream.php | 7 +------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/network/mcpe/protocol/Packet.php b/src/network/mcpe/protocol/Packet.php index 2c754240ab..e54489f812 100644 --- a/src/network/mcpe/protocol/Packet.php +++ b/src/network/mcpe/protocol/Packet.php @@ -30,6 +30,15 @@ interface Packet{ public function setOffset(int $offset) : void; + /** + * TODO: this can't have a native return type yet because of incompatibility with BinaryUtils + * really this should be addressed by making packets not extend BinaryStream, but that's a task for another day. + * + * @param string $buffer + * @param int $offset + * + * @return void + */ public function setBuffer(string $buffer = "", int $offset = 0); public function getOffset() : int; diff --git a/src/network/mcpe/serializer/NetworkBinaryStream.php b/src/network/mcpe/serializer/NetworkBinaryStream.php index 11d6bf51f5..bc29ec5881 100644 --- a/src/network/mcpe/serializer/NetworkBinaryStream.php +++ b/src/network/mcpe/serializer/NetworkBinaryStream.php @@ -122,12 +122,7 @@ class NetworkBinaryStream extends BinaryStream{ return new SkinData($skinId, $skinResourcePatch, $skinData, $animations, $capeData, $geometryData, $animationData, $premium, $persona, $capeOnClassic, $capeId); } - /** - * @param SkinData $skin - * - * @return void - */ - public function putSkin(SkinData $skin){ + public function putSkin(SkinData $skin): void{ $this->putString($skin->getSkinId()); $this->putString($skin->getResourcePatch()); $this->putSkinImage($skin->getSkinImage()); From df2551ed4d5596e84f60d2d1da41bac833584725 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 Jan 2020 20:00:05 +0000 Subject: [PATCH 1340/3224] NetworkSession: add missing return type for syncAttributes() --- src/network/mcpe/NetworkSession.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 3837e7b5fc..ca613441d9 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -684,7 +684,7 @@ class NetworkSession{ $this->sendDataPacket($pk); } - public function syncAttributes(Living $entity, bool $sendAll = false){ + public function syncAttributes(Living $entity, bool $sendAll = false) : void{ $entries = $sendAll ? $entity->getAttributeMap()->getAll() : $entity->getAttributeMap()->needSend(); if(count($entries) > 0){ $this->sendDataPacket(UpdateAttributesPacket::create($entity->getId(), $entries)); From 3cf0b50b4a81bd5af8e8faaa65d139d609100085 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 19 Jan 2020 09:58:40 +0000 Subject: [PATCH 1341/3224] update pocketmine/log and pocketmine/classloader dependencies --- composer.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.lock b/composer.lock index 82a8079a20..fb0f968a0f 100644 --- a/composer.lock +++ b/composer.lock @@ -333,12 +333,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/ClassLoader.git", - "reference": "f0d947debe366890206fc1d8f3fc7bef6bee6335" + "reference": "8aaeddd7366d95c938f88247fc409a5bedc4473a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/f0d947debe366890206fc1d8f3fc7bef6bee6335", - "reference": "f0d947debe366890206fc1d8f3fc7bef6bee6335", + "url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/8aaeddd7366d95c938f88247fc409a5bedc4473a", + "reference": "8aaeddd7366d95c938f88247fc409a5bedc4473a", "shasum": "" }, "require": { @@ -360,7 +360,7 @@ "source": "https://github.com/pmmp/ClassLoader/tree/master", "issues": "https://github.com/pmmp/ClassLoader/issues" }, - "time": "2019-11-04T11:25:46+00:00" + "time": "2020-01-14T16:30:55+00:00" }, { "name": "pocketmine/log", @@ -368,12 +368,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Log.git", - "reference": "48af0e1c9ca7b256c21ae995e83e5755587d233d" + "reference": "6e79bb262acd67344b8e3e394ed1afb4a72ea294" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Log/zipball/48af0e1c9ca7b256c21ae995e83e5755587d233d", - "reference": "48af0e1c9ca7b256c21ae995e83e5755587d233d", + "url": "https://api.github.com/repos/pmmp/Log/zipball/6e79bb262acd67344b8e3e394ed1afb4a72ea294", + "reference": "6e79bb262acd67344b8e3e394ed1afb4a72ea294", "shasum": "" }, "type": "library", @@ -390,7 +390,7 @@ "source": "https://github.com/pmmp/Log/tree/master", "issues": "https://github.com/pmmp/Log/issues" }, - "time": "2020-01-11T22:03:44+00:00" + "time": "2020-01-15T19:59:42+00:00" }, { "name": "pocketmine/math", From 3ee68877926c9b2a4896db3b7d7bf31b89f4b359 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 19 Jan 2020 10:26:35 +0000 Subject: [PATCH 1342/3224] populate remaining missing return types, using native returns where possible this is done separately to stable so that stable changes can be integrated easily using an empty merge. --- src/Server.php | 2 +- src/block/tile/Chest.php | 10 ++-- src/block/tile/Furnace.php | 2 +- src/command/PluginCommand.php | 2 +- src/inventory/CreativeInventory.php | 8 +-- src/lang/Language.php | 2 +- src/network/mcpe/protocol/DataPacket.php | 6 +- src/permission/DefaultPermissions.php | 2 +- src/player/OfflinePlayer.php | 2 +- src/player/Player.php | 54 +++++++++--------- src/plugin/PluginBase.php | 10 +++- src/scheduler/Task.php | 2 + src/thread/CommonThreadPartsTrait.php | 2 +- src/utils/Config.php | 2 +- src/utils/MainLogger.php | 2 + src/world/World.php | 72 ++++++++++++------------ src/world/format/SubChunk.php | 2 +- 17 files changed, 97 insertions(+), 85 deletions(-) diff --git a/src/Server.php b/src/Server.php index c98a61d525..2bd8f86b9d 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1744,7 +1744,7 @@ class Server{ exit(1); } - public function __debugInfo(){ + public function __debugInfo() : array{ return []; } diff --git a/src/block/tile/Chest.php b/src/block/tile/Chest.php index 04bfc42135..9a4f2dd445 100644 --- a/src/block/tile/Chest.php +++ b/src/block/tile/Chest.php @@ -136,7 +136,7 @@ class Chest extends Spawnable implements Container, Nameable{ return $this->inventory; } - protected function checkPairing(){ + protected function checkPairing() : void{ if($this->isPaired() and !$this->pos->getWorld()->isInLoadedTerrain(new Vector3($this->pairX, $this->pos->y, $this->pairZ))){ //paired to a tile in an unloaded chunk $this->doubleInventory = null; @@ -170,7 +170,7 @@ class Chest extends Spawnable implements Container, Nameable{ return "Chest"; } - public function isPaired(){ + public function isPaired() : bool{ return $this->pairX !== null and $this->pairZ !== null; } @@ -188,7 +188,7 @@ class Chest extends Spawnable implements Container, Nameable{ return null; } - public function pairWith(Chest $tile){ + public function pairWith(Chest $tile) : bool{ if($this->isPaired() or $tile->isPaired()){ return false; } @@ -202,7 +202,7 @@ class Chest extends Spawnable implements Container, Nameable{ return true; } - private function createPair(Chest $tile){ + private function createPair(Chest $tile) : void{ $this->pairX = $tile->getPos()->x; $this->pairZ = $tile->getPos()->z; @@ -210,7 +210,7 @@ class Chest extends Spawnable implements Container, Nameable{ $tile->pairZ = $this->getPos()->z; } - public function unpair(){ + public function unpair() : bool{ if(!$this->isPaired()){ return false; } diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index 2dc9b4fb37..dbd05dce7b 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -120,7 +120,7 @@ class Furnace extends Spawnable implements Container, Nameable{ return $this->getInventory(); } - protected function checkFuel(Item $fuel){ + protected function checkFuel(Item $fuel) : void{ $ev = new FurnaceBurnEvent($this, $fuel, $fuel->getFuelTime()); $ev->call(); if($ev->isCancelled()){ diff --git a/src/command/PluginCommand.php b/src/command/PluginCommand.php index a6cce85551..87c96bb320 100644 --- a/src/command/PluginCommand.php +++ b/src/command/PluginCommand.php @@ -72,7 +72,7 @@ class PluginCommand extends Command implements PluginIdentifiableCommand{ /** * @param CommandExecutor $executor */ - public function setExecutor(CommandExecutor $executor){ + public function setExecutor(CommandExecutor $executor) : void{ $this->executor = $executor; } diff --git a/src/inventory/CreativeInventory.php b/src/inventory/CreativeInventory.php index cf45cf7866..d157d79fb5 100644 --- a/src/inventory/CreativeInventory.php +++ b/src/inventory/CreativeInventory.php @@ -38,7 +38,7 @@ final class CreativeInventory{ //NOOP } - public static function init(){ + public static function init() : void{ self::clear(); $creativeItems = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla" . DIRECTORY_SEPARATOR . "creativeitems.json"), true); @@ -56,7 +56,7 @@ final class CreativeInventory{ * Removes all previously added items from the creative menu. * Note: Players who are already online when this is called will not see this change. */ - public static function clear(){ + public static function clear() : void{ self::$creative = []; } @@ -92,7 +92,7 @@ final class CreativeInventory{ * * @param Item $item */ - public static function add(Item $item){ + public static function add(Item $item) : void{ self::$creative[] = clone $item; } @@ -102,7 +102,7 @@ final class CreativeInventory{ * * @param Item $item */ - public static function remove(Item $item){ + public static function remove(Item $item) : void{ $index = self::getItemIndex($item); if($index !== -1){ unset(self::$creative[$index]); diff --git a/src/lang/Language.php b/src/lang/Language.php index 381f136346..4e8d7ff8b7 100644 --- a/src/lang/Language.php +++ b/src/lang/Language.php @@ -140,7 +140,7 @@ class Language{ return $baseText; } - public function translate(TextContainer $c){ + public function translate(TextContainer $c) : string{ if($c instanceof TranslationContainer){ $baseText = $this->internalGet($c->getText()); $baseText = $this->parseTranslation($baseText ?? $c->getText()); diff --git a/src/network/mcpe/protocol/DataPacket.php b/src/network/mcpe/protocol/DataPacket.php index 7e90ce6c9d..81543f4242 100644 --- a/src/network/mcpe/protocol/DataPacket.php +++ b/src/network/mcpe/protocol/DataPacket.php @@ -104,7 +104,7 @@ abstract class DataPacket extends NetworkBinaryStream implements Packet{ */ abstract protected function encodePayload() : void; - public function __debugInfo(){ + public function __debugInfo() : array{ $data = []; foreach((array) $this as $k => $v){ if($v === $this->getBuffer()){ @@ -121,6 +121,8 @@ abstract class DataPacket extends NetworkBinaryStream implements Packet{ /** * @param string $name + * + * @return mixed */ public function __get($name){ throw new \Error("Undefined property: " . get_class($this) . "::\$" . $name); @@ -130,7 +132,7 @@ abstract class DataPacket extends NetworkBinaryStream implements Packet{ * @param string $name * @param mixed $value */ - public function __set($name, $value){ + public function __set($name, $value) : void{ throw new \Error("Undefined property: " . get_class($this) . "::\$" . $name); } } diff --git a/src/permission/DefaultPermissions.php b/src/permission/DefaultPermissions.php index 1ae419c3fb..ea25519c7d 100644 --- a/src/permission/DefaultPermissions.php +++ b/src/permission/DefaultPermissions.php @@ -43,7 +43,7 @@ abstract class DefaultPermissions{ return PermissionManager::getInstance()->getPermission($perm->getName()); } - public static function registerCorePermissions(){ + public static function registerCorePermissions() : void{ $parent = self::registerPermission(new Permission(self::ROOT, "Allows using all PocketMine commands and utilities")); $broadcasts = self::registerPermission(new Permission(self::ROOT . ".broadcast", "Allows the user to receive all broadcast messages"), $parent); diff --git a/src/player/OfflinePlayer.php b/src/player/OfflinePlayer.php index 7768bf62f8..8dcca0a88f 100644 --- a/src/player/OfflinePlayer.php +++ b/src/player/OfflinePlayer.php @@ -54,7 +54,7 @@ class OfflinePlayer implements IPlayer{ return $this->name; } - public function getServer(){ + public function getServer() : Server{ return $this->server; } diff --git a/src/player/Player.php b/src/player/Player.php index a10c280696..fe1989d133 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -464,7 +464,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->lastPlayed - $this->firstPlayed > 1; // microtime(true) - microtime(true) may have less than one millisecond difference } - public function setAllowFlight(bool $value){ + public function setAllowFlight(bool $value) : void{ $this->allowFlight = $value; $this->networkSession->syncAdventureSettings($this); } @@ -473,7 +473,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->allowFlight; } - public function setFlying(bool $value){ + public function setFlying(bool $value) : void{ if($this->flying !== $value){ $this->flying = $value; $this->resetFallDistance(); @@ -485,7 +485,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->flying; } - public function setAutoJump(bool $value){ + public function setAutoJump(bool $value) : void{ $this->autoJump = $value; $this->networkSession->syncAdventureSettings($this); } @@ -520,7 +520,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * @param bool $remove */ - public function setRemoveFormat(bool $remove = true){ + public function setRemoveFormat(bool $remove = true) : void{ $this->removeFormat = $remove; } @@ -547,7 +547,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * @param Player $player */ - public function hidePlayer(Player $player){ + public function hidePlayer(Player $player) : void{ if($player === $this){ return; } @@ -558,7 +558,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * @param Player $player */ - public function showPlayer(Player $player){ + public function showPlayer(Player $player) : void{ if($player === $this){ return; } @@ -585,7 +585,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->viewDistance; } - public function setViewDistance(int $distance){ + public function setViewDistance(int $distance) : void{ $this->viewDistance = $this->server->getAllowedViewDistance($distance); $this->spawnThreshold = (int) (min($this->viewDistance, $this->server->getProperty("chunk-sending.spawn-radius", 4)) ** 2 * M_PI); @@ -685,7 +685,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * @param string $name */ - public function setDisplayName(string $name){ + public function setDisplayName(string $name) : void{ $this->displayName = $name; } @@ -738,7 +738,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->startAction > -1; } - public function setUsingItem(bool $value){ + public function setUsingItem(bool $value) : void{ $this->startAction = $value ? $this->server->getTick() : -1; } @@ -805,7 +805,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return false; } - protected function unloadChunk(int $x, int $z, ?World $world = null){ + protected function unloadChunk(int $x, int $z, ?World $world = null) : void{ $world = $world ?? $this->getWorld(); $index = World::chunkHash($x, $z); if(isset($this->usedChunks[$index])){ @@ -830,7 +830,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } - protected function requestChunks(){ + protected function requestChunks() : void{ if(!$this->isConnected()){ return; } @@ -883,7 +883,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, Timings::$playerChunkSendTimer->stopTiming(); } - public function doFirstSpawn(){ + public function doFirstSpawn() : void{ if($this->hasPermission(Server::BROADCAST_CHANNEL_USERS)){ PermissionManager::getInstance()->subscribeToPermission(Server::BROADCAST_CHANNEL_USERS, $this); } @@ -986,7 +986,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return isset($this->usedChunks[World::chunkHash($chunkX, $chunkZ)]); } - public function doChunkRequests(){ + public function doChunkRequests() : void{ if($this->nextChunkOrderRun !== PHP_INT_MAX and $this->nextChunkOrderRun-- <= 0){ $this->nextChunkOrderRun = PHP_INT_MAX; $this->orderChunks(); @@ -1023,7 +1023,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * * @param Vector3|Position $pos */ - public function setSpawn(Vector3 $pos){ + public function setSpawn(Vector3 $pos) : void{ if(!($pos instanceof Position)){ $world = $this->getWorld(); }else{ @@ -1068,7 +1068,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return true; } - public function stopSleep(){ + public function stopSleep() : void{ if($this->sleeping instanceof Vector3){ $b = $this->getWorld()->getBlock($this->sleeping); if($b instanceof Bed){ @@ -1218,7 +1218,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return false; //currently has no server-side movement } - protected function checkNearEntities(){ + protected function checkNearEntities() : void{ foreach($this->getWorld()->getNearbyEntities($this->boundingBox->expandedCopy(1, 0.5, 1), $this) as $entity){ $entity->scheduleUpdate(); @@ -1274,7 +1274,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->inAirTicks; } - protected function processMovement(int $tickDiff){ + protected function processMovement(int $tickDiff) : void{ if($this->newPosition === null or $this->isSleeping()){ return; } @@ -1923,14 +1923,14 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Removes the title from the client's screen. */ - public function removeTitles(){ + public function removeTitles() : void{ $this->networkSession->onClearTitle(); } /** * Resets the title duration settings to defaults and removes any existing titles. */ - public function resetTitles(){ + public function resetTitles() : void{ $this->networkSession->onResetTitleOptions(); } @@ -1941,7 +1941,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @param int $stay Title stay time in ticks. * @param int $fadeOut Title fade-out time in ticks. */ - public function setTitleDuration(int $fadeIn, int $stay, int $fadeOut){ + public function setTitleDuration(int $fadeIn, int $stay, int $fadeOut) : void{ if($fadeIn >= 0 and $stay >= 0 and $fadeOut >= 0){ $this->networkSession->onTitleDuration($fadeIn, $stay, $fadeOut); } @@ -1968,7 +1968,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @param string $message * @param string[] $parameters */ - public function sendTranslation(string $message, array $parameters = []){ + public function sendTranslation(string $message, array $parameters = []) : void{ if(!$this->server->isLanguageForced()){ foreach($parameters as $i => $p){ $parameters[$i] = $this->server->getLanguage()->translateString($p, [], "pocketmine."); @@ -1986,11 +1986,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * * @param string $message */ - public function sendPopup(string $message){ + public function sendPopup(string $message) : void{ $this->networkSession->onPopup($message); } - public function sendTip(string $message){ + public function sendTip(string $message) : void{ $this->networkSession->onTip($message); } @@ -2160,7 +2160,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, parent::destroyCycles(); } - public function __debugInfo(){ + public function __debugInfo() : array{ return []; } @@ -2182,7 +2182,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * * @throws \InvalidStateException if the player is closed */ - public function save(){ + public function save() : void{ if($this->closed){ throw new \InvalidStateException("Tried to save closed player"); } @@ -2353,7 +2353,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @param float|null $pitch * @param int $mode */ - public function sendPosition(Vector3 $pos, ?float $yaw = null, ?float $pitch = null, int $mode = MovePlayerPacket::MODE_NORMAL){ + public function sendPosition(Vector3 $pos, ?float $yaw = null, ?float $pitch = null, int $mode = MovePlayerPacket::MODE_NORMAL) : void{ $this->networkSession->syncMovement($pos, $yaw, $pitch, $mode); //TODO: get rid of this @@ -2390,7 +2390,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return false; } - protected function addDefaultWindows(){ + protected function addDefaultWindows() : void{ $this->cursorInventory = new PlayerCursorInventory($this); $this->craftingGrid = new CraftingGrid($this, CraftingGrid::SIZE_SMALL); diff --git a/src/plugin/PluginBase.php b/src/plugin/PluginBase.php index eb1f56a809..dbc51b9800 100644 --- a/src/plugin/PluginBase.php +++ b/src/plugin/PluginBase.php @@ -100,6 +100,8 @@ abstract class PluginBase implements Plugin, CommandExecutor{ /** * Called when the plugin is loaded, before calling onEnable() + * + * @return void */ protected function onLoad()/* : void /* TODO: uncomment this for next major version */{ @@ -107,6 +109,8 @@ abstract class PluginBase implements Plugin, CommandExecutor{ /** * Called when the plugin is enabled + * + * @return void */ protected function onEnable()/* : void /* TODO: uncomment this for next major version */{ @@ -115,6 +119,8 @@ abstract class PluginBase implements Plugin, CommandExecutor{ /** * Called when the plugin is disabled * Use this to free open things and finish actions + * + * @return void */ protected function onDisable()/* : void /* TODO: uncomment this for next major version */{ @@ -320,7 +326,7 @@ abstract class PluginBase implements Plugin, CommandExecutor{ return $this->config; } - public function saveConfig(){ + public function saveConfig() : void{ $this->getConfig()->save(); } @@ -331,7 +337,7 @@ abstract class PluginBase implements Plugin, CommandExecutor{ return false; } - public function reloadConfig(){ + public function reloadConfig() : void{ $this->saveDefaultConfig(); $this->config = new Config($this->configFile); } diff --git a/src/scheduler/Task.php b/src/scheduler/Task.php index 9fd170c83b..38085092bd 100644 --- a/src/scheduler/Task.php +++ b/src/scheduler/Task.php @@ -72,6 +72,8 @@ abstract class Task{ /** * Actions to execute if the Task is cancelled + * + * @return void */ public function onCancel(){ diff --git a/src/thread/CommonThreadPartsTrait.php b/src/thread/CommonThreadPartsTrait.php index 0c5a84eac1..e6cd6af54b 100644 --- a/src/thread/CommonThreadPartsTrait.php +++ b/src/thread/CommonThreadPartsTrait.php @@ -35,7 +35,7 @@ trait CommonThreadPartsTrait{ /** @var bool */ protected $isKilled = false; - public function getClassLoader(){ + public function getClassLoader() : ?\ClassLoader{ return $this->classLoader; } diff --git a/src/utils/Config.php b/src/utils/Config.php index c23b8b668b..2eea39ea82 100644 --- a/src/utils/Config.php +++ b/src/utils/Config.php @@ -319,7 +319,7 @@ class Config{ * @param string $k * @param mixed $v */ - public function __set($k, $v){ + public function __set($k, $v) : void{ $this->set($k, $v); } diff --git a/src/utils/MainLogger.php b/src/utils/MainLogger.php index af7afb8e5f..dc5e7e0d20 100644 --- a/src/utils/MainLogger.php +++ b/src/utils/MainLogger.php @@ -151,6 +151,8 @@ class MainLogger extends \AttachableThreadedLogger{ /** * @param \Throwable $e * @param array|null $trace + * + * @return void */ public function logException(\Throwable $e, $trace = null){ if($trace === null){ diff --git a/src/world/World.php b/src/world/World.php index c81d1e482a..7a5a8f4f8c 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -386,7 +386,7 @@ class World implements ChunkManager{ $this->server->getAsyncPool()->submitTaskToWorker(new GeneratorRegisterTask($this, $this->generator, $this->provider->getWorldData()->getGeneratorOptions()), $worker); } - public function unregisterGenerator(){ + public function unregisterGenerator() : void{ $pool = $this->server->getAsyncPool(); foreach($pool->getRunningWorkers() as $i){ if(isset($this->generatorRegisteredWorkers[$i])){ @@ -422,7 +422,7 @@ class World implements ChunkManager{ /** * @internal */ - public function close(){ + public function close() : void{ if($this->closed){ throw new \InvalidStateException("Tried to close a world which is already closed"); } @@ -443,7 +443,7 @@ class World implements ChunkManager{ $this->closed = true; } - public function addSound(Vector3 $pos, Sound $sound, ?array $players = null){ + public function addSound(Vector3 $pos, Sound $sound, ?array $players = null) : void{ $pk = $sound->encode($pos); if(!is_array($pk)){ $pk = [$pk]; @@ -459,7 +459,7 @@ class World implements ChunkManager{ } } - public function addParticle(Vector3 $pos, Particle $particle, ?array $players = null){ + public function addParticle(Vector3 $pos, Particle $particle, ?array $players = null) : void{ $pk = $particle->encode($pos); if(!is_array($pk)){ $pk = [$pk]; @@ -482,7 +482,7 @@ class World implements ChunkManager{ * @param int $evid * @param int $data */ - public function broadcastLevelEvent(?Vector3 $pos, int $evid, int $data = 0){ + public function broadcastLevelEvent(?Vector3 $pos, int $evid, int $data = 0) : void{ $pk = LevelEventPacket::create($evid, $data, $pos); if($pos !== null){ $this->broadcastPacketToViewers($pos, $pk); @@ -495,7 +495,7 @@ class World implements ChunkManager{ return $this->autoSave; } - public function setAutoSave(bool $value){ + public function setAutoSave(bool $value) : void{ $this->autoSave = $value; } @@ -544,7 +544,7 @@ class World implements ChunkManager{ * @param int $chunkZ * @param ClientboundPacket $packet */ - public function addChunkPacket(int $chunkX, int $chunkZ, ClientboundPacket $packet){ + public function addChunkPacket(int $chunkX, int $chunkZ, ClientboundPacket $packet) : void{ if(!isset($this->chunkPackets[$index = World::chunkHash($chunkX, $chunkZ)])){ $this->chunkPackets[$index] = [$packet]; }else{ @@ -571,7 +571,7 @@ class World implements ChunkManager{ $this->globalPackets[] = $packet; } - public function registerChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ, bool $autoLoad = true){ + public function registerChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ, bool $autoLoad = true) : void{ $loaderId = spl_object_id($loader); if(!isset($this->chunkLoaders[$chunkHash = World::chunkHash($chunkX, $chunkZ)])){ @@ -600,7 +600,7 @@ class World implements ChunkManager{ } } - public function unregisterChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ){ + public function unregisterChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ) : void{ $chunkHash = World::chunkHash($chunkX, $chunkZ); $loaderId = spl_object_id($loader); if(isset($this->chunkLoaders[$chunkHash][$loaderId])){ @@ -689,7 +689,7 @@ class World implements ChunkManager{ * * @param Player ...$targets If empty, will send to all players in the world. */ - public function sendTime(Player ...$targets){ + public function sendTime(Player ...$targets) : void{ $pk = SetTimePacket::create($this->time); if(empty($targets)){ @@ -709,7 +709,7 @@ class World implements ChunkManager{ * @param int $currentTick * */ - public function doTick(int $currentTick){ + public function doTick(int $currentTick) : void{ if($this->closed){ throw new \InvalidStateException("Attempted to tick a world which has been closed"); } @@ -852,7 +852,7 @@ class World implements ChunkManager{ $this->chunkPackets = []; } - public function checkSleep(){ + public function checkSleep() : void{ if(count($this->players) === 0){ return; } @@ -886,7 +886,7 @@ class World implements ChunkManager{ * @param Player[] $target * @param Vector3[] $blocks */ - public function sendBlocks(array $target, array $blocks){ + public function sendBlocks(array $target, array $blocks) : void{ $packets = []; foreach($blocks as $b){ @@ -906,7 +906,7 @@ class World implements ChunkManager{ $this->server->broadcastPackets($target, $packets); } - public function clearCache(bool $force = false){ + public function clearCache(bool $force = false) : void{ if($force){ $this->blockCache = []; }else{ @@ -928,18 +928,18 @@ class World implements ChunkManager{ return $this->randomTickBlocks; } - public function addRandomTickedBlock(Block $block){ + public function addRandomTickedBlock(Block $block) : void{ if($block instanceof UnknownBlock){ throw new \InvalidArgumentException("Cannot do random-tick on unknown block"); } $this->randomTickBlocks[$block->getFullId()] = true; } - public function removeRandomTickedBlock(Block $block){ + public function removeRandomTickedBlock(Block $block) : void{ unset($this->randomTickBlocks[$block->getFullId()]); } - private function tickChunks(){ + private function tickChunks() : void{ if($this->chunksPerTick <= 0 or count($this->loaders) === 0){ return; } @@ -1029,7 +1029,7 @@ class World implements ChunkManager{ return true; } - public function saveChunks(){ + public function saveChunks() : void{ $this->timings->syncChunkSaveTimer->startTiming(); try{ foreach($this->chunks as $chunk){ @@ -1050,7 +1050,7 @@ class World implements ChunkManager{ * @param Vector3 $pos * @param int $delay */ - public function scheduleDelayedBlockUpdate(Vector3 $pos, int $delay){ + public function scheduleDelayedBlockUpdate(Vector3 $pos, int $delay) : void{ if( !$this->isInWorld($pos->x, $pos->y, $pos->z) or (isset($this->scheduledBlockUpdateQueueIndex[$index = World::blockHash($pos->x, $pos->y, $pos->z)]) and $this->scheduledBlockUpdateQueueIndex[$index] <= $delay) @@ -1994,7 +1994,7 @@ class World implements ChunkManager{ * @param int $z * @param int $biomeId */ - public function setBiomeId(int $x, int $z, int $biomeId){ + public function setBiomeId(int $x, int $z, int $biomeId) : void{ $this->getChunk($x >> 4, $z >> 4, true)->setBiomeId($x & 0x0f, $z & 0x0f, $biomeId); } @@ -2076,7 +2076,7 @@ class World implements ChunkManager{ return isset($this->chunkLock[World::chunkHash($chunkX, $chunkZ)]); } - public function generateChunkCallback(int $x, int $z, ?Chunk $chunk){ + public function generateChunkCallback(int $x, int $z, ?Chunk $chunk) : void{ Timings::$generationCallbackTimer->startTiming(); if(isset($this->chunkPopulationQueue[$index = World::chunkHash($x, $z)])){ for($xx = -1; $xx <= 1; ++$xx){ @@ -2234,7 +2234,7 @@ class World implements ChunkManager{ * * @param Vector3 $pos */ - public function setSpawnLocation(Vector3 $pos){ + public function setSpawnLocation(Vector3 $pos) : void{ $previousSpawn = $this->getSpawnLocation(); $this->provider->getWorldData()->setSpawn($pos); (new SpawnChangeEvent($this, $previousSpawn))->call(); @@ -2245,7 +2245,7 @@ class World implements ChunkManager{ * * @throws \InvalidArgumentException */ - public function addEntity(Entity $entity){ + public function addEntity(Entity $entity) : void{ if($entity->isClosed()){ throw new \InvalidArgumentException("Attempted to add a garbage closed Entity to world"); } @@ -2266,7 +2266,7 @@ class World implements ChunkManager{ * * @throws \InvalidArgumentException */ - public function removeEntity(Entity $entity){ + public function removeEntity(Entity $entity) : void{ if($entity->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Entity world"); } @@ -2285,7 +2285,7 @@ class World implements ChunkManager{ * * @throws \InvalidArgumentException */ - public function addTile(Tile $tile){ + public function addTile(Tile $tile) : void{ if($tile->isClosed()){ throw new \InvalidArgumentException("Attempted to add a garbage closed Tile to world"); } @@ -2312,7 +2312,7 @@ class World implements ChunkManager{ * * @throws \InvalidArgumentException */ - public function removeTile(Tile $tile){ + public function removeTile(Tile $tile) : void{ $pos = $tile->getPos(); if($pos->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Tile world"); @@ -2404,11 +2404,11 @@ class World implements ChunkManager{ return true; } - private function queueUnloadChunk(int $x, int $z){ + private function queueUnloadChunk(int $x, int $z) : void{ $this->unloadQueue[World::chunkHash($x, $z)] = microtime(true); } - public function unloadChunkRequest(int $x, int $z, bool $safe = true){ + public function unloadChunkRequest(int $x, int $z, bool $safe = true) : bool{ if(($safe and $this->isChunkInUse($x, $z)) or $this->isSpawnChunk($x, $z)){ return false; } @@ -2418,7 +2418,7 @@ class World implements ChunkManager{ return true; } - public function cancelUnloadChunkRequest(int $x, int $z){ + public function cancelUnloadChunkRequest(int $x, int $z) : void{ unset($this->unloadQueue[World::chunkHash($x, $z)]); } @@ -2574,7 +2574,7 @@ class World implements ChunkManager{ * * @param int $time */ - public function setTime(int $time){ + public function setTime(int $time) : void{ $this->time = $time; $this->sendTime(); } @@ -2582,7 +2582,7 @@ class World implements ChunkManager{ /** * Stops the time for the world, will not save the lock state to disk */ - public function stopTime(){ + public function stopTime() : void{ $this->stopTime = true; $this->sendTime(); } @@ -2590,7 +2590,7 @@ class World implements ChunkManager{ /** * Start the time again, if it was stopped */ - public function startTime(){ + public function startTime() : void{ $this->stopTime = false; $this->sendTime(); } @@ -2618,7 +2618,7 @@ class World implements ChunkManager{ /** * @param int $difficulty */ - public function setDifficulty(int $difficulty){ + public function setDifficulty(int $difficulty) : void{ if($difficulty < 0 or $difficulty > 3){ throw new \InvalidArgumentException("Invalid difficulty level $difficulty"); } @@ -2630,7 +2630,7 @@ class World implements ChunkManager{ /** * @param Player ...$targets */ - public function sendDifficulty(Player ...$targets){ + public function sendDifficulty(Player ...$targets) : void{ $pk = SetDifficultyPacket::create($this->getDifficulty()); if(empty($targets)){ $this->broadcastGlobalPacket($pk); @@ -2676,7 +2676,7 @@ class World implements ChunkManager{ return true; } - public function doChunkGarbageCollection(){ + public function doChunkGarbageCollection() : void{ $this->timings->doChunkGC->startTiming(); foreach($this->chunks as $index => $chunk){ @@ -2694,7 +2694,7 @@ class World implements ChunkManager{ $this->timings->doChunkGC->stopTiming(); } - public function unloadChunks(bool $force = false){ + public function unloadChunks(bool $force = false) : void{ if(count($this->unloadQueue) > 0){ $maxUnload = 96; $now = microtime(true); diff --git a/src/world/format/SubChunk.php b/src/world/format/SubChunk.php index d0e1c2f181..0dad3fbb43 100644 --- a/src/world/format/SubChunk.php +++ b/src/world/format/SubChunk.php @@ -111,7 +111,7 @@ class SubChunk implements SubChunkInterface{ $this->blockLight = $data; } - public function __debugInfo(){ + public function __debugInfo() : array{ return []; } From 545f04b2c8649b5b4f344ec17bac85a29acccca3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 20 Jan 2020 17:28:26 +0000 Subject: [PATCH 1343/3224] Utils: apply phpstan generics to cloneObjectArray() --- src/utils/Utils.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/utils/Utils.php b/src/utils/Utils.php index c34a771f4c..3da8fcfdd8 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -143,6 +143,15 @@ class Utils{ }; } + /** + * @phpstan-template T of object + * + * @param object[] $array + * @phpstan-param T[] $array + * + * @return object[] + * @phpstan-return T[] + */ public static function cloneObjectArray(array $array) : array{ return array_map(self::cloneCallback(), $array); } From ccdf003c8d8dadb02475b0294a562725081ef475 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 22 Jan 2020 08:26:44 +0000 Subject: [PATCH 1344/3224] ResourcePacksPacketHandler: fixed chemistry being applied to top of stack instead of bottom it seems like the stack order is reversed, so all 'regular' in-memory stack behaviour goes out of the window. --- src/network/mcpe/handler/ResourcePacksPacketHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/handler/ResourcePacksPacketHandler.php b/src/network/mcpe/handler/ResourcePacksPacketHandler.php index 008c88abdf..ea97d9f47b 100644 --- a/src/network/mcpe/handler/ResourcePacksPacketHandler.php +++ b/src/network/mcpe/handler/ResourcePacksPacketHandler.php @@ -115,7 +115,7 @@ class ResourcePacksPacketHandler extends PacketHandler{ }, $this->resourcePackManager->getResourceStack()); //we support chemistry blocks by default, the client should already have this installed - array_unshift($stack, new ResourcePackStackEntry("0fba4063-dba1-4281-9b89-ff9390653530", "1.0.0", "")); + $stack[] = new ResourcePackStackEntry("0fba4063-dba1-4281-9b89-ff9390653530", "1.0.0", ""); //we don't force here, because it doesn't have user-facing effects //but it does have an annoying side-effect when true: it makes From 67bcc1c0fb3bbfc97ce70b0219c34607ac0645ed Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 22 Jan 2020 11:55:03 +0000 Subject: [PATCH 1345/3224] phpdoc armageddon for master, pass 1 --- src/MemoryManager.php | 32 --- src/Server.php | 214 -------------- src/block/Banner.php | 1 - src/block/BaseRail.php | 6 - src/block/Bed.php | 9 - src/block/Block.php | 121 -------- src/block/BlockBreakInfo.php | 23 -- src/block/BlockFactory.php | 11 - src/block/BlockIdentifier.php | 12 - src/block/BlockIdentifierFlattened.php | 3 - src/block/ConcretePowder.php | 6 - src/block/DaylightSensor.php | 2 - src/block/DoublePlant.php | 1 - src/block/Element.php | 9 - src/block/FlowerPot.php | 6 - src/block/Furnace.php | 2 - src/block/ItemFrame.php | 24 -- src/block/Liquid.php | 4 - src/block/NetherPortal.php | 4 - src/block/Note.php | 6 - src/block/RedstoneComparator.php | 20 -- src/block/RedstoneLamp.php | 2 - src/block/RedstoneOre.php | 2 - src/block/RedstoneRepeater.php | 2 - src/block/RedstoneTorch.php | 2 - src/block/Sign.php | 5 - src/block/Skull.php | 3 - src/block/Slab.php | 4 - src/block/VanillaBlocks.php | 5 - src/block/Wood.php | 1 - src/block/tile/Banner.php | 4 - src/block/tile/Chest.php | 6 - src/block/tile/Comparator.php | 6 - src/block/tile/Container.php | 4 - src/block/tile/ContainerTrait.php | 5 - src/block/tile/EnchantTable.php | 3 - src/block/tile/Furnace.php | 3 - src/block/tile/Nameable.php | 12 - src/block/tile/NameableTrait.php | 13 - src/block/tile/Note.php | 6 - src/block/tile/Sign.php | 6 - src/block/tile/Spawnable.php | 10 - src/block/tile/Tile.php | 12 - src/block/tile/TileFactory.php | 10 - src/block/utils/BannerPattern.php | 6 - src/block/utils/BlockDataSerializer.php | 12 - src/block/utils/DyeColor.php | 14 - src/block/utils/Fallable.php | 2 - src/block/utils/PillarRotationTrait.php | 15 - src/block/utils/SignText.php | 9 - src/block/utils/SkullType.php | 8 - src/block/utils/TreeType.php | 14 - src/command/Command.php | 67 ----- src/command/CommandExecutor.php | 5 - src/command/CommandMap.php | 22 -- src/command/CommandReader.php | 4 - src/command/CommandSender.php | 10 - src/command/ConsoleCommandSender.php | 12 - src/command/FormattedCommandAlias.php | 14 - src/command/PluginCommand.php | 11 - src/command/PluginIdentifiableCommand.php | 3 - src/command/SimpleCommandMap.php | 26 -- src/command/defaults/ParticleCommand.php | 6 - src/command/defaults/VanillaCommand.php | 19 -- src/crafting/CraftingGrid.php | 8 - src/crafting/CraftingManager.php | 24 -- src/crafting/CraftingRecipe.php | 6 - src/crafting/FurnaceRecipe.php | 10 - src/crafting/ShapedRecipe.php | 19 -- src/crafting/ShapelessRecipe.php | 8 - src/entity/Attribute.php | 23 -- src/entity/AttributeMap.php | 5 - src/entity/Entity.php | 113 -------- src/entity/EntityFactory.php | 16 -- src/entity/ExperienceManager.php | 43 --- src/entity/Human.php | 18 -- src/entity/HungerManager.php | 23 -- src/entity/Living.php | 48 ---- src/entity/Location.php | 5 - src/entity/Skin.php | 15 - src/entity/Villager.php | 2 - src/entity/effect/Effect.php | 22 -- src/entity/effect/EffectInstance.php | 39 --- src/entity/effect/EffectManager.php | 18 -- src/entity/effect/VanillaEffects.php | 10 - src/entity/object/ExperienceOrb.php | 6 - src/entity/object/ItemEntity.php | 25 -- src/entity/object/Painting.php | 14 - src/entity/object/PaintingMotive.php | 17 -- src/entity/projectile/Arrow.php | 12 - src/entity/projectile/Projectile.php | 17 -- src/entity/projectile/SplashPotion.php | 7 - src/entity/utils/ExperienceUtils.php | 12 - src/event/Cancellable.php | 6 - src/event/CancellableTrait.php | 6 - src/event/Event.php | 3 - src/event/EventPriority.php | 4 - src/event/HandlerList.php | 7 - src/event/HandlerListManager.php | 7 - src/event/RegisteredListener.php | 20 -- src/event/block/BlockBreakEvent.php | 16 -- src/event/block/BlockBurnEvent.php | 1 - src/event/block/BlockEvent.php | 6 - src/event/block/BlockGrowEvent.php | 3 - src/event/block/BlockPlaceEvent.php | 8 - src/event/block/BlockSpreadEvent.php | 3 - src/event/block/BlockTeleportEvent.php | 10 - src/event/block/SignChangeEvent.php | 17 -- src/event/entity/EntityBlockChangeEvent.php | 6 - .../entity/EntityCombustByBlockEvent.php | 8 - .../entity/EntityCombustByEntityEvent.php | 8 - src/event/entity/EntityCombustEvent.php | 5 - src/event/entity/EntityDamageByBlockEvent.php | 7 - .../entity/EntityDamageByChildEntityEvent.php | 7 - .../entity/EntityDamageByEntityEvent.php | 13 - src/event/entity/EntityDamageEvent.php | 40 --- src/event/entity/EntityDeathEvent.php | 5 - src/event/entity/EntityDespawnEvent.php | 3 - src/event/entity/EntityEffectAddEvent.php | 10 - src/event/entity/EntityExplodeEvent.php | 12 - src/event/entity/EntityMotionEvent.php | 3 - src/event/entity/EntityRegainHealthEvent.php | 13 - src/event/entity/EntityShootBowEvent.php | 20 -- src/event/entity/EntitySpawnEvent.php | 3 - src/event/entity/EntityTeleportEvent.php | 9 - src/event/entity/ExplosionPrimeEvent.php | 13 - src/event/entity/ItemDespawnEvent.php | 3 - src/event/entity/ItemSpawnEvent.php | 3 - src/event/entity/ProjectileHitBlockEvent.php | 2 - src/event/entity/ProjectileHitEntityEvent.php | 2 - src/event/entity/ProjectileHitEvent.php | 6 - src/event/entity/ProjectileLaunchEvent.php | 3 - src/event/inventory/CraftItemEvent.php | 12 - src/event/inventory/FurnaceBurnEvent.php | 23 -- src/event/inventory/FurnaceSmeltEvent.php | 17 -- src/event/inventory/InventoryCloseEvent.php | 7 - src/event/inventory/InventoryEvent.php | 3 - src/event/inventory/InventoryOpenEvent.php | 7 - .../inventory/InventoryPickupArrowEvent.php | 7 - .../inventory/InventoryPickupItemEvent.php | 7 - .../inventory/InventoryTransactionEvent.php | 6 - src/event/player/PlayerBedEnterEvent.php | 3 - src/event/player/PlayerBedLeaveEvent.php | 3 - src/event/player/PlayerBucketEvent.php | 20 -- src/event/player/PlayerChangeSkinEvent.php | 13 - src/event/player/PlayerChatEvent.php | 17 -- .../player/PlayerCommandPreprocessEvent.php | 14 - src/event/player/PlayerCreationEvent.php | 13 - src/event/player/PlayerDataSaveEvent.php | 5 - src/event/player/PlayerDeathEvent.php | 10 - src/event/player/PlayerDropItemEvent.php | 7 - .../player/PlayerDuplicateLoginEvent.php | 5 - src/event/player/PlayerEditBookEvent.php | 8 - src/event/player/PlayerExhaustEvent.php | 1 - .../player/PlayerExperienceChangeEvent.php | 12 - src/event/player/PlayerInteractEvent.php | 23 -- src/event/player/PlayerItemConsumeEvent.php | 7 - src/event/player/PlayerItemHeldEvent.php | 4 - src/event/player/PlayerItemUseEvent.php | 9 - src/event/player/PlayerJoinEvent.php | 1 - src/event/player/PlayerJumpEvent.php | 2 - src/event/player/PlayerKickEvent.php | 5 - src/event/player/PlayerLoginEvent.php | 10 - src/event/player/PlayerMoveEvent.php | 14 - src/event/player/PlayerPreLoginEvent.php | 35 --- src/event/player/PlayerQuitEvent.php | 5 - src/event/player/PlayerRespawnEvent.php | 10 - src/event/player/PlayerToggleFlightEvent.php | 7 - src/event/player/PlayerToggleSneakEvent.php | 7 - src/event/player/PlayerToggleSprintEvent.php | 7 - src/event/player/PlayerTransferEvent.php | 24 -- src/event/plugin/PluginEvent.php | 3 - src/event/server/CommandEvent.php | 13 - src/event/server/DataPacketReceiveEvent.php | 10 - src/event/server/LowMemoryEvent.php | 11 - src/event/server/NetworkInterfaceEvent.php | 6 - src/event/server/QueryRegenerateEvent.php | 45 --- src/event/world/ChunkEvent.php | 7 - src/event/world/ChunkLoadEvent.php | 3 - src/event/world/SpawnChangeEvent.php | 7 - src/event/world/WorldEvent.php | 6 - src/form/Form.php | 1 - src/inventory/BaseInventory.php | 7 - src/inventory/ChestInventory.php | 3 - src/inventory/CreativeInventory.php | 9 - src/inventory/DoubleChestInventory.php | 6 - src/inventory/EnderChestInventory.php | 3 - src/inventory/FurnaceInventory.php | 18 -- src/inventory/Inventory.php | 58 ---- src/inventory/PlayerInventory.php | 15 - .../transaction/CraftingTransaction.php | 3 - .../transaction/InventoryTransaction.php | 16 -- .../transaction/action/DropItemAction.php | 2 - .../transaction/action/InventoryAction.php | 14 - .../transaction/action/SlotChangeAction.php | 18 -- src/item/Armor.php | 8 - src/item/ArmorTypeInfo.php | 9 - src/item/Banner.php | 3 - src/item/Bed.php | 3 - src/item/Boat.php | 3 - src/item/Consumable.php | 2 - src/item/Durable.php | 8 - src/item/Dye.php | 3 - src/item/FoodSource.php | 1 - src/item/Item.php | 102 ------- src/item/ItemBlock.php | 2 - src/item/ItemEnchantmentHandlingTrait.php | 23 -- src/item/ItemFactory.php | 18 -- src/item/LiquidBucket.php | 3 - src/item/Potion.php | 2 - src/item/ProjectileItem.php | 2 - src/item/SpawnEgg.php | 4 - src/item/ToolTier.php | 12 - src/item/VanillaItems.php | 5 - src/item/WritableBookBase.php | 20 -- src/item/WritableBookPage.php | 6 - src/item/WrittenBook.php | 12 - src/item/enchantment/Enchantment.php | 36 --- src/item/enchantment/EnchantmentEntry.php | 2 - src/item/enchantment/EnchantmentInstance.php | 3 - src/item/enchantment/EnchantmentList.php | 9 - .../enchantment/MeleeWeaponEnchantment.php | 12 - .../enchantment/ProtectionEnchantment.php | 16 -- src/lang/Language.php | 27 -- src/lang/TextContainer.php | 12 - src/lang/TranslationContainer.php | 6 - src/network/AdvancedNetworkInterface.php | 12 - src/network/Network.php | 30 -- src/network/NetworkInterface.php | 3 - src/network/NetworkSessionManager.php | 12 - src/network/RawPacketHandler.php | 8 - src/network/mcpe/ChunkCache.php | 21 -- src/network/mcpe/NetworkSession.php | 43 --- src/network/mcpe/PacketBatch.php | 1 - src/network/mcpe/PacketSender.php | 5 - src/network/mcpe/auth/ProcessLoginTask.php | 4 - .../mcpe/compression/CompressBatchPromise.php | 3 - .../mcpe/compression/CompressBatchTask.php | 5 - src/network/mcpe/compression/Zlib.php | 5 - src/network/mcpe/encryption/NetworkCipher.php | 3 - .../mcpe/handler/InGamePacketHandler.php | 6 - .../mcpe/handler/LoginPacketHandler.php | 3 - src/network/mcpe/protocol/AddEntityPacket.php | 3 - .../mcpe/protocol/AvailableCommandsPacket.php | 10 - .../protocol/ClientCacheBlobStatusPacket.php | 2 - .../ClientCacheMissResponsePacket.php | 2 - .../mcpe/protocol/ClientCacheStatusPacket.php | 3 - .../mcpe/protocol/CommandOutputPacket.php | 1 - .../mcpe/protocol/CraftingDataPacket.php | 4 - src/network/mcpe/protocol/EmotePacket.php | 1 - .../mcpe/protocol/InventoryContentPacket.php | 1 - .../mcpe/protocol/LevelChunkPacket.php | 15 - .../mcpe/protocol/LevelEventGenericPacket.php | 6 - src/network/mcpe/protocol/LoginPacket.php | 2 - .../mcpe/protocol/MoveActorDeltaPacket.php | 6 - src/network/mcpe/protocol/Packet.php | 6 - src/network/mcpe/protocol/PacketPool.php | 11 - .../mcpe/protocol/PlayerAuthInputPacket.php | 11 - .../mcpe/protocol/RemoveEntityPacket.php | 3 - .../mcpe/protocol/ResourcePackStackPacket.php | 2 - .../mcpe/protocol/ResourcePacksInfoPacket.php | 2 - src/network/mcpe/protocol/TextPacket.php | 3 - .../mcpe/protocol/UpdateAttributesPacket.php | 1 - .../mcpe/protocol/types/ChunkCacheBlob.php | 9 - .../protocol/types/RuntimeBlockMapping.php | 8 - .../mcpe/protocol/types/SkinAdapter.php | 6 - .../mcpe/protocol/types/SkinAnimation.php | 6 - src/network/mcpe/protocol/types/SkinData.php | 40 --- .../protocol/types/command/CommandData.php | 20 -- .../protocol/types/command/CommandEnum.php | 4 - .../types/command/CommandEnumConstraint.php | 2 - .../types/entity/BlockPosMetadataProperty.php | 6 - .../entity/CompoundTagMetadataProperty.php | 9 - .../types/entity/EntityMetadataCollection.php | 50 ---- .../types/entity/FloatMetadataProperty.php | 6 - .../entity/IntegerishMetadataProperty.php | 6 - .../types/entity/StringMetadataProperty.php | 3 - .../types/entity/Vec3MetadataProperty.php | 6 - .../inventory/NetworkInventoryAction.php | 8 - .../inventory/ReleaseItemTransactionData.php | 12 - .../types/inventory/TransactionData.php | 7 - .../UseItemOnEntityTransactionData.php | 18 -- .../inventory/UseItemTransactionData.php | 24 -- .../resourcepacks/ResourcePackInfoEntry.php | 21 -- .../resourcepacks/ResourcePackStackEntry.php | 9 - .../mcpe/serializer/ChunkSerializer.php | 10 - .../mcpe/serializer/NetworkBinaryStream.php | 33 --- src/network/query/QueryHandler.php | 8 - src/permission/BanEntry.php | 14 - src/permission/BanList.php | 31 -- src/permission/DefaultPermissions.php | 3 - src/permission/Permissible.php | 16 -- src/permission/PermissibleBase.php | 21 -- src/permission/PermissibleDelegateTrait.php | 11 - src/permission/Permission.php | 18 -- src/permission/PermissionAttachment.php | 19 -- src/permission/PermissionAttachmentInfo.php | 17 -- src/permission/PermissionManager.php | 44 --- src/permission/PermissionParser.php | 14 - src/permission/PermissionRemovedExecutor.php | 5 - src/permission/ServerOperator.php | 4 - src/player/GameMode.php | 11 - src/player/IPlayer.php | 30 -- src/player/OfflinePlayer.php | 4 - src/player/Player.php | 164 ----------- src/player/PlayerInfo.php | 26 -- src/plugin/ApiVersion.php | 3 - src/plugin/DiskResourceProvider.php | 2 - src/plugin/PharPluginLoader.php | 6 - src/plugin/Plugin.php | 28 -- src/plugin/PluginBase.php | 46 --- src/plugin/PluginDescription.php | 41 --- src/plugin/PluginGraylist.php | 7 - src/plugin/PluginLoader.php | 12 - src/plugin/PluginManager.php | 37 --- src/plugin/ResourceProvider.php | 2 - src/plugin/ScriptPluginLoader.php | 6 - src/resourcepacks/ResourcePack.php | 5 - src/resourcepacks/ResourcePackManager.php | 7 - src/resourcepacks/ZippedResourcePack.php | 4 - src/scheduler/AsyncPool.php | 21 -- src/scheduler/AsyncTask.php | 11 - src/scheduler/AsyncWorker.php | 5 - src/scheduler/BulkCurlTask.php | 2 - src/scheduler/CancellableClosureTask.php | 2 - src/scheduler/DumpWorkerMemoryTask.php | 5 - src/scheduler/FileWriteTask.php | 2 - src/scheduler/SendUsageTask.php | 5 - src/scheduler/Task.php | 8 - src/scheduler/TaskHandler.php | 40 --- src/scheduler/TaskScheduler.php | 47 --- src/thread/ThreadManager.php | 3 - src/timings/Timings.php | 27 -- src/timings/TimingsHandler.php | 3 - src/updater/AutoUpdater.php | 16 -- src/utils/Color.php | 21 -- src/utils/Config.php | 43 --- src/utils/EnumTrait.php | 15 - src/utils/Filesystem.php | 3 - src/utils/Git.php | 7 - src/utils/Internet.php | 7 - src/utils/MainLogger.php | 11 - src/utils/Process.php | 2 - src/utils/Random.php | 12 - src/utils/RegistryTrait.php | 10 - src/utils/Terminal.php | 6 - src/utils/TextFormat.php | 14 - src/utils/UUID.php | 10 - src/utils/Utils.php | 46 --- src/utils/VersionString.php | 11 - src/world/BlockTransaction.php | 27 -- src/world/ChunkListener.php | 11 - src/world/ChunkManager.php | 30 -- src/world/Explosion.php | 6 - src/world/Position.php | 12 - src/world/SimpleChunkManager.php | 14 - src/world/World.php | 267 ------------------ src/world/WorldManager.php | 53 ---- src/world/biome/Biome.php | 11 - src/world/format/Chunk.php | 80 ------ src/world/format/SubChunk.php | 3 - src/world/format/SubChunkInterface.php | 35 --- src/world/format/io/BaseWorldProvider.php | 12 - src/world/format/io/ChunkUtils.php | 2 - src/world/format/io/FastChunkSerializer.php | 8 - src/world/format/io/WorldData.php | 33 --- src/world/format/io/WorldProvider.php | 23 -- src/world/format/io/WorldProviderManager.php | 14 - src/world/format/io/WritableWorldProvider.php | 8 - src/world/format/io/data/BaseNbtWorldData.php | 3 - src/world/format/io/leveldb/LevelDB.php | 15 - .../io/region/LegacyAnvilChunkTrait.php | 3 - src/world/format/io/region/McRegion.php | 6 - src/world/format/io/region/RegionLoader.php | 20 -- .../io/region/RegionLocationTableEntry.php | 19 -- .../format/io/region/RegionWorldProvider.php | 29 -- src/world/generator/Flat.php | 6 - src/world/generator/Generator.php | 8 - src/world/generator/GeneratorManager.php | 2 - src/world/generator/biome/BiomeSelector.php | 5 - src/world/generator/hell/Nether.php | 4 - src/world/generator/noise/Noise.php | 33 --- src/world/generator/normal/Normal.php | 4 - src/world/generator/object/Tree.php | 5 - src/world/generator/populator/Populator.php | 6 - src/world/particle/FloatingTextParticle.php | 4 - src/world/particle/Particle.php | 2 - src/world/particle/PotionSplashParticle.php | 5 - src/world/sound/ClickSound.php | 3 - src/world/sound/DoorSound.php | 3 - src/world/sound/FizzSound.php | 3 - src/world/sound/LaunchSound.php | 3 - src/world/sound/NoteInstrument.php | 3 - src/world/sound/PopSound.php | 3 - src/world/sound/Sound.php | 2 - src/world/sound/XpLevelUpSound.php | 3 - src/world/utils/SubChunkIteratorManager.php | 2 - 397 files changed, 5391 deletions(-) diff --git a/src/MemoryManager.php b/src/MemoryManager.php index 008e720e9b..adce630852 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -174,33 +174,20 @@ class MemoryManager{ gc_enable(); } - /** - * @return bool - */ public function isLowMemory() : bool{ return $this->lowMemory; } - /** - * @return int - */ public function getGlobalMemoryLimit() : int{ return $this->globalMemoryLimit; } - /** - * @return bool - */ public function canUseChunkCache() : bool{ return !$this->lowMemory or !$this->lowMemDisableChunkCache; } /** * Returns the allowed chunk radius based on the current memory usage. - * - * @param int $distance - * - * @return int */ public function getViewDistance(int $distance) : int{ return ($this->lowMemory and $this->lowMemChunkRadiusOverride > 0) ? (int) min($this->lowMemChunkRadiusOverride, $distance) : $distance; @@ -208,11 +195,6 @@ class MemoryManager{ /** * Triggers garbage collection and cache cleanup to try and free memory. - * - * @param int $memory - * @param int $limit - * @param bool $global - * @param int $triggerCount */ public function trigger(int $memory, int $limit, bool $global = false, int $triggerCount = 0) : void{ $this->logger->debug(sprintf("%sLow memory triggered, limit %gMB, using %gMB", @@ -280,9 +262,6 @@ class MemoryManager{ Timings::$memoryManagerTimer->stopTiming(); } - /** - * @return int - */ public function triggerGarbageCollector() : int{ Timings::$garbageCollectorTimer->startTiming(); @@ -305,10 +284,6 @@ class MemoryManager{ /** * Dumps the server memory into the specified output folder. - * - * @param string $outputFolder - * @param int $maxNesting - * @param int $maxStringSize */ public function dumpServerMemory(string $outputFolder, int $maxNesting, int $maxStringSize) : void{ $logger = new \PrefixedLogger($this->server->getLogger(), "Memory Dump"); @@ -327,10 +302,6 @@ class MemoryManager{ * Static memory dumper accessible from any thread. * * @param mixed $startingObject - * @param string $outputFolder - * @param int $maxNesting - * @param int $maxStringSize - * @param \Logger $logger * * @throws \ReflectionException */ @@ -488,9 +459,6 @@ class MemoryManager{ * @param mixed $data reference parameter * @param object[] $objects reference parameter * @param int[] $refCounts reference parameter - * @param int $recursion - * @param int $maxNesting - * @param int $maxStringSize */ private static function continueDump($from, &$data, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize) : void{ if($maxNesting <= 0){ diff --git a/src/Server.php b/src/Server.php index 2bd8f86b9d..72d4586437 100644 --- a/src/Server.php +++ b/src/Server.php @@ -284,72 +284,42 @@ class Server{ /** @var Player[] */ private $playerList = []; - /** - * @return string - */ public function getName() : string{ return \pocketmine\NAME; } - /** - * @return bool - */ public function isRunning() : bool{ return $this->isRunning; } - /** - * @return string - */ public function getPocketMineVersion() : string{ return \pocketmine\VERSION; } - /** - * @return string - */ public function getVersion() : string{ return ProtocolInfo::MINECRAFT_VERSION; } - /** - * @return string - */ public function getApiVersion() : string{ return \pocketmine\BASE_VERSION; } - /** - * @return string - */ public function getFilePath() : string{ return \pocketmine\PATH; } - /** - * @return string - */ public function getResourcePath() : string{ return \pocketmine\RESOURCE_PATH; } - /** - * @return string - */ public function getDataPath() : string{ return $this->dataPath; } - /** - * @return string - */ public function getPluginPath() : string{ return $this->pluginPath; } - /** - * @return int - */ public function getMaxPlayers() : int{ return $this->maxPlayers; } @@ -357,8 +327,6 @@ class Server{ /** * Returns whether the server requires that players be authenticated to Xbox Live. If true, connecting players who * are not logged into Xbox Live will be disconnected. - * - * @return bool */ public function getOnlineMode() : bool{ return $this->onlineMode; @@ -366,40 +334,26 @@ class Server{ /** * Alias of {@link #getOnlineMode()}. - * @return bool */ public function requiresAuthentication() : bool{ return $this->getOnlineMode(); } - /** - * @return int - */ public function getPort() : int{ return $this->getConfigInt("server-port", 19132); } - /** - * @return int - */ public function getViewDistance() : int{ return max(2, $this->getConfigInt("view-distance", 8)); } /** * Returns a view distance up to the currently-allowed limit. - * - * @param int $distance - * - * @return int */ public function getAllowedViewDistance(int $distance) : int{ return max(2, min($distance, $this->memoryManager->getViewDistance($this->getViewDistance()))); } - /** - * @return string - */ public function getIp() : string{ $str = $this->getConfigString("server-ip"); return $str !== "" ? $str : "0.0.0.0"; @@ -412,45 +366,29 @@ class Server{ return $this->serverID; } - /** - * @return GameMode - */ public function getGamemode() : GameMode{ return GameMode::fromMagicNumber($this->getConfigInt("gamemode", 0) & 0b11); } - /** - * @return bool - */ public function getForceGamemode() : bool{ return $this->getConfigBool("force-gamemode", false); } /** * Returns Server global difficulty. Note that this may be overridden in individual worlds. - * @return int */ public function getDifficulty() : int{ return $this->getConfigInt("difficulty", World::DIFFICULTY_NORMAL); } - /** - * @return bool - */ public function hasWhitelist() : bool{ return $this->getConfigBool("white-list", false); } - /** - * @return bool - */ public function isHardcore() : bool{ return $this->getConfigBool("hardcore", false); } - /** - * @return string - */ public function getMotd() : string{ return $this->getConfigString("motd", \pocketmine\NAME . " Server"); } @@ -490,16 +428,10 @@ class Server{ return $this->craftingManager; } - /** - * @return ResourcePackManager - */ public function getResourcePackManager() : ResourcePackManager{ return $this->resourceManager; } - /** - * @return WorldManager - */ public function getWorldManager() : WorldManager{ return $this->worldManager; } @@ -508,17 +440,12 @@ class Server{ return $this->asyncPool; } - /** - * @return int - */ public function getTick() : int{ return $this->tickCounter; } /** * Returns the last server TPS measure - * - * @return float */ public function getTicksPerSecond() : float{ return round($this->currentTPS, 2); @@ -526,8 +453,6 @@ class Server{ /** * Returns the last server TPS average measure - * - * @return float */ public function getTicksPerSecondAverage() : float{ return round(array_sum($this->tickAverage) / count($this->tickAverage), 2); @@ -535,8 +460,6 @@ class Server{ /** * Returns the TPS usage/load in % - * - * @return float */ public function getTickUsage() : float{ return round($this->currentUse * 100, 2); @@ -544,16 +467,11 @@ class Server{ /** * Returns the TPS usage/load average in % - * - * @return float */ public function getTickUsageAverage() : float{ return round((array_sum($this->useAverage) / count($this->useAverage)) * 100, 2); } - /** - * @return float - */ public function getStartTime() : float{ return $this->startTime; } @@ -577,8 +495,6 @@ class Server{ } /** - * @param string $name - * * @return OfflinePlayer|Player */ public function getOfflinePlayer(string $name){ @@ -594,21 +510,12 @@ class Server{ /** * Returns whether the server has stored any saved data for this player. - * - * @param string $name - * - * @return bool */ public function hasOfflinePlayerData(string $name) : bool{ $name = strtolower($name); return file_exists($this->getDataPath() . "players/$name.dat"); } - /** - * @param string $name - * - * @return CompoundTag|null - */ public function getOfflinePlayerData(string $name) : ?CompoundTag{ $name = strtolower($name); $path = $this->getDataPath() . "players/"; @@ -624,10 +531,6 @@ class Server{ return null; } - /** - * @param string $name - * @param CompoundTag $nbtTag - */ public function saveOfflinePlayerData(string $name, CompoundTag $nbtTag) : void{ $ev = new PlayerDataSaveEvent($nbtTag, $name); $ev->setCancelled(!$this->shouldSavePlayerData()); @@ -650,10 +553,6 @@ class Server{ * The closest match will be returned, or null if there are no online matches. * * @see Server::getPlayerExact() - * - * @param string $name - * - * @return Player|null */ public function getPlayer(string $name) : ?Player{ $found = null; @@ -677,10 +576,6 @@ class Server{ /** * Returns an online player with the given name (case insensitive), or null if not found. - * - * @param string $name - * - * @return Player|null */ public function getPlayerExact(string $name) : ?Player{ $name = strtolower($name); @@ -697,8 +592,6 @@ class Server{ * Returns a list of online players whose names contain with the given string (case insensitive). * If an exact match is found, only that match is returned. * - * @param string $partialName - * * @return Player[] */ public function matchPlayer(string $partialName) : array{ @@ -718,10 +611,6 @@ class Server{ /** * Returns the player online with the specified raw UUID, or null if not found - * - * @param string $rawUUID - * - * @return null|Player */ public function getPlayerByRawUUID(string $rawUUID) : ?Player{ return $this->playerList[$rawUUID] ?? null; @@ -729,17 +618,12 @@ class Server{ /** * Returns the player online with a UUID equivalent to the specified UUID object, or null if not found - * - * @param UUID $uuid - * - * @return null|Player */ public function getPlayerByUUID(UUID $uuid) : ?Player{ return $this->getPlayerByRawUUID($uuid->toBinary()); } /** - * @param string $variable * @param mixed $defaultValue * * @return mixed @@ -757,12 +641,6 @@ class Server{ return $this->propertyCache[$variable] ?? $defaultValue; } - /** - * @param string $variable - * @param string $defaultValue - * - * @return string - */ public function getConfigString(string $variable, string $defaultValue = "") : string{ $v = getopt("", ["$variable::"]); if(isset($v[$variable])){ @@ -772,20 +650,10 @@ class Server{ return $this->properties->exists($variable) ? (string) $this->properties->get($variable) : $defaultValue; } - /** - * @param string $variable - * @param string $value - */ public function setConfigString(string $variable, string $value) : void{ $this->properties->set($variable, $value); } - /** - * @param string $variable - * @param int $defaultValue - * - * @return int - */ public function getConfigInt(string $variable, int $defaultValue = 0) : int{ $v = getopt("", ["$variable::"]); if(isset($v[$variable])){ @@ -795,20 +663,10 @@ class Server{ return $this->properties->exists($variable) ? (int) $this->properties->get($variable) : $defaultValue; } - /** - * @param string $variable - * @param int $value - */ public function setConfigInt(string $variable, int $value) : void{ $this->properties->set($variable, $value); } - /** - * @param string $variable - * @param bool $defaultValue - * - * @return bool - */ public function getConfigBool(string $variable, bool $defaultValue = false) : bool{ $v = getopt("", ["$variable::"]); if(isset($v[$variable])){ @@ -831,17 +689,11 @@ class Server{ return false; } - /** - * @param string $variable - * @param bool $value - */ public function setConfigBool(string $variable, bool $value) : void{ $this->properties->set($variable, $value ? "1" : "0"); } /** - * @param string $name - * * @return PluginIdentifiableCommand|null */ public function getPluginCommand(string $name){ @@ -866,9 +718,6 @@ class Server{ return $this->banByIP; } - /** - * @param string $name - */ public function addOp(string $name) : void{ $this->operators->set(strtolower($name), true); @@ -878,9 +727,6 @@ class Server{ $this->operators->save(); } - /** - * @param string $name - */ public function removeOp(string $name) : void{ $this->operators->remove(strtolower($name)); @@ -890,36 +736,20 @@ class Server{ $this->operators->save(); } - /** - * @param string $name - */ public function addWhitelist(string $name) : void{ $this->whitelist->set(strtolower($name), true); $this->whitelist->save(); } - /** - * @param string $name - */ public function removeWhitelist(string $name) : void{ $this->whitelist->remove(strtolower($name)); $this->whitelist->save(); } - /** - * @param string $name - * - * @return bool - */ public function isWhitelisted(string $name) : bool{ return !$this->hasWhitelist() or $this->operators->exists($name, true) or $this->whitelist->exists($name, true); } - /** - * @param string $name - * - * @return bool - */ public function isOp(string $name) : bool{ return $this->operators->exists($name, true); } @@ -960,9 +790,6 @@ class Server{ return $result; } - /** - * @return Server - */ public static function getInstance() : Server{ if(self::$instance === null){ throw new \RuntimeException("Attempt to retrieve Server instance outside server thread"); @@ -970,12 +797,6 @@ class Server{ return self::$instance; } - /** - * @param \DynamicClassLoader $autoloader - * @param \AttachableThreadedLogger $logger - * @param string $dataPath - * @param string $pluginPath - */ public function __construct(\DynamicClassLoader $autoloader, \AttachableThreadedLogger $logger, string $dataPath, string $pluginPath){ if(self::$instance !== null){ throw new \InvalidStateException("Only one server instance can exist at once"); @@ -1316,8 +1137,6 @@ class Server{ /** * @param TextContainer|string $message * @param CommandSender[] $recipients - * - * @return int */ public function broadcastMessage($message, ?array $recipients = null) : int{ if(!is_array($recipients)){ @@ -1343,10 +1162,7 @@ class Server{ } /** - * @param string $tip * @param Player[] $recipients - * - * @return int */ public function broadcastTip(string $tip, ?array $recipients = null) : int{ $recipients = $recipients ?? $this->selectPermittedPlayers(self::BROADCAST_CHANNEL_USERS); @@ -1359,10 +1175,7 @@ class Server{ } /** - * @param string $popup * @param Player[] $recipients - * - * @return int */ public function broadcastPopup(string $popup, ?array $recipients = null) : int{ $recipients = $recipients ?? $this->selectPermittedPlayers(self::BROADCAST_CHANNEL_USERS); @@ -1375,14 +1188,10 @@ class Server{ } /** - * @param string $title - * @param string $subtitle * @param int $fadeIn Duration in ticks for fade-in. If -1 is given, client-sided defaults will be used. * @param int $stay Duration in ticks to stay on screen for * @param int $fadeOut Duration in ticks for fade-out. * @param Player[]|null $recipients - * - * @return int */ public function broadcastTitle(string $title, string $subtitle = "", int $fadeIn = -1, int $stay = -1, int $fadeOut = -1, ?array $recipients = null) : int{ $recipients = $recipients ?? $this->selectPermittedPlayers(self::BROADCAST_CHANNEL_USERS); @@ -1396,9 +1205,6 @@ class Server{ /** * @param TextContainer|string $message - * @param string $permissions - * - * @return int */ public function broadcast($message, string $permissions) : int{ /** @var CommandSender[] $recipients */ @@ -1421,8 +1227,6 @@ class Server{ /** * @param Player[] $players * @param ClientboundPacket[] $packets - * - * @return bool */ public function broadcastPackets(array $players, array $packets) : bool{ if(count($packets) === 0){ @@ -1467,11 +1271,6 @@ class Server{ /** * Broadcasts a list of packets in a batch to a list of players - * - * @param PacketBatch $stream - * @param bool $forceSync - * - * @return CompressBatchPromise */ public function prepareBatch(PacketBatch $stream, bool $forceSync = false) : CompressBatchPromise{ try{ @@ -1498,9 +1297,6 @@ class Server{ } } - /** - * @param PluginLoadOrder $type - */ public function enablePlugins(PluginLoadOrder $type) : void{ foreach($this->pluginManager->getPlugins() as $plugin){ if(!$plugin->isEnabled() and $plugin->getDescription()->getOrder()->equals($type)){ @@ -1516,12 +1312,6 @@ class Server{ /** * Executes a command from a CommandSender - * - * @param CommandSender $sender - * @param string $commandLine - * @param bool $internal - * - * @return bool */ public function dispatchCommand(CommandSender $sender, string $commandLine, bool $internal = false) : bool{ if(!$internal){ @@ -1627,7 +1417,6 @@ class Server{ } /** - * @param \Throwable $e * @param array|null $trace */ public function exceptionHandler(\Throwable $e, $trace = null) : void{ @@ -1799,9 +1588,6 @@ class Server{ return $this->language; } - /** - * @return bool - */ public function isLanguageForced() : bool{ return $this->forceLanguage; } diff --git a/src/block/Banner.php b/src/block/Banner.php index cf32d486b4..9091d5bfbb 100644 --- a/src/block/Banner.php +++ b/src/block/Banner.php @@ -120,7 +120,6 @@ class Banner extends Transparent{ /** * TODO: interface method? this is only the BASE colour... - * @return DyeColor */ public function getColor() : DyeColor{ return $this->baseColor; diff --git a/src/block/BaseRail.php b/src/block/BaseRail.php index 8bcd22e4b4..cff41ea3d6 100644 --- a/src/block/BaseRail.php +++ b/src/block/BaseRail.php @@ -124,10 +124,6 @@ abstract class BaseRail extends Flowable{ /** * Returns a meta value for the rail with the given connections. * - * @param array $connections - * - * @return int - * * @throws \InvalidArgumentException if no state matches the given connections */ protected function getMetaForState(array $connections) : int{ @@ -137,8 +133,6 @@ abstract class BaseRail extends Flowable{ /** * Returns the connection directions of this rail (depending on the current block state) * - * @param int $meta - * * @return int[] */ abstract protected function getConnectionsFromMeta(int $meta) : ?array; diff --git a/src/block/Bed.php b/src/block/Bed.php index a8f4cdf47e..fb5c35f235 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -99,9 +99,6 @@ class Bed extends Transparent{ return $this->head; } - /** - * @return bool - */ public function isOccupied() : bool{ return $this->occupied; } @@ -116,16 +113,10 @@ class Bed extends Transparent{ } } - /** - * @return int - */ private function getOtherHalfSide() : int{ return $this->head ? Facing::opposite($this->facing) : $this->facing; } - /** - * @return Bed|null - */ public function getOtherHalf() : ?Bed{ $other = $this->getSide($this->getOtherHalfSide()); if($other instanceof Bed and $other->head !== $this->head and $other->facing === $this->facing){ diff --git a/src/block/Block.php b/src/block/Block.php index 993b94d60d..e006a42179 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -68,9 +68,7 @@ class Block{ protected $collisionBoxes = null; /** - * @param BlockIdentifier $idInfo * @param string $name English name of the block type (TODO: implement translations) - * @param BlockBreakInfo $breakInfo */ public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ if(($idInfo->getVariant() & $this->getStateBitmask()) !== 0){ @@ -90,23 +88,16 @@ class Block{ return $this->idInfo; } - /** - * @return string - */ public function getName() : string{ return $this->fallbackName; } - /** - * @return int - */ public function getId() : int{ return $this->idInfo->getBlockId(); } /** * @internal - * @return int */ public function getFullId() : int{ return ($this->getId() << 4) | $this->getMeta(); @@ -118,26 +109,19 @@ class Block{ /** * @internal - * @return int */ public function getRuntimeId() : int{ return RuntimeBlockMapping::toStaticRuntimeId($this->getId(), $this->getMeta()); } - /** - * @return int - */ public function getMeta() : int{ $stateMeta = $this->writeStateToMeta(); assert(($stateMeta & ~$this->getStateBitmask()) === 0); return $this->idInfo->getVariant() | $stateMeta; } - /** * Returns a bitmask used to extract state bits from block metadata. - * - * @return int */ public function getStateBitmask() : int{ return 0; @@ -148,9 +132,6 @@ class Block{ } /** - * @param int $id - * @param int $stateMeta - * * @throws InvalidBlockStateException */ public function readStateFromData(int $id, int $stateMeta) : void{ @@ -191,10 +172,6 @@ class Block{ * * Note: This ignores additional IDs used to represent additional states. This means that, for example, a lit * furnace and unlit furnace are considered the same type. - * - * @param Block $other - * - * @return bool */ public function isSameType(Block $other) : bool{ return $this->idInfo->getBlockId() === $other->idInfo->getBlockId() and $this->idInfo->getVariant() === $other->idInfo->getVariant(); @@ -202,10 +179,6 @@ class Block{ /** * Returns whether the given block has the same type and properties as this block. - * - * @param Block $other - * - * @return bool */ public function isSameState(Block $other) : bool{ return $this->isSameType($other) and $this->writeStateToMeta() === $other->writeStateToMeta(); @@ -213,15 +186,11 @@ class Block{ /** * AKA: Block->isPlaceable - * @return bool */ public function canBePlaced() : bool{ return true; } - /** - * @return bool - */ public function canBeReplaced() : bool{ return false; } @@ -232,16 +201,6 @@ class Block{ /** * Places the Block, using block space and block target, and side. Returns if the block has been placed. - * - * @param BlockTransaction $tx - * @param Item $item - * @param Block $blockReplace - * @param Block $blockClicked - * @param int $face - * @param Vector3 $clickVector - * @param Player|null $player - * - * @return bool */ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $tx->addBlock($blockReplace->pos, $this); @@ -254,8 +213,6 @@ class Block{ /** * Returns an object containing information about the destruction requirements of this block. - * - * @return BlockBreakInfo */ public function getBreakInfo() : BlockBreakInfo{ return $this->breakInfo; @@ -263,11 +220,6 @@ class Block{ /** * Do the actions needed so the block is broken with the Item - * - * @param Item $item - * @param Player|null $player - * - * @return bool */ public function onBreak(Item $item, ?Player $player = null) : bool{ if(($t = $this->pos->getWorld()->getTile($this->pos)) !== null){ @@ -286,8 +238,6 @@ class Block{ /** * Returns whether random block updates will be done on this block. - * - * @return bool */ public function ticksRandomly() : bool{ return false; @@ -310,13 +260,6 @@ class Block{ /** * Do actions when interacted by Item. Returns if it has done anything - * - * @param Item $item - * @param int $face - * @param Vector3 $clickVector - * @param Player|null $player - * - * @return bool */ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ return false; @@ -326,19 +269,12 @@ class Block{ * Called when this block is attacked (left-clicked). This is called when a player left-clicks the block to try and * start to break it in survival mode. * - * @param Item $item - * @param int $face - * @param Player|null $player - * * @return bool if an action took place, prevents starting to break the block if true. */ public function onAttack(Item $item, int $face, ?Player $player = null) : bool{ return false; } - /** - * @return float - */ public function getFrictionFactor() : float{ return 0.6; } @@ -366,16 +302,11 @@ class Block{ * Examples of this behaviour include leaves and cobwebs. * * Light-diffusing blocks are included by the heightmap. - * - * @return bool */ public function diffusesSkyLight() : bool{ return false; } - /** - * @return bool - */ public function isTransparent() : bool{ return false; } @@ -386,7 +317,6 @@ class Block{ /** * AKA: Block->isFlowable - * @return bool */ public function canBeFlowedInto() : bool{ return false; @@ -398,7 +328,6 @@ class Block{ /** * Returns whether entities can climb up this block. - * @return bool */ public function canClimb() : bool{ return false; @@ -415,11 +344,6 @@ class Block{ /** * @internal - * - * @param World $world - * @param int $x - * @param int $y - * @param int $z */ final public function position(World $world, int $x, int $y, int $z) : void{ $this->pos->x = $x; @@ -431,8 +355,6 @@ class Block{ /** * Returns an array of Item objects to be dropped * - * @param Item $item - * * @return Item[] */ public function getDrops(Item $item) : array{ @@ -450,8 +372,6 @@ class Block{ /** * Returns an array of Items to be dropped when the block is broken using the correct tool type. * - * @param Item $item - * * @return Item[] */ public function getDropsForCompatibleTool(Item $item) : array{ @@ -461,8 +381,6 @@ class Block{ /** * Returns an array of Items to be dropped when the block is broken using a compatible Silk Touch-enchanted tool. * - * @param Item $item - * * @return Item[] */ public function getSilkTouchDrops(Item $item) : array{ @@ -471,10 +389,6 @@ class Block{ /** * Returns how much XP will be dropped by breaking this block with the given item. - * - * @param Item $item - * - * @return int */ public function getXpDropForTool(Item $item) : int{ if($item->hasEnchantment(Enchantment::SILK_TOUCH()) or !$this->breakInfo->isToolCompatible($item)){ @@ -486,8 +400,6 @@ class Block{ /** * Returns how much XP this block will drop when broken with an appropriate tool. - * - * @return int */ protected function getXpDropAmount() : int{ return 0; @@ -496,8 +408,6 @@ class Block{ /** * Returns whether Silk Touch enchanted tools will cause this block to drop as itself. Since most blocks drop * themselves anyway, this is implicitly true. - * - * @return bool */ public function isAffectedBySilkTouch() : bool{ return true; @@ -505,10 +415,6 @@ class Block{ /** * Returns the item that players will equip when middle-clicking on this block. - * - * @param bool $addUserData - * - * @return Item */ public function getPickedItem(bool $addUserData = false) : Item{ $item = $this->asItem(); @@ -527,7 +433,6 @@ class Block{ /** * Returns the time in ticks which the block will fuel a furnace for. - * @return int */ public function getFuelTime() : int{ return 0; @@ -536,8 +441,6 @@ class Block{ /** * Returns the chance that the block will catch fire from nearby fire sources. Higher values lead to faster catching * fire. - * - * @return int */ public function getFlameEncouragement() : int{ return 0; @@ -545,8 +448,6 @@ class Block{ /** * Returns the base flammability of this block. Higher values lead to the block burning away more quickly. - * - * @return int */ public function getFlammability() : int{ return 0; @@ -554,8 +455,6 @@ class Block{ /** * Returns whether fire lit on this block will burn indefinitely. - * - * @return bool */ public function burnsForever() : bool{ return false; @@ -563,8 +462,6 @@ class Block{ /** * Returns whether this block can catch fire. - * - * @return bool */ public function isFlammable() : bool{ return $this->getFlammability() > 0; @@ -580,9 +477,6 @@ class Block{ /** * Returns the Block on the side $side, works like Vector3::getSide() * - * @param int $side - * @param int $step - * * @return Block */ public function getSide(int $side, int $step = 1){ @@ -641,10 +535,6 @@ class Block{ /** * Checks for collision against an AxisAlignedBB - * - * @param AxisAlignedBB $bb - * - * @return bool */ public function collidesWithBB(AxisAlignedBB $bb) : bool{ foreach($this->getCollisionBoxes() as $bb2){ @@ -659,8 +549,6 @@ class Block{ /** * Called when an entity's bounding box clips inside this block's cell. Note that the entity may not be intersecting * with the collision box or bounding box. - * - * @param Entity $entity */ public function onEntityInside(Entity $entity) : void{ @@ -687,21 +575,12 @@ class Block{ return [AxisAlignedBB::one()]; } - /** - * @return bool - */ public function isFullCube() : bool{ $bb = $this->getCollisionBoxes(); return count($bb) === 1 and $bb[0]->getAverageEdgeLength() >= 1; //TODO: average length 1 != cube } - /** - * @param Vector3 $pos1 - * @param Vector3 $pos2 - * - * @return RayTraceResult|null - */ public function calculateIntercept(Vector3 $pos1, Vector3 $pos2) : ?RayTraceResult{ $bbs = $this->getCollisionBoxes(); if(count($bbs) === 0){ diff --git a/src/block/BlockBreakInfo.php b/src/block/BlockBreakInfo.php index 68e287bb69..cff5a9034b 100644 --- a/src/block/BlockBreakInfo.php +++ b/src/block/BlockBreakInfo.php @@ -38,9 +38,6 @@ class BlockBreakInfo{ private $toolHarvestLevel; /** - * @param float $hardness - * @param int $toolType - * @param int $toolHarvestLevel * @param float|null $blastResistance default 5x hardness */ public function __construct(float $hardness, int $toolType = BlockToolType::NONE, int $toolHarvestLevel = 0, ?float $blastResistance = null){ @@ -60,8 +57,6 @@ class BlockBreakInfo{ /** * Returns a base value used to compute block break times. - * - * @return float */ public function getHardness() : float{ return $this->hardness; @@ -69,8 +64,6 @@ class BlockBreakInfo{ /** * Returns whether the block can be broken at all. - * - * @return bool */ public function isBreakable() : bool{ return $this->hardness >= 0; @@ -78,8 +71,6 @@ class BlockBreakInfo{ /** * Returns whether this block can be instantly broken. - * - * @return bool */ public function breaksInstantly() : bool{ return $this->hardness == 0.0; @@ -87,16 +78,11 @@ class BlockBreakInfo{ /** * Returns the block's resistance to explosions. Usually 5x hardness. - * - * @return float */ public function getBlastResistance() : float{ return $this->blastResistance; } - /** - * @return int - */ public function getToolType() : int{ return $this->toolType; } @@ -110,8 +96,6 @@ class BlockBreakInfo{ * Otherwise, 1 should be returned if a tool is required, 0 if not. * * @see Item::getBlockToolHarvestLevel() - * - * @return int */ public function getToolHarvestLevel() : int{ return $this->toolHarvestLevel; @@ -123,10 +107,6 @@ class BlockBreakInfo{ * * In most cases this is also used to determine whether block drops should be created or not, except in some * special cases such as vines. - * - * @param Item $tool - * - * @return bool */ public function isToolCompatible(Item $tool) : bool{ if($this->hardness < 0){ @@ -140,9 +120,6 @@ class BlockBreakInfo{ /** * Returns the seconds that this block takes to be broken using an specific Item * - * @param Item $item - * - * @return float * @throws \InvalidArgumentException if the item efficiency is not a positive number */ public function getBreakTime(Item $item) : float{ diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 065f34eacb..5c34585e37 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -763,7 +763,6 @@ class BlockFactory{ * NOTE: If you are registering a new block type, you will need to add it to the creative inventory yourself - it * will not automatically appear there. * - * @param Block $block * @param bool $override Whether to override existing registrations * * @throws \RuntimeException if something attempted to override an already-registered block without specifying the @@ -828,11 +827,6 @@ class BlockFactory{ /** * Returns a new Block instance with the specified ID, meta and position. - * - * @param int $id - * @param int $meta - * - * @return Block */ public static function get(int $id, int $meta = 0) : Block{ if($meta < 0 or $meta > 0xf){ @@ -863,11 +857,6 @@ class BlockFactory{ /** * Returns whether a specified block state is already registered in the block factory. - * - * @param int $id - * @param int $meta - * - * @return bool */ public static function isRegistered(int $id, int $meta = 0) : bool{ $b = self::$fullList[($id << 4) | $meta]; diff --git a/src/block/BlockIdentifier.php b/src/block/BlockIdentifier.php index 87cae2ad7b..87faf3a316 100644 --- a/src/block/BlockIdentifier.php +++ b/src/block/BlockIdentifier.php @@ -41,9 +41,6 @@ class BlockIdentifier{ $this->tileClass = $tileClass; } - /** - * @return int - */ public function getBlockId() : int{ return $this->blockId; } @@ -55,23 +52,14 @@ class BlockIdentifier{ return [$this->blockId]; } - /** - * @return int - */ public function getVariant() : int{ return $this->variant; } - /** - * @return int - */ public function getItemId() : int{ return $this->itemId ?? ($this->blockId > 255 ? 255 - $this->blockId : $this->blockId); } - /** - * @return string|null - */ public function getTileClass() : ?string{ return $this->tileClass; } diff --git a/src/block/BlockIdentifierFlattened.php b/src/block/BlockIdentifierFlattened.php index adbeddedeb..f22c801d71 100644 --- a/src/block/BlockIdentifierFlattened.php +++ b/src/block/BlockIdentifierFlattened.php @@ -33,9 +33,6 @@ class BlockIdentifierFlattened extends BlockIdentifier{ $this->secondId = $secondId; } - /** - * @return int - */ public function getSecondId() : int{ return $this->secondId; } diff --git a/src/block/ConcretePowder.php b/src/block/ConcretePowder.php index 5261ddc7bc..432c6ef7c8 100644 --- a/src/block/ConcretePowder.php +++ b/src/block/ConcretePowder.php @@ -44,16 +44,10 @@ class ConcretePowder extends Opaque implements Fallable{ } } - /** - * @return null|Block - */ public function tickFalling() : ?Block{ return $this->checkAdjacentWater(); } - /** - * @return null|Block - */ private function checkAdjacentWater() : ?Block{ foreach(Facing::ALL as $i){ if($i === Facing::DOWN){ diff --git a/src/block/DaylightSensor.php b/src/block/DaylightSensor.php index ad16340cf2..5892bf0abc 100644 --- a/src/block/DaylightSensor.php +++ b/src/block/DaylightSensor.php @@ -70,8 +70,6 @@ class DaylightSensor extends Transparent{ } /** - * @param bool $inverted - * * @return $this */ public function setInverted(bool $inverted = true) : self{ diff --git a/src/block/DoublePlant.php b/src/block/DoublePlant.php index 2e1a891115..bfb02c8dde 100644 --- a/src/block/DoublePlant.php +++ b/src/block/DoublePlant.php @@ -64,7 +64,6 @@ class DoublePlant extends Flowable{ /** * Returns whether this double-plant has a corresponding other half. - * @return bool */ public function isValidHalfPlant() : bool{ $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); diff --git a/src/block/Element.php b/src/block/Element.php index 16234b3087..f12ab86725 100644 --- a/src/block/Element.php +++ b/src/block/Element.php @@ -39,23 +39,14 @@ class Element extends Opaque{ $this->symbol = $symbol; } - /** - * @return int - */ public function getAtomicWeight() : int{ return $this->atomicWeight; } - /** - * @return int - */ public function getGroup() : int{ return $this->group; } - /** - * @return string - */ public function getSymbol() : string{ return $this->symbol; } diff --git a/src/block/FlowerPot.php b/src/block/FlowerPot.php index 5f19a75756..1e8edd16f7 100644 --- a/src/block/FlowerPot.php +++ b/src/block/FlowerPot.php @@ -77,16 +77,10 @@ class FlowerPot extends Flowable{ $tile->setPlant($this->plant); } - /** - * @return Block|null - */ public function getPlant() : ?Block{ return $this->plant; } - /** - * @param Block|null $plant - */ public function setPlant(?Block $plant) : void{ if($plant === null or $plant instanceof Air){ $this->plant = null; diff --git a/src/block/Furnace.php b/src/block/Furnace.php index 736de20c7d..70ffde36d5 100644 --- a/src/block/Furnace.php +++ b/src/block/Furnace.php @@ -71,8 +71,6 @@ class Furnace extends Opaque{ } /** - * @param bool $lit - * * @return $this */ public function setLit(bool $lit = true) : self{ diff --git a/src/block/ItemFrame.php b/src/block/ItemFrame.php index f0a181637a..a28f00f62e 100644 --- a/src/block/ItemFrame.php +++ b/src/block/ItemFrame.php @@ -86,30 +86,18 @@ class ItemFrame extends Flowable{ return 0b111; } - /** - * @return int - */ public function getFacing() : int{ return $this->facing; } - /** - * @param int $facing - */ public function setFacing(int $facing) : void{ $this->facing = $facing; } - /** - * @return Item|null - */ public function getFramedItem() : ?Item{ return $this->framedItem !== null ? clone $this->framedItem : null; } - /** - * @param Item|null $item - */ public function setFramedItem(?Item $item) : void{ if($item === null or $item->isNull()){ $this->framedItem = null; @@ -119,30 +107,18 @@ class ItemFrame extends Flowable{ } } - /** - * @return int - */ public function getItemRotation() : int{ return $this->itemRotation; } - /** - * @param int $itemRotation - */ public function setItemRotation(int $itemRotation) : void{ $this->itemRotation = $itemRotation; } - /** - * @return float - */ public function getItemDropChance() : float{ return $this->itemDropChance; } - /** - * @param float $itemDropChance - */ public function setItemDropChance(float $itemDropChance) : void{ $this->itemDropChance = $itemDropChance; } diff --git a/src/block/Liquid.php b/src/block/Liquid.php index 46cdb947bf..3819f50397 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -143,8 +143,6 @@ abstract class Liquid extends Transparent{ } /** - * @param bool $still - * * @return $this */ public function setStill(bool $still = true) : self{ @@ -247,8 +245,6 @@ abstract class Liquid extends Transparent{ /** * Returns how many liquid levels are lost per block flowed horizontally. Affects how far the liquid can flow. - * - * @return int */ public function getFlowDecayPerBlock() : int{ return 1; diff --git a/src/block/NetherPortal.php b/src/block/NetherPortal.php index e68c65e325..0eb9efc052 100644 --- a/src/block/NetherPortal.php +++ b/src/block/NetherPortal.php @@ -48,15 +48,11 @@ class NetherPortal extends Transparent{ return 0b11; } - /** - * @return int - */ public function getAxis() : int{ return $this->axis; } /** - * @param int $axis * @throws \InvalidArgumentException */ public function setAxis(int $axis) : void{ diff --git a/src/block/Note.php b/src/block/Note.php index 2edd5b316a..3e027c220b 100644 --- a/src/block/Note.php +++ b/src/block/Note.php @@ -58,16 +58,10 @@ class Note extends Opaque{ return 300; } - /** - * @return int - */ public function getPitch() : int{ return $this->pitch; } - /** - * @param int $pitch - */ public function setPitch(int $pitch) : void{ if($pitch < self::MIN_PITCH or $pitch > self::MAX_PITCH){ throw new \InvalidArgumentException("Pitch must be in range " . self::MIN_PITCH . " - " . self::MAX_PITCH); diff --git a/src/block/RedstoneComparator.php b/src/block/RedstoneComparator.php index 7554e1e7c9..7372ab99a2 100644 --- a/src/block/RedstoneComparator.php +++ b/src/block/RedstoneComparator.php @@ -87,7 +87,6 @@ class RedstoneComparator extends Flowable{ /** * TODO: ad hoc, move to interface - * @return int */ public function getFacing() : int{ return $this->facing; @@ -95,50 +94,31 @@ class RedstoneComparator extends Flowable{ /** * TODO: ad hoc, move to interface - * @param int $facing */ public function setFacing(int $facing) : void{ $this->facing = $facing; } - /** - * @return bool - */ public function isSubtractMode() : bool{ return $this->isSubtractMode; } - /** - * @param bool $isSubtractMode - */ public function setSubtractMode(bool $isSubtractMode) : void{ $this->isSubtractMode = $isSubtractMode; } - /** - * @return bool - */ public function isPowered() : bool{ return $this->powered; } - /** - * @param bool $powered - */ public function setPowered(bool $powered) : void{ $this->powered = $powered; } - /** - * @return int - */ public function getSignalStrength() : int{ return $this->signalStrength; } - /** - * @param int $signalStrength - */ public function setSignalStrength(int $signalStrength) : void{ $this->signalStrength = $signalStrength; } diff --git a/src/block/RedstoneLamp.php b/src/block/RedstoneLamp.php index d16ca52e8c..c09f73b45b 100644 --- a/src/block/RedstoneLamp.php +++ b/src/block/RedstoneLamp.php @@ -48,8 +48,6 @@ class RedstoneLamp extends Opaque{ } /** - * @param bool $lit - * * @return $this */ public function setLit(bool $lit = true) : self{ diff --git a/src/block/RedstoneOre.php b/src/block/RedstoneOre.php index c3e2cbe11a..cde5462d00 100644 --- a/src/block/RedstoneOre.php +++ b/src/block/RedstoneOre.php @@ -54,8 +54,6 @@ class RedstoneOre extends Opaque{ } /** - * @param bool $lit - * * @return $this */ public function setLit(bool $lit = true) : self{ diff --git a/src/block/RedstoneRepeater.php b/src/block/RedstoneRepeater.php index c1e7a7af05..82af3f53d1 100644 --- a/src/block/RedstoneRepeater.php +++ b/src/block/RedstoneRepeater.php @@ -76,8 +76,6 @@ class RedstoneRepeater extends Flowable{ } /** - * @param bool $powered - * * @return $this */ public function setPowered(bool $powered = true) : self{ diff --git a/src/block/RedstoneTorch.php b/src/block/RedstoneTorch.php index a1974c2ce3..c47765b153 100644 --- a/src/block/RedstoneTorch.php +++ b/src/block/RedstoneTorch.php @@ -49,8 +49,6 @@ class RedstoneTorch extends Torch{ } /** - * @param bool $lit - * * @return $this */ public function setLit(bool $lit = true) : self{ diff --git a/src/block/Sign.php b/src/block/Sign.php index 88bd8f784c..e549ff741f 100644 --- a/src/block/Sign.php +++ b/src/block/Sign.php @@ -135,8 +135,6 @@ class Sign extends Transparent{ /** * Returns an object containing information about the sign text. - * - * @return SignText */ public function getText() : SignText{ return $this->text; @@ -145,9 +143,6 @@ class Sign extends Transparent{ /** * Called by the player controller (network session) to update the sign text, firing events as appropriate. * - * @param Player $author - * @param SignText $text - * * @return bool if the sign update was successful. * @throws \UnexpectedValueException if the text payload is too large */ diff --git a/src/block/Skull.php b/src/block/Skull.php index e5cd481e91..e912f19e0e 100644 --- a/src/block/Skull.php +++ b/src/block/Skull.php @@ -83,9 +83,6 @@ class Skull extends Flowable{ $tile->setSkullType($this->skullType); } - /** - * @return SkullType - */ public function getSkullType() : SkullType{ return $this->skullType; } diff --git a/src/block/Slab.php b/src/block/Slab.php index 4c8c701c1d..275aa8bf8a 100644 --- a/src/block/Slab.php +++ b/src/block/Slab.php @@ -72,16 +72,12 @@ class Slab extends Transparent{ /** * Returns the type of slab block. - * - * @return SlabType */ public function getSlabType() : SlabType{ return $this->slabType; } /** - * @param SlabType $slabType - * * @return $this */ public function setSlabType(SlabType $slabType) : self{ diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 605c629d68..fc85d0d657 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -675,11 +675,6 @@ final class VanillaBlocks{ self::_registryRegister($name, $block); } - /** - * @param string $name - * - * @return Block - */ public static function fromString(string $name) : Block{ $result = self::_registryFromString($name); assert($result instanceof Block); diff --git a/src/block/Wood.php b/src/block/Wood.php index a4650749b3..6db53bee07 100644 --- a/src/block/Wood.php +++ b/src/block/Wood.php @@ -37,7 +37,6 @@ class Wood extends Opaque{ /** * TODO: this is ad hoc, but add an interface for this to all tree-related blocks - * @return TreeType */ public function getTreeType() : TreeType{ return $this->treeType; diff --git a/src/block/tile/Banner.php b/src/block/tile/Banner.php index 1860997e1e..e72ee276df 100644 --- a/src/block/tile/Banner.php +++ b/src/block/tile/Banner.php @@ -98,8 +98,6 @@ class Banner extends Spawnable{ /** * Returns the color of the banner base. - * - * @return DyeColor */ public function getBaseColor() : DyeColor{ return $this->baseColor; @@ -107,8 +105,6 @@ class Banner extends Spawnable{ /** * Sets the color of the banner base. - * - * @param DyeColor $color */ public function setBaseColor(DyeColor $color) : void{ $this->baseColor = $color; diff --git a/src/block/tile/Chest.php b/src/block/tile/Chest.php index 9a4f2dd445..ed824a499b 100644 --- a/src/block/tile/Chest.php +++ b/src/block/tile/Chest.php @@ -163,9 +163,6 @@ class Chest extends Spawnable implements Container, Nameable{ } } - /** - * @return string - */ public function getDefaultName() : string{ return "Chest"; } @@ -174,9 +171,6 @@ class Chest extends Spawnable implements Container, Nameable{ return $this->pairX !== null and $this->pairZ !== null; } - /** - * @return Chest|null - */ public function getPair() : ?Chest{ if($this->isPaired()){ $tile = $this->pos->getWorld()->getTileAt($this->pairX, $this->pos->y, $this->pairZ); diff --git a/src/block/tile/Comparator.php b/src/block/tile/Comparator.php index c19383ab18..24e63a79d5 100644 --- a/src/block/tile/Comparator.php +++ b/src/block/tile/Comparator.php @@ -36,16 +36,10 @@ class Comparator extends Tile{ /** @var int */ protected $signalStrength = 0; - /** - * @return int - */ public function getSignalStrength() : int{ return $this->signalStrength; } - /** - * @param int $signalStrength - */ public function setSignalStrength(int $signalStrength) : void{ $this->signalStrength = $signalStrength; } diff --git a/src/block/tile/Container.php b/src/block/tile/Container.php index 0587d22d56..b549ad137f 100644 --- a/src/block/tile/Container.php +++ b/src/block/tile/Container.php @@ -37,10 +37,6 @@ interface Container extends InventoryHolder{ /** * Returns whether this container can be opened by an item with the given custom name. - * - * @param string $key - * - * @return bool */ public function canOpenWith(string $key) : bool; } diff --git a/src/block/tile/ContainerTrait.php b/src/block/tile/ContainerTrait.php index 6217b2f70b..2acc3ea805 100644 --- a/src/block/tile/ContainerTrait.php +++ b/src/block/tile/ContainerTrait.php @@ -78,10 +78,6 @@ trait ContainerTrait{ /** * @see Container::canOpenWith() - * - * @param string $key - * - * @return bool */ public function canOpenWith(string $key) : bool{ return $this->lock === null or $this->lock === $key; @@ -89,7 +85,6 @@ trait ContainerTrait{ /** * @see Position::asPosition() - * @return Position */ abstract protected function getPos() : Position; diff --git a/src/block/tile/EnchantTable.php b/src/block/tile/EnchantTable.php index fe48a85185..8e56166bef 100644 --- a/src/block/tile/EnchantTable.php +++ b/src/block/tile/EnchantTable.php @@ -29,9 +29,6 @@ class EnchantTable extends Spawnable implements Nameable{ saveName as writeSaveData; } - /** - * @return string - */ public function getDefaultName() : string{ return "Enchanting Table"; } diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index dbd05dce7b..0428cfb0bb 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -90,9 +90,6 @@ class Furnace extends Spawnable implements Container, Nameable{ $this->saveItems($nbt); } - /** - * @return string - */ public function getDefaultName() : string{ return "Furnace"; } diff --git a/src/block/tile/Nameable.php b/src/block/tile/Nameable.php index 8e8683533f..2d206ffc2b 100644 --- a/src/block/tile/Nameable.php +++ b/src/block/tile/Nameable.php @@ -26,23 +26,11 @@ namespace pocketmine\block\tile; interface Nameable{ public const TAG_CUSTOM_NAME = "CustomName"; - /** - * @return string - */ public function getDefaultName() : string; - /** - * @return string - */ public function getName() : string; - /** - * @param string $str - */ public function setName(string $str) : void; - /** - * @return bool - */ public function hasName() : bool; } diff --git a/src/block/tile/NameableTrait.php b/src/block/tile/NameableTrait.php index 38b89897c9..74631a25f3 100644 --- a/src/block/tile/NameableTrait.php +++ b/src/block/tile/NameableTrait.php @@ -34,21 +34,12 @@ trait NameableTrait{ /** @var string|null */ private $customName = null; - /** - * @return string - */ abstract public function getDefaultName() : string; - /** - * @return string - */ public function getName() : string{ return $this->customName ?? $this->getDefaultName(); } - /** - * @param string $name - */ public function setName(string $name) : void{ if($name === ""){ $this->customName = null; @@ -57,9 +48,6 @@ trait NameableTrait{ } } - /** - * @return bool - */ public function hasName() : bool{ return $this->customName !== null; } @@ -83,7 +71,6 @@ trait NameableTrait{ } /** - * @param Item $item * @see Tile::copyDataFromItem() */ public function copyDataFromItem(Item $item) : void{ diff --git a/src/block/tile/Note.php b/src/block/tile/Note.php index 4d178d837a..5157f74366 100644 --- a/src/block/tile/Note.php +++ b/src/block/tile/Note.php @@ -43,16 +43,10 @@ class Note extends Tile{ $nbt->setByte("note", $this->pitch); } - /** - * @return int - */ public function getPitch() : int{ return $this->pitch; } - /** - * @param int $pitch - */ public function setPitch(int $pitch) : void{ if($pitch < BlockNote::MIN_PITCH or $pitch > BlockNote::MAX_PITCH){ throw new \InvalidArgumentException("Pitch must be in range " . BlockNote::MIN_PITCH . " - " . BlockNote::MAX_PITCH); diff --git a/src/block/tile/Sign.php b/src/block/tile/Sign.php index e625448c94..dd9cfff705 100644 --- a/src/block/tile/Sign.php +++ b/src/block/tile/Sign.php @@ -78,16 +78,10 @@ class Sign extends Spawnable{ } } - /** - * @return SignText - */ public function getText() : SignText{ return $this->text; } - /** - * @param SignText $text - */ public function setText(SignText $text) : void{ $this->text = $text; } diff --git a/src/block/tile/Spawnable.php b/src/block/tile/Spawnable.php index c0d911fbc3..3c6c5d7c15 100644 --- a/src/block/tile/Spawnable.php +++ b/src/block/tile/Spawnable.php @@ -39,16 +39,11 @@ abstract class Spawnable extends Tile{ /** * Returns whether the tile needs to be respawned to viewers. - * - * @return bool */ public function isDirty() : bool{ return $this->dirty; } - /** - * @param bool $dirty - */ public function setDirty(bool $dirty = true) : void{ if($dirty){ $this->spawnCompoundCache = null; @@ -74,9 +69,6 @@ abstract class Spawnable extends Tile{ return $this->spawnCompoundCache; } - /** - * @return CompoundTag - */ final public function getSpawnCompound() : CompoundTag{ $nbt = CompoundTag::create() ->setString(self::TAG_ID, TileFactory::getSaveId(get_class($this))) //TODO: disassociate network ID from save ID @@ -90,8 +82,6 @@ abstract class Spawnable extends Tile{ /** * An extension to getSpawnCompound() for * further modifying the generic tile NBT. - * - * @param CompoundTag $nbt */ abstract protected function addAdditionalSpawnData(CompoundTag $nbt) : void; } diff --git a/src/block/tile/Tile.php b/src/block/tile/Tile.php index 734162544d..8a0184bf51 100644 --- a/src/block/tile/Tile.php +++ b/src/block/tile/Tile.php @@ -59,15 +59,11 @@ abstract class Tile{ /** * @internal * Reads additional data from the CompoundTag on tile creation. - * - * @param CompoundTag $nbt */ abstract public function readSaveData(CompoundTag $nbt) : void; /** * Writes additional save data to a CompoundTag, not including generic things like ID and coordinates. - * - * @param CompoundTag $nbt */ abstract protected function writeSaveData(CompoundTag $nbt) : void; @@ -90,8 +86,6 @@ abstract class Tile{ /** * @internal * - * @param Item $item - * * @throws \RuntimeException */ public function copyDataFromItem(Item $item) : void{ @@ -100,16 +94,10 @@ abstract class Tile{ } } - /** - * @return Block - */ public function getBlock() : Block{ return $this->pos->getWorld()->getBlock($this->pos); } - /** - * @return Position - */ public function getPos() : Position{ return $this->pos; } diff --git a/src/block/tile/TileFactory.php b/src/block/tile/TileFactory.php index c1e7d3c848..a72951af35 100644 --- a/src/block/tile/TileFactory.php +++ b/src/block/tile/TileFactory.php @@ -89,7 +89,6 @@ final class TileFactory{ } /** - * @param string $className * @param string[] $saveNames */ public static function register(string $className, array $saveNames = []) : void{ @@ -125,10 +124,6 @@ final class TileFactory{ } /** - * @param string $baseClass - * @param World $world - * @param Vector3 $pos - * * @return Tile (will be an instanceof $baseClass) * @throws \InvalidArgumentException if the specified class is not a registered tile */ @@ -149,12 +144,7 @@ final class TileFactory{ } /** - * @param World $world - * @param CompoundTag $nbt - * - * @return Tile|null *@internal - * */ public static function createFromData(World $world, CompoundTag $nbt) : ?Tile{ $type = $nbt->getString(Tile::TAG_ID, "", true); diff --git a/src/block/utils/BannerPattern.php b/src/block/utils/BannerPattern.php index 857bde3ac2..5d77cde81e 100644 --- a/src/block/utils/BannerPattern.php +++ b/src/block/utils/BannerPattern.php @@ -79,16 +79,10 @@ class BannerPattern{ $this->color = $color; } - /** - * @return string - */ public function getId() : string{ return $this->id; } - /** - * @return DyeColor - */ public function getColor() : DyeColor{ return $this->color; } diff --git a/src/block/utils/BlockDataSerializer.php b/src/block/utils/BlockDataSerializer.php index db0ae9ead4..95849dac22 100644 --- a/src/block/utils/BlockDataSerializer.php +++ b/src/block/utils/BlockDataSerializer.php @@ -32,9 +32,6 @@ final class BlockDataSerializer{ } /** - * @param int $raw - * - * @return int * @throws InvalidBlockStateException */ public static function readFacing(int $raw) : int{ @@ -68,9 +65,6 @@ final class BlockDataSerializer{ } /** - * @param int $facing - * - * @return int * @throws InvalidBlockStateException */ public static function readHorizontalFacing(int $facing) : int{ @@ -89,9 +83,6 @@ final class BlockDataSerializer{ } /** - * @param int $raw - * - * @return int * @throws InvalidBlockStateException */ public static function readLegacyHorizontalFacing(int $raw) : int{ @@ -121,9 +112,6 @@ final class BlockDataSerializer{ } /** - * @param int $value - * - * @return int * @throws InvalidBlockStateException */ public static function read5MinusHorizontalFacing(int $value) : int{ diff --git a/src/block/utils/DyeColor.php b/src/block/utils/DyeColor.php index 3540d62a31..764e138333 100644 --- a/src/block/utils/DyeColor.php +++ b/src/block/utils/DyeColor.php @@ -87,10 +87,8 @@ final class DyeColor{ * Returns a DyeColor object matching the given magic number * @internal * - * @param int $magicNumber * @param bool $inverted Invert the ID before using it (useful for actual dye magic IDs) * - * @return DyeColor * @throws \InvalidArgumentException */ public static function fromMagicNumber(int $magicNumber, bool $inverted = false) : DyeColor{ @@ -116,30 +114,18 @@ final class DyeColor{ $this->rgbValue = $rgbValue; } - /** - * @return string - */ public function getDisplayName() : string{ return $this->displayName; } - /** - * @return Color - */ public function getRgbValue() : Color{ return $this->rgbValue; } - /** - * @return int - */ public function getMagicNumber() : int{ return $this->magicNumber; } - /** - * @return int - */ public function getInvertedMagicNumber() : int{ return ~$this->magicNumber & 0xf; } diff --git a/src/block/utils/Fallable.php b/src/block/utils/Fallable.php index 1eb3cd12d6..70ac23e687 100644 --- a/src/block/utils/Fallable.php +++ b/src/block/utils/Fallable.php @@ -31,8 +31,6 @@ interface Fallable{ * Called every tick by FallingBlock to update the falling state of this block. Used by concrete to check when it * hits water. * Return null if you don't want to change the usual behaviour. - * - * @return Block|null */ public function tickFalling() : ?Block; } diff --git a/src/block/utils/PillarRotationTrait.php b/src/block/utils/PillarRotationTrait.php index 639dd3ed2a..fa7de1a4e1 100644 --- a/src/block/utils/PillarRotationTrait.php +++ b/src/block/utils/PillarRotationTrait.php @@ -41,7 +41,6 @@ trait PillarRotationTrait{ /** * @see Block::writeStateToMeta() - * @return int */ protected function writeStateToMeta() : int{ return $this->writeAxisToMeta(); @@ -49,9 +48,6 @@ trait PillarRotationTrait{ /** * @see Block::readStateFromData() - * - * @param int $id - * @param int $stateMeta */ public function readStateFromData(int $id, int $stateMeta) : void{ $this->readAxisFromMeta($stateMeta); @@ -59,7 +55,6 @@ trait PillarRotationTrait{ /** * @see Block::getStateBitmask() - * @return int */ public function getStateBitmask() : int{ return 0b11 << $this->getAxisMetaShift(); @@ -89,16 +84,6 @@ trait PillarRotationTrait{ /** * @see Block::place() - * - * @param BlockTransaction $tx - * @param Item $item - * @param Block $blockReplace - * @param Block $blockClicked - * @param int $face - * @param Vector3 $clickVector - * @param Player|null $player - * - * @return bool */ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->axis = Facing::axis($face); diff --git a/src/block/utils/SignText.php b/src/block/utils/SignText.php index 364b0ebea4..a4ab838bbf 100644 --- a/src/block/utils/SignText.php +++ b/src/block/utils/SignText.php @@ -50,9 +50,6 @@ class SignText{ * Parses sign lines from the given string blob. * TODO: add a strict mode for this * - * @param string $blob - * - * @return SignText * @throws \InvalidArgumentException if the text is not valid UTF-8 */ public static function fromBlob(string $blob) : SignText{ @@ -101,9 +98,6 @@ class SignText{ /** * Returns the sign line at the given offset. * - * @param int $index - * - * @return string * @throws \InvalidArgumentException */ public function getLine(int $index) : string{ @@ -114,9 +108,6 @@ class SignText{ /** * Sets the line at the given offset. * - * @param int $index - * @param string $line - * * @throws \InvalidArgumentException if the text is not valid UTF-8 * @throws \InvalidArgumentException if the text contains a newline */ diff --git a/src/block/utils/SkullType.php b/src/block/utils/SkullType.php index 38bdc20f61..408d68741c 100644 --- a/src/block/utils/SkullType.php +++ b/src/block/utils/SkullType.php @@ -64,9 +64,7 @@ final class SkullType{ /** * @internal - * @param int $magicNumber * - * @return SkullType * @throws \InvalidArgumentException */ public static function fromMagicNumber(int $magicNumber) : SkullType{ @@ -87,16 +85,10 @@ final class SkullType{ $this->magicNumber = $magicNumber; } - /** - * @return string - */ public function getDisplayName() : string{ return $this->displayName; } - /** - * @return int - */ public function getMagicNumber() : int{ return $this->magicNumber; } diff --git a/src/block/utils/TreeType.php b/src/block/utils/TreeType.php index 8e0622dd6b..4d880169af 100644 --- a/src/block/utils/TreeType.php +++ b/src/block/utils/TreeType.php @@ -65,9 +65,6 @@ final class TreeType{ /** * @internal * - * @param int $magicNumber - * - * @return TreeType * @throws \InvalidArgumentException */ public static function fromMagicNumber(int $magicNumber) : TreeType{ @@ -83,27 +80,16 @@ final class TreeType{ /** @var int */ private $magicNumber; - /** - * @param string $enumName - * @param string $displayName - * @param int $magicNumber - */ private function __construct(string $enumName, string $displayName, int $magicNumber){ $this->Enum___construct($enumName); $this->displayName = $displayName; $this->magicNumber = $magicNumber; } - /** - * @return string - */ public function getDisplayName() : string{ return $this->displayName; } - /** - * @return int - */ public function getMagicNumber() : int{ return $this->magicNumber; } diff --git a/src/command/Command.php b/src/command/Command.php index 87aae29c37..fbf73b3549 100644 --- a/src/command/Command.php +++ b/src/command/Command.php @@ -74,8 +74,6 @@ abstract class Command{ public $timings; /** - * @param string $name - * @param string $description * @param string $usageMessage * @param string[] $aliases */ @@ -88,8 +86,6 @@ abstract class Command{ } /** - * @param CommandSender $sender - * @param string $commandLabel * @param string[] $args * * @return mixed @@ -97,33 +93,18 @@ abstract class Command{ */ abstract public function execute(CommandSender $sender, string $commandLabel, array $args); - /** - * @return string - */ public function getName() : string{ return $this->name; } - /** - * @return string|null - */ public function getPermission() : ?string{ return $this->permission; } - - /** - * @param string|null $permission - */ public function setPermission(?string $permission) : void{ $this->permission = $permission; } - /** - * @param CommandSender $target - * - * @return bool - */ public function testPermission(CommandSender $target) : bool{ if($this->testPermissionSilent($target)){ return true; @@ -138,11 +119,6 @@ abstract class Command{ return false; } - /** - * @param CommandSender $target - * - * @return bool - */ public function testPermissionSilent(CommandSender $target) : bool{ if($this->permission === null or $this->permission === ""){ return true; @@ -157,9 +133,6 @@ abstract class Command{ return false; } - /** - * @return string - */ public function getLabel() : string{ return $this->label; } @@ -181,10 +154,6 @@ abstract class Command{ /** * Registers the command into a Command map - * - * @param CommandMap $commandMap - * - * @return bool */ public function register(CommandMap $commandMap) : bool{ if($this->allowChangesFrom($commandMap)){ @@ -196,11 +165,6 @@ abstract class Command{ return false; } - /** - * @param CommandMap $commandMap - * - * @return bool - */ public function unregister(CommandMap $commandMap) : bool{ if($this->allowChangesFrom($commandMap)){ $this->commandMap = null; @@ -213,18 +177,10 @@ abstract class Command{ return false; } - /** - * @param CommandMap $commandMap - * - * @return bool - */ private function allowChangesFrom(CommandMap $commandMap) : bool{ return $this->commandMap === null or $this->commandMap === $commandMap; } - /** - * @return bool - */ public function isRegistered() : bool{ return $this->commandMap !== null; } @@ -236,23 +192,14 @@ abstract class Command{ return $this->activeAliases; } - /** - * @return string|null - */ public function getPermissionMessage() : ?string{ return $this->permissionMessage; } - /** - * @return string - */ public function getDescription() : string{ return $this->description; } - /** - * @return string - */ public function getUsage() : string{ return $this->usageMessage; } @@ -267,31 +214,20 @@ abstract class Command{ } } - /** - * @param string $description - */ public function setDescription(string $description) : void{ $this->description = $description; } - /** - * @param string $permissionMessage - */ public function setPermissionMessage(string $permissionMessage) : void{ $this->permissionMessage = $permissionMessage; } - /** - * @param string $usage - */ public function setUsage(string $usage) : void{ $this->usageMessage = $usage; } /** - * @param CommandSender $source * @param TextContainer|string $message - * @param bool $sendToSource */ public static function broadcastCommandMessage(CommandSender $source, $message, bool $sendToSource = true) : void{ $users = PermissionManager::getInstance()->getPermissionSubscriptions(Server::BROADCAST_CHANNEL_ADMINISTRATIVE); @@ -325,9 +261,6 @@ abstract class Command{ } } - /** - * @return string - */ public function __toString() : string{ return $this->name; } diff --git a/src/command/CommandExecutor.php b/src/command/CommandExecutor.php index fcc75f15ff..1efcd5f525 100644 --- a/src/command/CommandExecutor.php +++ b/src/command/CommandExecutor.php @@ -27,12 +27,7 @@ namespace pocketmine\command; interface CommandExecutor{ /** - * @param CommandSender $sender - * @param Command $command - * @param string $label * @param string[] $args - * - * @return bool */ public function onCommand(CommandSender $sender, Command $command, string $label, array $args) : bool; diff --git a/src/command/CommandMap.php b/src/command/CommandMap.php index c8dda90193..fa1b63cbd8 100644 --- a/src/command/CommandMap.php +++ b/src/command/CommandMap.php @@ -27,38 +27,16 @@ namespace pocketmine\command; interface CommandMap{ /** - * @param string $fallbackPrefix * @param Command[] $commands */ public function registerAll(string $fallbackPrefix, array $commands) : void; - /** - * @param string $fallbackPrefix - * @param Command $command - * @param string|null $label - * - * @return bool - */ public function register(string $fallbackPrefix, Command $command, ?string $label = null) : bool; - /** - * @param CommandSender $sender - * @param string $cmdLine - * - * @return bool - */ public function dispatch(CommandSender $sender, string $cmdLine) : bool; - /** - * @return void - */ public function clearCommands() : void; - /** - * @param string $name - * - * @return Command|null - */ public function getCommand(string $name) : ?Command; diff --git a/src/command/CommandReader.php b/src/command/CommandReader.php index 0a9f7f3a6b..c1310e486f 100644 --- a/src/command/CommandReader.php +++ b/src/command/CommandReader.php @@ -114,8 +114,6 @@ class CommandReader extends Thread{ * Checks if the specified stream is a FIFO pipe. * * @param resource $stream - * - * @return bool */ private function isPipe($stream) : bool{ return is_resource($stream) and (!stream_isatty($stream) or ((fstat($stream)["mode"] & 0170000) === 0010000)); @@ -177,8 +175,6 @@ class CommandReader extends Thread{ /** * Reads a line from console, if available. Returns null if not available - * - * @return string|null */ public function getLine() : ?string{ if($this->buffer->count() !== 0){ diff --git a/src/command/CommandSender.php b/src/command/CommandSender.php index ab707ffcad..86406bb7d1 100644 --- a/src/command/CommandSender.php +++ b/src/command/CommandSender.php @@ -34,28 +34,18 @@ interface CommandSender extends Permissible{ */ public function sendMessage($message) : void; - /** - * @return Server - */ public function getServer() : Server; - /** - * @return string - */ public function getName() : string; /** * Returns the line height of the command-sender's screen. Used for determining sizes for command output pagination * such as in the /help command. - * - * @return int */ public function getScreenLineHeight() : int; /** * Sets the line height used for command output pagination for this command sender. `null` will reset it to default. - * - * @param int|null $height */ public function setScreenLineHeight(?int $height) : void; } diff --git a/src/command/ConsoleCommandSender.php b/src/command/ConsoleCommandSender.php index a80a3c235f..6eb61b4963 100644 --- a/src/command/ConsoleCommandSender.php +++ b/src/command/ConsoleCommandSender.php @@ -41,9 +41,6 @@ class ConsoleCommandSender implements CommandSender{ $this->perm = new PermissibleBase($this); } - /** - * @return Server - */ public function getServer() : Server{ return Server::getInstance(); } @@ -64,23 +61,14 @@ class ConsoleCommandSender implements CommandSender{ } } - /** - * @return string - */ public function getName() : string{ return "CONSOLE"; } - /** - * @return bool - */ public function isOp() : bool{ return true; } - /** - * @param bool $value - */ public function setOp(bool $value) : void{ } diff --git a/src/command/FormattedCommandAlias.php b/src/command/FormattedCommandAlias.php index d6daabed16..cfad083471 100644 --- a/src/command/FormattedCommandAlias.php +++ b/src/command/FormattedCommandAlias.php @@ -36,7 +36,6 @@ class FormattedCommandAlias extends Command{ private $formatStrings = []; /** - * @param string $alias * @param string[] $formatStrings */ public function __construct(string $alias, array $formatStrings){ @@ -65,12 +64,6 @@ class FormattedCommandAlias extends Command{ return (bool) $result; } - /** - * @param string $formatString - * @param array $args - * - * @return string - */ private function buildCommand(string $formatString, array $args) : string{ $index = strpos($formatString, '$'); while($index !== false){ @@ -144,13 +137,6 @@ class FormattedCommandAlias extends Command{ return $formatString; } - /** - * @param int $i - * @param int $j - * @param int $k - * - * @return bool - */ private static function inRange(int $i, int $j, int $k) : bool{ return $i >= $j and $i <= $k; } diff --git a/src/command/PluginCommand.php b/src/command/PluginCommand.php index 87c96bb320..827239c268 100644 --- a/src/command/PluginCommand.php +++ b/src/command/PluginCommand.php @@ -34,11 +34,6 @@ class PluginCommand extends Command implements PluginIdentifiableCommand{ /** @var CommandExecutor */ private $executor; - /** - * @param string $name - * @param Plugin $owner - * @param CommandExecutor $executor - */ public function __construct(string $name, Plugin $owner, CommandExecutor $executor){ parent::__construct($name); $this->owningPlugin = $owner; @@ -69,16 +64,10 @@ class PluginCommand extends Command implements PluginIdentifiableCommand{ return $this->executor; } - /** - * @param CommandExecutor $executor - */ public function setExecutor(CommandExecutor $executor) : void{ $this->executor = $executor; } - /** - * @return Plugin - */ public function getPlugin() : Plugin{ return $this->owningPlugin; } diff --git a/src/command/PluginIdentifiableCommand.php b/src/command/PluginIdentifiableCommand.php index 035bdc3277..02e85f7e92 100644 --- a/src/command/PluginIdentifiableCommand.php +++ b/src/command/PluginIdentifiableCommand.php @@ -27,8 +27,5 @@ use pocketmine\plugin\Plugin; interface PluginIdentifiableCommand{ - /** - * @return Plugin - */ public function getPlugin() : Plugin; } diff --git a/src/command/SimpleCommandMap.php b/src/command/SimpleCommandMap.php index 1374c53a80..1eff4dd702 100644 --- a/src/command/SimpleCommandMap.php +++ b/src/command/SimpleCommandMap.php @@ -142,13 +142,6 @@ class SimpleCommandMap implements CommandMap{ } } - /** - * @param string $fallbackPrefix - * @param Command $command - * @param string|null $label - * - * @return bool - */ public function register(string $fallbackPrefix, Command $command, ?string $label = null) : bool{ if($label === null){ $label = $command->getName(); @@ -175,11 +168,6 @@ class SimpleCommandMap implements CommandMap{ return $registered; } - /** - * @param Command $command - * - * @return bool - */ public function unregister(Command $command) : bool{ foreach($this->knownCommands as $lbl => $cmd){ if($cmd === $command){ @@ -192,14 +180,6 @@ class SimpleCommandMap implements CommandMap{ return true; } - /** - * @param Command $command - * @param bool $isAlias - * @param string $fallbackPrefix - * @param string $label - * - * @return bool - */ private function registerAlias(Command $command, bool $isAlias, string $fallbackPrefix, string $label) : bool{ $this->knownCommands[$fallbackPrefix . ":" . $label] = $command; if(($command instanceof VanillaCommand or $isAlias) and isset($this->knownCommands[$label])){ @@ -226,8 +206,6 @@ class SimpleCommandMap implements CommandMap{ * * @param string $commandName reference parameter * @param string[] $args reference parameter - * - * @return Command|null */ public function matchCommand(string &$commandName, array &$args) : ?Command{ $count = min(count($args), 255); @@ -294,10 +272,6 @@ class SimpleCommandMap implements CommandMap{ return $this->knownCommands; } - - /** - * @return void - */ public function registerServerAliases() : void{ $values = $this->server->getCommandAliases(); diff --git a/src/command/defaults/ParticleCommand.php b/src/command/defaults/ParticleCommand.php index 904c4ebe05..18342534c2 100644 --- a/src/command/defaults/ParticleCommand.php +++ b/src/command/defaults/ParticleCommand.php @@ -137,12 +137,6 @@ class ParticleCommand extends VanillaCommand{ return true; } - /** - * @param string $name - * @param int|null $data - * - * @return Particle|null - */ private function getParticle(string $name, ?int $data = null) : ?Particle{ switch($name){ case "explode": diff --git a/src/command/defaults/VanillaCommand.php b/src/command/defaults/VanillaCommand.php index 50c5313a15..c4b821e6da 100644 --- a/src/command/defaults/VanillaCommand.php +++ b/src/command/defaults/VanillaCommand.php @@ -36,12 +36,7 @@ abstract class VanillaCommand extends Command{ public const MIN_COORD = -30000000; /** - * @param CommandSender $sender * @param mixed $value - * @param int $min - * @param int $max - * - * @return int */ protected function getInteger(CommandSender $sender, $value, int $min = self::MIN_COORD, int $max = self::MAX_COORD) : int{ $i = (int) $value; @@ -55,15 +50,6 @@ abstract class VanillaCommand extends Command{ return $i; } - /** - * @param float $original - * @param CommandSender $sender - * @param string $input - * @param float $min - * @param float $max - * - * @return float - */ protected function getRelativeDouble(float $original, CommandSender $sender, string $input, float $min = self::MIN_COORD, float $max = self::MAX_COORD) : float{ if($input[0] === "~"){ $value = $this->getDouble($sender, substr($input, 1)); @@ -75,12 +61,7 @@ abstract class VanillaCommand extends Command{ } /** - * @param CommandSender $sender * @param mixed $value - * @param float $min - * @param float $max - * - * @return float */ protected function getDouble(CommandSender $sender, $value, float $min = self::MIN_COORD, float $max = self::MAX_COORD) : float{ $i = (double) $value; diff --git a/src/crafting/CraftingGrid.php b/src/crafting/CraftingGrid.php index 8812866bfa..cec88d9667 100644 --- a/src/crafting/CraftingGrid.php +++ b/src/crafting/CraftingGrid.php @@ -105,11 +105,6 @@ class CraftingGrid extends BaseInventory{ /** * Returns the item at offset x,y, offset by where the starts of the recipe rectangle are. - * - * @param int $x - * @param int $y - * - * @return Item */ public function getIngredient(int $x, int $y) : Item{ if($this->startX !== null and $this->startY !== null){ @@ -121,8 +116,6 @@ class CraftingGrid extends BaseInventory{ /** * Returns the width of the recipe we're trying to craft, based on items currently in the grid. - * - * @return int */ public function getRecipeWidth() : int{ return $this->xLen ?? 0; @@ -130,7 +123,6 @@ class CraftingGrid extends BaseInventory{ /** * Returns the height of the recipe we're trying to craft, based on items currently in the grid. - * @return int */ public function getRecipeHeight() : int{ return $this->yLen ?? 0; diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index b35e6b42c4..cdd740ba7c 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -124,8 +124,6 @@ class CraftingManager{ /** * Returns a pre-compressed CraftingDataPacket for sending to players. Rebuilds the cache if it is not found. - * - * @return CompressBatchPromise */ public function getCraftingDataPacket() : CompressBatchPromise{ if($this->craftingDataCache === null){ @@ -137,11 +135,6 @@ class CraftingManager{ /** * Function used to arrange Shapeless Recipe ingredient lists into a consistent order. - * - * @param Item $i1 - * @param Item $i2 - * - * @return int */ public static function sort(Item $i1, Item $i2) : int{ //Use spaceship operator to compare each property, then try the next one if they are equivalent. @@ -206,27 +199,18 @@ class CraftingManager{ return $this->furnaceRecipes; } - /** - * @param ShapedRecipe $recipe - */ public function registerShapedRecipe(ShapedRecipe $recipe) : void{ $this->shapedRecipes[self::hashOutputs($recipe->getResults())][] = $recipe; $this->craftingDataCache = null; } - /** - * @param ShapelessRecipe $recipe - */ public function registerShapelessRecipe(ShapelessRecipe $recipe) : void{ $this->shapelessRecipes[self::hashOutputs($recipe->getResults())][] = $recipe; $this->craftingDataCache = null; } - /** - * @param FurnaceRecipe $recipe - */ public function registerFurnaceRecipe(FurnaceRecipe $recipe) : void{ $input = $recipe->getInput(); $this->furnaceRecipes[$input->getId() . ":" . ($input->hasAnyDamageValue() ? "?" : $input->getMeta())] = $recipe; @@ -234,10 +218,7 @@ class CraftingManager{ } /** - * @param CraftingGrid $grid * @param Item[] $outputs - * - * @return CraftingRecipe|null */ public function matchRecipe(CraftingGrid $grid, array $outputs) : ?CraftingRecipe{ //TODO: try to match special recipes before anything else (first they need to be implemented!) @@ -286,11 +267,6 @@ class CraftingManager{ } } - /** - * @param Item $input - * - * @return FurnaceRecipe|null - */ public function matchFurnaceRecipe(Item $input) : ?FurnaceRecipe{ return $this->furnaceRecipes[$input->getId() . ":" . $input->getMeta()] ?? $this->furnaceRecipes[$input->getId() . ":?"] ?? null; } diff --git a/src/crafting/CraftingRecipe.php b/src/crafting/CraftingRecipe.php index 5a64c43090..44c387eff3 100644 --- a/src/crafting/CraftingRecipe.php +++ b/src/crafting/CraftingRecipe.php @@ -36,18 +36,12 @@ interface CraftingRecipe{ /** * Returns a list of results this recipe will produce when the inputs in the given crafting grid are consumed. * - * @param CraftingGrid $grid - * * @return Item[] */ public function getResultsFor(CraftingGrid $grid) : array; /** * Returns whether the given crafting grid meets the requirements to craft this recipe. - * - * @param CraftingGrid $grid - * - * @return bool */ public function matchesCraftingGrid(CraftingGrid $grid) : bool; } diff --git a/src/crafting/FurnaceRecipe.php b/src/crafting/FurnaceRecipe.php index cc1a4bf6ed..55a6104fec 100644 --- a/src/crafting/FurnaceRecipe.php +++ b/src/crafting/FurnaceRecipe.php @@ -33,25 +33,15 @@ class FurnaceRecipe{ /** @var Item */ private $ingredient; - /** - * @param Item $result - * @param Item $ingredient - */ public function __construct(Item $result, Item $ingredient){ $this->output = clone $result; $this->ingredient = clone $ingredient; } - /** - * @return Item - */ public function getInput() : Item{ return clone $this->ingredient; } - /** - * @return Item - */ public function getResult() : Item{ return clone $this->output; } diff --git a/src/crafting/ShapedRecipe.php b/src/crafting/ShapedRecipe.php index 278f725f81..1511224e04 100644 --- a/src/crafting/ShapedRecipe.php +++ b/src/crafting/ShapedRecipe.php @@ -114,8 +114,6 @@ class ShapedRecipe implements CraftingRecipe{ } /** - * @param CraftingGrid $grid - * * @return Item[] */ public function getResultsFor(CraftingGrid $grid) : array{ @@ -155,12 +153,6 @@ class ShapedRecipe implements CraftingRecipe{ return $ingredients; } - /** - * @param int $x - * @param int $y - * - * @return Item - */ public function getIngredient(int $x, int $y) : Item{ $exists = $this->ingredientList[$this->shape[$y]{$x}] ?? null; return $exists !== null ? clone $exists : ItemFactory::air(); @@ -174,12 +166,6 @@ class ShapedRecipe implements CraftingRecipe{ return $this->shape; } - /** - * @param CraftingGrid $grid - * @param bool $reverse - * - * @return bool - */ private function matchInputMap(CraftingGrid $grid, bool $reverse) : bool{ for($y = 0; $y < $this->height; ++$y){ for($x = 0; $x < $this->width; ++$x){ @@ -195,11 +181,6 @@ class ShapedRecipe implements CraftingRecipe{ return true; } - /** - * @param CraftingGrid $grid - * - * @return bool - */ public function matchesCraftingGrid(CraftingGrid $grid) : bool{ if($this->width !== $grid->getRecipeWidth() or $this->height !== $grid->getRecipeHeight()){ return false; diff --git a/src/crafting/ShapelessRecipe.php b/src/crafting/ShapelessRecipe.php index e772ee197f..53f20f55d5 100644 --- a/src/crafting/ShapelessRecipe.php +++ b/src/crafting/ShapelessRecipe.php @@ -67,9 +67,6 @@ class ShapelessRecipe implements CraftingRecipe{ return Utils::cloneObjectArray($this->ingredients); } - /** - * @return int - */ public function getIngredientCount() : int{ $count = 0; foreach($this->ingredients as $ingredient){ @@ -79,11 +76,6 @@ class ShapelessRecipe implements CraftingRecipe{ return $count; } - /** - * @param CraftingGrid $grid - * - * @return bool - */ public function matchesCraftingGrid(CraftingGrid $grid) : bool{ //don't pack the ingredients - shapeless recipes require that each ingredient be in a separate slot $input = $grid->getContents(); diff --git a/src/entity/Attribute.php b/src/entity/Attribute.php index 8778596ee8..38f22547f4 100644 --- a/src/entity/Attribute.php +++ b/src/entity/Attribute.php @@ -86,14 +86,6 @@ class Attribute{ } /** - * @param string $id - * @param float $minValue - * @param float $maxValue - * @param float $defaultValue - * @param bool $shouldSend - * - * @return Attribute - * * @throws \InvalidArgumentException */ public static function register(string $id, float $minValue, float $maxValue, float $defaultValue, bool $shouldSend = true) : Attribute{ @@ -104,11 +96,6 @@ class Attribute{ return self::$attributes[$id] = new Attribute($id, $minValue, $maxValue, $defaultValue, $shouldSend); } - /** - * @param string $id - * - * @return Attribute|null - */ public static function get(string $id) : ?Attribute{ return isset(self::$attributes[$id]) ? clone self::$attributes[$id] : null; } @@ -128,8 +115,6 @@ class Attribute{ } /** - * @param float $minValue - * * @return $this */ public function setMinValue(float $minValue){ @@ -149,8 +134,6 @@ class Attribute{ } /** - * @param float $maxValue - * * @return $this */ public function setMaxValue(float $maxValue){ @@ -170,8 +153,6 @@ class Attribute{ } /** - * @param float $defaultValue - * * @return $this */ public function setDefaultValue(float $defaultValue){ @@ -195,10 +176,6 @@ class Attribute{ } /** - * @param float $value - * @param bool $fit - * @param bool $forceSend - * * @return $this */ public function setValue(float $value, bool $fit = false, bool $forceSend = false){ diff --git a/src/entity/AttributeMap.php b/src/entity/AttributeMap.php index 70575c869e..60318f3bdb 100644 --- a/src/entity/AttributeMap.php +++ b/src/entity/AttributeMap.php @@ -33,11 +33,6 @@ class AttributeMap{ $this->attributes[$attribute->getId()] = $attribute; } - /** - * @param string $id - * - * @return Attribute|null - */ public function get(string $id) : ?Attribute{ return $this->attributes[$id] ?? null; } diff --git a/src/entity/Entity.php b/src/entity/Entity.php index daa095d029..067b135d55 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -281,72 +281,42 @@ abstract class Entity{ } - /** - * @return string - */ public function getNameTag() : string{ return $this->nameTag; } - /** - * @return bool - */ public function isNameTagVisible() : bool{ return $this->nameTagVisible; } - /** - * @return bool - */ public function isNameTagAlwaysVisible() : bool{ return $this->alwaysShowNameTag; } - /** - * @param string $name - */ public function setNameTag(string $name) : void{ $this->nameTag = $name; } - /** - * @param bool $value - */ public function setNameTagVisible(bool $value = true) : void{ $this->nameTagVisible = $value; } - /** - * @param bool $value - */ public function setNameTagAlwaysVisible(bool $value = true) : void{ $this->alwaysShowNameTag = $value; } - /** - * @return string|null - */ public function getScoreTag() : ?string{ return $this->scoreTag; //TODO: maybe this shouldn't be nullable? } - /** - * @param string $score - */ public function setScoreTag(string $score) : void{ $this->scoreTag = $score; } - /** - * @return float - */ public function getScale() : float{ return $this->scale; } - /** - * @param float $value - */ public function setScale(float $value) : void{ if($value <= 0){ throw new \InvalidArgumentException("Scale must be greater than 0"); @@ -417,7 +387,6 @@ abstract class Entity{ /** * Returns whether the entity is able to climb blocks such as ladders or vines. - * @return bool */ public function canClimb() : bool{ return $this->canClimb; @@ -425,8 +394,6 @@ abstract class Entity{ /** * Sets whether the entity is able to climb climbable blocks. - * - * @param bool $value */ public function setCanClimb(bool $value = true) : void{ $this->canClimb = $value; @@ -434,8 +401,6 @@ abstract class Entity{ /** * Returns whether this entity is climbing a block. By default this is only true if the entity is climbing a ladder or vine or similar block. - * - * @return bool */ public function canClimbWalls() : bool{ return $this->canClimbWalls; @@ -443,8 +408,6 @@ abstract class Entity{ /** * Sets whether the entity is climbing a block. If true, the entity can climb anything. - * - * @param bool $value */ public function setCanClimbWalls(bool $value = true) : void{ $this->canClimbWalls = $value; @@ -452,7 +415,6 @@ abstract class Entity{ /** * Returns the entity ID of the owning entity, or null if the entity doesn't have an owner. - * @return int|null */ public function getOwningEntityId() : ?int{ return $this->ownerId; @@ -460,7 +422,6 @@ abstract class Entity{ /** * Returns the owning entity, or null if the entity was not found. - * @return Entity|null */ public function getOwningEntity() : ?Entity{ return $this->ownerId !== null ? $this->server->getWorldManager()->findEntity($this->ownerId) : null; @@ -469,8 +430,6 @@ abstract class Entity{ /** * Sets the owner of the entity. Passing null will remove the current owner. * - * @param Entity|null $owner - * * @throws \InvalidArgumentException if the supplied entity is not valid */ public function setOwningEntity(?Entity $owner) : void{ @@ -485,7 +444,6 @@ abstract class Entity{ /** * Returns the entity ID of the entity's target, or null if it doesn't have a target. - * @return int|null */ public function getTargetEntityId() : ?int{ return $this->targetId; @@ -494,8 +452,6 @@ abstract class Entity{ /** * Returns the entity's target entity, or null if not found. * This is used for things like hostile mobs attacking entities, and for fishing rods reeling hit entities in. - * - * @return Entity|null */ public function getTargetEntity() : ?Entity{ return $this->targetId !== null ? $this->server->getWorldManager()->findEntity($this->targetId) : null; @@ -504,8 +460,6 @@ abstract class Entity{ /** * Sets the entity's target entity. Passing null will remove the current target. * - * @param Entity|null $target - * * @throws \InvalidArgumentException if the target entity is not valid */ public function setTargetEntity(?Entity $target) : void{ @@ -520,7 +474,6 @@ abstract class Entity{ /** * Returns whether this entity will be saved when its chunk is unloaded. - * @return bool */ public function canSaveWithChunk() : bool{ return $this->savedWithChunk; @@ -529,8 +482,6 @@ abstract class Entity{ /** * Sets whether this entity will be saved when its chunk is unloaded. This can be used to prevent the entity being * saved to disk. - * - * @param bool $value */ public function setCanSaveWithChunk(bool $value) : void{ $this->savedWithChunk = $value; @@ -596,9 +547,6 @@ abstract class Entity{ } - /** - * @param EntityDamageEvent $source - */ public function attack(EntityDamageEvent $source) : void{ $source->call(); if($source->isCancelled()){ @@ -610,9 +558,6 @@ abstract class Entity{ $this->setHealth($this->getHealth() - $source->getFinalDamage()); } - /** - * @param EntityRegainHealthEvent $source - */ public function heal(EntityRegainHealthEvent $source) : void{ $source->call(); if($source->isCancelled()){ @@ -639,10 +584,6 @@ abstract class Entity{ /** * Called to tick entities while dead. Returns whether the entity should be flagged for despawn yet. - * - * @param int $tickDiff - * - * @return bool */ protected function onDeathUpdate(int $tickDiff) : bool{ return true; @@ -652,17 +593,12 @@ abstract class Entity{ return $this->health > 0; } - /** - * @return float - */ public function getHealth() : float{ return $this->health; } /** * Sets the health of the Entity. This won't send any update to the players - * - * @param float $amount */ public function setHealth(float $amount) : void{ if($amount == $this->health){ @@ -680,30 +616,18 @@ abstract class Entity{ } } - /** - * @return int - */ public function getMaxHealth() : int{ return $this->maxHealth; } - /** - * @param int $amount - */ public function setMaxHealth(int $amount) : void{ $this->maxHealth = $amount; } - /** - * @param EntityDamageEvent $type - */ public function setLastDamageCause(EntityDamageEvent $type) : void{ $this->lastDamageCause = $type; } - /** - * @return EntityDamageEvent|null - */ public function getLastDamageCause() : ?EntityDamageEvent{ return $this->lastDamageCause; } @@ -764,15 +688,11 @@ abstract class Entity{ } } - /** - * @return int - */ public function getFireTicks() : int{ return $this->fireTicks; } /** - * @param int $fireTicks * @throws \InvalidArgumentException */ public function setFireTicks(int $fireTicks) : void{ @@ -1033,9 +953,6 @@ abstract class Entity{ return Facing::EAST; } - /** - * @return Vector3 - */ public function getDirectionVector() : Vector3{ $y = -sin(deg2rad($this->location->pitch)); $xz = cos(deg2rad($this->location->pitch)); @@ -1125,8 +1042,6 @@ abstract class Entity{ /** * Flags the entity as needing a movement update on the next tick. Setting this forces a movement update even if the * entity's motion is zero. Used to trigger movement updates when blocks change near entities. - * - * @param bool $value */ final public function setForceMovementUpdate(bool $value = true) : void{ $this->forceMovementUpdate = $value; @@ -1136,7 +1051,6 @@ abstract class Entity{ /** * Returns whether the entity needs a movement update on the next tick. - * @return bool */ public function hasMovementUpdate() : bool{ return ( @@ -1152,10 +1066,6 @@ abstract class Entity{ $this->fallDistance = 0.0; } - /** - * @param float $distanceThisTick - * @param bool $onGround - */ protected function updateFallState(float $distanceThisTick, bool $onGround) : void{ if($onGround){ if($this->fallDistance > 0){ @@ -1169,8 +1079,6 @@ abstract class Entity{ /** * Called when a falling entity hits the ground. - * - * @param float $fallDistance */ public function fall(float $fallDistance) : void{ @@ -1397,8 +1305,6 @@ abstract class Entity{ /** * Returns whether this entity can be moved by currents in liquids. - * - * @return bool */ public function canBeMovedByCurrents() : bool{ return true; @@ -1533,10 +1439,6 @@ abstract class Entity{ /** * Adds the given values to the entity's motion vector. - * - * @param float $x - * @param float $y - * @param float $z */ public function addMotion(float $x, float $y, float $z) : void{ $this->motion->x += $x; @@ -1550,10 +1452,6 @@ abstract class Entity{ /** * @param Vector3|Position|Location $pos - * @param float|null $yaw - * @param float|null $pitch - * - * @return bool */ public function teleport(Vector3 $pos, ?float $yaw = null, ?float $pitch = null) : bool{ if($pos instanceof Location){ @@ -1615,8 +1513,6 @@ abstract class Entity{ /** * Called by spawnTo() to send whatever packets needed to spawn the entity to the client. - * - * @param Player $player */ protected function sendSpawnPacket(Player $player) : void{ $pk = new AddActorPacket(); @@ -1633,9 +1529,6 @@ abstract class Entity{ $player->getNetworkSession()->sendDataPacket($pk); } - /** - * @param Player $player - */ public function spawnTo(Player $player) : void{ $id = spl_object_id($player); if(!isset($this->hasSpawned[$id]) and $player->isUsingChunk($this->location->getFloorX() >> 4, $this->location->getFloorZ() >> 4)){ @@ -1664,9 +1557,6 @@ abstract class Entity{ /** * @deprecated WARNING: This function DOES NOT permanently hide the entity from the player. As soon as the entity or * player moves, the player will once again be able to see the entity. - * - * @param Player $player - * @param bool $send */ public function despawnFrom(Player $player, bool $send = true) : void{ $id = spl_object_id($player); @@ -1702,7 +1592,6 @@ abstract class Entity{ /** * Returns whether the entity has been "closed". - * @return bool */ public function isClosed() : bool{ return $this->closed; @@ -1773,8 +1662,6 @@ abstract class Entity{ } /** - * @param bool $dirtyOnly - * * @return MetadataProperty[] */ final protected function getSyncedNetworkData(bool $dirtyOnly) : array{ diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index a4de128fdb..51ba2176ae 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -163,8 +163,6 @@ final class EntityFactory{ /** * Returns a new runtime entity ID for a new entity. - * - * @return int */ public static function nextRuntimeId() : int{ return self::$entityCount++; @@ -176,9 +174,6 @@ final class EntityFactory{ * * TODO: make this NBT-independent * - * @param string $baseClass - * @param World $world - * @param CompoundTag $nbt * @param mixed ...$args * * @return Entity instanceof $baseClass @@ -203,10 +198,6 @@ final class EntityFactory{ /** * Creates an entity from data stored on a chunk. * - * @param World $world - * @param CompoundTag $nbt - * - * @return Entity|null * @throws \RuntimeException *@internal * @@ -243,13 +234,6 @@ final class EntityFactory{ /** * Helper function which creates minimal NBT needed to spawn an entity. - * - * @param Vector3 $pos - * @param Vector3|null $motion - * @param float $yaw - * @param float $pitch - * - * @return CompoundTag */ public static function createBaseNBT(Vector3 $pos, ?Vector3 $motion = null, float $yaw = 0.0, float $pitch = 0.0) : CompoundTag{ return CompoundTag::create() diff --git a/src/entity/ExperienceManager.php b/src/entity/ExperienceManager.php index 1d280812dd..49aea2c27a 100644 --- a/src/entity/ExperienceManager.php +++ b/src/entity/ExperienceManager.php @@ -64,7 +64,6 @@ class ExperienceManager{ /** * Returns the player's experience level. - * @return int */ public function getXpLevel() : int{ return (int) $this->levelAttr->getValue(); @@ -72,10 +71,6 @@ class ExperienceManager{ /** * Sets the player's experience level. This does not affect their total XP or their XP progress. - * - * @param int $level - * - * @return bool */ public function setXpLevel(int $level) : bool{ return $this->setXpAndProgress($level, null); @@ -83,11 +78,6 @@ class ExperienceManager{ /** * Adds a number of XP levels to the player. - * - * @param int $amount - * @param bool $playSound - * - * @return bool */ public function addXpLevels(int $amount, bool $playSound = true) : bool{ $oldLevel = $this->getXpLevel(); @@ -107,10 +97,6 @@ class ExperienceManager{ /** * Subtracts a number of XP levels from the player. - * - * @param int $amount - * - * @return bool */ public function subtractXpLevels(int $amount) : bool{ return $this->addXpLevels(-$amount); @@ -118,7 +104,6 @@ class ExperienceManager{ /** * Returns a value between 0.0 and 1.0 to indicate how far through the current level the player is. - * @return float */ public function getXpProgress() : float{ return $this->progressAttr->getValue(); @@ -126,10 +111,6 @@ class ExperienceManager{ /** * Sets the player's progress through the current level to a value between 0.0 and 1.0. - * - * @param float $progress - * - * @return bool */ public function setXpProgress(float $progress) : bool{ return $this->setXpAndProgress(null, $progress); @@ -137,7 +118,6 @@ class ExperienceManager{ /** * Returns the number of XP points the player has progressed into their current level. - * @return int */ public function getRemainderXp() : int{ return (int) (ExperienceUtils::getXpToCompleteLevel($this->getXpLevel()) * $this->getXpProgress()); @@ -147,8 +127,6 @@ class ExperienceManager{ * Returns the amount of XP points the player currently has, calculated from their current level and progress * through their current level. This will be reduced by enchanting deducting levels and is used to calculate the * amount of XP the player drops on death. - * - * @return int */ public function getCurrentTotalXp() : int{ return ExperienceUtils::getXpToReachLevel($this->getXpLevel()) + $this->getRemainderXp(); @@ -157,10 +135,6 @@ class ExperienceManager{ /** * Sets the current total of XP the player has, recalculating their XP level and progress. * Note that this DOES NOT update the player's lifetime total XP. - * - * @param int $amount - * - * @return bool */ public function setCurrentTotalXp(int $amount) : bool{ $newLevel = ExperienceUtils::getLevelFromXp($amount); @@ -172,10 +146,7 @@ class ExperienceManager{ * Adds an amount of XP to the player, recalculating their XP level and progress. XP amount will be added to the * player's lifetime XP. * - * @param int $amount * @param bool $playSound Whether to play level-up and XP gained sounds. - * - * @return bool */ public function addXp(int $amount, bool $playSound = true) : bool{ $this->totalXp += $amount; @@ -201,10 +172,6 @@ class ExperienceManager{ /** * Takes an amount of XP from the player, recalculating their XP level and progress. - * - * @param int $amount - * - * @return bool */ public function subtractXp(int $amount) : bool{ return $this->addXp(-$amount); @@ -234,9 +201,6 @@ class ExperienceManager{ /** * @internal - * - * @param int $level - * @param float $progress */ public function setXpAndProgressNoEvent(int $level, float $progress) : void{ $this->levelAttr->setValue($level); @@ -246,8 +210,6 @@ class ExperienceManager{ /** * Returns the total XP the player has collected in their lifetime. Resets when the player dies. * XP levels being removed in enchanting do not reduce this number. - * - * @return int */ public function getLifetimeTotalXp() : int{ return $this->totalXp; @@ -256,8 +218,6 @@ class ExperienceManager{ /** * Sets the lifetime total XP of the player. This does not recalculate their level or progress. Used for player * score when they die. (TODO: add this when MCPE supports it) - * - * @param int $amount */ public function setLifetimeTotalXp(int $amount) : void{ if($amount < 0){ @@ -270,7 +230,6 @@ class ExperienceManager{ /** * Returns whether the human can pickup XP orbs (checks cooldown time) - * @return bool */ public function canPickupXp() : bool{ return $this->xpCooldown === 0; @@ -314,8 +273,6 @@ class ExperienceManager{ /** * Sets the duration in ticks until the human can pick up another XP orb. - * - * @param int $value */ public function resetXpCooldown(int $value = 2) : void{ $this->xpCooldown = $value; diff --git a/src/entity/Human.php b/src/entity/Human.php index bdf7969e0a..3cdc13d66c 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -112,25 +112,17 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ * @deprecated * * Checks the length of a supplied skin bitmap and returns whether the length is valid. - * - * @param string $skin - * - * @return bool */ public static function isValidSkin(string $skin) : bool{ return in_array(strlen($skin), Skin::ACCEPTED_SKIN_SIZES, true); } - /** - * @return UUID - */ public function getUniqueId() : UUID{ return $this->uuid; } /** * Returns a Skin object containing information about this human's skin. - * @return Skin */ public function getSkin() : Skin{ return $this->skin; @@ -139,8 +131,6 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ /** * Sets the human's skin. This will not send any update to viewers, you need to do that manually using * {@link sendSkin}. - * - * @param Skin $skin */ public function setSkin(Skin $skin) : void{ $this->skin = $skin; @@ -168,9 +158,6 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ } } - /** - * @return HungerManager - */ public function getHungerManager() : HungerManager{ return $this->hungerManager; } @@ -188,9 +175,6 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ return parent::consumeObject($consumable); } - /** - * @return ExperienceManager - */ public function getXpManager() : ExperienceManager{ return $this->xpManager; } @@ -214,8 +198,6 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ /** * For Human entities which are not players, sets their properties such as nametag, skin and UUID from NBT. - * - * @param CompoundTag $nbt */ protected function initHumanData(CompoundTag $nbt) : void{ if($nbt->hasTag("NameTag", StringTag::class)){ diff --git a/src/entity/HungerManager.php b/src/entity/HungerManager.php index 77e162c9be..8f8be0abd9 100644 --- a/src/entity/HungerManager.php +++ b/src/entity/HungerManager.php @@ -69,8 +69,6 @@ class HungerManager{ * WARNING: This method does not check if full and may throw an exception if out of bounds. * @see HungerManager::addFood() * - * @param float $new - * * @throws \InvalidArgumentException */ public function setFood(float $new) : void{ @@ -98,8 +96,6 @@ class HungerManager{ /** * Returns whether this Human may consume objects requiring hunger. - * - * @return bool */ public function isHungry() : bool{ return $this->getFood() < $this->getMaxFood(); @@ -113,8 +109,6 @@ class HungerManager{ * WARNING: This method does not check if saturated and may throw an exception if out of bounds. * @see HungerManager::addSaturation() * - * @param float $saturation - * * @throws \InvalidArgumentException */ public function setSaturation(float $saturation) : void{ @@ -132,8 +126,6 @@ class HungerManager{ /** * WARNING: This method does not check if exhausted and does not consume saturation/food. * @see HungerManager::exhaust() - * - * @param float $exhaustion */ public function setExhaustion(float $exhaustion) : void{ $this->exhaustionAttr->setValue($exhaustion); @@ -142,9 +134,6 @@ class HungerManager{ /** * Increases exhaustion level. * - * @param float $amount - * @param int $cause - * * @return float the amount of exhaustion level increased */ public function exhaust(float $amount, int $cause = PlayerExhaustEvent::CAUSE_CUSTOM) : float{ @@ -180,16 +169,10 @@ class HungerManager{ return $ev->getAmount(); } - /** - * @return int - */ public function getFoodTickTimer() : int{ return $this->foodTickTimer; } - /** - * @param int $foodTickTimer - */ public function setFoodTickTimer(int $foodTickTimer) : void{ if($foodTickTimer < 0){ throw new \InvalidArgumentException("Expected a non-negative value"); @@ -238,16 +221,10 @@ class HungerManager{ } } - /** - * @return bool - */ public function isEnabled() : bool{ return $this->enabled; } - /** - * @param bool $enabled - */ public function setEnabled(bool $enabled) : void{ $this->enabled = $enabled; } diff --git a/src/entity/Living.php b/src/entity/Living.php index afe021cd7c..0f741ff0f7 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -217,10 +217,6 @@ abstract class Living extends Entity{ /** * Causes the mob to consume the given Consumable object, applying applicable effects, health bonuses, food bonuses, * etc. - * - * @param Consumable $consumable - * - * @return bool */ public function consumeObject(Consumable $consumable) : bool{ foreach($consumable->getAdditionalEffects() as $effect){ @@ -234,7 +230,6 @@ abstract class Living extends Entity{ /** * Returns the initial upwards velocity of a jumping entity in blocks/tick, including additional velocity due to effects. - * @return float */ public function getJumpVelocity() : float{ return $this->jumpVelocity + ($this->effectManager->has(VanillaEffects::JUMP_BOOST()) ? ($this->effectManager->get(VanillaEffects::JUMP_BOOST())->getEffectLevel() / 10) : 0); @@ -261,8 +256,6 @@ abstract class Living extends Entity{ * Returns how many armour points this mob has. Armour points provide a percentage reduction to damage. * For mobs which can wear armour, this should return the sum total of the armour points provided by their * equipment. - * - * @return int */ public function getArmorPoints() : int{ $total = 0; @@ -275,10 +268,6 @@ abstract class Living extends Entity{ /** * Returns the highest level of the specified enchantment on any armour piece that the entity is currently wearing. - * - * @param Enchantment $enchantment - * - * @return int */ public function getHighestArmorEnchantmentLevel(Enchantment $enchantment) : int{ $result = 0; @@ -289,9 +278,6 @@ abstract class Living extends Entity{ return $result; } - /** - * @return ArmorInventory - */ public function getArmorInventory() : ArmorInventory{ return $this->armorInventory; } @@ -303,8 +289,6 @@ abstract class Living extends Entity{ /** * Called prior to EntityDamageEvent execution to apply modifications to the event's damage, such as reduction due * to effects or armour. - * - * @param EntityDamageEvent $source */ public function applyDamageModifiers(EntityDamageEvent $source) : void{ if($source->canBeReducedByArmor()){ @@ -332,8 +316,6 @@ abstract class Living extends Entity{ * Called after EntityDamageEvent execution to apply post-hurt effects, such as reducing absorption or modifying * armour durability. * This will not be called by damage sources causing death. - * - * @param EntityDamageEvent $source */ protected function applyPostDamageEffects(EntityDamageEvent $source) : void{ $this->setAbsorption(max(0, $this->getAbsorption() + $source->getModifier(EntityDamageEvent::MODIFIER_ABSORPTION))); @@ -363,8 +345,6 @@ abstract class Living extends Entity{ /** * Damages the worn armour according to the amount of damage given. Each 4 points (rounded down) deals 1 damage * point to each armour piece, but never less than 1 total. - * - * @param float $damage */ public function damageArmor(float $damage) : void{ $durabilityRemoved = (int) max(floor($damage / 4), 1); @@ -544,10 +524,6 @@ abstract class Living extends Entity{ /** * Ticks the entity's air supply, consuming it when underwater and regenerating it when out of water. - * - * @param int $tickDiff - * - * @return bool */ protected function doAirSupplyTick(int $tickDiff) : bool{ $ticks = $this->getAirSupplyTicks(); @@ -583,7 +559,6 @@ abstract class Living extends Entity{ /** * Returns whether the entity can currently breathe. - * @return bool */ public function canBreathe() : bool{ return $this->effectManager->has(VanillaEffects::WATER_BREATHING()) or $this->effectManager->has(VanillaEffects::CONDUIT_POWER()) or !$this->isUnderwater(); @@ -591,7 +566,6 @@ abstract class Living extends Entity{ /** * Returns whether the entity is currently breathing or not. If this is false, the entity's air supply will be used. - * @return bool */ public function isBreathing() : bool{ return $this->breathing; @@ -600,8 +574,6 @@ abstract class Living extends Entity{ /** * Sets whether the entity is currently breathing. If false, it will cause the entity's air supply to be used. * For players, this also shows the oxygen bar. - * - * @param bool $value */ public function setBreathing(bool $value = true) : void{ $this->breathing = $value; @@ -610,8 +582,6 @@ abstract class Living extends Entity{ /** * Returns the number of ticks remaining in the entity's air supply. Note that the entity may survive longer than * this amount of time without damage due to enchantments such as Respiration. - * - * @return int */ public function getAirSupplyTicks() : int{ return $this->breathTicks; @@ -619,8 +589,6 @@ abstract class Living extends Entity{ /** * Sets the number of air ticks left in the entity's air supply. - * - * @param int $ticks */ public function setAirSupplyTicks(int $ticks) : void{ $this->breathTicks = $ticks; @@ -628,7 +596,6 @@ abstract class Living extends Entity{ /** * Returns the maximum amount of air ticks the entity's air supply can contain. - * @return int */ public function getMaxAirSupplyTicks() : int{ return $this->maxBreathTicks; @@ -636,8 +603,6 @@ abstract class Living extends Entity{ /** * Sets the maximum amount of air ticks the air supply can hold. - * - * @param int $ticks */ public function setMaxAirSupplyTicks(int $ticks) : void{ $this->maxBreathTicks = $ticks; @@ -661,17 +626,12 @@ abstract class Living extends Entity{ /** * Returns the amount of XP this mob will drop on death. - * @return int */ public function getXpDropAmount() : int{ return 0; } /** - * @param int $maxDistance - * @param int $maxLength - * @param array $transparent - * * @return Block[] */ public function getLineOfSight(int $maxDistance, int $maxLength = 0, array $transparent = []) : array{ @@ -711,12 +671,6 @@ abstract class Living extends Entity{ return $blocks; } - /** - * @param int $maxDistance - * @param array $transparent - * - * @return Block|null - */ public function getTargetBlock(int $maxDistance, array $transparent = []) : ?Block{ $line = $this->getLineOfSight($maxDistance, 1, $transparent); if(count($line) > 0){ @@ -729,8 +683,6 @@ abstract class Living extends Entity{ /** * Changes the entity's yaw and pitch to make it look at the specified Vector3 position. For mobs, this will cause * their heads to turn. - * - * @param Vector3 $target */ public function lookAt(Vector3 $target) : void{ $horizontal = sqrt(($target->x - $this->location->x) ** 2 + ($target->z - $this->location->z) ** 2); diff --git a/src/entity/Location.php b/src/entity/Location.php index 6bb6f76fdc..8d7cf84ecf 100644 --- a/src/entity/Location.php +++ b/src/entity/Location.php @@ -38,8 +38,6 @@ class Location extends Position{ * @param float|int $x * @param float|int $y * @param float|int $z - * @param float $yaw - * @param float $pitch * @param World $world */ public function __construct($x = 0, $y = 0, $z = 0, float $yaw = 0.0, float $pitch = 0.0, ?World $world = null){ @@ -49,7 +47,6 @@ class Location extends Position{ } /** - * @param Vector3 $pos * @param World|null $world default null * @param float $yaw default 0.0 * @param float $pitch default 0.0 @@ -62,8 +59,6 @@ class Location extends Position{ /** * Return a Location instance - * - * @return Location */ public function asLocation() : Location{ return new Location($this->x, $this->y, $this->z, $this->yaw, $this->pitch, $this->world); diff --git a/src/entity/Skin.php b/src/entity/Skin.php index af26dbbacd..625f9f109d 100644 --- a/src/entity/Skin.php +++ b/src/entity/Skin.php @@ -83,37 +83,22 @@ final class Skin{ $this->geometryData = $geometryData; } - /** - * @return string - */ public function getSkinId() : string{ return $this->skinId; } - /** - * @return string - */ public function getSkinData() : string{ return $this->skinData; } - /** - * @return string - */ public function getCapeData() : string{ return $this->capeData; } - /** - * @return string - */ public function getGeometryName() : string{ return $this->geometryName; } - /** - * @return string - */ public function getGeometryData() : string{ return $this->geometryData; } diff --git a/src/entity/Villager.php b/src/entity/Villager.php index cfe07247d3..b76ff57fd1 100644 --- a/src/entity/Villager.php +++ b/src/entity/Villager.php @@ -71,8 +71,6 @@ class Villager extends Living implements Ageable{ /** * Sets the villager profession - * - * @param int $profession */ public function setProfession(int $profession) : void{ $this->profession = $profession; //TODO: validation diff --git a/src/entity/effect/Effect.php b/src/entity/effect/Effect.php index fe2f80bd1e..bcc347cf67 100644 --- a/src/entity/effect/Effect.php +++ b/src/entity/effect/Effect.php @@ -57,7 +57,6 @@ class Effect{ /** * Returns the effect ID as per Minecraft PE - * @return int */ public function getId() : int{ return $this->id; @@ -65,7 +64,6 @@ class Effect{ /** * Returns the translation key used to translate this effect's name. - * @return string */ public function getName() : string{ return $this->name; @@ -73,7 +71,6 @@ class Effect{ /** * Returns a Color object representing this effect's particle colour. - * @return Color */ public function getColor() : Color{ return $this->color; @@ -82,8 +79,6 @@ class Effect{ /** * Returns whether this effect is harmful. * TODO: implement inverse effect results for undead mobs - * - * @return bool */ public function isBad() : bool{ return $this->bad; @@ -91,7 +86,6 @@ class Effect{ /** * Returns the default duration (in ticks) this effect will apply for if a duration is not specified. - * @return int */ public function getDefaultDuration() : int{ return 600; @@ -99,7 +93,6 @@ class Effect{ /** * Returns whether this effect will give the subject potion bubbles. - * @return bool */ public function hasBubbles() : bool{ return $this->hasBubbles; @@ -107,10 +100,6 @@ class Effect{ /** * Returns whether the effect will do something on the current tick. - * - * @param EffectInstance $instance - * - * @return bool */ public function canTick(EffectInstance $instance) : bool{ return false; @@ -118,11 +107,6 @@ class Effect{ /** * Applies effect results to an entity. This will not be called unless canTick() returns true. - * - * @param Living $entity - * @param EffectInstance $instance - * @param float $potency - * @param null|Entity $source */ public function applyEffect(Living $entity, EffectInstance $instance, float $potency = 1.0, ?Entity $source = null) : void{ @@ -130,9 +114,6 @@ class Effect{ /** * Applies effects to the entity when the effect is first added. - * - * @param Living $entity - * @param EffectInstance $instance */ public function add(Living $entity, EffectInstance $instance) : void{ @@ -140,9 +121,6 @@ class Effect{ /** * Removes the effect from the entity, resetting any changed values back to their original defaults. - * - * @param Living $entity - * @param EffectInstance $instance */ public function remove(Living $entity, EffectInstance $instance) : void{ diff --git a/src/entity/effect/EffectInstance.php b/src/entity/effect/EffectInstance.php index 1af2e5b6e3..65f4c8ebb7 100644 --- a/src/entity/effect/EffectInstance.php +++ b/src/entity/effect/EffectInstance.php @@ -47,12 +47,7 @@ class EffectInstance{ private $color; /** - * @param Effect $effectType * @param int|null $duration Passing null will use the effect type's default duration - * @param int $amplifier - * @param bool $visible - * @param bool $ambient - * @param null|Color $overrideColor */ public function __construct(Effect $effectType, ?int $duration = null, int $amplifier = 0, bool $visible = true, bool $ambient = false, ?Color $overrideColor = null){ $this->effectType = $effectType; @@ -67,17 +62,12 @@ class EffectInstance{ return $this->effectType->getId(); } - /** - * @return Effect - */ public function getType() : Effect{ return $this->effectType; } /** * Returns the number of ticks remaining until the effect expires. - * - * @return int */ public function getDuration() : int{ return $this->duration; @@ -86,8 +76,6 @@ class EffectInstance{ /** * Sets the number of ticks remaining until the effect expires. * - * @param int $duration - * * @throws \InvalidArgumentException * * @return $this @@ -104,8 +92,6 @@ class EffectInstance{ /** * Decreases the duration by the given number of ticks, without dropping below zero. * - * @param int $ticks - * * @return $this */ public function decreaseDuration(int $ticks) : EffectInstance{ @@ -116,32 +102,23 @@ class EffectInstance{ /** * Returns whether the duration has run out. - * - * @return bool */ public function hasExpired() : bool{ return $this->duration <= 0; } - /** - * @return int - */ public function getAmplifier() : int{ return $this->amplifier; } /** * Returns the level of this effect, which is always one higher than the amplifier. - * - * @return int */ public function getEffectLevel() : int{ return $this->amplifier + 1; } /** - * @param int $amplifier - * * @return $this */ public function setAmplifier(int $amplifier) : EffectInstance{ @@ -155,16 +132,12 @@ class EffectInstance{ /** * Returns whether this effect will produce some visible effect, such as bubbles or particles. - * - * @return bool */ public function isVisible() : bool{ return $this->visible; } /** - * @param bool $visible - * * @return $this */ public function setVisible(bool $visible = true) : EffectInstance{ @@ -177,16 +150,12 @@ class EffectInstance{ * Returns whether the effect originated from the ambient environment. * Ambient effects can originate from things such as a Beacon's area of effect radius. * If this flag is set, the amount of visible particles will be reduced by a factor of 5. - * - * @return bool */ public function isAmbient() : bool{ return $this->ambient; } /** - * @param bool $ambient - * * @return $this */ public function setAmbient(bool $ambient = true) : EffectInstance{ @@ -198,8 +167,6 @@ class EffectInstance{ /** * Returns the particle colour of this effect instance. This can be overridden on a per-EffectInstance basis, so it * is not reflective of the default colour of the effect. - * - * @return Color */ public function getColor() : Color{ return $this->color; @@ -207,10 +174,6 @@ class EffectInstance{ /** * Sets the colour of this EffectInstance. - * - * @param Color $color - * - * @return EffectInstance */ public function setColor(Color $color) : EffectInstance{ $this->color = $color; @@ -220,8 +183,6 @@ class EffectInstance{ /** * Resets the colour of this EffectInstance to the default specified by its type. - * - * @return EffectInstance */ public function resetColor() : EffectInstance{ $this->color = $this->effectType->getColor(); diff --git a/src/entity/effect/EffectManager.php b/src/entity/effect/EffectManager.php index ab3cef6560..7cead7f74b 100644 --- a/src/entity/effect/EffectManager.php +++ b/src/entity/effect/EffectManager.php @@ -73,8 +73,6 @@ class EffectManager{ /** * Removes the effect with the specified ID from the mob. - * - * @param Effect $effectType */ public function remove(Effect $effectType) : void{ $index = $effectType->getId(); @@ -105,10 +103,6 @@ class EffectManager{ /** * Returns the effect instance active on this entity with the specified ID, or null if the mob does not have the * effect. - * - * @param Effect $effect - * - * @return EffectInstance|null */ public function get(Effect $effect) : ?EffectInstance{ return $this->effects[$effect->getId()] ?? null; @@ -116,10 +110,6 @@ class EffectManager{ /** * Returns whether the specified effect is active on the mob. - * - * @param Effect $effect - * - * @return bool */ public function has(Effect $effect) : bool{ return isset($this->effects[$effect->getId()]); @@ -130,8 +120,6 @@ class EffectManager{ * If a weaker effect of the same type is already applied, it will be replaced. * If a weaker or equal-strength effect is already applied but has a shorter duration, it will be replaced. * - * @param EffectInstance $effect - * * @return bool whether the effect has been successfully applied. */ public function add(EffectInstance $effect) : bool{ @@ -203,16 +191,10 @@ class EffectManager{ } } - /** - * @return Color - */ public function getBubbleColor() : Color{ return $this->bubbleColor; } - /** - * @return bool - */ public function hasOnlyAmbientEffects() : bool{ return $this->onlyAmbientEffects; } diff --git a/src/entity/effect/VanillaEffects.php b/src/entity/effect/VanillaEffects.php index 1f82926c51..a20b4ebb63 100644 --- a/src/entity/effect/VanillaEffects.php +++ b/src/entity/effect/VanillaEffects.php @@ -104,11 +104,6 @@ final class VanillaEffects{ self::$mcpeIdMap[$member->getId()] = $member; } - /** - * @param int $id - * - * @return Effect|null - */ public static function byMcpeId(int $id) : ?Effect{ self::checkInit(); return self::$mcpeIdMap[$id] ?? null; @@ -121,11 +116,6 @@ final class VanillaEffects{ return self::_registryGetAll(); } - /** - * @param string $name - * - * @return Effect - */ public static function fromString(string $name) : Effect{ $result = self::_registryFromString($name); assert($result instanceof Effect); diff --git a/src/entity/object/ExperienceOrb.php b/src/entity/object/ExperienceOrb.php index 31528fbb19..a1059ca949 100644 --- a/src/entity/object/ExperienceOrb.php +++ b/src/entity/object/ExperienceOrb.php @@ -52,10 +52,6 @@ class ExperienceOrb extends Entity{ /** * Returns the largest size of normal XP orb that will be spawned for the specified amount of XP. Used to split XP * up into multiple orbs when an amount of XP is dropped. - * - * @param int $amount - * - * @return int */ public static function getMaxOrbSize(int $amount) : int{ foreach(self::ORB_SPLIT_SIZES as $split){ @@ -70,8 +66,6 @@ class ExperienceOrb extends Entity{ /** * Splits the specified amount of XP into an array of acceptable XP orb sizes. * - * @param int $amount - * * @return int[] */ public static function splitIntoOrbSizes(int $amount) : array{ diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index 698c21d905..092bfe85c6 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -154,9 +154,6 @@ class ItemEntity extends Entity{ return $nbt; } - /** - * @return Item - */ public function getItem() : Item{ return $this->item; } @@ -169,32 +166,22 @@ class ItemEntity extends Entity{ return false; } - /** - * @return int - */ public function getPickupDelay() : int{ return $this->pickupDelay; } - /** - * @param int $delay - */ public function setPickupDelay(int $delay) : void{ $this->pickupDelay = $delay; } /** * Returns the number of ticks left before this item will despawn. If -1, the item will never despawn. - * - * @return int */ public function getDespawnDelay() : int{ return $this->despawnDelay; } /** - * @param int $despawnDelay - * * @throws \InvalidArgumentException */ public function setDespawnDelay(int $despawnDelay) : void{ @@ -204,30 +191,18 @@ class ItemEntity extends Entity{ $this->despawnDelay = $despawnDelay; } - /** - * @return string - */ public function getOwner() : string{ return $this->owner; } - /** - * @param string $owner - */ public function setOwner(string $owner) : void{ $this->owner = $owner; } - /** - * @return string - */ public function getThrower() : string{ return $this->thrower; } - /** - * @param string $thrower - */ public function setThrower(string $thrower) : void{ $this->thrower = $thrower; } diff --git a/src/entity/object/Painting.php b/src/entity/object/Painting.php index b9276755b1..7a5e341029 100644 --- a/src/entity/object/Painting.php +++ b/src/entity/object/Painting.php @@ -164,7 +164,6 @@ class Painting extends Entity{ /** * Returns the painting motive (which image is displayed on the painting) - * @return PaintingMotive */ public function getMotive() : PaintingMotive{ return PaintingMotive::getMotiveByName($this->motive); @@ -176,11 +175,6 @@ class Painting extends Entity{ /** * Returns the bounding-box a painting with the specified motive would have at the given position and direction. - * - * @param int $facing - * @param PaintingMotive $motive - * - * @return AxisAlignedBB */ private static function getPaintingBB(int $facing, PaintingMotive $motive) : AxisAlignedBB{ $width = $motive->getWidth(); @@ -199,14 +193,6 @@ class Painting extends Entity{ /** * Returns whether a painting with the specified motive can be placed at the given position. - * - * @param World $world - * @param Vector3 $blockIn - * @param int $facing - * @param bool $checkOverlap - * @param PaintingMotive $motive - * - * @return bool */ public static function canFit(World $world, Vector3 $blockIn, int $facing, bool $checkOverlap, PaintingMotive $motive) : bool{ $width = $motive->getWidth(); diff --git a/src/entity/object/PaintingMotive.php b/src/entity/object/PaintingMotive.php index c0f0cabc8a..1ae1deb176 100644 --- a/src/entity/object/PaintingMotive.php +++ b/src/entity/object/PaintingMotive.php @@ -64,18 +64,10 @@ class PaintingMotive{ } } - /** - * @param PaintingMotive $motive - */ public static function registerMotive(PaintingMotive $motive) : void{ self::$motives[$motive->getName()] = $motive; } - /** - * @param string $name - * - * @return PaintingMotive|null - */ public static function getMotiveByName(string $name) : ?PaintingMotive{ return self::$motives[$name] ?? null; } @@ -101,23 +93,14 @@ class PaintingMotive{ $this->height = $height; } - /** - * @return string - */ public function getName() : string{ return $this->name; } - /** - * @return int - */ public function getWidth() : int{ return $this->width; } - /** - * @return int - */ public function getHeight() : int{ return $this->height; } diff --git a/src/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php index f5bfeeabf4..9a2bae08ce 100644 --- a/src/entity/projectile/Arrow.php +++ b/src/entity/projectile/Arrow.php @@ -106,16 +106,10 @@ class Arrow extends Projectile{ } } - /** - * @return float - */ public function getPunchKnockback() : float{ return $this->punchKnockback; } - /** - * @param float $punchKnockback - */ public function setPunchKnockback(float $punchKnockback) : void{ $this->punchKnockback = $punchKnockback; } @@ -161,16 +155,10 @@ class Arrow extends Projectile{ } } - /** - * @return int - */ public function getPickupMode() : int{ return $this->pickupMode; } - /** - * @param int $pickupMode - */ public function setPickupMode(int $pickupMode) : void{ $this->pickupMode = $pickupMode; } diff --git a/src/entity/projectile/Projectile.php b/src/entity/projectile/Projectile.php index 62b00af9cd..db2b5bcce4 100644 --- a/src/entity/projectile/Projectile.php +++ b/src/entity/projectile/Projectile.php @@ -116,8 +116,6 @@ abstract class Projectile extends Entity{ /** * Returns the base damage applied on collision. This is multiplied by the projectile's speed to give a result * damage. - * - * @return float */ public function getBaseDamage() : float{ return $this->damage; @@ -125,8 +123,6 @@ abstract class Projectile extends Entity{ /** * Sets the base amount of damage applied by the projectile. - * - * @param float $damage */ public function setBaseDamage(float $damage) : void{ $this->damage = $damage; @@ -134,7 +130,6 @@ abstract class Projectile extends Entity{ /** * Returns the amount of damage this projectile will deal to the entity it hits. - * @return int */ public function getResultDamage() : int{ return (int) ceil($this->motion->length() * $this->damage); @@ -275,10 +270,6 @@ abstract class Projectile extends Entity{ * This can be overridden by other projectiles to allow altering the blocks which are collided with (for example * some projectiles collide with any non-air block). * - * @param Block $block - * @param Vector3 $start - * @param Vector3 $end - * * @return RayTraceResult|null the result of the ray trace if successful, or null if no interception is found. */ protected function calculateInterceptWithBlock(Block $block, Vector3 $start, Vector3 $end) : ?RayTraceResult{ @@ -288,8 +279,6 @@ abstract class Projectile extends Entity{ /** * Called when the projectile hits something. Override this to perform non-target-specific effects when the * projectile hits something. - * - * @param ProjectileHitEvent $event */ protected function onHit(ProjectileHitEvent $event) : void{ @@ -297,9 +286,6 @@ abstract class Projectile extends Entity{ /** * Called when the projectile collides with an Entity. - * - * @param Entity $entityHit - * @param RayTraceResult $hitResult */ protected function onHitEntity(Entity $entityHit, RayTraceResult $hitResult) : void{ $damage = $this->getResultDamage(); @@ -327,9 +313,6 @@ abstract class Projectile extends Entity{ /** * Called when the projectile collides with a Block. - * - * @param Block $blockHit - * @param RayTraceResult $hitResult */ protected function onHitBlock(Block $blockHit, RayTraceResult $hitResult) : void{ $this->blockHit = clone $blockHit; diff --git a/src/entity/projectile/SplashPotion.php b/src/entity/projectile/SplashPotion.php index 30b7a023cd..4c2336524d 100644 --- a/src/entity/projectile/SplashPotion.php +++ b/src/entity/projectile/SplashPotion.php @@ -142,22 +142,17 @@ class SplashPotion extends Throwable{ /** * Returns the meta value of the potion item that this splash potion corresponds to. This decides what effects will be applied to the entity when it collides with its target. - * @return int */ public function getPotionId() : int{ return $this->potionId; } - /** - * @param int $id - */ public function setPotionId(int $id) : void{ $this->potionId = $id; //TODO: validation } /** * Returns whether this splash potion will create an area-effect cloud when it lands. - * @return bool */ public function willLinger() : bool{ return $this->linger; @@ -165,8 +160,6 @@ class SplashPotion extends Throwable{ /** * Sets whether this splash potion will create an area-effect-cloud when it lands. - * - * @param bool $value */ public function setLinger(bool $value = true) : void{ $this->linger = $value; diff --git a/src/entity/utils/ExperienceUtils.php b/src/entity/utils/ExperienceUtils.php index 38c0ab991b..3e4f4f74e4 100644 --- a/src/entity/utils/ExperienceUtils.php +++ b/src/entity/utils/ExperienceUtils.php @@ -30,10 +30,6 @@ abstract class ExperienceUtils{ /** * Calculates and returns the amount of XP needed to get from level 0 to level $level - * - * @param int $level - * - * @return int */ public static function getXpToReachLevel(int $level) : int{ if($level <= 16){ @@ -47,10 +43,6 @@ abstract class ExperienceUtils{ /** * Returns the amount of XP needed to reach $level + 1. - * - * @param int $level - * - * @return int */ public static function getXpToCompleteLevel(int $level) : int{ if($level <= 15){ @@ -65,10 +57,6 @@ abstract class ExperienceUtils{ /** * Calculates and returns the number of XP levels the specified amount of XP points are worth. * This returns a floating-point number, the decimal part being the progress through the resulting level. - * - * @param int $xp - * - * @return float */ public static function getLevelFromXp(int $xp) : float{ if($xp <= self::getXpToReachLevel(16)){ diff --git a/src/event/Cancellable.php b/src/event/Cancellable.php index 63e4a3f1e5..1e439ad31d 100644 --- a/src/event/Cancellable.php +++ b/src/event/Cancellable.php @@ -28,13 +28,7 @@ namespace pocketmine\event; * Events that can be cancelled must use the interface Cancellable */ interface Cancellable{ - /** - * @return bool - */ public function isCancelled() : bool; - /** - * @param bool $value - */ public function setCancelled(bool $value = true) : void; } diff --git a/src/event/CancellableTrait.php b/src/event/CancellableTrait.php index 740f24a4e2..0fe5186ed2 100644 --- a/src/event/CancellableTrait.php +++ b/src/event/CancellableTrait.php @@ -31,16 +31,10 @@ trait CancellableTrait{ /** @var bool */ private $isCancelled = false; - /** - * @return bool - */ public function isCancelled() : bool{ return $this->isCancelled; } - /** - * @param bool $value - */ public function setCancelled(bool $value = true) : void{ $this->isCancelled = $value; } diff --git a/src/event/Event.php b/src/event/Event.php index 5977516f35..b9a8f9828a 100644 --- a/src/event/Event.php +++ b/src/event/Event.php @@ -36,9 +36,6 @@ abstract class Event{ /** @var string|null */ protected $eventName = null; - /** - * @return string - */ final public function getEventName() : string{ return $this->eventName ?? get_class($this); } diff --git a/src/event/EventPriority.php b/src/event/EventPriority.php index c7a788518e..bcb9143248 100644 --- a/src/event/EventPriority.php +++ b/src/event/EventPriority.php @@ -81,10 +81,6 @@ final class EventPriority{ public const MONITOR = 0; /** - * @param string $name - * - * @return int - * * @throws \InvalidArgumentException */ public static function fromString(string $name) : int{ diff --git a/src/event/HandlerList.php b/src/event/HandlerList.php index 80bc844486..b452a382c8 100644 --- a/src/event/HandlerList.php +++ b/src/event/HandlerList.php @@ -43,8 +43,6 @@ class HandlerList{ } /** - * @param RegisteredListener $listener - * * @throws \Exception */ public function register(RegisteredListener $listener) : void{ @@ -89,17 +87,12 @@ class HandlerList{ } /** - * @param int $priority - * * @return RegisteredListener[] */ public function getListenersByPriority(int $priority) : array{ return $this->handlerSlots[$priority]; } - /** - * @return null|HandlerList - */ public function getParent() : ?HandlerList{ return $this->parentList; } diff --git a/src/event/HandlerListManager.php b/src/event/HandlerListManager.php index ed1c2713b5..bf4cff143b 100644 --- a/src/event/HandlerListManager.php +++ b/src/event/HandlerListManager.php @@ -61,8 +61,6 @@ class HandlerListManager{ /** * @param ReflectionClass $class * @phpstan-param \ReflectionClass $class - * - * @return bool */ private static function isValidClass(\ReflectionClass $class) : bool{ $tags = Utils::parseDocComment((string) $class->getDocComment()); @@ -70,10 +68,8 @@ class HandlerListManager{ } /** - * @param \ReflectionClass $class * @phpstan-param \ReflectionClass $class * - * @return \ReflectionClass|null * @phpstan-return \ReflectionClass|null */ private static function resolveNearestHandleableParent(\ReflectionClass $class) : ?\ReflectionClass{ @@ -88,9 +84,6 @@ class HandlerListManager{ * * Calling this method also lazily initializes the $classMap inheritance tree of handler lists. * - * @param string $event - * - * @return HandlerList * @throws \ReflectionException * @throws \InvalidArgumentException */ diff --git a/src/event/RegisteredListener.php b/src/event/RegisteredListener.php index ac06cd6520..6d95660e74 100644 --- a/src/event/RegisteredListener.php +++ b/src/event/RegisteredListener.php @@ -44,14 +44,6 @@ class RegisteredListener{ /** @var TimingsHandler */ private $timings; - - /** - * @param \Closure $handler - * @param int $priority - * @param Plugin $plugin - * @param bool $handleCancelled - * @param TimingsHandler $timings - */ public function __construct(\Closure $handler, int $priority, Plugin $plugin, bool $handleCancelled, TimingsHandler $timings){ if(!in_array($priority, EventPriority::ALL, true)){ throw new \InvalidArgumentException("Invalid priority number $priority"); @@ -67,23 +59,14 @@ class RegisteredListener{ return $this->handler; } - /** - * @return Plugin - */ public function getPlugin() : Plugin{ return $this->plugin; } - /** - * @return int - */ public function getPriority() : int{ return $this->priority; } - /** - * @param Event $event - */ public function callEvent(Event $event) : void{ if($event instanceof Cancellable and $event->isCancelled() and !$this->isHandlingCancelled()){ return; @@ -97,9 +80,6 @@ class RegisteredListener{ $this->timings->remove(); } - /** - * @return bool - */ public function isHandlingCancelled() : bool{ return $this->handleCancelled; } diff --git a/src/event/block/BlockBreakEvent.php b/src/event/block/BlockBreakEvent.php index a01fc6ccbe..68f3fae189 100644 --- a/src/event/block/BlockBreakEvent.php +++ b/src/event/block/BlockBreakEvent.php @@ -49,12 +49,7 @@ class BlockBreakEvent extends BlockEvent implements Cancellable{ protected $xpDrops; /** - * @param Player $player - * @param Block $block - * @param Item $item - * @param bool $instaBreak * @param Item[] $drops - * @param int $xpDrops */ public function __construct(Player $player, Block $block, Item $item, bool $instaBreak = false, array $drops, int $xpDrops = 0){ parent::__construct($block); @@ -68,7 +63,6 @@ class BlockBreakEvent extends BlockEvent implements Cancellable{ /** * Returns the player who is destroying the block. - * @return Player */ public function getPlayer() : Player{ return $this->player; @@ -76,7 +70,6 @@ class BlockBreakEvent extends BlockEvent implements Cancellable{ /** * Returns the item used to destroy the block. - * @return Item */ public function getItem() : Item{ return $this->item; @@ -85,16 +78,11 @@ class BlockBreakEvent extends BlockEvent implements Cancellable{ /** * Returns whether the block may be broken in less than the amount of time calculated. This is usually true for * creative players. - * - * @return bool */ public function getInstaBreak() : bool{ return $this->instaBreak; } - /** - * @param bool $instaBreak - */ public function setInstaBreak(bool $instaBreak) : void{ $this->instaBreak = $instaBreak; } @@ -125,8 +113,6 @@ class BlockBreakEvent extends BlockEvent implements Cancellable{ /** * Returns how much XP will be dropped by breaking this block. - * - * @return int */ public function getXpDropAmount() : int{ return $this->xpDrops; @@ -134,8 +120,6 @@ class BlockBreakEvent extends BlockEvent implements Cancellable{ /** * Sets how much XP will be dropped by breaking this block. - * - * @param int $amount */ public function setXpDropAmount(int $amount) : void{ if($amount < 0){ diff --git a/src/event/block/BlockBurnEvent.php b/src/event/block/BlockBurnEvent.php index d50f96953f..96ddb62349 100644 --- a/src/event/block/BlockBurnEvent.php +++ b/src/event/block/BlockBurnEvent.php @@ -43,7 +43,6 @@ class BlockBurnEvent extends BlockEvent implements Cancellable{ /** * Returns the block (usually Fire) which caused the target block to be burned away. - * @return Block */ public function getCausingBlock() : Block{ return $this->causingBlock; diff --git a/src/event/block/BlockEvent.php b/src/event/block/BlockEvent.php index ec70779322..d506529ba7 100644 --- a/src/event/block/BlockEvent.php +++ b/src/event/block/BlockEvent.php @@ -33,16 +33,10 @@ abstract class BlockEvent extends Event{ /** @var Block */ protected $block; - /** - * @param Block $block - */ public function __construct(Block $block){ $this->block = $block; } - /** - * @return Block - */ public function getBlock() : Block{ return $this->block; } diff --git a/src/event/block/BlockGrowEvent.php b/src/event/block/BlockGrowEvent.php index 49cac65d7c..8786fd4523 100644 --- a/src/event/block/BlockGrowEvent.php +++ b/src/event/block/BlockGrowEvent.php @@ -41,9 +41,6 @@ class BlockGrowEvent extends BlockEvent implements Cancellable{ $this->newState = $newState; } - /** - * @return Block - */ public function getNewState() : Block{ return $this->newState; } diff --git a/src/event/block/BlockPlaceEvent.php b/src/event/block/BlockPlaceEvent.php index 57aaacc37d..955b901346 100644 --- a/src/event/block/BlockPlaceEvent.php +++ b/src/event/block/BlockPlaceEvent.php @@ -56,7 +56,6 @@ class BlockPlaceEvent extends BlockEvent implements Cancellable{ /** * Returns the player who is placing the block. - * @return Player */ public function getPlayer() : Player{ return $this->player; @@ -64,22 +63,15 @@ class BlockPlaceEvent extends BlockEvent implements Cancellable{ /** * Gets the item in hand - * @return Item */ public function getItem() : Item{ return $this->item; } - /** - * @return Block - */ public function getBlockReplaced() : Block{ return $this->blockReplace; } - /** - * @return Block - */ public function getBlockAgainst() : Block{ return $this->blockAgainst; } diff --git a/src/event/block/BlockSpreadEvent.php b/src/event/block/BlockSpreadEvent.php index d68fdb2ce9..098e2d6d91 100644 --- a/src/event/block/BlockSpreadEvent.php +++ b/src/event/block/BlockSpreadEvent.php @@ -37,9 +37,6 @@ class BlockSpreadEvent extends BlockFormEvent{ $this->source = $source; } - /** - * @return Block - */ public function getSource() : Block{ return $this->source; } diff --git a/src/event/block/BlockTeleportEvent.php b/src/event/block/BlockTeleportEvent.php index ac4d6ae519..3dcd041ae4 100644 --- a/src/event/block/BlockTeleportEvent.php +++ b/src/event/block/BlockTeleportEvent.php @@ -34,25 +34,15 @@ class BlockTeleportEvent extends BlockEvent implements Cancellable{ /** @var Vector3 */ private $to; - /** - * @param Block $block - * @param Vector3 $to - */ public function __construct(Block $block, Vector3 $to){ parent::__construct($block); $this->to = $to; } - /** - * @return Vector3 - */ public function getTo() : Vector3{ return $this->to; } - /** - * @param Vector3 $to - */ public function setTo(Vector3 $to) : void{ $this->to = $to; } diff --git a/src/event/block/SignChangeEvent.php b/src/event/block/SignChangeEvent.php index 70c7a789c1..63357c2381 100644 --- a/src/event/block/SignChangeEvent.php +++ b/src/event/block/SignChangeEvent.php @@ -44,11 +44,6 @@ class SignChangeEvent extends BlockEvent implements Cancellable{ /** @var SignText */ private $text; - /** - * @param Sign $sign - * @param Player $player - * @param SignText $text - */ public function __construct(Sign $sign, Player $player, SignText $text){ parent::__construct($sign); $this->sign = $sign; @@ -56,24 +51,16 @@ class SignChangeEvent extends BlockEvent implements Cancellable{ $this->text = $text; } - /** - * @return Sign - */ public function getSign() : Sign{ return $this->sign; } - /** - * @return Player - */ public function getPlayer() : Player{ return $this->player; } /** * Returns the text currently on the sign. - * - * @return SignText */ public function getOldText() : SignText{ return $this->sign->getText(); @@ -81,8 +68,6 @@ class SignChangeEvent extends BlockEvent implements Cancellable{ /** * Returns the text which will be on the sign after the event. - * - * @return SignText */ public function getNewText() : SignText{ return $this->text; @@ -90,8 +75,6 @@ class SignChangeEvent extends BlockEvent implements Cancellable{ /** * Sets the text to be written on the sign after the event. - * - * @param SignText $text */ public function setNewText(SignText $text) : void{ $this->text = $text; diff --git a/src/event/entity/EntityBlockChangeEvent.php b/src/event/entity/EntityBlockChangeEvent.php index 1655dc8d77..b6c28fd078 100644 --- a/src/event/entity/EntityBlockChangeEvent.php +++ b/src/event/entity/EntityBlockChangeEvent.php @@ -45,16 +45,10 @@ class EntityBlockChangeEvent extends EntityEvent implements Cancellable{ $this->to = $to; } - /** - * @return Block - */ public function getBlock() : Block{ return $this->from; } - /** - * @return Block - */ public function getTo() : Block{ return $this->to; } diff --git a/src/event/entity/EntityCombustByBlockEvent.php b/src/event/entity/EntityCombustByBlockEvent.php index 85f524a94e..9b1d56f5a6 100644 --- a/src/event/entity/EntityCombustByBlockEvent.php +++ b/src/event/entity/EntityCombustByBlockEvent.php @@ -30,19 +30,11 @@ class EntityCombustByBlockEvent extends EntityCombustEvent{ /** @var Block */ protected $combuster; - /** - * @param Block $combuster - * @param Entity $combustee - * @param int $duration - */ public function __construct(Block $combuster, Entity $combustee, int $duration){ parent::__construct($combustee, $duration); $this->combuster = $combuster; } - /** - * @return Block - */ public function getCombuster() : Block{ return $this->combuster; } diff --git a/src/event/entity/EntityCombustByEntityEvent.php b/src/event/entity/EntityCombustByEntityEvent.php index cfa448de29..435ab670a9 100644 --- a/src/event/entity/EntityCombustByEntityEvent.php +++ b/src/event/entity/EntityCombustByEntityEvent.php @@ -29,19 +29,11 @@ class EntityCombustByEntityEvent extends EntityCombustEvent{ /** @var Entity */ protected $combuster; - /** - * @param Entity $combuster - * @param Entity $combustee - * @param int $duration - */ public function __construct(Entity $combuster, Entity $combustee, int $duration){ parent::__construct($combustee, $duration); $this->combuster = $combuster; } - /** - * @return Entity - */ public function getCombuster() : Entity{ return $this->combuster; } diff --git a/src/event/entity/EntityCombustEvent.php b/src/event/entity/EntityCombustEvent.php index 6bee08a8c3..d45296ca7a 100644 --- a/src/event/entity/EntityCombustEvent.php +++ b/src/event/entity/EntityCombustEvent.php @@ -33,10 +33,6 @@ class EntityCombustEvent extends EntityEvent implements Cancellable{ /** @var int */ protected $duration; - /** - * @param Entity $combustee - * @param int $duration - */ public function __construct(Entity $combustee, int $duration){ $this->entity = $combustee; $this->duration = $duration; @@ -44,7 +40,6 @@ class EntityCombustEvent extends EntityEvent implements Cancellable{ /** * Returns the duration in seconds the entity will burn for. - * @return int */ public function getDuration() : int{ return $this->duration; diff --git a/src/event/entity/EntityDamageByBlockEvent.php b/src/event/entity/EntityDamageByBlockEvent.php index 044e679edf..d6699ea13f 100644 --- a/src/event/entity/EntityDamageByBlockEvent.php +++ b/src/event/entity/EntityDamageByBlockEvent.php @@ -34,10 +34,6 @@ class EntityDamageByBlockEvent extends EntityDamageEvent{ private $damager; /** - * @param Block $damager - * @param Entity $entity - * @param int $cause - * @param float $damage * @param float[] $modifiers */ public function __construct(Block $damager, Entity $entity, int $cause, float $damage, array $modifiers = []){ @@ -45,9 +41,6 @@ class EntityDamageByBlockEvent extends EntityDamageEvent{ parent::__construct($entity, $cause, $damage, $modifiers); } - /** - * @return Block - */ public function getDamager() : Block{ return $this->damager; } diff --git a/src/event/entity/EntityDamageByChildEntityEvent.php b/src/event/entity/EntityDamageByChildEntityEvent.php index ab994ad63a..e3e28ab0db 100644 --- a/src/event/entity/EntityDamageByChildEntityEvent.php +++ b/src/event/entity/EntityDamageByChildEntityEvent.php @@ -33,11 +33,6 @@ class EntityDamageByChildEntityEvent extends EntityDamageByEntityEvent{ private $childEntityEid; /** - * @param Entity $damager - * @param Entity $childEntity - * @param Entity $entity - * @param int $cause - * @param float $damage * @param float[] $modifiers */ public function __construct(Entity $damager, Entity $childEntity, Entity $entity, int $cause, float $damage, array $modifiers = []){ @@ -47,8 +42,6 @@ class EntityDamageByChildEntityEvent extends EntityDamageByEntityEvent{ /** * Returns the entity which caused the damage, or null if the entity has been killed or closed. - * - * @return Entity|null */ public function getChild() : ?Entity{ return $this->getEntity()->getWorld()->getServer()->getWorldManager()->findEntity($this->childEntityEid); diff --git a/src/event/entity/EntityDamageByEntityEvent.php b/src/event/entity/EntityDamageByEntityEvent.php index 755e4e0884..6774e808ee 100644 --- a/src/event/entity/EntityDamageByEntityEvent.php +++ b/src/event/entity/EntityDamageByEntityEvent.php @@ -37,12 +37,7 @@ class EntityDamageByEntityEvent extends EntityDamageEvent{ private $knockBack; /** - * @param Entity $damager - * @param Entity $entity - * @param int $cause - * @param float $damage * @param float[] $modifiers - * @param float $knockBack */ public function __construct(Entity $damager, Entity $entity, int $cause, float $damage, array $modifiers = [], float $knockBack = 0.4){ $this->damagerEntityId = $damager->getId(); @@ -66,23 +61,15 @@ class EntityDamageByEntityEvent extends EntityDamageEvent{ /** * Returns the attacking entity, or null if the attacker has been killed or closed. - * - * @return Entity|null */ public function getDamager() : ?Entity{ return $this->getEntity()->getWorld()->getServer()->getWorldManager()->findEntity($this->damagerEntityId); } - /** - * @return float - */ public function getKnockBack() : float{ return $this->knockBack; } - /** - * @param float $knockBack - */ public function setKnockBack(float $knockBack) : void{ $this->knockBack = $knockBack; } diff --git a/src/event/entity/EntityDamageEvent.php b/src/event/entity/EntityDamageEvent.php index 2fc305977c..e9390e7857 100644 --- a/src/event/entity/EntityDamageEvent.php +++ b/src/event/entity/EntityDamageEvent.php @@ -76,11 +76,7 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{ /** @var int */ private $attackCooldown = 10; - /** - * @param Entity $entity - * @param int $cause - * @param float $damage * @param float[] $modifiers */ public function __construct(Entity $entity, int $cause, float $damage, array $modifiers = []){ @@ -92,17 +88,12 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{ $this->originals = $this->modifiers; } - /** - * @return int - */ public function getCause() : int{ return $this->cause; } /** * Returns the base amount of damage applied, before modifiers. - * - * @return float */ public function getBaseDamage() : float{ return $this->baseDamage; @@ -112,8 +103,6 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{ * Sets the base amount of damage applied, optionally recalculating modifiers. * * TODO: add ability to recalculate modifiers when this is set - * - * @param float $damage */ public function setBaseDamage(float $damage) : void{ $this->baseDamage = $damage; @@ -121,8 +110,6 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{ /** * Returns the original base amount of damage applied, before alterations by plugins. - * - * @return float */ public function getOriginalBaseDamage() : float{ return $this->originalBase; @@ -135,11 +122,6 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{ return $this->originals; } - /** - * @param int $type - * - * @return float - */ public function getOriginalModifier(int $type) : float{ return $this->originals[$type] ?? 0.0; } @@ -151,42 +133,24 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{ return $this->modifiers; } - /** - * @param int $type - * - * @return float - */ public function getModifier(int $type) : float{ return $this->modifiers[$type] ?? 0.0; } - /** - * @param float $damage - * @param int $type - */ public function setModifier(float $damage, int $type) : void{ $this->modifiers[$type] = $damage; } - /** - * @param int $type - * - * @return bool - */ public function isApplicable(int $type) : bool{ return isset($this->modifiers[$type]); } - /** - * @return float - */ public function getFinalDamage() : float{ return $this->baseDamage + array_sum($this->modifiers); } /** * Returns whether an entity can use armour points to reduce this type of damage. - * @return bool */ public function canBeReducedByArmor() : bool{ switch($this->cause){ @@ -207,8 +171,6 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{ /** * Returns the cooldown in ticks before the target entity can be attacked again. - * - * @return int */ public function getAttackCooldown() : int{ return $this->attackCooldown; @@ -218,8 +180,6 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{ * Sets the cooldown in ticks before the target entity can be attacked again. * * NOTE: This value is not used in non-Living entities - * - * @param int $attackCooldown */ public function setAttackCooldown(int $attackCooldown) : void{ $this->attackCooldown = $attackCooldown; diff --git a/src/event/entity/EntityDeathEvent.php b/src/event/entity/EntityDeathEvent.php index aeb7e55744..4eb9953ab5 100644 --- a/src/event/entity/EntityDeathEvent.php +++ b/src/event/entity/EntityDeathEvent.php @@ -33,9 +33,7 @@ class EntityDeathEvent extends EntityEvent{ private $xp; /** - * @param Living $entity * @param Item[] $drops - * @param int $xp */ public function __construct(Living $entity, array $drops = [], int $xp = 0){ $this->entity = $entity; @@ -66,15 +64,12 @@ class EntityDeathEvent extends EntityEvent{ /** * Returns how much experience is dropped due to this entity's death. - * @return int */ public function getXpDropAmount() : int{ return $this->xp; } /** - * @param int $xp - * * @throws \InvalidArgumentException */ public function setXpDropAmount(int $xp) : void{ diff --git a/src/event/entity/EntityDespawnEvent.php b/src/event/entity/EntityDespawnEvent.php index 1978f60797..7e5272575a 100644 --- a/src/event/entity/EntityDespawnEvent.php +++ b/src/event/entity/EntityDespawnEvent.php @@ -30,9 +30,6 @@ use pocketmine\entity\Entity; */ class EntityDespawnEvent extends EntityEvent{ - /** - * @param Entity $entity - */ public function __construct(Entity $entity){ $this->entity = $entity; } diff --git a/src/event/entity/EntityEffectAddEvent.php b/src/event/entity/EntityEffectAddEvent.php index d8f5633576..43cbb2671f 100644 --- a/src/event/entity/EntityEffectAddEvent.php +++ b/src/event/entity/EntityEffectAddEvent.php @@ -34,8 +34,6 @@ class EntityEffectAddEvent extends EntityEffectEvent{ private $oldEffect; /** - * @param Entity $entity - * @param EffectInstance $effect * @param EffectInstance $oldEffect */ public function __construct(Entity $entity, EffectInstance $effect, ?EffectInstance $oldEffect = null){ @@ -45,23 +43,15 @@ class EntityEffectAddEvent extends EntityEffectEvent{ /** * Returns whether the effect addition will replace an existing effect already applied to the entity. - * - * @return bool */ public function willModify() : bool{ return $this->hasOldEffect(); } - /** - * @return bool - */ public function hasOldEffect() : bool{ return $this->oldEffect instanceof EffectInstance; } - /** - * @return EffectInstance|null - */ public function getOldEffect() : ?EffectInstance{ return $this->oldEffect; } diff --git a/src/event/entity/EntityExplodeEvent.php b/src/event/entity/EntityExplodeEvent.php index 106a6f6796..a48bd8646d 100644 --- a/src/event/entity/EntityExplodeEvent.php +++ b/src/event/entity/EntityExplodeEvent.php @@ -47,10 +47,7 @@ class EntityExplodeEvent extends EntityEvent implements Cancellable{ protected $yield; /** - * @param Entity $entity - * @param Position $position * @param Block[] $blocks - * @param float $yield */ public function __construct(Entity $entity, Position $position, array $blocks, float $yield){ $this->entity = $entity; @@ -59,9 +56,6 @@ class EntityExplodeEvent extends EntityEvent implements Cancellable{ $this->yield = $yield; } - /** - * @return Position - */ public function getPosition() : Position{ return $this->position; } @@ -80,16 +74,10 @@ class EntityExplodeEvent extends EntityEvent implements Cancellable{ $this->blocks = $blocks; } - /** - * @return float - */ public function getYield() : float{ return $this->yield; } - /** - * @param float $yield - */ public function setYield(float $yield) : void{ $this->yield = $yield; } diff --git a/src/event/entity/EntityMotionEvent.php b/src/event/entity/EntityMotionEvent.php index c917e0cac7..1519fcf164 100644 --- a/src/event/entity/EntityMotionEvent.php +++ b/src/event/entity/EntityMotionEvent.php @@ -39,9 +39,6 @@ class EntityMotionEvent extends EntityEvent implements Cancellable{ $this->mot = $mot; } - /** - * @return Vector3 - */ public function getVector() : Vector3{ return $this->mot; } diff --git a/src/event/entity/EntityRegainHealthEvent.php b/src/event/entity/EntityRegainHealthEvent.php index 153b0fd8aa..c063ea196f 100644 --- a/src/event/entity/EntityRegainHealthEvent.php +++ b/src/event/entity/EntityRegainHealthEvent.php @@ -41,35 +41,22 @@ class EntityRegainHealthEvent extends EntityEvent implements Cancellable{ /** @var int */ private $reason; - - /** - * @param Entity $entity - * @param float $amount - * @param int $regainReason - */ public function __construct(Entity $entity, float $amount, int $regainReason){ $this->entity = $entity; $this->amount = $amount; $this->reason = $regainReason; } - /** - * @return float - */ public function getAmount() : float{ return $this->amount; } - /** - * @param float $amount - */ public function setAmount(float $amount) : void{ $this->amount = $amount; } /** * Returns one of the CAUSE_* constants to indicate why this regeneration occurred. - * @return int */ public function getRegainReason() : int{ return $this->reason; diff --git a/src/event/entity/EntityShootBowEvent.php b/src/event/entity/EntityShootBowEvent.php index eeded96159..d4da02e7f5 100644 --- a/src/event/entity/EntityShootBowEvent.php +++ b/src/event/entity/EntityShootBowEvent.php @@ -41,12 +41,6 @@ class EntityShootBowEvent extends EntityEvent implements Cancellable{ /** @var float */ private $force; - /** - * @param Living $shooter - * @param Item $bow - * @param Projectile $projectile - * @param float $force - */ public function __construct(Living $shooter, Item $bow, Projectile $projectile, float $force){ $this->entity = $shooter; $this->bow = $bow; @@ -61,9 +55,6 @@ class EntityShootBowEvent extends EntityEvent implements Cancellable{ return $this->entity; } - /** - * @return Item - */ public function getBow() : Item{ return $this->bow; } @@ -72,16 +63,11 @@ class EntityShootBowEvent extends EntityEvent implements Cancellable{ * Returns the entity considered as the projectile in this event. * * NOTE: This might not return a Projectile if a plugin modified the target entity. - * - * @return Entity */ public function getProjectile() : Entity{ return $this->projectile; } - /** - * @param Entity $projectile - */ public function setProjectile(Entity $projectile) : void{ if($projectile !== $this->projectile){ if(count($this->projectile->getViewers()) === 0){ @@ -91,16 +77,10 @@ class EntityShootBowEvent extends EntityEvent implements Cancellable{ } } - /** - * @return float - */ public function getForce() : float{ return $this->force; } - /** - * @param float $force - */ public function setForce(float $force) : void{ $this->force = $force; } diff --git a/src/event/entity/EntitySpawnEvent.php b/src/event/entity/EntitySpawnEvent.php index e20b98dbc1..7a21a5346b 100644 --- a/src/event/entity/EntitySpawnEvent.php +++ b/src/event/entity/EntitySpawnEvent.php @@ -30,9 +30,6 @@ use pocketmine\entity\Entity; */ class EntitySpawnEvent extends EntityEvent{ - /** - * @param Entity $entity - */ public function __construct(Entity $entity){ $this->entity = $entity; } diff --git a/src/event/entity/EntityTeleportEvent.php b/src/event/entity/EntityTeleportEvent.php index 160b5f9b77..3c7eee6fd3 100644 --- a/src/event/entity/EntityTeleportEvent.php +++ b/src/event/entity/EntityTeleportEvent.php @@ -42,23 +42,14 @@ class EntityTeleportEvent extends EntityEvent implements Cancellable{ $this->to = $to; } - /** - * @return Position - */ public function getFrom() : Position{ return $this->from; } - /** - * @return Position - */ public function getTo() : Position{ return $this->to; } - /** - * @param Position $to - */ public function setTo(Position $to) : void{ $this->to = $to; } diff --git a/src/event/entity/ExplosionPrimeEvent.php b/src/event/entity/ExplosionPrimeEvent.php index c2ecb2cf80..a37aec131d 100644 --- a/src/event/entity/ExplosionPrimeEvent.php +++ b/src/event/entity/ExplosionPrimeEvent.php @@ -38,19 +38,12 @@ class ExplosionPrimeEvent extends EntityEvent implements Cancellable{ /** @var bool */ private $blockBreaking; - /** - * @param Entity $entity - * @param float $force - */ public function __construct(Entity $entity, float $force){ $this->entity = $entity; $this->force = $force; $this->blockBreaking = true; } - /** - * @return float - */ public function getForce() : float{ return $this->force; } @@ -59,16 +52,10 @@ class ExplosionPrimeEvent extends EntityEvent implements Cancellable{ $this->force = $force; } - /** - * @return bool - */ public function isBlockBreaking() : bool{ return $this->blockBreaking; } - /** - * @param bool $affectsBlocks - */ public function setBlockBreaking(bool $affectsBlocks) : void{ $this->blockBreaking = $affectsBlocks; } diff --git a/src/event/entity/ItemDespawnEvent.php b/src/event/entity/ItemDespawnEvent.php index 628c56cc86..3e39657063 100644 --- a/src/event/entity/ItemDespawnEvent.php +++ b/src/event/entity/ItemDespawnEvent.php @@ -30,9 +30,6 @@ use pocketmine\event\CancellableTrait; class ItemDespawnEvent extends EntityEvent implements Cancellable{ use CancellableTrait; - /** - * @param ItemEntity $item - */ public function __construct(ItemEntity $item){ $this->entity = $item; } diff --git a/src/event/entity/ItemSpawnEvent.php b/src/event/entity/ItemSpawnEvent.php index ed76cd0623..3675550376 100644 --- a/src/event/entity/ItemSpawnEvent.php +++ b/src/event/entity/ItemSpawnEvent.php @@ -27,9 +27,6 @@ use pocketmine\entity\object\ItemEntity; class ItemSpawnEvent extends EntityEvent{ - /** - * @param ItemEntity $item - */ public function __construct(ItemEntity $item){ $this->entity = $item; diff --git a/src/event/entity/ProjectileHitBlockEvent.php b/src/event/entity/ProjectileHitBlockEvent.php index 25cd856a48..d1929ed912 100644 --- a/src/event/entity/ProjectileHitBlockEvent.php +++ b/src/event/entity/ProjectileHitBlockEvent.php @@ -39,8 +39,6 @@ class ProjectileHitBlockEvent extends ProjectileHitEvent{ /** * Returns the Block struck by the projectile. * Hint: to get the block face hit, look at the RayTraceResult. - * - * @return Block */ public function getBlockHit() : Block{ return $this->blockHit; diff --git a/src/event/entity/ProjectileHitEntityEvent.php b/src/event/entity/ProjectileHitEntityEvent.php index e8508e3e58..3fe8b42b4c 100644 --- a/src/event/entity/ProjectileHitEntityEvent.php +++ b/src/event/entity/ProjectileHitEntityEvent.php @@ -38,8 +38,6 @@ class ProjectileHitEntityEvent extends ProjectileHitEvent{ /** * Returns the Entity struck by the projectile. - * - * @return Entity */ public function getEntityHit() : Entity{ return $this->entityHit; diff --git a/src/event/entity/ProjectileHitEvent.php b/src/event/entity/ProjectileHitEvent.php index 17025c61bc..b5a800d1cf 100644 --- a/src/event/entity/ProjectileHitEvent.php +++ b/src/event/entity/ProjectileHitEvent.php @@ -33,10 +33,6 @@ abstract class ProjectileHitEvent extends EntityEvent{ /** @var RayTraceResult */ private $rayTraceResult; - /** - * @param Projectile $entity - * @param RayTraceResult $rayTraceResult - */ public function __construct(Projectile $entity, RayTraceResult $rayTraceResult){ $this->entity = $entity; $this->rayTraceResult = $rayTraceResult; @@ -52,8 +48,6 @@ abstract class ProjectileHitEvent extends EntityEvent{ /** * Returns a RayTraceResult object containing information such as the exact position struck, the AABB it hit, and * the face of the AABB that it hit. - * - * @return RayTraceResult */ public function getRayTraceResult() : RayTraceResult{ return $this->rayTraceResult; diff --git a/src/event/entity/ProjectileLaunchEvent.php b/src/event/entity/ProjectileLaunchEvent.php index f7355131db..eaf2dcef30 100644 --- a/src/event/entity/ProjectileLaunchEvent.php +++ b/src/event/entity/ProjectileLaunchEvent.php @@ -30,9 +30,6 @@ use pocketmine\event\CancellableTrait; class ProjectileLaunchEvent extends EntityEvent implements Cancellable{ use CancellableTrait; - /** - * @param Projectile $entity - */ public function __construct(Projectile $entity){ $this->entity = $entity; } diff --git a/src/event/inventory/CraftItemEvent.php b/src/event/inventory/CraftItemEvent.php index 54c6cb5e10..63773158a4 100644 --- a/src/event/inventory/CraftItemEvent.php +++ b/src/event/inventory/CraftItemEvent.php @@ -46,9 +46,6 @@ class CraftItemEvent extends Event implements Cancellable{ private $outputs; /** - * @param CraftingTransaction $transaction - * @param CraftingRecipe $recipe - * @param int $repetitions * @param Item[] $inputs * @param Item[] $outputs */ @@ -62,8 +59,6 @@ class CraftItemEvent extends Event implements Cancellable{ /** * Returns the inventory transaction involved in this crafting event. - * - * @return CraftingTransaction */ public function getTransaction() : CraftingTransaction{ return $this->transaction; @@ -71,8 +66,6 @@ class CraftItemEvent extends Event implements Cancellable{ /** * Returns the recipe crafted. - * - * @return CraftingRecipe */ public function getRecipe() : CraftingRecipe{ return $this->recipe; @@ -81,8 +74,6 @@ class CraftItemEvent extends Event implements Cancellable{ /** * Returns the number of times the recipe was crafted. This is usually 1, but might be more in the case of recipe * book shift-clicks (which craft lots of items in a batch). - * - * @return int */ public function getRepetitions() : int{ return $this->repetitions; @@ -106,9 +97,6 @@ class CraftItemEvent extends Event implements Cancellable{ return $this->outputs; } - /** - * @return Player - */ public function getPlayer() : Player{ return $this->transaction->getSource(); } diff --git a/src/event/inventory/FurnaceBurnEvent.php b/src/event/inventory/FurnaceBurnEvent.php index 31d69f8957..32cc7efb85 100644 --- a/src/event/inventory/FurnaceBurnEvent.php +++ b/src/event/inventory/FurnaceBurnEvent.php @@ -41,11 +41,6 @@ class FurnaceBurnEvent extends BlockEvent implements Cancellable{ /** @var bool */ private $burning = true; - /** - * @param Furnace $furnace - * @param Item $fuel - * @param int $burnTime - */ public function __construct(Furnace $furnace, Item $fuel, int $burnTime){ parent::__construct($furnace->getBlock()); $this->fuel = $fuel; @@ -53,44 +48,26 @@ class FurnaceBurnEvent extends BlockEvent implements Cancellable{ $this->furnace = $furnace; } - /** - * @return Furnace - */ public function getFurnace() : Furnace{ return $this->furnace; } - /** - * @return Item - */ public function getFuel() : Item{ return $this->fuel; } - /** - * @return int - */ public function getBurnTime() : int{ return $this->burnTime; } - /** - * @param int $burnTime - */ public function setBurnTime(int $burnTime) : void{ $this->burnTime = $burnTime; } - /** - * @return bool - */ public function isBurning() : bool{ return $this->burning; } - /** - * @param bool $burning - */ public function setBurning(bool $burning) : void{ $this->burning = $burning; } diff --git a/src/event/inventory/FurnaceSmeltEvent.php b/src/event/inventory/FurnaceSmeltEvent.php index 5fb1f8be97..cb2b5d8284 100644 --- a/src/event/inventory/FurnaceSmeltEvent.php +++ b/src/event/inventory/FurnaceSmeltEvent.php @@ -39,11 +39,6 @@ class FurnaceSmeltEvent extends BlockEvent implements Cancellable{ /** @var Item */ private $result; - /** - * @param Furnace $furnace - * @param Item $source - * @param Item $result - */ public function __construct(Furnace $furnace, Item $source, Item $result){ parent::__construct($furnace->getBlock()); $this->source = clone $source; @@ -52,30 +47,18 @@ class FurnaceSmeltEvent extends BlockEvent implements Cancellable{ $this->furnace = $furnace; } - /** - * @return Furnace - */ public function getFurnace() : Furnace{ return $this->furnace; } - /** - * @return Item - */ public function getSource() : Item{ return $this->source; } - /** - * @return Item - */ public function getResult() : Item{ return $this->result; } - /** - * @param Item $result - */ public function setResult(Item $result) : void{ $this->result = $result; } diff --git a/src/event/inventory/InventoryCloseEvent.php b/src/event/inventory/InventoryCloseEvent.php index f123fc4974..1ea65234d6 100644 --- a/src/event/inventory/InventoryCloseEvent.php +++ b/src/event/inventory/InventoryCloseEvent.php @@ -30,18 +30,11 @@ class InventoryCloseEvent extends InventoryEvent{ /** @var Player */ private $who; - /** - * @param Inventory $inventory - * @param Player $who - */ public function __construct(Inventory $inventory, Player $who){ $this->who = $who; parent::__construct($inventory); } - /** - * @return Player - */ public function getPlayer() : Player{ return $this->who; } diff --git a/src/event/inventory/InventoryEvent.php b/src/event/inventory/InventoryEvent.php index 7c103e1a80..7c00c35fe1 100644 --- a/src/event/inventory/InventoryEvent.php +++ b/src/event/inventory/InventoryEvent.php @@ -38,9 +38,6 @@ abstract class InventoryEvent extends Event{ $this->inventory = $inventory; } - /** - * @return Inventory - */ public function getInventory() : Inventory{ return $this->inventory; } diff --git a/src/event/inventory/InventoryOpenEvent.php b/src/event/inventory/InventoryOpenEvent.php index 1eb43eb746..ee5c13eb53 100644 --- a/src/event/inventory/InventoryOpenEvent.php +++ b/src/event/inventory/InventoryOpenEvent.php @@ -34,18 +34,11 @@ class InventoryOpenEvent extends InventoryEvent implements Cancellable{ /** @var Player */ private $who; - /** - * @param Inventory $inventory - * @param Player $who - */ public function __construct(Inventory $inventory, Player $who){ $this->who = $who; parent::__construct($inventory); } - /** - * @return Player - */ public function getPlayer() : Player{ return $this->who; } diff --git a/src/event/inventory/InventoryPickupArrowEvent.php b/src/event/inventory/InventoryPickupArrowEvent.php index 058c6be929..1c4d2772d5 100644 --- a/src/event/inventory/InventoryPickupArrowEvent.php +++ b/src/event/inventory/InventoryPickupArrowEvent.php @@ -34,18 +34,11 @@ class InventoryPickupArrowEvent extends InventoryEvent implements Cancellable{ /** @var Arrow */ private $arrow; - /** - * @param Inventory $inventory - * @param Arrow $arrow - */ public function __construct(Inventory $inventory, Arrow $arrow){ $this->arrow = $arrow; parent::__construct($inventory); } - /** - * @return Arrow - */ public function getArrow() : Arrow{ return $this->arrow; } diff --git a/src/event/inventory/InventoryPickupItemEvent.php b/src/event/inventory/InventoryPickupItemEvent.php index 60ead87c74..ed15bbbe12 100644 --- a/src/event/inventory/InventoryPickupItemEvent.php +++ b/src/event/inventory/InventoryPickupItemEvent.php @@ -34,18 +34,11 @@ class InventoryPickupItemEvent extends InventoryEvent implements Cancellable{ /** @var ItemEntity */ private $item; - /** - * @param Inventory $inventory - * @param ItemEntity $item - */ public function __construct(Inventory $inventory, ItemEntity $item){ $this->item = $item; parent::__construct($inventory); } - /** - * @return ItemEntity - */ public function getItem() : ItemEntity{ return $this->item; } diff --git a/src/event/inventory/InventoryTransactionEvent.php b/src/event/inventory/InventoryTransactionEvent.php index 34f02ee242..7ec8c90234 100644 --- a/src/event/inventory/InventoryTransactionEvent.php +++ b/src/event/inventory/InventoryTransactionEvent.php @@ -38,16 +38,10 @@ class InventoryTransactionEvent extends Event implements Cancellable{ /** @var InventoryTransaction */ private $transaction; - /** - * @param InventoryTransaction $transaction - */ public function __construct(InventoryTransaction $transaction){ $this->transaction = $transaction; } - /** - * @return InventoryTransaction - */ public function getTransaction() : InventoryTransaction{ return $this->transaction; } diff --git a/src/event/player/PlayerBedEnterEvent.php b/src/event/player/PlayerBedEnterEvent.php index c25c28e268..a9e571c6fc 100644 --- a/src/event/player/PlayerBedEnterEvent.php +++ b/src/event/player/PlayerBedEnterEvent.php @@ -39,9 +39,6 @@ class PlayerBedEnterEvent extends PlayerEvent implements Cancellable{ $this->bed = $bed; } - /** - * @return Block - */ public function getBed() : Block{ return $this->bed; } diff --git a/src/event/player/PlayerBedLeaveEvent.php b/src/event/player/PlayerBedLeaveEvent.php index 0231edd362..7efe026733 100644 --- a/src/event/player/PlayerBedLeaveEvent.php +++ b/src/event/player/PlayerBedLeaveEvent.php @@ -35,9 +35,6 @@ class PlayerBedLeaveEvent extends PlayerEvent{ $this->bed = $bed; } - /** - * @return Block - */ public function getBed() : Block{ return $this->bed; } diff --git a/src/event/player/PlayerBucketEvent.php b/src/event/player/PlayerBucketEvent.php index 1080b533fb..3cea822428 100644 --- a/src/event/player/PlayerBucketEvent.php +++ b/src/event/player/PlayerBucketEvent.php @@ -44,13 +44,6 @@ abstract class PlayerBucketEvent extends PlayerEvent implements Cancellable{ /** @var Item */ private $item; - /** - * @param Player $who - * @param Block $blockClicked - * @param int $blockFace - * @param Item $bucket - * @param Item $itemInHand - */ public function __construct(Player $who, Block $blockClicked, int $blockFace, Item $bucket, Item $itemInHand){ $this->player = $who; $this->blockClicked = $blockClicked; @@ -61,8 +54,6 @@ abstract class PlayerBucketEvent extends PlayerEvent implements Cancellable{ /** * Returns the bucket used in this event - * - * @return Item */ public function getBucket() : Item{ return $this->bucket; @@ -70,30 +61,19 @@ abstract class PlayerBucketEvent extends PlayerEvent implements Cancellable{ /** * Returns the item in hand after the event - * - * @return Item */ public function getItem() : Item{ return $this->item; } - /** - * @param Item $item - */ public function setItem(Item $item) : void{ $this->item = $item; } - /** - * @return Block - */ public function getBlockClicked() : Block{ return $this->blockClicked; } - /** - * @return int - */ public function getBlockFace() : int{ return $this->blockFace; } diff --git a/src/event/player/PlayerChangeSkinEvent.php b/src/event/player/PlayerChangeSkinEvent.php index 0aa3802440..51fde74a3f 100644 --- a/src/event/player/PlayerChangeSkinEvent.php +++ b/src/event/player/PlayerChangeSkinEvent.php @@ -39,34 +39,21 @@ class PlayerChangeSkinEvent extends PlayerEvent implements Cancellable{ /** @var Skin */ private $newSkin; - /** - * @param Player $player - * @param Skin $oldSkin - * @param Skin $newSkin - */ public function __construct(Player $player, Skin $oldSkin, Skin $newSkin){ $this->player = $player; $this->oldSkin = $oldSkin; $this->newSkin = $newSkin; } - /** - * @return Skin - */ public function getOldSkin() : Skin{ return $this->oldSkin; } - /** - * @return Skin - */ public function getNewSkin() : Skin{ return $this->newSkin; } /** - * @param Skin $skin - * * @throws \InvalidArgumentException if the specified skin is not valid */ public function setNewSkin(Skin $skin) : void{ diff --git a/src/event/player/PlayerChatEvent.php b/src/event/player/PlayerChatEvent.php index b5ee99ac46..a7b7162f2c 100644 --- a/src/event/player/PlayerChatEvent.php +++ b/src/event/player/PlayerChatEvent.php @@ -49,9 +49,6 @@ class PlayerChatEvent extends PlayerEvent implements Cancellable{ protected $recipients = []; /** - * @param Player $player - * @param string $message - * @param string $format * @param CommandSender[] $recipients */ public function __construct(Player $player, string $message, string $format = "chat.type.text", ?array $recipients = null){ @@ -71,39 +68,25 @@ class PlayerChatEvent extends PlayerEvent implements Cancellable{ } } - /** - * @return string - */ public function getMessage() : string{ return $this->message; } - /** - * @param string $message - */ public function setMessage(string $message) : void{ $this->message = $message; } /** * Changes the player that is sending the message - * - * @param Player $player */ public function setPlayer(Player $player) : void{ $this->player = $player; } - /** - * @return string - */ public function getFormat() : string{ return $this->format; } - /** - * @param string $format - */ public function setFormat(string $format) : void{ $this->format = $format; } diff --git a/src/event/player/PlayerCommandPreprocessEvent.php b/src/event/player/PlayerCommandPreprocessEvent.php index 1831e1d19e..f1fae9665a 100644 --- a/src/event/player/PlayerCommandPreprocessEvent.php +++ b/src/event/player/PlayerCommandPreprocessEvent.php @@ -41,33 +41,19 @@ class PlayerCommandPreprocessEvent extends PlayerEvent implements Cancellable{ /** @var string */ protected $message; - - /** - * @param Player $player - * @param string $message - */ public function __construct(Player $player, string $message){ $this->player = $player; $this->message = $message; } - /** - * @return string - */ public function getMessage() : string{ return $this->message; } - /** - * @param string $message - */ public function setMessage(string $message) : void{ $this->message = $message; } - /** - * @param Player $player - */ public function setPlayer(Player $player) : void{ $this->player = $player; } diff --git a/src/event/player/PlayerCreationEvent.php b/src/event/player/PlayerCreationEvent.php index 28f8290be8..f9ed288078 100644 --- a/src/event/player/PlayerCreationEvent.php +++ b/src/event/player/PlayerCreationEvent.php @@ -41,31 +41,18 @@ class PlayerCreationEvent extends Event{ /** @var string */ private $playerClass = Player::class; - - /** - * @param NetworkSession $session - */ public function __construct(NetworkSession $session){ $this->session = $session; } - /** - * @return NetworkSession - */ public function getNetworkSession() : NetworkSession{ return $this->session; } - /** - * @return string - */ public function getAddress() : string{ return $this->session->getIp(); } - /** - * @return int - */ public function getPort() : int{ return $this->session->getPort(); } diff --git a/src/event/player/PlayerDataSaveEvent.php b/src/event/player/PlayerDataSaveEvent.php index 5f08d4fb4c..ad49aba2b7 100644 --- a/src/event/player/PlayerDataSaveEvent.php +++ b/src/event/player/PlayerDataSaveEvent.php @@ -48,22 +48,17 @@ class PlayerDataSaveEvent extends Event implements Cancellable{ /** * Returns the data to be written to disk as a CompoundTag - * @return CompoundTag */ public function getSaveData() : CompoundTag{ return $this->data; } - /** - * @param CompoundTag $data - */ public function setSaveData(CompoundTag $data) : void{ $this->data = $data; } /** * Returns the username of the player whose data is being saved. This is not necessarily an online player. - * @return string */ public function getPlayerName() : string{ return $this->playerName; diff --git a/src/event/player/PlayerDeathEvent.php b/src/event/player/PlayerDeathEvent.php index 303591777d..e28c643d10 100644 --- a/src/event/player/PlayerDeathEvent.php +++ b/src/event/player/PlayerDeathEvent.php @@ -44,9 +44,7 @@ class PlayerDeathEvent extends EntityDeathEvent{ private $keepInventory = false; /** - * @param Player $entity * @param Item[] $drops - * @param int $xp * @param string|TextContainer|null $deathMessage Null will cause the default vanilla message to be used */ public function __construct(Player $entity, array $drops, int $xp, $deathMessage){ @@ -61,9 +59,6 @@ class PlayerDeathEvent extends EntityDeathEvent{ return $this->entity; } - /** - * @return Player - */ public function getPlayer() : Player{ return $this->entity; } @@ -92,11 +87,6 @@ class PlayerDeathEvent extends EntityDeathEvent{ /** * Returns the vanilla death message for the given death cause. - * - * @param string $name - * @param null|EntityDamageEvent $deathCause - * - * @return TranslationContainer */ public static function deriveMessage(string $name, ?EntityDamageEvent $deathCause) : TranslationContainer{ $message = "death.attack.generic"; diff --git a/src/event/player/PlayerDropItemEvent.php b/src/event/player/PlayerDropItemEvent.php index 46a88ec9e9..a97a6f5fad 100644 --- a/src/event/player/PlayerDropItemEvent.php +++ b/src/event/player/PlayerDropItemEvent.php @@ -37,18 +37,11 @@ class PlayerDropItemEvent extends PlayerEvent implements Cancellable{ /** @var Item */ private $drop; - /** - * @param Player $player - * @param Item $drop - */ public function __construct(Player $player, Item $drop){ $this->player = $player; $this->drop = $drop; } - /** - * @return Item - */ public function getItem() : Item{ return $this->drop; } diff --git a/src/event/player/PlayerDuplicateLoginEvent.php b/src/event/player/PlayerDuplicateLoginEvent.php index d77f6fc4cc..92fc34547a 100644 --- a/src/event/player/PlayerDuplicateLoginEvent.php +++ b/src/event/player/PlayerDuplicateLoginEvent.php @@ -57,16 +57,11 @@ class PlayerDuplicateLoginEvent extends Event implements Cancellable{ /** * Returns the message shown to the session which gets disconnected. - * - * @return string */ public function getDisconnectMessage() : string{ return $this->disconnectMessage; } - /** - * @param string $message - */ public function setDisconnectMessage(string $message) : void{ $this->disconnectMessage = $message; } diff --git a/src/event/player/PlayerEditBookEvent.php b/src/event/player/PlayerEditBookEvent.php index 074bf3f132..ed5c037068 100644 --- a/src/event/player/PlayerEditBookEvent.php +++ b/src/event/player/PlayerEditBookEvent.php @@ -56,8 +56,6 @@ class PlayerEditBookEvent extends PlayerEvent implements Cancellable{ /** * Returns the action of the event. - * - * @return int */ public function getAction() : int{ return $this->action; @@ -65,8 +63,6 @@ class PlayerEditBookEvent extends PlayerEvent implements Cancellable{ /** * Returns the book before it was modified. - * - * @return WritableBookBase */ public function getOldBook() : WritableBookBase{ return $this->oldBook; @@ -75,8 +71,6 @@ class PlayerEditBookEvent extends PlayerEvent implements Cancellable{ /** * Returns the book after it was modified. * The new book may be a written book, if the book was signed. - * - * @return WritableBookBase */ public function getNewBook() : WritableBookBase{ return $this->newBook; @@ -84,8 +78,6 @@ class PlayerEditBookEvent extends PlayerEvent implements Cancellable{ /** * Sets the new book as the given instance. - * - * @param WritableBookBase $book */ public function setNewBook(WritableBookBase $book) : void{ $this->newBook = $book; diff --git a/src/event/player/PlayerExhaustEvent.php b/src/event/player/PlayerExhaustEvent.php index 91ab4caea3..0002d8d822 100644 --- a/src/event/player/PlayerExhaustEvent.php +++ b/src/event/player/PlayerExhaustEvent.php @@ -75,7 +75,6 @@ class PlayerExhaustEvent extends EntityEvent implements Cancellable{ /** * Returns an int cause of the exhaustion - one of the constants at the top of this class. - * @return int */ public function getCause() : int{ return $this->cause; diff --git a/src/event/player/PlayerExperienceChangeEvent.php b/src/event/player/PlayerExperienceChangeEvent.php index 56197678c3..86d0b085bd 100644 --- a/src/event/player/PlayerExperienceChangeEvent.php +++ b/src/event/player/PlayerExperienceChangeEvent.php @@ -54,16 +54,10 @@ class PlayerExperienceChangeEvent extends EntityEvent implements Cancellable{ $this->newProgress = $newProgress; } - /** - * @return int - */ public function getOldLevel() : int{ return $this->oldLevel; } - /** - * @return float - */ public function getOldProgress() : float{ return $this->oldProgress; } @@ -82,16 +76,10 @@ class PlayerExperienceChangeEvent extends EntityEvent implements Cancellable{ return $this->newProgress; } - /** - * @param int|null $newLevel - */ public function setNewLevel(?int $newLevel) : void{ $this->newLevel = $newLevel; } - /** - * @param float|null $newProgress - */ public function setNewProgress(?float $newProgress) : void{ $this->newProgress = $newProgress; } diff --git a/src/event/player/PlayerInteractEvent.php b/src/event/player/PlayerInteractEvent.php index 3d01955fcc..f67b72d9cf 100644 --- a/src/event/player/PlayerInteractEvent.php +++ b/src/event/player/PlayerInteractEvent.php @@ -54,14 +54,6 @@ class PlayerInteractEvent extends PlayerEvent implements Cancellable{ /** @var int */ protected $action; - /** - * @param Player $player - * @param Item $item - * @param Block $block - * @param Vector3|null $touchVector - * @param int $face - * @param int $action - */ public function __construct(Player $player, Item $item, Block $block, ?Vector3 $touchVector, int $face, int $action = PlayerInteractEvent::RIGHT_CLICK_BLOCK){ $this->player = $player; $this->item = $item; @@ -71,37 +63,22 @@ class PlayerInteractEvent extends PlayerEvent implements Cancellable{ $this->action = $action; } - /** - * @return int - */ public function getAction() : int{ return $this->action; } - /** - * @return Item - */ public function getItem() : Item{ return $this->item; } - /** - * @return Block - */ public function getBlock() : Block{ return $this->blockTouched; } - /** - * @return Vector3 - */ public function getTouchVector() : Vector3{ return $this->touchVector; } - /** - * @return int - */ public function getFace() : int{ return $this->blockFace; } diff --git a/src/event/player/PlayerItemConsumeEvent.php b/src/event/player/PlayerItemConsumeEvent.php index f08a5847fd..52bb5e2433 100644 --- a/src/event/player/PlayerItemConsumeEvent.php +++ b/src/event/player/PlayerItemConsumeEvent.php @@ -37,18 +37,11 @@ class PlayerItemConsumeEvent extends PlayerEvent implements Cancellable{ /** @var Item */ private $item; - /** - * @param Player $player - * @param Item $item - */ public function __construct(Player $player, Item $item){ $this->player = $player; $this->item = $item; } - /** - * @return Item - */ public function getItem() : Item{ return clone $this->item; } diff --git a/src/event/player/PlayerItemHeldEvent.php b/src/event/player/PlayerItemHeldEvent.php index 7fbd3f4cc1..71f55fc534 100644 --- a/src/event/player/PlayerItemHeldEvent.php +++ b/src/event/player/PlayerItemHeldEvent.php @@ -49,8 +49,6 @@ class PlayerItemHeldEvent extends PlayerEvent implements Cancellable{ * event will result in the **old** slot being changed, not this one. * * To change the item in the slot that the player is attempting to hold, set the slot that this function reports. - * - * @return int */ public function getSlot() : int{ return $this->hotbarSlot; @@ -58,8 +56,6 @@ class PlayerItemHeldEvent extends PlayerEvent implements Cancellable{ /** * Returns the item in the slot that the player is trying to equip. - * - * @return Item */ public function getItem() : Item{ return $this->item; diff --git a/src/event/player/PlayerItemUseEvent.php b/src/event/player/PlayerItemUseEvent.php index ec804115a8..b9216d5281 100644 --- a/src/event/player/PlayerItemUseEvent.php +++ b/src/event/player/PlayerItemUseEvent.php @@ -40,11 +40,6 @@ class PlayerItemUseEvent extends PlayerEvent implements Cancellable{ /** @var Vector3 */ private $directionVector; - /** - * @param Player $player - * @param Item $item - * @param Vector3 $directionVector - */ public function __construct(Player $player, Item $item, Vector3 $directionVector){ $this->player = $player; $this->item = $item; @@ -53,8 +48,6 @@ class PlayerItemUseEvent extends PlayerEvent implements Cancellable{ /** * Returns the item used. - * - * @return Item */ public function getItem() : Item{ return $this->item; @@ -62,8 +55,6 @@ class PlayerItemUseEvent extends PlayerEvent implements Cancellable{ /** * Returns the direction the player is aiming when activating this item. Used for projectile direction. - * - * @return Vector3 */ public function getDirectionVector() : Vector3{ return $this->directionVector; diff --git a/src/event/player/PlayerJoinEvent.php b/src/event/player/PlayerJoinEvent.php index 64b7a6c2d5..57e77ccdb3 100644 --- a/src/event/player/PlayerJoinEvent.php +++ b/src/event/player/PlayerJoinEvent.php @@ -40,7 +40,6 @@ class PlayerJoinEvent extends PlayerEvent{ /** * PlayerJoinEvent constructor. * - * @param Player $player * @param TextContainer|string $joinMessage */ public function __construct(Player $player, $joinMessage){ diff --git a/src/event/player/PlayerJumpEvent.php b/src/event/player/PlayerJumpEvent.php index e3e67da383..3d9b6d1674 100644 --- a/src/event/player/PlayerJumpEvent.php +++ b/src/event/player/PlayerJumpEvent.php @@ -32,8 +32,6 @@ class PlayerJumpEvent extends PlayerEvent{ /** * PlayerJumpEvent constructor. - * - * @param Player $player */ public function __construct(Player $player){ $this->player = $player; diff --git a/src/event/player/PlayerKickEvent.php b/src/event/player/PlayerKickEvent.php index 971269c2c7..dd78ba63a5 100644 --- a/src/event/player/PlayerKickEvent.php +++ b/src/event/player/PlayerKickEvent.php @@ -43,8 +43,6 @@ class PlayerKickEvent extends PlayerEvent implements Cancellable{ /** * PlayerKickEvent constructor. * - * @param Player $player - * @param string $reason * @param TextContainer|string $quitMessage */ public function __construct(Player $player, string $reason, $quitMessage){ @@ -53,9 +51,6 @@ class PlayerKickEvent extends PlayerEvent implements Cancellable{ $this->reason = $reason; } - /** - * @param string $reason - */ public function setReason(string $reason) : void{ $this->reason = $reason; } diff --git a/src/event/player/PlayerLoginEvent.php b/src/event/player/PlayerLoginEvent.php index 979750090c..8c418f7037 100644 --- a/src/event/player/PlayerLoginEvent.php +++ b/src/event/player/PlayerLoginEvent.php @@ -38,25 +38,15 @@ class PlayerLoginEvent extends PlayerEvent implements Cancellable{ /** @var string */ protected $kickMessage; - /** - * @param Player $player - * @param string $kickMessage - */ public function __construct(Player $player, string $kickMessage){ $this->player = $player; $this->kickMessage = $kickMessage; } - /** - * @param string $kickMessage - */ public function setKickMessage(string $kickMessage) : void{ $this->kickMessage = $kickMessage; } - /** - * @return string - */ public function getKickMessage() : string{ return $this->kickMessage; } diff --git a/src/event/player/PlayerMoveEvent.php b/src/event/player/PlayerMoveEvent.php index dbcf92bcf3..d9f258a3c7 100644 --- a/src/event/player/PlayerMoveEvent.php +++ b/src/event/player/PlayerMoveEvent.php @@ -36,34 +36,20 @@ class PlayerMoveEvent extends PlayerEvent implements Cancellable{ /** @var Location */ private $to; - /** - * @param Player $player - * @param Location $from - * @param Location $to - */ public function __construct(Player $player, Location $from, Location $to){ $this->player = $player; $this->from = $from; $this->to = $to; } - /** - * @return Location - */ public function getFrom() : Location{ return $this->from; } - /** - * @return Location - */ public function getTo() : Location{ return $this->to; } - /** - * @param Location $to - */ public function setTo(Location $to) : void{ $this->to = $to; } diff --git a/src/event/player/PlayerPreLoginEvent.php b/src/event/player/PlayerPreLoginEvent.php index 9a566813ec..03a6d2b852 100644 --- a/src/event/player/PlayerPreLoginEvent.php +++ b/src/event/player/PlayerPreLoginEvent.php @@ -62,12 +62,6 @@ class PlayerPreLoginEvent extends Event{ /** @var string[] reason const => associated message */ protected $kickReasons = []; - /** - * @param PlayerInfo $playerInfo - * @param string $ip - * @param int $port - * @param bool $authRequired - */ public function __construct(PlayerInfo $playerInfo, string $ip, int $port, bool $authRequired){ $this->playerInfo = $playerInfo; $this->ip = $ip; @@ -79,37 +73,23 @@ class PlayerPreLoginEvent extends Event{ * Returns an object containing self-proclaimed information about the connecting player. * WARNING: THE PLAYER IS NOT VERIFIED DURING THIS EVENT. At this point, it's unknown if the player is real or a * hacker. - * - * @return PlayerInfo */ public function getPlayerInfo() : PlayerInfo{ return $this->playerInfo; } - /** - * @return string - */ public function getIp() : string{ return $this->ip; } - /** - * @return int - */ public function getPort() : int{ return $this->port; } - /** - * @return bool - */ public function isAuthRequired() : bool{ return $this->authRequired; } - /** - * @param bool $v - */ public function setAuthRequired(bool $v) : void{ $this->authRequired = $v; } @@ -125,10 +105,6 @@ class PlayerPreLoginEvent extends Event{ /** * Returns whether the given kick reason is set for this event. - * - * @param int $flag - * - * @return bool */ public function isKickReasonSet(int $flag) : bool{ return isset($this->kickReasons[$flag]); @@ -137,9 +113,6 @@ class PlayerPreLoginEvent extends Event{ /** * Sets a reason to disallow the player to continue continue authenticating, with a message. * This can also be used to change kick messages for already-set flags. - * - * @param int $flag - * @param string $message */ public function setKickReason(int $flag, string $message) : void{ $this->kickReasons[$flag] = $message; @@ -164,8 +137,6 @@ class PlayerPreLoginEvent extends Event{ /** * Returns whether the player is allowed to continue logging in. - * - * @return bool */ public function isAllowed() : bool{ return empty($this->kickReasons); @@ -173,10 +144,6 @@ class PlayerPreLoginEvent extends Event{ /** * Returns the kick message provided for the given kick flag, or null if not set. - * - * @param int $flag - * - * @return string|null */ public function getKickMessage(int $flag) : ?string{ return $this->kickReasons[$flag] ?? null; @@ -189,8 +156,6 @@ class PlayerPreLoginEvent extends Event{ * messages. * * @see PlayerPreLoginEvent::KICK_REASON_PRIORITY - * - * @return string */ public function getFinalKickMessage() : string{ foreach(self::KICK_REASON_PRIORITY as $p){ diff --git a/src/event/player/PlayerQuitEvent.php b/src/event/player/PlayerQuitEvent.php index 028548b153..4fe6bf71f8 100644 --- a/src/event/player/PlayerQuitEvent.php +++ b/src/event/player/PlayerQuitEvent.php @@ -37,9 +37,7 @@ class PlayerQuitEvent extends PlayerEvent{ protected $quitReason; /** - * @param Player $player * @param TranslationContainer|string $quitMessage - * @param string $quitReason */ public function __construct(Player $player, $quitMessage, string $quitReason){ $this->player = $player; @@ -61,9 +59,6 @@ class PlayerQuitEvent extends PlayerEvent{ return $this->quitMessage; } - /** - * @return string - */ public function getQuitReason() : string{ return $this->quitReason; } diff --git a/src/event/player/PlayerRespawnEvent.php b/src/event/player/PlayerRespawnEvent.php index 926da5e178..8933aaeb59 100644 --- a/src/event/player/PlayerRespawnEvent.php +++ b/src/event/player/PlayerRespawnEvent.php @@ -33,25 +33,15 @@ class PlayerRespawnEvent extends PlayerEvent{ /** @var Position */ protected $position; - /** - * @param Player $player - * @param Position $position - */ public function __construct(Player $player, Position $position){ $this->player = $player; $this->position = $position; } - /** - * @return Position - */ public function getRespawnPosition() : Position{ return $this->position; } - /** - * @param Position $position - */ public function setRespawnPosition(Position $position) : void{ $this->position = $position; } diff --git a/src/event/player/PlayerToggleFlightEvent.php b/src/event/player/PlayerToggleFlightEvent.php index 1547e7ed2b..b8c0f93d9e 100644 --- a/src/event/player/PlayerToggleFlightEvent.php +++ b/src/event/player/PlayerToggleFlightEvent.php @@ -33,18 +33,11 @@ class PlayerToggleFlightEvent extends PlayerEvent implements Cancellable{ /** @var bool */ protected $isFlying; - /** - * @param Player $player - * @param bool $isFlying - */ public function __construct(Player $player, bool $isFlying){ $this->player = $player; $this->isFlying = $isFlying; } - /** - * @return bool - */ public function isFlying() : bool{ return $this->isFlying; } diff --git a/src/event/player/PlayerToggleSneakEvent.php b/src/event/player/PlayerToggleSneakEvent.php index 14dd0d4fec..0b7538975a 100644 --- a/src/event/player/PlayerToggleSneakEvent.php +++ b/src/event/player/PlayerToggleSneakEvent.php @@ -33,18 +33,11 @@ class PlayerToggleSneakEvent extends PlayerEvent implements Cancellable{ /** @var bool */ protected $isSneaking; - /** - * @param Player $player - * @param bool $isSneaking - */ public function __construct(Player $player, bool $isSneaking){ $this->player = $player; $this->isSneaking = $isSneaking; } - /** - * @return bool - */ public function isSneaking() : bool{ return $this->isSneaking; } diff --git a/src/event/player/PlayerToggleSprintEvent.php b/src/event/player/PlayerToggleSprintEvent.php index 67bae14245..2da14d7b7a 100644 --- a/src/event/player/PlayerToggleSprintEvent.php +++ b/src/event/player/PlayerToggleSprintEvent.php @@ -33,18 +33,11 @@ class PlayerToggleSprintEvent extends PlayerEvent implements Cancellable{ /** @var bool */ protected $isSprinting; - /** - * @param Player $player - * @param bool $isSprinting - */ public function __construct(Player $player, bool $isSprinting){ $this->player = $player; $this->isSprinting = $isSprinting; } - /** - * @return bool - */ public function isSprinting() : bool{ return $this->isSprinting; } diff --git a/src/event/player/PlayerTransferEvent.php b/src/event/player/PlayerTransferEvent.php index 082dd619b4..9e6669893e 100644 --- a/src/event/player/PlayerTransferEvent.php +++ b/src/event/player/PlayerTransferEvent.php @@ -37,12 +37,6 @@ class PlayerTransferEvent extends PlayerEvent implements Cancellable{ /** @var string */ protected $message; - /** - * @param Player $player - * @param string $address - * @param int $port - * @param string $message - */ public function __construct(Player $player, string $address, int $port, string $message){ $this->player = $player; $this->address = $address; @@ -50,44 +44,26 @@ class PlayerTransferEvent extends PlayerEvent implements Cancellable{ $this->message = $message; } - /** - * @return string - */ public function getAddress() : string{ return $this->address; } - /** - * @param string $address - */ public function setAddress(string $address) : void{ $this->address = $address; } - /** - * @return int - */ public function getPort() : int{ return $this->port; } - /** - * @param int $port - */ public function setPort(int $port) : void{ $this->port = $port; } - /** - * @return string - */ public function getMessage() : string{ return $this->message; } - /** - * @param string $message - */ public function setMessage(string $message) : void{ $this->message = $message; } diff --git a/src/event/plugin/PluginEvent.php b/src/event/plugin/PluginEvent.php index 2263d78f5f..82faa06380 100644 --- a/src/event/plugin/PluginEvent.php +++ b/src/event/plugin/PluginEvent.php @@ -37,9 +37,6 @@ abstract class PluginEvent extends Event{ $this->plugin = $plugin; } - /** - * @return Plugin - */ public function getPlugin() : Plugin{ return $this->plugin; } diff --git a/src/event/server/CommandEvent.php b/src/event/server/CommandEvent.php index 95f1cca6a5..818a465cb2 100644 --- a/src/event/server/CommandEvent.php +++ b/src/event/server/CommandEvent.php @@ -44,32 +44,19 @@ class CommandEvent extends ServerEvent implements Cancellable{ /** @var CommandSender */ protected $sender; - /** - * @param CommandSender $sender - * @param string $command - */ public function __construct(CommandSender $sender, string $command){ $this->sender = $sender; $this->command = $command; } - /** - * @return CommandSender - */ public function getSender() : CommandSender{ return $this->sender; } - /** - * @return string - */ public function getCommand() : string{ return $this->command; } - /** - * @param string $command - */ public function setCommand(string $command) : void{ $this->command = $command; } diff --git a/src/event/server/DataPacketReceiveEvent.php b/src/event/server/DataPacketReceiveEvent.php index 7b25a28c7f..c3443d2061 100644 --- a/src/event/server/DataPacketReceiveEvent.php +++ b/src/event/server/DataPacketReceiveEvent.php @@ -36,25 +36,15 @@ class DataPacketReceiveEvent extends ServerEvent implements Cancellable{ /** @var NetworkSession */ private $origin; - /** - * @param NetworkSession $origin - * @param ServerboundPacket $packet - */ public function __construct(NetworkSession $origin, ServerboundPacket $packet){ $this->packet = $packet; $this->origin = $origin; } - /** - * @return ServerboundPacket - */ public function getPacket() : ServerboundPacket{ return $this->packet; } - /** - * @return NetworkSession - */ public function getOrigin() : NetworkSession{ return $this->origin; } diff --git a/src/event/server/LowMemoryEvent.php b/src/event/server/LowMemoryEvent.php index aaaaded625..ecdfb2f469 100644 --- a/src/event/server/LowMemoryEvent.php +++ b/src/event/server/LowMemoryEvent.php @@ -49,8 +49,6 @@ class LowMemoryEvent extends ServerEvent{ /** * Returns the memory usage at the time of the event call (in bytes) - * - * @return int */ public function getMemory() : int{ return $this->memory; @@ -58,8 +56,6 @@ class LowMemoryEvent extends ServerEvent{ /** * Returns the memory limit defined (in bytes) - * - * @return int */ public function getMemoryLimit() : int{ return $this->memoryLimit; @@ -67,24 +63,17 @@ class LowMemoryEvent extends ServerEvent{ /** * Returns the times this event has been called in the current low-memory state - * - * @return int */ public function getTriggerCount() : int{ return $this->triggerCount; } - /** - * @return bool - */ public function isGlobal() : bool{ return $this->global; } /** * Amount of memory already freed - * - * @return int */ public function getMemoryFreed() : int{ return $this->getMemory() - ($this->isGlobal() ? Process::getMemoryUsage(true)[1] : Process::getMemoryUsage(true)[0]); diff --git a/src/event/server/NetworkInterfaceEvent.php b/src/event/server/NetworkInterfaceEvent.php index f6ed969c64..98f48f07db 100644 --- a/src/event/server/NetworkInterfaceEvent.php +++ b/src/event/server/NetworkInterfaceEvent.php @@ -29,16 +29,10 @@ class NetworkInterfaceEvent extends ServerEvent{ /** @var NetworkInterface */ protected $interface; - /** - * @param NetworkInterface $interface - */ public function __construct(NetworkInterface $interface){ $this->interface = $interface; } - /** - * @return NetworkInterface - */ public function getInterface() : NetworkInterface{ return $this->interface; } diff --git a/src/event/server/QueryRegenerateEvent.php b/src/event/server/QueryRegenerateEvent.php index fc007edcaf..d86101da59 100644 --- a/src/event/server/QueryRegenerateEvent.php +++ b/src/event/server/QueryRegenerateEvent.php @@ -71,10 +71,6 @@ class QueryRegenerateEvent extends ServerEvent{ /** @var string|null */ private $shortQueryCache = null; - - /** - * @param Server $server - */ public function __construct(Server $server){ $this->serverName = $server->getMotd(); $this->listPlugins = $server->getProperty("settings.query-plugins", true); @@ -99,31 +95,19 @@ class QueryRegenerateEvent extends ServerEvent{ $this->shortQueryCache = null; } - /** - * @return string - */ public function getServerName() : string{ return $this->serverName; } - /** - * @param string $serverName - */ public function setServerName(string $serverName) : void{ $this->serverName = $serverName; $this->destroyCache(); } - /** - * @return bool - */ public function canListPlugins() : bool{ return $this->listPlugins; } - /** - * @param bool $value - */ public function setListPlugins(bool $value) : void{ $this->listPlugins = $value; $this->destroyCache(); @@ -159,46 +143,28 @@ class QueryRegenerateEvent extends ServerEvent{ $this->destroyCache(); } - /** - * @return int - */ public function getPlayerCount() : int{ return $this->numPlayers; } - /** - * @param int $count - */ public function setPlayerCount(int $count) : void{ $this->numPlayers = $count; $this->destroyCache(); } - /** - * @return int - */ public function getMaxPlayerCount() : int{ return $this->maxPlayers; } - /** - * @param int $count - */ public function setMaxPlayerCount(int $count) : void{ $this->maxPlayers = $count; $this->destroyCache(); } - /** - * @return string - */ public function getWorld() : string{ return $this->map; } - /** - * @param string $world - */ public function setWorld(string $world) : void{ $this->map = $world; $this->destroyCache(); @@ -206,24 +172,16 @@ class QueryRegenerateEvent extends ServerEvent{ /** * Returns the extra Query data in key => value form - * - * @return array */ public function getExtraData() : array{ return $this->extraData; } - /** - * @param array $extraData - */ public function setExtraData(array $extraData) : void{ $this->extraData = $extraData; $this->destroyCache(); } - /** - * @return string - */ public function getLongQuery() : string{ if($this->longQueryCache !== null){ return $this->longQueryCache; @@ -273,9 +231,6 @@ class QueryRegenerateEvent extends ServerEvent{ return $this->longQueryCache = $query; } - /** - * @return string - */ public function getShortQuery() : string{ return $this->shortQueryCache ?? ($this->shortQueryCache = $this->serverName . "\x00" . $this->gametype . "\x00" . $this->map . "\x00" . $this->numPlayers . "\x00" . $this->maxPlayers . "\x00" . Binary::writeLShort($this->port) . $this->ip . "\x00"); } diff --git a/src/event/world/ChunkEvent.php b/src/event/world/ChunkEvent.php index 993e77d25d..02db808e22 100644 --- a/src/event/world/ChunkEvent.php +++ b/src/event/world/ChunkEvent.php @@ -34,18 +34,11 @@ abstract class ChunkEvent extends WorldEvent{ /** @var Chunk */ private $chunk; - /** - * @param World $world - * @param Chunk $chunk - */ public function __construct(World $world, Chunk $chunk){ parent::__construct($world); $this->chunk = $chunk; } - /** - * @return Chunk - */ public function getChunk() : Chunk{ return $this->chunk; } diff --git a/src/event/world/ChunkLoadEvent.php b/src/event/world/ChunkLoadEvent.php index 575bf74cf8..3e6dad4086 100644 --- a/src/event/world/ChunkLoadEvent.php +++ b/src/event/world/ChunkLoadEvent.php @@ -39,9 +39,6 @@ class ChunkLoadEvent extends ChunkEvent{ $this->newChunk = $newChunk; } - /** - * @return bool - */ public function isNewChunk() : bool{ return $this->newChunk; } diff --git a/src/event/world/SpawnChangeEvent.php b/src/event/world/SpawnChangeEvent.php index 2088568598..dba959a649 100644 --- a/src/event/world/SpawnChangeEvent.php +++ b/src/event/world/SpawnChangeEvent.php @@ -34,18 +34,11 @@ class SpawnChangeEvent extends WorldEvent{ /** @var Position */ private $previousSpawn; - /** - * @param World $world - * @param Position $previousSpawn - */ public function __construct(World $world, Position $previousSpawn){ parent::__construct($world); $this->previousSpawn = $previousSpawn; } - /** - * @return Position - */ public function getPreviousSpawn() : Position{ return $this->previousSpawn; } diff --git a/src/event/world/WorldEvent.php b/src/event/world/WorldEvent.php index 193a0d8e1c..c842825ae4 100644 --- a/src/event/world/WorldEvent.php +++ b/src/event/world/WorldEvent.php @@ -33,16 +33,10 @@ abstract class WorldEvent extends Event{ /** @var World */ private $world; - /** - * @param World $world - */ public function __construct(World $world){ $this->world = $world; } - /** - * @return World - */ public function getWorld() : World{ return $this->world; } diff --git a/src/form/Form.php b/src/form/Form.php index 1e6b43dd70..2598349f6b 100644 --- a/src/form/Form.php +++ b/src/form/Form.php @@ -34,7 +34,6 @@ interface Form extends \JsonSerializable{ /** * Handles a form response from a player. * - * @param Player $player * @param mixed $data * * @throws FormValidationException if the data could not be processed diff --git a/src/inventory/BaseInventory.php b/src/inventory/BaseInventory.php index 888d4a7b34..e03415e9c6 100644 --- a/src/inventory/BaseInventory.php +++ b/src/inventory/BaseInventory.php @@ -43,16 +43,12 @@ abstract class BaseInventory implements Inventory{ /** @var InventoryChangeListener[] */ protected $listeners = []; - /** - * @param int $size - */ public function __construct(int $size){ $this->slots = new \SplFixedArray($size); } /** * Returns the size of the inventory. - * @return int */ public function getSize() : int{ return $this->slots->getSize(); @@ -67,8 +63,6 @@ abstract class BaseInventory implements Inventory{ } /** - * @param bool $includeEmpty - * * @return Item[] */ public function getContents(bool $includeEmpty = false) : array{ @@ -87,7 +81,6 @@ abstract class BaseInventory implements Inventory{ /** * @param Item[] $items - * @param bool $send */ public function setContents(array $items, bool $send = true) : void{ if(count($items) > $this->getSize()){ diff --git a/src/inventory/ChestInventory.php b/src/inventory/ChestInventory.php index 49235d4446..bf1d3fed4f 100644 --- a/src/inventory/ChestInventory.php +++ b/src/inventory/ChestInventory.php @@ -33,9 +33,6 @@ use function count; class ChestInventory extends BlockInventory{ - /** - * @param Position $holder - */ public function __construct(Position $holder){ parent::__construct($holder, 27); } diff --git a/src/inventory/CreativeInventory.php b/src/inventory/CreativeInventory.php index d157d79fb5..45bee9f973 100644 --- a/src/inventory/CreativeInventory.php +++ b/src/inventory/CreativeInventory.php @@ -67,11 +67,6 @@ final class CreativeInventory{ return self::$creative; } - /** - * @param int $index - * - * @return Item|null - */ public static function getItem(int $index) : ?Item{ return self::$creative[$index] ?? null; } @@ -89,8 +84,6 @@ final class CreativeInventory{ /** * Adds an item to the creative menu. * Note: Players who are already online when this is called will not see this change. - * - * @param Item $item */ public static function add(Item $item) : void{ self::$creative[] = clone $item; @@ -99,8 +92,6 @@ final class CreativeInventory{ /** * Removes an item from the creative menu. * Note: Players who are already online when this is called will not see this change. - * - * @param Item $item */ public static function remove(Item $item) : void{ $index = self::getItemIndex($item); diff --git a/src/inventory/DoubleChestInventory.php b/src/inventory/DoubleChestInventory.php index 273e04c2a9..2f607f06a5 100644 --- a/src/inventory/DoubleChestInventory.php +++ b/src/inventory/DoubleChestInventory.php @@ -87,16 +87,10 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ parent::onClose($who); } - /** - * @return ChestInventory - */ public function getLeftSide() : ChestInventory{ return $this->left; } - /** - * @return ChestInventory - */ public function getRightSide() : ChestInventory{ return $this->right; } diff --git a/src/inventory/EnderChestInventory.php b/src/inventory/EnderChestInventory.php index 935ee7fe79..bd9a448f2c 100644 --- a/src/inventory/EnderChestInventory.php +++ b/src/inventory/EnderChestInventory.php @@ -34,9 +34,6 @@ class EnderChestInventory extends ChestInventory{ parent::__construct(new Position(0, 0, 0, null)); } - /** - * @param Position $pos - */ public function setHolderPosition(Position $pos) : void{ $this->holder = $pos->asPosition(); } diff --git a/src/inventory/FurnaceInventory.php b/src/inventory/FurnaceInventory.php index b04620dd94..c681111200 100644 --- a/src/inventory/FurnaceInventory.php +++ b/src/inventory/FurnaceInventory.php @@ -32,44 +32,26 @@ class FurnaceInventory extends BlockInventory{ parent::__construct($holder, 3); } - /** - * @return Item - */ public function getResult() : Item{ return $this->getItem(2); } - /** - * @return Item - */ public function getFuel() : Item{ return $this->getItem(1); } - /** - * @return Item - */ public function getSmelting() : Item{ return $this->getItem(0); } - /** - * @param Item $item - */ public function setResult(Item $item) : void{ $this->setItem(2, $item); } - /** - * @param Item $item - */ public function setFuel(Item $item) : void{ $this->setItem(1, $item); } - /** - * @param Item $item - */ public function setSmelting(Item $item) : void{ $this->setItem(0, $item); } diff --git a/src/inventory/Inventory.php b/src/inventory/Inventory.php index 0224ba4cfb..f8bdd9f1d1 100644 --- a/src/inventory/Inventory.php +++ b/src/inventory/Inventory.php @@ -32,34 +32,16 @@ use pocketmine\player\Player; interface Inventory{ public const MAX_STACK = 64; - /** - * @return int - */ public function getSize() : int; - /** - * @return int - */ public function getMaxStackSize() : int; - /** - * @param int $size - */ public function setMaxStackSize(int $size) : void; - /** - * @param int $index - * - * @return Item - */ public function getItem(int $index) : Item; /** * Puts an Item in a slot. - * - * @param int $index - * @param Item $item - * @param bool $send */ public function setItem(int $index, Item $item, bool $send = true) : void; @@ -77,10 +59,6 @@ interface Inventory{ /** * Checks if a given Item can be added to the inventory - * - * @param Item $item - * - * @return bool */ public function canAddItem(Item $item) : bool; @@ -95,25 +73,18 @@ interface Inventory{ public function removeItem(Item ...$slots) : array; /** - * @param bool $includeEmpty - * * @return Item[] */ public function getContents(bool $includeEmpty = false) : array; /** * @param Item[] $items - * @param bool $send */ public function setContents(array $items, bool $send = true) : void; /** * Checks if the inventory contains any Item with the same material data. * It will check id, amount, and metadata (if not null) - * - * @param Item $item - * - * @return bool */ public function contains(Item $item) : bool; @@ -121,8 +92,6 @@ interface Inventory{ * Will return all the Items that has the same id and metadata (if not null). * Won't check amount * - * @param Item $item - * * @return Item[] */ public function all(Item $item) : array; @@ -132,57 +101,36 @@ interface Inventory{ * and count >= to the count of the specified item stack. * * If $exact is true, only items with equal ID, damage, NBT and count will match. - * - * @param Item $item - * @param bool $exact - * - * @return int */ public function first(Item $item, bool $exact = false) : int; /** * Returns the first empty slot, or -1 if not found - * - * @return int */ public function firstEmpty() : int; /** * Returns whether the given slot is empty. - * - * @param int $index - * - * @return bool */ public function isSlotEmpty(int $index) : bool; /** * Will remove all the Items that has the same id and metadata (if not null) - * - * @param Item $item */ public function remove(Item $item) : void; /** * Will clear a specific slot - * - * @param int $index - * @param bool $send */ public function clear(int $index, bool $send = true) : void; /** * Clears all the slots - * - * @param bool $send */ public function clearAll(bool $send = true) : void; /** * Swaps the specified slots. - * - * @param int $slot1 - * @param int $slot2 */ public function swap(int $slot1, int $slot2) : void; @@ -196,8 +144,6 @@ interface Inventory{ /** * Called when a player opens this inventory. - * - * @param Player $who */ public function onOpen(Player $who) : void; @@ -205,10 +151,6 @@ interface Inventory{ /** * Returns whether the specified slot exists in the inventory. - * - * @param int $slot - * - * @return bool */ public function slotExists(int $slot) : bool; diff --git a/src/inventory/PlayerInventory.php b/src/inventory/PlayerInventory.php index 493d4d8a93..50d9296730 100644 --- a/src/inventory/PlayerInventory.php +++ b/src/inventory/PlayerInventory.php @@ -35,9 +35,6 @@ class PlayerInventory extends BaseInventory{ /** @var int */ protected $itemInHandIndex = 0; - /** - * @param Human $player - */ public function __construct(Human $player){ $this->holder = $player; parent::__construct(36); @@ -48,8 +45,6 @@ class PlayerInventory extends BaseInventory{ } /** - * @param int $slot - * * @throws \InvalidArgumentException */ private function throwIfNotHotbarSlot(int $slot) : void{ @@ -61,10 +56,6 @@ class PlayerInventory extends BaseInventory{ /** * Returns the item in the specified hotbar slot. * - * @param int $hotbarSlot - * - * @return Item - * * @throws \InvalidArgumentException if the hotbar slot index is out of range */ public function getHotbarSlotItem(int $hotbarSlot) : Item{ @@ -74,7 +65,6 @@ class PlayerInventory extends BaseInventory{ /** * Returns the hotbar slot number the holder is currently holding. - * @return int */ public function getHeldItemIndex() : int{ return $this->itemInHandIndex; @@ -104,8 +94,6 @@ class PlayerInventory extends BaseInventory{ /** * Returns the currently-held item. - * - * @return Item */ public function getItemInHand() : Item{ return $this->getHotbarSlotItem($this->itemInHandIndex); @@ -113,8 +101,6 @@ class PlayerInventory extends BaseInventory{ /** * Sets the item in the currently-held slot to the specified item. - * - * @param Item $item */ public function setItemInHand(Item $item) : void{ $this->setItem($this->getHeldItemIndex(), $item); @@ -125,7 +111,6 @@ class PlayerInventory extends BaseInventory{ /** * Returns the number of slots in the hotbar. - * @return int */ public function getHotbarSize() : int{ return 9; diff --git a/src/inventory/transaction/CraftingTransaction.php b/src/inventory/transaction/CraftingTransaction.php index 5a19fcd618..da7178ee94 100644 --- a/src/inventory/transaction/CraftingTransaction.php +++ b/src/inventory/transaction/CraftingTransaction.php @@ -61,10 +61,7 @@ class CraftingTransaction extends InventoryTransaction{ /** * @param Item[] $txItems * @param Item[] $recipeItems - * @param bool $wildcards - * @param int $iterations * - * @return int * @throws TransactionValidationException */ protected function matchRecipeItems(array $txItems, array $recipeItems, bool $wildcards, int $iterations = 0) : int{ diff --git a/src/inventory/transaction/InventoryTransaction.php b/src/inventory/transaction/InventoryTransaction.php index 31bb9dc9ed..43b247261d 100644 --- a/src/inventory/transaction/InventoryTransaction.php +++ b/src/inventory/transaction/InventoryTransaction.php @@ -66,7 +66,6 @@ class InventoryTransaction{ protected $actions = []; /** - * @param Player $source * @param InventoryAction[] $actions */ public function __construct(Player $source, array $actions = []){ @@ -76,9 +75,6 @@ class InventoryTransaction{ } } - /** - * @return Player - */ public function getSource() : Player{ return $this->source; } @@ -102,9 +98,6 @@ class InventoryTransaction{ return $this->actions; } - /** - * @param InventoryAction $action - */ public function addAction(InventoryAction $action) : void{ if(!isset($this->actions[$hash = spl_object_id($action)])){ $this->actions[$hash] = $action; @@ -130,8 +123,6 @@ class InventoryTransaction{ /** * @internal This method should not be used by plugins, it's used to add tracked inventories for InventoryActions * involving inventories. - * - * @param Inventory $inventory */ public function addInventory(Inventory $inventory) : void{ if(!isset($this->inventories[$hash = spl_object_id($inventory)])){ @@ -233,10 +224,7 @@ class InventoryTransaction{ } /** - * @param Item $needOrigin * @param SlotChangeAction[] $possibleActions - * - * @return null|Item */ protected function findResultItem(Item $needOrigin, array $possibleActions) : ?Item{ assert(count($possibleActions) > 0); @@ -295,7 +283,6 @@ class InventoryTransaction{ /** * Executes the group of actions, returning whether the transaction executed successfully or not. - * @return bool * * @throws TransactionValidationException */ @@ -330,9 +317,6 @@ class InventoryTransaction{ return true; } - /** - * @return bool - */ public function hasExecuted() : bool{ return $this->hasExecuted; } diff --git a/src/inventory/transaction/action/DropItemAction.php b/src/inventory/transaction/action/DropItemAction.php index 6c8db64a0e..a15e3fdd05 100644 --- a/src/inventory/transaction/action/DropItemAction.php +++ b/src/inventory/transaction/action/DropItemAction.php @@ -53,8 +53,6 @@ class DropItemAction extends InventoryAction{ /** * Drops the target item in front of the player. - * - * @param Player $source */ public function execute(Player $source) : void{ $source->dropItem($this->targetItem); diff --git a/src/inventory/transaction/action/InventoryAction.php b/src/inventory/transaction/action/InventoryAction.php index e5b9c2dad1..5b1e8db5db 100644 --- a/src/inventory/transaction/action/InventoryAction.php +++ b/src/inventory/transaction/action/InventoryAction.php @@ -43,7 +43,6 @@ abstract class InventoryAction{ /** * Returns the item that was present before the action took place. - * @return Item */ public function getSourceItem() : Item{ return clone $this->sourceItem; @@ -51,7 +50,6 @@ abstract class InventoryAction{ /** * Returns the item that the action attempted to replace the source item with. - * @return Item */ public function getTargetItem() : Item{ return clone $this->targetItem; @@ -59,17 +57,11 @@ abstract class InventoryAction{ /** * Returns whether this action is currently valid. This should perform any necessary sanity checks. - * - * @param Player $source - * - * @return bool */ abstract public function isValid(Player $source) : bool; /** * Called when the action is added to the specified InventoryTransaction. - * - * @param InventoryTransaction $transaction */ public function onAddToTransaction(InventoryTransaction $transaction) : void{ @@ -78,10 +70,6 @@ abstract class InventoryAction{ /** * Called by inventory transactions before any actions are processed. If this returns false, the transaction will * be cancelled. - * - * @param Player $source - * - * @return bool */ public function onPreExecute(Player $source) : bool{ return true; @@ -90,8 +78,6 @@ abstract class InventoryAction{ /** * Performs actions needed to complete the inventory-action server-side. This will only be called if the transaction * which it is part of is considered valid. - * - * @param Player $source */ abstract public function execute(Player $source) : void; } diff --git a/src/inventory/transaction/action/SlotChangeAction.php b/src/inventory/transaction/action/SlotChangeAction.php index e1145022f8..fe2b6d9b08 100644 --- a/src/inventory/transaction/action/SlotChangeAction.php +++ b/src/inventory/transaction/action/SlotChangeAction.php @@ -38,12 +38,6 @@ class SlotChangeAction extends InventoryAction{ /** @var int */ private $inventorySlot; - /** - * @param Inventory $inventory - * @param int $inventorySlot - * @param Item $sourceItem - * @param Item $targetItem - */ public function __construct(Inventory $inventory, int $inventorySlot, Item $sourceItem, Item $targetItem){ parent::__construct($sourceItem, $targetItem); $this->inventory = $inventory; @@ -52,8 +46,6 @@ class SlotChangeAction extends InventoryAction{ /** * Returns the inventory involved in this action. - * - * @return Inventory */ public function getInventory() : Inventory{ return $this->inventory; @@ -61,7 +53,6 @@ class SlotChangeAction extends InventoryAction{ /** * Returns the slot in the inventory which this action modified. - * @return int */ public function getSlot() : int{ return $this->inventorySlot; @@ -69,10 +60,6 @@ class SlotChangeAction extends InventoryAction{ /** * Checks if the item in the inventory at the specified slot is the same as this action's source item. - * - * @param Player $source - * - * @return bool */ public function isValid(Player $source) : bool{ return ( @@ -83,9 +70,6 @@ class SlotChangeAction extends InventoryAction{ /** * Adds this action's target inventory to the transaction's inventory list. - * - * @param InventoryTransaction $transaction - * */ public function onAddToTransaction(InventoryTransaction $transaction) : void{ $transaction->addInventory($this->inventory); @@ -93,8 +77,6 @@ class SlotChangeAction extends InventoryAction{ /** * Sets the item into the target inventory. - * - * @param Player $source */ public function execute(Player $source) : void{ $this->inventory->setItem($this->inventorySlot, $this->targetItem, false); diff --git a/src/item/Armor.php b/src/item/Armor.php index d2b5759ea1..3b64f6b084 100644 --- a/src/item/Armor.php +++ b/src/item/Armor.php @@ -63,7 +63,6 @@ class Armor extends Durable{ /** * @see ArmorInventory - * @return int */ public function getArmorSlot() : int{ return $this->armorInfo->getArmorSlot(); @@ -75,7 +74,6 @@ class Armor extends Durable{ /** * Returns the dyed colour of this armour piece. This generally only applies to leather armour. - * @return Color|null */ public function getCustomColor() : ?Color{ return $this->customColor; @@ -84,8 +82,6 @@ class Armor extends Durable{ /** * Sets the dyed colour of this armour piece. This generally only applies to leather armour. * - * @param Color $color - * * @return $this */ public function setCustomColor(Color $color) : self{ @@ -96,10 +92,6 @@ class Armor extends Durable{ /** * Returns the total enchantment protection factor this armour piece offers from all applicable protection * enchantments on the item. - * - * @param EntityDamageEvent $event - * - * @return int */ public function getEnchantmentProtectionFactor(EntityDamageEvent $event) : int{ $epf = 0; diff --git a/src/item/ArmorTypeInfo.php b/src/item/ArmorTypeInfo.php index 172a590b86..3542a554e8 100644 --- a/src/item/ArmorTypeInfo.php +++ b/src/item/ArmorTypeInfo.php @@ -38,23 +38,14 @@ class ArmorTypeInfo{ $this->armorSlot = $armorSlot; } - /** - * @return int - */ public function getDefensePoints() : int{ return $this->defensePoints; } - /** - * @return int - */ public function getMaxDurability() : int{ return $this->maxDurability; } - /** - * @return int - */ public function getArmorSlot() : int{ return $this->armorSlot; } diff --git a/src/item/Banner.php b/src/item/Banner.php index 7b0950c644..db566f7de5 100644 --- a/src/item/Banner.php +++ b/src/item/Banner.php @@ -53,9 +53,6 @@ class Banner extends Item{ $this->patterns = new Deque(); } - /** - * @return DyeColor - */ public function getColor() : DyeColor{ return $this->color; } diff --git a/src/item/Bed.php b/src/item/Bed.php index 9212b80b0f..a061129f98 100644 --- a/src/item/Bed.php +++ b/src/item/Bed.php @@ -37,9 +37,6 @@ class Bed extends Item{ $this->color = $color; } - /** - * @return DyeColor - */ public function getColor() : DyeColor{ return $this->color; } diff --git a/src/item/Boat.php b/src/item/Boat.php index 55a521423c..3f75abd4f8 100644 --- a/src/item/Boat.php +++ b/src/item/Boat.php @@ -34,9 +34,6 @@ class Boat extends Item{ $this->woodType = $woodType; } - /** - * @return TreeType - */ public function getWoodType() : TreeType{ return $this->woodType; } diff --git a/src/item/Consumable.php b/src/item/Consumable.php index b9f0c1c3c4..c4b809adcb 100644 --- a/src/item/Consumable.php +++ b/src/item/Consumable.php @@ -47,8 +47,6 @@ interface Consumable{ /** * Called when this Consumable is consumed by mob, after standard resulting effects have been applied. - * - * @param Living $consumer */ public function onConsume(Living $consumer) : void; } diff --git a/src/item/Durable.php b/src/item/Durable.php index 8462e25b21..a84956d0bf 100644 --- a/src/item/Durable.php +++ b/src/item/Durable.php @@ -41,7 +41,6 @@ abstract class Durable extends Item{ /** * Returns whether this item will take damage when used. - * @return bool */ public function isUnbreakable() : bool{ return $this->unbreakable; @@ -50,8 +49,6 @@ abstract class Durable extends Item{ /** * Sets whether the item will take damage when used. * - * @param bool $value - * * @return $this */ public function setUnbreakable(bool $value = true) : self{ @@ -62,8 +59,6 @@ abstract class Durable extends Item{ /** * Applies damage to the item. * - * @param int $amount - * * @return bool if any damage was applied to the item */ public function applyDamage(int $amount) : bool{ @@ -119,14 +114,11 @@ abstract class Durable extends Item{ /** * Returns the maximum amount of damage this item can take before it breaks. - * - * @return int */ abstract public function getMaxDurability() : int; /** * Returns whether the item is broken. - * @return bool */ public function isBroken() : bool{ return $this->damage >= $this->getMaxDurability(); diff --git a/src/item/Dye.php b/src/item/Dye.php index ba103b5193..0df19d7158 100644 --- a/src/item/Dye.php +++ b/src/item/Dye.php @@ -35,9 +35,6 @@ class Dye extends Item{ $this->color = $color; } - /** - * @return DyeColor - */ public function getColor() : DyeColor{ return $this->color; } diff --git a/src/item/FoodSource.php b/src/item/FoodSource.php index 0e5b553355..ddddb4a943 100644 --- a/src/item/FoodSource.php +++ b/src/item/FoodSource.php @@ -34,7 +34,6 @@ interface FoodSource extends Consumable{ /** * Returns whether a Human eating this FoodSource must have a non-full hunger bar. - * @return bool */ public function requiresHunger() : bool; } diff --git a/src/item/Item.php b/src/item/Item.php index 3b4443c671..0714dc67c5 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -103,10 +103,6 @@ class Item implements \JsonSerializable{ * * NOTE: This should NOT BE USED for creating items to set into an inventory. Use {@link ItemFactory#get} for that * purpose. - * - * @param int $id - * @param int $variant - * @param string $name */ public function __construct(int $id, int $variant = 0, string $name = "Unknown"){ if($id < -0x8000 or $id > 0x7fff){ //signed short range @@ -120,9 +116,6 @@ class Item implements \JsonSerializable{ $this->canDestroy = new Set(); } - /** - * @return bool - */ public function hasCustomBlockData() : bool{ return $this->blockEntityTag !== null; } @@ -136,8 +129,6 @@ class Item implements \JsonSerializable{ } /** - * @param CompoundTag $compound - * * @return $this */ public function setCustomBlockData(CompoundTag $compound) : Item{ @@ -146,30 +137,19 @@ class Item implements \JsonSerializable{ return $this; } - /** - * @return CompoundTag|null - */ public function getCustomBlockData() : ?CompoundTag{ return $this->blockEntityTag; } - /** - * @return bool - */ public function hasCustomName() : bool{ return $this->customName !== ""; } - /** - * @return string - */ public function getCustomName() : string{ return $this->customName; } /** - * @param string $name - * * @return $this */ public function setCustomName(string $name) : Item{ @@ -243,7 +223,6 @@ class Item implements \JsonSerializable{ /** * Returns whether this Item has a non-empty NBT. - * @return bool */ public function hasNamedTag() : bool{ return $this->getNamedTag()->count() > 0; @@ -252,8 +231,6 @@ class Item implements \JsonSerializable{ /** * Returns a tree of Tag objects representing the Item's NBT. If the item does not have any NBT, an empty CompoundTag * object is returned to allow the caller to manipulate and apply back to the item. - * - * @return CompoundTag */ public function getNamedTag() : CompoundTag{ if($this->nbt === null){ @@ -266,8 +243,6 @@ class Item implements \JsonSerializable{ /** * Sets the Item's NBT from the supplied CompoundTag object. * - * @param CompoundTag $tag - * * @return $this */ public function setNamedTag(CompoundTag $tag) : Item{ @@ -401,16 +376,11 @@ class Item implements \JsonSerializable{ } } - /** - * @return int - */ public function getCount() : int{ return $this->count; } /** - * @param int $count - * * @return $this */ public function setCount(int $count) : Item{ @@ -422,8 +392,6 @@ class Item implements \JsonSerializable{ /** * Pops an item from the stack and returns it, decreasing the stack count of this item stack by one. * - * @param int $count - * * @return $this * @throws \InvalidArgumentException if trying to pop more items than are on the stack */ @@ -446,7 +414,6 @@ class Item implements \JsonSerializable{ /** * Returns the name of the item, or the custom name if it is set. - * @return string */ final public function getName() : string{ return $this->hasCustomName() ? $this->getCustomName() : $this->getVanillaName(); @@ -454,37 +421,26 @@ class Item implements \JsonSerializable{ /** * Returns the vanilla name of the item, disregarding custom names. - * @return string */ public function getVanillaName() : string{ return $this->name; } - /** - * @return bool - */ final public function canBePlaced() : bool{ return $this->getBlock()->canBePlaced(); } /** * Returns the block corresponding to this Item. - * @return Block */ public function getBlock() : Block{ return VanillaBlocks::AIR(); } - /** - * @return int - */ final public function getId() : int{ return $this->id; } - /** - * @return int - */ public function getMeta() : int{ return $this->meta; } @@ -492,8 +448,6 @@ class Item implements \JsonSerializable{ /** * Returns whether this item can match any item with an equivalent ID with any meta value. * Used in crafting recipes which accept multiple variants of the same item, for example crafting tables recipes. - * - * @return bool */ public function hasAnyDamageValue() : bool{ return $this->meta === -1; @@ -501,7 +455,6 @@ class Item implements \JsonSerializable{ /** * Returns the highest amount of this item which will fit into one inventory slot. - * @return int */ public function getMaxStackSize() : int{ return 64; @@ -509,7 +462,6 @@ class Item implements \JsonSerializable{ /** * Returns the time in ticks which the item will fuel a furnace for. - * @return int */ public function getFuelTime() : int{ return 0; @@ -517,7 +469,6 @@ class Item implements \JsonSerializable{ /** * Returns how many points of damage this item will deal to an entity when used as a weapon. - * @return int */ public function getAttackPoints() : int{ return 1; @@ -525,7 +476,6 @@ class Item implements \JsonSerializable{ /** * Returns how many armor points can be gained by wearing this item. - * @return int */ public function getDefensePoints() : int{ return 0; @@ -534,8 +484,6 @@ class Item implements \JsonSerializable{ /** * Returns what type of block-breaking tool this is. Blocks requiring the same tool type as the item will break * faster (except for blocks requiring no tool, which break at the same speed regardless of the tool used) - * - * @return int */ public function getBlockToolType() : int{ return BlockToolType::NONE; @@ -547,8 +495,6 @@ class Item implements \JsonSerializable{ * This should return 1 for non-tiered tools, and the tool tier for tiered tools. * * @see BlockBreakInfo::getToolHarvestLevel() - * - * @return int */ public function getBlockToolHarvestLevel() : int{ return 0; @@ -560,14 +506,6 @@ class Item implements \JsonSerializable{ /** * Called when a player uses this item on a block. - * - * @param Player $player - * @param Block $blockReplace - * @param Block $blockClicked - * @param int $face - * @param Vector3 $clickVector - * - * @return ItemUseResult */ public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ return ItemUseResult::NONE(); @@ -576,11 +514,6 @@ class Item implements \JsonSerializable{ /** * Called when a player uses the item on air, for example throwing a projectile. * Returns whether the item was changed, for example count decrease or durability change. - * - * @param Player $player - * @param Vector3 $directionVector - * - * @return ItemUseResult */ public function onClickAir(Player $player, Vector3 $directionVector) : ItemUseResult{ return ItemUseResult::NONE(); @@ -589,10 +522,6 @@ class Item implements \JsonSerializable{ /** * Called when a player is using this item and releases it. Used to handle bow shoot actions. * Returns whether the item was changed, for example count decrease or durability change. - * - * @param Player $player - * - * @return ItemUseResult */ public function onReleaseUsing(Player $player) : ItemUseResult{ return ItemUseResult::NONE(); @@ -600,10 +529,6 @@ class Item implements \JsonSerializable{ /** * Called when this item is used to destroy a block. Usually used to update durability. - * - * @param Block $block - * - * @return bool */ public function onDestroyBlock(Block $block) : bool{ return false; @@ -611,10 +536,6 @@ class Item implements \JsonSerializable{ /** * Called when this item is used to attack an entity. Usually used to update durability. - * - * @param Entity $victim - * - * @return bool */ public function onAttackEntity(Entity $victim) : bool{ return false; @@ -622,8 +543,6 @@ class Item implements \JsonSerializable{ /** * Returns the number of ticks a player must wait before activating this item again. - * - * @return int */ public function getCooldownTicks() : int{ return 0; @@ -632,11 +551,8 @@ class Item implements \JsonSerializable{ /** * Compares an Item to this Item and check if they match. * - * @param Item $item * @param bool $checkDamage Whether to verify that the damage values match. * @param bool $checkCompound Whether to verify that the items' NBT match. - * - * @return bool */ final public function equals(Item $item, bool $checkDamage = true, bool $checkCompound = true) : bool{ return $this->id === $item->getId() and @@ -646,26 +562,17 @@ class Item implements \JsonSerializable{ /** * Returns whether the specified item stack has the same ID, damage, NBT and count as this item stack. - * - * @param Item $other - * - * @return bool */ final public function equalsExact(Item $other) : bool{ return $this->equals($other, true, true) and $this->count === $other->count; } - /** - * @return string - */ final public function __toString() : string{ return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->getMeta()) . ")x" . $this->count . ($this->hasNamedTag() ? " tags:0x" . base64_encode((new LittleEndianNbtSerializer())->write(new TreeRoot($this->getNamedTag()))) : ""); } /** * Returns an array of item stack properties that can be serialized to json. - * - * @return array */ final public function jsonSerialize() : array{ $data = [ @@ -690,9 +597,6 @@ class Item implements \JsonSerializable{ /** * Returns an Item from properties created in an array by {@link Item#jsonSerialize} * - * @param array $data - * - * @return Item * @throws NbtDataException * @throws \InvalidArgumentException */ @@ -716,8 +620,6 @@ class Item implements \JsonSerializable{ * Serializes the item to an NBT CompoundTag * * @param int $slot optional, the inventory slot of the item - * - * @return CompoundTag */ public function nbtSerialize(int $slot = -1) : CompoundTag{ $result = CompoundTag::create() @@ -738,10 +640,6 @@ class Item implements \JsonSerializable{ /** * Deserializes an Item from an NBT CompoundTag - * - * @param CompoundTag $tag - * - * @return Item */ public static function nbtDeserialize(CompoundTag $tag) : Item{ if(!$tag->hasTag("id") or !$tag->hasTag("Count")){ diff --git a/src/item/ItemBlock.php b/src/item/ItemBlock.php index e88576026b..ca67e2a992 100644 --- a/src/item/ItemBlock.php +++ b/src/item/ItemBlock.php @@ -34,9 +34,7 @@ class ItemBlock extends Item{ protected $blockId; /** - * @param int $blockId * @param int $meta usually 0-15 (placed blocks may only have meta values 0-15) - * @param int|null $itemId */ public function __construct(int $blockId, int $meta = 0, ?int $itemId = null){ if($blockId < 0){ //extended blocks diff --git a/src/item/ItemEnchantmentHandlingTrait.php b/src/item/ItemEnchantmentHandlingTrait.php index 20fdb83727..23ca86b032 100644 --- a/src/item/ItemEnchantmentHandlingTrait.php +++ b/src/item/ItemEnchantmentHandlingTrait.php @@ -35,37 +35,20 @@ trait ItemEnchantmentHandlingTrait{ /** @var EnchantmentInstance[] */ protected $enchantments = []; - /** - * @return bool - */ public function hasEnchantments() : bool{ return !empty($this->enchantments); } - /** - * @param Enchantment $enchantment - * @param int $level - * - * @return bool - */ public function hasEnchantment(Enchantment $enchantment, int $level = -1) : bool{ $id = $enchantment->getId(); return isset($this->enchantments[$id]) and ($level === -1 or $this->enchantments[$id]->getLevel() === $level); } - /** - * @param Enchantment $enchantment - * - * @return EnchantmentInstance|null - */ public function getEnchantment(Enchantment $enchantment) : ?EnchantmentInstance{ return $this->enchantments[$enchantment->getId()] ?? null; } /** - * @param Enchantment $enchantment - * @param int $level - * * @return $this */ public function removeEnchantment(Enchantment $enchantment, int $level = -1) : self{ @@ -86,8 +69,6 @@ trait ItemEnchantmentHandlingTrait{ } /** - * @param EnchantmentInstance $enchantment - * * @return $this */ public function addEnchantment(EnchantmentInstance $enchantment) : self{ @@ -105,10 +86,6 @@ trait ItemEnchantmentHandlingTrait{ /** * Returns the level of the enchantment on this item with the specified ID, or 0 if the item does not have the * enchantment. - * - * @param Enchantment $enchantment - * - * @return int */ public function getEnchantmentLevel(Enchantment $enchantment) : int{ return ($instance = $this->getEnchantment($enchantment)) !== null ? $instance->getLevel() : 0; diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index eb64616c45..a526114ba6 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -381,9 +381,6 @@ class ItemFactory{ * NOTE: If you are registering a new item type, you will need to add it to the creative inventory yourself - it * will not automatically appear there. * - * @param Item $item - * @param bool $override - * * @throws \RuntimeException if something attempted to override an already-registered item without specifying the * $override parameter. */ @@ -401,12 +398,6 @@ class ItemFactory{ /** * Returns an instance of the Item with the specified id, meta, count and NBT. * - * @param int $id - * @param int $meta - * @param int $count - * @param CompoundTag|null $tags - * - * @return Item * @throws \InvalidArgumentException */ public static function get(int $id, int $meta = 0, int $count = 1, ?CompoundTag $tags = null) : Item{ @@ -444,10 +435,6 @@ class ItemFactory{ * - `minecraft:string` * - `351:4 (lapis lazuli ID:meta)` * - * @param string $str - * - * @return Item - * * @throws \InvalidArgumentException if the given string cannot be parsed as an item identifier */ public static function fromString(string $str) : Item{ @@ -477,11 +464,6 @@ class ItemFactory{ /** * Returns whether the specified item ID is already registered in the item factory. - * - * @param int $id - * @param int $variant - * - * @return bool */ public static function isRegistered(int $id, int $variant = 0) : bool{ if($id < 256){ diff --git a/src/item/LiquidBucket.php b/src/item/LiquidBucket.php index 69e3e0ef39..ec759b2910 100644 --- a/src/item/LiquidBucket.php +++ b/src/item/LiquidBucket.php @@ -75,9 +75,6 @@ class LiquidBucket extends Item{ return ItemUseResult::FAIL(); } - /** - * @return Liquid - */ public function getLiquid() : Liquid{ return $this->liquid; } diff --git a/src/item/Potion.php b/src/item/Potion.php index 619882a569..54806da720 100644 --- a/src/item/Potion.php +++ b/src/item/Potion.php @@ -110,8 +110,6 @@ class Potion extends Item implements Consumable{ /** * Returns a list of effects applied by potions with the specified ID. * - * @param int $id - * * @return EffectInstance[] */ public static function getPotionEffectsById(int $id) : array{ diff --git a/src/item/ProjectileItem.php b/src/item/ProjectileItem.php index cd3461bd19..cbae038b38 100644 --- a/src/item/ProjectileItem.php +++ b/src/item/ProjectileItem.php @@ -45,8 +45,6 @@ abstract class ProjectileItem extends Item{ /** * Helper function to apply extra NBT tags to pass to the created projectile. - * - * @param CompoundTag $tag */ protected function addExtraTags(CompoundTag $tag) : void{ diff --git a/src/item/SpawnEgg.php b/src/item/SpawnEgg.php index ac3fd5b3ee..b9aa36165c 100644 --- a/src/item/SpawnEgg.php +++ b/src/item/SpawnEgg.php @@ -37,10 +37,6 @@ class SpawnEgg extends Item{ private $entityClass; /** - * @param int $id - * @param int $variant - * @param string $name - * * @param string $entityClass instanceof Entity * * @throws \InvalidArgumentException diff --git a/src/item/ToolTier.php b/src/item/ToolTier.php index 129da6bb22..f15ba7c3aa 100644 --- a/src/item/ToolTier.php +++ b/src/item/ToolTier.php @@ -69,30 +69,18 @@ final class ToolTier{ $this->baseEfficiency = $baseEfficiency; } - /** - * @return int - */ public function getHarvestLevel() : int{ return $this->harvestLevel; } - /** - * @return int - */ public function getMaxDurability() : int{ return $this->maxDurability; } - /** - * @return int - */ public function getBaseAttackPoints() : int{ return $this->baseAttackPoints; } - /** - * @return int - */ public function getBaseEfficiency() : int{ return $this->baseEfficiency; } diff --git a/src/item/VanillaItems.php b/src/item/VanillaItems.php index c0f8f15831..c5ee5cce2c 100644 --- a/src/item/VanillaItems.php +++ b/src/item/VanillaItems.php @@ -302,11 +302,6 @@ final class VanillaItems{ self::_registryRegister($name, $item); } - /** - * @param string $name - * - * @return Item - */ public static function fromString(string $name) : Item{ $result = self::_registryFromString($name); assert($result instanceof Item); diff --git a/src/item/WritableBookBase.php b/src/item/WritableBookBase.php index b822ab0325..75e997bf90 100644 --- a/src/item/WritableBookBase.php +++ b/src/item/WritableBookBase.php @@ -47,10 +47,6 @@ abstract class WritableBookBase extends Item{ /** * Returns whether the given page exists in this book. - * - * @param int $pageId - * - * @return bool */ public function pageExists(int $pageId) : bool{ return isset($this->pages[$pageId]); @@ -59,9 +55,6 @@ abstract class WritableBookBase extends Item{ /** * Returns a string containing the content of a page (which could be empty), or null if the page doesn't exist. * - * @param int $pageId - * - * @return string * @throws \OutOfRangeException if requesting a nonexisting page */ public function getPageText(int $pageId) : string{ @@ -71,9 +64,6 @@ abstract class WritableBookBase extends Item{ /** * Sets the text of a page in the book. Adds the page if the page does not yet exist. * - * @param int $pageId - * @param string $pageText - * * @return $this */ public function setPageText(int $pageId, string $pageText) : self{ @@ -89,8 +79,6 @@ abstract class WritableBookBase extends Item{ * Adds a new page with the given page ID. * Creates a new page for every page between the given ID and existing pages that doesn't yet exist. * - * @param int $pageId - * * @return $this */ public function addPage(int $pageId) : self{ @@ -107,8 +95,6 @@ abstract class WritableBookBase extends Item{ /** * Deletes an existing page with the given page ID. * - * @param int $pageId - * * @return $this */ public function deletePage(int $pageId) : self{ @@ -119,9 +105,6 @@ abstract class WritableBookBase extends Item{ /** * Inserts a new page with the given text and moves other pages upwards. * - * @param int $pageId - * @param string $pageText - * * @return $this */ public function insertPage(int $pageId, string $pageText = "") : self{ @@ -132,9 +115,6 @@ abstract class WritableBookBase extends Item{ /** * Switches the text of two pages with each other. * - * @param int $pageId1 - * @param int $pageId2 - * * @return bool indicating success * @throws \OutOfRangeException if either of the pages does not exist */ diff --git a/src/item/WritableBookPage.php b/src/item/WritableBookPage.php index 20ce682cba..62ebbcf50c 100644 --- a/src/item/WritableBookPage.php +++ b/src/item/WritableBookPage.php @@ -39,16 +39,10 @@ class WritableBookPage{ $this->photoName = $photoName; } - /** - * @return string - */ public function getText() : string{ return $this->text; } - /** - * @return string - */ public function getPhotoName() : string{ return $this->photoName; } diff --git a/src/item/WrittenBook.php b/src/item/WrittenBook.php index e0d5c0fad2..f356b1cd64 100644 --- a/src/item/WrittenBook.php +++ b/src/item/WrittenBook.php @@ -51,8 +51,6 @@ class WrittenBook extends WritableBookBase{ /** * Returns the generation of the book. * Generations higher than 1 can not be copied. - * - * @return int */ public function getGeneration() : int{ return $this->generation; @@ -61,8 +59,6 @@ class WrittenBook extends WritableBookBase{ /** * Sets the generation of a book. * - * @param int $generation - * * @return $this */ public function setGeneration(int $generation) : self{ @@ -78,8 +74,6 @@ class WrittenBook extends WritableBookBase{ * Returns the author of this book. * This is not a reliable way to get the name of the player who signed this book. * The author can be set to anything when signing a book. - * - * @return string */ public function getAuthor() : string{ return $this->author; @@ -88,8 +82,6 @@ class WrittenBook extends WritableBookBase{ /** * Sets the author of this book. * - * @param string $authorName - * * @return $this */ public function setAuthor(string $authorName) : self{ @@ -100,8 +92,6 @@ class WrittenBook extends WritableBookBase{ /** * Returns the title of this book. - * - * @return string */ public function getTitle() : string{ return $this->title; @@ -110,8 +100,6 @@ class WrittenBook extends WritableBookBase{ /** * Sets the author of this book. * - * @param string $title - * * @return $this */ public function setTitle(string $title) : self{ diff --git a/src/item/enchantment/Enchantment.php b/src/item/enchantment/Enchantment.php index e737c962ab..d93c475de3 100644 --- a/src/item/enchantment/Enchantment.php +++ b/src/item/enchantment/Enchantment.php @@ -220,27 +220,15 @@ class Enchantment{ /** * Registers an enchantment type. - * - * @param Enchantment $enchantment */ public static function register(Enchantment $enchantment) : void{ self::$enchantments[$enchantment->getId()] = clone $enchantment; } - /** - * @param int $id - * - * @return Enchantment|null - */ public static function get(int $id) : ?Enchantment{ return self::$enchantments[$id] ?? null; } - /** - * @param string $name - * - * @return Enchantment|null - */ public static function fromString(string $name) : ?Enchantment{ $const = Enchantment::class . "::" . strtoupper($name); if(defined($const)){ @@ -262,14 +250,6 @@ class Enchantment{ /** @var int */ private $maxLevel; - /** - * @param int $id - * @param string $name - * @param int $rarity - * @param int $primaryItemFlags - * @param int $secondaryItemFlags - * @param int $maxLevel - */ public function __construct(int $id, string $name, int $rarity, int $primaryItemFlags, int $secondaryItemFlags, int $maxLevel){ $this->id = $id; $this->name = $name; @@ -281,7 +261,6 @@ class Enchantment{ /** * Returns the ID of this enchantment as per Minecraft PE - * @return int */ public function getId() : int{ return $this->id; @@ -289,7 +268,6 @@ class Enchantment{ /** * Returns a translation key for this enchantment's name. - * @return string */ public function getName() : string{ return $this->name; @@ -297,7 +275,6 @@ class Enchantment{ /** * Returns an int constant indicating how rare this enchantment type is. - * @return int */ public function getRarity() : int{ return $this->rarity; @@ -305,8 +282,6 @@ class Enchantment{ /** * Returns a bitset indicating what item types can have this item applied from an enchanting table. - * - * @return int */ public function getPrimaryItemFlags() : int{ return $this->primaryItemFlags; @@ -315,8 +290,6 @@ class Enchantment{ /** * Returns a bitset indicating what item types cannot have this item applied from an enchanting table, but can from * an anvil. - * - * @return int */ public function getSecondaryItemFlags() : int{ return $this->secondaryItemFlags; @@ -324,10 +297,6 @@ class Enchantment{ /** * Returns whether this enchantment can apply to the item type from an enchanting table. - * - * @param int $flag - * - * @return bool */ public function hasPrimaryItemType(int $flag) : bool{ return ($this->primaryItemFlags & $flag) !== 0; @@ -335,10 +304,6 @@ class Enchantment{ /** * Returns whether this enchantment can apply to the item type from an anvil, if it is not a primary item. - * - * @param int $flag - * - * @return bool */ public function hasSecondaryItemType(int $flag) : bool{ return ($this->secondaryItemFlags & $flag) !== 0; @@ -346,7 +311,6 @@ class Enchantment{ /** * Returns the maximum level of this enchantment that can be found on an enchantment table. - * @return int */ public function getMaxLevel() : int{ return $this->maxLevel; diff --git a/src/item/enchantment/EnchantmentEntry.php b/src/item/enchantment/EnchantmentEntry.php index edd2dffb88..287305aec1 100644 --- a/src/item/enchantment/EnchantmentEntry.php +++ b/src/item/enchantment/EnchantmentEntry.php @@ -35,8 +35,6 @@ class EnchantmentEntry{ /** * @param Enchantment[] $enchantments - * @param int $cost - * @param string $randomName */ public function __construct(array $enchantments, int $cost, string $randomName){ $this->enchantments = $enchantments; diff --git a/src/item/enchantment/EnchantmentInstance.php b/src/item/enchantment/EnchantmentInstance.php index 4dadc77c13..f25c05d75a 100644 --- a/src/item/enchantment/EnchantmentInstance.php +++ b/src/item/enchantment/EnchantmentInstance.php @@ -47,7 +47,6 @@ final class EnchantmentInstance{ /** * Returns the type of this enchantment. - * @return Enchantment */ public function getType() : Enchantment{ return $this->enchantment; @@ -55,7 +54,6 @@ final class EnchantmentInstance{ /** * Returns the type identifier of this enchantment instance. - * @return int */ public function getId() : int{ return $this->enchantment->getId(); @@ -63,7 +61,6 @@ final class EnchantmentInstance{ /** * Returns the level of the enchantment. - * @return int */ public function getLevel() : int{ return $this->level; diff --git a/src/item/enchantment/EnchantmentList.php b/src/item/enchantment/EnchantmentList.php index ebec0a3f45..90914e0903 100644 --- a/src/item/enchantment/EnchantmentList.php +++ b/src/item/enchantment/EnchantmentList.php @@ -33,19 +33,10 @@ class EnchantmentList{ $this->enchantments = new \SplFixedArray($size); } - /** - * @param int $slot - * @param EnchantmentEntry $entry - */ public function setSlot(int $slot, EnchantmentEntry $entry) : void{ $this->enchantments[$slot] = $entry; } - /** - * @param int $slot - * - * @return EnchantmentEntry - */ public function getSlot(int $slot) : EnchantmentEntry{ return $this->enchantments[$slot]; } diff --git a/src/item/enchantment/MeleeWeaponEnchantment.php b/src/item/enchantment/MeleeWeaponEnchantment.php index 6d2c8a6317..9b61b16640 100644 --- a/src/item/enchantment/MeleeWeaponEnchantment.php +++ b/src/item/enchantment/MeleeWeaponEnchantment.php @@ -34,28 +34,16 @@ abstract class MeleeWeaponEnchantment extends Enchantment{ /** * Returns whether this melee enchantment has an effect on the target entity. For example, Smite only applies to * undead mobs. - * - * @param Entity $victim - * - * @return bool */ abstract public function isApplicableTo(Entity $victim) : bool; /** * Returns the amount of additional damage caused by this enchantment to applicable targets. - * - * @param int $enchantmentLevel - * - * @return float */ abstract public function getDamageBonus(int $enchantmentLevel) : float; /** * Called after damaging the entity to apply any post damage effects to the target. - * - * @param Entity $attacker - * @param Entity $victim - * @param int $enchantmentLevel */ public function onPostAttack(Entity $attacker, Entity $victim, int $enchantmentLevel) : void{ diff --git a/src/item/enchantment/ProtectionEnchantment.php b/src/item/enchantment/ProtectionEnchantment.php index 9793f795ca..8fc603aa97 100644 --- a/src/item/enchantment/ProtectionEnchantment.php +++ b/src/item/enchantment/ProtectionEnchantment.php @@ -36,13 +36,6 @@ class ProtectionEnchantment extends Enchantment{ /** * ProtectionEnchantment constructor. * - * @param int $id - * @param string $name - * @param int $rarity - * @param int $primaryItemFlags - * @param int $secondaryItemFlags - * @param int $maxLevel - * @param float $typeModifier * @param int[]|null $applicableDamageTypes EntityDamageEvent::CAUSE_* constants which this enchantment type applies to, or null if it applies to all types of damage. */ public function __construct(int $id, string $name, int $rarity, int $primaryItemFlags, int $secondaryItemFlags, int $maxLevel, float $typeModifier, ?array $applicableDamageTypes){ @@ -56,7 +49,6 @@ class ProtectionEnchantment extends Enchantment{ /** * Returns the multiplier by which this enchantment type's EPF increases with each enchantment level. - * @return float */ public function getTypeModifier() : float{ return $this->typeModifier; @@ -64,10 +56,6 @@ class ProtectionEnchantment extends Enchantment{ /** * Returns the base EPF this enchantment type offers for the given enchantment level. - * - * @param int $level - * - * @return int */ public function getProtectionFactor(int $level) : int{ return (int) floor((6 + $level ** 2) * $this->typeModifier / 3); @@ -75,10 +63,6 @@ class ProtectionEnchantment extends Enchantment{ /** * Returns whether this enchantment type offers protection from the specified damage source's cause. - * - * @param EntityDamageEvent $event - * - * @return bool */ public function isApplicable(EntityDamageEvent $event) : bool{ return $this->applicableDamageTypes === null or isset($this->applicableDamageTypes[$event->getCause()]); diff --git a/src/lang/Language.php b/src/lang/Language.php index 4e8d7ff8b7..e0de9dd00d 100644 --- a/src/lang/Language.php +++ b/src/lang/Language.php @@ -44,9 +44,6 @@ class Language{ public const FALLBACK_LANGUAGE = "eng"; /** - * @param string $path - * - * @return array * @throws LanguageNotFoundException */ public static function getLanguageList(string $path = "") : array{ @@ -88,10 +85,6 @@ class Language{ protected $fallbackLang = []; /** - * @param string $lang - * @param string|null $path - * @param string $fallback - * * @throws LanguageNotFoundException */ public function __construct(string $lang, ?string $path = null, string $fallback = self::FALLBACK_LANGUAGE){ @@ -123,11 +116,7 @@ class Language{ } /** - * @param string $str * @param (float|int|string)[] $params - * @param string|null $onlyPrefix - * - * @return string */ public function translateString(string $str, array $params = [], ?string $onlyPrefix = null) : string{ $baseText = $this->get($str); @@ -155,30 +144,14 @@ class Language{ return $baseText; } - /** - * @param string $id - * - * @return string|null - */ protected function internalGet(string $id) : ?string{ return $this->lang[$id] ?? $this->fallbackLang[$id] ?? null; } - /** - * @param string $id - * - * @return string - */ public function get(string $id) : string{ return $this->internalGet($id) ?? $id; } - /** - * @param string $text - * @param string|null $onlyPrefix - * - * @return string - */ protected function parseTranslation(string $text, ?string $onlyPrefix = null) : string{ $newString = ""; diff --git a/src/lang/TextContainer.php b/src/lang/TextContainer.php index 557fa2f5ed..e2265bc82c 100644 --- a/src/lang/TextContainer.php +++ b/src/lang/TextContainer.php @@ -28,30 +28,18 @@ class TextContainer{ /** @var string $text */ protected $text; - /** - * @param string $text - */ public function __construct(string $text){ $this->text = $text; } - /** - * @param string $text - */ public function setText(string $text) : void{ $this->text = $text; } - /** - * @return string - */ public function getText() : string{ return $this->text; } - /** - * @return string - */ public function __toString() : string{ return $this->getText(); } diff --git a/src/lang/TranslationContainer.php b/src/lang/TranslationContainer.php index 7091d6d85d..ccbb7f1b88 100644 --- a/src/lang/TranslationContainer.php +++ b/src/lang/TranslationContainer.php @@ -29,7 +29,6 @@ class TranslationContainer extends TextContainer{ protected $params = []; /** - * @param string $text * @param (float|int|string)[] $params */ public function __construct(string $text, array $params = []){ @@ -50,11 +49,6 @@ class TranslationContainer extends TextContainer{ return $this->params; } - /** - * @param int $i - * - * @return string|null - */ public function getParameter(int $i) : ?string{ return $this->params[$i] ?? null; } diff --git a/src/network/AdvancedNetworkInterface.php b/src/network/AdvancedNetworkInterface.php index 42c1ef62d5..db18361b31 100644 --- a/src/network/AdvancedNetworkInterface.php +++ b/src/network/AdvancedNetworkInterface.php @@ -35,37 +35,25 @@ interface AdvancedNetworkInterface extends NetworkInterface{ /** * Prevents packets received from the IP address getting processed for the given timeout. * - * @param string $address * @param int $timeout Seconds */ public function blockAddress(string $address, int $timeout = 300) : void; /** * Unblocks a previously-blocked address. - * - * @param string $address */ public function unblockAddress(string $address) : void; - /** - * @param Network $network - */ public function setNetwork(Network $network) : void; /** * Sends a raw payload to the network interface, bypassing any sessions. - * - * @param string $address - * @param int $port - * @param string $payload */ public function sendRawPacket(string $address, int $port, string $payload) : void; /** * Adds a regex filter for raw packets to this network interface. This filter should be used to check validity of * raw packets before relaying them to the main thread. - * - * @param string $regex */ public function addRawPacketFilter(string $regex) : void; } diff --git a/src/network/Network.php b/src/network/Network.php index 7f14e8149f..320d45be58 100644 --- a/src/network/Network.php +++ b/src/network/Network.php @@ -94,9 +94,6 @@ class Network{ return $this->interfaces; } - /** - * @return NetworkSessionManager - */ public function getSessionManager() : NetworkSessionManager{ return $this->sessionManager; } @@ -113,9 +110,6 @@ class Network{ $this->sessionManager->tick(); } - /** - * @param NetworkInterface $interface - */ public function registerInterface(NetworkInterface $interface) : void{ $ev = new NetworkInterfaceRegisterEvent($interface); $ev->call(); @@ -134,7 +128,6 @@ class Network{ } /** - * @param NetworkInterface $interface * @throws \InvalidArgumentException */ public function unregisterInterface(NetworkInterface $interface) : void{ @@ -148,8 +141,6 @@ class Network{ /** * Sets the server name shown on each interface Query - * - * @param string $name */ public function setName(string $name) : void{ $this->name = $name; @@ -158,9 +149,6 @@ class Network{ } } - /** - * @return string - */ public function getName() : string{ return $this->name; } @@ -171,11 +159,6 @@ class Network{ } } - /** - * @param string $address - * @param int $port - * @param string $payload - */ public function sendPacket(string $address, int $port, string $payload) : void{ foreach($this->advancedInterfaces as $interface){ $interface->sendRawPacket($address, $port, $payload); @@ -184,9 +167,6 @@ class Network{ /** * Blocks an IP address from the main interface. Setting timeout to -1 will block it forever - * - * @param string $address - * @param int $timeout */ public function blockAddress(string $address, int $timeout = 300) : void{ $this->bannedIps[$address] = $timeout > 0 ? time() + $timeout : PHP_INT_MAX; @@ -204,8 +184,6 @@ class Network{ /** * Registers a raw packet handler on the network. - * - * @param RawPacketHandler $handler */ public function registerRawPacketHandler(RawPacketHandler $handler) : void{ $this->rawPacketHandlers[spl_object_id($handler)] = $handler; @@ -218,19 +196,11 @@ class Network{ /** * Unregisters a previously-registered raw packet handler. - * - * @param RawPacketHandler $handler */ public function unregisterRawPacketHandler(RawPacketHandler $handler) : void{ unset($this->rawPacketHandlers[spl_object_id($handler)]); } - /** - * @param AdvancedNetworkInterface $interface - * @param string $address - * @param int $port - * @param string $packet - */ public function processRawPacket(AdvancedNetworkInterface $interface, string $address, int $port, string $packet) : void{ if(isset($this->bannedIps[$address]) and time() < $this->bannedIps[$address]){ $this->logger->debug("Dropped raw packet from banned address $address $port"); diff --git a/src/network/NetworkInterface.php b/src/network/NetworkInterface.php index 47241c341f..146a7351c5 100644 --- a/src/network/NetworkInterface.php +++ b/src/network/NetworkInterface.php @@ -36,9 +36,6 @@ interface NetworkInterface{ */ public function start() : void; - /** - * @param string $name - */ public function setName(string $name) : void; /** diff --git a/src/network/NetworkSessionManager.php b/src/network/NetworkSessionManager.php index 179ba38db2..9024ba41f2 100644 --- a/src/network/NetworkSessionManager.php +++ b/src/network/NetworkSessionManager.php @@ -37,8 +37,6 @@ class NetworkSessionManager{ /** * Adds a network session to the manager. This should only be called on session creation. - * - * @param NetworkSession $session */ public function add(NetworkSession $session) : void{ $idx = spl_object_id($session); @@ -48,8 +46,6 @@ class NetworkSessionManager{ /** * Removes the given network session, due to disconnect. This should only be called by a network session on * disconnection. - * - * @param NetworkSession $session */ public function remove(NetworkSession $session) : void{ $idx = spl_object_id($session); @@ -58,8 +54,6 @@ class NetworkSessionManager{ /** * Requests an update to be scheduled on the given network session at the next tick. - * - * @param NetworkSession $session */ public function scheduleUpdate(NetworkSession $session) : void{ $this->updateSessions[spl_object_id($session)] = $session; @@ -69,8 +63,6 @@ class NetworkSessionManager{ * Checks whether this network session is a duplicate of an already-connected session (same player connecting from * 2 locations). * - * @param NetworkSession $connectingSession - * * @return bool if the network session is still connected. */ public function kickDuplicates(NetworkSession $connectingSession) : bool{ @@ -96,8 +88,6 @@ class NetworkSessionManager{ /** * Returns the number of known connected sessions. - * - * @return int */ public function getSessionCount() : int{ return count($this->sessions); @@ -116,8 +106,6 @@ class NetworkSessionManager{ /** * Terminates all connected sessions with the given reason. - * - * @param string $reason */ public function close(string $reason = "") : void{ foreach($this->sessions as $session){ diff --git a/src/network/RawPacketHandler.php b/src/network/RawPacketHandler.php index e73d1f30eb..5ee01672c0 100644 --- a/src/network/RawPacketHandler.php +++ b/src/network/RawPacketHandler.php @@ -28,18 +28,10 @@ interface RawPacketHandler{ /** * Returns a preg_match() compatible regex pattern used to filter packets on this handler. Only packets matching * this pattern will be delivered to the handler. - * - * @return string */ public function getPattern() : string; /** - * @param AdvancedNetworkInterface $interface - * @param string $address - * @param int $port - * @param string $packet - * - * @return bool * @throws BadPacketException */ public function handle(AdvancedNetworkInterface $interface, string $address, int $port, string $packet) : bool; diff --git a/src/network/mcpe/ChunkCache.php b/src/network/mcpe/ChunkCache.php index e204b1b283..7ca9cde574 100644 --- a/src/network/mcpe/ChunkCache.php +++ b/src/network/mcpe/ChunkCache.php @@ -45,8 +45,6 @@ class ChunkCache implements ChunkListener{ /** * Fetches the ChunkCache instance for the given world. This lazily creates cache systems as needed. * - * @param World $world - * * @return ChunkCache */ public static function getInstance(World $world) : self{ @@ -64,9 +62,6 @@ class ChunkCache implements ChunkListener{ /** @var int */ private $misses = 0; - /** - * @param World $world - */ private function __construct(World $world){ $this->world = $world; } @@ -74,9 +69,6 @@ class ChunkCache implements ChunkListener{ /** * Requests asynchronous preparation of the chunk at the given coordinates. * - * @param int $chunkX - * @param int $chunkZ - * * @return CompressBatchPromise a promise of resolution which will contain a compressed chunk packet. */ public function request(int $chunkX, int $chunkZ) : CompressBatchPromise{ @@ -125,9 +117,6 @@ class ChunkCache implements ChunkListener{ /** * Restarts an async request for an unresolved chunk. * - * @param int $chunkX - * @param int $chunkZ - * * @throws \InvalidArgumentException */ private function restartPendingRequest(int $chunkX, int $chunkZ) : void{ @@ -143,9 +132,6 @@ class ChunkCache implements ChunkListener{ } /** - * @param int $chunkX - * @param int $chunkZ - * * @throws \InvalidArgumentException */ private function destroyOrRestart(int $chunkX, int $chunkZ) : void{ @@ -170,7 +156,6 @@ class ChunkCache implements ChunkListener{ /** * @see ChunkListener::onChunkChanged() - * @param Chunk $chunk */ public function onChunkChanged(Chunk $chunk) : void{ //FIXME: this gets fired for stuff that doesn't change terrain related things (like lighting updates) @@ -179,7 +164,6 @@ class ChunkCache implements ChunkListener{ /** * @see ChunkListener::onBlockChanged() - * @param Vector3 $block */ public function onBlockChanged(Vector3 $block) : void{ //FIXME: requesters will still receive this chunk after it's been dropped, but we can't mark this for a simple @@ -189,7 +173,6 @@ class ChunkCache implements ChunkListener{ /** * @see ChunkListener::onChunkUnloaded() - * @param Chunk $chunk */ public function onChunkUnloaded(Chunk $chunk) : void{ $this->destroy($chunk->getX(), $chunk->getZ()); @@ -199,8 +182,6 @@ class ChunkCache implements ChunkListener{ /** * Returns the number of bytes occupied by the cache data in this cache. This does not include the size of any * promises referenced by the cache. - * - * @return int */ public function calculateCacheSize() : int{ $result = 0; @@ -214,8 +195,6 @@ class ChunkCache implements ChunkListener{ /** * Returns the percentage of requests to the cache which resulted in a cache hit. - * - * @return float */ public function getHitPercentage() : float{ $total = $this->hits + $this->misses; diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index ca613441d9..bc65f64bbd 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -205,7 +205,6 @@ class NetworkSession{ /** * TODO: this shouldn't be accessible after the initial login phase * - * @param PlayerInfo $info * @throws \InvalidStateException */ public function setPlayerInfo(PlayerInfo $info) : void{ @@ -221,16 +220,10 @@ class NetworkSession{ return $this->connected; } - /** - * @return string - */ public function getIp() : string{ return $this->ip; } - /** - * @return int - */ public function getPort() : int{ return $this->port; } @@ -241,8 +234,6 @@ class NetworkSession{ /** * Returns the last recorded ping measurement for this session, in milliseconds. - * - * @return int */ public function getPing() : int{ return $this->ping; @@ -250,8 +241,6 @@ class NetworkSession{ /** * @internal Called by the network interface to update last recorded ping measurements. - * - * @param int $ping */ public function updatePing(int $ping) : void{ $this->ping = $ping; @@ -269,8 +258,6 @@ class NetworkSession{ } /** - * @param string $payload - * * @throws BadPacketException */ public function handleEncoded(string $payload) : void{ @@ -323,8 +310,6 @@ class NetworkSession{ } /** - * @param Packet $packet - * * @throws BadPacketException */ public function handleDataPacket(Packet $packet) : void{ @@ -384,7 +369,6 @@ class NetworkSession{ /** * @internal - * @param ClientboundPacket $packet */ public function addToSendBuffer(ClientboundPacket $packet) : void{ $timings = Timings::getSendDataPacketTimings($packet); @@ -462,9 +446,6 @@ class NetworkSession{ /** * Disconnects the session, destroying the associated player (if it exists). - * - * @param string $reason - * @param bool $notify */ public function disconnect(string $reason, bool $notify = true) : void{ $this->tryDisconnect(function() use ($reason, $notify){ @@ -478,10 +459,6 @@ class NetworkSession{ /** * Instructs the remote client to connect to a different server. * - * @param string $ip - * @param int $port - * @param string $reason - * * @throws \UnsupportedOperationException */ public function transfer(string $ip, int $port, string $reason = "transfer") : void{ @@ -497,9 +474,6 @@ class NetworkSession{ /** * Called by the Player when it is closed (for example due to getting kicked). - * - * @param string $reason - * @param bool $notify */ public function onPlayerDestroyed(string $reason, bool $notify = true) : void{ $this->tryDisconnect(function() use ($reason, $notify){ @@ -509,9 +483,6 @@ class NetworkSession{ /** * Internal helper function used to handle server disconnections. - * - * @param string $reason - * @param bool $notify */ private function doServerDisconnect(string $reason, bool $notify = true) : void{ if($notify){ @@ -524,8 +495,6 @@ class NetworkSession{ /** * Called by the network interface to close the session when the client disconnects without server input, for * example in a timeout condition or voluntary client disconnect. - * - * @param string $reason */ public function onClientDisconnect(string $reason) : void{ $this->tryDisconnect(function() use ($reason){ @@ -662,8 +631,6 @@ class NetworkSession{ /** * TODO: make this less specialized - * - * @param Player $for */ public function syncAdventureSettings(Player $for) : void{ $pk = new AdventureSettingsPacket(); @@ -763,8 +730,6 @@ class NetworkSession{ /** * Instructs the networksession to start using the chunk at the given coordinates. This may occur asynchronously. - * @param int $chunkX - * @param int $chunkZ * @param \Closure $onCompletion To be called when chunk sending has completed. */ public function startUsingChunk(int $chunkX, int $chunkZ, \Closure $onCompletion) : void{ @@ -805,9 +770,6 @@ class NetworkSession{ $world->sendDifficulty($this->player); } - /** - * @return InventoryManager - */ public function getInvManager() : InventoryManager{ return $this->invManager; } @@ -815,8 +777,6 @@ class NetworkSession{ /** * TODO: expand this to more than just humans * TODO: offhand - * - * @param Human $mob */ public function onMobEquipmentChange(Human $mob) : void{ //TODO: we could send zero for slot here because remote players don't need to know which slot was selected @@ -891,9 +851,6 @@ class NetworkSession{ * This function takes care of handling gamemodes known to MCPE (as of 1.1.0.3, that includes Survival, Creative and Adventure) * * @internal - * @param GameMode $gamemode - * - * @return int */ public static function getClientFriendlyGamemode(GameMode $gamemode) : int{ if($gamemode->equals(GameMode::SPECTATOR())){ diff --git a/src/network/mcpe/PacketBatch.php b/src/network/mcpe/PacketBatch.php index 31c081418c..aab0b93190 100644 --- a/src/network/mcpe/PacketBatch.php +++ b/src/network/mcpe/PacketBatch.php @@ -36,7 +36,6 @@ class PacketBatch extends NetworkBinaryStream{ } /** - * @return Packet * @throws BinaryDataException */ public function getPacket() : Packet{ diff --git a/src/network/mcpe/PacketSender.php b/src/network/mcpe/PacketSender.php index 857293ffb5..00ff202961 100644 --- a/src/network/mcpe/PacketSender.php +++ b/src/network/mcpe/PacketSender.php @@ -27,16 +27,11 @@ interface PacketSender{ /** * Pushes a packet into the channel to be processed. - * - * @param string $payload - * @param bool $immediate */ public function send(string $payload, bool $immediate) : void; /** * Closes the channel, terminating the connection. - * - * @param string $reason */ public function close(string $reason = "unknown reason") : void; } diff --git a/src/network/mcpe/auth/ProcessLoginTask.php b/src/network/mcpe/auth/ProcessLoginTask.php index 1cf855d2f5..2baf79263d 100644 --- a/src/network/mcpe/auth/ProcessLoginTask.php +++ b/src/network/mcpe/auth/ProcessLoginTask.php @@ -111,10 +111,6 @@ class ProcessLoginTask extends AsyncTask{ } /** - * @param string $jwt - * @param null|string $currentPublicKey - * @param bool $first - * * @throws VerifyLoginException if errors are encountered */ private function validateToken(string $jwt, ?string &$currentPublicKey, bool $first = false) : void{ diff --git a/src/network/mcpe/compression/CompressBatchPromise.php b/src/network/mcpe/compression/CompressBatchPromise.php index 709734f84a..f1d6c777ef 100644 --- a/src/network/mcpe/compression/CompressBatchPromise.php +++ b/src/network/mcpe/compression/CompressBatchPromise.php @@ -82,9 +82,6 @@ class CompressBatchPromise{ return $this->result !== null; } - /** - * @return bool - */ public function isCancelled() : bool{ return $this->cancelled; } diff --git a/src/network/mcpe/compression/CompressBatchTask.php b/src/network/mcpe/compression/CompressBatchTask.php index 62aa9a0371..e4012d8e0a 100644 --- a/src/network/mcpe/compression/CompressBatchTask.php +++ b/src/network/mcpe/compression/CompressBatchTask.php @@ -34,11 +34,6 @@ class CompressBatchTask extends AsyncTask{ /** @var string */ private $data; - /** - * @param string $data - * @param int $compressionLevel - * @param CompressBatchPromise $promise - */ public function __construct(string $data, int $compressionLevel, CompressBatchPromise $promise){ $this->data = $data; $this->level = $compressionLevel; diff --git a/src/network/mcpe/compression/Zlib.php b/src/network/mcpe/compression/Zlib.php index 05a44987f4..7c84adb704 100644 --- a/src/network/mcpe/compression/Zlib.php +++ b/src/network/mcpe/compression/Zlib.php @@ -38,10 +38,8 @@ final class Zlib{ } /** - * @param string $payload * @param int $maxDecodedLength default 2MB * - * @return string * @throws \ErrorException */ public static function decompress(string $payload, int $maxDecodedLength = 1024 * 1024 * 2) : string{ @@ -49,10 +47,7 @@ final class Zlib{ } /** - * @param string $payload * @param int $compressionLevel - * - * @return string */ public static function compress(string $payload, ?int $compressionLevel = null) : string{ return zlib_encode($payload, ZLIB_ENCODING_DEFLATE, $compressionLevel ?? self::$LEVEL); diff --git a/src/network/mcpe/encryption/NetworkCipher.php b/src/network/mcpe/encryption/NetworkCipher.php index 0b9c25a0fa..4afebce38a 100644 --- a/src/network/mcpe/encryption/NetworkCipher.php +++ b/src/network/mcpe/encryption/NetworkCipher.php @@ -65,9 +65,6 @@ class NetworkCipher{ } /** - * @param string $encrypted - * - * @return string * @throws \UnexpectedValueException */ public function decrypt(string $encrypted) : string{ diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index ffffc526dc..ca443c2895 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -319,9 +319,6 @@ class InGamePacketHandler extends PacketHandler{ /** * Internal function used to execute rollbacks when an action fails on a block. - * - * @param Vector3 $blockPos - * @param int|null $face */ private function onFailedBlockAction(Vector3 $blockPos, ?int $face) : void{ $this->session->getInvManager()->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); @@ -685,9 +682,6 @@ class InGamePacketHandler extends PacketHandler{ /** * Hack to work around a stupid bug in Minecraft W10 which causes empty strings to be sent unquoted in form responses. * - * @param string $json - * @param bool $assoc - * * @return mixed * @throws BadPacketException */ diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index a439ed4be2..f0d6876fc0 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -151,9 +151,6 @@ class LoginPacketHandler extends PacketHandler{ * TODO: This is separated for the purposes of allowing plugins (like Specter) to hack it and bypass authentication. * In the future this won't be necessary. * - * @param LoginPacket $packet - * @param bool $authRequired - * * @throws \InvalidArgumentException */ protected function processLogin(LoginPacket $packet, bool $authRequired) : void{ diff --git a/src/network/mcpe/protocol/AddEntityPacket.php b/src/network/mcpe/protocol/AddEntityPacket.php index e8a42ec73b..b4e0694f07 100644 --- a/src/network/mcpe/protocol/AddEntityPacket.php +++ b/src/network/mcpe/protocol/AddEntityPacket.php @@ -39,9 +39,6 @@ class AddEntityPacket extends DataPacket implements ClientboundPacket{ return $result; } - /** - * @return int - */ public function getUvarint1() : int{ return $this->uvarint1; } diff --git a/src/network/mcpe/protocol/AvailableCommandsPacket.php b/src/network/mcpe/protocol/AvailableCommandsPacket.php index 5705fee0ea..e7b8847d85 100644 --- a/src/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/network/mcpe/protocol/AvailableCommandsPacket.php @@ -150,7 +150,6 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ /** * @param string[] $enumValueList * - * @return CommandEnum * @throws BadPacketException * @throws BinaryDataException */ @@ -173,7 +172,6 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ } /** - * @return CommandEnum * @throws BinaryDataException */ protected function getSoftEnum() : CommandEnum{ @@ -189,7 +187,6 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ } /** - * @param CommandEnum $enum * @param int[] $enumValueMap */ protected function putEnum(CommandEnum $enum, array $enumValueMap) : void{ @@ -218,9 +215,6 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ } /** - * @param int $valueCount - * - * @return int * @throws BinaryDataException */ protected function getEnumValueIndex(int $valueCount) : int{ @@ -247,7 +241,6 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @param CommandEnum[] $enums * @param string[] $enumValues * - * @return CommandEnumConstraint * @throws BadPacketException * @throws BinaryDataException */ @@ -276,7 +269,6 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ } /** - * @param CommandEnumConstraint $constraint * @param int[] $enumIndexes string enum name -> int index * @param int[] $enumValueIndexes string value -> int index */ @@ -293,7 +285,6 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @param CommandEnum[] $enums * @param string[] $postfixes * - * @return CommandData * @throws BadPacketException * @throws BinaryDataException */ @@ -338,7 +329,6 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ } /** - * @param CommandData $data * @param int[] $enumIndexes string enum name -> int index * @param int[] $postfixIndexes */ diff --git a/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php b/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php index 35693516c0..d67cc00c20 100644 --- a/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php +++ b/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php @@ -39,8 +39,6 @@ class ClientCacheBlobStatusPacket extends DataPacket implements ServerboundPacke /** * @param int[] $hitHashes * @param int[] $missHashes - * - * @return self */ public static function create(array $hitHashes, array $missHashes) : self{ //type checks diff --git a/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php b/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php index d973aa59fe..b77cf169bc 100644 --- a/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php +++ b/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php @@ -37,8 +37,6 @@ class ClientCacheMissResponsePacket extends DataPacket implements ClientboundPac /** * @param ChunkCacheBlob[] $blobs - * - * @return self */ public static function create(array $blobs) : self{ //type check diff --git a/src/network/mcpe/protocol/ClientCacheStatusPacket.php b/src/network/mcpe/protocol/ClientCacheStatusPacket.php index cfa97c8e24..ec42d5cfc1 100644 --- a/src/network/mcpe/protocol/ClientCacheStatusPacket.php +++ b/src/network/mcpe/protocol/ClientCacheStatusPacket.php @@ -39,9 +39,6 @@ class ClientCacheStatusPacket extends DataPacket implements ServerboundPacket{ return $result; } - /** - * @return bool - */ public function isEnabled() : bool{ return $this->enabled; } diff --git a/src/network/mcpe/protocol/CommandOutputPacket.php b/src/network/mcpe/protocol/CommandOutputPacket.php index 36ac89a2c8..313933b649 100644 --- a/src/network/mcpe/protocol/CommandOutputPacket.php +++ b/src/network/mcpe/protocol/CommandOutputPacket.php @@ -60,7 +60,6 @@ class CommandOutputPacket extends DataPacket implements ClientboundPacket{ } /** - * @return CommandOutputMessage * @throws BinaryDataException */ protected function getCommandMessage() : CommandOutputMessage{ diff --git a/src/network/mcpe/protocol/CraftingDataPacket.php b/src/network/mcpe/protocol/CraftingDataPacket.php index d1d4c75db9..8ac5b2cf83 100644 --- a/src/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/network/mcpe/protocol/CraftingDataPacket.php @@ -163,10 +163,6 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{ /** * @param object $entry - * @param NetworkBinaryStream $stream - * @param int $pos - * - * @return int */ private static function writeEntry($entry, NetworkBinaryStream $stream, int $pos) : int{ if($entry instanceof ShapelessRecipe){ diff --git a/src/network/mcpe/protocol/EmotePacket.php b/src/network/mcpe/protocol/EmotePacket.php index 923cde0769..9bf12c3306 100644 --- a/src/network/mcpe/protocol/EmotePacket.php +++ b/src/network/mcpe/protocol/EmotePacket.php @@ -49,7 +49,6 @@ class EmotePacket extends DataPacket implements ClientboundPacket, ServerboundPa /** * TODO: we can't call this getEntityRuntimeId() because of base class collision (crap architecture, thanks Shoghi) - * @return int */ public function getEntityRuntimeIdField() : int{ return $this->entityRuntimeId; diff --git a/src/network/mcpe/protocol/InventoryContentPacket.php b/src/network/mcpe/protocol/InventoryContentPacket.php index 5aaa29b15c..2054dc7323 100644 --- a/src/network/mcpe/protocol/InventoryContentPacket.php +++ b/src/network/mcpe/protocol/InventoryContentPacket.php @@ -38,7 +38,6 @@ class InventoryContentPacket extends DataPacket implements ClientboundPacket{ public $items = []; /** - * @param int $windowId * @param Item[] $items * * @return InventoryContentPacket diff --git a/src/network/mcpe/protocol/LevelChunkPacket.php b/src/network/mcpe/protocol/LevelChunkPacket.php index 5689dff697..213d1847b0 100644 --- a/src/network/mcpe/protocol/LevelChunkPacket.php +++ b/src/network/mcpe/protocol/LevelChunkPacket.php @@ -70,30 +70,18 @@ class LevelChunkPacket extends DataPacket implements ClientboundPacket{ return $result; } - /** - * @return int - */ public function getChunkX() : int{ return $this->chunkX; } - /** - * @return int - */ public function getChunkZ() : int{ return $this->chunkZ; } - /** - * @return int - */ public function getSubChunkCount() : int{ return $this->subChunkCount; } - /** - * @return bool - */ public function isCacheEnabled() : bool{ return $this->cacheEnabled; } @@ -105,9 +93,6 @@ class LevelChunkPacket extends DataPacket implements ClientboundPacket{ return $this->usedBlobHashes; } - /** - * @return string - */ public function getExtraPayload() : string{ return $this->extraPayload; } diff --git a/src/network/mcpe/protocol/LevelEventGenericPacket.php b/src/network/mcpe/protocol/LevelEventGenericPacket.php index d462b407e8..1c6c0eaecd 100644 --- a/src/network/mcpe/protocol/LevelEventGenericPacket.php +++ b/src/network/mcpe/protocol/LevelEventGenericPacket.php @@ -45,16 +45,10 @@ class LevelEventGenericPacket extends DataPacket implements ClientboundPacket{ return $result; } - /** - * @return int - */ public function getEventId() : int{ return $this->eventId; } - /** - * @return string - */ public function getEventData() : string{ return $this->eventData; } diff --git a/src/network/mcpe/protocol/LoginPacket.php b/src/network/mcpe/protocol/LoginPacket.php index a594af3883..8ae9f09be8 100644 --- a/src/network/mcpe/protocol/LoginPacket.php +++ b/src/network/mcpe/protocol/LoginPacket.php @@ -109,8 +109,6 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ } /** - * @param Validator $v - * @param string $name * @param mixed $data * * @throws BadPacketException diff --git a/src/network/mcpe/protocol/MoveActorDeltaPacket.php b/src/network/mcpe/protocol/MoveActorDeltaPacket.php index be7abc1c16..304ab1d172 100644 --- a/src/network/mcpe/protocol/MoveActorDeltaPacket.php +++ b/src/network/mcpe/protocol/MoveActorDeltaPacket.php @@ -56,9 +56,6 @@ class MoveActorDeltaPacket extends DataPacket implements ClientboundPacket{ public $zRot = 0.0; /** - * @param int $flag - * - * @return int * @throws BinaryDataException */ private function maybeReadCoord(int $flag) : int{ @@ -69,9 +66,6 @@ class MoveActorDeltaPacket extends DataPacket implements ClientboundPacket{ } /** - * @param int $flag - * - * @return float * @throws BinaryDataException */ private function maybeReadRotation(int $flag) : float{ diff --git a/src/network/mcpe/protocol/Packet.php b/src/network/mcpe/protocol/Packet.php index e54489f812..6e68038726 100644 --- a/src/network/mcpe/protocol/Packet.php +++ b/src/network/mcpe/protocol/Packet.php @@ -34,9 +34,6 @@ interface Packet{ * TODO: this can't have a native return type yet because of incompatibility with BinaryUtils * really this should be addressed by making packets not extend BinaryStream, but that's a task for another day. * - * @param string $buffer - * @param int $offset - * * @return void */ public function setBuffer(string $buffer = "", int $offset = 0); @@ -47,7 +44,6 @@ interface Packet{ /** * Returns whether the offset has reached the end of the buffer. - * @return bool */ public function feof() : bool; @@ -74,8 +70,6 @@ interface Packet{ * Typically this method returns the return value of the handler in the supplied PacketHandler. See other packets * for examples how to implement this. * - * @param PacketHandler $handler - * * @return bool true if the packet was handled successfully, false if not. * @throws BadPacketException if broken data was found in the packet */ diff --git a/src/network/mcpe/protocol/PacketPool.php b/src/network/mcpe/protocol/PacketPool.php index 1e265a2620..e8b05db983 100644 --- a/src/network/mcpe/protocol/PacketPool.php +++ b/src/network/mcpe/protocol/PacketPool.php @@ -177,26 +177,15 @@ class PacketPool{ static::registerPacket(new PlayerAuthInputPacket()); } - /** - * @param Packet $packet - */ public static function registerPacket(Packet $packet) : void{ static::$pool[$packet->pid()] = clone $packet; } - /** - * @param int $pid - * - * @return Packet - */ public static function getPacketById(int $pid) : Packet{ return isset(static::$pool[$pid]) ? clone static::$pool[$pid] : new UnknownPacket(); } /** - * @param string $buffer - * - * @return Packet * @throws BinaryDataException */ public static function getPacket(string $buffer) : Packet{ diff --git a/src/network/mcpe/protocol/PlayerAuthInputPacket.php b/src/network/mcpe/protocol/PlayerAuthInputPacket.php index 0b80ff076e..9ab85d79e0 100644 --- a/src/network/mcpe/protocol/PlayerAuthInputPacket.php +++ b/src/network/mcpe/protocol/PlayerAuthInputPacket.php @@ -56,18 +56,9 @@ class PlayerAuthInputPacket extends DataPacket implements ServerboundPacket{ private $vrGazeDirection = null; /** - * @param Vector3 $position - * @param float $pitch - * @param float $yaw - * @param float $headYaw - * @param float $moveVecX - * @param float $moveVecZ - * @param int $inputFlags * @param int $inputMode @see InputMode * @param int $playMode @see PlayMode * @param Vector3|null $vrGazeDirection only used when PlayMode::VR - * - * @return self */ public static function create(Vector3 $position, float $pitch, float $yaw, float $headYaw, float $moveVecX, float $moveVecZ, int $inputFlags, int $inputMode, int $playMode, ?Vector3 $vrGazeDirection = null) : self{ if($playMode === PlayMode::VR and $vrGazeDirection === null){ @@ -120,7 +111,6 @@ class PlayerAuthInputPacket extends DataPacket implements ServerboundPacket{ /** * @see InputMode - * @return int */ public function getInputMode() : int{ return $this->inputMode; @@ -128,7 +118,6 @@ class PlayerAuthInputPacket extends DataPacket implements ServerboundPacket{ /** * @see PlayMode - * @return int */ public function getPlayMode() : int{ return $this->playMode; diff --git a/src/network/mcpe/protocol/RemoveEntityPacket.php b/src/network/mcpe/protocol/RemoveEntityPacket.php index a4cdf96b47..9b052ae506 100644 --- a/src/network/mcpe/protocol/RemoveEntityPacket.php +++ b/src/network/mcpe/protocol/RemoveEntityPacket.php @@ -39,9 +39,6 @@ class RemoveEntityPacket extends DataPacket implements ClientboundPacket{ return $result; } - /** - * @return int - */ public function getUvarint1() : int{ return $this->uvarint1; } diff --git a/src/network/mcpe/protocol/ResourcePackStackPacket.php b/src/network/mcpe/protocol/ResourcePackStackPacket.php index f0792c0d02..69d1684028 100644 --- a/src/network/mcpe/protocol/ResourcePackStackPacket.php +++ b/src/network/mcpe/protocol/ResourcePackStackPacket.php @@ -50,8 +50,6 @@ class ResourcePackStackPacket extends DataPacket implements ClientboundPacket{ /** * @param ResourcePackStackEntry[] $resourcePacks * @param ResourcePackStackEntry[] $behaviorPacks - * @param bool $mustAccept - * @param bool $isExperimental * * @return ResourcePackStackPacket */ diff --git a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php index 16113b7d71..753d60486d 100644 --- a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php +++ b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php @@ -45,8 +45,6 @@ class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ /** * @param ResourcePackInfoEntry[] $resourcePacks * @param ResourcePackInfoEntry[] $behaviorPacks - * @param bool $mustAccept - * @param bool $hasScripts * * @return ResourcePacksInfoPacket */ diff --git a/src/network/mcpe/protocol/TextPacket.php b/src/network/mcpe/protocol/TextPacket.php index de646852db..b167e2a197 100644 --- a/src/network/mcpe/protocol/TextPacket.php +++ b/src/network/mcpe/protocol/TextPacket.php @@ -79,7 +79,6 @@ class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPac } /** - * @param string $key * @param string[] $parameters * * @return TextPacket @@ -93,7 +92,6 @@ class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPac } /** - * @param string $key * @param string[] $parameters * * @return TextPacket @@ -103,7 +101,6 @@ class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPac } /** - * @param string $key * @param string[] $parameters * * @return TextPacket diff --git a/src/network/mcpe/protocol/UpdateAttributesPacket.php b/src/network/mcpe/protocol/UpdateAttributesPacket.php index 5766719031..de37371e36 100644 --- a/src/network/mcpe/protocol/UpdateAttributesPacket.php +++ b/src/network/mcpe/protocol/UpdateAttributesPacket.php @@ -39,7 +39,6 @@ class UpdateAttributesPacket extends DataPacket implements ClientboundPacket{ public $entries = []; /** - * @param int $entityRuntimeId * @param Attribute[] $attributes * * @return UpdateAttributesPacket diff --git a/src/network/mcpe/protocol/types/ChunkCacheBlob.php b/src/network/mcpe/protocol/types/ChunkCacheBlob.php index acf09f35fe..a20137620e 100644 --- a/src/network/mcpe/protocol/types/ChunkCacheBlob.php +++ b/src/network/mcpe/protocol/types/ChunkCacheBlob.php @@ -31,25 +31,16 @@ class ChunkCacheBlob{ /** * ChunkCacheBlob constructor. - * - * @param int $hash - * @param string $payload */ public function __construct(int $hash, string $payload){ $this->hash = $hash; $this->payload = $payload; } - /** - * @return int - */ public function getHash() : int{ return $this->hash; } - /** - * @return string - */ public function getPayload() : string{ return $this->payload; } diff --git a/src/network/mcpe/protocol/types/RuntimeBlockMapping.php b/src/network/mcpe/protocol/types/RuntimeBlockMapping.php index bee2f9c19a..0269a23f81 100644 --- a/src/network/mcpe/protocol/types/RuntimeBlockMapping.php +++ b/src/network/mcpe/protocol/types/RuntimeBlockMapping.php @@ -128,12 +128,6 @@ final class RuntimeBlockMapping{ return $table; } - /** - * @param int $id - * @param int $meta - * - * @return int - */ public static function toStaticRuntimeId(int $id, int $meta = 0) : int{ self::lazyInit(); /* @@ -145,8 +139,6 @@ final class RuntimeBlockMapping{ } /** - * @param int $runtimeId - * * @return int[] [id, meta] */ public static function fromStaticRuntimeId(int $runtimeId) : array{ diff --git a/src/network/mcpe/protocol/types/SkinAdapter.php b/src/network/mcpe/protocol/types/SkinAdapter.php index f030f4488a..357d7c2aba 100644 --- a/src/network/mcpe/protocol/types/SkinAdapter.php +++ b/src/network/mcpe/protocol/types/SkinAdapter.php @@ -32,17 +32,11 @@ interface SkinAdapter{ /** * Allows you to convert a skin entity to skin data. - * - * @param Skin $skin - * @return SkinData */ public function toSkinData(Skin $skin) : SkinData; /** * Allows you to convert skin data to a skin entity. - * - * @param SkinData $data - * @return Skin */ public function fromSkinData(SkinData $data) : Skin; } diff --git a/src/network/mcpe/protocol/types/SkinAnimation.php b/src/network/mcpe/protocol/types/SkinAnimation.php index 0f6726cf7c..40a9e96247 100644 --- a/src/network/mcpe/protocol/types/SkinAnimation.php +++ b/src/network/mcpe/protocol/types/SkinAnimation.php @@ -44,8 +44,6 @@ class SkinAnimation{ /** * Image of the animation. - * - * @return SkinImage */ public function getImage() : SkinImage{ return $this->image; @@ -53,8 +51,6 @@ class SkinAnimation{ /** * The type of animation you are applying. - * - * @return int */ public function getType() : int{ return $this->type; @@ -62,8 +58,6 @@ class SkinAnimation{ /** * The total amount of frames in an animation. - * - * @return float */ public function getFrames() : float{ return $this->frames; diff --git a/src/network/mcpe/protocol/types/SkinData.php b/src/network/mcpe/protocol/types/SkinData.php index 0e46d0a4f6..6ff6dfda89 100644 --- a/src/network/mcpe/protocol/types/SkinData.php +++ b/src/network/mcpe/protocol/types/SkinData.php @@ -49,17 +49,7 @@ class SkinData{ private $capeId; /** - * @param string $skinId - * @param string $resourcePatch - * @param SkinImage $skinImage * @param SkinAnimation[] $animations - * @param SkinImage|null $capeImage - * @param string $geometryData - * @param string $animationData - * @param bool $premium - * @param bool $persona - * @param bool $personaCapeOnClassic - * @param string $capeId */ public function __construct(string $skinId, string $resourcePatch, SkinImage $skinImage, array $animations = [], SkinImage $capeImage = null, string $geometryData = "", string $animationData = "", bool $premium = false, bool $persona = false, bool $personaCapeOnClassic = false, string $capeId = ""){ $this->skinId = $skinId; @@ -75,23 +65,14 @@ class SkinData{ $this->capeId = $capeId; } - /** - * @return string - */ public function getSkinId() : string{ return $this->skinId; } - /** - * @return string - */ public function getResourcePatch() : string{ return $this->resourcePatch; } - /** - * @return SkinImage - */ public function getSkinImage() : SkinImage{ return $this->skinImage; } @@ -103,51 +84,30 @@ class SkinData{ return $this->animations; } - /** - * @return SkinImage - */ public function getCapeImage() : SkinImage{ return $this->capeImage; } - /** - * @return string - */ public function getGeometryData() : string{ return $this->geometryData; } - /** - * @return string - */ public function getAnimationData() : string{ return $this->animationData; } - /** - * @return bool - */ public function isPersona() : bool{ return $this->persona; } - /** - * @return bool - */ public function isPremium() : bool{ return $this->premium; } - /** - * @return bool - */ public function isPersonaCapeOnClassic() : bool{ return $this->personaCapeOnClassic; } - /** - * @return string - */ public function getCapeId() : string{ return $this->capeId; } diff --git a/src/network/mcpe/protocol/types/command/CommandData.php b/src/network/mcpe/protocol/types/command/CommandData.php index 7bfc70354a..5b3ec8fe0a 100644 --- a/src/network/mcpe/protocol/types/command/CommandData.php +++ b/src/network/mcpe/protocol/types/command/CommandData.php @@ -38,11 +38,6 @@ class CommandData{ public $overloads = []; /** - * @param string $name - * @param string $description - * @param int $flags - * @param int $permission - * @param CommandEnum|null $aliases * @param CommandParameter[][] $overloads */ public function __construct(string $name, string $description, int $flags, int $permission, ?CommandEnum $aliases, array $overloads){ @@ -59,37 +54,22 @@ class CommandData{ $this->overloads = $overloads; } - /** - * @return string - */ public function getName() : string{ return $this->name; } - /** - * @return string - */ public function getDescription() : string{ return $this->description; } - /** - * @return int - */ public function getFlags() : int{ return $this->flags; } - /** - * @return int - */ public function getPermission() : int{ return $this->permission; } - /** - * @return CommandEnum|null - */ public function getAliases() : ?CommandEnum{ return $this->aliases; } diff --git a/src/network/mcpe/protocol/types/command/CommandEnum.php b/src/network/mcpe/protocol/types/command/CommandEnum.php index 2a46c260bd..dfaf39e5b7 100644 --- a/src/network/mcpe/protocol/types/command/CommandEnum.php +++ b/src/network/mcpe/protocol/types/command/CommandEnum.php @@ -30,7 +30,6 @@ class CommandEnum{ private $enumValues = []; /** - * @param string $enumName * @param string[] $enumValues */ public function __construct(string $enumName, array $enumValues){ @@ -38,9 +37,6 @@ class CommandEnum{ $this->enumValues = $enumValues; } - /** - * @return string - */ public function getName() : string{ return $this->enumName; } diff --git a/src/network/mcpe/protocol/types/command/CommandEnumConstraint.php b/src/network/mcpe/protocol/types/command/CommandEnumConstraint.php index ff4ad523ff..8f78094b93 100644 --- a/src/network/mcpe/protocol/types/command/CommandEnumConstraint.php +++ b/src/network/mcpe/protocol/types/command/CommandEnumConstraint.php @@ -32,8 +32,6 @@ class CommandEnumConstraint{ private $constraints; //TODO: find constants /** - * @param CommandEnum $enum - * @param int $valueOffset * @param int[] $constraints */ public function __construct(CommandEnum $enum, int $valueOffset, array $constraints){ diff --git a/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php b/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php index ebf88b1103..ae8ffe5620 100644 --- a/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php @@ -31,16 +31,10 @@ final class BlockPosMetadataProperty implements MetadataProperty{ /** @var Vector3 */ private $value; - /** - * @param Vector3 $value - */ public function __construct(Vector3 $value){ $this->value = $value->floor(); } - /** - * @return Vector3 - */ public function getValue() : Vector3{ return $this->value; } diff --git a/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php b/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php index 4c1c738410..62ecda9b4e 100644 --- a/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php @@ -34,16 +34,10 @@ final class CompoundTagMetadataProperty implements MetadataProperty{ /** @var CompoundTag */ private $value; - /** - * @param CompoundTag $value - */ public function __construct(CompoundTag $value){ $this->value = clone $value; } - /** - * @return CompoundTag - */ public function getValue() : CompoundTag{ return clone $this->value; } @@ -57,9 +51,6 @@ final class CompoundTagMetadataProperty implements MetadataProperty{ } /** - * @param NetworkBinaryStream $in - * - * @return self * @throws BadPacketException */ public static function read(NetworkBinaryStream $in) : self{ diff --git a/src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php b/src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php index 3fa0ea9dd3..c096143a9b 100644 --- a/src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php +++ b/src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php @@ -38,93 +38,43 @@ class EntityMetadataCollection{ } - /** - * @param int $key - * @param int $value - * @param bool $force - */ public function setByte(int $key, int $value, bool $force = false) : void{ $this->set($key, new ByteMetadataProperty($value), $force); } - /** - * @param int $key - * @param int $value - * @param bool $force - */ public function setShort(int $key, int $value, bool $force = false) : void{ $this->set($key, new ShortMetadataProperty($value), $force); } - /** - * @param int $key - * @param int $value - * @param bool $force - */ public function setInt(int $key, int $value, bool $force = false) : void{ $this->set($key, new IntMetadataProperty($value), $force); } - /** - * @param int $key - * @param float $value - * @param bool $force - */ public function setFloat(int $key, float $value, bool $force = false) : void{ $this->set($key, new FloatMetadataProperty($value), $force); } - /** - * @param int $key - * @param string $value - * @param bool $force - */ public function setString(int $key, string $value, bool $force = false) : void{ $this->set($key, new StringMetadataProperty($value), $force); } - /** - * @param int $key - * @param CompoundTag $value - * @param bool $force - */ public function setCompoundTag(int $key, CompoundTag $value, bool $force = false) : void{ $this->set($key, new CompoundTagMetadataProperty($value), $force); } - /** - * @param int $key - * @param null|Vector3 $value - * @param bool $force - */ public function setBlockPos(int $key, ?Vector3 $value, bool $force = false) : void{ $this->set($key, new BlockPosMetadataProperty($value ?? new Vector3(0, 0, 0)), $force); } - /** - * @param int $key - * @param int $value - * @param bool $force - */ public function setLong(int $key, int $value, bool $force = false) : void{ $this->set($key, new LongMetadataProperty($value), $force); } - /** - * @param int $key - * @param null|Vector3 $value - * @param bool $force - */ public function setVector3(int $key, ?Vector3 $value, bool $force = false) : void{ $this->set($key, new Vec3MetadataProperty($value ?? new Vector3(0, 0, 0)), $force); } - /** - * @param int $key - * @param MetadataProperty $value - * @param bool $force - */ public function set(int $key, MetadataProperty $value, bool $force = false) : void{ if(!$force and isset($this->properties[$key]) and !($this->properties[$key] instanceof $value)){ throw new \InvalidArgumentException("Can't overwrite property with mismatching types (have " . get_class($this->properties[$key]) . ")"); diff --git a/src/network/mcpe/protocol/types/entity/FloatMetadataProperty.php b/src/network/mcpe/protocol/types/entity/FloatMetadataProperty.php index faf2561118..afe8705cb2 100644 --- a/src/network/mcpe/protocol/types/entity/FloatMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/FloatMetadataProperty.php @@ -30,16 +30,10 @@ final class FloatMetadataProperty implements MetadataProperty{ /** @var float */ private $value; - /** - * @param float $value - */ public function __construct(float $value){ $this->value = $value; } - /** - * @return float - */ public function getValue() : float{ return $this->value; } diff --git a/src/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php b/src/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php index dad794140d..298e229b43 100644 --- a/src/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php @@ -27,9 +27,6 @@ trait IntegerishMetadataProperty{ /** @var int */ private $value; - /** - * @param int $value - */ public function __construct(int $value){ if($value < $this->min() or $value > $this->max()){ throw new \InvalidArgumentException("Value is out of range " . $this->min() . " - " . $this->max()); @@ -41,9 +38,6 @@ trait IntegerishMetadataProperty{ abstract protected function max() : int; - /** - * @return int - */ public function getValue() : int{ return $this->value; } diff --git a/src/network/mcpe/protocol/types/entity/StringMetadataProperty.php b/src/network/mcpe/protocol/types/entity/StringMetadataProperty.php index 846410a006..9c8ca620fd 100644 --- a/src/network/mcpe/protocol/types/entity/StringMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/StringMetadataProperty.php @@ -29,9 +29,6 @@ final class StringMetadataProperty implements MetadataProperty{ /** @var string */ private $value; - /** - * @param string $value - */ public function __construct(string $value){ $this->value = $value; } diff --git a/src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php b/src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php index 7115d42c50..bc4ec5a7c9 100644 --- a/src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php @@ -30,16 +30,10 @@ class Vec3MetadataProperty implements MetadataProperty{ /** @var Vector3 */ private $value; - /** - * @param Vector3 $value - */ public function __construct(Vector3 $value){ $this->value = $value->asVector3(); } - /** - * @return Vector3 - */ public function getValue() : Vector3{ return clone $this->value; } diff --git a/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php b/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php index b1ceb9fe41..a4a2f46b81 100644 --- a/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php +++ b/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php @@ -88,8 +88,6 @@ class NetworkInventoryAction{ public $newItem; /** - * @param NetworkBinaryStream $packet - * * @return $this * * @throws BinaryDataException @@ -122,8 +120,6 @@ class NetworkInventoryAction{ } /** - * @param NetworkBinaryStream $packet - * * @throws \InvalidArgumentException */ public function write(NetworkBinaryStream $packet) : void{ @@ -151,10 +147,6 @@ class NetworkInventoryAction{ } /** - * @param Player $player - * - * @return InventoryAction|null - * * @throws \UnexpectedValueException */ public function createInventoryAction(Player $player) : ?InventoryAction{ diff --git a/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php b/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php index 48f45312bf..d6274454bf 100644 --- a/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php @@ -41,30 +41,18 @@ class ReleaseItemTransactionData extends TransactionData{ /** @var Vector3 */ private $headPos; - /** - * @return int - */ public function getActionType() : int{ return $this->actionType; } - /** - * @return int - */ public function getHotbarSlot() : int{ return $this->hotbarSlot; } - /** - * @return Item - */ public function getItemInHand() : Item{ return $this->itemInHand; } - /** - * @return Vector3 - */ public function getHeadPos() : Vector3{ return $this->headPos; } diff --git a/src/network/mcpe/protocol/types/inventory/TransactionData.php b/src/network/mcpe/protocol/types/inventory/TransactionData.php index a58d037809..28c49010c5 100644 --- a/src/network/mcpe/protocol/types/inventory/TransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/TransactionData.php @@ -39,14 +39,9 @@ abstract class TransactionData{ return $this->actions; } - /** - * @return int - */ abstract public function getTypeId() : int; /** - * @param NetworkBinaryStream $stream - * * @throws BinaryDataException * @throws BadPacketException */ @@ -59,8 +54,6 @@ abstract class TransactionData{ } /** - * @param NetworkBinaryStream $stream - * * @throws BinaryDataException * @throws BadPacketException */ diff --git a/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php b/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php index cf1aac04fd..f487fee24c 100644 --- a/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php @@ -45,44 +45,26 @@ class UseItemOnEntityTransactionData extends TransactionData{ /** @var Vector3 */ private $clickPos; - /** - * @return int - */ public function getEntityRuntimeId() : int{ return $this->entityRuntimeId; } - /** - * @return int - */ public function getActionType() : int{ return $this->actionType; } - /** - * @return int - */ public function getHotbarSlot() : int{ return $this->hotbarSlot; } - /** - * @return Item - */ public function getItemInHand() : Item{ return $this->itemInHand; } - /** - * @return Vector3 - */ public function getPlayerPos() : Vector3{ return $this->playerPos; } - /** - * @return Vector3 - */ public function getClickPos() : Vector3{ return $this->clickPos; } diff --git a/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php b/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php index 06edaf8097..261b1c874f 100644 --- a/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php @@ -50,58 +50,34 @@ class UseItemTransactionData extends TransactionData{ /** @var int */ private $blockRuntimeId; - /** - * @return int - */ public function getActionType() : int{ return $this->actionType; } - /** - * @return Vector3 - */ public function getBlockPos() : Vector3{ return $this->blockPos; } - /** - * @return int - */ public function getFace() : int{ return $this->face; } - /** - * @return int - */ public function getHotbarSlot() : int{ return $this->hotbarSlot; } - /** - * @return Item - */ public function getItemInHand() : Item{ return $this->itemInHand; } - /** - * @return Vector3 - */ public function getPlayerPos() : Vector3{ return $this->playerPos; } - /** - * @return Vector3 - */ public function getClickPos() : Vector3{ return $this->clickPos; } - /** - * @return int - */ public function getBlockRuntimeId() : int{ return $this->blockRuntimeId; } diff --git a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php index e8331fbd3d..3877908147 100644 --- a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php +++ b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php @@ -52,51 +52,30 @@ class ResourcePackInfoEntry{ $this->hasScripts = $hasScripts; } - /** - * @return string - */ public function getPackId() : string{ return $this->packId; } - /** - * @return string - */ public function getVersion() : string{ return $this->version; } - /** - * @return int - */ public function getSizeBytes() : int{ return $this->sizeBytes; } - /** - * @return string - */ public function getEncryptionKey() : string{ return $this->encryptionKey; } - /** - * @return string - */ public function getSubPackName() : string{ return $this->subPackName; } - /** - * @return string - */ public function getContentId() : string{ return $this->contentId; } - /** - * @return bool - */ public function hasScripts() : bool{ return $this->hasScripts; } diff --git a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php index 843a87ce53..85ebfd92d3 100644 --- a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php +++ b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php @@ -40,23 +40,14 @@ class ResourcePackStackEntry{ $this->subPackName = $subPackName; } - /** - * @return string - */ public function getPackId() : string{ return $this->packId; } - /** - * @return string - */ public function getVersion() : string{ return $this->version; } - /** - * @return string - */ public function getSubPackName() : string{ return $this->subPackName; } diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index d7c17a92b9..a1d00f37d5 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -38,9 +38,6 @@ final class ChunkSerializer{ /** * Returns the number of subchunks that will be sent from the given chunk. * Chunks are sent in a stack, so every chunk below the top non-empty one must be sent. - * @param Chunk $chunk - * - * @return int */ public static function getSubChunkCount(Chunk $chunk) : int{ for($count = $chunk->getSubChunks()->count(); $count > 0; --$count){ @@ -53,13 +50,6 @@ final class ChunkSerializer{ return $count; } - /** - * @param Chunk $chunk - * - * @param string|null $tiles - * - * @return string - */ public static function serialize(Chunk $chunk, ?string $tiles = null) : string{ $stream = new NetworkBinaryStream(); $subChunkCount = self::getSubChunkCount($chunk); diff --git a/src/network/mcpe/serializer/NetworkBinaryStream.php b/src/network/mcpe/serializer/NetworkBinaryStream.php index bc29ec5881..df66701501 100644 --- a/src/network/mcpe/serializer/NetworkBinaryStream.php +++ b/src/network/mcpe/serializer/NetworkBinaryStream.php @@ -64,7 +64,6 @@ class NetworkBinaryStream extends BinaryStream{ private const DAMAGE_TAG_CONFLICT_RESOLUTION = "___Damage_ProtocolCollisionResolution___"; /** - * @return string * @throws BinaryDataException */ public function getString() : string{ @@ -77,7 +76,6 @@ class NetworkBinaryStream extends BinaryStream{ } /** - * @return UUID * @throws BinaryDataException */ public function getUUID() : UUID{ @@ -162,8 +160,6 @@ class NetworkBinaryStream extends BinaryStream{ } /** - * @return Item - * * @throws BadPacketException * @throws BinaryDataException */ @@ -401,7 +397,6 @@ class NetworkBinaryStream extends BinaryStream{ /** * Reads and returns an EntityUniqueID - * @return int * * @throws BinaryDataException */ @@ -411,8 +406,6 @@ class NetworkBinaryStream extends BinaryStream{ /** * Writes an EntityUniqueID - * - * @param int $eid */ public function putEntityUniqueId(int $eid) : void{ $this->putVarLong($eid); @@ -420,7 +413,6 @@ class NetworkBinaryStream extends BinaryStream{ /** * Reads and returns an EntityRuntimeID - * @return int * * @throws BinaryDataException */ @@ -430,8 +422,6 @@ class NetworkBinaryStream extends BinaryStream{ /** * Writes an EntityRuntimeID - * - * @param int $eid */ public function putEntityRuntimeId(int $eid) : void{ $this->putUnsignedVarLong($eid); @@ -454,10 +444,6 @@ class NetworkBinaryStream extends BinaryStream{ /** * Writes a block position with unsigned Y coordinate. - * - * @param int $x - * @param int $y - * @param int $z */ public function putBlockPosition(int $x, int $y, int $z) : void{ $this->putVarInt($x); @@ -482,10 +468,6 @@ class NetworkBinaryStream extends BinaryStream{ /** * Writes a block position with a signed Y coordinate. - * - * @param int $x - * @param int $y - * @param int $z */ public function putSignedBlockPosition(int $x, int $y, int $z) : void{ $this->putVarInt($x); @@ -496,8 +478,6 @@ class NetworkBinaryStream extends BinaryStream{ /** * Reads a floating-point Vector3 object with coordinates rounded to 4 decimal places. * - * @return Vector3 - * * @throws BinaryDataException */ public function getVector3() : Vector3{ @@ -515,8 +495,6 @@ class NetworkBinaryStream extends BinaryStream{ * For all other purposes, use the non-nullable version. * * @see NetworkBinaryStream::putVector3() - * - * @param Vector3|null $vector */ public function putVector3Nullable(?Vector3 $vector) : void{ if($vector){ @@ -530,8 +508,6 @@ class NetworkBinaryStream extends BinaryStream{ /** * Writes a floating-point Vector3 object - * - * @param Vector3 $vector */ public function putVector3(Vector3 $vector) : void{ $this->putLFloat($vector->x); @@ -540,7 +516,6 @@ class NetworkBinaryStream extends BinaryStream{ } /** - * @return float * @throws BinaryDataException */ public function getByteRotation() : float{ @@ -590,8 +565,6 @@ class NetworkBinaryStream extends BinaryStream{ /** * Writes a gamerule array, members should be in the structure [name => [type, value]] * TODO: implement this properly - * - * @param array $rules */ public function putGameRules(array $rules) : void{ $this->putUnsignedVarInt(count($rules)); @@ -615,8 +588,6 @@ class NetworkBinaryStream extends BinaryStream{ } /** - * @return EntityLink - * * @throws BinaryDataException */ protected function getEntityLink() : EntityLink{ @@ -630,9 +601,6 @@ class NetworkBinaryStream extends BinaryStream{ return $link; } - /** - * @param EntityLink $link - */ protected function putEntityLink(EntityLink $link) : void{ $this->putEntityUniqueId($link->fromEntityUniqueId); $this->putEntityUniqueId($link->toEntityUniqueId); @@ -641,7 +609,6 @@ class NetworkBinaryStream extends BinaryStream{ } /** - * @return CommandOriginData * @throws BinaryDataException */ protected function getCommandOriginData() : CommandOriginData{ diff --git a/src/network/query/QueryHandler.php b/src/network/query/QueryHandler.php index 36d6bef556..47941e27c6 100644 --- a/src/network/query/QueryHandler.php +++ b/src/network/query/QueryHandler.php @@ -86,14 +86,6 @@ class QueryHandler implements RawPacketHandler{ return Binary::readInt(substr(hash("sha512", $salt . ":" . $token, true), 7, 4)); } - /** - * @param AdvancedNetworkInterface $interface - * @param string $address - * @param int $port - * @param string $packet - * - * @return bool - */ public function handle(AdvancedNetworkInterface $interface, string $address, int $port, string $packet) : bool{ try{ $stream = new BinaryStream($packet); diff --git a/src/permission/BanEntry.php b/src/permission/BanEntry.php index 1d7422409c..6dd3ee032c 100644 --- a/src/permission/BanEntry.php +++ b/src/permission/BanEntry.php @@ -63,8 +63,6 @@ class BanEntry{ } /** - * @param \DateTime $date - * * @throws \InvalidArgumentException */ public function setCreated(\DateTime $date) : void{ @@ -80,15 +78,11 @@ class BanEntry{ $this->source = $source; } - /** - * @return \DateTime|null - */ public function getExpires() : ?\DateTime{ return $this->expirationDate; } /** - * @param \DateTime|null $date * @throws \InvalidArgumentException */ public function setExpires(?\DateTime $date) : void{ @@ -134,8 +128,6 @@ class BanEntry{ * * @link https://bugs.php.net/bug.php?id=75992 * - * @param \DateTime $dateTime - * * @throws \InvalidArgumentException if the argument can't be parsed from a formatted date string */ private static function validateDate(\DateTime $dateTime) : void{ @@ -147,9 +139,6 @@ class BanEntry{ } /** - * @param string $date - * - * @return \DateTime * @throws \RuntimeException */ private static function parseDate(string $date) : \DateTime{ @@ -162,9 +151,6 @@ class BanEntry{ } /** - * @param string $str - * - * @return BanEntry|null * @throws \RuntimeException */ public static function fromString(string $str) : ?BanEntry{ diff --git a/src/permission/BanList.php b/src/permission/BanList.php index f3e4ee63bb..3b08a59910 100644 --- a/src/permission/BanList.php +++ b/src/permission/BanList.php @@ -42,32 +42,18 @@ class BanList{ /** @var bool */ private $enabled = true; - /** - * @param string $file - */ public function __construct(string $file){ $this->file = $file; } - /** - * @return bool - */ public function isEnabled() : bool{ return $this->enabled; } - /** - * @param bool $flag - */ public function setEnabled(bool $flag) : void{ $this->enabled = $flag; } - /** - * @param string $name - * - * @return BanEntry|null - */ public function getEntry(string $name) : ?BanEntry{ $this->removeExpired(); @@ -83,11 +69,6 @@ class BanList{ return $this->list; } - /** - * @param string $name - * - * @return bool - */ public function isBanned(string $name) : bool{ $name = strtolower($name); if(!$this->isEnabled()){ @@ -99,21 +80,15 @@ class BanList{ } } - /** - * @param BanEntry $entry - */ public function add(BanEntry $entry) : void{ $this->list[$entry->getName()] = $entry; $this->save(); } /** - * @param string $target * @param string $reason * @param \DateTime $expires * @param string $source - * - * @return BanEntry */ public function addBan(string $target, ?string $reason = null, ?\DateTime $expires = null, ?string $source = null) : BanEntry{ $entry = new BanEntry($target); @@ -127,9 +102,6 @@ class BanList{ return $entry; } - /** - * @param string $name - */ public function remove(string $name) : void{ $name = strtolower($name); if(isset($this->list[$name])){ @@ -170,9 +142,6 @@ class BanList{ } } - /** - * @param bool $writeHeader - */ public function save(bool $writeHeader = true) : void{ $this->removeExpired(); $fp = @fopen($this->file, "w"); diff --git a/src/permission/DefaultPermissions.php b/src/permission/DefaultPermissions.php index ea25519c7d..4daed435e8 100644 --- a/src/permission/DefaultPermissions.php +++ b/src/permission/DefaultPermissions.php @@ -27,10 +27,7 @@ abstract class DefaultPermissions{ public const ROOT = "pocketmine"; /** - * @param Permission $perm * @param Permission $parent - * - * @return Permission */ public static function registerPermission(Permission $perm, ?Permission $parent = null) : Permission{ if($parent instanceof Permission){ diff --git a/src/permission/Permissible.php b/src/permission/Permissible.php index a9065bc4cb..74874512f1 100644 --- a/src/permission/Permissible.php +++ b/src/permission/Permissible.php @@ -31,8 +31,6 @@ interface Permissible extends ServerOperator{ * Checks if this instance has a permission overridden * * @param string|Permission $name - * - * @return bool */ public function isPermissionSet($name) : bool; @@ -40,31 +38,17 @@ interface Permissible extends ServerOperator{ * Returns the permission value if overridden, or the default value if not * * @param string|Permission $name - * - * @return bool */ public function hasPermission($name) : bool; /** - * @param Plugin $plugin * @param string $name * @param bool $value - * - * @return PermissionAttachment */ public function addAttachment(Plugin $plugin, ?string $name = null, ?bool $value = null) : PermissionAttachment; - /** - * @param PermissionAttachment $attachment - * - * @return void - */ public function removeAttachment(PermissionAttachment $attachment) : void; - - /** - * @return void - */ public function recalculatePermissions() : void; /** diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index 3e2a96eeac..12d6519a0e 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -45,9 +45,6 @@ class PermissibleBase implements Permissible{ */ private $permissions = []; - /** - * @param ServerOperator $opable - */ public function __construct(ServerOperator $opable){ $this->opable = $opable; if($opable instanceof Permissible){ @@ -55,24 +52,16 @@ class PermissibleBase implements Permissible{ } } - /** - * @return bool - */ public function isOp() : bool{ return $this->opable->isOp(); } - /** - * @param bool $value - */ public function setOp(bool $value) : void{ $this->opable->setOp($value); } /** * @param Permission|string $name - * - * @return bool */ public function isPermissionSet($name) : bool{ return isset($this->permissions[$name instanceof Permission ? $name->getName() : $name]); @@ -80,8 +69,6 @@ class PermissibleBase implements Permissible{ /** * @param Permission|string $name - * - * @return bool */ public function hasPermission($name) : bool{ if($name instanceof Permission){ @@ -105,11 +92,8 @@ class PermissibleBase implements Permissible{ /** * //TODO: tick scheduled attachments * - * @param Plugin $plugin * @param string $name * @param bool $value - * - * @return PermissionAttachment */ public function addAttachment(Plugin $plugin, ?string $name = null, ?bool $value = null) : PermissionAttachment{ if(!$plugin->isEnabled()){ @@ -127,9 +111,6 @@ class PermissibleBase implements Permissible{ return $result; } - /** - * @param PermissionAttachment $attachment - */ public function removeAttachment(PermissionAttachment $attachment) : void{ if(isset($this->attachments[spl_object_id($attachment)])){ unset($this->attachments[spl_object_id($attachment)]); @@ -177,8 +158,6 @@ class PermissibleBase implements Permissible{ /** * @param bool[] $children - * @param bool $invert - * @param PermissionAttachment|null $attachment */ private function calculateChildPermissions(array $children, bool $invert, ?PermissionAttachment $attachment) : void{ $permManager = PermissionManager::getInstance(); diff --git a/src/permission/PermissibleDelegateTrait.php b/src/permission/PermissibleDelegateTrait.php index a6bab9e4c4..371651973e 100644 --- a/src/permission/PermissibleDelegateTrait.php +++ b/src/permission/PermissibleDelegateTrait.php @@ -30,11 +30,8 @@ trait PermissibleDelegateTrait{ /** @var PermissibleBase */ private $perm = null; - /** * @param Permission|string $name - * - * @return bool */ public function isPermissionSet($name) : bool{ return $this->perm->isPermissionSet($name); @@ -42,27 +39,19 @@ trait PermissibleDelegateTrait{ /** * @param Permission|string $name - * - * @return bool */ public function hasPermission($name) : bool{ return $this->perm->hasPermission($name); } /** - * @param Plugin $plugin * @param string $name * @param bool $value - * - * @return PermissionAttachment */ public function addAttachment(Plugin $plugin, ?string $name = null, ?bool $value = null) : PermissionAttachment{ return $this->perm->addAttachment($plugin, $name, $value); } - /** - * @param PermissionAttachment $attachment - */ public function removeAttachment(PermissionAttachment $attachment) : void{ $this->perm->removeAttachment($attachment); } diff --git a/src/permission/Permission.php b/src/permission/Permission.php index adca9f5a1b..63228658bc 100644 --- a/src/permission/Permission.php +++ b/src/permission/Permission.php @@ -56,7 +56,6 @@ class Permission{ /** * Creates a new Permission object to be attached to Permissible objects * - * @param string $name * @param string $description * @param string $defaultValue * @param bool[] $children @@ -70,9 +69,6 @@ class Permission{ $this->recalculatePermissibles(); } - /** - * @return string - */ public function getName() : string{ return $this->name; } @@ -84,16 +80,10 @@ class Permission{ return $this->children; } - /** - * @return string - */ public function getDefault() : string{ return $this->defaultValue; } - /** - * @param string $value - */ public function setDefault(string $value) : void{ if($value !== $this->defaultValue){ $this->defaultValue = $value; @@ -101,16 +91,10 @@ class Permission{ } } - /** - * @return string - */ public function getDescription() : string{ return $this->description; } - /** - * @param string $value - */ public function setDescription(string $value) : void{ $this->description = $value; } @@ -132,10 +116,8 @@ class Permission{ } } - /** * @param string|Permission $name - * @param bool $value * * @return Permission|null Permission if $name is a string, null if it's a Permission */ diff --git a/src/permission/PermissionAttachment.php b/src/permission/PermissionAttachment.php index 7697503710..adea709191 100644 --- a/src/permission/PermissionAttachment.php +++ b/src/permission/PermissionAttachment.php @@ -42,9 +42,6 @@ class PermissionAttachment{ private $plugin; /** - * @param Plugin $plugin - * @param Permissible $permissible - * * @throws PluginException */ public function __construct(Plugin $plugin, Permissible $permissible){ @@ -56,30 +53,18 @@ class PermissionAttachment{ $this->plugin = $plugin; } - /** - * @return Plugin - */ public function getPlugin() : Plugin{ return $this->plugin; } - /** - * @param PermissionRemovedExecutor $ex - */ public function setRemovalCallback(PermissionRemovedExecutor $ex) : void{ $this->removed = $ex; } - /** - * @return PermissionRemovedExecutor|null - */ public function getRemovalCallback() : ?PermissionRemovedExecutor{ return $this->removed; } - /** - * @return Permissible - */ public function getPermissible() : Permissible{ return $this->permissible; } @@ -118,7 +103,6 @@ class PermissionAttachment{ /** * @param string|Permission $name - * @param bool $value */ public function setPermission($name, bool $value) : void{ $name = $name instanceof Permission ? $name->getName() : $name; @@ -143,9 +127,6 @@ class PermissionAttachment{ } } - /** - * @return void - */ public function remove() : void{ $this->permissible->removeAttachment($this); } diff --git a/src/permission/PermissionAttachmentInfo.php b/src/permission/PermissionAttachmentInfo.php index 002a480d44..57297a11cf 100644 --- a/src/permission/PermissionAttachmentInfo.php +++ b/src/permission/PermissionAttachmentInfo.php @@ -38,11 +38,6 @@ class PermissionAttachmentInfo{ private $value; /** - * @param Permissible $permissible - * @param string $permission - * @param PermissionAttachment|null $attachment - * @param bool $value - * * @throws \InvalidStateException */ public function __construct(Permissible $permissible, string $permission, ?PermissionAttachment $attachment, bool $value){ @@ -52,30 +47,18 @@ class PermissionAttachmentInfo{ $this->value = $value; } - /** - * @return Permissible - */ public function getPermissible() : Permissible{ return $this->permissible; } - /** - * @return string - */ public function getPermission() : string{ return $this->permission; } - /** - * @return PermissionAttachment|null - */ public function getAttachment() : ?PermissionAttachment{ return $this->attachment; } - /** - * @return bool - */ public function getValue() : bool{ return $this->value; } diff --git a/src/permission/PermissionManager.php b/src/permission/PermissionManager.php index fd11008778..b0c57373f4 100644 --- a/src/permission/PermissionManager.php +++ b/src/permission/PermissionManager.php @@ -52,20 +52,10 @@ class PermissionManager{ /** @var Permissible[] */ protected $defSubsOp = []; - /** - * @param string $name - * - * @return null|Permission - */ public function getPermission(string $name) : ?Permission{ return $this->permissions[$name] ?? null; } - /** - * @param Permission $permission - * - * @return bool - */ public function addPermission(Permission $permission) : bool{ if(!isset($this->permissions[$permission->getName()])){ $this->permissions[$permission->getName()] = $permission; @@ -89,8 +79,6 @@ class PermissionManager{ } /** - * @param bool $op - * * @return Permission[] */ public function getDefaultPermissions(bool $op) : array{ @@ -101,9 +89,6 @@ class PermissionManager{ } } - /** - * @param Permission $permission - */ public function recalculatePermissionDefaults(Permission $permission) : void{ if(isset($this->permissions[$permission->getName()])){ unset($this->defaultPermsOp[$permission->getName()]); @@ -112,9 +97,6 @@ class PermissionManager{ } } - /** - * @param Permission $permission - */ private function calculatePermissionDefault(Permission $permission) : void{ Timings::$permissionDefaultTimer->startTiming(); if($permission->getDefault() === Permission::DEFAULT_OP or $permission->getDefault() === Permission::DEFAULT_TRUE){ @@ -129,19 +111,12 @@ class PermissionManager{ Timings::$permissionDefaultTimer->startTiming(); } - /** - * @param bool $op - */ private function dirtyPermissibles(bool $op) : void{ foreach($this->getDefaultPermSubscriptions($op) as $p){ $p->recalculatePermissions(); } } - /** - * @param string $permission - * @param Permissible $permissible - */ public function subscribeToPermission(string $permission, Permissible $permissible) : void{ if(!isset($this->permSubs[$permission])){ $this->permSubs[$permission] = []; @@ -149,10 +124,6 @@ class PermissionManager{ $this->permSubs[$permission][spl_object_id($permissible)] = $permissible; } - /** - * @param string $permission - * @param Permissible $permissible - */ public function unsubscribeFromPermission(string $permission, Permissible $permissible) : void{ if(isset($this->permSubs[$permission])){ unset($this->permSubs[$permission][spl_object_id($permissible)]); @@ -162,9 +133,6 @@ class PermissionManager{ } } - /** - * @param Permissible $permissible - */ public function unsubscribeFromAllPermissions(Permissible $permissible) : void{ foreach($this->permSubs as $permission => &$subs){ unset($subs[spl_object_id($permissible)]); @@ -175,18 +143,12 @@ class PermissionManager{ } /** - * @param string $permission - * * @return array|Permissible[] */ public function getPermissionSubscriptions(string $permission) : array{ return $this->permSubs[$permission] ?? []; } - /** - * @param bool $op - * @param Permissible $permissible - */ public function subscribeToDefaultPerms(bool $op, Permissible $permissible) : void{ if($op){ $this->defSubsOp[spl_object_id($permissible)] = $permissible; @@ -195,10 +157,6 @@ class PermissionManager{ } } - /** - * @param bool $op - * @param Permissible $permissible - */ public function unsubscribeFromDefaultPerms(bool $op, Permissible $permissible) : void{ if($op){ unset($this->defSubsOp[spl_object_id($permissible)]); @@ -208,8 +166,6 @@ class PermissionManager{ } /** - * @param bool $op - * * @return Permissible[] */ public function getDefaultPermSubscriptions(bool $op) : array{ diff --git a/src/permission/PermissionParser.php b/src/permission/PermissionParser.php index bf9d83840d..36c4182bf7 100644 --- a/src/permission/PermissionParser.php +++ b/src/permission/PermissionParser.php @@ -33,8 +33,6 @@ class PermissionParser{ /** * @param bool|string $value * - * @return string - * * @throws \InvalidArgumentException */ public static function defaultFromString($value) : string{ @@ -72,9 +70,6 @@ class PermissionParser{ } /** - * @param array $data - * @param string $default - * * @return Permission[] */ public static function loadPermissions(array $data, string $default = Permission::DEFAULT_OP) : array{ @@ -87,13 +82,6 @@ class PermissionParser{ } /** - * @param string $name - * @param array $data - * @param string $default - * @param array $output - * - * @return Permission - * * @throws \Exception */ public static function loadPermission(string $name, array $data, string $default = Permission::DEFAULT_OP, array &$output = []) : Permission{ @@ -127,8 +115,6 @@ class PermissionParser{ /** * @param Permission[] $permissions - * - * @return array */ public static function emitPermissions(array $permissions) : array{ $result = []; diff --git a/src/permission/PermissionRemovedExecutor.php b/src/permission/PermissionRemovedExecutor.php index 0298f1bfac..71076d94dc 100644 --- a/src/permission/PermissionRemovedExecutor.php +++ b/src/permission/PermissionRemovedExecutor.php @@ -26,10 +26,5 @@ namespace pocketmine\permission; interface PermissionRemovedExecutor{ - /** - * @param PermissionAttachment $attachment - * - * @return void - */ public function attachmentRemoved(PermissionAttachment $attachment) : void; } diff --git a/src/permission/ServerOperator.php b/src/permission/ServerOperator.php index 55601af288..c9fe3afd84 100644 --- a/src/permission/ServerOperator.php +++ b/src/permission/ServerOperator.php @@ -27,15 +27,11 @@ namespace pocketmine\permission; interface ServerOperator{ /** * Checks if the current object has operator permissions - * - * @return bool */ public function isOp() : bool; /** * Sets the operator permission for the current object - * - * @param bool $value */ public function setOp(bool $value) : void; } diff --git a/src/player/GameMode.php b/src/player/GameMode.php index b294dd5ae1..7b99f5a811 100644 --- a/src/player/GameMode.php +++ b/src/player/GameMode.php @@ -70,8 +70,6 @@ final class GameMode{ } /** - * @param int $n - * * @return GameMode * @throws \InvalidArgumentException */ @@ -100,23 +98,14 @@ final class GameMode{ $this->aliases = $aliases; } - /** - * @return int - */ public function getMagicNumber() : int{ return $this->magicNumber; } - /** - * @return string - */ public function getEnglishName() : string{ return $this->englishName; } - /** - * @return string - */ public function getTranslationKey() : string{ return "%" . $this->translationKey; } diff --git a/src/player/IPlayer.php b/src/player/IPlayer.php index 5ba4168917..66609474a9 100644 --- a/src/player/IPlayer.php +++ b/src/player/IPlayer.php @@ -27,54 +27,24 @@ use pocketmine\permission\ServerOperator; interface IPlayer extends ServerOperator{ - /** - * @return bool - */ public function isOnline() : bool; - /** - * @return string - */ public function getName() : string; - /** - * @return bool - */ public function isBanned() : bool; - /** - * @param bool $banned - */ public function setBanned(bool $banned) : void; - /** - * @return bool - */ public function isWhitelisted() : bool; - /** - * @param bool $value - */ public function setWhitelisted(bool $value) : void; - /** - * @return Player|null - */ public function getPlayer() : ?Player; - /** - * @return int|null - */ public function getFirstPlayed() : ?int; - /** - * @return int|null - */ public function getLastPlayed() : ?int; - /** - * @return bool - */ public function hasPlayedBefore() : bool; } diff --git a/src/player/OfflinePlayer.php b/src/player/OfflinePlayer.php index 8dcca0a88f..a85b657c95 100644 --- a/src/player/OfflinePlayer.php +++ b/src/player/OfflinePlayer.php @@ -36,10 +36,6 @@ class OfflinePlayer implements IPlayer{ /** @var CompoundTag|null */ private $namedtag = null; - /** - * @param Server $server - * @param string $name - */ public function __construct(Server $server, string $name){ $this->server = $server; $this->name = $name; diff --git a/src/player/Player.php b/src/player/Player.php index fe1989d133..49f9f1bf32 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -138,8 +138,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * Validates the given username. * * @param string $name - * - * @return bool */ public static function isValidUserName(?string $name) : bool{ if($name === null){ @@ -248,12 +246,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** @var \Logger */ protected $logger; - /** - * @param Server $server - * @param NetworkSession $session - * @param PlayerInfo $playerInfo - * @param bool $authenticated - */ public function __construct(Server $server, NetworkSession $session, PlayerInfo $playerInfo, bool $authenticated){ $username = TextFormat::clean($playerInfo->getUsername()); $this->logger = new \PrefixedLogger($server->getLogger(), "Player: $username"); @@ -412,8 +404,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * If the player is logged into Xbox Live, returns their Xbox user ID (XUID) as a string. Returns an empty string if * the player is not logged into Xbox Live. - * - * @return string */ public function getXuid() : string{ return $this->xuid; @@ -433,8 +423,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * (In the olden days this method used to return a fake UUID computed by the server, which was used by plugins such * as SimpleAuth for authentication. This is NOT SAFE anymore as this UUID is now what was given by the client, NOT * a server-computed UUID.) - * - * @return UUID */ public function getUniqueId() : UUID{ return parent::getUniqueId(); @@ -446,7 +434,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * TODO: not sure this should be nullable - * @return int|null */ public function getFirstPlayed() : ?int{ return $this->firstPlayed; @@ -454,7 +441,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * TODO: not sure this should be nullable - * @return int|null */ public function getLastPlayed() : ?int{ return $this->lastPlayed; @@ -494,32 +480,20 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->autoJump; } - /** - * @param Player $player - */ public function spawnTo(Player $player) : void{ if($this->isAlive() and $player->isAlive() and $player->getWorld() === $this->getWorld() and $player->canSee($this) and !$this->isSpectator()){ parent::spawnTo($player); } } - /** - * @return Server - */ public function getServer() : Server{ return $this->server; } - /** - * @return bool - */ public function getRemoveFormat() : bool{ return $this->removeFormat; } - /** - * @param bool $remove - */ public function setRemoveFormat(bool $remove = true) : void{ $this->removeFormat = $remove; } @@ -535,18 +509,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->lineHeight = $height; } - /** - * @param Player $player - * - * @return bool - */ public function canSee(Player $player) : bool{ return !isset($this->hiddenPlayers[$player->getUniqueId()->toBinary()]); } - /** - * @param Player $player - */ public function hidePlayer(Player $player) : void{ if($player === $this){ return; @@ -555,9 +521,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $player->despawnFrom($this); } - /** - * @param Player $player - */ public function showPlayer(Player $player) : void{ if($player === $this){ return; @@ -597,23 +560,14 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->logger->debug("Setting view distance to " . $this->viewDistance . " (requested " . $distance . ")"); } - /** - * @return bool - */ public function isOnline() : bool{ return $this->isConnected(); } - /** - * @return bool - */ public function isOp() : bool{ return $this->server->isOp($this->getName()); } - /** - * @param bool $value - */ public function setOp(bool $value) : void{ if($value === $this->isOp()){ return; @@ -651,23 +605,16 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } - /** - * @return bool - */ public function isConnected() : bool{ return $this->networkSession !== null and $this->networkSession->isConnected(); } - /** - * @return NetworkSession - */ public function getNetworkSession() : NetworkSession{ return $this->networkSession; } /** * Gets the username - * @return string */ public function getName() : string{ return $this->username; @@ -675,23 +622,17 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Returns the "friendly" display name of this player to use in the chat. - * - * @return string */ public function getDisplayName() : string{ return $this->displayName; } - /** - * @param string $name - */ public function setDisplayName(string $name) : void{ $this->displayName = $name; } /** * Returns the player's locale, e.g. en_US. - * @return string */ public function getLocale() : string{ return $this->locale; @@ -700,12 +641,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Called when a player changes their skin. * Plugin developers should not use this, use setSkin() and sendSkin() instead. - * - * @param Skin $skin - * @param string $newSkinName - * @param string $oldSkinName - * - * @return bool */ public function changeSkin(Skin $skin, string $newSkinName, string $oldSkinName) : bool{ $ev = new PlayerChangeSkinEvent($this, $this->getSkin(), $skin); @@ -732,7 +667,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Returns whether the player is currently using an item (right-click and hold). - * @return bool */ public function isUsingItem() : bool{ return $this->startAction > -1; @@ -745,8 +679,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Returns how long the player has been using their currently-held item for. Used for determining arrow shoot force * for bows. - * - * @return int */ public function getItemUseDuration() : int{ return $this->startAction === -1 ? -1 : ($this->server->getTick() - $this->startAction); @@ -754,10 +686,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Returns whether the player has a cooldown period left before it can use the given item again. - * - * @param Item $item - * - * @return bool */ public function hasItemCooldown(Item $item) : bool{ $this->checkItemCooldowns(); @@ -766,8 +694,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Resets the player's cooldown time for the given item back to the maximum. - * - * @param Item $item */ public function resetItemCooldown(Item $item) : void{ $ticks = $item->getCooldownTicks(); @@ -1010,9 +936,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } - /** - * @return bool - */ public function hasValidSpawnPosition() : bool{ return $this->spawnPosition !== null and $this->spawnPosition->isValid(); } @@ -1033,18 +956,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->networkSession->syncPlayerSpawnPoint($this->spawnPosition); } - /** - * @return bool - */ public function isSleeping() : bool{ return $this->sleeping !== null; } - /** - * @param Vector3 $pos - * - * @return bool - */ public function sleepOn(Vector3 $pos) : bool{ $pos = $pos->floor(); $b = $this->getWorld()->getBlock($pos); @@ -1084,9 +999,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } - /** - * @return GameMode - */ public function getGamemode() : GameMode{ return $this->gamemode; } @@ -1106,10 +1018,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Sets the gamemode, and if needed, kicks the Player. - * - * @param GameMode $gm - * - * @return bool */ public function setGamemode(GameMode $gm) : bool{ if($this->gamemode->equals($gm)){ @@ -1139,8 +1047,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * in Adventure Mode. Supply the $literal parameter as true to force a literal Survival Mode check. * * @param bool $literal whether a literal check should be performed - * - * @return bool */ public function isSurvival(bool $literal = false) : bool{ return $this->gamemode->equals(GameMode::SURVIVAL()) or (!$literal and $this->gamemode->equals(GameMode::ADVENTURE())); @@ -1151,8 +1057,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * in Spectator Mode. Supply the $literal parameter as true to force a literal Creative Mode check. * * @param bool $literal whether a literal check should be performed - * - * @return bool */ public function isCreative(bool $literal = false) : bool{ return $this->gamemode->equals(GameMode::CREATIVE()) or (!$literal and $this->gamemode->equals(GameMode::SPECTATOR())); @@ -1163,24 +1067,17 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * in Spectator Mode. Supply the $literal parameter as true to force a literal Adventure Mode check. * * @param bool $literal whether a literal check should be performed - * - * @return bool */ public function isAdventure(bool $literal = false) : bool{ return $this->gamemode->equals(GameMode::ADVENTURE()) or (!$literal and $this->gamemode->equals(GameMode::SPECTATOR())); } - /** - * @return bool - */ public function isSpectator() : bool{ return $this->gamemode->equals(GameMode::SPECTATOR()); } /** * TODO: make this a dynamic ability instead of being hardcoded - * - * @return bool */ public function hasFiniteResources() : bool{ return $this->gamemode->equals(GameMode::SURVIVAL()) or $this->gamemode->equals(GameMode::ADVENTURE()); @@ -1233,8 +1130,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Returns the location that the player wants to be in at the end of this tick. Note that this may not be their * actual result position at the end due to plugin interference or a range of other things. - * - * @return Vector3 */ public function getNextPosition() : Vector3{ return $this->newPosition !== null ? clone $this->newPosition : $this->location->asVector3(); @@ -1438,11 +1333,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Returns whether the player can interact with the specified position. This checks distance and direction. * - * @param Vector3 $pos - * @param float $maxDistance * @param float $maxDiff defaults to half of the 3D diagonal width of a block - * - * @return bool */ public function canInteract(Vector3 $pos, float $maxDistance, float $maxDiff = M_SQRT3 / 2) : bool{ $eyePos = $this->getEyePos(); @@ -1459,10 +1350,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Sends a chat message as this player. If the message begins with a / (forward-slash) it will be treated * as a command. - * - * @param string $message - * - * @return bool */ public function chat(string $message) : bool{ $this->doCloseInventory(); @@ -1654,9 +1541,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Performs a left-click (attack) action on the block. * - * @param Vector3 $pos - * @param int $face - * * @return bool if an action took place successfully */ public function attackBlock(Vector3 $pos, int $face) : bool{ @@ -1708,8 +1592,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Breaks the block at the given position using the currently-held item. * - * @param Vector3 $pos - * * @return bool if the block was successfully broken, false if a rollback needs to take place. */ public function breakBlock(Vector3 $pos) : bool{ @@ -1734,10 +1616,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Touches the block at the given position with the currently-held item. * - * @param Vector3 $pos - * @param int $face - * @param Vector3 $clickOffset - * * @return bool if it did something */ public function interactBlock(Vector3 $pos, int $face, Vector3 $clickOffset) : bool{ @@ -1762,8 +1640,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * Attacks the given entity with the currently-held item. * TODO: move this up the class hierarchy * - * @param Entity $entity - * * @return bool if the entity was dealt damage */ public function attackEntity(Entity $entity) : bool{ @@ -1831,11 +1707,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Interacts with the given entity using the currently-held item. - * - * @param Entity $entity - * @param Vector3 $clickPos - * - * @return bool */ public function interactEntity(Entity $entity, Vector3 $clickPos) : bool{ //TODO @@ -1877,8 +1748,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Drops an item on the ground in front of the player. - * - * @param Item $item */ public function dropItem(Item $item) : void{ $this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers()); @@ -1888,8 +1757,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Adds a title text to the user's screen, with an optional subtitle. * - * @param string $title - * @param string $subtitle * @param int $fadeIn Duration in ticks for fade-in. If -1 is given, client-sided defaults will be used. * @param int $stay Duration in ticks to stay on screen for * @param int $fadeOut Duration in ticks for fade-out. @@ -1904,8 +1771,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Sets the subtitle message, without sending a title. - * - * @param string $subtitle */ public function sendSubTitle(string $subtitle) : void{ $this->networkSession->onSubTitle($subtitle); @@ -1913,8 +1778,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Adds small text to the user's screen. - * - * @param string $message */ public function sendActionBarMessage(string $message) : void{ $this->networkSession->onActionBar($message); @@ -1965,7 +1828,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } /** - * @param string $message * @param string[] $parameters */ public function sendTranslation(string $message, array $parameters = []) : void{ @@ -1983,8 +1845,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * Sends a popup message to the player * * TODO: add translation type popups - * - * @param string $message */ public function sendPopup(string $message) : void{ $this->networkSession->onPopup($message); @@ -1997,8 +1857,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Sends a Form to the player, or queue to send it if a form is already open. * - * @param Form $form - * * @throws \InvalidArgumentException */ public function sendForm(Form $form) : void{ @@ -2009,10 +1867,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } /** - * @param int $formId * @param mixed $responseData - * - * @return bool */ public function onFormSubmit(int $formId, $responseData) : bool{ if(!isset($this->forms[$formId])){ @@ -2055,11 +1910,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Kicks a player from the server * - * @param string $reason - * @param bool $isAdmin * @param TextContainer|string $quitMessage - * - * @return bool */ public function kick(string $reason = "", bool $isAdmin = true, $quitMessage = null) : bool{ $ev = new PlayerKickEvent($this, $reason, $quitMessage ?? $this->getLeaveMessage()); @@ -2093,7 +1944,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * * @param string $reason Shown to the player, usually this will appear on their disconnect screen. * @param TextContainer|string $quitMessage Message to broadcast to online players (null will use default) - * @param bool $notify */ public function disconnect(string $reason, $quitMessage = null, bool $notify = true) : void{ if(!$this->isConnected()){ @@ -2347,11 +2197,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * TODO: remove this - * - * @param Vector3 $pos - * @param float|null $yaw - * @param float|null $pitch - * @param int $mode */ public function sendPosition(Vector3 $pos, ?float $yaw = null, ?float $pitch = null, int $mode = MovePlayerPacket::MODE_NORMAL) : void{ $this->networkSession->syncMovement($pos, $yaw, $pitch, $mode); @@ -2407,9 +2252,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->craftingGrid; } - /** - * @param CraftingGrid $grid - */ public function setCraftingGrid(CraftingGrid $grid) : void{ $this->craftingGrid = $grid; } @@ -2440,8 +2282,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Returns the inventory the player is currently viewing. This might be a chest, furnace, or any other container. - * - * @return Inventory|null */ public function getCurrentWindow() : ?Inventory{ return $this->currentWindow; @@ -2449,10 +2289,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Opens an inventory window to the player. Returns if it was successful. - * - * @param Inventory $inventory - * - * @return bool */ public function setCurrentWindow(Inventory $inventory) : bool{ if($inventory === $this->currentWindow){ diff --git a/src/player/PlayerInfo.php b/src/player/PlayerInfo.php index e25b50e317..285294ddf6 100644 --- a/src/player/PlayerInfo.php +++ b/src/player/PlayerInfo.php @@ -45,14 +45,6 @@ class PlayerInfo{ /** @var array */ private $extraData; - /** - * @param string $username - * @param UUID $uuid - * @param Skin $skin - * @param string $locale - * @param string $xuid - * @param array $extraData - */ public function __construct(string $username, UUID $uuid, Skin $skin, string $locale, string $xuid, array $extraData = []){ $this->username = TextFormat::clean($username); $this->uuid = $uuid; @@ -62,44 +54,26 @@ class PlayerInfo{ $this->extraData = $extraData; } - /** - * @return string - */ public function getUsername() : string{ return $this->username; } - /** - * @return UUID - */ public function getUuid() : UUID{ return $this->uuid; } - /** - * @return Skin - */ public function getSkin() : Skin{ return $this->skin; } - /** - * @return string - */ public function getLocale() : string{ return $this->locale; } - /** - * @return string - */ public function getXuid() : string{ return $this->xuid; } - /** - * @return array - */ public function getExtraData() : array{ return $this->extraData; } diff --git a/src/plugin/ApiVersion.php b/src/plugin/ApiVersion.php index e935fa0fbb..be2d2ca078 100644 --- a/src/plugin/ApiVersion.php +++ b/src/plugin/ApiVersion.php @@ -36,10 +36,7 @@ final class ApiVersion{ } /** - * @param string $myVersionStr * @param string[] $wantVersionsStr - * - * @return bool */ public static function isCompatible(string $myVersionStr, array $wantVersionsStr) : bool{ $myVersion = new VersionString($myVersionStr); diff --git a/src/plugin/DiskResourceProvider.php b/src/plugin/DiskResourceProvider.php index c3487bb396..31016110f9 100644 --- a/src/plugin/DiskResourceProvider.php +++ b/src/plugin/DiskResourceProvider.php @@ -49,8 +49,6 @@ class DiskResourceProvider implements ResourceProvider{ * Gets an embedded resource on the plugin file. * WARNING: You must close the resource given using fclose() * - * @param string $filename - * * @return null|resource Resource data, or null */ public function getResource(string $filename){ diff --git a/src/plugin/PharPluginLoader.php b/src/plugin/PharPluginLoader.php index c0220a714e..98b3bed079 100644 --- a/src/plugin/PharPluginLoader.php +++ b/src/plugin/PharPluginLoader.php @@ -46,8 +46,6 @@ class PharPluginLoader implements PluginLoader{ /** * Loads the plugin contained in $file - * - * @param string $file */ public function loadPlugin(string $file) : void{ $this->loader->addPath("$file/src"); @@ -55,10 +53,6 @@ class PharPluginLoader implements PluginLoader{ /** * Gets the PluginDescription from the file - * - * @param string $file - * - * @return null|PluginDescription */ public function getPluginDescription(string $file) : ?PluginDescription{ $phar = new \Phar($file); diff --git a/src/plugin/Plugin.php b/src/plugin/Plugin.php index 7b6328e414..12ed87dde9 100644 --- a/src/plugin/Plugin.php +++ b/src/plugin/Plugin.php @@ -36,9 +36,6 @@ interface Plugin{ public function __construct(PluginLoader $loader, Server $server, PluginDescription $description, string $dataFolder, string $file, ResourceProvider $resourceProvider); - /** - * @return bool - */ public function isEnabled() : bool; /** @@ -47,52 +44,27 @@ interface Plugin{ * @internal This is intended for core use only and should not be used by plugins * @see PluginManager::enablePlugin() * @see PluginManager::disablePlugin() - * - * @param bool $enabled */ public function onEnableStateChange(bool $enabled) : void; - /** - * @return bool - */ public function isDisabled() : bool; /** * Gets the plugin's data folder to save files and configuration. * This directory name has a trailing slash. - * - * @return string */ public function getDataFolder() : string; - /** - * @return PluginDescription - */ public function getDescription() : PluginDescription; - /** - * @return Server - */ public function getServer() : Server; - /** - * @return string - */ public function getName() : string; - /** - * @return \AttachableLogger - */ public function getLogger() : \AttachableLogger; - /** - * @return PluginLoader - */ public function getPluginLoader() : PluginLoader; - /** - * @return TaskScheduler - */ public function getScheduler() : TaskScheduler; } diff --git a/src/plugin/PluginBase.php b/src/plugin/PluginBase.php index dbc51b9800..e4f25612ce 100644 --- a/src/plugin/PluginBase.php +++ b/src/plugin/PluginBase.php @@ -126,9 +126,6 @@ abstract class PluginBase implements Plugin, CommandExecutor{ } - /** - * @return bool - */ final public function isEnabled() : bool{ return $this->isEnabled; } @@ -139,8 +136,6 @@ abstract class PluginBase implements Plugin, CommandExecutor{ * @internal This is intended for core use only and should not be used by plugins * @see PluginManager::enablePlugin() * @see PluginManager::disablePlugin() - * - * @param bool $enabled */ final public function onEnableStateChange(bool $enabled) : void{ if($this->isEnabled !== $enabled){ @@ -153,9 +148,6 @@ abstract class PluginBase implements Plugin, CommandExecutor{ } } - /** - * @return bool - */ final public function isDisabled() : bool{ return !$this->isEnabled; } @@ -168,9 +160,6 @@ abstract class PluginBase implements Plugin, CommandExecutor{ return $this->description; } - /** - * @return \AttachableLogger - */ public function getLogger() : \AttachableLogger{ return $this->logger; } @@ -233,8 +222,6 @@ abstract class PluginBase implements Plugin, CommandExecutor{ } /** - * @param string $name - * * @return Command|PluginIdentifiableCommand|null */ public function getCommand(string $name){ @@ -251,12 +238,7 @@ abstract class PluginBase implements Plugin, CommandExecutor{ } /** - * @param CommandSender $sender - * @param Command $command - * @param string $label * @param string[] $args - * - * @return bool */ public function onCommand(CommandSender $sender, Command $command, string $label, array $args) : bool{ return false; @@ -266,8 +248,6 @@ abstract class PluginBase implements Plugin, CommandExecutor{ * Gets an embedded resource on the plugin file. * WARNING: You must close the resource given using fclose() * - * @param string $filename - * * @return null|resource Resource data, or null */ public function getResource(string $filename){ @@ -276,11 +256,6 @@ abstract class PluginBase implements Plugin, CommandExecutor{ /** * Saves an embedded resource to its relative location in the data folder - * - * @param string $filename - * @param bool $replace - * - * @return bool */ public function saveResource(string $filename, bool $replace = false) : bool{ if(trim($filename) === ""){ @@ -315,9 +290,6 @@ abstract class PluginBase implements Plugin, CommandExecutor{ return $this->resourceProvider->getResources(); } - /** - * @return Config - */ public function getConfig() : Config{ if($this->config === null){ $this->reloadConfig(); @@ -342,44 +314,26 @@ abstract class PluginBase implements Plugin, CommandExecutor{ $this->config = new Config($this->configFile); } - /** - * @return Server - */ final public function getServer() : Server{ return $this->server; } - /** - * @return string - */ final public function getName() : string{ return $this->description->getName(); } - /** - * @return string - */ final public function getFullName() : string{ return $this->description->getFullName(); } - /** - * @return string - */ protected function getFile() : string{ return $this->file; } - /** - * @return PluginLoader - */ public function getPluginLoader() : PluginLoader{ return $this->loader; } - /** - * @return TaskScheduler - */ public function getScheduler() : TaskScheduler{ return $this->scheduler; } diff --git a/src/plugin/PluginDescription.php b/src/plugin/PluginDescription.php index 0a6fe602a8..ec2bfbba2a 100644 --- a/src/plugin/PluginDescription.php +++ b/src/plugin/PluginDescription.php @@ -86,8 +86,6 @@ class PluginDescription{ } /** - * @param array $plugin - * * @throws PluginException */ private function loadMap(array $plugin) : void{ @@ -161,16 +159,10 @@ class PluginDescription{ } } - /** - * @return string - */ public function getFullName() : string{ return $this->name . " v" . $this->version; } - /** - * @return array - */ public function getCompatibleApis() : array{ return $this->api; } @@ -189,16 +181,10 @@ class PluginDescription{ return $this->authors; } - /** - * @return string - */ public function getPrefix() : string{ return $this->prefix; } - /** - * @return array - */ public function getCommands() : array{ return $this->commands; } @@ -244,44 +230,26 @@ class PluginDescription{ } } - /** - * @return array - */ public function getDepend() : array{ return $this->depend; } - /** - * @return string - */ public function getDescription() : string{ return $this->description; } - /** - * @return array - */ public function getLoadBefore() : array{ return $this->loadBefore; } - /** - * @return string - */ public function getMain() : string{ return $this->main; } - /** - * @return string - */ public function getName() : string{ return $this->name; } - /** - * @return PluginLoadOrder - */ public function getOrder() : PluginLoadOrder{ return $this->order; } @@ -293,23 +261,14 @@ class PluginDescription{ return $this->permissions; } - /** - * @return array - */ public function getSoftDepend() : array{ return $this->softDepend; } - /** - * @return string - */ public function getVersion() : string{ return $this->version; } - /** - * @return string - */ public function getWebsite() : string{ return $this->website; } diff --git a/src/plugin/PluginGraylist.php b/src/plugin/PluginGraylist.php index 2438b8281a..c7ab8c88ac 100644 --- a/src/plugin/PluginGraylist.php +++ b/src/plugin/PluginGraylist.php @@ -48,19 +48,12 @@ class PluginGraylist{ return array_flip($this->plugins); } - /** - * @return bool - */ public function isWhitelist() : bool{ return $this->isWhitelist; } /** * Returns whether the given name is permitted by this graylist. - * - * @param string $name - * - * @return bool */ public function isAllowed(string $name) : bool{ return $this->isWhitelist() === isset($this->plugins[$name]); diff --git a/src/plugin/PluginLoader.php b/src/plugin/PluginLoader.php index 7e019c46c0..2bf603ddeb 100644 --- a/src/plugin/PluginLoader.php +++ b/src/plugin/PluginLoader.php @@ -30,33 +30,21 @@ interface PluginLoader{ /** * Returns whether this PluginLoader can load the plugin in the given path. - * - * @param string $path - * - * @return bool */ public function canLoadPlugin(string $path) : bool; /** * Loads the plugin contained in $file - * - * @param string $file */ public function loadPlugin(string $file) : void; /** * Gets the PluginDescription from the file - * - * @param string $file - * - * @return null|PluginDescription */ public function getPluginDescription(string $file) : ?PluginDescription; /** * Returns the protocol prefix used to access files in this plugin, e.g. file://, phar:// - * - * @return string */ public function getAccessProtocol() : string; } diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index e30a275342..ee5810dd7f 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -87,11 +87,6 @@ class PluginManager{ /** @var PluginGraylist|null */ private $graylist; - /** - * @param Server $server - * @param null|string $pluginDataDirectory - * @param PluginGraylist|null $graylist - */ public function __construct(Server $server, ?string $pluginDataDirectory, ?PluginGraylist $graylist = null){ $this->server = $server; $this->pluginDataDirectory = $pluginDataDirectory; @@ -106,11 +101,6 @@ class PluginManager{ $this->graylist = $graylist; } - /** - * @param string $name - * - * @return null|Plugin - */ public function getPlugin(string $name) : ?Plugin{ if(isset($this->plugins[$name])){ return $this->plugins[$name]; @@ -119,9 +109,6 @@ class PluginManager{ return null; } - /** - * @param PluginLoader $loader - */ public function registerInterface(PluginLoader $loader) : void{ $this->fileAssociations[get_class($loader)] = $loader; } @@ -141,10 +128,7 @@ class PluginManager{ } /** - * @param string $path * @param PluginLoader[] $loaders - * - * @return Plugin|null */ public function loadPlugin(string $path, ?array $loaders = null) : ?Plugin{ foreach($loaders ?? $this->fileAssociations as $loader){ @@ -197,7 +181,6 @@ class PluginManager{ } /** - * @param string $directory * @param array $newLoaders * * @return Plugin[] @@ -372,8 +355,6 @@ class PluginManager{ * Returns whether a specified API version string is considered compatible with the server's API version. * * @param string ...$versions - * - * @return bool */ public function isCompatibleApi(string ...$versions) : bool{ $serverString = $this->server->getApiVersion(); @@ -411,18 +392,10 @@ class PluginManager{ return false; } - /** - * @param Plugin $plugin - * - * @return bool - */ public function isPluginEnabled(Plugin $plugin) : bool{ return isset($this->plugins[$plugin->getDescription()->getName()]) and $plugin->isEnabled(); } - /** - * @param Plugin $plugin - */ public function enablePlugin(Plugin $plugin) : void{ if(!$plugin->isEnabled()){ $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.plugin.enable", [$plugin->getDescription()->getFullName()])); @@ -446,9 +419,6 @@ class PluginManager{ } } - /** - * @param Plugin $plugin - */ public function disablePlugin(Plugin $plugin) : void{ if($plugin->isEnabled()){ $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.plugin.disable", [$plugin->getDescription()->getFullName()])); @@ -482,9 +452,6 @@ class PluginManager{ /** * Registers all the events in the given Listener class * - * @param Listener $listener - * @param Plugin $plugin - * * @throws PluginException */ public function registerEvents(Listener $listener, Plugin $plugin) : void{ @@ -548,10 +515,6 @@ class PluginManager{ /** * @param string $event Class name that extends Event - * @param \Closure $handler - * @param int $priority - * @param Plugin $plugin - * @param bool $handleCancelled * * @throws \ReflectionException */ diff --git a/src/plugin/ResourceProvider.php b/src/plugin/ResourceProvider.php index 2e4a3e0f08..fd2f29b627 100644 --- a/src/plugin/ResourceProvider.php +++ b/src/plugin/ResourceProvider.php @@ -28,8 +28,6 @@ interface ResourceProvider{ * Gets an embedded resource on the plugin file. * WARNING: You must close the resource given using fclose() * - * @param string $filename - * * @return null|resource Resource data, or null */ public function getResource(string $filename); diff --git a/src/plugin/ScriptPluginLoader.php b/src/plugin/ScriptPluginLoader.php index b714c67b53..126f66de27 100644 --- a/src/plugin/ScriptPluginLoader.php +++ b/src/plugin/ScriptPluginLoader.php @@ -46,8 +46,6 @@ class ScriptPluginLoader implements PluginLoader{ /** * Loads the plugin contained in $file - * - * @param string $file */ public function loadPlugin(string $file) : void{ include_once $file; @@ -55,10 +53,6 @@ class ScriptPluginLoader implements PluginLoader{ /** * Gets the PluginDescription from the file - * - * @param string $file - * - * @return null|PluginDescription */ public function getPluginDescription(string $file) : ?PluginDescription{ $content = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); diff --git a/src/resourcepacks/ResourcePack.php b/src/resourcepacks/ResourcePack.php index c411c8fa6a..74f8978880 100644 --- a/src/resourcepacks/ResourcePack.php +++ b/src/resourcepacks/ResourcePack.php @@ -29,31 +29,26 @@ interface ResourcePack{ /** * Returns the path to the resource pack. This might be a file or a directory, depending on the type of pack. - * @return string */ public function getPath() : string; /** * Returns the human-readable name of the resource pack - * @return string */ public function getPackName() : string; /** * Returns the pack's UUID as a human-readable string - * @return string */ public function getPackId() : string; /** * Returns the size of the pack on disk in bytes. - * @return int */ public function getPackSize() : int; /** * Returns a version number for the pack in the format major.minor.patch - * @return string */ public function getPackVersion() : string; diff --git a/src/resourcepacks/ResourcePackManager.php b/src/resourcepacks/ResourcePackManager.php index 5071016d0c..2891179273 100644 --- a/src/resourcepacks/ResourcePackManager.php +++ b/src/resourcepacks/ResourcePackManager.php @@ -52,7 +52,6 @@ class ResourcePackManager{ /** * @param string $path Path to resource-packs directory. - * @param \Logger $logger */ public function __construct(string $path, \Logger $logger){ $this->path = $path; @@ -122,7 +121,6 @@ class ResourcePackManager{ /** * Returns the directory which resource packs are loaded from. - * @return string */ public function getPath() : string{ return $this->path; @@ -130,7 +128,6 @@ class ResourcePackManager{ /** * Returns whether players must accept resource packs in order to join. - * @return bool */ public function resourcePacksRequired() : bool{ return $this->serverForceResources; @@ -146,10 +143,6 @@ class ResourcePackManager{ /** * Returns the resource pack matching the specified UUID string, or null if the ID was not recognized. - * - * @param string $id - * - * @return ResourcePack|null */ public function getPackById(string $id) : ?ResourcePack{ return $this->uuidList[strtolower($id)] ?? null; diff --git a/src/resourcepacks/ZippedResourcePack.php b/src/resourcepacks/ZippedResourcePack.php index 6a12ad12b0..3b262759fc 100644 --- a/src/resourcepacks/ZippedResourcePack.php +++ b/src/resourcepacks/ZippedResourcePack.php @@ -43,10 +43,6 @@ class ZippedResourcePack implements ResourcePack{ /** * Performs basic validation checks on a resource pack's manifest.json. * TODO: add more manifest validation - * - * @param \stdClass $manifest - * - * @return bool */ public static function verifyManifest(\stdClass $manifest) : bool{ if(!isset($manifest->format_version) or !isset($manifest->header) or !isset($manifest->modules)){ diff --git a/src/scheduler/AsyncPool.php b/src/scheduler/AsyncPool.php index 403703d419..5ac526afc0 100644 --- a/src/scheduler/AsyncPool.php +++ b/src/scheduler/AsyncPool.php @@ -69,8 +69,6 @@ class AsyncPool{ /** * Returns the maximum size of the pool. Note that there may be less active workers than this number. - * - * @return int */ public function getSize() : int{ return $this->size; @@ -78,8 +76,6 @@ class AsyncPool{ /** * Increases the maximum size of the pool to the specified amount. This does not immediately start new workers. - * - * @param int $newSize */ public function increaseSize(int $newSize) : void{ if($newSize > $this->size){ @@ -92,8 +88,6 @@ class AsyncPool{ * The signature should be `function(int $worker) : void` * * This function will call the hook for every already-running worker. - * - * @param \Closure $hook */ public function addWorkerStartHook(\Closure $hook) : void{ Utils::validateCallableSignature(function(int $worker) : void{}, $hook); @@ -105,8 +99,6 @@ class AsyncPool{ /** * Removes a previously-registered callback listening for workers being started. - * - * @param \Closure $hook */ public function removeWorkerStartHook(\Closure $hook) : void{ unset($this->workerStartHooks[spl_object_id($hook)]); @@ -124,10 +116,6 @@ class AsyncPool{ /** * Fetches the worker with the specified ID, starting it if it does not exist, and firing any registered worker * start hooks. - * - * @param int $worker - * - * @return AsyncWorker */ private function getWorker(int $worker) : AsyncWorker{ if(!isset($this->workers[$worker])){ @@ -148,9 +136,6 @@ class AsyncPool{ /** * Submits an AsyncTask to an arbitrary worker. - * - * @param AsyncTask $task - * @param int $worker */ public function submitTaskToWorker(AsyncTask $task, int $worker) : void{ if($worker < 0 or $worker >= $this->size){ @@ -174,8 +159,6 @@ class AsyncPool{ * - if an idle worker is found, it will be selected * - else, if the worker pool is not full, a new worker will be selected * - else, the worker with the smallest backlog is chosen. - * - * @return int */ public function selectWorker() : int{ $worker = null; @@ -206,10 +189,6 @@ class AsyncPool{ /** * Submits an AsyncTask to the worker with the least load. If all workers are busy and the pool is not full, a new * worker may be started. - * - * @param AsyncTask $task - * - * @return int */ public function submitTask(AsyncTask $task) : int{ if($task->isSubmitted()){ diff --git a/src/scheduler/AsyncTask.php b/src/scheduler/AsyncTask.php index f59949192a..be367f30f8 100644 --- a/src/scheduler/AsyncTask.php +++ b/src/scheduler/AsyncTask.php @@ -96,8 +96,6 @@ abstract class AsyncTask extends \Threaded{ /** * Returns whether this task has finished executing, whether successfully or not. This differs from isRunning() * because it is not true prior to task execution. - * - * @return bool */ public function isFinished() : bool{ return $this->finished or $this->isCrashed(); @@ -118,9 +116,6 @@ abstract class AsyncTask extends \Threaded{ return $this->cancelRun; } - /** - * @return bool - */ public function hasResult() : bool{ return $this->result !== null; } @@ -136,9 +131,6 @@ abstract class AsyncTask extends \Threaded{ $this->submitted = true; } - /** - * @return bool - */ public function isSubmitted() : bool{ return $this->submitted; } @@ -210,7 +202,6 @@ abstract class AsyncTask extends \Threaded{ * Objects stored in this storage can be retrieved using fetchLocal() on the same thread that this method was called * from. * - * @param string $key * @param mixed $complexData the data to store */ protected function storeLocal(string $key, $complexData) : void{ @@ -232,8 +223,6 @@ abstract class AsyncTask extends \Threaded{ * If you used storeLocal(), you can use this on the same thread to fetch data stored. This should be used during * onProgressUpdate() and onCompletion() to fetch thread-local data stored on the parent thread. * - * @param string $key - * * @return mixed * * @throws \InvalidArgumentException if no data were stored by this AsyncTask instance. diff --git a/src/scheduler/AsyncWorker.php b/src/scheduler/AsyncWorker.php index e817e26464..51bdfd06ef 100644 --- a/src/scheduler/AsyncWorker.php +++ b/src/scheduler/AsyncWorker.php @@ -79,7 +79,6 @@ class AsyncWorker extends Worker{ * Saves mixed data into the worker's thread-local object store. This can be used to store objects which you * want to use on this worker thread from multiple AsyncTasks. * - * @param string $identifier * @param mixed $value */ public function saveToThreadStore(string $identifier, $value) : void{ @@ -97,8 +96,6 @@ class AsyncWorker extends Worker{ * * Objects stored in this storage may ONLY be retrieved while the task is running. * - * @param string $identifier - * * @return mixed */ public function getFromThreadStore(string $identifier){ @@ -110,8 +107,6 @@ class AsyncWorker extends Worker{ /** * Removes previously-stored mixed data from the worker's thread-local object store. - * - * @param string $identifier */ public function removeFromThreadStore(string $identifier) : void{ if(\Thread::getCurrentThread() !== $this){ diff --git a/src/scheduler/BulkCurlTask.php b/src/scheduler/BulkCurlTask.php index 39666d7a0c..c2e7939e73 100644 --- a/src/scheduler/BulkCurlTask.php +++ b/src/scheduler/BulkCurlTask.php @@ -43,8 +43,6 @@ class BulkCurlTask extends AsyncTask{ * $operations accepts an array of arrays. Each member array must contain a string mapped to "page", and optionally, * "timeout", "extraHeaders" and "extraOpts". Documentation of these options are same as those in * {@link Utils::simpleCurl}. - * - * @param array $operations */ public function __construct(array $operations){ $this->operations = serialize($operations); diff --git a/src/scheduler/CancellableClosureTask.php b/src/scheduler/CancellableClosureTask.php index dbcd1f6e00..a900170e98 100644 --- a/src/scheduler/CancellableClosureTask.php +++ b/src/scheduler/CancellableClosureTask.php @@ -53,8 +53,6 @@ class CancellableClosureTask extends Task{ * * The closure should follow the signature callback(int $currentTick) : bool. The return value will be used to * decide whether to continue repeating. - * - * @param \Closure $closure */ public function __construct(\Closure $closure){ Utils::validateCallableSignature(function(int $currentTick) : bool{ return false; }, $closure); diff --git a/src/scheduler/DumpWorkerMemoryTask.php b/src/scheduler/DumpWorkerMemoryTask.php index 19cd248dee..213721fae3 100644 --- a/src/scheduler/DumpWorkerMemoryTask.php +++ b/src/scheduler/DumpWorkerMemoryTask.php @@ -37,11 +37,6 @@ class DumpWorkerMemoryTask extends AsyncTask{ /** @var int */ private $maxStringSize; - /** - * @param string $outputFolder - * @param int $maxNesting - * @param int $maxStringSize - */ public function __construct(string $outputFolder, int $maxNesting, int $maxStringSize){ $this->outputFolder = $outputFolder; $this->maxNesting = $maxNesting; diff --git a/src/scheduler/FileWriteTask.php b/src/scheduler/FileWriteTask.php index 772af28b78..788a8f7d56 100644 --- a/src/scheduler/FileWriteTask.php +++ b/src/scheduler/FileWriteTask.php @@ -35,9 +35,7 @@ class FileWriteTask extends AsyncTask{ private $flags; /** - * @param string $path * @param mixed $contents - * @param int $flags */ public function __construct(string $path, $contents, int $flags = 0){ $this->path = $path; diff --git a/src/scheduler/SendUsageTask.php b/src/scheduler/SendUsageTask.php index d43b48b3fc..547b566f82 100644 --- a/src/scheduler/SendUsageTask.php +++ b/src/scheduler/SendUsageTask.php @@ -52,11 +52,6 @@ class SendUsageTask extends AsyncTask{ /** @var string */ public $data; - /** - * @param Server $server - * @param int $type - * @param array $playerList - */ public function __construct(Server $server, int $type, array $playerList = []){ $endpoint = "http://" . $server->getProperty("anonymous-statistics.host", "stats.pocketmine.net") . "/"; diff --git a/src/scheduler/Task.php b/src/scheduler/Task.php index 38085092bd..72a0b237cc 100644 --- a/src/scheduler/Task.php +++ b/src/scheduler/Task.php @@ -37,9 +37,6 @@ abstract class Task{ return $this->taskHandler; } - /** - * @return int - */ final public function getTaskId() : int{ if($this->taskHandler !== null){ return $this->taskHandler->getTaskId(); @@ -52,9 +49,6 @@ abstract class Task{ return Utils::getNiceClassName($this); } - /** - * @param TaskHandler|null $taskHandler - */ final public function setHandler(?TaskHandler $taskHandler) : void{ if($this->taskHandler === null or $taskHandler === null){ $this->taskHandler = $taskHandler; @@ -64,8 +58,6 @@ abstract class Task{ /** * Actions to execute when run * - * @param int $currentTick - * * @return void */ abstract public function onRun(int $currentTick); diff --git a/src/scheduler/TaskHandler.php b/src/scheduler/TaskHandler.php index fb798eda9b..69159b3714 100644 --- a/src/scheduler/TaskHandler.php +++ b/src/scheduler/TaskHandler.php @@ -54,13 +54,6 @@ class TaskHandler{ /** @var string */ private $ownerName; - /** - * @param Task $task - * @param int $taskId - * @param int $delay - * @param int $period - * @param string|null $ownerName - */ public function __construct(Task $task, int $taskId, int $delay = -1, int $period = -1, ?string $ownerName = null){ $this->task = $task; $this->taskId = $taskId; @@ -72,65 +65,38 @@ class TaskHandler{ $this->task->setHandler($this); } - /** - * @return bool - */ public function isCancelled() : bool{ return $this->cancelled; } - /** - * @return int - */ public function getNextRun() : int{ return $this->nextRun; } - /** - * @param int $ticks - */ public function setNextRun(int $ticks) : void{ $this->nextRun = $ticks; } - /** - * @return int - */ public function getTaskId() : int{ return $this->taskId; } - /** - * @return Task - */ public function getTask() : Task{ return $this->task; } - /** - * @return int - */ public function getDelay() : int{ return $this->delay; } - /** - * @return bool - */ public function isDelayed() : bool{ return $this->delay > 0; } - /** - * @return bool - */ public function isRepeating() : bool{ return $this->period > 0; } - /** - * @return int - */ public function getPeriod() : int{ return $this->period; } @@ -150,9 +116,6 @@ class TaskHandler{ $this->task->setHandler(null); } - /** - * @param int $currentTick - */ public function run(int $currentTick) : void{ $this->timings->startTiming(); try{ @@ -162,9 +125,6 @@ class TaskHandler{ } } - /** - * @return string - */ public function getTaskName() : string{ return $this->taskName; } diff --git a/src/scheduler/TaskScheduler.php b/src/scheduler/TaskScheduler.php index d68e480d27..0700dd9c8e 100644 --- a/src/scheduler/TaskScheduler.php +++ b/src/scheduler/TaskScheduler.php @@ -52,57 +52,27 @@ class TaskScheduler{ /** @var int */ protected $currentTick = 0; - /** - * @param null|string $owner - */ public function __construct(?string $owner = null){ $this->owner = $owner; $this->queue = new ReversePriorityQueue(); } - /** - * @param Task $task - * - * @return TaskHandler - */ public function scheduleTask(Task $task) : TaskHandler{ return $this->addTask($task, -1, -1); } - /** - * @param Task $task - * @param int $delay - * - * @return TaskHandler - */ public function scheduleDelayedTask(Task $task, int $delay) : TaskHandler{ return $this->addTask($task, $delay, -1); } - /** - * @param Task $task - * @param int $period - * - * @return TaskHandler - */ public function scheduleRepeatingTask(Task $task, int $period) : TaskHandler{ return $this->addTask($task, -1, $period); } - /** - * @param Task $task - * @param int $delay - * @param int $period - * - * @return TaskHandler - */ public function scheduleDelayedRepeatingTask(Task $task, int $delay, int $period) : TaskHandler{ return $this->addTask($task, $delay, $period); } - /** - * @param int $taskId - */ public function cancelTask(int $taskId) : void{ if(isset($this->tasks[$taskId])){ try{ @@ -124,22 +94,11 @@ class TaskScheduler{ $this->ids = 1; } - /** - * @param int $taskId - * - * @return bool - */ public function isQueued(int $taskId) : bool{ return isset($this->tasks[$taskId]); } /** - * @param Task $task - * @param int $delay - * @param int $period - * - * @return TaskHandler - * * @throws \InvalidStateException */ private function addTask(Task $task, int $delay, int $period) : TaskHandler{ @@ -183,9 +142,6 @@ class TaskScheduler{ $this->enabled = $enabled; } - /** - * @param int $currentTick - */ public function mainThreadHeartbeat(int $currentTick) : void{ $this->currentTick = $currentTick; while($this->isReady($this->currentTick)){ @@ -210,9 +166,6 @@ class TaskScheduler{ return !$this->queue->isEmpty() and $this->queue->current()->getNextRun() <= $currentTick; } - /** - * @return int - */ private function nextId() : int{ return $this->ids++; } diff --git a/src/thread/ThreadManager.php b/src/thread/ThreadManager.php index 696b348251..1109a62e49 100644 --- a/src/thread/ThreadManager.php +++ b/src/thread/ThreadManager.php @@ -34,9 +34,6 @@ class ThreadManager extends \Volatile{ self::$instance = new ThreadManager(); } - /** - * @return ThreadManager - */ public static function getInstance() : ThreadManager{ return self::$instance; } diff --git a/src/timings/Timings.php b/src/timings/Timings.php index fed3350f9c..85835f5af4 100644 --- a/src/timings/Timings.php +++ b/src/timings/Timings.php @@ -161,12 +161,6 @@ abstract class Timings{ } - /** - * @param TaskHandler $task - * @param int $period - * - * @return TimingsHandler - */ public static function getScheduledTaskTimings(TaskHandler $task, int $period) : TimingsHandler{ $name = "Task: " . ($task->getOwnerName() ?? "Unknown") . " Runnable: " . $task->getTaskName(); @@ -183,11 +177,6 @@ abstract class Timings{ return self::$pluginTaskTimingMap[$name]; } - /** - * @param Entity $entity - * - * @return TimingsHandler - */ public static function getEntityTimings(Entity $entity) : TimingsHandler{ $entityType = (new \ReflectionClass($entity))->getShortName(); if(!isset(self::$entityTypeTimingMap[$entityType])){ @@ -201,11 +190,6 @@ abstract class Timings{ return self::$entityTypeTimingMap[$entityType]; } - /** - * @param Tile $tile - * - * @return TimingsHandler - */ public static function getTileEntityTimings(Tile $tile) : TimingsHandler{ $tileType = (new \ReflectionClass($tile))->getShortName(); if(!isset(self::$tileEntityTypeTimingMap[$tileType])){ @@ -215,11 +199,6 @@ abstract class Timings{ return self::$tileEntityTypeTimingMap[$tileType]; } - /** - * @param ServerboundPacket $pk - * - * @return TimingsHandler - */ public static function getReceiveDataPacketTimings(ServerboundPacket $pk) : TimingsHandler{ $pid = $pk->pid(); if(!isset(self::$packetReceiveTimingMap[$pid])){ @@ -230,12 +209,6 @@ abstract class Timings{ return self::$packetReceiveTimingMap[$pid]; } - - /** - * @param ClientboundPacket $pk - * - * @return TimingsHandler - */ public static function getSendDataPacketTimings(ClientboundPacket $pk) : TimingsHandler{ $pid = $pk->pid(); if(!isset(self::$packetSendTimingMap[$pid])){ diff --git a/src/timings/TimingsHandler.php b/src/timings/TimingsHandler.php index b8a4d0f0ea..cfcd9f938b 100644 --- a/src/timings/TimingsHandler.php +++ b/src/timings/TimingsHandler.php @@ -147,7 +147,6 @@ class TimingsHandler{ private $violations = 0; /** - * @param string $name * @param TimingsHandler $parent */ public function __construct(string $name, ?TimingsHandler $parent = null){ @@ -200,8 +199,6 @@ class TimingsHandler{ } /** - * @param \Closure $closure - * * @return mixed the result of the given closure */ public function time(\Closure $closure){ diff --git a/src/updater/AutoUpdater.php b/src/updater/AutoUpdater.php index 3b80d5cc50..a5086e9344 100644 --- a/src/updater/AutoUpdater.php +++ b/src/updater/AutoUpdater.php @@ -49,10 +49,6 @@ class AutoUpdater{ /** @var \Logger */ private $logger; - /** - * @param Server $server - * @param string $endpoint - */ public function __construct(Server $server, string $endpoint){ $this->server = $server; $this->logger = new \PrefixedLogger($server->getLogger(), "Auto Updater"); @@ -69,8 +65,6 @@ class AutoUpdater{ /** * Callback used at the end of the update checking task - * - * @param array $updateInfo */ public function checkUpdateCallback(array $updateInfo) : void{ $this->updateInfo = $updateInfo; @@ -91,8 +85,6 @@ class AutoUpdater{ /** * Returns whether there is an update available. - * - * @return bool */ public function hasUpdate() : bool{ return $this->newVersion !== null; @@ -115,8 +107,6 @@ class AutoUpdater{ /** * Shows a warning to a player to tell them there is an update available - * - * @param Player $player */ public function showPlayerUpdate(Player $player) : void{ $player->sendMessage(TextFormat::DARK_PURPLE . "The version of " . $this->server->getName() . " that this server is running is out of date. Please consider updating to the latest version."); @@ -148,8 +138,6 @@ class AutoUpdater{ /** * Returns the last retrieved update data. - * - * @return array|null */ public function getUpdateInfo() : ?array{ return $this->updateInfo; @@ -185,8 +173,6 @@ class AutoUpdater{ /** * Returns the channel used for update checking (stable, beta, dev) - * - * @return string */ public function getChannel() : string{ $channel = strtolower($this->server->getProperty("auto-updater.preferred-channel", "stable")); @@ -199,8 +185,6 @@ class AutoUpdater{ /** * Returns the host used for update checks. - * - * @return string */ public function getEndpoint() : string{ return $this->endpoint; diff --git a/src/utils/Color.php b/src/utils/Color.php index 12d679a498..047b709e6d 100644 --- a/src/utils/Color.php +++ b/src/utils/Color.php @@ -46,7 +46,6 @@ final class Color{ /** * Returns the alpha (opacity) value of this colour. - * @return int */ public function getA() : int{ return $this->a; @@ -54,7 +53,6 @@ final class Color{ /** * Retuns the red value of this colour. - * @return int */ public function getR() : int{ return $this->r; @@ -62,7 +60,6 @@ final class Color{ /** * Returns the green value of this colour. - * @return int */ public function getG() : int{ return $this->g; @@ -70,7 +67,6 @@ final class Color{ /** * Returns the blue value of this colour. - * @return int */ public function getB() : int{ return $this->b; @@ -79,10 +75,7 @@ final class Color{ /** * Mixes the supplied list of colours together to produce a result colour. * - * @param Color $color1 * @param Color ...$colors - * - * @return Color */ public static function mix(Color $color1, Color ...$colors) : Color{ $colors[] = $color1; @@ -102,10 +95,6 @@ final class Color{ /** * Returns a Color from the supplied RGB colour code (24-bit) - * - * @param int $code - * - * @return Color */ public static function fromRGB(int $code) : Color{ return new Color(($code >> 16) & 0xff, ($code >> 8) & 0xff, $code & 0xff); @@ -113,10 +102,6 @@ final class Color{ /** * Returns a Color from the supplied ARGB colour code (32-bit) - * - * @param int $code - * - * @return Color */ public static function fromARGB(int $code) : Color{ return new Color(($code >> 16) & 0xff, ($code >> 8) & 0xff, $code & 0xff, ($code >> 24) & 0xff); @@ -124,7 +109,6 @@ final class Color{ /** * Returns an ARGB 32-bit colour value. - * @return int */ public function toARGB() : int{ return ($this->a << 24) | ($this->r << 16) | ($this->g << 8) | $this->b; @@ -132,10 +116,6 @@ final class Color{ /** * Returns a Color from the supplied RGBA colour code (32-bit) - * - * @param int $c - * - * @return Color */ public static function fromRGBA(int $c) : Color{ return new Color(($c >> 24) & 0xff, ($c >> 16) & 0xff, ($c >> 8) & 0xff, $c & 0xff); @@ -143,7 +123,6 @@ final class Color{ /** * Returns an RGBA 32-bit colour value. - * @return int */ public function toRGBA() : int{ return ($this->r << 24) | ($this->g << 16) | ($this->b << 8) | $this->a; diff --git a/src/utils/Config.php b/src/utils/Config.php index 2eea39ea82..7acc43391c 100644 --- a/src/utils/Config.php +++ b/src/utils/Config.php @@ -129,20 +129,11 @@ class Config{ $this->changed = $changed; } - /** - * @param string $str - * - * @return string - */ public static function fixYAMLIndexes(string $str) : string{ return preg_replace("#^( *)(y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF)( *)\:#m", "$1\"$2\"$3:", $str); } /** - * @param string $file - * @param int $type - * @param array $default - * * @throws \InvalidArgumentException if config type could not be auto-detected * @throws \InvalidStateException if config type is invalid */ @@ -196,8 +187,6 @@ class Config{ /** * Returns the path of the config. - * - * @return string */ public function getPath() : string{ return $this->file; @@ -238,8 +227,6 @@ class Config{ /** * Sets the options for the JSON encoding when saving * - * @param int $options - * * @return Config $this * @throws \RuntimeException if the Config is not in JSON * @see json_encode @@ -257,8 +244,6 @@ class Config{ /** * Enables the given option in addition to the currently set JSON options * - * @param int $option - * * @return Config $this * @throws \RuntimeException if the Config is not in JSON * @see json_encode @@ -276,8 +261,6 @@ class Config{ /** * Disables the given option for the JSON encoding when saving * - * @param int $option - * * @return Config $this * @throws \RuntimeException if the Config is not in JSON * @see json_encode @@ -295,7 +278,6 @@ class Config{ /** * Returns the options for the JSON encoding when saving * - * @return int * @throws \RuntimeException if the Config is not in JSON * @see json_encode */ @@ -442,9 +424,6 @@ class Config{ } } - /** - * @param array $v - */ public function setAll(array $v) : void{ $this->config = $v; $this->changed = true; @@ -453,8 +432,6 @@ class Config{ /** * @param string $k * @param bool $lowercase If set, searches Config in single-case / lowercase. - * - * @return bool */ public function exists($k, bool $lowercase = false) : bool{ if($lowercase){ @@ -474,27 +451,16 @@ class Config{ $this->changed = true; } - /** - * @param bool $keys - * - * @return array - */ public function getAll(bool $keys = false) : array{ return ($keys ? array_keys($this->config) : $this->config); } - /** - * @param array $defaults - */ public function setDefaults(array $defaults) : void{ $this->fillDefaults($defaults, $this->config); } /** - * @param array $default * @param array $data reference parameter - * - * @return int */ private function fillDefaults(array $default, &$data) : int{ $changed = 0; @@ -517,9 +483,6 @@ class Config{ return $changed; } - /** - * @param string $content - */ private function parseList(string $content) : void{ foreach(explode("\n", trim(str_replace("\r\n", "\n", $content))) as $v){ $v = trim($v); @@ -530,9 +493,6 @@ class Config{ } } - /** - * @return string - */ private function writeProperties() : string{ $content = "#Properties Config file\r\n#" . date("D M j H:i:s T Y") . "\r\n"; foreach($this->config as $k => $v){ @@ -547,9 +507,6 @@ class Config{ return $content; } - /** - * @param string $content - */ private function parseProperties(string $content) : void{ if(preg_match_all('/^\s*([a-zA-Z0-9\-_\.]+)[ \t]*=([^\r\n]*)/um', $content, $matches) > 0){ //false or 0 matches foreach($matches[1] as $i => $k){ diff --git a/src/utils/EnumTrait.php b/src/utils/EnumTrait.php index c3c23bd829..9092bd888a 100644 --- a/src/utils/EnumTrait.php +++ b/src/utils/EnumTrait.php @@ -32,8 +32,6 @@ trait EnumTrait{ /** * Registers the given object as an enum member. * - * @param self $member - * * @throws \InvalidArgumentException */ protected static function register(self $member) : void{ @@ -77,9 +75,6 @@ trait EnumTrait{ * Returns the enum member matching the given name. * This is overridden to change the return typehint. * - * @param string $name - * - * @return self * @throws \InvalidArgumentException if no member matches. */ public static function fromString(string $name) : self{ @@ -95,7 +90,6 @@ trait EnumTrait{ private $runtimeId; /** - * @param string $enumName * @throws \InvalidArgumentException */ private function __construct(string $enumName){ @@ -110,9 +104,6 @@ trait EnumTrait{ $this->runtimeId = self::$nextId++; } - /** - * @return string - */ public function name() : string{ return $this->enumName; } @@ -121,8 +112,6 @@ trait EnumTrait{ * Returns a runtime-only identifier for this enum member. This will be different with each run, so don't try to * hardcode it. * This can be useful for switches or array indexing. - * - * @return int */ public function id() : int{ return $this->runtimeId; @@ -130,10 +119,6 @@ trait EnumTrait{ /** * Returns whether the two objects are equivalent. - * - * @param self $other - * - * @return bool */ public function equals(self $other) : bool{ return $this->enumName === $other->enumName; diff --git a/src/utils/Filesystem.php b/src/utils/Filesystem.php index 689a4fcdd6..0edc258c04 100644 --- a/src/utils/Filesystem.php +++ b/src/utils/Filesystem.php @@ -101,8 +101,6 @@ final class Filesystem{ * inform other processes that some file or folder is already in use, to avoid data corruption. * If this function succeeds in gaining a lock on the file, it writes the current PID to the file. * - * @param string $lockFilePath - * * @return int|null process ID of the process currently holding the lock failure, null on success. * @throws \InvalidArgumentException if the lock file path is invalid (e.g. parent directory doesn't exist, permission denied) */ @@ -132,7 +130,6 @@ final class Filesystem{ /** * Releases a file lock previously acquired by createLockFile() and deletes the lock file. * - * @param string $lockFilePath * @throws \InvalidArgumentException if the lock file path is invalid (e.g. parent directory doesn't exist, permission denied) */ public static function releaseLockFile(string $lockFilePath) : void{ diff --git a/src/utils/Git.php b/src/utils/Git.php index 6bb4f52343..dd83eb0331 100644 --- a/src/utils/Git.php +++ b/src/utils/Git.php @@ -36,10 +36,7 @@ final class Git{ /** * Returns the git hash of the currently checked out head of the given repository, or null on failure. * - * @param string $dir * @param bool $dirty reference parameter, set to whether the repo has local changes - * - * @return string|null */ public static function getRepositoryState(string $dir, bool &$dirty) : ?string{ if(Process::execute("git -C \"$dir\" rev-parse HEAD", $out) === 0 and $out !== false and strlen($out = trim($out)) === 40){ @@ -54,10 +51,6 @@ final class Git{ /** * Infallible, returns a string representing git state, or a string of zeros on failure. * If the repo is dirty, a "-dirty" suffix is added. - * - * @param string $dir - * - * @return string */ public static function getRepositoryStatePretty(string $dir) : string{ $dirty = false; diff --git a/src/utils/Internet.php b/src/utils/Internet.php index 1628d819e5..c2ce7c14ed 100644 --- a/src/utils/Internet.php +++ b/src/utils/Internet.php @@ -113,7 +113,6 @@ class Internet{ * Returns the machine's internal network IP address. If the machine is not behind a router, this may be the same * as the external IP. * - * @return string * @throws InternetException */ public static function getInternalIP() : string{ @@ -135,9 +134,7 @@ class Internet{ * GETs an URL using cURL * NOTE: This is a blocking operation and can take a significant amount of time. It is inadvisable to use this method on the main thread. * - * @param string $page * @param int $timeout default 10 - * @param array $extraHeaders * @param string $err reference parameter, will be set to the output of curl_error(). Use this to retrieve errors that occured during the operation. * @param array[] $headers reference parameter * @param int $httpCode reference parameter @@ -158,10 +155,7 @@ class Internet{ * POSTs data to an URL * NOTE: This is a blocking operation and can take a significant amount of time. It is inadvisable to use this method on the main thread. * - * @param string $page * @param array|string $args - * @param int $timeout - * @param array $extraHeaders * @param string $err reference parameter, will be set to the output of curl_error(). Use this to retrieve errors that occured during the operation. * @param array[] $headers reference parameter * @param int $httpCode reference parameter @@ -185,7 +179,6 @@ class Internet{ * General cURL shorthand function. * NOTE: This is a blocking operation and can take a significant amount of time. It is inadvisable to use this method on the main thread. * - * @param string $page * @param float|int $timeout The maximum connect timeout and timeout in seconds, correct to ms. * @param string[] $extraHeaders extra headers to send as a plain string array * @param array $extraOpts extra CURLOPT_* to set as an [opt => value] map diff --git a/src/utils/MainLogger.php b/src/utils/MainLogger.php index dc5e7e0d20..a4f354b390 100644 --- a/src/utils/MainLogger.php +++ b/src/utils/MainLogger.php @@ -61,9 +61,6 @@ class MainLogger extends \AttachableThreadedLogger{ private $timezone; /** - * @param string $logFile - * @param bool $logDebug - * * @throws \RuntimeException */ public function __construct(string $logFile, bool $logDebug = false){ @@ -82,8 +79,6 @@ class MainLogger extends \AttachableThreadedLogger{ /** * Returns the current logger format used for console output. - * - * @return string */ public function getFormat() : string{ return $this->format; @@ -99,8 +94,6 @@ class MainLogger extends \AttachableThreadedLogger{ * - message * * @see http://php.net/manual/en/function.sprintf.php - * - * @param string $format */ public function setFormat(string $format) : void{ $this->format = $format; @@ -141,15 +134,11 @@ class MainLogger extends \AttachableThreadedLogger{ $this->send($message, \LogLevel::DEBUG, "DEBUG", TextFormat::GRAY); } - /** - * @param bool $logDebug - */ public function setLogDebug(bool $logDebug) : void{ $this->logDebug = $logDebug; } /** - * @param \Throwable $e * @param array|null $trace * * @return void diff --git a/src/utils/Process.php b/src/utils/Process.php index 3728b159b1..de2aee85ef 100644 --- a/src/utils/Process.php +++ b/src/utils/Process.php @@ -47,8 +47,6 @@ final class Process{ } /** - * @param bool $advanced - * * @return int[]|int */ public static function getMemoryUsage(bool $advanced = false){ diff --git a/src/utils/Random.php b/src/utils/Random.php index 679d6bdc68..0719dcc2cf 100644 --- a/src/utils/Random.php +++ b/src/utils/Random.php @@ -86,8 +86,6 @@ class Random{ /** * Returns an 31-bit integer (not signed) - * - * @return int */ public function nextInt() : int{ return $this->nextSignedInt() & 0x7fffffff; @@ -95,8 +93,6 @@ class Random{ /** * Returns a 32-bit integer (signed) - * - * @return int */ public function nextSignedInt() : int{ $t = ($this->x ^ ($this->x << 11)) & 0xffffffff; @@ -112,8 +108,6 @@ class Random{ /** * Returns a float between 0.0 and 1.0 (inclusive) - * - * @return float */ public function nextFloat() : float{ return $this->nextInt() / 0x7fffffff; @@ -121,8 +115,6 @@ class Random{ /** * Returns a float between -1.0 and 1.0 (inclusive) - * - * @return float */ public function nextSignedFloat() : float{ return $this->nextSignedInt() / 0x7fffffff; @@ -130,8 +122,6 @@ class Random{ /** * Returns a random boolean - * - * @return bool */ public function nextBoolean() : bool{ return ($this->nextSignedInt() & 0x01) === 0; @@ -142,8 +132,6 @@ class Random{ * * @param int $start default 0 * @param int $end default 0x7fffffff - * - * @return int */ public function nextRange(int $start = 0, int $end = 0x7fffffff) : int{ return $start + ($this->nextInt() % ($end + 1 - $start)); diff --git a/src/utils/RegistryTrait.php b/src/utils/RegistryTrait.php index f905ad7ac6..b91fbd429b 100644 --- a/src/utils/RegistryTrait.php +++ b/src/utils/RegistryTrait.php @@ -39,9 +39,6 @@ trait RegistryTrait{ /** * Adds the given object to the registry. * - * @param string $name - * @param object $member - * * @throws \InvalidArgumentException */ private static function _registryRegister(string $name, object $member) : void{ @@ -72,9 +69,6 @@ trait RegistryTrait{ } /** - * @param string $name - * - * @return object * @throws \InvalidArgumentException */ private static function _registryFromString(string $name) : object{ @@ -113,8 +107,6 @@ trait RegistryTrait{ /** * Generates code for static methods for all known registry members. - * - * @return string */ public static function _generateGetters() : string{ $lines = []; @@ -132,8 +124,6 @@ public static function %1$s() : %2$s{ /** * Generates a block of @ method annotations for accessors for this registry's known members. - * - * @return string */ public static function _generateMethodAnnotations() : string{ $traitName = (new \ReflectionClass(__TRAIT__))->getShortName(); diff --git a/src/utils/Terminal.php b/src/utils/Terminal.php index 51f8546816..9f8c40d846 100644 --- a/src/utils/Terminal.php +++ b/src/utils/Terminal.php @@ -199,8 +199,6 @@ abstract class Terminal{ * Note that this is platform-dependent and might produce different results depending on the terminal type and/or OS. * * @param string|array $string - * - * @return string */ public static function toANSI($string) : string{ if(!is_array($string)){ @@ -289,8 +287,6 @@ abstract class Terminal{ /** * Emits a string containing Minecraft colour codes to the console formatted with native colours. - * - * @param string $line */ public static function write(string $line) : void{ echo self::toANSI($line); @@ -299,8 +295,6 @@ abstract class Terminal{ /** * Emits a string containing Minecraft colour codes to the console formatted with native colours, followed by a * newline character. - * - * @param string $line */ public static function writeLine(string $line) : void{ echo self::toANSI($line) . self::$FORMAT_RESET . PHP_EOL; diff --git a/src/utils/TextFormat.php b/src/utils/TextFormat.php index bea431abd9..6ecfe9c8e0 100644 --- a/src/utils/TextFormat.php +++ b/src/utils/TextFormat.php @@ -68,10 +68,6 @@ abstract class TextFormat{ /** * Splits the string by Format tokens - * - * @param string $string - * - * @return array */ public static function tokenize(string $string) : array{ return preg_split("/(" . TextFormat::ESCAPE . "[0-9a-fk-or])/u", $string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); @@ -80,9 +76,6 @@ abstract class TextFormat{ /** * Cleans the string from Minecraft codes, ANSI Escape Codes and invalid UTF-8 characters * - * @param string $string - * @param bool $removeFormat - * * @return string valid clean UTF-8 */ public static function clean(string $string, bool $removeFormat = true) : string{ @@ -97,10 +90,7 @@ abstract class TextFormat{ /** * Replaces placeholders of § with the correct character. Only valid codes (as in the constants of the TextFormat class) will be converted. * - * @param string $string * @param string $placeholder default "&" - * - * @return string */ public static function colorize(string $string, string $placeholder = "&") : string{ return preg_replace('/' . preg_quote($placeholder, "/") . '([0-9a-fk-or])/u', TextFormat::ESCAPE . '$1', $string); @@ -110,8 +100,6 @@ abstract class TextFormat{ * Returns an JSON-formatted string with colors/markup * * @param string|array $string - * - * @return string */ public static function toJSON($string) : string{ if(!is_array($string)){ @@ -298,8 +286,6 @@ abstract class TextFormat{ * Returns an HTML-formatted string with colors/markup * * @param string|array $string - * - * @return string */ public static function toHTML($string) : string{ if(!is_array($string)){ diff --git a/src/utils/UUID.php b/src/utils/UUID.php index c84b42f434..ff1b25ca50 100644 --- a/src/utils/UUID.php +++ b/src/utils/UUID.php @@ -60,10 +60,7 @@ final class UUID{ /** * Creates an UUID from an hexadecimal representation * - * @param string $uuid * @param int $version - * - * @return UUID */ public static function fromString(string $uuid, ?int $version = null) : UUID{ return self::fromBinary(hex2bin(str_replace("-", "", trim($uuid))), $version); @@ -72,11 +69,8 @@ final class UUID{ /** * Creates an UUID from a binary representation * - * @param string $uuid * @param int $version * - * @return UUID - * * @throws \InvalidArgumentException */ public static function fromBinary(string $uuid, ?int $version = null) : UUID{ @@ -91,8 +85,6 @@ final class UUID{ * Creates an UUIDv3 from binary data or list of binary data * * @param string ...$data - * - * @return UUID */ public static function fromData(string ...$data) : UUID{ $hash = hash("md5", implode($data), true); @@ -120,8 +112,6 @@ final class UUID{ } /** - * @param int $partNumber - * * @return int * @throws \InvalidArgumentException */ diff --git a/src/utils/Utils.php b/src/utils/Utils.php index 3da8fcfdd8..aa41cf5afe 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -95,9 +95,6 @@ class Utils{ /** * Returns a readable identifier for the given Closure, including file and line. * - * @param \Closure $closure - * - * @return string * @throws \ReflectionException */ public static function getNiceClosureName(\Closure $closure) : string{ @@ -123,9 +120,6 @@ class Utils{ /** * Returns a readable identifier for the class of the given object. Sanitizes class names for anonymous classes. * - * @param object $obj - * - * @return string * @throws \ReflectionException */ public static function getNiceClassName(object $obj) : string{ @@ -163,8 +157,6 @@ class Utils{ * The rest of the hash will change depending on other factors. * * @param string $extra optional, additional data to identify the machine - * - * @return UUID */ public static function getMachineUniqueId(string $extra = "") : UUID{ if(self::$serverUniqueId !== null and $extra === ""){ @@ -233,10 +225,6 @@ class Utils{ * Linux => Linux * BSD => bsd * Other => other - * - * @param bool $recalculate - * - * @return string */ public static function getOS(bool $recalculate = false) : string{ if(self::$os === null or $recalculate){ @@ -265,11 +253,6 @@ class Utils{ return self::$os; } - /** - * @param bool $recalculate - * - * @return int - */ public static function getCoreCount(bool $recalculate = false) : int{ static $processors = 0; @@ -307,10 +290,6 @@ class Utils{ /** * Returns a prettified hexdump - * - * @param string $bin - * - * @return string */ public static function hexdump(string $bin) : string{ $output = ""; @@ -329,8 +308,6 @@ class Utils{ * Returns a string that can be printed, replaces non-printable characters * * @param mixed $str - * - * @return string */ public static function printable($str) : string{ if(!is_string($str)){ @@ -373,8 +350,6 @@ class Utils{ /** - * @param string $token - * * @return array of claims * * @throws \UnexpectedValueException @@ -399,9 +374,6 @@ class Utils{ /** * @param object $value - * @param bool $includeCurrent - * - * @return int */ public static function getReferenceCount($value, bool $includeCurrent = true) : int{ ob_start(); @@ -415,12 +387,6 @@ class Utils{ return -1; } - /** - * @param array $trace - * @param int $maxStringLength - * - * @return array - */ public static function printableTrace(array $trace, int $maxStringLength = 80) : array{ $messages = []; for($i = 0; isset($trace[$i]); ++$i){ @@ -450,11 +416,6 @@ class Utils{ return $messages; } - /** - * @param int $skipFrames - * - * @return array - */ public static function currentTrace(int $skipFrames = 0) : array{ ++$skipFrames; //omit this frame from trace, in addition to other skipped frames if(function_exists("xdebug_get_function_stack")){ @@ -469,11 +430,6 @@ class Utils{ return array_values($trace); } - /** - * @param int $skipFrames - * - * @return array - */ public static function printableCurrentTrace(int $skipFrames = 0) : array{ return self::printableTrace(self::currentTrace(++$skipFrames)); } @@ -481,8 +437,6 @@ class Utils{ /** * Extracts one-line tags from the doc-comment * - * @param string $docComment - * * @return string[] an array of tagName => tag value. If the tag has no value, an empty string is used as the value. */ public static function parseDocComment(string $docComment) : array{ diff --git a/src/utils/VersionString.php b/src/utils/VersionString.php index e9a5f3c60b..37d803503d 100644 --- a/src/utils/VersionString.php +++ b/src/utils/VersionString.php @@ -48,11 +48,6 @@ class VersionString{ /** @var bool */ private $development = false; - /** - * @param string $baseVersion - * @param bool $isDevBuild - * @param int $buildNumber - */ public function __construct(string $baseVersion, bool $isDevBuild = false, int $buildNumber = 0){ $this->baseVersion = $baseVersion; $this->development = $isDevBuild; @@ -117,12 +112,6 @@ class VersionString{ return $this->getFullVersion(); } - /** - * @param VersionString $target - * @param bool $diff - * - * @return int - */ public function compare(VersionString $target, bool $diff = false) : int{ $number = $this->getNumber(); $tNumber = $target->getNumber(); diff --git a/src/world/BlockTransaction.php b/src/world/BlockTransaction.php index 428daaf8d3..55108bc494 100644 --- a/src/world/BlockTransaction.php +++ b/src/world/BlockTransaction.php @@ -47,9 +47,6 @@ class BlockTransaction{ /** * Adds a block to the transaction at the given position. * - * @param Vector3 $pos - * @param Block $state - * * @return $this */ public function addBlock(Vector3 $pos, Block $state) : self{ @@ -59,11 +56,6 @@ class BlockTransaction{ /** * Adds a block to the batch at the given coordinates. * - * @param int $x - * @param int $y - * @param int $z - * @param Block $state - * * @return $this */ public function addBlockAt(int $x, int $y, int $z, Block $state) : self{ @@ -74,10 +66,6 @@ class BlockTransaction{ /** * Reads a block from the given world, masked by the blocks in this transaction. This can be useful if you want to * add blocks to the transaction that depend on previous blocks should they exist. - * - * @param Vector3 $pos - * - * @return Block */ public function fetchBlock(Vector3 $pos) : Block{ return $this->fetchBlockAt($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ()); @@ -85,12 +73,6 @@ class BlockTransaction{ /** * @see BlockTransaction::fetchBlock() - * - * @param int $x - * @param int $y - * @param int $z - * - * @return Block */ public function fetchBlockAt(int $x, int $y, int $z) : Block{ return $this->blocks[$x][$y][$z] ?? $this->world->getBlockAt($x, $y, $z); @@ -133,8 +115,6 @@ class BlockTransaction{ * Add a validation predicate which will be used to validate every block. * The callable signature should be the same as the below dummy function. * @see BlockTransaction::dummyValidator() - * - * @param \Closure $validator */ public function addValidator(\Closure $validator) : void{ Utils::validateCallableSignature([$this, 'dummyValidator'], $validator); @@ -146,13 +126,6 @@ class BlockTransaction{ * @see BlockTransaction::addValidator() * * @dummy - * - * @param ChunkManager $world - * @param int $x - * @param int $y - * @param int $z - * - * @return bool */ public function dummyValidator(ChunkManager $world, int $x, int $y, int $z) : bool{ return true; diff --git a/src/world/ChunkListener.php b/src/world/ChunkListener.php index c88f31f76d..937cd0c8bf 100644 --- a/src/world/ChunkListener.php +++ b/src/world/ChunkListener.php @@ -42,38 +42,27 @@ interface ChunkListener{ /** * This method will be called when a Chunk is replaced by a new one - * - * @param Chunk $chunk */ public function onChunkChanged(Chunk $chunk) : void; /** * This method will be called when a registered chunk is loaded - * - * @param Chunk $chunk */ public function onChunkLoaded(Chunk $chunk) : void; - /** * This method will be called when a registered chunk is unloaded - * - * @param Chunk $chunk */ public function onChunkUnloaded(Chunk $chunk) : void; /** * This method will be called when a registered chunk is populated * Usually it'll be sent with another call to onChunkChanged() - * - * @param Chunk $chunk */ public function onChunkPopulated(Chunk $chunk) : void; /** * This method will be called when a block changes in a registered chunk - * - * @param Vector3 $block */ public function onBlockChanged(Vector3 $block) : void; } diff --git a/src/world/ChunkManager.php b/src/world/ChunkManager.php index eeac6332f9..97ef38a307 100644 --- a/src/world/ChunkManager.php +++ b/src/world/ChunkManager.php @@ -30,58 +30,28 @@ interface ChunkManager{ /** * Returns a Block object representing the block state at the given coordinates. - * - * @param int $x - * @param int $y - * @param int $z - * - * @return Block */ public function getBlockAt(int $x, int $y, int $z) : Block; /** * Sets the block at the given coordinates to the block state specified. * - * @param int $x - * @param int $y - * @param int $z - * @param Block $block - * * @throws \InvalidArgumentException */ public function setBlockAt(int $x, int $y, int $z, Block $block) : void; - /** - * @param int $chunkX - * @param int $chunkZ - * @param bool $create - * - * @return Chunk|null - */ public function getChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk; - /** - * @param int $chunkX - * @param int $chunkZ - * @param Chunk|null $chunk - */ public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk) : void; /** * Returns the height of the world - * @return int */ public function getWorldHeight() : int; /** * Returns whether the specified coordinates are within the valid world boundaries, taking world format limitations * into account. - * - * @param int $x - * @param int $y - * @param int $z - * - * @return bool */ public function isInWorld(int $x, int $y, int $z) : bool; } diff --git a/src/world/Explosion.php b/src/world/Explosion.php index 43fcec0d1b..ab295359a8 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -65,8 +65,6 @@ class Explosion{ private $subChunkHandler; /** - * @param Position $center - * @param float $size * @param Entity|Block $what */ public function __construct(Position $center, float $size, $what = null){ @@ -88,8 +86,6 @@ class Explosion{ /** * Calculates which blocks will be destroyed by this explosion. If explodeB() is called without calling this, no blocks * will be destroyed. - * - * @return bool */ public function explodeA() : bool{ if($this->size < 0.1){ @@ -152,8 +148,6 @@ class Explosion{ /** * Executes the explosion's effects on the world. This includes destroying blocks (if any), harming and knocking back entities, * and creating sounds and particles. - * - * @return bool */ public function explodeB() : bool{ $send = []; diff --git a/src/world/Position.php b/src/world/Position.php index 0d9da13ea8..28f6149831 100644 --- a/src/world/Position.php +++ b/src/world/Position.php @@ -43,9 +43,6 @@ class Position extends Vector3{ } /** - * @param Vector3 $pos - * @param World|null $world - * * @return Position */ public static function fromObject(Vector3 $pos, ?World $world = null){ @@ -54,8 +51,6 @@ class Position extends Vector3{ /** * Return a Position instance - * - * @return Position */ public function asPosition() : Position{ return new Position($this->x, $this->y, $this->z, $this->world); @@ -79,8 +74,6 @@ class Position extends Vector3{ /** * Sets the target world of the position. * - * @param World|null $world - * * @return $this * * @throws \InvalidArgumentException if the specified World has been closed @@ -96,8 +89,6 @@ class Position extends Vector3{ /** * Checks if this object has a valid reference to a loaded world - * - * @return bool */ public function isValid() : bool{ if($this->world !== null and $this->world->isClosed()){ @@ -112,9 +103,6 @@ class Position extends Vector3{ /** * Returns a side Vector * - * @param int $side - * @param int $step - * * @return Position */ public function getSide(int $side, int $step = 1){ diff --git a/src/world/SimpleChunkManager.php b/src/world/SimpleChunkManager.php index 2c04e85a6e..6d65b6803a 100644 --- a/src/world/SimpleChunkManager.php +++ b/src/world/SimpleChunkManager.php @@ -43,8 +43,6 @@ class SimpleChunkManager implements ChunkManager{ /** * SimpleChunkManager constructor. - * - * @param int $worldHeight */ public function __construct(int $worldHeight = World::Y_MAX){ $this->worldHeight = $worldHeight; @@ -67,23 +65,11 @@ class SimpleChunkManager implements ChunkManager{ } } - /** - * @param int $chunkX - * @param int $chunkZ - * @param bool $create - * - * @return Chunk|null - */ public function getChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk{ $hash = World::chunkHash($chunkX, $chunkZ); return $this->chunks[$hash] ?? ($create ? $this->chunks[$hash] = new Chunk($chunkX, $chunkZ) : null); } - /** - * @param int $chunkX - * @param int $chunkZ - * @param Chunk|null $chunk - */ public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk) : void{ if($chunk === null){ unset($this->chunks[World::chunkHash($chunkX, $chunkZ)]); diff --git a/src/world/World.php b/src/world/World.php index 7a5a8f4f8c..3e5f27204e 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -271,12 +271,6 @@ class World implements ChunkManager{ /** * Computes a small index relative to chunk base from the given coordinates. - * - * @param int $x - * @param int $y - * @param int $z - * - * @return int */ public static function chunkBlockHash(int $x, int $y, int $z) : int{ return ($y << 8) | (($z & 0xf) << 4) | ($x & 0xf); @@ -288,21 +282,11 @@ class World implements ChunkManager{ $z = $hash << 37 >> 37; } - /** - * @param int $hash - * @param int|null $x - * @param int|null $z - */ public static function getXZ(int $hash, ?int &$x, ?int &$z) : void{ $x = $hash >> 32; $z = ($hash & 0xFFFFFFFF) << 32 >> 32; } - /** - * @param string $str - * - * @return int - */ public static function getDifficultyFromString(string $str) : int{ switch(strtolower(trim($str))){ case "0": @@ -331,10 +315,6 @@ class World implements ChunkManager{ /** * Init the default world data - * - * @param Server $server - * @param string $name - * @param WritableWorldProvider $provider */ public function __construct(Server $server, string $name, WritableWorldProvider $provider){ $this->worldId = static::$worldIdCounter++; @@ -479,8 +459,6 @@ class World implements ChunkManager{ * Broadcasts a LevelEvent to players in the area. This could be sound, particles, weather changes, etc. * * @param Vector3|null $pos If null, broadcasts to every player in the World - * @param int $evid - * @param int $data */ public function broadcastLevelEvent(?Vector3 $pos, int $evid, int $data = 0) : void{ $pk = LevelEventPacket::create($evid, $data, $pos); @@ -505,9 +483,6 @@ class World implements ChunkManager{ * * Returns a list of players who have the target chunk within their view distance. * - * @param int $chunkX - * @param int $chunkZ - * * @return Player[] */ public function getChunkPlayers(int $chunkX, int $chunkZ) : array{ @@ -517,9 +492,6 @@ class World implements ChunkManager{ /** * Gets the chunk loaders being used in a specific chunk * - * @param int $chunkX - * @param int $chunkZ - * * @return ChunkLoader[] */ public function getChunkLoaders(int $chunkX, int $chunkZ) : array{ @@ -528,7 +500,6 @@ class World implements ChunkManager{ /** * Returns an array of players who have the target position within their view distance. - * @param Vector3 $pos * * @return Player[] */ @@ -539,10 +510,6 @@ class World implements ChunkManager{ /** * Queues a packet to be sent to all players using the chunk at the specified X/Z coordinates at the end of the * current tick. - * - * @param int $chunkX - * @param int $chunkZ - * @param ClientboundPacket $packet */ public function addChunkPacket(int $chunkX, int $chunkZ, ClientboundPacket $packet) : void{ if(!isset($this->chunkPackets[$index = World::chunkHash($chunkX, $chunkZ)])){ @@ -554,9 +521,6 @@ class World implements ChunkManager{ /** * Broadcasts a packet to every player who has the target position within their view distance. - * - * @param Vector3 $pos - * @param ClientboundPacket $packet */ public function broadcastPacketToViewers(Vector3 $pos, ClientboundPacket $packet) : void{ $this->addChunkPacket($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4, $packet); @@ -564,8 +528,6 @@ class World implements ChunkManager{ /** * Broadcasts a packet to every player in the world. - * - * @param ClientboundPacket $packet */ public function broadcastGlobalPacket(ClientboundPacket $packet) : void{ $this->globalPackets[] = $packet; @@ -621,10 +583,6 @@ class World implements ChunkManager{ /** * Registers a listener to receive events on a chunk. - * - * @param ChunkListener $listener - * @param int $chunkX - * @param int $chunkZ */ public function registerChunkListener(ChunkListener $listener, int $chunkX, int $chunkZ) : void{ $hash = World::chunkHash($chunkX, $chunkZ); @@ -638,10 +596,6 @@ class World implements ChunkManager{ /** * Unregisters a chunk listener previously registered. * - * @param ChunkListener $listener - * @param int $chunkX - * @param int $chunkZ - * *@see World::registerChunkListener() * */ @@ -657,8 +611,6 @@ class World implements ChunkManager{ /** * Unregisters a chunk listener from all chunks it is listening on in this World. - * - * @param ChunkListener $listener */ public function unregisterChunkListenerFromAll(ChunkListener $listener) : void{ $id = spl_object_id($listener); @@ -675,9 +627,6 @@ class World implements ChunkManager{ /** * Returns all the listeners attached to this chunk. * - * @param int $chunkX - * @param int $chunkZ - * * @return ChunkListener[] */ public function getChunkListeners(int $chunkX, int $chunkZ) : array{ @@ -705,9 +654,6 @@ class World implements ChunkManager{ /** * @internal - * - * @param int $currentTick - * */ public function doTick(int $currentTick) : void{ if($this->closed){ @@ -1009,11 +955,6 @@ class World implements ChunkManager{ return []; } - /** - * @param bool $force - * - * @return bool - */ public function save(bool $force = false) : bool{ if(!$this->getAutoSave() and !$force){ @@ -1046,9 +987,6 @@ class World implements ChunkManager{ /** * Schedules a block update to be executed after the specified number of ticks. * Blocks will be updated with the scheduled update type. - * - * @param Vector3 $pos - * @param int $delay */ public function scheduleDelayedBlockUpdate(Vector3 $pos, int $delay) : void{ if( @@ -1072,9 +1010,6 @@ class World implements ChunkManager{ } /** - * @param AxisAlignedBB $bb - * @param bool $targetFirst - * * @return Block[] */ public function getCollisionBlocks(AxisAlignedBB $bb, bool $targetFirst = false) : array{ @@ -1116,10 +1051,6 @@ class World implements ChunkManager{ } /** - * @param Entity $entity - * @param AxisAlignedBB $bb - * @param bool $entities - * * @return AxisAlignedBB[] */ public function getCollisionBoxes(Entity $entity, AxisAlignedBB $bb, bool $entities = true) : array{ @@ -1170,8 +1101,6 @@ class World implements ChunkManager{ /** * Computes the percentage of a circle away from noon the sun is currently at. This can be multiplied by 2 * M_PI to * get an angle in radians, or by 360 to get an angle in degrees. - * - * @return float */ public function computeSunAnglePercentage() : float{ $timeProgress = ($this->time % 24000) / 24000; @@ -1188,7 +1117,6 @@ class World implements ChunkManager{ /** * Returns the percentage of a circle away from noon the sun is currently at. - * @return float */ public function getSunAnglePercentage() : float{ return $this->sunAnglePercentage; @@ -1196,7 +1124,6 @@ class World implements ChunkManager{ /** * Returns the current sun angle in radians. - * @return float */ public function getSunAngleRadians() : float{ return $this->sunAnglePercentage * 2 * M_PI; @@ -1204,7 +1131,6 @@ class World implements ChunkManager{ /** * Returns the current sun angle in degrees. - * @return float */ public function getSunAngleDegrees() : float{ return $this->sunAnglePercentage * 360.0; @@ -1213,8 +1139,6 @@ class World implements ChunkManager{ /** * Computes how many points of sky light is subtracted based on the current time. Used to offset raw chunk sky light * to get a real light value. - * - * @return int */ public function computeSkyLightReduction() : int{ $percentage = max(0, min(1, -(cos($this->getSunAngleRadians()) * 2 - 0.5))); @@ -1226,7 +1150,6 @@ class World implements ChunkManager{ /** * Returns how many points of sky light is subtracted based on the current time. - * @return int */ public function getSkyLightReduction() : int{ return $this->skyLightReduction; @@ -1235,10 +1158,6 @@ class World implements ChunkManager{ /** * Returns the sky light level at the specified coordinates, offset by the current time and weather. * - * @param int $x - * @param int $y - * @param int $z - * * @return int 0-15 */ public function getRealBlockSkyLightAt(int $x, int $y, int $z) : int{ @@ -1264,12 +1183,6 @@ class World implements ChunkManager{ /** * Returns the highest block light level available in the positions adjacent to the specified block coordinates. - * - * @param int $x - * @param int $y - * @param int $z - * - * @return int */ public function getHighestAdjacentBlockSkyLight(int $x, int $y, int $z) : int{ $max = 0; @@ -1291,12 +1204,6 @@ class World implements ChunkManager{ /** * Returns the highest block light level available in the positions adjacent to the specified block coordinates. - * - * @param int $x - * @param int $y - * @param int $z - * - * @return int */ public function getHighestAdjacentBlockLight(int $x, int $y, int $z) : int{ $max = 0; @@ -1333,10 +1240,6 @@ class World implements ChunkManager{ } /** - * @param int $x - * @param int $y - * @param int $z - * * @return int bitmap, (id << 4) | data */ public function getFullBlock(int $x, int $y, int $z) : int{ @@ -1358,11 +1261,8 @@ class World implements ChunkManager{ * Note: If you're using this for performance-sensitive code, and you're guaranteed to be supplying ints in the * specified vector, consider using {@link getBlockAt} instead for better performance. * - * @param Vector3 $pos * @param bool $cached Whether to use the block cache for getting the block (faster, but may be inaccurate) * @param bool $addToCache Whether to cache the block object created by this method call. - * - * @return Block */ public function getBlock(Vector3 $pos, bool $cached = true, bool $addToCache = true) : Block{ return $this->getBlockAt((int) floor($pos->x), (int) floor($pos->y), (int) floor($pos->z), $cached, $addToCache); @@ -1374,13 +1274,8 @@ class World implements ChunkManager{ * Note for plugin developers: If you are using this method a lot (thousands of times for many positions for * example), you may want to set addToCache to false to avoid using excessive amounts of memory. * - * @param int $x - * @param int $y - * @param int $z * @param bool $cached Whether to use the block cache for getting the block (faster, but may be inaccurate) * @param bool $addToCache Whether to cache the block object created by this method call. - * - * @return Block */ public function getBlockAt(int $x, int $y, int $z, bool $cached = true, bool $addToCache = true) : Block{ $fullState = 0; @@ -1428,10 +1323,6 @@ class World implements ChunkManager{ /** * Sets the block at the given Vector3 coordinates. * - * @param Vector3 $pos - * @param Block $block - * @param bool $update - * * @throws \InvalidArgumentException if the position is out of the world bounds */ public function setBlock(Vector3 $pos, Block $block, bool $update = true) : void{ @@ -1444,12 +1335,6 @@ class World implements ChunkManager{ * If $update is true, it'll get the neighbour blocks (6 sides) and update them, and also update local lighting. * If you are doing big changes, you might want to set this to false, then update manually. * - * @param int $x - * @param int $y - * @param int $z - * @param Block $block - * @param bool $update - * * @throws \InvalidArgumentException if the position is out of the world bounds */ public function setBlockAt(int $x, int $y, int $z, Block $block, bool $update = true) : void{ @@ -1495,12 +1380,7 @@ class World implements ChunkManager{ } /** - * @param Vector3 $source - * @param Item $item * @param Vector3 $motion - * @param int $delay - * - * @return ItemEntity|null */ public function dropItem(Vector3 $source, Item $item, ?Vector3 $motion = null, int $delay = 10) : ?ItemEntity{ if($item->isNull()){ @@ -1523,9 +1403,6 @@ class World implements ChunkManager{ /** * Drops XP orbs into the world for the specified amount, splitting the amount into several orbs if necessary. * - * @param Vector3 $pos - * @param int $amount - * * @return ExperienceOrb[] */ public function dropExperience(Vector3 $pos, int $amount) : array{ @@ -1554,12 +1431,8 @@ class World implements ChunkManager{ * Tries to break a block using a item, including Player time checks if available * It'll try to lower the durability if Item is a tool, and set it to Air if broken. * - * @param Vector3 $vector * @param Item $item reference parameter (if null, can break anything) * @param Player $player - * @param bool $createParticles - * - * @return bool */ public function useBreakOn(Vector3 $vector, Item &$item = null, ?Player $player = null, bool $createParticles = false) : bool{ $vector = $vector->floor(); @@ -1650,14 +1523,8 @@ class World implements ChunkManager{ /** * Uses a item on a position and face, placing it or activating the block * - * @param Vector3 $vector - * @param Item $item - * @param int $face - * @param Vector3|null $clickVector * @param Player|null $player default null * @param bool $playSound Whether to play a block-place sound if the block was placed successfully. - * - * @return bool */ public function useItemOn(Vector3 $vector, Item &$item, int $face, ?Vector3 $clickVector = null, ?Player $player = null, bool $playSound = false) : bool{ $blockClicked = $this->getBlock($vector); @@ -1771,11 +1638,6 @@ class World implements ChunkManager{ return true; } - /** - * @param int $entityId - * - * @return Entity|null - */ public function getEntity(int $entityId) : ?Entity{ return $this->entities[$entityId] ?? null; } @@ -1792,9 +1654,6 @@ class World implements ChunkManager{ /** * Returns the entities colliding the current one inside the AxisAlignedBB * - * @param AxisAlignedBB $bb - * @param Entity|null $entity - * * @return Entity[] */ public function getCollidingEntities(AxisAlignedBB $bb, ?Entity $entity = null) : array{ @@ -1827,7 +1686,6 @@ class World implements ChunkManager{ /** * Returns the entities near the current one inside the AxisAlignedBB * - * @param AxisAlignedBB $bb * @param Entity $entity * * @return Entity[] @@ -1859,8 +1717,6 @@ class World implements ChunkManager{ /** * Returns the closest Entity to the specified position, within the given radius. * - * @param Vector3 $pos - * @param float $maxDistance * @param string $entityType Class of entity to use for instanceof * @param bool $includeDead Whether to include entitites which are dead * @@ -1921,10 +1777,6 @@ class World implements ChunkManager{ * * Note: This method wraps getTileAt(). If you're guaranteed to be passing integers, and you're using this method * in performance-sensitive code, consider using getTileAt() instead of this method for better performance. - * - * @param Vector3 $pos - * - * @return Tile|null */ public function getTile(Vector3 $pos) : ?Tile{ return $this->getTileAt((int) floor($pos->x), (int) floor($pos->y), (int) floor($pos->z)); @@ -1932,12 +1784,6 @@ class World implements ChunkManager{ /** * Returns the tile at the specified x,y,z coordinates, or null if it does not exist. - * - * @param int $x - * @param int $y - * @param int $z - * - * @return Tile|null */ public function getTileAt(int $x, int $y, int $z) : ?Tile{ return ($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null ? $chunk->getTile($x & 0x0f, $y, $z & 0x0f) : null; @@ -1946,10 +1792,6 @@ class World implements ChunkManager{ /** * Gets the raw block skylight level * - * @param int $x - * @param int $y - * @param int $z - * * @return int 0-15 */ public function getBlockSkyLightAt(int $x, int $y, int $z) : int{ @@ -1959,41 +1801,20 @@ class World implements ChunkManager{ /** * Gets the raw block light level * - * @param int $x - * @param int $y - * @param int $z - * * @return int 0-15 */ public function getBlockLightAt(int $x, int $y, int $z) : int{ return $this->getChunk($x >> 4, $z >> 4, true)->getBlockLight($x & 0x0f, $y, $z & 0x0f); } - /** - * @param int $x - * @param int $z - * - * @return int - */ public function getBiomeId(int $x, int $z) : int{ return $this->getChunk($x >> 4, $z >> 4, true)->getBiomeId($x & 0x0f, $z & 0x0f); } - /** - * @param int $x - * @param int $z - * - * @return Biome - */ public function getBiome(int $x, int $z) : Biome{ return Biome::getBiome($this->getBiomeId($x, $z)); } - /** - * @param int $x - * @param int $z - * @param int $biomeId - */ public function setBiomeId(int $x, int $z, int $biomeId) : void{ $this->getChunk($x >> 4, $z >> 4, true)->setBiomeId($x & 0x0f, $z & 0x0f, $biomeId); } @@ -2009,11 +1830,7 @@ class World implements ChunkManager{ * Returns the chunk at the specified X/Z coordinates. If the chunk is not loaded, attempts to (synchronously!!!) * load it. * - * @param int $chunkX - * @param int $chunkZ * @param bool $create Whether to create an empty chunk as a placeholder if the chunk does not exist - * - * @return Chunk|null */ public function getChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk{ if(isset($this->chunks[$index = World::chunkHash($chunkX, $chunkZ)])){ @@ -2027,11 +1844,6 @@ class World implements ChunkManager{ /** * Returns the chunk containing the given Vector3 position. - * - * @param Vector3 $pos - * @param bool $create - * - * @return null|Chunk */ public function getChunkAtPosition(Vector3 $pos, bool $create = false) : ?Chunk{ return $this->getChunk($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4, $create); @@ -2040,9 +1852,6 @@ class World implements ChunkManager{ /** * Returns the chunks adjacent to the specified chunk. * - * @param int $x - * @param int $z - * * @return (Chunk|null)[] */ public function getAdjacentChunks(int $x, int $z) : array{ @@ -2109,9 +1918,6 @@ class World implements ChunkManager{ } /** - * @param int $chunkX - * @param int $chunkZ - * @param Chunk|null $chunk * @param bool $deleteEntitiesAndTiles Whether to delete entities and tiles on the old chunk, or transfer them to the new one */ public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk, bool $deleteEntitiesAndTiles = true) : void{ @@ -2168,9 +1974,6 @@ class World implements ChunkManager{ /** * Gets the highest block Y value at a specific $x and $z * - * @param int $x - * @param int $z - * * @return int 0-255 */ public function getHighestBlockAt(int $x, int $z) : int{ @@ -2179,42 +1982,20 @@ class World implements ChunkManager{ /** * Returns whether the given position is in a loaded area of terrain. - * - * @param Vector3 $pos - * - * @return bool */ public function isInLoadedTerrain(Vector3 $pos) : bool{ return $this->isChunkLoaded($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4); } - /** - * @param int $x - * @param int $z - * - * @return bool - */ public function isChunkLoaded(int $x, int $z) : bool{ return isset($this->chunks[World::chunkHash($x, $z)]); } - /** - * @param int $x - * @param int $z - * - * @return bool - */ public function isChunkGenerated(int $x, int $z) : bool{ $chunk = $this->getChunk($x, $z); return $chunk !== null ? $chunk->isGenerated() : false; } - /** - * @param int $x - * @param int $z - * - * @return bool - */ public function isChunkPopulated(int $x, int $z) : bool{ $chunk = $this->getChunk($x, $z); return $chunk !== null ? $chunk->isPopulated() : false; @@ -2222,8 +2003,6 @@ class World implements ChunkManager{ /** * Returns a Position pointing to the spawn - * - * @return Position */ public function getSpawnLocation() : Position{ return Position::fromObject($this->provider->getWorldData()->getSpawn(), $this); @@ -2231,8 +2010,6 @@ class World implements ChunkManager{ /** * Sets the world spawn location - * - * @param Vector3 $pos */ public function setSpawnLocation(Vector3 $pos) : void{ $previousSpawn = $this->getSpawnLocation(); @@ -2241,8 +2018,6 @@ class World implements ChunkManager{ } /** - * @param Entity $entity - * * @throws \InvalidArgumentException */ public function addEntity(Entity $entity) : void{ @@ -2262,8 +2037,6 @@ class World implements ChunkManager{ /** * Removes the entity from the world index * - * @param Entity $entity - * * @throws \InvalidArgumentException */ public function removeEntity(Entity $entity) : void{ @@ -2281,8 +2054,6 @@ class World implements ChunkManager{ } /** - * @param Tile $tile - * * @throws \InvalidArgumentException */ public function addTile(Tile $tile) : void{ @@ -2308,8 +2079,6 @@ class World implements ChunkManager{ } /** - * @param Tile $tile - * * @throws \InvalidArgumentException */ public function removeTile(Tile $tile) : void{ @@ -2329,12 +2098,6 @@ class World implements ChunkManager{ } } - /** - * @param int $x - * @param int $z - * - * @return bool - */ public function isChunkInUse(int $x, int $z) : bool{ return isset($this->chunkLoaders[$index = World::chunkHash($x, $z)]) and count($this->chunkLoaders[$index]) > 0; } @@ -2342,8 +2105,6 @@ class World implements ChunkManager{ /** * Attempts to load a chunk from the world provider (if not already loaded). * - * @param int $x - * @param int $z * @param bool $create Whether to create an empty chunk to load if the chunk cannot be loaded from disk. * * @return bool if loading the chunk was successful @@ -2473,11 +2234,6 @@ class World implements ChunkManager{ /** * Returns whether the chunk at the specified coordinates is a spawn chunk - * - * @param int $X - * @param int $Z - * - * @return bool */ public function isSpawnChunk(int $X, int $Z) : bool{ $spawn = $this->getSpawnLocation(); @@ -2487,11 +2243,6 @@ class World implements ChunkManager{ return abs($X - $spawnX) <= 1 and abs($Z - $spawnZ) <= 1; } - /** - * @param Vector3|null $spawn - * - * @return Position - */ public function getSafeSpawn(?Vector3 $spawn = null) : Position{ if(!($spawn instanceof Vector3) or $spawn->y < 1){ $spawn = $this->getSpawnLocation(); @@ -2534,8 +2285,6 @@ class World implements ChunkManager{ /** * Gets the current time - * - * @return int */ public function getTime() : int{ return $this->time; @@ -2543,8 +2292,6 @@ class World implements ChunkManager{ /** * Returns the current time of day - * - * @return int */ public function getTimeOfDay() : int{ return $this->time % self::TIME_FULL; @@ -2553,8 +2300,6 @@ class World implements ChunkManager{ /** * Returns the World display name. * WARNING: This is NOT guaranteed to be unique. Multiple worlds at runtime may share the same display name. - * - * @return string */ public function getDisplayName() : string{ return $this->displayName; @@ -2562,8 +2307,6 @@ class World implements ChunkManager{ /** * Returns the World folder name. This will not change at runtime and will be unique to a world per runtime. - * - * @return string */ public function getFolderName() : string{ return $this->folderName; @@ -2571,8 +2314,6 @@ class World implements ChunkManager{ /** * Sets the current time on the world - * - * @param int $time */ public function setTime(int $time) : void{ $this->time = $time; @@ -2597,8 +2338,6 @@ class World implements ChunkManager{ /** * Gets the world seed - * - * @return int */ public function getSeed() : int{ return $this->provider->getWorldData()->getSeed(); @@ -2608,16 +2347,10 @@ class World implements ChunkManager{ return $this->worldHeight; } - /** - * @return int - */ public function getDifficulty() : int{ return $this->provider->getWorldData()->getDifficulty(); } - /** - * @param int $difficulty - */ public function setDifficulty(int $difficulty) : void{ if($difficulty < 0 or $difficulty > 3){ throw new \InvalidArgumentException("Invalid difficulty level $difficulty"); diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index f8059aaa83..8a86e727a2 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -83,9 +83,6 @@ class WorldManager{ return $this->worlds; } - /** - * @return World|null - */ public function getDefaultWorld() : ?World{ return $this->defaultWorld; } @@ -94,8 +91,6 @@ class WorldManager{ * Sets the default world to a different world * This won't change the level-name property, * it only affects the server on runtime - * - * @param World|null $world */ public function setDefaultWorld(?World $world) : void{ if($world === null or ($this->isWorldLoaded($world->getFolderName()) and $world !== $this->defaultWorld)){ @@ -103,30 +98,16 @@ class WorldManager{ } } - /** - * @param string $name - * - * @return bool - */ public function isWorldLoaded(string $name) : bool{ return $this->getWorldByName($name) instanceof World; } - /** - * @param int $worldId - * - * @return World|null - */ public function getWorld(int $worldId) : ?World{ return $this->worlds[$worldId] ?? null; } /** * NOTE: This matches worlds based on the FOLDER name, NOT the display name. - * - * @param string $name - * - * @return World|null */ public function getWorldByName(string $name) : ?World{ foreach($this->worlds as $world){ @@ -139,11 +120,6 @@ class WorldManager{ } /** - * @param World $world - * @param bool $forceUnload - * - * @return bool - * * @throws \InvalidArgumentException */ public function unloadWorld(World $world, bool $forceUnload = false) : bool{ @@ -186,11 +162,8 @@ class WorldManager{ /** * Loads a world from the data directory * - * @param string $name * @param bool $autoUpgrade Converts worlds to the default format if the world's format is not writable / deprecated * - * @return bool - * * @throws WorldException */ public function loadWorld(string $name, bool $autoUpgrade = false) : bool{ @@ -261,13 +234,8 @@ class WorldManager{ /** * Generates a new world if it does not exist * - * @param string $name - * @param int|null $seed * @param string $generator Class name that extends pocketmine\world\generator\Generator - * @param array $options - * @param bool $backgroundGeneration * - * @return bool * @throws \InvalidArgumentException */ public function generateWorld(string $name, ?int $seed = null, string $generator = Normal::class, array $options = [], bool $backgroundGeneration = true) : bool{ @@ -325,11 +293,6 @@ class WorldManager{ return true; } - /** - * @param string $name - * - * @return bool - */ public function isWorldGenerated(string $name) : bool{ if(trim($name) === ""){ return false; @@ -345,10 +308,6 @@ class WorldManager{ /** * Searches all worlds for the entity with the specified ID. * Useful for tracking entities across multiple worlds without needing strong references. - * - * @param int $entityId - * - * @return Entity|null */ public function findEntity(int $entityId) : ?Entity{ foreach($this->worlds as $world){ @@ -388,17 +347,10 @@ class WorldManager{ } } - - /** - * @return bool - */ public function getAutoSave() : bool{ return $this->autoSave; } - /** - * @param bool $value - */ public function setAutoSave(bool $value) : void{ $this->autoSave = $value; foreach($this->worlds as $world){ @@ -408,16 +360,11 @@ class WorldManager{ /** * Returns the period in ticks after which loaded worlds will be automatically saved to disk. - * - * @return int */ public function getAutoSaveInterval() : int{ return $this->autoSaveTicks; } - /** - * @param int $autoSaveTicks - */ public function setAutoSaveInterval(int $autoSaveTicks) : void{ if($autoSaveTicks <= 0){ throw new \InvalidArgumentException("Autosave ticks must be positive"); diff --git a/src/world/biome/Biome.php b/src/world/biome/Biome.php index 92800eae0a..eed499e5ac 100644 --- a/src/world/biome/Biome.php +++ b/src/world/biome/Biome.php @@ -102,11 +102,6 @@ abstract class Biome{ self::register(self::BIRCH_FOREST, new ForestBiome(TreeType::BIRCH())); } - /** - * @param int $id - * - * @return Biome - */ public static function getBiome(int $id) : Biome{ if(self::$biomes[$id] === null){ self::register($id, new UnknownBiome()); @@ -122,12 +117,6 @@ abstract class Biome{ $this->populators[] = $populator; } - /** - * @param ChunkManager $world - * @param int $chunkX - * @param int $chunkZ - * @param Random $random - */ public function populateChunk(ChunkManager $world, int $chunkX, int $chunkZ, Random $random) : void{ foreach($this->populators as $populator){ $populator->populate($world, $chunkX, $chunkZ, $random); diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 7733fd36f6..e5da1b5bf2 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -90,12 +90,9 @@ class Chunk{ protected $NBTentities; /** - * @param int $chunkX - * @param int $chunkZ * @param SubChunk[] $subChunks * @param CompoundTag[] $entities * @param CompoundTag[] $tiles - * @param string $biomeIds * @param int[] $heightMap */ public function __construct(int $chunkX, int $chunkZ, array $subChunks = [], ?array $entities = null, ?array $tiles = null, string $biomeIds = "", array $heightMap = []){ @@ -127,16 +124,10 @@ class Chunk{ $this->NBTentities = $entities; } - /** - * @return int - */ public function getX() : int{ return $this->x; } - /** - * @return int - */ public function getZ() : int{ return $this->z; } @@ -145,17 +136,12 @@ class Chunk{ $this->x = $x; } - /** - * @param int $z - */ public function setZ(int $z) : void{ $this->z = $z; } /** * Returns the chunk height in count of subchunks. - * - * @return int */ public function getHeight() : int{ return $this->subChunks->getSize(); @@ -176,11 +162,6 @@ class Chunk{ /** * Sets the blockstate at the given coordinate by internal ID. - * - * @param int $x - * @param int $y - * @param int $z - * @param int $block */ public function setFullBlock(int $x, int $y, int $z, int $block) : void{ $this->getSubChunk($y >> 4)->setFullBlock($x, $y & 0xf, $z, $block); @@ -212,9 +193,6 @@ class Chunk{ $this->getSubChunk($y >> 4)->getBlockSkyLightArray()->set($x & 0xf, $y & 0x0f, $z & 0xf, $level); } - /** - * @param int $level - */ public function setAllBlockSkyLight(int $level) : void{ for($y = $this->subChunks->count() - 1; $y >= 0; --$y){ $this->getSubChunk($y)->setBlockSkyLightArray(LightArray::fill($level)); @@ -246,9 +224,6 @@ class Chunk{ $this->getSubChunk($y >> 4)->getBlockLightArray()->set($x & 0xf, $y & 0x0f, $z & 0xf, $level); } - /** - * @param int $level - */ public function setAllBlockLight(int $level) : void{ for($y = $this->subChunks->count() - 1; $y >= 0; --$y){ $this->getSubChunk($y)->setBlockLightArray(LightArray::fill($level)); @@ -279,8 +254,6 @@ class Chunk{ * * @param int $x 0-15 * @param int $z 0-15 - * - * @return int */ public function getHeightMap(int $x, int $z) : int{ return $this->heightMap[($z << 4) | $x]; @@ -291,7 +264,6 @@ class Chunk{ * * @param int $x 0-15 * @param int $z 0-15 - * @param int $value */ public function setHeightMap(int $x, int $z, int $value) : void{ $this->heightMap[($z << 4) | $x] = $value; @@ -384,51 +356,30 @@ class Chunk{ $this->dirtyFlags |= self::DIRTY_FLAG_BIOMES; } - /** - * @return bool - */ public function isLightPopulated() : bool{ return $this->lightPopulated; } - /** - * @param bool $value - */ public function setLightPopulated(bool $value = true) : void{ $this->lightPopulated = $value; } - /** - * @return bool - */ public function isPopulated() : bool{ return $this->terrainPopulated; } - /** - * @param bool $value - */ public function setPopulated(bool $value = true) : void{ $this->terrainPopulated = $value; } - /** - * @return bool - */ public function isGenerated() : bool{ return $this->terrainGenerated; } - /** - * @param bool $value - */ public function setGenerated(bool $value = true) : void{ $this->terrainGenerated = $value; } - /** - * @param Entity $entity - */ public function addEntity(Entity $entity) : void{ if($entity->isClosed()){ throw new \InvalidArgumentException("Attempted to add a garbage closed Entity to a chunk"); @@ -439,9 +390,6 @@ class Chunk{ } } - /** - * @param Entity $entity - */ public function removeEntity(Entity $entity) : void{ unset($this->entities[$entity->getId()]); if(!($entity instanceof Player)){ @@ -449,9 +397,6 @@ class Chunk{ } } - /** - * @param Tile $tile - */ public function addTile(Tile $tile) : void{ if($tile->isClosed()){ throw new \InvalidArgumentException("Attempted to add a garbage closed Tile to a chunk"); @@ -465,9 +410,6 @@ class Chunk{ $this->dirtyFlags |= self::DIRTY_FLAG_TILES; } - /** - * @param Tile $tile - */ public function removeTile(Tile $tile) : void{ $pos = $tile->getPos(); unset($this->tiles[Chunk::blockHash($pos->x, $pos->y, $pos->z)]); @@ -503,8 +445,6 @@ class Chunk{ * @param int $x 0-15 * @param int $y * @param int $z 0-15 - * - * @return Tile|null */ public function getTile(int $x, int $y, int $z) : ?Tile{ return $this->tiles[Chunk::blockHash($x, $y, $z)] ?? null; @@ -542,8 +482,6 @@ class Chunk{ /** * Deserializes tiles and entities from NBT - * - * @param World $world */ public function initChunk(World $world) : void{ if($this->NBTentities !== null){ @@ -586,9 +524,6 @@ class Chunk{ } } - /** - * @return string - */ public function getBiomeIdArray() : string{ return $this->biomeIds; } @@ -611,9 +546,6 @@ class Chunk{ $this->heightMap = \SplFixedArray::fromArray($values); } - /** - * @return bool - */ public function isDirty() : bool{ return $this->dirtyFlags !== 0 or !empty($this->tiles) or !empty($this->getSavableEntities()); } @@ -622,9 +554,6 @@ class Chunk{ return ($this->dirtyFlags & $flag) !== 0; } - /** - * @return int - */ public function getDirtyFlags() : int{ return $this->dirtyFlags; } @@ -647,10 +576,6 @@ class Chunk{ /** * Returns the subchunk at the specified subchunk Y coordinate, or an empty, unmodifiable stub if it does not exist or the coordinate is out of range. - * - * @param int $y - * - * @return SubChunkInterface */ public function getSubChunk(int $y) : SubChunkInterface{ if($y < 0 or $y >= $this->subChunks->getSize()){ @@ -662,9 +587,6 @@ class Chunk{ /** * Sets a subchunk in the chunk index - * - * @param int $y - * @param SubChunk|null $subChunk */ public function setSubChunk(int $y, ?SubChunk $subChunk) : void{ if($y < 0 or $y >= $this->subChunks->getSize()){ @@ -697,8 +619,6 @@ class Chunk{ * @param int $x 0-15 * @param int $y * @param int $z 0-15 - * - * @return int */ public static function blockHash(int $x, int $y, int $z) : int{ return ($y << 8) | (($z & 0x0f) << 4) | ($x & 0x0f); diff --git a/src/world/format/SubChunk.php b/src/world/format/SubChunk.php index 0dad3fbb43..5a3f980cc7 100644 --- a/src/world/format/SubChunk.php +++ b/src/world/format/SubChunk.php @@ -39,10 +39,7 @@ class SubChunk implements SubChunkInterface{ /** * SubChunk constructor. * - * @param int $default * @param PalettedBlockArray[] $blocks - * @param LightArray|null $skyLight - * @param LightArray|null $blockLight */ public function __construct(int $default, array $blocks, ?LightArray $skyLight = null, ?LightArray $blockLight = null){ $this->defaultBlock = $default; diff --git a/src/world/format/SubChunkInterface.php b/src/world/format/SubChunkInterface.php index 670fac321c..8c0af17664 100644 --- a/src/world/format/SubChunkInterface.php +++ b/src/world/format/SubChunkInterface.php @@ -29,34 +29,17 @@ interface SubChunkInterface{ * Returns whether this subchunk contains any non-air blocks. * This function will do a slow check, usually by garbage collecting first. * This is typically useful for disk saving. - * - * @return bool */ public function isEmptyAuthoritative() : bool; /** * Returns a non-authoritative bool to indicate whether the chunk contains any blocks. * This is a fast check, but may be inaccurate if the chunk has been modified and not garbage-collected. - * - * @return bool */ public function isEmptyFast() : bool; - /** - * @param int $x - * @param int $y - * @param int $z - * - * @return int - */ public function getFullBlock(int $x, int $y, int $z) : int; - /** - * @param int $x - * @param int $y - * @param int $z - * @param int $block - */ public function setFullBlock(int $x, int $y, int $z, int $block) : void; /** @@ -64,31 +47,13 @@ interface SubChunkInterface{ */ public function getBlockLayers() : array; - /** - * @param int $x - * @param int $z - * - * @return int - */ public function getHighestBlockAt(int $x, int $z) : int; - /** - * @return LightArray - */ public function getBlockSkyLightArray() : LightArray; - /** - * @param LightArray $data - */ public function setBlockSkyLightArray(LightArray $data) : void; - /** - * @return LightArray - */ public function getBlockLightArray() : LightArray; - /** - * @param LightArray $data - */ public function setBlockLightArray(LightArray $data) : void; } diff --git a/src/world/format/io/BaseWorldProvider.php b/src/world/format/io/BaseWorldProvider.php index 2689d0f6c6..c44bf73056 100644 --- a/src/world/format/io/BaseWorldProvider.php +++ b/src/world/format/io/BaseWorldProvider.php @@ -46,7 +46,6 @@ abstract class BaseWorldProvider implements WorldProvider{ } /** - * @return WorldData * @throws CorruptedWorldException * @throws UnsupportedWorldFormatException */ @@ -56,18 +55,11 @@ abstract class BaseWorldProvider implements WorldProvider{ return $this->path; } - /** - * @return WorldData - */ public function getWorldData() : WorldData{ return $this->worldData; } /** - * @param int $chunkX - * @param int $chunkZ - * - * @return Chunk|null * @throws CorruptedChunkException */ public function loadChunk(int $chunkX, int $chunkZ) : ?Chunk{ @@ -82,10 +74,6 @@ abstract class BaseWorldProvider implements WorldProvider{ } /** - * @param int $chunkX - * @param int $chunkZ - * - * @return Chunk|null * @throws CorruptedChunkException */ abstract protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk; diff --git a/src/world/format/io/ChunkUtils.php b/src/world/format/io/ChunkUtils.php index b97dc2e731..9c8ab9893b 100644 --- a/src/world/format/io/ChunkUtils.php +++ b/src/world/format/io/ChunkUtils.php @@ -32,8 +32,6 @@ class ChunkUtils{ * Converts pre-MCPE-1.0 biome color array to biome ID array. * * @param int[] $array of biome color values - * - * @return string */ public static function convertBiomeColors(array $array) : string{ $result = str_repeat("\x00", 256); diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index 0ab45ff763..f20842114f 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -48,10 +48,6 @@ final class FastChunkSerializer{ /** * Fast-serializes the chunk for passing between threads * TODO: tiles and entities - * - * @param Chunk $chunk - * - * @return string */ public static function serialize(Chunk $chunk) : string{ $stream = new BinaryStream(); @@ -97,10 +93,6 @@ final class FastChunkSerializer{ /** * Deserializes a fast-serialized chunk - * - * @param string $data - * - * @return Chunk */ public static function deserialize(string $data) : Chunk{ $stream = new BinaryStream($data); diff --git a/src/world/format/io/WorldData.php b/src/world/format/io/WorldData.php index b24b660d28..d3b7757ba2 100644 --- a/src/world/format/io/WorldData.php +++ b/src/world/format/io/WorldData.php @@ -32,73 +32,42 @@ interface WorldData{ */ public function save() : void; - /** - * @return string - */ public function getName() : string; /** * Returns the generator name - * - * @return string */ public function getGenerator() : string; - /** - * @return array - */ public function getGeneratorOptions() : array; - /** - * @return int - */ public function getSeed() : int; - - - /** - * @return int - */ public function getTime() : int; - /** - * @param int $value - */ public function setTime(int $value) : void; - - /** - * @return Vector3 - */ public function getSpawn() : Vector3; - /** - * @param Vector3 $pos - */ public function setSpawn(Vector3 $pos) : void; /** * Returns the world difficulty. This will be one of the World constants. - * @return int */ public function getDifficulty() : int; /** * Sets the world difficulty. - * - * @param int $difficulty */ public function setDifficulty(int $difficulty) : void; /** * Returns the time in ticks to the next rain level change. - * @return int */ public function getRainTime() : int; /** * Sets the time in ticks to the next rain level change. - * @param int $ticks */ public function setRainTime(int $ticks) : void; @@ -114,13 +83,11 @@ interface WorldData{ /** * Returns the time in ticks to the next lightning level change. - * @return int */ public function getLightningTime() : int; /** * Sets the time in ticks to the next lightning level change. - * @param int $ticks */ public function setLightningTime(int $ticks) : void; diff --git a/src/world/format/io/WorldProvider.php b/src/world/format/io/WorldProvider.php index 122aca55fa..a81e0e5dfe 100644 --- a/src/world/format/io/WorldProvider.php +++ b/src/world/format/io/WorldProvider.php @@ -31,7 +31,6 @@ use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; interface WorldProvider{ /** - * @param string $path * @throws CorruptedWorldException * @throws UnsupportedWorldFormatException */ @@ -39,34 +38,20 @@ interface WorldProvider{ /** * Gets the build height limit of this world - * - * @return int */ public function getWorldHeight() : int; - /** - * @return string - */ public function getPath() : string; /** * Tells if the path is a valid world. * This must tell if the current format supports opening the files in the directory - * - * @param string $path - * - * @return bool */ public static function isValid(string $path) : bool; /** * Loads a chunk (usually from disk storage) and returns it. If the chunk does not exist, null is returned. * - * @param int $chunkX - * @param int $chunkZ - * - * @return null|Chunk - * * @throws CorruptedChunkException */ public function loadChunk(int $chunkX, int $chunkZ) : ?Chunk; @@ -78,8 +63,6 @@ interface WorldProvider{ /** * Returns information about the world - * - * @return WorldData */ public function getWorldData() : WorldData; @@ -91,10 +74,6 @@ interface WorldProvider{ /** * Returns a generator which yields all the chunks in this world. * - * @param bool $skipCorrupted - * - * @param \Logger|null $logger - * * @return \Generator|Chunk[] * @throws CorruptedChunkException */ @@ -102,8 +81,6 @@ interface WorldProvider{ /** * Returns the number of chunks in the provider. Used for world conversion time estimations. - * - * @return int */ public function calculateChunkCount() : int; } diff --git a/src/world/format/io/WorldProviderManager.php b/src/world/format/io/WorldProviderManager.php index d5f8bd48f9..1c8d0cea8b 100644 --- a/src/world/format/io/WorldProviderManager.php +++ b/src/world/format/io/WorldProviderManager.php @@ -47,8 +47,6 @@ abstract class WorldProviderManager{ /** * Returns the default format used to generate new worlds. - * - * @return string */ public static function getDefault() : string{ return self::$default; @@ -67,12 +65,6 @@ abstract class WorldProviderManager{ self::$default = $class; } - /** - * @param string $class - * - * @param string $name - * @param bool $overwrite - */ public static function addProvider(string $class, string $name, bool $overwrite = false) : void{ Utils::testValidInstance($class, WorldProvider::class); @@ -88,8 +80,6 @@ abstract class WorldProviderManager{ /** * Returns a WorldProvider class for this path, or null * - * @param string $path - * * @return string[]|WorldProvider[] */ public static function getMatchingProviders(string $path) : array{ @@ -112,10 +102,6 @@ abstract class WorldProviderManager{ /** * Returns a WorldProvider by name, or null if not found - * - * @param string $name - * - * @return string|null */ public static function getProviderByName(string $name) : ?string{ return self::$providers[trim(strtolower($name))] ?? null; diff --git a/src/world/format/io/WritableWorldProvider.php b/src/world/format/io/WritableWorldProvider.php index 1a5df45c75..ca0069bd88 100644 --- a/src/world/format/io/WritableWorldProvider.php +++ b/src/world/format/io/WritableWorldProvider.php @@ -28,19 +28,11 @@ use pocketmine\world\format\Chunk; interface WritableWorldProvider extends WorldProvider{ /** * Generate the needed files in the path given - * - * @param string $path - * @param string $name - * @param int $seed - * @param string $generator - * @param array $options */ public static function generate(string $path, string $name, int $seed, string $generator, array $options = []) : void; /** * Saves a chunk (usually to disk). - * - * @param Chunk $chunk */ public function saveChunk(Chunk $chunk) : void; } diff --git a/src/world/format/io/data/BaseNbtWorldData.php b/src/world/format/io/data/BaseNbtWorldData.php index 4fd3fc1fc1..4a5fcf75fe 100644 --- a/src/world/format/io/data/BaseNbtWorldData.php +++ b/src/world/format/io/data/BaseNbtWorldData.php @@ -39,8 +39,6 @@ abstract class BaseNbtWorldData implements WorldData{ protected $compoundTag; /** - * @param string $dataPath - * * @throws CorruptedWorldException * @throws UnsupportedWorldFormatException */ @@ -60,7 +58,6 @@ abstract class BaseNbtWorldData implements WorldData{ } /** - * @return CompoundTag * @throws CorruptedWorldException * @throws UnsupportedWorldFormatException */ diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 96690ae0d8..319ac2297e 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -108,9 +108,6 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ } /** - * @param string $path - * - * @return \LevelDB * @throws \LevelDBException */ private static function createDB(string $path) : \LevelDB{ @@ -197,9 +194,6 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ } /** - * @param string $index - * @param int $chunkVersion - * * @return PalettedBlockArray[] */ protected function deserializeLegacyExtraData(string $index, int $chunkVersion) : array{ @@ -232,10 +226,6 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ } /** - * @param int $chunkX - * @param int $chunkZ - * - * @return Chunk|null * @throws CorruptedChunkException */ protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk{ @@ -490,8 +480,6 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ /** * @param CompoundTag[] $targets - * @param string $index - * @param \LevelDBWriteBatch $write */ private function writeTags(array $targets, string $index, \LevelDBWriteBatch $write) : void{ if(!empty($targets)){ @@ -502,9 +490,6 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ } } - /** - * @return \LevelDB - */ public function getDatabase() : \LevelDB{ return $this->db; } diff --git a/src/world/format/io/region/LegacyAnvilChunkTrait.php b/src/world/format/io/region/LegacyAnvilChunkTrait.php index f65c373511..aacad403e6 100644 --- a/src/world/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/world/format/io/region/LegacyAnvilChunkTrait.php @@ -49,9 +49,6 @@ trait LegacyAnvilChunkTrait{ } /** - * @param string $data - * - * @return Chunk * @throws CorruptedChunkException */ protected function deserializeChunk(string $data) : Chunk{ diff --git a/src/world/format/io/region/McRegion.php b/src/world/format/io/region/McRegion.php index 02a89c6ecb..634edde903 100644 --- a/src/world/format/io/region/McRegion.php +++ b/src/world/format/io/region/McRegion.php @@ -39,9 +39,6 @@ use function str_repeat; class McRegion extends RegionWorldProvider{ /** - * @param Chunk $chunk - * - * @return string * @throws \RuntimeException */ protected function serializeChunk(Chunk $chunk) : string{ @@ -49,9 +46,6 @@ class McRegion extends RegionWorldProvider{ } /** - * @param string $data - * - * @return Chunk * @throws CorruptedChunkException */ protected function deserializeChunk(string $data) : Chunk{ diff --git a/src/world/format/io/region/RegionLoader.php b/src/world/format/io/region/RegionLoader.php index 518625fece..974470571e 100644 --- a/src/world/format/io/region/RegionLoader.php +++ b/src/world/format/io/region/RegionLoader.php @@ -111,10 +111,6 @@ class RegionLoader{ } /** - * @param int $x - * @param int $z - * - * @return null|string * @throws \InvalidArgumentException if invalid coordinates are given * @throws CorruptedChunkException if chunk corruption is detected */ @@ -163,10 +159,6 @@ class RegionLoader{ } /** - * @param int $x - * @param int $z - * - * @return bool * @throws \InvalidArgumentException */ public function chunkExists(int $x, int $z) : bool{ @@ -174,10 +166,6 @@ class RegionLoader{ } /** - * @param int $x - * @param int $z - * @param string $chunkData - * * @throws ChunkException * @throws \InvalidArgumentException */ @@ -207,9 +195,6 @@ class RegionLoader{ } /** - * @param int $x - * @param int $z - * * @throws \InvalidArgumentException */ public function removeChunk(int $x, int $z) : void{ @@ -219,10 +204,6 @@ class RegionLoader{ } /** - * @param int $x - * @param int $z - * - * @return int * @throws \InvalidArgumentException */ protected static function getChunkOffset(int $x, int $z) : int{ @@ -233,7 +214,6 @@ class RegionLoader{ } /** - * @param int $offset * @param int $x reference parameter * @param int $z reference parameter */ diff --git a/src/world/format/io/region/RegionLocationTableEntry.php b/src/world/format/io/region/RegionLocationTableEntry.php index 2d5c69ee60..acca6a80b9 100644 --- a/src/world/format/io/region/RegionLocationTableEntry.php +++ b/src/world/format/io/region/RegionLocationTableEntry.php @@ -35,10 +35,6 @@ class RegionLocationTableEntry{ private $timestamp; /** - * @param int $firstSector - * @param int $sectorCount - * @param int $timestamp - * * @throws \InvalidArgumentException */ public function __construct(int $firstSector, int $sectorCount, int $timestamp){ @@ -53,16 +49,10 @@ class RegionLocationTableEntry{ $this->timestamp = $timestamp; } - /** - * @return int - */ public function getFirstSector() : int{ return $this->firstSector; } - /** - * @return int - */ public function getLastSector() : int{ return $this->firstSector + $this->sectorCount - 1; } @@ -75,23 +65,14 @@ class RegionLocationTableEntry{ return range($this->getFirstSector(), $this->getLastSector()); } - /** - * @return int - */ public function getSectorCount() : int{ return $this->sectorCount; } - /** - * @return int - */ public function getTimestamp() : int{ return $this->timestamp; } - /** - * @return bool - */ public function isNull() : bool{ return $this->firstSector === 0 or $this->sectorCount === 0; } diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index 79a3cda15f..33faba2121 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -51,13 +51,11 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ /** * Returns the file extension used for regions in this region-based format. - * @return string */ abstract protected static function getRegionFileExtension() : string; /** * Returns the storage version as per Minecraft PC world formats. - * @return int */ abstract protected static function getPcWorldFormatVersion() : int; @@ -105,8 +103,6 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ } /** - * @param int $chunkX - * @param int $chunkZ * @param int $regionX reference parameter * @param int $regionZ reference parameter */ @@ -115,32 +111,17 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ $regionZ = $chunkZ >> 5; } - /** - * @param int $regionX - * @param int $regionZ - * - * @return RegionLoader|null - */ protected function getRegion(int $regionX, int $regionZ) : ?RegionLoader{ return $this->regions[World::chunkHash($regionX, $regionZ)] ?? null; } /** * Returns the path to a specific region file based on its X/Z coordinates - * - * @param int $regionX - * @param int $regionZ - * - * @return string */ protected function pathToRegion(int $regionX, int $regionZ) : string{ return $this->path . "/region/r.$regionX.$regionZ." . static::getRegionFileExtension(); } - /** - * @param int $regionX - * @param int $regionZ - */ protected function loadRegion(int $regionX, int $regionZ) : void{ if(!isset($this->regions[$index = World::chunkHash($regionX, $regionZ)])){ $path = $this->pathToRegion($regionX, $regionZ); @@ -183,17 +164,11 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ abstract protected function serializeChunk(Chunk $chunk) : string; /** - * @param string $data - * - * @return Chunk * @throws CorruptedChunkException */ abstract protected function deserializeChunk(string $data) : Chunk; /** - * @param string $context - * @param ListTag $list - * * @return CompoundTag[] * @throws CorruptedChunkException */ @@ -216,10 +191,6 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ } /** - * @param int $chunkX - * @param int $chunkZ - * - * @return Chunk|null * @throws CorruptedChunkException */ protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk{ diff --git a/src/world/generator/Flat.php b/src/world/generator/Flat.php index e284ac137a..2e6f370cbb 100644 --- a/src/world/generator/Flat.php +++ b/src/world/generator/Flat.php @@ -51,10 +51,6 @@ class Flat extends Generator{ private $preset; /** - * @param ChunkManager $world - * @param int $seed - * @param array $options - * * @throws InvalidGeneratorOptionsException */ public function __construct(ChunkManager $world, int $seed, array $options = []){ @@ -88,8 +84,6 @@ class Flat extends Generator{ } /** - * @param string $layers - * * @return int[] * @throws InvalidGeneratorOptionsException */ diff --git a/src/world/generator/Generator.php b/src/world/generator/Generator.php index 0dd619cba6..e428e51be2 100644 --- a/src/world/generator/Generator.php +++ b/src/world/generator/Generator.php @@ -35,10 +35,6 @@ abstract class Generator{ /** * Converts a string world seed into an integer for use by the generator. - * - * @param string $seed - * - * @return int|null */ public static function convertSeed(string $seed) : ?int{ if($seed === ""){ //empty seed should cause a random seed to be selected - can't use 0 here because 0 is a valid seed @@ -63,10 +59,6 @@ abstract class Generator{ protected $random; /** - * @param ChunkManager $world - * @param int $seed - * @param array $options - * * @throws InvalidGeneratorOptionsException */ public function __construct(ChunkManager $world, int $seed, array $options = []){ diff --git a/src/world/generator/GeneratorManager.php b/src/world/generator/GeneratorManager.php index 38e40007be..45d8f20838 100644 --- a/src/world/generator/GeneratorManager.php +++ b/src/world/generator/GeneratorManager.php @@ -73,7 +73,6 @@ final class GeneratorManager{ /** * Returns a class name of a registered Generator matching the given name. * - * @param string $name * @param bool $throwOnMissing @deprecated this is for backwards compatibility only * * @return string|Generator Name of class that extends Generator (not an actual Generator object) @@ -95,7 +94,6 @@ final class GeneratorManager{ * * @param string $class Fully qualified name of class that extends \pocketmine\world\generator\Generator * - * @return string * @throws \InvalidArgumentException if the class type cannot be matched to a known alias */ public static function getGeneratorName(string $class) : string{ diff --git a/src/world/generator/biome/BiomeSelector.php b/src/world/generator/biome/BiomeSelector.php index 187757442d..e06bbda7a2 100644 --- a/src/world/generator/biome/BiomeSelector.php +++ b/src/world/generator/biome/BiomeSelector.php @@ -45,9 +45,6 @@ abstract class BiomeSelector{ /** * Lookup function called by recalculate() to determine the biome to use for this temperature and rainfall. * - * @param float $temperature - * @param float $rainfall - * * @return int biome ID 0-255 */ abstract protected function lookup(float $temperature, float $rainfall) : int; @@ -89,8 +86,6 @@ abstract class BiomeSelector{ /** * @param int $x * @param int $z - * - * @return Biome */ public function pickBiome($x, $z) : Biome{ $temperature = (int) ($this->getTemperature($x, $z) * 63); diff --git a/src/world/generator/hell/Nether.php b/src/world/generator/hell/Nether.php index efb11abed9..d6dabd4e72 100644 --- a/src/world/generator/hell/Nether.php +++ b/src/world/generator/hell/Nether.php @@ -51,10 +51,6 @@ class Nether extends Generator{ private $noiseBase; /** - * @param ChunkManager $world - * @param int $seed - * @param array $options - * * @throws InvalidGeneratorOptionsException */ public function __construct(ChunkManager $world, int $seed, array $options = []){ diff --git a/src/world/generator/noise/Noise.php b/src/world/generator/noise/Noise.php index ecf42759de..efe418381e 100644 --- a/src/world/generator/noise/Noise.php +++ b/src/world/generator/noise/Noise.php @@ -205,16 +205,6 @@ abstract class Noise{ return $result; } - - /** - * @param int $xSize - * @param int $samplingRate - * @param int $x - * @param int $y - * @param int $z - * - * @return \SplFixedArray - */ public function getFastNoise1D(int $xSize, int $samplingRate, int $x, int $y, int $z) : \SplFixedArray{ if($samplingRate === 0){ throw new \InvalidArgumentException("samplingRate cannot be 0"); @@ -239,16 +229,6 @@ abstract class Noise{ return $noiseArray; } - /** - * @param int $xSize - * @param int $zSize - * @param int $samplingRate - * @param int $x - * @param int $y - * @param int $z - * - * @return \SplFixedArray - */ public function getFastNoise2D(int $xSize, int $zSize, int $samplingRate, int $x, int $y, int $z) : \SplFixedArray{ assert($samplingRate !== 0, new \InvalidArgumentException("samplingRate cannot be 0")); @@ -285,19 +265,6 @@ abstract class Noise{ return $noiseArray; } - /** - * @param int $xSize - * @param int $ySize - * @param int $zSize - * @param int $xSamplingRate - * @param int $ySamplingRate - * @param int $zSamplingRate - * @param int $x - * @param int $y - * @param int $z - * - * @return array - */ public function getFastNoise3D(int $xSize, int $ySize, int $zSize, int $xSamplingRate, int $ySamplingRate, int $zSamplingRate, int $x, int $y, int $z) : array{ assert($xSamplingRate !== 0, new \InvalidArgumentException("xSamplingRate cannot be 0")); diff --git a/src/world/generator/normal/Normal.php b/src/world/generator/normal/Normal.php index 848597c0fc..edb03999c2 100644 --- a/src/world/generator/normal/Normal.php +++ b/src/world/generator/normal/Normal.php @@ -58,10 +58,6 @@ class Normal extends Generator{ private static $SMOOTH_SIZE = 2; /** - * @param ChunkManager $world - * @param int $seed - * @param array $options - * * @throws InvalidGeneratorOptionsException */ public function __construct(ChunkManager $world, int $seed, array $options = []){ diff --git a/src/world/generator/object/Tree.php b/src/world/generator/object/Tree.php index be9a2adf64..b8345ba9c1 100644 --- a/src/world/generator/object/Tree.php +++ b/src/world/generator/object/Tree.php @@ -50,11 +50,6 @@ abstract class Tree{ } /** - * @param ChunkManager $world - * @param int $x - * @param int $y - * @param int $z - * @param Random $random * @param TreeType|null $type default oak * * @throws \InvalidArgumentException diff --git a/src/world/generator/populator/Populator.php b/src/world/generator/populator/Populator.php index 5c43d964c9..f0d0f7b8da 100644 --- a/src/world/generator/populator/Populator.php +++ b/src/world/generator/populator/Populator.php @@ -31,11 +31,5 @@ use pocketmine\world\ChunkManager; abstract class Populator{ - /** - * @param ChunkManager $world - * @param int $chunkX - * @param int $chunkZ - * @param Random $random - */ abstract public function populate(ChunkManager $world, int $chunkX, int $chunkZ, Random $random) : void; } diff --git a/src/world/particle/FloatingTextParticle.php b/src/world/particle/FloatingTextParticle.php index 0f9ceb7dda..8785eebfcc 100644 --- a/src/world/particle/FloatingTextParticle.php +++ b/src/world/particle/FloatingTextParticle.php @@ -51,10 +51,6 @@ class FloatingTextParticle implements Particle{ /** @var bool */ protected $invisible = false; - /** - * @param string $text - * @param string $title - */ public function __construct(string $text, string $title = ""){ $this->text = $text; $this->title = $title; diff --git a/src/world/particle/Particle.php b/src/world/particle/Particle.php index b800a66d96..4ed80a7c05 100644 --- a/src/world/particle/Particle.php +++ b/src/world/particle/Particle.php @@ -29,8 +29,6 @@ use pocketmine\network\mcpe\protocol\ClientboundPacket; interface Particle{ /** - * @param Vector3 $pos - * * @return ClientboundPacket|ClientboundPacket[] */ public function encode(Vector3 $pos); diff --git a/src/world/particle/PotionSplashParticle.php b/src/world/particle/PotionSplashParticle.php index 70ccd96329..89f9cf047e 100644 --- a/src/world/particle/PotionSplashParticle.php +++ b/src/world/particle/PotionSplashParticle.php @@ -40,16 +40,11 @@ class PotionSplashParticle implements Particle{ * Returns the default water-bottle splash colour. * * TODO: replace this with a standard surrogate object constant (first we need to implement them!) - * - * @return Color */ public static function DEFAULT_COLOR() : Color{ return new Color(0x38, 0x5d, 0xc6); } - /** - * @return Color - */ public function getColor() : Color{ return $this->color; } diff --git a/src/world/sound/ClickSound.php b/src/world/sound/ClickSound.php index 7fcb02fcea..67d904784b 100644 --- a/src/world/sound/ClickSound.php +++ b/src/world/sound/ClickSound.php @@ -35,9 +35,6 @@ class ClickSound implements Sound{ $this->pitch = $pitch; } - /** - * @return float - */ public function getPitch() : float{ return $this->pitch; } diff --git a/src/world/sound/DoorSound.php b/src/world/sound/DoorSound.php index e457e086da..57f2ba6f9f 100644 --- a/src/world/sound/DoorSound.php +++ b/src/world/sound/DoorSound.php @@ -35,9 +35,6 @@ class DoorSound implements Sound{ $this->pitch = $pitch; } - /** - * @return float - */ public function getPitch() : float{ return $this->pitch; } diff --git a/src/world/sound/FizzSound.php b/src/world/sound/FizzSound.php index d572d7c711..1f10bd22a0 100644 --- a/src/world/sound/FizzSound.php +++ b/src/world/sound/FizzSound.php @@ -35,9 +35,6 @@ class FizzSound implements Sound{ $this->pitch = $pitch; } - /** - * @return float - */ public function getPitch() : float{ return $this->pitch; } diff --git a/src/world/sound/LaunchSound.php b/src/world/sound/LaunchSound.php index 423289b14a..e84a4a1de4 100644 --- a/src/world/sound/LaunchSound.php +++ b/src/world/sound/LaunchSound.php @@ -35,9 +35,6 @@ class LaunchSound implements Sound{ $this->pitch = $pitch; } - /** - * @return float - */ public function getPitch() : float{ return $this->pitch; } diff --git a/src/world/sound/NoteInstrument.php b/src/world/sound/NoteInstrument.php index 255bfe1f85..a6fd778f2a 100644 --- a/src/world/sound/NoteInstrument.php +++ b/src/world/sound/NoteInstrument.php @@ -59,9 +59,6 @@ final class NoteInstrument{ $this->magicNumber = $magicNumber; } - /** - * @return int - */ public function getMagicNumber() : int{ return $this->magicNumber; } diff --git a/src/world/sound/PopSound.php b/src/world/sound/PopSound.php index d38b6473cf..6bec571a95 100644 --- a/src/world/sound/PopSound.php +++ b/src/world/sound/PopSound.php @@ -35,9 +35,6 @@ class PopSound implements Sound{ $this->pitch = $pitch; } - /** - * @return float - */ public function getPitch() : float{ return $this->pitch; } diff --git a/src/world/sound/Sound.php b/src/world/sound/Sound.php index ad486f0b6c..e44c0ecce0 100644 --- a/src/world/sound/Sound.php +++ b/src/world/sound/Sound.php @@ -29,8 +29,6 @@ use pocketmine\network\mcpe\protocol\ClientboundPacket; interface Sound{ /** - * @param Vector3|null $pos - * * @return ClientboundPacket|ClientboundPacket[] */ public function encode(?Vector3 $pos); diff --git a/src/world/sound/XpLevelUpSound.php b/src/world/sound/XpLevelUpSound.php index 6e41e96897..837067446e 100644 --- a/src/world/sound/XpLevelUpSound.php +++ b/src/world/sound/XpLevelUpSound.php @@ -37,9 +37,6 @@ class XpLevelUpSound implements Sound{ $this->xpLevel = $xpLevel; } - /** - * @return int - */ public function getXpLevel() : int{ return $this->xpLevel; } diff --git a/src/world/utils/SubChunkIteratorManager.php b/src/world/utils/SubChunkIteratorManager.php index a8fcf07940..5512f42512 100644 --- a/src/world/utils/SubChunkIteratorManager.php +++ b/src/world/utils/SubChunkIteratorManager.php @@ -90,8 +90,6 @@ class SubChunkIteratorManager{ /** * Returns whether we currently have a valid terrain pointer. - * - * @return bool */ public function isValid() : bool{ return $this->currentSubChunk !== null; From 1b33143f4f2f7f462b803b1b499d99fbce42a5c5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 22 Jan 2020 12:06:47 +0000 Subject: [PATCH 1346/3224] pass 2, manual removal of incorrect non-nullable phpdoc types --- src/command/Command.php | 1 - src/entity/Location.php | 5 ----- src/event/entity/EntityEffectAddEvent.php | 3 --- src/permission/BanList.php | 5 ----- src/permission/DefaultPermissions.php | 3 --- src/permission/Permissible.php | 4 ---- src/permission/PermissibleBase.php | 3 --- src/permission/PermissibleDelegateTrait.php | 4 ---- src/permission/Permission.php | 2 -- src/player/Player.php | 2 -- src/plugin/PluginManager.php | 2 -- src/timings/TimingsHandler.php | 3 --- src/utils/UUID.php | 4 ---- src/world/Position.php | 1 - src/world/World.php | 6 ------ 15 files changed, 48 deletions(-) diff --git a/src/command/Command.php b/src/command/Command.php index fbf73b3549..63ecc126fe 100644 --- a/src/command/Command.php +++ b/src/command/Command.php @@ -74,7 +74,6 @@ abstract class Command{ public $timings; /** - * @param string $usageMessage * @param string[] $aliases */ public function __construct(string $name, string $description = "", ?string $usageMessage = null, array $aliases = []){ diff --git a/src/entity/Location.php b/src/entity/Location.php index 8d7cf84ecf..f82cf0bd6b 100644 --- a/src/entity/Location.php +++ b/src/entity/Location.php @@ -38,7 +38,6 @@ class Location extends Position{ * @param float|int $x * @param float|int $y * @param float|int $z - * @param World $world */ public function __construct($x = 0, $y = 0, $z = 0, float $yaw = 0.0, float $pitch = 0.0, ?World $world = null){ $this->yaw = $yaw; @@ -47,10 +46,6 @@ class Location extends Position{ } /** - * @param World|null $world default null - * @param float $yaw default 0.0 - * @param float $pitch default 0.0 - * * @return Location */ public static function fromObject(Vector3 $pos, ?World $world = null, float $yaw = 0.0, float $pitch = 0.0){ diff --git a/src/event/entity/EntityEffectAddEvent.php b/src/event/entity/EntityEffectAddEvent.php index 43cbb2671f..3061a399c4 100644 --- a/src/event/entity/EntityEffectAddEvent.php +++ b/src/event/entity/EntityEffectAddEvent.php @@ -33,9 +33,6 @@ class EntityEffectAddEvent extends EntityEffectEvent{ /** @var EffectInstance|null */ private $oldEffect; - /** - * @param EffectInstance $oldEffect - */ public function __construct(Entity $entity, EffectInstance $effect, ?EffectInstance $oldEffect = null){ parent::__construct($entity, $effect); $this->oldEffect = $oldEffect; diff --git a/src/permission/BanList.php b/src/permission/BanList.php index 3b08a59910..714f1a4a37 100644 --- a/src/permission/BanList.php +++ b/src/permission/BanList.php @@ -85,11 +85,6 @@ class BanList{ $this->save(); } - /** - * @param string $reason - * @param \DateTime $expires - * @param string $source - */ public function addBan(string $target, ?string $reason = null, ?\DateTime $expires = null, ?string $source = null) : BanEntry{ $entry = new BanEntry($target); $entry->setSource($source ?? $entry->getSource()); diff --git a/src/permission/DefaultPermissions.php b/src/permission/DefaultPermissions.php index 4daed435e8..28432e1267 100644 --- a/src/permission/DefaultPermissions.php +++ b/src/permission/DefaultPermissions.php @@ -26,9 +26,6 @@ namespace pocketmine\permission; abstract class DefaultPermissions{ public const ROOT = "pocketmine"; - /** - * @param Permission $parent - */ public static function registerPermission(Permission $perm, ?Permission $parent = null) : Permission{ if($parent instanceof Permission){ $parent->getChildren()[$perm->getName()] = true; diff --git a/src/permission/Permissible.php b/src/permission/Permissible.php index 74874512f1..a9be574e26 100644 --- a/src/permission/Permissible.php +++ b/src/permission/Permissible.php @@ -41,10 +41,6 @@ interface Permissible extends ServerOperator{ */ public function hasPermission($name) : bool; - /** - * @param string $name - * @param bool $value - */ public function addAttachment(Plugin $plugin, ?string $name = null, ?bool $value = null) : PermissionAttachment; public function removeAttachment(PermissionAttachment $attachment) : void; diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index 12d6519a0e..167820313d 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -91,9 +91,6 @@ class PermissibleBase implements Permissible{ /** * //TODO: tick scheduled attachments - * - * @param string $name - * @param bool $value */ public function addAttachment(Plugin $plugin, ?string $name = null, ?bool $value = null) : PermissionAttachment{ if(!$plugin->isEnabled()){ diff --git a/src/permission/PermissibleDelegateTrait.php b/src/permission/PermissibleDelegateTrait.php index 371651973e..069394ad70 100644 --- a/src/permission/PermissibleDelegateTrait.php +++ b/src/permission/PermissibleDelegateTrait.php @@ -44,10 +44,6 @@ trait PermissibleDelegateTrait{ return $this->perm->hasPermission($name); } - /** - * @param string $name - * @param bool $value - */ public function addAttachment(Plugin $plugin, ?string $name = null, ?bool $value = null) : PermissionAttachment{ return $this->perm->addAttachment($plugin, $name, $value); } diff --git a/src/permission/Permission.php b/src/permission/Permission.php index 63228658bc..e728e797ba 100644 --- a/src/permission/Permission.php +++ b/src/permission/Permission.php @@ -56,8 +56,6 @@ class Permission{ /** * Creates a new Permission object to be attached to Permissible objects * - * @param string $description - * @param string $defaultValue * @param bool[] $children */ public function __construct(string $name, ?string $description = null, ?string $defaultValue = null, array $children = []){ diff --git a/src/player/Player.php b/src/player/Player.php index 49f9f1bf32..a51a622cb8 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -136,8 +136,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Validates the given username. - * - * @param string $name */ public static function isValidUserName(?string $name) : bool{ if($name === null){ diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index ee5810dd7f..4b13f1d127 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -181,8 +181,6 @@ class PluginManager{ } /** - * @param array $newLoaders - * * @return Plugin[] */ public function loadPlugins(string $directory, ?array $newLoaders = null) : array{ diff --git a/src/timings/TimingsHandler.php b/src/timings/TimingsHandler.php index cfcd9f938b..2d3de39729 100644 --- a/src/timings/TimingsHandler.php +++ b/src/timings/TimingsHandler.php @@ -146,9 +146,6 @@ class TimingsHandler{ /** @var int */ private $violations = 0; - /** - * @param TimingsHandler $parent - */ public function __construct(string $name, ?TimingsHandler $parent = null){ $this->name = $name; $this->parent = $parent; diff --git a/src/utils/UUID.php b/src/utils/UUID.php index ff1b25ca50..90ce95154e 100644 --- a/src/utils/UUID.php +++ b/src/utils/UUID.php @@ -59,8 +59,6 @@ final class UUID{ /** * Creates an UUID from an hexadecimal representation - * - * @param int $version */ public static function fromString(string $uuid, ?int $version = null) : UUID{ return self::fromBinary(hex2bin(str_replace("-", "", trim($uuid))), $version); @@ -69,8 +67,6 @@ final class UUID{ /** * Creates an UUID from a binary representation * - * @param int $version - * * @throws \InvalidArgumentException */ public static function fromBinary(string $uuid, ?int $version = null) : UUID{ diff --git a/src/world/Position.php b/src/world/Position.php index 28f6149831..e5c6e81059 100644 --- a/src/world/Position.php +++ b/src/world/Position.php @@ -35,7 +35,6 @@ class Position extends Vector3{ * @param float|int $x * @param float|int $y * @param float|int $z - * @param World $world */ public function __construct($x = 0, $y = 0, $z = 0, ?World $world = null){ parent::__construct($x, $y, $z); diff --git a/src/world/World.php b/src/world/World.php index 3e5f27204e..4faf36241f 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1379,9 +1379,6 @@ class World implements ChunkManager{ $this->timings->setBlock->stopTiming(); } - /** - * @param Vector3 $motion - */ public function dropItem(Vector3 $source, Item $item, ?Vector3 $motion = null, int $delay = 10) : ?ItemEntity{ if($item->isNull()){ return null; @@ -1432,7 +1429,6 @@ class World implements ChunkManager{ * It'll try to lower the durability if Item is a tool, and set it to Air if broken. * * @param Item $item reference parameter (if null, can break anything) - * @param Player $player */ public function useBreakOn(Vector3 $vector, Item &$item = null, ?Player $player = null, bool $createParticles = false) : bool{ $vector = $vector->floor(); @@ -1686,8 +1682,6 @@ class World implements ChunkManager{ /** * Returns the entities near the current one inside the AxisAlignedBB * - * @param Entity $entity - * * @return Entity[] */ public function getNearbyEntities(AxisAlignedBB $bb, ?Entity $entity = null) : array{ From a3bffd375b9194c92bbaff50b6efe7dcd750ee50 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 22 Jan 2020 15:07:47 +0000 Subject: [PATCH 1347/3224] master-specific addendum to cd55cdf5c6c8be2b3aed523487db430a7df861e3 --- src/entity/Entity.php | 4 +--- src/event/HandlerListManager.php | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 067b135d55..332c7322cb 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -82,9 +82,7 @@ abstract class Entity{ public const NETWORK_ID = -1; - /** - * @var Player[] - */ + /** @var Player[] */ protected $hasSpawned = []; /** @var int */ diff --git a/src/event/HandlerListManager.php b/src/event/HandlerListManager.php index bf4cff143b..46ac79c901 100644 --- a/src/event/HandlerListManager.php +++ b/src/event/HandlerListManager.php @@ -35,9 +35,7 @@ class HandlerListManager{ return self::$globalInstance ?? (self::$globalInstance = new self); } - /** - * @var HandlerList[] classname => HandlerList - */ + /** @var HandlerList[] classname => HandlerList */ private $allLists = []; /** From 055b13a6cf6814f7484fb2454c4ab00525ab12c4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 22 Jan 2020 15:14:10 +0000 Subject: [PATCH 1348/3224] strip extra blank lines (php-cs-fixer) --- src/MemoryManager.php | 1 - src/Server.php | 2 -- src/VersionInfo.php | 1 - src/block/Block.php | 1 - src/block/BlockFactory.php | 3 --- src/block/Crops.php | 1 - src/block/Door.php | 2 -- src/block/GlazedTerracotta.php | 1 - src/block/GlowingObsidian.php | 1 - src/block/Leaves.php | 1 - src/block/NetherWartPlant.php | 1 - src/block/Sponge.php | 1 - src/block/Transparent.php | 1 - src/block/tile/BrewingStand.php | 1 - src/command/CommandExecutor.php | 1 - src/command/CommandMap.php | 2 -- src/command/SimpleCommandMap.php | 2 -- src/command/defaults/EffectCommand.php | 1 - src/command/defaults/EnchantCommand.php | 1 - src/command/defaults/KickCommand.php | 1 - src/command/defaults/ParticleCommand.php | 1 - src/command/defaults/TimeCommand.php | 1 - src/command/defaults/TransferServerCommand.php | 2 -- src/entity/Ageable.php | 1 - src/entity/Animal.php | 1 - src/entity/Entity.php | 3 --- src/entity/EntityFactory.php | 1 - src/entity/ExperienceManager.php | 1 - src/entity/Explosive.php | 1 - src/entity/Living.php | 1 - src/entity/Squid.php | 1 - src/entity/effect/VanillaEffects.php | 1 - src/entity/object/ItemEntity.php | 2 -- src/entity/object/PaintingMotive.php | 1 - src/entity/object/PrimedTNT.php | 2 -- src/entity/projectile/Projectile.php | 1 - src/entity/projectile/ProjectileSource.php | 1 - src/event/Cancellable.php | 1 - src/event/block/BlockBreakEvent.php | 1 - src/event/plugin/PluginDisableEvent.php | 1 - src/event/plugin/PluginEnableEvent.php | 1 - src/event/server/LowMemoryEvent.php | 1 - src/event/world/ChunkEvent.php | 1 - src/event/world/ChunkLoadEvent.php | 1 - src/item/Apple.php | 1 - src/item/Armor.php | 1 - src/item/Banner.php | 1 - src/item/BeetrootSoup.php | 1 - src/item/Bowl.php | 1 - src/item/Coal.php | 1 - src/item/ItemEnchantmentHandlingTrait.php | 1 - src/item/Stick.php | 1 - src/item/ToolTier.php | 1 - src/item/enchantment/EnchantmentEntry.php | 1 - src/item/enchantment/EnchantmentList.php | 1 - src/network/mcpe/handler/LoginPacketHandler.php | 1 - src/network/mcpe/handler/ResourcePacksPacketHandler.php | 1 - src/network/mcpe/protocol/ActorFallPacket.php | 1 - src/network/mcpe/protocol/AdventureSettingsPacket.php | 1 - src/network/mcpe/protocol/AnimatePacket.php | 1 - src/network/mcpe/protocol/AvailableCommandsPacket.php | 1 - src/network/mcpe/protocol/BlockActorDataPacket.php | 1 - src/network/mcpe/protocol/BlockEventPacket.php | 1 - src/network/mcpe/protocol/BlockPickRequestPacket.php | 2 -- src/network/mcpe/protocol/BossEventPacket.php | 1 - src/network/mcpe/protocol/ChangeDimensionPacket.php | 1 - src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php | 1 - src/network/mcpe/protocol/ClientToServerHandshakePacket.php | 1 - src/network/mcpe/protocol/ClientboundMapItemDataPacket.php | 2 -- src/network/mcpe/protocol/CommandBlockUpdatePacket.php | 2 -- src/network/mcpe/protocol/ContainerClosePacket.php | 1 - src/network/mcpe/protocol/ContainerOpenPacket.php | 1 - src/network/mcpe/protocol/ContainerSetDataPacket.php | 1 - src/network/mcpe/protocol/CraftingDataPacket.php | 1 - src/network/mcpe/protocol/DisconnectPacket.php | 1 - src/network/mcpe/protocol/HurtArmorPacket.php | 1 - src/network/mcpe/protocol/InteractPacket.php | 1 - src/network/mcpe/protocol/LoginPacket.php | 1 - src/network/mcpe/protocol/MapInfoRequestPacket.php | 2 -- src/network/mcpe/protocol/MobArmorEquipmentPacket.php | 1 - src/network/mcpe/protocol/MobEffectPacket.php | 1 - src/network/mcpe/protocol/MobEquipmentPacket.php | 1 - src/network/mcpe/protocol/MoveActorAbsolutePacket.php | 1 - src/network/mcpe/protocol/MovePlayerPacket.php | 1 - src/network/mcpe/protocol/PlaySoundPacket.php | 2 -- src/network/mcpe/protocol/PlayStatusPacket.php | 1 - src/network/mcpe/protocol/PlayerActionPacket.php | 1 - src/network/mcpe/protocol/PlayerInputPacket.php | 1 - src/network/mcpe/protocol/PlayerListPacket.php | 1 - src/network/mcpe/protocol/RemoveActorPacket.php | 1 - src/network/mcpe/protocol/RequestChunkRadiusPacket.php | 1 - src/network/mcpe/protocol/ResourcePackChunkDataPacket.php | 2 -- src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php | 2 -- .../mcpe/protocol/ResourcePackClientResponsePacket.php | 1 - src/network/mcpe/protocol/ResourcePackDataInfoPacket.php | 2 -- src/network/mcpe/protocol/ResourcePackStackPacket.php | 2 -- src/network/mcpe/protocol/ResourcePacksInfoPacket.php | 1 - src/network/mcpe/protocol/RespawnPacket.php | 1 - src/network/mcpe/protocol/RiderJumpPacket.php | 2 -- src/network/mcpe/protocol/ServerToClientHandshakePacket.php | 1 - src/network/mcpe/protocol/SetActorDataPacket.php | 1 - src/network/mcpe/protocol/SetActorLinkPacket.php | 1 - src/network/mcpe/protocol/SetActorMotionPacket.php | 1 - src/network/mcpe/protocol/SetCommandsEnabledPacket.php | 1 - src/network/mcpe/protocol/SetDifficultyPacket.php | 1 - src/network/mcpe/protocol/SetHealthPacket.php | 1 - src/network/mcpe/protocol/SetPlayerGameTypePacket.php | 1 - src/network/mcpe/protocol/SetSpawnPositionPacket.php | 1 - src/network/mcpe/protocol/SetTitlePacket.php | 2 -- src/network/mcpe/protocol/ShowCreditsPacket.php | 2 -- src/network/mcpe/protocol/SpawnExperienceOrbPacket.php | 1 - src/network/mcpe/protocol/StartGamePacket.php | 1 - src/network/mcpe/protocol/StopSoundPacket.php | 2 -- src/network/mcpe/protocol/TakeItemActorPacket.php | 1 - src/network/mcpe/protocol/TextPacket.php | 1 - src/network/mcpe/protocol/UnknownPacket.php | 2 -- src/network/mcpe/protocol/UpdateAttributesPacket.php | 1 - src/network/mcpe/protocol/UpdateBlockPacket.php | 1 - src/network/mcpe/protocol/UpdateTradePacket.php | 2 -- src/network/mcpe/protocol/types/entity/EntityLegacyIds.php | 1 - src/network/mcpe/protocol/types/inventory/WindowTypes.php | 2 -- src/network/mcpe/serializer/NetworkBinaryStream.php | 1 - src/permission/PermissionAttachmentInfo.php | 1 - src/permission/PermissionRemovedExecutor.php | 1 - src/permission/ServerOperator.php | 1 - src/player/Player.php | 2 -- src/plugin/PluginManager.php | 1 - src/resourcepacks/ResourcePack.php | 2 -- src/resourcepacks/ResourcePackManager.php | 1 - src/resourcepacks/ZippedResourcePack.php | 2 -- src/scheduler/SendUsageTask.php | 1 - src/updater/UpdateCheckTask.php | 1 - src/utils/Process.php | 1 - src/utils/Timezone.php | 1 - src/utils/Utils.php | 2 -- src/utils/VersionString.php | 1 - src/wizard/SetupWizard.php | 1 - src/world/Explosion.php | 1 - src/world/World.php | 3 --- src/world/WorldManager.php | 1 - src/world/biome/Biome.php | 4 ---- src/world/biome/DesertBiome.php | 1 - src/world/biome/SmallMountainsBiome.php | 1 - src/world/format/io/data/BaseNbtWorldData.php | 1 - src/world/format/io/data/JavaWorldData.php | 1 - src/world/format/io/region/CorruptedRegionException.php | 2 -- src/world/format/io/region/RegionException.php | 2 -- src/world/generator/noise/Noise.php | 2 -- src/world/generator/object/Tree.php | 1 - 149 files changed, 188 deletions(-) diff --git a/src/MemoryManager.php b/src/MemoryManager.php index adce630852..fcda3bc5a4 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -435,7 +435,6 @@ class MemoryManager{ fwrite($obData, "$hash@$className: " . json_encode($info, JSON_UNESCAPED_SLASHES) . "\n"); } - }while($continue); $logger->info("Wrote " . count($objects) . " objects"); diff --git a/src/Server.php b/src/Server.php index 72d4586437..4cc793eacc 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1328,7 +1328,6 @@ class Server{ return true; } - $sender->sendMessage($this->getLanguage()->translateString(TextFormat::RED . "%commands.generic.notFound")); return false; @@ -1580,7 +1579,6 @@ class Server{ $this->uniquePlayers = []; } - /** * @return Language */ diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 4e5ede6a4b..20e7272b81 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -30,7 +30,6 @@ if(defined('pocketmine\_VERSION_INFO_INCLUDED')){ } const _VERSION_INFO_INCLUDED = true; - const NAME = "PocketMine-MP"; const BASE_VERSION = "4.0.0"; const IS_DEVELOPMENT_BUILD = true; diff --git a/src/block/Block.php b/src/block/Block.php index e006a42179..0674f6c5ed 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -333,7 +333,6 @@ class Block{ return false; } - public function addVelocityToEntity(Entity $entity, Vector3 $vector) : void{ } diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 5c34585e37..dd12f922c0 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -307,8 +307,6 @@ class BlockFactory{ self::register(new SeaPickle(new BID(Ids::SEA_PICKLE), "Sea Pickle")); self::register(new Skull(new BID(Ids::MOB_HEAD_BLOCK, 0, null, TileSkull::class), "Mob Head")); - - self::register(new Snow(new BID(Ids::SNOW), "Snow Block")); self::register(new SnowLayer(new BID(Ids::SNOW_LAYER), "Snow Layer")); self::register(new SoulSand(new BID(Ids::SOUL_SAND), "Soul Sand")); @@ -399,7 +397,6 @@ class BlockFactory{ self::register(new WeightedPressurePlateLight(new BID(Ids::LIGHT_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Light")); self::register(new Wheat(new BID(Ids::WHEAT_BLOCK), "Wheat Block")); - //region ugly treetype -> blockID mapping tables $woodenStairIds = [ TreeType::OAK()->id() => Ids::OAK_STAIRS, diff --git a/src/block/Crops.php b/src/block/Crops.php index 0d1b461e23..b9c8877f9d 100644 --- a/src/block/Crops.php +++ b/src/block/Crops.php @@ -61,7 +61,6 @@ abstract class Crops extends Flowable{ return false; } - public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($this->age < 7 and $item instanceof Fertilizer){ $block = clone $this; diff --git a/src/block/Door.php b/src/block/Door.php index 84f2cb1313..ab4ad13e8d 100644 --- a/src/block/Door.php +++ b/src/block/Door.php @@ -32,7 +32,6 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use pocketmine\world\sound\DoorSound; - class Door extends Transparent{ /** @var int */ protected $facing = Facing::NORTH; @@ -46,7 +45,6 @@ class Door extends Transparent{ /** @var bool */ protected $powered = false; - protected function writeStateToMeta() : int{ if($this->top){ return BlockLegacyMetadata::DOOR_FLAG_TOP | diff --git a/src/block/GlazedTerracotta.php b/src/block/GlazedTerracotta.php index b4d6baebb8..a9335ad6b2 100644 --- a/src/block/GlazedTerracotta.php +++ b/src/block/GlazedTerracotta.php @@ -1,6 +1,5 @@ x, $pos->y, $pos->z); if(isset($visited[$index])){ diff --git a/src/block/NetherWartPlant.php b/src/block/NetherWartPlant.php index 0b72bb0a08..7ca38d72f4 100644 --- a/src/block/NetherWartPlant.php +++ b/src/block/NetherWartPlant.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\block; - use pocketmine\block\utils\BlockDataSerializer; use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Item; diff --git a/src/block/Sponge.php b/src/block/Sponge.php index f95a7128ce..486fbff28c 100644 --- a/src/block/Sponge.php +++ b/src/block/Sponge.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\block; - class Sponge extends Opaque{ /** @var bool */ diff --git a/src/block/Transparent.php b/src/block/Transparent.php index 3d501dd768..46fe7217af 100644 --- a/src/block/Transparent.php +++ b/src/block/Transparent.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\block; - class Transparent extends Block{ public function isTransparent() : bool{ diff --git a/src/block/tile/BrewingStand.php b/src/block/tile/BrewingStand.php index 535a4180e5..62814e5281 100644 --- a/src/block/tile/BrewingStand.php +++ b/src/block/tile/BrewingStand.php @@ -51,7 +51,6 @@ class BrewingStand extends Spawnable implements Container, Nameable{ /** @var int */ private $remainingFuelTime = 0; - public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); $this->inventory = new BrewingStandInventory($this->pos); diff --git a/src/command/CommandExecutor.php b/src/command/CommandExecutor.php index 1efcd5f525..fb989590de 100644 --- a/src/command/CommandExecutor.php +++ b/src/command/CommandExecutor.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\command; - interface CommandExecutor{ /** diff --git a/src/command/CommandMap.php b/src/command/CommandMap.php index fa1b63cbd8..3be7850e69 100644 --- a/src/command/CommandMap.php +++ b/src/command/CommandMap.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\command; - interface CommandMap{ /** @@ -39,5 +38,4 @@ interface CommandMap{ public function getCommand(string $name) : ?Command; - } diff --git a/src/command/SimpleCommandMap.php b/src/command/SimpleCommandMap.php index d36e0ddb24..ac312143ba 100644 --- a/src/command/SimpleCommandMap.php +++ b/src/command/SimpleCommandMap.php @@ -133,7 +133,6 @@ class SimpleCommandMap implements CommandMap{ ]); } - public function registerAll(string $fallbackPrefix, array $commands) : void{ foreach($commands as $command){ $this->register($fallbackPrefix, $command); @@ -288,7 +287,6 @@ class SimpleCommandMap implements CommandMap{ $commandName = ""; $command = $this->matchCommand($commandName, $args); - if($command === null){ $bad[] = $commandString; }elseif($commandName === $alias){ diff --git a/src/command/defaults/EffectCommand.php b/src/command/defaults/EffectCommand.php index b7ec3760bf..fa0d74aa70 100644 --- a/src/command/defaults/EffectCommand.php +++ b/src/command/defaults/EffectCommand.php @@ -119,7 +119,6 @@ class EffectCommand extends VanillaCommand{ self::broadcastCommandMessage($sender, new TranslationContainer("%commands.effect.success", [$effect->getName(), $instance->getAmplifier(), $player->getDisplayName(), $instance->getDuration() / 20])); } - return true; } } diff --git a/src/command/defaults/EnchantCommand.php b/src/command/defaults/EnchantCommand.php index 2f770699b3..bd8b71bd6c 100644 --- a/src/command/defaults/EnchantCommand.php +++ b/src/command/defaults/EnchantCommand.php @@ -88,7 +88,6 @@ class EnchantCommand extends VanillaCommand{ $item->addEnchantment(new EnchantmentInstance($enchantment, $level)); $player->getInventory()->setItemInHand($item); - self::broadcastCommandMessage($sender, new TranslationContainer("%commands.enchant.success", [$player->getName()])); return true; } diff --git a/src/command/defaults/KickCommand.php b/src/command/defaults/KickCommand.php index 126215e410..879a181602 100644 --- a/src/command/defaults/KickCommand.php +++ b/src/command/defaults/KickCommand.php @@ -68,7 +68,6 @@ class KickCommand extends VanillaCommand{ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); } - return true; } } diff --git a/src/command/defaults/ParticleCommand.php b/src/command/defaults/ParticleCommand.php index 18342534c2..d503ee510f 100644 --- a/src/command/defaults/ParticleCommand.php +++ b/src/command/defaults/ParticleCommand.php @@ -121,7 +121,6 @@ class ParticleCommand extends VanillaCommand{ return true; } - $sender->sendMessage(new TranslationContainer("commands.particle.success", [$name, $count])); $random = new Random((int) (microtime(true) * 1000) + mt_rand()); diff --git a/src/command/defaults/TimeCommand.php b/src/command/defaults/TimeCommand.php index 91cc1cbc7f..147c3e4cfc 100644 --- a/src/command/defaults/TimeCommand.php +++ b/src/command/defaults/TimeCommand.php @@ -85,7 +85,6 @@ class TimeCommand extends VanillaCommand{ return true; } - if(count($args) < 2){ throw new InvalidCommandSyntaxException(); } diff --git a/src/command/defaults/TransferServerCommand.php b/src/command/defaults/TransferServerCommand.php index 9f102cb47a..295ce3f453 100644 --- a/src/command/defaults/TransferServerCommand.php +++ b/src/command/defaults/TransferServerCommand.php @@ -21,10 +21,8 @@ declare(strict_types=1); - namespace pocketmine\command\defaults; - use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\player\Player; diff --git a/src/entity/Ageable.php b/src/entity/Ageable.php index cc835dbbfb..bc74036d8e 100644 --- a/src/entity/Ageable.php +++ b/src/entity/Ageable.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\entity; - interface Ageable{ public function isBaby() : bool; } diff --git a/src/entity/Animal.php b/src/entity/Animal.php index b3116653f0..60dbf9c469 100644 --- a/src/entity/Animal.php +++ b/src/entity/Animal.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\entity; - use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; abstract class Animal extends Living implements Ageable{ diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 332c7322cb..9d7c2d6d58 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -988,7 +988,6 @@ abstract class Entity{ return true; } - $this->timings->startTiming(); if($this->hasMovementUpdate()){ @@ -1017,7 +1016,6 @@ abstract class Entity{ $hasUpdate = $this->entityBaseTick($tickDiff); Timings::$timerEntityBaseTick->stopTiming(); - $this->timings->stopTiming(); //if($this->isStatic()) @@ -1188,7 +1186,6 @@ abstract class Entity{ $moveBB->offset(0, 0, $dz); - if($this->stepHeight > 0 and $fallingFlag and ($movX != $dx or $movZ != $dz)){ $cx = $dx; $cy = $dy; diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index 51ba2176ae..2c0510a6bb 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -231,7 +231,6 @@ final class EntityFactory{ throw new \InvalidArgumentException("Entity $class is not registered"); } - /** * Helper function which creates minimal NBT needed to spawn an entity. */ diff --git a/src/entity/ExperienceManager.php b/src/entity/ExperienceManager.php index 49aea2c27a..cafbf42146 100644 --- a/src/entity/ExperienceManager.php +++ b/src/entity/ExperienceManager.php @@ -227,7 +227,6 @@ class ExperienceManager{ $this->totalXp = $amount; } - /** * Returns whether the human can pickup XP orbs (checks cooldown time) */ diff --git a/src/entity/Explosive.php b/src/entity/Explosive.php index 347c68a49a..94922cb19f 100644 --- a/src/entity/Explosive.php +++ b/src/entity/Explosive.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\entity; - interface Explosive{ public function explode() : void; diff --git a/src/entity/Living.php b/src/entity/Living.php index 0f741ff0f7..9dc43442b6 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -203,7 +203,6 @@ abstract class Living extends Entity{ return $nbt; } - public function hasLineOfSight(Entity $entity) : bool{ //TODO: head height return true; diff --git a/src/entity/Squid.php b/src/entity/Squid.php index 4b98c24019..a5ec3a4077 100644 --- a/src/entity/Squid.php +++ b/src/entity/Squid.php @@ -79,7 +79,6 @@ class Squid extends WaterAnimal{ return new Vector3(mt_rand(-1000, 1000) / 1000, mt_rand(-500, 500) / 1000, mt_rand(-1000, 1000) / 1000); } - protected function entityBaseTick(int $tickDiff = 1) : bool{ if($this->closed){ return false; diff --git a/src/entity/effect/VanillaEffects.php b/src/entity/effect/VanillaEffects.php index a20b4ebb63..c714c18429 100644 --- a/src/entity/effect/VanillaEffects.php +++ b/src/entity/effect/VanillaEffects.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\entity\effect; - use pocketmine\utils\Color; use pocketmine\utils\RegistryTrait; use function assert; diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index 092bfe85c6..32b2ba8058 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -80,7 +80,6 @@ class ItemEntity extends Entity{ $this->owner = $nbt->getString("Owner", $this->owner); $this->thrower = $nbt->getString("Thrower", $this->thrower); - $itemTag = $nbt->getCompoundTag("Item"); if($itemTag === null){ throw new \UnexpectedValueException("Invalid " . get_class($this) . " entity: expected \"Item\" NBT tag not found"); @@ -91,7 +90,6 @@ class ItemEntity extends Entity{ throw new \UnexpectedValueException("Item for " . get_class($this) . " is invalid"); } - (new ItemSpawnEvent($this))->call(); } diff --git a/src/entity/object/PaintingMotive.php b/src/entity/object/PaintingMotive.php index 1ae1deb176..a21bba2fc4 100644 --- a/src/entity/object/PaintingMotive.php +++ b/src/entity/object/PaintingMotive.php @@ -86,7 +86,6 @@ class PaintingMotive{ /** @var int */ protected $height; - public function __construct(int $width, int $height, string $name){ $this->name = $name; $this->width = $width; diff --git a/src/entity/object/PrimedTNT.php b/src/entity/object/PrimedTNT.php index 084c7f4894..505b22f555 100644 --- a/src/entity/object/PrimedTNT.php +++ b/src/entity/object/PrimedTNT.php @@ -51,7 +51,6 @@ class PrimedTNT extends Entity implements Explosive{ public $canCollide = false; - public function attack(EntityDamageEvent $source) : void{ if($source->getCause() === EntityDamageEvent::CAUSE_VOID){ parent::attack($source); @@ -66,7 +65,6 @@ class PrimedTNT extends Entity implements Explosive{ $this->getWorld()->addSound($this->location, new IgniteSound()); } - public function canCollideWith(Entity $entity) : bool{ return false; } diff --git a/src/entity/projectile/Projectile.php b/src/entity/projectile/Projectile.php index db2b5bcce4..82a1aa9922 100644 --- a/src/entity/projectile/Projectile.php +++ b/src/entity/projectile/Projectile.php @@ -261,7 +261,6 @@ abstract class Projectile extends Entity{ $this->checkChunks(); $this->checkBlockCollision(); - Timings::$entityMoveTimer->stopTiming(); } diff --git a/src/entity/projectile/ProjectileSource.php b/src/entity/projectile/ProjectileSource.php index 0bab7da5f2..e74cafad9a 100644 --- a/src/entity/projectile/ProjectileSource.php +++ b/src/entity/projectile/ProjectileSource.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\entity\projectile; - interface ProjectileSource{ } diff --git a/src/event/Cancellable.php b/src/event/Cancellable.php index 1e439ad31d..023549023d 100644 --- a/src/event/Cancellable.php +++ b/src/event/Cancellable.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\event; - /** * Events that can be cancelled must use the interface Cancellable */ diff --git a/src/event/block/BlockBreakEvent.php b/src/event/block/BlockBreakEvent.php index 68f3fae189..ca28352c36 100644 --- a/src/event/block/BlockBreakEvent.php +++ b/src/event/block/BlockBreakEvent.php @@ -87,7 +87,6 @@ class BlockBreakEvent extends BlockEvent implements Cancellable{ $this->instaBreak = $instaBreak; } - /** * @return Item[] */ diff --git a/src/event/plugin/PluginDisableEvent.php b/src/event/plugin/PluginDisableEvent.php index e551f7f3ac..6f847b7a44 100644 --- a/src/event/plugin/PluginDisableEvent.php +++ b/src/event/plugin/PluginDisableEvent.php @@ -21,7 +21,6 @@ declare(strict_types=1); - namespace pocketmine\event\plugin; class PluginDisableEvent extends PluginEvent{ diff --git a/src/event/plugin/PluginEnableEvent.php b/src/event/plugin/PluginEnableEvent.php index f00dd249e7..7496be1f35 100644 --- a/src/event/plugin/PluginEnableEvent.php +++ b/src/event/plugin/PluginEnableEvent.php @@ -21,7 +21,6 @@ declare(strict_types=1); - namespace pocketmine\event\plugin; class PluginEnableEvent extends PluginEvent{ diff --git a/src/event/server/LowMemoryEvent.php b/src/event/server/LowMemoryEvent.php index ecdfb2f469..46f0c8022c 100644 --- a/src/event/server/LowMemoryEvent.php +++ b/src/event/server/LowMemoryEvent.php @@ -25,7 +25,6 @@ namespace pocketmine\event\server; use pocketmine\utils\Process; - /** * Called when the server is in a low-memory state as defined by the properties * Plugins should free caches or other non-essential data. diff --git a/src/event/world/ChunkEvent.php b/src/event/world/ChunkEvent.php index 02db808e22..2c5cb5e512 100644 --- a/src/event/world/ChunkEvent.php +++ b/src/event/world/ChunkEvent.php @@ -21,7 +21,6 @@ declare(strict_types=1); - namespace pocketmine\event\world; use pocketmine\world\format\Chunk; diff --git a/src/event/world/ChunkLoadEvent.php b/src/event/world/ChunkLoadEvent.php index 3e6dad4086..a03c4ad159 100644 --- a/src/event/world/ChunkLoadEvent.php +++ b/src/event/world/ChunkLoadEvent.php @@ -21,7 +21,6 @@ declare(strict_types=1); - namespace pocketmine\event\world; use pocketmine\world\format\Chunk; diff --git a/src/item/Apple.php b/src/item/Apple.php index 82dfcf7890..5f2a711c01 100644 --- a/src/item/Apple.php +++ b/src/item/Apple.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\item; - class Apple extends Food{ public function getFoodRestore() : int{ diff --git a/src/item/Armor.php b/src/item/Armor.php index 3b64f6b084..a9b469965a 100644 --- a/src/item/Armor.php +++ b/src/item/Armor.php @@ -21,7 +21,6 @@ declare(strict_types=1); - namespace pocketmine\item; use pocketmine\block\Block; diff --git a/src/item/Banner.php b/src/item/Banner.php index db566f7de5..fa91c2c668 100644 --- a/src/item/Banner.php +++ b/src/item/Banner.php @@ -115,7 +115,6 @@ class Banner extends Item{ ); } - $tag->setTag(self::TAG_PATTERNS, $patterns); }else{ $tag->removeTag(self::TAG_PATTERNS); diff --git a/src/item/BeetrootSoup.php b/src/item/BeetrootSoup.php index 8f8e5bed1e..2671317392 100644 --- a/src/item/BeetrootSoup.php +++ b/src/item/BeetrootSoup.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\item; - class BeetrootSoup extends Food{ public function getMaxStackSize() : int{ diff --git a/src/item/Bowl.php b/src/item/Bowl.php index 47b93a2a86..66ef530b01 100644 --- a/src/item/Bowl.php +++ b/src/item/Bowl.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\item; - class Bowl extends Item{ //TODO: check fuel diff --git a/src/item/Coal.php b/src/item/Coal.php index ebdb65ee37..55aa444400 100644 --- a/src/item/Coal.php +++ b/src/item/Coal.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\item; - class Coal extends Item{ public function getFuelTime() : int{ diff --git a/src/item/ItemEnchantmentHandlingTrait.php b/src/item/ItemEnchantmentHandlingTrait.php index 23ca86b032..3760e16c67 100644 --- a/src/item/ItemEnchantmentHandlingTrait.php +++ b/src/item/ItemEnchantmentHandlingTrait.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\item; - use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\EnchantmentInstance; diff --git a/src/item/Stick.php b/src/item/Stick.php index d7b749e05e..59c5ed91be 100644 --- a/src/item/Stick.php +++ b/src/item/Stick.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\item; - class Stick extends Item{ public function getFuelTime() : int{ diff --git a/src/item/ToolTier.php b/src/item/ToolTier.php index f15ba7c3aa..1f2190bb8c 100644 --- a/src/item/ToolTier.php +++ b/src/item/ToolTier.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\item; - use pocketmine\utils\EnumTrait; /** diff --git a/src/item/enchantment/EnchantmentEntry.php b/src/item/enchantment/EnchantmentEntry.php index 287305aec1..6463d6cd56 100644 --- a/src/item/enchantment/EnchantmentEntry.php +++ b/src/item/enchantment/EnchantmentEntry.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\item\enchantment; - class EnchantmentEntry{ /** @var Enchantment[] */ diff --git a/src/item/enchantment/EnchantmentList.php b/src/item/enchantment/EnchantmentList.php index 90914e0903..617ca13afe 100644 --- a/src/item/enchantment/EnchantmentList.php +++ b/src/item/enchantment/EnchantmentList.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\item\enchantment; - class EnchantmentList{ /** @var \SplFixedArray|EnchantmentEntry[] */ diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index f0d6876fc0..a0bb6f3b03 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -50,7 +50,6 @@ class LoginPacketHandler extends PacketHandler{ /** @var NetworkSession */ private $session; - public function __construct(Server $server, NetworkSession $session){ $this->session = $session; $this->server = $server; diff --git a/src/network/mcpe/handler/ResourcePacksPacketHandler.php b/src/network/mcpe/handler/ResourcePacksPacketHandler.php index ea97d9f47b..1f79bf988e 100644 --- a/src/network/mcpe/handler/ResourcePacksPacketHandler.php +++ b/src/network/mcpe/handler/ResourcePacksPacketHandler.php @@ -57,7 +57,6 @@ class ResourcePacksPacketHandler extends PacketHandler{ /** @var bool[][] uuid => [chunk index => hasSent] */ private $downloadedChunks = []; - public function __construct(NetworkSession $session, ResourcePackManager $resourcePackManager){ $this->session = $session; $this->resourcePackManager = $resourcePackManager; diff --git a/src/network/mcpe/protocol/ActorFallPacket.php b/src/network/mcpe/protocol/ActorFallPacket.php index ab2d59fcb2..420940f239 100644 --- a/src/network/mcpe/protocol/ActorFallPacket.php +++ b/src/network/mcpe/protocol/ActorFallPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class ActorFallPacket extends DataPacket implements ServerboundPacket{ diff --git a/src/network/mcpe/protocol/AdventureSettingsPacket.php b/src/network/mcpe/protocol/AdventureSettingsPacket.php index a1f76b5523..71164de3d1 100644 --- a/src/network/mcpe/protocol/AdventureSettingsPacket.php +++ b/src/network/mcpe/protocol/AdventureSettingsPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; diff --git a/src/network/mcpe/protocol/AnimatePacket.php b/src/network/mcpe/protocol/AnimatePacket.php index 5fb3cb8a74..abb02d70e8 100644 --- a/src/network/mcpe/protocol/AnimatePacket.php +++ b/src/network/mcpe/protocol/AnimatePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class AnimatePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ diff --git a/src/network/mcpe/protocol/AvailableCommandsPacket.php b/src/network/mcpe/protocol/AvailableCommandsPacket.php index e7b8847d85..67fcf2a1f3 100644 --- a/src/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/network/mcpe/protocol/AvailableCommandsPacket.php @@ -39,7 +39,6 @@ use function dechex; class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::AVAILABLE_COMMANDS_PACKET; - /** * This flag is set on all types EXCEPT the POSTFIX type. Not completely sure what this is for, but it is required * for the argtype to work correctly. VALID seems as good a name as any. diff --git a/src/network/mcpe/protocol/BlockActorDataPacket.php b/src/network/mcpe/protocol/BlockActorDataPacket.php index 6e4b428e54..476a33f91b 100644 --- a/src/network/mcpe/protocol/BlockActorDataPacket.php +++ b/src/network/mcpe/protocol/BlockActorDataPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class BlockActorDataPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ diff --git a/src/network/mcpe/protocol/BlockEventPacket.php b/src/network/mcpe/protocol/BlockEventPacket.php index 9badd3036e..855995ac8c 100644 --- a/src/network/mcpe/protocol/BlockEventPacket.php +++ b/src/network/mcpe/protocol/BlockEventPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; diff --git a/src/network/mcpe/protocol/BlockPickRequestPacket.php b/src/network/mcpe/protocol/BlockPickRequestPacket.php index cc6ea483e3..8e2760b7ee 100644 --- a/src/network/mcpe/protocol/BlockPickRequestPacket.php +++ b/src/network/mcpe/protocol/BlockPickRequestPacket.php @@ -21,12 +21,10 @@ declare(strict_types=1); - namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class BlockPickRequestPacket extends DataPacket implements ServerboundPacket{ diff --git a/src/network/mcpe/protocol/BossEventPacket.php b/src/network/mcpe/protocol/BossEventPacket.php index 3a504c695e..bc215e1546 100644 --- a/src/network/mcpe/protocol/BossEventPacket.php +++ b/src/network/mcpe/protocol/BossEventPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class BossEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ diff --git a/src/network/mcpe/protocol/ChangeDimensionPacket.php b/src/network/mcpe/protocol/ChangeDimensionPacket.php index 95b66d4d40..0cf5dfae5c 100644 --- a/src/network/mcpe/protocol/ChangeDimensionPacket.php +++ b/src/network/mcpe/protocol/ChangeDimensionPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; diff --git a/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php b/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php index 3ff77d51ad..567c291e44 100644 --- a/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php +++ b/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class ChunkRadiusUpdatedPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/ClientToServerHandshakePacket.php b/src/network/mcpe/protocol/ClientToServerHandshakePacket.php index 99e2d0545d..697d462461 100644 --- a/src/network/mcpe/protocol/ClientToServerHandshakePacket.php +++ b/src/network/mcpe/protocol/ClientToServerHandshakePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class ClientToServerHandshakePacket extends DataPacket implements ServerboundPacket{ diff --git a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php index 503fec5307..e702121b4f 100644 --- a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php +++ b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php @@ -21,12 +21,10 @@ declare(strict_types=1); - namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\DimensionIds; diff --git a/src/network/mcpe/protocol/CommandBlockUpdatePacket.php b/src/network/mcpe/protocol/CommandBlockUpdatePacket.php index 51b610db56..da4f66ec3e 100644 --- a/src/network/mcpe/protocol/CommandBlockUpdatePacket.php +++ b/src/network/mcpe/protocol/CommandBlockUpdatePacket.php @@ -21,12 +21,10 @@ declare(strict_types=1); - namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class CommandBlockUpdatePacket extends DataPacket implements ServerboundPacket{ diff --git a/src/network/mcpe/protocol/ContainerClosePacket.php b/src/network/mcpe/protocol/ContainerClosePacket.php index d60ae79520..1d3ae9c6f0 100644 --- a/src/network/mcpe/protocol/ContainerClosePacket.php +++ b/src/network/mcpe/protocol/ContainerClosePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class ContainerClosePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ diff --git a/src/network/mcpe/protocol/ContainerOpenPacket.php b/src/network/mcpe/protocol/ContainerOpenPacket.php index 6b36f97820..2361de87d9 100644 --- a/src/network/mcpe/protocol/ContainerOpenPacket.php +++ b/src/network/mcpe/protocol/ContainerOpenPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; diff --git a/src/network/mcpe/protocol/ContainerSetDataPacket.php b/src/network/mcpe/protocol/ContainerSetDataPacket.php index 1782b66f54..d8b3a59342 100644 --- a/src/network/mcpe/protocol/ContainerSetDataPacket.php +++ b/src/network/mcpe/protocol/ContainerSetDataPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class ContainerSetDataPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/CraftingDataPacket.php b/src/network/mcpe/protocol/CraftingDataPacket.php index 8ac5b2cf83..f586b76b39 100644 --- a/src/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/network/mcpe/protocol/CraftingDataPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\crafting\FurnaceRecipe; use pocketmine\crafting\ShapedRecipe; use pocketmine\crafting\ShapelessRecipe; diff --git a/src/network/mcpe/protocol/DisconnectPacket.php b/src/network/mcpe/protocol/DisconnectPacket.php index d026193417..3c665d3447 100644 --- a/src/network/mcpe/protocol/DisconnectPacket.php +++ b/src/network/mcpe/protocol/DisconnectPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class DisconnectPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ diff --git a/src/network/mcpe/protocol/HurtArmorPacket.php b/src/network/mcpe/protocol/HurtArmorPacket.php index 6dbef6649c..b9e236c4f7 100644 --- a/src/network/mcpe/protocol/HurtArmorPacket.php +++ b/src/network/mcpe/protocol/HurtArmorPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class HurtArmorPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/InteractPacket.php b/src/network/mcpe/protocol/InteractPacket.php index 5ae4d1fe87..03773799f0 100644 --- a/src/network/mcpe/protocol/InteractPacket.php +++ b/src/network/mcpe/protocol/InteractPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class InteractPacket extends DataPacket implements ServerboundPacket{ diff --git a/src/network/mcpe/protocol/LoginPacket.php b/src/network/mcpe/protocol/LoginPacket.php index 8ae9f09be8..57578f57cf 100644 --- a/src/network/mcpe/protocol/LoginPacket.php +++ b/src/network/mcpe/protocol/LoginPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use Particle\Validator\Validator; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\PacketHandler; diff --git a/src/network/mcpe/protocol/MapInfoRequestPacket.php b/src/network/mcpe/protocol/MapInfoRequestPacket.php index a1bc4144fe..08248acf42 100644 --- a/src/network/mcpe/protocol/MapInfoRequestPacket.php +++ b/src/network/mcpe/protocol/MapInfoRequestPacket.php @@ -21,12 +21,10 @@ declare(strict_types=1); - namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class MapInfoRequestPacket extends DataPacket implements ServerboundPacket{ diff --git a/src/network/mcpe/protocol/MobArmorEquipmentPacket.php b/src/network/mcpe/protocol/MobArmorEquipmentPacket.php index 38f9305c5a..22b1556e82 100644 --- a/src/network/mcpe/protocol/MobArmorEquipmentPacket.php +++ b/src/network/mcpe/protocol/MobArmorEquipmentPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\item\Item; use pocketmine\network\mcpe\handler\PacketHandler; diff --git a/src/network/mcpe/protocol/MobEffectPacket.php b/src/network/mcpe/protocol/MobEffectPacket.php index 15c8c8a39c..03912a5fc6 100644 --- a/src/network/mcpe/protocol/MobEffectPacket.php +++ b/src/network/mcpe/protocol/MobEffectPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class MobEffectPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/MobEquipmentPacket.php b/src/network/mcpe/protocol/MobEquipmentPacket.php index d4cad955de..8b5486218d 100644 --- a/src/network/mcpe/protocol/MobEquipmentPacket.php +++ b/src/network/mcpe/protocol/MobEquipmentPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\item\Item; use pocketmine\network\mcpe\handler\PacketHandler; diff --git a/src/network/mcpe/protocol/MoveActorAbsolutePacket.php b/src/network/mcpe/protocol/MoveActorAbsolutePacket.php index f42a51a9c6..04116f46f8 100644 --- a/src/network/mcpe/protocol/MoveActorAbsolutePacket.php +++ b/src/network/mcpe/protocol/MoveActorAbsolutePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; diff --git a/src/network/mcpe/protocol/MovePlayerPacket.php b/src/network/mcpe/protocol/MovePlayerPacket.php index 6f6c6c06f7..98786299e1 100644 --- a/src/network/mcpe/protocol/MovePlayerPacket.php +++ b/src/network/mcpe/protocol/MovePlayerPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; diff --git a/src/network/mcpe/protocol/PlaySoundPacket.php b/src/network/mcpe/protocol/PlaySoundPacket.php index 952a97fb85..cda6b01a14 100644 --- a/src/network/mcpe/protocol/PlaySoundPacket.php +++ b/src/network/mcpe/protocol/PlaySoundPacket.php @@ -21,12 +21,10 @@ declare(strict_types=1); - namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class PlaySoundPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/PlayStatusPacket.php b/src/network/mcpe/protocol/PlayStatusPacket.php index 9084a3fa2c..9f4402d18b 100644 --- a/src/network/mcpe/protocol/PlayStatusPacket.php +++ b/src/network/mcpe/protocol/PlayStatusPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class PlayStatusPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/PlayerActionPacket.php b/src/network/mcpe/protocol/PlayerActionPacket.php index c79ddd25bf..7cffd0c5fe 100644 --- a/src/network/mcpe/protocol/PlayerActionPacket.php +++ b/src/network/mcpe/protocol/PlayerActionPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class PlayerActionPacket extends DataPacket implements ServerboundPacket{ diff --git a/src/network/mcpe/protocol/PlayerInputPacket.php b/src/network/mcpe/protocol/PlayerInputPacket.php index 1d4fd0b97c..6828cdaa57 100644 --- a/src/network/mcpe/protocol/PlayerInputPacket.php +++ b/src/network/mcpe/protocol/PlayerInputPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class PlayerInputPacket extends DataPacket implements ServerboundPacket{ diff --git a/src/network/mcpe/protocol/PlayerListPacket.php b/src/network/mcpe/protocol/PlayerListPacket.php index a4ca1c4eb4..8431c354eb 100644 --- a/src/network/mcpe/protocol/PlayerListPacket.php +++ b/src/network/mcpe/protocol/PlayerListPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use function count; diff --git a/src/network/mcpe/protocol/RemoveActorPacket.php b/src/network/mcpe/protocol/RemoveActorPacket.php index 690e5c1615..54e8aedede 100644 --- a/src/network/mcpe/protocol/RemoveActorPacket.php +++ b/src/network/mcpe/protocol/RemoveActorPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class RemoveActorPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/RequestChunkRadiusPacket.php b/src/network/mcpe/protocol/RequestChunkRadiusPacket.php index cc3caa251f..7d7fccf86e 100644 --- a/src/network/mcpe/protocol/RequestChunkRadiusPacket.php +++ b/src/network/mcpe/protocol/RequestChunkRadiusPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class RequestChunkRadiusPacket extends DataPacket implements ServerboundPacket{ diff --git a/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php b/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php index 4fbe71f847..87e1496bc5 100644 --- a/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php +++ b/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php @@ -21,12 +21,10 @@ declare(strict_types=1); - namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; use function strlen; diff --git a/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php b/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php index d414ba1b40..c15e7c3d27 100644 --- a/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php +++ b/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php @@ -21,12 +21,10 @@ declare(strict_types=1); - namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class ResourcePackChunkRequestPacket extends DataPacket implements ServerboundPacket{ diff --git a/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php b/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php index 833c3982c3..06bd7a039d 100644 --- a/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php +++ b/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; use function count; diff --git a/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php b/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php index c0bc3ad8eb..37fbde3b92 100644 --- a/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php +++ b/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php @@ -21,12 +21,10 @@ declare(strict_types=1); - namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackType; diff --git a/src/network/mcpe/protocol/ResourcePackStackPacket.php b/src/network/mcpe/protocol/ResourcePackStackPacket.php index 69d1684028..08d4e572cb 100644 --- a/src/network/mcpe/protocol/ResourcePackStackPacket.php +++ b/src/network/mcpe/protocol/ResourcePackStackPacket.php @@ -21,12 +21,10 @@ declare(strict_types=1); - namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackStackEntry; use function count; diff --git a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php index 753d60486d..868e219420 100644 --- a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php +++ b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackInfoEntry; use function count; diff --git a/src/network/mcpe/protocol/RespawnPacket.php b/src/network/mcpe/protocol/RespawnPacket.php index ff6d450be5..923ea7a4dc 100644 --- a/src/network/mcpe/protocol/RespawnPacket.php +++ b/src/network/mcpe/protocol/RespawnPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; diff --git a/src/network/mcpe/protocol/RiderJumpPacket.php b/src/network/mcpe/protocol/RiderJumpPacket.php index fad394c4f8..c6b9f534d3 100644 --- a/src/network/mcpe/protocol/RiderJumpPacket.php +++ b/src/network/mcpe/protocol/RiderJumpPacket.php @@ -21,12 +21,10 @@ declare(strict_types=1); - namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class RiderJumpPacket extends DataPacket implements ServerboundPacket{ diff --git a/src/network/mcpe/protocol/ServerToClientHandshakePacket.php b/src/network/mcpe/protocol/ServerToClientHandshakePacket.php index 78ce6ad827..577bf38dcf 100644 --- a/src/network/mcpe/protocol/ServerToClientHandshakePacket.php +++ b/src/network/mcpe/protocol/ServerToClientHandshakePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class ServerToClientHandshakePacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/SetActorDataPacket.php b/src/network/mcpe/protocol/SetActorDataPacket.php index cb9a603395..b25bb91d53 100644 --- a/src/network/mcpe/protocol/SetActorDataPacket.php +++ b/src/network/mcpe/protocol/SetActorDataPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; diff --git a/src/network/mcpe/protocol/SetActorLinkPacket.php b/src/network/mcpe/protocol/SetActorLinkPacket.php index a8cfbb4210..6e03372d8b 100644 --- a/src/network/mcpe/protocol/SetActorLinkPacket.php +++ b/src/network/mcpe/protocol/SetActorLinkPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; diff --git a/src/network/mcpe/protocol/SetActorMotionPacket.php b/src/network/mcpe/protocol/SetActorMotionPacket.php index dae0e6f8af..863af7485b 100644 --- a/src/network/mcpe/protocol/SetActorMotionPacket.php +++ b/src/network/mcpe/protocol/SetActorMotionPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; diff --git a/src/network/mcpe/protocol/SetCommandsEnabledPacket.php b/src/network/mcpe/protocol/SetCommandsEnabledPacket.php index 986350d052..6f0d1bcb3f 100644 --- a/src/network/mcpe/protocol/SetCommandsEnabledPacket.php +++ b/src/network/mcpe/protocol/SetCommandsEnabledPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class SetCommandsEnabledPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/SetDifficultyPacket.php b/src/network/mcpe/protocol/SetDifficultyPacket.php index 9aa2df4f4e..a6de96175c 100644 --- a/src/network/mcpe/protocol/SetDifficultyPacket.php +++ b/src/network/mcpe/protocol/SetDifficultyPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class SetDifficultyPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ diff --git a/src/network/mcpe/protocol/SetHealthPacket.php b/src/network/mcpe/protocol/SetHealthPacket.php index e11b05a84c..4efee7493d 100644 --- a/src/network/mcpe/protocol/SetHealthPacket.php +++ b/src/network/mcpe/protocol/SetHealthPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class SetHealthPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/SetPlayerGameTypePacket.php b/src/network/mcpe/protocol/SetPlayerGameTypePacket.php index 5385ec6a53..94695ac4aa 100644 --- a/src/network/mcpe/protocol/SetPlayerGameTypePacket.php +++ b/src/network/mcpe/protocol/SetPlayerGameTypePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class SetPlayerGameTypePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ diff --git a/src/network/mcpe/protocol/SetSpawnPositionPacket.php b/src/network/mcpe/protocol/SetSpawnPositionPacket.php index 41b2aeaf38..a5c600110e 100644 --- a/src/network/mcpe/protocol/SetSpawnPositionPacket.php +++ b/src/network/mcpe/protocol/SetSpawnPositionPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class SetSpawnPositionPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/SetTitlePacket.php b/src/network/mcpe/protocol/SetTitlePacket.php index f6afe5b6d1..937dffeca8 100644 --- a/src/network/mcpe/protocol/SetTitlePacket.php +++ b/src/network/mcpe/protocol/SetTitlePacket.php @@ -21,12 +21,10 @@ declare(strict_types=1); - namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class SetTitlePacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/ShowCreditsPacket.php b/src/network/mcpe/protocol/ShowCreditsPacket.php index 959f88c8b0..d898831f4e 100644 --- a/src/network/mcpe/protocol/ShowCreditsPacket.php +++ b/src/network/mcpe/protocol/ShowCreditsPacket.php @@ -21,12 +21,10 @@ declare(strict_types=1); - namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class ShowCreditsPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ diff --git a/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php b/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php index c7dcd25fbb..0ce2e61254 100644 --- a/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php +++ b/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; diff --git a/src/network/mcpe/protocol/StartGamePacket.php b/src/network/mcpe/protocol/StartGamePacket.php index 8e95ad56e3..5669f326aa 100644 --- a/src/network/mcpe/protocol/StartGamePacket.php +++ b/src/network/mcpe/protocol/StartGamePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\math\Vector3; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\TreeRoot; diff --git a/src/network/mcpe/protocol/StopSoundPacket.php b/src/network/mcpe/protocol/StopSoundPacket.php index 83d44d8066..72460d70d2 100644 --- a/src/network/mcpe/protocol/StopSoundPacket.php +++ b/src/network/mcpe/protocol/StopSoundPacket.php @@ -21,12 +21,10 @@ declare(strict_types=1); - namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class StopSoundPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/TakeItemActorPacket.php b/src/network/mcpe/protocol/TakeItemActorPacket.php index 36dd8fa629..1968922ddb 100644 --- a/src/network/mcpe/protocol/TakeItemActorPacket.php +++ b/src/network/mcpe/protocol/TakeItemActorPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class TakeItemActorPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/TextPacket.php b/src/network/mcpe/protocol/TextPacket.php index b167e2a197..d227eb0a92 100644 --- a/src/network/mcpe/protocol/TextPacket.php +++ b/src/network/mcpe/protocol/TextPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; use function count; diff --git a/src/network/mcpe/protocol/UnknownPacket.php b/src/network/mcpe/protocol/UnknownPacket.php index 490471dfe5..184115b07c 100644 --- a/src/network/mcpe/protocol/UnknownPacket.php +++ b/src/network/mcpe/protocol/UnknownPacket.php @@ -21,10 +21,8 @@ declare(strict_types=1); - namespace pocketmine\network\mcpe\protocol; - use pocketmine\network\mcpe\handler\PacketHandler; use function ord; use function strlen; diff --git a/src/network/mcpe/protocol/UpdateAttributesPacket.php b/src/network/mcpe/protocol/UpdateAttributesPacket.php index de37371e36..18a7e7acec 100644 --- a/src/network/mcpe/protocol/UpdateAttributesPacket.php +++ b/src/network/mcpe/protocol/UpdateAttributesPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\entity\Attribute; use pocketmine\network\mcpe\handler\PacketHandler; use function array_values; diff --git a/src/network/mcpe/protocol/UpdateBlockPacket.php b/src/network/mcpe/protocol/UpdateBlockPacket.php index 306d0ad257..46729ab80d 100644 --- a/src/network/mcpe/protocol/UpdateBlockPacket.php +++ b/src/network/mcpe/protocol/UpdateBlockPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; class UpdateBlockPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/UpdateTradePacket.php b/src/network/mcpe/protocol/UpdateTradePacket.php index bfb0537f0b..08d01c76d1 100644 --- a/src/network/mcpe/protocol/UpdateTradePacket.php +++ b/src/network/mcpe/protocol/UpdateTradePacket.php @@ -21,12 +21,10 @@ declare(strict_types=1); - namespace pocketmine\network\mcpe\protocol; #include - use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes; diff --git a/src/network/mcpe/protocol/types/entity/EntityLegacyIds.php b/src/network/mcpe/protocol/types/entity/EntityLegacyIds.php index a59e0a628a..a0745e7ee9 100644 --- a/src/network/mcpe/protocol/types/entity/EntityLegacyIds.php +++ b/src/network/mcpe/protocol/types/entity/EntityLegacyIds.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; - final class EntityLegacyIds{ public const CHICKEN = 10; diff --git a/src/network/mcpe/protocol/types/inventory/WindowTypes.php b/src/network/mcpe/protocol/types/inventory/WindowTypes.php index 6ee75daa1e..33aeb9c57a 100644 --- a/src/network/mcpe/protocol/types/inventory/WindowTypes.php +++ b/src/network/mcpe/protocol/types/inventory/WindowTypes.php @@ -21,10 +21,8 @@ declare(strict_types=1); - namespace pocketmine\network\mcpe\protocol\types\inventory; - final class WindowTypes{ private function __construct(){ diff --git a/src/network/mcpe/serializer/NetworkBinaryStream.php b/src/network/mcpe/serializer/NetworkBinaryStream.php index df66701501..2bbceec742 100644 --- a/src/network/mcpe/serializer/NetworkBinaryStream.php +++ b/src/network/mcpe/serializer/NetworkBinaryStream.php @@ -227,7 +227,6 @@ class NetworkBinaryStream extends BinaryStream{ } } - public function putSlot(Item $item) : void{ if($item->getId() === 0){ $this->putVarInt(0); diff --git a/src/permission/PermissionAttachmentInfo.php b/src/permission/PermissionAttachmentInfo.php index 57297a11cf..ad934f693c 100644 --- a/src/permission/PermissionAttachmentInfo.php +++ b/src/permission/PermissionAttachmentInfo.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\permission; - class PermissionAttachmentInfo{ /** @var Permissible */ private $permissible; diff --git a/src/permission/PermissionRemovedExecutor.php b/src/permission/PermissionRemovedExecutor.php index 71076d94dc..606d017ee5 100644 --- a/src/permission/PermissionRemovedExecutor.php +++ b/src/permission/PermissionRemovedExecutor.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\permission; - interface PermissionRemovedExecutor{ public function attachmentRemoved(PermissionAttachment $attachment) : void; diff --git a/src/permission/ServerOperator.php b/src/permission/ServerOperator.php index c9fe3afd84..bc5f233f23 100644 --- a/src/permission/ServerOperator.php +++ b/src/permission/ServerOperator.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\permission; - interface ServerOperator{ /** * Checks if the current object has operator permissions diff --git a/src/player/Player.php b/src/player/Player.php index a51a622cb8..57bac6e86b 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -125,7 +125,6 @@ use const M_PI; use const M_SQRT3; use const PHP_INT_MAX; - /** * Main class that handles networking, recovery, and packet sending to the server part */ @@ -2362,5 +2361,4 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->location->getZ(); } - } diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 76f69ff660..dce9ca86eb 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -278,7 +278,6 @@ class PluginManager{ } } - while(count($plugins) > 0){ $loadedThisLoop = 0; foreach($plugins as $name => $file){ diff --git a/src/resourcepacks/ResourcePack.php b/src/resourcepacks/ResourcePack.php index 74f8978880..aee9cf2c2c 100644 --- a/src/resourcepacks/ResourcePack.php +++ b/src/resourcepacks/ResourcePack.php @@ -21,10 +21,8 @@ declare(strict_types=1); - namespace pocketmine\resourcepacks; - interface ResourcePack{ /** diff --git a/src/resourcepacks/ResourcePackManager.php b/src/resourcepacks/ResourcePackManager.php index 2891179273..bbe83ca3c6 100644 --- a/src/resourcepacks/ResourcePackManager.php +++ b/src/resourcepacks/ResourcePackManager.php @@ -21,7 +21,6 @@ declare(strict_types=1); - namespace pocketmine\resourcepacks; use pocketmine\utils\Config; diff --git a/src/resourcepacks/ZippedResourcePack.php b/src/resourcepacks/ZippedResourcePack.php index 3b262759fc..f0106573c5 100644 --- a/src/resourcepacks/ZippedResourcePack.php +++ b/src/resourcepacks/ZippedResourcePack.php @@ -21,10 +21,8 @@ declare(strict_types=1); - namespace pocketmine\resourcepacks; - use Ahc\Json\Comment as CommentedJsonDecoder; use function count; use function fclose; diff --git a/src/scheduler/SendUsageTask.php b/src/scheduler/SendUsageTask.php index 547b566f82..f9ad8cd81b 100644 --- a/src/scheduler/SendUsageTask.php +++ b/src/scheduler/SendUsageTask.php @@ -115,7 +115,6 @@ class SendUsageTask extends AsyncTask{ "ticks" => $server->getTick() ]; - //This anonymizes the user ids so they cannot be reversed to the original foreach($playerList as $k => $v){ $playerList[$k] = md5($v); diff --git a/src/updater/UpdateCheckTask.php b/src/updater/UpdateCheckTask.php index 23efebb1bf..0129057859 100644 --- a/src/updater/UpdateCheckTask.php +++ b/src/updater/UpdateCheckTask.php @@ -21,7 +21,6 @@ declare(strict_types=1); - namespace pocketmine\updater; use pocketmine\scheduler\AsyncTask; diff --git a/src/utils/Process.php b/src/utils/Process.php index de2aee85ef..67441e729b 100644 --- a/src/utils/Process.php +++ b/src/utils/Process.php @@ -104,7 +104,6 @@ final class Process{ return [$heap, $stack]; } - public static function getThreadCount() : int{ if(Utils::getOS() === "linux" or Utils::getOS() === "android"){ if(preg_match("/Threads:[ \t]+([0-9]+)/", file_get_contents("/proc/self/status"), $matches) > 0){ diff --git a/src/utils/Timezone.php b/src/utils/Timezone.php index ff15d46adf..8158956c10 100644 --- a/src/utils/Timezone.php +++ b/src/utils/Timezone.php @@ -177,7 +177,6 @@ abstract class Timezone{ } } - /** * @param string $offset In the format of +09:00, +02:00, -04:00 etc. * diff --git a/src/utils/Utils.php b/src/utils/Utils.php index aa41cf5afe..1c634a8757 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -303,7 +303,6 @@ class Utils{ return $output; } - /** * Returns a string that can be printed, replaces non-printable characters * @@ -348,7 +347,6 @@ class Utils{ return $hash; } - /** * @return array of claims * diff --git a/src/utils/VersionString.php b/src/utils/VersionString.php index 37d803503d..ca100a8434 100644 --- a/src/utils/VersionString.php +++ b/src/utils/VersionString.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\utils; - use function count; use function preg_match; diff --git a/src/wizard/SetupWizard.php b/src/wizard/SetupWizard.php index 86d49b5545..66862b9f99 100644 --- a/src/wizard/SetupWizard.php +++ b/src/wizard/SetupWizard.php @@ -200,7 +200,6 @@ LICENSE; $config->save(); - $this->message($this->lang->get("ip_get")); $externalIP = Internet::getIP(); diff --git a/src/world/Explosion.php b/src/world/Explosion.php index ab295359a8..b6b5745970 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -203,7 +203,6 @@ class Explosion{ } } - $air = ItemFactory::air(); $airBlock = VanillaBlocks::AIR(); diff --git a/src/world/World.php b/src/world/World.php index 4faf36241f..3365e664dc 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -927,7 +927,6 @@ class World implements ChunkManager{ $entity->scheduleUpdate(); } - foreach($chunk->getSubChunks() as $Y => $subChunk){ if(!$subChunk->isEmptyFast()){ $k = mt_rand(0, 0xfffffffff); //36 bits @@ -1046,7 +1045,6 @@ class World implements ChunkManager{ } } - return $collides; } @@ -1589,7 +1587,6 @@ class World implements ChunkManager{ } } - if($player !== null){ $ev = new BlockPlaceEvent($player, $hand, $blockReplace, $blockClicked, $item); if($player->isAdventure(true) and !$ev->isCancelled()){ diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 8a86e727a2..bdeedab46d 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -320,7 +320,6 @@ class WorldManager{ return null; } - public function tick(int $currentTick) : void{ foreach($this->worlds as $k => $world){ if(!isset($this->worlds[$k])){ diff --git a/src/world/biome/Biome.php b/src/world/biome/Biome.php index eed499e5ac..89f4f14ba9 100644 --- a/src/world/biome/Biome.php +++ b/src/world/biome/Biome.php @@ -44,13 +44,10 @@ abstract class Biome{ public const ICE_PLAINS = 12; - public const SMALL_MOUNTAINS = 20; - public const BIRCH_FOREST = 27; - public const MAX_BIOMES = 256; /** @var Biome[]|\SplFixedArray */ @@ -96,7 +93,6 @@ abstract class Biome{ self::register(self::ICE_PLAINS, new IcePlainsBiome()); - self::register(self::SMALL_MOUNTAINS, new SmallMountainsBiome()); self::register(self::BIRCH_FOREST, new ForestBiome(TreeType::BIRCH())); diff --git a/src/world/biome/DesertBiome.php b/src/world/biome/DesertBiome.php index dac51c8718..79e3cda63a 100644 --- a/src/world/biome/DesertBiome.php +++ b/src/world/biome/DesertBiome.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\world\biome; - class DesertBiome extends SandyBiome{ public function __construct(){ diff --git a/src/world/biome/SmallMountainsBiome.php b/src/world/biome/SmallMountainsBiome.php index 8e649d889c..6ba7127fb4 100644 --- a/src/world/biome/SmallMountainsBiome.php +++ b/src/world/biome/SmallMountainsBiome.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\world\biome; - class SmallMountainsBiome extends MountainsBiome{ public function __construct(){ diff --git a/src/world/format/io/data/BaseNbtWorldData.php b/src/world/format/io/data/BaseNbtWorldData.php index 4a5fcf75fe..20074dc5ec 100644 --- a/src/world/format/io/data/BaseNbtWorldData.php +++ b/src/world/format/io/data/BaseNbtWorldData.php @@ -105,7 +105,6 @@ abstract class BaseNbtWorldData implements WorldData{ return $this->compoundTag; } - /* The below are common between PC and PE */ public function getName() : string{ diff --git a/src/world/format/io/data/JavaWorldData.php b/src/world/format/io/data/JavaWorldData.php index f3b509604a..bd0d6490c7 100644 --- a/src/world/format/io/data/JavaWorldData.php +++ b/src/world/format/io/data/JavaWorldData.php @@ -101,7 +101,6 @@ class JavaWorldData extends BaseNbtWorldData{ file_put_contents($this->dataPath, $buffer); } - public function getDifficulty() : int{ return $this->compoundTag->getByte("Difficulty", World::DIFFICULTY_NORMAL); } diff --git a/src/world/format/io/region/CorruptedRegionException.php b/src/world/format/io/region/CorruptedRegionException.php index 6c3943bcdf..93604f70dd 100644 --- a/src/world/format/io/region/CorruptedRegionException.php +++ b/src/world/format/io/region/CorruptedRegionException.php @@ -21,10 +21,8 @@ declare(strict_types=1); - namespace pocketmine\world\format\io\region; - class CorruptedRegionException extends RegionException{ } diff --git a/src/world/format/io/region/RegionException.php b/src/world/format/io/region/RegionException.php index fc9dcdb048..44cb1ff5fc 100644 --- a/src/world/format/io/region/RegionException.php +++ b/src/world/format/io/region/RegionException.php @@ -21,10 +21,8 @@ declare(strict_types=1); - namespace pocketmine\world\format\io\region; - class RegionException extends \RuntimeException{ } diff --git a/src/world/generator/noise/Noise.php b/src/world/generator/noise/Noise.php index efe418381e..9bee809b4c 100644 --- a/src/world/generator/noise/Noise.php +++ b/src/world/generator/noise/Noise.php @@ -26,13 +26,11 @@ declare(strict_types=1); */ namespace pocketmine\world\generator\noise; - use function array_fill; use function assert; abstract class Noise{ - /** * @param float $x * @param float $x1 diff --git a/src/world/generator/object/Tree.php b/src/world/generator/object/Tree.php index b8345ba9c1..c15ffb5610 100644 --- a/src/world/generator/object/Tree.php +++ b/src/world/generator/object/Tree.php @@ -82,7 +82,6 @@ abstract class Tree{ } } - public function canPlaceObject(ChunkManager $world, int $x, int $y, int $z, Random $random) : bool{ $radiusToCheck = 0; for($yy = 0; $yy < $this->treeHeight + 3; ++$yy){ From 8efc4d12ec305dcc4f43bb8613cb5c82b6fdcd3f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 22 Jan 2020 15:18:37 +0000 Subject: [PATCH 1349/3224] trim phpdoc lines --- src/entity/EntityFactory.php | 1 - src/world/World.php | 1 - 2 files changed, 2 deletions(-) diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index 2c0510a6bb..c7bab408c8 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -200,7 +200,6 @@ final class EntityFactory{ * * @throws \RuntimeException *@internal - * */ public static function createFromData(World $world, CompoundTag $nbt) : ?Entity{ $saveId = $nbt->getTag("id") ?? $nbt->getTag("identifier"); diff --git a/src/world/World.php b/src/world/World.php index 3365e664dc..aa374dd94b 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -597,7 +597,6 @@ class World implements ChunkManager{ * Unregisters a chunk listener previously registered. * *@see World::registerChunkListener() - * */ public function unregisterChunkListener(ChunkListener $listener, int $chunkX, int $chunkZ) : void{ $hash = World::chunkHash($chunkX, $chunkZ); From 5955ff53939cac6e466faa6fbfdf8f32be5fa5ee Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 22 Jan 2020 15:20:50 +0000 Subject: [PATCH 1350/3224] fix phpdoc spacing screwed up by phpstorm --- src/block/tile/TileFactory.php | 2 +- src/entity/EntityFactory.php | 2 +- src/world/World.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/block/tile/TileFactory.php b/src/block/tile/TileFactory.php index a72951af35..8f1d100d72 100644 --- a/src/block/tile/TileFactory.php +++ b/src/block/tile/TileFactory.php @@ -144,7 +144,7 @@ final class TileFactory{ } /** - *@internal + * @internal */ public static function createFromData(World $world, CompoundTag $nbt) : ?Tile{ $type = $nbt->getString(Tile::TAG_ID, "", true); diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index c7bab408c8..a74d615d99 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -199,7 +199,7 @@ final class EntityFactory{ * Creates an entity from data stored on a chunk. * * @throws \RuntimeException - *@internal + * @internal */ public static function createFromData(World $world, CompoundTag $nbt) : ?Entity{ $saveId = $nbt->getTag("id") ?? $nbt->getTag("identifier"); diff --git a/src/world/World.php b/src/world/World.php index aa374dd94b..05135cb6bd 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -596,7 +596,7 @@ class World implements ChunkManager{ /** * Unregisters a chunk listener previously registered. * - *@see World::registerChunkListener() + * @see World::registerChunkListener() */ public function unregisterChunkListener(ChunkListener $listener, int $chunkX, int $chunkZ) : void{ $hash = World::chunkHash($chunkX, $chunkZ); From e66197036dd9cf2e7712dad1af8fa578f2830862 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 25 Jan 2020 18:10:37 +0000 Subject: [PATCH 1351/3224] InGamePacketHandler: drop transactions with 0 actions without trying to execute them often we throw out actions that have no value, which can lead to an empty transaction and re-syncing the inventory. This happens every time we interact with the creative inventory in 1.13+, which causes items to appear to vanish when taking them from the creative menu. The correct fix for this is to resend only the slots affected by SlotChangeActions, but this fix will suffice for now without rewriting everything. --- src/network/mcpe/handler/InGamePacketHandler.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index ca443c2895..e3632fd66b 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -260,6 +260,11 @@ class InGamePacketHandler extends PacketHandler{ return false; } + if(count($actions) === 0){ + //TODO: 1.13+ often sends transactions with nothing but useless crap in them, no need for the debug noise + return true; + } + $transaction = new InventoryTransaction($this->player, $actions); try{ $transaction->execute(); From 35c23ea89ad6adf79988ab9478c11eb9fb3b1d69 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 27 Jan 2020 09:35:27 +0000 Subject: [PATCH 1352/3224] com_exception is no longer missing from phpstan stubs --- tests/phpstan/configs/phpstan-bugs.neon | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index efd9ba99e7..e2344dc5c2 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -59,16 +59,3 @@ parameters: message: "#^If condition is always false\\.$#" count: 1 path: ../../../src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php - - - - #missing from current stubs - message: "#^Caught class com_exception not found\\.$#" - count: 2 - path: ../../../src/network/upnp/UPnP.php - - - - #missing from current stubs - message: "#^Call to method getMessage\\(\\) on an unknown class com_exception\\.$#" - count: 1 - path: ../../../src/network/upnp/UPnP.php - From 42014311c58e2b4926c9267df94ebd5814510d0a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 27 Jan 2020 18:08:08 +0000 Subject: [PATCH 1353/3224] BrewingStand: added missing void return type --- src/block/tile/BrewingStand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/tile/BrewingStand.php b/src/block/tile/BrewingStand.php index 62814e5281..6d34ecfb8a 100644 --- a/src/block/tile/BrewingStand.php +++ b/src/block/tile/BrewingStand.php @@ -54,7 +54,7 @@ class BrewingStand extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); $this->inventory = new BrewingStandInventory($this->pos); - $this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange(function(Inventory $unused){ + $this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange(function(Inventory $unused) : void{ $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 1); })); } From 85fdb7ec052bc10505413879a890d0e45b035c9c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 27 Jan 2020 18:08:59 +0000 Subject: [PATCH 1354/3224] CallbackInventoryChangeListener: provide signature information for closures --- .../CallbackInventoryChangeListener.php | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/inventory/CallbackInventoryChangeListener.php b/src/inventory/CallbackInventoryChangeListener.php index 82c6b8ebb2..0978060c4e 100644 --- a/src/inventory/CallbackInventoryChangeListener.php +++ b/src/inventory/CallbackInventoryChangeListener.php @@ -27,11 +27,23 @@ use pocketmine\utils\Utils; class CallbackInventoryChangeListener implements InventoryChangeListener{ - /** @var \Closure|null */ + //TODO: turn the closure signatures into type aliases when PHPStan supports them + + /** + * @var \Closure|null + * @phpstan-var (\Closure(Inventory, int) : void)|null + */ private $onSlotChangeCallback; - /** @var \Closure|null */ + /** + * @var \Closure|null + * @phpstan-var (\Closure(Inventory) : void)|null + */ private $onContentChangeCallback; + /** + * @phpstan-param (\Closure(Inventory, int) : void)|null $onSlotChange + * @phpstan-param (\Closure(Inventory) : void)|null $onContentChange + */ public function __construct(?\Closure $onSlotChange, ?\Closure $onContentChange){ if($onSlotChange !== null){ Utils::validateCallableSignature(function(Inventory $inventory, int $slot){}, $onSlotChange); @@ -44,6 +56,9 @@ class CallbackInventoryChangeListener implements InventoryChangeListener{ $this->onContentChangeCallback = $onContentChange; } + /** + * @phpstan-param \Closure(Inventory) : void $onChange + */ public static function onAnyChange(\Closure $onChange) : self{ return new self( static function(Inventory $inventory, int $unused) use ($onChange) : void{ From ded0f5c80ed278317d92dcf6e17d391d162250d6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 28 Jan 2020 11:10:01 +0000 Subject: [PATCH 1355/3224] network: added some missing native closure return types --- src/network/mcpe/ChunkCache.php | 2 +- src/network/mcpe/NetworkSession.php | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/network/mcpe/ChunkCache.php b/src/network/mcpe/ChunkCache.php index 7ca9cde574..67d5b89115 100644 --- a/src/network/mcpe/ChunkCache.php +++ b/src/network/mcpe/ChunkCache.php @@ -92,7 +92,7 @@ class ChunkCache implements ChunkListener{ $chunkZ, $this->world->getChunk($chunkX, $chunkZ), $this->caches[$chunkHash], - function() use ($chunkX, $chunkZ){ + function() use ($chunkX, $chunkZ) : void{ $this->world->getLogger()->error("Failed preparing chunk $chunkX $chunkZ, retrying"); $this->restartPendingRequest($chunkX, $chunkZ); diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index bc65f64bbd..f5044b9a47 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -448,7 +448,7 @@ class NetworkSession{ * Disconnects the session, destroying the associated player (if it exists). */ public function disconnect(string $reason, bool $notify = true) : void{ - $this->tryDisconnect(function() use ($reason, $notify){ + $this->tryDisconnect(function() use ($reason, $notify) : void{ if($this->player !== null){ $this->player->disconnect($reason, null, $notify); } @@ -462,7 +462,7 @@ class NetworkSession{ * @throws \UnsupportedOperationException */ public function transfer(string $ip, int $port, string $reason = "transfer") : void{ - $this->tryDisconnect(function() use ($ip, $port, $reason){ + $this->tryDisconnect(function() use ($ip, $port, $reason) : void{ $this->sendDataPacket(TransferPacket::create($ip, $port), true); $this->disconnect($reason, false); if($this->player !== null){ @@ -476,7 +476,7 @@ class NetworkSession{ * Called by the Player when it is closed (for example due to getting kicked). */ public function onPlayerDestroyed(string $reason, bool $notify = true) : void{ - $this->tryDisconnect(function() use ($reason, $notify){ + $this->tryDisconnect(function() use ($reason, $notify) : void{ $this->doServerDisconnect($reason, $notify); }, $reason); } @@ -497,7 +497,7 @@ class NetworkSession{ * example in a timeout condition or voluntary client disconnect. */ public function onClientDisconnect(string $reason) : void{ - $this->tryDisconnect(function() use ($reason){ + $this->tryDisconnect(function() use ($reason) : void{ if($this->player !== null){ $this->player->disconnect($reason, null, false); } @@ -740,7 +740,7 @@ class NetworkSession{ ChunkCache::getInstance($world)->request($chunkX, $chunkZ)->onResolve( //this callback may be called synchronously or asynchronously, depending on whether the promise is resolved yet - function(CompressBatchPromise $promise) use ($world, $chunkX, $chunkZ, $onCompletion){ + function(CompressBatchPromise $promise) use ($world, $chunkX, $chunkZ, $onCompletion) : void{ if(!$this->isConnected()){ return; } From f68452a5d98d163652ec26e7a1f40235cec508b6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 28 Jan 2020 14:28:03 +0000 Subject: [PATCH 1356/3224] updated composer deps --- composer.lock | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/composer.lock b/composer.lock index fb0f968a0f..f0ae5b06b3 100644 --- a/composer.lock +++ b/composer.lock @@ -299,18 +299,21 @@ "source": { "type": "git", "url": "https://github.com/pmmp/BinaryUtils.git", - "reference": "7b50fa2b212c54e2a280217c84955b23e90cf5a1" + "reference": "a36705550b42e7e93e2a9748a8b9fa88985780bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/7b50fa2b212c54e2a280217c84955b23e90cf5a1", - "reference": "7b50fa2b212c54e2a280217c84955b23e90cf5a1", + "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/a36705550b42e7e93e2a9748a8b9fa88985780bf", + "reference": "a36705550b42e7e93e2a9748a8b9fa88985780bf", "shasum": "" }, "require": { "php": ">=7.2", "php-64bit": "*" }, + "require-dev": { + "phpstan/phpstan": "^0.12.8" + }, "type": "library", "autoload": { "psr-4": { @@ -325,7 +328,7 @@ "source": "https://github.com/pmmp/BinaryUtils/tree/master", "issues": "https://github.com/pmmp/BinaryUtils/issues" }, - "time": "2019-10-21T14:41:23+00:00" + "time": "2020-01-28T12:17:38+00:00" }, { "name": "pocketmine/classloader", @@ -398,18 +401,22 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "45f5156bf41083523568ec08f22bd52f31dcd109" + "reference": "9aa4018635e7d634c535d4c7d9e032c7d905c29d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/45f5156bf41083523568ec08f22bd52f31dcd109", - "reference": "45f5156bf41083523568ec08f22bd52f31dcd109", + "url": "https://api.github.com/repos/pmmp/Math/zipball/9aa4018635e7d634c535d4c7d9e032c7d905c29d", + "reference": "9aa4018635e7d634c535d4c7d9e032c7d905c29d", "shasum": "" }, "require": { "php": ">=7.2.0", "php-64bit": "*" }, + "require-dev": { + "irstea/phpunit-shim": "^7.5", + "phpstan/phpstan": "^0.12.8" + }, "type": "library", "autoload": { "psr-4": { @@ -429,7 +436,7 @@ "source": "https://github.com/pmmp/Math/tree/master", "issues": "https://github.com/pmmp/Math/issues" }, - "time": "2019-11-27T06:54:09+00:00" + "time": "2020-01-28T14:13:55+00:00" }, { "name": "pocketmine/nbt", @@ -437,12 +444,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "c1d440cccb0be90f8ef519f231de7e91bb8db28f" + "reference": "a30398cdb3d3c431f29862f5a84578d3ed2a6c6c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/c1d440cccb0be90f8ef519f231de7e91bb8db28f", - "reference": "c1d440cccb0be90f8ef519f231de7e91bb8db28f", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/a30398cdb3d3c431f29862f5a84578d3ed2a6c6c", + "reference": "a30398cdb3d3c431f29862f5a84578d3ed2a6c6c", "shasum": "" }, "require": { @@ -451,6 +458,9 @@ "php-64bit": "*", "pocketmine/binaryutils": "dev-master" }, + "require-dev": { + "phpstan/phpstan": "^0.12.8" + }, "type": "library", "autoload": { "psr-4": { @@ -470,7 +480,7 @@ "source": "https://github.com/pmmp/NBT/tree/master", "issues": "https://github.com/pmmp/NBT/issues" }, - "time": "2020-01-01T10:09:55+00:00" + "time": "2020-01-27T15:15:07+00:00" }, { "name": "pocketmine/raklib", From 68bea6d4aae52aa2f0c5fb479afd93441d7dfc72 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Jan 2020 19:36:52 +0000 Subject: [PATCH 1357/3224] ChunkRequestTask: fix @var for error hook fetch --- src/network/mcpe/ChunkRequestTask.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php index 55dd1e48d0..3062b13837 100644 --- a/src/network/mcpe/ChunkRequestTask.php +++ b/src/network/mcpe/ChunkRequestTask.php @@ -68,7 +68,7 @@ class ChunkRequestTask extends AsyncTask{ } public function onError() : void{ - /** @var \Closure $hook */ + /** @var \Closure|null $hook */ $hook = $this->fetchLocal(self::TLS_KEY_ERROR_HOOK); if($hook !== null){ $hook(); From 5c4487c98030d6dcedf0c53d805c49503a6b179c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Jan 2020 19:56:16 +0000 Subject: [PATCH 1358/3224] added some callable prototypes for phpstan --- src/entity/effect/EffectManager.php | 16 ++++++++++++++-- src/network/mcpe/ChunkRequestTask.php | 8 +++++++- src/network/mcpe/NetworkSession.php | 4 ++++ .../mcpe/compression/CompressBatchPromise.php | 9 ++++++++- src/plugin/PluginManager.php | 5 +++++ src/scheduler/CancellableClosureTask.php | 7 ++++++- src/timings/TimingsHandler.php | 4 ++++ src/utils/Utils.php | 3 +++ src/world/BlockTransaction.php | 7 ++++++- src/world/utils/SubChunkIteratorManager.php | 8 +++++++- 10 files changed, 64 insertions(+), 7 deletions(-) diff --git a/src/entity/effect/EffectManager.php b/src/entity/effect/EffectManager.php index 7cead7f74b..8545f22326 100644 --- a/src/entity/effect/EffectManager.php +++ b/src/entity/effect/EffectManager.php @@ -44,9 +44,15 @@ class EffectManager{ /** @var bool */ protected $onlyAmbientEffects = false; - /** @var \Closure[] */ + /** + * @var \Closure[] + * @phpstan-var (\Closure(EffectInstance, bool $replacesOldEffect) : void)[] + */ protected $effectAddHooks = []; - /** @var \Closure[] */ + /** + * @var \Closure[] + * @phpstan-var (\Closure(EffectInstance) : void)[] + */ protected $effectRemoveHooks = []; public function __construct(Living $entity){ @@ -214,11 +220,17 @@ class EffectManager{ return !empty($this->effects); } + /** + * @phpstan-param \Closure(EffectInstance, bool $replacesOldEffect) : void $closure + */ public function onEffectAdd(\Closure $closure) : void{ Utils::validateCallableSignature(function(EffectInstance $effect, bool $replacesOldEffect) : void{}, $closure); $this->effectAddHooks[spl_object_id($closure)] = $closure; } + /** + * @phpstan-param \Closure(EffectInstance) : void $closure + */ public function onEffectRemove(\Closure $closure) : void{ Utils::validateCallableSignature(function(EffectInstance $effect) : void{}, $closure); $this->effectRemoveHooks[spl_object_id($closure)] = $closure; diff --git a/src/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php index 3062b13837..299bfd7eba 100644 --- a/src/network/mcpe/ChunkRequestTask.php +++ b/src/network/mcpe/ChunkRequestTask.php @@ -48,6 +48,9 @@ class ChunkRequestTask extends AsyncTask{ /** @var string */ private $tiles = ""; + /** + * @phpstan-param (\Closure() : void)|null $onError + */ public function __construct(int $chunkX, int $chunkZ, Chunk $chunk, CompressBatchPromise $promise, ?\Closure $onError = null){ $this->compressionLevel = Zlib::$LEVEL; @@ -68,7 +71,10 @@ class ChunkRequestTask extends AsyncTask{ } public function onError() : void{ - /** @var \Closure|null $hook */ + /** + * @var \Closure|null $hook + * @phpstan-var (\Closure() : void)|null $hook + */ $hook = $this->fetchLocal(self::TLS_KEY_ERROR_HOOK); if($hook !== null){ $hook(); diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index f5044b9a47..a208550612 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -430,6 +430,9 @@ class NetworkSession{ $this->sender->send($payload, $immediate); } + /** + * @phpstan-param \Closure() : void $func + */ private function tryDisconnect(\Closure $func, string $reason) : void{ if($this->connected and !$this->disconnectGuard){ $this->disconnectGuard = true; @@ -731,6 +734,7 @@ class NetworkSession{ /** * Instructs the networksession to start using the chunk at the given coordinates. This may occur asynchronously. * @param \Closure $onCompletion To be called when chunk sending has completed. + * @phpstan-param \Closure(int $chunkX, int $chunkZ) : void $onCompletion */ public function startUsingChunk(int $chunkX, int $chunkZ, \Closure $onCompletion) : void{ Utils::validateCallableSignature(function(int $chunkX, int $chunkZ){}, $onCompletion); diff --git a/src/network/mcpe/compression/CompressBatchPromise.php b/src/network/mcpe/compression/CompressBatchPromise.php index f1d6c777ef..94909d5fd9 100644 --- a/src/network/mcpe/compression/CompressBatchPromise.php +++ b/src/network/mcpe/compression/CompressBatchPromise.php @@ -27,7 +27,10 @@ use pocketmine\utils\Utils; use function array_push; class CompressBatchPromise{ - /** @var \Closure[] */ + /** + * @var \Closure[] + * @phpstan-var (\Closure(self) : void)[] + */ private $callbacks = []; /** @var string|null */ @@ -36,6 +39,9 @@ class CompressBatchPromise{ /** @var bool */ private $cancelled = false; + /** + * @phpstan-param \Closure(self) : void ...$callbacks + */ public function onResolve(\Closure ...$callbacks) : void{ $this->checkCancelled(); foreach($callbacks as $callback){ @@ -65,6 +71,7 @@ class CompressBatchPromise{ /** * @return \Closure[] + * @phpstan-return (\Closure(self) : void)[] */ public function getResolveCallbacks() : array{ return $this->callbacks; diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index dce9ca86eb..8788520cef 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -499,6 +499,7 @@ class PluginManager{ } } + /** @phpstan-var \ReflectionClass $eventClass */ $this->registerEvent($eventClass->getName(), $handlerClosure, $priority, $plugin, $handleCancelled); } } @@ -507,6 +508,10 @@ class PluginManager{ /** * @param string $event Class name that extends Event * + * @phpstan-template TEvent of Event + * @phpstan-param class-string $event + * @phpstan-param \Closure(TEvent) : void $handler + * * @throws \ReflectionException */ public function registerEvent(string $event, \Closure $handler, int $priority, Plugin $plugin, bool $handleCancelled = false) : void{ diff --git a/src/scheduler/CancellableClosureTask.php b/src/scheduler/CancellableClosureTask.php index a900170e98..934edb9dd4 100644 --- a/src/scheduler/CancellableClosureTask.php +++ b/src/scheduler/CancellableClosureTask.php @@ -45,7 +45,10 @@ class CancellableClosureTask extends Task{ public const CONTINUE = true; public const CANCEL = false; - /** @var \Closure */ + /** + * @var \Closure + * @phpstan-var \Closure(int $currentTick) : bool + */ private $closure; /** @@ -53,6 +56,8 @@ class CancellableClosureTask extends Task{ * * The closure should follow the signature callback(int $currentTick) : bool. The return value will be used to * decide whether to continue repeating. + * + * @phpstan-param \Closure(int $currentTick) : bool $closure */ public function __construct(\Closure $closure){ Utils::validateCallableSignature(function(int $currentTick) : bool{ return false; }, $closure); diff --git a/src/timings/TimingsHandler.php b/src/timings/TimingsHandler.php index 2d3de39729..2b889ed1ec 100644 --- a/src/timings/TimingsHandler.php +++ b/src/timings/TimingsHandler.php @@ -197,6 +197,10 @@ class TimingsHandler{ /** * @return mixed the result of the given closure + * + * @phpstan-template TClosureReturn + * @phpstan-param \Closure() : TClosureReturn $closure + * @phpstan-return TClosureReturn */ public function time(\Closure $closure){ $this->startTiming(); diff --git a/src/utils/Utils.php b/src/utils/Utils.php index 1c634a8757..0186cd201a 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -131,6 +131,9 @@ class Utils{ return $reflect->getName(); } + /** + * @phpstan-return \Closure(object) : object + */ public static function cloneCallback() : \Closure{ return static function(object $o){ return clone $o; diff --git a/src/world/BlockTransaction.php b/src/world/BlockTransaction.php index 55108bc494..996649a5de 100644 --- a/src/world/BlockTransaction.php +++ b/src/world/BlockTransaction.php @@ -34,7 +34,10 @@ class BlockTransaction{ /** @var Block[][][] */ private $blocks = []; - /** @var \Closure[] */ + /** + * @var \Closure[] + * @phpstan-var (\Closure(ChunkManager $world, int $x, int $y, int $z) : bool)[] + */ private $validators = []; public function __construct(ChunkManager $world){ @@ -115,6 +118,8 @@ class BlockTransaction{ * Add a validation predicate which will be used to validate every block. * The callable signature should be the same as the below dummy function. * @see BlockTransaction::dummyValidator() + * + * @phpstan-param \Closure(ChunkManager $world, int $x, int $y, int $z) : bool $validator */ public function addValidator(\Closure $validator) : void{ Utils::validateCallableSignature([$this, 'dummyValidator'], $validator); diff --git a/src/world/utils/SubChunkIteratorManager.php b/src/world/utils/SubChunkIteratorManager.php index 5512f42512..6187f367e9 100644 --- a/src/world/utils/SubChunkIteratorManager.php +++ b/src/world/utils/SubChunkIteratorManager.php @@ -45,7 +45,10 @@ class SubChunkIteratorManager{ /** @var int */ protected $currentZ; - /** @var \Closure|null */ + /** + * @var \Closure|null + * @phpstan-var (\Closure() : void)|null + */ private $onSubChunkChangeFunc = null; public function __construct(ChunkManager $world){ @@ -83,6 +86,9 @@ class SubChunkIteratorManager{ return true; } + /** + * @phpstan-param \Closure() : void $callback + */ public function onSubChunkChange(\Closure $callback) : void{ Utils::validateCallableSignature(function(){}, $callback); $this->onSubChunkChangeFunc = $callback; From 9311437d4241c47283ed6837eb1b0fe918ac128d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 30 Jan 2020 12:07:14 +0000 Subject: [PATCH 1359/3224] Utils: add some phpstan docs to fix analyse failure fuck, I wish we had real generics :( --- src/utils/Utils.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/utils/Utils.php b/src/utils/Utils.php index 0186cd201a..52e08f04d8 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -150,7 +150,9 @@ class Utils{ * @phpstan-return T[] */ public static function cloneObjectArray(array $array) : array{ - return array_map(self::cloneCallback(), $array); + /** @phpstan-var \Closure(T) : T $callback */ + $callback = self::cloneCallback(); + return array_map($callback, $array); } /** From 89c6da13acc0122a1ff465344903d06c1d31292c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 31 Jan 2020 22:05:33 +0000 Subject: [PATCH 1360/3224] phpstan: use more class-string --- src/block/BlockIdentifier.php | 13 ++++++++++++- src/block/tile/TileFactory.php | 18 +++++++++++++++++- src/entity/EntityFactory.php | 19 ++++++++++++++++++- src/item/ProjectileItem.php | 1 + src/item/SpawnEgg.php | 6 +++++- src/world/format/io/WorldProviderManager.php | 15 +++++++++++---- tests/phpstan/configs/phpstan-bugs.neon | 6 ++++++ 7 files changed, 70 insertions(+), 8 deletions(-) diff --git a/src/block/BlockIdentifier.php b/src/block/BlockIdentifier.php index 87faf3a316..1df7d942c0 100644 --- a/src/block/BlockIdentifier.php +++ b/src/block/BlockIdentifier.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\tile\Tile; + class BlockIdentifier{ /** @var int */ @@ -31,9 +33,15 @@ class BlockIdentifier{ private $variant; /** @var int|null */ private $itemId; - /** @var string|null */ + /** + * @var string|null + * @phpstan-var class-string|null + */ private $tileClass; + /** + * @phpstan-param class-string|null $tileClass + */ public function __construct(int $blockId, int $variant = 0, ?int $itemId = null, ?string $tileClass = null){ $this->blockId = $blockId; $this->variant = $variant; @@ -60,6 +68,9 @@ class BlockIdentifier{ return $this->itemId ?? ($this->blockId > 255 ? 255 - $this->blockId : $this->blockId); } + /** + * @phpstan-return class-string|null + */ public function getTileClass() : ?string{ return $this->tileClass; } diff --git a/src/block/tile/TileFactory.php b/src/block/tile/TileFactory.php index 20752f39c3..130d99e56e 100644 --- a/src/block/tile/TileFactory.php +++ b/src/block/tile/TileFactory.php @@ -44,7 +44,10 @@ final class TileFactory{ * @phpstan-var array, list> */ private static $saveNames = []; - /** @var string[] base class => overridden class */ + /** + * @var string[] base class => overridden class + * @phpstan-var array, class-string> + */ private static $classMapping = []; private function __construct(){ @@ -119,6 +122,10 @@ final class TileFactory{ * @param string $baseClass Already-registered tile class to override * @param string $newClass Class which extends the base class * + * TODO: use an explicit template for param1 + * @phpstan-param class-string $baseClass + * @phpstan-param class-string $newClass + * * @throws \InvalidArgumentException if the base class is not a registered tile */ public static function override(string $baseClass, string $newClass) : void{ @@ -131,7 +138,12 @@ final class TileFactory{ } /** + * @phpstan-template TTile of Tile + * @phpstan-param class-string $baseClass + * * @return Tile (will be an instanceof $baseClass) + * @phpstan-return TTile + * * @throws \InvalidArgumentException if the specified class is not a registered tile */ public static function create(string $baseClass, World $world, Vector3 $pos) : Tile{ @@ -140,6 +152,7 @@ final class TileFactory{ assert(is_a($class, $baseClass, true)); /** * @var Tile $tile + * @phpstan-var TTile $tile * @see Tile::__construct() */ $tile = new $class($world, $pos); @@ -170,6 +183,9 @@ final class TileFactory{ return $tile; } + /** + * @phpstan-param class-string $class + */ public static function getSaveId(string $class) : string{ if(isset(self::$saveNames[$class])){ return reset(self::$saveNames[$class]); diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index 69fdbb3284..d333ce16f3 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -63,7 +63,10 @@ final class EntityFactory{ /** @var int */ private static $entityCount = 1; - /** @var string[] base class => currently used class for construction */ + /** + * @var string[] base class => currently used class for construction + * @phpstan-var array, class-string> + */ private static $classMapping = []; /** * @var string[] @@ -148,6 +151,10 @@ final class EntityFactory{ * @param string $baseClass Already-registered entity class to override * @param string $newClass Class which extends the base class * + * TODO: use an explicit template for param1 + * @phpstan-param class-string $baseClass + * @phpstan-param class-string $newClass + * * @throws \InvalidArgumentException */ public static function override(string $baseClass, string $newClass) : void{ @@ -163,6 +170,7 @@ final class EntityFactory{ * Returns an array of all registered entity classpaths. * * @return string[] + * @return class-string[] */ public static function getKnownTypes() : array{ return array_keys(self::$classMapping); @@ -181,9 +189,14 @@ final class EntityFactory{ * * TODO: make this NBT-independent * + * @phpstan-template TEntity of Entity + * * @param mixed ...$args + * @phpstan-param class-string $baseClass * * @return Entity instanceof $baseClass + * @phpstan-return TEntity + * * @throws \InvalidArgumentException if the class doesn't exist or is not registered */ public static function create(string $baseClass, World $world, CompoundTag $nbt, ...$args) : Entity{ @@ -192,6 +205,7 @@ final class EntityFactory{ assert(is_a($class, $baseClass, true)); /** * @var Entity $entity + * @phpstan-var TEntity $entity * @see Entity::__construct() */ $entity = new $class($world, $nbt, ...$args); @@ -230,6 +244,9 @@ final class EntityFactory{ return $entity; } + /** + * @phpstan-param class-string $class + */ public static function getSaveId(string $class) : string{ if(isset(self::$saveNames[$class])){ return reset(self::$saveNames[$class]); diff --git a/src/item/ProjectileItem.php b/src/item/ProjectileItem.php index cbae038b38..62d3e6e4b2 100644 --- a/src/item/ProjectileItem.php +++ b/src/item/ProjectileItem.php @@ -38,6 +38,7 @@ abstract class ProjectileItem extends Item{ * Returns the entity type that this projectile creates. This should return a ::class extending Throwable. * * @return string class extends Throwable + * @phpstan-return class-string */ abstract public function getProjectileEntityClass() : string; diff --git a/src/item/SpawnEgg.php b/src/item/SpawnEgg.php index b9aa36165c..0982839144 100644 --- a/src/item/SpawnEgg.php +++ b/src/item/SpawnEgg.php @@ -33,11 +33,15 @@ use function lcg_value; class SpawnEgg extends Item{ - /** @var string */ + /** + * @var string + * @phpstan-var class-string + */ private $entityClass; /** * @param string $entityClass instanceof Entity + * @phpstan-param class-string $entityClass * * @throws \InvalidArgumentException */ diff --git a/src/world/format/io/WorldProviderManager.php b/src/world/format/io/WorldProviderManager.php index a4f9360317..37e489709a 100644 --- a/src/world/format/io/WorldProviderManager.php +++ b/src/world/format/io/WorldProviderManager.php @@ -38,7 +38,10 @@ abstract class WorldProviderManager{ */ protected static $providers = []; - /** @var string|WorldProvider */ + /** + * @var string + * @phpstan-var class-string + */ private static $default = LevelDB::class; public static function init() : void{ @@ -50,6 +53,8 @@ abstract class WorldProviderManager{ /** * Returns the default format used to generate new worlds. + * + * @phpstan-return class-string */ public static function getDefault() : string{ return self::$default; @@ -59,6 +64,7 @@ abstract class WorldProviderManager{ * Sets the default format. * * @param string $class Class implementing WritableWorldProvider + * @phpstan-param class-string $class * * @throws \InvalidArgumentException */ @@ -86,12 +92,12 @@ abstract class WorldProviderManager{ /** * Returns a WorldProvider class for this path, or null * - * @return string[]|WorldProvider[] + * @return string[] + * @phpstan-return array> */ public static function getMatchingProviders(string $path) : array{ $result = []; foreach(self::$providers as $alias => $provider){ - /** @var WorldProvider|string $provider */ if($provider::isValid($path)){ $result[$alias] = $provider; } @@ -100,7 +106,8 @@ abstract class WorldProviderManager{ } /** - * @return string[]|WorldProvider[] + * @return string[] + * @phpstan-return array> */ public static function getAvailableProviders() : array{ return self::$providers; diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index e2344dc5c2..0cbf07abe7 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -22,6 +22,12 @@ parameters: count: 1 path: ../../../src/MemoryManager.php + - + #is_a() type narrowing isn't respected yet + message: "#^Parameter \\#1 \\$class of static method pocketmine\\\\world\\\\format\\\\io\\\\WorldProviderManager\\:\\:setDefault\\(\\) expects class\\-string\\, class\\-string\\ given\\.$#" + count: 1 + path: ../../../src/Server.php + - message: "#^Comparison operation \"\\>\\=\" between 0 and 2 is always false\\.$#" count: 1 From 200209b76c5f4ec5c4b67ad91b58daafceb5a723 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 1 Feb 2020 17:20:36 +0000 Subject: [PATCH 1361/3224] RegistryTrait: provide an explicit phpstan type for __callStatic arguments --- src/utils/RegistryTrait.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/utils/RegistryTrait.php b/src/utils/RegistryTrait.php index b91fbd429b..ec65253029 100644 --- a/src/utils/RegistryTrait.php +++ b/src/utils/RegistryTrait.php @@ -81,8 +81,9 @@ trait RegistryTrait{ } /** - * @param string $name - * @param array $arguments + * @param string $name + * @param mixed[] $arguments + * @phpstan-param list $arguments * * @return object */ From ff63f6d05566e089e88c3dd74a70fa041dba499f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 1 Feb 2020 20:19:57 +0000 Subject: [PATCH 1362/3224] fill in more iterable types (master) --- src/Server.php | 6 ++++++ src/entity/Entity.php | 3 +++ src/lang/Language.php | 4 ++++ src/network/mcpe/NetworkSession.php | 3 +++ src/network/mcpe/protocol/DataPacket.php | 3 +++ src/network/mcpe/protocol/LoginPacket.php | 5 ++++- src/network/mcpe/protocol/PlayerListPacket.php | 6 ++++++ src/network/mcpe/protocol/SetActorDataPacket.php | 4 ++++ src/network/mcpe/protocol/TextPacket.php | 3 +++ .../types/entity/IntegerishMetadataProperty.php | 4 ++++ .../types/inventory/ReleaseItemTransactionData.php | 3 +++ .../inventory/UseItemOnEntityTransactionData.php | 3 +++ .../types/inventory/UseItemTransactionData.php | 3 +++ src/permission/PermissionParser.php | 7 +++++++ src/player/GameMode.php | 3 +++ src/player/Player.php | 6 ++++++ src/player/PlayerInfo.php | 13 ++++++++++++- src/plugin/PluginGraylist.php | 10 ++++++++++ src/world/World.php | 6 ++++++ src/world/WorldManager.php | 2 ++ src/world/format/SubChunk.php | 3 +++ src/world/format/io/WorldData.php | 4 ++++ src/world/format/io/data/BedrockWorldData.php | 5 +++++ src/world/format/io/data/JavaWorldData.php | 5 +++++ src/world/format/io/region/RegionWorldProvider.php | 5 +++++ src/world/generator/Generator.php | 5 ++++- 26 files changed, 121 insertions(+), 3 deletions(-) diff --git a/src/Server.php b/src/Server.php index f7a6c40cae..19c82d2518 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1153,6 +1153,9 @@ class Server{ return count($recipients); } + /** + * @return Player[] + */ private function selectPermittedPlayers(string $permission) : array{ /** @var Player[] $players */ $players = []; @@ -1536,6 +1539,9 @@ class Server{ exit(1); } + /** + * @return mixed[] + */ public function __debugInfo() : array{ return []; } diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 910dd5875b..3237662f92 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1695,6 +1695,9 @@ abstract class Entity{ $this->server->broadcastPackets($players ?? $this->getViewers(), [ActorEventPacket::create($this->id, $eventId, $eventData ?? 0)]); } + /** + * @param Player[]|null $players + */ public function broadcastAnimation(?array $players, int $animationId) : void{ $this->server->broadcastPackets($players ?? $this->getViewers(), [AnimatePacket::create($this->id, $animationId)]); } diff --git a/src/lang/Language.php b/src/lang/Language.php index 4e2ebabe7b..47e71f0590 100644 --- a/src/lang/Language.php +++ b/src/lang/Language.php @@ -109,6 +109,10 @@ class Language{ return $this->langName; } + /** + * @return string[] + * @phpstan-return array + */ protected static function loadLang(string $path, string $languageCode) : array{ $file = $path . $languageCode . ".ini"; if(file_exists($file)){ diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index a208550612..33df65074a 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -711,6 +711,9 @@ class NetworkSession{ $this->sendDataPacket(TextPacket::raw($message)); } + /** + * @param string[] $parameters + */ public function onTranslatedChatMessage(string $key, array $parameters) : void{ $this->sendDataPacket(TextPacket::translation($key, $parameters)); } diff --git a/src/network/mcpe/protocol/DataPacket.php b/src/network/mcpe/protocol/DataPacket.php index 81543f4242..53fd9bd716 100644 --- a/src/network/mcpe/protocol/DataPacket.php +++ b/src/network/mcpe/protocol/DataPacket.php @@ -104,6 +104,9 @@ abstract class DataPacket extends NetworkBinaryStream implements Packet{ */ abstract protected function encodePayload() : void; + /** + * @return mixed[] + */ public function __debugInfo() : array{ $data = []; foreach((array) $this as $k => $v){ diff --git a/src/network/mcpe/protocol/LoginPacket.php b/src/network/mcpe/protocol/LoginPacket.php index 8eca676e8c..92e7a2cd55 100644 --- a/src/network/mcpe/protocol/LoginPacket.php +++ b/src/network/mcpe/protocol/LoginPacket.php @@ -83,7 +83,10 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ /** @var string[] array of encoded JWT */ public $chainDataJwt = []; - /** @var array|null extraData index of whichever JWT has it */ + /** + * @var mixed[]|null extraData index of whichever JWT has it + * @phpstan-var array + */ public $extraData = null; /** @var string */ public $clientDataJwt; diff --git a/src/network/mcpe/protocol/PlayerListPacket.php b/src/network/mcpe/protocol/PlayerListPacket.php index 8431c354eb..c514f4fdbc 100644 --- a/src/network/mcpe/protocol/PlayerListPacket.php +++ b/src/network/mcpe/protocol/PlayerListPacket.php @@ -40,6 +40,9 @@ class PlayerListPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $type; + /** + * @param PlayerListEntry[] $entries + */ public static function add(array $entries) : self{ $result = new self; $result->type = self::TYPE_ADD; @@ -47,6 +50,9 @@ class PlayerListPacket extends DataPacket implements ClientboundPacket{ return $result; } + /** + * @param PlayerListEntry[] $entries + */ public static function remove(array $entries) : self{ $result = new self; $result->type = self::TYPE_REMOVE; diff --git a/src/network/mcpe/protocol/SetActorDataPacket.php b/src/network/mcpe/protocol/SetActorDataPacket.php index c030b21542..ebde0894a0 100644 --- a/src/network/mcpe/protocol/SetActorDataPacket.php +++ b/src/network/mcpe/protocol/SetActorDataPacket.php @@ -39,6 +39,10 @@ class SetActorDataPacket extends DataPacket implements ClientboundPacket, Server */ public $metadata; + /** + * @param MetadataProperty[] $metadata + * @phpstan-param array $metadata + */ public static function create(int $entityRuntimeId, array $metadata) : self{ $result = new self; diff --git a/src/network/mcpe/protocol/TextPacket.php b/src/network/mcpe/protocol/TextPacket.php index d227eb0a92..5594b9e657 100644 --- a/src/network/mcpe/protocol/TextPacket.php +++ b/src/network/mcpe/protocol/TextPacket.php @@ -64,6 +64,9 @@ class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPac return $result; } + /** + * @param string[] $parameters + */ private static function baseTranslation(int $type, string $key, array $parameters) : self{ $result = new self; $result->type = $type; diff --git a/src/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php b/src/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php index 298e229b43..62be6a0d0b 100644 --- a/src/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php @@ -46,6 +46,10 @@ trait IntegerishMetadataProperty{ return $other instanceof self and $other->value === $this->value; } + /** + * @param bool[] $flags + * @phpstan-param array $flags + */ public static function buildFromFlags(array $flags) : self{ $value = 0; foreach($flags as $flag => $v){ diff --git a/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php b/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php index d6274454bf..b0d8a4f6df 100644 --- a/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php @@ -75,6 +75,9 @@ class ReleaseItemTransactionData extends TransactionData{ $stream->putVector3($this->headPos); } + /** + * @param NetworkInventoryAction[] $actions + */ public static function new(array $actions, int $actionType, int $hotbarSlot, Item $itemInHand, Vector3 $headPos) : self{ $result = new self; $result->actions = $actions; diff --git a/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php b/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php index f487fee24c..c53408cd0f 100644 --- a/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php @@ -91,6 +91,9 @@ class UseItemOnEntityTransactionData extends TransactionData{ $stream->putVector3($this->clickPos); } + /** + * @param NetworkInventoryAction[] $actions + */ public static function new(array $actions, int $entityRuntimeId, int $actionType, int $hotbarSlot, Item $itemInHand, Vector3 $playerPos, Vector3 $clickPos) : self{ $result = new self; $result->actions = $actions; diff --git a/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php b/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php index 261b1c874f..8131b6aa07 100644 --- a/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php @@ -109,6 +109,9 @@ class UseItemTransactionData extends TransactionData{ $stream->putUnsignedVarInt($this->blockRuntimeId); } + /** + * @param NetworkInventoryAction[] $actions + */ public static function new(array $actions, int $actionType, Vector3 $blockPos, int $face, int $hotbarSlot, Item $itemInHand, Vector3 $playerPos, Vector3 $clickPos, int $blockRuntimeId) : self{ $result = new self; $result->actions = $actions; diff --git a/src/permission/PermissionParser.php b/src/permission/PermissionParser.php index c0abfb1c90..c1d693c824 100644 --- a/src/permission/PermissionParser.php +++ b/src/permission/PermissionParser.php @@ -122,6 +122,9 @@ class PermissionParser{ /** * @param Permission[] $permissions + * + * @return mixed[] + * @phpstan-return array> */ public static function emitPermissions(array $permissions) : array{ $result = []; @@ -132,6 +135,10 @@ class PermissionParser{ return $result; } + /** + * @return mixed[] + * @phpstan-return array + */ private static function emitPermission(Permission $permission) : array{ $result = [ "description" => $permission->getDescription(), diff --git a/src/player/GameMode.php b/src/player/GameMode.php index 7b99f5a811..b4bab2d414 100644 --- a/src/player/GameMode.php +++ b/src/player/GameMode.php @@ -90,6 +90,9 @@ final class GameMode{ /** @var string[] */ private $aliases; + /** + * @param string[] $aliases + */ private function __construct(string $enumName, int $magicNumber, string $englishName, string $translationKey, array $aliases = []){ $this->Enum___construct($enumName); $this->magicNumber = $magicNumber; diff --git a/src/player/Player.php b/src/player/Player.php index 57bac6e86b..7ba7d85fbb 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -837,6 +837,9 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } + /** + * @return \Generator + */ protected function selectChunks() : \Generator{ $radius = $this->server->getAllowedViewDistance($this->viewDistance); $radiusSquared = $radius ** 2; @@ -2007,6 +2010,9 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, parent::destroyCycles(); } + /** + * @return mixed[] + */ public function __debugInfo() : array{ return []; } diff --git a/src/player/PlayerInfo.php b/src/player/PlayerInfo.php index 285294ddf6..a3120edce6 100644 --- a/src/player/PlayerInfo.php +++ b/src/player/PlayerInfo.php @@ -42,9 +42,16 @@ class PlayerInfo{ private $locale; /** @var string */ private $xuid; - /** @var array */ + /** + * @var mixed[] + * @phpstan-var array + */ private $extraData; + /** + * @param mixed[] $extraData + * @phpstan-param array $extraData + */ public function __construct(string $username, UUID $uuid, Skin $skin, string $locale, string $xuid, array $extraData = []){ $this->username = TextFormat::clean($username); $this->uuid = $uuid; @@ -74,6 +81,10 @@ class PlayerInfo{ return $this->xuid; } + /** + * @return mixed[] + * @phpstan-return array + */ public function getExtraData() : array{ return $this->extraData; } diff --git a/src/plugin/PluginGraylist.php b/src/plugin/PluginGraylist.php index c7ab8c88ac..8436ffc7f4 100644 --- a/src/plugin/PluginGraylist.php +++ b/src/plugin/PluginGraylist.php @@ -36,6 +36,9 @@ class PluginGraylist{ /** @var bool */ private $isWhitelist = false; + /** + * @param string[] $plugins + */ public function __construct(array $plugins = [], bool $whitelist = false){ $this->plugins = array_flip($plugins); $this->isWhitelist = $whitelist; @@ -59,6 +62,9 @@ class PluginGraylist{ return $this->isWhitelist() === isset($this->plugins[$name]); } + /** + * @param mixed[] $array + */ public static function fromArray(array $array) : PluginGraylist{ $v = new Validator(); $v->required("mode")->inArray(['whitelist', 'blacklist'], true); @@ -75,6 +81,10 @@ class PluginGraylist{ return new PluginGraylist($array["plugins"], $array["mode"] === 'whitelist'); } + /** + * @return mixed[] + * @phpstan-return array + */ public function toArray() : array{ return [ "mode" => $this->isWhitelist ? 'whitelist' : 'blacklist', diff --git a/src/world/World.php b/src/world/World.php index 5e5d6061d8..8a7796178e 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -423,6 +423,9 @@ class World implements ChunkManager{ $this->closed = true; } + /** + * @param Player[]|null $players + */ public function addSound(Vector3 $pos, Sound $sound, ?array $players = null) : void{ $pk = $sound->encode($pos); if(!is_array($pk)){ @@ -439,6 +442,9 @@ class World implements ChunkManager{ } } + /** + * @param Player[]|null $players + */ public function addParticle(Vector3 $pos, Particle $particle, ?array $players = null) : void{ $pk = $particle->encode($pos); if(!is_array($pk)){ diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index a7ec2de1f9..8dee91e69e 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -235,7 +235,9 @@ class WorldManager{ * Generates a new world if it does not exist * * @param string $generator Class name that extends pocketmine\world\generator\Generator + * @param mixed[] $options * @phpstan-param class-string $generator + * @phpstan-param array $options * * @throws \InvalidArgumentException */ diff --git a/src/world/format/SubChunk.php b/src/world/format/SubChunk.php index 5a3f980cc7..74056f62ac 100644 --- a/src/world/format/SubChunk.php +++ b/src/world/format/SubChunk.php @@ -108,6 +108,9 @@ class SubChunk implements SubChunkInterface{ $this->blockLight = $data; } + /** + * @return mixed[] + */ public function __debugInfo() : array{ return []; } diff --git a/src/world/format/io/WorldData.php b/src/world/format/io/WorldData.php index d3b7757ba2..46f4086e0c 100644 --- a/src/world/format/io/WorldData.php +++ b/src/world/format/io/WorldData.php @@ -39,6 +39,10 @@ interface WorldData{ */ public function getGenerator() : string; + /** + * @return mixed[] + * @phpstan-return array + */ public function getGeneratorOptions() : array; public function getSeed() : int; diff --git a/src/world/format/io/data/BedrockWorldData.php b/src/world/format/io/data/BedrockWorldData.php index 7827c51640..252513f760 100644 --- a/src/world/format/io/data/BedrockWorldData.php +++ b/src/world/format/io/data/BedrockWorldData.php @@ -53,6 +53,11 @@ class BedrockWorldData extends BaseNbtWorldData{ public const GENERATOR_INFINITE = 1; public const GENERATOR_FLAT = 2; + /** + * @param mixed[] $options + * @phpstan-param class-string $generator + * @phpstan-param array $options + */ public static function generate(string $path, string $name, int $seed, string $generator, array $options = []) : void{ Utils::testValidInstance($generator, Generator::class); switch($generator){ diff --git a/src/world/format/io/data/JavaWorldData.php b/src/world/format/io/data/JavaWorldData.php index bd0d6490c7..a51c5ce067 100644 --- a/src/world/format/io/data/JavaWorldData.php +++ b/src/world/format/io/data/JavaWorldData.php @@ -41,6 +41,11 @@ use function microtime; class JavaWorldData extends BaseNbtWorldData{ + /** + * @param mixed[] $options + * @phpstan-param class-string $generator + * @phpstan-param array $options + */ public static function generate(string $path, string $name, int $seed, string $generator, array $options = [], int $version = 19133) : void{ Utils::testValidInstance($generator, Generator::class); //TODO, add extra details diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index 33faba2121..fc4abe5900 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -72,6 +72,11 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ return false; } + /** + * @param mixed[] $options + * @phpstan-param class-string $generator + * @phpstan-param array $options + */ public static function generate(string $path, string $name, int $seed, string $generator, array $options = []) : void{ Utils::testValidInstance($generator, Generator::class); if(!file_exists($path)){ diff --git a/src/world/generator/Generator.php b/src/world/generator/Generator.php index f57e431ebc..b3221a6922 100644 --- a/src/world/generator/Generator.php +++ b/src/world/generator/Generator.php @@ -52,7 +52,10 @@ abstract class Generator{ protected $world; /** @var int */ protected $seed; - /** @var array */ + /** + * @var mixed[] + * @phpstan-var array + */ protected $options; /** @var Random */ From cc33c8155fb158cfdc10fc8d0657a3e5d4e01a87 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 1 Feb 2020 20:20:39 +0000 Subject: [PATCH 1363/3224] Language: specify key type for lang and fallbackLang fields --- src/lang/Language.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/lang/Language.php b/src/lang/Language.php index 47e71f0590..646e464afc 100644 --- a/src/lang/Language.php +++ b/src/lang/Language.php @@ -82,9 +82,15 @@ class Language{ /** @var string */ protected $langName; - /** @var string[] */ + /** + * @var string[] + * @phpstan-var array + */ protected $lang = []; - /** @var string[] */ + /** + * @var string[] + * @phpstan-var array + */ protected $fallbackLang = []; /** From 9c33ea8dd15d551924cce62b81620b3d1fc8d5ac Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 1 Feb 2020 20:33:30 +0000 Subject: [PATCH 1364/3224] EnumTrait: use a better method to initialize enums this method is simpler, and is also safe at the native type level. Coincidentally, it also eliminates 30 PHPStan false-positives. --- src/block/utils/DyeColor.php | 6 +++--- src/block/utils/SkullType.php | 6 +++--- src/block/utils/SlabType.php | 6 +++--- src/block/utils/StairShape.php | 6 +++--- src/block/utils/TreeType.php | 6 +++--- src/item/ItemUseResult.php | 6 +++--- src/item/ToolTier.php | 6 +++--- src/player/GameMode.php | 6 +++--- src/plugin/PluginLoadOrder.php | 6 +++--- src/utils/EnumTrait.php | 23 +++-------------------- src/world/sound/NoteInstrument.php | 6 +++--- 11 files changed, 33 insertions(+), 50 deletions(-) diff --git a/src/block/utils/DyeColor.php b/src/block/utils/DyeColor.php index 764e138333..80cb087670 100644 --- a/src/block/utils/DyeColor.php +++ b/src/block/utils/DyeColor.php @@ -57,8 +57,8 @@ final class DyeColor{ /** @var DyeColor[] */ private static $numericIdMap = []; - protected static function setup() : iterable{ - return [ + protected static function setup() : void{ + self::registerAll( new DyeColor("white", "White", 0, new Color(0xf0, 0xf0, 0xf0)), new DyeColor("orange", "Orange", 1, new Color(0xf9, 0x80, 0x1d)), new DyeColor("magenta", "Magenta", 2, new Color(0xc7, 0x4e, 0xbd)), @@ -75,7 +75,7 @@ final class DyeColor{ new DyeColor("green", "Green", 13, new Color(0x5e, 0x7c, 0x16)), new DyeColor("red", "Red", 14, new Color(0xb0, 0x2e, 0x26)), new DyeColor("black", "Black", 15, new Color(0x1d, 0x1d, 0x21)), - ]; + ); } protected static function register(DyeColor $color) : void{ diff --git a/src/block/utils/SkullType.php b/src/block/utils/SkullType.php index 408d68741c..43934ff2d1 100644 --- a/src/block/utils/SkullType.php +++ b/src/block/utils/SkullType.php @@ -46,15 +46,15 @@ final class SkullType{ /** @var SkullType[] */ private static $numericIdMap = []; - protected static function setup() : iterable{ - return [ + protected static function setup() : void{ + self::registerAll( new SkullType("skeleton", "Skeleton Skull", 0), new SkullType("wither_skeleton", "Wither Skeleton Skull", 1), new SkullType("zombie", "Zombie Head", 2), new SkullType("player", "Player Head", 3), new SkullType("creeper", "Creeper Head", 4), new SkullType("dragon", "Dragon Head", 5) - ]; + ); } protected static function register(SkullType $type) : void{ diff --git a/src/block/utils/SlabType.php b/src/block/utils/SlabType.php index 15035637e0..a56cf7ed4c 100644 --- a/src/block/utils/SlabType.php +++ b/src/block/utils/SlabType.php @@ -37,11 +37,11 @@ use pocketmine\utils\EnumTrait; final class SlabType{ use EnumTrait; - protected static function setup() : iterable{ - return [ + protected static function setup() : void{ + self::registerAll( new self("bottom"), new self("top"), new self("double") - ]; + ); } } diff --git a/src/block/utils/StairShape.php b/src/block/utils/StairShape.php index 89f4c544a8..b46b19f115 100644 --- a/src/block/utils/StairShape.php +++ b/src/block/utils/StairShape.php @@ -39,13 +39,13 @@ use pocketmine\utils\EnumTrait; final class StairShape{ use EnumTrait; - protected static function setup() : iterable{ - return [ + protected static function setup() : void{ + self::registerAll( new self("straight"), new self("inner_left"), new self("inner_right"), new self("outer_left"), new self("outer_right") - ]; + ); } } diff --git a/src/block/utils/TreeType.php b/src/block/utils/TreeType.php index 4d880169af..b3afdd95ec 100644 --- a/src/block/utils/TreeType.php +++ b/src/block/utils/TreeType.php @@ -46,15 +46,15 @@ final class TreeType{ /** @var TreeType[] */ private static $numericIdMap = []; - protected static function setup() : iterable{ - return [ + protected static function setup() : void{ + self::registerAll( new TreeType("oak", "Oak", 0), new TreeType("spruce", "Spruce", 1), new TreeType("birch", "Birch", 2), new TreeType("jungle", "Jungle", 3), new TreeType("acacia", "Acacia", 4), new TreeType("dark_oak", "Dark Oak", 5) - ]; + ); } protected static function register(TreeType $type) : void{ diff --git a/src/item/ItemUseResult.php b/src/item/ItemUseResult.php index 7f8bdba017..4469458033 100644 --- a/src/item/ItemUseResult.php +++ b/src/item/ItemUseResult.php @@ -37,11 +37,11 @@ use pocketmine\utils\EnumTrait; final class ItemUseResult{ use EnumTrait; - protected static function setup() : iterable{ - return [ + protected static function setup() : void{ + self::registerAll( new self("none"), new self("fail"), new self("success") - ]; + ); } } diff --git a/src/item/ToolTier.php b/src/item/ToolTier.php index 1f2190bb8c..30e184e9fa 100644 --- a/src/item/ToolTier.php +++ b/src/item/ToolTier.php @@ -41,14 +41,14 @@ final class ToolTier{ __construct as Enum___construct; } - protected static function setup() : iterable{ - return [ + protected static function setup() : void{ + self::registerAll( new self("wood", 1, 60, 5, 2), new self("gold", 2, 33, 5, 12), new self("stone", 3, 132, 6, 4), new self("iron", 4, 251, 7, 6), new self("diamond", 5, 1562, 8, 8) - ]; + ); } /** @var int */ diff --git a/src/player/GameMode.php b/src/player/GameMode.php index b4bab2d414..7d95513bae 100644 --- a/src/player/GameMode.php +++ b/src/player/GameMode.php @@ -47,13 +47,13 @@ final class GameMode{ /** @var self[] */ protected static $magicNumberMap = []; - protected static function setup() : iterable{ - return [ + protected static function setup() : void{ + self::registerAll( new self("survival", 0, "Survival", "gameMode.survival", ["s", "0"]), new self("creative", 1, "Creative", "gameMode.creative", ["c", "1"]), new self("adventure", 2, "Adventure", "gameMode.adventure", ["a", "2"]), new self("spectator", 3, "Spectator", "gameMode.spectator", ["v", "view", "3"]) - ]; + ); } protected static function register(self $member) : void{ diff --git a/src/plugin/PluginLoadOrder.php b/src/plugin/PluginLoadOrder.php index 8e27befcf5..fa99eeba98 100644 --- a/src/plugin/PluginLoadOrder.php +++ b/src/plugin/PluginLoadOrder.php @@ -36,10 +36,10 @@ use pocketmine\utils\EnumTrait; final class PluginLoadOrder{ use EnumTrait; - protected static function setup() : iterable{ - return [ + protected static function setup() : void{ + self::registerAll( new self("startup"), new self("postworld") - ]; + ); } } diff --git a/src/utils/EnumTrait.php b/src/utils/EnumTrait.php index 9092bd888a..6f6aa517c4 100644 --- a/src/utils/EnumTrait.php +++ b/src/utils/EnumTrait.php @@ -38,26 +38,9 @@ trait EnumTrait{ self::_registryRegister($member->name(), $member); } - /** - * Returns an array of enum members to be registered. - * - * (This ought to be private, but traits suck too much for that.) - * - * @return self[]|iterable - */ - abstract protected static function setup() : iterable; - - /** - * @internal Lazy-inits the enum if necessary. - * - * @throws \InvalidArgumentException - */ - protected static function checkInit() : void{ - if(self::$members === null){ - self::$members = []; - foreach(self::setup() as $item){ - self::register($item); - } + protected static function registerAll(self ...$members) : void{ + foreach($members as $member){ + self::register($member); } } diff --git a/src/world/sound/NoteInstrument.php b/src/world/sound/NoteInstrument.php index a6fd778f2a..cd37df98a4 100644 --- a/src/world/sound/NoteInstrument.php +++ b/src/world/sound/NoteInstrument.php @@ -41,14 +41,14 @@ final class NoteInstrument{ __construct as Enum___construct; } - protected static function setup() : iterable{ - return [ + protected static function setup() : void{ + self::registerAll( new self("piano", 0), new self("bass_drum", 1), new self("snare", 2), new self("clicks_and_sticks", 3), new self("double_bass", 4) - ]; + ); } /** @var int */ From 269066b2d02f74a820da93356adfb013f0b9e378 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 1 Feb 2020 20:42:04 +0000 Subject: [PATCH 1365/3224] added unit test for Enum lazy initialization --- tests/phpunit/utils/EnumTraitTest.php | 35 ++++++++++++++++++++ tests/phpunit/utils/TestEnum.php | 46 +++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 tests/phpunit/utils/EnumTraitTest.php create mode 100644 tests/phpunit/utils/TestEnum.php diff --git a/tests/phpunit/utils/EnumTraitTest.php b/tests/phpunit/utils/EnumTraitTest.php new file mode 100644 index 0000000000..aaa16cf771 --- /dev/null +++ b/tests/phpunit/utils/EnumTraitTest.php @@ -0,0 +1,35 @@ + Date: Sat, 1 Feb 2020 20:50:16 +0000 Subject: [PATCH 1366/3224] DyeColor: fix PHP 7.2 compatibility --- src/block/utils/DyeColor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/utils/DyeColor.php b/src/block/utils/DyeColor.php index 80cb087670..d6f98b974c 100644 --- a/src/block/utils/DyeColor.php +++ b/src/block/utils/DyeColor.php @@ -74,7 +74,7 @@ final class DyeColor{ new DyeColor("brown", "Brown", 12, new Color(0x83, 0x54, 0x32)), new DyeColor("green", "Green", 13, new Color(0x5e, 0x7c, 0x16)), new DyeColor("red", "Red", 14, new Color(0xb0, 0x2e, 0x26)), - new DyeColor("black", "Black", 15, new Color(0x1d, 0x1d, 0x21)), + new DyeColor("black", "Black", 15, new Color(0x1d, 0x1d, 0x21)) ); } From d48597ec5dd7f9d72bdde80fd0e14c3b9920cacb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 1 Feb 2020 22:14:24 +0000 Subject: [PATCH 1367/3224] move BedrockData submodule to resources/ --- .gitmodules | 2 +- {src/pocketmine/resources => resources}/vanilla | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename {src/pocketmine/resources => resources}/vanilla (100%) diff --git a/.gitmodules b/.gitmodules index e166c853ab..02fbaf5e65 100644 --- a/.gitmodules +++ b/.gitmodules @@ -11,5 +11,5 @@ path = build/php url = https://github.com/pmmp/php-build-scripts.git [submodule "src/pocketmine/resources/vanilla"] - path = src/pocketmine/resources/vanilla + path = resources/vanilla url = https://github.com/pmmp/BedrockData.git diff --git a/src/pocketmine/resources/vanilla b/resources/vanilla similarity index 100% rename from src/pocketmine/resources/vanilla rename to resources/vanilla From 80dc0eb8b88d11237bbeb91101905b4e967a34d2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 1 Feb 2020 22:14:53 +0000 Subject: [PATCH 1368/3224] rename BedrockData submodule --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 02fbaf5e65..9708c68dde 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,6 +10,6 @@ [submodule "build/php"] path = build/php url = https://github.com/pmmp/php-build-scripts.git -[submodule "src/pocketmine/resources/vanilla"] +[submodule "resources/vanilla"] path = resources/vanilla url = https://github.com/pmmp/BedrockData.git From 1b50a2d8d47eeb9cefc41cc49037ced0f5d1a847 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 1 Feb 2020 22:59:52 +0000 Subject: [PATCH 1369/3224] updated composer dependencies --- composer.lock | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/composer.lock b/composer.lock index 352806740e..7e46eb56c1 100644 --- a/composer.lock +++ b/composer.lock @@ -518,22 +518,25 @@ }, { "name": "pocketmine/snooze", - "version": "0.1.1", + "version": "0.1.2", "source": { "type": "git", "url": "https://github.com/pmmp/Snooze.git", - "reference": "b7bd231bdb75e69300cac89ccd515fc731c38c40" + "reference": "88420da3d9335dbcb3ee2decfd5e5453d057dcdf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Snooze/zipball/b7bd231bdb75e69300cac89ccd515fc731c38c40", - "reference": "b7bd231bdb75e69300cac89ccd515fc731c38c40", + "url": "https://api.github.com/repos/pmmp/Snooze/zipball/88420da3d9335dbcb3ee2decfd5e5453d057dcdf", + "reference": "88420da3d9335dbcb3ee2decfd5e5453d057dcdf", "shasum": "" }, "require": { "ext-pthreads": ">=3.1.7dev", "php-64bit": ">=7.2.0" }, + "require-dev": { + "phpstan/phpstan": "^0.12.8" + }, "type": "library", "autoload": { "psr-4": { @@ -545,7 +548,7 @@ "LGPL-3.0" ], "description": "Thread notification management library for code using the pthreads extension", - "time": "2019-01-04T15:54:45+00:00" + "time": "2020-01-28T19:08:10+00:00" }, { "name": "pocketmine/spl", From f713cf25b12e5420de33aa1f8de644703dadce30 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Feb 2020 13:51:22 +0000 Subject: [PATCH 1370/3224] travis: update leveldb version, only build sharedlibs targets on travis --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7f98d774c8..f2509a01e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,10 +7,10 @@ php: before_script: - phpenv config-rm xdebug.ini - - LEVELDB_VERSION=f1463cb0b2486b0caf7d42ca3c7684545e875f04 - - curl -fsSL "https://github.com/pmmp/leveldb-mcpe/archive/f1463cb0b2486b0caf7d42ca3c7684545e875f04.tar.gz" | tar -zx + - LEVELDB_VERSION=10f59b56bec1db3ffe42ff265afe22182073e0e2 + - curl -fsSL "https://github.com/pmmp/leveldb-mcpe/archive/$LEVELDB_VERSION.tar.gz" | tar -zx - mv leveldb-mcpe-$LEVELDB_VERSION leveldb-mcpe - - cd leveldb-mcpe && make -j4 && mv out-shared/libleveldb.* . && cd .. + - cd leveldb-mcpe && make -j4 sharedlibs && mv out-shared/libleveldb.* . && cd .. - git clone https://github.com/reeze/php-leveldb.git leveldb - cd leveldb - git checkout 9bcae79f71b81a5c3ea6f67e45ae9ae9fb2775a5 From 4140af459e249bed5bfb7a30d8108967b2ab92f2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Feb 2020 14:05:11 +0000 Subject: [PATCH 1371/3224] travis: cache leveldb artifacts to reduce build time --- .travis.yml | 8 ++++---- tests/build-leveldb.sh | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) create mode 100755 tests/build-leveldb.sh diff --git a/.travis.yml b/.travis.yml index f2509a01e8..1ee1fb6a27 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,10 +7,7 @@ php: before_script: - phpenv config-rm xdebug.ini - - LEVELDB_VERSION=10f59b56bec1db3ffe42ff265afe22182073e0e2 - - curl -fsSL "https://github.com/pmmp/leveldb-mcpe/archive/$LEVELDB_VERSION.tar.gz" | tar -zx - - mv leveldb-mcpe-$LEVELDB_VERSION leveldb-mcpe - - cd leveldb-mcpe && make -j4 sharedlibs && mv out-shared/libleveldb.* . && cd .. + - ./tests/build-leveldb.sh 10f59b56bec1db3ffe42ff265afe22182073e0e2 - git clone https://github.com/reeze/php-leveldb.git leveldb - cd leveldb - git checkout 9bcae79f71b81a5c3ea6f67e45ae9ae9fb2775a5 @@ -47,5 +44,8 @@ script: - composer install --no-dev - ./tests/travis.sh -t4 +cache: + - leveldb-mcpe + notifications: email: false diff --git a/tests/build-leveldb.sh b/tests/build-leveldb.sh new file mode 100755 index 0000000000..a4fcd3439a --- /dev/null +++ b/tests/build-leveldb.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +set -e + +LEVELDB_VERSION="$1" +if [ ! -f "./leveldb-mcpe/built_version" ] || [ $(cat "./leveldb-mcpe/built_version") != "$LEVELDB_VERSION" ]; then + echo "Building new LevelDB" + rm -rf "./leveldb-mcpe" || true + mkdir "./leveldb-mcpe" + + curl -fsSL "https://github.com/pmmp/leveldb-mcpe/archive/$LEVELDB_VERSION.tar.gz" | tar -zx + mv "./leveldb-mcpe-$LEVELDB_VERSION" leveldb-mcpe-build + cd leveldb-mcpe-build + make -j4 sharedlibs + + #put the artifacts in a separate dir, to avoid bloating travis cache" + mv out-shared/libleveldb.* ../leveldb-mcpe + mv include ../leveldb-mcpe + cd ../leveldb-mcpe + echo "$LEVELDB_VERSION" > "./built_version" + cd .. +else + echo "Using cached build for LevelDB version $LEVELDB_VERSION" +fi From 93671d8bfe41a28430af7fa9dc0a63074e1dd729 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Feb 2020 17:22:49 +0000 Subject: [PATCH 1372/3224] fixed broken tests from level->world rename how did this not get noticed before ??? --- .../phpunit/{level => world}/format/io/AbstractWorldProvider.php | 0 .../phpunit/{level => world}/format/io/InterfaceWorldProvider.php | 0 .../{level => world}/format/io/LevelProviderManagerTest.php | 0 .../{level => world}/format/io/region/RegionLoaderTest.php | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename tests/phpunit/{level => world}/format/io/AbstractWorldProvider.php (100%) rename tests/phpunit/{level => world}/format/io/InterfaceWorldProvider.php (100%) rename tests/phpunit/{level => world}/format/io/LevelProviderManagerTest.php (100%) rename tests/phpunit/{level => world}/format/io/region/RegionLoaderTest.php (100%) diff --git a/tests/phpunit/level/format/io/AbstractWorldProvider.php b/tests/phpunit/world/format/io/AbstractWorldProvider.php similarity index 100% rename from tests/phpunit/level/format/io/AbstractWorldProvider.php rename to tests/phpunit/world/format/io/AbstractWorldProvider.php diff --git a/tests/phpunit/level/format/io/InterfaceWorldProvider.php b/tests/phpunit/world/format/io/InterfaceWorldProvider.php similarity index 100% rename from tests/phpunit/level/format/io/InterfaceWorldProvider.php rename to tests/phpunit/world/format/io/InterfaceWorldProvider.php diff --git a/tests/phpunit/level/format/io/LevelProviderManagerTest.php b/tests/phpunit/world/format/io/LevelProviderManagerTest.php similarity index 100% rename from tests/phpunit/level/format/io/LevelProviderManagerTest.php rename to tests/phpunit/world/format/io/LevelProviderManagerTest.php diff --git a/tests/phpunit/level/format/io/region/RegionLoaderTest.php b/tests/phpunit/world/format/io/region/RegionLoaderTest.php similarity index 100% rename from tests/phpunit/level/format/io/region/RegionLoaderTest.php rename to tests/phpunit/world/format/io/region/RegionLoaderTest.php From 091873ca51de2b76ab968aa89bdb9e2073608782 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Feb 2020 18:14:43 +0000 Subject: [PATCH 1373/3224] HandlerListManagerTest: fix phpunit 8.x compatibility --- tests/phpunit/event/HandlerListManagerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/event/HandlerListManagerTest.php b/tests/phpunit/event/HandlerListManagerTest.php index a15456d9e4..bf35bf2dc0 100644 --- a/tests/phpunit/event/HandlerListManagerTest.php +++ b/tests/phpunit/event/HandlerListManagerTest.php @@ -33,7 +33,7 @@ class HandlerListManagerTest extends TestCase{ private $resolveParentFunc; - public function setUp(){ + public function setUp() : void{ /** @see HandlerListManager::isValidClass() */ $this->isValidFunc = (new \ReflectionMethod(HandlerListManager::class, 'isValidClass'))->getClosure(); /** @see HandlerListManager::resolveNearestHandleableParent() */ From 95896eb911cdffe9c27f2196568975a5559e7380 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Feb 2020 18:34:57 +0000 Subject: [PATCH 1374/3224] tests/phpunit: fill in some phpstan types --- tests/phpunit/event/HandlerListManagerTest.php | 11 +++++++++++ tests/phpunit/plugin/ApiVersionTest.php | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/tests/phpunit/event/HandlerListManagerTest.php b/tests/phpunit/event/HandlerListManagerTest.php index bf35bf2dc0..01de9ff84c 100644 --- a/tests/phpunit/event/HandlerListManagerTest.php +++ b/tests/phpunit/event/HandlerListManagerTest.php @@ -40,6 +40,10 @@ class HandlerListManagerTest extends TestCase{ $this->resolveParentFunc = (new \ReflectionMethod(HandlerListManager::class, 'resolveNearestHandleableParent'))->getClosure(); } + /** + * @return \Generator|mixed[][] + * @phpstan-return \Generator, bool, string}, void, void> + */ public function isValidClassProvider() : \Generator{ yield [new \ReflectionClass(Event::class), false, "event base should not be handleable"]; yield [new \ReflectionClass(TestConcreteEvent::class), true, ""]; @@ -53,11 +57,16 @@ class HandlerListManagerTest extends TestCase{ * @param \ReflectionClass $class * @param bool $isValid * @param string $reason + * @phpstan-param \ReflectionClass $class */ public function testIsValidClass(\ReflectionClass $class, bool $isValid, string $reason) : void{ self::assertSame($isValid, ($this->isValidFunc)($class), $reason); } + /** + * @return \Generator|\ReflectionClass[][] + * @phpstan-return \Generator, \ReflectionClass|null}, void, void> + */ public function resolveParentClassProvider() : \Generator{ yield [new \ReflectionClass(TestConcreteExtendsAllowHandleEvent::class), new \ReflectionClass(TestAbstractAllowHandleEvent::class)]; yield [new \ReflectionClass(TestConcreteEvent::class), null]; @@ -70,6 +79,8 @@ class HandlerListManagerTest extends TestCase{ * * @param \ReflectionClass $class * @param \ReflectionClass|null $expect + * @phpstan-param \ReflectionClass $class + * @phpstan-param \ReflectionClass|null $expect */ public function testResolveParentClass(\ReflectionClass $class, ?\ReflectionClass $expect) : void{ if($expect === null){ diff --git a/tests/phpunit/plugin/ApiVersionTest.php b/tests/phpunit/plugin/ApiVersionTest.php index 236b5b2c95..c6d8d37431 100644 --- a/tests/phpunit/plugin/ApiVersionTest.php +++ b/tests/phpunit/plugin/ApiVersionTest.php @@ -27,6 +27,10 @@ use PHPUnit\Framework\TestCase; class ApiVersionTest extends TestCase{ + /** + * @return \Generator|mixed[][] + * @phpstan-return \Generator + */ public function compatibleApiProvider() : \Generator{ yield ["3.0.0", "3.0.0", true]; yield ["3.1.0", "3.0.0", true]; @@ -53,6 +57,10 @@ class ApiVersionTest extends TestCase{ self::assertSame($expected, ApiVersion::isCompatible($myVersion, [$wantVersion]), "my version: $myVersion, their version: $wantVersion, expect " . ($expected ? "yes" : "no")); } + /** + * @return mixed[][][] + * @phpstan-return \Generator, list}, void, void> + */ public function ambiguousVersionsProvider() : \Generator{ yield [["3.0.0"], []]; yield [["3.0.0", "3.0.1"], ["3.0.0", "3.0.1"]]; From 31fcd8e5fabd7e3c020f034b1147cde36b929e51 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Feb 2020 18:35:26 +0000 Subject: [PATCH 1375/3224] ItemTest: use the proper method to explicitly fail a test --- tests/phpunit/item/ItemTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/item/ItemTest.php b/tests/phpunit/item/ItemTest.php index 42c358ddf0..205ebae30b 100644 --- a/tests/phpunit/item/ItemTest.php +++ b/tests/phpunit/item/ItemTest.php @@ -110,7 +110,7 @@ class ItemTest extends TestCase{ continue 2; } } - self::assertTrue(false, "Unknown extra enchantment found: " . $enchantment->getType()->getName() . " x" . $enchantment->getLevel()); + self::fail("Unknown extra enchantment found: " . $enchantment->getType()->getName() . " x" . $enchantment->getLevel()); } self::assertEmpty($enchantments, "Expected all enchantments to be present"); } From 31405f758714222c677514c3bb428db4f0292628 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Feb 2020 18:35:55 +0000 Subject: [PATCH 1376/3224] EnumTraitTest: use @doesNotPerformAssertions --- tests/phpunit/utils/EnumTraitTest.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/phpunit/utils/EnumTraitTest.php b/tests/phpunit/utils/EnumTraitTest.php index aaa16cf771..d58c61d08a 100644 --- a/tests/phpunit/utils/EnumTraitTest.php +++ b/tests/phpunit/utils/EnumTraitTest.php @@ -27,9 +27,12 @@ use PHPUnit\Framework\TestCase; class EnumTraitTest extends TestCase{ + /** + * @doesNotPerformAssertions + */ public function testEnumLazyInit() : void{ foreach([TestEnum::ONE(), TestEnum::TWO(), TestEnum::THREE()] as $member){ - self::assertInstanceOf(TestEnum::class, $member); + //NOOP } } } From 3a9e6bb612a04b545fee4e0b09ea7d5a064ea6bd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Feb 2020 19:28:43 +0000 Subject: [PATCH 1377/3224] CallbackInventoryChangeListener: fix use of tab instead of space --- src/inventory/CallbackInventoryChangeListener.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/inventory/CallbackInventoryChangeListener.php b/src/inventory/CallbackInventoryChangeListener.php index 0978060c4e..e16e01501c 100644 --- a/src/inventory/CallbackInventoryChangeListener.php +++ b/src/inventory/CallbackInventoryChangeListener.php @@ -46,7 +46,7 @@ class CallbackInventoryChangeListener implements InventoryChangeListener{ */ public function __construct(?\Closure $onSlotChange, ?\Closure $onContentChange){ if($onSlotChange !== null){ - Utils::validateCallableSignature(function(Inventory $inventory, int $slot){}, $onSlotChange); + Utils::validateCallableSignature(function(Inventory $inventory, int $slot){}, $onSlotChange); } if($onContentChange !== null){ Utils::validateCallableSignature(function(Inventory $inventory){}, $onContentChange); From 1ffabbb567e4157d2b07f6068e3f6c7238fd7235 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Feb 2020 20:25:08 +0000 Subject: [PATCH 1378/3224] fixed ignoreError for registerEvent() --- tests/phpstan/configs/runtime-type-checks.neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpstan/configs/runtime-type-checks.neon b/tests/phpstan/configs/runtime-type-checks.neon index 12f3073834..12ecd489c7 100644 --- a/tests/phpstan/configs/runtime-type-checks.neon +++ b/tests/phpstan/configs/runtime-type-checks.neon @@ -18,7 +18,7 @@ parameters: path: ../../../src/plugin/PluginBase.php - - message: "#^Call to function is_subclass_of\\(\\) with class\\-string\\ and 'pocketmine\\\\\\\\event…' will always evaluate to true\\.$#" + message: "#^Call to function is_subclass_of\\(\\) with class\\-string\\ and 'pocketmine\\\\\\\\event…' will always evaluate to true\\.$#" count: 1 path: ../../../src/plugin/PluginManager.php From aac7da6c96f55a85add8a72a6b12a8b42f5c6239 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Feb 2020 21:46:16 +0000 Subject: [PATCH 1379/3224] eliminate remaining empty() usages --- src/block/BaseRail.php | 2 +- src/block/Fence.php | 3 ++- src/block/Thin.php | 3 ++- src/block/Vine.php | 3 ++- src/entity/Entity.php | 2 +- src/entity/ExperienceManager.php | 3 ++- src/entity/Living.php | 2 +- src/entity/effect/EffectManager.php | 5 +++-- src/event/player/PlayerPreLoginEvent.php | 3 ++- src/item/Item.php | 3 ++- src/item/ItemEnchantmentHandlingTrait.php | 3 ++- src/network/mcpe/NetworkSession.php | 2 +- .../protocol/types/inventory/MismatchTransactionData.php | 2 +- src/permission/PermissionParser.php | 3 ++- src/player/Player.php | 2 +- src/plugin/PluginManager.php | 2 +- src/utils/RegistryTrait.php | 2 +- src/world/World.php | 8 ++++---- src/world/WorldManager.php | 4 ++-- src/world/format/Chunk.php | 2 +- src/world/format/SubChunk.php | 9 +++++---- src/world/format/io/leveldb/LevelDB.php | 2 +- 22 files changed, 40 insertions(+), 30 deletions(-) diff --git a/src/block/BaseRail.php b/src/block/BaseRail.php index ffc1cb8df4..017a3953ba 100644 --- a/src/block/BaseRail.php +++ b/src/block/BaseRail.php @@ -79,7 +79,7 @@ abstract class BaseRail extends Flowable{ } protected function writeStateToMeta() : int{ - if(empty($this->connections)){ + if(count($this->connections) === 0){ return BlockLegacyMetadata::RAIL_STRAIGHT_NORTH_SOUTH; } return $this->getMetaForState($this->connections); diff --git a/src/block/Fence.php b/src/block/Fence.php index 2a9d02d54f..2c99279b48 100644 --- a/src/block/Fence.php +++ b/src/block/Fence.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; +use function count; class Fence extends Transparent{ /** @var bool[] facing => dummy */ @@ -80,7 +81,7 @@ class Fence extends Transparent{ ->trim(Facing::SOUTH, $connectSouth ? 0 : $inset); } - if(empty($bbs)){ + if(count($bbs) === 0){ //centre post AABB (only needed if not connected on any axis - other BBs overlapping will do this if any connections are made) return [ AxisAlignedBB::one() diff --git a/src/block/Thin.php b/src/block/Thin.php index e98cc84653..1df7726988 100644 --- a/src/block/Thin.php +++ b/src/block/Thin.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; +use function count; class Thin extends Transparent{ /** @var bool[] facing => dummy */ @@ -71,7 +72,7 @@ class Thin extends Transparent{ $bbs[] = $bb; } - if(empty($bbs)){ + if(count($bbs) === 0){ //centre post AABB (only needed if not connected on any axis - other BBs overlapping will do this if any connections are made) return [ AxisAlignedBB::one()->contract($inset, 0, $inset) diff --git a/src/block/Vine.php b/src/block/Vine.php index 017e474ae7..b590c740d6 100644 --- a/src/block/Vine.php +++ b/src/block/Vine.php @@ -30,6 +30,7 @@ use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use function array_intersect_key; +use function count; class Vine extends Flowable{ @@ -113,7 +114,7 @@ class Vine extends Flowable{ } if($changed){ - if(empty($this->faces)){ + if(count($this->faces) === 0){ $this->pos->getWorld()->useBreakOn($this->pos); }else{ $this->pos->getWorld()->setBlock($this->pos, $this); diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 3237662f92..188ed72890 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -644,7 +644,7 @@ abstract class Entity{ $this->justCreated = false; $changedProperties = $this->getSyncedNetworkData(true); - if(!empty($changedProperties)){ + if(count($changedProperties) > 0){ $this->sendData($this->hasSpawned, $changedProperties); $this->networkProperties->clearDirtyProperties(); } diff --git a/src/entity/ExperienceManager.php b/src/entity/ExperienceManager.php index 12c4f894dc..89e7d26fca 100644 --- a/src/entity/ExperienceManager.php +++ b/src/entity/ExperienceManager.php @@ -31,6 +31,7 @@ use pocketmine\world\sound\XpCollectSound; use pocketmine\world\sound\XpLevelUpSound; use function array_rand; use function ceil; +use function count; use function max; use function min; @@ -251,7 +252,7 @@ class ExperienceManager{ } } - if(!empty($equipment)){ + if(count($equipment) > 0){ $repairItem = $equipment[$k = array_rand($equipment)]; if($repairItem->getDamage() > 0){ $repairAmount = min($repairItem->getDamage(), $xpValue * 2); diff --git a/src/entity/Living.php b/src/entity/Living.php index 3e8d0aaf1b..7acba21d9a 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -186,7 +186,7 @@ abstract class Living extends Entity{ $nbt->setShort("Air", $this->getAirSupplyTicks()); - if(!empty($this->effectManager->all())){ + if(count($this->effectManager->all()) > 0){ $effects = []; foreach($this->effectManager->all() as $effect){ $effects[] = CompoundTag::create() diff --git a/src/entity/effect/EffectManager.php b/src/entity/effect/EffectManager.php index 8545f22326..9f05a4eb12 100644 --- a/src/entity/effect/EffectManager.php +++ b/src/entity/effect/EffectManager.php @@ -29,6 +29,7 @@ use pocketmine\event\entity\EntityEffectRemoveEvent; use pocketmine\utils\Color; use pocketmine\utils\Utils; use function abs; +use function count; use function spl_object_id; class EffectManager{ @@ -188,7 +189,7 @@ class EffectManager{ } } - if(!empty($colors)){ + if(count($colors) > 0){ $this->bubbleColor = Color::mix(...$colors); $this->onlyAmbientEffects = $ambient; }else{ @@ -217,7 +218,7 @@ class EffectManager{ } } - return !empty($this->effects); + return count($this->effects) > 0; } /** diff --git a/src/event/player/PlayerPreLoginEvent.php b/src/event/player/PlayerPreLoginEvent.php index 03a6d2b852..040c827709 100644 --- a/src/event/player/PlayerPreLoginEvent.php +++ b/src/event/player/PlayerPreLoginEvent.php @@ -26,6 +26,7 @@ namespace pocketmine\event\player; use pocketmine\event\Event; use pocketmine\player\PlayerInfo; use function array_keys; +use function count; /** * Called when a player connects to the server, prior to authentication taking place. @@ -139,7 +140,7 @@ class PlayerPreLoginEvent extends Event{ * Returns whether the player is allowed to continue logging in. */ public function isAllowed() : bool{ - return empty($this->kickReasons); + return count($this->kickReasons) === 0; } /** diff --git a/src/item/Item.php b/src/item/Item.php index e4d678b38f..c8035873c6 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -48,6 +48,7 @@ use pocketmine\utils\Binary; use pocketmine\utils\Utils; use function base64_decode; use function base64_encode; +use function count; use function get_class; use function gettype; use function hex2bin; @@ -326,7 +327,7 @@ class Item implements \JsonSerializable{ $display->setString(self::TAG_DISPLAY_NAME, $this->getCustomName()) : $display->removeTag(self::TAG_DISPLAY); - if(!empty($this->lore)){ + if(count($this->lore) > 0){ $loreTag = new ListTag(); foreach($this->lore as $line){ $loreTag->push(new StringTag($line)); diff --git a/src/item/ItemEnchantmentHandlingTrait.php b/src/item/ItemEnchantmentHandlingTrait.php index 3760e16c67..9ef8c6ceea 100644 --- a/src/item/ItemEnchantmentHandlingTrait.php +++ b/src/item/ItemEnchantmentHandlingTrait.php @@ -25,6 +25,7 @@ namespace pocketmine\item; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\EnchantmentInstance; +use function count; /** * This trait encapsulates all enchantment handling needed for itemstacks. @@ -35,7 +36,7 @@ trait ItemEnchantmentHandlingTrait{ protected $enchantments = []; public function hasEnchantments() : bool{ - return !empty($this->enchantments); + return count($this->enchantments) > 0; } public function hasEnchantment(Enchantment $enchantment, int $level = -1) : bool{ diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 33df65074a..5b3725043d 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -682,7 +682,7 @@ class NetworkSession{ $lname = strtolower($command->getName()); $aliases = $command->getAliases(); $aliasObj = null; - if(!empty($aliases)){ + if(count($aliases) > 0){ if(!in_array($lname, $aliases, true)){ //work around a client bug which makes the original name not show when aliases are used $aliases[] = $lname; diff --git a/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php b/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php index bd69eb2442..7d3eedbdb0 100644 --- a/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php @@ -35,7 +35,7 @@ class MismatchTransactionData extends TransactionData{ } protected function decodeData(NetworkBinaryStream $stream) : void{ - if(!empty($this->actions)){ + if(count($this->actions) > 0){ throw new BadPacketException("Mismatch transaction type should not have any actions associated with it, but got " . count($this->actions)); } } diff --git a/src/permission/PermissionParser.php b/src/permission/PermissionParser.php index 33f8357eef..1be4ee2a51 100644 --- a/src/permission/PermissionParser.php +++ b/src/permission/PermissionParser.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\permission; +use function count; use function is_array; use function is_bool; use function ksort; @@ -151,7 +152,7 @@ class PermissionParser{ } $children[$name] = self::emitPermission($child); } - if(!empty($children)){ + if(count($children) > 0){ ksort($children); $result["children"] = $children; } diff --git a/src/player/Player.php b/src/player/Player.php index 93743445cb..90708a8f63 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -901,7 +901,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $this->loadQueue = $newOrder; - if(!empty($this->loadQueue) or !empty($unloadChunks)){ + if(count($this->loadQueue) > 0 or count($unloadChunks) > 0){ $this->networkSession->syncViewAreaCenterPoint($this->location, $this->viewDistance); } diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index b459e2bd84..5e031b7413 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -243,7 +243,7 @@ class PluginManager{ continue; } $ambiguousVersions = ApiVersion::checkAmbiguousVersions($description->getCompatibleApis()); - if(!empty($ambiguousVersions)){ + if(count($ambiguousVersions) > 0){ $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.loadError", [ $name, $this->server->getLanguage()->translateString("pocketmine.plugin.ambiguousMinAPI", [implode(", ", $ambiguousVersions)]) diff --git a/src/utils/RegistryTrait.php b/src/utils/RegistryTrait.php index ec65253029..f24a104788 100644 --- a/src/utils/RegistryTrait.php +++ b/src/utils/RegistryTrait.php @@ -88,7 +88,7 @@ trait RegistryTrait{ * @return object */ public static function __callStatic($name, $arguments){ - if(!empty($arguments)){ + if(count($arguments) > 0){ throw new \ArgumentCountError("Expected exactly 0 arguments, " . count($arguments) . " passed"); } try{ diff --git a/src/world/World.php b/src/world/World.php index 8ff05551aa..dae02190d6 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -608,7 +608,7 @@ class World implements ChunkManager{ $hash = World::chunkHash($chunkX, $chunkZ); if(isset($this->chunkListeners[$hash])){ unset($this->chunkListeners[$hash][spl_object_id($listener)]); - if(empty($this->chunkListeners[$hash])){ + if(count($this->chunkListeners[$hash]) === 0){ unset($this->chunkListeners[$hash]); } } @@ -622,7 +622,7 @@ class World implements ChunkManager{ foreach($this->chunkListeners as $hash => $listeners){ if(isset($listeners[$id])){ unset($this->chunkListeners[$hash][$id]); - if(empty($this->chunkListeners[$hash])){ + if(count($this->chunkListeners[$hash]) === 0){ unset($this->chunkListeners[$hash]); } } @@ -646,7 +646,7 @@ class World implements ChunkManager{ public function sendTime(Player ...$targets) : void{ $pk = SetTimePacket::create($this->time); - if(empty($targets)){ + if(count($targets) === 0){ $this->broadcastGlobalPacket($pk); }else{ $this->server->broadcastPackets($targets, [$pk]); @@ -2370,7 +2370,7 @@ class World implements ChunkManager{ */ public function sendDifficulty(Player ...$targets) : void{ $pk = SetDifficultyPacket::create($this->getDifficulty()); - if(empty($targets)){ + if(count($targets) === 0){ $this->broadcastGlobalPacket($pk); }else{ $this->server->broadcastPackets($targets, [$pk]); diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index f4d75910a4..dd9853b1f7 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -182,7 +182,7 @@ class WorldManager{ if(count($providers) !== 1){ $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.level.loadError", [ $name, - empty($providers) ? + count($providers) === 0 ? $this->server->getLanguage()->translateString("pocketmine.level.unknownFormat") : $this->server->getLanguage()->translateString("pocketmine.level.ambiguousFormat", [implode(", ", array_keys($providers))]) ])); @@ -302,7 +302,7 @@ class WorldManager{ } $path = $this->server->getDataPath() . "worlds/" . $name . "/"; if(!($this->getWorldByName($name) instanceof World)){ - return !empty(WorldProviderManager::getMatchingProviders($path)); + return count(WorldProviderManager::getMatchingProviders($path)) > 0; } return true; diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index e09a0381f8..eb48a59148 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -548,7 +548,7 @@ class Chunk{ } public function isDirty() : bool{ - return $this->dirtyFlags !== 0 or !empty($this->tiles) or !empty($this->getSavableEntities()); + return $this->dirtyFlags !== 0 or count($this->tiles) > 0 or count($this->getSavableEntities()) > 0; } public function getDirtyFlag(int $flag) : bool{ diff --git a/src/world/format/SubChunk.php b/src/world/format/SubChunk.php index 74056f62ac..d4514403e3 100644 --- a/src/world/format/SubChunk.php +++ b/src/world/format/SubChunk.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\world\format; use function array_values; +use function count; class SubChunk implements SubChunkInterface{ /** @var int */ @@ -55,18 +56,18 @@ class SubChunk implements SubChunkInterface{ } public function isEmptyFast() : bool{ - return empty($this->blockLayers); + return count($this->blockLayers) === 0; } public function getFullBlock(int $x, int $y, int $z) : int{ - if(empty($this->blockLayers)){ + if(count($this->blockLayers) === 0){ return $this->defaultBlock; } return $this->blockLayers[0]->get($x, $y, $z); } public function setFullBlock(int $x, int $y, int $z, int $block) : void{ - if(empty($this->blockLayers)){ + if(count($this->blockLayers) === 0){ $this->blockLayers[] = new PalettedBlockArray($this->defaultBlock); } $this->blockLayers[0]->set($x, $y, $z, $block); @@ -80,7 +81,7 @@ class SubChunk implements SubChunkInterface{ } public function getHighestBlockAt(int $x, int $z) : int{ - if(empty($this->blockLayers)){ + if(count($this->blockLayers) === 0){ return -1; } for($y = 15; $y >= 0; --$y){ diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 319ac2297e..a765dd03f5 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -482,7 +482,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ * @param CompoundTag[] $targets */ private function writeTags(array $targets, string $index, \LevelDBWriteBatch $write) : void{ - if(!empty($targets)){ + if(count($targets) > 0){ $nbt = new LittleEndianNbtSerializer(); $write->put($index, $nbt->writeMultiple(array_map(function(CompoundTag $tag) : TreeRoot{ return new TreeRoot($tag); }, $targets))); }else{ From d2aca6023b265a2d2a9de6fd2721d1d3b4243daa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Feb 2020 22:05:15 +0000 Subject: [PATCH 1380/3224] add native return types to closures (for phpstan) --- src/block/Banner.php | 2 +- src/inventory/CallbackInventoryChangeListener.php | 4 ++-- src/network/mcpe/NetworkSession.php | 4 ++-- src/network/mcpe/compression/CompressBatchPromise.php | 2 +- src/network/mcpe/handler/ResourcePacksPacketHandler.php | 4 ++-- src/network/mcpe/protocol/types/command/CommandData.php | 4 ++-- src/plugin/ApiVersion.php | 4 ++-- src/scheduler/ClosureTask.php | 2 +- src/scheduler/SendUsageTask.php | 2 +- src/world/utils/SubChunkIteratorManager.php | 2 +- 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/block/Banner.php b/src/block/Banner.php index 9091d5bfbb..9bf16b9fd5 100644 --- a/src/block/Banner.php +++ b/src/block/Banner.php @@ -138,7 +138,7 @@ class Banner extends Transparent{ * @phpstan-param Deque $patterns */ public function setPatterns(Deque $patterns) : void{ - $checked = $patterns->filter(function($v){ return $v instanceof BannerPattern; }); + $checked = $patterns->filter(function($v) : bool{ return $v instanceof BannerPattern; }); if($checked->count() !== $patterns->count()){ throw new \TypeError("Deque must only contain " . BannerPattern::class . " objects"); } diff --git a/src/inventory/CallbackInventoryChangeListener.php b/src/inventory/CallbackInventoryChangeListener.php index e16e01501c..388b9bf1bb 100644 --- a/src/inventory/CallbackInventoryChangeListener.php +++ b/src/inventory/CallbackInventoryChangeListener.php @@ -46,10 +46,10 @@ class CallbackInventoryChangeListener implements InventoryChangeListener{ */ public function __construct(?\Closure $onSlotChange, ?\Closure $onContentChange){ if($onSlotChange !== null){ - Utils::validateCallableSignature(function(Inventory $inventory, int $slot){}, $onSlotChange); + Utils::validateCallableSignature(function(Inventory $inventory, int $slot) : void{}, $onSlotChange); } if($onContentChange !== null){ - Utils::validateCallableSignature(function(Inventory $inventory){}, $onContentChange); + Utils::validateCallableSignature(function(Inventory $inventory) : void{}, $onContentChange); } $this->onSlotChangeCallback = $onSlotChange; diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 5b3725043d..27ddf11b2f 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -740,7 +740,7 @@ class NetworkSession{ * @phpstan-param \Closure(int $chunkX, int $chunkZ) : void $onCompletion */ public function startUsingChunk(int $chunkX, int $chunkZ, \Closure $onCompletion) : void{ - Utils::validateCallableSignature(function(int $chunkX, int $chunkZ){}, $onCompletion); + Utils::validateCallableSignature(function(int $chunkX, int $chunkZ) : void{}, $onCompletion); $world = $this->player->getLocation()->getWorld(); assert($world !== null); @@ -797,7 +797,7 @@ class NetworkSession{ } public function syncPlayerList() : void{ - $this->sendDataPacket(PlayerListPacket::add(array_map(function(Player $player){ + $this->sendDataPacket(PlayerListPacket::add(array_map(function(Player $player) : PlayerListEntry{ return PlayerListEntry::createAdditionEntry($player->getUniqueId(), $player->getId(), $player->getDisplayName(), SkinAdapterSingleton::get()->toSkinData($player->getSkin()), $player->getXuid()); }, $this->server->getOnlinePlayers()))); } diff --git a/src/network/mcpe/compression/CompressBatchPromise.php b/src/network/mcpe/compression/CompressBatchPromise.php index 94909d5fd9..8fa8b12ae7 100644 --- a/src/network/mcpe/compression/CompressBatchPromise.php +++ b/src/network/mcpe/compression/CompressBatchPromise.php @@ -45,7 +45,7 @@ class CompressBatchPromise{ public function onResolve(\Closure ...$callbacks) : void{ $this->checkCancelled(); foreach($callbacks as $callback){ - Utils::validateCallableSignature(function(CompressBatchPromise $promise){}, $callback); + Utils::validateCallableSignature(function(CompressBatchPromise $promise) : void{}, $callback); } if($this->result !== null){ foreach($callbacks as $callback){ diff --git a/src/network/mcpe/handler/ResourcePacksPacketHandler.php b/src/network/mcpe/handler/ResourcePacksPacketHandler.php index 1f79bf988e..51ec66cbab 100644 --- a/src/network/mcpe/handler/ResourcePacksPacketHandler.php +++ b/src/network/mcpe/handler/ResourcePacksPacketHandler.php @@ -63,7 +63,7 @@ class ResourcePacksPacketHandler extends PacketHandler{ } public function setUp() : void{ - $resourcePackEntries = array_map(static function(ResourcePack $pack){ + $resourcePackEntries = array_map(static function(ResourcePack $pack) : ResourcePackInfoEntry{ //TODO: more stuff return new ResourcePackInfoEntry($pack->getPackId(), $pack->getPackVersion(), $pack->getPackSize(), "", "", "", false); }, $this->resourcePackManager->getResourceStack()); @@ -109,7 +109,7 @@ class ResourcePacksPacketHandler extends PacketHandler{ break; case ResourcePackClientResponsePacket::STATUS_HAVE_ALL_PACKS: - $stack = array_map(static function(ResourcePack $pack){ + $stack = array_map(static function(ResourcePack $pack) : ResourcePackStackEntry{ return new ResourcePackStackEntry($pack->getPackId(), $pack->getPackVersion(), ""); //TODO: subpacks }, $this->resourcePackManager->getResourceStack()); diff --git a/src/network/mcpe/protocol/types/command/CommandData.php b/src/network/mcpe/protocol/types/command/CommandData.php index 5b3ec8fe0a..e528fb50af 100644 --- a/src/network/mcpe/protocol/types/command/CommandData.php +++ b/src/network/mcpe/protocol/types/command/CommandData.php @@ -41,9 +41,9 @@ class CommandData{ * @param CommandParameter[][] $overloads */ public function __construct(string $name, string $description, int $flags, int $permission, ?CommandEnum $aliases, array $overloads){ - (function(array ...$overloads){ + (function(array ...$overloads) : void{ foreach($overloads as $overload){ - (function(CommandParameter ...$parameters){})(...$overload); + (function(CommandParameter ...$parameters) : void{})(...$overload); } })(...$overloads); $this->name = $name; diff --git a/src/plugin/ApiVersion.php b/src/plugin/ApiVersion.php index be2d2ca078..2cf11a7226 100644 --- a/src/plugin/ApiVersion.php +++ b/src/plugin/ApiVersion.php @@ -93,8 +93,8 @@ final class ApiVersion{ } } - usort($result, static function(VersionString $string1, VersionString $string2){ return $string1->compare($string2); }); + usort($result, static function(VersionString $string1, VersionString $string2) : int{ return $string1->compare($string2); }); - return array_map(static function(VersionString $string){ return $string->getBaseVersion(); }, $result); + return array_map(static function(VersionString $string) : string{ return $string->getBaseVersion(); }, $result); } } diff --git a/src/scheduler/ClosureTask.php b/src/scheduler/ClosureTask.php index 6152469c05..2a9996de19 100644 --- a/src/scheduler/ClosureTask.php +++ b/src/scheduler/ClosureTask.php @@ -49,7 +49,7 @@ class ClosureTask extends Task{ * @phpstan-param \Closure(int) : void $closure */ public function __construct(\Closure $closure){ - Utils::validateCallableSignature(function(int $currentTick){}, $closure); + Utils::validateCallableSignature(function(int $currentTick) : void{}, $closure); $this->closure = $closure; } diff --git a/src/scheduler/SendUsageTask.php b/src/scheduler/SendUsageTask.php index d943efb6c4..4b12b26c76 100644 --- a/src/scheduler/SendUsageTask.php +++ b/src/scheduler/SendUsageTask.php @@ -124,7 +124,7 @@ class SendUsageTask extends AsyncTask{ $playerList[$k] = md5($v); } - $players = array_map(function(Player $p){ return md5($p->getUniqueId()->toBinary()); }, $server->getOnlinePlayers()); + $players = array_map(function(Player $p) : string{ return md5($p->getUniqueId()->toBinary()); }, $server->getOnlinePlayers()); $data["players"] = [ "count" => count($players), diff --git a/src/world/utils/SubChunkIteratorManager.php b/src/world/utils/SubChunkIteratorManager.php index 6187f367e9..453093017b 100644 --- a/src/world/utils/SubChunkIteratorManager.php +++ b/src/world/utils/SubChunkIteratorManager.php @@ -90,7 +90,7 @@ class SubChunkIteratorManager{ * @phpstan-param \Closure() : void $callback */ public function onSubChunkChange(\Closure $callback) : void{ - Utils::validateCallableSignature(function(){}, $callback); + Utils::validateCallableSignature(function() : void{}, $callback); $this->onSubChunkChangeFunc = $callback; } From fd675449e91da0b0a94962cc3c8880cc2927e35a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Feb 2020 22:06:34 +0000 Subject: [PATCH 1381/3224] BlockFactory: fill blastResistance with float(0) technically there wasn't anything wrong with this code, but it caused the type inference to report incompatibility, and I can't be bothered to report a PHPStan bug. --- src/block/BlockFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 61bffbe0be..715401fff3 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -93,7 +93,7 @@ class BlockFactory{ self::$lightFilter = \SplFixedArray::fromArray(array_fill(0, 8192, 1)); self::$diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 8192, false)); - self::$blastResistance = \SplFixedArray::fromArray(array_fill(0, 8192, 0)); + self::$blastResistance = \SplFixedArray::fromArray(array_fill(0, 8192, 0.0)); self::register(new ActivatorRail(new BID(Ids::ACTIVATOR_RAIL), "Activator Rail")); self::register(new Air(new BID(Ids::AIR), "Air")); From 85f3dca11b4fa05cc4cd21d04f1f23bf943c8f0a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Feb 2020 22:07:36 +0000 Subject: [PATCH 1382/3224] HandlerListManager: make resolveNearestHandleableParent() a little easier to follow and also sidestep phpstan complaining about using loop vars outside of loop --- src/event/HandlerListManager.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/event/HandlerListManager.php b/src/event/HandlerListManager.php index 46ac79c901..a9814657b6 100644 --- a/src/event/HandlerListManager.php +++ b/src/event/HandlerListManager.php @@ -71,10 +71,13 @@ class HandlerListManager{ * @phpstan-return \ReflectionClass|null */ private static function resolveNearestHandleableParent(\ReflectionClass $class) : ?\ReflectionClass{ - for($parent = $class->getParentClass(); $parent !== false && !self::isValidClass($parent); $parent = $parent->getParentClass()){ + for($parent = $class->getParentClass(); $parent !== false; $parent = $parent->getParentClass()){ + if(self::isValidClass($parent)){ + return $parent; + } //NOOP } - return $parent ?: null; + return null; } /** From bc60bb946237fea8d3961221ee1c403bb2241314 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Feb 2020 22:08:38 +0000 Subject: [PATCH 1383/3224] remove useless type asserts on Entity->getWorld() --- src/item/ChorusFruit.php | 1 - src/item/FlintSteel.php | 1 - 2 files changed, 2 deletions(-) diff --git a/src/item/ChorusFruit.php b/src/item/ChorusFruit.php index 5bca292084..ac1e10188b 100644 --- a/src/item/ChorusFruit.php +++ b/src/item/ChorusFruit.php @@ -47,7 +47,6 @@ class ChorusFruit extends Food{ public function onConsume(Living $consumer) : void{ $world = $consumer->getWorld(); - assert($world !== null); $origin = $consumer->getPosition(); $minX = $origin->getFloorX() - 8; diff --git a/src/item/FlintSteel.php b/src/item/FlintSteel.php index 04c3150904..def28d56e3 100644 --- a/src/item/FlintSteel.php +++ b/src/item/FlintSteel.php @@ -36,7 +36,6 @@ class FlintSteel extends Tool{ public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ if($blockReplace->getId() === BlockLegacyIds::AIR){ $world = $player->getWorld(); - assert($world !== null); $world->setBlock($blockReplace->getPos(), VanillaBlocks::FIRE()); $world->addSound($blockReplace->getPos()->add(0.5, 0.5, 0.5), new FlintSteelSound()); From ee36ac98758076dd4b4fc2f7d150febf1aecbbeb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Feb 2020 22:09:46 +0000 Subject: [PATCH 1384/3224] ProcessLoginTask: use strict base64_decode() --- src/network/mcpe/auth/ProcessLoginTask.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/auth/ProcessLoginTask.php b/src/network/mcpe/auth/ProcessLoginTask.php index 2baf79263d..dcc90d5b2a 100644 --- a/src/network/mcpe/auth/ProcessLoginTask.php +++ b/src/network/mcpe/auth/ProcessLoginTask.php @@ -135,7 +135,7 @@ class ProcessLoginTask extends AsyncTask{ $v = openssl_verify( "$headB64.$payloadB64", (new DerSignatureSerializer())->serialize($sig), - (new PemPublicKeySerializer($derSerializer))->serialize($derSerializer->parse(base64_decode($currentPublicKey))), + (new PemPublicKeySerializer($derSerializer))->serialize($derSerializer->parse(base64_decode($currentPublicKey, true))), OPENSSL_ALGO_SHA384 ); From 04a3e710478164cebe807227cb0a638c613e57c0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Feb 2020 22:10:23 +0000 Subject: [PATCH 1385/3224] ChunkSerializer: avoid using loop vars outside loop scope --- src/network/mcpe/serializer/ChunkSerializer.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index a1d00f37d5..e1e010d653 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -44,10 +44,10 @@ final class ChunkSerializer{ if($chunk->getSubChunk($count - 1)->isEmptyFast()){ continue; } - break; + return $count; } - return $count; + return 0; } public static function serialize(Chunk $chunk, ?string $tiles = null) : string{ From ec9ece56f5046424ac0f886359cd7dc3ffe9e35e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Feb 2020 22:11:14 +0000 Subject: [PATCH 1386/3224] Player: fetch world via location this code caters for the possibility of the world being null. --- src/player/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index 90708a8f63..84cea684bc 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -709,7 +709,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } protected function switchWorld(World $targetWorld) : bool{ - $oldWorld = $this->getWorld(); + $oldWorld = $this->location->getWorld(); if(parent::switchWorld($targetWorld)){ if($oldWorld !== null){ foreach($this->usedChunks as $index => $d){ From 66a1134ca1d55b8d03811ea57f316859d27ce7dd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Feb 2020 22:13:43 +0000 Subject: [PATCH 1387/3224] Player: avoid another empty() usage --- src/player/Player.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 84cea684bc..8ce67d7130 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1958,8 +1958,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $ev = new PlayerQuitEvent($this, $quitMessage ?? $this->getLeaveMessage(), $reason); $ev->call(); - if(!empty($ev->getQuitMessage())){ - $this->server->broadcastMessage($ev->getQuitMessage()); + if($quitMessage != ""){ + $this->server->broadcastMessage($quitMessage); } $this->save(); From 2d461251edde9a4c6dbcce0802e56494128d9731 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Feb 2020 22:14:51 +0000 Subject: [PATCH 1388/3224] phpstan: ignore more errors reported by strict-rules --- tests/phpstan/configs/phpstan-bugs.neon | 17 +++++++++++++++ .../phpstan/configs/runtime-type-checks.neon | 21 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index bb8131bf38..3b3f2db62f 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -21,6 +21,12 @@ parameters: count: 1 path: ../../../src/Server.php + - + #dynamic instanceof + message: "#^Instanceof between pocketmine\\\\block\\\\tile\\\\Tile and class\\-string\\ will always evaluate to true\\.$#" + count: 1 + path: ../../../src/block/Block.php + - message: "#^Comparison operation \"\\>\\=\" between 0 and 2 is always false\\.$#" count: 1 @@ -60,11 +66,22 @@ parameters: count: 1 path: ../../../src/network/mcpe/protocol/DataPacket.php + - + #object to array cast analysis bug + message: "#^Casting to string something that's already string\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/DataPacket.php + - message: "#^If condition is always false\\.$#" count: 1 path: ../../../src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php + - + message: "#^Instanceof between pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\entity\\\\MetadataProperty and pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\entity\\\\MetadataProperty will always evaluate to true\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php + - #phpstan doesn't understand that SplFixedArray may contain null message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertNotNull\\(\\) with int and string will always evaluate to true\\.$#" diff --git a/tests/phpstan/configs/runtime-type-checks.neon b/tests/phpstan/configs/runtime-type-checks.neon index 12ecd489c7..2dd8e5cd7c 100644 --- a/tests/phpstan/configs/runtime-type-checks.neon +++ b/tests/phpstan/configs/runtime-type-checks.neon @@ -1,5 +1,20 @@ parameters: ignoreErrors: + - + message: "#^Instanceof between pocketmine\\\\block\\\\utils\\\\BannerPattern and pocketmine\\\\block\\\\utils\\\\BannerPattern will always evaluate to true\\.$#" + count: 1 + path: ../../../src/block/Banner.php + + - + message: "#^Call to function assert\\(\\) with bool will always evaluate to true\\.$#" + count: 2 + path: ../../../src/block/tile/TileFactory.php + + - + message: "#^Call to function assert\\(\\) with bool will always evaluate to true\\.$#" + count: 2 + path: ../../../src/entity/EntityFactory.php + - message: "#^Instanceof between pocketmine\\\\event\\\\RegisteredListener and pocketmine\\\\event\\\\RegisteredListener will always evaluate to true\\.$#" count: 1 @@ -11,6 +26,12 @@ parameters: count: 3 path: ../../../src/item/Item.php + - + #setLore() + message: "#^Call to function is_string\\(\\) with string will always evaluate to true\\.$#" + count: 1 + path: ../../../src/item/Item.php + - #commands plugin.yml not currently validated, can't be sure message: "#^Call to function is_array\\(\\) with array\\ will always evaluate to true\\.$#" From 2e3a9f251f350f6bd14babe72d72ea3f47cb80ff Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 Feb 2020 22:17:33 +0000 Subject: [PATCH 1389/3224] missed one --- phpstan.neon.dist | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 4ca3d1f0ba..c756ebabec 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -66,6 +66,11 @@ parameters: count: 2 path: src/Server.php + - + message: "#^Instanceof between pocketmine\\\\world\\\\WorldManager and pocketmine\\\\world\\\\WorldManager will always evaluate to true\\.$#" + count: 1 + path: src/Server.php + - message: "#^Call to an undefined method pocketmine\\\\command\\\\CommandSender\\:\\:teleport\\(\\)\\.$#" count: 1 From 17fc49db8a83a5941a549773353c5aadd3c79f33 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 8 Feb 2020 09:07:09 +0000 Subject: [PATCH 1390/3224] Player: fix regression in disconnect caused by 66a1134ca1d55b8d03811ea57f316859d27ce7dd --- src/player/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index 8ce67d7130..cbb7c552a2 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1958,7 +1958,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $ev = new PlayerQuitEvent($this, $quitMessage ?? $this->getLeaveMessage(), $reason); $ev->call(); - if($quitMessage != ""){ + if(($quitMessage = $ev->getQuitMessage()) != ""){ $this->server->broadcastMessage($quitMessage); } $this->save(); From 2375e9519dc618c04470c40ac9270b8a53a5677b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 8 Feb 2020 09:34:22 +0000 Subject: [PATCH 1391/3224] RegionWorldProvider: fix CS --- src/world/format/io/region/RegionWorldProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index fc4abe5900..61ea9d66ac 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\world\format\io\region; use pocketmine\nbt\NBT; -use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\tag\ListTag; use pocketmine\utils\Utils; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\BaseWorldProvider; From 4c51f1dda348d9d1c53c89185ceeb909a1cad21a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 8 Feb 2020 13:38:02 +0000 Subject: [PATCH 1392/3224] Scrap TextContainer, make TranslationContainer immutable TextContainer provided zero real value as a base of TranslationContainer, given that it required its own logic to be handled wherever accepted. As such, it's no better than a simple string. Removing it also allows fixing an ambiguity when embedding translations inside other translations, allowing it to be made immutable. --- src/Server.php | 8 ++--- src/command/Command.php | 16 +++------- src/command/CommandSender.php | 4 +-- src/command/ConsoleCommandSender.php | 6 ++-- src/event/player/PlayerDeathEvent.php | 11 +++---- src/event/player/PlayerJoinEvent.php | 10 +++--- src/event/player/PlayerKickEvent.php | 10 +++--- src/lang/Language.php | 14 +++----- src/lang/TextContainer.php | 46 --------------------------- src/lang/TranslationContainer.php | 14 ++++++-- src/player/Player.php | 18 ++++------- 11 files changed, 53 insertions(+), 104 deletions(-) delete mode 100644 src/lang/TextContainer.php diff --git a/src/Server.php b/src/Server.php index 999ba6c30e..ff3024b22d 100644 --- a/src/Server.php +++ b/src/Server.php @@ -45,7 +45,7 @@ use pocketmine\item\enchantment\Enchantment; use pocketmine\item\ItemFactory; use pocketmine\lang\Language; use pocketmine\lang\LanguageNotFoundException; -use pocketmine\lang\TextContainer; +use pocketmine\lang\TranslationContainer; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; @@ -1138,8 +1138,8 @@ class Server{ } /** - * @param TextContainer|string $message - * @param CommandSender[]|null $recipients + * @param TranslationContainer|string $message + * @param CommandSender[]|null $recipients */ public function broadcastMessage($message, ?array $recipients = null) : int{ if(!is_array($recipients)){ @@ -1210,7 +1210,7 @@ class Server{ } /** - * @param TextContainer|string $message + * @param TranslationContainer|string $message */ public function broadcast($message, string $permissions) : int{ /** @var CommandSender[] $recipients */ diff --git a/src/command/Command.php b/src/command/Command.php index 5d85dc24a7..68cefe0a18 100644 --- a/src/command/Command.php +++ b/src/command/Command.php @@ -27,7 +27,6 @@ declare(strict_types=1); namespace pocketmine\command; use pocketmine\command\utils\CommandException; -use pocketmine\lang\TextContainer; use pocketmine\lang\TranslationContainer; use pocketmine\permission\PermissionManager; use pocketmine\Server; @@ -224,20 +223,15 @@ abstract class Command{ } /** - * @param TextContainer|string $message + * @param TranslationContainer|string $message */ public static function broadcastCommandMessage(CommandSender $source, $message, bool $sendToSource = true) : void{ $users = PermissionManager::getInstance()->getPermissionSubscriptions(Server::BROADCAST_CHANNEL_ADMINISTRATIVE); - if($message instanceof TextContainer){ - $m = clone $message; - $result = "[" . $source->getName() . ": " . ($source->getServer()->getLanguage()->get($m->getText()) !== $m->getText() ? "%" : "") . $m->getText() . "]"; + if($message instanceof TranslationContainer){ + $formatted = "[" . $source->getName() . ": %" . $message->getText() . "]"; - $colored = TextFormat::GRAY . TextFormat::ITALIC . $result; - - $m->setText($result); - $result = clone $m; - $m->setText($colored); - $colored = clone $m; + $result = new TranslationContainer($formatted, $message->getParameters()); + $colored = new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . $formatted, $message->getParameters()); }else{ $result = new TranslationContainer("chat.type.admin", [$source->getName(), $message]); $colored = new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . "%chat.type.admin", [$source->getName(), $message]); diff --git a/src/command/CommandSender.php b/src/command/CommandSender.php index 86406bb7d1..9d2f38cf74 100644 --- a/src/command/CommandSender.php +++ b/src/command/CommandSender.php @@ -23,14 +23,14 @@ declare(strict_types=1); namespace pocketmine\command; -use pocketmine\lang\TextContainer; +use pocketmine\lang\TranslationContainer; use pocketmine\permission\Permissible; use pocketmine\Server; interface CommandSender extends Permissible{ /** - * @param TextContainer|string $message + * @param TranslationContainer|string $message */ public function sendMessage($message) : void; diff --git a/src/command/ConsoleCommandSender.php b/src/command/ConsoleCommandSender.php index 6eb61b4963..7eb7086264 100644 --- a/src/command/ConsoleCommandSender.php +++ b/src/command/ConsoleCommandSender.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\command; -use pocketmine\lang\TextContainer; +use pocketmine\lang\TranslationContainer; use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissibleDelegateTrait; use pocketmine\Server; @@ -46,11 +46,11 @@ class ConsoleCommandSender implements CommandSender{ } /** - * @param TextContainer|string $message + * @param TranslationContainer|string $message */ public function sendMessage($message) : void{ $server = $this->getServer(); - if($message instanceof TextContainer){ + if($message instanceof TranslationContainer){ $message = $server->getLanguage()->translate($message); }else{ $message = $server->getLanguage()->translateString($message); diff --git a/src/event/player/PlayerDeathEvent.php b/src/event/player/PlayerDeathEvent.php index e28c643d10..acfa86a7e3 100644 --- a/src/event/player/PlayerDeathEvent.php +++ b/src/event/player/PlayerDeathEvent.php @@ -30,7 +30,6 @@ use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDeathEvent; use pocketmine\item\Item; -use pocketmine\lang\TextContainer; use pocketmine\lang\TranslationContainer; use pocketmine\player\Player; @@ -38,14 +37,14 @@ class PlayerDeathEvent extends EntityDeathEvent{ /** @var Player */ protected $entity; - /** @var TextContainer|string */ + /** @var TranslationContainer|string */ private $deathMessage; /** @var bool */ private $keepInventory = false; /** - * @param Item[] $drops - * @param string|TextContainer|null $deathMessage Null will cause the default vanilla message to be used + * @param Item[] $drops + * @param string|TranslationContainer|null $deathMessage Null will cause the default vanilla message to be used */ public function __construct(Player $entity, array $drops, int $xp, $deathMessage){ parent::__construct($entity, $drops, $xp); @@ -64,14 +63,14 @@ class PlayerDeathEvent extends EntityDeathEvent{ } /** - * @return TextContainer|string + * @return TranslationContainer|string */ public function getDeathMessage(){ return $this->deathMessage; } /** - * @param TextContainer|string $deathMessage + * @param TranslationContainer|string $deathMessage */ public function setDeathMessage($deathMessage) : void{ $this->deathMessage = $deathMessage; diff --git a/src/event/player/PlayerJoinEvent.php b/src/event/player/PlayerJoinEvent.php index 57e77ccdb3..30a46065bf 100644 --- a/src/event/player/PlayerJoinEvent.php +++ b/src/event/player/PlayerJoinEvent.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\event\player; -use pocketmine\lang\TextContainer; +use pocketmine\lang\TranslationContainer; use pocketmine\player\Player; /** @@ -34,13 +34,13 @@ use pocketmine\player\Player; * @see PlayerLoginEvent */ class PlayerJoinEvent extends PlayerEvent{ - /** @var string|TextContainer */ + /** @var string|TranslationContainer */ protected $joinMessage; /** * PlayerJoinEvent constructor. * - * @param TextContainer|string $joinMessage + * @param TranslationContainer|string $joinMessage */ public function __construct(Player $player, $joinMessage){ $this->player = $player; @@ -48,14 +48,14 @@ class PlayerJoinEvent extends PlayerEvent{ } /** - * @param string|TextContainer $joinMessage + * @param string|TranslationContainer $joinMessage */ public function setJoinMessage($joinMessage) : void{ $this->joinMessage = $joinMessage; } /** - * @return string|TextContainer + * @return string|TranslationContainer */ public function getJoinMessage(){ return $this->joinMessage; diff --git a/src/event/player/PlayerKickEvent.php b/src/event/player/PlayerKickEvent.php index dd78ba63a5..a31e9e1da6 100644 --- a/src/event/player/PlayerKickEvent.php +++ b/src/event/player/PlayerKickEvent.php @@ -25,7 +25,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\lang\TextContainer; +use pocketmine\lang\TranslationContainer; use pocketmine\player\Player; /** @@ -34,7 +34,7 @@ use pocketmine\player\Player; class PlayerKickEvent extends PlayerEvent implements Cancellable{ use CancellableTrait; - /** @var TextContainer|string */ + /** @var TranslationContainer|string */ protected $quitMessage; /** @var string */ @@ -43,7 +43,7 @@ class PlayerKickEvent extends PlayerEvent implements Cancellable{ /** * PlayerKickEvent constructor. * - * @param TextContainer|string $quitMessage + * @param TranslationContainer|string $quitMessage */ public function __construct(Player $player, string $reason, $quitMessage){ $this->player = $player; @@ -60,14 +60,14 @@ class PlayerKickEvent extends PlayerEvent implements Cancellable{ } /** - * @param TextContainer|string $quitMessage + * @param TranslationContainer|string $quitMessage */ public function setQuitMessage($quitMessage) : void{ $this->quitMessage = $quitMessage; } /** - * @return TextContainer|string + * @return TranslationContainer|string */ public function getQuitMessage(){ return $this->quitMessage; diff --git a/src/lang/Language.php b/src/lang/Language.php index 1afbb865c0..7e231542c3 100644 --- a/src/lang/Language.php +++ b/src/lang/Language.php @@ -142,16 +142,12 @@ class Language{ return $baseText; } - public function translate(TextContainer $c) : string{ - if($c instanceof TranslationContainer){ - $baseText = $this->internalGet($c->getText()); - $baseText = $this->parseTranslation($baseText ?? $c->getText()); + public function translate(TranslationContainer $c) : string{ + $baseText = $this->internalGet($c->getText()); + $baseText = $this->parseTranslation($baseText ?? $c->getText()); - foreach($c->getParameters() as $i => $p){ - $baseText = str_replace("{%$i}", $this->parseTranslation($p), $baseText); - } - }else{ - $baseText = $this->parseTranslation($c->getText()); + foreach($c->getParameters() as $i => $p){ + $baseText = str_replace("{%$i}", $this->parseTranslation($p), $baseText); } return $baseText; diff --git a/src/lang/TextContainer.php b/src/lang/TextContainer.php deleted file mode 100644 index e2265bc82c..0000000000 --- a/src/lang/TextContainer.php +++ /dev/null @@ -1,46 +0,0 @@ -text = $text; - } - - public function setText(string $text) : void{ - $this->text = $text; - } - - public function getText() : string{ - return $this->text; - } - - public function __toString() : string{ - return $this->getText(); - } -} diff --git a/src/lang/TranslationContainer.php b/src/lang/TranslationContainer.php index ccbb7f1b88..a16095d323 100644 --- a/src/lang/TranslationContainer.php +++ b/src/lang/TranslationContainer.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\lang; -class TranslationContainer extends TextContainer{ +final class TranslationContainer{ + /** @var string $text */ + protected $text; /** @var string[] $params */ protected $params = []; @@ -32,7 +34,7 @@ class TranslationContainer extends TextContainer{ * @param (float|int|string)[] $params */ public function __construct(string $text, array $params = []){ - parent::__construct($text); + $this->text = $text; $i = 0; foreach($params as $str){ @@ -42,6 +44,10 @@ class TranslationContainer extends TextContainer{ } } + public function getText() : string{ + return $this->text; + } + /** * @return string[] */ @@ -52,4 +58,8 @@ class TranslationContainer extends TextContainer{ public function getParameter(int $i) : ?string{ return $this->params[$i] ?? null; } + + public function __toString() : string{ + return $this->getText(); + } } diff --git a/src/player/Player.php b/src/player/Player.php index cbb7c552a2..d476925ba6 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -73,7 +73,6 @@ use pocketmine\item\enchantment\EnchantmentInstance; use pocketmine\item\enchantment\MeleeWeaponEnchantment; use pocketmine\item\Item; use pocketmine\item\ItemUseResult; -use pocketmine\lang\TextContainer; use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; @@ -1813,15 +1812,12 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Sends a direct chat message to a player * - * @param TextContainer|string $message + * @param TranslationContainer|string $message */ public function sendMessage($message) : void{ - if($message instanceof TextContainer){ - if($message instanceof TranslationContainer){ - $this->sendTranslation($message->getText(), $message->getParameters()); - return; - } - $message = $message->getText(); + if($message instanceof TranslationContainer){ + $this->sendTranslation($message->getText(), $message->getParameters()); + return; } $this->networkSession->onRawChatMessage($this->server->getLanguage()->translateString($message)); @@ -1910,7 +1906,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * Kicks a player from the server * - * @param TextContainer|string $quitMessage + * @param TranslationContainer|string $quitMessage */ public function kick(string $reason = "", bool $isAdmin = true, $quitMessage = null) : bool{ $ev = new PlayerKickEvent($this, $reason, $quitMessage ?? $this->getLeaveMessage()); @@ -1942,8 +1938,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * Note for plugin developers: Prefer kick() with the isAdmin flag set to kick without the "Kicked by admin" part * instead of this method. This way other plugins can have a say in whether the player is removed or not. * - * @param string $reason Shown to the player, usually this will appear on their disconnect screen. - * @param TextContainer|string $quitMessage Message to broadcast to online players (null will use default) + * @param string $reason Shown to the player, usually this will appear on their disconnect screen. + * @param TranslationContainer|string $quitMessage Message to broadcast to online players (null will use default) */ public function disconnect(string $reason, $quitMessage = null, bool $notify = true) : void{ if(!$this->isConnected()){ From ce42ca958e63fc6fa3d54d461093a427ef294db2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 9 Feb 2020 12:13:15 +0000 Subject: [PATCH 1393/3224] InGamePacketHandler: do not execute use-item action if already using item, fixes #3246 the useHeldItem() sets the using-item flag back to true immediately after consumeHeldItem() sets it to false, which caused this bug. stable has the same problem, but the effects don't show due to a well timed MobEquipmentPacket (a happy accident). --- src/network/mcpe/handler/InGamePacketHandler.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 83203d66e4..12a46fea96 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -310,8 +310,10 @@ class InGamePacketHandler extends PacketHandler{ } return true; case UseItemTransactionData::ACTION_CLICK_AIR: - if($this->player->isUsingItem() and !$this->player->consumeHeldItem()){ - $this->session->getInvManager()->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); + if($this->player->isUsingItem()){ + if(!$this->player->consumeHeldItem()){ + $this->session->getInvManager()->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); + } return true; } if(!$this->player->useHeldItem()){ From d360439c92d3f65306d75ac5cf6a6063e1311ffe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 9 Feb 2020 17:48:30 +0000 Subject: [PATCH 1394/3224] FastChunkSerializer: expose a method to disable lighting serialization this is useful for copies which don't care about lighting, such as chunk sending. --- src/world/format/io/FastChunkSerializer.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index f20842114f..cbdefee35b 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -45,15 +45,21 @@ final class FastChunkSerializer{ //NOOP } + public static function serializeWithoutLight(Chunk $chunk) : string{ + return self::serialize($chunk, false); + } + /** * Fast-serializes the chunk for passing between threads * TODO: tiles and entities */ - public static function serialize(Chunk $chunk) : string{ + public static function serialize(Chunk $chunk, bool $includeLight = true) : string{ + $includeLight = $includeLight && $chunk->isLightPopulated(); + $stream = new BinaryStream(); $stream->putInt($chunk->getX()); $stream->putInt($chunk->getZ()); - $stream->putByte(($chunk->isLightPopulated() ? 4 : 0) | ($chunk->isPopulated() ? 2 : 0) | ($chunk->isGenerated() ? 1 : 0)); + $stream->putByte(($includeLight ? 4 : 0) | ($chunk->isPopulated() ? 2 : 0) | ($chunk->isGenerated() ? 1 : 0)); if($chunk->isGenerated()){ //subchunks $subChunks = $chunk->getSubChunks(); @@ -75,7 +81,7 @@ final class FastChunkSerializer{ $stream->put($serialPalette); } - if($chunk->isLightPopulated()){ + if($includeLight){ $stream->put($subChunk->getBlockSkyLightArray()->getData()); $stream->put($subChunk->getBlockLightArray()->getData()); } @@ -83,7 +89,7 @@ final class FastChunkSerializer{ //biomes $stream->put($chunk->getBiomeIdArray()); - if($chunk->isLightPopulated()){ + if($includeLight){ $stream->put(pack("v*", ...$chunk->getHeightMapArray())); } } From 7ad44d840388112114763e9bd0075856bc6fbd22 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 9 Feb 2020 17:49:15 +0000 Subject: [PATCH 1395/3224] ChunkRequestTask: do not copy light information when sending chunks --- src/network/mcpe/ChunkRequestTask.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php index 299bfd7eba..b0218f45e4 100644 --- a/src/network/mcpe/ChunkRequestTask.php +++ b/src/network/mcpe/ChunkRequestTask.php @@ -54,7 +54,7 @@ class ChunkRequestTask extends AsyncTask{ public function __construct(int $chunkX, int $chunkZ, Chunk $chunk, CompressBatchPromise $promise, ?\Closure $onError = null){ $this->compressionLevel = Zlib::$LEVEL; - $this->chunk = FastChunkSerializer::serialize($chunk); + $this->chunk = FastChunkSerializer::serializeWithoutLight($chunk); $this->chunkX = $chunkX; $this->chunkZ = $chunkZ; $this->tiles = ChunkSerializer::serializeTiles($chunk); From e8bb6b86250c0e5331955e19728fdc177e6ffa36 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 10 Feb 2020 11:42:21 +0000 Subject: [PATCH 1396/3224] Command: fix output translation regression caused by 4c51f1dda348d9d1c53c89185ceeb909a1cad21a --- src/command/Command.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command/Command.php b/src/command/Command.php index 68cefe0a18..408fdd9db0 100644 --- a/src/command/Command.php +++ b/src/command/Command.php @@ -228,7 +228,7 @@ abstract class Command{ public static function broadcastCommandMessage(CommandSender $source, $message, bool $sendToSource = true) : void{ $users = PermissionManager::getInstance()->getPermissionSubscriptions(Server::BROADCAST_CHANNEL_ADMINISTRATIVE); if($message instanceof TranslationContainer){ - $formatted = "[" . $source->getName() . ": %" . $message->getText() . "]"; + $formatted = "[" . $source->getName() . ": " . ($source->getServer()->getLanguage()->get($message->getText()) !== $message->getText() ? "%" : "") . $message->getText() . "]"; $result = new TranslationContainer($formatted, $message->getParameters()); $colored = new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . $formatted, $message->getParameters()); From 42148f0d15949faecfbbef8f09ef4355d3dd3899 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 11 Feb 2020 19:14:01 +0000 Subject: [PATCH 1397/3224] PopulationTask: do not populate light in chunks out of the gate this is a relic from when we needed to store light on disk. Now we can just calculate lighting as-needed instead. --- src/world/generator/PopulationTask.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index bfe22168b8..2c6f12474a 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -118,10 +118,6 @@ class PopulationTask extends AsyncTask{ $chunk = $manager->getChunk($chunk->getX(), $chunk->getZ()); $chunk->setPopulated(); - $chunk->recalculateHeightMap(); - $chunk->populateSkyLight(); - $chunk->setLightPopulated(); - $this->chunk = FastChunkSerializer::serialize($chunk); foreach($chunks as $i => $c){ From cd71a6204f968cd31cd2e705240bec9d58d645a6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 11 Feb 2020 19:43:25 +0000 Subject: [PATCH 1398/3224] Revert "PopulationTask: do not populate light in chunks out of the gate" This reverts commit 42148f0d15949faecfbbef8f09ef4355d3dd3899. --- src/world/generator/PopulationTask.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 2c6f12474a..bfe22168b8 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -118,6 +118,10 @@ class PopulationTask extends AsyncTask{ $chunk = $manager->getChunk($chunk->getX(), $chunk->getZ()); $chunk->setPopulated(); + $chunk->recalculateHeightMap(); + $chunk->populateSkyLight(); + $chunk->setLightPopulated(); + $this->chunk = FastChunkSerializer::serialize($chunk); foreach($chunks as $i => $c){ From 4014f9a4f2426b358288ce96386b8d73db760512 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 11 Feb 2020 21:12:18 +0000 Subject: [PATCH 1399/3224] InventoryManager: be aware of client-side state when syncing slots this eliminates feedback loops during client-initiated slot changes, and also makes it possible to have a SlotChangeAction anonymous from its initiator. --- .../transaction/action/SlotChangeAction.php | 7 +---- src/network/mcpe/InventoryManager.php | 27 ++++++++++++++++++- .../mcpe/handler/InGamePacketHandler.php | 2 ++ 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/inventory/transaction/action/SlotChangeAction.php b/src/inventory/transaction/action/SlotChangeAction.php index fe2b6d9b08..eda92b4579 100644 --- a/src/inventory/transaction/action/SlotChangeAction.php +++ b/src/inventory/transaction/action/SlotChangeAction.php @@ -79,11 +79,6 @@ class SlotChangeAction extends InventoryAction{ * Sets the item into the target inventory. */ public function execute(Player $source) : void{ - $this->inventory->setItem($this->inventorySlot, $this->targetItem, false); - foreach($this->inventory->getViewers() as $viewer){ - if($viewer !== $source){ - $viewer->getNetworkSession()->getInvManager()->syncSlot($this->inventory, $this->inventorySlot); - } - } + $this->inventory->setItem($this->inventorySlot, $this->targetItem); } } diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index f7d9e5c6e2..7c8731f4a3 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -31,6 +31,9 @@ use pocketmine\inventory\EnchantInventory; use pocketmine\inventory\FurnaceInventory; use pocketmine\inventory\HopperInventory; use pocketmine\inventory\Inventory; +use pocketmine\inventory\transaction\action\SlotChangeAction; +use pocketmine\inventory\transaction\InventoryTransaction; +use pocketmine\item\Item; use pocketmine\network\mcpe\protocol\ContainerClosePacket; use pocketmine\network\mcpe\protocol\ContainerOpenPacket; use pocketmine\network\mcpe\protocol\ContainerSetDataPacket; @@ -55,6 +58,12 @@ class InventoryManager{ /** @var int */ private $lastInventoryNetworkId = ContainerIds::FIRST; + /** + * @var Item[][] + * @phpstan-var array> + */ + private $initiatedSlotChanges = []; + public function __construct(Player $player, NetworkSession $session){ $this->player = $player; $this->session = $session; @@ -76,6 +85,15 @@ class InventoryManager{ return $this->windowMap[$windowId] ?? null; } + public function onTransactionStart(InventoryTransaction $tx) : void{ + foreach($tx->getActions() as $action){ + if($action instanceof SlotChangeAction and ($windowId = $this->getWindowId($action->getInventory())) !== null){ + //in some cases the inventory might not have a window ID, but still be referenced by a transaction (e.g. crafting grid changes), so we can't unconditionally record the change here or we might leak things + $this->initiatedSlotChanges[$windowId][$action->getSlot()] = $action->getTargetItem(); + } + } + } + public function onCurrentWindowChange(Inventory $inventory) : void{ $this->onCurrentWindowRemove(); $this->windowMap[$this->lastInventoryNetworkId = max(ContainerIds::FIRST, ($this->lastInventoryNetworkId + 1) % ContainerIds::LAST)] = $inventory; @@ -114,6 +132,7 @@ class InventoryManager{ public function onCurrentWindowRemove() : void{ if(isset($this->windowMap[$this->lastInventoryNetworkId])){ unset($this->windowMap[$this->lastInventoryNetworkId]); + unset($this->initiatedSlotChanges[$this->lastInventoryNetworkId]); $this->session->sendDataPacket(ContainerClosePacket::create($this->lastInventoryNetworkId)); } } @@ -121,13 +140,19 @@ class InventoryManager{ public function syncSlot(Inventory $inventory, int $slot) : void{ $windowId = $this->getWindowId($inventory); if($windowId !== null){ - $this->session->sendDataPacket(InventorySlotPacket::create($windowId, $slot, $inventory->getItem($slot))); + $currentItem = $inventory->getItem($slot); + $clientSideItem = $this->initiatedSlotChanges[$windowId][$slot] ?? null; + if($clientSideItem === null or !$clientSideItem->equalsExact($currentItem)){ + $this->session->sendDataPacket(InventorySlotPacket::create($windowId, $slot, $currentItem)); + } + unset($this->initiatedSlotChanges[$windowId][$slot]); } } public function syncContents(Inventory $inventory) : void{ $windowId = $this->getWindowId($inventory); if($windowId !== null){ + unset($this->initiatedSlotChanges[$windowId]); $this->session->sendDataPacket(InventoryContentPacket::create($windowId, $inventory->getContents(true))); } } diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 12a46fea96..eac748203f 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -245,6 +245,7 @@ class InGamePacketHandler extends PacketHandler{ if($isFinalCraftingPart){ try{ + $this->session->getInvManager()->onTransactionStart($this->craftingTransaction); $this->craftingTransaction->execute(); }catch(TransactionValidationException $e){ $this->session->getLogger()->debug("Failed to execute crafting transaction: " . $e->getMessage()); @@ -267,6 +268,7 @@ class InGamePacketHandler extends PacketHandler{ } $transaction = new InventoryTransaction($this->player, $actions); + $this->session->getInvManager()->onTransactionStart($transaction); try{ $transaction->execute(); }catch(TransactionValidationException $e){ From 1c06438cbbc44632a9840c85a1de84bb86bbe756 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 Feb 2020 13:33:23 +0000 Subject: [PATCH 1400/3224] Inventory: remove final usage of $send parameter of setItem() and clear() --- src/inventory/BaseInventory.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/inventory/BaseInventory.php b/src/inventory/BaseInventory.php index ece76f7102..a7f8a66a44 100644 --- a/src/inventory/BaseInventory.php +++ b/src/inventory/BaseInventory.php @@ -92,16 +92,21 @@ abstract class BaseInventory implements Inventory{ $listeners = $this->listeners; $this->listeners = []; + $viewers = $this->viewers; + $this->viewers = []; for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ if(!isset($items[$i])){ - $this->clear($i, false); + $this->clear($i); }else{ - $this->setItem($i, $items[$i], false); + $this->setItem($i, $items[$i]); } } $this->addChangeListeners(...$listeners); //don't directly write, in case listeners were added while operation was in progress + foreach($viewers as $id => $viewer){ + $this->viewers[$id] = $viewer; + } foreach($this->listeners as $listener){ $listener->onContentChange($this); From b108fb61bf0759449ba4fb2a3118cdd2dc8f73fd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 Feb 2020 13:34:35 +0000 Subject: [PATCH 1401/3224] Inventory: drop $send params from setItem() and clear() --- src/crafting/CraftingGrid.php | 4 ++-- src/inventory/BaseInventory.php | 16 +++++++--------- src/inventory/DoubleChestInventory.php | 6 +++--- src/inventory/Inventory.php | 4 ++-- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/crafting/CraftingGrid.php b/src/crafting/CraftingGrid.php index cec88d9667..6b7b952c7b 100644 --- a/src/crafting/CraftingGrid.php +++ b/src/crafting/CraftingGrid.php @@ -58,8 +58,8 @@ class CraftingGrid extends BaseInventory{ return $this->gridWidth; } - public function setItem(int $index, Item $item, bool $send = true) : void{ - parent::setItem($index, $item, $send); + public function setItem(int $index, Item $item) : void{ + parent::setItem($index, $item); $this->seekRecipeBounds(); } diff --git a/src/inventory/BaseInventory.php b/src/inventory/BaseInventory.php index a7f8a66a44..66614c4589 100644 --- a/src/inventory/BaseInventory.php +++ b/src/inventory/BaseInventory.php @@ -119,7 +119,7 @@ abstract class BaseInventory implements Inventory{ } } - public function setItem(int $index, Item $item, bool $send = true) : void{ + public function setItem(int $index, Item $item) : void{ if($item->isNull()){ $item = ItemFactory::air(); }else{ @@ -129,7 +129,7 @@ abstract class BaseInventory implements Inventory{ $oldItem = $this->getItem($index); $this->slots[$index] = $item->isNull() ? null : $item; - $this->onSlotChange($index, $oldItem, $send); + $this->onSlotChange($index, $oldItem); } public function contains(Item $item) : bool{ @@ -313,8 +313,8 @@ abstract class BaseInventory implements Inventory{ return $itemSlots; } - public function clear(int $index, bool $send = true) : void{ - $this->setItem($index, ItemFactory::air(), $send); + public function clear(int $index) : void{ + $this->setItem($index, ItemFactory::air()); } public function clearAll(bool $send = true) : void{ @@ -359,14 +359,12 @@ abstract class BaseInventory implements Inventory{ unset($this->viewers[spl_object_id($who)]); } - protected function onSlotChange(int $index, Item $before, bool $send) : void{ + protected function onSlotChange(int $index, Item $before) : void{ foreach($this->listeners as $listener){ $listener->onSlotChange($this, $index); } - if($send){ - foreach($this->viewers as $viewer){ - $viewer->getNetworkSession()->getInvManager()->syncSlot($this, $index); - } + foreach($this->viewers as $viewer){ + $viewer->getNetworkSession()->getInvManager()->syncSlot($this, $index); } } diff --git a/src/inventory/DoubleChestInventory.php b/src/inventory/DoubleChestInventory.php index 2f607f06a5..41f7ce69e3 100644 --- a/src/inventory/DoubleChestInventory.php +++ b/src/inventory/DoubleChestInventory.php @@ -55,10 +55,10 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ return $index < $this->left->getSize() ? $this->left->getItem($index) : $this->right->getItem($index - $this->left->getSize()); } - public function setItem(int $index, Item $item, bool $send = true) : void{ + public function setItem(int $index, Item $item) : void{ $old = $this->getItem($index); - $index < $this->left->getSize() ? $this->left->setItem($index, $item, $send) : $this->right->setItem($index - $this->left->getSize(), $item, $send); - $this->onSlotChange($index, $old, $send); + $index < $this->left->getSize() ? $this->left->setItem($index, $item) : $this->right->setItem($index - $this->left->getSize(), $item); + $this->onSlotChange($index, $old); } public function getContents(bool $includeEmpty = false) : array{ diff --git a/src/inventory/Inventory.php b/src/inventory/Inventory.php index f8bdd9f1d1..8bb958676d 100644 --- a/src/inventory/Inventory.php +++ b/src/inventory/Inventory.php @@ -43,7 +43,7 @@ interface Inventory{ /** * Puts an Item in a slot. */ - public function setItem(int $index, Item $item, bool $send = true) : void; + public function setItem(int $index, Item $item) : void; /** * Stores the given Items in the inventory. This will try to fill @@ -122,7 +122,7 @@ interface Inventory{ /** * Will clear a specific slot */ - public function clear(int $index, bool $send = true) : void; + public function clear(int $index) : void; /** * Clears all the slots From 55e3b9ed91138dfbd28cca9f100f0c4802736845 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 Feb 2020 16:35:57 +0000 Subject: [PATCH 1402/3224] InventoryManager: avoid feedback loop when closing inventory --- src/network/mcpe/InventoryManager.php | 10 ++++++++++ src/network/mcpe/handler/InGamePacketHandler.php | 9 ++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index 7c8731f4a3..1348e8a5f9 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -137,6 +137,16 @@ class InventoryManager{ } } + public function onClientRemoveWindow(int $id) : void{ + if($id === $this->lastInventoryNetworkId){ + unset($this->windowMap[$id]); + unset($this->initiatedSlotChanges[$id]); + $this->player->removeCurrentWindow(); + }else{ + $this->session->getLogger()->debug("Attempted to close inventory with network ID $id, but current is $this->lastInventoryNetworkId"); + } + } + public function syncSlot(Inventory $inventory, int $slot) : void{ $windowId = $this->getWindowId($inventory); if($windowId !== null){ diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index eac748203f..045e48bc39 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -496,14 +496,9 @@ class InGamePacketHandler extends PacketHandler{ return true; } - $window = $this->player->getCurrentWindow(); - if($window !== null and $packet->windowId === $this->session->getInvManager()->getCurrentWindowId()){ - $this->player->removeCurrentWindow(); - return true; - } + $this->session->getInvManager()->onClientRemoveWindow($packet->windowId); - $this->session->getLogger()->debug("Attempted to close inventory with network ID $packet->windowId, but current is " . $this->session->getInvManager()->getCurrentWindowId()); - return false; + return true; } public function handlePlayerHotbar(PlayerHotbarPacket $packet) : bool{ From 95eddbdd7478d734edefb40b699817023dca3692 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 Feb 2020 17:36:29 +0000 Subject: [PATCH 1403/3224] InventoryManager: move add/remove logic to separate functions --- src/network/mcpe/InventoryManager.php | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index 1348e8a5f9..61f68142ef 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -68,9 +68,17 @@ class InventoryManager{ $this->player = $player; $this->session = $session; - $this->windowMap[ContainerIds::INVENTORY] = $this->player->getInventory(); - $this->windowMap[ContainerIds::ARMOR] = $this->player->getArmorInventory(); - $this->windowMap[ContainerIds::UI] = $this->player->getCursorInventory(); + $this->add(ContainerIds::INVENTORY, $this->player->getInventory()); + $this->add(ContainerIds::ARMOR, $this->player->getArmorInventory()); + $this->add(ContainerIds::UI, $this->player->getCursorInventory()); + } + + private function add(int $id, Inventory $inventory) : void{ + $this->windowMap[$id] = $inventory; + } + + private function remove(int $id) : void{ + unset($this->windowMap[$id], $this->initiatedSlotChanges[$id]); } public function getWindowId(Inventory $inventory) : ?int{ @@ -96,7 +104,7 @@ class InventoryManager{ public function onCurrentWindowChange(Inventory $inventory) : void{ $this->onCurrentWindowRemove(); - $this->windowMap[$this->lastInventoryNetworkId = max(ContainerIds::FIRST, ($this->lastInventoryNetworkId + 1) % ContainerIds::LAST)] = $inventory; + $this->add($this->lastInventoryNetworkId = max(ContainerIds::FIRST, ($this->lastInventoryNetworkId + 1) % ContainerIds::LAST), $inventory); $pk = $this->createContainerOpen($this->lastInventoryNetworkId, $inventory); if($pk !== null){ @@ -131,16 +139,14 @@ class InventoryManager{ public function onCurrentWindowRemove() : void{ if(isset($this->windowMap[$this->lastInventoryNetworkId])){ - unset($this->windowMap[$this->lastInventoryNetworkId]); - unset($this->initiatedSlotChanges[$this->lastInventoryNetworkId]); + $this->remove($this->lastInventoryNetworkId); $this->session->sendDataPacket(ContainerClosePacket::create($this->lastInventoryNetworkId)); } } public function onClientRemoveWindow(int $id) : void{ if($id === $this->lastInventoryNetworkId){ - unset($this->windowMap[$id]); - unset($this->initiatedSlotChanges[$id]); + $this->remove($id); $this->player->removeCurrentWindow(); }else{ $this->session->getLogger()->debug("Attempted to close inventory with network ID $id, but current is $this->lastInventoryNetworkId"); From 36685001bda7be0e20aeeb7f58b428ada4199459 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 23 Feb 2020 20:59:53 +0000 Subject: [PATCH 1404/3224] ContainerOpenPacket: fixed entityInv() not initializing x/y/z fields these are written even when not used, so they have to be initialized. --- src/network/mcpe/protocol/ContainerOpenPacket.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/mcpe/protocol/ContainerOpenPacket.php b/src/network/mcpe/protocol/ContainerOpenPacket.php index 2361de87d9..99743b7364 100644 --- a/src/network/mcpe/protocol/ContainerOpenPacket.php +++ b/src/network/mcpe/protocol/ContainerOpenPacket.php @@ -61,6 +61,7 @@ class ContainerOpenPacket extends DataPacket implements ClientboundPacket{ $result->windowId = $windowId; $result->type = $windowType; $result->entityUniqueId = $entityUniqueId; + $result->x = $result->y = $result->z = 0; //these have to be set even if they aren't used return $result; } From 7c2741e4f57412f1ad553950058acccac23e0fdc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 23 Feb 2020 21:59:51 +0000 Subject: [PATCH 1405/3224] Inventory: eliminate remaining $send parameters --- src/block/tile/ContainerTrait.php | 2 +- src/inventory/BaseInventory.php | 12 +++++------- src/inventory/Inventory.php | 4 ++-- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/block/tile/ContainerTrait.php b/src/block/tile/ContainerTrait.php index 2acc3ea805..f3386a207d 100644 --- a/src/block/tile/ContainerTrait.php +++ b/src/block/tile/ContainerTrait.php @@ -98,6 +98,6 @@ trait ContainerTrait{ foreach($inv->getContents() as $k => $item){ $pos->world->dropItem($pos->add(0.5, 0.5, 0.5), $item); } - $inv->clearAll(false); + $inv->clearAll(); } } diff --git a/src/inventory/BaseInventory.php b/src/inventory/BaseInventory.php index 66614c4589..57e3d199bc 100644 --- a/src/inventory/BaseInventory.php +++ b/src/inventory/BaseInventory.php @@ -85,7 +85,7 @@ abstract class BaseInventory implements Inventory{ /** * @param Item[] $items */ - public function setContents(array $items, bool $send = true) : void{ + public function setContents(array $items) : void{ if(count($items) > $this->getSize()){ $items = array_slice($items, 0, $this->getSize(), true); } @@ -112,10 +112,8 @@ abstract class BaseInventory implements Inventory{ $listener->onContentChange($this); } - if($send){ - foreach($this->getViewers() as $viewer){ - $viewer->getNetworkSession()->getInvManager()->syncContents($this); - } + foreach($this->getViewers() as $viewer){ + $viewer->getNetworkSession()->getInvManager()->syncContents($this); } } @@ -317,8 +315,8 @@ abstract class BaseInventory implements Inventory{ $this->setItem($index, ItemFactory::air()); } - public function clearAll(bool $send = true) : void{ - $this->setContents([], $send); + public function clearAll() : void{ + $this->setContents([]); } public function swap(int $slot1, int $slot2) : void{ diff --git a/src/inventory/Inventory.php b/src/inventory/Inventory.php index 8bb958676d..adbd26c1dd 100644 --- a/src/inventory/Inventory.php +++ b/src/inventory/Inventory.php @@ -80,7 +80,7 @@ interface Inventory{ /** * @param Item[] $items */ - public function setContents(array $items, bool $send = true) : void; + public function setContents(array $items) : void; /** * Checks if the inventory contains any Item with the same material data. @@ -127,7 +127,7 @@ interface Inventory{ /** * Clears all the slots */ - public function clearAll(bool $send = true) : void; + public function clearAll() : void; /** * Swaps the specified slots. From ce0af8b040419b61d034c5a7c7c0e924be3eef15 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 24 Feb 2020 18:59:54 +0000 Subject: [PATCH 1406/3224] DataPacket now encapsulates NetworkBinaryStream instead of extending it ultimately the goal is to remove the NetworkBinaryStream crap entirely, but this change has most of the same benefits and is less disruptive. --- src/network/mcpe/NetworkSession.php | 11 +- src/network/mcpe/PacketBatch.php | 2 +- .../mcpe/protocol/ActorEventPacket.php | 12 +- src/network/mcpe/protocol/ActorFallPacket.php | 12 +- .../mcpe/protocol/ActorPickRequestPacket.php | 8 +- src/network/mcpe/protocol/AddActorPacket.php | 64 +++--- .../mcpe/protocol/AddBehaviorTreePacket.php | 4 +- src/network/mcpe/protocol/AddEntityPacket.php | 4 +- .../mcpe/protocol/AddItemActorPacket.php | 28 +-- .../mcpe/protocol/AddPaintingPacket.php | 20 +- src/network/mcpe/protocol/AddPlayerPacket.php | 88 ++++---- .../mcpe/protocol/AdventureSettingsPacket.php | 24 +-- src/network/mcpe/protocol/AnimatePacket.php | 12 +- .../mcpe/protocol/AnvilDamagePacket.php | 8 +- .../AutomationClientConnectPacket.php | 4 +- .../AvailableActorIdentifiersPacket.php | 4 +- .../mcpe/protocol/AvailableCommandsPacket.php | 126 +++++------ .../protocol/BiomeDefinitionListPacket.php | 4 +- .../mcpe/protocol/BlockActorDataPacket.php | 8 +- .../mcpe/protocol/BlockEventPacket.php | 12 +- .../mcpe/protocol/BlockPickRequestPacket.php | 12 +- src/network/mcpe/protocol/BookEditPacket.php | 44 ++-- src/network/mcpe/protocol/BossEventPacket.php | 40 ++-- src/network/mcpe/protocol/CameraPacket.php | 8 +- .../mcpe/protocol/ChangeDimensionPacket.php | 12 +- .../protocol/ChunkRadiusUpdatedPacket.php | 4 +- .../protocol/ClientCacheBlobStatusPacket.php | 16 +- .../ClientCacheMissResponsePacket.php | 12 +- .../mcpe/protocol/ClientCacheStatusPacket.php | 4 +- .../protocol/ClientboundMapItemDataPacket.php | 96 ++++----- .../protocol/CommandBlockUpdatePacket.php | 48 ++--- .../mcpe/protocol/CommandOutputPacket.php | 36 ++-- .../mcpe/protocol/CommandRequestPacket.php | 12 +- .../protocol/CompletedUsingItemPacket.php | 8 +- .../mcpe/protocol/ContainerClosePacket.php | 4 +- .../mcpe/protocol/ContainerOpenPacket.php | 16 +- .../mcpe/protocol/ContainerSetDataPacket.php | 12 +- .../mcpe/protocol/CraftingDataPacket.php | 92 ++++---- .../mcpe/protocol/CraftingEventPacket.php | 28 +-- src/network/mcpe/protocol/DataPacket.php | 39 ++-- .../mcpe/protocol/DisconnectPacket.php | 8 +- .../mcpe/protocol/EducationSettingsPacket.php | 8 +- src/network/mcpe/protocol/EmotePacket.php | 12 +- src/network/mcpe/protocol/EventPacket.php | 12 +- .../mcpe/protocol/GameRulesChangedPacket.php | 4 +- .../mcpe/protocol/GuiDataPickItemPacket.php | 12 +- src/network/mcpe/protocol/HurtArmorPacket.php | 4 +- src/network/mcpe/protocol/InteractPacket.php | 20 +- .../mcpe/protocol/InventoryContentPacket.php | 12 +- .../mcpe/protocol/InventorySlotPacket.php | 12 +- .../protocol/InventoryTransactionPacket.php | 8 +- .../mcpe/protocol/ItemFrameDropItemPacket.php | 4 +- src/network/mcpe/protocol/LabTablePacket.php | 12 +- .../mcpe/protocol/LecternUpdatePacket.php | 16 +- .../mcpe/protocol/LevelChunkPacket.php | 28 +-- .../mcpe/protocol/LevelEventGenericPacket.php | 8 +- .../mcpe/protocol/LevelEventPacket.php | 12 +- .../mcpe/protocol/LevelSoundEventPacket.php | 24 +-- .../mcpe/protocol/LevelSoundEventPacketV1.php | 24 +-- .../mcpe/protocol/LevelSoundEventPacketV2.php | 24 +-- src/network/mcpe/protocol/LoginPacket.php | 4 +- .../protocol/MapCreateLockedCopyPacket.php | 8 +- .../mcpe/protocol/MapInfoRequestPacket.php | 4 +- .../mcpe/protocol/MobArmorEquipmentPacket.php | 20 +- src/network/mcpe/protocol/MobEffectPacket.php | 24 +-- .../mcpe/protocol/MobEquipmentPacket.php | 20 +- .../mcpe/protocol/ModalFormRequestPacket.php | 8 +- .../mcpe/protocol/ModalFormResponsePacket.php | 8 +- .../mcpe/protocol/MoveActorAbsolutePacket.php | 24 +-- .../mcpe/protocol/MoveActorDeltaPacket.php | 16 +- .../mcpe/protocol/MovePlayerPacket.php | 40 ++-- .../protocol/MultiplayerSettingsPacket.php | 4 +- .../NetworkChunkPublisherUpdatePacket.php | 8 +- .../mcpe/protocol/NetworkSettingsPacket.php | 4 +- .../protocol/NetworkStackLatencyPacket.php | 8 +- .../mcpe/protocol/NpcRequestPacket.php | 16 +- .../OnScreenTextureAnimationPacket.php | 4 +- src/network/mcpe/protocol/Packet.php | 20 +- src/network/mcpe/protocol/PacketPool.php | 2 +- .../mcpe/protocol/PhotoTransferPacket.php | 12 +- src/network/mcpe/protocol/PlaySoundPacket.php | 16 +- .../mcpe/protocol/PlayStatusPacket.php | 4 +- .../mcpe/protocol/PlayerActionPacket.php | 16 +- .../mcpe/protocol/PlayerAuthInputPacket.php | 40 ++-- .../mcpe/protocol/PlayerHotbarPacket.php | 12 +- .../mcpe/protocol/PlayerInputPacket.php | 16 +- .../mcpe/protocol/PlayerListPacket.php | 48 ++--- .../mcpe/protocol/PlayerSkinPacket.php | 16 +- .../mcpe/protocol/PurchaseReceiptPacket.php | 8 +- .../mcpe/protocol/RemoveActorPacket.php | 4 +- .../mcpe/protocol/RemoveEntityPacket.php | 4 +- .../mcpe/protocol/RemoveObjectivePacket.php | 4 +- .../protocol/RequestChunkRadiusPacket.php | 4 +- .../protocol/ResourcePackChunkDataPacket.php | 16 +- .../ResourcePackChunkRequestPacket.php | 8 +- .../ResourcePackClientResponsePacket.php | 12 +- .../protocol/ResourcePackDataInfoPacket.php | 28 +-- .../mcpe/protocol/ResourcePackStackPacket.php | 28 +-- .../mcpe/protocol/ResourcePacksInfoPacket.php | 24 +-- src/network/mcpe/protocol/RespawnPacket.php | 12 +- src/network/mcpe/protocol/RiderJumpPacket.php | 4 +- .../mcpe/protocol/ScriptCustomEventPacket.php | 8 +- .../protocol/ServerSettingsResponsePacket.php | 8 +- .../ServerToClientHandshakePacket.php | 4 +- .../mcpe/protocol/SetActorDataPacket.php | 8 +- .../mcpe/protocol/SetActorLinkPacket.php | 4 +- .../mcpe/protocol/SetActorMotionPacket.php | 8 +- .../protocol/SetCommandsEnabledPacket.php | 4 +- .../protocol/SetDefaultGameTypePacket.php | 4 +- .../mcpe/protocol/SetDifficultyPacket.php | 4 +- .../protocol/SetDisplayObjectivePacket.php | 20 +- src/network/mcpe/protocol/SetHealthPacket.php | 4 +- .../mcpe/protocol/SetLastHurtByPacket.php | 4 +- .../SetLocalPlayerAsInitializedPacket.php | 4 +- .../mcpe/protocol/SetPlayerGameTypePacket.php | 4 +- src/network/mcpe/protocol/SetScorePacket.php | 32 +-- .../protocol/SetScoreboardIdentityPacket.php | 16 +- .../mcpe/protocol/SetSpawnPositionPacket.php | 12 +- src/network/mcpe/protocol/SetTimePacket.php | 4 +- src/network/mcpe/protocol/SetTitlePacket.php | 20 +- .../mcpe/protocol/SettingsCommandPacket.php | 8 +- .../mcpe/protocol/ShowCreditsPacket.php | 8 +- .../mcpe/protocol/ShowProfilePacket.php | 4 +- .../mcpe/protocol/ShowStoreOfferPacket.php | 8 +- .../mcpe/protocol/SimpleEventPacket.php | 4 +- .../protocol/SpawnExperienceOrbPacket.php | 8 +- .../protocol/SpawnParticleEffectPacket.php | 16 +- src/network/mcpe/protocol/StartGamePacket.php | 202 +++++++++--------- src/network/mcpe/protocol/StopSoundPacket.php | 8 +- .../StructureTemplateDataRequestPacket.php | 16 +- .../StructureTemplateDataResponsePacket.php | 12 +- .../mcpe/protocol/SubClientLoginPacket.php | 4 +- .../mcpe/protocol/TakeItemActorPacket.php | 8 +- src/network/mcpe/protocol/TextPacket.php | 36 ++-- src/network/mcpe/protocol/TickSyncPacket.php | 8 +- src/network/mcpe/protocol/TransferPacket.php | 8 +- src/network/mcpe/protocol/UnknownPacket.php | 4 +- .../mcpe/protocol/UpdateAttributesPacket.php | 8 +- .../mcpe/protocol/UpdateBlockPacket.php | 16 +- .../protocol/UpdateBlockPropertiesPacket.php | 4 +- .../mcpe/protocol/UpdateBlockSyncedPacket.php | 8 +- .../mcpe/protocol/UpdateEquipPacket.php | 20 +- .../mcpe/protocol/UpdateSoftEnumPacket.php | 16 +- .../mcpe/protocol/UpdateTradePacket.php | 40 ++-- .../protocol/VideoStreamConnectPacket.php | 20 +- .../mcpe/serializer/NetworkBinaryStream.php | 12 +- 146 files changed, 1249 insertions(+), 1269 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 27ddf11b2f..0925f12493 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -303,7 +303,7 @@ class NetworkSession{ try{ $this->handleDataPacket($pk); }catch(BadPacketException $e){ - $this->logger->debug($pk->getName() . ": " . base64_encode($pk->getBuffer())); + $this->logger->debug($pk->getName() . ": " . base64_encode($pk->getBinaryStream()->getBuffer())); throw new BadPacketException("Error processing " . $pk->getName() . ": " . $e->getMessage(), 0, $e); } } @@ -315,7 +315,7 @@ class NetworkSession{ public function handleDataPacket(Packet $packet) : void{ if(!($packet instanceof ServerboundPacket)){ if($packet instanceof GarbageServerboundPacket){ - $this->logger->debug("Garbage serverbound " . $packet->getName() . ": " . base64_encode($packet->getBuffer())); + $this->logger->debug("Garbage serverbound " . $packet->getName() . ": " . base64_encode($packet->getBinaryStream()->getBuffer())); return; } throw new BadPacketException("Unexpected non-serverbound packet"); @@ -326,15 +326,16 @@ class NetworkSession{ try{ $packet->decode(); - if(!$packet->feof()){ - $remains = substr($packet->getBuffer(), $packet->getOffset()); + $stream = $packet->getBinaryStream(); + if(!$stream->feof()){ + $remains = substr($stream->getBuffer(), $stream->getOffset()); $this->logger->debug("Still " . strlen($remains) . " bytes unread in " . $packet->getName() . ": " . bin2hex($remains)); } $ev = new DataPacketReceiveEvent($this, $packet); $ev->call(); if(!$ev->isCancelled() and !$packet->handle($this->handler)){ - $this->logger->debug("Unhandled " . $packet->getName() . ": " . base64_encode($packet->getBuffer())); + $this->logger->debug("Unhandled " . $packet->getName() . ": " . base64_encode($stream->getBuffer())); } }finally{ $timings->stopTiming(); diff --git a/src/network/mcpe/PacketBatch.php b/src/network/mcpe/PacketBatch.php index aab0b93190..82f9412f1e 100644 --- a/src/network/mcpe/PacketBatch.php +++ b/src/network/mcpe/PacketBatch.php @@ -32,7 +32,7 @@ class PacketBatch extends NetworkBinaryStream{ public function putPacket(Packet $packet) : void{ $packet->encode(); - $this->putString($packet->getBuffer()); + $this->putString($packet->getBinaryStream()->getBuffer()); } /** diff --git a/src/network/mcpe/protocol/ActorEventPacket.php b/src/network/mcpe/protocol/ActorEventPacket.php index ae459f8cd8..438f7ce83c 100644 --- a/src/network/mcpe/protocol/ActorEventPacket.php +++ b/src/network/mcpe/protocol/ActorEventPacket.php @@ -98,15 +98,15 @@ class ActorEventPacket extends DataPacket implements ClientboundPacket, Serverbo } protected function decodePayload() : void{ - $this->entityRuntimeId = $this->getEntityRuntimeId(); - $this->event = $this->getByte(); - $this->data = $this->getVarInt(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + $this->event = $this->buf->getByte(); + $this->data = $this->buf->getVarInt(); } protected function encodePayload() : void{ - $this->putEntityRuntimeId($this->entityRuntimeId); - $this->putByte($this->event); - $this->putVarInt($this->data); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putByte($this->event); + $this->buf->putVarInt($this->data); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ActorFallPacket.php b/src/network/mcpe/protocol/ActorFallPacket.php index 420940f239..10fd48cc92 100644 --- a/src/network/mcpe/protocol/ActorFallPacket.php +++ b/src/network/mcpe/protocol/ActorFallPacket.php @@ -38,15 +38,15 @@ class ActorFallPacket extends DataPacket implements ServerboundPacket{ public $isInVoid; protected function decodePayload() : void{ - $this->entityRuntimeId = $this->getEntityRuntimeId(); - $this->fallDistance = $this->getLFloat(); - $this->isInVoid = $this->getBool(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + $this->fallDistance = $this->buf->getLFloat(); + $this->isInVoid = $this->buf->getBool(); } protected function encodePayload() : void{ - $this->putEntityRuntimeId($this->entityRuntimeId); - $this->putLFloat($this->fallDistance); - $this->putBool($this->isInVoid); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putLFloat($this->fallDistance); + $this->buf->putBool($this->isInVoid); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ActorPickRequestPacket.php b/src/network/mcpe/protocol/ActorPickRequestPacket.php index 6022ea703c..b307e7d518 100644 --- a/src/network/mcpe/protocol/ActorPickRequestPacket.php +++ b/src/network/mcpe/protocol/ActorPickRequestPacket.php @@ -36,13 +36,13 @@ class ActorPickRequestPacket extends DataPacket implements ServerboundPacket{ public $hotbarSlot; protected function decodePayload() : void{ - $this->entityUniqueId = $this->getLLong(); - $this->hotbarSlot = $this->getByte(); + $this->entityUniqueId = $this->buf->getLLong(); + $this->hotbarSlot = $this->buf->getByte(); } protected function encodePayload() : void{ - $this->putLLong($this->entityUniqueId); - $this->putByte($this->hotbarSlot); + $this->buf->putLLong($this->entityUniqueId); + $this->buf->putByte($this->hotbarSlot); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/AddActorPacket.php b/src/network/mcpe/protocol/AddActorPacket.php index 30f827f73c..60e802af72 100644 --- a/src/network/mcpe/protocol/AddActorPacket.php +++ b/src/network/mcpe/protocol/AddActorPacket.php @@ -174,24 +174,24 @@ class AddActorPacket extends DataPacket implements ClientboundPacket{ public $links = []; protected function decodePayload() : void{ - $this->entityUniqueId = $this->getEntityUniqueId(); - $this->entityRuntimeId = $this->getEntityRuntimeId(); - $this->type = array_search($t = $this->getString(), self::LEGACY_ID_MAP_BC, true); + $this->entityUniqueId = $this->buf->getEntityUniqueId(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + $this->type = array_search($t = $this->buf->getString(), self::LEGACY_ID_MAP_BC, true); if($this->type === false){ throw new BadPacketException("Can't map ID $t to legacy ID"); } - $this->position = $this->getVector3(); - $this->motion = $this->getVector3(); - $this->pitch = $this->getLFloat(); - $this->yaw = $this->getLFloat(); - $this->headYaw = $this->getLFloat(); + $this->position = $this->buf->getVector3(); + $this->motion = $this->buf->getVector3(); + $this->pitch = $this->buf->getLFloat(); + $this->yaw = $this->buf->getLFloat(); + $this->headYaw = $this->buf->getLFloat(); - $attrCount = $this->getUnsignedVarInt(); + $attrCount = $this->buf->getUnsignedVarInt(); for($i = 0; $i < $attrCount; ++$i){ - $id = $this->getString(); - $min = $this->getLFloat(); - $current = $this->getLFloat(); - $max = $this->getLFloat(); + $id = $this->buf->getString(); + $min = $this->buf->getLFloat(); + $current = $this->buf->getLFloat(); + $max = $this->buf->getLFloat(); $attr = Attribute::get($id); if($attr !== null){ @@ -208,38 +208,38 @@ class AddActorPacket extends DataPacket implements ClientboundPacket{ } } - $this->metadata = $this->getEntityMetadata(); - $linkCount = $this->getUnsignedVarInt(); + $this->metadata = $this->buf->getEntityMetadata(); + $linkCount = $this->buf->getUnsignedVarInt(); for($i = 0; $i < $linkCount; ++$i){ - $this->links[] = $this->getEntityLink(); + $this->links[] = $this->buf->getEntityLink(); } } protected function encodePayload() : void{ - $this->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); - $this->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); if(!isset(self::LEGACY_ID_MAP_BC[$this->type])){ throw new \InvalidArgumentException("Unknown entity numeric ID $this->type"); } - $this->putString(self::LEGACY_ID_MAP_BC[$this->type]); - $this->putVector3($this->position); - $this->putVector3Nullable($this->motion); - $this->putLFloat($this->pitch); - $this->putLFloat($this->yaw); - $this->putLFloat($this->headYaw); + $this->buf->putString(self::LEGACY_ID_MAP_BC[$this->type]); + $this->buf->putVector3($this->position); + $this->buf->putVector3Nullable($this->motion); + $this->buf->putLFloat($this->pitch); + $this->buf->putLFloat($this->yaw); + $this->buf->putLFloat($this->headYaw); - $this->putUnsignedVarInt(count($this->attributes)); + $this->buf->putUnsignedVarInt(count($this->attributes)); foreach($this->attributes as $attribute){ - $this->putString($attribute->getId()); - $this->putLFloat($attribute->getMinValue()); - $this->putLFloat($attribute->getValue()); - $this->putLFloat($attribute->getMaxValue()); + $this->buf->putString($attribute->getId()); + $this->buf->putLFloat($attribute->getMinValue()); + $this->buf->putLFloat($attribute->getValue()); + $this->buf->putLFloat($attribute->getMaxValue()); } - $this->putEntityMetadata($this->metadata); - $this->putUnsignedVarInt(count($this->links)); + $this->buf->putEntityMetadata($this->metadata); + $this->buf->putUnsignedVarInt(count($this->links)); foreach($this->links as $link){ - $this->putEntityLink($link); + $this->buf->putEntityLink($link); } } diff --git a/src/network/mcpe/protocol/AddBehaviorTreePacket.php b/src/network/mcpe/protocol/AddBehaviorTreePacket.php index 0ce5e4dd4c..57bb64c4f8 100644 --- a/src/network/mcpe/protocol/AddBehaviorTreePacket.php +++ b/src/network/mcpe/protocol/AddBehaviorTreePacket.php @@ -34,11 +34,11 @@ class AddBehaviorTreePacket extends DataPacket implements ClientboundPacket{ public $behaviorTreeJson; protected function decodePayload() : void{ - $this->behaviorTreeJson = $this->getString(); + $this->behaviorTreeJson = $this->buf->getString(); } protected function encodePayload() : void{ - $this->putString($this->behaviorTreeJson); + $this->buf->putString($this->behaviorTreeJson); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/AddEntityPacket.php b/src/network/mcpe/protocol/AddEntityPacket.php index b4e0694f07..7e03e96a29 100644 --- a/src/network/mcpe/protocol/AddEntityPacket.php +++ b/src/network/mcpe/protocol/AddEntityPacket.php @@ -44,11 +44,11 @@ class AddEntityPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->uvarint1 = $this->getUnsignedVarInt(); + $this->uvarint1 = $this->buf->getUnsignedVarInt(); } protected function encodePayload() : void{ - $this->putUnsignedVarInt($this->uvarint1); + $this->buf->putUnsignedVarInt($this->uvarint1); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/AddItemActorPacket.php b/src/network/mcpe/protocol/AddItemActorPacket.php index 0a4efa9ab0..9f841ea2c6 100644 --- a/src/network/mcpe/protocol/AddItemActorPacket.php +++ b/src/network/mcpe/protocol/AddItemActorPacket.php @@ -52,23 +52,23 @@ class AddItemActorPacket extends DataPacket implements ClientboundPacket{ public $isFromFishing = false; protected function decodePayload() : void{ - $this->entityUniqueId = $this->getEntityUniqueId(); - $this->entityRuntimeId = $this->getEntityRuntimeId(); - $this->item = $this->getSlot(); - $this->position = $this->getVector3(); - $this->motion = $this->getVector3(); - $this->metadata = $this->getEntityMetadata(); - $this->isFromFishing = $this->getBool(); + $this->entityUniqueId = $this->buf->getEntityUniqueId(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + $this->item = $this->buf->getSlot(); + $this->position = $this->buf->getVector3(); + $this->motion = $this->buf->getVector3(); + $this->metadata = $this->buf->getEntityMetadata(); + $this->isFromFishing = $this->buf->getBool(); } protected function encodePayload() : void{ - $this->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); - $this->putEntityRuntimeId($this->entityRuntimeId); - $this->putSlot($this->item); - $this->putVector3($this->position); - $this->putVector3Nullable($this->motion); - $this->putEntityMetadata($this->metadata); - $this->putBool($this->isFromFishing); + $this->buf->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putSlot($this->item); + $this->buf->putVector3($this->position); + $this->buf->putVector3Nullable($this->motion); + $this->buf->putEntityMetadata($this->metadata); + $this->buf->putBool($this->isFromFishing); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/AddPaintingPacket.php b/src/network/mcpe/protocol/AddPaintingPacket.php index 805e1eeabd..a4db84d687 100644 --- a/src/network/mcpe/protocol/AddPaintingPacket.php +++ b/src/network/mcpe/protocol/AddPaintingPacket.php @@ -43,19 +43,19 @@ class AddPaintingPacket extends DataPacket implements ClientboundPacket{ public $title; protected function decodePayload() : void{ - $this->entityUniqueId = $this->getEntityUniqueId(); - $this->entityRuntimeId = $this->getEntityRuntimeId(); - $this->position = $this->getVector3(); - $this->direction = $this->getVarInt(); - $this->title = $this->getString(); + $this->entityUniqueId = $this->buf->getEntityUniqueId(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + $this->position = $this->buf->getVector3(); + $this->direction = $this->buf->getVarInt(); + $this->title = $this->buf->getString(); } protected function encodePayload() : void{ - $this->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); - $this->putEntityRuntimeId($this->entityRuntimeId); - $this->putVector3($this->position); - $this->putVarInt($this->direction); - $this->putString($this->title); + $this->buf->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putVector3($this->position); + $this->buf->putVarInt($this->direction); + $this->buf->putString($this->title); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/AddPlayerPacket.php b/src/network/mcpe/protocol/AddPlayerPacket.php index b0d281834c..beb6fa5950 100644 --- a/src/network/mcpe/protocol/AddPlayerPacket.php +++ b/src/network/mcpe/protocol/AddPlayerPacket.php @@ -88,65 +88,65 @@ class AddPlayerPacket extends DataPacket implements ClientboundPacket{ public $buildPlatform = -1; protected function decodePayload() : void{ - $this->uuid = $this->getUUID(); - $this->username = $this->getString(); - $this->entityUniqueId = $this->getEntityUniqueId(); - $this->entityRuntimeId = $this->getEntityRuntimeId(); - $this->platformChatId = $this->getString(); - $this->position = $this->getVector3(); - $this->motion = $this->getVector3(); - $this->pitch = $this->getLFloat(); - $this->yaw = $this->getLFloat(); - $this->headYaw = $this->getLFloat(); - $this->item = $this->getSlot(); - $this->metadata = $this->getEntityMetadata(); + $this->uuid = $this->buf->getUUID(); + $this->username = $this->buf->getString(); + $this->entityUniqueId = $this->buf->getEntityUniqueId(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + $this->platformChatId = $this->buf->getString(); + $this->position = $this->buf->getVector3(); + $this->motion = $this->buf->getVector3(); + $this->pitch = $this->buf->getLFloat(); + $this->yaw = $this->buf->getLFloat(); + $this->headYaw = $this->buf->getLFloat(); + $this->item = $this->buf->getSlot(); + $this->metadata = $this->buf->getEntityMetadata(); - $this->uvarint1 = $this->getUnsignedVarInt(); - $this->uvarint2 = $this->getUnsignedVarInt(); - $this->uvarint3 = $this->getUnsignedVarInt(); - $this->uvarint4 = $this->getUnsignedVarInt(); - $this->uvarint5 = $this->getUnsignedVarInt(); + $this->uvarint1 = $this->buf->getUnsignedVarInt(); + $this->uvarint2 = $this->buf->getUnsignedVarInt(); + $this->uvarint3 = $this->buf->getUnsignedVarInt(); + $this->uvarint4 = $this->buf->getUnsignedVarInt(); + $this->uvarint5 = $this->buf->getUnsignedVarInt(); - $this->long1 = $this->getLLong(); + $this->long1 = $this->buf->getLLong(); - $linkCount = $this->getUnsignedVarInt(); + $linkCount = $this->buf->getUnsignedVarInt(); for($i = 0; $i < $linkCount; ++$i){ - $this->links[$i] = $this->getEntityLink(); + $this->links[$i] = $this->buf->getEntityLink(); } - $this->deviceId = $this->getString(); - $this->buildPlatform = $this->getLInt(); + $this->deviceId = $this->buf->getString(); + $this->buildPlatform = $this->buf->getLInt(); } protected function encodePayload() : void{ - $this->putUUID($this->uuid); - $this->putString($this->username); - $this->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); - $this->putEntityRuntimeId($this->entityRuntimeId); - $this->putString($this->platformChatId); - $this->putVector3($this->position); - $this->putVector3Nullable($this->motion); - $this->putLFloat($this->pitch); - $this->putLFloat($this->yaw); - $this->putLFloat($this->headYaw ?? $this->yaw); - $this->putSlot($this->item); - $this->putEntityMetadata($this->metadata); + $this->buf->putUUID($this->uuid); + $this->buf->putString($this->username); + $this->buf->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putString($this->platformChatId); + $this->buf->putVector3($this->position); + $this->buf->putVector3Nullable($this->motion); + $this->buf->putLFloat($this->pitch); + $this->buf->putLFloat($this->yaw); + $this->buf->putLFloat($this->headYaw ?? $this->yaw); + $this->buf->putSlot($this->item); + $this->buf->putEntityMetadata($this->metadata); - $this->putUnsignedVarInt($this->uvarint1); - $this->putUnsignedVarInt($this->uvarint2); - $this->putUnsignedVarInt($this->uvarint3); - $this->putUnsignedVarInt($this->uvarint4); - $this->putUnsignedVarInt($this->uvarint5); + $this->buf->putUnsignedVarInt($this->uvarint1); + $this->buf->putUnsignedVarInt($this->uvarint2); + $this->buf->putUnsignedVarInt($this->uvarint3); + $this->buf->putUnsignedVarInt($this->uvarint4); + $this->buf->putUnsignedVarInt($this->uvarint5); - $this->putLLong($this->long1); + $this->buf->putLLong($this->long1); - $this->putUnsignedVarInt(count($this->links)); + $this->buf->putUnsignedVarInt(count($this->links)); foreach($this->links as $link){ - $this->putEntityLink($link); + $this->buf->putEntityLink($link); } - $this->putString($this->deviceId); - $this->putLInt($this->buildPlatform); + $this->buf->putString($this->deviceId); + $this->buf->putLInt($this->buildPlatform); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/AdventureSettingsPacket.php b/src/network/mcpe/protocol/AdventureSettingsPacket.php index ccd0668560..a81782af25 100644 --- a/src/network/mcpe/protocol/AdventureSettingsPacket.php +++ b/src/network/mcpe/protocol/AdventureSettingsPacket.php @@ -76,21 +76,21 @@ class AdventureSettingsPacket extends DataPacket implements ClientboundPacket, S public $entityUniqueId; //This is a little-endian long, NOT a var-long. (WTF Mojang) protected function decodePayload() : void{ - $this->flags = $this->getUnsignedVarInt(); - $this->commandPermission = $this->getUnsignedVarInt(); - $this->flags2 = $this->getUnsignedVarInt(); - $this->playerPermission = $this->getUnsignedVarInt(); - $this->customFlags = $this->getUnsignedVarInt(); - $this->entityUniqueId = $this->getLLong(); + $this->flags = $this->buf->getUnsignedVarInt(); + $this->commandPermission = $this->buf->getUnsignedVarInt(); + $this->flags2 = $this->buf->getUnsignedVarInt(); + $this->playerPermission = $this->buf->getUnsignedVarInt(); + $this->customFlags = $this->buf->getUnsignedVarInt(); + $this->entityUniqueId = $this->buf->getLLong(); } protected function encodePayload() : void{ - $this->putUnsignedVarInt($this->flags); - $this->putUnsignedVarInt($this->commandPermission); - $this->putUnsignedVarInt($this->flags2); - $this->putUnsignedVarInt($this->playerPermission); - $this->putUnsignedVarInt($this->customFlags); - $this->putLLong($this->entityUniqueId); + $this->buf->putUnsignedVarInt($this->flags); + $this->buf->putUnsignedVarInt($this->commandPermission); + $this->buf->putUnsignedVarInt($this->flags2); + $this->buf->putUnsignedVarInt($this->playerPermission); + $this->buf->putUnsignedVarInt($this->customFlags); + $this->buf->putLLong($this->entityUniqueId); } public function getFlag(int $flag) : bool{ diff --git a/src/network/mcpe/protocol/AnimatePacket.php b/src/network/mcpe/protocol/AnimatePacket.php index 9ecdc5bb8e..003d7d5e4a 100644 --- a/src/network/mcpe/protocol/AnimatePacket.php +++ b/src/network/mcpe/protocol/AnimatePacket.php @@ -58,18 +58,18 @@ class AnimatePacket extends DataPacket implements ClientboundPacket, Serverbound } protected function decodePayload() : void{ - $this->action = $this->getVarInt(); - $this->entityRuntimeId = $this->getEntityRuntimeId(); + $this->action = $this->buf->getVarInt(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); if(($this->action & 0x80) !== 0){ - $this->float = $this->getLFloat(); + $this->float = $this->buf->getLFloat(); } } protected function encodePayload() : void{ - $this->putVarInt($this->action); - $this->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putVarInt($this->action); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); if(($this->action & 0x80) !== 0){ - $this->putLFloat($this->float); + $this->buf->putLFloat($this->float); } } diff --git a/src/network/mcpe/protocol/AnvilDamagePacket.php b/src/network/mcpe/protocol/AnvilDamagePacket.php index 7aa0a0a6ba..a0f1d1e20a 100644 --- a/src/network/mcpe/protocol/AnvilDamagePacket.php +++ b/src/network/mcpe/protocol/AnvilDamagePacket.php @@ -63,13 +63,13 @@ class AnvilDamagePacket extends DataPacket implements ServerboundPacket{ } protected function decodePayload() : void{ - $this->damageAmount = $this->getByte(); - $this->getBlockPosition($this->x, $this->y, $this->z); + $this->damageAmount = $this->buf->getByte(); + $this->buf->getBlockPosition($this->x, $this->y, $this->z); } protected function encodePayload() : void{ - $this->putByte($this->damageAmount); - $this->putBlockPosition($this->x, $this->y, $this->z); + $this->buf->putByte($this->damageAmount); + $this->buf->putBlockPosition($this->x, $this->y, $this->z); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/AutomationClientConnectPacket.php b/src/network/mcpe/protocol/AutomationClientConnectPacket.php index ee968cff1c..98e9740b63 100644 --- a/src/network/mcpe/protocol/AutomationClientConnectPacket.php +++ b/src/network/mcpe/protocol/AutomationClientConnectPacket.php @@ -34,11 +34,11 @@ class AutomationClientConnectPacket extends DataPacket implements ClientboundPac public $serverUri; protected function decodePayload() : void{ - $this->serverUri = $this->getString(); + $this->serverUri = $this->buf->getString(); } protected function encodePayload() : void{ - $this->putString($this->serverUri); + $this->buf->putString($this->serverUri); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php b/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php index d237877f04..53bb70539d 100644 --- a/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php +++ b/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php @@ -39,11 +39,11 @@ class AvailableActorIdentifiersPacket extends DataPacket implements ClientboundP public $namedtag; protected function decodePayload() : void{ - $this->namedtag = $this->getRemaining(); + $this->namedtag = $this->buf->getRemaining(); } protected function encodePayload() : void{ - $this->put( + $this->buf->put( $this->namedtag ?? self::$DEFAULT_NBT_CACHE ?? (self::$DEFAULT_NBT_CACHE = file_get_contents(\pocketmine\RESOURCE_PATH . '/vanilla/entity_identifiers.nbt')) diff --git a/src/network/mcpe/protocol/AvailableCommandsPacket.php b/src/network/mcpe/protocol/AvailableCommandsPacket.php index 47ad0ee8d4..4ed1ae8f39 100644 --- a/src/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/network/mcpe/protocol/AvailableCommandsPacket.php @@ -114,34 +114,34 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ protected function decodePayload() : void{ /** @var string[] $enumValues */ $enumValues = []; - for($i = 0, $enumValuesCount = $this->getUnsignedVarInt(); $i < $enumValuesCount; ++$i){ - $enumValues[] = $this->getString(); + for($i = 0, $enumValuesCount = $this->buf->getUnsignedVarInt(); $i < $enumValuesCount; ++$i){ + $enumValues[] = $this->buf->getString(); } /** @var string[] $postfixes */ $postfixes = []; - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ - $postfixes[] = $this->getString(); + for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ + $postfixes[] = $this->buf->getString(); } /** @var CommandEnum[] $enums */ $enums = []; - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ + for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ $enums[] = $enum = $this->getEnum($enumValues); if(isset(self::HARDCODED_ENUM_NAMES[$enum->getName()])){ $this->hardcodedEnums[] = $enum; } } - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ + for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ $this->commandData[] = $this->getCommandData($enums, $postfixes); } - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ + for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ $this->softEnums[] = $this->getSoftEnum(); } - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ + for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ $this->enumConstraints[] = $this->getEnumConstraint($enums, $enumValues); } } @@ -153,12 +153,12 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @throws BinaryDataException */ protected function getEnum(array $enumValueList) : CommandEnum{ - $enumName = $this->getString(); + $enumName = $this->buf->getString(); $enumValues = []; $listSize = count($enumValueList); - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ + for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ $index = $this->getEnumValueIndex($listSize); if(!isset($enumValueList[$index])){ throw new BadPacketException("Invalid enum value index $index"); @@ -174,12 +174,12 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @throws BinaryDataException */ protected function getSoftEnum() : CommandEnum{ - $enumName = $this->getString(); + $enumName = $this->buf->getString(); $enumValues = []; - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ + for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ //Get the enum value from the initial pile of mess - $enumValues[] = $this->getString(); + $enumValues[] = $this->buf->getString(); } return new CommandEnum($enumName, $enumValues); @@ -189,10 +189,10 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @param int[] $enumValueMap */ protected function putEnum(CommandEnum $enum, array $enumValueMap) : void{ - $this->putString($enum->getName()); + $this->buf->putString($enum->getName()); $values = $enum->getValues(); - $this->putUnsignedVarInt(count($values)); + $this->buf->putUnsignedVarInt(count($values)); $listSize = count($enumValueMap); foreach($values as $value){ $index = $enumValueMap[$value] ?? -1; @@ -204,12 +204,12 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ } protected function putSoftEnum(CommandEnum $enum) : void{ - $this->putString($enum->getName()); + $this->buf->putString($enum->getName()); $values = $enum->getValues(); - $this->putUnsignedVarInt(count($values)); + $this->buf->putUnsignedVarInt(count($values)); foreach($values as $value){ - $this->putString($value); + $this->buf->putString($value); } } @@ -218,21 +218,21 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ */ protected function getEnumValueIndex(int $valueCount) : int{ if($valueCount < 256){ - return $this->getByte(); + return $this->buf->getByte(); }elseif($valueCount < 65536){ - return $this->getLShort(); + return $this->buf->getLShort(); }else{ - return $this->getLInt(); + return $this->buf->getLInt(); } } protected function putEnumValueIndex(int $index, int $valueCount) : void{ if($valueCount < 256){ - $this->putByte($index); + $this->buf->putByte($index); }elseif($valueCount < 65536){ - $this->putLShort($index); + $this->buf->putLShort($index); }else{ - $this->putLInt($index); + $this->buf->putLInt($index); } } @@ -245,11 +245,11 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ */ protected function getEnumConstraint(array $enums, array $enumValues) : CommandEnumConstraint{ //wtf, what was wrong with an offset inside the enum? :( - $valueIndex = $this->getLInt(); + $valueIndex = $this->buf->getLInt(); if(!isset($enumValues[$valueIndex])){ throw new BadPacketException("Enum constraint refers to unknown enum value index $valueIndex"); } - $enumIndex = $this->getLInt(); + $enumIndex = $this->buf->getLInt(); if(!isset($enums[$enumIndex])){ throw new BadPacketException("Enum constraint refers to unknown enum index $enumIndex"); } @@ -260,8 +260,8 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ } $constraintIds = []; - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ - $constraintIds[] = $this->getByte(); + for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ + $constraintIds[] = $this->buf->getByte(); } return new CommandEnumConstraint($enum, $valueOffset, $constraintIds); @@ -272,11 +272,11 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @param int[] $enumValueIndexes string value -> int index */ protected function putEnumConstraint(CommandEnumConstraint $constraint, array $enumIndexes, array $enumValueIndexes) : void{ - $this->putLInt($enumValueIndexes[$constraint->getAffectedValue()]); - $this->putLInt($enumIndexes[$constraint->getEnum()->getName()]); - $this->putUnsignedVarInt(count($constraint->getConstraints())); + $this->buf->putLInt($enumValueIndexes[$constraint->getAffectedValue()]); + $this->buf->putLInt($enumIndexes[$constraint->getEnum()->getName()]); + $this->buf->putUnsignedVarInt(count($constraint->getConstraints())); foreach($constraint->getConstraints() as $v){ - $this->putByte($v); + $this->buf->putByte($v); } } @@ -288,21 +288,21 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @throws BinaryDataException */ protected function getCommandData(array $enums, array $postfixes) : CommandData{ - $name = $this->getString(); - $description = $this->getString(); - $flags = $this->getByte(); - $permission = $this->getByte(); - $aliases = $enums[$this->getLInt()] ?? null; + $name = $this->buf->getString(); + $description = $this->buf->getString(); + $flags = $this->buf->getByte(); + $permission = $this->buf->getByte(); + $aliases = $enums[$this->buf->getLInt()] ?? null; $overloads = []; - for($overloadIndex = 0, $overloadCount = $this->getUnsignedVarInt(); $overloadIndex < $overloadCount; ++$overloadIndex){ + for($overloadIndex = 0, $overloadCount = $this->buf->getUnsignedVarInt(); $overloadIndex < $overloadCount; ++$overloadIndex){ $overloads[$overloadIndex] = []; - for($paramIndex = 0, $paramCount = $this->getUnsignedVarInt(); $paramIndex < $paramCount; ++$paramIndex){ + for($paramIndex = 0, $paramCount = $this->buf->getUnsignedVarInt(); $paramIndex < $paramCount; ++$paramIndex){ $parameter = new CommandParameter(); - $parameter->paramName = $this->getString(); - $parameter->paramType = $this->getLInt(); - $parameter->isOptional = $this->getBool(); - $parameter->flags = $this->getByte(); + $parameter->paramName = $this->buf->getString(); + $parameter->paramType = $this->buf->getLInt(); + $parameter->isOptional = $this->buf->getBool(); + $parameter->flags = $this->buf->getByte(); if(($parameter->paramType & self::ARG_FLAG_ENUM) !== 0){ $index = ($parameter->paramType & 0xffff); @@ -332,23 +332,23 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @param int[] $postfixIndexes */ protected function putCommandData(CommandData $data, array $enumIndexes, array $postfixIndexes) : void{ - $this->putString($data->name); - $this->putString($data->description); - $this->putByte($data->flags); - $this->putByte($data->permission); + $this->buf->putString($data->name); + $this->buf->putString($data->description); + $this->buf->putByte($data->flags); + $this->buf->putByte($data->permission); if($data->aliases !== null){ - $this->putLInt($enumIndexes[$data->aliases->getName()] ?? -1); + $this->buf->putLInt($enumIndexes[$data->aliases->getName()] ?? -1); }else{ - $this->putLInt(-1); + $this->buf->putLInt(-1); } - $this->putUnsignedVarInt(count($data->overloads)); + $this->buf->putUnsignedVarInt(count($data->overloads)); foreach($data->overloads as $overload){ /** @var CommandParameter[] $overload */ - $this->putUnsignedVarInt(count($overload)); + $this->buf->putUnsignedVarInt(count($overload)); foreach($overload as $parameter){ - $this->putString($parameter->paramName); + $this->buf->putString($parameter->paramName); if($parameter->enum !== null){ $type = self::ARG_FLAG_ENUM | self::ARG_FLAG_VALID | ($enumIndexes[$parameter->enum->getName()] ?? -1); @@ -362,9 +362,9 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ $type = $parameter->paramType; } - $this->putLInt($type); - $this->putBool($parameter->isOptional); - $this->putByte($parameter->flags); + $this->buf->putLInt($type); + $this->buf->putBool($parameter->isOptional); + $this->buf->putByte($parameter->flags); } } } @@ -452,32 +452,32 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ } } - $this->putUnsignedVarInt(count($enumValueIndexes)); + $this->buf->putUnsignedVarInt(count($enumValueIndexes)); foreach($enumValueIndexes as $enumValue => $index){ - $this->putString((string) $enumValue); //stupid PHP key casting D: + $this->buf->putString((string) $enumValue); //stupid PHP key casting D: } - $this->putUnsignedVarInt(count($postfixIndexes)); + $this->buf->putUnsignedVarInt(count($postfixIndexes)); foreach($postfixIndexes as $postfix => $index){ - $this->putString((string) $postfix); //stupid PHP key casting D: + $this->buf->putString((string) $postfix); //stupid PHP key casting D: } - $this->putUnsignedVarInt(count($enums)); + $this->buf->putUnsignedVarInt(count($enums)); foreach($enums as $enum){ $this->putEnum($enum, $enumValueIndexes); } - $this->putUnsignedVarInt(count($this->commandData)); + $this->buf->putUnsignedVarInt(count($this->commandData)); foreach($this->commandData as $data){ $this->putCommandData($data, $enumIndexes, $postfixIndexes); } - $this->putUnsignedVarInt(count($this->softEnums)); + $this->buf->putUnsignedVarInt(count($this->softEnums)); foreach($this->softEnums as $enum){ $this->putSoftEnum($enum); } - $this->putUnsignedVarInt(count($this->enumConstraints)); + $this->buf->putUnsignedVarInt(count($this->enumConstraints)); foreach($this->enumConstraints as $constraint){ $this->putEnumConstraint($constraint, $enumIndexes, $enumValueIndexes); } diff --git a/src/network/mcpe/protocol/BiomeDefinitionListPacket.php b/src/network/mcpe/protocol/BiomeDefinitionListPacket.php index 4a691b7d33..a16f17708a 100644 --- a/src/network/mcpe/protocol/BiomeDefinitionListPacket.php +++ b/src/network/mcpe/protocol/BiomeDefinitionListPacket.php @@ -38,11 +38,11 @@ class BiomeDefinitionListPacket extends DataPacket implements ClientboundPacket{ public $namedtag; protected function decodePayload() : void{ - $this->namedtag = $this->getRemaining(); + $this->namedtag = $this->buf->getRemaining(); } protected function encodePayload() : void{ - $this->put( + $this->buf->put( $this->namedtag ?? self::$DEFAULT_NBT_CACHE ?? (self::$DEFAULT_NBT_CACHE = file_get_contents(\pocketmine\RESOURCE_PATH . '/vanilla/biome_definitions.nbt')) diff --git a/src/network/mcpe/protocol/BlockActorDataPacket.php b/src/network/mcpe/protocol/BlockActorDataPacket.php index 476a33f91b..2bcc51067b 100644 --- a/src/network/mcpe/protocol/BlockActorDataPacket.php +++ b/src/network/mcpe/protocol/BlockActorDataPacket.php @@ -47,13 +47,13 @@ class BlockActorDataPacket extends DataPacket implements ClientboundPacket, Serv } protected function decodePayload() : void{ - $this->getBlockPosition($this->x, $this->y, $this->z); - $this->namedtag = $this->getRemaining(); + $this->buf->getBlockPosition($this->x, $this->y, $this->z); + $this->namedtag = $this->buf->getRemaining(); } protected function encodePayload() : void{ - $this->putBlockPosition($this->x, $this->y, $this->z); - $this->put($this->namedtag); + $this->buf->putBlockPosition($this->x, $this->y, $this->z); + $this->buf->put($this->namedtag); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/BlockEventPacket.php b/src/network/mcpe/protocol/BlockEventPacket.php index 855995ac8c..b928db6c8a 100644 --- a/src/network/mcpe/protocol/BlockEventPacket.php +++ b/src/network/mcpe/protocol/BlockEventPacket.php @@ -53,15 +53,15 @@ class BlockEventPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->getBlockPosition($this->x, $this->y, $this->z); - $this->eventType = $this->getVarInt(); - $this->eventData = $this->getVarInt(); + $this->buf->getBlockPosition($this->x, $this->y, $this->z); + $this->eventType = $this->buf->getVarInt(); + $this->eventData = $this->buf->getVarInt(); } protected function encodePayload() : void{ - $this->putBlockPosition($this->x, $this->y, $this->z); - $this->putVarInt($this->eventType); - $this->putVarInt($this->eventData); + $this->buf->putBlockPosition($this->x, $this->y, $this->z); + $this->buf->putVarInt($this->eventType); + $this->buf->putVarInt($this->eventData); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/BlockPickRequestPacket.php b/src/network/mcpe/protocol/BlockPickRequestPacket.php index 8e2760b7ee..4adf0251de 100644 --- a/src/network/mcpe/protocol/BlockPickRequestPacket.php +++ b/src/network/mcpe/protocol/BlockPickRequestPacket.php @@ -42,15 +42,15 @@ class BlockPickRequestPacket extends DataPacket implements ServerboundPacket{ public $hotbarSlot; protected function decodePayload() : void{ - $this->getSignedBlockPosition($this->blockX, $this->blockY, $this->blockZ); - $this->addUserData = $this->getBool(); - $this->hotbarSlot = $this->getByte(); + $this->buf->getSignedBlockPosition($this->blockX, $this->blockY, $this->blockZ); + $this->addUserData = $this->buf->getBool(); + $this->hotbarSlot = $this->buf->getByte(); } protected function encodePayload() : void{ - $this->putSignedBlockPosition($this->blockX, $this->blockY, $this->blockZ); - $this->putBool($this->addUserData); - $this->putByte($this->hotbarSlot); + $this->buf->putSignedBlockPosition($this->blockX, $this->blockY, $this->blockZ); + $this->buf->putBool($this->addUserData); + $this->buf->putByte($this->hotbarSlot); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/BookEditPacket.php b/src/network/mcpe/protocol/BookEditPacket.php index 4d54cf8cb2..6df127780b 100644 --- a/src/network/mcpe/protocol/BookEditPacket.php +++ b/src/network/mcpe/protocol/BookEditPacket.php @@ -59,27 +59,27 @@ class BookEditPacket extends DataPacket implements ServerboundPacket{ public $xuid; protected function decodePayload() : void{ - $this->type = $this->getByte(); - $this->inventorySlot = $this->getByte(); + $this->type = $this->buf->getByte(); + $this->inventorySlot = $this->buf->getByte(); switch($this->type){ case self::TYPE_REPLACE_PAGE: case self::TYPE_ADD_PAGE: - $this->pageNumber = $this->getByte(); - $this->text = $this->getString(); - $this->photoName = $this->getString(); + $this->pageNumber = $this->buf->getByte(); + $this->text = $this->buf->getString(); + $this->photoName = $this->buf->getString(); break; case self::TYPE_DELETE_PAGE: - $this->pageNumber = $this->getByte(); + $this->pageNumber = $this->buf->getByte(); break; case self::TYPE_SWAP_PAGES: - $this->pageNumber = $this->getByte(); - $this->secondaryPageNumber = $this->getByte(); + $this->pageNumber = $this->buf->getByte(); + $this->secondaryPageNumber = $this->buf->getByte(); break; case self::TYPE_SIGN_BOOK: - $this->title = $this->getString(); - $this->author = $this->getString(); - $this->xuid = $this->getString(); + $this->title = $this->buf->getString(); + $this->author = $this->buf->getString(); + $this->xuid = $this->buf->getString(); break; default: throw new BadPacketException("Unknown book edit type $this->type!"); @@ -87,27 +87,27 @@ class BookEditPacket extends DataPacket implements ServerboundPacket{ } protected function encodePayload() : void{ - $this->putByte($this->type); - $this->putByte($this->inventorySlot); + $this->buf->putByte($this->type); + $this->buf->putByte($this->inventorySlot); switch($this->type){ case self::TYPE_REPLACE_PAGE: case self::TYPE_ADD_PAGE: - $this->putByte($this->pageNumber); - $this->putString($this->text); - $this->putString($this->photoName); + $this->buf->putByte($this->pageNumber); + $this->buf->putString($this->text); + $this->buf->putString($this->photoName); break; case self::TYPE_DELETE_PAGE: - $this->putByte($this->pageNumber); + $this->buf->putByte($this->pageNumber); break; case self::TYPE_SWAP_PAGES: - $this->putByte($this->pageNumber); - $this->putByte($this->secondaryPageNumber); + $this->buf->putByte($this->pageNumber); + $this->buf->putByte($this->secondaryPageNumber); break; case self::TYPE_SIGN_BOOK: - $this->putString($this->title); - $this->putString($this->author); - $this->putString($this->xuid); + $this->buf->putString($this->title); + $this->buf->putString($this->author); + $this->buf->putString($this->xuid); break; default: throw new \InvalidArgumentException("Unknown book edit type $this->type!"); diff --git a/src/network/mcpe/protocol/BossEventPacket.php b/src/network/mcpe/protocol/BossEventPacket.php index bc215e1546..460e9492d4 100644 --- a/src/network/mcpe/protocol/BossEventPacket.php +++ b/src/network/mcpe/protocol/BossEventPacket.php @@ -119,29 +119,29 @@ class BossEventPacket extends DataPacket implements ClientboundPacket, Serverbou } protected function decodePayload() : void{ - $this->bossEid = $this->getEntityUniqueId(); - $this->eventType = $this->getUnsignedVarInt(); + $this->bossEid = $this->buf->getEntityUniqueId(); + $this->eventType = $this->buf->getUnsignedVarInt(); switch($this->eventType){ case self::TYPE_REGISTER_PLAYER: case self::TYPE_UNREGISTER_PLAYER: - $this->playerEid = $this->getEntityUniqueId(); + $this->playerEid = $this->buf->getEntityUniqueId(); break; /** @noinspection PhpMissingBreakStatementInspection */ case self::TYPE_SHOW: - $this->title = $this->getString(); - $this->healthPercent = $this->getLFloat(); + $this->title = $this->buf->getString(); + $this->healthPercent = $this->buf->getLFloat(); /** @noinspection PhpMissingBreakStatementInspection */ case self::TYPE_UNKNOWN_6: - $this->unknownShort = $this->getLShort(); + $this->unknownShort = $this->buf->getLShort(); case self::TYPE_TEXTURE: - $this->color = $this->getUnsignedVarInt(); - $this->overlay = $this->getUnsignedVarInt(); + $this->color = $this->buf->getUnsignedVarInt(); + $this->overlay = $this->buf->getUnsignedVarInt(); break; case self::TYPE_HEALTH_PERCENT: - $this->healthPercent = $this->getLFloat(); + $this->healthPercent = $this->buf->getLFloat(); break; case self::TYPE_TITLE: - $this->title = $this->getString(); + $this->title = $this->buf->getString(); break; default: break; @@ -149,29 +149,29 @@ class BossEventPacket extends DataPacket implements ClientboundPacket, Serverbou } protected function encodePayload() : void{ - $this->putEntityUniqueId($this->bossEid); - $this->putUnsignedVarInt($this->eventType); + $this->buf->putEntityUniqueId($this->bossEid); + $this->buf->putUnsignedVarInt($this->eventType); switch($this->eventType){ case self::TYPE_REGISTER_PLAYER: case self::TYPE_UNREGISTER_PLAYER: - $this->putEntityUniqueId($this->playerEid); + $this->buf->putEntityUniqueId($this->playerEid); break; /** @noinspection PhpMissingBreakStatementInspection */ case self::TYPE_SHOW: - $this->putString($this->title); - $this->putLFloat($this->healthPercent); + $this->buf->putString($this->title); + $this->buf->putLFloat($this->healthPercent); /** @noinspection PhpMissingBreakStatementInspection */ case self::TYPE_UNKNOWN_6: - $this->putLShort($this->unknownShort); + $this->buf->putLShort($this->unknownShort); case self::TYPE_TEXTURE: - $this->putUnsignedVarInt($this->color); - $this->putUnsignedVarInt($this->overlay); + $this->buf->putUnsignedVarInt($this->color); + $this->buf->putUnsignedVarInt($this->overlay); break; case self::TYPE_HEALTH_PERCENT: - $this->putLFloat($this->healthPercent); + $this->buf->putLFloat($this->healthPercent); break; case self::TYPE_TITLE: - $this->putString($this->title); + $this->buf->putString($this->title); break; default: break; diff --git a/src/network/mcpe/protocol/CameraPacket.php b/src/network/mcpe/protocol/CameraPacket.php index 06ce1cd034..81a3bfe074 100644 --- a/src/network/mcpe/protocol/CameraPacket.php +++ b/src/network/mcpe/protocol/CameraPacket.php @@ -36,13 +36,13 @@ class CameraPacket extends DataPacket implements ClientboundPacket{ public $playerUniqueId; protected function decodePayload() : void{ - $this->cameraUniqueId = $this->getEntityUniqueId(); - $this->playerUniqueId = $this->getEntityUniqueId(); + $this->cameraUniqueId = $this->buf->getEntityUniqueId(); + $this->playerUniqueId = $this->buf->getEntityUniqueId(); } protected function encodePayload() : void{ - $this->putEntityUniqueId($this->cameraUniqueId); - $this->putEntityUniqueId($this->playerUniqueId); + $this->buf->putEntityUniqueId($this->cameraUniqueId); + $this->buf->putEntityUniqueId($this->playerUniqueId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ChangeDimensionPacket.php b/src/network/mcpe/protocol/ChangeDimensionPacket.php index 0cf5dfae5c..ac68ac1d14 100644 --- a/src/network/mcpe/protocol/ChangeDimensionPacket.php +++ b/src/network/mcpe/protocol/ChangeDimensionPacket.php @@ -39,15 +39,15 @@ class ChangeDimensionPacket extends DataPacket implements ClientboundPacket{ public $respawn = false; protected function decodePayload() : void{ - $this->dimension = $this->getVarInt(); - $this->position = $this->getVector3(); - $this->respawn = $this->getBool(); + $this->dimension = $this->buf->getVarInt(); + $this->position = $this->buf->getVector3(); + $this->respawn = $this->buf->getBool(); } protected function encodePayload() : void{ - $this->putVarInt($this->dimension); - $this->putVector3($this->position); - $this->putBool($this->respawn); + $this->buf->putVarInt($this->dimension); + $this->buf->putVector3($this->position); + $this->buf->putBool($this->respawn); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php b/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php index 567c291e44..996dfc3c70 100644 --- a/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php +++ b/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php @@ -40,11 +40,11 @@ class ChunkRadiusUpdatedPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->radius = $this->getVarInt(); + $this->radius = $this->buf->getVarInt(); } protected function encodePayload() : void{ - $this->putVarInt($this->radius); + $this->buf->putVarInt($this->radius); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php b/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php index 46a1eb005a..7954fa6bb5 100644 --- a/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php +++ b/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php @@ -66,24 +66,24 @@ class ClientCacheBlobStatusPacket extends DataPacket implements ServerboundPacke } protected function decodePayload() : void{ - $hitCount = $this->getUnsignedVarInt(); - $missCount = $this->getUnsignedVarInt(); + $hitCount = $this->buf->getUnsignedVarInt(); + $missCount = $this->buf->getUnsignedVarInt(); for($i = 0; $i < $hitCount; ++$i){ - $this->hitHashes[] = $this->getLLong(); + $this->hitHashes[] = $this->buf->getLLong(); } for($i = 0; $i < $missCount; ++$i){ - $this->missHashes[] = $this->getLLong(); + $this->missHashes[] = $this->buf->getLLong(); } } protected function encodePayload() : void{ - $this->putUnsignedVarInt(count($this->hitHashes)); - $this->putUnsignedVarInt(count($this->missHashes)); + $this->buf->putUnsignedVarInt(count($this->hitHashes)); + $this->buf->putUnsignedVarInt(count($this->missHashes)); foreach($this->hitHashes as $hash){ - $this->putLLong($hash); + $this->buf->putLLong($hash); } foreach($this->missHashes as $hash){ - $this->putLLong($hash); + $this->buf->putLLong($hash); } } diff --git a/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php b/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php index e523c479c8..883859acc3 100644 --- a/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php +++ b/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php @@ -55,18 +55,18 @@ class ClientCacheMissResponsePacket extends DataPacket implements ClientboundPac } protected function decodePayload() : void{ - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ - $hash = $this->getLLong(); - $payload = $this->getString(); + for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ + $hash = $this->buf->getLLong(); + $payload = $this->buf->getString(); $this->blobs[] = new ChunkCacheBlob($hash, $payload); } } protected function encodePayload() : void{ - $this->putUnsignedVarInt(count($this->blobs)); + $this->buf->putUnsignedVarInt(count($this->blobs)); foreach($this->blobs as $blob){ - $this->putLLong($blob->getHash()); - $this->putString($blob->getPayload()); + $this->buf->putLLong($blob->getHash()); + $this->buf->putString($blob->getPayload()); } } diff --git a/src/network/mcpe/protocol/ClientCacheStatusPacket.php b/src/network/mcpe/protocol/ClientCacheStatusPacket.php index ec42d5cfc1..4b44f6dc18 100644 --- a/src/network/mcpe/protocol/ClientCacheStatusPacket.php +++ b/src/network/mcpe/protocol/ClientCacheStatusPacket.php @@ -44,11 +44,11 @@ class ClientCacheStatusPacket extends DataPacket implements ServerboundPacket{ } protected function decodePayload() : void{ - $this->enabled = $this->getBool(); + $this->enabled = $this->buf->getBool(); } protected function encodePayload() : void{ - $this->putBool($this->enabled); + $this->buf->putBool($this->enabled); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php index 8be2da58e9..d9be5178e8 100644 --- a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php +++ b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php @@ -73,68 +73,68 @@ class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPack public $colors = []; protected function decodePayload() : void{ - $this->mapId = $this->getEntityUniqueId(); - $this->type = $this->getUnsignedVarInt(); - $this->dimensionId = $this->getByte(); - $this->isLocked = $this->getBool(); + $this->mapId = $this->buf->getEntityUniqueId(); + $this->type = $this->buf->getUnsignedVarInt(); + $this->dimensionId = $this->buf->getByte(); + $this->isLocked = $this->buf->getBool(); if(($this->type & 0x08) !== 0){ - $count = $this->getUnsignedVarInt(); + $count = $this->buf->getUnsignedVarInt(); for($i = 0; $i < $count; ++$i){ - $this->eids[] = $this->getEntityUniqueId(); + $this->eids[] = $this->buf->getEntityUniqueId(); } } if(($this->type & (0x08 | self::BITFLAG_DECORATION_UPDATE | self::BITFLAG_TEXTURE_UPDATE)) !== 0){ //Decoration bitflag or colour bitflag - $this->scale = $this->getByte(); + $this->scale = $this->buf->getByte(); } if(($this->type & self::BITFLAG_DECORATION_UPDATE) !== 0){ - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ + for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ $object = new MapTrackedObject(); - $object->type = $this->getLInt(); + $object->type = $this->buf->getLInt(); if($object->type === MapTrackedObject::TYPE_BLOCK){ - $this->getBlockPosition($object->x, $object->y, $object->z); + $this->buf->getBlockPosition($object->x, $object->y, $object->z); }elseif($object->type === MapTrackedObject::TYPE_ENTITY){ - $object->entityUniqueId = $this->getEntityUniqueId(); + $object->entityUniqueId = $this->buf->getEntityUniqueId(); }else{ throw new BadPacketException("Unknown map object type $object->type"); } $this->trackedEntities[] = $object; } - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ - $icon = $this->getByte(); - $rotation = $this->getByte(); - $xOffset = $this->getByte(); - $yOffset = $this->getByte(); - $label = $this->getString(); - $color = Color::fromRGBA(Binary::flipIntEndianness($this->getUnsignedVarInt())); + for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ + $icon = $this->buf->getByte(); + $rotation = $this->buf->getByte(); + $xOffset = $this->buf->getByte(); + $yOffset = $this->buf->getByte(); + $label = $this->buf->getString(); + $color = Color::fromRGBA(Binary::flipIntEndianness($this->buf->getUnsignedVarInt())); $this->decorations[] = new MapDecoration($icon, $rotation, $xOffset, $yOffset, $label, $color); } } if(($this->type & self::BITFLAG_TEXTURE_UPDATE) !== 0){ - $this->width = $this->getVarInt(); - $this->height = $this->getVarInt(); - $this->xOffset = $this->getVarInt(); - $this->yOffset = $this->getVarInt(); + $this->width = $this->buf->getVarInt(); + $this->height = $this->buf->getVarInt(); + $this->xOffset = $this->buf->getVarInt(); + $this->yOffset = $this->buf->getVarInt(); - $count = $this->getUnsignedVarInt(); + $count = $this->buf->getUnsignedVarInt(); if($count !== $this->width * $this->height){ throw new BadPacketException("Expected colour count of " . ($this->height * $this->width) . " (height $this->height * width $this->width), got $count"); } for($y = 0; $y < $this->height; ++$y){ for($x = 0; $x < $this->width; ++$x){ - $this->colors[$y][$x] = Color::fromRGBA(Binary::flipIntEndianness($this->getUnsignedVarInt())); + $this->colors[$y][$x] = Color::fromRGBA(Binary::flipIntEndianness($this->buf->getUnsignedVarInt())); } } } } protected function encodePayload() : void{ - $this->putEntityUniqueId($this->mapId); + $this->buf->putEntityUniqueId($this->mapId); $type = 0; if(($eidsCount = count($this->eids)) > 0){ @@ -147,57 +147,57 @@ class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPack $type |= self::BITFLAG_TEXTURE_UPDATE; } - $this->putUnsignedVarInt($type); - $this->putByte($this->dimensionId); - $this->putBool($this->isLocked); + $this->buf->putUnsignedVarInt($type); + $this->buf->putByte($this->dimensionId); + $this->buf->putBool($this->isLocked); if(($type & 0x08) !== 0){ //TODO: find out what these are for - $this->putUnsignedVarInt($eidsCount); + $this->buf->putUnsignedVarInt($eidsCount); foreach($this->eids as $eid){ - $this->putEntityUniqueId($eid); + $this->buf->putEntityUniqueId($eid); } } if(($type & (0x08 | self::BITFLAG_TEXTURE_UPDATE | self::BITFLAG_DECORATION_UPDATE)) !== 0){ - $this->putByte($this->scale); + $this->buf->putByte($this->scale); } if(($type & self::BITFLAG_DECORATION_UPDATE) !== 0){ - $this->putUnsignedVarInt(count($this->trackedEntities)); + $this->buf->putUnsignedVarInt(count($this->trackedEntities)); foreach($this->trackedEntities as $object){ - $this->putLInt($object->type); + $this->buf->putLInt($object->type); if($object->type === MapTrackedObject::TYPE_BLOCK){ - $this->putBlockPosition($object->x, $object->y, $object->z); + $this->buf->putBlockPosition($object->x, $object->y, $object->z); }elseif($object->type === MapTrackedObject::TYPE_ENTITY){ - $this->putEntityUniqueId($object->entityUniqueId); + $this->buf->putEntityUniqueId($object->entityUniqueId); }else{ throw new \InvalidArgumentException("Unknown map object type $object->type"); } } - $this->putUnsignedVarInt($decorationCount); + $this->buf->putUnsignedVarInt($decorationCount); foreach($this->decorations as $decoration){ - $this->putByte($decoration->getIcon()); - $this->putByte($decoration->getRotation()); - $this->putByte($decoration->getXOffset()); - $this->putByte($decoration->getYOffset()); - $this->putString($decoration->getLabel()); - $this->putUnsignedVarInt(Binary::flipIntEndianness($decoration->getColor()->toRGBA())); + $this->buf->putByte($decoration->getIcon()); + $this->buf->putByte($decoration->getRotation()); + $this->buf->putByte($decoration->getXOffset()); + $this->buf->putByte($decoration->getYOffset()); + $this->buf->putString($decoration->getLabel()); + $this->buf->putUnsignedVarInt(Binary::flipIntEndianness($decoration->getColor()->toRGBA())); } } if(($type & self::BITFLAG_TEXTURE_UPDATE) !== 0){ - $this->putVarInt($this->width); - $this->putVarInt($this->height); - $this->putVarInt($this->xOffset); - $this->putVarInt($this->yOffset); + $this->buf->putVarInt($this->width); + $this->buf->putVarInt($this->height); + $this->buf->putVarInt($this->xOffset); + $this->buf->putVarInt($this->yOffset); - $this->putUnsignedVarInt($this->width * $this->height); //list count, but we handle it as a 2D array... thanks for the confusion mojang + $this->buf->putUnsignedVarInt($this->width * $this->height); //list count, but we handle it as a 2D array... thanks for the confusion mojang for($y = 0; $y < $this->height; ++$y){ for($x = 0; $x < $this->width; ++$x){ //if mojang had any sense this would just be a regular LE int - $this->putUnsignedVarInt(Binary::flipIntEndianness($this->colors[$y][$x]->toRGBA())); + $this->buf->putUnsignedVarInt(Binary::flipIntEndianness($this->colors[$y][$x]->toRGBA())); } } } diff --git a/src/network/mcpe/protocol/CommandBlockUpdatePacket.php b/src/network/mcpe/protocol/CommandBlockUpdatePacket.php index da4f66ec3e..038e1bacb8 100644 --- a/src/network/mcpe/protocol/CommandBlockUpdatePacket.php +++ b/src/network/mcpe/protocol/CommandBlockUpdatePacket.php @@ -63,46 +63,46 @@ class CommandBlockUpdatePacket extends DataPacket implements ServerboundPacket{ public $executeOnFirstTick; protected function decodePayload() : void{ - $this->isBlock = $this->getBool(); + $this->isBlock = $this->buf->getBool(); if($this->isBlock){ - $this->getBlockPosition($this->x, $this->y, $this->z); - $this->commandBlockMode = $this->getUnsignedVarInt(); - $this->isRedstoneMode = $this->getBool(); - $this->isConditional = $this->getBool(); + $this->buf->getBlockPosition($this->x, $this->y, $this->z); + $this->commandBlockMode = $this->buf->getUnsignedVarInt(); + $this->isRedstoneMode = $this->buf->getBool(); + $this->isConditional = $this->buf->getBool(); }else{ //Minecart with command block - $this->minecartEid = $this->getEntityRuntimeId(); + $this->minecartEid = $this->buf->getEntityRuntimeId(); } - $this->command = $this->getString(); - $this->lastOutput = $this->getString(); - $this->name = $this->getString(); + $this->command = $this->buf->getString(); + $this->lastOutput = $this->buf->getString(); + $this->name = $this->buf->getString(); - $this->shouldTrackOutput = $this->getBool(); - $this->tickDelay = $this->getLInt(); - $this->executeOnFirstTick = $this->getBool(); + $this->shouldTrackOutput = $this->buf->getBool(); + $this->tickDelay = $this->buf->getLInt(); + $this->executeOnFirstTick = $this->buf->getBool(); } protected function encodePayload() : void{ - $this->putBool($this->isBlock); + $this->buf->putBool($this->isBlock); if($this->isBlock){ - $this->putBlockPosition($this->x, $this->y, $this->z); - $this->putUnsignedVarInt($this->commandBlockMode); - $this->putBool($this->isRedstoneMode); - $this->putBool($this->isConditional); + $this->buf->putBlockPosition($this->x, $this->y, $this->z); + $this->buf->putUnsignedVarInt($this->commandBlockMode); + $this->buf->putBool($this->isRedstoneMode); + $this->buf->putBool($this->isConditional); }else{ - $this->putEntityRuntimeId($this->minecartEid); + $this->buf->putEntityRuntimeId($this->minecartEid); } - $this->putString($this->command); - $this->putString($this->lastOutput); - $this->putString($this->name); + $this->buf->putString($this->command); + $this->buf->putString($this->lastOutput); + $this->buf->putString($this->name); - $this->putBool($this->shouldTrackOutput); - $this->putLInt($this->tickDelay); - $this->putBool($this->executeOnFirstTick); + $this->buf->putBool($this->shouldTrackOutput); + $this->buf->putLInt($this->tickDelay); + $this->buf->putBool($this->executeOnFirstTick); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/CommandOutputPacket.php b/src/network/mcpe/protocol/CommandOutputPacket.php index 313933b649..ec15f581ec 100644 --- a/src/network/mcpe/protocol/CommandOutputPacket.php +++ b/src/network/mcpe/protocol/CommandOutputPacket.php @@ -46,16 +46,16 @@ class CommandOutputPacket extends DataPacket implements ClientboundPacket{ public $unknownString; protected function decodePayload() : void{ - $this->originData = $this->getCommandOriginData(); - $this->outputType = $this->getByte(); - $this->successCount = $this->getUnsignedVarInt(); + $this->originData = $this->buf->getCommandOriginData(); + $this->outputType = $this->buf->getByte(); + $this->successCount = $this->buf->getUnsignedVarInt(); - for($i = 0, $size = $this->getUnsignedVarInt(); $i < $size; ++$i){ + for($i = 0, $size = $this->buf->getUnsignedVarInt(); $i < $size; ++$i){ $this->messages[] = $this->getCommandMessage(); } if($this->outputType === 4){ - $this->unknownString = $this->getString(); + $this->unknownString = $this->buf->getString(); } } @@ -65,38 +65,38 @@ class CommandOutputPacket extends DataPacket implements ClientboundPacket{ protected function getCommandMessage() : CommandOutputMessage{ $message = new CommandOutputMessage(); - $message->isInternal = $this->getBool(); - $message->messageId = $this->getString(); + $message->isInternal = $this->buf->getBool(); + $message->messageId = $this->buf->getString(); - for($i = 0, $size = $this->getUnsignedVarInt(); $i < $size; ++$i){ - $message->parameters[] = $this->getString(); + for($i = 0, $size = $this->buf->getUnsignedVarInt(); $i < $size; ++$i){ + $message->parameters[] = $this->buf->getString(); } return $message; } protected function encodePayload() : void{ - $this->putCommandOriginData($this->originData); - $this->putByte($this->outputType); - $this->putUnsignedVarInt($this->successCount); + $this->buf->putCommandOriginData($this->originData); + $this->buf->putByte($this->outputType); + $this->buf->putUnsignedVarInt($this->successCount); - $this->putUnsignedVarInt(count($this->messages)); + $this->buf->putUnsignedVarInt(count($this->messages)); foreach($this->messages as $message){ $this->putCommandMessage($message); } if($this->outputType === 4){ - $this->putString($this->unknownString); + $this->buf->putString($this->unknownString); } } protected function putCommandMessage(CommandOutputMessage $message) : void{ - $this->putBool($message->isInternal); - $this->putString($message->messageId); + $this->buf->putBool($message->isInternal); + $this->buf->putString($message->messageId); - $this->putUnsignedVarInt(count($message->parameters)); + $this->buf->putUnsignedVarInt(count($message->parameters)); foreach($message->parameters as $parameter){ - $this->putString($parameter); + $this->buf->putString($parameter); } } diff --git a/src/network/mcpe/protocol/CommandRequestPacket.php b/src/network/mcpe/protocol/CommandRequestPacket.php index 293acb1dbb..ab49ada1f8 100644 --- a/src/network/mcpe/protocol/CommandRequestPacket.php +++ b/src/network/mcpe/protocol/CommandRequestPacket.php @@ -39,15 +39,15 @@ class CommandRequestPacket extends DataPacket implements ServerboundPacket{ public $isInternal; protected function decodePayload() : void{ - $this->command = $this->getString(); - $this->originData = $this->getCommandOriginData(); - $this->isInternal = $this->getBool(); + $this->command = $this->buf->getString(); + $this->originData = $this->buf->getCommandOriginData(); + $this->isInternal = $this->buf->getBool(); } protected function encodePayload() : void{ - $this->putString($this->command); - $this->putCommandOriginData($this->originData); - $this->putBool($this->isInternal); + $this->buf->putString($this->command); + $this->buf->putCommandOriginData($this->originData); + $this->buf->putBool($this->isInternal); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/CompletedUsingItemPacket.php b/src/network/mcpe/protocol/CompletedUsingItemPacket.php index 984c9c14a1..4e7e4724a9 100644 --- a/src/network/mcpe/protocol/CompletedUsingItemPacket.php +++ b/src/network/mcpe/protocol/CompletedUsingItemPacket.php @@ -53,13 +53,13 @@ class CompletedUsingItemPacket extends DataPacket implements ClientboundPacket{ public $action; public function decodePayload() : void{ - $this->itemId = $this->getShort(); - $this->action = $this->getLInt(); + $this->itemId = $this->buf->getShort(); + $this->action = $this->buf->getLInt(); } public function encodePayload() : void{ - $this->putShort($this->itemId); - $this->putLInt($this->action); + $this->buf->putShort($this->itemId); + $this->buf->putLInt($this->action); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ContainerClosePacket.php b/src/network/mcpe/protocol/ContainerClosePacket.php index 1d3ae9c6f0..13a6948625 100644 --- a/src/network/mcpe/protocol/ContainerClosePacket.php +++ b/src/network/mcpe/protocol/ContainerClosePacket.php @@ -40,11 +40,11 @@ class ContainerClosePacket extends DataPacket implements ClientboundPacket, Serv } protected function decodePayload() : void{ - $this->windowId = $this->getByte(); + $this->windowId = $this->buf->getByte(); } protected function encodePayload() : void{ - $this->putByte($this->windowId); + $this->buf->putByte($this->windowId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ContainerOpenPacket.php b/src/network/mcpe/protocol/ContainerOpenPacket.php index 99743b7364..f45eccc064 100644 --- a/src/network/mcpe/protocol/ContainerOpenPacket.php +++ b/src/network/mcpe/protocol/ContainerOpenPacket.php @@ -66,17 +66,17 @@ class ContainerOpenPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->windowId = $this->getByte(); - $this->type = $this->getByte(); - $this->getBlockPosition($this->x, $this->y, $this->z); - $this->entityUniqueId = $this->getEntityUniqueId(); + $this->windowId = $this->buf->getByte(); + $this->type = $this->buf->getByte(); + $this->buf->getBlockPosition($this->x, $this->y, $this->z); + $this->entityUniqueId = $this->buf->getEntityUniqueId(); } protected function encodePayload() : void{ - $this->putByte($this->windowId); - $this->putByte($this->type); - $this->putBlockPosition($this->x, $this->y, $this->z); - $this->putEntityUniqueId($this->entityUniqueId); + $this->buf->putByte($this->windowId); + $this->buf->putByte($this->type); + $this->buf->putBlockPosition($this->x, $this->y, $this->z); + $this->buf->putEntityUniqueId($this->entityUniqueId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ContainerSetDataPacket.php b/src/network/mcpe/protocol/ContainerSetDataPacket.php index d8b3a59342..a67b3f2d3d 100644 --- a/src/network/mcpe/protocol/ContainerSetDataPacket.php +++ b/src/network/mcpe/protocol/ContainerSetDataPacket.php @@ -56,15 +56,15 @@ class ContainerSetDataPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->windowId = $this->getByte(); - $this->property = $this->getVarInt(); - $this->value = $this->getVarInt(); + $this->windowId = $this->buf->getByte(); + $this->property = $this->buf->getVarInt(); + $this->value = $this->buf->getVarInt(); } protected function encodePayload() : void{ - $this->putByte($this->windowId); - $this->putVarInt($this->property); - $this->putVarInt($this->value); + $this->buf->putByte($this->windowId); + $this->buf->putVarInt($this->property); + $this->buf->putVarInt($this->value); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/CraftingDataPacket.php b/src/network/mcpe/protocol/CraftingDataPacket.php index f586b76b39..362f10d28e 100644 --- a/src/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/network/mcpe/protocol/CraftingDataPacket.php @@ -67,60 +67,60 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{ protected function decodePayload() : void{ $this->decodedEntries = []; - $recipeCount = $this->getUnsignedVarInt(); + $recipeCount = $this->buf->getUnsignedVarInt(); for($i = 0; $i < $recipeCount; ++$i){ $entry = []; - $entry["type"] = $recipeType = $this->getVarInt(); + $entry["type"] = $recipeType = $this->buf->getVarInt(); switch($recipeType){ case self::ENTRY_SHAPELESS: case self::ENTRY_SHULKER_BOX: case self::ENTRY_SHAPELESS_CHEMISTRY: - $entry["recipe_id"] = $this->getString(); - $ingredientCount = $this->getUnsignedVarInt(); + $entry["recipe_id"] = $this->buf->getString(); + $ingredientCount = $this->buf->getUnsignedVarInt(); /** @var Item */ $entry["input"] = []; for($j = 0; $j < $ingredientCount; ++$j){ - $entry["input"][] = $in = $this->getRecipeIngredient(); + $entry["input"][] = $in = $this->buf->getRecipeIngredient(); $in->setCount(1); //TODO HACK: they send a useless count field which breaks the PM crafting system because it isn't always 1 } - $resultCount = $this->getUnsignedVarInt(); + $resultCount = $this->buf->getUnsignedVarInt(); $entry["output"] = []; for($k = 0; $k < $resultCount; ++$k){ - $entry["output"][] = $this->getSlot(); + $entry["output"][] = $this->buf->getSlot(); } - $entry["uuid"] = $this->getUUID()->toString(); - $entry["block"] = $this->getString(); - $entry["priority"] = $this->getVarInt(); + $entry["uuid"] = $this->buf->getUUID()->toString(); + $entry["block"] = $this->buf->getString(); + $entry["priority"] = $this->buf->getVarInt(); break; case self::ENTRY_SHAPED: case self::ENTRY_SHAPED_CHEMISTRY: - $entry["recipe_id"] = $this->getString(); - $entry["width"] = $this->getVarInt(); - $entry["height"] = $this->getVarInt(); + $entry["recipe_id"] = $this->buf->getString(); + $entry["width"] = $this->buf->getVarInt(); + $entry["height"] = $this->buf->getVarInt(); $count = $entry["width"] * $entry["height"]; $entry["input"] = []; for($j = 0; $j < $count; ++$j){ - $entry["input"][] = $in = $this->getRecipeIngredient(); + $entry["input"][] = $in = $this->buf->getRecipeIngredient(); $in->setCount(1); //TODO HACK: they send a useless count field which breaks the PM crafting system } - $resultCount = $this->getUnsignedVarInt(); + $resultCount = $this->buf->getUnsignedVarInt(); $entry["output"] = []; for($k = 0; $k < $resultCount; ++$k){ - $entry["output"][] = $this->getSlot(); + $entry["output"][] = $this->buf->getSlot(); } - $entry["uuid"] = $this->getUUID()->toString(); - $entry["block"] = $this->getString(); - $entry["priority"] = $this->getVarInt(); + $entry["uuid"] = $this->buf->getUUID()->toString(); + $entry["block"] = $this->buf->getString(); + $entry["priority"] = $this->buf->getVarInt(); break; case self::ENTRY_FURNACE: case self::ENTRY_FURNACE_DATA: - $inputId = $this->getVarInt(); + $inputId = $this->buf->getVarInt(); $inputData = -1; if($recipeType === self::ENTRY_FURNACE_DATA){ - $inputData = $this->getVarInt(); + $inputData = $this->buf->getVarInt(); if($inputData === 0x7fff){ $inputData = -1; } @@ -130,34 +130,34 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{ }catch(\InvalidArgumentException $e){ throw new BadPacketException($e->getMessage(), 0, $e); } - $entry["output"] = $out = $this->getSlot(); + $entry["output"] = $out = $this->buf->getSlot(); if($out->getMeta() === 0x7fff){ $entry["output"] = ItemFactory::get($out->getId(), 0); //TODO HACK: some 1.12 furnace recipe outputs have wildcard damage values } - $entry["block"] = $this->getString(); + $entry["block"] = $this->buf->getString(); break; case self::ENTRY_MULTI: - $entry["uuid"] = $this->getUUID()->toString(); + $entry["uuid"] = $this->buf->getUUID()->toString(); break; default: throw new BadPacketException("Unhandled recipe type $recipeType!"); //do not continue attempting to decode } $this->decodedEntries[] = $entry; } - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ - $input = $this->getVarInt(); - $ingredient = $this->getVarInt(); - $output = $this->getVarInt(); + for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ + $input = $this->buf->getVarInt(); + $ingredient = $this->buf->getVarInt(); + $output = $this->buf->getVarInt(); $this->potionTypeRecipes[] = new PotionTypeRecipe($input, $ingredient, $output); } - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ - $input = $this->getVarInt(); - $ingredient = $this->getVarInt(); - $output = $this->getVarInt(); + for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ + $input = $this->buf->getVarInt(); + $ingredient = $this->buf->getVarInt(); + $output = $this->buf->getVarInt(); $this->potionContainerRecipes[] = new PotionContainerChangeRecipe($input, $ingredient, $output); } - $this->cleanRecipes = $this->getBool(); + $this->cleanRecipes = $this->buf->getBool(); } /** @@ -245,35 +245,35 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{ } protected function encodePayload() : void{ - $this->putUnsignedVarInt(count($this->entries)); + $this->buf->putUnsignedVarInt(count($this->entries)); $writer = new NetworkBinaryStream(); $counter = 0; foreach($this->entries as $d){ $entryType = self::writeEntry($d, $writer, $counter++); if($entryType >= 0){ - $this->putVarInt($entryType); - $this->put($writer->getBuffer()); + $this->buf->putVarInt($entryType); + $this->buf->put($writer->getBuffer()); }else{ - $this->putVarInt(-1); + $this->buf->putVarInt(-1); } $writer->reset(); } - $this->putUnsignedVarInt(count($this->potionTypeRecipes)); + $this->buf->putUnsignedVarInt(count($this->potionTypeRecipes)); foreach($this->potionTypeRecipes as $recipe){ - $this->putVarInt($recipe->getInputPotionType()); - $this->putVarInt($recipe->getIngredientItemId()); - $this->putVarInt($recipe->getOutputPotionType()); + $this->buf->putVarInt($recipe->getInputPotionType()); + $this->buf->putVarInt($recipe->getIngredientItemId()); + $this->buf->putVarInt($recipe->getOutputPotionType()); } - $this->putUnsignedVarInt(count($this->potionContainerRecipes)); + $this->buf->putUnsignedVarInt(count($this->potionContainerRecipes)); foreach($this->potionContainerRecipes as $recipe){ - $this->putVarInt($recipe->getInputItemId()); - $this->putVarInt($recipe->getIngredientItemId()); - $this->putVarInt($recipe->getOutputItemId()); + $this->buf->putVarInt($recipe->getInputItemId()); + $this->buf->putVarInt($recipe->getIngredientItemId()); + $this->buf->putVarInt($recipe->getOutputItemId()); } - $this->putBool($this->cleanRecipes); + $this->buf->putBool($this->cleanRecipes); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/CraftingEventPacket.php b/src/network/mcpe/protocol/CraftingEventPacket.php index 53371d75ed..e932aa08a2 100644 --- a/src/network/mcpe/protocol/CraftingEventPacket.php +++ b/src/network/mcpe/protocol/CraftingEventPacket.php @@ -45,34 +45,34 @@ class CraftingEventPacket extends DataPacket implements ServerboundPacket{ public $output = []; protected function decodePayload() : void{ - $this->windowId = $this->getByte(); - $this->type = $this->getVarInt(); - $this->id = $this->getUUID(); + $this->windowId = $this->buf->getByte(); + $this->type = $this->buf->getVarInt(); + $this->id = $this->buf->getUUID(); - $size = $this->getUnsignedVarInt(); + $size = $this->buf->getUnsignedVarInt(); for($i = 0; $i < $size and $i < 128; ++$i){ - $this->input[] = $this->getSlot(); + $this->input[] = $this->buf->getSlot(); } - $size = $this->getUnsignedVarInt(); + $size = $this->buf->getUnsignedVarInt(); for($i = 0; $i < $size and $i < 128; ++$i){ - $this->output[] = $this->getSlot(); + $this->output[] = $this->buf->getSlot(); } } protected function encodePayload() : void{ - $this->putByte($this->windowId); - $this->putVarInt($this->type); - $this->putUUID($this->id); + $this->buf->putByte($this->windowId); + $this->buf->putVarInt($this->type); + $this->buf->putUUID($this->id); - $this->putUnsignedVarInt(count($this->input)); + $this->buf->putUnsignedVarInt(count($this->input)); foreach($this->input as $item){ - $this->putSlot($item); + $this->buf->putSlot($item); } - $this->putUnsignedVarInt(count($this->output)); + $this->buf->putUnsignedVarInt(count($this->output)); foreach($this->output as $item){ - $this->putSlot($item); + $this->buf->putSlot($item); } } diff --git a/src/network/mcpe/protocol/DataPacket.php b/src/network/mcpe/protocol/DataPacket.php index 53fd9bd716..390e141c97 100644 --- a/src/network/mcpe/protocol/DataPacket.php +++ b/src/network/mcpe/protocol/DataPacket.php @@ -35,7 +35,7 @@ use function is_object; use function is_string; use function method_exists; -abstract class DataPacket extends NetworkBinaryStream implements Packet{ +abstract class DataPacket implements Packet{ public const NETWORK_ID = 0; @@ -43,6 +43,17 @@ abstract class DataPacket extends NetworkBinaryStream implements Packet{ public $senderSubId = 0; /** @var int */ public $recipientSubId = 0; + + /** @var NetworkBinaryStream */ + protected $buf; + + public function __construct(){ + $this->buf = new NetworkBinaryStream(); + } + + public function getBinaryStream() : NetworkBinaryStream{ + return $this->buf; + } public function pid() : int{ return $this::NETWORK_ID; @@ -60,7 +71,7 @@ abstract class DataPacket extends NetworkBinaryStream implements Packet{ * @throws BadPacketException */ final public function decode() : void{ - $this->rewind(); + $this->buf->rewind(); try{ $this->decodeHeader(); $this->decodePayload(); @@ -74,7 +85,7 @@ abstract class DataPacket extends NetworkBinaryStream implements Packet{ * @throws \UnexpectedValueException */ protected function decodeHeader() : void{ - $pid = $this->getUnsignedVarInt(); + $pid = $this->buf->getUnsignedVarInt(); if($pid !== static::NETWORK_ID){ //TODO: this means a logical error in the code, but how to prevent it from happening? throw new \UnexpectedValueException("Expected " . static::NETWORK_ID . " for packet ID, got $pid"); @@ -90,13 +101,13 @@ abstract class DataPacket extends NetworkBinaryStream implements Packet{ abstract protected function decodePayload() : void; final public function encode() : void{ - $this->reset(); + $this->buf->reset(); $this->encodeHeader(); $this->encodePayload(); } protected function encodeHeader() : void{ - $this->putUnsignedVarInt(static::NETWORK_ID); + $this->buf->putUnsignedVarInt(static::NETWORK_ID); } /** @@ -104,24 +115,6 @@ abstract class DataPacket extends NetworkBinaryStream implements Packet{ */ abstract protected function encodePayload() : void; - /** - * @return mixed[] - */ - public function __debugInfo() : array{ - $data = []; - foreach((array) $this as $k => $v){ - if($v === $this->getBuffer()){ - $data[$k] = bin2hex($v); - }elseif(is_string($v) or (is_object($v) and method_exists($v, "__toString"))){ - $data[$k] = Utils::printable((string) $v); - }else{ - $data[$k] = $v; - } - } - - return $data; - } - /** * @param string $name * diff --git a/src/network/mcpe/protocol/DisconnectPacket.php b/src/network/mcpe/protocol/DisconnectPacket.php index 3c665d3447..25f84743fc 100644 --- a/src/network/mcpe/protocol/DisconnectPacket.php +++ b/src/network/mcpe/protocol/DisconnectPacket.php @@ -53,16 +53,16 @@ class DisconnectPacket extends DataPacket implements ClientboundPacket, Serverbo } protected function decodePayload() : void{ - $this->hideDisconnectionScreen = $this->getBool(); + $this->hideDisconnectionScreen = $this->buf->getBool(); if(!$this->hideDisconnectionScreen){ - $this->message = $this->getString(); + $this->message = $this->buf->getString(); } } protected function encodePayload() : void{ - $this->putBool($this->hideDisconnectionScreen); + $this->buf->putBool($this->hideDisconnectionScreen); if(!$this->hideDisconnectionScreen){ - $this->putString($this->message); + $this->buf->putString($this->message); } } diff --git a/src/network/mcpe/protocol/EducationSettingsPacket.php b/src/network/mcpe/protocol/EducationSettingsPacket.php index 498cf9f0d4..a561b5acb8 100644 --- a/src/network/mcpe/protocol/EducationSettingsPacket.php +++ b/src/network/mcpe/protocol/EducationSettingsPacket.php @@ -51,13 +51,13 @@ class EducationSettingsPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->codeBuilderDefaultUri = $this->getString(); - $this->hasQuiz = $this->getBool(); + $this->codeBuilderDefaultUri = $this->buf->getString(); + $this->hasQuiz = $this->buf->getBool(); } protected function encodePayload() : void{ - $this->putString($this->codeBuilderDefaultUri); - $this->putBool($this->hasQuiz); + $this->buf->putString($this->codeBuilderDefaultUri); + $this->buf->putBool($this->hasQuiz); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/EmotePacket.php b/src/network/mcpe/protocol/EmotePacket.php index 9bf12c3306..23194e6809 100644 --- a/src/network/mcpe/protocol/EmotePacket.php +++ b/src/network/mcpe/protocol/EmotePacket.php @@ -63,15 +63,15 @@ class EmotePacket extends DataPacket implements ClientboundPacket, ServerboundPa } protected function decodePayload() : void{ - $this->entityRuntimeId = $this->getEntityRuntimeId(); - $this->emoteId = $this->getString(); - $this->flags = $this->getByte(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + $this->emoteId = $this->buf->getString(); + $this->flags = $this->buf->getByte(); } protected function encodePayload() : void{ - $this->putEntityRuntimeId($this->entityRuntimeId); - $this->putString($this->emoteId); - $this->putByte($this->flags); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putString($this->emoteId); + $this->buf->putByte($this->flags); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/EventPacket.php b/src/network/mcpe/protocol/EventPacket.php index d44edecd2f..6dffeb7b4d 100644 --- a/src/network/mcpe/protocol/EventPacket.php +++ b/src/network/mcpe/protocol/EventPacket.php @@ -57,17 +57,17 @@ class EventPacket extends DataPacket implements ClientboundPacket{ public $type; protected function decodePayload() : void{ - $this->playerRuntimeId = $this->getEntityRuntimeId(); - $this->eventData = $this->getVarInt(); - $this->type = $this->getByte(); + $this->playerRuntimeId = $this->buf->getEntityRuntimeId(); + $this->eventData = $this->buf->getVarInt(); + $this->type = $this->buf->getByte(); //TODO: nice confusing mess } protected function encodePayload() : void{ - $this->putEntityRuntimeId($this->playerRuntimeId); - $this->putVarInt($this->eventData); - $this->putByte($this->type); + $this->buf->putEntityRuntimeId($this->playerRuntimeId); + $this->buf->putVarInt($this->eventData); + $this->buf->putByte($this->type); //TODO: also nice confusing mess } diff --git a/src/network/mcpe/protocol/GameRulesChangedPacket.php b/src/network/mcpe/protocol/GameRulesChangedPacket.php index 76895424df..7acbe1abcb 100644 --- a/src/network/mcpe/protocol/GameRulesChangedPacket.php +++ b/src/network/mcpe/protocol/GameRulesChangedPacket.php @@ -37,11 +37,11 @@ class GameRulesChangedPacket extends DataPacket implements ClientboundPacket{ public $gameRules = []; protected function decodePayload() : void{ - $this->gameRules = $this->getGameRules(); + $this->gameRules = $this->buf->getGameRules(); } protected function encodePayload() : void{ - $this->putGameRules($this->gameRules); + $this->buf->putGameRules($this->gameRules); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/GuiDataPickItemPacket.php b/src/network/mcpe/protocol/GuiDataPickItemPacket.php index cdba42aaef..f898dc6b1c 100644 --- a/src/network/mcpe/protocol/GuiDataPickItemPacket.php +++ b/src/network/mcpe/protocol/GuiDataPickItemPacket.php @@ -38,15 +38,15 @@ class GuiDataPickItemPacket extends DataPacket implements ClientboundPacket{ public $hotbarSlot; protected function decodePayload() : void{ - $this->itemDescription = $this->getString(); - $this->itemEffects = $this->getString(); - $this->hotbarSlot = $this->getLInt(); + $this->itemDescription = $this->buf->getString(); + $this->itemEffects = $this->buf->getString(); + $this->hotbarSlot = $this->buf->getLInt(); } protected function encodePayload() : void{ - $this->putString($this->itemDescription); - $this->putString($this->itemEffects); - $this->putLInt($this->hotbarSlot); + $this->buf->putString($this->itemDescription); + $this->buf->putString($this->itemEffects); + $this->buf->putLInt($this->hotbarSlot); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/HurtArmorPacket.php b/src/network/mcpe/protocol/HurtArmorPacket.php index b9e236c4f7..7ad5174a28 100644 --- a/src/network/mcpe/protocol/HurtArmorPacket.php +++ b/src/network/mcpe/protocol/HurtArmorPacket.php @@ -34,11 +34,11 @@ class HurtArmorPacket extends DataPacket implements ClientboundPacket{ public $health; protected function decodePayload() : void{ - $this->health = $this->getVarInt(); + $this->health = $this->buf->getVarInt(); } protected function encodePayload() : void{ - $this->putVarInt($this->health); + $this->buf->putVarInt($this->health); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/InteractPacket.php b/src/network/mcpe/protocol/InteractPacket.php index 03773799f0..715b248092 100644 --- a/src/network/mcpe/protocol/InteractPacket.php +++ b/src/network/mcpe/protocol/InteractPacket.php @@ -48,25 +48,25 @@ class InteractPacket extends DataPacket implements ServerboundPacket{ public $z; protected function decodePayload() : void{ - $this->action = $this->getByte(); - $this->target = $this->getEntityRuntimeId(); + $this->action = $this->buf->getByte(); + $this->target = $this->buf->getEntityRuntimeId(); if($this->action === self::ACTION_MOUSEOVER){ //TODO: should this be a vector3? - $this->x = $this->getLFloat(); - $this->y = $this->getLFloat(); - $this->z = $this->getLFloat(); + $this->x = $this->buf->getLFloat(); + $this->y = $this->buf->getLFloat(); + $this->z = $this->buf->getLFloat(); } } protected function encodePayload() : void{ - $this->putByte($this->action); - $this->putEntityRuntimeId($this->target); + $this->buf->putByte($this->action); + $this->buf->putEntityRuntimeId($this->target); if($this->action === self::ACTION_MOUSEOVER){ - $this->putLFloat($this->x); - $this->putLFloat($this->y); - $this->putLFloat($this->z); + $this->buf->putLFloat($this->x); + $this->buf->putLFloat($this->y); + $this->buf->putLFloat($this->z); } } diff --git a/src/network/mcpe/protocol/InventoryContentPacket.php b/src/network/mcpe/protocol/InventoryContentPacket.php index 2054dc7323..0375a651b5 100644 --- a/src/network/mcpe/protocol/InventoryContentPacket.php +++ b/src/network/mcpe/protocol/InventoryContentPacket.php @@ -50,18 +50,18 @@ class InventoryContentPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->windowId = $this->getUnsignedVarInt(); - $count = $this->getUnsignedVarInt(); + $this->windowId = $this->buf->getUnsignedVarInt(); + $count = $this->buf->getUnsignedVarInt(); for($i = 0; $i < $count; ++$i){ - $this->items[] = $this->getSlot(); + $this->items[] = $this->buf->getSlot(); } } protected function encodePayload() : void{ - $this->putUnsignedVarInt($this->windowId); - $this->putUnsignedVarInt(count($this->items)); + $this->buf->putUnsignedVarInt($this->windowId); + $this->buf->putUnsignedVarInt(count($this->items)); foreach($this->items as $item){ - $this->putSlot($item); + $this->buf->putSlot($item); } } diff --git a/src/network/mcpe/protocol/InventorySlotPacket.php b/src/network/mcpe/protocol/InventorySlotPacket.php index 5fc2f76c97..6c9c526ddc 100644 --- a/src/network/mcpe/protocol/InventorySlotPacket.php +++ b/src/network/mcpe/protocol/InventorySlotPacket.php @@ -47,15 +47,15 @@ class InventorySlotPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->windowId = $this->getUnsignedVarInt(); - $this->inventorySlot = $this->getUnsignedVarInt(); - $this->item = $this->getSlot(); + $this->windowId = $this->buf->getUnsignedVarInt(); + $this->inventorySlot = $this->buf->getUnsignedVarInt(); + $this->item = $this->buf->getSlot(); } protected function encodePayload() : void{ - $this->putUnsignedVarInt($this->windowId); - $this->putUnsignedVarInt($this->inventorySlot); - $this->putSlot($this->item); + $this->buf->putUnsignedVarInt($this->windowId); + $this->buf->putUnsignedVarInt($this->inventorySlot); + $this->buf->putSlot($this->item); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/InventoryTransactionPacket.php b/src/network/mcpe/protocol/InventoryTransactionPacket.php index a4cb59f834..9d34042528 100644 --- a/src/network/mcpe/protocol/InventoryTransactionPacket.php +++ b/src/network/mcpe/protocol/InventoryTransactionPacket.php @@ -50,7 +50,7 @@ class InventoryTransactionPacket extends DataPacket implements ClientboundPacket public $trData; protected function decodePayload() : void{ - $transactionType = $this->getUnsignedVarInt(); + $transactionType = $this->buf->getUnsignedVarInt(); switch($transactionType){ case self::TYPE_NORMAL: @@ -72,12 +72,12 @@ class InventoryTransactionPacket extends DataPacket implements ClientboundPacket throw new BadPacketException("Unknown transaction type $transactionType"); } - $this->trData->decode($this); + $this->trData->decode($this->buf); } protected function encodePayload() : void{ - $this->putUnsignedVarInt($this->trData->getTypeId()); - $this->trData->encode($this); + $this->buf->putUnsignedVarInt($this->trData->getTypeId()); + $this->trData->encode($this->buf); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ItemFrameDropItemPacket.php b/src/network/mcpe/protocol/ItemFrameDropItemPacket.php index c0a16b1eeb..f9bfb9753e 100644 --- a/src/network/mcpe/protocol/ItemFrameDropItemPacket.php +++ b/src/network/mcpe/protocol/ItemFrameDropItemPacket.php @@ -39,11 +39,11 @@ class ItemFrameDropItemPacket extends DataPacket implements ServerboundPacket{ public $z; protected function decodePayload() : void{ - $this->getBlockPosition($this->x, $this->y, $this->z); + $this->buf->getBlockPosition($this->x, $this->y, $this->z); } protected function encodePayload() : void{ - $this->putBlockPosition($this->x, $this->y, $this->z); + $this->buf->putBlockPosition($this->x, $this->y, $this->z); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/LabTablePacket.php b/src/network/mcpe/protocol/LabTablePacket.php index 70e0640cf9..09a5b11310 100644 --- a/src/network/mcpe/protocol/LabTablePacket.php +++ b/src/network/mcpe/protocol/LabTablePacket.php @@ -44,15 +44,15 @@ class LabTablePacket extends DataPacket implements ClientboundPacket, Serverboun public $reactionType; protected function decodePayload() : void{ - $this->uselessByte = $this->getByte(); - $this->getSignedBlockPosition($this->x, $this->y, $this->z); - $this->reactionType = $this->getByte(); + $this->uselessByte = $this->buf->getByte(); + $this->buf->getSignedBlockPosition($this->x, $this->y, $this->z); + $this->reactionType = $this->buf->getByte(); } protected function encodePayload() : void{ - $this->putByte($this->uselessByte); - $this->putSignedBlockPosition($this->x, $this->y, $this->z); - $this->putByte($this->reactionType); + $this->buf->putByte($this->uselessByte); + $this->buf->putSignedBlockPosition($this->x, $this->y, $this->z); + $this->buf->putByte($this->reactionType); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/LecternUpdatePacket.php b/src/network/mcpe/protocol/LecternUpdatePacket.php index a3ddf31d57..c46904d2e2 100644 --- a/src/network/mcpe/protocol/LecternUpdatePacket.php +++ b/src/network/mcpe/protocol/LecternUpdatePacket.php @@ -44,17 +44,17 @@ class LecternUpdatePacket extends DataPacket implements ServerboundPacket{ public $dropBook; protected function decodePayload() : void{ - $this->page = $this->getByte(); - $this->totalPages = $this->getByte(); - $this->getBlockPosition($this->x, $this->y, $this->z); - $this->dropBook = $this->getBool(); + $this->page = $this->buf->getByte(); + $this->totalPages = $this->buf->getByte(); + $this->buf->getBlockPosition($this->x, $this->y, $this->z); + $this->dropBook = $this->buf->getBool(); } protected function encodePayload() : void{ - $this->putByte($this->page); - $this->putByte($this->totalPages); - $this->putBlockPosition($this->x, $this->y, $this->z); - $this->putBool($this->dropBook); + $this->buf->putByte($this->page); + $this->buf->putByte($this->totalPages); + $this->buf->putBlockPosition($this->x, $this->y, $this->z); + $this->buf->putBool($this->dropBook); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/LevelChunkPacket.php b/src/network/mcpe/protocol/LevelChunkPacket.php index 38f578cbcd..f244911987 100644 --- a/src/network/mcpe/protocol/LevelChunkPacket.php +++ b/src/network/mcpe/protocol/LevelChunkPacket.php @@ -101,30 +101,30 @@ class LevelChunkPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->chunkX = $this->getVarInt(); - $this->chunkZ = $this->getVarInt(); - $this->subChunkCount = $this->getUnsignedVarInt(); - $this->cacheEnabled = $this->getBool(); + $this->chunkX = $this->buf->getVarInt(); + $this->chunkZ = $this->buf->getVarInt(); + $this->subChunkCount = $this->buf->getUnsignedVarInt(); + $this->cacheEnabled = $this->buf->getBool(); if($this->cacheEnabled){ - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ - $this->usedBlobHashes[] = $this->getLLong(); + for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ + $this->usedBlobHashes[] = $this->buf->getLLong(); } } - $this->extraPayload = $this->getString(); + $this->extraPayload = $this->buf->getString(); } protected function encodePayload() : void{ - $this->putVarInt($this->chunkX); - $this->putVarInt($this->chunkZ); - $this->putUnsignedVarInt($this->subChunkCount); - $this->putBool($this->cacheEnabled); + $this->buf->putVarInt($this->chunkX); + $this->buf->putVarInt($this->chunkZ); + $this->buf->putUnsignedVarInt($this->subChunkCount); + $this->buf->putBool($this->cacheEnabled); if($this->cacheEnabled){ - $this->putUnsignedVarInt(count($this->usedBlobHashes)); + $this->buf->putUnsignedVarInt(count($this->usedBlobHashes)); foreach($this->usedBlobHashes as $hash){ - $this->putLLong($hash); + $this->buf->putLLong($hash); } } - $this->putString($this->extraPayload); + $this->buf->putString($this->extraPayload); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/LevelEventGenericPacket.php b/src/network/mcpe/protocol/LevelEventGenericPacket.php index 1c6c0eaecd..6ae513b893 100644 --- a/src/network/mcpe/protocol/LevelEventGenericPacket.php +++ b/src/network/mcpe/protocol/LevelEventGenericPacket.php @@ -54,13 +54,13 @@ class LevelEventGenericPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->eventId = $this->getVarInt(); - $this->eventData = $this->getRemaining(); + $this->eventId = $this->buf->getVarInt(); + $this->eventData = $this->buf->getRemaining(); } protected function encodePayload() : void{ - $this->putVarInt($this->eventId); - $this->put($this->eventData); + $this->buf->putVarInt($this->eventId); + $this->buf->put($this->eventData); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/LevelEventPacket.php b/src/network/mcpe/protocol/LevelEventPacket.php index 99a3231d30..3c1d8e8a54 100644 --- a/src/network/mcpe/protocol/LevelEventPacket.php +++ b/src/network/mcpe/protocol/LevelEventPacket.php @@ -134,15 +134,15 @@ class LevelEventPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->evid = $this->getVarInt(); - $this->position = $this->getVector3(); - $this->data = $this->getVarInt(); + $this->evid = $this->buf->getVarInt(); + $this->position = $this->buf->getVector3(); + $this->data = $this->buf->getVarInt(); } protected function encodePayload() : void{ - $this->putVarInt($this->evid); - $this->putVector3Nullable($this->position); - $this->putVarInt($this->data); + $this->buf->putVarInt($this->evid); + $this->buf->putVector3Nullable($this->position); + $this->buf->putVarInt($this->data); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/LevelSoundEventPacket.php b/src/network/mcpe/protocol/LevelSoundEventPacket.php index 503622c02f..86d2631d8a 100644 --- a/src/network/mcpe/protocol/LevelSoundEventPacket.php +++ b/src/network/mcpe/protocol/LevelSoundEventPacket.php @@ -336,21 +336,21 @@ class LevelSoundEventPacket extends DataPacket implements ClientboundPacket, Ser public $disableRelativeVolume = false; protected function decodePayload() : void{ - $this->sound = $this->getUnsignedVarInt(); - $this->position = $this->getVector3(); - $this->extraData = $this->getVarInt(); - $this->entityType = $this->getString(); - $this->isBabyMob = $this->getBool(); - $this->disableRelativeVolume = $this->getBool(); + $this->sound = $this->buf->getUnsignedVarInt(); + $this->position = $this->buf->getVector3(); + $this->extraData = $this->buf->getVarInt(); + $this->entityType = $this->buf->getString(); + $this->isBabyMob = $this->buf->getBool(); + $this->disableRelativeVolume = $this->buf->getBool(); } protected function encodePayload() : void{ - $this->putUnsignedVarInt($this->sound); - $this->putVector3($this->position); - $this->putVarInt($this->extraData); - $this->putString($this->entityType); - $this->putBool($this->isBabyMob); - $this->putBool($this->disableRelativeVolume); + $this->buf->putUnsignedVarInt($this->sound); + $this->buf->putVector3($this->position); + $this->buf->putVarInt($this->extraData); + $this->buf->putString($this->entityType); + $this->buf->putBool($this->isBabyMob); + $this->buf->putBool($this->disableRelativeVolume); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/LevelSoundEventPacketV1.php b/src/network/mcpe/protocol/LevelSoundEventPacketV1.php index ae45de3e4b..cb20f6042b 100644 --- a/src/network/mcpe/protocol/LevelSoundEventPacketV1.php +++ b/src/network/mcpe/protocol/LevelSoundEventPacketV1.php @@ -48,21 +48,21 @@ class LevelSoundEventPacketV1 extends DataPacket{ public $disableRelativeVolume = false; protected function decodePayload() : void{ - $this->sound = $this->getByte(); - $this->position = $this->getVector3(); - $this->extraData = $this->getVarInt(); - $this->entityType = $this->getVarInt(); - $this->isBabyMob = $this->getBool(); - $this->disableRelativeVolume = $this->getBool(); + $this->sound = $this->buf->getByte(); + $this->position = $this->buf->getVector3(); + $this->extraData = $this->buf->getVarInt(); + $this->entityType = $this->buf->getVarInt(); + $this->isBabyMob = $this->buf->getBool(); + $this->disableRelativeVolume = $this->buf->getBool(); } protected function encodePayload() : void{ - $this->putByte($this->sound); - $this->putVector3($this->position); - $this->putVarInt($this->extraData); - $this->putVarInt($this->entityType); - $this->putBool($this->isBabyMob); - $this->putBool($this->disableRelativeVolume); + $this->buf->putByte($this->sound); + $this->buf->putVector3($this->position); + $this->buf->putVarInt($this->extraData); + $this->buf->putVarInt($this->entityType); + $this->buf->putBool($this->isBabyMob); + $this->buf->putBool($this->disableRelativeVolume); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/LevelSoundEventPacketV2.php b/src/network/mcpe/protocol/LevelSoundEventPacketV2.php index d540c4111f..753f6c9bad 100644 --- a/src/network/mcpe/protocol/LevelSoundEventPacketV2.php +++ b/src/network/mcpe/protocol/LevelSoundEventPacketV2.php @@ -48,21 +48,21 @@ class LevelSoundEventPacketV2 extends DataPacket{ public $disableRelativeVolume = false; protected function decodePayload() : void{ - $this->sound = $this->getByte(); - $this->position = $this->getVector3(); - $this->extraData = $this->getVarInt(); - $this->entityType = $this->getString(); - $this->isBabyMob = $this->getBool(); - $this->disableRelativeVolume = $this->getBool(); + $this->sound = $this->buf->getByte(); + $this->position = $this->buf->getVector3(); + $this->extraData = $this->buf->getVarInt(); + $this->entityType = $this->buf->getString(); + $this->isBabyMob = $this->buf->getBool(); + $this->disableRelativeVolume = $this->buf->getBool(); } protected function encodePayload() : void{ - $this->putByte($this->sound); - $this->putVector3($this->position); - $this->putVarInt($this->extraData); - $this->putString($this->entityType); - $this->putBool($this->isBabyMob); - $this->putBool($this->disableRelativeVolume); + $this->buf->putByte($this->sound); + $this->buf->putVector3($this->position); + $this->buf->putVarInt($this->extraData); + $this->buf->putString($this->entityType); + $this->buf->putBool($this->isBabyMob); + $this->buf->putBool($this->disableRelativeVolume); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/LoginPacket.php b/src/network/mcpe/protocol/LoginPacket.php index 92e7a2cd55..4206694ebd 100644 --- a/src/network/mcpe/protocol/LoginPacket.php +++ b/src/network/mcpe/protocol/LoginPacket.php @@ -109,7 +109,7 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ } protected function decodePayload() : void{ - $this->protocol = $this->getInt(); + $this->protocol = $this->buf->getInt(); $this->decodeConnectionRequest(); } @@ -134,7 +134,7 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ * @throws BinaryDataException */ protected function decodeConnectionRequest() : void{ - $buffer = new BinaryStream($this->getString()); + $buffer = new BinaryStream($this->buf->getString()); $chainData = json_decode($buffer->get($buffer->getLInt()), true); if(!is_array($chainData)){ diff --git a/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php b/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php index 92b8e9d461..3405c7b3b7 100644 --- a/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php +++ b/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php @@ -36,13 +36,13 @@ class MapCreateLockedCopyPacket extends DataPacket implements ServerboundPacket{ public $newMapId; protected function decodePayload() : void{ - $this->originalMapId = $this->getEntityUniqueId(); - $this->newMapId = $this->getEntityUniqueId(); + $this->originalMapId = $this->buf->getEntityUniqueId(); + $this->newMapId = $this->buf->getEntityUniqueId(); } protected function encodePayload() : void{ - $this->putEntityUniqueId($this->originalMapId); - $this->putEntityUniqueId($this->newMapId); + $this->buf->putEntityUniqueId($this->originalMapId); + $this->buf->putEntityUniqueId($this->newMapId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/MapInfoRequestPacket.php b/src/network/mcpe/protocol/MapInfoRequestPacket.php index 08248acf42..6aa6c21551 100644 --- a/src/network/mcpe/protocol/MapInfoRequestPacket.php +++ b/src/network/mcpe/protocol/MapInfoRequestPacket.php @@ -34,11 +34,11 @@ class MapInfoRequestPacket extends DataPacket implements ServerboundPacket{ public $mapId; protected function decodePayload() : void{ - $this->mapId = $this->getEntityUniqueId(); + $this->mapId = $this->buf->getEntityUniqueId(); } protected function encodePayload() : void{ - $this->putEntityUniqueId($this->mapId); + $this->buf->putEntityUniqueId($this->mapId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/MobArmorEquipmentPacket.php b/src/network/mcpe/protocol/MobArmorEquipmentPacket.php index 22b1556e82..d6cffa39b9 100644 --- a/src/network/mcpe/protocol/MobArmorEquipmentPacket.php +++ b/src/network/mcpe/protocol/MobArmorEquipmentPacket.php @@ -56,19 +56,19 @@ class MobArmorEquipmentPacket extends DataPacket implements ClientboundPacket, S } protected function decodePayload() : void{ - $this->entityRuntimeId = $this->getEntityRuntimeId(); - $this->head = $this->getSlot(); - $this->chest = $this->getSlot(); - $this->legs = $this->getSlot(); - $this->feet = $this->getSlot(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + $this->head = $this->buf->getSlot(); + $this->chest = $this->buf->getSlot(); + $this->legs = $this->buf->getSlot(); + $this->feet = $this->buf->getSlot(); } protected function encodePayload() : void{ - $this->putEntityRuntimeId($this->entityRuntimeId); - $this->putSlot($this->head); - $this->putSlot($this->chest); - $this->putSlot($this->legs); - $this->putSlot($this->feet); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putSlot($this->head); + $this->buf->putSlot($this->chest); + $this->buf->putSlot($this->legs); + $this->buf->putSlot($this->feet); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/MobEffectPacket.php b/src/network/mcpe/protocol/MobEffectPacket.php index 03912a5fc6..14d29fd77a 100644 --- a/src/network/mcpe/protocol/MobEffectPacket.php +++ b/src/network/mcpe/protocol/MobEffectPacket.php @@ -67,21 +67,21 @@ class MobEffectPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->entityRuntimeId = $this->getEntityRuntimeId(); - $this->eventId = $this->getByte(); - $this->effectId = $this->getVarInt(); - $this->amplifier = $this->getVarInt(); - $this->particles = $this->getBool(); - $this->duration = $this->getVarInt(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + $this->eventId = $this->buf->getByte(); + $this->effectId = $this->buf->getVarInt(); + $this->amplifier = $this->buf->getVarInt(); + $this->particles = $this->buf->getBool(); + $this->duration = $this->buf->getVarInt(); } protected function encodePayload() : void{ - $this->putEntityRuntimeId($this->entityRuntimeId); - $this->putByte($this->eventId); - $this->putVarInt($this->effectId); - $this->putVarInt($this->amplifier); - $this->putBool($this->particles); - $this->putVarInt($this->duration); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putByte($this->eventId); + $this->buf->putVarInt($this->effectId); + $this->buf->putVarInt($this->amplifier); + $this->buf->putBool($this->particles); + $this->buf->putVarInt($this->duration); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/MobEquipmentPacket.php b/src/network/mcpe/protocol/MobEquipmentPacket.php index 8b5486218d..0393df687b 100644 --- a/src/network/mcpe/protocol/MobEquipmentPacket.php +++ b/src/network/mcpe/protocol/MobEquipmentPacket.php @@ -53,19 +53,19 @@ class MobEquipmentPacket extends DataPacket implements ClientboundPacket, Server } protected function decodePayload() : void{ - $this->entityRuntimeId = $this->getEntityRuntimeId(); - $this->item = $this->getSlot(); - $this->inventorySlot = $this->getByte(); - $this->hotbarSlot = $this->getByte(); - $this->windowId = $this->getByte(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + $this->item = $this->buf->getSlot(); + $this->inventorySlot = $this->buf->getByte(); + $this->hotbarSlot = $this->buf->getByte(); + $this->windowId = $this->buf->getByte(); } protected function encodePayload() : void{ - $this->putEntityRuntimeId($this->entityRuntimeId); - $this->putSlot($this->item); - $this->putByte($this->inventorySlot); - $this->putByte($this->hotbarSlot); - $this->putByte($this->windowId); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putSlot($this->item); + $this->buf->putByte($this->inventorySlot); + $this->buf->putByte($this->hotbarSlot); + $this->buf->putByte($this->windowId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ModalFormRequestPacket.php b/src/network/mcpe/protocol/ModalFormRequestPacket.php index b60fb8cdf7..9f17b74509 100644 --- a/src/network/mcpe/protocol/ModalFormRequestPacket.php +++ b/src/network/mcpe/protocol/ModalFormRequestPacket.php @@ -43,13 +43,13 @@ class ModalFormRequestPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->formId = $this->getUnsignedVarInt(); - $this->formData = $this->getString(); + $this->formId = $this->buf->getUnsignedVarInt(); + $this->formData = $this->buf->getString(); } protected function encodePayload() : void{ - $this->putUnsignedVarInt($this->formId); - $this->putString($this->formData); + $this->buf->putUnsignedVarInt($this->formId); + $this->buf->putString($this->formData); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ModalFormResponsePacket.php b/src/network/mcpe/protocol/ModalFormResponsePacket.php index f97a7c0c33..06af847fed 100644 --- a/src/network/mcpe/protocol/ModalFormResponsePacket.php +++ b/src/network/mcpe/protocol/ModalFormResponsePacket.php @@ -36,13 +36,13 @@ class ModalFormResponsePacket extends DataPacket implements ServerboundPacket{ public $formData; //json protected function decodePayload() : void{ - $this->formId = $this->getUnsignedVarInt(); - $this->formData = $this->getString(); + $this->formId = $this->buf->getUnsignedVarInt(); + $this->formData = $this->buf->getString(); } protected function encodePayload() : void{ - $this->putUnsignedVarInt($this->formId); - $this->putString($this->formData); + $this->buf->putUnsignedVarInt($this->formId); + $this->buf->putString($this->formData); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/MoveActorAbsolutePacket.php b/src/network/mcpe/protocol/MoveActorAbsolutePacket.php index 04116f46f8..566ba2b9dd 100644 --- a/src/network/mcpe/protocol/MoveActorAbsolutePacket.php +++ b/src/network/mcpe/protocol/MoveActorAbsolutePacket.php @@ -48,21 +48,21 @@ class MoveActorAbsolutePacket extends DataPacket implements ClientboundPacket, S public $zRot; protected function decodePayload() : void{ - $this->entityRuntimeId = $this->getEntityRuntimeId(); - $this->flags = $this->getByte(); - $this->position = $this->getVector3(); - $this->xRot = $this->getByteRotation(); - $this->yRot = $this->getByteRotation(); - $this->zRot = $this->getByteRotation(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + $this->flags = $this->buf->getByte(); + $this->position = $this->buf->getVector3(); + $this->xRot = $this->buf->getByteRotation(); + $this->yRot = $this->buf->getByteRotation(); + $this->zRot = $this->buf->getByteRotation(); } protected function encodePayload() : void{ - $this->putEntityRuntimeId($this->entityRuntimeId); - $this->putByte($this->flags); - $this->putVector3($this->position); - $this->putByteRotation($this->xRot); - $this->putByteRotation($this->yRot); - $this->putByteRotation($this->zRot); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putByte($this->flags); + $this->buf->putVector3($this->position); + $this->buf->putByteRotation($this->xRot); + $this->buf->putByteRotation($this->yRot); + $this->buf->putByteRotation($this->zRot); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/MoveActorDeltaPacket.php b/src/network/mcpe/protocol/MoveActorDeltaPacket.php index c030415470..d252baf8e7 100644 --- a/src/network/mcpe/protocol/MoveActorDeltaPacket.php +++ b/src/network/mcpe/protocol/MoveActorDeltaPacket.php @@ -60,7 +60,7 @@ class MoveActorDeltaPacket extends DataPacket implements ClientboundPacket{ */ private function maybeReadCoord(int $flag) : int{ if(($this->flags & $flag) !== 0){ - return $this->getVarInt(); + return $this->buf->getVarInt(); } return 0; } @@ -70,14 +70,14 @@ class MoveActorDeltaPacket extends DataPacket implements ClientboundPacket{ */ private function maybeReadRotation(int $flag) : float{ if(($this->flags & $flag) !== 0){ - return $this->getByteRotation(); + return $this->buf->getByteRotation(); } return 0.0; } protected function decodePayload() : void{ - $this->entityRuntimeId = $this->getEntityRuntimeId(); - $this->flags = $this->getLShort(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + $this->flags = $this->buf->getLShort(); $this->xDiff = $this->maybeReadCoord(self::FLAG_HAS_X); $this->yDiff = $this->maybeReadCoord(self::FLAG_HAS_Y); $this->zDiff = $this->maybeReadCoord(self::FLAG_HAS_Z); @@ -88,19 +88,19 @@ class MoveActorDeltaPacket extends DataPacket implements ClientboundPacket{ private function maybeWriteCoord(int $flag, int $val) : void{ if(($this->flags & $flag) !== 0){ - $this->putVarInt($val); + $this->buf->putVarInt($val); } } private function maybeWriteRotation(int $flag, float $val) : void{ if(($this->flags & $flag) !== 0){ - $this->putByteRotation($val); + $this->buf->putByteRotation($val); } } protected function encodePayload() : void{ - $this->putEntityRuntimeId($this->entityRuntimeId); - $this->putLShort($this->flags); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putLShort($this->flags); $this->maybeWriteCoord(self::FLAG_HAS_X, $this->xDiff); $this->maybeWriteCoord(self::FLAG_HAS_Y, $this->yDiff); $this->maybeWriteCoord(self::FLAG_HAS_Z, $this->zDiff); diff --git a/src/network/mcpe/protocol/MovePlayerPacket.php b/src/network/mcpe/protocol/MovePlayerPacket.php index 98786299e1..3c42186a26 100644 --- a/src/network/mcpe/protocol/MovePlayerPacket.php +++ b/src/network/mcpe/protocol/MovePlayerPacket.php @@ -58,32 +58,32 @@ class MovePlayerPacket extends DataPacket implements ClientboundPacket, Serverbo public $teleportItem = 0; protected function decodePayload() : void{ - $this->entityRuntimeId = $this->getEntityRuntimeId(); - $this->position = $this->getVector3(); - $this->pitch = $this->getLFloat(); - $this->yaw = $this->getLFloat(); - $this->headYaw = $this->getLFloat(); - $this->mode = $this->getByte(); - $this->onGround = $this->getBool(); - $this->ridingEid = $this->getEntityRuntimeId(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + $this->position = $this->buf->getVector3(); + $this->pitch = $this->buf->getLFloat(); + $this->yaw = $this->buf->getLFloat(); + $this->headYaw = $this->buf->getLFloat(); + $this->mode = $this->buf->getByte(); + $this->onGround = $this->buf->getBool(); + $this->ridingEid = $this->buf->getEntityRuntimeId(); if($this->mode === MovePlayerPacket::MODE_TELEPORT){ - $this->teleportCause = $this->getLInt(); - $this->teleportItem = $this->getLInt(); + $this->teleportCause = $this->buf->getLInt(); + $this->teleportItem = $this->buf->getLInt(); } } protected function encodePayload() : void{ - $this->putEntityRuntimeId($this->entityRuntimeId); - $this->putVector3($this->position); - $this->putLFloat($this->pitch); - $this->putLFloat($this->yaw); - $this->putLFloat($this->headYaw); //TODO - $this->putByte($this->mode); - $this->putBool($this->onGround); - $this->putEntityRuntimeId($this->ridingEid); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putVector3($this->position); + $this->buf->putLFloat($this->pitch); + $this->buf->putLFloat($this->yaw); + $this->buf->putLFloat($this->headYaw); //TODO + $this->buf->putByte($this->mode); + $this->buf->putBool($this->onGround); + $this->buf->putEntityRuntimeId($this->ridingEid); if($this->mode === MovePlayerPacket::MODE_TELEPORT){ - $this->putLInt($this->teleportCause); - $this->putLInt($this->teleportItem); + $this->buf->putLInt($this->teleportCause); + $this->buf->putLInt($this->teleportItem); } } diff --git a/src/network/mcpe/protocol/MultiplayerSettingsPacket.php b/src/network/mcpe/protocol/MultiplayerSettingsPacket.php index 61d5e85fdd..7b59c8a8a9 100644 --- a/src/network/mcpe/protocol/MultiplayerSettingsPacket.php +++ b/src/network/mcpe/protocol/MultiplayerSettingsPacket.php @@ -48,11 +48,11 @@ class MultiplayerSettingsPacket extends DataPacket implements ServerboundPacket{ } protected function decodePayload() : void{ - $this->action = $this->getVarInt(); + $this->action = $this->buf->getVarInt(); } protected function encodePayload() : void{ - $this->putVarInt($this->action); + $this->buf->putVarInt($this->action); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php b/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php index fc78a0b9f1..0fccd283a1 100644 --- a/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php +++ b/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php @@ -49,13 +49,13 @@ class NetworkChunkPublisherUpdatePacket extends DataPacket implements Clientboun } protected function decodePayload() : void{ - $this->getSignedBlockPosition($this->x, $this->y, $this->z); - $this->radius = $this->getUnsignedVarInt(); + $this->buf->getSignedBlockPosition($this->x, $this->y, $this->z); + $this->radius = $this->buf->getUnsignedVarInt(); } protected function encodePayload() : void{ - $this->putSignedBlockPosition($this->x, $this->y, $this->z); - $this->putUnsignedVarInt($this->radius); + $this->buf->putSignedBlockPosition($this->x, $this->y, $this->z); + $this->buf->putUnsignedVarInt($this->radius); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/NetworkSettingsPacket.php b/src/network/mcpe/protocol/NetworkSettingsPacket.php index d509191664..7d1096eb4f 100644 --- a/src/network/mcpe/protocol/NetworkSettingsPacket.php +++ b/src/network/mcpe/protocol/NetworkSettingsPacket.php @@ -47,11 +47,11 @@ class NetworkSettingsPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->compressionThreshold = $this->getLShort(); + $this->compressionThreshold = $this->buf->getLShort(); } protected function encodePayload() : void{ - $this->putLShort($this->compressionThreshold); + $this->buf->putLShort($this->compressionThreshold); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/NetworkStackLatencyPacket.php b/src/network/mcpe/protocol/NetworkStackLatencyPacket.php index 27add3d3c2..327303c6e0 100644 --- a/src/network/mcpe/protocol/NetworkStackLatencyPacket.php +++ b/src/network/mcpe/protocol/NetworkStackLatencyPacket.php @@ -36,13 +36,13 @@ class NetworkStackLatencyPacket extends DataPacket implements ClientboundPacket, public $needResponse; protected function decodePayload() : void{ - $this->timestamp = $this->getLLong(); - $this->needResponse = $this->getBool(); + $this->timestamp = $this->buf->getLLong(); + $this->needResponse = $this->buf->getBool(); } protected function encodePayload() : void{ - $this->putLLong($this->timestamp); - $this->putBool($this->needResponse); + $this->buf->putLLong($this->timestamp); + $this->buf->putBool($this->needResponse); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/NpcRequestPacket.php b/src/network/mcpe/protocol/NpcRequestPacket.php index 7e9e6c69aa..d01c71d830 100644 --- a/src/network/mcpe/protocol/NpcRequestPacket.php +++ b/src/network/mcpe/protocol/NpcRequestPacket.php @@ -40,17 +40,17 @@ class NpcRequestPacket extends DataPacket implements ServerboundPacket{ public $actionType; protected function decodePayload() : void{ - $this->entityRuntimeId = $this->getEntityRuntimeId(); - $this->requestType = $this->getByte(); - $this->commandString = $this->getString(); - $this->actionType = $this->getByte(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + $this->requestType = $this->buf->getByte(); + $this->commandString = $this->buf->getString(); + $this->actionType = $this->buf->getByte(); } protected function encodePayload() : void{ - $this->putEntityRuntimeId($this->entityRuntimeId); - $this->putByte($this->requestType); - $this->putString($this->commandString); - $this->putByte($this->actionType); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putByte($this->requestType); + $this->buf->putString($this->commandString); + $this->buf->putByte($this->actionType); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php b/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php index e4cf449404..0aaf2b218f 100644 --- a/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php +++ b/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php @@ -34,11 +34,11 @@ class OnScreenTextureAnimationPacket extends DataPacket implements ClientboundPa public $effectId; protected function decodePayload() : void{ - $this->effectId = $this->getLInt(); //unsigned + $this->effectId = $this->buf->getLInt(); //unsigned } protected function encodePayload() : void{ - $this->putLInt($this->effectId); + $this->buf->putLInt($this->effectId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/Packet.php b/src/network/mcpe/protocol/Packet.php index 6e68038726..ded5c0f707 100644 --- a/src/network/mcpe/protocol/Packet.php +++ b/src/network/mcpe/protocol/Packet.php @@ -25,27 +25,11 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; interface Packet{ - public function setOffset(int $offset) : void; - - /** - * TODO: this can't have a native return type yet because of incompatibility with BinaryUtils - * really this should be addressed by making packets not extend BinaryStream, but that's a task for another day. - * - * @return void - */ - public function setBuffer(string $buffer = "", int $offset = 0); - - public function getOffset() : int; - - public function getBuffer() : string; - - /** - * Returns whether the offset has reached the end of the buffer. - */ - public function feof() : bool; + public function getBinaryStream() : NetworkBinaryStream; public function pid() : int; diff --git a/src/network/mcpe/protocol/PacketPool.php b/src/network/mcpe/protocol/PacketPool.php index 4596c40e6d..f58f900efa 100644 --- a/src/network/mcpe/protocol/PacketPool.php +++ b/src/network/mcpe/protocol/PacketPool.php @@ -191,7 +191,7 @@ class PacketPool{ public static function getPacket(string $buffer) : Packet{ $offset = 0; $pk = static::getPacketById(Binary::readUnsignedVarInt($buffer, $offset)); - $pk->setBuffer($buffer, $offset); + $pk->getBinaryStream()->setBuffer($buffer, $offset); return $pk; } diff --git a/src/network/mcpe/protocol/PhotoTransferPacket.php b/src/network/mcpe/protocol/PhotoTransferPacket.php index cf32d1472e..a08c56eada 100644 --- a/src/network/mcpe/protocol/PhotoTransferPacket.php +++ b/src/network/mcpe/protocol/PhotoTransferPacket.php @@ -38,15 +38,15 @@ class PhotoTransferPacket extends DataPacket implements ClientboundPacket{ public $bookId; //photos are stored in a sibling directory to the games folder (screenshots/(some UUID)/bookID/example.png) protected function decodePayload() : void{ - $this->photoName = $this->getString(); - $this->photoData = $this->getString(); - $this->bookId = $this->getString(); + $this->photoName = $this->buf->getString(); + $this->photoData = $this->buf->getString(); + $this->bookId = $this->buf->getString(); } protected function encodePayload() : void{ - $this->putString($this->photoName); - $this->putString($this->photoData); - $this->putString($this->bookId); + $this->buf->putString($this->photoName); + $this->buf->putString($this->photoData); + $this->buf->putString($this->bookId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/PlaySoundPacket.php b/src/network/mcpe/protocol/PlaySoundPacket.php index cda6b01a14..e90f1f403c 100644 --- a/src/network/mcpe/protocol/PlaySoundPacket.php +++ b/src/network/mcpe/protocol/PlaySoundPacket.php @@ -44,20 +44,20 @@ class PlaySoundPacket extends DataPacket implements ClientboundPacket{ public $pitch; protected function decodePayload() : void{ - $this->soundName = $this->getString(); - $this->getBlockPosition($this->x, $this->y, $this->z); + $this->soundName = $this->buf->getString(); + $this->buf->getBlockPosition($this->x, $this->y, $this->z); $this->x /= 8; $this->y /= 8; $this->z /= 8; - $this->volume = $this->getLFloat(); - $this->pitch = $this->getLFloat(); + $this->volume = $this->buf->getLFloat(); + $this->pitch = $this->buf->getLFloat(); } protected function encodePayload() : void{ - $this->putString($this->soundName); - $this->putBlockPosition((int) ($this->x * 8), (int) ($this->y * 8), (int) ($this->z * 8)); - $this->putLFloat($this->volume); - $this->putLFloat($this->pitch); + $this->buf->putString($this->soundName); + $this->buf->putBlockPosition((int) ($this->x * 8), (int) ($this->y * 8), (int) ($this->z * 8)); + $this->buf->putLFloat($this->volume); + $this->buf->putLFloat($this->pitch); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/PlayStatusPacket.php b/src/network/mcpe/protocol/PlayStatusPacket.php index 9f4402d18b..b0f88740d2 100644 --- a/src/network/mcpe/protocol/PlayStatusPacket.php +++ b/src/network/mcpe/protocol/PlayStatusPacket.php @@ -49,7 +49,7 @@ class PlayStatusPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->status = $this->getInt(); + $this->status = $this->buf->getInt(); } public function canBeSentBeforeLogin() : bool{ @@ -57,7 +57,7 @@ class PlayStatusPacket extends DataPacket implements ClientboundPacket{ } protected function encodePayload() : void{ - $this->putInt($this->status); + $this->buf->putInt($this->status); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/PlayerActionPacket.php b/src/network/mcpe/protocol/PlayerActionPacket.php index 7cffd0c5fe..2985a206e7 100644 --- a/src/network/mcpe/protocol/PlayerActionPacket.php +++ b/src/network/mcpe/protocol/PlayerActionPacket.php @@ -71,17 +71,17 @@ class PlayerActionPacket extends DataPacket implements ServerboundPacket{ public $face; protected function decodePayload() : void{ - $this->entityRuntimeId = $this->getEntityRuntimeId(); - $this->action = $this->getVarInt(); - $this->getBlockPosition($this->x, $this->y, $this->z); - $this->face = $this->getVarInt(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + $this->action = $this->buf->getVarInt(); + $this->buf->getBlockPosition($this->x, $this->y, $this->z); + $this->face = $this->buf->getVarInt(); } protected function encodePayload() : void{ - $this->putEntityRuntimeId($this->entityRuntimeId); - $this->putVarInt($this->action); - $this->putBlockPosition($this->x, $this->y, $this->z); - $this->putVarInt($this->face); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putVarInt($this->action); + $this->buf->putBlockPosition($this->x, $this->y, $this->z); + $this->buf->putVarInt($this->face); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/PlayerAuthInputPacket.php b/src/network/mcpe/protocol/PlayerAuthInputPacket.php index 9ab85d79e0..12fdcc80bc 100644 --- a/src/network/mcpe/protocol/PlayerAuthInputPacket.php +++ b/src/network/mcpe/protocol/PlayerAuthInputPacket.php @@ -128,33 +128,33 @@ class PlayerAuthInputPacket extends DataPacket implements ServerboundPacket{ } protected function decodePayload() : void{ - $this->yaw = $this->getLFloat(); - $this->pitch = $this->getLFloat(); - $this->position = $this->getVector3(); - $this->moveVecX = $this->getLFloat(); - $this->moveVecZ = $this->getLFloat(); - $this->headYaw = $this->getLFloat(); - $this->inputFlags = $this->getUnsignedVarLong(); - $this->inputMode = $this->getUnsignedVarInt(); - $this->playMode = $this->getUnsignedVarInt(); + $this->yaw = $this->buf->getLFloat(); + $this->pitch = $this->buf->getLFloat(); + $this->position = $this->buf->getVector3(); + $this->moveVecX = $this->buf->getLFloat(); + $this->moveVecZ = $this->buf->getLFloat(); + $this->headYaw = $this->buf->getLFloat(); + $this->inputFlags = $this->buf->getUnsignedVarLong(); + $this->inputMode = $this->buf->getUnsignedVarInt(); + $this->playMode = $this->buf->getUnsignedVarInt(); if($this->playMode === PlayMode::VR){ - $this->vrGazeDirection = $this->getVector3(); + $this->vrGazeDirection = $this->buf->getVector3(); } } protected function encodePayload() : void{ - $this->putLFloat($this->yaw); - $this->putLFloat($this->pitch); - $this->putVector3($this->position); - $this->putLFloat($this->moveVecX); - $this->putLFloat($this->moveVecZ); - $this->putLFloat($this->headYaw); - $this->putUnsignedVarLong($this->inputFlags); - $this->putUnsignedVarInt($this->inputMode); - $this->putUnsignedVarInt($this->playMode); + $this->buf->putLFloat($this->yaw); + $this->buf->putLFloat($this->pitch); + $this->buf->putVector3($this->position); + $this->buf->putLFloat($this->moveVecX); + $this->buf->putLFloat($this->moveVecZ); + $this->buf->putLFloat($this->headYaw); + $this->buf->putUnsignedVarLong($this->inputFlags); + $this->buf->putUnsignedVarInt($this->inputMode); + $this->buf->putUnsignedVarInt($this->playMode); if($this->playMode === PlayMode::VR){ assert($this->vrGazeDirection !== null); - $this->putVector3($this->vrGazeDirection); + $this->buf->putVector3($this->vrGazeDirection); } } diff --git a/src/network/mcpe/protocol/PlayerHotbarPacket.php b/src/network/mcpe/protocol/PlayerHotbarPacket.php index e0c9e53fb0..e5bd9f2d13 100644 --- a/src/network/mcpe/protocol/PlayerHotbarPacket.php +++ b/src/network/mcpe/protocol/PlayerHotbarPacket.php @@ -47,15 +47,15 @@ class PlayerHotbarPacket extends DataPacket implements ClientboundPacket, Server } protected function decodePayload() : void{ - $this->selectedHotbarSlot = $this->getUnsignedVarInt(); - $this->windowId = $this->getByte(); - $this->selectHotbarSlot = $this->getBool(); + $this->selectedHotbarSlot = $this->buf->getUnsignedVarInt(); + $this->windowId = $this->buf->getByte(); + $this->selectHotbarSlot = $this->buf->getBool(); } protected function encodePayload() : void{ - $this->putUnsignedVarInt($this->selectedHotbarSlot); - $this->putByte($this->windowId); - $this->putBool($this->selectHotbarSlot); + $this->buf->putUnsignedVarInt($this->selectedHotbarSlot); + $this->buf->putByte($this->windowId); + $this->buf->putBool($this->selectHotbarSlot); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/PlayerInputPacket.php b/src/network/mcpe/protocol/PlayerInputPacket.php index 6828cdaa57..f74da921ec 100644 --- a/src/network/mcpe/protocol/PlayerInputPacket.php +++ b/src/network/mcpe/protocol/PlayerInputPacket.php @@ -40,17 +40,17 @@ class PlayerInputPacket extends DataPacket implements ServerboundPacket{ public $sneaking; protected function decodePayload() : void{ - $this->motionX = $this->getLFloat(); - $this->motionY = $this->getLFloat(); - $this->jumping = $this->getBool(); - $this->sneaking = $this->getBool(); + $this->motionX = $this->buf->getLFloat(); + $this->motionY = $this->buf->getLFloat(); + $this->jumping = $this->buf->getBool(); + $this->sneaking = $this->buf->getBool(); } protected function encodePayload() : void{ - $this->putLFloat($this->motionX); - $this->putLFloat($this->motionY); - $this->putBool($this->jumping); - $this->putBool($this->sneaking); + $this->buf->putLFloat($this->motionX); + $this->buf->putLFloat($this->motionY); + $this->buf->putBool($this->jumping); + $this->buf->putBool($this->sneaking); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/PlayerListPacket.php b/src/network/mcpe/protocol/PlayerListPacket.php index c514f4fdbc..068f68b0f6 100644 --- a/src/network/mcpe/protocol/PlayerListPacket.php +++ b/src/network/mcpe/protocol/PlayerListPacket.php @@ -61,23 +61,23 @@ class PlayerListPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->type = $this->getByte(); - $count = $this->getUnsignedVarInt(); + $this->type = $this->buf->getByte(); + $count = $this->buf->getUnsignedVarInt(); for($i = 0; $i < $count; ++$i){ $entry = new PlayerListEntry(); if($this->type === self::TYPE_ADD){ - $entry->uuid = $this->getUUID(); - $entry->entityUniqueId = $this->getEntityUniqueId(); - $entry->username = $this->getString(); - $entry->xboxUserId = $this->getString(); - $entry->platformChatId = $this->getString(); - $entry->buildPlatform = $this->getLInt(); - $entry->skinData = $this->getSkin(); - $entry->isTeacher = $this->getBool(); - $entry->isHost = $this->getBool(); + $entry->uuid = $this->buf->getUUID(); + $entry->entityUniqueId = $this->buf->getEntityUniqueId(); + $entry->username = $this->buf->getString(); + $entry->xboxUserId = $this->buf->getString(); + $entry->platformChatId = $this->buf->getString(); + $entry->buildPlatform = $this->buf->getLInt(); + $entry->skinData = $this->buf->getSkin(); + $entry->isTeacher = $this->buf->getBool(); + $entry->isHost = $this->buf->getBool(); }else{ - $entry->uuid = $this->getUUID(); + $entry->uuid = $this->buf->getUUID(); } $this->entries[$i] = $entry; @@ -85,21 +85,21 @@ class PlayerListPacket extends DataPacket implements ClientboundPacket{ } protected function encodePayload() : void{ - $this->putByte($this->type); - $this->putUnsignedVarInt(count($this->entries)); + $this->buf->putByte($this->type); + $this->buf->putUnsignedVarInt(count($this->entries)); foreach($this->entries as $entry){ if($this->type === self::TYPE_ADD){ - $this->putUUID($entry->uuid); - $this->putEntityUniqueId($entry->entityUniqueId); - $this->putString($entry->username); - $this->putString($entry->xboxUserId); - $this->putString($entry->platformChatId); - $this->putLInt($entry->buildPlatform); - $this->putSkin($entry->skinData); - $this->putBool($entry->isTeacher); - $this->putBool($entry->isHost); + $this->buf->putUUID($entry->uuid); + $this->buf->putEntityUniqueId($entry->entityUniqueId); + $this->buf->putString($entry->username); + $this->buf->putString($entry->xboxUserId); + $this->buf->putString($entry->platformChatId); + $this->buf->putLInt($entry->buildPlatform); + $this->buf->putSkin($entry->skinData); + $this->buf->putBool($entry->isTeacher); + $this->buf->putBool($entry->isHost); }else{ - $this->putUUID($entry->uuid); + $this->buf->putUUID($entry->uuid); } } } diff --git a/src/network/mcpe/protocol/PlayerSkinPacket.php b/src/network/mcpe/protocol/PlayerSkinPacket.php index e2de10b78b..cefa9fbc86 100644 --- a/src/network/mcpe/protocol/PlayerSkinPacket.php +++ b/src/network/mcpe/protocol/PlayerSkinPacket.php @@ -42,17 +42,17 @@ class PlayerSkinPacket extends DataPacket implements ClientboundPacket, Serverbo public $skin; protected function decodePayload() : void{ - $this->uuid = $this->getUUID(); - $this->skin = $this->getSkin(); - $this->newSkinName = $this->getString(); - $this->oldSkinName = $this->getString(); + $this->uuid = $this->buf->getUUID(); + $this->skin = $this->buf->getSkin(); + $this->newSkinName = $this->buf->getString(); + $this->oldSkinName = $this->buf->getString(); } protected function encodePayload() : void{ - $this->putUUID($this->uuid); - $this->putSkin($this->skin); - $this->putString($this->newSkinName); - $this->putString($this->oldSkinName); + $this->buf->putUUID($this->uuid); + $this->buf->putSkin($this->skin); + $this->buf->putString($this->newSkinName); + $this->buf->putString($this->oldSkinName); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/PurchaseReceiptPacket.php b/src/network/mcpe/protocol/PurchaseReceiptPacket.php index 8b6b02b868..3d7fdc3101 100644 --- a/src/network/mcpe/protocol/PurchaseReceiptPacket.php +++ b/src/network/mcpe/protocol/PurchaseReceiptPacket.php @@ -35,16 +35,16 @@ class PurchaseReceiptPacket extends DataPacket implements ServerboundPacket{ public $entries = []; protected function decodePayload() : void{ - $count = $this->getUnsignedVarInt(); + $count = $this->buf->getUnsignedVarInt(); for($i = 0; $i < $count; ++$i){ - $this->entries[] = $this->getString(); + $this->entries[] = $this->buf->getString(); } } protected function encodePayload() : void{ - $this->putUnsignedVarInt(count($this->entries)); + $this->buf->putUnsignedVarInt(count($this->entries)); foreach($this->entries as $entry){ - $this->putString($entry); + $this->buf->putString($entry); } } diff --git a/src/network/mcpe/protocol/RemoveActorPacket.php b/src/network/mcpe/protocol/RemoveActorPacket.php index 54e8aedede..991fac0649 100644 --- a/src/network/mcpe/protocol/RemoveActorPacket.php +++ b/src/network/mcpe/protocol/RemoveActorPacket.php @@ -40,11 +40,11 @@ class RemoveActorPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->entityUniqueId = $this->getEntityUniqueId(); + $this->entityUniqueId = $this->buf->getEntityUniqueId(); } protected function encodePayload() : void{ - $this->putEntityUniqueId($this->entityUniqueId); + $this->buf->putEntityUniqueId($this->entityUniqueId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/RemoveEntityPacket.php b/src/network/mcpe/protocol/RemoveEntityPacket.php index 9b052ae506..2c26a1c350 100644 --- a/src/network/mcpe/protocol/RemoveEntityPacket.php +++ b/src/network/mcpe/protocol/RemoveEntityPacket.php @@ -44,11 +44,11 @@ class RemoveEntityPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->uvarint1 = $this->getUnsignedVarInt(); + $this->uvarint1 = $this->buf->getUnsignedVarInt(); } protected function encodePayload() : void{ - $this->putUnsignedVarInt($this->uvarint1); + $this->buf->putUnsignedVarInt($this->uvarint1); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/RemoveObjectivePacket.php b/src/network/mcpe/protocol/RemoveObjectivePacket.php index e05e1ed33c..c44291daf9 100644 --- a/src/network/mcpe/protocol/RemoveObjectivePacket.php +++ b/src/network/mcpe/protocol/RemoveObjectivePacket.php @@ -34,11 +34,11 @@ class RemoveObjectivePacket extends DataPacket implements ClientboundPacket{ public $objectiveName; protected function decodePayload() : void{ - $this->objectiveName = $this->getString(); + $this->objectiveName = $this->buf->getString(); } protected function encodePayload() : void{ - $this->putString($this->objectiveName); + $this->buf->putString($this->objectiveName); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/RequestChunkRadiusPacket.php b/src/network/mcpe/protocol/RequestChunkRadiusPacket.php index 7d7fccf86e..57b38afa60 100644 --- a/src/network/mcpe/protocol/RequestChunkRadiusPacket.php +++ b/src/network/mcpe/protocol/RequestChunkRadiusPacket.php @@ -34,11 +34,11 @@ class RequestChunkRadiusPacket extends DataPacket implements ServerboundPacket{ public $radius; protected function decodePayload() : void{ - $this->radius = $this->getVarInt(); + $this->radius = $this->buf->getVarInt(); } protected function encodePayload() : void{ - $this->putVarInt($this->radius); + $this->buf->putVarInt($this->radius); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php b/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php index 87e1496bc5..a2adbe8380 100644 --- a/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php +++ b/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php @@ -50,17 +50,17 @@ class ResourcePackChunkDataPacket extends DataPacket implements ClientboundPacke } protected function decodePayload() : void{ - $this->packId = $this->getString(); - $this->chunkIndex = $this->getLInt(); - $this->progress = $this->getLLong(); - $this->data = $this->getString(); + $this->packId = $this->buf->getString(); + $this->chunkIndex = $this->buf->getLInt(); + $this->progress = $this->buf->getLLong(); + $this->data = $this->buf->getString(); } protected function encodePayload() : void{ - $this->putString($this->packId); - $this->putLInt($this->chunkIndex); - $this->putLLong($this->progress); - $this->putString($this->data); + $this->buf->putString($this->packId); + $this->buf->putLInt($this->chunkIndex); + $this->buf->putLLong($this->progress); + $this->buf->putString($this->data); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php b/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php index c15e7c3d27..e90154bcd1 100644 --- a/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php +++ b/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php @@ -36,13 +36,13 @@ class ResourcePackChunkRequestPacket extends DataPacket implements ServerboundPa public $chunkIndex; protected function decodePayload() : void{ - $this->packId = $this->getString(); - $this->chunkIndex = $this->getLInt(); + $this->packId = $this->buf->getString(); + $this->chunkIndex = $this->buf->getLInt(); } protected function encodePayload() : void{ - $this->putString($this->packId); - $this->putLInt($this->chunkIndex); + $this->buf->putString($this->packId); + $this->buf->putLInt($this->chunkIndex); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php b/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php index 06bd7a039d..ca4b193632 100644 --- a/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php +++ b/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php @@ -42,18 +42,18 @@ class ResourcePackClientResponsePacket extends DataPacket implements Serverbound public $packIds = []; protected function decodePayload() : void{ - $this->status = $this->getByte(); - $entryCount = $this->getLShort(); + $this->status = $this->buf->getByte(); + $entryCount = $this->buf->getLShort(); while($entryCount-- > 0){ - $this->packIds[] = $this->getString(); + $this->packIds[] = $this->buf->getString(); } } protected function encodePayload() : void{ - $this->putByte($this->status); - $this->putLShort(count($this->packIds)); + $this->buf->putByte($this->status); + $this->buf->putLShort(count($this->packIds)); foreach($this->packIds as $id){ - $this->putString($id); + $this->buf->putString($id); } } diff --git a/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php b/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php index 37fbde3b92..f8066dcc17 100644 --- a/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php +++ b/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php @@ -57,23 +57,23 @@ class ResourcePackDataInfoPacket extends DataPacket implements ClientboundPacket } protected function decodePayload() : void{ - $this->packId = $this->getString(); - $this->maxChunkSize = $this->getLInt(); - $this->chunkCount = $this->getLInt(); - $this->compressedPackSize = $this->getLLong(); - $this->sha256 = $this->getString(); - $this->isPremium = $this->getBool(); - $this->packType = $this->getByte(); + $this->packId = $this->buf->getString(); + $this->maxChunkSize = $this->buf->getLInt(); + $this->chunkCount = $this->buf->getLInt(); + $this->compressedPackSize = $this->buf->getLLong(); + $this->sha256 = $this->buf->getString(); + $this->isPremium = $this->buf->getBool(); + $this->packType = $this->buf->getByte(); } protected function encodePayload() : void{ - $this->putString($this->packId); - $this->putLInt($this->maxChunkSize); - $this->putLInt($this->chunkCount); - $this->putLLong($this->compressedPackSize); - $this->putString($this->sha256); - $this->putBool($this->isPremium); - $this->putByte($this->packType); + $this->buf->putString($this->packId); + $this->buf->putLInt($this->maxChunkSize); + $this->buf->putLInt($this->chunkCount); + $this->buf->putLLong($this->compressedPackSize); + $this->buf->putString($this->sha256); + $this->buf->putBool($this->isPremium); + $this->buf->putByte($this->packType); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ResourcePackStackPacket.php b/src/network/mcpe/protocol/ResourcePackStackPacket.php index 08d4e572cb..f424fe8b58 100644 --- a/src/network/mcpe/protocol/ResourcePackStackPacket.php +++ b/src/network/mcpe/protocol/ResourcePackStackPacket.php @@ -61,36 +61,36 @@ class ResourcePackStackPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->mustAccept = $this->getBool(); - $behaviorPackCount = $this->getUnsignedVarInt(); + $this->mustAccept = $this->buf->getBool(); + $behaviorPackCount = $this->buf->getUnsignedVarInt(); while($behaviorPackCount-- > 0){ - $this->behaviorPackStack[] = ResourcePackStackEntry::read($this); + $this->behaviorPackStack[] = ResourcePackStackEntry::read($this->buf); } - $resourcePackCount = $this->getUnsignedVarInt(); + $resourcePackCount = $this->buf->getUnsignedVarInt(); while($resourcePackCount-- > 0){ - $this->resourcePackStack[] = ResourcePackStackEntry::read($this); + $this->resourcePackStack[] = ResourcePackStackEntry::read($this->buf); } - $this->isExperimental = $this->getBool(); - $this->baseGameVersion = $this->getString(); + $this->isExperimental = $this->buf->getBool(); + $this->baseGameVersion = $this->buf->getString(); } protected function encodePayload() : void{ - $this->putBool($this->mustAccept); + $this->buf->putBool($this->mustAccept); - $this->putUnsignedVarInt(count($this->behaviorPackStack)); + $this->buf->putUnsignedVarInt(count($this->behaviorPackStack)); foreach($this->behaviorPackStack as $entry){ - $entry->write($this); + $entry->write($this->buf); } - $this->putUnsignedVarInt(count($this->resourcePackStack)); + $this->buf->putUnsignedVarInt(count($this->resourcePackStack)); foreach($this->resourcePackStack as $entry){ - $entry->write($this); + $entry->write($this->buf); } - $this->putBool($this->isExperimental); - $this->putString($this->baseGameVersion); + $this->buf->putBool($this->isExperimental); + $this->buf->putString($this->baseGameVersion); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php index 868e219420..a0acc75860 100644 --- a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php +++ b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php @@ -57,29 +57,29 @@ class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->mustAccept = $this->getBool(); - $this->hasScripts = $this->getBool(); - $behaviorPackCount = $this->getLShort(); + $this->mustAccept = $this->buf->getBool(); + $this->hasScripts = $this->buf->getBool(); + $behaviorPackCount = $this->buf->getLShort(); while($behaviorPackCount-- > 0){ - $this->behaviorPackEntries[] = ResourcePackInfoEntry::read($this); + $this->behaviorPackEntries[] = ResourcePackInfoEntry::read($this->buf); } - $resourcePackCount = $this->getLShort(); + $resourcePackCount = $this->buf->getLShort(); while($resourcePackCount-- > 0){ - $this->resourcePackEntries[] = ResourcePackInfoEntry::read($this); + $this->resourcePackEntries[] = ResourcePackInfoEntry::read($this->buf); } } protected function encodePayload() : void{ - $this->putBool($this->mustAccept); - $this->putBool($this->hasScripts); - $this->putLShort(count($this->behaviorPackEntries)); + $this->buf->putBool($this->mustAccept); + $this->buf->putBool($this->hasScripts); + $this->buf->putLShort(count($this->behaviorPackEntries)); foreach($this->behaviorPackEntries as $entry){ - $entry->write($this); + $entry->write($this->buf); } - $this->putLShort(count($this->resourcePackEntries)); + $this->buf->putLShort(count($this->resourcePackEntries)); foreach($this->resourcePackEntries as $entry){ - $entry->write($this); + $entry->write($this->buf); } } diff --git a/src/network/mcpe/protocol/RespawnPacket.php b/src/network/mcpe/protocol/RespawnPacket.php index 923ea7a4dc..3bb6c69b9d 100644 --- a/src/network/mcpe/protocol/RespawnPacket.php +++ b/src/network/mcpe/protocol/RespawnPacket.php @@ -51,15 +51,15 @@ class RespawnPacket extends DataPacket implements ClientboundPacket, Serverbound } protected function decodePayload() : void{ - $this->position = $this->getVector3(); - $this->respawnState = $this->getByte(); - $this->entityRuntimeId = $this->getEntityRuntimeId(); + $this->position = $this->buf->getVector3(); + $this->respawnState = $this->buf->getByte(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); } protected function encodePayload() : void{ - $this->putVector3($this->position); - $this->putByte($this->respawnState); - $this->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putVector3($this->position); + $this->buf->putByte($this->respawnState); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/RiderJumpPacket.php b/src/network/mcpe/protocol/RiderJumpPacket.php index c6b9f534d3..162424be83 100644 --- a/src/network/mcpe/protocol/RiderJumpPacket.php +++ b/src/network/mcpe/protocol/RiderJumpPacket.php @@ -34,11 +34,11 @@ class RiderJumpPacket extends DataPacket implements ServerboundPacket{ public $jumpStrength; //percentage protected function decodePayload() : void{ - $this->jumpStrength = $this->getVarInt(); + $this->jumpStrength = $this->buf->getVarInt(); } protected function encodePayload() : void{ - $this->putVarInt($this->jumpStrength); + $this->buf->putVarInt($this->jumpStrength); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ScriptCustomEventPacket.php b/src/network/mcpe/protocol/ScriptCustomEventPacket.php index 999dad4f9f..3247bffed6 100644 --- a/src/network/mcpe/protocol/ScriptCustomEventPacket.php +++ b/src/network/mcpe/protocol/ScriptCustomEventPacket.php @@ -36,13 +36,13 @@ class ScriptCustomEventPacket extends DataPacket{ //TODO: this doesn't have hand public $eventData; protected function decodePayload() : void{ - $this->eventName = $this->getString(); - $this->eventData = $this->getString(); + $this->eventName = $this->buf->getString(); + $this->eventData = $this->buf->getString(); } protected function encodePayload() : void{ - $this->putString($this->eventName); - $this->putString($this->eventData); + $this->buf->putString($this->eventName); + $this->buf->putString($this->eventData); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ServerSettingsResponsePacket.php b/src/network/mcpe/protocol/ServerSettingsResponsePacket.php index 9bff90f314..1134a44b9b 100644 --- a/src/network/mcpe/protocol/ServerSettingsResponsePacket.php +++ b/src/network/mcpe/protocol/ServerSettingsResponsePacket.php @@ -36,13 +36,13 @@ class ServerSettingsResponsePacket extends DataPacket implements ClientboundPack public $formData; //json protected function decodePayload() : void{ - $this->formId = $this->getUnsignedVarInt(); - $this->formData = $this->getString(); + $this->formId = $this->buf->getUnsignedVarInt(); + $this->formData = $this->buf->getString(); } protected function encodePayload() : void{ - $this->putUnsignedVarInt($this->formId); - $this->putString($this->formData); + $this->buf->putUnsignedVarInt($this->formId); + $this->buf->putString($this->formData); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ServerToClientHandshakePacket.php b/src/network/mcpe/protocol/ServerToClientHandshakePacket.php index 577bf38dcf..51a2859b2c 100644 --- a/src/network/mcpe/protocol/ServerToClientHandshakePacket.php +++ b/src/network/mcpe/protocol/ServerToClientHandshakePacket.php @@ -47,11 +47,11 @@ class ServerToClientHandshakePacket extends DataPacket implements ClientboundPac } protected function decodePayload() : void{ - $this->jwt = $this->getString(); + $this->jwt = $this->buf->getString(); } protected function encodePayload() : void{ - $this->putString($this->jwt); + $this->buf->putString($this->jwt); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetActorDataPacket.php b/src/network/mcpe/protocol/SetActorDataPacket.php index ebde0894a0..0d93ffe0bf 100644 --- a/src/network/mcpe/protocol/SetActorDataPacket.php +++ b/src/network/mcpe/protocol/SetActorDataPacket.php @@ -52,13 +52,13 @@ class SetActorDataPacket extends DataPacket implements ClientboundPacket, Server } protected function decodePayload() : void{ - $this->entityRuntimeId = $this->getEntityRuntimeId(); - $this->metadata = $this->getEntityMetadata(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + $this->metadata = $this->buf->getEntityMetadata(); } protected function encodePayload() : void{ - $this->putEntityRuntimeId($this->entityRuntimeId); - $this->putEntityMetadata($this->metadata); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putEntityMetadata($this->metadata); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetActorLinkPacket.php b/src/network/mcpe/protocol/SetActorLinkPacket.php index 6e03372d8b..76efc27242 100644 --- a/src/network/mcpe/protocol/SetActorLinkPacket.php +++ b/src/network/mcpe/protocol/SetActorLinkPacket.php @@ -35,11 +35,11 @@ class SetActorLinkPacket extends DataPacket implements ClientboundPacket{ public $link; protected function decodePayload() : void{ - $this->link = $this->getEntityLink(); + $this->link = $this->buf->getEntityLink(); } protected function encodePayload() : void{ - $this->putEntityLink($this->link); + $this->buf->putEntityLink($this->link); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetActorMotionPacket.php b/src/network/mcpe/protocol/SetActorMotionPacket.php index 863af7485b..553eeddd72 100644 --- a/src/network/mcpe/protocol/SetActorMotionPacket.php +++ b/src/network/mcpe/protocol/SetActorMotionPacket.php @@ -47,13 +47,13 @@ class SetActorMotionPacket extends DataPacket implements ClientboundPacket, Garb } protected function decodePayload() : void{ - $this->entityRuntimeId = $this->getEntityRuntimeId(); - $this->motion = $this->getVector3(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + $this->motion = $this->buf->getVector3(); } protected function encodePayload() : void{ - $this->putEntityRuntimeId($this->entityRuntimeId); - $this->putVector3($this->motion); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putVector3($this->motion); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetCommandsEnabledPacket.php b/src/network/mcpe/protocol/SetCommandsEnabledPacket.php index 6f0d1bcb3f..38bcd87809 100644 --- a/src/network/mcpe/protocol/SetCommandsEnabledPacket.php +++ b/src/network/mcpe/protocol/SetCommandsEnabledPacket.php @@ -34,11 +34,11 @@ class SetCommandsEnabledPacket extends DataPacket implements ClientboundPacket{ public $enabled; protected function decodePayload() : void{ - $this->enabled = $this->getBool(); + $this->enabled = $this->buf->getBool(); } protected function encodePayload() : void{ - $this->putBool($this->enabled); + $this->buf->putBool($this->enabled); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetDefaultGameTypePacket.php b/src/network/mcpe/protocol/SetDefaultGameTypePacket.php index 383c91266e..f39bbce4d0 100644 --- a/src/network/mcpe/protocol/SetDefaultGameTypePacket.php +++ b/src/network/mcpe/protocol/SetDefaultGameTypePacket.php @@ -40,11 +40,11 @@ class SetDefaultGameTypePacket extends DataPacket implements ClientboundPacket, } protected function decodePayload() : void{ - $this->gamemode = $this->getVarInt(); + $this->gamemode = $this->buf->getVarInt(); } protected function encodePayload() : void{ - $this->putUnsignedVarInt($this->gamemode); + $this->buf->putUnsignedVarInt($this->gamemode); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetDifficultyPacket.php b/src/network/mcpe/protocol/SetDifficultyPacket.php index a6de96175c..3489abe99c 100644 --- a/src/network/mcpe/protocol/SetDifficultyPacket.php +++ b/src/network/mcpe/protocol/SetDifficultyPacket.php @@ -40,11 +40,11 @@ class SetDifficultyPacket extends DataPacket implements ClientboundPacket, Serve } protected function decodePayload() : void{ - $this->difficulty = $this->getUnsignedVarInt(); + $this->difficulty = $this->buf->getUnsignedVarInt(); } protected function encodePayload() : void{ - $this->putUnsignedVarInt($this->difficulty); + $this->buf->putUnsignedVarInt($this->difficulty); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetDisplayObjectivePacket.php b/src/network/mcpe/protocol/SetDisplayObjectivePacket.php index 9a0ba7bacf..2f4075b2ab 100644 --- a/src/network/mcpe/protocol/SetDisplayObjectivePacket.php +++ b/src/network/mcpe/protocol/SetDisplayObjectivePacket.php @@ -42,19 +42,19 @@ class SetDisplayObjectivePacket extends DataPacket implements ClientboundPacket{ public $sortOrder; protected function decodePayload() : void{ - $this->displaySlot = $this->getString(); - $this->objectiveName = $this->getString(); - $this->displayName = $this->getString(); - $this->criteriaName = $this->getString(); - $this->sortOrder = $this->getVarInt(); + $this->displaySlot = $this->buf->getString(); + $this->objectiveName = $this->buf->getString(); + $this->displayName = $this->buf->getString(); + $this->criteriaName = $this->buf->getString(); + $this->sortOrder = $this->buf->getVarInt(); } protected function encodePayload() : void{ - $this->putString($this->displaySlot); - $this->putString($this->objectiveName); - $this->putString($this->displayName); - $this->putString($this->criteriaName); - $this->putVarInt($this->sortOrder); + $this->buf->putString($this->displaySlot); + $this->buf->putString($this->objectiveName); + $this->buf->putString($this->displayName); + $this->buf->putString($this->criteriaName); + $this->buf->putVarInt($this->sortOrder); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetHealthPacket.php b/src/network/mcpe/protocol/SetHealthPacket.php index 4efee7493d..4fb3f16097 100644 --- a/src/network/mcpe/protocol/SetHealthPacket.php +++ b/src/network/mcpe/protocol/SetHealthPacket.php @@ -34,11 +34,11 @@ class SetHealthPacket extends DataPacket implements ClientboundPacket{ public $health; protected function decodePayload() : void{ - $this->health = $this->getVarInt(); + $this->health = $this->buf->getVarInt(); } protected function encodePayload() : void{ - $this->putVarInt($this->health); + $this->buf->putVarInt($this->health); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetLastHurtByPacket.php b/src/network/mcpe/protocol/SetLastHurtByPacket.php index ab2b703e01..6cff93835b 100644 --- a/src/network/mcpe/protocol/SetLastHurtByPacket.php +++ b/src/network/mcpe/protocol/SetLastHurtByPacket.php @@ -34,11 +34,11 @@ class SetLastHurtByPacket extends DataPacket implements ClientboundPacket{ public $entityTypeId; protected function decodePayload() : void{ - $this->entityTypeId = $this->getVarInt(); + $this->entityTypeId = $this->buf->getVarInt(); } protected function encodePayload() : void{ - $this->putVarInt($this->entityTypeId); + $this->buf->putVarInt($this->entityTypeId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php b/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php index 7b15c525ba..0897c63294 100644 --- a/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php +++ b/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php @@ -34,11 +34,11 @@ class SetLocalPlayerAsInitializedPacket extends DataPacket implements Serverboun public $entityRuntimeId; protected function decodePayload() : void{ - $this->entityRuntimeId = $this->getEntityRuntimeId(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); } protected function encodePayload() : void{ - $this->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetPlayerGameTypePacket.php b/src/network/mcpe/protocol/SetPlayerGameTypePacket.php index 94695ac4aa..bb8699aab7 100644 --- a/src/network/mcpe/protocol/SetPlayerGameTypePacket.php +++ b/src/network/mcpe/protocol/SetPlayerGameTypePacket.php @@ -40,11 +40,11 @@ class SetPlayerGameTypePacket extends DataPacket implements ClientboundPacket, S } protected function decodePayload() : void{ - $this->gamemode = $this->getVarInt(); + $this->gamemode = $this->buf->getVarInt(); } protected function encodePayload() : void{ - $this->putVarInt($this->gamemode); + $this->buf->putVarInt($this->gamemode); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetScorePacket.php b/src/network/mcpe/protocol/SetScorePacket.php index 9128ceac05..59f61d321c 100644 --- a/src/network/mcpe/protocol/SetScorePacket.php +++ b/src/network/mcpe/protocol/SetScorePacket.php @@ -42,21 +42,21 @@ class SetScorePacket extends DataPacket implements ClientboundPacket{ public $entries = []; protected function decodePayload() : void{ - $this->type = $this->getByte(); - for($i = 0, $i2 = $this->getUnsignedVarInt(); $i < $i2; ++$i){ + $this->type = $this->buf->getByte(); + for($i = 0, $i2 = $this->buf->getUnsignedVarInt(); $i < $i2; ++$i){ $entry = new ScorePacketEntry(); - $entry->scoreboardId = $this->getVarLong(); - $entry->objectiveName = $this->getString(); - $entry->score = $this->getLInt(); + $entry->scoreboardId = $this->buf->getVarLong(); + $entry->objectiveName = $this->buf->getString(); + $entry->score = $this->buf->getLInt(); if($this->type !== self::TYPE_REMOVE){ - $entry->type = $this->getByte(); + $entry->type = $this->buf->getByte(); switch($entry->type){ case ScorePacketEntry::TYPE_PLAYER: case ScorePacketEntry::TYPE_ENTITY: - $entry->entityUniqueId = $this->getEntityUniqueId(); + $entry->entityUniqueId = $this->buf->getEntityUniqueId(); break; case ScorePacketEntry::TYPE_FAKE_PLAYER: - $entry->customName = $this->getString(); + $entry->customName = $this->buf->getString(); break; default: throw new BadPacketException("Unknown entry type $entry->type"); @@ -67,21 +67,21 @@ class SetScorePacket extends DataPacket implements ClientboundPacket{ } protected function encodePayload() : void{ - $this->putByte($this->type); - $this->putUnsignedVarInt(count($this->entries)); + $this->buf->putByte($this->type); + $this->buf->putUnsignedVarInt(count($this->entries)); foreach($this->entries as $entry){ - $this->putVarLong($entry->scoreboardId); - $this->putString($entry->objectiveName); - $this->putLInt($entry->score); + $this->buf->putVarLong($entry->scoreboardId); + $this->buf->putString($entry->objectiveName); + $this->buf->putLInt($entry->score); if($this->type !== self::TYPE_REMOVE){ - $this->putByte($entry->type); + $this->buf->putByte($entry->type); switch($entry->type){ case ScorePacketEntry::TYPE_PLAYER: case ScorePacketEntry::TYPE_ENTITY: - $this->putEntityUniqueId($entry->entityUniqueId); + $this->buf->putEntityUniqueId($entry->entityUniqueId); break; case ScorePacketEntry::TYPE_FAKE_PLAYER: - $this->putString($entry->customName); + $this->buf->putString($entry->customName); break; default: throw new \InvalidArgumentException("Unknown entry type $entry->type"); diff --git a/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php b/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php index 2d8a39961e..991771accb 100644 --- a/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php +++ b/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php @@ -41,12 +41,12 @@ class SetScoreboardIdentityPacket extends DataPacket implements ClientboundPacke public $entries = []; protected function decodePayload() : void{ - $this->type = $this->getByte(); - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ + $this->type = $this->buf->getByte(); + for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ $entry = new ScoreboardIdentityPacketEntry(); - $entry->scoreboardId = $this->getVarLong(); + $entry->scoreboardId = $this->buf->getVarLong(); if($this->type === self::TYPE_REGISTER_IDENTITY){ - $entry->entityUniqueId = $this->getEntityUniqueId(); + $entry->entityUniqueId = $this->buf->getEntityUniqueId(); } $this->entries[] = $entry; @@ -54,12 +54,12 @@ class SetScoreboardIdentityPacket extends DataPacket implements ClientboundPacke } protected function encodePayload() : void{ - $this->putByte($this->type); - $this->putUnsignedVarInt(count($this->entries)); + $this->buf->putByte($this->type); + $this->buf->putUnsignedVarInt(count($this->entries)); foreach($this->entries as $entry){ - $this->putVarLong($entry->scoreboardId); + $this->buf->putVarLong($entry->scoreboardId); if($this->type === self::TYPE_REGISTER_IDENTITY){ - $this->putEntityUniqueId($entry->entityUniqueId); + $this->buf->putEntityUniqueId($entry->entityUniqueId); } } } diff --git a/src/network/mcpe/protocol/SetSpawnPositionPacket.php b/src/network/mcpe/protocol/SetSpawnPositionPacket.php index a5c600110e..9e8320a140 100644 --- a/src/network/mcpe/protocol/SetSpawnPositionPacket.php +++ b/src/network/mcpe/protocol/SetSpawnPositionPacket.php @@ -60,15 +60,15 @@ class SetSpawnPositionPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->spawnType = $this->getVarInt(); - $this->getBlockPosition($this->x, $this->y, $this->z); - $this->spawnForced = $this->getBool(); + $this->spawnType = $this->buf->getVarInt(); + $this->buf->getBlockPosition($this->x, $this->y, $this->z); + $this->spawnForced = $this->buf->getBool(); } protected function encodePayload() : void{ - $this->putVarInt($this->spawnType); - $this->putBlockPosition($this->x, $this->y, $this->z); - $this->putBool($this->spawnForced); + $this->buf->putVarInt($this->spawnType); + $this->buf->putBlockPosition($this->x, $this->y, $this->z); + $this->buf->putBool($this->spawnForced); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetTimePacket.php b/src/network/mcpe/protocol/SetTimePacket.php index a86d87046b..b6fbac90b6 100644 --- a/src/network/mcpe/protocol/SetTimePacket.php +++ b/src/network/mcpe/protocol/SetTimePacket.php @@ -40,11 +40,11 @@ class SetTimePacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->time = $this->getVarInt(); + $this->time = $this->buf->getVarInt(); } protected function encodePayload() : void{ - $this->putVarInt($this->time); + $this->buf->putVarInt($this->time); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetTitlePacket.php b/src/network/mcpe/protocol/SetTitlePacket.php index 937dffeca8..0e1585fa74 100644 --- a/src/network/mcpe/protocol/SetTitlePacket.php +++ b/src/network/mcpe/protocol/SetTitlePacket.php @@ -49,19 +49,19 @@ class SetTitlePacket extends DataPacket implements ClientboundPacket{ public $fadeOutTime = 0; protected function decodePayload() : void{ - $this->type = $this->getVarInt(); - $this->text = $this->getString(); - $this->fadeInTime = $this->getVarInt(); - $this->stayTime = $this->getVarInt(); - $this->fadeOutTime = $this->getVarInt(); + $this->type = $this->buf->getVarInt(); + $this->text = $this->buf->getString(); + $this->fadeInTime = $this->buf->getVarInt(); + $this->stayTime = $this->buf->getVarInt(); + $this->fadeOutTime = $this->buf->getVarInt(); } protected function encodePayload() : void{ - $this->putVarInt($this->type); - $this->putString($this->text); - $this->putVarInt($this->fadeInTime); - $this->putVarInt($this->stayTime); - $this->putVarInt($this->fadeOutTime); + $this->buf->putVarInt($this->type); + $this->buf->putString($this->text); + $this->buf->putVarInt($this->fadeInTime); + $this->buf->putVarInt($this->stayTime); + $this->buf->putVarInt($this->fadeOutTime); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SettingsCommandPacket.php b/src/network/mcpe/protocol/SettingsCommandPacket.php index 8752a8a0fe..0844494551 100644 --- a/src/network/mcpe/protocol/SettingsCommandPacket.php +++ b/src/network/mcpe/protocol/SettingsCommandPacket.php @@ -51,13 +51,13 @@ class SettingsCommandPacket extends DataPacket implements ServerboundPacket{ } protected function decodePayload() : void{ - $this->command = $this->getString(); - $this->suppressOutput = $this->getBool(); + $this->command = $this->buf->getString(); + $this->suppressOutput = $this->buf->getBool(); } protected function encodePayload() : void{ - $this->putString($this->command); - $this->putBool($this->suppressOutput); + $this->buf->putString($this->command); + $this->buf->putBool($this->suppressOutput); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ShowCreditsPacket.php b/src/network/mcpe/protocol/ShowCreditsPacket.php index d898831f4e..7d58c4cddc 100644 --- a/src/network/mcpe/protocol/ShowCreditsPacket.php +++ b/src/network/mcpe/protocol/ShowCreditsPacket.php @@ -39,13 +39,13 @@ class ShowCreditsPacket extends DataPacket implements ClientboundPacket, Serverb public $status; protected function decodePayload() : void{ - $this->playerEid = $this->getEntityRuntimeId(); - $this->status = $this->getVarInt(); + $this->playerEid = $this->buf->getEntityRuntimeId(); + $this->status = $this->buf->getVarInt(); } protected function encodePayload() : void{ - $this->putEntityRuntimeId($this->playerEid); - $this->putVarInt($this->status); + $this->buf->putEntityRuntimeId($this->playerEid); + $this->buf->putVarInt($this->status); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ShowProfilePacket.php b/src/network/mcpe/protocol/ShowProfilePacket.php index e9e4a900cd..0b78bc2a2d 100644 --- a/src/network/mcpe/protocol/ShowProfilePacket.php +++ b/src/network/mcpe/protocol/ShowProfilePacket.php @@ -34,11 +34,11 @@ class ShowProfilePacket extends DataPacket implements ClientboundPacket{ public $xuid; protected function decodePayload() : void{ - $this->xuid = $this->getString(); + $this->xuid = $this->buf->getString(); } protected function encodePayload() : void{ - $this->putString($this->xuid); + $this->buf->putString($this->xuid); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ShowStoreOfferPacket.php b/src/network/mcpe/protocol/ShowStoreOfferPacket.php index 7cf83dc08f..992dd18f8a 100644 --- a/src/network/mcpe/protocol/ShowStoreOfferPacket.php +++ b/src/network/mcpe/protocol/ShowStoreOfferPacket.php @@ -36,13 +36,13 @@ class ShowStoreOfferPacket extends DataPacket implements ClientboundPacket{ public $showAll; protected function decodePayload() : void{ - $this->offerId = $this->getString(); - $this->showAll = $this->getBool(); + $this->offerId = $this->buf->getString(); + $this->showAll = $this->buf->getBool(); } protected function encodePayload() : void{ - $this->putString($this->offerId); - $this->putBool($this->showAll); + $this->buf->putString($this->offerId); + $this->buf->putBool($this->showAll); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SimpleEventPacket.php b/src/network/mcpe/protocol/SimpleEventPacket.php index 94a43dac23..573fecbe87 100644 --- a/src/network/mcpe/protocol/SimpleEventPacket.php +++ b/src/network/mcpe/protocol/SimpleEventPacket.php @@ -37,11 +37,11 @@ class SimpleEventPacket extends DataPacket implements ClientboundPacket, Serverb public $eventType; protected function decodePayload() : void{ - $this->eventType = $this->getLShort(); + $this->eventType = $this->buf->getLShort(); } protected function encodePayload() : void{ - $this->putLShort($this->eventType); + $this->buf->putLShort($this->eventType); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php b/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php index 0ce2e61254..ea4aed7667 100644 --- a/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php +++ b/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php @@ -37,13 +37,13 @@ class SpawnExperienceOrbPacket extends DataPacket implements ServerboundPacket{ public $amount; protected function decodePayload() : void{ - $this->position = $this->getVector3(); - $this->amount = $this->getVarInt(); + $this->position = $this->buf->getVector3(); + $this->amount = $this->buf->getVarInt(); } protected function encodePayload() : void{ - $this->putVector3($this->position); - $this->putVarInt($this->amount); + $this->buf->putVector3($this->position); + $this->buf->putVarInt($this->amount); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SpawnParticleEffectPacket.php b/src/network/mcpe/protocol/SpawnParticleEffectPacket.php index 36374e5196..692dd8645c 100644 --- a/src/network/mcpe/protocol/SpawnParticleEffectPacket.php +++ b/src/network/mcpe/protocol/SpawnParticleEffectPacket.php @@ -42,17 +42,17 @@ class SpawnParticleEffectPacket extends DataPacket implements ClientboundPacket{ public $particleName; protected function decodePayload() : void{ - $this->dimensionId = $this->getByte(); - $this->entityUniqueId = $this->getEntityUniqueId(); - $this->position = $this->getVector3(); - $this->particleName = $this->getString(); + $this->dimensionId = $this->buf->getByte(); + $this->entityUniqueId = $this->buf->getEntityUniqueId(); + $this->position = $this->buf->getVector3(); + $this->particleName = $this->buf->getString(); } protected function encodePayload() : void{ - $this->putByte($this->dimensionId); - $this->putEntityUniqueId($this->entityUniqueId); - $this->putVector3($this->position); - $this->putString($this->particleName); + $this->buf->putByte($this->dimensionId); + $this->buf->putEntityUniqueId($this->entityUniqueId); + $this->buf->putVector3($this->position); + $this->buf->putString($this->particleName); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/StartGamePacket.php b/src/network/mcpe/protocol/StartGamePacket.php index 90c4fed2ce..43099a9071 100644 --- a/src/network/mcpe/protocol/StartGamePacket.php +++ b/src/network/mcpe/protocol/StartGamePacket.php @@ -163,147 +163,149 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{ public $itemTable = null; protected function decodePayload() : void{ - $this->entityUniqueId = $this->getEntityUniqueId(); - $this->entityRuntimeId = $this->getEntityRuntimeId(); - $this->playerGamemode = $this->getVarInt(); + $this->entityUniqueId = $this->buf->getEntityUniqueId(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + $this->playerGamemode = $this->buf->getVarInt(); - $this->playerPosition = $this->getVector3(); + $this->playerPosition = $this->buf->getVector3(); - $this->pitch = $this->getLFloat(); - $this->yaw = $this->getLFloat(); + $this->pitch = $this->buf->getLFloat(); + $this->yaw = $this->buf->getLFloat(); //Level settings - $this->seed = $this->getVarInt(); - $this->dimension = $this->getVarInt(); - $this->generator = $this->getVarInt(); - $this->worldGamemode = $this->getVarInt(); - $this->difficulty = $this->getVarInt(); - $this->getBlockPosition($this->spawnX, $this->spawnY, $this->spawnZ); - $this->hasAchievementsDisabled = $this->getBool(); - $this->time = $this->getVarInt(); - $this->eduEditionOffer = $this->getVarInt(); - $this->hasEduFeaturesEnabled = $this->getBool(); - $this->rainLevel = $this->getLFloat(); - $this->lightningLevel = $this->getLFloat(); - $this->hasConfirmedPlatformLockedContent = $this->getBool(); - $this->isMultiplayerGame = $this->getBool(); - $this->hasLANBroadcast = $this->getBool(); - $this->xboxLiveBroadcastMode = $this->getVarInt(); - $this->platformBroadcastMode = $this->getVarInt(); - $this->commandsEnabled = $this->getBool(); - $this->isTexturePacksRequired = $this->getBool(); - $this->gameRules = $this->getGameRules(); - $this->hasBonusChestEnabled = $this->getBool(); - $this->hasStartWithMapEnabled = $this->getBool(); - $this->defaultPlayerPermission = $this->getVarInt(); - $this->serverChunkTickRadius = $this->getLInt(); - $this->hasLockedBehaviorPack = $this->getBool(); - $this->hasLockedResourcePack = $this->getBool(); - $this->isFromLockedWorldTemplate = $this->getBool(); - $this->useMsaGamertagsOnly = $this->getBool(); - $this->isFromWorldTemplate = $this->getBool(); - $this->isWorldTemplateOptionLocked = $this->getBool(); - $this->onlySpawnV1Villagers = $this->getBool(); + $this->seed = $this->buf->getVarInt(); + $this->dimension = $this->buf->getVarInt(); + $this->generator = $this->buf->getVarInt(); + $this->worldGamemode = $this->buf->getVarInt(); + $this->difficulty = $this->buf->getVarInt(); + $this->buf->getBlockPosition($this->spawnX, $this->spawnY, $this->spawnZ); + $this->hasAchievementsDisabled = $this->buf->getBool(); + $this->time = $this->buf->getVarInt(); + $this->eduEditionOffer = $this->buf->getVarInt(); + $this->hasEduFeaturesEnabled = $this->buf->getBool(); + $this->rainLevel = $this->buf->getLFloat(); + $this->lightningLevel = $this->buf->getLFloat(); + $this->hasConfirmedPlatformLockedContent = $this->buf->getBool(); + $this->isMultiplayerGame = $this->buf->getBool(); + $this->hasLANBroadcast = $this->buf->getBool(); + $this->xboxLiveBroadcastMode = $this->buf->getVarInt(); + $this->platformBroadcastMode = $this->buf->getVarInt(); + $this->commandsEnabled = $this->buf->getBool(); + $this->isTexturePacksRequired = $this->buf->getBool(); + $this->gameRules = $this->buf->getGameRules(); + $this->hasBonusChestEnabled = $this->buf->getBool(); + $this->hasStartWithMapEnabled = $this->buf->getBool(); + $this->defaultPlayerPermission = $this->buf->getVarInt(); + $this->serverChunkTickRadius = $this->buf->getLInt(); + $this->hasLockedBehaviorPack = $this->buf->getBool(); + $this->hasLockedResourcePack = $this->buf->getBool(); + $this->isFromLockedWorldTemplate = $this->buf->getBool(); + $this->useMsaGamertagsOnly = $this->buf->getBool(); + $this->isFromWorldTemplate = $this->buf->getBool(); + $this->isWorldTemplateOptionLocked = $this->buf->getBool(); + $this->onlySpawnV1Villagers = $this->buf->getBool(); - $this->vanillaVersion = $this->getString(); - $this->levelId = $this->getString(); - $this->worldName = $this->getString(); - $this->premiumWorldTemplateId = $this->getString(); - $this->isTrial = $this->getBool(); - $this->isMovementServerAuthoritative = $this->getBool(); - $this->currentTick = $this->getLLong(); + $this->vanillaVersion = $this->buf->getString(); + $this->levelId = $this->buf->getString(); + $this->worldName = $this->buf->getString(); + $this->premiumWorldTemplateId = $this->buf->getString(); + $this->isTrial = $this->buf->getBool(); + $this->isMovementServerAuthoritative = $this->buf->getBool(); + $this->currentTick = $this->buf->getLLong(); - $this->enchantmentSeed = $this->getVarInt(); + $this->enchantmentSeed = $this->buf->getVarInt(); - $blockTable = (new NetworkNbtSerializer())->read($this->buffer, $this->offset, 512)->getTag(); + $offset = $this->buf->getOffset(); + $blockTable = (new NetworkNbtSerializer())->read($this->buf->getBuffer(), $offset, 512)->getTag(); + $this->buf->setOffset($offset); if(!($blockTable instanceof ListTag)){ throw new \UnexpectedValueException("Wrong block table root NBT tag type"); } $this->blockTable = $blockTable; $this->itemTable = []; - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ - $id = $this->getString(); - $legacyId = $this->getSignedLShort(); + for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ + $id = $this->buf->getString(); + $legacyId = $this->buf->getSignedLShort(); $this->itemTable[$id] = $legacyId; } - $this->multiplayerCorrelationId = $this->getString(); + $this->multiplayerCorrelationId = $this->buf->getString(); } protected function encodePayload() : void{ - $this->putEntityUniqueId($this->entityUniqueId); - $this->putEntityRuntimeId($this->entityRuntimeId); - $this->putVarInt($this->playerGamemode); + $this->buf->putEntityUniqueId($this->entityUniqueId); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putVarInt($this->playerGamemode); - $this->putVector3($this->playerPosition); + $this->buf->putVector3($this->playerPosition); - $this->putLFloat($this->pitch); - $this->putLFloat($this->yaw); + $this->buf->putLFloat($this->pitch); + $this->buf->putLFloat($this->yaw); //Level settings - $this->putVarInt($this->seed); - $this->putVarInt($this->dimension); - $this->putVarInt($this->generator); - $this->putVarInt($this->worldGamemode); - $this->putVarInt($this->difficulty); - $this->putBlockPosition($this->spawnX, $this->spawnY, $this->spawnZ); - $this->putBool($this->hasAchievementsDisabled); - $this->putVarInt($this->time); - $this->putVarInt($this->eduEditionOffer); - $this->putBool($this->hasEduFeaturesEnabled); - $this->putLFloat($this->rainLevel); - $this->putLFloat($this->lightningLevel); - $this->putBool($this->hasConfirmedPlatformLockedContent); - $this->putBool($this->isMultiplayerGame); - $this->putBool($this->hasLANBroadcast); - $this->putVarInt($this->xboxLiveBroadcastMode); - $this->putVarInt($this->platformBroadcastMode); - $this->putBool($this->commandsEnabled); - $this->putBool($this->isTexturePacksRequired); - $this->putGameRules($this->gameRules); - $this->putBool($this->hasBonusChestEnabled); - $this->putBool($this->hasStartWithMapEnabled); - $this->putVarInt($this->defaultPlayerPermission); - $this->putLInt($this->serverChunkTickRadius); - $this->putBool($this->hasLockedBehaviorPack); - $this->putBool($this->hasLockedResourcePack); - $this->putBool($this->isFromLockedWorldTemplate); - $this->putBool($this->useMsaGamertagsOnly); - $this->putBool($this->isFromWorldTemplate); - $this->putBool($this->isWorldTemplateOptionLocked); - $this->putBool($this->onlySpawnV1Villagers); + $this->buf->putVarInt($this->seed); + $this->buf->putVarInt($this->dimension); + $this->buf->putVarInt($this->generator); + $this->buf->putVarInt($this->worldGamemode); + $this->buf->putVarInt($this->difficulty); + $this->buf->putBlockPosition($this->spawnX, $this->spawnY, $this->spawnZ); + $this->buf->putBool($this->hasAchievementsDisabled); + $this->buf->putVarInt($this->time); + $this->buf->putVarInt($this->eduEditionOffer); + $this->buf->putBool($this->hasEduFeaturesEnabled); + $this->buf->putLFloat($this->rainLevel); + $this->buf->putLFloat($this->lightningLevel); + $this->buf->putBool($this->hasConfirmedPlatformLockedContent); + $this->buf->putBool($this->isMultiplayerGame); + $this->buf->putBool($this->hasLANBroadcast); + $this->buf->putVarInt($this->xboxLiveBroadcastMode); + $this->buf->putVarInt($this->platformBroadcastMode); + $this->buf->putBool($this->commandsEnabled); + $this->buf->putBool($this->isTexturePacksRequired); + $this->buf->putGameRules($this->gameRules); + $this->buf->putBool($this->hasBonusChestEnabled); + $this->buf->putBool($this->hasStartWithMapEnabled); + $this->buf->putVarInt($this->defaultPlayerPermission); + $this->buf->putLInt($this->serverChunkTickRadius); + $this->buf->putBool($this->hasLockedBehaviorPack); + $this->buf->putBool($this->hasLockedResourcePack); + $this->buf->putBool($this->isFromLockedWorldTemplate); + $this->buf->putBool($this->useMsaGamertagsOnly); + $this->buf->putBool($this->isFromWorldTemplate); + $this->buf->putBool($this->isWorldTemplateOptionLocked); + $this->buf->putBool($this->onlySpawnV1Villagers); - $this->putString($this->vanillaVersion); - $this->putString($this->levelId); - $this->putString($this->worldName); - $this->putString($this->premiumWorldTemplateId); - $this->putBool($this->isTrial); - $this->putBool($this->isMovementServerAuthoritative); - $this->putLLong($this->currentTick); + $this->buf->putString($this->vanillaVersion); + $this->buf->putString($this->levelId); + $this->buf->putString($this->worldName); + $this->buf->putString($this->premiumWorldTemplateId); + $this->buf->putBool($this->isTrial); + $this->buf->putBool($this->isMovementServerAuthoritative); + $this->buf->putLLong($this->currentTick); - $this->putVarInt($this->enchantmentSeed); + $this->buf->putVarInt($this->enchantmentSeed); if($this->blockTable === null){ if(self::$blockTableCache === null){ //this is a really nasty hack, but it'll do for now self::$blockTableCache = (new NetworkNbtSerializer())->write(new TreeRoot(new ListTag(RuntimeBlockMapping::getBedrockKnownStates()))); } - $this->put(self::$blockTableCache); + $this->buf->put(self::$blockTableCache); }else{ - $this->put((new NetworkNbtSerializer())->write(new TreeRoot($this->blockTable))); + $this->buf->put((new NetworkNbtSerializer())->write(new TreeRoot($this->blockTable))); } if($this->itemTable === null){ if(self::$itemTableCache === null){ self::$itemTableCache = self::serializeItemTable(json_decode(file_get_contents(RESOURCE_PATH . '/vanilla/item_id_map.json'), true)); } - $this->put(self::$itemTableCache); + $this->buf->put(self::$itemTableCache); }else{ - $this->put(self::serializeItemTable($this->itemTable)); + $this->buf->put(self::serializeItemTable($this->itemTable)); } - $this->putString($this->multiplayerCorrelationId); + $this->buf->putString($this->multiplayerCorrelationId); } /** diff --git a/src/network/mcpe/protocol/StopSoundPacket.php b/src/network/mcpe/protocol/StopSoundPacket.php index 72460d70d2..4a61eea6bf 100644 --- a/src/network/mcpe/protocol/StopSoundPacket.php +++ b/src/network/mcpe/protocol/StopSoundPacket.php @@ -36,13 +36,13 @@ class StopSoundPacket extends DataPacket implements ClientboundPacket{ public $stopAll; protected function decodePayload() : void{ - $this->soundName = $this->getString(); - $this->stopAll = $this->getBool(); + $this->soundName = $this->buf->getString(); + $this->stopAll = $this->buf->getBool(); } protected function encodePayload() : void{ - $this->putString($this->soundName); - $this->putBool($this->stopAll); + $this->buf->putString($this->soundName); + $this->buf->putBool($this->stopAll); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php b/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php index 847e457e67..b2c52ea31c 100644 --- a/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php +++ b/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php @@ -48,17 +48,17 @@ class StructureTemplateDataRequestPacket extends DataPacket implements Serverbou public $structureTemplateResponseType; protected function decodePayload() : void{ - $this->structureTemplateName = $this->getString(); - $this->getBlockPosition($this->structureBlockX, $this->structureBlockY, $this->structureBlockZ); - $this->structureSettings = $this->getStructureSettings(); - $this->structureTemplateResponseType = $this->getByte(); + $this->structureTemplateName = $this->buf->getString(); + $this->buf->getBlockPosition($this->structureBlockX, $this->structureBlockY, $this->structureBlockZ); + $this->structureSettings = $this->buf->getStructureSettings(); + $this->structureTemplateResponseType = $this->buf->getByte(); } protected function encodePayload() : void{ - $this->putString($this->structureTemplateName); - $this->putBlockPosition($this->structureBlockX, $this->structureBlockY, $this->structureBlockZ); - $this->putStructureSettings($this->structureSettings); - $this->putByte($this->structureTemplateResponseType); + $this->buf->putString($this->structureTemplateName); + $this->buf->putBlockPosition($this->structureBlockX, $this->structureBlockY, $this->structureBlockZ); + $this->buf->putStructureSettings($this->structureSettings); + $this->buf->putByte($this->structureTemplateResponseType); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php b/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php index 0f4d2b40fc..7d81ac3eef 100644 --- a/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php +++ b/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php @@ -36,17 +36,17 @@ class StructureTemplateDataResponsePacket extends DataPacket implements Clientbo public $namedtag; protected function decodePayload() : void{ - $this->structureTemplateName = $this->getString(); - if($this->getBool()){ - $this->namedtag = $this->getRemaining(); + $this->structureTemplateName = $this->buf->getString(); + if($this->buf->getBool()){ + $this->namedtag = $this->buf->getRemaining(); } } protected function encodePayload() : void{ - $this->putString($this->structureTemplateName); - $this->putBool($this->namedtag !== null); + $this->buf->putString($this->structureTemplateName); + $this->buf->putBool($this->namedtag !== null); if($this->namedtag !== null){ - $this->put($this->namedtag); + $this->buf->put($this->namedtag); } } diff --git a/src/network/mcpe/protocol/SubClientLoginPacket.php b/src/network/mcpe/protocol/SubClientLoginPacket.php index 8be6b0e985..90a4fa1b1d 100644 --- a/src/network/mcpe/protocol/SubClientLoginPacket.php +++ b/src/network/mcpe/protocol/SubClientLoginPacket.php @@ -34,11 +34,11 @@ class SubClientLoginPacket extends DataPacket implements ServerboundPacket{ public $connectionRequestData; protected function decodePayload() : void{ - $this->connectionRequestData = $this->getString(); + $this->connectionRequestData = $this->buf->getString(); } protected function encodePayload() : void{ - $this->putString($this->connectionRequestData); + $this->buf->putString($this->connectionRequestData); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/TakeItemActorPacket.php b/src/network/mcpe/protocol/TakeItemActorPacket.php index 1968922ddb..e3b768afe4 100644 --- a/src/network/mcpe/protocol/TakeItemActorPacket.php +++ b/src/network/mcpe/protocol/TakeItemActorPacket.php @@ -43,13 +43,13 @@ class TakeItemActorPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->target = $this->getEntityRuntimeId(); - $this->eid = $this->getEntityRuntimeId(); + $this->target = $this->buf->getEntityRuntimeId(); + $this->eid = $this->buf->getEntityRuntimeId(); } protected function encodePayload() : void{ - $this->putEntityRuntimeId($this->target); - $this->putEntityRuntimeId($this->eid); + $this->buf->putEntityRuntimeId($this->target); + $this->buf->putEntityRuntimeId($this->eid); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/TextPacket.php b/src/network/mcpe/protocol/TextPacket.php index 5594b9e657..0e37555c63 100644 --- a/src/network/mcpe/protocol/TextPacket.php +++ b/src/network/mcpe/protocol/TextPacket.php @@ -116,65 +116,65 @@ class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPac } protected function decodePayload() : void{ - $this->type = $this->getByte(); - $this->needsTranslation = $this->getBool(); + $this->type = $this->buf->getByte(); + $this->needsTranslation = $this->buf->getBool(); switch($this->type){ case self::TYPE_CHAT: case self::TYPE_WHISPER: /** @noinspection PhpMissingBreakStatementInspection */ case self::TYPE_ANNOUNCEMENT: - $this->sourceName = $this->getString(); + $this->sourceName = $this->buf->getString(); case self::TYPE_RAW: case self::TYPE_TIP: case self::TYPE_SYSTEM: case self::TYPE_JSON: - $this->message = $this->getString(); + $this->message = $this->buf->getString(); break; case self::TYPE_TRANSLATION: case self::TYPE_POPUP: case self::TYPE_JUKEBOX_POPUP: - $this->message = $this->getString(); - $count = $this->getUnsignedVarInt(); + $this->message = $this->buf->getString(); + $count = $this->buf->getUnsignedVarInt(); for($i = 0; $i < $count; ++$i){ - $this->parameters[] = $this->getString(); + $this->parameters[] = $this->buf->getString(); } break; } - $this->xboxUserId = $this->getString(); - $this->platformChatId = $this->getString(); + $this->xboxUserId = $this->buf->getString(); + $this->platformChatId = $this->buf->getString(); } protected function encodePayload() : void{ - $this->putByte($this->type); - $this->putBool($this->needsTranslation); + $this->buf->putByte($this->type); + $this->buf->putBool($this->needsTranslation); switch($this->type){ case self::TYPE_CHAT: case self::TYPE_WHISPER: /** @noinspection PhpMissingBreakStatementInspection */ case self::TYPE_ANNOUNCEMENT: - $this->putString($this->sourceName); + $this->buf->putString($this->sourceName); case self::TYPE_RAW: case self::TYPE_TIP: case self::TYPE_SYSTEM: case self::TYPE_JSON: - $this->putString($this->message); + $this->buf->putString($this->message); break; case self::TYPE_TRANSLATION: case self::TYPE_POPUP: case self::TYPE_JUKEBOX_POPUP: - $this->putString($this->message); - $this->putUnsignedVarInt(count($this->parameters)); + $this->buf->putString($this->message); + $this->buf->putUnsignedVarInt(count($this->parameters)); foreach($this->parameters as $p){ - $this->putString($p); + $this->buf->putString($p); } break; } - $this->putString($this->xboxUserId); - $this->putString($this->platformChatId); + $this->buf->putString($this->xboxUserId); + $this->buf->putString($this->platformChatId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/TickSyncPacket.php b/src/network/mcpe/protocol/TickSyncPacket.php index b8982efba9..c192f6d62c 100644 --- a/src/network/mcpe/protocol/TickSyncPacket.php +++ b/src/network/mcpe/protocol/TickSyncPacket.php @@ -58,13 +58,13 @@ class TickSyncPacket extends DataPacket implements ClientboundPacket, Serverboun } protected function decodePayload() : void{ - $this->clientSendTime = $this->getLLong(); - $this->serverReceiveTime = $this->getLLong(); + $this->clientSendTime = $this->buf->getLLong(); + $this->serverReceiveTime = $this->buf->getLLong(); } protected function encodePayload() : void{ - $this->putLLong($this->clientSendTime); - $this->putLLong($this->serverReceiveTime); + $this->buf->putLLong($this->clientSendTime); + $this->buf->putLLong($this->serverReceiveTime); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/TransferPacket.php b/src/network/mcpe/protocol/TransferPacket.php index 58170bd867..d02d1e5341 100644 --- a/src/network/mcpe/protocol/TransferPacket.php +++ b/src/network/mcpe/protocol/TransferPacket.php @@ -43,13 +43,13 @@ class TransferPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->address = $this->getString(); - $this->port = $this->getLShort(); + $this->address = $this->buf->getString(); + $this->port = $this->buf->getLShort(); } protected function encodePayload() : void{ - $this->putString($this->address); - $this->putLShort($this->port); + $this->buf->putString($this->address); + $this->buf->putLShort($this->port); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/UnknownPacket.php b/src/network/mcpe/protocol/UnknownPacket.php index 184115b07c..dee77cce62 100644 --- a/src/network/mcpe/protocol/UnknownPacket.php +++ b/src/network/mcpe/protocol/UnknownPacket.php @@ -49,7 +49,7 @@ class UnknownPacket extends DataPacket{ } protected function decodePayload() : void{ - $this->payload = $this->getRemaining(); + $this->payload = $this->buf->getRemaining(); } protected function encodeHeader() : void{ @@ -57,7 +57,7 @@ class UnknownPacket extends DataPacket{ } protected function encodePayload() : void{ - $this->put($this->payload); + $this->buf->put($this->payload); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/UpdateAttributesPacket.php b/src/network/mcpe/protocol/UpdateAttributesPacket.php index 18a7e7acec..4f14f13d8b 100644 --- a/src/network/mcpe/protocol/UpdateAttributesPacket.php +++ b/src/network/mcpe/protocol/UpdateAttributesPacket.php @@ -50,13 +50,13 @@ class UpdateAttributesPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->entityRuntimeId = $this->getEntityRuntimeId(); - $this->entries = $this->getAttributeList(); + $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + $this->entries = $this->buf->getAttributeList(); } protected function encodePayload() : void{ - $this->putEntityRuntimeId($this->entityRuntimeId); - $this->putAttributeList(...array_values($this->entries)); + $this->buf->putEntityRuntimeId($this->entityRuntimeId); + $this->buf->putAttributeList(...array_values($this->entries)); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/UpdateBlockPacket.php b/src/network/mcpe/protocol/UpdateBlockPacket.php index 46729ab80d..314999ef64 100644 --- a/src/network/mcpe/protocol/UpdateBlockPacket.php +++ b/src/network/mcpe/protocol/UpdateBlockPacket.php @@ -59,17 +59,17 @@ class UpdateBlockPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload() : void{ - $this->getBlockPosition($this->x, $this->y, $this->z); - $this->blockRuntimeId = $this->getUnsignedVarInt(); - $this->flags = $this->getUnsignedVarInt(); - $this->dataLayerId = $this->getUnsignedVarInt(); + $this->buf->getBlockPosition($this->x, $this->y, $this->z); + $this->blockRuntimeId = $this->buf->getUnsignedVarInt(); + $this->flags = $this->buf->getUnsignedVarInt(); + $this->dataLayerId = $this->buf->getUnsignedVarInt(); } protected function encodePayload() : void{ - $this->putBlockPosition($this->x, $this->y, $this->z); - $this->putUnsignedVarInt($this->blockRuntimeId); - $this->putUnsignedVarInt($this->flags); - $this->putUnsignedVarInt($this->dataLayerId); + $this->buf->putBlockPosition($this->x, $this->y, $this->z); + $this->buf->putUnsignedVarInt($this->blockRuntimeId); + $this->buf->putUnsignedVarInt($this->flags); + $this->buf->putUnsignedVarInt($this->dataLayerId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php b/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php index f0f1d41f43..1ab72c79dd 100644 --- a/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php +++ b/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php @@ -43,11 +43,11 @@ class UpdateBlockPropertiesPacket extends DataPacket implements ClientboundPacke } protected function decodePayload() : void{ - $this->nbt = $this->getRemaining(); + $this->nbt = $this->buf->getRemaining(); } protected function encodePayload() : void{ - $this->put($this->nbt); + $this->buf->put($this->nbt); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php b/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php index f5c6fdc225..ace3894d86 100644 --- a/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php +++ b/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php @@ -37,14 +37,14 @@ class UpdateBlockSyncedPacket extends UpdateBlockPacket{ protected function decodePayload() : void{ parent::decodePayload(); - $this->entityUniqueId = $this->getUnsignedVarLong(); - $this->uvarint64_2 = $this->getUnsignedVarLong(); + $this->entityUniqueId = $this->buf->getUnsignedVarLong(); + $this->uvarint64_2 = $this->buf->getUnsignedVarLong(); } protected function encodePayload() : void{ parent::encodePayload(); - $this->putUnsignedVarLong($this->entityUniqueId); - $this->putUnsignedVarLong($this->uvarint64_2); + $this->buf->putUnsignedVarLong($this->entityUniqueId); + $this->buf->putUnsignedVarLong($this->uvarint64_2); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/UpdateEquipPacket.php b/src/network/mcpe/protocol/UpdateEquipPacket.php index 594a505166..9567e865fc 100644 --- a/src/network/mcpe/protocol/UpdateEquipPacket.php +++ b/src/network/mcpe/protocol/UpdateEquipPacket.php @@ -42,19 +42,19 @@ class UpdateEquipPacket extends DataPacket implements ClientboundPacket{ public $namedtag; protected function decodePayload() : void{ - $this->windowId = $this->getByte(); - $this->windowType = $this->getByte(); - $this->unknownVarint = $this->getVarInt(); - $this->entityUniqueId = $this->getEntityUniqueId(); - $this->namedtag = $this->getRemaining(); + $this->windowId = $this->buf->getByte(); + $this->windowType = $this->buf->getByte(); + $this->unknownVarint = $this->buf->getVarInt(); + $this->entityUniqueId = $this->buf->getEntityUniqueId(); + $this->namedtag = $this->buf->getRemaining(); } protected function encodePayload() : void{ - $this->putByte($this->windowId); - $this->putByte($this->windowType); - $this->putVarInt($this->unknownVarint); - $this->putEntityUniqueId($this->entityUniqueId); - $this->put($this->namedtag); + $this->buf->putByte($this->windowId); + $this->buf->putByte($this->windowType); + $this->buf->putVarInt($this->unknownVarint); + $this->buf->putEntityUniqueId($this->entityUniqueId); + $this->buf->put($this->namedtag); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/UpdateSoftEnumPacket.php b/src/network/mcpe/protocol/UpdateSoftEnumPacket.php index d20f186d76..5744a02c40 100644 --- a/src/network/mcpe/protocol/UpdateSoftEnumPacket.php +++ b/src/network/mcpe/protocol/UpdateSoftEnumPacket.php @@ -43,20 +43,20 @@ class UpdateSoftEnumPacket extends DataPacket implements ClientboundPacket{ public $type; protected function decodePayload() : void{ - $this->enumName = $this->getString(); - for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){ - $this->values[] = $this->getString(); + $this->enumName = $this->buf->getString(); + for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ + $this->values[] = $this->buf->getString(); } - $this->type = $this->getByte(); + $this->type = $this->buf->getByte(); } protected function encodePayload() : void{ - $this->putString($this->enumName); - $this->putUnsignedVarInt(count($this->values)); + $this->buf->putString($this->enumName); + $this->buf->putUnsignedVarInt(count($this->values)); foreach($this->values as $v){ - $this->putString($v); + $this->buf->putString($v); } - $this->putByte($this->type); + $this->buf->putByte($this->type); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/UpdateTradePacket.php b/src/network/mcpe/protocol/UpdateTradePacket.php index 08d01c76d1..b581dd9261 100644 --- a/src/network/mcpe/protocol/UpdateTradePacket.php +++ b/src/network/mcpe/protocol/UpdateTradePacket.php @@ -55,29 +55,29 @@ class UpdateTradePacket extends DataPacket implements ClientboundPacket{ public $offers; protected function decodePayload() : void{ - $this->windowId = $this->getByte(); - $this->windowType = $this->getByte(); - $this->thisIsAlwaysZero = $this->getVarInt(); - $this->tradeTier = $this->getVarInt(); - $this->traderEid = $this->getEntityUniqueId(); - $this->playerEid = $this->getEntityUniqueId(); - $this->displayName = $this->getString(); - $this->isWilling = $this->getBool(); - $this->isV2Trading = $this->getBool(); - $this->offers = $this->getRemaining(); + $this->windowId = $this->buf->getByte(); + $this->windowType = $this->buf->getByte(); + $this->thisIsAlwaysZero = $this->buf->getVarInt(); + $this->tradeTier = $this->buf->getVarInt(); + $this->traderEid = $this->buf->getEntityUniqueId(); + $this->playerEid = $this->buf->getEntityUniqueId(); + $this->displayName = $this->buf->getString(); + $this->isWilling = $this->buf->getBool(); + $this->isV2Trading = $this->buf->getBool(); + $this->offers = $this->buf->getRemaining(); } protected function encodePayload() : void{ - $this->putByte($this->windowId); - $this->putByte($this->windowType); - $this->putVarInt($this->thisIsAlwaysZero); - $this->putVarInt($this->tradeTier); - $this->putEntityUniqueId($this->traderEid); - $this->putEntityUniqueId($this->playerEid); - $this->putString($this->displayName); - $this->putBool($this->isWilling); - $this->putBool($this->isV2Trading); - $this->put($this->offers); + $this->buf->putByte($this->windowId); + $this->buf->putByte($this->windowType); + $this->buf->putVarInt($this->thisIsAlwaysZero); + $this->buf->putVarInt($this->tradeTier); + $this->buf->putEntityUniqueId($this->traderEid); + $this->buf->putEntityUniqueId($this->playerEid); + $this->buf->putString($this->displayName); + $this->buf->putBool($this->isWilling); + $this->buf->putBool($this->isV2Trading); + $this->buf->put($this->offers); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/VideoStreamConnectPacket.php b/src/network/mcpe/protocol/VideoStreamConnectPacket.php index ba7f643bf5..d599b2a61b 100644 --- a/src/network/mcpe/protocol/VideoStreamConnectPacket.php +++ b/src/network/mcpe/protocol/VideoStreamConnectPacket.php @@ -45,19 +45,19 @@ class VideoStreamConnectPacket extends DataPacket implements ClientboundPacket{ public $resolutionY; protected function decodePayload() : void{ - $this->serverUri = $this->getString(); - $this->frameSendFrequency = $this->getLFloat(); - $this->action = $this->getByte(); - $this->resolutionX = $this->getLInt(); - $this->resolutionY = $this->getLInt(); + $this->serverUri = $this->buf->getString(); + $this->frameSendFrequency = $this->buf->getLFloat(); + $this->action = $this->buf->getByte(); + $this->resolutionX = $this->buf->getLInt(); + $this->resolutionY = $this->buf->getLInt(); } protected function encodePayload() : void{ - $this->putString($this->serverUri); - $this->putLFloat($this->frameSendFrequency); - $this->putByte($this->action); - $this->putLInt($this->resolutionX); - $this->putLInt($this->resolutionY); + $this->buf->putString($this->serverUri); + $this->buf->putLFloat($this->frameSendFrequency); + $this->buf->putByte($this->action); + $this->buf->putLInt($this->resolutionX); + $this->buf->putLInt($this->resolutionY); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/serializer/NetworkBinaryStream.php b/src/network/mcpe/serializer/NetworkBinaryStream.php index b1618ac16a..5248a8998b 100644 --- a/src/network/mcpe/serializer/NetworkBinaryStream.php +++ b/src/network/mcpe/serializer/NetworkBinaryStream.php @@ -595,7 +595,7 @@ class NetworkBinaryStream extends BinaryStream{ /** * @throws BinaryDataException */ - protected function getEntityLink() : EntityLink{ + public function getEntityLink() : EntityLink{ $link = new EntityLink(); $link->fromEntityUniqueId = $this->getEntityUniqueId(); @@ -606,7 +606,7 @@ class NetworkBinaryStream extends BinaryStream{ return $link; } - protected function putEntityLink(EntityLink $link) : void{ + public function putEntityLink(EntityLink $link) : void{ $this->putEntityUniqueId($link->fromEntityUniqueId); $this->putEntityUniqueId($link->toEntityUniqueId); $this->putByte($link->type); @@ -616,7 +616,7 @@ class NetworkBinaryStream extends BinaryStream{ /** * @throws BinaryDataException */ - protected function getCommandOriginData() : CommandOriginData{ + public function getCommandOriginData() : CommandOriginData{ $result = new CommandOriginData(); $result->type = $this->getUnsignedVarInt(); @@ -630,7 +630,7 @@ class NetworkBinaryStream extends BinaryStream{ return $result; } - protected function putCommandOriginData(CommandOriginData $data) : void{ + public function putCommandOriginData(CommandOriginData $data) : void{ $this->putUnsignedVarInt($data->type); $this->putUUID($data->uuid); $this->putString($data->requestId); @@ -640,7 +640,7 @@ class NetworkBinaryStream extends BinaryStream{ } } - protected function getStructureSettings() : StructureSettings{ + public function getStructureSettings() : StructureSettings{ $result = new StructureSettings(); $result->paletteName = $this->getString(); @@ -660,7 +660,7 @@ class NetworkBinaryStream extends BinaryStream{ return $result; } - protected function putStructureSettings(StructureSettings $structureSettings) : void{ + public function putStructureSettings(StructureSettings $structureSettings) : void{ $this->putString($structureSettings->paletteName); $this->putBool($structureSettings->ignoreEntities); From e279672d4515bd0472dc8fae5257350e68809bbd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 24 Feb 2020 22:00:03 +0000 Subject: [PATCH 1407/3224] updated pocketmine/nbt dependency --- composer.lock | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/composer.lock b/composer.lock index 67ebdef4ba..3e98a2d590 100644 --- a/composer.lock +++ b/composer.lock @@ -443,12 +443,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "c81711e2110545880f5d9a76028b7987d2ac5e32" + "reference": "1cdf6aec3024e2061b8c3e5045c43250df94a740" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/c81711e2110545880f5d9a76028b7987d2ac5e32", - "reference": "c81711e2110545880f5d9a76028b7987d2ac5e32", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/1cdf6aec3024e2061b8c3e5045c43250df94a740", + "reference": "1cdf6aec3024e2061b8c3e5045c43250df94a740", "shasum": "" }, "require": { @@ -459,7 +459,7 @@ }, "require-dev": { "irstea/phpunit-shim": "^7.5", - "phpstan/phpstan": "^0.12.8" + "phpstan/phpstan": "^0.12.11" }, "type": "library", "autoload": { @@ -472,7 +472,7 @@ "LGPL-3.0" ], "description": "PHP library for working with Named Binary Tags", - "time": "2020-01-28T17:04:17+00:00" + "time": "2020-02-24T21:43:33+00:00" }, { "name": "pocketmine/raklib", @@ -591,7 +591,7 @@ "source": { "type": "git", "url": "https://gitlab.irstea.fr/pole-is/tools/phpunit-shim.git", - "reference": "8ec63f895972681271191821a36f9081c236b993" + "reference": "39b6155954d6caec1110a9e78582c4816ab247bc" }, "require": { "ext-dom": "*", @@ -613,11 +613,6 @@ "phpunit" ], "type": "library", - "autoload": { - "exclude-from-classmap": [ - "phpunit" - ] - }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" @@ -637,7 +632,7 @@ "testing", "xunit" ], - "time": "2020-01-23T13:39:47+00:00" + "time": "2020-01-09T03:20:20+00:00" }, { "name": "phpstan/phpstan", From a633e415ef713d5a256aa8ab48fa01149e40ac18 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 25 Feb 2020 15:08:53 +0000 Subject: [PATCH 1408/3224] FastChunkSerializer: use machine endianness for pack() (thanks @Frago9876543210) this is faster due to not having to reverse bytes. Since we don't use this format for persistence, it's OK to use machine byte order for this. --- src/world/format/io/FastChunkSerializer.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index cbdefee35b..76aa5b77e9 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -76,7 +76,7 @@ final class FastChunkSerializer{ $stream->putByte($blocks->getBitsPerBlock()); $stream->put($wordArray); - $serialPalette = pack("N*", ...$palette); + $serialPalette = pack("L*", ...$palette); $stream->putInt(strlen($serialPalette)); $stream->put($serialPalette); } @@ -90,7 +90,7 @@ final class FastChunkSerializer{ //biomes $stream->put($chunk->getBiomeIdArray()); if($includeLight){ - $stream->put(pack("v*", ...$chunk->getHeightMapArray())); + $stream->put(pack("S*", ...$chunk->getHeightMapArray())); } } @@ -123,7 +123,7 @@ final class FastChunkSerializer{ for($i = 0, $layerCount = $stream->getByte(); $i < $layerCount; ++$i){ $bitsPerBlock = $stream->getByte(); $words = $stream->get(PalettedBlockArray::getExpectedWordArraySize($bitsPerBlock)); - $palette = array_values(unpack("N*", $stream->get($stream->getInt()))); + $palette = array_values(unpack("L*", $stream->get($stream->getInt()))); $layers[] = PalettedBlockArray::fromData($bitsPerBlock, $words, $palette); } @@ -134,7 +134,7 @@ final class FastChunkSerializer{ $biomeIds = $stream->get(256); if($lightPopulated){ - $heightMap = array_values(unpack("v*", $stream->get(512))); + $heightMap = array_values(unpack("S*", $stream->get(512))); } } From 5c2ae0257c33076ad9dde94f6c2c1d4d1ffb0af9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 25 Feb 2020 16:19:11 +0000 Subject: [PATCH 1409/3224] DataPacket: inject buffer via parameter instead of class field (packet & stream separation, step 2) this is not complete yet, but the final change (having the binarystream actually come from outside) is a little more disruptive, and some extra changes need to be made. This will grant some sanity in the meantime without breaking too much stuff. --- .../mcpe/protocol/ActorEventPacket.php | 17 +- src/network/mcpe/protocol/ActorFallPacket.php | 17 +- .../mcpe/protocol/ActorPickRequestPacket.php | 13 +- src/network/mcpe/protocol/AddActorPacket.php | 69 +++--- .../mcpe/protocol/AddBehaviorTreePacket.php | 9 +- src/network/mcpe/protocol/AddEntityPacket.php | 9 +- .../mcpe/protocol/AddItemActorPacket.php | 33 +-- .../mcpe/protocol/AddPaintingPacket.php | 25 ++- src/network/mcpe/protocol/AddPlayerPacket.php | 93 ++++---- .../mcpe/protocol/AdventureSettingsPacket.php | 29 +-- src/network/mcpe/protocol/AnimatePacket.php | 17 +- .../mcpe/protocol/AnvilDamagePacket.php | 13 +- .../AutomationClientConnectPacket.php | 9 +- .../AvailableActorIdentifiersPacket.php | 9 +- .../mcpe/protocol/AvailableCommandsPacket.php | 171 +++++++------- .../protocol/BiomeDefinitionListPacket.php | 9 +- .../mcpe/protocol/BlockActorDataPacket.php | 13 +- .../mcpe/protocol/BlockEventPacket.php | 17 +- .../mcpe/protocol/BlockPickRequestPacket.php | 17 +- src/network/mcpe/protocol/BookEditPacket.php | 49 +++-- src/network/mcpe/protocol/BossEventPacket.php | 45 ++-- src/network/mcpe/protocol/CameraPacket.php | 13 +- .../mcpe/protocol/ChangeDimensionPacket.php | 17 +- .../protocol/ChunkRadiusUpdatedPacket.php | 9 +- .../protocol/ClientCacheBlobStatusPacket.php | 21 +- .../ClientCacheMissResponsePacket.php | 17 +- .../mcpe/protocol/ClientCacheStatusPacket.php | 9 +- .../ClientToServerHandshakePacket.php | 5 +- .../protocol/ClientboundMapItemDataPacket.php | 101 ++++----- .../protocol/CommandBlockUpdatePacket.php | 53 ++--- .../mcpe/protocol/CommandOutputPacket.php | 49 +++-- .../mcpe/protocol/CommandRequestPacket.php | 17 +- .../protocol/CompletedUsingItemPacket.php | 13 +- .../mcpe/protocol/ContainerClosePacket.php | 9 +- .../mcpe/protocol/ContainerOpenPacket.php | 21 +- .../mcpe/protocol/ContainerSetDataPacket.php | 17 +- .../mcpe/protocol/CraftingDataPacket.php | 96 ++++---- .../mcpe/protocol/CraftingEventPacket.php | 33 +-- src/network/mcpe/protocol/DataPacket.php | 22 +- .../mcpe/protocol/DisconnectPacket.php | 13 +- .../mcpe/protocol/EducationSettingsPacket.php | 13 +- src/network/mcpe/protocol/EmotePacket.php | 17 +- src/network/mcpe/protocol/EventPacket.php | 17 +- .../mcpe/protocol/GameRulesChangedPacket.php | 9 +- .../mcpe/protocol/GuiDataPickItemPacket.php | 17 +- src/network/mcpe/protocol/HurtArmorPacket.php | 9 +- src/network/mcpe/protocol/InteractPacket.php | 25 ++- .../mcpe/protocol/InventoryContentPacket.php | 17 +- .../mcpe/protocol/InventorySlotPacket.php | 17 +- .../protocol/InventoryTransactionPacket.php | 13 +- .../mcpe/protocol/ItemFrameDropItemPacket.php | 9 +- src/network/mcpe/protocol/LabTablePacket.php | 17 +- .../mcpe/protocol/LecternUpdatePacket.php | 21 +- .../mcpe/protocol/LevelChunkPacket.php | 33 +-- .../mcpe/protocol/LevelEventGenericPacket.php | 13 +- .../mcpe/protocol/LevelEventPacket.php | 17 +- .../mcpe/protocol/LevelSoundEventPacket.php | 29 +-- .../mcpe/protocol/LevelSoundEventPacketV1.php | 29 +-- .../mcpe/protocol/LevelSoundEventPacketV2.php | 29 +-- src/network/mcpe/protocol/LoginPacket.php | 13 +- .../protocol/MapCreateLockedCopyPacket.php | 13 +- .../mcpe/protocol/MapInfoRequestPacket.php | 9 +- .../mcpe/protocol/MobArmorEquipmentPacket.php | 25 ++- src/network/mcpe/protocol/MobEffectPacket.php | 29 +-- .../mcpe/protocol/MobEquipmentPacket.php | 25 ++- .../mcpe/protocol/ModalFormRequestPacket.php | 13 +- .../mcpe/protocol/ModalFormResponsePacket.php | 13 +- .../mcpe/protocol/MoveActorAbsolutePacket.php | 29 +-- .../mcpe/protocol/MoveActorDeltaPacket.php | 53 ++--- .../mcpe/protocol/MovePlayerPacket.php | 45 ++-- .../protocol/MultiplayerSettingsPacket.php | 9 +- .../NetworkChunkPublisherUpdatePacket.php | 13 +- .../mcpe/protocol/NetworkSettingsPacket.php | 9 +- .../protocol/NetworkStackLatencyPacket.php | 13 +- .../mcpe/protocol/NpcRequestPacket.php | 21 +- .../OnScreenTextureAnimationPacket.php | 9 +- .../mcpe/protocol/PhotoTransferPacket.php | 17 +- src/network/mcpe/protocol/PlaySoundPacket.php | 21 +- .../mcpe/protocol/PlayStatusPacket.php | 9 +- .../mcpe/protocol/PlayerActionPacket.php | 21 +- .../mcpe/protocol/PlayerAuthInputPacket.php | 45 ++-- .../mcpe/protocol/PlayerHotbarPacket.php | 17 +- .../mcpe/protocol/PlayerInputPacket.php | 21 +- .../mcpe/protocol/PlayerListPacket.php | 53 ++--- .../mcpe/protocol/PlayerSkinPacket.php | 21 +- .../mcpe/protocol/PurchaseReceiptPacket.php | 13 +- .../mcpe/protocol/RemoveActorPacket.php | 9 +- .../mcpe/protocol/RemoveEntityPacket.php | 9 +- .../mcpe/protocol/RemoveObjectivePacket.php | 9 +- .../protocol/RequestChunkRadiusPacket.php | 9 +- .../protocol/ResourcePackChunkDataPacket.php | 21 +- .../ResourcePackChunkRequestPacket.php | 13 +- .../ResourcePackClientResponsePacket.php | 17 +- .../protocol/ResourcePackDataInfoPacket.php | 33 +-- .../mcpe/protocol/ResourcePackStackPacket.php | 33 +-- .../mcpe/protocol/ResourcePacksInfoPacket.php | 29 +-- src/network/mcpe/protocol/RespawnPacket.php | 17 +- src/network/mcpe/protocol/RiderJumpPacket.php | 9 +- .../mcpe/protocol/ScriptCustomEventPacket.php | 13 +- .../protocol/ServerSettingsRequestPacket.php | 5 +- .../protocol/ServerSettingsResponsePacket.php | 13 +- .../ServerToClientHandshakePacket.php | 9 +- .../mcpe/protocol/SetActorDataPacket.php | 13 +- .../mcpe/protocol/SetActorLinkPacket.php | 9 +- .../mcpe/protocol/SetActorMotionPacket.php | 13 +- .../protocol/SetCommandsEnabledPacket.php | 9 +- .../protocol/SetDefaultGameTypePacket.php | 9 +- .../mcpe/protocol/SetDifficultyPacket.php | 9 +- .../protocol/SetDisplayObjectivePacket.php | 25 ++- src/network/mcpe/protocol/SetHealthPacket.php | 9 +- .../mcpe/protocol/SetLastHurtByPacket.php | 9 +- .../SetLocalPlayerAsInitializedPacket.php | 9 +- .../mcpe/protocol/SetPlayerGameTypePacket.php | 9 +- src/network/mcpe/protocol/SetScorePacket.php | 37 ++-- .../protocol/SetScoreboardIdentityPacket.php | 21 +- .../mcpe/protocol/SetSpawnPositionPacket.php | 17 +- src/network/mcpe/protocol/SetTimePacket.php | 9 +- src/network/mcpe/protocol/SetTitlePacket.php | 25 ++- .../mcpe/protocol/SettingsCommandPacket.php | 13 +- .../mcpe/protocol/ShowCreditsPacket.php | 13 +- .../mcpe/protocol/ShowProfilePacket.php | 9 +- .../mcpe/protocol/ShowStoreOfferPacket.php | 13 +- .../mcpe/protocol/SimpleEventPacket.php | 9 +- .../protocol/SpawnExperienceOrbPacket.php | 13 +- .../protocol/SpawnParticleEffectPacket.php | 21 +- src/network/mcpe/protocol/StartGamePacket.php | 208 +++++++++--------- src/network/mcpe/protocol/StopSoundPacket.php | 13 +- .../protocol/StructureBlockUpdatePacket.php | 5 +- .../StructureTemplateDataRequestPacket.php | 21 +- .../StructureTemplateDataResponsePacket.php | 17 +- .../mcpe/protocol/SubClientLoginPacket.php | 9 +- .../mcpe/protocol/TakeItemActorPacket.php | 13 +- src/network/mcpe/protocol/TextPacket.php | 41 ++-- src/network/mcpe/protocol/TickSyncPacket.php | 13 +- src/network/mcpe/protocol/TransferPacket.php | 13 +- src/network/mcpe/protocol/UnknownPacket.php | 13 +- .../mcpe/protocol/UpdateAttributesPacket.php | 13 +- .../mcpe/protocol/UpdateBlockPacket.php | 21 +- .../protocol/UpdateBlockPropertiesPacket.php | 9 +- .../mcpe/protocol/UpdateBlockSyncedPacket.php | 17 +- .../mcpe/protocol/UpdateEquipPacket.php | 25 ++- .../mcpe/protocol/UpdateSoftEnumPacket.php | 21 +- .../mcpe/protocol/UpdateTradePacket.php | 45 ++-- .../protocol/VideoStreamConnectPacket.php | 25 ++- .../network/mcpe/protocol/TestPacket.php | 5 +- 145 files changed, 1704 insertions(+), 1562 deletions(-) diff --git a/src/network/mcpe/protocol/ActorEventPacket.php b/src/network/mcpe/protocol/ActorEventPacket.php index 438f7ce83c..292a0fcbf9 100644 --- a/src/network/mcpe/protocol/ActorEventPacket.php +++ b/src/network/mcpe/protocol/ActorEventPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ActorEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ACTOR_EVENT_PACKET; @@ -97,16 +98,16 @@ class ActorEventPacket extends DataPacket implements ClientboundPacket, Serverbo return $result; } - protected function decodePayload() : void{ - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); - $this->event = $this->buf->getByte(); - $this->data = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityRuntimeId = $in->getEntityRuntimeId(); + $this->event = $in->getByte(); + $this->data = $in->getVarInt(); } - protected function encodePayload() : void{ - $this->buf->putEntityRuntimeId($this->entityRuntimeId); - $this->buf->putByte($this->event); - $this->buf->putVarInt($this->data); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityRuntimeId($this->entityRuntimeId); + $out->putByte($this->event); + $out->putVarInt($this->data); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ActorFallPacket.php b/src/network/mcpe/protocol/ActorFallPacket.php index 10fd48cc92..deb0720064 100644 --- a/src/network/mcpe/protocol/ActorFallPacket.php +++ b/src/network/mcpe/protocol/ActorFallPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ActorFallPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ACTOR_FALL_PACKET; @@ -37,16 +38,16 @@ class ActorFallPacket extends DataPacket implements ServerboundPacket{ /** @var bool */ public $isInVoid; - protected function decodePayload() : void{ - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); - $this->fallDistance = $this->buf->getLFloat(); - $this->isInVoid = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityRuntimeId = $in->getEntityRuntimeId(); + $this->fallDistance = $in->getLFloat(); + $this->isInVoid = $in->getBool(); } - protected function encodePayload() : void{ - $this->buf->putEntityRuntimeId($this->entityRuntimeId); - $this->buf->putLFloat($this->fallDistance); - $this->buf->putBool($this->isInVoid); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityRuntimeId($this->entityRuntimeId); + $out->putLFloat($this->fallDistance); + $out->putBool($this->isInVoid); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ActorPickRequestPacket.php b/src/network/mcpe/protocol/ActorPickRequestPacket.php index b307e7d518..e87bf10617 100644 --- a/src/network/mcpe/protocol/ActorPickRequestPacket.php +++ b/src/network/mcpe/protocol/ActorPickRequestPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ActorPickRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ACTOR_PICK_REQUEST_PACKET; @@ -35,14 +36,14 @@ class ActorPickRequestPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $hotbarSlot; - protected function decodePayload() : void{ - $this->entityUniqueId = $this->buf->getLLong(); - $this->hotbarSlot = $this->buf->getByte(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityUniqueId = $in->getLLong(); + $this->hotbarSlot = $in->getByte(); } - protected function encodePayload() : void{ - $this->buf->putLLong($this->entityUniqueId); - $this->buf->putByte($this->hotbarSlot); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putLLong($this->entityUniqueId); + $out->putByte($this->hotbarSlot); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/AddActorPacket.php b/src/network/mcpe/protocol/AddActorPacket.php index 60e802af72..fb4e8b1898 100644 --- a/src/network/mcpe/protocol/AddActorPacket.php +++ b/src/network/mcpe/protocol/AddActorPacket.php @@ -32,6 +32,7 @@ use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function array_search; use function count; @@ -173,25 +174,25 @@ class AddActorPacket extends DataPacket implements ClientboundPacket{ /** @var EntityLink[] */ public $links = []; - protected function decodePayload() : void{ - $this->entityUniqueId = $this->buf->getEntityUniqueId(); - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); - $this->type = array_search($t = $this->buf->getString(), self::LEGACY_ID_MAP_BC, true); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityUniqueId = $in->getEntityUniqueId(); + $this->entityRuntimeId = $in->getEntityRuntimeId(); + $this->type = array_search($t = $in->getString(), self::LEGACY_ID_MAP_BC, true); if($this->type === false){ throw new BadPacketException("Can't map ID $t to legacy ID"); } - $this->position = $this->buf->getVector3(); - $this->motion = $this->buf->getVector3(); - $this->pitch = $this->buf->getLFloat(); - $this->yaw = $this->buf->getLFloat(); - $this->headYaw = $this->buf->getLFloat(); + $this->position = $in->getVector3(); + $this->motion = $in->getVector3(); + $this->pitch = $in->getLFloat(); + $this->yaw = $in->getLFloat(); + $this->headYaw = $in->getLFloat(); - $attrCount = $this->buf->getUnsignedVarInt(); + $attrCount = $in->getUnsignedVarInt(); for($i = 0; $i < $attrCount; ++$i){ - $id = $this->buf->getString(); - $min = $this->buf->getLFloat(); - $current = $this->buf->getLFloat(); - $max = $this->buf->getLFloat(); + $id = $in->getString(); + $min = $in->getLFloat(); + $current = $in->getLFloat(); + $max = $in->getLFloat(); $attr = Attribute::get($id); if($attr !== null){ @@ -208,38 +209,38 @@ class AddActorPacket extends DataPacket implements ClientboundPacket{ } } - $this->metadata = $this->buf->getEntityMetadata(); - $linkCount = $this->buf->getUnsignedVarInt(); + $this->metadata = $in->getEntityMetadata(); + $linkCount = $in->getUnsignedVarInt(); for($i = 0; $i < $linkCount; ++$i){ - $this->links[] = $this->buf->getEntityLink(); + $this->links[] = $in->getEntityLink(); } } - protected function encodePayload() : void{ - $this->buf->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); - $this->buf->putEntityRuntimeId($this->entityRuntimeId); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); + $out->putEntityRuntimeId($this->entityRuntimeId); if(!isset(self::LEGACY_ID_MAP_BC[$this->type])){ throw new \InvalidArgumentException("Unknown entity numeric ID $this->type"); } - $this->buf->putString(self::LEGACY_ID_MAP_BC[$this->type]); - $this->buf->putVector3($this->position); - $this->buf->putVector3Nullable($this->motion); - $this->buf->putLFloat($this->pitch); - $this->buf->putLFloat($this->yaw); - $this->buf->putLFloat($this->headYaw); + $out->putString(self::LEGACY_ID_MAP_BC[$this->type]); + $out->putVector3($this->position); + $out->putVector3Nullable($this->motion); + $out->putLFloat($this->pitch); + $out->putLFloat($this->yaw); + $out->putLFloat($this->headYaw); - $this->buf->putUnsignedVarInt(count($this->attributes)); + $out->putUnsignedVarInt(count($this->attributes)); foreach($this->attributes as $attribute){ - $this->buf->putString($attribute->getId()); - $this->buf->putLFloat($attribute->getMinValue()); - $this->buf->putLFloat($attribute->getValue()); - $this->buf->putLFloat($attribute->getMaxValue()); + $out->putString($attribute->getId()); + $out->putLFloat($attribute->getMinValue()); + $out->putLFloat($attribute->getValue()); + $out->putLFloat($attribute->getMaxValue()); } - $this->buf->putEntityMetadata($this->metadata); - $this->buf->putUnsignedVarInt(count($this->links)); + $out->putEntityMetadata($this->metadata); + $out->putUnsignedVarInt(count($this->links)); foreach($this->links as $link){ - $this->buf->putEntityLink($link); + $out->putEntityLink($link); } } diff --git a/src/network/mcpe/protocol/AddBehaviorTreePacket.php b/src/network/mcpe/protocol/AddBehaviorTreePacket.php index 57bb64c4f8..5fb1eefcc4 100644 --- a/src/network/mcpe/protocol/AddBehaviorTreePacket.php +++ b/src/network/mcpe/protocol/AddBehaviorTreePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class AddBehaviorTreePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_BEHAVIOR_TREE_PACKET; @@ -33,12 +34,12 @@ class AddBehaviorTreePacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $behaviorTreeJson; - protected function decodePayload() : void{ - $this->behaviorTreeJson = $this->buf->getString(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->behaviorTreeJson = $in->getString(); } - protected function encodePayload() : void{ - $this->buf->putString($this->behaviorTreeJson); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->behaviorTreeJson); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/AddEntityPacket.php b/src/network/mcpe/protocol/AddEntityPacket.php index 7e03e96a29..380747fe4f 100644 --- a/src/network/mcpe/protocol/AddEntityPacket.php +++ b/src/network/mcpe/protocol/AddEntityPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class AddEntityPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_ENTITY_PACKET; @@ -43,12 +44,12 @@ class AddEntityPacket extends DataPacket implements ClientboundPacket{ return $this->uvarint1; } - protected function decodePayload() : void{ - $this->uvarint1 = $this->buf->getUnsignedVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->uvarint1 = $in->getUnsignedVarInt(); } - protected function encodePayload() : void{ - $this->buf->putUnsignedVarInt($this->uvarint1); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putUnsignedVarInt($this->uvarint1); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/AddItemActorPacket.php b/src/network/mcpe/protocol/AddItemActorPacket.php index 9f841ea2c6..71ceab3911 100644 --- a/src/network/mcpe/protocol/AddItemActorPacket.php +++ b/src/network/mcpe/protocol/AddItemActorPacket.php @@ -29,6 +29,7 @@ use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class AddItemActorPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_ITEM_ACTOR_PACKET; @@ -51,24 +52,24 @@ class AddItemActorPacket extends DataPacket implements ClientboundPacket{ /** @var bool */ public $isFromFishing = false; - protected function decodePayload() : void{ - $this->entityUniqueId = $this->buf->getEntityUniqueId(); - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); - $this->item = $this->buf->getSlot(); - $this->position = $this->buf->getVector3(); - $this->motion = $this->buf->getVector3(); - $this->metadata = $this->buf->getEntityMetadata(); - $this->isFromFishing = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityUniqueId = $in->getEntityUniqueId(); + $this->entityRuntimeId = $in->getEntityRuntimeId(); + $this->item = $in->getSlot(); + $this->position = $in->getVector3(); + $this->motion = $in->getVector3(); + $this->metadata = $in->getEntityMetadata(); + $this->isFromFishing = $in->getBool(); } - protected function encodePayload() : void{ - $this->buf->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); - $this->buf->putEntityRuntimeId($this->entityRuntimeId); - $this->buf->putSlot($this->item); - $this->buf->putVector3($this->position); - $this->buf->putVector3Nullable($this->motion); - $this->buf->putEntityMetadata($this->metadata); - $this->buf->putBool($this->isFromFishing); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); + $out->putEntityRuntimeId($this->entityRuntimeId); + $out->putSlot($this->item); + $out->putVector3($this->position); + $out->putVector3Nullable($this->motion); + $out->putEntityMetadata($this->metadata); + $out->putBool($this->isFromFishing); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/AddPaintingPacket.php b/src/network/mcpe/protocol/AddPaintingPacket.php index a4db84d687..80f827111d 100644 --- a/src/network/mcpe/protocol/AddPaintingPacket.php +++ b/src/network/mcpe/protocol/AddPaintingPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class AddPaintingPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_PAINTING_PACKET; @@ -42,20 +43,20 @@ class AddPaintingPacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $title; - protected function decodePayload() : void{ - $this->entityUniqueId = $this->buf->getEntityUniqueId(); - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); - $this->position = $this->buf->getVector3(); - $this->direction = $this->buf->getVarInt(); - $this->title = $this->buf->getString(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityUniqueId = $in->getEntityUniqueId(); + $this->entityRuntimeId = $in->getEntityRuntimeId(); + $this->position = $in->getVector3(); + $this->direction = $in->getVarInt(); + $this->title = $in->getString(); } - protected function encodePayload() : void{ - $this->buf->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); - $this->buf->putEntityRuntimeId($this->entityRuntimeId); - $this->buf->putVector3($this->position); - $this->buf->putVarInt($this->direction); - $this->buf->putString($this->title); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); + $out->putEntityRuntimeId($this->entityRuntimeId); + $out->putVector3($this->position); + $out->putVarInt($this->direction); + $out->putString($this->title); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/AddPlayerPacket.php b/src/network/mcpe/protocol/AddPlayerPacket.php index beb6fa5950..453b10dbed 100644 --- a/src/network/mcpe/protocol/AddPlayerPacket.php +++ b/src/network/mcpe/protocol/AddPlayerPacket.php @@ -30,6 +30,7 @@ use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\UUID; use function count; @@ -87,66 +88,66 @@ class AddPlayerPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $buildPlatform = -1; - protected function decodePayload() : void{ - $this->uuid = $this->buf->getUUID(); - $this->username = $this->buf->getString(); - $this->entityUniqueId = $this->buf->getEntityUniqueId(); - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); - $this->platformChatId = $this->buf->getString(); - $this->position = $this->buf->getVector3(); - $this->motion = $this->buf->getVector3(); - $this->pitch = $this->buf->getLFloat(); - $this->yaw = $this->buf->getLFloat(); - $this->headYaw = $this->buf->getLFloat(); - $this->item = $this->buf->getSlot(); - $this->metadata = $this->buf->getEntityMetadata(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->uuid = $in->getUUID(); + $this->username = $in->getString(); + $this->entityUniqueId = $in->getEntityUniqueId(); + $this->entityRuntimeId = $in->getEntityRuntimeId(); + $this->platformChatId = $in->getString(); + $this->position = $in->getVector3(); + $this->motion = $in->getVector3(); + $this->pitch = $in->getLFloat(); + $this->yaw = $in->getLFloat(); + $this->headYaw = $in->getLFloat(); + $this->item = $in->getSlot(); + $this->metadata = $in->getEntityMetadata(); - $this->uvarint1 = $this->buf->getUnsignedVarInt(); - $this->uvarint2 = $this->buf->getUnsignedVarInt(); - $this->uvarint3 = $this->buf->getUnsignedVarInt(); - $this->uvarint4 = $this->buf->getUnsignedVarInt(); - $this->uvarint5 = $this->buf->getUnsignedVarInt(); + $this->uvarint1 = $in->getUnsignedVarInt(); + $this->uvarint2 = $in->getUnsignedVarInt(); + $this->uvarint3 = $in->getUnsignedVarInt(); + $this->uvarint4 = $in->getUnsignedVarInt(); + $this->uvarint5 = $in->getUnsignedVarInt(); - $this->long1 = $this->buf->getLLong(); + $this->long1 = $in->getLLong(); - $linkCount = $this->buf->getUnsignedVarInt(); + $linkCount = $in->getUnsignedVarInt(); for($i = 0; $i < $linkCount; ++$i){ - $this->links[$i] = $this->buf->getEntityLink(); + $this->links[$i] = $in->getEntityLink(); } - $this->deviceId = $this->buf->getString(); - $this->buildPlatform = $this->buf->getLInt(); + $this->deviceId = $in->getString(); + $this->buildPlatform = $in->getLInt(); } - protected function encodePayload() : void{ - $this->buf->putUUID($this->uuid); - $this->buf->putString($this->username); - $this->buf->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); - $this->buf->putEntityRuntimeId($this->entityRuntimeId); - $this->buf->putString($this->platformChatId); - $this->buf->putVector3($this->position); - $this->buf->putVector3Nullable($this->motion); - $this->buf->putLFloat($this->pitch); - $this->buf->putLFloat($this->yaw); - $this->buf->putLFloat($this->headYaw ?? $this->yaw); - $this->buf->putSlot($this->item); - $this->buf->putEntityMetadata($this->metadata); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putUUID($this->uuid); + $out->putString($this->username); + $out->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); + $out->putEntityRuntimeId($this->entityRuntimeId); + $out->putString($this->platformChatId); + $out->putVector3($this->position); + $out->putVector3Nullable($this->motion); + $out->putLFloat($this->pitch); + $out->putLFloat($this->yaw); + $out->putLFloat($this->headYaw ?? $this->yaw); + $out->putSlot($this->item); + $out->putEntityMetadata($this->metadata); - $this->buf->putUnsignedVarInt($this->uvarint1); - $this->buf->putUnsignedVarInt($this->uvarint2); - $this->buf->putUnsignedVarInt($this->uvarint3); - $this->buf->putUnsignedVarInt($this->uvarint4); - $this->buf->putUnsignedVarInt($this->uvarint5); + $out->putUnsignedVarInt($this->uvarint1); + $out->putUnsignedVarInt($this->uvarint2); + $out->putUnsignedVarInt($this->uvarint3); + $out->putUnsignedVarInt($this->uvarint4); + $out->putUnsignedVarInt($this->uvarint5); - $this->buf->putLLong($this->long1); + $out->putLLong($this->long1); - $this->buf->putUnsignedVarInt(count($this->links)); + $out->putUnsignedVarInt(count($this->links)); foreach($this->links as $link){ - $this->buf->putEntityLink($link); + $out->putEntityLink($link); } - $this->buf->putString($this->deviceId); - $this->buf->putLInt($this->buildPlatform); + $out->putString($this->deviceId); + $out->putLInt($this->buildPlatform); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/AdventureSettingsPacket.php b/src/network/mcpe/protocol/AdventureSettingsPacket.php index a81782af25..4075d65a03 100644 --- a/src/network/mcpe/protocol/AdventureSettingsPacket.php +++ b/src/network/mcpe/protocol/AdventureSettingsPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class AdventureSettingsPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ADVENTURE_SETTINGS_PACKET; @@ -75,22 +76,22 @@ class AdventureSettingsPacket extends DataPacket implements ClientboundPacket, S /** @var int */ public $entityUniqueId; //This is a little-endian long, NOT a var-long. (WTF Mojang) - protected function decodePayload() : void{ - $this->flags = $this->buf->getUnsignedVarInt(); - $this->commandPermission = $this->buf->getUnsignedVarInt(); - $this->flags2 = $this->buf->getUnsignedVarInt(); - $this->playerPermission = $this->buf->getUnsignedVarInt(); - $this->customFlags = $this->buf->getUnsignedVarInt(); - $this->entityUniqueId = $this->buf->getLLong(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->flags = $in->getUnsignedVarInt(); + $this->commandPermission = $in->getUnsignedVarInt(); + $this->flags2 = $in->getUnsignedVarInt(); + $this->playerPermission = $in->getUnsignedVarInt(); + $this->customFlags = $in->getUnsignedVarInt(); + $this->entityUniqueId = $in->getLLong(); } - protected function encodePayload() : void{ - $this->buf->putUnsignedVarInt($this->flags); - $this->buf->putUnsignedVarInt($this->commandPermission); - $this->buf->putUnsignedVarInt($this->flags2); - $this->buf->putUnsignedVarInt($this->playerPermission); - $this->buf->putUnsignedVarInt($this->customFlags); - $this->buf->putLLong($this->entityUniqueId); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putUnsignedVarInt($this->flags); + $out->putUnsignedVarInt($this->commandPermission); + $out->putUnsignedVarInt($this->flags2); + $out->putUnsignedVarInt($this->playerPermission); + $out->putUnsignedVarInt($this->customFlags); + $out->putLLong($this->entityUniqueId); } public function getFlag(int $flag) : bool{ diff --git a/src/network/mcpe/protocol/AnimatePacket.php b/src/network/mcpe/protocol/AnimatePacket.php index 003d7d5e4a..58a910a80e 100644 --- a/src/network/mcpe/protocol/AnimatePacket.php +++ b/src/network/mcpe/protocol/AnimatePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class AnimatePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ANIMATE_PACKET; @@ -57,19 +58,19 @@ class AnimatePacket extends DataPacket implements ClientboundPacket, Serverbound return $result; } - protected function decodePayload() : void{ - $this->action = $this->buf->getVarInt(); - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->action = $in->getVarInt(); + $this->entityRuntimeId = $in->getEntityRuntimeId(); if(($this->action & 0x80) !== 0){ - $this->float = $this->buf->getLFloat(); + $this->float = $in->getLFloat(); } } - protected function encodePayload() : void{ - $this->buf->putVarInt($this->action); - $this->buf->putEntityRuntimeId($this->entityRuntimeId); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putVarInt($this->action); + $out->putEntityRuntimeId($this->entityRuntimeId); if(($this->action & 0x80) !== 0){ - $this->buf->putLFloat($this->float); + $out->putLFloat($this->float); } } diff --git a/src/network/mcpe/protocol/AnvilDamagePacket.php b/src/network/mcpe/protocol/AnvilDamagePacket.php index a0f1d1e20a..495779b45f 100644 --- a/src/network/mcpe/protocol/AnvilDamagePacket.php +++ b/src/network/mcpe/protocol/AnvilDamagePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class AnvilDamagePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ANVIL_DAMAGE_PACKET; @@ -62,14 +63,14 @@ class AnvilDamagePacket extends DataPacket implements ServerboundPacket{ return $this->z; } - protected function decodePayload() : void{ - $this->damageAmount = $this->buf->getByte(); - $this->buf->getBlockPosition($this->x, $this->y, $this->z); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->damageAmount = $in->getByte(); + $in->getBlockPosition($this->x, $this->y, $this->z); } - protected function encodePayload() : void{ - $this->buf->putByte($this->damageAmount); - $this->buf->putBlockPosition($this->x, $this->y, $this->z); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putByte($this->damageAmount); + $out->putBlockPosition($this->x, $this->y, $this->z); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/AutomationClientConnectPacket.php b/src/network/mcpe/protocol/AutomationClientConnectPacket.php index 98e9740b63..b01f237abf 100644 --- a/src/network/mcpe/protocol/AutomationClientConnectPacket.php +++ b/src/network/mcpe/protocol/AutomationClientConnectPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class AutomationClientConnectPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::AUTOMATION_CLIENT_CONNECT_PACKET; @@ -33,12 +34,12 @@ class AutomationClientConnectPacket extends DataPacket implements ClientboundPac /** @var string */ public $serverUri; - protected function decodePayload() : void{ - $this->serverUri = $this->buf->getString(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->serverUri = $in->getString(); } - protected function encodePayload() : void{ - $this->buf->putString($this->serverUri); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->serverUri); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php b/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php index 53bb70539d..b583a85f73 100644 --- a/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php +++ b/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function base64_decode; use function file_get_contents; @@ -38,12 +39,12 @@ class AvailableActorIdentifiersPacket extends DataPacket implements ClientboundP /** @var string */ public $namedtag; - protected function decodePayload() : void{ - $this->namedtag = $this->buf->getRemaining(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->namedtag = $in->getRemaining(); } - protected function encodePayload() : void{ - $this->buf->put( + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->put( $this->namedtag ?? self::$DEFAULT_NBT_CACHE ?? (self::$DEFAULT_NBT_CACHE = file_get_contents(\pocketmine\RESOURCE_PATH . '/vanilla/entity_identifiers.nbt')) diff --git a/src/network/mcpe/protocol/AvailableCommandsPacket.php b/src/network/mcpe/protocol/AvailableCommandsPacket.php index 4ed1ae8f39..d98ee2e013 100644 --- a/src/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/network/mcpe/protocol/AvailableCommandsPacket.php @@ -31,6 +31,7 @@ use pocketmine\network\mcpe\protocol\types\command\CommandData; use pocketmine\network\mcpe\protocol\types\command\CommandEnum; use pocketmine\network\mcpe\protocol\types\command\CommandEnumConstraint; use pocketmine\network\mcpe\protocol\types\command\CommandParameter; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; use function array_search; use function count; @@ -111,38 +112,38 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ */ public $enumConstraints = []; - protected function decodePayload() : void{ + protected function decodePayload(NetworkBinaryStream $in) : void{ /** @var string[] $enumValues */ $enumValues = []; - for($i = 0, $enumValuesCount = $this->buf->getUnsignedVarInt(); $i < $enumValuesCount; ++$i){ - $enumValues[] = $this->buf->getString(); + for($i = 0, $enumValuesCount = $in->getUnsignedVarInt(); $i < $enumValuesCount; ++$i){ + $enumValues[] = $in->getString(); } /** @var string[] $postfixes */ $postfixes = []; - for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ - $postfixes[] = $this->buf->getString(); + for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ + $postfixes[] = $in->getString(); } /** @var CommandEnum[] $enums */ $enums = []; - for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ - $enums[] = $enum = $this->getEnum($enumValues); + for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ + $enums[] = $enum = $this->getEnum($enumValues, $in); if(isset(self::HARDCODED_ENUM_NAMES[$enum->getName()])){ $this->hardcodedEnums[] = $enum; } } - for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ - $this->commandData[] = $this->getCommandData($enums, $postfixes); + for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ + $this->commandData[] = $this->getCommandData($enums, $postfixes, $in); } - for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ - $this->softEnums[] = $this->getSoftEnum(); + for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ + $this->softEnums[] = $this->getSoftEnum($in); } - for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ - $this->enumConstraints[] = $this->getEnumConstraint($enums, $enumValues); + for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ + $this->enumConstraints[] = $this->getEnumConstraint($enums, $enumValues, $in); } } @@ -152,14 +153,14 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @throws BadPacketException * @throws BinaryDataException */ - protected function getEnum(array $enumValueList) : CommandEnum{ - $enumName = $this->buf->getString(); + protected function getEnum(array $enumValueList, NetworkBinaryStream $in) : CommandEnum{ + $enumName = $in->getString(); $enumValues = []; $listSize = count($enumValueList); - for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ - $index = $this->getEnumValueIndex($listSize); + for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ + $index = $this->getEnumValueIndex($listSize, $in); if(!isset($enumValueList[$index])){ throw new BadPacketException("Invalid enum value index $index"); } @@ -173,13 +174,13 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ /** * @throws BinaryDataException */ - protected function getSoftEnum() : CommandEnum{ - $enumName = $this->buf->getString(); + protected function getSoftEnum(NetworkBinaryStream $in) : CommandEnum{ + $enumName = $in->getString(); $enumValues = []; - for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ + for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ //Get the enum value from the initial pile of mess - $enumValues[] = $this->buf->getString(); + $enumValues[] = $in->getString(); } return new CommandEnum($enumName, $enumValues); @@ -188,51 +189,51 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ /** * @param int[] $enumValueMap */ - protected function putEnum(CommandEnum $enum, array $enumValueMap) : void{ - $this->buf->putString($enum->getName()); + protected function putEnum(CommandEnum $enum, array $enumValueMap, NetworkBinaryStream $out) : void{ + $out->putString($enum->getName()); $values = $enum->getValues(); - $this->buf->putUnsignedVarInt(count($values)); + $out->putUnsignedVarInt(count($values)); $listSize = count($enumValueMap); foreach($values as $value){ $index = $enumValueMap[$value] ?? -1; if($index === -1){ throw new \InvalidStateException("Enum value '$value' not found"); } - $this->putEnumValueIndex($index, $listSize); + $this->putEnumValueIndex($index, $listSize, $out); } } - protected function putSoftEnum(CommandEnum $enum) : void{ - $this->buf->putString($enum->getName()); + protected function putSoftEnum(CommandEnum $enum, NetworkBinaryStream $out) : void{ + $out->putString($enum->getName()); $values = $enum->getValues(); - $this->buf->putUnsignedVarInt(count($values)); + $out->putUnsignedVarInt(count($values)); foreach($values as $value){ - $this->buf->putString($value); + $out->putString($value); } } /** * @throws BinaryDataException */ - protected function getEnumValueIndex(int $valueCount) : int{ + protected function getEnumValueIndex(int $valueCount, NetworkBinaryStream $in) : int{ if($valueCount < 256){ - return $this->buf->getByte(); + return $in->getByte(); }elseif($valueCount < 65536){ - return $this->buf->getLShort(); + return $in->getLShort(); }else{ - return $this->buf->getLInt(); + return $in->getLInt(); } } - protected function putEnumValueIndex(int $index, int $valueCount) : void{ + protected function putEnumValueIndex(int $index, int $valueCount, NetworkBinaryStream $out) : void{ if($valueCount < 256){ - $this->buf->putByte($index); + $out->putByte($index); }elseif($valueCount < 65536){ - $this->buf->putLShort($index); + $out->putLShort($index); }else{ - $this->buf->putLInt($index); + $out->putLInt($index); } } @@ -243,13 +244,13 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @throws BadPacketException * @throws BinaryDataException */ - protected function getEnumConstraint(array $enums, array $enumValues) : CommandEnumConstraint{ + protected function getEnumConstraint(array $enums, array $enumValues, NetworkBinaryStream $in) : CommandEnumConstraint{ //wtf, what was wrong with an offset inside the enum? :( - $valueIndex = $this->buf->getLInt(); + $valueIndex = $in->getLInt(); if(!isset($enumValues[$valueIndex])){ throw new BadPacketException("Enum constraint refers to unknown enum value index $valueIndex"); } - $enumIndex = $this->buf->getLInt(); + $enumIndex = $in->getLInt(); if(!isset($enums[$enumIndex])){ throw new BadPacketException("Enum constraint refers to unknown enum index $enumIndex"); } @@ -260,8 +261,8 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ } $constraintIds = []; - for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ - $constraintIds[] = $this->buf->getByte(); + for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ + $constraintIds[] = $in->getByte(); } return new CommandEnumConstraint($enum, $valueOffset, $constraintIds); @@ -271,12 +272,12 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @param int[] $enumIndexes string enum name -> int index * @param int[] $enumValueIndexes string value -> int index */ - protected function putEnumConstraint(CommandEnumConstraint $constraint, array $enumIndexes, array $enumValueIndexes) : void{ - $this->buf->putLInt($enumValueIndexes[$constraint->getAffectedValue()]); - $this->buf->putLInt($enumIndexes[$constraint->getEnum()->getName()]); - $this->buf->putUnsignedVarInt(count($constraint->getConstraints())); + protected function putEnumConstraint(CommandEnumConstraint $constraint, array $enumIndexes, array $enumValueIndexes, NetworkBinaryStream $out) : void{ + $out->putLInt($enumValueIndexes[$constraint->getAffectedValue()]); + $out->putLInt($enumIndexes[$constraint->getEnum()->getName()]); + $out->putUnsignedVarInt(count($constraint->getConstraints())); foreach($constraint->getConstraints() as $v){ - $this->buf->putByte($v); + $out->putByte($v); } } @@ -287,22 +288,22 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @throws BadPacketException * @throws BinaryDataException */ - protected function getCommandData(array $enums, array $postfixes) : CommandData{ - $name = $this->buf->getString(); - $description = $this->buf->getString(); - $flags = $this->buf->getByte(); - $permission = $this->buf->getByte(); - $aliases = $enums[$this->buf->getLInt()] ?? null; + protected function getCommandData(array $enums, array $postfixes, NetworkBinaryStream $in) : CommandData{ + $name = $in->getString(); + $description = $in->getString(); + $flags = $in->getByte(); + $permission = $in->getByte(); + $aliases = $enums[$in->getLInt()] ?? null; $overloads = []; - for($overloadIndex = 0, $overloadCount = $this->buf->getUnsignedVarInt(); $overloadIndex < $overloadCount; ++$overloadIndex){ + for($overloadIndex = 0, $overloadCount = $in->getUnsignedVarInt(); $overloadIndex < $overloadCount; ++$overloadIndex){ $overloads[$overloadIndex] = []; - for($paramIndex = 0, $paramCount = $this->buf->getUnsignedVarInt(); $paramIndex < $paramCount; ++$paramIndex){ + for($paramIndex = 0, $paramCount = $in->getUnsignedVarInt(); $paramIndex < $paramCount; ++$paramIndex){ $parameter = new CommandParameter(); - $parameter->paramName = $this->buf->getString(); - $parameter->paramType = $this->buf->getLInt(); - $parameter->isOptional = $this->buf->getBool(); - $parameter->flags = $this->buf->getByte(); + $parameter->paramName = $in->getString(); + $parameter->paramType = $in->getLInt(); + $parameter->isOptional = $in->getBool(); + $parameter->flags = $in->getByte(); if(($parameter->paramType & self::ARG_FLAG_ENUM) !== 0){ $index = ($parameter->paramType & 0xffff); @@ -331,24 +332,24 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @param int[] $enumIndexes string enum name -> int index * @param int[] $postfixIndexes */ - protected function putCommandData(CommandData $data, array $enumIndexes, array $postfixIndexes) : void{ - $this->buf->putString($data->name); - $this->buf->putString($data->description); - $this->buf->putByte($data->flags); - $this->buf->putByte($data->permission); + protected function putCommandData(CommandData $data, array $enumIndexes, array $postfixIndexes, NetworkBinaryStream $out) : void{ + $out->putString($data->name); + $out->putString($data->description); + $out->putByte($data->flags); + $out->putByte($data->permission); if($data->aliases !== null){ - $this->buf->putLInt($enumIndexes[$data->aliases->getName()] ?? -1); + $out->putLInt($enumIndexes[$data->aliases->getName()] ?? -1); }else{ - $this->buf->putLInt(-1); + $out->putLInt(-1); } - $this->buf->putUnsignedVarInt(count($data->overloads)); + $out->putUnsignedVarInt(count($data->overloads)); foreach($data->overloads as $overload){ /** @var CommandParameter[] $overload */ - $this->buf->putUnsignedVarInt(count($overload)); + $out->putUnsignedVarInt(count($overload)); foreach($overload as $parameter){ - $this->buf->putString($parameter->paramName); + $out->putString($parameter->paramName); if($parameter->enum !== null){ $type = self::ARG_FLAG_ENUM | self::ARG_FLAG_VALID | ($enumIndexes[$parameter->enum->getName()] ?? -1); @@ -362,9 +363,9 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ $type = $parameter->paramType; } - $this->buf->putLInt($type); - $this->buf->putBool($parameter->isOptional); - $this->buf->putByte($parameter->flags); + $out->putLInt($type); + $out->putBool($parameter->isOptional); + $out->putByte($parameter->flags); } } } @@ -412,7 +413,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ return "unknown ($argtype)"; } - protected function encodePayload() : void{ + protected function encodePayload(NetworkBinaryStream $out) : void{ /** @var int[] $enumValueIndexes */ $enumValueIndexes = []; /** @var int[] $postfixIndexes */ @@ -452,34 +453,34 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ } } - $this->buf->putUnsignedVarInt(count($enumValueIndexes)); + $out->putUnsignedVarInt(count($enumValueIndexes)); foreach($enumValueIndexes as $enumValue => $index){ - $this->buf->putString((string) $enumValue); //stupid PHP key casting D: + $out->putString((string) $enumValue); //stupid PHP key casting D: } - $this->buf->putUnsignedVarInt(count($postfixIndexes)); + $out->putUnsignedVarInt(count($postfixIndexes)); foreach($postfixIndexes as $postfix => $index){ - $this->buf->putString((string) $postfix); //stupid PHP key casting D: + $out->putString((string) $postfix); //stupid PHP key casting D: } - $this->buf->putUnsignedVarInt(count($enums)); + $out->putUnsignedVarInt(count($enums)); foreach($enums as $enum){ - $this->putEnum($enum, $enumValueIndexes); + $this->putEnum($enum, $enumValueIndexes, $out); } - $this->buf->putUnsignedVarInt(count($this->commandData)); + $out->putUnsignedVarInt(count($this->commandData)); foreach($this->commandData as $data){ - $this->putCommandData($data, $enumIndexes, $postfixIndexes); + $this->putCommandData($data, $enumIndexes, $postfixIndexes, $out); } - $this->buf->putUnsignedVarInt(count($this->softEnums)); + $out->putUnsignedVarInt(count($this->softEnums)); foreach($this->softEnums as $enum){ - $this->putSoftEnum($enum); + $this->putSoftEnum($enum, $out); } - $this->buf->putUnsignedVarInt(count($this->enumConstraints)); + $out->putUnsignedVarInt(count($this->enumConstraints)); foreach($this->enumConstraints as $constraint){ - $this->putEnumConstraint($constraint, $enumIndexes, $enumValueIndexes); + $this->putEnumConstraint($constraint, $enumIndexes, $enumValueIndexes, $out); } } diff --git a/src/network/mcpe/protocol/BiomeDefinitionListPacket.php b/src/network/mcpe/protocol/BiomeDefinitionListPacket.php index a16f17708a..8ce5583bdc 100644 --- a/src/network/mcpe/protocol/BiomeDefinitionListPacket.php +++ b/src/network/mcpe/protocol/BiomeDefinitionListPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function file_get_contents; class BiomeDefinitionListPacket extends DataPacket implements ClientboundPacket{ @@ -37,12 +38,12 @@ class BiomeDefinitionListPacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $namedtag; - protected function decodePayload() : void{ - $this->namedtag = $this->buf->getRemaining(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->namedtag = $in->getRemaining(); } - protected function encodePayload() : void{ - $this->buf->put( + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->put( $this->namedtag ?? self::$DEFAULT_NBT_CACHE ?? (self::$DEFAULT_NBT_CACHE = file_get_contents(\pocketmine\RESOURCE_PATH . '/vanilla/biome_definitions.nbt')) diff --git a/src/network/mcpe/protocol/BlockActorDataPacket.php b/src/network/mcpe/protocol/BlockActorDataPacket.php index 2bcc51067b..21a981a59e 100644 --- a/src/network/mcpe/protocol/BlockActorDataPacket.php +++ b/src/network/mcpe/protocol/BlockActorDataPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class BlockActorDataPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::BLOCK_ACTOR_DATA_PACKET; @@ -46,14 +47,14 @@ class BlockActorDataPacket extends DataPacket implements ClientboundPacket, Serv return $result; } - protected function decodePayload() : void{ - $this->buf->getBlockPosition($this->x, $this->y, $this->z); - $this->namedtag = $this->buf->getRemaining(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $in->getBlockPosition($this->x, $this->y, $this->z); + $this->namedtag = $in->getRemaining(); } - protected function encodePayload() : void{ - $this->buf->putBlockPosition($this->x, $this->y, $this->z); - $this->buf->put($this->namedtag); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putBlockPosition($this->x, $this->y, $this->z); + $out->put($this->namedtag); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/BlockEventPacket.php b/src/network/mcpe/protocol/BlockEventPacket.php index b928db6c8a..a4b74ddb5a 100644 --- a/src/network/mcpe/protocol/BlockEventPacket.php +++ b/src/network/mcpe/protocol/BlockEventPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class BlockEventPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::BLOCK_EVENT_PACKET; @@ -52,16 +53,16 @@ class BlockEventPacket extends DataPacket implements ClientboundPacket{ return $pk; } - protected function decodePayload() : void{ - $this->buf->getBlockPosition($this->x, $this->y, $this->z); - $this->eventType = $this->buf->getVarInt(); - $this->eventData = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $in->getBlockPosition($this->x, $this->y, $this->z); + $this->eventType = $in->getVarInt(); + $this->eventData = $in->getVarInt(); } - protected function encodePayload() : void{ - $this->buf->putBlockPosition($this->x, $this->y, $this->z); - $this->buf->putVarInt($this->eventType); - $this->buf->putVarInt($this->eventData); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putBlockPosition($this->x, $this->y, $this->z); + $out->putVarInt($this->eventType); + $out->putVarInt($this->eventData); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/BlockPickRequestPacket.php b/src/network/mcpe/protocol/BlockPickRequestPacket.php index 4adf0251de..ff2a6ed953 100644 --- a/src/network/mcpe/protocol/BlockPickRequestPacket.php +++ b/src/network/mcpe/protocol/BlockPickRequestPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class BlockPickRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::BLOCK_PICK_REQUEST_PACKET; @@ -41,16 +42,16 @@ class BlockPickRequestPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $hotbarSlot; - protected function decodePayload() : void{ - $this->buf->getSignedBlockPosition($this->blockX, $this->blockY, $this->blockZ); - $this->addUserData = $this->buf->getBool(); - $this->hotbarSlot = $this->buf->getByte(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $in->getSignedBlockPosition($this->blockX, $this->blockY, $this->blockZ); + $this->addUserData = $in->getBool(); + $this->hotbarSlot = $in->getByte(); } - protected function encodePayload() : void{ - $this->buf->putSignedBlockPosition($this->blockX, $this->blockY, $this->blockZ); - $this->buf->putBool($this->addUserData); - $this->buf->putByte($this->hotbarSlot); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putSignedBlockPosition($this->blockX, $this->blockY, $this->blockZ); + $out->putBool($this->addUserData); + $out->putByte($this->hotbarSlot); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/BookEditPacket.php b/src/network/mcpe/protocol/BookEditPacket.php index 6df127780b..3527009df4 100644 --- a/src/network/mcpe/protocol/BookEditPacket.php +++ b/src/network/mcpe/protocol/BookEditPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class BookEditPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::BOOK_EDIT_PACKET; @@ -58,56 +59,56 @@ class BookEditPacket extends DataPacket implements ServerboundPacket{ /** @var string */ public $xuid; - protected function decodePayload() : void{ - $this->type = $this->buf->getByte(); - $this->inventorySlot = $this->buf->getByte(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->type = $in->getByte(); + $this->inventorySlot = $in->getByte(); switch($this->type){ case self::TYPE_REPLACE_PAGE: case self::TYPE_ADD_PAGE: - $this->pageNumber = $this->buf->getByte(); - $this->text = $this->buf->getString(); - $this->photoName = $this->buf->getString(); + $this->pageNumber = $in->getByte(); + $this->text = $in->getString(); + $this->photoName = $in->getString(); break; case self::TYPE_DELETE_PAGE: - $this->pageNumber = $this->buf->getByte(); + $this->pageNumber = $in->getByte(); break; case self::TYPE_SWAP_PAGES: - $this->pageNumber = $this->buf->getByte(); - $this->secondaryPageNumber = $this->buf->getByte(); + $this->pageNumber = $in->getByte(); + $this->secondaryPageNumber = $in->getByte(); break; case self::TYPE_SIGN_BOOK: - $this->title = $this->buf->getString(); - $this->author = $this->buf->getString(); - $this->xuid = $this->buf->getString(); + $this->title = $in->getString(); + $this->author = $in->getString(); + $this->xuid = $in->getString(); break; default: throw new BadPacketException("Unknown book edit type $this->type!"); } } - protected function encodePayload() : void{ - $this->buf->putByte($this->type); - $this->buf->putByte($this->inventorySlot); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putByte($this->type); + $out->putByte($this->inventorySlot); switch($this->type){ case self::TYPE_REPLACE_PAGE: case self::TYPE_ADD_PAGE: - $this->buf->putByte($this->pageNumber); - $this->buf->putString($this->text); - $this->buf->putString($this->photoName); + $out->putByte($this->pageNumber); + $out->putString($this->text); + $out->putString($this->photoName); break; case self::TYPE_DELETE_PAGE: - $this->buf->putByte($this->pageNumber); + $out->putByte($this->pageNumber); break; case self::TYPE_SWAP_PAGES: - $this->buf->putByte($this->pageNumber); - $this->buf->putByte($this->secondaryPageNumber); + $out->putByte($this->pageNumber); + $out->putByte($this->secondaryPageNumber); break; case self::TYPE_SIGN_BOOK: - $this->buf->putString($this->title); - $this->buf->putString($this->author); - $this->buf->putString($this->xuid); + $out->putString($this->title); + $out->putString($this->author); + $out->putString($this->xuid); break; default: throw new \InvalidArgumentException("Unknown book edit type $this->type!"); diff --git a/src/network/mcpe/protocol/BossEventPacket.php b/src/network/mcpe/protocol/BossEventPacket.php index 460e9492d4..867cf19f9c 100644 --- a/src/network/mcpe/protocol/BossEventPacket.php +++ b/src/network/mcpe/protocol/BossEventPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class BossEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::BOSS_EVENT_PACKET; @@ -118,60 +119,60 @@ class BossEventPacket extends DataPacket implements ClientboundPacket, Serverbou return $result; } - protected function decodePayload() : void{ - $this->bossEid = $this->buf->getEntityUniqueId(); - $this->eventType = $this->buf->getUnsignedVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->bossEid = $in->getEntityUniqueId(); + $this->eventType = $in->getUnsignedVarInt(); switch($this->eventType){ case self::TYPE_REGISTER_PLAYER: case self::TYPE_UNREGISTER_PLAYER: - $this->playerEid = $this->buf->getEntityUniqueId(); + $this->playerEid = $in->getEntityUniqueId(); break; /** @noinspection PhpMissingBreakStatementInspection */ case self::TYPE_SHOW: - $this->title = $this->buf->getString(); - $this->healthPercent = $this->buf->getLFloat(); + $this->title = $in->getString(); + $this->healthPercent = $in->getLFloat(); /** @noinspection PhpMissingBreakStatementInspection */ case self::TYPE_UNKNOWN_6: - $this->unknownShort = $this->buf->getLShort(); + $this->unknownShort = $in->getLShort(); case self::TYPE_TEXTURE: - $this->color = $this->buf->getUnsignedVarInt(); - $this->overlay = $this->buf->getUnsignedVarInt(); + $this->color = $in->getUnsignedVarInt(); + $this->overlay = $in->getUnsignedVarInt(); break; case self::TYPE_HEALTH_PERCENT: - $this->healthPercent = $this->buf->getLFloat(); + $this->healthPercent = $in->getLFloat(); break; case self::TYPE_TITLE: - $this->title = $this->buf->getString(); + $this->title = $in->getString(); break; default: break; } } - protected function encodePayload() : void{ - $this->buf->putEntityUniqueId($this->bossEid); - $this->buf->putUnsignedVarInt($this->eventType); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityUniqueId($this->bossEid); + $out->putUnsignedVarInt($this->eventType); switch($this->eventType){ case self::TYPE_REGISTER_PLAYER: case self::TYPE_UNREGISTER_PLAYER: - $this->buf->putEntityUniqueId($this->playerEid); + $out->putEntityUniqueId($this->playerEid); break; /** @noinspection PhpMissingBreakStatementInspection */ case self::TYPE_SHOW: - $this->buf->putString($this->title); - $this->buf->putLFloat($this->healthPercent); + $out->putString($this->title); + $out->putLFloat($this->healthPercent); /** @noinspection PhpMissingBreakStatementInspection */ case self::TYPE_UNKNOWN_6: - $this->buf->putLShort($this->unknownShort); + $out->putLShort($this->unknownShort); case self::TYPE_TEXTURE: - $this->buf->putUnsignedVarInt($this->color); - $this->buf->putUnsignedVarInt($this->overlay); + $out->putUnsignedVarInt($this->color); + $out->putUnsignedVarInt($this->overlay); break; case self::TYPE_HEALTH_PERCENT: - $this->buf->putLFloat($this->healthPercent); + $out->putLFloat($this->healthPercent); break; case self::TYPE_TITLE: - $this->buf->putString($this->title); + $out->putString($this->title); break; default: break; diff --git a/src/network/mcpe/protocol/CameraPacket.php b/src/network/mcpe/protocol/CameraPacket.php index 81a3bfe074..bcdd42f6e2 100644 --- a/src/network/mcpe/protocol/CameraPacket.php +++ b/src/network/mcpe/protocol/CameraPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class CameraPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CAMERA_PACKET; @@ -35,14 +36,14 @@ class CameraPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $playerUniqueId; - protected function decodePayload() : void{ - $this->cameraUniqueId = $this->buf->getEntityUniqueId(); - $this->playerUniqueId = $this->buf->getEntityUniqueId(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->cameraUniqueId = $in->getEntityUniqueId(); + $this->playerUniqueId = $in->getEntityUniqueId(); } - protected function encodePayload() : void{ - $this->buf->putEntityUniqueId($this->cameraUniqueId); - $this->buf->putEntityUniqueId($this->playerUniqueId); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityUniqueId($this->cameraUniqueId); + $out->putEntityUniqueId($this->playerUniqueId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ChangeDimensionPacket.php b/src/network/mcpe/protocol/ChangeDimensionPacket.php index ac68ac1d14..03d38f11e9 100644 --- a/src/network/mcpe/protocol/ChangeDimensionPacket.php +++ b/src/network/mcpe/protocol/ChangeDimensionPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ChangeDimensionPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CHANGE_DIMENSION_PACKET; @@ -38,16 +39,16 @@ class ChangeDimensionPacket extends DataPacket implements ClientboundPacket{ /** @var bool */ public $respawn = false; - protected function decodePayload() : void{ - $this->dimension = $this->buf->getVarInt(); - $this->position = $this->buf->getVector3(); - $this->respawn = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->dimension = $in->getVarInt(); + $this->position = $in->getVector3(); + $this->respawn = $in->getBool(); } - protected function encodePayload() : void{ - $this->buf->putVarInt($this->dimension); - $this->buf->putVector3($this->position); - $this->buf->putBool($this->respawn); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putVarInt($this->dimension); + $out->putVector3($this->position); + $out->putBool($this->respawn); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php b/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php index 996dfc3c70..b42a1474a2 100644 --- a/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php +++ b/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ChunkRadiusUpdatedPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CHUNK_RADIUS_UPDATED_PACKET; @@ -39,12 +40,12 @@ class ChunkRadiusUpdatedPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload() : void{ - $this->radius = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->radius = $in->getVarInt(); } - protected function encodePayload() : void{ - $this->buf->putVarInt($this->radius); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putVarInt($this->radius); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php b/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php index 7954fa6bb5..2d3e6f19ef 100644 --- a/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php +++ b/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class ClientCacheBlobStatusPacket extends DataPacket implements ServerboundPacket{ @@ -65,25 +66,25 @@ class ClientCacheBlobStatusPacket extends DataPacket implements ServerboundPacke return $this->missHashes; } - protected function decodePayload() : void{ - $hitCount = $this->buf->getUnsignedVarInt(); - $missCount = $this->buf->getUnsignedVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $hitCount = $in->getUnsignedVarInt(); + $missCount = $in->getUnsignedVarInt(); for($i = 0; $i < $hitCount; ++$i){ - $this->hitHashes[] = $this->buf->getLLong(); + $this->hitHashes[] = $in->getLLong(); } for($i = 0; $i < $missCount; ++$i){ - $this->missHashes[] = $this->buf->getLLong(); + $this->missHashes[] = $in->getLLong(); } } - protected function encodePayload() : void{ - $this->buf->putUnsignedVarInt(count($this->hitHashes)); - $this->buf->putUnsignedVarInt(count($this->missHashes)); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putUnsignedVarInt(count($this->hitHashes)); + $out->putUnsignedVarInt(count($this->missHashes)); foreach($this->hitHashes as $hash){ - $this->buf->putLLong($hash); + $out->putLLong($hash); } foreach($this->missHashes as $hash){ - $this->buf->putLLong($hash); + $out->putLLong($hash); } } diff --git a/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php b/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php index 883859acc3..8029582d64 100644 --- a/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php +++ b/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\ChunkCacheBlob; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class ClientCacheMissResponsePacket extends DataPacket implements ClientboundPacket{ @@ -54,19 +55,19 @@ class ClientCacheMissResponsePacket extends DataPacket implements ClientboundPac return $this->blobs; } - protected function decodePayload() : void{ - for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ - $hash = $this->buf->getLLong(); - $payload = $this->buf->getString(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ + $hash = $in->getLLong(); + $payload = $in->getString(); $this->blobs[] = new ChunkCacheBlob($hash, $payload); } } - protected function encodePayload() : void{ - $this->buf->putUnsignedVarInt(count($this->blobs)); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putUnsignedVarInt(count($this->blobs)); foreach($this->blobs as $blob){ - $this->buf->putLLong($blob->getHash()); - $this->buf->putString($blob->getPayload()); + $out->putLLong($blob->getHash()); + $out->putString($blob->getPayload()); } } diff --git a/src/network/mcpe/protocol/ClientCacheStatusPacket.php b/src/network/mcpe/protocol/ClientCacheStatusPacket.php index 4b44f6dc18..f15bc3a6b8 100644 --- a/src/network/mcpe/protocol/ClientCacheStatusPacket.php +++ b/src/network/mcpe/protocol/ClientCacheStatusPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ClientCacheStatusPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::CLIENT_CACHE_STATUS_PACKET; @@ -43,12 +44,12 @@ class ClientCacheStatusPacket extends DataPacket implements ServerboundPacket{ return $this->enabled; } - protected function decodePayload() : void{ - $this->enabled = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->enabled = $in->getBool(); } - protected function encodePayload() : void{ - $this->buf->putBool($this->enabled); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putBool($this->enabled); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ClientToServerHandshakePacket.php b/src/network/mcpe/protocol/ClientToServerHandshakePacket.php index 697d462461..c141822ea6 100644 --- a/src/network/mcpe/protocol/ClientToServerHandshakePacket.php +++ b/src/network/mcpe/protocol/ClientToServerHandshakePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ClientToServerHandshakePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::CLIENT_TO_SERVER_HANDSHAKE_PACKET; @@ -34,11 +35,11 @@ class ClientToServerHandshakePacket extends DataPacket implements ServerboundPac return true; } - protected function decodePayload() : void{ + protected function decodePayload(NetworkBinaryStream $in) : void{ //No payload } - protected function encodePayload() : void{ + protected function encodePayload(NetworkBinaryStream $out) : void{ //No payload } diff --git a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php index d9be5178e8..f427b959c1 100644 --- a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php +++ b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php @@ -30,6 +30,7 @@ use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\protocol\types\MapDecoration; use pocketmine\network\mcpe\protocol\types\MapTrackedObject; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\Color; use function count; #ifndef COMPILE @@ -72,69 +73,69 @@ class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPack /** @var Color[][] */ public $colors = []; - protected function decodePayload() : void{ - $this->mapId = $this->buf->getEntityUniqueId(); - $this->type = $this->buf->getUnsignedVarInt(); - $this->dimensionId = $this->buf->getByte(); - $this->isLocked = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->mapId = $in->getEntityUniqueId(); + $this->type = $in->getUnsignedVarInt(); + $this->dimensionId = $in->getByte(); + $this->isLocked = $in->getBool(); if(($this->type & 0x08) !== 0){ - $count = $this->buf->getUnsignedVarInt(); + $count = $in->getUnsignedVarInt(); for($i = 0; $i < $count; ++$i){ - $this->eids[] = $this->buf->getEntityUniqueId(); + $this->eids[] = $in->getEntityUniqueId(); } } if(($this->type & (0x08 | self::BITFLAG_DECORATION_UPDATE | self::BITFLAG_TEXTURE_UPDATE)) !== 0){ //Decoration bitflag or colour bitflag - $this->scale = $this->buf->getByte(); + $this->scale = $in->getByte(); } if(($this->type & self::BITFLAG_DECORATION_UPDATE) !== 0){ - for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ + for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ $object = new MapTrackedObject(); - $object->type = $this->buf->getLInt(); + $object->type = $in->getLInt(); if($object->type === MapTrackedObject::TYPE_BLOCK){ - $this->buf->getBlockPosition($object->x, $object->y, $object->z); + $in->getBlockPosition($object->x, $object->y, $object->z); }elseif($object->type === MapTrackedObject::TYPE_ENTITY){ - $object->entityUniqueId = $this->buf->getEntityUniqueId(); + $object->entityUniqueId = $in->getEntityUniqueId(); }else{ throw new BadPacketException("Unknown map object type $object->type"); } $this->trackedEntities[] = $object; } - for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ - $icon = $this->buf->getByte(); - $rotation = $this->buf->getByte(); - $xOffset = $this->buf->getByte(); - $yOffset = $this->buf->getByte(); - $label = $this->buf->getString(); - $color = Color::fromRGBA(Binary::flipIntEndianness($this->buf->getUnsignedVarInt())); + for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ + $icon = $in->getByte(); + $rotation = $in->getByte(); + $xOffset = $in->getByte(); + $yOffset = $in->getByte(); + $label = $in->getString(); + $color = Color::fromRGBA(Binary::flipIntEndianness($in->getUnsignedVarInt())); $this->decorations[] = new MapDecoration($icon, $rotation, $xOffset, $yOffset, $label, $color); } } if(($this->type & self::BITFLAG_TEXTURE_UPDATE) !== 0){ - $this->width = $this->buf->getVarInt(); - $this->height = $this->buf->getVarInt(); - $this->xOffset = $this->buf->getVarInt(); - $this->yOffset = $this->buf->getVarInt(); + $this->width = $in->getVarInt(); + $this->height = $in->getVarInt(); + $this->xOffset = $in->getVarInt(); + $this->yOffset = $in->getVarInt(); - $count = $this->buf->getUnsignedVarInt(); + $count = $in->getUnsignedVarInt(); if($count !== $this->width * $this->height){ throw new BadPacketException("Expected colour count of " . ($this->height * $this->width) . " (height $this->height * width $this->width), got $count"); } for($y = 0; $y < $this->height; ++$y){ for($x = 0; $x < $this->width; ++$x){ - $this->colors[$y][$x] = Color::fromRGBA(Binary::flipIntEndianness($this->buf->getUnsignedVarInt())); + $this->colors[$y][$x] = Color::fromRGBA(Binary::flipIntEndianness($in->getUnsignedVarInt())); } } } } - protected function encodePayload() : void{ - $this->buf->putEntityUniqueId($this->mapId); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityUniqueId($this->mapId); $type = 0; if(($eidsCount = count($this->eids)) > 0){ @@ -147,57 +148,57 @@ class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPack $type |= self::BITFLAG_TEXTURE_UPDATE; } - $this->buf->putUnsignedVarInt($type); - $this->buf->putByte($this->dimensionId); - $this->buf->putBool($this->isLocked); + $out->putUnsignedVarInt($type); + $out->putByte($this->dimensionId); + $out->putBool($this->isLocked); if(($type & 0x08) !== 0){ //TODO: find out what these are for - $this->buf->putUnsignedVarInt($eidsCount); + $out->putUnsignedVarInt($eidsCount); foreach($this->eids as $eid){ - $this->buf->putEntityUniqueId($eid); + $out->putEntityUniqueId($eid); } } if(($type & (0x08 | self::BITFLAG_TEXTURE_UPDATE | self::BITFLAG_DECORATION_UPDATE)) !== 0){ - $this->buf->putByte($this->scale); + $out->putByte($this->scale); } if(($type & self::BITFLAG_DECORATION_UPDATE) !== 0){ - $this->buf->putUnsignedVarInt(count($this->trackedEntities)); + $out->putUnsignedVarInt(count($this->trackedEntities)); foreach($this->trackedEntities as $object){ - $this->buf->putLInt($object->type); + $out->putLInt($object->type); if($object->type === MapTrackedObject::TYPE_BLOCK){ - $this->buf->putBlockPosition($object->x, $object->y, $object->z); + $out->putBlockPosition($object->x, $object->y, $object->z); }elseif($object->type === MapTrackedObject::TYPE_ENTITY){ - $this->buf->putEntityUniqueId($object->entityUniqueId); + $out->putEntityUniqueId($object->entityUniqueId); }else{ throw new \InvalidArgumentException("Unknown map object type $object->type"); } } - $this->buf->putUnsignedVarInt($decorationCount); + $out->putUnsignedVarInt($decorationCount); foreach($this->decorations as $decoration){ - $this->buf->putByte($decoration->getIcon()); - $this->buf->putByte($decoration->getRotation()); - $this->buf->putByte($decoration->getXOffset()); - $this->buf->putByte($decoration->getYOffset()); - $this->buf->putString($decoration->getLabel()); - $this->buf->putUnsignedVarInt(Binary::flipIntEndianness($decoration->getColor()->toRGBA())); + $out->putByte($decoration->getIcon()); + $out->putByte($decoration->getRotation()); + $out->putByte($decoration->getXOffset()); + $out->putByte($decoration->getYOffset()); + $out->putString($decoration->getLabel()); + $out->putUnsignedVarInt(Binary::flipIntEndianness($decoration->getColor()->toRGBA())); } } if(($type & self::BITFLAG_TEXTURE_UPDATE) !== 0){ - $this->buf->putVarInt($this->width); - $this->buf->putVarInt($this->height); - $this->buf->putVarInt($this->xOffset); - $this->buf->putVarInt($this->yOffset); + $out->putVarInt($this->width); + $out->putVarInt($this->height); + $out->putVarInt($this->xOffset); + $out->putVarInt($this->yOffset); - $this->buf->putUnsignedVarInt($this->width * $this->height); //list count, but we handle it as a 2D array... thanks for the confusion mojang + $out->putUnsignedVarInt($this->width * $this->height); //list count, but we handle it as a 2D array... thanks for the confusion mojang for($y = 0; $y < $this->height; ++$y){ for($x = 0; $x < $this->width; ++$x){ //if mojang had any sense this would just be a regular LE int - $this->buf->putUnsignedVarInt(Binary::flipIntEndianness($this->colors[$y][$x]->toRGBA())); + $out->putUnsignedVarInt(Binary::flipIntEndianness($this->colors[$y][$x]->toRGBA())); } } } diff --git a/src/network/mcpe/protocol/CommandBlockUpdatePacket.php b/src/network/mcpe/protocol/CommandBlockUpdatePacket.php index 038e1bacb8..daa0df0393 100644 --- a/src/network/mcpe/protocol/CommandBlockUpdatePacket.php +++ b/src/network/mcpe/protocol/CommandBlockUpdatePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class CommandBlockUpdatePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::COMMAND_BLOCK_UPDATE_PACKET; @@ -62,47 +63,47 @@ class CommandBlockUpdatePacket extends DataPacket implements ServerboundPacket{ /** @var bool */ public $executeOnFirstTick; - protected function decodePayload() : void{ - $this->isBlock = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->isBlock = $in->getBool(); if($this->isBlock){ - $this->buf->getBlockPosition($this->x, $this->y, $this->z); - $this->commandBlockMode = $this->buf->getUnsignedVarInt(); - $this->isRedstoneMode = $this->buf->getBool(); - $this->isConditional = $this->buf->getBool(); + $in->getBlockPosition($this->x, $this->y, $this->z); + $this->commandBlockMode = $in->getUnsignedVarInt(); + $this->isRedstoneMode = $in->getBool(); + $this->isConditional = $in->getBool(); }else{ //Minecart with command block - $this->minecartEid = $this->buf->getEntityRuntimeId(); + $this->minecartEid = $in->getEntityRuntimeId(); } - $this->command = $this->buf->getString(); - $this->lastOutput = $this->buf->getString(); - $this->name = $this->buf->getString(); + $this->command = $in->getString(); + $this->lastOutput = $in->getString(); + $this->name = $in->getString(); - $this->shouldTrackOutput = $this->buf->getBool(); - $this->tickDelay = $this->buf->getLInt(); - $this->executeOnFirstTick = $this->buf->getBool(); + $this->shouldTrackOutput = $in->getBool(); + $this->tickDelay = $in->getLInt(); + $this->executeOnFirstTick = $in->getBool(); } - protected function encodePayload() : void{ - $this->buf->putBool($this->isBlock); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putBool($this->isBlock); if($this->isBlock){ - $this->buf->putBlockPosition($this->x, $this->y, $this->z); - $this->buf->putUnsignedVarInt($this->commandBlockMode); - $this->buf->putBool($this->isRedstoneMode); - $this->buf->putBool($this->isConditional); + $out->putBlockPosition($this->x, $this->y, $this->z); + $out->putUnsignedVarInt($this->commandBlockMode); + $out->putBool($this->isRedstoneMode); + $out->putBool($this->isConditional); }else{ - $this->buf->putEntityRuntimeId($this->minecartEid); + $out->putEntityRuntimeId($this->minecartEid); } - $this->buf->putString($this->command); - $this->buf->putString($this->lastOutput); - $this->buf->putString($this->name); + $out->putString($this->command); + $out->putString($this->lastOutput); + $out->putString($this->name); - $this->buf->putBool($this->shouldTrackOutput); - $this->buf->putLInt($this->tickDelay); - $this->buf->putBool($this->executeOnFirstTick); + $out->putBool($this->shouldTrackOutput); + $out->putLInt($this->tickDelay); + $out->putBool($this->executeOnFirstTick); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/CommandOutputPacket.php b/src/network/mcpe/protocol/CommandOutputPacket.php index ec15f581ec..f01f5467c9 100644 --- a/src/network/mcpe/protocol/CommandOutputPacket.php +++ b/src/network/mcpe/protocol/CommandOutputPacket.php @@ -28,6 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; use pocketmine\network\mcpe\protocol\types\command\CommandOutputMessage; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; use function count; @@ -45,58 +46,58 @@ class CommandOutputPacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $unknownString; - protected function decodePayload() : void{ - $this->originData = $this->buf->getCommandOriginData(); - $this->outputType = $this->buf->getByte(); - $this->successCount = $this->buf->getUnsignedVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->originData = $in->getCommandOriginData(); + $this->outputType = $in->getByte(); + $this->successCount = $in->getUnsignedVarInt(); - for($i = 0, $size = $this->buf->getUnsignedVarInt(); $i < $size; ++$i){ - $this->messages[] = $this->getCommandMessage(); + for($i = 0, $size = $in->getUnsignedVarInt(); $i < $size; ++$i){ + $this->messages[] = $this->getCommandMessage($in); } if($this->outputType === 4){ - $this->unknownString = $this->buf->getString(); + $this->unknownString = $in->getString(); } } /** * @throws BinaryDataException */ - protected function getCommandMessage() : CommandOutputMessage{ + protected function getCommandMessage(NetworkBinaryStream $in) : CommandOutputMessage{ $message = new CommandOutputMessage(); - $message->isInternal = $this->buf->getBool(); - $message->messageId = $this->buf->getString(); + $message->isInternal = $in->getBool(); + $message->messageId = $in->getString(); - for($i = 0, $size = $this->buf->getUnsignedVarInt(); $i < $size; ++$i){ - $message->parameters[] = $this->buf->getString(); + for($i = 0, $size = $in->getUnsignedVarInt(); $i < $size; ++$i){ + $message->parameters[] = $in->getString(); } return $message; } - protected function encodePayload() : void{ - $this->buf->putCommandOriginData($this->originData); - $this->buf->putByte($this->outputType); - $this->buf->putUnsignedVarInt($this->successCount); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putCommandOriginData($this->originData); + $out->putByte($this->outputType); + $out->putUnsignedVarInt($this->successCount); - $this->buf->putUnsignedVarInt(count($this->messages)); + $out->putUnsignedVarInt(count($this->messages)); foreach($this->messages as $message){ - $this->putCommandMessage($message); + $this->putCommandMessage($message, $out); } if($this->outputType === 4){ - $this->buf->putString($this->unknownString); + $out->putString($this->unknownString); } } - protected function putCommandMessage(CommandOutputMessage $message) : void{ - $this->buf->putBool($message->isInternal); - $this->buf->putString($message->messageId); + protected function putCommandMessage(CommandOutputMessage $message, NetworkBinaryStream $out) : void{ + $out->putBool($message->isInternal); + $out->putString($message->messageId); - $this->buf->putUnsignedVarInt(count($message->parameters)); + $out->putUnsignedVarInt(count($message->parameters)); foreach($message->parameters as $parameter){ - $this->buf->putString($parameter); + $out->putString($parameter); } } diff --git a/src/network/mcpe/protocol/CommandRequestPacket.php b/src/network/mcpe/protocol/CommandRequestPacket.php index ab49ada1f8..682a074a44 100644 --- a/src/network/mcpe/protocol/CommandRequestPacket.php +++ b/src/network/mcpe/protocol/CommandRequestPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class CommandRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::COMMAND_REQUEST_PACKET; @@ -38,16 +39,16 @@ class CommandRequestPacket extends DataPacket implements ServerboundPacket{ /** @var bool */ public $isInternal; - protected function decodePayload() : void{ - $this->command = $this->buf->getString(); - $this->originData = $this->buf->getCommandOriginData(); - $this->isInternal = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->command = $in->getString(); + $this->originData = $in->getCommandOriginData(); + $this->isInternal = $in->getBool(); } - protected function encodePayload() : void{ - $this->buf->putString($this->command); - $this->buf->putCommandOriginData($this->originData); - $this->buf->putBool($this->isInternal); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->command); + $out->putCommandOriginData($this->originData); + $out->putBool($this->isInternal); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/CompletedUsingItemPacket.php b/src/network/mcpe/protocol/CompletedUsingItemPacket.php index 4e7e4724a9..72d84a3d2f 100644 --- a/src/network/mcpe/protocol/CompletedUsingItemPacket.php +++ b/src/network/mcpe/protocol/CompletedUsingItemPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class CompletedUsingItemPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::COMPLETED_USING_ITEM_PACKET; @@ -52,14 +53,14 @@ class CompletedUsingItemPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $action; - public function decodePayload() : void{ - $this->itemId = $this->buf->getShort(); - $this->action = $this->buf->getLInt(); + public function decodePayload(NetworkBinaryStream $in) : void{ + $this->itemId = $in->getShort(); + $this->action = $in->getLInt(); } - public function encodePayload() : void{ - $this->buf->putShort($this->itemId); - $this->buf->putLInt($this->action); + public function encodePayload(NetworkBinaryStream $out) : void{ + $out->putShort($this->itemId); + $out->putLInt($this->action); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ContainerClosePacket.php b/src/network/mcpe/protocol/ContainerClosePacket.php index 13a6948625..a0bc2f688c 100644 --- a/src/network/mcpe/protocol/ContainerClosePacket.php +++ b/src/network/mcpe/protocol/ContainerClosePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ContainerClosePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::CONTAINER_CLOSE_PACKET; @@ -39,12 +40,12 @@ class ContainerClosePacket extends DataPacket implements ClientboundPacket, Serv return $result; } - protected function decodePayload() : void{ - $this->windowId = $this->buf->getByte(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->windowId = $in->getByte(); } - protected function encodePayload() : void{ - $this->buf->putByte($this->windowId); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putByte($this->windowId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ContainerOpenPacket.php b/src/network/mcpe/protocol/ContainerOpenPacket.php index f45eccc064..0ac5907722 100644 --- a/src/network/mcpe/protocol/ContainerOpenPacket.php +++ b/src/network/mcpe/protocol/ContainerOpenPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ContainerOpenPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CONTAINER_OPEN_PACKET; @@ -65,18 +66,18 @@ class ContainerOpenPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload() : void{ - $this->windowId = $this->buf->getByte(); - $this->type = $this->buf->getByte(); - $this->buf->getBlockPosition($this->x, $this->y, $this->z); - $this->entityUniqueId = $this->buf->getEntityUniqueId(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->windowId = $in->getByte(); + $this->type = $in->getByte(); + $in->getBlockPosition($this->x, $this->y, $this->z); + $this->entityUniqueId = $in->getEntityUniqueId(); } - protected function encodePayload() : void{ - $this->buf->putByte($this->windowId); - $this->buf->putByte($this->type); - $this->buf->putBlockPosition($this->x, $this->y, $this->z); - $this->buf->putEntityUniqueId($this->entityUniqueId); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putByte($this->windowId); + $out->putByte($this->type); + $out->putBlockPosition($this->x, $this->y, $this->z); + $out->putEntityUniqueId($this->entityUniqueId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ContainerSetDataPacket.php b/src/network/mcpe/protocol/ContainerSetDataPacket.php index a67b3f2d3d..a7c2507ab8 100644 --- a/src/network/mcpe/protocol/ContainerSetDataPacket.php +++ b/src/network/mcpe/protocol/ContainerSetDataPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ContainerSetDataPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CONTAINER_SET_DATA_PACKET; @@ -55,16 +56,16 @@ class ContainerSetDataPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload() : void{ - $this->windowId = $this->buf->getByte(); - $this->property = $this->buf->getVarInt(); - $this->value = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->windowId = $in->getByte(); + $this->property = $in->getVarInt(); + $this->value = $in->getVarInt(); } - protected function encodePayload() : void{ - $this->buf->putByte($this->windowId); - $this->buf->putVarInt($this->property); - $this->buf->putVarInt($this->value); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putByte($this->windowId); + $out->putVarInt($this->property); + $out->putVarInt($this->value); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/CraftingDataPacket.php b/src/network/mcpe/protocol/CraftingDataPacket.php index 362f10d28e..e6a7cce039 100644 --- a/src/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/network/mcpe/protocol/CraftingDataPacket.php @@ -65,62 +65,62 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{ /** @var mixed[][] */ public $decodedEntries = []; - protected function decodePayload() : void{ + protected function decodePayload(NetworkBinaryStream $in) : void{ $this->decodedEntries = []; - $recipeCount = $this->buf->getUnsignedVarInt(); + $recipeCount = $in->getUnsignedVarInt(); for($i = 0; $i < $recipeCount; ++$i){ $entry = []; - $entry["type"] = $recipeType = $this->buf->getVarInt(); + $entry["type"] = $recipeType = $in->getVarInt(); switch($recipeType){ case self::ENTRY_SHAPELESS: case self::ENTRY_SHULKER_BOX: case self::ENTRY_SHAPELESS_CHEMISTRY: - $entry["recipe_id"] = $this->buf->getString(); - $ingredientCount = $this->buf->getUnsignedVarInt(); + $entry["recipe_id"] = $in->getString(); + $ingredientCount = $in->getUnsignedVarInt(); /** @var Item */ $entry["input"] = []; for($j = 0; $j < $ingredientCount; ++$j){ - $entry["input"][] = $in = $this->buf->getRecipeIngredient(); + $entry["input"][] = $in = $in->getRecipeIngredient(); $in->setCount(1); //TODO HACK: they send a useless count field which breaks the PM crafting system because it isn't always 1 } - $resultCount = $this->buf->getUnsignedVarInt(); + $resultCount = $in->getUnsignedVarInt(); $entry["output"] = []; for($k = 0; $k < $resultCount; ++$k){ - $entry["output"][] = $this->buf->getSlot(); + $entry["output"][] = $in->getSlot(); } - $entry["uuid"] = $this->buf->getUUID()->toString(); - $entry["block"] = $this->buf->getString(); - $entry["priority"] = $this->buf->getVarInt(); + $entry["uuid"] = $in->getUUID()->toString(); + $entry["block"] = $in->getString(); + $entry["priority"] = $in->getVarInt(); break; case self::ENTRY_SHAPED: case self::ENTRY_SHAPED_CHEMISTRY: - $entry["recipe_id"] = $this->buf->getString(); - $entry["width"] = $this->buf->getVarInt(); - $entry["height"] = $this->buf->getVarInt(); + $entry["recipe_id"] = $in->getString(); + $entry["width"] = $in->getVarInt(); + $entry["height"] = $in->getVarInt(); $count = $entry["width"] * $entry["height"]; $entry["input"] = []; for($j = 0; $j < $count; ++$j){ - $entry["input"][] = $in = $this->buf->getRecipeIngredient(); + $entry["input"][] = $in = $in->getRecipeIngredient(); $in->setCount(1); //TODO HACK: they send a useless count field which breaks the PM crafting system } - $resultCount = $this->buf->getUnsignedVarInt(); + $resultCount = $in->getUnsignedVarInt(); $entry["output"] = []; for($k = 0; $k < $resultCount; ++$k){ - $entry["output"][] = $this->buf->getSlot(); + $entry["output"][] = $in->getSlot(); } - $entry["uuid"] = $this->buf->getUUID()->toString(); - $entry["block"] = $this->buf->getString(); - $entry["priority"] = $this->buf->getVarInt(); + $entry["uuid"] = $in->getUUID()->toString(); + $entry["block"] = $in->getString(); + $entry["priority"] = $in->getVarInt(); break; case self::ENTRY_FURNACE: case self::ENTRY_FURNACE_DATA: - $inputId = $this->buf->getVarInt(); + $inputId = $in->getVarInt(); $inputData = -1; if($recipeType === self::ENTRY_FURNACE_DATA){ - $inputData = $this->buf->getVarInt(); + $inputData = $in->getVarInt(); if($inputData === 0x7fff){ $inputData = -1; } @@ -130,34 +130,34 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{ }catch(\InvalidArgumentException $e){ throw new BadPacketException($e->getMessage(), 0, $e); } - $entry["output"] = $out = $this->buf->getSlot(); + $entry["output"] = $out = $in->getSlot(); if($out->getMeta() === 0x7fff){ $entry["output"] = ItemFactory::get($out->getId(), 0); //TODO HACK: some 1.12 furnace recipe outputs have wildcard damage values } - $entry["block"] = $this->buf->getString(); + $entry["block"] = $in->getString(); break; case self::ENTRY_MULTI: - $entry["uuid"] = $this->buf->getUUID()->toString(); + $entry["uuid"] = $in->getUUID()->toString(); break; default: throw new BadPacketException("Unhandled recipe type $recipeType!"); //do not continue attempting to decode } $this->decodedEntries[] = $entry; } - for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ - $input = $this->buf->getVarInt(); - $ingredient = $this->buf->getVarInt(); - $output = $this->buf->getVarInt(); + for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ + $input = $in->getVarInt(); + $ingredient = $in->getVarInt(); + $output = $in->getVarInt(); $this->potionTypeRecipes[] = new PotionTypeRecipe($input, $ingredient, $output); } - for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ - $input = $this->buf->getVarInt(); - $ingredient = $this->buf->getVarInt(); - $output = $this->buf->getVarInt(); + for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ + $input = $in->getVarInt(); + $ingredient = $in->getVarInt(); + $output = $in->getVarInt(); $this->potionContainerRecipes[] = new PotionContainerChangeRecipe($input, $ingredient, $output); } - $this->cleanRecipes = $this->buf->getBool(); + $this->cleanRecipes = $in->getBool(); } /** @@ -244,36 +244,36 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{ $this->entries[] = $recipe; } - protected function encodePayload() : void{ - $this->buf->putUnsignedVarInt(count($this->entries)); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putUnsignedVarInt(count($this->entries)); $writer = new NetworkBinaryStream(); $counter = 0; foreach($this->entries as $d){ $entryType = self::writeEntry($d, $writer, $counter++); if($entryType >= 0){ - $this->buf->putVarInt($entryType); - $this->buf->put($writer->getBuffer()); + $out->putVarInt($entryType); + $out->put($writer->getBuffer()); }else{ - $this->buf->putVarInt(-1); + $out->putVarInt(-1); } $writer->reset(); } - $this->buf->putUnsignedVarInt(count($this->potionTypeRecipes)); + $out->putUnsignedVarInt(count($this->potionTypeRecipes)); foreach($this->potionTypeRecipes as $recipe){ - $this->buf->putVarInt($recipe->getInputPotionType()); - $this->buf->putVarInt($recipe->getIngredientItemId()); - $this->buf->putVarInt($recipe->getOutputPotionType()); + $out->putVarInt($recipe->getInputPotionType()); + $out->putVarInt($recipe->getIngredientItemId()); + $out->putVarInt($recipe->getOutputPotionType()); } - $this->buf->putUnsignedVarInt(count($this->potionContainerRecipes)); + $out->putUnsignedVarInt(count($this->potionContainerRecipes)); foreach($this->potionContainerRecipes as $recipe){ - $this->buf->putVarInt($recipe->getInputItemId()); - $this->buf->putVarInt($recipe->getIngredientItemId()); - $this->buf->putVarInt($recipe->getOutputItemId()); + $out->putVarInt($recipe->getInputItemId()); + $out->putVarInt($recipe->getIngredientItemId()); + $out->putVarInt($recipe->getOutputItemId()); } - $this->buf->putBool($this->cleanRecipes); + $out->putBool($this->cleanRecipes); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/CraftingEventPacket.php b/src/network/mcpe/protocol/CraftingEventPacket.php index e932aa08a2..b932f839b2 100644 --- a/src/network/mcpe/protocol/CraftingEventPacket.php +++ b/src/network/mcpe/protocol/CraftingEventPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\item\Item; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\UUID; use function count; @@ -44,35 +45,35 @@ class CraftingEventPacket extends DataPacket implements ServerboundPacket{ /** @var Item[] */ public $output = []; - protected function decodePayload() : void{ - $this->windowId = $this->buf->getByte(); - $this->type = $this->buf->getVarInt(); - $this->id = $this->buf->getUUID(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->windowId = $in->getByte(); + $this->type = $in->getVarInt(); + $this->id = $in->getUUID(); - $size = $this->buf->getUnsignedVarInt(); + $size = $in->getUnsignedVarInt(); for($i = 0; $i < $size and $i < 128; ++$i){ - $this->input[] = $this->buf->getSlot(); + $this->input[] = $in->getSlot(); } - $size = $this->buf->getUnsignedVarInt(); + $size = $in->getUnsignedVarInt(); for($i = 0; $i < $size and $i < 128; ++$i){ - $this->output[] = $this->buf->getSlot(); + $this->output[] = $in->getSlot(); } } - protected function encodePayload() : void{ - $this->buf->putByte($this->windowId); - $this->buf->putVarInt($this->type); - $this->buf->putUUID($this->id); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putByte($this->windowId); + $out->putVarInt($this->type); + $out->putUUID($this->id); - $this->buf->putUnsignedVarInt(count($this->input)); + $out->putUnsignedVarInt(count($this->input)); foreach($this->input as $item){ - $this->buf->putSlot($item); + $out->putSlot($item); } - $this->buf->putUnsignedVarInt(count($this->output)); + $out->putUnsignedVarInt(count($this->output)); foreach($this->output as $item){ - $this->buf->putSlot($item); + $out->putSlot($item); } } diff --git a/src/network/mcpe/protocol/DataPacket.php b/src/network/mcpe/protocol/DataPacket.php index 051fa9af27..157c83b69f 100644 --- a/src/network/mcpe/protocol/DataPacket.php +++ b/src/network/mcpe/protocol/DataPacket.php @@ -51,7 +51,7 @@ abstract class DataPacket implements Packet{ public $recipientSubId = 0; /** @var NetworkBinaryStream */ - protected $buf; + private $buf; public function __construct(){ $this->buf = new NetworkBinaryStream(); @@ -79,8 +79,8 @@ abstract class DataPacket implements Packet{ final public function decode() : void{ $this->buf->rewind(); try{ - $this->decodeHeader(); - $this->decodePayload(); + $this->decodeHeader($this->buf); + $this->decodePayload($this->buf); }catch(BinaryDataException | BadPacketException $e){ throw new BadPacketException($this->getName() . ": " . $e->getMessage(), 0, $e); } @@ -90,8 +90,8 @@ abstract class DataPacket implements Packet{ * @throws BinaryDataException * @throws \UnexpectedValueException */ - protected function decodeHeader() : void{ - $header = $this->buf->getUnsignedVarInt(); + protected function decodeHeader(NetworkBinaryStream $in) : void{ + $header = $in->getUnsignedVarInt(); $pid = $header & self::PID_MASK; if($pid !== static::NETWORK_ID){ //TODO: this means a logical error in the code, but how to prevent it from happening? @@ -108,16 +108,16 @@ abstract class DataPacket implements Packet{ * @throws BadPacketException * @throws BinaryDataException */ - abstract protected function decodePayload() : void; + abstract protected function decodePayload(NetworkBinaryStream $in) : void; final public function encode() : void{ $this->buf->reset(); - $this->encodeHeader(); - $this->encodePayload(); + $this->encodeHeader($this->buf); + $this->encodePayload($this->buf); } - protected function encodeHeader() : void{ - $this->buf->putUnsignedVarInt( + protected function encodeHeader(NetworkBinaryStream $out) : void{ + $out->putUnsignedVarInt( static::NETWORK_ID | ($this->senderSubId << self::SENDER_SUBCLIENT_ID_SHIFT) | ($this->recipientSubId << self::RECIPIENT_SUBCLIENT_ID_SHIFT) @@ -127,7 +127,7 @@ abstract class DataPacket implements Packet{ /** * Encodes the packet body, without the packet ID or other generic header fields. */ - abstract protected function encodePayload() : void; + abstract protected function encodePayload(NetworkBinaryStream $out) : void; /** * @param string $name diff --git a/src/network/mcpe/protocol/DisconnectPacket.php b/src/network/mcpe/protocol/DisconnectPacket.php index 25f84743fc..e9ec1cbbd6 100644 --- a/src/network/mcpe/protocol/DisconnectPacket.php +++ b/src/network/mcpe/protocol/DisconnectPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class DisconnectPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::DISCONNECT_PACKET; @@ -52,17 +53,17 @@ class DisconnectPacket extends DataPacket implements ClientboundPacket, Serverbo return true; } - protected function decodePayload() : void{ - $this->hideDisconnectionScreen = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->hideDisconnectionScreen = $in->getBool(); if(!$this->hideDisconnectionScreen){ - $this->message = $this->buf->getString(); + $this->message = $in->getString(); } } - protected function encodePayload() : void{ - $this->buf->putBool($this->hideDisconnectionScreen); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putBool($this->hideDisconnectionScreen); if(!$this->hideDisconnectionScreen){ - $this->buf->putString($this->message); + $out->putString($this->message); } } diff --git a/src/network/mcpe/protocol/EducationSettingsPacket.php b/src/network/mcpe/protocol/EducationSettingsPacket.php index a561b5acb8..264e34de07 100644 --- a/src/network/mcpe/protocol/EducationSettingsPacket.php +++ b/src/network/mcpe/protocol/EducationSettingsPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class EducationSettingsPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::EDUCATION_SETTINGS_PACKET; @@ -50,14 +51,14 @@ class EducationSettingsPacket extends DataPacket implements ClientboundPacket{ return $this->hasQuiz; } - protected function decodePayload() : void{ - $this->codeBuilderDefaultUri = $this->buf->getString(); - $this->hasQuiz = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->codeBuilderDefaultUri = $in->getString(); + $this->hasQuiz = $in->getBool(); } - protected function encodePayload() : void{ - $this->buf->putString($this->codeBuilderDefaultUri); - $this->buf->putBool($this->hasQuiz); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->codeBuilderDefaultUri); + $out->putBool($this->hasQuiz); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/EmotePacket.php b/src/network/mcpe/protocol/EmotePacket.php index 23194e6809..76ff71c18a 100644 --- a/src/network/mcpe/protocol/EmotePacket.php +++ b/src/network/mcpe/protocol/EmotePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class EmotePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::EMOTE_PACKET; @@ -62,16 +63,16 @@ class EmotePacket extends DataPacket implements ClientboundPacket, ServerboundPa return $this->flags; } - protected function decodePayload() : void{ - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); - $this->emoteId = $this->buf->getString(); - $this->flags = $this->buf->getByte(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityRuntimeId = $in->getEntityRuntimeId(); + $this->emoteId = $in->getString(); + $this->flags = $in->getByte(); } - protected function encodePayload() : void{ - $this->buf->putEntityRuntimeId($this->entityRuntimeId); - $this->buf->putString($this->emoteId); - $this->buf->putByte($this->flags); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityRuntimeId($this->entityRuntimeId); + $out->putString($this->emoteId); + $out->putByte($this->flags); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/EventPacket.php b/src/network/mcpe/protocol/EventPacket.php index 6dffeb7b4d..882e2c2418 100644 --- a/src/network/mcpe/protocol/EventPacket.php +++ b/src/network/mcpe/protocol/EventPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class EventPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::EVENT_PACKET; @@ -56,18 +57,18 @@ class EventPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $type; - protected function decodePayload() : void{ - $this->playerRuntimeId = $this->buf->getEntityRuntimeId(); - $this->eventData = $this->buf->getVarInt(); - $this->type = $this->buf->getByte(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->playerRuntimeId = $in->getEntityRuntimeId(); + $this->eventData = $in->getVarInt(); + $this->type = $in->getByte(); //TODO: nice confusing mess } - protected function encodePayload() : void{ - $this->buf->putEntityRuntimeId($this->playerRuntimeId); - $this->buf->putVarInt($this->eventData); - $this->buf->putByte($this->type); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityRuntimeId($this->playerRuntimeId); + $out->putVarInt($this->eventData); + $out->putByte($this->type); //TODO: also nice confusing mess } diff --git a/src/network/mcpe/protocol/GameRulesChangedPacket.php b/src/network/mcpe/protocol/GameRulesChangedPacket.php index 7acbe1abcb..f1249f87a8 100644 --- a/src/network/mcpe/protocol/GameRulesChangedPacket.php +++ b/src/network/mcpe/protocol/GameRulesChangedPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class GameRulesChangedPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::GAME_RULES_CHANGED_PACKET; @@ -36,12 +37,12 @@ class GameRulesChangedPacket extends DataPacket implements ClientboundPacket{ */ public $gameRules = []; - protected function decodePayload() : void{ - $this->gameRules = $this->buf->getGameRules(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->gameRules = $in->getGameRules(); } - protected function encodePayload() : void{ - $this->buf->putGameRules($this->gameRules); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putGameRules($this->gameRules); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/GuiDataPickItemPacket.php b/src/network/mcpe/protocol/GuiDataPickItemPacket.php index f898dc6b1c..8207256511 100644 --- a/src/network/mcpe/protocol/GuiDataPickItemPacket.php +++ b/src/network/mcpe/protocol/GuiDataPickItemPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class GuiDataPickItemPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::GUI_DATA_PICK_ITEM_PACKET; @@ -37,16 +38,16 @@ class GuiDataPickItemPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $hotbarSlot; - protected function decodePayload() : void{ - $this->itemDescription = $this->buf->getString(); - $this->itemEffects = $this->buf->getString(); - $this->hotbarSlot = $this->buf->getLInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->itemDescription = $in->getString(); + $this->itemEffects = $in->getString(); + $this->hotbarSlot = $in->getLInt(); } - protected function encodePayload() : void{ - $this->buf->putString($this->itemDescription); - $this->buf->putString($this->itemEffects); - $this->buf->putLInt($this->hotbarSlot); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->itemDescription); + $out->putString($this->itemEffects); + $out->putLInt($this->hotbarSlot); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/HurtArmorPacket.php b/src/network/mcpe/protocol/HurtArmorPacket.php index 7ad5174a28..a53cf4d15f 100644 --- a/src/network/mcpe/protocol/HurtArmorPacket.php +++ b/src/network/mcpe/protocol/HurtArmorPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class HurtArmorPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::HURT_ARMOR_PACKET; @@ -33,12 +34,12 @@ class HurtArmorPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $health; - protected function decodePayload() : void{ - $this->health = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->health = $in->getVarInt(); } - protected function encodePayload() : void{ - $this->buf->putVarInt($this->health); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putVarInt($this->health); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/InteractPacket.php b/src/network/mcpe/protocol/InteractPacket.php index 715b248092..38c8e2a2b3 100644 --- a/src/network/mcpe/protocol/InteractPacket.php +++ b/src/network/mcpe/protocol/InteractPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class InteractPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::INTERACT_PACKET; @@ -47,26 +48,26 @@ class InteractPacket extends DataPacket implements ServerboundPacket{ /** @var float */ public $z; - protected function decodePayload() : void{ - $this->action = $this->buf->getByte(); - $this->target = $this->buf->getEntityRuntimeId(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->action = $in->getByte(); + $this->target = $in->getEntityRuntimeId(); if($this->action === self::ACTION_MOUSEOVER){ //TODO: should this be a vector3? - $this->x = $this->buf->getLFloat(); - $this->y = $this->buf->getLFloat(); - $this->z = $this->buf->getLFloat(); + $this->x = $in->getLFloat(); + $this->y = $in->getLFloat(); + $this->z = $in->getLFloat(); } } - protected function encodePayload() : void{ - $this->buf->putByte($this->action); - $this->buf->putEntityRuntimeId($this->target); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putByte($this->action); + $out->putEntityRuntimeId($this->target); if($this->action === self::ACTION_MOUSEOVER){ - $this->buf->putLFloat($this->x); - $this->buf->putLFloat($this->y); - $this->buf->putLFloat($this->z); + $out->putLFloat($this->x); + $out->putLFloat($this->y); + $out->putLFloat($this->z); } } diff --git a/src/network/mcpe/protocol/InventoryContentPacket.php b/src/network/mcpe/protocol/InventoryContentPacket.php index 0375a651b5..2490b9b793 100644 --- a/src/network/mcpe/protocol/InventoryContentPacket.php +++ b/src/network/mcpe/protocol/InventoryContentPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\item\Item; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class InventoryContentPacket extends DataPacket implements ClientboundPacket{ @@ -49,19 +50,19 @@ class InventoryContentPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload() : void{ - $this->windowId = $this->buf->getUnsignedVarInt(); - $count = $this->buf->getUnsignedVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->windowId = $in->getUnsignedVarInt(); + $count = $in->getUnsignedVarInt(); for($i = 0; $i < $count; ++$i){ - $this->items[] = $this->buf->getSlot(); + $this->items[] = $in->getSlot(); } } - protected function encodePayload() : void{ - $this->buf->putUnsignedVarInt($this->windowId); - $this->buf->putUnsignedVarInt(count($this->items)); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putUnsignedVarInt($this->windowId); + $out->putUnsignedVarInt(count($this->items)); foreach($this->items as $item){ - $this->buf->putSlot($item); + $out->putSlot($item); } } diff --git a/src/network/mcpe/protocol/InventorySlotPacket.php b/src/network/mcpe/protocol/InventorySlotPacket.php index 6c9c526ddc..24632bc6e5 100644 --- a/src/network/mcpe/protocol/InventorySlotPacket.php +++ b/src/network/mcpe/protocol/InventorySlotPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\item\Item; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class InventorySlotPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::INVENTORY_SLOT_PACKET; @@ -46,16 +47,16 @@ class InventorySlotPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload() : void{ - $this->windowId = $this->buf->getUnsignedVarInt(); - $this->inventorySlot = $this->buf->getUnsignedVarInt(); - $this->item = $this->buf->getSlot(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->windowId = $in->getUnsignedVarInt(); + $this->inventorySlot = $in->getUnsignedVarInt(); + $this->item = $in->getSlot(); } - protected function encodePayload() : void{ - $this->buf->putUnsignedVarInt($this->windowId); - $this->buf->putUnsignedVarInt($this->inventorySlot); - $this->buf->putSlot($this->item); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putUnsignedVarInt($this->windowId); + $out->putUnsignedVarInt($this->inventorySlot); + $out->putSlot($this->item); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/InventoryTransactionPacket.php b/src/network/mcpe/protocol/InventoryTransactionPacket.php index 9d34042528..c3f99e55c5 100644 --- a/src/network/mcpe/protocol/InventoryTransactionPacket.php +++ b/src/network/mcpe/protocol/InventoryTransactionPacket.php @@ -33,6 +33,7 @@ use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\TransactionData; use pocketmine\network\mcpe\protocol\types\inventory\UseItemOnEntityTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\UseItemTransactionData; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; /** * This packet effectively crams multiple packets into one. @@ -49,8 +50,8 @@ class InventoryTransactionPacket extends DataPacket implements ClientboundPacket /** @var TransactionData */ public $trData; - protected function decodePayload() : void{ - $transactionType = $this->buf->getUnsignedVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $transactionType = $in->getUnsignedVarInt(); switch($transactionType){ case self::TYPE_NORMAL: @@ -72,12 +73,12 @@ class InventoryTransactionPacket extends DataPacket implements ClientboundPacket throw new BadPacketException("Unknown transaction type $transactionType"); } - $this->trData->decode($this->buf); + $this->trData->decode($in); } - protected function encodePayload() : void{ - $this->buf->putUnsignedVarInt($this->trData->getTypeId()); - $this->trData->encode($this->buf); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putUnsignedVarInt($this->trData->getTypeId()); + $this->trData->encode($out); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ItemFrameDropItemPacket.php b/src/network/mcpe/protocol/ItemFrameDropItemPacket.php index f9bfb9753e..bac21044af 100644 --- a/src/network/mcpe/protocol/ItemFrameDropItemPacket.php +++ b/src/network/mcpe/protocol/ItemFrameDropItemPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ItemFrameDropItemPacket extends DataPacket implements ServerboundPacket{ @@ -38,12 +39,12 @@ class ItemFrameDropItemPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $z; - protected function decodePayload() : void{ - $this->buf->getBlockPosition($this->x, $this->y, $this->z); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $in->getBlockPosition($this->x, $this->y, $this->z); } - protected function encodePayload() : void{ - $this->buf->putBlockPosition($this->x, $this->y, $this->z); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putBlockPosition($this->x, $this->y, $this->z); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/LabTablePacket.php b/src/network/mcpe/protocol/LabTablePacket.php index 09a5b11310..801c7d50e3 100644 --- a/src/network/mcpe/protocol/LabTablePacket.php +++ b/src/network/mcpe/protocol/LabTablePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class LabTablePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::LAB_TABLE_PACKET; @@ -43,16 +44,16 @@ class LabTablePacket extends DataPacket implements ClientboundPacket, Serverboun /** @var int */ public $reactionType; - protected function decodePayload() : void{ - $this->uselessByte = $this->buf->getByte(); - $this->buf->getSignedBlockPosition($this->x, $this->y, $this->z); - $this->reactionType = $this->buf->getByte(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->uselessByte = $in->getByte(); + $in->getSignedBlockPosition($this->x, $this->y, $this->z); + $this->reactionType = $in->getByte(); } - protected function encodePayload() : void{ - $this->buf->putByte($this->uselessByte); - $this->buf->putSignedBlockPosition($this->x, $this->y, $this->z); - $this->buf->putByte($this->reactionType); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putByte($this->uselessByte); + $out->putSignedBlockPosition($this->x, $this->y, $this->z); + $out->putByte($this->reactionType); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/LecternUpdatePacket.php b/src/network/mcpe/protocol/LecternUpdatePacket.php index c46904d2e2..3362ec0bf0 100644 --- a/src/network/mcpe/protocol/LecternUpdatePacket.php +++ b/src/network/mcpe/protocol/LecternUpdatePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class LecternUpdatePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::LECTERN_UPDATE_PACKET; @@ -43,18 +44,18 @@ class LecternUpdatePacket extends DataPacket implements ServerboundPacket{ /** @var bool */ public $dropBook; - protected function decodePayload() : void{ - $this->page = $this->buf->getByte(); - $this->totalPages = $this->buf->getByte(); - $this->buf->getBlockPosition($this->x, $this->y, $this->z); - $this->dropBook = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->page = $in->getByte(); + $this->totalPages = $in->getByte(); + $in->getBlockPosition($this->x, $this->y, $this->z); + $this->dropBook = $in->getBool(); } - protected function encodePayload() : void{ - $this->buf->putByte($this->page); - $this->buf->putByte($this->totalPages); - $this->buf->putBlockPosition($this->x, $this->y, $this->z); - $this->buf->putBool($this->dropBook); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putByte($this->page); + $out->putByte($this->totalPages); + $out->putBlockPosition($this->x, $this->y, $this->z); + $out->putBool($this->dropBook); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/LevelChunkPacket.php b/src/network/mcpe/protocol/LevelChunkPacket.php index f244911987..04a5e9c994 100644 --- a/src/network/mcpe/protocol/LevelChunkPacket.php +++ b/src/network/mcpe/protocol/LevelChunkPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class LevelChunkPacket extends DataPacket implements ClientboundPacket{ @@ -100,31 +101,31 @@ class LevelChunkPacket extends DataPacket implements ClientboundPacket{ return $this->extraPayload; } - protected function decodePayload() : void{ - $this->chunkX = $this->buf->getVarInt(); - $this->chunkZ = $this->buf->getVarInt(); - $this->subChunkCount = $this->buf->getUnsignedVarInt(); - $this->cacheEnabled = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->chunkX = $in->getVarInt(); + $this->chunkZ = $in->getVarInt(); + $this->subChunkCount = $in->getUnsignedVarInt(); + $this->cacheEnabled = $in->getBool(); if($this->cacheEnabled){ - for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ - $this->usedBlobHashes[] = $this->buf->getLLong(); + for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ + $this->usedBlobHashes[] = $in->getLLong(); } } - $this->extraPayload = $this->buf->getString(); + $this->extraPayload = $in->getString(); } - protected function encodePayload() : void{ - $this->buf->putVarInt($this->chunkX); - $this->buf->putVarInt($this->chunkZ); - $this->buf->putUnsignedVarInt($this->subChunkCount); - $this->buf->putBool($this->cacheEnabled); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putVarInt($this->chunkX); + $out->putVarInt($this->chunkZ); + $out->putUnsignedVarInt($this->subChunkCount); + $out->putBool($this->cacheEnabled); if($this->cacheEnabled){ - $this->buf->putUnsignedVarInt(count($this->usedBlobHashes)); + $out->putUnsignedVarInt(count($this->usedBlobHashes)); foreach($this->usedBlobHashes as $hash){ - $this->buf->putLLong($hash); + $out->putLLong($hash); } } - $this->buf->putString($this->extraPayload); + $out->putString($this->extraPayload); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/LevelEventGenericPacket.php b/src/network/mcpe/protocol/LevelEventGenericPacket.php index 6ae513b893..d0dc7d3df8 100644 --- a/src/network/mcpe/protocol/LevelEventGenericPacket.php +++ b/src/network/mcpe/protocol/LevelEventGenericPacket.php @@ -28,6 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; class LevelEventGenericPacket extends DataPacket implements ClientboundPacket{ @@ -53,14 +54,14 @@ class LevelEventGenericPacket extends DataPacket implements ClientboundPacket{ return $this->eventData; } - protected function decodePayload() : void{ - $this->eventId = $this->buf->getVarInt(); - $this->eventData = $this->buf->getRemaining(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->eventId = $in->getVarInt(); + $this->eventData = $in->getRemaining(); } - protected function encodePayload() : void{ - $this->buf->putVarInt($this->eventId); - $this->buf->put($this->eventData); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putVarInt($this->eventId); + $out->put($this->eventData); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/LevelEventPacket.php b/src/network/mcpe/protocol/LevelEventPacket.php index 3c1d8e8a54..27afb80085 100644 --- a/src/network/mcpe/protocol/LevelEventPacket.php +++ b/src/network/mcpe/protocol/LevelEventPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class LevelEventPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::LEVEL_EVENT_PACKET; @@ -133,16 +134,16 @@ class LevelEventPacket extends DataPacket implements ClientboundPacket{ return self::create(self::EVENT_ADD_PARTICLE_MASK | $particleId, $data, $pos); } - protected function decodePayload() : void{ - $this->evid = $this->buf->getVarInt(); - $this->position = $this->buf->getVector3(); - $this->data = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->evid = $in->getVarInt(); + $this->position = $in->getVector3(); + $this->data = $in->getVarInt(); } - protected function encodePayload() : void{ - $this->buf->putVarInt($this->evid); - $this->buf->putVector3Nullable($this->position); - $this->buf->putVarInt($this->data); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putVarInt($this->evid); + $out->putVector3Nullable($this->position); + $out->putVarInt($this->data); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/LevelSoundEventPacket.php b/src/network/mcpe/protocol/LevelSoundEventPacket.php index 86d2631d8a..447c55bafc 100644 --- a/src/network/mcpe/protocol/LevelSoundEventPacket.php +++ b/src/network/mcpe/protocol/LevelSoundEventPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class LevelSoundEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::LEVEL_SOUND_EVENT_PACKET; @@ -335,22 +336,22 @@ class LevelSoundEventPacket extends DataPacket implements ClientboundPacket, Ser /** @var bool */ public $disableRelativeVolume = false; - protected function decodePayload() : void{ - $this->sound = $this->buf->getUnsignedVarInt(); - $this->position = $this->buf->getVector3(); - $this->extraData = $this->buf->getVarInt(); - $this->entityType = $this->buf->getString(); - $this->isBabyMob = $this->buf->getBool(); - $this->disableRelativeVolume = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->sound = $in->getUnsignedVarInt(); + $this->position = $in->getVector3(); + $this->extraData = $in->getVarInt(); + $this->entityType = $in->getString(); + $this->isBabyMob = $in->getBool(); + $this->disableRelativeVolume = $in->getBool(); } - protected function encodePayload() : void{ - $this->buf->putUnsignedVarInt($this->sound); - $this->buf->putVector3($this->position); - $this->buf->putVarInt($this->extraData); - $this->buf->putString($this->entityType); - $this->buf->putBool($this->isBabyMob); - $this->buf->putBool($this->disableRelativeVolume); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putUnsignedVarInt($this->sound); + $out->putVector3($this->position); + $out->putVarInt($this->extraData); + $out->putString($this->entityType); + $out->putBool($this->isBabyMob); + $out->putBool($this->disableRelativeVolume); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/LevelSoundEventPacketV1.php b/src/network/mcpe/protocol/LevelSoundEventPacketV1.php index cb20f6042b..f7b93b19a1 100644 --- a/src/network/mcpe/protocol/LevelSoundEventPacketV1.php +++ b/src/network/mcpe/protocol/LevelSoundEventPacketV1.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; /** * Useless leftover from a 1.8 refactor, does nothing @@ -47,22 +48,22 @@ class LevelSoundEventPacketV1 extends DataPacket{ /** @var bool */ public $disableRelativeVolume = false; - protected function decodePayload() : void{ - $this->sound = $this->buf->getByte(); - $this->position = $this->buf->getVector3(); - $this->extraData = $this->buf->getVarInt(); - $this->entityType = $this->buf->getVarInt(); - $this->isBabyMob = $this->buf->getBool(); - $this->disableRelativeVolume = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->sound = $in->getByte(); + $this->position = $in->getVector3(); + $this->extraData = $in->getVarInt(); + $this->entityType = $in->getVarInt(); + $this->isBabyMob = $in->getBool(); + $this->disableRelativeVolume = $in->getBool(); } - protected function encodePayload() : void{ - $this->buf->putByte($this->sound); - $this->buf->putVector3($this->position); - $this->buf->putVarInt($this->extraData); - $this->buf->putVarInt($this->entityType); - $this->buf->putBool($this->isBabyMob); - $this->buf->putBool($this->disableRelativeVolume); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putByte($this->sound); + $out->putVector3($this->position); + $out->putVarInt($this->extraData); + $out->putVarInt($this->entityType); + $out->putBool($this->isBabyMob); + $out->putBool($this->disableRelativeVolume); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/LevelSoundEventPacketV2.php b/src/network/mcpe/protocol/LevelSoundEventPacketV2.php index 753f6c9bad..9447523cac 100644 --- a/src/network/mcpe/protocol/LevelSoundEventPacketV2.php +++ b/src/network/mcpe/protocol/LevelSoundEventPacketV2.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; /** * Useless leftover from a 1.9 refactor, does nothing @@ -47,22 +48,22 @@ class LevelSoundEventPacketV2 extends DataPacket{ /** @var bool */ public $disableRelativeVolume = false; - protected function decodePayload() : void{ - $this->sound = $this->buf->getByte(); - $this->position = $this->buf->getVector3(); - $this->extraData = $this->buf->getVarInt(); - $this->entityType = $this->buf->getString(); - $this->isBabyMob = $this->buf->getBool(); - $this->disableRelativeVolume = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->sound = $in->getByte(); + $this->position = $in->getVector3(); + $this->extraData = $in->getVarInt(); + $this->entityType = $in->getString(); + $this->isBabyMob = $in->getBool(); + $this->disableRelativeVolume = $in->getBool(); } - protected function encodePayload() : void{ - $this->buf->putByte($this->sound); - $this->buf->putVector3($this->position); - $this->buf->putVarInt($this->extraData); - $this->buf->putString($this->entityType); - $this->buf->putBool($this->isBabyMob); - $this->buf->putBool($this->disableRelativeVolume); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putByte($this->sound); + $out->putVector3($this->position); + $out->putVarInt($this->extraData); + $out->putString($this->entityType); + $out->putBool($this->isBabyMob); + $out->putBool($this->disableRelativeVolume); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/LoginPacket.php b/src/network/mcpe/protocol/LoginPacket.php index 4206694ebd..af33b46f60 100644 --- a/src/network/mcpe/protocol/LoginPacket.php +++ b/src/network/mcpe/protocol/LoginPacket.php @@ -28,6 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use Particle\Validator\Validator; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; use pocketmine\utils\Utils; @@ -108,9 +109,9 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ return true; } - protected function decodePayload() : void{ - $this->protocol = $this->buf->getInt(); - $this->decodeConnectionRequest(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->protocol = $in->getInt(); + $this->decodeConnectionRequest($in); } /** @@ -133,8 +134,8 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ * @throws BadPacketException * @throws BinaryDataException */ - protected function decodeConnectionRequest() : void{ - $buffer = new BinaryStream($this->buf->getString()); + protected function decodeConnectionRequest(NetworkBinaryStream $in) : void{ + $buffer = new BinaryStream($in->getString()); $chainData = json_decode($buffer->get($buffer->getLInt()), true); if(!is_array($chainData)){ @@ -219,7 +220,7 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ $this->clientData = $clientData; } - protected function encodePayload() : void{ + protected function encodePayload(NetworkBinaryStream $out) : void{ //TODO } diff --git a/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php b/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php index 3405c7b3b7..43b1a97184 100644 --- a/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php +++ b/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class MapCreateLockedCopyPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MAP_CREATE_LOCKED_COPY_PACKET; @@ -35,14 +36,14 @@ class MapCreateLockedCopyPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $newMapId; - protected function decodePayload() : void{ - $this->originalMapId = $this->buf->getEntityUniqueId(); - $this->newMapId = $this->buf->getEntityUniqueId(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->originalMapId = $in->getEntityUniqueId(); + $this->newMapId = $in->getEntityUniqueId(); } - protected function encodePayload() : void{ - $this->buf->putEntityUniqueId($this->originalMapId); - $this->buf->putEntityUniqueId($this->newMapId); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityUniqueId($this->originalMapId); + $out->putEntityUniqueId($this->newMapId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/MapInfoRequestPacket.php b/src/network/mcpe/protocol/MapInfoRequestPacket.php index 6aa6c21551..bbe8ba7b50 100644 --- a/src/network/mcpe/protocol/MapInfoRequestPacket.php +++ b/src/network/mcpe/protocol/MapInfoRequestPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class MapInfoRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MAP_INFO_REQUEST_PACKET; @@ -33,12 +34,12 @@ class MapInfoRequestPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $mapId; - protected function decodePayload() : void{ - $this->mapId = $this->buf->getEntityUniqueId(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->mapId = $in->getEntityUniqueId(); } - protected function encodePayload() : void{ - $this->buf->putEntityUniqueId($this->mapId); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityUniqueId($this->mapId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/MobArmorEquipmentPacket.php b/src/network/mcpe/protocol/MobArmorEquipmentPacket.php index d6cffa39b9..1d3aba6af4 100644 --- a/src/network/mcpe/protocol/MobArmorEquipmentPacket.php +++ b/src/network/mcpe/protocol/MobArmorEquipmentPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\item\Item; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class MobArmorEquipmentPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MOB_ARMOR_EQUIPMENT_PACKET; @@ -55,20 +56,20 @@ class MobArmorEquipmentPacket extends DataPacket implements ClientboundPacket, S return $result; } - protected function decodePayload() : void{ - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); - $this->head = $this->buf->getSlot(); - $this->chest = $this->buf->getSlot(); - $this->legs = $this->buf->getSlot(); - $this->feet = $this->buf->getSlot(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityRuntimeId = $in->getEntityRuntimeId(); + $this->head = $in->getSlot(); + $this->chest = $in->getSlot(); + $this->legs = $in->getSlot(); + $this->feet = $in->getSlot(); } - protected function encodePayload() : void{ - $this->buf->putEntityRuntimeId($this->entityRuntimeId); - $this->buf->putSlot($this->head); - $this->buf->putSlot($this->chest); - $this->buf->putSlot($this->legs); - $this->buf->putSlot($this->feet); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityRuntimeId($this->entityRuntimeId); + $out->putSlot($this->head); + $out->putSlot($this->chest); + $out->putSlot($this->legs); + $out->putSlot($this->feet); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/MobEffectPacket.php b/src/network/mcpe/protocol/MobEffectPacket.php index 14d29fd77a..683a5f2b24 100644 --- a/src/network/mcpe/protocol/MobEffectPacket.php +++ b/src/network/mcpe/protocol/MobEffectPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class MobEffectPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::MOB_EFFECT_PACKET; @@ -66,22 +67,22 @@ class MobEffectPacket extends DataPacket implements ClientboundPacket{ return $pk; } - protected function decodePayload() : void{ - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); - $this->eventId = $this->buf->getByte(); - $this->effectId = $this->buf->getVarInt(); - $this->amplifier = $this->buf->getVarInt(); - $this->particles = $this->buf->getBool(); - $this->duration = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityRuntimeId = $in->getEntityRuntimeId(); + $this->eventId = $in->getByte(); + $this->effectId = $in->getVarInt(); + $this->amplifier = $in->getVarInt(); + $this->particles = $in->getBool(); + $this->duration = $in->getVarInt(); } - protected function encodePayload() : void{ - $this->buf->putEntityRuntimeId($this->entityRuntimeId); - $this->buf->putByte($this->eventId); - $this->buf->putVarInt($this->effectId); - $this->buf->putVarInt($this->amplifier); - $this->buf->putBool($this->particles); - $this->buf->putVarInt($this->duration); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityRuntimeId($this->entityRuntimeId); + $out->putByte($this->eventId); + $out->putVarInt($this->effectId); + $out->putVarInt($this->amplifier); + $out->putBool($this->particles); + $out->putVarInt($this->duration); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/MobEquipmentPacket.php b/src/network/mcpe/protocol/MobEquipmentPacket.php index 0393df687b..53e87632c6 100644 --- a/src/network/mcpe/protocol/MobEquipmentPacket.php +++ b/src/network/mcpe/protocol/MobEquipmentPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\item\Item; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class MobEquipmentPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MOB_EQUIPMENT_PACKET; @@ -52,20 +53,20 @@ class MobEquipmentPacket extends DataPacket implements ClientboundPacket, Server return $result; } - protected function decodePayload() : void{ - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); - $this->item = $this->buf->getSlot(); - $this->inventorySlot = $this->buf->getByte(); - $this->hotbarSlot = $this->buf->getByte(); - $this->windowId = $this->buf->getByte(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityRuntimeId = $in->getEntityRuntimeId(); + $this->item = $in->getSlot(); + $this->inventorySlot = $in->getByte(); + $this->hotbarSlot = $in->getByte(); + $this->windowId = $in->getByte(); } - protected function encodePayload() : void{ - $this->buf->putEntityRuntimeId($this->entityRuntimeId); - $this->buf->putSlot($this->item); - $this->buf->putByte($this->inventorySlot); - $this->buf->putByte($this->hotbarSlot); - $this->buf->putByte($this->windowId); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityRuntimeId($this->entityRuntimeId); + $out->putSlot($this->item); + $out->putByte($this->inventorySlot); + $out->putByte($this->hotbarSlot); + $out->putByte($this->windowId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ModalFormRequestPacket.php b/src/network/mcpe/protocol/ModalFormRequestPacket.php index 9f17b74509..6865c8af04 100644 --- a/src/network/mcpe/protocol/ModalFormRequestPacket.php +++ b/src/network/mcpe/protocol/ModalFormRequestPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ModalFormRequestPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::MODAL_FORM_REQUEST_PACKET; @@ -42,14 +43,14 @@ class ModalFormRequestPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload() : void{ - $this->formId = $this->buf->getUnsignedVarInt(); - $this->formData = $this->buf->getString(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->formId = $in->getUnsignedVarInt(); + $this->formData = $in->getString(); } - protected function encodePayload() : void{ - $this->buf->putUnsignedVarInt($this->formId); - $this->buf->putString($this->formData); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putUnsignedVarInt($this->formId); + $out->putString($this->formData); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ModalFormResponsePacket.php b/src/network/mcpe/protocol/ModalFormResponsePacket.php index 06af847fed..7f4379ae44 100644 --- a/src/network/mcpe/protocol/ModalFormResponsePacket.php +++ b/src/network/mcpe/protocol/ModalFormResponsePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ModalFormResponsePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MODAL_FORM_RESPONSE_PACKET; @@ -35,14 +36,14 @@ class ModalFormResponsePacket extends DataPacket implements ServerboundPacket{ /** @var string */ public $formData; //json - protected function decodePayload() : void{ - $this->formId = $this->buf->getUnsignedVarInt(); - $this->formData = $this->buf->getString(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->formId = $in->getUnsignedVarInt(); + $this->formData = $in->getString(); } - protected function encodePayload() : void{ - $this->buf->putUnsignedVarInt($this->formId); - $this->buf->putString($this->formData); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putUnsignedVarInt($this->formId); + $out->putString($this->formData); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/MoveActorAbsolutePacket.php b/src/network/mcpe/protocol/MoveActorAbsolutePacket.php index 566ba2b9dd..71d9df47f9 100644 --- a/src/network/mcpe/protocol/MoveActorAbsolutePacket.php +++ b/src/network/mcpe/protocol/MoveActorAbsolutePacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class MoveActorAbsolutePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MOVE_ACTOR_ABSOLUTE_PACKET; @@ -47,22 +48,22 @@ class MoveActorAbsolutePacket extends DataPacket implements ClientboundPacket, S /** @var float */ public $zRot; - protected function decodePayload() : void{ - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); - $this->flags = $this->buf->getByte(); - $this->position = $this->buf->getVector3(); - $this->xRot = $this->buf->getByteRotation(); - $this->yRot = $this->buf->getByteRotation(); - $this->zRot = $this->buf->getByteRotation(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityRuntimeId = $in->getEntityRuntimeId(); + $this->flags = $in->getByte(); + $this->position = $in->getVector3(); + $this->xRot = $in->getByteRotation(); + $this->yRot = $in->getByteRotation(); + $this->zRot = $in->getByteRotation(); } - protected function encodePayload() : void{ - $this->buf->putEntityRuntimeId($this->entityRuntimeId); - $this->buf->putByte($this->flags); - $this->buf->putVector3($this->position); - $this->buf->putByteRotation($this->xRot); - $this->buf->putByteRotation($this->yRot); - $this->buf->putByteRotation($this->zRot); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityRuntimeId($this->entityRuntimeId); + $out->putByte($this->flags); + $out->putVector3($this->position); + $out->putByteRotation($this->xRot); + $out->putByteRotation($this->yRot); + $out->putByteRotation($this->zRot); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/MoveActorDeltaPacket.php b/src/network/mcpe/protocol/MoveActorDeltaPacket.php index d252baf8e7..5ea13f2b6a 100644 --- a/src/network/mcpe/protocol/MoveActorDeltaPacket.php +++ b/src/network/mcpe/protocol/MoveActorDeltaPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; class MoveActorDeltaPacket extends DataPacket implements ClientboundPacket{ @@ -58,9 +59,9 @@ class MoveActorDeltaPacket extends DataPacket implements ClientboundPacket{ /** * @throws BinaryDataException */ - private function maybeReadCoord(int $flag) : int{ + private function maybeReadCoord(int $flag, NetworkBinaryStream $in) : int{ if(($this->flags & $flag) !== 0){ - return $this->buf->getVarInt(); + return $in->getVarInt(); } return 0; } @@ -68,45 +69,45 @@ class MoveActorDeltaPacket extends DataPacket implements ClientboundPacket{ /** * @throws BinaryDataException */ - private function maybeReadRotation(int $flag) : float{ + private function maybeReadRotation(int $flag, NetworkBinaryStream $in) : float{ if(($this->flags & $flag) !== 0){ - return $this->buf->getByteRotation(); + return $in->getByteRotation(); } return 0.0; } - protected function decodePayload() : void{ - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); - $this->flags = $this->buf->getLShort(); - $this->xDiff = $this->maybeReadCoord(self::FLAG_HAS_X); - $this->yDiff = $this->maybeReadCoord(self::FLAG_HAS_Y); - $this->zDiff = $this->maybeReadCoord(self::FLAG_HAS_Z); - $this->xRot = $this->maybeReadRotation(self::FLAG_HAS_ROT_X); - $this->yRot = $this->maybeReadRotation(self::FLAG_HAS_ROT_Y); - $this->zRot = $this->maybeReadRotation(self::FLAG_HAS_ROT_Z); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityRuntimeId = $in->getEntityRuntimeId(); + $this->flags = $in->getLShort(); + $this->xDiff = $this->maybeReadCoord(self::FLAG_HAS_X, $in); + $this->yDiff = $this->maybeReadCoord(self::FLAG_HAS_Y, $in); + $this->zDiff = $this->maybeReadCoord(self::FLAG_HAS_Z, $in); + $this->xRot = $this->maybeReadRotation(self::FLAG_HAS_ROT_X, $in); + $this->yRot = $this->maybeReadRotation(self::FLAG_HAS_ROT_Y, $in); + $this->zRot = $this->maybeReadRotation(self::FLAG_HAS_ROT_Z, $in); } - private function maybeWriteCoord(int $flag, int $val) : void{ + private function maybeWriteCoord(int $flag, int $val, NetworkBinaryStream $out) : void{ if(($this->flags & $flag) !== 0){ - $this->buf->putVarInt($val); + $out->putVarInt($val); } } - private function maybeWriteRotation(int $flag, float $val) : void{ + private function maybeWriteRotation(int $flag, float $val, NetworkBinaryStream $out) : void{ if(($this->flags & $flag) !== 0){ - $this->buf->putByteRotation($val); + $out->putByteRotation($val); } } - protected function encodePayload() : void{ - $this->buf->putEntityRuntimeId($this->entityRuntimeId); - $this->buf->putLShort($this->flags); - $this->maybeWriteCoord(self::FLAG_HAS_X, $this->xDiff); - $this->maybeWriteCoord(self::FLAG_HAS_Y, $this->yDiff); - $this->maybeWriteCoord(self::FLAG_HAS_Z, $this->zDiff); - $this->maybeWriteRotation(self::FLAG_HAS_ROT_X, $this->xRot); - $this->maybeWriteRotation(self::FLAG_HAS_ROT_Y, $this->yRot); - $this->maybeWriteRotation(self::FLAG_HAS_ROT_Z, $this->zRot); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityRuntimeId($this->entityRuntimeId); + $out->putLShort($this->flags); + $this->maybeWriteCoord(self::FLAG_HAS_X, $this->xDiff, $out); + $this->maybeWriteCoord(self::FLAG_HAS_Y, $this->yDiff, $out); + $this->maybeWriteCoord(self::FLAG_HAS_Z, $this->zDiff, $out); + $this->maybeWriteRotation(self::FLAG_HAS_ROT_X, $this->xRot, $out); + $this->maybeWriteRotation(self::FLAG_HAS_ROT_Y, $this->yRot, $out); + $this->maybeWriteRotation(self::FLAG_HAS_ROT_Z, $this->zRot, $out); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/MovePlayerPacket.php b/src/network/mcpe/protocol/MovePlayerPacket.php index 3c42186a26..05a79649bc 100644 --- a/src/network/mcpe/protocol/MovePlayerPacket.php +++ b/src/network/mcpe/protocol/MovePlayerPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class MovePlayerPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MOVE_PLAYER_PACKET; @@ -57,33 +58,33 @@ class MovePlayerPacket extends DataPacket implements ClientboundPacket, Serverbo /** @var int */ public $teleportItem = 0; - protected function decodePayload() : void{ - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); - $this->position = $this->buf->getVector3(); - $this->pitch = $this->buf->getLFloat(); - $this->yaw = $this->buf->getLFloat(); - $this->headYaw = $this->buf->getLFloat(); - $this->mode = $this->buf->getByte(); - $this->onGround = $this->buf->getBool(); - $this->ridingEid = $this->buf->getEntityRuntimeId(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityRuntimeId = $in->getEntityRuntimeId(); + $this->position = $in->getVector3(); + $this->pitch = $in->getLFloat(); + $this->yaw = $in->getLFloat(); + $this->headYaw = $in->getLFloat(); + $this->mode = $in->getByte(); + $this->onGround = $in->getBool(); + $this->ridingEid = $in->getEntityRuntimeId(); if($this->mode === MovePlayerPacket::MODE_TELEPORT){ - $this->teleportCause = $this->buf->getLInt(); - $this->teleportItem = $this->buf->getLInt(); + $this->teleportCause = $in->getLInt(); + $this->teleportItem = $in->getLInt(); } } - protected function encodePayload() : void{ - $this->buf->putEntityRuntimeId($this->entityRuntimeId); - $this->buf->putVector3($this->position); - $this->buf->putLFloat($this->pitch); - $this->buf->putLFloat($this->yaw); - $this->buf->putLFloat($this->headYaw); //TODO - $this->buf->putByte($this->mode); - $this->buf->putBool($this->onGround); - $this->buf->putEntityRuntimeId($this->ridingEid); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityRuntimeId($this->entityRuntimeId); + $out->putVector3($this->position); + $out->putLFloat($this->pitch); + $out->putLFloat($this->yaw); + $out->putLFloat($this->headYaw); //TODO + $out->putByte($this->mode); + $out->putBool($this->onGround); + $out->putEntityRuntimeId($this->ridingEid); if($this->mode === MovePlayerPacket::MODE_TELEPORT){ - $this->buf->putLInt($this->teleportCause); - $this->buf->putLInt($this->teleportItem); + $out->putLInt($this->teleportCause); + $out->putLInt($this->teleportItem); } } diff --git a/src/network/mcpe/protocol/MultiplayerSettingsPacket.php b/src/network/mcpe/protocol/MultiplayerSettingsPacket.php index 7b59c8a8a9..2fb6f692c5 100644 --- a/src/network/mcpe/protocol/MultiplayerSettingsPacket.php +++ b/src/network/mcpe/protocol/MultiplayerSettingsPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class MultiplayerSettingsPacket extends DataPacket implements ServerboundPacket{ //TODO: this might be clientbound too, but unsure public const NETWORK_ID = ProtocolInfo::MULTIPLAYER_SETTINGS_PACKET; @@ -47,12 +48,12 @@ class MultiplayerSettingsPacket extends DataPacket implements ServerboundPacket{ return $this->action; } - protected function decodePayload() : void{ - $this->action = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->action = $in->getVarInt(); } - protected function encodePayload() : void{ - $this->buf->putVarInt($this->action); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putVarInt($this->action); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php b/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php index 0fccd283a1..92b9b1df4e 100644 --- a/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php +++ b/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class NetworkChunkPublisherUpdatePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::NETWORK_CHUNK_PUBLISHER_UPDATE_PACKET; @@ -48,14 +49,14 @@ class NetworkChunkPublisherUpdatePacket extends DataPacket implements Clientboun return $result; } - protected function decodePayload() : void{ - $this->buf->getSignedBlockPosition($this->x, $this->y, $this->z); - $this->radius = $this->buf->getUnsignedVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $in->getSignedBlockPosition($this->x, $this->y, $this->z); + $this->radius = $in->getUnsignedVarInt(); } - protected function encodePayload() : void{ - $this->buf->putSignedBlockPosition($this->x, $this->y, $this->z); - $this->buf->putUnsignedVarInt($this->radius); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putSignedBlockPosition($this->x, $this->y, $this->z); + $out->putUnsignedVarInt($this->radius); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/NetworkSettingsPacket.php b/src/network/mcpe/protocol/NetworkSettingsPacket.php index 7d1096eb4f..40b387320a 100644 --- a/src/network/mcpe/protocol/NetworkSettingsPacket.php +++ b/src/network/mcpe/protocol/NetworkSettingsPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class NetworkSettingsPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::NETWORK_SETTINGS_PACKET; @@ -46,12 +47,12 @@ class NetworkSettingsPacket extends DataPacket implements ClientboundPacket{ return $this->compressionThreshold; } - protected function decodePayload() : void{ - $this->compressionThreshold = $this->buf->getLShort(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->compressionThreshold = $in->getLShort(); } - protected function encodePayload() : void{ - $this->buf->putLShort($this->compressionThreshold); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putLShort($this->compressionThreshold); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/NetworkStackLatencyPacket.php b/src/network/mcpe/protocol/NetworkStackLatencyPacket.php index 327303c6e0..ce1459d941 100644 --- a/src/network/mcpe/protocol/NetworkStackLatencyPacket.php +++ b/src/network/mcpe/protocol/NetworkStackLatencyPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class NetworkStackLatencyPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::NETWORK_STACK_LATENCY_PACKET; @@ -35,14 +36,14 @@ class NetworkStackLatencyPacket extends DataPacket implements ClientboundPacket, /** @var bool */ public $needResponse; - protected function decodePayload() : void{ - $this->timestamp = $this->buf->getLLong(); - $this->needResponse = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->timestamp = $in->getLLong(); + $this->needResponse = $in->getBool(); } - protected function encodePayload() : void{ - $this->buf->putLLong($this->timestamp); - $this->buf->putBool($this->needResponse); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putLLong($this->timestamp); + $out->putBool($this->needResponse); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/NpcRequestPacket.php b/src/network/mcpe/protocol/NpcRequestPacket.php index d01c71d830..26b11eacbf 100644 --- a/src/network/mcpe/protocol/NpcRequestPacket.php +++ b/src/network/mcpe/protocol/NpcRequestPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class NpcRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::NPC_REQUEST_PACKET; @@ -39,18 +40,18 @@ class NpcRequestPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $actionType; - protected function decodePayload() : void{ - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); - $this->requestType = $this->buf->getByte(); - $this->commandString = $this->buf->getString(); - $this->actionType = $this->buf->getByte(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityRuntimeId = $in->getEntityRuntimeId(); + $this->requestType = $in->getByte(); + $this->commandString = $in->getString(); + $this->actionType = $in->getByte(); } - protected function encodePayload() : void{ - $this->buf->putEntityRuntimeId($this->entityRuntimeId); - $this->buf->putByte($this->requestType); - $this->buf->putString($this->commandString); - $this->buf->putByte($this->actionType); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityRuntimeId($this->entityRuntimeId); + $out->putByte($this->requestType); + $out->putString($this->commandString); + $out->putByte($this->actionType); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php b/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php index 0aaf2b218f..0a2565623f 100644 --- a/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php +++ b/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class OnScreenTextureAnimationPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ON_SCREEN_TEXTURE_ANIMATION_PACKET; @@ -33,12 +34,12 @@ class OnScreenTextureAnimationPacket extends DataPacket implements ClientboundPa /** @var int */ public $effectId; - protected function decodePayload() : void{ - $this->effectId = $this->buf->getLInt(); //unsigned + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->effectId = $in->getLInt(); //unsigned } - protected function encodePayload() : void{ - $this->buf->putLInt($this->effectId); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putLInt($this->effectId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/PhotoTransferPacket.php b/src/network/mcpe/protocol/PhotoTransferPacket.php index a08c56eada..5e04ed441b 100644 --- a/src/network/mcpe/protocol/PhotoTransferPacket.php +++ b/src/network/mcpe/protocol/PhotoTransferPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class PhotoTransferPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::PHOTO_TRANSFER_PACKET; @@ -37,16 +38,16 @@ class PhotoTransferPacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $bookId; //photos are stored in a sibling directory to the games folder (screenshots/(some UUID)/bookID/example.png) - protected function decodePayload() : void{ - $this->photoName = $this->buf->getString(); - $this->photoData = $this->buf->getString(); - $this->bookId = $this->buf->getString(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->photoName = $in->getString(); + $this->photoData = $in->getString(); + $this->bookId = $in->getString(); } - protected function encodePayload() : void{ - $this->buf->putString($this->photoName); - $this->buf->putString($this->photoData); - $this->buf->putString($this->bookId); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->photoName); + $out->putString($this->photoData); + $out->putString($this->bookId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/PlaySoundPacket.php b/src/network/mcpe/protocol/PlaySoundPacket.php index e90f1f403c..f59cd463c8 100644 --- a/src/network/mcpe/protocol/PlaySoundPacket.php +++ b/src/network/mcpe/protocol/PlaySoundPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class PlaySoundPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAY_SOUND_PACKET; @@ -43,21 +44,21 @@ class PlaySoundPacket extends DataPacket implements ClientboundPacket{ /** @var float */ public $pitch; - protected function decodePayload() : void{ - $this->soundName = $this->buf->getString(); - $this->buf->getBlockPosition($this->x, $this->y, $this->z); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->soundName = $in->getString(); + $in->getBlockPosition($this->x, $this->y, $this->z); $this->x /= 8; $this->y /= 8; $this->z /= 8; - $this->volume = $this->buf->getLFloat(); - $this->pitch = $this->buf->getLFloat(); + $this->volume = $in->getLFloat(); + $this->pitch = $in->getLFloat(); } - protected function encodePayload() : void{ - $this->buf->putString($this->soundName); - $this->buf->putBlockPosition((int) ($this->x * 8), (int) ($this->y * 8), (int) ($this->z * 8)); - $this->buf->putLFloat($this->volume); - $this->buf->putLFloat($this->pitch); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->soundName); + $out->putBlockPosition((int) ($this->x * 8), (int) ($this->y * 8), (int) ($this->z * 8)); + $out->putLFloat($this->volume); + $out->putLFloat($this->pitch); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/PlayStatusPacket.php b/src/network/mcpe/protocol/PlayStatusPacket.php index b0f88740d2..76f3a54818 100644 --- a/src/network/mcpe/protocol/PlayStatusPacket.php +++ b/src/network/mcpe/protocol/PlayStatusPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class PlayStatusPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAY_STATUS_PACKET; @@ -48,16 +49,16 @@ class PlayStatusPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload() : void{ - $this->status = $this->buf->getInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->status = $in->getInt(); } public function canBeSentBeforeLogin() : bool{ return true; } - protected function encodePayload() : void{ - $this->buf->putInt($this->status); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putInt($this->status); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/PlayerActionPacket.php b/src/network/mcpe/protocol/PlayerActionPacket.php index 2985a206e7..d3593289b6 100644 --- a/src/network/mcpe/protocol/PlayerActionPacket.php +++ b/src/network/mcpe/protocol/PlayerActionPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class PlayerActionPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAYER_ACTION_PACKET; @@ -70,18 +71,18 @@ class PlayerActionPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $face; - protected function decodePayload() : void{ - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); - $this->action = $this->buf->getVarInt(); - $this->buf->getBlockPosition($this->x, $this->y, $this->z); - $this->face = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityRuntimeId = $in->getEntityRuntimeId(); + $this->action = $in->getVarInt(); + $in->getBlockPosition($this->x, $this->y, $this->z); + $this->face = $in->getVarInt(); } - protected function encodePayload() : void{ - $this->buf->putEntityRuntimeId($this->entityRuntimeId); - $this->buf->putVarInt($this->action); - $this->buf->putBlockPosition($this->x, $this->y, $this->z); - $this->buf->putVarInt($this->face); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityRuntimeId($this->entityRuntimeId); + $out->putVarInt($this->action); + $out->putBlockPosition($this->x, $this->y, $this->z); + $out->putVarInt($this->face); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/PlayerAuthInputPacket.php b/src/network/mcpe/protocol/PlayerAuthInputPacket.php index 12fdcc80bc..5fd9d8fd20 100644 --- a/src/network/mcpe/protocol/PlayerAuthInputPacket.php +++ b/src/network/mcpe/protocol/PlayerAuthInputPacket.php @@ -29,6 +29,7 @@ use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\InputMode; use pocketmine\network\mcpe\protocol\types\PlayMode; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function assert; class PlayerAuthInputPacket extends DataPacket implements ServerboundPacket{ @@ -127,34 +128,34 @@ class PlayerAuthInputPacket extends DataPacket implements ServerboundPacket{ return $this->vrGazeDirection; } - protected function decodePayload() : void{ - $this->yaw = $this->buf->getLFloat(); - $this->pitch = $this->buf->getLFloat(); - $this->position = $this->buf->getVector3(); - $this->moveVecX = $this->buf->getLFloat(); - $this->moveVecZ = $this->buf->getLFloat(); - $this->headYaw = $this->buf->getLFloat(); - $this->inputFlags = $this->buf->getUnsignedVarLong(); - $this->inputMode = $this->buf->getUnsignedVarInt(); - $this->playMode = $this->buf->getUnsignedVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->yaw = $in->getLFloat(); + $this->pitch = $in->getLFloat(); + $this->position = $in->getVector3(); + $this->moveVecX = $in->getLFloat(); + $this->moveVecZ = $in->getLFloat(); + $this->headYaw = $in->getLFloat(); + $this->inputFlags = $in->getUnsignedVarLong(); + $this->inputMode = $in->getUnsignedVarInt(); + $this->playMode = $in->getUnsignedVarInt(); if($this->playMode === PlayMode::VR){ - $this->vrGazeDirection = $this->buf->getVector3(); + $this->vrGazeDirection = $in->getVector3(); } } - protected function encodePayload() : void{ - $this->buf->putLFloat($this->yaw); - $this->buf->putLFloat($this->pitch); - $this->buf->putVector3($this->position); - $this->buf->putLFloat($this->moveVecX); - $this->buf->putLFloat($this->moveVecZ); - $this->buf->putLFloat($this->headYaw); - $this->buf->putUnsignedVarLong($this->inputFlags); - $this->buf->putUnsignedVarInt($this->inputMode); - $this->buf->putUnsignedVarInt($this->playMode); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putLFloat($this->yaw); + $out->putLFloat($this->pitch); + $out->putVector3($this->position); + $out->putLFloat($this->moveVecX); + $out->putLFloat($this->moveVecZ); + $out->putLFloat($this->headYaw); + $out->putUnsignedVarLong($this->inputFlags); + $out->putUnsignedVarInt($this->inputMode); + $out->putUnsignedVarInt($this->playMode); if($this->playMode === PlayMode::VR){ assert($this->vrGazeDirection !== null); - $this->buf->putVector3($this->vrGazeDirection); + $out->putVector3($this->vrGazeDirection); } } diff --git a/src/network/mcpe/protocol/PlayerHotbarPacket.php b/src/network/mcpe/protocol/PlayerHotbarPacket.php index e5bd9f2d13..36f10aa437 100644 --- a/src/network/mcpe/protocol/PlayerHotbarPacket.php +++ b/src/network/mcpe/protocol/PlayerHotbarPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class PlayerHotbarPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAYER_HOTBAR_PACKET; @@ -46,16 +47,16 @@ class PlayerHotbarPacket extends DataPacket implements ClientboundPacket, Server return $result; } - protected function decodePayload() : void{ - $this->selectedHotbarSlot = $this->buf->getUnsignedVarInt(); - $this->windowId = $this->buf->getByte(); - $this->selectHotbarSlot = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->selectedHotbarSlot = $in->getUnsignedVarInt(); + $this->windowId = $in->getByte(); + $this->selectHotbarSlot = $in->getBool(); } - protected function encodePayload() : void{ - $this->buf->putUnsignedVarInt($this->selectedHotbarSlot); - $this->buf->putByte($this->windowId); - $this->buf->putBool($this->selectHotbarSlot); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putUnsignedVarInt($this->selectedHotbarSlot); + $out->putByte($this->windowId); + $out->putBool($this->selectHotbarSlot); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/PlayerInputPacket.php b/src/network/mcpe/protocol/PlayerInputPacket.php index f74da921ec..c7446fcc52 100644 --- a/src/network/mcpe/protocol/PlayerInputPacket.php +++ b/src/network/mcpe/protocol/PlayerInputPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class PlayerInputPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAYER_INPUT_PACKET; @@ -39,18 +40,18 @@ class PlayerInputPacket extends DataPacket implements ServerboundPacket{ /** @var bool */ public $sneaking; - protected function decodePayload() : void{ - $this->motionX = $this->buf->getLFloat(); - $this->motionY = $this->buf->getLFloat(); - $this->jumping = $this->buf->getBool(); - $this->sneaking = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->motionX = $in->getLFloat(); + $this->motionY = $in->getLFloat(); + $this->jumping = $in->getBool(); + $this->sneaking = $in->getBool(); } - protected function encodePayload() : void{ - $this->buf->putLFloat($this->motionX); - $this->buf->putLFloat($this->motionY); - $this->buf->putBool($this->jumping); - $this->buf->putBool($this->sneaking); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putLFloat($this->motionX); + $out->putLFloat($this->motionY); + $out->putBool($this->jumping); + $out->putBool($this->sneaking); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/PlayerListPacket.php b/src/network/mcpe/protocol/PlayerListPacket.php index 068f68b0f6..f23d40bacc 100644 --- a/src/network/mcpe/protocol/PlayerListPacket.php +++ b/src/network/mcpe/protocol/PlayerListPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class PlayerListPacket extends DataPacket implements ClientboundPacket{ @@ -60,46 +61,46 @@ class PlayerListPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload() : void{ - $this->type = $this->buf->getByte(); - $count = $this->buf->getUnsignedVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->type = $in->getByte(); + $count = $in->getUnsignedVarInt(); for($i = 0; $i < $count; ++$i){ $entry = new PlayerListEntry(); if($this->type === self::TYPE_ADD){ - $entry->uuid = $this->buf->getUUID(); - $entry->entityUniqueId = $this->buf->getEntityUniqueId(); - $entry->username = $this->buf->getString(); - $entry->xboxUserId = $this->buf->getString(); - $entry->platformChatId = $this->buf->getString(); - $entry->buildPlatform = $this->buf->getLInt(); - $entry->skinData = $this->buf->getSkin(); - $entry->isTeacher = $this->buf->getBool(); - $entry->isHost = $this->buf->getBool(); + $entry->uuid = $in->getUUID(); + $entry->entityUniqueId = $in->getEntityUniqueId(); + $entry->username = $in->getString(); + $entry->xboxUserId = $in->getString(); + $entry->platformChatId = $in->getString(); + $entry->buildPlatform = $in->getLInt(); + $entry->skinData = $in->getSkin(); + $entry->isTeacher = $in->getBool(); + $entry->isHost = $in->getBool(); }else{ - $entry->uuid = $this->buf->getUUID(); + $entry->uuid = $in->getUUID(); } $this->entries[$i] = $entry; } } - protected function encodePayload() : void{ - $this->buf->putByte($this->type); - $this->buf->putUnsignedVarInt(count($this->entries)); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putByte($this->type); + $out->putUnsignedVarInt(count($this->entries)); foreach($this->entries as $entry){ if($this->type === self::TYPE_ADD){ - $this->buf->putUUID($entry->uuid); - $this->buf->putEntityUniqueId($entry->entityUniqueId); - $this->buf->putString($entry->username); - $this->buf->putString($entry->xboxUserId); - $this->buf->putString($entry->platformChatId); - $this->buf->putLInt($entry->buildPlatform); - $this->buf->putSkin($entry->skinData); - $this->buf->putBool($entry->isTeacher); - $this->buf->putBool($entry->isHost); + $out->putUUID($entry->uuid); + $out->putEntityUniqueId($entry->entityUniqueId); + $out->putString($entry->username); + $out->putString($entry->xboxUserId); + $out->putString($entry->platformChatId); + $out->putLInt($entry->buildPlatform); + $out->putSkin($entry->skinData); + $out->putBool($entry->isTeacher); + $out->putBool($entry->isHost); }else{ - $this->buf->putUUID($entry->uuid); + $out->putUUID($entry->uuid); } } } diff --git a/src/network/mcpe/protocol/PlayerSkinPacket.php b/src/network/mcpe/protocol/PlayerSkinPacket.php index cefa9fbc86..2b66aa4dd5 100644 --- a/src/network/mcpe/protocol/PlayerSkinPacket.php +++ b/src/network/mcpe/protocol/PlayerSkinPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\SkinData; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\UUID; class PlayerSkinPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -41,18 +42,18 @@ class PlayerSkinPacket extends DataPacket implements ClientboundPacket, Serverbo /** @var SkinData */ public $skin; - protected function decodePayload() : void{ - $this->uuid = $this->buf->getUUID(); - $this->skin = $this->buf->getSkin(); - $this->newSkinName = $this->buf->getString(); - $this->oldSkinName = $this->buf->getString(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->uuid = $in->getUUID(); + $this->skin = $in->getSkin(); + $this->newSkinName = $in->getString(); + $this->oldSkinName = $in->getString(); } - protected function encodePayload() : void{ - $this->buf->putUUID($this->uuid); - $this->buf->putSkin($this->skin); - $this->buf->putString($this->newSkinName); - $this->buf->putString($this->oldSkinName); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putUUID($this->uuid); + $out->putSkin($this->skin); + $out->putString($this->newSkinName); + $out->putString($this->oldSkinName); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/PurchaseReceiptPacket.php b/src/network/mcpe/protocol/PurchaseReceiptPacket.php index 3d7fdc3101..6083353728 100644 --- a/src/network/mcpe/protocol/PurchaseReceiptPacket.php +++ b/src/network/mcpe/protocol/PurchaseReceiptPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class PurchaseReceiptPacket extends DataPacket implements ServerboundPacket{ @@ -34,17 +35,17 @@ class PurchaseReceiptPacket extends DataPacket implements ServerboundPacket{ /** @var string[] */ public $entries = []; - protected function decodePayload() : void{ - $count = $this->buf->getUnsignedVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $count = $in->getUnsignedVarInt(); for($i = 0; $i < $count; ++$i){ - $this->entries[] = $this->buf->getString(); + $this->entries[] = $in->getString(); } } - protected function encodePayload() : void{ - $this->buf->putUnsignedVarInt(count($this->entries)); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putUnsignedVarInt(count($this->entries)); foreach($this->entries as $entry){ - $this->buf->putString($entry); + $out->putString($entry); } } diff --git a/src/network/mcpe/protocol/RemoveActorPacket.php b/src/network/mcpe/protocol/RemoveActorPacket.php index 991fac0649..276460f94b 100644 --- a/src/network/mcpe/protocol/RemoveActorPacket.php +++ b/src/network/mcpe/protocol/RemoveActorPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class RemoveActorPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::REMOVE_ACTOR_PACKET; @@ -39,12 +40,12 @@ class RemoveActorPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload() : void{ - $this->entityUniqueId = $this->buf->getEntityUniqueId(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityUniqueId = $in->getEntityUniqueId(); } - protected function encodePayload() : void{ - $this->buf->putEntityUniqueId($this->entityUniqueId); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityUniqueId($this->entityUniqueId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/RemoveEntityPacket.php b/src/network/mcpe/protocol/RemoveEntityPacket.php index 2c26a1c350..e04182cd63 100644 --- a/src/network/mcpe/protocol/RemoveEntityPacket.php +++ b/src/network/mcpe/protocol/RemoveEntityPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class RemoveEntityPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::REMOVE_ENTITY_PACKET; @@ -43,12 +44,12 @@ class RemoveEntityPacket extends DataPacket implements ClientboundPacket{ return $this->uvarint1; } - protected function decodePayload() : void{ - $this->uvarint1 = $this->buf->getUnsignedVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->uvarint1 = $in->getUnsignedVarInt(); } - protected function encodePayload() : void{ - $this->buf->putUnsignedVarInt($this->uvarint1); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putUnsignedVarInt($this->uvarint1); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/RemoveObjectivePacket.php b/src/network/mcpe/protocol/RemoveObjectivePacket.php index c44291daf9..c05f118ad3 100644 --- a/src/network/mcpe/protocol/RemoveObjectivePacket.php +++ b/src/network/mcpe/protocol/RemoveObjectivePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class RemoveObjectivePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::REMOVE_OBJECTIVE_PACKET; @@ -33,12 +34,12 @@ class RemoveObjectivePacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $objectiveName; - protected function decodePayload() : void{ - $this->objectiveName = $this->buf->getString(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->objectiveName = $in->getString(); } - protected function encodePayload() : void{ - $this->buf->putString($this->objectiveName); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->objectiveName); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/RequestChunkRadiusPacket.php b/src/network/mcpe/protocol/RequestChunkRadiusPacket.php index 57b38afa60..2d669fa30e 100644 --- a/src/network/mcpe/protocol/RequestChunkRadiusPacket.php +++ b/src/network/mcpe/protocol/RequestChunkRadiusPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class RequestChunkRadiusPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::REQUEST_CHUNK_RADIUS_PACKET; @@ -33,12 +34,12 @@ class RequestChunkRadiusPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $radius; - protected function decodePayload() : void{ - $this->radius = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->radius = $in->getVarInt(); } - protected function encodePayload() : void{ - $this->buf->putVarInt($this->radius); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putVarInt($this->radius); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php b/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php index a2adbe8380..26dee397a0 100644 --- a/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php +++ b/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function strlen; class ResourcePackChunkDataPacket extends DataPacket implements ClientboundPacket{ @@ -49,18 +50,18 @@ class ResourcePackChunkDataPacket extends DataPacket implements ClientboundPacke return $result; } - protected function decodePayload() : void{ - $this->packId = $this->buf->getString(); - $this->chunkIndex = $this->buf->getLInt(); - $this->progress = $this->buf->getLLong(); - $this->data = $this->buf->getString(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->packId = $in->getString(); + $this->chunkIndex = $in->getLInt(); + $this->progress = $in->getLLong(); + $this->data = $in->getString(); } - protected function encodePayload() : void{ - $this->buf->putString($this->packId); - $this->buf->putLInt($this->chunkIndex); - $this->buf->putLLong($this->progress); - $this->buf->putString($this->data); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->packId); + $out->putLInt($this->chunkIndex); + $out->putLLong($this->progress); + $out->putString($this->data); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php b/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php index e90154bcd1..a8004ac10c 100644 --- a/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php +++ b/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ResourcePackChunkRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_CHUNK_REQUEST_PACKET; @@ -35,14 +36,14 @@ class ResourcePackChunkRequestPacket extends DataPacket implements ServerboundPa /** @var int */ public $chunkIndex; - protected function decodePayload() : void{ - $this->packId = $this->buf->getString(); - $this->chunkIndex = $this->buf->getLInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->packId = $in->getString(); + $this->chunkIndex = $in->getLInt(); } - protected function encodePayload() : void{ - $this->buf->putString($this->packId); - $this->buf->putLInt($this->chunkIndex); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->packId); + $out->putLInt($this->chunkIndex); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php b/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php index ca4b193632..246a5924a2 100644 --- a/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php +++ b/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class ResourcePackClientResponsePacket extends DataPacket implements ServerboundPacket{ @@ -41,19 +42,19 @@ class ResourcePackClientResponsePacket extends DataPacket implements Serverbound /** @var string[] */ public $packIds = []; - protected function decodePayload() : void{ - $this->status = $this->buf->getByte(); - $entryCount = $this->buf->getLShort(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->status = $in->getByte(); + $entryCount = $in->getLShort(); while($entryCount-- > 0){ - $this->packIds[] = $this->buf->getString(); + $this->packIds[] = $in->getString(); } } - protected function encodePayload() : void{ - $this->buf->putByte($this->status); - $this->buf->putLShort(count($this->packIds)); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putByte($this->status); + $out->putLShort(count($this->packIds)); foreach($this->packIds as $id){ - $this->buf->putString($id); + $out->putString($id); } } diff --git a/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php b/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php index f8066dcc17..fa3b8816e8 100644 --- a/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php +++ b/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackType; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ResourcePackDataInfoPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_DATA_INFO_PACKET; @@ -56,24 +57,24 @@ class ResourcePackDataInfoPacket extends DataPacket implements ClientboundPacket return $result; } - protected function decodePayload() : void{ - $this->packId = $this->buf->getString(); - $this->maxChunkSize = $this->buf->getLInt(); - $this->chunkCount = $this->buf->getLInt(); - $this->compressedPackSize = $this->buf->getLLong(); - $this->sha256 = $this->buf->getString(); - $this->isPremium = $this->buf->getBool(); - $this->packType = $this->buf->getByte(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->packId = $in->getString(); + $this->maxChunkSize = $in->getLInt(); + $this->chunkCount = $in->getLInt(); + $this->compressedPackSize = $in->getLLong(); + $this->sha256 = $in->getString(); + $this->isPremium = $in->getBool(); + $this->packType = $in->getByte(); } - protected function encodePayload() : void{ - $this->buf->putString($this->packId); - $this->buf->putLInt($this->maxChunkSize); - $this->buf->putLInt($this->chunkCount); - $this->buf->putLLong($this->compressedPackSize); - $this->buf->putString($this->sha256); - $this->buf->putBool($this->isPremium); - $this->buf->putByte($this->packType); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->packId); + $out->putLInt($this->maxChunkSize); + $out->putLInt($this->chunkCount); + $out->putLLong($this->compressedPackSize); + $out->putString($this->sha256); + $out->putBool($this->isPremium); + $out->putByte($this->packType); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ResourcePackStackPacket.php b/src/network/mcpe/protocol/ResourcePackStackPacket.php index f424fe8b58..89f85738ef 100644 --- a/src/network/mcpe/protocol/ResourcePackStackPacket.php +++ b/src/network/mcpe/protocol/ResourcePackStackPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackStackEntry; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class ResourcePackStackPacket extends DataPacket implements ClientboundPacket{ @@ -60,37 +61,37 @@ class ResourcePackStackPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload() : void{ - $this->mustAccept = $this->buf->getBool(); - $behaviorPackCount = $this->buf->getUnsignedVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->mustAccept = $in->getBool(); + $behaviorPackCount = $in->getUnsignedVarInt(); while($behaviorPackCount-- > 0){ - $this->behaviorPackStack[] = ResourcePackStackEntry::read($this->buf); + $this->behaviorPackStack[] = ResourcePackStackEntry::read($in); } - $resourcePackCount = $this->buf->getUnsignedVarInt(); + $resourcePackCount = $in->getUnsignedVarInt(); while($resourcePackCount-- > 0){ - $this->resourcePackStack[] = ResourcePackStackEntry::read($this->buf); + $this->resourcePackStack[] = ResourcePackStackEntry::read($in); } - $this->isExperimental = $this->buf->getBool(); - $this->baseGameVersion = $this->buf->getString(); + $this->isExperimental = $in->getBool(); + $this->baseGameVersion = $in->getString(); } - protected function encodePayload() : void{ - $this->buf->putBool($this->mustAccept); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putBool($this->mustAccept); - $this->buf->putUnsignedVarInt(count($this->behaviorPackStack)); + $out->putUnsignedVarInt(count($this->behaviorPackStack)); foreach($this->behaviorPackStack as $entry){ - $entry->write($this->buf); + $entry->write($out); } - $this->buf->putUnsignedVarInt(count($this->resourcePackStack)); + $out->putUnsignedVarInt(count($this->resourcePackStack)); foreach($this->resourcePackStack as $entry){ - $entry->write($this->buf); + $entry->write($out); } - $this->buf->putBool($this->isExperimental); - $this->buf->putString($this->baseGameVersion); + $out->putBool($this->isExperimental); + $out->putString($this->baseGameVersion); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php index a0acc75860..a187a4db70 100644 --- a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php +++ b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackInfoEntry; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ @@ -56,30 +57,30 @@ class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload() : void{ - $this->mustAccept = $this->buf->getBool(); - $this->hasScripts = $this->buf->getBool(); - $behaviorPackCount = $this->buf->getLShort(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->mustAccept = $in->getBool(); + $this->hasScripts = $in->getBool(); + $behaviorPackCount = $in->getLShort(); while($behaviorPackCount-- > 0){ - $this->behaviorPackEntries[] = ResourcePackInfoEntry::read($this->buf); + $this->behaviorPackEntries[] = ResourcePackInfoEntry::read($in); } - $resourcePackCount = $this->buf->getLShort(); + $resourcePackCount = $in->getLShort(); while($resourcePackCount-- > 0){ - $this->resourcePackEntries[] = ResourcePackInfoEntry::read($this->buf); + $this->resourcePackEntries[] = ResourcePackInfoEntry::read($in); } } - protected function encodePayload() : void{ - $this->buf->putBool($this->mustAccept); - $this->buf->putBool($this->hasScripts); - $this->buf->putLShort(count($this->behaviorPackEntries)); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putBool($this->mustAccept); + $out->putBool($this->hasScripts); + $out->putLShort(count($this->behaviorPackEntries)); foreach($this->behaviorPackEntries as $entry){ - $entry->write($this->buf); + $entry->write($out); } - $this->buf->putLShort(count($this->resourcePackEntries)); + $out->putLShort(count($this->resourcePackEntries)); foreach($this->resourcePackEntries as $entry){ - $entry->write($this->buf); + $entry->write($out); } } diff --git a/src/network/mcpe/protocol/RespawnPacket.php b/src/network/mcpe/protocol/RespawnPacket.php index 3bb6c69b9d..dfad800acb 100644 --- a/src/network/mcpe/protocol/RespawnPacket.php +++ b/src/network/mcpe/protocol/RespawnPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class RespawnPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::RESPAWN_PACKET; @@ -50,16 +51,16 @@ class RespawnPacket extends DataPacket implements ClientboundPacket, Serverbound return $result; } - protected function decodePayload() : void{ - $this->position = $this->buf->getVector3(); - $this->respawnState = $this->buf->getByte(); - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->position = $in->getVector3(); + $this->respawnState = $in->getByte(); + $this->entityRuntimeId = $in->getEntityRuntimeId(); } - protected function encodePayload() : void{ - $this->buf->putVector3($this->position); - $this->buf->putByte($this->respawnState); - $this->buf->putEntityRuntimeId($this->entityRuntimeId); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putVector3($this->position); + $out->putByte($this->respawnState); + $out->putEntityRuntimeId($this->entityRuntimeId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/RiderJumpPacket.php b/src/network/mcpe/protocol/RiderJumpPacket.php index 162424be83..ed67e227e3 100644 --- a/src/network/mcpe/protocol/RiderJumpPacket.php +++ b/src/network/mcpe/protocol/RiderJumpPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class RiderJumpPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::RIDER_JUMP_PACKET; @@ -33,12 +34,12 @@ class RiderJumpPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $jumpStrength; //percentage - protected function decodePayload() : void{ - $this->jumpStrength = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->jumpStrength = $in->getVarInt(); } - protected function encodePayload() : void{ - $this->buf->putVarInt($this->jumpStrength); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putVarInt($this->jumpStrength); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ScriptCustomEventPacket.php b/src/network/mcpe/protocol/ScriptCustomEventPacket.php index 3247bffed6..59def62185 100644 --- a/src/network/mcpe/protocol/ScriptCustomEventPacket.php +++ b/src/network/mcpe/protocol/ScriptCustomEventPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ScriptCustomEventPacket extends DataPacket{ //TODO: this doesn't have handlers in either client or server in the game as of 1.8 public const NETWORK_ID = ProtocolInfo::SCRIPT_CUSTOM_EVENT_PACKET; @@ -35,14 +36,14 @@ class ScriptCustomEventPacket extends DataPacket{ //TODO: this doesn't have hand /** @var string json data */ public $eventData; - protected function decodePayload() : void{ - $this->eventName = $this->buf->getString(); - $this->eventData = $this->buf->getString(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->eventName = $in->getString(); + $this->eventData = $in->getString(); } - protected function encodePayload() : void{ - $this->buf->putString($this->eventName); - $this->buf->putString($this->eventData); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->eventName); + $out->putString($this->eventData); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ServerSettingsRequestPacket.php b/src/network/mcpe/protocol/ServerSettingsRequestPacket.php index 53243e44da..c17b1b2a1f 100644 --- a/src/network/mcpe/protocol/ServerSettingsRequestPacket.php +++ b/src/network/mcpe/protocol/ServerSettingsRequestPacket.php @@ -26,15 +26,16 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ServerSettingsRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SERVER_SETTINGS_REQUEST_PACKET; - protected function decodePayload() : void{ + protected function decodePayload(NetworkBinaryStream $in) : void{ //No payload } - protected function encodePayload() : void{ + protected function encodePayload(NetworkBinaryStream $out) : void{ //No payload } diff --git a/src/network/mcpe/protocol/ServerSettingsResponsePacket.php b/src/network/mcpe/protocol/ServerSettingsResponsePacket.php index 1134a44b9b..aa6dd24b85 100644 --- a/src/network/mcpe/protocol/ServerSettingsResponsePacket.php +++ b/src/network/mcpe/protocol/ServerSettingsResponsePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ServerSettingsResponsePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SERVER_SETTINGS_RESPONSE_PACKET; @@ -35,14 +36,14 @@ class ServerSettingsResponsePacket extends DataPacket implements ClientboundPack /** @var string */ public $formData; //json - protected function decodePayload() : void{ - $this->formId = $this->buf->getUnsignedVarInt(); - $this->formData = $this->buf->getString(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->formId = $in->getUnsignedVarInt(); + $this->formData = $in->getString(); } - protected function encodePayload() : void{ - $this->buf->putUnsignedVarInt($this->formId); - $this->buf->putString($this->formData); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putUnsignedVarInt($this->formId); + $out->putString($this->formData); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ServerToClientHandshakePacket.php b/src/network/mcpe/protocol/ServerToClientHandshakePacket.php index 51a2859b2c..b0c62ee65c 100644 --- a/src/network/mcpe/protocol/ServerToClientHandshakePacket.php +++ b/src/network/mcpe/protocol/ServerToClientHandshakePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ServerToClientHandshakePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SERVER_TO_CLIENT_HANDSHAKE_PACKET; @@ -46,12 +47,12 @@ class ServerToClientHandshakePacket extends DataPacket implements ClientboundPac return true; } - protected function decodePayload() : void{ - $this->jwt = $this->buf->getString(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->jwt = $in->getString(); } - protected function encodePayload() : void{ - $this->buf->putString($this->jwt); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->jwt); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetActorDataPacket.php b/src/network/mcpe/protocol/SetActorDataPacket.php index 0d93ffe0bf..776a1cfc5d 100644 --- a/src/network/mcpe/protocol/SetActorDataPacket.php +++ b/src/network/mcpe/protocol/SetActorDataPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetActorDataPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ //TODO: check why this is serverbound public const NETWORK_ID = ProtocolInfo::SET_ACTOR_DATA_PACKET; @@ -51,14 +52,14 @@ class SetActorDataPacket extends DataPacket implements ClientboundPacket, Server return $result; } - protected function decodePayload() : void{ - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); - $this->metadata = $this->buf->getEntityMetadata(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityRuntimeId = $in->getEntityRuntimeId(); + $this->metadata = $in->getEntityMetadata(); } - protected function encodePayload() : void{ - $this->buf->putEntityRuntimeId($this->entityRuntimeId); - $this->buf->putEntityMetadata($this->metadata); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityRuntimeId($this->entityRuntimeId); + $out->putEntityMetadata($this->metadata); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetActorLinkPacket.php b/src/network/mcpe/protocol/SetActorLinkPacket.php index 76efc27242..d981ce69f9 100644 --- a/src/network/mcpe/protocol/SetActorLinkPacket.php +++ b/src/network/mcpe/protocol/SetActorLinkPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetActorLinkPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_ACTOR_LINK_PACKET; @@ -34,12 +35,12 @@ class SetActorLinkPacket extends DataPacket implements ClientboundPacket{ /** @var EntityLink */ public $link; - protected function decodePayload() : void{ - $this->link = $this->buf->getEntityLink(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->link = $in->getEntityLink(); } - protected function encodePayload() : void{ - $this->buf->putEntityLink($this->link); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityLink($this->link); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetActorMotionPacket.php b/src/network/mcpe/protocol/SetActorMotionPacket.php index 553eeddd72..42f1c4bb5c 100644 --- a/src/network/mcpe/protocol/SetActorMotionPacket.php +++ b/src/network/mcpe/protocol/SetActorMotionPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; /** * TODO: This packet is (erroneously) sent to the server when the client is riding a vehicle. @@ -46,14 +47,14 @@ class SetActorMotionPacket extends DataPacket implements ClientboundPacket, Garb return $result; } - protected function decodePayload() : void{ - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); - $this->motion = $this->buf->getVector3(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityRuntimeId = $in->getEntityRuntimeId(); + $this->motion = $in->getVector3(); } - protected function encodePayload() : void{ - $this->buf->putEntityRuntimeId($this->entityRuntimeId); - $this->buf->putVector3($this->motion); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityRuntimeId($this->entityRuntimeId); + $out->putVector3($this->motion); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetCommandsEnabledPacket.php b/src/network/mcpe/protocol/SetCommandsEnabledPacket.php index 38bcd87809..8a93313929 100644 --- a/src/network/mcpe/protocol/SetCommandsEnabledPacket.php +++ b/src/network/mcpe/protocol/SetCommandsEnabledPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetCommandsEnabledPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_COMMANDS_ENABLED_PACKET; @@ -33,12 +34,12 @@ class SetCommandsEnabledPacket extends DataPacket implements ClientboundPacket{ /** @var bool */ public $enabled; - protected function decodePayload() : void{ - $this->enabled = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->enabled = $in->getBool(); } - protected function encodePayload() : void{ - $this->buf->putBool($this->enabled); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putBool($this->enabled); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetDefaultGameTypePacket.php b/src/network/mcpe/protocol/SetDefaultGameTypePacket.php index f39bbce4d0..24882377b4 100644 --- a/src/network/mcpe/protocol/SetDefaultGameTypePacket.php +++ b/src/network/mcpe/protocol/SetDefaultGameTypePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetDefaultGameTypePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_DEFAULT_GAME_TYPE_PACKET; @@ -39,12 +40,12 @@ class SetDefaultGameTypePacket extends DataPacket implements ClientboundPacket, return $result; } - protected function decodePayload() : void{ - $this->gamemode = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->gamemode = $in->getVarInt(); } - protected function encodePayload() : void{ - $this->buf->putUnsignedVarInt($this->gamemode); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putUnsignedVarInt($this->gamemode); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetDifficultyPacket.php b/src/network/mcpe/protocol/SetDifficultyPacket.php index 3489abe99c..e8ae53f882 100644 --- a/src/network/mcpe/protocol/SetDifficultyPacket.php +++ b/src/network/mcpe/protocol/SetDifficultyPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetDifficultyPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_DIFFICULTY_PACKET; @@ -39,12 +40,12 @@ class SetDifficultyPacket extends DataPacket implements ClientboundPacket, Serve return $result; } - protected function decodePayload() : void{ - $this->difficulty = $this->buf->getUnsignedVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->difficulty = $in->getUnsignedVarInt(); } - protected function encodePayload() : void{ - $this->buf->putUnsignedVarInt($this->difficulty); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putUnsignedVarInt($this->difficulty); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetDisplayObjectivePacket.php b/src/network/mcpe/protocol/SetDisplayObjectivePacket.php index 2f4075b2ab..c2d146dd6f 100644 --- a/src/network/mcpe/protocol/SetDisplayObjectivePacket.php +++ b/src/network/mcpe/protocol/SetDisplayObjectivePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetDisplayObjectivePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_DISPLAY_OBJECTIVE_PACKET; @@ -41,20 +42,20 @@ class SetDisplayObjectivePacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $sortOrder; - protected function decodePayload() : void{ - $this->displaySlot = $this->buf->getString(); - $this->objectiveName = $this->buf->getString(); - $this->displayName = $this->buf->getString(); - $this->criteriaName = $this->buf->getString(); - $this->sortOrder = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->displaySlot = $in->getString(); + $this->objectiveName = $in->getString(); + $this->displayName = $in->getString(); + $this->criteriaName = $in->getString(); + $this->sortOrder = $in->getVarInt(); } - protected function encodePayload() : void{ - $this->buf->putString($this->displaySlot); - $this->buf->putString($this->objectiveName); - $this->buf->putString($this->displayName); - $this->buf->putString($this->criteriaName); - $this->buf->putVarInt($this->sortOrder); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->displaySlot); + $out->putString($this->objectiveName); + $out->putString($this->displayName); + $out->putString($this->criteriaName); + $out->putVarInt($this->sortOrder); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetHealthPacket.php b/src/network/mcpe/protocol/SetHealthPacket.php index 4fb3f16097..33d995ee1a 100644 --- a/src/network/mcpe/protocol/SetHealthPacket.php +++ b/src/network/mcpe/protocol/SetHealthPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetHealthPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_HEALTH_PACKET; @@ -33,12 +34,12 @@ class SetHealthPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $health; - protected function decodePayload() : void{ - $this->health = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->health = $in->getVarInt(); } - protected function encodePayload() : void{ - $this->buf->putVarInt($this->health); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putVarInt($this->health); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetLastHurtByPacket.php b/src/network/mcpe/protocol/SetLastHurtByPacket.php index 6cff93835b..41cf6cc7b6 100644 --- a/src/network/mcpe/protocol/SetLastHurtByPacket.php +++ b/src/network/mcpe/protocol/SetLastHurtByPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetLastHurtByPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_LAST_HURT_BY_PACKET; @@ -33,12 +34,12 @@ class SetLastHurtByPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $entityTypeId; - protected function decodePayload() : void{ - $this->entityTypeId = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityTypeId = $in->getVarInt(); } - protected function encodePayload() : void{ - $this->buf->putVarInt($this->entityTypeId); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putVarInt($this->entityTypeId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php b/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php index 0897c63294..9bad32b374 100644 --- a/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php +++ b/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetLocalPlayerAsInitializedPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_LOCAL_PLAYER_AS_INITIALIZED_PACKET; @@ -33,12 +34,12 @@ class SetLocalPlayerAsInitializedPacket extends DataPacket implements Serverboun /** @var int */ public $entityRuntimeId; - protected function decodePayload() : void{ - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityRuntimeId = $in->getEntityRuntimeId(); } - protected function encodePayload() : void{ - $this->buf->putEntityRuntimeId($this->entityRuntimeId); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityRuntimeId($this->entityRuntimeId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetPlayerGameTypePacket.php b/src/network/mcpe/protocol/SetPlayerGameTypePacket.php index bb8699aab7..212810dab7 100644 --- a/src/network/mcpe/protocol/SetPlayerGameTypePacket.php +++ b/src/network/mcpe/protocol/SetPlayerGameTypePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetPlayerGameTypePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_PLAYER_GAME_TYPE_PACKET; @@ -39,12 +40,12 @@ class SetPlayerGameTypePacket extends DataPacket implements ClientboundPacket, S return $pk; } - protected function decodePayload() : void{ - $this->gamemode = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->gamemode = $in->getVarInt(); } - protected function encodePayload() : void{ - $this->buf->putVarInt($this->gamemode); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putVarInt($this->gamemode); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetScorePacket.php b/src/network/mcpe/protocol/SetScorePacket.php index 59f61d321c..73e1208dc0 100644 --- a/src/network/mcpe/protocol/SetScorePacket.php +++ b/src/network/mcpe/protocol/SetScorePacket.php @@ -28,6 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\ScorePacketEntry; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class SetScorePacket extends DataPacket implements ClientboundPacket{ @@ -41,22 +42,22 @@ class SetScorePacket extends DataPacket implements ClientboundPacket{ /** @var ScorePacketEntry[] */ public $entries = []; - protected function decodePayload() : void{ - $this->type = $this->buf->getByte(); - for($i = 0, $i2 = $this->buf->getUnsignedVarInt(); $i < $i2; ++$i){ + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->type = $in->getByte(); + for($i = 0, $i2 = $in->getUnsignedVarInt(); $i < $i2; ++$i){ $entry = new ScorePacketEntry(); - $entry->scoreboardId = $this->buf->getVarLong(); - $entry->objectiveName = $this->buf->getString(); - $entry->score = $this->buf->getLInt(); + $entry->scoreboardId = $in->getVarLong(); + $entry->objectiveName = $in->getString(); + $entry->score = $in->getLInt(); if($this->type !== self::TYPE_REMOVE){ - $entry->type = $this->buf->getByte(); + $entry->type = $in->getByte(); switch($entry->type){ case ScorePacketEntry::TYPE_PLAYER: case ScorePacketEntry::TYPE_ENTITY: - $entry->entityUniqueId = $this->buf->getEntityUniqueId(); + $entry->entityUniqueId = $in->getEntityUniqueId(); break; case ScorePacketEntry::TYPE_FAKE_PLAYER: - $entry->customName = $this->buf->getString(); + $entry->customName = $in->getString(); break; default: throw new BadPacketException("Unknown entry type $entry->type"); @@ -66,22 +67,22 @@ class SetScorePacket extends DataPacket implements ClientboundPacket{ } } - protected function encodePayload() : void{ - $this->buf->putByte($this->type); - $this->buf->putUnsignedVarInt(count($this->entries)); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putByte($this->type); + $out->putUnsignedVarInt(count($this->entries)); foreach($this->entries as $entry){ - $this->buf->putVarLong($entry->scoreboardId); - $this->buf->putString($entry->objectiveName); - $this->buf->putLInt($entry->score); + $out->putVarLong($entry->scoreboardId); + $out->putString($entry->objectiveName); + $out->putLInt($entry->score); if($this->type !== self::TYPE_REMOVE){ - $this->buf->putByte($entry->type); + $out->putByte($entry->type); switch($entry->type){ case ScorePacketEntry::TYPE_PLAYER: case ScorePacketEntry::TYPE_ENTITY: - $this->buf->putEntityUniqueId($entry->entityUniqueId); + $out->putEntityUniqueId($entry->entityUniqueId); break; case ScorePacketEntry::TYPE_FAKE_PLAYER: - $this->buf->putString($entry->customName); + $out->putString($entry->customName); break; default: throw new \InvalidArgumentException("Unknown entry type $entry->type"); diff --git a/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php b/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php index 991771accb..bd42d29cba 100644 --- a/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php +++ b/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\ScoreboardIdentityPacketEntry; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class SetScoreboardIdentityPacket extends DataPacket implements ClientboundPacket{ @@ -40,26 +41,26 @@ class SetScoreboardIdentityPacket extends DataPacket implements ClientboundPacke /** @var ScoreboardIdentityPacketEntry[] */ public $entries = []; - protected function decodePayload() : void{ - $this->type = $this->buf->getByte(); - for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->type = $in->getByte(); + for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ $entry = new ScoreboardIdentityPacketEntry(); - $entry->scoreboardId = $this->buf->getVarLong(); + $entry->scoreboardId = $in->getVarLong(); if($this->type === self::TYPE_REGISTER_IDENTITY){ - $entry->entityUniqueId = $this->buf->getEntityUniqueId(); + $entry->entityUniqueId = $in->getEntityUniqueId(); } $this->entries[] = $entry; } } - protected function encodePayload() : void{ - $this->buf->putByte($this->type); - $this->buf->putUnsignedVarInt(count($this->entries)); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putByte($this->type); + $out->putUnsignedVarInt(count($this->entries)); foreach($this->entries as $entry){ - $this->buf->putVarLong($entry->scoreboardId); + $out->putVarLong($entry->scoreboardId); if($this->type === self::TYPE_REGISTER_IDENTITY){ - $this->buf->putEntityUniqueId($entry->entityUniqueId); + $out->putEntityUniqueId($entry->entityUniqueId); } } } diff --git a/src/network/mcpe/protocol/SetSpawnPositionPacket.php b/src/network/mcpe/protocol/SetSpawnPositionPacket.php index 9e8320a140..fe65a4965d 100644 --- a/src/network/mcpe/protocol/SetSpawnPositionPacket.php +++ b/src/network/mcpe/protocol/SetSpawnPositionPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetSpawnPositionPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_SPAWN_POSITION_PACKET; @@ -59,16 +60,16 @@ class SetSpawnPositionPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload() : void{ - $this->spawnType = $this->buf->getVarInt(); - $this->buf->getBlockPosition($this->x, $this->y, $this->z); - $this->spawnForced = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->spawnType = $in->getVarInt(); + $in->getBlockPosition($this->x, $this->y, $this->z); + $this->spawnForced = $in->getBool(); } - protected function encodePayload() : void{ - $this->buf->putVarInt($this->spawnType); - $this->buf->putBlockPosition($this->x, $this->y, $this->z); - $this->buf->putBool($this->spawnForced); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putVarInt($this->spawnType); + $out->putBlockPosition($this->x, $this->y, $this->z); + $out->putBool($this->spawnForced); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetTimePacket.php b/src/network/mcpe/protocol/SetTimePacket.php index b6fbac90b6..1883524926 100644 --- a/src/network/mcpe/protocol/SetTimePacket.php +++ b/src/network/mcpe/protocol/SetTimePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetTimePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_TIME_PACKET; @@ -39,12 +40,12 @@ class SetTimePacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload() : void{ - $this->time = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->time = $in->getVarInt(); } - protected function encodePayload() : void{ - $this->buf->putVarInt($this->time); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putVarInt($this->time); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SetTitlePacket.php b/src/network/mcpe/protocol/SetTitlePacket.php index 0e1585fa74..ca765ad530 100644 --- a/src/network/mcpe/protocol/SetTitlePacket.php +++ b/src/network/mcpe/protocol/SetTitlePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetTitlePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_TITLE_PACKET; @@ -48,20 +49,20 @@ class SetTitlePacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $fadeOutTime = 0; - protected function decodePayload() : void{ - $this->type = $this->buf->getVarInt(); - $this->text = $this->buf->getString(); - $this->fadeInTime = $this->buf->getVarInt(); - $this->stayTime = $this->buf->getVarInt(); - $this->fadeOutTime = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->type = $in->getVarInt(); + $this->text = $in->getString(); + $this->fadeInTime = $in->getVarInt(); + $this->stayTime = $in->getVarInt(); + $this->fadeOutTime = $in->getVarInt(); } - protected function encodePayload() : void{ - $this->buf->putVarInt($this->type); - $this->buf->putString($this->text); - $this->buf->putVarInt($this->fadeInTime); - $this->buf->putVarInt($this->stayTime); - $this->buf->putVarInt($this->fadeOutTime); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putVarInt($this->type); + $out->putString($this->text); + $out->putVarInt($this->fadeInTime); + $out->putVarInt($this->stayTime); + $out->putVarInt($this->fadeOutTime); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SettingsCommandPacket.php b/src/network/mcpe/protocol/SettingsCommandPacket.php index 0844494551..7b81a20983 100644 --- a/src/network/mcpe/protocol/SettingsCommandPacket.php +++ b/src/network/mcpe/protocol/SettingsCommandPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SettingsCommandPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SETTINGS_COMMAND_PACKET; @@ -50,14 +51,14 @@ class SettingsCommandPacket extends DataPacket implements ServerboundPacket{ return $this->suppressOutput; } - protected function decodePayload() : void{ - $this->command = $this->buf->getString(); - $this->suppressOutput = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->command = $in->getString(); + $this->suppressOutput = $in->getBool(); } - protected function encodePayload() : void{ - $this->buf->putString($this->command); - $this->buf->putBool($this->suppressOutput); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->command); + $out->putBool($this->suppressOutput); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ShowCreditsPacket.php b/src/network/mcpe/protocol/ShowCreditsPacket.php index 7d58c4cddc..3d3ea2ca1a 100644 --- a/src/network/mcpe/protocol/ShowCreditsPacket.php +++ b/src/network/mcpe/protocol/ShowCreditsPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ShowCreditsPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SHOW_CREDITS_PACKET; @@ -38,14 +39,14 @@ class ShowCreditsPacket extends DataPacket implements ClientboundPacket, Serverb /** @var int */ public $status; - protected function decodePayload() : void{ - $this->playerEid = $this->buf->getEntityRuntimeId(); - $this->status = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->playerEid = $in->getEntityRuntimeId(); + $this->status = $in->getVarInt(); } - protected function encodePayload() : void{ - $this->buf->putEntityRuntimeId($this->playerEid); - $this->buf->putVarInt($this->status); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityRuntimeId($this->playerEid); + $out->putVarInt($this->status); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ShowProfilePacket.php b/src/network/mcpe/protocol/ShowProfilePacket.php index 0b78bc2a2d..b8865b9ecd 100644 --- a/src/network/mcpe/protocol/ShowProfilePacket.php +++ b/src/network/mcpe/protocol/ShowProfilePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ShowProfilePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SHOW_PROFILE_PACKET; @@ -33,12 +34,12 @@ class ShowProfilePacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $xuid; - protected function decodePayload() : void{ - $this->xuid = $this->buf->getString(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->xuid = $in->getString(); } - protected function encodePayload() : void{ - $this->buf->putString($this->xuid); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->xuid); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/ShowStoreOfferPacket.php b/src/network/mcpe/protocol/ShowStoreOfferPacket.php index 992dd18f8a..61f430a9d2 100644 --- a/src/network/mcpe/protocol/ShowStoreOfferPacket.php +++ b/src/network/mcpe/protocol/ShowStoreOfferPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ShowStoreOfferPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SHOW_STORE_OFFER_PACKET; @@ -35,14 +36,14 @@ class ShowStoreOfferPacket extends DataPacket implements ClientboundPacket{ /** @var bool */ public $showAll; - protected function decodePayload() : void{ - $this->offerId = $this->buf->getString(); - $this->showAll = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->offerId = $in->getString(); + $this->showAll = $in->getBool(); } - protected function encodePayload() : void{ - $this->buf->putString($this->offerId); - $this->buf->putBool($this->showAll); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->offerId); + $out->putBool($this->showAll); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SimpleEventPacket.php b/src/network/mcpe/protocol/SimpleEventPacket.php index 573fecbe87..732475b471 100644 --- a/src/network/mcpe/protocol/SimpleEventPacket.php +++ b/src/network/mcpe/protocol/SimpleEventPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SimpleEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SIMPLE_EVENT_PACKET; @@ -36,12 +37,12 @@ class SimpleEventPacket extends DataPacket implements ClientboundPacket, Serverb /** @var int */ public $eventType; - protected function decodePayload() : void{ - $this->eventType = $this->buf->getLShort(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->eventType = $in->getLShort(); } - protected function encodePayload() : void{ - $this->buf->putLShort($this->eventType); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putLShort($this->eventType); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php b/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php index ea4aed7667..74c6b2b25f 100644 --- a/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php +++ b/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SpawnExperienceOrbPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SPAWN_EXPERIENCE_ORB_PACKET; @@ -36,14 +37,14 @@ class SpawnExperienceOrbPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $amount; - protected function decodePayload() : void{ - $this->position = $this->buf->getVector3(); - $this->amount = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->position = $in->getVector3(); + $this->amount = $in->getVarInt(); } - protected function encodePayload() : void{ - $this->buf->putVector3($this->position); - $this->buf->putVarInt($this->amount); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putVector3($this->position); + $out->putVarInt($this->amount); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/SpawnParticleEffectPacket.php b/src/network/mcpe/protocol/SpawnParticleEffectPacket.php index 692dd8645c..e5bf0e6a92 100644 --- a/src/network/mcpe/protocol/SpawnParticleEffectPacket.php +++ b/src/network/mcpe/protocol/SpawnParticleEffectPacket.php @@ -28,6 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\DimensionIds; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SpawnParticleEffectPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SPAWN_PARTICLE_EFFECT_PACKET; @@ -41,18 +42,18 @@ class SpawnParticleEffectPacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $particleName; - protected function decodePayload() : void{ - $this->dimensionId = $this->buf->getByte(); - $this->entityUniqueId = $this->buf->getEntityUniqueId(); - $this->position = $this->buf->getVector3(); - $this->particleName = $this->buf->getString(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->dimensionId = $in->getByte(); + $this->entityUniqueId = $in->getEntityUniqueId(); + $this->position = $in->getVector3(); + $this->particleName = $in->getString(); } - protected function encodePayload() : void{ - $this->buf->putByte($this->dimensionId); - $this->buf->putEntityUniqueId($this->entityUniqueId); - $this->buf->putVector3($this->position); - $this->buf->putString($this->particleName); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putByte($this->dimensionId); + $out->putEntityUniqueId($this->entityUniqueId); + $out->putVector3($this->position); + $out->putString($this->particleName); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/StartGamePacket.php b/src/network/mcpe/protocol/StartGamePacket.php index 43099a9071..f61cba1358 100644 --- a/src/network/mcpe/protocol/StartGamePacket.php +++ b/src/network/mcpe/protocol/StartGamePacket.php @@ -162,150 +162,150 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{ */ public $itemTable = null; - protected function decodePayload() : void{ - $this->entityUniqueId = $this->buf->getEntityUniqueId(); - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); - $this->playerGamemode = $this->buf->getVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityUniqueId = $in->getEntityUniqueId(); + $this->entityRuntimeId = $in->getEntityRuntimeId(); + $this->playerGamemode = $in->getVarInt(); - $this->playerPosition = $this->buf->getVector3(); + $this->playerPosition = $in->getVector3(); - $this->pitch = $this->buf->getLFloat(); - $this->yaw = $this->buf->getLFloat(); + $this->pitch = $in->getLFloat(); + $this->yaw = $in->getLFloat(); //Level settings - $this->seed = $this->buf->getVarInt(); - $this->dimension = $this->buf->getVarInt(); - $this->generator = $this->buf->getVarInt(); - $this->worldGamemode = $this->buf->getVarInt(); - $this->difficulty = $this->buf->getVarInt(); - $this->buf->getBlockPosition($this->spawnX, $this->spawnY, $this->spawnZ); - $this->hasAchievementsDisabled = $this->buf->getBool(); - $this->time = $this->buf->getVarInt(); - $this->eduEditionOffer = $this->buf->getVarInt(); - $this->hasEduFeaturesEnabled = $this->buf->getBool(); - $this->rainLevel = $this->buf->getLFloat(); - $this->lightningLevel = $this->buf->getLFloat(); - $this->hasConfirmedPlatformLockedContent = $this->buf->getBool(); - $this->isMultiplayerGame = $this->buf->getBool(); - $this->hasLANBroadcast = $this->buf->getBool(); - $this->xboxLiveBroadcastMode = $this->buf->getVarInt(); - $this->platformBroadcastMode = $this->buf->getVarInt(); - $this->commandsEnabled = $this->buf->getBool(); - $this->isTexturePacksRequired = $this->buf->getBool(); - $this->gameRules = $this->buf->getGameRules(); - $this->hasBonusChestEnabled = $this->buf->getBool(); - $this->hasStartWithMapEnabled = $this->buf->getBool(); - $this->defaultPlayerPermission = $this->buf->getVarInt(); - $this->serverChunkTickRadius = $this->buf->getLInt(); - $this->hasLockedBehaviorPack = $this->buf->getBool(); - $this->hasLockedResourcePack = $this->buf->getBool(); - $this->isFromLockedWorldTemplate = $this->buf->getBool(); - $this->useMsaGamertagsOnly = $this->buf->getBool(); - $this->isFromWorldTemplate = $this->buf->getBool(); - $this->isWorldTemplateOptionLocked = $this->buf->getBool(); - $this->onlySpawnV1Villagers = $this->buf->getBool(); + $this->seed = $in->getVarInt(); + $this->dimension = $in->getVarInt(); + $this->generator = $in->getVarInt(); + $this->worldGamemode = $in->getVarInt(); + $this->difficulty = $in->getVarInt(); + $in->getBlockPosition($this->spawnX, $this->spawnY, $this->spawnZ); + $this->hasAchievementsDisabled = $in->getBool(); + $this->time = $in->getVarInt(); + $this->eduEditionOffer = $in->getVarInt(); + $this->hasEduFeaturesEnabled = $in->getBool(); + $this->rainLevel = $in->getLFloat(); + $this->lightningLevel = $in->getLFloat(); + $this->hasConfirmedPlatformLockedContent = $in->getBool(); + $this->isMultiplayerGame = $in->getBool(); + $this->hasLANBroadcast = $in->getBool(); + $this->xboxLiveBroadcastMode = $in->getVarInt(); + $this->platformBroadcastMode = $in->getVarInt(); + $this->commandsEnabled = $in->getBool(); + $this->isTexturePacksRequired = $in->getBool(); + $this->gameRules = $in->getGameRules(); + $this->hasBonusChestEnabled = $in->getBool(); + $this->hasStartWithMapEnabled = $in->getBool(); + $this->defaultPlayerPermission = $in->getVarInt(); + $this->serverChunkTickRadius = $in->getLInt(); + $this->hasLockedBehaviorPack = $in->getBool(); + $this->hasLockedResourcePack = $in->getBool(); + $this->isFromLockedWorldTemplate = $in->getBool(); + $this->useMsaGamertagsOnly = $in->getBool(); + $this->isFromWorldTemplate = $in->getBool(); + $this->isWorldTemplateOptionLocked = $in->getBool(); + $this->onlySpawnV1Villagers = $in->getBool(); - $this->vanillaVersion = $this->buf->getString(); - $this->levelId = $this->buf->getString(); - $this->worldName = $this->buf->getString(); - $this->premiumWorldTemplateId = $this->buf->getString(); - $this->isTrial = $this->buf->getBool(); - $this->isMovementServerAuthoritative = $this->buf->getBool(); - $this->currentTick = $this->buf->getLLong(); + $this->vanillaVersion = $in->getString(); + $this->levelId = $in->getString(); + $this->worldName = $in->getString(); + $this->premiumWorldTemplateId = $in->getString(); + $this->isTrial = $in->getBool(); + $this->isMovementServerAuthoritative = $in->getBool(); + $this->currentTick = $in->getLLong(); - $this->enchantmentSeed = $this->buf->getVarInt(); + $this->enchantmentSeed = $in->getVarInt(); - $offset = $this->buf->getOffset(); - $blockTable = (new NetworkNbtSerializer())->read($this->buf->getBuffer(), $offset, 512)->getTag(); - $this->buf->setOffset($offset); + $offset = $in->getOffset(); + $blockTable = (new NetworkNbtSerializer())->read($in->getBuffer(), $offset, 512)->getTag(); + $in->setOffset($offset); if(!($blockTable instanceof ListTag)){ throw new \UnexpectedValueException("Wrong block table root NBT tag type"); } $this->blockTable = $blockTable; $this->itemTable = []; - for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ - $id = $this->buf->getString(); - $legacyId = $this->buf->getSignedLShort(); + for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ + $id = $in->getString(); + $legacyId = $in->getSignedLShort(); $this->itemTable[$id] = $legacyId; } - $this->multiplayerCorrelationId = $this->buf->getString(); + $this->multiplayerCorrelationId = $in->getString(); } - protected function encodePayload() : void{ - $this->buf->putEntityUniqueId($this->entityUniqueId); - $this->buf->putEntityRuntimeId($this->entityRuntimeId); - $this->buf->putVarInt($this->playerGamemode); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityUniqueId($this->entityUniqueId); + $out->putEntityRuntimeId($this->entityRuntimeId); + $out->putVarInt($this->playerGamemode); - $this->buf->putVector3($this->playerPosition); + $out->putVector3($this->playerPosition); - $this->buf->putLFloat($this->pitch); - $this->buf->putLFloat($this->yaw); + $out->putLFloat($this->pitch); + $out->putLFloat($this->yaw); //Level settings - $this->buf->putVarInt($this->seed); - $this->buf->putVarInt($this->dimension); - $this->buf->putVarInt($this->generator); - $this->buf->putVarInt($this->worldGamemode); - $this->buf->putVarInt($this->difficulty); - $this->buf->putBlockPosition($this->spawnX, $this->spawnY, $this->spawnZ); - $this->buf->putBool($this->hasAchievementsDisabled); - $this->buf->putVarInt($this->time); - $this->buf->putVarInt($this->eduEditionOffer); - $this->buf->putBool($this->hasEduFeaturesEnabled); - $this->buf->putLFloat($this->rainLevel); - $this->buf->putLFloat($this->lightningLevel); - $this->buf->putBool($this->hasConfirmedPlatformLockedContent); - $this->buf->putBool($this->isMultiplayerGame); - $this->buf->putBool($this->hasLANBroadcast); - $this->buf->putVarInt($this->xboxLiveBroadcastMode); - $this->buf->putVarInt($this->platformBroadcastMode); - $this->buf->putBool($this->commandsEnabled); - $this->buf->putBool($this->isTexturePacksRequired); - $this->buf->putGameRules($this->gameRules); - $this->buf->putBool($this->hasBonusChestEnabled); - $this->buf->putBool($this->hasStartWithMapEnabled); - $this->buf->putVarInt($this->defaultPlayerPermission); - $this->buf->putLInt($this->serverChunkTickRadius); - $this->buf->putBool($this->hasLockedBehaviorPack); - $this->buf->putBool($this->hasLockedResourcePack); - $this->buf->putBool($this->isFromLockedWorldTemplate); - $this->buf->putBool($this->useMsaGamertagsOnly); - $this->buf->putBool($this->isFromWorldTemplate); - $this->buf->putBool($this->isWorldTemplateOptionLocked); - $this->buf->putBool($this->onlySpawnV1Villagers); + $out->putVarInt($this->seed); + $out->putVarInt($this->dimension); + $out->putVarInt($this->generator); + $out->putVarInt($this->worldGamemode); + $out->putVarInt($this->difficulty); + $out->putBlockPosition($this->spawnX, $this->spawnY, $this->spawnZ); + $out->putBool($this->hasAchievementsDisabled); + $out->putVarInt($this->time); + $out->putVarInt($this->eduEditionOffer); + $out->putBool($this->hasEduFeaturesEnabled); + $out->putLFloat($this->rainLevel); + $out->putLFloat($this->lightningLevel); + $out->putBool($this->hasConfirmedPlatformLockedContent); + $out->putBool($this->isMultiplayerGame); + $out->putBool($this->hasLANBroadcast); + $out->putVarInt($this->xboxLiveBroadcastMode); + $out->putVarInt($this->platformBroadcastMode); + $out->putBool($this->commandsEnabled); + $out->putBool($this->isTexturePacksRequired); + $out->putGameRules($this->gameRules); + $out->putBool($this->hasBonusChestEnabled); + $out->putBool($this->hasStartWithMapEnabled); + $out->putVarInt($this->defaultPlayerPermission); + $out->putLInt($this->serverChunkTickRadius); + $out->putBool($this->hasLockedBehaviorPack); + $out->putBool($this->hasLockedResourcePack); + $out->putBool($this->isFromLockedWorldTemplate); + $out->putBool($this->useMsaGamertagsOnly); + $out->putBool($this->isFromWorldTemplate); + $out->putBool($this->isWorldTemplateOptionLocked); + $out->putBool($this->onlySpawnV1Villagers); - $this->buf->putString($this->vanillaVersion); - $this->buf->putString($this->levelId); - $this->buf->putString($this->worldName); - $this->buf->putString($this->premiumWorldTemplateId); - $this->buf->putBool($this->isTrial); - $this->buf->putBool($this->isMovementServerAuthoritative); - $this->buf->putLLong($this->currentTick); + $out->putString($this->vanillaVersion); + $out->putString($this->levelId); + $out->putString($this->worldName); + $out->putString($this->premiumWorldTemplateId); + $out->putBool($this->isTrial); + $out->putBool($this->isMovementServerAuthoritative); + $out->putLLong($this->currentTick); - $this->buf->putVarInt($this->enchantmentSeed); + $out->putVarInt($this->enchantmentSeed); if($this->blockTable === null){ if(self::$blockTableCache === null){ //this is a really nasty hack, but it'll do for now self::$blockTableCache = (new NetworkNbtSerializer())->write(new TreeRoot(new ListTag(RuntimeBlockMapping::getBedrockKnownStates()))); } - $this->buf->put(self::$blockTableCache); + $out->put(self::$blockTableCache); }else{ - $this->buf->put((new NetworkNbtSerializer())->write(new TreeRoot($this->blockTable))); + $out->put((new NetworkNbtSerializer())->write(new TreeRoot($this->blockTable))); } if($this->itemTable === null){ if(self::$itemTableCache === null){ self::$itemTableCache = self::serializeItemTable(json_decode(file_get_contents(RESOURCE_PATH . '/vanilla/item_id_map.json'), true)); } - $this->buf->put(self::$itemTableCache); + $out->put(self::$itemTableCache); }else{ - $this->buf->put(self::serializeItemTable($this->itemTable)); + $out->put(self::serializeItemTable($this->itemTable)); } - $this->buf->putString($this->multiplayerCorrelationId); + $out->putString($this->multiplayerCorrelationId); } /** diff --git a/src/network/mcpe/protocol/StopSoundPacket.php b/src/network/mcpe/protocol/StopSoundPacket.php index 4a61eea6bf..50e92ede74 100644 --- a/src/network/mcpe/protocol/StopSoundPacket.php +++ b/src/network/mcpe/protocol/StopSoundPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class StopSoundPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::STOP_SOUND_PACKET; @@ -35,14 +36,14 @@ class StopSoundPacket extends DataPacket implements ClientboundPacket{ /** @var bool */ public $stopAll; - protected function decodePayload() : void{ - $this->soundName = $this->buf->getString(); - $this->stopAll = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->soundName = $in->getString(); + $this->stopAll = $in->getBool(); } - protected function encodePayload() : void{ - $this->buf->putString($this->soundName); - $this->buf->putBool($this->stopAll); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->soundName); + $out->putBool($this->stopAll); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/StructureBlockUpdatePacket.php b/src/network/mcpe/protocol/StructureBlockUpdatePacket.php index 422ad3a438..69e258de59 100644 --- a/src/network/mcpe/protocol/StructureBlockUpdatePacket.php +++ b/src/network/mcpe/protocol/StructureBlockUpdatePacket.php @@ -26,15 +26,16 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class StructureBlockUpdatePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::STRUCTURE_BLOCK_UPDATE_PACKET; - protected function decodePayload() : void{ + protected function decodePayload(NetworkBinaryStream $in) : void{ //TODO } - protected function encodePayload() : void{ + protected function encodePayload(NetworkBinaryStream $out) : void{ //TODO } diff --git a/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php b/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php index b2c52ea31c..11344f0dd5 100644 --- a/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php +++ b/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\StructureSettings; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class StructureTemplateDataRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::STRUCTURE_TEMPLATE_DATA_REQUEST_PACKET; @@ -47,18 +48,18 @@ class StructureTemplateDataRequestPacket extends DataPacket implements Serverbou /** @var int */ public $structureTemplateResponseType; - protected function decodePayload() : void{ - $this->structureTemplateName = $this->buf->getString(); - $this->buf->getBlockPosition($this->structureBlockX, $this->structureBlockY, $this->structureBlockZ); - $this->structureSettings = $this->buf->getStructureSettings(); - $this->structureTemplateResponseType = $this->buf->getByte(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->structureTemplateName = $in->getString(); + $in->getBlockPosition($this->structureBlockX, $this->structureBlockY, $this->structureBlockZ); + $this->structureSettings = $in->getStructureSettings(); + $this->structureTemplateResponseType = $in->getByte(); } - protected function encodePayload() : void{ - $this->buf->putString($this->structureTemplateName); - $this->buf->putBlockPosition($this->structureBlockX, $this->structureBlockY, $this->structureBlockZ); - $this->buf->putStructureSettings($this->structureSettings); - $this->buf->putByte($this->structureTemplateResponseType); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->structureTemplateName); + $out->putBlockPosition($this->structureBlockX, $this->structureBlockY, $this->structureBlockZ); + $out->putStructureSettings($this->structureSettings); + $out->putByte($this->structureTemplateResponseType); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php b/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php index 7d81ac3eef..78f565296c 100644 --- a/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php +++ b/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class StructureTemplateDataResponsePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::STRUCTURE_TEMPLATE_DATA_RESPONSE_PACKET; @@ -35,18 +36,18 @@ class StructureTemplateDataResponsePacket extends DataPacket implements Clientbo /** @var string|null */ public $namedtag; - protected function decodePayload() : void{ - $this->structureTemplateName = $this->buf->getString(); - if($this->buf->getBool()){ - $this->namedtag = $this->buf->getRemaining(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->structureTemplateName = $in->getString(); + if($in->getBool()){ + $this->namedtag = $in->getRemaining(); } } - protected function encodePayload() : void{ - $this->buf->putString($this->structureTemplateName); - $this->buf->putBool($this->namedtag !== null); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->structureTemplateName); + $out->putBool($this->namedtag !== null); if($this->namedtag !== null){ - $this->buf->put($this->namedtag); + $out->put($this->namedtag); } } diff --git a/src/network/mcpe/protocol/SubClientLoginPacket.php b/src/network/mcpe/protocol/SubClientLoginPacket.php index 90a4fa1b1d..d2f8b4a091 100644 --- a/src/network/mcpe/protocol/SubClientLoginPacket.php +++ b/src/network/mcpe/protocol/SubClientLoginPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SubClientLoginPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SUB_CLIENT_LOGIN_PACKET; @@ -33,12 +34,12 @@ class SubClientLoginPacket extends DataPacket implements ServerboundPacket{ /** @var string */ public $connectionRequestData; - protected function decodePayload() : void{ - $this->connectionRequestData = $this->buf->getString(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->connectionRequestData = $in->getString(); } - protected function encodePayload() : void{ - $this->buf->putString($this->connectionRequestData); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->connectionRequestData); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/TakeItemActorPacket.php b/src/network/mcpe/protocol/TakeItemActorPacket.php index e3b768afe4..6a689b0eff 100644 --- a/src/network/mcpe/protocol/TakeItemActorPacket.php +++ b/src/network/mcpe/protocol/TakeItemActorPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class TakeItemActorPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::TAKE_ITEM_ACTOR_PACKET; @@ -42,14 +43,14 @@ class TakeItemActorPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload() : void{ - $this->target = $this->buf->getEntityRuntimeId(); - $this->eid = $this->buf->getEntityRuntimeId(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->target = $in->getEntityRuntimeId(); + $this->eid = $in->getEntityRuntimeId(); } - protected function encodePayload() : void{ - $this->buf->putEntityRuntimeId($this->target); - $this->buf->putEntityRuntimeId($this->eid); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityRuntimeId($this->target); + $out->putEntityRuntimeId($this->eid); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/TextPacket.php b/src/network/mcpe/protocol/TextPacket.php index 0e37555c63..0cc905363d 100644 --- a/src/network/mcpe/protocol/TextPacket.php +++ b/src/network/mcpe/protocol/TextPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -115,66 +116,66 @@ class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPac return self::messageOnly(self::TYPE_TIP, $message); } - protected function decodePayload() : void{ - $this->type = $this->buf->getByte(); - $this->needsTranslation = $this->buf->getBool(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->type = $in->getByte(); + $this->needsTranslation = $in->getBool(); switch($this->type){ case self::TYPE_CHAT: case self::TYPE_WHISPER: /** @noinspection PhpMissingBreakStatementInspection */ case self::TYPE_ANNOUNCEMENT: - $this->sourceName = $this->buf->getString(); + $this->sourceName = $in->getString(); case self::TYPE_RAW: case self::TYPE_TIP: case self::TYPE_SYSTEM: case self::TYPE_JSON: - $this->message = $this->buf->getString(); + $this->message = $in->getString(); break; case self::TYPE_TRANSLATION: case self::TYPE_POPUP: case self::TYPE_JUKEBOX_POPUP: - $this->message = $this->buf->getString(); - $count = $this->buf->getUnsignedVarInt(); + $this->message = $in->getString(); + $count = $in->getUnsignedVarInt(); for($i = 0; $i < $count; ++$i){ - $this->parameters[] = $this->buf->getString(); + $this->parameters[] = $in->getString(); } break; } - $this->xboxUserId = $this->buf->getString(); - $this->platformChatId = $this->buf->getString(); + $this->xboxUserId = $in->getString(); + $this->platformChatId = $in->getString(); } - protected function encodePayload() : void{ - $this->buf->putByte($this->type); - $this->buf->putBool($this->needsTranslation); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putByte($this->type); + $out->putBool($this->needsTranslation); switch($this->type){ case self::TYPE_CHAT: case self::TYPE_WHISPER: /** @noinspection PhpMissingBreakStatementInspection */ case self::TYPE_ANNOUNCEMENT: - $this->buf->putString($this->sourceName); + $out->putString($this->sourceName); case self::TYPE_RAW: case self::TYPE_TIP: case self::TYPE_SYSTEM: case self::TYPE_JSON: - $this->buf->putString($this->message); + $out->putString($this->message); break; case self::TYPE_TRANSLATION: case self::TYPE_POPUP: case self::TYPE_JUKEBOX_POPUP: - $this->buf->putString($this->message); - $this->buf->putUnsignedVarInt(count($this->parameters)); + $out->putString($this->message); + $out->putUnsignedVarInt(count($this->parameters)); foreach($this->parameters as $p){ - $this->buf->putString($p); + $out->putString($p); } break; } - $this->buf->putString($this->xboxUserId); - $this->buf->putString($this->platformChatId); + $out->putString($this->xboxUserId); + $out->putString($this->platformChatId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/TickSyncPacket.php b/src/network/mcpe/protocol/TickSyncPacket.php index c192f6d62c..47c0e3c0ef 100644 --- a/src/network/mcpe/protocol/TickSyncPacket.php +++ b/src/network/mcpe/protocol/TickSyncPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class TickSyncPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::TICK_SYNC_PACKET; @@ -57,14 +58,14 @@ class TickSyncPacket extends DataPacket implements ClientboundPacket, Serverboun return $this->serverReceiveTime; } - protected function decodePayload() : void{ - $this->clientSendTime = $this->buf->getLLong(); - $this->serverReceiveTime = $this->buf->getLLong(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->clientSendTime = $in->getLLong(); + $this->serverReceiveTime = $in->getLLong(); } - protected function encodePayload() : void{ - $this->buf->putLLong($this->clientSendTime); - $this->buf->putLLong($this->serverReceiveTime); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putLLong($this->clientSendTime); + $out->putLLong($this->serverReceiveTime); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/TransferPacket.php b/src/network/mcpe/protocol/TransferPacket.php index d02d1e5341..22bc5de944 100644 --- a/src/network/mcpe/protocol/TransferPacket.php +++ b/src/network/mcpe/protocol/TransferPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class TransferPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::TRANSFER_PACKET; @@ -42,14 +43,14 @@ class TransferPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload() : void{ - $this->address = $this->buf->getString(); - $this->port = $this->buf->getLShort(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->address = $in->getString(); + $this->port = $in->getLShort(); } - protected function encodePayload() : void{ - $this->buf->putString($this->address); - $this->buf->putLShort($this->port); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->address); + $out->putLShort($this->port); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/UnknownPacket.php b/src/network/mcpe/protocol/UnknownPacket.php index dee77cce62..c5ba65a7a6 100644 --- a/src/network/mcpe/protocol/UnknownPacket.php +++ b/src/network/mcpe/protocol/UnknownPacket.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function ord; use function strlen; @@ -44,20 +45,20 @@ class UnknownPacket extends DataPacket{ return "unknown packet"; } - protected function decodeHeader() : void{ + protected function decodeHeader(NetworkBinaryStream $in) : void{ } - protected function decodePayload() : void{ - $this->payload = $this->buf->getRemaining(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->payload = $in->getRemaining(); } - protected function encodeHeader() : void{ + protected function encodeHeader(NetworkBinaryStream $out) : void{ } - protected function encodePayload() : void{ - $this->buf->put($this->payload); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->put($this->payload); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/UpdateAttributesPacket.php b/src/network/mcpe/protocol/UpdateAttributesPacket.php index 4f14f13d8b..65c25dd120 100644 --- a/src/network/mcpe/protocol/UpdateAttributesPacket.php +++ b/src/network/mcpe/protocol/UpdateAttributesPacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\entity\Attribute; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function array_values; class UpdateAttributesPacket extends DataPacket implements ClientboundPacket{ @@ -49,14 +50,14 @@ class UpdateAttributesPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload() : void{ - $this->entityRuntimeId = $this->buf->getEntityRuntimeId(); - $this->entries = $this->buf->getAttributeList(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->entityRuntimeId = $in->getEntityRuntimeId(); + $this->entries = $in->getAttributeList(); } - protected function encodePayload() : void{ - $this->buf->putEntityRuntimeId($this->entityRuntimeId); - $this->buf->putAttributeList(...array_values($this->entries)); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putEntityRuntimeId($this->entityRuntimeId); + $out->putAttributeList(...array_values($this->entries)); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/UpdateBlockPacket.php b/src/network/mcpe/protocol/UpdateBlockPacket.php index 314999ef64..c7cb2669a2 100644 --- a/src/network/mcpe/protocol/UpdateBlockPacket.php +++ b/src/network/mcpe/protocol/UpdateBlockPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class UpdateBlockPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_BLOCK_PACKET; @@ -58,18 +59,18 @@ class UpdateBlockPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload() : void{ - $this->buf->getBlockPosition($this->x, $this->y, $this->z); - $this->blockRuntimeId = $this->buf->getUnsignedVarInt(); - $this->flags = $this->buf->getUnsignedVarInt(); - $this->dataLayerId = $this->buf->getUnsignedVarInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $in->getBlockPosition($this->x, $this->y, $this->z); + $this->blockRuntimeId = $in->getUnsignedVarInt(); + $this->flags = $in->getUnsignedVarInt(); + $this->dataLayerId = $in->getUnsignedVarInt(); } - protected function encodePayload() : void{ - $this->buf->putBlockPosition($this->x, $this->y, $this->z); - $this->buf->putUnsignedVarInt($this->blockRuntimeId); - $this->buf->putUnsignedVarInt($this->flags); - $this->buf->putUnsignedVarInt($this->dataLayerId); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putBlockPosition($this->x, $this->y, $this->z); + $out->putUnsignedVarInt($this->blockRuntimeId); + $out->putUnsignedVarInt($this->flags); + $out->putUnsignedVarInt($this->dataLayerId); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php b/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php index 1ab72c79dd..838a7a4ef1 100644 --- a/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php +++ b/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php @@ -28,6 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; class UpdateBlockPropertiesPacket extends DataPacket implements ClientboundPacket{ @@ -42,12 +43,12 @@ class UpdateBlockPropertiesPacket extends DataPacket implements ClientboundPacke return $result; } - protected function decodePayload() : void{ - $this->nbt = $this->buf->getRemaining(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->nbt = $in->getRemaining(); } - protected function encodePayload() : void{ - $this->buf->put($this->nbt); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->put($this->nbt); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php b/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php index ace3894d86..605550dd3c 100644 --- a/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php +++ b/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class UpdateBlockSyncedPacket extends UpdateBlockPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_BLOCK_SYNCED_PACKET; @@ -35,16 +36,16 @@ class UpdateBlockSyncedPacket extends UpdateBlockPacket{ /** @var int */ public $uvarint64_2 = 0; - protected function decodePayload() : void{ - parent::decodePayload(); - $this->entityUniqueId = $this->buf->getUnsignedVarLong(); - $this->uvarint64_2 = $this->buf->getUnsignedVarLong(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + parent::decodePayload($in); + $this->entityUniqueId = $in->getUnsignedVarLong(); + $this->uvarint64_2 = $in->getUnsignedVarLong(); } - protected function encodePayload() : void{ - parent::encodePayload(); - $this->buf->putUnsignedVarLong($this->entityUniqueId); - $this->buf->putUnsignedVarLong($this->uvarint64_2); + protected function encodePayload(NetworkBinaryStream $out) : void{ + parent::encodePayload($out); + $out->putUnsignedVarLong($this->entityUniqueId); + $out->putUnsignedVarLong($this->uvarint64_2); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/UpdateEquipPacket.php b/src/network/mcpe/protocol/UpdateEquipPacket.php index 9567e865fc..3c155c6114 100644 --- a/src/network/mcpe/protocol/UpdateEquipPacket.php +++ b/src/network/mcpe/protocol/UpdateEquipPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class UpdateEquipPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_EQUIP_PACKET; @@ -41,20 +42,20 @@ class UpdateEquipPacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $namedtag; - protected function decodePayload() : void{ - $this->windowId = $this->buf->getByte(); - $this->windowType = $this->buf->getByte(); - $this->unknownVarint = $this->buf->getVarInt(); - $this->entityUniqueId = $this->buf->getEntityUniqueId(); - $this->namedtag = $this->buf->getRemaining(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->windowId = $in->getByte(); + $this->windowType = $in->getByte(); + $this->unknownVarint = $in->getVarInt(); + $this->entityUniqueId = $in->getEntityUniqueId(); + $this->namedtag = $in->getRemaining(); } - protected function encodePayload() : void{ - $this->buf->putByte($this->windowId); - $this->buf->putByte($this->windowType); - $this->buf->putVarInt($this->unknownVarint); - $this->buf->putEntityUniqueId($this->entityUniqueId); - $this->buf->put($this->namedtag); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putByte($this->windowId); + $out->putByte($this->windowType); + $out->putVarInt($this->unknownVarint); + $out->putEntityUniqueId($this->entityUniqueId); + $out->put($this->namedtag); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/UpdateSoftEnumPacket.php b/src/network/mcpe/protocol/UpdateSoftEnumPacket.php index 5744a02c40..f838a195d9 100644 --- a/src/network/mcpe/protocol/UpdateSoftEnumPacket.php +++ b/src/network/mcpe/protocol/UpdateSoftEnumPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class UpdateSoftEnumPacket extends DataPacket implements ClientboundPacket{ @@ -42,21 +43,21 @@ class UpdateSoftEnumPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $type; - protected function decodePayload() : void{ - $this->enumName = $this->buf->getString(); - for($i = 0, $count = $this->buf->getUnsignedVarInt(); $i < $count; ++$i){ - $this->values[] = $this->buf->getString(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->enumName = $in->getString(); + for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ + $this->values[] = $in->getString(); } - $this->type = $this->buf->getByte(); + $this->type = $in->getByte(); } - protected function encodePayload() : void{ - $this->buf->putString($this->enumName); - $this->buf->putUnsignedVarInt(count($this->values)); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->enumName); + $out->putUnsignedVarInt(count($this->values)); foreach($this->values as $v){ - $this->buf->putString($v); + $out->putString($v); } - $this->buf->putByte($this->type); + $out->putByte($this->type); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/UpdateTradePacket.php b/src/network/mcpe/protocol/UpdateTradePacket.php index 36e39ef8e3..6fc84a9c16 100644 --- a/src/network/mcpe/protocol/UpdateTradePacket.php +++ b/src/network/mcpe/protocol/UpdateTradePacket.php @@ -27,6 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class UpdateTradePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_TRADE_PACKET; @@ -54,30 +55,30 @@ class UpdateTradePacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $offers; - protected function decodePayload() : void{ - $this->windowId = $this->buf->getByte(); - $this->windowType = $this->buf->getByte(); - $this->thisIsAlwaysZero = $this->buf->getVarInt(); - $this->tradeTier = $this->buf->getVarInt(); - $this->traderEid = $this->buf->getEntityUniqueId(); - $this->playerEid = $this->buf->getEntityUniqueId(); - $this->displayName = $this->buf->getString(); - $this->isV2Trading = $this->buf->getBool(); - $this->isWilling = $this->buf->getBool(); - $this->offers = $this->buf->getRemaining(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->windowId = $in->getByte(); + $this->windowType = $in->getByte(); + $this->thisIsAlwaysZero = $in->getVarInt(); + $this->tradeTier = $in->getVarInt(); + $this->traderEid = $in->getEntityUniqueId(); + $this->playerEid = $in->getEntityUniqueId(); + $this->displayName = $in->getString(); + $this->isV2Trading = $in->getBool(); + $this->isWilling = $in->getBool(); + $this->offers = $in->getRemaining(); } - protected function encodePayload() : void{ - $this->buf->putByte($this->windowId); - $this->buf->putByte($this->windowType); - $this->buf->putVarInt($this->thisIsAlwaysZero); - $this->buf->putVarInt($this->tradeTier); - $this->buf->putEntityUniqueId($this->traderEid); - $this->buf->putEntityUniqueId($this->playerEid); - $this->buf->putString($this->displayName); - $this->buf->putBool($this->isV2Trading); - $this->buf->putBool($this->isWilling); - $this->buf->put($this->offers); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putByte($this->windowId); + $out->putByte($this->windowType); + $out->putVarInt($this->thisIsAlwaysZero); + $out->putVarInt($this->tradeTier); + $out->putEntityUniqueId($this->traderEid); + $out->putEntityUniqueId($this->playerEid); + $out->putString($this->displayName); + $out->putBool($this->isV2Trading); + $out->putBool($this->isWilling); + $out->put($this->offers); } public function handle(PacketHandler $handler) : bool{ diff --git a/src/network/mcpe/protocol/VideoStreamConnectPacket.php b/src/network/mcpe/protocol/VideoStreamConnectPacket.php index d599b2a61b..94e8250c2a 100644 --- a/src/network/mcpe/protocol/VideoStreamConnectPacket.php +++ b/src/network/mcpe/protocol/VideoStreamConnectPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class VideoStreamConnectPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::VIDEO_STREAM_CONNECT_PACKET; @@ -44,20 +45,20 @@ class VideoStreamConnectPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $resolutionY; - protected function decodePayload() : void{ - $this->serverUri = $this->buf->getString(); - $this->frameSendFrequency = $this->buf->getLFloat(); - $this->action = $this->buf->getByte(); - $this->resolutionX = $this->buf->getLInt(); - $this->resolutionY = $this->buf->getLInt(); + protected function decodePayload(NetworkBinaryStream $in) : void{ + $this->serverUri = $in->getString(); + $this->frameSendFrequency = $in->getLFloat(); + $this->action = $in->getByte(); + $this->resolutionX = $in->getLInt(); + $this->resolutionY = $in->getLInt(); } - protected function encodePayload() : void{ - $this->buf->putString($this->serverUri); - $this->buf->putLFloat($this->frameSendFrequency); - $this->buf->putByte($this->action); - $this->buf->putLInt($this->resolutionX); - $this->buf->putLInt($this->resolutionY); + protected function encodePayload(NetworkBinaryStream $out) : void{ + $out->putString($this->serverUri); + $out->putLFloat($this->frameSendFrequency); + $out->putByte($this->action); + $out->putLInt($this->resolutionX); + $out->putLInt($this->resolutionY); } public function handle(PacketHandler $handler) : bool{ diff --git a/tests/phpunit/network/mcpe/protocol/TestPacket.php b/tests/phpunit/network/mcpe/protocol/TestPacket.php index 86e82f2d00..17a30bcb01 100644 --- a/tests/phpunit/network/mcpe/protocol/TestPacket.php +++ b/tests/phpunit/network/mcpe/protocol/TestPacket.php @@ -24,15 +24,16 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class TestPacket extends DataPacket{ public const NETWORK_ID = 1023; - protected function decodePayload() : void{ + protected function decodePayload(NetworkBinaryStream $in) : void{ } - protected function encodePayload() : void{ + protected function encodePayload(NetworkBinaryStream $out) : void{ } From 995309424e652b81beb2b39ffdbb1d89820541fd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Mar 2020 17:53:37 +0000 Subject: [PATCH 1410/3224] updated pocketmine/nbt dependency this is going to need work on exception handling, but right now it's so inconsistent that it doesn't matter anyway. --- composer.lock | 8 ++++---- src/block/tile/Comparator.php | 2 +- src/block/tile/Furnace.php | 6 +++--- src/block/tile/ItemFrame.php | 4 ++-- src/block/tile/Skull.php | 2 +- src/block/tile/TileFactory.php | 2 +- src/entity/Human.php | 14 +++++++------- src/entity/object/PrimedTNT.php | 2 +- src/entity/projectile/Arrow.php | 2 +- src/item/Item.php | 6 +++--- src/player/Player.php | 2 +- src/world/format/Chunk.php | 13 +++++++++++-- src/world/format/io/data/BaseNbtWorldData.php | 8 ++++++-- src/world/format/io/data/BedrockWorldData.php | 2 +- src/world/format/io/data/JavaWorldData.php | 2 +- .../format/io/region/LegacyAnvilChunkTrait.php | 2 +- 16 files changed, 45 insertions(+), 32 deletions(-) diff --git a/composer.lock b/composer.lock index 3e98a2d590..6bfe05bd38 100644 --- a/composer.lock +++ b/composer.lock @@ -443,12 +443,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "1cdf6aec3024e2061b8c3e5045c43250df94a740" + "reference": "f205b5e6fe47ddf0ead4f1438b37f9cdee1fc407" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/1cdf6aec3024e2061b8c3e5045c43250df94a740", - "reference": "1cdf6aec3024e2061b8c3e5045c43250df94a740", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/f205b5e6fe47ddf0ead4f1438b37f9cdee1fc407", + "reference": "f205b5e6fe47ddf0ead4f1438b37f9cdee1fc407", "shasum": "" }, "require": { @@ -472,7 +472,7 @@ "LGPL-3.0" ], "description": "PHP library for working with Named Binary Tags", - "time": "2020-02-24T21:43:33+00:00" + "time": "2020-03-04T16:39:25+00:00" }, { "name": "pocketmine/raklib", diff --git a/src/block/tile/Comparator.php b/src/block/tile/Comparator.php index 24e63a79d5..317a682f48 100644 --- a/src/block/tile/Comparator.php +++ b/src/block/tile/Comparator.php @@ -45,7 +45,7 @@ class Comparator extends Tile{ } public function readSaveData(CompoundTag $nbt) : void{ - $this->signalStrength = $nbt->getInt(self::TAG_OUTPUT_SIGNAL, 0, true); + $this->signalStrength = $nbt->getInt(self::TAG_OUTPUT_SIGNAL, 0); } protected function writeSaveData(CompoundTag $nbt) : void{ diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index 0428cfb0bb..a94491afdf 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -66,14 +66,14 @@ class Furnace extends Spawnable implements Container, Nameable{ } public function readSaveData(CompoundTag $nbt) : void{ - $this->remainingFuelTime = max(0, $nbt->getShort(self::TAG_BURN_TIME, $this->remainingFuelTime, true)); + $this->remainingFuelTime = max(0, $nbt->getShort(self::TAG_BURN_TIME, $this->remainingFuelTime)); - $this->cookTime = $nbt->getShort(self::TAG_COOK_TIME, $this->cookTime, true); + $this->cookTime = $nbt->getShort(self::TAG_COOK_TIME, $this->cookTime); if($this->remainingFuelTime === 0){ $this->cookTime = 0; } - $this->maxFuelTime = $nbt->getShort(self::TAG_MAX_TIME, $this->maxFuelTime, true); + $this->maxFuelTime = $nbt->getShort(self::TAG_MAX_TIME, $this->maxFuelTime); if($this->maxFuelTime === 0){ $this->maxFuelTime = $this->remainingFuelTime; } diff --git a/src/block/tile/ItemFrame.php b/src/block/tile/ItemFrame.php index a3910046f5..32d55f2010 100644 --- a/src/block/tile/ItemFrame.php +++ b/src/block/tile/ItemFrame.php @@ -54,8 +54,8 @@ class ItemFrame extends Spawnable{ if(($itemTag = $nbt->getCompoundTag(self::TAG_ITEM)) !== null){ $this->item = Item::nbtDeserialize($itemTag); } - $this->itemRotation = $nbt->getByte(self::TAG_ITEM_ROTATION, $this->itemRotation, true); - $this->itemDropChance = $nbt->getFloat(self::TAG_ITEM_DROP_CHANCE, $this->itemDropChance, true); + $this->itemRotation = $nbt->getByte(self::TAG_ITEM_ROTATION, $this->itemRotation); + $this->itemDropChance = $nbt->getFloat(self::TAG_ITEM_DROP_CHANCE, $this->itemDropChance); } protected function writeSaveData(CompoundTag $nbt) : void{ diff --git a/src/block/tile/Skull.php b/src/block/tile/Skull.php index fe0fe062c2..13de524cf4 100644 --- a/src/block/tile/Skull.php +++ b/src/block/tile/Skull.php @@ -58,7 +58,7 @@ class Skull extends Spawnable{ //bad data, drop it } } - $rotation = $nbt->getByte(self::TAG_ROT, 0, true); + $rotation = $nbt->getByte(self::TAG_ROT, 0); if($rotation >= 0 and $rotation <= 15){ $this->skullRotation = $rotation; } diff --git a/src/block/tile/TileFactory.php b/src/block/tile/TileFactory.php index 130d99e56e..186b280688 100644 --- a/src/block/tile/TileFactory.php +++ b/src/block/tile/TileFactory.php @@ -167,7 +167,7 @@ final class TileFactory{ * @internal */ public static function createFromData(World $world, CompoundTag $nbt) : ?Tile{ - $type = $nbt->getString(Tile::TAG_ID, "", true); + $type = $nbt->getString(Tile::TAG_ID, ""); if(!isset(self::$knownTiles[$type])){ return null; } diff --git a/src/entity/Human.php b/src/entity/Human.php index 72c5f10e74..a3e1db0da6 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -248,15 +248,15 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $this->inventory->setHeldItemIndex($nbt->getInt("SelectedInventorySlot", 0), false); - $this->hungerManager->setFood((float) $nbt->getInt("foodLevel", (int) $this->hungerManager->getFood(), true)); - $this->hungerManager->setExhaustion($nbt->getFloat("foodExhaustionLevel", $this->hungerManager->getExhaustion(), true)); - $this->hungerManager->setSaturation($nbt->getFloat("foodSaturationLevel", $this->hungerManager->getSaturation(), true)); - $this->hungerManager->setFoodTickTimer($nbt->getInt("foodTickTimer", $this->hungerManager->getFoodTickTimer(), true)); + $this->hungerManager->setFood((float) $nbt->getInt("foodLevel", (int) $this->hungerManager->getFood())); + $this->hungerManager->setExhaustion($nbt->getFloat("foodExhaustionLevel", $this->hungerManager->getExhaustion())); + $this->hungerManager->setSaturation($nbt->getFloat("foodSaturationLevel", $this->hungerManager->getSaturation())); + $this->hungerManager->setFoodTickTimer($nbt->getInt("foodTickTimer", $this->hungerManager->getFoodTickTimer())); $this->xpManager->setXpAndProgressNoEvent( - $nbt->getInt("XpLevel", 0, true), - $nbt->getFloat("XpP", 0.0, true)); - $this->xpManager->setLifetimeTotalXp($nbt->getInt("XpTotal", 0, true)); + $nbt->getInt("XpLevel", 0), + $nbt->getFloat("XpP", 0.0)); + $this->xpManager->setLifetimeTotalXp($nbt->getInt("XpTotal", 0)); if($nbt->hasTag("XpSeed", IntTag::class)){ $this->xpSeed = $nbt->getInt("XpSeed"); diff --git a/src/entity/object/PrimedTNT.php b/src/entity/object/PrimedTNT.php index 505b22f555..e6d72c0399 100644 --- a/src/entity/object/PrimedTNT.php +++ b/src/entity/object/PrimedTNT.php @@ -60,7 +60,7 @@ class PrimedTNT extends Entity implements Explosive{ protected function initEntity(CompoundTag $nbt) : void{ parent::initEntity($nbt); - $this->fuse = $nbt->getShort("Fuse", 80, true); + $this->fuse = $nbt->getShort("Fuse", 80); $this->getWorld()->addSound($this->location, new IgniteSound()); } diff --git a/src/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php index 9a2bae08ce..b0ba0fa7e3 100644 --- a/src/entity/projectile/Arrow.php +++ b/src/entity/projectile/Arrow.php @@ -78,7 +78,7 @@ class Arrow extends Projectile{ protected function initEntity(CompoundTag $nbt) : void{ parent::initEntity($nbt); - $this->pickupMode = $nbt->getByte(self::TAG_PICKUP, self::PICKUP_ANY, true); + $this->pickupMode = $nbt->getByte(self::TAG_PICKUP, self::PICKUP_ANY); $this->collideTicks = $nbt->getShort("life", $this->collideTicks); } diff --git a/src/item/Item.php b/src/item/Item.php index bc4364ca38..fef054c6ce 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -273,7 +273,7 @@ class Item implements \JsonSerializable{ $display = $tag->getCompoundTag(self::TAG_DISPLAY); if($display !== null){ - $this->customName = $display->getString(self::TAG_DISPLAY_NAME, $this->customName, true); + $this->customName = $display->getString(self::TAG_DISPLAY_NAME, $this->customName); $lore = $display->getListTag(self::TAG_DISPLAY_LORE); if($lore !== null and $lore->getTagType() === NBT::TAG_String){ /** @var StringTag $t */ @@ -288,8 +288,8 @@ class Item implements \JsonSerializable{ if($enchantments !== null and $enchantments->getTagType() === NBT::TAG_Compound){ /** @var CompoundTag $enchantment */ foreach($enchantments as $enchantment){ - $magicNumber = $enchantment->getShort("id", -1, true); - $level = $enchantment->getShort("lvl", 0, true); + $magicNumber = $enchantment->getShort("id", -1); + $level = $enchantment->getShort("lvl", 0); if($level <= 0){ continue; } diff --git a/src/player/Player.php b/src/player/Player.php index d476925ba6..3a2e8fce14 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -267,7 +267,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $spawnReset = false; - if($namedtag !== null and ($world = $this->server->getWorldManager()->getWorldByName($namedtag->getString("Level", "", true))) !== null){ + if($namedtag !== null and ($world = $this->server->getWorldManager()->getWorldByName($namedtag->getString("Level", ""))) !== null){ /** @var float[] $pos */ $pos = $namedtag->getListTag("Pos")->getAllValues(); $spawn = new Vector3($pos[0], $pos[1], $pos[2]); diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index e6ada96ac9..82aa8bde26 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -33,6 +33,8 @@ use pocketmine\block\tile\TileFactory; use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\tag\IntTag; +use pocketmine\nbt\tag\StringTag; use pocketmine\player\Player; use pocketmine\world\World; use function array_fill; @@ -498,7 +500,14 @@ class Chunk{ try{ $entity = EntityFactory::createFromData($world, $nbt); if(!($entity instanceof Entity)){ - $world->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown entity type " . $nbt->getString("id", $nbt->getString("identifier", "", true), true)); + $saveIdTag = $nbt->getTag("id") ?? $nbt->getTag("identifier"); + $saveId = ""; + if($saveIdTag instanceof StringTag){ + $saveId = $saveIdTag->getValue(); + }elseif($saveIdTag instanceof IntTag){ //legacy MCPE format + $saveId = "legacy(" . $saveIdTag->getValue() . ")"; + } + $world->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown entity type $saveId"); continue; } }catch(\Exception $t){ //TODO: this shouldn't be here @@ -517,7 +526,7 @@ class Chunk{ if(($tile = TileFactory::createFromData($world, $nbt)) !== null){ $world->addTile($tile); }else{ - $world->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown tile entity type " . $nbt->getString("id", "", true)); + $world->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown tile entity type " . $nbt->getString("id", "")); continue; } } diff --git a/src/world/format/io/data/BaseNbtWorldData.php b/src/world/format/io/data/BaseNbtWorldData.php index 20074dc5ec..b1092130f1 100644 --- a/src/world/format/io/data/BaseNbtWorldData.php +++ b/src/world/format/io/data/BaseNbtWorldData.php @@ -25,6 +25,7 @@ namespace pocketmine\world\format\io\data; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\tag\IntTag; use pocketmine\world\format\io\exception\CorruptedWorldException; use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; use pocketmine\world\format\io\WorldData; @@ -124,11 +125,14 @@ abstract class BaseNbtWorldData implements WorldData{ } public function getTime() : int{ - return $this->compoundTag->getLong("Time", 0, true); + if($this->compoundTag->hasTag("Time", IntTag::class)){ //some older PM worlds had this in the wrong format + return $this->compoundTag->getInt("Time"); + } + return $this->compoundTag->getLong("Time", 0); } public function setTime(int $value) : void{ - $this->compoundTag->setLong("Time", $value, true); //some older PM worlds had this in the wrong format + $this->compoundTag->setLong("Time", $value); } public function getSpawn() : Vector3{ diff --git a/src/world/format/io/data/BedrockWorldData.php b/src/world/format/io/data/BedrockWorldData.php index 252513f760..5be66be8b9 100644 --- a/src/world/format/io/data/BedrockWorldData.php +++ b/src/world/format/io/data/BedrockWorldData.php @@ -122,7 +122,7 @@ class BedrockWorldData extends BaseNbtWorldData{ throw new CorruptedWorldException($e->getMessage(), 0, $e); } - $version = $worldData->getInt("StorageVersion", Limits::INT32_MAX, true); + $version = $worldData->getInt("StorageVersion", Limits::INT32_MAX); if($version > self::CURRENT_STORAGE_VERSION){ throw new UnsupportedWorldFormatException("LevelDB world format version $version is currently unsupported"); } diff --git a/src/world/format/io/data/JavaWorldData.php b/src/world/format/io/data/JavaWorldData.php index a51c5ce067..2b7f455980 100644 --- a/src/world/format/io/data/JavaWorldData.php +++ b/src/world/format/io/data/JavaWorldData.php @@ -90,7 +90,7 @@ class JavaWorldData extends BaseNbtWorldData{ protected function fix() : void{ if(!$this->compoundTag->hasTag("generatorName", StringTag::class)){ - $this->compoundTag->setString("generatorName", "default", true); + $this->compoundTag->setString("generatorName", "default"); }elseif(($generatorName = self::hackyFixForGeneratorClasspathInLevelDat($this->compoundTag->getString("generatorName"))) !== null){ $this->compoundTag->setString("generatorName", $generatorName); } diff --git a/src/world/format/io/region/LegacyAnvilChunkTrait.php b/src/world/format/io/region/LegacyAnvilChunkTrait.php index aacad403e6..204edff3be 100644 --- a/src/world/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/world/format/io/region/LegacyAnvilChunkTrait.php @@ -75,7 +75,7 @@ trait LegacyAnvilChunkTrait{ if($chunk->hasTag("BiomeColors", IntArrayTag::class)){ $biomeIds = ChunkUtils::convertBiomeColors($chunk->getIntArray("BiomeColors")); //Convert back to original format }else{ - $biomeIds = $chunk->getByteArray("Biomes", "", true); + $biomeIds = $chunk->getByteArray("Biomes", ""); } $result = new Chunk( From 12e4e928942baaa38690a3763ceac36736d3e289 Mon Sep 17 00:00:00 2001 From: DaPigGuy Date: Mon, 9 Mar 2020 06:52:15 -0700 Subject: [PATCH 1411/3224] Inventory: Pass old item(s) to inventory change listeners, closes #3323 (#3337) --- src/inventory/BaseInventory.php | 6 ++-- .../CallbackInventoryChangeListener.php | 28 +++++++++++-------- src/inventory/InventoryChangeListener.php | 9 ++++-- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/inventory/BaseInventory.php b/src/inventory/BaseInventory.php index 98419a01a2..bcfefe272f 100644 --- a/src/inventory/BaseInventory.php +++ b/src/inventory/BaseInventory.php @@ -90,6 +90,8 @@ abstract class BaseInventory implements Inventory{ $items = array_slice($items, 0, $this->getSize(), true); } + $oldContents = $this->slots->toArray(); + $listeners = $this->listeners; $this->listeners = []; $viewers = $this->viewers; @@ -109,7 +111,7 @@ abstract class BaseInventory implements Inventory{ } foreach($this->listeners as $listener){ - $listener->onContentChange($this); + $listener->onContentChange($this, $oldContents); } foreach($this->getViewers() as $viewer){ @@ -359,7 +361,7 @@ abstract class BaseInventory implements Inventory{ protected function onSlotChange(int $index, Item $before) : void{ foreach($this->listeners as $listener){ - $listener->onSlotChange($this, $index); + $listener->onSlotChange($this, $index, $before); } foreach($this->viewers as $viewer){ $viewer->getNetworkSession()->getInvManager()->syncSlot($this, $index); diff --git a/src/inventory/CallbackInventoryChangeListener.php b/src/inventory/CallbackInventoryChangeListener.php index 388b9bf1bb..c3b12a6d49 100644 --- a/src/inventory/CallbackInventoryChangeListener.php +++ b/src/inventory/CallbackInventoryChangeListener.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\inventory; +use pocketmine\item\Item; use pocketmine\utils\Utils; class CallbackInventoryChangeListener implements InventoryChangeListener{ @@ -31,25 +32,25 @@ class CallbackInventoryChangeListener implements InventoryChangeListener{ /** * @var \Closure|null - * @phpstan-var (\Closure(Inventory, int) : void)|null + * @phpstan-var (\Closure(Inventory, int, Item) : void)|null */ private $onSlotChangeCallback; /** * @var \Closure|null - * @phpstan-var (\Closure(Inventory) : void)|null + * @phpstan-var (\Closure(Inventory, Item[]) : void)|null */ private $onContentChangeCallback; /** - * @phpstan-param (\Closure(Inventory, int) : void)|null $onSlotChange - * @phpstan-param (\Closure(Inventory) : void)|null $onContentChange + * @phpstan-param (\Closure(Inventory, int, Item) : void)|null $onSlotChange + * @phpstan-param (\Closure(Inventory, Item[]) : void)|null $onContentChange */ public function __construct(?\Closure $onSlotChange, ?\Closure $onContentChange){ if($onSlotChange !== null){ - Utils::validateCallableSignature(function(Inventory $inventory, int $slot) : void{}, $onSlotChange); + Utils::validateCallableSignature(function(Inventory $inventory, int $slot, Item $oldItem) : void{}, $onSlotChange); } if($onContentChange !== null){ - Utils::validateCallableSignature(function(Inventory $inventory) : void{}, $onContentChange); + Utils::validateCallableSignature(function(Inventory $inventory, array $oldContents) : void{}, $onContentChange); } $this->onSlotChangeCallback = $onSlotChange; @@ -61,20 +62,23 @@ class CallbackInventoryChangeListener implements InventoryChangeListener{ */ public static function onAnyChange(\Closure $onChange) : self{ return new self( - static function(Inventory $inventory, int $unused) use ($onChange) : void{ + static function(Inventory $inventory, int $unused, Item $unusedB) use ($onChange) : void{ $onChange($inventory); }, - static function(Inventory $inventory) use ($onChange) : void{ + static function(Inventory $inventory, array $unused) use ($onChange) : void{ $onChange($inventory); } ); } - public function onSlotChange(Inventory $inventory, int $slot) : void{ - ($this->onSlotChangeCallback)($inventory, $slot); + public function onSlotChange(Inventory $inventory, int $slot, Item $oldItem) : void{ + ($this->onSlotChangeCallback)($inventory, $slot, $oldItem); } - public function onContentChange(Inventory $inventory) : void{ - ($this->onContentChangeCallback)($inventory); + /** + * @param Item[] $oldContents + */ + public function onContentChange(Inventory $inventory, array $oldContents) : void{ + ($this->onContentChangeCallback)($inventory, $oldContents); } } diff --git a/src/inventory/InventoryChangeListener.php b/src/inventory/InventoryChangeListener.php index d13edf7f08..60069305ef 100644 --- a/src/inventory/InventoryChangeListener.php +++ b/src/inventory/InventoryChangeListener.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\inventory; +use pocketmine\item\Item; + /** * Classes implementing this interface can be injected into inventories to receive notifications when content changes * occur. @@ -32,7 +34,10 @@ namespace pocketmine\inventory; */ interface InventoryChangeListener{ - public function onSlotChange(Inventory $inventory, int $slot) : void; + public function onSlotChange(Inventory $inventory, int $slot, Item $oldItem) : void; - public function onContentChange(Inventory $inventory) : void; + /** + * @param Item[] $oldContents + */ + public function onContentChange(Inventory $inventory, array $oldContents) : void; } From 899d05c6ece8b07fadb0eec593751713a6b1461f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 10 Mar 2020 13:06:16 +0000 Subject: [PATCH 1412/3224] DataPacket: strip some whitespace --- src/network/mcpe/protocol/DataPacket.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/protocol/DataPacket.php b/src/network/mcpe/protocol/DataPacket.php index 157c83b69f..f45b35d747 100644 --- a/src/network/mcpe/protocol/DataPacket.php +++ b/src/network/mcpe/protocol/DataPacket.php @@ -49,7 +49,7 @@ abstract class DataPacket implements Packet{ public $senderSubId = 0; /** @var int */ public $recipientSubId = 0; - + /** @var NetworkBinaryStream */ private $buf; From c9e859851079c3bc10b94be4dfa885340408f634 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 13 Mar 2020 15:19:32 +0000 Subject: [PATCH 1413/3224] InGamePacketHandler: do not handle inbound ActorEvents that are not for self --- src/network/mcpe/handler/InGamePacketHandler.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 045e48bc39..165a3250db 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -149,6 +149,10 @@ class InGamePacketHandler extends PacketHandler{ } public function handleActorEvent(ActorEventPacket $packet) : bool{ + if($packet->entityRuntimeId !== $this->player->getId()){ + //TODO HACK: EATING_ITEM is sent back to the server when the server sends it for other players (1.14 bug, maybe earlier) + return $packet->event === ActorEventPacket::EATING_ITEM; + } $this->player->doCloseInventory(); switch($packet->event){ From 093a7c239ee61c72314d281ef2592f63146ee726 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 14 Mar 2020 14:24:50 +0000 Subject: [PATCH 1414/3224] CraftingDataPacket: fix variable name collision --- src/network/mcpe/protocol/CraftingDataPacket.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/network/mcpe/protocol/CraftingDataPacket.php b/src/network/mcpe/protocol/CraftingDataPacket.php index e6a7cce039..cd068fedd2 100644 --- a/src/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/network/mcpe/protocol/CraftingDataPacket.php @@ -81,8 +81,8 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{ /** @var Item */ $entry["input"] = []; for($j = 0; $j < $ingredientCount; ++$j){ - $entry["input"][] = $in = $in->getRecipeIngredient(); - $in->setCount(1); //TODO HACK: they send a useless count field which breaks the PM crafting system because it isn't always 1 + $entry["input"][] = $input = $in->getRecipeIngredient(); + $input->setCount(1); //TODO HACK: they send a useless count field which breaks the PM crafting system because it isn't always 1 } $resultCount = $in->getUnsignedVarInt(); $entry["output"] = []; @@ -102,8 +102,8 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{ $count = $entry["width"] * $entry["height"]; $entry["input"] = []; for($j = 0; $j < $count; ++$j){ - $entry["input"][] = $in = $in->getRecipeIngredient(); - $in->setCount(1); //TODO HACK: they send a useless count field which breaks the PM crafting system + $entry["input"][] = $input = $in->getRecipeIngredient(); + $input->setCount(1); //TODO HACK: they send a useless count field which breaks the PM crafting system } $resultCount = $in->getUnsignedVarInt(); $entry["output"] = []; From d930abce2dd4551273fe8776e0690cfc424bee3d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 17 Mar 2020 21:16:43 +0000 Subject: [PATCH 1415/3224] ChunkSerializer: improve palette writing performance with one weird trick this optimization relies on the fact that palette entries are always unsigned, and positive zigzag varints are just the same as their non-zigzag counterparts, except shifted left by 1 bit. This eliminates some function call overhead, making the encoding slightly less agonizingly slow. --- src/network/mcpe/serializer/ChunkSerializer.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index e1e010d653..2b1643ac0f 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -63,9 +63,13 @@ final class ChunkSerializer{ $stream->putByte(($blocks->getBitsPerBlock() << 1) | 1); //last 1-bit means "network format", but seems pointless $stream->put($blocks->getWordArray()); $palette = $blocks->getPalette(); - $stream->putVarInt(count($palette)); //yes, this is intentionally zigzag + + //these LSHIFT by 1 uvarints are optimizations: the client expects zigzag varints here + //but since we know they are always unsigned, we can avoid the extra fcall overhead of + //zigzag and just shift directly. + $stream->putUnsignedVarInt(count($palette) << 1); //yes, this is intentionally zigzag foreach($palette as $p){ - $stream->putVarInt(RuntimeBlockMapping::toStaticRuntimeId($p >> 4, $p & 0xf)); + $stream->putUnsignedVarInt(RuntimeBlockMapping::toStaticRuntimeId($p >> 4, $p & 0xf) << 1); } } } From 2d46ae44764fb06b224fe371771040846a4ed837 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 23 Mar 2020 21:27:08 +0000 Subject: [PATCH 1416/3224] Added BadPacketException::wrap() --- src/network/BadPacketException.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/network/BadPacketException.php b/src/network/BadPacketException.php index 179110a65c..ae573c953d 100644 --- a/src/network/BadPacketException.php +++ b/src/network/BadPacketException.php @@ -25,4 +25,7 @@ namespace pocketmine\network; class BadPacketException extends \RuntimeException{ + public static function wrap(\Throwable $previous, ?string $prefix = null) : self{ + return new self(($prefix !== null ? $prefix . ": " : "") . $previous->getMessage(), 0, $previous); + } } From 3e5d3a646b9fa8d2a31eabd5f9f22357f0aa603b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 23 Mar 2020 21:28:38 +0000 Subject: [PATCH 1417/3224] Make use of BadPacketException::wrap() --- src/network/mcpe/NetworkSession.php | 8 ++++---- src/network/mcpe/handler/InGamePacketHandler.php | 6 +++--- src/network/mcpe/protocol/AddActorPacket.php | 2 +- src/network/mcpe/protocol/CraftingDataPacket.php | 2 +- src/network/mcpe/protocol/DataPacket.php | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 0925f12493..205dd01ad4 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -271,7 +271,7 @@ class NetworkSession{ $payload = $this->cipher->decrypt($payload); }catch(\UnexpectedValueException $e){ $this->logger->debug("Encrypted packet: " . base64_encode($payload)); - throw new BadPacketException("Packet decryption error: " . $e->getMessage(), 0, $e); + throw BadPacketException::wrap($e, "Packet decryption error"); }finally{ Timings::$playerNetworkReceiveDecryptTimer->stopTiming(); } @@ -283,7 +283,7 @@ class NetworkSession{ }catch(\ErrorException $e){ $this->logger->debug("Failed to decompress packet: " . base64_encode($payload)); //TODO: this isn't incompatible game version if we already established protocol version - throw new BadPacketException("Compressed packet batch decode error: " . $e->getMessage(), 0, $e); + throw BadPacketException::wrap($e, "Compressed packet batch decode error"); }finally{ Timings::$playerNetworkReceiveDecompressTimer->stopTiming(); } @@ -297,14 +297,14 @@ class NetworkSession{ $pk = $stream->getPacket(); }catch(BinaryDataException $e){ $this->logger->debug("Packet batch: " . base64_encode($stream->getBuffer())); - throw new BadPacketException("Packet batch decode error: " . $e->getMessage(), 0, $e); + throw BadPacketException::wrap($e, "Packet batch decode error"); } try{ $this->handleDataPacket($pk); }catch(BadPacketException $e){ $this->logger->debug($pk->getName() . ": " . base64_encode($pk->getBinaryStream()->getBuffer())); - throw new BadPacketException("Error processing " . $pk->getName() . ": " . $e->getMessage(), 0, $e); + throw BadPacketException::wrap($e, "Error processing " . $pk->getName()); } } } diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 165a3250db..b04e97ce10 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -544,7 +544,7 @@ class InGamePacketHandler extends PacketHandler{ $offset = 0; $nbt = (new NetworkNbtSerializer())->read($packet->namedtag, $offset, 512)->mustGetCompoundTag(); }catch(NbtDataException $e){ - throw new BadPacketException($e->getMessage(), 0, $e); + throw BadPacketException::wrap($e); } if($block instanceof Sign){ @@ -552,7 +552,7 @@ class InGamePacketHandler extends PacketHandler{ try{ $text = SignText::fromBlob($nbt->getString("Text")); }catch(\InvalidArgumentException $e){ - throw new BadPacketException("Invalid sign text update: " . $e->getMessage(), 0, $e); + throw BadPacketException::wrap($e, "Invalid sign text update"); } try{ @@ -560,7 +560,7 @@ class InGamePacketHandler extends PacketHandler{ $this->player->getWorld()->sendBlocks([$this->player], [$pos]); } }catch(\UnexpectedValueException $e){ - throw new BadPacketException($e->getMessage(), 0, $e); + throw BadPacketException::wrap($e); } return true; diff --git a/src/network/mcpe/protocol/AddActorPacket.php b/src/network/mcpe/protocol/AddActorPacket.php index 7a78010d88..815b1743a7 100644 --- a/src/network/mcpe/protocol/AddActorPacket.php +++ b/src/network/mcpe/protocol/AddActorPacket.php @@ -198,7 +198,7 @@ class AddActorPacket extends DataPacket implements ClientboundPacket{ $attr->setMaxValue($max); $attr->setValue($current); }catch(\InvalidArgumentException $e){ - throw new BadPacketException($e->getMessage(), 0, $e); //TODO: address this properly + throw BadPacketException::wrap($e); //TODO: address this properly } $this->attributes[] = $attr; }else{ diff --git a/src/network/mcpe/protocol/CraftingDataPacket.php b/src/network/mcpe/protocol/CraftingDataPacket.php index cd068fedd2..af504e8eda 100644 --- a/src/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/network/mcpe/protocol/CraftingDataPacket.php @@ -128,7 +128,7 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{ try{ $entry["input"] = ItemFactory::get($inputId, $inputData); }catch(\InvalidArgumentException $e){ - throw new BadPacketException($e->getMessage(), 0, $e); + throw BadPacketException::wrap($e); } $entry["output"] = $out = $in->getSlot(); if($out->getMeta() === 0x7fff){ diff --git a/src/network/mcpe/protocol/DataPacket.php b/src/network/mcpe/protocol/DataPacket.php index f45b35d747..0d5601cc07 100644 --- a/src/network/mcpe/protocol/DataPacket.php +++ b/src/network/mcpe/protocol/DataPacket.php @@ -82,7 +82,7 @@ abstract class DataPacket implements Packet{ $this->decodeHeader($this->buf); $this->decodePayload($this->buf); }catch(BinaryDataException | BadPacketException $e){ - throw new BadPacketException($this->getName() . ": " . $e->getMessage(), 0, $e); + throw BadPacketException::wrap($e, $this->getName()); } } From 83a3adecffef6a854682e9a956a7271f7bf6dd7b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 23 Mar 2020 21:58:12 +0000 Subject: [PATCH 1418/3224] LoginPacket: use netresearch/jsonmapper for login data decoding this makes retrieval static analysis friendly without extra steps. --- composer.json | 3 +- composer.lock | 48 +++- phpstan.neon.dist | 1 + src/network/mcpe/auth/ProcessLoginTask.php | 2 +- .../mcpe/handler/LoginPacketHandler.php | 45 ++-- src/network/mcpe/protocol/LoginPacket.php | 154 +++--------- .../types/login/AuthenticationData.php | 51 ++++ .../mcpe/protocol/types/login/ClientData.php | 219 ++++++++++++++++++ .../types/login/ClientDataAnimationFrame.php | 60 +++++ .../mcpe/protocol/types/login/JwtChain.php | 36 +++ tests/phpstan/stubs/JsonMapper.stub | 19 ++ 11 files changed, 495 insertions(+), 143 deletions(-) create mode 100644 src/network/mcpe/protocol/types/login/AuthenticationData.php create mode 100644 src/network/mcpe/protocol/types/login/ClientData.php create mode 100644 src/network/mcpe/protocol/types/login/ClientDataAnimationFrame.php create mode 100644 src/network/mcpe/protocol/types/login/JwtChain.php create mode 100644 tests/phpstan/stubs/JsonMapper.stub diff --git a/composer.json b/composer.json index 01fa850816..f6727a6b13 100644 --- a/composer.json +++ b/composer.json @@ -41,7 +41,8 @@ "pocketmine/classloader": "dev-master", "pocketmine/callback-validator": "^1.0.1", "adhocore/json-comment": "^0.1.0", - "particle/validator": "^2.3" + "particle/validator": "^2.3", + "netresearch/jsonmapper": "^2.0" }, "require-dev": { "phpstan/phpstan": "^0.12.14", diff --git a/composer.lock b/composer.lock index bb7a5cc77f..5eb5a25915 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b59b043a71525b45752770b4fd1ce2cb", + "content-hash": "8a94ad4a1822c04cb884a6dee81923df", "packages": [ { "name": "adhocore/json-comment", @@ -191,6 +191,52 @@ ], "time": "2018-12-03T18:17:01+00:00" }, + { + "name": "netresearch/jsonmapper", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/cweiske/jsonmapper.git", + "reference": "e245890383c3ed38b6d202ee373c23ccfebc0f54" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/e245890383c3ed38b6d202ee373c23ccfebc0f54", + "reference": "e245890383c3ed38b6d202ee373c23ccfebc0f54", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "~4.8.35 || ~5.7 || ~6.4 || ~7.0", + "squizlabs/php_codesniffer": "~3.5" + }, + "type": "library", + "autoload": { + "psr-0": { + "JsonMapper": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OSL-3.0" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@cweiske.de", + "homepage": "http://github.com/cweiske/jsonmapper/", + "role": "Developer" + } + ], + "description": "Map nested JSON structures onto PHP classes", + "time": "2020-03-04T17:23:33+00:00" + }, { "name": "particle/validator", "version": "v2.3.4", diff --git a/phpstan.neon.dist b/phpstan.neon.dist index c756ebabec..c19818e44c 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -33,6 +33,7 @@ parameters: - pocketmine\IS_DEVELOPMENT_BUILD - pocketmine\DEBUG stubFiles: + - tests/phpstan/stubs/JsonMapper.stub - tests/phpstan/stubs/pthreads.stub reportUnmatchedIgnoredErrors: false #no other way to silence platform-specific non-warnings ignoreErrors: diff --git a/src/network/mcpe/auth/ProcessLoginTask.php b/src/network/mcpe/auth/ProcessLoginTask.php index dcc90d5b2a..cadd54c047 100644 --- a/src/network/mcpe/auth/ProcessLoginTask.php +++ b/src/network/mcpe/auth/ProcessLoginTask.php @@ -95,7 +95,7 @@ class ProcessLoginTask extends AsyncTask{ $currentKey = null; $first = true; - foreach($packet->chainDataJwt as $jwt){ + foreach($packet->chainDataJwt->chain as $jwt){ $this->validateToken($jwt, $currentKey, $first); if($first){ $first = false; diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index c76935dbda..c4f215e577 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -68,38 +68,39 @@ class LoginPacketHandler extends PacketHandler{ return true; } - if(!Player::isValidUserName($packet->extraData[LoginPacket::I_USERNAME])){ + if(!Player::isValidUserName($packet->extraData->displayName)){ $this->session->disconnect("disconnectionScreen.invalidName"); return true; } try{ + $clientData = $packet->clientData; //this serves no purpose except readability /** @var SkinAnimation[] $animations */ $animations = []; - foreach($packet->clientData[LoginPacket::I_ANIMATION_IMAGES] as $animation){ + foreach($clientData->AnimatedImageData as $animation){ $animations[] = new SkinAnimation( new SkinImage( - $animation[LoginPacket::I_ANIMATION_IMAGE_HEIGHT], - $animation[LoginPacket::I_ANIMATION_IMAGE_WIDTH], - base64_decode($animation[LoginPacket::I_ANIMATION_IMAGE_DATA], true) + $animation->ImageHeight, + $animation->ImageWidth, + base64_decode($animation->Image, true) ), - $animation[LoginPacket::I_ANIMATION_IMAGE_TYPE], - $animation[LoginPacket::I_ANIMATION_IMAGE_FRAMES] + $animation->Type, + $animation->Frames ); } $skinData = new SkinData( - $packet->clientData[LoginPacket::I_SKIN_ID], - base64_decode($packet->clientData[LoginPacket::I_SKIN_RESOURCE_PATCH], true), - new SkinImage($packet->clientData[LoginPacket::I_SKIN_HEIGHT], $packet->clientData[LoginPacket::I_SKIN_WIDTH], base64_decode($packet->clientData[LoginPacket::I_SKIN_DATA], true)), + $clientData->SkinId, + base64_decode($clientData->SkinResourcePatch, true), + new SkinImage($clientData->SkinImageHeight, $clientData->SkinImageWidth, base64_decode($clientData->SkinData, true)), $animations, - new SkinImage($packet->clientData[LoginPacket::I_CAPE_HEIGHT], $packet->clientData[LoginPacket::I_CAPE_WIDTH], base64_decode($packet->clientData[LoginPacket::I_CAPE_DATA], true)), - base64_decode($packet->clientData[LoginPacket::I_GEOMETRY_DATA], true), - base64_decode($packet->clientData[LoginPacket::I_ANIMATION_DATA], true), - $packet->clientData[LoginPacket::I_PREMIUM_SKIN], - $packet->clientData[LoginPacket::I_PERSONA_SKIN], - $packet->clientData[LoginPacket::I_PERSONA_CAPE_ON_CLASSIC_SKIN], - $packet->clientData[LoginPacket::I_CAPE_ID] + new SkinImage($clientData->CapeImageHeight, $clientData->CapeImageWidth, base64_decode($clientData->CapeData, true)), + base64_decode($clientData->SkinGeometryData, true), + base64_decode($clientData->SkinAnimationData, true), + $clientData->PremiumSkin, + $clientData->PersonaSkin, + $clientData->CapeOnClassicSkin, + $clientData->CapeId ); $skin = SkinAdapterSingleton::get()->fromSkinData($skinData); @@ -111,12 +112,12 @@ class LoginPacketHandler extends PacketHandler{ } $this->session->setPlayerInfo(new PlayerInfo( - $packet->extraData[LoginPacket::I_USERNAME], - UUID::fromString($packet->extraData[LoginPacket::I_UUID]), + $packet->extraData->displayName, + UUID::fromString($packet->extraData->identity), $skin, - $packet->clientData[LoginPacket::I_LANGUAGE_CODE], - $packet->extraData[LoginPacket::I_XUID], - $packet->clientData + $packet->clientData->LanguageCode, + $packet->extraData->XUID, + (array) $packet->clientData )); $ev = new PlayerPreLoginEvent( diff --git a/src/network/mcpe/protocol/LoginPacket.php b/src/network/mcpe/protocol/LoginPacket.php index af33b46f60..f2bc7c23e6 100644 --- a/src/network/mcpe/protocol/LoginPacket.php +++ b/src/network/mcpe/protocol/LoginPacket.php @@ -25,77 +25,34 @@ namespace pocketmine\network\mcpe\protocol; #include -use Particle\Validator\Validator; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\protocol\types\login\AuthenticationData; +use pocketmine\network\mcpe\protocol\types\login\ClientData; +use pocketmine\network\mcpe\protocol\types\login\JwtChain; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; use pocketmine\utils\Utils; -use function array_filter; -use function count; -use function implode; use function is_array; use function json_decode; -use function json_last_error_msg; class LoginPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::LOGIN_PACKET; public const EDITION_POCKET = 0; - public const I_USERNAME = 'displayName'; - public const I_UUID = 'identity'; - public const I_XUID = 'XUID'; - - public const I_CLIENT_RANDOM_ID = 'ClientRandomId'; - public const I_SERVER_ADDRESS = 'ServerAddress'; - public const I_LANGUAGE_CODE = 'LanguageCode'; - - public const I_SKIN_RESOURCE_PATCH = 'SkinResourcePatch'; - - public const I_SKIN_ID = 'SkinId'; - public const I_SKIN_HEIGHT = 'SkinImageHeight'; - public const I_SKIN_WIDTH = 'SkinImageWidth'; - public const I_SKIN_DATA = 'SkinData'; - - public const I_CAPE_ID = 'CapeId'; - public const I_CAPE_HEIGHT = 'CapeImageHeight'; - public const I_CAPE_WIDTH = 'CapeImageWidth'; - public const I_CAPE_DATA = 'CapeData'; - - public const I_GEOMETRY_DATA = 'SkinGeometryData'; - - public const I_ANIMATION_DATA = 'SkinAnimationData'; - public const I_ANIMATION_IMAGES = 'AnimatedImageData'; - - public const I_ANIMATION_IMAGE_HEIGHT = 'ImageHeight'; - public const I_ANIMATION_IMAGE_WIDTH = 'ImageWidth'; - public const I_ANIMATION_IMAGE_FRAMES = 'Frames'; - public const I_ANIMATION_IMAGE_TYPE = 'Type'; - public const I_ANIMATION_IMAGE_DATA = 'Image'; - - public const I_PREMIUM_SKIN = 'PremiumSkin'; - public const I_PERSONA_SKIN = 'PersonaSkin'; - public const I_PERSONA_CAPE_ON_CLASSIC_SKIN = 'CapeOnClassicSkin'; - /** @var int */ public $protocol; - /** @var string[] array of encoded JWT */ - public $chainDataJwt = []; - /** - * @var mixed[]|null extraData index of whichever JWT has it - * @phpstan-var array - */ + /** @var JwtChain */ + public $chainDataJwt; + /** @var AuthenticationData|null extraData index of whichever JWT has it */ public $extraData = null; /** @var string */ public $clientDataJwt; - /** - * @var mixed[] decoded payload of the clientData JWT - * @phpstan-var array - */ - public $clientData = []; + /** @var ClientData decoded payload of the clientData JWT */ + public $clientData; /** * This field may be used by plugins to bypass keychain verification. It should only be used for plugins such as @@ -114,22 +71,6 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ $this->decodeConnectionRequest($in); } - /** - * @param mixed $data - * - * @throws BadPacketException - */ - private static function validate(Validator $v, string $name, $data) : void{ - $result = $v->validate($data); - if($result->isNotValid()){ - $messages = []; - foreach($result->getFailures() as $f){ - $messages[] = $f->format(); - } - throw new BadPacketException("Failed to validate '$name': " . implode(", ", $messages)); - } - } - /** * @throws BadPacketException * @throws BinaryDataException @@ -137,19 +78,19 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ protected function decodeConnectionRequest(NetworkBinaryStream $in) : void{ $buffer = new BinaryStream($in->getString()); - $chainData = json_decode($buffer->get($buffer->getLInt()), true); - if(!is_array($chainData)){ - throw new BadPacketException("Failed to decode chainData JSON: " . json_last_error_msg()); + $chainDataJson = json_decode($buffer->get($buffer->getLInt())); + $mapper = new \JsonMapper; + $mapper->bExceptionOnMissingData = true; + $mapper->bExceptionOnUndefinedProperty = true; + try{ + $chainData = $mapper->map($chainDataJson, new JwtChain); + }catch(\JsonMapper_Exception $e){ + throw BadPacketException::wrap($e); } - $vd = new Validator(); - $vd->required('chain')->isArray()->callback(function(array $data) : bool{ - return count($data) <= 3 and count(array_filter($data, '\is_string')) === count($data); - }); - self::validate($vd, "chainData", $chainData); + $this->chainDataJwt = $chainData; - $this->chainDataJwt = $chainData['chain']; - foreach($this->chainDataJwt as $k => $chain){ + foreach($this->chainDataJwt->chain as $k => $chain){ //validate every chain element try{ $claims = Utils::getJwtClaims($chain); @@ -164,13 +105,15 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ throw new BadPacketException("Found 'extraData' more than once in chainData"); } - $extraV = new Validator(); - $extraV->required(self::I_USERNAME)->string(); - $extraV->required(self::I_UUID)->uuid(); - $extraV->required(self::I_XUID)->string()->digits()->allowEmpty(true); - self::validate($extraV, "chain.$k.extraData", $claims['extraData']); - - $this->extraData = $claims['extraData']; + $mapper = new \JsonMapper; + $mapper->bEnforceMapType = false; //TODO: we don't really need this as an array, but right now we don't have enough models + $mapper->bExceptionOnMissingData = true; + $mapper->bExceptionOnUndefinedProperty = true; + try{ + $this->extraData = $mapper->map($claims['extraData'], new AuthenticationData); + }catch(\JsonMapper_Exception $e){ + throw BadPacketException::wrap($e); + } } } if($this->extraData === null){ @@ -184,40 +127,15 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ throw new BadPacketException($e->getMessage(), 0, $e); } - $v = new Validator(); - $v->required(self::I_CLIENT_RANDOM_ID)->integer(); - $v->required(self::I_SERVER_ADDRESS)->string(); - $v->required(self::I_LANGUAGE_CODE)->string(); - - $v->required(self::I_SKIN_RESOURCE_PATCH)->string(); - - $v->required(self::I_SKIN_ID)->string(); - $v->required(self::I_SKIN_DATA)->string(); - $v->required(self::I_SKIN_HEIGHT)->integer(true); - $v->required(self::I_SKIN_WIDTH)->integer(true); - - $v->required(self::I_CAPE_ID, null, true)->string(); - $v->required(self::I_CAPE_DATA, null, true)->string(); - $v->required(self::I_CAPE_HEIGHT)->integer(true); - $v->required(self::I_CAPE_WIDTH)->integer(true); - - $v->required(self::I_GEOMETRY_DATA, null, true)->string(); - - $v->required(self::I_ANIMATION_DATA, null, true)->string(); - $v->required(self::I_ANIMATION_IMAGES, null, true)->isArray()->each(function(Validator $vSub) : void{ - $vSub->required(self::I_ANIMATION_IMAGE_HEIGHT)->integer(true); - $vSub->required(self::I_ANIMATION_IMAGE_WIDTH)->integer(true); - $vSub->required(self::I_ANIMATION_IMAGE_FRAMES)->numeric(); //float() doesn't accept ints ??? - $vSub->required(self::I_ANIMATION_IMAGE_TYPE)->integer(true); - $vSub->required(self::I_ANIMATION_IMAGE_DATA)->string(); - }); - $v->required(self::I_PREMIUM_SKIN)->bool(); - $v->required(self::I_PERSONA_SKIN)->bool(); - $v->required(self::I_PERSONA_CAPE_ON_CLASSIC_SKIN)->bool(); - - self::validate($v, 'clientData', $clientData); - - $this->clientData = $clientData; + $mapper = new \JsonMapper; + $mapper->bEnforceMapType = false; //TODO: we don't really need this as an array, but right now we don't have enough models + $mapper->bExceptionOnMissingData = true; + $mapper->bExceptionOnUndefinedProperty = true; + try{ + $this->clientData = $mapper->map($clientData, new ClientData); + }catch(\JsonMapper_Exception $e){ + throw BadPacketException::wrap($e); + } } protected function encodePayload(NetworkBinaryStream $out) : void{ diff --git a/src/network/mcpe/protocol/types/login/AuthenticationData.php b/src/network/mcpe/protocol/types/login/AuthenticationData.php new file mode 100644 index 0000000000..6e48143d25 --- /dev/null +++ b/src/network/mcpe/protocol/types/login/AuthenticationData.php @@ -0,0 +1,51 @@ + Date: Tue, 24 Mar 2020 00:43:23 +0000 Subject: [PATCH 1419/3224] Airgap Attribute, fix decoding of non-registered attributes for protocol debugging --- src/entity/Entity.php | 6 +- src/network/mcpe/NetworkSession.php | 6 +- src/network/mcpe/protocol/AddActorPacket.php | 24 ++----- .../mcpe/protocol/UpdateAttributesPacket.php | 2 +- .../mcpe/protocol/types/entity/Attribute.php | 65 +++++++++++++++++++ .../mcpe/serializer/NetworkBinaryStream.php | 22 ++----- 6 files changed, 87 insertions(+), 38 deletions(-) create mode 100644 src/network/mcpe/protocol/types/entity/Attribute.php diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 23faa65141..8affc11b0d 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -50,6 +50,7 @@ use pocketmine\network\mcpe\protocol\MoveActorAbsolutePacket; use pocketmine\network\mcpe\protocol\RemoveActorPacket; use pocketmine\network\mcpe\protocol\SetActorDataPacket; use pocketmine\network\mcpe\protocol\SetActorMotionPacket; +use pocketmine\network\mcpe\protocol\types\entity\Attribute as NetworkAttribute; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; @@ -62,6 +63,7 @@ use pocketmine\world\format\Chunk; use pocketmine\world\Position; use pocketmine\world\World; use function abs; +use function array_map; use function assert; use function cos; use function count; @@ -1518,7 +1520,9 @@ abstract class Entity{ $pk->yaw = $this->location->yaw; $pk->headYaw = $this->location->yaw; //TODO $pk->pitch = $this->location->pitch; - $pk->attributes = $this->attributeMap->getAll(); + $pk->attributes = array_map(function(Attribute $attr) : NetworkAttribute{ + return new NetworkAttribute($attr->getId(), $attr->getMinValue(), $attr->getMaxValue(), $attr->getValue(), $attr->getDefaultValue()); + }, $this->attributeMap->getAll()); $pk->metadata = $this->getSyncedNetworkData(false); $player->getNetworkSession()->sendDataPacket($pk); diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 205dd01ad4..6da5497c01 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; +use pocketmine\entity\Attribute; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\Human; use pocketmine\entity\Living; @@ -70,6 +71,7 @@ use pocketmine\network\mcpe\protocol\TransferPacket; use pocketmine\network\mcpe\protocol\types\command\CommandData; use pocketmine\network\mcpe\protocol\types\command\CommandEnum; use pocketmine\network\mcpe\protocol\types\command\CommandParameter; +use pocketmine\network\mcpe\protocol\types\entity\Attribute as NetworkAttribute; use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; @@ -658,7 +660,9 @@ class NetworkSession{ public function syncAttributes(Living $entity, bool $sendAll = false) : void{ $entries = $sendAll ? $entity->getAttributeMap()->getAll() : $entity->getAttributeMap()->needSend(); if(count($entries) > 0){ - $this->sendDataPacket(UpdateAttributesPacket::create($entity->getId(), $entries)); + $this->sendDataPacket(UpdateAttributesPacket::create($entity->getId(), array_map(function(Attribute $attr) : NetworkAttribute{ + return new NetworkAttribute($attr->getId(), $attr->getMinValue(), $attr->getMaxValue(), $attr->getValue(), $attr->getDefaultValue()); + }, $entries))); foreach($entries as $entry){ $entry->markSynchronized(); } diff --git a/src/network/mcpe/protocol/AddActorPacket.php b/src/network/mcpe/protocol/AddActorPacket.php index 815b1743a7..47c3f18f90 100644 --- a/src/network/mcpe/protocol/AddActorPacket.php +++ b/src/network/mcpe/protocol/AddActorPacket.php @@ -25,10 +25,9 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\entity\Attribute; use pocketmine\math\Vector3; -use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\protocol\types\entity\Attribute; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; @@ -190,20 +189,7 @@ class AddActorPacket extends DataPacket implements ClientboundPacket{ $min = $in->getLFloat(); $current = $in->getLFloat(); $max = $in->getLFloat(); - $attr = Attribute::get($id); - - if($attr !== null){ - try{ - $attr->setMinValue($min); - $attr->setMaxValue($max); - $attr->setValue($current); - }catch(\InvalidArgumentException $e){ - throw BadPacketException::wrap($e); //TODO: address this properly - } - $this->attributes[] = $attr; - }else{ - throw new BadPacketException("Unknown attribute type \"$id\""); - } + $this->attributes[] = new Attribute($id, $min, $max, $current, $current); } $this->metadata = $in->getEntityMetadata(); @@ -226,9 +212,9 @@ class AddActorPacket extends DataPacket implements ClientboundPacket{ $out->putUnsignedVarInt(count($this->attributes)); foreach($this->attributes as $attribute){ $out->putString($attribute->getId()); - $out->putLFloat($attribute->getMinValue()); - $out->putLFloat($attribute->getValue()); - $out->putLFloat($attribute->getMaxValue()); + $out->putLFloat($attribute->getMin()); + $out->putLFloat($attribute->getCurrent()); + $out->putLFloat($attribute->getMax()); } $out->putEntityMetadata($this->metadata); diff --git a/src/network/mcpe/protocol/UpdateAttributesPacket.php b/src/network/mcpe/protocol/UpdateAttributesPacket.php index 65c25dd120..347a1552cc 100644 --- a/src/network/mcpe/protocol/UpdateAttributesPacket.php +++ b/src/network/mcpe/protocol/UpdateAttributesPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\entity\Attribute; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\protocol\types\entity\Attribute; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function array_values; diff --git a/src/network/mcpe/protocol/types/entity/Attribute.php b/src/network/mcpe/protocol/types/entity/Attribute.php new file mode 100644 index 0000000000..84deb8c600 --- /dev/null +++ b/src/network/mcpe/protocol/types/entity/Attribute.php @@ -0,0 +1,65 @@ +id = $id; + $this->min = $min; + $this->max = $max; + $this->current = $current; + $this->default = $default; + } + + public function getId() : string{ + return $this->id; + } + + public function getMin() : float{ + return $this->min; + } + + public function getMax() : float{ + return $this->max; + } + + public function getCurrent() : float{ + return $this->current; + } + + public function getDefault() : float{ + return $this->default; + } +} diff --git a/src/network/mcpe/serializer/NetworkBinaryStream.php b/src/network/mcpe/serializer/NetworkBinaryStream.php index ebc0d9cab0..9b0fdc6f7a 100644 --- a/src/network/mcpe/serializer/NetworkBinaryStream.php +++ b/src/network/mcpe/serializer/NetworkBinaryStream.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\serializer; #include -use pocketmine\entity\Attribute; use pocketmine\item\Durable; use pocketmine\item\Item; use pocketmine\item\ItemFactory; @@ -37,6 +36,7 @@ use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\TreeRoot; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; +use pocketmine\network\mcpe\protocol\types\entity\Attribute; use pocketmine\network\mcpe\protocol\types\entity\BlockPosMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\ByteMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\CompoundTagMetadataProperty; @@ -362,17 +362,7 @@ class NetworkBinaryStream extends BinaryStream{ $default = $this->getLFloat(); $id = $this->getString(); - $attr = Attribute::get($id); - if($attr !== null){ - $attr->setMinValue($min); - $attr->setMaxValue($max); - $attr->setValue($current); - $attr->setDefaultValue($default); - - $list[] = $attr; - }else{ - throw new BadPacketException("Unknown attribute type \"$id\""); - } + $list[] = new Attribute($id, $min, $max, $current, $default); } return $list; @@ -386,10 +376,10 @@ class NetworkBinaryStream extends BinaryStream{ public function putAttributeList(Attribute ...$attributes) : void{ $this->putUnsignedVarInt(count($attributes)); foreach($attributes as $attribute){ - $this->putLFloat($attribute->getMinValue()); - $this->putLFloat($attribute->getMaxValue()); - $this->putLFloat($attribute->getValue()); - $this->putLFloat($attribute->getDefaultValue()); + $this->putLFloat($attribute->getMin()); + $this->putLFloat($attribute->getMax()); + $this->putLFloat($attribute->getCurrent()); + $this->putLFloat($attribute->getDefault()); $this->putString($attribute->getId()); } } From 0691a402045d2ba1c3ebe6c755a1e3019709fbad Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 24 Mar 2020 11:06:58 +0000 Subject: [PATCH 1420/3224] UpdateBlockPropertiesPacket: expose nbt field --- src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php b/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php index 838a7a4ef1..9d972aea3e 100644 --- a/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php +++ b/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php @@ -43,6 +43,10 @@ class UpdateBlockPropertiesPacket extends DataPacket implements ClientboundPacke return $result; } + public function getNbt() : string{ + return $this->nbt; + } + protected function decodePayload(NetworkBinaryStream $in) : void{ $this->nbt = $in->getRemaining(); } From 2e75594c3438ca971ab85b69d2c08bd8dceba6df Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 28 Mar 2020 13:28:12 +0000 Subject: [PATCH 1421/3224] updated RakLib dependency --- composer.lock | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/composer.lock b/composer.lock index e39e70df02..597001ca09 100644 --- a/composer.lock +++ b/composer.lock @@ -529,12 +529,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "8d7e27ca17dda204fbefa084efbbba9e9681cadd" + "reference": "48c67e3325bc222cbba51de7bd5d7e9847b8de7b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/8d7e27ca17dda204fbefa084efbbba9e9681cadd", - "reference": "8d7e27ca17dda204fbefa084efbbba9e9681cadd", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/48c67e3325bc222cbba51de7bd5d7e9847b8de7b", + "reference": "48c67e3325bc222cbba51de7bd5d7e9847b8de7b", "shasum": "" }, "require": { @@ -550,7 +550,8 @@ "pocketmine/spl": "dev-master" }, "require-dev": { - "phpstan/phpstan": "^0.12.8" + "phpstan/phpstan": "^0.12.18", + "phpstan/phpstan-strict-rules": "^0.12.2" }, "type": "library", "autoload": { @@ -563,7 +564,7 @@ "GPL-3.0" ], "description": "A RakNet server implementation written in PHP", - "time": "2020-01-31T15:36:55+00:00" + "time": "2020-03-28T01:04:17+00:00" }, { "name": "pocketmine/snooze", From eb7c31d3ffb209faf433b468e4ee7d28c3856795 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 29 Mar 2020 16:26:22 +0100 Subject: [PATCH 1422/3224] RakLibInterface: remove useless shutdown check from tick() the thread should never be shutdown during an update cycle, because we stop the interface from being ticked when it gets shutdown. --- src/network/mcpe/raklib/RakLibInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index fa53227cf7..c6f3f88609 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -105,7 +105,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ } public function tick() : void{ - if(!$this->rakLib->isRunning() and !$this->rakLib->isShutdown()){ + if(!$this->rakLib->isRunning()){ $e = $this->rakLib->getCrashInfo(); if($e !== null){ throw $e; From f779881b6a50cd80534b605f955b088ce55946e9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 29 Mar 2020 16:52:36 +0100 Subject: [PATCH 1423/3224] Updated to latest RakLib bleeding edge this version brings quite a few inter-thread communication improvements. --- composer.lock | 9 ++++----- src/network/mcpe/raklib/RakLibInterface.php | 6 +++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/composer.lock b/composer.lock index 597001ca09..5eceef78dd 100644 --- a/composer.lock +++ b/composer.lock @@ -529,16 +529,15 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "48c67e3325bc222cbba51de7bd5d7e9847b8de7b" + "reference": "76e8d9f15c5ecc0d08d39968023380a2086f0d31" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/48c67e3325bc222cbba51de7bd5d7e9847b8de7b", - "reference": "48c67e3325bc222cbba51de7bd5d7e9847b8de7b", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/76e8d9f15c5ecc0d08d39968023380a2086f0d31", + "reference": "76e8d9f15c5ecc0d08d39968023380a2086f0d31", "shasum": "" }, "require": { - "ext-bcmath": "*", "ext-pthreads": "~3.2.0", "ext-sockets": "*", "php": ">=7.2.0", @@ -564,7 +563,7 @@ "GPL-3.0" ], "description": "A RakNet server implementation written in PHP", - "time": "2020-03-28T01:04:17+00:00" + "time": "2020-03-29T10:00:16+00:00" }, { "name": "pocketmine/snooze", diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index c6f3f88609..7618a953e2 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -139,15 +139,15 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $this->sessions[$sessionId] = $session; } - public function handleEncapsulated(int $sessionId, EncapsulatedPacket $packet, int $flags) : void{ + public function handleEncapsulated(int $sessionId, string $packet) : void{ if(isset($this->sessions[$sessionId])){ - if($packet->buffer === "" or $packet->buffer{0} !== self::MCPE_RAKNET_PACKET_ID){ + if($packet === "" or $packet[0] !== self::MCPE_RAKNET_PACKET_ID){ return; } //get this now for blocking in case the player was closed before the exception was raised $session = $this->sessions[$sessionId]; $address = $session->getIp(); - $buf = substr($packet->buffer, 1); + $buf = substr($packet, 1); try{ $session->handleEncoded($buf); }catch(BadPacketException $e){ From 4e54e544213e38d85b45c3e88e02d94fde57bd21 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 29 Mar 2020 18:18:39 +0100 Subject: [PATCH 1424/3224] Updated RakLib dependency --- composer.lock | 8 +- src/network/mcpe/raklib/RakLibInterface.php | 11 +- src/network/mcpe/raklib/RakLibServer.php | 193 ++++++++++++++++++++ src/utils/Process.php | 2 +- 4 files changed, 206 insertions(+), 8 deletions(-) create mode 100644 src/network/mcpe/raklib/RakLibServer.php diff --git a/composer.lock b/composer.lock index 5eceef78dd..45e20f16f6 100644 --- a/composer.lock +++ b/composer.lock @@ -529,12 +529,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "76e8d9f15c5ecc0d08d39968023380a2086f0d31" + "reference": "b049d56a3ef5c87e545882737f8e1a8e965fec1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/76e8d9f15c5ecc0d08d39968023380a2086f0d31", - "reference": "76e8d9f15c5ecc0d08d39968023380a2086f0d31", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/b049d56a3ef5c87e545882737f8e1a8e965fec1d", + "reference": "b049d56a3ef5c87e545882737f8e1a8e965fec1d", "shasum": "" }, "require": { @@ -563,7 +563,7 @@ "GPL-3.0" ], "description": "A RakNet server implementation written in PHP", - "time": "2020-03-29T10:00:16+00:00" + "time": "2020-03-29T17:01:59+00:00" }, { "name": "pocketmine/snooze", diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 7618a953e2..fc3a6b1d91 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -35,7 +35,8 @@ use pocketmine\utils\Utils; use raklib\protocol\EncapsulatedPacket; use raklib\protocol\PacketReliability; use raklib\RakLib; -use raklib\server\RakLibServer; +use raklib\server\InterThreadChannelReader; +use raklib\server\InterThreadChannelWriter; use raklib\server\ServerHandler; use raklib\server\ServerInstance; use raklib\utils\InternetAddress; @@ -82,13 +83,16 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ $this->rakLib = new RakLibServer( $this->server->getLogger(), - \pocketmine\COMPOSER_AUTOLOADER_PATH, new InternetAddress($this->server->getIp(), $this->server->getPort(), 4), (int) $this->server->getProperty("network.max-mtu-size", 1492), self::MCPE_RAKNET_PROTOCOL_VERSION, $this->sleeper ); - $this->interface = new ServerHandler($this->rakLib, $this); + $this->interface = new ServerHandler( + $this, + new InterThreadChannelReader($this->rakLib->getExternalQueue()), + new InterThreadChannelWriter($this->rakLib->getInternalQueue()) + ); } public function start() : void{ @@ -132,6 +136,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ public function shutdown() : void{ $this->server->getTickSleeper()->removeNotifier($this->sleeper); $this->interface->shutdown(); + $this->rakLib->quit(); } public function openSession(int $sessionId, string $address, int $port, int $clientID) : void{ diff --git a/src/network/mcpe/raklib/RakLibServer.php b/src/network/mcpe/raklib/RakLibServer.php new file mode 100644 index 0000000000..7c88693131 --- /dev/null +++ b/src/network/mcpe/raklib/RakLibServer.php @@ -0,0 +1,193 @@ +address = $address; + + $this->serverId = mt_rand(0, PHP_INT_MAX); + $this->maxMtuSize = $maxMtuSize; + + $this->logger = $logger; + + $this->externalQueue = new \Threaded; + $this->internalQueue = new \Threaded; + + $this->mainPath = \pocketmine\PATH; + + $this->protocolVersion = $overrideProtocolVersion ?? RakLib::DEFAULT_PROTOCOL_VERSION; + + $this->mainThreadNotifier = $sleeper; + } + + /** + * Returns the RakNet server ID + * @return int + */ + public function getServerId() : int{ + return $this->serverId; + } + + /** + * @return \Threaded + */ + public function getExternalQueue() : \Threaded{ + return $this->externalQueue; + } + + /** + * @return \Threaded + */ + public function getInternalQueue() : \Threaded{ + return $this->internalQueue; + } + + /** + * @return void + */ + public function shutdownHandler(){ + if($this->cleanShutdown !== true){ + $error = error_get_last(); + + if($error !== null){ + $this->logger->emergency("Fatal error: " . $error["message"] . " in " . $error["file"] . " on line " . $error["line"]); + $this->setCrashInfo(new \ErrorException($error['message'], 0, $error['type'], $error['file'], $error['line'])); + }else{ + $this->logger->emergency("RakLib shutdown unexpectedly"); + } + } + } + + public function getCrashInfo() : ?\Throwable{ + return $this->crashInfo; + } + + private function setCrashInfo(\Throwable $e) : void{ + $this->synchronized(function(\Throwable $e) : void{ + $this->crashInfo = $e; + $this->notify(); + }, $e); + } + + public function startAndWait(int $options = PTHREADS_INHERIT_NONE) : void{ + $this->start($options); + $this->synchronized(function() : void{ + while(!$this->ready and $this->crashInfo === null){ + $this->wait(); + } + if($this->crashInfo !== null){ + throw $this->crashInfo; + } + }); + } + + public function onRun() : void{ + try{ + gc_enable(); + ini_set("display_errors", '1'); + ini_set("display_startup_errors", '1'); + + register_shutdown_function([$this, "shutdownHandler"]); + + $socket = new Socket($this->address); + $manager = new SessionManager( + $this->serverId, + $this->logger, + $socket, + $this->maxMtuSize, + $this->protocolVersion, + new InterThreadChannelReader($this->internalQueue), + new InterThreadChannelWriter($this->externalQueue, $this->mainThreadNotifier), + new ExceptionTraceCleaner($this->mainPath) + ); + $this->synchronized(function() : void{ + $this->ready = true; + $this->notify(); + }); + $manager->run(); + $this->cleanShutdown = true; + }catch(\Throwable $e){ + $this->setCrashInfo($e); + $this->logger->logException($e); + } + } + +} diff --git a/src/utils/Process.php b/src/utils/Process.php index c76f9caf58..1d26bee642 100644 --- a/src/utils/Process.php +++ b/src/utils/Process.php @@ -114,7 +114,7 @@ final class Process{ //TODO: more OS - return count(ThreadManager::getInstance()->getAll()) + 3; //RakLib + MainLogger + Main Thread + return count(ThreadManager::getInstance()->getAll()) + 2; //MainLogger + Main Thread } /** From d89cdfc18ec804ffbc0e0efce2598279e76f0905 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 29 Mar 2020 18:42:15 +0100 Subject: [PATCH 1425/3224] Relieve RakLibServer of more responsibilities at this point it's really not much more than just a thread-safe way to transmit parameters from main to thread. Maybe we can ditch it in favour of a generic closure-based thread implementation. --- src/network/mcpe/raklib/RakLibInterface.php | 17 +++++-- src/network/mcpe/raklib/RakLibServer.php | 51 ++++++++------------- 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index fc3a6b1d91..8d32ffe223 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -43,6 +43,7 @@ use raklib\utils\InternetAddress; use function addcslashes; use function bin2hex; use function implode; +use function mt_rand; use function random_bytes; use function rtrim; use function substr; @@ -64,6 +65,9 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ /** @var Network */ private $network; + /** @var int */ + private $rakServerId; + /** @var RakLibServer */ private $rakLib; @@ -78,20 +82,27 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ public function __construct(Server $server){ $this->server = $server; + $this->rakServerId = mt_rand(0, PHP_INT_MAX); $this->sleeper = new SleeperNotifier(); + $mainToThreadBuffer = new \Threaded; + $threadToMainBuffer = new \Threaded; + $this->rakLib = new RakLibServer( $this->server->getLogger(), + $mainToThreadBuffer, + $threadToMainBuffer, new InternetAddress($this->server->getIp(), $this->server->getPort(), 4), + $this->rakServerId, (int) $this->server->getProperty("network.max-mtu-size", 1492), self::MCPE_RAKNET_PROTOCOL_VERSION, $this->sleeper ); $this->interface = new ServerHandler( $this, - new InterThreadChannelReader($this->rakLib->getExternalQueue()), - new InterThreadChannelWriter($this->rakLib->getInternalQueue()) + new InterThreadChannelReader($threadToMainBuffer), + new InterThreadChannelWriter($mainToThreadBuffer) ); } @@ -207,7 +218,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ ProtocolInfo::MINECRAFT_VERSION_NETWORK, $info->getPlayerCount(), $info->getMaxPlayerCount(), - $this->rakLib->getServerId(), + $this->rakServerId, $this->server->getName(), $this->server->getGamemode()->getEnglishName() ]) . ";" diff --git a/src/network/mcpe/raklib/RakLibServer.php b/src/network/mcpe/raklib/RakLibServer.php index 7c88693131..afc418ccff 100644 --- a/src/network/mcpe/raklib/RakLibServer.php +++ b/src/network/mcpe/raklib/RakLibServer.php @@ -35,9 +35,7 @@ use raklib\utils\InternetAddress; use function error_get_last; use function gc_enable; use function ini_set; -use function mt_rand; use function register_shutdown_function; -use const PHP_INT_MAX; use const PTHREADS_INHERIT_NONE; class RakLibServer extends Thread{ @@ -53,15 +51,15 @@ class RakLibServer extends Thread{ protected $ready = false; /** @var \Threaded */ - protected $externalQueue; + protected $mainToThreadBuffer; /** @var \Threaded */ - protected $internalQueue; + protected $threadToMainBuffer; /** @var string */ protected $mainPath; /** @var int */ - protected $serverId = 0; + protected $serverId; /** @var int */ protected $maxMtuSize; /** @var int */ @@ -80,16 +78,25 @@ class RakLibServer extends Thread{ * @param int|null $overrideProtocolVersion Optional custom protocol version to use, defaults to current RakLib's protocol * @param SleeperNotifier|null $sleeper */ - public function __construct(\ThreadedLogger $logger, InternetAddress $address, int $maxMtuSize = 1492, ?int $overrideProtocolVersion = null, ?SleeperNotifier $sleeper = null){ + public function __construct( + \ThreadedLogger $logger, + \Threaded $mainToThreadBuffer, + \Threaded $threadToMainBuffer, + InternetAddress $address, + int $serverId, + int $maxMtuSize = 1492, + ?int $overrideProtocolVersion = null, + ?SleeperNotifier $sleeper = null + ){ $this->address = $address; - $this->serverId = mt_rand(0, PHP_INT_MAX); + $this->serverId = $serverId; $this->maxMtuSize = $maxMtuSize; $this->logger = $logger; - $this->externalQueue = new \Threaded; - $this->internalQueue = new \Threaded; + $this->mainToThreadBuffer = $mainToThreadBuffer; + $this->threadToMainBuffer = $threadToMainBuffer; $this->mainPath = \pocketmine\PATH; @@ -98,28 +105,6 @@ class RakLibServer extends Thread{ $this->mainThreadNotifier = $sleeper; } - /** - * Returns the RakNet server ID - * @return int - */ - public function getServerId() : int{ - return $this->serverId; - } - - /** - * @return \Threaded - */ - public function getExternalQueue() : \Threaded{ - return $this->externalQueue; - } - - /** - * @return \Threaded - */ - public function getInternalQueue() : \Threaded{ - return $this->internalQueue; - } - /** * @return void */ @@ -174,8 +159,8 @@ class RakLibServer extends Thread{ $socket, $this->maxMtuSize, $this->protocolVersion, - new InterThreadChannelReader($this->internalQueue), - new InterThreadChannelWriter($this->externalQueue, $this->mainThreadNotifier), + new InterThreadChannelReader($this->mainToThreadBuffer), + new InterThreadChannelWriter($this->threadToMainBuffer, $this->mainThreadNotifier), new ExceptionTraceCleaner($this->mainPath) ); $this->synchronized(function() : void{ From abd1ed735205388738635cd612e02815fd6769d6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 29 Mar 2020 18:45:48 +0100 Subject: [PATCH 1426/3224] RakLibServer: make onRun() protected --- src/network/mcpe/raklib/RakLibServer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/raklib/RakLibServer.php b/src/network/mcpe/raklib/RakLibServer.php index afc418ccff..709e5d3894 100644 --- a/src/network/mcpe/raklib/RakLibServer.php +++ b/src/network/mcpe/raklib/RakLibServer.php @@ -144,7 +144,7 @@ class RakLibServer extends Thread{ }); } - public function onRun() : void{ + protected function onRun() : void{ try{ gc_enable(); ini_set("display_errors", '1'); From 927872ce08fffee3b0301aac8c6f20d5d2ec9366 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 29 Mar 2020 23:53:00 +0100 Subject: [PATCH 1427/3224] Updated to latest bleeding-edge RakLib --- composer.lock | 8 +++--- src/network/mcpe/raklib/RakLibInterface.php | 27 +++++++++++-------- .../mcpe/raklib/RakLibPacketSender.php | 2 +- src/network/mcpe/raklib/RakLibServer.php | 6 +++-- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/composer.lock b/composer.lock index 45e20f16f6..4172673ae6 100644 --- a/composer.lock +++ b/composer.lock @@ -529,12 +529,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "b049d56a3ef5c87e545882737f8e1a8e965fec1d" + "reference": "45378244744328ceda76f95f2636a4f2d6e365c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/b049d56a3ef5c87e545882737f8e1a8e965fec1d", - "reference": "b049d56a3ef5c87e545882737f8e1a8e965fec1d", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/45378244744328ceda76f95f2636a4f2d6e365c7", + "reference": "45378244744328ceda76f95f2636a4f2d6e365c7", "shasum": "" }, "require": { @@ -563,7 +563,7 @@ "GPL-3.0" ], "description": "A RakNet server implementation written in PHP", - "time": "2020-03-29T17:01:59+00:00" + "time": "2020-03-29T22:42:27+00:00" }, { "name": "pocketmine/snooze", diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 8d32ffe223..cd3a8f196d 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -37,8 +37,9 @@ use raklib\protocol\PacketReliability; use raklib\RakLib; use raklib\server\InterThreadChannelReader; use raklib\server\InterThreadChannelWriter; -use raklib\server\ServerHandler; -use raklib\server\ServerInstance; +use raklib\server\RakLibToUserThreadMessageReceiver; +use raklib\server\ServerEventListener; +use raklib\server\UserToRakLibThreadMessageSender; use raklib\utils\InternetAddress; use function addcslashes; use function bin2hex; @@ -50,7 +51,7 @@ use function substr; use function unserialize; use const PTHREADS_INHERIT_CONSTANTS; -class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ +class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ /** * Sometimes this gets changed when the MCPE-layer protocol gets broken to the point where old and new can't * communicate. It's important that we check this to avoid catastrophes. @@ -74,7 +75,9 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ /** @var NetworkSession[] */ private $sessions = []; - /** @var ServerHandler */ + /** @var RakLibToUserThreadMessageReceiver */ + private $eventReceiver; + /** @var UserToRakLibThreadMessageSender */ private $interface; /** @var SleeperNotifier */ @@ -99,16 +102,18 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ self::MCPE_RAKNET_PROTOCOL_VERSION, $this->sleeper ); - $this->interface = new ServerHandler( + $this->eventReceiver = new RakLibToUserThreadMessageReceiver( $this, - new InterThreadChannelReader($threadToMainBuffer), + new InterThreadChannelReader($threadToMainBuffer) + ); + $this->interface = new UserToRakLibThreadMessageSender( new InterThreadChannelWriter($mainToThreadBuffer) ); } public function start() : void{ $this->server->getTickSleeper()->addNotifier($this->sleeper, function() : void{ - while($this->interface->handlePacket()); + while($this->eventReceiver->handle()); }); $this->server->getLogger()->debug("Waiting for RakLib to start..."); $this->rakLib->startAndWait(PTHREADS_INHERIT_CONSTANTS); //HACK: MainLogger needs constants for exception logging @@ -137,10 +142,10 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ } } - public function close(int $sessionId, string $reason = "unknown reason") : void{ + public function close(int $sessionId) : void{ if(isset($this->sessions[$sessionId])){ unset($this->sessions[$sessionId]); - $this->interface->closeSession($sessionId, $reason); + $this->interface->closeSession($sessionId); } } @@ -210,7 +215,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ public function setName(string $name) : void{ $info = $this->server->getQueryInformation(); - $this->interface->sendOption("name", implode(";", + $this->interface->setOption("name", implode(";", [ "MCPE", rtrim(addcslashes($name, ";"), '\\'), @@ -226,7 +231,7 @@ class RakLibInterface implements ServerInstance, AdvancedNetworkInterface{ } public function setPortCheck(bool $name) : void{ - $this->interface->sendOption("portChecking", $name); + $this->interface->setOption("portChecking", $name); } public function handleOption(string $option, string $value) : void{ diff --git a/src/network/mcpe/raklib/RakLibPacketSender.php b/src/network/mcpe/raklib/RakLibPacketSender.php index 8c1e33782e..11821959b1 100644 --- a/src/network/mcpe/raklib/RakLibPacketSender.php +++ b/src/network/mcpe/raklib/RakLibPacketSender.php @@ -49,7 +49,7 @@ class RakLibPacketSender implements PacketSender{ public function close(string $reason = "unknown reason") : void{ if(!$this->closed){ $this->closed = true; - $this->handler->close($this->sessionId, $reason); + $this->handler->close($this->sessionId); } } } diff --git a/src/network/mcpe/raklib/RakLibServer.php b/src/network/mcpe/raklib/RakLibServer.php index 709e5d3894..000d38d108 100644 --- a/src/network/mcpe/raklib/RakLibServer.php +++ b/src/network/mcpe/raklib/RakLibServer.php @@ -29,7 +29,9 @@ use raklib\generic\Socket; use raklib\RakLib; use raklib\server\InterThreadChannelReader; use raklib\server\InterThreadChannelWriter; +use raklib\server\RakLibToUserThreadMessageSender; use raklib\server\SessionManager; +use raklib\server\UserToRakLibThreadMessageReceiver; use raklib\utils\ExceptionTraceCleaner; use raklib\utils\InternetAddress; use function error_get_last; @@ -159,8 +161,8 @@ class RakLibServer extends Thread{ $socket, $this->maxMtuSize, $this->protocolVersion, - new InterThreadChannelReader($this->mainToThreadBuffer), - new InterThreadChannelWriter($this->threadToMainBuffer, $this->mainThreadNotifier), + new UserToRakLibThreadMessageReceiver(new InterThreadChannelReader($this->mainToThreadBuffer)), + new RakLibToUserThreadMessageSender(new InterThreadChannelWriter($this->threadToMainBuffer, $this->mainThreadNotifier)), new ExceptionTraceCleaner($this->mainPath) ); $this->synchronized(function() : void{ From 00cc2ee0920d9b9c9ff67c50e3b3325b9ce267b6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 30 Mar 2020 00:22:45 +0100 Subject: [PATCH 1428/3224] one more RakLib update for the day ... --- composer.lock | 8 ++++---- src/network/mcpe/raklib/RakLibInterface.php | 8 ++++---- src/network/mcpe/raklib/RakLibServer.php | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/composer.lock b/composer.lock index 4172673ae6..3e8049f7d1 100644 --- a/composer.lock +++ b/composer.lock @@ -529,12 +529,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "45378244744328ceda76f95f2636a4f2d6e365c7" + "reference": "637f1ddd682eda6955ca91e301953d3990dc4b37" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/45378244744328ceda76f95f2636a4f2d6e365c7", - "reference": "45378244744328ceda76f95f2636a4f2d6e365c7", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/637f1ddd682eda6955ca91e301953d3990dc4b37", + "reference": "637f1ddd682eda6955ca91e301953d3990dc4b37", "shasum": "" }, "require": { @@ -563,7 +563,7 @@ "GPL-3.0" ], "description": "A RakNet server implementation written in PHP", - "time": "2020-03-29T22:42:27+00:00" + "time": "2020-03-29T23:17:14+00:00" }, { "name": "pocketmine/snooze", diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index cd3a8f196d..1f06f01680 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -35,11 +35,11 @@ use pocketmine\utils\Utils; use raklib\protocol\EncapsulatedPacket; use raklib\protocol\PacketReliability; use raklib\RakLib; -use raklib\server\InterThreadChannelReader; -use raklib\server\InterThreadChannelWriter; -use raklib\server\RakLibToUserThreadMessageReceiver; +use raklib\server\ipc\InterThreadChannelReader; +use raklib\server\ipc\InterThreadChannelWriter; +use raklib\server\ipc\RakLibToUserThreadMessageReceiver; +use raklib\server\ipc\UserToRakLibThreadMessageSender; use raklib\server\ServerEventListener; -use raklib\server\UserToRakLibThreadMessageSender; use raklib\utils\InternetAddress; use function addcslashes; use function bin2hex; diff --git a/src/network/mcpe/raklib/RakLibServer.php b/src/network/mcpe/raklib/RakLibServer.php index 000d38d108..67eb126dae 100644 --- a/src/network/mcpe/raklib/RakLibServer.php +++ b/src/network/mcpe/raklib/RakLibServer.php @@ -27,11 +27,11 @@ use pocketmine\snooze\SleeperNotifier; use pocketmine\thread\Thread; use raklib\generic\Socket; use raklib\RakLib; -use raklib\server\InterThreadChannelReader; -use raklib\server\InterThreadChannelWriter; -use raklib\server\RakLibToUserThreadMessageSender; +use raklib\server\ipc\InterThreadChannelReader; +use raklib\server\ipc\InterThreadChannelWriter; +use raklib\server\ipc\RakLibToUserThreadMessageSender; +use raklib\server\ipc\UserToRakLibThreadMessageReceiver; use raklib\server\SessionManager; -use raklib\server\UserToRakLibThreadMessageReceiver; use raklib\utils\ExceptionTraceCleaner; use raklib\utils\InternetAddress; use function error_get_last; From 64d5320ac90705913bc1fc840f54ba48ab466b5a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 31 Mar 2020 19:41:37 +0100 Subject: [PATCH 1429/3224] update for pthreads-free raklib --- .../mcpe/raklib/PthreadsChannelReader.php | 39 ++++++++++++++++++ .../mcpe/raklib/PthreadsChannelWriter.php | 40 +++++++++++++++++++ src/network/mcpe/raklib/RakLibInterface.php | 6 +-- src/network/mcpe/raklib/RakLibServer.php | 6 +-- 4 files changed, 83 insertions(+), 8 deletions(-) create mode 100644 src/network/mcpe/raklib/PthreadsChannelReader.php create mode 100644 src/network/mcpe/raklib/PthreadsChannelWriter.php diff --git a/src/network/mcpe/raklib/PthreadsChannelReader.php b/src/network/mcpe/raklib/PthreadsChannelReader.php new file mode 100644 index 0000000000..4b32b0f383 --- /dev/null +++ b/src/network/mcpe/raklib/PthreadsChannelReader.php @@ -0,0 +1,39 @@ +buffer = $buffer; + } + + public function read() : ?string{ + return $this->buffer->shift(); + } +} diff --git a/src/network/mcpe/raklib/PthreadsChannelWriter.php b/src/network/mcpe/raklib/PthreadsChannelWriter.php new file mode 100644 index 0000000000..580d774bb8 --- /dev/null +++ b/src/network/mcpe/raklib/PthreadsChannelWriter.php @@ -0,0 +1,40 @@ +buffer = $buffer; + $this->notifier = $notifier; + } + + public function write(string $str) : void{ + $this->buffer[] = $str; + if($this->notifier !== null){ + $this->notifier->wakeupSleeper(); + } + } +} diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 1f06f01680..8afba969ef 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -35,8 +35,6 @@ use pocketmine\utils\Utils; use raklib\protocol\EncapsulatedPacket; use raklib\protocol\PacketReliability; use raklib\RakLib; -use raklib\server\ipc\InterThreadChannelReader; -use raklib\server\ipc\InterThreadChannelWriter; use raklib\server\ipc\RakLibToUserThreadMessageReceiver; use raklib\server\ipc\UserToRakLibThreadMessageSender; use raklib\server\ServerEventListener; @@ -104,10 +102,10 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ ); $this->eventReceiver = new RakLibToUserThreadMessageReceiver( $this, - new InterThreadChannelReader($threadToMainBuffer) + new PthreadsChannelReader($threadToMainBuffer) ); $this->interface = new UserToRakLibThreadMessageSender( - new InterThreadChannelWriter($mainToThreadBuffer) + new PthreadsChannelWriter($mainToThreadBuffer) ); } diff --git a/src/network/mcpe/raklib/RakLibServer.php b/src/network/mcpe/raklib/RakLibServer.php index 67eb126dae..d01175a430 100644 --- a/src/network/mcpe/raklib/RakLibServer.php +++ b/src/network/mcpe/raklib/RakLibServer.php @@ -27,8 +27,6 @@ use pocketmine\snooze\SleeperNotifier; use pocketmine\thread\Thread; use raklib\generic\Socket; use raklib\RakLib; -use raklib\server\ipc\InterThreadChannelReader; -use raklib\server\ipc\InterThreadChannelWriter; use raklib\server\ipc\RakLibToUserThreadMessageSender; use raklib\server\ipc\UserToRakLibThreadMessageReceiver; use raklib\server\SessionManager; @@ -161,8 +159,8 @@ class RakLibServer extends Thread{ $socket, $this->maxMtuSize, $this->protocolVersion, - new UserToRakLibThreadMessageReceiver(new InterThreadChannelReader($this->mainToThreadBuffer)), - new RakLibToUserThreadMessageSender(new InterThreadChannelWriter($this->threadToMainBuffer, $this->mainThreadNotifier)), + new UserToRakLibThreadMessageReceiver(new PthreadsChannelReader($this->mainToThreadBuffer)), + new RakLibToUserThreadMessageSender(new PthreadsChannelWriter($this->threadToMainBuffer, $this->mainThreadNotifier)), new ExceptionTraceCleaner($this->mainPath) ); $this->synchronized(function() : void{ From f5cd87ac95322c871cec4a3421e43afe71607f6b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 1 Apr 2020 20:09:42 +0100 Subject: [PATCH 1430/3224] MainLogger: implement BufferedLogger --- src/utils/MainLogger.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/utils/MainLogger.php b/src/utils/MainLogger.php index ab88e2e583..120768cca3 100644 --- a/src/utils/MainLogger.php +++ b/src/utils/MainLogger.php @@ -38,7 +38,7 @@ use function trim; use const PHP_EOL; use const PTHREADS_INHERIT_NONE; -class MainLogger extends \AttachableThreadedLogger{ +class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ /** @var string */ protected $logFile; @@ -149,7 +149,7 @@ class MainLogger extends \AttachableThreadedLogger{ $trace = $e->getTrace(); } - $this->synchronized(function() use ($e, $trace) : void{ + $this->buffer(function() use ($e, $trace) : void{ $this->critical(self::printExceptionMessage($e)); foreach(Utils::printableTrace($trace) as $line){ $this->debug($line, true); @@ -210,6 +210,13 @@ class MainLogger extends \AttachableThreadedLogger{ } } + /** + * @phpstan-param \Closure() : void $c + */ + public function buffer(\Closure $c) : void{ + $this->synchronized($c); + } + public function shutdown() : void{ $this->shutdown = true; $this->notify(); From f5bf93455a87f78da31c68d5915adb0054b91b68 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 1 Apr 2020 20:16:21 +0100 Subject: [PATCH 1431/3224] update to latest RakLib --- composer.lock | 8 ++++---- src/network/mcpe/raklib/RakLibServer.php | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 27d1a64fab..aaa4537740 100644 --- a/composer.lock +++ b/composer.lock @@ -567,12 +567,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "7e883f7498e979a63b079606af0cb8f20b082c46" + "reference": "092d26f64b8a72e0727fb02b8a8fbb4279433b54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/7e883f7498e979a63b079606af0cb8f20b082c46", - "reference": "7e883f7498e979a63b079606af0cb8f20b082c46", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/092d26f64b8a72e0727fb02b8a8fbb4279433b54", + "reference": "092d26f64b8a72e0727fb02b8a8fbb4279433b54", "shasum": "" }, "require": { @@ -598,7 +598,7 @@ "GPL-3.0" ], "description": "A RakNet server implementation written in PHP", - "time": "2020-03-31T18:03:55+00:00" + "time": "2020-04-01T19:11:14+00:00" }, { "name": "pocketmine/snooze", diff --git a/src/network/mcpe/raklib/RakLibServer.php b/src/network/mcpe/raklib/RakLibServer.php index d01175a430..63a26da0f8 100644 --- a/src/network/mcpe/raklib/RakLibServer.php +++ b/src/network/mcpe/raklib/RakLibServer.php @@ -29,7 +29,7 @@ use raklib\generic\Socket; use raklib\RakLib; use raklib\server\ipc\RakLibToUserThreadMessageSender; use raklib\server\ipc\UserToRakLibThreadMessageReceiver; -use raklib\server\SessionManager; +use raklib\server\Server; use raklib\utils\ExceptionTraceCleaner; use raklib\utils\InternetAddress; use function error_get_last; @@ -153,7 +153,7 @@ class RakLibServer extends Thread{ register_shutdown_function([$this, "shutdownHandler"]); $socket = new Socket($this->address); - $manager = new SessionManager( + $manager = new Server( $this->serverId, $this->logger, $socket, From 1d9cb174b6b87ed6c9912ac7c2a056f810ffbb9e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 4 Apr 2020 23:30:55 +0100 Subject: [PATCH 1432/3224] updated RakLib dependency --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index aaa4537740..fce0cd14bf 100644 --- a/composer.lock +++ b/composer.lock @@ -567,12 +567,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "092d26f64b8a72e0727fb02b8a8fbb4279433b54" + "reference": "1911022465f2563668d79d8a7481856076ef046f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/092d26f64b8a72e0727fb02b8a8fbb4279433b54", - "reference": "092d26f64b8a72e0727fb02b8a8fbb4279433b54", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/1911022465f2563668d79d8a7481856076ef046f", + "reference": "1911022465f2563668d79d8a7481856076ef046f", "shasum": "" }, "require": { @@ -598,7 +598,7 @@ "GPL-3.0" ], "description": "A RakNet server implementation written in PHP", - "time": "2020-04-01T19:11:14+00:00" + "time": "2020-04-04T22:26:02+00:00" }, { "name": "pocketmine/snooze", From d3a6da1b3ae8c5e6267a1bb5d8b48d05cf9fcdc8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 4 Apr 2020 23:33:30 +0100 Subject: [PATCH 1433/3224] NetworkSession->getPing() now returns null when no measurement of ping has yet been completed --- src/network/mcpe/NetworkSession.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 6da5497c01..e32f8f3b39 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -117,8 +117,8 @@ class NetworkSession{ private $port; /** @var PlayerInfo */ private $info; - /** @var int */ - private $ping; + /** @var int|null */ + private $ping = null; /** @var PacketHandler */ private $handler; @@ -235,9 +235,9 @@ class NetworkSession{ } /** - * Returns the last recorded ping measurement for this session, in milliseconds. + * Returns the last recorded ping measurement for this session, in milliseconds, or null if a ping measurement has not yet been recorded. */ - public function getPing() : int{ + public function getPing() : ?int{ return $this->ping; } From 9ba47f90d11cd74f8462d3813878c3ac0a91d5bb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 16 Apr 2020 01:45:00 +0100 Subject: [PATCH 1434/3224] LoginPacketHandler: account for failure to correctly parse UUID this will still crash in some circumstances, pending merging bug fixes from stable. --- src/network/mcpe/handler/LoginPacketHandler.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index c4f215e577..6df832e053 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe\handler; use pocketmine\entity\Skin; use pocketmine\event\player\PlayerPreLoginEvent; +use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\auth\ProcessLoginTask; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\LoginPacket; @@ -111,9 +112,14 @@ class LoginPacketHandler extends PacketHandler{ return true; } + try{ + $uuid = UUID::fromString($packet->extraData->identity); + }catch(\InvalidArgumentException $e){ + throw BadPacketException::wrap($e, "Failed to parse login UUID"); + } $this->session->setPlayerInfo(new PlayerInfo( $packet->extraData->displayName, - UUID::fromString($packet->extraData->identity), + $uuid, $skin, $packet->clientData->LanguageCode, $packet->extraData->XUID, From e86c243db5f5eb74e147f0421f42061e70bf1e8a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 16 Apr 2020 01:55:52 +0100 Subject: [PATCH 1435/3224] NetworkSession: do not expose setPlayerInfo() --- src/network/mcpe/NetworkSession.php | 20 +++++-------------- .../mcpe/handler/LoginPacketHandler.php | 13 ++++++++++-- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index e32f8f3b39..6add549003 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -162,7 +162,11 @@ class NetworkSession{ $this->connectTime = time(); - $this->setHandler(new LoginPacketHandler($this->server, $this)); + $this->setHandler(new LoginPacketHandler($this->server, $this, function(PlayerInfo $info) : void{ + $this->info = $info; + $this->logger->info("Player: " . TextFormat::AQUA . $info->getUsername() . TextFormat::RESET); + $this->logger->setPrefix($this->getLogPrefix()); + })); $this->manager->add($this); $this->logger->info("Session opened"); @@ -204,20 +208,6 @@ class NetworkSession{ return $this->info; } - /** - * TODO: this shouldn't be accessible after the initial login phase - * - * @throws \InvalidStateException - */ - public function setPlayerInfo(PlayerInfo $info) : void{ - if($this->info !== null){ - throw new \InvalidStateException("Player info has already been set"); - } - $this->info = $info; - $this->logger->info("Player: " . TextFormat::AQUA . $info->getUsername() . TextFormat::RESET); - $this->logger->setPrefix($this->getLogPrefix()); - } - public function isConnected() : bool{ return $this->connected; } diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index 6df832e053..3c020ec75d 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -50,10 +50,19 @@ class LoginPacketHandler extends PacketHandler{ private $server; /** @var NetworkSession */ private $session; + /** + * @var \Closure + * @phpstan-var \Closure(PlayerInfo) : void + */ + private $playerInfoConsumer; - public function __construct(Server $server, NetworkSession $session){ + /** + * @phpstan-param \Closure(PlayerInfo) : void $playerInfoConsumer + */ + public function __construct(Server $server, NetworkSession $session, \Closure $playerInfoConsumer){ $this->session = $session; $this->server = $server; + $this->playerInfoConsumer = $playerInfoConsumer; } public function handleLogin(LoginPacket $packet) : bool{ @@ -117,7 +126,7 @@ class LoginPacketHandler extends PacketHandler{ }catch(\InvalidArgumentException $e){ throw BadPacketException::wrap($e, "Failed to parse login UUID"); } - $this->session->setPlayerInfo(new PlayerInfo( + ($this->playerInfoConsumer)(new PlayerInfo( $packet->extraData->displayName, $uuid, $skin, From 3d3a487422b5acfdf4f67e6784fcbf1b91a3c5c1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 Apr 2020 11:25:29 +0100 Subject: [PATCH 1436/3224] PrepareEncryptionTask: remove cyclic dependency on NetworkSession --- src/network/mcpe/NetworkSession.php | 24 ++++++++---------- .../mcpe/encryption/PrepareEncryptionTask.php | 25 +++++++++++++------ 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 6add549003..6eee0f7a77 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -530,25 +530,23 @@ class NetworkSession{ if($this->manager->kickDuplicates($this)){ if(NetworkCipher::$ENABLED){ - $this->server->getAsyncPool()->submitTask(new PrepareEncryptionTask($this, $clientPubKey)); + $this->server->getAsyncPool()->submitTask(new PrepareEncryptionTask($clientPubKey, function(string $encryptionKey, string $handshakeJwt) : void{ + if(!$this->connected){ + return; + } + $this->sendDataPacket(ServerToClientHandshakePacket::create($handshakeJwt), true); //make sure this gets sent before encryption is enabled + + $this->cipher = new NetworkCipher($encryptionKey); + + $this->setHandler(new HandshakePacketHandler($this)); + $this->logger->debug("Enabled encryption"); + })); }else{ $this->onLoginSuccess(); } } } - public function enableEncryption(string $encryptionKey, string $handshakeJwt) : void{ - if(!$this->connected){ - return; - } - $this->sendDataPacket(ServerToClientHandshakePacket::create($handshakeJwt), true); //make sure this gets sent before encryption is enabled - - $this->cipher = new NetworkCipher($encryptionKey); - - $this->setHandler(new HandshakePacketHandler($this)); - $this->logger->debug("Enabled encryption"); - } - public function onLoginSuccess() : void{ $this->loggedIn = true; diff --git a/src/network/mcpe/encryption/PrepareEncryptionTask.php b/src/network/mcpe/encryption/PrepareEncryptionTask.php index 05a3b16234..e36fc6afdf 100644 --- a/src/network/mcpe/encryption/PrepareEncryptionTask.php +++ b/src/network/mcpe/encryption/PrepareEncryptionTask.php @@ -30,7 +30,6 @@ use Mdanter\Ecc\Serializer\PrivateKey\DerPrivateKeySerializer; use Mdanter\Ecc\Serializer\PrivateKey\PemPrivateKeySerializer; use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer; -use pocketmine\network\mcpe\NetworkSession; use pocketmine\scheduler\AsyncTask; use function base64_encode; use function gmp_strval; @@ -47,7 +46,7 @@ use const STR_PAD_LEFT; class PrepareEncryptionTask extends AsyncTask{ - private const TLS_KEY_SESSION = "session"; + private const TLS_KEY_ON_COMPLETION = "completion"; /** @var PrivateKeyInterface|null */ private static $SERVER_PRIVATE_KEY = null; @@ -61,15 +60,24 @@ class PrepareEncryptionTask extends AsyncTask{ private $handshakeJwt = null; /** @var PublicKeyInterface */ private $clientPub; + /** + * @var \Closure + * @phpstan-var \Closure(string $encryptionKey, string $handshakeJwt) : void + */ + private $onCompletion; - public function __construct(NetworkSession $session, PublicKeyInterface $clientPub){ + /** + * @phpstan-param \Closure(string $encryptionKey, string $handshakeJwt) : void $onCompletion + */ + public function __construct(PublicKeyInterface $clientPub, \Closure $onCompletion){ if(self::$SERVER_PRIVATE_KEY === null){ self::$SERVER_PRIVATE_KEY = EccFactory::getNistCurves()->generator384()->createPrivateKey(); } $this->serverPrivateKey = self::$SERVER_PRIVATE_KEY; $this->clientPub = $clientPub; - $this->storeLocal(self::TLS_KEY_SESSION, $session); + $this->storeLocal(self::TLS_KEY_ON_COMPLETION, $onCompletion); + $this->onCompletion = $onCompletion; } public function onRun() : void{ @@ -107,8 +115,11 @@ class PrepareEncryptionTask extends AsyncTask{ } public function onCompletion() : void{ - /** @var NetworkSession $session */ - $session = $this->fetchLocal(self::TLS_KEY_SESSION); - $session->enableEncryption($this->aesKey, $this->handshakeJwt); + /** + * @var \Closure $callback + * @phpstan-var \Closure(string $encryptionKey, string $handshakeJwt) : void $callback + */ + $callback = $this->fetchLocal(self::TLS_KEY_ON_COMPLETION); + $callback($this->aesKey, $this->handshakeJwt); } } From 86f67445c6541cb2b5e42b2b62f5c062cd6e72eb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 19 Apr 2020 11:19:06 +0100 Subject: [PATCH 1437/3224] fix merge error --- tests/phpstan/configs/phpstan-bugs.neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index c070f2bfac..07f95fc530 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -86,7 +86,7 @@ parameters: #readlink() can return false but phpstan doesn't know this message: "#^Strict comparison using \\!\\=\\= between string and false will always evaluate to true\\.$#" count: 1 - path: ../../../src/pocketmine/utils/Timezone.php + path: ../../../src/utils/Timezone.php - #phpstan doesn't understand that SplFixedArray may contain null From c6d6afe65e795cf8529aeb6197253c38ae350aed Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 19 Apr 2020 12:27:44 +0100 Subject: [PATCH 1438/3224] bring RakLibInterface up to speed with latest RakLib --- src/network/mcpe/raklib/RakLibInterface.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index fcac5fb380..0906390d14 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -34,7 +34,6 @@ use pocketmine\utils\Filesystem; use pocketmine\utils\Utils; use raklib\protocol\EncapsulatedPacket; use raklib\protocol\PacketReliability; -use raklib\RakLib; use raklib\server\ipc\RakLibToUserThreadMessageReceiver; use raklib\server\ipc\UserToRakLibThreadMessageSender; use raklib\server\ServerEventListener; @@ -101,7 +100,6 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ $this->sleeper ); $this->eventReceiver = new RakLibToUserThreadMessageReceiver( - $this, new PthreadsChannelReader($threadToMainBuffer) ); $this->interface = new UserToRakLibThreadMessageSender( @@ -111,7 +109,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ public function start() : void{ $this->server->getTickSleeper()->addNotifier($this->sleeper, function() : void{ - while($this->eventReceiver->handle()); + while($this->eventReceiver->handle($this)); }); $this->server->getLogger()->debug("Waiting for RakLib to start..."); $this->rakLib->startAndWait(PTHREADS_INHERIT_CONSTANTS); //HACK: MainLogger needs constants for exception logging @@ -250,7 +248,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ $pk->reliability = PacketReliability::RELIABLE_ORDERED; $pk->orderChannel = 0; - $this->interface->sendEncapsulated($sessionId, $pk, ($immediate ? RakLib::PRIORITY_IMMEDIATE : RakLib::PRIORITY_NORMAL)); + $this->interface->sendEncapsulated($sessionId, $pk, $immediate); } } From 67247b2e817aeb22a937c5725b1093f26485f258 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 19 Apr 2020 13:53:06 +0100 Subject: [PATCH 1439/3224] fix make-release --- build/make-release.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/make-release.php b/build/make-release.php index d78f9adcc2..eed343d89b 100644 --- a/build/make-release.php +++ b/build/make-release.php @@ -70,7 +70,7 @@ function main(array $argv) : void{ $currentVer->getPatch() + 1 )); - $versionInfoPath = dirname(__DIR__) . '/src/pocketmine/VersionInfo.php'; + $versionInfoPath = dirname(__DIR__) . '/src/VersionInfo.php'; replaceVersion($versionInfoPath, $currentVer->getBaseVersion(), false); echo "please add appropriate notes to the changelog and press enter..."; From 5a33dbd4c6a88e86c2b0b2f4365429e615c26d3a Mon Sep 17 00:00:00 2001 From: Muqsit Date: Sun, 19 Apr 2020 18:27:37 +0100 Subject: [PATCH 1440/3224] Player: drop isAdmin from kick(), closes #3275 --- src/command/defaults/BanIpCommand.php | 2 +- src/command/defaults/KickCommand.php | 2 +- src/player/Player.php | 19 ++++++------------- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/command/defaults/BanIpCommand.php b/src/command/defaults/BanIpCommand.php index 18f09efe3e..b70d1ff71b 100644 --- a/src/command/defaults/BanIpCommand.php +++ b/src/command/defaults/BanIpCommand.php @@ -81,7 +81,7 @@ class BanIpCommand extends VanillaCommand{ foreach($sender->getServer()->getOnlinePlayers() as $player){ if($player->getNetworkSession()->getIp() === $ip){ - $player->kick($reason !== "" ? $reason : "IP banned."); + $player->kick("Banned by admin. Reason: " . ($reason !== "" ? $reason : "IP banned.")); } } diff --git a/src/command/defaults/KickCommand.php b/src/command/defaults/KickCommand.php index 879a181602..f9cb617601 100644 --- a/src/command/defaults/KickCommand.php +++ b/src/command/defaults/KickCommand.php @@ -58,7 +58,7 @@ class KickCommand extends VanillaCommand{ $reason = trim(implode(" ", $args)); if(($player = $sender->getServer()->getPlayer($name)) instanceof Player){ - $player->kick($reason); + $player->kick("Kicked by admin." . ($reason !== "" ? "Reason: " . $reason : "")); if($reason !== ""){ Command::broadcastCommandMessage($sender, new TranslationContainer("commands.kick.success.reason", [$player->getName(), $reason])); }else{ diff --git a/src/player/Player.php b/src/player/Player.php index 97383d14d4..18c5aac294 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1909,22 +1909,15 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * * @param TranslationContainer|string $quitMessage */ - public function kick(string $reason = "", bool $isAdmin = true, $quitMessage = null) : bool{ + public function kick(string $reason = "", $quitMessage = null) : bool{ $ev = new PlayerKickEvent($this, $reason, $quitMessage ?? $this->getLeaveMessage()); $ev->call(); if(!$ev->isCancelled()){ $reason = $ev->getReason(); - $message = $reason; - if($isAdmin){ - if(!$this->isBanned()){ - $message = "Kicked by admin." . ($reason !== "" ? " Reason: " . $reason : ""); - } - }else{ - if($reason === ""){ - $message = "disconnectionScreen.noReason"; - } + if($reason === ""){ + $reason = "disconnectionScreen.noReason"; } - $this->disconnect($message, $ev->getQuitMessage()); + $this->disconnect($reason, $ev->getQuitMessage()); return true; } @@ -1936,8 +1929,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * Removes the player from the server. This cannot be cancelled. * This is used for remote disconnects and for uninterruptible disconnects (for example, when the server shuts down). * - * Note for plugin developers: Prefer kick() with the isAdmin flag set to kick without the "Kicked by admin" part - * instead of this method. This way other plugins can have a say in whether the player is removed or not. + * Note for plugin developers: Prefer kick() instead of this method. + * That way other plugins can have a say in whether the player is removed or not. * * @param string $reason Shown to the player, usually this will appear on their disconnect screen. * @param TranslationContainer|string $quitMessage Message to broadcast to online players (null will use default) From dd37d286f083f9738676ff7010d736a68444db4c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 22 Apr 2020 09:40:26 +0100 Subject: [PATCH 1441/3224] use a dedicated exception class for throwing exceptions on decrypt failure --- src/network/mcpe/NetworkSession.php | 3 +- .../mcpe/encryption/DecryptionException.php | 28 +++++++++++++++++++ src/network/mcpe/encryption/NetworkCipher.php | 6 ++-- 3 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 src/network/mcpe/encryption/DecryptionException.php diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 6eee0f7a77..399bbac6fa 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -36,6 +36,7 @@ use pocketmine\math\Vector3; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\compression\CompressBatchPromise; use pocketmine\network\mcpe\compression\Zlib; +use pocketmine\network\mcpe\encryption\DecryptionException; use pocketmine\network\mcpe\encryption\NetworkCipher; use pocketmine\network\mcpe\encryption\PrepareEncryptionTask; use pocketmine\network\mcpe\handler\DeathPacketHandler; @@ -261,7 +262,7 @@ class NetworkSession{ Timings::$playerNetworkReceiveDecryptTimer->startTiming(); try{ $payload = $this->cipher->decrypt($payload); - }catch(\UnexpectedValueException $e){ + }catch(DecryptionException $e){ $this->logger->debug("Encrypted packet: " . base64_encode($payload)); throw BadPacketException::wrap($e, "Packet decryption error"); }finally{ diff --git a/src/network/mcpe/encryption/DecryptionException.php b/src/network/mcpe/encryption/DecryptionException.php new file mode 100644 index 0000000000..1a5e7e6901 --- /dev/null +++ b/src/network/mcpe/encryption/DecryptionException.php @@ -0,0 +1,28 @@ +decryptCipher->decryptUpdate($encrypted); $payload = substr($decrypted, 0, -8); if(($expected = $this->calculateChecksum($this->decryptCounter++, $payload)) !== ($actual = substr($decrypted, -8))){ - throw new \UnexpectedValueException("Encrypted payload has invalid checksum (expected " . bin2hex($expected) . ", got " . bin2hex($actual) . ")"); + throw new DecryptionException("Encrypted payload has invalid checksum (expected " . bin2hex($expected) . ", got " . bin2hex($actual) . ")"); } return $payload; From 35d656c6e5745f28c4c8f411b2bbf71188d9b0fc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 22 Apr 2020 13:30:37 +0100 Subject: [PATCH 1442/3224] ProcessLoginTask no longer depends on NetworkSession --- src/network/mcpe/NetworkSession.php | 17 ++++++++++++----- src/network/mcpe/auth/ProcessLoginTask.php | 19 ++++++++++++------- .../mcpe/handler/LoginPacketHandler.php | 17 ++++++++++++++--- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 399bbac6fa..906dbef540 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -163,11 +163,18 @@ class NetworkSession{ $this->connectTime = time(); - $this->setHandler(new LoginPacketHandler($this->server, $this, function(PlayerInfo $info) : void{ - $this->info = $info; - $this->logger->info("Player: " . TextFormat::AQUA . $info->getUsername() . TextFormat::RESET); - $this->logger->setPrefix($this->getLogPrefix()); - })); + $this->setHandler(new LoginPacketHandler( + $this->server, + $this, + function(PlayerInfo $info) : void{ + $this->info = $info; + $this->logger->info("Player: " . TextFormat::AQUA . $info->getUsername() . TextFormat::RESET); + $this->logger->setPrefix($this->getLogPrefix()); + }, + function(bool $isAuthenticated, bool $authRequired, ?string $error, ?PublicKeyInterface $clientPubKey) : void{ + $this->setAuthenticationStatus($isAuthenticated, $authRequired, $error, $clientPubKey); + } + )); $this->manager->add($this); $this->logger->info("Session opened"); diff --git a/src/network/mcpe/auth/ProcessLoginTask.php b/src/network/mcpe/auth/ProcessLoginTask.php index cadd54c047..73c0b31b66 100644 --- a/src/network/mcpe/auth/ProcessLoginTask.php +++ b/src/network/mcpe/auth/ProcessLoginTask.php @@ -28,7 +28,6 @@ use Mdanter\Ecc\Crypto\Signature\Signature; use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; use Mdanter\Ecc\Serializer\PublicKey\PemPublicKeySerializer; use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer; -use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\LoginPacket; use pocketmine\scheduler\AsyncTask; use function assert; @@ -46,7 +45,7 @@ use function time; use const OPENSSL_ALGO_SHA384; class ProcessLoginTask extends AsyncTask{ - private const TLS_KEY_SESSION = "session"; + private const TLS_KEY_ON_COMPLETION = "completion"; public const MOJANG_ROOT_PUBLIC_KEY = "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8ELkixyLcwlZryUQcu1TvPOmI2B7vX83ndnWRUaXm74wFfa5f/lwQNTfrLVHa2PmenpGI6JhIMUJaWZrjmMj90NoKNFSNBuKdm8rYiXsfaz3K36x/1U26HpG0ZxK/V1V"; @@ -74,8 +73,11 @@ class ProcessLoginTask extends AsyncTask{ /** @var PublicKeyInterface|null */ private $clientPublicKey = null; - public function __construct(NetworkSession $session, LoginPacket $packet, bool $authRequired){ - $this->storeLocal(self::TLS_KEY_SESSION, $session); + /** + * @phpstan-var \Closure(bool $isAuthenticated, bool $authRequired, ?string $error, ?PublicKeyInterface $clientPublicKey) : void $onCompletion + */ + public function __construct(LoginPacket $packet, bool $authRequired, \Closure $onCompletion){ + $this->storeLocal(self::TLS_KEY_ON_COMPLETION, $onCompletion); $this->packet = $packet; $this->authRequired = $authRequired; } @@ -169,8 +171,11 @@ class ProcessLoginTask extends AsyncTask{ } public function onCompletion() : void{ - /** @var NetworkSession $session */ - $session = $this->fetchLocal(self::TLS_KEY_SESSION); - $session->setAuthenticationStatus($this->authenticated, $this->authRequired, $this->error, $this->clientPublicKey); + /** + * @var \Closure $callback + * @phpstan-var \Closure(bool, bool, ?string, ?PublicKeyInterface) : void $callback + */ + $callback = $this->fetchLocal(self::TLS_KEY_ON_COMPLETION); + $callback($this->authenticated, $this->authRequired, $this->error, $this->clientPublicKey); } } diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index 7777ff5c4a..7f18fbb681 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; -use pocketmine\entity\Skin; +use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; use pocketmine\event\player\PlayerPreLoginEvent; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\auth\ProcessLoginTask; @@ -59,14 +59,25 @@ class LoginPacketHandler extends PacketHandler{ * @phpstan-var \Closure(PlayerInfo) : void */ private $playerInfoConsumer; + /** + * @var \Closure + * @phpstan-var \Closure(bool, bool, ?string, ?PublicKeyInterface) : void + */ + private $authCallback; /** * @phpstan-param \Closure(PlayerInfo) : void $playerInfoConsumer + * @phpstan-param \Closure(bool $isAuthenticated, bool $authRequired, ?string $error, ?PublicKeyInterface $clientPubKey) : void $authCallback */ - public function __construct(Server $server, NetworkSession $session, \Closure $playerInfoConsumer){ + public function __construct(Server $server, NetworkSession $session, \Closure $playerInfoConsumer, \Closure $authCallback){ $this->session = $session; $this->server = $server; $this->playerInfoConsumer = $playerInfoConsumer; + $this->authCallback = $authCallback; + } + + private static function dummy() : void{ + echo PublicKeyInterface::class; //this prevents the import getting removed by tools that don't understand phpstan } public function handleLogin(LoginPacket $packet) : bool{ @@ -182,7 +193,7 @@ class LoginPacketHandler extends PacketHandler{ * @throws \InvalidArgumentException */ protected function processLogin(LoginPacket $packet, bool $authRequired) : void{ - $this->server->getAsyncPool()->submitTask(new ProcessLoginTask($this->session, $packet, $authRequired)); + $this->server->getAsyncPool()->submitTask(new ProcessLoginTask($packet, $authRequired, $this->authCallback)); $this->session->setHandler(NullPacketHandler::getInstance()); //drop packets received during login verification } From 843993f02b900dd97f413468a482b8d6b19c967d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 22 Apr 2020 13:45:29 +0100 Subject: [PATCH 1443/3224] Throw a specific exception for zlib decompression failure --- src/network/mcpe/NetworkSession.php | 3 +- .../compression/DecompressionException.php | 28 +++++++++++++++++++ src/network/mcpe/compression/Zlib.php | 8 ++++-- 3 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 src/network/mcpe/compression/DecompressionException.php diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 906dbef540..5da1cf2cfa 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -35,6 +35,7 @@ use pocketmine\form\Form; use pocketmine\math\Vector3; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\compression\CompressBatchPromise; +use pocketmine\network\mcpe\compression\DecompressionException; use pocketmine\network\mcpe\compression\Zlib; use pocketmine\network\mcpe\encryption\DecryptionException; use pocketmine\network\mcpe\encryption\NetworkCipher; @@ -280,7 +281,7 @@ class NetworkSession{ Timings::$playerNetworkReceiveDecompressTimer->startTiming(); try{ $stream = new PacketBatch(Zlib::decompress($payload)); - }catch(\ErrorException $e){ + }catch(DecompressionException $e){ $this->logger->debug("Failed to decompress packet: " . base64_encode($payload)); //TODO: this isn't incompatible game version if we already established protocol version throw BadPacketException::wrap($e, "Compressed packet batch decode error"); diff --git a/src/network/mcpe/compression/DecompressionException.php b/src/network/mcpe/compression/DecompressionException.php new file mode 100644 index 0000000000..dfaf7e50e8 --- /dev/null +++ b/src/network/mcpe/compression/DecompressionException.php @@ -0,0 +1,28 @@ + Date: Thu, 23 Apr 2020 14:11:48 +0100 Subject: [PATCH 1444/3224] the great airgapping of recipes and itemstacks --- src/crafting/CraftingManager.php | 54 ++++- src/entity/Human.php | 3 +- src/entity/object/ItemEntity.php | 3 +- src/network/mcpe/InventoryManager.php | 14 +- src/network/mcpe/NetworkSession.php | 12 +- src/network/mcpe/convert/TypeConverter.php | 124 ++++++++++++ .../mcpe/handler/InGamePacketHandler.php | 7 +- .../mcpe/handler/LoginPacketHandler.php | 1 + .../mcpe/protocol/AddItemActorPacket.php | 4 +- src/network/mcpe/protocol/AddPlayerPacket.php | 4 +- .../mcpe/protocol/CraftingDataPacket.php | 189 ++---------------- .../mcpe/protocol/CraftingEventPacket.php | 6 +- .../mcpe/protocol/InventoryContentPacket.php | 6 +- .../mcpe/protocol/InventorySlotPacket.php | 7 +- .../mcpe/protocol/MobArmorEquipmentPacket.php | 13 +- .../mcpe/protocol/MobEquipmentPacket.php | 6 +- .../protocol/types/inventory/ItemStack.php | 100 +++++++++ .../inventory/NetworkInventoryAction.php | 18 +- .../inventory/ReleaseItemTransactionData.php | 8 +- .../UseItemOnEntityTransactionData.php | 7 +- .../inventory/UseItemTransactionData.php | 7 +- .../protocol/types/recipe/FurnaceRecipe.php | 85 ++++++++ .../protocol/types/recipe/MultiRecipe.php | 50 +++++ .../types/recipe/RecipeIngredient.php | 52 +++++ .../types/recipe/RecipeWithTypeId.php | 41 ++++ .../protocol/types/recipe/ShapedRecipe.php | 151 ++++++++++++++ .../protocol/types/recipe/ShapelessRecipe.php | 123 ++++++++++++ .../mcpe/serializer/NetworkBinaryStream.php | 107 ++++------ src/world/particle/FloatingTextParticle.php | 4 +- 29 files changed, 907 insertions(+), 299 deletions(-) create mode 100644 src/network/mcpe/convert/TypeConverter.php create mode 100644 src/network/mcpe/protocol/types/inventory/ItemStack.php create mode 100644 src/network/mcpe/protocol/types/recipe/FurnaceRecipe.php create mode 100644 src/network/mcpe/protocol/types/recipe/MultiRecipe.php create mode 100644 src/network/mcpe/protocol/types/recipe/RecipeIngredient.php create mode 100644 src/network/mcpe/protocol/types/recipe/RecipeWithTypeId.php create mode 100644 src/network/mcpe/protocol/types/recipe/ShapedRecipe.php create mode 100644 src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index 4733f7df77..c3243176dd 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -26,13 +26,22 @@ namespace pocketmine\crafting; use pocketmine\item\Item; use pocketmine\network\mcpe\compression\CompressBatchPromise; use pocketmine\network\mcpe\compression\Zlib; +use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\PacketBatch; use pocketmine\network\mcpe\protocol\CraftingDataPacket; +use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; +use pocketmine\network\mcpe\protocol\types\recipe\FurnaceRecipe as ProtocolFurnaceRecipe; +use pocketmine\network\mcpe\protocol\types\recipe\RecipeIngredient; +use pocketmine\network\mcpe\protocol\types\recipe\ShapedRecipe as ProtocolShapedRecipe; +use pocketmine\network\mcpe\protocol\types\recipe\ShapelessRecipe as ProtocolShapelessRecipe; use pocketmine\timings\Timings; +use pocketmine\utils\Binary; +use pocketmine\utils\UUID; use function array_map; use function file_get_contents; use function json_decode; use function json_encode; +use function str_repeat; use function usort; use const DIRECTORY_SEPARATOR; @@ -101,19 +110,58 @@ class CraftingManager{ $pk = new CraftingDataPacket(); $pk->cleanRecipes = true; + $counter = 0; + $nullUUID = UUID::fromData(str_repeat("\x00", 16)); + $converter = TypeConverter::getInstance(); foreach($this->shapelessRecipes as $list){ foreach($list as $recipe){ - $pk->addShapelessRecipe($recipe); + $pk->entries[] = new ProtocolShapelessRecipe( + CraftingDataPacket::ENTRY_SHAPELESS, + Binary::writeInt($counter++), + array_map(function(Item $item) use ($converter) : RecipeIngredient{ + return $converter->coreItemStackToRecipeIngredient($item); + }, $recipe->getIngredientList()), + array_map(function(Item $item) use ($converter) : ItemStack{ + return $converter->coreItemStackToNet($item); + }, $recipe->getResults()), + $nullUUID, + "crafting_table", + 50 + ); } } foreach($this->shapedRecipes as $list){ foreach($list as $recipe){ - $pk->addShapedRecipe($recipe); + $inputs = []; + + for($row = 0, $height = $recipe->getHeight(); $row < $height; ++$row){ + for($column = 0, $width = $recipe->getWidth(); $column < $width; ++$column){ + $inputs[$row][$column] = $converter->coreItemStackToRecipeIngredient($recipe->getIngredient($column, $row)); + } + } + $pk->entries[] = $r = new ProtocolShapedRecipe( + CraftingDataPacket::ENTRY_SHAPED, + Binary::writeInt($counter++), + $inputs, + array_map(function(Item $item) use ($converter) : ItemStack{ + return $converter->coreItemStackToNet($item); + }, $recipe->getResults()), + $nullUUID, + "crafting_table", + 50 + ); } } foreach($this->furnaceRecipes as $recipe){ - $pk->addFurnaceRecipe($recipe); + $input = $converter->coreItemStackToNet($recipe->getInput()); + $pk->entries[] = new ProtocolFurnaceRecipe( + CraftingDataPacket::ENTRY_FURNACE_DATA, + $input->getId(), + $input->getMeta(), + $converter->coreItemStackToNet($recipe->getResult()), + "furnace" + ); } $this->craftingDataCache = new CompressBatchPromise(); diff --git a/src/entity/Human.php b/src/entity/Human.php index a3e1db0da6..c85e9ee575 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -41,6 +41,7 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; +use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\ActorEventPacket; use pocketmine\network\mcpe\protocol\AddPlayerPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; @@ -403,7 +404,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $pk->motion = $this->getMotion(); $pk->yaw = $this->location->yaw; $pk->pitch = $this->location->pitch; - $pk->item = $this->getInventory()->getItemInHand(); + $pk->item = TypeConverter::getInstance()->coreItemStackToNet($this->getInventory()->getItemInHand()); $pk->metadata = $this->getSyncedNetworkData(false); $player->getNetworkSession()->sendDataPacket($pk); diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index 32b2ba8058..6ddf055a3c 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -29,6 +29,7 @@ use pocketmine\event\entity\ItemSpawnEvent; use pocketmine\event\inventory\InventoryPickupItemEvent; use pocketmine\item\Item; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\AddItemActorPacket; use pocketmine\network\mcpe\protocol\TakeItemActorPacket; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; @@ -210,7 +211,7 @@ class ItemEntity extends Entity{ $pk->entityRuntimeId = $this->getId(); $pk->position = $this->location->asVector3(); $pk->motion = $this->getMotion(); - $pk->item = $this->getItem(); + $pk->item = TypeConverter::getInstance()->coreItemStackToNet($this->getItem()); $pk->metadata = $this->getSyncedNetworkData(false); $player->getNetworkSession()->sendDataPacket($pk); diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index 61f68142ef..b589e57408 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -34,6 +34,7 @@ use pocketmine\inventory\Inventory; use pocketmine\inventory\transaction\action\SlotChangeAction; use pocketmine\inventory\transaction\InventoryTransaction; use pocketmine\item\Item; +use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\ContainerClosePacket; use pocketmine\network\mcpe\protocol\ContainerOpenPacket; use pocketmine\network\mcpe\protocol\ContainerSetDataPacket; @@ -41,6 +42,7 @@ use pocketmine\network\mcpe\protocol\InventoryContentPacket; use pocketmine\network\mcpe\protocol\InventorySlotPacket; use pocketmine\network\mcpe\protocol\MobEquipmentPacket; use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; +use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes; use pocketmine\player\Player; use function array_search; @@ -159,7 +161,7 @@ class InventoryManager{ $currentItem = $inventory->getItem($slot); $clientSideItem = $this->initiatedSlotChanges[$windowId][$slot] ?? null; if($clientSideItem === null or !$clientSideItem->equalsExact($currentItem)){ - $this->session->sendDataPacket(InventorySlotPacket::create($windowId, $slot, $currentItem)); + $this->session->sendDataPacket(InventorySlotPacket::create($windowId, $slot, TypeConverter::getInstance()->coreItemStackToNet($currentItem))); } unset($this->initiatedSlotChanges[$windowId][$slot]); } @@ -169,7 +171,10 @@ class InventoryManager{ $windowId = $this->getWindowId($inventory); if($windowId !== null){ unset($this->initiatedSlotChanges[$windowId]); - $this->session->sendDataPacket(InventoryContentPacket::create($windowId, $inventory->getContents(true))); + $typeConverter = TypeConverter::getInstance(); + $this->session->sendDataPacket(InventoryContentPacket::create($windowId, array_map(function(Item $itemStack) use ($typeConverter) : ItemStack{ + return $typeConverter->coreItemStackToNet($itemStack); + }, $inventory->getContents(true)))); } } @@ -189,7 +194,7 @@ class InventoryManager{ public function syncSelectedHotbarSlot() : void{ $this->session->sendDataPacket(MobEquipmentPacket::create( $this->player->getId(), - $this->player->getInventory()->getItemInHand(), + TypeConverter::getInstance()->coreItemStackToNet($this->player->getInventory()->getItemInHand()), $this->player->getInventory()->getHeldItemIndex(), ContainerIds::INVENTORY )); @@ -197,9 +202,10 @@ class InventoryManager{ public function syncCreative() : void{ $items = []; + $typeConverter = TypeConverter::getInstance(); if(!$this->player->isSpectator()){ //fill it for all gamemodes except spectator foreach(CreativeInventory::getAll() as $i => $item){ - $items[$i] = clone $item; + $items[$i] = $typeConverter->coreItemStackToNet($item); } } diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 5da1cf2cfa..4b81e1c3a7 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -37,6 +37,7 @@ use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\compression\CompressBatchPromise; use pocketmine\network\mcpe\compression\DecompressionException; use pocketmine\network\mcpe\compression\Zlib; +use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\encryption\DecryptionException; use pocketmine\network\mcpe\encryption\NetworkCipher; use pocketmine\network\mcpe\encryption\PrepareEncryptionTask; @@ -790,12 +791,19 @@ class NetworkSession{ public function onMobEquipmentChange(Human $mob) : void{ //TODO: we could send zero for slot here because remote players don't need to know which slot was selected $inv = $mob->getInventory(); - $this->sendDataPacket(MobEquipmentPacket::create($mob->getId(), $inv->getItemInHand(), $inv->getHeldItemIndex(), ContainerIds::INVENTORY)); + $this->sendDataPacket(MobEquipmentPacket::create($mob->getId(), TypeConverter::getInstance()->coreItemStackToNet($inv->getItemInHand()), $inv->getHeldItemIndex(), ContainerIds::INVENTORY)); } public function onMobArmorChange(Living $mob) : void{ $inv = $mob->getArmorInventory(); - $this->sendDataPacket(MobArmorEquipmentPacket::create($mob->getId(), $inv->getHelmet(), $inv->getChestplate(), $inv->getLeggings(), $inv->getBoots())); + $converter = TypeConverter::getInstance(); + $this->sendDataPacket(MobArmorEquipmentPacket::create( + $mob->getId(), + $converter->coreItemStackToNet($inv->getHelmet()), + $converter->coreItemStackToNet($inv->getChestplate()), + $converter->coreItemStackToNet($inv->getLeggings()), + $converter->coreItemStackToNet($inv->getBoots()) + )); } public function syncPlayerList() : void{ diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php new file mode 100644 index 0000000000..775095a567 --- /dev/null +++ b/src/network/mcpe/convert/TypeConverter.php @@ -0,0 +1,124 @@ +getMeta(); + return new RecipeIngredient($itemStack->getId(), $meta === -1 ? 0x7fff : $meta, $itemStack->getCount()); + } + + public function recipeIngredientToCoreItemStack(RecipeIngredient $ingredient) : Item{ + $meta = $ingredient->getMeta(); + return ItemFactory::get($ingredient->getId(), $meta === 0x7fff ? -1 : $meta, $ingredient->getCount()); + } + + public function coreItemStackToNet(Item $itemStack) : ItemStack{ + $nbt = null; + if($itemStack->hasNamedTag()){ + $nbt = clone $itemStack->getNamedTag(); + } + if($itemStack instanceof Durable and $itemStack->getDamage() > 0){ + if($nbt !== null){ + if(($existing = $nbt->getTag(self::DAMAGE_TAG)) !== null){ + $nbt->removeTag(self::DAMAGE_TAG); + $nbt->setTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION, $existing); + } + }else{ + $nbt = new CompoundTag(); + } + $nbt->setInt(self::DAMAGE_TAG, $itemStack->getDamage()); + } + $id = $itemStack->getId(); + $meta = $itemStack->getMeta(); + + return new ItemStack( + $id, + $meta === -1 ? 0x7fff : $meta, + $itemStack->getCount(), + $nbt, + [], + [], + $id === ItemIds::SHIELD ? 0 : null + ); + } + + public function netItemStackToCore(ItemStack $itemStack) : Item{ + $compound = $itemStack->getNbt(); + $meta = $itemStack->getMeta(); + + if($compound !== null){ + $compound = clone $compound; + if($compound->hasTag(self::DAMAGE_TAG, IntTag::class)){ + $meta = $compound->getInt(self::DAMAGE_TAG); + $compound->removeTag(self::DAMAGE_TAG); + if($compound->count() === 0){ + $compound = null; + goto end; + } + } + if(($conflicted = $compound->getTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION)) !== null){ + $compound->removeTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION); + $compound->setTag(self::DAMAGE_TAG, $conflicted); + } + } + + end: + return ItemFactory::get( + $itemStack->getId(), + $meta !== 0x7fff ? $meta : -1, + $itemStack->getCount(), + $compound + ); + } +} \ No newline at end of file diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 75b124f850..70c03c1c5c 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -38,6 +38,7 @@ use pocketmine\math\Vector3; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\StringTag; use pocketmine\network\BadPacketException; +use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\ActorEventPacket; use pocketmine\network\mcpe\protocol\ActorFallPacket; @@ -205,14 +206,16 @@ class InGamePacketHandler extends PacketHandler{ $isCrafting = false; $isFinalCraftingPart = false; foreach($data->getActions() as $networkInventoryAction){ + $old = TypeConverter::getInstance()->netItemStackToCore($networkInventoryAction->oldItem); + $new = TypeConverter::getInstance()->netItemStackToCore($networkInventoryAction->newItem); if( $networkInventoryAction->sourceType === NetworkInventoryAction::SOURCE_CONTAINER and $networkInventoryAction->windowId === ContainerIds::UI and $networkInventoryAction->inventorySlot === 50 and - !$networkInventoryAction->oldItem->equalsExact($networkInventoryAction->newItem) + !$old->equalsExact($new) ){ $isCrafting = true; - if(!$networkInventoryAction->oldItem->isNull() and $networkInventoryAction->newItem->isNull()){ + if(!$old->isNull() and $new->isNull()){ $isFinalCraftingPart = true; } }elseif( diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index 7f18fbb681..87d720df1f 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -43,6 +43,7 @@ use pocketmine\player\Player; use pocketmine\player\PlayerInfo; use pocketmine\Server; use pocketmine\utils\UUID; +use function array_map; use function base64_decode; /** diff --git a/src/network/mcpe/protocol/AddItemActorPacket.php b/src/network/mcpe/protocol/AddItemActorPacket.php index 71ceab3911..e174bad9f7 100644 --- a/src/network/mcpe/protocol/AddItemActorPacket.php +++ b/src/network/mcpe/protocol/AddItemActorPacket.php @@ -25,10 +25,10 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; +use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class AddItemActorPacket extends DataPacket implements ClientboundPacket{ @@ -38,7 +38,7 @@ class AddItemActorPacket extends DataPacket implements ClientboundPacket{ public $entityUniqueId = null; //TODO /** @var int */ public $entityRuntimeId; - /** @var Item */ + /** @var ItemStack */ public $item; /** @var Vector3 */ public $position; diff --git a/src/network/mcpe/protocol/AddPlayerPacket.php b/src/network/mcpe/protocol/AddPlayerPacket.php index 453b10dbed..6e1475fc7b 100644 --- a/src/network/mcpe/protocol/AddPlayerPacket.php +++ b/src/network/mcpe/protocol/AddPlayerPacket.php @@ -25,11 +25,11 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; +use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\UUID; use function count; @@ -57,7 +57,7 @@ class AddPlayerPacket extends DataPacket implements ClientboundPacket{ public $yaw = 0.0; /** @var float|null */ public $headYaw = null; //TODO - /** @var Item */ + /** @var ItemStack */ public $item; /** * @var MetadataProperty[] diff --git a/src/network/mcpe/protocol/CraftingDataPacket.php b/src/network/mcpe/protocol/CraftingDataPacket.php index af504e8eda..f94cb40ad9 100644 --- a/src/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/network/mcpe/protocol/CraftingDataPacket.php @@ -25,21 +25,17 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\crafting\FurnaceRecipe; -use pocketmine\crafting\ShapedRecipe; -use pocketmine\crafting\ShapelessRecipe; -use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\PotionContainerChangeRecipe; use pocketmine\network\mcpe\protocol\types\PotionTypeRecipe; +use pocketmine\network\mcpe\protocol\types\recipe\FurnaceRecipe; +use pocketmine\network\mcpe\protocol\types\recipe\MultiRecipe; +use pocketmine\network\mcpe\protocol\types\recipe\RecipeWithTypeId; +use pocketmine\network\mcpe\protocol\types\recipe\ShapedRecipe; +use pocketmine\network\mcpe\protocol\types\recipe\ShapelessRecipe; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; -#ifndef COMPILE -use pocketmine\utils\Binary; -#endif use function count; -use function str_repeat; class CraftingDataPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CRAFTING_DATA_PACKET; @@ -48,12 +44,12 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{ public const ENTRY_SHAPED = 1; public const ENTRY_FURNACE = 2; public const ENTRY_FURNACE_DATA = 3; - public const ENTRY_MULTI = 4; //TODO - public const ENTRY_SHULKER_BOX = 5; //TODO - public const ENTRY_SHAPELESS_CHEMISTRY = 6; //TODO - public const ENTRY_SHAPED_CHEMISTRY = 7; //TODO + public const ENTRY_MULTI = 4; + public const ENTRY_SHULKER_BOX = 5; + public const ENTRY_SHAPELESS_CHEMISTRY = 6; + public const ENTRY_SHAPED_CHEMISTRY = 7; - /** @var object[] */ + /** @var RecipeWithTypeId[] */ public $entries = []; /** @var PotionTypeRecipe[] */ public $potionTypeRecipes = []; @@ -62,88 +58,31 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{ /** @var bool */ public $cleanRecipes = false; - /** @var mixed[][] */ - public $decodedEntries = []; - protected function decodePayload(NetworkBinaryStream $in) : void{ - $this->decodedEntries = []; $recipeCount = $in->getUnsignedVarInt(); for($i = 0; $i < $recipeCount; ++$i){ - $entry = []; - $entry["type"] = $recipeType = $in->getVarInt(); + $recipeType = $in->getVarInt(); switch($recipeType){ case self::ENTRY_SHAPELESS: case self::ENTRY_SHULKER_BOX: case self::ENTRY_SHAPELESS_CHEMISTRY: - $entry["recipe_id"] = $in->getString(); - $ingredientCount = $in->getUnsignedVarInt(); - /** @var Item */ - $entry["input"] = []; - for($j = 0; $j < $ingredientCount; ++$j){ - $entry["input"][] = $input = $in->getRecipeIngredient(); - $input->setCount(1); //TODO HACK: they send a useless count field which breaks the PM crafting system because it isn't always 1 - } - $resultCount = $in->getUnsignedVarInt(); - $entry["output"] = []; - for($k = 0; $k < $resultCount; ++$k){ - $entry["output"][] = $in->getSlot(); - } - $entry["uuid"] = $in->getUUID()->toString(); - $entry["block"] = $in->getString(); - $entry["priority"] = $in->getVarInt(); - + $this->entries[] = ShapelessRecipe::decode($recipeType, $in); break; case self::ENTRY_SHAPED: case self::ENTRY_SHAPED_CHEMISTRY: - $entry["recipe_id"] = $in->getString(); - $entry["width"] = $in->getVarInt(); - $entry["height"] = $in->getVarInt(); - $count = $entry["width"] * $entry["height"]; - $entry["input"] = []; - for($j = 0; $j < $count; ++$j){ - $entry["input"][] = $input = $in->getRecipeIngredient(); - $input->setCount(1); //TODO HACK: they send a useless count field which breaks the PM crafting system - } - $resultCount = $in->getUnsignedVarInt(); - $entry["output"] = []; - for($k = 0; $k < $resultCount; ++$k){ - $entry["output"][] = $in->getSlot(); - } - $entry["uuid"] = $in->getUUID()->toString(); - $entry["block"] = $in->getString(); - $entry["priority"] = $in->getVarInt(); - + $this->entries[] = ShapedRecipe::decode($recipeType, $in); break; case self::ENTRY_FURNACE: case self::ENTRY_FURNACE_DATA: - $inputId = $in->getVarInt(); - $inputData = -1; - if($recipeType === self::ENTRY_FURNACE_DATA){ - $inputData = $in->getVarInt(); - if($inputData === 0x7fff){ - $inputData = -1; - } - } - try{ - $entry["input"] = ItemFactory::get($inputId, $inputData); - }catch(\InvalidArgumentException $e){ - throw BadPacketException::wrap($e); - } - $entry["output"] = $out = $in->getSlot(); - if($out->getMeta() === 0x7fff){ - $entry["output"] = ItemFactory::get($out->getId(), 0); //TODO HACK: some 1.12 furnace recipe outputs have wildcard damage values - } - $entry["block"] = $in->getString(); - + $this->entries[] = FurnaceRecipe::decode($recipeType, $in); break; case self::ENTRY_MULTI: - $entry["uuid"] = $in->getUUID()->toString(); + $this->entries[] = MultiRecipe::decode($recipeType, $in); break; default: throw new BadPacketException("Unhandled recipe type $recipeType!"); //do not continue attempting to decode } - $this->decodedEntries[] = $entry; } for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ $input = $in->getVarInt(); @@ -160,105 +99,11 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{ $this->cleanRecipes = $in->getBool(); } - /** - * @param object $entry - */ - private static function writeEntry($entry, NetworkBinaryStream $stream, int $pos) : int{ - if($entry instanceof ShapelessRecipe){ - return self::writeShapelessRecipe($entry, $stream, $pos); - }elseif($entry instanceof ShapedRecipe){ - return self::writeShapedRecipe($entry, $stream, $pos); - }elseif($entry instanceof FurnaceRecipe){ - return self::writeFurnaceRecipe($entry, $stream); - } - //TODO: add MultiRecipe - - return -1; - } - - private static function writeShapelessRecipe(ShapelessRecipe $recipe, NetworkBinaryStream $stream, int $pos) : int{ - $stream->putString(Binary::writeInt($pos)); //some kind of recipe ID, doesn't matter what it is as long as it's unique - $stream->putUnsignedVarInt($recipe->getIngredientCount()); - foreach($recipe->getIngredientList() as $item){ - $stream->putRecipeIngredient($item); - } - - $results = $recipe->getResults(); - $stream->putUnsignedVarInt(count($results)); - foreach($results as $item){ - $stream->putSlot($item); - } - - $stream->put(str_repeat("\x00", 16)); //Null UUID - $stream->putString("crafting_table"); //TODO: blocktype (no prefix) (this might require internal API breaks) - $stream->putVarInt(50); //TODO: priority - - return CraftingDataPacket::ENTRY_SHAPELESS; - } - - private static function writeShapedRecipe(ShapedRecipe $recipe, NetworkBinaryStream $stream, int $pos) : int{ - $stream->putString(Binary::writeInt($pos)); //some kind of recipe ID, doesn't matter what it is as long as it's unique - $stream->putVarInt($recipe->getWidth()); - $stream->putVarInt($recipe->getHeight()); - - for($z = 0; $z < $recipe->getHeight(); ++$z){ - for($x = 0; $x < $recipe->getWidth(); ++$x){ - $stream->putRecipeIngredient($recipe->getIngredient($x, $z)); - } - } - - $results = $recipe->getResults(); - $stream->putUnsignedVarInt(count($results)); - foreach($results as $item){ - $stream->putSlot($item); - } - - $stream->put(str_repeat("\x00", 16)); //Null UUID - $stream->putString("crafting_table"); //TODO: blocktype (no prefix) (this might require internal API breaks) - $stream->putVarInt(50); //TODO: priority - - return CraftingDataPacket::ENTRY_SHAPED; - } - - private static function writeFurnaceRecipe(FurnaceRecipe $recipe, NetworkBinaryStream $stream) : int{ - $stream->putVarInt($recipe->getInput()->getId()); - $result = CraftingDataPacket::ENTRY_FURNACE; - if(!$recipe->getInput()->hasAnyDamageValue()){ //Data recipe - $stream->putVarInt($recipe->getInput()->getMeta()); - $result = CraftingDataPacket::ENTRY_FURNACE_DATA; - } - $stream->putSlot($recipe->getResult()); - $stream->putString("furnace"); //TODO: blocktype (no prefix) (this might require internal API breaks) - return $result; - } - - public function addShapelessRecipe(ShapelessRecipe $recipe) : void{ - $this->entries[] = $recipe; - } - - public function addShapedRecipe(ShapedRecipe $recipe) : void{ - $this->entries[] = $recipe; - } - - public function addFurnaceRecipe(FurnaceRecipe $recipe) : void{ - $this->entries[] = $recipe; - } - protected function encodePayload(NetworkBinaryStream $out) : void{ $out->putUnsignedVarInt(count($this->entries)); - - $writer = new NetworkBinaryStream(); - $counter = 0; foreach($this->entries as $d){ - $entryType = self::writeEntry($d, $writer, $counter++); - if($entryType >= 0){ - $out->putVarInt($entryType); - $out->put($writer->getBuffer()); - }else{ - $out->putVarInt(-1); - } - - $writer->reset(); + $out->putVarInt($d->getTypeId()); + $d->encode($out); } $out->putUnsignedVarInt(count($this->potionTypeRecipes)); foreach($this->potionTypeRecipes as $recipe){ diff --git a/src/network/mcpe/protocol/CraftingEventPacket.php b/src/network/mcpe/protocol/CraftingEventPacket.php index b932f839b2..c9f357cf21 100644 --- a/src/network/mcpe/protocol/CraftingEventPacket.php +++ b/src/network/mcpe/protocol/CraftingEventPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\item\Item; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\UUID; use function count; @@ -40,9 +40,9 @@ class CraftingEventPacket extends DataPacket implements ServerboundPacket{ public $type; /** @var UUID */ public $id; - /** @var Item[] */ + /** @var ItemStack[] */ public $input = []; - /** @var Item[] */ + /** @var ItemStack[] */ public $output = []; protected function decodePayload(NetworkBinaryStream $in) : void{ diff --git a/src/network/mcpe/protocol/InventoryContentPacket.php b/src/network/mcpe/protocol/InventoryContentPacket.php index 2490b9b793..28b28d954f 100644 --- a/src/network/mcpe/protocol/InventoryContentPacket.php +++ b/src/network/mcpe/protocol/InventoryContentPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\item\Item; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; @@ -35,11 +35,11 @@ class InventoryContentPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $windowId; - /** @var Item[] */ + /** @var ItemStack[] */ public $items = []; /** - * @param Item[] $items + * @param ItemStack[] $items * * @return InventoryContentPacket */ diff --git a/src/network/mcpe/protocol/InventorySlotPacket.php b/src/network/mcpe/protocol/InventorySlotPacket.php index 24632bc6e5..485226bae3 100644 --- a/src/network/mcpe/protocol/InventorySlotPacket.php +++ b/src/network/mcpe/protocol/InventorySlotPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\item\Item; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class InventorySlotPacket extends DataPacket implements ClientboundPacket{ @@ -36,14 +36,15 @@ class InventorySlotPacket extends DataPacket implements ClientboundPacket{ public $windowId; /** @var int */ public $inventorySlot; - /** @var Item */ + /** @var ItemStack */ public $item; - public static function create(int $windowId, int $slot, Item $item) : self{ + public static function create(int $windowId, int $slot, ItemStack $item) : self{ $result = new self; $result->inventorySlot = $slot; $result->item = $item; $result->windowId = $windowId; + return $result; } diff --git a/src/network/mcpe/protocol/MobArmorEquipmentPacket.php b/src/network/mcpe/protocol/MobArmorEquipmentPacket.php index 1d3aba6af4..255350bc21 100644 --- a/src/network/mcpe/protocol/MobArmorEquipmentPacket.php +++ b/src/network/mcpe/protocol/MobArmorEquipmentPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\item\Item; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class MobArmorEquipmentPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -37,22 +37,23 @@ class MobArmorEquipmentPacket extends DataPacket implements ClientboundPacket, S //this intentionally doesn't use an array because we don't want any implicit dependencies on internal order - /** @var Item */ + /** @var ItemStack */ public $head; - /** @var Item */ + /** @var ItemStack */ public $chest; - /** @var Item */ + /** @var ItemStack */ public $legs; - /** @var Item */ + /** @var ItemStack */ public $feet; - public static function create(int $entityRuntimeId, Item $head, Item $chest, Item $legs, Item $feet) : self{ + public static function create(int $entityRuntimeId, ItemStack $head, ItemStack $chest, ItemStack $legs, ItemStack $feet) : self{ $result = new self; $result->entityRuntimeId = $entityRuntimeId; $result->head = $head; $result->chest = $chest; $result->legs = $legs; $result->feet = $feet; + return $result; } diff --git a/src/network/mcpe/protocol/MobEquipmentPacket.php b/src/network/mcpe/protocol/MobEquipmentPacket.php index 53e87632c6..69d0f1ce48 100644 --- a/src/network/mcpe/protocol/MobEquipmentPacket.php +++ b/src/network/mcpe/protocol/MobEquipmentPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\item\Item; use pocketmine\network\mcpe\handler\PacketHandler; +use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class MobEquipmentPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -34,7 +34,7 @@ class MobEquipmentPacket extends DataPacket implements ClientboundPacket, Server /** @var int */ public $entityRuntimeId; - /** @var Item */ + /** @var ItemStack */ public $item; /** @var int */ public $inventorySlot; @@ -43,7 +43,7 @@ class MobEquipmentPacket extends DataPacket implements ClientboundPacket, Server /** @var int */ public $windowId = 0; - public static function create(int $entityRuntimeId, Item $item, int $inventorySlot, int $windowId) : self{ + public static function create(int $entityRuntimeId, ItemStack $item, int $inventorySlot, int $windowId) : self{ $result = new self; $result->entityRuntimeId = $entityRuntimeId; $result->item = $item; diff --git a/src/network/mcpe/protocol/types/inventory/ItemStack.php b/src/network/mcpe/protocol/types/inventory/ItemStack.php new file mode 100644 index 0000000000..1a745a0cb2 --- /dev/null +++ b/src/network/mcpe/protocol/types/inventory/ItemStack.php @@ -0,0 +1,100 @@ +id = $id; + $this->meta = $meta; + $this->count = $count; + $this->canPlaceOn = $canPlaceOn; + $this->canDestroy = $canDestroy; + $this->nbt = $nbt; + $this->shieldBlockingTick = $shieldBlockingTick; + } + + public static function null() : self{ + return new self(0, 0, 0, null, [], [], null); + } + + public function getId() : int{ + return $this->id; + } + + public function getMeta() : int{ + return $this->meta; + } + + public function getCount() : int{ + return $this->count; + } + + /** + * @return string[] + */ + public function getCanPlaceOn() : array{ + return $this->canPlaceOn; + } + + /** + * @return string[] + */ + public function getCanDestroy() : array{ + return $this->canDestroy; + } + + public function getNbt() : ?CompoundTag{ + return $this->nbt; + } + + public function getShieldBlockingTick() : ?int{ + return $this->shieldBlockingTick; + } +} diff --git a/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php b/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php index a4a2f46b81..db8b34db9c 100644 --- a/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php +++ b/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php @@ -31,8 +31,8 @@ use pocketmine\inventory\transaction\action\DestroyItemAction; use pocketmine\inventory\transaction\action\DropItemAction; use pocketmine\inventory\transaction\action\InventoryAction; use pocketmine\inventory\transaction\action\SlotChangeAction; -use pocketmine\item\Item; use pocketmine\network\BadPacketException; +use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\player\Player; use pocketmine\utils\BinaryDataException; @@ -82,9 +82,9 @@ class NetworkInventoryAction{ public $sourceFlags = 0; /** @var int */ public $inventorySlot; - /** @var Item */ + /** @var ItemStack */ public $oldItem; - /** @var Item */ + /** @var ItemStack */ public $newItem; /** @@ -150,7 +150,9 @@ class NetworkInventoryAction{ * @throws \UnexpectedValueException */ public function createInventoryAction(Player $player) : ?InventoryAction{ - if($this->oldItem->equalsExact($this->newItem)){ + $old = TypeConverter::getInstance()->netItemStackToCore($this->oldItem); + $new = TypeConverter::getInstance()->netItemStackToCore($this->newItem); + if($old->equalsExact($new)){ //filter out useless noise in 1.13 return null; } @@ -180,7 +182,7 @@ class NetworkInventoryAction{ $slot = $this->inventorySlot; } if($window !== null){ - return new SlotChangeAction($window, $slot, $this->oldItem, $this->newItem); + return new SlotChangeAction($window, $slot, $old, $new); } throw new \UnexpectedValueException("No open container with window ID $this->windowId"); @@ -189,13 +191,13 @@ class NetworkInventoryAction{ throw new \UnexpectedValueException("Only expecting drop-item world actions from the client!"); } - return new DropItemAction($this->newItem); + return new DropItemAction($new); case self::SOURCE_CREATIVE: switch($this->inventorySlot){ case self::ACTION_MAGIC_SLOT_CREATIVE_DELETE_ITEM: - return new DestroyItemAction($this->newItem); + return new DestroyItemAction($new); case self::ACTION_MAGIC_SLOT_CREATIVE_CREATE_ITEM: - return new CreateItemAction($this->oldItem); + return new CreateItemAction($new); default: throw new \UnexpectedValueException("Unexpected creative action type $this->inventorySlot"); diff --git a/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php b/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php index b0d8a4f6df..5b399b0541 100644 --- a/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\inventory; -use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; @@ -36,7 +35,7 @@ class ReleaseItemTransactionData extends TransactionData{ private $actionType; /** @var int */ private $hotbarSlot; - /** @var Item */ + /** @var ItemStack */ private $itemInHand; /** @var Vector3 */ private $headPos; @@ -49,7 +48,7 @@ class ReleaseItemTransactionData extends TransactionData{ return $this->hotbarSlot; } - public function getItemInHand() : Item{ + public function getItemInHand() : ItemStack{ return $this->itemInHand; } @@ -78,13 +77,14 @@ class ReleaseItemTransactionData extends TransactionData{ /** * @param NetworkInventoryAction[] $actions */ - public static function new(array $actions, int $actionType, int $hotbarSlot, Item $itemInHand, Vector3 $headPos) : self{ + public static function new(array $actions, int $actionType, int $hotbarSlot, ItemStack $itemInHand, Vector3 $headPos) : self{ $result = new self; $result->actions = $actions; $result->actionType = $actionType; $result->hotbarSlot = $hotbarSlot; $result->itemInHand = $itemInHand; $result->headPos = $headPos; + return $result; } } diff --git a/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php b/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php index c53408cd0f..005fc14096 100644 --- a/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\inventory; -use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; @@ -38,7 +37,7 @@ class UseItemOnEntityTransactionData extends TransactionData{ private $actionType; /** @var int */ private $hotbarSlot; - /** @var Item */ + /** @var ItemStack */ private $itemInHand; /** @var Vector3 */ private $playerPos; @@ -57,7 +56,7 @@ class UseItemOnEntityTransactionData extends TransactionData{ return $this->hotbarSlot; } - public function getItemInHand() : Item{ + public function getItemInHand() : ItemStack{ return $this->itemInHand; } @@ -94,7 +93,7 @@ class UseItemOnEntityTransactionData extends TransactionData{ /** * @param NetworkInventoryAction[] $actions */ - public static function new(array $actions, int $entityRuntimeId, int $actionType, int $hotbarSlot, Item $itemInHand, Vector3 $playerPos, Vector3 $clickPos) : self{ + public static function new(array $actions, int $entityRuntimeId, int $actionType, int $hotbarSlot, ItemStack $itemInHand, Vector3 $playerPos, Vector3 $clickPos) : self{ $result = new self; $result->actions = $actions; $result->entityRuntimeId = $entityRuntimeId; diff --git a/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php b/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php index 8131b6aa07..71d832b1ee 100644 --- a/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\inventory; -use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; @@ -41,7 +40,7 @@ class UseItemTransactionData extends TransactionData{ private $face; /** @var int */ private $hotbarSlot; - /** @var Item */ + /** @var ItemStack */ private $itemInHand; /** @var Vector3 */ private $playerPos; @@ -66,7 +65,7 @@ class UseItemTransactionData extends TransactionData{ return $this->hotbarSlot; } - public function getItemInHand() : Item{ + public function getItemInHand() : ItemStack{ return $this->itemInHand; } @@ -112,7 +111,7 @@ class UseItemTransactionData extends TransactionData{ /** * @param NetworkInventoryAction[] $actions */ - public static function new(array $actions, int $actionType, Vector3 $blockPos, int $face, int $hotbarSlot, Item $itemInHand, Vector3 $playerPos, Vector3 $clickPos, int $blockRuntimeId) : self{ + public static function new(array $actions, int $actionType, Vector3 $blockPos, int $face, int $hotbarSlot, ItemStack $itemInHand, Vector3 $playerPos, Vector3 $clickPos, int $blockRuntimeId) : self{ $result = new self; $result->actions = $actions; $result->actionType = $actionType; diff --git a/src/network/mcpe/protocol/types/recipe/FurnaceRecipe.php b/src/network/mcpe/protocol/types/recipe/FurnaceRecipe.php new file mode 100644 index 0000000000..163e54668d --- /dev/null +++ b/src/network/mcpe/protocol/types/recipe/FurnaceRecipe.php @@ -0,0 +1,85 @@ +inputId = $inputId; + $this->inputMeta = $inputMeta; + $this->result = $result; + $this->blockName = $blockName; + } + + public function getInputId() : int{ + return $this->inputId; + } + + public function getInputMeta() : ?int{ + return $this->inputMeta; + } + + public function getResult() : ItemStack{ + return $this->result; + } + + public function getBlockName() : string{ + return $this->blockName; + } + + public static function decode(int $typeId, NetworkBinaryStream $in) : self{ + $inputId = $in->getVarInt(); + $inputData = null; + if($typeId === CraftingDataPacket::ENTRY_FURNACE_DATA){ + $inputData = $in->getVarInt(); + } + $output = $in->getSlot(); + $block = $in->getString(); + + return new self($typeId, $inputId, $inputData, $output, $block); + } + + public function encode(NetworkBinaryStream $out) : void{ + $out->putVarInt($this->inputId); + if($this->getTypeId() === CraftingDataPacket::ENTRY_FURNACE_DATA){ + $out->putVarInt($this->inputMeta); + } + $out->putSlot($this->result); + $out->putString($this->blockName); + } +} diff --git a/src/network/mcpe/protocol/types/recipe/MultiRecipe.php b/src/network/mcpe/protocol/types/recipe/MultiRecipe.php new file mode 100644 index 0000000000..24bc370d70 --- /dev/null +++ b/src/network/mcpe/protocol/types/recipe/MultiRecipe.php @@ -0,0 +1,50 @@ +recipeId = $recipeId; + } + + public function getRecipeId() : UUID{ + return $this->recipeId; + } + + public static function decode(int $typeId, NetworkBinaryStream $in) : self{ + return new self($typeId, $in->getUUID()); + } + + public function encode(NetworkBinaryStream $out) : void{ + $out->putUUID($this->recipeId); + } +} diff --git a/src/network/mcpe/protocol/types/recipe/RecipeIngredient.php b/src/network/mcpe/protocol/types/recipe/RecipeIngredient.php new file mode 100644 index 0000000000..1349e26343 --- /dev/null +++ b/src/network/mcpe/protocol/types/recipe/RecipeIngredient.php @@ -0,0 +1,52 @@ +id = $id; + $this->meta = $meta; + $this->count = $count; + } + + public function getId() : int{ + return $this->id; + } + + public function getMeta() : int{ + return $this->meta; + } + + public function getCount() : int{ + return $this->count; + } +} diff --git a/src/network/mcpe/protocol/types/recipe/RecipeWithTypeId.php b/src/network/mcpe/protocol/types/recipe/RecipeWithTypeId.php new file mode 100644 index 0000000000..9b61c0c146 --- /dev/null +++ b/src/network/mcpe/protocol/types/recipe/RecipeWithTypeId.php @@ -0,0 +1,41 @@ +typeId = $typeId; + } + + final public function getTypeId() : int{ + return $this->typeId; + } + + abstract public function encode(NetworkBinaryStream $out) : void; +} diff --git a/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php b/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php new file mode 100644 index 0000000000..b18e822462 --- /dev/null +++ b/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php @@ -0,0 +1,151 @@ + 3){ + throw new \InvalidArgumentException("Expected 1, 2 or 3 input rows"); + } + $columns = null; + foreach($input as $rowNumber => $row){ + if($columns === null){ + $columns = count($row); + }elseif(count($row) !== $columns){ + throw new \InvalidArgumentException("Expected each row to be $columns columns, but have " . count($row) . " in row $rowNumber"); + } + } + $this->recipeId = $recipeId; + $this->input = $input; + $this->output = $output; + $this->blockName = $blockType; + $this->priority = $priority; + $this->uuid = $uuid; + } + + public function getRecipeId() : string{ + return $this->recipeId; + } + + public function getWidth() : int{ + return count($this->input[0]); + } + + public function getHeight() : int{ + return count($this->input); + } + + /** + * @return RecipeIngredient[][] + */ + public function getInput() : array{ + return $this->input; + } + + /** + * @return ItemStack[] + */ + public function getOutput() : array{ + return $this->output; + } + + public function getUuid() : UUID{ + return $this->uuid; + } + + public function getBlockName() : string{ + return $this->blockName; + } + + public function getPriority() : int{ + return $this->priority; + } + + public static function decode(int $recipeType, NetworkBinaryStream $in) : self{ + $recipeId = $in->getString(); + $width = $in->getVarInt(); + $height = $in->getVarInt(); + $input = []; + for($row = 0; $row < $height; ++$row){ + for($column = 0; $column < $width; ++$column){ + $input[$row][$column] = $in->getRecipeIngredient(); + } + } + + $output = []; + for($k = 0, $resultCount = $in->getUnsignedVarInt(); $k < $resultCount; ++$k){ + $output[] = $in->getSlot(); + } + $uuid = $in->getUUID(); + $block = $in->getString(); + $priority = $in->getVarInt(); + + return new self($recipeType, $recipeId, $input, $output, $uuid, $block, $priority); + } + + public function encode(NetworkBinaryStream $out) : void{ + $out->putString($this->recipeId); + $out->putVarInt($this->getWidth()); + $out->putVarInt($this->getHeight()); + foreach($this->input as $row){ + foreach($row as $ingredient){ + $out->putRecipeIngredient($ingredient); + } + } + + $out->putUnsignedVarInt(count($this->output)); + foreach($this->output as $item){ + $out->putSlot($item); + } + + $out->putUUID($this->uuid); + $out->putString($this->blockName); + $out->putVarInt($this->priority); + } +} diff --git a/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php b/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php new file mode 100644 index 0000000000..d91d1f4e6e --- /dev/null +++ b/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php @@ -0,0 +1,123 @@ +recipeId = $recipeId; + $this->inputs = $inputs; + $this->outputs = $outputs; + $this->uuid = $uuid; + $this->blockName = $blockName; + $this->priority = $priority; + } + + public function getRecipeId() : string{ + return $this->recipeId; + } + + /** + * @return RecipeIngredient[] + */ + public function getInputs() : array{ + return $this->inputs; + } + + /** + * @return ItemStack[] + */ + public function getOutputs() : array{ + return $this->outputs; + } + + public function getUuid() : UUID{ + return $this->uuid; + } + + public function getBlockName() : string{ + return $this->blockName; + } + + public function getPriority() : int{ + return $this->priority; + } + + public static function decode(int $recipeType, NetworkBinaryStream $in) : self{ + $recipeId = $in->getString(); + $input = []; + for($j = 0, $ingredientCount = $in->getUnsignedVarInt(); $j < $ingredientCount; ++$j){ + $input[] = $in->getRecipeIngredient(); + } + $output = []; + for($k = 0, $resultCount = $in->getUnsignedVarInt(); $k < $resultCount; ++$k){ + $output[] = $in->getSlot(); + } + $uuid = $in->getUUID(); + $block = $in->getString(); + $priority = $in->getVarInt(); + + return new self($recipeType, $recipeId, $input, $output, $uuid, $block, $priority); + } + + public function encode(NetworkBinaryStream $out) : void{ + $out->putString($this->recipeId); + $out->putUnsignedVarInt(count($this->inputs)); + foreach($this->inputs as $item){ + $out->putRecipeIngredient($item); + } + + $out->putUnsignedVarInt(count($this->outputs)); + foreach($this->outputs as $item){ + $out->putSlot($item); + } + + $out->putUUID($this->uuid); + $out->putString($this->blockName); + $out->putVarInt($this->priority); + } +} diff --git a/src/network/mcpe/serializer/NetworkBinaryStream.php b/src/network/mcpe/serializer/NetworkBinaryStream.php index 29de90a4d7..4e0f2116aa 100644 --- a/src/network/mcpe/serializer/NetworkBinaryStream.php +++ b/src/network/mcpe/serializer/NetworkBinaryStream.php @@ -25,14 +25,10 @@ namespace pocketmine\network\mcpe\serializer; #include -use pocketmine\item\Durable; -use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\item\ItemIds; use pocketmine\math\Vector3; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\TreeRoot; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; @@ -48,8 +44,10 @@ use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\ShortMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\StringMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\Vec3MetadataProperty; +use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\protocol\types\PersonaPieceTintColor; use pocketmine\network\mcpe\protocol\types\PersonaSkinPiece; +use pocketmine\network\mcpe\protocol\types\recipe\RecipeIngredient; use pocketmine\network\mcpe\protocol\types\SkinAnimation; use pocketmine\network\mcpe\protocol\types\SkinData; use pocketmine\network\mcpe\protocol\types\SkinImage; @@ -63,9 +61,6 @@ use function strlen; class NetworkBinaryStream extends BinaryStream{ - private const DAMAGE_TAG = "Damage"; //TAG_Int - private const DAMAGE_TAG_CONFLICT_RESOLUTION = "___Damage_ProtocolCollisionResolution___"; - /** * @throws BinaryDataException */ @@ -209,15 +204,15 @@ class NetworkBinaryStream extends BinaryStream{ * @throws BadPacketException * @throws BinaryDataException */ - public function getSlot() : Item{ + public function getSlot() : ItemStack{ $id = $this->getVarInt(); if($id === 0){ - return ItemFactory::get(0, 0, 0); + return ItemStack::null(); } $auxValue = $this->getVarInt(); - $data = $auxValue >> 8; - $cnt = $auxValue & 0xff; + $meta = $auxValue >> 8; + $count = $auxValue & 0xff; $nbtLen = $this->getLShort(); @@ -237,43 +232,25 @@ class NetworkBinaryStream extends BinaryStream{ throw new BadPacketException("Unexpected fake NBT length $nbtLen"); } - //TODO - for($i = 0, $canPlaceOn = $this->getVarInt(); $i < $canPlaceOn; ++$i){ - $this->getString(); + $canPlaceOn = []; + for($i = 0, $canPlaceOnCount = $this->getVarInt(); $i < $canPlaceOnCount; ++$i){ + $canPlaceOn[] = $this->getString(); } - //TODO - for($i = 0, $canDestroy = $this->getVarInt(); $i < $canDestroy; ++$i){ - $this->getString(); + $canDestroy = []; + for($i = 0, $canDestroyCount = $this->getVarInt(); $i < $canDestroyCount; ++$i){ + $canDestroy[] = $this->getString(); } + $shieldBlockingTick = null; if($id === ItemIds::SHIELD){ - $this->getVarLong(); //"blocking tick" (ffs mojang) + $shieldBlockingTick = $this->getVarLong(); } - if($compound !== null){ - if($compound->hasTag(self::DAMAGE_TAG, IntTag::class)){ - $data = $compound->getInt(self::DAMAGE_TAG); - $compound->removeTag(self::DAMAGE_TAG); - if($compound->count() === 0){ - $compound = null; - goto end; - } - } - if(($conflicted = $compound->getTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION)) !== null){ - $compound->removeTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION); - $compound->setTag(self::DAMAGE_TAG, $conflicted); - } - } - end: - try{ - return ItemFactory::get($id, $data, $cnt, $compound); - }catch(\InvalidArgumentException $e){ - throw new BadPacketException($e->getMessage(), 0, $e); - } + return new ItemStack($id, $meta, $count, $compound, $canPlaceOn, $canDestroy, $shieldBlockingTick); } - public function putSlot(Item $item) : void{ + public function putSlot(ItemStack $item) : void{ if($item->getId() === 0){ $this->putVarInt(0); @@ -284,22 +261,7 @@ class NetworkBinaryStream extends BinaryStream{ $auxValue = (($item->getMeta() & 0x7fff) << 8) | $item->getCount(); $this->putVarInt($auxValue); - $nbt = null; - if($item->hasNamedTag()){ - $nbt = clone $item->getNamedTag(); - } - if($item instanceof Durable and $item->getDamage() > 0){ - if($nbt !== null){ - if(($existing = $nbt->getTag(self::DAMAGE_TAG)) !== null){ - $nbt->removeTag(self::DAMAGE_TAG); - $nbt->setTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION, $existing); - } - }else{ - $nbt = new CompoundTag(); - } - $nbt->setInt(self::DAMAGE_TAG, $item->getDamage()); - } - + $nbt = $item->getNbt(); if($nbt !== null){ $this->putLShort(0xffff); $this->putByte(1); //TODO: some kind of count field? always 1 as of 1.9.0 @@ -308,34 +270,39 @@ class NetworkBinaryStream extends BinaryStream{ $this->putLShort(0); } - $this->putVarInt(0); //CanPlaceOn entry count (TODO) - $this->putVarInt(0); //CanDestroy entry count (TODO) + $this->putVarInt(count($item->getCanPlaceOn())); + foreach($item->getCanPlaceOn() as $entry){ + $this->putString($entry); + } + $this->putVarInt(count($item->getCanDestroy())); + foreach($item->getCanDestroy() as $entry){ + $this->putString($entry); + } - if($item->getId() === ItemIds::SHIELD){ - $this->putVarLong(0); //"blocking tick" (ffs mojang) + $blockingTick = $item->getShieldBlockingTick(); + if($blockingTick !== null){ + $this->putVarLong($blockingTick); } } - public function getRecipeIngredient() : Item{ + public function getRecipeIngredient() : RecipeIngredient{ $id = $this->getVarInt(); if($id === 0){ - return ItemFactory::get(ItemIds::AIR, 0, 0); + return new RecipeIngredient(0, 0, 0); } $meta = $this->getVarInt(); - if($meta === 0x7fff){ - $meta = -1; - } $count = $this->getVarInt(); - return ItemFactory::get($id, $meta, $count); + + return new RecipeIngredient($id, $meta, $count); } - public function putRecipeIngredient(Item $item) : void{ - if($item->isNull()){ + public function putRecipeIngredient(RecipeIngredient $ingredient) : void{ + if($ingredient->getId() === 0){ $this->putVarInt(0); }else{ - $this->putVarInt($item->getId()); - $this->putVarInt($item->getMeta() & 0x7fff); - $this->putVarInt($item->getCount()); + $this->putVarInt($ingredient->getId()); + $this->putVarInt($ingredient->getMeta()); + $this->putVarInt($ingredient->getCount()); } } diff --git a/src/world/particle/FloatingTextParticle.php b/src/world/particle/FloatingTextParticle.php index 8785eebfcc..76d2c3f80a 100644 --- a/src/world/particle/FloatingTextParticle.php +++ b/src/world/particle/FloatingTextParticle.php @@ -25,7 +25,6 @@ namespace pocketmine\world\particle; use pocketmine\entity\EntityFactory; use pocketmine\entity\Skin; -use pocketmine\item\ItemFactory; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\AddPlayerPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket; @@ -34,6 +33,7 @@ use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\entity\FloatMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\LongMetadataProperty; +use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\network\mcpe\protocol\types\SkinAdapterSingleton; use pocketmine\utils\UUID; @@ -100,7 +100,7 @@ class FloatingTextParticle implements Particle{ $pk->username = $name; $pk->entityRuntimeId = $this->entityId; $pk->position = $pos; //TODO: check offset - $pk->item = ItemFactory::air(); + $pk->item = ItemStack::null(); $flags = ( 1 << EntityMetadataFlags::IMMOBILE From 1b26cf1df9411c4e61a6597881675ce88a1f9ccc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 23 Apr 2020 15:23:20 +0100 Subject: [PATCH 1445/3224] break the hard cycle between mcpe\handler and mcpe\protocol preparing to move mcpe\protocol to a separate library --- src/network/mcpe/handler/PacketHandler.php | 3 +- .../mcpe/protocol/ActorEventPacket.php | 3 +- src/network/mcpe/protocol/ActorFallPacket.php | 3 +- .../mcpe/protocol/ActorPickRequestPacket.php | 3 +- src/network/mcpe/protocol/AddActorPacket.php | 3 +- .../mcpe/protocol/AddBehaviorTreePacket.php | 3 +- src/network/mcpe/protocol/AddEntityPacket.php | 3 +- .../mcpe/protocol/AddItemActorPacket.php | 3 +- .../mcpe/protocol/AddPaintingPacket.php | 3 +- src/network/mcpe/protocol/AddPlayerPacket.php | 3 +- .../mcpe/protocol/AdventureSettingsPacket.php | 3 +- src/network/mcpe/protocol/AnimatePacket.php | 3 +- .../mcpe/protocol/AnvilDamagePacket.php | 3 +- .../AutomationClientConnectPacket.php | 3 +- .../AvailableActorIdentifiersPacket.php | 3 +- .../mcpe/protocol/AvailableCommandsPacket.php | 3 +- .../protocol/BiomeDefinitionListPacket.php | 3 +- .../mcpe/protocol/BlockActorDataPacket.php | 3 +- .../mcpe/protocol/BlockEventPacket.php | 3 +- .../mcpe/protocol/BlockPickRequestPacket.php | 3 +- src/network/mcpe/protocol/BookEditPacket.php | 3 +- src/network/mcpe/protocol/BossEventPacket.php | 3 +- src/network/mcpe/protocol/CameraPacket.php | 3 +- .../mcpe/protocol/ChangeDimensionPacket.php | 3 +- .../protocol/ChunkRadiusUpdatedPacket.php | 3 +- .../protocol/ClientCacheBlobStatusPacket.php | 3 +- .../ClientCacheMissResponsePacket.php | 3 +- .../mcpe/protocol/ClientCacheStatusPacket.php | 3 +- .../ClientToServerHandshakePacket.php | 3 +- .../protocol/ClientboundMapItemDataPacket.php | 3 +- .../protocol/CommandBlockUpdatePacket.php | 3 +- .../mcpe/protocol/CommandOutputPacket.php | 3 +- .../mcpe/protocol/CommandRequestPacket.php | 3 +- .../protocol/CompletedUsingItemPacket.php | 3 +- .../mcpe/protocol/ContainerClosePacket.php | 3 +- .../mcpe/protocol/ContainerOpenPacket.php | 3 +- .../mcpe/protocol/ContainerSetDataPacket.php | 3 +- .../mcpe/protocol/CraftingDataPacket.php | 3 +- .../mcpe/protocol/CraftingEventPacket.php | 3 +- .../mcpe/protocol/DisconnectPacket.php | 3 +- .../mcpe/protocol/EducationSettingsPacket.php | 3 +- src/network/mcpe/protocol/EmotePacket.php | 3 +- src/network/mcpe/protocol/EventPacket.php | 3 +- .../mcpe/protocol/GameRulesChangedPacket.php | 3 +- .../mcpe/protocol/GuiDataPickItemPacket.php | 3 +- src/network/mcpe/protocol/HurtArmorPacket.php | 3 +- src/network/mcpe/protocol/InteractPacket.php | 3 +- .../mcpe/protocol/InventoryContentPacket.php | 3 +- .../mcpe/protocol/InventorySlotPacket.php | 3 +- .../protocol/InventoryTransactionPacket.php | 3 +- .../mcpe/protocol/ItemFrameDropItemPacket.php | 3 +- src/network/mcpe/protocol/LabTablePacket.php | 3 +- .../mcpe/protocol/LecternUpdatePacket.php | 3 +- .../mcpe/protocol/LevelChunkPacket.php | 3 +- .../mcpe/protocol/LevelEventGenericPacket.php | 3 +- .../mcpe/protocol/LevelEventPacket.php | 3 +- .../mcpe/protocol/LevelSoundEventPacket.php | 3 +- .../mcpe/protocol/LevelSoundEventPacketV1.php | 3 +- .../mcpe/protocol/LevelSoundEventPacketV2.php | 3 +- src/network/mcpe/protocol/LoginPacket.php | 3 +- .../protocol/MapCreateLockedCopyPacket.php | 3 +- .../mcpe/protocol/MapInfoRequestPacket.php | 3 +- .../mcpe/protocol/MobArmorEquipmentPacket.php | 3 +- src/network/mcpe/protocol/MobEffectPacket.php | 3 +- .../mcpe/protocol/MobEquipmentPacket.php | 3 +- .../mcpe/protocol/ModalFormRequestPacket.php | 3 +- .../mcpe/protocol/ModalFormResponsePacket.php | 3 +- .../mcpe/protocol/MoveActorAbsolutePacket.php | 3 +- .../mcpe/protocol/MoveActorDeltaPacket.php | 3 +- .../mcpe/protocol/MovePlayerPacket.php | 3 +- .../protocol/MultiplayerSettingsPacket.php | 3 +- .../NetworkChunkPublisherUpdatePacket.php | 3 +- .../mcpe/protocol/NetworkSettingsPacket.php | 3 +- .../protocol/NetworkStackLatencyPacket.php | 3 +- .../mcpe/protocol/NpcRequestPacket.php | 3 +- .../OnScreenTextureAnimationPacket.php | 3 +- src/network/mcpe/protocol/Packet.php | 5 +- .../mcpe/protocol/PacketHandlerInterface.php | 313 ++++++++++++++++++ .../mcpe/protocol/PhotoTransferPacket.php | 3 +- src/network/mcpe/protocol/PlaySoundPacket.php | 3 +- .../mcpe/protocol/PlayStatusPacket.php | 3 +- .../mcpe/protocol/PlayerActionPacket.php | 3 +- .../mcpe/protocol/PlayerAuthInputPacket.php | 3 +- .../mcpe/protocol/PlayerHotbarPacket.php | 3 +- .../mcpe/protocol/PlayerInputPacket.php | 3 +- .../mcpe/protocol/PlayerListPacket.php | 3 +- .../mcpe/protocol/PlayerSkinPacket.php | 3 +- .../mcpe/protocol/PurchaseReceiptPacket.php | 3 +- .../mcpe/protocol/RemoveActorPacket.php | 3 +- .../mcpe/protocol/RemoveEntityPacket.php | 3 +- .../mcpe/protocol/RemoveObjectivePacket.php | 3 +- .../protocol/RequestChunkRadiusPacket.php | 3 +- .../protocol/ResourcePackChunkDataPacket.php | 3 +- .../ResourcePackChunkRequestPacket.php | 3 +- .../ResourcePackClientResponsePacket.php | 3 +- .../protocol/ResourcePackDataInfoPacket.php | 3 +- .../mcpe/protocol/ResourcePackStackPacket.php | 3 +- .../mcpe/protocol/ResourcePacksInfoPacket.php | 3 +- src/network/mcpe/protocol/RespawnPacket.php | 3 +- src/network/mcpe/protocol/RiderJumpPacket.php | 3 +- .../mcpe/protocol/ScriptCustomEventPacket.php | 3 +- .../protocol/ServerSettingsRequestPacket.php | 3 +- .../protocol/ServerSettingsResponsePacket.php | 3 +- .../ServerToClientHandshakePacket.php | 3 +- .../mcpe/protocol/SetActorDataPacket.php | 3 +- .../mcpe/protocol/SetActorLinkPacket.php | 3 +- .../mcpe/protocol/SetActorMotionPacket.php | 3 +- .../protocol/SetCommandsEnabledPacket.php | 3 +- .../protocol/SetDefaultGameTypePacket.php | 3 +- .../mcpe/protocol/SetDifficultyPacket.php | 3 +- .../protocol/SetDisplayObjectivePacket.php | 3 +- src/network/mcpe/protocol/SetHealthPacket.php | 3 +- .../mcpe/protocol/SetLastHurtByPacket.php | 3 +- .../SetLocalPlayerAsInitializedPacket.php | 3 +- .../mcpe/protocol/SetPlayerGameTypePacket.php | 3 +- src/network/mcpe/protocol/SetScorePacket.php | 3 +- .../protocol/SetScoreboardIdentityPacket.php | 3 +- .../mcpe/protocol/SetSpawnPositionPacket.php | 3 +- src/network/mcpe/protocol/SetTimePacket.php | 3 +- src/network/mcpe/protocol/SetTitlePacket.php | 3 +- .../mcpe/protocol/SettingsCommandPacket.php | 3 +- .../mcpe/protocol/ShowCreditsPacket.php | 3 +- .../mcpe/protocol/ShowProfilePacket.php | 3 +- .../mcpe/protocol/ShowStoreOfferPacket.php | 3 +- .../mcpe/protocol/SimpleEventPacket.php | 3 +- .../protocol/SpawnExperienceOrbPacket.php | 3 +- .../protocol/SpawnParticleEffectPacket.php | 3 +- src/network/mcpe/protocol/StartGamePacket.php | 3 +- src/network/mcpe/protocol/StopSoundPacket.php | 3 +- .../protocol/StructureBlockUpdatePacket.php | 3 +- .../StructureTemplateDataRequestPacket.php | 3 +- .../StructureTemplateDataResponsePacket.php | 3 +- .../mcpe/protocol/SubClientLoginPacket.php | 3 +- .../mcpe/protocol/TakeItemActorPacket.php | 3 +- src/network/mcpe/protocol/TextPacket.php | 3 +- src/network/mcpe/protocol/TickSyncPacket.php | 3 +- src/network/mcpe/protocol/TransferPacket.php | 3 +- src/network/mcpe/protocol/UnknownPacket.php | 3 +- .../mcpe/protocol/UpdateAttributesPacket.php | 3 +- .../mcpe/protocol/UpdateBlockPacket.php | 3 +- .../protocol/UpdateBlockPropertiesPacket.php | 3 +- .../mcpe/protocol/UpdateBlockSyncedPacket.php | 3 +- .../mcpe/protocol/UpdateEquipPacket.php | 3 +- .../mcpe/protocol/UpdateSoftEnumPacket.php | 3 +- .../mcpe/protocol/UpdateTradePacket.php | 3 +- .../protocol/VideoStreamConnectPacket.php | 3 +- .../network/mcpe/protocol/TestPacket.php | 3 +- 147 files changed, 462 insertions(+), 291 deletions(-) create mode 100644 src/network/mcpe/protocol/PacketHandlerInterface.php diff --git a/src/network/mcpe/handler/PacketHandler.php b/src/network/mcpe/handler/PacketHandler.php index 8a21c04c08..0679682847 100644 --- a/src/network/mcpe/handler/PacketHandler.php +++ b/src/network/mcpe/handler/PacketHandler.php @@ -98,6 +98,7 @@ use pocketmine\network\mcpe\protocol\NetworkSettingsPacket; use pocketmine\network\mcpe\protocol\NetworkStackLatencyPacket; use pocketmine\network\mcpe\protocol\NpcRequestPacket; use pocketmine\network\mcpe\protocol\OnScreenTextureAnimationPacket; +use pocketmine\network\mcpe\protocol\PacketHandlerInterface; use pocketmine\network\mcpe\protocol\PhotoTransferPacket; use pocketmine\network\mcpe\protocol\PlayerActionPacket; use pocketmine\network\mcpe\protocol\PlayerAuthInputPacket; @@ -172,7 +173,7 @@ use pocketmine\network\mcpe\protocol\VideoStreamConnectPacket; * * This class is an automatically generated stub. Do not edit it manually. */ -abstract class PacketHandler{ +abstract class PacketHandler implements PacketHandlerInterface{ public function setUp() : void{ diff --git a/src/network/mcpe/protocol/ActorEventPacket.php b/src/network/mcpe/protocol/ActorEventPacket.php index 14e1ff457d..86f42759c1 100644 --- a/src/network/mcpe/protocol/ActorEventPacket.php +++ b/src/network/mcpe/protocol/ActorEventPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ActorEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -118,7 +117,7 @@ class ActorEventPacket extends DataPacket implements ClientboundPacket, Serverbo $out->putVarInt($this->data); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleActorEvent($this); } } diff --git a/src/network/mcpe/protocol/ActorFallPacket.php b/src/network/mcpe/protocol/ActorFallPacket.php index deb0720064..4bd7cca89e 100644 --- a/src/network/mcpe/protocol/ActorFallPacket.php +++ b/src/network/mcpe/protocol/ActorFallPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ActorFallPacket extends DataPacket implements ServerboundPacket{ @@ -50,7 +49,7 @@ class ActorFallPacket extends DataPacket implements ServerboundPacket{ $out->putBool($this->isInVoid); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleActorFall($this); } } diff --git a/src/network/mcpe/protocol/ActorPickRequestPacket.php b/src/network/mcpe/protocol/ActorPickRequestPacket.php index e87bf10617..15d24f1ce7 100644 --- a/src/network/mcpe/protocol/ActorPickRequestPacket.php +++ b/src/network/mcpe/protocol/ActorPickRequestPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ActorPickRequestPacket extends DataPacket implements ServerboundPacket{ @@ -46,7 +45,7 @@ class ActorPickRequestPacket extends DataPacket implements ServerboundPacket{ $out->putByte($this->hotbarSlot); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleActorPickRequest($this); } } diff --git a/src/network/mcpe/protocol/AddActorPacket.php b/src/network/mcpe/protocol/AddActorPacket.php index 47c3f18f90..3b1572309a 100644 --- a/src/network/mcpe/protocol/AddActorPacket.php +++ b/src/network/mcpe/protocol/AddActorPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\entity\Attribute; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; @@ -224,7 +223,7 @@ class AddActorPacket extends DataPacket implements ClientboundPacket{ } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleAddActor($this); } } diff --git a/src/network/mcpe/protocol/AddBehaviorTreePacket.php b/src/network/mcpe/protocol/AddBehaviorTreePacket.php index 5fb1eefcc4..f62e0f8974 100644 --- a/src/network/mcpe/protocol/AddBehaviorTreePacket.php +++ b/src/network/mcpe/protocol/AddBehaviorTreePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class AddBehaviorTreePacket extends DataPacket implements ClientboundPacket{ @@ -42,7 +41,7 @@ class AddBehaviorTreePacket extends DataPacket implements ClientboundPacket{ $out->putString($this->behaviorTreeJson); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleAddBehaviorTree($this); } } diff --git a/src/network/mcpe/protocol/AddEntityPacket.php b/src/network/mcpe/protocol/AddEntityPacket.php index 380747fe4f..a8fa734988 100644 --- a/src/network/mcpe/protocol/AddEntityPacket.php +++ b/src/network/mcpe/protocol/AddEntityPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class AddEntityPacket extends DataPacket implements ClientboundPacket{ @@ -52,7 +51,7 @@ class AddEntityPacket extends DataPacket implements ClientboundPacket{ $out->putUnsignedVarInt($this->uvarint1); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleAddEntity($this); } } diff --git a/src/network/mcpe/protocol/AddItemActorPacket.php b/src/network/mcpe/protocol/AddItemActorPacket.php index e174bad9f7..92a8141e41 100644 --- a/src/network/mcpe/protocol/AddItemActorPacket.php +++ b/src/network/mcpe/protocol/AddItemActorPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; @@ -72,7 +71,7 @@ class AddItemActorPacket extends DataPacket implements ClientboundPacket{ $out->putBool($this->isFromFishing); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleAddItemActor($this); } } diff --git a/src/network/mcpe/protocol/AddPaintingPacket.php b/src/network/mcpe/protocol/AddPaintingPacket.php index 80f827111d..6c0080a644 100644 --- a/src/network/mcpe/protocol/AddPaintingPacket.php +++ b/src/network/mcpe/protocol/AddPaintingPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class AddPaintingPacket extends DataPacket implements ClientboundPacket{ @@ -59,7 +58,7 @@ class AddPaintingPacket extends DataPacket implements ClientboundPacket{ $out->putString($this->title); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleAddPainting($this); } } diff --git a/src/network/mcpe/protocol/AddPlayerPacket.php b/src/network/mcpe/protocol/AddPlayerPacket.php index 6e1475fc7b..f2dafb1e8d 100644 --- a/src/network/mcpe/protocol/AddPlayerPacket.php +++ b/src/network/mcpe/protocol/AddPlayerPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; @@ -150,7 +149,7 @@ class AddPlayerPacket extends DataPacket implements ClientboundPacket{ $out->putLInt($this->buildPlatform); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleAddPlayer($this); } } diff --git a/src/network/mcpe/protocol/AdventureSettingsPacket.php b/src/network/mcpe/protocol/AdventureSettingsPacket.php index 4075d65a03..4ec2202f2f 100644 --- a/src/network/mcpe/protocol/AdventureSettingsPacket.php +++ b/src/network/mcpe/protocol/AdventureSettingsPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; @@ -116,7 +115,7 @@ class AdventureSettingsPacket extends DataPacket implements ClientboundPacket, S } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleAdventureSettings($this); } } diff --git a/src/network/mcpe/protocol/AnimatePacket.php b/src/network/mcpe/protocol/AnimatePacket.php index ea64998b5d..ee3389409e 100644 --- a/src/network/mcpe/protocol/AnimatePacket.php +++ b/src/network/mcpe/protocol/AnimatePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class AnimatePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -75,7 +74,7 @@ class AnimatePacket extends DataPacket implements ClientboundPacket, Serverbound } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleAnimate($this); } } diff --git a/src/network/mcpe/protocol/AnvilDamagePacket.php b/src/network/mcpe/protocol/AnvilDamagePacket.php index 495779b45f..9c28b857ae 100644 --- a/src/network/mcpe/protocol/AnvilDamagePacket.php +++ b/src/network/mcpe/protocol/AnvilDamagePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class AnvilDamagePacket extends DataPacket implements ServerboundPacket{ @@ -73,7 +72,7 @@ class AnvilDamagePacket extends DataPacket implements ServerboundPacket{ $out->putBlockPosition($this->x, $this->y, $this->z); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleAnvilDamage($this); } } diff --git a/src/network/mcpe/protocol/AutomationClientConnectPacket.php b/src/network/mcpe/protocol/AutomationClientConnectPacket.php index b01f237abf..455234c16c 100644 --- a/src/network/mcpe/protocol/AutomationClientConnectPacket.php +++ b/src/network/mcpe/protocol/AutomationClientConnectPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class AutomationClientConnectPacket extends DataPacket implements ClientboundPacket{ @@ -42,7 +41,7 @@ class AutomationClientConnectPacket extends DataPacket implements ClientboundPac $out->putString($this->serverUri); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleAutomationClientConnect($this); } } diff --git a/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php b/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php index b583a85f73..f5de597f70 100644 --- a/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php +++ b/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function base64_decode; use function file_get_contents; @@ -51,7 +50,7 @@ class AvailableActorIdentifiersPacket extends DataPacket implements ClientboundP ); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleAvailableActorIdentifiers($this); } } diff --git a/src/network/mcpe/protocol/AvailableCommandsPacket.php b/src/network/mcpe/protocol/AvailableCommandsPacket.php index 70992f42ab..02e96f74be 100644 --- a/src/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/network/mcpe/protocol/AvailableCommandsPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\command\CommandData; use pocketmine\network\mcpe\protocol\types\command\CommandEnum; use pocketmine\network\mcpe\protocol\types\command\CommandEnumConstraint; @@ -482,7 +481,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleAvailableCommands($this); } } diff --git a/src/network/mcpe/protocol/BiomeDefinitionListPacket.php b/src/network/mcpe/protocol/BiomeDefinitionListPacket.php index 8ce5583bdc..9587e9b8e8 100644 --- a/src/network/mcpe/protocol/BiomeDefinitionListPacket.php +++ b/src/network/mcpe/protocol/BiomeDefinitionListPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function file_get_contents; @@ -50,7 +49,7 @@ class BiomeDefinitionListPacket extends DataPacket implements ClientboundPacket{ ); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleBiomeDefinitionList($this); } } diff --git a/src/network/mcpe/protocol/BlockActorDataPacket.php b/src/network/mcpe/protocol/BlockActorDataPacket.php index 21a981a59e..e5c3aefa11 100644 --- a/src/network/mcpe/protocol/BlockActorDataPacket.php +++ b/src/network/mcpe/protocol/BlockActorDataPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class BlockActorDataPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -57,7 +56,7 @@ class BlockActorDataPacket extends DataPacket implements ClientboundPacket, Serv $out->put($this->namedtag); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleBlockActorData($this); } } diff --git a/src/network/mcpe/protocol/BlockEventPacket.php b/src/network/mcpe/protocol/BlockEventPacket.php index a4b74ddb5a..acfce2b68c 100644 --- a/src/network/mcpe/protocol/BlockEventPacket.php +++ b/src/network/mcpe/protocol/BlockEventPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class BlockEventPacket extends DataPacket implements ClientboundPacket{ @@ -65,7 +64,7 @@ class BlockEventPacket extends DataPacket implements ClientboundPacket{ $out->putVarInt($this->eventData); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleBlockEvent($this); } } diff --git a/src/network/mcpe/protocol/BlockPickRequestPacket.php b/src/network/mcpe/protocol/BlockPickRequestPacket.php index ff2a6ed953..9366e4f2bc 100644 --- a/src/network/mcpe/protocol/BlockPickRequestPacket.php +++ b/src/network/mcpe/protocol/BlockPickRequestPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class BlockPickRequestPacket extends DataPacket implements ServerboundPacket{ @@ -54,7 +53,7 @@ class BlockPickRequestPacket extends DataPacket implements ServerboundPacket{ $out->putByte($this->hotbarSlot); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleBlockPickRequest($this); } } diff --git a/src/network/mcpe/protocol/BookEditPacket.php b/src/network/mcpe/protocol/BookEditPacket.php index 3527009df4..f61423f45a 100644 --- a/src/network/mcpe/protocol/BookEditPacket.php +++ b/src/network/mcpe/protocol/BookEditPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class BookEditPacket extends DataPacket implements ServerboundPacket{ @@ -115,7 +114,7 @@ class BookEditPacket extends DataPacket implements ServerboundPacket{ } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleBookEdit($this); } } diff --git a/src/network/mcpe/protocol/BossEventPacket.php b/src/network/mcpe/protocol/BossEventPacket.php index 867cf19f9c..6797952629 100644 --- a/src/network/mcpe/protocol/BossEventPacket.php +++ b/src/network/mcpe/protocol/BossEventPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class BossEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -179,7 +178,7 @@ class BossEventPacket extends DataPacket implements ClientboundPacket, Serverbou } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleBossEvent($this); } } diff --git a/src/network/mcpe/protocol/CameraPacket.php b/src/network/mcpe/protocol/CameraPacket.php index bcdd42f6e2..c12eeb06d4 100644 --- a/src/network/mcpe/protocol/CameraPacket.php +++ b/src/network/mcpe/protocol/CameraPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class CameraPacket extends DataPacket implements ClientboundPacket{ @@ -46,7 +45,7 @@ class CameraPacket extends DataPacket implements ClientboundPacket{ $out->putEntityUniqueId($this->playerUniqueId); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleCamera($this); } } diff --git a/src/network/mcpe/protocol/ChangeDimensionPacket.php b/src/network/mcpe/protocol/ChangeDimensionPacket.php index 03d38f11e9..c50df0db5b 100644 --- a/src/network/mcpe/protocol/ChangeDimensionPacket.php +++ b/src/network/mcpe/protocol/ChangeDimensionPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ChangeDimensionPacket extends DataPacket implements ClientboundPacket{ @@ -51,7 +50,7 @@ class ChangeDimensionPacket extends DataPacket implements ClientboundPacket{ $out->putBool($this->respawn); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleChangeDimension($this); } } diff --git a/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php b/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php index b42a1474a2..4fd7247e67 100644 --- a/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php +++ b/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ChunkRadiusUpdatedPacket extends DataPacket implements ClientboundPacket{ @@ -48,7 +47,7 @@ class ChunkRadiusUpdatedPacket extends DataPacket implements ClientboundPacket{ $out->putVarInt($this->radius); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleChunkRadiusUpdated($this); } } diff --git a/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php b/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php index 2d3e6f19ef..f71ecd5638 100644 --- a/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php +++ b/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; @@ -88,7 +87,7 @@ class ClientCacheBlobStatusPacket extends DataPacket implements ServerboundPacke } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleClientCacheBlobStatus($this); } } diff --git a/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php b/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php index 8029582d64..4294ba27f2 100644 --- a/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php +++ b/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\ChunkCacheBlob; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; @@ -71,7 +70,7 @@ class ClientCacheMissResponsePacket extends DataPacket implements ClientboundPac } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleClientCacheMissResponse($this); } } diff --git a/src/network/mcpe/protocol/ClientCacheStatusPacket.php b/src/network/mcpe/protocol/ClientCacheStatusPacket.php index f15bc3a6b8..d96b402bd8 100644 --- a/src/network/mcpe/protocol/ClientCacheStatusPacket.php +++ b/src/network/mcpe/protocol/ClientCacheStatusPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ClientCacheStatusPacket extends DataPacket implements ServerboundPacket{ @@ -52,7 +51,7 @@ class ClientCacheStatusPacket extends DataPacket implements ServerboundPacket{ $out->putBool($this->enabled); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleClientCacheStatus($this); } } diff --git a/src/network/mcpe/protocol/ClientToServerHandshakePacket.php b/src/network/mcpe/protocol/ClientToServerHandshakePacket.php index c141822ea6..3e80204962 100644 --- a/src/network/mcpe/protocol/ClientToServerHandshakePacket.php +++ b/src/network/mcpe/protocol/ClientToServerHandshakePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ClientToServerHandshakePacket extends DataPacket implements ServerboundPacket{ @@ -43,7 +42,7 @@ class ClientToServerHandshakePacket extends DataPacket implements ServerboundPac //No payload } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleClientToServerHandshake($this); } } diff --git a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php index f427b959c1..a82108ab94 100644 --- a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php +++ b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\protocol\types\MapDecoration; use pocketmine\network\mcpe\protocol\types\MapTrackedObject; @@ -204,7 +203,7 @@ class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPack } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleClientboundMapItemData($this); } } diff --git a/src/network/mcpe/protocol/CommandBlockUpdatePacket.php b/src/network/mcpe/protocol/CommandBlockUpdatePacket.php index daa0df0393..0773994e04 100644 --- a/src/network/mcpe/protocol/CommandBlockUpdatePacket.php +++ b/src/network/mcpe/protocol/CommandBlockUpdatePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class CommandBlockUpdatePacket extends DataPacket implements ServerboundPacket{ @@ -106,7 +105,7 @@ class CommandBlockUpdatePacket extends DataPacket implements ServerboundPacket{ $out->putBool($this->executeOnFirstTick); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleCommandBlockUpdate($this); } } diff --git a/src/network/mcpe/protocol/CommandOutputPacket.php b/src/network/mcpe/protocol/CommandOutputPacket.php index f01f5467c9..2909ee699b 100644 --- a/src/network/mcpe/protocol/CommandOutputPacket.php +++ b/src/network/mcpe/protocol/CommandOutputPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; use pocketmine\network\mcpe\protocol\types\command\CommandOutputMessage; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; @@ -101,7 +100,7 @@ class CommandOutputPacket extends DataPacket implements ClientboundPacket{ } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleCommandOutput($this); } } diff --git a/src/network/mcpe/protocol/CommandRequestPacket.php b/src/network/mcpe/protocol/CommandRequestPacket.php index 682a074a44..0d27805287 100644 --- a/src/network/mcpe/protocol/CommandRequestPacket.php +++ b/src/network/mcpe/protocol/CommandRequestPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; @@ -51,7 +50,7 @@ class CommandRequestPacket extends DataPacket implements ServerboundPacket{ $out->putBool($this->isInternal); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleCommandRequest($this); } } diff --git a/src/network/mcpe/protocol/CompletedUsingItemPacket.php b/src/network/mcpe/protocol/CompletedUsingItemPacket.php index 72d84a3d2f..7d7994dd3c 100644 --- a/src/network/mcpe/protocol/CompletedUsingItemPacket.php +++ b/src/network/mcpe/protocol/CompletedUsingItemPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class CompletedUsingItemPacket extends DataPacket implements ClientboundPacket{ @@ -63,7 +62,7 @@ class CompletedUsingItemPacket extends DataPacket implements ClientboundPacket{ $out->putLInt($this->action); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleCompletedUsingItem($this); } } diff --git a/src/network/mcpe/protocol/ContainerClosePacket.php b/src/network/mcpe/protocol/ContainerClosePacket.php index a0bc2f688c..6ef089a498 100644 --- a/src/network/mcpe/protocol/ContainerClosePacket.php +++ b/src/network/mcpe/protocol/ContainerClosePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ContainerClosePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -48,7 +47,7 @@ class ContainerClosePacket extends DataPacket implements ClientboundPacket, Serv $out->putByte($this->windowId); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleContainerClose($this); } } diff --git a/src/network/mcpe/protocol/ContainerOpenPacket.php b/src/network/mcpe/protocol/ContainerOpenPacket.php index 0ac5907722..ab283e8d54 100644 --- a/src/network/mcpe/protocol/ContainerOpenPacket.php +++ b/src/network/mcpe/protocol/ContainerOpenPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ContainerOpenPacket extends DataPacket implements ClientboundPacket{ @@ -80,7 +79,7 @@ class ContainerOpenPacket extends DataPacket implements ClientboundPacket{ $out->putEntityUniqueId($this->entityUniqueId); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleContainerOpen($this); } } diff --git a/src/network/mcpe/protocol/ContainerSetDataPacket.php b/src/network/mcpe/protocol/ContainerSetDataPacket.php index a7c2507ab8..4ab0eb7a99 100644 --- a/src/network/mcpe/protocol/ContainerSetDataPacket.php +++ b/src/network/mcpe/protocol/ContainerSetDataPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ContainerSetDataPacket extends DataPacket implements ClientboundPacket{ @@ -68,7 +67,7 @@ class ContainerSetDataPacket extends DataPacket implements ClientboundPacket{ $out->putVarInt($this->value); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleContainerSetData($this); } } diff --git a/src/network/mcpe/protocol/CraftingDataPacket.php b/src/network/mcpe/protocol/CraftingDataPacket.php index f94cb40ad9..0a338ea1bc 100644 --- a/src/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/network/mcpe/protocol/CraftingDataPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\PotionContainerChangeRecipe; use pocketmine\network\mcpe\protocol\types\PotionTypeRecipe; use pocketmine\network\mcpe\protocol\types\recipe\FurnaceRecipe; @@ -121,7 +120,7 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{ $out->putBool($this->cleanRecipes); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleCraftingData($this); } } diff --git a/src/network/mcpe/protocol/CraftingEventPacket.php b/src/network/mcpe/protocol/CraftingEventPacket.php index c9f357cf21..2b06745ac1 100644 --- a/src/network/mcpe/protocol/CraftingEventPacket.php +++ b/src/network/mcpe/protocol/CraftingEventPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\UUID; @@ -77,7 +76,7 @@ class CraftingEventPacket extends DataPacket implements ServerboundPacket{ } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleCraftingEvent($this); } } diff --git a/src/network/mcpe/protocol/DisconnectPacket.php b/src/network/mcpe/protocol/DisconnectPacket.php index e9ec1cbbd6..539c9e1be6 100644 --- a/src/network/mcpe/protocol/DisconnectPacket.php +++ b/src/network/mcpe/protocol/DisconnectPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class DisconnectPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -67,7 +66,7 @@ class DisconnectPacket extends DataPacket implements ClientboundPacket, Serverbo } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleDisconnect($this); } } diff --git a/src/network/mcpe/protocol/EducationSettingsPacket.php b/src/network/mcpe/protocol/EducationSettingsPacket.php index 264e34de07..d27b6794d2 100644 --- a/src/network/mcpe/protocol/EducationSettingsPacket.php +++ b/src/network/mcpe/protocol/EducationSettingsPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class EducationSettingsPacket extends DataPacket implements ClientboundPacket{ @@ -61,7 +60,7 @@ class EducationSettingsPacket extends DataPacket implements ClientboundPacket{ $out->putBool($this->hasQuiz); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleEducationSettings($this); } } diff --git a/src/network/mcpe/protocol/EmotePacket.php b/src/network/mcpe/protocol/EmotePacket.php index 76ff71c18a..733855c497 100644 --- a/src/network/mcpe/protocol/EmotePacket.php +++ b/src/network/mcpe/protocol/EmotePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class EmotePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -75,7 +74,7 @@ class EmotePacket extends DataPacket implements ClientboundPacket, ServerboundPa $out->putByte($this->flags); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleEmote($this); } } diff --git a/src/network/mcpe/protocol/EventPacket.php b/src/network/mcpe/protocol/EventPacket.php index 882e2c2418..0386098b4b 100644 --- a/src/network/mcpe/protocol/EventPacket.php +++ b/src/network/mcpe/protocol/EventPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class EventPacket extends DataPacket implements ClientboundPacket{ @@ -73,7 +72,7 @@ class EventPacket extends DataPacket implements ClientboundPacket{ //TODO: also nice confusing mess } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleEvent($this); } } diff --git a/src/network/mcpe/protocol/GameRulesChangedPacket.php b/src/network/mcpe/protocol/GameRulesChangedPacket.php index f1249f87a8..96eeddbdba 100644 --- a/src/network/mcpe/protocol/GameRulesChangedPacket.php +++ b/src/network/mcpe/protocol/GameRulesChangedPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class GameRulesChangedPacket extends DataPacket implements ClientboundPacket{ @@ -45,7 +44,7 @@ class GameRulesChangedPacket extends DataPacket implements ClientboundPacket{ $out->putGameRules($this->gameRules); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleGameRulesChanged($this); } } diff --git a/src/network/mcpe/protocol/GuiDataPickItemPacket.php b/src/network/mcpe/protocol/GuiDataPickItemPacket.php index 8207256511..11f255d6a7 100644 --- a/src/network/mcpe/protocol/GuiDataPickItemPacket.php +++ b/src/network/mcpe/protocol/GuiDataPickItemPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class GuiDataPickItemPacket extends DataPacket implements ClientboundPacket{ @@ -50,7 +49,7 @@ class GuiDataPickItemPacket extends DataPacket implements ClientboundPacket{ $out->putLInt($this->hotbarSlot); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleGuiDataPickItem($this); } } diff --git a/src/network/mcpe/protocol/HurtArmorPacket.php b/src/network/mcpe/protocol/HurtArmorPacket.php index a53cf4d15f..90a583ced9 100644 --- a/src/network/mcpe/protocol/HurtArmorPacket.php +++ b/src/network/mcpe/protocol/HurtArmorPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class HurtArmorPacket extends DataPacket implements ClientboundPacket{ @@ -42,7 +41,7 @@ class HurtArmorPacket extends DataPacket implements ClientboundPacket{ $out->putVarInt($this->health); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleHurtArmor($this); } } diff --git a/src/network/mcpe/protocol/InteractPacket.php b/src/network/mcpe/protocol/InteractPacket.php index 1260665df2..422de4cc99 100644 --- a/src/network/mcpe/protocol/InteractPacket.php +++ b/src/network/mcpe/protocol/InteractPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class InteractPacket extends DataPacket implements ServerboundPacket{ @@ -71,7 +70,7 @@ class InteractPacket extends DataPacket implements ServerboundPacket{ } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleInteract($this); } } diff --git a/src/network/mcpe/protocol/InventoryContentPacket.php b/src/network/mcpe/protocol/InventoryContentPacket.php index 28b28d954f..e3cba72787 100644 --- a/src/network/mcpe/protocol/InventoryContentPacket.php +++ b/src/network/mcpe/protocol/InventoryContentPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; @@ -66,7 +65,7 @@ class InventoryContentPacket extends DataPacket implements ClientboundPacket{ } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleInventoryContent($this); } } diff --git a/src/network/mcpe/protocol/InventorySlotPacket.php b/src/network/mcpe/protocol/InventorySlotPacket.php index 485226bae3..593eb6378b 100644 --- a/src/network/mcpe/protocol/InventorySlotPacket.php +++ b/src/network/mcpe/protocol/InventorySlotPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; @@ -60,7 +59,7 @@ class InventorySlotPacket extends DataPacket implements ClientboundPacket{ $out->putSlot($this->item); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleInventorySlot($this); } } diff --git a/src/network/mcpe/protocol/InventoryTransactionPacket.php b/src/network/mcpe/protocol/InventoryTransactionPacket.php index c3f99e55c5..1683aa6288 100644 --- a/src/network/mcpe/protocol/InventoryTransactionPacket.php +++ b/src/network/mcpe/protocol/InventoryTransactionPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\inventory\MismatchTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\NormalTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData; @@ -81,7 +80,7 @@ class InventoryTransactionPacket extends DataPacket implements ClientboundPacket $this->trData->encode($out); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleInventoryTransaction($this); } } diff --git a/src/network/mcpe/protocol/ItemFrameDropItemPacket.php b/src/network/mcpe/protocol/ItemFrameDropItemPacket.php index bac21044af..30c0ae0858 100644 --- a/src/network/mcpe/protocol/ItemFrameDropItemPacket.php +++ b/src/network/mcpe/protocol/ItemFrameDropItemPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ItemFrameDropItemPacket extends DataPacket implements ServerboundPacket{ @@ -47,7 +46,7 @@ class ItemFrameDropItemPacket extends DataPacket implements ServerboundPacket{ $out->putBlockPosition($this->x, $this->y, $this->z); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleItemFrameDropItem($this); } } diff --git a/src/network/mcpe/protocol/LabTablePacket.php b/src/network/mcpe/protocol/LabTablePacket.php index fcf24bb5f6..6a020f276d 100644 --- a/src/network/mcpe/protocol/LabTablePacket.php +++ b/src/network/mcpe/protocol/LabTablePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class LabTablePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -60,7 +59,7 @@ class LabTablePacket extends DataPacket implements ClientboundPacket, Serverboun $out->putByte($this->reactionType); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleLabTable($this); } } diff --git a/src/network/mcpe/protocol/LecternUpdatePacket.php b/src/network/mcpe/protocol/LecternUpdatePacket.php index 3362ec0bf0..440f8554e7 100644 --- a/src/network/mcpe/protocol/LecternUpdatePacket.php +++ b/src/network/mcpe/protocol/LecternUpdatePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class LecternUpdatePacket extends DataPacket implements ServerboundPacket{ @@ -58,7 +57,7 @@ class LecternUpdatePacket extends DataPacket implements ServerboundPacket{ $out->putBool($this->dropBook); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleLecternUpdate($this); } } diff --git a/src/network/mcpe/protocol/LevelChunkPacket.php b/src/network/mcpe/protocol/LevelChunkPacket.php index 04a5e9c994..514024b16a 100644 --- a/src/network/mcpe/protocol/LevelChunkPacket.php +++ b/src/network/mcpe/protocol/LevelChunkPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; @@ -128,7 +127,7 @@ class LevelChunkPacket extends DataPacket implements ClientboundPacket{ $out->putString($this->extraPayload); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleLevelChunk($this); } } diff --git a/src/network/mcpe/protocol/LevelEventGenericPacket.php b/src/network/mcpe/protocol/LevelEventGenericPacket.php index d0dc7d3df8..52a65d964e 100644 --- a/src/network/mcpe/protocol/LevelEventGenericPacket.php +++ b/src/network/mcpe/protocol/LevelEventGenericPacket.php @@ -27,7 +27,6 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; @@ -64,7 +63,7 @@ class LevelEventGenericPacket extends DataPacket implements ClientboundPacket{ $out->put($this->eventData); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleLevelEventGeneric($this); } } diff --git a/src/network/mcpe/protocol/LevelEventPacket.php b/src/network/mcpe/protocol/LevelEventPacket.php index 27afb80085..6c39d76ac1 100644 --- a/src/network/mcpe/protocol/LevelEventPacket.php +++ b/src/network/mcpe/protocol/LevelEventPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class LevelEventPacket extends DataPacket implements ClientboundPacket{ @@ -146,7 +145,7 @@ class LevelEventPacket extends DataPacket implements ClientboundPacket{ $out->putVarInt($this->data); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleLevelEvent($this); } } diff --git a/src/network/mcpe/protocol/LevelSoundEventPacket.php b/src/network/mcpe/protocol/LevelSoundEventPacket.php index 447c55bafc..8ee820d0de 100644 --- a/src/network/mcpe/protocol/LevelSoundEventPacket.php +++ b/src/network/mcpe/protocol/LevelSoundEventPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class LevelSoundEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -354,7 +353,7 @@ class LevelSoundEventPacket extends DataPacket implements ClientboundPacket, Ser $out->putBool($this->disableRelativeVolume); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleLevelSoundEvent($this); } } diff --git a/src/network/mcpe/protocol/LevelSoundEventPacketV1.php b/src/network/mcpe/protocol/LevelSoundEventPacketV1.php index f7b93b19a1..20f5d30611 100644 --- a/src/network/mcpe/protocol/LevelSoundEventPacketV1.php +++ b/src/network/mcpe/protocol/LevelSoundEventPacketV1.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; /** @@ -66,7 +65,7 @@ class LevelSoundEventPacketV1 extends DataPacket{ $out->putBool($this->disableRelativeVolume); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleLevelSoundEventPacketV1($this); } } diff --git a/src/network/mcpe/protocol/LevelSoundEventPacketV2.php b/src/network/mcpe/protocol/LevelSoundEventPacketV2.php index 9447523cac..b771f7835b 100644 --- a/src/network/mcpe/protocol/LevelSoundEventPacketV2.php +++ b/src/network/mcpe/protocol/LevelSoundEventPacketV2.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; /** @@ -66,7 +65,7 @@ class LevelSoundEventPacketV2 extends DataPacket{ $out->putBool($this->disableRelativeVolume); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleLevelSoundEventPacketV2($this); } } diff --git a/src/network/mcpe/protocol/LoginPacket.php b/src/network/mcpe/protocol/LoginPacket.php index f2bc7c23e6..4de771f2a3 100644 --- a/src/network/mcpe/protocol/LoginPacket.php +++ b/src/network/mcpe/protocol/LoginPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\login\AuthenticationData; use pocketmine\network\mcpe\protocol\types\login\ClientData; use pocketmine\network\mcpe\protocol\types\login\JwtChain; @@ -142,7 +141,7 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ //TODO } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleLogin($this); } } diff --git a/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php b/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php index 43b1a97184..b0fd28e31d 100644 --- a/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php +++ b/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class MapCreateLockedCopyPacket extends DataPacket implements ServerboundPacket{ @@ -46,7 +45,7 @@ class MapCreateLockedCopyPacket extends DataPacket implements ServerboundPacket{ $out->putEntityUniqueId($this->newMapId); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleMapCreateLockedCopy($this); } } diff --git a/src/network/mcpe/protocol/MapInfoRequestPacket.php b/src/network/mcpe/protocol/MapInfoRequestPacket.php index bbe8ba7b50..d26519025d 100644 --- a/src/network/mcpe/protocol/MapInfoRequestPacket.php +++ b/src/network/mcpe/protocol/MapInfoRequestPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class MapInfoRequestPacket extends DataPacket implements ServerboundPacket{ @@ -42,7 +41,7 @@ class MapInfoRequestPacket extends DataPacket implements ServerboundPacket{ $out->putEntityUniqueId($this->mapId); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleMapInfoRequest($this); } } diff --git a/src/network/mcpe/protocol/MobArmorEquipmentPacket.php b/src/network/mcpe/protocol/MobArmorEquipmentPacket.php index 255350bc21..7606b4c136 100644 --- a/src/network/mcpe/protocol/MobArmorEquipmentPacket.php +++ b/src/network/mcpe/protocol/MobArmorEquipmentPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; @@ -73,7 +72,7 @@ class MobArmorEquipmentPacket extends DataPacket implements ClientboundPacket, S $out->putSlot($this->feet); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleMobArmorEquipment($this); } } diff --git a/src/network/mcpe/protocol/MobEffectPacket.php b/src/network/mcpe/protocol/MobEffectPacket.php index 683a5f2b24..695a4e2f94 100644 --- a/src/network/mcpe/protocol/MobEffectPacket.php +++ b/src/network/mcpe/protocol/MobEffectPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class MobEffectPacket extends DataPacket implements ClientboundPacket{ @@ -85,7 +84,7 @@ class MobEffectPacket extends DataPacket implements ClientboundPacket{ $out->putVarInt($this->duration); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleMobEffect($this); } } diff --git a/src/network/mcpe/protocol/MobEquipmentPacket.php b/src/network/mcpe/protocol/MobEquipmentPacket.php index 69d0f1ce48..1b8691f314 100644 --- a/src/network/mcpe/protocol/MobEquipmentPacket.php +++ b/src/network/mcpe/protocol/MobEquipmentPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; @@ -69,7 +68,7 @@ class MobEquipmentPacket extends DataPacket implements ClientboundPacket, Server $out->putByte($this->windowId); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleMobEquipment($this); } } diff --git a/src/network/mcpe/protocol/ModalFormRequestPacket.php b/src/network/mcpe/protocol/ModalFormRequestPacket.php index 6865c8af04..2672e67d38 100644 --- a/src/network/mcpe/protocol/ModalFormRequestPacket.php +++ b/src/network/mcpe/protocol/ModalFormRequestPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ModalFormRequestPacket extends DataPacket implements ClientboundPacket{ @@ -53,7 +52,7 @@ class ModalFormRequestPacket extends DataPacket implements ClientboundPacket{ $out->putString($this->formData); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleModalFormRequest($this); } } diff --git a/src/network/mcpe/protocol/ModalFormResponsePacket.php b/src/network/mcpe/protocol/ModalFormResponsePacket.php index 7f4379ae44..bee8fb2d48 100644 --- a/src/network/mcpe/protocol/ModalFormResponsePacket.php +++ b/src/network/mcpe/protocol/ModalFormResponsePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ModalFormResponsePacket extends DataPacket implements ServerboundPacket{ @@ -46,7 +45,7 @@ class ModalFormResponsePacket extends DataPacket implements ServerboundPacket{ $out->putString($this->formData); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleModalFormResponse($this); } } diff --git a/src/network/mcpe/protocol/MoveActorAbsolutePacket.php b/src/network/mcpe/protocol/MoveActorAbsolutePacket.php index 71d9df47f9..ef57798e6f 100644 --- a/src/network/mcpe/protocol/MoveActorAbsolutePacket.php +++ b/src/network/mcpe/protocol/MoveActorAbsolutePacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class MoveActorAbsolutePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -66,7 +65,7 @@ class MoveActorAbsolutePacket extends DataPacket implements ClientboundPacket, S $out->putByteRotation($this->zRot); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleMoveActorAbsolute($this); } } diff --git a/src/network/mcpe/protocol/MoveActorDeltaPacket.php b/src/network/mcpe/protocol/MoveActorDeltaPacket.php index 5ea13f2b6a..319e4b6399 100644 --- a/src/network/mcpe/protocol/MoveActorDeltaPacket.php +++ b/src/network/mcpe/protocol/MoveActorDeltaPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; @@ -110,7 +109,7 @@ class MoveActorDeltaPacket extends DataPacket implements ClientboundPacket{ $this->maybeWriteRotation(self::FLAG_HAS_ROT_Z, $this->zRot, $out); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleMoveActorDelta($this); } } diff --git a/src/network/mcpe/protocol/MovePlayerPacket.php b/src/network/mcpe/protocol/MovePlayerPacket.php index 05a79649bc..7f392b49e6 100644 --- a/src/network/mcpe/protocol/MovePlayerPacket.php +++ b/src/network/mcpe/protocol/MovePlayerPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class MovePlayerPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -88,7 +87,7 @@ class MovePlayerPacket extends DataPacket implements ClientboundPacket, Serverbo } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleMovePlayer($this); } } diff --git a/src/network/mcpe/protocol/MultiplayerSettingsPacket.php b/src/network/mcpe/protocol/MultiplayerSettingsPacket.php index d30139e76d..0b2169265d 100644 --- a/src/network/mcpe/protocol/MultiplayerSettingsPacket.php +++ b/src/network/mcpe/protocol/MultiplayerSettingsPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class MultiplayerSettingsPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -56,7 +55,7 @@ class MultiplayerSettingsPacket extends DataPacket implements ClientboundPacket, $out->putVarInt($this->action); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleMultiplayerSettings($this); } } diff --git a/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php b/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php index 92b9b1df4e..eeb2db1c50 100644 --- a/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php +++ b/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class NetworkChunkPublisherUpdatePacket extends DataPacket implements ClientboundPacket{ @@ -59,7 +58,7 @@ class NetworkChunkPublisherUpdatePacket extends DataPacket implements Clientboun $out->putUnsignedVarInt($this->radius); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleNetworkChunkPublisherUpdate($this); } } diff --git a/src/network/mcpe/protocol/NetworkSettingsPacket.php b/src/network/mcpe/protocol/NetworkSettingsPacket.php index 40b387320a..357e118d4b 100644 --- a/src/network/mcpe/protocol/NetworkSettingsPacket.php +++ b/src/network/mcpe/protocol/NetworkSettingsPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class NetworkSettingsPacket extends DataPacket implements ClientboundPacket{ @@ -55,7 +54,7 @@ class NetworkSettingsPacket extends DataPacket implements ClientboundPacket{ $out->putLShort($this->compressionThreshold); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleNetworkSettings($this); } } diff --git a/src/network/mcpe/protocol/NetworkStackLatencyPacket.php b/src/network/mcpe/protocol/NetworkStackLatencyPacket.php index ce1459d941..7a045b30db 100644 --- a/src/network/mcpe/protocol/NetworkStackLatencyPacket.php +++ b/src/network/mcpe/protocol/NetworkStackLatencyPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class NetworkStackLatencyPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -46,7 +45,7 @@ class NetworkStackLatencyPacket extends DataPacket implements ClientboundPacket, $out->putBool($this->needResponse); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleNetworkStackLatency($this); } } diff --git a/src/network/mcpe/protocol/NpcRequestPacket.php b/src/network/mcpe/protocol/NpcRequestPacket.php index 26b11eacbf..9789f52fbb 100644 --- a/src/network/mcpe/protocol/NpcRequestPacket.php +++ b/src/network/mcpe/protocol/NpcRequestPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class NpcRequestPacket extends DataPacket implements ServerboundPacket{ @@ -54,7 +53,7 @@ class NpcRequestPacket extends DataPacket implements ServerboundPacket{ $out->putByte($this->actionType); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleNpcRequest($this); } } diff --git a/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php b/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php index 0a2565623f..032427acaa 100644 --- a/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php +++ b/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class OnScreenTextureAnimationPacket extends DataPacket implements ClientboundPacket{ @@ -42,7 +41,7 @@ class OnScreenTextureAnimationPacket extends DataPacket implements ClientboundPa $out->putLInt($this->effectId); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleOnScreenTextureAnimation($this); } } diff --git a/src/network/mcpe/protocol/Packet.php b/src/network/mcpe/protocol/Packet.php index ded5c0f707..aec47b8cf9 100644 --- a/src/network/mcpe/protocol/Packet.php +++ b/src/network/mcpe/protocol/Packet.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; interface Packet{ @@ -54,8 +53,10 @@ interface Packet{ * Typically this method returns the return value of the handler in the supplied PacketHandler. See other packets * for examples how to implement this. * + * @param PacketHandlerInterface $handler + * * @return bool true if the packet was handled successfully, false if not. * @throws BadPacketException if broken data was found in the packet */ - public function handle(PacketHandler $handler) : bool; + public function handle(PacketHandlerInterface $handler) : bool; } diff --git a/src/network/mcpe/protocol/PacketHandlerInterface.php b/src/network/mcpe/protocol/PacketHandlerInterface.php new file mode 100644 index 0000000000..730824d372 --- /dev/null +++ b/src/network/mcpe/protocol/PacketHandlerInterface.php @@ -0,0 +1,313 @@ + -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class PhotoTransferPacket extends DataPacket implements ClientboundPacket{ @@ -50,7 +49,7 @@ class PhotoTransferPacket extends DataPacket implements ClientboundPacket{ $out->putString($this->bookId); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handlePhotoTransfer($this); } } diff --git a/src/network/mcpe/protocol/PlaySoundPacket.php b/src/network/mcpe/protocol/PlaySoundPacket.php index f59cd463c8..df969a7425 100644 --- a/src/network/mcpe/protocol/PlaySoundPacket.php +++ b/src/network/mcpe/protocol/PlaySoundPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class PlaySoundPacket extends DataPacket implements ClientboundPacket{ @@ -61,7 +60,7 @@ class PlaySoundPacket extends DataPacket implements ClientboundPacket{ $out->putLFloat($this->pitch); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handlePlaySound($this); } } diff --git a/src/network/mcpe/protocol/PlayStatusPacket.php b/src/network/mcpe/protocol/PlayStatusPacket.php index 76f3a54818..096f97a75d 100644 --- a/src/network/mcpe/protocol/PlayStatusPacket.php +++ b/src/network/mcpe/protocol/PlayStatusPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class PlayStatusPacket extends DataPacket implements ClientboundPacket{ @@ -61,7 +60,7 @@ class PlayStatusPacket extends DataPacket implements ClientboundPacket{ $out->putInt($this->status); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handlePlayStatus($this); } } diff --git a/src/network/mcpe/protocol/PlayerActionPacket.php b/src/network/mcpe/protocol/PlayerActionPacket.php index d3593289b6..87945518aa 100644 --- a/src/network/mcpe/protocol/PlayerActionPacket.php +++ b/src/network/mcpe/protocol/PlayerActionPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class PlayerActionPacket extends DataPacket implements ServerboundPacket{ @@ -85,7 +84,7 @@ class PlayerActionPacket extends DataPacket implements ServerboundPacket{ $out->putVarInt($this->face); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handlePlayerAction($this); } } diff --git a/src/network/mcpe/protocol/PlayerAuthInputPacket.php b/src/network/mcpe/protocol/PlayerAuthInputPacket.php index 5fd9d8fd20..eb945f7ea0 100644 --- a/src/network/mcpe/protocol/PlayerAuthInputPacket.php +++ b/src/network/mcpe/protocol/PlayerAuthInputPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\InputMode; use pocketmine\network\mcpe\protocol\types\PlayMode; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; @@ -159,7 +158,7 @@ class PlayerAuthInputPacket extends DataPacket implements ServerboundPacket{ } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handlePlayerAuthInput($this); } } diff --git a/src/network/mcpe/protocol/PlayerHotbarPacket.php b/src/network/mcpe/protocol/PlayerHotbarPacket.php index 36f10aa437..23e8248bd3 100644 --- a/src/network/mcpe/protocol/PlayerHotbarPacket.php +++ b/src/network/mcpe/protocol/PlayerHotbarPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; @@ -59,7 +58,7 @@ class PlayerHotbarPacket extends DataPacket implements ClientboundPacket, Server $out->putBool($this->selectHotbarSlot); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handlePlayerHotbar($this); } } diff --git a/src/network/mcpe/protocol/PlayerInputPacket.php b/src/network/mcpe/protocol/PlayerInputPacket.php index c7446fcc52..930316fc3a 100644 --- a/src/network/mcpe/protocol/PlayerInputPacket.php +++ b/src/network/mcpe/protocol/PlayerInputPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class PlayerInputPacket extends DataPacket implements ServerboundPacket{ @@ -54,7 +53,7 @@ class PlayerInputPacket extends DataPacket implements ServerboundPacket{ $out->putBool($this->sneaking); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handlePlayerInput($this); } } diff --git a/src/network/mcpe/protocol/PlayerListPacket.php b/src/network/mcpe/protocol/PlayerListPacket.php index 8655f781ce..94ef66ed30 100644 --- a/src/network/mcpe/protocol/PlayerListPacket.php +++ b/src/network/mcpe/protocol/PlayerListPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; @@ -115,7 +114,7 @@ class PlayerListPacket extends DataPacket implements ClientboundPacket{ } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handlePlayerList($this); } } diff --git a/src/network/mcpe/protocol/PlayerSkinPacket.php b/src/network/mcpe/protocol/PlayerSkinPacket.php index c44c29de83..f4e57f13fd 100644 --- a/src/network/mcpe/protocol/PlayerSkinPacket.php +++ b/src/network/mcpe/protocol/PlayerSkinPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\SkinData; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\UUID; @@ -58,7 +57,7 @@ class PlayerSkinPacket extends DataPacket implements ClientboundPacket, Serverbo $out->putBool($this->skin->isVerified()); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handlePlayerSkin($this); } } diff --git a/src/network/mcpe/protocol/PurchaseReceiptPacket.php b/src/network/mcpe/protocol/PurchaseReceiptPacket.php index 6083353728..d9aafafc84 100644 --- a/src/network/mcpe/protocol/PurchaseReceiptPacket.php +++ b/src/network/mcpe/protocol/PurchaseReceiptPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; @@ -49,7 +48,7 @@ class PurchaseReceiptPacket extends DataPacket implements ServerboundPacket{ } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handlePurchaseReceipt($this); } } diff --git a/src/network/mcpe/protocol/RemoveActorPacket.php b/src/network/mcpe/protocol/RemoveActorPacket.php index 276460f94b..730733cf89 100644 --- a/src/network/mcpe/protocol/RemoveActorPacket.php +++ b/src/network/mcpe/protocol/RemoveActorPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class RemoveActorPacket extends DataPacket implements ClientboundPacket{ @@ -48,7 +47,7 @@ class RemoveActorPacket extends DataPacket implements ClientboundPacket{ $out->putEntityUniqueId($this->entityUniqueId); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleRemoveActor($this); } } diff --git a/src/network/mcpe/protocol/RemoveEntityPacket.php b/src/network/mcpe/protocol/RemoveEntityPacket.php index e04182cd63..c471e4d2f8 100644 --- a/src/network/mcpe/protocol/RemoveEntityPacket.php +++ b/src/network/mcpe/protocol/RemoveEntityPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class RemoveEntityPacket extends DataPacket implements ClientboundPacket{ @@ -52,7 +51,7 @@ class RemoveEntityPacket extends DataPacket implements ClientboundPacket{ $out->putUnsignedVarInt($this->uvarint1); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleRemoveEntity($this); } } diff --git a/src/network/mcpe/protocol/RemoveObjectivePacket.php b/src/network/mcpe/protocol/RemoveObjectivePacket.php index c05f118ad3..b338017d93 100644 --- a/src/network/mcpe/protocol/RemoveObjectivePacket.php +++ b/src/network/mcpe/protocol/RemoveObjectivePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class RemoveObjectivePacket extends DataPacket implements ClientboundPacket{ @@ -42,7 +41,7 @@ class RemoveObjectivePacket extends DataPacket implements ClientboundPacket{ $out->putString($this->objectiveName); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleRemoveObjective($this); } } diff --git a/src/network/mcpe/protocol/RequestChunkRadiusPacket.php b/src/network/mcpe/protocol/RequestChunkRadiusPacket.php index 2d669fa30e..8b8a4a5701 100644 --- a/src/network/mcpe/protocol/RequestChunkRadiusPacket.php +++ b/src/network/mcpe/protocol/RequestChunkRadiusPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class RequestChunkRadiusPacket extends DataPacket implements ServerboundPacket{ @@ -42,7 +41,7 @@ class RequestChunkRadiusPacket extends DataPacket implements ServerboundPacket{ $out->putVarInt($this->radius); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleRequestChunkRadius($this); } } diff --git a/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php b/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php index 26dee397a0..2c4096a711 100644 --- a/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php +++ b/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function strlen; @@ -64,7 +63,7 @@ class ResourcePackChunkDataPacket extends DataPacket implements ClientboundPacke $out->putString($this->data); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleResourcePackChunkData($this); } } diff --git a/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php b/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php index a8004ac10c..b925423e61 100644 --- a/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php +++ b/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ResourcePackChunkRequestPacket extends DataPacket implements ServerboundPacket{ @@ -46,7 +45,7 @@ class ResourcePackChunkRequestPacket extends DataPacket implements ServerboundPa $out->putLInt($this->chunkIndex); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleResourcePackChunkRequest($this); } } diff --git a/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php b/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php index 246a5924a2..58ea907a7f 100644 --- a/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php +++ b/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; @@ -58,7 +57,7 @@ class ResourcePackClientResponsePacket extends DataPacket implements Serverbound } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleResourcePackClientResponse($this); } } diff --git a/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php b/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php index fa3b8816e8..ad2af8423b 100644 --- a/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php +++ b/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackType; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; @@ -77,7 +76,7 @@ class ResourcePackDataInfoPacket extends DataPacket implements ClientboundPacket $out->putByte($this->packType); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleResourcePackDataInfo($this); } } diff --git a/src/network/mcpe/protocol/ResourcePackStackPacket.php b/src/network/mcpe/protocol/ResourcePackStackPacket.php index 89f85738ef..a2209ab86e 100644 --- a/src/network/mcpe/protocol/ResourcePackStackPacket.php +++ b/src/network/mcpe/protocol/ResourcePackStackPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackStackEntry; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; @@ -94,7 +93,7 @@ class ResourcePackStackPacket extends DataPacket implements ClientboundPacket{ $out->putString($this->baseGameVersion); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleResourcePackStack($this); } } diff --git a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php index a187a4db70..6a88c50487 100644 --- a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php +++ b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackInfoEntry; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; @@ -84,7 +83,7 @@ class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleResourcePacksInfo($this); } } diff --git a/src/network/mcpe/protocol/RespawnPacket.php b/src/network/mcpe/protocol/RespawnPacket.php index dfad800acb..c5d02c703e 100644 --- a/src/network/mcpe/protocol/RespawnPacket.php +++ b/src/network/mcpe/protocol/RespawnPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class RespawnPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -63,7 +62,7 @@ class RespawnPacket extends DataPacket implements ClientboundPacket, Serverbound $out->putEntityRuntimeId($this->entityRuntimeId); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleRespawn($this); } } diff --git a/src/network/mcpe/protocol/RiderJumpPacket.php b/src/network/mcpe/protocol/RiderJumpPacket.php index ed67e227e3..c213340c5f 100644 --- a/src/network/mcpe/protocol/RiderJumpPacket.php +++ b/src/network/mcpe/protocol/RiderJumpPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class RiderJumpPacket extends DataPacket implements ServerboundPacket{ @@ -42,7 +41,7 @@ class RiderJumpPacket extends DataPacket implements ServerboundPacket{ $out->putVarInt($this->jumpStrength); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleRiderJump($this); } } diff --git a/src/network/mcpe/protocol/ScriptCustomEventPacket.php b/src/network/mcpe/protocol/ScriptCustomEventPacket.php index 59def62185..ed3ba8d36c 100644 --- a/src/network/mcpe/protocol/ScriptCustomEventPacket.php +++ b/src/network/mcpe/protocol/ScriptCustomEventPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ScriptCustomEventPacket extends DataPacket{ //TODO: this doesn't have handlers in either client or server in the game as of 1.8 @@ -46,7 +45,7 @@ class ScriptCustomEventPacket extends DataPacket{ //TODO: this doesn't have hand $out->putString($this->eventData); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleScriptCustomEvent($this); } } diff --git a/src/network/mcpe/protocol/ServerSettingsRequestPacket.php b/src/network/mcpe/protocol/ServerSettingsRequestPacket.php index c17b1b2a1f..fe261df1ca 100644 --- a/src/network/mcpe/protocol/ServerSettingsRequestPacket.php +++ b/src/network/mcpe/protocol/ServerSettingsRequestPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ServerSettingsRequestPacket extends DataPacket implements ServerboundPacket{ @@ -39,7 +38,7 @@ class ServerSettingsRequestPacket extends DataPacket implements ServerboundPacke //No payload } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleServerSettingsRequest($this); } } diff --git a/src/network/mcpe/protocol/ServerSettingsResponsePacket.php b/src/network/mcpe/protocol/ServerSettingsResponsePacket.php index aa6dd24b85..23a7dfce62 100644 --- a/src/network/mcpe/protocol/ServerSettingsResponsePacket.php +++ b/src/network/mcpe/protocol/ServerSettingsResponsePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ServerSettingsResponsePacket extends DataPacket implements ClientboundPacket{ @@ -46,7 +45,7 @@ class ServerSettingsResponsePacket extends DataPacket implements ClientboundPack $out->putString($this->formData); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleServerSettingsResponse($this); } } diff --git a/src/network/mcpe/protocol/ServerToClientHandshakePacket.php b/src/network/mcpe/protocol/ServerToClientHandshakePacket.php index b0c62ee65c..03c4509bd9 100644 --- a/src/network/mcpe/protocol/ServerToClientHandshakePacket.php +++ b/src/network/mcpe/protocol/ServerToClientHandshakePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ServerToClientHandshakePacket extends DataPacket implements ClientboundPacket{ @@ -55,7 +54,7 @@ class ServerToClientHandshakePacket extends DataPacket implements ClientboundPac $out->putString($this->jwt); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleServerToClientHandshake($this); } } diff --git a/src/network/mcpe/protocol/SetActorDataPacket.php b/src/network/mcpe/protocol/SetActorDataPacket.php index 776a1cfc5d..59b6d7d4f5 100644 --- a/src/network/mcpe/protocol/SetActorDataPacket.php +++ b/src/network/mcpe/protocol/SetActorDataPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; @@ -62,7 +61,7 @@ class SetActorDataPacket extends DataPacket implements ClientboundPacket, Server $out->putEntityMetadata($this->metadata); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSetActorData($this); } } diff --git a/src/network/mcpe/protocol/SetActorLinkPacket.php b/src/network/mcpe/protocol/SetActorLinkPacket.php index d981ce69f9..50c765b8f1 100644 --- a/src/network/mcpe/protocol/SetActorLinkPacket.php +++ b/src/network/mcpe/protocol/SetActorLinkPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; @@ -43,7 +42,7 @@ class SetActorLinkPacket extends DataPacket implements ClientboundPacket{ $out->putEntityLink($this->link); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSetActorLink($this); } } diff --git a/src/network/mcpe/protocol/SetActorMotionPacket.php b/src/network/mcpe/protocol/SetActorMotionPacket.php index 42f1c4bb5c..acd72be78d 100644 --- a/src/network/mcpe/protocol/SetActorMotionPacket.php +++ b/src/network/mcpe/protocol/SetActorMotionPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; /** @@ -57,7 +56,7 @@ class SetActorMotionPacket extends DataPacket implements ClientboundPacket, Garb $out->putVector3($this->motion); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSetActorMotion($this); } } diff --git a/src/network/mcpe/protocol/SetCommandsEnabledPacket.php b/src/network/mcpe/protocol/SetCommandsEnabledPacket.php index 8a93313929..505a356800 100644 --- a/src/network/mcpe/protocol/SetCommandsEnabledPacket.php +++ b/src/network/mcpe/protocol/SetCommandsEnabledPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetCommandsEnabledPacket extends DataPacket implements ClientboundPacket{ @@ -42,7 +41,7 @@ class SetCommandsEnabledPacket extends DataPacket implements ClientboundPacket{ $out->putBool($this->enabled); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSetCommandsEnabled($this); } } diff --git a/src/network/mcpe/protocol/SetDefaultGameTypePacket.php b/src/network/mcpe/protocol/SetDefaultGameTypePacket.php index 24882377b4..ad2bf5bad0 100644 --- a/src/network/mcpe/protocol/SetDefaultGameTypePacket.php +++ b/src/network/mcpe/protocol/SetDefaultGameTypePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetDefaultGameTypePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -48,7 +47,7 @@ class SetDefaultGameTypePacket extends DataPacket implements ClientboundPacket, $out->putUnsignedVarInt($this->gamemode); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSetDefaultGameType($this); } } diff --git a/src/network/mcpe/protocol/SetDifficultyPacket.php b/src/network/mcpe/protocol/SetDifficultyPacket.php index e8ae53f882..5543bf57cd 100644 --- a/src/network/mcpe/protocol/SetDifficultyPacket.php +++ b/src/network/mcpe/protocol/SetDifficultyPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetDifficultyPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -48,7 +47,7 @@ class SetDifficultyPacket extends DataPacket implements ClientboundPacket, Serve $out->putUnsignedVarInt($this->difficulty); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSetDifficulty($this); } } diff --git a/src/network/mcpe/protocol/SetDisplayObjectivePacket.php b/src/network/mcpe/protocol/SetDisplayObjectivePacket.php index c2d146dd6f..461e2b0ed1 100644 --- a/src/network/mcpe/protocol/SetDisplayObjectivePacket.php +++ b/src/network/mcpe/protocol/SetDisplayObjectivePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetDisplayObjectivePacket extends DataPacket implements ClientboundPacket{ @@ -58,7 +57,7 @@ class SetDisplayObjectivePacket extends DataPacket implements ClientboundPacket{ $out->putVarInt($this->sortOrder); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSetDisplayObjective($this); } } diff --git a/src/network/mcpe/protocol/SetHealthPacket.php b/src/network/mcpe/protocol/SetHealthPacket.php index 33d995ee1a..41be570007 100644 --- a/src/network/mcpe/protocol/SetHealthPacket.php +++ b/src/network/mcpe/protocol/SetHealthPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetHealthPacket extends DataPacket implements ClientboundPacket{ @@ -42,7 +41,7 @@ class SetHealthPacket extends DataPacket implements ClientboundPacket{ $out->putVarInt($this->health); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSetHealth($this); } } diff --git a/src/network/mcpe/protocol/SetLastHurtByPacket.php b/src/network/mcpe/protocol/SetLastHurtByPacket.php index 41cf6cc7b6..601d11e1e2 100644 --- a/src/network/mcpe/protocol/SetLastHurtByPacket.php +++ b/src/network/mcpe/protocol/SetLastHurtByPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetLastHurtByPacket extends DataPacket implements ClientboundPacket{ @@ -42,7 +41,7 @@ class SetLastHurtByPacket extends DataPacket implements ClientboundPacket{ $out->putVarInt($this->entityTypeId); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSetLastHurtBy($this); } } diff --git a/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php b/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php index 9bad32b374..c7e4ffffdc 100644 --- a/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php +++ b/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetLocalPlayerAsInitializedPacket extends DataPacket implements ServerboundPacket{ @@ -42,7 +41,7 @@ class SetLocalPlayerAsInitializedPacket extends DataPacket implements Serverboun $out->putEntityRuntimeId($this->entityRuntimeId); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSetLocalPlayerAsInitialized($this); } } diff --git a/src/network/mcpe/protocol/SetPlayerGameTypePacket.php b/src/network/mcpe/protocol/SetPlayerGameTypePacket.php index 212810dab7..93dba5df9e 100644 --- a/src/network/mcpe/protocol/SetPlayerGameTypePacket.php +++ b/src/network/mcpe/protocol/SetPlayerGameTypePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetPlayerGameTypePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -48,7 +47,7 @@ class SetPlayerGameTypePacket extends DataPacket implements ClientboundPacket, S $out->putVarInt($this->gamemode); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSetPlayerGameType($this); } } diff --git a/src/network/mcpe/protocol/SetScorePacket.php b/src/network/mcpe/protocol/SetScorePacket.php index 73e1208dc0..5643b9407b 100644 --- a/src/network/mcpe/protocol/SetScorePacket.php +++ b/src/network/mcpe/protocol/SetScorePacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\ScorePacketEntry; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; @@ -91,7 +90,7 @@ class SetScorePacket extends DataPacket implements ClientboundPacket{ } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSetScore($this); } } diff --git a/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php b/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php index bd42d29cba..6c5ae55a46 100644 --- a/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php +++ b/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\ScoreboardIdentityPacketEntry; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; @@ -65,7 +64,7 @@ class SetScoreboardIdentityPacket extends DataPacket implements ClientboundPacke } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSetScoreboardIdentity($this); } } diff --git a/src/network/mcpe/protocol/SetSpawnPositionPacket.php b/src/network/mcpe/protocol/SetSpawnPositionPacket.php index fe65a4965d..b2f5ee5017 100644 --- a/src/network/mcpe/protocol/SetSpawnPositionPacket.php +++ b/src/network/mcpe/protocol/SetSpawnPositionPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetSpawnPositionPacket extends DataPacket implements ClientboundPacket{ @@ -72,7 +71,7 @@ class SetSpawnPositionPacket extends DataPacket implements ClientboundPacket{ $out->putBool($this->spawnForced); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSetSpawnPosition($this); } } diff --git a/src/network/mcpe/protocol/SetTimePacket.php b/src/network/mcpe/protocol/SetTimePacket.php index 1883524926..d4a2fcd3f9 100644 --- a/src/network/mcpe/protocol/SetTimePacket.php +++ b/src/network/mcpe/protocol/SetTimePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetTimePacket extends DataPacket implements ClientboundPacket{ @@ -48,7 +47,7 @@ class SetTimePacket extends DataPacket implements ClientboundPacket{ $out->putVarInt($this->time); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSetTime($this); } } diff --git a/src/network/mcpe/protocol/SetTitlePacket.php b/src/network/mcpe/protocol/SetTitlePacket.php index ca765ad530..e7acddc420 100644 --- a/src/network/mcpe/protocol/SetTitlePacket.php +++ b/src/network/mcpe/protocol/SetTitlePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetTitlePacket extends DataPacket implements ClientboundPacket{ @@ -65,7 +64,7 @@ class SetTitlePacket extends DataPacket implements ClientboundPacket{ $out->putVarInt($this->fadeOutTime); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSetTitle($this); } diff --git a/src/network/mcpe/protocol/SettingsCommandPacket.php b/src/network/mcpe/protocol/SettingsCommandPacket.php index 7b81a20983..4909470161 100644 --- a/src/network/mcpe/protocol/SettingsCommandPacket.php +++ b/src/network/mcpe/protocol/SettingsCommandPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SettingsCommandPacket extends DataPacket implements ServerboundPacket{ @@ -61,7 +60,7 @@ class SettingsCommandPacket extends DataPacket implements ServerboundPacket{ $out->putBool($this->suppressOutput); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSettingsCommand($this); } } diff --git a/src/network/mcpe/protocol/ShowCreditsPacket.php b/src/network/mcpe/protocol/ShowCreditsPacket.php index 3d3ea2ca1a..02cc700179 100644 --- a/src/network/mcpe/protocol/ShowCreditsPacket.php +++ b/src/network/mcpe/protocol/ShowCreditsPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ShowCreditsPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -49,7 +48,7 @@ class ShowCreditsPacket extends DataPacket implements ClientboundPacket, Serverb $out->putVarInt($this->status); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleShowCredits($this); } } diff --git a/src/network/mcpe/protocol/ShowProfilePacket.php b/src/network/mcpe/protocol/ShowProfilePacket.php index b8865b9ecd..d1a2c073ab 100644 --- a/src/network/mcpe/protocol/ShowProfilePacket.php +++ b/src/network/mcpe/protocol/ShowProfilePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ShowProfilePacket extends DataPacket implements ClientboundPacket{ @@ -42,7 +41,7 @@ class ShowProfilePacket extends DataPacket implements ClientboundPacket{ $out->putString($this->xuid); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleShowProfile($this); } } diff --git a/src/network/mcpe/protocol/ShowStoreOfferPacket.php b/src/network/mcpe/protocol/ShowStoreOfferPacket.php index 61f430a9d2..3896e4419e 100644 --- a/src/network/mcpe/protocol/ShowStoreOfferPacket.php +++ b/src/network/mcpe/protocol/ShowStoreOfferPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ShowStoreOfferPacket extends DataPacket implements ClientboundPacket{ @@ -46,7 +45,7 @@ class ShowStoreOfferPacket extends DataPacket implements ClientboundPacket{ $out->putBool($this->showAll); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleShowStoreOffer($this); } } diff --git a/src/network/mcpe/protocol/SimpleEventPacket.php b/src/network/mcpe/protocol/SimpleEventPacket.php index 732475b471..f571910722 100644 --- a/src/network/mcpe/protocol/SimpleEventPacket.php +++ b/src/network/mcpe/protocol/SimpleEventPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SimpleEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -45,7 +44,7 @@ class SimpleEventPacket extends DataPacket implements ClientboundPacket, Serverb $out->putLShort($this->eventType); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSimpleEvent($this); } } diff --git a/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php b/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php index 74c6b2b25f..c2f6cdaaf4 100644 --- a/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php +++ b/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SpawnExperienceOrbPacket extends DataPacket implements ServerboundPacket{ @@ -47,7 +46,7 @@ class SpawnExperienceOrbPacket extends DataPacket implements ServerboundPacket{ $out->putVarInt($this->amount); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSpawnExperienceOrb($this); } } diff --git a/src/network/mcpe/protocol/SpawnParticleEffectPacket.php b/src/network/mcpe/protocol/SpawnParticleEffectPacket.php index e5bf0e6a92..4595a39ea0 100644 --- a/src/network/mcpe/protocol/SpawnParticleEffectPacket.php +++ b/src/network/mcpe/protocol/SpawnParticleEffectPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; @@ -56,7 +55,7 @@ class SpawnParticleEffectPacket extends DataPacket implements ClientboundPacket{ $out->putString($this->particleName); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSpawnParticleEffect($this); } } diff --git a/src/network/mcpe/protocol/StartGamePacket.php b/src/network/mcpe/protocol/StartGamePacket.php index f61cba1358..4d9dc419f1 100644 --- a/src/network/mcpe/protocol/StartGamePacket.php +++ b/src/network/mcpe/protocol/StartGamePacket.php @@ -28,7 +28,6 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\TreeRoot; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; @@ -322,7 +321,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{ return $stream->getBuffer(); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleStartGame($this); } } diff --git a/src/network/mcpe/protocol/StopSoundPacket.php b/src/network/mcpe/protocol/StopSoundPacket.php index 50e92ede74..af4f05df9d 100644 --- a/src/network/mcpe/protocol/StopSoundPacket.php +++ b/src/network/mcpe/protocol/StopSoundPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class StopSoundPacket extends DataPacket implements ClientboundPacket{ @@ -46,7 +45,7 @@ class StopSoundPacket extends DataPacket implements ClientboundPacket{ $out->putBool($this->stopAll); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleStopSound($this); } } diff --git a/src/network/mcpe/protocol/StructureBlockUpdatePacket.php b/src/network/mcpe/protocol/StructureBlockUpdatePacket.php index f139c6e096..c3e1a33405 100644 --- a/src/network/mcpe/protocol/StructureBlockUpdatePacket.php +++ b/src/network/mcpe/protocol/StructureBlockUpdatePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\StructureEditorData; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; @@ -55,7 +54,7 @@ class StructureBlockUpdatePacket extends DataPacket implements ServerboundPacket $out->putBool($this->isPowered); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleStructureBlockUpdate($this); } } diff --git a/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php b/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php index 11344f0dd5..9c58f46cab 100644 --- a/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php +++ b/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\StructureSettings; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; @@ -62,7 +61,7 @@ class StructureTemplateDataRequestPacket extends DataPacket implements Serverbou $out->putByte($this->structureTemplateResponseType); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleStructureTemplateDataRequest($this); } } diff --git a/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php b/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php index 78f565296c..b2418d74e8 100644 --- a/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php +++ b/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class StructureTemplateDataResponsePacket extends DataPacket implements ClientboundPacket{ @@ -51,7 +50,7 @@ class StructureTemplateDataResponsePacket extends DataPacket implements Clientbo } } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleStructureTemplateDataResponse($this); } } diff --git a/src/network/mcpe/protocol/SubClientLoginPacket.php b/src/network/mcpe/protocol/SubClientLoginPacket.php index d2f8b4a091..8fd6709a74 100644 --- a/src/network/mcpe/protocol/SubClientLoginPacket.php +++ b/src/network/mcpe/protocol/SubClientLoginPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SubClientLoginPacket extends DataPacket implements ServerboundPacket{ @@ -42,7 +41,7 @@ class SubClientLoginPacket extends DataPacket implements ServerboundPacket{ $out->putString($this->connectionRequestData); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleSubClientLogin($this); } } diff --git a/src/network/mcpe/protocol/TakeItemActorPacket.php b/src/network/mcpe/protocol/TakeItemActorPacket.php index 6a689b0eff..83eff49d51 100644 --- a/src/network/mcpe/protocol/TakeItemActorPacket.php +++ b/src/network/mcpe/protocol/TakeItemActorPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class TakeItemActorPacket extends DataPacket implements ClientboundPacket{ @@ -53,7 +52,7 @@ class TakeItemActorPacket extends DataPacket implements ClientboundPacket{ $out->putEntityRuntimeId($this->eid); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleTakeItemActor($this); } } diff --git a/src/network/mcpe/protocol/TextPacket.php b/src/network/mcpe/protocol/TextPacket.php index 0cc905363d..ccbbbe53ec 100644 --- a/src/network/mcpe/protocol/TextPacket.php +++ b/src/network/mcpe/protocol/TextPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; @@ -178,7 +177,7 @@ class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPac $out->putString($this->platformChatId); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleText($this); } } diff --git a/src/network/mcpe/protocol/TickSyncPacket.php b/src/network/mcpe/protocol/TickSyncPacket.php index 47c0e3c0ef..bc989030fe 100644 --- a/src/network/mcpe/protocol/TickSyncPacket.php +++ b/src/network/mcpe/protocol/TickSyncPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class TickSyncPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -68,7 +67,7 @@ class TickSyncPacket extends DataPacket implements ClientboundPacket, Serverboun $out->putLLong($this->serverReceiveTime); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleTickSync($this); } } diff --git a/src/network/mcpe/protocol/TransferPacket.php b/src/network/mcpe/protocol/TransferPacket.php index 22bc5de944..22eb3aaccd 100644 --- a/src/network/mcpe/protocol/TransferPacket.php +++ b/src/network/mcpe/protocol/TransferPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class TransferPacket extends DataPacket implements ClientboundPacket{ @@ -53,7 +52,7 @@ class TransferPacket extends DataPacket implements ClientboundPacket{ $out->putLShort($this->port); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleTransfer($this); } } diff --git a/src/network/mcpe/protocol/UnknownPacket.php b/src/network/mcpe/protocol/UnknownPacket.php index c5ba65a7a6..e4cac4aefe 100644 --- a/src/network/mcpe/protocol/UnknownPacket.php +++ b/src/network/mcpe/protocol/UnknownPacket.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function ord; use function strlen; @@ -61,7 +60,7 @@ class UnknownPacket extends DataPacket{ $out->put($this->payload); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return false; } } diff --git a/src/network/mcpe/protocol/UpdateAttributesPacket.php b/src/network/mcpe/protocol/UpdateAttributesPacket.php index 347a1552cc..aef34a6bf1 100644 --- a/src/network/mcpe/protocol/UpdateAttributesPacket.php +++ b/src/network/mcpe/protocol/UpdateAttributesPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\entity\Attribute; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function array_values; @@ -60,7 +59,7 @@ class UpdateAttributesPacket extends DataPacket implements ClientboundPacket{ $out->putAttributeList(...array_values($this->entries)); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleUpdateAttributes($this); } } diff --git a/src/network/mcpe/protocol/UpdateBlockPacket.php b/src/network/mcpe/protocol/UpdateBlockPacket.php index c7cb2669a2..0d739b719a 100644 --- a/src/network/mcpe/protocol/UpdateBlockPacket.php +++ b/src/network/mcpe/protocol/UpdateBlockPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class UpdateBlockPacket extends DataPacket implements ClientboundPacket{ @@ -73,7 +72,7 @@ class UpdateBlockPacket extends DataPacket implements ClientboundPacket{ $out->putUnsignedVarInt($this->dataLayerId); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleUpdateBlock($this); } } diff --git a/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php b/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php index 9d972aea3e..9b42188ac6 100644 --- a/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php +++ b/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php @@ -27,7 +27,6 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; @@ -55,7 +54,7 @@ class UpdateBlockPropertiesPacket extends DataPacket implements ClientboundPacke $out->put($this->nbt); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleUpdateBlockProperties($this); } } diff --git a/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php b/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php index 605550dd3c..8a08b3e979 100644 --- a/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php +++ b/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class UpdateBlockSyncedPacket extends UpdateBlockPacket{ @@ -48,7 +47,7 @@ class UpdateBlockSyncedPacket extends UpdateBlockPacket{ $out->putUnsignedVarLong($this->uvarint64_2); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleUpdateBlockSynced($this); } } diff --git a/src/network/mcpe/protocol/UpdateEquipPacket.php b/src/network/mcpe/protocol/UpdateEquipPacket.php index 61629a037c..290a2a550a 100644 --- a/src/network/mcpe/protocol/UpdateEquipPacket.php +++ b/src/network/mcpe/protocol/UpdateEquipPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class UpdateEquipPacket extends DataPacket implements ClientboundPacket{ @@ -58,7 +57,7 @@ class UpdateEquipPacket extends DataPacket implements ClientboundPacket{ $out->put($this->namedtag); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleUpdateEquip($this); } } diff --git a/src/network/mcpe/protocol/UpdateSoftEnumPacket.php b/src/network/mcpe/protocol/UpdateSoftEnumPacket.php index f838a195d9..767ccf5c73 100644 --- a/src/network/mcpe/protocol/UpdateSoftEnumPacket.php +++ b/src/network/mcpe/protocol/UpdateSoftEnumPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; @@ -60,7 +59,7 @@ class UpdateSoftEnumPacket extends DataPacket implements ClientboundPacket{ $out->putByte($this->type); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleUpdateSoftEnum($this); } } diff --git a/src/network/mcpe/protocol/UpdateTradePacket.php b/src/network/mcpe/protocol/UpdateTradePacket.php index a97bbcb57c..59df00bb77 100644 --- a/src/network/mcpe/protocol/UpdateTradePacket.php +++ b/src/network/mcpe/protocol/UpdateTradePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; @@ -81,7 +80,7 @@ class UpdateTradePacket extends DataPacket implements ClientboundPacket{ $out->put($this->offers); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleUpdateTrade($this); } } diff --git a/src/network/mcpe/protocol/VideoStreamConnectPacket.php b/src/network/mcpe/protocol/VideoStreamConnectPacket.php index 94e8250c2a..dfb4750b96 100644 --- a/src/network/mcpe/protocol/VideoStreamConnectPacket.php +++ b/src/network/mcpe/protocol/VideoStreamConnectPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class VideoStreamConnectPacket extends DataPacket implements ClientboundPacket{ @@ -61,7 +60,7 @@ class VideoStreamConnectPacket extends DataPacket implements ClientboundPacket{ $out->putLInt($this->resolutionY); } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return $handler->handleVideoStreamConnect($this); } } diff --git a/tests/phpunit/network/mcpe/protocol/TestPacket.php b/tests/phpunit/network/mcpe/protocol/TestPacket.php index 17a30bcb01..0a68aea30f 100644 --- a/tests/phpunit/network/mcpe/protocol/TestPacket.php +++ b/tests/phpunit/network/mcpe/protocol/TestPacket.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; -use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class TestPacket extends DataPacket{ @@ -37,7 +36,7 @@ class TestPacket extends DataPacket{ } - public function handle(PacketHandler $handler) : bool{ + public function handle(PacketHandlerInterface $handler) : bool{ return false; } } From 33f899f2fcfe9f851fb4cc5ec55c60996e00ff53 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 23 Apr 2020 15:27:46 +0100 Subject: [PATCH 1446/3224] protocol: imports cleanup --- src/network/mcpe/protocol/AddActorPacket.php | 1 - .../mcpe/protocol/AvailableActorIdentifiersPacket.php | 1 - src/network/mcpe/protocol/DataPacket.php | 5 ----- src/network/mcpe/protocol/ResourcePackChunkDataPacket.php | 1 - src/network/mcpe/protocol/types/PlayerListEntry.php | 1 - src/network/mcpe/protocol/types/RuntimeBlockMapping.php | 2 -- .../mcpe/protocol/types/inventory/NetworkInventoryAction.php | 2 -- 7 files changed, 13 deletions(-) diff --git a/src/network/mcpe/protocol/AddActorPacket.php b/src/network/mcpe/protocol/AddActorPacket.php index 3b1572309a..c207dad19b 100644 --- a/src/network/mcpe/protocol/AddActorPacket.php +++ b/src/network/mcpe/protocol/AddActorPacket.php @@ -31,7 +31,6 @@ use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; -use function array_search; use function count; class AddActorPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php b/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php index f5de597f70..01d3dfce2e 100644 --- a/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php +++ b/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\serializer\NetworkBinaryStream; -use function base64_decode; use function file_get_contents; class AvailableActorIdentifiersPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/DataPacket.php b/src/network/mcpe/protocol/DataPacket.php index 0d5601cc07..e58cb7e1e0 100644 --- a/src/network/mcpe/protocol/DataPacket.php +++ b/src/network/mcpe/protocol/DataPacket.php @@ -28,12 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; -use pocketmine\utils\Utils; -use function bin2hex; use function get_class; -use function is_object; -use function is_string; -use function method_exists; abstract class DataPacket implements Packet{ diff --git a/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php b/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php index 2c4096a711..a2badc20c2 100644 --- a/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php +++ b/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\serializer\NetworkBinaryStream; -use function strlen; class ResourcePackChunkDataPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_CHUNK_DATA_PACKET; diff --git a/src/network/mcpe/protocol/types/PlayerListEntry.php b/src/network/mcpe/protocol/types/PlayerListEntry.php index ee46417a93..1393bf48b0 100644 --- a/src/network/mcpe/protocol/types/PlayerListEntry.php +++ b/src/network/mcpe/protocol/types/PlayerListEntry.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types; -use pocketmine\entity\Skin; use pocketmine\utils\UUID; class PlayerListEntry{ diff --git a/src/network/mcpe/protocol/types/RuntimeBlockMapping.php b/src/network/mcpe/protocol/types/RuntimeBlockMapping.php index f928238273..45b422dd8c 100644 --- a/src/network/mcpe/protocol/types/RuntimeBlockMapping.php +++ b/src/network/mcpe/protocol/types/RuntimeBlockMapping.php @@ -27,9 +27,7 @@ use pocketmine\block\BlockLegacyIds; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; -use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; -use pocketmine\utils\BinaryDataException; use function file_get_contents; use function getmypid; use function json_decode; diff --git a/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php b/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php index db8b34db9c..1ade37922b 100644 --- a/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php +++ b/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php @@ -24,8 +24,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\crafting\CraftingGrid; -use pocketmine\inventory\AnvilInventory; -use pocketmine\inventory\EnchantInventory; use pocketmine\inventory\transaction\action\CreateItemAction; use pocketmine\inventory\transaction\action\DestroyItemAction; use pocketmine\inventory\transaction\action\DropItemAction; From ebcfab4b61367e915ef4619e1e4c7e85420111dd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 23 Apr 2020 15:40:23 +0100 Subject: [PATCH 1447/3224] NetworkInventoryAction: move type translation to TypeConverter --- src/network/mcpe/convert/TypeConverter.php | 81 +++++++++++++++++++ .../mcpe/handler/InGamePacketHandler.php | 7 +- .../inventory/NetworkInventoryAction.php | 79 ------------------ 3 files changed, 85 insertions(+), 82 deletions(-) diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index 775095a567..1a6a79a7ea 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -22,14 +22,24 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\convert; +use pocketmine\crafting\CraftingGrid; +use pocketmine\inventory\transaction\action\CreateItemAction; +use pocketmine\inventory\transaction\action\DestroyItemAction; +use pocketmine\inventory\transaction\action\DropItemAction; +use pocketmine\inventory\transaction\action\InventoryAction; +use pocketmine\inventory\transaction\action\SlotChangeAction; use pocketmine\item\Durable; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\ItemIds; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; +use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; +use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; +use pocketmine\network\mcpe\protocol\types\inventory\NetworkInventoryAction; use pocketmine\network\mcpe\protocol\types\recipe\RecipeIngredient; +use pocketmine\player\Player; class TypeConverter{ private const DAMAGE_TAG = "Damage"; //TAG_Int @@ -121,4 +131,75 @@ class TypeConverter{ $compound ); } + + /** + * @throws \UnexpectedValueException + */ + public function createInventoryAction(NetworkInventoryAction $action, Player $player) : ?InventoryAction{ + $old = TypeConverter::getInstance()->netItemStackToCore($action->oldItem); + $new = TypeConverter::getInstance()->netItemStackToCore($action->newItem); + if($old->equalsExact($new)){ + //filter out useless noise in 1.13 + return null; + } + switch($action->sourceType){ + case NetworkInventoryAction::SOURCE_CONTAINER: + if($action->windowId === ContainerIds::UI and $action->inventorySlot > 0){ + if($action->inventorySlot === 50){ + return null; //useless noise + } + if($action->inventorySlot >= 28 and $action->inventorySlot <= 31){ + $window = $player->getCraftingGrid(); + if($window->getGridWidth() !== CraftingGrid::SIZE_SMALL){ + throw new \UnexpectedValueException("Expected small crafting grid"); + } + $slot = $action->inventorySlot - 28; + }elseif($action->inventorySlot >= 32 and $action->inventorySlot <= 40){ + $window = $player->getCraftingGrid(); + if($window->getGridWidth() !== CraftingGrid::SIZE_BIG){ + throw new \UnexpectedValueException("Expected big crafting grid"); + } + $slot = $action->inventorySlot - 32; + }else{ + throw new \UnexpectedValueException("Unhandled magic UI slot offset $action->inventorySlot"); + } + }else{ + $window = $player->getNetworkSession()->getInvManager()->getWindow($action->windowId); + $slot = $action->inventorySlot; + } + if($window !== null){ + return new SlotChangeAction($window, $slot, $old, $new); + } + + throw new \UnexpectedValueException("No open container with window ID $action->windowId"); + case NetworkInventoryAction::SOURCE_WORLD: + if($action->inventorySlot !== NetworkInventoryAction::ACTION_MAGIC_SLOT_DROP_ITEM){ + throw new \UnexpectedValueException("Only expecting drop-item world actions from the client!"); + } + + return new DropItemAction($new); + case NetworkInventoryAction::SOURCE_CREATIVE: + switch($action->inventorySlot){ + case NetworkInventoryAction::ACTION_MAGIC_SLOT_CREATIVE_DELETE_ITEM: + return new DestroyItemAction($new); + case NetworkInventoryAction::ACTION_MAGIC_SLOT_CREATIVE_CREATE_ITEM: + return new CreateItemAction($new); + default: + throw new \UnexpectedValueException("Unexpected creative action type $action->inventorySlot"); + + } + case NetworkInventoryAction::SOURCE_TODO: + //These types need special handling. + switch($action->windowId){ + case NetworkInventoryAction::SOURCE_TYPE_CRAFTING_RESULT: + case NetworkInventoryAction::SOURCE_TYPE_CRAFTING_USE_INGREDIENT: + return null; + } + + //TODO: more stuff + throw new \UnexpectedValueException("No open container with window ID $action->windowId"); + default: + throw new \UnexpectedValueException("Unknown inventory source type $action->sourceType"); + } + } } \ No newline at end of file diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 70c03c1c5c..692f736e69 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -205,9 +205,10 @@ class InGamePacketHandler extends PacketHandler{ $isCrafting = false; $isFinalCraftingPart = false; + $converter = TypeConverter::getInstance(); foreach($data->getActions() as $networkInventoryAction){ - $old = TypeConverter::getInstance()->netItemStackToCore($networkInventoryAction->oldItem); - $new = TypeConverter::getInstance()->netItemStackToCore($networkInventoryAction->newItem); + $old = $converter->netItemStackToCore($networkInventoryAction->oldItem); + $new = $converter->netItemStackToCore($networkInventoryAction->newItem); if( $networkInventoryAction->sourceType === NetworkInventoryAction::SOURCE_CONTAINER and $networkInventoryAction->windowId === ContainerIds::UI and @@ -228,7 +229,7 @@ class InGamePacketHandler extends PacketHandler{ } try{ - $action = $networkInventoryAction->createInventoryAction($this->player); + $action = $converter->createInventoryAction($networkInventoryAction, $this->player); if($action !== null){ $actions[] = $action; } diff --git a/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php b/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php index 1ade37922b..6d87dfc526 100644 --- a/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php +++ b/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php @@ -23,16 +23,8 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\inventory; -use pocketmine\crafting\CraftingGrid; -use pocketmine\inventory\transaction\action\CreateItemAction; -use pocketmine\inventory\transaction\action\DestroyItemAction; -use pocketmine\inventory\transaction\action\DropItemAction; -use pocketmine\inventory\transaction\action\InventoryAction; -use pocketmine\inventory\transaction\action\SlotChangeAction; use pocketmine\network\BadPacketException; -use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; -use pocketmine\player\Player; use pocketmine\utils\BinaryDataException; class NetworkInventoryAction{ @@ -143,75 +135,4 @@ class NetworkInventoryAction{ $packet->putSlot($this->oldItem); $packet->putSlot($this->newItem); } - - /** - * @throws \UnexpectedValueException - */ - public function createInventoryAction(Player $player) : ?InventoryAction{ - $old = TypeConverter::getInstance()->netItemStackToCore($this->oldItem); - $new = TypeConverter::getInstance()->netItemStackToCore($this->newItem); - if($old->equalsExact($new)){ - //filter out useless noise in 1.13 - return null; - } - switch($this->sourceType){ - case self::SOURCE_CONTAINER: - if($this->windowId === ContainerIds::UI and $this->inventorySlot > 0){ - if($this->inventorySlot === 50){ - return null; //useless noise - } - if($this->inventorySlot >= 28 and $this->inventorySlot <= 31){ - $window = $player->getCraftingGrid(); - if($window->getGridWidth() !== CraftingGrid::SIZE_SMALL){ - throw new \UnexpectedValueException("Expected small crafting grid"); - } - $slot = $this->inventorySlot - 28; - }elseif($this->inventorySlot >= 32 and $this->inventorySlot <= 40){ - $window = $player->getCraftingGrid(); - if($window->getGridWidth() !== CraftingGrid::SIZE_BIG){ - throw new \UnexpectedValueException("Expected big crafting grid"); - } - $slot = $this->inventorySlot - 32; - }else{ - throw new \UnexpectedValueException("Unhandled magic UI slot offset $this->inventorySlot"); - } - }else{ - $window = $player->getNetworkSession()->getInvManager()->getWindow($this->windowId); - $slot = $this->inventorySlot; - } - if($window !== null){ - return new SlotChangeAction($window, $slot, $old, $new); - } - - throw new \UnexpectedValueException("No open container with window ID $this->windowId"); - case self::SOURCE_WORLD: - if($this->inventorySlot !== self::ACTION_MAGIC_SLOT_DROP_ITEM){ - throw new \UnexpectedValueException("Only expecting drop-item world actions from the client!"); - } - - return new DropItemAction($new); - case self::SOURCE_CREATIVE: - switch($this->inventorySlot){ - case self::ACTION_MAGIC_SLOT_CREATIVE_DELETE_ITEM: - return new DestroyItemAction($new); - case self::ACTION_MAGIC_SLOT_CREATIVE_CREATE_ITEM: - return new CreateItemAction($new); - default: - throw new \UnexpectedValueException("Unexpected creative action type $this->inventorySlot"); - - } - case self::SOURCE_TODO: - //These types need special handling. - switch($this->windowId){ - case self::SOURCE_TYPE_CRAFTING_RESULT: - case self::SOURCE_TYPE_CRAFTING_USE_INGREDIENT: - return null; - } - - //TODO: more stuff - throw new \UnexpectedValueException("No open container with window ID $this->windowId"); - default: - throw new \UnexpectedValueException("Unknown inventory source type $this->sourceType"); - } - } } From f3d7c320a12286a5f44c2e9dcfc9e2173f66bc8a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 23 Apr 2020 15:46:37 +0100 Subject: [PATCH 1448/3224] move SkinAdapter stuff to convert package --- src/entity/Human.php | 2 +- src/network/mcpe/NetworkSession.php | 2 +- .../mcpe/{protocol/types => convert}/LegacySkinAdapter.php | 4 +++- src/network/mcpe/{protocol/types => convert}/SkinAdapter.php | 3 ++- .../mcpe/{protocol/types => convert}/SkinAdapterSingleton.php | 2 +- src/network/mcpe/handler/InGamePacketHandler.php | 2 +- src/network/mcpe/handler/LoginPacketHandler.php | 2 +- src/world/particle/FloatingTextParticle.php | 2 +- 8 files changed, 11 insertions(+), 8 deletions(-) rename src/network/mcpe/{protocol/types => convert}/LegacySkinAdapter.php (93%) rename src/network/mcpe/{protocol/types => convert}/SkinAdapter.php (92%) rename src/network/mcpe/{protocol/types => convert}/SkinAdapterSingleton.php (95%) diff --git a/src/entity/Human.php b/src/entity/Human.php index c85e9ee575..c357bf1d84 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -41,6 +41,7 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; +use pocketmine\network\mcpe\convert\SkinAdapterSingleton; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\ActorEventPacket; use pocketmine\network\mcpe\protocol\AddPlayerPacket; @@ -50,7 +51,6 @@ use pocketmine\network\mcpe\protocol\PlayerSkinPacket; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\entity\StringMetadataProperty; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; -use pocketmine\network\mcpe\protocol\types\SkinAdapterSingleton; use pocketmine\player\Player; use pocketmine\utils\Limits; use pocketmine\utils\UUID; diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 4b81e1c3a7..85863b12fd 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -37,6 +37,7 @@ use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\compression\CompressBatchPromise; use pocketmine\network\mcpe\compression\DecompressionException; use pocketmine\network\mcpe\compression\Zlib; +use pocketmine\network\mcpe\convert\SkinAdapterSingleton; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\encryption\DecryptionException; use pocketmine\network\mcpe\encryption\NetworkCipher; @@ -78,7 +79,6 @@ use pocketmine\network\mcpe\protocol\types\entity\Attribute as NetworkAttribute; use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; -use pocketmine\network\mcpe\protocol\types\SkinAdapterSingleton; use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; use pocketmine\network\NetworkSessionManager; use pocketmine\player\GameMode; diff --git a/src/network/mcpe/protocol/types/LegacySkinAdapter.php b/src/network/mcpe/convert/LegacySkinAdapter.php similarity index 93% rename from src/network/mcpe/protocol/types/LegacySkinAdapter.php rename to src/network/mcpe/convert/LegacySkinAdapter.php index 3b81144cd5..74f74a0ee8 100644 --- a/src/network/mcpe/protocol/types/LegacySkinAdapter.php +++ b/src/network/mcpe/convert/LegacySkinAdapter.php @@ -21,10 +21,12 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\convert; use pocketmine\entity\Skin; +use pocketmine\network\mcpe\protocol\types\SkinData; +use pocketmine\network\mcpe\protocol\types\SkinImage; use function is_string; use function json_decode; use function json_encode; diff --git a/src/network/mcpe/protocol/types/SkinAdapter.php b/src/network/mcpe/convert/SkinAdapter.php similarity index 92% rename from src/network/mcpe/protocol/types/SkinAdapter.php rename to src/network/mcpe/convert/SkinAdapter.php index 357d7c2aba..54ae833ea9 100644 --- a/src/network/mcpe/protocol/types/SkinAdapter.php +++ b/src/network/mcpe/convert/SkinAdapter.php @@ -21,9 +21,10 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\convert; use pocketmine\entity\Skin; +use pocketmine\network\mcpe\protocol\types\SkinData; /** * Used to convert new skin data to the skin entity or old skin entity to skin data. diff --git a/src/network/mcpe/protocol/types/SkinAdapterSingleton.php b/src/network/mcpe/convert/SkinAdapterSingleton.php similarity index 95% rename from src/network/mcpe/protocol/types/SkinAdapterSingleton.php rename to src/network/mcpe/convert/SkinAdapterSingleton.php index b92cdf0df3..c49d3a780c 100644 --- a/src/network/mcpe/protocol/types/SkinAdapterSingleton.php +++ b/src/network/mcpe/convert/SkinAdapterSingleton.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\convert; /** * Accessor for SkinAdapter diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 692f736e69..235c4c70e8 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -38,6 +38,7 @@ use pocketmine\math\Vector3; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\StringTag; use pocketmine\network\BadPacketException; +use pocketmine\network\mcpe\convert\SkinAdapterSingleton; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\ActorEventPacket; @@ -83,7 +84,6 @@ use pocketmine\network\mcpe\protocol\types\inventory\NormalTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\UseItemOnEntityTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\UseItemTransactionData; -use pocketmine\network\mcpe\protocol\types\SkinAdapterSingleton; use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; use pocketmine\player\Player; use function array_push; diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index 87d720df1f..6553293b5d 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -27,6 +27,7 @@ use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; use pocketmine\event\player\PlayerPreLoginEvent; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\auth\ProcessLoginTask; +use pocketmine\network\mcpe\convert\SkinAdapterSingleton; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\LoginPacket; use pocketmine\network\mcpe\protocol\PlayStatusPacket; @@ -35,7 +36,6 @@ use pocketmine\network\mcpe\protocol\types\login\ClientDataPersonaPieceTintColor use pocketmine\network\mcpe\protocol\types\login\ClientDataPersonaSkinPiece; use pocketmine\network\mcpe\protocol\types\PersonaPieceTintColor; use pocketmine\network\mcpe\protocol\types\PersonaSkinPiece; -use pocketmine\network\mcpe\protocol\types\SkinAdapterSingleton; use pocketmine\network\mcpe\protocol\types\SkinAnimation; use pocketmine\network\mcpe\protocol\types\SkinData; use pocketmine\network\mcpe\protocol\types\SkinImage; diff --git a/src/world/particle/FloatingTextParticle.php b/src/world/particle/FloatingTextParticle.php index 76d2c3f80a..0d5e467867 100644 --- a/src/world/particle/FloatingTextParticle.php +++ b/src/world/particle/FloatingTextParticle.php @@ -26,6 +26,7 @@ namespace pocketmine\world\particle; use pocketmine\entity\EntityFactory; use pocketmine\entity\Skin; use pocketmine\math\Vector3; +use pocketmine\network\mcpe\convert\SkinAdapterSingleton; use pocketmine\network\mcpe\protocol\AddPlayerPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\RemoveActorPacket; @@ -35,7 +36,6 @@ use pocketmine\network\mcpe\protocol\types\entity\FloatMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\LongMetadataProperty; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; -use pocketmine\network\mcpe\protocol\types\SkinAdapterSingleton; use pocketmine\utils\UUID; use function str_repeat; From 095a21ea5a774406a67f68eee8a7969f9e318061 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 23 Apr 2020 16:11:47 +0100 Subject: [PATCH 1449/3224] PacketPool is now non-static this allows greater flexibility for customisation, and will facilitate future multi version support. --- src/network/Network.php | 2 - src/network/mcpe/PacketBatch.php | 2 +- src/network/mcpe/protocol/PacketPool.php | 312 ++++++++++++----------- 3 files changed, 162 insertions(+), 154 deletions(-) diff --git a/src/network/Network.php b/src/network/Network.php index 320d45be58..2f671df3ca 100644 --- a/src/network/Network.php +++ b/src/network/Network.php @@ -28,7 +28,6 @@ namespace pocketmine\network; use pocketmine\event\server\NetworkInterfaceRegisterEvent; use pocketmine\event\server\NetworkInterfaceUnregisterEvent; -use pocketmine\network\mcpe\protocol\PacketPool; use function base64_encode; use function get_class; use function preg_match; @@ -64,7 +63,6 @@ class Network{ private $logger; public function __construct(\Logger $logger){ - PacketPool::init(); $this->sessionManager = new NetworkSessionManager(); $this->logger = $logger; } diff --git a/src/network/mcpe/PacketBatch.php b/src/network/mcpe/PacketBatch.php index 82f9412f1e..c2b1458797 100644 --- a/src/network/mcpe/PacketBatch.php +++ b/src/network/mcpe/PacketBatch.php @@ -39,7 +39,7 @@ class PacketBatch extends NetworkBinaryStream{ * @throws BinaryDataException */ public function getPacket() : Packet{ - return PacketPool::getPacket($this->getString()); + return PacketPool::getInstance()->getPacket($this->getString()); } /** diff --git a/src/network/mcpe/protocol/PacketPool.php b/src/network/mcpe/protocol/PacketPool.php index a619fe6458..6c0fc2d0ec 100644 --- a/src/network/mcpe/protocol/PacketPool.php +++ b/src/network/mcpe/protocol/PacketPool.php @@ -27,170 +27,180 @@ use pocketmine\utils\Binary; use pocketmine\utils\BinaryDataException; class PacketPool{ + /** @var self|null */ + protected static $instance = null; + + public static function getInstance() : self{ + if(self::$instance === null){ + self::$instance = new self; + } + return self::$instance; + } + /** @var \SplFixedArray */ - protected static $pool; + protected $pool; - public static function init() : void{ - static::$pool = new \SplFixedArray(256); + public function __construct(){ + $this->pool = new \SplFixedArray(256); - static::registerPacket(new LoginPacket()); - static::registerPacket(new PlayStatusPacket()); - static::registerPacket(new ServerToClientHandshakePacket()); - static::registerPacket(new ClientToServerHandshakePacket()); - static::registerPacket(new DisconnectPacket()); - static::registerPacket(new ResourcePacksInfoPacket()); - static::registerPacket(new ResourcePackStackPacket()); - static::registerPacket(new ResourcePackClientResponsePacket()); - static::registerPacket(new TextPacket()); - static::registerPacket(new SetTimePacket()); - static::registerPacket(new StartGamePacket()); - static::registerPacket(new AddPlayerPacket()); - static::registerPacket(new AddActorPacket()); - static::registerPacket(new RemoveActorPacket()); - static::registerPacket(new AddItemActorPacket()); - static::registerPacket(new TakeItemActorPacket()); - static::registerPacket(new MoveActorAbsolutePacket()); - static::registerPacket(new MovePlayerPacket()); - static::registerPacket(new RiderJumpPacket()); - static::registerPacket(new UpdateBlockPacket()); - static::registerPacket(new AddPaintingPacket()); - static::registerPacket(new TickSyncPacket()); - static::registerPacket(new LevelSoundEventPacketV1()); - static::registerPacket(new LevelEventPacket()); - static::registerPacket(new BlockEventPacket()); - static::registerPacket(new ActorEventPacket()); - static::registerPacket(new MobEffectPacket()); - static::registerPacket(new UpdateAttributesPacket()); - static::registerPacket(new InventoryTransactionPacket()); - static::registerPacket(new MobEquipmentPacket()); - static::registerPacket(new MobArmorEquipmentPacket()); - static::registerPacket(new InteractPacket()); - static::registerPacket(new BlockPickRequestPacket()); - static::registerPacket(new ActorPickRequestPacket()); - static::registerPacket(new PlayerActionPacket()); - static::registerPacket(new ActorFallPacket()); - static::registerPacket(new HurtArmorPacket()); - static::registerPacket(new SetActorDataPacket()); - static::registerPacket(new SetActorMotionPacket()); - static::registerPacket(new SetActorLinkPacket()); - static::registerPacket(new SetHealthPacket()); - static::registerPacket(new SetSpawnPositionPacket()); - static::registerPacket(new AnimatePacket()); - static::registerPacket(new RespawnPacket()); - static::registerPacket(new ContainerOpenPacket()); - static::registerPacket(new ContainerClosePacket()); - static::registerPacket(new PlayerHotbarPacket()); - static::registerPacket(new InventoryContentPacket()); - static::registerPacket(new InventorySlotPacket()); - static::registerPacket(new ContainerSetDataPacket()); - static::registerPacket(new CraftingDataPacket()); - static::registerPacket(new CraftingEventPacket()); - static::registerPacket(new GuiDataPickItemPacket()); - static::registerPacket(new AdventureSettingsPacket()); - static::registerPacket(new BlockActorDataPacket()); - static::registerPacket(new PlayerInputPacket()); - static::registerPacket(new LevelChunkPacket()); - static::registerPacket(new SetCommandsEnabledPacket()); - static::registerPacket(new SetDifficultyPacket()); - static::registerPacket(new ChangeDimensionPacket()); - static::registerPacket(new SetPlayerGameTypePacket()); - static::registerPacket(new PlayerListPacket()); - static::registerPacket(new SimpleEventPacket()); - static::registerPacket(new EventPacket()); - static::registerPacket(new SpawnExperienceOrbPacket()); - static::registerPacket(new ClientboundMapItemDataPacket()); - static::registerPacket(new MapInfoRequestPacket()); - static::registerPacket(new RequestChunkRadiusPacket()); - static::registerPacket(new ChunkRadiusUpdatedPacket()); - static::registerPacket(new ItemFrameDropItemPacket()); - static::registerPacket(new GameRulesChangedPacket()); - static::registerPacket(new CameraPacket()); - static::registerPacket(new BossEventPacket()); - static::registerPacket(new ShowCreditsPacket()); - static::registerPacket(new AvailableCommandsPacket()); - static::registerPacket(new CommandRequestPacket()); - static::registerPacket(new CommandBlockUpdatePacket()); - static::registerPacket(new CommandOutputPacket()); - static::registerPacket(new UpdateTradePacket()); - static::registerPacket(new UpdateEquipPacket()); - static::registerPacket(new ResourcePackDataInfoPacket()); - static::registerPacket(new ResourcePackChunkDataPacket()); - static::registerPacket(new ResourcePackChunkRequestPacket()); - static::registerPacket(new TransferPacket()); - static::registerPacket(new PlaySoundPacket()); - static::registerPacket(new StopSoundPacket()); - static::registerPacket(new SetTitlePacket()); - static::registerPacket(new AddBehaviorTreePacket()); - static::registerPacket(new StructureBlockUpdatePacket()); - static::registerPacket(new ShowStoreOfferPacket()); - static::registerPacket(new PurchaseReceiptPacket()); - static::registerPacket(new PlayerSkinPacket()); - static::registerPacket(new SubClientLoginPacket()); - static::registerPacket(new AutomationClientConnectPacket()); - static::registerPacket(new SetLastHurtByPacket()); - static::registerPacket(new BookEditPacket()); - static::registerPacket(new NpcRequestPacket()); - static::registerPacket(new PhotoTransferPacket()); - static::registerPacket(new ModalFormRequestPacket()); - static::registerPacket(new ModalFormResponsePacket()); - static::registerPacket(new ServerSettingsRequestPacket()); - static::registerPacket(new ServerSettingsResponsePacket()); - static::registerPacket(new ShowProfilePacket()); - static::registerPacket(new SetDefaultGameTypePacket()); - static::registerPacket(new RemoveObjectivePacket()); - static::registerPacket(new SetDisplayObjectivePacket()); - static::registerPacket(new SetScorePacket()); - static::registerPacket(new LabTablePacket()); - static::registerPacket(new UpdateBlockSyncedPacket()); - static::registerPacket(new MoveActorDeltaPacket()); - static::registerPacket(new SetScoreboardIdentityPacket()); - static::registerPacket(new SetLocalPlayerAsInitializedPacket()); - static::registerPacket(new UpdateSoftEnumPacket()); - static::registerPacket(new NetworkStackLatencyPacket()); - static::registerPacket(new ScriptCustomEventPacket()); - static::registerPacket(new SpawnParticleEffectPacket()); - static::registerPacket(new AvailableActorIdentifiersPacket()); - static::registerPacket(new LevelSoundEventPacketV2()); - static::registerPacket(new NetworkChunkPublisherUpdatePacket()); - static::registerPacket(new BiomeDefinitionListPacket()); - static::registerPacket(new LevelSoundEventPacket()); - static::registerPacket(new LevelEventGenericPacket()); - static::registerPacket(new LecternUpdatePacket()); - static::registerPacket(new VideoStreamConnectPacket()); - static::registerPacket(new AddEntityPacket()); - static::registerPacket(new RemoveEntityPacket()); - static::registerPacket(new ClientCacheStatusPacket()); - static::registerPacket(new OnScreenTextureAnimationPacket()); - static::registerPacket(new MapCreateLockedCopyPacket()); - static::registerPacket(new StructureTemplateDataRequestPacket()); - static::registerPacket(new StructureTemplateDataResponsePacket()); - static::registerPacket(new UpdateBlockPropertiesPacket()); - static::registerPacket(new ClientCacheBlobStatusPacket()); - static::registerPacket(new ClientCacheMissResponsePacket()); - static::registerPacket(new EducationSettingsPacket()); - static::registerPacket(new EmotePacket()); - static::registerPacket(new MultiplayerSettingsPacket()); - static::registerPacket(new SettingsCommandPacket()); - static::registerPacket(new AnvilDamagePacket()); - static::registerPacket(new CompletedUsingItemPacket()); - static::registerPacket(new NetworkSettingsPacket()); - static::registerPacket(new PlayerAuthInputPacket()); + $this->registerPacket(new LoginPacket()); + $this->registerPacket(new PlayStatusPacket()); + $this->registerPacket(new ServerToClientHandshakePacket()); + $this->registerPacket(new ClientToServerHandshakePacket()); + $this->registerPacket(new DisconnectPacket()); + $this->registerPacket(new ResourcePacksInfoPacket()); + $this->registerPacket(new ResourcePackStackPacket()); + $this->registerPacket(new ResourcePackClientResponsePacket()); + $this->registerPacket(new TextPacket()); + $this->registerPacket(new SetTimePacket()); + $this->registerPacket(new StartGamePacket()); + $this->registerPacket(new AddPlayerPacket()); + $this->registerPacket(new AddActorPacket()); + $this->registerPacket(new RemoveActorPacket()); + $this->registerPacket(new AddItemActorPacket()); + $this->registerPacket(new TakeItemActorPacket()); + $this->registerPacket(new MoveActorAbsolutePacket()); + $this->registerPacket(new MovePlayerPacket()); + $this->registerPacket(new RiderJumpPacket()); + $this->registerPacket(new UpdateBlockPacket()); + $this->registerPacket(new AddPaintingPacket()); + $this->registerPacket(new TickSyncPacket()); + $this->registerPacket(new LevelSoundEventPacketV1()); + $this->registerPacket(new LevelEventPacket()); + $this->registerPacket(new BlockEventPacket()); + $this->registerPacket(new ActorEventPacket()); + $this->registerPacket(new MobEffectPacket()); + $this->registerPacket(new UpdateAttributesPacket()); + $this->registerPacket(new InventoryTransactionPacket()); + $this->registerPacket(new MobEquipmentPacket()); + $this->registerPacket(new MobArmorEquipmentPacket()); + $this->registerPacket(new InteractPacket()); + $this->registerPacket(new BlockPickRequestPacket()); + $this->registerPacket(new ActorPickRequestPacket()); + $this->registerPacket(new PlayerActionPacket()); + $this->registerPacket(new ActorFallPacket()); + $this->registerPacket(new HurtArmorPacket()); + $this->registerPacket(new SetActorDataPacket()); + $this->registerPacket(new SetActorMotionPacket()); + $this->registerPacket(new SetActorLinkPacket()); + $this->registerPacket(new SetHealthPacket()); + $this->registerPacket(new SetSpawnPositionPacket()); + $this->registerPacket(new AnimatePacket()); + $this->registerPacket(new RespawnPacket()); + $this->registerPacket(new ContainerOpenPacket()); + $this->registerPacket(new ContainerClosePacket()); + $this->registerPacket(new PlayerHotbarPacket()); + $this->registerPacket(new InventoryContentPacket()); + $this->registerPacket(new InventorySlotPacket()); + $this->registerPacket(new ContainerSetDataPacket()); + $this->registerPacket(new CraftingDataPacket()); + $this->registerPacket(new CraftingEventPacket()); + $this->registerPacket(new GuiDataPickItemPacket()); + $this->registerPacket(new AdventureSettingsPacket()); + $this->registerPacket(new BlockActorDataPacket()); + $this->registerPacket(new PlayerInputPacket()); + $this->registerPacket(new LevelChunkPacket()); + $this->registerPacket(new SetCommandsEnabledPacket()); + $this->registerPacket(new SetDifficultyPacket()); + $this->registerPacket(new ChangeDimensionPacket()); + $this->registerPacket(new SetPlayerGameTypePacket()); + $this->registerPacket(new PlayerListPacket()); + $this->registerPacket(new SimpleEventPacket()); + $this->registerPacket(new EventPacket()); + $this->registerPacket(new SpawnExperienceOrbPacket()); + $this->registerPacket(new ClientboundMapItemDataPacket()); + $this->registerPacket(new MapInfoRequestPacket()); + $this->registerPacket(new RequestChunkRadiusPacket()); + $this->registerPacket(new ChunkRadiusUpdatedPacket()); + $this->registerPacket(new ItemFrameDropItemPacket()); + $this->registerPacket(new GameRulesChangedPacket()); + $this->registerPacket(new CameraPacket()); + $this->registerPacket(new BossEventPacket()); + $this->registerPacket(new ShowCreditsPacket()); + $this->registerPacket(new AvailableCommandsPacket()); + $this->registerPacket(new CommandRequestPacket()); + $this->registerPacket(new CommandBlockUpdatePacket()); + $this->registerPacket(new CommandOutputPacket()); + $this->registerPacket(new UpdateTradePacket()); + $this->registerPacket(new UpdateEquipPacket()); + $this->registerPacket(new ResourcePackDataInfoPacket()); + $this->registerPacket(new ResourcePackChunkDataPacket()); + $this->registerPacket(new ResourcePackChunkRequestPacket()); + $this->registerPacket(new TransferPacket()); + $this->registerPacket(new PlaySoundPacket()); + $this->registerPacket(new StopSoundPacket()); + $this->registerPacket(new SetTitlePacket()); + $this->registerPacket(new AddBehaviorTreePacket()); + $this->registerPacket(new StructureBlockUpdatePacket()); + $this->registerPacket(new ShowStoreOfferPacket()); + $this->registerPacket(new PurchaseReceiptPacket()); + $this->registerPacket(new PlayerSkinPacket()); + $this->registerPacket(new SubClientLoginPacket()); + $this->registerPacket(new AutomationClientConnectPacket()); + $this->registerPacket(new SetLastHurtByPacket()); + $this->registerPacket(new BookEditPacket()); + $this->registerPacket(new NpcRequestPacket()); + $this->registerPacket(new PhotoTransferPacket()); + $this->registerPacket(new ModalFormRequestPacket()); + $this->registerPacket(new ModalFormResponsePacket()); + $this->registerPacket(new ServerSettingsRequestPacket()); + $this->registerPacket(new ServerSettingsResponsePacket()); + $this->registerPacket(new ShowProfilePacket()); + $this->registerPacket(new SetDefaultGameTypePacket()); + $this->registerPacket(new RemoveObjectivePacket()); + $this->registerPacket(new SetDisplayObjectivePacket()); + $this->registerPacket(new SetScorePacket()); + $this->registerPacket(new LabTablePacket()); + $this->registerPacket(new UpdateBlockSyncedPacket()); + $this->registerPacket(new MoveActorDeltaPacket()); + $this->registerPacket(new SetScoreboardIdentityPacket()); + $this->registerPacket(new SetLocalPlayerAsInitializedPacket()); + $this->registerPacket(new UpdateSoftEnumPacket()); + $this->registerPacket(new NetworkStackLatencyPacket()); + $this->registerPacket(new ScriptCustomEventPacket()); + $this->registerPacket(new SpawnParticleEffectPacket()); + $this->registerPacket(new AvailableActorIdentifiersPacket()); + $this->registerPacket(new LevelSoundEventPacketV2()); + $this->registerPacket(new NetworkChunkPublisherUpdatePacket()); + $this->registerPacket(new BiomeDefinitionListPacket()); + $this->registerPacket(new LevelSoundEventPacket()); + $this->registerPacket(new LevelEventGenericPacket()); + $this->registerPacket(new LecternUpdatePacket()); + $this->registerPacket(new VideoStreamConnectPacket()); + $this->registerPacket(new AddEntityPacket()); + $this->registerPacket(new RemoveEntityPacket()); + $this->registerPacket(new ClientCacheStatusPacket()); + $this->registerPacket(new OnScreenTextureAnimationPacket()); + $this->registerPacket(new MapCreateLockedCopyPacket()); + $this->registerPacket(new StructureTemplateDataRequestPacket()); + $this->registerPacket(new StructureTemplateDataResponsePacket()); + $this->registerPacket(new UpdateBlockPropertiesPacket()); + $this->registerPacket(new ClientCacheBlobStatusPacket()); + $this->registerPacket(new ClientCacheMissResponsePacket()); + $this->registerPacket(new EducationSettingsPacket()); + $this->registerPacket(new EmotePacket()); + $this->registerPacket(new MultiplayerSettingsPacket()); + $this->registerPacket(new SettingsCommandPacket()); + $this->registerPacket(new AnvilDamagePacket()); + $this->registerPacket(new CompletedUsingItemPacket()); + $this->registerPacket(new NetworkSettingsPacket()); + $this->registerPacket(new PlayerAuthInputPacket()); } - public static function registerPacket(Packet $packet) : void{ - static::$pool[$packet->pid()] = clone $packet; + public function registerPacket(Packet $packet) : void{ + $this->pool[$packet->pid()] = clone $packet; } - public static function getPacketById(int $pid) : Packet{ - return isset(static::$pool[$pid]) ? clone static::$pool[$pid] : new UnknownPacket(); + public function getPacketById(int $pid) : Packet{ + return isset($this->pool[$pid]) ? clone $this->pool[$pid] : new UnknownPacket(); } /** * @throws BinaryDataException */ - public static function getPacket(string $buffer) : Packet{ + public function getPacket(string $buffer) : Packet{ $offset = 0; - $pk = static::getPacketById(Binary::readUnsignedVarInt($buffer, $offset) & DataPacket::PID_MASK); + $pk = $this->getPacketById(Binary::readUnsignedVarInt($buffer, $offset) & DataPacket::PID_MASK); $pk->getBinaryStream()->setBuffer($buffer, $offset); return $pk; From b2636161f73409d496de3f5ce69a4cca71115203 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 23 Apr 2020 16:27:49 +0100 Subject: [PATCH 1450/3224] PrepareEncryptionTask: move a bunch of stuff out of the AsyncTask class --- .../mcpe/encryption/EncryptionUtils.php | 71 +++++++++++++++++++ .../mcpe/encryption/PrepareEncryptionTask.php | 33 ++------- 2 files changed, 75 insertions(+), 29 deletions(-) create mode 100644 src/network/mcpe/encryption/EncryptionUtils.php diff --git a/src/network/mcpe/encryption/EncryptionUtils.php b/src/network/mcpe/encryption/EncryptionUtils.php new file mode 100644 index 0000000000..ad09457bbf --- /dev/null +++ b/src/network/mcpe/encryption/EncryptionUtils.php @@ -0,0 +1,71 @@ +createExchange($remotePub)->calculateSharedKey(); + } + + public static function generateKey(\GMP $secret, string $salt) : string{ + return openssl_digest($salt . hex2bin(str_pad(gmp_strval($secret, 16), 96, "0", STR_PAD_LEFT)), 'sha256', true); + } + + public static function generateServerHandshakeJwt(PrivateKeyInterface $serverPriv, string $salt) : string{ + $jwtBody = self::b64UrlEncode(json_encode([ + "x5u" => base64_encode((new DerPublicKeySerializer())->serialize($serverPriv->getPublicKey())), + "alg" => "ES384" + ]) + ) . "." . self::b64UrlEncode(json_encode([ + "salt" => base64_encode($salt) + ]) + ); + + openssl_sign($jwtBody, $sig, (new PemPrivateKeySerializer(new DerPrivateKeySerializer()))->serialize($serverPriv), OPENSSL_ALGO_SHA384); + + $decodedSig = (new DerSignatureSerializer())->parse($sig); + $jwtSig = self::b64UrlEncode( + hex2bin(str_pad(gmp_strval($decodedSig->getR(), 16), 96, "0", STR_PAD_LEFT)) . + hex2bin(str_pad(gmp_strval($decodedSig->getS(), 16), 96, "0", STR_PAD_LEFT)) + ); + + return "$jwtBody.$jwtSig"; + } +} \ No newline at end of file diff --git a/src/network/mcpe/encryption/PrepareEncryptionTask.php b/src/network/mcpe/encryption/PrepareEncryptionTask.php index e36fc6afdf..65314b3b24 100644 --- a/src/network/mcpe/encryption/PrepareEncryptionTask.php +++ b/src/network/mcpe/encryption/PrepareEncryptionTask.php @@ -82,36 +82,11 @@ class PrepareEncryptionTask extends AsyncTask{ public function onRun() : void{ $serverPriv = $this->serverPrivateKey; + $sharedSecret = EncryptionUtils::generateSharedSecret($serverPriv, $this->clientPub); + $salt = random_bytes(16); - $sharedSecret = $serverPriv->createExchange($this->clientPub)->calculateSharedKey(); - - $this->aesKey = openssl_digest($salt . hex2bin(str_pad(gmp_strval($sharedSecret, 16), 96, "0", STR_PAD_LEFT)), 'sha256', true); - $this->handshakeJwt = $this->generateServerHandshakeJwt($serverPriv, $salt); - } - - private function generateServerHandshakeJwt(PrivateKeyInterface $serverPriv, string $salt) : string{ - $jwtBody = self::b64UrlEncode(json_encode([ - "x5u" => base64_encode((new DerPublicKeySerializer())->serialize($serverPriv->getPublicKey())), - "alg" => "ES384" - ]) - ) . "." . self::b64UrlEncode(json_encode([ - "salt" => base64_encode($salt) - ]) - ); - - openssl_sign($jwtBody, $sig, (new PemPrivateKeySerializer(new DerPrivateKeySerializer()))->serialize($serverPriv), OPENSSL_ALGO_SHA384); - - $decodedSig = (new DerSignatureSerializer())->parse($sig); - $jwtSig = self::b64UrlEncode( - hex2bin(str_pad(gmp_strval($decodedSig->getR(), 16), 96, "0", STR_PAD_LEFT)) . - hex2bin(str_pad(gmp_strval($decodedSig->getS(), 16), 96, "0", STR_PAD_LEFT)) - ); - - return "$jwtBody.$jwtSig"; - } - - private static function b64UrlEncode(string $str) : string{ - return rtrim(strtr(base64_encode($str), '+/', '-_'), '='); + $this->aesKey = EncryptionUtils::generateKey($sharedSecret, $salt); + $this->handshakeJwt = EncryptionUtils::generateServerHandshakeJwt($serverPriv, $salt); } public function onCompletion() : void{ From f3fed60d575389c59468cbe3868e38f03747f7d6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 23 Apr 2020 19:45:59 +0100 Subject: [PATCH 1451/3224] crafting: ditch MultiRecipe, it's a network-only thing MultiRecipes are really nothing more than feature toggles at the network layer, and they don't belong in the main core code. --- src/crafting/MultiRecipe.php | 48 ------------------- .../protocol/types/recipe/MultiRecipe.php | 13 +++++ 2 files changed, 13 insertions(+), 48 deletions(-) delete mode 100644 src/crafting/MultiRecipe.php diff --git a/src/crafting/MultiRecipe.php b/src/crafting/MultiRecipe.php deleted file mode 100644 index 1cf8147ef7..0000000000 --- a/src/crafting/MultiRecipe.php +++ /dev/null @@ -1,48 +0,0 @@ -uuid = $uuid; - } -} diff --git a/src/network/mcpe/protocol/types/recipe/MultiRecipe.php b/src/network/mcpe/protocol/types/recipe/MultiRecipe.php index 24bc370d70..9fc939c0aa 100644 --- a/src/network/mcpe/protocol/types/recipe/MultiRecipe.php +++ b/src/network/mcpe/protocol/types/recipe/MultiRecipe.php @@ -28,6 +28,19 @@ use pocketmine\utils\UUID; final class MultiRecipe extends RecipeWithTypeId{ + public const TYPE_REPAIR_ITEM = "00000000-0000-0000-0000-000000000001"; + public const TYPE_MAP_EXTENDING = "D392B075-4BA1-40AE-8789-AF868D56F6CE"; + public const TYPE_MAP_EXTENDING_CARTOGRAPHY = "8B36268C-1829-483C-A0F1-993B7156A8F2"; + public const TYPE_MAP_CLONING = "85939755-BA10-4D9D-A4CC-EFB7A8E943C4"; + public const TYPE_MAP_CLONING_CARTOGRAPHY = "442D85ED-8272-4543-A6F1-418F90DED05D"; + public const TYPE_MAP_UPGRADING = "AECD2294-4B94-434B-8667-4499BB2C9327"; + public const TYPE_MAP_UPGRADING_CARTOGRAPHY = "98C84B38-1085-46BD-B1CE-DD38C159E6CC"; + public const TYPE_BOOK_CLONING = "D1CA6B84-338E-4F2F-9C6B-76CC8B4BD98D"; + public const TYPE_BANNER_DUPLICATE = "B5C5D105-75A2-4076-AF2B-923EA2BF4BF0"; + public const TYPE_BANNER_ADD_PATTERN = "D81AAEAF-E172-4440-9225-868DF030D27B"; + public const TYPE_FIREWORKS = "00000000-0000-0000-0000-000000000002"; + public const TYPE_MAP_LOCKING_CARTOGRAPHY = "602234E4-CAC1-4353-8BB7-B1EBFF70024B"; + /** @var UUID */ private $recipeId; From aa1828aa98fc540aced9853c29e37b9934f9c64f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 23 Apr 2020 21:09:58 +0100 Subject: [PATCH 1452/3224] RuntimeBlockMapping is now a singleton instead of static class this prepares for a fully dynamic block mapper, as well as allowing a small performance improvement to chunk encoding by eliding the constant lazy-init checks. --- src/block/Block.php | 2 +- src/network/mcpe/protocol/StartGamePacket.php | 2 +- .../protocol/types/RuntimeBlockMapping.php | 63 +++++++++---------- .../mcpe/serializer/ChunkSerializer.php | 3 +- 4 files changed, 34 insertions(+), 36 deletions(-) diff --git a/src/block/Block.php b/src/block/Block.php index 9aa0459aa2..a6defb949e 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -111,7 +111,7 @@ class Block{ * @internal */ public function getRuntimeId() : int{ - return RuntimeBlockMapping::toStaticRuntimeId($this->getId(), $this->getMeta()); + return RuntimeBlockMapping::getInstance()->toStaticRuntimeId($this->getId(), $this->getMeta()); } public function getMeta() : int{ diff --git a/src/network/mcpe/protocol/StartGamePacket.php b/src/network/mcpe/protocol/StartGamePacket.php index 4d9dc419f1..f6ef854f99 100644 --- a/src/network/mcpe/protocol/StartGamePacket.php +++ b/src/network/mcpe/protocol/StartGamePacket.php @@ -289,7 +289,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{ if($this->blockTable === null){ if(self::$blockTableCache === null){ //this is a really nasty hack, but it'll do for now - self::$blockTableCache = (new NetworkNbtSerializer())->write(new TreeRoot(new ListTag(RuntimeBlockMapping::getBedrockKnownStates()))); + self::$blockTableCache = (new NetworkNbtSerializer())->write(new TreeRoot(new ListTag(RuntimeBlockMapping::getInstance()->getBedrockKnownStates()))); } $out->put(self::$blockTableCache); }else{ diff --git a/src/network/mcpe/protocol/types/RuntimeBlockMapping.php b/src/network/mcpe/protocol/types/RuntimeBlockMapping.php index 45b422dd8c..da1c0ce795 100644 --- a/src/network/mcpe/protocol/types/RuntimeBlockMapping.php +++ b/src/network/mcpe/protocol/types/RuntimeBlockMapping.php @@ -39,19 +39,25 @@ use function shuffle; * @internal */ final class RuntimeBlockMapping{ + /** @var self|null */ + private static $instance = null; - /** @var int[] */ - private static $legacyToRuntimeMap = []; - /** @var int[] */ - private static $runtimeToLegacyMap = []; - /** @var CompoundTag[]|null */ - private static $bedrockKnownStates = null; + public static function getInstance() : self{ + if(self::$instance === null){ + self::$instance = new self; + } - private function __construct(){ - //NOOP + return self::$instance; } - public static function init() : void{ + /** @var int[] */ + private $legacyToRuntimeMap = []; + /** @var int[] */ + private $runtimeToLegacyMap = []; + /** @var CompoundTag[]|null */ + private $bedrockKnownStates = null; + + private function __construct(){ $tag = (new NetworkNbtSerializer())->read(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla/required_block_states.nbt"))->getTag(); if(!($tag instanceof ListTag) or $tag->getTagType() !== NBT::TAG_Compound){ //this is a little redundant currently, but good for auto complete and makes phpstan happy throw new \RuntimeException("Invalid blockstates table, expected TAG_List root"); @@ -59,12 +65,12 @@ final class RuntimeBlockMapping{ /** @var CompoundTag[] $list */ $list = $tag->getValue(); - self::$bedrockKnownStates = self::randomizeTable($list); + $this->bedrockKnownStates = self::randomizeTable($list); - self::setupLegacyMappings(); + $this->setupLegacyMappings(); } - private static function setupLegacyMappings() : void{ + private function setupLegacyMappings() : void{ $legacyIdMap = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla/block_id_map.json"), true); $legacyStateMap = (new NetworkNbtSerializer())->read(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla/r12_to_current_block_map.nbt"))->getTag(); if(!($legacyStateMap instanceof ListTag) or $legacyStateMap->getTagType() !== NBT::TAG_Compound){ @@ -75,7 +81,7 @@ final class RuntimeBlockMapping{ * @var int[][] $idToStatesMap string id -> int[] list of candidate state indices */ $idToStatesMap = []; - foreach(self::$bedrockKnownStates as $k => $state){ + foreach($this->bedrockKnownStates as $k => $state){ $idToStatesMap[$state->getCompoundTag("block")->getString("name")][] = $k; } /** @var CompoundTag $pair */ @@ -93,9 +99,9 @@ final class RuntimeBlockMapping{ throw new \RuntimeException("Mapped new state does not appear in network table"); } foreach($idToStatesMap[$mappedName] as $k){ - $networkState = self::$bedrockKnownStates[$k]; + $networkState = $this->bedrockKnownStates[$k]; if($mappedState->equals($networkState->getCompoundTag("block"))){ - self::registerMapping($k, $id, $data); + $this->registerMapping($k, $id, $data); continue 2; } } @@ -103,12 +109,6 @@ final class RuntimeBlockMapping{ } } - private static function lazyInit() : void{ - if(self::$bedrockKnownStates === null){ - self::init(); - } - } - /** * Randomizes the order of the runtimeID table to prevent plugins relying on them. * Plugins shouldn't use this stuff anyway, but plugin devs have an irritating habit of ignoring what they @@ -126,35 +126,32 @@ final class RuntimeBlockMapping{ return $table; } - public static function toStaticRuntimeId(int $id, int $meta = 0) : int{ - self::lazyInit(); + public function toStaticRuntimeId(int $id, int $meta = 0) : int{ /* * try id+meta first * if not found, try id+0 (strip meta) * if still not found, return update! block */ - return self::$legacyToRuntimeMap[($id << 4) | $meta] ?? self::$legacyToRuntimeMap[$id << 4] ?? self::$legacyToRuntimeMap[BlockLegacyIds::INFO_UPDATE << 4]; + return $this->legacyToRuntimeMap[($id << 4) | $meta] ?? $this->legacyToRuntimeMap[$id << 4] ?? $this->legacyToRuntimeMap[BlockLegacyIds::INFO_UPDATE << 4]; } /** * @return int[] [id, meta] */ - public static function fromStaticRuntimeId(int $runtimeId) : array{ - self::lazyInit(); - $v = self::$runtimeToLegacyMap[$runtimeId]; + public function fromStaticRuntimeId(int $runtimeId) : array{ + $v = $this->runtimeToLegacyMap[$runtimeId]; return [$v >> 4, $v & 0xf]; } - private static function registerMapping(int $staticRuntimeId, int $legacyId, int $legacyMeta) : void{ - self::$legacyToRuntimeMap[($legacyId << 4) | $legacyMeta] = $staticRuntimeId; - self::$runtimeToLegacyMap[$staticRuntimeId] = ($legacyId << 4) | $legacyMeta; + private function registerMapping(int $staticRuntimeId, int $legacyId, int $legacyMeta) : void{ + $this->legacyToRuntimeMap[($legacyId << 4) | $legacyMeta] = $staticRuntimeId; + $this->runtimeToLegacyMap[$staticRuntimeId] = ($legacyId << 4) | $legacyMeta; } /** * @return CompoundTag[] */ - public static function getBedrockKnownStates() : array{ - self::lazyInit(); - return self::$bedrockKnownStates; + public function getBedrockKnownStates() : array{ + return $this->bedrockKnownStates; } } diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index 2b1643ac0f..06dc2e1f22 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -53,6 +53,7 @@ final class ChunkSerializer{ public static function serialize(Chunk $chunk, ?string $tiles = null) : string{ $stream = new NetworkBinaryStream(); $subChunkCount = self::getSubChunkCount($chunk); + $blockMapper = RuntimeBlockMapping::getInstance(); for($y = 0; $y < $subChunkCount; ++$y){ $layers = $chunk->getSubChunk($y)->getBlockLayers(); $stream->putByte(8); //version @@ -69,7 +70,7 @@ final class ChunkSerializer{ //zigzag and just shift directly. $stream->putUnsignedVarInt(count($palette) << 1); //yes, this is intentionally zigzag foreach($palette as $p){ - $stream->putUnsignedVarInt(RuntimeBlockMapping::toStaticRuntimeId($p >> 4, $p & 0xf) << 1); + $stream->putUnsignedVarInt($blockMapper->toStaticRuntimeId($p >> 4, $p & 0xf) << 1); } } } From accc0da0cb018ab021b33857b71dbc13ad3a864f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 23 Apr 2020 21:31:28 +0100 Subject: [PATCH 1453/3224] Chunk no longer depends on BlockFactory really this light population crap shouldn't be in the chunk to begin with, but that's a bit more complicated. --- src/world/format/Chunk.php | 25 ++++++++++++++++++------- src/world/generator/PopulationTask.php | 5 +++-- src/world/light/LightPopulationTask.php | 4 ++-- src/world/light/SkyLightUpdate.php | 2 +- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index c1ab0db608..09c329b61f 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -26,7 +26,6 @@ declare(strict_types=1); namespace pocketmine\world\format; -use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\block\tile\Tile; use pocketmine\block\tile\TileFactory; @@ -279,11 +278,16 @@ class Chunk{ /** * Recalculates the heightmap for the whole chunk. + * + * @param \SplFixedArray|int[] $lightFilters + * @param \SplFixedArray|bool[] $lightDiffusers + * @phpstan-param \SplFixedArray $lightFilters + * @phpstan-param \SplFixedArray $lightDiffusers */ - public function recalculateHeightMap() : void{ + public function recalculateHeightMap(\SplFixedArray $lightFilters, \SplFixedArray $lightDiffusers) : void{ for($z = 0; $z < 16; ++$z){ for($x = 0; $x < 16; ++$x){ - $this->recalculateHeightMapColumn($x, $z); + $this->recalculateHeightMapColumn($x, $z, $lightFilters, $lightDiffusers); } } } @@ -293,13 +297,17 @@ class Chunk{ * * @param int $x 0-15 * @param int $z 0-15 + * @param \SplFixedArray|int[] $lightFilters + * @param \SplFixedArray|bool[] $lightDiffusers + * @phpstan-param \SplFixedArray $lightFilters + * @phpstan-param \SplFixedArray $lightDiffusers * * @return int New calculated heightmap value (0-256 inclusive) */ - public function recalculateHeightMapColumn(int $x, int $z) : int{ + public function recalculateHeightMapColumn(int $x, int $z, \SplFixedArray $lightFilters, \SplFixedArray $lightDiffusers) : int{ $y = $this->getHighestBlockAt($x, $z); for(; $y >= 0; --$y){ - if(BlockFactory::$lightFilter[$state = $this->getFullBlock($x, $y, $z)] > 1 or BlockFactory::$diffusesSkyLight[$state]){ + if($lightFilters[$state = $this->getFullBlock($x, $y, $z)] > 1 or $lightDiffusers[$state]){ break; } } @@ -313,9 +321,12 @@ class Chunk{ * This does not cater for adjacent sky light, this performs direct sky light population only. This may cause some strange visual artifacts * if the chunk is light-populated after being terrain-populated. * + * @param \SplFixedArray|int[] $lightFilters + * @phpstan-param \SplFixedArray $lightFilters + * * TODO: fast adjacent light spread */ - public function populateSkyLight() : void{ + public function populateSkyLight(\SplFixedArray $lightFilters) : void{ $this->setAllBlockSkyLight(0); for($x = 0; $x < 16; ++$x){ @@ -329,7 +340,7 @@ class Chunk{ $light = 15; for(; $y >= 0; --$y){ - $light -= BlockFactory::$lightFilter[$this->getFullBlock($x, $y, $z)]; + $light -= $lightFilters[$this->getFullBlock($x, $y, $z)]; if($light <= 0){ break; } diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index bfe22168b8..a6b79ca716 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\generator; +use pocketmine\block\BlockFactory; use pocketmine\scheduler\AsyncTask; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\FastChunkSerializer; @@ -118,8 +119,8 @@ class PopulationTask extends AsyncTask{ $chunk = $manager->getChunk($chunk->getX(), $chunk->getZ()); $chunk->setPopulated(); - $chunk->recalculateHeightMap(); - $chunk->populateSkyLight(); + $chunk->recalculateHeightMap(BlockFactory::$lightFilter, BlockFactory::$diffusesSkyLight); + $chunk->populateSkyLight(BlockFactory::$lightFilter); $chunk->setLightPopulated(); $this->chunk = FastChunkSerializer::serialize($chunk); diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index 37989dd250..0fd0b40d60 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -63,8 +63,8 @@ class LightPopulationTask extends AsyncTask{ /** @var Chunk $chunk */ $chunk = FastChunkSerializer::deserialize($this->chunk); - $chunk->recalculateHeightMap(); - $chunk->populateSkyLight(); + $chunk->recalculateHeightMap(BlockFactory::$lightFilter, BlockFactory::$diffusesSkyLight); + $chunk->populateSkyLight(BlockFactory::$lightFilter); $chunk->setLightPopulated(); $this->resultHeightMap = igbinary_serialize($chunk->getHeightMapArray()); diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index f06b2b3c88..74eba4031b 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -51,7 +51,7 @@ class SkyLightUpdate extends LightUpdate{ $yPlusOne = $y + 1; if($yPlusOne === $oldHeightMap){ //Block changed directly beneath the heightmap. Check if a block was removed or changed to a different light-filter. - $newHeightMap = $chunk->recalculateHeightMapColumn($x & 0x0f, $z & 0x0f); + $newHeightMap = $chunk->recalculateHeightMapColumn($x & 0x0f, $z & 0x0f, BlockFactory::$lightFilter, BlockFactory::$diffusesSkyLight); }elseif($yPlusOne > $oldHeightMap){ //Block changed above the heightmap. if($source->getLightFilter() > 0 or $source->diffusesSkyLight()){ $chunk->setHeightMap($x & 0xf, $z & 0xf, $yPlusOne); From 13d784cd0c583e3f1c4e64b7b565993510aa00f8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 23 Apr 2020 23:45:13 +0100 Subject: [PATCH 1454/3224] Convert BlockFactory to singleton --- src/Server.php | 2 - src/block/BlockFactory.php | 878 ++++++------ src/block/ConcretePowder.php | 2 +- src/block/VanillaBlocks.php | 1263 +++++++++-------- src/block/tile/FlowerPot.php | 2 +- src/command/defaults/ParticleCommand.php | 4 +- src/entity/object/FallingBlock.php | 2 +- src/entity/projectile/Projectile.php | 2 +- src/item/ItemBlock.php | 2 +- src/item/ItemFactory.php | 2 +- src/world/Explosion.php | 5 +- src/world/SimpleChunkManager.php | 2 +- src/world/World.php | 6 +- src/world/generator/GeneratorRegisterTask.php | 2 - src/world/generator/PopulationTask.php | 5 +- src/world/generator/populator/GroundCover.php | 5 +- src/world/light/BlockLightUpdate.php | 2 +- src/world/light/LightPopulationTask.php | 8 +- src/world/light/LightUpdate.php | 2 +- src/world/light/SkyLightUpdate.php | 4 +- tests/phpunit/block/BlockTest.php | 33 +- .../block/regenerate_consistency_check.php | 4 +- tests/phpunit/item/ItemFactoryTest.php | 3 +- tests/phpunit/item/ItemTest.php | 2 - 24 files changed, 1121 insertions(+), 1121 deletions(-) diff --git a/src/Server.php b/src/Server.php index b7732ee0f7..b31a2eb8e8 100644 --- a/src/Server.php +++ b/src/Server.php @@ -27,7 +27,6 @@ declare(strict_types=1); */ namespace pocketmine; -use pocketmine\block\BlockFactory; use pocketmine\command\CommandReader; use pocketmine\command\CommandSender; use pocketmine\command\ConsoleCommandSender; @@ -985,7 +984,6 @@ class Server{ $this->commandMap = new SimpleCommandMap($this); EntityFactory::init(); - BlockFactory::init(); Enchantment::init(); ItemFactory::init(); CreativeInventory::init(); diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 715401fff3..88ed24cd4a 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -60,354 +60,360 @@ use function min; * Manages block registration and instance creation */ class BlockFactory{ + /** @var self|null */ + private static $instance = null; + + public static function getInstance() : self{ + if(self::$instance === null){ + self::$instance = new self; + } + return self::$instance; + } + /** * @var \SplFixedArray|Block[] * @phpstan-var \SplFixedArray */ - private static $fullList; + private $fullList; /** * @var \SplFixedArray|int[] * @phpstan-var \SplFixedArray */ - public static $lightFilter; + public $lightFilter; /** * @var \SplFixedArray|bool[] * @phpstan-var \SplFixedArray */ - public static $diffusesSkyLight; + public $diffusesSkyLight; /** * @var \SplFixedArray|float[] * @phpstan-var \SplFixedArray */ - public static $blastResistance; + public $blastResistance; - /** - * Initializes the block factory. By default this is called only once on server start, however you may wish to use - * this if you need to reset the block factory back to its original defaults for whatever reason. - */ - public static function init() : void{ + public function __construct(){ TileFactory::init(); - self::$fullList = new \SplFixedArray(8192); + $this->fullList = new \SplFixedArray(8192); - self::$lightFilter = \SplFixedArray::fromArray(array_fill(0, 8192, 1)); - self::$diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 8192, false)); - self::$blastResistance = \SplFixedArray::fromArray(array_fill(0, 8192, 0.0)); + $this->lightFilter = \SplFixedArray::fromArray(array_fill(0, 8192, 1)); + $this->diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 8192, false)); + $this->blastResistance = \SplFixedArray::fromArray(array_fill(0, 8192, 0.0)); - self::register(new ActivatorRail(new BID(Ids::ACTIVATOR_RAIL), "Activator Rail")); - self::register(new Air(new BID(Ids::AIR), "Air")); - self::register(new Anvil(new BID(Ids::ANVIL, Meta::ANVIL_NORMAL), "Anvil")); - self::register(new Anvil(new BID(Ids::ANVIL, Meta::ANVIL_SLIGHTLY_DAMAGED), "Slightly Damaged Anvil")); - self::register(new Anvil(new BID(Ids::ANVIL, Meta::ANVIL_VERY_DAMAGED), "Very Damaged Anvil")); - self::register(new Banner(new BIDFlattened(Ids::STANDING_BANNER, Ids::WALL_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Banner")); - self::register(new Transparent(new BID(Ids::BARRIER), "Barrier", BlockBreakInfo::indestructible())); - self::register(new Bed(new BID(Ids::BED_BLOCK, 0, ItemIds::BED, TileBed::class), "Bed Block")); - self::register(new Bedrock(new BID(Ids::BEDROCK), "Bedrock")); - self::register(new Beetroot(new BID(Ids::BEETROOT_BLOCK), "Beetroot Block")); - self::register(new BlueIce(new BID(Ids::BLUE_ICE), "Blue Ice")); - self::register(new BoneBlock(new BID(Ids::BONE_BLOCK), "Bone Block")); - self::register(new Bookshelf(new BID(Ids::BOOKSHELF), "Bookshelf")); - self::register(new BrewingStand(new BID(Ids::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND, TileBrewingStand::class), "Brewing Stand")); + $this->register(new ActivatorRail(new BID(Ids::ACTIVATOR_RAIL), "Activator Rail")); + $this->register(new Air(new BID(Ids::AIR), "Air")); + $this->register(new Anvil(new BID(Ids::ANVIL, Meta::ANVIL_NORMAL), "Anvil")); + $this->register(new Anvil(new BID(Ids::ANVIL, Meta::ANVIL_SLIGHTLY_DAMAGED), "Slightly Damaged Anvil")); + $this->register(new Anvil(new BID(Ids::ANVIL, Meta::ANVIL_VERY_DAMAGED), "Very Damaged Anvil")); + $this->register(new Banner(new BIDFlattened(Ids::STANDING_BANNER, Ids::WALL_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Banner")); + $this->register(new Transparent(new BID(Ids::BARRIER), "Barrier", BlockBreakInfo::indestructible())); + $this->register(new Bed(new BID(Ids::BED_BLOCK, 0, ItemIds::BED, TileBed::class), "Bed Block")); + $this->register(new Bedrock(new BID(Ids::BEDROCK), "Bedrock")); + $this->register(new Beetroot(new BID(Ids::BEETROOT_BLOCK), "Beetroot Block")); + $this->register(new BlueIce(new BID(Ids::BLUE_ICE), "Blue Ice")); + $this->register(new BoneBlock(new BID(Ids::BONE_BLOCK), "Bone Block")); + $this->register(new Bookshelf(new BID(Ids::BOOKSHELF), "Bookshelf")); + $this->register(new BrewingStand(new BID(Ids::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND, TileBrewingStand::class), "Brewing Stand")); $bricksBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - self::register(new Stair(new BID(Ids::BRICK_STAIRS), "Brick Stairs", $bricksBreakInfo)); - self::register(new Opaque(new BID(Ids::BRICK_BLOCK), "Bricks", $bricksBreakInfo)); + $this->register(new Stair(new BID(Ids::BRICK_STAIRS), "Brick Stairs", $bricksBreakInfo)); + $this->register(new Opaque(new BID(Ids::BRICK_BLOCK), "Bricks", $bricksBreakInfo)); - self::register(new BrownMushroom(new BID(Ids::BROWN_MUSHROOM), "Brown Mushroom")); - self::register(new BrownMushroomBlock(new BID(Ids::BROWN_MUSHROOM_BLOCK), "Brown Mushroom Block")); - self::register(new Cactus(new BID(Ids::CACTUS), "Cactus")); - self::register(new Cake(new BID(Ids::CAKE_BLOCK, 0, ItemIds::CAKE), "Cake")); - self::register(new Carrot(new BID(Ids::CARROTS), "Carrot Block")); - self::register(new Chest(new BID(Ids::CHEST, 0, null, TileChest::class), "Chest")); - self::register(new Clay(new BID(Ids::CLAY_BLOCK), "Clay Block")); - self::register(new Coal(new BID(Ids::COAL_BLOCK), "Coal Block")); - self::register(new CoalOre(new BID(Ids::COAL_ORE), "Coal Ore")); - self::register(new CoarseDirt(new BID(Ids::DIRT, Meta::DIRT_COARSE), "Coarse Dirt")); + $this->register(new BrownMushroom(new BID(Ids::BROWN_MUSHROOM), "Brown Mushroom")); + $this->register(new BrownMushroomBlock(new BID(Ids::BROWN_MUSHROOM_BLOCK), "Brown Mushroom Block")); + $this->register(new Cactus(new BID(Ids::CACTUS), "Cactus")); + $this->register(new Cake(new BID(Ids::CAKE_BLOCK, 0, ItemIds::CAKE), "Cake")); + $this->register(new Carrot(new BID(Ids::CARROTS), "Carrot Block")); + $this->register(new Chest(new BID(Ids::CHEST, 0, null, TileChest::class), "Chest")); + $this->register(new Clay(new BID(Ids::CLAY_BLOCK), "Clay Block")); + $this->register(new Coal(new BID(Ids::COAL_BLOCK), "Coal Block")); + $this->register(new CoalOre(new BID(Ids::COAL_ORE), "Coal Ore")); + $this->register(new CoarseDirt(new BID(Ids::DIRT, Meta::DIRT_COARSE), "Coarse Dirt")); $cobblestoneBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - self::register(new Opaque(new BID(Ids::COBBLESTONE), "Cobblestone", $cobblestoneBreakInfo)); - self::register(new Opaque(new BID(Ids::MOSSY_COBBLESTONE), "Mossy Cobblestone", $cobblestoneBreakInfo)); - self::register(new Stair(new BID(Ids::COBBLESTONE_STAIRS), "Cobblestone Stairs", $cobblestoneBreakInfo)); - self::register(new Stair(new BID(Ids::MOSSY_COBBLESTONE_STAIRS), "Mossy Cobblestone Stairs", $cobblestoneBreakInfo)); + $this->register(new Opaque(new BID(Ids::COBBLESTONE), "Cobblestone", $cobblestoneBreakInfo)); + $this->register(new Opaque(new BID(Ids::MOSSY_COBBLESTONE), "Mossy Cobblestone", $cobblestoneBreakInfo)); + $this->register(new Stair(new BID(Ids::COBBLESTONE_STAIRS), "Cobblestone Stairs", $cobblestoneBreakInfo)); + $this->register(new Stair(new BID(Ids::MOSSY_COBBLESTONE_STAIRS), "Mossy Cobblestone Stairs", $cobblestoneBreakInfo)); - self::register(new Cobweb(new BID(Ids::COBWEB), "Cobweb")); - self::register(new CocoaBlock(new BID(Ids::COCOA), "Cocoa Block")); - self::register(new CraftingTable(new BID(Ids::CRAFTING_TABLE), "Crafting Table")); - self::register(new DaylightSensor(new BIDFlattened(Ids::DAYLIGHT_DETECTOR, Ids::DAYLIGHT_DETECTOR_INVERTED, 0, null, TileDaylightSensor::class), "Daylight Sensor")); - self::register(new DeadBush(new BID(Ids::DEADBUSH), "Dead Bush")); - self::register(new DetectorRail(new BID(Ids::DETECTOR_RAIL), "Detector Rail")); + $this->register(new Cobweb(new BID(Ids::COBWEB), "Cobweb")); + $this->register(new CocoaBlock(new BID(Ids::COCOA), "Cocoa Block")); + $this->register(new CraftingTable(new BID(Ids::CRAFTING_TABLE), "Crafting Table")); + $this->register(new DaylightSensor(new BIDFlattened(Ids::DAYLIGHT_DETECTOR, Ids::DAYLIGHT_DETECTOR_INVERTED, 0, null, TileDaylightSensor::class), "Daylight Sensor")); + $this->register(new DeadBush(new BID(Ids::DEADBUSH), "Dead Bush")); + $this->register(new DetectorRail(new BID(Ids::DETECTOR_RAIL), "Detector Rail")); - self::register(new Opaque(new BID(Ids::DIAMOND_BLOCK), "Diamond Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); - self::register(new DiamondOre(new BID(Ids::DIAMOND_ORE), "Diamond Ore")); - self::register(new Dirt(new BID(Ids::DIRT, Meta::DIRT_NORMAL), "Dirt")); - self::register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_SUNFLOWER), "Sunflower")); - self::register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LILAC), "Lilac")); - self::register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_ROSE_BUSH), "Rose Bush")); - self::register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_PEONY), "Peony")); - self::register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_TALLGRASS), "Double Tallgrass")); - self::register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LARGE_FERN), "Large Fern")); - self::register(new DragonEgg(new BID(Ids::DRAGON_EGG), "Dragon Egg")); - self::register(new DriedKelp(new BID(Ids::DRIED_KELP_BLOCK), "Dried Kelp Block", new BlockBreakInfo(0.5, BlockToolType::NONE, 0, 12.5))); - self::register(new Opaque(new BID(Ids::EMERALD_BLOCK), "Emerald Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); - self::register(new EmeraldOre(new BID(Ids::EMERALD_ORE), "Emerald Ore")); - self::register(new EnchantingTable(new BID(Ids::ENCHANTING_TABLE, 0, null, TileEnchantingTable::class), "Enchanting Table")); - self::register(new EndPortalFrame(new BID(Ids::END_PORTAL_FRAME), "End Portal Frame")); - self::register(new EndRod(new BID(Ids::END_ROD), "End Rod")); - self::register(new Opaque(new BID(Ids::END_STONE), "End Stone", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 45.0))); + $this->register(new Opaque(new BID(Ids::DIAMOND_BLOCK), "Diamond Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); + $this->register(new DiamondOre(new BID(Ids::DIAMOND_ORE), "Diamond Ore")); + $this->register(new Dirt(new BID(Ids::DIRT, Meta::DIRT_NORMAL), "Dirt")); + $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_SUNFLOWER), "Sunflower")); + $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LILAC), "Lilac")); + $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_ROSE_BUSH), "Rose Bush")); + $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_PEONY), "Peony")); + $this->register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_TALLGRASS), "Double Tallgrass")); + $this->register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LARGE_FERN), "Large Fern")); + $this->register(new DragonEgg(new BID(Ids::DRAGON_EGG), "Dragon Egg")); + $this->register(new DriedKelp(new BID(Ids::DRIED_KELP_BLOCK), "Dried Kelp Block", new BlockBreakInfo(0.5, BlockToolType::NONE, 0, 12.5))); + $this->register(new Opaque(new BID(Ids::EMERALD_BLOCK), "Emerald Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); + $this->register(new EmeraldOre(new BID(Ids::EMERALD_ORE), "Emerald Ore")); + $this->register(new EnchantingTable(new BID(Ids::ENCHANTING_TABLE, 0, null, TileEnchantingTable::class), "Enchanting Table")); + $this->register(new EndPortalFrame(new BID(Ids::END_PORTAL_FRAME), "End Portal Frame")); + $this->register(new EndRod(new BID(Ids::END_ROD), "End Rod")); + $this->register(new Opaque(new BID(Ids::END_STONE), "End Stone", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 45.0))); $endBrickBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 4.0); - self::register(new Opaque(new BID(Ids::END_BRICKS), "End Stone Bricks", $endBrickBreakInfo)); - self::register(new Stair(new BID(Ids::END_BRICK_STAIRS), "End Stone Brick Stairs", $endBrickBreakInfo)); + $this->register(new Opaque(new BID(Ids::END_BRICKS), "End Stone Bricks", $endBrickBreakInfo)); + $this->register(new Stair(new BID(Ids::END_BRICK_STAIRS), "End Stone Brick Stairs", $endBrickBreakInfo)); - self::register(new EnderChest(new BID(Ids::ENDER_CHEST, 0, null, TileEnderChest::class), "Ender Chest")); - self::register(new Farmland(new BID(Ids::FARMLAND), "Farmland")); - self::register(new Fire(new BID(Ids::FIRE), "Fire Block")); - self::register(new Flower(new BID(Ids::DANDELION), "Dandelion")); - self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ALLIUM), "Allium")); - self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_AZURE_BLUET), "Azure Bluet")); - self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_BLUE_ORCHID), "Blue Orchid")); - self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_CORNFLOWER), "Cornflower")); - self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_LILY_OF_THE_VALLEY), "Lily of the Valley")); - self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ORANGE_TULIP), "Orange Tulip")); - self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_OXEYE_DAISY), "Oxeye Daisy")); - self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_PINK_TULIP), "Pink Tulip")); - self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_POPPY), "Poppy")); - self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_RED_TULIP), "Red Tulip")); - self::register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_WHITE_TULIP), "White Tulip")); - self::register(new FlowerPot(new BID(Ids::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, TileFlowerPot::class), "Flower Pot")); - self::register(new FrostedIce(new BID(Ids::FROSTED_ICE), "Frosted Ice")); - self::register(new Furnace(new BIDFlattened(Ids::FURNACE, Ids::LIT_FURNACE, 0, null, TileFurnace::class), "Furnace")); - self::register(new Glass(new BID(Ids::GLASS), "Glass")); - self::register(new GlassPane(new BID(Ids::GLASS_PANE), "Glass Pane")); - self::register(new GlowingObsidian(new BID(Ids::GLOWINGOBSIDIAN), "Glowing Obsidian")); - self::register(new Glowstone(new BID(Ids::GLOWSTONE), "Glowstone")); - self::register(new Opaque(new BID(Ids::GOLD_BLOCK), "Gold Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); - self::register(new Opaque(new BID(Ids::GOLD_ORE), "Gold Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); - self::register(new Grass(new BID(Ids::GRASS), "Grass")); - self::register(new GrassPath(new BID(Ids::GRASS_PATH), "Grass Path")); - self::register(new Gravel(new BID(Ids::GRAVEL), "Gravel")); - self::register(new HardenedClay(new BID(Ids::HARDENED_CLAY), "Hardened Clay")); - self::register(new HardenedGlass(new BID(Ids::HARD_GLASS), "Hardened Glass")); - self::register(new HardenedGlassPane(new BID(Ids::HARD_GLASS_PANE), "Hardened Glass Pane")); - self::register(new HayBale(new BID(Ids::HAY_BALE), "Hay Bale")); - self::register(new Hopper(new BID(Ids::HOPPER_BLOCK, 0, ItemIds::HOPPER, TileHopper::class), "Hopper", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 15.0))); - self::register(new Ice(new BID(Ids::ICE), "Ice")); - self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE), "Infested Stone") extends InfestedStone{ + $this->register(new EnderChest(new BID(Ids::ENDER_CHEST, 0, null, TileEnderChest::class), "Ender Chest")); + $this->register(new Farmland(new BID(Ids::FARMLAND), "Farmland")); + $this->register(new Fire(new BID(Ids::FIRE), "Fire Block")); + $this->register(new Flower(new BID(Ids::DANDELION), "Dandelion")); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ALLIUM), "Allium")); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_AZURE_BLUET), "Azure Bluet")); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_BLUE_ORCHID), "Blue Orchid")); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_CORNFLOWER), "Cornflower")); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_LILY_OF_THE_VALLEY), "Lily of the Valley")); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ORANGE_TULIP), "Orange Tulip")); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_OXEYE_DAISY), "Oxeye Daisy")); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_PINK_TULIP), "Pink Tulip")); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_POPPY), "Poppy")); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_RED_TULIP), "Red Tulip")); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_WHITE_TULIP), "White Tulip")); + $this->register(new FlowerPot(new BID(Ids::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, TileFlowerPot::class), "Flower Pot")); + $this->register(new FrostedIce(new BID(Ids::FROSTED_ICE), "Frosted Ice")); + $this->register(new Furnace(new BIDFlattened(Ids::FURNACE, Ids::LIT_FURNACE, 0, null, TileFurnace::class), "Furnace")); + $this->register(new Glass(new BID(Ids::GLASS), "Glass")); + $this->register(new GlassPane(new BID(Ids::GLASS_PANE), "Glass Pane")); + $this->register(new GlowingObsidian(new BID(Ids::GLOWINGOBSIDIAN), "Glowing Obsidian")); + $this->register(new Glowstone(new BID(Ids::GLOWSTONE), "Glowstone")); + $this->register(new Opaque(new BID(Ids::GOLD_BLOCK), "Gold Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); + $this->register(new Opaque(new BID(Ids::GOLD_ORE), "Gold Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); + $this->register(new Grass(new BID(Ids::GRASS), "Grass")); + $this->register(new GrassPath(new BID(Ids::GRASS_PATH), "Grass Path")); + $this->register(new Gravel(new BID(Ids::GRAVEL), "Gravel")); + $this->register(new HardenedClay(new BID(Ids::HARDENED_CLAY), "Hardened Clay")); + $this->register(new HardenedGlass(new BID(Ids::HARD_GLASS), "Hardened Glass")); + $this->register(new HardenedGlassPane(new BID(Ids::HARD_GLASS_PANE), "Hardened Glass Pane")); + $this->register(new HayBale(new BID(Ids::HAY_BALE), "Hay Bale")); + $this->register(new Hopper(new BID(Ids::HOPPER_BLOCK, 0, ItemIds::HOPPER, TileHopper::class), "Hopper", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 15.0))); + $this->register(new Ice(new BID(Ids::ICE), "Ice")); + $this->register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE), "Infested Stone") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [VanillaBlocks::STONE()->asItem()]; } }); - self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_COBBLESTONE), "Infested Cobblestone") extends InfestedStone{ + $this->register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_COBBLESTONE), "Infested Cobblestone") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [VanillaBlocks::COBBLESTONE()->asItem()]; } }); - self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK), "Infested Stone Brick") extends InfestedStone{ + $this->register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK), "Infested Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [VanillaBlocks::STONE_BRICKS()->asItem()]; } }); - self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_MOSSY), "Infested Mossy Stone Brick") extends InfestedStone{ + $this->register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_MOSSY), "Infested Mossy Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [VanillaBlocks::MOSSY_STONE_BRICKS()->asItem()]; } }); - self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CRACKED), "Infested Cracked Stone Brick") extends InfestedStone{ + $this->register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CRACKED), "Infested Cracked Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [VanillaBlocks::CRACKED_STONE_BRICKS()->asItem()]; } }); - self::register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CHISELED), "Infested Chiseled Stone Brick") extends InfestedStone{ + $this->register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CHISELED), "Infested Chiseled Stone Brick") extends InfestedStone{ public function getSilkTouchDrops(Item $item) : array{ return [VanillaBlocks::CHISELED_STONE_BRICKS()->asItem()]; } }); $updateBlockBreakInfo = new BlockBreakInfo(1.0); - self::register(new Opaque(new BID(Ids::INFO_UPDATE), "update!", $updateBlockBreakInfo)); - self::register(new Opaque(new BID(Ids::INFO_UPDATE2), "ate!upd", $updateBlockBreakInfo)); - self::register(new Transparent(new BID(Ids::INVISIBLEBEDROCK), "Invisible Bedrock", BlockBreakInfo::indestructible())); - self::register(new Opaque(new BID(Ids::IRON_BLOCK), "Iron Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel(), 30.0))); - self::register(new Thin(new BID(Ids::IRON_BARS), "Iron Bars", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0))); - self::register(new Door(new BID(Ids::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0))); - self::register(new Opaque(new BID(Ids::IRON_ORE), "Iron Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); - self::register(new Trapdoor(new BID(Ids::IRON_TRAPDOOR), "Iron Trapdoor", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0))); - self::register(new ItemFrame(new BID(Ids::FRAME_BLOCK, 0, ItemIds::FRAME, TileItemFrame::class), "Item Frame")); - self::register(new Ladder(new BID(Ids::LADDER), "Ladder")); - self::register(new Lantern(new BID(Ids::LANTERN), "Lantern", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - self::register(new Opaque(new BID(Ids::LAPIS_BLOCK), "Lapis Lazuli Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); - self::register(new LapisOre(new BID(Ids::LAPIS_ORE), "Lapis Lazuli Ore")); - self::register(new Lava(new BIDFlattened(Ids::FLOWING_LAVA, Ids::STILL_LAVA), "Lava")); - self::register(new Lever(new BID(Ids::LEVER), "Lever")); - self::register(new Magma(new BID(Ids::MAGMA), "Magma Block")); - self::register(new Melon(new BID(Ids::MELON_BLOCK), "Melon Block")); - self::register(new MelonStem(new BID(Ids::MELON_STEM, 0, ItemIds::MELON_SEEDS), "Melon Stem")); - self::register(new MonsterSpawner(new BID(Ids::MOB_SPAWNER, 0, null, TileMonsterSpawner::class), "Monster Spawner")); - self::register(new Mycelium(new BID(Ids::MYCELIUM), "Mycelium")); + $this->register(new Opaque(new BID(Ids::INFO_UPDATE), "update!", $updateBlockBreakInfo)); + $this->register(new Opaque(new BID(Ids::INFO_UPDATE2), "ate!upd", $updateBlockBreakInfo)); + $this->register(new Transparent(new BID(Ids::INVISIBLEBEDROCK), "Invisible Bedrock", BlockBreakInfo::indestructible())); + $this->register(new Opaque(new BID(Ids::IRON_BLOCK), "Iron Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel(), 30.0))); + $this->register(new Thin(new BID(Ids::IRON_BARS), "Iron Bars", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0))); + $this->register(new Door(new BID(Ids::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0))); + $this->register(new Opaque(new BID(Ids::IRON_ORE), "Iron Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); + $this->register(new Trapdoor(new BID(Ids::IRON_TRAPDOOR), "Iron Trapdoor", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0))); + $this->register(new ItemFrame(new BID(Ids::FRAME_BLOCK, 0, ItemIds::FRAME, TileItemFrame::class), "Item Frame")); + $this->register(new Ladder(new BID(Ids::LADDER), "Ladder")); + $this->register(new Lantern(new BID(Ids::LANTERN), "Lantern", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->register(new Opaque(new BID(Ids::LAPIS_BLOCK), "Lapis Lazuli Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); + $this->register(new LapisOre(new BID(Ids::LAPIS_ORE), "Lapis Lazuli Ore")); + $this->register(new Lava(new BIDFlattened(Ids::FLOWING_LAVA, Ids::STILL_LAVA), "Lava")); + $this->register(new Lever(new BID(Ids::LEVER), "Lever")); + $this->register(new Magma(new BID(Ids::MAGMA), "Magma Block")); + $this->register(new Melon(new BID(Ids::MELON_BLOCK), "Melon Block")); + $this->register(new MelonStem(new BID(Ids::MELON_STEM, 0, ItemIds::MELON_SEEDS), "Melon Stem")); + $this->register(new MonsterSpawner(new BID(Ids::MOB_SPAWNER, 0, null, TileMonsterSpawner::class), "Monster Spawner")); + $this->register(new Mycelium(new BID(Ids::MYCELIUM), "Mycelium")); $netherBrickBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - self::register(new Opaque(new BID(Ids::NETHER_BRICK_BLOCK), "Nether Bricks", $netherBrickBreakInfo)); - self::register(new Opaque(new BID(Ids::RED_NETHER_BRICK), "Red Nether Bricks", $netherBrickBreakInfo)); - self::register(new Fence(new BID(Ids::NETHER_BRICK_FENCE), "Nether Brick Fence", $netherBrickBreakInfo)); - self::register(new Stair(new BID(Ids::NETHER_BRICK_STAIRS), "Nether Brick Stairs", $netherBrickBreakInfo)); - self::register(new Stair(new BID(Ids::RED_NETHER_BRICK_STAIRS), "Red Nether Brick Stairs", $netherBrickBreakInfo)); - self::register(new NetherPortal(new BID(Ids::PORTAL), "Nether Portal")); - self::register(new NetherQuartzOre(new BID(Ids::NETHER_QUARTZ_ORE), "Nether Quartz Ore")); - self::register(new NetherReactor(new BID(Ids::NETHERREACTOR), "Nether Reactor Core")); - self::register(new Opaque(new BID(Ids::NETHER_WART_BLOCK), "Nether Wart Block", new BlockBreakInfo(1.0))); - self::register(new NetherWartPlant(new BID(Ids::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART), "Nether Wart")); - self::register(new Netherrack(new BID(Ids::NETHERRACK), "Netherrack")); - self::register(new Note(new BID(Ids::NOTEBLOCK, 0, null, TileNote::class), "Note Block")); - self::register(new Opaque(new BID(Ids::OBSIDIAN), "Obsidian", new BlockBreakInfo(35.0 /* 50 in PC */, BlockToolType::PICKAXE, ToolTier::DIAMOND()->getHarvestLevel(), 6000.0))); - self::register(new PackedIce(new BID(Ids::PACKED_ICE), "Packed Ice")); - self::register(new Podzol(new BID(Ids::PODZOL), "Podzol")); - self::register(new Potato(new BID(Ids::POTATOES), "Potato Block")); - self::register(new PoweredRail(new BID(Ids::GOLDEN_RAIL, Meta::RAIL_STRAIGHT_NORTH_SOUTH), "Powered Rail")); + $this->register(new Opaque(new BID(Ids::NETHER_BRICK_BLOCK), "Nether Bricks", $netherBrickBreakInfo)); + $this->register(new Opaque(new BID(Ids::RED_NETHER_BRICK), "Red Nether Bricks", $netherBrickBreakInfo)); + $this->register(new Fence(new BID(Ids::NETHER_BRICK_FENCE), "Nether Brick Fence", $netherBrickBreakInfo)); + $this->register(new Stair(new BID(Ids::NETHER_BRICK_STAIRS), "Nether Brick Stairs", $netherBrickBreakInfo)); + $this->register(new Stair(new BID(Ids::RED_NETHER_BRICK_STAIRS), "Red Nether Brick Stairs", $netherBrickBreakInfo)); + $this->register(new NetherPortal(new BID(Ids::PORTAL), "Nether Portal")); + $this->register(new NetherQuartzOre(new BID(Ids::NETHER_QUARTZ_ORE), "Nether Quartz Ore")); + $this->register(new NetherReactor(new BID(Ids::NETHERREACTOR), "Nether Reactor Core")); + $this->register(new Opaque(new BID(Ids::NETHER_WART_BLOCK), "Nether Wart Block", new BlockBreakInfo(1.0))); + $this->register(new NetherWartPlant(new BID(Ids::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART), "Nether Wart")); + $this->register(new Netherrack(new BID(Ids::NETHERRACK), "Netherrack")); + $this->register(new Note(new BID(Ids::NOTEBLOCK, 0, null, TileNote::class), "Note Block")); + $this->register(new Opaque(new BID(Ids::OBSIDIAN), "Obsidian", new BlockBreakInfo(35.0 /* 50 in PC */, BlockToolType::PICKAXE, ToolTier::DIAMOND()->getHarvestLevel(), 6000.0))); + $this->register(new PackedIce(new BID(Ids::PACKED_ICE), "Packed Ice")); + $this->register(new Podzol(new BID(Ids::PODZOL), "Podzol")); + $this->register(new Potato(new BID(Ids::POTATOES), "Potato Block")); + $this->register(new PoweredRail(new BID(Ids::GOLDEN_RAIL, Meta::RAIL_STRAIGHT_NORTH_SOUTH), "Powered Rail")); $prismarineBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - self::register(new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_BRICKS), "Prismarine Bricks", $prismarineBreakInfo)); - self::register(new Stair(new BID(Ids::PRISMARINE_BRICKS_STAIRS), "Prismarine Bricks Stairs", $prismarineBreakInfo)); - self::register(new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_DARK), "Dark Prismarine", $prismarineBreakInfo)); - self::register(new Stair(new BID(Ids::DARK_PRISMARINE_STAIRS), "Dark Prismarine Stairs", $prismarineBreakInfo)); - self::register(new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_NORMAL), "Prismarine", $prismarineBreakInfo)); - self::register(new Stair(new BID(Ids::PRISMARINE_STAIRS), "Prismarine Stairs", $prismarineBreakInfo)); + $this->register(new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_BRICKS), "Prismarine Bricks", $prismarineBreakInfo)); + $this->register(new Stair(new BID(Ids::PRISMARINE_BRICKS_STAIRS), "Prismarine Bricks Stairs", $prismarineBreakInfo)); + $this->register(new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_DARK), "Dark Prismarine", $prismarineBreakInfo)); + $this->register(new Stair(new BID(Ids::DARK_PRISMARINE_STAIRS), "Dark Prismarine Stairs", $prismarineBreakInfo)); + $this->register(new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_NORMAL), "Prismarine", $prismarineBreakInfo)); + $this->register(new Stair(new BID(Ids::PRISMARINE_STAIRS), "Prismarine Stairs", $prismarineBreakInfo)); $pumpkinBreakInfo = new BlockBreakInfo(1.0, BlockToolType::AXE); - self::register($pumpkin = new Opaque(new BID(Ids::PUMPKIN), "Pumpkin", $pumpkinBreakInfo)); + $this->register($pumpkin = new Opaque(new BID(Ids::PUMPKIN), "Pumpkin", $pumpkinBreakInfo)); for($i = 1; $i <= 3; ++$i){ - self::remap(Ids::PUMPKIN, $i, $pumpkin); + $this->remap(Ids::PUMPKIN, $i, $pumpkin); } - self::register(new CarvedPumpkin(new BID(Ids::CARVED_PUMPKIN), "Carved Pumpkin", $pumpkinBreakInfo)); - self::register(new LitPumpkin(new BID(Ids::JACK_O_LANTERN), "Jack o'Lantern", $pumpkinBreakInfo)); + $this->register(new CarvedPumpkin(new BID(Ids::CARVED_PUMPKIN), "Carved Pumpkin", $pumpkinBreakInfo)); + $this->register(new LitPumpkin(new BID(Ids::JACK_O_LANTERN), "Jack o'Lantern", $pumpkinBreakInfo)); - self::register(new PumpkinStem(new BID(Ids::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem")); + $this->register(new PumpkinStem(new BID(Ids::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem")); $purpurBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - self::register(new Opaque(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_NORMAL), "Purpur Block", $purpurBreakInfo)); - self::register(new class(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_PILLAR), "Purpur Pillar", $purpurBreakInfo) extends Opaque{ + $this->register(new Opaque(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_NORMAL), "Purpur Block", $purpurBreakInfo)); + $this->register(new class(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_PILLAR), "Purpur Pillar", $purpurBreakInfo) extends Opaque{ use PillarRotationTrait; }); - self::register(new Stair(new BID(Ids::PURPUR_STAIRS), "Purpur Stairs", $purpurBreakInfo)); + $this->register(new Stair(new BID(Ids::PURPUR_STAIRS), "Purpur Stairs", $purpurBreakInfo)); $quartzBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()); - self::register(new Opaque(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_NORMAL), "Quartz Block", $quartzBreakInfo)); - self::register(new Stair(new BID(Ids::QUARTZ_STAIRS), "Quartz Stairs", $quartzBreakInfo)); - self::register(new class(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_CHISELED), "Chiseled Quartz Block", $quartzBreakInfo) extends Opaque{ + $this->register(new Opaque(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_NORMAL), "Quartz Block", $quartzBreakInfo)); + $this->register(new Stair(new BID(Ids::QUARTZ_STAIRS), "Quartz Stairs", $quartzBreakInfo)); + $this->register(new class(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_CHISELED), "Chiseled Quartz Block", $quartzBreakInfo) extends Opaque{ use PillarRotationTrait; }); - self::register(new class(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_PILLAR), "Quartz Pillar", $quartzBreakInfo) extends Opaque{ + $this->register(new class(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_PILLAR), "Quartz Pillar", $quartzBreakInfo) extends Opaque{ use PillarRotationTrait; }); - self::register(new Opaque(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_SMOOTH), "Smooth Quartz Block", $quartzBreakInfo)); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) - self::register(new Stair(new BID(Ids::SMOOTH_QUARTZ_STAIRS), "Smooth Quartz Stairs", $quartzBreakInfo)); + $this->register(new Opaque(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_SMOOTH), "Smooth Quartz Block", $quartzBreakInfo)); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) + $this->register(new Stair(new BID(Ids::SMOOTH_QUARTZ_STAIRS), "Smooth Quartz Stairs", $quartzBreakInfo)); - self::register(new Rail(new BID(Ids::RAIL), "Rail")); - self::register(new RedMushroom(new BID(Ids::RED_MUSHROOM), "Red Mushroom")); - self::register(new RedMushroomBlock(new BID(Ids::RED_MUSHROOM_BLOCK), "Red Mushroom Block")); - self::register(new Redstone(new BID(Ids::REDSTONE_BLOCK), "Redstone Block")); - self::register(new RedstoneComparator(new BIDFlattened(Ids::UNPOWERED_COMPARATOR, Ids::POWERED_COMPARATOR, 0, ItemIds::COMPARATOR, TileComparator::class), "Redstone Comparator")); - self::register(new RedstoneLamp(new BIDFlattened(Ids::REDSTONE_LAMP, Ids::LIT_REDSTONE_LAMP), "Redstone Lamp")); - self::register(new RedstoneOre(new BIDFlattened(Ids::REDSTONE_ORE, Ids::LIT_REDSTONE_ORE), "Redstone Ore")); - self::register(new RedstoneRepeater(new BIDFlattened(Ids::UNPOWERED_REPEATER, Ids::POWERED_REPEATER, 0, ItemIds::REPEATER), "Redstone Repeater")); - self::register(new RedstoneTorch(new BIDFlattened(Ids::REDSTONE_TORCH, Ids::UNLIT_REDSTONE_TORCH), "Redstone Torch")); - self::register(new RedstoneWire(new BID(Ids::REDSTONE_WIRE, 0, ItemIds::REDSTONE), "Redstone")); - self::register(new Reserved6(new BID(Ids::RESERVED6), "reserved6")); - self::register(new Sand(new BID(Ids::SAND), "Sand")); - self::register(new Sand(new BID(Ids::SAND, 1), "Red Sand")); - self::register(new SeaLantern(new BID(Ids::SEALANTERN), "Sea Lantern")); - self::register(new SeaPickle(new BID(Ids::SEA_PICKLE), "Sea Pickle")); - self::register(new Skull(new BID(Ids::MOB_HEAD_BLOCK, 0, null, TileSkull::class), "Mob Head")); + $this->register(new Rail(new BID(Ids::RAIL), "Rail")); + $this->register(new RedMushroom(new BID(Ids::RED_MUSHROOM), "Red Mushroom")); + $this->register(new RedMushroomBlock(new BID(Ids::RED_MUSHROOM_BLOCK), "Red Mushroom Block")); + $this->register(new Redstone(new BID(Ids::REDSTONE_BLOCK), "Redstone Block")); + $this->register(new RedstoneComparator(new BIDFlattened(Ids::UNPOWERED_COMPARATOR, Ids::POWERED_COMPARATOR, 0, ItemIds::COMPARATOR, TileComparator::class), "Redstone Comparator")); + $this->register(new RedstoneLamp(new BIDFlattened(Ids::REDSTONE_LAMP, Ids::LIT_REDSTONE_LAMP), "Redstone Lamp")); + $this->register(new RedstoneOre(new BIDFlattened(Ids::REDSTONE_ORE, Ids::LIT_REDSTONE_ORE), "Redstone Ore")); + $this->register(new RedstoneRepeater(new BIDFlattened(Ids::UNPOWERED_REPEATER, Ids::POWERED_REPEATER, 0, ItemIds::REPEATER), "Redstone Repeater")); + $this->register(new RedstoneTorch(new BIDFlattened(Ids::REDSTONE_TORCH, Ids::UNLIT_REDSTONE_TORCH), "Redstone Torch")); + $this->register(new RedstoneWire(new BID(Ids::REDSTONE_WIRE, 0, ItemIds::REDSTONE), "Redstone")); + $this->register(new Reserved6(new BID(Ids::RESERVED6), "reserved6")); + $this->register(new Sand(new BID(Ids::SAND), "Sand")); + $this->register(new Sand(new BID(Ids::SAND, 1), "Red Sand")); + $this->register(new SeaLantern(new BID(Ids::SEALANTERN), "Sea Lantern")); + $this->register(new SeaPickle(new BID(Ids::SEA_PICKLE), "Sea Pickle")); + $this->register(new Skull(new BID(Ids::MOB_HEAD_BLOCK, 0, null, TileSkull::class), "Mob Head")); - self::register(new Snow(new BID(Ids::SNOW), "Snow Block")); - self::register(new SnowLayer(new BID(Ids::SNOW_LAYER), "Snow Layer")); - self::register(new SoulSand(new BID(Ids::SOUL_SAND), "Soul Sand")); - self::register(new Sponge(new BID(Ids::SPONGE), "Sponge")); + $this->register(new Snow(new BID(Ids::SNOW), "Snow Block")); + $this->register(new SnowLayer(new BID(Ids::SNOW_LAYER), "Snow Layer")); + $this->register(new SoulSand(new BID(Ids::SOUL_SAND), "Soul Sand")); + $this->register(new Sponge(new BID(Ids::SPONGE), "Sponge")); $stoneBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - self::register(new class(new BID(Ids::STONE, Meta::STONE_NORMAL), "Stone", $stoneBreakInfo) extends Opaque{ + $this->register(new class(new BID(Ids::STONE, Meta::STONE_NORMAL), "Stone", $stoneBreakInfo) extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ return [VanillaBlocks::COBBLESTONE()->asItem()]; } }); - self::register(new Stair(new BID(Ids::NORMAL_STONE_STAIRS), "Stone Stairs", $stoneBreakInfo)); - self::register(new Opaque(new BID(Ids::SMOOTH_STONE), "Smooth Stone", $stoneBreakInfo)); - self::register(new Opaque(new BID(Ids::STONE, Meta::STONE_ANDESITE), "Andesite", $stoneBreakInfo)); - self::register(new Stair(new BID(Ids::ANDESITE_STAIRS), "Andesite Stairs", $stoneBreakInfo)); - self::register(new Opaque(new BID(Ids::STONE, Meta::STONE_DIORITE), "Diorite", $stoneBreakInfo)); - self::register(new Stair(new BID(Ids::DIORITE_STAIRS), "Diorite Stairs", $stoneBreakInfo)); - self::register(new Opaque(new BID(Ids::STONE, Meta::STONE_GRANITE), "Granite", $stoneBreakInfo)); - self::register(new Stair(new BID(Ids::GRANITE_STAIRS), "Granite Stairs", $stoneBreakInfo)); - self::register(new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_ANDESITE), "Polished Andesite", $stoneBreakInfo)); - self::register(new Stair(new BID(Ids::POLISHED_ANDESITE_STAIRS), "Polished Andesite Stairs", $stoneBreakInfo)); - self::register(new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_DIORITE), "Polished Diorite", $stoneBreakInfo)); - self::register(new Stair(new BID(Ids::POLISHED_DIORITE_STAIRS), "Polished Diorite Stairs", $stoneBreakInfo)); - self::register(new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_GRANITE), "Polished Granite", $stoneBreakInfo)); - self::register(new Stair(new BID(Ids::POLISHED_GRANITE_STAIRS), "Polished Granite Stairs", $stoneBreakInfo)); - self::register(new Stair(new BID(Ids::STONE_BRICK_STAIRS), "Stone Brick Stairs", $stoneBreakInfo)); - self::register(new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CHISELED), "Chiseled Stone Bricks", $stoneBreakInfo)); - self::register(new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CRACKED), "Cracked Stone Bricks", $stoneBreakInfo)); - self::register(new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_MOSSY), "Mossy Stone Bricks", $stoneBreakInfo)); - self::register(new Stair(new BID(Ids::MOSSY_STONE_BRICK_STAIRS), "Mossy Stone Brick Stairs", $stoneBreakInfo)); - self::register(new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_NORMAL), "Stone Bricks", $stoneBreakInfo)); - self::register(new StoneButton(new BID(Ids::STONE_BUTTON), "Stone Button")); - self::register(new StonePressurePlate(new BID(Ids::STONE_PRESSURE_PLATE), "Stone Pressure Plate")); + $this->register(new Stair(new BID(Ids::NORMAL_STONE_STAIRS), "Stone Stairs", $stoneBreakInfo)); + $this->register(new Opaque(new BID(Ids::SMOOTH_STONE), "Smooth Stone", $stoneBreakInfo)); + $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_ANDESITE), "Andesite", $stoneBreakInfo)); + $this->register(new Stair(new BID(Ids::ANDESITE_STAIRS), "Andesite Stairs", $stoneBreakInfo)); + $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_DIORITE), "Diorite", $stoneBreakInfo)); + $this->register(new Stair(new BID(Ids::DIORITE_STAIRS), "Diorite Stairs", $stoneBreakInfo)); + $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_GRANITE), "Granite", $stoneBreakInfo)); + $this->register(new Stair(new BID(Ids::GRANITE_STAIRS), "Granite Stairs", $stoneBreakInfo)); + $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_ANDESITE), "Polished Andesite", $stoneBreakInfo)); + $this->register(new Stair(new BID(Ids::POLISHED_ANDESITE_STAIRS), "Polished Andesite Stairs", $stoneBreakInfo)); + $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_DIORITE), "Polished Diorite", $stoneBreakInfo)); + $this->register(new Stair(new BID(Ids::POLISHED_DIORITE_STAIRS), "Polished Diorite Stairs", $stoneBreakInfo)); + $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_GRANITE), "Polished Granite", $stoneBreakInfo)); + $this->register(new Stair(new BID(Ids::POLISHED_GRANITE_STAIRS), "Polished Granite Stairs", $stoneBreakInfo)); + $this->register(new Stair(new BID(Ids::STONE_BRICK_STAIRS), "Stone Brick Stairs", $stoneBreakInfo)); + $this->register(new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CHISELED), "Chiseled Stone Bricks", $stoneBreakInfo)); + $this->register(new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CRACKED), "Cracked Stone Bricks", $stoneBreakInfo)); + $this->register(new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_MOSSY), "Mossy Stone Bricks", $stoneBreakInfo)); + $this->register(new Stair(new BID(Ids::MOSSY_STONE_BRICK_STAIRS), "Mossy Stone Brick Stairs", $stoneBreakInfo)); + $this->register(new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_NORMAL), "Stone Bricks", $stoneBreakInfo)); + $this->register(new StoneButton(new BID(Ids::STONE_BUTTON), "Stone Button")); + $this->register(new StonePressurePlate(new BID(Ids::STONE_PRESSURE_PLATE), "Stone Pressure Plate")); //TODO: in the future this won't be the same for all the types $stoneSlabBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_BRICK), "Brick", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_COBBLESTONE), "Cobblestone", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_FAKE_WOODEN), "Fake Wooden", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_NETHER_BRICK), "Nether Brick", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_QUARTZ), "Quartz", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_SANDSTONE), "Sandstone", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_SMOOTH_STONE), "Smooth Stone", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_STONE_BRICK), "Stone Brick", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_DARK_PRISMARINE), "Dark Prismarine", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_MOSSY_COBBLESTONE), "Mossy Cobblestone", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_PRISMARINE), "Prismarine", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_PRISMARINE_BRICKS), "Prismarine Bricks", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_PURPUR), "Purpur", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_RED_NETHER_BRICK), "Red Nether Brick", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_RED_SANDSTONE), "Red Sandstone", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_SMOOTH_SANDSTONE), "Smooth Sandstone", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_ANDESITE), "Andesite", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_DIORITE), "Diorite", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_END_STONE_BRICK), "End Stone Brick", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_GRANITE), "Granite", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_POLISHED_ANDESITE), "Polished Andesite", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_POLISHED_DIORITE), "Polished Diorite", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_POLISHED_GRANITE), "Polished Granite", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_SMOOTH_RED_SANDSTONE), "Smooth Red Sandstone", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_CUT_RED_SANDSTONE), "Cut Red Sandstone", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_CUT_SANDSTONE), "Cut Sandstone", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_MOSSY_STONE_BRICK), "Mossy Stone Brick", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_SMOOTH_QUARTZ), "Smooth Quartz", $stoneSlabBreakInfo)); - self::register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_STONE), "Stone", $stoneSlabBreakInfo)); - self::register(new Opaque(new BID(Ids::STONECUTTER), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - self::register(new Sugarcane(new BID(Ids::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane")); - self::register(new TNT(new BID(Ids::TNT), "TNT")); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_BRICK), "Brick", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_COBBLESTONE), "Cobblestone", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_FAKE_WOODEN), "Fake Wooden", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_NETHER_BRICK), "Nether Brick", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_QUARTZ), "Quartz", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_SANDSTONE), "Sandstone", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_SMOOTH_STONE), "Smooth Stone", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_STONE_BRICK), "Stone Brick", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_DARK_PRISMARINE), "Dark Prismarine", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_MOSSY_COBBLESTONE), "Mossy Cobblestone", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_PRISMARINE), "Prismarine", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_PRISMARINE_BRICKS), "Prismarine Bricks", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_PURPUR), "Purpur", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_RED_NETHER_BRICK), "Red Nether Brick", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_RED_SANDSTONE), "Red Sandstone", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_SMOOTH_SANDSTONE), "Smooth Sandstone", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_ANDESITE), "Andesite", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_DIORITE), "Diorite", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_END_STONE_BRICK), "End Stone Brick", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_GRANITE), "Granite", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_POLISHED_ANDESITE), "Polished Andesite", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_POLISHED_DIORITE), "Polished Diorite", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_POLISHED_GRANITE), "Polished Granite", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_SMOOTH_RED_SANDSTONE), "Smooth Red Sandstone", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_CUT_RED_SANDSTONE), "Cut Red Sandstone", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_CUT_SANDSTONE), "Cut Sandstone", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_MOSSY_STONE_BRICK), "Mossy Stone Brick", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_SMOOTH_QUARTZ), "Smooth Quartz", $stoneSlabBreakInfo)); + $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_STONE), "Stone", $stoneSlabBreakInfo)); + $this->register(new Opaque(new BID(Ids::STONECUTTER), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->register(new Sugarcane(new BID(Ids::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane")); + $this->register(new TNT(new BID(Ids::TNT), "TNT")); $fern = new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_FERN), "Fern"); - self::register($fern); - self::remap(Ids::TALLGRASS, 0, $fern); - self::remap(Ids::TALLGRASS, 3, $fern); - self::register(new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_NORMAL), "Tall Grass")); - self::register(new Torch(new BID(Ids::COLORED_TORCH_BP), "Blue Torch")); - self::register(new Torch(new BID(Ids::COLORED_TORCH_BP, 8), "Purple Torch")); - self::register(new Torch(new BID(Ids::COLORED_TORCH_RG), "Red Torch")); - self::register(new Torch(new BID(Ids::COLORED_TORCH_RG, 8), "Green Torch")); - self::register(new Torch(new BID(Ids::TORCH), "Torch")); - self::register(new TrappedChest(new BID(Ids::TRAPPED_CHEST, 0, null, TileChest::class), "Trapped Chest")); - self::register(new Tripwire(new BID(Ids::TRIPWIRE, 0, ItemIds::STRING), "Tripwire")); - self::register(new TripwireHook(new BID(Ids::TRIPWIRE_HOOK), "Tripwire Hook")); - self::register(new UnderwaterTorch(new BID(Ids::UNDERWATER_TORCH), "Underwater Torch")); - self::register(new Vine(new BID(Ids::VINE), "Vines")); - self::register(new Water(new BIDFlattened(Ids::FLOWING_WATER, Ids::STILL_WATER), "Water")); - self::register(new WaterLily(new BID(Ids::LILY_PAD), "Lily Pad")); - self::register(new WeightedPressurePlateHeavy(new BID(Ids::HEAVY_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Heavy")); - self::register(new WeightedPressurePlateLight(new BID(Ids::LIGHT_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Light")); - self::register(new Wheat(new BID(Ids::WHEAT_BLOCK), "Wheat Block")); + $this->register($fern); + $this->remap(Ids::TALLGRASS, 0, $fern); + $this->remap(Ids::TALLGRASS, 3, $fern); + $this->register(new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_NORMAL), "Tall Grass")); + $this->register(new Torch(new BID(Ids::COLORED_TORCH_BP), "Blue Torch")); + $this->register(new Torch(new BID(Ids::COLORED_TORCH_BP, 8), "Purple Torch")); + $this->register(new Torch(new BID(Ids::COLORED_TORCH_RG), "Red Torch")); + $this->register(new Torch(new BID(Ids::COLORED_TORCH_RG, 8), "Green Torch")); + $this->register(new Torch(new BID(Ids::TORCH), "Torch")); + $this->register(new TrappedChest(new BID(Ids::TRAPPED_CHEST, 0, null, TileChest::class), "Trapped Chest")); + $this->register(new Tripwire(new BID(Ids::TRIPWIRE, 0, ItemIds::STRING), "Tripwire")); + $this->register(new TripwireHook(new BID(Ids::TRIPWIRE_HOOK), "Tripwire Hook")); + $this->register(new UnderwaterTorch(new BID(Ids::UNDERWATER_TORCH), "Underwater Torch")); + $this->register(new Vine(new BID(Ids::VINE), "Vines")); + $this->register(new Water(new BIDFlattened(Ids::FLOWING_WATER, Ids::STILL_WATER), "Water")); + $this->register(new WaterLily(new BID(Ids::LILY_PAD), "Lily Pad")); + $this->register(new WeightedPressurePlateHeavy(new BID(Ids::HEAVY_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Heavy")); + $this->register(new WeightedPressurePlateLight(new BID(Ids::LIGHT_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Light")); + $this->register(new Wheat(new BID(Ids::WHEAT_BLOCK), "Wheat Block")); //region ugly treetype -> blockID mapping tables $woodenStairIds = [ @@ -475,28 +481,28 @@ class BlockFactory{ foreach(TreeType::getAll() as $treeType){ $magicNumber = $treeType->getMagicNumber(); $name = $treeType->getDisplayName(); - self::register(new Planks(new BID(Ids::PLANKS, $magicNumber), $name . " Planks")); - self::register(new Sapling(new BID(Ids::SAPLING, $magicNumber), $name . " Sapling", $treeType)); - self::register(new WoodenFence(new BID(Ids::FENCE, $magicNumber), $name . " Fence")); - self::register(new WoodenSlab(new BIDFlattened(Ids::WOODEN_SLAB, Ids::DOUBLE_WOODEN_SLAB, $treeType->getMagicNumber()), $treeType->getDisplayName())); + $this->register(new Planks(new BID(Ids::PLANKS, $magicNumber), $name . " Planks")); + $this->register(new Sapling(new BID(Ids::SAPLING, $magicNumber), $name . " Sapling", $treeType)); + $this->register(new WoodenFence(new BID(Ids::FENCE, $magicNumber), $name . " Fence")); + $this->register(new WoodenSlab(new BIDFlattened(Ids::WOODEN_SLAB, Ids::DOUBLE_WOODEN_SLAB, $treeType->getMagicNumber()), $treeType->getDisplayName())); //TODO: find a better way to deal with this split - self::register(new Leaves(new BID($magicNumber >= 4 ? Ids::LEAVES2 : Ids::LEAVES, $magicNumber & 0x03), $name . " Leaves", $treeType)); - self::register(new Log(new BID($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, $magicNumber & 0x03), $name . " Log", $treeType)); + $this->register(new Leaves(new BID($magicNumber >= 4 ? Ids::LEAVES2 : Ids::LEAVES, $magicNumber & 0x03), $name . " Leaves", $treeType)); + $this->register(new Log(new BID($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, $magicNumber & 0x03), $name . " Log", $treeType)); $wood = new Wood(new BID(Ids::WOOD, $magicNumber), $name . " Wood", $treeType); - self::register($wood); - self::remap($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, ($magicNumber & 0x03) | 0b1100, $wood); + $this->register($wood); + $this->remap($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, ($magicNumber & 0x03) | 0b1100, $wood); - self::register(new FenceGate(new BID($fenceGateIds[$treeType->id()]), $treeType->getDisplayName() . " Fence Gate")); - self::register(new WoodenStairs(new BID($woodenStairIds[$treeType->id()]), $treeType->getDisplayName() . " Stairs")); - self::register(new WoodenDoor($woodenDoorIds[$treeType->id()], $treeType->getDisplayName() . " Door")); + $this->register(new FenceGate(new BID($fenceGateIds[$treeType->id()]), $treeType->getDisplayName() . " Fence Gate")); + $this->register(new WoodenStairs(new BID($woodenStairIds[$treeType->id()]), $treeType->getDisplayName() . " Stairs")); + $this->register(new WoodenDoor($woodenDoorIds[$treeType->id()], $treeType->getDisplayName() . " Door")); - self::register(new WoodenButton(new BID($woodenButtonIds[$treeType->id()]), $treeType->getDisplayName() . " Button")); - self::register(new WoodenPressurePlate(new BID($woodenPressurePlateIds[$treeType->id()]), $treeType->getDisplayName() . " Pressure Plate")); - self::register(new WoodenTrapdoor(new BID($woodenTrapdoorIds[$treeType->id()]), $treeType->getDisplayName() . " Trapdoor")); + $this->register(new WoodenButton(new BID($woodenButtonIds[$treeType->id()]), $treeType->getDisplayName() . " Button")); + $this->register(new WoodenPressurePlate(new BID($woodenPressurePlateIds[$treeType->id()]), $treeType->getDisplayName() . " Pressure Plate")); + $this->register(new WoodenTrapdoor(new BID($woodenTrapdoorIds[$treeType->id()]), $treeType->getDisplayName() . " Trapdoor")); - self::register(new Sign($woodenSignIds[$treeType->id()], $treeType->getDisplayName() . " Sign")); + $this->register(new Sign($woodenSignIds[$treeType->id()], $treeType->getDisplayName() . " Sign")); } static $sandstoneTypes = [ @@ -506,13 +512,13 @@ class BlockFactory{ Meta::SANDSTONE_SMOOTH => "Smooth " ]; $sandstoneBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()); - self::register(new Stair(new BID(Ids::RED_SANDSTONE_STAIRS), "Red Sandstone Stairs", $sandstoneBreakInfo)); - self::register(new Stair(new BID(Ids::SMOOTH_RED_SANDSTONE_STAIRS), "Smooth Red Sandstone Stairs", $sandstoneBreakInfo)); - self::register(new Stair(new BID(Ids::SANDSTONE_STAIRS), "Sandstone Stairs", $sandstoneBreakInfo)); - self::register(new Stair(new BID(Ids::SMOOTH_SANDSTONE_STAIRS), "Smooth Sandstone Stairs", $sandstoneBreakInfo)); + $this->register(new Stair(new BID(Ids::RED_SANDSTONE_STAIRS), "Red Sandstone Stairs", $sandstoneBreakInfo)); + $this->register(new Stair(new BID(Ids::SMOOTH_RED_SANDSTONE_STAIRS), "Smooth Red Sandstone Stairs", $sandstoneBreakInfo)); + $this->register(new Stair(new BID(Ids::SANDSTONE_STAIRS), "Sandstone Stairs", $sandstoneBreakInfo)); + $this->register(new Stair(new BID(Ids::SMOOTH_SANDSTONE_STAIRS), "Smooth Sandstone Stairs", $sandstoneBreakInfo)); foreach($sandstoneTypes as $variant => $prefix){ - self::register(new Opaque(new BID(Ids::SANDSTONE, $variant), $prefix . "Sandstone", $sandstoneBreakInfo)); - self::register(new Opaque(new BID(Ids::RED_SANDSTONE, $variant), $prefix . "Red Sandstone", $sandstoneBreakInfo)); + $this->register(new Opaque(new BID(Ids::SANDSTONE, $variant), $prefix . "Sandstone", $sandstoneBreakInfo)); + $this->register(new Opaque(new BID(Ids::RED_SANDSTONE, $variant), $prefix . "Red Sandstone", $sandstoneBreakInfo)); } //region ugly glazed-terracotta colour -> ID mapping table @@ -538,16 +544,16 @@ class BlockFactory{ //endregion foreach(DyeColor::getAll() as $color){ - self::register(new Carpet(new BID(Ids::CARPET, $color->getMagicNumber()), $color->getDisplayName() . " Carpet")); - self::register(new Concrete(new BID(Ids::CONCRETE, $color->getMagicNumber()), $color->getDisplayName() . " Concrete")); - self::register(new ConcretePowder(new BID(Ids::CONCRETE_POWDER, $color->getMagicNumber()), $color->getDisplayName() . " Concrete Powder")); - self::register(new Glass(new BID(Ids::STAINED_GLASS, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass")); - self::register(new GlassPane(new BID(Ids::STAINED_GLASS_PANE, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass Pane")); - self::register(new GlazedTerracotta(new BID($glazedTerracottaIds[$color->id()]), $color->getDisplayName() . " Glazed Terracotta")); - self::register(new HardenedClay(new BID(Ids::STAINED_CLAY, $color->getMagicNumber()), $color->getDisplayName() . " Stained Clay")); - self::register(new HardenedGlass(new BID(Ids::HARD_STAINED_GLASS, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass")); - self::register(new HardenedGlassPane(new BID(Ids::HARD_STAINED_GLASS_PANE, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass Pane")); - self::register(new Wool(new BID(Ids::WOOL, $color->getMagicNumber()), $color->getDisplayName() . " Wool")); + $this->register(new Carpet(new BID(Ids::CARPET, $color->getMagicNumber()), $color->getDisplayName() . " Carpet")); + $this->register(new Concrete(new BID(Ids::CONCRETE, $color->getMagicNumber()), $color->getDisplayName() . " Concrete")); + $this->register(new ConcretePowder(new BID(Ids::CONCRETE_POWDER, $color->getMagicNumber()), $color->getDisplayName() . " Concrete Powder")); + $this->register(new Glass(new BID(Ids::STAINED_GLASS, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass")); + $this->register(new GlassPane(new BID(Ids::STAINED_GLASS_PANE, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass Pane")); + $this->register(new GlazedTerracotta(new BID($glazedTerracottaIds[$color->id()]), $color->getDisplayName() . " Glazed Terracotta")); + $this->register(new HardenedClay(new BID(Ids::STAINED_CLAY, $color->getMagicNumber()), $color->getDisplayName() . " Stained Clay")); + $this->register(new HardenedGlass(new BID(Ids::HARD_STAINED_GLASS, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass")); + $this->register(new HardenedGlassPane(new BID(Ids::HARD_STAINED_GLASS_PANE, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass Pane")); + $this->register(new Wool(new BID(Ids::WOOL, $color->getMagicNumber()), $color->getDisplayName() . " Wool")); } static $wallTypes = [ @@ -567,10 +573,10 @@ class BlockFactory{ Meta::WALL_STONE_BRICK => "Stone Brick" ]; foreach($wallTypes as $magicNumber => $prefix){ - self::register(new Wall(new BID(Ids::COBBLESTONE_WALL, $magicNumber), $prefix . " Wall")); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, $magicNumber), $prefix . " Wall")); } - self::registerElements(); + $this->registerElements(); //region --- auto-generated TODOs --- //TODO: minecraft:bamboo @@ -638,131 +644,127 @@ class BlockFactory{ //endregion } - private static function registerElements() : void{ - self::register(new Opaque(new BID(Ids::ELEMENT_0), "???", BlockBreakInfo::instant())); + private function registerElements() : void{ + $this->register(new Opaque(new BID(Ids::ELEMENT_0), "???", BlockBreakInfo::instant())); - self::register(new Element(new BID(Ids::ELEMENT_1), "Hydrogen", BlockBreakInfo::instant(), "h", 1, 5)); - self::register(new Element(new BID(Ids::ELEMENT_2), "Helium", BlockBreakInfo::instant(), "he", 2, 7)); - self::register(new Element(new BID(Ids::ELEMENT_3), "Lithium", BlockBreakInfo::instant(), "li", 3, 0)); - self::register(new Element(new BID(Ids::ELEMENT_4), "Beryllium", BlockBreakInfo::instant(), "be", 4, 1)); - self::register(new Element(new BID(Ids::ELEMENT_5), "Boron", BlockBreakInfo::instant(), "b", 5, 4)); - self::register(new Element(new BID(Ids::ELEMENT_6), "Carbon", BlockBreakInfo::instant(), "c", 6, 5)); - self::register(new Element(new BID(Ids::ELEMENT_7), "Nitrogen", BlockBreakInfo::instant(), "n", 7, 5)); - self::register(new Element(new BID(Ids::ELEMENT_8), "Oxygen", BlockBreakInfo::instant(), "o", 8, 5)); - self::register(new Element(new BID(Ids::ELEMENT_9), "Fluorine", BlockBreakInfo::instant(), "f", 9, 6)); - self::register(new Element(new BID(Ids::ELEMENT_10), "Neon", BlockBreakInfo::instant(), "ne", 10, 7)); - self::register(new Element(new BID(Ids::ELEMENT_11), "Sodium", BlockBreakInfo::instant(), "na", 11, 0)); - self::register(new Element(new BID(Ids::ELEMENT_12), "Magnesium", BlockBreakInfo::instant(), "mg", 12, 1)); - self::register(new Element(new BID(Ids::ELEMENT_13), "Aluminum", BlockBreakInfo::instant(), "al", 13, 3)); - self::register(new Element(new BID(Ids::ELEMENT_14), "Silicon", BlockBreakInfo::instant(), "si", 14, 4)); - self::register(new Element(new BID(Ids::ELEMENT_15), "Phosphorus", BlockBreakInfo::instant(), "p", 15, 5)); - self::register(new Element(new BID(Ids::ELEMENT_16), "Sulfur", BlockBreakInfo::instant(), "s", 16, 5)); - self::register(new Element(new BID(Ids::ELEMENT_17), "Chlorine", BlockBreakInfo::instant(), "cl", 17, 6)); - self::register(new Element(new BID(Ids::ELEMENT_18), "Argon", BlockBreakInfo::instant(), "ar", 18, 7)); - self::register(new Element(new BID(Ids::ELEMENT_19), "Potassium", BlockBreakInfo::instant(), "k", 19, 0)); - self::register(new Element(new BID(Ids::ELEMENT_20), "Calcium", BlockBreakInfo::instant(), "ca", 20, 1)); - self::register(new Element(new BID(Ids::ELEMENT_21), "Scandium", BlockBreakInfo::instant(), "sc", 21, 2)); - self::register(new Element(new BID(Ids::ELEMENT_22), "Titanium", BlockBreakInfo::instant(), "ti", 22, 2)); - self::register(new Element(new BID(Ids::ELEMENT_23), "Vanadium", BlockBreakInfo::instant(), "v", 23, 2)); - self::register(new Element(new BID(Ids::ELEMENT_24), "Chromium", BlockBreakInfo::instant(), "cr", 24, 2)); - self::register(new Element(new BID(Ids::ELEMENT_25), "Manganese", BlockBreakInfo::instant(), "mn", 25, 2)); - self::register(new Element(new BID(Ids::ELEMENT_26), "Iron", BlockBreakInfo::instant(), "fe", 26, 2)); - self::register(new Element(new BID(Ids::ELEMENT_27), "Cobalt", BlockBreakInfo::instant(), "co", 27, 2)); - self::register(new Element(new BID(Ids::ELEMENT_28), "Nickel", BlockBreakInfo::instant(), "ni", 28, 2)); - self::register(new Element(new BID(Ids::ELEMENT_29), "Copper", BlockBreakInfo::instant(), "cu", 29, 2)); - self::register(new Element(new BID(Ids::ELEMENT_30), "Zinc", BlockBreakInfo::instant(), "zn", 30, 2)); - self::register(new Element(new BID(Ids::ELEMENT_31), "Gallium", BlockBreakInfo::instant(), "ga", 31, 3)); - self::register(new Element(new BID(Ids::ELEMENT_32), "Germanium", BlockBreakInfo::instant(), "ge", 32, 4)); - self::register(new Element(new BID(Ids::ELEMENT_33), "Arsenic", BlockBreakInfo::instant(), "as", 33, 4)); - self::register(new Element(new BID(Ids::ELEMENT_34), "Selenium", BlockBreakInfo::instant(), "se", 34, 5)); - self::register(new Element(new BID(Ids::ELEMENT_35), "Bromine", BlockBreakInfo::instant(), "br", 35, 6)); - self::register(new Element(new BID(Ids::ELEMENT_36), "Krypton", BlockBreakInfo::instant(), "kr", 36, 7)); - self::register(new Element(new BID(Ids::ELEMENT_37), "Rubidium", BlockBreakInfo::instant(), "rb", 37, 0)); - self::register(new Element(new BID(Ids::ELEMENT_38), "Strontium", BlockBreakInfo::instant(), "sr", 38, 1)); - self::register(new Element(new BID(Ids::ELEMENT_39), "Yttrium", BlockBreakInfo::instant(), "y", 39, 2)); - self::register(new Element(new BID(Ids::ELEMENT_40), "Zirconium", BlockBreakInfo::instant(), "zr", 40, 2)); - self::register(new Element(new BID(Ids::ELEMENT_41), "Niobium", BlockBreakInfo::instant(), "nb", 41, 2)); - self::register(new Element(new BID(Ids::ELEMENT_42), "Molybdenum", BlockBreakInfo::instant(), "mo", 42, 2)); - self::register(new Element(new BID(Ids::ELEMENT_43), "Technetium", BlockBreakInfo::instant(), "tc", 43, 2)); - self::register(new Element(new BID(Ids::ELEMENT_44), "Ruthenium", BlockBreakInfo::instant(), "ru", 44, 2)); - self::register(new Element(new BID(Ids::ELEMENT_45), "Rhodium", BlockBreakInfo::instant(), "rh", 45, 2)); - self::register(new Element(new BID(Ids::ELEMENT_46), "Palladium", BlockBreakInfo::instant(), "pd", 46, 2)); - self::register(new Element(new BID(Ids::ELEMENT_47), "Silver", BlockBreakInfo::instant(), "ag", 47, 2)); - self::register(new Element(new BID(Ids::ELEMENT_48), "Cadmium", BlockBreakInfo::instant(), "cd", 48, 2)); - self::register(new Element(new BID(Ids::ELEMENT_49), "Indium", BlockBreakInfo::instant(), "in", 49, 3)); - self::register(new Element(new BID(Ids::ELEMENT_50), "Tin", BlockBreakInfo::instant(), "sn", 50, 3)); - self::register(new Element(new BID(Ids::ELEMENT_51), "Antimony", BlockBreakInfo::instant(), "sb", 51, 4)); - self::register(new Element(new BID(Ids::ELEMENT_52), "Tellurium", BlockBreakInfo::instant(), "te", 52, 4)); - self::register(new Element(new BID(Ids::ELEMENT_53), "Iodine", BlockBreakInfo::instant(), "i", 53, 6)); - self::register(new Element(new BID(Ids::ELEMENT_54), "Xenon", BlockBreakInfo::instant(), "xe", 54, 7)); - self::register(new Element(new BID(Ids::ELEMENT_55), "Cesium", BlockBreakInfo::instant(), "cs", 55, 0)); - self::register(new Element(new BID(Ids::ELEMENT_56), "Barium", BlockBreakInfo::instant(), "ba", 56, 1)); - self::register(new Element(new BID(Ids::ELEMENT_57), "Lanthanum", BlockBreakInfo::instant(), "la", 57, 8)); - self::register(new Element(new BID(Ids::ELEMENT_58), "Cerium", BlockBreakInfo::instant(), "ce", 58, 8)); - self::register(new Element(new BID(Ids::ELEMENT_59), "Praseodymium", BlockBreakInfo::instant(), "pr", 59, 8)); - self::register(new Element(new BID(Ids::ELEMENT_60), "Neodymium", BlockBreakInfo::instant(), "nd", 60, 8)); - self::register(new Element(new BID(Ids::ELEMENT_61), "Promethium", BlockBreakInfo::instant(), "pm", 61, 8)); - self::register(new Element(new BID(Ids::ELEMENT_62), "Samarium", BlockBreakInfo::instant(), "sm", 62, 8)); - self::register(new Element(new BID(Ids::ELEMENT_63), "Europium", BlockBreakInfo::instant(), "eu", 63, 8)); - self::register(new Element(new BID(Ids::ELEMENT_64), "Gadolinium", BlockBreakInfo::instant(), "gd", 64, 8)); - self::register(new Element(new BID(Ids::ELEMENT_65), "Terbium", BlockBreakInfo::instant(), "tb", 65, 8)); - self::register(new Element(new BID(Ids::ELEMENT_66), "Dysprosium", BlockBreakInfo::instant(), "dy", 66, 8)); - self::register(new Element(new BID(Ids::ELEMENT_67), "Holmium", BlockBreakInfo::instant(), "ho", 67, 8)); - self::register(new Element(new BID(Ids::ELEMENT_68), "Erbium", BlockBreakInfo::instant(), "er", 68, 8)); - self::register(new Element(new BID(Ids::ELEMENT_69), "Thulium", BlockBreakInfo::instant(), "tm", 69, 8)); - self::register(new Element(new BID(Ids::ELEMENT_70), "Ytterbium", BlockBreakInfo::instant(), "yb", 70, 8)); - self::register(new Element(new BID(Ids::ELEMENT_71), "Lutetium", BlockBreakInfo::instant(), "lu", 71, 8)); - self::register(new Element(new BID(Ids::ELEMENT_72), "Hafnium", BlockBreakInfo::instant(), "hf", 72, 2)); - self::register(new Element(new BID(Ids::ELEMENT_73), "Tantalum", BlockBreakInfo::instant(), "ta", 73, 2)); - self::register(new Element(new BID(Ids::ELEMENT_74), "Tungsten", BlockBreakInfo::instant(), "w", 74, 2)); - self::register(new Element(new BID(Ids::ELEMENT_75), "Rhenium", BlockBreakInfo::instant(), "re", 75, 2)); - self::register(new Element(new BID(Ids::ELEMENT_76), "Osmium", BlockBreakInfo::instant(), "os", 76, 2)); - self::register(new Element(new BID(Ids::ELEMENT_77), "Iridium", BlockBreakInfo::instant(), "ir", 77, 2)); - self::register(new Element(new BID(Ids::ELEMENT_78), "Platinum", BlockBreakInfo::instant(), "pt", 78, 2)); - self::register(new Element(new BID(Ids::ELEMENT_79), "Gold", BlockBreakInfo::instant(), "au", 79, 2)); - self::register(new Element(new BID(Ids::ELEMENT_80), "Mercury", BlockBreakInfo::instant(), "hg", 80, 2)); - self::register(new Element(new BID(Ids::ELEMENT_81), "Thallium", BlockBreakInfo::instant(), "tl", 81, 3)); - self::register(new Element(new BID(Ids::ELEMENT_82), "Lead", BlockBreakInfo::instant(), "pb", 82, 3)); - self::register(new Element(new BID(Ids::ELEMENT_83), "Bismuth", BlockBreakInfo::instant(), "bi", 83, 3)); - self::register(new Element(new BID(Ids::ELEMENT_84), "Polonium", BlockBreakInfo::instant(), "po", 84, 4)); - self::register(new Element(new BID(Ids::ELEMENT_85), "Astatine", BlockBreakInfo::instant(), "at", 85, 6)); - self::register(new Element(new BID(Ids::ELEMENT_86), "Radon", BlockBreakInfo::instant(), "rn", 86, 7)); - self::register(new Element(new BID(Ids::ELEMENT_87), "Francium", BlockBreakInfo::instant(), "fr", 87, 0)); - self::register(new Element(new BID(Ids::ELEMENT_88), "Radium", BlockBreakInfo::instant(), "ra", 88, 1)); - self::register(new Element(new BID(Ids::ELEMENT_89), "Actinium", BlockBreakInfo::instant(), "ac", 89, 9)); - self::register(new Element(new BID(Ids::ELEMENT_90), "Thorium", BlockBreakInfo::instant(), "th", 90, 9)); - self::register(new Element(new BID(Ids::ELEMENT_91), "Protactinium", BlockBreakInfo::instant(), "pa", 91, 9)); - self::register(new Element(new BID(Ids::ELEMENT_92), "Uranium", BlockBreakInfo::instant(), "u", 92, 9)); - self::register(new Element(new BID(Ids::ELEMENT_93), "Neptunium", BlockBreakInfo::instant(), "np", 93, 9)); - self::register(new Element(new BID(Ids::ELEMENT_94), "Plutonium", BlockBreakInfo::instant(), "pu", 94, 9)); - self::register(new Element(new BID(Ids::ELEMENT_95), "Americium", BlockBreakInfo::instant(), "am", 95, 9)); - self::register(new Element(new BID(Ids::ELEMENT_96), "Curium", BlockBreakInfo::instant(), "cm", 96, 9)); - self::register(new Element(new BID(Ids::ELEMENT_97), "Berkelium", BlockBreakInfo::instant(), "bk", 97, 9)); - self::register(new Element(new BID(Ids::ELEMENT_98), "Californium", BlockBreakInfo::instant(), "cf", 98, 9)); - self::register(new Element(new BID(Ids::ELEMENT_99), "Einsteinium", BlockBreakInfo::instant(), "es", 99, 9)); - self::register(new Element(new BID(Ids::ELEMENT_100), "Fermium", BlockBreakInfo::instant(), "fm", 100, 9)); - self::register(new Element(new BID(Ids::ELEMENT_101), "Mendelevium", BlockBreakInfo::instant(), "md", 101, 9)); - self::register(new Element(new BID(Ids::ELEMENT_102), "Nobelium", BlockBreakInfo::instant(), "no", 102, 9)); - self::register(new Element(new BID(Ids::ELEMENT_103), "Lawrencium", BlockBreakInfo::instant(), "lr", 103, 9)); - self::register(new Element(new BID(Ids::ELEMENT_104), "Rutherfordium", BlockBreakInfo::instant(), "rf", 104, 2)); - self::register(new Element(new BID(Ids::ELEMENT_105), "Dubnium", BlockBreakInfo::instant(), "db", 105, 2)); - self::register(new Element(new BID(Ids::ELEMENT_106), "Seaborgium", BlockBreakInfo::instant(), "sg", 106, 2)); - self::register(new Element(new BID(Ids::ELEMENT_107), "Bohrium", BlockBreakInfo::instant(), "bh", 107, 2)); - self::register(new Element(new BID(Ids::ELEMENT_108), "Hassium", BlockBreakInfo::instant(), "hs", 108, 2)); - self::register(new Element(new BID(Ids::ELEMENT_109), "Meitnerium", BlockBreakInfo::instant(), "mt", 109, 2)); - self::register(new Element(new BID(Ids::ELEMENT_110), "Darmstadtium", BlockBreakInfo::instant(), "ds", 110, 2)); - self::register(new Element(new BID(Ids::ELEMENT_111), "Roentgenium", BlockBreakInfo::instant(), "rg", 111, 2)); - self::register(new Element(new BID(Ids::ELEMENT_112), "Copernicium", BlockBreakInfo::instant(), "cn", 112, 2)); - self::register(new Element(new BID(Ids::ELEMENT_113), "Nihonium", BlockBreakInfo::instant(), "nh", 113, 3)); - self::register(new Element(new BID(Ids::ELEMENT_114), "Flerovium", BlockBreakInfo::instant(), "fl", 114, 3)); - self::register(new Element(new BID(Ids::ELEMENT_115), "Moscovium", BlockBreakInfo::instant(), "mc", 115, 3)); - self::register(new Element(new BID(Ids::ELEMENT_116), "Livermorium", BlockBreakInfo::instant(), "lv", 116, 3)); - self::register(new Element(new BID(Ids::ELEMENT_117), "Tennessine", BlockBreakInfo::instant(), "ts", 117, 6)); - self::register(new Element(new BID(Ids::ELEMENT_118), "Oganesson", BlockBreakInfo::instant(), "og", 118, 7)); - } - - public static function isInit() : bool{ - return self::$fullList !== null; + $this->register(new Element(new BID(Ids::ELEMENT_1), "Hydrogen", BlockBreakInfo::instant(), "h", 1, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_2), "Helium", BlockBreakInfo::instant(), "he", 2, 7)); + $this->register(new Element(new BID(Ids::ELEMENT_3), "Lithium", BlockBreakInfo::instant(), "li", 3, 0)); + $this->register(new Element(new BID(Ids::ELEMENT_4), "Beryllium", BlockBreakInfo::instant(), "be", 4, 1)); + $this->register(new Element(new BID(Ids::ELEMENT_5), "Boron", BlockBreakInfo::instant(), "b", 5, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_6), "Carbon", BlockBreakInfo::instant(), "c", 6, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_7), "Nitrogen", BlockBreakInfo::instant(), "n", 7, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_8), "Oxygen", BlockBreakInfo::instant(), "o", 8, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_9), "Fluorine", BlockBreakInfo::instant(), "f", 9, 6)); + $this->register(new Element(new BID(Ids::ELEMENT_10), "Neon", BlockBreakInfo::instant(), "ne", 10, 7)); + $this->register(new Element(new BID(Ids::ELEMENT_11), "Sodium", BlockBreakInfo::instant(), "na", 11, 0)); + $this->register(new Element(new BID(Ids::ELEMENT_12), "Magnesium", BlockBreakInfo::instant(), "mg", 12, 1)); + $this->register(new Element(new BID(Ids::ELEMENT_13), "Aluminum", BlockBreakInfo::instant(), "al", 13, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_14), "Silicon", BlockBreakInfo::instant(), "si", 14, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_15), "Phosphorus", BlockBreakInfo::instant(), "p", 15, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_16), "Sulfur", BlockBreakInfo::instant(), "s", 16, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_17), "Chlorine", BlockBreakInfo::instant(), "cl", 17, 6)); + $this->register(new Element(new BID(Ids::ELEMENT_18), "Argon", BlockBreakInfo::instant(), "ar", 18, 7)); + $this->register(new Element(new BID(Ids::ELEMENT_19), "Potassium", BlockBreakInfo::instant(), "k", 19, 0)); + $this->register(new Element(new BID(Ids::ELEMENT_20), "Calcium", BlockBreakInfo::instant(), "ca", 20, 1)); + $this->register(new Element(new BID(Ids::ELEMENT_21), "Scandium", BlockBreakInfo::instant(), "sc", 21, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_22), "Titanium", BlockBreakInfo::instant(), "ti", 22, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_23), "Vanadium", BlockBreakInfo::instant(), "v", 23, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_24), "Chromium", BlockBreakInfo::instant(), "cr", 24, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_25), "Manganese", BlockBreakInfo::instant(), "mn", 25, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_26), "Iron", BlockBreakInfo::instant(), "fe", 26, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_27), "Cobalt", BlockBreakInfo::instant(), "co", 27, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_28), "Nickel", BlockBreakInfo::instant(), "ni", 28, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_29), "Copper", BlockBreakInfo::instant(), "cu", 29, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_30), "Zinc", BlockBreakInfo::instant(), "zn", 30, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_31), "Gallium", BlockBreakInfo::instant(), "ga", 31, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_32), "Germanium", BlockBreakInfo::instant(), "ge", 32, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_33), "Arsenic", BlockBreakInfo::instant(), "as", 33, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_34), "Selenium", BlockBreakInfo::instant(), "se", 34, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_35), "Bromine", BlockBreakInfo::instant(), "br", 35, 6)); + $this->register(new Element(new BID(Ids::ELEMENT_36), "Krypton", BlockBreakInfo::instant(), "kr", 36, 7)); + $this->register(new Element(new BID(Ids::ELEMENT_37), "Rubidium", BlockBreakInfo::instant(), "rb", 37, 0)); + $this->register(new Element(new BID(Ids::ELEMENT_38), "Strontium", BlockBreakInfo::instant(), "sr", 38, 1)); + $this->register(new Element(new BID(Ids::ELEMENT_39), "Yttrium", BlockBreakInfo::instant(), "y", 39, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_40), "Zirconium", BlockBreakInfo::instant(), "zr", 40, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_41), "Niobium", BlockBreakInfo::instant(), "nb", 41, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_42), "Molybdenum", BlockBreakInfo::instant(), "mo", 42, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_43), "Technetium", BlockBreakInfo::instant(), "tc", 43, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_44), "Ruthenium", BlockBreakInfo::instant(), "ru", 44, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_45), "Rhodium", BlockBreakInfo::instant(), "rh", 45, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_46), "Palladium", BlockBreakInfo::instant(), "pd", 46, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_47), "Silver", BlockBreakInfo::instant(), "ag", 47, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_48), "Cadmium", BlockBreakInfo::instant(), "cd", 48, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_49), "Indium", BlockBreakInfo::instant(), "in", 49, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_50), "Tin", BlockBreakInfo::instant(), "sn", 50, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_51), "Antimony", BlockBreakInfo::instant(), "sb", 51, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_52), "Tellurium", BlockBreakInfo::instant(), "te", 52, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_53), "Iodine", BlockBreakInfo::instant(), "i", 53, 6)); + $this->register(new Element(new BID(Ids::ELEMENT_54), "Xenon", BlockBreakInfo::instant(), "xe", 54, 7)); + $this->register(new Element(new BID(Ids::ELEMENT_55), "Cesium", BlockBreakInfo::instant(), "cs", 55, 0)); + $this->register(new Element(new BID(Ids::ELEMENT_56), "Barium", BlockBreakInfo::instant(), "ba", 56, 1)); + $this->register(new Element(new BID(Ids::ELEMENT_57), "Lanthanum", BlockBreakInfo::instant(), "la", 57, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_58), "Cerium", BlockBreakInfo::instant(), "ce", 58, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_59), "Praseodymium", BlockBreakInfo::instant(), "pr", 59, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_60), "Neodymium", BlockBreakInfo::instant(), "nd", 60, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_61), "Promethium", BlockBreakInfo::instant(), "pm", 61, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_62), "Samarium", BlockBreakInfo::instant(), "sm", 62, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_63), "Europium", BlockBreakInfo::instant(), "eu", 63, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_64), "Gadolinium", BlockBreakInfo::instant(), "gd", 64, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_65), "Terbium", BlockBreakInfo::instant(), "tb", 65, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_66), "Dysprosium", BlockBreakInfo::instant(), "dy", 66, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_67), "Holmium", BlockBreakInfo::instant(), "ho", 67, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_68), "Erbium", BlockBreakInfo::instant(), "er", 68, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_69), "Thulium", BlockBreakInfo::instant(), "tm", 69, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_70), "Ytterbium", BlockBreakInfo::instant(), "yb", 70, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_71), "Lutetium", BlockBreakInfo::instant(), "lu", 71, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_72), "Hafnium", BlockBreakInfo::instant(), "hf", 72, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_73), "Tantalum", BlockBreakInfo::instant(), "ta", 73, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_74), "Tungsten", BlockBreakInfo::instant(), "w", 74, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_75), "Rhenium", BlockBreakInfo::instant(), "re", 75, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_76), "Osmium", BlockBreakInfo::instant(), "os", 76, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_77), "Iridium", BlockBreakInfo::instant(), "ir", 77, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_78), "Platinum", BlockBreakInfo::instant(), "pt", 78, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_79), "Gold", BlockBreakInfo::instant(), "au", 79, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_80), "Mercury", BlockBreakInfo::instant(), "hg", 80, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_81), "Thallium", BlockBreakInfo::instant(), "tl", 81, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_82), "Lead", BlockBreakInfo::instant(), "pb", 82, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_83), "Bismuth", BlockBreakInfo::instant(), "bi", 83, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_84), "Polonium", BlockBreakInfo::instant(), "po", 84, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_85), "Astatine", BlockBreakInfo::instant(), "at", 85, 6)); + $this->register(new Element(new BID(Ids::ELEMENT_86), "Radon", BlockBreakInfo::instant(), "rn", 86, 7)); + $this->register(new Element(new BID(Ids::ELEMENT_87), "Francium", BlockBreakInfo::instant(), "fr", 87, 0)); + $this->register(new Element(new BID(Ids::ELEMENT_88), "Radium", BlockBreakInfo::instant(), "ra", 88, 1)); + $this->register(new Element(new BID(Ids::ELEMENT_89), "Actinium", BlockBreakInfo::instant(), "ac", 89, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_90), "Thorium", BlockBreakInfo::instant(), "th", 90, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_91), "Protactinium", BlockBreakInfo::instant(), "pa", 91, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_92), "Uranium", BlockBreakInfo::instant(), "u", 92, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_93), "Neptunium", BlockBreakInfo::instant(), "np", 93, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_94), "Plutonium", BlockBreakInfo::instant(), "pu", 94, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_95), "Americium", BlockBreakInfo::instant(), "am", 95, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_96), "Curium", BlockBreakInfo::instant(), "cm", 96, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_97), "Berkelium", BlockBreakInfo::instant(), "bk", 97, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_98), "Californium", BlockBreakInfo::instant(), "cf", 98, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_99), "Einsteinium", BlockBreakInfo::instant(), "es", 99, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_100), "Fermium", BlockBreakInfo::instant(), "fm", 100, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_101), "Mendelevium", BlockBreakInfo::instant(), "md", 101, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_102), "Nobelium", BlockBreakInfo::instant(), "no", 102, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_103), "Lawrencium", BlockBreakInfo::instant(), "lr", 103, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_104), "Rutherfordium", BlockBreakInfo::instant(), "rf", 104, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_105), "Dubnium", BlockBreakInfo::instant(), "db", 105, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_106), "Seaborgium", BlockBreakInfo::instant(), "sg", 106, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_107), "Bohrium", BlockBreakInfo::instant(), "bh", 107, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_108), "Hassium", BlockBreakInfo::instant(), "hs", 108, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_109), "Meitnerium", BlockBreakInfo::instant(), "mt", 109, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_110), "Darmstadtium", BlockBreakInfo::instant(), "ds", 110, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_111), "Roentgenium", BlockBreakInfo::instant(), "rg", 111, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_112), "Copernicium", BlockBreakInfo::instant(), "cn", 112, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_113), "Nihonium", BlockBreakInfo::instant(), "nh", 113, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_114), "Flerovium", BlockBreakInfo::instant(), "fl", 114, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_115), "Moscovium", BlockBreakInfo::instant(), "mc", 115, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_116), "Livermorium", BlockBreakInfo::instant(), "lv", 116, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_117), "Tennessine", BlockBreakInfo::instant(), "ts", 117, 6)); + $this->register(new Element(new BID(Ids::ELEMENT_118), "Oganesson", BlockBreakInfo::instant(), "og", 118, 7)); } /** @@ -777,7 +779,7 @@ class BlockFactory{ * @throws \RuntimeException if something attempted to override an already-registered block without specifying the * $override parameter. */ - public static function register(Block $block, bool $override = false) : void{ + public function register(Block $block, bool $override = false) : void{ $variant = $block->getIdInfo()->getVariant(); $stateMask = $block->getStateBitmask(); @@ -786,7 +788,7 @@ class BlockFactory{ } foreach($block->getIdInfo()->getAllBlockIds() as $id){ - if(!$override and self::isRegistered($id, $variant)){ + if(!$override and $this->isRegistered($id, $variant)){ throw new \InvalidArgumentException("Block registration $id:$variant conflicts with an existing block"); } @@ -795,7 +797,7 @@ class BlockFactory{ continue; } - if(!$override and self::isRegistered($id, $m)){ + if(!$override and $this->isRegistered($id, $m)){ throw new \InvalidArgumentException("Block registration " . get_class($block) . " has states which conflict with other blocks"); } @@ -811,33 +813,33 @@ class BlockFactory{ continue; } - self::fillStaticArrays($index, $v); + $this->fillStaticArrays($index, $v); } - if(!self::isRegistered($id, $variant)){ - self::fillStaticArrays(($id << 4) | $variant, $block); //register default state mapped to variant, for blocks which don't use 0 as valid state + if(!$this->isRegistered($id, $variant)){ + $this->fillStaticArrays(($id << 4) | $variant, $block); //register default state mapped to variant, for blocks which don't use 0 as valid state } } } - public static function remap(int $id, int $meta, Block $block) : void{ - if(self::isRegistered($id, $meta)){ + public function remap(int $id, int $meta, Block $block) : void{ + if($this->isRegistered($id, $meta)){ throw new \InvalidArgumentException("$id:$meta is already mapped"); } - self::fillStaticArrays(($id << 4) | $meta, $block); + $this->fillStaticArrays(($id << 4) | $meta, $block); } - private static function fillStaticArrays(int $index, Block $block) : void{ - self::$fullList[$index] = $block; - self::$lightFilter[$index] = min(15, $block->getLightFilter() + 1); //opacity plus 1 standard light filter - self::$diffusesSkyLight[$index] = $block->diffusesSkyLight(); - self::$blastResistance[$index] = $block->getBreakInfo()->getBlastResistance(); + private function fillStaticArrays(int $index, Block $block) : void{ + $this->fullList[$index] = $block; + $this->lightFilter[$index] = min(15, $block->getLightFilter() + 1); //opacity plus 1 standard light filter + $this->diffusesSkyLight[$index] = $block->diffusesSkyLight(); + $this->blastResistance[$index] = $block->getBreakInfo()->getBlastResistance(); } /** * Returns a new Block instance with the specified ID, meta and position. */ - public static function get(int $id, int $meta = 0) : Block{ + public function get(int $id, int $meta = 0) : Block{ if($meta < 0 or $meta > 0xf){ throw new \InvalidArgumentException("Block meta value $meta is out of bounds"); } @@ -846,8 +848,8 @@ class BlockFactory{ $block = null; try{ $index = ($id << 4) | $meta; - if(self::$fullList[$index] !== null){ - $block = clone self::$fullList[$index]; + if($this->fullList[$index] !== null){ + $block = clone $this->fullList[$index]; } }catch(\RuntimeException $e){ throw new \InvalidArgumentException("Block ID $id is out of bounds"); @@ -860,22 +862,22 @@ class BlockFactory{ return $block; } - public static function fromFullBlock(int $fullState) : Block{ - return self::get($fullState >> 4, $fullState & 0xf); + public function fromFullBlock(int $fullState) : Block{ + return $this->get($fullState >> 4, $fullState & 0xf); } /** * Returns whether a specified block state is already registered in the block factory. */ - public static function isRegistered(int $id, int $meta = 0) : bool{ - $b = self::$fullList[($id << 4) | $meta]; + public function isRegistered(int $id, int $meta = 0) : bool{ + $b = $this->fullList[($id << 4) | $meta]; return $b !== null and !($b instanceof UnknownBlock); } /** * @return Block[] */ - public static function getAllKnownStates() : array{ - return array_filter(self::$fullList->toArray(), function(?Block $v) : bool{ return $v !== null; }); + public function getAllKnownStates() : array{ + return array_filter($this->fullList->toArray(), function(?Block $v) : bool{ return $v !== null; }); } } diff --git a/src/block/ConcretePowder.php b/src/block/ConcretePowder.php index 63cf6c9935..2154acce13 100644 --- a/src/block/ConcretePowder.php +++ b/src/block/ConcretePowder.php @@ -54,7 +54,7 @@ class ConcretePowder extends Opaque implements Fallable{ continue; } if($this->getSide($i) instanceof Water){ - return BlockFactory::get(BlockLegacyIds::CONCRETE, $this->idInfo->getVariant()); + return BlockFactory::getInstance()->get(BlockLegacyIds::CONCRETE, $this->idInfo->getVariant()); } } diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index fc85d0d657..5da766624b 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -689,636 +689,637 @@ final class VanillaBlocks{ } protected static function setup() : void{ - self::register("acacia_button", BlockFactory::get(395)); - self::register("acacia_door", BlockFactory::get(196)); - self::register("acacia_fence", BlockFactory::get(85, 4)); - self::register("acacia_fence_gate", BlockFactory::get(187)); - self::register("acacia_leaves", BlockFactory::get(161)); - self::register("acacia_log", BlockFactory::get(162)); - self::register("acacia_planks", BlockFactory::get(5, 4)); - self::register("acacia_pressure_plate", BlockFactory::get(405)); - self::register("acacia_sapling", BlockFactory::get(6, 4)); - self::register("acacia_sign", BlockFactory::get(445)); - self::register("acacia_slab", BlockFactory::get(158, 4)); - self::register("acacia_stairs", BlockFactory::get(163)); - self::register("acacia_trapdoor", BlockFactory::get(400)); - self::register("acacia_wood", BlockFactory::get(467, 4)); - self::register("activator_rail", BlockFactory::get(126)); - self::register("air", BlockFactory::get(0)); - self::register("allium", BlockFactory::get(38, 2)); - self::register("andesite", BlockFactory::get(1, 5)); - self::register("andesite_slab", BlockFactory::get(417, 3)); - self::register("andesite_stairs", BlockFactory::get(426)); - self::register("andesite_wall", BlockFactory::get(139, 4)); - self::register("anvil", BlockFactory::get(145)); - self::register("azure_bluet", BlockFactory::get(38, 3)); - self::register("banner", BlockFactory::get(176)); - self::register("barrier", BlockFactory::get(416)); - self::register("bed", BlockFactory::get(26)); - self::register("bedrock", BlockFactory::get(7)); - self::register("beetroots", BlockFactory::get(244)); - self::register("birch_button", BlockFactory::get(396)); - self::register("birch_door", BlockFactory::get(194)); - self::register("birch_fence", BlockFactory::get(85, 2)); - self::register("birch_fence_gate", BlockFactory::get(184)); - self::register("birch_leaves", BlockFactory::get(18, 2)); - self::register("birch_log", BlockFactory::get(17, 2)); - self::register("birch_planks", BlockFactory::get(5, 2)); - self::register("birch_pressure_plate", BlockFactory::get(406)); - self::register("birch_sapling", BlockFactory::get(6, 2)); - self::register("birch_sign", BlockFactory::get(441)); - self::register("birch_slab", BlockFactory::get(158, 2)); - self::register("birch_stairs", BlockFactory::get(135)); - self::register("birch_trapdoor", BlockFactory::get(401)); - self::register("birch_wood", BlockFactory::get(467, 2)); - self::register("black_carpet", BlockFactory::get(171, 15)); - self::register("black_concrete", BlockFactory::get(236, 15)); - self::register("black_concrete_powder", BlockFactory::get(237, 15)); - self::register("black_glazed_terracotta", BlockFactory::get(235, 2)); - self::register("black_stained_clay", BlockFactory::get(159, 15)); - self::register("black_stained_glass", BlockFactory::get(241, 15)); - self::register("black_stained_glass_pane", BlockFactory::get(160, 15)); - self::register("black_wool", BlockFactory::get(35, 15)); - self::register("blue_carpet", BlockFactory::get(171, 11)); - self::register("blue_concrete", BlockFactory::get(236, 11)); - self::register("blue_concrete_powder", BlockFactory::get(237, 11)); - self::register("blue_glazed_terracotta", BlockFactory::get(231, 2)); - self::register("blue_ice", BlockFactory::get(266)); - self::register("blue_orchid", BlockFactory::get(38, 1)); - self::register("blue_stained_clay", BlockFactory::get(159, 11)); - self::register("blue_stained_glass", BlockFactory::get(241, 11)); - self::register("blue_stained_glass_pane", BlockFactory::get(160, 11)); - self::register("blue_torch", BlockFactory::get(204, 5)); - self::register("blue_wool", BlockFactory::get(35, 11)); - self::register("bone_block", BlockFactory::get(216)); - self::register("bookshelf", BlockFactory::get(47)); - self::register("brewing_stand", BlockFactory::get(117)); - self::register("brick_slab", BlockFactory::get(44, 4)); - self::register("brick_stairs", BlockFactory::get(108)); - self::register("brick_wall", BlockFactory::get(139, 6)); - self::register("bricks", BlockFactory::get(45)); - self::register("brown_carpet", BlockFactory::get(171, 12)); - self::register("brown_concrete", BlockFactory::get(236, 12)); - self::register("brown_concrete_powder", BlockFactory::get(237, 12)); - self::register("brown_glazed_terracotta", BlockFactory::get(232, 2)); - self::register("brown_mushroom", BlockFactory::get(39)); - self::register("brown_mushroom_block", BlockFactory::get(99)); - self::register("brown_stained_clay", BlockFactory::get(159, 12)); - self::register("brown_stained_glass", BlockFactory::get(241, 12)); - self::register("brown_stained_glass_pane", BlockFactory::get(160, 12)); - self::register("brown_wool", BlockFactory::get(35, 12)); - self::register("cactus", BlockFactory::get(81)); - self::register("cake", BlockFactory::get(92)); - self::register("carrots", BlockFactory::get(141)); - self::register("carved_pumpkin", BlockFactory::get(410)); - self::register("chest", BlockFactory::get(54, 2)); - self::register("chiseled_quartz", BlockFactory::get(155, 1)); - self::register("chiseled_red_sandstone", BlockFactory::get(179, 1)); - self::register("chiseled_sandstone", BlockFactory::get(24, 1)); - self::register("chiseled_stone_bricks", BlockFactory::get(98, 3)); - self::register("clay", BlockFactory::get(82)); - self::register("coal", BlockFactory::get(173)); - self::register("coal_ore", BlockFactory::get(16)); - self::register("coarse_dirt", BlockFactory::get(3, 1)); - self::register("cobblestone", BlockFactory::get(4)); - self::register("cobblestone_slab", BlockFactory::get(44, 3)); - self::register("cobblestone_stairs", BlockFactory::get(67)); - self::register("cobblestone_wall", BlockFactory::get(139)); - self::register("cobweb", BlockFactory::get(30)); - self::register("cocoa_pod", BlockFactory::get(127)); - self::register("cornflower", BlockFactory::get(38, 9)); - self::register("cracked_stone_bricks", BlockFactory::get(98, 2)); - self::register("crafting_table", BlockFactory::get(58)); - self::register("cut_red_sandstone", BlockFactory::get(179, 2)); - self::register("cut_red_sandstone_slab", BlockFactory::get(421, 4)); - self::register("cut_sandstone", BlockFactory::get(24, 2)); - self::register("cut_sandstone_slab", BlockFactory::get(421, 3)); - self::register("cyan_carpet", BlockFactory::get(171, 9)); - self::register("cyan_concrete", BlockFactory::get(236, 9)); - self::register("cyan_concrete_powder", BlockFactory::get(237, 9)); - self::register("cyan_glazed_terracotta", BlockFactory::get(229, 2)); - self::register("cyan_stained_clay", BlockFactory::get(159, 9)); - self::register("cyan_stained_glass", BlockFactory::get(241, 9)); - self::register("cyan_stained_glass_pane", BlockFactory::get(160, 9)); - self::register("cyan_wool", BlockFactory::get(35, 9)); - self::register("dandelion", BlockFactory::get(37)); - self::register("dark_oak_button", BlockFactory::get(397)); - self::register("dark_oak_door", BlockFactory::get(197)); - self::register("dark_oak_fence", BlockFactory::get(85, 5)); - self::register("dark_oak_fence_gate", BlockFactory::get(186)); - self::register("dark_oak_leaves", BlockFactory::get(161, 1)); - self::register("dark_oak_log", BlockFactory::get(162, 1)); - self::register("dark_oak_planks", BlockFactory::get(5, 5)); - self::register("dark_oak_pressure_plate", BlockFactory::get(407)); - self::register("dark_oak_sapling", BlockFactory::get(6, 5)); - self::register("dark_oak_sign", BlockFactory::get(447)); - self::register("dark_oak_slab", BlockFactory::get(158, 5)); - self::register("dark_oak_stairs", BlockFactory::get(164)); - self::register("dark_oak_trapdoor", BlockFactory::get(402)); - self::register("dark_oak_wood", BlockFactory::get(467, 5)); - self::register("dark_prismarine", BlockFactory::get(168, 1)); - self::register("dark_prismarine_slab", BlockFactory::get(182, 3)); - self::register("dark_prismarine_stairs", BlockFactory::get(258)); - self::register("daylight_sensor", BlockFactory::get(151)); - self::register("dead_bush", BlockFactory::get(32)); - self::register("detector_rail", BlockFactory::get(28)); - self::register("diamond", BlockFactory::get(57)); - self::register("diamond_ore", BlockFactory::get(56)); - self::register("diorite", BlockFactory::get(1, 3)); - self::register("diorite_slab", BlockFactory::get(417, 4)); - self::register("diorite_stairs", BlockFactory::get(425)); - self::register("diorite_wall", BlockFactory::get(139, 3)); - self::register("dirt", BlockFactory::get(3)); - self::register("double_tallgrass", BlockFactory::get(175, 2)); - self::register("dragon_egg", BlockFactory::get(122)); - self::register("dried_kelp", BlockFactory::get(394)); - self::register("element_actinium", BlockFactory::get(355)); - self::register("element_aluminum", BlockFactory::get(279)); - self::register("element_americium", BlockFactory::get(361)); - self::register("element_antimony", BlockFactory::get(317)); - self::register("element_argon", BlockFactory::get(284)); - self::register("element_arsenic", BlockFactory::get(299)); - self::register("element_astatine", BlockFactory::get(351)); - self::register("element_barium", BlockFactory::get(322)); - self::register("element_berkelium", BlockFactory::get(363)); - self::register("element_beryllium", BlockFactory::get(270)); - self::register("element_bismuth", BlockFactory::get(349)); - self::register("element_bohrium", BlockFactory::get(373)); - self::register("element_boron", BlockFactory::get(271)); - self::register("element_bromine", BlockFactory::get(301)); - self::register("element_cadmium", BlockFactory::get(314)); - self::register("element_calcium", BlockFactory::get(286)); - self::register("element_californium", BlockFactory::get(364)); - self::register("element_carbon", BlockFactory::get(272)); - self::register("element_cerium", BlockFactory::get(324)); - self::register("element_cesium", BlockFactory::get(321)); - self::register("element_chlorine", BlockFactory::get(283)); - self::register("element_chromium", BlockFactory::get(290)); - self::register("element_cobalt", BlockFactory::get(293)); - self::register("element_copernicium", BlockFactory::get(378)); - self::register("element_copper", BlockFactory::get(295)); - self::register("element_curium", BlockFactory::get(362)); - self::register("element_darmstadtium", BlockFactory::get(376)); - self::register("element_dubnium", BlockFactory::get(371)); - self::register("element_dysprosium", BlockFactory::get(332)); - self::register("element_einsteinium", BlockFactory::get(365)); - self::register("element_erbium", BlockFactory::get(334)); - self::register("element_europium", BlockFactory::get(329)); - self::register("element_fermium", BlockFactory::get(366)); - self::register("element_flerovium", BlockFactory::get(380)); - self::register("element_fluorine", BlockFactory::get(275)); - self::register("element_francium", BlockFactory::get(353)); - self::register("element_gadolinium", BlockFactory::get(330)); - self::register("element_gallium", BlockFactory::get(297)); - self::register("element_germanium", BlockFactory::get(298)); - self::register("element_gold", BlockFactory::get(345)); - self::register("element_hafnium", BlockFactory::get(338)); - self::register("element_hassium", BlockFactory::get(374)); - self::register("element_helium", BlockFactory::get(268)); - self::register("element_holmium", BlockFactory::get(333)); - self::register("element_hydrogen", BlockFactory::get(267)); - self::register("element_indium", BlockFactory::get(315)); - self::register("element_iodine", BlockFactory::get(319)); - self::register("element_iridium", BlockFactory::get(343)); - self::register("element_iron", BlockFactory::get(292)); - self::register("element_krypton", BlockFactory::get(302)); - self::register("element_lanthanum", BlockFactory::get(323)); - self::register("element_lawrencium", BlockFactory::get(369)); - self::register("element_lead", BlockFactory::get(348)); - self::register("element_lithium", BlockFactory::get(269)); - self::register("element_livermorium", BlockFactory::get(382)); - self::register("element_lutetium", BlockFactory::get(337)); - self::register("element_magnesium", BlockFactory::get(278)); - self::register("element_manganese", BlockFactory::get(291)); - self::register("element_meitnerium", BlockFactory::get(375)); - self::register("element_mendelevium", BlockFactory::get(367)); - self::register("element_mercury", BlockFactory::get(346)); - self::register("element_molybdenum", BlockFactory::get(308)); - self::register("element_moscovium", BlockFactory::get(381)); - self::register("element_neodymium", BlockFactory::get(326)); - self::register("element_neon", BlockFactory::get(276)); - self::register("element_neptunium", BlockFactory::get(359)); - self::register("element_nickel", BlockFactory::get(294)); - self::register("element_nihonium", BlockFactory::get(379)); - self::register("element_niobium", BlockFactory::get(307)); - self::register("element_nitrogen", BlockFactory::get(273)); - self::register("element_nobelium", BlockFactory::get(368)); - self::register("element_oganesson", BlockFactory::get(384)); - self::register("element_osmium", BlockFactory::get(342)); - self::register("element_oxygen", BlockFactory::get(274)); - self::register("element_palladium", BlockFactory::get(312)); - self::register("element_phosphorus", BlockFactory::get(281)); - self::register("element_platinum", BlockFactory::get(344)); - self::register("element_plutonium", BlockFactory::get(360)); - self::register("element_polonium", BlockFactory::get(350)); - self::register("element_potassium", BlockFactory::get(285)); - self::register("element_praseodymium", BlockFactory::get(325)); - self::register("element_promethium", BlockFactory::get(327)); - self::register("element_protactinium", BlockFactory::get(357)); - self::register("element_radium", BlockFactory::get(354)); - self::register("element_radon", BlockFactory::get(352)); - self::register("element_rhenium", BlockFactory::get(341)); - self::register("element_rhodium", BlockFactory::get(311)); - self::register("element_roentgenium", BlockFactory::get(377)); - self::register("element_rubidium", BlockFactory::get(303)); - self::register("element_ruthenium", BlockFactory::get(310)); - self::register("element_rutherfordium", BlockFactory::get(370)); - self::register("element_samarium", BlockFactory::get(328)); - self::register("element_scandium", BlockFactory::get(287)); - self::register("element_seaborgium", BlockFactory::get(372)); - self::register("element_selenium", BlockFactory::get(300)); - self::register("element_silicon", BlockFactory::get(280)); - self::register("element_silver", BlockFactory::get(313)); - self::register("element_sodium", BlockFactory::get(277)); - self::register("element_strontium", BlockFactory::get(304)); - self::register("element_sulfur", BlockFactory::get(282)); - self::register("element_tantalum", BlockFactory::get(339)); - self::register("element_technetium", BlockFactory::get(309)); - self::register("element_tellurium", BlockFactory::get(318)); - self::register("element_tennessine", BlockFactory::get(383)); - self::register("element_terbium", BlockFactory::get(331)); - self::register("element_thallium", BlockFactory::get(347)); - self::register("element_thorium", BlockFactory::get(356)); - self::register("element_thulium", BlockFactory::get(335)); - self::register("element_tin", BlockFactory::get(316)); - self::register("element_titanium", BlockFactory::get(288)); - self::register("element_tungsten", BlockFactory::get(340)); - self::register("element_uranium", BlockFactory::get(358)); - self::register("element_vanadium", BlockFactory::get(289)); - self::register("element_xenon", BlockFactory::get(320)); - self::register("element_ytterbium", BlockFactory::get(336)); - self::register("element_yttrium", BlockFactory::get(305)); - self::register("element_zero", BlockFactory::get(36)); - self::register("element_zinc", BlockFactory::get(296)); - self::register("element_zirconium", BlockFactory::get(306)); - self::register("emerald", BlockFactory::get(133)); - self::register("emerald_ore", BlockFactory::get(129)); - self::register("enchanting_table", BlockFactory::get(116)); - self::register("end_portal_frame", BlockFactory::get(120)); - self::register("end_rod", BlockFactory::get(208)); - self::register("end_stone", BlockFactory::get(121)); - self::register("end_stone_brick_slab", BlockFactory::get(417)); - self::register("end_stone_brick_stairs", BlockFactory::get(433)); - self::register("end_stone_brick_wall", BlockFactory::get(139, 10)); - self::register("end_stone_bricks", BlockFactory::get(206)); - self::register("ender_chest", BlockFactory::get(130, 2)); - self::register("fake_wooden_slab", BlockFactory::get(44, 2)); - self::register("farmland", BlockFactory::get(60)); - self::register("fern", BlockFactory::get(31, 2)); - self::register("fire", BlockFactory::get(51)); - self::register("flower_pot", BlockFactory::get(140)); - self::register("frosted_ice", BlockFactory::get(207)); - self::register("furnace", BlockFactory::get(61, 2)); - self::register("glass", BlockFactory::get(20)); - self::register("glass_pane", BlockFactory::get(102)); - self::register("glowing_obsidian", BlockFactory::get(246)); - self::register("glowstone", BlockFactory::get(89)); - self::register("gold", BlockFactory::get(41)); - self::register("gold_ore", BlockFactory::get(14)); - self::register("granite", BlockFactory::get(1, 1)); - self::register("granite_slab", BlockFactory::get(417, 6)); - self::register("granite_stairs", BlockFactory::get(424)); - self::register("granite_wall", BlockFactory::get(139, 2)); - self::register("grass", BlockFactory::get(2)); - self::register("grass_path", BlockFactory::get(198)); - self::register("gravel", BlockFactory::get(13)); - self::register("gray_carpet", BlockFactory::get(171, 7)); - self::register("gray_concrete", BlockFactory::get(236, 7)); - self::register("gray_concrete_powder", BlockFactory::get(237, 7)); - self::register("gray_glazed_terracotta", BlockFactory::get(227, 2)); - self::register("gray_stained_clay", BlockFactory::get(159, 7)); - self::register("gray_stained_glass", BlockFactory::get(241, 7)); - self::register("gray_stained_glass_pane", BlockFactory::get(160, 7)); - self::register("gray_wool", BlockFactory::get(35, 7)); - self::register("green_carpet", BlockFactory::get(171, 13)); - self::register("green_concrete", BlockFactory::get(236, 13)); - self::register("green_concrete_powder", BlockFactory::get(237, 13)); - self::register("green_glazed_terracotta", BlockFactory::get(233, 2)); - self::register("green_stained_clay", BlockFactory::get(159, 13)); - self::register("green_stained_glass", BlockFactory::get(241, 13)); - self::register("green_stained_glass_pane", BlockFactory::get(160, 13)); - self::register("green_torch", BlockFactory::get(202, 13)); - self::register("green_wool", BlockFactory::get(35, 13)); - self::register("hardened_black_stained_glass", BlockFactory::get(254, 15)); - self::register("hardened_black_stained_glass_pane", BlockFactory::get(191, 15)); - self::register("hardened_blue_stained_glass", BlockFactory::get(254, 11)); - self::register("hardened_blue_stained_glass_pane", BlockFactory::get(191, 11)); - self::register("hardened_brown_stained_glass", BlockFactory::get(254, 12)); - self::register("hardened_brown_stained_glass_pane", BlockFactory::get(191, 12)); - self::register("hardened_clay", BlockFactory::get(172)); - self::register("hardened_cyan_stained_glass", BlockFactory::get(254, 9)); - self::register("hardened_cyan_stained_glass_pane", BlockFactory::get(191, 9)); - self::register("hardened_glass", BlockFactory::get(253)); - self::register("hardened_glass_pane", BlockFactory::get(190)); - self::register("hardened_gray_stained_glass", BlockFactory::get(254, 7)); - self::register("hardened_gray_stained_glass_pane", BlockFactory::get(191, 7)); - self::register("hardened_green_stained_glass", BlockFactory::get(254, 13)); - self::register("hardened_green_stained_glass_pane", BlockFactory::get(191, 13)); - self::register("hardened_light_blue_stained_glass", BlockFactory::get(254, 3)); - self::register("hardened_light_blue_stained_glass_pane", BlockFactory::get(191, 3)); - self::register("hardened_light_gray_stained_glass", BlockFactory::get(254, 8)); - self::register("hardened_light_gray_stained_glass_pane", BlockFactory::get(191, 8)); - self::register("hardened_lime_stained_glass", BlockFactory::get(254, 5)); - self::register("hardened_lime_stained_glass_pane", BlockFactory::get(191, 5)); - self::register("hardened_magenta_stained_glass", BlockFactory::get(254, 2)); - self::register("hardened_magenta_stained_glass_pane", BlockFactory::get(191, 2)); - self::register("hardened_orange_stained_glass", BlockFactory::get(254, 1)); - self::register("hardened_orange_stained_glass_pane", BlockFactory::get(191, 1)); - self::register("hardened_pink_stained_glass", BlockFactory::get(254, 6)); - self::register("hardened_pink_stained_glass_pane", BlockFactory::get(191, 6)); - self::register("hardened_purple_stained_glass", BlockFactory::get(254, 10)); - self::register("hardened_purple_stained_glass_pane", BlockFactory::get(191, 10)); - self::register("hardened_red_stained_glass", BlockFactory::get(254, 14)); - self::register("hardened_red_stained_glass_pane", BlockFactory::get(191, 14)); - self::register("hardened_white_stained_glass", BlockFactory::get(254)); - self::register("hardened_white_stained_glass_pane", BlockFactory::get(191)); - self::register("hardened_yellow_stained_glass", BlockFactory::get(254, 4)); - self::register("hardened_yellow_stained_glass_pane", BlockFactory::get(191, 4)); - self::register("hay_bale", BlockFactory::get(170)); - self::register("hopper", BlockFactory::get(154)); - self::register("ice", BlockFactory::get(79)); - self::register("infested_chiseled_stone_brick", BlockFactory::get(97, 5)); - self::register("infested_cobblestone", BlockFactory::get(97, 1)); - self::register("infested_cracked_stone_brick", BlockFactory::get(97, 4)); - self::register("infested_mossy_stone_brick", BlockFactory::get(97, 3)); - self::register("infested_stone", BlockFactory::get(97)); - self::register("infested_stone_brick", BlockFactory::get(97, 2)); - self::register("info_update", BlockFactory::get(248)); - self::register("info_update2", BlockFactory::get(249)); - self::register("invisible_bedrock", BlockFactory::get(95)); - self::register("iron", BlockFactory::get(42)); - self::register("iron_bars", BlockFactory::get(101)); - self::register("iron_door", BlockFactory::get(71)); - self::register("iron_ore", BlockFactory::get(15)); - self::register("iron_trapdoor", BlockFactory::get(167)); - self::register("item_frame", BlockFactory::get(199)); - self::register("jungle_button", BlockFactory::get(398)); - self::register("jungle_door", BlockFactory::get(195)); - self::register("jungle_fence", BlockFactory::get(85, 3)); - self::register("jungle_fence_gate", BlockFactory::get(185)); - self::register("jungle_leaves", BlockFactory::get(18, 3)); - self::register("jungle_log", BlockFactory::get(17, 3)); - self::register("jungle_planks", BlockFactory::get(5, 3)); - self::register("jungle_pressure_plate", BlockFactory::get(408)); - self::register("jungle_sapling", BlockFactory::get(6, 3)); - self::register("jungle_sign", BlockFactory::get(443)); - self::register("jungle_slab", BlockFactory::get(158, 3)); - self::register("jungle_stairs", BlockFactory::get(136)); - self::register("jungle_trapdoor", BlockFactory::get(403)); - self::register("jungle_wood", BlockFactory::get(467, 3)); - self::register("ladder", BlockFactory::get(65, 2)); - self::register("lantern", BlockFactory::get(463)); - self::register("lapis_lazuli", BlockFactory::get(22)); - self::register("lapis_lazuli_ore", BlockFactory::get(21)); - self::register("large_fern", BlockFactory::get(175, 3)); - self::register("lava", BlockFactory::get(10)); - self::register("legacy_stonecutter", BlockFactory::get(245)); - self::register("lever", BlockFactory::get(69)); - self::register("light_blue_carpet", BlockFactory::get(171, 3)); - self::register("light_blue_concrete", BlockFactory::get(236, 3)); - self::register("light_blue_concrete_powder", BlockFactory::get(237, 3)); - self::register("light_blue_glazed_terracotta", BlockFactory::get(223, 2)); - self::register("light_blue_stained_clay", BlockFactory::get(159, 3)); - self::register("light_blue_stained_glass", BlockFactory::get(241, 3)); - self::register("light_blue_stained_glass_pane", BlockFactory::get(160, 3)); - self::register("light_blue_wool", BlockFactory::get(35, 3)); - self::register("light_gray_carpet", BlockFactory::get(171, 8)); - self::register("light_gray_concrete", BlockFactory::get(236, 8)); - self::register("light_gray_concrete_powder", BlockFactory::get(237, 8)); - self::register("light_gray_glazed_terracotta", BlockFactory::get(228, 2)); - self::register("light_gray_stained_clay", BlockFactory::get(159, 8)); - self::register("light_gray_stained_glass", BlockFactory::get(241, 8)); - self::register("light_gray_stained_glass_pane", BlockFactory::get(160, 8)); - self::register("light_gray_wool", BlockFactory::get(35, 8)); - self::register("lilac", BlockFactory::get(175, 1)); - self::register("lily_of_the_valley", BlockFactory::get(38, 10)); - self::register("lily_pad", BlockFactory::get(111)); - self::register("lime_carpet", BlockFactory::get(171, 5)); - self::register("lime_concrete", BlockFactory::get(236, 5)); - self::register("lime_concrete_powder", BlockFactory::get(237, 5)); - self::register("lime_glazed_terracotta", BlockFactory::get(225, 2)); - self::register("lime_stained_clay", BlockFactory::get(159, 5)); - self::register("lime_stained_glass", BlockFactory::get(241, 5)); - self::register("lime_stained_glass_pane", BlockFactory::get(160, 5)); - self::register("lime_wool", BlockFactory::get(35, 5)); - self::register("lit_pumpkin", BlockFactory::get(91)); - self::register("magenta_carpet", BlockFactory::get(171, 2)); - self::register("magenta_concrete", BlockFactory::get(236, 2)); - self::register("magenta_concrete_powder", BlockFactory::get(237, 2)); - self::register("magenta_glazed_terracotta", BlockFactory::get(222, 2)); - self::register("magenta_stained_clay", BlockFactory::get(159, 2)); - self::register("magenta_stained_glass", BlockFactory::get(241, 2)); - self::register("magenta_stained_glass_pane", BlockFactory::get(160, 2)); - self::register("magenta_wool", BlockFactory::get(35, 2)); - self::register("magma", BlockFactory::get(213)); - self::register("melon", BlockFactory::get(103)); - self::register("melon_stem", BlockFactory::get(105)); - self::register("mob_head", BlockFactory::get(144, 2)); - self::register("monster_spawner", BlockFactory::get(52)); - self::register("mossy_cobblestone", BlockFactory::get(48)); - self::register("mossy_cobblestone_slab", BlockFactory::get(182, 5)); - self::register("mossy_cobblestone_stairs", BlockFactory::get(434)); - self::register("mossy_cobblestone_wall", BlockFactory::get(139, 1)); - self::register("mossy_stone_brick_slab", BlockFactory::get(421)); - self::register("mossy_stone_brick_stairs", BlockFactory::get(430)); - self::register("mossy_stone_brick_wall", BlockFactory::get(139, 8)); - self::register("mossy_stone_bricks", BlockFactory::get(98, 1)); - self::register("mycelium", BlockFactory::get(110)); - self::register("nether_brick_fence", BlockFactory::get(113)); - self::register("nether_brick_slab", BlockFactory::get(44, 7)); - self::register("nether_brick_stairs", BlockFactory::get(114)); - self::register("nether_brick_wall", BlockFactory::get(139, 9)); - self::register("nether_bricks", BlockFactory::get(112)); - self::register("nether_portal", BlockFactory::get(90, 1)); - self::register("nether_quartz_ore", BlockFactory::get(153)); - self::register("nether_reactor_core", BlockFactory::get(247)); - self::register("nether_wart", BlockFactory::get(115)); - self::register("nether_wart_block", BlockFactory::get(214)); - self::register("netherrack", BlockFactory::get(87)); - self::register("note_block", BlockFactory::get(25)); - self::register("oak_button", BlockFactory::get(143)); - self::register("oak_door", BlockFactory::get(64)); - self::register("oak_fence", BlockFactory::get(85)); - self::register("oak_fence_gate", BlockFactory::get(107)); - self::register("oak_leaves", BlockFactory::get(18)); - self::register("oak_log", BlockFactory::get(17)); - self::register("oak_planks", BlockFactory::get(5)); - self::register("oak_pressure_plate", BlockFactory::get(72)); - self::register("oak_sapling", BlockFactory::get(6)); - self::register("oak_sign", BlockFactory::get(63)); - self::register("oak_slab", BlockFactory::get(158)); - self::register("oak_stairs", BlockFactory::get(53)); - self::register("oak_trapdoor", BlockFactory::get(96)); - self::register("oak_wood", BlockFactory::get(467)); - self::register("obsidian", BlockFactory::get(49)); - self::register("orange_carpet", BlockFactory::get(171, 1)); - self::register("orange_concrete", BlockFactory::get(236, 1)); - self::register("orange_concrete_powder", BlockFactory::get(237, 1)); - self::register("orange_glazed_terracotta", BlockFactory::get(221, 2)); - self::register("orange_stained_clay", BlockFactory::get(159, 1)); - self::register("orange_stained_glass", BlockFactory::get(241, 1)); - self::register("orange_stained_glass_pane", BlockFactory::get(160, 1)); - self::register("orange_tulip", BlockFactory::get(38, 5)); - self::register("orange_wool", BlockFactory::get(35, 1)); - self::register("oxeye_daisy", BlockFactory::get(38, 8)); - self::register("packed_ice", BlockFactory::get(174)); - self::register("peony", BlockFactory::get(175, 5)); - self::register("pink_carpet", BlockFactory::get(171, 6)); - self::register("pink_concrete", BlockFactory::get(236, 6)); - self::register("pink_concrete_powder", BlockFactory::get(237, 6)); - self::register("pink_glazed_terracotta", BlockFactory::get(226, 2)); - self::register("pink_stained_clay", BlockFactory::get(159, 6)); - self::register("pink_stained_glass", BlockFactory::get(241, 6)); - self::register("pink_stained_glass_pane", BlockFactory::get(160, 6)); - self::register("pink_tulip", BlockFactory::get(38, 7)); - self::register("pink_wool", BlockFactory::get(35, 6)); - self::register("podzol", BlockFactory::get(243)); - self::register("polished_andesite", BlockFactory::get(1, 6)); - self::register("polished_andesite_slab", BlockFactory::get(417, 2)); - self::register("polished_andesite_stairs", BlockFactory::get(429)); - self::register("polished_diorite", BlockFactory::get(1, 4)); - self::register("polished_diorite_slab", BlockFactory::get(417, 5)); - self::register("polished_diorite_stairs", BlockFactory::get(428)); - self::register("polished_granite", BlockFactory::get(1, 2)); - self::register("polished_granite_slab", BlockFactory::get(417, 7)); - self::register("polished_granite_stairs", BlockFactory::get(427)); - self::register("poppy", BlockFactory::get(38)); - self::register("potatoes", BlockFactory::get(142)); - self::register("powered_rail", BlockFactory::get(27)); - self::register("prismarine", BlockFactory::get(168)); - self::register("prismarine_bricks", BlockFactory::get(168, 2)); - self::register("prismarine_bricks_slab", BlockFactory::get(182, 4)); - self::register("prismarine_bricks_stairs", BlockFactory::get(259)); - self::register("prismarine_slab", BlockFactory::get(182, 2)); - self::register("prismarine_stairs", BlockFactory::get(257)); - self::register("prismarine_wall", BlockFactory::get(139, 11)); - self::register("pumpkin", BlockFactory::get(86)); - self::register("pumpkin_stem", BlockFactory::get(104)); - self::register("purple_carpet", BlockFactory::get(171, 10)); - self::register("purple_concrete", BlockFactory::get(236, 10)); - self::register("purple_concrete_powder", BlockFactory::get(237, 10)); - self::register("purple_glazed_terracotta", BlockFactory::get(219, 2)); - self::register("purple_stained_clay", BlockFactory::get(159, 10)); - self::register("purple_stained_glass", BlockFactory::get(241, 10)); - self::register("purple_stained_glass_pane", BlockFactory::get(160, 10)); - self::register("purple_torch", BlockFactory::get(204, 13)); - self::register("purple_wool", BlockFactory::get(35, 10)); - self::register("purpur", BlockFactory::get(201)); - self::register("purpur_pillar", BlockFactory::get(201, 2)); - self::register("purpur_slab", BlockFactory::get(182, 1)); - self::register("purpur_stairs", BlockFactory::get(203)); - self::register("quartz", BlockFactory::get(155)); - self::register("quartz_pillar", BlockFactory::get(155, 2)); - self::register("quartz_slab", BlockFactory::get(44, 6)); - self::register("quartz_stairs", BlockFactory::get(156)); - self::register("rail", BlockFactory::get(66)); - self::register("red_carpet", BlockFactory::get(171, 14)); - self::register("red_concrete", BlockFactory::get(236, 14)); - self::register("red_concrete_powder", BlockFactory::get(237, 14)); - self::register("red_glazed_terracotta", BlockFactory::get(234, 2)); - self::register("red_mushroom", BlockFactory::get(40)); - self::register("red_mushroom_block", BlockFactory::get(100)); - self::register("red_nether_brick_slab", BlockFactory::get(182, 7)); - self::register("red_nether_brick_stairs", BlockFactory::get(439)); - self::register("red_nether_brick_wall", BlockFactory::get(139, 13)); - self::register("red_nether_bricks", BlockFactory::get(215)); - self::register("red_sand", BlockFactory::get(12, 1)); - self::register("red_sandstone", BlockFactory::get(179)); - self::register("red_sandstone_slab", BlockFactory::get(182)); - self::register("red_sandstone_stairs", BlockFactory::get(180)); - self::register("red_sandstone_wall", BlockFactory::get(139, 12)); - self::register("red_stained_clay", BlockFactory::get(159, 14)); - self::register("red_stained_glass", BlockFactory::get(241, 14)); - self::register("red_stained_glass_pane", BlockFactory::get(160, 14)); - self::register("red_torch", BlockFactory::get(202, 5)); - self::register("red_tulip", BlockFactory::get(38, 4)); - self::register("red_wool", BlockFactory::get(35, 14)); - self::register("redstone", BlockFactory::get(152)); - self::register("redstone_comparator", BlockFactory::get(149)); - self::register("redstone_lamp", BlockFactory::get(123)); - self::register("redstone_ore", BlockFactory::get(73)); - self::register("redstone_repeater", BlockFactory::get(93)); - self::register("redstone_torch", BlockFactory::get(76, 5)); - self::register("redstone_wire", BlockFactory::get(55)); - self::register("reserved6", BlockFactory::get(255)); - self::register("rose_bush", BlockFactory::get(175, 4)); - self::register("sand", BlockFactory::get(12)); - self::register("sandstone", BlockFactory::get(24)); - self::register("sandstone_slab", BlockFactory::get(44, 1)); - self::register("sandstone_stairs", BlockFactory::get(128)); - self::register("sandstone_wall", BlockFactory::get(139, 5)); - self::register("sea_lantern", BlockFactory::get(169)); - self::register("sea_pickle", BlockFactory::get(411)); - self::register("slightly_damaged_anvil", BlockFactory::get(145, 4)); - self::register("smooth_quartz", BlockFactory::get(155, 3)); - self::register("smooth_quartz_slab", BlockFactory::get(421, 1)); - self::register("smooth_quartz_stairs", BlockFactory::get(440)); - self::register("smooth_red_sandstone", BlockFactory::get(179, 3)); - self::register("smooth_red_sandstone_slab", BlockFactory::get(417, 1)); - self::register("smooth_red_sandstone_stairs", BlockFactory::get(431)); - self::register("smooth_sandstone", BlockFactory::get(24, 3)); - self::register("smooth_sandstone_slab", BlockFactory::get(182, 6)); - self::register("smooth_sandstone_stairs", BlockFactory::get(432)); - self::register("smooth_stone", BlockFactory::get(438)); - self::register("smooth_stone_slab", BlockFactory::get(44)); - self::register("snow", BlockFactory::get(80)); - self::register("snow_layer", BlockFactory::get(78)); - self::register("soul_sand", BlockFactory::get(88)); - self::register("sponge", BlockFactory::get(19)); - self::register("spruce_button", BlockFactory::get(399)); - self::register("spruce_door", BlockFactory::get(193)); - self::register("spruce_fence", BlockFactory::get(85, 1)); - self::register("spruce_fence_gate", BlockFactory::get(183)); - self::register("spruce_leaves", BlockFactory::get(18, 1)); - self::register("spruce_log", BlockFactory::get(17, 1)); - self::register("spruce_planks", BlockFactory::get(5, 1)); - self::register("spruce_pressure_plate", BlockFactory::get(409)); - self::register("spruce_sapling", BlockFactory::get(6, 1)); - self::register("spruce_sign", BlockFactory::get(436)); - self::register("spruce_slab", BlockFactory::get(158, 1)); - self::register("spruce_stairs", BlockFactory::get(134)); - self::register("spruce_trapdoor", BlockFactory::get(404)); - self::register("spruce_wood", BlockFactory::get(467, 1)); - self::register("stone", BlockFactory::get(1)); - self::register("stone_brick_slab", BlockFactory::get(44, 5)); - self::register("stone_brick_stairs", BlockFactory::get(109)); - self::register("stone_brick_wall", BlockFactory::get(139, 7)); - self::register("stone_bricks", BlockFactory::get(98)); - self::register("stone_button", BlockFactory::get(77)); - self::register("stone_pressure_plate", BlockFactory::get(70)); - self::register("stone_slab", BlockFactory::get(421, 2)); - self::register("stone_stairs", BlockFactory::get(435)); - self::register("sugarcane", BlockFactory::get(83)); - self::register("sunflower", BlockFactory::get(175)); - self::register("tall_grass", BlockFactory::get(31, 1)); - self::register("tnt", BlockFactory::get(46)); - self::register("torch", BlockFactory::get(50, 5)); - self::register("trapped_chest", BlockFactory::get(146, 2)); - self::register("tripwire", BlockFactory::get(132)); - self::register("tripwire_hook", BlockFactory::get(131)); - self::register("underwater_torch", BlockFactory::get(239, 5)); - self::register("very_damaged_anvil", BlockFactory::get(145, 8)); - self::register("vines", BlockFactory::get(106)); - self::register("water", BlockFactory::get(8)); - self::register("weighted_pressure_plate_heavy", BlockFactory::get(148)); - self::register("weighted_pressure_plate_light", BlockFactory::get(147)); - self::register("wheat", BlockFactory::get(59)); - self::register("white_carpet", BlockFactory::get(171)); - self::register("white_concrete", BlockFactory::get(236)); - self::register("white_concrete_powder", BlockFactory::get(237)); - self::register("white_glazed_terracotta", BlockFactory::get(220, 2)); - self::register("white_stained_clay", BlockFactory::get(159)); - self::register("white_stained_glass", BlockFactory::get(241)); - self::register("white_stained_glass_pane", BlockFactory::get(160)); - self::register("white_tulip", BlockFactory::get(38, 6)); - self::register("white_wool", BlockFactory::get(35)); - self::register("yellow_carpet", BlockFactory::get(171, 4)); - self::register("yellow_concrete", BlockFactory::get(236, 4)); - self::register("yellow_concrete_powder", BlockFactory::get(237, 4)); - self::register("yellow_glazed_terracotta", BlockFactory::get(224, 2)); - self::register("yellow_stained_clay", BlockFactory::get(159, 4)); - self::register("yellow_stained_glass", BlockFactory::get(241, 4)); - self::register("yellow_stained_glass_pane", BlockFactory::get(160, 4)); - self::register("yellow_wool", BlockFactory::get(35, 4)); + $factory = BlockFactory::getInstance(); + self::register("acacia_button", $factory->get(395)); + self::register("acacia_door", $factory->get(196)); + self::register("acacia_fence", $factory->get(85, 4)); + self::register("acacia_fence_gate", $factory->get(187)); + self::register("acacia_leaves", $factory->get(161)); + self::register("acacia_log", $factory->get(162)); + self::register("acacia_planks", $factory->get(5, 4)); + self::register("acacia_pressure_plate", $factory->get(405)); + self::register("acacia_sapling", $factory->get(6, 4)); + self::register("acacia_sign", $factory->get(445)); + self::register("acacia_slab", $factory->get(158, 4)); + self::register("acacia_stairs", $factory->get(163)); + self::register("acacia_trapdoor", $factory->get(400)); + self::register("acacia_wood", $factory->get(467, 4)); + self::register("activator_rail", $factory->get(126)); + self::register("air", $factory->get(0)); + self::register("allium", $factory->get(38, 2)); + self::register("andesite", $factory->get(1, 5)); + self::register("andesite_slab", $factory->get(417, 3)); + self::register("andesite_stairs", $factory->get(426)); + self::register("andesite_wall", $factory->get(139, 4)); + self::register("anvil", $factory->get(145)); + self::register("azure_bluet", $factory->get(38, 3)); + self::register("banner", $factory->get(176)); + self::register("barrier", $factory->get(416)); + self::register("bed", $factory->get(26)); + self::register("bedrock", $factory->get(7)); + self::register("beetroots", $factory->get(244)); + self::register("birch_button", $factory->get(396)); + self::register("birch_door", $factory->get(194)); + self::register("birch_fence", $factory->get(85, 2)); + self::register("birch_fence_gate", $factory->get(184)); + self::register("birch_leaves", $factory->get(18, 2)); + self::register("birch_log", $factory->get(17, 2)); + self::register("birch_planks", $factory->get(5, 2)); + self::register("birch_pressure_plate", $factory->get(406)); + self::register("birch_sapling", $factory->get(6, 2)); + self::register("birch_sign", $factory->get(441)); + self::register("birch_slab", $factory->get(158, 2)); + self::register("birch_stairs", $factory->get(135)); + self::register("birch_trapdoor", $factory->get(401)); + self::register("birch_wood", $factory->get(467, 2)); + self::register("black_carpet", $factory->get(171, 15)); + self::register("black_concrete", $factory->get(236, 15)); + self::register("black_concrete_powder", $factory->get(237, 15)); + self::register("black_glazed_terracotta", $factory->get(235, 2)); + self::register("black_stained_clay", $factory->get(159, 15)); + self::register("black_stained_glass", $factory->get(241, 15)); + self::register("black_stained_glass_pane", $factory->get(160, 15)); + self::register("black_wool", $factory->get(35, 15)); + self::register("blue_carpet", $factory->get(171, 11)); + self::register("blue_concrete", $factory->get(236, 11)); + self::register("blue_concrete_powder", $factory->get(237, 11)); + self::register("blue_glazed_terracotta", $factory->get(231, 2)); + self::register("blue_ice", $factory->get(266)); + self::register("blue_orchid", $factory->get(38, 1)); + self::register("blue_stained_clay", $factory->get(159, 11)); + self::register("blue_stained_glass", $factory->get(241, 11)); + self::register("blue_stained_glass_pane", $factory->get(160, 11)); + self::register("blue_torch", $factory->get(204, 5)); + self::register("blue_wool", $factory->get(35, 11)); + self::register("bone_block", $factory->get(216)); + self::register("bookshelf", $factory->get(47)); + self::register("brewing_stand", $factory->get(117)); + self::register("brick_slab", $factory->get(44, 4)); + self::register("brick_stairs", $factory->get(108)); + self::register("brick_wall", $factory->get(139, 6)); + self::register("bricks", $factory->get(45)); + self::register("brown_carpet", $factory->get(171, 12)); + self::register("brown_concrete", $factory->get(236, 12)); + self::register("brown_concrete_powder", $factory->get(237, 12)); + self::register("brown_glazed_terracotta", $factory->get(232, 2)); + self::register("brown_mushroom", $factory->get(39)); + self::register("brown_mushroom_block", $factory->get(99)); + self::register("brown_stained_clay", $factory->get(159, 12)); + self::register("brown_stained_glass", $factory->get(241, 12)); + self::register("brown_stained_glass_pane", $factory->get(160, 12)); + self::register("brown_wool", $factory->get(35, 12)); + self::register("cactus", $factory->get(81)); + self::register("cake", $factory->get(92)); + self::register("carrots", $factory->get(141)); + self::register("carved_pumpkin", $factory->get(410)); + self::register("chest", $factory->get(54, 2)); + self::register("chiseled_quartz", $factory->get(155, 1)); + self::register("chiseled_red_sandstone", $factory->get(179, 1)); + self::register("chiseled_sandstone", $factory->get(24, 1)); + self::register("chiseled_stone_bricks", $factory->get(98, 3)); + self::register("clay", $factory->get(82)); + self::register("coal", $factory->get(173)); + self::register("coal_ore", $factory->get(16)); + self::register("coarse_dirt", $factory->get(3, 1)); + self::register("cobblestone", $factory->get(4)); + self::register("cobblestone_slab", $factory->get(44, 3)); + self::register("cobblestone_stairs", $factory->get(67)); + self::register("cobblestone_wall", $factory->get(139)); + self::register("cobweb", $factory->get(30)); + self::register("cocoa_pod", $factory->get(127)); + self::register("cornflower", $factory->get(38, 9)); + self::register("cracked_stone_bricks", $factory->get(98, 2)); + self::register("crafting_table", $factory->get(58)); + self::register("cut_red_sandstone", $factory->get(179, 2)); + self::register("cut_red_sandstone_slab", $factory->get(421, 4)); + self::register("cut_sandstone", $factory->get(24, 2)); + self::register("cut_sandstone_slab", $factory->get(421, 3)); + self::register("cyan_carpet", $factory->get(171, 9)); + self::register("cyan_concrete", $factory->get(236, 9)); + self::register("cyan_concrete_powder", $factory->get(237, 9)); + self::register("cyan_glazed_terracotta", $factory->get(229, 2)); + self::register("cyan_stained_clay", $factory->get(159, 9)); + self::register("cyan_stained_glass", $factory->get(241, 9)); + self::register("cyan_stained_glass_pane", $factory->get(160, 9)); + self::register("cyan_wool", $factory->get(35, 9)); + self::register("dandelion", $factory->get(37)); + self::register("dark_oak_button", $factory->get(397)); + self::register("dark_oak_door", $factory->get(197)); + self::register("dark_oak_fence", $factory->get(85, 5)); + self::register("dark_oak_fence_gate", $factory->get(186)); + self::register("dark_oak_leaves", $factory->get(161, 1)); + self::register("dark_oak_log", $factory->get(162, 1)); + self::register("dark_oak_planks", $factory->get(5, 5)); + self::register("dark_oak_pressure_plate", $factory->get(407)); + self::register("dark_oak_sapling", $factory->get(6, 5)); + self::register("dark_oak_sign", $factory->get(447)); + self::register("dark_oak_slab", $factory->get(158, 5)); + self::register("dark_oak_stairs", $factory->get(164)); + self::register("dark_oak_trapdoor", $factory->get(402)); + self::register("dark_oak_wood", $factory->get(467, 5)); + self::register("dark_prismarine", $factory->get(168, 1)); + self::register("dark_prismarine_slab", $factory->get(182, 3)); + self::register("dark_prismarine_stairs", $factory->get(258)); + self::register("daylight_sensor", $factory->get(151)); + self::register("dead_bush", $factory->get(32)); + self::register("detector_rail", $factory->get(28)); + self::register("diamond", $factory->get(57)); + self::register("diamond_ore", $factory->get(56)); + self::register("diorite", $factory->get(1, 3)); + self::register("diorite_slab", $factory->get(417, 4)); + self::register("diorite_stairs", $factory->get(425)); + self::register("diorite_wall", $factory->get(139, 3)); + self::register("dirt", $factory->get(3)); + self::register("double_tallgrass", $factory->get(175, 2)); + self::register("dragon_egg", $factory->get(122)); + self::register("dried_kelp", $factory->get(394)); + self::register("element_actinium", $factory->get(355)); + self::register("element_aluminum", $factory->get(279)); + self::register("element_americium", $factory->get(361)); + self::register("element_antimony", $factory->get(317)); + self::register("element_argon", $factory->get(284)); + self::register("element_arsenic", $factory->get(299)); + self::register("element_astatine", $factory->get(351)); + self::register("element_barium", $factory->get(322)); + self::register("element_berkelium", $factory->get(363)); + self::register("element_beryllium", $factory->get(270)); + self::register("element_bismuth", $factory->get(349)); + self::register("element_bohrium", $factory->get(373)); + self::register("element_boron", $factory->get(271)); + self::register("element_bromine", $factory->get(301)); + self::register("element_cadmium", $factory->get(314)); + self::register("element_calcium", $factory->get(286)); + self::register("element_californium", $factory->get(364)); + self::register("element_carbon", $factory->get(272)); + self::register("element_cerium", $factory->get(324)); + self::register("element_cesium", $factory->get(321)); + self::register("element_chlorine", $factory->get(283)); + self::register("element_chromium", $factory->get(290)); + self::register("element_cobalt", $factory->get(293)); + self::register("element_copernicium", $factory->get(378)); + self::register("element_copper", $factory->get(295)); + self::register("element_curium", $factory->get(362)); + self::register("element_darmstadtium", $factory->get(376)); + self::register("element_dubnium", $factory->get(371)); + self::register("element_dysprosium", $factory->get(332)); + self::register("element_einsteinium", $factory->get(365)); + self::register("element_erbium", $factory->get(334)); + self::register("element_europium", $factory->get(329)); + self::register("element_fermium", $factory->get(366)); + self::register("element_flerovium", $factory->get(380)); + self::register("element_fluorine", $factory->get(275)); + self::register("element_francium", $factory->get(353)); + self::register("element_gadolinium", $factory->get(330)); + self::register("element_gallium", $factory->get(297)); + self::register("element_germanium", $factory->get(298)); + self::register("element_gold", $factory->get(345)); + self::register("element_hafnium", $factory->get(338)); + self::register("element_hassium", $factory->get(374)); + self::register("element_helium", $factory->get(268)); + self::register("element_holmium", $factory->get(333)); + self::register("element_hydrogen", $factory->get(267)); + self::register("element_indium", $factory->get(315)); + self::register("element_iodine", $factory->get(319)); + self::register("element_iridium", $factory->get(343)); + self::register("element_iron", $factory->get(292)); + self::register("element_krypton", $factory->get(302)); + self::register("element_lanthanum", $factory->get(323)); + self::register("element_lawrencium", $factory->get(369)); + self::register("element_lead", $factory->get(348)); + self::register("element_lithium", $factory->get(269)); + self::register("element_livermorium", $factory->get(382)); + self::register("element_lutetium", $factory->get(337)); + self::register("element_magnesium", $factory->get(278)); + self::register("element_manganese", $factory->get(291)); + self::register("element_meitnerium", $factory->get(375)); + self::register("element_mendelevium", $factory->get(367)); + self::register("element_mercury", $factory->get(346)); + self::register("element_molybdenum", $factory->get(308)); + self::register("element_moscovium", $factory->get(381)); + self::register("element_neodymium", $factory->get(326)); + self::register("element_neon", $factory->get(276)); + self::register("element_neptunium", $factory->get(359)); + self::register("element_nickel", $factory->get(294)); + self::register("element_nihonium", $factory->get(379)); + self::register("element_niobium", $factory->get(307)); + self::register("element_nitrogen", $factory->get(273)); + self::register("element_nobelium", $factory->get(368)); + self::register("element_oganesson", $factory->get(384)); + self::register("element_osmium", $factory->get(342)); + self::register("element_oxygen", $factory->get(274)); + self::register("element_palladium", $factory->get(312)); + self::register("element_phosphorus", $factory->get(281)); + self::register("element_platinum", $factory->get(344)); + self::register("element_plutonium", $factory->get(360)); + self::register("element_polonium", $factory->get(350)); + self::register("element_potassium", $factory->get(285)); + self::register("element_praseodymium", $factory->get(325)); + self::register("element_promethium", $factory->get(327)); + self::register("element_protactinium", $factory->get(357)); + self::register("element_radium", $factory->get(354)); + self::register("element_radon", $factory->get(352)); + self::register("element_rhenium", $factory->get(341)); + self::register("element_rhodium", $factory->get(311)); + self::register("element_roentgenium", $factory->get(377)); + self::register("element_rubidium", $factory->get(303)); + self::register("element_ruthenium", $factory->get(310)); + self::register("element_rutherfordium", $factory->get(370)); + self::register("element_samarium", $factory->get(328)); + self::register("element_scandium", $factory->get(287)); + self::register("element_seaborgium", $factory->get(372)); + self::register("element_selenium", $factory->get(300)); + self::register("element_silicon", $factory->get(280)); + self::register("element_silver", $factory->get(313)); + self::register("element_sodium", $factory->get(277)); + self::register("element_strontium", $factory->get(304)); + self::register("element_sulfur", $factory->get(282)); + self::register("element_tantalum", $factory->get(339)); + self::register("element_technetium", $factory->get(309)); + self::register("element_tellurium", $factory->get(318)); + self::register("element_tennessine", $factory->get(383)); + self::register("element_terbium", $factory->get(331)); + self::register("element_thallium", $factory->get(347)); + self::register("element_thorium", $factory->get(356)); + self::register("element_thulium", $factory->get(335)); + self::register("element_tin", $factory->get(316)); + self::register("element_titanium", $factory->get(288)); + self::register("element_tungsten", $factory->get(340)); + self::register("element_uranium", $factory->get(358)); + self::register("element_vanadium", $factory->get(289)); + self::register("element_xenon", $factory->get(320)); + self::register("element_ytterbium", $factory->get(336)); + self::register("element_yttrium", $factory->get(305)); + self::register("element_zero", $factory->get(36)); + self::register("element_zinc", $factory->get(296)); + self::register("element_zirconium", $factory->get(306)); + self::register("emerald", $factory->get(133)); + self::register("emerald_ore", $factory->get(129)); + self::register("enchanting_table", $factory->get(116)); + self::register("end_portal_frame", $factory->get(120)); + self::register("end_rod", $factory->get(208)); + self::register("end_stone", $factory->get(121)); + self::register("end_stone_brick_slab", $factory->get(417)); + self::register("end_stone_brick_stairs", $factory->get(433)); + self::register("end_stone_brick_wall", $factory->get(139, 10)); + self::register("end_stone_bricks", $factory->get(206)); + self::register("ender_chest", $factory->get(130, 2)); + self::register("fake_wooden_slab", $factory->get(44, 2)); + self::register("farmland", $factory->get(60)); + self::register("fern", $factory->get(31, 2)); + self::register("fire", $factory->get(51)); + self::register("flower_pot", $factory->get(140)); + self::register("frosted_ice", $factory->get(207)); + self::register("furnace", $factory->get(61, 2)); + self::register("glass", $factory->get(20)); + self::register("glass_pane", $factory->get(102)); + self::register("glowing_obsidian", $factory->get(246)); + self::register("glowstone", $factory->get(89)); + self::register("gold", $factory->get(41)); + self::register("gold_ore", $factory->get(14)); + self::register("granite", $factory->get(1, 1)); + self::register("granite_slab", $factory->get(417, 6)); + self::register("granite_stairs", $factory->get(424)); + self::register("granite_wall", $factory->get(139, 2)); + self::register("grass", $factory->get(2)); + self::register("grass_path", $factory->get(198)); + self::register("gravel", $factory->get(13)); + self::register("gray_carpet", $factory->get(171, 7)); + self::register("gray_concrete", $factory->get(236, 7)); + self::register("gray_concrete_powder", $factory->get(237, 7)); + self::register("gray_glazed_terracotta", $factory->get(227, 2)); + self::register("gray_stained_clay", $factory->get(159, 7)); + self::register("gray_stained_glass", $factory->get(241, 7)); + self::register("gray_stained_glass_pane", $factory->get(160, 7)); + self::register("gray_wool", $factory->get(35, 7)); + self::register("green_carpet", $factory->get(171, 13)); + self::register("green_concrete", $factory->get(236, 13)); + self::register("green_concrete_powder", $factory->get(237, 13)); + self::register("green_glazed_terracotta", $factory->get(233, 2)); + self::register("green_stained_clay", $factory->get(159, 13)); + self::register("green_stained_glass", $factory->get(241, 13)); + self::register("green_stained_glass_pane", $factory->get(160, 13)); + self::register("green_torch", $factory->get(202, 13)); + self::register("green_wool", $factory->get(35, 13)); + self::register("hardened_black_stained_glass", $factory->get(254, 15)); + self::register("hardened_black_stained_glass_pane", $factory->get(191, 15)); + self::register("hardened_blue_stained_glass", $factory->get(254, 11)); + self::register("hardened_blue_stained_glass_pane", $factory->get(191, 11)); + self::register("hardened_brown_stained_glass", $factory->get(254, 12)); + self::register("hardened_brown_stained_glass_pane", $factory->get(191, 12)); + self::register("hardened_clay", $factory->get(172)); + self::register("hardened_cyan_stained_glass", $factory->get(254, 9)); + self::register("hardened_cyan_stained_glass_pane", $factory->get(191, 9)); + self::register("hardened_glass", $factory->get(253)); + self::register("hardened_glass_pane", $factory->get(190)); + self::register("hardened_gray_stained_glass", $factory->get(254, 7)); + self::register("hardened_gray_stained_glass_pane", $factory->get(191, 7)); + self::register("hardened_green_stained_glass", $factory->get(254, 13)); + self::register("hardened_green_stained_glass_pane", $factory->get(191, 13)); + self::register("hardened_light_blue_stained_glass", $factory->get(254, 3)); + self::register("hardened_light_blue_stained_glass_pane", $factory->get(191, 3)); + self::register("hardened_light_gray_stained_glass", $factory->get(254, 8)); + self::register("hardened_light_gray_stained_glass_pane", $factory->get(191, 8)); + self::register("hardened_lime_stained_glass", $factory->get(254, 5)); + self::register("hardened_lime_stained_glass_pane", $factory->get(191, 5)); + self::register("hardened_magenta_stained_glass", $factory->get(254, 2)); + self::register("hardened_magenta_stained_glass_pane", $factory->get(191, 2)); + self::register("hardened_orange_stained_glass", $factory->get(254, 1)); + self::register("hardened_orange_stained_glass_pane", $factory->get(191, 1)); + self::register("hardened_pink_stained_glass", $factory->get(254, 6)); + self::register("hardened_pink_stained_glass_pane", $factory->get(191, 6)); + self::register("hardened_purple_stained_glass", $factory->get(254, 10)); + self::register("hardened_purple_stained_glass_pane", $factory->get(191, 10)); + self::register("hardened_red_stained_glass", $factory->get(254, 14)); + self::register("hardened_red_stained_glass_pane", $factory->get(191, 14)); + self::register("hardened_white_stained_glass", $factory->get(254)); + self::register("hardened_white_stained_glass_pane", $factory->get(191)); + self::register("hardened_yellow_stained_glass", $factory->get(254, 4)); + self::register("hardened_yellow_stained_glass_pane", $factory->get(191, 4)); + self::register("hay_bale", $factory->get(170)); + self::register("hopper", $factory->get(154)); + self::register("ice", $factory->get(79)); + self::register("infested_chiseled_stone_brick", $factory->get(97, 5)); + self::register("infested_cobblestone", $factory->get(97, 1)); + self::register("infested_cracked_stone_brick", $factory->get(97, 4)); + self::register("infested_mossy_stone_brick", $factory->get(97, 3)); + self::register("infested_stone", $factory->get(97)); + self::register("infested_stone_brick", $factory->get(97, 2)); + self::register("info_update", $factory->get(248)); + self::register("info_update2", $factory->get(249)); + self::register("invisible_bedrock", $factory->get(95)); + self::register("iron", $factory->get(42)); + self::register("iron_bars", $factory->get(101)); + self::register("iron_door", $factory->get(71)); + self::register("iron_ore", $factory->get(15)); + self::register("iron_trapdoor", $factory->get(167)); + self::register("item_frame", $factory->get(199)); + self::register("jungle_button", $factory->get(398)); + self::register("jungle_door", $factory->get(195)); + self::register("jungle_fence", $factory->get(85, 3)); + self::register("jungle_fence_gate", $factory->get(185)); + self::register("jungle_leaves", $factory->get(18, 3)); + self::register("jungle_log", $factory->get(17, 3)); + self::register("jungle_planks", $factory->get(5, 3)); + self::register("jungle_pressure_plate", $factory->get(408)); + self::register("jungle_sapling", $factory->get(6, 3)); + self::register("jungle_sign", $factory->get(443)); + self::register("jungle_slab", $factory->get(158, 3)); + self::register("jungle_stairs", $factory->get(136)); + self::register("jungle_trapdoor", $factory->get(403)); + self::register("jungle_wood", $factory->get(467, 3)); + self::register("ladder", $factory->get(65, 2)); + self::register("lantern", $factory->get(463)); + self::register("lapis_lazuli", $factory->get(22)); + self::register("lapis_lazuli_ore", $factory->get(21)); + self::register("large_fern", $factory->get(175, 3)); + self::register("lava", $factory->get(10)); + self::register("legacy_stonecutter", $factory->get(245)); + self::register("lever", $factory->get(69)); + self::register("light_blue_carpet", $factory->get(171, 3)); + self::register("light_blue_concrete", $factory->get(236, 3)); + self::register("light_blue_concrete_powder", $factory->get(237, 3)); + self::register("light_blue_glazed_terracotta", $factory->get(223, 2)); + self::register("light_blue_stained_clay", $factory->get(159, 3)); + self::register("light_blue_stained_glass", $factory->get(241, 3)); + self::register("light_blue_stained_glass_pane", $factory->get(160, 3)); + self::register("light_blue_wool", $factory->get(35, 3)); + self::register("light_gray_carpet", $factory->get(171, 8)); + self::register("light_gray_concrete", $factory->get(236, 8)); + self::register("light_gray_concrete_powder", $factory->get(237, 8)); + self::register("light_gray_glazed_terracotta", $factory->get(228, 2)); + self::register("light_gray_stained_clay", $factory->get(159, 8)); + self::register("light_gray_stained_glass", $factory->get(241, 8)); + self::register("light_gray_stained_glass_pane", $factory->get(160, 8)); + self::register("light_gray_wool", $factory->get(35, 8)); + self::register("lilac", $factory->get(175, 1)); + self::register("lily_of_the_valley", $factory->get(38, 10)); + self::register("lily_pad", $factory->get(111)); + self::register("lime_carpet", $factory->get(171, 5)); + self::register("lime_concrete", $factory->get(236, 5)); + self::register("lime_concrete_powder", $factory->get(237, 5)); + self::register("lime_glazed_terracotta", $factory->get(225, 2)); + self::register("lime_stained_clay", $factory->get(159, 5)); + self::register("lime_stained_glass", $factory->get(241, 5)); + self::register("lime_stained_glass_pane", $factory->get(160, 5)); + self::register("lime_wool", $factory->get(35, 5)); + self::register("lit_pumpkin", $factory->get(91)); + self::register("magenta_carpet", $factory->get(171, 2)); + self::register("magenta_concrete", $factory->get(236, 2)); + self::register("magenta_concrete_powder", $factory->get(237, 2)); + self::register("magenta_glazed_terracotta", $factory->get(222, 2)); + self::register("magenta_stained_clay", $factory->get(159, 2)); + self::register("magenta_stained_glass", $factory->get(241, 2)); + self::register("magenta_stained_glass_pane", $factory->get(160, 2)); + self::register("magenta_wool", $factory->get(35, 2)); + self::register("magma", $factory->get(213)); + self::register("melon", $factory->get(103)); + self::register("melon_stem", $factory->get(105)); + self::register("mob_head", $factory->get(144, 2)); + self::register("monster_spawner", $factory->get(52)); + self::register("mossy_cobblestone", $factory->get(48)); + self::register("mossy_cobblestone_slab", $factory->get(182, 5)); + self::register("mossy_cobblestone_stairs", $factory->get(434)); + self::register("mossy_cobblestone_wall", $factory->get(139, 1)); + self::register("mossy_stone_brick_slab", $factory->get(421)); + self::register("mossy_stone_brick_stairs", $factory->get(430)); + self::register("mossy_stone_brick_wall", $factory->get(139, 8)); + self::register("mossy_stone_bricks", $factory->get(98, 1)); + self::register("mycelium", $factory->get(110)); + self::register("nether_brick_fence", $factory->get(113)); + self::register("nether_brick_slab", $factory->get(44, 7)); + self::register("nether_brick_stairs", $factory->get(114)); + self::register("nether_brick_wall", $factory->get(139, 9)); + self::register("nether_bricks", $factory->get(112)); + self::register("nether_portal", $factory->get(90, 1)); + self::register("nether_quartz_ore", $factory->get(153)); + self::register("nether_reactor_core", $factory->get(247)); + self::register("nether_wart", $factory->get(115)); + self::register("nether_wart_block", $factory->get(214)); + self::register("netherrack", $factory->get(87)); + self::register("note_block", $factory->get(25)); + self::register("oak_button", $factory->get(143)); + self::register("oak_door", $factory->get(64)); + self::register("oak_fence", $factory->get(85)); + self::register("oak_fence_gate", $factory->get(107)); + self::register("oak_leaves", $factory->get(18)); + self::register("oak_log", $factory->get(17)); + self::register("oak_planks", $factory->get(5)); + self::register("oak_pressure_plate", $factory->get(72)); + self::register("oak_sapling", $factory->get(6)); + self::register("oak_sign", $factory->get(63)); + self::register("oak_slab", $factory->get(158)); + self::register("oak_stairs", $factory->get(53)); + self::register("oak_trapdoor", $factory->get(96)); + self::register("oak_wood", $factory->get(467)); + self::register("obsidian", $factory->get(49)); + self::register("orange_carpet", $factory->get(171, 1)); + self::register("orange_concrete", $factory->get(236, 1)); + self::register("orange_concrete_powder", $factory->get(237, 1)); + self::register("orange_glazed_terracotta", $factory->get(221, 2)); + self::register("orange_stained_clay", $factory->get(159, 1)); + self::register("orange_stained_glass", $factory->get(241, 1)); + self::register("orange_stained_glass_pane", $factory->get(160, 1)); + self::register("orange_tulip", $factory->get(38, 5)); + self::register("orange_wool", $factory->get(35, 1)); + self::register("oxeye_daisy", $factory->get(38, 8)); + self::register("packed_ice", $factory->get(174)); + self::register("peony", $factory->get(175, 5)); + self::register("pink_carpet", $factory->get(171, 6)); + self::register("pink_concrete", $factory->get(236, 6)); + self::register("pink_concrete_powder", $factory->get(237, 6)); + self::register("pink_glazed_terracotta", $factory->get(226, 2)); + self::register("pink_stained_clay", $factory->get(159, 6)); + self::register("pink_stained_glass", $factory->get(241, 6)); + self::register("pink_stained_glass_pane", $factory->get(160, 6)); + self::register("pink_tulip", $factory->get(38, 7)); + self::register("pink_wool", $factory->get(35, 6)); + self::register("podzol", $factory->get(243)); + self::register("polished_andesite", $factory->get(1, 6)); + self::register("polished_andesite_slab", $factory->get(417, 2)); + self::register("polished_andesite_stairs", $factory->get(429)); + self::register("polished_diorite", $factory->get(1, 4)); + self::register("polished_diorite_slab", $factory->get(417, 5)); + self::register("polished_diorite_stairs", $factory->get(428)); + self::register("polished_granite", $factory->get(1, 2)); + self::register("polished_granite_slab", $factory->get(417, 7)); + self::register("polished_granite_stairs", $factory->get(427)); + self::register("poppy", $factory->get(38)); + self::register("potatoes", $factory->get(142)); + self::register("powered_rail", $factory->get(27)); + self::register("prismarine", $factory->get(168)); + self::register("prismarine_bricks", $factory->get(168, 2)); + self::register("prismarine_bricks_slab", $factory->get(182, 4)); + self::register("prismarine_bricks_stairs", $factory->get(259)); + self::register("prismarine_slab", $factory->get(182, 2)); + self::register("prismarine_stairs", $factory->get(257)); + self::register("prismarine_wall", $factory->get(139, 11)); + self::register("pumpkin", $factory->get(86)); + self::register("pumpkin_stem", $factory->get(104)); + self::register("purple_carpet", $factory->get(171, 10)); + self::register("purple_concrete", $factory->get(236, 10)); + self::register("purple_concrete_powder", $factory->get(237, 10)); + self::register("purple_glazed_terracotta", $factory->get(219, 2)); + self::register("purple_stained_clay", $factory->get(159, 10)); + self::register("purple_stained_glass", $factory->get(241, 10)); + self::register("purple_stained_glass_pane", $factory->get(160, 10)); + self::register("purple_torch", $factory->get(204, 13)); + self::register("purple_wool", $factory->get(35, 10)); + self::register("purpur", $factory->get(201)); + self::register("purpur_pillar", $factory->get(201, 2)); + self::register("purpur_slab", $factory->get(182, 1)); + self::register("purpur_stairs", $factory->get(203)); + self::register("quartz", $factory->get(155)); + self::register("quartz_pillar", $factory->get(155, 2)); + self::register("quartz_slab", $factory->get(44, 6)); + self::register("quartz_stairs", $factory->get(156)); + self::register("rail", $factory->get(66)); + self::register("red_carpet", $factory->get(171, 14)); + self::register("red_concrete", $factory->get(236, 14)); + self::register("red_concrete_powder", $factory->get(237, 14)); + self::register("red_glazed_terracotta", $factory->get(234, 2)); + self::register("red_mushroom", $factory->get(40)); + self::register("red_mushroom_block", $factory->get(100)); + self::register("red_nether_brick_slab", $factory->get(182, 7)); + self::register("red_nether_brick_stairs", $factory->get(439)); + self::register("red_nether_brick_wall", $factory->get(139, 13)); + self::register("red_nether_bricks", $factory->get(215)); + self::register("red_sand", $factory->get(12, 1)); + self::register("red_sandstone", $factory->get(179)); + self::register("red_sandstone_slab", $factory->get(182)); + self::register("red_sandstone_stairs", $factory->get(180)); + self::register("red_sandstone_wall", $factory->get(139, 12)); + self::register("red_stained_clay", $factory->get(159, 14)); + self::register("red_stained_glass", $factory->get(241, 14)); + self::register("red_stained_glass_pane", $factory->get(160, 14)); + self::register("red_torch", $factory->get(202, 5)); + self::register("red_tulip", $factory->get(38, 4)); + self::register("red_wool", $factory->get(35, 14)); + self::register("redstone", $factory->get(152)); + self::register("redstone_comparator", $factory->get(149)); + self::register("redstone_lamp", $factory->get(123)); + self::register("redstone_ore", $factory->get(73)); + self::register("redstone_repeater", $factory->get(93)); + self::register("redstone_torch", $factory->get(76, 5)); + self::register("redstone_wire", $factory->get(55)); + self::register("reserved6", $factory->get(255)); + self::register("rose_bush", $factory->get(175, 4)); + self::register("sand", $factory->get(12)); + self::register("sandstone", $factory->get(24)); + self::register("sandstone_slab", $factory->get(44, 1)); + self::register("sandstone_stairs", $factory->get(128)); + self::register("sandstone_wall", $factory->get(139, 5)); + self::register("sea_lantern", $factory->get(169)); + self::register("sea_pickle", $factory->get(411)); + self::register("slightly_damaged_anvil", $factory->get(145, 4)); + self::register("smooth_quartz", $factory->get(155, 3)); + self::register("smooth_quartz_slab", $factory->get(421, 1)); + self::register("smooth_quartz_stairs", $factory->get(440)); + self::register("smooth_red_sandstone", $factory->get(179, 3)); + self::register("smooth_red_sandstone_slab", $factory->get(417, 1)); + self::register("smooth_red_sandstone_stairs", $factory->get(431)); + self::register("smooth_sandstone", $factory->get(24, 3)); + self::register("smooth_sandstone_slab", $factory->get(182, 6)); + self::register("smooth_sandstone_stairs", $factory->get(432)); + self::register("smooth_stone", $factory->get(438)); + self::register("smooth_stone_slab", $factory->get(44)); + self::register("snow", $factory->get(80)); + self::register("snow_layer", $factory->get(78)); + self::register("soul_sand", $factory->get(88)); + self::register("sponge", $factory->get(19)); + self::register("spruce_button", $factory->get(399)); + self::register("spruce_door", $factory->get(193)); + self::register("spruce_fence", $factory->get(85, 1)); + self::register("spruce_fence_gate", $factory->get(183)); + self::register("spruce_leaves", $factory->get(18, 1)); + self::register("spruce_log", $factory->get(17, 1)); + self::register("spruce_planks", $factory->get(5, 1)); + self::register("spruce_pressure_plate", $factory->get(409)); + self::register("spruce_sapling", $factory->get(6, 1)); + self::register("spruce_sign", $factory->get(436)); + self::register("spruce_slab", $factory->get(158, 1)); + self::register("spruce_stairs", $factory->get(134)); + self::register("spruce_trapdoor", $factory->get(404)); + self::register("spruce_wood", $factory->get(467, 1)); + self::register("stone", $factory->get(1)); + self::register("stone_brick_slab", $factory->get(44, 5)); + self::register("stone_brick_stairs", $factory->get(109)); + self::register("stone_brick_wall", $factory->get(139, 7)); + self::register("stone_bricks", $factory->get(98)); + self::register("stone_button", $factory->get(77)); + self::register("stone_pressure_plate", $factory->get(70)); + self::register("stone_slab", $factory->get(421, 2)); + self::register("stone_stairs", $factory->get(435)); + self::register("sugarcane", $factory->get(83)); + self::register("sunflower", $factory->get(175)); + self::register("tall_grass", $factory->get(31, 1)); + self::register("tnt", $factory->get(46)); + self::register("torch", $factory->get(50, 5)); + self::register("trapped_chest", $factory->get(146, 2)); + self::register("tripwire", $factory->get(132)); + self::register("tripwire_hook", $factory->get(131)); + self::register("underwater_torch", $factory->get(239, 5)); + self::register("very_damaged_anvil", $factory->get(145, 8)); + self::register("vines", $factory->get(106)); + self::register("water", $factory->get(8)); + self::register("weighted_pressure_plate_heavy", $factory->get(148)); + self::register("weighted_pressure_plate_light", $factory->get(147)); + self::register("wheat", $factory->get(59)); + self::register("white_carpet", $factory->get(171)); + self::register("white_concrete", $factory->get(236)); + self::register("white_concrete_powder", $factory->get(237)); + self::register("white_glazed_terracotta", $factory->get(220, 2)); + self::register("white_stained_clay", $factory->get(159)); + self::register("white_stained_glass", $factory->get(241)); + self::register("white_stained_glass_pane", $factory->get(160)); + self::register("white_tulip", $factory->get(38, 6)); + self::register("white_wool", $factory->get(35)); + self::register("yellow_carpet", $factory->get(171, 4)); + self::register("yellow_concrete", $factory->get(236, 4)); + self::register("yellow_concrete_powder", $factory->get(237, 4)); + self::register("yellow_glazed_terracotta", $factory->get(224, 2)); + self::register("yellow_stained_clay", $factory->get(159, 4)); + self::register("yellow_stained_glass", $factory->get(241, 4)); + self::register("yellow_stained_glass_pane", $factory->get(160, 4)); + self::register("yellow_wool", $factory->get(35, 4)); } } diff --git a/src/block/tile/FlowerPot.php b/src/block/tile/FlowerPot.php index d6641a1f3f..279041303b 100644 --- a/src/block/tile/FlowerPot.php +++ b/src/block/tile/FlowerPot.php @@ -44,7 +44,7 @@ class FlowerPot extends Spawnable{ public function readSaveData(CompoundTag $nbt) : void{ if($nbt->hasTag(self::TAG_ITEM, ShortTag::class) and $nbt->hasTag(self::TAG_ITEM_DATA, IntTag::class)){ try{ - $this->setPlant(BlockFactory::get($nbt->getShort(self::TAG_ITEM), $nbt->getInt(self::TAG_ITEM_DATA))); + $this->setPlant(BlockFactory::getInstance()->get($nbt->getShort(self::TAG_ITEM), $nbt->getInt(self::TAG_ITEM_DATA))); }catch(\InvalidArgumentException $e){ //noop } diff --git a/src/command/defaults/ParticleCommand.php b/src/command/defaults/ParticleCommand.php index d503ee510f..e9f7a649fa 100644 --- a/src/command/defaults/ParticleCommand.php +++ b/src/command/defaults/ParticleCommand.php @@ -185,7 +185,7 @@ class ParticleCommand extends VanillaCommand{ break; case "terrain": if($data !== null and $data !== 0){ - return new TerrainParticle(BlockFactory::get($data)); + return new TerrainParticle(BlockFactory::getInstance()->get($data)); } break; case "heart": @@ -213,7 +213,7 @@ class ParticleCommand extends VanillaCommand{ }elseif(strpos($name, "blockcrack_") === 0){ $d = explode("_", $name); if(count($d) === 2){ - return new TerrainParticle(BlockFactory::get(((int) $d[1]) & 0xff, ((int) $d[1]) >> 12)); + return new TerrainParticle(BlockFactory::getInstance()->get(((int) $d[1]) & 0xff, ((int) $d[1]) >> 12)); } }elseif(strpos($name, "blockdust_") === 0){ $d = explode("_", $name); diff --git a/src/entity/object/FallingBlock.php b/src/entity/object/FallingBlock.php index fe23efbcf9..20c7403b15 100644 --- a/src/entity/object/FallingBlock.php +++ b/src/entity/object/FallingBlock.php @@ -71,7 +71,7 @@ class FallingBlock extends Entity{ $damage = $nbt->getByte("Data", 0); - $this->block = BlockFactory::get($blockId, $damage); + $this->block = BlockFactory::getInstance()->get($blockId, $damage); } public function canCollideWith(Entity $entity) : bool{ diff --git a/src/entity/projectile/Projectile.php b/src/entity/projectile/Projectile.php index 82a1aa9922..5a9777053f 100644 --- a/src/entity/projectile/Projectile.php +++ b/src/entity/projectile/Projectile.php @@ -100,7 +100,7 @@ abstract class Projectile extends Entity{ break; } - $this->blockHit = BlockFactory::get($blockId, $blockData); + $this->blockHit = BlockFactory::getInstance()->get($blockId, $blockData); $this->blockHit->position($this->getWorld(), $blockPos->getFloorX(), $blockPos->getFloorY(), $blockPos->getFloorZ()); }while(false); } diff --git a/src/item/ItemBlock.php b/src/item/ItemBlock.php index ca67e2a992..aa207e9249 100644 --- a/src/item/ItemBlock.php +++ b/src/item/ItemBlock.php @@ -50,7 +50,7 @@ class ItemBlock extends Item{ } public function getBlock() : Block{ - return BlockFactory::get($this->blockId, $this->meta === -1 ? 0 : $this->meta & 0xf); + return BlockFactory::getInstance()->get($this->blockId, $this->meta === -1 ? 0 : $this->meta & 0xf); } public function getFuelTime() : int{ diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index a526114ba6..940bdaebd2 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -467,7 +467,7 @@ class ItemFactory{ */ public static function isRegistered(int $id, int $variant = 0) : bool{ if($id < 256){ - return BlockFactory::isRegistered($id); + return BlockFactory::getInstance()->isRegistered($id); } return isset(self::$list[self::getListOffset($id, $variant)]); diff --git a/src/world/Explosion.php b/src/world/Explosion.php index 4f89c705e0..f0cba16ed0 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -93,6 +93,7 @@ class Explosion{ } $vector = new Vector3(0, 0, 0); + $blockFactory = BlockFactory::getInstance(); $currentChunk = null; $currentSubChunk = null; @@ -127,10 +128,10 @@ class Explosion{ $state = $this->subChunkHandler->currentSubChunk->getFullBlock($vBlockX & 0x0f, $vBlockY & 0x0f, $vBlockZ & 0x0f); if($state !== 0){ - $blastForce -= (BlockFactory::$blastResistance[$state] / 5 + 0.3) * $this->stepLen; + $blastForce -= ($blockFactory->blastResistance[$state] / 5 + 0.3) * $this->stepLen; if($blastForce > 0){ if(!isset($this->affectedBlocks[$index = World::blockHash($vBlockX, $vBlockY, $vBlockZ)])){ - $_block = BlockFactory::fromFullBlock($state); + $_block = $blockFactory->fromFullBlock($state); $_block->position($this->world, $vBlockX, $vBlockY, $vBlockZ); $this->affectedBlocks[$index] = $_block; } diff --git a/src/world/SimpleChunkManager.php b/src/world/SimpleChunkManager.php index 6d65b6803a..754142e5be 100644 --- a/src/world/SimpleChunkManager.php +++ b/src/world/SimpleChunkManager.php @@ -51,7 +51,7 @@ class SimpleChunkManager implements ChunkManager{ public function getBlockAt(int $x, int $y, int $z) : Block{ if($this->terrainPointer->moveTo($x, $y, $z, false)){ - return BlockFactory::fromFullBlock($this->terrainPointer->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf)); + return BlockFactory::getInstance()->fromFullBlock($this->terrainPointer->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf)); } return VanillaBlocks::AIR(); } diff --git a/src/world/World.php b/src/world/World.php index dae02190d6..4594b5946d 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -346,7 +346,7 @@ class World implements ChunkManager{ $dontTickBlocks = array_fill_keys($this->server->getProperty("chunk-ticking.disable-block-ticking", []), true); - foreach(BlockFactory::getAllKnownStates() as $state){ + foreach(BlockFactory::getInstance()->getAllKnownStates() as $state){ if(!isset($dontTickBlocks[$state->getId()]) and $state->ticksRandomly()){ $this->randomTickBlocks[$state->getFullId()] = true; } @@ -945,7 +945,7 @@ class World implements ChunkManager{ if(isset($this->randomTickBlocks[$state])){ /** @var Block $block */ - $block = BlockFactory::fromFullBlock($state); + $block = BlockFactory::getInstance()->fromFullBlock($state); $block->position($this, $chunkX * 16 + $x, ($Y << 4) + $y, $chunkZ * 16 + $z); $block->onRandomTick(); } @@ -1303,7 +1303,7 @@ class World implements ChunkManager{ } } - $block = BlockFactory::fromFullBlock($fullState); + $block = BlockFactory::getInstance()->fromFullBlock($fullState); $block->position($this, $x, $y, $z); static $dynamicStateRead = false; diff --git a/src/world/generator/GeneratorRegisterTask.php b/src/world/generator/GeneratorRegisterTask.php index 5b31a31f8d..d002351207 100644 --- a/src/world/generator/GeneratorRegisterTask.php +++ b/src/world/generator/GeneratorRegisterTask.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\world\generator; -use pocketmine\block\BlockFactory; use pocketmine\scheduler\AsyncTask; use pocketmine\world\biome\Biome; use pocketmine\world\World; @@ -56,7 +55,6 @@ class GeneratorRegisterTask extends AsyncTask{ } public function onRun() : void{ - BlockFactory::init(); Biome::init(); $manager = new GeneratorChunkManager($this->worldHeight); $this->worker->saveToThreadStore("generation.world{$this->worldId}.manager", $manager); diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index a6b79ca716..e1a488b89b 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -119,8 +119,9 @@ class PopulationTask extends AsyncTask{ $chunk = $manager->getChunk($chunk->getX(), $chunk->getZ()); $chunk->setPopulated(); - $chunk->recalculateHeightMap(BlockFactory::$lightFilter, BlockFactory::$diffusesSkyLight); - $chunk->populateSkyLight(BlockFactory::$lightFilter); + $blockFactory = BlockFactory::getInstance(); + $chunk->recalculateHeightMap($blockFactory->lightFilter, $blockFactory->diffusesSkyLight); + $chunk->populateSkyLight($blockFactory->lightFilter); $chunk->setLightPopulated(); $this->chunk = FastChunkSerializer::serialize($chunk); diff --git a/src/world/generator/populator/GroundCover.php b/src/world/generator/populator/GroundCover.php index 96e09d237c..98bb73faec 100644 --- a/src/world/generator/populator/GroundCover.php +++ b/src/world/generator/populator/GroundCover.php @@ -36,6 +36,7 @@ class GroundCover extends Populator{ public function populate(ChunkManager $world, int $chunkX, int $chunkZ, Random $random) : void{ $chunk = $world->getChunk($chunkX, $chunkZ); + $factory = BlockFactory::getInstance(); for($x = 0; $x < 16; ++$x){ for($z = 0; $z < 16; ++$z){ $biome = Biome::getBiome($chunk->getBiomeId($x, $z)); @@ -48,7 +49,7 @@ class GroundCover extends Populator{ $startY = 127; for(; $startY > 0; --$startY){ - if(!BlockFactory::fromFullBlock($chunk->getFullBlock($x, $startY, $z))->isTransparent()){ + if(!$factory->fromFullBlock($chunk->getFullBlock($x, $startY, $z))->isTransparent()){ break; } } @@ -56,7 +57,7 @@ class GroundCover extends Populator{ $endY = $startY - count($cover); for($y = $startY; $y > $endY and $y >= 0; --$y){ $b = $cover[$startY - $y]; - $id = BlockFactory::fromFullBlock($chunk->getFullBlock($x, $y, $z)); + $id = $factory->fromFullBlock($chunk->getFullBlock($x, $y, $z)); if($id->getId() === BlockLegacyIds::AIR and $b->isSolid()){ break; } diff --git a/src/world/light/BlockLightUpdate.php b/src/world/light/BlockLightUpdate.php index 9be3d6a370..266e84f4bc 100644 --- a/src/world/light/BlockLightUpdate.php +++ b/src/world/light/BlockLightUpdate.php @@ -33,6 +33,6 @@ class BlockLightUpdate extends LightUpdate{ public function recalculateNode(int $x, int $y, int $z) : void{ $block = $this->world->getBlockAt($x, $y, $z); - $this->setAndUpdateLight($x, $y, $z, max($block->getLightLevel(), $this->getHighestAdjacentLight($x, $y, $z) - BlockFactory::$lightFilter[$block->getFullId()])); + $this->setAndUpdateLight($x, $y, $z, max($block->getLightLevel(), $this->getHighestAdjacentLight($x, $y, $z) - BlockFactory::getInstance()->lightFilter[$block->getFullId()])); } } diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index 0fd0b40d60..8fa5776e99 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -57,14 +57,12 @@ class LightPopulationTask extends AsyncTask{ } public function onRun() : void{ - if(!BlockFactory::isInit()){ - BlockFactory::init(); - } /** @var Chunk $chunk */ $chunk = FastChunkSerializer::deserialize($this->chunk); - $chunk->recalculateHeightMap(BlockFactory::$lightFilter, BlockFactory::$diffusesSkyLight); - $chunk->populateSkyLight(BlockFactory::$lightFilter); + $blockFactory = BlockFactory::getInstance(); + $chunk->recalculateHeightMap($blockFactory->lightFilter, $blockFactory->diffusesSkyLight); + $chunk->populateSkyLight($blockFactory->lightFilter); $chunk->setLightPopulated(); $this->resultHeightMap = igbinary_serialize($chunk->getHeightMapArray()); diff --git a/src/world/light/LightUpdate.php b/src/world/light/LightUpdate.php index c91a68ac47..4a8abe8e5e 100644 --- a/src/world/light/LightUpdate.php +++ b/src/world/light/LightUpdate.php @@ -188,7 +188,7 @@ abstract class LightUpdate{ protected function computeSpreadLight(int $x, int $y, int $z, int $newAdjacentLevel) : void{ $current = $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); - $potentialLight = $newAdjacentLevel - BlockFactory::$lightFilter[$this->subChunkHandler->currentSubChunk->getFullBlock($x & 0x0f, $y & 0x0f, $z & 0x0f)]; + $potentialLight = $newAdjacentLevel - BlockFactory::getInstance()->lightFilter[$this->subChunkHandler->currentSubChunk->getFullBlock($x & 0x0f, $y & 0x0f, $z & 0x0f)]; if($current < $potentialLight){ $this->currentLightArray->set($x & 0xf, $y & 0xf, $z & 0xf, $potentialLight); diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index 74eba4031b..290537da94 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -51,7 +51,7 @@ class SkyLightUpdate extends LightUpdate{ $yPlusOne = $y + 1; if($yPlusOne === $oldHeightMap){ //Block changed directly beneath the heightmap. Check if a block was removed or changed to a different light-filter. - $newHeightMap = $chunk->recalculateHeightMapColumn($x & 0x0f, $z & 0x0f, BlockFactory::$lightFilter, BlockFactory::$diffusesSkyLight); + $newHeightMap = $chunk->recalculateHeightMapColumn($x & 0x0f, $z & 0x0f, BlockFactory::getInstance()->lightFilter, BlockFactory::getInstance()->diffusesSkyLight); }elseif($yPlusOne > $oldHeightMap){ //Block changed above the heightmap. if($source->getLightFilter() > 0 or $source->diffusesSkyLight()){ $chunk->setHeightMap($x & 0xf, $z & 0xf, $yPlusOne); @@ -72,7 +72,7 @@ class SkyLightUpdate extends LightUpdate{ $this->setAndUpdateLight($x, $i, $z, 15); } }else{ //No heightmap change, block changed "underground" - $this->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentLight($x, $y, $z) - BlockFactory::$lightFilter[$source->getFullId()])); + $this->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentLight($x, $y, $z) - BlockFactory::getInstance()->lightFilter[$source->getFullId()])); } } } diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index 218897d82e..fef6694bdf 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -29,8 +29,11 @@ use function json_decode; class BlockTest extends TestCase{ + /** @var BlockFactory */ + private $blockFactory; + public function setUp() : void{ - BlockFactory::init(); + $this->blockFactory = new BlockFactory(); } /** @@ -39,7 +42,7 @@ class BlockTest extends TestCase{ public function testAccidentalOverrideBlock() : void{ $block = new MyCustomBlock(new BlockIdentifier(BlockLegacyIds::COBBLESTONE), "Cobblestone", BlockBreakInfo::instant()); $this->expectException(\InvalidArgumentException::class); - BlockFactory::register($block); + $this->blockFactory->register($block); } /** @@ -47,8 +50,8 @@ class BlockTest extends TestCase{ */ public function testDeliberateOverrideBlock() : void{ $block = new MyCustomBlock(new BlockIdentifier(BlockLegacyIds::COBBLESTONE), "Cobblestone", BlockBreakInfo::instant()); - BlockFactory::register($block, true); - self::assertInstanceOf(MyCustomBlock::class, BlockFactory::get($block->getId())); + $this->blockFactory->register($block, true); + self::assertInstanceOf(MyCustomBlock::class, $this->blockFactory->get($block->getId())); } /** @@ -56,10 +59,10 @@ class BlockTest extends TestCase{ */ public function testRegisterNewBlock() : void{ for($i = 0; $i < 256; ++$i){ - if(!BlockFactory::isRegistered($i)){ + if(!$this->blockFactory->isRegistered($i)){ $b = new StrangeNewBlock(new BlockIdentifier($i), "Strange New Block", BlockBreakInfo::instant()); - BlockFactory::register($b); - self::assertInstanceOf(StrangeNewBlock::class, BlockFactory::get($b->getId())); + $this->blockFactory->register($b); + self::assertInstanceOf(StrangeNewBlock::class, $this->blockFactory->get($b->getId())); return; } } @@ -72,7 +75,7 @@ class BlockTest extends TestCase{ */ public function testRegisterIdTooLarge() : void{ self::expectException(\RuntimeException::class); - BlockFactory::register(new OutOfBoundsBlock(new BlockIdentifier(25555), "Out Of Bounds Block", BlockBreakInfo::instant())); + $this->blockFactory->register(new OutOfBoundsBlock(new BlockIdentifier(25555), "Out Of Bounds Block", BlockBreakInfo::instant())); } /** @@ -80,7 +83,7 @@ class BlockTest extends TestCase{ */ public function testRegisterIdTooSmall() : void{ self::expectException(\RuntimeException::class); - BlockFactory::register(new OutOfBoundsBlock(new BlockIdentifier(-1), "Out Of Bounds Block", BlockBreakInfo::instant())); + $this->blockFactory->register(new OutOfBoundsBlock(new BlockIdentifier(-1), "Out Of Bounds Block", BlockBreakInfo::instant())); } /** @@ -90,8 +93,8 @@ class BlockTest extends TestCase{ */ public function testBlockFactoryClone() : void{ for($i = 0; $i < 256; ++$i){ - $b1 = BlockFactory::get($i); - $b2 = BlockFactory::get($i); + $b1 = $this->blockFactory->get($i); + $b2 = $this->blockFactory->get($i); self::assertNotSame($b1, $b2); } } @@ -117,7 +120,7 @@ class BlockTest extends TestCase{ * @param int $meta */ public function testBlockGet(int $id, int $meta) : void{ - $block = BlockFactory::get($id, $meta); + $block = $this->blockFactory->get($id, $meta); self::assertEquals($id, $block->getId()); self::assertEquals($meta, $block->getMeta()); @@ -125,7 +128,7 @@ class BlockTest extends TestCase{ public function testBlockIds() : void{ for($i = 0; $i < 256; ++$i){ - $b = BlockFactory::get($i); + $b = $this->blockFactory->get($i); self::assertContains($i, $b->getIdInfo()->getAllBlockIds()); } } @@ -135,7 +138,7 @@ class BlockTest extends TestCase{ * (like freezes) when doing light population. */ public function testLightFiltersValid() : void{ - foreach(BlockFactory::$lightFilter as $id => $value){ + foreach($this->blockFactory->lightFilter as $id => $value){ self::assertNotNull($value, "Light filter value missing for $id"); self::assertLessThanOrEqual(15, $value, "Light filter value for $id is larger than the expected 15"); self::assertGreaterThan(0, $value, "Light filter value for $id must be larger than 0"); @@ -144,7 +147,7 @@ class BlockTest extends TestCase{ public function testConsistency() : void{ $list = json_decode(file_get_contents(__DIR__ . '/block_factory_consistency_check.json'), true); - $states = BlockFactory::getAllKnownStates(); + $states = $this->blockFactory->getAllKnownStates(); foreach($states as $k => $state){ self::assertArrayHasKey($k, $list, "New block state $k (" . $state->getName() . ") - consistency check may need regenerating"); self::assertSame($list[$k], $state->getName()); diff --git a/tests/phpunit/block/regenerate_consistency_check.php b/tests/phpunit/block/regenerate_consistency_check.php index 693bd89aea..aac5194c9c 100644 --- a/tests/phpunit/block/regenerate_consistency_check.php +++ b/tests/phpunit/block/regenerate_consistency_check.php @@ -25,14 +25,14 @@ require dirname(__DIR__, 3) . '/vendor/autoload.php'; /* This script needs to be re-run after any intentional blockfactory change (adding or removing a block state). */ -\pocketmine\block\BlockFactory::init(); +$factory = new \pocketmine\block\BlockFactory(); $old = json_decode(file_get_contents(__DIR__ . '/block_factory_consistency_check.json'), true); $new = array_map( function(\pocketmine\block\Block $block) : string{ return $block->getName(); }, - \pocketmine\block\BlockFactory::getAllKnownStates() + $factory->getAllKnownStates() ); foreach($old as $k => $name){ if(!isset($new[$k])){ diff --git a/tests/phpunit/item/ItemFactoryTest.php b/tests/phpunit/item/ItemFactoryTest.php index a05fba0807..9e85f06657 100644 --- a/tests/phpunit/item/ItemFactoryTest.php +++ b/tests/phpunit/item/ItemFactoryTest.php @@ -29,7 +29,6 @@ use pocketmine\block\BlockFactory; class ItemFactoryTest extends TestCase{ public function setUp() : void{ - BlockFactory::init(); ItemFactory::init(); } @@ -38,7 +37,7 @@ class ItemFactoryTest extends TestCase{ */ public function testItemBlockRegistered() : void{ for($id = 0; $id < 256; ++$id){ - self::assertEquals(BlockFactory::isRegistered($id), ItemFactory::isRegistered($id)); + self::assertEquals(BlockFactory::getInstance()->isRegistered($id), ItemFactory::isRegistered($id)); } } diff --git a/tests/phpunit/item/ItemTest.php b/tests/phpunit/item/ItemTest.php index 205ebae30b..ee98abb3cf 100644 --- a/tests/phpunit/item/ItemTest.php +++ b/tests/phpunit/item/ItemTest.php @@ -24,14 +24,12 @@ declare(strict_types=1); namespace pocketmine\item; use PHPUnit\Framework\TestCase; -use pocketmine\block\BlockFactory; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\EnchantmentInstance; class ItemTest extends TestCase{ public static function setUpBeforeClass() : void{ - BlockFactory::init(); ItemFactory::init(); Enchantment::init(); } From 5a94af40e28d6c55eff072126a49438f620a32fc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 24 Apr 2020 00:18:31 +0100 Subject: [PATCH 1455/3224] Convert ItemFactory to singleton --- src/Server.php | 2 - src/block/Banner.php | 2 +- src/block/Bed.php | 2 +- src/block/Block.php | 2 +- src/block/Leaves.php | 2 +- src/block/Skull.php | 2 +- src/block/tile/Furnace.php | 2 +- src/command/defaults/GiveCommand.php | 2 +- src/command/defaults/ParticleCommand.php | 4 +- src/item/Bucket.php | 2 +- src/item/Item.php | 8 +- src/item/ItemFactory.php | 503 ++++++++--------- src/item/VanillaItems.php | 517 +++++++++--------- src/network/mcpe/convert/TypeConverter.php | 4 +- src/world/World.php | 6 +- src/world/generator/Flat.php | 3 +- tests/phpunit/inventory/BaseInventoryTest.php | 8 +- tests/phpunit/item/ItemFactoryTest.php | 12 +- tests/phpunit/item/ItemTest.php | 9 +- 19 files changed, 546 insertions(+), 546 deletions(-) diff --git a/src/Server.php b/src/Server.php index b31a2eb8e8..2deb2f2bf1 100644 --- a/src/Server.php +++ b/src/Server.php @@ -41,7 +41,6 @@ use pocketmine\event\server\DataPacketSendEvent; use pocketmine\event\server\QueryRegenerateEvent; use pocketmine\inventory\CreativeInventory; use pocketmine\item\enchantment\Enchantment; -use pocketmine\item\ItemFactory; use pocketmine\lang\Language; use pocketmine\lang\LanguageNotFoundException; use pocketmine\lang\TranslationContainer; @@ -985,7 +984,6 @@ class Server{ EntityFactory::init(); Enchantment::init(); - ItemFactory::init(); CreativeInventory::init(); Biome::init(); diff --git a/src/block/Banner.php b/src/block/Banner.php index 8abfbf1ef2..cb4a5449fe 100644 --- a/src/block/Banner.php +++ b/src/block/Banner.php @@ -176,7 +176,7 @@ class Banner extends Transparent{ } public function asItem() : Item{ - return ItemFactory::get(ItemIds::BANNER, $this->baseColor->getInvertedMagicNumber()); + return ItemFactory::getInstance()->get(ItemIds::BANNER, $this->baseColor->getInvertedMagicNumber()); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/block/Bed.php b/src/block/Bed.php index 5f2636876b..a5176d1b45 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -193,7 +193,7 @@ class Bed extends Transparent{ } public function asItem() : Item{ - return ItemFactory::get($this->idInfo->getItemId(), $this->color->getMagicNumber()); + return ItemFactory::getInstance()->get($this->idInfo->getItemId(), $this->color->getMagicNumber()); } public function getAffectedBlocks() : array{ diff --git a/src/block/Block.php b/src/block/Block.php index a6defb949e..a19610f07a 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -104,7 +104,7 @@ class Block{ } public function asItem() : Item{ - return ItemFactory::get($this->idInfo->getItemId(), $this->idInfo->getVariant()); + return ItemFactory::getInstance()->get($this->idInfo->getItemId(), $this->idInfo->getVariant()); } /** diff --git a/src/block/Leaves.php b/src/block/Leaves.php index 09dd3ca91b..07bd70ff0c 100644 --- a/src/block/Leaves.php +++ b/src/block/Leaves.php @@ -130,7 +130,7 @@ class Leaves extends Transparent{ $drops = []; if(mt_rand(1, 20) === 1){ //Saplings - $drops[] = ItemFactory::get(ItemIds::SAPLING, $this->treeType->getMagicNumber()); + $drops[] = ItemFactory::getInstance()->get(ItemIds::SAPLING, $this->treeType->getMagicNumber()); } if(($this->treeType->equals(TreeType::OAK()) or $this->treeType->equals(TreeType::DARK_OAK())) and mt_rand(1, 200) === 1){ //Apples $drops[] = VanillaItems::APPLE(); diff --git a/src/block/Skull.php b/src/block/Skull.php index c2675aa53d..1aaeda4e05 100644 --- a/src/block/Skull.php +++ b/src/block/Skull.php @@ -111,6 +111,6 @@ class Skull extends Flowable{ } public function asItem() : Item{ - return ItemFactory::get(ItemIds::SKULL, $this->skullType->getMagicNumber()); + return ItemFactory::getInstance()->get(ItemIds::SKULL, $this->skullType->getMagicNumber()); } } diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index 6c7bad9198..425f119119 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -169,7 +169,7 @@ class Furnace extends Spawnable implements Container, Nameable{ ++$this->cookTime; if($this->cookTime >= 200){ //10 seconds - $product = ItemFactory::get($smelt->getResult()->getId(), $smelt->getResult()->getMeta(), $product->getCount() + 1); + $product = ItemFactory::getInstance()->get($smelt->getResult()->getId(), $smelt->getResult()->getMeta(), $product->getCount() + 1); $ev = new FurnaceSmeltEvent($this, $raw, $product); $ev->call(); diff --git a/src/command/defaults/GiveCommand.php b/src/command/defaults/GiveCommand.php index c84ee33456..1b0c0bbf51 100644 --- a/src/command/defaults/GiveCommand.php +++ b/src/command/defaults/GiveCommand.php @@ -62,7 +62,7 @@ class GiveCommand extends VanillaCommand{ } try{ - $item = ItemFactory::fromString($args[1]); + $item = ItemFactory::getInstance()->fromString($args[1]); }catch(\InvalidArgumentException $e){ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.give.item.notFound", [$args[1]])); return true; diff --git a/src/command/defaults/ParticleCommand.php b/src/command/defaults/ParticleCommand.php index e9f7a649fa..37ba888f17 100644 --- a/src/command/defaults/ParticleCommand.php +++ b/src/command/defaults/ParticleCommand.php @@ -180,7 +180,7 @@ class ParticleCommand extends VanillaCommand{ return new ItemBreakParticle(VanillaItems::SLIMEBALL()); case "itembreak": if($data !== null and $data !== 0){ - return new ItemBreakParticle(ItemFactory::get($data)); + return new ItemBreakParticle(ItemFactory::getInstance()->get($data)); } break; case "terrain": @@ -208,7 +208,7 @@ class ParticleCommand extends VanillaCommand{ if(strpos($name, "iconcrack_") === 0){ $d = explode("_", $name); if(count($d) === 3){ - return new ItemBreakParticle(ItemFactory::get((int) $d[1], (int) $d[2])); + return new ItemBreakParticle(ItemFactory::getInstance()->get((int) $d[1], (int) $d[2])); } }elseif(strpos($name, "blockcrack_") === 0){ $d = explode("_", $name); diff --git a/src/item/Bucket.php b/src/item/Bucket.php index c9b23ac1ff..649c45a2bc 100644 --- a/src/item/Bucket.php +++ b/src/item/Bucket.php @@ -42,7 +42,7 @@ class Bucket extends Item{ $stack = clone $this; $stack->pop(); - $resultItem = ItemFactory::get(ItemIds::BUCKET, $blockClicked->getFlowingForm()->getId()); + $resultItem = ItemFactory::getInstance()->get(ItemIds::BUCKET, $blockClicked->getFlowingForm()->getId()); $ev = new PlayerBucketFillEvent($player, $blockReplace, $face, $this, $resultItem); $ev->call(); if(!$ev->isCancelled()){ diff --git a/src/item/Item.php b/src/item/Item.php index fef054c6ce..7dca64d853 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -624,7 +624,7 @@ class Item implements \JsonSerializable{ }elseif(isset($data["nbt_b64"])){ $nbt = base64_decode($data["nbt_b64"], true); } - return ItemFactory::get( + return ItemFactory::getInstance()->get( (int) $data["id"], (int) ($data["damage"] ?? 0), (int) ($data["count"] ?? 1), $nbt !== "" ? (new LittleEndianNbtSerializer())->read($nbt)->mustGetCompoundTag() : null ); } @@ -656,7 +656,7 @@ class Item implements \JsonSerializable{ */ public static function nbtDeserialize(CompoundTag $tag) : Item{ if(!$tag->hasTag("id") or !$tag->hasTag("Count")){ - return ItemFactory::get(0); + return ItemFactory::getInstance()->get(0); } $count = Binary::unsignByte($tag->getByte("Count")); @@ -664,10 +664,10 @@ class Item implements \JsonSerializable{ $idTag = $tag->getTag("id"); if($idTag instanceof ShortTag){ - $item = ItemFactory::get($idTag->getValue(), $meta, $count); + $item = ItemFactory::getInstance()->get($idTag->getValue(), $meta, $count); }elseif($idTag instanceof StringTag){ //PC item save format try{ - $item = ItemFactory::fromString($idTag->getValue() . ":$meta"); + $item = ItemFactory::getInstance()->fromString($idTag->getValue() . ":$meta"); }catch(\InvalidArgumentException $e){ //TODO: improve error handling return ItemFactory::air(); diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 940bdaebd2..02cab6d320 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -46,196 +46,203 @@ use function trim; * Manages Item instance creation and registration */ class ItemFactory{ + /** @var self|null */ + private static $instance = null; + + public static function getInstance() : self{ + if(self::$instance === null){ + self::$instance = new self; + } + return self::$instance; + } /** @var Item[] */ - private static $list = []; + private $list = []; /** @var Item|null */ private static $air = null; - public static function init() : void{ - self::$list = []; //in case of re-initializing + public function __construct(){ + $this->registerArmorItems(); + $this->registerTierToolItems(); - self::registerArmorItems(); - self::registerTierToolItems(); + $this->register(new Apple(ItemIds::APPLE, 0, "Apple")); + $this->register(new Arrow(ItemIds::ARROW, 0, "Arrow")); - self::register(new Apple(ItemIds::APPLE, 0, "Apple")); - self::register(new Arrow(ItemIds::ARROW, 0, "Arrow")); - - self::register(new BakedPotato(ItemIds::BAKED_POTATO, 0, "Baked Potato")); - self::register(new Beetroot(ItemIds::BEETROOT, 0, "Beetroot")); - self::register(new BeetrootSeeds(ItemIds::BEETROOT_SEEDS, 0, "Beetroot Seeds")); - self::register(new BeetrootSoup(ItemIds::BEETROOT_SOUP, 0, "Beetroot Soup")); - self::register(new BlazeRod(ItemIds::BLAZE_ROD, 0, "Blaze Rod")); - self::register(new Book(ItemIds::BOOK, 0, "Book")); - self::register(new Bow(ItemIds::BOW, 0, "Bow")); - self::register(new Bowl(ItemIds::BOWL, 0, "Bowl")); - self::register(new Bread(ItemIds::BREAD, 0, "Bread")); - self::register(new Bucket(ItemIds::BUCKET, 0, "Bucket")); - self::register(new Carrot(ItemIds::CARROT, 0, "Carrot")); - self::register(new ChorusFruit(ItemIds::CHORUS_FRUIT, 0, "Chorus Fruit")); - self::register(new Clock(ItemIds::CLOCK, 0, "Clock")); - self::register(new Clownfish(ItemIds::CLOWNFISH, 0, "Clownfish")); - self::register(new Coal(ItemIds::COAL, 0, "Coal")); - self::register(new Coal(ItemIds::COAL, 1, "Charcoal")); - self::register(new CocoaBeans(ItemIds::DYE, 3, "Cocoa Beans")); - self::register(new Compass(ItemIds::COMPASS, 0, "Compass")); - self::register(new CookedChicken(ItemIds::COOKED_CHICKEN, 0, "Cooked Chicken")); - self::register(new CookedFish(ItemIds::COOKED_FISH, 0, "Cooked Fish")); - self::register(new CookedMutton(ItemIds::COOKED_MUTTON, 0, "Cooked Mutton")); - self::register(new CookedPorkchop(ItemIds::COOKED_PORKCHOP, 0, "Cooked Porkchop")); - self::register(new CookedRabbit(ItemIds::COOKED_RABBIT, 0, "Cooked Rabbit")); - self::register(new CookedSalmon(ItemIds::COOKED_SALMON, 0, "Cooked Salmon")); - self::register(new Cookie(ItemIds::COOKIE, 0, "Cookie")); - self::register(new DriedKelp(ItemIds::DRIED_KELP, 0, "Dried Kelp")); - self::register(new Egg(ItemIds::EGG, 0, "Egg")); - self::register(new EnderPearl(ItemIds::ENDER_PEARL, 0, "Ender Pearl")); - self::register(new ExperienceBottle(ItemIds::EXPERIENCE_BOTTLE, 0, "Bottle o' Enchanting")); - self::register(new Fertilizer(ItemIds::DYE, 15, "Bone Meal")); - self::register(new FishingRod(ItemIds::FISHING_ROD, 0, "Fishing Rod")); - self::register(new FlintSteel(ItemIds::FLINT_STEEL, 0, "Flint and Steel")); - self::register(new GlassBottle(ItemIds::GLASS_BOTTLE, 0, "Glass Bottle")); - self::register(new GoldenApple(ItemIds::GOLDEN_APPLE, 0, "Golden Apple")); - self::register(new GoldenAppleEnchanted(ItemIds::ENCHANTED_GOLDEN_APPLE, 0, "Enchanted Golden Apple")); - self::register(new GoldenCarrot(ItemIds::GOLDEN_CARROT, 0, "Golden Carrot")); - self::register(new Item(ItemIds::BLAZE_POWDER, 0, "Blaze Powder")); - self::register(new Item(ItemIds::BLEACH, 0, "Bleach")); //EDU - self::register(new Item(ItemIds::BONE, 0, "Bone")); - self::register(new Item(ItemIds::BRICK, 0, "Brick")); - self::register(new Item(ItemIds::CHORUS_FRUIT_POPPED, 0, "Popped Chorus Fruit")); - self::register(new Item(ItemIds::CLAY_BALL, 0, "Clay")); - self::register(new Item(ItemIds::COMPOUND, 0, "Salt")); - self::register(new Item(ItemIds::COMPOUND, 1, "Sodium Oxide")); - self::register(new Item(ItemIds::COMPOUND, 2, "Sodium Hydroxide")); - self::register(new Item(ItemIds::COMPOUND, 3, "Magnesium Nitrate")); - self::register(new Item(ItemIds::COMPOUND, 4, "Iron Sulphide")); - self::register(new Item(ItemIds::COMPOUND, 5, "Lithium Hydride")); - self::register(new Item(ItemIds::COMPOUND, 6, "Sodium Hydride")); - self::register(new Item(ItemIds::COMPOUND, 7, "Calcium Bromide")); - self::register(new Item(ItemIds::COMPOUND, 8, "Magnesium Oxide")); - self::register(new Item(ItemIds::COMPOUND, 9, "Sodium Acetate")); - self::register(new Item(ItemIds::COMPOUND, 10, "Luminol")); - self::register(new Item(ItemIds::COMPOUND, 11, "Charcoal")); //??? maybe bug - self::register(new Item(ItemIds::COMPOUND, 12, "Sugar")); //??? maybe bug - self::register(new Item(ItemIds::COMPOUND, 13, "Aluminium Oxide")); - self::register(new Item(ItemIds::COMPOUND, 14, "Boron Trioxide")); - self::register(new Item(ItemIds::COMPOUND, 15, "Soap")); - self::register(new Item(ItemIds::COMPOUND, 16, "Polyethylene")); - self::register(new Item(ItemIds::COMPOUND, 17, "Rubbish")); - self::register(new Item(ItemIds::COMPOUND, 18, "Magnesium Salts")); - self::register(new Item(ItemIds::COMPOUND, 19, "Sulphate")); - self::register(new Item(ItemIds::COMPOUND, 20, "Barium Sulphate")); - self::register(new Item(ItemIds::COMPOUND, 21, "Potassium Chloride")); - self::register(new Item(ItemIds::COMPOUND, 22, "Mercuric Chloride")); - self::register(new Item(ItemIds::COMPOUND, 23, "Cerium Chloride")); - self::register(new Item(ItemIds::COMPOUND, 24, "Tungsten Chloride")); - self::register(new Item(ItemIds::COMPOUND, 25, "Calcium Chloride")); - self::register(new Item(ItemIds::COMPOUND, 26, "Water")); //??? - self::register(new Item(ItemIds::COMPOUND, 27, "Glue")); - self::register(new Item(ItemIds::COMPOUND, 28, "Hypochlorite")); - self::register(new Item(ItemIds::COMPOUND, 29, "Crude Oil")); - self::register(new Item(ItemIds::COMPOUND, 30, "Latex")); - self::register(new Item(ItemIds::COMPOUND, 31, "Potassium Iodide")); - self::register(new Item(ItemIds::COMPOUND, 32, "Sodium Fluoride")); - self::register(new Item(ItemIds::COMPOUND, 33, "Benzene")); - self::register(new Item(ItemIds::COMPOUND, 34, "Ink")); - self::register(new Item(ItemIds::COMPOUND, 35, "Hydrogen Peroxide")); - self::register(new Item(ItemIds::COMPOUND, 36, "Ammonia")); - self::register(new Item(ItemIds::COMPOUND, 37, "Sodium Hypochlorite")); - self::register(new Item(ItemIds::DIAMOND, 0, "Diamond")); - self::register(new Item(ItemIds::DRAGON_BREATH, 0, "Dragon's Breath")); - self::register(new Item(ItemIds::DYE, 0, "Ink Sac")); - self::register(new Item(ItemIds::DYE, 4, "Lapis Lazuli")); - self::register(new Item(ItemIds::EMERALD, 0, "Emerald")); - self::register(new Item(ItemIds::FEATHER, 0, "Feather")); - self::register(new Item(ItemIds::FERMENTED_SPIDER_EYE, 0, "Fermented Spider Eye")); - self::register(new Item(ItemIds::FLINT, 0, "Flint")); - self::register(new Item(ItemIds::GHAST_TEAR, 0, "Ghast Tear")); - self::register(new Item(ItemIds::GLISTERING_MELON, 0, "Glistering Melon")); - self::register(new Item(ItemIds::GLOWSTONE_DUST, 0, "Glowstone Dust")); - self::register(new Item(ItemIds::GOLD_INGOT, 0, "Gold Ingot")); - self::register(new Item(ItemIds::GOLD_NUGGET, 0, "Gold Nugget")); - self::register(new Item(ItemIds::GUNPOWDER, 0, "Gunpowder")); - self::register(new Item(ItemIds::HEART_OF_THE_SEA, 0, "Heart of the Sea")); - self::register(new Item(ItemIds::IRON_INGOT, 0, "Iron Ingot")); - self::register(new Item(ItemIds::IRON_NUGGET, 0, "Iron Nugget")); - self::register(new Item(ItemIds::LEATHER, 0, "Leather")); - self::register(new Item(ItemIds::MAGMA_CREAM, 0, "Magma Cream")); - self::register(new Item(ItemIds::NAUTILUS_SHELL, 0, "Nautilus Shell")); - self::register(new Item(ItemIds::NETHER_BRICK, 0, "Nether Brick")); - self::register(new Item(ItemIds::NETHER_QUARTZ, 0, "Nether Quartz")); - self::register(new Item(ItemIds::NETHER_STAR, 0, "Nether Star")); - self::register(new Item(ItemIds::PAPER, 0, "Paper")); - self::register(new Item(ItemIds::PRISMARINE_CRYSTALS, 0, "Prismarine Crystals")); - self::register(new Item(ItemIds::PRISMARINE_SHARD, 0, "Prismarine Shard")); - self::register(new Item(ItemIds::RABBIT_FOOT, 0, "Rabbit's Foot")); - self::register(new Item(ItemIds::RABBIT_HIDE, 0, "Rabbit Hide")); - self::register(new Item(ItemIds::SHULKER_SHELL, 0, "Shulker Shell")); - self::register(new Item(ItemIds::SLIME_BALL, 0, "Slimeball")); - self::register(new Item(ItemIds::SUGAR, 0, "Sugar")); - self::register(new Item(ItemIds::TURTLE_SHELL_PIECE, 0, "Scute")); - self::register(new Item(ItemIds::WHEAT, 0, "Wheat")); - self::register(new ItemBlock(BlockLegacyIds::ACACIA_DOOR_BLOCK, 0, ItemIds::ACACIA_DOOR)); - self::register(new ItemBlock(BlockLegacyIds::BIRCH_DOOR_BLOCK, 0, ItemIds::BIRCH_DOOR)); - self::register(new ItemBlock(BlockLegacyIds::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND)); - self::register(new ItemBlock(BlockLegacyIds::CAKE_BLOCK, 0, ItemIds::CAKE)); - self::register(new ItemBlock(BlockLegacyIds::CAULDRON_BLOCK, 0, ItemIds::CAULDRON)); - self::register(new ItemBlock(BlockLegacyIds::COMPARATOR_BLOCK, 0, ItemIds::COMPARATOR)); - self::register(new ItemBlock(BlockLegacyIds::DARK_OAK_DOOR_BLOCK, 0, ItemIds::DARK_OAK_DOOR)); - self::register(new ItemBlock(BlockLegacyIds::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT)); - self::register(new ItemBlock(BlockLegacyIds::HOPPER_BLOCK, 0, ItemIds::HOPPER)); - self::register(new ItemBlock(BlockLegacyIds::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR)); - self::register(new ItemBlock(BlockLegacyIds::ITEM_FRAME_BLOCK, 0, ItemIds::ITEM_FRAME)); - self::register(new ItemBlock(BlockLegacyIds::JUNGLE_DOOR_BLOCK, 0, ItemIds::JUNGLE_DOOR)); - self::register(new ItemBlock(BlockLegacyIds::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART)); - self::register(new ItemBlock(BlockLegacyIds::OAK_DOOR_BLOCK, 0, ItemIds::OAK_DOOR)); - self::register(new ItemBlock(BlockLegacyIds::REPEATER_BLOCK, 0, ItemIds::REPEATER)); - self::register(new ItemBlock(BlockLegacyIds::SPRUCE_DOOR_BLOCK, 0, ItemIds::SPRUCE_DOOR)); - self::register(new ItemBlock(BlockLegacyIds::SUGARCANE_BLOCK, 0, ItemIds::SUGARCANE)); + $this->register(new BakedPotato(ItemIds::BAKED_POTATO, 0, "Baked Potato")); + $this->register(new Beetroot(ItemIds::BEETROOT, 0, "Beetroot")); + $this->register(new BeetrootSeeds(ItemIds::BEETROOT_SEEDS, 0, "Beetroot Seeds")); + $this->register(new BeetrootSoup(ItemIds::BEETROOT_SOUP, 0, "Beetroot Soup")); + $this->register(new BlazeRod(ItemIds::BLAZE_ROD, 0, "Blaze Rod")); + $this->register(new Book(ItemIds::BOOK, 0, "Book")); + $this->register(new Bow(ItemIds::BOW, 0, "Bow")); + $this->register(new Bowl(ItemIds::BOWL, 0, "Bowl")); + $this->register(new Bread(ItemIds::BREAD, 0, "Bread")); + $this->register(new Bucket(ItemIds::BUCKET, 0, "Bucket")); + $this->register(new Carrot(ItemIds::CARROT, 0, "Carrot")); + $this->register(new ChorusFruit(ItemIds::CHORUS_FRUIT, 0, "Chorus Fruit")); + $this->register(new Clock(ItemIds::CLOCK, 0, "Clock")); + $this->register(new Clownfish(ItemIds::CLOWNFISH, 0, "Clownfish")); + $this->register(new Coal(ItemIds::COAL, 0, "Coal")); + $this->register(new Coal(ItemIds::COAL, 1, "Charcoal")); + $this->register(new CocoaBeans(ItemIds::DYE, 3, "Cocoa Beans")); + $this->register(new Compass(ItemIds::COMPASS, 0, "Compass")); + $this->register(new CookedChicken(ItemIds::COOKED_CHICKEN, 0, "Cooked Chicken")); + $this->register(new CookedFish(ItemIds::COOKED_FISH, 0, "Cooked Fish")); + $this->register(new CookedMutton(ItemIds::COOKED_MUTTON, 0, "Cooked Mutton")); + $this->register(new CookedPorkchop(ItemIds::COOKED_PORKCHOP, 0, "Cooked Porkchop")); + $this->register(new CookedRabbit(ItemIds::COOKED_RABBIT, 0, "Cooked Rabbit")); + $this->register(new CookedSalmon(ItemIds::COOKED_SALMON, 0, "Cooked Salmon")); + $this->register(new Cookie(ItemIds::COOKIE, 0, "Cookie")); + $this->register(new DriedKelp(ItemIds::DRIED_KELP, 0, "Dried Kelp")); + $this->register(new Egg(ItemIds::EGG, 0, "Egg")); + $this->register(new EnderPearl(ItemIds::ENDER_PEARL, 0, "Ender Pearl")); + $this->register(new ExperienceBottle(ItemIds::EXPERIENCE_BOTTLE, 0, "Bottle o' Enchanting")); + $this->register(new Fertilizer(ItemIds::DYE, 15, "Bone Meal")); + $this->register(new FishingRod(ItemIds::FISHING_ROD, 0, "Fishing Rod")); + $this->register(new FlintSteel(ItemIds::FLINT_STEEL, 0, "Flint and Steel")); + $this->register(new GlassBottle(ItemIds::GLASS_BOTTLE, 0, "Glass Bottle")); + $this->register(new GoldenApple(ItemIds::GOLDEN_APPLE, 0, "Golden Apple")); + $this->register(new GoldenAppleEnchanted(ItemIds::ENCHANTED_GOLDEN_APPLE, 0, "Enchanted Golden Apple")); + $this->register(new GoldenCarrot(ItemIds::GOLDEN_CARROT, 0, "Golden Carrot")); + $this->register(new Item(ItemIds::BLAZE_POWDER, 0, "Blaze Powder")); + $this->register(new Item(ItemIds::BLEACH, 0, "Bleach")); //EDU + $this->register(new Item(ItemIds::BONE, 0, "Bone")); + $this->register(new Item(ItemIds::BRICK, 0, "Brick")); + $this->register(new Item(ItemIds::CHORUS_FRUIT_POPPED, 0, "Popped Chorus Fruit")); + $this->register(new Item(ItemIds::CLAY_BALL, 0, "Clay")); + $this->register(new Item(ItemIds::COMPOUND, 0, "Salt")); + $this->register(new Item(ItemIds::COMPOUND, 1, "Sodium Oxide")); + $this->register(new Item(ItemIds::COMPOUND, 2, "Sodium Hydroxide")); + $this->register(new Item(ItemIds::COMPOUND, 3, "Magnesium Nitrate")); + $this->register(new Item(ItemIds::COMPOUND, 4, "Iron Sulphide")); + $this->register(new Item(ItemIds::COMPOUND, 5, "Lithium Hydride")); + $this->register(new Item(ItemIds::COMPOUND, 6, "Sodium Hydride")); + $this->register(new Item(ItemIds::COMPOUND, 7, "Calcium Bromide")); + $this->register(new Item(ItemIds::COMPOUND, 8, "Magnesium Oxide")); + $this->register(new Item(ItemIds::COMPOUND, 9, "Sodium Acetate")); + $this->register(new Item(ItemIds::COMPOUND, 10, "Luminol")); + $this->register(new Item(ItemIds::COMPOUND, 11, "Charcoal")); //??? maybe bug + $this->register(new Item(ItemIds::COMPOUND, 12, "Sugar")); //??? maybe bug + $this->register(new Item(ItemIds::COMPOUND, 13, "Aluminium Oxide")); + $this->register(new Item(ItemIds::COMPOUND, 14, "Boron Trioxide")); + $this->register(new Item(ItemIds::COMPOUND, 15, "Soap")); + $this->register(new Item(ItemIds::COMPOUND, 16, "Polyethylene")); + $this->register(new Item(ItemIds::COMPOUND, 17, "Rubbish")); + $this->register(new Item(ItemIds::COMPOUND, 18, "Magnesium Salts")); + $this->register(new Item(ItemIds::COMPOUND, 19, "Sulphate")); + $this->register(new Item(ItemIds::COMPOUND, 20, "Barium Sulphate")); + $this->register(new Item(ItemIds::COMPOUND, 21, "Potassium Chloride")); + $this->register(new Item(ItemIds::COMPOUND, 22, "Mercuric Chloride")); + $this->register(new Item(ItemIds::COMPOUND, 23, "Cerium Chloride")); + $this->register(new Item(ItemIds::COMPOUND, 24, "Tungsten Chloride")); + $this->register(new Item(ItemIds::COMPOUND, 25, "Calcium Chloride")); + $this->register(new Item(ItemIds::COMPOUND, 26, "Water")); //??? + $this->register(new Item(ItemIds::COMPOUND, 27, "Glue")); + $this->register(new Item(ItemIds::COMPOUND, 28, "Hypochlorite")); + $this->register(new Item(ItemIds::COMPOUND, 29, "Crude Oil")); + $this->register(new Item(ItemIds::COMPOUND, 30, "Latex")); + $this->register(new Item(ItemIds::COMPOUND, 31, "Potassium Iodide")); + $this->register(new Item(ItemIds::COMPOUND, 32, "Sodium Fluoride")); + $this->register(new Item(ItemIds::COMPOUND, 33, "Benzene")); + $this->register(new Item(ItemIds::COMPOUND, 34, "Ink")); + $this->register(new Item(ItemIds::COMPOUND, 35, "Hydrogen Peroxide")); + $this->register(new Item(ItemIds::COMPOUND, 36, "Ammonia")); + $this->register(new Item(ItemIds::COMPOUND, 37, "Sodium Hypochlorite")); + $this->register(new Item(ItemIds::DIAMOND, 0, "Diamond")); + $this->register(new Item(ItemIds::DRAGON_BREATH, 0, "Dragon's Breath")); + $this->register(new Item(ItemIds::DYE, 0, "Ink Sac")); + $this->register(new Item(ItemIds::DYE, 4, "Lapis Lazuli")); + $this->register(new Item(ItemIds::EMERALD, 0, "Emerald")); + $this->register(new Item(ItemIds::FEATHER, 0, "Feather")); + $this->register(new Item(ItemIds::FERMENTED_SPIDER_EYE, 0, "Fermented Spider Eye")); + $this->register(new Item(ItemIds::FLINT, 0, "Flint")); + $this->register(new Item(ItemIds::GHAST_TEAR, 0, "Ghast Tear")); + $this->register(new Item(ItemIds::GLISTERING_MELON, 0, "Glistering Melon")); + $this->register(new Item(ItemIds::GLOWSTONE_DUST, 0, "Glowstone Dust")); + $this->register(new Item(ItemIds::GOLD_INGOT, 0, "Gold Ingot")); + $this->register(new Item(ItemIds::GOLD_NUGGET, 0, "Gold Nugget")); + $this->register(new Item(ItemIds::GUNPOWDER, 0, "Gunpowder")); + $this->register(new Item(ItemIds::HEART_OF_THE_SEA, 0, "Heart of the Sea")); + $this->register(new Item(ItemIds::IRON_INGOT, 0, "Iron Ingot")); + $this->register(new Item(ItemIds::IRON_NUGGET, 0, "Iron Nugget")); + $this->register(new Item(ItemIds::LEATHER, 0, "Leather")); + $this->register(new Item(ItemIds::MAGMA_CREAM, 0, "Magma Cream")); + $this->register(new Item(ItemIds::NAUTILUS_SHELL, 0, "Nautilus Shell")); + $this->register(new Item(ItemIds::NETHER_BRICK, 0, "Nether Brick")); + $this->register(new Item(ItemIds::NETHER_QUARTZ, 0, "Nether Quartz")); + $this->register(new Item(ItemIds::NETHER_STAR, 0, "Nether Star")); + $this->register(new Item(ItemIds::PAPER, 0, "Paper")); + $this->register(new Item(ItemIds::PRISMARINE_CRYSTALS, 0, "Prismarine Crystals")); + $this->register(new Item(ItemIds::PRISMARINE_SHARD, 0, "Prismarine Shard")); + $this->register(new Item(ItemIds::RABBIT_FOOT, 0, "Rabbit's Foot")); + $this->register(new Item(ItemIds::RABBIT_HIDE, 0, "Rabbit Hide")); + $this->register(new Item(ItemIds::SHULKER_SHELL, 0, "Shulker Shell")); + $this->register(new Item(ItemIds::SLIME_BALL, 0, "Slimeball")); + $this->register(new Item(ItemIds::SUGAR, 0, "Sugar")); + $this->register(new Item(ItemIds::TURTLE_SHELL_PIECE, 0, "Scute")); + $this->register(new Item(ItemIds::WHEAT, 0, "Wheat")); + $this->register(new ItemBlock(BlockLegacyIds::ACACIA_DOOR_BLOCK, 0, ItemIds::ACACIA_DOOR)); + $this->register(new ItemBlock(BlockLegacyIds::BIRCH_DOOR_BLOCK, 0, ItemIds::BIRCH_DOOR)); + $this->register(new ItemBlock(BlockLegacyIds::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND)); + $this->register(new ItemBlock(BlockLegacyIds::CAKE_BLOCK, 0, ItemIds::CAKE)); + $this->register(new ItemBlock(BlockLegacyIds::CAULDRON_BLOCK, 0, ItemIds::CAULDRON)); + $this->register(new ItemBlock(BlockLegacyIds::COMPARATOR_BLOCK, 0, ItemIds::COMPARATOR)); + $this->register(new ItemBlock(BlockLegacyIds::DARK_OAK_DOOR_BLOCK, 0, ItemIds::DARK_OAK_DOOR)); + $this->register(new ItemBlock(BlockLegacyIds::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT)); + $this->register(new ItemBlock(BlockLegacyIds::HOPPER_BLOCK, 0, ItemIds::HOPPER)); + $this->register(new ItemBlock(BlockLegacyIds::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR)); + $this->register(new ItemBlock(BlockLegacyIds::ITEM_FRAME_BLOCK, 0, ItemIds::ITEM_FRAME)); + $this->register(new ItemBlock(BlockLegacyIds::JUNGLE_DOOR_BLOCK, 0, ItemIds::JUNGLE_DOOR)); + $this->register(new ItemBlock(BlockLegacyIds::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART)); + $this->register(new ItemBlock(BlockLegacyIds::OAK_DOOR_BLOCK, 0, ItemIds::OAK_DOOR)); + $this->register(new ItemBlock(BlockLegacyIds::REPEATER_BLOCK, 0, ItemIds::REPEATER)); + $this->register(new ItemBlock(BlockLegacyIds::SPRUCE_DOOR_BLOCK, 0, ItemIds::SPRUCE_DOOR)); + $this->register(new ItemBlock(BlockLegacyIds::SUGARCANE_BLOCK, 0, ItemIds::SUGARCANE)); //TODO: fix metadata for buckets with still liquid in them //the meta values are intentionally hardcoded because block IDs will change in the future - self::register(new LiquidBucket(ItemIds::BUCKET, 8, "Water Bucket", VanillaBlocks::WATER())); - self::register(new LiquidBucket(ItemIds::BUCKET, 10, "Lava Bucket", VanillaBlocks::LAVA())); - self::register(new Melon(ItemIds::MELON, 0, "Melon")); - self::register(new MelonSeeds(ItemIds::MELON_SEEDS, 0, "Melon Seeds")); - self::register(new MilkBucket(ItemIds::BUCKET, 1, "Milk Bucket")); - self::register(new Minecart(ItemIds::MINECART, 0, "Minecart")); - self::register(new MushroomStew(ItemIds::MUSHROOM_STEW, 0, "Mushroom Stew")); - self::register(new PaintingItem(ItemIds::PAINTING, 0, "Painting")); - self::register(new PoisonousPotato(ItemIds::POISONOUS_POTATO, 0, "Poisonous Potato")); - self::register(new Potato(ItemIds::POTATO, 0, "Potato")); - self::register(new Pufferfish(ItemIds::PUFFERFISH, 0, "Pufferfish")); - self::register(new PumpkinPie(ItemIds::PUMPKIN_PIE, 0, "Pumpkin Pie")); - self::register(new PumpkinSeeds(ItemIds::PUMPKIN_SEEDS, 0, "Pumpkin Seeds")); - self::register(new RabbitStew(ItemIds::RABBIT_STEW, 0, "Rabbit Stew")); - self::register(new RawBeef(ItemIds::RAW_BEEF, 0, "Raw Beef")); - self::register(new RawChicken(ItemIds::RAW_CHICKEN, 0, "Raw Chicken")); - self::register(new RawFish(ItemIds::RAW_FISH, 0, "Raw Fish")); - self::register(new RawMutton(ItemIds::RAW_MUTTON, 0, "Raw Mutton")); - self::register(new RawPorkchop(ItemIds::RAW_PORKCHOP, 0, "Raw Porkchop")); - self::register(new RawRabbit(ItemIds::RAW_RABBIT, 0, "Raw Rabbit")); - self::register(new RawSalmon(ItemIds::RAW_SALMON, 0, "Raw Salmon")); - self::register(new Redstone(ItemIds::REDSTONE, 0, "Redstone")); - self::register(new RottenFlesh(ItemIds::ROTTEN_FLESH, 0, "Rotten Flesh")); - self::register(new Shears(ItemIds::SHEARS, 0, "Shears")); - self::register(new Sign(BlockLegacyIds::STANDING_SIGN, 0, ItemIds::SIGN)); - self::register(new Sign(BlockLegacyIds::SPRUCE_STANDING_SIGN, 0, ItemIds::SPRUCE_SIGN)); - self::register(new Sign(BlockLegacyIds::BIRCH_STANDING_SIGN, 0, ItemIds::BIRCH_SIGN)); - self::register(new Sign(BlockLegacyIds::JUNGLE_STANDING_SIGN, 0, ItemIds::JUNGLE_SIGN)); - self::register(new Sign(BlockLegacyIds::ACACIA_STANDING_SIGN, 0, ItemIds::ACACIA_SIGN)); - self::register(new Sign(BlockLegacyIds::DARKOAK_STANDING_SIGN, 0, ItemIds::DARKOAK_SIGN)); - self::register(new Snowball(ItemIds::SNOWBALL, 0, "Snowball")); - self::register(new SpiderEye(ItemIds::SPIDER_EYE, 0, "Spider Eye")); - self::register(new Steak(ItemIds::STEAK, 0, "Steak")); - self::register(new Stick(ItemIds::STICK, 0, "Stick")); - self::register(new StringItem(ItemIds::STRING, 0, "String")); - self::register(new Totem(ItemIds::TOTEM, 0, "Totem of Undying")); - self::register(new WheatSeeds(ItemIds::WHEAT_SEEDS, 0, "Wheat Seeds")); - self::register(new WritableBook(ItemIds::WRITABLE_BOOK, 0, "Book & Quill")); - self::register(new WrittenBook(ItemIds::WRITTEN_BOOK, 0, "Written Book")); + $this->register(new LiquidBucket(ItemIds::BUCKET, 8, "Water Bucket", VanillaBlocks::WATER())); + $this->register(new LiquidBucket(ItemIds::BUCKET, 10, "Lava Bucket", VanillaBlocks::LAVA())); + $this->register(new Melon(ItemIds::MELON, 0, "Melon")); + $this->register(new MelonSeeds(ItemIds::MELON_SEEDS, 0, "Melon Seeds")); + $this->register(new MilkBucket(ItemIds::BUCKET, 1, "Milk Bucket")); + $this->register(new Minecart(ItemIds::MINECART, 0, "Minecart")); + $this->register(new MushroomStew(ItemIds::MUSHROOM_STEW, 0, "Mushroom Stew")); + $this->register(new PaintingItem(ItemIds::PAINTING, 0, "Painting")); + $this->register(new PoisonousPotato(ItemIds::POISONOUS_POTATO, 0, "Poisonous Potato")); + $this->register(new Potato(ItemIds::POTATO, 0, "Potato")); + $this->register(new Pufferfish(ItemIds::PUFFERFISH, 0, "Pufferfish")); + $this->register(new PumpkinPie(ItemIds::PUMPKIN_PIE, 0, "Pumpkin Pie")); + $this->register(new PumpkinSeeds(ItemIds::PUMPKIN_SEEDS, 0, "Pumpkin Seeds")); + $this->register(new RabbitStew(ItemIds::RABBIT_STEW, 0, "Rabbit Stew")); + $this->register(new RawBeef(ItemIds::RAW_BEEF, 0, "Raw Beef")); + $this->register(new RawChicken(ItemIds::RAW_CHICKEN, 0, "Raw Chicken")); + $this->register(new RawFish(ItemIds::RAW_FISH, 0, "Raw Fish")); + $this->register(new RawMutton(ItemIds::RAW_MUTTON, 0, "Raw Mutton")); + $this->register(new RawPorkchop(ItemIds::RAW_PORKCHOP, 0, "Raw Porkchop")); + $this->register(new RawRabbit(ItemIds::RAW_RABBIT, 0, "Raw Rabbit")); + $this->register(new RawSalmon(ItemIds::RAW_SALMON, 0, "Raw Salmon")); + $this->register(new Redstone(ItemIds::REDSTONE, 0, "Redstone")); + $this->register(new RottenFlesh(ItemIds::ROTTEN_FLESH, 0, "Rotten Flesh")); + $this->register(new Shears(ItemIds::SHEARS, 0, "Shears")); + $this->register(new Sign(BlockLegacyIds::STANDING_SIGN, 0, ItemIds::SIGN)); + $this->register(new Sign(BlockLegacyIds::SPRUCE_STANDING_SIGN, 0, ItemIds::SPRUCE_SIGN)); + $this->register(new Sign(BlockLegacyIds::BIRCH_STANDING_SIGN, 0, ItemIds::BIRCH_SIGN)); + $this->register(new Sign(BlockLegacyIds::JUNGLE_STANDING_SIGN, 0, ItemIds::JUNGLE_SIGN)); + $this->register(new Sign(BlockLegacyIds::ACACIA_STANDING_SIGN, 0, ItemIds::ACACIA_SIGN)); + $this->register(new Sign(BlockLegacyIds::DARKOAK_STANDING_SIGN, 0, ItemIds::DARKOAK_SIGN)); + $this->register(new Snowball(ItemIds::SNOWBALL, 0, "Snowball")); + $this->register(new SpiderEye(ItemIds::SPIDER_EYE, 0, "Spider Eye")); + $this->register(new Steak(ItemIds::STEAK, 0, "Steak")); + $this->register(new Stick(ItemIds::STICK, 0, "Stick")); + $this->register(new StringItem(ItemIds::STRING, 0, "String")); + $this->register(new Totem(ItemIds::TOTEM, 0, "Totem of Undying")); + $this->register(new WheatSeeds(ItemIds::WHEAT_SEEDS, 0, "Wheat Seeds")); + $this->register(new WritableBook(ItemIds::WRITABLE_BOOK, 0, "Book & Quill")); + $this->register(new WrittenBook(ItemIds::WRITTEN_BOOK, 0, "Written Book")); foreach(SkullType::getAll() as $skullType){ - self::register(new Skull(ItemIds::SKULL, $skullType->getMagicNumber(), $skullType->getDisplayName(), $skullType)); + $this->register(new Skull(ItemIds::SKULL, $skullType->getMagicNumber(), $skullType->getDisplayName(), $skullType)); } $dyeMap = [ @@ -247,25 +254,25 @@ class ItemFactory{ foreach(DyeColor::getAll() as $color){ //TODO: use colour object directly //TODO: add interface to dye-colour objects - self::register(new Dye(ItemIds::DYE, $dyeMap[$color->id()] ?? $color->getInvertedMagicNumber(), $color->getDisplayName() . " Dye", $color)); - self::register(new Bed(ItemIds::BED, $color->getMagicNumber(), $color->getDisplayName() . " Bed", $color)); - self::register(new Banner(ItemIds::BANNER, $color->getInvertedMagicNumber(), $color->getDisplayName() . " Banner", $color)); + $this->register(new Dye(ItemIds::DYE, $dyeMap[$color->id()] ?? $color->getInvertedMagicNumber(), $color->getDisplayName() . " Dye", $color)); + $this->register(new Bed(ItemIds::BED, $color->getMagicNumber(), $color->getDisplayName() . " Bed", $color)); + $this->register(new Banner(ItemIds::BANNER, $color->getInvertedMagicNumber(), $color->getDisplayName() . " Banner", $color)); } foreach(Potion::ALL as $type){ - self::register(new Potion(ItemIds::POTION, $type, "Potion")); - self::register(new SplashPotion(ItemIds::SPLASH_POTION, $type, "Splash Potion")); + $this->register(new Potion(ItemIds::POTION, $type, "Potion")); + $this->register(new SplashPotion(ItemIds::SPLASH_POTION, $type, "Splash Potion")); } foreach(EntityFactory::getKnownTypes() as $className){ /** @var Living|string $className */ if(is_a($className, Living::class, true) and $className::NETWORK_ID !== -1){ - self::register(new SpawnEgg(ItemIds::SPAWN_EGG, $className::NETWORK_ID, "Spawn Egg", $className)); + $this->register(new SpawnEgg(ItemIds::SPAWN_EGG, $className::NETWORK_ID, "Spawn Egg", $className)); } } foreach(TreeType::getAll() as $type){ - self::register(new Boat(ItemIds::BOAT, $type->getMagicNumber(), $type->getDisplayName() . " Boat", $type)); + $this->register(new Boat(ItemIds::BOAT, $type->getMagicNumber(), $type->getDisplayName() . " Boat", $type)); } //region --- auto-generated TODOs --- @@ -323,55 +330,55 @@ class ItemFactory{ //endregion } - private static function registerTierToolItems() : void{ - self::register(new Axe(ItemIds::DIAMOND_AXE, "Diamond Axe", ToolTier::DIAMOND())); - self::register(new Axe(ItemIds::GOLDEN_AXE, "Golden Axe", ToolTier::GOLD())); - self::register(new Axe(ItemIds::IRON_AXE, "Iron Axe", ToolTier::IRON())); - self::register(new Axe(ItemIds::STONE_AXE, "Stone Axe", ToolTier::STONE())); - self::register(new Axe(ItemIds::WOODEN_AXE, "Wooden Axe", ToolTier::WOOD())); - self::register(new Hoe(ItemIds::DIAMOND_HOE, "Diamond Hoe", ToolTier::DIAMOND())); - self::register(new Hoe(ItemIds::GOLDEN_HOE, "Golden Hoe", ToolTier::GOLD())); - self::register(new Hoe(ItemIds::IRON_HOE, "Iron Hoe", ToolTier::IRON())); - self::register(new Hoe(ItemIds::STONE_HOE, "Stone Hoe", ToolTier::STONE())); - self::register(new Hoe(ItemIds::WOODEN_HOE, "Wooden Hoe", ToolTier::WOOD())); - self::register(new Pickaxe(ItemIds::DIAMOND_PICKAXE, "Diamond Pickaxe", ToolTier::DIAMOND())); - self::register(new Pickaxe(ItemIds::GOLDEN_PICKAXE, "Golden Pickaxe", ToolTier::GOLD())); - self::register(new Pickaxe(ItemIds::IRON_PICKAXE, "Iron Pickaxe", ToolTier::IRON())); - self::register(new Pickaxe(ItemIds::STONE_PICKAXE, "Stone Pickaxe", ToolTier::STONE())); - self::register(new Pickaxe(ItemIds::WOODEN_PICKAXE, "Wooden Pickaxe", ToolTier::WOOD())); - self::register(new Shovel(ItemIds::DIAMOND_SHOVEL, "Diamond Shovel", ToolTier::DIAMOND())); - self::register(new Shovel(ItemIds::GOLDEN_SHOVEL, "Golden Shovel", ToolTier::GOLD())); - self::register(new Shovel(ItemIds::IRON_SHOVEL, "Iron Shovel", ToolTier::IRON())); - self::register(new Shovel(ItemIds::STONE_SHOVEL, "Stone Shovel", ToolTier::STONE())); - self::register(new Shovel(ItemIds::WOODEN_SHOVEL, "Wooden Shovel", ToolTier::WOOD())); - self::register(new Sword(ItemIds::DIAMOND_SWORD, "Diamond Sword", ToolTier::DIAMOND())); - self::register(new Sword(ItemIds::GOLDEN_SWORD, "Golden Sword", ToolTier::GOLD())); - self::register(new Sword(ItemIds::IRON_SWORD, "Iron Sword", ToolTier::IRON())); - self::register(new Sword(ItemIds::STONE_SWORD, "Stone Sword", ToolTier::STONE())); - self::register(new Sword(ItemIds::WOODEN_SWORD, "Wooden Sword", ToolTier::WOOD())); + private function registerTierToolItems() : void{ + $this->register(new Axe(ItemIds::DIAMOND_AXE, "Diamond Axe", ToolTier::DIAMOND())); + $this->register(new Axe(ItemIds::GOLDEN_AXE, "Golden Axe", ToolTier::GOLD())); + $this->register(new Axe(ItemIds::IRON_AXE, "Iron Axe", ToolTier::IRON())); + $this->register(new Axe(ItemIds::STONE_AXE, "Stone Axe", ToolTier::STONE())); + $this->register(new Axe(ItemIds::WOODEN_AXE, "Wooden Axe", ToolTier::WOOD())); + $this->register(new Hoe(ItemIds::DIAMOND_HOE, "Diamond Hoe", ToolTier::DIAMOND())); + $this->register(new Hoe(ItemIds::GOLDEN_HOE, "Golden Hoe", ToolTier::GOLD())); + $this->register(new Hoe(ItemIds::IRON_HOE, "Iron Hoe", ToolTier::IRON())); + $this->register(new Hoe(ItemIds::STONE_HOE, "Stone Hoe", ToolTier::STONE())); + $this->register(new Hoe(ItemIds::WOODEN_HOE, "Wooden Hoe", ToolTier::WOOD())); + $this->register(new Pickaxe(ItemIds::DIAMOND_PICKAXE, "Diamond Pickaxe", ToolTier::DIAMOND())); + $this->register(new Pickaxe(ItemIds::GOLDEN_PICKAXE, "Golden Pickaxe", ToolTier::GOLD())); + $this->register(new Pickaxe(ItemIds::IRON_PICKAXE, "Iron Pickaxe", ToolTier::IRON())); + $this->register(new Pickaxe(ItemIds::STONE_PICKAXE, "Stone Pickaxe", ToolTier::STONE())); + $this->register(new Pickaxe(ItemIds::WOODEN_PICKAXE, "Wooden Pickaxe", ToolTier::WOOD())); + $this->register(new Shovel(ItemIds::DIAMOND_SHOVEL, "Diamond Shovel", ToolTier::DIAMOND())); + $this->register(new Shovel(ItemIds::GOLDEN_SHOVEL, "Golden Shovel", ToolTier::GOLD())); + $this->register(new Shovel(ItemIds::IRON_SHOVEL, "Iron Shovel", ToolTier::IRON())); + $this->register(new Shovel(ItemIds::STONE_SHOVEL, "Stone Shovel", ToolTier::STONE())); + $this->register(new Shovel(ItemIds::WOODEN_SHOVEL, "Wooden Shovel", ToolTier::WOOD())); + $this->register(new Sword(ItemIds::DIAMOND_SWORD, "Diamond Sword", ToolTier::DIAMOND())); + $this->register(new Sword(ItemIds::GOLDEN_SWORD, "Golden Sword", ToolTier::GOLD())); + $this->register(new Sword(ItemIds::IRON_SWORD, "Iron Sword", ToolTier::IRON())); + $this->register(new Sword(ItemIds::STONE_SWORD, "Stone Sword", ToolTier::STONE())); + $this->register(new Sword(ItemIds::WOODEN_SWORD, "Wooden Sword", ToolTier::WOOD())); } - private static function registerArmorItems() : void{ - self::register(new Armor(ItemIds::CHAIN_BOOTS, 0, "Chainmail Boots", new ArmorTypeInfo(1, 196, ArmorInventory::SLOT_FEET))); - self::register(new Armor(ItemIds::DIAMOND_BOOTS, 0, "Diamond Boots", new ArmorTypeInfo(3, 430, ArmorInventory::SLOT_FEET))); - self::register(new Armor(ItemIds::GOLDEN_BOOTS, 0, "Golden Boots", new ArmorTypeInfo(1, 92, ArmorInventory::SLOT_FEET))); - self::register(new Armor(ItemIds::IRON_BOOTS, 0, "Iron Boots", new ArmorTypeInfo(2, 196, ArmorInventory::SLOT_FEET))); - self::register(new Armor(ItemIds::LEATHER_BOOTS, 0, "Leather Boots", new ArmorTypeInfo(1, 66, ArmorInventory::SLOT_FEET))); - self::register(new Armor(ItemIds::CHAIN_CHESTPLATE, 0, "Chainmail Chestplate", new ArmorTypeInfo(5, 241, ArmorInventory::SLOT_CHEST))); - self::register(new Armor(ItemIds::DIAMOND_CHESTPLATE, 0, "Diamond Chestplate", new ArmorTypeInfo(8, 529, ArmorInventory::SLOT_CHEST))); - self::register(new Armor(ItemIds::GOLDEN_CHESTPLATE, 0, "Golden Chestplate", new ArmorTypeInfo(5, 113, ArmorInventory::SLOT_CHEST))); - self::register(new Armor(ItemIds::IRON_CHESTPLATE, 0, "Iron Chestplate", new ArmorTypeInfo(6, 241, ArmorInventory::SLOT_CHEST))); - self::register(new Armor(ItemIds::LEATHER_CHESTPLATE, 0, "Leather Tunic", new ArmorTypeInfo(3, 81, ArmorInventory::SLOT_CHEST))); - self::register(new Armor(ItemIds::CHAIN_HELMET, 0, "Chainmail Helmet", new ArmorTypeInfo(2, 166, ArmorInventory::SLOT_HEAD))); - self::register(new Armor(ItemIds::DIAMOND_HELMET, 0, "Diamond Helmet", new ArmorTypeInfo(3, 364, ArmorInventory::SLOT_HEAD))); - self::register(new Armor(ItemIds::GOLDEN_HELMET, 0, "Golden Helmet", new ArmorTypeInfo(2, 78, ArmorInventory::SLOT_HEAD))); - self::register(new Armor(ItemIds::IRON_HELMET, 0, "Iron Helmet", new ArmorTypeInfo(2, 166, ArmorInventory::SLOT_HEAD))); - self::register(new Armor(ItemIds::LEATHER_HELMET, 0, "Leather Cap", new ArmorTypeInfo(1, 56, ArmorInventory::SLOT_HEAD))); - self::register(new Armor(ItemIds::CHAIN_LEGGINGS, 0, "Chainmail Leggings", new ArmorTypeInfo(4, 226, ArmorInventory::SLOT_LEGS))); - self::register(new Armor(ItemIds::DIAMOND_LEGGINGS, 0, "Diamond Leggings", new ArmorTypeInfo(6, 496, ArmorInventory::SLOT_LEGS))); - self::register(new Armor(ItemIds::GOLDEN_LEGGINGS, 0, "Golden Leggings", new ArmorTypeInfo(3, 106, ArmorInventory::SLOT_LEGS))); - self::register(new Armor(ItemIds::IRON_LEGGINGS, 0, "Iron Leggings", new ArmorTypeInfo(5, 226, ArmorInventory::SLOT_LEGS))); - self::register(new Armor(ItemIds::LEATHER_LEGGINGS, 0, "Leather Pants", new ArmorTypeInfo(2, 76, ArmorInventory::SLOT_LEGS))); + private function registerArmorItems() : void{ + $this->register(new Armor(ItemIds::CHAIN_BOOTS, 0, "Chainmail Boots", new ArmorTypeInfo(1, 196, ArmorInventory::SLOT_FEET))); + $this->register(new Armor(ItemIds::DIAMOND_BOOTS, 0, "Diamond Boots", new ArmorTypeInfo(3, 430, ArmorInventory::SLOT_FEET))); + $this->register(new Armor(ItemIds::GOLDEN_BOOTS, 0, "Golden Boots", new ArmorTypeInfo(1, 92, ArmorInventory::SLOT_FEET))); + $this->register(new Armor(ItemIds::IRON_BOOTS, 0, "Iron Boots", new ArmorTypeInfo(2, 196, ArmorInventory::SLOT_FEET))); + $this->register(new Armor(ItemIds::LEATHER_BOOTS, 0, "Leather Boots", new ArmorTypeInfo(1, 66, ArmorInventory::SLOT_FEET))); + $this->register(new Armor(ItemIds::CHAIN_CHESTPLATE, 0, "Chainmail Chestplate", new ArmorTypeInfo(5, 241, ArmorInventory::SLOT_CHEST))); + $this->register(new Armor(ItemIds::DIAMOND_CHESTPLATE, 0, "Diamond Chestplate", new ArmorTypeInfo(8, 529, ArmorInventory::SLOT_CHEST))); + $this->register(new Armor(ItemIds::GOLDEN_CHESTPLATE, 0, "Golden Chestplate", new ArmorTypeInfo(5, 113, ArmorInventory::SLOT_CHEST))); + $this->register(new Armor(ItemIds::IRON_CHESTPLATE, 0, "Iron Chestplate", new ArmorTypeInfo(6, 241, ArmorInventory::SLOT_CHEST))); + $this->register(new Armor(ItemIds::LEATHER_CHESTPLATE, 0, "Leather Tunic", new ArmorTypeInfo(3, 81, ArmorInventory::SLOT_CHEST))); + $this->register(new Armor(ItemIds::CHAIN_HELMET, 0, "Chainmail Helmet", new ArmorTypeInfo(2, 166, ArmorInventory::SLOT_HEAD))); + $this->register(new Armor(ItemIds::DIAMOND_HELMET, 0, "Diamond Helmet", new ArmorTypeInfo(3, 364, ArmorInventory::SLOT_HEAD))); + $this->register(new Armor(ItemIds::GOLDEN_HELMET, 0, "Golden Helmet", new ArmorTypeInfo(2, 78, ArmorInventory::SLOT_HEAD))); + $this->register(new Armor(ItemIds::IRON_HELMET, 0, "Iron Helmet", new ArmorTypeInfo(2, 166, ArmorInventory::SLOT_HEAD))); + $this->register(new Armor(ItemIds::LEATHER_HELMET, 0, "Leather Cap", new ArmorTypeInfo(1, 56, ArmorInventory::SLOT_HEAD))); + $this->register(new Armor(ItemIds::CHAIN_LEGGINGS, 0, "Chainmail Leggings", new ArmorTypeInfo(4, 226, ArmorInventory::SLOT_LEGS))); + $this->register(new Armor(ItemIds::DIAMOND_LEGGINGS, 0, "Diamond Leggings", new ArmorTypeInfo(6, 496, ArmorInventory::SLOT_LEGS))); + $this->register(new Armor(ItemIds::GOLDEN_LEGGINGS, 0, "Golden Leggings", new ArmorTypeInfo(3, 106, ArmorInventory::SLOT_LEGS))); + $this->register(new Armor(ItemIds::IRON_LEGGINGS, 0, "Iron Leggings", new ArmorTypeInfo(5, 226, ArmorInventory::SLOT_LEGS))); + $this->register(new Armor(ItemIds::LEATHER_LEGGINGS, 0, "Leather Pants", new ArmorTypeInfo(2, 76, ArmorInventory::SLOT_LEGS))); } /** @@ -384,15 +391,15 @@ class ItemFactory{ * @throws \RuntimeException if something attempted to override an already-registered item without specifying the * $override parameter. */ - public static function register(Item $item, bool $override = false) : void{ + public function register(Item $item, bool $override = false) : void{ $id = $item->getId(); $variant = $item->getMeta(); - if(!$override and self::isRegistered($id, $variant)){ + if(!$override and $this->isRegistered($id, $variant)){ throw new \RuntimeException("Trying to overwrite an already registered item"); } - self::$list[self::getListOffset($id, $variant)] = clone $item; + $this->list[self::getListOffset($id, $variant)] = clone $item; } /** @@ -400,15 +407,15 @@ class ItemFactory{ * * @throws \InvalidArgumentException */ - public static function get(int $id, int $meta = 0, int $count = 1, ?CompoundTag $tags = null) : Item{ + public function get(int $id, int $meta = 0, int $count = 1, ?CompoundTag $tags = null) : Item{ /** @var Item|null $item */ $item = null; if($meta !== -1){ - if(isset(self::$list[$offset = self::getListOffset($id, $meta)])){ - $item = clone self::$list[$offset]; - }elseif(isset(self::$list[$zero = self::getListOffset($id, 0)]) and self::$list[$zero] instanceof Durable){ + if(isset($this->list[$offset = self::getListOffset($id, $meta)])){ + $item = clone $this->list[$offset]; + }elseif(isset($this->list[$zero = self::getListOffset($id, 0)]) and $this->list[$zero] instanceof Durable){ /** @var Durable $item */ - $item = clone self::$list[$zero]; + $item = clone $this->list[$zero]; $item->setDamage($meta); }elseif($id < 256){ //intentionally includes negatives, for extended block IDs $item = new ItemBlock($id, $meta); @@ -437,7 +444,7 @@ class ItemFactory{ * * @throws \InvalidArgumentException if the given string cannot be parsed as an item identifier */ - public static function fromString(string $str) : Item{ + public function fromString(string $str) : Item{ $b = explode(":", str_replace([" ", "minecraft:"], ["_", ""], trim($str))); if(!isset($b[1])){ $meta = 0; @@ -448,9 +455,9 @@ class ItemFactory{ } if(is_numeric($b[0])){ - $item = self::get((int) $b[0], $meta); + $item = $this->get((int) $b[0], $meta); }elseif(defined(ItemIds::class . "::" . strtoupper($b[0]))){ - $item = self::get(constant(ItemIds::class . "::" . strtoupper($b[0])), $meta); + $item = $this->get(constant(ItemIds::class . "::" . strtoupper($b[0])), $meta); }else{ throw new \InvalidArgumentException("Unable to resolve \"" . $str . "\" to a valid item"); } @@ -459,18 +466,18 @@ class ItemFactory{ } public static function air() : Item{ - return self::$air ?? (self::$air = self::get(ItemIds::AIR, 0, 0)); + return self::$air ?? (self::$air = self::getInstance()->get(ItemIds::AIR, 0, 0)); } /** * Returns whether the specified item ID is already registered in the item factory. */ - public static function isRegistered(int $id, int $variant = 0) : bool{ + public function isRegistered(int $id, int $variant = 0) : bool{ if($id < 256){ return BlockFactory::getInstance()->isRegistered($id); } - return isset(self::$list[self::getListOffset($id, $variant)]); + return isset($this->list[self::getListOffset($id, $variant)]); } private static function getListOffset(int $id, int $variant) : int{ @@ -483,7 +490,7 @@ class ItemFactory{ /** * @return Item[] */ - public static function getAllRegistered() : array{ - return self::$list; + public function getAllRegistered() : array{ + return $this->list; } } diff --git a/src/item/VanillaItems.php b/src/item/VanillaItems.php index c5ee5cce2c..d8bb6b655a 100644 --- a/src/item/VanillaItems.php +++ b/src/item/VanillaItems.php @@ -316,263 +316,264 @@ final class VanillaItems{ } protected static function setup() : void{ - self::register("acacia_boat", ItemFactory::get(333, 4)); - self::register("apple", ItemFactory::get(260)); - self::register("arrow", ItemFactory::get(262)); - self::register("baked_potato", ItemFactory::get(393)); - self::register("beetroot", ItemFactory::get(457)); - self::register("beetroot_seeds", ItemFactory::get(458)); - self::register("beetroot_soup", ItemFactory::get(459)); - self::register("birch_boat", ItemFactory::get(333, 2)); - self::register("black_banner", ItemFactory::get(446)); - self::register("black_bed", ItemFactory::get(355, 15)); - self::register("black_dye", ItemFactory::get(351, 16)); - self::register("blaze_powder", ItemFactory::get(377)); - self::register("blaze_rod", ItemFactory::get(369)); - self::register("bleach", ItemFactory::get(451)); - self::register("blue_banner", ItemFactory::get(446, 4)); - self::register("blue_bed", ItemFactory::get(355, 11)); - self::register("blue_dye", ItemFactory::get(351, 18)); - self::register("bone", ItemFactory::get(352)); - self::register("bone_meal", ItemFactory::get(351, 15)); - self::register("book", ItemFactory::get(340)); - self::register("bow", ItemFactory::get(261)); - self::register("bowl", ItemFactory::get(281)); - self::register("bread", ItemFactory::get(297)); - self::register("brick", ItemFactory::get(336)); - self::register("brown_banner", ItemFactory::get(446, 3)); - self::register("brown_bed", ItemFactory::get(355, 12)); - self::register("brown_dye", ItemFactory::get(351, 17)); - self::register("bucket", ItemFactory::get(325)); - self::register("cake", ItemFactory::get(354)); - self::register("carrot", ItemFactory::get(391)); - self::register("chainmail_boots", ItemFactory::get(305)); - self::register("chainmail_chestplate", ItemFactory::get(303)); - self::register("chainmail_helmet", ItemFactory::get(302)); - self::register("chainmail_leggings", ItemFactory::get(304)); - self::register("charcoal", ItemFactory::get(263, 1)); - self::register("chemical_aluminium_oxide", ItemFactory::get(499, 13)); - self::register("chemical_ammonia", ItemFactory::get(499, 36)); - self::register("chemical_barium_sulphate", ItemFactory::get(499, 20)); - self::register("chemical_benzene", ItemFactory::get(499, 33)); - self::register("chemical_boron_trioxide", ItemFactory::get(499, 14)); - self::register("chemical_calcium_bromide", ItemFactory::get(499, 7)); - self::register("chemical_calcium_chloride", ItemFactory::get(499, 25)); - self::register("chemical_cerium_chloride", ItemFactory::get(499, 23)); - self::register("chemical_charcoal", ItemFactory::get(499, 11)); - self::register("chemical_crude_oil", ItemFactory::get(499, 29)); - self::register("chemical_glue", ItemFactory::get(499, 27)); - self::register("chemical_hydrogen_peroxide", ItemFactory::get(499, 35)); - self::register("chemical_hypochlorite", ItemFactory::get(499, 28)); - self::register("chemical_ink", ItemFactory::get(499, 34)); - self::register("chemical_iron_sulphide", ItemFactory::get(499, 4)); - self::register("chemical_latex", ItemFactory::get(499, 30)); - self::register("chemical_lithium_hydride", ItemFactory::get(499, 5)); - self::register("chemical_luminol", ItemFactory::get(499, 10)); - self::register("chemical_magnesium_nitrate", ItemFactory::get(499, 3)); - self::register("chemical_magnesium_oxide", ItemFactory::get(499, 8)); - self::register("chemical_magnesium_salts", ItemFactory::get(499, 18)); - self::register("chemical_mercuric_chloride", ItemFactory::get(499, 22)); - self::register("chemical_polyethylene", ItemFactory::get(499, 16)); - self::register("chemical_potassium_chloride", ItemFactory::get(499, 21)); - self::register("chemical_potassium_iodide", ItemFactory::get(499, 31)); - self::register("chemical_rubbish", ItemFactory::get(499, 17)); - self::register("chemical_salt", ItemFactory::get(499)); - self::register("chemical_soap", ItemFactory::get(499, 15)); - self::register("chemical_sodium_acetate", ItemFactory::get(499, 9)); - self::register("chemical_sodium_fluoride", ItemFactory::get(499, 32)); - self::register("chemical_sodium_hydride", ItemFactory::get(499, 6)); - self::register("chemical_sodium_hydroxide", ItemFactory::get(499, 2)); - self::register("chemical_sodium_hypochlorite", ItemFactory::get(499, 37)); - self::register("chemical_sodium_oxide", ItemFactory::get(499, 1)); - self::register("chemical_sugar", ItemFactory::get(499, 12)); - self::register("chemical_sulphate", ItemFactory::get(499, 19)); - self::register("chemical_tungsten_chloride", ItemFactory::get(499, 24)); - self::register("chemical_water", ItemFactory::get(499, 26)); - self::register("chorus_fruit", ItemFactory::get(432)); - self::register("clay", ItemFactory::get(337)); - self::register("clock", ItemFactory::get(347)); - self::register("clownfish", ItemFactory::get(461)); - self::register("coal", ItemFactory::get(263)); - self::register("cocoa_beans", ItemFactory::get(351, 3)); - self::register("compass", ItemFactory::get(345)); - self::register("cooked_chicken", ItemFactory::get(366)); - self::register("cooked_fish", ItemFactory::get(350)); - self::register("cooked_mutton", ItemFactory::get(424)); - self::register("cooked_porkchop", ItemFactory::get(320)); - self::register("cooked_rabbit", ItemFactory::get(412)); - self::register("cooked_salmon", ItemFactory::get(463)); - self::register("cookie", ItemFactory::get(357)); - self::register("creeper_head", ItemFactory::get(397, 4)); - self::register("cyan_banner", ItemFactory::get(446, 6)); - self::register("cyan_bed", ItemFactory::get(355, 9)); - self::register("cyan_dye", ItemFactory::get(351, 6)); - self::register("dark_oak_boat", ItemFactory::get(333, 5)); - self::register("diamond", ItemFactory::get(264)); - self::register("diamond_axe", ItemFactory::get(279)); - self::register("diamond_boots", ItemFactory::get(313)); - self::register("diamond_chestplate", ItemFactory::get(311)); - self::register("diamond_helmet", ItemFactory::get(310)); - self::register("diamond_hoe", ItemFactory::get(293)); - self::register("diamond_leggings", ItemFactory::get(312)); - self::register("diamond_pickaxe", ItemFactory::get(278)); - self::register("diamond_shovel", ItemFactory::get(277)); - self::register("diamond_sword", ItemFactory::get(276)); - self::register("dragon_breath", ItemFactory::get(437)); - self::register("dragon_head", ItemFactory::get(397, 5)); - self::register("dried_kelp", ItemFactory::get(464)); - self::register("egg", ItemFactory::get(344)); - self::register("emerald", ItemFactory::get(388)); - self::register("enchanted_golden_apple", ItemFactory::get(466)); - self::register("ender_pearl", ItemFactory::get(368)); - self::register("experience_bottle", ItemFactory::get(384)); - self::register("feather", ItemFactory::get(288)); - self::register("fermented_spider_eye", ItemFactory::get(376)); - self::register("fishing_rod", ItemFactory::get(346)); - self::register("flint", ItemFactory::get(318)); - self::register("flint_and_steel", ItemFactory::get(259)); - self::register("ghast_tear", ItemFactory::get(370)); - self::register("glass_bottle", ItemFactory::get(374)); - self::register("glistering_melon", ItemFactory::get(382)); - self::register("glowstone_dust", ItemFactory::get(348)); - self::register("gold_ingot", ItemFactory::get(266)); - self::register("gold_nugget", ItemFactory::get(371)); - self::register("golden_apple", ItemFactory::get(322)); - self::register("golden_axe", ItemFactory::get(286)); - self::register("golden_boots", ItemFactory::get(317)); - self::register("golden_carrot", ItemFactory::get(396)); - self::register("golden_chestplate", ItemFactory::get(315)); - self::register("golden_helmet", ItemFactory::get(314)); - self::register("golden_hoe", ItemFactory::get(294)); - self::register("golden_leggings", ItemFactory::get(316)); - self::register("golden_pickaxe", ItemFactory::get(285)); - self::register("golden_shovel", ItemFactory::get(284)); - self::register("golden_sword", ItemFactory::get(283)); - self::register("gray_banner", ItemFactory::get(446, 8)); - self::register("gray_bed", ItemFactory::get(355, 7)); - self::register("gray_dye", ItemFactory::get(351, 8)); - self::register("green_banner", ItemFactory::get(446, 2)); - self::register("green_bed", ItemFactory::get(355, 13)); - self::register("green_dye", ItemFactory::get(351, 2)); - self::register("gunpowder", ItemFactory::get(289)); - self::register("heart_of_the_sea", ItemFactory::get(467)); - self::register("ink_sac", ItemFactory::get(351)); - self::register("iron_axe", ItemFactory::get(258)); - self::register("iron_boots", ItemFactory::get(309)); - self::register("iron_chestplate", ItemFactory::get(307)); - self::register("iron_helmet", ItemFactory::get(306)); - self::register("iron_hoe", ItemFactory::get(292)); - self::register("iron_ingot", ItemFactory::get(265)); - self::register("iron_leggings", ItemFactory::get(308)); - self::register("iron_nugget", ItemFactory::get(452)); - self::register("iron_pickaxe", ItemFactory::get(257)); - self::register("iron_shovel", ItemFactory::get(256)); - self::register("iron_sword", ItemFactory::get(267)); - self::register("jungle_boat", ItemFactory::get(333, 3)); - self::register("lapis_lazuli", ItemFactory::get(351, 4)); - self::register("lava_bucket", ItemFactory::get(325, 10)); - self::register("leather", ItemFactory::get(334)); - self::register("leather_boots", ItemFactory::get(301)); - self::register("leather_cap", ItemFactory::get(298)); - self::register("leather_pants", ItemFactory::get(300)); - self::register("leather_tunic", ItemFactory::get(299)); - self::register("light_blue_banner", ItemFactory::get(446, 12)); - self::register("light_blue_bed", ItemFactory::get(355, 3)); - self::register("light_blue_dye", ItemFactory::get(351, 12)); - self::register("light_gray_banner", ItemFactory::get(446, 7)); - self::register("light_gray_bed", ItemFactory::get(355, 8)); - self::register("light_gray_dye", ItemFactory::get(351, 7)); - self::register("lime_banner", ItemFactory::get(446, 10)); - self::register("lime_bed", ItemFactory::get(355, 5)); - self::register("lime_dye", ItemFactory::get(351, 10)); - self::register("magenta_banner", ItemFactory::get(446, 13)); - self::register("magenta_bed", ItemFactory::get(355, 2)); - self::register("magenta_dye", ItemFactory::get(351, 13)); - self::register("magma_cream", ItemFactory::get(378)); - self::register("melon", ItemFactory::get(360)); - self::register("melon_seeds", ItemFactory::get(362)); - self::register("milk_bucket", ItemFactory::get(325, 1)); - self::register("minecart", ItemFactory::get(328)); - self::register("mushroom_stew", ItemFactory::get(282)); - self::register("nautilus_shell", ItemFactory::get(465)); - self::register("nether_brick", ItemFactory::get(405)); - self::register("nether_quartz", ItemFactory::get(406)); - self::register("nether_star", ItemFactory::get(399)); - self::register("nether_wart", ItemFactory::get(372)); - self::register("oak_boat", ItemFactory::get(333)); - self::register("orange_banner", ItemFactory::get(446, 14)); - self::register("orange_bed", ItemFactory::get(355, 1)); - self::register("orange_dye", ItemFactory::get(351, 14)); - self::register("painting", ItemFactory::get(321)); - self::register("paper", ItemFactory::get(339)); - self::register("pink_banner", ItemFactory::get(446, 9)); - self::register("pink_bed", ItemFactory::get(355, 6)); - self::register("pink_dye", ItemFactory::get(351, 9)); - self::register("player_head", ItemFactory::get(397, 3)); - self::register("poisonous_potato", ItemFactory::get(394)); - self::register("popped_chorus_fruit", ItemFactory::get(433)); - self::register("potato", ItemFactory::get(392)); - self::register("potion", ItemFactory::get(373)); - self::register("prismarine_crystals", ItemFactory::get(422)); - self::register("prismarine_shard", ItemFactory::get(409)); - self::register("pufferfish", ItemFactory::get(462)); - self::register("pumpkin_pie", ItemFactory::get(400)); - self::register("pumpkin_seeds", ItemFactory::get(361)); - self::register("purple_banner", ItemFactory::get(446, 5)); - self::register("purple_bed", ItemFactory::get(355, 10)); - self::register("purple_dye", ItemFactory::get(351, 5)); - self::register("rabbit_foot", ItemFactory::get(414)); - self::register("rabbit_hide", ItemFactory::get(415)); - self::register("rabbit_stew", ItemFactory::get(413)); - self::register("raw_beef", ItemFactory::get(363)); - self::register("raw_chicken", ItemFactory::get(365)); - self::register("raw_fish", ItemFactory::get(349)); - self::register("raw_mutton", ItemFactory::get(423)); - self::register("raw_porkchop", ItemFactory::get(319)); - self::register("raw_rabbit", ItemFactory::get(411)); - self::register("raw_salmon", ItemFactory::get(460)); - self::register("red_banner", ItemFactory::get(446, 1)); - self::register("red_bed", ItemFactory::get(355, 14)); - self::register("red_dye", ItemFactory::get(351, 1)); - self::register("redstone_dust", ItemFactory::get(331)); - self::register("rotten_flesh", ItemFactory::get(367)); - self::register("scute", ItemFactory::get(468)); - self::register("shears", ItemFactory::get(359)); - self::register("shulker_shell", ItemFactory::get(445)); - self::register("skeleton_skull", ItemFactory::get(397)); - self::register("slimeball", ItemFactory::get(341)); - self::register("snowball", ItemFactory::get(332)); - self::register("spider_eye", ItemFactory::get(375)); - self::register("splash_potion", ItemFactory::get(438)); - self::register("spruce_boat", ItemFactory::get(333, 1)); - self::register("steak", ItemFactory::get(364)); - self::register("stick", ItemFactory::get(280)); - self::register("stone_axe", ItemFactory::get(275)); - self::register("stone_hoe", ItemFactory::get(291)); - self::register("stone_pickaxe", ItemFactory::get(274)); - self::register("stone_shovel", ItemFactory::get(273)); - self::register("stone_sword", ItemFactory::get(272)); - self::register("string", ItemFactory::get(287)); - self::register("sugar", ItemFactory::get(353)); - self::register("sugarcane", ItemFactory::get(338)); - self::register("totem", ItemFactory::get(450)); - self::register("water_bucket", ItemFactory::get(325, 8)); - self::register("wheat", ItemFactory::get(296)); - self::register("wheat_seeds", ItemFactory::get(295)); - self::register("white_banner", ItemFactory::get(446, 15)); - self::register("white_bed", ItemFactory::get(355)); - self::register("white_dye", ItemFactory::get(351, 19)); - self::register("wither_skeleton_skull", ItemFactory::get(397, 1)); - self::register("wooden_axe", ItemFactory::get(271)); - self::register("wooden_hoe", ItemFactory::get(290)); - self::register("wooden_pickaxe", ItemFactory::get(270)); - self::register("wooden_shovel", ItemFactory::get(269)); - self::register("wooden_sword", ItemFactory::get(268)); - self::register("writable_book", ItemFactory::get(386)); - self::register("written_book", ItemFactory::get(387)); - self::register("yellow_banner", ItemFactory::get(446, 11)); - self::register("yellow_bed", ItemFactory::get(355, 4)); - self::register("yellow_dye", ItemFactory::get(351, 11)); - self::register("zombie_head", ItemFactory::get(397, 2)); + $factory = ItemFactory::getInstance(); + self::register("acacia_boat", $factory->get(333, 4)); + self::register("apple", $factory->get(260)); + self::register("arrow", $factory->get(262)); + self::register("baked_potato", $factory->get(393)); + self::register("beetroot", $factory->get(457)); + self::register("beetroot_seeds", $factory->get(458)); + self::register("beetroot_soup", $factory->get(459)); + self::register("birch_boat", $factory->get(333, 2)); + self::register("black_banner", $factory->get(446)); + self::register("black_bed", $factory->get(355, 15)); + self::register("black_dye", $factory->get(351, 16)); + self::register("blaze_powder", $factory->get(377)); + self::register("blaze_rod", $factory->get(369)); + self::register("bleach", $factory->get(451)); + self::register("blue_banner", $factory->get(446, 4)); + self::register("blue_bed", $factory->get(355, 11)); + self::register("blue_dye", $factory->get(351, 18)); + self::register("bone", $factory->get(352)); + self::register("bone_meal", $factory->get(351, 15)); + self::register("book", $factory->get(340)); + self::register("bow", $factory->get(261)); + self::register("bowl", $factory->get(281)); + self::register("bread", $factory->get(297)); + self::register("brick", $factory->get(336)); + self::register("brown_banner", $factory->get(446, 3)); + self::register("brown_bed", $factory->get(355, 12)); + self::register("brown_dye", $factory->get(351, 17)); + self::register("bucket", $factory->get(325)); + self::register("cake", $factory->get(354)); + self::register("carrot", $factory->get(391)); + self::register("chainmail_boots", $factory->get(305)); + self::register("chainmail_chestplate", $factory->get(303)); + self::register("chainmail_helmet", $factory->get(302)); + self::register("chainmail_leggings", $factory->get(304)); + self::register("charcoal", $factory->get(263, 1)); + self::register("chemical_aluminium_oxide", $factory->get(499, 13)); + self::register("chemical_ammonia", $factory->get(499, 36)); + self::register("chemical_barium_sulphate", $factory->get(499, 20)); + self::register("chemical_benzene", $factory->get(499, 33)); + self::register("chemical_boron_trioxide", $factory->get(499, 14)); + self::register("chemical_calcium_bromide", $factory->get(499, 7)); + self::register("chemical_calcium_chloride", $factory->get(499, 25)); + self::register("chemical_cerium_chloride", $factory->get(499, 23)); + self::register("chemical_charcoal", $factory->get(499, 11)); + self::register("chemical_crude_oil", $factory->get(499, 29)); + self::register("chemical_glue", $factory->get(499, 27)); + self::register("chemical_hydrogen_peroxide", $factory->get(499, 35)); + self::register("chemical_hypochlorite", $factory->get(499, 28)); + self::register("chemical_ink", $factory->get(499, 34)); + self::register("chemical_iron_sulphide", $factory->get(499, 4)); + self::register("chemical_latex", $factory->get(499, 30)); + self::register("chemical_lithium_hydride", $factory->get(499, 5)); + self::register("chemical_luminol", $factory->get(499, 10)); + self::register("chemical_magnesium_nitrate", $factory->get(499, 3)); + self::register("chemical_magnesium_oxide", $factory->get(499, 8)); + self::register("chemical_magnesium_salts", $factory->get(499, 18)); + self::register("chemical_mercuric_chloride", $factory->get(499, 22)); + self::register("chemical_polyethylene", $factory->get(499, 16)); + self::register("chemical_potassium_chloride", $factory->get(499, 21)); + self::register("chemical_potassium_iodide", $factory->get(499, 31)); + self::register("chemical_rubbish", $factory->get(499, 17)); + self::register("chemical_salt", $factory->get(499)); + self::register("chemical_soap", $factory->get(499, 15)); + self::register("chemical_sodium_acetate", $factory->get(499, 9)); + self::register("chemical_sodium_fluoride", $factory->get(499, 32)); + self::register("chemical_sodium_hydride", $factory->get(499, 6)); + self::register("chemical_sodium_hydroxide", $factory->get(499, 2)); + self::register("chemical_sodium_hypochlorite", $factory->get(499, 37)); + self::register("chemical_sodium_oxide", $factory->get(499, 1)); + self::register("chemical_sugar", $factory->get(499, 12)); + self::register("chemical_sulphate", $factory->get(499, 19)); + self::register("chemical_tungsten_chloride", $factory->get(499, 24)); + self::register("chemical_water", $factory->get(499, 26)); + self::register("chorus_fruit", $factory->get(432)); + self::register("clay", $factory->get(337)); + self::register("clock", $factory->get(347)); + self::register("clownfish", $factory->get(461)); + self::register("coal", $factory->get(263)); + self::register("cocoa_beans", $factory->get(351, 3)); + self::register("compass", $factory->get(345)); + self::register("cooked_chicken", $factory->get(366)); + self::register("cooked_fish", $factory->get(350)); + self::register("cooked_mutton", $factory->get(424)); + self::register("cooked_porkchop", $factory->get(320)); + self::register("cooked_rabbit", $factory->get(412)); + self::register("cooked_salmon", $factory->get(463)); + self::register("cookie", $factory->get(357)); + self::register("creeper_head", $factory->get(397, 4)); + self::register("cyan_banner", $factory->get(446, 6)); + self::register("cyan_bed", $factory->get(355, 9)); + self::register("cyan_dye", $factory->get(351, 6)); + self::register("dark_oak_boat", $factory->get(333, 5)); + self::register("diamond", $factory->get(264)); + self::register("diamond_axe", $factory->get(279)); + self::register("diamond_boots", $factory->get(313)); + self::register("diamond_chestplate", $factory->get(311)); + self::register("diamond_helmet", $factory->get(310)); + self::register("diamond_hoe", $factory->get(293)); + self::register("diamond_leggings", $factory->get(312)); + self::register("diamond_pickaxe", $factory->get(278)); + self::register("diamond_shovel", $factory->get(277)); + self::register("diamond_sword", $factory->get(276)); + self::register("dragon_breath", $factory->get(437)); + self::register("dragon_head", $factory->get(397, 5)); + self::register("dried_kelp", $factory->get(464)); + self::register("egg", $factory->get(344)); + self::register("emerald", $factory->get(388)); + self::register("enchanted_golden_apple", $factory->get(466)); + self::register("ender_pearl", $factory->get(368)); + self::register("experience_bottle", $factory->get(384)); + self::register("feather", $factory->get(288)); + self::register("fermented_spider_eye", $factory->get(376)); + self::register("fishing_rod", $factory->get(346)); + self::register("flint", $factory->get(318)); + self::register("flint_and_steel", $factory->get(259)); + self::register("ghast_tear", $factory->get(370)); + self::register("glass_bottle", $factory->get(374)); + self::register("glistering_melon", $factory->get(382)); + self::register("glowstone_dust", $factory->get(348)); + self::register("gold_ingot", $factory->get(266)); + self::register("gold_nugget", $factory->get(371)); + self::register("golden_apple", $factory->get(322)); + self::register("golden_axe", $factory->get(286)); + self::register("golden_boots", $factory->get(317)); + self::register("golden_carrot", $factory->get(396)); + self::register("golden_chestplate", $factory->get(315)); + self::register("golden_helmet", $factory->get(314)); + self::register("golden_hoe", $factory->get(294)); + self::register("golden_leggings", $factory->get(316)); + self::register("golden_pickaxe", $factory->get(285)); + self::register("golden_shovel", $factory->get(284)); + self::register("golden_sword", $factory->get(283)); + self::register("gray_banner", $factory->get(446, 8)); + self::register("gray_bed", $factory->get(355, 7)); + self::register("gray_dye", $factory->get(351, 8)); + self::register("green_banner", $factory->get(446, 2)); + self::register("green_bed", $factory->get(355, 13)); + self::register("green_dye", $factory->get(351, 2)); + self::register("gunpowder", $factory->get(289)); + self::register("heart_of_the_sea", $factory->get(467)); + self::register("ink_sac", $factory->get(351)); + self::register("iron_axe", $factory->get(258)); + self::register("iron_boots", $factory->get(309)); + self::register("iron_chestplate", $factory->get(307)); + self::register("iron_helmet", $factory->get(306)); + self::register("iron_hoe", $factory->get(292)); + self::register("iron_ingot", $factory->get(265)); + self::register("iron_leggings", $factory->get(308)); + self::register("iron_nugget", $factory->get(452)); + self::register("iron_pickaxe", $factory->get(257)); + self::register("iron_shovel", $factory->get(256)); + self::register("iron_sword", $factory->get(267)); + self::register("jungle_boat", $factory->get(333, 3)); + self::register("lapis_lazuli", $factory->get(351, 4)); + self::register("lava_bucket", $factory->get(325, 10)); + self::register("leather", $factory->get(334)); + self::register("leather_boots", $factory->get(301)); + self::register("leather_cap", $factory->get(298)); + self::register("leather_pants", $factory->get(300)); + self::register("leather_tunic", $factory->get(299)); + self::register("light_blue_banner", $factory->get(446, 12)); + self::register("light_blue_bed", $factory->get(355, 3)); + self::register("light_blue_dye", $factory->get(351, 12)); + self::register("light_gray_banner", $factory->get(446, 7)); + self::register("light_gray_bed", $factory->get(355, 8)); + self::register("light_gray_dye", $factory->get(351, 7)); + self::register("lime_banner", $factory->get(446, 10)); + self::register("lime_bed", $factory->get(355, 5)); + self::register("lime_dye", $factory->get(351, 10)); + self::register("magenta_banner", $factory->get(446, 13)); + self::register("magenta_bed", $factory->get(355, 2)); + self::register("magenta_dye", $factory->get(351, 13)); + self::register("magma_cream", $factory->get(378)); + self::register("melon", $factory->get(360)); + self::register("melon_seeds", $factory->get(362)); + self::register("milk_bucket", $factory->get(325, 1)); + self::register("minecart", $factory->get(328)); + self::register("mushroom_stew", $factory->get(282)); + self::register("nautilus_shell", $factory->get(465)); + self::register("nether_brick", $factory->get(405)); + self::register("nether_quartz", $factory->get(406)); + self::register("nether_star", $factory->get(399)); + self::register("nether_wart", $factory->get(372)); + self::register("oak_boat", $factory->get(333)); + self::register("orange_banner", $factory->get(446, 14)); + self::register("orange_bed", $factory->get(355, 1)); + self::register("orange_dye", $factory->get(351, 14)); + self::register("painting", $factory->get(321)); + self::register("paper", $factory->get(339)); + self::register("pink_banner", $factory->get(446, 9)); + self::register("pink_bed", $factory->get(355, 6)); + self::register("pink_dye", $factory->get(351, 9)); + self::register("player_head", $factory->get(397, 3)); + self::register("poisonous_potato", $factory->get(394)); + self::register("popped_chorus_fruit", $factory->get(433)); + self::register("potato", $factory->get(392)); + self::register("potion", $factory->get(373)); + self::register("prismarine_crystals", $factory->get(422)); + self::register("prismarine_shard", $factory->get(409)); + self::register("pufferfish", $factory->get(462)); + self::register("pumpkin_pie", $factory->get(400)); + self::register("pumpkin_seeds", $factory->get(361)); + self::register("purple_banner", $factory->get(446, 5)); + self::register("purple_bed", $factory->get(355, 10)); + self::register("purple_dye", $factory->get(351, 5)); + self::register("rabbit_foot", $factory->get(414)); + self::register("rabbit_hide", $factory->get(415)); + self::register("rabbit_stew", $factory->get(413)); + self::register("raw_beef", $factory->get(363)); + self::register("raw_chicken", $factory->get(365)); + self::register("raw_fish", $factory->get(349)); + self::register("raw_mutton", $factory->get(423)); + self::register("raw_porkchop", $factory->get(319)); + self::register("raw_rabbit", $factory->get(411)); + self::register("raw_salmon", $factory->get(460)); + self::register("red_banner", $factory->get(446, 1)); + self::register("red_bed", $factory->get(355, 14)); + self::register("red_dye", $factory->get(351, 1)); + self::register("redstone_dust", $factory->get(331)); + self::register("rotten_flesh", $factory->get(367)); + self::register("scute", $factory->get(468)); + self::register("shears", $factory->get(359)); + self::register("shulker_shell", $factory->get(445)); + self::register("skeleton_skull", $factory->get(397)); + self::register("slimeball", $factory->get(341)); + self::register("snowball", $factory->get(332)); + self::register("spider_eye", $factory->get(375)); + self::register("splash_potion", $factory->get(438)); + self::register("spruce_boat", $factory->get(333, 1)); + self::register("steak", $factory->get(364)); + self::register("stick", $factory->get(280)); + self::register("stone_axe", $factory->get(275)); + self::register("stone_hoe", $factory->get(291)); + self::register("stone_pickaxe", $factory->get(274)); + self::register("stone_shovel", $factory->get(273)); + self::register("stone_sword", $factory->get(272)); + self::register("string", $factory->get(287)); + self::register("sugar", $factory->get(353)); + self::register("sugarcane", $factory->get(338)); + self::register("totem", $factory->get(450)); + self::register("water_bucket", $factory->get(325, 8)); + self::register("wheat", $factory->get(296)); + self::register("wheat_seeds", $factory->get(295)); + self::register("white_banner", $factory->get(446, 15)); + self::register("white_bed", $factory->get(355)); + self::register("white_dye", $factory->get(351, 19)); + self::register("wither_skeleton_skull", $factory->get(397, 1)); + self::register("wooden_axe", $factory->get(271)); + self::register("wooden_hoe", $factory->get(290)); + self::register("wooden_pickaxe", $factory->get(270)); + self::register("wooden_shovel", $factory->get(269)); + self::register("wooden_sword", $factory->get(268)); + self::register("writable_book", $factory->get(386)); + self::register("written_book", $factory->get(387)); + self::register("yellow_banner", $factory->get(446, 11)); + self::register("yellow_bed", $factory->get(355, 4)); + self::register("yellow_dye", $factory->get(351, 11)); + self::register("zombie_head", $factory->get(397, 2)); } } diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index 1a6a79a7ea..e6df8382c5 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -70,7 +70,7 @@ class TypeConverter{ public function recipeIngredientToCoreItemStack(RecipeIngredient $ingredient) : Item{ $meta = $ingredient->getMeta(); - return ItemFactory::get($ingredient->getId(), $meta === 0x7fff ? -1 : $meta, $ingredient->getCount()); + return ItemFactory::getInstance()->get($ingredient->getId(), $meta === 0x7fff ? -1 : $meta, $ingredient->getCount()); } public function coreItemStackToNet(Item $itemStack) : ItemStack{ @@ -124,7 +124,7 @@ class TypeConverter{ } end: - return ItemFactory::get( + return ItemFactory::getInstance()->get( $itemStack->getId(), $meta !== 0x7fff ? $meta : -1, $itemStack->getCount(), diff --git a/src/world/World.php b/src/world/World.php index 4594b5946d..0dbd7ad922 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1464,8 +1464,9 @@ class World implements ChunkManager{ if($player->isAdventure(true) and !$ev->isCancelled()){ $canBreak = false; + $itemFactory = ItemFactory::getInstance(); foreach($item->getCanDestroy() as $v){ - $entry = ItemFactory::fromString($v); + $entry = $itemFactory->fromString($v); if($entry->getBlock()->isSameType($target)){ $canBreak = true; break; @@ -1599,8 +1600,9 @@ class World implements ChunkManager{ $ev = new BlockPlaceEvent($player, $hand, $blockReplace, $blockClicked, $item); if($player->isAdventure(true) and !$ev->isCancelled()){ $canPlace = false; + $itemFactory = ItemFactory::getInstance(); foreach($item->getCanPlaceOn() as $v){ - $entry = ItemFactory::fromString($v); + $entry = $itemFactory->fromString($v); if($entry->getBlock()->isSameType($blockClicked)){ $canPlace = true; break; diff --git a/src/world/generator/Flat.php b/src/world/generator/Flat.php index ffc51eef21..59c09e6520 100644 --- a/src/world/generator/Flat.php +++ b/src/world/generator/Flat.php @@ -99,6 +99,7 @@ class Flat extends Generator{ $result = []; $split = array_map('\trim', explode(',', $layers)); $y = 0; + $itemFactory = ItemFactory::getInstance(); foreach($split as $line){ preg_match('#^(?:(\d+)[x|*])?(.+)$#', $line, $matches); if(count($matches) !== 3){ @@ -107,7 +108,7 @@ class Flat extends Generator{ $cnt = $matches[1] !== "" ? (int) $matches[1] : 1; try{ - $b = ItemFactory::fromString($matches[2])->getBlock(); + $b = $itemFactory->fromString($matches[2])->getBlock(); }catch(\InvalidArgumentException $e){ throw new InvalidGeneratorOptionsException("Invalid preset layer \"$line\": " . $e->getMessage(), 0, $e); } diff --git a/tests/phpunit/inventory/BaseInventoryTest.php b/tests/phpunit/inventory/BaseInventoryTest.php index 4d90235841..9dec6b9c24 100644 --- a/tests/phpunit/inventory/BaseInventoryTest.php +++ b/tests/phpunit/inventory/BaseInventoryTest.php @@ -29,16 +29,12 @@ use pocketmine\item\ItemIds; class BaseInventoryTest extends TestCase{ - public static function setUpBeforeClass() : void{ - ItemFactory::init(); - } - public function testAddItemDifferentUserData() : void{ $inv = new class(1) extends BaseInventory{ }; - $item1 = ItemFactory::get(ItemIds::ARROW, 0, 1); - $item2 = ItemFactory::get(ItemIds::ARROW, 0, 1)->setCustomName("TEST"); + $item1 = ItemFactory::getInstance()->get(ItemIds::ARROW, 0, 1); + $item2 = ItemFactory::getInstance()->get(ItemIds::ARROW, 0, 1)->setCustomName("TEST"); $inv->addItem(clone $item1); self::assertFalse($inv->canAddItem($item2), "Item WITHOUT userdata should not stack with item WITH userdata"); diff --git a/tests/phpunit/item/ItemFactoryTest.php b/tests/phpunit/item/ItemFactoryTest.php index 9e85f06657..723eed6c83 100644 --- a/tests/phpunit/item/ItemFactoryTest.php +++ b/tests/phpunit/item/ItemFactoryTest.php @@ -28,16 +28,12 @@ use pocketmine\block\BlockFactory; class ItemFactoryTest extends TestCase{ - public function setUp() : void{ - ItemFactory::init(); - } - /** * Tests that blocks are considered to be valid registered items */ public function testItemBlockRegistered() : void{ for($id = 0; $id < 256; ++$id){ - self::assertEquals(BlockFactory::getInstance()->isRegistered($id), ItemFactory::isRegistered($id)); + self::assertEquals(BlockFactory::getInstance()->isRegistered($id), ItemFactory::getInstance()->isRegistered($id)); } } @@ -64,7 +60,7 @@ class ItemFactoryTest extends TestCase{ * @param int $meta */ public function testFromStringSingle(string $string, int $id, int $meta) : void{ - $item = ItemFactory::fromString($string); + $item = ItemFactory::getInstance()->fromString($string); self::assertEquals($id, $item->getId()); self::assertEquals($meta, $item->getMeta()); @@ -74,10 +70,10 @@ class ItemFactoryTest extends TestCase{ * Test that durable items are correctly created by the item factory */ public function testGetDurableItem() : void{ - self::assertInstanceOf(Sword::class, $i1 = ItemFactory::get(ItemIds::WOODEN_SWORD)); + self::assertInstanceOf(Sword::class, $i1 = ItemFactory::getInstance()->get(ItemIds::WOODEN_SWORD)); /** @var Sword $i1 */ self::assertSame(0, $i1->getDamage()); - self::assertInstanceOf(Sword::class, $i2 = ItemFactory::get(ItemIds::WOODEN_SWORD, 1)); + self::assertInstanceOf(Sword::class, $i2 = ItemFactory::getInstance()->get(ItemIds::WOODEN_SWORD, 1)); /** @var Sword $i2 */ self::assertSame(1, $i2->getDamage()); } diff --git a/tests/phpunit/item/ItemTest.php b/tests/phpunit/item/ItemTest.php index ee98abb3cf..6a7f14dade 100644 --- a/tests/phpunit/item/ItemTest.php +++ b/tests/phpunit/item/ItemTest.php @@ -30,7 +30,6 @@ use pocketmine\item\enchantment\EnchantmentInstance; class ItemTest extends TestCase{ public static function setUpBeforeClass() : void{ - ItemFactory::init(); Enchantment::init(); } @@ -38,14 +37,14 @@ class ItemTest extends TestCase{ private $item; public function setUp() : void{ - $this->item = ItemFactory::get(ItemIds::DIAMOND_SWORD); + $this->item = ItemFactory::getInstance()->get(ItemIds::DIAMOND_SWORD); } /** * Test for issue #1145 (items aren't considered equal after NBT serializing and deserializing */ public function testItemEquals() : void{ - $item = ItemFactory::get(ItemIds::STONE)->setCustomName("HI"); + $item = ItemFactory::getInstance()->get(ItemIds::STONE)->setCustomName("HI"); $item2 = Item::nbtDeserialize($item->nbtSerialize()); self::assertTrue($item2->equals($item)); self::assertTrue($item->equals($item2)); @@ -55,7 +54,7 @@ class ItemTest extends TestCase{ * Test that same items without NBT are considered equal */ public function testItemEqualsNoNbt() : void{ - $item1 = ItemFactory::get(ItemIds::DIAMOND_SWORD); + $item1 = ItemFactory::getInstance()->get(ItemIds::DIAMOND_SWORD); $item2 = clone $item1; self::assertTrue($item1->equals($item2)); } @@ -67,7 +66,7 @@ class ItemTest extends TestCase{ public function testItemPersistsDisplayProperties() : void{ $lore = ["Line A", "Line B"]; $name = "HI"; - $item = ItemFactory::get(ItemIds::DIAMOND_SWORD); + $item = ItemFactory::getInstance()->get(ItemIds::DIAMOND_SWORD); $item->setCustomName($name); $item->setLore($lore); $item = Item::nbtDeserialize($item->nbtSerialize()); From a5441e009dd5a4357eb29e2d82746f547c687fda Mon Sep 17 00:00:00 2001 From: Muqsit Rayyan Date: Fri, 24 Apr 2020 04:21:00 +0500 Subject: [PATCH 1456/3224] remove "resource/" suffixed to DiskResourceProvider::$file (#3433) --- src/plugin/DiskResourceProvider.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugin/DiskResourceProvider.php b/src/plugin/DiskResourceProvider.php index 9a748aefb4..3ef8e6d66c 100644 --- a/src/plugin/DiskResourceProvider.php +++ b/src/plugin/DiskResourceProvider.php @@ -54,8 +54,8 @@ class DiskResourceProvider implements ResourceProvider{ */ public function getResource(string $filename){ $filename = rtrim(str_replace("\\", "/", $filename), "/"); - if(file_exists($this->file . "resources/" . $filename)){ - $resource = fopen($this->file . "resources/" . $filename, "rb"); + if(file_exists($this->file . $filename)){ + $resource = fopen($this->file . $filename, "rb"); if($resource === false) throw new AssumptionFailedError("fopen() should not fail on a file which exists"); return $resource; } From 5cc03775d374d103674076657348c3ef1fee9914 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 24 Apr 2020 00:30:36 +0100 Subject: [PATCH 1457/3224] added a SingletonTrait to reduce code duplication --- src/block/BlockFactory.php | 11 ++------- src/item/ItemFactory.php | 11 ++------- src/utils/SingletonTrait.php | 44 ++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 18 deletions(-) create mode 100644 src/utils/SingletonTrait.php diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 88ed24cd4a..4f88fbd49d 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -51,6 +51,7 @@ use pocketmine\block\utils\TreeType; use pocketmine\item\Item; use pocketmine\item\ItemIds; use pocketmine\item\ToolTier; +use pocketmine\utils\SingletonTrait; use function array_fill; use function array_filter; use function get_class; @@ -60,15 +61,7 @@ use function min; * Manages block registration and instance creation */ class BlockFactory{ - /** @var self|null */ - private static $instance = null; - - public static function getInstance() : self{ - if(self::$instance === null){ - self::$instance = new self; - } - return self::$instance; - } + use SingletonTrait; /** * @var \SplFixedArray|Block[] diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 02cab6d320..4d6884ff08 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -33,6 +33,7 @@ use pocketmine\entity\EntityFactory; use pocketmine\entity\Living; use pocketmine\inventory\ArmorInventory; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\utils\SingletonTrait; use function constant; use function defined; use function explode; @@ -46,15 +47,7 @@ use function trim; * Manages Item instance creation and registration */ class ItemFactory{ - /** @var self|null */ - private static $instance = null; - - public static function getInstance() : self{ - if(self::$instance === null){ - self::$instance = new self; - } - return self::$instance; - } + use SingletonTrait; /** @var Item[] */ private $list = []; diff --git a/src/utils/SingletonTrait.php b/src/utils/SingletonTrait.php new file mode 100644 index 0000000000..dfffe0b672 --- /dev/null +++ b/src/utils/SingletonTrait.php @@ -0,0 +1,44 @@ + Date: Fri, 24 Apr 2020 00:38:18 +0100 Subject: [PATCH 1458/3224] Convert CreativeInventory to singleton --- src/Server.php | 2 - src/inventory/CreativeInventory.php | 42 +++++++++---------- .../transaction/action/CreateItemAction.php | 2 +- src/network/mcpe/InventoryManager.php | 2 +- 4 files changed, 21 insertions(+), 27 deletions(-) diff --git a/src/Server.php b/src/Server.php index 2deb2f2bf1..567cfb3e3b 100644 --- a/src/Server.php +++ b/src/Server.php @@ -39,7 +39,6 @@ use pocketmine\event\player\PlayerDataSaveEvent; use pocketmine\event\server\CommandEvent; use pocketmine\event\server\DataPacketSendEvent; use pocketmine\event\server\QueryRegenerateEvent; -use pocketmine\inventory\CreativeInventory; use pocketmine\item\enchantment\Enchantment; use pocketmine\lang\Language; use pocketmine\lang\LanguageNotFoundException; @@ -984,7 +983,6 @@ class Server{ EntityFactory::init(); Enchantment::init(); - CreativeInventory::init(); Biome::init(); $this->craftingManager = new CraftingManager(); diff --git a/src/inventory/CreativeInventory.php b/src/inventory/CreativeInventory.php index 45bee9f973..a2666d1bed 100644 --- a/src/inventory/CreativeInventory.php +++ b/src/inventory/CreativeInventory.php @@ -25,22 +25,18 @@ namespace pocketmine\inventory; use pocketmine\item\Durable; use pocketmine\item\Item; +use pocketmine\utils\SingletonTrait; use function file_get_contents; use function json_decode; use const DIRECTORY_SEPARATOR; final class CreativeInventory{ + use SingletonTrait; /** @var Item[] */ - public static $creative = []; + private $creative = []; private function __construct(){ - //NOOP - } - - public static function init() : void{ - self::clear(); - $creativeItems = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla" . DIRECTORY_SEPARATOR . "creativeitems.json"), true); foreach($creativeItems as $data){ @@ -48,7 +44,7 @@ final class CreativeInventory{ if($item->getName() === "Unknown"){ continue; } - self::add($item); + $this->add($item); } } @@ -56,23 +52,23 @@ final class CreativeInventory{ * Removes all previously added items from the creative menu. * Note: Players who are already online when this is called will not see this change. */ - public static function clear() : void{ - self::$creative = []; + public function clear() : void{ + $this->creative = []; } /** * @return Item[] */ - public static function getAll() : array{ - return self::$creative; + public function getAll() : array{ + return $this->creative; } - public static function getItem(int $index) : ?Item{ - return self::$creative[$index] ?? null; + public function getItem(int $index) : ?Item{ + return $this->creative[$index] ?? null; } - public static function getItemIndex(Item $item) : int{ - foreach(self::$creative as $i => $d){ + public function getItemIndex(Item $item) : int{ + foreach($this->creative as $i => $d){ if($item->equals($d, !($item instanceof Durable))){ return $i; } @@ -85,22 +81,22 @@ final class CreativeInventory{ * Adds an item to the creative menu. * Note: Players who are already online when this is called will not see this change. */ - public static function add(Item $item) : void{ - self::$creative[] = clone $item; + public function add(Item $item) : void{ + $this->creative[] = clone $item; } /** * Removes an item from the creative menu. * Note: Players who are already online when this is called will not see this change. */ - public static function remove(Item $item) : void{ - $index = self::getItemIndex($item); + public function remove(Item $item) : void{ + $index = $this->getItemIndex($item); if($index !== -1){ - unset(self::$creative[$index]); + unset($this->creative[$index]); } } - public static function contains(Item $item) : bool{ - return self::getItemIndex($item) !== -1; + public function contains(Item $item) : bool{ + return $this->getItemIndex($item) !== -1; } } diff --git a/src/inventory/transaction/action/CreateItemAction.php b/src/inventory/transaction/action/CreateItemAction.php index 2ecd868a63..18cd4a5368 100644 --- a/src/inventory/transaction/action/CreateItemAction.php +++ b/src/inventory/transaction/action/CreateItemAction.php @@ -39,7 +39,7 @@ class CreateItemAction extends InventoryAction{ } public function isValid(Player $source) : bool{ - return !$source->hasFiniteResources() and CreativeInventory::contains($this->sourceItem); + return !$source->hasFiniteResources() and CreativeInventory::getInstance()->contains($this->sourceItem); } public function execute(Player $source) : void{ diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index b589e57408..bd665dee9f 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -204,7 +204,7 @@ class InventoryManager{ $items = []; $typeConverter = TypeConverter::getInstance(); if(!$this->player->isSpectator()){ //fill it for all gamemodes except spectator - foreach(CreativeInventory::getAll() as $i => $item){ + foreach(CreativeInventory::getInstance()->getAll() as $i => $item){ $items[$i] = $typeConverter->coreItemStackToNet($item); } } From 287bf4274ff96095aacc0967a642a04c1ed239e3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 24 Apr 2020 12:42:43 +0100 Subject: [PATCH 1459/3224] move RuntimeBlockMapping to convert package --- src/block/Block.php | 2 +- .../mcpe/{protocol/types => convert}/RuntimeBlockMapping.php | 2 +- src/network/mcpe/protocol/StartGamePacket.php | 2 +- src/network/mcpe/serializer/ChunkSerializer.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename src/network/mcpe/{protocol/types => convert}/RuntimeBlockMapping.php (99%) diff --git a/src/block/Block.php b/src/block/Block.php index a19610f07a..e653e5b762 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -39,7 +39,7 @@ use pocketmine\math\Facing; use pocketmine\math\RayTraceResult; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; +use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use pocketmine\world\Position; diff --git a/src/network/mcpe/protocol/types/RuntimeBlockMapping.php b/src/network/mcpe/convert/RuntimeBlockMapping.php similarity index 99% rename from src/network/mcpe/protocol/types/RuntimeBlockMapping.php rename to src/network/mcpe/convert/RuntimeBlockMapping.php index da1c0ce795..fc5b4fee3d 100644 --- a/src/network/mcpe/protocol/types/RuntimeBlockMapping.php +++ b/src/network/mcpe/convert/RuntimeBlockMapping.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\convert; use pocketmine\block\BlockLegacyIds; use pocketmine\nbt\NBT; diff --git a/src/network/mcpe/protocol/StartGamePacket.php b/src/network/mcpe/protocol/StartGamePacket.php index f6ef854f99..ce1a8b8de3 100644 --- a/src/network/mcpe/protocol/StartGamePacket.php +++ b/src/network/mcpe/protocol/StartGamePacket.php @@ -29,7 +29,7 @@ use pocketmine\math\Vector3; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; -use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; +use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; use function count; diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index 06dc2e1f22..a388bfc279 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\serializer; use pocketmine\block\tile\Spawnable; -use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; +use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\utils\BinaryStream; use pocketmine\world\format\Chunk; use function count; From ff915b829cebf2965403642468404909322dc80e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 24 Apr 2020 20:50:56 +0100 Subject: [PATCH 1460/3224] StartGamePacket: remove hardcoded cache, move to RuntimeBlockMapping --- .../mcpe/convert/RuntimeBlockMapping.php | 14 +++++ .../mcpe/handler/PreSpawnPacketHandler.php | 3 + src/network/mcpe/protocol/StartGamePacket.php | 25 +++----- .../mcpe/protocol/types/CacheableNbt.php | 60 +++++++++++++++++++ 4 files changed, 86 insertions(+), 16 deletions(-) create mode 100644 src/network/mcpe/protocol/types/CacheableNbt.php diff --git a/src/network/mcpe/convert/RuntimeBlockMapping.php b/src/network/mcpe/convert/RuntimeBlockMapping.php index fc5b4fee3d..dd1378daf7 100644 --- a/src/network/mcpe/convert/RuntimeBlockMapping.php +++ b/src/network/mcpe/convert/RuntimeBlockMapping.php @@ -27,6 +27,7 @@ use pocketmine\block\BlockLegacyIds; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; +use pocketmine\network\mcpe\protocol\types\CacheableNbt; use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; use function file_get_contents; use function getmypid; @@ -56,6 +57,11 @@ final class RuntimeBlockMapping{ private $runtimeToLegacyMap = []; /** @var CompoundTag[]|null */ private $bedrockKnownStates = null; + /** + * @var CacheableNbt|null + * @phpstan-var CacheableNbt<\pocketmine\nbt\tag\ListTag>|null + */ + private $startGamePaletteCache = null; private function __construct(){ $tag = (new NetworkNbtSerializer())->read(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla/required_block_states.nbt"))->getTag(); @@ -146,6 +152,7 @@ final class RuntimeBlockMapping{ private function registerMapping(int $staticRuntimeId, int $legacyId, int $legacyMeta) : void{ $this->legacyToRuntimeMap[($legacyId << 4) | $legacyMeta] = $staticRuntimeId; $this->runtimeToLegacyMap[$staticRuntimeId] = ($legacyId << 4) | $legacyMeta; + $this->startGamePaletteCache = null; } /** @@ -154,4 +161,11 @@ final class RuntimeBlockMapping{ public function getBedrockKnownStates() : array{ return $this->bedrockKnownStates; } + + /** + * @phpstan-return CacheableNbt<\pocketmine\nbt\tag\ListTag> + */ + public function getStartGamePaletteCache() : ?CacheableNbt{ + return $this->startGamePaletteCache ?? new CacheableNbt(new ListTag($this->bedrockKnownStates)); + } } diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index 435d297b53..13cccb07cc 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; +use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\AvailableActorIdentifiersPacket; use pocketmine\network\mcpe\protocol\BiomeDefinitionListPacket; @@ -77,6 +78,8 @@ class PreSpawnPacketHandler extends PacketHandler{ $pk->commandsEnabled = true; $pk->levelId = ""; $pk->worldName = $this->server->getMotd(); + $pk->blockTable = RuntimeBlockMapping::getInstance()->getStartGamePaletteCache(); + $this->session->sendDataPacket($pk); $this->session->sendDataPacket(new AvailableActorIdentifiersPacket()); diff --git a/src/network/mcpe/protocol/StartGamePacket.php b/src/network/mcpe/protocol/StartGamePacket.php index ce1a8b8de3..241afa12d5 100644 --- a/src/network/mcpe/protocol/StartGamePacket.php +++ b/src/network/mcpe/protocol/StartGamePacket.php @@ -27,9 +27,8 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\nbt\tag\ListTag; -use pocketmine\nbt\TreeRoot; +use pocketmine\network\mcpe\protocol\types\CacheableNbt; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; -use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; use function count; @@ -40,8 +39,6 @@ use const pocketmine\RESOURCE_PATH; class StartGamePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::START_GAME_PACKET; - /** @var string|null */ - private static $blockTableCache = null; /** @var string|null */ private static $itemTableCache = null; @@ -153,8 +150,11 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $multiplayerCorrelationId = ""; //TODO: this should be filled with a UUID of some sort - /** @var ListTag|null */ - public $blockTable = null; + /** + * @var CacheableNbt + * @phpstan-var CacheableNbt<\pocketmine\nbt\tag\ListTag> + */ + public $blockTable; /** * @var int[]|null string (name) => int16 (legacyID) * @phpstan-var array|null @@ -220,7 +220,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{ if(!($blockTable instanceof ListTag)){ throw new \UnexpectedValueException("Wrong block table root NBT tag type"); } - $this->blockTable = $blockTable; + $this->blockTable = new CacheableNbt($blockTable); $this->itemTable = []; for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ @@ -286,15 +286,8 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{ $out->putVarInt($this->enchantmentSeed); - if($this->blockTable === null){ - if(self::$blockTableCache === null){ - //this is a really nasty hack, but it'll do for now - self::$blockTableCache = (new NetworkNbtSerializer())->write(new TreeRoot(new ListTag(RuntimeBlockMapping::getInstance()->getBedrockKnownStates()))); - } - $out->put(self::$blockTableCache); - }else{ - $out->put((new NetworkNbtSerializer())->write(new TreeRoot($this->blockTable))); - } + $out->put($this->blockTable->getEncodedNbt()); + if($this->itemTable === null){ if(self::$itemTableCache === null){ self::$itemTableCache = self::serializeItemTable(json_decode(file_get_contents(RESOURCE_PATH . '/vanilla/item_id_map.json'), true)); diff --git a/src/network/mcpe/protocol/types/CacheableNbt.php b/src/network/mcpe/protocol/types/CacheableNbt.php new file mode 100644 index 0000000000..43439500e3 --- /dev/null +++ b/src/network/mcpe/protocol/types/CacheableNbt.php @@ -0,0 +1,60 @@ +root = $nbtRoot; + } + + /** + * @phpstan-return TTagType + */ + public function getRoot() : Tag{ + return $this->root; + } + + public function getEncodedNbt() : string{ + return $this->encodedNbt ?? ($this->encodedNbt = (new NetworkNbtSerializer())->write(new TreeRoot($this->root))); + } +} From 1df345ba6fd7fcc4243d1a4e140c907c83c3d02b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 24 Apr 2020 20:55:57 +0100 Subject: [PATCH 1461/3224] tools/convert-world: do not redefine RESOURCE_PATH this is now defined automatically when including the autoloader. --- tools/convert-world.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/convert-world.php b/tools/convert-world.php index c61d8651d5..8caab26927 100644 --- a/tools/convert-world.php +++ b/tools/convert-world.php @@ -31,8 +31,6 @@ require_once dirname(__DIR__) . '/vendor/autoload.php'; WorldProviderManager::init(); GeneratorManager::registerDefaultGenerators(); -define('pocketmine\RESOURCE_PATH', dirname(__DIR__) . '/resources/'); - $writableFormats = array_filter(WorldProviderManager::getAvailableProviders(), function(string $class){ return is_a($class, WritableWorldProvider::class, true); From 3a42c21cc18ca5e603e68269edc0ad65de70540e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 24 Apr 2020 21:28:27 +0100 Subject: [PATCH 1462/3224] wrap up block_id_map in a class --- .../bedrock/LegacyBlockIdToStringIdMap.php | 69 +++++++++++++++++++ .../mcpe/convert/RuntimeBlockMapping.php | 9 ++- src/world/format/io/leveldb/LevelDB.php | 19 ++--- 3 files changed, 80 insertions(+), 17 deletions(-) create mode 100644 src/data/bedrock/LegacyBlockIdToStringIdMap.php diff --git a/src/data/bedrock/LegacyBlockIdToStringIdMap.php b/src/data/bedrock/LegacyBlockIdToStringIdMap.php new file mode 100644 index 0000000000..de012d850a --- /dev/null +++ b/src/data/bedrock/LegacyBlockIdToStringIdMap.php @@ -0,0 +1,69 @@ + + */ + private $legacyToString = []; + /** + * @var int[] + * @phpstan-var array + */ + private $stringToLegacy = []; + + public function __construct(){ + $stringToLegacyId = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . 'vanilla/block_id_map.json'), true); + if(!is_array($stringToLegacyId)){ + throw new AssumptionFailedError("Invalid format of block_id_map"); + } + foreach($stringToLegacyId as $stringId => $legacyId){ + if(!is_string($stringId) or !is_int($legacyId)){ + throw new AssumptionFailedError("Block ID map should have string keys and int values"); + } + $this->legacyToString[$legacyId] = $stringId; + $this->stringToLegacy[$stringId] = $legacyId; + } + } + + public function legacyToString(int $legacy) : ?string{ + return $this->legacyToString[$legacy] ?? null; + } + + public function stringToLegacy(string $string) : ?int{ + return $this->stringToLegacy[$string] ?? null; + } +} \ No newline at end of file diff --git a/src/network/mcpe/convert/RuntimeBlockMapping.php b/src/network/mcpe/convert/RuntimeBlockMapping.php index dd1378daf7..570878defe 100644 --- a/src/network/mcpe/convert/RuntimeBlockMapping.php +++ b/src/network/mcpe/convert/RuntimeBlockMapping.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\convert; use pocketmine\block\BlockLegacyIds; +use pocketmine\data\bedrock\LegacyBlockIdToStringIdMap; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; @@ -31,7 +32,6 @@ use pocketmine\network\mcpe\protocol\types\CacheableNbt; use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; use function file_get_contents; use function getmypid; -use function json_decode; use function mt_rand; use function mt_srand; use function shuffle; @@ -77,7 +77,7 @@ final class RuntimeBlockMapping{ } private function setupLegacyMappings() : void{ - $legacyIdMap = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla/block_id_map.json"), true); + $legacyIdMap = LegacyBlockIdToStringIdMap::getInstance(); $legacyStateMap = (new NetworkNbtSerializer())->read(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla/r12_to_current_block_map.nbt"))->getTag(); if(!($legacyStateMap instanceof ListTag) or $legacyStateMap->getTagType() !== NBT::TAG_Compound){ throw new \RuntimeException("Invalid legacy states mapping table, expected TAG_List root"); @@ -93,7 +93,10 @@ final class RuntimeBlockMapping{ /** @var CompoundTag $pair */ foreach($legacyStateMap as $pair){ $oldState = $pair->getCompoundTag("old"); - $id = $legacyIdMap[$oldState->getString("name")]; + $id = $legacyIdMap->stringToLegacy($oldState->getString("name")); + if($id === null){ + throw new \RuntimeException("State does not have a legacy ID"); + } $data = $oldState->getShort("val"); if($data > 15){ //we can't handle metadata with more than 4 bits diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index a765dd03f5..7bd49dac77 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\world\format\io\leveldb; use pocketmine\block\BlockLegacyIds; +use pocketmine\data\bedrock\LegacyBlockIdToStringIdMap; use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; @@ -45,7 +46,6 @@ use pocketmine\world\format\io\WritableWorldProvider; use pocketmine\world\format\PalettedBlockArray; use pocketmine\world\format\SubChunk; use pocketmine\world\generator\Generator; -use function array_flip; use function array_map; use function array_values; use function chr; @@ -53,9 +53,7 @@ use function count; use function defined; use function extension_loaded; use function file_exists; -use function file_get_contents; use function is_dir; -use function json_decode; use function mkdir; use function ord; use function str_repeat; @@ -153,11 +151,6 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ } protected function deserializePaletted(BinaryStream $stream) : PalettedBlockArray{ - static $stringToLegacyId = null; - if($stringToLegacyId === null){ - $stringToLegacyId = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . 'vanilla/block_id_map.json'), true); - } - $bitsPerBlock = $stream->getByte() >> 1; try{ @@ -167,12 +160,13 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ } $nbt = new LittleEndianNbtSerializer(); $palette = []; + $idMap = LegacyBlockIdToStringIdMap::getInstance(); for($i = 0, $paletteSize = $stream->getLInt(); $i < $paletteSize; ++$i){ $offset = $stream->getOffset(); $tag = $nbt->read($stream->getBuffer(), $offset)->mustGetCompoundTag(); $stream->setOffset($offset); - $id = $stringToLegacyId[$tag->getString("name")] ?? BlockLegacyIds::INFO_UPDATE; + $id = $idMap->stringToLegacy($tag->getString("name")) ?? BlockLegacyIds::INFO_UPDATE; $data = $tag->getShort("val"); $palette[] = ($id << 4) | $data; } @@ -419,10 +413,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ } protected function writeChunk(Chunk $chunk) : void{ - static $idMap = null; - if($idMap === null){ - $idMap = array_flip(json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . 'vanilla/block_id_map.json'), true)); - } + $idMap = LegacyBlockIdToStringIdMap::getInstance(); $index = LevelDB::chunkIndex($chunk->getX(), $chunk->getZ()); $write = new \LevelDBWriteBatch(); @@ -449,7 +440,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $tags = []; foreach($palette as $p){ $tags[] = new TreeRoot(CompoundTag::create() - ->setString("name", $idMap[$p >> 4] ?? "minecraft:info_update") + ->setString("name", $idMap->legacyToString($p >> 4) ?? "minecraft:info_update") ->setInt("oldid", $p >> 4) //PM only (debugging), vanilla doesn't have this ->setShort("val", $p & 0xf)); } From a75241ef03bc92121d68bcc3b981b3b7a63b6d65 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 24 Apr 2020 21:32:47 +0100 Subject: [PATCH 1463/3224] RuntimeBlockMapping: use SingletonTrait --- src/network/mcpe/convert/RuntimeBlockMapping.php | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/network/mcpe/convert/RuntimeBlockMapping.php b/src/network/mcpe/convert/RuntimeBlockMapping.php index 570878defe..367a3af14a 100644 --- a/src/network/mcpe/convert/RuntimeBlockMapping.php +++ b/src/network/mcpe/convert/RuntimeBlockMapping.php @@ -30,6 +30,7 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\protocol\types\CacheableNbt; use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; +use pocketmine\utils\SingletonTrait; use function file_get_contents; use function getmypid; use function mt_rand; @@ -40,16 +41,7 @@ use function shuffle; * @internal */ final class RuntimeBlockMapping{ - /** @var self|null */ - private static $instance = null; - - public static function getInstance() : self{ - if(self::$instance === null){ - self::$instance = new self; - } - - return self::$instance; - } + use SingletonTrait; /** @var int[] */ private $legacyToRuntimeMap = []; From 7d9df6af6f180d91e5df41f8b06ce68648c15aed Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 24 Apr 2020 22:43:02 +0100 Subject: [PATCH 1464/3224] Convert EntityFactory to singleton --- src/Server.php | 2 - src/block/TNT.php | 2 +- src/block/utils/FallableTrait.php | 2 +- src/entity/Entity.php | 2 +- src/entity/EntityFactory.php | 88 +++++++++++++++---------------- src/item/Bow.php | 2 +- src/item/ItemFactory.php | 2 +- src/item/PaintingItem.php | 2 +- src/item/ProjectileItem.php | 2 +- src/item/SpawnEgg.php | 2 +- src/world/World.php | 4 +- src/world/format/Chunk.php | 3 +- 12 files changed, 54 insertions(+), 59 deletions(-) diff --git a/src/Server.php b/src/Server.php index 567cfb3e3b..eac08dea9f 100644 --- a/src/Server.php +++ b/src/Server.php @@ -33,7 +33,6 @@ use pocketmine\command\ConsoleCommandSender; use pocketmine\command\PluginIdentifiableCommand; use pocketmine\command\SimpleCommandMap; use pocketmine\crafting\CraftingManager; -use pocketmine\entity\EntityFactory; use pocketmine\event\HandlerListManager; use pocketmine\event\player\PlayerDataSaveEvent; use pocketmine\event\server\CommandEvent; @@ -981,7 +980,6 @@ class Server{ $this->commandMap = new SimpleCommandMap($this); - EntityFactory::init(); Enchantment::init(); Biome::init(); diff --git a/src/block/TNT.php b/src/block/TNT.php index b42b06d5af..b20b090167 100644 --- a/src/block/TNT.php +++ b/src/block/TNT.php @@ -97,7 +97,7 @@ class TNT extends Opaque{ $nbt->setShort("Fuse", $fuse); /** @var PrimedTNT $tnt */ - $tnt = EntityFactory::create(PrimedTNT::class, $this->pos->getWorldNonNull(), $nbt); + $tnt = EntityFactory::getInstance()->create(PrimedTNT::class, $this->pos->getWorldNonNull(), $nbt); $tnt->spawnToAll(); } diff --git a/src/block/utils/FallableTrait.php b/src/block/utils/FallableTrait.php index 1d22c123ec..c1a0817035 100644 --- a/src/block/utils/FallableTrait.php +++ b/src/block/utils/FallableTrait.php @@ -56,7 +56,7 @@ trait FallableTrait{ $nbt->setByte("Data", $this->getMeta()); /** @var FallingBlock $fall */ - $fall = EntityFactory::create(FallingBlock::class, $pos->getWorldNonNull(), $nbt); + $fall = EntityFactory::getInstance()->create(FallingBlock::class, $pos->getWorldNonNull(), $nbt); $fall->spawnToAll(); } } diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 0d3dce992a..84fafbdcff 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -490,7 +490,7 @@ abstract class Entity{ public function saveNBT() : CompoundTag{ $nbt = new CompoundTag(); if(!($this instanceof Player)){ - $nbt->setString("id", EntityFactory::getSaveId(get_class($this))); + $nbt->setString("id", EntityFactory::getInstance()->getSaveId(get_class($this))); if($this->getNameTag() !== ""){ $nbt->setString("CustomName", $this->getNameTag()); diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index 198fff6217..a8119ed5d0 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -43,6 +43,7 @@ use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\utils\SingletonTrait; use pocketmine\utils\Utils; use pocketmine\world\World; use function array_keys; @@ -60,52 +61,47 @@ use function reset; * create(MyEntity::class) instead of `new MyEntity()` if you want to allow this. */ final class EntityFactory{ + use SingletonTrait; /** @var int */ private static $entityCount = 1; + /** * @var string[] base class => currently used class for construction * @phpstan-var array, class-string> */ - private static $classMapping = []; + private $classMapping = []; /** * @var string[] * @phpstan-var array> */ - private static $knownEntities = []; + private $knownEntities = []; /** * @var string[][] * @phpstan-var array, list> */ - private static $saveNames = []; + private $saveNames = []; - private function __construct(){ - //NOOP - } - - /** - * Called on server startup to register default entity types. - */ - public static function init() : void{ + public function __construct(){ //define legacy save IDs first - use them for saving for maximum compatibility with Minecraft PC //TODO: index them by version to allow proper multi-save compatibility - self::register(Arrow::class, ['Arrow', 'minecraft:arrow'], EntityLegacyIds::ARROW); - self::register(Egg::class, ['Egg', 'minecraft:egg'], EntityLegacyIds::EGG); - self::register(EnderPearl::class, ['ThrownEnderpearl', 'minecraft:ender_pearl'], EntityLegacyIds::ENDER_PEARL); - self::register(ExperienceBottle::class, ['ThrownExpBottle', 'minecraft:xp_bottle'], EntityLegacyIds::XP_BOTTLE); - self::register(ExperienceOrb::class, ['XPOrb', 'minecraft:xp_orb'], EntityLegacyIds::XP_ORB); - self::register(FallingBlock::class, ['FallingSand', 'minecraft:falling_block'], EntityLegacyIds::FALLING_BLOCK); - self::register(ItemEntity::class, ['Item', 'minecraft:item'], EntityLegacyIds::ITEM); - self::register(Painting::class, ['Painting', 'minecraft:painting'], EntityLegacyIds::PAINTING); - self::register(PrimedTNT::class, ['PrimedTnt', 'PrimedTNT', 'minecraft:tnt'], EntityLegacyIds::TNT); - self::register(Snowball::class, ['Snowball', 'minecraft:snowball'], EntityLegacyIds::SNOWBALL); - self::register(SplashPotion::class, ['ThrownPotion', 'minecraft:potion', 'thrownpotion'], EntityLegacyIds::SPLASH_POTION); - self::register(Squid::class, ['Squid', 'minecraft:squid'], EntityLegacyIds::SQUID); - self::register(Villager::class, ['Villager', 'minecraft:villager'], EntityLegacyIds::VILLAGER); - self::register(Zombie::class, ['Zombie', 'minecraft:zombie'], EntityLegacyIds::ZOMBIE); + $this->register(Arrow::class, ['Arrow', 'minecraft:arrow'], EntityLegacyIds::ARROW); + $this->register(Egg::class, ['Egg', 'minecraft:egg'], EntityLegacyIds::EGG); + $this->register(EnderPearl::class, ['ThrownEnderpearl', 'minecraft:ender_pearl'], EntityLegacyIds::ENDER_PEARL); + $this->register(ExperienceBottle::class, ['ThrownExpBottle', 'minecraft:xp_bottle'], EntityLegacyIds::XP_BOTTLE); + $this->register(ExperienceOrb::class, ['XPOrb', 'minecraft:xp_orb'], EntityLegacyIds::XP_ORB); + $this->register(FallingBlock::class, ['FallingSand', 'minecraft:falling_block'], EntityLegacyIds::FALLING_BLOCK); + $this->register(ItemEntity::class, ['Item', 'minecraft:item'], EntityLegacyIds::ITEM); + $this->register(Painting::class, ['Painting', 'minecraft:painting'], EntityLegacyIds::PAINTING); + $this->register(PrimedTNT::class, ['PrimedTnt', 'PrimedTNT', 'minecraft:tnt'], EntityLegacyIds::TNT); + $this->register(Snowball::class, ['Snowball', 'minecraft:snowball'], EntityLegacyIds::SNOWBALL); + $this->register(SplashPotion::class, ['ThrownPotion', 'minecraft:potion', 'thrownpotion'], EntityLegacyIds::SPLASH_POTION); + $this->register(Squid::class, ['Squid', 'minecraft:squid'], EntityLegacyIds::SQUID); + $this->register(Villager::class, ['Villager', 'minecraft:villager'], EntityLegacyIds::VILLAGER); + $this->register(Zombie::class, ['Zombie', 'minecraft:zombie'], EntityLegacyIds::ZOMBIE); - self::register(Human::class, ['Human']); + $this->register(Human::class, ['Human']); Attribute::init(); PaintingMotive::init(); @@ -124,10 +120,10 @@ final class EntityFactory{ * * @throws \InvalidArgumentException */ - public static function register(string $className, array $saveNames, ?int $legacyMcpeSaveId = null) : void{ + public function register(string $className, array $saveNames, ?int $legacyMcpeSaveId = null) : void{ Utils::testValidInstance($className, Entity::class); - self::$classMapping[$className] = $className; + $this->classMapping[$className] = $className; $shortName = (new \ReflectionClass($className))->getShortName(); if(!in_array($shortName, $saveNames, true)){ @@ -135,13 +131,13 @@ final class EntityFactory{ } foreach($saveNames as $name){ - self::$knownEntities[$name] = $className; + $this->knownEntities[$name] = $className; } if($legacyMcpeSaveId !== null){ - self::$knownEntities[$legacyMcpeSaveId] = $className; + $this->knownEntities[$legacyMcpeSaveId] = $className; } - self::$saveNames[$className] = $saveNames; + $this->saveNames[$className] = $saveNames; } /** @@ -157,13 +153,13 @@ final class EntityFactory{ * * @throws \InvalidArgumentException */ - public static function override(string $baseClass, string $newClass) : void{ - if(!isset(self::$classMapping[$baseClass])){ + public function override(string $baseClass, string $newClass) : void{ + if(!isset($this->classMapping[$baseClass])){ throw new \InvalidArgumentException("Class $baseClass is not a registered entity"); } Utils::testValidInstance($newClass, $baseClass); - self::$classMapping[$baseClass] = $newClass; + $this->classMapping[$baseClass] = $newClass; } /** @@ -172,8 +168,8 @@ final class EntityFactory{ * @return string[] * @return class-string[] */ - public static function getKnownTypes() : array{ - return array_keys(self::$classMapping); + public function getKnownTypes() : array{ + return array_keys($this->classMapping); } /** @@ -199,9 +195,9 @@ final class EntityFactory{ * * @throws \InvalidArgumentException if the class doesn't exist or is not registered */ - public static function create(string $baseClass, World $world, CompoundTag $nbt, ...$args) : Entity{ - if(isset(self::$classMapping[$baseClass])){ - $class = self::$classMapping[$baseClass]; + public function create(string $baseClass, World $world, CompoundTag $nbt, ...$args) : Entity{ + if(isset($this->classMapping[$baseClass])){ + $class = $this->classMapping[$baseClass]; assert(is_a($class, $baseClass, true)); /** * @var Entity $entity @@ -222,18 +218,18 @@ final class EntityFactory{ * @throws \RuntimeException * @internal */ - public static function createFromData(World $world, CompoundTag $nbt) : ?Entity{ + public function createFromData(World $world, CompoundTag $nbt) : ?Entity{ $saveId = $nbt->getTag("id") ?? $nbt->getTag("identifier"); $baseClass = null; if($saveId instanceof StringTag){ - $baseClass = self::$knownEntities[$saveId->getValue()] ?? null; + $baseClass = $this->knownEntities[$saveId->getValue()] ?? null; }elseif($saveId instanceof IntTag){ //legacy MCPE format - $baseClass = self::$knownEntities[$saveId->getValue() & 0xff] ?? null; + $baseClass = $this->knownEntities[$saveId->getValue() & 0xff] ?? null; } if($baseClass === null){ return null; } - $class = self::$classMapping[$baseClass]; + $class = $this->classMapping[$baseClass]; assert(is_a($class, $baseClass, true)); /** * @var Entity $entity @@ -247,9 +243,9 @@ final class EntityFactory{ /** * @phpstan-param class-string $class */ - public static function getSaveId(string $class) : string{ - if(isset(self::$saveNames[$class])){ - return reset(self::$saveNames[$class]); + public function getSaveId(string $class) : string{ + if(isset($this->saveNames[$class])){ + return reset($this->saveNames[$class]); } throw new \InvalidArgumentException("Entity $class is not registered"); } diff --git a/src/item/Bow.php b/src/item/Bow.php index 1700f1381f..673c696b73 100644 --- a/src/item/Bow.php +++ b/src/item/Bow.php @@ -64,7 +64,7 @@ class Bow extends Tool{ $baseForce = min((($p ** 2) + $p * 2) / 3, 1); /** @var ArrowEntity $entity */ - $entity = EntityFactory::create(ArrowEntity::class, $location->getWorld(), $nbt, $player, $baseForce >= 1); + $entity = EntityFactory::getInstance()->create(ArrowEntity::class, $location->getWorld(), $nbt, $player, $baseForce >= 1); $infinity = $this->hasEnchantment(Enchantment::INFINITY()); if($infinity){ diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 4d6884ff08..2f54c4ec60 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -257,7 +257,7 @@ class ItemFactory{ $this->register(new SplashPotion(ItemIds::SPLASH_POTION, $type, "Splash Potion")); } - foreach(EntityFactory::getKnownTypes() as $className){ + foreach(EntityFactory::getInstance()->getKnownTypes() as $className){ /** @var Living|string $className */ if(is_a($className, Living::class, true) and $className::NETWORK_ID !== -1){ $this->register(new SpawnEgg(ItemIds::SPAWN_EGG, $className::NETWORK_ID, "Spawn Egg", $className)); diff --git a/src/item/PaintingItem.php b/src/item/PaintingItem.php index 54d6d7ffa7..1bd726510a 100644 --- a/src/item/PaintingItem.php +++ b/src/item/PaintingItem.php @@ -94,7 +94,7 @@ class PaintingItem extends Item{ $nbt->setInt("TileZ", $clickedPos->getFloorZ()); /** @var Painting $entity */ - $entity = EntityFactory::create(Painting::class, $replacePos->getWorldNonNull(), $nbt); + $entity = EntityFactory::getInstance()->create(Painting::class, $replacePos->getWorldNonNull(), $nbt); $this->pop(); $entity->spawnToAll(); diff --git a/src/item/ProjectileItem.php b/src/item/ProjectileItem.php index 27e7b403e8..027b6b86ed 100644 --- a/src/item/ProjectileItem.php +++ b/src/item/ProjectileItem.php @@ -60,7 +60,7 @@ abstract class ProjectileItem extends Item{ Utils::testValidInstance($class, Throwable::class); /** @var Throwable $projectile */ - $projectile = EntityFactory::create($class, $location->getWorld(), $nbt, $player); + $projectile = EntityFactory::getInstance()->create($class, $location->getWorld(), $nbt, $player); $projectile->setMotion($projectile->getMotion()->multiply($this->getThrowForce())); $projectileEv = new ProjectileLaunchEvent($projectile); diff --git a/src/item/SpawnEgg.php b/src/item/SpawnEgg.php index 0982839144..d743255269 100644 --- a/src/item/SpawnEgg.php +++ b/src/item/SpawnEgg.php @@ -58,7 +58,7 @@ class SpawnEgg extends Item{ $nbt->setString("CustomName", $this->getCustomName()); } - $entity = EntityFactory::create($this->entityClass, $player->getWorld(), $nbt); + $entity = EntityFactory::getInstance()->create($this->entityClass, $player->getWorld(), $nbt); $this->pop(); $entity->spawnToAll(); //TODO: what if the entity was marked for deletion? diff --git a/src/world/World.php b/src/world/World.php index 0dbd7ad922..a1ccf69be6 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1397,7 +1397,7 @@ class World implements ChunkManager{ $nbt->setTag("Item", $item->nbtSerialize()); /** @var ItemEntity $itemEntity */ - $itemEntity = EntityFactory::create(ItemEntity::class, $this, $nbt); + $itemEntity = EntityFactory::getInstance()->create(ItemEntity::class, $this, $nbt); $itemEntity->spawnToAll(); return $itemEntity; @@ -1422,7 +1422,7 @@ class World implements ChunkManager{ $nbt->setShort(ExperienceOrb::TAG_VALUE_PC, $split); /** @var ExperienceOrb $orb */ - $orb = EntityFactory::create(ExperienceOrb::class, $this, $nbt); + $orb = EntityFactory::getInstance()->create(ExperienceOrb::class, $this, $nbt); $orb->spawnToAll(); $orbs[] = $orb; } diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 09c329b61f..bbfa169716 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -507,9 +507,10 @@ class Chunk{ if($this->NBTentities !== null){ $this->dirtyFlags |= self::DIRTY_FLAG_ENTITIES; $world->timings->syncChunkLoadEntitiesTimer->startTiming(); + $entityFactory = EntityFactory::getInstance(); foreach($this->NBTentities as $nbt){ try{ - $entity = EntityFactory::createFromData($world, $nbt); + $entity = $entityFactory->createFromData($world, $nbt); if(!($entity instanceof Entity)){ $saveIdTag = $nbt->getTag("id") ?? $nbt->getTag("identifier"); $saveId = ""; From c869a7f099237ca189dc574fe3df6e7630eeec51 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 24 Apr 2020 23:18:29 +0100 Subject: [PATCH 1465/3224] HandshakePacketHandler no longer depends on NetworkSession --- src/network/mcpe/NetworkSession.php | 6 +- .../mcpe/handler/HandshakePacketHandler.php | 17 +++-- src/world/biome/BiomeRegistry.php | 69 +++++++++++++++++++ 3 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 src/world/biome/BiomeRegistry.php diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 85863b12fd..be754503fd 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -548,7 +548,9 @@ class NetworkSession{ $this->cipher = new NetworkCipher($encryptionKey); - $this->setHandler(new HandshakePacketHandler($this)); + $this->setHandler(new HandshakePacketHandler(function() : void{ + $this->onLoginSuccess(); + })); $this->logger->debug("Enabled encryption"); })); }else{ @@ -557,7 +559,7 @@ class NetworkSession{ } } - public function onLoginSuccess() : void{ + private function onLoginSuccess() : void{ $this->loggedIn = true; $this->sendDataPacket(PlayStatusPacket::create(PlayStatusPacket::LOGIN_SUCCESS)); diff --git a/src/network/mcpe/handler/HandshakePacketHandler.php b/src/network/mcpe/handler/HandshakePacketHandler.php index 451351941a..ed64da49f8 100644 --- a/src/network/mcpe/handler/HandshakePacketHandler.php +++ b/src/network/mcpe/handler/HandshakePacketHandler.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; -use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\ClientToServerHandshakePacket; /** @@ -31,15 +30,21 @@ use pocketmine\network\mcpe\protocol\ClientToServerHandshakePacket; */ class HandshakePacketHandler extends PacketHandler{ - /** @var NetworkSession */ - private $session; + /** + * @var \Closure + * @phpstan-var \Closure() : void + */ + private $onHandshakeCompleted; - public function __construct(NetworkSession $session){ - $this->session = $session; + /** + * @phpstan-param \Closure() : void $onHandshakeCompleted + */ + public function __construct(\Closure $onHandshakeCompleted){ + $this->onHandshakeCompleted = $onHandshakeCompleted; } public function handleClientToServerHandshake(ClientToServerHandshakePacket $packet) : bool{ - $this->session->onLoginSuccess(); + ($this->onHandshakeCompleted)(); return true; } } diff --git a/src/world/biome/BiomeRegistry.php b/src/world/biome/BiomeRegistry.php new file mode 100644 index 0000000000..83e4023ea3 --- /dev/null +++ b/src/world/biome/BiomeRegistry.php @@ -0,0 +1,69 @@ + + */ + private $biomes; + + public function __construct(){ + $this->biomes = new \SplFixedArray(Biome::MAX_BIOMES); + + $this->register(Biome::OCEAN, new OceanBiome()); + $this->register(Biome::PLAINS, new PlainBiome()); + $this->register(Biome::DESERT, new DesertBiome()); + $this->register(Biome::MOUNTAINS, new MountainsBiome()); + $this->register(Biome::FOREST, new ForestBiome()); + $this->register(Biome::TAIGA, new TaigaBiome()); + $this->register(Biome::SWAMP, new SwampBiome()); + $this->register(Biome::RIVER, new RiverBiome()); + + $this->register(Biome::ICE_PLAINS, new IcePlainsBiome()); + + $this->register(Biome::SMALL_MOUNTAINS, new SmallMountainsBiome()); + + $this->register(Biome::BIRCH_FOREST, new ForestBiome(TreeType::BIRCH())); + } + + public function register(int $id, Biome $biome) : void{ + $this->biomes[$id] = $biome; + $biome->setId($id); + } + + public function getBiome(int $id) : Biome{ + if($this->biomes[$id] === null){ + $this->register($id, new UnknownBiome()); + } + + return $this->biomes[$id]; + } +} \ No newline at end of file From 4fbf4dcdc68477bfc081e629de3df806685e5e8b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 24 Apr 2020 23:44:38 +0100 Subject: [PATCH 1466/3224] Rename InventoryChangeListener -> InventoryListener --- src/block/tile/BrewingStand.php | 4 ++-- src/block/tile/ContainerTrait.php | 6 +++--- src/block/tile/Furnace.php | 4 ++-- src/entity/Human.php | 6 +++--- src/entity/Living.php | 4 ++-- src/inventory/BaseInventory.php | 10 +++++----- ...ngeListener.php => CallbackInventoryListener.php} | 2 +- src/inventory/Inventory.php | 12 ++++++------ ...ntoryChangeListener.php => InventoryListener.php} | 8 ++++---- 9 files changed, 28 insertions(+), 28 deletions(-) rename src/inventory/{CallbackInventoryChangeListener.php => CallbackInventoryListener.php} (97%) rename src/inventory/{InventoryChangeListener.php => InventoryListener.php} (85%) diff --git a/src/block/tile/BrewingStand.php b/src/block/tile/BrewingStand.php index 350a8209e4..740578e7ff 100644 --- a/src/block/tile/BrewingStand.php +++ b/src/block/tile/BrewingStand.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block\tile; use pocketmine\inventory\BrewingStandInventory; -use pocketmine\inventory\CallbackInventoryChangeListener; +use pocketmine\inventory\CallbackInventoryListener; use pocketmine\inventory\Inventory; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; @@ -54,7 +54,7 @@ class BrewingStand extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); $this->inventory = new BrewingStandInventory($this->pos); - $this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange(function(Inventory $unused) : void{ + $this->inventory->addListeners(CallbackInventoryListener::onAnyChange(function(Inventory $unused) : void{ $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, 1); })); } diff --git a/src/block/tile/ContainerTrait.php b/src/block/tile/ContainerTrait.php index f3386a207d..45711b5964 100644 --- a/src/block/tile/ContainerTrait.php +++ b/src/block/tile/ContainerTrait.php @@ -48,14 +48,14 @@ trait ContainerTrait{ $inventoryTag = $tag->getListTag(Container::TAG_ITEMS); $inventory = $this->getRealInventory(); - $listeners = $inventory->getChangeListeners(); - $inventory->removeChangeListeners(...$listeners); //prevent any events being fired by initialization + $listeners = $inventory->getListeners(); + $inventory->removeListeners(...$listeners); //prevent any events being fired by initialization $inventory->clearAll(); /** @var CompoundTag $itemNBT */ foreach($inventoryTag as $itemNBT){ $inventory->setItem($itemNBT->getByte("Slot"), Item::nbtDeserialize($itemNBT)); } - $inventory->addChangeListeners(...$listeners); + $inventory->addListeners(...$listeners); } if($tag->hasTag(Container::TAG_LOCK, StringTag::class)){ diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index 425f119119..0ad0dba36f 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -27,7 +27,7 @@ use pocketmine\block\Furnace as BlockFurnace; use pocketmine\crafting\FurnaceRecipe; use pocketmine\event\inventory\FurnaceBurnEvent; use pocketmine\event\inventory\FurnaceSmeltEvent; -use pocketmine\inventory\CallbackInventoryChangeListener; +use pocketmine\inventory\CallbackInventoryListener; use pocketmine\inventory\FurnaceInventory; use pocketmine\inventory\Inventory; use pocketmine\item\Item; @@ -58,7 +58,7 @@ class Furnace extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); $this->inventory = new FurnaceInventory($this->pos); - $this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange( + $this->inventory->addListeners(CallbackInventoryListener::onAnyChange( function(Inventory $unused) : void{ $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, 1); }) diff --git a/src/entity/Human.php b/src/entity/Human.php index c357bf1d84..042675f58c 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -221,8 +221,8 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $inventoryTag = $nbt->getListTag("Inventory"); if($inventoryTag !== null){ - $armorListeners = $this->armorInventory->getChangeListeners(); - $this->armorInventory->removeChangeListeners(...$armorListeners); + $armorListeners = $this->armorInventory->getListeners(); + $this->armorInventory->removeListeners(...$armorListeners); /** @var CompoundTag $item */ foreach($inventoryTag as $i => $item){ @@ -236,7 +236,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ } } - $this->armorInventory->addChangeListeners(...$armorListeners); + $this->armorInventory->addListeners(...$armorListeners); } $enderChestInventoryTag = $nbt->getListTag("EnderChestInventory"); diff --git a/src/entity/Living.php b/src/entity/Living.php index dee6381a3a..11993396fb 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -32,7 +32,7 @@ use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDeathEvent; use pocketmine\inventory\ArmorInventory; -use pocketmine\inventory\CallbackInventoryChangeListener; +use pocketmine\inventory\CallbackInventoryListener; use pocketmine\inventory\Inventory; use pocketmine\item\Armor; use pocketmine\item\Consumable; @@ -104,7 +104,7 @@ abstract class Living extends Entity{ $this->armorInventory = new ArmorInventory($this); //TODO: load/save armor inventory contents - $this->armorInventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange( + $this->armorInventory->addListeners(CallbackInventoryListener::onAnyChange( function(Inventory $unused) : void{ foreach($this->getViewers() as $viewer){ $viewer->getNetworkSession()->onMobArmorChange($this); diff --git a/src/inventory/BaseInventory.php b/src/inventory/BaseInventory.php index bcfefe272f..dcf620bfd4 100644 --- a/src/inventory/BaseInventory.php +++ b/src/inventory/BaseInventory.php @@ -43,7 +43,7 @@ abstract class BaseInventory implements Inventory{ protected $slots; /** @var Player[] */ protected $viewers = []; - /** @var InventoryChangeListener[] */ + /** @var InventoryListener[] */ protected $listeners = []; public function __construct(int $size){ @@ -105,7 +105,7 @@ abstract class BaseInventory implements Inventory{ } } - $this->addChangeListeners(...$listeners); //don't directly write, in case listeners were added while operation was in progress + $this->addListeners(...$listeners); //don't directly write, in case listeners were added while operation was in progress foreach($viewers as $id => $viewer){ $this->viewers[$id] = $viewer; } @@ -372,19 +372,19 @@ abstract class BaseInventory implements Inventory{ return $slot >= 0 and $slot < $this->slots->getSize(); } - public function addChangeListeners(InventoryChangeListener ...$listeners) : void{ + public function addListeners(InventoryListener ...$listeners) : void{ foreach($listeners as $listener){ $this->listeners[spl_object_id($listener)] = $listener; } } - public function removeChangeListeners(InventoryChangeListener ...$listeners) : void{ + public function removeListeners(InventoryListener ...$listeners) : void{ foreach($listeners as $listener){ unset($this->listeners[spl_object_id($listener)]); } } - public function getChangeListeners() : array{ + public function getListeners() : array{ return $this->listeners; } } diff --git a/src/inventory/CallbackInventoryChangeListener.php b/src/inventory/CallbackInventoryListener.php similarity index 97% rename from src/inventory/CallbackInventoryChangeListener.php rename to src/inventory/CallbackInventoryListener.php index c3b12a6d49..3bb1efdce0 100644 --- a/src/inventory/CallbackInventoryChangeListener.php +++ b/src/inventory/CallbackInventoryListener.php @@ -26,7 +26,7 @@ namespace pocketmine\inventory; use pocketmine\item\Item; use pocketmine\utils\Utils; -class CallbackInventoryChangeListener implements InventoryChangeListener{ +class CallbackInventoryListener implements InventoryListener{ //TODO: turn the closure signatures into type aliases when PHPStan supports them diff --git a/src/inventory/Inventory.php b/src/inventory/Inventory.php index adbd26c1dd..17be0db27a 100644 --- a/src/inventory/Inventory.php +++ b/src/inventory/Inventory.php @@ -155,17 +155,17 @@ interface Inventory{ public function slotExists(int $slot) : bool; /** - * @param InventoryChangeListener ...$listeners + * @param InventoryListener ...$listeners */ - public function addChangeListeners(InventoryChangeListener ...$listeners) : void; + public function addListeners(InventoryListener ...$listeners) : void; /** - * @param InventoryChangeListener ...$listeners + * @param InventoryListener ...$listeners */ - public function removeChangeListeners(InventoryChangeListener ...$listeners) : void; + public function removeListeners(InventoryListener ...$listeners) : void; /** - * @return InventoryChangeListener[] + * @return InventoryListener[] */ - public function getChangeListeners() : array; + public function getListeners() : array; } diff --git a/src/inventory/InventoryChangeListener.php b/src/inventory/InventoryListener.php similarity index 85% rename from src/inventory/InventoryChangeListener.php rename to src/inventory/InventoryListener.php index 60069305ef..da8274661e 100644 --- a/src/inventory/InventoryChangeListener.php +++ b/src/inventory/InventoryListener.php @@ -28,11 +28,11 @@ use pocketmine\item\Item; /** * Classes implementing this interface can be injected into inventories to receive notifications when content changes * occur. - * @see CallbackInventoryChangeListener for a closure-based listener - * @see Inventory::addChangeListeners() - * @see Inventory::removeChangeListeners() + * @see CallbackInventoryListener for a closure-based listener + * @see Inventory::addListeners() + * @see Inventory::removeListeners() */ -interface InventoryChangeListener{ +interface InventoryListener{ public function onSlotChange(Inventory $inventory, int $slot, Item $oldItem) : void; From 6dd31cc3f5554aa27954c7447dc8a624994f5049 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 24 Apr 2020 23:52:29 +0100 Subject: [PATCH 1467/3224] break cycle between block and inventory packages --- src/block/Anvil.php | 2 +- src/block/EnchantingTable.php | 2 +- src/{ => block}/inventory/AnvilInventory.php | 2 +- src/{ => block}/inventory/BlockInventory.php | 3 ++- src/{ => block}/inventory/BrewingStandInventory.php | 2 +- src/{ => block}/inventory/ChestInventory.php | 2 +- src/{ => block}/inventory/DoubleChestInventory.php | 4 +++- src/{ => block}/inventory/EnchantInventory.php | 2 +- src/{ => block}/inventory/EnderChestInventory.php | 2 +- src/{ => block}/inventory/FurnaceInventory.php | 2 +- src/{ => block}/inventory/HopperInventory.php | 2 +- src/block/tile/BrewingStand.php | 2 +- src/block/tile/Chest.php | 4 ++-- src/block/tile/Furnace.php | 2 +- src/block/tile/Hopper.php | 2 +- src/entity/Human.php | 2 +- src/network/mcpe/InventoryManager.php | 12 ++++++------ 17 files changed, 26 insertions(+), 23 deletions(-) rename src/{ => block}/inventory/AnvilInventory.php (96%) rename src/{ => block}/inventory/BlockInventory.php (93%) rename src/{ => block}/inventory/BrewingStandInventory.php (96%) rename src/{ => block}/inventory/ChestInventory.php (98%) rename src/{ => block}/inventory/DoubleChestInventory.php (95%) rename src/{ => block}/inventory/EnchantInventory.php (96%) rename src/{ => block}/inventory/EnderChestInventory.php (97%) rename src/{ => block}/inventory/FurnaceInventory.php (97%) rename src/{ => block}/inventory/HopperInventory.php (96%) diff --git a/src/block/Anvil.php b/src/block/Anvil.php index 99ab726eb9..68f1a7392e 100644 --- a/src/block/Anvil.php +++ b/src/block/Anvil.php @@ -23,10 +23,10 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\inventory\AnvilInventory; use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\Fallable; use pocketmine\block\utils\FallableTrait; -use pocketmine\inventory\AnvilInventory; use pocketmine\item\Item; use pocketmine\item\ToolTier; use pocketmine\math\AxisAlignedBB; diff --git a/src/block/EnchantingTable.php b/src/block/EnchantingTable.php index 9507433d4b..d59e258dd2 100644 --- a/src/block/EnchantingTable.php +++ b/src/block/EnchantingTable.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\inventory\EnchantInventory; +use pocketmine\block\inventory\EnchantInventory; use pocketmine\item\Item; use pocketmine\item\ToolTier; use pocketmine\math\AxisAlignedBB; diff --git a/src/inventory/AnvilInventory.php b/src/block/inventory/AnvilInventory.php similarity index 96% rename from src/inventory/AnvilInventory.php rename to src/block/inventory/AnvilInventory.php index e07ff965e9..b6ecddf135 100644 --- a/src/inventory/AnvilInventory.php +++ b/src/block/inventory/AnvilInventory.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\inventory; +namespace pocketmine\block\inventory; use pocketmine\player\Player; use pocketmine\world\Position; diff --git a/src/inventory/BlockInventory.php b/src/block/inventory/BlockInventory.php similarity index 93% rename from src/inventory/BlockInventory.php rename to src/block/inventory/BlockInventory.php index 5e4267b61f..bb346a598a 100644 --- a/src/inventory/BlockInventory.php +++ b/src/block/inventory/BlockInventory.php @@ -21,8 +21,9 @@ declare(strict_types=1); -namespace pocketmine\inventory; +namespace pocketmine\block\inventory; +use pocketmine\inventory\BaseInventory; use pocketmine\world\Position; class BlockInventory extends BaseInventory{ diff --git a/src/inventory/BrewingStandInventory.php b/src/block/inventory/BrewingStandInventory.php similarity index 96% rename from src/inventory/BrewingStandInventory.php rename to src/block/inventory/BrewingStandInventory.php index 48aaaa6b37..39d806b33f 100644 --- a/src/inventory/BrewingStandInventory.php +++ b/src/block/inventory/BrewingStandInventory.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\inventory; +namespace pocketmine\block\inventory; use pocketmine\world\Position; diff --git a/src/inventory/ChestInventory.php b/src/block/inventory/ChestInventory.php similarity index 98% rename from src/inventory/ChestInventory.php rename to src/block/inventory/ChestInventory.php index 1aea2a77d7..377703ebd1 100644 --- a/src/inventory/ChestInventory.php +++ b/src/block/inventory/ChestInventory.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\inventory; +namespace pocketmine\block\inventory; use pocketmine\network\mcpe\protocol\BlockEventPacket; use pocketmine\player\Player; diff --git a/src/inventory/DoubleChestInventory.php b/src/block/inventory/DoubleChestInventory.php similarity index 95% rename from src/inventory/DoubleChestInventory.php rename to src/block/inventory/DoubleChestInventory.php index 41f7ce69e3..1998f18229 100644 --- a/src/inventory/DoubleChestInventory.php +++ b/src/block/inventory/DoubleChestInventory.php @@ -21,8 +21,10 @@ declare(strict_types=1); -namespace pocketmine\inventory; +namespace pocketmine\block\inventory; +use pocketmine\inventory\BaseInventory; +use pocketmine\inventory\InventoryHolder; use pocketmine\item\Item; use pocketmine\player\Player; use pocketmine\world\Position; diff --git a/src/inventory/EnchantInventory.php b/src/block/inventory/EnchantInventory.php similarity index 96% rename from src/inventory/EnchantInventory.php rename to src/block/inventory/EnchantInventory.php index 06d7f651ca..54be05fc1b 100644 --- a/src/inventory/EnchantInventory.php +++ b/src/block/inventory/EnchantInventory.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\inventory; +namespace pocketmine\block\inventory; use pocketmine\player\Player; use pocketmine\world\Position; diff --git a/src/inventory/EnderChestInventory.php b/src/block/inventory/EnderChestInventory.php similarity index 97% rename from src/inventory/EnderChestInventory.php rename to src/block/inventory/EnderChestInventory.php index bd9a448f2c..1e822aa28e 100644 --- a/src/inventory/EnderChestInventory.php +++ b/src/block/inventory/EnderChestInventory.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\inventory; +namespace pocketmine\block\inventory; use pocketmine\world\Position; use pocketmine\world\sound\EnderChestCloseSound; diff --git a/src/inventory/FurnaceInventory.php b/src/block/inventory/FurnaceInventory.php similarity index 97% rename from src/inventory/FurnaceInventory.php rename to src/block/inventory/FurnaceInventory.php index c681111200..40abbe954e 100644 --- a/src/inventory/FurnaceInventory.php +++ b/src/block/inventory/FurnaceInventory.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\inventory; +namespace pocketmine\block\inventory; use pocketmine\item\Item; use pocketmine\world\Position; diff --git a/src/inventory/HopperInventory.php b/src/block/inventory/HopperInventory.php similarity index 96% rename from src/inventory/HopperInventory.php rename to src/block/inventory/HopperInventory.php index 8378458ce0..ce79ebb904 100644 --- a/src/inventory/HopperInventory.php +++ b/src/block/inventory/HopperInventory.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\inventory; +namespace pocketmine\block\inventory; use pocketmine\world\Position; diff --git a/src/block/tile/BrewingStand.php b/src/block/tile/BrewingStand.php index 740578e7ff..9e5c5dd16d 100644 --- a/src/block/tile/BrewingStand.php +++ b/src/block/tile/BrewingStand.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block\tile; -use pocketmine\inventory\BrewingStandInventory; +use pocketmine\block\inventory\BrewingStandInventory; use pocketmine\inventory\CallbackInventoryListener; use pocketmine\inventory\Inventory; use pocketmine\math\Vector3; diff --git a/src/block/tile/Chest.php b/src/block/tile/Chest.php index 3cea051022..e197685e43 100644 --- a/src/block/tile/Chest.php +++ b/src/block/tile/Chest.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\block\tile; -use pocketmine\inventory\ChestInventory; -use pocketmine\inventory\DoubleChestInventory; +use pocketmine\block\inventory\ChestInventory; +use pocketmine\block\inventory\DoubleChestInventory; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index 0ad0dba36f..2fccc2d5da 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -24,11 +24,11 @@ declare(strict_types=1); namespace pocketmine\block\tile; use pocketmine\block\Furnace as BlockFurnace; +use pocketmine\block\inventory\FurnaceInventory; use pocketmine\crafting\FurnaceRecipe; use pocketmine\event\inventory\FurnaceBurnEvent; use pocketmine\event\inventory\FurnaceSmeltEvent; use pocketmine\inventory\CallbackInventoryListener; -use pocketmine\inventory\FurnaceInventory; use pocketmine\inventory\Inventory; use pocketmine\item\Item; use pocketmine\item\ItemFactory; diff --git a/src/block/tile/Hopper.php b/src/block/tile/Hopper.php index 838cc2f345..6a0988dcf3 100644 --- a/src/block/tile/Hopper.php +++ b/src/block/tile/Hopper.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block\tile; -use pocketmine\inventory\HopperInventory; +use pocketmine\block\inventory\HopperInventory; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\world\World; diff --git a/src/entity/Human.php b/src/entity/Human.php index 042675f58c..54ef3de9cb 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -28,7 +28,7 @@ use pocketmine\entity\effect\VanillaEffects; use pocketmine\entity\projectile\ProjectileSource; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\player\PlayerExhaustEvent; -use pocketmine\inventory\EnderChestInventory; +use pocketmine\block\inventory\EnderChestInventory; use pocketmine\inventory\InventoryHolder; use pocketmine\inventory\PlayerInventory; use pocketmine\item\Consumable; diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index bd665dee9f..cd09663f48 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -23,13 +23,13 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; -use pocketmine\inventory\AnvilInventory; -use pocketmine\inventory\BlockInventory; -use pocketmine\inventory\BrewingStandInventory; +use pocketmine\block\inventory\AnvilInventory; +use pocketmine\block\inventory\BlockInventory; +use pocketmine\block\inventory\BrewingStandInventory; +use pocketmine\block\inventory\EnchantInventory; +use pocketmine\block\inventory\FurnaceInventory; +use pocketmine\block\inventory\HopperInventory; use pocketmine\inventory\CreativeInventory; -use pocketmine\inventory\EnchantInventory; -use pocketmine\inventory\FurnaceInventory; -use pocketmine\inventory\HopperInventory; use pocketmine\inventory\Inventory; use pocketmine\inventory\transaction\action\SlotChangeAction; use pocketmine\inventory\transaction\InventoryTransaction; From 80680f15f4071b93973bc0a605d4e4248230c44a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 25 Apr 2020 03:31:13 +0100 Subject: [PATCH 1468/3224] seal up resource pack completion callback visibility --- src/network/mcpe/NetworkSession.php | 6 ++++-- .../mcpe/handler/ResourcePacksPacketHandler.php | 13 +++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index be754503fd..c60fc9e1c4 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -565,10 +565,12 @@ class NetworkSession{ $this->sendDataPacket(PlayStatusPacket::create(PlayStatusPacket::LOGIN_SUCCESS)); $this->logger->debug("Initiating resource packs phase"); - $this->setHandler(new ResourcePacksPacketHandler($this, $this->server->getResourcePackManager())); + $this->setHandler(new ResourcePacksPacketHandler($this, $this->server->getResourcePackManager(), function() : void{ + $this->onResourcePacksDone(); + })); } - public function onResourcePacksDone() : void{ + private function onResourcePacksDone() : void{ $this->createPlayer(); $this->setHandler(new PreSpawnPacketHandler($this->server, $this->player, $this)); diff --git a/src/network/mcpe/handler/ResourcePacksPacketHandler.php b/src/network/mcpe/handler/ResourcePacksPacketHandler.php index 51ec66cbab..5a55231fd8 100644 --- a/src/network/mcpe/handler/ResourcePacksPacketHandler.php +++ b/src/network/mcpe/handler/ResourcePacksPacketHandler.php @@ -53,13 +53,22 @@ class ResourcePacksPacketHandler extends PacketHandler{ private $session; /** @var ResourcePackManager */ private $resourcePackManager; + /** + * @var \Closure + * @phpstan-var \Closure() : void + */ + private $completionCallback; /** @var bool[][] uuid => [chunk index => hasSent] */ private $downloadedChunks = []; - public function __construct(NetworkSession $session, ResourcePackManager $resourcePackManager){ + /** + * @phpstan-param \Closure() : void $completionCallback + */ + public function __construct(NetworkSession $session, ResourcePackManager $resourcePackManager, \Closure $completionCallback){ $this->session = $session; $this->resourcePackManager = $resourcePackManager; + $this->completionCallback = $completionCallback; } public function setUp() : void{ @@ -124,7 +133,7 @@ class ResourcePacksPacketHandler extends PacketHandler{ break; case ResourcePackClientResponsePacket::STATUS_COMPLETED: $this->session->getLogger()->debug("Resource packs sequence completed"); - $this->session->onResourcePacksDone(); + ($this->completionCallback)(); break; default: return false; From 1f7f33d35d6674f3fdf118a0c39901d0b75e00b5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 25 Apr 2020 03:33:44 +0100 Subject: [PATCH 1469/3224] NetworkSession: privatise setAuthenticationStatus() this is accessed via a closure proxy, so it doesn't need to be exported anymore. --- src/network/mcpe/NetworkSession.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index c60fc9e1c4..da8c858787 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -510,7 +510,7 @@ class NetworkSession{ }, $reason); } - public function setAuthenticationStatus(bool $authenticated, bool $authRequired, ?string $error, ?PublicKeyInterface $clientPubKey) : void{ + private function setAuthenticationStatus(bool $authenticated, bool $authRequired, ?string $error, ?PublicKeyInterface $clientPubKey) : void{ if(!$this->connected){ return; } From b1eff87ad1af1be7861a177720a742267693a5a5 Mon Sep 17 00:00:00 2001 From: Muqsit Rayyan Date: Sat, 25 Apr 2020 14:21:40 +0500 Subject: [PATCH 1470/3224] fix incorrect conversion of CreateItemAction, close #3436 (#3437) --- src/network/mcpe/convert/TypeConverter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index e6df8382c5..e0f257ea1a 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -183,7 +183,7 @@ class TypeConverter{ case NetworkInventoryAction::ACTION_MAGIC_SLOT_CREATIVE_DELETE_ITEM: return new DestroyItemAction($new); case NetworkInventoryAction::ACTION_MAGIC_SLOT_CREATIVE_CREATE_ITEM: - return new CreateItemAction($new); + return new CreateItemAction($old); default: throw new \UnexpectedValueException("Unexpected creative action type $action->inventorySlot"); From d3da485278915bc570ad154bad4cfeacc1779886 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 25 Apr 2020 10:43:06 +0100 Subject: [PATCH 1471/3224] fix phpstan analyze failure --- phpstan.neon.dist | 4 ++-- tests/phpstan/configs/gc-hacks.neon | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 6291c23df1..13391d9ae6 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -116,9 +116,9 @@ parameters: path: src/event/entity/ProjectileLaunchEvent.php - - message: "#^pocketmine\\\\inventory\\\\DoubleChestInventory\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\inventory\\\\ChestInventory\\.$#" + message: "#^pocketmine\\\\block\\\\inventory\\\\DoubleChestInventory\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\block\\\\inventory\\\\ChestInventory\\.$#" count: 1 - path: src/inventory/DoubleChestInventory.php + path: src/block/inventory/DoubleChestInventory.php - message: "#^Cannot instantiate interface pocketmine\\\\world\\\\format\\\\io\\\\WorldProvider\\.$#" diff --git a/tests/phpstan/configs/gc-hacks.neon b/tests/phpstan/configs/gc-hacks.neon index 331553ce03..f675b7f6f4 100644 --- a/tests/phpstan/configs/gc-hacks.neon +++ b/tests/phpstan/configs/gc-hacks.neon @@ -4,22 +4,22 @@ parameters: ignoreErrors: - - message: "#^Property pocketmine\\\\block\\\\tile\\\\BrewingStand\\:\\:\\$inventory \\(pocketmine\\\\inventory\\\\BrewingStandInventory\\) does not accept null\\.$#" + message: "#^Property pocketmine\\\\block\\\\tile\\\\BrewingStand\\:\\:\\$inventory \\(pocketmine\\\\block\\\\inventory\\\\BrewingStandInventory\\) does not accept null\\.$#" count: 1 path: ../../../src/block/tile/BrewingStand.php - - message: "#^Property pocketmine\\\\block\\\\tile\\\\Chest\\:\\:\\$inventory \\(pocketmine\\\\inventory\\\\ChestInventory\\) does not accept null\\.$#" + message: "#^Property pocketmine\\\\block\\\\tile\\\\Chest\\:\\:\\$inventory \\(pocketmine\\\\block\\\\inventory\\\\ChestInventory\\) does not accept null\\.$#" count: 1 path: ../../../src/block/tile/Chest.php - - message: "#^Property pocketmine\\\\block\\\\tile\\\\Furnace\\:\\:\\$inventory \\(pocketmine\\\\inventory\\\\FurnaceInventory\\) does not accept null\\.$#" + message: "#^Property pocketmine\\\\block\\\\tile\\\\Furnace\\:\\:\\$inventory \\(pocketmine\\\\block\\\\inventory\\\\FurnaceInventory\\) does not accept null\\.$#" count: 1 path: ../../../src/block/tile/Furnace.php - - message: "#^Property pocketmine\\\\block\\\\tile\\\\Hopper\\:\\:\\$inventory \\(pocketmine\\\\inventory\\\\HopperInventory\\) does not accept null\\.$#" + message: "#^Property pocketmine\\\\block\\\\tile\\\\Hopper\\:\\:\\$inventory \\(pocketmine\\\\block\\\\inventory\\\\HopperInventory\\) does not accept null\\.$#" count: 1 path: ../../../src/block/tile/Hopper.php @@ -44,7 +44,7 @@ parameters: path: ../../../src/entity/Human.php - - message: "#^Property pocketmine\\\\entity\\\\Human\\:\\:\\$enderChestInventory \\(pocketmine\\\\inventory\\\\EnderChestInventory\\) does not accept null\\.$#" + message: "#^Property pocketmine\\\\entity\\\\Human\\:\\:\\$enderChestInventory \\(pocketmine\\\\block\\\\inventory\\\\EnderChestInventory\\) does not accept null\\.$#" count: 1 path: ../../../src/entity/Human.php From ac5cf2443e409c342a4b2d8baa9e647134178bbb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 26 Apr 2020 01:11:30 +0100 Subject: [PATCH 1472/3224] convert TileFactory to singleton --- src/block/Block.php | 2 +- src/block/BlockFactory.php | 3 -- src/block/tile/Spawnable.php | 2 +- src/block/tile/Tile.php | 2 +- src/block/tile/TileFactory.php | 78 +++++++++++++++++----------------- src/world/format/Chunk.php | 3 +- 6 files changed, 43 insertions(+), 47 deletions(-) diff --git a/src/block/Block.php b/src/block/Block.php index e653e5b762..d97471555b 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -163,7 +163,7 @@ class Block{ } } if($oldTile === null and $tileType !== null){ - $this->pos->getWorldNonNull()->addTile(TileFactory::create($tileType, $this->pos->getWorld(), $this->pos->asVector3())); + $this->pos->getWorldNonNull()->addTile(TileFactory::getInstance()->create($tileType, $this->pos->getWorld(), $this->pos->asVector3())); } } diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 4f88fbd49d..bb33876603 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -43,7 +43,6 @@ use pocketmine\block\tile\MonsterSpawner as TileMonsterSpawner; use pocketmine\block\tile\Note as TileNote; use pocketmine\block\tile\Sign as TileSign; use pocketmine\block\tile\Skull as TileSkull; -use pocketmine\block\tile\TileFactory; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\block\utils\PillarRotationTrait; @@ -86,8 +85,6 @@ class BlockFactory{ public $blastResistance; public function __construct(){ - TileFactory::init(); - $this->fullList = new \SplFixedArray(8192); $this->lightFilter = \SplFixedArray::fromArray(array_fill(0, 8192, 1)); diff --git a/src/block/tile/Spawnable.php b/src/block/tile/Spawnable.php index 3c6c5d7c15..9abd96969f 100644 --- a/src/block/tile/Spawnable.php +++ b/src/block/tile/Spawnable.php @@ -71,7 +71,7 @@ abstract class Spawnable extends Tile{ final public function getSpawnCompound() : CompoundTag{ $nbt = CompoundTag::create() - ->setString(self::TAG_ID, TileFactory::getSaveId(get_class($this))) //TODO: disassociate network ID from save ID + ->setString(self::TAG_ID, TileFactory::getInstance()->getSaveId(get_class($this))) //TODO: disassociate network ID from save ID ->setInt(self::TAG_X, $this->pos->x) ->setInt(self::TAG_Y, $this->pos->y) ->setInt(self::TAG_Z, $this->pos->z); diff --git a/src/block/tile/Tile.php b/src/block/tile/Tile.php index a5ffdfb5f5..8895b69421 100644 --- a/src/block/tile/Tile.php +++ b/src/block/tile/Tile.php @@ -69,7 +69,7 @@ abstract class Tile{ public function saveNBT() : CompoundTag{ $nbt = CompoundTag::create() - ->setString(self::TAG_ID, TileFactory::getSaveId(get_class($this))) + ->setString(self::TAG_ID, TileFactory::getInstance()->getSaveId(get_class($this))) ->setInt(self::TAG_X, $this->pos->getFloorX()) ->setInt(self::TAG_Y, $this->pos->getFloorY()) ->setInt(self::TAG_Z, $this->pos->getFloorZ()); diff --git a/src/block/tile/TileFactory.php b/src/block/tile/TileFactory.php index 186b280688..19f4fcb2ae 100644 --- a/src/block/tile/TileFactory.php +++ b/src/block/tile/TileFactory.php @@ -25,6 +25,7 @@ namespace pocketmine\block\tile; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\utils\SingletonTrait; use pocketmine\utils\Utils; use pocketmine\world\World; use function assert; @@ -33,44 +34,41 @@ use function is_a; use function reset; final class TileFactory{ + use SingletonTrait; /** * @var string[] classes that extend Tile * @phpstan-var array> */ - private static $knownTiles = []; + private $knownTiles = []; /** * @var string[][] * @phpstan-var array, list> */ - private static $saveNames = []; + private $saveNames = []; /** * @var string[] base class => overridden class * @phpstan-var array, class-string> */ - private static $classMapping = []; + private $classMapping = []; - private function __construct(){ - //NOOP - } - - public static function init() : void{ - self::register(Banner::class, ["Banner", "minecraft:banner"]); - self::register(Bed::class, ["Bed", "minecraft:bed"]); - self::register(BrewingStand::class, ["BrewingStand", "minecraft:brewing_stand"]); - self::register(Chest::class, ["Chest", "minecraft:chest"]); - self::register(Comparator::class, ["Comparator", "minecraft:comparator"]); - self::register(DaylightSensor::class, ["DaylightDetector", "minecraft:daylight_detector"]); - self::register(EnchantTable::class, ["EnchantTable", "minecraft:enchanting_table"]); - self::register(EnderChest::class, ["EnderChest", "minecraft:ender_chest"]); - self::register(FlowerPot::class, ["FlowerPot", "minecraft:flower_pot"]); - self::register(Furnace::class, ["Furnace", "minecraft:furnace"]); - self::register(Hopper::class, ["Hopper", "minecraft:hopper"]); - self::register(ItemFrame::class, ["ItemFrame"]); //this is an entity in PC - self::register(MonsterSpawner::class, ["MobSpawner", "minecraft:mob_spawner"]); - self::register(Note::class, ["Music", "minecraft:noteblock"]); - self::register(Sign::class, ["Sign", "minecraft:sign"]); - self::register(Skull::class, ["Skull", "minecraft:skull"]); + public function __construct(){ + $this->register(Banner::class, ["Banner", "minecraft:banner"]); + $this->register(Bed::class, ["Bed", "minecraft:bed"]); + $this->register(BrewingStand::class, ["BrewingStand", "minecraft:brewing_stand"]); + $this->register(Chest::class, ["Chest", "minecraft:chest"]); + $this->register(Comparator::class, ["Comparator", "minecraft:comparator"]); + $this->register(DaylightSensor::class, ["DaylightDetector", "minecraft:daylight_detector"]); + $this->register(EnchantTable::class, ["EnchantTable", "minecraft:enchanting_table"]); + $this->register(EnderChest::class, ["EnderChest", "minecraft:ender_chest"]); + $this->register(FlowerPot::class, ["FlowerPot", "minecraft:flower_pot"]); + $this->register(Furnace::class, ["Furnace", "minecraft:furnace"]); + $this->register(Hopper::class, ["Hopper", "minecraft:hopper"]); + $this->register(ItemFrame::class, ["ItemFrame"]); //this is an entity in PC + $this->register(MonsterSpawner::class, ["MobSpawner", "minecraft:mob_spawner"]); + $this->register(Note::class, ["Music", "minecraft:noteblock"]); + $this->register(Sign::class, ["Sign", "minecraft:sign"]); + $this->register(Skull::class, ["Skull", "minecraft:skull"]); //TODO: Barrel //TODO: Beacon @@ -101,10 +99,10 @@ final class TileFactory{ * @param string[] $saveNames * @phpstan-param class-string $className */ - public static function register(string $className, array $saveNames = []) : void{ + public function register(string $className, array $saveNames = []) : void{ Utils::testValidInstance($className, Tile::class); - self::$classMapping[$className] = $className; + $this->classMapping[$className] = $className; $shortName = (new \ReflectionClass($className))->getShortName(); if(!in_array($shortName, $saveNames, true)){ @@ -112,10 +110,10 @@ final class TileFactory{ } foreach($saveNames as $name){ - self::$knownTiles[$name] = $className; + $this->knownTiles[$name] = $className; } - self::$saveNames[$className] = $saveNames; + $this->saveNames[$className] = $saveNames; } /** @@ -128,13 +126,13 @@ final class TileFactory{ * * @throws \InvalidArgumentException if the base class is not a registered tile */ - public static function override(string $baseClass, string $newClass) : void{ - if(!isset(self::$classMapping[$baseClass])){ + public function override(string $baseClass, string $newClass) : void{ + if(!isset($this->classMapping[$baseClass])){ throw new \InvalidArgumentException("Class $baseClass is not a registered tile"); } Utils::testValidInstance($newClass, $baseClass); - self::$classMapping[$baseClass] = $newClass; + $this->classMapping[$baseClass] = $newClass; } /** @@ -146,9 +144,9 @@ final class TileFactory{ * * @throws \InvalidArgumentException if the specified class is not a registered tile */ - public static function create(string $baseClass, World $world, Vector3 $pos) : Tile{ - if(isset(self::$classMapping[$baseClass])){ - $class = self::$classMapping[$baseClass]; + public function create(string $baseClass, World $world, Vector3 $pos) : Tile{ + if(isset($this->classMapping[$baseClass])){ + $class = $this->classMapping[$baseClass]; assert(is_a($class, $baseClass, true)); /** * @var Tile $tile @@ -166,12 +164,12 @@ final class TileFactory{ /** * @internal */ - public static function createFromData(World $world, CompoundTag $nbt) : ?Tile{ + public function createFromData(World $world, CompoundTag $nbt) : ?Tile{ $type = $nbt->getString(Tile::TAG_ID, ""); - if(!isset(self::$knownTiles[$type])){ + if(!isset($this->knownTiles[$type])){ return null; } - $class = self::$knownTiles[$type]; + $class = $this->knownTiles[$type]; assert(is_a($class, Tile::class, true)); /** * @var Tile $tile @@ -186,9 +184,9 @@ final class TileFactory{ /** * @phpstan-param class-string $class */ - public static function getSaveId(string $class) : string{ - if(isset(self::$saveNames[$class])){ - return reset(self::$saveNames[$class]); + public function getSaveId(string $class) : string{ + if(isset($this->saveNames[$class])){ + return reset($this->saveNames[$class]); } throw new \InvalidArgumentException("Tile $class is not registered"); } diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index bbfa169716..1a07af6bc4 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -534,8 +534,9 @@ class Chunk{ if($this->NBTtiles !== null){ $this->dirtyFlags |= self::DIRTY_FLAG_TILES; $world->timings->syncChunkLoadTileEntitiesTimer->startTiming(); + $tileFactory = TileFactory::getInstance(); foreach($this->NBTtiles as $nbt){ - if(($tile = TileFactory::createFromData($world, $nbt)) !== null){ + if(($tile = $tileFactory->createFromData($world, $nbt)) !== null){ $world->addTile($tile); }else{ $world->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown tile entity type " . $nbt->getString("id", "")); From f91e2f41e0d623edca01d99ef321585bdb37136e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 26 Apr 2020 11:01:27 +0100 Subject: [PATCH 1473/3224] move SendUsageTask to stats namespace maybe separate this out into a library? --- src/Server.php | 2 +- src/{scheduler => stats}/SendUsageTask.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) rename src/{scheduler => stats}/SendUsageTask.php (98%) diff --git a/src/Server.php b/src/Server.php index eac08dea9f..963f03000b 100644 --- a/src/Server.php +++ b/src/Server.php @@ -72,9 +72,9 @@ use pocketmine\plugin\PluginManager; use pocketmine\plugin\ScriptPluginLoader; use pocketmine\resourcepacks\ResourcePackManager; use pocketmine\scheduler\AsyncPool; -use pocketmine\scheduler\SendUsageTask; use pocketmine\snooze\SleeperHandler; use pocketmine\snooze\SleeperNotifier; +use pocketmine\stats\SendUsageTask; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; use pocketmine\updater\AutoUpdater; diff --git a/src/scheduler/SendUsageTask.php b/src/stats/SendUsageTask.php similarity index 98% rename from src/scheduler/SendUsageTask.php rename to src/stats/SendUsageTask.php index de1a6a0e23..2d9cf557ed 100644 --- a/src/scheduler/SendUsageTask.php +++ b/src/stats/SendUsageTask.php @@ -21,10 +21,11 @@ declare(strict_types=1); -namespace pocketmine\scheduler; +namespace pocketmine\stats; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\player\Player; +use pocketmine\scheduler\AsyncTask; use pocketmine\Server; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Internet; From 15c744b0d7b6fd1aeaa833df478bbb874a57006b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 27 Apr 2020 12:55:00 +0100 Subject: [PATCH 1474/3224] protocol: specialize exception used for bad packets --- src/network/mcpe/NetworkSession.php | 7 ++++- .../mcpe/protocol/AvailableCommandsPacket.php | 21 ++++++------- src/network/mcpe/protocol/BookEditPacket.php | 3 +- .../protocol/ClientboundMapItemDataPacket.php | 5 ++- .../mcpe/protocol/CraftingDataPacket.php | 3 +- src/network/mcpe/protocol/DataPacket.php | 9 +++--- .../protocol/InventoryTransactionPacket.php | 3 +- src/network/mcpe/protocol/LoginPacket.php | 19 ++++++------ src/network/mcpe/protocol/Packet.php | 5 ++- .../mcpe/protocol/PacketDecodeException.php | 31 +++++++++++++++++++ src/network/mcpe/protocol/SetScorePacket.php | 3 +- .../entity/CompoundTagMetadataProperty.php | 6 ++-- .../inventory/MismatchTransactionData.php | 4 +-- .../inventory/NetworkInventoryAction.php | 6 ++-- .../types/inventory/TransactionData.php | 6 ++-- 15 files changed, 79 insertions(+), 52 deletions(-) create mode 100644 src/network/mcpe/protocol/PacketDecodeException.php diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index da8c858787..36c8f12045 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -63,6 +63,7 @@ use pocketmine\network\mcpe\protocol\ModalFormRequestPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\NetworkChunkPublisherUpdatePacket; use pocketmine\network\mcpe\protocol\Packet; +use pocketmine\network\mcpe\protocol\PacketDecodeException; use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\PlayStatusPacket; use pocketmine\network\mcpe\protocol\ServerboundPacket; @@ -327,7 +328,11 @@ class NetworkSession{ $timings->startTiming(); try{ - $packet->decode(); + try{ + $packet->decode(); + }catch(PacketDecodeException $e){ + throw BadPacketException::wrap($e); + } $stream = $packet->getBinaryStream(); if(!$stream->feof()){ $remains = substr($stream->getBuffer(), $stream->getOffset()); diff --git a/src/network/mcpe/protocol/AvailableCommandsPacket.php b/src/network/mcpe/protocol/AvailableCommandsPacket.php index 02e96f74be..df651ee82f 100644 --- a/src/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/network/mcpe/protocol/AvailableCommandsPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\types\command\CommandData; use pocketmine\network\mcpe\protocol\types\command\CommandEnum; use pocketmine\network\mcpe\protocol\types\command\CommandEnumConstraint; @@ -147,7 +146,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ /** * @param string[] $enumValueList * - * @throws BadPacketException + * @throws PacketDecodeException * @throws BinaryDataException */ protected function getEnum(array $enumValueList, NetworkBinaryStream $in) : CommandEnum{ @@ -159,7 +158,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ $index = $this->getEnumValueIndex($listSize, $in); if(!isset($enumValueList[$index])){ - throw new BadPacketException("Invalid enum value index $index"); + throw new PacketDecodeException("Invalid enum value index $index"); } //Get the enum value from the initial pile of mess $enumValues[] = $enumValueList[$index]; @@ -238,23 +237,23 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @param CommandEnum[] $enums * @param string[] $enumValues * - * @throws BadPacketException + * @throws PacketDecodeException * @throws BinaryDataException */ protected function getEnumConstraint(array $enums, array $enumValues, NetworkBinaryStream $in) : CommandEnumConstraint{ //wtf, what was wrong with an offset inside the enum? :( $valueIndex = $in->getLInt(); if(!isset($enumValues[$valueIndex])){ - throw new BadPacketException("Enum constraint refers to unknown enum value index $valueIndex"); + throw new PacketDecodeException("Enum constraint refers to unknown enum value index $valueIndex"); } $enumIndex = $in->getLInt(); if(!isset($enums[$enumIndex])){ - throw new BadPacketException("Enum constraint refers to unknown enum index $enumIndex"); + throw new PacketDecodeException("Enum constraint refers to unknown enum index $enumIndex"); } $enum = $enums[$enumIndex]; $valueOffset = array_search($enumValues[$valueIndex], $enum->getValues(), true); if($valueOffset === false){ - throw new BadPacketException("Value \"" . $enumValues[$valueIndex] . "\" does not belong to enum \"" . $enum->getName() . "\""); + throw new PacketDecodeException("Value \"" . $enumValues[$valueIndex] . "\" does not belong to enum \"" . $enum->getName() . "\""); } $constraintIds = []; @@ -282,7 +281,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @param CommandEnum[] $enums * @param string[] $postfixes * - * @throws BadPacketException + * @throws PacketDecodeException * @throws BinaryDataException */ protected function getCommandData(array $enums, array $postfixes, NetworkBinaryStream $in) : CommandData{ @@ -306,16 +305,16 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ $index = ($parameter->paramType & 0xffff); $parameter->enum = $enums[$index] ?? null; if($parameter->enum === null){ - throw new BadPacketException("deserializing $name parameter $parameter->paramName: expected enum at $index, but got none"); + throw new PacketDecodeException("deserializing $name parameter $parameter->paramName: expected enum at $index, but got none"); } }elseif(($parameter->paramType & self::ARG_FLAG_POSTFIX) !== 0){ $index = ($parameter->paramType & 0xffff); $parameter->postfix = $postfixes[$index] ?? null; if($parameter->postfix === null){ - throw new BadPacketException("deserializing $name parameter $parameter->paramName: expected postfix at $index, but got none"); + throw new PacketDecodeException("deserializing $name parameter $parameter->paramName: expected postfix at $index, but got none"); } }elseif(($parameter->paramType & self::ARG_FLAG_VALID) === 0){ - throw new BadPacketException("deserializing $name parameter $parameter->paramName: Invalid parameter type 0x" . dechex($parameter->paramType)); + throw new PacketDecodeException("deserializing $name parameter $parameter->paramName: Invalid parameter type 0x" . dechex($parameter->paramType)); } $overloads[$overloadIndex][$paramIndex] = $parameter; diff --git a/src/network/mcpe/protocol/BookEditPacket.php b/src/network/mcpe/protocol/BookEditPacket.php index f61423f45a..d2bb25084f 100644 --- a/src/network/mcpe/protocol/BookEditPacket.php +++ b/src/network/mcpe/protocol/BookEditPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class BookEditPacket extends DataPacket implements ServerboundPacket{ @@ -82,7 +81,7 @@ class BookEditPacket extends DataPacket implements ServerboundPacket{ $this->xuid = $in->getString(); break; default: - throw new BadPacketException("Unknown book edit type $this->type!"); + throw new PacketDecodeException("Unknown book edit type $this->type!"); } } diff --git a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php index a82108ab94..3ca24def34 100644 --- a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php +++ b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\protocol\types\MapDecoration; use pocketmine\network\mcpe\protocol\types\MapTrackedObject; @@ -98,7 +97,7 @@ class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPack }elseif($object->type === MapTrackedObject::TYPE_ENTITY){ $object->entityUniqueId = $in->getEntityUniqueId(); }else{ - throw new BadPacketException("Unknown map object type $object->type"); + throw new PacketDecodeException("Unknown map object type $object->type"); } $this->trackedEntities[] = $object; } @@ -122,7 +121,7 @@ class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPack $count = $in->getUnsignedVarInt(); if($count !== $this->width * $this->height){ - throw new BadPacketException("Expected colour count of " . ($this->height * $this->width) . " (height $this->height * width $this->width), got $count"); + throw new PacketDecodeException("Expected colour count of " . ($this->height * $this->width) . " (height $this->height * width $this->width), got $count"); } for($y = 0; $y < $this->height; ++$y){ diff --git a/src/network/mcpe/protocol/CraftingDataPacket.php b/src/network/mcpe/protocol/CraftingDataPacket.php index 0a338ea1bc..43cf1f7ef1 100644 --- a/src/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/network/mcpe/protocol/CraftingDataPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\types\PotionContainerChangeRecipe; use pocketmine\network\mcpe\protocol\types\PotionTypeRecipe; use pocketmine\network\mcpe\protocol\types\recipe\FurnaceRecipe; @@ -80,7 +79,7 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{ $this->entries[] = MultiRecipe::decode($recipeType, $in); break; default: - throw new BadPacketException("Unhandled recipe type $recipeType!"); //do not continue attempting to decode + throw new PacketDecodeException("Unhandled recipe type $recipeType!"); //do not continue attempting to decode } } for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ diff --git a/src/network/mcpe/protocol/DataPacket.php b/src/network/mcpe/protocol/DataPacket.php index e58cb7e1e0..9051480044 100644 --- a/src/network/mcpe/protocol/DataPacket.php +++ b/src/network/mcpe/protocol/DataPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; use function get_class; @@ -69,15 +68,15 @@ abstract class DataPacket implements Packet{ } /** - * @throws BadPacketException + * @throws PacketDecodeException */ final public function decode() : void{ $this->buf->rewind(); try{ $this->decodeHeader($this->buf); $this->decodePayload($this->buf); - }catch(BinaryDataException | BadPacketException $e){ - throw BadPacketException::wrap($e, $this->getName()); + }catch(BinaryDataException | PacketDecodeException $e){ + throw PacketDecodeException::wrap($e, $this->getName()); } } @@ -100,7 +99,7 @@ abstract class DataPacket implements Packet{ /** * Decodes the packet body, without the packet ID or other generic header fields. * - * @throws BadPacketException + * @throws PacketDecodeException * @throws BinaryDataException */ abstract protected function decodePayload(NetworkBinaryStream $in) : void; diff --git a/src/network/mcpe/protocol/InventoryTransactionPacket.php b/src/network/mcpe/protocol/InventoryTransactionPacket.php index 1683aa6288..68401b7716 100644 --- a/src/network/mcpe/protocol/InventoryTransactionPacket.php +++ b/src/network/mcpe/protocol/InventoryTransactionPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\types\inventory\MismatchTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\NormalTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData; @@ -69,7 +68,7 @@ class InventoryTransactionPacket extends DataPacket implements ClientboundPacket $this->trData = new ReleaseItemTransactionData(); break; default: - throw new BadPacketException("Unknown transaction type $transactionType"); + throw new PacketDecodeException("Unknown transaction type $transactionType"); } $this->trData->decode($in); diff --git a/src/network/mcpe/protocol/LoginPacket.php b/src/network/mcpe/protocol/LoginPacket.php index 4de771f2a3..156630ea71 100644 --- a/src/network/mcpe/protocol/LoginPacket.php +++ b/src/network/mcpe/protocol/LoginPacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\types\login\AuthenticationData; use pocketmine\network\mcpe\protocol\types\login\ClientData; use pocketmine\network\mcpe\protocol\types\login\JwtChain; @@ -71,7 +70,7 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ } /** - * @throws BadPacketException + * @throws PacketDecodeException * @throws BinaryDataException */ protected function decodeConnectionRequest(NetworkBinaryStream $in) : void{ @@ -84,7 +83,7 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ try{ $chainData = $mapper->map($chainDataJson, new JwtChain); }catch(\JsonMapper_Exception $e){ - throw BadPacketException::wrap($e); + throw PacketDecodeException::wrap($e); } $this->chainDataJwt = $chainData; @@ -94,14 +93,14 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ try{ $claims = Utils::getJwtClaims($chain); }catch(\UnexpectedValueException $e){ - throw new BadPacketException($e->getMessage(), 0, $e); + throw new PacketDecodeException($e->getMessage(), 0, $e); } if(isset($claims["extraData"])){ if(!is_array($claims["extraData"])){ - throw new BadPacketException("'extraData' key should be an array"); + throw new PacketDecodeException("'extraData' key should be an array"); } if($this->extraData !== null){ - throw new BadPacketException("Found 'extraData' more than once in chainData"); + throw new PacketDecodeException("Found 'extraData' more than once in chainData"); } $mapper = new \JsonMapper; @@ -111,19 +110,19 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ try{ $this->extraData = $mapper->map($claims['extraData'], new AuthenticationData); }catch(\JsonMapper_Exception $e){ - throw BadPacketException::wrap($e); + throw PacketDecodeException::wrap($e); } } } if($this->extraData === null){ - throw new BadPacketException("'extraData' not found in chain data"); + throw new PacketDecodeException("'extraData' not found in chain data"); } $this->clientDataJwt = $buffer->get($buffer->getLInt()); try{ $clientData = Utils::getJwtClaims($this->clientDataJwt); }catch(\UnexpectedValueException $e){ - throw new BadPacketException($e->getMessage(), 0, $e); + throw new PacketDecodeException($e->getMessage(), 0, $e); } $mapper = new \JsonMapper; @@ -133,7 +132,7 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ try{ $this->clientData = $mapper->map($clientData, new ClientData); }catch(\JsonMapper_Exception $e){ - throw BadPacketException::wrap($e); + throw PacketDecodeException::wrap($e); } } diff --git a/src/network/mcpe/protocol/Packet.php b/src/network/mcpe/protocol/Packet.php index aec47b8cf9..b90fe3392d 100644 --- a/src/network/mcpe/protocol/Packet.php +++ b/src/network/mcpe/protocol/Packet.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; -use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; interface Packet{ @@ -37,7 +36,7 @@ interface Packet{ public function canBeSentBeforeLogin() : bool; /** - * @throws BadPacketException + * @throws PacketDecodeException */ public function decode() : void; @@ -56,7 +55,7 @@ interface Packet{ * @param PacketHandlerInterface $handler * * @return bool true if the packet was handled successfully, false if not. - * @throws BadPacketException if broken data was found in the packet + * @throws PacketDecodeException if broken data was found in the packet */ public function handle(PacketHandlerInterface $handler) : bool; } diff --git a/src/network/mcpe/protocol/PacketDecodeException.php b/src/network/mcpe/protocol/PacketDecodeException.php new file mode 100644 index 0000000000..cf06946c69 --- /dev/null +++ b/src/network/mcpe/protocol/PacketDecodeException.php @@ -0,0 +1,31 @@ +getMessage(), 0, $previous); + } +} \ No newline at end of file diff --git a/src/network/mcpe/protocol/SetScorePacket.php b/src/network/mcpe/protocol/SetScorePacket.php index 5643b9407b..0962fecd8a 100644 --- a/src/network/mcpe/protocol/SetScorePacket.php +++ b/src/network/mcpe/protocol/SetScorePacket.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\types\ScorePacketEntry; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; @@ -59,7 +58,7 @@ class SetScorePacket extends DataPacket implements ClientboundPacket{ $entry->customName = $in->getString(); break; default: - throw new BadPacketException("Unknown entry type $entry->type"); + throw new PacketDecodeException("Unknown entry type $entry->type"); } } $this->entries[] = $entry; diff --git a/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php b/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php index 62ecda9b4e..055724e739 100644 --- a/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol\types\entity; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; -use pocketmine\network\BadPacketException; +use pocketmine\network\mcpe\protocol\PacketDecodeException; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; @@ -51,14 +51,14 @@ final class CompoundTagMetadataProperty implements MetadataProperty{ } /** - * @throws BadPacketException + * @throws PacketDecodeException */ public static function read(NetworkBinaryStream $in) : self{ $offset = $in->getOffset(); try{ $tag = (new NetworkNbtSerializer())->read($in->getBuffer(), $offset, 512)->mustGetCompoundTag(); }catch(NbtDataException $e){ - throw new BadPacketException($e->getMessage(), 0, $e); + throw new PacketDecodeException($e->getMessage(), 0, $e); } $in->setOffset($offset); return new self($tag); diff --git a/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php b/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php index 7d3eedbdb0..fed3737c5c 100644 --- a/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\inventory; -use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; +use pocketmine\network\mcpe\protocol\PacketDecodeException; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; @@ -36,7 +36,7 @@ class MismatchTransactionData extends TransactionData{ protected function decodeData(NetworkBinaryStream $stream) : void{ if(count($this->actions) > 0){ - throw new BadPacketException("Mismatch transaction type should not have any actions associated with it, but got " . count($this->actions)); + throw new PacketDecodeException("Mismatch transaction type should not have any actions associated with it, but got " . count($this->actions)); } } diff --git a/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php b/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php index 6d87dfc526..5312876054 100644 --- a/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php +++ b/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\inventory; -use pocketmine\network\BadPacketException; +use pocketmine\network\mcpe\protocol\PacketDecodeException; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; @@ -81,7 +81,7 @@ class NetworkInventoryAction{ * @return $this * * @throws BinaryDataException - * @throws BadPacketException + * @throws PacketDecodeException */ public function read(NetworkBinaryStream $packet) : NetworkInventoryAction{ $this->sourceType = $packet->getUnsignedVarInt(); @@ -99,7 +99,7 @@ class NetworkInventoryAction{ $this->windowId = $packet->getVarInt(); break; default: - throw new BadPacketException("Unknown inventory action source type $this->sourceType"); + throw new PacketDecodeException("Unknown inventory action source type $this->sourceType"); } $this->inventorySlot = $packet->getUnsignedVarInt(); diff --git a/src/network/mcpe/protocol/types/inventory/TransactionData.php b/src/network/mcpe/protocol/types/inventory/TransactionData.php index 28c49010c5..34dac5d594 100644 --- a/src/network/mcpe/protocol/types/inventory/TransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/TransactionData.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\inventory; -use pocketmine\network\BadPacketException; +use pocketmine\network\mcpe\protocol\PacketDecodeException; use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; use function count; @@ -43,7 +43,7 @@ abstract class TransactionData{ /** * @throws BinaryDataException - * @throws BadPacketException + * @throws PacketDecodeException */ final public function decode(NetworkBinaryStream $stream) : void{ $actionCount = $stream->getUnsignedVarInt(); @@ -55,7 +55,7 @@ abstract class TransactionData{ /** * @throws BinaryDataException - * @throws BadPacketException + * @throws PacketDecodeException */ abstract protected function decodeData(NetworkBinaryStream $stream) : void; From 0397204c68f9dcc7f2524a08c4d7641d95596368 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 27 Apr 2020 12:56:28 +0100 Subject: [PATCH 1475/3224] network/mcpe: imports cleanup --- src/network/mcpe/InventoryManager.php | 1 + src/network/mcpe/convert/TypeConverter.php | 1 - src/network/mcpe/encryption/EncryptionUtils.php | 9 +++++++++ .../mcpe/encryption/PrepareEncryptionTask.php | 15 --------------- .../mcpe/handler/ResourcePacksPacketHandler.php | 1 - 5 files changed, 10 insertions(+), 17 deletions(-) diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index cd09663f48..a6e33268b5 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -45,6 +45,7 @@ use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes; use pocketmine\player\Player; +use function array_map; use function array_search; use function max; diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index e0f257ea1a..b3ecd9214d 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -34,7 +34,6 @@ use pocketmine\item\ItemFactory; use pocketmine\item\ItemIds; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; -use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\protocol\types\inventory\NetworkInventoryAction; diff --git a/src/network/mcpe/encryption/EncryptionUtils.php b/src/network/mcpe/encryption/EncryptionUtils.php index ad09457bbf..38fe0e95a8 100644 --- a/src/network/mcpe/encryption/EncryptionUtils.php +++ b/src/network/mcpe/encryption/EncryptionUtils.php @@ -29,6 +29,15 @@ use Mdanter\Ecc\Serializer\PrivateKey\DerPrivateKeySerializer; use Mdanter\Ecc\Serializer\PrivateKey\PemPrivateKeySerializer; use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer; +use function base64_encode; +use function gmp_strval; +use function hex2bin; +use function json_encode; +use function openssl_digest; +use function openssl_sign; +use function rtrim; +use function str_pad; +use function strtr; final class EncryptionUtils{ diff --git a/src/network/mcpe/encryption/PrepareEncryptionTask.php b/src/network/mcpe/encryption/PrepareEncryptionTask.php index 65314b3b24..39bf8c0437 100644 --- a/src/network/mcpe/encryption/PrepareEncryptionTask.php +++ b/src/network/mcpe/encryption/PrepareEncryptionTask.php @@ -26,23 +26,8 @@ namespace pocketmine\network\mcpe\encryption; use Mdanter\Ecc\Crypto\Key\PrivateKeyInterface; use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; use Mdanter\Ecc\EccFactory; -use Mdanter\Ecc\Serializer\PrivateKey\DerPrivateKeySerializer; -use Mdanter\Ecc\Serializer\PrivateKey\PemPrivateKeySerializer; -use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; -use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer; use pocketmine\scheduler\AsyncTask; -use function base64_encode; -use function gmp_strval; -use function hex2bin; -use function json_encode; -use function openssl_digest; -use function openssl_sign; use function random_bytes; -use function rtrim; -use function str_pad; -use function strtr; -use const OPENSSL_ALGO_SHA384; -use const STR_PAD_LEFT; class PrepareEncryptionTask extends AsyncTask{ diff --git a/src/network/mcpe/handler/ResourcePacksPacketHandler.php b/src/network/mcpe/handler/ResourcePacksPacketHandler.php index 5a55231fd8..2986e15a5b 100644 --- a/src/network/mcpe/handler/ResourcePacksPacketHandler.php +++ b/src/network/mcpe/handler/ResourcePacksPacketHandler.php @@ -35,7 +35,6 @@ use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackStackEntry; use pocketmine\resourcepacks\ResourcePack; use pocketmine\resourcepacks\ResourcePackManager; use function array_map; -use function array_unshift; use function ceil; use function count; use function implode; From a97cafd4f6b93878e355a1192199f614a6d78cbd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 27 Apr 2020 13:54:39 +0100 Subject: [PATCH 1476/3224] moving serializers into protocol namespace --- src/Server.php | 2 +- src/block/tile/Spawnable.php | 2 +- src/crafting/CraftingManager.php | 2 +- src/network/mcpe/ChunkRequestTask.php | 1 + src/network/mcpe/NetworkSession.php | 1 + src/network/mcpe/convert/RuntimeBlockMapping.php | 2 +- src/network/mcpe/handler/InGamePacketHandler.php | 2 +- src/network/mcpe/protocol/ActorEventPacket.php | 2 +- src/network/mcpe/protocol/ActorFallPacket.php | 2 +- src/network/mcpe/protocol/ActorPickRequestPacket.php | 2 +- src/network/mcpe/protocol/AddActorPacket.php | 2 +- src/network/mcpe/protocol/AddBehaviorTreePacket.php | 2 +- src/network/mcpe/protocol/AddEntityPacket.php | 2 +- src/network/mcpe/protocol/AddItemActorPacket.php | 2 +- src/network/mcpe/protocol/AddPaintingPacket.php | 2 +- src/network/mcpe/protocol/AddPlayerPacket.php | 2 +- src/network/mcpe/protocol/AdventureSettingsPacket.php | 2 +- src/network/mcpe/protocol/AnimatePacket.php | 2 +- src/network/mcpe/protocol/AnvilDamagePacket.php | 2 +- src/network/mcpe/protocol/AutomationClientConnectPacket.php | 2 +- src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php | 2 +- src/network/mcpe/protocol/AvailableCommandsPacket.php | 2 +- src/network/mcpe/protocol/BiomeDefinitionListPacket.php | 2 +- src/network/mcpe/protocol/BlockActorDataPacket.php | 2 +- src/network/mcpe/protocol/BlockEventPacket.php | 2 +- src/network/mcpe/protocol/BlockPickRequestPacket.php | 2 +- src/network/mcpe/protocol/BookEditPacket.php | 2 +- src/network/mcpe/protocol/BossEventPacket.php | 2 +- src/network/mcpe/protocol/CameraPacket.php | 2 +- src/network/mcpe/protocol/ChangeDimensionPacket.php | 2 +- src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php | 2 +- src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php | 2 +- src/network/mcpe/protocol/ClientCacheMissResponsePacket.php | 2 +- src/network/mcpe/protocol/ClientCacheStatusPacket.php | 2 +- src/network/mcpe/protocol/ClientToServerHandshakePacket.php | 2 +- src/network/mcpe/protocol/ClientboundMapItemDataPacket.php | 2 +- src/network/mcpe/protocol/CommandBlockUpdatePacket.php | 2 +- src/network/mcpe/protocol/CommandOutputPacket.php | 2 +- src/network/mcpe/protocol/CommandRequestPacket.php | 2 +- src/network/mcpe/protocol/CompletedUsingItemPacket.php | 2 +- src/network/mcpe/protocol/ContainerClosePacket.php | 2 +- src/network/mcpe/protocol/ContainerOpenPacket.php | 2 +- src/network/mcpe/protocol/ContainerSetDataPacket.php | 2 +- src/network/mcpe/protocol/CraftingDataPacket.php | 2 +- src/network/mcpe/protocol/CraftingEventPacket.php | 2 +- src/network/mcpe/protocol/DataPacket.php | 2 +- src/network/mcpe/protocol/DisconnectPacket.php | 2 +- src/network/mcpe/protocol/EducationSettingsPacket.php | 2 +- src/network/mcpe/protocol/EmotePacket.php | 2 +- src/network/mcpe/protocol/EventPacket.php | 2 +- src/network/mcpe/protocol/GameRulesChangedPacket.php | 2 +- src/network/mcpe/protocol/GuiDataPickItemPacket.php | 2 +- src/network/mcpe/protocol/HurtArmorPacket.php | 2 +- src/network/mcpe/protocol/InteractPacket.php | 2 +- src/network/mcpe/protocol/InventoryContentPacket.php | 2 +- src/network/mcpe/protocol/InventorySlotPacket.php | 2 +- src/network/mcpe/protocol/InventoryTransactionPacket.php | 2 +- src/network/mcpe/protocol/ItemFrameDropItemPacket.php | 2 +- src/network/mcpe/protocol/LabTablePacket.php | 2 +- src/network/mcpe/protocol/LecternUpdatePacket.php | 2 +- src/network/mcpe/protocol/LevelChunkPacket.php | 2 +- src/network/mcpe/protocol/LevelEventGenericPacket.php | 4 ++-- src/network/mcpe/protocol/LevelEventPacket.php | 2 +- src/network/mcpe/protocol/LevelSoundEventPacket.php | 2 +- src/network/mcpe/protocol/LevelSoundEventPacketV1.php | 2 +- src/network/mcpe/protocol/LevelSoundEventPacketV2.php | 2 +- src/network/mcpe/protocol/LoginPacket.php | 2 +- src/network/mcpe/protocol/MapCreateLockedCopyPacket.php | 2 +- src/network/mcpe/protocol/MapInfoRequestPacket.php | 2 +- src/network/mcpe/protocol/MobArmorEquipmentPacket.php | 2 +- src/network/mcpe/protocol/MobEffectPacket.php | 2 +- src/network/mcpe/protocol/MobEquipmentPacket.php | 2 +- src/network/mcpe/protocol/ModalFormRequestPacket.php | 2 +- src/network/mcpe/protocol/ModalFormResponsePacket.php | 2 +- src/network/mcpe/protocol/MoveActorAbsolutePacket.php | 2 +- src/network/mcpe/protocol/MoveActorDeltaPacket.php | 2 +- src/network/mcpe/protocol/MovePlayerPacket.php | 2 +- src/network/mcpe/protocol/MultiplayerSettingsPacket.php | 2 +- .../mcpe/protocol/NetworkChunkPublisherUpdatePacket.php | 2 +- src/network/mcpe/protocol/NetworkSettingsPacket.php | 2 +- src/network/mcpe/protocol/NetworkStackLatencyPacket.php | 2 +- src/network/mcpe/protocol/NpcRequestPacket.php | 2 +- src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php | 2 +- src/network/mcpe/protocol/Packet.php | 2 +- src/network/mcpe/protocol/PhotoTransferPacket.php | 2 +- src/network/mcpe/protocol/PlaySoundPacket.php | 2 +- src/network/mcpe/protocol/PlayStatusPacket.php | 2 +- src/network/mcpe/protocol/PlayerActionPacket.php | 2 +- src/network/mcpe/protocol/PlayerAuthInputPacket.php | 2 +- src/network/mcpe/protocol/PlayerHotbarPacket.php | 2 +- src/network/mcpe/protocol/PlayerInputPacket.php | 2 +- src/network/mcpe/protocol/PlayerListPacket.php | 2 +- src/network/mcpe/protocol/PlayerSkinPacket.php | 2 +- src/network/mcpe/protocol/PurchaseReceiptPacket.php | 2 +- src/network/mcpe/protocol/RemoveActorPacket.php | 2 +- src/network/mcpe/protocol/RemoveEntityPacket.php | 2 +- src/network/mcpe/protocol/RemoveObjectivePacket.php | 2 +- src/network/mcpe/protocol/RequestChunkRadiusPacket.php | 2 +- src/network/mcpe/protocol/ResourcePackChunkDataPacket.php | 2 +- src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php | 2 +- .../mcpe/protocol/ResourcePackClientResponsePacket.php | 2 +- src/network/mcpe/protocol/ResourcePackDataInfoPacket.php | 2 +- src/network/mcpe/protocol/ResourcePackStackPacket.php | 2 +- src/network/mcpe/protocol/ResourcePacksInfoPacket.php | 2 +- src/network/mcpe/protocol/RespawnPacket.php | 2 +- src/network/mcpe/protocol/RiderJumpPacket.php | 2 +- src/network/mcpe/protocol/ScriptCustomEventPacket.php | 2 +- src/network/mcpe/protocol/ServerSettingsRequestPacket.php | 2 +- src/network/mcpe/protocol/ServerSettingsResponsePacket.php | 2 +- src/network/mcpe/protocol/ServerToClientHandshakePacket.php | 2 +- src/network/mcpe/protocol/SetActorDataPacket.php | 2 +- src/network/mcpe/protocol/SetActorLinkPacket.php | 2 +- src/network/mcpe/protocol/SetActorMotionPacket.php | 2 +- src/network/mcpe/protocol/SetCommandsEnabledPacket.php | 2 +- src/network/mcpe/protocol/SetDefaultGameTypePacket.php | 2 +- src/network/mcpe/protocol/SetDifficultyPacket.php | 2 +- src/network/mcpe/protocol/SetDisplayObjectivePacket.php | 2 +- src/network/mcpe/protocol/SetHealthPacket.php | 2 +- src/network/mcpe/protocol/SetLastHurtByPacket.php | 2 +- .../mcpe/protocol/SetLocalPlayerAsInitializedPacket.php | 2 +- src/network/mcpe/protocol/SetPlayerGameTypePacket.php | 2 +- src/network/mcpe/protocol/SetScorePacket.php | 2 +- src/network/mcpe/protocol/SetScoreboardIdentityPacket.php | 2 +- src/network/mcpe/protocol/SetSpawnPositionPacket.php | 2 +- src/network/mcpe/protocol/SetTimePacket.php | 2 +- src/network/mcpe/protocol/SetTitlePacket.php | 2 +- src/network/mcpe/protocol/SettingsCommandPacket.php | 2 +- src/network/mcpe/protocol/ShowCreditsPacket.php | 2 +- src/network/mcpe/protocol/ShowProfilePacket.php | 2 +- src/network/mcpe/protocol/ShowStoreOfferPacket.php | 2 +- src/network/mcpe/protocol/SimpleEventPacket.php | 2 +- src/network/mcpe/protocol/SpawnExperienceOrbPacket.php | 2 +- src/network/mcpe/protocol/SpawnParticleEffectPacket.php | 2 +- src/network/mcpe/protocol/StartGamePacket.php | 4 ++-- src/network/mcpe/protocol/StopSoundPacket.php | 2 +- src/network/mcpe/protocol/StructureBlockUpdatePacket.php | 2 +- .../mcpe/protocol/StructureTemplateDataRequestPacket.php | 2 +- .../mcpe/protocol/StructureTemplateDataResponsePacket.php | 2 +- src/network/mcpe/protocol/SubClientLoginPacket.php | 2 +- src/network/mcpe/protocol/TakeItemActorPacket.php | 2 +- src/network/mcpe/protocol/TextPacket.php | 2 +- src/network/mcpe/protocol/TickSyncPacket.php | 2 +- src/network/mcpe/protocol/TransferPacket.php | 2 +- src/network/mcpe/protocol/UnknownPacket.php | 2 +- src/network/mcpe/protocol/UpdateAttributesPacket.php | 2 +- src/network/mcpe/protocol/UpdateBlockPacket.php | 2 +- src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php | 4 ++-- src/network/mcpe/protocol/UpdateBlockSyncedPacket.php | 2 +- src/network/mcpe/protocol/UpdateEquipPacket.php | 2 +- src/network/mcpe/protocol/UpdateSoftEnumPacket.php | 2 +- src/network/mcpe/protocol/UpdateTradePacket.php | 2 +- src/network/mcpe/protocol/VideoStreamConnectPacket.php | 2 +- .../mcpe/{ => protocol}/serializer/NetworkBinaryStream.php | 2 +- .../mcpe/{ => protocol}/serializer/NetworkNbtSerializer.php | 2 +- src/network/mcpe/{ => protocol/serializer}/PacketBatch.php | 3 +-- src/network/mcpe/protocol/types/CacheableNbt.php | 2 +- .../mcpe/protocol/types/entity/BlockPosMetadataProperty.php | 2 +- .../mcpe/protocol/types/entity/ByteMetadataProperty.php | 2 +- .../protocol/types/entity/CompoundTagMetadataProperty.php | 4 ++-- .../mcpe/protocol/types/entity/FloatMetadataProperty.php | 2 +- .../mcpe/protocol/types/entity/IntMetadataProperty.php | 2 +- .../mcpe/protocol/types/entity/LongMetadataProperty.php | 2 +- src/network/mcpe/protocol/types/entity/MetadataProperty.php | 2 +- .../mcpe/protocol/types/entity/ShortMetadataProperty.php | 2 +- .../mcpe/protocol/types/entity/StringMetadataProperty.php | 2 +- .../mcpe/protocol/types/entity/Vec3MetadataProperty.php | 2 +- .../mcpe/protocol/types/inventory/MismatchTransactionData.php | 2 +- .../mcpe/protocol/types/inventory/NetworkInventoryAction.php | 2 +- .../mcpe/protocol/types/inventory/NormalTransactionData.php | 2 +- .../protocol/types/inventory/ReleaseItemTransactionData.php | 2 +- src/network/mcpe/protocol/types/inventory/TransactionData.php | 2 +- .../types/inventory/UseItemOnEntityTransactionData.php | 2 +- .../mcpe/protocol/types/inventory/UseItemTransactionData.php | 2 +- src/network/mcpe/protocol/types/recipe/FurnaceRecipe.php | 2 +- src/network/mcpe/protocol/types/recipe/MultiRecipe.php | 2 +- src/network/mcpe/protocol/types/recipe/RecipeWithTypeId.php | 2 +- src/network/mcpe/protocol/types/recipe/ShapedRecipe.php | 2 +- src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php | 2 +- .../protocol/types/resourcepacks/ResourcePackInfoEntry.php | 2 +- .../protocol/types/resourcepacks/ResourcePackStackEntry.php | 2 +- src/network/mcpe/serializer/ChunkSerializer.php | 1 + tests/phpunit/network/mcpe/protocol/TestPacket.php | 2 +- 182 files changed, 186 insertions(+), 184 deletions(-) rename src/network/mcpe/{ => protocol}/serializer/NetworkBinaryStream.php (99%) rename src/network/mcpe/{ => protocol}/serializer/NetworkNbtSerializer.php (97%) rename src/network/mcpe/{ => protocol/serializer}/PacketBatch.php (94%) diff --git a/src/Server.php b/src/Server.php index 963f03000b..9492aa88f0 100644 --- a/src/Server.php +++ b/src/Server.php @@ -51,7 +51,7 @@ use pocketmine\network\mcpe\compression\CompressBatchTask; use pocketmine\network\mcpe\compression\Zlib as ZlibNetworkCompression; use pocketmine\network\mcpe\encryption\NetworkCipher; use pocketmine\network\mcpe\NetworkSession; -use pocketmine\network\mcpe\PacketBatch; +use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\raklib\RakLibInterface; diff --git a/src/block/tile/Spawnable.php b/src/block/tile/Spawnable.php index 9abd96969f..3204c8cf54 100644 --- a/src/block/tile/Spawnable.php +++ b/src/block/tile/Spawnable.php @@ -25,7 +25,7 @@ namespace pocketmine\block\tile; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; -use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; +use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; use function get_class; abstract class Spawnable extends Tile{ diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index c3243176dd..2301783cf2 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -27,7 +27,7 @@ use pocketmine\item\Item; use pocketmine\network\mcpe\compression\CompressBatchPromise; use pocketmine\network\mcpe\compression\Zlib; use pocketmine\network\mcpe\convert\TypeConverter; -use pocketmine\network\mcpe\PacketBatch; +use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\protocol\CraftingDataPacket; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\protocol\types\recipe\FurnaceRecipe as ProtocolFurnaceRecipe; diff --git a/src/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php index b0218f45e4..75274e177a 100644 --- a/src/network/mcpe/ChunkRequestTask.php +++ b/src/network/mcpe/ChunkRequestTask.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe; use pocketmine\network\mcpe\compression\CompressBatchPromise; use pocketmine\network\mcpe\compression\Zlib; use pocketmine\network\mcpe\protocol\LevelChunkPacket; +use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\serializer\ChunkSerializer; use pocketmine\scheduler\AsyncTask; use pocketmine\world\format\Chunk; diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 36c8f12045..5b4a069555 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -66,6 +66,7 @@ use pocketmine\network\mcpe\protocol\Packet; use pocketmine\network\mcpe\protocol\PacketDecodeException; use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\PlayStatusPacket; +use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\protocol\ServerboundPacket; use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket; use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; diff --git a/src/network/mcpe/convert/RuntimeBlockMapping.php b/src/network/mcpe/convert/RuntimeBlockMapping.php index 367a3af14a..83ff78d21d 100644 --- a/src/network/mcpe/convert/RuntimeBlockMapping.php +++ b/src/network/mcpe/convert/RuntimeBlockMapping.php @@ -29,7 +29,7 @@ use pocketmine\nbt\NBT; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\protocol\types\CacheableNbt; -use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; +use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; use pocketmine\utils\SingletonTrait; use function file_get_contents; use function getmypid; diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 235c4c70e8..766ff51366 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -84,7 +84,7 @@ use pocketmine\network\mcpe\protocol\types\inventory\NormalTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\UseItemOnEntityTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\UseItemTransactionData; -use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; +use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; use pocketmine\player\Player; use function array_push; use function base64_encode; diff --git a/src/network/mcpe/protocol/ActorEventPacket.php b/src/network/mcpe/protocol/ActorEventPacket.php index 86f42759c1..a2686fbbf5 100644 --- a/src/network/mcpe/protocol/ActorEventPacket.php +++ b/src/network/mcpe/protocol/ActorEventPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ActorEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ACTOR_EVENT_PACKET; diff --git a/src/network/mcpe/protocol/ActorFallPacket.php b/src/network/mcpe/protocol/ActorFallPacket.php index 4bd7cca89e..4612d7dad9 100644 --- a/src/network/mcpe/protocol/ActorFallPacket.php +++ b/src/network/mcpe/protocol/ActorFallPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ActorFallPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ACTOR_FALL_PACKET; diff --git a/src/network/mcpe/protocol/ActorPickRequestPacket.php b/src/network/mcpe/protocol/ActorPickRequestPacket.php index 15d24f1ce7..911258e2f3 100644 --- a/src/network/mcpe/protocol/ActorPickRequestPacket.php +++ b/src/network/mcpe/protocol/ActorPickRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ActorPickRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ACTOR_PICK_REQUEST_PACKET; diff --git a/src/network/mcpe/protocol/AddActorPacket.php b/src/network/mcpe/protocol/AddActorPacket.php index c207dad19b..9dc200c86c 100644 --- a/src/network/mcpe/protocol/AddActorPacket.php +++ b/src/network/mcpe/protocol/AddActorPacket.php @@ -26,11 +26,11 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\entity\Attribute; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class AddActorPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/AddBehaviorTreePacket.php b/src/network/mcpe/protocol/AddBehaviorTreePacket.php index f62e0f8974..e9d6318cad 100644 --- a/src/network/mcpe/protocol/AddBehaviorTreePacket.php +++ b/src/network/mcpe/protocol/AddBehaviorTreePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class AddBehaviorTreePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_BEHAVIOR_TREE_PACKET; diff --git a/src/network/mcpe/protocol/AddEntityPacket.php b/src/network/mcpe/protocol/AddEntityPacket.php index a8fa734988..8d9e9debf7 100644 --- a/src/network/mcpe/protocol/AddEntityPacket.php +++ b/src/network/mcpe/protocol/AddEntityPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class AddEntityPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_ENTITY_PACKET; diff --git a/src/network/mcpe/protocol/AddItemActorPacket.php b/src/network/mcpe/protocol/AddItemActorPacket.php index 92a8141e41..8c0ddc2eb5 100644 --- a/src/network/mcpe/protocol/AddItemActorPacket.php +++ b/src/network/mcpe/protocol/AddItemActorPacket.php @@ -26,9 +26,9 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class AddItemActorPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_ITEM_ACTOR_PACKET; diff --git a/src/network/mcpe/protocol/AddPaintingPacket.php b/src/network/mcpe/protocol/AddPaintingPacket.php index 6c0080a644..54a2e2e8cc 100644 --- a/src/network/mcpe/protocol/AddPaintingPacket.php +++ b/src/network/mcpe/protocol/AddPaintingPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class AddPaintingPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_PAINTING_PACKET; diff --git a/src/network/mcpe/protocol/AddPlayerPacket.php b/src/network/mcpe/protocol/AddPlayerPacket.php index f2dafb1e8d..8c151bf89d 100644 --- a/src/network/mcpe/protocol/AddPlayerPacket.php +++ b/src/network/mcpe/protocol/AddPlayerPacket.php @@ -26,10 +26,10 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\UUID; use function count; diff --git a/src/network/mcpe/protocol/AdventureSettingsPacket.php b/src/network/mcpe/protocol/AdventureSettingsPacket.php index 4ec2202f2f..e6d9f0c3bd 100644 --- a/src/network/mcpe/protocol/AdventureSettingsPacket.php +++ b/src/network/mcpe/protocol/AdventureSettingsPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class AdventureSettingsPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ADVENTURE_SETTINGS_PACKET; diff --git a/src/network/mcpe/protocol/AnimatePacket.php b/src/network/mcpe/protocol/AnimatePacket.php index ee3389409e..785ea0ab0a 100644 --- a/src/network/mcpe/protocol/AnimatePacket.php +++ b/src/network/mcpe/protocol/AnimatePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class AnimatePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ANIMATE_PACKET; diff --git a/src/network/mcpe/protocol/AnvilDamagePacket.php b/src/network/mcpe/protocol/AnvilDamagePacket.php index 9c28b857ae..75163d3e98 100644 --- a/src/network/mcpe/protocol/AnvilDamagePacket.php +++ b/src/network/mcpe/protocol/AnvilDamagePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class AnvilDamagePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ANVIL_DAMAGE_PACKET; diff --git a/src/network/mcpe/protocol/AutomationClientConnectPacket.php b/src/network/mcpe/protocol/AutomationClientConnectPacket.php index 455234c16c..877e031e90 100644 --- a/src/network/mcpe/protocol/AutomationClientConnectPacket.php +++ b/src/network/mcpe/protocol/AutomationClientConnectPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class AutomationClientConnectPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::AUTOMATION_CLIENT_CONNECT_PACKET; diff --git a/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php b/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php index 01d3dfce2e..c3990e3aab 100644 --- a/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php +++ b/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use function file_get_contents; class AvailableActorIdentifiersPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/AvailableCommandsPacket.php b/src/network/mcpe/protocol/AvailableCommandsPacket.php index df651ee82f..a4fe85fec9 100644 --- a/src/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/network/mcpe/protocol/AvailableCommandsPacket.php @@ -25,11 +25,11 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\command\CommandData; use pocketmine\network\mcpe\protocol\types\command\CommandEnum; use pocketmine\network\mcpe\protocol\types\command\CommandEnumConstraint; use pocketmine\network\mcpe\protocol\types\command\CommandParameter; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; use function array_search; use function count; diff --git a/src/network/mcpe/protocol/BiomeDefinitionListPacket.php b/src/network/mcpe/protocol/BiomeDefinitionListPacket.php index 9587e9b8e8..8229843e2e 100644 --- a/src/network/mcpe/protocol/BiomeDefinitionListPacket.php +++ b/src/network/mcpe/protocol/BiomeDefinitionListPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use function file_get_contents; class BiomeDefinitionListPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/BlockActorDataPacket.php b/src/network/mcpe/protocol/BlockActorDataPacket.php index e5c3aefa11..8c9bfaf69f 100644 --- a/src/network/mcpe/protocol/BlockActorDataPacket.php +++ b/src/network/mcpe/protocol/BlockActorDataPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class BlockActorDataPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::BLOCK_ACTOR_DATA_PACKET; diff --git a/src/network/mcpe/protocol/BlockEventPacket.php b/src/network/mcpe/protocol/BlockEventPacket.php index acfce2b68c..2b29bad5bf 100644 --- a/src/network/mcpe/protocol/BlockEventPacket.php +++ b/src/network/mcpe/protocol/BlockEventPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class BlockEventPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::BLOCK_EVENT_PACKET; diff --git a/src/network/mcpe/protocol/BlockPickRequestPacket.php b/src/network/mcpe/protocol/BlockPickRequestPacket.php index 9366e4f2bc..091e788bfc 100644 --- a/src/network/mcpe/protocol/BlockPickRequestPacket.php +++ b/src/network/mcpe/protocol/BlockPickRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class BlockPickRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::BLOCK_PICK_REQUEST_PACKET; diff --git a/src/network/mcpe/protocol/BookEditPacket.php b/src/network/mcpe/protocol/BookEditPacket.php index d2bb25084f..4c4a3bd224 100644 --- a/src/network/mcpe/protocol/BookEditPacket.php +++ b/src/network/mcpe/protocol/BookEditPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class BookEditPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::BOOK_EDIT_PACKET; diff --git a/src/network/mcpe/protocol/BossEventPacket.php b/src/network/mcpe/protocol/BossEventPacket.php index 6797952629..00ffa78985 100644 --- a/src/network/mcpe/protocol/BossEventPacket.php +++ b/src/network/mcpe/protocol/BossEventPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class BossEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::BOSS_EVENT_PACKET; diff --git a/src/network/mcpe/protocol/CameraPacket.php b/src/network/mcpe/protocol/CameraPacket.php index c12eeb06d4..f6c5185137 100644 --- a/src/network/mcpe/protocol/CameraPacket.php +++ b/src/network/mcpe/protocol/CameraPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class CameraPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CAMERA_PACKET; diff --git a/src/network/mcpe/protocol/ChangeDimensionPacket.php b/src/network/mcpe/protocol/ChangeDimensionPacket.php index c50df0db5b..0417f18ef3 100644 --- a/src/network/mcpe/protocol/ChangeDimensionPacket.php +++ b/src/network/mcpe/protocol/ChangeDimensionPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ChangeDimensionPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CHANGE_DIMENSION_PACKET; diff --git a/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php b/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php index 4fd7247e67..20c8691632 100644 --- a/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php +++ b/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ChunkRadiusUpdatedPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CHUNK_RADIUS_UPDATED_PACKET; diff --git a/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php b/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php index f71ecd5638..028cc16e6c 100644 --- a/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php +++ b/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use function count; class ClientCacheBlobStatusPacket extends DataPacket implements ServerboundPacket{ diff --git a/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php b/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php index 4294ba27f2..f1510669c3 100644 --- a/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php +++ b/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\ChunkCacheBlob; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class ClientCacheMissResponsePacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/ClientCacheStatusPacket.php b/src/network/mcpe/protocol/ClientCacheStatusPacket.php index d96b402bd8..261846cc11 100644 --- a/src/network/mcpe/protocol/ClientCacheStatusPacket.php +++ b/src/network/mcpe/protocol/ClientCacheStatusPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ClientCacheStatusPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::CLIENT_CACHE_STATUS_PACKET; diff --git a/src/network/mcpe/protocol/ClientToServerHandshakePacket.php b/src/network/mcpe/protocol/ClientToServerHandshakePacket.php index 3e80204962..dc58eeb8de 100644 --- a/src/network/mcpe/protocol/ClientToServerHandshakePacket.php +++ b/src/network/mcpe/protocol/ClientToServerHandshakePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ClientToServerHandshakePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::CLIENT_TO_SERVER_HANDSHAKE_PACKET; diff --git a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php index 3ca24def34..3b1cec6ab7 100644 --- a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php +++ b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php @@ -25,10 +25,10 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\protocol\types\MapDecoration; use pocketmine\network\mcpe\protocol\types\MapTrackedObject; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\Color; use function count; #ifndef COMPILE diff --git a/src/network/mcpe/protocol/CommandBlockUpdatePacket.php b/src/network/mcpe/protocol/CommandBlockUpdatePacket.php index 0773994e04..ed10a2fea7 100644 --- a/src/network/mcpe/protocol/CommandBlockUpdatePacket.php +++ b/src/network/mcpe/protocol/CommandBlockUpdatePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class CommandBlockUpdatePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::COMMAND_BLOCK_UPDATE_PACKET; diff --git a/src/network/mcpe/protocol/CommandOutputPacket.php b/src/network/mcpe/protocol/CommandOutputPacket.php index 2909ee699b..6a8af61a1f 100644 --- a/src/network/mcpe/protocol/CommandOutputPacket.php +++ b/src/network/mcpe/protocol/CommandOutputPacket.php @@ -25,9 +25,9 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; use pocketmine\network\mcpe\protocol\types\command\CommandOutputMessage; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; use function count; diff --git a/src/network/mcpe/protocol/CommandRequestPacket.php b/src/network/mcpe/protocol/CommandRequestPacket.php index 0d27805287..ed9de73580 100644 --- a/src/network/mcpe/protocol/CommandRequestPacket.php +++ b/src/network/mcpe/protocol/CommandRequestPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class CommandRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::COMMAND_REQUEST_PACKET; diff --git a/src/network/mcpe/protocol/CompletedUsingItemPacket.php b/src/network/mcpe/protocol/CompletedUsingItemPacket.php index 7d7994dd3c..1e02def893 100644 --- a/src/network/mcpe/protocol/CompletedUsingItemPacket.php +++ b/src/network/mcpe/protocol/CompletedUsingItemPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class CompletedUsingItemPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::COMPLETED_USING_ITEM_PACKET; diff --git a/src/network/mcpe/protocol/ContainerClosePacket.php b/src/network/mcpe/protocol/ContainerClosePacket.php index 6ef089a498..549aa41126 100644 --- a/src/network/mcpe/protocol/ContainerClosePacket.php +++ b/src/network/mcpe/protocol/ContainerClosePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ContainerClosePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::CONTAINER_CLOSE_PACKET; diff --git a/src/network/mcpe/protocol/ContainerOpenPacket.php b/src/network/mcpe/protocol/ContainerOpenPacket.php index ab283e8d54..a1bdf1e937 100644 --- a/src/network/mcpe/protocol/ContainerOpenPacket.php +++ b/src/network/mcpe/protocol/ContainerOpenPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ContainerOpenPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CONTAINER_OPEN_PACKET; diff --git a/src/network/mcpe/protocol/ContainerSetDataPacket.php b/src/network/mcpe/protocol/ContainerSetDataPacket.php index 4ab0eb7a99..67a583cc06 100644 --- a/src/network/mcpe/protocol/ContainerSetDataPacket.php +++ b/src/network/mcpe/protocol/ContainerSetDataPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ContainerSetDataPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CONTAINER_SET_DATA_PACKET; diff --git a/src/network/mcpe/protocol/CraftingDataPacket.php b/src/network/mcpe/protocol/CraftingDataPacket.php index 43cf1f7ef1..46551c9d3f 100644 --- a/src/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/network/mcpe/protocol/CraftingDataPacket.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\PotionContainerChangeRecipe; use pocketmine\network\mcpe\protocol\types\PotionTypeRecipe; use pocketmine\network\mcpe\protocol\types\recipe\FurnaceRecipe; @@ -32,7 +33,6 @@ use pocketmine\network\mcpe\protocol\types\recipe\MultiRecipe; use pocketmine\network\mcpe\protocol\types\recipe\RecipeWithTypeId; use pocketmine\network\mcpe\protocol\types\recipe\ShapedRecipe; use pocketmine\network\mcpe\protocol\types\recipe\ShapelessRecipe; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class CraftingDataPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/CraftingEventPacket.php b/src/network/mcpe/protocol/CraftingEventPacket.php index 2b06745ac1..847e5ae03c 100644 --- a/src/network/mcpe/protocol/CraftingEventPacket.php +++ b/src/network/mcpe/protocol/CraftingEventPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\UUID; use function count; diff --git a/src/network/mcpe/protocol/DataPacket.php b/src/network/mcpe/protocol/DataPacket.php index 9051480044..d77f07e25b 100644 --- a/src/network/mcpe/protocol/DataPacket.php +++ b/src/network/mcpe/protocol/DataPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; use function get_class; diff --git a/src/network/mcpe/protocol/DisconnectPacket.php b/src/network/mcpe/protocol/DisconnectPacket.php index 539c9e1be6..98fa2edbb9 100644 --- a/src/network/mcpe/protocol/DisconnectPacket.php +++ b/src/network/mcpe/protocol/DisconnectPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class DisconnectPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::DISCONNECT_PACKET; diff --git a/src/network/mcpe/protocol/EducationSettingsPacket.php b/src/network/mcpe/protocol/EducationSettingsPacket.php index d27b6794d2..40345fb181 100644 --- a/src/network/mcpe/protocol/EducationSettingsPacket.php +++ b/src/network/mcpe/protocol/EducationSettingsPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class EducationSettingsPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::EDUCATION_SETTINGS_PACKET; diff --git a/src/network/mcpe/protocol/EmotePacket.php b/src/network/mcpe/protocol/EmotePacket.php index 733855c497..7bbf0ec56b 100644 --- a/src/network/mcpe/protocol/EmotePacket.php +++ b/src/network/mcpe/protocol/EmotePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class EmotePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::EMOTE_PACKET; diff --git a/src/network/mcpe/protocol/EventPacket.php b/src/network/mcpe/protocol/EventPacket.php index 0386098b4b..ca2e8e6ef0 100644 --- a/src/network/mcpe/protocol/EventPacket.php +++ b/src/network/mcpe/protocol/EventPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class EventPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::EVENT_PACKET; diff --git a/src/network/mcpe/protocol/GameRulesChangedPacket.php b/src/network/mcpe/protocol/GameRulesChangedPacket.php index 96eeddbdba..c39be28403 100644 --- a/src/network/mcpe/protocol/GameRulesChangedPacket.php +++ b/src/network/mcpe/protocol/GameRulesChangedPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class GameRulesChangedPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::GAME_RULES_CHANGED_PACKET; diff --git a/src/network/mcpe/protocol/GuiDataPickItemPacket.php b/src/network/mcpe/protocol/GuiDataPickItemPacket.php index 11f255d6a7..47cac7f5aa 100644 --- a/src/network/mcpe/protocol/GuiDataPickItemPacket.php +++ b/src/network/mcpe/protocol/GuiDataPickItemPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class GuiDataPickItemPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::GUI_DATA_PICK_ITEM_PACKET; diff --git a/src/network/mcpe/protocol/HurtArmorPacket.php b/src/network/mcpe/protocol/HurtArmorPacket.php index 90a583ced9..ff24f8e9ae 100644 --- a/src/network/mcpe/protocol/HurtArmorPacket.php +++ b/src/network/mcpe/protocol/HurtArmorPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class HurtArmorPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::HURT_ARMOR_PACKET; diff --git a/src/network/mcpe/protocol/InteractPacket.php b/src/network/mcpe/protocol/InteractPacket.php index 422de4cc99..d37e00ca77 100644 --- a/src/network/mcpe/protocol/InteractPacket.php +++ b/src/network/mcpe/protocol/InteractPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class InteractPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::INTERACT_PACKET; diff --git a/src/network/mcpe/protocol/InventoryContentPacket.php b/src/network/mcpe/protocol/InventoryContentPacket.php index e3cba72787..d39b573b19 100644 --- a/src/network/mcpe/protocol/InventoryContentPacket.php +++ b/src/network/mcpe/protocol/InventoryContentPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class InventoryContentPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/InventorySlotPacket.php b/src/network/mcpe/protocol/InventorySlotPacket.php index 593eb6378b..9077f21c17 100644 --- a/src/network/mcpe/protocol/InventorySlotPacket.php +++ b/src/network/mcpe/protocol/InventorySlotPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class InventorySlotPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::INVENTORY_SLOT_PACKET; diff --git a/src/network/mcpe/protocol/InventoryTransactionPacket.php b/src/network/mcpe/protocol/InventoryTransactionPacket.php index 68401b7716..d554ae4b80 100644 --- a/src/network/mcpe/protocol/InventoryTransactionPacket.php +++ b/src/network/mcpe/protocol/InventoryTransactionPacket.php @@ -25,13 +25,13 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\inventory\MismatchTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\NormalTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\TransactionData; use pocketmine\network\mcpe\protocol\types\inventory\UseItemOnEntityTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\UseItemTransactionData; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; /** * This packet effectively crams multiple packets into one. diff --git a/src/network/mcpe/protocol/ItemFrameDropItemPacket.php b/src/network/mcpe/protocol/ItemFrameDropItemPacket.php index 30c0ae0858..872565698a 100644 --- a/src/network/mcpe/protocol/ItemFrameDropItemPacket.php +++ b/src/network/mcpe/protocol/ItemFrameDropItemPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ItemFrameDropItemPacket extends DataPacket implements ServerboundPacket{ diff --git a/src/network/mcpe/protocol/LabTablePacket.php b/src/network/mcpe/protocol/LabTablePacket.php index 6a020f276d..1e79cc5434 100644 --- a/src/network/mcpe/protocol/LabTablePacket.php +++ b/src/network/mcpe/protocol/LabTablePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class LabTablePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::LAB_TABLE_PACKET; diff --git a/src/network/mcpe/protocol/LecternUpdatePacket.php b/src/network/mcpe/protocol/LecternUpdatePacket.php index 440f8554e7..ebc74afd70 100644 --- a/src/network/mcpe/protocol/LecternUpdatePacket.php +++ b/src/network/mcpe/protocol/LecternUpdatePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class LecternUpdatePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::LECTERN_UPDATE_PACKET; diff --git a/src/network/mcpe/protocol/LevelChunkPacket.php b/src/network/mcpe/protocol/LevelChunkPacket.php index 514024b16a..bcbd0dd41f 100644 --- a/src/network/mcpe/protocol/LevelChunkPacket.php +++ b/src/network/mcpe/protocol/LevelChunkPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use function count; class LevelChunkPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/LevelEventGenericPacket.php b/src/network/mcpe/protocol/LevelEventGenericPacket.php index 52a65d964e..29be8b4fc7 100644 --- a/src/network/mcpe/protocol/LevelEventGenericPacket.php +++ b/src/network/mcpe/protocol/LevelEventGenericPacket.php @@ -27,8 +27,8 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; -use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; class LevelEventGenericPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::LEVEL_EVENT_GENERIC_PACKET; diff --git a/src/network/mcpe/protocol/LevelEventPacket.php b/src/network/mcpe/protocol/LevelEventPacket.php index 6c39d76ac1..31f76242e1 100644 --- a/src/network/mcpe/protocol/LevelEventPacket.php +++ b/src/network/mcpe/protocol/LevelEventPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class LevelEventPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::LEVEL_EVENT_PACKET; diff --git a/src/network/mcpe/protocol/LevelSoundEventPacket.php b/src/network/mcpe/protocol/LevelSoundEventPacket.php index 8ee820d0de..ec424b2c6b 100644 --- a/src/network/mcpe/protocol/LevelSoundEventPacket.php +++ b/src/network/mcpe/protocol/LevelSoundEventPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class LevelSoundEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::LEVEL_SOUND_EVENT_PACKET; diff --git a/src/network/mcpe/protocol/LevelSoundEventPacketV1.php b/src/network/mcpe/protocol/LevelSoundEventPacketV1.php index 20f5d30611..b6c7de132e 100644 --- a/src/network/mcpe/protocol/LevelSoundEventPacketV1.php +++ b/src/network/mcpe/protocol/LevelSoundEventPacketV1.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; /** * Useless leftover from a 1.8 refactor, does nothing diff --git a/src/network/mcpe/protocol/LevelSoundEventPacketV2.php b/src/network/mcpe/protocol/LevelSoundEventPacketV2.php index b771f7835b..29c7c64a0f 100644 --- a/src/network/mcpe/protocol/LevelSoundEventPacketV2.php +++ b/src/network/mcpe/protocol/LevelSoundEventPacketV2.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; /** * Useless leftover from a 1.9 refactor, does nothing diff --git a/src/network/mcpe/protocol/LoginPacket.php b/src/network/mcpe/protocol/LoginPacket.php index 156630ea71..dc433a8a9e 100644 --- a/src/network/mcpe/protocol/LoginPacket.php +++ b/src/network/mcpe/protocol/LoginPacket.php @@ -25,10 +25,10 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\login\AuthenticationData; use pocketmine\network\mcpe\protocol\types\login\ClientData; use pocketmine\network\mcpe\protocol\types\login\JwtChain; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; use pocketmine\utils\Utils; diff --git a/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php b/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php index b0fd28e31d..7c3b9a1f94 100644 --- a/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php +++ b/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class MapCreateLockedCopyPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MAP_CREATE_LOCKED_COPY_PACKET; diff --git a/src/network/mcpe/protocol/MapInfoRequestPacket.php b/src/network/mcpe/protocol/MapInfoRequestPacket.php index d26519025d..d7a09dae1d 100644 --- a/src/network/mcpe/protocol/MapInfoRequestPacket.php +++ b/src/network/mcpe/protocol/MapInfoRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class MapInfoRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MAP_INFO_REQUEST_PACKET; diff --git a/src/network/mcpe/protocol/MobArmorEquipmentPacket.php b/src/network/mcpe/protocol/MobArmorEquipmentPacket.php index 7606b4c136..ea830ee4c2 100644 --- a/src/network/mcpe/protocol/MobArmorEquipmentPacket.php +++ b/src/network/mcpe/protocol/MobArmorEquipmentPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class MobArmorEquipmentPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MOB_ARMOR_EQUIPMENT_PACKET; diff --git a/src/network/mcpe/protocol/MobEffectPacket.php b/src/network/mcpe/protocol/MobEffectPacket.php index 695a4e2f94..1e7beb3f44 100644 --- a/src/network/mcpe/protocol/MobEffectPacket.php +++ b/src/network/mcpe/protocol/MobEffectPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class MobEffectPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::MOB_EFFECT_PACKET; diff --git a/src/network/mcpe/protocol/MobEquipmentPacket.php b/src/network/mcpe/protocol/MobEquipmentPacket.php index 1b8691f314..f3abb8fd6f 100644 --- a/src/network/mcpe/protocol/MobEquipmentPacket.php +++ b/src/network/mcpe/protocol/MobEquipmentPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class MobEquipmentPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MOB_EQUIPMENT_PACKET; diff --git a/src/network/mcpe/protocol/ModalFormRequestPacket.php b/src/network/mcpe/protocol/ModalFormRequestPacket.php index 2672e67d38..60138ab91a 100644 --- a/src/network/mcpe/protocol/ModalFormRequestPacket.php +++ b/src/network/mcpe/protocol/ModalFormRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ModalFormRequestPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::MODAL_FORM_REQUEST_PACKET; diff --git a/src/network/mcpe/protocol/ModalFormResponsePacket.php b/src/network/mcpe/protocol/ModalFormResponsePacket.php index bee8fb2d48..ab7bded1f3 100644 --- a/src/network/mcpe/protocol/ModalFormResponsePacket.php +++ b/src/network/mcpe/protocol/ModalFormResponsePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ModalFormResponsePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MODAL_FORM_RESPONSE_PACKET; diff --git a/src/network/mcpe/protocol/MoveActorAbsolutePacket.php b/src/network/mcpe/protocol/MoveActorAbsolutePacket.php index ef57798e6f..d2894d811a 100644 --- a/src/network/mcpe/protocol/MoveActorAbsolutePacket.php +++ b/src/network/mcpe/protocol/MoveActorAbsolutePacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class MoveActorAbsolutePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MOVE_ACTOR_ABSOLUTE_PACKET; diff --git a/src/network/mcpe/protocol/MoveActorDeltaPacket.php b/src/network/mcpe/protocol/MoveActorDeltaPacket.php index 319e4b6399..83632035f3 100644 --- a/src/network/mcpe/protocol/MoveActorDeltaPacket.php +++ b/src/network/mcpe/protocol/MoveActorDeltaPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; class MoveActorDeltaPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/MovePlayerPacket.php b/src/network/mcpe/protocol/MovePlayerPacket.php index 7f392b49e6..cf2a3a8b7a 100644 --- a/src/network/mcpe/protocol/MovePlayerPacket.php +++ b/src/network/mcpe/protocol/MovePlayerPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class MovePlayerPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MOVE_PLAYER_PACKET; diff --git a/src/network/mcpe/protocol/MultiplayerSettingsPacket.php b/src/network/mcpe/protocol/MultiplayerSettingsPacket.php index 0b2169265d..ef0a192faa 100644 --- a/src/network/mcpe/protocol/MultiplayerSettingsPacket.php +++ b/src/network/mcpe/protocol/MultiplayerSettingsPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class MultiplayerSettingsPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MULTIPLAYER_SETTINGS_PACKET; diff --git a/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php b/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php index eeb2db1c50..845664bba5 100644 --- a/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php +++ b/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class NetworkChunkPublisherUpdatePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::NETWORK_CHUNK_PUBLISHER_UPDATE_PACKET; diff --git a/src/network/mcpe/protocol/NetworkSettingsPacket.php b/src/network/mcpe/protocol/NetworkSettingsPacket.php index 357e118d4b..4651b371d0 100644 --- a/src/network/mcpe/protocol/NetworkSettingsPacket.php +++ b/src/network/mcpe/protocol/NetworkSettingsPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class NetworkSettingsPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::NETWORK_SETTINGS_PACKET; diff --git a/src/network/mcpe/protocol/NetworkStackLatencyPacket.php b/src/network/mcpe/protocol/NetworkStackLatencyPacket.php index 7a045b30db..d05b7ee01f 100644 --- a/src/network/mcpe/protocol/NetworkStackLatencyPacket.php +++ b/src/network/mcpe/protocol/NetworkStackLatencyPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class NetworkStackLatencyPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::NETWORK_STACK_LATENCY_PACKET; diff --git a/src/network/mcpe/protocol/NpcRequestPacket.php b/src/network/mcpe/protocol/NpcRequestPacket.php index 9789f52fbb..7fe02de6e5 100644 --- a/src/network/mcpe/protocol/NpcRequestPacket.php +++ b/src/network/mcpe/protocol/NpcRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class NpcRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::NPC_REQUEST_PACKET; diff --git a/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php b/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php index 032427acaa..b7fb8e81e6 100644 --- a/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php +++ b/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class OnScreenTextureAnimationPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ON_SCREEN_TEXTURE_ANIMATION_PACKET; diff --git a/src/network/mcpe/protocol/Packet.php b/src/network/mcpe/protocol/Packet.php index b90fe3392d..f631040e1f 100644 --- a/src/network/mcpe/protocol/Packet.php +++ b/src/network/mcpe/protocol/Packet.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; interface Packet{ diff --git a/src/network/mcpe/protocol/PhotoTransferPacket.php b/src/network/mcpe/protocol/PhotoTransferPacket.php index 9863282204..67222f8ece 100644 --- a/src/network/mcpe/protocol/PhotoTransferPacket.php +++ b/src/network/mcpe/protocol/PhotoTransferPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class PhotoTransferPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::PHOTO_TRANSFER_PACKET; diff --git a/src/network/mcpe/protocol/PlaySoundPacket.php b/src/network/mcpe/protocol/PlaySoundPacket.php index df969a7425..17cbdeb86a 100644 --- a/src/network/mcpe/protocol/PlaySoundPacket.php +++ b/src/network/mcpe/protocol/PlaySoundPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class PlaySoundPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAY_SOUND_PACKET; diff --git a/src/network/mcpe/protocol/PlayStatusPacket.php b/src/network/mcpe/protocol/PlayStatusPacket.php index 096f97a75d..7fb52ebd81 100644 --- a/src/network/mcpe/protocol/PlayStatusPacket.php +++ b/src/network/mcpe/protocol/PlayStatusPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class PlayStatusPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAY_STATUS_PACKET; diff --git a/src/network/mcpe/protocol/PlayerActionPacket.php b/src/network/mcpe/protocol/PlayerActionPacket.php index 87945518aa..8cc9d79bde 100644 --- a/src/network/mcpe/protocol/PlayerActionPacket.php +++ b/src/network/mcpe/protocol/PlayerActionPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class PlayerActionPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAYER_ACTION_PACKET; diff --git a/src/network/mcpe/protocol/PlayerAuthInputPacket.php b/src/network/mcpe/protocol/PlayerAuthInputPacket.php index eb945f7ea0..2a5fa871e7 100644 --- a/src/network/mcpe/protocol/PlayerAuthInputPacket.php +++ b/src/network/mcpe/protocol/PlayerAuthInputPacket.php @@ -26,9 +26,9 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\InputMode; use pocketmine\network\mcpe\protocol\types\PlayMode; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function assert; class PlayerAuthInputPacket extends DataPacket implements ServerboundPacket{ diff --git a/src/network/mcpe/protocol/PlayerHotbarPacket.php b/src/network/mcpe/protocol/PlayerHotbarPacket.php index 23e8248bd3..67f8d8b8f2 100644 --- a/src/network/mcpe/protocol/PlayerHotbarPacket.php +++ b/src/network/mcpe/protocol/PlayerHotbarPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class PlayerHotbarPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAYER_HOTBAR_PACKET; diff --git a/src/network/mcpe/protocol/PlayerInputPacket.php b/src/network/mcpe/protocol/PlayerInputPacket.php index 930316fc3a..a2ec3122a8 100644 --- a/src/network/mcpe/protocol/PlayerInputPacket.php +++ b/src/network/mcpe/protocol/PlayerInputPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class PlayerInputPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAYER_INPUT_PACKET; diff --git a/src/network/mcpe/protocol/PlayerListPacket.php b/src/network/mcpe/protocol/PlayerListPacket.php index 94ef66ed30..462156bf65 100644 --- a/src/network/mcpe/protocol/PlayerListPacket.php +++ b/src/network/mcpe/protocol/PlayerListPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class PlayerListPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/PlayerSkinPacket.php b/src/network/mcpe/protocol/PlayerSkinPacket.php index f4e57f13fd..f1128c9b79 100644 --- a/src/network/mcpe/protocol/PlayerSkinPacket.php +++ b/src/network/mcpe/protocol/PlayerSkinPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\SkinData; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\UUID; class PlayerSkinPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ diff --git a/src/network/mcpe/protocol/PurchaseReceiptPacket.php b/src/network/mcpe/protocol/PurchaseReceiptPacket.php index d9aafafc84..6d3d6e495c 100644 --- a/src/network/mcpe/protocol/PurchaseReceiptPacket.php +++ b/src/network/mcpe/protocol/PurchaseReceiptPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use function count; class PurchaseReceiptPacket extends DataPacket implements ServerboundPacket{ diff --git a/src/network/mcpe/protocol/RemoveActorPacket.php b/src/network/mcpe/protocol/RemoveActorPacket.php index 730733cf89..8f92a97e88 100644 --- a/src/network/mcpe/protocol/RemoveActorPacket.php +++ b/src/network/mcpe/protocol/RemoveActorPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class RemoveActorPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::REMOVE_ACTOR_PACKET; diff --git a/src/network/mcpe/protocol/RemoveEntityPacket.php b/src/network/mcpe/protocol/RemoveEntityPacket.php index c471e4d2f8..c6c7cd79cf 100644 --- a/src/network/mcpe/protocol/RemoveEntityPacket.php +++ b/src/network/mcpe/protocol/RemoveEntityPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class RemoveEntityPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::REMOVE_ENTITY_PACKET; diff --git a/src/network/mcpe/protocol/RemoveObjectivePacket.php b/src/network/mcpe/protocol/RemoveObjectivePacket.php index b338017d93..e69121c337 100644 --- a/src/network/mcpe/protocol/RemoveObjectivePacket.php +++ b/src/network/mcpe/protocol/RemoveObjectivePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class RemoveObjectivePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::REMOVE_OBJECTIVE_PACKET; diff --git a/src/network/mcpe/protocol/RequestChunkRadiusPacket.php b/src/network/mcpe/protocol/RequestChunkRadiusPacket.php index 8b8a4a5701..2df4dd5e31 100644 --- a/src/network/mcpe/protocol/RequestChunkRadiusPacket.php +++ b/src/network/mcpe/protocol/RequestChunkRadiusPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class RequestChunkRadiusPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::REQUEST_CHUNK_RADIUS_PACKET; diff --git a/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php b/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php index a2badc20c2..113035ed12 100644 --- a/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php +++ b/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ResourcePackChunkDataPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_CHUNK_DATA_PACKET; diff --git a/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php b/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php index b925423e61..fb5adb68ee 100644 --- a/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php +++ b/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ResourcePackChunkRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_CHUNK_REQUEST_PACKET; diff --git a/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php b/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php index 58ea907a7f..de6994557a 100644 --- a/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php +++ b/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use function count; class ResourcePackClientResponsePacket extends DataPacket implements ServerboundPacket{ diff --git a/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php b/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php index ad2af8423b..37e07589df 100644 --- a/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php +++ b/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackType; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class ResourcePackDataInfoPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_DATA_INFO_PACKET; diff --git a/src/network/mcpe/protocol/ResourcePackStackPacket.php b/src/network/mcpe/protocol/ResourcePackStackPacket.php index a2209ab86e..4391599624 100644 --- a/src/network/mcpe/protocol/ResourcePackStackPacket.php +++ b/src/network/mcpe/protocol/ResourcePackStackPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackStackEntry; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class ResourcePackStackPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php index 6a88c50487..7cd76f11a0 100644 --- a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php +++ b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackInfoEntry; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/RespawnPacket.php b/src/network/mcpe/protocol/RespawnPacket.php index c5d02c703e..0e6604ee39 100644 --- a/src/network/mcpe/protocol/RespawnPacket.php +++ b/src/network/mcpe/protocol/RespawnPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class RespawnPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::RESPAWN_PACKET; diff --git a/src/network/mcpe/protocol/RiderJumpPacket.php b/src/network/mcpe/protocol/RiderJumpPacket.php index c213340c5f..5e2b1bc197 100644 --- a/src/network/mcpe/protocol/RiderJumpPacket.php +++ b/src/network/mcpe/protocol/RiderJumpPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class RiderJumpPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::RIDER_JUMP_PACKET; diff --git a/src/network/mcpe/protocol/ScriptCustomEventPacket.php b/src/network/mcpe/protocol/ScriptCustomEventPacket.php index ed3ba8d36c..7c0cf70ccf 100644 --- a/src/network/mcpe/protocol/ScriptCustomEventPacket.php +++ b/src/network/mcpe/protocol/ScriptCustomEventPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ScriptCustomEventPacket extends DataPacket{ //TODO: this doesn't have handlers in either client or server in the game as of 1.8 public const NETWORK_ID = ProtocolInfo::SCRIPT_CUSTOM_EVENT_PACKET; diff --git a/src/network/mcpe/protocol/ServerSettingsRequestPacket.php b/src/network/mcpe/protocol/ServerSettingsRequestPacket.php index fe261df1ca..4a4367cb0e 100644 --- a/src/network/mcpe/protocol/ServerSettingsRequestPacket.php +++ b/src/network/mcpe/protocol/ServerSettingsRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ServerSettingsRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SERVER_SETTINGS_REQUEST_PACKET; diff --git a/src/network/mcpe/protocol/ServerSettingsResponsePacket.php b/src/network/mcpe/protocol/ServerSettingsResponsePacket.php index 23a7dfce62..da6aee42aa 100644 --- a/src/network/mcpe/protocol/ServerSettingsResponsePacket.php +++ b/src/network/mcpe/protocol/ServerSettingsResponsePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ServerSettingsResponsePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SERVER_SETTINGS_RESPONSE_PACKET; diff --git a/src/network/mcpe/protocol/ServerToClientHandshakePacket.php b/src/network/mcpe/protocol/ServerToClientHandshakePacket.php index 03c4509bd9..0124d94560 100644 --- a/src/network/mcpe/protocol/ServerToClientHandshakePacket.php +++ b/src/network/mcpe/protocol/ServerToClientHandshakePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ServerToClientHandshakePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SERVER_TO_CLIENT_HANDSHAKE_PACKET; diff --git a/src/network/mcpe/protocol/SetActorDataPacket.php b/src/network/mcpe/protocol/SetActorDataPacket.php index 59b6d7d4f5..809172f9e3 100644 --- a/src/network/mcpe/protocol/SetActorDataPacket.php +++ b/src/network/mcpe/protocol/SetActorDataPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetActorDataPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ //TODO: check why this is serverbound public const NETWORK_ID = ProtocolInfo::SET_ACTOR_DATA_PACKET; diff --git a/src/network/mcpe/protocol/SetActorLinkPacket.php b/src/network/mcpe/protocol/SetActorLinkPacket.php index 50c765b8f1..882ae1bc7b 100644 --- a/src/network/mcpe/protocol/SetActorLinkPacket.php +++ b/src/network/mcpe/protocol/SetActorLinkPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SetActorLinkPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_ACTOR_LINK_PACKET; diff --git a/src/network/mcpe/protocol/SetActorMotionPacket.php b/src/network/mcpe/protocol/SetActorMotionPacket.php index acd72be78d..a1d8dc8881 100644 --- a/src/network/mcpe/protocol/SetActorMotionPacket.php +++ b/src/network/mcpe/protocol/SetActorMotionPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; /** * TODO: This packet is (erroneously) sent to the server when the client is riding a vehicle. diff --git a/src/network/mcpe/protocol/SetCommandsEnabledPacket.php b/src/network/mcpe/protocol/SetCommandsEnabledPacket.php index 505a356800..c772854af3 100644 --- a/src/network/mcpe/protocol/SetCommandsEnabledPacket.php +++ b/src/network/mcpe/protocol/SetCommandsEnabledPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class SetCommandsEnabledPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_COMMANDS_ENABLED_PACKET; diff --git a/src/network/mcpe/protocol/SetDefaultGameTypePacket.php b/src/network/mcpe/protocol/SetDefaultGameTypePacket.php index ad2bf5bad0..7791d2c822 100644 --- a/src/network/mcpe/protocol/SetDefaultGameTypePacket.php +++ b/src/network/mcpe/protocol/SetDefaultGameTypePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class SetDefaultGameTypePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_DEFAULT_GAME_TYPE_PACKET; diff --git a/src/network/mcpe/protocol/SetDifficultyPacket.php b/src/network/mcpe/protocol/SetDifficultyPacket.php index 5543bf57cd..d80ccc127f 100644 --- a/src/network/mcpe/protocol/SetDifficultyPacket.php +++ b/src/network/mcpe/protocol/SetDifficultyPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class SetDifficultyPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_DIFFICULTY_PACKET; diff --git a/src/network/mcpe/protocol/SetDisplayObjectivePacket.php b/src/network/mcpe/protocol/SetDisplayObjectivePacket.php index 461e2b0ed1..aa2ee249f0 100644 --- a/src/network/mcpe/protocol/SetDisplayObjectivePacket.php +++ b/src/network/mcpe/protocol/SetDisplayObjectivePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class SetDisplayObjectivePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_DISPLAY_OBJECTIVE_PACKET; diff --git a/src/network/mcpe/protocol/SetHealthPacket.php b/src/network/mcpe/protocol/SetHealthPacket.php index 41be570007..8defcfb6e3 100644 --- a/src/network/mcpe/protocol/SetHealthPacket.php +++ b/src/network/mcpe/protocol/SetHealthPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class SetHealthPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_HEALTH_PACKET; diff --git a/src/network/mcpe/protocol/SetLastHurtByPacket.php b/src/network/mcpe/protocol/SetLastHurtByPacket.php index 601d11e1e2..fd468f4ae4 100644 --- a/src/network/mcpe/protocol/SetLastHurtByPacket.php +++ b/src/network/mcpe/protocol/SetLastHurtByPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class SetLastHurtByPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_LAST_HURT_BY_PACKET; diff --git a/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php b/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php index c7e4ffffdc..9218524c21 100644 --- a/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php +++ b/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class SetLocalPlayerAsInitializedPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_LOCAL_PLAYER_AS_INITIALIZED_PACKET; diff --git a/src/network/mcpe/protocol/SetPlayerGameTypePacket.php b/src/network/mcpe/protocol/SetPlayerGameTypePacket.php index 93dba5df9e..28a8023fcc 100644 --- a/src/network/mcpe/protocol/SetPlayerGameTypePacket.php +++ b/src/network/mcpe/protocol/SetPlayerGameTypePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class SetPlayerGameTypePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_PLAYER_GAME_TYPE_PACKET; diff --git a/src/network/mcpe/protocol/SetScorePacket.php b/src/network/mcpe/protocol/SetScorePacket.php index 0962fecd8a..43a4f73dd5 100644 --- a/src/network/mcpe/protocol/SetScorePacket.php +++ b/src/network/mcpe/protocol/SetScorePacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\ScorePacketEntry; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class SetScorePacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php b/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php index 6c5ae55a46..3e195d812f 100644 --- a/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php +++ b/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\ScoreboardIdentityPacketEntry; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function count; class SetScoreboardIdentityPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/SetSpawnPositionPacket.php b/src/network/mcpe/protocol/SetSpawnPositionPacket.php index b2f5ee5017..fd7da1f46f 100644 --- a/src/network/mcpe/protocol/SetSpawnPositionPacket.php +++ b/src/network/mcpe/protocol/SetSpawnPositionPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class SetSpawnPositionPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_SPAWN_POSITION_PACKET; diff --git a/src/network/mcpe/protocol/SetTimePacket.php b/src/network/mcpe/protocol/SetTimePacket.php index d4a2fcd3f9..54b51e9df7 100644 --- a/src/network/mcpe/protocol/SetTimePacket.php +++ b/src/network/mcpe/protocol/SetTimePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class SetTimePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_TIME_PACKET; diff --git a/src/network/mcpe/protocol/SetTitlePacket.php b/src/network/mcpe/protocol/SetTitlePacket.php index e7acddc420..6d4d4b470a 100644 --- a/src/network/mcpe/protocol/SetTitlePacket.php +++ b/src/network/mcpe/protocol/SetTitlePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class SetTitlePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_TITLE_PACKET; diff --git a/src/network/mcpe/protocol/SettingsCommandPacket.php b/src/network/mcpe/protocol/SettingsCommandPacket.php index 4909470161..b189118d33 100644 --- a/src/network/mcpe/protocol/SettingsCommandPacket.php +++ b/src/network/mcpe/protocol/SettingsCommandPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class SettingsCommandPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SETTINGS_COMMAND_PACKET; diff --git a/src/network/mcpe/protocol/ShowCreditsPacket.php b/src/network/mcpe/protocol/ShowCreditsPacket.php index 02cc700179..8306ea67af 100644 --- a/src/network/mcpe/protocol/ShowCreditsPacket.php +++ b/src/network/mcpe/protocol/ShowCreditsPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ShowCreditsPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SHOW_CREDITS_PACKET; diff --git a/src/network/mcpe/protocol/ShowProfilePacket.php b/src/network/mcpe/protocol/ShowProfilePacket.php index d1a2c073ab..9a52cee363 100644 --- a/src/network/mcpe/protocol/ShowProfilePacket.php +++ b/src/network/mcpe/protocol/ShowProfilePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ShowProfilePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SHOW_PROFILE_PACKET; diff --git a/src/network/mcpe/protocol/ShowStoreOfferPacket.php b/src/network/mcpe/protocol/ShowStoreOfferPacket.php index 3896e4419e..1b76dc3514 100644 --- a/src/network/mcpe/protocol/ShowStoreOfferPacket.php +++ b/src/network/mcpe/protocol/ShowStoreOfferPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ShowStoreOfferPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SHOW_STORE_OFFER_PACKET; diff --git a/src/network/mcpe/protocol/SimpleEventPacket.php b/src/network/mcpe/protocol/SimpleEventPacket.php index f571910722..fb96307c77 100644 --- a/src/network/mcpe/protocol/SimpleEventPacket.php +++ b/src/network/mcpe/protocol/SimpleEventPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class SimpleEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SIMPLE_EVENT_PACKET; diff --git a/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php b/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php index c2f6cdaaf4..9c9cfc5706 100644 --- a/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php +++ b/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class SpawnExperienceOrbPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SPAWN_EXPERIENCE_ORB_PACKET; diff --git a/src/network/mcpe/protocol/SpawnParticleEffectPacket.php b/src/network/mcpe/protocol/SpawnParticleEffectPacket.php index 4595a39ea0..7f299373a4 100644 --- a/src/network/mcpe/protocol/SpawnParticleEffectPacket.php +++ b/src/network/mcpe/protocol/SpawnParticleEffectPacket.php @@ -26,8 +26,8 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\DimensionIds; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class SpawnParticleEffectPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SPAWN_PARTICLE_EFFECT_PACKET; diff --git a/src/network/mcpe/protocol/StartGamePacket.php b/src/network/mcpe/protocol/StartGamePacket.php index 241afa12d5..0d06bc9397 100644 --- a/src/network/mcpe/protocol/StartGamePacket.php +++ b/src/network/mcpe/protocol/StartGamePacket.php @@ -27,10 +27,10 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\nbt\tag\ListTag; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; use pocketmine\network\mcpe\protocol\types\CacheableNbt; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; -use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; use function count; use function file_get_contents; use function json_decode; diff --git a/src/network/mcpe/protocol/StopSoundPacket.php b/src/network/mcpe/protocol/StopSoundPacket.php index af4f05df9d..bb1db9d4c4 100644 --- a/src/network/mcpe/protocol/StopSoundPacket.php +++ b/src/network/mcpe/protocol/StopSoundPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class StopSoundPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::STOP_SOUND_PACKET; diff --git a/src/network/mcpe/protocol/StructureBlockUpdatePacket.php b/src/network/mcpe/protocol/StructureBlockUpdatePacket.php index c3e1a33405..a17a50148b 100644 --- a/src/network/mcpe/protocol/StructureBlockUpdatePacket.php +++ b/src/network/mcpe/protocol/StructureBlockUpdatePacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\StructureEditorData; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class StructureBlockUpdatePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::STRUCTURE_BLOCK_UPDATE_PACKET; diff --git a/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php b/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php index 9c58f46cab..5abb98420e 100644 --- a/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php +++ b/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\StructureSettings; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class StructureTemplateDataRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::STRUCTURE_TEMPLATE_DATA_REQUEST_PACKET; diff --git a/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php b/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php index b2418d74e8..9d576e1a50 100644 --- a/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php +++ b/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class StructureTemplateDataResponsePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::STRUCTURE_TEMPLATE_DATA_RESPONSE_PACKET; diff --git a/src/network/mcpe/protocol/SubClientLoginPacket.php b/src/network/mcpe/protocol/SubClientLoginPacket.php index 8fd6709a74..a20d1592bf 100644 --- a/src/network/mcpe/protocol/SubClientLoginPacket.php +++ b/src/network/mcpe/protocol/SubClientLoginPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class SubClientLoginPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SUB_CLIENT_LOGIN_PACKET; diff --git a/src/network/mcpe/protocol/TakeItemActorPacket.php b/src/network/mcpe/protocol/TakeItemActorPacket.php index 83eff49d51..67737f9ea6 100644 --- a/src/network/mcpe/protocol/TakeItemActorPacket.php +++ b/src/network/mcpe/protocol/TakeItemActorPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class TakeItemActorPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::TAKE_ITEM_ACTOR_PACKET; diff --git a/src/network/mcpe/protocol/TextPacket.php b/src/network/mcpe/protocol/TextPacket.php index ccbbbe53ec..4224d89531 100644 --- a/src/network/mcpe/protocol/TextPacket.php +++ b/src/network/mcpe/protocol/TextPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use function count; class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ diff --git a/src/network/mcpe/protocol/TickSyncPacket.php b/src/network/mcpe/protocol/TickSyncPacket.php index bc989030fe..84d3f5d2c4 100644 --- a/src/network/mcpe/protocol/TickSyncPacket.php +++ b/src/network/mcpe/protocol/TickSyncPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class TickSyncPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::TICK_SYNC_PACKET; diff --git a/src/network/mcpe/protocol/TransferPacket.php b/src/network/mcpe/protocol/TransferPacket.php index 22eb3aaccd..635d61f0c5 100644 --- a/src/network/mcpe/protocol/TransferPacket.php +++ b/src/network/mcpe/protocol/TransferPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class TransferPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::TRANSFER_PACKET; diff --git a/src/network/mcpe/protocol/UnknownPacket.php b/src/network/mcpe/protocol/UnknownPacket.php index e4cac4aefe..720211fbdc 100644 --- a/src/network/mcpe/protocol/UnknownPacket.php +++ b/src/network/mcpe/protocol/UnknownPacket.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use function ord; use function strlen; diff --git a/src/network/mcpe/protocol/UpdateAttributesPacket.php b/src/network/mcpe/protocol/UpdateAttributesPacket.php index aef34a6bf1..31929d3ab3 100644 --- a/src/network/mcpe/protocol/UpdateAttributesPacket.php +++ b/src/network/mcpe/protocol/UpdateAttributesPacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\entity\Attribute; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use function array_values; class UpdateAttributesPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/UpdateBlockPacket.php b/src/network/mcpe/protocol/UpdateBlockPacket.php index 0d739b719a..0d590385f6 100644 --- a/src/network/mcpe/protocol/UpdateBlockPacket.php +++ b/src/network/mcpe/protocol/UpdateBlockPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class UpdateBlockPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_BLOCK_PACKET; diff --git a/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php b/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php index 9b42188ac6..07131bdf70 100644 --- a/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php +++ b/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php @@ -27,8 +27,8 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; -use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; class UpdateBlockPropertiesPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_BLOCK_PROPERTIES_PACKET; diff --git a/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php b/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php index 8a08b3e979..c116295504 100644 --- a/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php +++ b/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class UpdateBlockSyncedPacket extends UpdateBlockPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_BLOCK_SYNCED_PACKET; diff --git a/src/network/mcpe/protocol/UpdateEquipPacket.php b/src/network/mcpe/protocol/UpdateEquipPacket.php index 290a2a550a..a6a6a5114a 100644 --- a/src/network/mcpe/protocol/UpdateEquipPacket.php +++ b/src/network/mcpe/protocol/UpdateEquipPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class UpdateEquipPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_EQUIP_PACKET; diff --git a/src/network/mcpe/protocol/UpdateSoftEnumPacket.php b/src/network/mcpe/protocol/UpdateSoftEnumPacket.php index 767ccf5c73..9e91cdace3 100644 --- a/src/network/mcpe/protocol/UpdateSoftEnumPacket.php +++ b/src/network/mcpe/protocol/UpdateSoftEnumPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use function count; class UpdateSoftEnumPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/UpdateTradePacket.php b/src/network/mcpe/protocol/UpdateTradePacket.php index 59df00bb77..f64e31ce61 100644 --- a/src/network/mcpe/protocol/UpdateTradePacket.php +++ b/src/network/mcpe/protocol/UpdateTradePacket.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; class UpdateTradePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_TRADE_PACKET; diff --git a/src/network/mcpe/protocol/VideoStreamConnectPacket.php b/src/network/mcpe/protocol/VideoStreamConnectPacket.php index dfb4750b96..def67364cd 100644 --- a/src/network/mcpe/protocol/VideoStreamConnectPacket.php +++ b/src/network/mcpe/protocol/VideoStreamConnectPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class VideoStreamConnectPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::VIDEO_STREAM_CONNECT_PACKET; diff --git a/src/network/mcpe/serializer/NetworkBinaryStream.php b/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php similarity index 99% rename from src/network/mcpe/serializer/NetworkBinaryStream.php rename to src/network/mcpe/protocol/serializer/NetworkBinaryStream.php index 4e0f2116aa..fdd54858b5 100644 --- a/src/network/mcpe/serializer/NetworkBinaryStream.php +++ b/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\serializer; +namespace pocketmine\network\mcpe\protocol\serializer; #include diff --git a/src/network/mcpe/serializer/NetworkNbtSerializer.php b/src/network/mcpe/protocol/serializer/NetworkNbtSerializer.php similarity index 97% rename from src/network/mcpe/serializer/NetworkNbtSerializer.php rename to src/network/mcpe/protocol/serializer/NetworkNbtSerializer.php index 8d4a882634..91a679323f 100644 --- a/src/network/mcpe/serializer/NetworkNbtSerializer.php +++ b/src/network/mcpe/protocol/serializer/NetworkNbtSerializer.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\serializer; +namespace pocketmine\network\mcpe\protocol\serializer; use pocketmine\nbt\LittleEndianNbtSerializer; use function count; diff --git a/src/network/mcpe/PacketBatch.php b/src/network/mcpe/protocol/serializer/PacketBatch.php similarity index 94% rename from src/network/mcpe/PacketBatch.php rename to src/network/mcpe/protocol/serializer/PacketBatch.php index c2b1458797..9dbc6b2577 100644 --- a/src/network/mcpe/PacketBatch.php +++ b/src/network/mcpe/protocol/serializer/PacketBatch.php @@ -21,11 +21,10 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe; +namespace pocketmine\network\mcpe\protocol\serializer; use pocketmine\network\mcpe\protocol\Packet; use pocketmine\network\mcpe\protocol\PacketPool; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; class PacketBatch extends NetworkBinaryStream{ diff --git a/src/network/mcpe/protocol/types/CacheableNbt.php b/src/network/mcpe/protocol/types/CacheableNbt.php index 43439500e3..073c40c1d4 100644 --- a/src/network/mcpe/protocol/types/CacheableNbt.php +++ b/src/network/mcpe/protocol/types/CacheableNbt.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol\types; use pocketmine\nbt\tag\Tag; use pocketmine\nbt\TreeRoot; -use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; +use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; /** * @phpstan-template TTagType of Tag diff --git a/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php b/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php index ae8ffe5620..9043ee1bf3 100644 --- a/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; final class BlockPosMetadataProperty implements MetadataProperty{ diff --git a/src/network/mcpe/protocol/types/entity/ByteMetadataProperty.php b/src/network/mcpe/protocol/types/entity/ByteMetadataProperty.php index 1945b316d4..c85d818120 100644 --- a/src/network/mcpe/protocol/types/entity/ByteMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/ByteMetadataProperty.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; final class ByteMetadataProperty implements MetadataProperty{ use IntegerishMetadataProperty; diff --git a/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php b/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php index 055724e739..4ddbdc8f26 100644 --- a/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php @@ -27,8 +27,8 @@ use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\protocol\PacketDecodeException; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; -use pocketmine\network\mcpe\serializer\NetworkNbtSerializer; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; final class CompoundTagMetadataProperty implements MetadataProperty{ /** @var CompoundTag */ diff --git a/src/network/mcpe/protocol/types/entity/FloatMetadataProperty.php b/src/network/mcpe/protocol/types/entity/FloatMetadataProperty.php index afe8705cb2..fe4b43ba02 100644 --- a/src/network/mcpe/protocol/types/entity/FloatMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/FloatMetadataProperty.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; final class FloatMetadataProperty implements MetadataProperty{ diff --git a/src/network/mcpe/protocol/types/entity/IntMetadataProperty.php b/src/network/mcpe/protocol/types/entity/IntMetadataProperty.php index 1bdcbb888f..da4ec2d1dc 100644 --- a/src/network/mcpe/protocol/types/entity/IntMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/IntMetadataProperty.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; final class IntMetadataProperty implements MetadataProperty{ use IntegerishMetadataProperty; diff --git a/src/network/mcpe/protocol/types/entity/LongMetadataProperty.php b/src/network/mcpe/protocol/types/entity/LongMetadataProperty.php index 463014d5aa..685670d606 100644 --- a/src/network/mcpe/protocol/types/entity/LongMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/LongMetadataProperty.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use const PHP_INT_MAX; use const PHP_INT_MIN; diff --git a/src/network/mcpe/protocol/types/entity/MetadataProperty.php b/src/network/mcpe/protocol/types/entity/MetadataProperty.php index 9a920d70b4..8310732535 100644 --- a/src/network/mcpe/protocol/types/entity/MetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/MetadataProperty.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; interface MetadataProperty{ diff --git a/src/network/mcpe/protocol/types/entity/ShortMetadataProperty.php b/src/network/mcpe/protocol/types/entity/ShortMetadataProperty.php index ed435d748a..51ff0f33da 100644 --- a/src/network/mcpe/protocol/types/entity/ShortMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/ShortMetadataProperty.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; final class ShortMetadataProperty implements MetadataProperty{ use IntegerishMetadataProperty; diff --git a/src/network/mcpe/protocol/types/entity/StringMetadataProperty.php b/src/network/mcpe/protocol/types/entity/StringMetadataProperty.php index 9c8ca620fd..0a16ad056e 100644 --- a/src/network/mcpe/protocol/types/entity/StringMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/StringMetadataProperty.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; final class StringMetadataProperty implements MetadataProperty{ /** @var string */ diff --git a/src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php b/src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php index bc4ec5a7c9..ffe2843884 100644 --- a/src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class Vec3MetadataProperty implements MetadataProperty{ /** @var Vector3 */ diff --git a/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php b/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php index fed3737c5c..a0a588e904 100644 --- a/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; use pocketmine\network\mcpe\protocol\PacketDecodeException; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use function count; class MismatchTransactionData extends TransactionData{ diff --git a/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php b/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php index 5312876054..4ffa11b868 100644 --- a/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php +++ b/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\network\mcpe\protocol\PacketDecodeException; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; class NetworkInventoryAction{ diff --git a/src/network/mcpe/protocol/types/inventory/NormalTransactionData.php b/src/network/mcpe/protocol/types/inventory/NormalTransactionData.php index ea889f9793..761fc97ed1 100644 --- a/src/network/mcpe/protocol/types/inventory/NormalTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/NormalTransactionData.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class NormalTransactionData extends TransactionData{ diff --git a/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php b/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php index 5b399b0541..2cb2ccf037 100644 --- a/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ReleaseItemTransactionData extends TransactionData{ public const ACTION_RELEASE = 0; //bow shoot diff --git a/src/network/mcpe/protocol/types/inventory/TransactionData.php b/src/network/mcpe/protocol/types/inventory/TransactionData.php index 34dac5d594..35936bf092 100644 --- a/src/network/mcpe/protocol/types/inventory/TransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/TransactionData.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\network\mcpe\protocol\PacketDecodeException; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryDataException; use function count; diff --git a/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php b/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php index 005fc14096..17e56701b7 100644 --- a/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class UseItemOnEntityTransactionData extends TransactionData{ public const ACTION_INTERACT = 0; diff --git a/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php b/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php index 71d832b1ee..a8e47bd599 100644 --- a/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class UseItemTransactionData extends TransactionData{ public const ACTION_CLICK_BLOCK = 0; diff --git a/src/network/mcpe/protocol/types/recipe/FurnaceRecipe.php b/src/network/mcpe/protocol/types/recipe/FurnaceRecipe.php index 163e54668d..e81ab935af 100644 --- a/src/network/mcpe/protocol/types/recipe/FurnaceRecipe.php +++ b/src/network/mcpe/protocol/types/recipe/FurnaceRecipe.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\recipe; use pocketmine\network\mcpe\protocol\CraftingDataPacket; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; final class FurnaceRecipe extends RecipeWithTypeId{ diff --git a/src/network/mcpe/protocol/types/recipe/MultiRecipe.php b/src/network/mcpe/protocol/types/recipe/MultiRecipe.php index 9fc939c0aa..559a266178 100644 --- a/src/network/mcpe/protocol/types/recipe/MultiRecipe.php +++ b/src/network/mcpe/protocol/types/recipe/MultiRecipe.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\recipe; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\utils\UUID; final class MultiRecipe extends RecipeWithTypeId{ diff --git a/src/network/mcpe/protocol/types/recipe/RecipeWithTypeId.php b/src/network/mcpe/protocol/types/recipe/RecipeWithTypeId.php index 9b61c0c146..1960aead47 100644 --- a/src/network/mcpe/protocol/types/recipe/RecipeWithTypeId.php +++ b/src/network/mcpe/protocol/types/recipe/RecipeWithTypeId.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\recipe; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; abstract class RecipeWithTypeId{ /** @var int */ diff --git a/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php b/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php index b18e822462..00c9360776 100644 --- a/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php +++ b/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\recipe; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\UUID; use function count; diff --git a/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php b/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php index d91d1f4e6e..f6e54c0a09 100644 --- a/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php +++ b/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\recipe; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; use pocketmine\utils\UUID; use function count; diff --git a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php index 3877908147..4be6018e5d 100644 --- a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php +++ b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\resourcepacks; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ResourcePackInfoEntry{ diff --git a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php index 85ebfd92d3..02fb9b4b8a 100644 --- a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php +++ b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\resourcepacks; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class ResourcePackStackEntry{ diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index a388bfc279..c2a1d0fdf6 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe\serializer; use pocketmine\block\tile\Spawnable; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\utils\BinaryStream; use pocketmine\world\format\Chunk; use function count; diff --git a/tests/phpunit/network/mcpe/protocol/TestPacket.php b/tests/phpunit/network/mcpe/protocol/TestPacket.php index 0a68aea30f..ede9c0bf5e 100644 --- a/tests/phpunit/network/mcpe/protocol/TestPacket.php +++ b/tests/phpunit/network/mcpe/protocol/TestPacket.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; -use pocketmine\network\mcpe\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; class TestPacket extends DataPacket{ public const NETWORK_ID = 1023; From fe258740e385bbee62221c4820e101d35b0b3741 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 28 Apr 2020 14:31:56 +0100 Subject: [PATCH 1477/3224] SingletonTrait: added setInstance() --- src/utils/SingletonTrait.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/utils/SingletonTrait.php b/src/utils/SingletonTrait.php index dfffe0b672..99e30e41cc 100644 --- a/src/utils/SingletonTrait.php +++ b/src/utils/SingletonTrait.php @@ -38,6 +38,10 @@ trait SingletonTrait{ return self::$instance; } + public static function setInstance(self $instance) : void{ + self::$instance = $instance; + } + public static function reset() : void{ self::$instance = null; } From d9e4783b244d5142ff2a0f0527b65e4fd3416aa3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 28 Apr 2020 14:47:01 +0100 Subject: [PATCH 1478/3224] start making network compressors dynamic this will facilitate future multi version support where compression types are different between versions --- src/Server.php | 28 +++---- src/crafting/CraftingManager.php | 4 +- src/network/mcpe/ChunkRequestTask.php | 10 +-- src/network/mcpe/NetworkSession.php | 4 +- .../mcpe/compression/CompressBatchTask.php | 10 +-- src/network/mcpe/compression/Zlib.php | 59 -------------- .../mcpe/compression/ZlibCompressor.php | 77 +++++++++++++++++++ tests/phpstan/configs/phpstan-bugs.neon | 5 ++ 8 files changed, 110 insertions(+), 87 deletions(-) delete mode 100644 src/network/mcpe/compression/Zlib.php create mode 100644 src/network/mcpe/compression/ZlibCompressor.php diff --git a/src/Server.php b/src/Server.php index 9492aa88f0..5b590ccb1a 100644 --- a/src/Server.php +++ b/src/Server.php @@ -48,7 +48,7 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\compression\CompressBatchPromise; use pocketmine\network\mcpe\compression\CompressBatchTask; -use pocketmine\network\mcpe\compression\Zlib as ZlibNetworkCompression; +use pocketmine\network\mcpe\compression\ZlibCompressor as ZlibNetworkCompression; use pocketmine\network\mcpe\encryption\NetworkCipher; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; @@ -912,17 +912,18 @@ class Server{ $this->asyncPool = new AsyncPool($poolSize, max(-1, (int) $this->getProperty("memory.async-worker-hard-limit", 256)), $this->autoloader, $this->logger); + $netCompressionThreshold = -1; if($this->getProperty("network.batch-threshold", 256) >= 0){ - ZlibNetworkCompression::$THRESHOLD = (int) $this->getProperty("network.batch-threshold", 256); - }else{ - ZlibNetworkCompression::$THRESHOLD = -1; + $netCompressionThreshold = (int) $this->getProperty("network.batch-threshold", 256); } - ZlibNetworkCompression::$LEVEL = $this->getProperty("network.compression-level", 7); - if(ZlibNetworkCompression::$LEVEL < 1 or ZlibNetworkCompression::$LEVEL > 9){ - $this->logger->warning("Invalid network compression level " . ZlibNetworkCompression::$LEVEL . " set, setting to default 7"); - ZlibNetworkCompression::$LEVEL = 7; + $netCompressionLevel = $this->getProperty("network.compression-level", 7); + if($netCompressionLevel < 1 or $netCompressionLevel > 9){ + $this->logger->warning("Invalid network compression level $netCompressionLevel set, setting to default 7"); + $netCompressionLevel = 7; } + ZlibNetworkCompression::setInstance(new ZlibNetworkCompression($netCompressionLevel, $netCompressionThreshold, ZlibNetworkCompression::DEFAULT_MAX_DECOMPRESSION_SIZE)); + $this->networkCompressionAsync = (bool) $this->getProperty("network.async-compression", true); NetworkCipher::$ENABLED = (bool) $this->getProperty("network.enable-encryption", true); @@ -1251,7 +1252,7 @@ class Server{ $stream = PacketBatch::fromPackets(...$ev->getPackets()); - if(ZlibNetworkCompression::$THRESHOLD < 0 or strlen($stream->getBuffer()) < ZlibNetworkCompression::$THRESHOLD){ + if(!ZlibNetworkCompression::getInstance()->willCompress($stream->getBuffer())){ foreach($recipients as $target){ foreach($ev->getPackets() as $pk){ $target->addToSendBuffer($pk); @@ -1274,19 +1275,18 @@ class Server{ try{ Timings::$playerNetworkSendCompressTimer->startTiming(); - $compressionLevel = ZlibNetworkCompression::$LEVEL; + $compressor = ZlibNetworkCompression::getInstance(); $buffer = $stream->getBuffer(); - if(ZlibNetworkCompression::$THRESHOLD < 0 or strlen($buffer) < ZlibNetworkCompression::$THRESHOLD){ - $compressionLevel = 0; //Do not compress packets under the threshold + if(!$compressor->willCompress($buffer)){ $forceSync = true; } $promise = new CompressBatchPromise(); if(!$forceSync and $this->networkCompressionAsync){ - $task = new CompressBatchTask($buffer, $compressionLevel, $promise); + $task = new CompressBatchTask($buffer, $promise, $compressor); $this->asyncPool->submitTask($task); }else{ - $promise->resolve(ZlibNetworkCompression::compress($buffer, $compressionLevel)); + $promise->resolve($compressor->compress($buffer)); } return $promise; diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index 2301783cf2..4abb8bc9b0 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -25,7 +25,7 @@ namespace pocketmine\crafting; use pocketmine\item\Item; use pocketmine\network\mcpe\compression\CompressBatchPromise; -use pocketmine\network\mcpe\compression\Zlib; +use pocketmine\network\mcpe\compression\ZlibCompressor; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\protocol\CraftingDataPacket; @@ -165,7 +165,7 @@ class CraftingManager{ } $this->craftingDataCache = new CompressBatchPromise(); - $this->craftingDataCache->resolve(Zlib::compress(PacketBatch::fromPackets($pk)->getBuffer())); + $this->craftingDataCache->resolve(ZlibCompressor::getInstance()->compress(PacketBatch::fromPackets($pk)->getBuffer())); Timings::$craftingDataCacheRebuildTimer->stopTiming(); } diff --git a/src/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php index 75274e177a..25e10bda97 100644 --- a/src/network/mcpe/ChunkRequestTask.php +++ b/src/network/mcpe/ChunkRequestTask.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; use pocketmine\network\mcpe\compression\CompressBatchPromise; -use pocketmine\network\mcpe\compression\Zlib; +use pocketmine\network\mcpe\compression\ZlibCompressor; use pocketmine\network\mcpe\protocol\LevelChunkPacket; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\serializer\ChunkSerializer; @@ -43,8 +43,8 @@ class ChunkRequestTask extends AsyncTask{ /** @var int */ protected $chunkZ; - /** @var int */ - protected $compressionLevel; + /** @var ZlibCompressor */ + protected $compressor; /** @var string */ private $tiles = ""; @@ -53,7 +53,7 @@ class ChunkRequestTask extends AsyncTask{ * @phpstan-param (\Closure() : void)|null $onError */ public function __construct(int $chunkX, int $chunkZ, Chunk $chunk, CompressBatchPromise $promise, ?\Closure $onError = null){ - $this->compressionLevel = Zlib::$LEVEL; + $this->compressor = ZlibCompressor::getInstance(); //TODO: this should be injectable $this->chunk = FastChunkSerializer::serializeWithoutLight($chunk); $this->chunkX = $chunkX; @@ -68,7 +68,7 @@ class ChunkRequestTask extends AsyncTask{ $chunk = FastChunkSerializer::deserialize($this->chunk); $subCount = ChunkSerializer::getSubChunkCount($chunk); $payload = ChunkSerializer::serialize($chunk, $this->tiles); - $this->setResult(Zlib::compress(PacketBatch::fromPackets(LevelChunkPacket::withoutCache($this->chunkX, $this->chunkZ, $subCount, $payload))->getBuffer(), $this->compressionLevel)); + $this->setResult($this->compressor->compress(PacketBatch::fromPackets(LevelChunkPacket::withoutCache($this->chunkX, $this->chunkZ, $subCount, $payload))->getBuffer())); } public function onError() : void{ diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 5b4a069555..dec765ac1f 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -36,7 +36,7 @@ use pocketmine\math\Vector3; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\compression\CompressBatchPromise; use pocketmine\network\mcpe\compression\DecompressionException; -use pocketmine\network\mcpe\compression\Zlib; +use pocketmine\network\mcpe\compression\ZlibCompressor; use pocketmine\network\mcpe\convert\SkinAdapterSingleton; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\encryption\DecryptionException; @@ -283,7 +283,7 @@ class NetworkSession{ Timings::$playerNetworkReceiveDecompressTimer->startTiming(); try{ - $stream = new PacketBatch(Zlib::decompress($payload)); + $stream = new PacketBatch(ZlibCompressor::getInstance()->decompress($payload)); //TODO: make this dynamic }catch(DecompressionException $e){ $this->logger->debug("Failed to decompress packet: " . base64_encode($payload)); //TODO: this isn't incompatible game version if we already established protocol version diff --git a/src/network/mcpe/compression/CompressBatchTask.php b/src/network/mcpe/compression/CompressBatchTask.php index e4012d8e0a..05ce2ce2d3 100644 --- a/src/network/mcpe/compression/CompressBatchTask.php +++ b/src/network/mcpe/compression/CompressBatchTask.php @@ -29,19 +29,19 @@ class CompressBatchTask extends AsyncTask{ private const TLS_KEY_PROMISE = "promise"; - /** @var int */ - private $level; /** @var string */ private $data; + /** @var ZlibCompressor */ + private $compressor; - public function __construct(string $data, int $compressionLevel, CompressBatchPromise $promise){ + public function __construct(string $data, CompressBatchPromise $promise, ZlibCompressor $compressor){ $this->data = $data; - $this->level = $compressionLevel; + $this->compressor = $compressor; $this->storeLocal(self::TLS_KEY_PROMISE, $promise); } public function onRun() : void{ - $this->setResult(Zlib::compress($this->data, $this->level)); + $this->setResult($this->compressor->compress($this->data)); } public function onCompletion() : void{ diff --git a/src/network/mcpe/compression/Zlib.php b/src/network/mcpe/compression/Zlib.php deleted file mode 100644 index 867996f15d..0000000000 --- a/src/network/mcpe/compression/Zlib.php +++ /dev/null @@ -1,59 +0,0 @@ -level = $level; + $this->threshold = $minCompressionSize; + $this->maxDecompressionSize = $maxDecompressionSize; + } + + public function willCompress(string $data) : bool{ + return $this->threshold > -1 and strlen($data) >= $this->threshold; + } + + /** + * @throws DecompressionException + */ + public function decompress(string $payload) : string{ + $result = @zlib_decode($payload, $this->maxDecompressionSize); + if($result === false){ + throw new DecompressionException("Failed to decompress data"); + } + return $result; + } + + public function compress(string $payload) : string{ + return zlib_encode($payload, ZLIB_ENCODING_DEFLATE, $this->willCompress($payload) ? $this->level : 0); + } +} diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index fcfec4efa8..75cc5b1fce 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -70,6 +70,11 @@ parameters: count: 1 path: ../../../src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php + - + message: "#^Class pocketmine\\\\network\\\\mcpe\\\\compression\\\\ZlibCompressor constructor invoked with 0 parameters, 3 required\\.$#" + count: 1 + path: ../../../src/network/mcpe/compression/ZlibCompressor.php + - message: "#^Strict comparison using \\!\\=\\= between string and false will always evaluate to true\\.$#" count: 1 From 3be9548b1ea240cdf352fa08a603cc3729f88682 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 28 Apr 2020 16:21:18 +0100 Subject: [PATCH 1479/3224] net: compressors are now fully dynamic (or at least the potential to be) the compressor used by RakLibInterface when opening a session is still hardcoded, but that's because we have no way to select the correct compressor at that point in the login sequence, since we aren't propagating the protocol information up from RakLib right now. --- src/Server.php | 38 ++++++++++++------- src/crafting/CraftingManager.php | 32 ++++++++-------- src/network/mcpe/ChunkCache.php | 19 ++++++++-- src/network/mcpe/ChunkRequestTask.php | 8 ++-- src/network/mcpe/NetworkSession.php | 17 ++++++--- .../mcpe/compression/CompressBatchTask.php | 4 +- src/network/mcpe/compression/Compressor.php | 36 ++++++++++++++++++ .../mcpe/compression/ZlibCompressor.php | 2 +- .../mcpe/handler/PreSpawnPacketHandler.php | 2 +- src/network/mcpe/raklib/RakLibInterface.php | 10 ++++- 10 files changed, 122 insertions(+), 46 deletions(-) create mode 100644 src/network/mcpe/compression/Compressor.php diff --git a/src/Server.php b/src/Server.php index 5b590ccb1a..3e4e713974 100644 --- a/src/Server.php +++ b/src/Server.php @@ -48,7 +48,8 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\compression\CompressBatchPromise; use pocketmine\network\mcpe\compression\CompressBatchTask; -use pocketmine\network\mcpe\compression\ZlibCompressor as ZlibNetworkCompression; +use pocketmine\network\mcpe\compression\Compressor; +use pocketmine\network\mcpe\compression\ZlibCompressor; use pocketmine\network\mcpe\encryption\NetworkCipher; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; @@ -922,7 +923,7 @@ class Server{ $this->logger->warning("Invalid network compression level $netCompressionLevel set, setting to default 7"); $netCompressionLevel = 7; } - ZlibNetworkCompression::setInstance(new ZlibNetworkCompression($netCompressionLevel, $netCompressionThreshold, ZlibNetworkCompression::DEFAULT_MAX_DECOMPRESSION_SIZE)); + ZlibCompressor::setInstance(new ZlibCompressor($netCompressionLevel, $netCompressionThreshold, ZlibCompressor::DEFAULT_MAX_DECOMPRESSION_SIZE)); $this->networkCompressionAsync = (bool) $this->getProperty("network.async-compression", true); @@ -1252,16 +1253,28 @@ class Server{ $stream = PacketBatch::fromPackets(...$ev->getPackets()); - if(!ZlibNetworkCompression::getInstance()->willCompress($stream->getBuffer())){ - foreach($recipients as $target){ - foreach($ev->getPackets() as $pk){ - $target->addToSendBuffer($pk); + $compressors = []; + $compressorTargets = []; + foreach($recipients as $recipient){ + $compressor = $recipient->getCompressor(); + $compressorId = spl_object_id($compressor); + //TODO: different compressors might be compatible, it might not be necessary to split them up by object + $compressors[$compressorId] = $compressor; + $compressorTargets[$compressorId][] = $recipient; + } + + foreach($compressors as $compressorId => $compressor){ + if(!$compressor->willCompress($stream->getBuffer())){ + foreach($compressorTargets[$compressorId] as $target){ + foreach($ev->getPackets() as $pk){ + $target->addToSendBuffer($pk); + } + } + }else{ + $promise = $this->prepareBatch($stream, $compressor); + foreach($compressorTargets[$compressorId] as $target){ + $target->queueCompressed($promise); } - } - }else{ - $promise = $this->prepareBatch($stream); - foreach($recipients as $target){ - $target->queueCompressed($promise); } } @@ -1271,11 +1284,10 @@ class Server{ /** * Broadcasts a list of packets in a batch to a list of players */ - public function prepareBatch(PacketBatch $stream, bool $forceSync = false) : CompressBatchPromise{ + public function prepareBatch(PacketBatch $stream, Compressor $compressor, bool $forceSync = false) : CompressBatchPromise{ try{ Timings::$playerNetworkSendCompressTimer->startTiming(); - $compressor = ZlibNetworkCompression::getInstance(); $buffer = $stream->getBuffer(); if(!$compressor->willCompress($buffer)){ $forceSync = true; diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index 4abb8bc9b0..8fec8b9228 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -25,7 +25,7 @@ namespace pocketmine\crafting; use pocketmine\item\Item; use pocketmine\network\mcpe\compression\CompressBatchPromise; -use pocketmine\network\mcpe\compression\ZlibCompressor; +use pocketmine\network\mcpe\compression\Compressor; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\protocol\CraftingDataPacket; @@ -41,6 +41,7 @@ use function array_map; use function file_get_contents; use function json_decode; use function json_encode; +use function spl_object_id; use function str_repeat; use function usort; use const DIRECTORY_SEPARATOR; @@ -53,8 +54,8 @@ class CraftingManager{ /** @var FurnaceRecipe[] */ protected $furnaceRecipes = []; - /** @var CompressBatchPromise|null */ - private $craftingDataCache; + /** @var CompressBatchPromise[] */ + private $craftingDataCaches = []; public function __construct(){ $this->init(); @@ -98,14 +99,12 @@ class CraftingManager{ break; } } - - $this->buildCraftingDataCache(); } /** * Rebuilds the cached CraftingDataPacket. */ - public function buildCraftingDataCache() : void{ + private function buildCraftingDataCache(Compressor $compressor) : CompressBatchPromise{ Timings::$craftingDataCacheRebuildTimer->startTiming(); $pk = new CraftingDataPacket(); $pk->cleanRecipes = true; @@ -164,21 +163,24 @@ class CraftingManager{ ); } - $this->craftingDataCache = new CompressBatchPromise(); - $this->craftingDataCache->resolve(ZlibCompressor::getInstance()->compress(PacketBatch::fromPackets($pk)->getBuffer())); + $promise = new CompressBatchPromise(); + $promise->resolve($compressor->compress(PacketBatch::fromPackets($pk)->getBuffer())); Timings::$craftingDataCacheRebuildTimer->stopTiming(); + return $promise; } /** * Returns a pre-compressed CraftingDataPacket for sending to players. Rebuilds the cache if it is not found. */ - public function getCraftingDataPacket() : CompressBatchPromise{ - if($this->craftingDataCache === null){ - $this->buildCraftingDataCache(); + public function getCraftingDataPacket(Compressor $compressor) : CompressBatchPromise{ + $compressorId = spl_object_id($compressor); + + if(!isset($this->craftingDataCaches[$compressorId])){ + $this->craftingDataCaches[$compressorId] = $this->buildCraftingDataCache($compressor); } - return $this->craftingDataCache; + return $this->craftingDataCaches[$compressorId]; } /** @@ -253,19 +255,19 @@ class CraftingManager{ public function registerShapedRecipe(ShapedRecipe $recipe) : void{ $this->shapedRecipes[self::hashOutputs($recipe->getResults())][] = $recipe; - $this->craftingDataCache = null; + $this->craftingDataCaches = []; } public function registerShapelessRecipe(ShapelessRecipe $recipe) : void{ $this->shapelessRecipes[self::hashOutputs($recipe->getResults())][] = $recipe; - $this->craftingDataCache = null; + $this->craftingDataCaches = []; } public function registerFurnaceRecipe(FurnaceRecipe $recipe) : void{ $input = $recipe->getInput(); $this->furnaceRecipes[$input->getId() . ":" . ($input->hasAnyDamageValue() ? "?" : $input->getMeta())] = $recipe; - $this->craftingDataCache = null; + $this->craftingDataCaches = []; } /** diff --git a/src/network/mcpe/ChunkCache.php b/src/network/mcpe/ChunkCache.php index 67d5b89115..399da5c29a 100644 --- a/src/network/mcpe/ChunkCache.php +++ b/src/network/mcpe/ChunkCache.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe; use pocketmine\math\Vector3; use pocketmine\network\mcpe\compression\CompressBatchPromise; +use pocketmine\network\mcpe\compression\Compressor; use pocketmine\world\ChunkListener; use pocketmine\world\ChunkListenerNoOpTrait; use pocketmine\world\format\Chunk; @@ -39,7 +40,7 @@ use function strlen; * TODO: this needs a hook for world unloading */ class ChunkCache implements ChunkListener{ - /** @var self[] */ + /** @var self[][] */ private static $instances = []; /** @@ -47,12 +48,20 @@ class ChunkCache implements ChunkListener{ * * @return ChunkCache */ - public static function getInstance(World $world) : self{ - return self::$instances[spl_object_id($world)] ?? (self::$instances[spl_object_id($world)] = new self($world)); + public static function getInstance(World $world, Compressor $compressor) : self{ + $worldId = spl_object_id($world); + $compressorId = spl_object_id($compressor); + if(!isset(self::$instances[$worldId][$compressorId])){ + \GlobalLogger::get()->debug("Created new chunk packet cache (world#$worldId, compressor#$compressorId)"); + self::$instances[$worldId][$compressorId] = new self($world, $compressor); + } + return self::$instances[$worldId][$compressorId]; } /** @var World */ private $world; + /** @var Compressor */ + private $compressor; /** @var CompressBatchPromise[] */ private $caches = []; @@ -62,8 +71,9 @@ class ChunkCache implements ChunkListener{ /** @var int */ private $misses = 0; - private function __construct(World $world){ + private function __construct(World $world, Compressor $compressor){ $this->world = $world; + $this->compressor = $compressor; } /** @@ -92,6 +102,7 @@ class ChunkCache implements ChunkListener{ $chunkZ, $this->world->getChunk($chunkX, $chunkZ), $this->caches[$chunkHash], + $this->compressor, function() use ($chunkX, $chunkZ) : void{ $this->world->getLogger()->error("Failed preparing chunk $chunkX $chunkZ, retrying"); diff --git a/src/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php index 25e10bda97..a8b135d97b 100644 --- a/src/network/mcpe/ChunkRequestTask.php +++ b/src/network/mcpe/ChunkRequestTask.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; use pocketmine\network\mcpe\compression\CompressBatchPromise; -use pocketmine\network\mcpe\compression\ZlibCompressor; +use pocketmine\network\mcpe\compression\Compressor; use pocketmine\network\mcpe\protocol\LevelChunkPacket; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\serializer\ChunkSerializer; @@ -43,7 +43,7 @@ class ChunkRequestTask extends AsyncTask{ /** @var int */ protected $chunkZ; - /** @var ZlibCompressor */ + /** @var Compressor */ protected $compressor; /** @var string */ @@ -52,8 +52,8 @@ class ChunkRequestTask extends AsyncTask{ /** * @phpstan-param (\Closure() : void)|null $onError */ - public function __construct(int $chunkX, int $chunkZ, Chunk $chunk, CompressBatchPromise $promise, ?\Closure $onError = null){ - $this->compressor = ZlibCompressor::getInstance(); //TODO: this should be injectable + public function __construct(int $chunkX, int $chunkZ, Chunk $chunk, CompressBatchPromise $promise, Compressor $compressor, ?\Closure $onError = null){ + $this->compressor = $compressor; $this->chunk = FastChunkSerializer::serializeWithoutLight($chunk); $this->chunkX = $chunkX; diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index dec765ac1f..aafdf7e39d 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -35,8 +35,8 @@ use pocketmine\form\Form; use pocketmine\math\Vector3; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\compression\CompressBatchPromise; +use pocketmine\network\mcpe\compression\Compressor; use pocketmine\network\mcpe\compression\DecompressionException; -use pocketmine\network\mcpe\compression\ZlibCompressor; use pocketmine\network\mcpe\convert\SkinAdapterSingleton; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\encryption\DecryptionException; @@ -147,6 +147,8 @@ class NetworkSession{ /** @var \SplQueue|CompressBatchPromise[] */ private $compressedQueue; + /** @var Compressor */ + private $compressor; /** @var InventoryManager|null */ private $invManager = null; @@ -154,7 +156,7 @@ class NetworkSession{ /** @var PacketSender */ private $sender; - public function __construct(Server $server, NetworkSessionManager $manager, PacketSender $sender, string $ip, int $port){ + public function __construct(Server $server, NetworkSessionManager $manager, PacketSender $sender, Compressor $compressor, string $ip, int $port){ $this->server = $server; $this->manager = $manager; $this->sender = $sender; @@ -164,6 +166,7 @@ class NetworkSession{ $this->logger = new \PrefixedLogger($this->server->getLogger(), $this->getLogPrefix()); $this->compressedQueue = new \SplQueue(); + $this->compressor = $compressor; $this->connectTime = time(); @@ -283,7 +286,7 @@ class NetworkSession{ Timings::$playerNetworkReceiveDecompressTimer->startTiming(); try{ - $stream = new PacketBatch(ZlibCompressor::getInstance()->decompress($payload)); //TODO: make this dynamic + $stream = new PacketBatch($this->compressor->decompress($payload)); }catch(DecompressionException $e){ $this->logger->debug("Failed to decompress packet: " . base64_encode($payload)); //TODO: this isn't incompatible game version if we already established protocol version @@ -395,12 +398,16 @@ class NetworkSession{ private function flushSendBuffer(bool $immediate = false) : void{ if($this->sendBuffer !== null){ - $promise = $this->server->prepareBatch($this->sendBuffer, $immediate); + $promise = $this->server->prepareBatch($this->sendBuffer, $this->compressor, $immediate); $this->sendBuffer = null; $this->queueCompressed($promise, $immediate); } } + public function getCompressor() : Compressor{ + return $this->compressor; + } + public function queueCompressed(CompressBatchPromise $payload, bool $immediate = false) : void{ $this->flushSendBuffer($immediate); //Maintain ordering if possible if($immediate){ @@ -757,7 +764,7 @@ class NetworkSession{ $world = $this->player->getLocation()->getWorld(); assert($world !== null); - ChunkCache::getInstance($world)->request($chunkX, $chunkZ)->onResolve( + ChunkCache::getInstance($world, $this->compressor)->request($chunkX, $chunkZ)->onResolve( //this callback may be called synchronously or asynchronously, depending on whether the promise is resolved yet function(CompressBatchPromise $promise) use ($world, $chunkX, $chunkZ, $onCompletion) : void{ diff --git a/src/network/mcpe/compression/CompressBatchTask.php b/src/network/mcpe/compression/CompressBatchTask.php index 05ce2ce2d3..d13546b3a6 100644 --- a/src/network/mcpe/compression/CompressBatchTask.php +++ b/src/network/mcpe/compression/CompressBatchTask.php @@ -31,10 +31,10 @@ class CompressBatchTask extends AsyncTask{ /** @var string */ private $data; - /** @var ZlibCompressor */ + /** @var Compressor */ private $compressor; - public function __construct(string $data, CompressBatchPromise $promise, ZlibCompressor $compressor){ + public function __construct(string $data, CompressBatchPromise $promise, Compressor $compressor){ $this->data = $data; $this->compressor = $compressor; $this->storeLocal(self::TLS_KEY_PROMISE, $promise); diff --git a/src/network/mcpe/compression/Compressor.php b/src/network/mcpe/compression/Compressor.php new file mode 100644 index 0000000000..bbc8fac4f1 --- /dev/null +++ b/src/network/mcpe/compression/Compressor.php @@ -0,0 +1,36 @@ +session->getInvManager()->syncAll(); $this->session->getInvManager()->syncCreative(); $this->session->getInvManager()->syncSelectedHotbarSlot(); - $this->session->queueCompressed($this->server->getCraftingManager()->getCraftingDataPacket()); + $this->session->queueCompressed($this->server->getCraftingManager()->getCraftingDataPacket($this->session->getCompressor())); $this->session->syncPlayerList(); } diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 0906390d14..8321e57686 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe\raklib; use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\BadPacketException; +use pocketmine\network\mcpe\compression\ZlibCompressor; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\Network; @@ -152,7 +153,14 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ } public function openSession(int $sessionId, string $address, int $port, int $clientID) : void{ - $session = new NetworkSession($this->server, $this->network->getSessionManager(), new RakLibPacketSender($sessionId, $this), $address, $port); + $session = new NetworkSession( + $this->server, + $this->network->getSessionManager(), + new RakLibPacketSender($sessionId, $this), + ZlibCompressor::getInstance(), //TODO: this shouldn't be hardcoded, but we might need the RakNet protocol version to select it + $address, + $port + ); $this->sessions[$sessionId] = $session; } From 81044d6aea90379ea7f16cfe9bc41cb644a50f64 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 28 Apr 2020 16:30:29 +0100 Subject: [PATCH 1480/3224] updated to latest RakLib --- composer.lock | 8 ++++---- src/network/mcpe/raklib/RakLibServer.php | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/composer.lock b/composer.lock index 7dfd59df07..8d2da2acbe 100644 --- a/composer.lock +++ b/composer.lock @@ -618,12 +618,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "832ee61c53df9df90ec12b7d57dfd97c022f5382" + "reference": "84c9289542544fb70e611fea0ed3854d4b52bdde" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/832ee61c53df9df90ec12b7d57dfd97c022f5382", - "reference": "832ee61c53df9df90ec12b7d57dfd97c022f5382", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/84c9289542544fb70e611fea0ed3854d4b52bdde", + "reference": "84c9289542544fb70e611fea0ed3854d4b52bdde", "shasum": "" }, "require": { @@ -649,7 +649,7 @@ "GPL-3.0" ], "description": "A RakNet server implementation written in PHP", - "time": "2020-04-08T18:43:23+00:00" + "time": "2020-04-28T11:10:59+00:00" }, { "name": "pocketmine/snooze", diff --git a/src/network/mcpe/raklib/RakLibServer.php b/src/network/mcpe/raklib/RakLibServer.php index 63a26da0f8..7543b66fcd 100644 --- a/src/network/mcpe/raklib/RakLibServer.php +++ b/src/network/mcpe/raklib/RakLibServer.php @@ -30,6 +30,7 @@ use raklib\RakLib; use raklib\server\ipc\RakLibToUserThreadMessageSender; use raklib\server\ipc\UserToRakLibThreadMessageReceiver; use raklib\server\Server; +use raklib\server\SimpleProtocolAcceptor; use raklib\utils\ExceptionTraceCleaner; use raklib\utils\InternetAddress; use function error_get_last; @@ -158,7 +159,7 @@ class RakLibServer extends Thread{ $this->logger, $socket, $this->maxMtuSize, - $this->protocolVersion, + new SimpleProtocolAcceptor($this->protocolVersion), new UserToRakLibThreadMessageReceiver(new PthreadsChannelReader($this->mainToThreadBuffer)), new RakLibToUserThreadMessageSender(new PthreadsChannelWriter($this->threadToMainBuffer, $this->mainThreadNotifier)), new ExceptionTraceCleaner($this->mainPath) From f9a587d40e8f425846317b38ac302c4563d75454 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 28 Apr 2020 17:27:38 +0100 Subject: [PATCH 1481/3224] imports cleanup --- src/Server.php | 3 +-- src/crafting/CraftingManager.php | 2 +- src/entity/Human.php | 2 +- src/item/ChorusFruit.php | 1 - src/item/FlintSteel.php | 1 - src/network/mcpe/convert/RuntimeBlockMapping.php | 2 +- src/network/mcpe/handler/InGamePacketHandler.php | 2 +- src/plugin/PluginManager.php | 1 + src/scheduler/AsyncTask.php | 1 + src/stats/SendUsageTask.php | 1 + src/thread/Thread.php | 1 + src/thread/Worker.php | 1 + src/utils/Internet.php | 1 + src/utils/Terminal.php | 1 + src/utils/TextFormat.php | 2 ++ src/utils/Timezone.php | 2 -- src/utils/Utils.php | 1 - 17 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/Server.php b/src/Server.php index 3e4e713974..71012b4e1f 100644 --- a/src/Server.php +++ b/src/Server.php @@ -52,9 +52,9 @@ use pocketmine\network\mcpe\compression\Compressor; use pocketmine\network\mcpe\compression\ZlibCompressor; use pocketmine\network\mcpe\encryption\NetworkCipher; use pocketmine\network\mcpe\NetworkSession; -use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\ProtocolInfo; +use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\raklib\RakLibInterface; use pocketmine\network\Network; use pocketmine\network\query\QueryHandler; @@ -113,7 +113,6 @@ use function get_class; use function getmypid; use function getopt; use function implode; -use function ini_get; use function ini_set; use function is_a; use function is_array; diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index 8fec8b9228..c97dc10f06 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -27,8 +27,8 @@ use pocketmine\item\Item; use pocketmine\network\mcpe\compression\CompressBatchPromise; use pocketmine\network\mcpe\compression\Compressor; use pocketmine\network\mcpe\convert\TypeConverter; -use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\protocol\CraftingDataPacket; +use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\protocol\types\recipe\FurnaceRecipe as ProtocolFurnaceRecipe; use pocketmine\network\mcpe\protocol\types\recipe\RecipeIngredient; diff --git a/src/entity/Human.php b/src/entity/Human.php index 54ef3de9cb..3b99ba8da7 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -23,12 +23,12 @@ declare(strict_types=1); namespace pocketmine\entity; +use pocketmine\block\inventory\EnderChestInventory; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\VanillaEffects; use pocketmine\entity\projectile\ProjectileSource; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\player\PlayerExhaustEvent; -use pocketmine\block\inventory\EnderChestInventory; use pocketmine\inventory\InventoryHolder; use pocketmine\inventory\PlayerInventory; use pocketmine\item\Consumable; diff --git a/src/item/ChorusFruit.php b/src/item/ChorusFruit.php index ac1e10188b..8ba82d2811 100644 --- a/src/item/ChorusFruit.php +++ b/src/item/ChorusFruit.php @@ -27,7 +27,6 @@ use pocketmine\block\Liquid; use pocketmine\entity\Living; use pocketmine\math\Vector3; use pocketmine\world\sound\EndermanTeleportSound; -use function assert; use function min; use function mt_rand; diff --git a/src/item/FlintSteel.php b/src/item/FlintSteel.php index def28d56e3..0ddac5cc2d 100644 --- a/src/item/FlintSteel.php +++ b/src/item/FlintSteel.php @@ -29,7 +29,6 @@ use pocketmine\block\VanillaBlocks; use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\world\sound\FlintSteelSound; -use function assert; class FlintSteel extends Tool{ diff --git a/src/network/mcpe/convert/RuntimeBlockMapping.php b/src/network/mcpe/convert/RuntimeBlockMapping.php index 83ff78d21d..0f0445251a 100644 --- a/src/network/mcpe/convert/RuntimeBlockMapping.php +++ b/src/network/mcpe/convert/RuntimeBlockMapping.php @@ -28,8 +28,8 @@ use pocketmine\data\bedrock\LegacyBlockIdToStringIdMap; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; -use pocketmine\network\mcpe\protocol\types\CacheableNbt; use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; +use pocketmine\network\mcpe\protocol\types\CacheableNbt; use pocketmine\utils\SingletonTrait; use function file_get_contents; use function getmypid; diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 766ff51366..29eee96ae5 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -71,6 +71,7 @@ use pocketmine\network\mcpe\protocol\PlayerHotbarPacket; use pocketmine\network\mcpe\protocol\PlayerInputPacket; use pocketmine\network\mcpe\protocol\PlayerSkinPacket; use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; +use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; use pocketmine\network\mcpe\protocol\ServerSettingsRequestPacket; use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; use pocketmine\network\mcpe\protocol\ShowCreditsPacket; @@ -84,7 +85,6 @@ use pocketmine\network\mcpe\protocol\types\inventory\NormalTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\UseItemOnEntityTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\UseItemTransactionData; -use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; use pocketmine\player\Player; use function array_push; use function base64_encode; diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 1d939bc3d4..ea193ed200 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -51,6 +51,7 @@ use function in_array; use function is_a; use function is_array; use function is_dir; +use function is_string; use function is_subclass_of; use function iterator_to_array; use function mkdir; diff --git a/src/scheduler/AsyncTask.php b/src/scheduler/AsyncTask.php index 89a410539a..29ff9a3bdc 100644 --- a/src/scheduler/AsyncTask.php +++ b/src/scheduler/AsyncTask.php @@ -25,6 +25,7 @@ namespace pocketmine\scheduler; use pocketmine\utils\AssumptionFailedError; use function is_scalar; +use function is_string; use function serialize; use function spl_object_id; use function unserialize; diff --git a/src/stats/SendUsageTask.php b/src/stats/SendUsageTask.php index 2d9cf557ed..afa69ed6b4 100644 --- a/src/stats/SendUsageTask.php +++ b/src/stats/SendUsageTask.php @@ -37,6 +37,7 @@ use function array_map; use function array_values; use function count; use function json_encode; +use function json_last_error_msg; use function md5; use function microtime; use function php_uname; diff --git a/src/thread/Thread.php b/src/thread/Thread.php index 26c2037b23..140dba225f 100644 --- a/src/thread/Thread.php +++ b/src/thread/Thread.php @@ -22,6 +22,7 @@ declare(strict_types=1); namespace pocketmine\thread; + use const PTHREADS_INHERIT_ALL; /** diff --git a/src/thread/Worker.php b/src/thread/Worker.php index 1d473e95f8..0874ad547b 100644 --- a/src/thread/Worker.php +++ b/src/thread/Worker.php @@ -22,6 +22,7 @@ declare(strict_types=1); namespace pocketmine\thread; + use const PTHREADS_INHERIT_ALL; /** diff --git a/src/utils/Internet.php b/src/utils/Internet.php index ccdfad21fd..1fba58924a 100644 --- a/src/utils/Internet.php +++ b/src/utils/Internet.php @@ -31,6 +31,7 @@ use function curl_getinfo; use function curl_init; use function curl_setopt_array; use function explode; +use function is_string; use function preg_match; use function socket_close; use function socket_connect; diff --git a/src/utils/Terminal.php b/src/utils/Terminal.php index 08bd2caff7..61df61dc7f 100644 --- a/src/utils/Terminal.php +++ b/src/utils/Terminal.php @@ -28,6 +28,7 @@ use function fopen; use function function_exists; use function getenv; use function is_array; +use function sapi_windows_vt100_support; use function stream_isatty; use const PHP_EOL; diff --git a/src/utils/TextFormat.php b/src/utils/TextFormat.php index 6d106db1c9..86662aa8e9 100644 --- a/src/utils/TextFormat.php +++ b/src/utils/TextFormat.php @@ -25,7 +25,9 @@ namespace pocketmine\utils; use function is_array; use function json_encode; +use function json_last_error_msg; use function mb_scrub; +use function preg_last_error; use function preg_quote; use function preg_replace; use function preg_split; diff --git a/src/utils/Timezone.php b/src/utils/Timezone.php index 4e6031c0a4..404f2bb238 100644 --- a/src/utils/Timezone.php +++ b/src/utils/Timezone.php @@ -27,12 +27,10 @@ use function abs; use function date_default_timezone_set; use function date_parse; use function exec; -use function file_exists; use function file_get_contents; use function implode; use function ini_get; use function ini_set; -use function is_link; use function is_string; use function json_decode; use function parse_ini_file; diff --git a/src/utils/Utils.php b/src/utils/Utils.php index 6b2217555f..1e30358d58 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -51,7 +51,6 @@ use function gettype; use function implode; use function is_array; use function is_object; -use function is_readable; use function is_string; use function json_decode; use function json_last_error_msg; From 8093a94e5ddfe76f6a330d28d2b459faaf11e05b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 28 Apr 2020 18:56:27 +0100 Subject: [PATCH 1482/3224] do not hardcode data deserialization into CraftingManager --- src/Server.php | 3 +- src/crafting/CraftingManager.php | 47 ------------ .../CraftingManagerFromDataHelper.php | 75 +++++++++++++++++++ 3 files changed, 77 insertions(+), 48 deletions(-) create mode 100644 src/crafting/CraftingManagerFromDataHelper.php diff --git a/src/Server.php b/src/Server.php index 71012b4e1f..fa604d6d9e 100644 --- a/src/Server.php +++ b/src/Server.php @@ -33,6 +33,7 @@ use pocketmine\command\ConsoleCommandSender; use pocketmine\command\PluginIdentifiableCommand; use pocketmine\command\SimpleCommandMap; use pocketmine\crafting\CraftingManager; +use pocketmine\crafting\CraftingManagerFromDataHelper; use pocketmine\event\HandlerListManager; use pocketmine\event\player\PlayerDataSaveEvent; use pocketmine\event\server\CommandEvent; @@ -984,7 +985,7 @@ class Server{ Enchantment::init(); Biome::init(); - $this->craftingManager = new CraftingManager(); + $this->craftingManager = CraftingManagerFromDataHelper::make(\pocketmine\RESOURCE_PATH . '/vanilla/recipes.json'); $this->resourceManager = new ResourcePackManager($this->getDataPath() . "resource_packs" . DIRECTORY_SEPARATOR, $this->logger); diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index c97dc10f06..fe51038e71 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -38,13 +38,10 @@ use pocketmine\timings\Timings; use pocketmine\utils\Binary; use pocketmine\utils\UUID; use function array_map; -use function file_get_contents; -use function json_decode; use function json_encode; use function spl_object_id; use function str_repeat; use function usort; -use const DIRECTORY_SEPARATOR; class CraftingManager{ /** @var ShapedRecipe[][] */ @@ -57,50 +54,6 @@ class CraftingManager{ /** @var CompressBatchPromise[] */ private $craftingDataCaches = []; - public function __construct(){ - $this->init(); - } - - public function init() : void{ - $recipes = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla" . DIRECTORY_SEPARATOR . "recipes.json"), true); - - $itemDeserializerFunc = \Closure::fromCallable([Item::class, 'jsonDeserialize']); - foreach($recipes as $recipe){ - switch($recipe["type"]){ - case "shapeless": - if($recipe["block"] !== "crafting_table"){ //TODO: filter others out for now to avoid breaking economics - break; - } - $this->registerShapelessRecipe(new ShapelessRecipe( - array_map($itemDeserializerFunc, $recipe["input"]), - array_map($itemDeserializerFunc, $recipe["output"]) - )); - break; - case "shaped": - if($recipe["block"] !== "crafting_table"){ //TODO: filter others out for now to avoid breaking economics - break; - } - $this->registerShapedRecipe(new ShapedRecipe( - $recipe["shape"], - array_map($itemDeserializerFunc, $recipe["input"]), - array_map($itemDeserializerFunc, $recipe["output"]) - )); - break; - case "smelting": - if($recipe["block"] !== "furnace"){ //TODO: filter others out for now to avoid breaking economics - break; - } - $this->registerFurnaceRecipe(new FurnaceRecipe( - Item::jsonDeserialize($recipe["output"]), - Item::jsonDeserialize($recipe["input"])) - ); - break; - default: - break; - } - } - } - /** * Rebuilds the cached CraftingDataPacket. */ diff --git a/src/crafting/CraftingManagerFromDataHelper.php b/src/crafting/CraftingManagerFromDataHelper.php new file mode 100644 index 0000000000..84ac260a31 --- /dev/null +++ b/src/crafting/CraftingManagerFromDataHelper.php @@ -0,0 +1,75 @@ +registerShapelessRecipe(new ShapelessRecipe( + array_map($itemDeserializerFunc, $recipe["input"]), + array_map($itemDeserializerFunc, $recipe["output"]) + )); + break; + case "shaped": + if($recipe["block"] !== "crafting_table"){ //TODO: filter others out for now to avoid breaking economics + break; + } + $result->registerShapedRecipe(new ShapedRecipe( + $recipe["shape"], + array_map($itemDeserializerFunc, $recipe["input"]), + array_map($itemDeserializerFunc, $recipe["output"]) + )); + break; + case "smelting": + if($recipe["block"] !== "furnace"){ //TODO: filter others out for now to avoid breaking economics + break; + } + $result->registerFurnaceRecipe(new FurnaceRecipe( + Item::jsonDeserialize($recipe["output"]), + Item::jsonDeserialize($recipe["input"])) + ); + break; + default: + break; + } + } + + return $result; + } +} \ No newline at end of file From aa57d05e12bf0b9e67a407b4d0b078c3391767e6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Apr 2020 10:36:28 +0100 Subject: [PATCH 1483/3224] update to a non-broken build of RakLib --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 8d2da2acbe..1ace8c8420 100644 --- a/composer.lock +++ b/composer.lock @@ -618,12 +618,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "84c9289542544fb70e611fea0ed3854d4b52bdde" + "reference": "ef39315146790d0f6940dd47ee57b1c13614ce19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/84c9289542544fb70e611fea0ed3854d4b52bdde", - "reference": "84c9289542544fb70e611fea0ed3854d4b52bdde", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/ef39315146790d0f6940dd47ee57b1c13614ce19", + "reference": "ef39315146790d0f6940dd47ee57b1c13614ce19", "shasum": "" }, "require": { @@ -649,7 +649,7 @@ "GPL-3.0" ], "description": "A RakNet server implementation written in PHP", - "time": "2020-04-28T11:10:59+00:00" + "time": "2020-04-28T20:06:17+00:00" }, { "name": "pocketmine/snooze", From f6f1d31112f55606b666b700238dc40b7771d849 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Apr 2020 11:34:25 +0100 Subject: [PATCH 1484/3224] do not mess with cached data directly in packets --- src/network/mcpe/StaticPacketCache.php | 69 +++++++++++++++++++ .../mcpe/handler/PreSpawnPacketHandler.php | 7 +- .../AvailableActorIdentifiersPacket.php | 35 +++++++--- .../protocol/BiomeDefinitionListPacket.php | 35 +++++++--- 4 files changed, 120 insertions(+), 26 deletions(-) create mode 100644 src/network/mcpe/StaticPacketCache.php diff --git a/src/network/mcpe/StaticPacketCache.php b/src/network/mcpe/StaticPacketCache.php new file mode 100644 index 0000000000..6ef7e8aedd --- /dev/null +++ b/src/network/mcpe/StaticPacketCache.php @@ -0,0 +1,69 @@ + + */ + private static function loadCompoundFromFile(string $filePath) : CacheableNbt{ + $rawNbt = @file_get_contents($filePath); + if($rawNbt === false) throw new \RuntimeException("Failed to read file"); + return new CacheableNbt((new NetworkNbtSerializer())->read($rawNbt)->mustGetCompoundTag()); + } + + private static function make() : self{ + return new self( + BiomeDefinitionListPacket::create(self::loadCompoundFromFile(\pocketmine\RESOURCE_PATH . '/vanilla/biome_definitions.nbt')), + AvailableActorIdentifiersPacket::create(self::loadCompoundFromFile(\pocketmine\RESOURCE_PATH . '/vanilla/entity_identifiers.nbt')) + ); + } + + public function __construct(BiomeDefinitionListPacket $biomeDefs, AvailableActorIdentifiersPacket $availableActorIdentifiers){ + $this->biomeDefs = $biomeDefs; + $this->availableActorIdentifiers = $availableActorIdentifiers; + } + + public function getBiomeDefs() : BiomeDefinitionListPacket{ + return $this->biomeDefs; + } + + public function getAvailableActorIdentifiers() : AvailableActorIdentifiersPacket{ + return $this->availableActorIdentifiers; + } +} \ No newline at end of file diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index b25ad0267e..1407c727df 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -25,12 +25,11 @@ namespace pocketmine\network\mcpe\handler; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\NetworkSession; -use pocketmine\network\mcpe\protocol\AvailableActorIdentifiersPacket; -use pocketmine\network\mcpe\protocol\BiomeDefinitionListPacket; use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; use pocketmine\network\mcpe\protocol\SetLocalPlayerAsInitializedPacket; use pocketmine\network\mcpe\protocol\StartGamePacket; use pocketmine\network\mcpe\protocol\types\DimensionIds; +use pocketmine\network\mcpe\StaticPacketCache; use pocketmine\player\Player; use pocketmine\Server; @@ -82,8 +81,8 @@ class PreSpawnPacketHandler extends PacketHandler{ $this->session->sendDataPacket($pk); - $this->session->sendDataPacket(new AvailableActorIdentifiersPacket()); - $this->session->sendDataPacket(new BiomeDefinitionListPacket()); + $this->session->sendDataPacket(StaticPacketCache::getInstance()->getAvailableActorIdentifiers()); + $this->session->sendDataPacket(StaticPacketCache::getInstance()->getBiomeDefs()); $this->player->setImmobile(); //HACK: fix client-side falling pre-spawn diff --git a/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php b/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php index c3990e3aab..4d2a1cade0 100644 --- a/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php +++ b/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php @@ -25,28 +25,41 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\nbt\NbtDataException; use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; -use function file_get_contents; +use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; +use pocketmine\network\mcpe\protocol\types\CacheableNbt; class AvailableActorIdentifiersPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::AVAILABLE_ACTOR_IDENTIFIERS_PACKET; - /** @var string|null */ - private static $DEFAULT_NBT_CACHE = null; + /** + * @var CacheableNbt + * @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag> + */ + public $identifiers; - /** @var string */ - public $namedtag; + /** + * @phpstan-param CacheableNbt<\pocketmine\nbt\tag\CompoundTag> $nbt + */ + public static function create(CacheableNbt $nbt) : self{ + $result = new self; + $result->identifiers = $nbt; + return $result; + } protected function decodePayload(NetworkBinaryStream $in) : void{ - $this->namedtag = $in->getRemaining(); + $offset = $in->getOffset(); + try{ + $this->identifiers = new CacheableNbt((new NetworkNbtSerializer())->read($in->getBuffer(), $offset)->mustGetCompoundTag()); + }catch(NbtDataException $e){ + throw PacketDecodeException::wrap($e, "Failed decoding actor identifiers"); + } + $in->setOffset($offset); } protected function encodePayload(NetworkBinaryStream $out) : void{ - $out->put( - $this->namedtag ?? - self::$DEFAULT_NBT_CACHE ?? - (self::$DEFAULT_NBT_CACHE = file_get_contents(\pocketmine\RESOURCE_PATH . '/vanilla/entity_identifiers.nbt')) - ); + $out->put($this->identifiers->getEncodedNbt()); } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/network/mcpe/protocol/BiomeDefinitionListPacket.php b/src/network/mcpe/protocol/BiomeDefinitionListPacket.php index 8229843e2e..0388c11093 100644 --- a/src/network/mcpe/protocol/BiomeDefinitionListPacket.php +++ b/src/network/mcpe/protocol/BiomeDefinitionListPacket.php @@ -25,28 +25,41 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\nbt\NbtDataException; use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; -use function file_get_contents; +use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; +use pocketmine\network\mcpe\protocol\types\CacheableNbt; class BiomeDefinitionListPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::BIOME_DEFINITION_LIST_PACKET; - /** @var string|null */ - private static $DEFAULT_NBT_CACHE = null; + /** + * @var CacheableNbt + * @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag> + */ + public $defs; - /** @var string */ - public $namedtag; + /** + * @phpstan-param CacheableNbt<\pocketmine\nbt\tag\CompoundTag> $nbt + */ + public static function create(CacheableNbt $nbt) : self{ + $result = new self; + $result->defs = $nbt; + return $result; + } protected function decodePayload(NetworkBinaryStream $in) : void{ - $this->namedtag = $in->getRemaining(); + $offset = $in->getOffset(); + try{ + $this->defs = new CacheableNbt((new NetworkNbtSerializer())->read($in->getBuffer(), $offset)->mustGetCompoundTag()); + }catch(NbtDataException $e){ + throw PacketDecodeException::wrap($e, "Failed decoding biome definitions"); + } + $in->setOffset($offset); } protected function encodePayload(NetworkBinaryStream $out) : void{ - $out->put( - $this->namedtag ?? - self::$DEFAULT_NBT_CACHE ?? - (self::$DEFAULT_NBT_CACHE = file_get_contents(\pocketmine\RESOURCE_PATH . '/vanilla/biome_definitions.nbt')) - ); + $out->put($this->defs->getEncodedNbt()); } public function handle(PacketHandlerInterface $handler) : bool{ From 098a5518a6b4cb293524b57b8072074688cc60d0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Apr 2020 11:35:12 +0100 Subject: [PATCH 1485/3224] phpstan: ignore another trait override bug --- tests/phpstan/configs/phpstan-bugs.neon | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 75cc5b1fce..21bf738f1b 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -60,6 +60,11 @@ parameters: count: 1 path: ../../../src/item/ItemFactory.php + - + message: "#^Class pocketmine\\\\network\\\\mcpe\\\\StaticPacketCache constructor invoked with 0 parameters, 2 required\\.$#" + count: 1 + path: ../../../src/network/mcpe/StaticPacketCache.php + - message: "#^If condition is always false\\.$#" count: 1 From 09e994a0268ac97b310e99c60bbdf17c73134c45 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Apr 2020 11:39:44 +0100 Subject: [PATCH 1486/3224] NetworkBinaryStream: swap BadPacketException for PacketDecodeException --- .../serializer/NetworkBinaryStream.php | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php b/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php index fdd54858b5..f1aacc8a4d 100644 --- a/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php +++ b/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php @@ -30,7 +30,7 @@ use pocketmine\math\Vector3; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; -use pocketmine\network\BadPacketException; +use pocketmine\network\mcpe\protocol\PacketDecodeException; use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; use pocketmine\network\mcpe\protocol\types\entity\Attribute; use pocketmine\network\mcpe\protocol\types\entity\BlockPosMetadataProperty; @@ -190,7 +190,7 @@ class NetworkBinaryStream extends BinaryStream{ try{ return new SkinImage($height, $width, $data); }catch(\InvalidArgumentException $e){ - throw new BadPacketException($e->getMessage(), 0, $e); + throw new PacketDecodeException($e->getMessage(), 0, $e); } } @@ -201,7 +201,7 @@ class NetworkBinaryStream extends BinaryStream{ } /** - * @throws BadPacketException + * @throws PacketDecodeException * @throws BinaryDataException */ public function getSlot() : ItemStack{ @@ -221,15 +221,15 @@ class NetworkBinaryStream extends BinaryStream{ if($nbtLen === 0xffff){ $c = $this->getByte(); if($c !== 1){ - throw new BadPacketException("Unexpected NBT count $c"); + throw new PacketDecodeException("Unexpected NBT count $c"); } try{ $compound = (new NetworkNbtSerializer())->read($this->buffer, $this->offset, 512)->mustGetCompoundTag(); }catch(NbtDataException $e){ - throw new BadPacketException($e->getMessage(), 0, $e); + throw new PacketDecodeException($e->getMessage(), 0, $e); } }elseif($nbtLen !== 0){ - throw new BadPacketException("Unexpected fake NBT length $nbtLen"); + throw new PacketDecodeException("Unexpected fake NBT length $nbtLen"); } $canPlaceOn = []; @@ -312,7 +312,7 @@ class NetworkBinaryStream extends BinaryStream{ * @return MetadataProperty[] * @phpstan-return array * - * @throws BadPacketException + * @throws PacketDecodeException * @throws BinaryDataException */ public function getEntityMetadata() : array{ @@ -340,7 +340,7 @@ class NetworkBinaryStream extends BinaryStream{ case LongMetadataProperty::id(): return LongMetadataProperty::read($this); case Vec3MetadataProperty::id(): return Vec3MetadataProperty::read($this); default: - throw new BadPacketException("Unknown entity metadata type " . $type); + throw new PacketDecodeException("Unknown entity metadata type " . $type); } } @@ -363,7 +363,7 @@ class NetworkBinaryStream extends BinaryStream{ * Reads a list of Attributes from the stream. * @return Attribute[] * - * @throws BadPacketException if reading an attribute with an unrecognized name + * @throws PacketDecodeException if reading an attribute with an unrecognized name * @throws BinaryDataException */ public function getAttributeList() : array{ @@ -537,7 +537,7 @@ class NetworkBinaryStream extends BinaryStream{ * @return mixed[][], members are in the structure [name => [type, value]] * @phpstan-return array * - * @throws BadPacketException + * @throws PacketDecodeException * @throws BinaryDataException */ public function getGameRules() : array{ @@ -558,7 +558,7 @@ class NetworkBinaryStream extends BinaryStream{ $value = $this->getLFloat(); break; default: - throw new BadPacketException("Unknown gamerule type $type"); + throw new PacketDecodeException("Unknown gamerule type $type"); } $rules[$name] = [$type, $value]; From b6214744d52514833c48c015ddbfb9880ea28a1d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Apr 2020 12:48:28 +0100 Subject: [PATCH 1487/3224] NetworkSession: inject PacketPool instead of hardcoding it this will make it slightly easier for multi version implementations, but handlers are still quite a big problem. --- src/network/mcpe/NetworkSession.php | 9 +++++++-- src/network/mcpe/protocol/serializer/PacketBatch.php | 4 ++-- src/network/mcpe/raklib/RakLibInterface.php | 2 ++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index aafdf7e39d..41036ee704 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -64,6 +64,7 @@ use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\NetworkChunkPublisherUpdatePacket; use pocketmine\network\mcpe\protocol\Packet; use pocketmine\network\mcpe\protocol\PacketDecodeException; +use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\PlayStatusPacket; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; @@ -150,13 +151,16 @@ class NetworkSession{ /** @var Compressor */ private $compressor; + /** @var PacketPool */ + private $packetPool; + /** @var InventoryManager|null */ private $invManager = null; /** @var PacketSender */ private $sender; - public function __construct(Server $server, NetworkSessionManager $manager, PacketSender $sender, Compressor $compressor, string $ip, int $port){ + public function __construct(Server $server, NetworkSessionManager $manager, PacketPool $packetPool, PacketSender $sender, Compressor $compressor, string $ip, int $port){ $this->server = $server; $this->manager = $manager; $this->sender = $sender; @@ -167,6 +171,7 @@ class NetworkSession{ $this->compressedQueue = new \SplQueue(); $this->compressor = $compressor; + $this->packetPool = $packetPool; $this->connectTime = time(); @@ -301,7 +306,7 @@ class NetworkSession{ throw new BadPacketException("Too many packets in a single batch"); } try{ - $pk = $stream->getPacket(); + $pk = $stream->getPacket($this->packetPool); }catch(BinaryDataException $e){ $this->logger->debug("Packet batch: " . base64_encode($stream->getBuffer())); throw BadPacketException::wrap($e, "Packet batch decode error"); diff --git a/src/network/mcpe/protocol/serializer/PacketBatch.php b/src/network/mcpe/protocol/serializer/PacketBatch.php index 9dbc6b2577..15bfaeb3b3 100644 --- a/src/network/mcpe/protocol/serializer/PacketBatch.php +++ b/src/network/mcpe/protocol/serializer/PacketBatch.php @@ -37,8 +37,8 @@ class PacketBatch extends NetworkBinaryStream{ /** * @throws BinaryDataException */ - public function getPacket() : Packet{ - return PacketPool::getInstance()->getPacket($this->getString()); + public function getPacket(PacketPool $packetPool) : Packet{ + return $packetPool->getPacket($this->getString()); } /** diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 8321e57686..c99cf1f962 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -27,6 +27,7 @@ use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\compression\ZlibCompressor; use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\Network; use pocketmine\Server; @@ -156,6 +157,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ $session = new NetworkSession( $this->server, $this->network->getSessionManager(), + PacketPool::getInstance(), new RakLibPacketSender($sessionId, $this), ZlibCompressor::getInstance(), //TODO: this shouldn't be hardcoded, but we might need the RakNet protocol version to select it $address, From 549940d8a7a7a72b3d042f6ac68db6b111b2b508 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Apr 2020 13:14:23 +0100 Subject: [PATCH 1488/3224] remove NullPacketHandler this is a waste of LOC --- src/network/mcpe/NetworkSession.php | 17 ++++---- .../mcpe/handler/LoginPacketHandler.php | 2 +- .../mcpe/handler/NullPacketHandler.php | 40 ------------------- 3 files changed, 10 insertions(+), 49 deletions(-) delete mode 100644 src/network/mcpe/handler/NullPacketHandler.php diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 41036ee704..7c47b67634 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -46,7 +46,6 @@ use pocketmine\network\mcpe\handler\DeathPacketHandler; use pocketmine\network\mcpe\handler\HandshakePacketHandler; use pocketmine\network\mcpe\handler\InGamePacketHandler; use pocketmine\network\mcpe\handler\LoginPacketHandler; -use pocketmine\network\mcpe\handler\NullPacketHandler; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\handler\PreSpawnPacketHandler; use pocketmine\network\mcpe\handler\ResourcePacksPacketHandler; @@ -126,8 +125,8 @@ class NetworkSession{ /** @var int|null */ private $ping = null; - /** @var PacketHandler */ - private $handler; + /** @var PacketHandler|null */ + private $handler = null; /** @var bool */ private $connected = true; @@ -258,14 +257,16 @@ class NetworkSession{ $this->ping = $ping; } - public function getHandler() : PacketHandler{ + public function getHandler() : ?PacketHandler{ return $this->handler; } - public function setHandler(PacketHandler $handler) : void{ + public function setHandler(?PacketHandler $handler) : void{ if($this->connected){ //TODO: this is fine since we can't handle anything from a disconnected session, but it might produce surprises in some cases $this->handler = $handler; - $this->handler->setUp(); + if($this->handler !== null){ + $this->handler->setUp(); + } } } @@ -350,7 +351,7 @@ class NetworkSession{ $ev = new DataPacketReceiveEvent($this, $packet); $ev->call(); - if(!$ev->isCancelled() and !$packet->handle($this->handler)){ + if(!$ev->isCancelled() and ($this->handler === null or !$packet->handle($this->handler))){ $this->logger->debug("Unhandled " . $packet->getName() . ": " . base64_encode($stream->getBuffer())); } }finally{ @@ -459,7 +460,7 @@ class NetworkSession{ $this->disconnectGuard = true; $func(); $this->disconnectGuard = false; - $this->setHandler(NullPacketHandler::getInstance()); + $this->setHandler(null); $this->connected = false; $this->manager->remove($this); $this->logger->info("Session closed due to $reason"); diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index 6553293b5d..6b2f7faa73 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -195,7 +195,7 @@ class LoginPacketHandler extends PacketHandler{ */ protected function processLogin(LoginPacket $packet, bool $authRequired) : void{ $this->server->getAsyncPool()->submitTask(new ProcessLoginTask($packet, $authRequired, $this->authCallback)); - $this->session->setHandler(NullPacketHandler::getInstance()); //drop packets received during login verification + $this->session->setHandler(null); //drop packets received during login verification } protected function isCompatibleProtocol(int $protocolVersion) : bool{ diff --git a/src/network/mcpe/handler/NullPacketHandler.php b/src/network/mcpe/handler/NullPacketHandler.php deleted file mode 100644 index 17cbf200b3..0000000000 --- a/src/network/mcpe/handler/NullPacketHandler.php +++ /dev/null @@ -1,40 +0,0 @@ - Date: Wed, 29 Apr 2020 13:26:49 +0100 Subject: [PATCH 1489/3224] phpstorm can't infer these types :( --- src/Server.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Server.php b/src/Server.php index fa604d6d9e..3aaa1eb2d7 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1253,7 +1253,9 @@ class Server{ $stream = PacketBatch::fromPackets(...$ev->getPackets()); + /** @var Compressor[] $compressors */ $compressors = []; + /** @var NetworkSession[][] $compressorTargets */ $compressorTargets = []; foreach($recipients as $recipient){ $compressor = $recipient->getCompressor(); From d8968e9e401345d594331c43cc932e667136dbfd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Apr 2020 16:24:04 +0100 Subject: [PATCH 1490/3224] box up TakeItemActorPacket sending behind NetworkSession API we need to start thinking about moving this into interfaces. --- src/entity/object/ItemEntity.php | 5 +++-- src/entity/projectile/Arrow.php | 5 +++-- src/network/mcpe/NetworkSession.php | 6 ++++++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index 6ddf055a3c..e4550c6994 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -31,7 +31,6 @@ use pocketmine\item\Item; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\AddItemActorPacket; -use pocketmine\network\mcpe\protocol\TakeItemActorPacket; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\player\Player; use function get_class; @@ -235,7 +234,9 @@ class ItemEntity extends Entity{ return; } - $this->server->broadcastPackets($this->getViewers(), [TakeItemActorPacket::create($player->getId(), $this->getId())]); + foreach($this->getViewers() as $viewer){ + $viewer->getNetworkSession()->onPlayerPickUpItem($player, $this); + } $playerInventory->addItem(clone $item); $this->flagForDespawn(); diff --git a/src/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php index b0ba0fa7e3..86d3acfa9e 100644 --- a/src/entity/projectile/Arrow.php +++ b/src/entity/projectile/Arrow.php @@ -31,7 +31,6 @@ use pocketmine\item\VanillaItems; use pocketmine\math\RayTraceResult; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\ActorEventPacket; -use pocketmine\network\mcpe\protocol\TakeItemActorPacket; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\player\Player; @@ -185,7 +184,9 @@ class Arrow extends Projectile{ return; } - $this->server->broadcastPackets($this->getViewers(), [TakeItemActorPacket::create($player->getId(), $this->getId())]); + foreach($this->getViewers() as $viewer){ + $viewer->getNetworkSession()->onPlayerPickUpItem($player, $this); + } $playerInventory->addItem(clone $item); $this->flagForDespawn(); diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 7c47b67634..7f1a781338 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe; use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; use pocketmine\entity\Attribute; use pocketmine\entity\effect\EffectInstance; +use pocketmine\entity\Entity; use pocketmine\entity\Human; use pocketmine\entity\Living; use pocketmine\event\player\PlayerCreationEvent; @@ -72,6 +73,7 @@ use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket; use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket; use pocketmine\network\mcpe\protocol\SetTitlePacket; +use pocketmine\network\mcpe\protocol\TakeItemActorPacket; use pocketmine\network\mcpe\protocol\TextPacket; use pocketmine\network\mcpe\protocol\TransferPacket; use pocketmine\network\mcpe\protocol\types\command\CommandData; @@ -829,6 +831,10 @@ class NetworkSession{ )); } + public function onPlayerPickUpItem(Player $collector, Entity $pickedUp) : void{ + $this->sendDataPacket(TakeItemActorPacket::create($collector->getId(), $pickedUp->getId())); + } + public function syncPlayerList() : void{ $this->sendDataPacket(PlayerListPacket::add(array_map(function(Player $player) : PlayerListEntry{ return PlayerListEntry::createAdditionEntry($player->getUniqueId(), $player->getId(), $player->getDisplayName(), SkinAdapterSingleton::get()->toSkinData($player->getSkin()), $player->getXuid()); From ad70a9e3dcbd2617c9d0c0e4a1aa94887b76fb5a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Apr 2020 16:27:34 +0100 Subject: [PATCH 1491/3224] NetworkSession: allow provision of a custom list of players to syncPlayerList() --- src/network/mcpe/NetworkSession.php | 7 +++++-- src/network/mcpe/handler/PreSpawnPacketHandler.php | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 7f1a781338..6f4380d4a3 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -835,10 +835,13 @@ class NetworkSession{ $this->sendDataPacket(TakeItemActorPacket::create($collector->getId(), $pickedUp->getId())); } - public function syncPlayerList() : void{ + /** + * @param Player[] $players + */ + public function syncPlayerList(array $players) : void{ $this->sendDataPacket(PlayerListPacket::add(array_map(function(Player $player) : PlayerListEntry{ return PlayerListEntry::createAdditionEntry($player->getUniqueId(), $player->getId(), $player->getDisplayName(), SkinAdapterSingleton::get()->toSkinData($player->getSkin()), $player->getXuid()); - }, $this->server->getOnlinePlayers()))); + }, $players))); } public function onPlayerAdded(Player $p) : void{ diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index 1407c727df..726cdb7de3 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -99,7 +99,7 @@ class PreSpawnPacketHandler extends PacketHandler{ $this->session->getInvManager()->syncSelectedHotbarSlot(); $this->session->queueCompressed($this->server->getCraftingManager()->getCraftingDataPacket($this->session->getCompressor())); - $this->session->syncPlayerList(); + $this->session->syncPlayerList($this->server->getOnlinePlayers()); } public function handleRequestChunkRadius(RequestChunkRadiusPacket $packet) : bool{ From f35b7bf80b3f6783ee488584aa0be6dd20a835b3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Apr 2020 16:32:56 +0100 Subject: [PATCH 1492/3224] NetworkBinaryStream: remove stale @throws from getAttributeList() --- src/network/mcpe/protocol/serializer/NetworkBinaryStream.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php b/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php index f1aacc8a4d..f74937870b 100644 --- a/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php +++ b/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php @@ -363,7 +363,6 @@ class NetworkBinaryStream extends BinaryStream{ * Reads a list of Attributes from the stream. * @return Attribute[] * - * @throws PacketDecodeException if reading an attribute with an unrecognized name * @throws BinaryDataException */ public function getAttributeList() : array{ From f6f714c1583298ca77227e5de1be72729a127ac9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Apr 2020 16:38:10 +0100 Subject: [PATCH 1493/3224] NetworkSession: do not mark shared attributes as synchronized, they don't necessarily belong to us if we decided to start sending entity attribute changes to viewers too, this would have caused some unexpected behaviour. --- src/network/mcpe/NetworkSession.php | 3 --- src/player/Player.php | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 6f4380d4a3..5c4075eac0 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -686,9 +686,6 @@ class NetworkSession{ $this->sendDataPacket(UpdateAttributesPacket::create($entity->getId(), array_map(function(Attribute $attr) : NetworkAttribute{ return new NetworkAttribute($attr->getId(), $attr->getMinValue(), $attr->getMaxValue(), $attr->getValue(), $attr->getDefaultValue()); }, $entries))); - foreach($entries as $entry){ - $entry->markSynchronized(); - } } } diff --git a/src/player/Player.php b/src/player/Player.php index 18c5aac294..1d4f8169a5 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1292,6 +1292,9 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, //TODO: move this to network session ticking (this is specifically related to net sync) $this->networkSession->syncAttributes($this); + foreach($this->attributeMap->getAll() as $attribute){ + $attribute->markSynchronized(); + } if(!$this->isAlive() and $this->spawned){ $this->onDeathUpdate($tickDiff); From d1b28ce17a1a6b4bcbbdf7952469f612e3046a92 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Apr 2020 16:45:09 +0100 Subject: [PATCH 1494/3224] NetworkSession: allow sending an arbitrary set of attributes for an entity --- src/network/mcpe/NetworkSession.php | 10 ++++++---- src/network/mcpe/handler/PreSpawnPacketHandler.php | 2 +- src/player/Player.php | 5 +++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 5c4075eac0..0017f764e2 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -680,12 +680,14 @@ class NetworkSession{ $this->sendDataPacket($pk); } - public function syncAttributes(Living $entity, bool $sendAll = false) : void{ - $entries = $sendAll ? $entity->getAttributeMap()->getAll() : $entity->getAttributeMap()->needSend(); - if(count($entries) > 0){ + /** + * @param Attribute[] $attributes + */ + public function syncAttributes(Living $entity, array $attributes) : void{ + if(count($attributes) > 0){ $this->sendDataPacket(UpdateAttributesPacket::create($entity->getId(), array_map(function(Attribute $attr) : NetworkAttribute{ return new NetworkAttribute($attr->getId(), $attr->getMinValue(), $attr->getMaxValue(), $attr->getValue(), $attr->getDefaultValue()); - }, $entries))); + }, $attributes))); } } diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index 726cdb7de3..f475d53704 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -86,7 +86,7 @@ class PreSpawnPacketHandler extends PacketHandler{ $this->player->setImmobile(); //HACK: fix client-side falling pre-spawn - $this->session->syncAttributes($this->player, true); + $this->session->syncAttributes($this->player, $this->player->getAttributeMap()->getAll()); $this->session->syncAvailableCommands(); $this->session->syncAdventureSettings($this->player); foreach($this->player->getEffects()->all() as $effect){ diff --git a/src/player/Player.php b/src/player/Player.php index 1d4f8169a5..0730fb1649 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1291,8 +1291,9 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->lastUpdate = $currentTick; //TODO: move this to network session ticking (this is specifically related to net sync) - $this->networkSession->syncAttributes($this); - foreach($this->attributeMap->getAll() as $attribute){ + $dirtyAttributes = $this->attributeMap->needSend(); + $this->networkSession->syncAttributes($this, $dirtyAttributes); + foreach($dirtyAttributes as $attribute){ $attribute->markSynchronized(); } From 4ce6525065ced2032c7677f3035e077f24dc64f0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Apr 2020 16:50:52 +0100 Subject: [PATCH 1495/3224] NetworkSession: incomplete abstraction of SetActorDataPacket handling this needs to have the metadata properties separated too, but that's a job that's going to get VERY messy. --- src/entity/Entity.php | 8 ++++---- src/network/mcpe/NetworkSession.php | 10 ++++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 84fafbdcff..4613006aa2 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -48,7 +48,6 @@ use pocketmine\network\mcpe\protocol\AddActorPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\MoveActorAbsolutePacket; use pocketmine\network\mcpe\protocol\RemoveActorPacket; -use pocketmine\network\mcpe\protocol\SetActorDataPacket; use pocketmine\network\mcpe\protocol\SetActorMotionPacket; use pocketmine\network\mcpe\protocol\types\entity\Attribute as NetworkAttribute; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; @@ -1647,17 +1646,18 @@ abstract class Entity{ $player = [$player]; } - $pk = SetActorDataPacket::create($this->getId(), $data ?? $this->getSyncedNetworkData(false)); + $data = $data ?? $this->getSyncedNetworkData(false); foreach($player as $p){ if($p === $this){ continue; } - $p->getNetworkSession()->sendDataPacket(clone $pk); + $p->getNetworkSession()->syncActorData($this, $data); } if($this instanceof Player){ - $this->getNetworkSession()->sendDataPacket($pk); + //TODO: bad hack, remove + $this->getNetworkSession()->syncActorData($this, $data); } } diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 0017f764e2..c82bf2f065 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -70,6 +70,7 @@ use pocketmine\network\mcpe\protocol\PlayStatusPacket; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\protocol\ServerboundPacket; use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket; +use pocketmine\network\mcpe\protocol\SetActorDataPacket; use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket; use pocketmine\network\mcpe\protocol\SetTitlePacket; @@ -80,6 +81,7 @@ use pocketmine\network\mcpe\protocol\types\command\CommandData; use pocketmine\network\mcpe\protocol\types\command\CommandEnum; use pocketmine\network\mcpe\protocol\types\command\CommandParameter; use pocketmine\network\mcpe\protocol\types\entity\Attribute as NetworkAttribute; +use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; @@ -691,6 +693,14 @@ class NetworkSession{ } } + /** + * @param MetadataProperty[] $properties + * @phpstan-param array $properties + */ + public function syncActorData(Entity $entity, array $properties) : void{ + $this->sendDataPacket(SetActorDataPacket::create($entity->getId(), $properties)); + } + public function onEntityEffectAdded(Living $entity, EffectInstance $effect, bool $replacesOldEffect) : void{ $this->sendDataPacket(MobEffectPacket::add($entity->getId(), $replacesOldEffect, $effect->getId(), $effect->getAmplifier(), $effect->isVisible(), $effect->getDuration())); } From adadd5423d0d7f7015f2891b1cd0313a75951a4d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Apr 2020 16:54:23 +0100 Subject: [PATCH 1496/3224] move force-close crafting grid hack to InGamePacketHandler the crafting transaction implementation has no business caring about this --- src/inventory/transaction/CraftingTransaction.php | 14 -------------- src/network/mcpe/handler/InGamePacketHandler.php | 9 +++++++++ 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/inventory/transaction/CraftingTransaction.php b/src/inventory/transaction/CraftingTransaction.php index da7178ee94..db9428447c 100644 --- a/src/inventory/transaction/CraftingTransaction.php +++ b/src/inventory/transaction/CraftingTransaction.php @@ -26,8 +26,6 @@ namespace pocketmine\inventory\transaction; use pocketmine\crafting\CraftingRecipe; use pocketmine\event\inventory\CraftItemEvent; use pocketmine\item\Item; -use pocketmine\network\mcpe\protocol\ContainerClosePacket; -use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; use function array_pop; use function count; use function intdiv; @@ -154,16 +152,4 @@ class CraftingTransaction extends InventoryTransaction{ $ev->call(); return !$ev->isCancelled(); } - - protected function sendInventories() : void{ - parent::sendInventories(); - - /* - * TODO: HACK! - * we can't resend the contents of the crafting window, so we force the client to close it instead. - * So people don't whine about messy desync issues when someone cancels CraftItemEvent, or when a crafting - * transaction goes wrong. - */ - $this->source->getNetworkSession()->sendDataPacket(ContainerClosePacket::create(ContainerIds::NONE)); - } } diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 29eee96ae5..adbea3b1aa 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -257,6 +257,15 @@ class InGamePacketHandler extends PacketHandler{ $this->craftingTransaction->execute(); }catch(TransactionValidationException $e){ $this->session->getLogger()->debug("Failed to execute crafting transaction: " . $e->getMessage()); + + /* + * TODO: HACK! + * we can't resend the contents of the crafting window, so we force the client to close it instead. + * So people don't whine about messy desync issues when someone cancels CraftItemEvent, or when a crafting + * transaction goes wrong. + */ + $this->session->sendDataPacket(ContainerClosePacket::create(ContainerIds::NONE)); + return false; }finally{ $this->craftingTransaction = null; From c8c0a1533c5c80e976461e92674904d98230a30c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Apr 2020 17:00:47 +0100 Subject: [PATCH 1497/3224] NetworkSession: seal up actor removal behind API --- src/entity/Entity.php | 3 +-- src/network/mcpe/NetworkSession.php | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 4613006aa2..b75d99dcd0 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -47,7 +47,6 @@ use pocketmine\network\mcpe\protocol\ActorEventPacket; use pocketmine\network\mcpe\protocol\AddActorPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\MoveActorAbsolutePacket; -use pocketmine\network\mcpe\protocol\RemoveActorPacket; use pocketmine\network\mcpe\protocol\SetActorMotionPacket; use pocketmine\network\mcpe\protocol\types\entity\Attribute as NetworkAttribute; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; @@ -1560,7 +1559,7 @@ abstract class Entity{ $id = spl_object_id($player); if(isset($this->hasSpawned[$id])){ if($send){ - $player->getNetworkSession()->sendDataPacket(RemoveActorPacket::create($this->id)); + $player->getNetworkSession()->onEntityRemoved($this); } unset($this->hasSpawned[$id]); } diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index c82bf2f065..0d1ae96a3a 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -67,6 +67,7 @@ use pocketmine\network\mcpe\protocol\PacketDecodeException; use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\PlayStatusPacket; +use pocketmine\network\mcpe\protocol\RemoveActorPacket; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\protocol\ServerboundPacket; use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket; @@ -709,6 +710,10 @@ class NetworkSession{ $this->sendDataPacket(MobEffectPacket::remove($entity->getId(), $effect->getId())); } + public function onEntityRemoved(Entity $entity) : void{ + $this->sendDataPacket(RemoveActorPacket::create($entity->getId())); + } + public function syncAvailableCommands() : void{ $pk = new AvailableCommandsPacket(); foreach($this->server->getCommandMap()->getCommands() as $name => $command){ From bb11cbd89c31c33908de30f2502ea231d3c83a49 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Apr 2020 18:31:54 +0100 Subject: [PATCH 1498/3224] World: relocate packet stuff for time and difficulty behind NetworkSession API --- src/network/mcpe/NetworkSession.php | 14 ++++++++++++-- src/world/World.php | 24 ++++-------------------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 0d1ae96a3a..1826c86186 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -72,8 +72,10 @@ use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\protocol\ServerboundPacket; use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket; use pocketmine\network\mcpe\protocol\SetActorDataPacket; +use pocketmine\network\mcpe\protocol\SetDifficultyPacket; use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket; +use pocketmine\network\mcpe\protocol\SetTimePacket; use pocketmine\network\mcpe\protocol\SetTitlePacket; use pocketmine\network\mcpe\protocol\TakeItemActorPacket; use pocketmine\network\mcpe\protocol\TextPacket; @@ -815,8 +817,16 @@ class NetworkSession{ public function onEnterWorld() : void{ $world = $this->player->getWorld(); - $world->sendTime($this->player); - $world->sendDifficulty($this->player); + $this->syncWorldTime($world->getTime()); + $this->syncWorldDifficulty($world->getDifficulty()); + } + + public function syncWorldTime(int $worldTime) : void{ + $this->sendDataPacket(SetTimePacket::create($worldTime)); + } + + public function syncWorldDifficulty(int $worldDifficulty) : void{ + $this->sendDataPacket(SetDifficultyPacket::create($worldDifficulty)); } public function getInvManager() : InventoryManager{ diff --git a/src/world/World.php b/src/world/World.php index 855661059f..71de88a1e1 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -54,8 +54,6 @@ use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\BlockActorDataPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; -use pocketmine\network\mcpe\protocol\SetDifficultyPacket; -use pocketmine\network\mcpe\protocol\SetTimePacket; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; use pocketmine\player\Player; use pocketmine\Server; @@ -644,12 +642,8 @@ class World implements ChunkManager{ * @param Player ...$targets If empty, will send to all players in the world. */ public function sendTime(Player ...$targets) : void{ - $pk = SetTimePacket::create($this->time); - - if(count($targets) === 0){ - $this->broadcastGlobalPacket($pk); - }else{ - $this->server->broadcastPackets($targets, [$pk]); + foreach($targets as $player){ + $player->getNetworkSession()->syncWorldTime($this->time); } } @@ -2362,18 +2356,8 @@ class World implements ChunkManager{ } $this->provider->getWorldData()->setDifficulty($difficulty); - $this->sendDifficulty(); - } - - /** - * @param Player ...$targets - */ - public function sendDifficulty(Player ...$targets) : void{ - $pk = SetDifficultyPacket::create($this->getDifficulty()); - if(count($targets) === 0){ - $this->broadcastGlobalPacket($pk); - }else{ - $this->server->broadcastPackets($targets, [$pk]); + foreach($this->players as $player){ + $player->getNetworkSession()->syncWorldDifficulty($this->getDifficulty()); } } From 3ce9a4801fc6f1b03dc5ec1f53c1f7725e76e9be Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Apr 2020 18:48:16 +0100 Subject: [PATCH 1499/3224] World: allow registering unload hooks this will be used for cache management when worlds get unloaded. --- src/world/World.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index 71de88a1e1..ae4214f9c7 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -246,6 +246,11 @@ class World implements ChunkManager{ /** @var bool */ private $closed = false; + /** + * @var \Closure[] + * @phpstan-var array + */ + private $unloadCallbacks = []; /** @var BlockLightUpdate|null */ private $blockLightUpdate = null; @@ -405,6 +410,11 @@ class World implements ChunkManager{ throw new \InvalidStateException("Tried to close a world which is already closed"); } + foreach($this->unloadCallbacks as $callback){ + $callback(); + } + $this->unloadCallbacks = []; + foreach($this->chunks as $chunk){ $this->unloadChunk($chunk->getX(), $chunk->getZ(), false); } @@ -421,6 +431,14 @@ class World implements ChunkManager{ $this->closed = true; } + public function addOnUnloadCallback(\Closure $callback) : void{ + $this->unloadCallbacks[spl_object_id($callback)] = $callback; + } + + public function removeOnUnloadCallback(\Closure $callback) : void{ + unset($this->unloadCallbacks[spl_object_id($callback)]); + } + /** * @param Player[]|null $players */ From b74f177958cc99e46ce97aa45e1cb3fc200d4e2e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Apr 2020 18:50:33 +0100 Subject: [PATCH 1500/3224] ChunkCache: destroy cache when world is unloaded --- src/network/mcpe/ChunkCache.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/network/mcpe/ChunkCache.php b/src/network/mcpe/ChunkCache.php index 399da5c29a..128d5890b9 100644 --- a/src/network/mcpe/ChunkCache.php +++ b/src/network/mcpe/ChunkCache.php @@ -74,6 +74,12 @@ class ChunkCache implements ChunkListener{ private function __construct(World $world, Compressor $compressor){ $this->world = $world; $this->compressor = $compressor; + $worldId = spl_object_id($world); + $this->world->addOnUnloadCallback(function() use ($worldId) : void{ + $this->caches = []; + unset(self::$instances[$worldId]); + \GlobalLogger::get()->debug("Destroyed chunk packet caches for world#$worldId"); + }); } /** From 6f38031121cfcf4f1a52fd9eee7a49395624a230 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 30 Apr 2020 09:35:42 +0100 Subject: [PATCH 1501/3224] Liquid: do not schedule delayed blockupdate when hardening occurs on nearby blockupdate fix #3390 fix #3392 --- src/block/Lava.php | 5 ++++- src/block/Liquid.php | 9 +++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/block/Lava.php b/src/block/Lava.php index e897a606b3..aa1dec0757 100644 --- a/src/block/Lava.php +++ b/src/block/Lava.php @@ -54,7 +54,7 @@ class Lava extends Liquid{ return 2; //TODO: this is 1 in the nether } - protected function checkForHarden() : void{ + protected function checkForHarden() : bool{ $colliding = null; foreach(Facing::ALL as $side){ if($side === Facing::DOWN){ @@ -70,10 +70,13 @@ class Lava extends Liquid{ if($colliding !== null){ if($this->decay === 0){ $this->liquidCollide($colliding, VanillaBlocks::OBSIDIAN()); + return true; }elseif($this->decay <= 4){ $this->liquidCollide($colliding, VanillaBlocks::COBBLESTONE()); + return true; } } + return false; } protected function flowIntoBlock(Block $block, int $newFlowDecay, bool $falling) : void{ diff --git a/src/block/Liquid.php b/src/block/Liquid.php index 68990cb147..3cf4916406 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -251,8 +251,9 @@ abstract class Liquid extends Transparent{ } public function onNearbyBlockChange() : void{ - $this->checkForHarden(); - $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, $this->tickRate()); + if(!$this->checkForHarden()){ + $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, $this->tickRate()); + } } public function onScheduledUpdate() : void{ @@ -469,8 +470,8 @@ abstract class Liquid extends Transparent{ return ($decay >= 0 && $blockDecay >= $decay) ? $decay : $blockDecay; } - protected function checkForHarden() : void{ - + protected function checkForHarden() : bool{ + return false; } protected function liquidCollide(Block $cause, Block $result) : bool{ From 1969766b7013847d9e9ddb1f3775d431d33e93a5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 May 2020 11:52:32 +0100 Subject: [PATCH 1502/3224] Nix some client-sided sounds, control them from the server this is a necessary step to knock out the implicit assumption that every player is using the same protocol. --- src/entity/Living.php | 20 +++++++ .../mcpe/handler/InGamePacketHandler.php | 8 +++ src/network/mcpe/protocol/AddActorPacket.php | 1 + src/world/sound/EntityLandSound.php | 57 +++++++++++++++++++ src/world/sound/EntityLongFallSound.php | 54 ++++++++++++++++++ src/world/sound/EntityShortFallSound.php | 53 +++++++++++++++++ 6 files changed, 193 insertions(+) create mode 100644 src/world/sound/EntityLandSound.php create mode 100644 src/world/sound/EntityLongFallSound.php create mode 100644 src/world/sound/EntityShortFallSound.php diff --git a/src/entity/Living.php b/src/entity/Living.php index 11993396fb..d41567ce5e 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity; use pocketmine\block\Block; +use pocketmine\block\BlockLegacyIds; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\EffectManager; use pocketmine\entity\effect\VanillaEffects; @@ -51,6 +52,9 @@ use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\player\Player; use pocketmine\timings\Timings; use pocketmine\utils\Binary; +use pocketmine\world\sound\EntityLandSound; +use pocketmine\world\sound\EntityLongFallSound; +use pocketmine\world\sound\EntityShortFallSound; use pocketmine\world\sound\ItemBreakSound; use function array_shift; use function atan2; @@ -248,6 +252,22 @@ abstract class Living extends Entity{ if($damage > 0){ $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FALL, $damage); $this->attack($ev); + + $this->getWorld()->addSound($this->location, $damage > 4 ? + new EntityLongFallSound($this) : + new EntityShortFallSound($this) + ); + }else{ + $fallBlockPos = $this->location->floor(); + $fallBlock = $this->getWorld()->getBlock($fallBlockPos); + for( + ; + $fallBlock->getId() === BlockLegacyIds::AIR; + $fallBlockPos = $fallBlockPos->subtract(0, 1, 0), $fallBlock = $this->getWorld()->getBlock($fallBlockPos) + ){ + //this allows the correct sound to be played when landing in snow + } + $this->getWorld()->addSound($this->location, new EntityLandSound($this, $fallBlock)); } } diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index adbea3b1aa..312a7fda9d 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -754,6 +754,14 @@ class InGamePacketHandler extends PacketHandler{ } public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{ + //TODO: we want to block out this packet completely, but we don't yet know the full scope of sounds that the client sends us from here + switch($packet->sound){ + case LevelSoundEventPacket::SOUND_LAND: + case LevelSoundEventPacket::SOUND_FALL: + case LevelSoundEventPacket::SOUND_FALL_SMALL: + case LevelSoundEventPacket::SOUND_FALL_BIG: + return true; + } $this->player->getWorld()->broadcastPacketToViewers($this->player->getPosition(), $packet); return true; } diff --git a/src/network/mcpe/protocol/AddActorPacket.php b/src/network/mcpe/protocol/AddActorPacket.php index 9dc200c86c..3f375ae937 100644 --- a/src/network/mcpe/protocol/AddActorPacket.php +++ b/src/network/mcpe/protocol/AddActorPacket.php @@ -44,6 +44,7 @@ class AddActorPacket extends DataPacket implements ClientboundPacket{ * TODO: remove this on 4.0 */ public const LEGACY_ID_MAP_BC = [ + -1 => ":", EntityLegacyIds::NPC => "minecraft:npc", EntityLegacyIds::PLAYER => "minecraft:player", EntityLegacyIds::WITHER_SKELETON => "minecraft:wither_skeleton", diff --git a/src/world/sound/EntityLandSound.php b/src/world/sound/EntityLandSound.php new file mode 100644 index 0000000000..3de49758dd --- /dev/null +++ b/src/world/sound/EntityLandSound.php @@ -0,0 +1,57 @@ +entity = $entity; + $this->blockLandedOn = $blockLandedOn; + } + + public function encode(?Vector3 $pos){ + return LevelSoundEventPacket::create( + LevelSoundEventPacket::SOUND_LAND, + $pos, + $this->blockLandedOn->getRuntimeId(), + $this->entity instanceof Player ? "minecraft:player" : AddActorPacket::LEGACY_ID_MAP_BC[$this->entity::NETWORK_ID] //TODO: bad hack, stuff depends on players having a -1 network ID :( + //TODO: does isBaby have any relevance here? + ); + } +} \ No newline at end of file diff --git a/src/world/sound/EntityLongFallSound.php b/src/world/sound/EntityLongFallSound.php new file mode 100644 index 0000000000..bef0286e72 --- /dev/null +++ b/src/world/sound/EntityLongFallSound.php @@ -0,0 +1,54 @@ +entity = $entity; + } + + public function encode(?Vector3 $pos){ + return LevelSoundEventPacket::create( + LevelSoundEventPacket::SOUND_FALL_BIG, + $pos, + -1, + $this->entity instanceof Player ? "minecraft:player" : AddActorPacket::LEGACY_ID_MAP_BC[$this->entity::NETWORK_ID] //TODO: bad hack, stuff depends on players having a -1 network ID :( + //TODO: is isBaby relevant here? + ); + } +} \ No newline at end of file diff --git a/src/world/sound/EntityShortFallSound.php b/src/world/sound/EntityShortFallSound.php new file mode 100644 index 0000000000..3049f652b7 --- /dev/null +++ b/src/world/sound/EntityShortFallSound.php @@ -0,0 +1,53 @@ +entity = $entity; + } + + public function encode(?Vector3 $pos){ + return LevelSoundEventPacket::create( + LevelSoundEventPacket::SOUND_FALL_SMALL, + $pos, + -1, + $this->entity instanceof Player ? "minecraft:player" : AddActorPacket::LEGACY_ID_MAP_BC[$this->entity::NETWORK_ID] //TODO: bad hack, stuff depends on players having a -1 network ID :( + //TODO: does isBaby have any relevance here? + ); + } +} \ No newline at end of file From 2964a4be35a8b9ad69e6517f5b6782566332dd93 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 May 2020 12:23:00 +0100 Subject: [PATCH 1503/3224] making BlockPunchSound server-controlled --- .../mcpe/handler/InGamePacketHandler.php | 1 + src/player/Player.php | 2 + src/world/sound/BlockPunchSound.php | 49 +++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 src/world/sound/BlockPunchSound.php diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 312a7fda9d..0a4aa37228 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -756,6 +756,7 @@ class InGamePacketHandler extends PacketHandler{ public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{ //TODO: we want to block out this packet completely, but we don't yet know the full scope of sounds that the client sends us from here switch($packet->sound){ + case LevelSoundEventPacket::SOUND_HIT: //block punch, maybe entity attack too? case LevelSoundEventPacket::SOUND_LAND: case LevelSoundEventPacket::SOUND_FALL: case LevelSoundEventPacket::SOUND_FALL_SMALL: diff --git a/src/player/Player.php b/src/player/Player.php index 0730fb1649..8cf2648fb4 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -100,6 +100,7 @@ use pocketmine\world\ChunkLoader; use pocketmine\world\format\Chunk; use pocketmine\world\particle\PunchBlockParticle; use pocketmine\world\Position; +use pocketmine\world\sound\BlockPunchSound; use pocketmine\world\World; use function abs; use function assert; @@ -1583,6 +1584,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, public function continueBreakBlock(Vector3 $pos, int $face) : void{ $block = $this->getWorld()->getBlock($pos); $this->getWorld()->addParticle($pos, new PunchBlockParticle($block, $face)); + $this->getWorld()->addSound($pos, new BlockPunchSound($block)); $this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers()); //TODO: destroy-progress level event diff --git a/src/world/sound/BlockPunchSound.php b/src/world/sound/BlockPunchSound.php new file mode 100644 index 0000000000..75b23e02cf --- /dev/null +++ b/src/world/sound/BlockPunchSound.php @@ -0,0 +1,49 @@ +block = $block; + } + + public function encode(?Vector3 $pos){ + return LevelSoundEventPacket::create( + LevelSoundEventPacket::SOUND_HIT, + $pos, + $this->block->getRuntimeId() + ); + } +} From 9615186afd61b4e5e17aa69dec23dce1d5b10e89 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 May 2020 12:36:31 +0100 Subject: [PATCH 1504/3224] rename PunchBlockParticle -> BlockPunchParticle --- src/player/Player.php | 4 ++-- .../{PunchBlockParticle.php => BlockPunchParticle.php} | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/world/particle/{PunchBlockParticle.php => BlockPunchParticle.php} (96%) diff --git a/src/player/Player.php b/src/player/Player.php index 8cf2648fb4..f682514bab 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -98,7 +98,7 @@ use pocketmine\world\ChunkListener; use pocketmine\world\ChunkListenerNoOpTrait; use pocketmine\world\ChunkLoader; use pocketmine\world\format\Chunk; -use pocketmine\world\particle\PunchBlockParticle; +use pocketmine\world\particle\BlockPunchParticle; use pocketmine\world\Position; use pocketmine\world\sound\BlockPunchSound; use pocketmine\world\World; @@ -1583,7 +1583,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, public function continueBreakBlock(Vector3 $pos, int $face) : void{ $block = $this->getWorld()->getBlock($pos); - $this->getWorld()->addParticle($pos, new PunchBlockParticle($block, $face)); + $this->getWorld()->addParticle($pos, new BlockPunchParticle($block, $face)); $this->getWorld()->addSound($pos, new BlockPunchSound($block)); $this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers()); diff --git a/src/world/particle/PunchBlockParticle.php b/src/world/particle/BlockPunchParticle.php similarity index 96% rename from src/world/particle/PunchBlockParticle.php rename to src/world/particle/BlockPunchParticle.php index ff461c87e8..11d23bcf68 100644 --- a/src/world/particle/PunchBlockParticle.php +++ b/src/world/particle/BlockPunchParticle.php @@ -30,7 +30,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; /** * This particle appears when a player is attacking a block face in survival mode attempting to break it. */ -class PunchBlockParticle implements Particle{ +class BlockPunchParticle implements Particle{ /** @var Block */ private $block; From 8682ea35f7d8c6354db8dc0fb3ed81fae5a9a336 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 May 2020 13:57:26 +0100 Subject: [PATCH 1505/3224] Introduce some (not great) API for entity animations while this API is a bit yucky, it's a step forward for protocol isolation and offers the possibility of controlling animations by adding events. --- src/entity/Entity.php | 16 ++---- src/entity/Human.php | 4 +- src/entity/Living.php | 10 ++-- src/entity/Squid.php | 4 +- src/entity/animation/Animation.php | 36 ++++++++++++++ src/entity/animation/ArmSwingAnimation.php | 43 ++++++++++++++++ src/entity/animation/ArrowShakeAnimation.php | 46 +++++++++++++++++ .../animation/ConsumingItemAnimation.php | 49 +++++++++++++++++++ src/entity/animation/CriticalHitAnimation.php | 43 ++++++++++++++++ src/entity/animation/DeathAnimation.php | 43 ++++++++++++++++ src/entity/animation/HurtAnimation.php | 43 ++++++++++++++++ src/entity/animation/RespawnAnimation.php | 43 ++++++++++++++++ .../animation/SquidInkCloudAnimation.php | 43 ++++++++++++++++ src/entity/animation/TotemUseAnimation.php | 44 +++++++++++++++++ src/entity/projectile/Arrow.php | 4 +- .../mcpe/handler/InGamePacketHandler.php | 7 +-- src/player/Player.php | 41 +++++++--------- 17 files changed, 471 insertions(+), 48 deletions(-) create mode 100644 src/entity/animation/Animation.php create mode 100644 src/entity/animation/ArmSwingAnimation.php create mode 100644 src/entity/animation/ArrowShakeAnimation.php create mode 100644 src/entity/animation/ConsumingItemAnimation.php create mode 100644 src/entity/animation/CriticalHitAnimation.php create mode 100644 src/entity/animation/DeathAnimation.php create mode 100644 src/entity/animation/HurtAnimation.php create mode 100644 src/entity/animation/RespawnAnimation.php create mode 100644 src/entity/animation/SquidInkCloudAnimation.php create mode 100644 src/entity/animation/TotemUseAnimation.php diff --git a/src/entity/Entity.php b/src/entity/Entity.php index b75d99dcd0..46e74f3b62 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -28,6 +28,7 @@ namespace pocketmine\entity; use pocketmine\block\Block; use pocketmine\block\Water; +use pocketmine\entity\animation\Animation; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDespawnEvent; use pocketmine\event\entity\EntityMotionEvent; @@ -43,9 +44,7 @@ use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; -use pocketmine\network\mcpe\protocol\ActorEventPacket; use pocketmine\network\mcpe\protocol\AddActorPacket; -use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\MoveActorAbsolutePacket; use pocketmine\network\mcpe\protocol\SetActorMotionPacket; use pocketmine\network\mcpe\protocol\types\entity\Attribute as NetworkAttribute; @@ -1692,17 +1691,10 @@ abstract class Entity{ } /** - * @param Player[]|null $players + * @param Player[]|null $targets */ - public function broadcastEntityEvent(int $eventId, ?int $eventData = null, ?array $players = null) : void{ - $this->server->broadcastPackets($players ?? $this->getViewers(), [ActorEventPacket::create($this->id, $eventId, $eventData ?? 0)]); - } - - /** - * @param Player[]|null $players - */ - public function broadcastAnimation(?array $players, int $animationId) : void{ - $this->server->broadcastPackets($players ?? $this->getViewers(), [AnimatePacket::create($this->id, $animationId)]); + public function broadcastAnimation(Animation $animation, ?array $targets = null) : void{ + $this->server->broadcastPackets($targets ?? $this->getViewers(), $animation->encode()); } public function __destruct(){ diff --git a/src/entity/Human.php b/src/entity/Human.php index 3b99ba8da7..2e647b84a9 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity; use pocketmine\block\inventory\EnderChestInventory; +use pocketmine\entity\animation\TotemUseAnimation; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\VanillaEffects; use pocketmine\entity\projectile\ProjectileSource; @@ -43,7 +44,6 @@ use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\convert\SkinAdapterSingleton; use pocketmine\network\mcpe\convert\TypeConverter; -use pocketmine\network\mcpe\protocol\ActorEventPacket; use pocketmine\network\mcpe\protocol\AddPlayerPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket; @@ -303,7 +303,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $this->effectManager->add(new EffectInstance(VanillaEffects::FIRE_RESISTANCE(), 40 * 20, 1)); $this->effectManager->add(new EffectInstance(VanillaEffects::ABSORPTION(), 5 * 20, 1)); - $this->broadcastEntityEvent(ActorEventPacket::CONSUME_TOTEM); + $this->broadcastAnimation(new TotemUseAnimation($this)); $this->getWorld()->addSound($this->location->add(0, $this->eyeHeight, 0), new TotemUseSound()); $hand = $this->inventory->getItemInHand(); diff --git a/src/entity/Living.php b/src/entity/Living.php index d41567ce5e..daa2a69c44 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -25,6 +25,9 @@ namespace pocketmine\entity; use pocketmine\block\Block; use pocketmine\block\BlockLegacyIds; +use pocketmine\entity\animation\DeathAnimation; +use pocketmine\entity\animation\HurtAnimation; +use pocketmine\entity\animation\RespawnAnimation; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\EffectManager; use pocketmine\entity\effect\VanillaEffects; @@ -46,7 +49,6 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ShortTag; -use pocketmine\network\mcpe\protocol\ActorEventPacket; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\player\Player; @@ -164,7 +166,7 @@ abstract class Living extends Entity{ parent::setHealth($amount); $this->attributeMap->get(Attribute::HEALTH)->setValue(ceil($this->getHealth()), true); if($this->isAlive() and !$wasAlive){ - $this->broadcastEntityEvent(ActorEventPacket::RESPAWN); + $this->broadcastAnimation(new RespawnAnimation($this)); } } @@ -451,7 +453,7 @@ abstract class Living extends Entity{ } protected function doHitAnimation() : void{ - $this->broadcastEntityEvent(ActorEventPacket::HURT_ANIMATION); + $this->broadcastAnimation(new HurtAnimation($this)); } public function knockBack(float $x, float $z, float $base = 0.4) : void{ @@ -504,7 +506,7 @@ abstract class Living extends Entity{ } protected function startDeathAnimation() : void{ - $this->broadcastEntityEvent(ActorEventPacket::DEATH_ANIMATION); + $this->broadcastAnimation(new DeathAnimation($this)); } protected function endDeathAnimation() : void{ diff --git a/src/entity/Squid.php b/src/entity/Squid.php index a5ec3a4077..29fe795e7a 100644 --- a/src/entity/Squid.php +++ b/src/entity/Squid.php @@ -23,12 +23,12 @@ declare(strict_types=1); namespace pocketmine\entity; +use pocketmine\entity\animation\SquidInkCloudAnimation; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\item\VanillaItems; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\protocol\ActorEventPacket; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use function atan2; use function mt_rand; @@ -71,7 +71,7 @@ class Squid extends WaterAnimal{ $this->swimDirection = $this->location->subtract($e->location)->normalize(); } - $this->broadcastEntityEvent(ActorEventPacket::SQUID_INK_CLOUD); + $this->broadcastAnimation(new SquidInkCloudAnimation($this)); } } diff --git a/src/entity/animation/Animation.php b/src/entity/animation/Animation.php new file mode 100644 index 0000000000..44dfa827bb --- /dev/null +++ b/src/entity/animation/Animation.php @@ -0,0 +1,36 @@ +entity = $entity; + } + + public function encode() : array{ + return [ + ActorEventPacket::create($this->entity->getId(), ActorEventPacket::ARM_SWING, 0) + ]; + } +} diff --git a/src/entity/animation/ArrowShakeAnimation.php b/src/entity/animation/ArrowShakeAnimation.php new file mode 100644 index 0000000000..925b93d3a8 --- /dev/null +++ b/src/entity/animation/ArrowShakeAnimation.php @@ -0,0 +1,46 @@ +arrow = $arrow; + $this->durationInTicks = $durationInTicks; + } + + public function encode() : array{ + return [ + ActorEventPacket::create($this->arrow->getId(), ActorEventPacket::ARROW_SHAKE, $this->durationInTicks) + ]; + } +} diff --git a/src/entity/animation/ConsumingItemAnimation.php b/src/entity/animation/ConsumingItemAnimation.php new file mode 100644 index 0000000000..767d22caf9 --- /dev/null +++ b/src/entity/animation/ConsumingItemAnimation.php @@ -0,0 +1,49 @@ +human = $human; + $this->item = $item; + } + + public function encode() : array{ + return [ + //TODO: need to check the data values + ActorEventPacket::create($this->human->getId(), ActorEventPacket::EATING_ITEM, ($this->item->getId() << 16) | $this->item->getMeta()) + ]; + } +} diff --git a/src/entity/animation/CriticalHitAnimation.php b/src/entity/animation/CriticalHitAnimation.php new file mode 100644 index 0000000000..f3a588b796 --- /dev/null +++ b/src/entity/animation/CriticalHitAnimation.php @@ -0,0 +1,43 @@ +entity = $entity; + } + + public function encode() : array{ + return [ + AnimatePacket::create($this->entity->getId(), AnimatePacket::ACTION_CRITICAL_HIT) + ]; + } +} diff --git a/src/entity/animation/DeathAnimation.php b/src/entity/animation/DeathAnimation.php new file mode 100644 index 0000000000..35dab4597b --- /dev/null +++ b/src/entity/animation/DeathAnimation.php @@ -0,0 +1,43 @@ +entity = $entity; + } + + public function encode() : array{ + return [ + ActorEventPacket::create($this->entity->getId(), ActorEventPacket::DEATH_ANIMATION, 0) + ]; + } +} diff --git a/src/entity/animation/HurtAnimation.php b/src/entity/animation/HurtAnimation.php new file mode 100644 index 0000000000..3ba5ebb8c6 --- /dev/null +++ b/src/entity/animation/HurtAnimation.php @@ -0,0 +1,43 @@ +entity = $entity; + } + + public function encode() : array{ + return [ + ActorEventPacket::create($this->entity->getId(), ActorEventPacket::HURT_ANIMATION, 0) + ]; + } +} diff --git a/src/entity/animation/RespawnAnimation.php b/src/entity/animation/RespawnAnimation.php new file mode 100644 index 0000000000..defb26cf72 --- /dev/null +++ b/src/entity/animation/RespawnAnimation.php @@ -0,0 +1,43 @@ +entity = $entity; + } + + public function encode() : array{ + return [ + ActorEventPacket::create($this->entity->getId(), ActorEventPacket::RESPAWN, 0) + ]; + } +} diff --git a/src/entity/animation/SquidInkCloudAnimation.php b/src/entity/animation/SquidInkCloudAnimation.php new file mode 100644 index 0000000000..fa3a9fd6b1 --- /dev/null +++ b/src/entity/animation/SquidInkCloudAnimation.php @@ -0,0 +1,43 @@ +squid = $squid; + } + + public function encode() : array{ + return [ + ActorEventPacket::create($this->squid->getId(), ActorEventPacket::SQUID_INK_CLOUD, 0) + ]; + } +} diff --git a/src/entity/animation/TotemUseAnimation.php b/src/entity/animation/TotemUseAnimation.php new file mode 100644 index 0000000000..11eb68e464 --- /dev/null +++ b/src/entity/animation/TotemUseAnimation.php @@ -0,0 +1,44 @@ +human = $human; + } + + public function encode() : array{ + return [ + ActorEventPacket::create($this->human->getId(), ActorEventPacket::CONSUME_TOTEM, 0) + ]; + } +} diff --git a/src/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php index 86d3acfa9e..cbf1e5ba79 100644 --- a/src/entity/projectile/Arrow.php +++ b/src/entity/projectile/Arrow.php @@ -24,13 +24,13 @@ declare(strict_types=1); namespace pocketmine\entity\projectile; use pocketmine\block\Block; +use pocketmine\entity\animation\ArrowShakeAnimation; use pocketmine\entity\Entity; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\event\inventory\InventoryPickupArrowEvent; use pocketmine\item\VanillaItems; use pocketmine\math\RayTraceResult; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\protocol\ActorEventPacket; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\player\Player; @@ -140,7 +140,7 @@ class Arrow extends Projectile{ protected function onHitBlock(Block $blockHit, RayTraceResult $hitResult) : void{ parent::onHitBlock($blockHit, $hitResult); - $this->broadcastEntityEvent(ActorEventPacket::ARROW_SHAKE, 7); //7 ticks + $this->broadcastAnimation(new ArrowShakeAnimation($this, 7)); } protected function onHitEntity(Entity $entityHit, RayTraceResult $hitResult) : void{ diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 0a4aa37228..f121d2bd2a 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\handler; use pocketmine\block\ItemFrame; use pocketmine\block\Sign; use pocketmine\block\utils\SignText; +use pocketmine\entity\animation\ConsumingItemAnimation; use pocketmine\event\player\PlayerEditBookEvent; use pocketmine\inventory\transaction\action\InventoryAction; use pocketmine\inventory\transaction\CraftingTransaction; @@ -158,11 +159,11 @@ class InGamePacketHandler extends PacketHandler{ switch($packet->event){ case ActorEventPacket::EATING_ITEM: //TODO: ignore this and handle it server-side - if($packet->data === 0){ + $item = $this->player->getInventory()->getItemInHand(); + if($item->isNull()){ return false; } - - $this->player->broadcastEntityEvent(ActorEventPacket::EATING_ITEM, $packet->data); + $this->player->broadcastAnimation(new ConsumingItemAnimation($this->player, $this->player->getInventory()->getItemInHand())); break; default: return false; diff --git a/src/player/Player.php b/src/player/Player.php index f682514bab..2cce880e8d 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -29,10 +29,14 @@ use pocketmine\block\UnknownBlock; use pocketmine\block\VanillaBlocks; use pocketmine\command\CommandSender; use pocketmine\crafting\CraftingGrid; +use pocketmine\entity\animation\Animation; +use pocketmine\entity\animation\ArmSwingAnimation; +use pocketmine\entity\animation\CriticalHitAnimation; use pocketmine\entity\effect\VanillaEffects; use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; use pocketmine\entity\Human; +use pocketmine\entity\Living; use pocketmine\entity\object\ItemEntity; use pocketmine\entity\projectile\Arrow; use pocketmine\entity\Skin; @@ -80,7 +84,6 @@ use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\NetworkSession; -use pocketmine\network\mcpe\protocol\ActorEventPacket; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; @@ -995,7 +998,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->getWorld()->setSleepTicks(0); - $this->broadcastAnimation([$this], AnimatePacket::ACTION_STOP_SLEEP); + $this->networkSession->sendDataPacket(AnimatePacket::create($this->getId(), AnimatePacket::ACTION_STOP_SLEEP)); } } @@ -1559,7 +1562,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($ev->isCancelled()){ return false; } - $this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers()); + $this->broadcastAnimation(new ArmSwingAnimation($this), $this->getViewers()); if($target->onAttack($this->inventory->getItemInHand(), $face, $this)){ return true; } @@ -1585,7 +1588,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $block = $this->getWorld()->getBlock($pos); $this->getWorld()->addParticle($pos, new BlockPunchParticle($block, $face)); $this->getWorld()->addSound($pos, new BlockPunchSound($block)); - $this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers()); + $this->broadcastAnimation(new ArmSwingAnimation($this), $this->getViewers()); //TODO: destroy-progress level event } @@ -1603,7 +1606,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->doCloseInventory(); if($this->canInteract($pos->add(0.5, 0.5, 0.5), $this->isCreative() ? 13 : 7) and !$this->isSpectator()){ - $this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers()); + $this->broadcastAnimation(new ArmSwingAnimation($this), $this->getViewers()); $item = $this->inventory->getItemInHand(); $oldItem = clone $item; if($this->getWorld()->useBreakOn($pos, $item, $this, true)){ @@ -1627,7 +1630,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->setUsingItem(false); if($this->canInteract($pos->add(0.5, 0.5, 0.5), 13) and !$this->isSpectator()){ - $this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers()); + $this->broadcastAnimation(new ArmSwingAnimation($this), $this->getViewers()); $item = $this->inventory->getItemInHand(); //this is a copy of the real item $oldItem = clone $item; if($this->getWorld()->useItemOn($pos, $item, $face, $clickOffset, $this, true)){ @@ -1686,10 +1689,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($ev->isCancelled()){ return false; } - $this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers()); + $this->broadcastAnimation(new ArmSwingAnimation($this), $this->getViewers()); - if($ev->getModifier(EntityDamageEvent::MODIFIER_CRITICAL) > 0){ - $entity->broadcastAnimation(null, AnimatePacket::ACTION_CRITICAL_HIT); + if($ev->getModifier(EntityDamageEvent::MODIFIER_CRITICAL) > 0 and $entity instanceof Living){ + $entity->broadcastAnimation(new CriticalHitAnimation($entity)); } foreach($meleeEnchantments as $enchantment){ @@ -1756,7 +1759,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * Drops an item on the ground in front of the player. */ public function dropItem(Item $item) : void{ - $this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers()); + $this->broadcastAnimation(new ArmSwingAnimation($this), $this->getViewers()); $this->getWorld()->dropItem($this->location->add(0, 1.3, 0), $item, $this->getDirectionVector()->multiply(0.4), 40); } @@ -2172,20 +2175,12 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->networkProperties->setBlockPos(EntityMetadataProperties::PLAYER_BED_POSITION, $this->sleeping ?? new Vector3(0, 0, 0)); } - public function broadcastEntityEvent(int $eventId, ?int $eventData = null, ?array $players = null) : void{ - if($this->spawned and $players === null){ - $players = $this->getViewers(); - $players[] = $this; + public function broadcastAnimation(Animation $animation, ?array $targets = null) : void{ + if($this->spawned and $targets === null){ + $targets = $this->getViewers(); + $targets[] = $this; } - parent::broadcastEntityEvent($eventId, $eventData, $players); - } - - public function broadcastAnimation(?array $players, int $animationId) : void{ - if($this->spawned and $players === null){ - $players = $this->getViewers(); - $players[] = $this; - } - parent::broadcastAnimation($players, $animationId); + parent::broadcastAnimation($animation, $targets); } public function getOffsetPosition(Vector3 $vector3) : Vector3{ From 6e6fffa4613b9dcbc26762c76f64d29abc71d001 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 May 2020 21:44:45 +0100 Subject: [PATCH 1506/3224] Inventory: added removeAllListeners() this isn't strictly necessary because it could be done by removeListeners(...getListeners()), but I think developers will appreciate not needing so much boilerplate code. --- src/inventory/BaseInventory.php | 4 ++++ src/inventory/Inventory.php | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/inventory/BaseInventory.php b/src/inventory/BaseInventory.php index dcf620bfd4..63ecb4d8f6 100644 --- a/src/inventory/BaseInventory.php +++ b/src/inventory/BaseInventory.php @@ -384,6 +384,10 @@ abstract class BaseInventory implements Inventory{ } } + public function removeAllListeners() : void{ + $this->listeners = []; + } + public function getListeners() : array{ return $this->listeners; } diff --git a/src/inventory/Inventory.php b/src/inventory/Inventory.php index 17be0db27a..95ea5001a2 100644 --- a/src/inventory/Inventory.php +++ b/src/inventory/Inventory.php @@ -164,6 +164,8 @@ interface Inventory{ */ public function removeListeners(InventoryListener ...$listeners) : void; + public function removeAllListeners() : void; + /** * @return InventoryListener[] */ From f34753c4968f35b353c149c1a3da786bd9c790a7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 May 2020 21:48:32 +0100 Subject: [PATCH 1507/3224] CallbackInventoryListener: fix crash when any of the callbacks isn't provided --- src/inventory/CallbackInventoryListener.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/inventory/CallbackInventoryListener.php b/src/inventory/CallbackInventoryListener.php index 3bb1efdce0..8d08c4c78f 100644 --- a/src/inventory/CallbackInventoryListener.php +++ b/src/inventory/CallbackInventoryListener.php @@ -72,13 +72,17 @@ class CallbackInventoryListener implements InventoryListener{ } public function onSlotChange(Inventory $inventory, int $slot, Item $oldItem) : void{ - ($this->onSlotChangeCallback)($inventory, $slot, $oldItem); + if($this->onSlotChangeCallback !== null){ + ($this->onSlotChangeCallback)($inventory, $slot, $oldItem); + } } /** * @param Item[] $oldContents */ public function onContentChange(Inventory $inventory, array $oldContents) : void{ - ($this->onContentChangeCallback)($inventory, $oldContents); + if($this->onContentChangeCallback !== null){ + ($this->onContentChangeCallback)($inventory, $oldContents); + } } } From b1021315b0e3adbd763e8607e0a7e600c6cffb00 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 4 May 2020 02:28:34 +0100 Subject: [PATCH 1508/3224] World: remove protocol-specialized broadcastLevelEvent() --- src/player/Player.php | 4 ++-- src/world/World.php | 14 -------------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 2cce880e8d..32ff6a2ddf 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1577,7 +1577,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, //TODO: improve this to take stuff like swimming, ladders, enchanted tools into account, fix wrong tool break time calculations for bad tools (pmmp/PocketMine-MP#211) $breakTime = ceil($target->getBreakInfo()->getBreakTime($this->inventory->getItemInHand()) * 20); if($breakTime > 0){ - $this->getWorld()->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_START_BREAK, (int) (65535 / $breakTime)); + $this->getWorld()->broadcastPacketToViewers($pos, LevelEventPacket::create(LevelEventPacket::EVENT_BLOCK_START_BREAK, (int) (65535 / $breakTime), $pos)); } } @@ -1594,7 +1594,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } public function stopBreakBlock(Vector3 $pos) : void{ - $this->getWorld()->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_STOP_BREAK); + $this->getWorld()->broadcastPacketToViewers($pos, LevelEventPacket::create(LevelEventPacket::EVENT_BLOCK_STOP_BREAK, 0, $pos)); } /** diff --git a/src/world/World.php b/src/world/World.php index ae4214f9c7..022c64b3b4 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -477,20 +477,6 @@ class World implements ChunkManager{ } } - /** - * Broadcasts a LevelEvent to players in the area. This could be sound, particles, weather changes, etc. - * - * @param Vector3|null $pos If null, broadcasts to every player in the World - */ - public function broadcastLevelEvent(?Vector3 $pos, int $evid, int $data = 0) : void{ - $pk = LevelEventPacket::create($evid, $data, $pos); - if($pos !== null){ - $this->broadcastPacketToViewers($pos, $pk); - }else{ - $this->broadcastGlobalPacket($pk); - } - } - public function getAutoSave() : bool{ return $this->autoSave; } From c490bc5a8c1178dc7b5e22c2ed4ce7be4f09fd8e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 4 May 2020 02:31:19 +0100 Subject: [PATCH 1509/3224] World: drop global packet broadcast --- src/world/World.php | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 022c64b3b4..24a063f9dc 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -168,8 +168,6 @@ class World implements ChunkManager{ /** @var ClientboundPacket[][] */ private $chunkPackets = []; - /** @var ClientboundPacket[] */ - private $globalPackets = []; /** @var float[] */ private $unloadQueue = []; @@ -534,13 +532,6 @@ class World implements ChunkManager{ $this->addChunkPacket($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4, $packet); } - /** - * Broadcasts a packet to every player in the world. - */ - public function broadcastGlobalPacket(ClientboundPacket $packet) : void{ - $this->globalPackets[] = $packet; - } - public function registerChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ, bool $autoLoad = true) : void{ $loaderId = spl_object_id($loader); @@ -783,13 +774,6 @@ class World implements ChunkManager{ $this->checkSleep(); } - if(count($this->globalPackets) > 0){ - if(count($this->players) > 0){ - $this->server->broadcastPackets($this->players, $this->globalPackets); - } - $this->globalPackets = []; - } - foreach($this->chunkPackets as $index => $entries){ World::getXZ($index, $chunkX, $chunkZ); $chunkPlayers = $this->getChunkPlayers($chunkX, $chunkZ); From aac017eae4e41bfd91d1aef32c41eb792963ef92 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 4 May 2020 10:22:39 +0100 Subject: [PATCH 1510/3224] World: drop unused and very misleadingly named addChunkPacket() --- src/world/World.php | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 24a063f9dc..e1caee8cb1 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -514,24 +514,16 @@ class World implements ChunkManager{ } /** - * Queues a packet to be sent to all players using the chunk at the specified X/Z coordinates at the end of the - * current tick. + * Broadcasts a packet to every player who has the target position within their view distance. */ - public function addChunkPacket(int $chunkX, int $chunkZ, ClientboundPacket $packet) : void{ - if(!isset($this->chunkPackets[$index = World::chunkHash($chunkX, $chunkZ)])){ + public function broadcastPacketToViewers(Vector3 $pos, ClientboundPacket $packet) : void{ + if(!isset($this->chunkPackets[$index = World::chunkHash($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4)])){ $this->chunkPackets[$index] = [$packet]; }else{ $this->chunkPackets[$index][] = $packet; } } - /** - * Broadcasts a packet to every player who has the target position within their view distance. - */ - public function broadcastPacketToViewers(Vector3 $pos, ClientboundPacket $packet) : void{ - $this->addChunkPacket($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4, $packet); - } - public function registerChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ, bool $autoLoad = true) : void{ $loaderId = spl_object_id($loader); From d40152e3bbeb9b46662b373729085619511b9479 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 4 May 2020 11:23:44 +0100 Subject: [PATCH 1511/3224] World: fix time sync --- src/world/World.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index e1caee8cb1..a17a459a02 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -629,6 +629,9 @@ class World implements ChunkManager{ * @param Player ...$targets If empty, will send to all players in the world. */ public function sendTime(Player ...$targets) : void{ + if(count($targets) === 0){ + $targets = $this->players; + } foreach($targets as $player){ $player->getNetworkSession()->syncWorldTime($this->time); } From d3dcb8a4e3482c78aac1f58a9118fb4ccb8e5986 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 4 May 2020 11:50:42 +0100 Subject: [PATCH 1512/3224] moving entity attack sounds to server-side --- .../mcpe/handler/InGamePacketHandler.php | 3 ++ src/player/Player.php | 5 +++ src/world/sound/EntityAttackNoDamageSound.php | 43 +++++++++++++++++++ src/world/sound/EntityAttackSound.php | 43 +++++++++++++++++++ 4 files changed, 94 insertions(+) create mode 100644 src/world/sound/EntityAttackNoDamageSound.php create mode 100644 src/world/sound/EntityAttackSound.php diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index f121d2bd2a..96355daf75 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -757,6 +757,9 @@ class InGamePacketHandler extends PacketHandler{ public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{ //TODO: we want to block out this packet completely, but we don't yet know the full scope of sounds that the client sends us from here switch($packet->sound){ + case LevelSoundEventPacket::SOUND_ATTACK: + case LevelSoundEventPacket::SOUND_ATTACK_NODAMAGE: + case LevelSoundEventPacket::SOUND_ATTACK_STRONG: //TODO: reassess this, seems like the regular attack is never used ?? case LevelSoundEventPacket::SOUND_HIT: //block punch, maybe entity attack too? case LevelSoundEventPacket::SOUND_LAND: case LevelSoundEventPacket::SOUND_FALL: diff --git a/src/player/Player.php b/src/player/Player.php index 32ff6a2ddf..a657be6a43 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -104,6 +104,8 @@ use pocketmine\world\format\Chunk; use pocketmine\world\particle\BlockPunchParticle; use pocketmine\world\Position; use pocketmine\world\sound\BlockPunchSound; +use pocketmine\world\sound\EntityAttackNoDamageSound; +use pocketmine\world\sound\EntityAttackSound; use pocketmine\world\World; use function abs; use function assert; @@ -1686,10 +1688,13 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $entity->attack($ev); + $soundPos = $entity->getPosition()->add(0, $entity->width / 2, 0); if($ev->isCancelled()){ + $this->getWorld()->addSound($soundPos, new EntityAttackNoDamageSound()); return false; } $this->broadcastAnimation(new ArmSwingAnimation($this), $this->getViewers()); + $this->getWorld()->addSound($soundPos, new EntityAttackSound()); if($ev->getModifier(EntityDamageEvent::MODIFIER_CRITICAL) > 0 and $entity instanceof Living){ $entity->broadcastAnimation(new CriticalHitAnimation($entity)); diff --git a/src/world/sound/EntityAttackNoDamageSound.php b/src/world/sound/EntityAttackNoDamageSound.php new file mode 100644 index 0000000000..8c2fde1cbb --- /dev/null +++ b/src/world/sound/EntityAttackNoDamageSound.php @@ -0,0 +1,43 @@ + Date: Mon, 4 May 2020 11:58:57 +0100 Subject: [PATCH 1513/3224] World: remove unused import we're getting so close !!! --- src/world/World.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index a17a459a02..054737ce97 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -53,7 +53,6 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\BlockActorDataPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; -use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; use pocketmine\player\Player; use pocketmine\Server; From c2857a91bd99b2a45b5a8dd72850d2f8bd0a1074 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 4 May 2020 12:14:27 +0100 Subject: [PATCH 1514/3224] [Network]ChunkSerializer: allow injecting RuntimeBlockMapping this will allow the same serializer to be reused with different mapping tables (will be needed for multi version). --- src/network/mcpe/ChunkRequestTask.php | 3 ++- src/network/mcpe/serializer/ChunkSerializer.php | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php index a8b135d97b..d90e0cd32d 100644 --- a/src/network/mcpe/ChunkRequestTask.php +++ b/src/network/mcpe/ChunkRequestTask.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe; use pocketmine\network\mcpe\compression\CompressBatchPromise; use pocketmine\network\mcpe\compression\Compressor; +use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\LevelChunkPacket; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\serializer\ChunkSerializer; @@ -67,7 +68,7 @@ class ChunkRequestTask extends AsyncTask{ public function onRun() : void{ $chunk = FastChunkSerializer::deserialize($this->chunk); $subCount = ChunkSerializer::getSubChunkCount($chunk); - $payload = ChunkSerializer::serialize($chunk, $this->tiles); + $payload = ChunkSerializer::serialize($chunk, RuntimeBlockMapping::getInstance(), $this->tiles); $this->setResult($this->compressor->compress(PacketBatch::fromPackets(LevelChunkPacket::withoutCache($this->chunkX, $this->chunkZ, $subCount, $payload))->getBuffer())); } diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index c2a1d0fdf6..9b7a4a9bc2 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -51,10 +51,9 @@ final class ChunkSerializer{ return 0; } - public static function serialize(Chunk $chunk, ?string $tiles = null) : string{ + public static function serialize(Chunk $chunk, RuntimeBlockMapping $blockMapper, ?string $tiles = null) : string{ $stream = new NetworkBinaryStream(); $subChunkCount = self::getSubChunkCount($chunk); - $blockMapper = RuntimeBlockMapping::getInstance(); for($y = 0; $y < $subChunkCount; ++$y){ $layers = $chunk->getSubChunk($y)->getBlockLayers(); $stream->putByte(8); //version From a73c54bdd02debf94ecb5f1297d2d12040452252 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 4 May 2020 12:35:13 +0100 Subject: [PATCH 1515/3224] making tile spawn compound cache use CacheableNbt instead of strings --- src/block/tile/Spawnable.php | 17 ++++++------- .../mcpe/handler/InGamePacketHandler.php | 14 ++++------- .../mcpe/protocol/BlockActorDataPacket.php | 25 ++++++++++++++++--- .../mcpe/serializer/ChunkSerializer.php | 2 +- .../phpstan/configs/runtime-type-checks.neon | 5 ++++ 5 files changed, 40 insertions(+), 23 deletions(-) diff --git a/src/block/tile/Spawnable.php b/src/block/tile/Spawnable.php index 3204c8cf54..a4851b04f1 100644 --- a/src/block/tile/Spawnable.php +++ b/src/block/tile/Spawnable.php @@ -24,12 +24,15 @@ declare(strict_types=1); namespace pocketmine\block\tile; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; +use pocketmine\network\mcpe\protocol\types\CacheableNbt; use function get_class; abstract class Spawnable extends Tile{ - /** @var string|null */ + /** + * @var CacheableNbt|null + * @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag>|null + */ private $spawnCompoundCache = null; /** @var bool */ private $dirty = true; //default dirty, until it's been spawned appropriately on the world @@ -55,15 +58,11 @@ abstract class Spawnable extends Tile{ * Returns encoded NBT (varint, little-endian) used to spawn this tile to clients. Uses cache where possible, * populates cache if it is null. * - * @return string encoded NBT + * @phpstan-return CacheableNbt<\pocketmine\nbt\tag\CompoundTag> */ - final public function getSerializedSpawnCompound() : string{ + final public function getSerializedSpawnCompound() : CacheableNbt{ if($this->spawnCompoundCache === null){ - if(self::$nbtWriter === null){ - self::$nbtWriter = new NetworkNbtSerializer(); - } - - $this->spawnCompoundCache = self::$nbtWriter->write(new TreeRoot($this->getSpawnCompound())); + $this->spawnCompoundCache = new CacheableNbt($this->getSpawnCompound()); } return $this->spawnCompoundCache; diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 96355daf75..665a080697 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -36,7 +36,7 @@ use pocketmine\item\VanillaItems; use pocketmine\item\WritableBook; use pocketmine\item\WrittenBook; use pocketmine\math\Vector3; -use pocketmine\nbt\NbtDataException; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\convert\SkinAdapterSingleton; @@ -72,7 +72,6 @@ use pocketmine\network\mcpe\protocol\PlayerHotbarPacket; use pocketmine\network\mcpe\protocol\PlayerInputPacket; use pocketmine\network\mcpe\protocol\PlayerSkinPacket; use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; -use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; use pocketmine\network\mcpe\protocol\ServerSettingsRequestPacket; use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; use pocketmine\network\mcpe\protocol\ShowCreditsPacket; @@ -87,6 +86,7 @@ use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\UseItemOnEntityTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\UseItemTransactionData; use pocketmine\player\Player; +use pocketmine\utils\AssumptionFailedError; use function array_push; use function base64_encode; use function count; @@ -554,12 +554,8 @@ class InGamePacketHandler extends PacketHandler{ } $block = $this->player->getLocation()->getWorldNonNull()->getBlock($pos); - try{ - $offset = 0; - $nbt = (new NetworkNbtSerializer())->read($packet->namedtag, $offset, 512)->mustGetCompoundTag(); - }catch(NbtDataException $e){ - throw BadPacketException::wrap($e); - } + $nbt = $packet->namedtag->getRoot(); + if(!($nbt instanceof CompoundTag)) throw new AssumptionFailedError("PHPStan should ensure this is a CompoundTag"); //for phpstorm's benefit if($block instanceof Sign){ if($nbt->hasTag("Text", StringTag::class)){ @@ -580,7 +576,7 @@ class InGamePacketHandler extends PacketHandler{ return true; } - $this->session->getLogger()->debug("Invalid sign update data: " . base64_encode($packet->namedtag)); + $this->session->getLogger()->debug("Invalid sign update data: " . base64_encode($packet->namedtag->getEncodedNbt())); } return false; diff --git a/src/network/mcpe/protocol/BlockActorDataPacket.php b/src/network/mcpe/protocol/BlockActorDataPacket.php index 8c9bfaf69f..54ac3fc8bb 100644 --- a/src/network/mcpe/protocol/BlockActorDataPacket.php +++ b/src/network/mcpe/protocol/BlockActorDataPacket.php @@ -25,7 +25,10 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\nbt\NbtDataException; use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; +use pocketmine\network\mcpe\protocol\types\CacheableNbt; class BlockActorDataPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::BLOCK_ACTOR_DATA_PACKET; @@ -36,10 +39,16 @@ class BlockActorDataPacket extends DataPacket implements ClientboundPacket, Serv public $y; /** @var int */ public $z; - /** @var string */ + /** + * @var CacheableNbt + * @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag> + */ public $namedtag; - public static function create(int $x, int $y, int $z, string $nbt) : self{ + /** + * @phpstan-param CacheableNbt<\pocketmine\nbt\tag\CompoundTag> $nbt + */ + public static function create(int $x, int $y, int $z, CacheableNbt $nbt) : self{ $result = new self; [$result->x, $result->y, $result->z] = [$x, $y, $z]; $result->namedtag = $nbt; @@ -48,12 +57,20 @@ class BlockActorDataPacket extends DataPacket implements ClientboundPacket, Serv protected function decodePayload(NetworkBinaryStream $in) : void{ $in->getBlockPosition($this->x, $this->y, $this->z); - $this->namedtag = $in->getRemaining(); + try{ + $offset = $in->getOffset(); + $this->namedtag = new CacheableNbt( + (new NetworkNbtSerializer())->read($this->getBinaryStream()->getBuffer(), $offset, 512)->mustGetCompoundTag() + ); + $in->setOffset($offset); + }catch(NbtDataException $e){ + throw PacketDecodeException::wrap($e, "Failed decoding block actor NBT"); + } } protected function encodePayload(NetworkBinaryStream $out) : void{ $out->putBlockPosition($this->x, $this->y, $this->z); - $out->put($this->namedtag); + $out->put($this->namedtag->getEncodedNbt()); } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index 9b7a4a9bc2..94ce8e89ce 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -90,7 +90,7 @@ final class ChunkSerializer{ $stream = new BinaryStream(); foreach($chunk->getTiles() as $tile){ if($tile instanceof Spawnable){ - $stream->put($tile->getSerializedSpawnCompound()); + $stream->put($tile->getSerializedSpawnCompound()->getEncodedNbt()); } } diff --git a/tests/phpstan/configs/runtime-type-checks.neon b/tests/phpstan/configs/runtime-type-checks.neon index b0579c90d1..de922a304f 100644 --- a/tests/phpstan/configs/runtime-type-checks.neon +++ b/tests/phpstan/configs/runtime-type-checks.neon @@ -30,6 +30,11 @@ parameters: count: 3 path: ../../../src/item/Item.php + - + message: "#^Instanceof between pocketmine\\\\nbt\\\\tag\\\\CompoundTag and pocketmine\\\\nbt\\\\tag\\\\CompoundTag will always evaluate to true\\.$#" + count: 1 + path: ../../../src/network/mcpe/handler/InGamePacketHandler.php + - message: "#^Call to function is_array\\(\\) with array\\ will always evaluate to true\\.$#" count: 1 From 0eec536f97a799ac3fc51b56266f10f51caee38d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 4 May 2020 13:10:23 +0100 Subject: [PATCH 1516/3224] Spawnable: remove unused field --- src/block/tile/Spawnable.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/block/tile/Spawnable.php b/src/block/tile/Spawnable.php index a4851b04f1..c81b71138d 100644 --- a/src/block/tile/Spawnable.php +++ b/src/block/tile/Spawnable.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\block\tile; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; use pocketmine\network\mcpe\protocol\types\CacheableNbt; use function get_class; @@ -37,9 +36,6 @@ abstract class Spawnable extends Tile{ /** @var bool */ private $dirty = true; //default dirty, until it's been spawned appropriately on the world - /** @var NetworkNbtSerializer|null */ - private static $nbtWriter = null; - /** * Returns whether the tile needs to be respawned to viewers. */ From fcd6a69000f28cb9d0febc82b8ae4af4b51f418b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 4 May 2020 13:23:29 +0100 Subject: [PATCH 1517/3224] cleaning up NBT handling on packet decode/encode now we always decode, because it's not safe to assume that we can just grab the rest of the bytes in the packet. --- .../AvailableActorIdentifiersPacket.php | 10 +------- .../protocol/BiomeDefinitionListPacket.php | 10 +------- .../mcpe/protocol/BlockActorDataPacket.php | 12 +-------- .../mcpe/protocol/LevelEventGenericPacket.php | 19 ++++++++------ src/network/mcpe/protocol/StartGamePacket.php | 5 +--- .../StructureTemplateDataResponsePacket.php | 10 +++++--- .../protocol/UpdateBlockPropertiesPacket.php | 23 ++++++++++------- .../mcpe/protocol/UpdateEquipPacket.php | 10 +++++--- .../mcpe/protocol/UpdateTradePacket.php | 10 +++++--- .../serializer/NetworkBinaryStream.php | 25 +++++++++++++++---- .../entity/CompoundTagMetadataProperty.php | 10 +------- 11 files changed, 72 insertions(+), 72 deletions(-) diff --git a/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php b/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php index 4d2a1cade0..4f79632488 100644 --- a/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php +++ b/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php @@ -25,9 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\nbt\NbtDataException; use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; -use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; use pocketmine\network\mcpe\protocol\types\CacheableNbt; class AvailableActorIdentifiersPacket extends DataPacket implements ClientboundPacket{ @@ -49,13 +47,7 @@ class AvailableActorIdentifiersPacket extends DataPacket implements ClientboundP } protected function decodePayload(NetworkBinaryStream $in) : void{ - $offset = $in->getOffset(); - try{ - $this->identifiers = new CacheableNbt((new NetworkNbtSerializer())->read($in->getBuffer(), $offset)->mustGetCompoundTag()); - }catch(NbtDataException $e){ - throw PacketDecodeException::wrap($e, "Failed decoding actor identifiers"); - } - $in->setOffset($offset); + $this->identifiers = new CacheableNbt($in->getNbtCompoundRoot()); } protected function encodePayload(NetworkBinaryStream $out) : void{ diff --git a/src/network/mcpe/protocol/BiomeDefinitionListPacket.php b/src/network/mcpe/protocol/BiomeDefinitionListPacket.php index 0388c11093..52afb205f5 100644 --- a/src/network/mcpe/protocol/BiomeDefinitionListPacket.php +++ b/src/network/mcpe/protocol/BiomeDefinitionListPacket.php @@ -25,9 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\nbt\NbtDataException; use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; -use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; use pocketmine\network\mcpe\protocol\types\CacheableNbt; class BiomeDefinitionListPacket extends DataPacket implements ClientboundPacket{ @@ -49,13 +47,7 @@ class BiomeDefinitionListPacket extends DataPacket implements ClientboundPacket{ } protected function decodePayload(NetworkBinaryStream $in) : void{ - $offset = $in->getOffset(); - try{ - $this->defs = new CacheableNbt((new NetworkNbtSerializer())->read($in->getBuffer(), $offset)->mustGetCompoundTag()); - }catch(NbtDataException $e){ - throw PacketDecodeException::wrap($e, "Failed decoding biome definitions"); - } - $in->setOffset($offset); + $this->defs = new CacheableNbt($in->getNbtCompoundRoot()); } protected function encodePayload(NetworkBinaryStream $out) : void{ diff --git a/src/network/mcpe/protocol/BlockActorDataPacket.php b/src/network/mcpe/protocol/BlockActorDataPacket.php index 54ac3fc8bb..e5a71d747d 100644 --- a/src/network/mcpe/protocol/BlockActorDataPacket.php +++ b/src/network/mcpe/protocol/BlockActorDataPacket.php @@ -25,9 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\nbt\NbtDataException; use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; -use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; use pocketmine\network\mcpe\protocol\types\CacheableNbt; class BlockActorDataPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -57,15 +55,7 @@ class BlockActorDataPacket extends DataPacket implements ClientboundPacket, Serv protected function decodePayload(NetworkBinaryStream $in) : void{ $in->getBlockPosition($this->x, $this->y, $this->z); - try{ - $offset = $in->getOffset(); - $this->namedtag = new CacheableNbt( - (new NetworkNbtSerializer())->read($this->getBinaryStream()->getBuffer(), $offset, 512)->mustGetCompoundTag() - ); - $in->setOffset($offset); - }catch(NbtDataException $e){ - throw PacketDecodeException::wrap($e, "Failed decoding block actor NBT"); - } + $this->namedtag = new CacheableNbt($in->getNbtCompoundRoot()); } protected function encodePayload(NetworkBinaryStream $out) : void{ diff --git a/src/network/mcpe/protocol/LevelEventGenericPacket.php b/src/network/mcpe/protocol/LevelEventGenericPacket.php index 29be8b4fc7..ade936c3e3 100644 --- a/src/network/mcpe/protocol/LevelEventGenericPacket.php +++ b/src/network/mcpe/protocol/LevelEventGenericPacket.php @@ -26,22 +26,24 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; -use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; +use pocketmine\network\mcpe\protocol\types\CacheableNbt; class LevelEventGenericPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::LEVEL_EVENT_GENERIC_PACKET; /** @var int */ private $eventId; - /** @var string network-format NBT */ + /** + * @var CacheableNbt + * @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag> + */ private $eventData; public static function create(int $eventId, CompoundTag $data) : self{ $result = new self; $result->eventId = $eventId; - $result->eventData = (new NetworkNbtSerializer())->write(new TreeRoot($data)); + $result->eventData = new CacheableNbt($data); return $result; } @@ -49,18 +51,21 @@ class LevelEventGenericPacket extends DataPacket implements ClientboundPacket{ return $this->eventId; } - public function getEventData() : string{ + /** + * @phpstan-return CacheableNbt<\pocketmine\nbt\tag\CompoundTag> + */ + public function getEventData() : CacheableNbt{ return $this->eventData; } protected function decodePayload(NetworkBinaryStream $in) : void{ $this->eventId = $in->getVarInt(); - $this->eventData = $in->getRemaining(); + $this->eventData = new CacheableNbt($in->getNbtCompoundRoot()); } protected function encodePayload(NetworkBinaryStream $out) : void{ $out->putVarInt($this->eventId); - $out->put($this->eventData); + $out->put($this->eventData->getEncodedNbt()); } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/network/mcpe/protocol/StartGamePacket.php b/src/network/mcpe/protocol/StartGamePacket.php index 0d06bc9397..1ebae773b3 100644 --- a/src/network/mcpe/protocol/StartGamePacket.php +++ b/src/network/mcpe/protocol/StartGamePacket.php @@ -28,7 +28,6 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; -use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; use pocketmine\network\mcpe\protocol\types\CacheableNbt; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use function count; @@ -214,9 +213,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{ $this->enchantmentSeed = $in->getVarInt(); - $offset = $in->getOffset(); - $blockTable = (new NetworkNbtSerializer())->read($in->getBuffer(), $offset, 512)->getTag(); - $in->setOffset($offset); + $blockTable = $in->getNbtRoot()->getTag(); if(!($blockTable instanceof ListTag)){ throw new \UnexpectedValueException("Wrong block table root NBT tag type"); } diff --git a/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php b/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php index 9d576e1a50..fbbd2c4fb5 100644 --- a/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php +++ b/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php @@ -26,19 +26,23 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\types\CacheableNbt; class StructureTemplateDataResponsePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::STRUCTURE_TEMPLATE_DATA_RESPONSE_PACKET; /** @var string */ public $structureTemplateName; - /** @var string|null */ + /** + * @var CacheableNbt|null + * @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag> + */ public $namedtag; protected function decodePayload(NetworkBinaryStream $in) : void{ $this->structureTemplateName = $in->getString(); if($in->getBool()){ - $this->namedtag = $in->getRemaining(); + $this->namedtag = new CacheableNbt($in->getNbtCompoundRoot()); } } @@ -46,7 +50,7 @@ class StructureTemplateDataResponsePacket extends DataPacket implements Clientbo $out->putString($this->structureTemplateName); $out->putBool($this->namedtag !== null); if($this->namedtag !== null){ - $out->put($this->namedtag); + $out->put($this->namedtag->getEncodedNbt()); } } diff --git a/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php b/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php index 07131bdf70..e7b018ee5e 100644 --- a/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php +++ b/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php @@ -26,32 +26,37 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; -use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; +use pocketmine\network\mcpe\protocol\types\CacheableNbt; class UpdateBlockPropertiesPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_BLOCK_PROPERTIES_PACKET; - /** @var string */ - private $nbt; + /** + * @var CacheableNbt + * @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag> + */ + private $blockProperties; public static function create(CompoundTag $data) : self{ $result = new self; - $result->nbt = (new NetworkNbtSerializer())->write(new TreeRoot($data)); + $result->blockProperties = new CacheableNbt($data); return $result; } - public function getNbt() : string{ - return $this->nbt; + /** + * @phpstan-return CacheableNbt<\pocketmine\nbt\tag\CompoundTag> + */ + public function getBlockProperties() : CacheableNbt{ + return $this->blockProperties; } protected function decodePayload(NetworkBinaryStream $in) : void{ - $this->nbt = $in->getRemaining(); + $this->blockProperties = new CacheableNbt($in->getNbtCompoundRoot()); } protected function encodePayload(NetworkBinaryStream $out) : void{ - $out->put($this->nbt); + $out->put($this->blockProperties->getEncodedNbt()); } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/network/mcpe/protocol/UpdateEquipPacket.php b/src/network/mcpe/protocol/UpdateEquipPacket.php index a6a6a5114a..a4aa6a2eac 100644 --- a/src/network/mcpe/protocol/UpdateEquipPacket.php +++ b/src/network/mcpe/protocol/UpdateEquipPacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\types\CacheableNbt; class UpdateEquipPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_EQUIP_PACKET; @@ -38,7 +39,10 @@ class UpdateEquipPacket extends DataPacket implements ClientboundPacket{ public $windowSlotCount; //useless, seems to be part of a standard container header /** @var int */ public $entityUniqueId; - /** @var string */ + /** + * @var CacheableNbt + * @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag> + */ public $namedtag; protected function decodePayload(NetworkBinaryStream $in) : void{ @@ -46,7 +50,7 @@ class UpdateEquipPacket extends DataPacket implements ClientboundPacket{ $this->windowType = $in->getByte(); $this->windowSlotCount = $in->getVarInt(); $this->entityUniqueId = $in->getEntityUniqueId(); - $this->namedtag = $in->getRemaining(); + $this->namedtag = new CacheableNbt($in->getNbtCompoundRoot()); } protected function encodePayload(NetworkBinaryStream $out) : void{ @@ -54,7 +58,7 @@ class UpdateEquipPacket extends DataPacket implements ClientboundPacket{ $out->putByte($this->windowType); $out->putVarInt($this->windowSlotCount); $out->putEntityUniqueId($this->entityUniqueId); - $out->put($this->namedtag); + $out->put($this->namedtag->getEncodedNbt()); } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/network/mcpe/protocol/UpdateTradePacket.php b/src/network/mcpe/protocol/UpdateTradePacket.php index f64e31ce61..2665621ae2 100644 --- a/src/network/mcpe/protocol/UpdateTradePacket.php +++ b/src/network/mcpe/protocol/UpdateTradePacket.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\types\CacheableNbt; use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes; class UpdateTradePacket extends DataPacket implements ClientboundPacket{ @@ -51,7 +52,10 @@ class UpdateTradePacket extends DataPacket implements ClientboundPacket{ public $isV2Trading; /** @var bool */ public $isWilling; - /** @var string */ + /** + * @var CacheableNbt + * @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag> + */ public $offers; protected function decodePayload(NetworkBinaryStream $in) : void{ @@ -64,7 +68,7 @@ class UpdateTradePacket extends DataPacket implements ClientboundPacket{ $this->displayName = $in->getString(); $this->isV2Trading = $in->getBool(); $this->isWilling = $in->getBool(); - $this->offers = $in->getRemaining(); + $this->offers = new CacheableNbt($in->getNbtCompoundRoot()); } protected function encodePayload(NetworkBinaryStream $out) : void{ @@ -77,7 +81,7 @@ class UpdateTradePacket extends DataPacket implements ClientboundPacket{ $out->putString($this->displayName); $out->putBool($this->isV2Trading); $out->putBool($this->isWilling); - $out->put($this->offers); + $out->put($this->offers->getEncodedNbt()); } public function handle(PacketHandlerInterface $handler) : bool{ diff --git a/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php b/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php index f74937870b..bfe2eefbbd 100644 --- a/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php +++ b/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php @@ -223,11 +223,7 @@ class NetworkBinaryStream extends BinaryStream{ if($c !== 1){ throw new PacketDecodeException("Unexpected NBT count $c"); } - try{ - $compound = (new NetworkNbtSerializer())->read($this->buffer, $this->offset, 512)->mustGetCompoundTag(); - }catch(NbtDataException $e){ - throw new PacketDecodeException($e->getMessage(), 0, $e); - } + $compound = $this->getNbtCompoundRoot(); }elseif($nbtLen !== 0){ throw new PacketDecodeException("Unexpected fake NBT length $nbtLen"); } @@ -707,4 +703,23 @@ class NetworkBinaryStream extends BinaryStream{ $this->putStructureSettings($structureEditorData->structureSettings); $this->putVarInt($structureEditorData->structureRedstoneSaveMove); } + + public function getNbtRoot() : TreeRoot{ + $offset = $this->getOffset(); + try{ + return (new NetworkNbtSerializer())->read($this->getBuffer(), $offset, 512); + }catch(NbtDataException $e){ + throw PacketDecodeException::wrap($e, "Failed decoding NBT root"); + }finally{ + $this->setOffset($offset); + } + } + + public function getNbtCompoundRoot() : CompoundTag{ + try{ + return $this->getNbtRoot()->mustGetCompoundTag(); + }catch(NbtDataException $e){ + throw PacketDecodeException::wrap($e, "Expected TAG_Compound NBT root"); + } + } } diff --git a/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php b/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php index 4ddbdc8f26..375b9e2591 100644 --- a/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; -use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\protocol\PacketDecodeException; @@ -54,14 +53,7 @@ final class CompoundTagMetadataProperty implements MetadataProperty{ * @throws PacketDecodeException */ public static function read(NetworkBinaryStream $in) : self{ - $offset = $in->getOffset(); - try{ - $tag = (new NetworkNbtSerializer())->read($in->getBuffer(), $offset, 512)->mustGetCompoundTag(); - }catch(NbtDataException $e){ - throw new PacketDecodeException($e->getMessage(), 0, $e); - } - $in->setOffset($offset); - return new self($tag); + return new self($in->getNbtCompoundRoot()); } public function write(NetworkBinaryStream $out) : void{ From ba6fb872800264582a492840996640b4a57da359 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 4 May 2020 13:27:31 +0100 Subject: [PATCH 1518/3224] remove unused imports --- src/world/sound/EntityAttackNoDamageSound.php | 1 - src/world/sound/EntityAttackSound.php | 1 - 2 files changed, 2 deletions(-) diff --git a/src/world/sound/EntityAttackNoDamageSound.php b/src/world/sound/EntityAttackNoDamageSound.php index 8c2fde1cbb..5684adf6bc 100644 --- a/src/world/sound/EntityAttackNoDamageSound.php +++ b/src/world/sound/EntityAttackNoDamageSound.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\world\sound; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; /** diff --git a/src/world/sound/EntityAttackSound.php b/src/world/sound/EntityAttackSound.php index b1ffd4a568..102e458d6f 100644 --- a/src/world/sound/EntityAttackSound.php +++ b/src/world/sound/EntityAttackSound.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\world\sound; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; /** From f0dfa451726f014353969ed80b3c8ee5849b6015 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 4 May 2020 13:46:20 +0100 Subject: [PATCH 1519/3224] phpstorm fixing EOF newlines that phpstorm screwed up --- src/world/sound/EntityLandSound.php | 2 +- src/world/sound/EntityLongFallSound.php | 2 +- src/world/sound/EntityShortFallSound.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/world/sound/EntityLandSound.php b/src/world/sound/EntityLandSound.php index 3de49758dd..6e47329e18 100644 --- a/src/world/sound/EntityLandSound.php +++ b/src/world/sound/EntityLandSound.php @@ -54,4 +54,4 @@ class EntityLandSound implements Sound{ //TODO: does isBaby have any relevance here? ); } -} \ No newline at end of file +} diff --git a/src/world/sound/EntityLongFallSound.php b/src/world/sound/EntityLongFallSound.php index bef0286e72..907f4ac2f4 100644 --- a/src/world/sound/EntityLongFallSound.php +++ b/src/world/sound/EntityLongFallSound.php @@ -51,4 +51,4 @@ class EntityLongFallSound implements Sound{ //TODO: is isBaby relevant here? ); } -} \ No newline at end of file +} diff --git a/src/world/sound/EntityShortFallSound.php b/src/world/sound/EntityShortFallSound.php index 3049f652b7..130cecb431 100644 --- a/src/world/sound/EntityShortFallSound.php +++ b/src/world/sound/EntityShortFallSound.php @@ -50,4 +50,4 @@ class EntityShortFallSound implements Sound{ //TODO: does isBaby have any relevance here? ); } -} \ No newline at end of file +} From 81f982a8d9ee23283217624933fd54f0b0c801f1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 4 May 2020 13:47:39 +0100 Subject: [PATCH 1520/3224] remove hardcoded legacy entity type ID mapping, load from resources instead --- src/block/tile/MonsterSpawner.php | 4 +- src/entity/Entity.php | 3 +- src/network/mcpe/protocol/AddActorPacket.php | 110 ------------------- src/world/sound/EntityLandSound.php | 4 +- src/world/sound/EntityLongFallSound.php | 4 +- src/world/sound/EntityShortFallSound.php | 4 +- 6 files changed, 10 insertions(+), 119 deletions(-) diff --git a/src/block/tile/MonsterSpawner.php b/src/block/tile/MonsterSpawner.php index 601c15e2d4..2ee3cf55c1 100644 --- a/src/block/tile/MonsterSpawner.php +++ b/src/block/tile/MonsterSpawner.php @@ -23,11 +23,11 @@ declare(strict_types=1); namespace pocketmine\block\tile; +use pocketmine\data\bedrock\LegacyEntityIdToStringIdMap; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; -use pocketmine\network\mcpe\protocol\AddActorPacket; /** * @deprecated @@ -97,7 +97,7 @@ class MonsterSpawner extends Spawnable{ public function readSaveData(CompoundTag $nbt) : void{ if($nbt->hasTag(self::TAG_LEGACY_ENTITY_TYPE_ID, IntTag::class)){ //TODO: this will cause unexpected results when there's no mapping for the entity - $this->entityTypeId = AddActorPacket::LEGACY_ID_MAP_BC[$nbt->getInt(self::TAG_LEGACY_ENTITY_TYPE_ID)] ?? ":"; + $this->entityTypeId = LegacyEntityIdToStringIdMap::getInstance()->legacyToString($nbt->getInt(self::TAG_LEGACY_ENTITY_TYPE_ID)) ?? ":"; }elseif($nbt->hasTag(self::TAG_ENTITY_TYPE_ID, StringTag::class)){ $this->entityTypeId = $nbt->getString(self::TAG_ENTITY_TYPE_ID); }else{ diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 46e74f3b62..fdc034c04b 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -28,6 +28,7 @@ namespace pocketmine\entity; use pocketmine\block\Block; use pocketmine\block\Water; +use pocketmine\data\bedrock\LegacyEntityIdToStringIdMap; use pocketmine\entity\animation\Animation; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDespawnEvent; @@ -1511,7 +1512,7 @@ abstract class Entity{ protected function sendSpawnPacket(Player $player) : void{ $pk = new AddActorPacket(); $pk->entityRuntimeId = $this->getId(); - $pk->type = AddActorPacket::LEGACY_ID_MAP_BC[static::NETWORK_ID]; + $pk->type = LegacyEntityIdToStringIdMap::getInstance()->legacyToString(static::NETWORK_ID); $pk->position = $this->location->asVector3(); $pk->motion = $this->getMotion(); $pk->yaw = $this->location->yaw; diff --git a/src/network/mcpe/protocol/AddActorPacket.php b/src/network/mcpe/protocol/AddActorPacket.php index 3f375ae937..a0fc3bceea 100644 --- a/src/network/mcpe/protocol/AddActorPacket.php +++ b/src/network/mcpe/protocol/AddActorPacket.php @@ -28,7 +28,6 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\entity\Attribute; -use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; use function count; @@ -36,115 +35,6 @@ use function count; class AddActorPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_ACTOR_PACKET; - /* - * Really really really really really nasty hack, to preserve backwards compatibility. - * We can't transition to string IDs within 3.x because the network IDs (the integer ones) are exposed - * to the API in some places (for god's sake shoghi). - * - * TODO: remove this on 4.0 - */ - public const LEGACY_ID_MAP_BC = [ - -1 => ":", - EntityLegacyIds::NPC => "minecraft:npc", - EntityLegacyIds::PLAYER => "minecraft:player", - EntityLegacyIds::WITHER_SKELETON => "minecraft:wither_skeleton", - EntityLegacyIds::HUSK => "minecraft:husk", - EntityLegacyIds::STRAY => "minecraft:stray", - EntityLegacyIds::WITCH => "minecraft:witch", - EntityLegacyIds::ZOMBIE_VILLAGER => "minecraft:zombie_villager", - EntityLegacyIds::BLAZE => "minecraft:blaze", - EntityLegacyIds::MAGMA_CUBE => "minecraft:magma_cube", - EntityLegacyIds::GHAST => "minecraft:ghast", - EntityLegacyIds::CAVE_SPIDER => "minecraft:cave_spider", - EntityLegacyIds::SILVERFISH => "minecraft:silverfish", - EntityLegacyIds::ENDERMAN => "minecraft:enderman", - EntityLegacyIds::SLIME => "minecraft:slime", - EntityLegacyIds::ZOMBIE_PIGMAN => "minecraft:zombie_pigman", - EntityLegacyIds::SPIDER => "minecraft:spider", - EntityLegacyIds::SKELETON => "minecraft:skeleton", - EntityLegacyIds::CREEPER => "minecraft:creeper", - EntityLegacyIds::ZOMBIE => "minecraft:zombie", - EntityLegacyIds::SKELETON_HORSE => "minecraft:skeleton_horse", - EntityLegacyIds::MULE => "minecraft:mule", - EntityLegacyIds::DONKEY => "minecraft:donkey", - EntityLegacyIds::DOLPHIN => "minecraft:dolphin", - EntityLegacyIds::TROPICALFISH => "minecraft:tropicalfish", - EntityLegacyIds::WOLF => "minecraft:wolf", - EntityLegacyIds::SQUID => "minecraft:squid", - EntityLegacyIds::DROWNED => "minecraft:drowned", - EntityLegacyIds::SHEEP => "minecraft:sheep", - EntityLegacyIds::MOOSHROOM => "minecraft:mooshroom", - EntityLegacyIds::PANDA => "minecraft:panda", - EntityLegacyIds::SALMON => "minecraft:salmon", - EntityLegacyIds::PIG => "minecraft:pig", - EntityLegacyIds::VILLAGER => "minecraft:villager", - EntityLegacyIds::COD => "minecraft:cod", - EntityLegacyIds::PUFFERFISH => "minecraft:pufferfish", - EntityLegacyIds::COW => "minecraft:cow", - EntityLegacyIds::CHICKEN => "minecraft:chicken", - EntityLegacyIds::BALLOON => "minecraft:balloon", - EntityLegacyIds::LLAMA => "minecraft:llama", - EntityLegacyIds::IRON_GOLEM => "minecraft:iron_golem", - EntityLegacyIds::RABBIT => "minecraft:rabbit", - EntityLegacyIds::SNOW_GOLEM => "minecraft:snow_golem", - EntityLegacyIds::BAT => "minecraft:bat", - EntityLegacyIds::OCELOT => "minecraft:ocelot", - EntityLegacyIds::HORSE => "minecraft:horse", - EntityLegacyIds::CAT => "minecraft:cat", - EntityLegacyIds::POLAR_BEAR => "minecraft:polar_bear", - EntityLegacyIds::ZOMBIE_HORSE => "minecraft:zombie_horse", - EntityLegacyIds::TURTLE => "minecraft:turtle", - EntityLegacyIds::PARROT => "minecraft:parrot", - EntityLegacyIds::GUARDIAN => "minecraft:guardian", - EntityLegacyIds::ELDER_GUARDIAN => "minecraft:elder_guardian", - EntityLegacyIds::VINDICATOR => "minecraft:vindicator", - EntityLegacyIds::WITHER => "minecraft:wither", - EntityLegacyIds::ENDER_DRAGON => "minecraft:ender_dragon", - EntityLegacyIds::SHULKER => "minecraft:shulker", - EntityLegacyIds::ENDERMITE => "minecraft:endermite", - EntityLegacyIds::MINECART => "minecraft:minecart", - EntityLegacyIds::HOPPER_MINECART => "minecraft:hopper_minecart", - EntityLegacyIds::TNT_MINECART => "minecraft:tnt_minecart", - EntityLegacyIds::CHEST_MINECART => "minecraft:chest_minecart", - EntityLegacyIds::COMMAND_BLOCK_MINECART => "minecraft:command_block_minecart", - EntityLegacyIds::ARMOR_STAND => "minecraft:armor_stand", - EntityLegacyIds::ITEM => "minecraft:item", - EntityLegacyIds::TNT => "minecraft:tnt", - EntityLegacyIds::FALLING_BLOCK => "minecraft:falling_block", - EntityLegacyIds::XP_BOTTLE => "minecraft:xp_bottle", - EntityLegacyIds::XP_ORB => "minecraft:xp_orb", - EntityLegacyIds::EYE_OF_ENDER_SIGNAL => "minecraft:eye_of_ender_signal", - EntityLegacyIds::ENDER_CRYSTAL => "minecraft:ender_crystal", - EntityLegacyIds::SHULKER_BULLET => "minecraft:shulker_bullet", - EntityLegacyIds::FISHING_HOOK => "minecraft:fishing_hook", - EntityLegacyIds::DRAGON_FIREBALL => "minecraft:dragon_fireball", - EntityLegacyIds::ARROW => "minecraft:arrow", - EntityLegacyIds::SNOWBALL => "minecraft:snowball", - EntityLegacyIds::EGG => "minecraft:egg", - EntityLegacyIds::PAINTING => "minecraft:painting", - EntityLegacyIds::THROWN_TRIDENT => "minecraft:thrown_trident", - EntityLegacyIds::FIREBALL => "minecraft:fireball", - EntityLegacyIds::SPLASH_POTION => "minecraft:splash_potion", - EntityLegacyIds::ENDER_PEARL => "minecraft:ender_pearl", - EntityLegacyIds::LEASH_KNOT => "minecraft:leash_knot", - EntityLegacyIds::WITHER_SKULL => "minecraft:wither_skull", - EntityLegacyIds::WITHER_SKULL_DANGEROUS => "minecraft:wither_skull_dangerous", - EntityLegacyIds::BOAT => "minecraft:boat", - EntityLegacyIds::LIGHTNING_BOLT => "minecraft:lightning_bolt", - EntityLegacyIds::SMALL_FIREBALL => "minecraft:small_fireball", - EntityLegacyIds::LLAMA_SPIT => "minecraft:llama_spit", - EntityLegacyIds::AREA_EFFECT_CLOUD => "minecraft:area_effect_cloud", - EntityLegacyIds::LINGERING_POTION => "minecraft:lingering_potion", - EntityLegacyIds::FIREWORKS_ROCKET => "minecraft:fireworks_rocket", - EntityLegacyIds::EVOCATION_FANG => "minecraft:evocation_fang", - EntityLegacyIds::EVOCATION_ILLAGER => "minecraft:evocation_illager", - EntityLegacyIds::VEX => "minecraft:vex", - EntityLegacyIds::AGENT => "minecraft:agent", - EntityLegacyIds::ICE_BOMB => "minecraft:ice_bomb", - EntityLegacyIds::PHANTOM => "minecraft:phantom", - EntityLegacyIds::TRIPOD_CAMERA => "minecraft:tripod_camera" - ]; - /** @var int|null */ public $entityUniqueId = null; //TODO /** @var int */ diff --git a/src/world/sound/EntityLandSound.php b/src/world/sound/EntityLandSound.php index 6e47329e18..ddd4c00ff5 100644 --- a/src/world/sound/EntityLandSound.php +++ b/src/world/sound/EntityLandSound.php @@ -24,9 +24,9 @@ declare(strict_types=1); namespace pocketmine\world\sound; use pocketmine\block\Block; +use pocketmine\data\bedrock\LegacyEntityIdToStringIdMap; use pocketmine\entity\Entity; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\AddActorPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\player\Player; @@ -50,7 +50,7 @@ class EntityLandSound implements Sound{ LevelSoundEventPacket::SOUND_LAND, $pos, $this->blockLandedOn->getRuntimeId(), - $this->entity instanceof Player ? "minecraft:player" : AddActorPacket::LEGACY_ID_MAP_BC[$this->entity::NETWORK_ID] //TODO: bad hack, stuff depends on players having a -1 network ID :( + $this->entity instanceof Player ? "minecraft:player" : LegacyEntityIdToStringIdMap::getInstance()->legacyToString($this->entity::NETWORK_ID) //TODO: bad hack, stuff depends on players having a -1 network ID :( //TODO: does isBaby have any relevance here? ); } diff --git a/src/world/sound/EntityLongFallSound.php b/src/world/sound/EntityLongFallSound.php index 907f4ac2f4..d6f75b4598 100644 --- a/src/world/sound/EntityLongFallSound.php +++ b/src/world/sound/EntityLongFallSound.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace pocketmine\world\sound; +use pocketmine\data\bedrock\LegacyEntityIdToStringIdMap; use pocketmine\entity\Entity; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\AddActorPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\player\Player; @@ -47,7 +47,7 @@ class EntityLongFallSound implements Sound{ LevelSoundEventPacket::SOUND_FALL_BIG, $pos, -1, - $this->entity instanceof Player ? "minecraft:player" : AddActorPacket::LEGACY_ID_MAP_BC[$this->entity::NETWORK_ID] //TODO: bad hack, stuff depends on players having a -1 network ID :( + $this->entity instanceof Player ? "minecraft:player" : LegacyEntityIdToStringIdMap::getInstance()->legacyToString($this->entity::NETWORK_ID) //TODO: bad hack, stuff depends on players having a -1 network ID :( //TODO: is isBaby relevant here? ); } diff --git a/src/world/sound/EntityShortFallSound.php b/src/world/sound/EntityShortFallSound.php index 130cecb431..9c743f4c92 100644 --- a/src/world/sound/EntityShortFallSound.php +++ b/src/world/sound/EntityShortFallSound.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace pocketmine\world\sound; +use pocketmine\data\bedrock\LegacyEntityIdToStringIdMap; use pocketmine\entity\Entity; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\AddActorPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\player\Player; @@ -46,7 +46,7 @@ class EntityShortFallSound implements Sound{ LevelSoundEventPacket::SOUND_FALL_SMALL, $pos, -1, - $this->entity instanceof Player ? "minecraft:player" : AddActorPacket::LEGACY_ID_MAP_BC[$this->entity::NETWORK_ID] //TODO: bad hack, stuff depends on players having a -1 network ID :( + $this->entity instanceof Player ? "minecraft:player" : LegacyEntityIdToStringIdMap::getInstance()->legacyToString($this->entity::NETWORK_ID) //TODO: bad hack, stuff depends on players having a -1 network ID :( //TODO: does isBaby have any relevance here? ); } From c2b438ccb63b4ec9600d441a8e8a604808438509 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 4 May 2020 14:30:01 +0100 Subject: [PATCH 1521/3224] git you need to stop doing this to me REEEEEEEEEEEEEEEEEEEEEEE --- .../bedrock/LegacyEntityIdToStringIdMap.php | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/data/bedrock/LegacyEntityIdToStringIdMap.php diff --git a/src/data/bedrock/LegacyEntityIdToStringIdMap.php b/src/data/bedrock/LegacyEntityIdToStringIdMap.php new file mode 100644 index 0000000000..84f46b1165 --- /dev/null +++ b/src/data/bedrock/LegacyEntityIdToStringIdMap.php @@ -0,0 +1,69 @@ + + */ + private $legacyToString = []; + /** + * @var int[] + * @phpstan-var array + */ + private $stringToLegacy = []; + + public function __construct(){ + $rawJson = @file_get_contents(\pocketmine\RESOURCE_PATH . '/vanilla/entity_id_map.json'); + if($rawJson === false) throw new AssumptionFailedError("Missing required resource file"); + $mapping = json_decode($rawJson, true); + if(!is_array($mapping)) throw new AssumptionFailedError("Entity ID map should be a JSON object"); + foreach($mapping as $stringId => $legacyId){ + if(!is_string($stringId) or !is_int($legacyId)){ + throw new AssumptionFailedError("Block ID map should have string keys and int values"); + } + $this->legacyToString[$legacyId] = $stringId; + $this->stringToLegacy[$stringId] = $legacyId; + } + } + + public function legacyToString(int $legacy) : ?string{ + return $this->legacyToString[$legacy] ?? null; + } + + public function stringToLegacy(string $string) : ?int{ + return $this->stringToLegacy[$string] ?? null; + } +} From 9cf410d484725d5ba99c56e968875a5b3a7dbdc9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 May 2020 18:55:13 +0100 Subject: [PATCH 1522/3224] Player: fixed broken behaviour of entity spawning on chunk send, closes #3355 --- src/entity/Entity.php | 5 +++- src/player/Player.php | 38 ++++++++++++++++----------- src/player/UsedChunkStatus.php | 47 ++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 16 deletions(-) create mode 100644 src/player/UsedChunkStatus.php diff --git a/src/entity/Entity.php b/src/entity/Entity.php index fdc034c04b..ba098ed276 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1528,7 +1528,10 @@ abstract class Entity{ public function spawnTo(Player $player) : void{ $id = spl_object_id($player); - if(!isset($this->hasSpawned[$id]) and $player->isUsingChunk($this->location->getFloorX() >> 4, $this->location->getFloorZ() >> 4)){ + //TODO: this will cause some visible lag during chunk resends; if the player uses a spawn egg in a chunk, the + //created entity won't be visible until after the resend arrives. However, this is better than possibly crashing + //the player by sending them entities too early. + if(!isset($this->hasSpawned[$id]) and $player->hasReceivedChunk($this->location->getFloorX() >> 4, $this->location->getFloorZ() >> 4)){ $this->hasSpawned[$id] = $player; $this->sendSpawnPacket($player); diff --git a/src/player/Player.php b/src/player/Player.php index a657be6a43..a8af8829bf 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -189,7 +189,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** @var GameMode */ protected $gamemode; - /** @var bool[] chunkHash => bool (true = sent, false = needs sending) */ + /** + * @var UsedChunkStatus[] chunkHash => status + * @phpstan-var array + */ protected $usedChunks = []; /** @var bool[] chunkHash => dummy */ protected $loadQueue = []; @@ -286,7 +289,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, //load the spawn chunk so we can see the terrain $world->registerChunkLoader($this, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4, true); $world->registerChunkListener($this, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4); - $this->usedChunks[World::chunkHash($spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4)] = false; + $this->usedChunks[World::chunkHash($spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4)] = UsedChunkStatus::NEEDED(); if($namedtag === null){ $namedtag = EntityFactory::createBaseNBT($spawn); @@ -717,7 +720,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $oldWorld = $this->location->getWorld(); if(parent::switchWorld($targetWorld)){ if($oldWorld !== null){ - foreach($this->usedChunks as $index => $d){ + foreach($this->usedChunks as $index => $status){ World::getXZ($index, $X, $Z); $this->unloadChunk($X, $Z, $oldWorld); } @@ -778,7 +781,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, ++$count; - $this->usedChunks[$index] = false; + $this->usedChunks[$index] = UsedChunkStatus::NEEDED(); $this->getWorld()->registerChunkLoader($this, $X, $Z, true); $this->getWorld()->registerChunkListener($this, $X, $Z); @@ -787,20 +790,20 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } unset($this->loadQueue[$index]); - $this->usedChunks[$index] = true; + $this->usedChunks[$index] = UsedChunkStatus::REQUESTED(); - $this->networkSession->startUsingChunk($X, $Z, function(int $chunkX, int $chunkZ) : void{ + $this->networkSession->startUsingChunk($X, $Z, function(int $chunkX, int $chunkZ) use ($index) : void{ + $this->usedChunks[$index] = UsedChunkStatus::SENT(); if($this->spawned){ $this->spawnEntitiesOnChunk($chunkX, $chunkZ); }elseif($this->spawnChunkLoadCount++ === $this->spawnThreshold){ $this->spawned = true; - foreach($this->usedChunks as $chunkHash => $hasSent){ - if(!$hasSent){ - continue; + foreach($this->usedChunks as $chunkHash => $status){ + if($status->equals(UsedChunkStatus::SENT())){ + World::getXZ($chunkHash, $_x, $_z); + $this->spawnEntitiesOnChunk($_x, $_z); } - World::getXZ($chunkHash, $_x, $_z); - $this->spawnEntitiesOnChunk($_x, $_z); } $this->networkSession->onTerrainReady(); @@ -894,13 +897,13 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $unloadChunks = $this->usedChunks; foreach($this->selectChunks() as $hash){ - if(!isset($this->usedChunks[$hash]) or $this->usedChunks[$hash] === false){ + if(!isset($this->usedChunks[$hash]) or $this->usedChunks[$hash]->equals(UsedChunkStatus::NEEDED())){ $newOrder[$hash] = true; } unset($unloadChunks[$hash]); } - foreach($unloadChunks as $index => $bool){ + foreach($unloadChunks as $index => $status){ World::getXZ($index, $X, $Z); $this->unloadChunk($X, $Z); } @@ -917,6 +920,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return isset($this->usedChunks[World::chunkHash($chunkX, $chunkZ)]); } + public function hasReceivedChunk(int $chunkX, int $chunkZ) : bool{ + $status = $this->usedChunks[World::chunkHash($chunkX, $chunkZ)] ?? null; + return $status !== null and $status->equals(UsedChunkStatus::SENT()); + } + public function doChunkRequests() : void{ if($this->nextChunkOrderRun !== PHP_INT_MAX and $this->nextChunkOrderRun-- <= 0){ $this->nextChunkOrderRun = PHP_INT_MAX; @@ -1982,7 +1990,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->hiddenPlayers = []; if($this->location->isValid()){ - foreach($this->usedChunks as $index => $d){ + foreach($this->usedChunks as $index => $status){ World::getXZ($index, $chunkX, $chunkZ); $this->unloadChunk($chunkX, $chunkZ); } @@ -2342,7 +2350,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, public function onChunkChanged(Chunk $chunk) : void{ if(isset($this->usedChunks[$hash = World::chunkHash($chunk->getX(), $chunk->getZ())])){ - $this->usedChunks[$hash] = false; + $this->usedChunks[$hash] = UsedChunkStatus::NEEDED(); $this->nextChunkOrderRun = 0; } } diff --git a/src/player/UsedChunkStatus.php b/src/player/UsedChunkStatus.php new file mode 100644 index 0000000000..ce36ab86c1 --- /dev/null +++ b/src/player/UsedChunkStatus.php @@ -0,0 +1,47 @@ + Date: Tue, 5 May 2020 19:22:20 +0100 Subject: [PATCH 1523/3224] TypeConverter: use SingletonTrait --- src/network/mcpe/convert/TypeConverter.php | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index b3ecd9214d..244c2eaa78 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -39,29 +39,14 @@ use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\protocol\types\inventory\NetworkInventoryAction; use pocketmine\network\mcpe\protocol\types\recipe\RecipeIngredient; use pocketmine\player\Player; +use pocketmine\utils\SingletonTrait; class TypeConverter{ + use SingletonTrait; + private const DAMAGE_TAG = "Damage"; //TAG_Int private const DAMAGE_TAG_CONFLICT_RESOLUTION = "___Damage_ProtocolCollisionResolution___"; - /** @var self|null */ - private static $instance; - - private function __construct(){ - //NOOP - } - - public static function getInstance() : self{ - if(self::$instance === null){ - self::$instance = new self; - } - return self::$instance; - } - - public static function setInstance(self $instance) : void{ - self::$instance = $instance; - } - public function coreItemStackToRecipeIngredient(Item $itemStack) : RecipeIngredient{ $meta = $itemStack->getMeta(); return new RecipeIngredient($itemStack->getId(), $meta === -1 ? 0x7fff : $meta, $itemStack->getCount()); From 218f32f5b8be2449862f6baea1910a891ad68799 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 May 2020 13:15:54 +0100 Subject: [PATCH 1524/3224] De-duplicate code used by legacy <-> string ID mapping classes --- .../bedrock/LegacyBlockIdToStringIdMap.php | 35 +-------- .../bedrock/LegacyEntityIdToStringIdMap.php | 33 +------- .../LegacyToStringBidirectionalIdMap.php | 78 +++++++++++++++++++ 3 files changed, 83 insertions(+), 63 deletions(-) create mode 100644 src/data/bedrock/LegacyToStringBidirectionalIdMap.php diff --git a/src/data/bedrock/LegacyBlockIdToStringIdMap.php b/src/data/bedrock/LegacyBlockIdToStringIdMap.php index de012d850a..d613da6755 100644 --- a/src/data/bedrock/LegacyBlockIdToStringIdMap.php +++ b/src/data/bedrock/LegacyBlockIdToStringIdMap.php @@ -31,39 +31,10 @@ use function is_int; use function is_string; use function json_decode; -final class LegacyBlockIdToStringIdMap{ +final class LegacyBlockIdToStringIdMap extends LegacyToStringBidirectionalIdMap{ use SingletonTrait; - /** - * @var string[] - * @phpstan-var array - */ - private $legacyToString = []; - /** - * @var int[] - * @phpstan-var array - */ - private $stringToLegacy = []; - public function __construct(){ - $stringToLegacyId = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . 'vanilla/block_id_map.json'), true); - if(!is_array($stringToLegacyId)){ - throw new AssumptionFailedError("Invalid format of block_id_map"); - } - foreach($stringToLegacyId as $stringId => $legacyId){ - if(!is_string($stringId) or !is_int($legacyId)){ - throw new AssumptionFailedError("Block ID map should have string keys and int values"); - } - $this->legacyToString[$legacyId] = $stringId; - $this->stringToLegacy[$stringId] = $legacyId; - } + parent::__construct(\pocketmine\RESOURCE_PATH . 'vanilla/block_id_map.json'); } - - public function legacyToString(int $legacy) : ?string{ - return $this->legacyToString[$legacy] ?? null; - } - - public function stringToLegacy(string $string) : ?int{ - return $this->stringToLegacy[$string] ?? null; - } -} \ No newline at end of file +} diff --git a/src/data/bedrock/LegacyEntityIdToStringIdMap.php b/src/data/bedrock/LegacyEntityIdToStringIdMap.php index 84f46b1165..9457e70091 100644 --- a/src/data/bedrock/LegacyEntityIdToStringIdMap.php +++ b/src/data/bedrock/LegacyEntityIdToStringIdMap.php @@ -31,39 +31,10 @@ use function is_int; use function is_string; use function json_decode; -final class LegacyEntityIdToStringIdMap{ +final class LegacyEntityIdToStringIdMap extends LegacyToStringBidirectionalIdMap{ use SingletonTrait; - /** - * @var string[] - * @phpstan-var array - */ - private $legacyToString = []; - /** - * @var int[] - * @phpstan-var array - */ - private $stringToLegacy = []; - public function __construct(){ - $rawJson = @file_get_contents(\pocketmine\RESOURCE_PATH . '/vanilla/entity_id_map.json'); - if($rawJson === false) throw new AssumptionFailedError("Missing required resource file"); - $mapping = json_decode($rawJson, true); - if(!is_array($mapping)) throw new AssumptionFailedError("Entity ID map should be a JSON object"); - foreach($mapping as $stringId => $legacyId){ - if(!is_string($stringId) or !is_int($legacyId)){ - throw new AssumptionFailedError("Block ID map should have string keys and int values"); - } - $this->legacyToString[$legacyId] = $stringId; - $this->stringToLegacy[$stringId] = $legacyId; - } - } - - public function legacyToString(int $legacy) : ?string{ - return $this->legacyToString[$legacy] ?? null; - } - - public function stringToLegacy(string $string) : ?int{ - return $this->stringToLegacy[$string] ?? null; + parent::__construct(\pocketmine\RESOURCE_PATH . '/vanilla/entity_id_map.json'); } } diff --git a/src/data/bedrock/LegacyToStringBidirectionalIdMap.php b/src/data/bedrock/LegacyToStringBidirectionalIdMap.php new file mode 100644 index 0000000000..9afb0dc57b --- /dev/null +++ b/src/data/bedrock/LegacyToStringBidirectionalIdMap.php @@ -0,0 +1,78 @@ + + */ + private $legacyToString = []; + /** + * @var int[] + * @phpstan-var array + */ + private $stringToLegacy = []; + + public function __construct(string $file){ + $stringToLegacyId = json_decode(file_get_contents($file), true); + if(!is_array($stringToLegacyId)){ + throw new AssumptionFailedError("Invalid format of ID map"); + } + foreach($stringToLegacyId as $stringId => $legacyId){ + if(!is_string($stringId) or !is_int($legacyId)){ + throw new AssumptionFailedError("ID map should have string keys and int values"); + } + $this->legacyToString[$legacyId] = $stringId; + $this->stringToLegacy[$stringId] = $legacyId; + } + } + + public function legacyToString(int $legacy) : ?string{ + return $this->legacyToString[$legacy] ?? null; + } + + public function stringToLegacy(string $string) : ?int{ + return $this->stringToLegacy[$string] ?? null; + } + + /** + * @return string[] + * @phpstan-return array + */ + public function getLegacyToStringMap() : array{ + return $this->legacyToString; + } + + /** + * @return int[] + * @phpstan-return array + */ + public function getStringToLegacyMap() : array{ + return $this->stringToLegacy; + } +} From b4606a4cd042ce9b6bd83cf22c1f0ceed7b20895 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 May 2020 13:17:16 +0100 Subject: [PATCH 1525/3224] remove PM resource interaction from StartGamePacket also lose the cache, because it's not very useful ... --- .../bedrock/LegacyItemIdToStringIdMap.php | 40 +++++++++++++++++++ .../mcpe/handler/PreSpawnPacketHandler.php | 3 +- src/network/mcpe/protocol/StartGamePacket.php | 18 ++------- 3 files changed, 46 insertions(+), 15 deletions(-) create mode 100644 src/data/bedrock/LegacyItemIdToStringIdMap.php diff --git a/src/data/bedrock/LegacyItemIdToStringIdMap.php b/src/data/bedrock/LegacyItemIdToStringIdMap.php new file mode 100644 index 0000000000..03efcc1610 --- /dev/null +++ b/src/data/bedrock/LegacyItemIdToStringIdMap.php @@ -0,0 +1,40 @@ +levelId = ""; $pk->worldName = $this->server->getMotd(); $pk->blockTable = RuntimeBlockMapping::getInstance()->getStartGamePaletteCache(); - + $pk->itemTable = LegacyItemIdToStringIdMap::getInstance()->getStringToLegacyMap(); //TODO: check if this is actually needed $this->session->sendDataPacket($pk); $this->session->sendDataPacket(StaticPacketCache::getInstance()->getAvailableActorIdentifiers()); diff --git a/src/network/mcpe/protocol/StartGamePacket.php b/src/network/mcpe/protocol/StartGamePacket.php index 1ebae773b3..f31eb6c814 100644 --- a/src/network/mcpe/protocol/StartGamePacket.php +++ b/src/network/mcpe/protocol/StartGamePacket.php @@ -38,9 +38,6 @@ use const pocketmine\RESOURCE_PATH; class StartGamePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::START_GAME_PACKET; - /** @var string|null */ - private static $itemTableCache = null; - /** @var int */ public $entityUniqueId; /** @var int */ @@ -155,10 +152,10 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{ */ public $blockTable; /** - * @var int[]|null string (name) => int16 (legacyID) - * @phpstan-var array|null + * @var int[] string (name) => int16 (legacyID) + * @phpstan-var array */ - public $itemTable = null; + public $itemTable = []; protected function decodePayload(NetworkBinaryStream $in) : void{ $this->entityUniqueId = $in->getEntityUniqueId(); @@ -285,14 +282,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{ $out->put($this->blockTable->getEncodedNbt()); - if($this->itemTable === null){ - if(self::$itemTableCache === null){ - self::$itemTableCache = self::serializeItemTable(json_decode(file_get_contents(RESOURCE_PATH . '/vanilla/item_id_map.json'), true)); - } - $out->put(self::$itemTableCache); - }else{ - $out->put(self::serializeItemTable($this->itemTable)); - } + $out->put(self::serializeItemTable($this->itemTable)); $out->putString($this->multiplayerCorrelationId); } From ff53ddd3ad5747810c41f37ce29fe9fd4a33093e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 May 2020 13:29:58 +0100 Subject: [PATCH 1526/3224] PrepareEncryptionTask: fix wrongly-specified nullability of serverPrivateKey --- src/network/mcpe/encryption/PrepareEncryptionTask.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/mcpe/encryption/PrepareEncryptionTask.php b/src/network/mcpe/encryption/PrepareEncryptionTask.php index 39bf8c0437..13992f37c4 100644 --- a/src/network/mcpe/encryption/PrepareEncryptionTask.php +++ b/src/network/mcpe/encryption/PrepareEncryptionTask.php @@ -36,8 +36,8 @@ class PrepareEncryptionTask extends AsyncTask{ /** @var PrivateKeyInterface|null */ private static $SERVER_PRIVATE_KEY = null; - /** @var PrivateKeyInterface|null */ - private $serverPrivateKey = null; + /** @var PrivateKeyInterface */ + private $serverPrivateKey; /** @var string|null */ private $aesKey = null; From e392a6a8073bca339cf1e4d9017fc35178a7529e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 May 2020 13:32:18 +0100 Subject: [PATCH 1527/3224] PrepareEncryptionTask: do not store onCompletion as a field pthreads will screw around with it and make it do things it's not supposed to, which is the exact reason why we have thread-local storage to begin with. --- src/network/mcpe/encryption/PrepareEncryptionTask.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/network/mcpe/encryption/PrepareEncryptionTask.php b/src/network/mcpe/encryption/PrepareEncryptionTask.php index 13992f37c4..aae8968537 100644 --- a/src/network/mcpe/encryption/PrepareEncryptionTask.php +++ b/src/network/mcpe/encryption/PrepareEncryptionTask.php @@ -45,11 +45,6 @@ class PrepareEncryptionTask extends AsyncTask{ private $handshakeJwt = null; /** @var PublicKeyInterface */ private $clientPub; - /** - * @var \Closure - * @phpstan-var \Closure(string $encryptionKey, string $handshakeJwt) : void - */ - private $onCompletion; /** * @phpstan-param \Closure(string $encryptionKey, string $handshakeJwt) : void $onCompletion @@ -62,7 +57,6 @@ class PrepareEncryptionTask extends AsyncTask{ $this->serverPrivateKey = self::$SERVER_PRIVATE_KEY; $this->clientPub = $clientPub; $this->storeLocal(self::TLS_KEY_ON_COMPLETION, $onCompletion); - $this->onCompletion = $onCompletion; } public function onRun() : void{ From 88c6dcf46d6b786b3a6e83bb3fd7f930ca089f31 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 May 2020 13:41:36 +0100 Subject: [PATCH 1528/3224] ChunkCache: clean up handling of cache cleanup on world unload --- src/network/mcpe/ChunkCache.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/network/mcpe/ChunkCache.php b/src/network/mcpe/ChunkCache.php index 128d5890b9..5985b9e3c7 100644 --- a/src/network/mcpe/ChunkCache.php +++ b/src/network/mcpe/ChunkCache.php @@ -51,6 +51,16 @@ class ChunkCache implements ChunkListener{ public static function getInstance(World $world, Compressor $compressor) : self{ $worldId = spl_object_id($world); $compressorId = spl_object_id($compressor); + if(!isset(self::$instances[$worldId])){ + self::$instances[$worldId] = []; + $world->addOnUnloadCallback(static function() use ($worldId) : void{ + foreach(self::$instances[$worldId] as $cache){ + $cache->caches = []; + } + unset(self::$instances[$worldId]); + \GlobalLogger::get()->debug("Destroyed chunk packet caches for world#$worldId"); + }); + } if(!isset(self::$instances[$worldId][$compressorId])){ \GlobalLogger::get()->debug("Created new chunk packet cache (world#$worldId, compressor#$compressorId)"); self::$instances[$worldId][$compressorId] = new self($world, $compressor); @@ -74,12 +84,6 @@ class ChunkCache implements ChunkListener{ private function __construct(World $world, Compressor $compressor){ $this->world = $world; $this->compressor = $compressor; - $worldId = spl_object_id($world); - $this->world->addOnUnloadCallback(function() use ($worldId) : void{ - $this->caches = []; - unset(self::$instances[$worldId]); - \GlobalLogger::get()->debug("Destroyed chunk packet caches for world#$worldId"); - }); } /** From a92580b99316d12ffa2601627e346e130e2cd6b3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 May 2020 21:14:57 +0100 Subject: [PATCH 1529/3224] StartGamePacket: remove unused imports --- src/network/mcpe/protocol/StartGamePacket.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/network/mcpe/protocol/StartGamePacket.php b/src/network/mcpe/protocol/StartGamePacket.php index f31eb6c814..71869a482c 100644 --- a/src/network/mcpe/protocol/StartGamePacket.php +++ b/src/network/mcpe/protocol/StartGamePacket.php @@ -31,9 +31,6 @@ use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\CacheableNbt; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use function count; -use function file_get_contents; -use function json_decode; -use const pocketmine\RESOURCE_PATH; class StartGamePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::START_GAME_PACKET; From 5d154e43a9e8aef701bec5b63ecf0a641a128ff9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 May 2020 21:18:05 +0100 Subject: [PATCH 1530/3224] LoginPacket: removed an old hack that's no longer used --- src/network/mcpe/protocol/LoginPacket.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/network/mcpe/protocol/LoginPacket.php b/src/network/mcpe/protocol/LoginPacket.php index dc433a8a9e..ca86b98b38 100644 --- a/src/network/mcpe/protocol/LoginPacket.php +++ b/src/network/mcpe/protocol/LoginPacket.php @@ -52,14 +52,6 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ /** @var ClientData decoded payload of the clientData JWT */ public $clientData; - /** - * This field may be used by plugins to bypass keychain verification. It should only be used for plugins such as - * Specter where passing verification would take too much time and not be worth it. - * - * @var bool - */ - public $skipVerification = false; - public function canBeSentBeforeLogin() : bool{ return true; } From ed757c7207d046ae073e6ab21a409d02061a3f36 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 May 2020 21:32:22 +0100 Subject: [PATCH 1531/3224] consolidate some JWT handling into one class --- src/network/mcpe/JwtUtils.php | 66 +++++++++++++++++++ src/network/mcpe/auth/ProcessLoginTask.php | 14 ++-- .../mcpe/encryption/EncryptionUtils.php | 15 ++--- src/network/mcpe/protocol/LoginPacket.php | 6 +- src/utils/Utils.php | 24 ------- 5 files changed, 78 insertions(+), 47 deletions(-) create mode 100644 src/network/mcpe/JwtUtils.php diff --git a/src/network/mcpe/JwtUtils.php b/src/network/mcpe/JwtUtils.php new file mode 100644 index 0000000000..1ef186ef22 --- /dev/null +++ b/src/network/mcpe/JwtUtils.php @@ -0,0 +1,66 @@ + + * + * @throws \UnexpectedValueException + */ + public static function getClaims(string $token) : array{ + $v = explode(".", $token); + if(count($v) !== 3){ + throw new \UnexpectedValueException("Expected exactly 3 JWT parts, got " . count($v)); + } + $payloadB64 = $v[1]; + $payloadJSON = self::b64UrlDecode($payloadB64); + if($payloadJSON === false){ + throw new \UnexpectedValueException("Invalid base64 JWT payload"); + } + $result = json_decode($payloadJSON, true); + if(!is_array($result)){ + throw new \UnexpectedValueException("Failed to decode JWT payload JSON: " . json_last_error_msg()); + } + + return $result; + } + + public static function b64UrlEncode(string $str) : string{ + return rtrim(strtr(base64_encode($str), '+/', '-_'), '='); + } + + public static function b64UrlDecode(string $str) : string{ + if(($len = strlen($str) % 4) !== 0){ + $str .= str_repeat('=', 4 - $len); + } + $decoded = base64_decode(strtr($str, '-_', '+/'), true); + if($decoded === false){ + throw new \UnexpectedValueException("Malformed base64url encoded payload could not be decoded"); + } + return $decoded; + } +} diff --git a/src/network/mcpe/auth/ProcessLoginTask.php b/src/network/mcpe/auth/ProcessLoginTask.php index 73c0b31b66..3fcc730a14 100644 --- a/src/network/mcpe/auth/ProcessLoginTask.php +++ b/src/network/mcpe/auth/ProcessLoginTask.php @@ -28,6 +28,7 @@ use Mdanter\Ecc\Crypto\Signature\Signature; use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; use Mdanter\Ecc\Serializer\PublicKey\PemPublicKeySerializer; use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer; +use pocketmine\network\mcpe\JwtUtils; use pocketmine\network\mcpe\protocol\LoginPacket; use pocketmine\scheduler\AsyncTask; use function assert; @@ -124,11 +125,11 @@ class ProcessLoginTask extends AsyncTask{ } //First link, check that it is self-signed - $headers = json_decode(self::b64UrlDecode($headB64), true); + $headers = json_decode(JwtUtils::b64UrlDecode($headB64), true); $currentPublicKey = $headers["x5u"]; } - $plainSignature = self::b64UrlDecode($sigB64); + $plainSignature = JwtUtils::b64UrlDecode($sigB64); assert(strlen($plainSignature) === 96); [$rString, $sString] = str_split($plainSignature, 48); $sig = new Signature(gmp_init(bin2hex($rString), 16), gmp_init(bin2hex($sString), 16)); @@ -149,7 +150,7 @@ class ProcessLoginTask extends AsyncTask{ $this->authenticated = true; //we're signed into xbox live } - $claims = json_decode(self::b64UrlDecode($payloadB64), true); + $claims = json_decode(JwtUtils::b64UrlDecode($payloadB64), true); $time = time(); if(isset($claims["nbf"]) and $claims["nbf"] > $time + self::CLOCK_DRIFT_MAX){ @@ -163,13 +164,6 @@ class ProcessLoginTask extends AsyncTask{ $currentPublicKey = $claims["identityPublicKey"] ?? null; //if there are further links, the next link should be signed with this } - private static function b64UrlDecode(string $str) : string{ - if(($len = strlen($str) % 4) !== 0){ - $str .= str_repeat('=', 4 - $len); - } - return base64_decode(strtr($str, '-_', '+/'), true); - } - public function onCompletion() : void{ /** * @var \Closure $callback diff --git a/src/network/mcpe/encryption/EncryptionUtils.php b/src/network/mcpe/encryption/EncryptionUtils.php index 38fe0e95a8..a396c8ab19 100644 --- a/src/network/mcpe/encryption/EncryptionUtils.php +++ b/src/network/mcpe/encryption/EncryptionUtils.php @@ -29,15 +29,14 @@ use Mdanter\Ecc\Serializer\PrivateKey\DerPrivateKeySerializer; use Mdanter\Ecc\Serializer\PrivateKey\PemPrivateKeySerializer; use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer; +use pocketmine\network\mcpe\JwtUtils; use function base64_encode; use function gmp_strval; use function hex2bin; use function json_encode; use function openssl_digest; use function openssl_sign; -use function rtrim; use function str_pad; -use function strtr; final class EncryptionUtils{ @@ -45,10 +44,6 @@ final class EncryptionUtils{ //NOOP } - private static function b64UrlEncode(string $str) : string{ - return rtrim(strtr(base64_encode($str), '+/', '-_'), '='); - } - public static function generateSharedSecret(PrivateKeyInterface $localPriv, PublicKeyInterface $remotePub) : \GMP{ return $localPriv->createExchange($remotePub)->calculateSharedKey(); } @@ -58,11 +53,11 @@ final class EncryptionUtils{ } public static function generateServerHandshakeJwt(PrivateKeyInterface $serverPriv, string $salt) : string{ - $jwtBody = self::b64UrlEncode(json_encode([ + $jwtBody = JwtUtils::b64UrlEncode(json_encode([ "x5u" => base64_encode((new DerPublicKeySerializer())->serialize($serverPriv->getPublicKey())), "alg" => "ES384" ]) - ) . "." . self::b64UrlEncode(json_encode([ + ) . "." . JwtUtils::b64UrlEncode(json_encode([ "salt" => base64_encode($salt) ]) ); @@ -70,11 +65,11 @@ final class EncryptionUtils{ openssl_sign($jwtBody, $sig, (new PemPrivateKeySerializer(new DerPrivateKeySerializer()))->serialize($serverPriv), OPENSSL_ALGO_SHA384); $decodedSig = (new DerSignatureSerializer())->parse($sig); - $jwtSig = self::b64UrlEncode( + $jwtSig = JwtUtils::b64UrlEncode( hex2bin(str_pad(gmp_strval($decodedSig->getR(), 16), 96, "0", STR_PAD_LEFT)) . hex2bin(str_pad(gmp_strval($decodedSig->getS(), 16), 96, "0", STR_PAD_LEFT)) ); return "$jwtBody.$jwtSig"; } -} \ No newline at end of file +} diff --git a/src/network/mcpe/protocol/LoginPacket.php b/src/network/mcpe/protocol/LoginPacket.php index ca86b98b38..6ca62209ab 100644 --- a/src/network/mcpe/protocol/LoginPacket.php +++ b/src/network/mcpe/protocol/LoginPacket.php @@ -25,13 +25,13 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\JwtUtils; use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\login\AuthenticationData; use pocketmine\network\mcpe\protocol\types\login\ClientData; use pocketmine\network\mcpe\protocol\types\login\JwtChain; use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; -use pocketmine\utils\Utils; use function is_array; use function json_decode; @@ -83,7 +83,7 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ foreach($this->chainDataJwt->chain as $k => $chain){ //validate every chain element try{ - $claims = Utils::getJwtClaims($chain); + $claims = JwtUtils::getClaims($chain); }catch(\UnexpectedValueException $e){ throw new PacketDecodeException($e->getMessage(), 0, $e); } @@ -112,7 +112,7 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ $this->clientDataJwt = $buffer->get($buffer->getLInt()); try{ - $clientData = Utils::getJwtClaims($this->clientDataJwt); + $clientData = JwtUtils::getClaims($this->clientDataJwt); }catch(\UnexpectedValueException $e){ throw new PacketDecodeException($e->getMessage(), 0, $e); } diff --git a/src/utils/Utils.php b/src/utils/Utils.php index 1536baca68..4fe1cd973e 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -361,30 +361,6 @@ class Utils{ return $hash; } - /** - * @return mixed[] array of claims - * @phpstan-return array - * - * @throws \UnexpectedValueException - */ - public static function getJwtClaims(string $token) : array{ - $v = explode(".", $token); - if(count($v) !== 3){ - throw new \UnexpectedValueException("Expected exactly 3 JWT parts, got " . count($v)); - } - $payloadB64 = $v[1]; - $payloadJSON = base64_decode(strtr($payloadB64, '-_', '+/'), true); - if($payloadJSON === false){ - throw new \UnexpectedValueException("Invalid base64 JWT payload"); - } - $result = json_decode($payloadJSON, true); - if(!is_array($result)){ - throw new \UnexpectedValueException("Failed to decode JWT payload JSON: " . json_last_error_msg()); - } - - return $result; - } - /** * @param object $value */ From 0b6d6306cf4c7c6ed7d37ded8609d9fa01022e3a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 May 2020 21:46:35 +0100 Subject: [PATCH 1532/3224] LoginPacket: fixed error handling edge case with malformed chain data JSON --- src/network/mcpe/protocol/LoginPacket.php | 5 ++ .../network/mcpe/protocol/LoginPacketTest.php | 48 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 tests/phpunit/network/mcpe/protocol/LoginPacketTest.php diff --git a/src/network/mcpe/protocol/LoginPacket.php b/src/network/mcpe/protocol/LoginPacket.php index 6ca62209ab..5b5fc75945 100644 --- a/src/network/mcpe/protocol/LoginPacket.php +++ b/src/network/mcpe/protocol/LoginPacket.php @@ -33,7 +33,9 @@ use pocketmine\network\mcpe\protocol\types\login\JwtChain; use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; use function is_array; +use function is_object; use function json_decode; +use function json_last_error_msg; class LoginPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::LOGIN_PACKET; @@ -69,6 +71,9 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ $buffer = new BinaryStream($in->getString()); $chainDataJson = json_decode($buffer->get($buffer->getLInt())); + if(!is_object($chainDataJson)){ + throw new PacketDecodeException("Failed decoding chain data JSON: " . json_last_error_msg()); + } $mapper = new \JsonMapper; $mapper->bExceptionOnMissingData = true; $mapper->bExceptionOnUndefinedProperty = true; diff --git a/tests/phpunit/network/mcpe/protocol/LoginPacketTest.php b/tests/phpunit/network/mcpe/protocol/LoginPacketTest.php new file mode 100644 index 0000000000..f5abc6fbaf --- /dev/null +++ b/tests/phpunit/network/mcpe/protocol/LoginPacketTest.php @@ -0,0 +1,48 @@ +putUnsignedVarInt(ProtocolInfo::LOGIN_PACKET); + $payload = '{"chain":[]'; //intentionally malformed + $stream->putInt(ProtocolInfo::CURRENT_PROTOCOL); + + $stream2 = new NetworkBinaryStream(); + $stream2->putLInt(strlen($payload)); + $stream2->put($payload); + $stream->putString($stream2->getBuffer()); + + $pk = PacketPool::getInstance()->getPacket($stream->getBuffer()); + + $this->expectException(PacketDecodeException::class); + $pk->decode(); //bang + } +} From a6c35cab9ace6ebf582f2bad0d1a78c17248ac2f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 May 2020 22:00:11 +0100 Subject: [PATCH 1533/3224] JwtUtils: fix phpstan failure --- src/network/mcpe/JwtUtils.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/network/mcpe/JwtUtils.php b/src/network/mcpe/JwtUtils.php index 1ef186ef22..503ca2a517 100644 --- a/src/network/mcpe/JwtUtils.php +++ b/src/network/mcpe/JwtUtils.php @@ -36,12 +36,7 @@ final class JwtUtils{ if(count($v) !== 3){ throw new \UnexpectedValueException("Expected exactly 3 JWT parts, got " . count($v)); } - $payloadB64 = $v[1]; - $payloadJSON = self::b64UrlDecode($payloadB64); - if($payloadJSON === false){ - throw new \UnexpectedValueException("Invalid base64 JWT payload"); - } - $result = json_decode($payloadJSON, true); + $result = json_decode(self::b64UrlDecode($v[1]), true); if(!is_array($result)){ throw new \UnexpectedValueException("Failed to decode JWT payload JSON: " . json_last_error_msg()); } From 8efe7fcfb0b0f86e86e127b1c0c7b3200f77d196 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 10 May 2020 11:50:31 +0100 Subject: [PATCH 1534/3224] World: allow configuring blocks-per-tick for random updating this makes it much easier to observe and debug stuff that depends on it, such as grass, crop and tree growth, since they'll happen much faster. A future improvement would be to have the update function use a non-global random so that the output can be reproduced using a given seed. --- resources/pocketmine.yml | 3 +++ src/world/World.php | 13 +++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/resources/pocketmine.yml b/resources/pocketmine.yml index fdbc80f6f7..e218eaf404 100644 --- a/resources/pocketmine.yml +++ b/resources/pocketmine.yml @@ -120,6 +120,9 @@ chunk-ticking: per-tick: 40 #Radius of chunks around a player to tick tick-radius: 3 + #Number of blocks inside ticking areas' subchunks that get ticked every tick. Higher values will accelerate events + #like tree and plant growth, but at a higher performance cost. + blocks-per-subchunk-per-tick: 3 #IDs of blocks not to perform random ticking on. disable-block-ticking: #- 2 # grass diff --git a/src/world/World.php b/src/world/World.php index 054737ce97..4964461907 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -125,6 +125,8 @@ class World implements ChunkManager{ public const DIFFICULTY_NORMAL = 2; public const DIFFICULTY_HARD = 3; + public const DEFAULT_TICKED_BLOCKS_PER_SUBCHUNK_PER_TICK = 3; + /** @var Player[] */ private $players = []; @@ -226,6 +228,8 @@ class World implements ChunkManager{ private $chunkTickRadius; /** @var int */ private $chunksPerTick; + /** @var int */ + private $tickedBlocksPerSubchunkPerTick = self::DEFAULT_TICKED_BLOCKS_PER_SUBCHUNK_PER_TICK; /** @var bool[] */ private $randomTickBlocks = []; @@ -342,6 +346,7 @@ class World implements ChunkManager{ $this->chunkTickRadius = min($this->server->getViewDistance(), max(1, (int) $this->server->getProperty("chunk-ticking.tick-radius", 4))); $this->chunksPerTick = (int) $this->server->getProperty("chunk-ticking.per-tick", 40); + $this->tickedBlocksPerSubchunkPerTick = (int) $this->server->getProperty("chunk-ticking.blocks-per-subchunk-per-tick", self::DEFAULT_TICKED_BLOCKS_PER_SUBCHUNK_PER_TICK); $this->chunkPopulationQueueSize = (int) $this->server->getProperty("chunk-generation.population-queue-size", 2); $dontTickBlocks = array_fill_keys($this->server->getProperty("chunk-ticking.disable-block-ticking", []), true); @@ -910,8 +915,12 @@ class World implements ChunkManager{ foreach($chunk->getSubChunks() as $Y => $subChunk){ if(!$subChunk->isEmptyFast()){ - $k = mt_rand(0, 0xfffffffff); //36 bits - for($i = 0; $i < 3; ++$i){ + $k = 0; + for($i = 0; $i < $this->tickedBlocksPerSubchunkPerTick; ++$i){ + if(($i % 5) === 0){ + //60 bits will be used by 5 blocks (12 bits each) + $k = mt_rand(0, (1 << 60) - 1); + } $x = $k & 0x0f; $y = ($k >> 4) & 0x0f; $z = ($k >> 8) & 0x0f; From 65e359584e62866b3578ae548681cae119835f82 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 10 May 2020 11:59:03 +0100 Subject: [PATCH 1535/3224] Updated RakLib to pmmp/RakLib@12153dc --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 84327e9301..ce5cec32fe 100644 --- a/composer.lock +++ b/composer.lock @@ -618,12 +618,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "ef39315146790d0f6940dd47ee57b1c13614ce19" + "reference": "12153dcd1e37d1d1b026db65605210f094579861" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/ef39315146790d0f6940dd47ee57b1c13614ce19", - "reference": "ef39315146790d0f6940dd47ee57b1c13614ce19", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/12153dcd1e37d1d1b026db65605210f094579861", + "reference": "12153dcd1e37d1d1b026db65605210f094579861", "shasum": "" }, "require": { @@ -649,7 +649,7 @@ "GPL-3.0" ], "description": "A RakNet server implementation written in PHP", - "time": "2020-04-28T20:06:17+00:00" + "time": "2020-05-10T10:47:44+00:00" }, { "name": "pocketmine/snooze", From 3299bc4023c6c83a54e0698695cece41e70e142d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 10 May 2020 13:04:40 +0100 Subject: [PATCH 1536/3224] start using pocketmine/errorhandler --- composer.json | 1 + composer.lock | 36 ++++++++++++++++++++++++++- src/CrashDump.php | 3 ++- src/PocketMine.php | 3 ++- src/thread/CommonThreadPartsTrait.php | 3 ++- src/utils/MainLogger.php | 3 ++- 6 files changed, 44 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 9f9fccd28f..e2ca398005 100644 --- a/composer.json +++ b/composer.json @@ -41,6 +41,7 @@ "pocketmine/classloader": "dev-master", "pocketmine/log-pthreads": "dev-master", "pocketmine/callback-validator": "^1.0.1", + "pocketmine/errorhandler": "^0.1.0", "adhocore/json-comment": "^0.1.0", "particle/validator": "^2.3", "netresearch/jsonmapper": "^2.0", diff --git a/composer.lock b/composer.lock index ce5cec32fe..27f3211118 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "da1e60f0dfc0109a44d3a47b311ae8e5", + "content-hash": "e5a2f9b7992a8ed0050a9745ec04e569", "packages": [ { "name": "adhocore/json-comment", @@ -465,6 +465,40 @@ "description": "Ad-hoc autoloading components used by PocketMine-MP", "time": "2020-01-31T14:26:22+00:00" }, + { + "name": "pocketmine/errorhandler", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/pmmp/ErrorHandler.git", + "reference": "0503a1929a3934e754114814509ff9152f4908eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pmmp/ErrorHandler/zipball/0503a1929a3934e754114814509ff9152f4908eb", + "reference": "0503a1929a3934e754114814509ff9152f4908eb", + "shasum": "" + }, + "require": { + "php": "^7.2" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.23", + "phpstan/phpstan-strict-rules": "^0.12.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "pocketmine\\errorhandler\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0" + ], + "description": "Utilities to handle nasty PHP E_* errors in a usable way", + "time": "2020-05-10T11:45:02+00:00" + }, { "name": "pocketmine/log", "version": "dev-master", diff --git a/src/CrashDump.php b/src/CrashDump.php index 632cf59bc0..d3ca48cce7 100644 --- a/src/CrashDump.php +++ b/src/CrashDump.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine; use PackageVersions\Versions; +use pocketmine\errorhandler\ErrorTypeToStringMap; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\plugin\PluginBase; use pocketmine\plugin\PluginManager; @@ -220,7 +221,7 @@ class CrashDump{ $error["fullFile"] = $error["file"]; $error["file"] = Filesystem::cleanPath($error["file"]); try{ - $error["type"] = \ErrorUtils::errorTypeToString($error["type"]); + $error["type"] = ErrorTypeToStringMap::get($error["type"]); }catch(\InvalidArgumentException $e){ //pass } diff --git a/src/PocketMine.php b/src/PocketMine.php index 3830c2ffe5..ddaa3bcc38 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine { + use pocketmine\errorhandler\ErrorToExceptionHandler; use pocketmine\thread\ThreadManager; use pocketmine\utils\Filesystem; use pocketmine\utils\Git; @@ -194,7 +195,7 @@ namespace pocketmine { \parallel\bootstrap(\pocketmine\COMPOSER_AUTOLOADER_PATH); } - \ErrorUtils::setErrorExceptionHandler(); + ErrorToExceptionHandler::set(); $version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER); define('pocketmine\VERSION', $version->getFullVersion(true)); diff --git a/src/thread/CommonThreadPartsTrait.php b/src/thread/CommonThreadPartsTrait.php index e6cd6af54b..7ce63983a9 100644 --- a/src/thread/CommonThreadPartsTrait.php +++ b/src/thread/CommonThreadPartsTrait.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\thread; +use pocketmine\errorhandler\ErrorToExceptionHandler; use pocketmine\Server; use function error_reporting; @@ -68,7 +69,7 @@ trait CommonThreadPartsTrait{ error_reporting(-1); $this->registerClassLoader(); //set this after the autoloader is registered - \ErrorUtils::setErrorExceptionHandler(); + ErrorToExceptionHandler::set(); $this->onRun(); } diff --git a/src/utils/MainLogger.php b/src/utils/MainLogger.php index 120768cca3..ed3abded9a 100644 --- a/src/utils/MainLogger.php +++ b/src/utils/MainLogger.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\utils; use LogLevel; +use pocketmine\errorhandler\ErrorTypeToStringMap; use pocketmine\thread\Thread; use pocketmine\thread\Worker; use function fclose; @@ -170,7 +171,7 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ $errno = $e->getCode(); try{ - $errno = \ErrorUtils::errorTypeToString($errno); + $errno = ErrorTypeToStringMap::get($errno); }catch(\InvalidArgumentException $e){ //pass } From cb33f408a18244114b319e8cd03a564d6f6817db Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 10 May 2020 13:08:48 +0100 Subject: [PATCH 1537/3224] updated pocketmine/spl to get rid of ErrorUtils --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 27f3211118..68341f7549 100644 --- a/composer.lock +++ b/composer.lock @@ -725,12 +725,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/SPL.git", - "reference": "9856cb78ebeeea40375a432a4f87aa47307b9351" + "reference": "98589af98ff5662f4f69a76bdbf3129c9e2e3614" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/SPL/zipball/9856cb78ebeeea40375a432a4f87aa47307b9351", - "reference": "9856cb78ebeeea40375a432a4f87aa47307b9351", + "url": "https://api.github.com/repos/pmmp/SPL/zipball/98589af98ff5662f4f69a76bdbf3129c9e2e3614", + "reference": "98589af98ff5662f4f69a76bdbf3129c9e2e3614", "shasum": "" }, "require": { @@ -750,7 +750,7 @@ "LGPL-3.0" ], "description": "Standard library files required by PocketMine-MP and related projects", - "time": "2020-01-31T16:18:46+00:00" + "time": "2020-05-10T12:05:24+00:00" } ], "packages-dev": [ From b7cf4f01f9f1e78f91f4b5b7e02fcbab2501ac1e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 May 2020 10:46:48 +0100 Subject: [PATCH 1538/3224] remove utils\UUID, switch to pocketmine/uuid package --- composer.json | 1 + composer.lock | 37 ++++- src/Server.php | 2 +- src/crafting/CraftingManager.php | 2 +- src/entity/Human.php | 2 +- .../mcpe/handler/LoginPacketHandler.php | 2 +- src/network/mcpe/protocol/AddPlayerPacket.php | 2 +- .../mcpe/protocol/CraftingEventPacket.php | 2 +- .../mcpe/protocol/PlayerSkinPacket.php | 2 +- .../serializer/NetworkBinaryStream.php | 2 +- .../mcpe/protocol/types/PlayerListEntry.php | 2 +- src/network/mcpe/protocol/types/SkinData.php | 2 +- .../types/command/CommandOriginData.php | 2 +- .../protocol/types/recipe/MultiRecipe.php | 2 +- .../protocol/types/recipe/ShapedRecipe.php | 2 +- .../protocol/types/recipe/ShapelessRecipe.php | 2 +- src/player/Player.php | 2 +- src/player/PlayerInfo.php | 2 +- src/stats/SendUsageTask.php | 2 +- src/utils/UUID.php | 132 ------------------ src/utils/Utils.php | 1 + src/world/particle/FloatingTextParticle.php | 2 +- 22 files changed, 56 insertions(+), 151 deletions(-) delete mode 100644 src/utils/UUID.php diff --git a/composer.json b/composer.json index e2ca398005..11a8f8eb6b 100644 --- a/composer.json +++ b/composer.json @@ -42,6 +42,7 @@ "pocketmine/log-pthreads": "dev-master", "pocketmine/callback-validator": "^1.0.1", "pocketmine/errorhandler": "^0.1.0", + "pocketmine/uuid": "^0.1.0", "adhocore/json-comment": "^0.1.0", "particle/validator": "^2.3", "netresearch/jsonmapper": "^2.0", diff --git a/composer.lock b/composer.lock index 68341f7549..eef9e14ff9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e5a2f9b7992a8ed0050a9745ec04e569", + "content-hash": "a852a026a0a9f5ca2dbea5c06aab4856", "packages": [ { "name": "adhocore/json-comment", @@ -751,6 +751,41 @@ ], "description": "Standard library files required by PocketMine-MP and related projects", "time": "2020-05-10T12:05:24+00:00" + }, + { + "name": "pocketmine/uuid", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/pmmp/UUID.git", + "reference": "c45c995cb87eafee01a14a06a4b7b517cada03a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pmmp/UUID/zipball/c45c995cb87eafee01a14a06a4b7b517cada03a5", + "reference": "c45c995cb87eafee01a14a06a4b7b517cada03a5", + "shasum": "" + }, + "require": { + "php": "^7.3", + "pocketmine/binaryutils": "^0.1 || dev-master" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.23", + "phpstan/phpstan-strict-rules": "^0.12.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "pocketmine\\uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0" + ], + "description": "Basic UUID implementation used by PocketMine-MP and related projects", + "time": "2020-05-10T12:38:41+00:00" } ], "packages-dev": [ diff --git a/src/Server.php b/src/Server.php index 3aaa1eb2d7..20347fb046 100644 --- a/src/Server.php +++ b/src/Server.php @@ -88,7 +88,7 @@ use pocketmine\utils\Process; use pocketmine\utils\Terminal; use pocketmine\utils\TextFormat; use pocketmine\utils\Utils; -use pocketmine\utils\UUID; +use pocketmine\uuid\UUID; use pocketmine\world\biome\Biome; use pocketmine\world\format\io\WorldProviderManager; use pocketmine\world\format\io\WritableWorldProvider; diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index fe51038e71..ec2d6effbd 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -36,7 +36,7 @@ use pocketmine\network\mcpe\protocol\types\recipe\ShapedRecipe as ProtocolShaped use pocketmine\network\mcpe\protocol\types\recipe\ShapelessRecipe as ProtocolShapelessRecipe; use pocketmine\timings\Timings; use pocketmine\utils\Binary; -use pocketmine\utils\UUID; +use pocketmine\uuid\UUID; use function array_map; use function json_encode; use function spl_object_id; diff --git a/src/entity/Human.php b/src/entity/Human.php index 2e647b84a9..ff0a843c78 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -53,7 +53,7 @@ use pocketmine\network\mcpe\protocol\types\entity\StringMetadataProperty; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\player\Player; use pocketmine\utils\Limits; -use pocketmine\utils\UUID; +use pocketmine\uuid\UUID; use pocketmine\world\sound\TotemUseSound; use pocketmine\world\World; use function array_filter; diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index 6b2f7faa73..243bbe2adc 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -42,7 +42,7 @@ use pocketmine\network\mcpe\protocol\types\SkinImage; use pocketmine\player\Player; use pocketmine\player\PlayerInfo; use pocketmine\Server; -use pocketmine\utils\UUID; +use pocketmine\uuid\UUID; use function array_map; use function base64_decode; diff --git a/src/network/mcpe/protocol/AddPlayerPacket.php b/src/network/mcpe/protocol/AddPlayerPacket.php index 8c151bf89d..289f6e08d3 100644 --- a/src/network/mcpe/protocol/AddPlayerPacket.php +++ b/src/network/mcpe/protocol/AddPlayerPacket.php @@ -30,7 +30,7 @@ use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\utils\UUID; +use pocketmine\uuid\UUID; use function count; class AddPlayerPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/network/mcpe/protocol/CraftingEventPacket.php b/src/network/mcpe/protocol/CraftingEventPacket.php index 847e5ae03c..744de3c565 100644 --- a/src/network/mcpe/protocol/CraftingEventPacket.php +++ b/src/network/mcpe/protocol/CraftingEventPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\utils\UUID; +use pocketmine\uuid\UUID; use function count; class CraftingEventPacket extends DataPacket implements ServerboundPacket{ diff --git a/src/network/mcpe/protocol/PlayerSkinPacket.php b/src/network/mcpe/protocol/PlayerSkinPacket.php index f1128c9b79..37e335e77a 100644 --- a/src/network/mcpe/protocol/PlayerSkinPacket.php +++ b/src/network/mcpe/protocol/PlayerSkinPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\SkinData; -use pocketmine\utils\UUID; +use pocketmine\uuid\UUID; class PlayerSkinPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAYER_SKIN_PACKET; diff --git a/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php b/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php index bfe2eefbbd..8b9eaedbcf 100644 --- a/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php +++ b/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php @@ -55,7 +55,7 @@ use pocketmine\network\mcpe\protocol\types\StructureEditorData; use pocketmine\network\mcpe\protocol\types\StructureSettings; use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; -use pocketmine\utils\UUID; +use pocketmine\uuid\UUID; use function count; use function strlen; diff --git a/src/network/mcpe/protocol/types/PlayerListEntry.php b/src/network/mcpe/protocol/types/PlayerListEntry.php index 1393bf48b0..013eb0812b 100644 --- a/src/network/mcpe/protocol/types/PlayerListEntry.php +++ b/src/network/mcpe/protocol/types/PlayerListEntry.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types; -use pocketmine\utils\UUID; +use pocketmine\uuid\UUID; class PlayerListEntry{ diff --git a/src/network/mcpe/protocol/types/SkinData.php b/src/network/mcpe/protocol/types/SkinData.php index 1393748b45..151c94297b 100644 --- a/src/network/mcpe/protocol/types/SkinData.php +++ b/src/network/mcpe/protocol/types/SkinData.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types; -use pocketmine\utils\UUID; +use pocketmine\uuid\UUID; class SkinData{ diff --git a/src/network/mcpe/protocol/types/command/CommandOriginData.php b/src/network/mcpe/protocol/types/command/CommandOriginData.php index 4214f8a0e5..3cd5237015 100644 --- a/src/network/mcpe/protocol/types/command/CommandOriginData.php +++ b/src/network/mcpe/protocol/types/command/CommandOriginData.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\command; -use pocketmine\utils\UUID; +use pocketmine\uuid\UUID; class CommandOriginData{ public const ORIGIN_PLAYER = 0; diff --git a/src/network/mcpe/protocol/types/recipe/MultiRecipe.php b/src/network/mcpe/protocol/types/recipe/MultiRecipe.php index 559a266178..bd23b231af 100644 --- a/src/network/mcpe/protocol/types/recipe/MultiRecipe.php +++ b/src/network/mcpe/protocol/types/recipe/MultiRecipe.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\recipe; use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; -use pocketmine\utils\UUID; +use pocketmine\uuid\UUID; final class MultiRecipe extends RecipeWithTypeId{ diff --git a/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php b/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php index 00c9360776..4a868ac73f 100644 --- a/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php +++ b/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol\types\recipe; use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\utils\UUID; +use pocketmine\uuid\UUID; use function count; final class ShapedRecipe extends RecipeWithTypeId{ diff --git a/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php b/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php index f6e54c0a09..acffe7fb1b 100644 --- a/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php +++ b/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol\types\recipe; use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\utils\UUID; +use pocketmine\uuid\UUID; use function count; final class ShapelessRecipe extends RecipeWithTypeId{ diff --git a/src/player/Player.php b/src/player/Player.php index a8af8829bf..92564f441f 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -96,7 +96,7 @@ use pocketmine\permission\PermissionManager; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\TextFormat; -use pocketmine\utils\UUID; +use pocketmine\uuid\UUID; use pocketmine\world\ChunkListener; use pocketmine\world\ChunkListenerNoOpTrait; use pocketmine\world\ChunkLoader; diff --git a/src/player/PlayerInfo.php b/src/player/PlayerInfo.php index a3120edce6..dee690aa1d 100644 --- a/src/player/PlayerInfo.php +++ b/src/player/PlayerInfo.php @@ -25,7 +25,7 @@ namespace pocketmine\player; use pocketmine\entity\Skin; use pocketmine\utils\TextFormat; -use pocketmine\utils\UUID; +use pocketmine\uuid\UUID; /** * Encapsulates data needed to create a player. diff --git a/src/stats/SendUsageTask.php b/src/stats/SendUsageTask.php index afa69ed6b4..d68f506080 100644 --- a/src/stats/SendUsageTask.php +++ b/src/stats/SendUsageTask.php @@ -31,8 +31,8 @@ use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Internet; use pocketmine\utils\Process; use pocketmine\utils\Utils; -use pocketmine\utils\UUID; use pocketmine\utils\VersionString; +use pocketmine\uuid\UUID; use function array_map; use function array_values; use function count; diff --git a/src/utils/UUID.php b/src/utils/UUID.php deleted file mode 100644 index 05e0715e44..0000000000 --- a/src/utils/UUID.php +++ /dev/null @@ -1,132 +0,0 @@ -parts = [$part1, $part2, $part3, $part4]; - - $this->version = $version ?? ($this->parts[1] & 0xf000) >> 12; - } - - public function getVersion() : int{ - return $this->version; - } - - public function equals(UUID $uuid) : bool{ - return $uuid->parts === $this->parts; - } - - /** - * Creates an UUID from an hexadecimal representation - */ - public static function fromString(string $uuid, ?int $version = null) : UUID{ - //TODO: should we be stricter about the notation (8-4-4-4-12)? - $binary = @hex2bin(str_replace("-", "", trim($uuid))); - if($binary === false){ - throw new \InvalidArgumentException("Invalid hex string UUID representation"); - } - return self::fromBinary($binary, $version); - } - - /** - * Creates an UUID from a binary representation - * - * @throws \InvalidArgumentException - */ - public static function fromBinary(string $uuid, ?int $version = null) : UUID{ - if(strlen($uuid) !== 16){ - throw new \InvalidArgumentException("Must have exactly 16 bytes"); - } - - return new UUID(Binary::readInt(substr($uuid, 0, 4)), Binary::readInt(substr($uuid, 4, 4)), Binary::readInt(substr($uuid, 8, 4)), Binary::readInt(substr($uuid, 12, 4)), $version); - } - - /** - * Creates an UUIDv3 from binary data or list of binary data - * - * @param string ...$data - */ - public static function fromData(string ...$data) : UUID{ - $hash = hash("md5", implode($data), true); - - return self::fromBinary($hash, 3); - } - - public static function fromRandom() : UUID{ - return self::fromData(Binary::writeInt(time()), Binary::writeShort(getmypid()), Binary::writeShort(getmyuid()), Binary::writeInt(mt_rand(-0x7fffffff, 0x7fffffff)), Binary::writeInt(mt_rand(-0x7fffffff, 0x7fffffff))); - } - - public function toBinary() : string{ - return Binary::writeInt($this->parts[0]) . Binary::writeInt($this->parts[1]) . Binary::writeInt($this->parts[2]) . Binary::writeInt($this->parts[3]); - } - - public function toString() : string{ - $hex = bin2hex($this->toBinary()); - - //xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx 8-4-4-4-12 - return substr($hex, 0, 8) . "-" . substr($hex, 8, 4) . "-" . substr($hex, 12, 4) . "-" . substr($hex, 16, 4) . "-" . substr($hex, 20, 12); - } - - public function __toString() : string{ - return $this->toString(); - } - - /** - * @return int - * @throws \InvalidArgumentException - */ - public function getPart(int $partNumber){ - if($partNumber < 0 or $partNumber > 3){ - throw new \InvalidArgumentException("Invalid UUID part index $partNumber"); - } - return $this->parts[$partNumber]; - } - - /** - * @return int[] - */ - public function getParts() : array{ - return $this->parts; - } -} diff --git a/src/utils/Utils.php b/src/utils/Utils.php index 4fe1cd973e..e858cbc948 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -28,6 +28,7 @@ declare(strict_types=1); namespace pocketmine\utils; use DaveRandom\CallbackValidator\CallbackType; +use pocketmine\uuid\UUID; use function array_combine; use function array_map; use function array_reverse; diff --git a/src/world/particle/FloatingTextParticle.php b/src/world/particle/FloatingTextParticle.php index 0d5e467867..5a99f9df08 100644 --- a/src/world/particle/FloatingTextParticle.php +++ b/src/world/particle/FloatingTextParticle.php @@ -36,7 +36,7 @@ use pocketmine\network\mcpe\protocol\types\entity\FloatMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\LongMetadataProperty; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; -use pocketmine\utils\UUID; +use pocketmine\uuid\UUID; use function str_repeat; class FloatingTextParticle implements Particle{ From e3dec95b756545e8dc0075013e3fd35b7c043eb4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 May 2020 11:26:56 +0100 Subject: [PATCH 1539/3224] Convert AsyncPool tests into PHPUnit tests --- tests/phpunit/scheduler/AsyncPoolTest.php | 74 +++++++++++++++++++ .../scheduler/LeakTestAsyncTask.php} | 29 +------- .../PublishProgressRaceAsyncTask.php | 40 ++++++++++ .../src/pmmp/TesterPlugin/Main.php | 5 +- .../AsyncTaskPublishProgressRaceTest.php | 69 ----------------- 5 files changed, 119 insertions(+), 98 deletions(-) create mode 100644 tests/phpunit/scheduler/AsyncPoolTest.php rename tests/{plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMemoryLeakTest.php => phpunit/scheduler/LeakTestAsyncTask.php} (59%) create mode 100644 tests/phpunit/scheduler/PublishProgressRaceAsyncTask.php delete mode 100644 tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskPublishProgressRaceTest.php diff --git a/tests/phpunit/scheduler/AsyncPoolTest.php b/tests/phpunit/scheduler/AsyncPoolTest.php new file mode 100644 index 0000000000..f2a521ead5 --- /dev/null +++ b/tests/phpunit/scheduler/AsyncPoolTest.php @@ -0,0 +1,74 @@ +mainLogger = new MainLogger(tempnam(sys_get_temp_dir(), "pmlog")); + $this->pool = new AsyncPool(2, 1024, new \BaseClassLoader(), $this->mainLogger); + } + + public function tearDown() : void{ + $this->pool->shutdown(); + $this->mainLogger->shutdown(); + $this->mainLogger->join(); + } + + public function testTaskLeak() : void{ + $start = microtime(true); + $this->pool->submitTask(new LeakTestAsyncTask()); + while(!LeakTestAsyncTask::$destroyed and microtime(true) < $start + 30){ + usleep(50 * 1000); + $this->pool->collectTasks(); + } + self::assertTrue(LeakTestAsyncTask::$destroyed, "Task was not destroyed after 30 seconds"); + } + + public function testPublishProgressRace() : void{ + $task = new PublishProgressRaceAsyncTask(); + $this->pool->submitTask($task); + while($this->pool->collectTasks()){ + usleep(50 * 1000); + } + self::assertTrue(PublishProgressRaceAsyncTask::$success, "Progress was not reported before task completion"); + } +} diff --git a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMemoryLeakTest.php b/tests/phpunit/scheduler/LeakTestAsyncTask.php similarity index 59% rename from tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMemoryLeakTest.php rename to tests/phpunit/scheduler/LeakTestAsyncTask.php index eba13c43ca..942b751d78 100644 --- a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskMemoryLeakTest.php +++ b/tests/phpunit/scheduler/LeakTestAsyncTask.php @@ -21,33 +21,12 @@ declare(strict_types=1); -namespace pmmp\TesterPlugin\tests; +namespace pocketmine\scheduler; -use pmmp\TesterPlugin\Test; -use pocketmine\scheduler\AsyncTask; +use function usleep; -class AsyncTaskMemoryLeakTest extends Test{ - - public function run(){ - $this->getPlugin()->getServer()->getAsyncPool()->submitTask(new TestAsyncTask()); - } - - public function tick(){ - if(TestAsyncTask::$destroyed === true){ - $this->setResult(Test::RESULT_OK); - } - } - - public function getName() : string{ - return "AsyncTask memory leak after completion"; - } - - public function getDescription() : string{ - return "Regression test for AsyncTasks objects not being destroyed after completion"; - } -} - -class TestAsyncTask extends AsyncTask{ +class LeakTestAsyncTask extends AsyncTask{ + /** @var bool */ public static $destroyed = false; public function onRun() : void{ diff --git a/tests/phpunit/scheduler/PublishProgressRaceAsyncTask.php b/tests/phpunit/scheduler/PublishProgressRaceAsyncTask.php new file mode 100644 index 0000000000..6c70d26202 --- /dev/null +++ b/tests/phpunit/scheduler/PublishProgressRaceAsyncTask.php @@ -0,0 +1,40 @@ +publishProgress("hello"); + } + + public function onProgressUpdate($progress) : void{ + if($progress === "hello"){ + // thread local on main thread + self::$success = true; + } + } +} diff --git a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/Main.php b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/Main.php index 7b40795b82..b28d8c7e69 100644 --- a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/Main.php +++ b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/Main.php @@ -42,10 +42,7 @@ class Main extends PluginBase implements Listener{ $this->getServer()->getPluginManager()->registerEvents($this, $this); $this->getScheduler()->scheduleRepeatingTask(new CheckTestCompletionTask($this), 10); - $this->waitingTests = [ - new tests\AsyncTaskMemoryLeakTest($this), - new tests\AsyncTaskPublishProgressRaceTest($this) - ]; + $this->waitingTests = []; } public function onServerCommand(CommandEvent $event){ diff --git a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskPublishProgressRaceTest.php b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskPublishProgressRaceTest.php deleted file mode 100644 index ea637a57d7..0000000000 --- a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/tests/AsyncTaskPublishProgressRaceTest.php +++ /dev/null @@ -1,69 +0,0 @@ -getPlugin()->getServer()->getAsyncPool()->submitTask(new class($this) extends AsyncTask{ - private const TLS_KEY_TEST = "test"; - - private static $success = false; - - public function __construct(AsyncTaskPublishProgressRaceTest $t){ - $this->storeLocal(self::TLS_KEY_TEST, $t); - } - - public function onRun() : void{ - $this->publishProgress("hello"); - } - - public function onProgressUpdate($progress) : void{ - if($progress === "hello"){ - // thread local on main thread - self::$success = true; - } - } - - public function onCompletion() : void{ - /** @var AsyncTaskPublishProgressRaceTest $t */ - $t = $this->fetchLocal(self::TLS_KEY_TEST); - $t->setResult(self::$success ? Test::RESULT_OK : Test::RESULT_FAILED); - } - }); - } -} From 6b037d6a4ccafd3c9dc1273c0a19be586fea1952 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 May 2020 12:40:55 +0100 Subject: [PATCH 1540/3224] RuntimeBlockMapping: these IDs are not static any more --- src/block/Block.php | 2 +- src/network/mcpe/convert/RuntimeBlockMapping.php | 4 ++-- src/network/mcpe/serializer/ChunkSerializer.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/block/Block.php b/src/block/Block.php index d97471555b..f77607b463 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -111,7 +111,7 @@ class Block{ * @internal */ public function getRuntimeId() : int{ - return RuntimeBlockMapping::getInstance()->toStaticRuntimeId($this->getId(), $this->getMeta()); + return RuntimeBlockMapping::getInstance()->toRuntimeId($this->getId(), $this->getMeta()); } public function getMeta() : int{ diff --git a/src/network/mcpe/convert/RuntimeBlockMapping.php b/src/network/mcpe/convert/RuntimeBlockMapping.php index 0f0445251a..4aef0c5432 100644 --- a/src/network/mcpe/convert/RuntimeBlockMapping.php +++ b/src/network/mcpe/convert/RuntimeBlockMapping.php @@ -127,7 +127,7 @@ final class RuntimeBlockMapping{ return $table; } - public function toStaticRuntimeId(int $id, int $meta = 0) : int{ + public function toRuntimeId(int $id, int $meta = 0) : int{ /* * try id+meta first * if not found, try id+0 (strip meta) @@ -139,7 +139,7 @@ final class RuntimeBlockMapping{ /** * @return int[] [id, meta] */ - public function fromStaticRuntimeId(int $runtimeId) : array{ + public function fromRuntimeId(int $runtimeId) : array{ $v = $this->runtimeToLegacyMap[$runtimeId]; return [$v >> 4, $v & 0xf]; } diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index 94ce8e89ce..54f79222c2 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -70,7 +70,7 @@ final class ChunkSerializer{ //zigzag and just shift directly. $stream->putUnsignedVarInt(count($palette) << 1); //yes, this is intentionally zigzag foreach($palette as $p){ - $stream->putUnsignedVarInt($blockMapper->toStaticRuntimeId($p >> 4, $p & 0xf) << 1); + $stream->putUnsignedVarInt($blockMapper->toRuntimeId($p >> 4, $p & 0xf) << 1); } } } From 3238b4ff33ec3caa06b4547d2838930dea20937b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 May 2020 19:25:52 +0100 Subject: [PATCH 1541/3224] Remove PluginIdentifiableCommand in favour of a more generic PluginOwned interface --- src/Server.php | 8 ++-- src/command/PluginCommand.php | 12 ++---- src/plugin/PluginBase.php | 8 ++-- .../PluginOwned.php} | 11 ++--- src/plugin/PluginOwnedTrait.php | 40 +++++++++++++++++++ tests/plugins/PocketMine-DevTools | 2 +- 6 files changed, 60 insertions(+), 21 deletions(-) rename src/{command/PluginIdentifiableCommand.php => plugin/PluginOwned.php} (76%) create mode 100644 src/plugin/PluginOwnedTrait.php diff --git a/src/Server.php b/src/Server.php index 20347fb046..22cb9a9ab4 100644 --- a/src/Server.php +++ b/src/Server.php @@ -27,10 +27,10 @@ declare(strict_types=1); */ namespace pocketmine; +use pocketmine\command\Command; use pocketmine\command\CommandReader; use pocketmine\command\CommandSender; use pocketmine\command\ConsoleCommandSender; -use pocketmine\command\PluginIdentifiableCommand; use pocketmine\command\SimpleCommandMap; use pocketmine\crafting\CraftingManager; use pocketmine\crafting\CraftingManagerFromDataHelper; @@ -71,6 +71,7 @@ use pocketmine\plugin\Plugin; use pocketmine\plugin\PluginGraylist; use pocketmine\plugin\PluginLoadOrder; use pocketmine\plugin\PluginManager; +use pocketmine\plugin\PluginOwned; use pocketmine\plugin\ScriptPluginLoader; use pocketmine\resourcepacks\ResourcePackManager; use pocketmine\scheduler\AsyncPool; @@ -694,10 +695,11 @@ class Server{ } /** - * @return PluginIdentifiableCommand|null + * @return Command|PluginOwned|null + * @phpstan-return (Command&PluginOwned)|null */ public function getPluginCommand(string $name){ - if(($command = $this->commandMap->getCommand($name)) instanceof PluginIdentifiableCommand){ + if(($command = $this->commandMap->getCommand($name)) instanceof PluginOwned){ return $command; }else{ return null; diff --git a/src/command/PluginCommand.php b/src/command/PluginCommand.php index 827239c268..d4c0abf64c 100644 --- a/src/command/PluginCommand.php +++ b/src/command/PluginCommand.php @@ -25,11 +25,11 @@ namespace pocketmine\command; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\plugin\Plugin; +use pocketmine\plugin\PluginOwned; +use pocketmine\plugin\PluginOwnedTrait; -class PluginCommand extends Command implements PluginIdentifiableCommand{ - - /** @var Plugin */ - private $owningPlugin; +class PluginCommand extends Command implements PluginOwned{ + use PluginOwnedTrait; /** @var CommandExecutor */ private $executor; @@ -67,8 +67,4 @@ class PluginCommand extends Command implements PluginIdentifiableCommand{ public function setExecutor(CommandExecutor $executor) : void{ $this->executor = $executor; } - - public function getPlugin() : Plugin{ - return $this->owningPlugin; - } } diff --git a/src/plugin/PluginBase.php b/src/plugin/PluginBase.php index 63ddd10a7b..8f5c0d3b80 100644 --- a/src/plugin/PluginBase.php +++ b/src/plugin/PluginBase.php @@ -27,7 +27,6 @@ use pocketmine\command\Command; use pocketmine\command\CommandExecutor; use pocketmine\command\CommandSender; use pocketmine\command\PluginCommand; -use pocketmine\command\PluginIdentifiableCommand; use pocketmine\scheduler\TaskScheduler; use pocketmine\Server; use pocketmine\utils\AssumptionFailedError; @@ -223,15 +222,16 @@ abstract class PluginBase implements Plugin, CommandExecutor{ } /** - * @return Command|PluginIdentifiableCommand|null + * @return Command|PluginOwned|null + * @phpstan-return (Command&PluginOwned)|null */ public function getCommand(string $name){ $command = $this->getServer()->getPluginCommand($name); - if($command === null or $command->getPlugin() !== $this){ + if($command === null or $command->getOwningPlugin() !== $this){ $command = $this->getServer()->getPluginCommand(strtolower($this->description->getName()) . ":" . $name); } - if($command instanceof PluginIdentifiableCommand and $command->getPlugin() === $this){ + if($command instanceof PluginOwned and $command->getOwningPlugin() === $this){ return $command; }else{ return null; diff --git a/src/command/PluginIdentifiableCommand.php b/src/plugin/PluginOwned.php similarity index 76% rename from src/command/PluginIdentifiableCommand.php rename to src/plugin/PluginOwned.php index 02e85f7e92..8497c78663 100644 --- a/src/command/PluginIdentifiableCommand.php +++ b/src/plugin/PluginOwned.php @@ -21,11 +21,12 @@ declare(strict_types=1); -namespace pocketmine\command; +namespace pocketmine\plugin; -use pocketmine\plugin\Plugin; +/** + * This interface may be implemented by objects which are owned by plugins, to allow them to be identified as such. + */ +interface PluginOwned{ -interface PluginIdentifiableCommand{ - - public function getPlugin() : Plugin; + public function getOwningPlugin() : Plugin; } diff --git a/src/plugin/PluginOwnedTrait.php b/src/plugin/PluginOwnedTrait.php new file mode 100644 index 0000000000..278108c607 --- /dev/null +++ b/src/plugin/PluginOwnedTrait.php @@ -0,0 +1,40 @@ +owningPlugin = $owningPlugin; + } + + public function getOwningPlugin() : Plugin{ + return $this->owningPlugin; + } +} diff --git a/tests/plugins/PocketMine-DevTools b/tests/plugins/PocketMine-DevTools index beb079c256..aef2b10185 160000 --- a/tests/plugins/PocketMine-DevTools +++ b/tests/plugins/PocketMine-DevTools @@ -1 +1 @@ -Subproject commit beb079c256eea7cae0f68f02e2b61096ddc00690 +Subproject commit aef2b101855762bf02638dfdb64bec585f5cba68 From 24b63d71ab89f3bd52dd18d6d2989b52e1114a46 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 May 2020 19:30:52 +0100 Subject: [PATCH 1542/3224] updated DevTools submodule --- tests/plugins/PocketMine-DevTools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/plugins/PocketMine-DevTools b/tests/plugins/PocketMine-DevTools index aef2b10185..5d02f043be 160000 --- a/tests/plugins/PocketMine-DevTools +++ b/tests/plugins/PocketMine-DevTools @@ -1 +1 @@ -Subproject commit aef2b101855762bf02638dfdb64bec585f5cba68 +Subproject commit 5d02f043bec539cca41cf4eb3c774fbe8e0629e8 From 3a6cdba2818c8d6b5f4e78f70d8dfdc9a9e3d6af Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 May 2020 21:16:30 +0100 Subject: [PATCH 1543/3224] Implemented server-side block-break FX handling, closes #3485 this had been planned for a long time already, just never finished. It's not fully done, because there needs to be synchronization of block-break handlers between different players attempting to break the same block, but this should resolve a lot of the bugs that previously existed, while also opening the doors to making the logic more flexible. --- src/player/Player.php | 35 +++--- src/player/SurvivalBlockBreakHandler.php | 142 +++++++++++++++++++++++ 2 files changed, 161 insertions(+), 16 deletions(-) create mode 100644 src/player/SurvivalBlockBreakHandler.php diff --git a/src/player/Player.php b/src/player/Player.php index 92564f441f..290e14e06c 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -85,7 +85,6 @@ use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\AnimatePacket; -use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; @@ -101,15 +100,12 @@ use pocketmine\world\ChunkListener; use pocketmine\world\ChunkListenerNoOpTrait; use pocketmine\world\ChunkLoader; use pocketmine\world\format\Chunk; -use pocketmine\world\particle\BlockPunchParticle; use pocketmine\world\Position; -use pocketmine\world\sound\BlockPunchSound; use pocketmine\world\sound\EntityAttackNoDamageSound; use pocketmine\world\sound\EntityAttackSound; use pocketmine\world\World; use function abs; use function assert; -use function ceil; use function count; use function explode; use function floor; @@ -251,6 +247,9 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** @var \Logger */ protected $logger; + /** @var SurvivalBlockBreakHandler|null */ + protected $blockBreakHandler = null; + public function __construct(Server $server, NetworkSession $session, PlayerInfo $playerInfo, bool $authenticated){ $username = TextFormat::clean($playerInfo->getUsername()); $this->logger = new \PrefixedLogger($server->getLogger(), "Player: $username"); @@ -1336,6 +1335,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->checkNearEntities(); Timings::$playerCheckNearEntitiesTimer->stopTiming(); } + + if($this->blockBreakHandler !== null and !$this->blockBreakHandler->update()){ + $this->blockBreakHandler = null; + } } $this->timings->stopTiming(); @@ -1584,27 +1587,23 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } if(!$this->isCreative()){ - //TODO: improve this to take stuff like swimming, ladders, enchanted tools into account, fix wrong tool break time calculations for bad tools (pmmp/PocketMine-MP#211) - $breakTime = ceil($target->getBreakInfo()->getBreakTime($this->inventory->getItemInHand()) * 20); - if($breakTime > 0){ - $this->getWorld()->broadcastPacketToViewers($pos, LevelEventPacket::create(LevelEventPacket::EVENT_BLOCK_START_BREAK, (int) (65535 / $breakTime), $pos)); - } + $this->blockBreakHandler = new SurvivalBlockBreakHandler($this, $pos, $target, $face, 16); } return true; } public function continueBreakBlock(Vector3 $pos, int $face) : void{ - $block = $this->getWorld()->getBlock($pos); - $this->getWorld()->addParticle($pos, new BlockPunchParticle($block, $face)); - $this->getWorld()->addSound($pos, new BlockPunchSound($block)); - $this->broadcastAnimation(new ArmSwingAnimation($this), $this->getViewers()); - - //TODO: destroy-progress level event + if($this->blockBreakHandler !== null and $this->blockBreakHandler->getBlockPos()->distanceSquared($pos) < 0.0001){ + //TODO: check the targeted block matches the one we're told to target + $this->blockBreakHandler->setTargetedFace($face); + } } public function stopBreakBlock(Vector3 $pos) : void{ - $this->getWorld()->broadcastPacketToViewers($pos, LevelEventPacket::create(LevelEventPacket::EVENT_BLOCK_STOP_BREAK, 0, $pos)); + if($this->blockBreakHandler !== null and $this->blockBreakHandler->getBlockPos()->distanceSquared($pos) < 0.0001){ + $this->blockBreakHandler = null; + } } /** @@ -1617,6 +1616,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($this->canInteract($pos->add(0.5, 0.5, 0.5), $this->isCreative() ? 13 : 7) and !$this->isSpectator()){ $this->broadcastAnimation(new ArmSwingAnimation($this), $this->getViewers()); + $this->stopBreakBlock($pos); $item = $this->inventory->getItemInHand(); $oldItem = clone $item; if($this->getWorld()->useBreakOn($pos, $item, $this, true)){ @@ -1978,6 +1978,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->spawned = false; $this->stopSleep(); + $this->blockBreakHandler = null; $this->despawnFromAll(); $this->server->removeOnlinePlayer($this); @@ -2019,6 +2020,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->craftingGrid = null; $this->spawnPosition = null; $this->perm = null; + $this->blockBreakHandler = null; parent::destroyCycles(); } @@ -2229,6 +2231,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->nextChunkOrderRun = 0; $this->newPosition = null; $this->stopSleep(); + $this->blockBreakHandler = null; $this->isTeleporting = true; diff --git a/src/player/SurvivalBlockBreakHandler.php b/src/player/SurvivalBlockBreakHandler.php new file mode 100644 index 0000000000..6ec62ef669 --- /dev/null +++ b/src/player/SurvivalBlockBreakHandler.php @@ -0,0 +1,142 @@ +player = $player; + $this->blockPos = $blockPos; + $this->block = $block; + $this->targetedFace = $targetedFace; + $this->fxTickInterval = $fxTickInterval; + $this->maxPlayerDistance = $maxPlayerDistance; + + $this->breakSpeed = $this->calculateBreakProgressPerTick(); + if($this->breakSpeed !== null){ + $this->player->getWorld()->broadcastPacketToViewers( + $this->blockPos, + LevelEventPacket::create(LevelEventPacket::EVENT_BLOCK_START_BREAK, (int) (65535 * $this->breakSpeed), $this->blockPos) + ); + } + } + + /** + * Returns the calculated break speed as percentage progress per game tick. + */ + private function calculateBreakProgressPerTick() : ?float{ + //TODO: improve this to take stuff like swimming, ladders, enchanted tools into account, fix wrong tool break time calculations for bad tools (pmmp/PocketMine-MP#211) + $breakTime = $this->block->getBreakInfo()->getBreakTime($this->player->getInventory()->getItemInHand()) * 20; + if($breakTime > 0){ + return 1 / $breakTime; + } + return null; + } + + public function update() : bool{ + if( + $this->player->getPosition()->distanceSquared($this->blockPos->add(0.5, 0.5, 0.5)) > $this->maxPlayerDistance){ + return false; + } + if($this->breakSpeed !== null){ + $newBreakSpeed = $this->calculateBreakProgressPerTick(); + if(abs($newBreakSpeed - $this->breakSpeed) > 0.0001){ + $this->breakSpeed = $newBreakSpeed; + //TODO: sync with client + } + + $this->breakProgress += $this->breakSpeed; + + if(($this->fxTicker++ % $this->fxTickInterval) === 0){ + $this->player->getWorld()->addParticle($this->blockPos, new BlockPunchParticle($this->block, $this->targetedFace)); + $this->player->getWorld()->addSound($this->blockPos, new BlockPunchSound($this->block)); + $this->player->broadcastAnimation(new ArmSwingAnimation($this->player), $this->player->getViewers()); + } + } + return $this->breakSpeed !== null and $this->breakProgress < 1; + } + + public function getBlockPos() : Vector3{ + return $this->blockPos; + } + + public function getTargetedFace() : int{ + return $this->targetedFace; + } + + public function setTargetedFace(int $face) : void{ + Facing::validate($face); + $this->targetedFace = $face; + } + + public function getBreakSpeed() : ?float{ + return $this->breakSpeed; + } + + public function getBreakProgress() : float{ + return $this->breakProgress; + } + + public function __destruct(){ + if($this->breakSpeed !== null and $this->player->getWorld()->isInLoadedTerrain($this->blockPos)){ + $this->player->getWorld()->broadcastPacketToViewers( + $this->blockPos, + LevelEventPacket::create(LevelEventPacket::EVENT_BLOCK_STOP_BREAK, 0, $this->blockPos) + ); + } + } +} From 152da604bef530acc0db5d21b7d88738bc24e3cb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 12 May 2020 22:37:23 +0100 Subject: [PATCH 1544/3224] MemoryManager::dumpMemory() should never throw an exception that matters to calling code --- src/MemoryManager.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/MemoryManager.php b/src/MemoryManager.php index 0de2dba664..aacc7101c1 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -302,8 +302,6 @@ class MemoryManager{ * Static memory dumper accessible from any thread. * * @param mixed $startingObject - * - * @throws \ReflectionException */ public static function dumpMemory($startingObject, string $outputFolder, int $maxNesting, int $maxStringSize, \Logger $logger) : void{ $hardLimit = ini_get('memory_limit'); From 144a66c1104f74f946599237e1997da7528978fb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 12 May 2020 22:38:59 +0100 Subject: [PATCH 1545/3224] cumulative imports cleanup (again) --- src/data/bedrock/LegacyBlockIdToStringIdMap.php | 6 ------ src/data/bedrock/LegacyEntityIdToStringIdMap.php | 6 ------ src/data/bedrock/LegacyItemIdToStringIdMap.php | 6 ------ .../bedrock/LegacyToStringBidirectionalIdMap.php | 5 +++++ src/network/mcpe/JwtUtils.php | 12 ++++++++++++ src/network/mcpe/auth/ProcessLoginTask.php | 2 -- src/utils/Utils.php | 4 ---- 7 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/data/bedrock/LegacyBlockIdToStringIdMap.php b/src/data/bedrock/LegacyBlockIdToStringIdMap.php index d613da6755..e46fefb9dd 100644 --- a/src/data/bedrock/LegacyBlockIdToStringIdMap.php +++ b/src/data/bedrock/LegacyBlockIdToStringIdMap.php @@ -23,13 +23,7 @@ declare(strict_types=1); namespace pocketmine\data\bedrock; -use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\SingletonTrait; -use function file_get_contents; -use function is_array; -use function is_int; -use function is_string; -use function json_decode; final class LegacyBlockIdToStringIdMap extends LegacyToStringBidirectionalIdMap{ use SingletonTrait; diff --git a/src/data/bedrock/LegacyEntityIdToStringIdMap.php b/src/data/bedrock/LegacyEntityIdToStringIdMap.php index 9457e70091..b12cc8bced 100644 --- a/src/data/bedrock/LegacyEntityIdToStringIdMap.php +++ b/src/data/bedrock/LegacyEntityIdToStringIdMap.php @@ -23,13 +23,7 @@ declare(strict_types=1); namespace pocketmine\data\bedrock; -use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\SingletonTrait; -use function file_get_contents; -use function is_array; -use function is_int; -use function is_string; -use function json_decode; final class LegacyEntityIdToStringIdMap extends LegacyToStringBidirectionalIdMap{ use SingletonTrait; diff --git a/src/data/bedrock/LegacyItemIdToStringIdMap.php b/src/data/bedrock/LegacyItemIdToStringIdMap.php index 03efcc1610..93219a549e 100644 --- a/src/data/bedrock/LegacyItemIdToStringIdMap.php +++ b/src/data/bedrock/LegacyItemIdToStringIdMap.php @@ -23,13 +23,7 @@ declare(strict_types=1); namespace pocketmine\data\bedrock; -use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\SingletonTrait; -use function file_get_contents; -use function is_array; -use function is_int; -use function is_string; -use function json_decode; final class LegacyItemIdToStringIdMap extends LegacyToStringBidirectionalIdMap{ use SingletonTrait; diff --git a/src/data/bedrock/LegacyToStringBidirectionalIdMap.php b/src/data/bedrock/LegacyToStringBidirectionalIdMap.php index 9afb0dc57b..0dcc7ff0fe 100644 --- a/src/data/bedrock/LegacyToStringBidirectionalIdMap.php +++ b/src/data/bedrock/LegacyToStringBidirectionalIdMap.php @@ -24,6 +24,11 @@ declare(strict_types=1); namespace pocketmine\data\bedrock; use pocketmine\utils\AssumptionFailedError; +use function file_get_contents; +use function is_array; +use function is_int; +use function is_string; +use function json_decode; abstract class LegacyToStringBidirectionalIdMap{ diff --git a/src/network/mcpe/JwtUtils.php b/src/network/mcpe/JwtUtils.php index 503ca2a517..0e5a81b0ad 100644 --- a/src/network/mcpe/JwtUtils.php +++ b/src/network/mcpe/JwtUtils.php @@ -23,6 +23,18 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; +use function base64_decode; +use function base64_encode; +use function count; +use function explode; +use function is_array; +use function json_decode; +use function json_last_error_msg; +use function rtrim; +use function str_repeat; +use function strlen; +use function strtr; + final class JwtUtils{ /** diff --git a/src/network/mcpe/auth/ProcessLoginTask.php b/src/network/mcpe/auth/ProcessLoginTask.php index 3fcc730a14..c997b48d7f 100644 --- a/src/network/mcpe/auth/ProcessLoginTask.php +++ b/src/network/mcpe/auth/ProcessLoginTask.php @@ -38,10 +38,8 @@ use function explode; use function gmp_init; use function json_decode; use function openssl_verify; -use function str_repeat; use function str_split; use function strlen; -use function strtr; use function time; use const OPENSSL_ALGO_SHA384; diff --git a/src/utils/Utils.php b/src/utils/Utils.php index e858cbc948..17d4b495db 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -33,7 +33,6 @@ use function array_combine; use function array_map; use function array_reverse; use function array_values; -use function base64_decode; use function bin2hex; use function chunk_split; use function count; @@ -53,8 +52,6 @@ use function implode; use function is_array; use function is_object; use function is_string; -use function json_decode; -use function json_last_error_msg; use function mb_check_encoding; use function ob_end_clean; use function ob_get_contents; @@ -71,7 +68,6 @@ use function str_split; use function stripos; use function strlen; use function strpos; -use function strtr; use function substr; use function sys_get_temp_dir; use function trim; From ac4c1c9086652e5e8407ec0f80f47f3924e0d082 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 12 May 2020 22:45:42 +0100 Subject: [PATCH 1546/3224] Clean up to SurvivalBlockBreakHandler internals - don't create a handler if it won't be used anyway --- src/player/Player.php | 2 +- src/player/SurvivalBlockBreakHandler.php | 62 ++++++++++++++---------- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 290e14e06c..58b55ca686 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1587,7 +1587,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } if(!$this->isCreative()){ - $this->blockBreakHandler = new SurvivalBlockBreakHandler($this, $pos, $target, $face, 16); + $this->blockBreakHandler = SurvivalBlockBreakHandler::createIfNecessary($this, $pos, $target, $face, 16); } return true; diff --git a/src/player/SurvivalBlockBreakHandler.php b/src/player/SurvivalBlockBreakHandler.php index 6ec62ef669..f715ec896f 100644 --- a/src/player/SurvivalBlockBreakHandler.php +++ b/src/player/SurvivalBlockBreakHandler.php @@ -52,13 +52,13 @@ final class SurvivalBlockBreakHandler{ /** @var int */ private $maxPlayerDistance; - /** @var float|null */ + /** @var float */ private $breakSpeed; /** @var float */ private $breakProgress = 0; - public function __construct(Player $player, Vector3 $blockPos, Block $block, int $targetedFace, int $maxPlayerDistance, int $fxTickInterval = self::DEFAULT_FX_INTERVAL_TICKS){ + private function __construct(Player $player, Vector3 $blockPos, Block $block, int $targetedFace, int $maxPlayerDistance, int $fxTickInterval = self::DEFAULT_FX_INTERVAL_TICKS){ $this->player = $player; $this->blockPos = $blockPos; $this->block = $block; @@ -67,7 +67,7 @@ final class SurvivalBlockBreakHandler{ $this->maxPlayerDistance = $maxPlayerDistance; $this->breakSpeed = $this->calculateBreakProgressPerTick(); - if($this->breakSpeed !== null){ + if($this->breakSpeed > 0){ $this->player->getWorld()->broadcastPacketToViewers( $this->blockPos, LevelEventPacket::create(LevelEventPacket::EVENT_BLOCK_START_BREAK, (int) (65535 * $this->breakSpeed), $this->blockPos) @@ -75,16 +75,28 @@ final class SurvivalBlockBreakHandler{ } } + public static function createIfNecessary(Player $player, Vector3 $blockPos, Block $block, int $targetedFace, int $maxPlayerDistance, int $fxTickInterval = self::DEFAULT_FX_INTERVAL_TICKS) : ?self{ + $breakInfo = $block->getBreakInfo(); + if(!$breakInfo->breaksInstantly()){ + return new self($player, $blockPos, $block, $targetedFace, $maxPlayerDistance, $fxTickInterval); + } + return null; + } + /** * Returns the calculated break speed as percentage progress per game tick. */ - private function calculateBreakProgressPerTick() : ?float{ - //TODO: improve this to take stuff like swimming, ladders, enchanted tools into account, fix wrong tool break time calculations for bad tools (pmmp/PocketMine-MP#211) - $breakTime = $this->block->getBreakInfo()->getBreakTime($this->player->getInventory()->getItemInHand()) * 20; - if($breakTime > 0){ - return 1 / $breakTime; + private function calculateBreakProgressPerTick() : float{ + if(!$this->block->getBreakInfo()->isBreakable()){ + return 0.0; } - return null; + //TODO: improve this to take stuff like swimming, ladders, enchanted tools into account, fix wrong tool break time calculations for bad tools (pmmp/PocketMine-MP#211) + $breakTimePerTick = $this->block->getBreakInfo()->getBreakTime($this->player->getInventory()->getItemInHand()) * 20; + + if($breakTimePerTick > 0){ + return 1 / $breakTimePerTick; + } + return 1; } public function update() : bool{ @@ -92,22 +104,22 @@ final class SurvivalBlockBreakHandler{ $this->player->getPosition()->distanceSquared($this->blockPos->add(0.5, 0.5, 0.5)) > $this->maxPlayerDistance){ return false; } - if($this->breakSpeed !== null){ - $newBreakSpeed = $this->calculateBreakProgressPerTick(); - if(abs($newBreakSpeed - $this->breakSpeed) > 0.0001){ - $this->breakSpeed = $newBreakSpeed; - //TODO: sync with client - } - $this->breakProgress += $this->breakSpeed; - - if(($this->fxTicker++ % $this->fxTickInterval) === 0){ - $this->player->getWorld()->addParticle($this->blockPos, new BlockPunchParticle($this->block, $this->targetedFace)); - $this->player->getWorld()->addSound($this->blockPos, new BlockPunchSound($this->block)); - $this->player->broadcastAnimation(new ArmSwingAnimation($this->player), $this->player->getViewers()); - } + $newBreakSpeed = $this->calculateBreakProgressPerTick(); + if(abs($newBreakSpeed - $this->breakSpeed) > 0.0001){ + $this->breakSpeed = $newBreakSpeed; + //TODO: sync with client } - return $this->breakSpeed !== null and $this->breakProgress < 1; + + $this->breakProgress += $this->breakSpeed; + + if(($this->fxTicker++ % $this->fxTickInterval) === 0 and $this->breakProgress < 1){ + $this->player->getWorld()->addParticle($this->blockPos, new BlockPunchParticle($this->block, $this->targetedFace)); + $this->player->getWorld()->addSound($this->blockPos, new BlockPunchSound($this->block)); + $this->player->broadcastAnimation(new ArmSwingAnimation($this->player), $this->player->getViewers()); + } + + return $this->breakProgress < 1; } public function getBlockPos() : Vector3{ @@ -123,7 +135,7 @@ final class SurvivalBlockBreakHandler{ $this->targetedFace = $face; } - public function getBreakSpeed() : ?float{ + public function getBreakSpeed() : float{ return $this->breakSpeed; } @@ -132,7 +144,7 @@ final class SurvivalBlockBreakHandler{ } public function __destruct(){ - if($this->breakSpeed !== null and $this->player->getWorld()->isInLoadedTerrain($this->blockPos)){ + if($this->player->getWorld()->isInLoadedTerrain($this->blockPos)){ $this->player->getWorld()->broadcastPacketToViewers( $this->blockPos, LevelEventPacket::create(LevelEventPacket::EVENT_BLOCK_STOP_BREAK, 0, $this->blockPos) From ec13aa659a0ec9826cd79bc6734b594e45b971cf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 12 May 2020 23:28:17 +0100 Subject: [PATCH 1547/3224] ItemFactory: do not explode on invalid damage values for durables just treat them as unknown items instead this might break some use cases, but at least this way they won't crash the server when read from disk and they won't get lost either. --- src/item/ItemFactory.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 2f54c4ec60..0f00937d34 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -409,7 +409,11 @@ class ItemFactory{ }elseif(isset($this->list[$zero = self::getListOffset($id, 0)]) and $this->list[$zero] instanceof Durable){ /** @var Durable $item */ $item = clone $this->list[$zero]; - $item->setDamage($meta); + try{ + $item->setDamage($meta); + }catch(\InvalidArgumentException $e){ + $item = new Item($id, $meta); + } }elseif($id < 256){ //intentionally includes negatives, for extended block IDs $item = new ItemBlock($id, $meta); } From 11ef9fb0c00df2a6ee0740c174e52eba72aafe68 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 May 2020 00:17:15 +0100 Subject: [PATCH 1548/3224] Item-from-string parsing no longer depends on ItemIds after this is done I'm banning the constant() function. --- resources/item_from_string_bc_map.json | 810 ++++++++++++++++++ src/command/defaults/GiveCommand.php | 4 +- src/item/Item.php | 2 +- src/item/ItemFactory.php | 38 - src/item/LegacyStringToItemParser.php | 117 +++ src/world/World.php | 9 +- src/world/generator/Flat.php | 6 +- tests/phpunit/item/ItemFactoryTest.php | 29 - .../item/LegacyStringToItemParserTest.php | 58 ++ 9 files changed, 996 insertions(+), 77 deletions(-) create mode 100644 resources/item_from_string_bc_map.json create mode 100644 src/item/LegacyStringToItemParser.php create mode 100644 tests/phpunit/item/LegacyStringToItemParserTest.php diff --git a/resources/item_from_string_bc_map.json b/resources/item_from_string_bc_map.json new file mode 100644 index 0000000000..34de8fbbed --- /dev/null +++ b/resources/item_from_string_bc_map.json @@ -0,0 +1,810 @@ +{ + "acacia_button": -140, + "acacia_door": 430, + "acacia_door_block": 196, + "acacia_fence_gate": 187, + "acacia_pressure_plate": -150, + "acacia_sign": 475, + "acacia_stairs": 163, + "acacia_standing_sign": -190, + "acacia_trapdoor": -145, + "acacia_wall_sign": -191, + "activator_rail": 126, + "air": 0, + "andesite_stairs": -171, + "anvil": 145, + "apple": 260, + "apple_enchanted": 466, + "appleenchanted": 466, + "armor_stand": 425, + "arrow": 262, + "baked_potato": 393, + "balloon": 448, + "bamboo": -163, + "bamboo_sapling": -164, + "banner": 446, + "banner_pattern": 434, + "barrel": -203, + "barrier": -161, + "beacon": 138, + "bed": 355, + "bed_block": 26, + "bedrock": 7, + "beef": 363, + "beetroot": 457, + "beetroot_block": 244, + "beetroot_seeds": 458, + "beetroot_soup": 459, + "bell": -206, + "birch_button": -141, + "birch_door": 428, + "birch_door_block": 194, + "birch_fence_gate": 184, + "birch_pressure_plate": -151, + "birch_sign": 473, + "birch_stairs": 135, + "birch_standing_sign": -186, + "birch_trapdoor": -146, + "birch_wall_sign": -187, + "black_glazed_terracotta": 235, + "blast_furnace": -196, + "blaze_powder": 377, + "blaze_rod": 369, + "bleach": 451, + "blue_glazed_terracotta": 231, + "blue_ice": -11, + "boat": 333, + "bone": 352, + "bone_block": 216, + "book": 340, + "bookshelf": 47, + "bottle_o_enchanting": 384, + "bow": 261, + "bowl": 281, + "bread": 297, + "brewing_stand": 379, + "brewing_stand_block": 117, + "brick": 336, + "brick_block": 45, + "brick_stairs": 108, + "brown_glazed_terracotta": 232, + "brown_mushroom": 39, + "brown_mushroom_block": 99, + "bubble_column": -160, + "bucket": 325, + "burning_furnace": 62, + "cactus": 81, + "cake": 354, + "cake_block": 92, + "campfire": -209, + "carpet": 171, + "carrot": 391, + "carrot_block": 141, + "carrot_on_a_stick": 398, + "carrotonastick": 398, + "carrots": 141, + "cartography_table": -200, + "carved_pumpkin": -155, + "cauldron": 380, + "cauldron_block": 118, + "chain_boots": 305, + "chain_chestplate": 303, + "chain_command_block": 189, + "chain_helmet": 302, + "chain_leggings": 304, + "chainmail_boots": 305, + "chainmail_chestplate": 303, + "chainmail_helmet": 302, + "chainmail_leggings": 304, + "chemical_heat": 192, + "chemistry_table": 238, + "chest": 54, + "chest_minecart": 342, + "chicken": 365, + "chorus_flower": 200, + "chorus_fruit": 432, + "chorus_fruit_popped": 433, + "chorus_plant": 240, + "clay": 337, + "clay_ball": 337, + "clay_block": 82, + "clock": 347, + "clownfish": 461, + "coal": 263, + "coal_block": 173, + "coal_ore": 16, + "cobblestone": 4, + "cobblestone_stairs": 67, + "cobblestone_wall": 139, + "cobweb": 30, + "cocoa": 127, + "cocoa_block": 127, + "colored_torch_bp": 204, + "colored_torch_rg": 202, + "command_block": 137, + "command_block_minecart": 443, + "comparator": 404, + "comparator_block": 149, + "compass": 345, + "composter": -213, + "compound": 499, + "concrete": 236, + "concrete_powder": 237, + "concretepowder": 237, + "conduit": -157, + "cooked_beef": 364, + "cooked_chicken": 366, + "cooked_fish": 350, + "cooked_mutton": 424, + "cooked_porkchop": 320, + "cooked_rabbit": 412, + "cooked_salmon": 463, + "cookie": 357, + "coral": -131, + "coral_block": -132, + "coral_fan": -133, + "coral_fan_dead": -134, + "coral_fan_hang": -135, + "coral_fan_hang2": -136, + "coral_fan_hang3": -137, + "crafting_table": 58, + "crossbow": 471, + "cyan_glazed_terracotta": 229, + "dandelion": 37, + "dark_oak_button": -142, + "dark_oak_door": 431, + "dark_oak_door_block": 197, + "dark_oak_fence_gate": 186, + "dark_oak_pressure_plate": -152, + "dark_oak_stairs": 164, + "dark_oak_trapdoor": -147, + "dark_prismarine_stairs": -3, + "darkoak_sign": 476, + "darkoak_standing_sign": -192, + "darkoak_wall_sign": -193, + "daylight_detector": 151, + "daylight_detector_inverted": 178, + "daylight_sensor": 151, + "daylight_sensor_inverted": 178, + "dead_bush": 32, + "deadbush": 32, + "detector_rail": 28, + "diamond": 264, + "diamond_axe": 279, + "diamond_block": 57, + "diamond_boots": 313, + "diamond_chestplate": 311, + "diamond_helmet": 310, + "diamond_hoe": 293, + "diamond_horse_armor": 419, + "diamond_leggings": 312, + "diamond_ore": 56, + "diamond_pickaxe": 278, + "diamond_shovel": 277, + "diamond_sword": 276, + "diorite_stairs": -170, + "dirt": 3, + "dispenser": 23, + "double_plant": 175, + "double_stone_slab": 43, + "double_stone_slab2": 181, + "double_stone_slab3": -167, + "double_stone_slab4": -168, + "double_wooden_slab": 157, + "dragon_breath": 437, + "dragon_egg": 122, + "dried_kelp": 464, + "dried_kelp_block": -139, + "dropper": 125, + "dye": 351, + "egg": 344, + "element_0": 36, + "element_1": -12, + "element_10": -21, + "element_100": -111, + "element_101": -112, + "element_102": -113, + "element_103": -114, + "element_104": -115, + "element_105": -116, + "element_106": -117, + "element_107": -118, + "element_108": -119, + "element_109": -120, + "element_11": -22, + "element_110": -121, + "element_111": -122, + "element_112": -123, + "element_113": -124, + "element_114": -125, + "element_115": -126, + "element_116": -127, + "element_117": -128, + "element_118": -129, + "element_12": -23, + "element_13": -24, + "element_14": -25, + "element_15": -26, + "element_16": -27, + "element_17": -28, + "element_18": -29, + "element_19": -30, + "element_2": -13, + "element_20": -31, + "element_21": -32, + "element_22": -33, + "element_23": -34, + "element_24": -35, + "element_25": -36, + "element_26": -37, + "element_27": -38, + "element_28": -39, + "element_29": -40, + "element_3": -14, + "element_30": -41, + "element_31": -42, + "element_32": -43, + "element_33": -44, + "element_34": -45, + "element_35": -46, + "element_36": -47, + "element_37": -48, + "element_38": -49, + "element_39": -50, + "element_4": -15, + "element_40": -51, + "element_41": -52, + "element_42": -53, + "element_43": -54, + "element_44": -55, + "element_45": -56, + "element_46": -57, + "element_47": -58, + "element_48": -59, + "element_49": -60, + "element_5": -16, + "element_50": -61, + "element_51": -62, + "element_52": -63, + "element_53": -64, + "element_54": -65, + "element_55": -66, + "element_56": -67, + "element_57": -68, + "element_58": -69, + "element_59": -70, + "element_6": -17, + "element_60": -71, + "element_61": -72, + "element_62": -73, + "element_63": -74, + "element_64": -75, + "element_65": -76, + "element_66": -77, + "element_67": -78, + "element_68": -79, + "element_69": -80, + "element_7": -18, + "element_70": -81, + "element_71": -82, + "element_72": -83, + "element_73": -84, + "element_74": -85, + "element_75": -86, + "element_76": -87, + "element_77": -88, + "element_78": -89, + "element_79": -90, + "element_8": -19, + "element_80": -91, + "element_81": -92, + "element_82": -93, + "element_83": -94, + "element_84": -95, + "element_85": -96, + "element_86": -97, + "element_87": -98, + "element_88": -99, + "element_89": -100, + "element_9": -20, + "element_90": -101, + "element_91": -102, + "element_92": -103, + "element_93": -104, + "element_94": -105, + "element_95": -106, + "element_96": -107, + "element_97": -108, + "element_98": -109, + "element_99": -110, + "elytra": 444, + "emerald": 388, + "emerald_block": 133, + "emerald_ore": 129, + "empty_map": 395, + "emptymap": 395, + "enchanted_book": 403, + "enchanted_golden_apple": 466, + "enchanting_table": 116, + "enchantment_table": 116, + "end_brick_stairs": -178, + "end_bricks": 206, + "end_crystal": 426, + "end_gateway": 209, + "end_portal": 119, + "end_portal_frame": 120, + "end_rod": 208, + "end_stone": 121, + "ender_chest": 130, + "ender_eye": 381, + "ender_pearl": 368, + "experience_bottle": 384, + "farmland": 60, + "feather": 288, + "fence": 85, + "fence_gate": 107, + "fermented_spider_eye": 376, + "filled_map": 358, + "fire": 51, + "fire_charge": 385, + "fireball": 385, + "fireworks": 401, + "fireworks_charge": 402, + "fireworkscharge": 402, + "fish": 349, + "fishing_rod": 346, + "fletching_table": -201, + "flint": 318, + "flint_and_steel": 259, + "flint_steel": 259, + "flower_pot": 390, + "flower_pot_block": 140, + "flowing_lava": 10, + "flowing_water": 8, + "frame": 389, + "frame_block": 199, + "frosted_ice": 207, + "furnace": 61, + "ghast_tear": 370, + "glass": 20, + "glass_bottle": 374, + "glass_pane": 102, + "glistering_melon": 382, + "glow_stick": 166, + "glowing_obsidian": 246, + "glowing_redstone_ore": 74, + "glowingobsidian": 246, + "glowstone": 89, + "glowstone_dust": 348, + "gold_axe": 286, + "gold_block": 41, + "gold_boots": 317, + "gold_chestplate": 315, + "gold_helmet": 314, + "gold_hoe": 294, + "gold_horse_armor": 418, + "gold_ingot": 266, + "gold_leggings": 316, + "gold_nugget": 371, + "gold_ore": 14, + "gold_pickaxe": 285, + "gold_shovel": 284, + "gold_sword": 283, + "golden_apple": 322, + "golden_axe": 286, + "golden_boots": 317, + "golden_carrot": 396, + "golden_chestplate": 315, + "golden_helmet": 314, + "golden_hoe": 294, + "golden_horse_armor": 418, + "golden_leggings": 316, + "golden_nugget": 371, + "golden_pickaxe": 285, + "golden_rail": 27, + "golden_shovel": 284, + "golden_sword": 283, + "granite_stairs": -169, + "grass": 2, + "grass_path": 198, + "gravel": 13, + "gray_glazed_terracotta": 227, + "green_glazed_terracotta": 233, + "grindstone": -195, + "gunpowder": 289, + "hard_glass": 253, + "hard_glass_pane": 190, + "hard_stained_glass": 254, + "hard_stained_glass_pane": 191, + "hardened_clay": 172, + "hay_bale": 170, + "hay_block": 170, + "heart_of_the_sea": 467, + "heavy_weighted_pressure_plate": 148, + "hopper": 410, + "hopper_block": 154, + "hopper_minecart": 408, + "horse_armor_diamond": 419, + "horse_armor_gold": 418, + "horse_armor_iron": 417, + "horse_armor_leather": 416, + "horsearmordiamond": 419, + "horsearmorgold": 418, + "horsearmoriron": 417, + "horsearmorleather": 416, + "ice": 79, + "ice_bomb": 453, + "info_update": 248, + "info_update2": 249, + "invisible_bedrock": 95, + "invisiblebedrock": 95, + "iron_axe": 258, + "iron_bars": 101, + "iron_block": 42, + "iron_boots": 309, + "iron_chestplate": 307, + "iron_door": 330, + "iron_door_block": 71, + "iron_helmet": 306, + "iron_hoe": 292, + "iron_horse_armor": 417, + "iron_ingot": 265, + "iron_leggings": 308, + "iron_nugget": 452, + "iron_ore": 15, + "iron_pickaxe": 257, + "iron_shovel": 256, + "iron_sword": 267, + "iron_trapdoor": 167, + "item_frame": 389, + "item_frame_block": 199, + "jack_o_lantern": 91, + "jigsaw": -211, + "jukebox": 84, + "jungle_button": -143, + "jungle_door": 429, + "jungle_door_block": 195, + "jungle_fence_gate": 185, + "jungle_pressure_plate": -153, + "jungle_sign": 474, + "jungle_stairs": 136, + "jungle_standing_sign": -188, + "jungle_trapdoor": -148, + "jungle_wall_sign": -189, + "kelp": 335, + "kelp_block": -138, + "ladder": 65, + "lantern": -208, + "lapis_block": 22, + "lapis_ore": 21, + "lava": 11, + "lava_cauldron": -210, + "lead": 420, + "leather": 334, + "leather_boots": 301, + "leather_cap": 298, + "leather_chestplate": 299, + "leather_helmet": 298, + "leather_horse_armor": 416, + "leather_leggings": 300, + "leather_pants": 300, + "leather_tunic": 299, + "leaves": 18, + "leaves2": 161, + "lectern": -194, + "lever": 69, + "light_blue_glazed_terracotta": 223, + "light_weighted_pressure_plate": 147, + "lily_pad": 111, + "lime_glazed_terracotta": 225, + "lingering_potion": 441, + "lit_blast_furnace": -214, + "lit_furnace": 62, + "lit_pumpkin": 91, + "lit_redstone_lamp": 124, + "lit_redstone_ore": 74, + "lit_redstone_torch": 76, + "lit_smoker": -199, + "log": 17, + "log2": 162, + "loom": -204, + "magenta_glazed_terracotta": 222, + "magma": 213, + "magma_cream": 378, + "map": 395, + "medicine": 447, + "melon": 360, + "melon_block": 103, + "melon_seeds": 362, + "melon_slice": 360, + "melon_stem": 105, + "minecart": 328, + "minecart_with_chest": 342, + "minecart_with_command_block": 443, + "minecart_with_hopper": 408, + "minecart_with_tnt": 407, + "mob_head": 397, + "mob_head_block": 144, + "mob_spawner": 52, + "monster_egg": 97, + "monster_spawner": 52, + "moss_stone": 48, + "mossy_cobblestone": 48, + "mossy_cobblestone_stairs": -179, + "mossy_stone_brick_stairs": -175, + "moving_block": 250, + "movingblock": 250, + "mushroom_stew": 282, + "mutton": 423, + "mutton_cooked": 424, + "mutton_raw": 423, + "muttoncooked": 424, + "muttonraw": 423, + "mycelium": 110, + "name_tag": 421, + "nametag": 421, + "nautilus_shell": 465, + "nether_brick": 405, + "nether_brick_block": 112, + "nether_brick_fence": 113, + "nether_brick_stairs": 114, + "nether_quartz": 406, + "nether_quartz_ore": 153, + "nether_reactor": 247, + "nether_star": 399, + "nether_wart": 372, + "nether_wart_block": 214, + "nether_wart_plant": 115, + "netherbrick": 405, + "netherrack": 87, + "netherreactor": 247, + "netherstar": 399, + "normal_stone_stairs": -180, + "note_block": 25, + "noteblock": 25, + "oak_door": 324, + "oak_door_block": 64, + "oak_fence_gate": 107, + "oak_stairs": 53, + "observer": 251, + "obsidian": 49, + "orange_glazed_terracotta": 221, + "packed_ice": 174, + "painting": 321, + "paper": 339, + "phantom_membrane": 470, + "pink_glazed_terracotta": 226, + "piston": 33, + "piston_arm_collision": 34, + "pistonarmcollision": 34, + "planks": 5, + "podzol": 243, + "poisonous_potato": 394, + "polished_andesite_stairs": -174, + "polished_diorite_stairs": -173, + "polished_granite_stairs": -172, + "poppy": 38, + "porkchop": 319, + "portal": 90, + "potato": 392, + "potato_block": 142, + "potatoes": 142, + "potion": 373, + "powered_comparator": 150, + "powered_rail": 27, + "powered_repeater": 94, + "prismarine": 168, + "prismarine_bricks_stairs": -4, + "prismarine_crystals": 422, + "prismarine_shard": 409, + "prismarine_stairs": -2, + "pufferfish": 462, + "pumpkin": 86, + "pumpkin_pie": 400, + "pumpkin_seeds": 361, + "pumpkin_stem": 104, + "purple_glazed_terracotta": 219, + "purpur_block": 201, + "purpur_stairs": 203, + "quartz": 406, + "quartz_block": 155, + "quartz_ore": 153, + "quartz_stairs": 156, + "rabbit": 411, + "rabbit_foot": 414, + "rabbit_hide": 415, + "rabbit_stew": 413, + "rail": 66, + "rapid_fertilizer": 449, + "raw_beef": 363, + "raw_chicken": 365, + "raw_fish": 349, + "raw_mutton": 423, + "raw_porkchop": 319, + "raw_rabbit": 411, + "raw_salmon": 460, + "record_11": 510, + "record_13": 500, + "record_blocks": 502, + "record_cat": 501, + "record_chirp": 503, + "record_far": 504, + "record_mall": 505, + "record_mellohi": 506, + "record_stal": 507, + "record_strad": 508, + "record_wait": 511, + "record_ward": 509, + "red_flower": 38, + "red_glazed_terracotta": 234, + "red_mushroom": 40, + "red_mushroom_block": 100, + "red_nether_brick": 215, + "red_nether_brick_stairs": -184, + "red_sandstone": 179, + "red_sandstone_stairs": 180, + "redstone": 331, + "redstone_block": 152, + "redstone_dust": 331, + "redstone_lamp": 123, + "redstone_ore": 73, + "redstone_torch": 76, + "redstone_wire": 55, + "reeds": 338, + "reeds_block": 83, + "repeater": 356, + "repeater_block": 93, + "repeating_command_block": 188, + "reserved6": 255, + "rotten_flesh": 367, + "saddle": 329, + "salmon": 460, + "sand": 12, + "sandstone": 24, + "sandstone_stairs": 128, + "sapling": 6, + "scaffolding": -165, + "sea_lantern": 169, + "sea_pickle": -156, + "seagrass": -130, + "sealantern": 169, + "seeds": 295, + "shears": 359, + "shield": 513, + "shulker_box": 218, + "shulker_shell": 445, + "sign": 323, + "sign_post": 63, + "silver_glazed_terracotta": 228, + "skull": 397, + "skull_block": 144, + "slime": 165, + "slime_ball": 341, + "slime_block": 165, + "slimeball": 341, + "smithing_table": -202, + "smoker": -198, + "smooth_quartz_stairs": -185, + "smooth_red_sandstone_stairs": -176, + "smooth_sandstone_stairs": -177, + "smooth_stone": -183, + "snow": 80, + "snow_block": 80, + "snow_layer": 78, + "snowball": 332, + "soul_sand": 88, + "sparkler": 442, + "spawn_egg": 383, + "speckled_melon": 382, + "spider_eye": 375, + "splash_potion": 438, + "sponge": 19, + "spruce_button": -144, + "spruce_door": 427, + "spruce_door_block": 193, + "spruce_fence_gate": 183, + "spruce_pressure_plate": -154, + "spruce_sign": 472, + "spruce_stairs": 134, + "spruce_standing_sign": -181, + "spruce_trapdoor": -149, + "spruce_wall_sign": -182, + "stained_clay": 159, + "stained_glass": 241, + "stained_glass_pane": 160, + "stained_hardened_clay": 159, + "standing_banner": 176, + "standing_sign": 63, + "steak": 364, + "stick": 280, + "sticky_piston": 29, + "still_lava": 11, + "still_water": 9, + "stone": 1, + "stone_axe": 275, + "stone_brick": 98, + "stone_brick_stairs": 109, + "stone_bricks": 98, + "stone_button": 77, + "stone_hoe": 291, + "stone_pickaxe": 274, + "stone_pressure_plate": 70, + "stone_shovel": 273, + "stone_slab": 44, + "stone_slab2": 182, + "stone_slab3": -162, + "stone_slab4": -166, + "stone_stairs": 67, + "stone_sword": 272, + "stone_wall": 139, + "stonebrick": 98, + "stonecutter": 245, + "stonecutter_block": -197, + "string": 287, + "stripped_acacia_log": -8, + "stripped_birch_log": -6, + "stripped_dark_oak_log": -9, + "stripped_jungle_log": -7, + "stripped_oak_log": -10, + "stripped_spruce_log": -5, + "structure_block": 252, + "sugar": 353, + "sugarcane": 338, + "sugarcane_block": 83, + "sweet_berries": 477, + "sweet_berry_bush": -207, + "tall_grass": 31, + "tallgrass": 31, + "terracotta": 159, + "tnt": 46, + "tnt_minecart": 407, + "torch": 50, + "totem": 450, + "trapdoor": 96, + "trapped_chest": 146, + "trident": 455, + "trip_wire": 132, + "tripwire": 132, + "tripwire_hook": 131, + "turtle_egg": -159, + "turtle_helmet": 469, + "turtle_shell_piece": 468, + "underwater_torch": 239, + "undyed_shulker_box": 205, + "unlit_redstone_torch": 75, + "unpowered_comparator": 149, + "unpowered_repeater": 93, + "vine": 106, + "vines": 106, + "wall_banner": 177, + "wall_sign": 68, + "water": 9, + "water_lily": 111, + "waterlily": 111, + "web": 30, + "wheat": 296, + "wheat_block": 59, + "wheat_seeds": 295, + "white_glazed_terracotta": 220, + "wood": 17, + "wood2": 162, + "wooden_axe": 271, + "wooden_button": 143, + "wooden_door": 324, + "wooden_door_block": 64, + "wooden_hoe": 290, + "wooden_pickaxe": 270, + "wooden_planks": 5, + "wooden_pressure_plate": 72, + "wooden_shovel": 269, + "wooden_slab": 158, + "wooden_stairs": 53, + "wooden_sword": 268, + "wooden_trapdoor": 96, + "wool": 35, + "workbench": 58, + "writable_book": 386, + "written_book": 387, + "yellow_flower": 37, + "yellow_glazed_terracotta": 224 +} diff --git a/src/command/defaults/GiveCommand.php b/src/command/defaults/GiveCommand.php index 1b0c0bbf51..a3632fa4cb 100644 --- a/src/command/defaults/GiveCommand.php +++ b/src/command/defaults/GiveCommand.php @@ -26,7 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; -use pocketmine\item\ItemFactory; +use pocketmine\item\LegacyStringToItemParser; use pocketmine\lang\TranslationContainer; use pocketmine\nbt\JsonNbtParser; use pocketmine\nbt\NbtDataException; @@ -62,7 +62,7 @@ class GiveCommand extends VanillaCommand{ } try{ - $item = ItemFactory::getInstance()->fromString($args[1]); + $item = LegacyStringToItemParser::getInstance()->parse($args[1]); }catch(\InvalidArgumentException $e){ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.give.item.notFound", [$args[1]])); return true; diff --git a/src/item/Item.php b/src/item/Item.php index 7dca64d853..b8f1864794 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -667,7 +667,7 @@ class Item implements \JsonSerializable{ $item = ItemFactory::getInstance()->get($idTag->getValue(), $meta, $count); }elseif($idTag instanceof StringTag){ //PC item save format try{ - $item = ItemFactory::getInstance()->fromString($idTag->getValue() . ":$meta"); + $item = LegacyStringToItemParser::getInstance()->parse($idTag->getValue() . ":$meta"); }catch(\InvalidArgumentException $e){ //TODO: improve error handling return ItemFactory::air(); diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 0f00937d34..e197fe24ba 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -34,14 +34,7 @@ use pocketmine\entity\Living; use pocketmine\inventory\ArmorInventory; use pocketmine\nbt\tag\CompoundTag; use pocketmine\utils\SingletonTrait; -use function constant; -use function defined; -use function explode; use function is_a; -use function is_numeric; -use function str_replace; -use function strtoupper; -use function trim; /** * Manages Item instance creation and registration @@ -431,37 +424,6 @@ class ItemFactory{ return $item; } - /** - * Tries to parse the specified string into Item types. - * - * Example accepted formats: - * - `diamond_pickaxe:5` - * - `minecraft:string` - * - `351:4 (lapis lazuli ID:meta)` - * - * @throws \InvalidArgumentException if the given string cannot be parsed as an item identifier - */ - public function fromString(string $str) : Item{ - $b = explode(":", str_replace([" ", "minecraft:"], ["_", ""], trim($str))); - if(!isset($b[1])){ - $meta = 0; - }elseif(is_numeric($b[1])){ - $meta = (int) $b[1]; - }else{ - throw new \InvalidArgumentException("Unable to parse \"" . $b[1] . "\" from \"" . $str . "\" as a valid meta value"); - } - - if(is_numeric($b[0])){ - $item = $this->get((int) $b[0], $meta); - }elseif(defined(ItemIds::class . "::" . strtoupper($b[0]))){ - $item = $this->get(constant(ItemIds::class . "::" . strtoupper($b[0])), $meta); - }else{ - throw new \InvalidArgumentException("Unable to resolve \"" . $str . "\" to a valid item"); - } - - return $item; - } - public static function air() : Item{ return self::$air ?? (self::$air = self::getInstance()->get(ItemIds::AIR, 0, 0)); } diff --git a/src/item/LegacyStringToItemParser.php b/src/item/LegacyStringToItemParser.php new file mode 100644 index 0000000000..ea5eb5c228 --- /dev/null +++ b/src/item/LegacyStringToItemParser.php @@ -0,0 +1,117 @@ + $id){ + if(!is_string($name) or !is_int($id)) throw new AssumptionFailedError("Invalid mappings format, expected string keys and int values"); + $result->addMapping($name, $id); + } + + return $result; + } + + /** + * @var int[] + * @phpstan-var array + */ + private $map = []; + + public function __construct(ItemFactory $itemFactory){ + $this->itemFactory = $itemFactory; + } + + public function addMapping(string $alias, int $id) : void{ + $this->map[$alias] = $id; + } + + /** + * Tries to parse the specified string into Item types. + * + * Example accepted formats: + * - `diamond_pickaxe:5` + * - `minecraft:string` + * - `351:4 (lapis lazuli ID:meta)` + * + * @throws \InvalidArgumentException if the given string cannot be parsed as an item identifier + */ + public function parse(string $input) : Item{ + $key = $this->reprocess($input); + $b = explode(":", $key); + + if(!isset($b[1])){ + $meta = 0; + }elseif(is_numeric($b[1])){ + $meta = (int) $b[1]; + }else{ + throw new \InvalidArgumentException("Unable to parse \"" . $b[1] . "\" from \"" . $input . "\" as a valid meta value"); + } + + if(is_numeric($b[0])){ + $item = $this->itemFactory->get((int) $b[0], $meta); + }elseif(isset($this->map[strtolower($b[0])])){ + $item = $this->itemFactory->get($this->map[strtolower($b[0])], $meta); + }else{ + throw new \InvalidArgumentException("Unable to resolve \"" . $input . "\" to a valid item"); + } + + return $item; + } + + protected function reprocess(string $input) : string{ + return str_replace([" ", "minecraft:"], ["_", ""], trim($input)); + } +} diff --git a/src/world/World.php b/src/world/World.php index 4964461907..626d46a9ef 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -49,6 +49,7 @@ use pocketmine\event\world\WorldSaveEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\ItemUseResult; +use pocketmine\item\LegacyStringToItemParser; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\BlockActorDataPacket; @@ -1449,9 +1450,9 @@ class World implements ChunkManager{ if($player->isAdventure(true) and !$ev->isCancelled()){ $canBreak = false; - $itemFactory = ItemFactory::getInstance(); + $itemParser = LegacyStringToItemParser::getInstance(); foreach($item->getCanDestroy() as $v){ - $entry = $itemFactory->fromString($v); + $entry = $itemParser->parse($v); if($entry->getBlock()->isSameType($target)){ $canBreak = true; break; @@ -1583,9 +1584,9 @@ class World implements ChunkManager{ $ev = new BlockPlaceEvent($player, $hand, $blockReplace, $blockClicked, $item); if($player->isAdventure(true) and !$ev->isCancelled()){ $canPlace = false; - $itemFactory = ItemFactory::getInstance(); + $itemParser = LegacyStringToItemParser::getInstance(); foreach($item->getCanPlaceOn() as $v){ - $entry = $itemFactory->fromString($v); + $entry = $itemParser->parse($v); if($entry->getBlock()->isSameType($blockClicked)){ $canPlace = true; break; diff --git a/src/world/generator/Flat.php b/src/world/generator/Flat.php index 59c09e6520..716986c577 100644 --- a/src/world/generator/Flat.php +++ b/src/world/generator/Flat.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\world\generator; use pocketmine\block\VanillaBlocks; -use pocketmine\item\ItemFactory; +use pocketmine\item\LegacyStringToItemParser; use pocketmine\world\ChunkManager; use pocketmine\world\format\Chunk; use pocketmine\world\generator\object\OreType; @@ -99,7 +99,7 @@ class Flat extends Generator{ $result = []; $split = array_map('\trim', explode(',', $layers)); $y = 0; - $itemFactory = ItemFactory::getInstance(); + $itemParser = LegacyStringToItemParser::getInstance(); foreach($split as $line){ preg_match('#^(?:(\d+)[x|*])?(.+)$#', $line, $matches); if(count($matches) !== 3){ @@ -108,7 +108,7 @@ class Flat extends Generator{ $cnt = $matches[1] !== "" ? (int) $matches[1] : 1; try{ - $b = $itemFactory->fromString($matches[2])->getBlock(); + $b = $itemParser->parse($matches[2])->getBlock(); }catch(\InvalidArgumentException $e){ throw new InvalidGeneratorOptionsException("Invalid preset layer \"$line\": " . $e->getMessage(), 0, $e); } diff --git a/tests/phpunit/item/ItemFactoryTest.php b/tests/phpunit/item/ItemFactoryTest.php index 723eed6c83..3ae28fb271 100644 --- a/tests/phpunit/item/ItemFactoryTest.php +++ b/tests/phpunit/item/ItemFactoryTest.php @@ -37,35 +37,6 @@ class ItemFactoryTest extends TestCase{ } } - /** - * @return mixed[][] - * @phpstan-return list - */ - public function itemFromStringProvider() : array{ - return [ - ["dye:4", ItemIds::DYE, 4], - ["351", ItemIds::DYE, 0], - ["351:4", ItemIds::DYE, 4], - ["stone:3", ItemIds::STONE, 3], - ["minecraft:string", ItemIds::STRING, 0], - ["diamond_pickaxe", ItemIds::DIAMOND_PICKAXE, 0], - ["diamond_pickaxe:5", ItemIds::DIAMOND_PICKAXE, 5] - ]; - } - - /** - * @dataProvider itemFromStringProvider - * @param string $string - * @param int $id - * @param int $meta - */ - public function testFromStringSingle(string $string, int $id, int $meta) : void{ - $item = ItemFactory::getInstance()->fromString($string); - - self::assertEquals($id, $item->getId()); - self::assertEquals($meta, $item->getMeta()); - } - /** * Test that durable items are correctly created by the item factory */ diff --git a/tests/phpunit/item/LegacyStringToItemParserTest.php b/tests/phpunit/item/LegacyStringToItemParserTest.php new file mode 100644 index 0000000000..56e3565528 --- /dev/null +++ b/tests/phpunit/item/LegacyStringToItemParserTest.php @@ -0,0 +1,58 @@ + + */ + public function itemFromStringProvider() : array{ + return [ + ["dye:4", ItemIds::DYE, 4], + ["351", ItemIds::DYE, 0], + ["351:4", ItemIds::DYE, 4], + ["stone:3", ItemIds::STONE, 3], + ["minecraft:string", ItemIds::STRING, 0], + ["diamond_pickaxe", ItemIds::DIAMOND_PICKAXE, 0], + ["diamond_pickaxe:5", ItemIds::DIAMOND_PICKAXE, 5] + ]; + } + + /** + * @dataProvider itemFromStringProvider + * @param string $string + * @param int $id + * @param int $meta + */ + public function testFromStringSingle(string $string, int $id, int $meta) : void{ + $item = LegacyStringToItemParser::getInstance()->parse($string); + + self::assertEquals($id, $item->getId()); + self::assertEquals($meta, $item->getMeta()); + } +} From 84f41153e97ddf4415ff197f4c1bfd7c21291a8f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 May 2020 00:25:16 +0100 Subject: [PATCH 1549/3224] silence another phpstan bug --- tests/phpstan/configs/phpstan-bugs.neon | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 0c8e285123..22a51e2fb7 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -70,6 +70,11 @@ parameters: count: 1 path: ../../../src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php + - + message: "#^Class pocketmine\\\\item\\\\LegacyStringToItemParser constructor invoked with 0 parameters, 1 required\\.$#" + count: 1 + path: ../../../src/item/LegacyStringToItemParser.php + - message: "#^Class pocketmine\\\\network\\\\mcpe\\\\StaticPacketCache constructor invoked with 0 parameters, 2 required\\.$#" count: 1 From 45f9c61d0f9bf1fbe7540ec1b19973feb399d1d0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 May 2020 13:28:35 +0100 Subject: [PATCH 1550/3224] forward-port of 2f47597d75b514944a2f3f5d293f2fb72dd7fb56 as best it fits --- src/world/format/io/data/BedrockWorldData.php | 7 +++++-- src/world/format/io/data/JavaWorldData.php | 6 +++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/world/format/io/data/BedrockWorldData.php b/src/world/format/io/data/BedrockWorldData.php index 5be66be8b9..ad50b9dddc 100644 --- a/src/world/format/io/data/BedrockWorldData.php +++ b/src/world/format/io/data/BedrockWorldData.php @@ -111,8 +111,11 @@ class BedrockWorldData extends BaseNbtWorldData{ } protected function load() : CompoundTag{ - $rawLevelData = file_get_contents($this->dataPath); - if($rawLevelData === false or strlen($rawLevelData) <= 8){ + $rawLevelData = @file_get_contents($this->dataPath); + if($rawLevelData === false){ + throw new CorruptedWorldException("Failed to read level.dat (permission denied or doesn't exist)"); + } + if(strlen($rawLevelData) <= 8){ throw new CorruptedWorldException("Truncated level.dat"); } $nbt = new LittleEndianNbtSerializer(); diff --git a/src/world/format/io/data/JavaWorldData.php b/src/world/format/io/data/JavaWorldData.php index 2b7f455980..271728f5d9 100644 --- a/src/world/format/io/data/JavaWorldData.php +++ b/src/world/format/io/data/JavaWorldData.php @@ -75,9 +75,13 @@ class JavaWorldData extends BaseNbtWorldData{ } protected function load() : CompoundTag{ + $rawLevelData = @file_get_contents($this->dataPath); + if($rawLevelData === false){ + throw new CorruptedWorldException("Failed to read level.dat (permission denied or doesn't exist)"); + } $nbt = new BigEndianNbtSerializer(); try{ - $worldData = $nbt->readCompressed(file_get_contents($this->dataPath))->mustGetCompoundTag(); + $worldData = $nbt->readCompressed($rawLevelData)->mustGetCompoundTag(); }catch(NbtDataException $e){ throw new CorruptedWorldException($e->getMessage(), 0, $e); } From 8c2878fe5be1be88e8dbc2e748c5131a6a0834f1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 May 2020 13:36:42 +0100 Subject: [PATCH 1551/3224] Added JwtUtils::parse(), make ProcessLoginTask more robust --- src/network/mcpe/JwtUtils.php | 20 +++++++++++++------- src/network/mcpe/auth/ProcessLoginTask.php | 10 +++++----- src/network/mcpe/protocol/LoginPacket.php | 4 ++-- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/network/mcpe/JwtUtils.php b/src/network/mcpe/JwtUtils.php index 0e5a81b0ad..358da0372f 100644 --- a/src/network/mcpe/JwtUtils.php +++ b/src/network/mcpe/JwtUtils.php @@ -38,22 +38,28 @@ use function strtr; final class JwtUtils{ /** - * @return mixed[] array of claims - * @phpstan-return array + * TODO: replace this result with an object + * + * @return mixed[] + * @phpstan-return array{mixed[], mixed[], string} * * @throws \UnexpectedValueException */ - public static function getClaims(string $token) : array{ + public static function parse(string $token) : array{ $v = explode(".", $token); if(count($v) !== 3){ throw new \UnexpectedValueException("Expected exactly 3 JWT parts, got " . count($v)); } - $result = json_decode(self::b64UrlDecode($v[1]), true); - if(!is_array($result)){ + $header = json_decode(self::b64UrlDecode($v[0]), true); + if(!is_array($header)){ + throw new \UnexpectedValueException("Failed to decode JWT header JSON: ". json_last_error_msg()); + } + $body = json_decode(self::b64UrlDecode($v[1]), true); + if(!is_array($body)){ throw new \UnexpectedValueException("Failed to decode JWT payload JSON: " . json_last_error_msg()); } - - return $result; + $signature = self::b64UrlDecode($v[2]); + return [$header, $body, $signature]; } public static function b64UrlEncode(string $str) : string{ diff --git a/src/network/mcpe/auth/ProcessLoginTask.php b/src/network/mcpe/auth/ProcessLoginTask.php index c997b48d7f..2cc68a30fb 100644 --- a/src/network/mcpe/auth/ProcessLoginTask.php +++ b/src/network/mcpe/auth/ProcessLoginTask.php @@ -36,7 +36,6 @@ use function base64_decode; use function bin2hex; use function explode; use function gmp_init; -use function json_decode; use function openssl_verify; use function str_split; use function strlen; @@ -115,7 +114,11 @@ class ProcessLoginTask extends AsyncTask{ * @throws VerifyLoginException if errors are encountered */ private function validateToken(string $jwt, ?string &$currentPublicKey, bool $first = false) : void{ - [$headB64, $payloadB64, $sigB64] = explode('.', $jwt); + try{ + [$headers, $claims, $plainSignature] = JwtUtils::parse($jwt); + }catch(\UnexpectedValueException $e){ + throw new VerifyLoginException("Failed to parse JWT: " . $e->getMessage(), 0, $e); + } if($currentPublicKey === null){ if(!$first){ @@ -123,7 +126,6 @@ class ProcessLoginTask extends AsyncTask{ } //First link, check that it is self-signed - $headers = json_decode(JwtUtils::b64UrlDecode($headB64), true); $currentPublicKey = $headers["x5u"]; } @@ -148,8 +150,6 @@ class ProcessLoginTask extends AsyncTask{ $this->authenticated = true; //we're signed into xbox live } - $claims = json_decode(JwtUtils::b64UrlDecode($payloadB64), true); - $time = time(); if(isset($claims["nbf"]) and $claims["nbf"] > $time + self::CLOCK_DRIFT_MAX){ throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.tooEarly"); diff --git a/src/network/mcpe/protocol/LoginPacket.php b/src/network/mcpe/protocol/LoginPacket.php index 5b5fc75945..e8c90826fa 100644 --- a/src/network/mcpe/protocol/LoginPacket.php +++ b/src/network/mcpe/protocol/LoginPacket.php @@ -88,7 +88,7 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ foreach($this->chainDataJwt->chain as $k => $chain){ //validate every chain element try{ - $claims = JwtUtils::getClaims($chain); + [, $claims, ] = JwtUtils::parse($chain); }catch(\UnexpectedValueException $e){ throw new PacketDecodeException($e->getMessage(), 0, $e); } @@ -117,7 +117,7 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ $this->clientDataJwt = $buffer->get($buffer->getLInt()); try{ - $clientData = JwtUtils::getClaims($this->clientDataJwt); + [, $clientData, ] = JwtUtils::parse($this->clientDataJwt); }catch(\UnexpectedValueException $e){ throw new PacketDecodeException($e->getMessage(), 0, $e); } From 934f85841ca3bfd2709e399c4bb40ec95de970f4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 May 2020 13:37:49 +0100 Subject: [PATCH 1552/3224] asserts :clap: are :clap: not :clap: error :clap: checking --- src/network/mcpe/auth/ProcessLoginTask.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/network/mcpe/auth/ProcessLoginTask.php b/src/network/mcpe/auth/ProcessLoginTask.php index 2cc68a30fb..01c03a21ce 100644 --- a/src/network/mcpe/auth/ProcessLoginTask.php +++ b/src/network/mcpe/auth/ProcessLoginTask.php @@ -31,7 +31,7 @@ use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer; use pocketmine\network\mcpe\JwtUtils; use pocketmine\network\mcpe\protocol\LoginPacket; use pocketmine\scheduler\AsyncTask; -use function assert; +use pocketmine\utils\AssumptionFailedError; use function base64_decode; use function bin2hex; use function explode; @@ -129,14 +129,18 @@ class ProcessLoginTask extends AsyncTask{ $currentPublicKey = $headers["x5u"]; } - $plainSignature = JwtUtils::b64UrlDecode($sigB64); - assert(strlen($plainSignature) === 96); + if(strlen($plainSignature) !== 96){ + throw new VerifyLoginException("JWT signature has unexpected length, expected 96, got " . strlen($plainSignature)); + } + [$rString, $sString] = str_split($plainSignature, 48); $sig = new Signature(gmp_init(bin2hex($rString), 16), gmp_init(bin2hex($sString), 16)); + $rawParts = explode('.', $jwt); + if(count($rawParts) !== 3) throw new AssumptionFailedError("Parts count should be 3 as verified by JwtUtils::parse()"); $derSerializer = new DerPublicKeySerializer(); $v = openssl_verify( - "$headB64.$payloadB64", + $rawParts[0] . '.' . $rawParts[1], (new DerSignatureSerializer())->serialize($sig), (new PemPublicKeySerializer($derSerializer))->serialize($derSerializer->parse(base64_decode($currentPublicKey, true))), OPENSSL_ALGO_SHA384 From 161ac468f3a527935164296f5776cbf971fca7c3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 May 2020 19:23:01 +0100 Subject: [PATCH 1553/3224] ProcessLoginTask: properly cater for key parsing errors --- src/network/mcpe/auth/ProcessLoginTask.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/network/mcpe/auth/ProcessLoginTask.php b/src/network/mcpe/auth/ProcessLoginTask.php index 01c03a21ce..0e10d0e12b 100644 --- a/src/network/mcpe/auth/ProcessLoginTask.php +++ b/src/network/mcpe/auth/ProcessLoginTask.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\auth; +use FG\ASN1\Exception\ParserException; use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; use Mdanter\Ecc\Crypto\Signature\Signature; use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; @@ -34,6 +35,7 @@ use pocketmine\scheduler\AsyncTask; use pocketmine\utils\AssumptionFailedError; use function base64_decode; use function bin2hex; +use function count; use function explode; use function gmp_init; use function openssl_verify; @@ -136,13 +138,23 @@ class ProcessLoginTask extends AsyncTask{ [$rString, $sString] = str_split($plainSignature, 48); $sig = new Signature(gmp_init(bin2hex($rString), 16), gmp_init(bin2hex($sString), 16)); + $derPublicKeySerializer = new DerPublicKeySerializer(); + $rawPublicKey = base64_decode($currentPublicKey, true); + if($rawPublicKey === false){ + throw new VerifyLoginException("Failed to decode base64'd public key"); + } + try{ + $signingKey = $derPublicKeySerializer->parse($rawPublicKey); + }catch(\RuntimeException | ParserException $e){ + throw new VerifyLoginException("Failed to parse DER public key: " . $e->getMessage(), 0, $e); + } + $rawParts = explode('.', $jwt); if(count($rawParts) !== 3) throw new AssumptionFailedError("Parts count should be 3 as verified by JwtUtils::parse()"); - $derSerializer = new DerPublicKeySerializer(); $v = openssl_verify( $rawParts[0] . '.' . $rawParts[1], (new DerSignatureSerializer())->serialize($sig), - (new PemPublicKeySerializer($derSerializer))->serialize($derSerializer->parse(base64_decode($currentPublicKey, true))), + (new PemPublicKeySerializer($derPublicKeySerializer))->serialize($signingKey), OPENSSL_ALGO_SHA384 ); From d7eb4f9651194819d5d6199bb64cd09b5eb2c974 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 May 2020 20:46:01 +0100 Subject: [PATCH 1554/3224] Extract more general-purpose logic to JwtUtils this code could now be reused for creating custom login packets. --- src/network/mcpe/JwtUtils.php | 73 +++++++++++++++++++ src/network/mcpe/auth/ProcessLoginTask.php | 38 ++-------- .../mcpe/encryption/EncryptionUtils.php | 31 +++----- 3 files changed, 89 insertions(+), 53 deletions(-) diff --git a/src/network/mcpe/JwtUtils.php b/src/network/mcpe/JwtUtils.php index 358da0372f..3e847f8599 100644 --- a/src/network/mcpe/JwtUtils.php +++ b/src/network/mcpe/JwtUtils.php @@ -23,17 +23,39 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; +use Mdanter\Ecc\Crypto\Key\PrivateKeyInterface; +use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; +use Mdanter\Ecc\Crypto\Signature\Signature; +use Mdanter\Ecc\Serializer\PrivateKey\DerPrivateKeySerializer; +use Mdanter\Ecc\Serializer\PrivateKey\PemPrivateKeySerializer; +use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; +use Mdanter\Ecc\Serializer\PublicKey\PemPublicKeySerializer; +use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer; +use pocketmine\network\mcpe\auth\VerifyLoginException; +use pocketmine\utils\AssumptionFailedError; use function base64_decode; use function base64_encode; +use function bin2hex; use function count; use function explode; +use function gmp_init; +use function gmp_strval; +use function hex2bin; use function is_array; use function json_decode; +use function json_encode; use function json_last_error_msg; +use function openssl_error_string; +use function openssl_sign; +use function openssl_verify; use function rtrim; +use function str_pad; use function str_repeat; +use function str_split; use function strlen; use function strtr; +use const OPENSSL_ALGO_SHA384; +use const STR_PAD_LEFT; final class JwtUtils{ @@ -62,6 +84,57 @@ final class JwtUtils{ return [$header, $body, $signature]; } + /** + * @throws \UnexpectedValueException + */ + public static function verify(string $jwt, PublicKeyInterface $signingKey) : bool{ + $parts = explode('.', $jwt); + if(count($parts) !== 3){ + throw new \UnexpectedValueException("Expected exactly 3 JWT parts, got " . count($parts)); + } + [$header, $body, $signature] = $parts; + + $plainSignature = self::b64UrlDecode($signature); + if(strlen($plainSignature) !== 96){ + throw new VerifyLoginException("JWT signature has unexpected length, expected 96, got " . strlen($plainSignature)); + } + + [$rString, $sString] = str_split($plainSignature, 48); + $sig = new Signature(gmp_init(bin2hex($rString), 16), gmp_init(bin2hex($sString), 16)); + + $v = openssl_verify( + $header . '.' . $body, + (new DerSignatureSerializer())->serialize($sig), + (new PemPublicKeySerializer(new DerPublicKeySerializer()))->serialize($signingKey), + OPENSSL_ALGO_SHA384 + ); + switch($v){ + case 0: return false; + case 1: return true; + case -1: throw new \UnexpectedValueException("Error verifying JWT signature: " . openssl_error_string()); + default: throw new AssumptionFailedError("openssl_verify() should only return -1, 0 or 1"); + } + } + + public static function create(array $header, array $claims, PrivateKeyInterface $signingKey) : string{ + $jwtBody = JwtUtils::b64UrlEncode(json_encode($header)) . "." . JwtUtils::b64UrlEncode(json_encode($claims)); + + openssl_sign( + $jwtBody, + $sig, + (new PemPrivateKeySerializer(new DerPrivateKeySerializer()))->serialize($signingKey), + OPENSSL_ALGO_SHA384 + ); + + $decodedSig = (new DerSignatureSerializer())->parse($sig); + $jwtSig = JwtUtils::b64UrlEncode( + hex2bin(str_pad(gmp_strval($decodedSig->getR(), 16), 96, "0", STR_PAD_LEFT)) . + hex2bin(str_pad(gmp_strval($decodedSig->getS(), 16), 96, "0", STR_PAD_LEFT)) + ); + + return "$jwtBody.$jwtSig"; + } + public static function b64UrlEncode(string $str) : string{ return rtrim(strtr(base64_encode($str), '+/', '-_'), '='); } diff --git a/src/network/mcpe/auth/ProcessLoginTask.php b/src/network/mcpe/auth/ProcessLoginTask.php index 0e10d0e12b..24b3bcbb6e 100644 --- a/src/network/mcpe/auth/ProcessLoginTask.php +++ b/src/network/mcpe/auth/ProcessLoginTask.php @@ -25,24 +25,12 @@ namespace pocketmine\network\mcpe\auth; use FG\ASN1\Exception\ParserException; use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; -use Mdanter\Ecc\Crypto\Signature\Signature; use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; -use Mdanter\Ecc\Serializer\PublicKey\PemPublicKeySerializer; -use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer; use pocketmine\network\mcpe\JwtUtils; use pocketmine\network\mcpe\protocol\LoginPacket; use pocketmine\scheduler\AsyncTask; -use pocketmine\utils\AssumptionFailedError; use function base64_decode; -use function bin2hex; -use function count; -use function explode; -use function gmp_init; -use function openssl_verify; -use function str_split; -use function strlen; use function time; -use const OPENSSL_ALGO_SHA384; class ProcessLoginTask extends AsyncTask{ private const TLS_KEY_ON_COMPLETION = "completion"; @@ -117,7 +105,7 @@ class ProcessLoginTask extends AsyncTask{ */ private function validateToken(string $jwt, ?string &$currentPublicKey, bool $first = false) : void{ try{ - [$headers, $claims, $plainSignature] = JwtUtils::parse($jwt); + [$headers, $claims, ] = JwtUtils::parse($jwt); }catch(\UnexpectedValueException $e){ throw new VerifyLoginException("Failed to parse JWT: " . $e->getMessage(), 0, $e); } @@ -131,13 +119,6 @@ class ProcessLoginTask extends AsyncTask{ $currentPublicKey = $headers["x5u"]; } - if(strlen($plainSignature) !== 96){ - throw new VerifyLoginException("JWT signature has unexpected length, expected 96, got " . strlen($plainSignature)); - } - - [$rString, $sString] = str_split($plainSignature, 48); - $sig = new Signature(gmp_init(bin2hex($rString), 16), gmp_init(bin2hex($sString), 16)); - $derPublicKeySerializer = new DerPublicKeySerializer(); $rawPublicKey = base64_decode($currentPublicKey, true); if($rawPublicKey === false){ @@ -149,17 +130,12 @@ class ProcessLoginTask extends AsyncTask{ throw new VerifyLoginException("Failed to parse DER public key: " . $e->getMessage(), 0, $e); } - $rawParts = explode('.', $jwt); - if(count($rawParts) !== 3) throw new AssumptionFailedError("Parts count should be 3 as verified by JwtUtils::parse()"); - $v = openssl_verify( - $rawParts[0] . '.' . $rawParts[1], - (new DerSignatureSerializer())->serialize($sig), - (new PemPublicKeySerializer($derPublicKeySerializer))->serialize($signingKey), - OPENSSL_ALGO_SHA384 - ); - - if($v !== 1){ - throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.badSignature"); + try{ + if(!JwtUtils::verify($jwt, $signingKey)){ + throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.badSignature"); + } + }catch(\UnexpectedValueException $e){ + throw new VerifyLoginException($e->getMessage(), 0, $e); } if($currentPublicKey === self::MOJANG_ROOT_PUBLIC_KEY){ diff --git a/src/network/mcpe/encryption/EncryptionUtils.php b/src/network/mcpe/encryption/EncryptionUtils.php index a396c8ab19..c34e4a38f3 100644 --- a/src/network/mcpe/encryption/EncryptionUtils.php +++ b/src/network/mcpe/encryption/EncryptionUtils.php @@ -25,17 +25,12 @@ namespace pocketmine\network\mcpe\encryption; use Mdanter\Ecc\Crypto\Key\PrivateKeyInterface; use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; -use Mdanter\Ecc\Serializer\PrivateKey\DerPrivateKeySerializer; -use Mdanter\Ecc\Serializer\PrivateKey\PemPrivateKeySerializer; use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; -use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer; use pocketmine\network\mcpe\JwtUtils; use function base64_encode; use function gmp_strval; use function hex2bin; -use function json_encode; use function openssl_digest; -use function openssl_sign; use function str_pad; final class EncryptionUtils{ @@ -53,23 +48,15 @@ final class EncryptionUtils{ } public static function generateServerHandshakeJwt(PrivateKeyInterface $serverPriv, string $salt) : string{ - $jwtBody = JwtUtils::b64UrlEncode(json_encode([ - "x5u" => base64_encode((new DerPublicKeySerializer())->serialize($serverPriv->getPublicKey())), - "alg" => "ES384" - ]) - ) . "." . JwtUtils::b64UrlEncode(json_encode([ - "salt" => base64_encode($salt) - ]) - ); - - openssl_sign($jwtBody, $sig, (new PemPrivateKeySerializer(new DerPrivateKeySerializer()))->serialize($serverPriv), OPENSSL_ALGO_SHA384); - - $decodedSig = (new DerSignatureSerializer())->parse($sig); - $jwtSig = JwtUtils::b64UrlEncode( - hex2bin(str_pad(gmp_strval($decodedSig->getR(), 16), 96, "0", STR_PAD_LEFT)) . - hex2bin(str_pad(gmp_strval($decodedSig->getS(), 16), 96, "0", STR_PAD_LEFT)) + return JwtUtils::create( + [ + "x5u" => base64_encode((new DerPublicKeySerializer())->serialize($serverPriv->getPublicKey())), + "alg" => "ES384" + ], + [ + "salt" => base64_encode($salt) + ], + $serverPriv ); - - return "$jwtBody.$jwtSig"; } } From 44a7829536390c177f44943794de7c7711b1804c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 May 2020 20:50:41 +0100 Subject: [PATCH 1555/3224] VerifyLoginException: fixed rogue usage in JwtUtils --- src/network/mcpe/JwtUtils.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/network/mcpe/JwtUtils.php b/src/network/mcpe/JwtUtils.php index 3e847f8599..d1715418ef 100644 --- a/src/network/mcpe/JwtUtils.php +++ b/src/network/mcpe/JwtUtils.php @@ -31,7 +31,6 @@ use Mdanter\Ecc\Serializer\PrivateKey\PemPrivateKeySerializer; use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; use Mdanter\Ecc\Serializer\PublicKey\PemPublicKeySerializer; use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer; -use pocketmine\network\mcpe\auth\VerifyLoginException; use pocketmine\utils\AssumptionFailedError; use function base64_decode; use function base64_encode; @@ -96,7 +95,7 @@ final class JwtUtils{ $plainSignature = self::b64UrlDecode($signature); if(strlen($plainSignature) !== 96){ - throw new VerifyLoginException("JWT signature has unexpected length, expected 96, got " . strlen($plainSignature)); + throw new \UnexpectedValueException("JWT signature has unexpected length, expected 96, got " . strlen($plainSignature)); } [$rString, $sString] = str_split($plainSignature, 48); From 486e0e710b807f8d1c2325d156ee63e814832cc8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 May 2020 20:51:24 +0100 Subject: [PATCH 1556/3224] JwtUtils: fix minor formatting issue --- src/network/mcpe/JwtUtils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/JwtUtils.php b/src/network/mcpe/JwtUtils.php index d1715418ef..2a89e1b180 100644 --- a/src/network/mcpe/JwtUtils.php +++ b/src/network/mcpe/JwtUtils.php @@ -73,7 +73,7 @@ final class JwtUtils{ } $header = json_decode(self::b64UrlDecode($v[0]), true); if(!is_array($header)){ - throw new \UnexpectedValueException("Failed to decode JWT header JSON: ". json_last_error_msg()); + throw new \UnexpectedValueException("Failed to decode JWT header JSON: " . json_last_error_msg()); } $body = json_decode(self::b64UrlDecode($v[1]), true); if(!is_array($body)){ From 84291e798039bce314ee958f6b4c352be8d20331 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 May 2020 21:23:04 +0100 Subject: [PATCH 1557/3224] Throw a more specific exception for JWT handling errors --- src/network/mcpe/JwtException.php | 28 ++++++++++++++++++++++ src/network/mcpe/JwtUtils.php | 18 +++++++------- src/network/mcpe/auth/ProcessLoginTask.php | 5 ++-- src/network/mcpe/protocol/LoginPacket.php | 5 ++-- 4 files changed, 43 insertions(+), 13 deletions(-) create mode 100644 src/network/mcpe/JwtException.php diff --git a/src/network/mcpe/JwtException.php b/src/network/mcpe/JwtException.php new file mode 100644 index 0000000000..14a3c21a23 --- /dev/null +++ b/src/network/mcpe/JwtException.php @@ -0,0 +1,28 @@ +getMessage(), 0, $e); } @@ -134,7 +135,7 @@ class ProcessLoginTask extends AsyncTask{ if(!JwtUtils::verify($jwt, $signingKey)){ throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.badSignature"); } - }catch(\UnexpectedValueException $e){ + }catch(JwtException $e){ throw new VerifyLoginException($e->getMessage(), 0, $e); } diff --git a/src/network/mcpe/protocol/LoginPacket.php b/src/network/mcpe/protocol/LoginPacket.php index e8c90826fa..c018f65821 100644 --- a/src/network/mcpe/protocol/LoginPacket.php +++ b/src/network/mcpe/protocol/LoginPacket.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\network\mcpe\JwtException; use pocketmine\network\mcpe\JwtUtils; use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\login\AuthenticationData; @@ -89,7 +90,7 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ //validate every chain element try{ [, $claims, ] = JwtUtils::parse($chain); - }catch(\UnexpectedValueException $e){ + }catch(JwtException $e){ throw new PacketDecodeException($e->getMessage(), 0, $e); } if(isset($claims["extraData"])){ @@ -118,7 +119,7 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ $this->clientDataJwt = $buffer->get($buffer->getLInt()); try{ [, $clientData, ] = JwtUtils::parse($this->clientDataJwt); - }catch(\UnexpectedValueException $e){ + }catch(JwtException $e){ throw new PacketDecodeException($e->getMessage(), 0, $e); } From 97a4a53e59854e0cc6bc17e7469bbe18ad14176f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 May 2020 22:48:08 +0100 Subject: [PATCH 1558/3224] added legacy string item mappings that were unknowingly removed these are returned for the sake of backwards compatibility for plugins. --- resources/item_from_string_bc_map.json | 78 ++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/resources/item_from_string_bc_map.json b/resources/item_from_string_bc_map.json index 34de8fbbed..0edc1e7dfb 100644 --- a/resources/item_from_string_bc_map.json +++ b/resources/item_from_string_bc_map.json @@ -9,7 +9,10 @@ "acacia_standing_sign": -190, "acacia_trapdoor": -145, "acacia_wall_sign": -191, + "acacia_wood_stairs": 163, + "acacia_wooden_stairs": 163, "activator_rail": 126, + "active_redstone_lamp": 124, "air": 0, "andesite_stairs": -171, "anvil": 145, @@ -18,7 +21,9 @@ "appleenchanted": 466, "armor_stand": 425, "arrow": 262, + "ateupd_block": 249, "baked_potato": 393, + "baked_potatoes": 393, "balloon": 448, "bamboo": -163, "bamboo_sapling": -164, @@ -33,6 +38,7 @@ "beef": 363, "beetroot": 457, "beetroot_block": 244, + "beetroot_seed": 458, "beetroot_seeds": 458, "beetroot_soup": 459, "bell": -206, @@ -46,11 +52,14 @@ "birch_standing_sign": -186, "birch_trapdoor": -146, "birch_wall_sign": -187, + "birch_wood_stairs": 135, + "birch_wooden_stairs": 135, "black_glazed_terracotta": 235, "blast_furnace": -196, "blaze_powder": 377, "blaze_rod": 369, "bleach": 451, + "block_moved_by_piston": 250, "blue_glazed_terracotta": 231, "blue_ice": -11, "boat": 333, @@ -67,12 +76,15 @@ "brick": 336, "brick_block": 45, "brick_stairs": 108, + "bricks": 45, + "bricks_block": 45, "brown_glazed_terracotta": 232, "brown_mushroom": 39, "brown_mushroom_block": 99, "bubble_column": -160, "bucket": 325, "burning_furnace": 62, + "bush": 32, "cactus": 81, "cake": 354, "cake_block": 92, @@ -109,16 +121,21 @@ "clay_ball": 337, "clay_block": 82, "clock": 347, + "clown_fish": 461, "clownfish": 461, "coal": 263, "coal_block": 173, "coal_ore": 16, + "cobble": 4, + "cobble_stairs": 67, + "cobble_wall": 139, "cobblestone": 4, "cobblestone_stairs": 67, "cobblestone_wall": 139, "cobweb": 30, "cocoa": 127, "cocoa_block": 127, + "cocoa_pods": 127, "colored_torch_bp": 204, "colored_torch_rg": 202, "command_block": 137, @@ -158,6 +175,8 @@ "dark_oak_pressure_plate": -152, "dark_oak_stairs": 164, "dark_oak_trapdoor": -147, + "dark_oak_wood_stairs": 164, + "dark_oak_wooden_stairs": 164, "dark_prismarine_stairs": -3, "darkoak_sign": 476, "darkoak_standing_sign": -192, @@ -185,12 +204,19 @@ "diorite_stairs": -170, "dirt": 3, "dispenser": 23, + "door_block": 64, "double_plant": 175, + "double_red_sandstone_slab": 181, + "double_slab": 43, + "double_slabs": 43, "double_stone_slab": 43, "double_stone_slab2": 181, "double_stone_slab3": -167, "double_stone_slab4": -168, + "double_wood_slab": 157, + "double_wood_slabs": 157, "double_wooden_slab": 157, + "double_wooden_slabs": 157, "dragon_breath": 437, "dragon_egg": 122, "dried_kelp": 464, @@ -323,8 +349,10 @@ "emerald_ore": 129, "empty_map": 395, "emptymap": 395, + "enchant_table": 116, "enchanted_book": 403, "enchanted_golden_apple": 466, + "enchanting_bottle": 384, "enchanting_table": 116, "enchantment_table": 116, "end_brick_stairs": -178, @@ -343,6 +371,11 @@ "feather": 288, "fence": 85, "fence_gate": 107, + "fence_gate_acacia": 187, + "fence_gate_birch": 184, + "fence_gate_dark_oak": 186, + "fence_gate_jungle": 185, + "fence_gate_spruce": 183, "fermented_spider_eye": 376, "filled_map": 358, "fire": 51, @@ -369,12 +402,14 @@ "glass": 20, "glass_bottle": 374, "glass_pane": 102, + "glass_panel": 102, "glistering_melon": 382, "glow_stick": 166, "glowing_obsidian": 246, "glowing_redstone_ore": 74, "glowingobsidian": 246, "glowstone": 89, + "glowstone_block": 89, "glowstone_dust": 348, "gold_axe": 286, "gold_block": 41, @@ -388,6 +423,7 @@ "gold_nugget": 371, "gold_ore": 14, "gold_pickaxe": 285, + "gold_pressure_plate": 147, "gold_shovel": 284, "gold_sword": 283, "golden_apple": 322, @@ -434,11 +470,15 @@ "horsearmorleather": 416, "ice": 79, "ice_bomb": 453, + "inactive_redstone_lamp": 123, + "info_reserved6": 255, "info_update": 248, "info_update2": 249, + "inverted_daylight_sensor": 178, "invisible_bedrock": 95, "invisiblebedrock": 95, "iron_axe": 258, + "iron_bar": 101, "iron_bars": 101, "iron_block": 42, "iron_boots": 309, @@ -453,6 +493,7 @@ "iron_nugget": 452, "iron_ore": 15, "iron_pickaxe": 257, + "iron_pressure_plate": 148, "iron_shovel": 256, "iron_sword": 267, "iron_trapdoor": 167, @@ -480,6 +521,7 @@ "lava": 11, "lava_cauldron": -210, "lead": 420, + "leash": 420, "leather": 334, "leather_boots": 301, "leather_cap": 298, @@ -489,7 +531,9 @@ "leather_leggings": 300, "leather_pants": 300, "leather_tunic": 299, + "leave": 18, "leaves": 18, + "leave2": 161, "leaves2": 161, "lectern": -194, "lever": 69, @@ -527,10 +571,12 @@ "mob_head_block": 144, "mob_spawner": 52, "monster_egg": 97, + "monster_egg_block": 97, "monster_spawner": 52, "moss_stone": 48, "mossy_cobblestone": 48, "mossy_cobblestone_stairs": -179, + "mossy_stone": 48, "mossy_stone_brick_stairs": -175, "moving_block": 250, "movingblock": 250, @@ -548,6 +594,8 @@ "nether_brick_block": 112, "nether_brick_fence": 113, "nether_brick_stairs": 114, + "nether_bricks": 112, + "nether_bricks_stairs": 114, "nether_quartz": 406, "nether_quartz_ore": 153, "nether_reactor": 247, @@ -566,6 +614,8 @@ "oak_door_block": 64, "oak_fence_gate": 107, "oak_stairs": 53, + "oak_wood_stairs": 53, + "oak_wooden_stairs": 53, "observer": 251, "obsidian": 49, "orange_glazed_terracotta": 221, @@ -576,7 +626,9 @@ "pink_glazed_terracotta": 226, "piston": 33, "piston_arm_collision": 34, + "piston_head": 34, "pistonarmcollision": 34, + "plank": 5, "planks": 5, "podzol": 243, "poisonous_potato": 394, @@ -586,18 +638,22 @@ "poppy": 38, "porkchop": 319, "portal": 90, + "portal_block": 90, "potato": 392, "potato_block": 142, "potatoes": 142, "potion": 373, "powered_comparator": 150, + "powered_comparator_block": 150, "powered_rail": 27, "powered_repeater": 94, + "powered_repeater_block": 94, "prismarine": 168, "prismarine_bricks_stairs": -4, "prismarine_crystals": 422, "prismarine_shard": 409, "prismarine_stairs": -2, + "puffer_fish": 462, "pufferfish": 462, "pumpkin": 86, "pumpkin_pie": 400, @@ -642,6 +698,7 @@ "red_nether_brick": 215, "red_nether_brick_stairs": -184, "red_sandstone": 179, + "red_sandstone_slab": 182, "red_sandstone_stairs": 180, "redstone": 331, "redstone_block": 152, @@ -656,6 +713,7 @@ "repeater_block": 93, "repeating_command_block": 188, "reserved6": 255, + "rose": 38, "rotten_flesh": 367, "saddle": 329, "salmon": 460, @@ -678,6 +736,8 @@ "silver_glazed_terracotta": 228, "skull": 397, "skull_block": 144, + "slab": 44, + "slabs": 44, "slime": 165, "slime_ball": 341, "slime_block": 165, @@ -709,6 +769,8 @@ "spruce_standing_sign": -181, "spruce_trapdoor": -149, "spruce_wall_sign": -182, + "spruce_wood_stairs": 134, + "spruce_wooden_stairs": 134, "stained_clay": 159, "stained_glass": 241, "stained_glass_pane": 160, @@ -717,6 +779,7 @@ "standing_sign": 63, "steak": 364, "stick": 280, + "sticks": 280, "sticky_piston": 29, "still_lava": 11, "still_water": 9, @@ -749,6 +812,8 @@ "stripped_spruce_log": -5, "structure_block": 252, "sugar": 353, + "sugar_cane": 338, + "sugar_canes": 338, "sugarcane": 338, "sugarcane_block": 83, "sweet_berries": 477, @@ -766,6 +831,8 @@ "trip_wire": 132, "tripwire": 132, "tripwire_hook": 131, + "trunk": 5, + "trunk2": 162, "turtle_egg": -159, "turtle_helmet": 469, "turtle_shell_piece": 468, @@ -773,7 +840,10 @@ "undyed_shulker_box": 205, "unlit_redstone_torch": 75, "unpowered_comparator": 149, + "unpowered_comparator_block": 149, "unpowered_repeater": 93, + "unpowered_repeater_block": 93, + "update_block": 248, "vine": 106, "vines": 106, "wall_banner": 177, @@ -782,22 +852,30 @@ "water_lily": 111, "waterlily": 111, "web": 30, + "weighted_pressure_plate_heavy": 148, + "weighted_pressure_plate_light": 147, "wheat": 296, "wheat_block": 59, "wheat_seeds": 295, "white_glazed_terracotta": 220, "wood": 17, "wood2": 162, + "wood_door_block": 64, + "wood_slab": 158, + "wood_slabs": 158, + "wood_stairs": 53, "wooden_axe": 271, "wooden_button": 143, "wooden_door": 324, "wooden_door_block": 64, "wooden_hoe": 290, "wooden_pickaxe": 270, + "wooden_plank": 5, "wooden_planks": 5, "wooden_pressure_plate": 72, "wooden_shovel": 269, "wooden_slab": 158, + "wooden_slabs": 158, "wooden_stairs": 53, "wooden_sword": 268, "wooden_trapdoor": 96, From e9ecb9a9fdc21559f573a0965ae8519567bb94a4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 May 2020 22:54:24 +0100 Subject: [PATCH 1559/3224] fixed build failure --- src/network/mcpe/JwtUtils.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/network/mcpe/JwtUtils.php b/src/network/mcpe/JwtUtils.php index c60a289cda..4f127efc0f 100644 --- a/src/network/mcpe/JwtUtils.php +++ b/src/network/mcpe/JwtUtils.php @@ -115,6 +115,10 @@ final class JwtUtils{ } } + /** + * @phpstan-param array $header + * @phpstan-param array $claims + */ public static function create(array $header, array $claims, PrivateKeyInterface $signingKey) : string{ $jwtBody = JwtUtils::b64UrlEncode(json_encode($header)) . "." . JwtUtils::b64UrlEncode(json_encode($claims)); From 36c5d9117d0d68001eb225d669c1492f2660ac25 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 14 May 2020 09:46:44 +0100 Subject: [PATCH 1560/3224] LoginPacketHandler: properly handle failure to base64_decode stuff from JWT previously this might just return false and blow up in your face. I considered fixing this on stable too, but it's less useful there because so much stuff on stable just explodes at the first wrong thing anyway. --- .../mcpe/handler/LoginPacketHandler.php | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index 243bbe2adc..efd3e4d9ae 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -100,16 +100,23 @@ class LoginPacketHandler extends PacketHandler{ return true; } + $safeB64Decode = static function(string $base64, string $context) : string{ + $result = base64_decode($base64, true); + if($result === false){ + throw new \InvalidArgumentException("$context: Malformed base64, cannot be decoded"); + } + return $result; + }; try{ $clientData = $packet->clientData; //this serves no purpose except readability /** @var SkinAnimation[] $animations */ $animations = []; - foreach($clientData->AnimatedImageData as $animation){ + foreach($clientData->AnimatedImageData as $k => $animation){ $animations[] = new SkinAnimation( new SkinImage( $animation->ImageHeight, $animation->ImageWidth, - base64_decode($animation->Image, true) + $safeB64Decode($animation->Image, "AnimatedImageData.$k.Image") ), $animation->Type, $animation->Frames @@ -117,12 +124,12 @@ class LoginPacketHandler extends PacketHandler{ } $skinData = new SkinData( $clientData->SkinId, - base64_decode($clientData->SkinResourcePatch, true), - new SkinImage($clientData->SkinImageHeight, $clientData->SkinImageWidth, base64_decode($clientData->SkinData, true)), + $safeB64Decode($clientData->SkinResourcePatch, "SkinResourcePatch"), + new SkinImage($clientData->SkinImageHeight, $clientData->SkinImageWidth, $safeB64Decode($clientData->SkinData, "SkinData")), $animations, - new SkinImage($clientData->CapeImageHeight, $clientData->CapeImageWidth, base64_decode($clientData->CapeData, true)), - base64_decode($clientData->SkinGeometryData, true), - base64_decode($clientData->SkinAnimationData, true), + new SkinImage($clientData->CapeImageHeight, $clientData->CapeImageWidth, $safeB64Decode($clientData->CapeData, "CapeData")), + $safeB64Decode($clientData->SkinGeometryData, "SkinGeometryData"), + $safeB64Decode($clientData->SkinAnimationData, "SkinAnimationData"), $clientData->PremiumSkin, $clientData->PersonaSkin, $clientData->CapeOnClassicSkin, From 3dafee6aa6704405cc43516ffc75431ae263ae48 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 14 May 2020 10:58:37 +0100 Subject: [PATCH 1561/3224] NetworkSession: explicitly unregister effect manager hooks on dispose, close #3455 --- src/entity/effect/EffectManager.php | 33 +++++++++++++++-------------- src/network/mcpe/NetworkSession.php | 23 ++++++++++++++++++-- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/entity/effect/EffectManager.php b/src/entity/effect/EffectManager.php index 9f05a4eb12..683c713bb6 100644 --- a/src/entity/effect/EffectManager.php +++ b/src/entity/effect/EffectManager.php @@ -23,14 +23,13 @@ declare(strict_types=1); namespace pocketmine\entity\effect; +use Ds\Set; use pocketmine\entity\Living; use pocketmine\event\entity\EntityEffectAddEvent; use pocketmine\event\entity\EntityEffectRemoveEvent; use pocketmine\utils\Color; -use pocketmine\utils\Utils; use function abs; use function count; -use function spl_object_id; class EffectManager{ @@ -46,19 +45,21 @@ class EffectManager{ protected $onlyAmbientEffects = false; /** - * @var \Closure[] - * @phpstan-var (\Closure(EffectInstance, bool $replacesOldEffect) : void)[] + * @var \Closure[]|Set + * @phpstan-var Set<\Closure(EffectInstance, bool $replacesOldEffect) : void> */ - protected $effectAddHooks = []; + protected $effectAddHooks; /** - * @var \Closure[] - * @phpstan-var (\Closure(EffectInstance) : void)[] + * @var \Closure[]|Set + * @phpstan-var Set<\Closure(EffectInstance) : void> */ - protected $effectRemoveHooks = []; + protected $effectRemoveHooks; public function __construct(Living $entity){ $this->entity = $entity; $this->bubbleColor = new Color(0, 0, 0, 0); + $this->effectAddHooks = new Set(); + $this->effectRemoveHooks = new Set(); } /** @@ -222,18 +223,18 @@ class EffectManager{ } /** - * @phpstan-param \Closure(EffectInstance, bool $replacesOldEffect) : void $closure + * @return \Closure[]|Set + * @phpstan-return Set<\Closure(EffectInstance, bool $replacesOldEffect) : void> */ - public function onEffectAdd(\Closure $closure) : void{ - Utils::validateCallableSignature(function(EffectInstance $effect, bool $replacesOldEffect) : void{}, $closure); - $this->effectAddHooks[spl_object_id($closure)] = $closure; + public function getEffectAddHooks() : Set{ + return $this->effectAddHooks; } /** - * @phpstan-param \Closure(EffectInstance) : void $closure + * @return \Closure[]|Set + * @phpstan-return Set<\Closure(EffectInstance) : void> */ - public function onEffectRemove(\Closure $closure) : void{ - Utils::validateCallableSignature(function(EffectInstance $effect) : void{}, $closure); - $this->effectRemoveHooks[spl_object_id($closure)] = $closure; + public function getEffectRemoveHooks() : Set{ + return $this->effectRemoveHooks; } } diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 1826c86186..ce295a065e 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; +use Ds\Set; use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; use pocketmine\entity\Attribute; use pocketmine\entity\effect\EffectInstance; @@ -166,6 +167,12 @@ class NetworkSession{ /** @var PacketSender */ private $sender; + /** + * @var \Closure[]|Set + * @phpstan-var Set<\Closure() : void> + */ + private $disposeHooks; + public function __construct(Server $server, NetworkSessionManager $manager, PacketPool $packetPool, PacketSender $sender, Compressor $compressor, string $ip, int $port){ $this->server = $server; $this->manager = $manager; @@ -179,6 +186,8 @@ class NetworkSession{ $this->compressor = $compressor; $this->packetPool = $packetPool; + $this->disposeHooks = new Set(); + $this->connectTime = time(); $this->setHandler(new LoginPacketHandler( @@ -218,12 +227,18 @@ class NetworkSession{ $this->player = new $class($this->server, $this, $this->info, $this->authenticated); $this->invManager = new InventoryManager($this->player, $this); - $this->player->getEffects()->onEffectAdd(function(EffectInstance $effect, bool $replacesOldEffect) : void{ + + $effectManager = $this->player->getEffects(); + $effectManager->getEffectAddHooks()->add($effectAddHook = function(EffectInstance $effect, bool $replacesOldEffect) : void{ $this->onEntityEffectAdded($this->player, $effect, $replacesOldEffect); }); - $this->player->getEffects()->onEffectRemove(function(EffectInstance $effect) : void{ + $effectManager->getEffectRemoveHooks()->add($effectRemoveHook = function(EffectInstance $effect) : void{ $this->onEntityEffectRemoved($this->player, $effect); }); + $this->disposeHooks->add(static function() use ($effectManager, $effectAddHook, $effectRemoveHook) : void{ + $effectManager->getEffectAddHooks()->remove($effectAddHook); + $effectManager->getEffectRemoveHooks()->remove($effectRemoveHook); + }); } public function getPlayer() : ?Player{ @@ -467,6 +482,10 @@ class NetworkSession{ $this->disconnectGuard = true; $func(); $this->disconnectGuard = false; + foreach($this->disposeHooks as $callback){ + $callback(); + } + $this->disposeHooks->clear(); $this->setHandler(null); $this->connected = false; $this->manager->remove($this); From 4437756987c53bf5407136eacaa951c545ca6aeb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 14 May 2020 14:13:28 +0100 Subject: [PATCH 1562/3224] Inventory: reduce API duplication by using a Set for viewers --- src/block/tile/BrewingStand.php | 2 +- src/block/tile/ContainerTrait.php | 6 +++--- src/block/tile/Furnace.php | 2 +- src/entity/Human.php | 6 +++--- src/entity/Living.php | 2 +- src/inventory/BaseInventory.php | 33 ++++++++++------------------- src/inventory/Inventory.php | 18 ++++------------ src/inventory/InventoryListener.php | 3 +-- 8 files changed, 25 insertions(+), 47 deletions(-) diff --git a/src/block/tile/BrewingStand.php b/src/block/tile/BrewingStand.php index 9e5c5dd16d..d6571f6301 100644 --- a/src/block/tile/BrewingStand.php +++ b/src/block/tile/BrewingStand.php @@ -54,7 +54,7 @@ class BrewingStand extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); $this->inventory = new BrewingStandInventory($this->pos); - $this->inventory->addListeners(CallbackInventoryListener::onAnyChange(function(Inventory $unused) : void{ + $this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange(function(Inventory $unused) : void{ $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, 1); })); } diff --git a/src/block/tile/ContainerTrait.php b/src/block/tile/ContainerTrait.php index 45711b5964..76ebacf31d 100644 --- a/src/block/tile/ContainerTrait.php +++ b/src/block/tile/ContainerTrait.php @@ -48,14 +48,14 @@ trait ContainerTrait{ $inventoryTag = $tag->getListTag(Container::TAG_ITEMS); $inventory = $this->getRealInventory(); - $listeners = $inventory->getListeners(); - $inventory->removeListeners(...$listeners); //prevent any events being fired by initialization + $listeners = $inventory->getListeners()->toArray(); + $inventory->getListeners()->remove(...$listeners); //prevent any events being fired by initialization $inventory->clearAll(); /** @var CompoundTag $itemNBT */ foreach($inventoryTag as $itemNBT){ $inventory->setItem($itemNBT->getByte("Slot"), Item::nbtDeserialize($itemNBT)); } - $inventory->addListeners(...$listeners); + $inventory->getListeners()->add(...$listeners); } if($tag->hasTag(Container::TAG_LOCK, StringTag::class)){ diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index 2fccc2d5da..ce67b83fce 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -58,7 +58,7 @@ class Furnace extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); $this->inventory = new FurnaceInventory($this->pos); - $this->inventory->addListeners(CallbackInventoryListener::onAnyChange( + $this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange( function(Inventory $unused) : void{ $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, 1); }) diff --git a/src/entity/Human.php b/src/entity/Human.php index ff0a843c78..55518fcf4c 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -221,8 +221,8 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $inventoryTag = $nbt->getListTag("Inventory"); if($inventoryTag !== null){ - $armorListeners = $this->armorInventory->getListeners(); - $this->armorInventory->removeListeners(...$armorListeners); + $armorListeners = $this->armorInventory->getListeners()->toArray(); + $this->armorInventory->getListeners()->clear(); /** @var CompoundTag $item */ foreach($inventoryTag as $i => $item){ @@ -236,7 +236,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ } } - $this->armorInventory->addListeners(...$armorListeners); + $this->armorInventory->getListeners()->add(...$armorListeners); } $enderChestInventoryTag = $nbt->getListTag("EnderChestInventory"); diff --git a/src/entity/Living.php b/src/entity/Living.php index daa2a69c44..c5cbf8949f 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -110,7 +110,7 @@ abstract class Living extends Entity{ $this->armorInventory = new ArmorInventory($this); //TODO: load/save armor inventory contents - $this->armorInventory->addListeners(CallbackInventoryListener::onAnyChange( + $this->armorInventory->getListeners()->add(CallbackInventoryListener::onAnyChange( function(Inventory $unused) : void{ foreach($this->getViewers() as $viewer){ $viewer->getNetworkSession()->onMobArmorChange($this); diff --git a/src/inventory/BaseInventory.php b/src/inventory/BaseInventory.php index 63ecb4d8f6..38bc601d38 100644 --- a/src/inventory/BaseInventory.php +++ b/src/inventory/BaseInventory.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\inventory; +use Ds\Set; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\player\Player; @@ -43,11 +44,15 @@ abstract class BaseInventory implements Inventory{ protected $slots; /** @var Player[] */ protected $viewers = []; - /** @var InventoryListener[] */ - protected $listeners = []; + /** + * @var InventoryListener[]|Set + * @phpstan-var Set + */ + protected $listeners; public function __construct(int $size){ $this->slots = new \SplFixedArray($size); + $this->listeners = new Set(); } /** @@ -92,8 +97,8 @@ abstract class BaseInventory implements Inventory{ $oldContents = $this->slots->toArray(); - $listeners = $this->listeners; - $this->listeners = []; + $listeners = $this->listeners->toArray(); + $this->listeners->clear(); $viewers = $this->viewers; $this->viewers = []; @@ -105,7 +110,7 @@ abstract class BaseInventory implements Inventory{ } } - $this->addListeners(...$listeners); //don't directly write, in case listeners were added while operation was in progress + $this->listeners->add(...$listeners); //don't directly write, in case listeners were added while operation was in progress foreach($viewers as $id => $viewer){ $this->viewers[$id] = $viewer; } @@ -372,23 +377,7 @@ abstract class BaseInventory implements Inventory{ return $slot >= 0 and $slot < $this->slots->getSize(); } - public function addListeners(InventoryListener ...$listeners) : void{ - foreach($listeners as $listener){ - $this->listeners[spl_object_id($listener)] = $listener; - } - } - - public function removeListeners(InventoryListener ...$listeners) : void{ - foreach($listeners as $listener){ - unset($this->listeners[spl_object_id($listener)]); - } - } - - public function removeAllListeners() : void{ - $this->listeners = []; - } - - public function getListeners() : array{ + public function getListeners() : Set{ return $this->listeners; } } diff --git a/src/inventory/Inventory.php b/src/inventory/Inventory.php index 95ea5001a2..e2226f82fc 100644 --- a/src/inventory/Inventory.php +++ b/src/inventory/Inventory.php @@ -26,6 +26,7 @@ declare(strict_types=1); */ namespace pocketmine\inventory; +use Ds\Set; use pocketmine\item\Item; use pocketmine\player\Player; @@ -155,19 +156,8 @@ interface Inventory{ public function slotExists(int $slot) : bool; /** - * @param InventoryListener ...$listeners + * @return InventoryListener[]|Set + * @phpstan-return Set */ - public function addListeners(InventoryListener ...$listeners) : void; - - /** - * @param InventoryListener ...$listeners - */ - public function removeListeners(InventoryListener ...$listeners) : void; - - public function removeAllListeners() : void; - - /** - * @return InventoryListener[] - */ - public function getListeners() : array; + public function getListeners() : Set; } diff --git a/src/inventory/InventoryListener.php b/src/inventory/InventoryListener.php index da8274661e..c5040993ff 100644 --- a/src/inventory/InventoryListener.php +++ b/src/inventory/InventoryListener.php @@ -29,8 +29,7 @@ use pocketmine\item\Item; * Classes implementing this interface can be injected into inventories to receive notifications when content changes * occur. * @see CallbackInventoryListener for a closure-based listener - * @see Inventory::addListeners() - * @see Inventory::removeListeners() + * @see Inventory::getListeners() */ interface InventoryListener{ From 86db3af89661ee123bdc79082d5138a865cdbe81 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 14 May 2020 20:38:08 +0100 Subject: [PATCH 1563/3224] remove utils\Color, use new pocketmine/color class we're so close to separating protocol from core !!! --- composer.json | 1 + composer.lock | 36 ++++- src/block/utils/DyeColor.php | 2 +- src/command/defaults/ParticleCommand.php | 2 +- src/entity/effect/Effect.php | 2 +- src/entity/effect/EffectInstance.php | 2 +- src/entity/effect/EffectManager.php | 2 +- src/entity/effect/PoisonEffect.php | 2 +- src/entity/effect/VanillaEffects.php | 2 +- src/entity/projectile/SplashPotion.php | 2 +- src/item/Armor.php | 2 +- .../protocol/ClientboundMapItemDataPacket.php | 2 +- .../mcpe/protocol/types/MapDecoration.php | 2 +- src/utils/Color.php | 130 ------------------ src/world/particle/DustParticle.php | 2 +- src/world/particle/InstantEnchantParticle.php | 2 +- src/world/particle/PotionSplashParticle.php | 2 +- 17 files changed, 50 insertions(+), 145 deletions(-) delete mode 100644 src/utils/Color.php diff --git a/composer.json b/composer.json index 7bc7933ca6..06b474b941 100644 --- a/composer.json +++ b/composer.json @@ -43,6 +43,7 @@ "pocketmine/callback-validator": "^1.0.1", "pocketmine/errorhandler": "^0.1.0", "pocketmine/uuid": "^0.1.0", + "pocketmine/color": "^0.1.0", "adhocore/json-comment": "^0.1.0", "particle/validator": "^2.3", "netresearch/jsonmapper": "^2.0", diff --git a/composer.lock b/composer.lock index e8d057667a..4009aa716c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "475fdc2cb5250b9813bc55fb87f7733c", + "content-hash": "4bd35ad045d13f81b88bef943137c79f", "packages": [ { "name": "adhocore/json-comment", @@ -465,6 +465,40 @@ "description": "Ad-hoc autoloading components used by PocketMine-MP", "time": "2020-01-31T14:26:22+00:00" }, + { + "name": "pocketmine/color", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/pmmp/Color.git", + "reference": "10f3453d0eb3eccbccad5cf58a00e42cdaef1772" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pmmp/Color/zipball/10f3453d0eb3eccbccad5cf58a00e42cdaef1772", + "reference": "10f3453d0eb3eccbccad5cf58a00e42cdaef1772", + "shasum": "" + }, + "require": { + "php": "^7.2" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.25", + "phpstan/phpstan-strict-rules": "^0.12.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "pocketmine\\color\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0" + ], + "description": "Color handling library used by PocketMine-MP and related projects", + "time": "2020-05-14T19:15:33+00:00" + }, { "name": "pocketmine/errorhandler", "version": "0.1.0", diff --git a/src/block/utils/DyeColor.php b/src/block/utils/DyeColor.php index d6f98b974c..855f8659cd 100644 --- a/src/block/utils/DyeColor.php +++ b/src/block/utils/DyeColor.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block\utils; -use pocketmine\utils\Color; +use pocketmine\color\Color; use pocketmine\utils\EnumTrait; /** diff --git a/src/command/defaults/ParticleCommand.php b/src/command/defaults/ParticleCommand.php index 37ba888f17..ef0df87df7 100644 --- a/src/command/defaults/ParticleCommand.php +++ b/src/command/defaults/ParticleCommand.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\command\defaults; use pocketmine\block\BlockFactory; +use pocketmine\color\Color; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\ItemFactory; @@ -31,7 +32,6 @@ use pocketmine\item\VanillaItems; use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; use pocketmine\player\Player; -use pocketmine\utils\Color; use pocketmine\utils\Random; use pocketmine\utils\TextFormat; use pocketmine\world\particle\AngryVillagerParticle; diff --git a/src/entity/effect/Effect.php b/src/entity/effect/Effect.php index 8b6e757e16..a6b85ea062 100644 --- a/src/entity/effect/Effect.php +++ b/src/entity/effect/Effect.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace pocketmine\entity\effect; +use pocketmine\color\Color; use pocketmine\entity\Entity; use pocketmine\entity\Living; -use pocketmine\utils\Color; class Effect{ diff --git a/src/entity/effect/EffectInstance.php b/src/entity/effect/EffectInstance.php index 65f4c8ebb7..c006275e78 100644 --- a/src/entity/effect/EffectInstance.php +++ b/src/entity/effect/EffectInstance.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\entity\effect; -use pocketmine\utils\Color; +use pocketmine\color\Color; use pocketmine\utils\Limits; use function max; diff --git a/src/entity/effect/EffectManager.php b/src/entity/effect/EffectManager.php index 683c713bb6..842447ae3c 100644 --- a/src/entity/effect/EffectManager.php +++ b/src/entity/effect/EffectManager.php @@ -24,10 +24,10 @@ declare(strict_types=1); namespace pocketmine\entity\effect; use Ds\Set; +use pocketmine\color\Color; use pocketmine\entity\Living; use pocketmine\event\entity\EntityEffectAddEvent; use pocketmine\event\entity\EntityEffectRemoveEvent; -use pocketmine\utils\Color; use function abs; use function count; diff --git a/src/entity/effect/PoisonEffect.php b/src/entity/effect/PoisonEffect.php index 2c351981a2..5c977be27b 100644 --- a/src/entity/effect/PoisonEffect.php +++ b/src/entity/effect/PoisonEffect.php @@ -23,10 +23,10 @@ declare(strict_types=1); namespace pocketmine\entity\effect; +use pocketmine\color\Color; use pocketmine\entity\Entity; use pocketmine\entity\Living; use pocketmine\event\entity\EntityDamageEvent; -use pocketmine\utils\Color; class PoisonEffect extends Effect{ diff --git a/src/entity/effect/VanillaEffects.php b/src/entity/effect/VanillaEffects.php index c714c18429..9efc7add99 100644 --- a/src/entity/effect/VanillaEffects.php +++ b/src/entity/effect/VanillaEffects.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\entity\effect; -use pocketmine\utils\Color; +use pocketmine\color\Color; use pocketmine\utils\RegistryTrait; use function assert; diff --git a/src/entity/projectile/SplashPotion.php b/src/entity/projectile/SplashPotion.php index 4c2336524d..20a087dee9 100644 --- a/src/entity/projectile/SplashPotion.php +++ b/src/entity/projectile/SplashPotion.php @@ -25,6 +25,7 @@ namespace pocketmine\entity\projectile; use pocketmine\block\BlockLegacyIds; use pocketmine\block\VanillaBlocks; +use pocketmine\color\Color; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\InstantEffect; use pocketmine\entity\Living; @@ -36,7 +37,6 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; -use pocketmine\utils\Color; use pocketmine\world\particle\PotionSplashParticle; use pocketmine\world\sound\PotionSplashSound; use function count; diff --git a/src/item/Armor.php b/src/item/Armor.php index a9b469965a..b10ae3ab93 100644 --- a/src/item/Armor.php +++ b/src/item/Armor.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\Block; +use pocketmine\color\Color; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\inventory\ArmorInventory; use pocketmine\item\enchantment\Enchantment; @@ -33,7 +34,6 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\player\Player; use pocketmine\utils\Binary; -use pocketmine\utils\Color; use function lcg_value; use function mt_rand; diff --git a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php index 3b1cec6ab7..dfaa37f33f 100644 --- a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php +++ b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php @@ -25,11 +25,11 @@ namespace pocketmine\network\mcpe\protocol; #include +use pocketmine\color\Color; use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\protocol\types\MapDecoration; use pocketmine\network\mcpe\protocol\types\MapTrackedObject; -use pocketmine\utils\Color; use function count; #ifndef COMPILE use pocketmine\utils\Binary; diff --git a/src/network/mcpe/protocol/types/MapDecoration.php b/src/network/mcpe/protocol/types/MapDecoration.php index 564cdf4bf6..7cf2dbde25 100644 --- a/src/network/mcpe/protocol/types/MapDecoration.php +++ b/src/network/mcpe/protocol/types/MapDecoration.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types; -use pocketmine\utils\Color; +use pocketmine\color\Color; class MapDecoration{ /** @var int */ diff --git a/src/utils/Color.php b/src/utils/Color.php deleted file mode 100644 index 047b709e6d..0000000000 --- a/src/utils/Color.php +++ /dev/null @@ -1,130 +0,0 @@ -r = $r & 0xff; - $this->g = $g & 0xff; - $this->b = $b & 0xff; - $this->a = $a & 0xff; - } - - /** - * Returns the alpha (opacity) value of this colour. - */ - public function getA() : int{ - return $this->a; - } - - /** - * Retuns the red value of this colour. - */ - public function getR() : int{ - return $this->r; - } - - /** - * Returns the green value of this colour. - */ - public function getG() : int{ - return $this->g; - } - - /** - * Returns the blue value of this colour. - */ - public function getB() : int{ - return $this->b; - } - - /** - * Mixes the supplied list of colours together to produce a result colour. - * - * @param Color ...$colors - */ - public static function mix(Color $color1, Color ...$colors) : Color{ - $colors[] = $color1; - $count = count($colors); - - $a = $r = $g = $b = 0; - - foreach($colors as $color){ - $a += $color->a; - $r += $color->r; - $g += $color->g; - $b += $color->b; - } - - return new Color(intdiv($r, $count), intdiv($g, $count), intdiv($b, $count), intdiv($a, $count)); - } - - /** - * Returns a Color from the supplied RGB colour code (24-bit) - */ - public static function fromRGB(int $code) : Color{ - return new Color(($code >> 16) & 0xff, ($code >> 8) & 0xff, $code & 0xff); - } - - /** - * Returns a Color from the supplied ARGB colour code (32-bit) - */ - public static function fromARGB(int $code) : Color{ - return new Color(($code >> 16) & 0xff, ($code >> 8) & 0xff, $code & 0xff, ($code >> 24) & 0xff); - } - - /** - * Returns an ARGB 32-bit colour value. - */ - public function toARGB() : int{ - return ($this->a << 24) | ($this->r << 16) | ($this->g << 8) | $this->b; - } - - /** - * Returns a Color from the supplied RGBA colour code (32-bit) - */ - public static function fromRGBA(int $c) : Color{ - return new Color(($c >> 24) & 0xff, ($c >> 16) & 0xff, ($c >> 8) & 0xff, $c & 0xff); - } - - /** - * Returns an RGBA 32-bit colour value. - */ - public function toRGBA() : int{ - return ($this->r << 24) | ($this->g << 16) | ($this->b << 8) | $this->a; - } -} diff --git a/src/world/particle/DustParticle.php b/src/world/particle/DustParticle.php index de9aa13359..27a7d742fd 100644 --- a/src/world/particle/DustParticle.php +++ b/src/world/particle/DustParticle.php @@ -23,10 +23,10 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\color\Color; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -use pocketmine\utils\Color; class DustParticle implements Particle{ /** @var Color */ diff --git a/src/world/particle/InstantEnchantParticle.php b/src/world/particle/InstantEnchantParticle.php index 1f48004e6d..17156d1ef9 100644 --- a/src/world/particle/InstantEnchantParticle.php +++ b/src/world/particle/InstantEnchantParticle.php @@ -23,10 +23,10 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\color\Color; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; -use pocketmine\utils\Color; class InstantEnchantParticle implements Particle{ /** @var Color */ diff --git a/src/world/particle/PotionSplashParticle.php b/src/world/particle/PotionSplashParticle.php index 89f9cf047e..6c7fc67c33 100644 --- a/src/world/particle/PotionSplashParticle.php +++ b/src/world/particle/PotionSplashParticle.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace pocketmine\world\particle; +use pocketmine\color\Color; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; -use pocketmine\utils\Color; class PotionSplashParticle implements Particle{ From 31e4fc6fcb50a3e0587de18b67a82b7177a16121 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 15 May 2020 10:55:29 +0100 Subject: [PATCH 1564/3224] fixing incompatible protocol handling, do not explode immediately on bad clientdata, login encode/decode is now symmetrical --- .../mcpe/handler/LoginPacketHandler.php | 83 +++++++++++++++-- src/network/mcpe/protocol/LoginPacket.php | 91 +++++-------------- 2 files changed, 101 insertions(+), 73 deletions(-) diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index efd3e4d9ae..3606152f81 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -28,12 +28,17 @@ use pocketmine\event\player\PlayerPreLoginEvent; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\auth\ProcessLoginTask; use pocketmine\network\mcpe\convert\SkinAdapterSingleton; +use pocketmine\network\mcpe\JwtException; +use pocketmine\network\mcpe\JwtUtils; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\LoginPacket; use pocketmine\network\mcpe\protocol\PlayStatusPacket; use pocketmine\network\mcpe\protocol\ProtocolInfo; +use pocketmine\network\mcpe\protocol\types\login\AuthenticationData; +use pocketmine\network\mcpe\protocol\types\login\ClientData; use pocketmine\network\mcpe\protocol\types\login\ClientDataPersonaPieceTintColor; use pocketmine\network\mcpe\protocol\types\login\ClientDataPersonaSkinPiece; +use pocketmine\network\mcpe\protocol\types\login\JwtChain; use pocketmine\network\mcpe\protocol\types\PersonaPieceTintColor; use pocketmine\network\mcpe\protocol\types\PersonaSkinPiece; use pocketmine\network\mcpe\protocol\types\SkinAnimation; @@ -45,6 +50,7 @@ use pocketmine\Server; use pocketmine\uuid\UUID; use function array_map; use function base64_decode; +use function is_array; /** * Handles the initial login phase of the session. This handler is used as the initial state. @@ -94,12 +100,15 @@ class LoginPacketHandler extends PacketHandler{ return true; } - if(!Player::isValidUserName($packet->extraData->displayName)){ + $extraData = $this->fetchAuthData($packet->chainDataJwt); + + if(!Player::isValidUserName($extraData->displayName)){ $this->session->disconnect("disconnectionScreen.invalidName"); return true; } + $clientData = $this->parseClientData($packet->clientDataJwt); $safeB64Decode = static function(string $base64, string $context) : string{ $result = base64_decode($base64, true); if($result === false){ @@ -108,7 +117,6 @@ class LoginPacketHandler extends PacketHandler{ return $result; }; try{ - $clientData = $packet->clientData; //this serves no purpose except readability /** @var SkinAnimation[] $animations */ $animations = []; foreach($clientData->AnimatedImageData as $k => $animation){ @@ -154,17 +162,17 @@ class LoginPacketHandler extends PacketHandler{ } try{ - $uuid = UUID::fromString($packet->extraData->identity); + $uuid = UUID::fromString($extraData->identity); }catch(\InvalidArgumentException $e){ throw BadPacketException::wrap($e, "Failed to parse login UUID"); } ($this->playerInfoConsumer)(new PlayerInfo( - $packet->extraData->displayName, + $extraData->displayName, $uuid, $skin, - $packet->clientData->LanguageCode, - $packet->extraData->XUID, - (array) $packet->clientData + $clientData->LanguageCode, + $extraData->XUID, + (array) $clientData )); $ev = new PlayerPreLoginEvent( @@ -194,6 +202,67 @@ class LoginPacketHandler extends PacketHandler{ return true; } + /** + * @throws BadPacketException + */ + protected function fetchAuthData(JwtChain $chain) : AuthenticationData{ + /** @var AuthenticationData|null $extraData */ + $extraData = null; + foreach($chain->chain as $k => $chain){ + //validate every chain element + try{ + [, $claims, ] = JwtUtils::parse($chain); + }catch(JwtException $e){ + throw BadPacketException::wrap($e); + } + if(isset($claims["extraData"])){ + if($extraData !== null){ + throw new BadPacketException("Found 'extraData' more than once in chainData"); + } + + if(!is_array($claims["extraData"])){ + throw new BadPacketException("'extraData' key should be an array"); + } + $mapper = new \JsonMapper; + $mapper->bEnforceMapType = false; //TODO: we don't really need this as an array, but right now we don't have enough models + $mapper->bExceptionOnMissingData = true; + $mapper->bExceptionOnUndefinedProperty = true; + try{ + /** @var AuthenticationData $extraData */ + $extraData = $mapper->map($claims['extraData'], new AuthenticationData); + }catch(\JsonMapper_Exception $e){ + throw BadPacketException::wrap($e); + } + } + } + if($extraData === null){ + throw new BadPacketException("'extraData' not found in chain data"); + } + return $extraData; + } + + /** + * @throws BadPacketException + */ + protected function parseClientData(string $clientDataJwt) : ClientData{ + try{ + [, $clientDataClaims, ] = JwtUtils::parse($clientDataJwt); + }catch(JwtException $e){ + throw BadPacketException::wrap($e); + } + + $mapper = new \JsonMapper; + $mapper->bEnforceMapType = false; //TODO: we don't really need this as an array, but right now we don't have enough models + $mapper->bExceptionOnMissingData = true; + $mapper->bExceptionOnUndefinedProperty = true; + try{ + $clientData = $mapper->map($clientDataClaims, new ClientData); + }catch(\JsonMapper_Exception $e){ + throw BadPacketException::wrap($e); + } + return $clientData; + } + /** * TODO: This is separated for the purposes of allowing plugins (like Specter) to hack it and bypass authentication. * In the future this won't be necessary. diff --git a/src/network/mcpe/protocol/LoginPacket.php b/src/network/mcpe/protocol/LoginPacket.php index c018f65821..35e8387452 100644 --- a/src/network/mcpe/protocol/LoginPacket.php +++ b/src/network/mcpe/protocol/LoginPacket.php @@ -25,18 +25,14 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\JwtException; -use pocketmine\network\mcpe\JwtUtils; use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; -use pocketmine\network\mcpe\protocol\types\login\AuthenticationData; -use pocketmine\network\mcpe\protocol\types\login\ClientData; use pocketmine\network\mcpe\protocol\types\login\JwtChain; -use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; -use function is_array; use function is_object; use function json_decode; +use function json_encode; use function json_last_error_msg; +use function strlen; class LoginPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::LOGIN_PACKET; @@ -48,12 +44,8 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ /** @var JwtChain */ public $chainDataJwt; - /** @var AuthenticationData|null extraData index of whichever JWT has it */ - public $extraData = null; /** @var string */ public $clientDataJwt; - /** @var ClientData decoded payload of the clientData JWT */ - public $clientData; public function canBeSentBeforeLogin() : bool{ return true; @@ -61,17 +53,13 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ protected function decodePayload(NetworkBinaryStream $in) : void{ $this->protocol = $in->getInt(); - $this->decodeConnectionRequest($in); + $this->decodeConnectionRequest($in->getString()); } - /** - * @throws PacketDecodeException - * @throws BinaryDataException - */ - protected function decodeConnectionRequest(NetworkBinaryStream $in) : void{ - $buffer = new BinaryStream($in->getString()); + protected function decodeConnectionRequest(string $binary) : void{ + $connRequestReader = new BinaryStream($binary); - $chainDataJson = json_decode($buffer->get($buffer->getLInt())); + $chainDataJson = json_decode($connRequestReader->get($connRequestReader->getLInt())); if(!is_object($chainDataJson)){ throw new PacketDecodeException("Failed decoding chain data JSON: " . json_last_error_msg()); } @@ -85,57 +73,28 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ } $this->chainDataJwt = $chainData; - - foreach($this->chainDataJwt->chain as $k => $chain){ - //validate every chain element - try{ - [, $claims, ] = JwtUtils::parse($chain); - }catch(JwtException $e){ - throw new PacketDecodeException($e->getMessage(), 0, $e); - } - if(isset($claims["extraData"])){ - if(!is_array($claims["extraData"])){ - throw new PacketDecodeException("'extraData' key should be an array"); - } - if($this->extraData !== null){ - throw new PacketDecodeException("Found 'extraData' more than once in chainData"); - } - - $mapper = new \JsonMapper; - $mapper->bEnforceMapType = false; //TODO: we don't really need this as an array, but right now we don't have enough models - $mapper->bExceptionOnMissingData = true; - $mapper->bExceptionOnUndefinedProperty = true; - try{ - $this->extraData = $mapper->map($claims['extraData'], new AuthenticationData); - }catch(\JsonMapper_Exception $e){ - throw PacketDecodeException::wrap($e); - } - } - } - if($this->extraData === null){ - throw new PacketDecodeException("'extraData' not found in chain data"); - } - - $this->clientDataJwt = $buffer->get($buffer->getLInt()); - try{ - [, $clientData, ] = JwtUtils::parse($this->clientDataJwt); - }catch(JwtException $e){ - throw new PacketDecodeException($e->getMessage(), 0, $e); - } - - $mapper = new \JsonMapper; - $mapper->bEnforceMapType = false; //TODO: we don't really need this as an array, but right now we don't have enough models - $mapper->bExceptionOnMissingData = true; - $mapper->bExceptionOnUndefinedProperty = true; - try{ - $this->clientData = $mapper->map($clientData, new ClientData); - }catch(\JsonMapper_Exception $e){ - throw PacketDecodeException::wrap($e); - } + $this->clientDataJwt = $connRequestReader->get($connRequestReader->getLInt()); } protected function encodePayload(NetworkBinaryStream $out) : void{ - //TODO + $out->putInt($this->protocol); + $out->putString($this->encodeConnectionRequest()); + } + + protected function encodeConnectionRequest() : string{ + $connRequestWriter = new BinaryStream(); + + $chainDataJson = json_encode($this->chainDataJwt); + if($chainDataJson === false){ + throw new \InvalidStateException("Failed to encode chain data JSON: " . json_last_error_msg()); + } + $connRequestWriter->putLInt(strlen($chainDataJson)); + $connRequestWriter->put($chainDataJson); + + $connRequestWriter->putLInt(strlen($this->clientDataJwt)); + $connRequestWriter->put($this->clientDataJwt); + + return $connRequestWriter->getBuffer(); } public function handle(PacketHandlerInterface $handler) : bool{ From 129a7c1b3e134459283468408c619acb2b398fa3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 15 May 2020 11:19:14 +0100 Subject: [PATCH 1565/3224] LoginPacketHandler: avoid trashing variables in foreach --- src/network/mcpe/handler/LoginPacketHandler.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index 3606152f81..e90e72ddef 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -208,10 +208,10 @@ class LoginPacketHandler extends PacketHandler{ protected function fetchAuthData(JwtChain $chain) : AuthenticationData{ /** @var AuthenticationData|null $extraData */ $extraData = null; - foreach($chain->chain as $k => $chain){ + foreach($chain->chain as $k => $jwt){ //validate every chain element try{ - [, $claims, ] = JwtUtils::parse($chain); + [, $claims, ] = JwtUtils::parse($jwt); }catch(JwtException $e){ throw BadPacketException::wrap($e); } From 3fb34ad18e7b3adab1f31b3b47c7cc914e8edf02 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 15 May 2020 22:57:38 +0100 Subject: [PATCH 1566/3224] remove particle/validator dependency, require respect/validation, close #3228 this fixes a few crashes that could appear from invalid plugin_list.yml setups, which was the reason #3228 was opened to begin with. Respect also has nicer error messages, as long as you don't use the static API :) --- composer.json | 4 +- composer.lock | 253 +++++++++++++++++++++++++--------- src/plugin/PluginGraylist.php | 32 +++-- 3 files changed, 209 insertions(+), 80 deletions(-) diff --git a/composer.json b/composer.json index 06b474b941..5b77fda8c2 100644 --- a/composer.json +++ b/composer.json @@ -45,9 +45,9 @@ "pocketmine/uuid": "^0.1.0", "pocketmine/color": "^0.1.0", "adhocore/json-comment": "^0.1.0", - "particle/validator": "^2.3", "netresearch/jsonmapper": "^2.0", - "ocramius/package-versions": "^1.5" + "ocramius/package-versions": "^1.5", + "respect/validation": "^2.0" }, "require-dev": { "phpstan/phpstan": "^0.12.25", diff --git a/composer.lock b/composer.lock index 4009aa716c..9c0ccda230 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4bd35ad045d13f81b88bef943137c79f", + "content-hash": "873133d73021dccbdf46b9ffac2e07a6", "packages": [ { "name": "adhocore/json-comment", @@ -288,68 +288,6 @@ "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", "time": "2019-07-17T15:49:50+00:00" }, - { - "name": "particle/validator", - "version": "v2.3.4", - "source": { - "type": "git", - "url": "https://github.com/particle-php/Validator.git", - "reference": "657c7543e51938dd9d114750e49d695129527a7a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/particle-php/Validator/zipball/657c7543e51938dd9d114750e49d695129527a7a", - "reference": "657c7543e51938dd9d114750e49d695129527a7a", - "shasum": "" - }, - "require": { - "php": ">=5.4" - }, - "require-dev": { - "byrokrat/checkdigit": "^1.0", - "giggsey/libphonenumber-for-php": "^7.2", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "2.*" - }, - "suggest": { - "byrokrat/checkdigit": "If you want to use CreditCard validation rule, this library must be installed.", - "giggsey/libphonenumber-for-php": "If you want to use Phone validation rule, this library must be installed." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "psr-4": { - "Particle\\Validator\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Berry Langerak", - "email": "berry@berryllium.nl", - "role": "Developer" - }, - { - "name": "Rick van der Staaij", - "homepage": "http://rickvanderstaaij.nl", - "role": "Developer" - } - ], - "description": "Flexible and highly usable validation library with no dependencies.", - "homepage": "http://github.com/particle-php/validator", - "keywords": [ - "validation", - "validator" - ], - "time": "2019-01-07T13:39:13+00:00" - }, { "name": "pocketmine/binaryutils", "version": "dev-master", @@ -820,6 +758,195 @@ ], "description": "Basic UUID implementation used by PocketMine-MP and related projects", "time": "2020-05-10T12:38:41+00:00" + }, + { + "name": "respect/stringifier", + "version": "0.2.0", + "source": { + "type": "git", + "url": "https://github.com/Respect/Stringifier.git", + "reference": "e55af3c8aeaeaa2abb5fa47a58a8e9688cc23b59" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Respect/Stringifier/zipball/e55af3c8aeaeaa2abb5fa47a58a8e9688cc23b59", + "reference": "e55af3c8aeaeaa2abb5fa47a58a8e9688cc23b59", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.8", + "malukenho/docheader": "^0.1.7", + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Respect\\Stringifier\\": "src/" + }, + "files": [ + "src/stringify.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Respect/Stringifier Contributors", + "homepage": "https://github.com/Respect/Stringifier/graphs/contributors" + } + ], + "description": "Converts any value to a string", + "homepage": "http://respect.github.io/Stringifier/", + "keywords": [ + "respect", + "stringifier", + "stringify" + ], + "time": "2017-12-29T19:39:25+00:00" + }, + { + "name": "respect/validation", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/Respect/Validation.git", + "reference": "3463343b14a7fa5ba931f03b5dcb8efcbc0ddf9c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Respect/Validation/zipball/3463343b14a7fa5ba931f03b5dcb8efcbc0ddf9c", + "reference": "3463343b14a7fa5ba931f03b5dcb8efcbc0ddf9c", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "respect/stringifier": "^0.2.0", + "symfony/polyfill-mbstring": "^1.2" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0", + "egulias/email-validator": "^2.1", + "malukenho/docheader": "^0.1", + "mikey179/vfsstream": "^1.6", + "phpstan/phpstan": "^0.11", + "phpstan/phpstan-deprecation-rules": "^0.11.0", + "phpstan/phpstan-phpunit": "^0.11.0", + "phpunit/phpunit": "^7.5", + "respect/coding-standard": "^1.0", + "squizlabs/php_codesniffer": "^3.5", + "symfony/validator": "^3.0||^4.0", + "zendframework/zend-validator": "^2.1" + }, + "suggest": { + "egulias/email-validator": "Strict (RFC compliant) email validation", + "ext-bcmath": "Arbitrary Precision Mathematics", + "ext-fileinfo": "File Information", + "ext-mbstring": "Multibyte String Functions", + "symfony/validator": "Use Symfony validator through Respect\\Validation", + "zendframework/zend-validator": "Use Zend Framework validator through Respect\\Validation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Respect\\Validation\\": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Respect/Validation Contributors", + "homepage": "https://github.com/Respect/Validation/graphs/contributors" + } + ], + "description": "The most awesome validation engine ever created for PHP", + "homepage": "http://respect.github.io/Validation/", + "keywords": [ + "respect", + "validation", + "validator" + ], + "time": "2020-05-13T16:41:55+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "fa79b11539418b02fc5e1897267673ba2c19419c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fa79b11539418b02fc5e1897267673ba2c19419c", + "reference": "fa79b11539418b02fc5e1897267673ba2c19419c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" } ], "packages-dev": [ diff --git a/src/plugin/PluginGraylist.php b/src/plugin/PluginGraylist.php index 8436ffc7f4..72cbbd4a25 100644 --- a/src/plugin/PluginGraylist.php +++ b/src/plugin/PluginGraylist.php @@ -23,11 +23,15 @@ declare(strict_types=1); namespace pocketmine\plugin; -use Particle\Validator\Validator; -use function array_filter; +use Respect\Validation\Exceptions\NestedValidationException; +use Respect\Validation\Rules\AllOf; +use Respect\Validation\Rules\ArrayType; +use Respect\Validation\Rules\Each; +use Respect\Validation\Rules\In; +use Respect\Validation\Rules\Key; +use Respect\Validation\Rules\StringType; +use Respect\Validation\Validator; use function array_flip; -use function count; -use function implode; class PluginGraylist{ @@ -66,17 +70,15 @@ class PluginGraylist{ * @param mixed[] $array */ public static function fromArray(array $array) : PluginGraylist{ - $v = new Validator(); - $v->required("mode")->inArray(['whitelist', 'blacklist'], true); - $v->required("plugins")->isArray()->allowEmpty(true)->callback(function(array $elements) : bool{ return count(array_filter($elements, '\is_string')) === count($elements); }); - - $result = $v->validate($array); - if($result->isNotValid()){ - $messages = []; - foreach($result->getFailures() as $f){ - $messages[] = $f->format(); - } - throw new \InvalidArgumentException("Invalid data: " . implode(", ", $messages)); + $validator = new Validator( + new Key("mode", new In(['whitelist', 'blacklist'], true), false), + new Key("plugins", new AllOf(new ArrayType(), new Each(new StringType())), false) + ); + $validator->setName('plugin_list.yml'); + try{ + $validator->assert($array); + }catch(NestedValidationException $e){ + throw new \InvalidArgumentException($e->getFullMessage(), 0, $e); } return new PluginGraylist($array["plugins"], $array["mode"] === 'whitelist'); } From 38e28f91e839414dc6c2cf5655a7b0178717c9de Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 16 May 2020 11:26:00 +0100 Subject: [PATCH 1567/3224] PermissionParser: move default string mappings to const array instead of switch this allows them to be used for validation in stuff like Respect In() rule. --- src/permission/PermissionParser.php | 43 +++++++++++++++-------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/permission/PermissionParser.php b/src/permission/PermissionParser.php index 1be4ee2a51..17cee102d2 100644 --- a/src/permission/PermissionParser.php +++ b/src/permission/PermissionParser.php @@ -31,6 +31,25 @@ use function strtolower; class PermissionParser{ + public const DEFAULT_STRING_MAP = [ + "op" => Permission::DEFAULT_OP, + "isop" => Permission::DEFAULT_OP, + "operator" => Permission::DEFAULT_OP, + "isoperator" => Permission::DEFAULT_OP, + "admin" => Permission::DEFAULT_OP, + "isadmin" => Permission::DEFAULT_OP, + + "!op" => Permission::DEFAULT_NOT_OP, + "notop" => Permission::DEFAULT_NOT_OP, + "!operator" => Permission::DEFAULT_NOT_OP, + "notoperator" => Permission::DEFAULT_NOT_OP, + "!admin" => Permission::DEFAULT_NOT_OP, + "notadmin" => Permission::DEFAULT_NOT_OP, + + "true" => Permission::DEFAULT_TRUE, + "false" => Permission::DEFAULT_FALSE, + ]; + /** * @param bool|string $value * @@ -44,27 +63,9 @@ class PermissionParser{ return "false"; } } - switch(strtolower($value)){ - case "op": - case "isop": - case "operator": - case "isoperator": - case "admin": - case "isadmin": - return Permission::DEFAULT_OP; - - case "!op": - case "notop": - case "!operator": - case "notoperator": - case "!admin": - case "notadmin": - return Permission::DEFAULT_NOT_OP; - - case "true": - return Permission::DEFAULT_TRUE; - case "false": - return Permission::DEFAULT_FALSE; + $lower = strtolower($value); + if(isset(self::DEFAULT_STRING_MAP[$lower])){ + return self::DEFAULT_STRING_MAP[$lower]; } throw new \InvalidArgumentException("Unknown permission default name \"$value\""); From 67666db827e2c85886b3edb880308d3d223ef451 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Sat, 16 May 2020 15:28:45 +0100 Subject: [PATCH 1568/3224] Task: Remove currentTick parameter (#3498) This parameter is not used for the vast majority of task use cases and just serves as extra useless boilerplate code, especially for closure-based tasks. This use case can be replaced using Server->getTick() in the cases where it matters. --- src/scheduler/CancellableClosureTask.php | 16 ++++++++-------- src/scheduler/ClosureTask.php | 16 ++++++++-------- src/scheduler/Task.php | 2 +- src/scheduler/TaskHandler.php | 4 ++-- src/scheduler/TaskScheduler.php | 2 +- .../TesterPlugin/CheckTestCompletionTask.php | 2 +- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/scheduler/CancellableClosureTask.php b/src/scheduler/CancellableClosureTask.php index 934edb9dd4..68d2fa946c 100644 --- a/src/scheduler/CancellableClosureTask.php +++ b/src/scheduler/CancellableClosureTask.php @@ -32,8 +32,8 @@ use pocketmine\utils\Utils; * Example usage: * * ``` - * TaskScheduler->scheduleTask(new CancellableClosureTask(function(int $currentTick) : bool{ - * echo "HI on $currentTick\n"; + * TaskScheduler->scheduleTask(new CancellableClosureTask(function() : bool{ + * echo "HI\n"; * $continue = false; * return $continue; //stop repeating * }); @@ -47,20 +47,20 @@ class CancellableClosureTask extends Task{ /** * @var \Closure - * @phpstan-var \Closure(int $currentTick) : bool + * @phpstan-var \Closure() : bool */ private $closure; /** * CancellableClosureTask constructor. * - * The closure should follow the signature callback(int $currentTick) : bool. The return value will be used to + * The closure should follow the signature callback() : bool. The return value will be used to * decide whether to continue repeating. * - * @phpstan-param \Closure(int $currentTick) : bool $closure + * @phpstan-param \Closure() : bool $closure */ public function __construct(\Closure $closure){ - Utils::validateCallableSignature(function(int $currentTick) : bool{ return false; }, $closure); + Utils::validateCallableSignature(function() : bool{ return false; }, $closure); $this->closure = $closure; } @@ -68,8 +68,8 @@ class CancellableClosureTask extends Task{ return Utils::getNiceClosureName($this->closure); } - public function onRun(int $currentTick) : void{ - if(!($this->closure)($currentTick)){ + public function onRun() : void{ + if(!($this->closure)()){ $this->getHandler()->cancel(); } } diff --git a/src/scheduler/ClosureTask.php b/src/scheduler/ClosureTask.php index 2a9996de19..45e30212ed 100644 --- a/src/scheduler/ClosureTask.php +++ b/src/scheduler/ClosureTask.php @@ -31,8 +31,8 @@ use pocketmine\utils\Utils; * Example usage: * * ``` - * TaskScheduler->scheduleTask(new ClosureTask(function(int $currentTick) : void{ - * echo "HI on $currentTick\n"; + * TaskScheduler->scheduleTask(new ClosureTask(function() : void{ + * echo "HI\n"; * }); * ``` */ @@ -40,16 +40,16 @@ class ClosureTask extends Task{ /** * @var \Closure - * @phpstan-var \Closure(int) : void + * @phpstan-var \Closure() : void */ private $closure; /** - * @param \Closure $closure Must accept only ONE parameter, $currentTick - * @phpstan-param \Closure(int) : void $closure + * @param \Closure $closure Must accept zero parameters + * @phpstan-param \Closure() : void $closure */ public function __construct(\Closure $closure){ - Utils::validateCallableSignature(function(int $currentTick) : void{}, $closure); + Utils::validateCallableSignature(function() : void{}, $closure); $this->closure = $closure; } @@ -57,7 +57,7 @@ class ClosureTask extends Task{ return Utils::getNiceClosureName($this->closure); } - public function onRun(int $currentTick) : void{ - ($this->closure)($currentTick); + public function onRun() : void{ + ($this->closure)(); } } diff --git a/src/scheduler/Task.php b/src/scheduler/Task.php index 72a0b237cc..9d3e5a6fe0 100644 --- a/src/scheduler/Task.php +++ b/src/scheduler/Task.php @@ -60,7 +60,7 @@ abstract class Task{ * * @return void */ - abstract public function onRun(int $currentTick); + abstract public function onRun(); /** * Actions to execute if the Task is cancelled diff --git a/src/scheduler/TaskHandler.php b/src/scheduler/TaskHandler.php index 69159b3714..986b8005e1 100644 --- a/src/scheduler/TaskHandler.php +++ b/src/scheduler/TaskHandler.php @@ -116,10 +116,10 @@ class TaskHandler{ $this->task->setHandler(null); } - public function run(int $currentTick) : void{ + public function run() : void{ $this->timings->startTiming(); try{ - $this->task->onRun($currentTick); + $this->task->onRun(); }finally{ $this->timings->stopTiming(); } diff --git a/src/scheduler/TaskScheduler.php b/src/scheduler/TaskScheduler.php index 55b70de0bb..2786bc4179 100644 --- a/src/scheduler/TaskScheduler.php +++ b/src/scheduler/TaskScheduler.php @@ -147,7 +147,7 @@ class TaskScheduler{ unset($this->tasks[$task->getTaskId()]); continue; } - $task->run($this->currentTick); + $task->run(); if($task->isRepeating()){ $task->setNextRun($this->currentTick + $task->getPeriod()); $this->queue->insert($task, $this->currentTick + $task->getPeriod()); diff --git a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/CheckTestCompletionTask.php b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/CheckTestCompletionTask.php index dc65a9a72a..49ee205b0c 100644 --- a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/CheckTestCompletionTask.php +++ b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/CheckTestCompletionTask.php @@ -34,7 +34,7 @@ class CheckTestCompletionTask extends Task{ $this->plugin = $plugin; } - public function onRun(int $currentTick){ + public function onRun(){ $test = $this->plugin->getCurrentTest(); if($test === null){ if(!$this->plugin->startNextTest()){ From c30dd9f1b67999c45802f2c73bdc8ee667038a77 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 16 May 2020 16:08:12 +0100 Subject: [PATCH 1569/3224] Entity: add abstract getNetworkTypeId(), remove NETWORK_ID constant this now requires that subclasses supply a proper NETWORK_ID. --- src/entity/Entity.php | 6 +++--- src/entity/Human.php | 4 ++++ src/entity/Squid.php | 3 ++- src/entity/Villager.php | 2 +- src/entity/Zombie.php | 3 ++- src/entity/object/ExperienceOrb.php | 4 +++- src/entity/object/FallingBlock.php | 3 ++- src/entity/object/ItemEntity.php | 3 ++- src/entity/object/Painting.php | 2 +- src/entity/object/PrimedTNT.php | 3 ++- src/entity/projectile/Arrow.php | 3 ++- src/entity/projectile/Egg.php | 2 +- src/entity/projectile/EnderPearl.php | 2 +- src/entity/projectile/ExperienceBottle.php | 2 +- src/entity/projectile/Snowball.php | 2 +- src/entity/projectile/SplashPotion.php | 2 +- src/item/ItemFactory.php | 4 ++-- src/world/sound/EntityLandSound.php | 2 +- src/world/sound/EntityLongFallSound.php | 2 +- src/world/sound/EntityShortFallSound.php | 2 +- tests/phpstan/configs/phpstan-bugs.neon | 10 ---------- 21 files changed, 34 insertions(+), 32 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index ba098ed276..29113e2094 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -80,8 +80,6 @@ abstract class Entity{ public const MOTION_THRESHOLD = 0.00001; - public const NETWORK_ID = -1; - /** @var Player[] */ protected $hasSpawned = []; @@ -1506,13 +1504,15 @@ abstract class Entity{ return $this->hasSpawned; } + abstract public static function getNetworkTypeId() : int; + /** * Called by spawnTo() to send whatever packets needed to spawn the entity to the client. */ protected function sendSpawnPacket(Player $player) : void{ $pk = new AddActorPacket(); $pk->entityRuntimeId = $this->getId(); - $pk->type = LegacyEntityIdToStringIdMap::getInstance()->legacyToString(static::NETWORK_ID); + $pk->type = LegacyEntityIdToStringIdMap::getInstance()->legacyToString(static::getNetworkTypeId()); $pk->position = $this->location->asVector3(); $pk->motion = $this->getMotion(); $pk->yaw = $this->location->yaw; diff --git a/src/entity/Human.php b/src/entity/Human.php index 55518fcf4c..36762dcdf0 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -66,6 +66,10 @@ use function strlen; class Human extends Living implements ProjectileSource, InventoryHolder{ + public static function getNetworkTypeId() : int{ + return -1; //TODO: ideally we shouldn't have to specify this at all here ... + } + /** @var PlayerInventory */ protected $inventory; diff --git a/src/entity/Squid.php b/src/entity/Squid.php index 29fe795e7a..a2bed5329c 100644 --- a/src/entity/Squid.php +++ b/src/entity/Squid.php @@ -36,7 +36,8 @@ use function sqrt; use const M_PI; class Squid extends WaterAnimal{ - public const NETWORK_ID = EntityLegacyIds::SQUID; + + public static function getNetworkTypeId() : int{ return EntityLegacyIds::SQUID; } public $width = 0.95; public $height = 0.95; diff --git a/src/entity/Villager.php b/src/entity/Villager.php index b76ff57fd1..e784d0c57d 100644 --- a/src/entity/Villager.php +++ b/src/entity/Villager.php @@ -35,7 +35,7 @@ class Villager extends Living implements Ageable{ public const PROFESSION_BLACKSMITH = 3; public const PROFESSION_BUTCHER = 4; - public const NETWORK_ID = EntityLegacyIds::VILLAGER; + public static function getNetworkTypeId() : int{ return EntityLegacyIds::VILLAGER; } public $width = 0.6; public $height = 1.8; diff --git a/src/entity/Zombie.php b/src/entity/Zombie.php index a33b191d77..307d9d5744 100644 --- a/src/entity/Zombie.php +++ b/src/entity/Zombie.php @@ -28,7 +28,8 @@ use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use function mt_rand; class Zombie extends Living{ - public const NETWORK_ID = EntityLegacyIds::ZOMBIE; + + public static function getNetworkTypeId() : int{ return EntityLegacyIds::ZOMBIE; } public $width = 0.6; public $height = 1.8; diff --git a/src/entity/object/ExperienceOrb.php b/src/entity/object/ExperienceOrb.php index c872177955..3ae1888b31 100644 --- a/src/entity/object/ExperienceOrb.php +++ b/src/entity/object/ExperienceOrb.php @@ -31,10 +31,12 @@ use pocketmine\nbt\tag\ShortTag; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\player\Player; +use function realpath; use function sqrt; class ExperienceOrb extends Entity{ - public const NETWORK_ID = EntityLegacyIds::XP_ORB; + + public static function getNetworkTypeId() : int{ return EntityLegacyIds::XP_ORB; } public const TAG_VALUE_PC = "Value"; //short public const TAG_VALUE_PE = "experience value"; //int (WTF?) diff --git a/src/entity/object/FallingBlock.php b/src/entity/object/FallingBlock.php index 20c7403b15..94e85cf389 100644 --- a/src/entity/object/FallingBlock.php +++ b/src/entity/object/FallingBlock.php @@ -38,7 +38,8 @@ use function abs; use function get_class; class FallingBlock extends Entity{ - public const NETWORK_ID = EntityLegacyIds::FALLING_BLOCK; + + public static function getNetworkTypeId() : int{ return EntityLegacyIds::FALLING_BLOCK; } public $width = 0.98; public $height = 0.98; diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index e4550c6994..d933e978d8 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -37,7 +37,8 @@ use function get_class; use function max; class ItemEntity extends Entity{ - public const NETWORK_ID = EntityLegacyIds::ITEM; + + public static function getNetworkTypeId() : int{ return EntityLegacyIds::ITEM; } public const DEFAULT_DESPAWN_DELAY = 6000; //5 minutes public const NEVER_DESPAWN = -1; diff --git a/src/entity/object/Painting.php b/src/entity/object/Painting.php index 7a5e341029..f2d9f21e68 100644 --- a/src/entity/object/Painting.php +++ b/src/entity/object/Painting.php @@ -40,7 +40,7 @@ use pocketmine\world\World; use function ceil; class Painting extends Entity{ - public const NETWORK_ID = EntityLegacyIds::PAINTING; + public static function getNetworkTypeId() : int{ return EntityLegacyIds::PAINTING; } private const DATA_TO_FACING = [ 0 => Facing::SOUTH, diff --git a/src/entity/object/PrimedTNT.php b/src/entity/object/PrimedTNT.php index e6d72c0399..da6019b161 100644 --- a/src/entity/object/PrimedTNT.php +++ b/src/entity/object/PrimedTNT.php @@ -36,7 +36,8 @@ use pocketmine\world\Position; use pocketmine\world\sound\IgniteSound; class PrimedTNT extends Entity implements Explosive{ - public const NETWORK_ID = EntityLegacyIds::TNT; + + public static function getNetworkTypeId() : int{ return EntityLegacyIds::TNT; } public $width = 0.98; public $height = 0.98; diff --git a/src/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php index cbf1e5ba79..bfddc295bc 100644 --- a/src/entity/projectile/Arrow.php +++ b/src/entity/projectile/Arrow.php @@ -40,7 +40,8 @@ use function mt_rand; use function sqrt; class Arrow extends Projectile{ - public const NETWORK_ID = EntityLegacyIds::ARROW; + + public static function getNetworkTypeId() : int{ return EntityLegacyIds::ARROW; } public const PICKUP_NONE = 0; public const PICKUP_ANY = 1; diff --git a/src/entity/projectile/Egg.php b/src/entity/projectile/Egg.php index d16f11d9c6..a2ccbb41aa 100644 --- a/src/entity/projectile/Egg.php +++ b/src/entity/projectile/Egg.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\world\particle\ItemBreakParticle; class Egg extends Throwable{ - public const NETWORK_ID = EntityLegacyIds::EGG; + public static function getNetworkTypeId() : int{ return EntityLegacyIds::EGG; } //TODO: spawn chickens on collision diff --git a/src/entity/projectile/EnderPearl.php b/src/entity/projectile/EnderPearl.php index 9d41d255ae..3789525215 100644 --- a/src/entity/projectile/EnderPearl.php +++ b/src/entity/projectile/EnderPearl.php @@ -30,7 +30,7 @@ use pocketmine\world\particle\EndermanTeleportParticle; use pocketmine\world\sound\EndermanTeleportSound; class EnderPearl extends Throwable{ - public const NETWORK_ID = EntityLegacyIds::ENDER_PEARL; + public static function getNetworkTypeId() : int{ return EntityLegacyIds::ENDER_PEARL; } protected function onHit(ProjectileHitEvent $event) : void{ $owner = $this->getOwningEntity(); diff --git a/src/entity/projectile/ExperienceBottle.php b/src/entity/projectile/ExperienceBottle.php index fbb3666bf8..0c787a04e0 100644 --- a/src/entity/projectile/ExperienceBottle.php +++ b/src/entity/projectile/ExperienceBottle.php @@ -30,7 +30,7 @@ use pocketmine\world\sound\PotionSplashSound; use function mt_rand; class ExperienceBottle extends Throwable{ - public const NETWORK_ID = EntityLegacyIds::XP_BOTTLE; + public static function getNetworkTypeId() : int{ return EntityLegacyIds::XP_BOTTLE; } protected $gravity = 0.07; diff --git a/src/entity/projectile/Snowball.php b/src/entity/projectile/Snowball.php index 88fcc42234..b758505b6e 100644 --- a/src/entity/projectile/Snowball.php +++ b/src/entity/projectile/Snowball.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\world\particle\SnowballPoofParticle; class Snowball extends Throwable{ - public const NETWORK_ID = EntityLegacyIds::SNOWBALL; + public static function getNetworkTypeId() : int{ return EntityLegacyIds::SNOWBALL; } protected function onHit(ProjectileHitEvent $event) : void{ for($i = 0; $i < 6; ++$i){ diff --git a/src/entity/projectile/SplashPotion.php b/src/entity/projectile/SplashPotion.php index 20a087dee9..168dac90a0 100644 --- a/src/entity/projectile/SplashPotion.php +++ b/src/entity/projectile/SplashPotion.php @@ -45,7 +45,7 @@ use function sqrt; class SplashPotion extends Throwable{ - public const NETWORK_ID = EntityLegacyIds::SPLASH_POTION; + public static function getNetworkTypeId() : int{ return EntityLegacyIds::SPLASH_POTION; } protected $gravity = 0.05; protected $drag = 0.01; diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index e197fe24ba..c42b825a81 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -252,8 +252,8 @@ class ItemFactory{ foreach(EntityFactory::getInstance()->getKnownTypes() as $className){ /** @var Living|string $className */ - if(is_a($className, Living::class, true) and $className::NETWORK_ID !== -1){ - $this->register(new SpawnEgg(ItemIds::SPAWN_EGG, $className::NETWORK_ID, "Spawn Egg", $className)); + if(is_a($className, Living::class, true) and $className::getNetworkTypeId() !== -1){ + $this->register(new SpawnEgg(ItemIds::SPAWN_EGG, $className::getNetworkTypeId(), "Spawn Egg", $className)); } } diff --git a/src/world/sound/EntityLandSound.php b/src/world/sound/EntityLandSound.php index ddd4c00ff5..c163c07f13 100644 --- a/src/world/sound/EntityLandSound.php +++ b/src/world/sound/EntityLandSound.php @@ -50,7 +50,7 @@ class EntityLandSound implements Sound{ LevelSoundEventPacket::SOUND_LAND, $pos, $this->blockLandedOn->getRuntimeId(), - $this->entity instanceof Player ? "minecraft:player" : LegacyEntityIdToStringIdMap::getInstance()->legacyToString($this->entity::NETWORK_ID) //TODO: bad hack, stuff depends on players having a -1 network ID :( + $this->entity instanceof Player ? "minecraft:player" : LegacyEntityIdToStringIdMap::getInstance()->legacyToString($this->entity::getNetworkTypeId()) //TODO: bad hack, stuff depends on players having a -1 network ID :( //TODO: does isBaby have any relevance here? ); } diff --git a/src/world/sound/EntityLongFallSound.php b/src/world/sound/EntityLongFallSound.php index d6f75b4598..896cc8f0be 100644 --- a/src/world/sound/EntityLongFallSound.php +++ b/src/world/sound/EntityLongFallSound.php @@ -47,7 +47,7 @@ class EntityLongFallSound implements Sound{ LevelSoundEventPacket::SOUND_FALL_BIG, $pos, -1, - $this->entity instanceof Player ? "minecraft:player" : LegacyEntityIdToStringIdMap::getInstance()->legacyToString($this->entity::NETWORK_ID) //TODO: bad hack, stuff depends on players having a -1 network ID :( + $this->entity instanceof Player ? "minecraft:player" : LegacyEntityIdToStringIdMap::getInstance()->legacyToString($this->entity::getNetworkTypeId()) //TODO: bad hack, stuff depends on players having a -1 network ID :( //TODO: is isBaby relevant here? ); } diff --git a/src/world/sound/EntityShortFallSound.php b/src/world/sound/EntityShortFallSound.php index 9c743f4c92..ff1f1bbb1b 100644 --- a/src/world/sound/EntityShortFallSound.php +++ b/src/world/sound/EntityShortFallSound.php @@ -46,7 +46,7 @@ class EntityShortFallSound implements Sound{ LevelSoundEventPacket::SOUND_FALL_SMALL, $pos, -1, - $this->entity instanceof Player ? "minecraft:player" : LegacyEntityIdToStringIdMap::getInstance()->legacyToString($this->entity::NETWORK_ID) //TODO: bad hack, stuff depends on players having a -1 network ID :( + $this->entity instanceof Player ? "minecraft:player" : LegacyEntityIdToStringIdMap::getInstance()->legacyToString($this->entity::getNetworkTypeId()) //TODO: bad hack, stuff depends on players having a -1 network ID :( //TODO: does isBaby have any relevance here? ); } diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index bd2169ecf2..7d4858d656 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -30,16 +30,6 @@ parameters: count: 1 path: ../../../src/entity/projectile/Projectile.php - - - message: "#^If condition is always false\\.$#" - count: 1 - path: ../../../src/item/ItemFactory.php - - - - message: "#^Strict comparison using \\!\\=\\= between \\-1 and \\-1 will always evaluate to false\\.$#" - count: 1 - path: ../../../src/item/ItemFactory.php - - message: "#^If condition is always false\\.$#" count: 1 From 82d361d75f319eeb07cc303a755f777b533d9885 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 16 May 2020 17:36:22 +0100 Subject: [PATCH 1570/3224] extract a BiomeArray unit from Chunk this now also properly validates data read from disk. --- src/world/format/BiomeArray.php | 67 +++++++++++++++++++ src/world/format/Chunk.php | 17 ++--- src/world/format/io/FastChunkSerializer.php | 5 +- src/world/format/io/leveldb/LevelDB.php | 11 +-- .../io/region/LegacyAnvilChunkTrait.php | 18 +++-- src/world/format/io/region/McRegion.php | 15 +++-- 6 files changed, 107 insertions(+), 26 deletions(-) create mode 100644 src/world/format/BiomeArray.php diff --git a/src/world/format/BiomeArray.php b/src/world/format/BiomeArray.php new file mode 100644 index 0000000000..4e0734611b --- /dev/null +++ b/src/world/format/BiomeArray.php @@ -0,0 +1,67 @@ +payload = $payload; + } + + private static function idx(int $x, int $z) : int{ + if($x >= 16 or $z >= 16){ + throw new \InvalidArgumentException("x and z must be in the range 0-15"); + } + return ($z << 4) | $x; + } + + public function get(int $x, int $z) : int{ + return ord($this->payload[self::idx($x, $z)]); + } + + public function set(int $x, int $z, int $biomeId) : void{ + if($biomeId < 0 or $biomeId >= 256){ + throw new \InvalidArgumentException("Biome ID must be in the range 0-255"); + } + $this->payload[self::idx($x, $z)] = chr($biomeId); + } + + /** + * @return string ZZZZXXXX key bits + */ + public function getData() : string{ + return $this->payload; + } +} diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 1a07af6bc4..a0b9e651a3 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -87,7 +87,7 @@ class Chunk{ */ protected $heightMap; - /** @var string */ + /** @var BiomeArray */ protected $biomeIds; /** @var CompoundTag[]|null */ @@ -102,7 +102,7 @@ class Chunk{ * @param CompoundTag[] $tiles * @param int[] $heightMap */ - public function __construct(int $chunkX, int $chunkZ, array $subChunks = [], ?array $entities = null, ?array $tiles = null, string $biomeIds = "", array $heightMap = []){ + public function __construct(int $chunkX, int $chunkZ, array $subChunks = [], ?array $entities = null, ?array $tiles = null, ?BiomeArray $biomeIds = null, array $heightMap = []){ $this->x = $chunkX; $this->z = $chunkZ; @@ -120,12 +120,7 @@ class Chunk{ $this->heightMap = \SplFixedArray::fromArray(array_fill(0, 256, $val)); } - if(strlen($biomeIds) === 256){ - $this->biomeIds = $biomeIds; - }else{ - assert($biomeIds === "", "Wrong BiomeIds value count, expected 256, got " . strlen($biomeIds)); - $this->biomeIds = str_repeat("\x00", 256); - } + $this->biomeIds = $biomeIds ?? new BiomeArray(str_repeat("\x00", 256)); $this->NBTtiles = $tiles; $this->NBTentities = $entities; @@ -359,7 +354,7 @@ class Chunk{ * @return int 0-255 */ public function getBiomeId(int $x, int $z) : int{ - return ord($this->biomeIds[($z << 4) | $x]); + return $this->biomeIds->get($x, $z); } /** @@ -370,7 +365,7 @@ class Chunk{ * @param int $biomeId 0-255 */ public function setBiomeId(int $x, int $z, int $biomeId) : void{ - $this->biomeIds[($z << 4) | $x] = chr($biomeId & 0xff); + $this->biomeIds->set($x, $z, $biomeId); $this->dirtyFlags |= self::DIRTY_FLAG_BIOMES; } @@ -550,7 +545,7 @@ class Chunk{ } public function getBiomeIdArray() : string{ - return $this->biomeIds; + return $this->biomeIds->getData(); } /** diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index 76aa5b77e9..d2ff757558 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -25,6 +25,7 @@ namespace pocketmine\world\format\io; use pocketmine\block\BlockLegacyIds; use pocketmine\utils\BinaryStream; +use pocketmine\world\format\BiomeArray; use pocketmine\world\format\Chunk; use pocketmine\world\format\LightArray; use pocketmine\world\format\PalettedBlockArray; @@ -111,7 +112,7 @@ final class FastChunkSerializer{ $terrainGenerated = (bool) ($flags & 1); $subChunks = []; - $biomeIds = ""; + $biomeIds = null; $heightMap = []; if($terrainGenerated){ $count = $stream->getByte(); @@ -132,7 +133,7 @@ final class FastChunkSerializer{ ); } - $biomeIds = $stream->get(256); + $biomeIds = new BiomeArray($stream->get(256)); if($lightPopulated){ $heightMap = array_values(unpack("S*", $stream->get(512))); } diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 7bd49dac77..1aea0231d4 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -33,6 +33,7 @@ use pocketmine\utils\Binary; use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; use pocketmine\utils\Utils; +use pocketmine\world\format\BiomeArray; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\BaseWorldProvider; use pocketmine\world\format\io\ChunkUtils; @@ -232,8 +233,8 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ /** @var SubChunk[] $subChunks */ $subChunks = []; - /** @var string $biomeIds */ - $biomeIds = ""; + /** @var BiomeArray|null $biomeArray */ + $biomeArray = null; $chunkVersion = ord($this->db->get($index . self::TAG_VERSION)); $hasBeenUpgraded = $chunkVersion < self::CURRENT_LEVEL_CHUNK_VERSION; @@ -326,7 +327,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ try{ $binaryStream->get(512); //heightmap, discard it - $biomeIds = $binaryStream->get(256); + $biomeArray = new BiomeArray($binaryStream->get(256)); //never throws }catch(BinaryDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } @@ -360,7 +361,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ try{ $binaryStream->get(256); //heightmap, discard it - $biomeIds = ChunkUtils::convertBiomeColors(array_values(unpack("N*", $binaryStream->get(1024)))); + $biomeArray = new BiomeArray(ChunkUtils::convertBiomeColors(array_values(unpack("N*", $binaryStream->get(1024))))); //never throws }catch(BinaryDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } @@ -398,7 +399,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $subChunks, $entities, $tiles, - $biomeIds + $biomeArray ); //TODO: tile ticks, biome states (?) diff --git a/src/world/format/io/region/LegacyAnvilChunkTrait.php b/src/world/format/io/region/LegacyAnvilChunkTrait.php index 204edff3be..bc06f7ed0b 100644 --- a/src/world/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/world/format/io/region/LegacyAnvilChunkTrait.php @@ -25,9 +25,11 @@ namespace pocketmine\world\format\io\region; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NbtDataException; +use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntArrayTag; use pocketmine\nbt\tag\ListTag; +use pocketmine\world\format\BiomeArray; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\ChunkUtils; use pocketmine\world\format\io\exception\CorruptedChunkException; @@ -72,10 +74,18 @@ trait LegacyAnvilChunkTrait{ } } + $makeBiomeArray = function(string $biomeIds) : BiomeArray{ + try{ + return new BiomeArray($biomeIds); + }catch(\InvalidArgumentException $e){ + throw new CorruptedChunkException($e->getMessage(), 0, $e); + } + }; + $biomeArray = null; if($chunk->hasTag("BiomeColors", IntArrayTag::class)){ - $biomeIds = ChunkUtils::convertBiomeColors($chunk->getIntArray("BiomeColors")); //Convert back to original format - }else{ - $biomeIds = $chunk->getByteArray("Biomes", ""); + $biomeArray = $makeBiomeArray(ChunkUtils::convertBiomeColors($chunk->getIntArray("BiomeColors"))); //Convert back to original format + }elseif($chunk->hasTag("Biomes", ByteArrayTag::class)){ + $biomeArray = $makeBiomeArray($chunk->getByteArray("Biomes")); } $result = new Chunk( @@ -84,7 +94,7 @@ trait LegacyAnvilChunkTrait{ $subChunks, $chunk->hasTag("Entities", ListTag::class) ? self::getCompoundList("Entities", $chunk->getListTag("Entities")) : [], $chunk->hasTag("TileEntities", ListTag::class) ? self::getCompoundList("TileEntities", $chunk->getListTag("TileEntities")) : [], - $biomeIds + $biomeArray ); $result->setPopulated($chunk->getByte("TerrainPopulated", 0) !== 0); $result->setGenerated(); diff --git a/src/world/format/io/region/McRegion.php b/src/world/format/io/region/McRegion.php index 634edde903..f6de24ea42 100644 --- a/src/world/format/io/region/McRegion.php +++ b/src/world/format/io/region/McRegion.php @@ -29,6 +29,7 @@ use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\IntArrayTag; use pocketmine\nbt\tag\ListTag; +use pocketmine\world\format\BiomeArray; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\ChunkUtils; use pocketmine\world\format\io\exception\CorruptedChunkException; @@ -69,12 +70,18 @@ class McRegion extends RegionWorldProvider{ $subChunks[$y] = new SubChunk(BlockLegacyIds::AIR << 4, [SubChunkConverter::convertSubChunkFromLegacyColumn($fullIds, $fullData, $y)]); } + $makeBiomeArray = function(string $biomeIds) : BiomeArray{ + try{ + return new BiomeArray($biomeIds); + }catch(\InvalidArgumentException $e){ + throw new CorruptedChunkException($e->getMessage(), 0, $e); + } + }; + $biomeIds = null; if($chunk->hasTag("BiomeColors", IntArrayTag::class)){ - $biomeIds = ChunkUtils::convertBiomeColors($chunk->getIntArray("BiomeColors")); //Convert back to original format + $biomeIds = $makeBiomeArray(ChunkUtils::convertBiomeColors($chunk->getIntArray("BiomeColors"))); //Convert back to original format }elseif($chunk->hasTag("Biomes", ByteArrayTag::class)){ - $biomeIds = $chunk->getByteArray("Biomes"); - }else{ - $biomeIds = ""; + $biomeIds = $makeBiomeArray($chunk->getByteArray("Biomes")); } $result = new Chunk( From a31240f60b9411bcb064fef7212d699fbf403d28 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 16 May 2020 18:06:00 +0100 Subject: [PATCH 1571/3224] FastChunkSerializer: added constants for internal flags --- src/world/format/io/FastChunkSerializer.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index d2ff757558..e41776d323 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -41,6 +41,9 @@ use function unpack; * The serialization format **is not intended for permanent storage** and may change without warning. */ final class FastChunkSerializer{ + private const FLAG_GENERATED = 1 << 0; + private const FLAG_POPULATED = 1 << 1; + private const FLAG_HAS_LIGHT = 1 << 2; private function __construct(){ //NOOP @@ -60,7 +63,11 @@ final class FastChunkSerializer{ $stream = new BinaryStream(); $stream->putInt($chunk->getX()); $stream->putInt($chunk->getZ()); - $stream->putByte(($includeLight ? 4 : 0) | ($chunk->isPopulated() ? 2 : 0) | ($chunk->isGenerated() ? 1 : 0)); + $stream->putByte( + ($includeLight ? self::FLAG_HAS_LIGHT : 0) | + ($chunk->isPopulated() ? self::FLAG_POPULATED : 0) | + ($chunk->isGenerated() ? self::FLAG_GENERATED : 0) + ); if($chunk->isGenerated()){ //subchunks $subChunks = $chunk->getSubChunks(); @@ -107,9 +114,9 @@ final class FastChunkSerializer{ $x = $stream->getInt(); $z = $stream->getInt(); $flags = $stream->getByte(); - $lightPopulated = (bool) ($flags & 4); - $terrainPopulated = (bool) ($flags & 2); - $terrainGenerated = (bool) ($flags & 1); + $lightPopulated = (bool) ($flags & self::FLAG_HAS_LIGHT); + $terrainPopulated = (bool) ($flags & self::FLAG_POPULATED); + $terrainGenerated = (bool) ($flags & self::FLAG_GENERATED); $subChunks = []; $biomeIds = null; From 88715c7055fb30ad2290a98fcdf5e27239122f15 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 16 May 2020 18:41:27 +0100 Subject: [PATCH 1572/3224] extracted a HeightArray type from Chunk --- src/world/format/Chunk.php | 30 +++------ src/world/format/HeightArray.php | 73 +++++++++++++++++++++ src/world/format/io/FastChunkSerializer.php | 5 +- 3 files changed, 84 insertions(+), 24 deletions(-) create mode 100644 src/world/format/HeightArray.php diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index a0b9e651a3..9e02c6ea0c 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -81,10 +81,7 @@ class Chunk{ /** @var Entity[] */ protected $entities = []; - /** - * @var \SplFixedArray|int[] - * @phpstan-var \SplFixedArray - */ + /** @var HeightArray */ protected $heightMap; /** @var BiomeArray */ @@ -100,9 +97,8 @@ class Chunk{ * @param SubChunk[] $subChunks * @param CompoundTag[] $entities * @param CompoundTag[] $tiles - * @param int[] $heightMap */ - public function __construct(int $chunkX, int $chunkZ, array $subChunks = [], ?array $entities = null, ?array $tiles = null, ?BiomeArray $biomeIds = null, array $heightMap = []){ + public function __construct(int $chunkX, int $chunkZ, array $subChunks = [], ?array $entities = null, ?array $tiles = null, ?BiomeArray $biomeIds = null, ?HeightArray $heightMap = null){ $this->x = $chunkX; $this->z = $chunkZ; @@ -112,14 +108,8 @@ class Chunk{ $this->subChunks[$y] = $subChunks[$y] ?? new SubChunk(BlockLegacyIds::AIR << 4, []); } - if(count($heightMap) === 256){ - $this->heightMap = \SplFixedArray::fromArray($heightMap); - }else{ - assert(count($heightMap) === 0, "Wrong HeightMap value count, expected 256, got " . count($heightMap)); - $val = ($this->subChunks->getSize() * 16); - $this->heightMap = \SplFixedArray::fromArray(array_fill(0, 256, $val)); - } - + $val = ($this->subChunks->getSize() * 16); + $this->heightMap = $heightMap ?? new HeightArray(array_fill(0, 256, $val)); $this->biomeIds = $biomeIds ?? new BiomeArray(str_repeat("\x00", 256)); $this->NBTtiles = $tiles; @@ -258,7 +248,7 @@ class Chunk{ * @param int $z 0-15 */ public function getHeightMap(int $x, int $z) : int{ - return $this->heightMap[($z << 4) | $x]; + return $this->heightMap->get($x, $z); } /** @@ -268,7 +258,7 @@ class Chunk{ * @param int $z 0-15 */ public function setHeightMap(int $x, int $z, int $value) : void{ - $this->heightMap[($z << 4) | $x] = $value; + $this->heightMap->set($x, $z, $value); } /** @@ -552,18 +542,14 @@ class Chunk{ * @return int[] */ public function getHeightMapArray() : array{ - return $this->heightMap->toArray(); + return $this->heightMap->getValues(); } /** * @param int[] $values - * @throws \InvalidArgumentException */ public function setHeightMapArray(array $values) : void{ - if(count($values) !== 256){ - throw new \InvalidArgumentException("Expected exactly 256 values"); - } - $this->heightMap = \SplFixedArray::fromArray($values); + $this->heightMap = new HeightArray($values); } public function isDirty() : bool{ diff --git a/src/world/format/HeightArray.php b/src/world/format/HeightArray.php new file mode 100644 index 0000000000..3025d6f620 --- /dev/null +++ b/src/world/format/HeightArray.php @@ -0,0 +1,73 @@ + + */ + private $array; + + /** + * @param int[] $values ZZZZXXXX key bit order + * @phpstan-param list $values + */ + public function __construct(array $values){ + if(count($values) !== 256){ + throw new \InvalidArgumentException("Expected exactly 256 values"); + } + $this->array = \SplFixedArray::fromArray($values); + } + + private static function idx(int $x, int $z) : int{ + if($x < 0 or $x >= 16 or $z < 0 or $z >= 16){ + throw new \InvalidArgumentException("x and z must be in the range 0-15"); + } + return ($z << 4) | $x; + } + + public function get(int $x, int $z) : int{ + return $this->array[self::idx($x, $z)]; + } + + public function set(int $x, int $z, int $height) : void{ + $this->array[self::idx($x, $z)] = $height; + } + + /** + * @return int[] ZZZZXXXX key bit order + * @phpstan-return list + */ + public function getValues() : array{ + return $this->array->toArray(); + } + + public function __clone(){ + $this->array = clone $this->array; + } +} diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index e41776d323..242caebb85 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -27,6 +27,7 @@ use pocketmine\block\BlockLegacyIds; use pocketmine\utils\BinaryStream; use pocketmine\world\format\BiomeArray; use pocketmine\world\format\Chunk; +use pocketmine\world\format\HeightArray; use pocketmine\world\format\LightArray; use pocketmine\world\format\PalettedBlockArray; use pocketmine\world\format\SubChunk; @@ -120,7 +121,7 @@ final class FastChunkSerializer{ $subChunks = []; $biomeIds = null; - $heightMap = []; + $heightMap = null; if($terrainGenerated){ $count = $stream->getByte(); for($subCount = 0; $subCount < $count; ++$subCount){ @@ -142,7 +143,7 @@ final class FastChunkSerializer{ $biomeIds = new BiomeArray($stream->get(256)); if($lightPopulated){ - $heightMap = array_values(unpack("S*", $stream->get(512))); + $heightMap = new HeightArray(array_values(unpack("S*", $stream->get(512)))); } } From ae6a7b7cc9828091248a75b48db76908da8d0c4b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 16 May 2020 18:42:08 +0100 Subject: [PATCH 1573/3224] imports cleanup --- src/entity/object/ExperienceOrb.php | 1 - src/world/format/BiomeArray.php | 2 ++ src/world/format/Chunk.php | 4 ---- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/entity/object/ExperienceOrb.php b/src/entity/object/ExperienceOrb.php index 3ae1888b31..69f47eb606 100644 --- a/src/entity/object/ExperienceOrb.php +++ b/src/entity/object/ExperienceOrb.php @@ -31,7 +31,6 @@ use pocketmine\nbt\tag\ShortTag; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\player\Player; -use function realpath; use function sqrt; class ExperienceOrb extends Entity{ diff --git a/src/world/format/BiomeArray.php b/src/world/format/BiomeArray.php index 4e0734611b..f2e07d0d2b 100644 --- a/src/world/format/BiomeArray.php +++ b/src/world/format/BiomeArray.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\world\format; +use function chr; +use function ord; use function strlen; final class BiomeArray{ diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 9e02c6ea0c..517e4170b0 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -39,12 +39,8 @@ use pocketmine\world\World; use function array_fill; use function array_filter; use function array_map; -use function assert; -use function chr; use function count; -use function ord; use function str_repeat; -use function strlen; class Chunk{ public const DIRTY_FLAG_TERRAIN = 1 << 0; From b3454b34881771be3c982f5e639e94eb222dfb8b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 16 May 2020 18:42:47 +0100 Subject: [PATCH 1574/3224] BiomeArray: check lower bounds in ::idx() as well as upper bounds --- src/world/format/BiomeArray.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/format/BiomeArray.php b/src/world/format/BiomeArray.php index f2e07d0d2b..ca91fbea05 100644 --- a/src/world/format/BiomeArray.php +++ b/src/world/format/BiomeArray.php @@ -43,7 +43,7 @@ final class BiomeArray{ } private static function idx(int $x, int $z) : int{ - if($x >= 16 or $z >= 16){ + if($x < 0 or $x >= 16 or $z < 0 or $z >= 16){ throw new \InvalidArgumentException("x and z must be in the range 0-15"); } return ($z << 4) | $x; From 65f82f5cdf7d113c3695b64b7c899ee60b4dac24 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 17 May 2020 13:58:01 +0100 Subject: [PATCH 1575/3224] Task::onRun() and Task::onCancel() now require :void return typehints --- src/scheduler/Task.php | 8 ++------ .../src/pmmp/TesterPlugin/CheckTestCompletionTask.php | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/scheduler/Task.php b/src/scheduler/Task.php index 9d3e5a6fe0..85c0da6c72 100644 --- a/src/scheduler/Task.php +++ b/src/scheduler/Task.php @@ -57,17 +57,13 @@ abstract class Task{ /** * Actions to execute when run - * - * @return void */ - abstract public function onRun(); + abstract public function onRun() : void; /** * Actions to execute if the Task is cancelled - * - * @return void */ - public function onCancel(){ + public function onCancel() : void{ } } diff --git a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/CheckTestCompletionTask.php b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/CheckTestCompletionTask.php index 49ee205b0c..9cebd98a4e 100644 --- a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/CheckTestCompletionTask.php +++ b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/CheckTestCompletionTask.php @@ -34,7 +34,7 @@ class CheckTestCompletionTask extends Task{ $this->plugin = $plugin; } - public function onRun(){ + public function onRun() : void{ $test = $this->plugin->getCurrentTest(); if($test === null){ if(!$this->plugin->startNextTest()){ From 3c367c70cd97a991c3b97f8375333a168a04f214 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 18 May 2020 10:44:29 +0100 Subject: [PATCH 1576/3224] update build/php submodule to pmmp/php-build-scripts@8084604600c6d7490af07d9f1a46a4353e77dc74 --- build/php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/php b/build/php index 1e186a8fe2..8084604600 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit 1e186a8fe239d74ca833992ccd8b1f2e911b6876 +Subproject commit 8084604600c6d7490af07d9f1a46a4353e77dc74 From e96b082a54eca69122b46b12fad046fc7f024bfb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 18 May 2020 11:40:02 +0100 Subject: [PATCH 1577/3224] RegistryTrait: fixing use of method that doesn't belong to the trait --- src/utils/RegistryTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/RegistryTrait.php b/src/utils/RegistryTrait.php index f24a104788..547b08c578 100644 --- a/src/utils/RegistryTrait.php +++ b/src/utils/RegistryTrait.php @@ -92,7 +92,7 @@ trait RegistryTrait{ throw new \ArgumentCountError("Expected exactly 0 arguments, " . count($arguments) . " passed"); } try{ - return self::fromString($name); + return self::_registryFromString($name); }catch(\InvalidArgumentException $e){ throw new \Error($e->getMessage(), 0, $e); } From 486ce140d83b18d34b272fee78d05884d738d8dc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 18 May 2020 17:35:30 +0100 Subject: [PATCH 1578/3224] PacketBatch no longer extends NetworkBinaryStream this removes a whole bunch of crap from its API that shouldn't have been exposed. In the future we should look at splitting this into reader/writer halves, but for now this is a step in the right direction. --- .../mcpe/protocol/serializer/PacketBatch.php | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/network/mcpe/protocol/serializer/PacketBatch.php b/src/network/mcpe/protocol/serializer/PacketBatch.php index 15bfaeb3b3..e58001539d 100644 --- a/src/network/mcpe/protocol/serializer/PacketBatch.php +++ b/src/network/mcpe/protocol/serializer/PacketBatch.php @@ -27,18 +27,25 @@ use pocketmine\network\mcpe\protocol\Packet; use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\utils\BinaryDataException; -class PacketBatch extends NetworkBinaryStream{ +class PacketBatch{ + + /** @var NetworkBinaryStream */ + private $binaryStream; + + public function __construct(?string $buffer = null){ + $this->binaryStream = new NetworkBinaryStream($buffer ?? ""); + } public function putPacket(Packet $packet) : void{ $packet->encode(); - $this->putString($packet->getBinaryStream()->getBuffer()); + $this->binaryStream->putString($packet->getBinaryStream()->getBuffer()); } /** * @throws BinaryDataException */ public function getPacket(PacketPool $packetPool) : Packet{ - return $packetPool->getPacket($this->getString()); + return $packetPool->getPacket($this->binaryStream->getString()); } /** @@ -55,4 +62,12 @@ class PacketBatch extends NetworkBinaryStream{ } return $result; } + + public function getBuffer() : string{ + return $this->binaryStream->getBuffer(); + } + + public function feof() : bool{ + return $this->binaryStream->feof(); + } } From 07f979fbdeb0b5718581489d4b1f2837bc9dbac9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 18 May 2020 17:54:27 +0100 Subject: [PATCH 1579/3224] RuntimeBlockMapping: bedrockKnownStates is never null --- src/network/mcpe/convert/RuntimeBlockMapping.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/mcpe/convert/RuntimeBlockMapping.php b/src/network/mcpe/convert/RuntimeBlockMapping.php index 4aef0c5432..056842172e 100644 --- a/src/network/mcpe/convert/RuntimeBlockMapping.php +++ b/src/network/mcpe/convert/RuntimeBlockMapping.php @@ -47,8 +47,8 @@ final class RuntimeBlockMapping{ private $legacyToRuntimeMap = []; /** @var int[] */ private $runtimeToLegacyMap = []; - /** @var CompoundTag[]|null */ - private $bedrockKnownStates = null; + /** @var CompoundTag[] */ + private $bedrockKnownStates; /** * @var CacheableNbt|null * @phpstan-var CacheableNbt<\pocketmine\nbt\tag\ListTag>|null From 22425551ed004e51e9cbc264f5758f10e856bc28 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 18 May 2020 18:12:04 +0100 Subject: [PATCH 1580/3224] separate default attribute creation from Attribute into AttributeMap --- src/entity/Attribute.php | 36 +----------------- src/entity/AttributeFactory.php | 63 ++++++++++++++++++++++++++++++++ src/entity/EntityFactory.php | 1 - src/entity/ExperienceManager.php | 2 +- src/entity/HungerManager.php | 2 +- src/entity/Living.php | 12 +++--- 6 files changed, 72 insertions(+), 44 deletions(-) create mode 100644 src/entity/AttributeFactory.php diff --git a/src/entity/Attribute.php b/src/entity/Attribute.php index 38f22547f4..68c00bbc23 100644 --- a/src/entity/Attribute.php +++ b/src/entity/Attribute.php @@ -63,44 +63,10 @@ class Attribute{ /** @var bool */ protected $desynchronized = true; - /** @var Attribute[] */ - protected static $attributes = []; - - public static function init() : void{ - self::register(self::ABSORPTION, 0.00, 340282346638528859811704183484516925440.00, 0.00); - self::register(self::SATURATION, 0.00, 20.00, 20.00); - self::register(self::EXHAUSTION, 0.00, 5.00, 0.0, false); - self::register(self::KNOCKBACK_RESISTANCE, 0.00, 1.00, 0.00); - self::register(self::HEALTH, 0.00, 20.00, 20.00); - self::register(self::MOVEMENT_SPEED, 0.00, 340282346638528859811704183484516925440.00, 0.10); - self::register(self::FOLLOW_RANGE, 0.00, 2048.00, 16.00, false); - self::register(self::HUNGER, 0.00, 20.00, 20.00); - self::register(self::ATTACK_DAMAGE, 0.00, 340282346638528859811704183484516925440.00, 1.00, false); - self::register(self::EXPERIENCE_LEVEL, 0.00, 24791.00, 0.00); - self::register(self::EXPERIENCE, 0.00, 1.00, 0.00); - self::register(self::UNDERWATER_MOVEMENT, 0.0, 340282346638528859811704183484516925440.0, 0.02); - self::register(self::LUCK, -1024.0, 1024.0, 0.0); - self::register(self::FALL_DAMAGE, 0.0, 340282346638528859811704183484516925440.0, 1.0); - self::register(self::HORSE_JUMP_STRENGTH, 0.0, 2.0, 0.7); - self::register(self::ZOMBIE_SPAWN_REINFORCEMENTS, 0.0, 1.0, 0.0); - } - - /** - * @throws \InvalidArgumentException - */ - public static function register(string $id, float $minValue, float $maxValue, float $defaultValue, bool $shouldSend = true) : Attribute{ + public function __construct(string $id, float $minValue, float $maxValue, float $defaultValue, bool $shouldSend = true){ if($minValue > $maxValue or $defaultValue > $maxValue or $defaultValue < $minValue){ throw new \InvalidArgumentException("Invalid ranges: min value: $minValue, max value: $maxValue, $defaultValue: $defaultValue"); } - - return self::$attributes[$id] = new Attribute($id, $minValue, $maxValue, $defaultValue, $shouldSend); - } - - public static function get(string $id) : ?Attribute{ - return isset(self::$attributes[$id]) ? clone self::$attributes[$id] : null; - } - - private function __construct(string $id, float $minValue, float $maxValue, float $defaultValue, bool $shouldSend = true){ $this->id = $id; $this->minValue = $minValue; $this->maxValue = $maxValue; diff --git a/src/entity/AttributeFactory.php b/src/entity/AttributeFactory.php new file mode 100644 index 0000000000..5a9cd77e3d --- /dev/null +++ b/src/entity/AttributeFactory.php @@ -0,0 +1,63 @@ +register(Attribute::ABSORPTION, 0.00, 340282346638528859811704183484516925440.00, 0.00); + $this->register(Attribute::SATURATION, 0.00, 20.00, 20.00); + $this->register(Attribute::EXHAUSTION, 0.00, 5.00, 0.0, false); + $this->register(Attribute::KNOCKBACK_RESISTANCE, 0.00, 1.00, 0.00); + $this->register(Attribute::HEALTH, 0.00, 20.00, 20.00); + $this->register(Attribute::MOVEMENT_SPEED, 0.00, 340282346638528859811704183484516925440.00, 0.10); + $this->register(Attribute::FOLLOW_RANGE, 0.00, 2048.00, 16.00, false); + $this->register(Attribute::HUNGER, 0.00, 20.00, 20.00); + $this->register(Attribute::ATTACK_DAMAGE, 0.00, 340282346638528859811704183484516925440.00, 1.00, false); + $this->register(Attribute::EXPERIENCE_LEVEL, 0.00, 24791.00, 0.00); + $this->register(Attribute::EXPERIENCE, 0.00, 1.00, 0.00); + $this->register(Attribute::UNDERWATER_MOVEMENT, 0.0, 340282346638528859811704183484516925440.0, 0.02); + $this->register(Attribute::LUCK, -1024.0, 1024.0, 0.0); + $this->register(Attribute::FALL_DAMAGE, 0.0, 340282346638528859811704183484516925440.0, 1.0); + $this->register(Attribute::HORSE_JUMP_STRENGTH, 0.0, 2.0, 0.7); + $this->register(Attribute::ZOMBIE_SPAWN_REINFORCEMENTS, 0.0, 1.0, 0.0); + } + + public function get(string $id) : ?Attribute{ + return isset($this->attributes[$id]) ? clone $this->attributes[$id] : null; + } + + /** + * @throws \InvalidArgumentException + */ + public function register(string $id, float $minValue, float $maxValue, float $defaultValue, bool $shouldSend = true) : Attribute{ + return $this->attributes[$id] = new Attribute($id, $minValue, $maxValue, $defaultValue, $shouldSend); + } +} diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index a8119ed5d0..0f4a83a8d0 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -103,7 +103,6 @@ final class EntityFactory{ $this->register(Human::class, ['Human']); - Attribute::init(); PaintingMotive::init(); } diff --git a/src/entity/ExperienceManager.php b/src/entity/ExperienceManager.php index 89e7d26fca..0b8fb050cc 100644 --- a/src/entity/ExperienceManager.php +++ b/src/entity/ExperienceManager.php @@ -59,7 +59,7 @@ class ExperienceManager{ } private static function fetchAttribute(Entity $entity, string $attributeId) : Attribute{ - $entity->getAttributeMap()->add(Attribute::get($attributeId)); + $entity->getAttributeMap()->add(AttributeFactory::getInstance()->get($attributeId)); return $entity->getAttributeMap()->get($attributeId); } diff --git a/src/entity/HungerManager.php b/src/entity/HungerManager.php index 8f8be0abd9..331f8e96cc 100644 --- a/src/entity/HungerManager.php +++ b/src/entity/HungerManager.php @@ -57,7 +57,7 @@ class HungerManager{ } private static function fetchAttribute(Entity $entity, string $attributeId) : Attribute{ - $entity->getAttributeMap()->add(Attribute::get($attributeId)); + $entity->getAttributeMap()->add(AttributeFactory::getInstance()->get($attributeId)); return $entity->getAttributeMap()->get($attributeId); } diff --git a/src/entity/Living.php b/src/entity/Living.php index c5cbf8949f..a8b175d557 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -153,12 +153,12 @@ abstract class Living extends Entity{ } protected function addAttributes() : void{ - $this->attributeMap->add(Attribute::get(Attribute::HEALTH)); - $this->attributeMap->add(Attribute::get(Attribute::FOLLOW_RANGE)); - $this->attributeMap->add(Attribute::get(Attribute::KNOCKBACK_RESISTANCE)); - $this->attributeMap->add(Attribute::get(Attribute::MOVEMENT_SPEED)); - $this->attributeMap->add(Attribute::get(Attribute::ATTACK_DAMAGE)); - $this->attributeMap->add(Attribute::get(Attribute::ABSORPTION)); + $this->attributeMap->add(AttributeFactory::getInstance()->get(Attribute::HEALTH)); + $this->attributeMap->add(AttributeFactory::getInstance()->get(Attribute::FOLLOW_RANGE)); + $this->attributeMap->add(AttributeFactory::getInstance()->get(Attribute::KNOCKBACK_RESISTANCE)); + $this->attributeMap->add(AttributeFactory::getInstance()->get(Attribute::MOVEMENT_SPEED)); + $this->attributeMap->add(AttributeFactory::getInstance()->get(Attribute::ATTACK_DAMAGE)); + $this->attributeMap->add(AttributeFactory::getInstance()->get(Attribute::ABSORPTION)); } public function setHealth(float $amount) : void{ From f0fefecf40c6485cc1ff8cf90be00bf4253a298c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 18 May 2020 20:36:50 +0100 Subject: [PATCH 1581/3224] updated l7 and l8 baselines for master --- tests/phpstan/configs/l7-baseline.neon | 1521 +++++++----- tests/phpstan/configs/l8-baseline.neon | 3081 +++++++++++------------- 2 files changed, 2226 insertions(+), 2376 deletions(-) diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index d09af1cf32..7225ec7932 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -18,1015 +18,1230 @@ parameters: - message: "#^Parameter \\#1 \\$fp of function fwrite expects resource, resource\\|false given\\.$#" count: 1 - path: ../../../src/pocketmine/MemoryManager.php + path: ../../../src/MemoryManager.php - message: "#^Parameter \\#1 \\$fp of function fclose expects resource, resource\\|false given\\.$#" count: 1 - path: ../../../src/pocketmine/MemoryManager.php - - - - message: "#^Parameter \\#3 \\$data of class pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\SkinImage constructor expects string, string\\|false given\\.$#" - count: 3 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Parameter \\#2 \\$resourcePatch of class pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\SkinData constructor expects string, string\\|false given\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Parameter \\#6 \\$geometryData of class pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\SkinData constructor expects string, string\\|false given\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Parameter \\#7 \\$animationData of class pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\SkinData constructor expects string, string\\|false given\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\ModalFormRequestPacket\\:\\:\\$formData \\(string\\) does not accept string\\|false\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Only booleans are allowed in an if condition, bool\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php + path: ../../../src/MemoryManager.php - message: "#^Parameter \\#1 \\$haystack of function substr_count expects string, string\\|false given\\.$#" count: 1 - path: ../../../src/pocketmine/PocketMine.php + path: ../../../src/PocketMine.php - message: "#^Parameter \\#1 \\$version1 of function version_compare expects string, string\\|false given\\.$#" count: 2 - path: ../../../src/pocketmine/PocketMine.php + path: ../../../src/PocketMine.php - message: "#^Parameter \\#1 \\$path of function realpath expects string, array\\\\|string\\|false given\\.$#" count: 1 - path: ../../../src/pocketmine/PocketMine.php + path: ../../../src/PocketMine.php - message: "#^Parameter \\#1 \\$filename of function is_file expects string, array\\\\|string given\\.$#" count: 1 - path: ../../../src/pocketmine/PocketMine.php + path: ../../../src/PocketMine.php - message: "#^Binary operation \"\\.\" between 'Composer autoloader…' and array\\\\|string\\|false results in an error\\.$#" count: 1 - path: ../../../src/pocketmine/PocketMine.php + path: ../../../src/PocketMine.php - message: "#^Binary operation \"\\.\" between array\\\\|string\\|false and '/'\\|'\\\\\\\\' results in an error\\.$#" count: 2 - path: ../../../src/pocketmine/PocketMine.php + path: ../../../src/PocketMine.php - message: "#^Parameter \\#1 \\$path of function realpath expects string, string\\|false given\\.$#" count: 2 - path: ../../../src/pocketmine/PocketMine.php + path: ../../../src/PocketMine.php - - message: "#^Parameter \\#1 \\$fp of function flock expects resource, resource\\|false given\\.$#" - count: 3 - path: ../../../src/pocketmine/PocketMine.php - - - - message: "#^Parameter \\#1 \\$source of function stream_get_contents expects resource, resource\\|false given\\.$#" + message: "#^Parameter \\#1 \\$buffer of method pocketmine\\\\nbt\\\\BaseNbtSerializer\\:\\:readCompressed\\(\\) expects string, string\\|false given\\.$#" count: 1 - path: ../../../src/pocketmine/PocketMine.php - - - - message: "#^Parameter \\#1 \\$fp of function ftruncate expects resource, resource\\|false given\\.$#" - count: 1 - path: ../../../src/pocketmine/PocketMine.php - - - - message: "#^Parameter \\#1 \\$fp of function fwrite expects resource, resource\\|false given\\.$#" - count: 1 - path: ../../../src/pocketmine/PocketMine.php - - - - message: "#^Parameter \\#1 \\$fp of function fflush expects resource, resource\\|false given\\.$#" - count: 1 - path: ../../../src/pocketmine/PocketMine.php - - - - message: "#^Parameter \\#1 \\$buffer of method pocketmine\\\\nbt\\\\NBTStream\\:\\:readCompressed\\(\\) expects string, string\\|false given\\.$#" - count: 1 - path: ../../../src/pocketmine/Server.php - - - - message: "#^Parameter \\#1 \\$input of function array_filter expects array, array\\\\|false given\\.$#" - count: 1 - path: ../../../src/pocketmine/Server.php + path: ../../../src/Server.php - message: "#^Cannot cast array\\\\|string\\|false to string\\.$#" count: 1 - path: ../../../src/pocketmine/Server.php + path: ../../../src/Server.php - message: "#^Cannot cast array\\\\|string\\|false to int\\.$#" count: 1 - path: ../../../src/pocketmine/Server.php + path: ../../../src/Server.php - message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, string\\|false given\\.$#" count: 1 - path: ../../../src/pocketmine/Server.php + path: ../../../src/Server.php + + - + message: "#^Parameter \\#1 \\$input of function yaml_parse expects string, string\\|false given\\.$#" + count: 1 + path: ../../../src/Server.php - message: "#^Only numeric types are allowed in \\+, int\\|false given on the left side\\.$#" count: 1 - path: ../../../src/pocketmine/Server.php + path: ../../../src/Server.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\format\\\\Chunk\\:\\:setFullBlock\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Cactus.php + path: ../../../src/block/Block.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Cactus.php + path: ../../../src/block/Cactus.php - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Cactus.php + path: ../../../src/block/Cactus.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getBlockIdAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Farmland.php + path: ../../../src/block/Cactus.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getBlockIdAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getRealBlockSkyLightAt\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Farmland.php + path: ../../../src/block/DaylightSensor.php - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getBlockIdAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getRealBlockSkyLightAt\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Farmland.php + path: ../../../src/block/DaylightSensor.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getRealBlockSkyLightAt\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Grass.php + path: ../../../src/block/DaylightSensor.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Grass.php + path: ../../../src/block/DragonEgg.php - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Grass.php + path: ../../../src/block/DragonEgg.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getBlockIdAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Grass.php + path: ../../../src/block/DragonEgg.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getBlockIdAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#1 \\$xDiff of class pocketmine\\\\world\\\\particle\\\\DragonEggTeleportParticle constructor expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Grass.php + path: ../../../src/block/DragonEgg.php - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getBlockIdAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#2 \\$yDiff of class pocketmine\\\\world\\\\particle\\\\DragonEggTeleportParticle constructor expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Grass.php + path: ../../../src/block/DragonEgg.php + + - + message: "#^Parameter \\#3 \\$zDiff of class pocketmine\\\\world\\\\particle\\\\DragonEggTeleportParticle constructor expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/DragonEgg.php + + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Farmland.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Farmland.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Farmland.php + + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentBlockLight\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/FrostedIce.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentBlockLight\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/FrostedIce.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentBlockLight\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/FrostedIce.php + + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentBlockSkyLight\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/FrostedIce.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentBlockSkyLight\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/FrostedIce.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentBlockSkyLight\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/FrostedIce.php + + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/FrostedIce.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/FrostedIce.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/FrostedIce.php + + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Grass.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Grass.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Grass.php + + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Grass.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Grass.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Grass.php - message: "#^Parameter \\#1 \\$min of function mt_rand expects int, float\\|int given\\.$#" count: 3 - path: ../../../src/pocketmine/block/Grass.php + path: ../../../src/block/Grass.php - message: "#^Parameter \\#2 \\$max of function mt_rand expects int, float\\|int given\\.$#" count: 3 - path: ../../../src/pocketmine/block/Grass.php + path: ../../../src/block/Grass.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getHighestAdjacentBlockLight\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentBlockLight\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Ice.php + path: ../../../src/block/Ice.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getHighestAdjacentBlockLight\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentBlockLight\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Ice.php + path: ../../../src/block/Ice.php - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getHighestAdjacentBlockLight\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentBlockLight\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Ice.php + path: ../../../src/block/Ice.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#1 \\$x of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Leaves.php + + - + message: "#^Parameter \\#2 \\$y of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Leaves.php + + - + message: "#^Parameter \\#3 \\$z of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Leaves.php + + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 23 - path: ../../../src/pocketmine/block/Liquid.php + path: ../../../src/block/Liquid.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 23 - path: ../../../src/pocketmine/block/Liquid.php + path: ../../../src/block/Liquid.php - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 23 - path: ../../../src/pocketmine/block/Liquid.php + path: ../../../src/block/Liquid.php - - message: "#^Parameter \\#1 \\$x of static method pocketmine\\\\level\\\\Level\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#1 \\$x of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" count: 3 - path: ../../../src/pocketmine/block/Liquid.php + path: ../../../src/block/Liquid.php - - message: "#^Parameter \\#2 \\$y of static method pocketmine\\\\level\\\\Level\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#2 \\$y of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" count: 3 - path: ../../../src/pocketmine/block/Liquid.php + path: ../../../src/block/Liquid.php - - message: "#^Parameter \\#3 \\$z of static method pocketmine\\\\level\\\\Level\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#3 \\$z of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" count: 3 - path: ../../../src/pocketmine/block/Liquid.php + path: ../../../src/block/Liquid.php - message: "#^Parameter \\#1 \\$blockX of method pocketmine\\\\block\\\\Liquid\\:\\:calculateFlowCost\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Liquid.php + path: ../../../src/block/Liquid.php - message: "#^Parameter \\#2 \\$blockY of method pocketmine\\\\block\\\\Liquid\\:\\:calculateFlowCost\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Liquid.php + path: ../../../src/block/Liquid.php - message: "#^Parameter \\#3 \\$blockZ of method pocketmine\\\\block\\\\Liquid\\:\\:calculateFlowCost\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Liquid.php + path: ../../../src/block/Liquid.php + + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Liquid.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Liquid.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Liquid.php - message: "#^Parameter \\#1 \\$min of function mt_rand expects int, float\\|int given\\.$#" count: 3 - path: ../../../src/pocketmine/block/Mycelium.php + path: ../../../src/block/Mycelium.php - message: "#^Parameter \\#2 \\$max of function mt_rand expects int, float\\|int given\\.$#" count: 3 - path: ../../../src/pocketmine/block/Mycelium.php + path: ../../../src/block/Mycelium.php - message: "#^Method pocketmine\\\\block\\\\Rail\\:\\:getPossibleConnectionDirectionsOneConstraint\\(\\) should return array\\ but returns array\\\\.$#" count: 1 - path: ../../../src/pocketmine/block/Rail.php + path: ../../../src/block/Rail.php - - message: "#^Parameter \\#2 \\$x of static method pocketmine\\\\level\\\\generator\\\\object\\\\Tree\\:\\:growTree\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#2 \\$x of static method pocketmine\\\\world\\\\generator\\\\object\\\\Tree\\:\\:growTree\\(\\) expects int, float\\|int given\\.$#" count: 2 - path: ../../../src/pocketmine/block/Sapling.php + path: ../../../src/block/Sapling.php - - message: "#^Parameter \\#3 \\$y of static method pocketmine\\\\level\\\\generator\\\\object\\\\Tree\\:\\:growTree\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#3 \\$y of static method pocketmine\\\\world\\\\generator\\\\object\\\\Tree\\:\\:growTree\\(\\) expects int, float\\|int given\\.$#" count: 2 - path: ../../../src/pocketmine/block/Sapling.php + path: ../../../src/block/Sapling.php - - message: "#^Parameter \\#4 \\$z of static method pocketmine\\\\level\\\\generator\\\\object\\\\Tree\\:\\:growTree\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#4 \\$z of static method pocketmine\\\\world\\\\generator\\\\object\\\\Tree\\:\\:growTree\\(\\) expects int, float\\|int given\\.$#" count: 2 - path: ../../../src/pocketmine/block/Sapling.php + path: ../../../src/block/Sapling.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Sapling.php + path: ../../../src/block/Sapling.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Sapling.php + path: ../../../src/block/Sapling.php - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Sapling.php + path: ../../../src/block/Sapling.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getBlockLightAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getBlockLightAt\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/SnowLayer.php + path: ../../../src/block/SnowLayer.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getBlockLightAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getBlockLightAt\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/SnowLayer.php + path: ../../../src/block/SnowLayer.php - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getBlockLightAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getBlockLightAt\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/block/SnowLayer.php + path: ../../../src/block/SnowLayer.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 2 - path: ../../../src/pocketmine/block/Sugarcane.php + path: ../../../src/block/Sugarcane.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 2 - path: ../../../src/pocketmine/block/Sugarcane.php + path: ../../../src/block/Sugarcane.php - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 2 - path: ../../../src/pocketmine/block/Sugarcane.php + path: ../../../src/block/Sugarcane.php + + - + message: "#^Method pocketmine\\\\block\\\\VanillaBlocks\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" + count: 1 + path: ../../../src/block/VanillaBlocks.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getTileAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/tile/Chest.php + + - + message: "#^Property pocketmine\\\\block\\\\tile\\\\Chest\\:\\:\\$pairX \\(int\\|null\\) does not accept float\\|int\\.$#" + count: 2 + path: ../../../src/block/tile/Chest.php + + - + message: "#^Property pocketmine\\\\block\\\\tile\\\\Chest\\:\\:\\$pairZ \\(int\\|null\\) does not accept float\\|int\\.$#" + count: 2 + path: ../../../src/block/tile/Chest.php + + - + message: "#^Parameter \\#2 \\$value of method pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\:\\:setInt\\(\\) expects int, float\\|int given\\.$#" + count: 3 + path: ../../../src/block/tile/Spawnable.php + + - + message: "#^Method pocketmine\\\\block\\\\tile\\\\TileFactory\\:\\:getSaveId\\(\\) should return string but returns string\\|false\\.$#" + count: 1 + path: ../../../src/block/tile/TileFactory.php - message: "#^Static property pocketmine\\\\command\\\\CommandReader\\:\\:\\$stdin \\(resource\\) does not accept resource\\|false\\.$#" count: 1 - path: ../../../src/pocketmine/command/CommandReader.php + path: ../../../src/command/CommandReader.php - message: "#^Parameter \\#1 \\$stream of method pocketmine\\\\command\\\\CommandReader\\:\\:isPipe\\(\\) expects resource, resource\\|false given\\.$#" count: 1 - path: ../../../src/pocketmine/command/CommandReader.php + path: ../../../src/command/CommandReader.php - message: "#^Cannot access offset 'mode' on array\\(0 \\=\\> int, 1 \\=\\> int, 2 \\=\\> int, 3 \\=\\> int, 4 \\=\\> int, 5 \\=\\> int, 6 \\=\\> int, 7 \\=\\> int, \\.\\.\\.\\)\\|false\\.$#" count: 1 - path: ../../../src/pocketmine/command/CommandReader.php + path: ../../../src/command/CommandReader.php - message: "#^Parameter \\#2 \\$params of class pocketmine\\\\lang\\\\TranslationContainer constructor expects array\\, array\\ given\\.$#" count: 1 - path: ../../../src/pocketmine/command/defaults/BanCommand.php + path: ../../../src/command/defaults/BanCommand.php - message: "#^Only booleans are allowed in an if condition, int\\|false given\\.$#" count: 1 - path: ../../../src/pocketmine/command/defaults/BanIpCommand.php + path: ../../../src/command/defaults/BanIpCommand.php - message: "#^Parameter \\#2 \\$params of class pocketmine\\\\lang\\\\TranslationContainer constructor expects array\\, array\\ given\\.$#" count: 1 - path: ../../../src/pocketmine/command/defaults/BanIpCommand.php + path: ../../../src/command/defaults/BanIpCommand.php - message: "#^Only booleans are allowed in an if condition, int\\|false given\\.$#" count: 1 - path: ../../../src/pocketmine/command/defaults/PardonIpCommand.php + path: ../../../src/command/defaults/PardonIpCommand.php - message: "#^Parameter \\#1 \\$fp of static method pocketmine\\\\timings\\\\TimingsHandler\\:\\:printTimings\\(\\) expects resource, resource\\|false given\\.$#" count: 1 - path: ../../../src/pocketmine/command/defaults/TimingsCommand.php + path: ../../../src/command/defaults/TimingsCommand.php - message: "#^Parameter \\#1 \\$fp of function fseek expects resource, resource\\|false given\\.$#" count: 1 - path: ../../../src/pocketmine/command/defaults/TimingsCommand.php + path: ../../../src/command/defaults/TimingsCommand.php - message: "#^Parameter \\#1 \\$source of function stream_get_contents expects resource, resource\\|false given\\.$#" count: 1 - path: ../../../src/pocketmine/command/defaults/TimingsCommand.php + path: ../../../src/command/defaults/TimingsCommand.php - message: "#^Parameter \\#1 \\$fp of function fclose expects resource, resource\\|false given\\.$#" count: 2 - path: ../../../src/pocketmine/command/defaults/TimingsCommand.php + path: ../../../src/command/defaults/TimingsCommand.php - - message: "#^Parameter \\#4 \\$data of class class@anonymous/src/pocketmine/command/defaults/TimingsCommand\\.php\\:125 constructor expects array\\, array\\ given\\.$#" + message: "#^Parameter \\#4 \\$data of class class@anonymous/src/command/defaults/TimingsCommand\\.php\\:124 constructor expects array\\, array\\ given\\.$#" count: 1 - path: ../../../src/pocketmine/command/defaults/TimingsCommand.php + path: ../../../src/command/defaults/TimingsCommand.php + + - + message: "#^Method pocketmine\\\\crafting\\\\CraftingManager\\:\\:hashOutputs\\(\\) should return string but returns string\\|false\\.$#" + count: 1 + path: ../../../src/crafting/CraftingManager.php + + - + message: "#^Parameter \\#1 \\$json of function json_decode expects string, string\\|false given\\.$#" + count: 1 + path: ../../../src/crafting/CraftingManagerFromDataHelper.php + + - + message: "#^Parameter \\#1 \\$json of function json_decode expects string, string\\|false given\\.$#" + count: 1 + path: ../../../src/data/bedrock/LegacyToStringBidirectionalIdMap.php + + - + message: "#^Method pocketmine\\\\entity\\\\EntityFactory\\:\\:getSaveId\\(\\) should return string but returns string\\|false\\.$#" + count: 1 + path: ../../../src/entity/EntityFactory.php - message: "#^Parameter \\#1 \\$index of method pocketmine\\\\inventory\\\\BaseInventory\\:\\:setItem\\(\\) expects int, int\\|string given\\.$#" count: 1 - path: ../../../src/pocketmine/entity/Human.php + path: ../../../src/entity/ExperienceManager.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/entity/Living.php + path: ../../../src/entity/Living.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/entity/Living.php + path: ../../../src/entity/Living.php - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/entity/Living.php + path: ../../../src/entity/Living.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Property pocketmine\\\\entity\\\\Skin\\:\\:\\$geometryData \\(string\\) does not accept string\\|false\\.$#" count: 1 - path: ../../../src/pocketmine/entity/object/Painting.php + path: ../../../src/entity/Skin.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Method pocketmine\\\\entity\\\\effect\\\\VanillaEffects\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" count: 1 - path: ../../../src/pocketmine/entity/object/Painting.php + path: ../../../src/entity/effect/VanillaEffects.php - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#2 \\$x of method pocketmine\\\\block\\\\Block\\:\\:position\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/entity/object/Painting.php + path: ../../../src/entity/object/FallingBlock.php + + - + message: "#^Parameter \\#3 \\$y of method pocketmine\\\\block\\\\Block\\:\\:position\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/entity/object/FallingBlock.php + + - + message: "#^Parameter \\#4 \\$z of method pocketmine\\\\block\\\\Block\\:\\:position\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/entity/object/FallingBlock.php + + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/entity/object/Painting.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/entity/object/Painting.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/entity/object/Painting.php - message: "#^Parameter \\#2 \\$value of method pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\:\\:setInt\\(\\) expects int, float\\|int given\\.$#" count: 3 - path: ../../../src/pocketmine/entity/projectile/Projectile.php + path: ../../../src/entity/projectile/Projectile.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" - count: 2 - path: ../../../src/pocketmine/entity/projectile/Projectile.php + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/entity/projectile/Projectile.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" - count: 2 - path: ../../../src/pocketmine/entity/projectile/Projectile.php + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/entity/projectile/Projectile.php - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" - count: 2 - path: ../../../src/pocketmine/entity/projectile/Projectile.php + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/entity/projectile/Projectile.php - message: "#^Parameter \\#1 \\$argument of class ReflectionClass constructor expects class\\-string\\\\|T of object, string given\\.$#" count: 1 - path: ../../../src/pocketmine/event/HandlerList.php + path: ../../../src/event/HandlerListManager.php - message: "#^Parameter \\#1 \\$json of function json_decode expects string, string\\|false given\\.$#" count: 1 - path: ../../../src/pocketmine/inventory/CraftingManager.php + path: ../../../src/inventory/CreativeInventory.php - - message: "#^Method pocketmine\\\\inventory\\\\CraftingManager\\:\\:hashOutputs\\(\\) should return string but returns string\\|false\\.$#" + message: "#^Parameter \\#1 \\$buffer of method pocketmine\\\\nbt\\\\BaseNbtSerializer\\:\\:read\\(\\) expects string, string\\|false given\\.$#" count: 1 - path: ../../../src/pocketmine/inventory/CraftingManager.php + path: ../../../src/item/Item.php - - message: "#^Method pocketmine\\\\item\\\\Item\\:\\:writeCompoundTag\\(\\) should return string but returns string\\|false\\.$#" + message: "#^Parameter \\#4 \\$entityClass of class pocketmine\\\\item\\\\SpawnEgg constructor expects class\\-string\\, pocketmine\\\\entity\\\\Living\\|string given\\.$#" count: 1 - path: ../../../src/pocketmine/item/Item.php + path: ../../../src/item/ItemFactory.php - - message: "#^Parameter \\#1 \\$json of function json_decode expects string, string\\|false given\\.$#" + message: "#^Method pocketmine\\\\item\\\\VanillaItems\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" count: 1 - path: ../../../src/pocketmine/item/Item.php + path: ../../../src/item/VanillaItems.php - message: "#^Parameter \\#2 \\$input1 of function array_map expects array, array\\|false given\\.$#" count: 1 - path: ../../../src/pocketmine/lang/BaseLang.php + path: ../../../src/lang/Language.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:setBlockIdAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:setBlockIdAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:setBlockIdAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:setBlockDataAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:setBlockDataAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:setBlockDataAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getTileAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getTileAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getTileAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Parameter \\#1 \\$x of static method pocketmine\\\\level\\\\Level\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Parameter \\#2 \\$y of static method pocketmine\\\\level\\\\Level\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Parameter \\#3 \\$z of static method pocketmine\\\\level\\\\Level\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Parameter \\#2 \\$generatorClass of class pocketmine\\\\level\\\\generator\\\\GeneratorRegisterTask constructor expects string, pocketmine\\\\level\\\\generator\\\\Generator\\|string given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#1 \\$x of static method pocketmine\\\\level\\\\Level\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" - count: 3 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#2 \\$y of static method pocketmine\\\\level\\\\Level\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" - count: 3 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#3 \\$z of static method pocketmine\\\\level\\\\Level\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" - count: 3 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\UpdateBlockPacket\\:\\:\\$x \\(int\\) does not accept float\\|int\\.$#" + message: "#^Parameter \\#1 \\$str of static method pocketmine\\\\network\\\\mcpe\\\\JwtUtils\\:\\:b64UrlEncode\\(\\) expects string, string\\|false given\\.$#" count: 2 - path: ../../../src/pocketmine/level/Level.php + path: ../../../src/network/mcpe/JwtUtils.php - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\UpdateBlockPacket\\:\\:\\$y \\(int\\) does not accept float\\|int\\.$#" - count: 2 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\UpdateBlockPacket\\:\\:\\$z \\(int\\) does not accept float\\|int\\.$#" - count: 2 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getFullBlock\\(\\) expects int, float\\|int given\\.$#" - count: 2 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getFullBlock\\(\\) expects int, float\\|int given\\.$#" - count: 2 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getFullBlock\\(\\) expects int, float\\|int given\\.$#" - count: 2 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" - count: 4 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" - count: 4 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" - count: 4 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#1 \\$string of method Mdanter\\\\Ecc\\\\Serializer\\\\PublicKey\\\\DerPublicKeySerializer\\:\\:parse\\(\\) expects string, string\\|false given\\.$#" count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:updateBlockSkyLight\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:updateBlockSkyLight\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:updateBlockSkyLight\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:updateBlockLight\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:updateBlockLight\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:updateBlockLight\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\format\\\\Chunk\\:\\:setBlock\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#1 \\$x of static method pocketmine\\\\level\\\\Level\\:\\:chunkBlockHash\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#2 \\$y of static method pocketmine\\\\level\\\\Level\\:\\:chunkBlockHash\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#3 \\$z of static method pocketmine\\\\level\\\\Level\\:\\:chunkBlockHash\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#6 \\$xpDrops of class pocketmine\\\\event\\\\block\\\\BlockBreakEvent constructor expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#2 \\$amount of method pocketmine\\\\level\\\\Level\\:\\:dropExperience\\(\\) expects int, float\\|int\\<1, max\\> given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#1 \\$data of static method SplFixedArray\\\\:\\:fromArray\\(\\) expects array\\, array\\ given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/Chunk.php - - - - message: "#^Method pocketmine\\\\level\\\\format\\\\io\\\\ChunkUtils\\:\\:convertBiomeColors\\(\\) should return string but returns array\\\\|string\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/io/ChunkUtils.php - - - - message: "#^Parameter \\#1 \\$string of function strlen expects string, string\\|false given\\.$#" - count: 2 - path: ../../../src/pocketmine/level/format/io/leveldb/LevelDB.php - - - - message: "#^Parameter \\#2 \\$value of method LevelDB\\:\\:put\\(\\) expects string, string\\|false given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/io/leveldb/LevelDB.php - - - - message: "#^Method pocketmine\\\\level\\\\format\\\\io\\\\region\\\\Anvil\\:\\:nbtSerialize\\(\\) should return string but returns string\\|false\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/io/region/Anvil.php - - - - message: "#^Method pocketmine\\\\level\\\\format\\\\io\\\\region\\\\McRegion\\:\\:nbtSerialize\\(\\) should return string but returns string\\|false\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/io/region/McRegion.php - - - - message: "#^Parameter \\#1 \\$input of function array_filter expects array, array\\\\|false given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/io/region/McRegion.php - - - - message: "#^Only numeric types are allowed in \\+, int\\|false given on the left side\\.$#" - count: 2 - path: ../../../src/pocketmine/level/format/io/region/McRegion.php - - - - message: "#^Only numeric types are allowed in %, int\\|false given on the left side\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/io/region/RegionLoader.php - - - - message: "#^Parameter \\#1 \\$string of function strlen expects string, string\\|false given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/io/region/RegionLoader.php - - - - message: "#^Parameter \\#2 \\$data of function unpack expects string, string\\|false given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/io/region/RegionLoader.php - - - - message: "#^Parameter \\#1 \\$start of method pocketmine\\\\utils\\\\Random\\:\\:nextRange\\(\\) expects int, float\\|int given\\.$#" - count: 2 - path: ../../../src/pocketmine/level/generator/object/TallGrass.php - - - - message: "#^Parameter \\#2 \\$end of method pocketmine\\\\utils\\\\Random\\:\\:nextRange\\(\\) expects int, float\\|int given\\.$#" - count: 2 - path: ../../../src/pocketmine/level/generator/object/TallGrass.php - - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\ChunkManager\\:\\:getBlockIdAt\\(\\) expects int, float\\|int given\\.$#" - count: 2 - path: ../../../src/pocketmine/level/generator/object/TallGrass.php - - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\ChunkManager\\:\\:setBlockIdAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/object/TallGrass.php - - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\ChunkManager\\:\\:setBlockDataAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/object/TallGrass.php - - - - message: "#^Method pocketmine\\\\metadata\\\\MetadataStore\\:\\:getMetadataInternal\\(\\) should return array\\ but returns array\\\\|SplObjectStorage\\.$#" - count: 1 - path: ../../../src/pocketmine/metadata/MetadataStore.php - - - - message: "#^Cannot call method count\\(\\) on array\\\\|SplObjectStorage\\.$#" - count: 1 - path: ../../../src/pocketmine/metadata/MetadataStore.php - - - - message: "#^Parameter \\#1 \\$str of method pocketmine\\\\utils\\\\BinaryStream\\:\\:put\\(\\) expects string, string\\|false given\\.$#" - count: 2 - path: ../../../src/pocketmine/network/mcpe/NetworkBinaryStream.php - - - - message: "#^Method pocketmine\\\\network\\\\mcpe\\\\NetworkBinaryStream\\:\\:getGameRules\\(\\) should return array\\ but returns array\\\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/NetworkBinaryStream.php - - - - message: "#^Parameter \\#1 \\$v of method pocketmine\\\\utils\\\\BinaryStream\\:\\:putBool\\(\\) expects bool, bool\\|float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/NetworkBinaryStream.php - - - - message: "#^Parameter \\#1 \\$v of method pocketmine\\\\utils\\\\BinaryStream\\:\\:putUnsignedVarInt\\(\\) expects int, bool\\|float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/NetworkBinaryStream.php - - - - message: "#^Parameter \\#1 \\$v of method pocketmine\\\\utils\\\\BinaryStream\\:\\:putLFloat\\(\\) expects float, bool\\|float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/NetworkBinaryStream.php - - - - message: "#^Offset 'chain' does not exist on array\\(\\?'chain' \\=\\> array\\\\)\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/VerifyLoginTask.php - - - - message: "#^Parameter \\#1 \\$json of function json_decode expects string, string\\|false given\\.$#" - count: 2 - path: ../../../src/pocketmine/network/mcpe/VerifyLoginTask.php - - - - message: "#^Parameter \\#1 \\$string of function strlen expects string, string\\|false given\\.$#" - count: 2 - path: ../../../src/pocketmine/network/mcpe/VerifyLoginTask.php - - - - message: "#^Parameter \\#1 \\$str of function str_split expects string, string\\|false given\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/VerifyLoginTask.php - - - - message: "#^Parameter \\#1 \\$str of method pocketmine\\\\utils\\\\BinaryStream\\:\\:put\\(\\) expects string, string\\|false given\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/AvailableActorIdentifiersPacket.php - - - - message: "#^Static property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\AvailableActorIdentifiersPacket\\:\\:\\$DEFAULT_NBT_CACHE \\(string\\|null\\) does not accept string\\|false\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/AvailableActorIdentifiersPacket.php - - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\BatchPacket\\:\\:\\$payload \\(string\\) does not accept string\\|false\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/BatchPacket.php - - - - message: "#^Parameter \\#1 \\$str of method pocketmine\\\\utils\\\\BinaryStream\\:\\:put\\(\\) expects string, string\\|false given\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/BiomeDefinitionListPacket.php - - - - message: "#^Static property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\BiomeDefinitionListPacket\\:\\:\\$DEFAULT_NBT_CACHE \\(string\\|null\\) does not accept string\\|false\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/BiomeDefinitionListPacket.php - - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\LevelEventGenericPacket\\:\\:\\$eventData \\(string\\) does not accept string\\|false\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/LevelEventGenericPacket.php - - - - message: "#^Static property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\StartGamePacket\\:\\:\\$blockTableCache \\(string\\|null\\) does not accept string\\|false\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/StartGamePacket.php - - - - message: "#^Parameter \\#1 \\$str of method pocketmine\\\\utils\\\\BinaryStream\\:\\:put\\(\\) expects string, string\\|false given\\.$#" - count: 2 - path: ../../../src/pocketmine/network/mcpe/protocol/StartGamePacket.php - - - - message: "#^Parameter \\#1 \\$json of function json_decode expects string, string\\|false given\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/StartGamePacket.php - - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\UpdateBlockPropertiesPacket\\:\\:\\$nbt \\(string\\) does not accept string\\|false\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/UpdateBlockPropertiesPacket.php + path: ../../../src/network/mcpe/auth/ProcessLoginTask.php - message: "#^Parameter \\#2 \\$resourcePatch of class pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\SkinData constructor expects string, string\\|false given\\.$#" count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/types/LegacySkinAdapter.php + path: ../../../src/network/mcpe/convert/LegacySkinAdapter.php - - message: "#^Parameter \\#1 \\$buffer of method pocketmine\\\\nbt\\\\NBTStream\\:\\:read\\(\\) expects string, string\\|false given\\.$#" + message: "#^Parameter \\#1 \\$buffer of method pocketmine\\\\nbt\\\\BaseNbtSerializer\\:\\:read\\(\\) expects string, string\\|false given\\.$#" count: 2 - path: ../../../src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php + path: ../../../src/network/mcpe/convert/RuntimeBlockMapping.php - - message: "#^Parameter \\#1 \\$json of function json_decode expects string, string\\|false given\\.$#" + message: "#^Method pocketmine\\\\network\\\\mcpe\\\\encryption\\\\EncryptionUtils\\:\\:generateKey\\(\\) should return string but returns string\\|false\\.$#" count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php + path: ../../../src/network/mcpe/encryption/EncryptionUtils.php + + - + message: "#^Parameter \\#1 \\$str of function substr expects string, string\\|false given\\.$#" + count: 1 + path: ../../../src/network/mcpe/encryption/NetworkCipher.php + + - + message: "#^Parameter \\#1 \\$v of method pocketmine\\\\utils\\\\BinaryStream\\:\\:putBool\\(\\) expects bool, bool\\|float\\|int given\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/serializer/NetworkBinaryStream.php + + - + message: "#^Parameter \\#1 \\$v of method pocketmine\\\\utils\\\\BinaryStream\\:\\:putUnsignedVarInt\\(\\) expects int, bool\\|float\\|int given\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/serializer/NetworkBinaryStream.php + + - + message: "#^Parameter \\#1 \\$v of method pocketmine\\\\utils\\\\BinaryStream\\:\\:putLFloat\\(\\) expects float, bool\\|float\\|int given\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/serializer/NetworkBinaryStream.php + + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\NetworkBinaryStream\\:\\:putSignedBlockPosition\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\NetworkBinaryStream\\:\\:putSignedBlockPosition\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\NetworkBinaryStream\\:\\:putSignedBlockPosition\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php + + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\NetworkBinaryStream\\:\\:putBlockPosition\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\NetworkBinaryStream\\:\\:putBlockPosition\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\NetworkBinaryStream\\:\\:putBlockPosition\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php - message: "#^Call to an undefined method object\\:\\:Add\\(\\)\\.$#" count: 1 - path: ../../../src/pocketmine/network/upnp/UPnP.php + path: ../../../src/network/upnp/UPnP.php - message: "#^Call to an undefined method object\\:\\:Remove\\(\\)\\.$#" count: 1 - path: ../../../src/pocketmine/network/upnp/UPnP.php + path: ../../../src/network/upnp/UPnP.php - - message: "#^Parameter \\#1 \\$event of method pocketmine\\\\plugin\\\\PluginManager\\:\\:registerEvent\\(\\) expects class\\-string\\, class\\-string\\ given\\.$#" - count: 1 - path: ../../../src/pocketmine/plugin/PluginManager.php + message: "#^Array \\(array\\\\) does not accept key \\(int\\|string\\)\\.$#" + count: 3 + path: ../../../src/player/Player.php - message: "#^Parameter \\#1 \\$string of function strlen expects string, string\\|false given\\.$#" count: 2 - path: ../../../src/pocketmine/resourcepacks/ZippedResourcePack.php + path: ../../../src/resourcepacks/ZippedResourcePack.php - message: "#^Parameter \\#2 \\$subject of function preg_match expects string, string\\|false given\\.$#" count: 1 - path: ../../../src/pocketmine/resourcepacks/ZippedResourcePack.php + path: ../../../src/resourcepacks/ZippedResourcePack.php - message: "#^Property pocketmine\\\\resourcepacks\\\\ZippedResourcePack\\:\\:\\$fileResource \\(resource\\) does not accept resource\\|false\\.$#" count: 1 - path: ../../../src/pocketmine/resourcepacks/ZippedResourcePack.php + path: ../../../src/resourcepacks/ZippedResourcePack.php - message: "#^Method pocketmine\\\\resourcepacks\\\\ZippedResourcePack\\:\\:getPackSize\\(\\) should return int but returns int\\|false\\.$#" count: 1 - path: ../../../src/pocketmine/resourcepacks/ZippedResourcePack.php + path: ../../../src/resourcepacks/ZippedResourcePack.php - message: "#^Property pocketmine\\\\resourcepacks\\\\ZippedResourcePack\\:\\:\\$sha256 \\(string\\|null\\) does not accept string\\|false\\.$#" count: 1 - path: ../../../src/pocketmine/resourcepacks/ZippedResourcePack.php + path: ../../../src/resourcepacks/ZippedResourcePack.php - message: "#^Method pocketmine\\\\resourcepacks\\\\ZippedResourcePack\\:\\:getSha256\\(\\) should return string but returns string\\|false\\.$#" count: 1 - path: ../../../src/pocketmine/resourcepacks/ZippedResourcePack.php + path: ../../../src/resourcepacks/ZippedResourcePack.php - message: "#^Method pocketmine\\\\resourcepacks\\\\ZippedResourcePack\\:\\:getPackChunk\\(\\) should return string but returns string\\|false\\.$#" count: 1 - path: ../../../src/pocketmine/resourcepacks/ZippedResourcePack.php + path: ../../../src/resourcepacks/ZippedResourcePack.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getTileAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Cannot call method enqueue\\(\\) on array\\\\|SplQueue\\.$#" count: 1 - path: ../../../src/pocketmine/tile/Chest.php + path: ../../../src/scheduler/AsyncPool.php - - message: "#^Property pocketmine\\\\tile\\\\Chest\\:\\:\\$pairX \\(int\\|null\\) does not accept float\\|int\\.$#" - count: 2 - path: ../../../src/pocketmine/tile/Chest.php - - - - message: "#^Property pocketmine\\\\tile\\\\Chest\\:\\:\\$pairZ \\(int\\|null\\) does not accept float\\|int\\.$#" - count: 2 - path: ../../../src/pocketmine/tile/Chest.php - - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\BlockActorDataPacket\\:\\:\\$x \\(int\\) does not accept float\\|int\\.$#" + message: "#^Cannot call method count\\(\\) on array\\\\|SplQueue\\.$#" count: 1 - path: ../../../src/pocketmine/tile/Spawnable.php + path: ../../../src/scheduler/AsyncPool.php - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\BlockActorDataPacket\\:\\:\\$y \\(int\\) does not accept float\\|int\\.$#" + message: "#^Method pocketmine\\\\scheduler\\\\AsyncPool\\:\\:selectWorker\\(\\) should return int but returns int\\|string\\.$#" count: 1 - path: ../../../src/pocketmine/tile/Spawnable.php + path: ../../../src/scheduler/AsyncPool.php - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\BlockActorDataPacket\\:\\:\\$z \\(int\\) does not accept float\\|int\\.$#" - count: 1 - path: ../../../src/pocketmine/tile/Spawnable.php - - - - message: "#^Parameter \\#2 \\$value of class pocketmine\\\\nbt\\\\tag\\\\IntTag constructor expects int, float\\|int given\\.$#" + message: "#^Cannot call method isEmpty\\(\\) on array\\\\|SplQueue\\.$#" count: 3 - path: ../../../src/pocketmine/tile/Spawnable.php + path: ../../../src/scheduler/AsyncPool.php - - message: "#^Parameter \\#2 \\$value of method pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\:\\:setInt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Cannot call method bottom\\(\\) on array\\\\|SplQueue\\.$#" + count: 1 + path: ../../../src/scheduler/AsyncPool.php + + - + message: "#^Cannot call method dequeue\\(\\) on array\\\\|SplQueue\\.$#" + count: 2 + path: ../../../src/scheduler/AsyncPool.php + + - + message: "#^Method pocketmine\\\\block\\\\utils\\\\DyeColor\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" + count: 1 + path: ../../../src/block/utils/DyeColor.php + + - + message: "#^Method pocketmine\\\\block\\\\utils\\\\DyeColor\\:\\:fromString\\(\\) should return pocketmine\\\\block\\\\utils\\\\DyeColor but returns object\\.$#" + count: 1 + path: ../../../src/block/utils/DyeColor.php + + - + message: "#^Method pocketmine\\\\block\\\\utils\\\\SkullType\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" + count: 1 + path: ../../../src/block/utils/SkullType.php + + - + message: "#^Method pocketmine\\\\block\\\\utils\\\\SkullType\\:\\:fromString\\(\\) should return pocketmine\\\\block\\\\utils\\\\SkullType but returns object\\.$#" + count: 1 + path: ../../../src/block/utils/SkullType.php + + - + message: "#^Method pocketmine\\\\block\\\\utils\\\\SlabType\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" + count: 1 + path: ../../../src/block/utils/SlabType.php + + - + message: "#^Method pocketmine\\\\block\\\\utils\\\\SlabType\\:\\:fromString\\(\\) should return pocketmine\\\\block\\\\utils\\\\SlabType but returns object\\.$#" + count: 1 + path: ../../../src/block/utils/SlabType.php + + - + message: "#^Method pocketmine\\\\block\\\\utils\\\\StairShape\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" + count: 1 + path: ../../../src/block/utils/StairShape.php + + - + message: "#^Method pocketmine\\\\block\\\\utils\\\\StairShape\\:\\:fromString\\(\\) should return pocketmine\\\\block\\\\utils\\\\StairShape but returns object\\.$#" + count: 1 + path: ../../../src/block/utils/StairShape.php + + - + message: "#^Method pocketmine\\\\block\\\\utils\\\\TreeType\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" + count: 1 + path: ../../../src/block/utils/TreeType.php + + - + message: "#^Method pocketmine\\\\block\\\\utils\\\\TreeType\\:\\:fromString\\(\\) should return pocketmine\\\\block\\\\utils\\\\TreeType but returns object\\.$#" + count: 1 + path: ../../../src/block/utils/TreeType.php + + - + message: "#^Method pocketmine\\\\item\\\\ItemUseResult\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" + count: 1 + path: ../../../src/item/ItemUseResult.php + + - + message: "#^Method pocketmine\\\\item\\\\ItemUseResult\\:\\:fromString\\(\\) should return pocketmine\\\\item\\\\ItemUseResult but returns object\\.$#" + count: 1 + path: ../../../src/item/ItemUseResult.php + + - + message: "#^Method pocketmine\\\\item\\\\ToolTier\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" + count: 1 + path: ../../../src/item/ToolTier.php + + - + message: "#^Method pocketmine\\\\item\\\\ToolTier\\:\\:fromString\\(\\) should return pocketmine\\\\item\\\\ToolTier but returns object\\.$#" + count: 1 + path: ../../../src/item/ToolTier.php + + - + message: "#^Method pocketmine\\\\player\\\\GameMode\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" + count: 1 + path: ../../../src/player/GameMode.php + + - + message: "#^Method pocketmine\\\\player\\\\GameMode\\:\\:fromString\\(\\) should return pocketmine\\\\player\\\\GameMode but returns object\\.$#" + count: 1 + path: ../../../src/player/GameMode.php + + - + message: "#^Method pocketmine\\\\player\\\\UsedChunkStatus\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" + count: 1 + path: ../../../src/player/UsedChunkStatus.php + + - + message: "#^Method pocketmine\\\\player\\\\UsedChunkStatus\\:\\:fromString\\(\\) should return pocketmine\\\\player\\\\UsedChunkStatus but returns object\\.$#" + count: 1 + path: ../../../src/player/UsedChunkStatus.php + + - + message: "#^Method pocketmine\\\\plugin\\\\PluginLoadOrder\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" + count: 1 + path: ../../../src/plugin/PluginLoadOrder.php + + - + message: "#^Method pocketmine\\\\plugin\\\\PluginLoadOrder\\:\\:fromString\\(\\) should return pocketmine\\\\plugin\\\\PluginLoadOrder but returns object\\.$#" + count: 1 + path: ../../../src/plugin/PluginLoadOrder.php + + - + message: "#^Method pocketmine\\\\utils\\\\TestEnum\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" + count: 1 + path: ../../phpunit/utils/TestEnum.php + + - + message: "#^Method pocketmine\\\\utils\\\\TestEnum\\:\\:fromString\\(\\) should return pocketmine\\\\utils\\\\TestEnum but returns object\\.$#" + count: 1 + path: ../../phpunit/utils/TestEnum.php + + - + message: "#^Method pocketmine\\\\world\\\\sound\\\\NoteInstrument\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" + count: 1 + path: ../../../src/world/sound/NoteInstrument.php + + - + message: "#^Method pocketmine\\\\world\\\\sound\\\\NoteInstrument\\:\\:fromString\\(\\) should return pocketmine\\\\world\\\\sound\\\\NoteInstrument but returns object\\.$#" + count: 1 + path: ../../../src/world/sound/NoteInstrument.php + + - + message: "#^Parameter \\#2 \\$subject of function preg_match expects string, string\\|false given\\.$#" + count: 1 + path: ../../../src/utils/Filesystem.php + + - + message: "#^Parameter \\#1 \\$haystack of function strpos expects string, string\\|false given\\.$#" + count: 1 + path: ../../../src/utils/Timezone.php + + - + message: "#^Parameter \\#1 \\$abbr of function timezone_name_from_abbr expects string, string\\|false given\\.$#" + count: 1 + path: ../../../src/utils/Timezone.php + + - + message: "#^Parameter \\#1 \\$timezone_identifier of function date_default_timezone_set expects string, string\\|false given\\.$#" + count: 1 + path: ../../../src/utils/Timezone.php + + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getTileAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/Explosion.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getTileAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/Explosion.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getTileAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/Explosion.php + + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:setBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/Explosion.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:setBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/Explosion.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:setBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/Explosion.php + + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:updateAllLight\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/Explosion.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:updateAllLight\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/Explosion.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:updateAllLight\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/Explosion.php + + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/Explosion.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/Explosion.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/Explosion.php + + - + message: "#^Parameter \\#1 \\$x of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/Explosion.php + + - + message: "#^Parameter \\#2 \\$y of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/Explosion.php + + - + message: "#^Parameter \\#3 \\$z of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/Explosion.php + + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/Explosion.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/Explosion.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/Explosion.php + + - + message: "#^Parameter \\#2 \\$generatorClass of class pocketmine\\\\world\\\\generator\\\\GeneratorRegisterTask constructor expects string, pocketmine\\\\world\\\\generator\\\\Generator\\|string given\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#1 \\$x of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" count: 3 - path: ../../../src/pocketmine/tile/Tile.php + path: ../../../src/world/World.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/tile/Tile.php + message: "#^Parameter \\#2 \\$y of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" + count: 3 + path: ../../../src/world/World.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/pocketmine/tile/Tile.php + message: "#^Parameter \\#3 \\$z of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" + count: 3 + path: ../../../src/world/World.php - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 1 - path: ../../../src/pocketmine/tile/Tile.php + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#1 \\$x of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\UpdateBlockPacket\\:\\:create\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#2 \\$y of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\UpdateBlockPacket\\:\\:create\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#3 \\$z of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\UpdateBlockPacket\\:\\:create\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getTileAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getTileAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getTileAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#1 \\$x of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\BlockActorDataPacket\\:\\:create\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#2 \\$y of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\BlockActorDataPacket\\:\\:create\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#3 \\$z of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\BlockActorDataPacket\\:\\:create\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" + count: 3 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" + count: 3 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" + count: 3 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#6 \\$xpDrops of class pocketmine\\\\event\\\\block\\\\BlockBreakEvent constructor expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#2 \\$amount of method pocketmine\\\\world\\\\World\\:\\:dropExperience\\(\\) expects int, float\\|int\\<1, max\\> given\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#2 \\$x of method pocketmine\\\\block\\\\Block\\:\\:position\\(\\) expects int, float\\|int given\\.$#" + count: 2 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#3 \\$y of method pocketmine\\\\block\\\\Block\\:\\:position\\(\\) expects int, float\\|int given\\.$#" + count: 2 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#4 \\$z of method pocketmine\\\\block\\\\Block\\:\\:position\\(\\) expects int, float\\|int given\\.$#" + count: 2 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#1 \\$x of static method pocketmine\\\\world\\\\format\\\\Chunk\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" + count: 2 + path: ../../../src/world/format/Chunk.php + + - + message: "#^Parameter \\#2 \\$y of static method pocketmine\\\\world\\\\format\\\\Chunk\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" + count: 2 + path: ../../../src/world/format/Chunk.php + + - + message: "#^Parameter \\#3 \\$z of static method pocketmine\\\\world\\\\format\\\\Chunk\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" + count: 2 + path: ../../../src/world/format/Chunk.php + + - + message: "#^Method pocketmine\\\\world\\\\format\\\\io\\\\ChunkUtils\\:\\:convertBiomeColors\\(\\) should return string but returns array\\\\|string\\.$#" + count: 1 + path: ../../../src/world/format/io/ChunkUtils.php + + - + message: "#^Parameter \\#1 \\$className of static method pocketmine\\\\utils\\\\Utils\\:\\:testValidInstance\\(\\) expects class\\-string, string given\\.$#" + count: 1 + path: ../../../src/world/format/io/FormatConverter.php + + - + message: "#^Only numeric types are allowed in %, int\\|false given on the left side\\.$#" + count: 1 + path: ../../../src/world/format/io/region/RegionLoader.php + + - + message: "#^Parameter \\#1 \\$string of function strlen expects string, string\\|false given\\.$#" + count: 1 + path: ../../../src/world/format/io/region/RegionLoader.php + + - + message: "#^Parameter \\#2 \\$data of function unpack expects string, string\\|false given\\.$#" + count: 1 + path: ../../../src/world/format/io/region/RegionLoader.php + + - + message: "#^Argument of an invalid type array\\\\|false supplied for foreach, only iterables are supported\\.$#" + count: 1 + path: ../../../src/world/format/io/region/RegionWorldProvider.php + + - + message: "#^Only numeric types are allowed in \\+, int\\|false given on the left side\\.$#" + count: 1 + path: ../../../src/world/format/io/region/RegionWorldProvider.php + + - + message: "#^Parameter \\#1 \\$start of method pocketmine\\\\utils\\\\Random\\:\\:nextRange\\(\\) expects int, float\\|int given\\.$#" + count: 2 + path: ../../../src/world/generator/object/TallGrass.php + + - + message: "#^Parameter \\#2 \\$end of method pocketmine\\\\utils\\\\Random\\:\\:nextRange\\(\\) expects int, float\\|int given\\.$#" + count: 2 + path: ../../../src/world/generator/object/TallGrass.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\ChunkManager\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 2 + path: ../../../src/world/generator/object/TallGrass.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\ChunkManager\\:\\:setBlockAt\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/world/generator/object/TallGrass.php + + - + message: "#^Parameter \\#1 \\$json of function json_decode expects string, string\\|false given\\.$#" + count: 1 + path: ../../phpunit/block/BlockTest.php + + - + message: "#^Parameter \\#1 \\$json of function json_decode expects string, string\\|false given\\.$#" + count: 1 + path: ../../phpunit/block/regenerate_consistency_check.php + + - + message: "#^Parameter \\#1 \\$logFile of class pocketmine\\\\utils\\\\MainLogger constructor expects string, string\\|false given\\.$#" + count: 1 + path: ../../phpunit/scheduler/AsyncPoolTest.php diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index ee06cb56c4..5a522407c7 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -11,1827 +11,1462 @@ parameters: path: ../../../build/server-phar.php - - message: "#^Parameter \\#1 \\$uuid of method pocketmine\\\\Server\\:\\:updatePlayerListData\\(\\) expects pocketmine\\\\utils\\\\UUID, pocketmine\\\\utils\\\\UUID\\|null given\\.$#" + message: "#^Parameter \\#1 \\$name of static method pocketmine\\\\world\\\\generator\\\\GeneratorManager\\:\\:getGenerator\\(\\) expects string, string\\|null given\\.$#" count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method sendTime\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method sendDifficulty\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method getChunkEntities\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 4 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method unregisterChunkLoader\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method registerChunkLoader\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method populateChunk\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method requestChunk\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Method pocketmine\\\\Player\\:\\:getSpawn\\(\\) should return pocketmine\\\\level\\\\Position but returns pocketmine\\\\level\\\\Position\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method getSafeSpawn\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 3 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method getBlock\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 6 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method setSleepTicks\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method getCollisionBlocks\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method getNearbyEntities\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method isChunkGenerated\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method isInLoadedTerrain\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method equals\\(\\) on pocketmine\\\\utils\\\\UUID\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Only numeric types are allowed in \\-, int\\|null given on the left side\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Only numeric types are allowed in \\-, int\\|null given on the right side\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method getFolderName\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method getAllValues\\(\\) on pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Parameter \\#1 \\$level of method pocketmine\\\\entity\\\\Human\\:\\:__construct\\(\\) expects pocketmine\\\\level\\\\Level, pocketmine\\\\level\\\\Level\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method getDifficulty\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method getTime\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method getName\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method useItemOn\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method sendBlocks\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method useBreakOn\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method getTile\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method getEntity\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method getBlockAt\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method checkSpawnProtection\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 3 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method broadcastLevelEvent\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 3 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method dropItem\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 3 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method getTileAt\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method getLevelNonNull\\(\\) on pocketmine\\\\level\\\\Position\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method getFloorX\\(\\) on pocketmine\\\\level\\\\Position\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method getFloorY\\(\\) on pocketmine\\\\level\\\\Position\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method getFloorZ\\(\\) on pocketmine\\\\level\\\\Position\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot access property \\$x on pocketmine\\\\level\\\\Position\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot access property \\$y on pocketmine\\\\level\\\\Position\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot access property \\$z on pocketmine\\\\level\\\\Position\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method dropExperience\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Player.php - - - - message: "#^Cannot call method getSafeSpawn\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Server.php - - - - message: "#^Cannot call method getFolderName\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Server.php - - - - message: "#^Cannot call method wait\\(\\) on Threaded\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/Server.php - - - - message: "#^Parameter \\#1 \\$name of static method pocketmine\\\\level\\\\generator\\\\GeneratorManager\\:\\:getGenerator\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/Server.php - - - - message: "#^Parameter \\#1 \\$uuid of method pocketmine\\\\Server\\:\\:updatePlayerListData\\(\\) expects pocketmine\\\\utils\\\\UUID, pocketmine\\\\utils\\\\UUID\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/Server.php - - - - message: "#^Parameter \\#1 \\$uuid of method pocketmine\\\\Server\\:\\:removePlayerListData\\(\\) expects pocketmine\\\\utils\\\\UUID, pocketmine\\\\utils\\\\UUID\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/Server.php - - - - message: "#^Parameter \\#1 \\$uuid of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\PlayerListEntry\\:\\:createAdditionEntry\\(\\) expects pocketmine\\\\utils\\\\UUID, pocketmine\\\\utils\\\\UUID\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/Server.php - - - - message: "#^Parameter \\#1 \\$options of method Thread\\:\\:start\\(\\) expects int, int\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/Thread.php - - - - message: "#^Parameter \\#1 \\$options of method Thread\\:\\:start\\(\\) expects int, int\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/Worker.php + path: ../../../src/Server.php - message: "#^Parameter \\#1 \\$constraint of method pocketmine\\\\block\\\\BaseRail\\:\\:getPossibleConnectionDirectionsOneConstraint\\(\\) expects int, int\\|null given\\.$#" count: 1 - path: ../../../src/pocketmine/block/BaseRail.php + path: ../../../src/block/BaseRail.php - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" + message: "#^Cannot call method setFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" count: 1 - path: ../../../src/pocketmine/block/BaseRail.php + path: ../../../src/block/Block.php - - message: "#^Only numeric types are allowed in \\-, int\\|null given on the left side\\.$#" + message: "#^Parameter \\#2 \\$world of method pocketmine\\\\block\\\\tile\\\\TileFactory\\:\\:create\\(\\) expects pocketmine\\\\world\\\\World, pocketmine\\\\world\\\\World\\|null given\\.$#" count: 1 - path: ../../../src/pocketmine/block/Bed.php + path: ../../../src/block/Block.php - - message: "#^Cannot call method getBlockMetadata\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 4 - path: ../../../src/pocketmine/block/Block.php - - - - message: "#^Cannot clone pocketmine\\\\block\\\\Block\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/BlockFactory.php - - - - message: "#^Cannot access property \\$x on pocketmine\\\\block\\\\Block\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/BlockFactory.php - - - - message: "#^Cannot access property \\$y on pocketmine\\\\block\\\\Block\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/BlockFactory.php - - - - message: "#^Cannot access property \\$z on pocketmine\\\\block\\\\Block\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/BlockFactory.php - - - - message: "#^Cannot access property \\$level on pocketmine\\\\block\\\\Block\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/BlockFactory.php - - - - message: "#^Method pocketmine\\\\block\\\\BlockFactory\\:\\:get\\(\\) should return pocketmine\\\\block\\\\Block but returns pocketmine\\\\block\\\\Block\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/BlockFactory.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/Button.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/Cake.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/ConcretePowder.php - - - - message: "#^Only numeric types are allowed in \\+, int\\|null given on the left side\\.$#" - count: 1 - path: ../../../src/pocketmine/block/Door.php - - - - message: "#^Cannot call method getDirection\\(\\) on pocketmine\\\\Player\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/Door.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/block/Door.php - - - - message: "#^Cannot call method addSound\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/block/Door.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/EndRod.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/Fallable.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 4 - path: ../../../src/pocketmine/block/Farmland.php - - - - message: "#^Cannot call method getBlockIdAt\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/Farmland.php - - - - message: "#^Only numeric types are allowed in \\-, int\\|null given on the left side\\.$#" - count: 2 - path: ../../../src/pocketmine/block/FenceGate.php - - - - message: "#^Cannot call method addSound\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/FenceGate.php - - - - message: "#^Cannot call method scheduleDelayedBlockUpdate\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/block/Fire.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 3 - path: ../../../src/pocketmine/block/Fire.php - - - - message: "#^Only numeric types are allowed in \\-, int\\|null given on the left side\\.$#" - count: 1 - path: ../../../src/pocketmine/block/GlazedTerracotta.php - - - - message: "#^Cannot call method getFullLightAt\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/block/Grass.php - - - - message: "#^Cannot call method getBlockIdAt\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 3 - path: ../../../src/pocketmine/block/Grass.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/block/Grass.php - - - - message: "#^Cannot call method getBlockDataAt\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/Grass.php - - - - message: "#^Cannot call method getBlockAt\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/Grass.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/GrassPath.php - - - - message: "#^Cannot call method getHighestAdjacentBlockLight\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/Ice.php - - - - message: "#^Cannot call method useBreakOn\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/Ice.php - - - - message: "#^Cannot call method getTile\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/block/ItemFrame.php - - - - message: "#^Cannot call method useBreakOn\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/ItemFrame.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/ItemFrame.php - - - - message: "#^Cannot call method useBreakOn\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/Ladder.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/Lever.php - - - - message: "#^Cannot call method useBreakOn\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/Lever.php - - - - message: "#^Cannot call method getBlockAt\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 25 - path: ../../../src/pocketmine/block/Liquid.php - - - - message: "#^Cannot call method scheduleDelayedBlockUpdate\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 3 - path: ../../../src/pocketmine/block/Liquid.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 4 - path: ../../../src/pocketmine/block/Liquid.php - - - - message: "#^Cannot call method useBreakOn\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/Liquid.php - - - - message: "#^Cannot call method addSound\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/Liquid.php - - - - message: "#^Cannot call method getFullLightAt\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/Sapling.php - - - - message: "#^Cannot call method getTile\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/Skull.php - - - - message: "#^Cannot call method getBlockLightAt\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/SnowLayer.php - - - - message: "#^Cannot call method getTile\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/StandingBanner.php - - - - message: "#^Cannot call method addSound\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/Trapdoor.php - - - - message: "#^Cannot call method useBreakOn\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/Vine.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/block/Vine.php - - - - message: "#^Parameter \\#2 \\$replace of function str_replace expects array\\|string, string\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/command/Command.php - - - - message: "#^Cannot call method startTiming\\(\\) on pocketmine\\\\timings\\\\TimingsHandler\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/command/SimpleCommandMap.php - - - - message: "#^Cannot call method stopTiming\\(\\) on pocketmine\\\\timings\\\\TimingsHandler\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/command/SimpleCommandMap.php - - - - message: "#^Parameter \\#1 \\$target of method pocketmine\\\\permission\\\\BanList\\:\\:addBan\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/command/defaults/BanCommand.php - - - - message: "#^Parameter \\#1 \\$name of method pocketmine\\\\Server\\:\\:getPlayerExact\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/command/defaults/BanCommand.php - - - - message: "#^Parameter \\#2 \\$subject of function preg_match expects string, string\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/command/defaults/BanIpCommand.php - - - - message: "#^Parameter \\#1 \\$ip of method pocketmine\\\\command\\\\defaults\\\\BanIpCommand\\:\\:processIPBan\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/command/defaults/BanIpCommand.php - - - - message: "#^Parameter \\#1 \\$name of method pocketmine\\\\Server\\:\\:getPlayer\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/command/defaults/BanIpCommand.php - - - - message: "#^Parameter \\#1 \\$name of method pocketmine\\\\Server\\:\\:getOfflinePlayer\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/command/defaults/DeopCommand.php - - - - message: "#^Parameter \\#1 \\$name of method pocketmine\\\\Server\\:\\:getPlayer\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/command/defaults/KickCommand.php - - - - message: "#^Parameter \\#1 \\$name of method pocketmine\\\\Server\\:\\:getOfflinePlayer\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/command/defaults/OpCommand.php - - - - message: "#^Cannot call method addParticle\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/command/defaults/ParticleCommand.php - - - - message: "#^Cannot call method getSeed\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/command/defaults/SeedCommand.php - - - - message: "#^Cannot call method setSpawnLocation\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/command/defaults/SetWorldSpawnCommand.php - - - - message: "#^Cannot call method getSpawnLocation\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/command/defaults/SpawnpointCommand.php - - - - message: "#^Parameter \\#1 \\$name of method pocketmine\\\\Server\\:\\:getPlayer\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/command/defaults/TellCommand.php - - - - message: "#^Cannot call method getTime\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/command/defaults/TimeCommand.php - - - - message: "#^Cannot call method getValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 4 - path: ../../../src/pocketmine/entity/Effect.php - - - - message: "#^Cannot call method setValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 4 - path: ../../../src/pocketmine/entity/Effect.php - - - - message: "#^Cannot call method getAllValues\\(\\) on pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null\\.$#" - count: 3 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Cannot call method getChunkAtPosition\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Cannot call method addEntity\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Cannot call method addEntity\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Method pocketmine\\\\entity\\\\Entity\\:\\:getNameTag\\(\\) should return string but returns string\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Method pocketmine\\\\entity\\\\Entity\\:\\:getScale\\(\\) should return float but returns float\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Cannot call method getValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Cannot call method setValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Parameter \\#2 \\$value of method pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\:\\:setShort\\(\\) expects int, int\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Cannot call method broadcastPacketToViewers\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Cannot call method getBlockAt\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 4 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Cannot call method getCollisionCubes\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 4 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Cannot call method getBlockIdAt\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 7 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Only booleans are allowed in an if condition, bool\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Only booleans are allowed in a negated boolean, bool\\|null given\\.$#" - count: 6 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Cannot access property \\$updateEntities on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Cannot call method getCollisionBlocks\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Cannot call method getTickRateTime\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Cannot call method getChunk\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Cannot call method getViewersForPosition\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Parameter \\#2 \\$originLevel of class pocketmine\\\\event\\\\entity\\\\EntityLevelChangeEvent constructor expects pocketmine\\\\level\\\\Level, pocketmine\\\\level\\\\Level\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Cannot call method removeEntity\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/entity/Entity.php - - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\PlayerSkinPacket\\:\\:\\$uuid \\(pocketmine\\\\utils\\\\UUID\\) does not accept pocketmine\\\\utils\\\\UUID\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Human.php - - - - message: "#^Cannot call method getValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 8 - path: ../../../src/pocketmine/entity/Human.php - - - - message: "#^Cannot call method setValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 6 - path: ../../../src/pocketmine/entity/Human.php - - - - message: "#^Cannot call method getMaxValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/entity/Human.php - - - - message: "#^Cannot call method getMinValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Human.php - - - - message: "#^Cannot call method broadcastLevelEvent\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/entity/Human.php - - - - message: "#^Cannot call method broadcastLevelSoundEvent\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Human.php - - - - message: "#^Parameter \\#1 \\$attribute of method pocketmine\\\\entity\\\\AttributeMap\\:\\:addAttribute\\(\\) expects pocketmine\\\\entity\\\\Attribute, pocketmine\\\\entity\\\\Attribute\\|null given\\.$#" - count: 5 - path: ../../../src/pocketmine/entity/Human.php - - - - message: "#^Cannot call method getDifficulty\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Human.php - - - - message: "#^Parameter \\#1 \\$effectType of class pocketmine\\\\entity\\\\EffectInstance constructor expects pocketmine\\\\entity\\\\Effect, pocketmine\\\\entity\\\\Effect\\|null given\\.$#" - count: 3 - path: ../../../src/pocketmine/entity/Human.php - - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\AddPlayerPacket\\:\\:\\$uuid \\(pocketmine\\\\utils\\\\UUID\\) does not accept pocketmine\\\\utils\\\\UUID\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Human.php - - - - message: "#^Cannot call method getValue\\(\\) on pocketmine\\\\nbt\\\\tag\\\\NamedTag\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Living.php - - - - message: "#^Parameter \\#1 \\$attribute of method pocketmine\\\\entity\\\\AttributeMap\\:\\:addAttribute\\(\\) expects pocketmine\\\\entity\\\\Attribute, pocketmine\\\\entity\\\\Attribute\\|null given\\.$#" - count: 6 - path: ../../../src/pocketmine/entity/Living.php - - - - message: "#^Cannot call method setValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/entity/Living.php - - - - message: "#^Cannot call method getMaxValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Living.php - - - - message: "#^Cannot call method setMaxValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Living.php - - - - message: "#^Cannot call method getValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/entity/Living.php - - - - message: "#^Cannot call method getEffectLevel\\(\\) on pocketmine\\\\entity\\\\EffectInstance\\|null\\.$#" - count: 3 - path: ../../../src/pocketmine/entity/Living.php - - - - message: "#^Cannot call method attack\\(\\) on pocketmine\\\\entity\\\\Entity\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Living.php - - - - message: "#^Parameter \\#2 \\$entity of class pocketmine\\\\event\\\\entity\\\\EntityDamageByEntityEvent constructor expects pocketmine\\\\entity\\\\Entity, pocketmine\\\\entity\\\\Entity\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Living.php - - - - message: "#^Cannot call method broadcastLevelSoundEvent\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Living.php - - - - message: "#^Cannot call method getDifficulty\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Living.php - - - - message: "#^Cannot call method dropExperience\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Living.php - - - - message: "#^Method pocketmine\\\\entity\\\\Living\\:\\:getAirSupplyTicks\\(\\) should return int but returns int\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Living.php - - - - message: "#^Method pocketmine\\\\entity\\\\Living\\:\\:getMaxAirSupplyTicks\\(\\) should return int but returns int\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Living.php - - - - message: "#^Cannot call method getBlockAt\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Living.php - - - - message: "#^Method pocketmine\\\\entity\\\\Villager\\:\\:getProfession\\(\\) should return int but returns int\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/Villager.php - - - - message: "#^Cannot call method getEntity\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/object/ExperienceOrb.php - - - - message: "#^Cannot call method getNearestEntity\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/object/ExperienceOrb.php - - - - message: "#^Cannot call method getBlock\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/object/FallingBlock.php - - - - message: "#^Cannot call method dropItem\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/object/Painting.php - - - - message: "#^Cannot call method addParticle\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/object/Painting.php - - - - message: "#^Parameter \\#1 \\$level of static method pocketmine\\\\entity\\\\object\\\\Painting\\:\\:canFit\\(\\) expects pocketmine\\\\level\\\\Level, pocketmine\\\\level\\\\Level\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/object/Painting.php - - - - message: "#^Method pocketmine\\\\entity\\\\object\\\\Painting\\:\\:getMotive\\(\\) should return pocketmine\\\\entity\\\\object\\\\PaintingMotive but returns pocketmine\\\\entity\\\\object\\\\PaintingMotive\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/object/Painting.php - - - - message: "#^Cannot call method broadcastLevelEvent\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/object/PrimedTNT.php - - - - message: "#^Cannot call method broadcastLevelSoundEvent\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/projectile/Arrow.php - - - - message: "#^Cannot call method addParticle\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/projectile/Egg.php - - - - message: "#^Cannot call method broadcastLevelEvent\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/projectile/EnderPearl.php - - - - message: "#^Cannot call method addSound\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/entity/projectile/EnderPearl.php - - - - message: "#^Cannot call method broadcastLevelEvent\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/projectile/ExperienceBottle.php - - - - message: "#^Cannot call method broadcastLevelSoundEvent\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/projectile/ExperienceBottle.php - - - - message: "#^Cannot call method dropExperience\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/projectile/ExperienceBottle.php - - - - message: "#^Parameter \\#2 \\$value of method pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\:\\:setInt\\(\\) expects int, int\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/projectile/Projectile.php - - - - message: "#^Parameter \\#2 \\$value of method pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\:\\:setByte\\(\\) expects int, int\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/projectile/Projectile.php - - - - message: "#^Cannot call method getBlockAt\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/entity/projectile/Projectile.php - - - - message: "#^Cannot call method getCollidingEntities\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/projectile/Projectile.php - - - - message: "#^Cannot call method addParticle\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/projectile/Snowball.php - - - - message: "#^Cannot call method broadcastLevelEvent\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/projectile/SplashPotion.php - - - - message: "#^Cannot call method broadcastLevelSoundEvent\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/projectile/SplashPotion.php - - - - message: "#^Cannot call method getNearbyEntities\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/entity/projectile/SplashPotion.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/entity/projectile/SplashPotion.php - - - - message: "#^Cannot call method getEffectLevel\\(\\) on pocketmine\\\\entity\\\\EffectInstance\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/event/entity/EntityDamageByEntityEvent.php - - - - message: "#^Property pocketmine\\\\inventory\\\\BaseInventory\\:\\:\\$eventProcessor \\(pocketmine\\\\inventory\\\\InventoryEventProcessor\\) does not accept pocketmine\\\\inventory\\\\InventoryEventProcessor\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/inventory/BaseInventory.php - - - - message: "#^Method pocketmine\\\\inventory\\\\CraftingManager\\:\\:getCraftingDataPacket\\(\\) should return pocketmine\\\\network\\\\mcpe\\\\protocol\\\\BatchPacket but returns pocketmine\\\\network\\\\mcpe\\\\protocol\\\\BatchPacket\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/inventory/CraftingManager.php - - - - message: "#^Parameter \\#2 \\$recipe of class pocketmine\\\\event\\\\inventory\\\\CraftItemEvent constructor expects pocketmine\\\\inventory\\\\CraftingRecipe, pocketmine\\\\inventory\\\\CraftingRecipe\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/inventory/transaction/CraftingTransaction.php - - - - message: "#^Parameter \\#3 \\$repetitions of class pocketmine\\\\event\\\\inventory\\\\CraftItemEvent constructor expects int, int\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/inventory/transaction/CraftingTransaction.php - - - - message: "#^Cannot call method isset\\(\\) on pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/item/Banner.php - - - - message: "#^Cannot call method count\\(\\) on pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/item/Banner.php - - - - message: "#^Parameter \\#2 \\$level of static method pocketmine\\\\entity\\\\Entity\\:\\:createEntity\\(\\) expects pocketmine\\\\level\\\\Level, pocketmine\\\\level\\\\Level\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/item/Bow.php - - - - message: "#^Cannot call method broadcastLevelSoundEvent\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/item/Bow.php - - - - message: "#^Cannot call method spawnToAll\\(\\) on pocketmine\\\\entity\\\\Entity\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/item/Bow.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/item/Bucket.php - - - - message: "#^Cannot call method broadcastLevelSoundEvent\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/item/Bucket.php - - - - message: "#^Parameter \\#1 \\$effectType of class pocketmine\\\\entity\\\\EffectInstance constructor expects pocketmine\\\\entity\\\\Effect, pocketmine\\\\entity\\\\Effect\\|null given\\.$#" - count: 2 - path: ../../../src/pocketmine/item/GoldenApple.php - - - - message: "#^Parameter \\#1 \\$effectType of class pocketmine\\\\entity\\\\EffectInstance constructor expects pocketmine\\\\entity\\\\Effect, pocketmine\\\\entity\\\\Effect\\|null given\\.$#" - count: 4 - path: ../../../src/pocketmine/item/GoldenAppleEnchanted.php - - - - message: "#^Parameter \\#1 \\$object of function get_class expects object, pocketmine\\\\nbt\\\\tag\\\\NamedTag\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/item/Item.php - - - - message: "#^Parameter \\#1 \\$level of static method pocketmine\\\\entity\\\\object\\\\Painting\\:\\:canFit\\(\\) expects pocketmine\\\\level\\\\Level, pocketmine\\\\level\\\\Level\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/item/PaintingItem.php - - - - message: "#^Cannot call method broadcastLevelEvent\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/item/PaintingItem.php - - - - message: "#^Parameter \\#1 \\$effectType of class pocketmine\\\\entity\\\\EffectInstance constructor expects pocketmine\\\\entity\\\\Effect, pocketmine\\\\entity\\\\Effect\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/item/PoisonousPotato.php - - - - message: "#^Parameter \\#1 \\$effectType of class pocketmine\\\\entity\\\\EffectInstance constructor expects pocketmine\\\\entity\\\\Effect, pocketmine\\\\entity\\\\Effect\\|null given\\.$#" - count: 32 - path: ../../../src/pocketmine/item/Potion.php - - - - message: "#^Parameter \\#2 \\$level of static method pocketmine\\\\entity\\\\Entity\\:\\:createEntity\\(\\) expects pocketmine\\\\level\\\\Level, pocketmine\\\\level\\\\Level\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/item/ProjectileItem.php - - - - message: "#^Cannot call method broadcastLevelSoundEvent\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/item/ProjectileItem.php - - - - message: "#^Parameter \\#1 \\$effectType of class pocketmine\\\\entity\\\\EffectInstance constructor expects pocketmine\\\\entity\\\\Effect, pocketmine\\\\entity\\\\Effect\\|null given\\.$#" - count: 3 - path: ../../../src/pocketmine/item/Pufferfish.php - - - - message: "#^Parameter \\#1 \\$effectType of class pocketmine\\\\entity\\\\EffectInstance constructor expects pocketmine\\\\entity\\\\Effect, pocketmine\\\\entity\\\\Effect\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/item/RawChicken.php - - - - message: "#^Parameter \\#1 \\$effectType of class pocketmine\\\\entity\\\\EffectInstance constructor expects pocketmine\\\\entity\\\\Effect, pocketmine\\\\entity\\\\Effect\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/item/RottenFlesh.php - - - - message: "#^Parameter \\#2 \\$level of static method pocketmine\\\\entity\\\\Entity\\:\\:createEntity\\(\\) expects pocketmine\\\\level\\\\Level, pocketmine\\\\level\\\\Level\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/item/SpawnEgg.php - - - - message: "#^Parameter \\#1 \\$effectType of class pocketmine\\\\entity\\\\EffectInstance constructor expects pocketmine\\\\entity\\\\Effect, pocketmine\\\\entity\\\\Effect\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/item/SpiderEye.php - - - - message: "#^Parameter \\#2 \\$pageText of method pocketmine\\\\item\\\\WritableBook\\:\\:setPageText\\(\\) expects string, string\\|null given\\.$#" - count: 2 - path: ../../../src/pocketmine/item/WritableBook.php - - - - message: "#^Method pocketmine\\\\item\\\\enchantment\\\\EnchantmentList\\:\\:getSlot\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\EnchantmentEntry but returns pocketmine\\\\item\\\\enchantment\\\\EnchantmentEntry\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/item/enchantment/EnchantmentList.php - - - - message: "#^Cannot call method getBlockId\\(\\) on pocketmine\\\\level\\\\format\\\\SubChunkInterface\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Only numeric types are allowed in /, float\\|null given on the left side\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Cannot call method getBlockData\\(\\) on pocketmine\\\\level\\\\format\\\\SubChunkInterface\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Explosion.php - - - - message: "#^Parameter \\#1 \\$chunk of method pocketmine\\\\Player\\:\\:onChunkChanged\\(\\) expects pocketmine\\\\level\\\\format\\\\Chunk, pocketmine\\\\level\\\\format\\\\Chunk\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot call method getFullBlock\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot clone pocketmine\\\\block\\\\Block\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot access property \\$x on pocketmine\\\\block\\\\Block\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot access property \\$y on pocketmine\\\\block\\\\Block\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot access property \\$z on pocketmine\\\\block\\\\Block\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot access property \\$level on pocketmine\\\\block\\\\Block\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Method pocketmine\\\\level\\\\Level\\:\\:getBlockAt\\(\\) should return pocketmine\\\\block\\\\Block but returns pocketmine\\\\block\\\\Block\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot call method recalculateHeightMapColumn\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Only numeric types are allowed in \\-, int\\|null given on the right side\\.$#" - count: 2 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#4 \\$newLevel of method pocketmine\\\\level\\\\light\\\\LightUpdate\\:\\:setAndUpdateLight\\(\\) expects int, int\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot call method getBlockId\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot call method setBlockId\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot call method getBlockData\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot call method setBlockData\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot call method getBlockSkyLight\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot call method setBlockSkyLight\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot call method getBlockLight\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot call method setBlockLight\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot call method getBiomeId\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot call method setBiomeId\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot call method getHeightMap\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot call method setHeightMap\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot call method getHighestBlockAt\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Cannot call method isPopulated\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Parameter \\#2 \\$chunk of class pocketmine\\\\level\\\\generator\\\\PopulationTask constructor expects pocketmine\\\\level\\\\format\\\\Chunk, pocketmine\\\\level\\\\format\\\\Chunk\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/Level.php - - - - message: "#^Method pocketmine\\\\level\\\\biome\\\\Biome\\:\\:getBiome\\(\\) should return pocketmine\\\\level\\\\biome\\\\Biome but returns pocketmine\\\\level\\\\biome\\\\Biome\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/biome/Biome.php - - - - message: "#^Method pocketmine\\\\level\\\\format\\\\Chunk\\:\\:getHeightMap\\(\\) should return int but returns int\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/Chunk.php - - - - message: "#^Cannot call method getValue\\(\\) on pocketmine\\\\nbt\\\\tag\\\\NamedTag\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/Chunk.php - - - - message: "#^Method pocketmine\\\\level\\\\format\\\\Chunk\\:\\:getSubChunk\\(\\) should return pocketmine\\\\level\\\\format\\\\SubChunkInterface but returns pocketmine\\\\level\\\\format\\\\SubChunkInterface\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/Chunk.php - - - - message: "#^Cannot call method networkSerialize\\(\\) on pocketmine\\\\level\\\\format\\\\SubChunkInterface\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/Chunk.php - - - - message: "#^Property pocketmine\\\\level\\\\format\\\\io\\\\BaseLevelProvider\\:\\:\\$levelData \\(pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\) does not accept pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/io/BaseLevelProvider.php - - - - message: "#^Cannot call method getListTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 3 - path: ../../../src/pocketmine/level/format/io/region/Anvil.php - - - - message: "#^Cannot call method hasTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 3 - path: ../../../src/pocketmine/level/format/io/region/Anvil.php - - - - message: "#^Cannot call method getIntArray\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/level/format/io/region/Anvil.php - - - - message: "#^Cannot call method getByteArray\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/io/region/Anvil.php - - - - message: "#^Cannot call method getInt\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/level/format/io/region/Anvil.php - - - - message: "#^Parameter \\#2 \\$list of static method pocketmine\\\\level\\\\format\\\\io\\\\region\\\\McRegion\\:\\:getCompoundList\\(\\) expects pocketmine\\\\nbt\\\\tag\\\\ListTag, pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null given\\.$#" - count: 2 - path: ../../../src/pocketmine/level/format/io/region/Anvil.php - - - - message: "#^Cannot call method getByte\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/level/format/io/region/Anvil.php - - - - message: "#^Cannot call method getBlockIdColumn\\(\\) on pocketmine\\\\level\\\\format\\\\SubChunkInterface\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/io/region/McRegion.php - - - - message: "#^Cannot call method getBlockDataColumn\\(\\) on pocketmine\\\\level\\\\format\\\\SubChunkInterface\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/io/region/McRegion.php - - - - message: "#^Cannot call method getBlockSkyLightColumn\\(\\) on pocketmine\\\\level\\\\format\\\\SubChunkInterface\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/io/region/McRegion.php - - - - message: "#^Cannot call method getBlockLightColumn\\(\\) on pocketmine\\\\level\\\\format\\\\SubChunkInterface\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/io/region/McRegion.php - - - - message: "#^Cannot call method getByteArray\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 6 - path: ../../../src/pocketmine/level/format/io/region/McRegion.php - - - - message: "#^Cannot call method hasTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 10 - path: ../../../src/pocketmine/level/format/io/region/McRegion.php - - - - message: "#^Cannot call method getIntArray\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/level/format/io/region/McRegion.php - - - - message: "#^Cannot call method getInt\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/level/format/io/region/McRegion.php - - - - message: "#^Cannot call method getListTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/level/format/io/region/McRegion.php - - - - message: "#^Parameter \\#2 \\$list of static method pocketmine\\\\level\\\\format\\\\io\\\\region\\\\McRegion\\:\\:getCompoundList\\(\\) expects pocketmine\\\\nbt\\\\tag\\\\ListTag, pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null given\\.$#" - count: 2 - path: ../../../src/pocketmine/level/format/io/region/McRegion.php - - - - message: "#^Cannot call method getByte\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/level/format/io/region/McRegion.php - - - - message: "#^Cannot call method readChunk\\(\\) on pocketmine\\\\level\\\\format\\\\io\\\\region\\\\RegionLoader\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/io/region/McRegion.php - - - - message: "#^Cannot call method writeChunk\\(\\) on pocketmine\\\\level\\\\format\\\\io\\\\region\\\\RegionLoader\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/format/io/region/McRegion.php - - - - message: "#^Cannot call method setGenerated\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/level/generator/PopulationTask.php - - - - message: "#^Cannot call method getX\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 5 - path: ../../../src/pocketmine/level/generator/PopulationTask.php - - - - message: "#^Cannot call method getZ\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 5 - path: ../../../src/pocketmine/level/generator/PopulationTask.php - - - - message: "#^Cannot call method isGenerated\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/PopulationTask.php - - - - message: "#^Cannot call method setPopulated\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/PopulationTask.php - - - - message: "#^Cannot call method recalculateHeightMap\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/PopulationTask.php - - - - message: "#^Cannot call method populateSkyLight\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/PopulationTask.php - - - - message: "#^Cannot call method setLightPopulated\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/PopulationTask.php - - - - message: "#^Cannot call method fastSerialize\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/level/generator/PopulationTask.php - - - - message: "#^Cannot call method hasChanged\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/PopulationTask.php - - - - message: "#^Cannot call method getAsyncWorkerId\\(\\) on pocketmine\\\\scheduler\\\\AsyncWorker\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/PopulationTask.php - - - - message: "#^Method pocketmine\\\\level\\\\generator\\\\biome\\\\BiomeSelector\\:\\:pickBiome\\(\\) should return pocketmine\\\\level\\\\biome\\\\Biome but returns pocketmine\\\\level\\\\biome\\\\Biome\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/biome/BiomeSelector.php - - - - message: "#^Cannot call method setBiomeId\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/hell/Nether.php - - - - message: "#^Cannot call method setBlockId\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 3 - path: ../../../src/pocketmine/level/generator/hell/Nether.php - - - - message: "#^Cannot call method getBiomeId\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/hell/Nether.php - - - - message: "#^Cannot call method setBiomeId\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/normal/Normal.php - - - - message: "#^Offset int does not exist on array\\\\>\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/normal/Normal.php - - - - message: "#^Cannot call method setBlockId\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 3 - path: ../../../src/pocketmine/level/generator/normal/Normal.php - - - - message: "#^Cannot call method getBiomeId\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/normal/Normal.php - - - - message: "#^Only booleans are allowed in a negated boolean, bool\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/object/SpruceTree.php - - - - message: "#^Only booleans are allowed in a negated boolean, bool\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/object/Tree.php - - - - message: "#^Cannot call method getBiomeId\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/populator/GroundCover.php - - - - message: "#^Cannot call method getBlockIdColumn\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/populator/GroundCover.php - - - - message: "#^Cannot call method setBlockId\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/populator/GroundCover.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\level\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/generator/populator/GroundCover.php - - - - message: "#^Cannot call method getBlockLight\\(\\) on pocketmine\\\\level\\\\format\\\\SubChunkInterface\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/light/BlockLightUpdate.php - - - - message: "#^Cannot call method setBlockLight\\(\\) on pocketmine\\\\level\\\\format\\\\SubChunkInterface\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/light/BlockLightUpdate.php - - - - message: "#^Cannot call method getBlockId\\(\\) on pocketmine\\\\level\\\\format\\\\SubChunkInterface\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/light/LightUpdate.php - - - - message: "#^Only numeric types are allowed in \\-, int\\|null given on the right side\\.$#" - count: 1 - path: ../../../src/pocketmine/level/light/LightUpdate.php - - - - message: "#^Cannot call method getBlockSkyLight\\(\\) on pocketmine\\\\level\\\\format\\\\SubChunkInterface\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/light/SkyLightUpdate.php - - - - message: "#^Cannot call method setBlockSkyLight\\(\\) on pocketmine\\\\level\\\\format\\\\SubChunkInterface\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/level/light/SkyLightUpdate.php - - - - message: "#^Cannot call method getTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/NetworkBinaryStream.php - - - - message: "#^Cannot call method removeTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/NetworkBinaryStream.php - - - - message: "#^Cannot call method setTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/NetworkBinaryStream.php - - - - message: "#^Parameter \\#1 \\$eid of method pocketmine\\\\network\\\\mcpe\\\\NetworkBinaryStream\\:\\:putEntityUniqueId\\(\\) expects int, int\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/SetScorePacket.php - - - - message: "#^Parameter \\#1 \\$v of method pocketmine\\\\network\\\\mcpe\\\\NetworkBinaryStream\\:\\:putString\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/SetScorePacket.php - - - - message: "#^Parameter \\#1 \\$eid of method pocketmine\\\\network\\\\mcpe\\\\NetworkBinaryStream\\:\\:putEntityUniqueId\\(\\) expects int, int\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/SetScoreboardIdentityPacket.php - - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\EntityLink\\:\\:\\$fromEntityUniqueId \\(int\\) does not accept int\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/types/EntityLink.php - - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\EntityLink\\:\\:\\$toEntityUniqueId \\(int\\) does not accept int\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/types/EntityLink.php - - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\EntityLink\\:\\:\\$type \\(int\\) does not accept int\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/types/EntityLink.php - - - - message: "#^Argument of an invalid type array\\\\|null supplied for foreach, only iterables are supported\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php - - - - message: "#^Cannot call method getString\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 2 - path: ../../../src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php - - - - message: "#^Cannot call method getShort\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php - - - - message: "#^Cannot call method setName\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php - - - - message: "#^Offset mixed does not exist on array\\\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php - - - - message: "#^Cannot call method equals\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php - - - - message: "#^Method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\RuntimeBlockMapping\\:\\:getBedrockKnownStates\\(\\) should return array\\ but returns array\\\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/types/RuntimeBlockMapping.php - - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\SkinData\\:\\:\\$capeImage \\(pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\SkinImage\\) does not accept pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\SkinImage\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/network/mcpe/protocol/types/SkinData.php - - - - message: "#^Cannot call method wakeupSleeper\\(\\) on pocketmine\\\\snooze\\\\SleeperNotifier\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/network/rcon/RCONInstance.php - - - - message: "#^Parameter \\#1 \\$str of function trim expects string, string\\|null given\\.$#" - count: 1 - path: ../../../src/pocketmine/permission/BanEntry.php - - - - message: "#^Method pocketmine\\\\permission\\\\DefaultPermissions\\:\\:registerPermission\\(\\) should return pocketmine\\\\permission\\\\Permission but returns pocketmine\\\\permission\\\\Permission\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/permission/DefaultPermissions.php - - - - message: "#^Method pocketmine\\\\plugin\\\\PluginBase\\:\\:getConfig\\(\\) should return pocketmine\\\\utils\\\\Config but returns pocketmine\\\\utils\\\\Config\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/plugin/PluginBase.php - - - - message: "#^Parameter \\#1 \\$closure of static method pocketmine\\\\utils\\\\Utils\\:\\:getNiceClosureName\\(\\) expects Closure, Closure\\|null given\\.$#" - count: 3 - path: ../../../src/pocketmine/plugin/PluginManager.php - - - - message: "#^Cannot call method handleException\\(\\) on pocketmine\\\\scheduler\\\\AsyncWorker\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/scheduler/AsyncTask.php - - - - message: "#^Cannot call method getAsyncWorkerId\\(\\) on pocketmine\\\\scheduler\\\\AsyncWorker\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/scheduler/DumpWorkerMemoryTask.php - - - - message: "#^Cannot call method getLogger\\(\\) on pocketmine\\\\scheduler\\\\AsyncWorker\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/scheduler/DumpWorkerMemoryTask.php - - - - message: "#^Cannot call method toBinary\\(\\) on pocketmine\\\\utils\\\\UUID\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/scheduler/SendUsageTask.php - - - - message: "#^Parameter \\#1 \\$tag of method pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\:\\:setTag\\(\\) expects pocketmine\\\\nbt\\\\tag\\\\NamedTag, pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null given\\.$#" + message: "#^Parameter \\#2 \\$item of method pocketmine\\\\world\\\\World\\:\\:dropItem\\(\\) expects pocketmine\\\\item\\\\Item, pocketmine\\\\item\\\\Item\\|null given\\.$#" count: 1 - path: ../../../src/pocketmine/tile/Banner.php + path: ../../../src/block/ItemFrame.php - message: "#^Parameter \\#2 \\$value of method pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\:\\:setInt\\(\\) expects int, int\\|null given\\.$#" count: 4 - path: ../../../src/pocketmine/tile/Chest.php - - - - message: "#^Cannot call method isChunkLoaded\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/tile/Chest.php + path: ../../../src/block/tile/Chest.php - message: "#^Parameter \\#1 \\$x of class pocketmine\\\\math\\\\Vector3 constructor expects float\\|int, int\\|null given\\.$#" count: 1 - path: ../../../src/pocketmine/tile/Chest.php + path: ../../../src/block/tile/Chest.php - message: "#^Parameter \\#3 \\$z of class pocketmine\\\\math\\\\Vector3 constructor expects float\\|int, int\\|null given\\.$#" count: 1 - path: ../../../src/pocketmine/tile/Chest.php + path: ../../../src/block/tile/Chest.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\level\\\\Level\\:\\:getTileAt\\(\\) expects int, int\\|null given\\.$#" + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getTileAt\\(\\) expects int, int\\|null given\\.$#" count: 1 - path: ../../../src/pocketmine/tile/Chest.php + path: ../../../src/block/tile/Chest.php - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\level\\\\Level\\:\\:getTileAt\\(\\) expects int, int\\|null given\\.$#" + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getTileAt\\(\\) expects int, int\\|null given\\.$#" count: 1 - path: ../../../src/pocketmine/tile/Chest.php + path: ../../../src/block/tile/Chest.php - message: "#^Argument of an invalid type pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null supplied for foreach, only iterables are supported\\.$#" count: 1 - path: ../../../src/pocketmine/tile/Chest.php + path: ../../../src/block/tile/Chest.php + + - + message: "#^Cannot call method dropItem\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" + count: 1 + path: ../../../src/block/tile/Chest.php - message: "#^Argument of an invalid type pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null supplied for foreach, only iterables are supported\\.$#" count: 1 - path: ../../../src/pocketmine/tile/Furnace.php + path: ../../../src/block/tile/BrewingStand.php - - message: "#^Cannot call method broadcastPacketToViewers\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" + message: "#^Cannot call method dropItem\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" count: 1 - path: ../../../src/pocketmine/tile/Spawnable.php + path: ../../../src/block/tile/BrewingStand.php - - message: "#^Cannot call method clearChunkCache\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" + message: "#^Argument of an invalid type pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null supplied for foreach, only iterables are supported\\.$#" count: 1 - path: ../../../src/pocketmine/tile/Spawnable.php + path: ../../../src/block/tile/Furnace.php - - message: "#^Cannot clone non\\-object variable \\$customBlockDataTag of type pocketmine\\\\nbt\\\\tag\\\\NamedTag\\|null\\.$#" + message: "#^Cannot call method dropItem\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" count: 1 - path: ../../../src/pocketmine/tile/Tile.php + path: ../../../src/block/tile/Furnace.php - - message: "#^Parameter \\#1 \\$tag of method pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\:\\:setTag\\(\\) expects pocketmine\\\\nbt\\\\tag\\\\NamedTag, pocketmine\\\\nbt\\\\tag\\\\NamedTag\\|null given\\.$#" + message: "#^Argument of an invalid type pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null supplied for foreach, only iterables are supported\\.$#" count: 1 - path: ../../../src/pocketmine/tile/Tile.php + path: ../../../src/block/tile/Hopper.php - - message: "#^Cannot call method getBlockAt\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" + message: "#^Cannot call method dropItem\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" count: 1 - path: ../../../src/pocketmine/tile/Tile.php + path: ../../../src/block/tile/Hopper.php - - message: "#^Cannot access property \\$updateTiles on pocketmine\\\\level\\\\Level\\|null\\.$#" + message: "#^Parameter \\#1 \\$nbt of method pocketmine\\\\block\\\\tile\\\\Tile\\:\\:readSaveData\\(\\) expects pocketmine\\\\nbt\\\\tag\\\\CompoundTag, pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null given\\.$#" count: 1 - path: ../../../src/pocketmine/tile/Tile.php + path: ../../../src/block/tile/Tile.php - - message: "#^Cannot call method removeTile\\(\\) on pocketmine\\\\level\\\\Level\\|null\\.$#" + message: "#^Cannot call method getBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" count: 1 - path: ../../../src/pocketmine/tile/Tile.php + path: ../../../src/block/Anvil.php + + - + message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" + count: 1 + path: ../../../src/block/Anvil.php + + - + message: "#^Cannot call method getBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" + count: 1 + path: ../../../src/block/ConcretePowder.php + + - + message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" + count: 1 + path: ../../../src/block/ConcretePowder.php + + - + message: "#^Cannot call method getBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" + count: 1 + path: ../../../src/block/DragonEgg.php + + - + message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" + count: 1 + path: ../../../src/block/DragonEgg.php + + - + message: "#^Cannot call method getBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" + count: 1 + path: ../../../src/block/Gravel.php + + - + message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" + count: 1 + path: ../../../src/block/Gravel.php + + - + message: "#^Cannot call method getBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" + count: 1 + path: ../../../src/block/Sand.php + + - + message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" + count: 1 + path: ../../../src/block/Sand.php + + - + message: "#^Cannot call method getBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" + count: 1 + path: ../../../src/block/SnowLayer.php + + - + message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" + count: 1 + path: ../../../src/block/SnowLayer.php + + - + message: "#^Parameter \\#2 \\$replace of function str_replace expects array\\|string, string\\|null given\\.$#" + count: 1 + path: ../../../src/command/Command.php + + - + message: "#^Cannot call method startTiming\\(\\) on pocketmine\\\\timings\\\\TimingsHandler\\|null\\.$#" + count: 1 + path: ../../../src/command/SimpleCommandMap.php + + - + message: "#^Cannot call method stopTiming\\(\\) on pocketmine\\\\timings\\\\TimingsHandler\\|null\\.$#" + count: 1 + path: ../../../src/command/SimpleCommandMap.php + + - + message: "#^Parameter \\#1 \\$target of method pocketmine\\\\permission\\\\BanList\\:\\:addBan\\(\\) expects string, string\\|null given\\.$#" + count: 1 + path: ../../../src/command/defaults/BanCommand.php + + - + message: "#^Parameter \\#1 \\$name of method pocketmine\\\\Server\\:\\:getPlayerExact\\(\\) expects string, string\\|null given\\.$#" + count: 1 + path: ../../../src/command/defaults/BanCommand.php + + - + message: "#^Parameter \\#2 \\$subject of function preg_match expects string, string\\|null given\\.$#" + count: 1 + path: ../../../src/command/defaults/BanIpCommand.php + + - + message: "#^Parameter \\#1 \\$ip of method pocketmine\\\\command\\\\defaults\\\\BanIpCommand\\:\\:processIPBan\\(\\) expects string, string\\|null given\\.$#" + count: 1 + path: ../../../src/command/defaults/BanIpCommand.php + + - + message: "#^Parameter \\#1 \\$name of method pocketmine\\\\Server\\:\\:getPlayer\\(\\) expects string, string\\|null given\\.$#" + count: 1 + path: ../../../src/command/defaults/BanIpCommand.php + + - + message: "#^Parameter \\#1 \\$name of method pocketmine\\\\Server\\:\\:getOfflinePlayer\\(\\) expects string, string\\|null given\\.$#" + count: 1 + path: ../../../src/command/defaults/DeopCommand.php + + - + message: "#^Parameter \\#1 \\$name of method pocketmine\\\\Server\\:\\:getPlayer\\(\\) expects string, string\\|null given\\.$#" + count: 1 + path: ../../../src/command/defaults/KickCommand.php + + - + message: "#^Parameter \\#1 \\$name of method pocketmine\\\\Server\\:\\:getOfflinePlayer\\(\\) expects string, string\\|null given\\.$#" + count: 1 + path: ../../../src/command/defaults/OpCommand.php + + - + message: "#^Cannot call method addParticle\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" + count: 1 + path: ../../../src/command/defaults/ParticleCommand.php + + - + message: "#^Cannot call method getSeed\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" + count: 1 + path: ../../../src/command/defaults/SeedCommand.php + + - + message: "#^Cannot call method setSpawnLocation\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" + count: 1 + path: ../../../src/command/defaults/SetWorldSpawnCommand.php + + - + message: "#^Parameter \\#1 \\$name of method pocketmine\\\\Server\\:\\:getPlayer\\(\\) expects string, string\\|null given\\.$#" + count: 1 + path: ../../../src/command/defaults/TellCommand.php + + - + message: "#^Cannot call method getTime\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" + count: 1 + path: ../../../src/command/defaults/TimeCommand.php + + - + message: "#^Cannot call method getAllValues\\(\\) on pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null\\.$#" + count: 3 + path: ../../../src/entity/Entity.php + + - + message: "#^Cannot call method addEntity\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/entity/Entity.php + + - + message: "#^Cannot call method getValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" + count: 2 + path: ../../../src/entity/Entity.php + + - + message: "#^Cannot call method setValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" + count: 1 + path: ../../../src/entity/Entity.php + + - + message: "#^Method pocketmine\\\\entity\\\\Entity\\:\\:getWorld\\(\\) should return pocketmine\\\\world\\\\World but returns pocketmine\\\\world\\\\World\\|null\\.$#" + count: 1 + path: ../../../src/entity/Entity.php + + - + message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\AddActorPacket\\:\\:\\$type \\(string\\) does not accept string\\|null\\.$#" + count: 1 + path: ../../../src/entity/Entity.php + + - + message: "#^Parameter \\#1 \\$attribute of method pocketmine\\\\entity\\\\AttributeMap\\:\\:add\\(\\) expects pocketmine\\\\entity\\\\Attribute, pocketmine\\\\entity\\\\Attribute\\|null given\\.$#" + count: 1 + path: ../../../src/entity/ExperienceManager.php + + - + message: "#^Method pocketmine\\\\entity\\\\ExperienceManager\\:\\:fetchAttribute\\(\\) should return pocketmine\\\\entity\\\\Attribute but returns pocketmine\\\\entity\\\\Attribute\\|null\\.$#" + count: 1 + path: ../../../src/entity/ExperienceManager.php + + - + message: "#^Parameter \\#1 \\$attribute of method pocketmine\\\\entity\\\\AttributeMap\\:\\:add\\(\\) expects pocketmine\\\\entity\\\\Attribute, pocketmine\\\\entity\\\\Attribute\\|null given\\.$#" + count: 1 + path: ../../../src/entity/HungerManager.php + + - + message: "#^Method pocketmine\\\\entity\\\\HungerManager\\:\\:fetchAttribute\\(\\) should return pocketmine\\\\entity\\\\Attribute but returns pocketmine\\\\entity\\\\Attribute\\|null\\.$#" + count: 1 + path: ../../../src/entity/HungerManager.php + + - + message: "#^Parameter \\#1 \\$attribute of method pocketmine\\\\entity\\\\AttributeMap\\:\\:add\\(\\) expects pocketmine\\\\entity\\\\Attribute, pocketmine\\\\entity\\\\Attribute\\|null given\\.$#" + count: 6 + path: ../../../src/entity/Living.php + + - + message: "#^Cannot call method setValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" + count: 2 + path: ../../../src/entity/Living.php + + - + message: "#^Cannot call method getMaxValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" + count: 1 + path: ../../../src/entity/Living.php + + - + message: "#^Cannot call method setMaxValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" + count: 1 + path: ../../../src/entity/Living.php + + - + message: "#^Cannot call method getValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" + count: 2 + path: ../../../src/entity/Living.php + + - + message: "#^Cannot call method getEffectLevel\\(\\) on pocketmine\\\\entity\\\\effect\\\\EffectInstance\\|null\\.$#" + count: 3 + path: ../../../src/entity/Living.php + + - + message: "#^Cannot call method attack\\(\\) on pocketmine\\\\entity\\\\Entity\\|null\\.$#" + count: 1 + path: ../../../src/entity/Living.php + + - + message: "#^Parameter \\#2 \\$entity of class pocketmine\\\\event\\\\entity\\\\EntityDamageByEntityEvent constructor expects pocketmine\\\\entity\\\\Entity, pocketmine\\\\entity\\\\Entity\\|null given\\.$#" + count: 1 + path: ../../../src/entity/Living.php + + - + message: "#^Cannot call method getValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" + count: 2 + path: ../../../src/entity/effect/SlownessEffect.php + + - + message: "#^Cannot call method setValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" + count: 2 + path: ../../../src/entity/effect/SlownessEffect.php + + - + message: "#^Cannot call method getValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" + count: 2 + path: ../../../src/entity/effect/SpeedEffect.php + + - + message: "#^Cannot call method setValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" + count: 2 + path: ../../../src/entity/effect/SpeedEffect.php + + - + message: "#^Method pocketmine\\\\entity\\\\object\\\\Painting\\:\\:getMotive\\(\\) should return pocketmine\\\\entity\\\\object\\\\PaintingMotive but returns pocketmine\\\\entity\\\\object\\\\PaintingMotive\\|null\\.$#" + count: 1 + path: ../../../src/entity/object/Painting.php + + - + message: "#^Cannot call method getEffectLevel\\(\\) on pocketmine\\\\entity\\\\effect\\\\EffectInstance\\|null\\.$#" + count: 2 + path: ../../../src/event/entity/EntityDamageByEntityEvent.php + + - + message: "#^Parameter \\#2 \\$oldContents of method pocketmine\\\\inventory\\\\InventoryListener\\:\\:onContentChange\\(\\) expects array\\, array\\ given\\.$#" + count: 1 + path: ../../../src/inventory/BaseInventory.php + + - + message: "#^Parameter \\#2 \\$recipe of class pocketmine\\\\event\\\\inventory\\\\CraftItemEvent constructor expects pocketmine\\\\crafting\\\\CraftingRecipe, pocketmine\\\\crafting\\\\CraftingRecipe\\|null given\\.$#" + count: 1 + path: ../../../src/inventory/transaction/CraftingTransaction.php + + - + message: "#^Parameter \\#3 \\$repetitions of class pocketmine\\\\event\\\\inventory\\\\CraftItemEvent constructor expects int, int\\|null given\\.$#" + count: 1 + path: ../../../src/inventory/transaction/CraftingTransaction.php + + - + message: "#^Parameter \\#2 \\$world of method pocketmine\\\\entity\\\\EntityFactory\\:\\:create\\(\\) expects pocketmine\\\\world\\\\World, pocketmine\\\\world\\\\World\\|null given\\.$#" + count: 1 + path: ../../../src/item/Bow.php + + - + message: "#^Method pocketmine\\\\item\\\\Item\\:\\:getNamedTag\\(\\) should return pocketmine\\\\nbt\\\\tag\\\\CompoundTag but returns pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 1 + path: ../../../src/item/Item.php + + - + message: "#^Cannot clone pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 1 + path: ../../../src/item/Item.php + + - + message: "#^Parameter \\#2 \\$tag of method pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\:\\:setTag\\(\\) expects pocketmine\\\\nbt\\\\tag\\\\Tag, pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null given\\.$#" + count: 1 + path: ../../../src/item/Item.php + + - + message: "#^Parameter \\#1 \\$object of function get_class expects object, pocketmine\\\\nbt\\\\tag\\\\Tag\\|null given\\.$#" + count: 1 + path: ../../../src/item/Item.php + + - + message: "#^Parameter \\#2 \\$world of method pocketmine\\\\entity\\\\EntityFactory\\:\\:create\\(\\) expects pocketmine\\\\world\\\\World, pocketmine\\\\world\\\\World\\|null given\\.$#" + count: 1 + path: ../../../src/item/ProjectileItem.php + + - + message: "#^Method pocketmine\\\\item\\\\enchantment\\\\Enchantment\\:\\:BLAST_PROTECTION\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\Enchantment but returns pocketmine\\\\item\\\\enchantment\\\\Enchantment\\|null\\.$#" + count: 1 + path: ../../../src/item/enchantment/Enchantment.php + + - + message: "#^Method pocketmine\\\\item\\\\enchantment\\\\Enchantment\\:\\:EFFICIENCY\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\Enchantment but returns pocketmine\\\\item\\\\enchantment\\\\Enchantment\\|null\\.$#" + count: 1 + path: ../../../src/item/enchantment/Enchantment.php + + - + message: "#^Method pocketmine\\\\item\\\\enchantment\\\\Enchantment\\:\\:FEATHER_FALLING\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\Enchantment but returns pocketmine\\\\item\\\\enchantment\\\\Enchantment\\|null\\.$#" + count: 1 + path: ../../../src/item/enchantment/Enchantment.php + + - + message: "#^Method pocketmine\\\\item\\\\enchantment\\\\Enchantment\\:\\:FIRE_ASPECT\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\Enchantment but returns pocketmine\\\\item\\\\enchantment\\\\Enchantment\\|null\\.$#" + count: 1 + path: ../../../src/item/enchantment/Enchantment.php + + - + message: "#^Method pocketmine\\\\item\\\\enchantment\\\\Enchantment\\:\\:FIRE_PROTECTION\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\Enchantment but returns pocketmine\\\\item\\\\enchantment\\\\Enchantment\\|null\\.$#" + count: 1 + path: ../../../src/item/enchantment/Enchantment.php + + - + message: "#^Method pocketmine\\\\item\\\\enchantment\\\\Enchantment\\:\\:FLAME\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\Enchantment but returns pocketmine\\\\item\\\\enchantment\\\\Enchantment\\|null\\.$#" + count: 1 + path: ../../../src/item/enchantment/Enchantment.php + + - + message: "#^Method pocketmine\\\\item\\\\enchantment\\\\Enchantment\\:\\:INFINITY\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\Enchantment but returns pocketmine\\\\item\\\\enchantment\\\\Enchantment\\|null\\.$#" + count: 1 + path: ../../../src/item/enchantment/Enchantment.php + + - + message: "#^Method pocketmine\\\\item\\\\enchantment\\\\Enchantment\\:\\:KNOCKBACK\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\Enchantment but returns pocketmine\\\\item\\\\enchantment\\\\Enchantment\\|null\\.$#" + count: 1 + path: ../../../src/item/enchantment/Enchantment.php + + - + message: "#^Method pocketmine\\\\item\\\\enchantment\\\\Enchantment\\:\\:MENDING\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\Enchantment but returns pocketmine\\\\item\\\\enchantment\\\\Enchantment\\|null\\.$#" + count: 1 + path: ../../../src/item/enchantment/Enchantment.php + + - + message: "#^Method pocketmine\\\\item\\\\enchantment\\\\Enchantment\\:\\:POWER\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\Enchantment but returns pocketmine\\\\item\\\\enchantment\\\\Enchantment\\|null\\.$#" + count: 1 + path: ../../../src/item/enchantment/Enchantment.php + + - + message: "#^Method pocketmine\\\\item\\\\enchantment\\\\Enchantment\\:\\:PROJECTILE_PROTECTION\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\Enchantment but returns pocketmine\\\\item\\\\enchantment\\\\Enchantment\\|null\\.$#" + count: 1 + path: ../../../src/item/enchantment/Enchantment.php + + - + message: "#^Method pocketmine\\\\item\\\\enchantment\\\\Enchantment\\:\\:PROTECTION\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\Enchantment but returns pocketmine\\\\item\\\\enchantment\\\\Enchantment\\|null\\.$#" + count: 1 + path: ../../../src/item/enchantment/Enchantment.php + + - + message: "#^Method pocketmine\\\\item\\\\enchantment\\\\Enchantment\\:\\:PUNCH\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\Enchantment but returns pocketmine\\\\item\\\\enchantment\\\\Enchantment\\|null\\.$#" + count: 1 + path: ../../../src/item/enchantment/Enchantment.php + + - + message: "#^Method pocketmine\\\\item\\\\enchantment\\\\Enchantment\\:\\:RESPIRATION\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\Enchantment but returns pocketmine\\\\item\\\\enchantment\\\\Enchantment\\|null\\.$#" + count: 1 + path: ../../../src/item/enchantment/Enchantment.php + + - + message: "#^Method pocketmine\\\\item\\\\enchantment\\\\Enchantment\\:\\:SHARPNESS\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\Enchantment but returns pocketmine\\\\item\\\\enchantment\\\\Enchantment\\|null\\.$#" + count: 1 + path: ../../../src/item/enchantment/Enchantment.php + + - + message: "#^Method pocketmine\\\\item\\\\enchantment\\\\Enchantment\\:\\:SILK_TOUCH\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\Enchantment but returns pocketmine\\\\item\\\\enchantment\\\\Enchantment\\|null\\.$#" + count: 1 + path: ../../../src/item/enchantment/Enchantment.php + + - + message: "#^Method pocketmine\\\\item\\\\enchantment\\\\Enchantment\\:\\:THORNS\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\Enchantment but returns pocketmine\\\\item\\\\enchantment\\\\Enchantment\\|null\\.$#" + count: 1 + path: ../../../src/item/enchantment/Enchantment.php + + - + message: "#^Method pocketmine\\\\item\\\\enchantment\\\\Enchantment\\:\\:UNBREAKING\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\Enchantment but returns pocketmine\\\\item\\\\enchantment\\\\Enchantment\\|null\\.$#" + count: 1 + path: ../../../src/item/enchantment/Enchantment.php + + - + message: "#^Method pocketmine\\\\item\\\\enchantment\\\\Enchantment\\:\\:VANISHING\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\Enchantment but returns pocketmine\\\\item\\\\enchantment\\\\Enchantment\\|null\\.$#" + count: 1 + path: ../../../src/item/enchantment/Enchantment.php + + - + message: "#^Method pocketmine\\\\item\\\\enchantment\\\\EnchantmentList\\:\\:getSlot\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\EnchantmentEntry but returns pocketmine\\\\item\\\\enchantment\\\\EnchantmentEntry\\|null\\.$#" + count: 1 + path: ../../../src/item/enchantment/EnchantmentList.php + + - + message: "#^Cannot call method getUsername\\(\\) on pocketmine\\\\player\\\\PlayerInfo\\|null\\.$#" + count: 1 + path: ../../../src/network/NetworkSessionManager.php + + - + message: "#^Cannot call method getUuid\\(\\) on pocketmine\\\\player\\\\PlayerInfo\\|null\\.$#" + count: 1 + path: ../../../src/network/NetworkSessionManager.php + + - + message: "#^Parameter \\#3 \\$chunk of class pocketmine\\\\network\\\\mcpe\\\\ChunkRequestTask constructor expects pocketmine\\\\world\\\\format\\\\Chunk, pocketmine\\\\world\\\\format\\\\Chunk\\|null given\\.$#" + count: 1 + path: ../../../src/network/mcpe/ChunkCache.php + + - + message: "#^Parameter \\#1 \\$entity of method pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:onEntityEffectAdded\\(\\) expects pocketmine\\\\entity\\\\Living, pocketmine\\\\player\\\\Player\\|null given\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Parameter \\#1 \\$entity of method pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:onEntityEffectRemoved\\(\\) expects pocketmine\\\\entity\\\\Living, pocketmine\\\\player\\\\Player\\|null given\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Parameter \\#1 \\$clientPub of class pocketmine\\\\network\\\\mcpe\\\\encryption\\\\PrepareEncryptionTask constructor expects Mdanter\\\\Ecc\\\\Crypto\\\\Key\\\\PublicKeyInterface, Mdanter\\\\Ecc\\\\Crypto\\\\Key\\\\PublicKeyInterface\\|null given\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Parameter \\#2 \\$player of class pocketmine\\\\network\\\\mcpe\\\\handler\\\\PreSpawnPacketHandler constructor expects pocketmine\\\\player\\\\Player, pocketmine\\\\player\\\\Player\\|null given\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Cannot call method doFirstSpawn\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Parameter \\#1 \\$player of class pocketmine\\\\network\\\\mcpe\\\\handler\\\\InGamePacketHandler constructor expects pocketmine\\\\player\\\\Player, pocketmine\\\\player\\\\Player\\|null given\\.$#" + count: 2 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Parameter \\#1 \\$player of class pocketmine\\\\network\\\\mcpe\\\\handler\\\\DeathPacketHandler constructor expects pocketmine\\\\player\\\\Player, pocketmine\\\\player\\\\Player\\|null given\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Cannot call method sendData\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" + count: 2 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Cannot call method getViewers\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Parameter \\#1 \\$for of method pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:syncAdventureSettings\\(\\) expects pocketmine\\\\player\\\\Player, pocketmine\\\\player\\\\Player\\|null given\\.$#" + count: 2 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Cannot call method syncAll\\(\\) on pocketmine\\\\network\\\\mcpe\\\\InventoryManager\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Cannot call method getLocation\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" + count: 3 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Cannot call method getId\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Cannot call method getOffsetPosition\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Cannot call method syncCreative\\(\\) on pocketmine\\\\network\\\\mcpe\\\\InventoryManager\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Parameter \\#1 \\$target of method pocketmine\\\\command\\\\Command\\:\\:testPermissionSilent\\(\\) expects pocketmine\\\\command\\\\CommandSender, pocketmine\\\\player\\\\Player\\|null given\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Cannot call method isUsingChunk\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Cannot call method getWorld\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Method pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:getInvManager\\(\\) should return pocketmine\\\\network\\\\mcpe\\\\InventoryManager but returns pocketmine\\\\network\\\\mcpe\\\\InventoryManager\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Cannot call method getString\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 3 + path: ../../../src/network/mcpe/convert/RuntimeBlockMapping.php + + - + message: "#^Cannot call method getShort\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/convert/RuntimeBlockMapping.php + + - + message: "#^Cannot call method equals\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/convert/RuntimeBlockMapping.php + + - + message: "#^Cannot call method getTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/convert/TypeConverter.php + + - + message: "#^Cannot call method removeTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/convert/TypeConverter.php + + - + message: "#^Cannot call method setTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/convert/TypeConverter.php + + - + message: "#^Parameter \\#1 \\$\\$encryptionKey of closure expects string, string\\|null given\\.$#" + count: 1 + path: ../../../src/network/mcpe/encryption/PrepareEncryptionTask.php + + - + message: "#^Parameter \\#2 \\$\\$handshakeJwt of closure expects string, string\\|null given\\.$#" + count: 1 + path: ../../../src/network/mcpe/encryption/PrepareEncryptionTask.php + + - + message: "#^Parameter \\#1 \\$playerInfo of class pocketmine\\\\event\\\\player\\\\PlayerPreLoginEvent constructor expects pocketmine\\\\player\\\\PlayerInfo, pocketmine\\\\player\\\\PlayerInfo\\|null given\\.$#" + count: 1 + path: ../../../src/network/mcpe/handler/LoginPacketHandler.php + + - + message: "#^Cannot call method getUsername\\(\\) on pocketmine\\\\player\\\\PlayerInfo\\|null\\.$#" + count: 2 + path: ../../../src/network/mcpe/handler/LoginPacketHandler.php + + - + message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\StartGamePacket\\:\\:\\$blockTable \\(pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\CacheableNbt\\\\) does not accept pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\CacheableNbt\\\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/handler/PreSpawnPacketHandler.php + + - + message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\LevelSoundEventPacket\\:\\:\\$position \\(pocketmine\\\\math\\\\Vector3\\) does not accept pocketmine\\\\math\\\\Vector3\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/LevelSoundEventPacket.php + + - + message: "#^Parameter \\#1 \\$eid of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\NetworkBinaryStream\\:\\:putEntityUniqueId\\(\\) expects int, int\\|null given\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/SetScorePacket.php + + - + message: "#^Parameter \\#1 \\$v of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\NetworkBinaryStream\\:\\:putString\\(\\) expects string, string\\|null given\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/SetScorePacket.php + + - + message: "#^Parameter \\#1 \\$eid of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\NetworkBinaryStream\\:\\:putEntityUniqueId\\(\\) expects int, int\\|null given\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/SetScoreboardIdentityPacket.php + + - + message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\SkinData\\:\\:\\$capeImage \\(pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\SkinImage\\) does not accept pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\SkinImage\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/types/SkinData.php + + - + message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\entity\\\\EntityLink\\:\\:\\$fromEntityUniqueId \\(int\\) does not accept int\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/types/entity/EntityLink.php + + - + message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\entity\\\\EntityLink\\:\\:\\$toEntityUniqueId \\(int\\) does not accept int\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/types/entity/EntityLink.php + + - + message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\entity\\\\EntityLink\\:\\:\\$type \\(int\\) does not accept int\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/types/entity/EntityLink.php + + - + message: "#^Parameter \\#1 \\$v of method pocketmine\\\\utils\\\\BinaryStream\\:\\:putVarInt\\(\\) expects int, int\\|null given\\.$#" + count: 1 + path: ../../../src/network/mcpe/protocol/types/recipe/FurnaceRecipe.php + + - + message: "#^Property pocketmine\\\\network\\\\mcpe\\\\raklib\\\\RakLibServer\\:\\:\\$mainThreadNotifier \\(pocketmine\\\\snooze\\\\SleeperNotifier\\) does not accept pocketmine\\\\snooze\\\\SleeperNotifier\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/raklib/RakLibServer.php + + - + message: "#^Parameter \\#1 \\$str of function trim expects string, string\\|null given\\.$#" + count: 4 + path: ../../../src/permission/BanEntry.php + + - + message: "#^Parameter \\#1 \\$date of static method pocketmine\\\\permission\\\\BanEntry\\:\\:parseDate\\(\\) expects string, string\\|null given\\.$#" + count: 1 + path: ../../../src/permission/BanEntry.php + + - + message: "#^Method pocketmine\\\\permission\\\\DefaultPermissions\\:\\:registerPermission\\(\\) should return pocketmine\\\\permission\\\\Permission but returns pocketmine\\\\permission\\\\Permission\\|null\\.$#" + count: 1 + path: ../../../src/permission/DefaultPermissions.php + + - + message: "#^Cannot call method getAllValues\\(\\) on pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method getSafeSpawn\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" + count: 2 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method registerChunkLoader\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method registerChunkListener\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Parameter \\#1 \\$world of method pocketmine\\\\entity\\\\Human\\:\\:__construct\\(\\) expects pocketmine\\\\world\\\\World, pocketmine\\\\world\\\\World\\|null given\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method syncAdventureSettings\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 4 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method syncViewAreaRadius\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method syncAvailableCommands\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Method pocketmine\\\\player\\\\Player\\:\\:getNetworkSession\\(\\) should return pocketmine\\\\network\\\\mcpe\\\\NetworkSession but returns pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method onEnterWorld\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method getEntities\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 2 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method stopUsingChunk\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method startUsingChunk\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method onTerrainReady\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method syncViewAreaCenterPoint\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Method pocketmine\\\\player\\\\Player\\:\\:getSpawn\\(\\) should return pocketmine\\\\world\\\\Position but returns pocketmine\\\\world\\\\Position\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method syncPlayerSpawnPoint\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method sendDataPacket\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method syncGameMode\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method syncAttributes\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method onTitle\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method onSubTitle\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method onActionBar\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method onClearTitle\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method onResetTitleOptions\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method onTitleDuration\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method onRawChatMessage\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method onTranslatedChatMessage\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method onPopup\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method onTip\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method onFormSent\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method transfer\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method onPlayerDestroyed\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method getWorldNonNull\\(\\) on pocketmine\\\\world\\\\Position\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method getFloorX\\(\\) on pocketmine\\\\world\\\\Position\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method getFloorY\\(\\) on pocketmine\\\\world\\\\Position\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method getFloorZ\\(\\) on pocketmine\\\\world\\\\Position\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot access property \\$x on pocketmine\\\\world\\\\Position\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot access property \\$y on pocketmine\\\\world\\\\Position\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot access property \\$z on pocketmine\\\\world\\\\Position\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method onDeath\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method onRespawn\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method syncMovement\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 + path: ../../../src/player/Player.php + + - + message: "#^Cannot call method getInvManager\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 2 + path: ../../../src/player/Player.php + + - + message: "#^Method pocketmine\\\\plugin\\\\PluginBase\\:\\:getConfig\\(\\) should return pocketmine\\\\utils\\\\Config but returns pocketmine\\\\utils\\\\Config\\|null\\.$#" + count: 1 + path: ../../../src/plugin/PluginBase.php + + - + message: "#^Parameter \\#1 \\$closure of static method pocketmine\\\\utils\\\\Utils\\:\\:getNiceClosureName\\(\\) expects Closure, Closure\\|null given\\.$#" + count: 3 + path: ../../../src/plugin/PluginManager.php + + - + message: "#^Parameter \\#2 \\$handler of method pocketmine\\\\plugin\\\\PluginManager\\:\\:registerEvent\\(\\) expects Closure\\(pocketmine\\\\event\\\\Event\\)\\: void, Closure\\|null given\\.$#" + count: 1 + path: ../../../src/plugin/PluginManager.php + + - + message: "#^Cannot call method handleException\\(\\) on pocketmine\\\\scheduler\\\\AsyncWorker\\|null\\.$#" + count: 1 + path: ../../../src/scheduler/AsyncTask.php + + - + message: "#^Cannot call method count\\(\\) on ArrayObject\\\\>\\|null\\.$#" + count: 1 + path: ../../../src/scheduler/AsyncTask.php + + - + message: "#^Cannot call method cancel\\(\\) on pocketmine\\\\scheduler\\\\TaskHandler\\|null\\.$#" + count: 1 + path: ../../../src/scheduler/CancellableClosureTask.php + + - + message: "#^Cannot call method getAsyncWorkerId\\(\\) on pocketmine\\\\scheduler\\\\AsyncWorker\\|null\\.$#" + count: 1 + path: ../../../src/scheduler/DumpWorkerMemoryTask.php + + - + message: "#^Cannot call method getLogger\\(\\) on pocketmine\\\\scheduler\\\\AsyncWorker\\|null\\.$#" + count: 1 + path: ../../../src/scheduler/DumpWorkerMemoryTask.php + + - + message: "#^Parameter \\#1 \\$options of method Thread\\:\\:start\\(\\) expects int, int\\|null given\\.$#" + count: 1 + path: ../../../src/thread/Thread.php + + - + message: "#^Parameter \\#1 \\$options of method Thread\\:\\:start\\(\\) expects int, int\\|null given\\.$#" + count: 1 + path: ../../../src/thread/Worker.php - message: "#^Cannot call method getFullVersion\\(\\) on pocketmine\\\\utils\\\\VersionString\\|null\\.$#" count: 1 - path: ../../../src/pocketmine/updater/AutoUpdater.php + path: ../../../src/updater/AutoUpdater.php - message: "#^Offset 'date' does not exist on array\\\\|null\\.$#" count: 1 - path: ../../../src/pocketmine/updater/AutoUpdater.php + path: ../../../src/updater/AutoUpdater.php - message: "#^Offset 'details_url' does not exist on array\\\\|null\\.$#" count: 2 - path: ../../../src/pocketmine/updater/AutoUpdater.php + path: ../../../src/updater/AutoUpdater.php - message: "#^Offset 'download_url' does not exist on array\\\\|null\\.$#" count: 1 - path: ../../../src/pocketmine/updater/AutoUpdater.php + path: ../../../src/updater/AutoUpdater.php - message: "#^Method pocketmine\\\\utils\\\\Config\\:\\:fixYAMLIndexes\\(\\) should return string but returns string\\|null\\.$#" count: 1 - path: ../../../src/pocketmine/utils/Config.php + path: ../../../src/utils/Config.php - message: "#^Parameter \\#1 \\$str of function trim expects string, string\\|null given\\.$#" count: 1 - path: ../../../src/pocketmine/utils/Config.php - - - - message: "#^Method pocketmine\\\\utils\\\\MainLogger\\:\\:getLogger\\(\\) should return pocketmine\\\\utils\\\\MainLogger but returns pocketmine\\\\utils\\\\MainLogger\\|null\\.$#" - count: 1 - path: ../../../src/pocketmine/utils/MainLogger.php + path: ../../../src/utils/Config.php - message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, string\\|null given\\.$#" count: 2 - path: ../../../src/pocketmine/utils/TextFormat.php + path: ../../../src/utils/TextFormat.php - message: "#^Method pocketmine\\\\utils\\\\TextFormat\\:\\:colorize\\(\\) should return string but returns string\\|null\\.$#" count: 1 - path: ../../../src/pocketmine/utils/TextFormat.php + path: ../../../src/utils/TextFormat.php - message: "#^Method pocketmine\\\\utils\\\\Utils\\:\\:printable\\(\\) should return string but returns string\\|null\\.$#" count: 1 - path: ../../../src/pocketmine/utils/Utils.php + path: ../../../src/utils/Utils.php - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\StupidJsonDecodeTest\\:\\:\\$stupidJsonDecodeFunc \\(Closure\\) does not accept Closure\\|null\\.$#" + message: "#^Cannot call method getFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" count: 1 - path: ../../phpunit/network/mcpe/StupidJsonDecodeTest.php + path: ../../../src/world/Explosion.php + + - + message: "#^Only numeric types are allowed in /, float\\|null given on the left side\\.$#" + count: 1 + path: ../../../src/world/Explosion.php + + - + message: "#^Cannot call method getFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" + count: 1 + path: ../../../src/world/SimpleChunkManager.php + + - + message: "#^Cannot call method setFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" + count: 1 + path: ../../../src/world/SimpleChunkManager.php + + - + message: "#^Cannot call method setDirtyFlag\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/SimpleChunkManager.php + + - + message: "#^Parameter \\#1 \\$chunk of method pocketmine\\\\player\\\\Player\\:\\:onChunkChanged\\(\\) expects pocketmine\\\\world\\\\format\\\\Chunk, pocketmine\\\\world\\\\format\\\\Chunk\\|null given\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Cannot call method getFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Cannot call method getEntities\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 3 + path: ../../../src/world/World.php + + - + message: "#^Cannot call method getBlockSkyLight\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Cannot call method getBlockLight\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Cannot call method getBiomeId\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Cannot call method setBiomeId\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Cannot call method getHighestBlockAt\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Cannot call method isPopulated\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Parameter \\#2 \\$chunk of class pocketmine\\\\world\\\\generator\\\\PopulationTask constructor expects pocketmine\\\\world\\\\format\\\\Chunk, pocketmine\\\\world\\\\format\\\\Chunk\\|null given\\.$#" + count: 1 + path: ../../../src/world/World.php + + - + message: "#^Method pocketmine\\\\world\\\\biome\\\\Biome\\:\\:getBiome\\(\\) should return pocketmine\\\\world\\\\biome\\\\Biome but returns pocketmine\\\\world\\\\biome\\\\Biome\\|null\\.$#" + count: 1 + path: ../../../src/world/biome/Biome.php + + - + message: "#^Method pocketmine\\\\world\\\\biome\\\\BiomeRegistry\\:\\:getBiome\\(\\) should return pocketmine\\\\world\\\\biome\\\\Biome but returns pocketmine\\\\world\\\\biome\\\\Biome\\|null\\.$#" + count: 1 + path: ../../../src/world/biome/BiomeRegistry.php + + - + message: "#^Method pocketmine\\\\world\\\\format\\\\Chunk\\:\\:getSubChunk\\(\\) should return pocketmine\\\\world\\\\format\\\\SubChunkInterface but returns pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" + count: 1 + path: ../../../src/world/format/Chunk.php + + - + message: "#^Method pocketmine\\\\world\\\\format\\\\HeightArray\\:\\:get\\(\\) should return int but returns int\\|null\\.$#" + count: 1 + path: ../../../src/world/format/HeightArray.php + + - + message: "#^Method pocketmine\\\\world\\\\format\\\\io\\\\data\\\\JavaWorldData\\:\\:load\\(\\) should return pocketmine\\\\nbt\\\\tag\\\\CompoundTag but returns pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 1 + path: ../../../src/world/format/io/data/JavaWorldData.php + + - + message: "#^Cannot call method getListTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 3 + path: ../../../src/world/format/io/region/Anvil.php + + - + message: "#^Cannot call method hasTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 4 + path: ../../../src/world/format/io/region/Anvil.php + + - + message: "#^Cannot call method getIntArray\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 1 + path: ../../../src/world/format/io/region/Anvil.php + + - + message: "#^Cannot call method getByteArray\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 1 + path: ../../../src/world/format/io/region/Anvil.php + + - + message: "#^Cannot call method getInt\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 2 + path: ../../../src/world/format/io/region/Anvil.php + + - + message: "#^Parameter \\#2 \\$list of static method pocketmine\\\\world\\\\format\\\\io\\\\region\\\\RegionWorldProvider\\:\\:getCompoundList\\(\\) expects pocketmine\\\\nbt\\\\tag\\\\ListTag, pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null given\\.$#" + count: 2 + path: ../../../src/world/format/io/region/Anvil.php + + - + message: "#^Cannot call method getByte\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 1 + path: ../../../src/world/format/io/region/Anvil.php + + - + message: "#^Cannot call method getListTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 3 + path: ../../../src/world/format/io/region/PMAnvil.php + + - + message: "#^Cannot call method hasTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 4 + path: ../../../src/world/format/io/region/PMAnvil.php + + - + message: "#^Cannot call method getIntArray\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 1 + path: ../../../src/world/format/io/region/PMAnvil.php + + - + message: "#^Cannot call method getByteArray\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 1 + path: ../../../src/world/format/io/region/PMAnvil.php + + - + message: "#^Cannot call method getInt\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 2 + path: ../../../src/world/format/io/region/PMAnvil.php + + - + message: "#^Parameter \\#2 \\$list of static method pocketmine\\\\world\\\\format\\\\io\\\\region\\\\RegionWorldProvider\\:\\:getCompoundList\\(\\) expects pocketmine\\\\nbt\\\\tag\\\\ListTag, pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null given\\.$#" + count: 2 + path: ../../../src/world/format/io/region/PMAnvil.php + + - + message: "#^Cannot call method getByte\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 1 + path: ../../../src/world/format/io/region/PMAnvil.php + + - + message: "#^Cannot call method getByteArray\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 3 + path: ../../../src/world/format/io/region/McRegion.php + + - + message: "#^Cannot call method hasTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 6 + path: ../../../src/world/format/io/region/McRegion.php + + - + message: "#^Cannot call method getIntArray\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 1 + path: ../../../src/world/format/io/region/McRegion.php + + - + message: "#^Cannot call method getInt\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 2 + path: ../../../src/world/format/io/region/McRegion.php + + - + message: "#^Cannot call method getListTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 2 + path: ../../../src/world/format/io/region/McRegion.php + + - + message: "#^Parameter \\#2 \\$list of static method pocketmine\\\\world\\\\format\\\\io\\\\region\\\\RegionWorldProvider\\:\\:getCompoundList\\(\\) expects pocketmine\\\\nbt\\\\tag\\\\ListTag, pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null given\\.$#" + count: 2 + path: ../../../src/world/format/io/region/McRegion.php + + - + message: "#^Cannot call method getByte\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" + count: 1 + path: ../../../src/world/format/io/region/McRegion.php + + - + message: "#^Cannot call method readChunk\\(\\) on pocketmine\\\\world\\\\format\\\\io\\\\region\\\\RegionLoader\\|null\\.$#" + count: 1 + path: ../../../src/world/format/io/region/RegionWorldProvider.php + + - + message: "#^Cannot call method writeChunk\\(\\) on pocketmine\\\\world\\\\format\\\\io\\\\region\\\\RegionLoader\\|null\\.$#" + count: 1 + path: ../../../src/world/format/io/region/RegionWorldProvider.php + + - + message: "#^Cannot call method calculateChunkCount\\(\\) on pocketmine\\\\world\\\\format\\\\io\\\\region\\\\RegionLoader\\|null\\.$#" + count: 1 + path: ../../../src/world/format/io/region/RegionWorldProvider.php + + - + message: "#^Cannot call method saveToThreadStore\\(\\) on pocketmine\\\\scheduler\\\\AsyncWorker\\|null\\.$#" + count: 2 + path: ../../../src/world/generator/GeneratorRegisterTask.php + + - + message: "#^Cannot call method removeFromThreadStore\\(\\) on pocketmine\\\\scheduler\\\\AsyncWorker\\|null\\.$#" + count: 2 + path: ../../../src/world/generator/GeneratorUnregisterTask.php + + - + message: "#^Cannot call method getFromThreadStore\\(\\) on pocketmine\\\\scheduler\\\\AsyncWorker\\|null\\.$#" + count: 2 + path: ../../../src/world/generator/PopulationTask.php + + - + message: "#^Cannot call method setGenerated\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 2 + path: ../../../src/world/generator/PopulationTask.php + + - + message: "#^Cannot call method getX\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 5 + path: ../../../src/world/generator/PopulationTask.php + + - + message: "#^Cannot call method getZ\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 5 + path: ../../../src/world/generator/PopulationTask.php + + - + message: "#^Cannot call method isGenerated\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/generator/PopulationTask.php + + - + message: "#^Cannot call method setPopulated\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/generator/PopulationTask.php + + - + message: "#^Cannot call method recalculateHeightMap\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/generator/PopulationTask.php + + - + message: "#^Cannot call method populateSkyLight\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/generator/PopulationTask.php + + - + message: "#^Cannot call method setLightPopulated\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/generator/PopulationTask.php + + - + message: "#^Parameter \\#1 \\$chunk of static method pocketmine\\\\world\\\\format\\\\io\\\\FastChunkSerializer\\:\\:serialize\\(\\) expects pocketmine\\\\world\\\\format\\\\Chunk, pocketmine\\\\world\\\\format\\\\Chunk\\|null given\\.$#" + count: 2 + path: ../../../src/world/generator/PopulationTask.php + + - + message: "#^Cannot call method isDirty\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/generator/PopulationTask.php + + - + message: "#^Cannot call method getAsyncWorkerId\\(\\) on pocketmine\\\\scheduler\\\\AsyncWorker\\|null\\.$#" + count: 1 + path: ../../../src/world/generator/PopulationTask.php + + - + message: "#^Method pocketmine\\\\world\\\\generator\\\\biome\\\\BiomeSelector\\:\\:pickBiome\\(\\) should return pocketmine\\\\world\\\\biome\\\\Biome but returns pocketmine\\\\world\\\\biome\\\\Biome\\|null\\.$#" + count: 1 + path: ../../../src/world/generator/biome/BiomeSelector.php + + - + message: "#^Cannot call method setBiomeId\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/generator/hell/Nether.php + + - + message: "#^Cannot call method setFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 3 + path: ../../../src/world/generator/hell/Nether.php + + - + message: "#^Cannot call method getBiomeId\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/generator/hell/Nether.php + + - + message: "#^Cannot call method setBiomeId\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/generator/normal/Normal.php + + - + message: "#^Offset int does not exist on array\\\\>\\|null\\.$#" + count: 1 + path: ../../../src/world/generator/normal/Normal.php + + - + message: "#^Cannot call method setFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 3 + path: ../../../src/world/generator/normal/Normal.php + + - + message: "#^Cannot call method getBiomeId\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/generator/normal/Normal.php + + - + message: "#^Cannot call method getBiomeId\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/generator/populator/GroundCover.php + + - + message: "#^Cannot call method getFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 2 + path: ../../../src/world/generator/populator/GroundCover.php + + - + message: "#^Cannot call method setFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/generator/populator/GroundCover.php + + - + message: "#^Cannot call method getBlockLightArray\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" + count: 1 + path: ../../../src/world/light/BlockLightUpdate.php + + - + message: "#^Only numeric types are allowed in \\-, int\\|null given on the right side\\.$#" + count: 1 + path: ../../../src/world/light/BlockLightUpdate.php + + - + message: "#^Cannot call method get\\(\\) on pocketmine\\\\world\\\\format\\\\LightArray\\|null\\.$#" + count: 4 + path: ../../../src/world/light/LightUpdate.php + + - + message: "#^Cannot call method set\\(\\) on pocketmine\\\\world\\\\format\\\\LightArray\\|null\\.$#" + count: 3 + path: ../../../src/world/light/LightUpdate.php + + - + message: "#^Cannot call method getFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" + count: 1 + path: ../../../src/world/light/LightUpdate.php + + - + message: "#^Only numeric types are allowed in \\-, int\\|null given on the right side\\.$#" + count: 1 + path: ../../../src/world/light/LightUpdate.php + + - + message: "#^Cannot call method getBlockSkyLightArray\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" + count: 1 + path: ../../../src/world/light/SkyLightUpdate.php + + - + message: "#^Only numeric types are allowed in \\-, int\\|null given on the right side\\.$#" + count: 1 + path: ../../../src/world/light/SkyLightUpdate.php + + - + message: "#^Parameter \\#4 \\$entityType of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\LevelSoundEventPacket\\:\\:create\\(\\) expects string, string\\|null given\\.$#" + count: 1 + path: ../../../src/world/sound/EntityLandSound.php + + - + message: "#^Parameter \\#4 \\$entityType of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\LevelSoundEventPacket\\:\\:create\\(\\) expects string, string\\|null given\\.$#" + count: 1 + path: ../../../src/world/sound/EntityLongFallSound.php + + - + message: "#^Parameter \\#4 \\$entityType of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\LevelSoundEventPacket\\:\\:create\\(\\) expects string, string\\|null given\\.$#" + count: 1 + path: ../../../src/world/sound/EntityShortFallSound.php + + - + message: "#^Property pocketmine\\\\event\\\\HandlerListManagerTest\\:\\:\\$isValidFunc \\(Closure\\) does not accept Closure\\|null\\.$#" + count: 1 + path: ../../phpunit/event/HandlerListManagerTest.php + + - + message: "#^Property pocketmine\\\\event\\\\HandlerListManagerTest\\:\\:\\$resolveParentFunc \\(Closure\\) does not accept Closure\\|null\\.$#" + count: 1 + path: ../../phpunit/event/HandlerListManagerTest.php + + - + message: "#^Property pocketmine\\\\network\\\\mcpe\\\\handler\\\\StupidJsonDecodeTest\\:\\:\\$stupidJsonDecodeFunc \\(Closure\\) does not accept Closure\\|null\\.$#" + count: 1 + path: ../../phpunit/network/mcpe/handler/StupidJsonDecodeTest.php From 148228e36060b896791d105d37fa9caf6fbb6f9a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 19 May 2020 12:26:18 +0100 Subject: [PATCH 1582/3224] update pocketmine/math, adapt to add() changes --- composer.lock | 8 ++++---- src/entity/Entity.php | 2 +- src/entity/Squid.php | 2 +- src/entity/object/ExperienceOrb.php | 2 +- src/entity/projectile/Projectile.php | 4 ++-- src/item/enchantment/KnockbackEnchantment.php | 2 +- src/world/Explosion.php | 4 ++-- src/world/World.php | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/composer.lock b/composer.lock index 9c0ccda230..0d00971ba9 100644 --- a/composer.lock +++ b/composer.lock @@ -552,12 +552,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "9aa4018635e7d634c535d4c7d9e032c7d905c29d" + "reference": "6d5af66a6c923bd8fad93258f3a1736091225aa1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/9aa4018635e7d634c535d4c7d9e032c7d905c29d", - "reference": "9aa4018635e7d634c535d4c7d9e032c7d905c29d", + "url": "https://api.github.com/repos/pmmp/Math/zipball/6d5af66a6c923bd8fad93258f3a1736091225aa1", + "reference": "6d5af66a6c923bd8fad93258f3a1736091225aa1", "shasum": "" }, "require": { @@ -579,7 +579,7 @@ "LGPL-3.0" ], "description": "PHP library containing math related code used in PocketMine-MP", - "time": "2020-01-28T14:13:55+00:00" + "time": "2020-05-19T11:19:57+00:00" }, { "name": "pocketmine/nbt", diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 29113e2094..b42a62c36d 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -746,7 +746,7 @@ abstract class Entity{ $diffPosition = $this->location->distanceSquared($this->lastLocation); $diffRotation = ($this->location->yaw - $this->lastLocation->yaw) ** 2 + ($this->location->pitch - $this->lastLocation->pitch) ** 2; - $diffMotion = $this->motion->subtract($this->lastMotion)->lengthSquared(); + $diffMotion = $this->motion->subtractVector($this->lastMotion)->lengthSquared(); $still = $this->motion->lengthSquared() == 0.0; $wasStill = $this->lastMotion->lengthSquared() == 0.0; diff --git a/src/entity/Squid.php b/src/entity/Squid.php index a2bed5329c..209f63a8bb 100644 --- a/src/entity/Squid.php +++ b/src/entity/Squid.php @@ -69,7 +69,7 @@ class Squid extends WaterAnimal{ $this->swimSpeed = mt_rand(150, 350) / 2000; $e = $source->getDamager(); if($e !== null){ - $this->swimDirection = $this->location->subtract($e->location)->normalize(); + $this->swimDirection = $this->location->subtractVector($e->location)->normalize(); } $this->broadcastAnimation(new SquidInkCloudAnimation($this)); diff --git a/src/entity/object/ExperienceOrb.php b/src/entity/object/ExperienceOrb.php index 69f47eb606..65f0ad89c8 100644 --- a/src/entity/object/ExperienceOrb.php +++ b/src/entity/object/ExperienceOrb.php @@ -190,7 +190,7 @@ class ExperienceOrb extends Entity{ $this->setTargetPlayer($currentTarget); if($currentTarget !== null){ - $vector = $currentTarget->getPosition()->add(0, $currentTarget->getEyeHeight() / 2, 0)->subtract($this->location)->divide(self::MAX_TARGET_DISTANCE); + $vector = $currentTarget->getPosition()->add(0, $currentTarget->getEyeHeight() / 2, 0)->subtractVector($this->location)->divide(self::MAX_TARGET_DISTANCE); $distance = $vector->lengthSquared(); if($distance < 1){ diff --git a/src/entity/projectile/Projectile.php b/src/entity/projectile/Projectile.php index 5a9777053f..018d28a515 100644 --- a/src/entity/projectile/Projectile.php +++ b/src/entity/projectile/Projectile.php @@ -176,7 +176,7 @@ abstract class Projectile extends Entity{ Timings::$entityMoveTimer->startTiming(); $start = $this->location->asVector3(); - $end = $start->add($this->motion); + $end = $start->addVector($this->motion); $blockHit = null; $entityHit = null; @@ -196,7 +196,7 @@ abstract class Projectile extends Entity{ $entityDistance = PHP_INT_MAX; - $newDiff = $end->subtract($start); + $newDiff = $end->subtractVector($start); foreach($this->getWorld()->getCollidingEntities($this->boundingBox->addCoord($newDiff->x, $newDiff->y, $newDiff->z)->expand(1, 1, 1), $this) as $entity){ if($entity->getId() === $this->getOwningEntityId() and $this->ticksLived < 5){ continue; diff --git a/src/item/enchantment/KnockbackEnchantment.php b/src/item/enchantment/KnockbackEnchantment.php index d504700036..5b37bbce0f 100644 --- a/src/item/enchantment/KnockbackEnchantment.php +++ b/src/item/enchantment/KnockbackEnchantment.php @@ -38,7 +38,7 @@ class KnockbackEnchantment extends MeleeWeaponEnchantment{ public function onPostAttack(Entity $attacker, Entity $victim, int $enchantmentLevel) : void{ if($victim instanceof Living){ - $diff = $victim->getPosition()->subtract($attacker->getPosition()); + $diff = $victim->getPosition()->subtractVector($attacker->getPosition()); $victim->knockBack($diff->x, $diff->z, $enchantmentLevel * 0.5); } } diff --git a/src/world/Explosion.php b/src/world/Explosion.php index f0cba16ed0..b75b9c7618 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -185,7 +185,7 @@ class Explosion{ $distance = $entityPos->distance($this->source) / $explosionSize; if($distance <= 1){ - $motion = $entityPos->subtract($this->source)->normalize(); + $motion = $entityPos->subtractVector($this->source)->normalize(); $impact = (1 - $distance) * ($exposure = 1); @@ -241,7 +241,7 @@ class Explosion{ $updateBlocks[$index] = true; } } - $send[] = $pos->subtract($source); + $send[] = $pos->subtractVector($source); } $this->world->addParticle($source, new HugeExplodeSeedParticle()); diff --git a/src/world/World.php b/src/world/World.php index f278a78dbc..8e88ab79cf 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1573,7 +1573,7 @@ class World implements ChunkManager{ } if($player !== null){ - if(($diff = $player->getNextPosition()->subtract($player->getPosition())) and $diff->lengthSquared() > 0.00001){ + if(($diff = $player->getNextPosition()->subtractVector($player->getPosition())) and $diff->lengthSquared() > 0.00001){ $bb = $player->getBoundingBox()->offsetCopy($diff->x, $diff->y, $diff->z); if($collisionBox->intersectsWith($bb)){ return false; //Inside player BB From 8a8b1b0b973348f4b9a40e34cb0bad7a30c53d06 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 19 May 2020 18:33:16 +0100 Subject: [PATCH 1583/3224] Remove Position->setWorld() --- src/block/Block.php | 5 +---- src/block/tile/Tile.php | 2 +- src/entity/Entity.php | 11 +++++++++-- src/world/Position.php | 22 +++++----------------- tests/phpstan/configs/gc-hacks.neon | 10 ++++++++++ 5 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/block/Block.php b/src/block/Block.php index f77607b463..88bb8e64e7 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -345,10 +345,7 @@ class Block{ * @internal */ final public function position(World $world, int $x, int $y, int $z) : void{ - $this->pos->x = $x; - $this->pos->y = $y; - $this->pos->z = $z; - $this->pos->world = $world; + $this->pos = new Position($x, $y, $z, $world); } /** diff --git a/src/block/tile/Tile.php b/src/block/tile/Tile.php index 8895b69421..4afcd3f23e 100644 --- a/src/block/tile/Tile.php +++ b/src/block/tile/Tile.php @@ -131,8 +131,8 @@ abstract class Tile{ if($this->pos->isValid()){ $this->pos->getWorldNonNull()->removeTile($this); - $this->pos->setWorld(null); } + $this->pos = null; } } } diff --git a/src/entity/Entity.php b/src/entity/Entity.php index b42a62c36d..cacca686c4 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1486,7 +1486,14 @@ abstract class Entity{ $this->despawnFromAll(); } - $this->location->setWorld($targetWorld); + $this->location = new Location( + $this->location->x, + $this->location->y, + $this->location->z, + $this->location->yaw, + $this->location->pitch, + $targetWorld + ); $this->getWorld()->addEntity($this); $this->chunk = null; @@ -1634,7 +1641,7 @@ abstract class Entity{ */ protected function destroyCycles() : void{ $this->chunk = null; - $this->location->setWorld(null); + $this->location = null; $this->lastDamageCause = null; } diff --git a/src/world/Position.php b/src/world/Position.php index 6ea8a0f192..c295a585f1 100644 --- a/src/world/Position.php +++ b/src/world/Position.php @@ -39,7 +39,11 @@ class Position extends Vector3{ */ public function __construct($x = 0, $y = 0, $z = 0, ?World $world = null){ parent::__construct($x, $y, $z); - $this->setWorld($world); + if($world !== null and $world->isClosed()){ + throw new \InvalidArgumentException("Specified world has been unloaded and cannot be used"); + } + + $this->world = $world; } /** @@ -85,22 +89,6 @@ class Position extends Vector3{ return $world; } - /** - * Sets the target world of the position. - * - * @return $this - * - * @throws \InvalidArgumentException if the specified World has been closed - */ - public function setWorld(?World $world){ - if($world !== null and $world->isClosed()){ - throw new \InvalidArgumentException("Specified world has been unloaded and cannot be used"); - } - - $this->world = $world; - return $this; - } - /** * Checks if this object has a valid reference to a loaded world */ diff --git a/tests/phpstan/configs/gc-hacks.neon b/tests/phpstan/configs/gc-hacks.neon index a2cb1cbc3e..d5814ad90f 100644 --- a/tests/phpstan/configs/gc-hacks.neon +++ b/tests/phpstan/configs/gc-hacks.neon @@ -20,6 +20,16 @@ parameters: count: 1 path: ../../../src/block/tile/Hopper.php + - + message: "#^Property pocketmine\\\\block\\\\tile\\\\Tile\\:\\:\\$pos \\(pocketmine\\\\world\\\\Position\\) does not accept null\\.$#" + count: 1 + path: ../../../src/block/tile/Tile.php + + - + message: "#^Property pocketmine\\\\entity\\\\Entity\\:\\:\\$location \\(pocketmine\\\\entity\\\\Location\\) does not accept null\\.$#" + count: 1 + path: ../../../src/entity/Entity.php + - message: "#^Property pocketmine\\\\entity\\\\Human\\:\\:\\$inventory \\(pocketmine\\\\inventory\\\\PlayerInventory\\) does not accept null\\.$#" count: 1 From 337addf1de57fa10ef41ca50b3c6cdf97ede6a57 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 19 May 2020 19:14:56 +0100 Subject: [PATCH 1584/3224] Eradicate remaining usages of public Position->world field and as an added bonus, ditch a bunch of extra phpstan errors --- src/block/tile/ContainerTrait.php | 2 +- src/block/utils/FallableTrait.php | 4 +- src/entity/Entity.php | 2 +- tests/phpstan/configs/l8-baseline.neon | 80 -------------------------- 4 files changed, 4 insertions(+), 84 deletions(-) diff --git a/src/block/tile/ContainerTrait.php b/src/block/tile/ContainerTrait.php index 76ebacf31d..f76944a6ad 100644 --- a/src/block/tile/ContainerTrait.php +++ b/src/block/tile/ContainerTrait.php @@ -96,7 +96,7 @@ trait ContainerTrait{ $pos = $this->getPos(); foreach($inv->getContents() as $k => $item){ - $pos->world->dropItem($pos->add(0.5, 0.5, 0.5), $item); + $pos->getWorldNonNull()->dropItem($pos->add(0.5, 0.5, 0.5), $item); } $inv->clearAll(); } diff --git a/src/block/utils/FallableTrait.php b/src/block/utils/FallableTrait.php index c1a0817035..b398dabe74 100644 --- a/src/block/utils/FallableTrait.php +++ b/src/block/utils/FallableTrait.php @@ -47,9 +47,9 @@ trait FallableTrait{ public function onNearbyBlockChange() : void{ $pos = $this->getPos(); - $down = $pos->world->getBlock($pos->getSide(Facing::DOWN)); + $down = $pos->getWorldNonNull()->getBlock($pos->getSide(Facing::DOWN)); if($down->getId() === BlockLegacyIds::AIR or $down instanceof Liquid or $down instanceof Fire){ - $pos->world->setBlock($pos, VanillaBlocks::AIR()); + $pos->getWorldNonNull()->setBlock($pos, VanillaBlocks::AIR()); $nbt = EntityFactory::createBaseNBT($pos->add(0.5, 0, 0.5)); $nbt->setInt("TileID", $this->getId()); diff --git a/src/entity/Entity.php b/src/entity/Entity.php index cacca686c4..6a9923830e 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1337,7 +1337,7 @@ abstract class Entity{ return false; } - if($pos instanceof Position and $pos->world !== null and $pos->world !== $this->getWorld()){ + if($pos instanceof Position and $pos->isValid() and $pos->getWorldNonNull() !== $this->getWorld()){ if(!$this->switchWorld($pos->getWorldNonNull())){ return false; } diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 5a522407c7..f5211c84bb 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -65,106 +65,26 @@ parameters: count: 1 path: ../../../src/block/tile/Chest.php - - - message: "#^Cannot call method dropItem\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" - count: 1 - path: ../../../src/block/tile/Chest.php - - message: "#^Argument of an invalid type pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null supplied for foreach, only iterables are supported\\.$#" count: 1 path: ../../../src/block/tile/BrewingStand.php - - - message: "#^Cannot call method dropItem\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" - count: 1 - path: ../../../src/block/tile/BrewingStand.php - - message: "#^Argument of an invalid type pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null supplied for foreach, only iterables are supported\\.$#" count: 1 path: ../../../src/block/tile/Furnace.php - - - message: "#^Cannot call method dropItem\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" - count: 1 - path: ../../../src/block/tile/Furnace.php - - message: "#^Argument of an invalid type pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null supplied for foreach, only iterables are supported\\.$#" count: 1 path: ../../../src/block/tile/Hopper.php - - - message: "#^Cannot call method dropItem\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" - count: 1 - path: ../../../src/block/tile/Hopper.php - - message: "#^Parameter \\#1 \\$nbt of method pocketmine\\\\block\\\\tile\\\\Tile\\:\\:readSaveData\\(\\) expects pocketmine\\\\nbt\\\\tag\\\\CompoundTag, pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null given\\.$#" count: 1 path: ../../../src/block/tile/Tile.php - - - message: "#^Cannot call method getBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" - count: 1 - path: ../../../src/block/Anvil.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" - count: 1 - path: ../../../src/block/Anvil.php - - - - message: "#^Cannot call method getBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" - count: 1 - path: ../../../src/block/ConcretePowder.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" - count: 1 - path: ../../../src/block/ConcretePowder.php - - - - message: "#^Cannot call method getBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" - count: 1 - path: ../../../src/block/DragonEgg.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" - count: 1 - path: ../../../src/block/DragonEgg.php - - - - message: "#^Cannot call method getBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" - count: 1 - path: ../../../src/block/Gravel.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" - count: 1 - path: ../../../src/block/Gravel.php - - - - message: "#^Cannot call method getBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" - count: 1 - path: ../../../src/block/Sand.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" - count: 1 - path: ../../../src/block/Sand.php - - - - message: "#^Cannot call method getBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" - count: 1 - path: ../../../src/block/SnowLayer.php - - - - message: "#^Cannot call method setBlock\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" - count: 1 - path: ../../../src/block/SnowLayer.php - - message: "#^Parameter \\#2 \\$replace of function str_replace expects array\\|string, string\\|null given\\.$#" count: 1 From 3f1f135a59078bd78a1fb8c87ba748c423a08000 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 19 May 2020 21:38:51 +0100 Subject: [PATCH 1585/3224] remove a couple more Position->getWorld() usages --- src/block/Block.php | 2 +- src/entity/Entity.php | 2 +- src/network/mcpe/NetworkSession.php | 5 ++--- tests/phpstan/configs/l8-baseline.neon | 10 ---------- 4 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/block/Block.php b/src/block/Block.php index 88bb8e64e7..d173807025 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -163,7 +163,7 @@ class Block{ } } if($oldTile === null and $tileType !== null){ - $this->pos->getWorldNonNull()->addTile(TileFactory::getInstance()->create($tileType, $this->pos->getWorld(), $this->pos->asVector3())); + $this->pos->getWorldNonNull()->addTile(TileFactory::getInstance()->create($tileType, $this->pos->getWorldNonNull(), $this->pos->asVector3())); } } diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 6a9923830e..01b01c2dab 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1329,7 +1329,7 @@ abstract class Entity{ } public function getWorld() : World{ - return $this->location->getWorld(); + return $this->location->getWorldNonNull(); } protected function setPosition(Vector3 $pos) : bool{ diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index ce295a065e..d5439a0a37 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -805,8 +805,7 @@ class NetworkSession{ public function startUsingChunk(int $chunkX, int $chunkZ, \Closure $onCompletion) : void{ Utils::validateCallableSignature(function(int $chunkX, int $chunkZ) : void{}, $onCompletion); - $world = $this->player->getLocation()->getWorld(); - assert($world !== null); + $world = $this->player->getLocation()->getWorldNonNull(); ChunkCache::getInstance($world, $this->compressor)->request($chunkX, $chunkZ)->onResolve( //this callback may be called synchronously or asynchronously, depending on whether the promise is resolved yet @@ -814,7 +813,7 @@ class NetworkSession{ if(!$this->isConnected()){ return; } - $currentWorld = $this->player->getLocation()->getWorld(); + $currentWorld = $this->player->getLocation()->getWorldNonNull(); if($world !== $currentWorld or !$this->player->isUsingChunk($chunkX, $chunkZ)){ $this->logger->debug("Tried to send no-longer-active chunk $chunkX $chunkZ in world " . $world->getFolderName()); return; diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 84cf6b1c82..be9bde78f9 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -25,11 +25,6 @@ parameters: count: 1 path: ../../../src/block/Block.php - - - message: "#^Parameter \\#2 \\$world of method pocketmine\\\\block\\\\tile\\\\TileFactory\\:\\:create\\(\\) expects pocketmine\\\\world\\\\World, pocketmine\\\\world\\\\World\\|null given\\.$#" - count: 1 - path: ../../../src/block/Block.php - - message: "#^Parameter \\#2 \\$item of method pocketmine\\\\world\\\\World\\:\\:dropItem\\(\\) expects pocketmine\\\\item\\\\Item, pocketmine\\\\item\\\\Item\\|null given\\.$#" count: 1 @@ -185,11 +180,6 @@ parameters: count: 1 path: ../../../src/entity/Entity.php - - - message: "#^Method pocketmine\\\\entity\\\\Entity\\:\\:getWorld\\(\\) should return pocketmine\\\\world\\\\World but returns pocketmine\\\\world\\\\World\\|null\\.$#" - count: 1 - path: ../../../src/entity/Entity.php - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\AddActorPacket\\:\\:\\$type \\(string\\) does not accept string\\|null\\.$#" count: 1 From b09379151a9ca5e9195750cc479ec06f46213537 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 19 May 2020 22:43:44 +0100 Subject: [PATCH 1586/3224] MainLogger: fix exception messages always reporting ErrorTypeToStringMap source if they have non-zero code --- src/utils/MainLogger.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/MainLogger.php b/src/utils/MainLogger.php index ed3abded9a..3a255abe9f 100644 --- a/src/utils/MainLogger.php +++ b/src/utils/MainLogger.php @@ -172,7 +172,7 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ $errno = $e->getCode(); try{ $errno = ErrorTypeToStringMap::get($errno); - }catch(\InvalidArgumentException $e){ + }catch(\InvalidArgumentException $ex){ //pass } From 82e257cf131c482cc261e7cd9f41ea91ac2bf544 Mon Sep 17 00:00:00 2001 From: Krzysztof Matuszak <53585406+KMatuszak@users.noreply.github.com> Date: Tue, 19 May 2020 23:44:57 +0200 Subject: [PATCH 1587/3224] BUILDING.md: Fixed wrong instruction of running from source (#3512) --- BUILDING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILDING.md b/BUILDING.md index 6853f5979d..92c78d06c3 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -35,4 +35,4 @@ Run `build/server-phar.php` using your preferred PHP binary. It'll drop a `Pocke You can also use the `--out` option to change the output filename. ## Running PocketMine-MP from source code -Run `src/pocketmine/PocketMine.php` using your preferred PHP binary. +Run `src/PocketMine.php` using your preferred PHP binary. From 3bb53658daf73f2f19f31bfd16377cbf3e6b968f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 May 2020 11:08:49 +0100 Subject: [PATCH 1588/3224] Do not allow remote clients to spawn themselves before we're ready this would have allowed clients to send SetLocalPlayerAsInitializedPacket at any time during the spawn sequence, which would have caused undefined behaviour around spawning logic. --- src/network/mcpe/NetworkSession.php | 9 +++- .../mcpe/handler/PreSpawnPacketHandler.php | 12 ----- .../handler/SpawnResponsePacketHandler.php | 47 +++++++++++++++++++ 3 files changed, 55 insertions(+), 13 deletions(-) create mode 100644 src/network/mcpe/handler/SpawnResponsePacketHandler.php diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index d5439a0a37..1a962a2523 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -51,6 +51,7 @@ use pocketmine\network\mcpe\handler\LoginPacketHandler; use pocketmine\network\mcpe\handler\PacketHandler; use pocketmine\network\mcpe\handler\PreSpawnPacketHandler; use pocketmine\network\mcpe\handler\ResourcePacksPacketHandler; +use pocketmine\network\mcpe\handler\SpawnResponsePacketHandler; use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; @@ -619,16 +620,22 @@ class NetworkSession{ $this->createPlayer(); $this->setHandler(new PreSpawnPacketHandler($this->server, $this->player, $this)); + $this->player->setImmobile(); //TODO: HACK: fix client-side falling pre-spawn + $this->logger->debug("Waiting for spawn chunks"); } public function onTerrainReady() : void{ $this->logger->debug("Sending spawn notification, waiting for spawn response"); $this->sendDataPacket(PlayStatusPacket::create(PlayStatusPacket::PLAYER_SPAWN)); + $this->setHandler(new SpawnResponsePacketHandler(function() : void{ + $this->onSpawn(); + })); } - public function onSpawn() : void{ + private function onSpawn() : void{ $this->logger->debug("Received spawn response, entering in-game phase"); + $this->player->setImmobile(false); //TODO: HACK: we set this during the spawn sequence to prevent the client sending junk movements $this->player->doFirstSpawn(); $this->setHandler(new InGamePacketHandler($this->player, $this)); } diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index d3ddb516f4..e71e755b70 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -27,7 +27,6 @@ use pocketmine\data\bedrock\LegacyItemIdToStringIdMap; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; -use pocketmine\network\mcpe\protocol\SetLocalPlayerAsInitializedPacket; use pocketmine\network\mcpe\protocol\StartGamePacket; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\StaticPacketCache; @@ -84,9 +83,6 @@ class PreSpawnPacketHandler extends PacketHandler{ $this->session->sendDataPacket(StaticPacketCache::getInstance()->getAvailableActorIdentifiers()); $this->session->sendDataPacket(StaticPacketCache::getInstance()->getBiomeDefs()); - - $this->player->setImmobile(); //HACK: fix client-side falling pre-spawn - $this->session->syncAttributes($this->player, $this->player->getAttributeMap()->getAll()); $this->session->syncAvailableCommands(); $this->session->syncAdventureSettings($this->player); @@ -108,12 +104,4 @@ class PreSpawnPacketHandler extends PacketHandler{ return true; } - - public function handleSetLocalPlayerAsInitialized(SetLocalPlayerAsInitializedPacket $packet) : bool{ - $this->player->setImmobile(false); //HACK: this is set to prevent client-side falling before spawn - - $this->session->onSpawn(); - - return true; - } } diff --git a/src/network/mcpe/handler/SpawnResponsePacketHandler.php b/src/network/mcpe/handler/SpawnResponsePacketHandler.php new file mode 100644 index 0000000000..cc33a69086 --- /dev/null +++ b/src/network/mcpe/handler/SpawnResponsePacketHandler.php @@ -0,0 +1,47 @@ +responseCallback = $responseCallback; + } + + public function handleSetLocalPlayerAsInitialized(SetLocalPlayerAsInitializedPacket $packet) : bool{ + ($this->responseCallback)(); + return true; + } +} From 64bb126bf5d39dd2f534189443d2d4860c01e793 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 May 2020 20:25:32 +0100 Subject: [PATCH 1589/3224] ignore some more l8 errors (architectural issue in NetworkSession) --- tests/phpstan/configs/l8-baseline.neon | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index be9bde78f9..b34208e492 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -445,6 +445,11 @@ parameters: count: 1 path: ../../../src/network/mcpe/NetworkSession.php + - + message: "#^Cannot call method setImmobile\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" + count: 2 + path: ../../../src/network/mcpe/NetworkSession.php + - message: "#^Cannot call method doFirstSpawn\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" count: 1 From 7aca41a530580f0f5f4d94bf27e26a0b1478ddd1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 May 2020 20:33:25 +0100 Subject: [PATCH 1590/3224] Living: do not loop downwards searching for collision block, closes #3517 --- src/entity/Living.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/entity/Living.php b/src/entity/Living.php index 96922f2001..febc3f1c2c 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -262,14 +262,13 @@ abstract class Living extends Entity{ }else{ $fallBlockPos = $this->location->floor(); $fallBlock = $this->getWorld()->getBlock($fallBlockPos); - for( - ; - $fallBlock->getId() === BlockLegacyIds::AIR; - $fallBlockPos = $fallBlockPos->subtract(0, 1, 0), $fallBlock = $this->getWorld()->getBlock($fallBlockPos) - ){ - //this allows the correct sound to be played when landing in snow + if($fallBlock->getId() === BlockLegacyIds::AIR){ + $fallBlockPos = $fallBlockPos->subtract(0, 1, 0); + $fallBlock = $this->getWorld()->getBlock($fallBlockPos); + } + if($fallBlock->getId() !== BlockLegacyIds::AIR){ + $this->getWorld()->addSound($this->location, new EntityLandSound($this, $fallBlock)); } - $this->getWorld()->addSound($this->location, new EntityLandSound($this, $fallBlock)); } } From 8ec2ba79de0c0f0fa43c8210b286e86ca33eb4ca Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 May 2020 11:38:02 +0100 Subject: [PATCH 1591/3224] Unhackify Registry member cloning, fixes #3519 --- src/block/VanillaBlocks.php | 8 +-- src/item/VanillaItems.php | 8 +-- src/utils/CloningRegistryTrait.php | 32 +++++++++++ src/utils/RegistryTrait.php | 11 +++- .../utils/CloningRegistryTraitTest.php | 55 +++++++++++++++++++ tests/phpunit/utils/TestCloningRegistry.php | 54 ++++++++++++++++++ 6 files changed, 158 insertions(+), 10 deletions(-) create mode 100644 src/utils/CloningRegistryTrait.php create mode 100644 tests/phpunit/utils/CloningRegistryTraitTest.php create mode 100644 tests/phpunit/utils/TestCloningRegistry.php diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 5da766624b..3371a7d251 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\utils\CloningRegistryTrait; use pocketmine\utils\RegistryTrait; -use pocketmine\utils\Utils; use function assert; /** @@ -665,7 +665,7 @@ use function assert; * @method static Wool YELLOW_WOOL() */ final class VanillaBlocks{ - use RegistryTrait; + use CloningRegistryTrait; private function __construct(){ //NOOP @@ -678,14 +678,14 @@ final class VanillaBlocks{ public static function fromString(string $name) : Block{ $result = self::_registryFromString($name); assert($result instanceof Block); - return clone $result; + return $result; } /** * @return Block[] */ public static function getAll() : array{ - return Utils::cloneObjectArray(self::_registryGetAll()); + return self::_registryGetAll(); } protected static function setup() : void{ diff --git a/src/item/VanillaItems.php b/src/item/VanillaItems.php index d8bb6b655a..a95604b8e4 100644 --- a/src/item/VanillaItems.php +++ b/src/item/VanillaItems.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\utils\CloningRegistryTrait; use pocketmine\utils\RegistryTrait; -use pocketmine\utils\Utils; use function assert; /** @@ -292,7 +292,7 @@ use function assert; * @method static Skull ZOMBIE_HEAD() */ final class VanillaItems{ - use RegistryTrait; + use CloningRegistryTrait; private function __construct(){ //NOOP @@ -305,14 +305,14 @@ final class VanillaItems{ public static function fromString(string $name) : Item{ $result = self::_registryFromString($name); assert($result instanceof Item); - return clone $result; + return $result; } /** * @return Item[] */ public static function getAll() : array{ - return Utils::cloneObjectArray(self::_registryGetAll()); + return self::_registryGetAll(); } protected static function setup() : void{ diff --git a/src/utils/CloningRegistryTrait.php b/src/utils/CloningRegistryTrait.php new file mode 100644 index 0000000000..af815658eb --- /dev/null +++ b/src/utils/CloningRegistryTrait.php @@ -0,0 +1,32 @@ + + */ + public function cloningRegistryMembersProvider() : \Generator{ + yield [function() : \stdClass{ return TestCloningRegistry::TEST1(); }]; + yield [function() : \stdClass{ return TestCloningRegistry::TEST2(); }]; + yield [function() : \stdClass{ return TestCloningRegistry::TEST3(); }]; + } + + /** + * @dataProvider cloningRegistryMembersProvider + * @phpstan-param \Closure() : \stdClass $provider + */ + public function testEachMemberClone(\Closure $provider) : void{ + self::assertNotSame($provider(), $provider(), "Cloning registry should never return the same object twice"); + } + + public function testGetAllClone() : void{ + $list1 = TestCloningRegistry::getAll(); + $list2 = TestCloningRegistry::getAll(); + foreach($list1 as $k => $member){ + self::assertNotSame($member, $list2[$k], "VanillaBlocks ought to clone its members"); + } + } +} diff --git a/tests/phpunit/utils/TestCloningRegistry.php b/tests/phpunit/utils/TestCloningRegistry.php new file mode 100644 index 0000000000..5683fd11bc --- /dev/null +++ b/tests/phpunit/utils/TestCloningRegistry.php @@ -0,0 +1,54 @@ + Date: Thu, 21 May 2020 11:46:43 +0100 Subject: [PATCH 1592/3224] Slab: ignore silk touch on breaking tools, closes #2794 --- src/block/Slab.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/block/Slab.php b/src/block/Slab.php index 275aa8bf8a..fec34afacd 100644 --- a/src/block/Slab.php +++ b/src/block/Slab.php @@ -128,4 +128,8 @@ class Slab extends Transparent{ public function getDropsForCompatibleTool(Item $item) : array{ return [$this->asItem()->setCount($this->slabType->equals(SlabType::DOUBLE()) ? 2 : 1)]; } + + public function isAffectedBySilkTouch() : bool{ + return false; + } } From 8e2b9b686b35bdcf2a452aa0a83bac5561101c39 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 May 2020 13:02:36 +0100 Subject: [PATCH 1593/3224] Block: Invert default behaviour of silk touch (more logical) Now, blocks do not respond to silk touch unless specifically opted into. Since this always involves custom drops in one way or another, it's easy enough to figure out which blocks need to be marked for silk touch - anything that overrides getDrops, getDropsForCompatibleTool or getSilkTouchDrops is a block which _might_ need to be flagged. Using these criteria to reduce the number of blocks needing to be checked, I was able to manually invert the behaviour as needed. This fixes reoccurring bugs with blocks erroneously dropping themselves whenever new blocks are added and someone forgot to set that flag, granting players access to internal blocks with strange behaviour. --- src/block/Banner.php | 4 ---- src/block/Block.php | 5 ++--- src/block/BlockFactory.php | 4 ++++ src/block/Bookshelf.php | 4 ++++ src/block/BrownMushroomBlock.php | 4 ++++ src/block/Cake.php | 4 ---- src/block/Clay.php | 4 ++++ src/block/CoalOre.php | 4 ++++ src/block/Cobweb.php | 4 ++++ src/block/CocoaBlock.php | 4 ---- src/block/Crops.php | 4 ---- src/block/DeadBush.php | 4 ++++ src/block/DiamondOre.php | 4 ++++ src/block/EmeraldOre.php | 4 ++++ src/block/Farmland.php | 4 ---- src/block/FlowerPot.php | 4 ---- src/block/Glass.php | 4 ++++ src/block/GlassPane.php | 4 ++++ src/block/Glowstone.php | 4 ++++ src/block/Grass.php | 4 ++++ src/block/GrassPath.php | 4 ++++ src/block/Gravel.php | 4 ++++ src/block/Ice.php | 4 ++++ src/block/InfestedStone.php | 4 ++++ src/block/ItemFrame.php | 4 ---- src/block/LapisOre.php | 4 ++++ src/block/Melon.php | 4 ++++ src/block/MonsterSpawner.php | 4 ---- src/block/Mycelium.php | 4 ++++ src/block/NetherQuartzOre.php | 4 ++++ src/block/PackedIce.php | 4 ++++ src/block/RedMushroomBlock.php | 4 ++++ src/block/RedstoneOre.php | 4 ++++ src/block/SeaLantern.php | 4 ++++ src/block/Slab.php | 4 ---- src/block/Snow.php | 4 ++++ src/block/SnowLayer.php | 4 ---- src/block/Tripwire.php | 4 ---- 38 files changed, 106 insertions(+), 47 deletions(-) diff --git a/src/block/Banner.php b/src/block/Banner.php index cb4a5449fe..2be5e82e7a 100644 --- a/src/block/Banner.php +++ b/src/block/Banner.php @@ -195,8 +195,4 @@ class Banner extends Transparent{ } return $result; } - - public function isAffectedBySilkTouch() : bool{ - return false; - } } diff --git a/src/block/Block.php b/src/block/Block.php index d173807025..b2fda913d3 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -402,11 +402,10 @@ class Block{ } /** - * Returns whether Silk Touch enchanted tools will cause this block to drop as itself. Since most blocks drop - * themselves anyway, this is implicitly true. + * Returns whether Silk Touch enchanted tools will cause this block to drop as itself. */ public function isAffectedBySilkTouch() : bool{ - return true; + return false; } /** diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index bb33876603..1abdc06524 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -325,6 +325,10 @@ class BlockFactory{ public function getDropsForCompatibleTool(Item $item) : array{ return [VanillaBlocks::COBBLESTONE()->asItem()]; } + + public function isAffectedBySilkTouch() : bool{ + return true; + } }); $this->register(new Stair(new BID(Ids::NORMAL_STONE_STAIRS), "Stone Stairs", $stoneBreakInfo)); $this->register(new Opaque(new BID(Ids::SMOOTH_STONE), "Smooth Stone", $stoneBreakInfo)); diff --git a/src/block/Bookshelf.php b/src/block/Bookshelf.php index f4af2e1116..e72d99b96f 100644 --- a/src/block/Bookshelf.php +++ b/src/block/Bookshelf.php @@ -38,6 +38,10 @@ class Bookshelf extends Opaque{ ]; } + public function isAffectedBySilkTouch() : bool{ + return true; + } + public function getFuelTime() : int{ return 300; } diff --git a/src/block/BrownMushroomBlock.php b/src/block/BrownMushroomBlock.php index 09b183491b..47f2ff07dc 100644 --- a/src/block/BrownMushroomBlock.php +++ b/src/block/BrownMushroomBlock.php @@ -33,4 +33,8 @@ class BrownMushroomBlock extends RedMushroomBlock{ VanillaBlocks::BROWN_MUSHROOM()->asItem()->setCount(mt_rand(0, 2)) ]; } + + public function isAffectedBySilkTouch() : bool{ + return true; + } } diff --git a/src/block/Cake.php b/src/block/Cake.php index 23ed7b3b85..200d2e2a39 100644 --- a/src/block/Cake.php +++ b/src/block/Cake.php @@ -86,10 +86,6 @@ class Cake extends Transparent implements FoodSource{ return []; } - public function isAffectedBySilkTouch() : bool{ - return false; - } - public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $player->consumeObject($this); diff --git a/src/block/Clay.php b/src/block/Clay.php index b3b51e2dd5..2947a50bef 100644 --- a/src/block/Clay.php +++ b/src/block/Clay.php @@ -37,4 +37,8 @@ class Clay extends Opaque{ VanillaItems::CLAY()->setCount(4) ]; } + + public function isAffectedBySilkTouch() : bool{ + return true; + } } diff --git a/src/block/CoalOre.php b/src/block/CoalOre.php index 434e5ee0bf..33b514c09a 100644 --- a/src/block/CoalOre.php +++ b/src/block/CoalOre.php @@ -40,6 +40,10 @@ class CoalOre extends Opaque{ ]; } + public function isAffectedBySilkTouch() : bool{ + return true; + } + protected function getXpDropAmount() : int{ return mt_rand(0, 2); } diff --git a/src/block/Cobweb.php b/src/block/Cobweb.php index 82c42422de..e28bf19a7e 100644 --- a/src/block/Cobweb.php +++ b/src/block/Cobweb.php @@ -47,6 +47,10 @@ class Cobweb extends Flowable{ ]; } + public function isAffectedBySilkTouch() : bool{ + return true; + } + public function diffusesSkyLight() : bool{ return true; } diff --git a/src/block/CocoaBlock.php b/src/block/CocoaBlock.php index c4be193975..02534a10a2 100644 --- a/src/block/CocoaBlock.php +++ b/src/block/CocoaBlock.php @@ -59,10 +59,6 @@ class CocoaBlock extends Transparent{ return 0b1111; } - public function isAffectedBySilkTouch() : bool{ - return false; - } - /** * @return AxisAlignedBB[] */ diff --git a/src/block/Crops.php b/src/block/Crops.php index 0abc972259..1d96ff210c 100644 --- a/src/block/Crops.php +++ b/src/block/Crops.php @@ -104,8 +104,4 @@ abstract class Crops extends Flowable{ } } } - - public function isAffectedBySilkTouch() : bool{ - return false; - } } diff --git a/src/block/DeadBush.php b/src/block/DeadBush.php index 7828ad4940..611c675961 100644 --- a/src/block/DeadBush.php +++ b/src/block/DeadBush.php @@ -61,6 +61,10 @@ class DeadBush extends Flowable{ return parent::getDrops($item); } + public function isAffectedBySilkTouch() : bool{ + return true; + } + public function getFlameEncouragement() : int{ return 60; } diff --git a/src/block/DiamondOre.php b/src/block/DiamondOre.php index 44d89c9667..c6d104ba5d 100644 --- a/src/block/DiamondOre.php +++ b/src/block/DiamondOre.php @@ -40,6 +40,10 @@ class DiamondOre extends Opaque{ ]; } + public function isAffectedBySilkTouch() : bool{ + return true; + } + protected function getXpDropAmount() : int{ return mt_rand(3, 7); } diff --git a/src/block/EmeraldOre.php b/src/block/EmeraldOre.php index aa9b95c27b..ec630c3bba 100644 --- a/src/block/EmeraldOre.php +++ b/src/block/EmeraldOre.php @@ -40,6 +40,10 @@ class EmeraldOre extends Opaque{ ]; } + public function isAffectedBySilkTouch() : bool{ + return true; + } + protected function getXpDropAmount() : int{ return mt_rand(3, 7); } diff --git a/src/block/Farmland.php b/src/block/Farmland.php index 1752479ce3..a18d6119fd 100644 --- a/src/block/Farmland.php +++ b/src/block/Farmland.php @@ -103,10 +103,6 @@ class Farmland extends Transparent{ ]; } - public function isAffectedBySilkTouch() : bool{ - return false; - } - public function getPickedItem(bool $addUserData = false) : Item{ return VanillaBlocks::DIRT()->asItem(); } diff --git a/src/block/FlowerPot.php b/src/block/FlowerPot.php index ddd6d6e473..a60e8bc09f 100644 --- a/src/block/FlowerPot.php +++ b/src/block/FlowerPot.php @@ -151,8 +151,4 @@ class FlowerPot extends Flowable{ public function getPickedItem(bool $addUserData = false) : Item{ return $this->plant !== null ? $this->plant->asItem() : parent::getPickedItem($addUserData); } - - public function isAffectedBySilkTouch() : bool{ - return false; - } } diff --git a/src/block/Glass.php b/src/block/Glass.php index 5ba7742f5f..1eb1d35168 100644 --- a/src/block/Glass.php +++ b/src/block/Glass.php @@ -34,4 +34,8 @@ class Glass extends Transparent{ public function getDropsForCompatibleTool(Item $item) : array{ return []; } + + public function isAffectedBySilkTouch() : bool{ + return true; + } } diff --git a/src/block/GlassPane.php b/src/block/GlassPane.php index 464b178a7d..a549ef4ccc 100644 --- a/src/block/GlassPane.php +++ b/src/block/GlassPane.php @@ -34,4 +34,8 @@ class GlassPane extends Thin{ public function getDropsForCompatibleTool(Item $item) : array{ return []; } + + public function isAffectedBySilkTouch() : bool{ + return true; + } } diff --git a/src/block/Glowstone.php b/src/block/Glowstone.php index 47785dd722..aa63125af7 100644 --- a/src/block/Glowstone.php +++ b/src/block/Glowstone.php @@ -42,4 +42,8 @@ class Glowstone extends Transparent{ VanillaItems::GLOWSTONE_DUST()->setCount(mt_rand(2, 4)) ]; } + + public function isAffectedBySilkTouch() : bool{ + return true; + } } diff --git a/src/block/Grass.php b/src/block/Grass.php index 7c74d4b08c..67bbcfb0f3 100644 --- a/src/block/Grass.php +++ b/src/block/Grass.php @@ -47,6 +47,10 @@ class Grass extends Opaque{ ]; } + public function isAffectedBySilkTouch() : bool{ + return true; + } + public function ticksRandomly() : bool{ return true; } diff --git a/src/block/GrassPath.php b/src/block/GrassPath.php index 98611bc2ef..011d0525b9 100644 --- a/src/block/GrassPath.php +++ b/src/block/GrassPath.php @@ -51,4 +51,8 @@ class GrassPath extends Transparent{ VanillaBlocks::DIRT()->asItem() ]; } + + public function isAffectedBySilkTouch() : bool{ + return true; + } } diff --git a/src/block/Gravel.php b/src/block/Gravel.php index 1089b58933..a3cf7b07ef 100644 --- a/src/block/Gravel.php +++ b/src/block/Gravel.php @@ -46,6 +46,10 @@ class Gravel extends Opaque implements Fallable{ return parent::getDropsForCompatibleTool($item); } + public function isAffectedBySilkTouch() : bool{ + return true; + } + public function tickFalling() : ?Block{ return null; } diff --git a/src/block/Ice.php b/src/block/Ice.php index a908d27265..b825991ab0 100644 --- a/src/block/Ice.php +++ b/src/block/Ice.php @@ -62,4 +62,8 @@ class Ice extends Transparent{ public function getDropsForCompatibleTool(Item $item) : array{ return []; } + + public function isAffectedBySilkTouch() : bool{ + return true; + } } diff --git a/src/block/InfestedStone.php b/src/block/InfestedStone.php index 1457daf4c6..d19737ebde 100644 --- a/src/block/InfestedStone.php +++ b/src/block/InfestedStone.php @@ -35,5 +35,9 @@ abstract class InfestedStone extends Opaque{ return []; } + public function isAffectedBySilkTouch() : bool{ + return true; + } + //TODO } diff --git a/src/block/ItemFrame.php b/src/block/ItemFrame.php index 885b7eda66..625a5c3880 100644 --- a/src/block/ItemFrame.php +++ b/src/block/ItemFrame.php @@ -177,8 +177,4 @@ class ItemFrame extends Flowable{ public function getPickedItem(bool $addUserData = false) : Item{ return $this->framedItem !== null ? clone $this->framedItem : parent::getPickedItem($addUserData); } - - public function isAffectedBySilkTouch() : bool{ - return false; - } } diff --git a/src/block/LapisOre.php b/src/block/LapisOre.php index f79a952398..fc4accccbd 100644 --- a/src/block/LapisOre.php +++ b/src/block/LapisOre.php @@ -40,6 +40,10 @@ class LapisOre extends Opaque{ ]; } + public function isAffectedBySilkTouch() : bool{ + return true; + } + protected function getXpDropAmount() : int{ return mt_rand(2, 5); } diff --git a/src/block/Melon.php b/src/block/Melon.php index 40bc3a8777..35502475e7 100644 --- a/src/block/Melon.php +++ b/src/block/Melon.php @@ -38,4 +38,8 @@ class Melon extends Transparent{ VanillaItems::MELON()->setCount(mt_rand(3, 7)) ]; } + + public function isAffectedBySilkTouch() : bool{ + return true; + } } diff --git a/src/block/MonsterSpawner.php b/src/block/MonsterSpawner.php index b27f6c0d8d..d2599e134b 100644 --- a/src/block/MonsterSpawner.php +++ b/src/block/MonsterSpawner.php @@ -37,10 +37,6 @@ class MonsterSpawner extends Transparent{ return []; } - public function isAffectedBySilkTouch() : bool{ - return false; - } - protected function getXpDropAmount() : int{ return mt_rand(15, 43); } diff --git a/src/block/Mycelium.php b/src/block/Mycelium.php index 7e80a06ae8..d3dce32f9f 100644 --- a/src/block/Mycelium.php +++ b/src/block/Mycelium.php @@ -40,6 +40,10 @@ class Mycelium extends Opaque{ ]; } + public function isAffectedBySilkTouch() : bool{ + return true; + } + public function ticksRandomly() : bool{ return true; } diff --git a/src/block/NetherQuartzOre.php b/src/block/NetherQuartzOre.php index 598ded41d0..eab0898c48 100644 --- a/src/block/NetherQuartzOre.php +++ b/src/block/NetherQuartzOre.php @@ -40,6 +40,10 @@ class NetherQuartzOre extends Opaque{ ]; } + public function isAffectedBySilkTouch() : bool{ + return true; + } + protected function getXpDropAmount() : int{ return mt_rand(2, 5); } diff --git a/src/block/PackedIce.php b/src/block/PackedIce.php index 852b07e3c9..0d52af4aa7 100644 --- a/src/block/PackedIce.php +++ b/src/block/PackedIce.php @@ -38,4 +38,8 @@ class PackedIce extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ return []; } + + public function isAffectedBySilkTouch() : bool{ + return true; + } } diff --git a/src/block/RedMushroomBlock.php b/src/block/RedMushroomBlock.php index 2e9a43fa70..90aebcc1e7 100644 --- a/src/block/RedMushroomBlock.php +++ b/src/block/RedMushroomBlock.php @@ -58,4 +58,8 @@ class RedMushroomBlock extends Opaque{ VanillaBlocks::RED_MUSHROOM()->asItem()->setCount(mt_rand(0, 2)) ]; } + + public function isAffectedBySilkTouch() : bool{ + return true; + } } diff --git a/src/block/RedstoneOre.php b/src/block/RedstoneOre.php index ef6fcee95b..5981b19ad3 100644 --- a/src/block/RedstoneOre.php +++ b/src/block/RedstoneOre.php @@ -97,6 +97,10 @@ class RedstoneOre extends Opaque{ ]; } + public function isAffectedBySilkTouch() : bool{ + return true; + } + protected function getXpDropAmount() : int{ return mt_rand(1, 5); } diff --git a/src/block/SeaLantern.php b/src/block/SeaLantern.php index a076fc02d4..d222cf0520 100644 --- a/src/block/SeaLantern.php +++ b/src/block/SeaLantern.php @@ -41,4 +41,8 @@ class SeaLantern extends Transparent{ VanillaItems::PRISMARINE_CRYSTALS()->setCount(3) ]; } + + public function isAffectedBySilkTouch() : bool{ + return true; + } } diff --git a/src/block/Slab.php b/src/block/Slab.php index fec34afacd..275aa8bf8a 100644 --- a/src/block/Slab.php +++ b/src/block/Slab.php @@ -128,8 +128,4 @@ class Slab extends Transparent{ public function getDropsForCompatibleTool(Item $item) : array{ return [$this->asItem()->setCount($this->slabType->equals(SlabType::DOUBLE()) ? 2 : 1)]; } - - public function isAffectedBySilkTouch() : bool{ - return false; - } } diff --git a/src/block/Snow.php b/src/block/Snow.php index 9d227333a4..19077382d6 100644 --- a/src/block/Snow.php +++ b/src/block/Snow.php @@ -38,4 +38,8 @@ class Snow extends Opaque{ VanillaItems::SNOWBALL()->setCount(4) ]; } + + public function isAffectedBySilkTouch() : bool{ + return true; + } } diff --git a/src/block/SnowLayer.php b/src/block/SnowLayer.php index 5a78b9c17f..de2ffd7798 100644 --- a/src/block/SnowLayer.php +++ b/src/block/SnowLayer.php @@ -105,8 +105,4 @@ class SnowLayer extends Flowable implements Fallable{ VanillaItems::SNOWBALL()->setCount(max(1, (int) floor($this->layers / 2))) ]; } - - public function isAffectedBySilkTouch() : bool{ - return false; - } } diff --git a/src/block/Tripwire.php b/src/block/Tripwire.php index f0d9f20947..6aa56ce30d 100644 --- a/src/block/Tripwire.php +++ b/src/block/Tripwire.php @@ -55,8 +55,4 @@ class Tripwire extends Flowable{ public function getStateBitmask() : int{ return 0b1111; } - - public function isAffectedBySilkTouch() : bool{ - return false; - } } From f93bc0739c213bcb589aa2e431b525208fa04260 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 May 2020 19:12:48 +0100 Subject: [PATCH 1594/3224] Force types of RegistryTrait usages to shut PHPStan up we need generic traits to solve this problem properly. --- src/block/VanillaBlocks.php | 5 +- src/entity/effect/VanillaEffects.php | 5 +- src/item/VanillaItems.php | 5 +- src/utils/EnumTrait.php | 10 +- tests/phpstan/configs/l7-baseline.neon | 135 -------------------- tests/phpunit/utils/TestCloningRegistry.php | 8 +- 6 files changed, 26 insertions(+), 142 deletions(-) diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 3371a7d251..faf49a9033 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -685,7 +685,10 @@ final class VanillaBlocks{ * @return Block[] */ public static function getAll() : array{ - return self::_registryGetAll(); + //phpstan doesn't support generic traits yet :( + /** @var Block[] $result */ + $result = self::_registryGetAll(); + return $result; } protected static function setup() : void{ diff --git a/src/entity/effect/VanillaEffects.php b/src/entity/effect/VanillaEffects.php index 9efc7add99..3458fc5874 100644 --- a/src/entity/effect/VanillaEffects.php +++ b/src/entity/effect/VanillaEffects.php @@ -112,7 +112,10 @@ final class VanillaEffects{ * @return Effect[] */ public static function getAll() : array{ - return self::_registryGetAll(); + //phpstan doesn't support generic traits yet :( + /** @var Effect[] $result */ + $result = self::_registryGetAll(); + return $result; } public static function fromString(string $name) : Effect{ diff --git a/src/item/VanillaItems.php b/src/item/VanillaItems.php index a95604b8e4..e44aa31b7d 100644 --- a/src/item/VanillaItems.php +++ b/src/item/VanillaItems.php @@ -312,7 +312,10 @@ final class VanillaItems{ * @return Item[] */ public static function getAll() : array{ - return self::_registryGetAll(); + //phpstan doesn't support generic traits yet :( + /** @var Item[] $result */ + $result = self::_registryGetAll(); + return $result; } protected static function setup() : void{ diff --git a/src/utils/EnumTrait.php b/src/utils/EnumTrait.php index 6f6aa517c4..8eb2a10755 100644 --- a/src/utils/EnumTrait.php +++ b/src/utils/EnumTrait.php @@ -51,7 +51,10 @@ trait EnumTrait{ * @return self[] */ public static function getAll() : array{ - return self::_registryGetAll(); + //phpstan doesn't support generic traits yet :( + /** @var self[] $result */ + $result = self::_registryGetAll(); + return $result; } /** @@ -61,7 +64,10 @@ trait EnumTrait{ * @throws \InvalidArgumentException if no member matches. */ public static function fromString(string $name) : self{ - return self::_registryFromString($name); + //phpstan doesn't support generic traits yet :( + /** @var self $result */ + $result = self::_registryFromString($name); + return $result; } /** @var int|null */ diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index 7225ec7932..51bbcd87b0 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -420,11 +420,6 @@ parameters: count: 2 path: ../../../src/block/Sugarcane.php - - - message: "#^Method pocketmine\\\\block\\\\VanillaBlocks\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" - count: 1 - path: ../../../src/block/VanillaBlocks.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getTileAt\\(\\) expects int, float\\|int given\\.$#" count: 1 @@ -555,11 +550,6 @@ parameters: count: 1 path: ../../../src/entity/Skin.php - - - message: "#^Method pocketmine\\\\entity\\\\effect\\\\VanillaEffects\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" - count: 1 - path: ../../../src/entity/effect/VanillaEffects.php - - message: "#^Parameter \\#2 \\$x of method pocketmine\\\\block\\\\Block\\:\\:position\\(\\) expects int, float\\|int given\\.$#" count: 1 @@ -630,11 +620,6 @@ parameters: count: 1 path: ../../../src/item/ItemFactory.php - - - message: "#^Method pocketmine\\\\item\\\\VanillaItems\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" - count: 1 - path: ../../../src/item/VanillaItems.php - - message: "#^Parameter \\#2 \\$input1 of function array_map expects array, array\\|false given\\.$#" count: 1 @@ -795,126 +780,6 @@ parameters: count: 2 path: ../../../src/scheduler/AsyncPool.php - - - message: "#^Method pocketmine\\\\block\\\\utils\\\\DyeColor\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" - count: 1 - path: ../../../src/block/utils/DyeColor.php - - - - message: "#^Method pocketmine\\\\block\\\\utils\\\\DyeColor\\:\\:fromString\\(\\) should return pocketmine\\\\block\\\\utils\\\\DyeColor but returns object\\.$#" - count: 1 - path: ../../../src/block/utils/DyeColor.php - - - - message: "#^Method pocketmine\\\\block\\\\utils\\\\SkullType\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" - count: 1 - path: ../../../src/block/utils/SkullType.php - - - - message: "#^Method pocketmine\\\\block\\\\utils\\\\SkullType\\:\\:fromString\\(\\) should return pocketmine\\\\block\\\\utils\\\\SkullType but returns object\\.$#" - count: 1 - path: ../../../src/block/utils/SkullType.php - - - - message: "#^Method pocketmine\\\\block\\\\utils\\\\SlabType\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" - count: 1 - path: ../../../src/block/utils/SlabType.php - - - - message: "#^Method pocketmine\\\\block\\\\utils\\\\SlabType\\:\\:fromString\\(\\) should return pocketmine\\\\block\\\\utils\\\\SlabType but returns object\\.$#" - count: 1 - path: ../../../src/block/utils/SlabType.php - - - - message: "#^Method pocketmine\\\\block\\\\utils\\\\StairShape\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" - count: 1 - path: ../../../src/block/utils/StairShape.php - - - - message: "#^Method pocketmine\\\\block\\\\utils\\\\StairShape\\:\\:fromString\\(\\) should return pocketmine\\\\block\\\\utils\\\\StairShape but returns object\\.$#" - count: 1 - path: ../../../src/block/utils/StairShape.php - - - - message: "#^Method pocketmine\\\\block\\\\utils\\\\TreeType\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" - count: 1 - path: ../../../src/block/utils/TreeType.php - - - - message: "#^Method pocketmine\\\\block\\\\utils\\\\TreeType\\:\\:fromString\\(\\) should return pocketmine\\\\block\\\\utils\\\\TreeType but returns object\\.$#" - count: 1 - path: ../../../src/block/utils/TreeType.php - - - - message: "#^Method pocketmine\\\\item\\\\ItemUseResult\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" - count: 1 - path: ../../../src/item/ItemUseResult.php - - - - message: "#^Method pocketmine\\\\item\\\\ItemUseResult\\:\\:fromString\\(\\) should return pocketmine\\\\item\\\\ItemUseResult but returns object\\.$#" - count: 1 - path: ../../../src/item/ItemUseResult.php - - - - message: "#^Method pocketmine\\\\item\\\\ToolTier\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" - count: 1 - path: ../../../src/item/ToolTier.php - - - - message: "#^Method pocketmine\\\\item\\\\ToolTier\\:\\:fromString\\(\\) should return pocketmine\\\\item\\\\ToolTier but returns object\\.$#" - count: 1 - path: ../../../src/item/ToolTier.php - - - - message: "#^Method pocketmine\\\\player\\\\GameMode\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" - count: 1 - path: ../../../src/player/GameMode.php - - - - message: "#^Method pocketmine\\\\player\\\\GameMode\\:\\:fromString\\(\\) should return pocketmine\\\\player\\\\GameMode but returns object\\.$#" - count: 1 - path: ../../../src/player/GameMode.php - - - - message: "#^Method pocketmine\\\\player\\\\UsedChunkStatus\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" - count: 1 - path: ../../../src/player/UsedChunkStatus.php - - - - message: "#^Method pocketmine\\\\player\\\\UsedChunkStatus\\:\\:fromString\\(\\) should return pocketmine\\\\player\\\\UsedChunkStatus but returns object\\.$#" - count: 1 - path: ../../../src/player/UsedChunkStatus.php - - - - message: "#^Method pocketmine\\\\plugin\\\\PluginLoadOrder\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" - count: 1 - path: ../../../src/plugin/PluginLoadOrder.php - - - - message: "#^Method pocketmine\\\\plugin\\\\PluginLoadOrder\\:\\:fromString\\(\\) should return pocketmine\\\\plugin\\\\PluginLoadOrder but returns object\\.$#" - count: 1 - path: ../../../src/plugin/PluginLoadOrder.php - - - - message: "#^Method pocketmine\\\\utils\\\\TestEnum\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" - count: 1 - path: ../../phpunit/utils/TestEnum.php - - - - message: "#^Method pocketmine\\\\utils\\\\TestEnum\\:\\:fromString\\(\\) should return pocketmine\\\\utils\\\\TestEnum but returns object\\.$#" - count: 1 - path: ../../phpunit/utils/TestEnum.php - - - - message: "#^Method pocketmine\\\\world\\\\sound\\\\NoteInstrument\\:\\:getAll\\(\\) should return array\\ but returns array\\\\.$#" - count: 1 - path: ../../../src/world/sound/NoteInstrument.php - - - - message: "#^Method pocketmine\\\\world\\\\sound\\\\NoteInstrument\\:\\:fromString\\(\\) should return pocketmine\\\\world\\\\sound\\\\NoteInstrument but returns object\\.$#" - count: 1 - path: ../../../src/world/sound/NoteInstrument.php - - message: "#^Parameter \\#2 \\$subject of function preg_match expects string, string\\|false given\\.$#" count: 1 diff --git a/tests/phpunit/utils/TestCloningRegistry.php b/tests/phpunit/utils/TestCloningRegistry.php index 5683fd11bc..edc7a4102b 100644 --- a/tests/phpunit/utils/TestCloningRegistry.php +++ b/tests/phpunit/utils/TestCloningRegistry.php @@ -39,11 +39,15 @@ final class TestCloningRegistry{ * @return \stdClass[] */ public static function getAll() : array{ - return self::_registryGetAll(); + /** @var \stdClass[] $result */ + $result = self::_registryGetAll(); + return $result; } public static function fromString(string $s) : \stdClass{ - return self::_registryFromString($s); + /** @var \stdClass $result */ + $result = self::_registryFromString($s); + return $result; } protected static function setup() : void{ From 74e1f6320a2ffd9ebe697151e4dc1c6228b94aaf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 May 2020 19:18:00 +0100 Subject: [PATCH 1595/3224] Store attributes as local vars, reduce usage of AttributeMap ideally we want attribute map to only be used for properties that need synchronization. --- src/entity/AttributeFactory.php | 8 ++++++ src/entity/ExperienceManager.php | 5 ++-- src/entity/HungerManager.php | 5 ++-- src/entity/Living.php | 31 ++++++++++++++--------- tests/phpstan/configs/l8-baseline.neon | 35 -------------------------- 5 files changed, 33 insertions(+), 51 deletions(-) diff --git a/src/entity/AttributeFactory.php b/src/entity/AttributeFactory.php index 5a9cd77e3d..e25f7c1c4a 100644 --- a/src/entity/AttributeFactory.php +++ b/src/entity/AttributeFactory.php @@ -54,6 +54,14 @@ final class AttributeFactory{ return isset($this->attributes[$id]) ? clone $this->attributes[$id] : null; } + public function mustGet(string $id) : Attribute{ + $result = $this->get($id); + if($result === null){ + throw new \InvalidArgumentException("Attribute $id is not registered"); + } + return $result; + } + /** * @throws \InvalidArgumentException */ diff --git a/src/entity/ExperienceManager.php b/src/entity/ExperienceManager.php index 0b8fb050cc..cc880198be 100644 --- a/src/entity/ExperienceManager.php +++ b/src/entity/ExperienceManager.php @@ -59,8 +59,9 @@ class ExperienceManager{ } private static function fetchAttribute(Entity $entity, string $attributeId) : Attribute{ - $entity->getAttributeMap()->add(AttributeFactory::getInstance()->get($attributeId)); - return $entity->getAttributeMap()->get($attributeId); + $attribute = AttributeFactory::getInstance()->mustGet($attributeId); + $entity->getAttributeMap()->add($attribute); + return $attribute; } /** diff --git a/src/entity/HungerManager.php b/src/entity/HungerManager.php index 331f8e96cc..77eb87d113 100644 --- a/src/entity/HungerManager.php +++ b/src/entity/HungerManager.php @@ -57,8 +57,9 @@ class HungerManager{ } private static function fetchAttribute(Entity $entity, string $attributeId) : Attribute{ - $entity->getAttributeMap()->add(AttributeFactory::getInstance()->get($attributeId)); - return $entity->getAttributeMap()->get($attributeId); + $attribute = AttributeFactory::getInstance()->get($attributeId); + $entity->getAttributeMap()->add($attribute); + return $attribute; } public function getFood() : float{ diff --git a/src/entity/Living.php b/src/entity/Living.php index febc3f1c2c..524f17dda2 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -101,6 +101,13 @@ abstract class Living extends Entity{ /** @var int */ protected $maxBreathTicks = self::DEFAULT_BREATH_TICKS; + /** @var Attribute */ + protected $healthAttr; + /** @var Attribute */ + protected $absorptionAttr; + /** @var Attribute */ + protected $knockbackResistanceAttr; + abstract public function getName() : string; protected function initEntity(CompoundTag $nbt) : void{ @@ -153,37 +160,37 @@ abstract class Living extends Entity{ } protected function addAttributes() : void{ - $this->attributeMap->add(AttributeFactory::getInstance()->get(Attribute::HEALTH)); - $this->attributeMap->add(AttributeFactory::getInstance()->get(Attribute::FOLLOW_RANGE)); - $this->attributeMap->add(AttributeFactory::getInstance()->get(Attribute::KNOCKBACK_RESISTANCE)); - $this->attributeMap->add(AttributeFactory::getInstance()->get(Attribute::MOVEMENT_SPEED)); - $this->attributeMap->add(AttributeFactory::getInstance()->get(Attribute::ATTACK_DAMAGE)); - $this->attributeMap->add(AttributeFactory::getInstance()->get(Attribute::ABSORPTION)); + $this->attributeMap->add($this->healthAttr = AttributeFactory::getInstance()->mustGet(Attribute::HEALTH)); + $this->attributeMap->add(AttributeFactory::getInstance()->mustGet(Attribute::FOLLOW_RANGE)); + $this->attributeMap->add($this->knockbackResistanceAttr = AttributeFactory::getInstance()->mustGet(Attribute::KNOCKBACK_RESISTANCE)); + $this->attributeMap->add(AttributeFactory::getInstance()->mustGet(Attribute::MOVEMENT_SPEED)); + $this->attributeMap->add(AttributeFactory::getInstance()->mustGet(Attribute::ATTACK_DAMAGE)); + $this->attributeMap->add($this->absorptionAttr = AttributeFactory::getInstance()->mustGet(Attribute::ABSORPTION)); } public function setHealth(float $amount) : void{ $wasAlive = $this->isAlive(); parent::setHealth($amount); - $this->attributeMap->get(Attribute::HEALTH)->setValue(ceil($this->getHealth()), true); + $this->healthAttr->setValue(ceil($this->getHealth()), true); if($this->isAlive() and !$wasAlive){ $this->broadcastAnimation(new RespawnAnimation($this)); } } public function getMaxHealth() : int{ - return (int) $this->attributeMap->get(Attribute::HEALTH)->getMaxValue(); + return (int) $this->healthAttr->getMaxValue(); } public function setMaxHealth(int $amount) : void{ - $this->attributeMap->get(Attribute::HEALTH)->setMaxValue($amount)->setDefaultValue($amount); + $this->healthAttr->setMaxValue($amount)->setDefaultValue($amount); } public function getAbsorption() : float{ - return $this->attributeMap->get(Attribute::ABSORPTION)->getValue(); + return $this->absorptionAttr->getValue(); } public function setAbsorption(float $absorption) : void{ - $this->attributeMap->get(Attribute::ABSORPTION)->setValue($absorption); + $this->absorptionAttr->setValue($absorption); } public function saveNBT() : CompoundTag{ @@ -453,7 +460,7 @@ abstract class Living extends Entity{ if($f <= 0){ return; } - if(mt_rand() / mt_getrandmax() > $this->getAttributeMap()->get(Attribute::KNOCKBACK_RESISTANCE)->getValue()){ + if(mt_rand() / mt_getrandmax() > $this->knockbackResistanceAttr->getValue()){ $f = 1 / $f; $motion = clone $this->motion; diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index b34208e492..28ca59cff1 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -185,16 +185,6 @@ parameters: count: 1 path: ../../../src/entity/Entity.php - - - message: "#^Parameter \\#1 \\$attribute of method pocketmine\\\\entity\\\\AttributeMap\\:\\:add\\(\\) expects pocketmine\\\\entity\\\\Attribute, pocketmine\\\\entity\\\\Attribute\\|null given\\.$#" - count: 1 - path: ../../../src/entity/ExperienceManager.php - - - - message: "#^Method pocketmine\\\\entity\\\\ExperienceManager\\:\\:fetchAttribute\\(\\) should return pocketmine\\\\entity\\\\Attribute but returns pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 1 - path: ../../../src/entity/ExperienceManager.php - - message: "#^Parameter \\#1 \\$attribute of method pocketmine\\\\entity\\\\AttributeMap\\:\\:add\\(\\) expects pocketmine\\\\entity\\\\Attribute, pocketmine\\\\entity\\\\Attribute\\|null given\\.$#" count: 1 @@ -205,31 +195,6 @@ parameters: count: 1 path: ../../../src/entity/HungerManager.php - - - message: "#^Parameter \\#1 \\$attribute of method pocketmine\\\\entity\\\\AttributeMap\\:\\:add\\(\\) expects pocketmine\\\\entity\\\\Attribute, pocketmine\\\\entity\\\\Attribute\\|null given\\.$#" - count: 6 - path: ../../../src/entity/Living.php - - - - message: "#^Cannot call method setValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 2 - path: ../../../src/entity/Living.php - - - - message: "#^Cannot call method getMaxValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 1 - path: ../../../src/entity/Living.php - - - - message: "#^Cannot call method setMaxValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 1 - path: ../../../src/entity/Living.php - - - - message: "#^Cannot call method getValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 2 - path: ../../../src/entity/Living.php - - message: "#^Cannot call method getEffectLevel\\(\\) on pocketmine\\\\entity\\\\effect\\\\EffectInstance\\|null\\.$#" count: 3 From ec8ee2929157962296ddb204292ac10959075471 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 May 2020 19:55:58 +0100 Subject: [PATCH 1596/3224] moving sneak & sprint properties to Living --- src/block/Magma.php | 3 ++- src/entity/Entity.php | 25 ------------------------- src/entity/Living.php | 26 ++++++++++++++++++++++++++ tests/phpstan/configs/l8-baseline.neon | 20 ++++++++++---------- 4 files changed, 38 insertions(+), 36 deletions(-) diff --git a/src/block/Magma.php b/src/block/Magma.php index fd3437bc4d..d16ae056be 100644 --- a/src/block/Magma.php +++ b/src/block/Magma.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\entity\Entity; +use pocketmine\entity\Living; use pocketmine\event\entity\EntityDamageByBlockEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\item\ToolTier; @@ -43,7 +44,7 @@ class Magma extends Opaque{ } public function onEntityInside(Entity $entity) : void{ - if(!$entity->isSneaking()){ + if($entity instanceof Living and !$entity->isSneaking()){ $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1); $entity->attack($ev); } diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 01b01c2dab..e428b13915 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -209,10 +209,6 @@ abstract class Entity{ protected $immobile = false; /** @var bool */ protected $invisible = false; - /** @var bool */ - protected $sneaking = false; - /** @var bool */ - protected $sprinting = false; /** @var int|null */ protected $ownerId = null; @@ -345,26 +341,6 @@ abstract class Entity{ ); } - public function isSneaking() : bool{ - return $this->sneaking; - } - - public function setSneaking(bool $value = true) : void{ - $this->sneaking = $value; - } - - public function isSprinting() : bool{ - return $this->sprinting; - } - - public function setSprinting(bool $value = true) : void{ - if($value !== $this->isSprinting()){ - $this->sprinting = $value; - $attr = $this->attributeMap->get(Attribute::MOVEMENT_SPEED); - $attr->setValue($value ? ($attr->getValue() * 1.3) : ($attr->getValue() / 1.3), false, true); - } - } - public function isImmobile() : bool{ return $this->immobile; } @@ -1697,7 +1673,6 @@ abstract class Entity{ $this->networkProperties->setGenericFlag(EntityMetadataFlags::IMMOBILE, $this->immobile); $this->networkProperties->setGenericFlag(EntityMetadataFlags::INVISIBLE, $this->invisible); $this->networkProperties->setGenericFlag(EntityMetadataFlags::ONFIRE, $this->isOnFire()); - $this->networkProperties->setGenericFlag(EntityMetadataFlags::SNEAKING, $this->sneaking); $this->networkProperties->setGenericFlag(EntityMetadataFlags::WALLCLIMBING, $this->canClimbWalls); } diff --git a/src/entity/Living.php b/src/entity/Living.php index 524f17dda2..089e84ed4f 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -108,6 +108,11 @@ abstract class Living extends Entity{ /** @var Attribute */ protected $knockbackResistanceAttr; + /** @var bool */ + protected $sprinting = false; + /** @var bool */ + protected $sneaking = false; + abstract public function getName() : string; protected function initEntity(CompoundTag $nbt) : void{ @@ -193,6 +198,26 @@ abstract class Living extends Entity{ $this->absorptionAttr->setValue($absorption); } + public function isSneaking() : bool{ + return $this->sneaking; + } + + public function setSneaking(bool $value = true) : void{ + $this->sneaking = $value; + } + + public function isSprinting() : bool{ + return $this->sprinting; + } + + public function setSprinting(bool $value = true) : void{ + if($value !== $this->isSprinting()){ + $this->sprinting = $value; + $attr = $this->attributeMap->get(Attribute::MOVEMENT_SPEED); + $attr->setValue($value ? ($attr->getValue() * 1.3) : ($attr->getValue() / 1.3), false, true); + } + } + public function saveNBT() : CompoundTag{ $nbt = parent::saveNBT(); $nbt->setFloat("Health", $this->getHealth()); @@ -739,6 +764,7 @@ abstract class Living extends Entity{ $this->networkProperties->setShort(EntityMetadataProperties::MAX_AIR, $this->maxBreathTicks); $this->networkProperties->setGenericFlag(EntityMetadataFlags::BREATHING, $this->breathing); + $this->networkProperties->setGenericFlag(EntityMetadataFlags::SNEAKING, $this->sneaking); } protected function onDispose() : void{ diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 28ca59cff1..860fc02c18 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -170,16 +170,6 @@ parameters: count: 1 path: ../../../src/entity/Entity.php - - - message: "#^Cannot call method getValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 2 - path: ../../../src/entity/Entity.php - - - - message: "#^Cannot call method setValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 1 - path: ../../../src/entity/Entity.php - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\AddActorPacket\\:\\:\\$type \\(string\\) does not accept string\\|null\\.$#" count: 1 @@ -195,6 +185,16 @@ parameters: count: 1 path: ../../../src/entity/HungerManager.php + - + message: "#^Cannot call method getValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" + count: 2 + path: ../../../src/entity/Living.php + + - + message: "#^Cannot call method setValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" + count: 1 + path: ../../../src/entity/Living.php + - message: "#^Cannot call method getEffectLevel\\(\\) on pocketmine\\\\entity\\\\effect\\\\EffectInstance\\|null\\.$#" count: 3 From f77eea8c4444a94f03b8e7434203cfd4ee5bc4b1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 May 2020 20:01:37 +0100 Subject: [PATCH 1597/3224] Living: set SPRINTING flag when it's needed, close #3521 --- src/entity/Living.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/entity/Living.php b/src/entity/Living.php index 089e84ed4f..604dfd3257 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -765,6 +765,7 @@ abstract class Living extends Entity{ $this->networkProperties->setGenericFlag(EntityMetadataFlags::BREATHING, $this->breathing); $this->networkProperties->setGenericFlag(EntityMetadataFlags::SNEAKING, $this->sneaking); + $this->networkProperties->setGenericFlag(EntityMetadataFlags::SPRINTING, $this->sprinting); } protected function onDispose() : void{ From 1aa92bd6a801544211b9d698f905ee3b29e62840 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 May 2020 20:13:24 +0100 Subject: [PATCH 1598/3224] Living: Do not rely on attribute map for moveSpeed attribute access --- src/entity/Living.php | 17 ++++++++++++--- src/entity/effect/SlownessEffect.php | 7 ++---- src/entity/effect/SpeedEffect.php | 7 ++---- tests/phpstan/configs/l8-baseline.neon | 30 -------------------------- 4 files changed, 18 insertions(+), 43 deletions(-) diff --git a/src/entity/Living.php b/src/entity/Living.php index 604dfd3257..2097bf0d49 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -107,6 +107,8 @@ abstract class Living extends Entity{ protected $absorptionAttr; /** @var Attribute */ protected $knockbackResistanceAttr; + /** @var Attribute */ + protected $moveSpeedAttr; /** @var bool */ protected $sprinting = false; @@ -168,7 +170,7 @@ abstract class Living extends Entity{ $this->attributeMap->add($this->healthAttr = AttributeFactory::getInstance()->mustGet(Attribute::HEALTH)); $this->attributeMap->add(AttributeFactory::getInstance()->mustGet(Attribute::FOLLOW_RANGE)); $this->attributeMap->add($this->knockbackResistanceAttr = AttributeFactory::getInstance()->mustGet(Attribute::KNOCKBACK_RESISTANCE)); - $this->attributeMap->add(AttributeFactory::getInstance()->mustGet(Attribute::MOVEMENT_SPEED)); + $this->attributeMap->add($this->moveSpeedAttr = AttributeFactory::getInstance()->mustGet(Attribute::MOVEMENT_SPEED)); $this->attributeMap->add(AttributeFactory::getInstance()->mustGet(Attribute::ATTACK_DAMAGE)); $this->attributeMap->add($this->absorptionAttr = AttributeFactory::getInstance()->mustGet(Attribute::ABSORPTION)); } @@ -213,11 +215,20 @@ abstract class Living extends Entity{ public function setSprinting(bool $value = true) : void{ if($value !== $this->isSprinting()){ $this->sprinting = $value; - $attr = $this->attributeMap->get(Attribute::MOVEMENT_SPEED); - $attr->setValue($value ? ($attr->getValue() * 1.3) : ($attr->getValue() / 1.3), false, true); + $moveSpeed = $this->getMovementSpeed(); + $this->setMovementSpeed($value ? ($moveSpeed * 1.3) : ($moveSpeed / 1.3)); + $this->moveSpeedAttr->markSynchronized(false); //TODO: reevaluate this hack } } + public function getMovementSpeed() : float{ + return $this->moveSpeedAttr->getValue(); + } + + public function setMovementSpeed(float $v, bool $fit = false) : void{ + $this->moveSpeedAttr->setValue($v, $fit); + } + public function saveNBT() : CompoundTag{ $nbt = parent::saveNBT(); $nbt->setFloat("Health", $this->getHealth()); diff --git a/src/entity/effect/SlownessEffect.php b/src/entity/effect/SlownessEffect.php index a2604a1ba0..6ab11bdbec 100644 --- a/src/entity/effect/SlownessEffect.php +++ b/src/entity/effect/SlownessEffect.php @@ -23,18 +23,15 @@ declare(strict_types=1); namespace pocketmine\entity\effect; -use pocketmine\entity\Attribute; use pocketmine\entity\Living; class SlownessEffect extends Effect{ public function add(Living $entity, EffectInstance $instance) : void{ - $attr = $entity->getAttributeMap()->get(Attribute::MOVEMENT_SPEED); - $attr->setValue($attr->getValue() * (1 - 0.15 * $instance->getEffectLevel()), true); + $entity->setMovementSpeed($entity->getMovementSpeed() * (1 - 0.15 * $instance->getEffectLevel()), true); } public function remove(Living $entity, EffectInstance $instance) : void{ - $attr = $entity->getAttributeMap()->get(Attribute::MOVEMENT_SPEED); - $attr->setValue($attr->getValue() / (1 - 0.15 * $instance->getEffectLevel())); + $entity->setMovementSpeed($entity->getMovementSpeed() / (1 - 0.15 * $instance->getEffectLevel())); } } diff --git a/src/entity/effect/SpeedEffect.php b/src/entity/effect/SpeedEffect.php index caafe0b745..d84d3a6d62 100644 --- a/src/entity/effect/SpeedEffect.php +++ b/src/entity/effect/SpeedEffect.php @@ -23,18 +23,15 @@ declare(strict_types=1); namespace pocketmine\entity\effect; -use pocketmine\entity\Attribute; use pocketmine\entity\Living; class SpeedEffect extends Effect{ public function add(Living $entity, EffectInstance $instance) : void{ - $attr = $entity->getAttributeMap()->get(Attribute::MOVEMENT_SPEED); - $attr->setValue($attr->getValue() * (1 + 0.2 * $instance->getEffectLevel())); + $entity->setMovementSpeed($entity->getMovementSpeed() * (1 + 0.2 * $instance->getEffectLevel())); } public function remove(Living $entity, EffectInstance $instance) : void{ - $attr = $entity->getAttributeMap()->get(Attribute::MOVEMENT_SPEED); - $attr->setValue($attr->getValue() / (1 + 0.2 * $instance->getEffectLevel())); + $entity->setMovementSpeed($entity->getMovementSpeed() / (1 + 0.2 * $instance->getEffectLevel())); } } diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 860fc02c18..fe34314b69 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -185,16 +185,6 @@ parameters: count: 1 path: ../../../src/entity/HungerManager.php - - - message: "#^Cannot call method getValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 2 - path: ../../../src/entity/Living.php - - - - message: "#^Cannot call method setValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 1 - path: ../../../src/entity/Living.php - - message: "#^Cannot call method getEffectLevel\\(\\) on pocketmine\\\\entity\\\\effect\\\\EffectInstance\\|null\\.$#" count: 3 @@ -210,26 +200,6 @@ parameters: count: 1 path: ../../../src/entity/Living.php - - - message: "#^Cannot call method getValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 2 - path: ../../../src/entity/effect/SlownessEffect.php - - - - message: "#^Cannot call method setValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 2 - path: ../../../src/entity/effect/SlownessEffect.php - - - - message: "#^Cannot call method getValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 2 - path: ../../../src/entity/effect/SpeedEffect.php - - - - message: "#^Cannot call method setValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 2 - path: ../../../src/entity/effect/SpeedEffect.php - - message: "#^Method pocketmine\\\\entity\\\\object\\\\Painting\\:\\:getMotive\\(\\) should return pocketmine\\\\entity\\\\object\\\\PaintingMotive but returns pocketmine\\\\entity\\\\object\\\\PaintingMotive\\|null\\.$#" count: 1 From 6257f717b1f3cfabd5cc6265a3ba63c1d21bb4d6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 May 2020 20:29:06 +0100 Subject: [PATCH 1599/3224] Entity: make networkProperties private this reduces the temptation to use it in high-level code, as well as making syncNetworkData() more useful (now it can export to many data collections, which means we can start to think about having a property cache per network session, which is more flexible) --- src/entity/Animal.php | 7 +++-- src/entity/Entity.php | 40 +++++++++++++------------- src/entity/Living.php | 19 ++++++------ src/entity/Villager.php | 9 +++--- src/entity/WaterAnimal.php | 7 +++-- src/entity/object/ExperienceOrb.php | 7 +++-- src/entity/object/FallingBlock.php | 7 +++-- src/entity/object/PrimedTNT.php | 9 +++--- src/entity/projectile/Arrow.php | 7 +++-- src/entity/projectile/SplashPotion.php | 9 +++--- src/player/Player.php | 11 +++---- 11 files changed, 71 insertions(+), 61 deletions(-) diff --git a/src/entity/Animal.php b/src/entity/Animal.php index 60dbf9c469..17fb750b29 100644 --- a/src/entity/Animal.php +++ b/src/entity/Animal.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\entity; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; abstract class Animal extends Living implements Ageable{ @@ -33,8 +34,8 @@ abstract class Animal extends Living implements Ageable{ return $this->baby; } - protected function syncNetworkData() : void{ - parent::syncNetworkData(); - $this->networkProperties->setGenericFlag(EntityMetadataFlags::BABY, $this->baby); + protected function syncNetworkData(EntityMetadataCollection $properties) : void{ + parent::syncNetworkData($properties); + $properties->setGenericFlag(EntityMetadataFlags::BABY, $this->baby); } } diff --git a/src/entity/Entity.php b/src/entity/Entity.php index e428b13915..0125fa5571 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -87,7 +87,7 @@ abstract class Entity{ protected $id; /** @var EntityMetadataCollection */ - protected $networkProperties; + private $networkProperties; /** @var Chunk|null */ public $chunk; @@ -1650,30 +1650,30 @@ abstract class Entity{ * @return MetadataProperty[] */ final protected function getSyncedNetworkData(bool $dirtyOnly) : array{ - $this->syncNetworkData(); + $this->syncNetworkData($this->networkProperties); return $dirtyOnly ? $this->networkProperties->getDirty() : $this->networkProperties->getAll(); } - protected function syncNetworkData() : void{ - $this->networkProperties->setByte(EntityMetadataProperties::ALWAYS_SHOW_NAMETAG, $this->alwaysShowNameTag ? 1 : 0); - $this->networkProperties->setFloat(EntityMetadataProperties::BOUNDING_BOX_HEIGHT, $this->height); - $this->networkProperties->setFloat(EntityMetadataProperties::BOUNDING_BOX_WIDTH, $this->width); - $this->networkProperties->setFloat(EntityMetadataProperties::SCALE, $this->scale); - $this->networkProperties->setLong(EntityMetadataProperties::LEAD_HOLDER_EID, -1); - $this->networkProperties->setLong(EntityMetadataProperties::OWNER_EID, $this->ownerId ?? -1); - $this->networkProperties->setLong(EntityMetadataProperties::TARGET_EID, $this->targetId ?? 0); - $this->networkProperties->setString(EntityMetadataProperties::NAMETAG, $this->nameTag); - $this->networkProperties->setString(EntityMetadataProperties::SCORE_TAG, $this->scoreTag); + protected function syncNetworkData(EntityMetadataCollection $properties) : void{ + $properties->setByte(EntityMetadataProperties::ALWAYS_SHOW_NAMETAG, $this->alwaysShowNameTag ? 1 : 0); + $properties->setFloat(EntityMetadataProperties::BOUNDING_BOX_HEIGHT, $this->height); + $properties->setFloat(EntityMetadataProperties::BOUNDING_BOX_WIDTH, $this->width); + $properties->setFloat(EntityMetadataProperties::SCALE, $this->scale); + $properties->setLong(EntityMetadataProperties::LEAD_HOLDER_EID, -1); + $properties->setLong(EntityMetadataProperties::OWNER_EID, $this->ownerId ?? -1); + $properties->setLong(EntityMetadataProperties::TARGET_EID, $this->targetId ?? 0); + $properties->setString(EntityMetadataProperties::NAMETAG, $this->nameTag); + $properties->setString(EntityMetadataProperties::SCORE_TAG, $this->scoreTag); - $this->networkProperties->setGenericFlag(EntityMetadataFlags::AFFECTED_BY_GRAVITY, true); - $this->networkProperties->setGenericFlag(EntityMetadataFlags::CAN_CLIMB, $this->canClimb); - $this->networkProperties->setGenericFlag(EntityMetadataFlags::CAN_SHOW_NAMETAG, $this->nameTagVisible); - $this->networkProperties->setGenericFlag(EntityMetadataFlags::HAS_COLLISION, true); - $this->networkProperties->setGenericFlag(EntityMetadataFlags::IMMOBILE, $this->immobile); - $this->networkProperties->setGenericFlag(EntityMetadataFlags::INVISIBLE, $this->invisible); - $this->networkProperties->setGenericFlag(EntityMetadataFlags::ONFIRE, $this->isOnFire()); - $this->networkProperties->setGenericFlag(EntityMetadataFlags::WALLCLIMBING, $this->canClimbWalls); + $properties->setGenericFlag(EntityMetadataFlags::AFFECTED_BY_GRAVITY, true); + $properties->setGenericFlag(EntityMetadataFlags::CAN_CLIMB, $this->canClimb); + $properties->setGenericFlag(EntityMetadataFlags::CAN_SHOW_NAMETAG, $this->nameTagVisible); + $properties->setGenericFlag(EntityMetadataFlags::HAS_COLLISION, true); + $properties->setGenericFlag(EntityMetadataFlags::IMMOBILE, $this->immobile); + $properties->setGenericFlag(EntityMetadataFlags::INVISIBLE, $this->invisible); + $properties->setGenericFlag(EntityMetadataFlags::ONFIRE, $this->isOnFire()); + $properties->setGenericFlag(EntityMetadataFlags::WALLCLIMBING, $this->canClimbWalls); } /** diff --git a/src/entity/Living.php b/src/entity/Living.php index 2097bf0d49..0f96a58770 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -49,6 +49,7 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ShortTag; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\player\Player; @@ -766,17 +767,17 @@ abstract class Living extends Entity{ $player->getNetworkSession()->onMobArmorChange($this); } - protected function syncNetworkData() : void{ - parent::syncNetworkData(); + protected function syncNetworkData(EntityMetadataCollection $properties) : void{ + parent::syncNetworkData($properties); - $this->networkProperties->setByte(EntityMetadataProperties::POTION_AMBIENT, $this->effectManager->hasOnlyAmbientEffects() ? 1 : 0); - $this->networkProperties->setInt(EntityMetadataProperties::POTION_COLOR, Binary::signInt($this->effectManager->getBubbleColor()->toARGB())); - $this->networkProperties->setShort(EntityMetadataProperties::AIR, $this->breathTicks); - $this->networkProperties->setShort(EntityMetadataProperties::MAX_AIR, $this->maxBreathTicks); + $properties->setByte(EntityMetadataProperties::POTION_AMBIENT, $this->effectManager->hasOnlyAmbientEffects() ? 1 : 0); + $properties->setInt(EntityMetadataProperties::POTION_COLOR, Binary::signInt($this->effectManager->getBubbleColor()->toARGB())); + $properties->setShort(EntityMetadataProperties::AIR, $this->breathTicks); + $properties->setShort(EntityMetadataProperties::MAX_AIR, $this->maxBreathTicks); - $this->networkProperties->setGenericFlag(EntityMetadataFlags::BREATHING, $this->breathing); - $this->networkProperties->setGenericFlag(EntityMetadataFlags::SNEAKING, $this->sneaking); - $this->networkProperties->setGenericFlag(EntityMetadataFlags::SPRINTING, $this->sprinting); + $properties->setGenericFlag(EntityMetadataFlags::BREATHING, $this->breathing); + $properties->setGenericFlag(EntityMetadataFlags::SNEAKING, $this->sneaking); + $properties->setGenericFlag(EntityMetadataFlags::SPRINTING, $this->sprinting); } protected function onDispose() : void{ diff --git a/src/entity/Villager.php b/src/entity/Villager.php index e784d0c57d..bdc0e33ae0 100644 --- a/src/entity/Villager.php +++ b/src/entity/Villager.php @@ -25,6 +25,7 @@ namespace pocketmine\entity; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; @@ -84,10 +85,10 @@ class Villager extends Living implements Ageable{ return $this->baby; } - protected function syncNetworkData() : void{ - parent::syncNetworkData(); - $this->networkProperties->setGenericFlag(EntityMetadataFlags::BABY, $this->baby); + protected function syncNetworkData(EntityMetadataCollection $properties) : void{ + parent::syncNetworkData($properties); + $properties->setGenericFlag(EntityMetadataFlags::BABY, $this->baby); - $this->networkProperties->setInt(EntityMetadataProperties::VARIANT, $this->profession); + $properties->setInt(EntityMetadataProperties::VARIANT, $this->profession); } } diff --git a/src/entity/WaterAnimal.php b/src/entity/WaterAnimal.php index 9217667115..5edae8ffd4 100644 --- a/src/entity/WaterAnimal.php +++ b/src/entity/WaterAnimal.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity; use pocketmine\event\entity\EntityDamageEvent; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; abstract class WaterAnimal extends Living implements Ageable{ @@ -43,8 +44,8 @@ abstract class WaterAnimal extends Living implements Ageable{ $this->attack($ev); } - protected function syncNetworkData() : void{ - parent::syncNetworkData(); - $this->networkProperties->setGenericFlag(EntityMetadataFlags::BABY, $this->baby); + protected function syncNetworkData(EntityMetadataCollection $properties) : void{ + parent::syncNetworkData($properties); + $properties->setGenericFlag(EntityMetadataFlags::BABY, $this->baby); } } diff --git a/src/entity/object/ExperienceOrb.php b/src/entity/object/ExperienceOrb.php index 65f0ad89c8..a58ba10343 100644 --- a/src/entity/object/ExperienceOrb.php +++ b/src/entity/object/ExperienceOrb.php @@ -29,6 +29,7 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ShortTag; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\player\Player; use function sqrt; @@ -220,9 +221,9 @@ class ExperienceOrb extends Entity{ return false; } - protected function syncNetworkData() : void{ - parent::syncNetworkData(); + protected function syncNetworkData(EntityMetadataCollection $properties) : void{ + parent::syncNetworkData($properties); - $this->networkProperties->setInt(EntityMetadataProperties::EXPERIENCE_VALUE, $this->xpValue); + $properties->setInt(EntityMetadataProperties::EXPERIENCE_VALUE, $this->xpValue); } } diff --git a/src/entity/object/FallingBlock.php b/src/entity/object/FallingBlock.php index 94e85cf389..e53070a24d 100644 --- a/src/entity/object/FallingBlock.php +++ b/src/entity/object/FallingBlock.php @@ -33,6 +33,7 @@ use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use function abs; use function get_class; @@ -140,9 +141,9 @@ class FallingBlock extends Entity{ return $nbt; } - protected function syncNetworkData() : void{ - parent::syncNetworkData(); + protected function syncNetworkData(EntityMetadataCollection $properties) : void{ + parent::syncNetworkData($properties); - $this->networkProperties->setInt(EntityMetadataProperties::VARIANT, $this->block->getRuntimeId()); + $properties->setInt(EntityMetadataProperties::VARIANT, $this->block->getRuntimeId()); } } diff --git a/src/entity/object/PrimedTNT.php b/src/entity/object/PrimedTNT.php index da6019b161..b38f8a68f3 100644 --- a/src/entity/object/PrimedTNT.php +++ b/src/entity/object/PrimedTNT.php @@ -29,6 +29,7 @@ use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\ExplosionPrimeEvent; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\world\Explosion; @@ -108,10 +109,10 @@ class PrimedTNT extends Entity implements Explosive{ } } - protected function syncNetworkData() : void{ - parent::syncNetworkData(); + protected function syncNetworkData(EntityMetadataCollection $properties) : void{ + parent::syncNetworkData($properties); - $this->networkProperties->setGenericFlag(EntityMetadataFlags::IGNITED, true); - $this->networkProperties->setInt(EntityMetadataProperties::FUSE_LENGTH, $this->fuse); + $properties->setGenericFlag(EntityMetadataFlags::IGNITED, true); + $properties->setInt(EntityMetadataProperties::FUSE_LENGTH, $this->fuse); } } diff --git a/src/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php index bfddc295bc..6609453ee9 100644 --- a/src/entity/projectile/Arrow.php +++ b/src/entity/projectile/Arrow.php @@ -32,6 +32,7 @@ use pocketmine\item\VanillaItems; use pocketmine\math\RayTraceResult; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\player\Player; use pocketmine\world\sound\ArrowHitSound; @@ -193,9 +194,9 @@ class Arrow extends Projectile{ $this->flagForDespawn(); } - protected function syncNetworkData() : void{ - parent::syncNetworkData(); + protected function syncNetworkData(EntityMetadataCollection $properties) : void{ + parent::syncNetworkData($properties); - $this->networkProperties->setGenericFlag(EntityMetadataFlags::CRITICAL, $this->critical); + $properties->setGenericFlag(EntityMetadataFlags::CRITICAL, $this->critical); } } diff --git a/src/entity/projectile/SplashPotion.php b/src/entity/projectile/SplashPotion.php index 168dac90a0..a6f2cf0b4f 100644 --- a/src/entity/projectile/SplashPotion.php +++ b/src/entity/projectile/SplashPotion.php @@ -35,6 +35,7 @@ use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\item\Potion; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\world\particle\PotionSplashParticle; @@ -172,10 +173,10 @@ class SplashPotion extends Throwable{ return Potion::getPotionEffectsById($this->getPotionId()); } - protected function syncNetworkData() : void{ - parent::syncNetworkData(); + protected function syncNetworkData(EntityMetadataCollection $properties) : void{ + parent::syncNetworkData($properties); - $this->networkProperties->setShort(EntityMetadataProperties::POTION_AUX_VALUE, $this->potionId); - $this->networkProperties->setGenericFlag(EntityMetadataFlags::LINGER, $this->linger); + $properties->setShort(EntityMetadataProperties::POTION_AUX_VALUE, $this->potionId); + $properties->setGenericFlag(EntityMetadataFlags::LINGER, $this->linger); } } diff --git a/src/player/Player.php b/src/player/Player.php index 58b55ca686..defd369b64 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -86,6 +86,7 @@ use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; +use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\entity\PlayerMetadataFlags; @@ -2181,13 +2182,13 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, parent::attack($source); } - protected function syncNetworkData() : void{ - parent::syncNetworkData(); + protected function syncNetworkData(EntityMetadataCollection $properties) : void{ + parent::syncNetworkData($properties); - $this->networkProperties->setGenericFlag(EntityMetadataFlags::ACTION, $this->startAction > -1); + $properties->setGenericFlag(EntityMetadataFlags::ACTION, $this->startAction > -1); - $this->networkProperties->setPlayerFlag(PlayerMetadataFlags::SLEEP, $this->sleeping !== null); - $this->networkProperties->setBlockPos(EntityMetadataProperties::PLAYER_BED_POSITION, $this->sleeping ?? new Vector3(0, 0, 0)); + $properties->setPlayerFlag(PlayerMetadataFlags::SLEEP, $this->sleeping !== null); + $properties->setBlockPos(EntityMetadataProperties::PLAYER_BED_POSITION, $this->sleeping ?? new Vector3(0, 0, 0)); } public function broadcastAnimation(Animation $animation, ?array $targets = null) : void{ From fcea7da183012a34d580219dec9e3e5aa0fa97ce Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 May 2020 09:37:37 +0100 Subject: [PATCH 1600/3224] WorldManager: allow dataPath to be injected via constructor --- src/Server.php | 2 +- src/world/WorldManager.php | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Server.php b/src/Server.php index ab75f901c3..e691f54116 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1018,7 +1018,7 @@ class Server{ } GeneratorManager::registerDefaultGenerators(); - $this->worldManager = new WorldManager($this); + $this->worldManager = new WorldManager($this, $this->dataPath . "/worlds"); $this->updater = new AutoUpdater($this, $this->getProperty("auto-updater.host", "update.pmmp.io")); diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index dd9853b1f7..c504494fb1 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -53,6 +53,9 @@ use function sprintf; use function trim; class WorldManager{ + /** @var string */ + private $dataPath; + /** @var World[] */ private $worlds = []; /** @var World|null */ @@ -69,8 +72,9 @@ class WorldManager{ /** @var int */ private $autoSaveTicker = 0; - public function __construct(Server $server){ + public function __construct(Server $server, string $dataPath){ $this->server = $server; + $this->dataPath = $dataPath; $this->autoSave = $this->server->getConfigBool("auto-save", $this->autoSave); $this->autoSaveTicks = (int) $this->server->getProperty("ticks-per.autosave", 6000); @@ -176,7 +180,7 @@ class WorldManager{ return false; } - $path = $this->server->getDataPath() . "worlds/" . $name . "/"; + $path = $this->dataPath . "/" . $name . "/"; $providers = WorldProviderManager::getMatchingProviders($path); if(count($providers) !== 1){ @@ -252,7 +256,7 @@ class WorldManager{ $providerClass = WorldProviderManager::getDefault(); - $path = $this->server->getDataPath() . "worlds/" . $name . "/"; + $path = $this->dataPath . "/" . $name . "/"; /** @var WritableWorldProvider $providerClass */ $providerClass::generate($path, $name, $seed, $generator, $options); @@ -300,7 +304,7 @@ class WorldManager{ if(trim($name) === ""){ return false; } - $path = $this->server->getDataPath() . "worlds/" . $name . "/"; + $path = $this->dataPath . "/" . $name . "/"; if(!($this->getWorldByName($name) instanceof World)){ return count(WorldProviderManager::getMatchingProviders($path)) > 0; } From 8d9759288c077c9413d09aaa50f79d59f07c1ea8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 May 2020 09:43:59 +0100 Subject: [PATCH 1601/3224] WorldManager: don't hard-depend on server configuration for autosave settings --- src/Server.php | 2 ++ src/world/WorldManager.php | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Server.php b/src/Server.php index e691f54116..e1fad2d2da 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1019,6 +1019,8 @@ class Server{ GeneratorManager::registerDefaultGenerators(); $this->worldManager = new WorldManager($this, $this->dataPath . "/worlds"); + $this->worldManager->setAutoSave($this->getConfigBool("auto-save", $this->worldManager->getAutoSave())); + $this->worldManager->setAutoSaveInterval((int) $this->getProperty("ticks-per.autosave", 6000)); $this->updater = new AutoUpdater($this, $this->getProperty("auto-updater.host", "update.pmmp.io")); diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index c504494fb1..6d0689a388 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -75,9 +75,6 @@ class WorldManager{ public function __construct(Server $server, string $dataPath){ $this->server = $server; $this->dataPath = $dataPath; - - $this->autoSave = $this->server->getConfigBool("auto-save", $this->autoSave); - $this->autoSaveTicks = (int) $this->server->getProperty("ticks-per.autosave", 6000); } /** From e2232dd8d494836f93ffaa610cdd58a1ba6ddee3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 May 2020 09:50:25 +0100 Subject: [PATCH 1602/3224] WorldManager: reduce code duplication for world path discovery --- src/world/WorldManager.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 6d0689a388..5aa991cebb 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -177,7 +177,7 @@ class WorldManager{ return false; } - $path = $this->dataPath . "/" . $name . "/"; + $path = $this->getWorldPath($name); $providers = WorldProviderManager::getMatchingProviders($path); if(count($providers) !== 1){ @@ -253,7 +253,7 @@ class WorldManager{ $providerClass = WorldProviderManager::getDefault(); - $path = $this->dataPath . "/" . $name . "/"; + $path = $this->getWorldPath($name); /** @var WritableWorldProvider $providerClass */ $providerClass::generate($path, $name, $seed, $generator, $options); @@ -297,11 +297,15 @@ class WorldManager{ return true; } + private function getWorldPath(string $name) : string{ + return $this->dataPath . "/" . $name . "/"; + } + public function isWorldGenerated(string $name) : bool{ if(trim($name) === ""){ return false; } - $path = $this->dataPath . "/" . $name . "/"; + $path = $this->getWorldPath($name); if(!($this->getWorldByName($name) instanceof World)){ return count(WorldProviderManager::getMatchingProviders($path)) > 0; } From 640428c415fe0d166b9cff1a086796467035d84c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 May 2020 10:02:09 +0100 Subject: [PATCH 1603/3224] Convert WorldProviderManager to singleton --- src/Server.php | 6 +-- src/world/WorldManager.php | 8 ++-- src/world/format/io/WorldProviderManager.php | 37 ++++++++++--------- tests/phpstan/configs/phpstan-bugs.neon | 2 +- .../phpstan/configs/phpunit-wiring-tests.neon | 2 +- .../format/io/LevelProviderManagerTest.php | 15 ++++++-- tools/convert-world.php | 5 +-- 7 files changed, 42 insertions(+), 33 deletions(-) diff --git a/src/Server.php b/src/Server.php index e1fad2d2da..4744a2c98b 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1007,12 +1007,12 @@ class Server{ $this->pluginManager->registerInterface(new PharPluginLoader($this->autoloader)); $this->pluginManager->registerInterface(new ScriptPluginLoader()); - WorldProviderManager::init(); + $providerManager = WorldProviderManager::getInstance(); if( - ($format = WorldProviderManager::getProviderByName($formatName = (string) $this->getProperty("level-settings.default-format"))) !== null and + ($format = $providerManager->getProviderByName($formatName = (string) $this->getProperty("level-settings.default-format"))) !== null and is_a($format, WritableWorldProvider::class, true) ){ - WorldProviderManager::setDefault($format); + $providerManager->setDefault($format); }elseif($formatName !== ""){ $this->logger->warning($this->language->translateString("pocketmine.level.badDefaultFormat", [$formatName])); } diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 5aa991cebb..d641598fbc 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -179,7 +179,7 @@ class WorldManager{ $path = $this->getWorldPath($name); - $providers = WorldProviderManager::getMatchingProviders($path); + $providers = WorldProviderManager::getInstance()->getMatchingProviders($path); if(count($providers) !== 1){ $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.level.loadError", [ $name, @@ -216,7 +216,7 @@ class WorldManager{ } $this->server->getLogger()->notice("Upgrading world \"$name\" to new format. This may take a while."); - $converter = new FormatConverter($provider, WorldProviderManager::getDefault(), $this->server->getDataPath() . "world_conversion_backups", $this->server->getLogger()); + $converter = new FormatConverter($provider, WorldProviderManager::getInstance()->getDefault(), $this->server->getDataPath() . "world_conversion_backups", $this->server->getLogger()); $provider = $converter->execute(); $this->server->getLogger()->notice("Upgraded world \"$name\" to new format successfully. Backed up pre-conversion world at " . $converter->getBackupPath()); @@ -251,7 +251,7 @@ class WorldManager{ Utils::testValidInstance($generator, Generator::class); - $providerClass = WorldProviderManager::getDefault(); + $providerClass = WorldProviderManager::getInstance()->getDefault(); $path = $this->getWorldPath($name); /** @var WritableWorldProvider $providerClass */ @@ -307,7 +307,7 @@ class WorldManager{ } $path = $this->getWorldPath($name); if(!($this->getWorldByName($name) instanceof World)){ - return count(WorldProviderManager::getMatchingProviders($path)) > 0; + return count(WorldProviderManager::getInstance()->getMatchingProviders($path)) > 0; } return true; diff --git a/src/world/format/io/WorldProviderManager.php b/src/world/format/io/WorldProviderManager.php index 37e489709a..1232935995 100644 --- a/src/world/format/io/WorldProviderManager.php +++ b/src/world/format/io/WorldProviderManager.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\format\io; +use pocketmine\utils\SingletonTrait; use pocketmine\utils\Utils; use pocketmine\world\format\io\leveldb\LevelDB; use pocketmine\world\format\io\region\Anvil; @@ -31,20 +32,22 @@ use pocketmine\world\format\io\region\PMAnvil; use function strtolower; use function trim; -abstract class WorldProviderManager{ +final class WorldProviderManager{ + use SingletonTrait; + /** * @var string[] * @phpstan-var array> */ - protected static $providers = []; + protected $providers = []; /** * @var string * @phpstan-var class-string */ - private static $default = LevelDB::class; + private $default = LevelDB::class; - public static function init() : void{ + public function __construct(){ self::addProvider(Anvil::class, "anvil"); self::addProvider(McRegion::class, "mcregion"); self::addProvider(PMAnvil::class, "pmanvil"); @@ -56,8 +59,8 @@ abstract class WorldProviderManager{ * * @phpstan-return class-string */ - public static function getDefault() : string{ - return self::$default; + public function getDefault() : string{ + return $this->default; } /** @@ -68,25 +71,25 @@ abstract class WorldProviderManager{ * * @throws \InvalidArgumentException */ - public static function setDefault(string $class) : void{ + public function setDefault(string $class) : void{ Utils::testValidInstance($class, WritableWorldProvider::class); - self::$default = $class; + $this->default = $class; } /** * @phpstan-param class-string $class */ - public static function addProvider(string $class, string $name, bool $overwrite = false) : void{ + public function addProvider(string $class, string $name, bool $overwrite = false) : void{ Utils::testValidInstance($class, WorldProvider::class); $name = strtolower($name); - if(!$overwrite and isset(self::$providers[$name])){ + if(!$overwrite and isset($this->providers[$name])){ throw new \InvalidArgumentException("Alias \"$name\" is already assigned"); } /** @var WorldProvider $class */ - self::$providers[$name] = $class; + $this->providers[$name] = $class; } /** @@ -95,9 +98,9 @@ abstract class WorldProviderManager{ * @return string[] * @phpstan-return array> */ - public static function getMatchingProviders(string $path) : array{ + public function getMatchingProviders(string $path) : array{ $result = []; - foreach(self::$providers as $alias => $provider){ + foreach($this->providers as $alias => $provider){ if($provider::isValid($path)){ $result[$alias] = $provider; } @@ -109,8 +112,8 @@ abstract class WorldProviderManager{ * @return string[] * @phpstan-return array> */ - public static function getAvailableProviders() : array{ - return self::$providers; + public function getAvailableProviders() : array{ + return $this->providers; } /** @@ -118,7 +121,7 @@ abstract class WorldProviderManager{ * * @phpstan-return class-string|null */ - public static function getProviderByName(string $name) : ?string{ - return self::$providers[trim(strtolower($name))] ?? null; + public function getProviderByName(string $name) : ?string{ + return $this->providers[trim(strtolower($name))] ?? null; } } diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 7d4858d656..e6712299b5 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -1,7 +1,7 @@ parameters: ignoreErrors: - - message: "#^Parameter \\#1 \\$class of static method pocketmine\\\\world\\\\format\\\\io\\\\WorldProviderManager\\:\\:setDefault\\(\\) expects class\\-string\\, class\\-string\\ given\\.$#" + message: "#^Parameter \\#1 \\$class of method pocketmine\\\\world\\\\format\\\\io\\\\WorldProviderManager\\:\\:setDefault\\(\\) expects class\\-string\\, class\\-string\\ given\\.$#" count: 1 path: ../../../src/Server.php diff --git a/tests/phpstan/configs/phpunit-wiring-tests.neon b/tests/phpstan/configs/phpunit-wiring-tests.neon index d939ca84e7..40cbef80d2 100644 --- a/tests/phpstan/configs/phpunit-wiring-tests.neon +++ b/tests/phpstan/configs/phpunit-wiring-tests.neon @@ -1,7 +1,7 @@ parameters: ignoreErrors: - - message: "#^Parameter \\#1 \\$class of static method pocketmine\\\\world\\\\format\\\\io\\\\WorldProviderManager\\:\\:addProvider\\(\\) expects class\\-string\\, string given\\.$#" + message: "#^Parameter \\#1 \\$class of method pocketmine\\\\world\\\\format\\\\io\\\\WorldProviderManager\\:\\:addProvider\\(\\) expects class\\-string\\, string given\\.$#" count: 2 path: ../../phpunit/world/format/io/LevelProviderManagerTest.php diff --git a/tests/phpunit/world/format/io/LevelProviderManagerTest.php b/tests/phpunit/world/format/io/LevelProviderManagerTest.php index 738a16bc3e..8cd9bb0658 100644 --- a/tests/phpunit/world/format/io/LevelProviderManagerTest.php +++ b/tests/phpunit/world/format/io/LevelProviderManagerTest.php @@ -27,27 +27,34 @@ use PHPUnit\Framework\TestCase; class LevelProviderManagerTest extends TestCase{ + /** @var WorldProviderManager */ + private $providerManager; + + protected function setUp() : void{ + $this->providerManager = new WorldProviderManager(); + } + public function testAddNonClassProvider() : void{ $this->expectException(\InvalidArgumentException::class); - WorldProviderManager::addProvider("lol", "nope"); + $this->providerManager->addProvider("lol", "nope"); } public function testAddAbstractClassProvider() : void{ $this->expectException(\InvalidArgumentException::class); - WorldProviderManager::addProvider(AbstractWorldProvider::class, "abstract"); + $this->providerManager->addProvider(AbstractWorldProvider::class, "abstract"); } public function testAddInterfaceProvider() : void{ $this->expectException(\InvalidArgumentException::class); - WorldProviderManager::addProvider(InterfaceWorldProvider::class, "interface"); + $this->providerManager->addProvider(InterfaceWorldProvider::class, "interface"); } public function testAddWrongClassProvider() : void{ $this->expectException(\InvalidArgumentException::class); - WorldProviderManager::addProvider(LevelProviderManagerTest::class, "bad_class"); + $this->providerManager->addProvider(LevelProviderManagerTest::class, "bad_class"); } } diff --git a/tools/convert-world.php b/tools/convert-world.php index 8caab26927..f4e376853e 100644 --- a/tools/convert-world.php +++ b/tools/convert-world.php @@ -29,10 +29,9 @@ use pocketmine\world\generator\GeneratorManager; require_once dirname(__DIR__) . '/vendor/autoload.php'; -WorldProviderManager::init(); GeneratorManager::registerDefaultGenerators(); -$writableFormats = array_filter(WorldProviderManager::getAvailableProviders(), function(string $class){ +$writableFormats = array_filter(WorldProviderManager::getInstance()->getAvailableProviders(), function(string $class){ return is_a($class, WritableWorldProvider::class, true); }); $requiredOpts = [ @@ -63,7 +62,7 @@ if((!@mkdir($backupPath, 0777, true) and !is_dir($backupPath)) or !is_writable($ die("Backup file path " . $backupPath . " is not writable (permission error or doesn't exist), aborting"); } -$oldProviderClasses = WorldProviderManager::getMatchingProviders($inputPath); +$oldProviderClasses = WorldProviderManager::getInstance()->getMatchingProviders($inputPath); if(count($oldProviderClasses) === 0){ die("Unknown input world format"); } From c9af5ce7a95b8579a733354027677e97c164f03c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 May 2020 10:13:03 +0100 Subject: [PATCH 1604/3224] Convert GeneratorManager to singleton --- src/Server.php | 5 +-- src/world/World.php | 2 +- src/world/WorldManager.php | 2 +- src/world/format/io/FormatConverter.php | 2 +- src/world/format/io/data/BedrockWorldData.php | 2 +- src/world/format/io/data/JavaWorldData.php | 2 +- src/world/generator/GeneratorManager.php | 44 +++++++++---------- tests/phpstan/configs/l8-baseline.neon | 2 +- tools/convert-world.php | 3 -- 9 files changed, 28 insertions(+), 36 deletions(-) diff --git a/src/Server.php b/src/Server.php index 4744a2c98b..38f192f5fd 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1017,7 +1017,6 @@ class Server{ $this->logger->warning($this->language->translateString("pocketmine.level.badDefaultFormat", [$formatName])); } - GeneratorManager::registerDefaultGenerators(); $this->worldManager = new WorldManager($this, $this->dataPath . "/worlds"); $this->worldManager->setAutoSave($this->getConfigBool("auto-save", $this->worldManager->getAutoSave())); $this->worldManager->setAutoSaveInterval((int) $this->getProperty("ticks-per.autosave", 6000)); @@ -1040,7 +1039,7 @@ class Server{ if(!$this->worldManager->loadWorld($name, true)){ if(isset($options["generator"])){ $generatorOptions = explode(":", $options["generator"]); - $generator = GeneratorManager::getGenerator(array_shift($generatorOptions)); + $generator = GeneratorManager::getInstance()->getGenerator(array_shift($generatorOptions)); if(count($options) > 0){ $options["preset"] = implode(":", $generatorOptions); } @@ -1063,7 +1062,7 @@ class Server{ $this->worldManager->generateWorld( $default, Generator::convertSeed($this->getConfigString("level-seed")), - GeneratorManager::getGenerator($this->getConfigString("level-type")), + GeneratorManager::getInstance()->getGenerator($this->getConfigString("level-type")), ["preset" => $this->getConfigString("generator-settings")] ); } diff --git a/src/world/World.php b/src/world/World.php index 8e88ab79cf..3d46df649b 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -335,7 +335,7 @@ class World implements ChunkManager{ $this->worldHeight = $this->provider->getWorldHeight(); $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.level.preparing", [$this->displayName])); - $this->generator = GeneratorManager::getGenerator($this->provider->getWorldData()->getGenerator(), true); + $this->generator = GeneratorManager::getInstance()->getGenerator($this->provider->getWorldData()->getGenerator(), true); //TODO: validate generator options $this->folderName = $name; diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index d641598fbc..02f88d8683 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -205,7 +205,7 @@ class WorldManager{ return false; } try{ - GeneratorManager::getGenerator($provider->getWorldData()->getGenerator(), true); + GeneratorManager::getInstance()->getGenerator($provider->getWorldData()->getGenerator(), true); }catch(\InvalidArgumentException $e){ $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.level.loadError", [$name, "Unknown generator \"" . $provider->getWorldData()->getGenerator() . "\""])); return false; diff --git a/src/world/format/io/FormatConverter.php b/src/world/format/io/FormatConverter.php index cc01bd1611..d60be76b07 100644 --- a/src/world/format/io/FormatConverter.php +++ b/src/world/format/io/FormatConverter.php @@ -101,7 +101,7 @@ class FormatConverter{ $this->logger->info("Found previous conversion attempt, deleting..."); Filesystem::recursiveUnlink($convertedOutput); } - $this->newProvider::generate($convertedOutput, $data->getName(), $data->getSeed(), GeneratorManager::getGenerator($data->getGenerator()), $data->getGeneratorOptions()); + $this->newProvider::generate($convertedOutput, $data->getName(), $data->getSeed(), GeneratorManager::getInstance()->getGenerator($data->getGenerator()), $data->getGeneratorOptions()); /** * @see WritableWorldProvider::__construct() diff --git a/src/world/format/io/data/BedrockWorldData.php b/src/world/format/io/data/BedrockWorldData.php index ad50b9dddc..a3139a90c9 100644 --- a/src/world/format/io/data/BedrockWorldData.php +++ b/src/world/format/io/data/BedrockWorldData.php @@ -102,7 +102,7 @@ class BedrockWorldData extends BaseNbtWorldData{ //Additional PocketMine-MP fields ->setTag("GameRules", new CompoundTag()) ->setByte("hardcore", ($options["hardcore"] ?? false) === true ? 1 : 0) - ->setString("generatorName", GeneratorManager::getGeneratorName($generator)) + ->setString("generatorName", GeneratorManager::getInstance()->getGeneratorName($generator)) ->setString("generatorOptions", $options["preset"] ?? ""); $nbt = new LittleEndianNbtSerializer(); diff --git a/src/world/format/io/data/JavaWorldData.php b/src/world/format/io/data/JavaWorldData.php index 271728f5d9..f01d1446d7 100644 --- a/src/world/format/io/data/JavaWorldData.php +++ b/src/world/format/io/data/JavaWorldData.php @@ -64,7 +64,7 @@ class JavaWorldData extends BaseNbtWorldData{ ->setLong("RandomSeed", $seed) ->setLong("SizeOnDisk", 0) ->setLong("Time", 0) - ->setString("generatorName", GeneratorManager::getGeneratorName($generator)) + ->setString("generatorName", GeneratorManager::getInstance()->getGeneratorName($generator)) ->setString("generatorOptions", $options["preset"] ?? "") ->setString("LevelName", $name) ->setTag("GameRules", new CompoundTag()); diff --git a/src/world/generator/GeneratorManager.php b/src/world/generator/GeneratorManager.php index b55640750d..58811f05f1 100644 --- a/src/world/generator/GeneratorManager.php +++ b/src/world/generator/GeneratorManager.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\generator; +use pocketmine\utils\SingletonTrait; use pocketmine\utils\Utils; use pocketmine\world\generator\hell\Nether; use pocketmine\world\generator\normal\Normal; @@ -30,21 +31,20 @@ use function array_keys; use function strtolower; final class GeneratorManager{ + use SingletonTrait; + /** * @var string[] name => classname mapping * @phpstan-var array> */ - private static $list = []; + private $list = []; - /** - * Registers the default known generators. - */ - public static function registerDefaultGenerators() : void{ - self::addGenerator(Flat::class, "flat"); - self::addGenerator(Normal::class, "normal"); - self::addGenerator(Normal::class, "default"); - self::addGenerator(Nether::class, "hell"); - self::addGenerator(Nether::class, "nether"); + public function __construct(){ + $this->addGenerator(Flat::class, "flat"); + $this->addGenerator(Normal::class, "normal"); + $this->addGenerator(Normal::class, "default"); + $this->addGenerator(Nether::class, "hell"); + $this->addGenerator(Nether::class, "nether"); } /** @@ -55,14 +55,14 @@ final class GeneratorManager{ * * @throws \InvalidArgumentException */ - public static function addGenerator(string $class, string $name, bool $overwrite = false) : void{ + public function addGenerator(string $class, string $name, bool $overwrite = false) : void{ Utils::testValidInstance($class, Generator::class); - if(!$overwrite and isset(self::$list[$name = strtolower($name)])){ + if(!$overwrite and isset($this->list[$name = strtolower($name)])){ throw new \InvalidArgumentException("Alias \"$name\" is already assigned"); } - self::$list[$name] = $class; + $this->list[$name] = $class; } /** @@ -70,8 +70,8 @@ final class GeneratorManager{ * * @return string[] */ - public static function getGeneratorList() : array{ - return array_keys(self::$list); + public function getGeneratorList() : array{ + return array_keys($this->list); } /** @@ -84,9 +84,9 @@ final class GeneratorManager{ * * @throws \InvalidArgumentException if the generator type isn't registered */ - public static function getGenerator(string $name, bool $throwOnMissing = false){ - if(isset(self::$list[$name = strtolower($name)])){ - return self::$list[$name]; + public function getGenerator(string $name, bool $throwOnMissing = false){ + if(isset($this->list[$name = strtolower($name)])){ + return $this->list[$name]; } if($throwOnMissing){ @@ -103,9 +103,9 @@ final class GeneratorManager{ * * @throws \InvalidArgumentException if the class type cannot be matched to a known alias */ - public static function getGeneratorName(string $class) : string{ + public function getGeneratorName(string $class) : string{ Utils::testValidInstance($class, Generator::class); - foreach(self::$list as $name => $c){ + foreach($this->list as $name => $c){ if($c === $class){ return $name; } @@ -113,8 +113,4 @@ final class GeneratorManager{ throw new \InvalidArgumentException("Generator class $class is not registered"); } - - private function __construct(){ - //NOOP - } } diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index fe34314b69..bf2e09ae23 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -11,7 +11,7 @@ parameters: path: ../../../build/server-phar.php - - message: "#^Parameter \\#1 \\$name of static method pocketmine\\\\world\\\\generator\\\\GeneratorManager\\:\\:getGenerator\\(\\) expects string, string\\|null given\\.$#" + message: "#^Parameter \\#1 \\$name of method pocketmine\\\\world\\\\generator\\\\GeneratorManager\\:\\:getGenerator\\(\\) expects string, string\\|null given\\.$#" count: 1 path: ../../../src/Server.php diff --git a/tools/convert-world.php b/tools/convert-world.php index f4e376853e..e524b1b6fa 100644 --- a/tools/convert-world.php +++ b/tools/convert-world.php @@ -25,12 +25,9 @@ use pocketmine\world\format\io\FormatConverter; use pocketmine\world\format\io\WorldProvider; use pocketmine\world\format\io\WorldProviderManager; use pocketmine\world\format\io\WritableWorldProvider; -use pocketmine\world\generator\GeneratorManager; require_once dirname(__DIR__) . '/vendor/autoload.php'; -GeneratorManager::registerDefaultGenerators(); - $writableFormats = array_filter(WorldProviderManager::getInstance()->getAvailableProviders(), function(string $class){ return is_a($class, WritableWorldProvider::class, true); }); From 23ab6a283bdd98ef9cdde9d27d94a7bffc350ae2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 May 2020 11:55:29 +0100 Subject: [PATCH 1605/3224] Separate QueryInfo from QueryRegenerateEvent this removes some useless and confusing APIs from query info. --- src/Server.php | 15 +- src/event/server/QueryRegenerateEvent.php | 222 +------------------ src/network/query/QueryInfo.php | 248 ++++++++++++++++++++++ 3 files changed, 264 insertions(+), 221 deletions(-) create mode 100644 src/network/query/QueryInfo.php diff --git a/src/Server.php b/src/Server.php index 38f192f5fd..24c1a509c7 100644 --- a/src/Server.php +++ b/src/Server.php @@ -59,6 +59,7 @@ use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\raklib\RakLibInterface; use pocketmine\network\Network; use pocketmine\network\query\QueryHandler; +use pocketmine\network\query\QueryInfo; use pocketmine\network\upnp\UPnP; use pocketmine\permission\BanList; use pocketmine\permission\DefaultPermissions; @@ -271,8 +272,8 @@ class Server{ */ private $uniquePlayers = []; - /** @var QueryRegenerateEvent */ - private $queryRegenerateTask; + /** @var QueryInfo */ + private $queryInfo; /** @var Config */ private $properties; @@ -1023,7 +1024,7 @@ class Server{ $this->updater = new AutoUpdater($this, $this->getProperty("auto-updater.host", "update.pmmp.io")); - $this->queryRegenerateTask = new QueryRegenerateEvent($this); + $this->queryInfo = new QueryInfo($this); register_shutdown_function([$this, "crashDump"]); @@ -1424,10 +1425,10 @@ class Server{ } /** - * @return QueryRegenerateEvent + * @return QueryInfo */ public function getQueryInformation(){ - return $this->queryRegenerateTask; + return $this->queryInfo; } /** @@ -1680,7 +1681,9 @@ class Server{ $this->currentTPS = 20; $this->currentUse = 0; - ($this->queryRegenerateTask = new QueryRegenerateEvent($this))->call(); + $queryRegenerateEvent = new QueryRegenerateEvent(new QueryInfo($this)); + $queryRegenerateEvent->call(); + $this->queryInfo = $queryRegenerateEvent->getQueryInfo(); $this->network->updateName(); $this->network->resetStatistics(); diff --git a/src/event/server/QueryRegenerateEvent.php b/src/event/server/QueryRegenerateEvent.php index 3b6a19c2a1..5bf879f942 100644 --- a/src/event/server/QueryRegenerateEvent.php +++ b/src/event/server/QueryRegenerateEvent.php @@ -23,225 +23,17 @@ declare(strict_types=1); namespace pocketmine\event\server; -use pocketmine\player\Player; -use pocketmine\plugin\Plugin; -use pocketmine\Server; -use pocketmine\utils\Binary; -use function chr; -use function count; -use function str_replace; -use function substr; +use pocketmine\network\query\QueryInfo; class QueryRegenerateEvent extends ServerEvent{ - public const GAME_ID = "MINECRAFTPE"; - - /** @var string */ - private $serverName; - /** @var bool */ - private $listPlugins; - /** @var Plugin[] */ - private $plugins; - /** @var Player[] */ - private $players; - - /** @var string */ - private $gametype; - /** @var string */ - private $version; - /** @var string */ - private $server_engine; - /** @var string */ - private $map; - /** @var int */ - private $numPlayers; - /** @var int */ - private $maxPlayers; - /** @var string */ - private $whitelist; - /** @var int */ - private $port; - /** @var string */ - private $ip; - - /** - * @var string[] - * @phpstan-var array - */ - private $extraData = []; - - /** @var string|null */ - private $longQueryCache = null; - /** @var string|null */ - private $shortQueryCache = null; - - public function __construct(Server $server){ - $this->serverName = $server->getMotd(); - $this->listPlugins = $server->getProperty("settings.query-plugins", true); - $this->plugins = $server->getPluginManager()->getPlugins(); - $this->players = $server->getOnlinePlayers(); - - $this->gametype = ($server->getGamemode()->getMagicNumber() & 0x01) === 0 ? "SMP" : "CMP"; - $this->version = $server->getVersion(); - $this->server_engine = $server->getName() . " " . $server->getPocketMineVersion(); - $world = $server->getWorldManager()->getDefaultWorld(); - $this->map = $world === null ? "unknown" : $world->getDisplayName(); - $this->numPlayers = count($this->players); - $this->maxPlayers = $server->getMaxPlayers(); - $this->whitelist = $server->hasWhitelist() ? "on" : "off"; - $this->port = $server->getPort(); - $this->ip = $server->getIp(); + /** @var QueryInfo */ + private $queryInfo; + public function __construct(QueryInfo $queryInfo){ + $this->queryInfo = $queryInfo; } - private function destroyCache() : void{ - $this->longQueryCache = null; - $this->shortQueryCache = null; - } - - public function getServerName() : string{ - return $this->serverName; - } - - public function setServerName(string $serverName) : void{ - $this->serverName = $serverName; - $this->destroyCache(); - } - - public function canListPlugins() : bool{ - return $this->listPlugins; - } - - public function setListPlugins(bool $value) : void{ - $this->listPlugins = $value; - $this->destroyCache(); - } - - /** - * @return Plugin[] - */ - public function getPlugins() : array{ - return $this->plugins; - } - - /** - * @param Plugin[] $plugins - */ - public function setPlugins(array $plugins) : void{ - $this->plugins = $plugins; - $this->destroyCache(); - } - - /** - * @return Player[] - */ - public function getPlayerList() : array{ - return $this->players; - } - - /** - * @param Player[] $players - */ - public function setPlayerList(array $players) : void{ - $this->players = $players; - $this->destroyCache(); - } - - public function getPlayerCount() : int{ - return $this->numPlayers; - } - - public function setPlayerCount(int $count) : void{ - $this->numPlayers = $count; - $this->destroyCache(); - } - - public function getMaxPlayerCount() : int{ - return $this->maxPlayers; - } - - public function setMaxPlayerCount(int $count) : void{ - $this->maxPlayers = $count; - $this->destroyCache(); - } - - public function getWorld() : string{ - return $this->map; - } - - public function setWorld(string $world) : void{ - $this->map = $world; - $this->destroyCache(); - } - - /** - * Returns the extra Query data in key => value form - * - * @return string[] - * @phpstan-return array - */ - public function getExtraData() : array{ - return $this->extraData; - } - - /** - * @param string[] $extraData - * @phpstan-param array $extraData - */ - public function setExtraData(array $extraData) : void{ - $this->extraData = $extraData; - $this->destroyCache(); - } - - public function getLongQuery() : string{ - if($this->longQueryCache !== null){ - return $this->longQueryCache; - } - $query = ""; - - $plist = $this->server_engine; - if(count($this->plugins) > 0 and $this->listPlugins){ - $plist .= ":"; - foreach($this->plugins as $p){ - $d = $p->getDescription(); - $plist .= " " . str_replace([";", ":", " "], ["", "", "_"], $d->getName()) . " " . str_replace([";", ":", " "], ["", "", "_"], $d->getVersion()) . ";"; - } - $plist = substr($plist, 0, -1); - } - - $KVdata = [ - "splitnum" => chr(128), - "hostname" => $this->serverName, - "gametype" => $this->gametype, - "game_id" => self::GAME_ID, - "version" => $this->version, - "server_engine" => $this->server_engine, - "plugins" => $plist, - "map" => $this->map, - "numplayers" => $this->numPlayers, - "maxplayers" => $this->maxPlayers, - "whitelist" => $this->whitelist, - "hostip" => $this->ip, - "hostport" => $this->port - ]; - - foreach($KVdata as $key => $value){ - $query .= $key . "\x00" . $value . "\x00"; - } - - foreach($this->extraData as $key => $value){ - $query .= $key . "\x00" . $value . "\x00"; - } - - $query .= "\x00\x01player_\x00\x00"; - foreach($this->players as $player){ - $query .= $player->getName() . "\x00"; - } - $query .= "\x00"; - - return $this->longQueryCache = $query; - } - - public function getShortQuery() : string{ - return $this->shortQueryCache ?? ($this->shortQueryCache = $this->serverName . "\x00" . $this->gametype . "\x00" . $this->map . "\x00" . $this->numPlayers . "\x00" . $this->maxPlayers . "\x00" . Binary::writeLShort($this->port) . $this->ip . "\x00"); + public function getQueryInfo() : QueryInfo{ + return $this->queryInfo; } } diff --git a/src/network/query/QueryInfo.php b/src/network/query/QueryInfo.php new file mode 100644 index 0000000000..975bfa7149 --- /dev/null +++ b/src/network/query/QueryInfo.php @@ -0,0 +1,248 @@ + + */ + private $extraData = []; + + /** @var string|null */ + private $longQueryCache = null; + /** @var string|null */ + private $shortQueryCache = null; + + public function __construct(Server $server){ + $this->serverName = $server->getMotd(); + $this->listPlugins = $server->getProperty("settings.query-plugins", true); + $this->plugins = $server->getPluginManager()->getPlugins(); + $this->players = $server->getOnlinePlayers(); + + $this->gametype = ($server->getGamemode()->getMagicNumber() & 0x01) === 0 ? "SMP" : "CMP"; + $this->version = $server->getVersion(); + $this->server_engine = $server->getName() . " " . $server->getPocketMineVersion(); + $world = $server->getWorldManager()->getDefaultWorld(); + $this->map = $world === null ? "unknown" : $world->getDisplayName(); + $this->numPlayers = count($this->players); + $this->maxPlayers = $server->getMaxPlayers(); + $this->whitelist = $server->hasWhitelist() ? "on" : "off"; + $this->port = $server->getPort(); + $this->ip = $server->getIp(); + + } + + private function destroyCache() : void{ + $this->longQueryCache = null; + $this->shortQueryCache = null; + } + + public function getServerName() : string{ + return $this->serverName; + } + + public function setServerName(string $serverName) : void{ + $this->serverName = $serverName; + $this->destroyCache(); + } + + public function canListPlugins() : bool{ + return $this->listPlugins; + } + + public function setListPlugins(bool $value) : void{ + $this->listPlugins = $value; + $this->destroyCache(); + } + + /** + * @return Plugin[] + */ + public function getPlugins() : array{ + return $this->plugins; + } + + /** + * @param Plugin[] $plugins + */ + public function setPlugins(array $plugins) : void{ + $this->plugins = $plugins; + $this->destroyCache(); + } + + /** + * @return Player[] + */ + public function getPlayerList() : array{ + return $this->players; + } + + /** + * @param Player[] $players + */ + public function setPlayerList(array $players) : void{ + $this->players = $players; + $this->destroyCache(); + } + + public function getPlayerCount() : int{ + return $this->numPlayers; + } + + public function setPlayerCount(int $count) : void{ + $this->numPlayers = $count; + $this->destroyCache(); + } + + public function getMaxPlayerCount() : int{ + return $this->maxPlayers; + } + + public function setMaxPlayerCount(int $count) : void{ + $this->maxPlayers = $count; + $this->destroyCache(); + } + + public function getWorld() : string{ + return $this->map; + } + + public function setWorld(string $world) : void{ + $this->map = $world; + $this->destroyCache(); + } + + /** + * Returns the extra Query data in key => value form + * + * @return string[] + * @phpstan-return array + */ + public function getExtraData() : array{ + return $this->extraData; + } + + /** + * @param string[] $extraData + * + * @phpstan-param array $extraData + */ + public function setExtraData(array $extraData) : void{ + $this->extraData = $extraData; + $this->destroyCache(); + } + + public function getLongQuery() : string{ + if($this->longQueryCache !== null){ + return $this->longQueryCache; + } + $query = ""; + + $plist = $this->server_engine; + if(count($this->plugins) > 0 and $this->listPlugins){ + $plist .= ":"; + foreach($this->plugins as $p){ + $d = $p->getDescription(); + $plist .= " " . str_replace([";", ":", " "], ["", "", "_"], $d->getName()) . " " . str_replace([";", ":", " "], ["", "", "_"], $d->getVersion()) . ";"; + } + $plist = substr($plist, 0, -1); + } + + $KVdata = [ + "splitnum" => chr(128), + "hostname" => $this->serverName, + "gametype" => $this->gametype, + "game_id" => self::GAME_ID, + "version" => $this->version, + "server_engine" => $this->server_engine, + "plugins" => $plist, + "map" => $this->map, + "numplayers" => $this->numPlayers, + "maxplayers" => $this->maxPlayers, + "whitelist" => $this->whitelist, + "hostip" => $this->ip, + "hostport" => $this->port + ]; + + foreach($KVdata as $key => $value){ + $query .= $key . "\x00" . $value . "\x00"; + } + + foreach($this->extraData as $key => $value){ + $query .= $key . "\x00" . $value . "\x00"; + } + + $query .= "\x00\x01player_\x00\x00"; + foreach($this->players as $player){ + $query .= $player->getName() . "\x00"; + } + $query .= "\x00"; + + return $this->longQueryCache = $query; + } + + public function getShortQuery() : string{ + return $this->shortQueryCache ?? ($this->shortQueryCache = $this->serverName . "\x00" . $this->gametype . "\x00" . $this->map . "\x00" . $this->numPlayers . "\x00" . $this->maxPlayers . "\x00" . Binary::writeLShort($this->port) . $this->ip . "\x00"); + } +} From 5f2e65d60898c3c58f9db5810140e5242b026843 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 May 2020 12:28:12 +0100 Subject: [PATCH 1606/3224] QueryHandler: be honest about dependency on Server --- src/Server.php | 2 +- src/network/query/QueryHandler.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Server.php b/src/Server.php index 24c1a509c7..59a09aa404 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1084,7 +1084,7 @@ class Server{ $this->logger->info($this->getLanguage()->translateString("pocketmine.server.networkStart", [$this->getIp(), $this->getPort()])); if($this->getConfigBool("enable-query", true)){ - $this->network->registerRawPacketHandler(new QueryHandler()); + $this->network->registerRawPacketHandler(new QueryHandler($this)); } foreach($this->getIPBans()->getEntries() as $entry){ diff --git a/src/network/query/QueryHandler.php b/src/network/query/QueryHandler.php index 47941e27c6..b88e47b739 100644 --- a/src/network/query/QueryHandler.php +++ b/src/network/query/QueryHandler.php @@ -53,8 +53,8 @@ class QueryHandler implements RawPacketHandler{ public const HANDSHAKE = 9; public const STATISTICS = 0; - public function __construct(){ - $this->server = Server::getInstance(); + public function __construct(Server $server){ + $this->server = $server; $this->logger = new \PrefixedLogger($this->server->getLogger(), "Query Handler"); $addr = $this->server->getIp(); $port = $this->server->getPort(); From 5eadb0ac44a96726a6658584ce80f30b2ddfaaef Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 May 2020 12:31:22 +0100 Subject: [PATCH 1607/3224] ConsoleCommandSender: be honest about Server dependency --- src/Server.php | 2 +- src/command/ConsoleCommandSender.php | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Server.php b/src/Server.php index 59a09aa404..9c8d685a85 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1113,7 +1113,7 @@ class Server{ $this->logger->info($this->getLanguage()->translateString("pocketmine.server.startFinished", [round(microtime(true) - $this->startTime, 3)])); //TODO: move console parts to a separate component - $consoleSender = new ConsoleCommandSender(); + $consoleSender = new ConsoleCommandSender($this); PermissionManager::getInstance()->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $consoleSender); PermissionManager::getInstance()->subscribeToPermission(Server::BROADCAST_CHANNEL_USERS, $consoleSender); diff --git a/src/command/ConsoleCommandSender.php b/src/command/ConsoleCommandSender.php index 7eb7086264..f4dbf2264e 100644 --- a/src/command/ConsoleCommandSender.php +++ b/src/command/ConsoleCommandSender.php @@ -34,15 +34,18 @@ use const PHP_INT_MAX; class ConsoleCommandSender implements CommandSender{ use PermissibleDelegateTrait; + /** @var Server */ + private $server; /** @var int|null */ protected $lineHeight = null; - public function __construct(){ + public function __construct(Server $server){ + $this->server = $server; $this->perm = new PermissibleBase($this); } public function getServer() : Server{ - return Server::getInstance(); + return $this->server; } /** From 2170f81cdd47633b1a11a633443eee086b6f03e3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 May 2020 14:14:47 +0100 Subject: [PATCH 1608/3224] PluginManager: remove dead function isCompatibleApi() moved to ApiVersion static class --- src/plugin/PluginManager.php | 45 ------------------------------------ 1 file changed, 45 deletions(-) diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index ea193ed200..90185862d2 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -37,13 +37,10 @@ use pocketmine\timings\TimingsHandler; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Utils; use function array_intersect; -use function array_map; use function array_merge; -use function array_pad; use function class_exists; use function count; use function dirname; -use function explode; use function file_exists; use function get_class; use function implode; @@ -59,7 +56,6 @@ use function shuffle; use function stripos; use function strpos; use function strtolower; -use function strtoupper; use const DIRECTORY_SEPARATOR; /** @@ -360,47 +356,6 @@ class PluginManager{ return $loadedPlugins; } - /** - * Returns whether a specified API version string is considered compatible with the server's API version. - * - * @param string ...$versions - */ - public function isCompatibleApi(string ...$versions) : bool{ - $serverString = $this->server->getApiVersion(); - $serverApi = array_pad(explode("-", $serverString, 2), 2, ""); - $serverNumbers = array_map("\intval", explode(".", $serverApi[0])); - - foreach($versions as $version){ - //Format: majorVersion.minorVersion.patch (3.0.0) - // or: majorVersion.minorVersion.patch-devBuild (3.0.0-alpha1) - if($version !== $serverString){ - $pluginApi = array_pad(explode("-", $version, 2), 2, ""); //0 = version, 1 = suffix (optional) - - if(strtoupper($pluginApi[1]) !== strtoupper($serverApi[1])){ //Different release phase (alpha vs. beta) or phase build (alpha.1 vs alpha.2) - continue; - } - - $pluginNumbers = array_map("\intval", array_pad(explode(".", $pluginApi[0]), 3, "0")); //plugins might specify API like "3.0" or "3" - - if($pluginNumbers[0] !== $serverNumbers[0]){ //Completely different API version - continue; - } - - if($pluginNumbers[1] > $serverNumbers[1]){ //If the plugin requires new API features, being backwards compatible - continue; - } - - if($pluginNumbers[1] === $serverNumbers[1] and $pluginNumbers[2] > $serverNumbers[2]){ //If the plugin requires bug fixes in patches, being backwards compatible - continue; - } - } - - return true; - } - - return false; - } - public function isPluginEnabled(Plugin $plugin) : bool{ return isset($this->plugins[$plugin->getDescription()->getName()]) and $plugin->isEnabled(); } From 49bd58a86a0cdb7abc4ae1baf5f6d666ff004d0d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 May 2020 14:26:12 +0100 Subject: [PATCH 1609/3224] DiskResourceProvider: do not trim backslashes from path when we're not on Windows --- src/plugin/DiskResourceProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugin/DiskResourceProvider.php b/src/plugin/DiskResourceProvider.php index 33d62b18c0..b1fd026864 100644 --- a/src/plugin/DiskResourceProvider.php +++ b/src/plugin/DiskResourceProvider.php @@ -43,7 +43,7 @@ class DiskResourceProvider implements ResourceProvider{ private $file; public function __construct(string $path){ - $this->file = rtrim($path, "/\\") . "/"; + $this->file = rtrim(str_replace(DIRECTORY_SEPARATOR, "/", $path), "/") . "/"; } /** From c95951479c666c1e169cbf8e22d225097ccdfa62 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 May 2020 14:28:07 +0100 Subject: [PATCH 1610/3224] FormatConverter: beware paths with \ on linux --- src/world/format/io/FormatConverter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/format/io/FormatConverter.php b/src/world/format/io/FormatConverter.php index d60be76b07..9accebbe5c 100644 --- a/src/world/format/io/FormatConverter.php +++ b/src/world/format/io/FormatConverter.php @@ -96,7 +96,7 @@ class FormatConverter{ $this->logger->info("Generating new world"); $data = $this->oldProvider->getWorldData(); - $convertedOutput = rtrim($this->oldProvider->getPath(), "/\\") . "_converted" . DIRECTORY_SEPARATOR; + $convertedOutput = rtrim($this->oldProvider->getPath(), "/" . DIRECTORY_SEPARATOR) . "_converted" . DIRECTORY_SEPARATOR; if(file_exists($convertedOutput)){ $this->logger->info("Found previous conversion attempt, deleting..."); Filesystem::recursiveUnlink($convertedOutput); From b05fab3e3c0e4cbb17640f4e7165f7d807a6674c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 May 2020 14:30:59 +0100 Subject: [PATCH 1611/3224] FormatConverter: do not hardcode progress update interval --- src/world/format/io/FormatConverter.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/world/format/io/FormatConverter.php b/src/world/format/io/FormatConverter.php index 9accebbe5c..70f83cf791 100644 --- a/src/world/format/io/FormatConverter.php +++ b/src/world/format/io/FormatConverter.php @@ -51,11 +51,15 @@ class FormatConverter{ /** @var \Logger */ private $logger; - public function __construct(WorldProvider $oldProvider, string $newProvider, string $backupPath, \Logger $logger){ + /** @var int */ + private $chunksPerProgressUpdate; + + public function __construct(WorldProvider $oldProvider, string $newProvider, string $backupPath, \Logger $logger, int $chunksPerProgressUpdate = 256){ $this->oldProvider = $oldProvider; Utils::testValidInstance($newProvider, WritableWorldProvider::class); $this->newProvider = $newProvider; $this->logger = new \PrefixedLogger($logger, "World Converter: " . $this->oldProvider->getWorldData()->getName()); + $this->chunksPerProgressUpdate = $chunksPerProgressUpdate; if(!file_exists($backupPath)){ @mkdir($backupPath, 0777, true); @@ -134,16 +138,15 @@ class FormatConverter{ $start = microtime(true); $thisRound = $start; - static $reportInterval = 256; foreach($this->oldProvider->getAllChunks(true, $this->logger) as $chunk){ $chunk->setDirty(); $new->saveChunk($chunk); $counter++; - if(($counter % $reportInterval) === 0){ + if(($counter % $this->chunksPerProgressUpdate) === 0){ $time = microtime(true); $diff = $time - $thisRound; $thisRound = $time; - $this->logger->info("Converted $counter / $count chunks (" . floor($reportInterval / $diff) . " chunks/sec)"); + $this->logger->info("Converted $counter / $count chunks (" . floor($this->chunksPerProgressUpdate / $diff) . " chunks/sec)"); } } $total = microtime(true) - $start; From fe649d8d70b93f82ed53cfc383205efdeecfd434 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 May 2020 15:48:03 +0100 Subject: [PATCH 1612/3224] Extract ServerConfigGroup from Server this API isn't very nice, but it's pretty much the same as the original, and at least this can be _kinda_ unit-tested... --- src/CrashDump.php | 6 +- src/MemoryManager.php | 34 +-- src/Server.php | 231 ++++++------------ src/ServerConfigGroup.php | 128 ++++++++++ .../defaults/DefaultGamemodeCommand.php | 2 +- src/command/defaults/DifficultyCommand.php | 2 +- src/command/defaults/TimingsCommand.php | 2 +- src/command/defaults/WhitelistCommand.php | 4 +- src/network/mcpe/raklib/RakLibInterface.php | 2 +- src/network/query/QueryInfo.php | 2 +- src/player/Player.php | 10 +- src/stats/SendUsageTask.php | 2 +- src/updater/AutoUpdater.php | 6 +- src/world/World.php | 11 +- tests/phpstan/configs/l7-baseline.neon | 20 +- 15 files changed, 258 insertions(+), 204 deletions(-) create mode 100644 src/ServerConfigGroup.php diff --git a/src/CrashDump.php b/src/CrashDump.php index d3ca48cce7..bd97b35957 100644 --- a/src/CrashDump.php +++ b/src/CrashDump.php @@ -183,7 +183,7 @@ class CrashDump{ private function extraData() : void{ global $argv; - if($this->server->getProperty("auto-report.send-settings", true) !== false){ + if($this->server->getConfigGroup()->getProperty("auto-report.send-settings", true) !== false){ $this->data["parameters"] = (array) $argv; $this->data["server.properties"] = @file_get_contents($this->server->getDataPath() . "server.properties"); $this->data["server.properties"] = preg_replace("#^rcon\\.password=(.*)$#m", "rcon.password=******", $this->data["server.properties"]); @@ -199,7 +199,7 @@ class CrashDump{ } $this->data["extensions"] = $extensions; - if($this->server->getProperty("auto-report.send-phpinfo", true) !== false){ + if($this->server->getConfigGroup()->getProperty("auto-report.send-phpinfo", true) !== false){ ob_start(); phpinfo(); $this->data["phpinfo"] = ob_get_contents(); @@ -261,7 +261,7 @@ class CrashDump{ $this->addLine("Code:"); $this->data["code"] = []; - if($this->server->getProperty("auto-report.send-code", true) !== false and file_exists($error["fullFile"])){ + if($this->server->getConfigGroup()->getProperty("auto-report.send-code", true) !== false and file_exists($error["fullFile"])){ $file = @file($error["fullFile"], FILE_IGNORE_NEW_LINES); if($file !== false){ for($l = max(0, $error["line"] - 10); $l < $error["line"] + 10 and isset($file[$l]); ++$l){ diff --git a/src/MemoryManager.php b/src/MemoryManager.php index 0ab9f41eef..137bd5d955 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -118,15 +118,15 @@ class MemoryManager{ $this->server = $server; $this->logger = new \PrefixedLogger($server->getLogger(), "Memory Manager"); - $this->init(); + $this->init($server->getConfigGroup()); } - private function init() : void{ - $this->memoryLimit = ((int) $this->server->getProperty("memory.main-limit", 0)) * 1024 * 1024; + private function init(ServerConfigGroup $config) : void{ + $this->memoryLimit = ((int) $config->getProperty("memory.main-limit", 0)) * 1024 * 1024; $defaultMemory = 1024; - if(preg_match("/([0-9]+)([KMGkmg])/", $this->server->getConfigString("memory-limit", ""), $matches) > 0){ + if(preg_match("/([0-9]+)([KMGkmg])/", $config->getConfigString("memory-limit", ""), $matches) > 0){ $m = (int) $matches[1]; if($m <= 0){ $defaultMemory = 0; @@ -148,7 +148,7 @@ class MemoryManager{ } } - $hardLimit = ((int) $this->server->getProperty("memory.main-hard-limit", $defaultMemory)); + $hardLimit = ((int) $config->getProperty("memory.main-hard-limit", $defaultMemory)); if($hardLimit <= 0){ ini_set("memory_limit", '-1'); @@ -156,22 +156,22 @@ class MemoryManager{ ini_set("memory_limit", $hardLimit . "M"); } - $this->globalMemoryLimit = ((int) $this->server->getProperty("memory.global-limit", 0)) * 1024 * 1024; - $this->checkRate = (int) $this->server->getProperty("memory.check-rate", 20); - $this->continuousTrigger = (bool) $this->server->getProperty("memory.continuous-trigger", true); - $this->continuousTriggerRate = (int) $this->server->getProperty("memory.continuous-trigger-rate", 30); + $this->globalMemoryLimit = ((int) $config->getProperty("memory.global-limit", 0)) * 1024 * 1024; + $this->checkRate = (int) $config->getProperty("memory.check-rate", 20); + $this->continuousTrigger = (bool) $config->getProperty("memory.continuous-trigger", true); + $this->continuousTriggerRate = (int) $config->getProperty("memory.continuous-trigger-rate", 30); - $this->garbageCollectionPeriod = (int) $this->server->getProperty("memory.garbage-collection.period", 36000); - $this->garbageCollectionTrigger = (bool) $this->server->getProperty("memory.garbage-collection.low-memory-trigger", true); - $this->garbageCollectionAsync = (bool) $this->server->getProperty("memory.garbage-collection.collect-async-worker", true); + $this->garbageCollectionPeriod = (int) $config->getProperty("memory.garbage-collection.period", 36000); + $this->garbageCollectionTrigger = (bool) $config->getProperty("memory.garbage-collection.low-memory-trigger", true); + $this->garbageCollectionAsync = (bool) $config->getProperty("memory.garbage-collection.collect-async-worker", true); - $this->lowMemChunkRadiusOverride = (int) $this->server->getProperty("memory.max-chunks.chunk-radius", 4); - $this->lowMemChunkGC = (bool) $this->server->getProperty("memory.max-chunks.trigger-chunk-collect", true); + $this->lowMemChunkRadiusOverride = (int) $config->getProperty("memory.max-chunks.chunk-radius", 4); + $this->lowMemChunkGC = (bool) $config->getProperty("memory.max-chunks.trigger-chunk-collect", true); - $this->lowMemDisableChunkCache = (bool) $this->server->getProperty("memory.world-caches.disable-chunk-cache", true); - $this->lowMemClearWorldCache = (bool) $this->server->getProperty("memory.world-caches.low-memory-trigger", true); + $this->lowMemDisableChunkCache = (bool) $config->getProperty("memory.world-caches.disable-chunk-cache", true); + $this->lowMemClearWorldCache = (bool) $config->getProperty("memory.world-caches.low-memory-trigger", true); - $this->dumpWorkers = (bool) $this->server->getProperty("memory.memory-dump.dump-async-worker", true); + $this->dumpWorkers = (bool) $config->getProperty("memory.memory-dump.dump-async-worker", true); gc_enable(); } diff --git a/src/Server.php b/src/Server.php index 9c8d685a85..cdf1c0f9c5 100644 --- a/src/Server.php +++ b/src/Server.php @@ -99,7 +99,6 @@ use pocketmine\world\generator\GeneratorManager; use pocketmine\world\generator\normal\Normal; use pocketmine\world\World; use pocketmine\world\WorldManager; -use function array_key_exists; use function array_shift; use function array_sum; use function base64_encode; @@ -114,12 +113,10 @@ use function file_put_contents; use function filemtime; use function get_class; use function getmypid; -use function getopt; use function implode; use function ini_set; use function is_a; use function is_array; -use function is_bool; use function is_string; use function json_decode; use function max; @@ -275,13 +272,8 @@ class Server{ /** @var QueryInfo */ private $queryInfo; - /** @var Config */ - private $properties; - /** @var mixed[] */ - private $propertyCache = []; - - /** @var Config */ - private $config; + /** @var ServerConfigGroup */ + private $configGroup; /** @var Player[] */ private $playerList = []; @@ -342,11 +334,11 @@ class Server{ } public function getPort() : int{ - return $this->getConfigInt("server-port", 19132); + return $this->configGroup->getConfigInt("server-port", 19132); } public function getViewDistance() : int{ - return max(2, $this->getConfigInt("view-distance", 8)); + return max(2, $this->configGroup->getConfigInt("view-distance", 8)); } /** @@ -357,7 +349,7 @@ class Server{ } public function getIp() : string{ - $str = $this->getConfigString("server-ip"); + $str = $this->configGroup->getConfigString("server-ip"); return $str !== "" ? $str : "0.0.0.0"; } @@ -369,30 +361,30 @@ class Server{ } public function getGamemode() : GameMode{ - return GameMode::fromMagicNumber($this->getConfigInt("gamemode", 0) & 0b11); + return GameMode::fromMagicNumber($this->configGroup->getConfigInt("gamemode", 0) & 0b11); } public function getForceGamemode() : bool{ - return $this->getConfigBool("force-gamemode", false); + return $this->configGroup->getConfigBool("force-gamemode", false); } /** * Returns Server global difficulty. Note that this may be overridden in individual worlds. */ public function getDifficulty() : int{ - return $this->getConfigInt("difficulty", World::DIFFICULTY_NORMAL); + return $this->configGroup->getConfigInt("difficulty", World::DIFFICULTY_NORMAL); } public function hasWhitelist() : bool{ - return $this->getConfigBool("white-list", false); + return $this->configGroup->getConfigBool("white-list", false); } public function isHardcore() : bool{ - return $this->getConfigBool("hardcore", false); + return $this->configGroup->getConfigBool("hardcore", false); } public function getMotd() : string{ - return $this->getConfigString("motd", \pocketmine\NAME . " Server"); + return $this->configGroup->getConfigString("motd", \pocketmine\NAME . " Server"); } /** @@ -493,7 +485,7 @@ class Server{ } public function shouldSavePlayerData() : bool{ - return (bool) $this->getProperty("player.save-player-data", true); + return (bool) $this->configGroup->getProperty("player.save-player-data", true); } /** @@ -625,74 +617,8 @@ class Server{ return $this->getPlayerByRawUUID($uuid->toBinary()); } - /** - * @param mixed $defaultValue - * - * @return mixed - */ - public function getProperty(string $variable, $defaultValue = null){ - if(!array_key_exists($variable, $this->propertyCache)){ - $v = getopt("", ["$variable::"]); - if(isset($v[$variable])){ - $this->propertyCache[$variable] = $v[$variable]; - }else{ - $this->propertyCache[$variable] = $this->config->getNested($variable); - } - } - - return $this->propertyCache[$variable] ?? $defaultValue; - } - - public function getConfigString(string $variable, string $defaultValue = "") : string{ - $v = getopt("", ["$variable::"]); - if(isset($v[$variable])){ - return (string) $v[$variable]; - } - - return $this->properties->exists($variable) ? (string) $this->properties->get($variable) : $defaultValue; - } - - public function setConfigString(string $variable, string $value) : void{ - $this->properties->set($variable, $value); - } - - public function getConfigInt(string $variable, int $defaultValue = 0) : int{ - $v = getopt("", ["$variable::"]); - if(isset($v[$variable])){ - return (int) $v[$variable]; - } - - return $this->properties->exists($variable) ? (int) $this->properties->get($variable) : $defaultValue; - } - - public function setConfigInt(string $variable, int $value) : void{ - $this->properties->set($variable, $value); - } - - public function getConfigBool(string $variable, bool $defaultValue = false) : bool{ - $v = getopt("", ["$variable::"]); - if(isset($v[$variable])){ - $value = $v[$variable]; - }else{ - $value = $this->properties->exists($variable) ? $this->properties->get($variable) : $defaultValue; - } - - if(is_bool($value)){ - return $value; - } - switch(strtolower($value)){ - case "on": - case "true": - case "1": - case "yes": - return true; - } - - return false; - } - - public function setConfigBool(string $variable, bool $value) : void{ - $this->properties->set($variable, $value ? "1" : "0"); + public function getConfigGroup() : ServerConfigGroup{ + return $this->configGroup; } /** @@ -775,7 +701,7 @@ class Server{ * @return string[][] */ public function getCommandAliases() : array{ - $section = $this->getProperty("aliases"); + $section = $this->configGroup->getProperty("aliases"); $result = []; if(is_array($section)){ foreach($section as $key => $value){ @@ -827,7 +753,7 @@ class Server{ $this->dataPath = realpath($dataPath) . DIRECTORY_SEPARATOR; $this->pluginPath = realpath($pluginPath) . DIRECTORY_SEPARATOR; - $this->logger->info("Loading pocketmine.yml..."); + $this->logger->info("Loading server configuration"); if(!file_exists($this->dataPath . "pocketmine.yml")){ $content = file_get_contents(\pocketmine\RESOURCE_PATH . "pocketmine.yml"); if(\pocketmine\IS_DEVELOPMENT_BUILD){ @@ -835,37 +761,38 @@ class Server{ } @file_put_contents($this->dataPath . "pocketmine.yml", $content); } - $this->config = new Config($this->dataPath . "pocketmine.yml", Config::YAML, []); - $this->logger->info("Loading server properties..."); - $this->properties = new Config($this->dataPath . "server.properties", Config::PROPERTIES, [ - "motd" => \pocketmine\NAME . " Server", - "server-port" => 19132, - "white-list" => false, - "max-players" => 20, - "gamemode" => 0, - "force-gamemode" => false, - "hardcore" => false, - "pvp" => true, - "difficulty" => World::DIFFICULTY_NORMAL, - "generator-settings" => "", - "level-name" => "world", - "level-seed" => "", - "level-type" => "DEFAULT", - "enable-query" => true, - "auto-save" => true, - "view-distance" => 8, - "xbox-auth" => true, - "language" => "eng" - ]); + $this->configGroup = new ServerConfigGroup( + new Config($this->dataPath . "pocketmine.yml", Config::YAML, []), + new Config($this->dataPath . "server.properties", Config::PROPERTIES, [ + "motd" => \pocketmine\NAME . " Server", + "server-port" => 19132, + "white-list" => false, + "max-players" => 20, + "gamemode" => 0, + "force-gamemode" => false, + "hardcore" => false, + "pvp" => true, + "difficulty" => World::DIFFICULTY_NORMAL, + "generator-settings" => "", + "level-name" => "world", + "level-seed" => "", + "level-type" => "DEFAULT", + "enable-query" => true, + "auto-save" => true, + "view-distance" => 8, + "xbox-auth" => true, + "language" => "eng" + ]) + ); - $debugLogLevel = (int) $this->getProperty("debug.level", 1); + $debugLogLevel = (int) $this->configGroup->getProperty("debug.level", 1); if($this->logger instanceof MainLogger){ $this->logger->setLogDebug($debugLogLevel > 1); } - $this->forceLanguage = (bool) $this->getProperty("settings.force-language", false); - $selectedLang = $this->getConfigString("language", $this->getProperty("settings.language", Language::FALLBACK_LANGUAGE)); + $this->forceLanguage = (bool) $this->configGroup->getProperty("settings.force-language", false); + $selectedLang = $this->configGroup->getConfigString("language", $this->configGroup->getProperty("settings.language", Language::FALLBACK_LANGUAGE)); try{ $this->language = new Language($selectedLang); }catch(LanguageNotFoundException $e){ @@ -881,7 +808,7 @@ class Server{ $this->logger->info($this->getLanguage()->translateString("language.selected", [$this->getLanguage()->getName(), $this->getLanguage()->getLang()])); if(\pocketmine\IS_DEVELOPMENT_BUILD){ - if(!((bool) $this->getProperty("settings.enable-dev-builds", false))){ + if(!((bool) $this->configGroup->getProperty("settings.enable-dev-builds", false))){ $this->logger->emergency($this->language->translateString("pocketmine.server.devBuild.error1", [\pocketmine\NAME])); $this->logger->emergency($this->language->translateString("pocketmine.server.devBuild.error2")); $this->logger->emergency($this->language->translateString("pocketmine.server.devBuild.error3")); @@ -903,7 +830,7 @@ class Server{ $this->logger->info($this->getLanguage()->translateString("pocketmine.server.start", [TextFormat::AQUA . $this->getVersion() . TextFormat::RESET])); - if(($poolSize = $this->getProperty("settings.async-workers", "auto")) === "auto"){ + if(($poolSize = $this->configGroup->getProperty("settings.async-workers", "auto")) === "auto"){ $poolSize = 2; $processors = Utils::getCoreCount() - 2; @@ -914,25 +841,25 @@ class Server{ $poolSize = max(1, (int) $poolSize); } - $this->asyncPool = new AsyncPool($poolSize, max(-1, (int) $this->getProperty("memory.async-worker-hard-limit", 256)), $this->autoloader, $this->logger); + $this->asyncPool = new AsyncPool($poolSize, max(-1, (int) $this->configGroup->getProperty("memory.async-worker-hard-limit", 256)), $this->autoloader, $this->logger); $netCompressionThreshold = -1; - if($this->getProperty("network.batch-threshold", 256) >= 0){ - $netCompressionThreshold = (int) $this->getProperty("network.batch-threshold", 256); + if($this->configGroup->getProperty("network.batch-threshold", 256) >= 0){ + $netCompressionThreshold = (int) $this->configGroup->getProperty("network.batch-threshold", 256); } - $netCompressionLevel = (int) $this->getProperty("network.compression-level", 7); + $netCompressionLevel = (int) $this->configGroup->getProperty("network.compression-level", 7); if($netCompressionLevel < 1 or $netCompressionLevel > 9){ $this->logger->warning("Invalid network compression level $netCompressionLevel set, setting to default 7"); $netCompressionLevel = 7; } ZlibCompressor::setInstance(new ZlibCompressor($netCompressionLevel, $netCompressionThreshold, ZlibCompressor::DEFAULT_MAX_DECOMPRESSION_SIZE)); - $this->networkCompressionAsync = (bool) $this->getProperty("network.async-compression", true); + $this->networkCompressionAsync = (bool) $this->configGroup->getProperty("network.async-compression", true); - NetworkCipher::$ENABLED = (bool) $this->getProperty("network.enable-encryption", true); + NetworkCipher::$ENABLED = (bool) $this->configGroup->getProperty("network.enable-encryption", true); - $this->doTitleTick = ((bool) $this->getProperty("console.title-tick", true)) && Terminal::hasFormattingCodes(); + $this->doTitleTick = ((bool) $this->configGroup->getProperty("console.title-tick", true)) && Terminal::hasFormattingCodes(); $this->operators = new Config($this->dataPath . "ops.txt", Config::ENUM); $this->whitelist = new Config($this->dataPath . "white-list.txt", Config::ENUM); @@ -946,9 +873,9 @@ class Server{ $this->banByIP = new BanList($this->dataPath . "banned-ips.txt"); $this->banByIP->load(); - $this->maxPlayers = $this->getConfigInt("max-players", 20); + $this->maxPlayers = $this->configGroup->getConfigInt("max-players", 20); - $this->onlineMode = $this->getConfigBool("xbox-auth", true); + $this->onlineMode = $this->configGroup->getConfigBool("xbox-auth", true); if($this->onlineMode){ $this->logger->notice($this->getLanguage()->translateString("pocketmine.server.auth.enabled")); $this->logger->notice($this->getLanguage()->translateString("pocketmine.server.authProperty.enabled")); @@ -958,8 +885,8 @@ class Server{ $this->logger->warning($this->getLanguage()->translateString("pocketmine.server.authProperty.disabled")); } - if($this->getConfigBool("hardcore", false) and $this->getDifficulty() < World::DIFFICULTY_HARD){ - $this->setConfigInt("difficulty", World::DIFFICULTY_HARD); + if($this->configGroup->getConfigBool("hardcore", false) and $this->getDifficulty() < World::DIFFICULTY_HARD){ + $this->configGroup->setConfigInt("difficulty", World::DIFFICULTY_HARD); } @cli_set_process_title($this->getName() . " " . $this->getPocketMineVersion()); @@ -980,8 +907,8 @@ class Server{ $this->logger->info($this->getLanguage()->translateString("pocketmine.server.license", [$this->getName()])); Timings::init(); - TimingsHandler::setEnabled((bool) $this->getProperty("settings.enable-profiling", false)); - $this->profilingTickRate = (float) $this->getProperty("settings.profile-report-trigger", 20); + TimingsHandler::setEnabled((bool) $this->configGroup->getProperty("settings.enable-profiling", false)); + $this->profilingTickRate = (float) $this->configGroup->getProperty("settings.profile-report-trigger", 20); $this->commandMap = new SimpleCommandMap($this); @@ -1004,13 +931,13 @@ class Server{ $this->forceShutdown(); return; } - $this->pluginManager = new PluginManager($this, ((bool) $this->getProperty("plugins.legacy-data-dir", true)) ? null : $this->getDataPath() . "plugin_data" . DIRECTORY_SEPARATOR, $pluginGraylist); + $this->pluginManager = new PluginManager($this, ((bool) $this->configGroup->getProperty("plugins.legacy-data-dir", true)) ? null : $this->getDataPath() . "plugin_data" . DIRECTORY_SEPARATOR, $pluginGraylist); $this->pluginManager->registerInterface(new PharPluginLoader($this->autoloader)); $this->pluginManager->registerInterface(new ScriptPluginLoader()); $providerManager = WorldProviderManager::getInstance(); if( - ($format = $providerManager->getProviderByName($formatName = (string) $this->getProperty("level-settings.default-format"))) !== null and + ($format = $providerManager->getProviderByName($formatName = (string) $this->configGroup->getProperty("level-settings.default-format"))) !== null and is_a($format, WritableWorldProvider::class, true) ){ $providerManager->setDefault($format); @@ -1019,10 +946,10 @@ class Server{ } $this->worldManager = new WorldManager($this, $this->dataPath . "/worlds"); - $this->worldManager->setAutoSave($this->getConfigBool("auto-save", $this->worldManager->getAutoSave())); - $this->worldManager->setAutoSaveInterval((int) $this->getProperty("ticks-per.autosave", 6000)); + $this->worldManager->setAutoSave($this->configGroup->getConfigBool("auto-save", $this->worldManager->getAutoSave())); + $this->worldManager->setAutoSaveInterval((int) $this->configGroup->getProperty("ticks-per.autosave", 6000)); - $this->updater = new AutoUpdater($this, $this->getProperty("auto-updater.host", "update.pmmp.io")); + $this->updater = new AutoUpdater($this, $this->configGroup->getProperty("auto-updater.host", "update.pmmp.io")); $this->queryInfo = new QueryInfo($this); @@ -1031,7 +958,7 @@ class Server{ $this->pluginManager->loadPlugins($this->pluginPath); $this->enablePlugins(PluginLoadOrder::STARTUP()); - foreach((array) $this->getProperty("worlds", []) as $name => $options){ + foreach((array) $this->configGroup->getProperty("worlds", []) as $name => $options){ if($options === null){ $options = []; }elseif(!is_array($options)){ @@ -1053,18 +980,18 @@ class Server{ } if($this->worldManager->getDefaultWorld() === null){ - $default = $this->getConfigString("level-name", "world"); + $default = $this->configGroup->getConfigString("level-name", "world"); if(trim($default) == ""){ $this->getLogger()->warning("level-name cannot be null, using default"); $default = "world"; - $this->setConfigString("level-name", "world"); + $this->configGroup->setConfigString("level-name", "world"); } if(!$this->worldManager->loadWorld($default, true)){ $this->worldManager->generateWorld( $default, - Generator::convertSeed($this->getConfigString("level-seed")), - GeneratorManager::getInstance()->getGenerator($this->getConfigString("level-type")), - ["preset" => $this->getConfigString("generator-settings")] + Generator::convertSeed($this->configGroup->getConfigString("level-seed")), + GeneratorManager::getInstance()->getGenerator($this->configGroup->getConfigString("level-type")), + ["preset" => $this->configGroup->getConfigString("generator-settings")] ); } @@ -1083,7 +1010,7 @@ class Server{ $this->network->registerInterface(new RakLibInterface($this)); $this->logger->info($this->getLanguage()->translateString("pocketmine.server.networkStart", [$this->getIp(), $this->getPort()])); - if($this->getConfigBool("enable-query", true)){ + if($this->configGroup->getConfigBool("enable-query", true)){ $this->network->registerRawPacketHandler(new QueryHandler($this)); } @@ -1091,7 +1018,7 @@ class Server{ $this->network->blockAddress($entry->getName(), -1); } - if((bool) $this->getProperty("network.upnp-forwarding", false)){ + if((bool) $this->configGroup->getProperty("network.upnp-forwarding", false)){ try{ $this->network->registerInterface(new UPnP($this->logger, Internet::getInternalIP(), $this->getPort())); }catch(\RuntimeException $e){ @@ -1099,14 +1026,12 @@ class Server{ } } - if((bool) $this->getProperty("settings.send-usage", true)){ + if((bool) $this->configGroup->getProperty("settings.send-usage", true)){ $this->sendUsageTicker = 6000; $this->sendUsage(SendUsageTask::TYPE_OPEN); } - if($this->properties->hasChanged()){ - $this->properties->save(); - } + $this->configGroup->save(); $this->logger->info($this->getLanguage()->translateString("pocketmine.server.defaultGameMode", [$this->getGamemode()->getTranslationKey()])); $this->logger->info($this->getLanguage()->translateString("pocketmine.server.donate", [TextFormat::AQUA . "https://patreon.com/pocketminemp" . TextFormat::RESET])); @@ -1380,7 +1305,7 @@ class Server{ } if($this->network instanceof Network){ - $this->network->getSessionManager()->close($this->getProperty("settings.shutdown-message", "Server closed")); + $this->network->getSessionManager()->close($this->configGroup->getProperty("settings.shutdown-message", "Server closed")); } if($this->worldManager instanceof WorldManager){ @@ -1398,9 +1323,9 @@ class Server{ $this->asyncPool->shutdown(); } - if($this->properties !== null and $this->properties->hasChanged()){ + if($this->configGroup !== null){ $this->getLogger()->debug("Saving properties"); - $this->properties->save(); + $this->configGroup->save(); } if($this->console instanceof CommandReader){ @@ -1485,7 +1410,7 @@ class Server{ $this->logger->emergency($this->getLanguage()->translateString("pocketmine.crash.submit", [$dump->getPath()])); - if($this->getProperty("auto-report.enabled", true) !== false){ + if($this->configGroup->getProperty("auto-report.enabled", true) !== false){ $report = true; $stamp = $this->getDataPath() . "crashdumps/.last_crash"; @@ -1514,7 +1439,7 @@ class Server{ } if($report){ - $url = ((bool) $this->getProperty("auto-report.use-https", true) ? "https" : "http") . "://" . $this->getProperty("auto-report.host", "crash.pmmp.io") . "/submit/api"; + $url = ((bool) $this->configGroup->getProperty("auto-report.use-https", true) ? "https" : "http") . "://" . $this->configGroup->getProperty("auto-report.host", "crash.pmmp.io") . "/submit/api"; $reply = Internet::postURL($url, [ "report" => "yes", "name" => $this->getName() . " " . $this->getPocketMineVersion(), @@ -1593,7 +1518,7 @@ class Server{ } public function sendUsage(int $type = SendUsageTask::TYPE_STATUS) : void{ - if((bool) $this->getProperty("anonymous-statistics.enabled", true)){ + if((bool) $this->configGroup->getProperty("anonymous-statistics.enabled", true)){ $this->asyncPool->submitTask(new SendUsageTask($this, $type, $this->uniquePlayers)); } $this->uniquePlayers = []; diff --git a/src/ServerConfigGroup.php b/src/ServerConfigGroup.php new file mode 100644 index 0000000000..88d2bc441d --- /dev/null +++ b/src/ServerConfigGroup.php @@ -0,0 +1,128 @@ + + */ + private $propertyCache = []; + + public function __construct(Config $pocketmineYml, Config $serverProperties){ + $this->pocketmineYml = $pocketmineYml; + $this->serverProperties = $serverProperties; + } + + /** + * @param mixed $defaultValue + * + * @return mixed + */ + public function getProperty(string $variable, $defaultValue = null){ + if(!array_key_exists($variable, $this->propertyCache)){ + $v = getopt("", ["$variable::"]); + if(isset($v[$variable])){ + $this->propertyCache[$variable] = $v[$variable]; + }else{ + $this->propertyCache[$variable] = $this->pocketmineYml->getNested($variable); + } + } + + return $this->propertyCache[$variable] ?? $defaultValue; + } + + public function getConfigString(string $variable, string $defaultValue = "") : string{ + $v = getopt("", ["$variable::"]); + if(isset($v[$variable])){ + return (string) $v[$variable]; + } + + return $this->serverProperties->exists($variable) ? (string) $this->serverProperties->get($variable) : $defaultValue; + } + + public function setConfigString(string $variable, string $value) : void{ + $this->serverProperties->set($variable, $value); + } + + public function getConfigInt(string $variable, int $defaultValue = 0) : int{ + $v = getopt("", ["$variable::"]); + if(isset($v[$variable])){ + return (int) $v[$variable]; + } + + return $this->serverProperties->exists($variable) ? (int) $this->serverProperties->get($variable) : $defaultValue; + } + + public function setConfigInt(string $variable, int $value) : void{ + $this->serverProperties->set($variable, $value); + } + + public function getConfigBool(string $variable, bool $defaultValue = false) : bool{ + $v = getopt("", ["$variable::"]); + if(isset($v[$variable])){ + $value = $v[$variable]; + }else{ + $value = $this->serverProperties->exists($variable) ? $this->serverProperties->get($variable) : $defaultValue; + } + + if(is_bool($value)){ + return $value; + } + switch(strtolower($value)){ + case "on": + case "true": + case "1": + case "yes": + return true; + } + + return false; + } + + public function setConfigBool(string $variable, bool $value) : void{ + $this->serverProperties->set($variable, $value ? "1" : "0"); + } + + public function save() : void{ + if($this->serverProperties->hasChanged()){ + $this->serverProperties->save(); + } + if($this->pocketmineYml->hasChanged()){ + $this->pocketmineYml->save(); + } + } +} diff --git a/src/command/defaults/DefaultGamemodeCommand.php b/src/command/defaults/DefaultGamemodeCommand.php index 6e3957ce9b..33f5b16866 100644 --- a/src/command/defaults/DefaultGamemodeCommand.php +++ b/src/command/defaults/DefaultGamemodeCommand.php @@ -56,7 +56,7 @@ class DefaultGamemodeCommand extends VanillaCommand{ return true; } - $sender->getServer()->setConfigInt("gamemode", $gameMode->getMagicNumber()); + $sender->getServer()->getConfigGroup()->setConfigInt("gamemode", $gameMode->getMagicNumber()); $sender->sendMessage(new TranslationContainer("commands.defaultgamemode.success", [$gameMode->getTranslationKey()])); return true; } diff --git a/src/command/defaults/DifficultyCommand.php b/src/command/defaults/DifficultyCommand.php index 9b2bbd6027..1f05070a33 100644 --- a/src/command/defaults/DifficultyCommand.php +++ b/src/command/defaults/DifficultyCommand.php @@ -57,7 +57,7 @@ class DifficultyCommand extends VanillaCommand{ } if($difficulty !== -1){ - $sender->getServer()->setConfigInt("difficulty", $difficulty); + $sender->getServer()->getConfigGroup()->setConfigInt("difficulty", $difficulty); //TODO: add per-world support foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){ diff --git a/src/command/defaults/TimingsCommand.php b/src/command/defaults/TimingsCommand.php index e42b44b040..cdaa5c312f 100644 --- a/src/command/defaults/TimingsCommand.php +++ b/src/command/defaults/TimingsCommand.php @@ -119,7 +119,7 @@ class TimingsCommand extends VanillaCommand{ ]; fclose($fileTimings); - $host = $sender->getServer()->getProperty("timings.host", "timings.pmmp.io"); + $host = $sender->getServer()->getConfigGroup()->getProperty("timings.host", "timings.pmmp.io"); $sender->getServer()->getAsyncPool()->submitTask(new class($sender, $host, $agent, $data) extends BulkCurlTask{ private const TLS_KEY_SENDER = "sender"; diff --git a/src/command/defaults/WhitelistCommand.php b/src/command/defaults/WhitelistCommand.php index e53c741646..6b80cfe4c0 100644 --- a/src/command/defaults/WhitelistCommand.php +++ b/src/command/defaults/WhitelistCommand.php @@ -64,12 +64,12 @@ class WhitelistCommand extends VanillaCommand{ return true; case "on": - $sender->getServer()->setConfigBool("white-list", true); + $sender->getServer()->getConfigGroup()->setConfigBool("white-list", true); Command::broadcastCommandMessage($sender, new TranslationContainer("commands.whitelist.enabled")); return true; case "off": - $sender->getServer()->setConfigBool("white-list", false); + $sender->getServer()->getConfigGroup()->setConfigBool("white-list", false); Command::broadcastCommandMessage($sender, new TranslationContainer("commands.whitelist.disabled")); return true; diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index c99cf1f962..2e1de979e9 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -97,7 +97,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ $threadToMainBuffer, new InternetAddress($this->server->getIp(), $this->server->getPort(), 4), $this->rakServerId, - (int) $this->server->getProperty("network.max-mtu-size", 1492), + (int) $this->server->getConfigGroup()->getProperty("network.max-mtu-size", 1492), self::MCPE_RAKNET_PROTOCOL_VERSION, $this->sleeper ); diff --git a/src/network/query/QueryInfo.php b/src/network/query/QueryInfo.php index 975bfa7149..9b015004af 100644 --- a/src/network/query/QueryInfo.php +++ b/src/network/query/QueryInfo.php @@ -76,7 +76,7 @@ final class QueryInfo{ public function __construct(Server $server){ $this->serverName = $server->getMotd(); - $this->listPlugins = $server->getProperty("settings.query-plugins", true); + $this->listPlugins = $server->getConfigGroup()->getProperty("settings.query-plugins", true); $this->plugins = $server->getPluginManager()->getPlugins(); $this->players = $server->getOnlinePlayers(); diff --git a/src/player/Player.php b/src/player/Player.php index defd369b64..206a31f589 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -269,8 +269,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->xuid = $this->playerInfo->getXuid(); $this->perm = new PermissibleBase($this); - $this->chunksPerTick = (int) $this->server->getProperty("chunk-sending.per-tick", 4); - $this->spawnThreshold = (int) (($this->server->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); + $this->chunksPerTick = (int) $this->server->getConfigGroup()->getProperty("chunk-sending.per-tick", 4); + $this->spawnThreshold = (int) (($this->server->getConfigGroup()->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); $namedtag = $this->server->getOfflinePlayerData($this->username); //TODO: make this async @@ -556,7 +556,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, public function setViewDistance(int $distance) : void{ $this->viewDistance = $this->server->getAllowedViewDistance($distance); - $this->spawnThreshold = (int) (min($this->viewDistance, $this->server->getProperty("chunk-sending.spawn-radius", 4)) ** 2 * M_PI); + $this->spawnThreshold = (int) (min($this->viewDistance, $this->server->getConfigGroup()->getProperty("chunk-sending.spawn-radius", 4)) ** 2 * M_PI); $this->nextChunkOrderRun = 0; @@ -836,7 +836,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->spawnToAll(); - if($this->server->getUpdater()->hasUpdate() and $this->hasPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE) and $this->server->getProperty("auto-updater.on-update.warn-ops", true)){ + if($this->server->getUpdater()->hasUpdate() and $this->hasPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE) and $this->server->getConfigGroup()->getProperty("auto-updater.on-update.warn-ops", true)){ $this->server->getUpdater()->showPlayerUpdate($this); } @@ -1675,7 +1675,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $oldItem = clone $heldItem; $ev = new EntityDamageByEntityEvent($this, $entity, EntityDamageEvent::CAUSE_ENTITY_ATTACK, $heldItem->getAttackPoints()); - if(!$this->canInteract($entity->getLocation(), 8) or ($entity instanceof Player and !$this->server->getConfigBool("pvp"))){ + if(!$this->canInteract($entity->getLocation(), 8) or ($entity instanceof Player and !$this->server->getConfigGroup()->getConfigBool("pvp"))){ $ev->setCancelled(); } diff --git a/src/stats/SendUsageTask.php b/src/stats/SendUsageTask.php index d68f506080..3fb0ff207b 100644 --- a/src/stats/SendUsageTask.php +++ b/src/stats/SendUsageTask.php @@ -60,7 +60,7 @@ class SendUsageTask extends AsyncTask{ * @phpstan-param array $playerList */ public function __construct(Server $server, int $type, array $playerList = []){ - $endpoint = "http://" . $server->getProperty("anonymous-statistics.host", "stats.pocketmine.net") . "/"; + $endpoint = "http://" . $server->getConfigGroup()->getProperty("anonymous-statistics.host", "stats.pocketmine.net") . "/"; $data = []; $data["uniqueServerId"] = $server->getServerUniqueId()->toString(); diff --git a/src/updater/AutoUpdater.php b/src/updater/AutoUpdater.php index 02e998919c..5c987ad69b 100644 --- a/src/updater/AutoUpdater.php +++ b/src/updater/AutoUpdater.php @@ -57,7 +57,7 @@ class AutoUpdater{ $this->logger = new \PrefixedLogger($server->getLogger(), "Auto Updater"); $this->endpoint = "http://$endpoint/api/"; - if((bool) $server->getProperty("auto-updater.enabled", true)){ + if((bool) $server->getConfigGroup()->getProperty("auto-updater.enabled", true)){ $this->doCheck(); } } @@ -77,7 +77,7 @@ class AutoUpdater{ $this->checkUpdate(); if($this->hasUpdate()){ (new UpdateNotifyEvent($this))->call(); - if((bool) $this->server->getProperty("auto-updater.on-update.warn-console", true)){ + if((bool) $this->server->getConfigGroup()->getProperty("auto-updater.on-update.warn-console", true)){ $this->showConsoleUpdate(); } }else{ @@ -187,7 +187,7 @@ class AutoUpdater{ * Returns the channel used for update checking (stable, beta, dev) */ public function getChannel() : string{ - $channel = strtolower($this->server->getProperty("auto-updater.preferred-channel", "stable")); + $channel = strtolower($this->server->getConfigGroup()->getProperty("auto-updater.preferred-channel", "stable")); if($channel !== "stable" and $channel !== "beta" and $channel !== "alpha" and $channel !== "development"){ $channel = "stable"; } diff --git a/src/world/World.php b/src/world/World.php index 3d46df649b..0c1e6d15ed 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -347,12 +347,13 @@ class World implements ChunkManager{ $this->time = $this->provider->getWorldData()->getTime(); - $this->chunkTickRadius = min($this->server->getViewDistance(), max(1, (int) $this->server->getProperty("chunk-ticking.tick-radius", 4))); - $this->chunksPerTick = (int) $this->server->getProperty("chunk-ticking.per-tick", 40); - $this->tickedBlocksPerSubchunkPerTick = (int) $this->server->getProperty("chunk-ticking.blocks-per-subchunk-per-tick", self::DEFAULT_TICKED_BLOCKS_PER_SUBCHUNK_PER_TICK); - $this->chunkPopulationQueueSize = (int) $this->server->getProperty("chunk-generation.population-queue-size", 2); + $cfg = $this->server->getConfigGroup(); + $this->chunkTickRadius = min($this->server->getViewDistance(), max(1, (int) $cfg->getProperty("chunk-ticking.tick-radius", 4))); + $this->chunksPerTick = (int) $cfg->getProperty("chunk-ticking.per-tick", 40); + $this->tickedBlocksPerSubchunkPerTick = (int) $cfg->getProperty("chunk-ticking.blocks-per-subchunk-per-tick", self::DEFAULT_TICKED_BLOCKS_PER_SUBCHUNK_PER_TICK); + $this->chunkPopulationQueueSize = (int) $cfg->getProperty("chunk-generation.population-queue-size", 2); - $dontTickBlocks = array_fill_keys($this->server->getProperty("chunk-ticking.disable-block-ticking", []), true); + $dontTickBlocks = array_fill_keys($cfg->getProperty("chunk-ticking.disable-block-ticking", []), true); foreach(BlockFactory::getInstance()->getAllKnownStates() as $state){ if(!isset($dontTickBlocks[$state->getId()]) and $state->ticksRandomly()){ diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index 51bbcd87b0..622caf86d7 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -65,16 +65,6 @@ parameters: count: 1 path: ../../../src/Server.php - - - message: "#^Cannot cast array\\\\|string\\|false to string\\.$#" - count: 1 - path: ../../../src/Server.php - - - - message: "#^Cannot cast array\\\\|string\\|false to int\\.$#" - count: 1 - path: ../../../src/Server.php - - message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, string\\|false given\\.$#" count: 1 @@ -90,6 +80,16 @@ parameters: count: 1 path: ../../../src/Server.php + - + message: "#^Cannot cast array\\\\|string\\|false to string\\.$#" + count: 1 + path: ../../../src/ServerConfigGroup.php + + - + message: "#^Cannot cast array\\\\|string\\|false to int\\.$#" + count: 1 + path: ../../../src/ServerConfigGroup.php + - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\format\\\\Chunk\\:\\:setFullBlock\\(\\) expects int, float\\|int given\\.$#" count: 1 From 3473254d01e5012a39bf9f714a6c87d58907c4ab Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 May 2020 16:09:45 +0100 Subject: [PATCH 1613/3224] added Timings::INCLUDED_BY_OTHER_TIMINGS constant --- src/command/Command.php | 3 ++- src/timings/Timings.php | 42 ++++++++++++++++++++------------------ src/world/WorldTimings.php | 30 +++++++++++++-------------- 3 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/command/Command.php b/src/command/Command.php index 408fdd9db0..4e8f93ecaf 100644 --- a/src/command/Command.php +++ b/src/command/Command.php @@ -30,6 +30,7 @@ use pocketmine\command\utils\CommandException; use pocketmine\lang\TranslationContainer; use pocketmine\permission\PermissionManager; use pocketmine\Server; +use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; use pocketmine\utils\TextFormat; use function explode; @@ -139,7 +140,7 @@ abstract class Command{ if($this->timings instanceof TimingsHandler){ $this->timings->remove(); } - $this->timings = new TimingsHandler("** Command: " . $name); + $this->timings = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Command: " . $name); $this->label = $name; return true; diff --git a/src/timings/Timings.php b/src/timings/Timings.php index 85835f5af4..0c74a9e54d 100644 --- a/src/timings/Timings.php +++ b/src/timings/Timings.php @@ -32,6 +32,8 @@ use pocketmine\scheduler\TaskHandler; use function dechex; abstract class Timings{ + public const INCLUDED_BY_OTHER_TIMINGS_PREFIX = "** "; + /** @var bool */ private static $initialized = false; @@ -121,18 +123,18 @@ abstract class Timings{ self::$initialized = true; self::$fullTickTimer = new TimingsHandler("Full Server Tick"); - self::$serverTickTimer = new TimingsHandler("** Full Server Tick", self::$fullTickTimer); + self::$serverTickTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Full Server Tick", self::$fullTickTimer); self::$memoryManagerTimer = new TimingsHandler("Memory Manager"); self::$garbageCollectorTimer = new TimingsHandler("Garbage Collector", self::$memoryManagerTimer); self::$titleTickTimer = new TimingsHandler("Console Title Tick"); self::$playerNetworkSendTimer = new TimingsHandler("Player Network Send"); - self::$playerNetworkSendCompressTimer = new TimingsHandler("** Player Network Send - Compression", self::$playerNetworkSendTimer); - self::$playerNetworkSendEncryptTimer = new TimingsHandler("** Player Network Send - Encryption", self::$playerNetworkSendTimer); + self::$playerNetworkSendCompressTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Player Network Send - Compression", self::$playerNetworkSendTimer); + self::$playerNetworkSendEncryptTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Player Network Send - Encryption", self::$playerNetworkSendTimer); self::$playerNetworkReceiveTimer = new TimingsHandler("Player Network Receive"); - self::$playerNetworkReceiveDecompressTimer = new TimingsHandler("** Player Network Receive - Decompression", self::$playerNetworkReceiveTimer); - self::$playerNetworkReceiveDecryptTimer = new TimingsHandler("** Player Network Receive - Decryption", self::$playerNetworkReceiveTimer); + self::$playerNetworkReceiveDecompressTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Player Network Receive - Decompression", self::$playerNetworkReceiveTimer); + self::$playerNetworkReceiveDecryptTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Player Network Receive - Decryption", self::$playerNetworkReceiveTimer); self::$playerChunkOrderTimer = new TimingsHandler("Player Order Chunks"); self::$playerChunkSendTimer = new TimingsHandler("Player Send Chunks"); @@ -145,19 +147,19 @@ abstract class Timings{ self::$permissibleCalculationTimer = new TimingsHandler("Permissible Calculation"); self::$permissionDefaultTimer = new TimingsHandler("Default Permission Calculation"); - self::$entityMoveTimer = new TimingsHandler("** entityMove"); - self::$playerCheckNearEntitiesTimer = new TimingsHandler("** checkNearEntities"); - self::$tickEntityTimer = new TimingsHandler("** tickEntity"); - self::$tickTileEntityTimer = new TimingsHandler("** tickTileEntity"); + self::$entityMoveTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "entityMove"); + self::$playerCheckNearEntitiesTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "checkNearEntities"); + self::$tickEntityTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "tickEntity"); + self::$tickTileEntityTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "tickTileEntity"); - self::$timerEntityBaseTick = new TimingsHandler("** entityBaseTick"); - self::$timerLivingEntityBaseTick = new TimingsHandler("** livingEntityBaseTick"); + self::$timerEntityBaseTick = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "entityBaseTick"); + self::$timerLivingEntityBaseTick = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "livingEntityBaseTick"); - self::$schedulerSyncTimer = new TimingsHandler("** Scheduler - Sync Tasks"); - self::$schedulerAsyncTimer = new TimingsHandler("** Scheduler - Async Tasks"); + self::$schedulerSyncTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Scheduler - Sync Tasks"); + self::$schedulerAsyncTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Scheduler - Async Tasks"); - self::$playerCommandTimer = new TimingsHandler("** playerCommand"); - self::$craftingDataCacheRebuildTimer = new TimingsHandler("** craftingDataCacheRebuild"); + self::$playerCommandTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "playerCommand"); + self::$craftingDataCacheRebuildTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "craftingDataCacheRebuild"); } @@ -181,9 +183,9 @@ abstract class Timings{ $entityType = (new \ReflectionClass($entity))->getShortName(); if(!isset(self::$entityTypeTimingMap[$entityType])){ if($entity instanceof Player){ - self::$entityTypeTimingMap[$entityType] = new TimingsHandler("** tickEntity - EntityPlayer", self::$tickEntityTimer); + self::$entityTypeTimingMap[$entityType] = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "tickEntity - EntityPlayer", self::$tickEntityTimer); }else{ - self::$entityTypeTimingMap[$entityType] = new TimingsHandler("** tickEntity - " . $entityType, self::$tickEntityTimer); + self::$entityTypeTimingMap[$entityType] = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "tickEntity - " . $entityType, self::$tickEntityTimer); } } @@ -193,7 +195,7 @@ abstract class Timings{ public static function getTileEntityTimings(Tile $tile) : TimingsHandler{ $tileType = (new \ReflectionClass($tile))->getShortName(); if(!isset(self::$tileEntityTypeTimingMap[$tileType])){ - self::$tileEntityTypeTimingMap[$tileType] = new TimingsHandler("** tickTileEntity - " . $tileType, self::$tickTileEntityTimer); + self::$tileEntityTypeTimingMap[$tileType] = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "tickTileEntity - " . $tileType, self::$tickTileEntityTimer); } return self::$tileEntityTypeTimingMap[$tileType]; @@ -203,7 +205,7 @@ abstract class Timings{ $pid = $pk->pid(); if(!isset(self::$packetReceiveTimingMap[$pid])){ $pkName = (new \ReflectionClass($pk))->getShortName(); - self::$packetReceiveTimingMap[$pid] = new TimingsHandler("** receivePacket - " . $pkName . " [0x" . dechex($pid) . "]", self::$playerNetworkReceiveTimer); + self::$packetReceiveTimingMap[$pid] = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "receivePacket - " . $pkName . " [0x" . dechex($pid) . "]", self::$playerNetworkReceiveTimer); } return self::$packetReceiveTimingMap[$pid]; @@ -213,7 +215,7 @@ abstract class Timings{ $pid = $pk->pid(); if(!isset(self::$packetSendTimingMap[$pid])){ $pkName = (new \ReflectionClass($pk))->getShortName(); - self::$packetSendTimingMap[$pid] = new TimingsHandler("** sendPacket - " . $pkName . " [0x" . dechex($pid) . "]", self::$playerNetworkSendTimer); + self::$packetSendTimingMap[$pid] = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "sendPacket - " . $pkName . " [0x" . dechex($pid) . "]", self::$playerNetworkSendTimer); } return self::$packetSendTimingMap[$pid]; diff --git a/src/world/WorldTimings.php b/src/world/WorldTimings.php index ab8c2d30c5..a921cb8f5e 100644 --- a/src/world/WorldTimings.php +++ b/src/world/WorldTimings.php @@ -67,26 +67,26 @@ class WorldTimings{ public function __construct(World $world){ $name = $world->getFolderName() . " - "; - $this->setBlock = new TimingsHandler("** " . $name . "setBlock"); - $this->doBlockLightUpdates = new TimingsHandler("** " . $name . "doBlockLightUpdates"); - $this->doBlockSkyLightUpdates = new TimingsHandler("** " . $name . "doBlockSkyLightUpdates"); + $this->setBlock = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "setBlock"); + $this->doBlockLightUpdates = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "doBlockLightUpdates"); + $this->doBlockSkyLightUpdates = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "doBlockSkyLightUpdates"); - $this->doChunkUnload = new TimingsHandler("** " . $name . "doChunkUnload"); - $this->doTickPending = new TimingsHandler("** " . $name . "doTickPending"); - $this->doTickTiles = new TimingsHandler("** " . $name . "doTickTiles"); - $this->doChunkGC = new TimingsHandler("** " . $name . "doChunkGC"); - $this->entityTick = new TimingsHandler("** " . $name . "entityTick"); + $this->doChunkUnload = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "doChunkUnload"); + $this->doTickPending = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "doTickPending"); + $this->doTickTiles = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "doTickTiles"); + $this->doChunkGC = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "doChunkGC"); + $this->entityTick = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "entityTick"); - $this->syncChunkSendTimer = new TimingsHandler("** " . $name . "syncChunkSend"); - $this->syncChunkSendPrepareTimer = new TimingsHandler("** " . $name . "syncChunkSendPrepare"); + $this->syncChunkSendTimer = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "syncChunkSend"); + $this->syncChunkSendPrepareTimer = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "syncChunkSendPrepare"); - $this->syncChunkLoadTimer = new TimingsHandler("** " . $name . "syncChunkLoad"); - $this->syncChunkLoadDataTimer = new TimingsHandler("** " . $name . "syncChunkLoad - Data"); - $this->syncChunkLoadEntitiesTimer = new TimingsHandler("** " . $name . "syncChunkLoad - Entities"); - $this->syncChunkLoadTileEntitiesTimer = new TimingsHandler("** " . $name . "syncChunkLoad - TileEntities"); + $this->syncChunkLoadTimer = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "syncChunkLoad"); + $this->syncChunkLoadDataTimer = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "syncChunkLoad - Data"); + $this->syncChunkLoadEntitiesTimer = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "syncChunkLoad - Entities"); + $this->syncChunkLoadTileEntitiesTimer = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "syncChunkLoad - TileEntities"); Timings::init(); //make sure the timer we want is available - $this->syncChunkSaveTimer = new TimingsHandler("** " . $name . "syncChunkSave", Timings::$worldSaveTimer); + $this->syncChunkSaveTimer = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "syncChunkSave", Timings::$worldSaveTimer); $this->doTick = new TimingsHandler($name . "doTick"); } From 41566e8077d5a8738fa779a4974a7aab43a127d0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 May 2020 18:33:04 +0100 Subject: [PATCH 1614/3224] Server: remove unused BOOTUP_RANDOM constant this used to be used for /dumpmemory filenames, but those were confusing and stupid, and it's not used anymore since March 2018. --- src/Server.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Server.php b/src/Server.php index cdf1c0f9c5..aa5a073fbd 100644 --- a/src/Server.php +++ b/src/Server.php @@ -105,7 +105,6 @@ use function base64_encode; use function cli_set_process_title; use function copy; use function count; -use function define; use function explode; use function file_exists; use function file_get_contents; @@ -125,7 +124,6 @@ use function min; use function mkdir; use function ob_end_flush; use function preg_replace; -use function random_bytes; use function realpath; use function register_shutdown_function; use function rename; @@ -891,7 +889,6 @@ class Server{ @cli_set_process_title($this->getName() . " " . $this->getPocketMineVersion()); - define("BOOTUP_RANDOM", random_bytes(16)); $this->serverID = Utils::getMachineUniqueId($this->getIp() . $this->getPort()); $this->getLogger()->debug("Server unique id: " . $this->getServerUniqueId()); From 63d622a3cc8005068c07aa5c923e626b99443aed Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 May 2020 18:37:09 +0100 Subject: [PATCH 1615/3224] Remove GlobalConstants the constants described in this file are now provided by pocketmine\utils\Limits in the BinaryUtils dependency. --- composer.json | 1 - src/GlobalConstants.php | 32 -------------------------------- 2 files changed, 33 deletions(-) delete mode 100644 src/GlobalConstants.php diff --git a/composer.json b/composer.json index 5b77fda8c2..684d78d14e 100644 --- a/composer.json +++ b/composer.json @@ -61,7 +61,6 @@ }, "files": [ "src/CoreConstants.php", - "src/GlobalConstants.php", "src/VersionInfo.php" ] }, diff --git a/src/GlobalConstants.php b/src/GlobalConstants.php deleted file mode 100644 index e32d07c040..0000000000 --- a/src/GlobalConstants.php +++ /dev/null @@ -1,32 +0,0 @@ - Date: Sun, 24 May 2020 18:59:43 +0100 Subject: [PATCH 1616/3224] Player: make selectChunks() non-dependent on the player's current view distance & location --- src/player/Player.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 206a31f589..fefe43fb14 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -848,13 +848,9 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** * @return \Generator */ - protected function selectChunks() : \Generator{ - $radius = $this->server->getAllowedViewDistance($this->viewDistance); + protected function selectChunks(int $radius, int $centerX, int $centerZ) : \Generator{ $radiusSquared = $radius ** 2; - $centerX = $this->location->getFloorX() >> 4; - $centerZ = $this->location->getFloorZ() >> 4; - for($x = 0; $x < $radius; ++$x){ for($z = 0; $z <= $x; ++$z){ if(($x ** 2 + $z ** 2) > $radiusSquared){ @@ -896,7 +892,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $newOrder = []; $unloadChunks = $this->usedChunks; - foreach($this->selectChunks() as $hash){ + foreach($this->selectChunks( + $this->server->getAllowedViewDistance($this->viewDistance), + $this->location->getFloorX() >> 4, + $this->location->getFloorZ() >> 4 + ) as $hash){ if(!isset($this->usedChunks[$hash]) or $this->usedChunks[$hash]->equals(UsedChunkStatus::NEEDED())){ $newOrder[$hash] = true; } From 437e4d75abeffaef70468c71a0b0d294eeb4c581 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 May 2020 19:16:57 +0100 Subject: [PATCH 1617/3224] WorldProviderManager: use $this-> instead of self:: --- src/world/format/io/WorldProviderManager.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/world/format/io/WorldProviderManager.php b/src/world/format/io/WorldProviderManager.php index 1232935995..ed1d7a5297 100644 --- a/src/world/format/io/WorldProviderManager.php +++ b/src/world/format/io/WorldProviderManager.php @@ -48,10 +48,10 @@ final class WorldProviderManager{ private $default = LevelDB::class; public function __construct(){ - self::addProvider(Anvil::class, "anvil"); - self::addProvider(McRegion::class, "mcregion"); - self::addProvider(PMAnvil::class, "pmanvil"); - self::addProvider(LevelDB::class, "leveldb"); + $this->addProvider(Anvil::class, "anvil"); + $this->addProvider(McRegion::class, "mcregion"); + $this->addProvider(PMAnvil::class, "pmanvil"); + $this->addProvider(LevelDB::class, "leveldb"); } /** From c93038f5740d807d4ea746ecd4c1f3bf67648b16 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 24 May 2020 19:22:04 +0100 Subject: [PATCH 1618/3224] Inject WorldProviderManager to WorldManager's constructor, no longer singleton --- src/Server.php | 4 ++-- src/world/WorldManager.php | 14 +++++++++----- src/world/format/io/WorldProviderManager.php | 3 --- tools/convert-world.php | 5 +++-- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/Server.php b/src/Server.php index aa5a073fbd..4b0db5532b 100644 --- a/src/Server.php +++ b/src/Server.php @@ -932,7 +932,7 @@ class Server{ $this->pluginManager->registerInterface(new PharPluginLoader($this->autoloader)); $this->pluginManager->registerInterface(new ScriptPluginLoader()); - $providerManager = WorldProviderManager::getInstance(); + $providerManager = new WorldProviderManager(); if( ($format = $providerManager->getProviderByName($formatName = (string) $this->configGroup->getProperty("level-settings.default-format"))) !== null and is_a($format, WritableWorldProvider::class, true) @@ -942,7 +942,7 @@ class Server{ $this->logger->warning($this->language->translateString("pocketmine.level.badDefaultFormat", [$formatName])); } - $this->worldManager = new WorldManager($this, $this->dataPath . "/worlds"); + $this->worldManager = new WorldManager($this, $this->dataPath . "/worlds", $providerManager); $this->worldManager->setAutoSave($this->configGroup->getConfigBool("auto-save", $this->worldManager->getAutoSave())); $this->worldManager->setAutoSaveInterval((int) $this->configGroup->getProperty("ticks-per.autosave", 6000)); diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 02f88d8683..79f47b7dd1 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -56,6 +56,9 @@ class WorldManager{ /** @var string */ private $dataPath; + /** @var WorldProviderManager */ + private $providerManager; + /** @var World[] */ private $worlds = []; /** @var World|null */ @@ -72,9 +75,10 @@ class WorldManager{ /** @var int */ private $autoSaveTicker = 0; - public function __construct(Server $server, string $dataPath){ + public function __construct(Server $server, string $dataPath, WorldProviderManager $providerManager){ $this->server = $server; $this->dataPath = $dataPath; + $this->providerManager = $providerManager; } /** @@ -179,7 +183,7 @@ class WorldManager{ $path = $this->getWorldPath($name); - $providers = WorldProviderManager::getInstance()->getMatchingProviders($path); + $providers = $this->providerManager->getMatchingProviders($path); if(count($providers) !== 1){ $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.level.loadError", [ $name, @@ -216,7 +220,7 @@ class WorldManager{ } $this->server->getLogger()->notice("Upgrading world \"$name\" to new format. This may take a while."); - $converter = new FormatConverter($provider, WorldProviderManager::getInstance()->getDefault(), $this->server->getDataPath() . "world_conversion_backups", $this->server->getLogger()); + $converter = new FormatConverter($provider, $this->providerManager->getDefault(), $this->server->getDataPath() . "world_conversion_backups", $this->server->getLogger()); $provider = $converter->execute(); $this->server->getLogger()->notice("Upgraded world \"$name\" to new format successfully. Backed up pre-conversion world at " . $converter->getBackupPath()); @@ -251,7 +255,7 @@ class WorldManager{ Utils::testValidInstance($generator, Generator::class); - $providerClass = WorldProviderManager::getInstance()->getDefault(); + $providerClass = $this->providerManager->getDefault(); $path = $this->getWorldPath($name); /** @var WritableWorldProvider $providerClass */ @@ -307,7 +311,7 @@ class WorldManager{ } $path = $this->getWorldPath($name); if(!($this->getWorldByName($name) instanceof World)){ - return count(WorldProviderManager::getInstance()->getMatchingProviders($path)) > 0; + return count($this->providerManager->getMatchingProviders($path)) > 0; } return true; diff --git a/src/world/format/io/WorldProviderManager.php b/src/world/format/io/WorldProviderManager.php index ed1d7a5297..b2fb0437a9 100644 --- a/src/world/format/io/WorldProviderManager.php +++ b/src/world/format/io/WorldProviderManager.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\world\format\io; -use pocketmine\utils\SingletonTrait; use pocketmine\utils\Utils; use pocketmine\world\format\io\leveldb\LevelDB; use pocketmine\world\format\io\region\Anvil; @@ -33,8 +32,6 @@ use function strtolower; use function trim; final class WorldProviderManager{ - use SingletonTrait; - /** * @var string[] * @phpstan-var array> diff --git a/tools/convert-world.php b/tools/convert-world.php index e524b1b6fa..3884b19939 100644 --- a/tools/convert-world.php +++ b/tools/convert-world.php @@ -28,7 +28,8 @@ use pocketmine\world\format\io\WritableWorldProvider; require_once dirname(__DIR__) . '/vendor/autoload.php'; -$writableFormats = array_filter(WorldProviderManager::getInstance()->getAvailableProviders(), function(string $class){ +$providerManager = new WorldProviderManager(); +$writableFormats = array_filter($providerManager->getAvailableProviders(), function(string $class){ return is_a($class, WritableWorldProvider::class, true); }); $requiredOpts = [ @@ -59,7 +60,7 @@ if((!@mkdir($backupPath, 0777, true) and !is_dir($backupPath)) or !is_writable($ die("Backup file path " . $backupPath . " is not writable (permission error or doesn't exist), aborting"); } -$oldProviderClasses = WorldProviderManager::getInstance()->getMatchingProviders($inputPath); +$oldProviderClasses = $providerManager->getMatchingProviders($inputPath); if(count($oldProviderClasses) === 0){ die("Unknown input world format"); } From 4ce5f2a6c6dfea031bcf004e1393fb27dac6bb43 Mon Sep 17 00:00:00 2001 From: Govdim <50422762+Govdim@users.noreply.github.com> Date: Tue, 26 May 2020 08:59:19 +0300 Subject: [PATCH 1619/3224] WorldManager: Add access to WorldProviderManager (#3527) * WorldProvider: Add access to WorldProviderManager * WorldManager: Updated getProvider method Co-authored-by: Govdim --- src/world/WorldManager.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 79f47b7dd1..57bf4ac6fb 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -81,6 +81,10 @@ class WorldManager{ $this->providerManager = $providerManager; } + public function getProviderManager() : WorldProviderManager{ + return $this->providerManager; + } + /** * @return World[] */ From cc549630e58ec9daefbe1bd2ee4fc1a92bf75b26 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 30 May 2020 22:29:30 +0100 Subject: [PATCH 1620/3224] HandlerListManager: fixed @param doc comment not referring to correct ReflectionClass phpstan doesn't notice this because of the phpstan-param doc directly underneath. --- src/event/HandlerListManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/event/HandlerListManager.php b/src/event/HandlerListManager.php index a9814657b6..0f7867d2f5 100644 --- a/src/event/HandlerListManager.php +++ b/src/event/HandlerListManager.php @@ -57,7 +57,7 @@ class HandlerListManager{ } /** - * @param ReflectionClass $class + * @param \ReflectionClass $class * @phpstan-param \ReflectionClass $class */ private static function isValidClass(\ReflectionClass $class) : bool{ From 7e863545194189ca87cc0ff1b151f0251fbf79d2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 May 2020 14:59:00 +0100 Subject: [PATCH 1621/3224] updated composer lockfile --- composer.lock | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/composer.lock b/composer.lock index 0d00971ba9..ef9f4aa89a 100644 --- a/composer.lock +++ b/composer.lock @@ -552,12 +552,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "6d5af66a6c923bd8fad93258f3a1736091225aa1" + "reference": "9d8a73014725f57cf4bf5cbdb40e340fe4643169" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/6d5af66a6c923bd8fad93258f3a1736091225aa1", - "reference": "6d5af66a6c923bd8fad93258f3a1736091225aa1", + "url": "https://api.github.com/repos/pmmp/Math/zipball/9d8a73014725f57cf4bf5cbdb40e340fe4643169", + "reference": "9d8a73014725f57cf4bf5cbdb40e340fe4643169", "shasum": "" }, "require": { @@ -566,7 +566,7 @@ }, "require-dev": { "irstea/phpunit-shim": "^7.5", - "phpstan/phpstan": "^0.12.8" + "phpstan/phpstan": "^0.12.25" }, "type": "library", "autoload": { @@ -579,7 +579,7 @@ "LGPL-3.0" ], "description": "PHP library containing math related code used in PocketMine-MP", - "time": "2020-05-19T11:19:57+00:00" + "time": "2020-05-19T12:13:12+00:00" }, { "name": "pocketmine/nbt", @@ -811,16 +811,16 @@ }, { "name": "respect/validation", - "version": "2.0.3", + "version": "2.0.8", "source": { "type": "git", "url": "https://github.com/Respect/Validation.git", - "reference": "3463343b14a7fa5ba931f03b5dcb8efcbc0ddf9c" + "reference": "e0fbed32c90b408652bb30803647d90901f612f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Respect/Validation/zipball/3463343b14a7fa5ba931f03b5dcb8efcbc0ddf9c", - "reference": "3463343b14a7fa5ba931f03b5dcb8efcbc0ddf9c", + "url": "https://api.github.com/repos/Respect/Validation/zipball/e0fbed32c90b408652bb30803647d90901f612f1", + "reference": "e0fbed32c90b408652bb30803647d90901f612f1", "shasum": "" }, "require": { @@ -873,7 +873,7 @@ "validation", "validator" ], - "time": "2020-05-13T16:41:55+00:00" + "time": "2020-05-20T13:02:44+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -952,11 +952,11 @@ "packages-dev": [ { "name": "irstea/phpunit-shim", - "version": "8.5.4", + "version": "8.5.5", "source": { "type": "git", "url": "https://gitlab.irstea.fr/pole-is/tools/phpunit-shim.git", - "reference": "25b3ffe1502bfd35d5cd23dc37f2f2e70cdf0b54" + "reference": "5b9425eb62f807517e8c96415b07fd35a65e8e7b" }, "require": { "ext-dom": "*", @@ -1002,7 +1002,7 @@ "testing", "xunit" ], - "time": "2020-04-24T02:20:21+00:00" + "time": "2020-05-24T13:47:48+00:00" }, { "name": "phpstan/phpstan", @@ -1062,21 +1062,21 @@ }, { "name": "phpstan/phpstan-phpunit", - "version": "0.12.8", + "version": "0.12.10", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-phpunit.git", - "reference": "7232c17e2493dc598173da784477ce0afb2c4e0e" + "reference": "74c1c5f00312e23533fdf579aea71a8343dd3e78" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/7232c17e2493dc598173da784477ce0afb2c4e0e", - "reference": "7232c17e2493dc598173da784477ce0afb2c4e0e", + "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/74c1c5f00312e23533fdf579aea71a8343dd3e78", + "reference": "74c1c5f00312e23533fdf579aea71a8343dd3e78", "shasum": "" }, "require": { "php": "~7.1", - "phpstan/phpstan": "^0.12.6" + "phpstan/phpstan": "^0.12.20" }, "conflict": { "phpunit/phpunit": "<7.0" @@ -1088,7 +1088,7 @@ "jakub-onderka/php-parallel-lint": "^1.0", "phing/phing": "^2.16.0", "phpstan/phpstan-strict-rules": "^0.12", - "phpunit/phpunit": "^7.0", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", "satooshi/php-coveralls": "^1.0", "slevomat/coding-standard": "^4.7.2" }, @@ -1114,7 +1114,7 @@ "MIT" ], "description": "PHPUnit extensions and rules for PHPStan", - "time": "2020-04-17T08:04:10+00:00" + "time": "2020-05-31T06:33:59+00:00" }, { "name": "phpstan/phpstan-strict-rules", From 1974afec78d3b95577c3162d3f1a8f38dc64bd9c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 May 2020 15:04:37 +0100 Subject: [PATCH 1622/3224] updated build/php submodule to pmmp/pthreads@653d6856282d9b805d9a390b1905bef70b79d29a --- build/php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/php b/build/php index 8084604600..653d685628 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit 8084604600c6d7490af07d9f1a46a4353e77dc74 +Subproject commit 653d6856282d9b805d9a390b1905bef70b79d29a From 4bf40df770e2e2e268449852e6e16b02fa9a485d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 May 2020 15:10:28 +0100 Subject: [PATCH 1623/3224] tools: added a script to remove garbage from region files --- tools/compact-regions.php | 178 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 tools/compact-regions.php diff --git a/tools/compact-regions.php b/tools/compact-regions.php new file mode 100644 index 0000000000..90d3f8ee88 --- /dev/null +++ b/tools/compact-regions.php @@ -0,0 +1,178 @@ + $files + */ +function find_regions_recursive(string $dir, array &$files) : void{ + foreach(scandir($dir, SCANDIR_SORT_NONE) as $file){ + if($file === "." or $file === ".."){ + continue; + } + $fullPath = $dir . "/" . $file; + if( + in_array(pathinfo($fullPath, PATHINFO_EXTENSION), SUPPORTED_EXTENSIONS, true) and + is_file($fullPath) + ){ + $files[$fullPath] = filesize($fullPath); + }elseif(is_dir($fullPath)){ + find_regions_recursive($fullPath, $files); + } + } +} + +/** + * @param string[] $argv + */ +function main(array $argv) : int{ + if(!isset($argv[1])){ + echo "Usage: " . PHP_BINARY . " " . __FILE__ . " \n"; + return 1; + } + + $logger = \GlobalLogger::get(); + + /** @phpstan-var array $files */ + $files = []; + if(is_file($argv[1])){ + $files[$argv[1]] = filesize($argv[1]); + }elseif(is_dir($argv[1])){ + find_regions_recursive($argv[1], $files); + } + if(count($files) === 0){ + echo "No supported files found\n"; + return 1; + } + + arsort($files, SORT_NUMERIC); + $currentSize = array_sum($files); + $logger->info("Discovered " . count($files) . " files totalling " . number_format($currentSize) . " bytes"); + $logger->warning("Please DO NOT forcibly kill the compactor, or your files may be damaged."); + + $corruptedFiles = []; + $doneCount = 0; + $totalCount = count($files); + foreach($files as $file => $size){ + $oldRegion = new RegionLoader($file); + try{ + $oldRegion->open(); + }catch(CorruptedRegionException $e){ + $logger->error("Damaged region in file $file (" . $e->getMessage() . "), skipping"); + $corruptedFiles[] = $file; + $doneCount++; + continue; + } + + $newFile = $file . ".compacted"; + $newRegion = new RegionLoader($newFile); + $newRegion->open(); + + $emptyRegion = true; + $corruption = false; + for($x = 0; $x < 32; $x++){ + for($z = 0; $z < 32; $z++){ + try{ + $data = $oldRegion->readChunk($x, $z); + }catch(CorruptedChunkException $e){ + $logger->error("Damaged chunk $x $z in file $file (" . $e->getMessage() . "), skipping"); + $corruption = true; + continue; + } + if($data !== null){ + $emptyRegion = false; + $newRegion->writeChunk($x, $z, $data); + } + } + } + + $oldRegion->close(); + $newRegion->close(); + if(!$corruption){ + unlink($file); + }else{ + rename($file, $file . ".bak"); + $corruptedFiles[] = $file . ".bak"; + } + if(!$emptyRegion){ + rename($newFile, $file); + }else{ + unlink($newFile); + } + $doneCount++; + $logger->info("Compacted region $file ($doneCount/$totalCount, " . round(($doneCount / $totalCount) * 100, 2) . "%)"); + } + + clearstatcache(); + $newSize = 0; + foreach($files as $file => $oldSize){ + $newSize += file_exists($file) ? filesize($file) : 0; + } + $diff = $currentSize - $newSize; + $logger->info("Finished compaction of " . count($files) . " files. Freed " . number_format($diff) . " bytes of space (" . round(($diff / $currentSize) * 100, 2) . "% reduction)."); + if(count($corruptedFiles) > 0){ + $logger->error("The following backup files were not removed due to corruption detected:"); + foreach($corruptedFiles as $file){ + echo $file . "\n"; + } + return 1; + } + return 0; +} + +if(!defined('pocketmine\_PHPSTAN_ANALYSIS')){ + exit(main($argv)); +} From 017afead3b799e1bbc94ef626b1f839b7dec3cd0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 3 Jun 2020 18:59:59 +0100 Subject: [PATCH 1624/3224] extract FurnaceRecipeManager unit from CraftingManager I'd like to have this directly provided to Furnace, but I don't know how to short of making into a singleton. Since I want to have per-furnace recipe managers (e.g. for stuff like blast furnace vs regular furnace etc), a singleton isn't really an option. --- src/block/tile/Furnace.php | 2 +- src/crafting/CraftingManager.php | 31 ++++----- .../CraftingManagerFromDataHelper.php | 2 +- src/crafting/FurnaceRecipeManager.php | 68 +++++++++++++++++++ 4 files changed, 83 insertions(+), 20 deletions(-) create mode 100644 src/crafting/FurnaceRecipeManager.php diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index ce67b83fce..d80809b751 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -155,7 +155,7 @@ class Furnace extends Spawnable implements Container, Nameable{ $fuel = $this->inventory->getFuel(); $raw = $this->inventory->getSmelting(); $product = $this->inventory->getResult(); - $smelt = $this->pos->getWorldNonNull()->getServer()->getCraftingManager()->matchFurnaceRecipe($raw); + $smelt = $this->pos->getWorldNonNull()->getServer()->getCraftingManager()->getFurnaceRecipeManager()->match($raw); $canSmelt = ($smelt instanceof FurnaceRecipe and $raw->getCount() > 0 and (($smelt->getResult()->equals($product) and $product->getCount() < $product->getMaxStackSize()) or $product->isNull())); if($this->remainingFuelTime <= 0 and $canSmelt and $fuel->getFuelTime() > 0 and $fuel->getCount() > 0){ diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index ec2d6effbd..701d231642 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -48,12 +48,20 @@ class CraftingManager{ protected $shapedRecipes = []; /** @var ShapelessRecipe[][] */ protected $shapelessRecipes = []; - /** @var FurnaceRecipe[] */ - protected $furnaceRecipes = []; + + /** @var FurnaceRecipeManager */ + protected $furnaceRecipeManager; /** @var CompressBatchPromise[] */ private $craftingDataCaches = []; + public function __construct(){ + $this->furnaceRecipeManager = new FurnaceRecipeManager(); + $this->furnaceRecipeManager->getRecipeRegisteredCallbacks()->add(function(FurnaceRecipe $recipe) : void{ + $this->craftingDataCaches = []; + }); + } + /** * Rebuilds the cached CraftingDataPacket. */ @@ -105,7 +113,7 @@ class CraftingManager{ } } - foreach($this->furnaceRecipes as $recipe){ + foreach($this->furnaceRecipeManager->getAll() as $recipe){ $input = $converter->coreItemStackToNet($recipe->getInput()); $pk->entries[] = new ProtocolFurnaceRecipe( CraftingDataPacket::ENTRY_FURNACE_DATA, @@ -198,11 +206,8 @@ class CraftingManager{ return $this->shapedRecipes; } - /** - * @return FurnaceRecipe[] - */ - public function getFurnaceRecipes() : array{ - return $this->furnaceRecipes; + public function getFurnaceRecipeManager() : FurnaceRecipeManager{ + return $this->furnaceRecipeManager; } public function registerShapedRecipe(ShapedRecipe $recipe) : void{ @@ -217,12 +222,6 @@ class CraftingManager{ $this->craftingDataCaches = []; } - public function registerFurnaceRecipe(FurnaceRecipe $recipe) : void{ - $input = $recipe->getInput(); - $this->furnaceRecipes[$input->getId() . ":" . ($input->hasAnyDamageValue() ? "?" : $input->getMeta())] = $recipe; - $this->craftingDataCaches = []; - } - /** * @param Item[] $outputs */ @@ -273,8 +272,4 @@ class CraftingManager{ } } } - - public function matchFurnaceRecipe(Item $input) : ?FurnaceRecipe{ - return $this->furnaceRecipes[$input->getId() . ":" . $input->getMeta()] ?? $this->furnaceRecipes[$input->getId() . ":?"] ?? null; - } } diff --git a/src/crafting/CraftingManagerFromDataHelper.php b/src/crafting/CraftingManagerFromDataHelper.php index 84ac260a31..c82d437b2d 100644 --- a/src/crafting/CraftingManagerFromDataHelper.php +++ b/src/crafting/CraftingManagerFromDataHelper.php @@ -60,7 +60,7 @@ final class CraftingManagerFromDataHelper{ if($recipe["block"] !== "furnace"){ //TODO: filter others out for now to avoid breaking economics break; } - $result->registerFurnaceRecipe(new FurnaceRecipe( + $result->getFurnaceRecipeManager()->register(new FurnaceRecipe( Item::jsonDeserialize($recipe["output"]), Item::jsonDeserialize($recipe["input"])) ); diff --git a/src/crafting/FurnaceRecipeManager.php b/src/crafting/FurnaceRecipeManager.php new file mode 100644 index 0000000000..18b5204765 --- /dev/null +++ b/src/crafting/FurnaceRecipeManager.php @@ -0,0 +1,68 @@ + + */ + private $recipeRegisteredCallbacks; + + public function __construct(){ + $this->recipeRegisteredCallbacks = new Set(); + } + + /** + * @phpstan-return Set<\Closure(FurnaceRecipe) : void> + */ + public function getRecipeRegisteredCallbacks() : Set{ + return $this->recipeRegisteredCallbacks; + } + + /** + * @return FurnaceRecipe[] + */ + public function getAll() : array{ + return $this->furnaceRecipes; + } + + public function register(FurnaceRecipe $recipe) : void{ + $input = $recipe->getInput(); + $this->furnaceRecipes[$input->getId() . ":" . ($input->hasAnyDamageValue() ? "?" : $input->getMeta())] = $recipe; + foreach($this->recipeRegisteredCallbacks as $callback){ + $callback($recipe); + } + } + + public function match(Item $input) : ?FurnaceRecipe{ + return $this->furnaceRecipes[$input->getId() . ":" . $input->getMeta()] ?? $this->furnaceRecipes[$input->getId() . ":?"] ?? null; + } +} \ No newline at end of file From f3bcd04e87c0354de4a26e4825e9aa0af353508c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Jun 2020 14:16:45 +0100 Subject: [PATCH 1625/3224] update build/php submodule to pmmp/php-build-scripts@fd749b299a680f04a9126931b121cd3cfcde0c7a --- build/php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/php b/build/php index 653d685628..fd749b299a 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit 653d6856282d9b805d9a390b1905bef70b79d29a +Subproject commit fd749b299a680f04a9126931b121cd3cfcde0c7a From 586f26503324f9079cda6ebedbeede3172a50277 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 13 Jun 2020 11:17:58 +0100 Subject: [PATCH 1626/3224] update build/php submodule to pmmp/php-build-scripts@2f422db397509fd9d7161b0c388401ec5be5a46f --- build/php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/php b/build/php index fd749b299a..2f422db397 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit fd749b299a680f04a9126931b121cd3cfcde0c7a +Subproject commit 2f422db397509fd9d7161b0c388401ec5be5a46f From 465285b3c2a51c18f47a6db9db8d7bc73a741dab Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 13 Jun 2020 12:26:17 +0100 Subject: [PATCH 1627/3224] do not rely on GameMode::getMagicNumber() to match protocol IDs --- src/network/mcpe/NetworkSession.php | 2 +- src/network/mcpe/convert/TypeConverter.php | 18 +++++++++++++++++- .../mcpe/handler/InGamePacketHandler.php | 3 ++- .../mcpe/handler/PreSpawnPacketHandler.php | 4 ++-- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index cf449bf528..d53d1d86f2 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -684,7 +684,7 @@ class NetworkSession{ } public function syncGameMode(GameMode $mode, bool $isRollback = false) : void{ - $this->sendDataPacket(SetPlayerGameTypePacket::create(TypeConverter::getInstance()->getClientFriendlyGamemode($mode))); + $this->sendDataPacket(SetPlayerGameTypePacket::create(TypeConverter::getInstance()->coreGameModeToProtocol($mode))); $this->syncAdventureSettings($this->player); if(!$isRollback){ $this->invManager->syncCreative(); diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index cd0bc83c9a..b421fc8c93 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -56,7 +56,7 @@ class TypeConverter{ * * @internal */ - public function getClientFriendlyGamemode(GameMode $gamemode) : int{ + public function coreGameModeToProtocol(GameMode $gamemode) : int{ switch($gamemode->id()){ case GameMode::SURVIVAL()->id(): return ProtocolGameMode::SURVIVAL; @@ -70,6 +70,22 @@ class TypeConverter{ } } + public function protocolGameModeToCore(int $gameMode) : GameMode{ + switch($gameMode){ + case ProtocolGameMode::SURVIVAL: + return GameMode::SURVIVAL(); + case ProtocolGameMode::CREATIVE: + return GameMode::CREATIVE(); + case ProtocolGameMode::ADVENTURE: + return GameMode::ADVENTURE(); + case ProtocolGameMode::CREATIVE_VIEWER: + case ProtocolGameMode::SURVIVAL_VIEWER: + return GameMode::SPECTATOR(); + default: + throw new \UnexpectedValueException("Unmapped protocol game mode $gameMode"); + } + } + public function coreItemStackToRecipeIngredient(Item $itemStack) : RecipeIngredient{ $meta = $itemStack->getMeta(); return new RecipeIngredient($itemStack->getId(), $meta === -1 ? 0x7fff : $meta, $itemStack->getCount()); diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 8afb331f89..e5041ab19e 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -582,7 +582,8 @@ class InGamePacketHandler extends PacketHandler{ } public function handleSetPlayerGameType(SetPlayerGameTypePacket $packet) : bool{ - if($packet->gamemode !== $this->player->getGamemode()->getMagicNumber()){ + $converter = TypeConverter::getInstance(); + if(!$converter->protocolGameModeToCore($packet->gamemode)->equals($this->player->getGamemode())){ //Set this back to default. TODO: handle this properly $this->session->syncGameMode($this->player->getGamemode(), true); } diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index b681b31719..007da0fb72 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -59,13 +59,13 @@ class PreSpawnPacketHandler extends PacketHandler{ $pk = new StartGamePacket(); $pk->entityUniqueId = $this->player->getId(); $pk->entityRuntimeId = $this->player->getId(); - $pk->playerGamemode = TypeConverter::getInstance()->getClientFriendlyGamemode($this->player->getGamemode()); + $pk->playerGamemode = TypeConverter::getInstance()->coreGameModeToProtocol($this->player->getGamemode()); $pk->playerPosition = $this->player->getOffsetPosition($location); $pk->pitch = $location->pitch; $pk->yaw = $location->yaw; $pk->seed = -1; $pk->dimension = DimensionIds::OVERWORLD; //TODO: implement this properly - $pk->worldGamemode = TypeConverter::getInstance()->getClientFriendlyGamemode($this->server->getGamemode()); + $pk->worldGamemode = TypeConverter::getInstance()->coreGameModeToProtocol($this->server->getGamemode()); $pk->difficulty = $location->getWorldNonNull()->getDifficulty(); $pk->spawnX = $spawnPosition->getFloorX(); $pk->spawnY = $spawnPosition->getFloorY(); From 5f0f5236f8277f9c398fba4edc3f1efac6652f0b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 13 Jun 2020 18:34:23 +0100 Subject: [PATCH 1628/3224] RegistryTrait: fix crash when child classes don't define getAll() --- src/utils/RegistryTrait.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/RegistryTrait.php b/src/utils/RegistryTrait.php index 682a11a713..044900bd4e 100644 --- a/src/utils/RegistryTrait.php +++ b/src/utils/RegistryTrait.php @@ -124,7 +124,7 @@ public static function %1$s() : %2$s{ return self::fromString("%1$s"); }'; - foreach(self::getAll() as $name => $member){ + foreach(self::_registryGetAll() as $name => $member){ $lines[] = sprintf($fnTmpl, $name, '\\' . get_class($member)); } return "//region auto-generated code\n" . implode("\n", $lines) . "\n\n//endregion\n"; @@ -144,7 +144,7 @@ public static function %1$s() : %2$s{ static $lineTmpl = " * @method static %2\$s %s()"; $thisNamespace = (new \ReflectionClass(__CLASS__))->getNamespaceName(); - foreach(self::getAll() as $name => $member){ + foreach(self::_registryGetAll() as $name => $member){ $reflect = new \ReflectionClass($member); while($reflect !== false and $reflect->isAnonymous()){ $reflect = $reflect->getParentClass(); From 5f79071e4c27cf06dea421010bc22bb7238f4cf3 Mon Sep 17 00:00:00 2001 From: "Eren A. Akyol" Date: Sun, 14 Jun 2020 13:48:15 +0300 Subject: [PATCH 1629/3224] Registry Trait: fixed magic methods not working properly when system locale is tr_TR (#3580) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed incorrect case of incorrect letters on operating systems using languages other than English. Like (Stair => STAİR) --- src/utils/RegistryTrait.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/utils/RegistryTrait.php b/src/utils/RegistryTrait.php index 044900bd4e..80abf6adc7 100644 --- a/src/utils/RegistryTrait.php +++ b/src/utils/RegistryTrait.php @@ -30,7 +30,7 @@ use function implode; use function sprintf; use function strlen; use function strpos; -use function strtoupper; +use function mb_strtoupper; use function substr; trait RegistryTrait{ @@ -43,11 +43,11 @@ trait RegistryTrait{ * @throws \InvalidArgumentException */ private static function _registryRegister(string $name, object $member) : void{ - $name = strtoupper($name); + $name = mb_strtoupper($name); if(isset(self::$members[$name])){ throw new \InvalidArgumentException("\"$name\" is already reserved"); } - self::$members[strtoupper($name)] = $member; + self::$members[mb_strtoupper($name)] = $member; } /** @@ -74,7 +74,7 @@ trait RegistryTrait{ */ private static function _registryFromString(string $name) : object{ self::checkInit(); - $name = strtoupper($name); + $name = mb_strtoupper($name); if(!isset(self::$members[$name])){ throw new \InvalidArgumentException("No such registry member: " . self::class . "::" . $name); } From 9ce531fef4d105c56790612a8607a030f3fd766d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 14 Jun 2020 19:29:33 +0100 Subject: [PATCH 1630/3224] (master) imports cleanup --- src/network/mcpe/NetworkSession.php | 1 - src/network/mcpe/handler/InGamePacketHandler.php | 1 + src/utils/RegistryTrait.php | 2 +- src/utils/Utils.php | 1 - 4 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index d53d1d86f2..0ac4898029 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -103,7 +103,6 @@ use pocketmine\utils\Utils; use pocketmine\world\Position; use function array_map; use function array_values; -use function assert; use function base64_encode; use function bin2hex; use function count; diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index e5041ab19e..0514c6e909 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -95,6 +95,7 @@ use function implode; use function json_decode; use function json_encode; use function json_last_error_msg; +use function max; use function microtime; use function preg_match; use function strlen; diff --git a/src/utils/RegistryTrait.php b/src/utils/RegistryTrait.php index 80abf6adc7..9be348d686 100644 --- a/src/utils/RegistryTrait.php +++ b/src/utils/RegistryTrait.php @@ -27,10 +27,10 @@ use function array_map; use function count; use function get_class; use function implode; +use function mb_strtoupper; use function sprintf; use function strlen; use function strpos; -use function mb_strtoupper; use function substr; trait RegistryTrait{ diff --git a/src/utils/Utils.php b/src/utils/Utils.php index 16f9f16d2a..565cb2abbf 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -72,7 +72,6 @@ use function substr; use function sys_get_temp_dir; use function trim; use function xdebug_get_function_stack; -use const DIRECTORY_SEPARATOR; use const PHP_EOL; use const PHP_INT_MAX; use const PHP_INT_SIZE; From 3294075aada3781df927f34aacffe793a2cf4042 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 15 Jun 2020 20:31:09 +0100 Subject: [PATCH 1631/3224] LoginPacketHandler: use double quotes consistently the mixture of single quotes and double quotes makes PHPStan type inference quietly not work, and reports an error here in checkExplicitMixed mode. --- src/network/mcpe/handler/LoginPacketHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index e90e72ddef..26b1bf4530 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -229,7 +229,7 @@ class LoginPacketHandler extends PacketHandler{ $mapper->bExceptionOnUndefinedProperty = true; try{ /** @var AuthenticationData $extraData */ - $extraData = $mapper->map($claims['extraData'], new AuthenticationData); + $extraData = $mapper->map($claims["extraData"], new AuthenticationData); }catch(\JsonMapper_Exception $e){ throw BadPacketException::wrap($e); } From a381fc884811cc2022e072883211e589e271029b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 15 Jun 2020 22:24:44 +0100 Subject: [PATCH 1632/3224] sync composer dependencies --- composer.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/composer.lock b/composer.lock index da33cbb697..e91a2b1c76 100644 --- a/composer.lock +++ b/composer.lock @@ -552,12 +552,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "9d8a73014725f57cf4bf5cbdb40e340fe4643169" + "reference": "666175cd9a6561217d436902c666405b790a1a86" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/9d8a73014725f57cf4bf5cbdb40e340fe4643169", - "reference": "9d8a73014725f57cf4bf5cbdb40e340fe4643169", + "url": "https://api.github.com/repos/pmmp/Math/zipball/666175cd9a6561217d436902c666405b790a1a86", + "reference": "666175cd9a6561217d436902c666405b790a1a86", "shasum": "" }, "require": { @@ -579,7 +579,7 @@ "LGPL-3.0" ], "description": "PHP library containing math related code used in PocketMine-MP", - "time": "2020-05-19T12:13:12+00:00" + "time": "2020-06-15T21:21:46+00:00" }, { "name": "pocketmine/nbt", @@ -624,12 +624,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "12153dcd1e37d1d1b026db65605210f094579861" + "reference": "a63bad0250e3218e606c055fbc77820ce8214fb8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/12153dcd1e37d1d1b026db65605210f094579861", - "reference": "12153dcd1e37d1d1b026db65605210f094579861", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/a63bad0250e3218e606c055fbc77820ce8214fb8", + "reference": "a63bad0250e3218e606c055fbc77820ce8214fb8", "shasum": "" }, "require": { @@ -655,7 +655,7 @@ "GPL-3.0" ], "description": "A RakNet server implementation written in PHP", - "time": "2020-05-10T10:47:44+00:00" + "time": "2020-06-03T19:14:17+00:00" }, { "name": "pocketmine/snooze", @@ -811,16 +811,16 @@ }, { "name": "respect/validation", - "version": "2.0.8", + "version": "2.0.10", "source": { "type": "git", "url": "https://github.com/Respect/Validation.git", - "reference": "e0fbed32c90b408652bb30803647d90901f612f1" + "reference": "80f236bb900e5bc5e790737a31806f4d10c560ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Respect/Validation/zipball/e0fbed32c90b408652bb30803647d90901f612f1", - "reference": "e0fbed32c90b408652bb30803647d90901f612f1", + "url": "https://api.github.com/repos/Respect/Validation/zipball/80f236bb900e5bc5e790737a31806f4d10c560ba", + "reference": "80f236bb900e5bc5e790737a31806f4d10c560ba", "shasum": "" }, "require": { @@ -873,7 +873,7 @@ "validation", "validator" ], - "time": "2020-05-20T13:02:44+00:00" + "time": "2020-06-07T00:14:45+00:00" }, { "name": "symfony/polyfill-mbstring", From c6557f0222784586f4657114ce3939ff36eb7708 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jun 2020 11:06:26 +0100 Subject: [PATCH 1633/3224] protocol: added a FixedItemIds class (this is fully auto-generated, unlike the one provided by the API) this may be different from the IDs exposed on the API and shouldn't be used for anything outside the protocol. TODO: we need to review the dynamicness of item numeric IDs and find out if it's possible for them to change based on StartGamePacket content. If they can, we might need to change this. --- .../serializer/NetworkBinaryStream.php | 4 +- .../mcpe/protocol/types/FixedItemIds.php | 757 ++++++++++++++++++ .../protocol/types/inventory/ItemStack.php | 4 +- 3 files changed, 761 insertions(+), 4 deletions(-) create mode 100644 src/network/mcpe/protocol/types/FixedItemIds.php diff --git a/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php b/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php index 60d5aa425a..a1d5dd8334 100644 --- a/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php +++ b/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol\serializer; #include -use pocketmine\item\ItemIds; use pocketmine\math\Vector3; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; @@ -46,6 +45,7 @@ use pocketmine\network\mcpe\protocol\types\entity\StringMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\Vec3MetadataProperty; use pocketmine\network\mcpe\protocol\types\GameRuleType; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; +use pocketmine\network\mcpe\protocol\types\FixedItemIds; use pocketmine\network\mcpe\protocol\types\PersonaPieceTintColor; use pocketmine\network\mcpe\protocol\types\PersonaSkinPiece; use pocketmine\network\mcpe\protocol\types\recipe\RecipeIngredient; @@ -240,7 +240,7 @@ class NetworkBinaryStream extends BinaryStream{ } $shieldBlockingTick = null; - if($id === ItemIds::SHIELD){ + if($id === FixedItemIds::SHIELD){ $shieldBlockingTick = $this->getVarLong(); } diff --git a/src/network/mcpe/protocol/types/FixedItemIds.php b/src/network/mcpe/protocol/types/FixedItemIds.php new file mode 100644 index 0000000000..5b145e1512 --- /dev/null +++ b/src/network/mcpe/protocol/types/FixedItemIds.php @@ -0,0 +1,757 @@ +id = $id; From 6c096c44aa4860dcebfdcb34d78ad792669a6d13 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jun 2020 11:31:13 +0100 Subject: [PATCH 1634/3224] Rename NetworkBinaryStream -> PacketSerializer --- .../mcpe/protocol/ActorEventPacket.php | 6 ++-- src/network/mcpe/protocol/ActorFallPacket.php | 6 ++-- .../mcpe/protocol/ActorPickRequestPacket.php | 6 ++-- src/network/mcpe/protocol/AddActorPacket.php | 6 ++-- .../mcpe/protocol/AddBehaviorTreePacket.php | 6 ++-- src/network/mcpe/protocol/AddEntityPacket.php | 6 ++-- .../mcpe/protocol/AddItemActorPacket.php | 6 ++-- .../mcpe/protocol/AddPaintingPacket.php | 6 ++-- src/network/mcpe/protocol/AddPlayerPacket.php | 6 ++-- .../mcpe/protocol/AdventureSettingsPacket.php | 6 ++-- src/network/mcpe/protocol/AnimatePacket.php | 6 ++-- .../mcpe/protocol/AnvilDamagePacket.php | 6 ++-- .../AutomationClientConnectPacket.php | 6 ++-- .../AvailableActorIdentifiersPacket.php | 6 ++-- .../mcpe/protocol/AvailableCommandsPacket.php | 26 +++++++------- .../protocol/BiomeDefinitionListPacket.php | 6 ++-- .../mcpe/protocol/BlockActorDataPacket.php | 6 ++-- .../mcpe/protocol/BlockEventPacket.php | 6 ++-- .../mcpe/protocol/BlockPickRequestPacket.php | 6 ++-- src/network/mcpe/protocol/BookEditPacket.php | 6 ++-- src/network/mcpe/protocol/BossEventPacket.php | 6 ++-- src/network/mcpe/protocol/CameraPacket.php | 6 ++-- .../mcpe/protocol/ChangeDimensionPacket.php | 6 ++-- .../protocol/ChunkRadiusUpdatedPacket.php | 6 ++-- .../protocol/ClientCacheBlobStatusPacket.php | 6 ++-- .../ClientCacheMissResponsePacket.php | 6 ++-- .../mcpe/protocol/ClientCacheStatusPacket.php | 6 ++-- .../ClientToServerHandshakePacket.php | 6 ++-- .../protocol/ClientboundMapItemDataPacket.php | 6 ++-- .../protocol/CommandBlockUpdatePacket.php | 6 ++-- .../mcpe/protocol/CommandOutputPacket.php | 10 +++--- .../mcpe/protocol/CommandRequestPacket.php | 6 ++-- .../protocol/CompletedUsingItemPacket.php | 6 ++-- .../mcpe/protocol/ContainerClosePacket.php | 6 ++-- .../mcpe/protocol/ContainerOpenPacket.php | 6 ++-- .../mcpe/protocol/ContainerSetDataPacket.php | 6 ++-- .../mcpe/protocol/CraftingDataPacket.php | 6 ++-- .../mcpe/protocol/CraftingEventPacket.php | 6 ++-- src/network/mcpe/protocol/DataPacket.php | 16 ++++----- .../mcpe/protocol/DisconnectPacket.php | 6 ++-- .../mcpe/protocol/EducationSettingsPacket.php | 6 ++-- src/network/mcpe/protocol/EmotePacket.php | 6 ++-- src/network/mcpe/protocol/EventPacket.php | 6 ++-- .../mcpe/protocol/GameRulesChangedPacket.php | 6 ++-- .../mcpe/protocol/GuiDataPickItemPacket.php | 6 ++-- src/network/mcpe/protocol/HurtArmorPacket.php | 6 ++-- src/network/mcpe/protocol/InteractPacket.php | 6 ++-- .../mcpe/protocol/InventoryContentPacket.php | 6 ++-- .../mcpe/protocol/InventorySlotPacket.php | 6 ++-- .../protocol/InventoryTransactionPacket.php | 6 ++-- .../mcpe/protocol/ItemFrameDropItemPacket.php | 6 ++-- src/network/mcpe/protocol/LabTablePacket.php | 6 ++-- .../mcpe/protocol/LecternUpdatePacket.php | 6 ++-- .../mcpe/protocol/LevelChunkPacket.php | 6 ++-- .../mcpe/protocol/LevelEventGenericPacket.php | 6 ++-- .../mcpe/protocol/LevelEventPacket.php | 6 ++-- .../mcpe/protocol/LevelSoundEventPacket.php | 6 ++-- .../mcpe/protocol/LevelSoundEventPacketV1.php | 6 ++-- .../mcpe/protocol/LevelSoundEventPacketV2.php | 6 ++-- src/network/mcpe/protocol/LoginPacket.php | 6 ++-- .../protocol/MapCreateLockedCopyPacket.php | 6 ++-- .../mcpe/protocol/MapInfoRequestPacket.php | 6 ++-- .../mcpe/protocol/MobArmorEquipmentPacket.php | 6 ++-- src/network/mcpe/protocol/MobEffectPacket.php | 6 ++-- .../mcpe/protocol/MobEquipmentPacket.php | 6 ++-- .../mcpe/protocol/ModalFormRequestPacket.php | 6 ++-- .../mcpe/protocol/ModalFormResponsePacket.php | 6 ++-- .../mcpe/protocol/MoveActorAbsolutePacket.php | 6 ++-- .../mcpe/protocol/MoveActorDeltaPacket.php | 14 ++++---- .../mcpe/protocol/MovePlayerPacket.php | 6 ++-- .../protocol/MultiplayerSettingsPacket.php | 6 ++-- .../NetworkChunkPublisherUpdatePacket.php | 6 ++-- .../mcpe/protocol/NetworkSettingsPacket.php | 6 ++-- .../protocol/NetworkStackLatencyPacket.php | 6 ++-- .../mcpe/protocol/NpcRequestPacket.php | 6 ++-- .../OnScreenTextureAnimationPacket.php | 6 ++-- src/network/mcpe/protocol/Packet.php | 4 +-- .../mcpe/protocol/PhotoTransferPacket.php | 6 ++-- src/network/mcpe/protocol/PlaySoundPacket.php | 6 ++-- .../mcpe/protocol/PlayStatusPacket.php | 6 ++-- .../mcpe/protocol/PlayerActionPacket.php | 6 ++-- .../mcpe/protocol/PlayerAuthInputPacket.php | 6 ++-- .../mcpe/protocol/PlayerHotbarPacket.php | 6 ++-- .../mcpe/protocol/PlayerInputPacket.php | 6 ++-- .../mcpe/protocol/PlayerListPacket.php | 6 ++-- .../mcpe/protocol/PlayerSkinPacket.php | 6 ++-- .../mcpe/protocol/PurchaseReceiptPacket.php | 6 ++-- .../mcpe/protocol/RemoveActorPacket.php | 6 ++-- .../mcpe/protocol/RemoveEntityPacket.php | 6 ++-- .../mcpe/protocol/RemoveObjectivePacket.php | 6 ++-- .../protocol/RequestChunkRadiusPacket.php | 6 ++-- .../protocol/ResourcePackChunkDataPacket.php | 6 ++-- .../ResourcePackChunkRequestPacket.php | 6 ++-- .../ResourcePackClientResponsePacket.php | 6 ++-- .../protocol/ResourcePackDataInfoPacket.php | 6 ++-- .../mcpe/protocol/ResourcePackStackPacket.php | 6 ++-- .../mcpe/protocol/ResourcePacksInfoPacket.php | 6 ++-- src/network/mcpe/protocol/RespawnPacket.php | 6 ++-- src/network/mcpe/protocol/RiderJumpPacket.php | 6 ++-- .../mcpe/protocol/ScriptCustomEventPacket.php | 6 ++-- .../protocol/ServerSettingsRequestPacket.php | 6 ++-- .../protocol/ServerSettingsResponsePacket.php | 6 ++-- .../ServerToClientHandshakePacket.php | 6 ++-- .../mcpe/protocol/SetActorDataPacket.php | 6 ++-- .../mcpe/protocol/SetActorLinkPacket.php | 6 ++-- .../mcpe/protocol/SetActorMotionPacket.php | 6 ++-- .../protocol/SetCommandsEnabledPacket.php | 6 ++-- .../protocol/SetDefaultGameTypePacket.php | 6 ++-- .../mcpe/protocol/SetDifficultyPacket.php | 6 ++-- .../protocol/SetDisplayObjectivePacket.php | 6 ++-- src/network/mcpe/protocol/SetHealthPacket.php | 6 ++-- .../mcpe/protocol/SetLastHurtByPacket.php | 6 ++-- .../SetLocalPlayerAsInitializedPacket.php | 6 ++-- .../mcpe/protocol/SetPlayerGameTypePacket.php | 6 ++-- src/network/mcpe/protocol/SetScorePacket.php | 6 ++-- .../protocol/SetScoreboardIdentityPacket.php | 6 ++-- .../mcpe/protocol/SetSpawnPositionPacket.php | 6 ++-- src/network/mcpe/protocol/SetTimePacket.php | 6 ++-- src/network/mcpe/protocol/SetTitlePacket.php | 6 ++-- .../mcpe/protocol/SettingsCommandPacket.php | 6 ++-- .../mcpe/protocol/ShowCreditsPacket.php | 6 ++-- .../mcpe/protocol/ShowProfilePacket.php | 6 ++-- .../mcpe/protocol/ShowStoreOfferPacket.php | 6 ++-- .../mcpe/protocol/SimpleEventPacket.php | 6 ++-- .../protocol/SpawnExperienceOrbPacket.php | 6 ++-- .../protocol/SpawnParticleEffectPacket.php | 6 ++-- src/network/mcpe/protocol/StartGamePacket.php | 8 ++--- src/network/mcpe/protocol/StopSoundPacket.php | 6 ++-- .../protocol/StructureBlockUpdatePacket.php | 6 ++-- .../StructureTemplateDataRequestPacket.php | 6 ++-- .../StructureTemplateDataResponsePacket.php | 6 ++-- .../mcpe/protocol/SubClientLoginPacket.php | 6 ++-- .../mcpe/protocol/TakeItemActorPacket.php | 6 ++-- src/network/mcpe/protocol/TextPacket.php | 6 ++-- src/network/mcpe/protocol/TickSyncPacket.php | 6 ++-- src/network/mcpe/protocol/TransferPacket.php | 6 ++-- src/network/mcpe/protocol/UnknownPacket.php | 10 +++--- .../mcpe/protocol/UpdateAttributesPacket.php | 6 ++-- .../mcpe/protocol/UpdateBlockPacket.php | 6 ++-- .../protocol/UpdateBlockPropertiesPacket.php | 6 ++-- .../mcpe/protocol/UpdateBlockSyncedPacket.php | 6 ++-- .../mcpe/protocol/UpdateEquipPacket.php | 6 ++-- .../mcpe/protocol/UpdateSoftEnumPacket.php | 6 ++-- .../mcpe/protocol/UpdateTradePacket.php | 6 ++-- .../protocol/VideoStreamConnectPacket.php | 6 ++-- .../mcpe/protocol/serializer/PacketBatch.php | 4 +-- ...kBinaryStream.php => PacketSerializer.php} | 35 ++++++++++++------- .../types/entity/BlockPosMetadataProperty.php | 6 ++-- .../types/entity/ByteMetadataProperty.php | 6 ++-- .../entity/CompoundTagMetadataProperty.php | 6 ++-- .../types/entity/FloatMetadataProperty.php | 6 ++-- .../types/entity/IntMetadataProperty.php | 6 ++-- .../types/entity/LongMetadataProperty.php | 6 ++-- .../types/entity/MetadataProperty.php | 4 +-- .../types/entity/ShortMetadataProperty.php | 6 ++-- .../types/entity/StringMetadataProperty.php | 6 ++-- .../types/entity/Vec3MetadataProperty.php | 6 ++-- .../inventory/MismatchTransactionData.php | 6 ++-- .../inventory/NetworkInventoryAction.php | 6 ++-- .../types/inventory/NormalTransactionData.php | 6 ++-- .../inventory/ReleaseItemTransactionData.php | 6 ++-- .../types/inventory/TransactionData.php | 10 +++--- .../UseItemOnEntityTransactionData.php | 6 ++-- .../inventory/UseItemTransactionData.php | 6 ++-- .../protocol/types/recipe/FurnaceRecipe.php | 6 ++-- .../protocol/types/recipe/MultiRecipe.php | 6 ++-- .../types/recipe/RecipeWithTypeId.php | 4 +-- .../protocol/types/recipe/ShapedRecipe.php | 6 ++-- .../protocol/types/recipe/ShapelessRecipe.php | 6 ++-- .../resourcepacks/ResourcePackInfoEntry.php | 6 ++-- .../resourcepacks/ResourcePackStackEntry.php | 6 ++-- .../mcpe/serializer/ChunkSerializer.php | 4 +-- tests/phpstan/configs/l7-baseline.neon | 18 +++++----- tests/phpstan/configs/l8-baseline.neon | 6 ++-- .../network/mcpe/protocol/LoginPacketTest.php | 6 ++-- .../network/mcpe/protocol/TestPacket.php | 6 ++-- 176 files changed, 575 insertions(+), 564 deletions(-) rename src/network/mcpe/protocol/serializer/{NetworkBinaryStream.php => PacketSerializer.php} (95%) diff --git a/src/network/mcpe/protocol/ActorEventPacket.php b/src/network/mcpe/protocol/ActorEventPacket.php index a2686fbbf5..7e6226231c 100644 --- a/src/network/mcpe/protocol/ActorEventPacket.php +++ b/src/network/mcpe/protocol/ActorEventPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ActorEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ACTOR_EVENT_PACKET; @@ -105,13 +105,13 @@ class ActorEventPacket extends DataPacket implements ClientboundPacket, Serverbo return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityRuntimeId = $in->getEntityRuntimeId(); $this->event = $in->getByte(); $this->data = $in->getVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityRuntimeId($this->entityRuntimeId); $out->putByte($this->event); $out->putVarInt($this->data); diff --git a/src/network/mcpe/protocol/ActorFallPacket.php b/src/network/mcpe/protocol/ActorFallPacket.php index 4612d7dad9..6b79d9d96a 100644 --- a/src/network/mcpe/protocol/ActorFallPacket.php +++ b/src/network/mcpe/protocol/ActorFallPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ActorFallPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ACTOR_FALL_PACKET; @@ -37,13 +37,13 @@ class ActorFallPacket extends DataPacket implements ServerboundPacket{ /** @var bool */ public $isInVoid; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityRuntimeId = $in->getEntityRuntimeId(); $this->fallDistance = $in->getLFloat(); $this->isInVoid = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityRuntimeId($this->entityRuntimeId); $out->putLFloat($this->fallDistance); $out->putBool($this->isInVoid); diff --git a/src/network/mcpe/protocol/ActorPickRequestPacket.php b/src/network/mcpe/protocol/ActorPickRequestPacket.php index 911258e2f3..bf04e560a8 100644 --- a/src/network/mcpe/protocol/ActorPickRequestPacket.php +++ b/src/network/mcpe/protocol/ActorPickRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ActorPickRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ACTOR_PICK_REQUEST_PACKET; @@ -35,12 +35,12 @@ class ActorPickRequestPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $hotbarSlot; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityUniqueId = $in->getLLong(); $this->hotbarSlot = $in->getByte(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putLLong($this->entityUniqueId); $out->putByte($this->hotbarSlot); } diff --git a/src/network/mcpe/protocol/AddActorPacket.php b/src/network/mcpe/protocol/AddActorPacket.php index a0fc3bceea..356797ade3 100644 --- a/src/network/mcpe/protocol/AddActorPacket.php +++ b/src/network/mcpe/protocol/AddActorPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\entity\Attribute; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; @@ -62,7 +62,7 @@ class AddActorPacket extends DataPacket implements ClientboundPacket{ /** @var EntityLink[] */ public $links = []; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityUniqueId = $in->getEntityUniqueId(); $this->entityRuntimeId = $in->getEntityRuntimeId(); $this->type = $in->getString(); @@ -88,7 +88,7 @@ class AddActorPacket extends DataPacket implements ClientboundPacket{ } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); $out->putEntityRuntimeId($this->entityRuntimeId); $out->putString($this->type); diff --git a/src/network/mcpe/protocol/AddBehaviorTreePacket.php b/src/network/mcpe/protocol/AddBehaviorTreePacket.php index e9d6318cad..30052c748c 100644 --- a/src/network/mcpe/protocol/AddBehaviorTreePacket.php +++ b/src/network/mcpe/protocol/AddBehaviorTreePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class AddBehaviorTreePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_BEHAVIOR_TREE_PACKET; @@ -33,11 +33,11 @@ class AddBehaviorTreePacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $behaviorTreeJson; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->behaviorTreeJson = $in->getString(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->behaviorTreeJson); } diff --git a/src/network/mcpe/protocol/AddEntityPacket.php b/src/network/mcpe/protocol/AddEntityPacket.php index 8d9e9debf7..7d5ff64ce3 100644 --- a/src/network/mcpe/protocol/AddEntityPacket.php +++ b/src/network/mcpe/protocol/AddEntityPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class AddEntityPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_ENTITY_PACKET; @@ -43,11 +43,11 @@ class AddEntityPacket extends DataPacket implements ClientboundPacket{ return $this->uvarint1; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->uvarint1 = $in->getUnsignedVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putUnsignedVarInt($this->uvarint1); } diff --git a/src/network/mcpe/protocol/AddItemActorPacket.php b/src/network/mcpe/protocol/AddItemActorPacket.php index 8c0ddc2eb5..2a2b058745 100644 --- a/src/network/mcpe/protocol/AddItemActorPacket.php +++ b/src/network/mcpe/protocol/AddItemActorPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; @@ -51,7 +51,7 @@ class AddItemActorPacket extends DataPacket implements ClientboundPacket{ /** @var bool */ public $isFromFishing = false; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityUniqueId = $in->getEntityUniqueId(); $this->entityRuntimeId = $in->getEntityRuntimeId(); $this->item = $in->getSlot(); @@ -61,7 +61,7 @@ class AddItemActorPacket extends DataPacket implements ClientboundPacket{ $this->isFromFishing = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); $out->putEntityRuntimeId($this->entityRuntimeId); $out->putSlot($this->item); diff --git a/src/network/mcpe/protocol/AddPaintingPacket.php b/src/network/mcpe/protocol/AddPaintingPacket.php index 54a2e2e8cc..0f8a38ed73 100644 --- a/src/network/mcpe/protocol/AddPaintingPacket.php +++ b/src/network/mcpe/protocol/AddPaintingPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class AddPaintingPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_PAINTING_PACKET; @@ -42,7 +42,7 @@ class AddPaintingPacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $title; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityUniqueId = $in->getEntityUniqueId(); $this->entityRuntimeId = $in->getEntityRuntimeId(); $this->position = $in->getVector3(); @@ -50,7 +50,7 @@ class AddPaintingPacket extends DataPacket implements ClientboundPacket{ $this->title = $in->getString(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); $out->putEntityRuntimeId($this->entityRuntimeId); $out->putVector3($this->position); diff --git a/src/network/mcpe/protocol/AddPlayerPacket.php b/src/network/mcpe/protocol/AddPlayerPacket.php index afef818781..f5b6adeed4 100644 --- a/src/network/mcpe/protocol/AddPlayerPacket.php +++ b/src/network/mcpe/protocol/AddPlayerPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\DeviceOS; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; @@ -88,7 +88,7 @@ class AddPlayerPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $buildPlatform = DeviceOS::UNKNOWN; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->uuid = $in->getUUID(); $this->username = $in->getString(); $this->entityUniqueId = $in->getEntityUniqueId(); @@ -119,7 +119,7 @@ class AddPlayerPacket extends DataPacket implements ClientboundPacket{ $this->buildPlatform = $in->getLInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putUUID($this->uuid); $out->putString($this->username); $out->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); diff --git a/src/network/mcpe/protocol/AdventureSettingsPacket.php b/src/network/mcpe/protocol/AdventureSettingsPacket.php index e6d9f0c3bd..04c54cf78a 100644 --- a/src/network/mcpe/protocol/AdventureSettingsPacket.php +++ b/src/network/mcpe/protocol/AdventureSettingsPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; class AdventureSettingsPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -75,7 +75,7 @@ class AdventureSettingsPacket extends DataPacket implements ClientboundPacket, S /** @var int */ public $entityUniqueId; //This is a little-endian long, NOT a var-long. (WTF Mojang) - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->flags = $in->getUnsignedVarInt(); $this->commandPermission = $in->getUnsignedVarInt(); $this->flags2 = $in->getUnsignedVarInt(); @@ -84,7 +84,7 @@ class AdventureSettingsPacket extends DataPacket implements ClientboundPacket, S $this->entityUniqueId = $in->getLLong(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putUnsignedVarInt($this->flags); $out->putUnsignedVarInt($this->commandPermission); $out->putUnsignedVarInt($this->flags2); diff --git a/src/network/mcpe/protocol/AnimatePacket.php b/src/network/mcpe/protocol/AnimatePacket.php index 785ea0ab0a..95aea04795 100644 --- a/src/network/mcpe/protocol/AnimatePacket.php +++ b/src/network/mcpe/protocol/AnimatePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class AnimatePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ANIMATE_PACKET; @@ -58,7 +58,7 @@ class AnimatePacket extends DataPacket implements ClientboundPacket, Serverbound return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->action = $in->getVarInt(); $this->entityRuntimeId = $in->getEntityRuntimeId(); if(($this->action & 0x80) !== 0){ @@ -66,7 +66,7 @@ class AnimatePacket extends DataPacket implements ClientboundPacket, Serverbound } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putVarInt($this->action); $out->putEntityRuntimeId($this->entityRuntimeId); if(($this->action & 0x80) !== 0){ diff --git a/src/network/mcpe/protocol/AnvilDamagePacket.php b/src/network/mcpe/protocol/AnvilDamagePacket.php index 75163d3e98..7f6616ddec 100644 --- a/src/network/mcpe/protocol/AnvilDamagePacket.php +++ b/src/network/mcpe/protocol/AnvilDamagePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class AnvilDamagePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::ANVIL_DAMAGE_PACKET; @@ -62,12 +62,12 @@ class AnvilDamagePacket extends DataPacket implements ServerboundPacket{ return $this->z; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->damageAmount = $in->getByte(); $in->getBlockPosition($this->x, $this->y, $this->z); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putByte($this->damageAmount); $out->putBlockPosition($this->x, $this->y, $this->z); } diff --git a/src/network/mcpe/protocol/AutomationClientConnectPacket.php b/src/network/mcpe/protocol/AutomationClientConnectPacket.php index 877e031e90..e9ae268c02 100644 --- a/src/network/mcpe/protocol/AutomationClientConnectPacket.php +++ b/src/network/mcpe/protocol/AutomationClientConnectPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class AutomationClientConnectPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::AUTOMATION_CLIENT_CONNECT_PACKET; @@ -33,11 +33,11 @@ class AutomationClientConnectPacket extends DataPacket implements ClientboundPac /** @var string */ public $serverUri; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->serverUri = $in->getString(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->serverUri); } diff --git a/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php b/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php index 4f79632488..93f0bab998 100644 --- a/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php +++ b/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\CacheableNbt; class AvailableActorIdentifiersPacket extends DataPacket implements ClientboundPacket{ @@ -46,11 +46,11 @@ class AvailableActorIdentifiersPacket extends DataPacket implements ClientboundP return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->identifiers = new CacheableNbt($in->getNbtCompoundRoot()); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->put($this->identifiers->getEncodedNbt()); } diff --git a/src/network/mcpe/protocol/AvailableCommandsPacket.php b/src/network/mcpe/protocol/AvailableCommandsPacket.php index a4fe85fec9..aa0cb8d481 100644 --- a/src/network/mcpe/protocol/AvailableCommandsPacket.php +++ b/src/network/mcpe/protocol/AvailableCommandsPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\command\CommandData; use pocketmine\network\mcpe\protocol\types\command\CommandEnum; use pocketmine\network\mcpe\protocol\types\command\CommandEnumConstraint; @@ -108,7 +108,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ */ public $enumConstraints = []; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ /** @var string[] $enumValues */ $enumValues = []; for($i = 0, $enumValuesCount = $in->getUnsignedVarInt(); $i < $enumValuesCount; ++$i){ @@ -149,7 +149,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @throws PacketDecodeException * @throws BinaryDataException */ - protected function getEnum(array $enumValueList, NetworkBinaryStream $in) : CommandEnum{ + protected function getEnum(array $enumValueList, PacketSerializer $in) : CommandEnum{ $enumName = $in->getString(); $enumValues = []; @@ -170,7 +170,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ /** * @throws BinaryDataException */ - protected function getSoftEnum(NetworkBinaryStream $in) : CommandEnum{ + protected function getSoftEnum(PacketSerializer $in) : CommandEnum{ $enumName = $in->getString(); $enumValues = []; @@ -185,7 +185,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ /** * @param int[] $enumValueMap */ - protected function putEnum(CommandEnum $enum, array $enumValueMap, NetworkBinaryStream $out) : void{ + protected function putEnum(CommandEnum $enum, array $enumValueMap, PacketSerializer $out) : void{ $out->putString($enum->getName()); $values = $enum->getValues(); @@ -200,7 +200,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ } } - protected function putSoftEnum(CommandEnum $enum, NetworkBinaryStream $out) : void{ + protected function putSoftEnum(CommandEnum $enum, PacketSerializer $out) : void{ $out->putString($enum->getName()); $values = $enum->getValues(); @@ -213,7 +213,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ /** * @throws BinaryDataException */ - protected function getEnumValueIndex(int $valueCount, NetworkBinaryStream $in) : int{ + protected function getEnumValueIndex(int $valueCount, PacketSerializer $in) : int{ if($valueCount < 256){ return $in->getByte(); }elseif($valueCount < 65536){ @@ -223,7 +223,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ } } - protected function putEnumValueIndex(int $index, int $valueCount, NetworkBinaryStream $out) : void{ + protected function putEnumValueIndex(int $index, int $valueCount, PacketSerializer $out) : void{ if($valueCount < 256){ $out->putByte($index); }elseif($valueCount < 65536){ @@ -240,7 +240,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @throws PacketDecodeException * @throws BinaryDataException */ - protected function getEnumConstraint(array $enums, array $enumValues, NetworkBinaryStream $in) : CommandEnumConstraint{ + protected function getEnumConstraint(array $enums, array $enumValues, PacketSerializer $in) : CommandEnumConstraint{ //wtf, what was wrong with an offset inside the enum? :( $valueIndex = $in->getLInt(); if(!isset($enumValues[$valueIndex])){ @@ -268,7 +268,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @param int[] $enumIndexes string enum name -> int index * @param int[] $enumValueIndexes string value -> int index */ - protected function putEnumConstraint(CommandEnumConstraint $constraint, array $enumIndexes, array $enumValueIndexes, NetworkBinaryStream $out) : void{ + protected function putEnumConstraint(CommandEnumConstraint $constraint, array $enumIndexes, array $enumValueIndexes, PacketSerializer $out) : void{ $out->putLInt($enumValueIndexes[$constraint->getAffectedValue()]); $out->putLInt($enumIndexes[$constraint->getEnum()->getName()]); $out->putUnsignedVarInt(count($constraint->getConstraints())); @@ -284,7 +284,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @throws PacketDecodeException * @throws BinaryDataException */ - protected function getCommandData(array $enums, array $postfixes, NetworkBinaryStream $in) : CommandData{ + protected function getCommandData(array $enums, array $postfixes, PacketSerializer $in) : CommandData{ $name = $in->getString(); $description = $in->getString(); $flags = $in->getByte(); @@ -328,7 +328,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ * @param int[] $enumIndexes string enum name -> int index * @param int[] $postfixIndexes */ - protected function putCommandData(CommandData $data, array $enumIndexes, array $postfixIndexes, NetworkBinaryStream $out) : void{ + protected function putCommandData(CommandData $data, array $enumIndexes, array $postfixIndexes, PacketSerializer $out) : void{ $out->putString($data->name); $out->putString($data->description); $out->putByte($data->flags); @@ -409,7 +409,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ return "unknown ($argtype)"; } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ /** @var int[] $enumValueIndexes */ $enumValueIndexes = []; /** @var int[] $postfixIndexes */ diff --git a/src/network/mcpe/protocol/BiomeDefinitionListPacket.php b/src/network/mcpe/protocol/BiomeDefinitionListPacket.php index 52afb205f5..6ef0456329 100644 --- a/src/network/mcpe/protocol/BiomeDefinitionListPacket.php +++ b/src/network/mcpe/protocol/BiomeDefinitionListPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\CacheableNbt; class BiomeDefinitionListPacket extends DataPacket implements ClientboundPacket{ @@ -46,11 +46,11 @@ class BiomeDefinitionListPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->defs = new CacheableNbt($in->getNbtCompoundRoot()); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->put($this->defs->getEncodedNbt()); } diff --git a/src/network/mcpe/protocol/BlockActorDataPacket.php b/src/network/mcpe/protocol/BlockActorDataPacket.php index e5a71d747d..7f111aa5d7 100644 --- a/src/network/mcpe/protocol/BlockActorDataPacket.php +++ b/src/network/mcpe/protocol/BlockActorDataPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\CacheableNbt; class BlockActorDataPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -53,12 +53,12 @@ class BlockActorDataPacket extends DataPacket implements ClientboundPacket, Serv return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $in->getBlockPosition($this->x, $this->y, $this->z); $this->namedtag = new CacheableNbt($in->getNbtCompoundRoot()); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putBlockPosition($this->x, $this->y, $this->z); $out->put($this->namedtag->getEncodedNbt()); } diff --git a/src/network/mcpe/protocol/BlockEventPacket.php b/src/network/mcpe/protocol/BlockEventPacket.php index 2b29bad5bf..bc706c29ed 100644 --- a/src/network/mcpe/protocol/BlockEventPacket.php +++ b/src/network/mcpe/protocol/BlockEventPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class BlockEventPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::BLOCK_EVENT_PACKET; @@ -52,13 +52,13 @@ class BlockEventPacket extends DataPacket implements ClientboundPacket{ return $pk; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $in->getBlockPosition($this->x, $this->y, $this->z); $this->eventType = $in->getVarInt(); $this->eventData = $in->getVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putBlockPosition($this->x, $this->y, $this->z); $out->putVarInt($this->eventType); $out->putVarInt($this->eventData); diff --git a/src/network/mcpe/protocol/BlockPickRequestPacket.php b/src/network/mcpe/protocol/BlockPickRequestPacket.php index 091e788bfc..51a62955ee 100644 --- a/src/network/mcpe/protocol/BlockPickRequestPacket.php +++ b/src/network/mcpe/protocol/BlockPickRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class BlockPickRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::BLOCK_PICK_REQUEST_PACKET; @@ -41,13 +41,13 @@ class BlockPickRequestPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $hotbarSlot; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $in->getSignedBlockPosition($this->blockX, $this->blockY, $this->blockZ); $this->addUserData = $in->getBool(); $this->hotbarSlot = $in->getByte(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putSignedBlockPosition($this->blockX, $this->blockY, $this->blockZ); $out->putBool($this->addUserData); $out->putByte($this->hotbarSlot); diff --git a/src/network/mcpe/protocol/BookEditPacket.php b/src/network/mcpe/protocol/BookEditPacket.php index 4c4a3bd224..f080ad62a7 100644 --- a/src/network/mcpe/protocol/BookEditPacket.php +++ b/src/network/mcpe/protocol/BookEditPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class BookEditPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::BOOK_EDIT_PACKET; @@ -57,7 +57,7 @@ class BookEditPacket extends DataPacket implements ServerboundPacket{ /** @var string */ public $xuid; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->type = $in->getByte(); $this->inventorySlot = $in->getByte(); @@ -85,7 +85,7 @@ class BookEditPacket extends DataPacket implements ServerboundPacket{ } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putByte($this->type); $out->putByte($this->inventorySlot); diff --git a/src/network/mcpe/protocol/BossEventPacket.php b/src/network/mcpe/protocol/BossEventPacket.php index 00ffa78985..46b7f078bd 100644 --- a/src/network/mcpe/protocol/BossEventPacket.php +++ b/src/network/mcpe/protocol/BossEventPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class BossEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::BOSS_EVENT_PACKET; @@ -118,7 +118,7 @@ class BossEventPacket extends DataPacket implements ClientboundPacket, Serverbou return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->bossEid = $in->getEntityUniqueId(); $this->eventType = $in->getUnsignedVarInt(); switch($this->eventType){ @@ -148,7 +148,7 @@ class BossEventPacket extends DataPacket implements ClientboundPacket, Serverbou } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityUniqueId($this->bossEid); $out->putUnsignedVarInt($this->eventType); switch($this->eventType){ diff --git a/src/network/mcpe/protocol/CameraPacket.php b/src/network/mcpe/protocol/CameraPacket.php index f6c5185137..fac61d86cc 100644 --- a/src/network/mcpe/protocol/CameraPacket.php +++ b/src/network/mcpe/protocol/CameraPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class CameraPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CAMERA_PACKET; @@ -35,12 +35,12 @@ class CameraPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $playerUniqueId; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->cameraUniqueId = $in->getEntityUniqueId(); $this->playerUniqueId = $in->getEntityUniqueId(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityUniqueId($this->cameraUniqueId); $out->putEntityUniqueId($this->playerUniqueId); } diff --git a/src/network/mcpe/protocol/ChangeDimensionPacket.php b/src/network/mcpe/protocol/ChangeDimensionPacket.php index 0417f18ef3..7e654b56e2 100644 --- a/src/network/mcpe/protocol/ChangeDimensionPacket.php +++ b/src/network/mcpe/protocol/ChangeDimensionPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ChangeDimensionPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CHANGE_DIMENSION_PACKET; @@ -38,13 +38,13 @@ class ChangeDimensionPacket extends DataPacket implements ClientboundPacket{ /** @var bool */ public $respawn = false; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->dimension = $in->getVarInt(); $this->position = $in->getVector3(); $this->respawn = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putVarInt($this->dimension); $out->putVector3($this->position); $out->putBool($this->respawn); diff --git a/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php b/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php index 20c8691632..25a06caf7c 100644 --- a/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php +++ b/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ChunkRadiusUpdatedPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CHUNK_RADIUS_UPDATED_PACKET; @@ -39,11 +39,11 @@ class ChunkRadiusUpdatedPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->radius = $in->getVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putVarInt($this->radius); } diff --git a/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php b/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php index 028cc16e6c..32ced5d530 100644 --- a/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php +++ b/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use function count; class ClientCacheBlobStatusPacket extends DataPacket implements ServerboundPacket{ @@ -65,7 +65,7 @@ class ClientCacheBlobStatusPacket extends DataPacket implements ServerboundPacke return $this->missHashes; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $hitCount = $in->getUnsignedVarInt(); $missCount = $in->getUnsignedVarInt(); for($i = 0; $i < $hitCount; ++$i){ @@ -76,7 +76,7 @@ class ClientCacheBlobStatusPacket extends DataPacket implements ServerboundPacke } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putUnsignedVarInt(count($this->hitHashes)); $out->putUnsignedVarInt(count($this->missHashes)); foreach($this->hitHashes as $hash){ diff --git a/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php b/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php index f1510669c3..afa4441fa6 100644 --- a/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php +++ b/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\ChunkCacheBlob; use function count; @@ -54,7 +54,7 @@ class ClientCacheMissResponsePacket extends DataPacket implements ClientboundPac return $this->blobs; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ $hash = $in->getLLong(); $payload = $in->getString(); @@ -62,7 +62,7 @@ class ClientCacheMissResponsePacket extends DataPacket implements ClientboundPac } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putUnsignedVarInt(count($this->blobs)); foreach($this->blobs as $blob){ $out->putLLong($blob->getHash()); diff --git a/src/network/mcpe/protocol/ClientCacheStatusPacket.php b/src/network/mcpe/protocol/ClientCacheStatusPacket.php index 261846cc11..15f493cdc1 100644 --- a/src/network/mcpe/protocol/ClientCacheStatusPacket.php +++ b/src/network/mcpe/protocol/ClientCacheStatusPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ClientCacheStatusPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::CLIENT_CACHE_STATUS_PACKET; @@ -43,11 +43,11 @@ class ClientCacheStatusPacket extends DataPacket implements ServerboundPacket{ return $this->enabled; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->enabled = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putBool($this->enabled); } diff --git a/src/network/mcpe/protocol/ClientToServerHandshakePacket.php b/src/network/mcpe/protocol/ClientToServerHandshakePacket.php index dc58eeb8de..7457d27eed 100644 --- a/src/network/mcpe/protocol/ClientToServerHandshakePacket.php +++ b/src/network/mcpe/protocol/ClientToServerHandshakePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ClientToServerHandshakePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::CLIENT_TO_SERVER_HANDSHAKE_PACKET; @@ -34,11 +34,11 @@ class ClientToServerHandshakePacket extends DataPacket implements ServerboundPac return true; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ //No payload } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ //No payload } diff --git a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php index dfaa37f33f..d92077cf1b 100644 --- a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php +++ b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\color\Color; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\protocol\types\MapDecoration; use pocketmine\network\mcpe\protocol\types\MapTrackedObject; @@ -71,7 +71,7 @@ class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPack /** @var Color[][] */ public $colors = []; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->mapId = $in->getEntityUniqueId(); $this->type = $in->getUnsignedVarInt(); $this->dimensionId = $in->getByte(); @@ -132,7 +132,7 @@ class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPack } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityUniqueId($this->mapId); $type = 0; diff --git a/src/network/mcpe/protocol/CommandBlockUpdatePacket.php b/src/network/mcpe/protocol/CommandBlockUpdatePacket.php index ed10a2fea7..2fadff4ec2 100644 --- a/src/network/mcpe/protocol/CommandBlockUpdatePacket.php +++ b/src/network/mcpe/protocol/CommandBlockUpdatePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class CommandBlockUpdatePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::COMMAND_BLOCK_UPDATE_PACKET; @@ -62,7 +62,7 @@ class CommandBlockUpdatePacket extends DataPacket implements ServerboundPacket{ /** @var bool */ public $executeOnFirstTick; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->isBlock = $in->getBool(); if($this->isBlock){ @@ -84,7 +84,7 @@ class CommandBlockUpdatePacket extends DataPacket implements ServerboundPacket{ $this->executeOnFirstTick = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putBool($this->isBlock); if($this->isBlock){ diff --git a/src/network/mcpe/protocol/CommandOutputPacket.php b/src/network/mcpe/protocol/CommandOutputPacket.php index 6a8af61a1f..40470ba10a 100644 --- a/src/network/mcpe/protocol/CommandOutputPacket.php +++ b/src/network/mcpe/protocol/CommandOutputPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; use pocketmine\network\mcpe\protocol\types\command\CommandOutputMessage; use pocketmine\utils\BinaryDataException; @@ -45,7 +45,7 @@ class CommandOutputPacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $unknownString; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->originData = $in->getCommandOriginData(); $this->outputType = $in->getByte(); $this->successCount = $in->getUnsignedVarInt(); @@ -62,7 +62,7 @@ class CommandOutputPacket extends DataPacket implements ClientboundPacket{ /** * @throws BinaryDataException */ - protected function getCommandMessage(NetworkBinaryStream $in) : CommandOutputMessage{ + protected function getCommandMessage(PacketSerializer $in) : CommandOutputMessage{ $message = new CommandOutputMessage(); $message->isInternal = $in->getBool(); @@ -75,7 +75,7 @@ class CommandOutputPacket extends DataPacket implements ClientboundPacket{ return $message; } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putCommandOriginData($this->originData); $out->putByte($this->outputType); $out->putUnsignedVarInt($this->successCount); @@ -90,7 +90,7 @@ class CommandOutputPacket extends DataPacket implements ClientboundPacket{ } } - protected function putCommandMessage(CommandOutputMessage $message, NetworkBinaryStream $out) : void{ + protected function putCommandMessage(CommandOutputMessage $message, PacketSerializer $out) : void{ $out->putBool($message->isInternal); $out->putString($message->messageId); diff --git a/src/network/mcpe/protocol/CommandRequestPacket.php b/src/network/mcpe/protocol/CommandRequestPacket.php index ed9de73580..ecc8f336d7 100644 --- a/src/network/mcpe/protocol/CommandRequestPacket.php +++ b/src/network/mcpe/protocol/CommandRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; class CommandRequestPacket extends DataPacket implements ServerboundPacket{ @@ -38,13 +38,13 @@ class CommandRequestPacket extends DataPacket implements ServerboundPacket{ /** @var bool */ public $isInternal; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->command = $in->getString(); $this->originData = $in->getCommandOriginData(); $this->isInternal = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->command); $out->putCommandOriginData($this->originData); $out->putBool($this->isInternal); diff --git a/src/network/mcpe/protocol/CompletedUsingItemPacket.php b/src/network/mcpe/protocol/CompletedUsingItemPacket.php index 1e02def893..f8fe5357b6 100644 --- a/src/network/mcpe/protocol/CompletedUsingItemPacket.php +++ b/src/network/mcpe/protocol/CompletedUsingItemPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class CompletedUsingItemPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::COMPLETED_USING_ITEM_PACKET; @@ -52,12 +52,12 @@ class CompletedUsingItemPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $action; - public function decodePayload(NetworkBinaryStream $in) : void{ + public function decodePayload(PacketSerializer $in) : void{ $this->itemId = $in->getShort(); $this->action = $in->getLInt(); } - public function encodePayload(NetworkBinaryStream $out) : void{ + public function encodePayload(PacketSerializer $out) : void{ $out->putShort($this->itemId); $out->putLInt($this->action); } diff --git a/src/network/mcpe/protocol/ContainerClosePacket.php b/src/network/mcpe/protocol/ContainerClosePacket.php index 549aa41126..dbfd8a4743 100644 --- a/src/network/mcpe/protocol/ContainerClosePacket.php +++ b/src/network/mcpe/protocol/ContainerClosePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ContainerClosePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::CONTAINER_CLOSE_PACKET; @@ -39,11 +39,11 @@ class ContainerClosePacket extends DataPacket implements ClientboundPacket, Serv return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->windowId = $in->getByte(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putByte($this->windowId); } diff --git a/src/network/mcpe/protocol/ContainerOpenPacket.php b/src/network/mcpe/protocol/ContainerOpenPacket.php index a1bdf1e937..54f5890557 100644 --- a/src/network/mcpe/protocol/ContainerOpenPacket.php +++ b/src/network/mcpe/protocol/ContainerOpenPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ContainerOpenPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CONTAINER_OPEN_PACKET; @@ -65,14 +65,14 @@ class ContainerOpenPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->windowId = $in->getByte(); $this->type = $in->getByte(); $in->getBlockPosition($this->x, $this->y, $this->z); $this->entityUniqueId = $in->getEntityUniqueId(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putByte($this->windowId); $out->putByte($this->type); $out->putBlockPosition($this->x, $this->y, $this->z); diff --git a/src/network/mcpe/protocol/ContainerSetDataPacket.php b/src/network/mcpe/protocol/ContainerSetDataPacket.php index 67a583cc06..9778ef25ef 100644 --- a/src/network/mcpe/protocol/ContainerSetDataPacket.php +++ b/src/network/mcpe/protocol/ContainerSetDataPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ContainerSetDataPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::CONTAINER_SET_DATA_PACKET; @@ -55,13 +55,13 @@ class ContainerSetDataPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->windowId = $in->getByte(); $this->property = $in->getVarInt(); $this->value = $in->getVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putByte($this->windowId); $out->putVarInt($this->property); $out->putVarInt($this->value); diff --git a/src/network/mcpe/protocol/CraftingDataPacket.php b/src/network/mcpe/protocol/CraftingDataPacket.php index 46551c9d3f..335c7efe6e 100644 --- a/src/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/network/mcpe/protocol/CraftingDataPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\PotionContainerChangeRecipe; use pocketmine\network\mcpe\protocol\types\PotionTypeRecipe; use pocketmine\network\mcpe\protocol\types\recipe\FurnaceRecipe; @@ -56,7 +56,7 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{ /** @var bool */ public $cleanRecipes = false; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $recipeCount = $in->getUnsignedVarInt(); for($i = 0; $i < $recipeCount; ++$i){ $recipeType = $in->getVarInt(); @@ -97,7 +97,7 @@ class CraftingDataPacket extends DataPacket implements ClientboundPacket{ $this->cleanRecipes = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putUnsignedVarInt(count($this->entries)); foreach($this->entries as $d){ $out->putVarInt($d->getTypeId()); diff --git a/src/network/mcpe/protocol/CraftingEventPacket.php b/src/network/mcpe/protocol/CraftingEventPacket.php index 744de3c565..e2dd9bddce 100644 --- a/src/network/mcpe/protocol/CraftingEventPacket.php +++ b/src/network/mcpe/protocol/CraftingEventPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\uuid\UUID; use function count; @@ -44,7 +44,7 @@ class CraftingEventPacket extends DataPacket implements ServerboundPacket{ /** @var ItemStack[] */ public $output = []; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->windowId = $in->getByte(); $this->type = $in->getVarInt(); $this->id = $in->getUUID(); @@ -60,7 +60,7 @@ class CraftingEventPacket extends DataPacket implements ServerboundPacket{ } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putByte($this->windowId); $out->putVarInt($this->type); $out->putUUID($this->id); diff --git a/src/network/mcpe/protocol/DataPacket.php b/src/network/mcpe/protocol/DataPacket.php index d77f07e25b..89e8280e4c 100644 --- a/src/network/mcpe/protocol/DataPacket.php +++ b/src/network/mcpe/protocol/DataPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\utils\BinaryDataException; use function get_class; @@ -44,14 +44,14 @@ abstract class DataPacket implements Packet{ /** @var int */ public $recipientSubId = 0; - /** @var NetworkBinaryStream */ + /** @var PacketSerializer */ private $buf; public function __construct(){ - $this->buf = new NetworkBinaryStream(); + $this->buf = new PacketSerializer(); } - public function getBinaryStream() : NetworkBinaryStream{ + public function getBinaryStream() : PacketSerializer{ return $this->buf; } @@ -84,7 +84,7 @@ abstract class DataPacket implements Packet{ * @throws BinaryDataException * @throws \UnexpectedValueException */ - protected function decodeHeader(NetworkBinaryStream $in) : void{ + protected function decodeHeader(PacketSerializer $in) : void{ $header = $in->getUnsignedVarInt(); $pid = $header & self::PID_MASK; if($pid !== static::NETWORK_ID){ @@ -102,7 +102,7 @@ abstract class DataPacket implements Packet{ * @throws PacketDecodeException * @throws BinaryDataException */ - abstract protected function decodePayload(NetworkBinaryStream $in) : void; + abstract protected function decodePayload(PacketSerializer $in) : void; final public function encode() : void{ $this->buf->reset(); @@ -110,7 +110,7 @@ abstract class DataPacket implements Packet{ $this->encodePayload($this->buf); } - protected function encodeHeader(NetworkBinaryStream $out) : void{ + protected function encodeHeader(PacketSerializer $out) : void{ $out->putUnsignedVarInt( static::NETWORK_ID | ($this->senderSubId << self::SENDER_SUBCLIENT_ID_SHIFT) | @@ -121,7 +121,7 @@ abstract class DataPacket implements Packet{ /** * Encodes the packet body, without the packet ID or other generic header fields. */ - abstract protected function encodePayload(NetworkBinaryStream $out) : void; + abstract protected function encodePayload(PacketSerializer $out) : void; /** * @param string $name diff --git a/src/network/mcpe/protocol/DisconnectPacket.php b/src/network/mcpe/protocol/DisconnectPacket.php index 98fa2edbb9..31bd9e509b 100644 --- a/src/network/mcpe/protocol/DisconnectPacket.php +++ b/src/network/mcpe/protocol/DisconnectPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class DisconnectPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::DISCONNECT_PACKET; @@ -52,14 +52,14 @@ class DisconnectPacket extends DataPacket implements ClientboundPacket, Serverbo return true; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->hideDisconnectionScreen = $in->getBool(); if(!$this->hideDisconnectionScreen){ $this->message = $in->getString(); } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putBool($this->hideDisconnectionScreen); if(!$this->hideDisconnectionScreen){ $out->putString($this->message); diff --git a/src/network/mcpe/protocol/EducationSettingsPacket.php b/src/network/mcpe/protocol/EducationSettingsPacket.php index 40345fb181..40198ad842 100644 --- a/src/network/mcpe/protocol/EducationSettingsPacket.php +++ b/src/network/mcpe/protocol/EducationSettingsPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class EducationSettingsPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::EDUCATION_SETTINGS_PACKET; @@ -50,12 +50,12 @@ class EducationSettingsPacket extends DataPacket implements ClientboundPacket{ return $this->hasQuiz; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->codeBuilderDefaultUri = $in->getString(); $this->hasQuiz = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->codeBuilderDefaultUri); $out->putBool($this->hasQuiz); } diff --git a/src/network/mcpe/protocol/EmotePacket.php b/src/network/mcpe/protocol/EmotePacket.php index 7bbf0ec56b..00ece97c1a 100644 --- a/src/network/mcpe/protocol/EmotePacket.php +++ b/src/network/mcpe/protocol/EmotePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class EmotePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::EMOTE_PACKET; @@ -62,13 +62,13 @@ class EmotePacket extends DataPacket implements ClientboundPacket, ServerboundPa return $this->flags; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityRuntimeId = $in->getEntityRuntimeId(); $this->emoteId = $in->getString(); $this->flags = $in->getByte(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityRuntimeId($this->entityRuntimeId); $out->putString($this->emoteId); $out->putByte($this->flags); diff --git a/src/network/mcpe/protocol/EventPacket.php b/src/network/mcpe/protocol/EventPacket.php index ca2e8e6ef0..924163f96e 100644 --- a/src/network/mcpe/protocol/EventPacket.php +++ b/src/network/mcpe/protocol/EventPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class EventPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::EVENT_PACKET; @@ -56,7 +56,7 @@ class EventPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $type; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->playerRuntimeId = $in->getEntityRuntimeId(); $this->eventData = $in->getVarInt(); $this->type = $in->getByte(); @@ -64,7 +64,7 @@ class EventPacket extends DataPacket implements ClientboundPacket{ //TODO: nice confusing mess } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityRuntimeId($this->playerRuntimeId); $out->putVarInt($this->eventData); $out->putByte($this->type); diff --git a/src/network/mcpe/protocol/GameRulesChangedPacket.php b/src/network/mcpe/protocol/GameRulesChangedPacket.php index c39be28403..d9647ea896 100644 --- a/src/network/mcpe/protocol/GameRulesChangedPacket.php +++ b/src/network/mcpe/protocol/GameRulesChangedPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class GameRulesChangedPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::GAME_RULES_CHANGED_PACKET; @@ -36,11 +36,11 @@ class GameRulesChangedPacket extends DataPacket implements ClientboundPacket{ */ public $gameRules = []; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->gameRules = $in->getGameRules(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putGameRules($this->gameRules); } diff --git a/src/network/mcpe/protocol/GuiDataPickItemPacket.php b/src/network/mcpe/protocol/GuiDataPickItemPacket.php index 47cac7f5aa..808cd882a5 100644 --- a/src/network/mcpe/protocol/GuiDataPickItemPacket.php +++ b/src/network/mcpe/protocol/GuiDataPickItemPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class GuiDataPickItemPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::GUI_DATA_PICK_ITEM_PACKET; @@ -37,13 +37,13 @@ class GuiDataPickItemPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $hotbarSlot; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->itemDescription = $in->getString(); $this->itemEffects = $in->getString(); $this->hotbarSlot = $in->getLInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->itemDescription); $out->putString($this->itemEffects); $out->putLInt($this->hotbarSlot); diff --git a/src/network/mcpe/protocol/HurtArmorPacket.php b/src/network/mcpe/protocol/HurtArmorPacket.php index ff24f8e9ae..e01d908b6f 100644 --- a/src/network/mcpe/protocol/HurtArmorPacket.php +++ b/src/network/mcpe/protocol/HurtArmorPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class HurtArmorPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::HURT_ARMOR_PACKET; @@ -33,11 +33,11 @@ class HurtArmorPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $health; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->health = $in->getVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putVarInt($this->health); } diff --git a/src/network/mcpe/protocol/InteractPacket.php b/src/network/mcpe/protocol/InteractPacket.php index d37e00ca77..829d39a81c 100644 --- a/src/network/mcpe/protocol/InteractPacket.php +++ b/src/network/mcpe/protocol/InteractPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class InteractPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::INTERACT_PACKET; @@ -47,7 +47,7 @@ class InteractPacket extends DataPacket implements ServerboundPacket{ /** @var float */ public $z; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->action = $in->getByte(); $this->target = $in->getEntityRuntimeId(); @@ -59,7 +59,7 @@ class InteractPacket extends DataPacket implements ServerboundPacket{ } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putByte($this->action); $out->putEntityRuntimeId($this->target); diff --git a/src/network/mcpe/protocol/InventoryContentPacket.php b/src/network/mcpe/protocol/InventoryContentPacket.php index d39b573b19..67a576d695 100644 --- a/src/network/mcpe/protocol/InventoryContentPacket.php +++ b/src/network/mcpe/protocol/InventoryContentPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use function count; @@ -49,7 +49,7 @@ class InventoryContentPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->windowId = $in->getUnsignedVarInt(); $count = $in->getUnsignedVarInt(); for($i = 0; $i < $count; ++$i){ @@ -57,7 +57,7 @@ class InventoryContentPacket extends DataPacket implements ClientboundPacket{ } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putUnsignedVarInt($this->windowId); $out->putUnsignedVarInt(count($this->items)); foreach($this->items as $item){ diff --git a/src/network/mcpe/protocol/InventorySlotPacket.php b/src/network/mcpe/protocol/InventorySlotPacket.php index 9077f21c17..86b071d0f3 100644 --- a/src/network/mcpe/protocol/InventorySlotPacket.php +++ b/src/network/mcpe/protocol/InventorySlotPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; class InventorySlotPacket extends DataPacket implements ClientboundPacket{ @@ -47,13 +47,13 @@ class InventorySlotPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->windowId = $in->getUnsignedVarInt(); $this->inventorySlot = $in->getUnsignedVarInt(); $this->item = $in->getSlot(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putUnsignedVarInt($this->windowId); $out->putUnsignedVarInt($this->inventorySlot); $out->putSlot($this->item); diff --git a/src/network/mcpe/protocol/InventoryTransactionPacket.php b/src/network/mcpe/protocol/InventoryTransactionPacket.php index d554ae4b80..3959f0542c 100644 --- a/src/network/mcpe/protocol/InventoryTransactionPacket.php +++ b/src/network/mcpe/protocol/InventoryTransactionPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\inventory\MismatchTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\NormalTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData; @@ -48,7 +48,7 @@ class InventoryTransactionPacket extends DataPacket implements ClientboundPacket /** @var TransactionData */ public $trData; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $transactionType = $in->getUnsignedVarInt(); switch($transactionType){ @@ -74,7 +74,7 @@ class InventoryTransactionPacket extends DataPacket implements ClientboundPacket $this->trData->decode($in); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putUnsignedVarInt($this->trData->getTypeId()); $this->trData->encode($out); } diff --git a/src/network/mcpe/protocol/ItemFrameDropItemPacket.php b/src/network/mcpe/protocol/ItemFrameDropItemPacket.php index 872565698a..f09998e67d 100644 --- a/src/network/mcpe/protocol/ItemFrameDropItemPacket.php +++ b/src/network/mcpe/protocol/ItemFrameDropItemPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ItemFrameDropItemPacket extends DataPacket implements ServerboundPacket{ @@ -38,11 +38,11 @@ class ItemFrameDropItemPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $z; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $in->getBlockPosition($this->x, $this->y, $this->z); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putBlockPosition($this->x, $this->y, $this->z); } diff --git a/src/network/mcpe/protocol/LabTablePacket.php b/src/network/mcpe/protocol/LabTablePacket.php index 1e79cc5434..375572c3c4 100644 --- a/src/network/mcpe/protocol/LabTablePacket.php +++ b/src/network/mcpe/protocol/LabTablePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class LabTablePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::LAB_TABLE_PACKET; @@ -47,13 +47,13 @@ class LabTablePacket extends DataPacket implements ClientboundPacket, Serverboun /** @var int */ public $reactionType; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->type = $in->getByte(); $in->getSignedBlockPosition($this->x, $this->y, $this->z); $this->reactionType = $in->getByte(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putByte($this->type); $out->putSignedBlockPosition($this->x, $this->y, $this->z); $out->putByte($this->reactionType); diff --git a/src/network/mcpe/protocol/LecternUpdatePacket.php b/src/network/mcpe/protocol/LecternUpdatePacket.php index ebc74afd70..9ce58e55e7 100644 --- a/src/network/mcpe/protocol/LecternUpdatePacket.php +++ b/src/network/mcpe/protocol/LecternUpdatePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class LecternUpdatePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::LECTERN_UPDATE_PACKET; @@ -43,14 +43,14 @@ class LecternUpdatePacket extends DataPacket implements ServerboundPacket{ /** @var bool */ public $dropBook; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->page = $in->getByte(); $this->totalPages = $in->getByte(); $in->getBlockPosition($this->x, $this->y, $this->z); $this->dropBook = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putByte($this->page); $out->putByte($this->totalPages); $out->putBlockPosition($this->x, $this->y, $this->z); diff --git a/src/network/mcpe/protocol/LevelChunkPacket.php b/src/network/mcpe/protocol/LevelChunkPacket.php index bcbd0dd41f..bbbe2dd987 100644 --- a/src/network/mcpe/protocol/LevelChunkPacket.php +++ b/src/network/mcpe/protocol/LevelChunkPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use function count; class LevelChunkPacket extends DataPacket implements ClientboundPacket{ @@ -100,7 +100,7 @@ class LevelChunkPacket extends DataPacket implements ClientboundPacket{ return $this->extraPayload; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->chunkX = $in->getVarInt(); $this->chunkZ = $in->getVarInt(); $this->subChunkCount = $in->getUnsignedVarInt(); @@ -113,7 +113,7 @@ class LevelChunkPacket extends DataPacket implements ClientboundPacket{ $this->extraPayload = $in->getString(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putVarInt($this->chunkX); $out->putVarInt($this->chunkZ); $out->putUnsignedVarInt($this->subChunkCount); diff --git a/src/network/mcpe/protocol/LevelEventGenericPacket.php b/src/network/mcpe/protocol/LevelEventGenericPacket.php index ade936c3e3..d538c66581 100644 --- a/src/network/mcpe/protocol/LevelEventGenericPacket.php +++ b/src/network/mcpe/protocol/LevelEventGenericPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\CacheableNbt; class LevelEventGenericPacket extends DataPacket implements ClientboundPacket{ @@ -58,12 +58,12 @@ class LevelEventGenericPacket extends DataPacket implements ClientboundPacket{ return $this->eventData; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->eventId = $in->getVarInt(); $this->eventData = new CacheableNbt($in->getNbtCompoundRoot()); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putVarInt($this->eventId); $out->put($this->eventData->getEncodedNbt()); } diff --git a/src/network/mcpe/protocol/LevelEventPacket.php b/src/network/mcpe/protocol/LevelEventPacket.php index 31f76242e1..6e560f91b7 100644 --- a/src/network/mcpe/protocol/LevelEventPacket.php +++ b/src/network/mcpe/protocol/LevelEventPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class LevelEventPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::LEVEL_EVENT_PACKET; @@ -133,13 +133,13 @@ class LevelEventPacket extends DataPacket implements ClientboundPacket{ return self::create(self::EVENT_ADD_PARTICLE_MASK | $particleId, $data, $pos); } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->evid = $in->getVarInt(); $this->position = $in->getVector3(); $this->data = $in->getVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putVarInt($this->evid); $out->putVector3Nullable($this->position); $out->putVarInt($this->data); diff --git a/src/network/mcpe/protocol/LevelSoundEventPacket.php b/src/network/mcpe/protocol/LevelSoundEventPacket.php index ec424b2c6b..6c1311a8a8 100644 --- a/src/network/mcpe/protocol/LevelSoundEventPacket.php +++ b/src/network/mcpe/protocol/LevelSoundEventPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class LevelSoundEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::LEVEL_SOUND_EVENT_PACKET; @@ -335,7 +335,7 @@ class LevelSoundEventPacket extends DataPacket implements ClientboundPacket, Ser /** @var bool */ public $disableRelativeVolume = false; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->sound = $in->getUnsignedVarInt(); $this->position = $in->getVector3(); $this->extraData = $in->getVarInt(); @@ -344,7 +344,7 @@ class LevelSoundEventPacket extends DataPacket implements ClientboundPacket, Ser $this->disableRelativeVolume = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putUnsignedVarInt($this->sound); $out->putVector3($this->position); $out->putVarInt($this->extraData); diff --git a/src/network/mcpe/protocol/LevelSoundEventPacketV1.php b/src/network/mcpe/protocol/LevelSoundEventPacketV1.php index b6c7de132e..213db6f716 100644 --- a/src/network/mcpe/protocol/LevelSoundEventPacketV1.php +++ b/src/network/mcpe/protocol/LevelSoundEventPacketV1.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; /** * Useless leftover from a 1.8 refactor, does nothing @@ -47,7 +47,7 @@ class LevelSoundEventPacketV1 extends DataPacket{ /** @var bool */ public $disableRelativeVolume = false; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->sound = $in->getByte(); $this->position = $in->getVector3(); $this->extraData = $in->getVarInt(); @@ -56,7 +56,7 @@ class LevelSoundEventPacketV1 extends DataPacket{ $this->disableRelativeVolume = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putByte($this->sound); $out->putVector3($this->position); $out->putVarInt($this->extraData); diff --git a/src/network/mcpe/protocol/LevelSoundEventPacketV2.php b/src/network/mcpe/protocol/LevelSoundEventPacketV2.php index 29c7c64a0f..934004602c 100644 --- a/src/network/mcpe/protocol/LevelSoundEventPacketV2.php +++ b/src/network/mcpe/protocol/LevelSoundEventPacketV2.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; /** * Useless leftover from a 1.9 refactor, does nothing @@ -47,7 +47,7 @@ class LevelSoundEventPacketV2 extends DataPacket{ /** @var bool */ public $disableRelativeVolume = false; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->sound = $in->getByte(); $this->position = $in->getVector3(); $this->extraData = $in->getVarInt(); @@ -56,7 +56,7 @@ class LevelSoundEventPacketV2 extends DataPacket{ $this->disableRelativeVolume = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putByte($this->sound); $out->putVector3($this->position); $out->putVarInt($this->extraData); diff --git a/src/network/mcpe/protocol/LoginPacket.php b/src/network/mcpe/protocol/LoginPacket.php index ec1903d2d1..615afa1384 100644 --- a/src/network/mcpe/protocol/LoginPacket.php +++ b/src/network/mcpe/protocol/LoginPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\login\JwtChain; use pocketmine\utils\BinaryStream; use function is_object; @@ -49,7 +49,7 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ return true; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->protocol = $in->getInt(); $this->decodeConnectionRequest($in->getString()); } @@ -74,7 +74,7 @@ class LoginPacket extends DataPacket implements ServerboundPacket{ $this->clientDataJwt = $connRequestReader->get($connRequestReader->getLInt()); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putInt($this->protocol); $out->putString($this->encodeConnectionRequest()); } diff --git a/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php b/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php index 7c3b9a1f94..2c74b60e1a 100644 --- a/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php +++ b/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class MapCreateLockedCopyPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MAP_CREATE_LOCKED_COPY_PACKET; @@ -35,12 +35,12 @@ class MapCreateLockedCopyPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $newMapId; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->originalMapId = $in->getEntityUniqueId(); $this->newMapId = $in->getEntityUniqueId(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityUniqueId($this->originalMapId); $out->putEntityUniqueId($this->newMapId); } diff --git a/src/network/mcpe/protocol/MapInfoRequestPacket.php b/src/network/mcpe/protocol/MapInfoRequestPacket.php index d7a09dae1d..7d8ac82f05 100644 --- a/src/network/mcpe/protocol/MapInfoRequestPacket.php +++ b/src/network/mcpe/protocol/MapInfoRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class MapInfoRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MAP_INFO_REQUEST_PACKET; @@ -33,11 +33,11 @@ class MapInfoRequestPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $mapId; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->mapId = $in->getEntityUniqueId(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityUniqueId($this->mapId); } diff --git a/src/network/mcpe/protocol/MobArmorEquipmentPacket.php b/src/network/mcpe/protocol/MobArmorEquipmentPacket.php index ea830ee4c2..b7e9ed301d 100644 --- a/src/network/mcpe/protocol/MobArmorEquipmentPacket.php +++ b/src/network/mcpe/protocol/MobArmorEquipmentPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; class MobArmorEquipmentPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -56,7 +56,7 @@ class MobArmorEquipmentPacket extends DataPacket implements ClientboundPacket, S return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityRuntimeId = $in->getEntityRuntimeId(); $this->head = $in->getSlot(); $this->chest = $in->getSlot(); @@ -64,7 +64,7 @@ class MobArmorEquipmentPacket extends DataPacket implements ClientboundPacket, S $this->feet = $in->getSlot(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityRuntimeId($this->entityRuntimeId); $out->putSlot($this->head); $out->putSlot($this->chest); diff --git a/src/network/mcpe/protocol/MobEffectPacket.php b/src/network/mcpe/protocol/MobEffectPacket.php index 1e7beb3f44..7265c22535 100644 --- a/src/network/mcpe/protocol/MobEffectPacket.php +++ b/src/network/mcpe/protocol/MobEffectPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class MobEffectPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::MOB_EFFECT_PACKET; @@ -66,7 +66,7 @@ class MobEffectPacket extends DataPacket implements ClientboundPacket{ return $pk; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityRuntimeId = $in->getEntityRuntimeId(); $this->eventId = $in->getByte(); $this->effectId = $in->getVarInt(); @@ -75,7 +75,7 @@ class MobEffectPacket extends DataPacket implements ClientboundPacket{ $this->duration = $in->getVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityRuntimeId($this->entityRuntimeId); $out->putByte($this->eventId); $out->putVarInt($this->effectId); diff --git a/src/network/mcpe/protocol/MobEquipmentPacket.php b/src/network/mcpe/protocol/MobEquipmentPacket.php index f3abb8fd6f..083b2f6b2a 100644 --- a/src/network/mcpe/protocol/MobEquipmentPacket.php +++ b/src/network/mcpe/protocol/MobEquipmentPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; class MobEquipmentPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -52,7 +52,7 @@ class MobEquipmentPacket extends DataPacket implements ClientboundPacket, Server return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityRuntimeId = $in->getEntityRuntimeId(); $this->item = $in->getSlot(); $this->inventorySlot = $in->getByte(); @@ -60,7 +60,7 @@ class MobEquipmentPacket extends DataPacket implements ClientboundPacket, Server $this->windowId = $in->getByte(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityRuntimeId($this->entityRuntimeId); $out->putSlot($this->item); $out->putByte($this->inventorySlot); diff --git a/src/network/mcpe/protocol/ModalFormRequestPacket.php b/src/network/mcpe/protocol/ModalFormRequestPacket.php index 60138ab91a..0d00021e3a 100644 --- a/src/network/mcpe/protocol/ModalFormRequestPacket.php +++ b/src/network/mcpe/protocol/ModalFormRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ModalFormRequestPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::MODAL_FORM_REQUEST_PACKET; @@ -42,12 +42,12 @@ class ModalFormRequestPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->formId = $in->getUnsignedVarInt(); $this->formData = $in->getString(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putUnsignedVarInt($this->formId); $out->putString($this->formData); } diff --git a/src/network/mcpe/protocol/ModalFormResponsePacket.php b/src/network/mcpe/protocol/ModalFormResponsePacket.php index ab7bded1f3..1d7d552a5d 100644 --- a/src/network/mcpe/protocol/ModalFormResponsePacket.php +++ b/src/network/mcpe/protocol/ModalFormResponsePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ModalFormResponsePacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MODAL_FORM_RESPONSE_PACKET; @@ -35,12 +35,12 @@ class ModalFormResponsePacket extends DataPacket implements ServerboundPacket{ /** @var string */ public $formData; //json - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->formId = $in->getUnsignedVarInt(); $this->formData = $in->getString(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putUnsignedVarInt($this->formId); $out->putString($this->formData); } diff --git a/src/network/mcpe/protocol/MoveActorAbsolutePacket.php b/src/network/mcpe/protocol/MoveActorAbsolutePacket.php index cbe4ce444c..2844b3a5be 100644 --- a/src/network/mcpe/protocol/MoveActorAbsolutePacket.php +++ b/src/network/mcpe/protocol/MoveActorAbsolutePacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class MoveActorAbsolutePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MOVE_ACTOR_ABSOLUTE_PACKET; @@ -48,7 +48,7 @@ class MoveActorAbsolutePacket extends DataPacket implements ClientboundPacket, S /** @var float */ public $zRot; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityRuntimeId = $in->getEntityRuntimeId(); $this->flags = $in->getByte(); $this->position = $in->getVector3(); @@ -57,7 +57,7 @@ class MoveActorAbsolutePacket extends DataPacket implements ClientboundPacket, S $this->zRot = $in->getByteRotation(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityRuntimeId($this->entityRuntimeId); $out->putByte($this->flags); $out->putVector3($this->position); diff --git a/src/network/mcpe/protocol/MoveActorDeltaPacket.php b/src/network/mcpe/protocol/MoveActorDeltaPacket.php index d4dc927c3c..7f10c3d2dd 100644 --- a/src/network/mcpe/protocol/MoveActorDeltaPacket.php +++ b/src/network/mcpe/protocol/MoveActorDeltaPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\utils\BinaryDataException; class MoveActorDeltaPacket extends DataPacket implements ClientboundPacket{ @@ -61,7 +61,7 @@ class MoveActorDeltaPacket extends DataPacket implements ClientboundPacket{ /** * @throws BinaryDataException */ - private function maybeReadCoord(int $flag, NetworkBinaryStream $in) : int{ + private function maybeReadCoord(int $flag, PacketSerializer $in) : int{ if(($this->flags & $flag) !== 0){ return $in->getVarInt(); } @@ -71,14 +71,14 @@ class MoveActorDeltaPacket extends DataPacket implements ClientboundPacket{ /** * @throws BinaryDataException */ - private function maybeReadRotation(int $flag, NetworkBinaryStream $in) : float{ + private function maybeReadRotation(int $flag, PacketSerializer $in) : float{ if(($this->flags & $flag) !== 0){ return $in->getByteRotation(); } return 0.0; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityRuntimeId = $in->getEntityRuntimeId(); $this->flags = $in->getLShort(); $this->xDiff = $this->maybeReadCoord(self::FLAG_HAS_X, $in); @@ -89,19 +89,19 @@ class MoveActorDeltaPacket extends DataPacket implements ClientboundPacket{ $this->zRot = $this->maybeReadRotation(self::FLAG_HAS_ROT_Z, $in); } - private function maybeWriteCoord(int $flag, int $val, NetworkBinaryStream $out) : void{ + private function maybeWriteCoord(int $flag, int $val, PacketSerializer $out) : void{ if(($this->flags & $flag) !== 0){ $out->putVarInt($val); } } - private function maybeWriteRotation(int $flag, float $val, NetworkBinaryStream $out) : void{ + private function maybeWriteRotation(int $flag, float $val, PacketSerializer $out) : void{ if(($this->flags & $flag) !== 0){ $out->putByteRotation($val); } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityRuntimeId($this->entityRuntimeId); $out->putLShort($this->flags); $this->maybeWriteCoord(self::FLAG_HAS_X, $this->xDiff, $out); diff --git a/src/network/mcpe/protocol/MovePlayerPacket.php b/src/network/mcpe/protocol/MovePlayerPacket.php index cf2a3a8b7a..19b0e6aad0 100644 --- a/src/network/mcpe/protocol/MovePlayerPacket.php +++ b/src/network/mcpe/protocol/MovePlayerPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class MovePlayerPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MOVE_PLAYER_PACKET; @@ -57,7 +57,7 @@ class MovePlayerPacket extends DataPacket implements ClientboundPacket, Serverbo /** @var int */ public $teleportItem = 0; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityRuntimeId = $in->getEntityRuntimeId(); $this->position = $in->getVector3(); $this->pitch = $in->getLFloat(); @@ -72,7 +72,7 @@ class MovePlayerPacket extends DataPacket implements ClientboundPacket, Serverbo } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityRuntimeId($this->entityRuntimeId); $out->putVector3($this->position); $out->putLFloat($this->pitch); diff --git a/src/network/mcpe/protocol/MultiplayerSettingsPacket.php b/src/network/mcpe/protocol/MultiplayerSettingsPacket.php index ef0a192faa..0c635b5179 100644 --- a/src/network/mcpe/protocol/MultiplayerSettingsPacket.php +++ b/src/network/mcpe/protocol/MultiplayerSettingsPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class MultiplayerSettingsPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::MULTIPLAYER_SETTINGS_PACKET; @@ -47,11 +47,11 @@ class MultiplayerSettingsPacket extends DataPacket implements ClientboundPacket, return $this->action; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->action = $in->getVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putVarInt($this->action); } diff --git a/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php b/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php index 845664bba5..32aeb02740 100644 --- a/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php +++ b/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class NetworkChunkPublisherUpdatePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::NETWORK_CHUNK_PUBLISHER_UPDATE_PACKET; @@ -48,12 +48,12 @@ class NetworkChunkPublisherUpdatePacket extends DataPacket implements Clientboun return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $in->getSignedBlockPosition($this->x, $this->y, $this->z); $this->radius = $in->getUnsignedVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putSignedBlockPosition($this->x, $this->y, $this->z); $out->putUnsignedVarInt($this->radius); } diff --git a/src/network/mcpe/protocol/NetworkSettingsPacket.php b/src/network/mcpe/protocol/NetworkSettingsPacket.php index 4651b371d0..77477d1299 100644 --- a/src/network/mcpe/protocol/NetworkSettingsPacket.php +++ b/src/network/mcpe/protocol/NetworkSettingsPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class NetworkSettingsPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::NETWORK_SETTINGS_PACKET; @@ -46,11 +46,11 @@ class NetworkSettingsPacket extends DataPacket implements ClientboundPacket{ return $this->compressionThreshold; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->compressionThreshold = $in->getLShort(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putLShort($this->compressionThreshold); } diff --git a/src/network/mcpe/protocol/NetworkStackLatencyPacket.php b/src/network/mcpe/protocol/NetworkStackLatencyPacket.php index d05b7ee01f..559f4c5287 100644 --- a/src/network/mcpe/protocol/NetworkStackLatencyPacket.php +++ b/src/network/mcpe/protocol/NetworkStackLatencyPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class NetworkStackLatencyPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::NETWORK_STACK_LATENCY_PACKET; @@ -35,12 +35,12 @@ class NetworkStackLatencyPacket extends DataPacket implements ClientboundPacket, /** @var bool */ public $needResponse; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->timestamp = $in->getLLong(); $this->needResponse = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putLLong($this->timestamp); $out->putBool($this->needResponse); } diff --git a/src/network/mcpe/protocol/NpcRequestPacket.php b/src/network/mcpe/protocol/NpcRequestPacket.php index a2a1c94af7..fb007fce2f 100644 --- a/src/network/mcpe/protocol/NpcRequestPacket.php +++ b/src/network/mcpe/protocol/NpcRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class NpcRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::NPC_REQUEST_PACKET; @@ -46,14 +46,14 @@ class NpcRequestPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $actionType; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityRuntimeId = $in->getEntityRuntimeId(); $this->requestType = $in->getByte(); $this->commandString = $in->getString(); $this->actionType = $in->getByte(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityRuntimeId($this->entityRuntimeId); $out->putByte($this->requestType); $out->putString($this->commandString); diff --git a/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php b/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php index b7fb8e81e6..80d66b37a9 100644 --- a/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php +++ b/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class OnScreenTextureAnimationPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ON_SCREEN_TEXTURE_ANIMATION_PACKET; @@ -33,11 +33,11 @@ class OnScreenTextureAnimationPacket extends DataPacket implements ClientboundPa /** @var int */ public $effectId; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->effectId = $in->getLInt(); //unsigned } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putLInt($this->effectId); } diff --git a/src/network/mcpe/protocol/Packet.php b/src/network/mcpe/protocol/Packet.php index f631040e1f..d2aff314dd 100644 --- a/src/network/mcpe/protocol/Packet.php +++ b/src/network/mcpe/protocol/Packet.php @@ -23,11 +23,11 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; interface Packet{ - public function getBinaryStream() : NetworkBinaryStream; + public function getBinaryStream() : PacketSerializer; public function pid() : int; diff --git a/src/network/mcpe/protocol/PhotoTransferPacket.php b/src/network/mcpe/protocol/PhotoTransferPacket.php index 67222f8ece..ccaf0eb510 100644 --- a/src/network/mcpe/protocol/PhotoTransferPacket.php +++ b/src/network/mcpe/protocol/PhotoTransferPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class PhotoTransferPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::PHOTO_TRANSFER_PACKET; @@ -37,13 +37,13 @@ class PhotoTransferPacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $bookId; //photos are stored in a sibling directory to the games folder (screenshots/(some UUID)/bookID/example.png) - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->photoName = $in->getString(); $this->photoData = $in->getString(); $this->bookId = $in->getString(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->photoName); $out->putString($this->photoData); $out->putString($this->bookId); diff --git a/src/network/mcpe/protocol/PlaySoundPacket.php b/src/network/mcpe/protocol/PlaySoundPacket.php index 17cbdeb86a..7384145fae 100644 --- a/src/network/mcpe/protocol/PlaySoundPacket.php +++ b/src/network/mcpe/protocol/PlaySoundPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class PlaySoundPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAY_SOUND_PACKET; @@ -43,7 +43,7 @@ class PlaySoundPacket extends DataPacket implements ClientboundPacket{ /** @var float */ public $pitch; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->soundName = $in->getString(); $in->getBlockPosition($this->x, $this->y, $this->z); $this->x /= 8; @@ -53,7 +53,7 @@ class PlaySoundPacket extends DataPacket implements ClientboundPacket{ $this->pitch = $in->getLFloat(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->soundName); $out->putBlockPosition((int) ($this->x * 8), (int) ($this->y * 8), (int) ($this->z * 8)); $out->putLFloat($this->volume); diff --git a/src/network/mcpe/protocol/PlayStatusPacket.php b/src/network/mcpe/protocol/PlayStatusPacket.php index 7fb52ebd81..98aec071cf 100644 --- a/src/network/mcpe/protocol/PlayStatusPacket.php +++ b/src/network/mcpe/protocol/PlayStatusPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class PlayStatusPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAY_STATUS_PACKET; @@ -48,7 +48,7 @@ class PlayStatusPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->status = $in->getInt(); } @@ -56,7 +56,7 @@ class PlayStatusPacket extends DataPacket implements ClientboundPacket{ return true; } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putInt($this->status); } diff --git a/src/network/mcpe/protocol/PlayerActionPacket.php b/src/network/mcpe/protocol/PlayerActionPacket.php index 1794944016..d34a10c670 100644 --- a/src/network/mcpe/protocol/PlayerActionPacket.php +++ b/src/network/mcpe/protocol/PlayerActionPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class PlayerActionPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAYER_ACTION_PACKET; @@ -70,14 +70,14 @@ class PlayerActionPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $face; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityRuntimeId = $in->getEntityRuntimeId(); $this->action = $in->getVarInt(); $in->getBlockPosition($this->x, $this->y, $this->z); $this->face = $in->getVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityRuntimeId($this->entityRuntimeId); $out->putVarInt($this->action); $out->putBlockPosition($this->x, $this->y, $this->z); diff --git a/src/network/mcpe/protocol/PlayerAuthInputPacket.php b/src/network/mcpe/protocol/PlayerAuthInputPacket.php index 2a5fa871e7..8c5b089d51 100644 --- a/src/network/mcpe/protocol/PlayerAuthInputPacket.php +++ b/src/network/mcpe/protocol/PlayerAuthInputPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\InputMode; use pocketmine\network\mcpe\protocol\types\PlayMode; use function assert; @@ -127,7 +127,7 @@ class PlayerAuthInputPacket extends DataPacket implements ServerboundPacket{ return $this->vrGazeDirection; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->yaw = $in->getLFloat(); $this->pitch = $in->getLFloat(); $this->position = $in->getVector3(); @@ -142,7 +142,7 @@ class PlayerAuthInputPacket extends DataPacket implements ServerboundPacket{ } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putLFloat($this->yaw); $out->putLFloat($this->pitch); $out->putVector3($this->position); diff --git a/src/network/mcpe/protocol/PlayerHotbarPacket.php b/src/network/mcpe/protocol/PlayerHotbarPacket.php index 67f8d8b8f2..b6dc141a7f 100644 --- a/src/network/mcpe/protocol/PlayerHotbarPacket.php +++ b/src/network/mcpe/protocol/PlayerHotbarPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; class PlayerHotbarPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -46,13 +46,13 @@ class PlayerHotbarPacket extends DataPacket implements ClientboundPacket, Server return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->selectedHotbarSlot = $in->getUnsignedVarInt(); $this->windowId = $in->getByte(); $this->selectHotbarSlot = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putUnsignedVarInt($this->selectedHotbarSlot); $out->putByte($this->windowId); $out->putBool($this->selectHotbarSlot); diff --git a/src/network/mcpe/protocol/PlayerInputPacket.php b/src/network/mcpe/protocol/PlayerInputPacket.php index a2ec3122a8..5069a66fde 100644 --- a/src/network/mcpe/protocol/PlayerInputPacket.php +++ b/src/network/mcpe/protocol/PlayerInputPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class PlayerInputPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAYER_INPUT_PACKET; @@ -39,14 +39,14 @@ class PlayerInputPacket extends DataPacket implements ServerboundPacket{ /** @var bool */ public $sneaking; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->motionX = $in->getLFloat(); $this->motionY = $in->getLFloat(); $this->jumping = $in->getBool(); $this->sneaking = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putLFloat($this->motionX); $out->putLFloat($this->motionY); $out->putBool($this->jumping); diff --git a/src/network/mcpe/protocol/PlayerListPacket.php b/src/network/mcpe/protocol/PlayerListPacket.php index 462156bf65..54ac6462f8 100644 --- a/src/network/mcpe/protocol/PlayerListPacket.php +++ b/src/network/mcpe/protocol/PlayerListPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use function count; @@ -60,7 +60,7 @@ class PlayerListPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->type = $in->getByte(); $count = $in->getUnsignedVarInt(); for($i = 0; $i < $count; ++$i){ @@ -89,7 +89,7 @@ class PlayerListPacket extends DataPacket implements ClientboundPacket{ } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putByte($this->type); $out->putUnsignedVarInt(count($this->entries)); foreach($this->entries as $entry){ diff --git a/src/network/mcpe/protocol/PlayerSkinPacket.php b/src/network/mcpe/protocol/PlayerSkinPacket.php index 37e335e77a..f13fe08aa6 100644 --- a/src/network/mcpe/protocol/PlayerSkinPacket.php +++ b/src/network/mcpe/protocol/PlayerSkinPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\SkinData; use pocketmine\uuid\UUID; @@ -41,7 +41,7 @@ class PlayerSkinPacket extends DataPacket implements ClientboundPacket, Serverbo /** @var SkinData */ public $skin; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->uuid = $in->getUUID(); $this->skin = $in->getSkin(); $this->newSkinName = $in->getString(); @@ -49,7 +49,7 @@ class PlayerSkinPacket extends DataPacket implements ClientboundPacket, Serverbo $this->skin->setVerified($in->getBool()); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putUUID($this->uuid); $out->putSkin($this->skin); $out->putString($this->newSkinName); diff --git a/src/network/mcpe/protocol/PurchaseReceiptPacket.php b/src/network/mcpe/protocol/PurchaseReceiptPacket.php index 6d3d6e495c..02b5163c70 100644 --- a/src/network/mcpe/protocol/PurchaseReceiptPacket.php +++ b/src/network/mcpe/protocol/PurchaseReceiptPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use function count; class PurchaseReceiptPacket extends DataPacket implements ServerboundPacket{ @@ -34,14 +34,14 @@ class PurchaseReceiptPacket extends DataPacket implements ServerboundPacket{ /** @var string[] */ public $entries = []; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $count = $in->getUnsignedVarInt(); for($i = 0; $i < $count; ++$i){ $this->entries[] = $in->getString(); } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putUnsignedVarInt(count($this->entries)); foreach($this->entries as $entry){ $out->putString($entry); diff --git a/src/network/mcpe/protocol/RemoveActorPacket.php b/src/network/mcpe/protocol/RemoveActorPacket.php index 8f92a97e88..8fdc2a766d 100644 --- a/src/network/mcpe/protocol/RemoveActorPacket.php +++ b/src/network/mcpe/protocol/RemoveActorPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class RemoveActorPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::REMOVE_ACTOR_PACKET; @@ -39,11 +39,11 @@ class RemoveActorPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityUniqueId = $in->getEntityUniqueId(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityUniqueId($this->entityUniqueId); } diff --git a/src/network/mcpe/protocol/RemoveEntityPacket.php b/src/network/mcpe/protocol/RemoveEntityPacket.php index c6c7cd79cf..f2f3344409 100644 --- a/src/network/mcpe/protocol/RemoveEntityPacket.php +++ b/src/network/mcpe/protocol/RemoveEntityPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class RemoveEntityPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::REMOVE_ENTITY_PACKET; @@ -43,11 +43,11 @@ class RemoveEntityPacket extends DataPacket implements ClientboundPacket{ return $this->uvarint1; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->uvarint1 = $in->getUnsignedVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putUnsignedVarInt($this->uvarint1); } diff --git a/src/network/mcpe/protocol/RemoveObjectivePacket.php b/src/network/mcpe/protocol/RemoveObjectivePacket.php index e69121c337..7b4bf22e82 100644 --- a/src/network/mcpe/protocol/RemoveObjectivePacket.php +++ b/src/network/mcpe/protocol/RemoveObjectivePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class RemoveObjectivePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::REMOVE_OBJECTIVE_PACKET; @@ -33,11 +33,11 @@ class RemoveObjectivePacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $objectiveName; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->objectiveName = $in->getString(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->objectiveName); } diff --git a/src/network/mcpe/protocol/RequestChunkRadiusPacket.php b/src/network/mcpe/protocol/RequestChunkRadiusPacket.php index 2df4dd5e31..76cdd84709 100644 --- a/src/network/mcpe/protocol/RequestChunkRadiusPacket.php +++ b/src/network/mcpe/protocol/RequestChunkRadiusPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class RequestChunkRadiusPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::REQUEST_CHUNK_RADIUS_PACKET; @@ -33,11 +33,11 @@ class RequestChunkRadiusPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $radius; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->radius = $in->getVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putVarInt($this->radius); } diff --git a/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php b/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php index 113035ed12..a26db209e6 100644 --- a/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php +++ b/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ResourcePackChunkDataPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_CHUNK_DATA_PACKET; @@ -48,14 +48,14 @@ class ResourcePackChunkDataPacket extends DataPacket implements ClientboundPacke return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->packId = $in->getString(); $this->chunkIndex = $in->getLInt(); $this->progress = $in->getLLong(); $this->data = $in->getString(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->packId); $out->putLInt($this->chunkIndex); $out->putLLong($this->progress); diff --git a/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php b/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php index fb5adb68ee..30ea02cd84 100644 --- a/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php +++ b/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ResourcePackChunkRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_CHUNK_REQUEST_PACKET; @@ -35,12 +35,12 @@ class ResourcePackChunkRequestPacket extends DataPacket implements ServerboundPa /** @var int */ public $chunkIndex; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->packId = $in->getString(); $this->chunkIndex = $in->getLInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->packId); $out->putLInt($this->chunkIndex); } diff --git a/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php b/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php index de6994557a..5907160263 100644 --- a/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php +++ b/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use function count; class ResourcePackClientResponsePacket extends DataPacket implements ServerboundPacket{ @@ -41,7 +41,7 @@ class ResourcePackClientResponsePacket extends DataPacket implements Serverbound /** @var string[] */ public $packIds = []; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->status = $in->getByte(); $entryCount = $in->getLShort(); while($entryCount-- > 0){ @@ -49,7 +49,7 @@ class ResourcePackClientResponsePacket extends DataPacket implements Serverbound } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putByte($this->status); $out->putLShort(count($this->packIds)); foreach($this->packIds as $id){ diff --git a/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php b/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php index 37e07589df..a7ed482534 100644 --- a/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php +++ b/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackType; class ResourcePackDataInfoPacket extends DataPacket implements ClientboundPacket{ @@ -56,7 +56,7 @@ class ResourcePackDataInfoPacket extends DataPacket implements ClientboundPacket return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->packId = $in->getString(); $this->maxChunkSize = $in->getLInt(); $this->chunkCount = $in->getLInt(); @@ -66,7 +66,7 @@ class ResourcePackDataInfoPacket extends DataPacket implements ClientboundPacket $this->packType = $in->getByte(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->packId); $out->putLInt($this->maxChunkSize); $out->putLInt($this->chunkCount); diff --git a/src/network/mcpe/protocol/ResourcePackStackPacket.php b/src/network/mcpe/protocol/ResourcePackStackPacket.php index 4391599624..b18963a61d 100644 --- a/src/network/mcpe/protocol/ResourcePackStackPacket.php +++ b/src/network/mcpe/protocol/ResourcePackStackPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackStackEntry; use function count; @@ -60,7 +60,7 @@ class ResourcePackStackPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->mustAccept = $in->getBool(); $behaviorPackCount = $in->getUnsignedVarInt(); while($behaviorPackCount-- > 0){ @@ -76,7 +76,7 @@ class ResourcePackStackPacket extends DataPacket implements ClientboundPacket{ $this->baseGameVersion = $in->getString(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putBool($this->mustAccept); $out->putUnsignedVarInt(count($this->behaviorPackStack)); diff --git a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php index 7cd76f11a0..e70f4f9458 100644 --- a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php +++ b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackInfoEntry; use function count; @@ -56,7 +56,7 @@ class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->mustAccept = $in->getBool(); $this->hasScripts = $in->getBool(); $behaviorPackCount = $in->getLShort(); @@ -70,7 +70,7 @@ class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putBool($this->mustAccept); $out->putBool($this->hasScripts); $out->putLShort(count($this->behaviorPackEntries)); diff --git a/src/network/mcpe/protocol/RespawnPacket.php b/src/network/mcpe/protocol/RespawnPacket.php index 0e6604ee39..4bf6945173 100644 --- a/src/network/mcpe/protocol/RespawnPacket.php +++ b/src/network/mcpe/protocol/RespawnPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class RespawnPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::RESPAWN_PACKET; @@ -50,13 +50,13 @@ class RespawnPacket extends DataPacket implements ClientboundPacket, Serverbound return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->position = $in->getVector3(); $this->respawnState = $in->getByte(); $this->entityRuntimeId = $in->getEntityRuntimeId(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putVector3($this->position); $out->putByte($this->respawnState); $out->putEntityRuntimeId($this->entityRuntimeId); diff --git a/src/network/mcpe/protocol/RiderJumpPacket.php b/src/network/mcpe/protocol/RiderJumpPacket.php index 5e2b1bc197..d7186968b7 100644 --- a/src/network/mcpe/protocol/RiderJumpPacket.php +++ b/src/network/mcpe/protocol/RiderJumpPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class RiderJumpPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::RIDER_JUMP_PACKET; @@ -33,11 +33,11 @@ class RiderJumpPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $jumpStrength; //percentage - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->jumpStrength = $in->getVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putVarInt($this->jumpStrength); } diff --git a/src/network/mcpe/protocol/ScriptCustomEventPacket.php b/src/network/mcpe/protocol/ScriptCustomEventPacket.php index 7c0cf70ccf..17be40ff91 100644 --- a/src/network/mcpe/protocol/ScriptCustomEventPacket.php +++ b/src/network/mcpe/protocol/ScriptCustomEventPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ScriptCustomEventPacket extends DataPacket{ //TODO: this doesn't have handlers in either client or server in the game as of 1.8 public const NETWORK_ID = ProtocolInfo::SCRIPT_CUSTOM_EVENT_PACKET; @@ -35,12 +35,12 @@ class ScriptCustomEventPacket extends DataPacket{ //TODO: this doesn't have hand /** @var string json data */ public $eventData; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->eventName = $in->getString(); $this->eventData = $in->getString(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->eventName); $out->putString($this->eventData); } diff --git a/src/network/mcpe/protocol/ServerSettingsRequestPacket.php b/src/network/mcpe/protocol/ServerSettingsRequestPacket.php index 4a4367cb0e..9d1e60b35e 100644 --- a/src/network/mcpe/protocol/ServerSettingsRequestPacket.php +++ b/src/network/mcpe/protocol/ServerSettingsRequestPacket.php @@ -25,16 +25,16 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ServerSettingsRequestPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SERVER_SETTINGS_REQUEST_PACKET; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ //No payload } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ //No payload } diff --git a/src/network/mcpe/protocol/ServerSettingsResponsePacket.php b/src/network/mcpe/protocol/ServerSettingsResponsePacket.php index da6aee42aa..b1fd1a2708 100644 --- a/src/network/mcpe/protocol/ServerSettingsResponsePacket.php +++ b/src/network/mcpe/protocol/ServerSettingsResponsePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ServerSettingsResponsePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SERVER_SETTINGS_RESPONSE_PACKET; @@ -35,12 +35,12 @@ class ServerSettingsResponsePacket extends DataPacket implements ClientboundPack /** @var string */ public $formData; //json - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->formId = $in->getUnsignedVarInt(); $this->formData = $in->getString(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putUnsignedVarInt($this->formId); $out->putString($this->formData); } diff --git a/src/network/mcpe/protocol/ServerToClientHandshakePacket.php b/src/network/mcpe/protocol/ServerToClientHandshakePacket.php index 0124d94560..19f15ade2d 100644 --- a/src/network/mcpe/protocol/ServerToClientHandshakePacket.php +++ b/src/network/mcpe/protocol/ServerToClientHandshakePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ServerToClientHandshakePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SERVER_TO_CLIENT_HANDSHAKE_PACKET; @@ -46,11 +46,11 @@ class ServerToClientHandshakePacket extends DataPacket implements ClientboundPac return true; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->jwt = $in->getString(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->jwt); } diff --git a/src/network/mcpe/protocol/SetActorDataPacket.php b/src/network/mcpe/protocol/SetActorDataPacket.php index 809172f9e3..864368633c 100644 --- a/src/network/mcpe/protocol/SetActorDataPacket.php +++ b/src/network/mcpe/protocol/SetActorDataPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; class SetActorDataPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ //TODO: check why this is serverbound @@ -51,12 +51,12 @@ class SetActorDataPacket extends DataPacket implements ClientboundPacket, Server return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityRuntimeId = $in->getEntityRuntimeId(); $this->metadata = $in->getEntityMetadata(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityRuntimeId($this->entityRuntimeId); $out->putEntityMetadata($this->metadata); } diff --git a/src/network/mcpe/protocol/SetActorLinkPacket.php b/src/network/mcpe/protocol/SetActorLinkPacket.php index 882ae1bc7b..f8ca170b81 100644 --- a/src/network/mcpe/protocol/SetActorLinkPacket.php +++ b/src/network/mcpe/protocol/SetActorLinkPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; class SetActorLinkPacket extends DataPacket implements ClientboundPacket{ @@ -34,11 +34,11 @@ class SetActorLinkPacket extends DataPacket implements ClientboundPacket{ /** @var EntityLink */ public $link; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->link = $in->getEntityLink(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityLink($this->link); } diff --git a/src/network/mcpe/protocol/SetActorMotionPacket.php b/src/network/mcpe/protocol/SetActorMotionPacket.php index a1d8dc8881..49a5fd9a34 100644 --- a/src/network/mcpe/protocol/SetActorMotionPacket.php +++ b/src/network/mcpe/protocol/SetActorMotionPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; /** * TODO: This packet is (erroneously) sent to the server when the client is riding a vehicle. @@ -46,12 +46,12 @@ class SetActorMotionPacket extends DataPacket implements ClientboundPacket, Garb return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityRuntimeId = $in->getEntityRuntimeId(); $this->motion = $in->getVector3(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityRuntimeId($this->entityRuntimeId); $out->putVector3($this->motion); } diff --git a/src/network/mcpe/protocol/SetCommandsEnabledPacket.php b/src/network/mcpe/protocol/SetCommandsEnabledPacket.php index c772854af3..bf094e2bf6 100644 --- a/src/network/mcpe/protocol/SetCommandsEnabledPacket.php +++ b/src/network/mcpe/protocol/SetCommandsEnabledPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class SetCommandsEnabledPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_COMMANDS_ENABLED_PACKET; @@ -33,11 +33,11 @@ class SetCommandsEnabledPacket extends DataPacket implements ClientboundPacket{ /** @var bool */ public $enabled; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->enabled = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putBool($this->enabled); } diff --git a/src/network/mcpe/protocol/SetDefaultGameTypePacket.php b/src/network/mcpe/protocol/SetDefaultGameTypePacket.php index 7791d2c822..63cd53f653 100644 --- a/src/network/mcpe/protocol/SetDefaultGameTypePacket.php +++ b/src/network/mcpe/protocol/SetDefaultGameTypePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class SetDefaultGameTypePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_DEFAULT_GAME_TYPE_PACKET; @@ -39,11 +39,11 @@ class SetDefaultGameTypePacket extends DataPacket implements ClientboundPacket, return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->gamemode = $in->getVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putUnsignedVarInt($this->gamemode); } diff --git a/src/network/mcpe/protocol/SetDifficultyPacket.php b/src/network/mcpe/protocol/SetDifficultyPacket.php index d80ccc127f..e430c53d64 100644 --- a/src/network/mcpe/protocol/SetDifficultyPacket.php +++ b/src/network/mcpe/protocol/SetDifficultyPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class SetDifficultyPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_DIFFICULTY_PACKET; @@ -39,11 +39,11 @@ class SetDifficultyPacket extends DataPacket implements ClientboundPacket, Serve return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->difficulty = $in->getUnsignedVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putUnsignedVarInt($this->difficulty); } diff --git a/src/network/mcpe/protocol/SetDisplayObjectivePacket.php b/src/network/mcpe/protocol/SetDisplayObjectivePacket.php index aa2ee249f0..9c996dd4e2 100644 --- a/src/network/mcpe/protocol/SetDisplayObjectivePacket.php +++ b/src/network/mcpe/protocol/SetDisplayObjectivePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class SetDisplayObjectivePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_DISPLAY_OBJECTIVE_PACKET; @@ -41,7 +41,7 @@ class SetDisplayObjectivePacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $sortOrder; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->displaySlot = $in->getString(); $this->objectiveName = $in->getString(); $this->displayName = $in->getString(); @@ -49,7 +49,7 @@ class SetDisplayObjectivePacket extends DataPacket implements ClientboundPacket{ $this->sortOrder = $in->getVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->displaySlot); $out->putString($this->objectiveName); $out->putString($this->displayName); diff --git a/src/network/mcpe/protocol/SetHealthPacket.php b/src/network/mcpe/protocol/SetHealthPacket.php index 8defcfb6e3..87e08b9baa 100644 --- a/src/network/mcpe/protocol/SetHealthPacket.php +++ b/src/network/mcpe/protocol/SetHealthPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class SetHealthPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_HEALTH_PACKET; @@ -33,11 +33,11 @@ class SetHealthPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $health; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->health = $in->getVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putVarInt($this->health); } diff --git a/src/network/mcpe/protocol/SetLastHurtByPacket.php b/src/network/mcpe/protocol/SetLastHurtByPacket.php index fd468f4ae4..6a3fd71119 100644 --- a/src/network/mcpe/protocol/SetLastHurtByPacket.php +++ b/src/network/mcpe/protocol/SetLastHurtByPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class SetLastHurtByPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_LAST_HURT_BY_PACKET; @@ -33,11 +33,11 @@ class SetLastHurtByPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $entityTypeId; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityTypeId = $in->getVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putVarInt($this->entityTypeId); } diff --git a/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php b/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php index 9218524c21..5f9eda5663 100644 --- a/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php +++ b/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class SetLocalPlayerAsInitializedPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_LOCAL_PLAYER_AS_INITIALIZED_PACKET; @@ -33,11 +33,11 @@ class SetLocalPlayerAsInitializedPacket extends DataPacket implements Serverboun /** @var int */ public $entityRuntimeId; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityRuntimeId = $in->getEntityRuntimeId(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityRuntimeId($this->entityRuntimeId); } diff --git a/src/network/mcpe/protocol/SetPlayerGameTypePacket.php b/src/network/mcpe/protocol/SetPlayerGameTypePacket.php index 28a8023fcc..eb337f2a71 100644 --- a/src/network/mcpe/protocol/SetPlayerGameTypePacket.php +++ b/src/network/mcpe/protocol/SetPlayerGameTypePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class SetPlayerGameTypePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_PLAYER_GAME_TYPE_PACKET; @@ -39,11 +39,11 @@ class SetPlayerGameTypePacket extends DataPacket implements ClientboundPacket, S return $pk; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->gamemode = $in->getVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putVarInt($this->gamemode); } diff --git a/src/network/mcpe/protocol/SetScorePacket.php b/src/network/mcpe/protocol/SetScorePacket.php index 43a4f73dd5..2d135c938b 100644 --- a/src/network/mcpe/protocol/SetScorePacket.php +++ b/src/network/mcpe/protocol/SetScorePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\ScorePacketEntry; use function count; @@ -40,7 +40,7 @@ class SetScorePacket extends DataPacket implements ClientboundPacket{ /** @var ScorePacketEntry[] */ public $entries = []; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->type = $in->getByte(); for($i = 0, $i2 = $in->getUnsignedVarInt(); $i < $i2; ++$i){ $entry = new ScorePacketEntry(); @@ -65,7 +65,7 @@ class SetScorePacket extends DataPacket implements ClientboundPacket{ } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putByte($this->type); $out->putUnsignedVarInt(count($this->entries)); foreach($this->entries as $entry){ diff --git a/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php b/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php index 3e195d812f..d48a7e9bec 100644 --- a/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php +++ b/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\ScoreboardIdentityPacketEntry; use function count; @@ -40,7 +40,7 @@ class SetScoreboardIdentityPacket extends DataPacket implements ClientboundPacke /** @var ScoreboardIdentityPacketEntry[] */ public $entries = []; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->type = $in->getByte(); for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ $entry = new ScoreboardIdentityPacketEntry(); @@ -53,7 +53,7 @@ class SetScoreboardIdentityPacket extends DataPacket implements ClientboundPacke } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putByte($this->type); $out->putUnsignedVarInt(count($this->entries)); foreach($this->entries as $entry){ diff --git a/src/network/mcpe/protocol/SetSpawnPositionPacket.php b/src/network/mcpe/protocol/SetSpawnPositionPacket.php index fd7da1f46f..d8c0c60444 100644 --- a/src/network/mcpe/protocol/SetSpawnPositionPacket.php +++ b/src/network/mcpe/protocol/SetSpawnPositionPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class SetSpawnPositionPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_SPAWN_POSITION_PACKET; @@ -59,13 +59,13 @@ class SetSpawnPositionPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->spawnType = $in->getVarInt(); $in->getBlockPosition($this->x, $this->y, $this->z); $this->spawnForced = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putVarInt($this->spawnType); $out->putBlockPosition($this->x, $this->y, $this->z); $out->putBool($this->spawnForced); diff --git a/src/network/mcpe/protocol/SetTimePacket.php b/src/network/mcpe/protocol/SetTimePacket.php index 54b51e9df7..a8e38e03e1 100644 --- a/src/network/mcpe/protocol/SetTimePacket.php +++ b/src/network/mcpe/protocol/SetTimePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class SetTimePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_TIME_PACKET; @@ -39,11 +39,11 @@ class SetTimePacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->time = $in->getVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putVarInt($this->time); } diff --git a/src/network/mcpe/protocol/SetTitlePacket.php b/src/network/mcpe/protocol/SetTitlePacket.php index 6d4d4b470a..58a6d7d332 100644 --- a/src/network/mcpe/protocol/SetTitlePacket.php +++ b/src/network/mcpe/protocol/SetTitlePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class SetTitlePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SET_TITLE_PACKET; @@ -48,7 +48,7 @@ class SetTitlePacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $fadeOutTime = 0; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->type = $in->getVarInt(); $this->text = $in->getString(); $this->fadeInTime = $in->getVarInt(); @@ -56,7 +56,7 @@ class SetTitlePacket extends DataPacket implements ClientboundPacket{ $this->fadeOutTime = $in->getVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putVarInt($this->type); $out->putString($this->text); $out->putVarInt($this->fadeInTime); diff --git a/src/network/mcpe/protocol/SettingsCommandPacket.php b/src/network/mcpe/protocol/SettingsCommandPacket.php index b189118d33..3bf2d10c6a 100644 --- a/src/network/mcpe/protocol/SettingsCommandPacket.php +++ b/src/network/mcpe/protocol/SettingsCommandPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class SettingsCommandPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SETTINGS_COMMAND_PACKET; @@ -50,12 +50,12 @@ class SettingsCommandPacket extends DataPacket implements ServerboundPacket{ return $this->suppressOutput; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->command = $in->getString(); $this->suppressOutput = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->command); $out->putBool($this->suppressOutput); } diff --git a/src/network/mcpe/protocol/ShowCreditsPacket.php b/src/network/mcpe/protocol/ShowCreditsPacket.php index 8306ea67af..22b56ed297 100644 --- a/src/network/mcpe/protocol/ShowCreditsPacket.php +++ b/src/network/mcpe/protocol/ShowCreditsPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ShowCreditsPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SHOW_CREDITS_PACKET; @@ -38,12 +38,12 @@ class ShowCreditsPacket extends DataPacket implements ClientboundPacket, Serverb /** @var int */ public $status; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->playerEid = $in->getEntityRuntimeId(); $this->status = $in->getVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityRuntimeId($this->playerEid); $out->putVarInt($this->status); } diff --git a/src/network/mcpe/protocol/ShowProfilePacket.php b/src/network/mcpe/protocol/ShowProfilePacket.php index 9a52cee363..0d3ae01658 100644 --- a/src/network/mcpe/protocol/ShowProfilePacket.php +++ b/src/network/mcpe/protocol/ShowProfilePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ShowProfilePacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SHOW_PROFILE_PACKET; @@ -33,11 +33,11 @@ class ShowProfilePacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $xuid; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->xuid = $in->getString(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->xuid); } diff --git a/src/network/mcpe/protocol/ShowStoreOfferPacket.php b/src/network/mcpe/protocol/ShowStoreOfferPacket.php index 1b76dc3514..5636f3c175 100644 --- a/src/network/mcpe/protocol/ShowStoreOfferPacket.php +++ b/src/network/mcpe/protocol/ShowStoreOfferPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ShowStoreOfferPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::SHOW_STORE_OFFER_PACKET; @@ -35,12 +35,12 @@ class ShowStoreOfferPacket extends DataPacket implements ClientboundPacket{ /** @var bool */ public $showAll; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->offerId = $in->getString(); $this->showAll = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->offerId); $out->putBool($this->showAll); } diff --git a/src/network/mcpe/protocol/SimpleEventPacket.php b/src/network/mcpe/protocol/SimpleEventPacket.php index edfc883ce7..0ae0bfdebf 100644 --- a/src/network/mcpe/protocol/SimpleEventPacket.php +++ b/src/network/mcpe/protocol/SimpleEventPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class SimpleEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SIMPLE_EVENT_PACKET; @@ -37,11 +37,11 @@ class SimpleEventPacket extends DataPacket implements ClientboundPacket, Serverb /** @var int */ public $eventType; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->eventType = $in->getLShort(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putLShort($this->eventType); } diff --git a/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php b/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php index 9c9cfc5706..6f1ee186d0 100644 --- a/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php +++ b/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class SpawnExperienceOrbPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SPAWN_EXPERIENCE_ORB_PACKET; @@ -36,12 +36,12 @@ class SpawnExperienceOrbPacket extends DataPacket implements ServerboundPacket{ /** @var int */ public $amount; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->position = $in->getVector3(); $this->amount = $in->getVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putVector3($this->position); $out->putVarInt($this->amount); } diff --git a/src/network/mcpe/protocol/SpawnParticleEffectPacket.php b/src/network/mcpe/protocol/SpawnParticleEffectPacket.php index 7f299373a4..2485608d33 100644 --- a/src/network/mcpe/protocol/SpawnParticleEffectPacket.php +++ b/src/network/mcpe/protocol/SpawnParticleEffectPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\DimensionIds; class SpawnParticleEffectPacket extends DataPacket implements ClientboundPacket{ @@ -41,14 +41,14 @@ class SpawnParticleEffectPacket extends DataPacket implements ClientboundPacket{ /** @var string */ public $particleName; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->dimensionId = $in->getByte(); $this->entityUniqueId = $in->getEntityUniqueId(); $this->position = $in->getVector3(); $this->particleName = $in->getString(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putByte($this->dimensionId); $out->putEntityUniqueId($this->entityUniqueId); $out->putVector3($this->position); diff --git a/src/network/mcpe/protocol/StartGamePacket.php b/src/network/mcpe/protocol/StartGamePacket.php index caf9b2a2b9..9e4911f213 100644 --- a/src/network/mcpe/protocol/StartGamePacket.php +++ b/src/network/mcpe/protocol/StartGamePacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\nbt\tag\ListTag; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\CacheableNbt; use pocketmine\network\mcpe\protocol\types\EducationEditionOffer; use pocketmine\network\mcpe\protocol\types\GameRuleType; @@ -158,7 +158,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{ */ public $itemTable = []; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityUniqueId = $in->getEntityUniqueId(); $this->entityRuntimeId = $in->getEntityRuntimeId(); $this->playerGamemode = $in->getVarInt(); @@ -228,7 +228,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{ $this->multiplayerCorrelationId = $in->getString(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityUniqueId($this->entityUniqueId); $out->putEntityRuntimeId($this->entityRuntimeId); $out->putVarInt($this->playerGamemode); @@ -293,7 +293,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{ * @phpstan-param array $table */ private static function serializeItemTable(array $table) : string{ - $stream = new NetworkBinaryStream(); + $stream = new PacketSerializer(); $stream->putUnsignedVarInt(count($table)); foreach($table as $name => $legacyId){ $stream->putString($name); diff --git a/src/network/mcpe/protocol/StopSoundPacket.php b/src/network/mcpe/protocol/StopSoundPacket.php index bb1db9d4c4..50f747500e 100644 --- a/src/network/mcpe/protocol/StopSoundPacket.php +++ b/src/network/mcpe/protocol/StopSoundPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class StopSoundPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::STOP_SOUND_PACKET; @@ -35,12 +35,12 @@ class StopSoundPacket extends DataPacket implements ClientboundPacket{ /** @var bool */ public $stopAll; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->soundName = $in->getString(); $this->stopAll = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->soundName); $out->putBool($this->stopAll); } diff --git a/src/network/mcpe/protocol/StructureBlockUpdatePacket.php b/src/network/mcpe/protocol/StructureBlockUpdatePacket.php index a17a50148b..4ec92a45c1 100644 --- a/src/network/mcpe/protocol/StructureBlockUpdatePacket.php +++ b/src/network/mcpe/protocol/StructureBlockUpdatePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\StructureEditorData; class StructureBlockUpdatePacket extends DataPacket implements ServerboundPacket{ @@ -42,13 +42,13 @@ class StructureBlockUpdatePacket extends DataPacket implements ServerboundPacket /** @var bool */ public $isPowered; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $in->getBlockPosition($this->x, $this->y, $this->z); $this->structureEditorData = $in->getStructureEditorData(); $this->isPowered = $in->getBool(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putBlockPosition($this->x, $this->y, $this->z); $out->putStructureEditorData($this->structureEditorData); $out->putBool($this->isPowered); diff --git a/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php b/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php index 5abb98420e..376e300b3a 100644 --- a/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php +++ b/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\StructureSettings; class StructureTemplateDataRequestPacket extends DataPacket implements ServerboundPacket{ @@ -47,14 +47,14 @@ class StructureTemplateDataRequestPacket extends DataPacket implements Serverbou /** @var int */ public $structureTemplateResponseType; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->structureTemplateName = $in->getString(); $in->getBlockPosition($this->structureBlockX, $this->structureBlockY, $this->structureBlockZ); $this->structureSettings = $in->getStructureSettings(); $this->structureTemplateResponseType = $in->getByte(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->structureTemplateName); $out->putBlockPosition($this->structureBlockX, $this->structureBlockY, $this->structureBlockZ); $out->putStructureSettings($this->structureSettings); diff --git a/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php b/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php index fbbd2c4fb5..ad3e080511 100644 --- a/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php +++ b/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\CacheableNbt; class StructureTemplateDataResponsePacket extends DataPacket implements ClientboundPacket{ @@ -39,14 +39,14 @@ class StructureTemplateDataResponsePacket extends DataPacket implements Clientbo */ public $namedtag; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->structureTemplateName = $in->getString(); if($in->getBool()){ $this->namedtag = new CacheableNbt($in->getNbtCompoundRoot()); } } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->structureTemplateName); $out->putBool($this->namedtag !== null); if($this->namedtag !== null){ diff --git a/src/network/mcpe/protocol/SubClientLoginPacket.php b/src/network/mcpe/protocol/SubClientLoginPacket.php index a20d1592bf..f2685891bf 100644 --- a/src/network/mcpe/protocol/SubClientLoginPacket.php +++ b/src/network/mcpe/protocol/SubClientLoginPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class SubClientLoginPacket extends DataPacket implements ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::SUB_CLIENT_LOGIN_PACKET; @@ -33,11 +33,11 @@ class SubClientLoginPacket extends DataPacket implements ServerboundPacket{ /** @var string */ public $connectionRequestData; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->connectionRequestData = $in->getString(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->connectionRequestData); } diff --git a/src/network/mcpe/protocol/TakeItemActorPacket.php b/src/network/mcpe/protocol/TakeItemActorPacket.php index 67737f9ea6..74331a615c 100644 --- a/src/network/mcpe/protocol/TakeItemActorPacket.php +++ b/src/network/mcpe/protocol/TakeItemActorPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class TakeItemActorPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::TAKE_ITEM_ACTOR_PACKET; @@ -42,12 +42,12 @@ class TakeItemActorPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->target = $in->getEntityRuntimeId(); $this->eid = $in->getEntityRuntimeId(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityRuntimeId($this->target); $out->putEntityRuntimeId($this->eid); } diff --git a/src/network/mcpe/protocol/TextPacket.php b/src/network/mcpe/protocol/TextPacket.php index 4224d89531..ed10825f0a 100644 --- a/src/network/mcpe/protocol/TextPacket.php +++ b/src/network/mcpe/protocol/TextPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use function count; class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -115,7 +115,7 @@ class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPac return self::messageOnly(self::TYPE_TIP, $message); } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->type = $in->getByte(); $this->needsTranslation = $in->getBool(); switch($this->type){ @@ -146,7 +146,7 @@ class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPac $this->platformChatId = $in->getString(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putByte($this->type); $out->putBool($this->needsTranslation); switch($this->type){ diff --git a/src/network/mcpe/protocol/TickSyncPacket.php b/src/network/mcpe/protocol/TickSyncPacket.php index 84d3f5d2c4..134ca40aff 100644 --- a/src/network/mcpe/protocol/TickSyncPacket.php +++ b/src/network/mcpe/protocol/TickSyncPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class TickSyncPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::TICK_SYNC_PACKET; @@ -57,12 +57,12 @@ class TickSyncPacket extends DataPacket implements ClientboundPacket, Serverboun return $this->serverReceiveTime; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->clientSendTime = $in->getLLong(); $this->serverReceiveTime = $in->getLLong(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putLLong($this->clientSendTime); $out->putLLong($this->serverReceiveTime); } diff --git a/src/network/mcpe/protocol/TransferPacket.php b/src/network/mcpe/protocol/TransferPacket.php index 635d61f0c5..8b25ef64eb 100644 --- a/src/network/mcpe/protocol/TransferPacket.php +++ b/src/network/mcpe/protocol/TransferPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class TransferPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::TRANSFER_PACKET; @@ -42,12 +42,12 @@ class TransferPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->address = $in->getString(); $this->port = $in->getLShort(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->address); $out->putLShort($this->port); } diff --git a/src/network/mcpe/protocol/UnknownPacket.php b/src/network/mcpe/protocol/UnknownPacket.php index 720211fbdc..feecedea20 100644 --- a/src/network/mcpe/protocol/UnknownPacket.php +++ b/src/network/mcpe/protocol/UnknownPacket.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use function ord; use function strlen; @@ -44,19 +44,19 @@ class UnknownPacket extends DataPacket{ return "unknown packet"; } - protected function decodeHeader(NetworkBinaryStream $in) : void{ + protected function decodeHeader(PacketSerializer $in) : void{ } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->payload = $in->getRemaining(); } - protected function encodeHeader(NetworkBinaryStream $out) : void{ + protected function encodeHeader(PacketSerializer $out) : void{ } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->put($this->payload); } diff --git a/src/network/mcpe/protocol/UpdateAttributesPacket.php b/src/network/mcpe/protocol/UpdateAttributesPacket.php index 31929d3ab3..ba68b6a08c 100644 --- a/src/network/mcpe/protocol/UpdateAttributesPacket.php +++ b/src/network/mcpe/protocol/UpdateAttributesPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\entity\Attribute; use function array_values; @@ -49,12 +49,12 @@ class UpdateAttributesPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->entityRuntimeId = $in->getEntityRuntimeId(); $this->entries = $in->getAttributeList(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putEntityRuntimeId($this->entityRuntimeId); $out->putAttributeList(...array_values($this->entries)); } diff --git a/src/network/mcpe/protocol/UpdateBlockPacket.php b/src/network/mcpe/protocol/UpdateBlockPacket.php index 0d590385f6..a4ea6faffa 100644 --- a/src/network/mcpe/protocol/UpdateBlockPacket.php +++ b/src/network/mcpe/protocol/UpdateBlockPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class UpdateBlockPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_BLOCK_PACKET; @@ -58,14 +58,14 @@ class UpdateBlockPacket extends DataPacket implements ClientboundPacket{ return $result; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $in->getBlockPosition($this->x, $this->y, $this->z); $this->blockRuntimeId = $in->getUnsignedVarInt(); $this->flags = $in->getUnsignedVarInt(); $this->dataLayerId = $in->getUnsignedVarInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putBlockPosition($this->x, $this->y, $this->z); $out->putUnsignedVarInt($this->blockRuntimeId); $out->putUnsignedVarInt($this->flags); diff --git a/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php b/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php index e7b018ee5e..15662da9f1 100644 --- a/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php +++ b/src/network/mcpe/protocol/UpdateBlockPropertiesPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\CacheableNbt; class UpdateBlockPropertiesPacket extends DataPacket implements ClientboundPacket{ @@ -51,11 +51,11 @@ class UpdateBlockPropertiesPacket extends DataPacket implements ClientboundPacke return $this->blockProperties; } - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->blockProperties = new CacheableNbt($in->getNbtCompoundRoot()); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->put($this->blockProperties->getEncodedNbt()); } diff --git a/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php b/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php index ad35d4f894..373365b917 100644 --- a/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php +++ b/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class UpdateBlockSyncedPacket extends UpdateBlockPacket{ public const NETWORK_ID = ProtocolInfo::UPDATE_BLOCK_SYNCED_PACKET; @@ -39,13 +39,13 @@ class UpdateBlockSyncedPacket extends UpdateBlockPacket{ /** @var int */ public $updateType; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ parent::decodePayload($in); $this->entityUniqueId = $in->getUnsignedVarLong(); $this->updateType = $in->getUnsignedVarLong(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ parent::encodePayload($out); $out->putUnsignedVarLong($this->entityUniqueId); $out->putUnsignedVarLong($this->updateType); diff --git a/src/network/mcpe/protocol/UpdateEquipPacket.php b/src/network/mcpe/protocol/UpdateEquipPacket.php index a4aa6a2eac..45051919c6 100644 --- a/src/network/mcpe/protocol/UpdateEquipPacket.php +++ b/src/network/mcpe/protocol/UpdateEquipPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\CacheableNbt; class UpdateEquipPacket extends DataPacket implements ClientboundPacket{ @@ -45,7 +45,7 @@ class UpdateEquipPacket extends DataPacket implements ClientboundPacket{ */ public $namedtag; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->windowId = $in->getByte(); $this->windowType = $in->getByte(); $this->windowSlotCount = $in->getVarInt(); @@ -53,7 +53,7 @@ class UpdateEquipPacket extends DataPacket implements ClientboundPacket{ $this->namedtag = new CacheableNbt($in->getNbtCompoundRoot()); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putByte($this->windowId); $out->putByte($this->windowType); $out->putVarInt($this->windowSlotCount); diff --git a/src/network/mcpe/protocol/UpdateSoftEnumPacket.php b/src/network/mcpe/protocol/UpdateSoftEnumPacket.php index 9e91cdace3..7ec0e4d745 100644 --- a/src/network/mcpe/protocol/UpdateSoftEnumPacket.php +++ b/src/network/mcpe/protocol/UpdateSoftEnumPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use function count; class UpdateSoftEnumPacket extends DataPacket implements ClientboundPacket{ @@ -42,7 +42,7 @@ class UpdateSoftEnumPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $type; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->enumName = $in->getString(); for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ $this->values[] = $in->getString(); @@ -50,7 +50,7 @@ class UpdateSoftEnumPacket extends DataPacket implements ClientboundPacket{ $this->type = $in->getByte(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->enumName); $out->putUnsignedVarInt(count($this->values)); foreach($this->values as $v){ diff --git a/src/network/mcpe/protocol/UpdateTradePacket.php b/src/network/mcpe/protocol/UpdateTradePacket.php index 2665621ae2..ef70485b0c 100644 --- a/src/network/mcpe/protocol/UpdateTradePacket.php +++ b/src/network/mcpe/protocol/UpdateTradePacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\CacheableNbt; use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes; @@ -58,7 +58,7 @@ class UpdateTradePacket extends DataPacket implements ClientboundPacket{ */ public $offers; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->windowId = $in->getByte(); $this->windowType = $in->getByte(); $this->windowSlotCount = $in->getVarInt(); @@ -71,7 +71,7 @@ class UpdateTradePacket extends DataPacket implements ClientboundPacket{ $this->offers = new CacheableNbt($in->getNbtCompoundRoot()); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putByte($this->windowId); $out->putByte($this->windowType); $out->putVarInt($this->windowSlotCount); diff --git a/src/network/mcpe/protocol/VideoStreamConnectPacket.php b/src/network/mcpe/protocol/VideoStreamConnectPacket.php index def67364cd..06954c94a3 100644 --- a/src/network/mcpe/protocol/VideoStreamConnectPacket.php +++ b/src/network/mcpe/protocol/VideoStreamConnectPacket.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol; #include -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class VideoStreamConnectPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::VIDEO_STREAM_CONNECT_PACKET; @@ -44,7 +44,7 @@ class VideoStreamConnectPacket extends DataPacket implements ClientboundPacket{ /** @var int */ public $resolutionY; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ $this->serverUri = $in->getString(); $this->frameSendFrequency = $in->getLFloat(); $this->action = $in->getByte(); @@ -52,7 +52,7 @@ class VideoStreamConnectPacket extends DataPacket implements ClientboundPacket{ $this->resolutionY = $in->getLInt(); } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ $out->putString($this->serverUri); $out->putLFloat($this->frameSendFrequency); $out->putByte($this->action); diff --git a/src/network/mcpe/protocol/serializer/PacketBatch.php b/src/network/mcpe/protocol/serializer/PacketBatch.php index e58001539d..605f6be65e 100644 --- a/src/network/mcpe/protocol/serializer/PacketBatch.php +++ b/src/network/mcpe/protocol/serializer/PacketBatch.php @@ -29,11 +29,11 @@ use pocketmine\utils\BinaryDataException; class PacketBatch{ - /** @var NetworkBinaryStream */ + /** @var PacketSerializer */ private $binaryStream; public function __construct(?string $buffer = null){ - $this->binaryStream = new NetworkBinaryStream($buffer ?? ""); + $this->binaryStream = new PacketSerializer($buffer ?? ""); } public function putPacket(Packet $packet) : void{ diff --git a/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php b/src/network/mcpe/protocol/serializer/PacketSerializer.php similarity index 95% rename from src/network/mcpe/protocol/serializer/NetworkBinaryStream.php rename to src/network/mcpe/protocol/serializer/PacketSerializer.php index a1d5dd8334..10e6fb72e7 100644 --- a/src/network/mcpe/protocol/serializer/NetworkBinaryStream.php +++ b/src/network/mcpe/protocol/serializer/PacketSerializer.php @@ -60,7 +60,7 @@ use pocketmine\uuid\UUID; use function count; use function strlen; -class NetworkBinaryStream extends BinaryStream{ +class PacketSerializer extends BinaryStream{ /** * @throws BinaryDataException @@ -146,7 +146,7 @@ class NetworkBinaryStream extends BinaryStream{ return new SkinData($skinId, $skinResourcePatch, $skinData, $animations, $capeData, $geometryData, $animationData, $premium, $persona, $capeOnClassic, $capeId, $fullSkinId, $armSize, $skinColor, $personaPieces, $pieceTintColors); } - public function putSkin(SkinData $skin): void{ + public function putSkin(SkinData $skin) : void{ $this->putString($skin->getSkinId()); $this->putString($skin->getResourcePatch()); $this->putSkinImage($skin->getSkinImage()); @@ -327,15 +327,24 @@ class NetworkBinaryStream extends BinaryStream{ private function readMetadataProperty(int $type) : MetadataProperty{ switch($type){ - case ByteMetadataProperty::id(): return ByteMetadataProperty::read($this); - case ShortMetadataProperty::id(): return ShortMetadataProperty::read($this); - case IntMetadataProperty::id(): return IntMetadataProperty::read($this); - case FloatMetadataProperty::id(): return FloatMetadataProperty::read($this); - case StringMetadataProperty::id(): return StringMetadataProperty::read($this); - case CompoundTagMetadataProperty::id(): return CompoundTagMetadataProperty::read($this); - case BlockPosMetadataProperty::id(): return BlockPosMetadataProperty::read($this); - case LongMetadataProperty::id(): return LongMetadataProperty::read($this); - case Vec3MetadataProperty::id(): return Vec3MetadataProperty::read($this); + case ByteMetadataProperty::id(): + return ByteMetadataProperty::read($this); + case ShortMetadataProperty::id(): + return ShortMetadataProperty::read($this); + case IntMetadataProperty::id(): + return IntMetadataProperty::read($this); + case FloatMetadataProperty::id(): + return FloatMetadataProperty::read($this); + case StringMetadataProperty::id(): + return StringMetadataProperty::read($this); + case CompoundTagMetadataProperty::id(): + return CompoundTagMetadataProperty::read($this); + case BlockPosMetadataProperty::id(): + return BlockPosMetadataProperty::read($this); + case LongMetadataProperty::id(): + return LongMetadataProperty::read($this); + case Vec3MetadataProperty::id(): + return Vec3MetadataProperty::read($this); default: throw new PacketDecodeException("Unknown entity metadata type " . $type); } @@ -345,6 +354,7 @@ class NetworkBinaryStream extends BinaryStream{ * Writes entity metadata to the packet buffer. * * @param MetadataProperty[] $metadata + * * @phpstan-param array $metadata */ public function putEntityMetadata(array $metadata) : void{ @@ -494,7 +504,7 @@ class NetworkBinaryStream extends BinaryStream{ * Note: ONLY use this where it is reasonable to allow not specifying the vector. * For all other purposes, use the non-nullable version. * - * @see NetworkBinaryStream::putVector3() + * @see PacketSerializer::putVector3() */ public function putVector3Nullable(?Vector3 $vector) : void{ if($vector !== null){ @@ -568,6 +578,7 @@ class NetworkBinaryStream extends BinaryStream{ * TODO: implement this properly * * @param mixed[][] $rules + * * @phpstan-param array $rules */ public function putGameRules(array $rules) : void{ diff --git a/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php b/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php index 9043ee1bf3..628b545bee 100644 --- a/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; final class BlockPosMetadataProperty implements MetadataProperty{ @@ -43,13 +43,13 @@ final class BlockPosMetadataProperty implements MetadataProperty{ return EntityMetadataTypes::POS; } - public static function read(NetworkBinaryStream $in) : self{ + public static function read(PacketSerializer $in) : self{ $vec = new Vector3(0, 0, 0); $in->getSignedBlockPosition($vec->x, $vec->y, $vec->z); return new self($vec); } - public function write(NetworkBinaryStream $out) : void{ + public function write(PacketSerializer $out) : void{ $out->putSignedBlockPosition($this->value->x, $this->value->y, $this->value->z); } diff --git a/src/network/mcpe/protocol/types/entity/ByteMetadataProperty.php b/src/network/mcpe/protocol/types/entity/ByteMetadataProperty.php index c85d818120..b4ee55377d 100644 --- a/src/network/mcpe/protocol/types/entity/ByteMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/ByteMetadataProperty.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; final class ByteMetadataProperty implements MetadataProperty{ use IntegerishMetadataProperty; @@ -40,11 +40,11 @@ final class ByteMetadataProperty implements MetadataProperty{ return EntityMetadataTypes::BYTE; } - public static function read(NetworkBinaryStream $in) : self{ + public static function read(PacketSerializer $in) : self{ return new self($in->getByte()); } - public function write(NetworkBinaryStream $out) : void{ + public function write(PacketSerializer $out) : void{ $out->putByte($this->value); } } diff --git a/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php b/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php index 375b9e2591..970c7ff635 100644 --- a/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php @@ -26,8 +26,8 @@ namespace pocketmine\network\mcpe\protocol\types\entity; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\protocol\PacketDecodeException; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; final class CompoundTagMetadataProperty implements MetadataProperty{ /** @var CompoundTag */ @@ -52,11 +52,11 @@ final class CompoundTagMetadataProperty implements MetadataProperty{ /** * @throws PacketDecodeException */ - public static function read(NetworkBinaryStream $in) : self{ + public static function read(PacketSerializer $in) : self{ return new self($in->getNbtCompoundRoot()); } - public function write(NetworkBinaryStream $out) : void{ + public function write(PacketSerializer $out) : void{ $out->put((new NetworkNbtSerializer())->write(new TreeRoot($this->value))); } } diff --git a/src/network/mcpe/protocol/types/entity/FloatMetadataProperty.php b/src/network/mcpe/protocol/types/entity/FloatMetadataProperty.php index fe4b43ba02..e7b550df46 100644 --- a/src/network/mcpe/protocol/types/entity/FloatMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/FloatMetadataProperty.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; final class FloatMetadataProperty implements MetadataProperty{ @@ -46,11 +46,11 @@ final class FloatMetadataProperty implements MetadataProperty{ return $other instanceof self and $other->value === $this->value; } - public static function read(NetworkBinaryStream $in) : self{ + public static function read(PacketSerializer $in) : self{ return new self($in->getLFloat()); } - public function write(NetworkBinaryStream $out) : void{ + public function write(PacketSerializer $out) : void{ $out->putLFloat($this->value); } } diff --git a/src/network/mcpe/protocol/types/entity/IntMetadataProperty.php b/src/network/mcpe/protocol/types/entity/IntMetadataProperty.php index da4ec2d1dc..ea17316782 100644 --- a/src/network/mcpe/protocol/types/entity/IntMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/IntMetadataProperty.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; final class IntMetadataProperty implements MetadataProperty{ use IntegerishMetadataProperty; @@ -40,11 +40,11 @@ final class IntMetadataProperty implements MetadataProperty{ return EntityMetadataTypes::INT; } - public static function read(NetworkBinaryStream $in) : self{ + public static function read(PacketSerializer $in) : self{ return new self($in->getVarInt()); } - public function write(NetworkBinaryStream $out) : void{ + public function write(PacketSerializer $out) : void{ $out->putVarInt($this->value); } } diff --git a/src/network/mcpe/protocol/types/entity/LongMetadataProperty.php b/src/network/mcpe/protocol/types/entity/LongMetadataProperty.php index 685670d606..895dbe7066 100644 --- a/src/network/mcpe/protocol/types/entity/LongMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/LongMetadataProperty.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use const PHP_INT_MAX; use const PHP_INT_MIN; @@ -42,11 +42,11 @@ final class LongMetadataProperty implements MetadataProperty{ return EntityMetadataTypes::LONG; } - public static function read(NetworkBinaryStream $in) : self{ + public static function read(PacketSerializer $in) : self{ return new self($in->getVarLong()); } - public function write(NetworkBinaryStream $out) : void{ + public function write(PacketSerializer $out) : void{ $out->putVarLong($this->value); } } diff --git a/src/network/mcpe/protocol/types/entity/MetadataProperty.php b/src/network/mcpe/protocol/types/entity/MetadataProperty.php index 8310732535..63673d9320 100644 --- a/src/network/mcpe/protocol/types/entity/MetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/MetadataProperty.php @@ -23,13 +23,13 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; interface MetadataProperty{ public static function id() : int; - public function write(NetworkBinaryStream $out) : void; + public function write(PacketSerializer $out) : void; public function equals(MetadataProperty $other) : bool; } diff --git a/src/network/mcpe/protocol/types/entity/ShortMetadataProperty.php b/src/network/mcpe/protocol/types/entity/ShortMetadataProperty.php index 51ff0f33da..2623e89823 100644 --- a/src/network/mcpe/protocol/types/entity/ShortMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/ShortMetadataProperty.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; final class ShortMetadataProperty implements MetadataProperty{ use IntegerishMetadataProperty; @@ -40,11 +40,11 @@ final class ShortMetadataProperty implements MetadataProperty{ return EntityMetadataTypes::SHORT; } - public static function read(NetworkBinaryStream $in) : self{ + public static function read(PacketSerializer $in) : self{ return new self($in->getSignedLShort()); } - public function write(NetworkBinaryStream $out) : void{ + public function write(PacketSerializer $out) : void{ $out->putLShort($this->value); } } diff --git a/src/network/mcpe/protocol/types/entity/StringMetadataProperty.php b/src/network/mcpe/protocol/types/entity/StringMetadataProperty.php index 0a16ad056e..5396d34b16 100644 --- a/src/network/mcpe/protocol/types/entity/StringMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/StringMetadataProperty.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; final class StringMetadataProperty implements MetadataProperty{ /** @var string */ @@ -37,11 +37,11 @@ final class StringMetadataProperty implements MetadataProperty{ return EntityMetadataTypes::STRING; } - public static function read(NetworkBinaryStream $in) : self{ + public static function read(PacketSerializer $in) : self{ return new self($in->getString()); } - public function write(NetworkBinaryStream $out) : void{ + public function write(PacketSerializer $out) : void{ $out->putString($this->value); } diff --git a/src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php b/src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php index ffe2843884..44b81e6105 100644 --- a/src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\entity; use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class Vec3MetadataProperty implements MetadataProperty{ /** @var Vector3 */ @@ -42,11 +42,11 @@ class Vec3MetadataProperty implements MetadataProperty{ return EntityMetadataTypes::VECTOR3F; } - public static function read(NetworkBinaryStream $in) : self{ + public static function read(PacketSerializer $in) : self{ return new self($in->getVector3()); } - public function write(NetworkBinaryStream $out) : void{ + public function write(PacketSerializer $out) : void{ $out->putVector3($this->value); } diff --git a/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php b/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php index a0a588e904..66e0c0ff78 100644 --- a/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; use pocketmine\network\mcpe\protocol\PacketDecodeException; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use function count; class MismatchTransactionData extends TransactionData{ @@ -34,13 +34,13 @@ class MismatchTransactionData extends TransactionData{ return InventoryTransactionPacket::TYPE_MISMATCH; } - protected function decodeData(NetworkBinaryStream $stream) : void{ + protected function decodeData(PacketSerializer $stream) : void{ if(count($this->actions) > 0){ throw new PacketDecodeException("Mismatch transaction type should not have any actions associated with it, but got " . count($this->actions)); } } - protected function encodeData(NetworkBinaryStream $stream) : void{ + protected function encodeData(PacketSerializer $stream) : void{ } diff --git a/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php b/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php index 4ffa11b868..58abac5d14 100644 --- a/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php +++ b/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\network\mcpe\protocol\PacketDecodeException; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\utils\BinaryDataException; class NetworkInventoryAction{ @@ -83,7 +83,7 @@ class NetworkInventoryAction{ * @throws BinaryDataException * @throws PacketDecodeException */ - public function read(NetworkBinaryStream $packet) : NetworkInventoryAction{ + public function read(PacketSerializer $packet) : NetworkInventoryAction{ $this->sourceType = $packet->getUnsignedVarInt(); switch($this->sourceType){ @@ -112,7 +112,7 @@ class NetworkInventoryAction{ /** * @throws \InvalidArgumentException */ - public function write(NetworkBinaryStream $packet) : void{ + public function write(PacketSerializer $packet) : void{ $packet->putUnsignedVarInt($this->sourceType); switch($this->sourceType){ diff --git a/src/network/mcpe/protocol/types/inventory/NormalTransactionData.php b/src/network/mcpe/protocol/types/inventory/NormalTransactionData.php index 761fc97ed1..37c2e565dd 100644 --- a/src/network/mcpe/protocol/types/inventory/NormalTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/NormalTransactionData.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class NormalTransactionData extends TransactionData{ @@ -32,11 +32,11 @@ class NormalTransactionData extends TransactionData{ return InventoryTransactionPacket::TYPE_NORMAL; } - protected function decodeData(NetworkBinaryStream $stream) : void{ + protected function decodeData(PacketSerializer $stream) : void{ } - protected function encodeData(NetworkBinaryStream $stream) : void{ + protected function encodeData(PacketSerializer $stream) : void{ } diff --git a/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php b/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php index 2cb2ccf037..f60086d6d7 100644 --- a/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ReleaseItemTransactionData extends TransactionData{ public const ACTION_RELEASE = 0; //bow shoot @@ -60,14 +60,14 @@ class ReleaseItemTransactionData extends TransactionData{ return InventoryTransactionPacket::TYPE_RELEASE_ITEM; } - protected function decodeData(NetworkBinaryStream $stream) : void{ + protected function decodeData(PacketSerializer $stream) : void{ $this->actionType = $stream->getUnsignedVarInt(); $this->hotbarSlot = $stream->getVarInt(); $this->itemInHand = $stream->getSlot(); $this->headPos = $stream->getVector3(); } - protected function encodeData(NetworkBinaryStream $stream) : void{ + protected function encodeData(PacketSerializer $stream) : void{ $stream->putUnsignedVarInt($this->actionType); $stream->putVarInt($this->hotbarSlot); $stream->putSlot($this->itemInHand); diff --git a/src/network/mcpe/protocol/types/inventory/TransactionData.php b/src/network/mcpe/protocol/types/inventory/TransactionData.php index 35936bf092..ea10fce258 100644 --- a/src/network/mcpe/protocol/types/inventory/TransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/TransactionData.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\network\mcpe\protocol\PacketDecodeException; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\utils\BinaryDataException; use function count; @@ -45,7 +45,7 @@ abstract class TransactionData{ * @throws BinaryDataException * @throws PacketDecodeException */ - final public function decode(NetworkBinaryStream $stream) : void{ + final public function decode(PacketSerializer $stream) : void{ $actionCount = $stream->getUnsignedVarInt(); for($i = 0; $i < $actionCount; ++$i){ $this->actions[] = (new NetworkInventoryAction())->read($stream); @@ -57,9 +57,9 @@ abstract class TransactionData{ * @throws BinaryDataException * @throws PacketDecodeException */ - abstract protected function decodeData(NetworkBinaryStream $stream) : void; + abstract protected function decodeData(PacketSerializer $stream) : void; - final public function encode(NetworkBinaryStream $stream) : void{ + final public function encode(PacketSerializer $stream) : void{ $stream->putUnsignedVarInt(count($this->actions)); foreach($this->actions as $action){ $action->write($stream); @@ -67,5 +67,5 @@ abstract class TransactionData{ $this->encodeData($stream); } - abstract protected function encodeData(NetworkBinaryStream $stream) : void; + abstract protected function encodeData(PacketSerializer $stream) : void; } diff --git a/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php b/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php index 17e56701b7..e2e1eb229a 100644 --- a/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class UseItemOnEntityTransactionData extends TransactionData{ public const ACTION_INTERACT = 0; @@ -72,7 +72,7 @@ class UseItemOnEntityTransactionData extends TransactionData{ return InventoryTransactionPacket::TYPE_USE_ITEM_ON_ENTITY; } - protected function decodeData(NetworkBinaryStream $stream) : void{ + protected function decodeData(PacketSerializer $stream) : void{ $this->entityRuntimeId = $stream->getEntityRuntimeId(); $this->actionType = $stream->getUnsignedVarInt(); $this->hotbarSlot = $stream->getVarInt(); @@ -81,7 +81,7 @@ class UseItemOnEntityTransactionData extends TransactionData{ $this->clickPos = $stream->getVector3(); } - protected function encodeData(NetworkBinaryStream $stream) : void{ + protected function encodeData(PacketSerializer $stream) : void{ $stream->putEntityRuntimeId($this->entityRuntimeId); $stream->putUnsignedVarInt($this->actionType); $stream->putVarInt($this->hotbarSlot); diff --git a/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php b/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php index a8e47bd599..17d5ad627c 100644 --- a/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class UseItemTransactionData extends TransactionData{ public const ACTION_CLICK_BLOCK = 0; @@ -85,7 +85,7 @@ class UseItemTransactionData extends TransactionData{ return InventoryTransactionPacket::TYPE_USE_ITEM; } - protected function decodeData(NetworkBinaryStream $stream) : void{ + protected function decodeData(PacketSerializer $stream) : void{ $this->actionType = $stream->getUnsignedVarInt(); $this->blockPos = new Vector3(); $stream->getBlockPosition($this->blockPos->x, $this->blockPos->y, $this->blockPos->z); @@ -97,7 +97,7 @@ class UseItemTransactionData extends TransactionData{ $this->blockRuntimeId = $stream->getUnsignedVarInt(); } - protected function encodeData(NetworkBinaryStream $stream) : void{ + protected function encodeData(PacketSerializer $stream) : void{ $stream->putUnsignedVarInt($this->actionType); $stream->putBlockPosition($this->blockPos->x, $this->blockPos->y, $this->blockPos->z); $stream->putVarInt($this->face); diff --git a/src/network/mcpe/protocol/types/recipe/FurnaceRecipe.php b/src/network/mcpe/protocol/types/recipe/FurnaceRecipe.php index e81ab935af..5d122fc243 100644 --- a/src/network/mcpe/protocol/types/recipe/FurnaceRecipe.php +++ b/src/network/mcpe/protocol/types/recipe/FurnaceRecipe.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\recipe; use pocketmine\network\mcpe\protocol\CraftingDataPacket; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; final class FurnaceRecipe extends RecipeWithTypeId{ @@ -62,7 +62,7 @@ final class FurnaceRecipe extends RecipeWithTypeId{ return $this->blockName; } - public static function decode(int $typeId, NetworkBinaryStream $in) : self{ + public static function decode(int $typeId, PacketSerializer $in) : self{ $inputId = $in->getVarInt(); $inputData = null; if($typeId === CraftingDataPacket::ENTRY_FURNACE_DATA){ @@ -74,7 +74,7 @@ final class FurnaceRecipe extends RecipeWithTypeId{ return new self($typeId, $inputId, $inputData, $output, $block); } - public function encode(NetworkBinaryStream $out) : void{ + public function encode(PacketSerializer $out) : void{ $out->putVarInt($this->inputId); if($this->getTypeId() === CraftingDataPacket::ENTRY_FURNACE_DATA){ $out->putVarInt($this->inputMeta); diff --git a/src/network/mcpe/protocol/types/recipe/MultiRecipe.php b/src/network/mcpe/protocol/types/recipe/MultiRecipe.php index bd23b231af..bac528c706 100644 --- a/src/network/mcpe/protocol/types/recipe/MultiRecipe.php +++ b/src/network/mcpe/protocol/types/recipe/MultiRecipe.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\recipe; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\uuid\UUID; final class MultiRecipe extends RecipeWithTypeId{ @@ -53,11 +53,11 @@ final class MultiRecipe extends RecipeWithTypeId{ return $this->recipeId; } - public static function decode(int $typeId, NetworkBinaryStream $in) : self{ + public static function decode(int $typeId, PacketSerializer $in) : self{ return new self($typeId, $in->getUUID()); } - public function encode(NetworkBinaryStream $out) : void{ + public function encode(PacketSerializer $out) : void{ $out->putUUID($this->recipeId); } } diff --git a/src/network/mcpe/protocol/types/recipe/RecipeWithTypeId.php b/src/network/mcpe/protocol/types/recipe/RecipeWithTypeId.php index 1960aead47..9171f52bc6 100644 --- a/src/network/mcpe/protocol/types/recipe/RecipeWithTypeId.php +++ b/src/network/mcpe/protocol/types/recipe/RecipeWithTypeId.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\recipe; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; abstract class RecipeWithTypeId{ /** @var int */ @@ -37,5 +37,5 @@ abstract class RecipeWithTypeId{ return $this->typeId; } - abstract public function encode(NetworkBinaryStream $out) : void; + abstract public function encode(PacketSerializer $out) : void; } diff --git a/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php b/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php index 4a868ac73f..195e54e6cd 100644 --- a/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php +++ b/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\recipe; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\uuid\UUID; use function count; @@ -107,7 +107,7 @@ final class ShapedRecipe extends RecipeWithTypeId{ return $this->priority; } - public static function decode(int $recipeType, NetworkBinaryStream $in) : self{ + public static function decode(int $recipeType, PacketSerializer $in) : self{ $recipeId = $in->getString(); $width = $in->getVarInt(); $height = $in->getVarInt(); @@ -129,7 +129,7 @@ final class ShapedRecipe extends RecipeWithTypeId{ return new self($recipeType, $recipeId, $input, $output, $uuid, $block, $priority); } - public function encode(NetworkBinaryStream $out) : void{ + public function encode(PacketSerializer $out) : void{ $out->putString($this->recipeId); $out->putVarInt($this->getWidth()); $out->putVarInt($this->getHeight()); diff --git a/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php b/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php index acffe7fb1b..92ada07b15 100644 --- a/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php +++ b/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\recipe; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\uuid\UUID; use function count; @@ -87,7 +87,7 @@ final class ShapelessRecipe extends RecipeWithTypeId{ return $this->priority; } - public static function decode(int $recipeType, NetworkBinaryStream $in) : self{ + public static function decode(int $recipeType, PacketSerializer $in) : self{ $recipeId = $in->getString(); $input = []; for($j = 0, $ingredientCount = $in->getUnsignedVarInt(); $j < $ingredientCount; ++$j){ @@ -104,7 +104,7 @@ final class ShapelessRecipe extends RecipeWithTypeId{ return new self($recipeType, $recipeId, $input, $output, $uuid, $block, $priority); } - public function encode(NetworkBinaryStream $out) : void{ + public function encode(PacketSerializer $out) : void{ $out->putString($this->recipeId); $out->putUnsignedVarInt(count($this->inputs)); foreach($this->inputs as $item){ diff --git a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php index 4be6018e5d..e2ed65901d 100644 --- a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php +++ b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\resourcepacks; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ResourcePackInfoEntry{ @@ -80,7 +80,7 @@ class ResourcePackInfoEntry{ return $this->hasScripts; } - public function write(NetworkBinaryStream $out) : void{ + public function write(PacketSerializer $out) : void{ $out->putString($this->packId); $out->putString($this->version); $out->putLLong($this->sizeBytes); @@ -90,7 +90,7 @@ class ResourcePackInfoEntry{ $out->putBool($this->hasScripts); } - public static function read(NetworkBinaryStream $in) : self{ + public static function read(PacketSerializer $in) : self{ return new self( $uuid = $in->getString(), $version = $in->getString(), diff --git a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php index 02fb9b4b8a..2e809fb7ed 100644 --- a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php +++ b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\resourcepacks; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class ResourcePackStackEntry{ @@ -52,13 +52,13 @@ class ResourcePackStackEntry{ return $this->subPackName; } - public function write(NetworkBinaryStream $out) : void{ + public function write(PacketSerializer $out) : void{ $out->putString($this->packId); $out->putString($this->version); $out->putString($this->subPackName); } - public static function read(NetworkBinaryStream $in) : self{ + public static function read(PacketSerializer $in) : self{ return new self( $packId = $in->getString(), $version = $in->getString(), diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index 54f79222c2..cbe0d075fa 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\serializer; use pocketmine\block\tile\Spawnable; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\utils\BinaryStream; use pocketmine\world\format\Chunk; use function count; @@ -52,7 +52,7 @@ final class ChunkSerializer{ } public static function serialize(Chunk $chunk, RuntimeBlockMapping $blockMapper, ?string $tiles = null) : string{ - $stream = new NetworkBinaryStream(); + $stream = new PacketSerializer(); $subChunkCount = self::getSubChunkCount($chunk); for($y = 0; $y < $subChunkCount; ++$y){ $layers = $chunk->getSubChunk($y)->getBlockLayers(); diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index b0cb94d4bc..233cde25bc 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -658,45 +658,45 @@ parameters: - message: "#^Parameter \\#1 \\$v of method pocketmine\\\\utils\\\\BinaryStream\\:\\:putBool\\(\\) expects bool, bool\\|float\\|int given\\.$#" count: 1 - path: ../../../src/network/mcpe/protocol/serializer/NetworkBinaryStream.php + path: ../../../src/network/mcpe/protocol/serializer/PacketSerializer.php - message: "#^Parameter \\#1 \\$v of method pocketmine\\\\utils\\\\BinaryStream\\:\\:putUnsignedVarInt\\(\\) expects int, bool\\|float\\|int given\\.$#" count: 1 - path: ../../../src/network/mcpe/protocol/serializer/NetworkBinaryStream.php + path: ../../../src/network/mcpe/protocol/serializer/PacketSerializer.php - message: "#^Parameter \\#1 \\$v of method pocketmine\\\\utils\\\\BinaryStream\\:\\:putLFloat\\(\\) expects float, bool\\|float\\|int given\\.$#" count: 1 - path: ../../../src/network/mcpe/protocol/serializer/NetworkBinaryStream.php + path: ../../../src/network/mcpe/protocol/serializer/PacketSerializer.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\NetworkBinaryStream\\:\\:putSignedBlockPosition\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:putSignedBlockPosition\\(\\) expects int, float\\|int given\\.$#" count: 1 path: ../../../src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\NetworkBinaryStream\\:\\:putSignedBlockPosition\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:putSignedBlockPosition\\(\\) expects int, float\\|int given\\.$#" count: 1 path: ../../../src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\NetworkBinaryStream\\:\\:putSignedBlockPosition\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:putSignedBlockPosition\\(\\) expects int, float\\|int given\\.$#" count: 1 path: ../../../src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\NetworkBinaryStream\\:\\:putBlockPosition\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:putBlockPosition\\(\\) expects int, float\\|int given\\.$#" count: 1 path: ../../../src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\NetworkBinaryStream\\:\\:putBlockPosition\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:putBlockPosition\\(\\) expects int, float\\|int given\\.$#" count: 1 path: ../../../src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\NetworkBinaryStream\\:\\:putBlockPosition\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:putBlockPosition\\(\\) expects int, float\\|int given\\.$#" count: 1 path: ../../../src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 13fe7df3d1..89106bbb03 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -526,17 +526,17 @@ parameters: path: ../../../src/network/mcpe/protocol/LevelSoundEventPacket.php - - message: "#^Parameter \\#1 \\$eid of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\NetworkBinaryStream\\:\\:putEntityUniqueId\\(\\) expects int, int\\|null given\\.$#" + message: "#^Parameter \\#1 \\$eid of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:putEntityUniqueId\\(\\) expects int, int\\|null given\\.$#" count: 1 path: ../../../src/network/mcpe/protocol/SetScorePacket.php - - message: "#^Parameter \\#1 \\$v of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\NetworkBinaryStream\\:\\:putString\\(\\) expects string, string\\|null given\\.$#" + message: "#^Parameter \\#1 \\$v of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:putString\\(\\) expects string, string\\|null given\\.$#" count: 1 path: ../../../src/network/mcpe/protocol/SetScorePacket.php - - message: "#^Parameter \\#1 \\$eid of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\NetworkBinaryStream\\:\\:putEntityUniqueId\\(\\) expects int, int\\|null given\\.$#" + message: "#^Parameter \\#1 \\$eid of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:putEntityUniqueId\\(\\) expects int, int\\|null given\\.$#" count: 1 path: ../../../src/network/mcpe/protocol/SetScoreboardIdentityPacket.php diff --git a/tests/phpunit/network/mcpe/protocol/LoginPacketTest.php b/tests/phpunit/network/mcpe/protocol/LoginPacketTest.php index f5abc6fbaf..00cfaafe06 100644 --- a/tests/phpunit/network/mcpe/protocol/LoginPacketTest.php +++ b/tests/phpunit/network/mcpe/protocol/LoginPacketTest.php @@ -24,18 +24,18 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; use PHPUnit\Framework\TestCase; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use function strlen; class LoginPacketTest extends TestCase{ public function testInvalidChainDataJsonHandling() : void{ - $stream = new NetworkBinaryStream(); + $stream = new PacketSerializer(); $stream->putUnsignedVarInt(ProtocolInfo::LOGIN_PACKET); $payload = '{"chain":[]'; //intentionally malformed $stream->putInt(ProtocolInfo::CURRENT_PROTOCOL); - $stream2 = new NetworkBinaryStream(); + $stream2 = new PacketSerializer(); $stream2->putLInt(strlen($payload)); $stream2->put($payload); $stream->putString($stream2->getBuffer()); diff --git a/tests/phpunit/network/mcpe/protocol/TestPacket.php b/tests/phpunit/network/mcpe/protocol/TestPacket.php index ede9c0bf5e..6e6091c677 100644 --- a/tests/phpunit/network/mcpe/protocol/TestPacket.php +++ b/tests/phpunit/network/mcpe/protocol/TestPacket.php @@ -23,16 +23,16 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; -use pocketmine\network\mcpe\protocol\serializer\NetworkBinaryStream; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class TestPacket extends DataPacket{ public const NETWORK_ID = 1023; - protected function decodePayload(NetworkBinaryStream $in) : void{ + protected function decodePayload(PacketSerializer $in) : void{ } - protected function encodePayload(NetworkBinaryStream $out) : void{ + protected function encodePayload(PacketSerializer $out) : void{ } From 9c46a1f1416f90b1add866b97655feb02dfc7e0d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jun 2020 11:33:59 +0100 Subject: [PATCH 1635/3224] Rename Packet->getBinaryStream() -> Packet->getSerializer() --- src/network/mcpe/NetworkSession.php | 6 +++--- src/network/mcpe/protocol/DataPacket.php | 2 +- src/network/mcpe/protocol/Packet.php | 2 +- src/network/mcpe/protocol/PacketPool.php | 2 +- src/network/mcpe/protocol/serializer/PacketBatch.php | 12 ++++++------ .../phpunit/network/mcpe/protocol/DataPacketTest.php | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index b08c8cddd1..44405214f1 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -342,7 +342,7 @@ class NetworkSession{ try{ $this->handleDataPacket($pk); }catch(BadPacketException $e){ - $this->logger->debug($pk->getName() . ": " . base64_encode($pk->getBinaryStream()->getBuffer())); + $this->logger->debug($pk->getName() . ": " . base64_encode($pk->getSerializer()->getBuffer())); throw BadPacketException::wrap($e, "Error processing " . $pk->getName()); } } @@ -354,7 +354,7 @@ class NetworkSession{ public function handleDataPacket(Packet $packet) : void{ if(!($packet instanceof ServerboundPacket)){ if($packet instanceof GarbageServerboundPacket){ - $this->logger->debug("Garbage serverbound " . $packet->getName() . ": " . base64_encode($packet->getBinaryStream()->getBuffer())); + $this->logger->debug("Garbage serverbound " . $packet->getName() . ": " . base64_encode($packet->getSerializer()->getBuffer())); return; } throw new BadPacketException("Unexpected non-serverbound packet"); @@ -369,7 +369,7 @@ class NetworkSession{ }catch(PacketDecodeException $e){ throw BadPacketException::wrap($e); } - $stream = $packet->getBinaryStream(); + $stream = $packet->getSerializer(); if(!$stream->feof()){ $remains = substr($stream->getBuffer(), $stream->getOffset()); $this->logger->debug("Still " . strlen($remains) . " bytes unread in " . $packet->getName() . ": " . bin2hex($remains)); diff --git a/src/network/mcpe/protocol/DataPacket.php b/src/network/mcpe/protocol/DataPacket.php index 89e8280e4c..e61ad00f74 100644 --- a/src/network/mcpe/protocol/DataPacket.php +++ b/src/network/mcpe/protocol/DataPacket.php @@ -51,7 +51,7 @@ abstract class DataPacket implements Packet{ $this->buf = new PacketSerializer(); } - public function getBinaryStream() : PacketSerializer{ + public function getSerializer() : PacketSerializer{ return $this->buf; } diff --git a/src/network/mcpe/protocol/Packet.php b/src/network/mcpe/protocol/Packet.php index d2aff314dd..b2f6317ee5 100644 --- a/src/network/mcpe/protocol/Packet.php +++ b/src/network/mcpe/protocol/Packet.php @@ -27,7 +27,7 @@ use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; interface Packet{ - public function getBinaryStream() : PacketSerializer; + public function getSerializer() : PacketSerializer; public function pid() : int; diff --git a/src/network/mcpe/protocol/PacketPool.php b/src/network/mcpe/protocol/PacketPool.php index 6c0fc2d0ec..dd2b0879b5 100644 --- a/src/network/mcpe/protocol/PacketPool.php +++ b/src/network/mcpe/protocol/PacketPool.php @@ -201,7 +201,7 @@ class PacketPool{ public function getPacket(string $buffer) : Packet{ $offset = 0; $pk = $this->getPacketById(Binary::readUnsignedVarInt($buffer, $offset) & DataPacket::PID_MASK); - $pk->getBinaryStream()->setBuffer($buffer, $offset); + $pk->getSerializer()->setBuffer($buffer, $offset); return $pk; } diff --git a/src/network/mcpe/protocol/serializer/PacketBatch.php b/src/network/mcpe/protocol/serializer/PacketBatch.php index 605f6be65e..a242a2b6f8 100644 --- a/src/network/mcpe/protocol/serializer/PacketBatch.php +++ b/src/network/mcpe/protocol/serializer/PacketBatch.php @@ -30,22 +30,22 @@ use pocketmine\utils\BinaryDataException; class PacketBatch{ /** @var PacketSerializer */ - private $binaryStream; + private $serializer; public function __construct(?string $buffer = null){ - $this->binaryStream = new PacketSerializer($buffer ?? ""); + $this->serializer = new PacketSerializer($buffer ?? ""); } public function putPacket(Packet $packet) : void{ $packet->encode(); - $this->binaryStream->putString($packet->getBinaryStream()->getBuffer()); + $this->serializer->putString($packet->getSerializer()->getBuffer()); } /** * @throws BinaryDataException */ public function getPacket(PacketPool $packetPool) : Packet{ - return $packetPool->getPacket($this->binaryStream->getString()); + return $packetPool->getPacket($this->serializer->getString()); } /** @@ -64,10 +64,10 @@ class PacketBatch{ } public function getBuffer() : string{ - return $this->binaryStream->getBuffer(); + return $this->serializer->getBuffer(); } public function feof() : bool{ - return $this->binaryStream->feof(); + return $this->serializer->feof(); } } diff --git a/tests/phpunit/network/mcpe/protocol/DataPacketTest.php b/tests/phpunit/network/mcpe/protocol/DataPacketTest.php index 5163d36aab..bcfd0e9d2f 100644 --- a/tests/phpunit/network/mcpe/protocol/DataPacketTest.php +++ b/tests/phpunit/network/mcpe/protocol/DataPacketTest.php @@ -34,7 +34,7 @@ class DataPacketTest extends TestCase{ $pk->encode(); $pk2 = new TestPacket(); - $pk2->getBinaryStream()->setBuffer($pk->getBinaryStream()->getBuffer()); + $pk2->getSerializer()->setBuffer($pk->getSerializer()->getBuffer()); $pk2->decode(); self::assertSame($pk2->senderSubId, 3); self::assertSame($pk2->recipientSubId, 2); From 893f7cb6ef89fa4350febee22aa949eb35e68101 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jun 2020 12:39:54 +0100 Subject: [PATCH 1636/3224] fix crash whn player joins in spectator mode --- src/network/mcpe/NetworkSession.php | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 44405214f1..c5c249c94f 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -657,20 +657,22 @@ class NetworkSession{ } public function syncMovement(Vector3 $pos, ?float $yaw = null, ?float $pitch = null, int $mode = MovePlayerPacket::MODE_NORMAL) : void{ - $location = $this->player->getLocation(); - $yaw = $yaw ?? $location->getYaw(); - $pitch = $pitch ?? $location->getPitch(); + if($this->player !== null){ + $location = $this->player->getLocation(); + $yaw = $yaw ?? $location->getYaw(); + $pitch = $pitch ?? $location->getPitch(); - $pk = new MovePlayerPacket(); - $pk->entityRuntimeId = $this->player->getId(); - $pk->position = $this->player->getOffsetPosition($pos); - $pk->pitch = $pitch; - $pk->headYaw = $yaw; - $pk->yaw = $yaw; - $pk->mode = $mode; - $pk->onGround = $this->player->onGround; + $pk = new MovePlayerPacket(); + $pk->entityRuntimeId = $this->player->getId(); + $pk->position = $this->player->getOffsetPosition($pos); + $pk->pitch = $pitch; + $pk->headYaw = $yaw; + $pk->yaw = $yaw; + $pk->mode = $mode; + $pk->onGround = $this->player->onGround; - $this->sendDataPacket($pk); + $this->sendDataPacket($pk); + } } public function syncViewAreaRadius(int $distance) : void{ From c618932d258f81f30a3cf1758c74e59f9a12cf2d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jun 2020 13:49:43 +0100 Subject: [PATCH 1637/3224] Eliminate usages of BinaryStream->setBuffer() and BinaryStream->reset() --- src/network/mcpe/protocol/DataPacket.php | 6 +++++- src/network/mcpe/protocol/Packet.php | 2 ++ src/network/mcpe/protocol/PacketPool.php | 8 ++++---- src/world/format/io/leveldb/LevelDB.php | 8 +++----- tests/phpunit/network/mcpe/protocol/DataPacketTest.php | 3 ++- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/network/mcpe/protocol/DataPacket.php b/src/network/mcpe/protocol/DataPacket.php index e61ad00f74..be7904ee69 100644 --- a/src/network/mcpe/protocol/DataPacket.php +++ b/src/network/mcpe/protocol/DataPacket.php @@ -55,6 +55,10 @@ abstract class DataPacket implements Packet{ return $this->buf; } + public function setSerializer(PacketSerializer $serializer) : void{ + $this->buf = $serializer; + } + public function pid() : int{ return $this::NETWORK_ID; } @@ -105,7 +109,7 @@ abstract class DataPacket implements Packet{ abstract protected function decodePayload(PacketSerializer $in) : void; final public function encode() : void{ - $this->buf->reset(); + $this->buf = new PacketSerializer(); $this->encodeHeader($this->buf); $this->encodePayload($this->buf); } diff --git a/src/network/mcpe/protocol/Packet.php b/src/network/mcpe/protocol/Packet.php index b2f6317ee5..6ea81b4f75 100644 --- a/src/network/mcpe/protocol/Packet.php +++ b/src/network/mcpe/protocol/Packet.php @@ -29,6 +29,8 @@ interface Packet{ public function getSerializer() : PacketSerializer; + public function setSerializer(PacketSerializer $serializer) : void; + public function pid() : int; public function getName() : string; diff --git a/src/network/mcpe/protocol/PacketPool.php b/src/network/mcpe/protocol/PacketPool.php index dd2b0879b5..14abe765f2 100644 --- a/src/network/mcpe/protocol/PacketPool.php +++ b/src/network/mcpe/protocol/PacketPool.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; -use pocketmine\utils\Binary; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\utils\BinaryDataException; class PacketPool{ @@ -199,9 +199,9 @@ class PacketPool{ * @throws BinaryDataException */ public function getPacket(string $buffer) : Packet{ - $offset = 0; - $pk = $this->getPacketById(Binary::readUnsignedVarInt($buffer, $offset) & DataPacket::PID_MASK); - $pk->getSerializer()->setBuffer($buffer, $offset); + $serializer = new PacketSerializer($buffer); + $pk = $this->getPacketById($serializer->getUnsignedVarInt() & DataPacket::PID_MASK); + $pk->setSerializer($serializer); return $pk; } diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 6c2a76b972..769c7faafa 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -240,8 +240,6 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $chunkVersion = ord($chunkVersionRaw); $hasBeenUpgraded = $chunkVersion < self::CURRENT_LEVEL_CHUNK_VERSION; - $binaryStream = new BinaryStream(); - switch($chunkVersion){ case 15: //MCPE 1.12.0.4 beta (???) case 14: //MCPE 1.11.1.2 (???) @@ -262,7 +260,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ continue; } - $binaryStream->setBuffer($data); + $binaryStream = new BinaryStream($data); if($binaryStream->feof()){ throw new CorruptedChunkException("Unexpected empty data for subchunk $y"); } @@ -324,7 +322,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ } if(($maps2d = $this->db->get($index . self::TAG_DATA_2D)) !== false){ - $binaryStream->setBuffer($maps2d); + $binaryStream = new BinaryStream($maps2d); try{ $binaryStream->get(512); //heightmap, discard it @@ -343,7 +341,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ if($legacyTerrain === false){ throw new CorruptedChunkException("Missing expected LEGACY_TERRAIN tag for format version $chunkVersion"); } - $binaryStream->setBuffer($legacyTerrain); + $binaryStream = new BinaryStream($legacyTerrain); try{ $fullIds = $binaryStream->get(32768); $fullData = $binaryStream->get(16384); diff --git a/tests/phpunit/network/mcpe/protocol/DataPacketTest.php b/tests/phpunit/network/mcpe/protocol/DataPacketTest.php index bcfd0e9d2f..52634b4c5b 100644 --- a/tests/phpunit/network/mcpe/protocol/DataPacketTest.php +++ b/tests/phpunit/network/mcpe/protocol/DataPacketTest.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; use PHPUnit\Framework\TestCase; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; class DataPacketTest extends TestCase{ @@ -34,7 +35,7 @@ class DataPacketTest extends TestCase{ $pk->encode(); $pk2 = new TestPacket(); - $pk2->getSerializer()->setBuffer($pk->getSerializer()->getBuffer()); + $pk2->setSerializer(new PacketSerializer($pk->getSerializer()->getBuffer())); $pk2->decode(); self::assertSame($pk2->senderSubId, 3); self::assertSame($pk2->recipientSubId, 2); From 76e15016a2b52b40c4bc54e8cbbbdf23863ee0da Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jun 2020 13:51:14 +0100 Subject: [PATCH 1638/3224] updated composer dependencies --- composer.lock | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/composer.lock b/composer.lock index e91a2b1c76..2d91d10237 100644 --- a/composer.lock +++ b/composer.lock @@ -294,12 +294,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/BinaryUtils.git", - "reference": "a36705550b42e7e93e2a9748a8b9fa88985780bf" + "reference": "f126c8babe63220ca7141ff696761751c19ca756" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/a36705550b42e7e93e2a9748a8b9fa88985780bf", - "reference": "a36705550b42e7e93e2a9748a8b9fa88985780bf", + "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/f126c8babe63220ca7141ff696761751c19ca756", + "reference": "f126c8babe63220ca7141ff696761751c19ca756", "shasum": "" }, "require": { @@ -320,7 +320,7 @@ "LGPL-3.0" ], "description": "Classes and methods for conveniently handling binary data", - "time": "2020-01-28T12:17:38+00:00" + "time": "2020-06-17T12:14:53+00:00" }, { "name": "pocketmine/callback-validator", @@ -587,12 +587,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "8e42604a7a91d52578af0c9a8024635ed5985b97" + "reference": "bdb818fc048055a3dcd0f86d9d7e1ad733105921" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/8e42604a7a91d52578af0c9a8024635ed5985b97", - "reference": "8e42604a7a91d52578af0c9a8024635ed5985b97", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/bdb818fc048055a3dcd0f86d9d7e1ad733105921", + "reference": "bdb818fc048055a3dcd0f86d9d7e1ad733105921", "shasum": "" }, "require": { @@ -616,7 +616,7 @@ "LGPL-3.0" ], "description": "PHP library for working with Named Binary Tags", - "time": "2020-04-19T12:18:01+00:00" + "time": "2020-06-17T12:18:23+00:00" }, { "name": "pocketmine/raklib", @@ -624,12 +624,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "a63bad0250e3218e606c055fbc77820ce8214fb8" + "reference": "31e2b2259404399cac7f50ae4a9bbdfdd8c1035e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/a63bad0250e3218e606c055fbc77820ce8214fb8", - "reference": "a63bad0250e3218e606c055fbc77820ce8214fb8", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/31e2b2259404399cac7f50ae4a9bbdfdd8c1035e", + "reference": "31e2b2259404399cac7f50ae4a9bbdfdd8c1035e", "shasum": "" }, "require": { @@ -655,7 +655,7 @@ "GPL-3.0" ], "description": "A RakNet server implementation written in PHP", - "time": "2020-06-03T19:14:17+00:00" + "time": "2020-06-17T12:01:42+00:00" }, { "name": "pocketmine/snooze", @@ -1827,16 +1827,16 @@ }, { "name": "phpunit/php-token-stream", - "version": "4.0.1", + "version": "4.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "cdc0db5aed8fbfaf475fbd95bfd7bab83c7a779c" + "reference": "e61c593e9734b47ef462340c24fca8d6a57da14e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/cdc0db5aed8fbfaf475fbd95bfd7bab83c7a779c", - "reference": "cdc0db5aed8fbfaf475fbd95bfd7bab83c7a779c", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e61c593e9734b47ef462340c24fca8d6a57da14e", + "reference": "e61c593e9734b47ef462340c24fca8d6a57da14e", "shasum": "" }, "require": { @@ -1878,7 +1878,7 @@ "type": "github" } ], - "time": "2020-05-06T09:56:31+00:00" + "time": "2020-06-16T07:00:44+00:00" }, { "name": "phpunit/phpunit", @@ -2808,16 +2808,16 @@ }, { "name": "webmozart/assert", - "version": "1.8.0", + "version": "1.9.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "ab2cb0b3b559010b75981b1bdce728da3ee90ad6" + "reference": "9dc4f203e36f2b486149058bade43c851dd97451" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/ab2cb0b3b559010b75981b1bdce728da3ee90ad6", - "reference": "ab2cb0b3b559010b75981b1bdce728da3ee90ad6", + "url": "https://api.github.com/repos/webmozart/assert/zipball/9dc4f203e36f2b486149058bade43c851dd97451", + "reference": "9dc4f203e36f2b486149058bade43c851dd97451", "shasum": "" }, "require": { @@ -2825,6 +2825,7 @@ "symfony/polyfill-ctype": "^1.8" }, "conflict": { + "phpstan/phpstan": "<0.12.20", "vimeo/psalm": "<3.9.1" }, "require-dev": { @@ -2852,7 +2853,7 @@ "check", "validate" ], - "time": "2020-04-18T12:12:48+00:00" + "time": "2020-06-16T10:16:42+00:00" } ], "aliases": [], From 3cdf808da1d5dfcbf3baa8432a685cd9fbedaafb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jun 2020 13:55:29 +0100 Subject: [PATCH 1639/3224] NetworkNbtSerializer: do not assume that this format is related to the disk little-endian format --- .../serializer/NetworkNbtSerializer.php | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/network/mcpe/protocol/serializer/NetworkNbtSerializer.php b/src/network/mcpe/protocol/serializer/NetworkNbtSerializer.php index 91a679323f..e3949444fc 100644 --- a/src/network/mcpe/protocol/serializer/NetworkNbtSerializer.php +++ b/src/network/mcpe/protocol/serializer/NetworkNbtSerializer.php @@ -23,11 +23,23 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\serializer; -use pocketmine\nbt\LittleEndianNbtSerializer; +use pocketmine\nbt\BaseNbtSerializer; use function count; use function strlen; -class NetworkNbtSerializer extends LittleEndianNbtSerializer{ +class NetworkNbtSerializer extends BaseNbtSerializer{ + + public function readShort() : int{ + return $this->buffer->getLShort(); + } + + public function readSignedShort() : int{ + return $this->buffer->getSignedLShort(); + } + + public function writeShort(int $v) : void{ + $this->buffer->putLShort($v); + } public function readInt() : int{ return $this->buffer->getVarInt(); @@ -54,6 +66,22 @@ class NetworkNbtSerializer extends LittleEndianNbtSerializer{ $this->buffer->put($v); } + public function readFloat() : float{ + return $this->buffer->getLFloat(); + } + + public function writeFloat(float $v) : void{ + $this->buffer->putLFloat($v); + } + + public function readDouble() : float{ + return $this->buffer->getLDouble(); + } + + public function writeDouble(float $v) : void{ + $this->buffer->putLDouble($v); + } + public function readIntArray() : array{ $len = $this->readInt(); //varint $ret = []; From 506f98efc474ba4c1bfd12a58d9bf32154dfe1d2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jun 2020 14:31:56 +0100 Subject: [PATCH 1640/3224] Eliminate usages of BaseNbtSerializer->readCompressed() and BaseNbtSerializer->writeCompressed() --- src/Server.php | 30 ++++++++++++++++--- src/world/format/io/data/JavaWorldData.php | 13 ++++++-- .../io/region/LegacyAnvilChunkTrait.php | 7 ++++- src/world/format/io/region/McRegion.php | 7 ++++- 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/Server.php b/src/Server.php index 728084a640..8bc2da6745 100644 --- a/src/Server.php +++ b/src/Server.php @@ -141,10 +141,14 @@ use function time; use function touch; use function trim; use function yaml_parse; +use function zlib_decode; +use function zlib_encode; use const DIRECTORY_SEPARATOR; use const PHP_EOL; use const PHP_INT_MAX; use const PTHREADS_INHERIT_NONE; +use const ZLIB_ENCODING_DEFLATE; +use const ZLIB_ENCODING_GZIP; /** * The class that manages everything @@ -511,16 +515,34 @@ class Server{ return file_exists($this->getPlayerDataPath($name)); } + private function handleCorruptedPlayerData(string $name) : void{ + $path = $this->getPlayerDataPath($name); + rename($path, $path . '.bak'); + $this->logger->error($this->getLanguage()->translateString("pocketmine.data.playerCorrupted", [$name])); + } + public function getOfflinePlayerData(string $name) : ?CompoundTag{ $name = strtolower($name); $path = $this->getPlayerDataPath($name); if(file_exists($path)){ + $contents = @file_get_contents($path); + if($contents === false){ + throw new \RuntimeException("Failed to read player data file \"$path\" (permission denied?)"); + } + $decompressed = @zlib_decode($contents); + if($decompressed === false){ + $this->logger->debug("Failed to decompress raw player data for \"$name\""); + $this->handleCorruptedPlayerData($name); + return null; + } + try{ - return (new BigEndianNbtSerializer())->readCompressed(file_get_contents($path))->mustGetCompoundTag(); + return (new BigEndianNbtSerializer())->read($decompressed)->mustGetCompoundTag(); }catch(NbtDataException $e){ //zlib decode error / corrupt data - rename($path, $path . '.bak'); - $this->logger->error($this->getLanguage()->translateString("pocketmine.data.playerCorrupted", [$name])); + $this->logger->debug("Failed to decode NBT data for \"$name\": " . $e->getMessage()); + $this->handleCorruptedPlayerData($name); + return null; } } return null; @@ -535,7 +557,7 @@ class Server{ if(!$ev->isCancelled()){ $nbt = new BigEndianNbtSerializer(); try{ - file_put_contents($this->getPlayerDataPath($name), $nbt->writeCompressed(new TreeRoot($ev->getSaveData()))); + file_put_contents($this->getPlayerDataPath($name), zlib_encode($nbt->write(new TreeRoot($ev->getSaveData())), ZLIB_ENCODING_GZIP)); }catch(\ErrorException $e){ $this->logger->critical($this->getLanguage()->translateString("pocketmine.data.saveError", [$name, $e->getMessage()])); $this->logger->logException($e); diff --git a/src/world/format/io/data/JavaWorldData.php b/src/world/format/io/data/JavaWorldData.php index f01d1446d7..279c99c9b5 100644 --- a/src/world/format/io/data/JavaWorldData.php +++ b/src/world/format/io/data/JavaWorldData.php @@ -38,6 +38,9 @@ use function ceil; use function file_get_contents; use function file_put_contents; use function microtime; +use function zlib_decode; +use function zlib_encode; +use const ZLIB_ENCODING_GZIP; class JavaWorldData extends BaseNbtWorldData{ @@ -70,7 +73,7 @@ class JavaWorldData extends BaseNbtWorldData{ ->setTag("GameRules", new CompoundTag()); $nbt = new BigEndianNbtSerializer(); - $buffer = $nbt->writeCompressed(new TreeRoot(CompoundTag::create()->setTag("Data", $worldData))); + $buffer = zlib_encode($nbt->write(new TreeRoot(CompoundTag::create()->setTag("Data", $worldData))), ZLIB_ENCODING_GZIP); file_put_contents($path . "level.dat", $buffer); } @@ -80,8 +83,12 @@ class JavaWorldData extends BaseNbtWorldData{ throw new CorruptedWorldException("Failed to read level.dat (permission denied or doesn't exist)"); } $nbt = new BigEndianNbtSerializer(); + $decompressed = @zlib_decode($rawLevelData); + if($decompressed === false){ + throw new CorruptedWorldException("Failed to decompress level.dat contents"); + } try{ - $worldData = $nbt->readCompressed($rawLevelData)->mustGetCompoundTag(); + $worldData = $nbt->read($decompressed)->mustGetCompoundTag(); }catch(NbtDataException $e){ throw new CorruptedWorldException($e->getMessage(), 0, $e); } @@ -106,7 +113,7 @@ class JavaWorldData extends BaseNbtWorldData{ public function save() : void{ $nbt = new BigEndianNbtSerializer(); - $buffer = $nbt->writeCompressed(new TreeRoot(CompoundTag::create()->setTag("Data", $this->compoundTag))); + $buffer = zlib_encode($nbt->write(new TreeRoot(CompoundTag::create()->setTag("Data", $this->compoundTag))), ZLIB_ENCODING_GZIP); file_put_contents($this->dataPath, $buffer); } diff --git a/src/world/format/io/region/LegacyAnvilChunkTrait.php b/src/world/format/io/region/LegacyAnvilChunkTrait.php index bc06f7ed0b..ae5521e7b9 100644 --- a/src/world/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/world/format/io/region/LegacyAnvilChunkTrait.php @@ -34,6 +34,7 @@ use pocketmine\world\format\Chunk; use pocketmine\world\format\io\ChunkUtils; use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\SubChunk; +use function zlib_decode; /** * Trait containing I/O methods for handling legacy Anvil-style chunks. @@ -54,9 +55,13 @@ trait LegacyAnvilChunkTrait{ * @throws CorruptedChunkException */ protected function deserializeChunk(string $data) : Chunk{ + $decompressed = @zlib_decode($data); + if($decompressed === false){ + throw new CorruptedChunkException("Failed to decompress chunk NBT"); + } $nbt = new BigEndianNbtSerializer(); try{ - $chunk = $nbt->readCompressed($data)->mustGetCompoundTag(); + $chunk = $nbt->read($decompressed)->mustGetCompoundTag(); }catch(NbtDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } diff --git a/src/world/format/io/region/McRegion.php b/src/world/format/io/region/McRegion.php index f6de24ea42..73f24e021b 100644 --- a/src/world/format/io/region/McRegion.php +++ b/src/world/format/io/region/McRegion.php @@ -36,6 +36,7 @@ use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\SubChunkConverter; use pocketmine\world\format\SubChunk; use function str_repeat; +use function zlib_decode; class McRegion extends RegionWorldProvider{ @@ -50,9 +51,13 @@ class McRegion extends RegionWorldProvider{ * @throws CorruptedChunkException */ protected function deserializeChunk(string $data) : Chunk{ + $decompressed = @zlib_decode($data); + if($decompressed === false){ + throw new CorruptedChunkException("Failed to decompress chunk NBT"); + } $nbt = new BigEndianNbtSerializer(); try{ - $chunk = $nbt->readCompressed($data)->mustGetCompoundTag(); + $chunk = $nbt->read($decompressed)->mustGetCompoundTag(); }catch(NbtDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } From 4bb93eeca7c8ab847e15bdb12cee89d729209b22 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jun 2020 14:32:57 +0100 Subject: [PATCH 1641/3224] updated composer dependencies --- composer.lock | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/composer.lock b/composer.lock index 2d91d10237..0ab79499ec 100644 --- a/composer.lock +++ b/composer.lock @@ -587,16 +587,15 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "bdb818fc048055a3dcd0f86d9d7e1ad733105921" + "reference": "b99216a32b96109db8f43c039c2f705c0ecd730a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/bdb818fc048055a3dcd0f86d9d7e1ad733105921", - "reference": "bdb818fc048055a3dcd0f86d9d7e1ad733105921", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/b99216a32b96109db8f43c039c2f705c0ecd730a", + "reference": "b99216a32b96109db8f43c039c2f705c0ecd730a", "shasum": "" }, "require": { - "ext-zlib": "*", "php": ">=7.2.0", "php-64bit": "*", "pocketmine/binaryutils": "dev-master" @@ -616,7 +615,7 @@ "LGPL-3.0" ], "description": "PHP library for working with Named Binary Tags", - "time": "2020-06-17T12:18:23+00:00" + "time": "2020-06-17T13:22:22+00:00" }, { "name": "pocketmine/raklib", From 57908586bdeb9f6840ff7493223a0aab933b1d19 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jun 2020 19:00:11 +0100 Subject: [PATCH 1642/3224] more jsonmapper models for login --- src/network/mcpe/auth/ProcessLoginTask.php | 36 ++++++++++++--- .../protocol/types/login/JwtBodyRfc7519.php | 45 +++++++++++++++++++ .../protocol/types/login/JwtChainLinkBody.php | 33 ++++++++++++++ .../mcpe/protocol/types/login/JwtHeader.php | 37 +++++++++++++++ 4 files changed, 146 insertions(+), 5 deletions(-) create mode 100644 src/network/mcpe/protocol/types/login/JwtBodyRfc7519.php create mode 100644 src/network/mcpe/protocol/types/login/JwtChainLinkBody.php create mode 100644 src/network/mcpe/protocol/types/login/JwtHeader.php diff --git a/src/network/mcpe/auth/ProcessLoginTask.php b/src/network/mcpe/auth/ProcessLoginTask.php index 9fd706582c..b92015560f 100644 --- a/src/network/mcpe/auth/ProcessLoginTask.php +++ b/src/network/mcpe/auth/ProcessLoginTask.php @@ -29,6 +29,8 @@ use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; use pocketmine\network\mcpe\JwtException; use pocketmine\network\mcpe\JwtUtils; use pocketmine\network\mcpe\protocol\LoginPacket; +use pocketmine\network\mcpe\protocol\types\login\JwtChainLinkBody; +use pocketmine\network\mcpe\protocol\types\login\JwtHeader; use pocketmine\scheduler\AsyncTask; use function base64_decode; use function time; @@ -106,18 +108,30 @@ class ProcessLoginTask extends AsyncTask{ */ private function validateToken(string $jwt, ?string &$currentPublicKey, bool $first = false) : void{ try{ - [$headers, $claims, ] = JwtUtils::parse($jwt); + [$headersArray, $claimsArray, ] = JwtUtils::parse($jwt); }catch(JwtException $e){ throw new VerifyLoginException("Failed to parse JWT: " . $e->getMessage(), 0, $e); } + $mapper = new \JsonMapper(); + $mapper->bExceptionOnMissingData = true; + $mapper->bExceptionOnUndefinedProperty = true; + $mapper->bEnforceMapType = false; + + try{ + /** @var JwtHeader $headers */ + $headers = $mapper->map($headersArray, new JwtHeader()); + }catch(\JsonMapper_Exception $e){ + throw new VerifyLoginException("Invalid JWT header: " . $e->getMessage(), 0, $e); + } + if($currentPublicKey === null){ if(!$first){ throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.missingKey"); } //First link, check that it is self-signed - $currentPublicKey = $headers["x5u"]; + $currentPublicKey = $headers->x5u; } $derPublicKeySerializer = new DerPublicKeySerializer(); @@ -143,16 +157,28 @@ class ProcessLoginTask extends AsyncTask{ $this->authenticated = true; //we're signed into xbox live } + $mapper = new \JsonMapper(); + $mapper->bExceptionOnUndefinedProperty = false; //we only care about the properties we're using in this case + $mapper->bExceptionOnMissingData = true; + $mapper->bEnforceMapType = false; + $mapper->bRemoveUndefinedAttributes = true; + try{ + /** @var JwtChainLinkBody $claims */ + $claims = $mapper->map($claimsArray, new JwtChainLinkBody()); + }catch(\JsonMapper_Exception $e){ + throw new VerifyLoginException("Invalid chain link body: " . $e->getMessage(), 0, $e); + } + $time = time(); - if(isset($claims["nbf"]) and $claims["nbf"] > $time + self::CLOCK_DRIFT_MAX){ + if(isset($claims->nbf) and $claims->nbf > $time + self::CLOCK_DRIFT_MAX){ throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.tooEarly"); } - if(isset($claims["exp"]) and $claims["exp"] < $time - self::CLOCK_DRIFT_MAX){ + if(isset($claims->exp) and $claims->exp < $time - self::CLOCK_DRIFT_MAX){ throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.tooLate"); } - $currentPublicKey = $claims["identityPublicKey"] ?? null; //if there are further links, the next link should be signed with this + $currentPublicKey = $claims->identityPublicKey ?? null; //if there are further links, the next link should be signed with this } public function onCompletion() : void{ diff --git a/src/network/mcpe/protocol/types/login/JwtBodyRfc7519.php b/src/network/mcpe/protocol/types/login/JwtBodyRfc7519.php new file mode 100644 index 0000000000..301779401b --- /dev/null +++ b/src/network/mcpe/protocol/types/login/JwtBodyRfc7519.php @@ -0,0 +1,45 @@ + Date: Wed, 17 Jun 2020 21:24:12 +0100 Subject: [PATCH 1643/3224] moved skin-parsing code from LoginPacketHandler to its own dedicated helper class --- .../mcpe/handler/LoginPacketHandler.php | 46 +--------- .../login/ClientDataToSkinDataHelper.php | 86 +++++++++++++++++++ 2 files changed, 88 insertions(+), 44 deletions(-) create mode 100644 src/network/mcpe/protocol/types/login/ClientDataToSkinDataHelper.php diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index 496871ebc1..7203f4bd06 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -38,6 +38,7 @@ use pocketmine\network\mcpe\protocol\types\login\AuthenticationData; use pocketmine\network\mcpe\protocol\types\login\ClientData; use pocketmine\network\mcpe\protocol\types\login\ClientDataPersonaPieceTintColor; use pocketmine\network\mcpe\protocol\types\login\ClientDataPersonaSkinPiece; +use pocketmine\network\mcpe\protocol\types\login\ClientDataToSkinDataHelper; use pocketmine\network\mcpe\protocol\types\login\JwtChain; use pocketmine\network\mcpe\protocol\types\PersonaPieceTintColor; use pocketmine\network\mcpe\protocol\types\PersonaSkinPiece; @@ -109,51 +110,8 @@ class LoginPacketHandler extends PacketHandler{ } $clientData = $this->parseClientData($packet->clientDataJwt); - $safeB64Decode = static function(string $base64, string $context) : string{ - $result = base64_decode($base64, true); - if($result === false){ - throw new \InvalidArgumentException("$context: Malformed base64, cannot be decoded"); - } - return $result; - }; try{ - /** @var SkinAnimation[] $animations */ - $animations = []; - foreach($clientData->AnimatedImageData as $k => $animation){ - $animations[] = new SkinAnimation( - new SkinImage( - $animation->ImageHeight, - $animation->ImageWidth, - $safeB64Decode($animation->Image, "AnimatedImageData.$k.Image") - ), - $animation->Type, - $animation->Frames - ); - } - $skinData = new SkinData( - $clientData->SkinId, - $safeB64Decode($clientData->SkinResourcePatch, "SkinResourcePatch"), - new SkinImage($clientData->SkinImageHeight, $clientData->SkinImageWidth, $safeB64Decode($clientData->SkinData, "SkinData")), - $animations, - new SkinImage($clientData->CapeImageHeight, $clientData->CapeImageWidth, $safeB64Decode($clientData->CapeData, "CapeData")), - $safeB64Decode($clientData->SkinGeometryData, "SkinGeometryData"), - $safeB64Decode($clientData->SkinAnimationData, "SkinAnimationData"), - $clientData->PremiumSkin, - $clientData->PersonaSkin, - $clientData->CapeOnClassicSkin, - $clientData->CapeId, - null, - $clientData->ArmSize, - $clientData->SkinColor, - array_map(function(ClientDataPersonaSkinPiece $piece) : PersonaSkinPiece{ - return new PersonaSkinPiece($piece->PieceId, $piece->PieceType, $piece->PackId, $piece->IsDefault, $piece->ProductId); - }, $clientData->PersonaPieces), - array_map(function(ClientDataPersonaPieceTintColor $tint) : PersonaPieceTintColor{ - return new PersonaPieceTintColor($tint->PieceType, $tint->Colors); - }, $clientData->PieceTintColors) - ); - - $skin = SkinAdapterSingleton::get()->fromSkinData($skinData); + $skin = SkinAdapterSingleton::get()->fromSkinData(ClientDataToSkinDataHelper::getInstance()->fromClientData($clientData)); }catch(\InvalidArgumentException $e){ $this->session->getLogger()->debug("Invalid skin: " . $e->getMessage()); $this->session->disconnect("disconnectionScreen.invalidSkin"); diff --git a/src/network/mcpe/protocol/types/login/ClientDataToSkinDataHelper.php b/src/network/mcpe/protocol/types/login/ClientDataToSkinDataHelper.php new file mode 100644 index 0000000000..e334c0e5d3 --- /dev/null +++ b/src/network/mcpe/protocol/types/login/ClientDataToSkinDataHelper.php @@ -0,0 +1,86 @@ +AnimatedImageData as $k => $animation){ + $animations[] = new SkinAnimation( + new SkinImage( + $animation->ImageHeight, + $animation->ImageWidth, + $safeB64Decode($animation->Image, "AnimatedImageData.$k.Image") + ), + $animation->Type, + $animation->Frames + ); + } + return new SkinData( + $clientData->SkinId, + $safeB64Decode($clientData->SkinResourcePatch, "SkinResourcePatch"), + new SkinImage($clientData->SkinImageHeight, $clientData->SkinImageWidth, $safeB64Decode($clientData->SkinData, "SkinData")), + $animations, + new SkinImage($clientData->CapeImageHeight, $clientData->CapeImageWidth, $safeB64Decode($clientData->CapeData, "CapeData")), + $safeB64Decode($clientData->SkinGeometryData, "SkinGeometryData"), + $safeB64Decode($clientData->SkinAnimationData, "SkinAnimationData"), + $clientData->PremiumSkin, + $clientData->PersonaSkin, + $clientData->CapeOnClassicSkin, + $clientData->CapeId, + null, + $clientData->ArmSize, + $clientData->SkinColor, + array_map(function(ClientDataPersonaSkinPiece $piece) : PersonaSkinPiece{ + return new PersonaSkinPiece($piece->PieceId, $piece->PieceType, $piece->PackId, $piece->IsDefault, $piece->ProductId); + }, $clientData->PersonaPieces), + array_map(function(ClientDataPersonaPieceTintColor $tint) : PersonaPieceTintColor{ + return new PersonaPieceTintColor($tint->PieceType, $tint->Colors); + }, $clientData->PieceTintColors) + ); + } +} \ No newline at end of file From 7558f2cb1252e8126a184b11e0dac22781f75b74 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jun 2020 21:27:51 +0100 Subject: [PATCH 1644/3224] regenerated phpstan level 8 baseline --- tests/phpstan/configs/l8-baseline.neon | 40 ++++---------------------- 1 file changed, 5 insertions(+), 35 deletions(-) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index e66475f1e6..19c3f1f46a 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -415,26 +415,6 @@ parameters: count: 1 path: ../../../src/network/mcpe/NetworkSession.php - - - message: "#^Cannot call method getLocation\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" - count: 3 - path: ../../../src/network/mcpe/NetworkSession.php - - - - message: "#^Cannot call method getId\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" - count: 1 - path: ../../../src/network/mcpe/NetworkSession.php - - - - message: "#^Cannot call method getOffsetPosition\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" - count: 1 - path: ../../../src/network/mcpe/NetworkSession.php - - - - message: "#^Cannot access property \\$onGround on pocketmine\\\\player\\\\Player\\|null\\.$#" - count: 1 - path: ../../../src/network/mcpe/NetworkSession.php - - message: "#^Cannot call method syncCreative\\(\\) on pocketmine\\\\network\\\\mcpe\\\\InventoryManager\\|null\\.$#" count: 1 @@ -445,6 +425,11 @@ parameters: count: 1 path: ../../../src/network/mcpe/NetworkSession.php + - + message: "#^Cannot call method getLocation\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" + count: 2 + path: ../../../src/network/mcpe/NetworkSession.php + - message: "#^Cannot call method isUsingChunk\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" count: 1 @@ -535,21 +520,6 @@ parameters: count: 1 path: ../../../src/network/mcpe/protocol/SetScoreboardIdentityPacket.php - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\entity\\\\EntityLink\\:\\:\\$fromEntityUniqueId \\(int\\) does not accept int\\|null\\.$#" - count: 1 - path: ../../../src/network/mcpe/protocol/types/entity/EntityLink.php - - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\entity\\\\EntityLink\\:\\:\\$toEntityUniqueId \\(int\\) does not accept int\\|null\\.$#" - count: 1 - path: ../../../src/network/mcpe/protocol/types/entity/EntityLink.php - - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\entity\\\\EntityLink\\:\\:\\$type \\(int\\) does not accept int\\|null\\.$#" - count: 1 - path: ../../../src/network/mcpe/protocol/types/entity/EntityLink.php - - message: "#^Parameter \\#1 \\$v of method pocketmine\\\\utils\\\\BinaryStream\\:\\:putVarInt\\(\\) expects int, int\\|null given\\.$#" count: 1 From eefb6ae8e7a109a97658b7c6c5768cbffaed58a1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jun 2020 21:29:16 +0100 Subject: [PATCH 1645/3224] LoginPacketHandler: use reference to new PlayerInfo directly, fixes a PHPStan level 8 error --- src/network/mcpe/handler/LoginPacketHandler.php | 7 ++++--- tests/phpstan/configs/l8-baseline.neon | 5 ----- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index 7203f4bd06..c6577d6251 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -124,17 +124,18 @@ class LoginPacketHandler extends PacketHandler{ }catch(\InvalidArgumentException $e){ throw BadPacketException::wrap($e, "Failed to parse login UUID"); } - ($this->playerInfoConsumer)(new PlayerInfo( + $playerInfo = new PlayerInfo( $extraData->displayName, $uuid, $skin, $clientData->LanguageCode, $extraData->XUID, (array) $clientData - )); + ); + ($this->playerInfoConsumer)($playerInfo); $ev = new PlayerPreLoginEvent( - $this->session->getPlayerInfo(), + $playerInfo, $this->session->getIp(), $this->session->getPort(), $this->server->requiresAuthentication() diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 19c3f1f46a..8b49c96809 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -485,11 +485,6 @@ parameters: count: 1 path: ../../../src/network/mcpe/encryption/PrepareEncryptionTask.php - - - message: "#^Parameter \\#1 \\$playerInfo of class pocketmine\\\\event\\\\player\\\\PlayerPreLoginEvent constructor expects pocketmine\\\\player\\\\PlayerInfo, pocketmine\\\\player\\\\PlayerInfo\\|null given\\.$#" - count: 1 - path: ../../../src/network/mcpe/handler/LoginPacketHandler.php - - message: "#^Cannot call method getUsername\\(\\) on pocketmine\\\\player\\\\PlayerInfo\\|null\\.$#" count: 2 From 715fca89863bc9461bf9f7a826dbb0c286aab202 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jun 2020 21:30:34 +0100 Subject: [PATCH 1646/3224] LoginPacketHandler: use playerInfo directly again, fix another 2 PHPStan level 8 errors --- src/network/mcpe/handler/LoginPacketHandler.php | 4 ++-- tests/phpstan/configs/l8-baseline.neon | 5 ----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index c6577d6251..99dfd0c21b 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -143,10 +143,10 @@ class LoginPacketHandler extends PacketHandler{ if($this->server->getNetwork()->getConnectionCount() > $this->server->getMaxPlayers()){ $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_SERVER_FULL, "disconnectionScreen.serverFull"); } - if(!$this->server->isWhitelisted($this->session->getPlayerInfo()->getUsername())){ + if(!$this->server->isWhitelisted($playerInfo->getUsername())){ $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_SERVER_WHITELISTED, "Server is whitelisted"); } - if($this->server->getNameBans()->isBanned($this->session->getPlayerInfo()->getUsername()) or $this->server->getIPBans()->isBanned($this->session->getIp())){ + if($this->server->getNameBans()->isBanned($playerInfo->getUsername()) or $this->server->getIPBans()->isBanned($this->session->getIp())){ $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_BANNED, "You are banned"); } diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 8b49c96809..724427da11 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -485,11 +485,6 @@ parameters: count: 1 path: ../../../src/network/mcpe/encryption/PrepareEncryptionTask.php - - - message: "#^Cannot call method getUsername\\(\\) on pocketmine\\\\player\\\\PlayerInfo\\|null\\.$#" - count: 2 - path: ../../../src/network/mcpe/handler/LoginPacketHandler.php - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\StartGamePacket\\:\\:\\$blockTable \\(pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\CacheableNbt\\\\) does not accept pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\CacheableNbt\\\\|null\\.$#" count: 1 From 333ed8ed2fa6d1d132bb817e7a8290c4ca3ba55c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jun 2020 21:32:51 +0100 Subject: [PATCH 1647/3224] RuntimeBlockMapping: remove unnecessary nullable flag --- src/network/mcpe/convert/RuntimeBlockMapping.php | 2 +- tests/phpstan/configs/l8-baseline.neon | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/network/mcpe/convert/RuntimeBlockMapping.php b/src/network/mcpe/convert/RuntimeBlockMapping.php index 056842172e..54002ed509 100644 --- a/src/network/mcpe/convert/RuntimeBlockMapping.php +++ b/src/network/mcpe/convert/RuntimeBlockMapping.php @@ -160,7 +160,7 @@ final class RuntimeBlockMapping{ /** * @phpstan-return CacheableNbt<\pocketmine\nbt\tag\ListTag> */ - public function getStartGamePaletteCache() : ?CacheableNbt{ + public function getStartGamePaletteCache() : CacheableNbt{ return $this->startGamePaletteCache ?? new CacheableNbt(new ListTag($this->bedrockKnownStates)); } } diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 724427da11..4b7cfbd5af 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -485,11 +485,6 @@ parameters: count: 1 path: ../../../src/network/mcpe/encryption/PrepareEncryptionTask.php - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\StartGamePacket\\:\\:\\$blockTable \\(pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\CacheableNbt\\\\) does not accept pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\CacheableNbt\\\\|null\\.$#" - count: 1 - path: ../../../src/network/mcpe/handler/PreSpawnPacketHandler.php - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\LevelSoundEventPacket\\:\\:\\$position \\(pocketmine\\\\math\\\\Vector3\\) does not accept pocketmine\\\\math\\\\Vector3\\|null\\.$#" count: 1 From a686840e5e2fe3126729197f4e6dd08bda678fe3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jun 2020 21:33:56 +0100 Subject: [PATCH 1648/3224] RuntimeBlockMapping: fixed palette cache never being initialized I must have been very tired when I wrote this code --- src/network/mcpe/convert/RuntimeBlockMapping.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/convert/RuntimeBlockMapping.php b/src/network/mcpe/convert/RuntimeBlockMapping.php index 54002ed509..9c4b08536f 100644 --- a/src/network/mcpe/convert/RuntimeBlockMapping.php +++ b/src/network/mcpe/convert/RuntimeBlockMapping.php @@ -161,6 +161,6 @@ final class RuntimeBlockMapping{ * @phpstan-return CacheableNbt<\pocketmine\nbt\tag\ListTag> */ public function getStartGamePaletteCache() : CacheableNbt{ - return $this->startGamePaletteCache ?? new CacheableNbt(new ListTag($this->bedrockKnownStates)); + return $this->startGamePaletteCache ?? ($this->startGamePaletteCache = new CacheableNbt(new ListTag($this->bedrockKnownStates))); } } From 05615b3eb7cf0de809db03aba780dcea0f955ec5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jun 2020 22:27:13 +0100 Subject: [PATCH 1649/3224] ClientDataToSkinDataHelper: move safeB64Decode to its own function --- .../login/ClientDataToSkinDataHelper.php | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/network/mcpe/protocol/types/login/ClientDataToSkinDataHelper.php b/src/network/mcpe/protocol/types/login/ClientDataToSkinDataHelper.php index e334c0e5d3..2ed495eb87 100644 --- a/src/network/mcpe/protocol/types/login/ClientDataToSkinDataHelper.php +++ b/src/network/mcpe/protocol/types/login/ClientDataToSkinDataHelper.php @@ -38,15 +38,18 @@ final class ClientDataToSkinDataHelper{ /** * @throws \InvalidArgumentException */ - public function fromClientData(ClientData $clientData) : SkinData{ - $safeB64Decode = static function(string $base64, string $context) : string{ - $result = base64_decode($base64, true); - if($result === false){ - throw new \InvalidArgumentException("$context: Malformed base64, cannot be decoded"); - } - return $result; - }; + private static function safeB64Decode(string $base64, string $context) : string{ + $result = base64_decode($base64, true); + if($result === false){ + throw new \InvalidArgumentException("$context: Malformed base64, cannot be decoded"); + } + return $result; + } + /** + * @throws \InvalidArgumentException + */ + public function fromClientData(ClientData $clientData) : SkinData{ /** @var SkinAnimation[] $animations */ $animations = []; foreach($clientData->AnimatedImageData as $k => $animation){ @@ -54,7 +57,7 @@ final class ClientDataToSkinDataHelper{ new SkinImage( $animation->ImageHeight, $animation->ImageWidth, - $safeB64Decode($animation->Image, "AnimatedImageData.$k.Image") + self::safeB64Decode($animation->Image, "AnimatedImageData.$k.Image") ), $animation->Type, $animation->Frames @@ -62,12 +65,12 @@ final class ClientDataToSkinDataHelper{ } return new SkinData( $clientData->SkinId, - $safeB64Decode($clientData->SkinResourcePatch, "SkinResourcePatch"), - new SkinImage($clientData->SkinImageHeight, $clientData->SkinImageWidth, $safeB64Decode($clientData->SkinData, "SkinData")), + self::safeB64Decode($clientData->SkinResourcePatch, "SkinResourcePatch"), + new SkinImage($clientData->SkinImageHeight, $clientData->SkinImageWidth, self::safeB64Decode($clientData->SkinData, "SkinData")), $animations, - new SkinImage($clientData->CapeImageHeight, $clientData->CapeImageWidth, $safeB64Decode($clientData->CapeData, "CapeData")), - $safeB64Decode($clientData->SkinGeometryData, "SkinGeometryData"), - $safeB64Decode($clientData->SkinAnimationData, "SkinAnimationData"), + new SkinImage($clientData->CapeImageHeight, $clientData->CapeImageWidth, self::safeB64Decode($clientData->CapeData, "CapeData")), + self::safeB64Decode($clientData->SkinGeometryData, "SkinGeometryData"), + self::safeB64Decode($clientData->SkinAnimationData, "SkinAnimationData"), $clientData->PremiumSkin, $clientData->PersonaSkin, $clientData->CapeOnClassicSkin, From 6f4d4be3dac85223813a84de4759bf367329ea2a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jun 2020 22:31:44 +0100 Subject: [PATCH 1650/3224] InGamePacketHandler: handle InvalidSkinException thrown by SkinAdapter::fromSkinData() --- src/network/mcpe/handler/InGamePacketHandler.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 0514c6e909..3f46d8792d 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -27,6 +27,7 @@ use pocketmine\block\ItemFrame; use pocketmine\block\Sign; use pocketmine\block\utils\SignText; use pocketmine\entity\animation\ConsumingItemAnimation; +use pocketmine\entity\InvalidSkinException; use pocketmine\event\player\PlayerEditBookEvent; use pocketmine\inventory\transaction\action\InventoryAction; use pocketmine\inventory\transaction\CraftingTransaction; @@ -634,7 +635,12 @@ class InGamePacketHandler extends PacketHandler{ } public function handlePlayerSkin(PlayerSkinPacket $packet) : bool{ - return $this->player->changeSkin(SkinAdapterSingleton::get()->fromSkinData($packet->skin), $packet->newSkinName, $packet->oldSkinName); + try{ + $skin = SkinAdapterSingleton::get()->fromSkinData($packet->skin); + }catch(InvalidSkinException $e){ + throw BadPacketException::wrap($e, "Invalid skin in PlayerSkinPacket"); + } + return $this->player->changeSkin($skin, $packet->newSkinName, $packet->oldSkinName); } public function handleSubClientLogin(SubClientLoginPacket $packet) : bool{ From 82b3e3398b67232cf5fa6ab19e7b7cc98d7d99c0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Jun 2020 23:03:03 +0100 Subject: [PATCH 1651/3224] make more use of igbinary_serialize() and igbinary_unserialize() --- src/network/mcpe/auth/ProcessLoginTask.php | 8 ++++---- src/scheduler/AsyncTask.php | 12 ++++++------ src/scheduler/BulkCurlTask.php | 8 ++++---- src/world/generator/GeneratorRegisterTask.php | 8 ++++---- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/network/mcpe/auth/ProcessLoginTask.php b/src/network/mcpe/auth/ProcessLoginTask.php index c65203613b..c19f679843 100644 --- a/src/network/mcpe/auth/ProcessLoginTask.php +++ b/src/network/mcpe/auth/ProcessLoginTask.php @@ -32,9 +32,9 @@ use pocketmine\network\mcpe\protocol\types\login\JwtChainLinkBody; use pocketmine\network\mcpe\protocol\types\login\JwtHeader; use pocketmine\scheduler\AsyncTask; use function base64_decode; -use function serialize; +use function igbinary_serialize; +use function igbinary_unserialize; use function time; -use function unserialize; class ProcessLoginTask extends AsyncTask{ private const TLS_KEY_ON_COMPLETION = "completion"; @@ -73,7 +73,7 @@ class ProcessLoginTask extends AsyncTask{ */ public function __construct(array $chainJwts, string $clientDataJwt, bool $authRequired, \Closure $onCompletion){ $this->storeLocal(self::TLS_KEY_ON_COMPLETION, $onCompletion); - $this->chain = serialize($chainJwts); + $this->chain = igbinary_serialize($chainJwts); $this->clientDataJwt = $clientDataJwt; $this->authRequired = $authRequired; } @@ -89,7 +89,7 @@ class ProcessLoginTask extends AsyncTask{ private function validateChain() : PublicKeyInterface{ /** @var string[] $chain */ - $chain = unserialize($this->chain); + $chain = igbinary_unserialize($this->chain); $currentKey = null; $first = true; diff --git a/src/scheduler/AsyncTask.php b/src/scheduler/AsyncTask.php index 29ff9a3bdc..cd79e6f409 100644 --- a/src/scheduler/AsyncTask.php +++ b/src/scheduler/AsyncTask.php @@ -24,11 +24,11 @@ declare(strict_types=1); namespace pocketmine\scheduler; use pocketmine\utils\AssumptionFailedError; +use function igbinary_serialize; +use function igbinary_unserialize; use function is_scalar; use function is_string; -use function serialize; use function spl_object_id; -use function unserialize; /** * Class used to run async tasks in other threads. @@ -109,7 +109,7 @@ abstract class AsyncTask extends \Threaded{ public function getResult(){ if($this->serialized){ if(!is_string($this->result)) throw new AssumptionFailedError("Result expected to be a serialized string"); - return unserialize($this->result); + return igbinary_unserialize($this->result); } return $this->result; } @@ -130,7 +130,7 @@ abstract class AsyncTask extends \Threaded{ * @param mixed $result */ public function setResult($result) : void{ - $this->result = ($this->serialized = !is_scalar($result)) ? serialize($result) : $result; + $this->result = ($this->serialized = !is_scalar($result)) ? igbinary_serialize($result) : $result; } public function setSubmitted() : void{ @@ -161,7 +161,7 @@ abstract class AsyncTask extends \Threaded{ * @param mixed $progress A value that can be safely serialize()'ed. */ public function publishProgress($progress) : void{ - $this->progressUpdates[] = serialize($progress); + $this->progressUpdates[] = igbinary_serialize($progress); } /** @@ -170,7 +170,7 @@ abstract class AsyncTask extends \Threaded{ public function checkProgressUpdates() : void{ while($this->progressUpdates->count() !== 0){ $progress = $this->progressUpdates->shift(); - $this->onProgressUpdate(unserialize($progress)); + $this->onProgressUpdate(igbinary_unserialize($progress)); } } diff --git a/src/scheduler/BulkCurlTask.php b/src/scheduler/BulkCurlTask.php index 5dd534ebdc..bd9a3b0594 100644 --- a/src/scheduler/BulkCurlTask.php +++ b/src/scheduler/BulkCurlTask.php @@ -25,8 +25,8 @@ namespace pocketmine\scheduler; use pocketmine\utils\Internet; use pocketmine\utils\InternetException; -use function serialize; -use function unserialize; +use function igbinary_serialize; +use function igbinary_unserialize; /** * Executes a consecutive list of cURL operations. @@ -48,12 +48,12 @@ class BulkCurlTask extends AsyncTask{ * @phpstan-param list, extraOpts?: array}> $operations */ public function __construct(array $operations){ - $this->operations = serialize($operations); + $this->operations = igbinary_serialize($operations); } public function onRun() : void{ /** @phpstan-var list, extraOpts?: array}> $operations */ - $operations = unserialize($this->operations); + $operations = igbinary_unserialize($this->operations); $results = []; foreach($operations as $op){ try{ diff --git a/src/world/generator/GeneratorRegisterTask.php b/src/world/generator/GeneratorRegisterTask.php index d002351207..25f4777d6b 100644 --- a/src/world/generator/GeneratorRegisterTask.php +++ b/src/world/generator/GeneratorRegisterTask.php @@ -26,8 +26,8 @@ namespace pocketmine\world\generator; use pocketmine\scheduler\AsyncTask; use pocketmine\world\biome\Biome; use pocketmine\world\World; -use function serialize; -use function unserialize; +use function igbinary_serialize; +use function igbinary_unserialize; class GeneratorRegisterTask extends AsyncTask{ @@ -48,7 +48,7 @@ class GeneratorRegisterTask extends AsyncTask{ */ public function __construct(World $world, string $generatorClass, array $generatorSettings = []){ $this->generatorClass = $generatorClass; - $this->settings = serialize($generatorSettings); + $this->settings = igbinary_serialize($generatorSettings); $this->seed = $world->getSeed(); $this->worldId = $world->getId(); $this->worldHeight = $world->getWorldHeight(); @@ -63,7 +63,7 @@ class GeneratorRegisterTask extends AsyncTask{ * @var Generator $generator * @see Generator::__construct() */ - $generator = new $this->generatorClass($manager, $this->seed, unserialize($this->settings)); + $generator = new $this->generatorClass($manager, $this->seed, igbinary_unserialize($this->settings)); $this->worker->saveToThreadStore("generation.world{$this->worldId}.generator", $generator); } } From edc3156bea77c188e352f29e2c85853a8884df1c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Jun 2020 11:37:53 +0100 Subject: [PATCH 1652/3224] Rename NetworkCipher -> EncryptionContext --- src/Server.php | 4 ++-- src/network/mcpe/NetworkSession.php | 8 ++++---- .../{NetworkCipher.php => EncryptionContext.php} | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) rename src/network/mcpe/encryption/{NetworkCipher.php => EncryptionContext.php} (99%) diff --git a/src/Server.php b/src/Server.php index 8bc2da6745..33197af82d 100644 --- a/src/Server.php +++ b/src/Server.php @@ -51,7 +51,7 @@ use pocketmine\network\mcpe\compression\CompressBatchPromise; use pocketmine\network\mcpe\compression\CompressBatchTask; use pocketmine\network\mcpe\compression\Compressor; use pocketmine\network\mcpe\compression\ZlibCompressor; -use pocketmine\network\mcpe\encryption\NetworkCipher; +use pocketmine\network\mcpe\encryption\EncryptionContext; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\ProtocolInfo; @@ -880,7 +880,7 @@ class Server{ $this->networkCompressionAsync = (bool) $this->configGroup->getProperty("network.async-compression", true); - NetworkCipher::$ENABLED = (bool) $this->configGroup->getProperty("network.enable-encryption", true); + EncryptionContext::$ENABLED = (bool) $this->configGroup->getProperty("network.enable-encryption", true); $this->doTitleTick = ((bool) $this->configGroup->getProperty("console.title-tick", true)) && Terminal::hasFormattingCodes(); diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index c5c249c94f..43f555bda8 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -42,7 +42,7 @@ use pocketmine\network\mcpe\compression\DecompressionException; use pocketmine\network\mcpe\convert\SkinAdapterSingleton; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\encryption\DecryptionException; -use pocketmine\network\mcpe\encryption\NetworkCipher; +use pocketmine\network\mcpe\encryption\EncryptionContext; use pocketmine\network\mcpe\encryption\PrepareEncryptionTask; use pocketmine\network\mcpe\handler\DeathPacketHandler; use pocketmine\network\mcpe\handler\HandshakePacketHandler; @@ -148,7 +148,7 @@ class NetworkSession{ /** @var int */ private $connectTime; - /** @var NetworkCipher */ + /** @var EncryptionContext */ private $cipher; /** @var PacketBatch|null */ @@ -588,14 +588,14 @@ class NetworkSession{ $this->logger->debug("Xbox Live authenticated: " . ($this->authenticated ? "YES" : "NO")); if($this->manager->kickDuplicates($this)){ - if(NetworkCipher::$ENABLED){ + if(EncryptionContext::$ENABLED){ $this->server->getAsyncPool()->submitTask(new PrepareEncryptionTask($clientPubKey, function(string $encryptionKey, string $handshakeJwt) : void{ if(!$this->connected){ return; } $this->sendDataPacket(ServerToClientHandshakePacket::create($handshakeJwt), true); //make sure this gets sent before encryption is enabled - $this->cipher = new NetworkCipher($encryptionKey); + $this->cipher = new EncryptionContext($encryptionKey); $this->setHandler(new HandshakePacketHandler(function() : void{ $this->onLoginSuccess(); diff --git a/src/network/mcpe/encryption/NetworkCipher.php b/src/network/mcpe/encryption/EncryptionContext.php similarity index 99% rename from src/network/mcpe/encryption/NetworkCipher.php rename to src/network/mcpe/encryption/EncryptionContext.php index 8a71b7647a..b6cd471074 100644 --- a/src/network/mcpe/encryption/NetworkCipher.php +++ b/src/network/mcpe/encryption/EncryptionContext.php @@ -30,7 +30,7 @@ use function openssl_digest; use function strlen; use function substr; -class NetworkCipher{ +class EncryptionContext{ private const ENCRYPTION_SCHEME = "AES-256-CFB8"; private const CHECKSUM_ALGO = "sha256"; From 95114dcc1e08b681efae260cb65652891b52c345 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Jun 2020 11:50:43 +0100 Subject: [PATCH 1653/3224] EncryptionContext: fixed a phpstan level 7 error (openssl_digest() might return false for god knows what reason) --- src/network/mcpe/encryption/EncryptionContext.php | 7 ++++++- tests/phpstan/configs/l7-baseline.neon | 5 ----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/network/mcpe/encryption/EncryptionContext.php b/src/network/mcpe/encryption/EncryptionContext.php index b6cd471074..8abae1919b 100644 --- a/src/network/mcpe/encryption/EncryptionContext.php +++ b/src/network/mcpe/encryption/EncryptionContext.php @@ -27,6 +27,7 @@ use Crypto\Cipher; use pocketmine\utils\Binary; use function bin2hex; use function openssl_digest; +use function openssl_error_string; use function strlen; use function substr; @@ -86,6 +87,10 @@ class EncryptionContext{ } private function calculateChecksum(int $counter, string $payload) : string{ - return substr(openssl_digest(Binary::writeLLong($counter) . $payload . $this->key, self::CHECKSUM_ALGO, true), 0, 8); + $hash = openssl_digest(Binary::writeLLong($counter) . $payload . $this->key, self::CHECKSUM_ALGO, true); + if($hash === false){ + throw new \RuntimeException("Encryption error: " . openssl_error_string()); + } + return substr($hash, 0, 8); } } diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index ec3ff969a8..e09daf79b9 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -645,11 +645,6 @@ parameters: count: 1 path: ../../../src/network/mcpe/encryption/EncryptionUtils.php - - - message: "#^Parameter \\#1 \\$str of function substr expects string, string\\|false given\\.$#" - count: 1 - path: ../../../src/network/mcpe/encryption/NetworkCipher.php - - message: "#^Parameter \\#1 \\$v of method pocketmine\\\\utils\\\\BinaryStream\\:\\:putBool\\(\\) expects bool, bool\\|float\\|int given\\.$#" count: 1 From d931a5bcc02cab53a0e19fb71618bdfae8c46d80 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Jun 2020 11:51:07 +0100 Subject: [PATCH 1654/3224] phpstan: drop an obsolete level 7 ignoreErrors pattern --- tests/phpstan/configs/l7-baseline.neon | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index e09daf79b9..da5dfc1504 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -60,11 +60,6 @@ parameters: count: 2 path: ../../../src/PocketMine.php - - - message: "#^Parameter \\#1 \\$buffer of method pocketmine\\\\nbt\\\\BaseNbtSerializer\\:\\:readCompressed\\(\\) expects string, string\\|false given\\.$#" - count: 1 - path: ../../../src/Server.php - - message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, string\\|false given\\.$#" count: 1 From 222399d178475298882afd20853c2581ab9da512 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Jun 2020 11:52:05 +0100 Subject: [PATCH 1655/3224] EncryptionContext: fix exception message --- src/network/mcpe/encryption/EncryptionContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/encryption/EncryptionContext.php b/src/network/mcpe/encryption/EncryptionContext.php index 8abae1919b..4c98f2b22f 100644 --- a/src/network/mcpe/encryption/EncryptionContext.php +++ b/src/network/mcpe/encryption/EncryptionContext.php @@ -89,7 +89,7 @@ class EncryptionContext{ private function calculateChecksum(int $counter, string $payload) : string{ $hash = openssl_digest(Binary::writeLLong($counter) . $payload . $this->key, self::CHECKSUM_ALGO, true); if($hash === false){ - throw new \RuntimeException("Encryption error: " . openssl_error_string()); + throw new \RuntimeException("openssl_digest() error: " . openssl_error_string()); } return substr($hash, 0, 8); } From 755e53cd71b54d30253df34643318a230b6cf01d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Jun 2020 12:05:54 +0100 Subject: [PATCH 1656/3224] JwtUtils: added a split() function to reduce code duplication --- src/network/mcpe/JwtUtils.php | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/network/mcpe/JwtUtils.php b/src/network/mcpe/JwtUtils.php index 4f127efc0f..1b11623621 100644 --- a/src/network/mcpe/JwtUtils.php +++ b/src/network/mcpe/JwtUtils.php @@ -58,6 +58,19 @@ use const STR_PAD_LEFT; final class JwtUtils{ + /** + * @return string[] + * @phpstan-return array{string, string, string} + * @throws JwtException + */ + public static function split(string $jwt) : array{ + $v = explode(".", $jwt); + if(count($v) !== 3){ + throw new JwtException("Expected exactly 3 JWT parts, got " . count($v)); + } + return [$v[0], $v[1], $v[2]]; //workaround phpstan bug + } + /** * TODO: replace this result with an object * @@ -67,10 +80,7 @@ final class JwtUtils{ * @throws JwtException */ public static function parse(string $token) : array{ - $v = explode(".", $token); - if(count($v) !== 3){ - throw new JwtException("Expected exactly 3 JWT parts, got " . count($v)); - } + $v = self::split($token); $header = json_decode(self::b64UrlDecode($v[0]), true); if(!is_array($header)){ throw new JwtException("Failed to decode JWT header JSON: " . json_last_error_msg()); @@ -87,11 +97,7 @@ final class JwtUtils{ * @throws JwtException */ public static function verify(string $jwt, PublicKeyInterface $signingKey) : bool{ - $parts = explode('.', $jwt); - if(count($parts) !== 3){ - throw new JwtException("Expected exactly 3 JWT parts, got " . count($parts)); - } - [$header, $body, $signature] = $parts; + [$header, $body, $signature] = self::split($jwt); $plainSignature = self::b64UrlDecode($signature); if(strlen($plainSignature) !== 96){ From 98f04479128d0766fe1efe8b9e991205ca2009be Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Jun 2020 19:03:11 +0100 Subject: [PATCH 1657/3224] AutoUpdater: use JsonMapper to handle API response information --- src/updater/AutoUpdater.php | 25 ++--- src/updater/UpdateCheckTask.php | 27 +++--- src/updater/UpdateInfo.php | 96 +++++++++++++++++++ .../check-explicit-mixed-baseline.neon | 25 ----- tests/phpstan/configs/l8-baseline.neon | 14 +-- 5 files changed, 128 insertions(+), 59 deletions(-) create mode 100644 src/updater/UpdateInfo.php diff --git a/src/updater/AutoUpdater.php b/src/updater/AutoUpdater.php index 5c987ad69b..1851b0edac 100644 --- a/src/updater/AutoUpdater.php +++ b/src/updater/AutoUpdater.php @@ -41,10 +41,7 @@ class AutoUpdater{ protected $server; /** @var string */ protected $endpoint; - /** - * @var mixed[]|null - * @phpstan-var array|null - */ + /** @var UpdateInfo|null */ protected $updateInfo = null; /** @var VersionString|null */ protected $newVersion; @@ -69,10 +66,9 @@ class AutoUpdater{ /** * Callback used at the end of the update checking task * - * @param mixed[] $updateInfo - * @phpstan-param array $updateInfo + * @param UpdateInfo $updateInfo */ - public function checkUpdateCallback(array $updateInfo) : void{ + public function checkUpdateCallback(UpdateInfo $updateInfo) : void{ $this->updateInfo = $updateInfo; $this->checkUpdate(); if($this->hasUpdate()){ @@ -101,12 +97,12 @@ class AutoUpdater{ */ public function showConsoleUpdate() : void{ $messages = [ - "Your version of " . $this->server->getName() . " is out of date. Version " . $this->newVersion->getFullVersion(true) . " was released on " . date("D M j h:i:s Y", $this->updateInfo["date"]) + "Your version of " . $this->server->getName() . " is out of date. Version " . $this->newVersion->getFullVersion(true) . " was released on " . date("D M j h:i:s Y", $this->updateInfo->date) ]; - if($this->updateInfo["details_url"] !== null){ - $messages[] = "Details: " . $this->updateInfo["details_url"]; + if($this->updateInfo->details_url !== null){ + $messages[] = "Details: " . $this->updateInfo->details_url; } - $messages[] = "Download: " . $this->updateInfo["download_url"]; + $messages[] = "Download: " . $this->updateInfo->download_url; $this->printConsoleMessage($messages, \LogLevel::WARNING); } @@ -148,10 +144,9 @@ class AutoUpdater{ /** * Returns the last retrieved update data. * - * @return mixed[]|null - * @phpstan-return array|null + * @return UpdateInfo|null */ - public function getUpdateInfo() : ?array{ + public function getUpdateInfo() : ?UpdateInfo{ return $this->updateInfo; } @@ -171,7 +166,7 @@ class AutoUpdater{ } $currentVersion = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER); try{ - $newVersion = new VersionString($this->updateInfo["base_version"], $this->updateInfo["is_dev"], $this->updateInfo["build"]); + $newVersion = new VersionString($this->updateInfo->base_version, $this->updateInfo->is_dev, $this->updateInfo->build); }catch(\InvalidArgumentException $e){ //Invalid version returned from API, assume there's no update $this->logger->debug("Assuming no update because \"" . $e->getMessage() . "\""); diff --git a/src/updater/UpdateCheckTask.php b/src/updater/UpdateCheckTask.php index 0129057859..22b1f5acba 100644 --- a/src/updater/UpdateCheckTask.php +++ b/src/updater/UpdateCheckTask.php @@ -26,6 +26,7 @@ namespace pocketmine\updater; use pocketmine\scheduler\AsyncTask; use pocketmine\utils\Internet; use function is_array; +use function is_string; use function json_decode; class UpdateCheckTask extends AsyncTask{ @@ -52,19 +53,19 @@ class UpdateCheckTask extends AsyncTask{ if($response !== false){ $response = json_decode($response, true); if(is_array($response)){ - if( - isset($response["base_version"]) and - isset($response["is_dev"]) and - isset($response["build"]) and - isset($response["date"]) and - isset($response["download_url"]) - ){ - $response["details_url"] = $response["details_url"] ?? null; - $this->setResult($response); - }elseif(isset($response["error"])){ + if(isset($response["error"]) and is_string($response["error"])){ $this->error = $response["error"]; }else{ - $this->error = "Invalid response data"; + $mapper = new \JsonMapper(); + $mapper->bExceptionOnMissingData = true; + $mapper->bEnforceMapType = false; + try{ + /** @var UpdateInfo $responseObj */ + $responseObj = $mapper->map($response, new UpdateInfo()); + $this->setResult($responseObj); + }catch(\JsonMapper_Exception $e){ + $this->error = "Invalid JSON response data: " . $e->getMessage(); + } } }else{ $this->error = "Invalid response data"; @@ -76,7 +77,9 @@ class UpdateCheckTask extends AsyncTask{ /** @var AutoUpdater $updater */ $updater = $this->fetchLocal(self::TLS_KEY_UPDATER); if($this->hasResult()){ - $updater->checkUpdateCallback($this->getResult()); + /** @var UpdateInfo $response */ + $response = $this->getResult(); + $updater->checkUpdateCallback($response); }else{ $updater->checkUpdateError($this->error); } diff --git a/src/updater/UpdateInfo.php b/src/updater/UpdateInfo.php new file mode 100644 index 0000000000..2b0d1eb4c9 --- /dev/null +++ b/src/updater/UpdateInfo.php @@ -0,0 +1,96 @@ +, mixed given\\.$#" - count: 1 - path: ../../../src/updater/UpdateCheckTask.php - - message: "#^Parameter \\#3 \\$length of function substr expects int, mixed given\\.$#" count: 1 diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 4b7cfbd5af..b8b48f9778 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -800,23 +800,23 @@ parameters: count: 1 path: ../../../src/thread/Worker.php + - + message: "#^Cannot access property \\$date on pocketmine\\\\updater\\\\UpdateInfo\\|null\\.$#" + count: 1 + path: ../../../src/updater/AutoUpdater.php + - message: "#^Cannot call method getFullVersion\\(\\) on pocketmine\\\\utils\\\\VersionString\\|null\\.$#" count: 1 path: ../../../src/updater/AutoUpdater.php - - message: "#^Offset 'date' does not exist on array\\\\|null\\.$#" - count: 1 - path: ../../../src/updater/AutoUpdater.php - - - - message: "#^Offset 'details_url' does not exist on array\\\\|null\\.$#" + message: "#^Cannot access property \\$details_url on pocketmine\\\\updater\\\\UpdateInfo\\|null\\.$#" count: 2 path: ../../../src/updater/AutoUpdater.php - - message: "#^Offset 'download_url' does not exist on array\\\\|null\\.$#" + message: "#^Cannot access property \\$download_url on pocketmine\\\\updater\\\\UpdateInfo\\|null\\.$#" count: 1 path: ../../../src/updater/AutoUpdater.php From 44814a8421ba270df0b06dce5052ba39b3e6f318 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Jun 2020 19:06:42 +0100 Subject: [PATCH 1658/3224] AutoUpdater: remove useless check (details_url is mandatory) --- src/updater/AutoUpdater.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/updater/AutoUpdater.php b/src/updater/AutoUpdater.php index 1851b0edac..d60b42c59e 100644 --- a/src/updater/AutoUpdater.php +++ b/src/updater/AutoUpdater.php @@ -99,9 +99,8 @@ class AutoUpdater{ $messages = [ "Your version of " . $this->server->getName() . " is out of date. Version " . $this->newVersion->getFullVersion(true) . " was released on " . date("D M j h:i:s Y", $this->updateInfo->date) ]; - if($this->updateInfo->details_url !== null){ - $messages[] = "Details: " . $this->updateInfo->details_url; - } + + $messages[] = "Details: " . $this->updateInfo->details_url; $messages[] = "Download: " . $this->updateInfo->download_url; $this->printConsoleMessage($messages, \LogLevel::WARNING); From 11eb1f1c5e379306833af8b7a7833363e0454c11 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Jun 2020 20:01:19 +0100 Subject: [PATCH 1659/3224] imports cleanup --- src/Server.php | 1 - src/network/mcpe/handler/LoginPacketHandler.php | 9 --------- .../mcpe/protocol/serializer/PacketSerializer.php | 2 +- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/Server.php b/src/Server.php index 33197af82d..02c3da5972 100644 --- a/src/Server.php +++ b/src/Server.php @@ -147,7 +147,6 @@ use const DIRECTORY_SEPARATOR; use const PHP_EOL; use const PHP_INT_MAX; use const PTHREADS_INHERIT_NONE; -use const ZLIB_ENCODING_DEFLATE; use const ZLIB_ENCODING_GZIP; /** diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index 870bbc4d8e..b9b072fa74 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -37,21 +37,12 @@ use pocketmine\network\mcpe\protocol\PlayStatusPacket; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\types\login\AuthenticationData; use pocketmine\network\mcpe\protocol\types\login\ClientData; -use pocketmine\network\mcpe\protocol\types\login\ClientDataPersonaPieceTintColor; -use pocketmine\network\mcpe\protocol\types\login\ClientDataPersonaSkinPiece; use pocketmine\network\mcpe\protocol\types\login\ClientDataToSkinDataHelper; use pocketmine\network\mcpe\protocol\types\login\JwtChain; -use pocketmine\network\mcpe\protocol\types\PersonaPieceTintColor; -use pocketmine\network\mcpe\protocol\types\PersonaSkinPiece; -use pocketmine\network\mcpe\protocol\types\SkinAnimation; -use pocketmine\network\mcpe\protocol\types\SkinData; -use pocketmine\network\mcpe\protocol\types\SkinImage; use pocketmine\player\Player; use pocketmine\player\PlayerInfo; use pocketmine\Server; use pocketmine\uuid\UUID; -use function array_map; -use function base64_decode; use function is_array; /** diff --git a/src/network/mcpe/protocol/serializer/PacketSerializer.php b/src/network/mcpe/protocol/serializer/PacketSerializer.php index c6f0c3bce6..5c40a49041 100644 --- a/src/network/mcpe/protocol/serializer/PacketSerializer.php +++ b/src/network/mcpe/protocol/serializer/PacketSerializer.php @@ -43,9 +43,9 @@ use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\ShortMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\StringMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\Vec3MetadataProperty; +use pocketmine\network\mcpe\protocol\types\FixedItemIds; use pocketmine\network\mcpe\protocol\types\GameRuleType; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\network\mcpe\protocol\types\FixedItemIds; use pocketmine\network\mcpe\protocol\types\PersonaPieceTintColor; use pocketmine\network\mcpe\protocol\types\PersonaSkinPiece; use pocketmine\network\mcpe\protocol\types\recipe\RecipeIngredient; From b3df5f4e95c220258bd4e1916528be03ed5945e7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Jun 2020 20:01:49 +0100 Subject: [PATCH 1660/3224] CS: strip unneeded phpdoc --- src/entity/EntityFactory.php | 1 - src/event/HandlerListManager.php | 1 - src/network/mcpe/protocol/Packet.php | 2 -- src/network/mcpe/raklib/RakLibServer.php | 4 ---- src/updater/AutoUpdater.php | 4 ---- 5 files changed, 12 deletions(-) diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index 0f4a83a8d0..be1085e50a 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -111,7 +111,6 @@ final class EntityFactory{ * * @param string $className Class that extends Entity * @param string[] $saveNames An array of save names which this entity might be saved under. Defaults to the short name of the class itself if empty. - * @param int|null $legacyMcpeSaveId * @phpstan-param class-string $className * * NOTE: The first save name in the $saveNames array will be used when saving the entity to disk. The reflection diff --git a/src/event/HandlerListManager.php b/src/event/HandlerListManager.php index 0f7867d2f5..4bd61f8023 100644 --- a/src/event/HandlerListManager.php +++ b/src/event/HandlerListManager.php @@ -57,7 +57,6 @@ class HandlerListManager{ } /** - * @param \ReflectionClass $class * @phpstan-param \ReflectionClass $class */ private static function isValidClass(\ReflectionClass $class) : bool{ diff --git a/src/network/mcpe/protocol/Packet.php b/src/network/mcpe/protocol/Packet.php index 6ea81b4f75..6c84cd97f2 100644 --- a/src/network/mcpe/protocol/Packet.php +++ b/src/network/mcpe/protocol/Packet.php @@ -54,8 +54,6 @@ interface Packet{ * Typically this method returns the return value of the handler in the supplied PacketHandler. See other packets * for examples how to implement this. * - * @param PacketHandlerInterface $handler - * * @return bool true if the packet was handled successfully, false if not. * @throws PacketDecodeException if broken data was found in the packet */ diff --git a/src/network/mcpe/raklib/RakLibServer.php b/src/network/mcpe/raklib/RakLibServer.php index 7543b66fcd..ec335cf3cc 100644 --- a/src/network/mcpe/raklib/RakLibServer.php +++ b/src/network/mcpe/raklib/RakLibServer.php @@ -73,11 +73,7 @@ class RakLibServer extends Thread{ public $crashInfo = null; /** - * @param \ThreadedLogger $logger - * @param InternetAddress $address - * @param int $maxMtuSize * @param int|null $overrideProtocolVersion Optional custom protocol version to use, defaults to current RakLib's protocol - * @param SleeperNotifier|null $sleeper */ public function __construct( \ThreadedLogger $logger, diff --git a/src/updater/AutoUpdater.php b/src/updater/AutoUpdater.php index d60b42c59e..662dc3d778 100644 --- a/src/updater/AutoUpdater.php +++ b/src/updater/AutoUpdater.php @@ -65,8 +65,6 @@ class AutoUpdater{ /** * Callback used at the end of the update checking task - * - * @param UpdateInfo $updateInfo */ public function checkUpdateCallback(UpdateInfo $updateInfo) : void{ $this->updateInfo = $updateInfo; @@ -142,8 +140,6 @@ class AutoUpdater{ /** * Returns the last retrieved update data. - * - * @return UpdateInfo|null */ public function getUpdateInfo() : ?UpdateInfo{ return $this->updateInfo; From 0ae357cf8f028ceff2419770f31cedc30d73bc6d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Jun 2020 20:25:19 +0100 Subject: [PATCH 1661/3224] ProjectileItem: get NBT as far away as possible --- src/item/Egg.php | 16 ++++++++++++++-- src/item/EnderPearl.php | 16 ++++++++++++++-- src/item/ExperienceBottle.php | 16 ++++++++++++++-- src/item/ProjectileItem.php | 26 +++----------------------- src/item/Snowball.php | 16 ++++++++++++++-- src/item/SplashPotion.php | 23 ++++++++++++++++------- 6 files changed, 75 insertions(+), 38 deletions(-) diff --git a/src/item/Egg.php b/src/item/Egg.php index 7d3bece760..2d9391ce29 100644 --- a/src/item/Egg.php +++ b/src/item/Egg.php @@ -23,7 +23,12 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\entity\EntityFactory; +use pocketmine\entity\Location; use pocketmine\entity\projectile\Egg as EggEntity; +use pocketmine\entity\projectile\Throwable; +use pocketmine\math\Vector3; +use pocketmine\player\Player; class Egg extends ProjectileItem{ @@ -31,8 +36,15 @@ class Egg extends ProjectileItem{ return 16; } - public function getProjectileEntityClass() : string{ - return EggEntity::class; + protected function createEntity(EntityFactory $factory, Location $location, Vector3 $velocity, Player $thrower) : Throwable{ + /** @var EggEntity $projectile */ + $projectile = $factory->create( + EggEntity::class, + $location->getWorldNonNull(), + EntityFactory::createBaseNBT($location, $velocity, $location->yaw, $location->pitch), + $thrower + ); + return $projectile; } public function getThrowForce() : float{ diff --git a/src/item/EnderPearl.php b/src/item/EnderPearl.php index 337b30a7f9..a61055cc59 100644 --- a/src/item/EnderPearl.php +++ b/src/item/EnderPearl.php @@ -23,7 +23,12 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\entity\EntityFactory; +use pocketmine\entity\Location; use pocketmine\entity\projectile\EnderPearl as EnderPearlEntity; +use pocketmine\entity\projectile\Throwable; +use pocketmine\math\Vector3; +use pocketmine\player\Player; class EnderPearl extends ProjectileItem{ @@ -31,8 +36,15 @@ class EnderPearl extends ProjectileItem{ return 16; } - public function getProjectileEntityClass() : string{ - return EnderPearlEntity::class; + protected function createEntity(EntityFactory $factory, Location $location, Vector3 $velocity, Player $thrower) : Throwable{ + /** @var EnderPearlEntity $projectile */ + $projectile = $factory->create( + EnderPearlEntity::class, + $location->getWorldNonNull(), + EntityFactory::createBaseNBT($location, $velocity, $location->yaw, $location->pitch), + $thrower + ); + return $projectile; } public function getThrowForce() : float{ diff --git a/src/item/ExperienceBottle.php b/src/item/ExperienceBottle.php index 191d932b87..2482e0b0d2 100644 --- a/src/item/ExperienceBottle.php +++ b/src/item/ExperienceBottle.php @@ -23,12 +23,24 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\entity\EntityFactory; +use pocketmine\entity\Location; use pocketmine\entity\projectile\ExperienceBottle as ExperienceBottleEntity; +use pocketmine\entity\projectile\Throwable; +use pocketmine\math\Vector3; +use pocketmine\player\Player; class ExperienceBottle extends ProjectileItem{ - public function getProjectileEntityClass() : string{ - return ExperienceBottleEntity::class; + protected function createEntity(EntityFactory $factory, Location $location, Vector3 $velocity, Player $thrower) : Throwable{ + /** @var ExperienceBottleEntity $projectile */ + $projectile = $factory->create( + ExperienceBottleEntity::class, + $location->getWorldNonNull(), + EntityFactory::createBaseNBT($location, $velocity, $location->yaw, $location->pitch), + $thrower + ); + return $projectile; } public function getThrowForce() : float{ diff --git a/src/item/ProjectileItem.php b/src/item/ProjectileItem.php index a881e07ac5..305430c5b0 100644 --- a/src/item/ProjectileItem.php +++ b/src/item/ProjectileItem.php @@ -24,43 +24,23 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\entity\EntityFactory; +use pocketmine\entity\Location; use pocketmine\entity\projectile\Throwable; use pocketmine\event\entity\ProjectileLaunchEvent; use pocketmine\math\Vector3; -use pocketmine\nbt\tag\CompoundTag; use pocketmine\player\Player; -use pocketmine\utils\Utils; use pocketmine\world\sound\ThrowSound; abstract class ProjectileItem extends Item{ - /** - * Returns the entity type that this projectile creates. This should return a ::class extending Throwable. - * - * @return string class extends Throwable - * @phpstan-return class-string - */ - abstract public function getProjectileEntityClass() : string; - abstract public function getThrowForce() : float; - /** - * Helper function to apply extra NBT tags to pass to the created projectile. - */ - protected function addExtraTags(CompoundTag $tag) : void{ - - } + abstract protected function createEntity(EntityFactory $factory, Location $location, Vector3 $velocity, Player $thrower) : Throwable; public function onClickAir(Player $player, Vector3 $directionVector) : ItemUseResult{ $location = $player->getLocation(); - $nbt = EntityFactory::createBaseNBT($player->getEyePos(), $directionVector, $location->yaw, $location->pitch); - $this->addExtraTags($nbt); - $class = $this->getProjectileEntityClass(); - Utils::testValidInstance($class, Throwable::class); - - /** @var Throwable $projectile */ - $projectile = EntityFactory::getInstance()->create($class, $location->getWorldNonNull(), $nbt, $player); + $projectile = $this->createEntity(EntityFactory::getInstance(), Location::fromObject($player->getEyePos(), $player->getWorld(), $location->yaw, $location->pitch), $directionVector, $player); $projectile->setMotion($projectile->getMotion()->multiply($this->getThrowForce())); $projectileEv = new ProjectileLaunchEvent($projectile); diff --git a/src/item/Snowball.php b/src/item/Snowball.php index 8da341c06e..da959980ad 100644 --- a/src/item/Snowball.php +++ b/src/item/Snowball.php @@ -23,7 +23,12 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\entity\EntityFactory; +use pocketmine\entity\Location; use pocketmine\entity\projectile\Snowball as SnowballEntity; +use pocketmine\entity\projectile\Throwable; +use pocketmine\math\Vector3; +use pocketmine\player\Player; class Snowball extends ProjectileItem{ @@ -31,8 +36,15 @@ class Snowball extends ProjectileItem{ return 16; } - public function getProjectileEntityClass() : string{ - return SnowballEntity::class; + protected function createEntity(EntityFactory $factory, Location $location, Vector3 $velocity, Player $thrower) : Throwable{ + /** @var SnowballEntity $projectile */ + $projectile = $factory->create( + SnowballEntity::class, + $location->getWorldNonNull(), + EntityFactory::createBaseNBT($location, $velocity, $location->yaw, $location->pitch), + $thrower + ); + return $projectile; } public function getThrowForce() : float{ diff --git a/src/item/SplashPotion.php b/src/item/SplashPotion.php index d29f5839b7..83748dd74d 100644 --- a/src/item/SplashPotion.php +++ b/src/item/SplashPotion.php @@ -23,8 +23,12 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\entity\EntityFactory; +use pocketmine\entity\Location; use pocketmine\entity\projectile\SplashPotion as SplashPotionEntity; -use pocketmine\nbt\tag\CompoundTag; +use pocketmine\entity\projectile\Throwable; +use pocketmine\math\Vector3; +use pocketmine\player\Player; class SplashPotion extends ProjectileItem{ @@ -32,15 +36,20 @@ class SplashPotion extends ProjectileItem{ return 1; } - public function getProjectileEntityClass() : string{ - return SplashPotionEntity::class; + protected function createEntity(EntityFactory $factory, Location $location, Vector3 $velocity, Player $thrower) : Throwable{ + /** @var SplashPotionEntity $projectile */ + $projectile = $factory->create( + SplashPotionEntity::class, + $location->getWorldNonNull(), + EntityFactory::createBaseNBT($location, $velocity, $location->yaw, $location->pitch), + $thrower + ); + + $projectile->setPotionId($this->meta); + return $projectile; } public function getThrowForce() : float{ return 0.5; } - - protected function addExtraTags(CompoundTag $tag) : void{ - $tag->setShort("PotionId", $this->meta); - } } From cf85857660eb9ad086ad20e68c0a8f5ebe6c4f55 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jun 2020 01:07:18 +0100 Subject: [PATCH 1662/3224] Entity: remove duplicated code from saveNBT() --- src/entity/Entity.php | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 6c5aceee16..883081bcef 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -41,8 +41,6 @@ use pocketmine\math\Facing; use pocketmine\math\Vector2; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\DoubleTag; -use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\protocol\AddActorPacket; @@ -460,7 +458,8 @@ abstract class Entity{ } public function saveNBT() : CompoundTag{ - $nbt = new CompoundTag(); + $nbt = EntityFactory::createBaseNBT($this->location, $this->motion, $this->location->yaw, $this->location->pitch); + if(!($this instanceof Player)){ $nbt->setString("id", EntityFactory::getInstance()->getSaveId(get_class($this))); @@ -470,23 +469,6 @@ abstract class Entity{ } } - $nbt->setTag("Pos", new ListTag([ - new DoubleTag($this->location->x), - new DoubleTag($this->location->y), - new DoubleTag($this->location->z) - ])); - - $nbt->setTag("Motion", new ListTag([ - new DoubleTag($this->motion->x), - new DoubleTag($this->motion->y), - new DoubleTag($this->motion->z) - ])); - - $nbt->setTag("Rotation", new ListTag([ - new FloatTag($this->location->yaw), - new FloatTag($this->location->pitch) - ])); - $nbt->setFloat("FallDistance", $this->fallDistance); $nbt->setShort("Fire", $this->fireTicks); $nbt->setByte("OnGround", $this->onGround ? 1 : 0); From ced89add3cd8740ba4f84a3b4407cd5f6216448f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jun 2020 01:13:00 +0100 Subject: [PATCH 1663/3224] Human: remove dead function --- src/entity/Human.php | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/entity/Human.php b/src/entity/Human.php index 36762dcdf0..2e5e7756ed 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -59,10 +59,8 @@ use pocketmine\world\World; use function array_filter; use function array_merge; use function array_values; -use function in_array; use function min; use function random_int; -use function strlen; class Human extends Living implements ProjectileSource, InventoryHolder{ @@ -114,15 +112,6 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ parent::__construct($world, $nbt); } - /** - * @deprecated - * - * Checks the length of a supplied skin bitmap and returns whether the length is valid. - */ - public static function isValidSkin(string $skin) : bool{ - return in_array(strlen($skin), Skin::ACCEPTED_SKIN_SIZES, true); - } - public function getUniqueId() : UUID{ return $this->uuid; } From 3bdd9ee8608980efa3c135d5992630816cbc363f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jun 2020 10:49:21 +0100 Subject: [PATCH 1664/3224] phpstan: drop a bunch of error patterns that don't appear on 0.12.29+ --- tests/phpstan/configs/phpstan-bugs.neon | 30 ------------------------- 1 file changed, 30 deletions(-) diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index e6712299b5..a445332417 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -5,11 +5,6 @@ parameters: count: 1 path: ../../../src/Server.php - - - message: "#^Instanceof between pocketmine\\\\block\\\\tile\\\\Tile and class\\-string\\ will always evaluate to true\\.$#" - count: 1 - path: ../../../src/block/Block.php - - message: "#^Comparison operation \"\\>\\=\" between 0 and 2 is always false\\.$#" count: 1 @@ -30,31 +25,6 @@ parameters: count: 1 path: ../../../src/entity/projectile/Projectile.php - - - message: "#^If condition is always false\\.$#" - count: 1 - path: ../../../src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php - - - - message: "#^Instanceof between pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\entity\\\\MetadataProperty and pocketmine\\\\network\\\\mcpe\\\\protocol\\\\types\\\\entity\\\\MetadataProperty will always evaluate to true\\.$#" - count: 1 - path: ../../../src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php - - - - message: "#^Class pocketmine\\\\item\\\\LegacyStringToItemParser constructor invoked with 0 parameters, 1 required\\.$#" - count: 1 - path: ../../../src/item/LegacyStringToItemParser.php - - - - message: "#^Class pocketmine\\\\network\\\\mcpe\\\\StaticPacketCache constructor invoked with 0 parameters, 2 required\\.$#" - count: 1 - path: ../../../src/network/mcpe/StaticPacketCache.php - - - - message: "#^Class pocketmine\\\\network\\\\mcpe\\\\compression\\\\ZlibCompressor constructor invoked with 0 parameters, 3 required\\.$#" - count: 1 - path: ../../../src/network/mcpe/compression/ZlibCompressor.php - - message: "#^Strict comparison using \\=\\=\\= between string and false will always evaluate to false\\.$#" count: 1 From 72a7fc68c1adf5dc97ff85a6ccdab6cb76aedfc4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 May 2020 21:38:45 +0100 Subject: [PATCH 1665/3224] First look at making entity creation closure-driven this allows doing stuff like injecting plugin references to entity constructors for now. I want to make this more flexible still, but I've done about as much as I feel like doing today and don't want this disappearing into a stash to never be seen again. --- src/entity/EntityFactory.php | 143 ++++++++++++++++-------- tests/phpstan/configs/phpstan-bugs.neon | 10 ++ 2 files changed, 109 insertions(+), 44 deletions(-) diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index be1085e50a..c992d5513f 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -23,6 +23,9 @@ declare(strict_types=1); namespace pocketmine\entity; +use DaveRandom\CallbackValidator\CallbackType; +use DaveRandom\CallbackValidator\ParameterType; +use DaveRandom\CallbackValidator\ReturnType; use pocketmine\entity\object\ExperienceOrb; use pocketmine\entity\object\FallingBlock; use pocketmine\entity\object\ItemEntity; @@ -47,9 +50,7 @@ use pocketmine\utils\SingletonTrait; use pocketmine\utils\Utils; use pocketmine\world\World; use function array_keys; -use function assert; use function in_array; -use function is_a; use function reset; /** @@ -67,10 +68,10 @@ final class EntityFactory{ private static $entityCount = 1; /** - * @var string[] base class => currently used class for construction - * @phpstan-var array, class-string> + * @var \Closure[] base class => creator function + * @phpstan-var array, \Closure(World, CompoundTag, mixed...) : Entity> */ - private $classMapping = []; + private $creationFuncs = []; /** * @var string[] * @phpstan-var array> @@ -86,42 +87,104 @@ final class EntityFactory{ //define legacy save IDs first - use them for saving for maximum compatibility with Minecraft PC //TODO: index them by version to allow proper multi-save compatibility - $this->register(Arrow::class, ['Arrow', 'minecraft:arrow'], EntityLegacyIds::ARROW); - $this->register(Egg::class, ['Egg', 'minecraft:egg'], EntityLegacyIds::EGG); - $this->register(EnderPearl::class, ['ThrownEnderpearl', 'minecraft:ender_pearl'], EntityLegacyIds::ENDER_PEARL); - $this->register(ExperienceBottle::class, ['ThrownExpBottle', 'minecraft:xp_bottle'], EntityLegacyIds::XP_BOTTLE); - $this->register(ExperienceOrb::class, ['XPOrb', 'minecraft:xp_orb'], EntityLegacyIds::XP_ORB); - $this->register(FallingBlock::class, ['FallingSand', 'minecraft:falling_block'], EntityLegacyIds::FALLING_BLOCK); - $this->register(ItemEntity::class, ['Item', 'minecraft:item'], EntityLegacyIds::ITEM); - $this->register(Painting::class, ['Painting', 'minecraft:painting'], EntityLegacyIds::PAINTING); - $this->register(PrimedTNT::class, ['PrimedTnt', 'PrimedTNT', 'minecraft:tnt'], EntityLegacyIds::TNT); - $this->register(Snowball::class, ['Snowball', 'minecraft:snowball'], EntityLegacyIds::SNOWBALL); - $this->register(SplashPotion::class, ['ThrownPotion', 'minecraft:potion', 'thrownpotion'], EntityLegacyIds::SPLASH_POTION); - $this->register(Squid::class, ['Squid', 'minecraft:squid'], EntityLegacyIds::SQUID); - $this->register(Villager::class, ['Villager', 'minecraft:villager'], EntityLegacyIds::VILLAGER); - $this->register(Zombie::class, ['Zombie', 'minecraft:zombie'], EntityLegacyIds::ZOMBIE); + $this->register(Arrow::class, function(World $world, CompoundTag $nbt, ...$extraArgs) : Arrow{ + return new Arrow($world, $nbt, ...$extraArgs); + }, ['Arrow', 'minecraft:arrow'], EntityLegacyIds::ARROW); - $this->register(Human::class, ['Human']); + $this->register(Egg::class, function(World $world, CompoundTag $nbt, ...$extraArgs) : Egg{ + return new Egg($world, $nbt, ...$extraArgs); + }, ['Egg', 'minecraft:egg'], EntityLegacyIds::EGG); + + $this->register(EnderPearl::class, function(World $world, CompoundTag $nbt, ...$extraArgs) : EnderPearl{ + return new EnderPearl($world, $nbt, ...$extraArgs); + }, ['ThrownEnderpearl', 'minecraft:ender_pearl'], EntityLegacyIds::ENDER_PEARL); + + $this->register(ExperienceBottle::class, function(World $world, CompoundTag $nbt, ...$extraArgs) : ExperienceBottle{ + return new ExperienceBottle($world, $nbt, ...$extraArgs); + }, ['ThrownExpBottle', 'minecraft:xp_bottle'], EntityLegacyIds::XP_BOTTLE); + + $this->register(ExperienceOrb::class, function(World $world, CompoundTag $nbt) : ExperienceOrb{ + return new ExperienceOrb($world, $nbt); + }, ['XPOrb', 'minecraft:xp_orb'], EntityLegacyIds::XP_ORB); + + $this->register(FallingBlock::class, function(World $world, CompoundTag $nbt) : FallingBlock{ + return new FallingBlock($world, $nbt); + }, ['FallingSand', 'minecraft:falling_block'], EntityLegacyIds::FALLING_BLOCK); + + $this->register(ItemEntity::class, function(World $world, CompoundTag $nbt) : ItemEntity{ + return new ItemEntity($world, $nbt); + }, ['Item', 'minecraft:item'], EntityLegacyIds::ITEM); + + $this->register(Painting::class, function(World $world, CompoundTag $nbt) : Painting{ + return new Painting($world, $nbt); + }, ['Painting', 'minecraft:painting'], EntityLegacyIds::PAINTING); + + $this->register(PrimedTNT::class, function(World $world, CompoundTag $nbt) : PrimedTNT{ + return new PrimedTNT($world, $nbt); + }, ['PrimedTnt', 'PrimedTNT', 'minecraft:tnt'], EntityLegacyIds::TNT); + + $this->register(Snowball::class, function(World $world, CompoundTag $nbt, ...$extraArgs) : Snowball{ + return new Snowball($world, $nbt, ...$extraArgs); + }, ['Snowball', 'minecraft:snowball'], EntityLegacyIds::SNOWBALL); + + $this->register(SplashPotion::class, function(World $world, CompoundTag $nbt, ...$extraArgs) : SplashPotion{ + return new SplashPotion($world, $nbt, ...$extraArgs); + }, ['ThrownPotion', 'minecraft:potion', 'thrownpotion'], EntityLegacyIds::SPLASH_POTION); + + $this->register(Squid::class, function(World $world, CompoundTag $nbt) : Squid{ + return new Squid($world, $nbt); + }, ['Squid', 'minecraft:squid'], EntityLegacyIds::SQUID); + + $this->register(Villager::class, function(World $world, CompoundTag $nbt) : Villager{ + return new Villager($world, $nbt); + }, ['Villager', 'minecraft:villager'], EntityLegacyIds::VILLAGER); + + $this->register(Zombie::class, function(World $world, CompoundTag $nbt) : Zombie{ + return new Zombie($world, $nbt); + }, ['Zombie', 'minecraft:zombie'], EntityLegacyIds::ZOMBIE); + + $this->register(Human::class, function(World $world, CompoundTag $nbt) : Human{ + return new Human($world, $nbt); + }, ['Human']); PaintingMotive::init(); } + /** + * @phpstan-param class-string $baseClass + * @phpstan-param \Closure(World, CompoundTag, mixed...) : Entity $creationFunc + */ + private static function validateCreationFunc(string $baseClass, \Closure $creationFunc) : void{ + $sig = new CallbackType( + new ReturnType($baseClass), + new ParameterType("world", World::class), + new ParameterType("nbt", CompoundTag::class), + new ParameterType("extraArgs", null, ParameterType::VARIADIC | ParameterType::CONTRAVARIANT | ParameterType::OPTIONAL) + ); + if(!$sig->isSatisfiedBy($creationFunc)){ + throw new \TypeError("Declaration of callable `" . CallbackType::createFromCallable($creationFunc) . "` must be compatible with `" . $sig . "`"); + } + } + /** * Registers an entity type into the index. * * @param string $className Class that extends Entity + * @param \Closure $creationFunc * @param string[] $saveNames An array of save names which this entity might be saved under. Defaults to the short name of the class itself if empty. * @phpstan-param class-string $className + * @phpstan-param \Closure(World $world, CompoundTag $nbt, mixed ...$args) : Entity $creationFunc * * NOTE: The first save name in the $saveNames array will be used when saving the entity to disk. The reflection * name of the class will be appended to the end and only used if no other save names are specified. * * @throws \InvalidArgumentException */ - public function register(string $className, array $saveNames, ?int $legacyMcpeSaveId = null) : void{ + public function register(string $className, \Closure $creationFunc, array $saveNames, ?int $legacyMcpeSaveId = null) : void{ Utils::testValidInstance($className, Entity::class); - $this->classMapping[$className] = $className; + self::validateCreationFunc($className, $creationFunc); + $this->creationFuncs[$className] = $creationFunc; $shortName = (new \ReflectionClass($className))->getShortName(); if(!in_array($shortName, $saveNames, true)){ @@ -142,22 +205,21 @@ final class EntityFactory{ * Registers a class override for the given class. When a new entity is constructed using the factory, the new class * will be used instead of the base class. * - * @param string $baseClass Already-registered entity class to override - * @param string $newClass Class which extends the base class + * @param string $baseClass Already-registered entity class to override + * @param \Closure $newCreationFunc * - * TODO: use an explicit template for param1 * @phpstan-param class-string $baseClass - * @phpstan-param class-string $newClass + * @phpstan-param \Closure(World, CompoundTag, mixed...) : Entity $newCreationFunc * * @throws \InvalidArgumentException */ - public function override(string $baseClass, string $newClass) : void{ - if(!isset($this->classMapping[$baseClass])){ + public function override(string $baseClass, \Closure $newCreationFunc) : void{ + if(!isset($this->creationFuncs[$baseClass])){ throw new \InvalidArgumentException("Class $baseClass is not a registered entity"); } - Utils::testValidInstance($newClass, $baseClass); - $this->classMapping[$baseClass] = $newClass; + self::validateCreationFunc($baseClass, $newCreationFunc); + $this->creationFuncs[$baseClass] = $newCreationFunc; } /** @@ -167,7 +229,7 @@ final class EntityFactory{ * @return class-string[] */ public function getKnownTypes() : array{ - return array_keys($this->classMapping); + return array_keys($this->creationFuncs); } /** @@ -194,16 +256,13 @@ final class EntityFactory{ * @throws \InvalidArgumentException if the class doesn't exist or is not registered */ public function create(string $baseClass, World $world, CompoundTag $nbt, ...$args) : Entity{ - if(isset($this->classMapping[$baseClass])){ - $class = $this->classMapping[$baseClass]; - assert(is_a($class, $baseClass, true)); + if(isset($this->creationFuncs[$baseClass])){ + $func = $this->creationFuncs[$baseClass]; /** * @var Entity $entity * @phpstan-var TEntity $entity - * @see Entity::__construct() */ - $entity = new $class($world, $nbt, ...$args); - + $entity = $func($world, $nbt, ...$args); return $entity; } @@ -227,13 +286,9 @@ final class EntityFactory{ if($baseClass === null){ return null; } - $class = $this->classMapping[$baseClass]; - assert(is_a($class, $baseClass, true)); - /** - * @var Entity $entity - * @see Entity::__construct() - */ - $entity = new $class($world, $nbt); + $func = $this->creationFuncs[$baseClass]; + /** @var Entity $entity */ + $entity = $func($world, $nbt); return $entity; } diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index a445332417..8268d7e95b 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -20,6 +20,16 @@ parameters: count: 3 path: ../../../src/command/CommandReader.php + - + message: "#^Closure invoked with 2 parameters, at least 3 required\\.$#" + count: 1 + path: ../../../src/entity/EntityFactory.php + + - + message: "#^Only iterables can be unpacked, mixed given in argument \\#3\\.$#" + count: 6 + path: ../../../src/entity/EntityFactory.php + - message: "#^Call to function assert\\(\\) with false and 'unknown hit type' will always evaluate to false\\.$#" count: 1 From 6a26c0bebfda21af469b8a13319d1f9c83f37ab3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jun 2020 00:40:44 +0100 Subject: [PATCH 1666/3224] EntityFactory now exclusively handles loading data from disk this commit removes the ability to replace centrally registered entity classes in favour of using constructors directly. In future commits I may introduce a dedicated factory interface which allows an _actual_ factory pattern (e.g. factory->createArrow(world, pos, shooter, isCritical) with proper static analysability) but for now it's peripheral to my intended objective. The purpose of this change is to facilitate untangling of NBT from entity constructors so that they can be properly created without using NBT at all, and instead use nice APIs. Spawn eggs now support arbitrary entity creation functions like EntityFactory does, allowing much more flexibility in what can be passed to an entity's constructor (e.g. a Plugin reference can be injected by use()ing it in a closure or via traditional DI. --- src/block/TNT.php | 3 +- src/block/utils/FallableTrait.php | 3 +- src/entity/EntityFactory.php | 92 +++++-------------------- src/item/Bow.php | 3 +- src/item/Egg.php | 7 +- src/item/EnderPearl.php | 7 +- src/item/ExperienceBottle.php | 7 +- src/item/ItemFactory.php | 36 +++++++--- src/item/PaintingItem.php | 3 +- src/item/ProjectileItem.php | 5 +- src/item/Snowball.php | 7 +- src/item/SpawnEgg.php | 27 ++------ src/item/SplashPotion.php | 6 +- src/world/World.php | 6 +- tests/phpstan/configs/phpstan-bugs.neon | 10 --- 15 files changed, 68 insertions(+), 154 deletions(-) diff --git a/src/block/TNT.php b/src/block/TNT.php index b20b090167..19a6b466ef 100644 --- a/src/block/TNT.php +++ b/src/block/TNT.php @@ -96,8 +96,7 @@ class TNT extends Opaque{ $nbt = EntityFactory::createBaseNBT($this->pos->add(0.5, 0, 0.5), new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02)); $nbt->setShort("Fuse", $fuse); - /** @var PrimedTNT $tnt */ - $tnt = EntityFactory::getInstance()->create(PrimedTNT::class, $this->pos->getWorldNonNull(), $nbt); + $tnt = new PrimedTNT($this->pos->getWorldNonNull(), $nbt); $tnt->spawnToAll(); } diff --git a/src/block/utils/FallableTrait.php b/src/block/utils/FallableTrait.php index b398dabe74..f17fdcfab2 100644 --- a/src/block/utils/FallableTrait.php +++ b/src/block/utils/FallableTrait.php @@ -55,8 +55,7 @@ trait FallableTrait{ $nbt->setInt("TileID", $this->getId()); $nbt->setByte("Data", $this->getMeta()); - /** @var FallingBlock $fall */ - $fall = EntityFactory::getInstance()->create(FallingBlock::class, $pos->getWorldNonNull(), $nbt); + $fall = new FallingBlock($pos->getWorldNonNull(), $nbt); $fall->spawnToAll(); } } diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index c992d5513f..fc698b9f8b 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -54,12 +54,8 @@ use function in_array; use function reset; /** - * This class manages the creation of entities loaded from disk (and optionally entities created at runtime). - * - * You need to register your entity class into this factory if: - * a) you want to load/save your entity on disk (saving with chunks) - * b) you want to allow custom things to provide a custom class for your entity. Note that you must use - * create(MyEntity::class) instead of `new MyEntity()` if you want to allow this. + * This class manages the creation of entities loaded from disk. + * You need to register your entity into this factory if you want to load/save your entity on disk (saving with chunks). */ final class EntityFactory{ use SingletonTrait; @@ -69,7 +65,7 @@ final class EntityFactory{ /** * @var \Closure[] base class => creator function - * @phpstan-var array, \Closure(World, CompoundTag, mixed...) : Entity> + * @phpstan-var array, \Closure(World, CompoundTag) : Entity> */ private $creationFuncs = []; /** @@ -87,20 +83,20 @@ final class EntityFactory{ //define legacy save IDs first - use them for saving for maximum compatibility with Minecraft PC //TODO: index them by version to allow proper multi-save compatibility - $this->register(Arrow::class, function(World $world, CompoundTag $nbt, ...$extraArgs) : Arrow{ - return new Arrow($world, $nbt, ...$extraArgs); + $this->register(Arrow::class, function(World $world, CompoundTag $nbt) : Arrow{ + return new Arrow($world, $nbt); }, ['Arrow', 'minecraft:arrow'], EntityLegacyIds::ARROW); - $this->register(Egg::class, function(World $world, CompoundTag $nbt, ...$extraArgs) : Egg{ - return new Egg($world, $nbt, ...$extraArgs); + $this->register(Egg::class, function(World $world, CompoundTag $nbt) : Egg{ + return new Egg($world, $nbt); }, ['Egg', 'minecraft:egg'], EntityLegacyIds::EGG); - $this->register(EnderPearl::class, function(World $world, CompoundTag $nbt, ...$extraArgs) : EnderPearl{ - return new EnderPearl($world, $nbt, ...$extraArgs); + $this->register(EnderPearl::class, function(World $world, CompoundTag $nbt) : EnderPearl{ + return new EnderPearl($world, $nbt); }, ['ThrownEnderpearl', 'minecraft:ender_pearl'], EntityLegacyIds::ENDER_PEARL); - $this->register(ExperienceBottle::class, function(World $world, CompoundTag $nbt, ...$extraArgs) : ExperienceBottle{ - return new ExperienceBottle($world, $nbt, ...$extraArgs); + $this->register(ExperienceBottle::class, function(World $world, CompoundTag $nbt) : ExperienceBottle{ + return new ExperienceBottle($world, $nbt); }, ['ThrownExpBottle', 'minecraft:xp_bottle'], EntityLegacyIds::XP_BOTTLE); $this->register(ExperienceOrb::class, function(World $world, CompoundTag $nbt) : ExperienceOrb{ @@ -123,12 +119,12 @@ final class EntityFactory{ return new PrimedTNT($world, $nbt); }, ['PrimedTnt', 'PrimedTNT', 'minecraft:tnt'], EntityLegacyIds::TNT); - $this->register(Snowball::class, function(World $world, CompoundTag $nbt, ...$extraArgs) : Snowball{ - return new Snowball($world, $nbt, ...$extraArgs); + $this->register(Snowball::class, function(World $world, CompoundTag $nbt) : Snowball{ + return new Snowball($world, $nbt); }, ['Snowball', 'minecraft:snowball'], EntityLegacyIds::SNOWBALL); - $this->register(SplashPotion::class, function(World $world, CompoundTag $nbt, ...$extraArgs) : SplashPotion{ - return new SplashPotion($world, $nbt, ...$extraArgs); + $this->register(SplashPotion::class, function(World $world, CompoundTag $nbt) : SplashPotion{ + return new SplashPotion($world, $nbt); }, ['ThrownPotion', 'minecraft:potion', 'thrownpotion'], EntityLegacyIds::SPLASH_POTION); $this->register(Squid::class, function(World $world, CompoundTag $nbt) : Squid{ @@ -152,14 +148,13 @@ final class EntityFactory{ /** * @phpstan-param class-string $baseClass - * @phpstan-param \Closure(World, CompoundTag, mixed...) : Entity $creationFunc + * @phpstan-param \Closure(World, CompoundTag) : Entity $creationFunc */ private static function validateCreationFunc(string $baseClass, \Closure $creationFunc) : void{ $sig = new CallbackType( new ReturnType($baseClass), new ParameterType("world", World::class), - new ParameterType("nbt", CompoundTag::class), - new ParameterType("extraArgs", null, ParameterType::VARIADIC | ParameterType::CONTRAVARIANT | ParameterType::OPTIONAL) + new ParameterType("nbt", CompoundTag::class) ); if(!$sig->isSatisfiedBy($creationFunc)){ throw new \TypeError("Declaration of callable `" . CallbackType::createFromCallable($creationFunc) . "` must be compatible with `" . $sig . "`"); @@ -173,7 +168,7 @@ final class EntityFactory{ * @param \Closure $creationFunc * @param string[] $saveNames An array of save names which this entity might be saved under. Defaults to the short name of the class itself if empty. * @phpstan-param class-string $className - * @phpstan-param \Closure(World $world, CompoundTag $nbt, mixed ...$args) : Entity $creationFunc + * @phpstan-param \Closure(World $world, CompoundTag $nbt) : Entity $creationFunc * * NOTE: The first save name in the $saveNames array will be used when saving the entity to disk. The reflection * name of the class will be appended to the end and only used if no other save names are specified. @@ -201,27 +196,6 @@ final class EntityFactory{ $this->saveNames[$className] = $saveNames; } - /** - * Registers a class override for the given class. When a new entity is constructed using the factory, the new class - * will be used instead of the base class. - * - * @param string $baseClass Already-registered entity class to override - * @param \Closure $newCreationFunc - * - * @phpstan-param class-string $baseClass - * @phpstan-param \Closure(World, CompoundTag, mixed...) : Entity $newCreationFunc - * - * @throws \InvalidArgumentException - */ - public function override(string $baseClass, \Closure $newCreationFunc) : void{ - if(!isset($this->creationFuncs[$baseClass])){ - throw new \InvalidArgumentException("Class $baseClass is not a registered entity"); - } - - self::validateCreationFunc($baseClass, $newCreationFunc); - $this->creationFuncs[$baseClass] = $newCreationFunc; - } - /** * Returns an array of all registered entity classpaths. * @@ -239,36 +213,6 @@ final class EntityFactory{ return self::$entityCount++; } - /** - * Creates an entity with the specified type, world and NBT, with optional additional arguments to pass to the - * entity's constructor. - * - * TODO: make this NBT-independent - * - * @phpstan-template TEntity of Entity - * - * @param mixed ...$args - * @phpstan-param class-string $baseClass - * - * @return Entity instanceof $baseClass - * @phpstan-return TEntity - * - * @throws \InvalidArgumentException if the class doesn't exist or is not registered - */ - public function create(string $baseClass, World $world, CompoundTag $nbt, ...$args) : Entity{ - if(isset($this->creationFuncs[$baseClass])){ - $func = $this->creationFuncs[$baseClass]; - /** - * @var Entity $entity - * @phpstan-var TEntity $entity - */ - $entity = $func($world, $nbt, ...$args); - return $entity; - } - - throw new \InvalidArgumentException("Class $baseClass is not a registered entity"); - } - /** * Creates an entity from data stored on a chunk. * diff --git a/src/item/Bow.php b/src/item/Bow.php index 04b15a6cad..f5fe19e47a 100644 --- a/src/item/Bow.php +++ b/src/item/Bow.php @@ -62,8 +62,7 @@ class Bow extends Tool{ $p = $diff / 20; $baseForce = min((($p ** 2) + $p * 2) / 3, 1); - /** @var ArrowEntity $entity */ - $entity = EntityFactory::getInstance()->create(ArrowEntity::class, $location->getWorldNonNull(), $nbt, $player, $baseForce >= 1); + $entity = new ArrowEntity($location->getWorldNonNull(), $nbt, $player, $baseForce >= 1); $infinity = $this->hasEnchantment(Enchantment::INFINITY()); if($infinity){ diff --git a/src/item/Egg.php b/src/item/Egg.php index 2d9391ce29..f9657ee95a 100644 --- a/src/item/Egg.php +++ b/src/item/Egg.php @@ -36,15 +36,12 @@ class Egg extends ProjectileItem{ return 16; } - protected function createEntity(EntityFactory $factory, Location $location, Vector3 $velocity, Player $thrower) : Throwable{ - /** @var EggEntity $projectile */ - $projectile = $factory->create( - EggEntity::class, + protected function createEntity(Location $location, Vector3 $velocity, Player $thrower) : Throwable{ + return new EggEntity( $location->getWorldNonNull(), EntityFactory::createBaseNBT($location, $velocity, $location->yaw, $location->pitch), $thrower ); - return $projectile; } public function getThrowForce() : float{ diff --git a/src/item/EnderPearl.php b/src/item/EnderPearl.php index a61055cc59..19d62da581 100644 --- a/src/item/EnderPearl.php +++ b/src/item/EnderPearl.php @@ -36,15 +36,12 @@ class EnderPearl extends ProjectileItem{ return 16; } - protected function createEntity(EntityFactory $factory, Location $location, Vector3 $velocity, Player $thrower) : Throwable{ - /** @var EnderPearlEntity $projectile */ - $projectile = $factory->create( - EnderPearlEntity::class, + protected function createEntity(Location $location, Vector3 $velocity, Player $thrower) : Throwable{ + return new EnderPearlEntity( $location->getWorldNonNull(), EntityFactory::createBaseNBT($location, $velocity, $location->yaw, $location->pitch), $thrower ); - return $projectile; } public function getThrowForce() : float{ diff --git a/src/item/ExperienceBottle.php b/src/item/ExperienceBottle.php index 2482e0b0d2..8d1225bb5f 100644 --- a/src/item/ExperienceBottle.php +++ b/src/item/ExperienceBottle.php @@ -32,15 +32,12 @@ use pocketmine\player\Player; class ExperienceBottle extends ProjectileItem{ - protected function createEntity(EntityFactory $factory, Location $location, Vector3 $velocity, Player $thrower) : Throwable{ - /** @var ExperienceBottleEntity $projectile */ - $projectile = $factory->create( - ExperienceBottleEntity::class, + protected function createEntity(Location $location, Vector3 $velocity, Player $thrower) : Throwable{ + return new ExperienceBottleEntity( $location->getWorldNonNull(), EntityFactory::createBaseNBT($location, $velocity, $location->yaw, $location->pitch), $thrower ); - return $projectile; } public function getThrowForce() : float{ diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index c42b825a81..2c286bc57e 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -29,12 +29,17 @@ use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\SkullType; use pocketmine\block\utils\TreeType; use pocketmine\block\VanillaBlocks; +use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; -use pocketmine\entity\Living; +use pocketmine\entity\Squid; +use pocketmine\entity\Villager; +use pocketmine\entity\Zombie; use pocketmine\inventory\ArmorInventory; +use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\utils\SingletonTrait; -use function is_a; +use pocketmine\world\World; /** * Manages Item instance creation and registration @@ -50,6 +55,7 @@ class ItemFactory{ public function __construct(){ $this->registerArmorItems(); + $this->registerSpawnEggs(); $this->registerTierToolItems(); $this->register(new Apple(ItemIds::APPLE, 0, "Apple")); @@ -250,13 +256,6 @@ class ItemFactory{ $this->register(new SplashPotion(ItemIds::SPLASH_POTION, $type, "Splash Potion")); } - foreach(EntityFactory::getInstance()->getKnownTypes() as $className){ - /** @var Living|string $className */ - if(is_a($className, Living::class, true) and $className::getNetworkTypeId() !== -1){ - $this->register(new SpawnEgg(ItemIds::SPAWN_EGG, $className::getNetworkTypeId(), "Spawn Egg", $className)); - } - } - foreach(TreeType::getAll() as $type){ $this->register(new Boat(ItemIds::BOAT, $type->getMagicNumber(), $type->getDisplayName() . " Boat", $type)); } @@ -316,6 +315,25 @@ class ItemFactory{ //endregion } + private function registerSpawnEggs() : void{ + //TODO: the meta values should probably be hardcoded; they won't change, but the EntityLegacyIds might + $this->register(new class(ItemIds::SPAWN_EGG, EntityLegacyIds::ZOMBIE, "Zombie Spawn Egg") extends SpawnEgg{ + protected function createEntity(World $world, Vector3 $pos, float $yaw, float $pitch) : Entity{ + return new Zombie($world, EntityFactory::createBaseNBT($pos, null, $yaw, $pitch)); + } + }); + $this->register(new class(ItemIds::SPAWN_EGG, EntityLegacyIds::SQUID, "Squid Spawn Egg") extends SpawnEgg{ + public function createEntity(World $world, Vector3 $pos, float $yaw, float $pitch) : Entity{ + return new Squid($world, EntityFactory::createBaseNBT($pos, null, $yaw, $pitch)); + } + }); + $this->register(new class(ItemIds::SPAWN_EGG, EntityLegacyIds::VILLAGER, "Villager Spawn Egg") extends SpawnEgg{ + public function createEntity(World $world, Vector3 $pos, float $yaw, float $pitch) : Entity{ + return new Villager($world, EntityFactory::createBaseNBT($pos, null, $yaw, $pitch)); + } + }); + } + private function registerTierToolItems() : void{ $this->register(new Axe(ItemIds::DIAMOND_AXE, "Diamond Axe", ToolTier::DIAMOND())); $this->register(new Axe(ItemIds::GOLDEN_AXE, "Golden Axe", ToolTier::GOLD())); diff --git a/src/item/PaintingItem.php b/src/item/PaintingItem.php index 1bd726510a..16de653354 100644 --- a/src/item/PaintingItem.php +++ b/src/item/PaintingItem.php @@ -93,8 +93,7 @@ class PaintingItem extends Item{ $nbt->setInt("TileY", $clickedPos->getFloorY()); $nbt->setInt("TileZ", $clickedPos->getFloorZ()); - /** @var Painting $entity */ - $entity = EntityFactory::getInstance()->create(Painting::class, $replacePos->getWorldNonNull(), $nbt); + $entity = new Painting($replacePos->getWorldNonNull(), $nbt); $this->pop(); $entity->spawnToAll(); diff --git a/src/item/ProjectileItem.php b/src/item/ProjectileItem.php index 305430c5b0..90ac91315d 100644 --- a/src/item/ProjectileItem.php +++ b/src/item/ProjectileItem.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\EntityFactory; use pocketmine\entity\Location; use pocketmine\entity\projectile\Throwable; use pocketmine\event\entity\ProjectileLaunchEvent; @@ -35,12 +34,12 @@ abstract class ProjectileItem extends Item{ abstract public function getThrowForce() : float; - abstract protected function createEntity(EntityFactory $factory, Location $location, Vector3 $velocity, Player $thrower) : Throwable; + abstract protected function createEntity(Location $location, Vector3 $velocity, Player $thrower) : Throwable; public function onClickAir(Player $player, Vector3 $directionVector) : ItemUseResult{ $location = $player->getLocation(); - $projectile = $this->createEntity(EntityFactory::getInstance(), Location::fromObject($player->getEyePos(), $player->getWorld(), $location->yaw, $location->pitch), $directionVector, $player); + $projectile = $this->createEntity(Location::fromObject($player->getEyePos(), $player->getWorld(), $location->yaw, $location->pitch), $directionVector, $player); $projectile->setMotion($projectile->getMotion()->multiply($this->getThrowForce())); $projectileEv = new ProjectileLaunchEvent($projectile); diff --git a/src/item/Snowball.php b/src/item/Snowball.php index da959980ad..c0f1b0f321 100644 --- a/src/item/Snowball.php +++ b/src/item/Snowball.php @@ -36,15 +36,12 @@ class Snowball extends ProjectileItem{ return 16; } - protected function createEntity(EntityFactory $factory, Location $location, Vector3 $velocity, Player $thrower) : Throwable{ - /** @var SnowballEntity $projectile */ - $projectile = $factory->create( - SnowballEntity::class, + protected function createEntity(Location $location, Vector3 $velocity, Player $thrower) : Throwable{ + return new SnowballEntity( $location->getWorldNonNull(), EntityFactory::createBaseNBT($location, $velocity, $location->yaw, $location->pitch), $thrower ); - return $projectile; } public function getThrowForce() : float{ diff --git a/src/item/SpawnEgg.php b/src/item/SpawnEgg.php index d743255269..330bd11286 100644 --- a/src/item/SpawnEgg.php +++ b/src/item/SpawnEgg.php @@ -29,36 +29,19 @@ use pocketmine\entity\EntityFactory; use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\utils\Utils; +use pocketmine\world\World; use function lcg_value; -class SpawnEgg extends Item{ +abstract class SpawnEgg extends Item{ - /** - * @var string - * @phpstan-var class-string - */ - private $entityClass; - - /** - * @param string $entityClass instanceof Entity - * @phpstan-param class-string $entityClass - * - * @throws \InvalidArgumentException - */ - public function __construct(int $id, int $variant, string $name, string $entityClass){ - parent::__construct($id, $variant, $name); - Utils::testValidInstance($entityClass, Entity::class); - $this->entityClass = $entityClass; - } + abstract protected function createEntity(World $world, Vector3 $pos, float $yaw, float $pitch) : Entity; public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ - $nbt = EntityFactory::createBaseNBT($blockReplace->getPos()->add(0.5, 0, 0.5), null, lcg_value() * 360, 0); + $entity = $this->createEntity($player->getWorld(), $blockReplace->getPos()->add(0.5, 0, 0.5), lcg_value() * 360, 0); if($this->hasCustomName()){ - $nbt->setString("CustomName", $this->getCustomName()); + $entity->setNameTag($this->getCustomName()); } - - $entity = EntityFactory::getInstance()->create($this->entityClass, $player->getWorld(), $nbt); $this->pop(); $entity->spawnToAll(); //TODO: what if the entity was marked for deletion? diff --git a/src/item/SplashPotion.php b/src/item/SplashPotion.php index 83748dd74d..8a658843c9 100644 --- a/src/item/SplashPotion.php +++ b/src/item/SplashPotion.php @@ -36,10 +36,8 @@ class SplashPotion extends ProjectileItem{ return 1; } - protected function createEntity(EntityFactory $factory, Location $location, Vector3 $velocity, Player $thrower) : Throwable{ - /** @var SplashPotionEntity $projectile */ - $projectile = $factory->create( - SplashPotionEntity::class, + protected function createEntity(Location $location, Vector3 $velocity, Player $thrower) : Throwable{ + $projectile = new SplashPotionEntity( $location->getWorldNonNull(), EntityFactory::createBaseNBT($location, $velocity, $location->yaw, $location->pitch), $thrower diff --git a/src/world/World.php b/src/world/World.php index 5400478366..d1a7b0c561 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1391,8 +1391,7 @@ class World implements ChunkManager{ $nbt->setShort("PickupDelay", $delay); $nbt->setTag("Item", $item->nbtSerialize()); - /** @var ItemEntity $itemEntity */ - $itemEntity = EntityFactory::getInstance()->create(ItemEntity::class, $this, $nbt); + $itemEntity = new ItemEntity($this, $nbt); $itemEntity->spawnToAll(); return $itemEntity; @@ -1416,8 +1415,7 @@ class World implements ChunkManager{ ); $nbt->setShort(ExperienceOrb::TAG_VALUE_PC, $split); - /** @var ExperienceOrb $orb */ - $orb = EntityFactory::getInstance()->create(ExperienceOrb::class, $this, $nbt); + $orb = new ExperienceOrb($this, $nbt); $orb->spawnToAll(); $orbs[] = $orb; } diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 8268d7e95b..a445332417 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -20,16 +20,6 @@ parameters: count: 3 path: ../../../src/command/CommandReader.php - - - message: "#^Closure invoked with 2 parameters, at least 3 required\\.$#" - count: 1 - path: ../../../src/entity/EntityFactory.php - - - - message: "#^Only iterables can be unpacked, mixed given in argument \\#3\\.$#" - count: 6 - path: ../../../src/entity/EntityFactory.php - - message: "#^Call to function assert\\(\\) with false and 'unknown hit type' will always evaluate to false\\.$#" count: 1 From 3f135da7040844e65433fa203eb9176a602e195a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jun 2020 02:38:01 +0100 Subject: [PATCH 1667/3224] Simplify motion handling in ProjectileItem --- src/item/Egg.php | 5 ++--- src/item/EnderPearl.php | 5 ++--- src/item/ExperienceBottle.php | 5 ++--- src/item/ProjectileItem.php | 6 +++--- src/item/Snowball.php | 5 ++--- src/item/SplashPotion.php | 5 ++--- 6 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/item/Egg.php b/src/item/Egg.php index f9657ee95a..6ad22172eb 100644 --- a/src/item/Egg.php +++ b/src/item/Egg.php @@ -27,7 +27,6 @@ use pocketmine\entity\EntityFactory; use pocketmine\entity\Location; use pocketmine\entity\projectile\Egg as EggEntity; use pocketmine\entity\projectile\Throwable; -use pocketmine\math\Vector3; use pocketmine\player\Player; class Egg extends ProjectileItem{ @@ -36,10 +35,10 @@ class Egg extends ProjectileItem{ return 16; } - protected function createEntity(Location $location, Vector3 $velocity, Player $thrower) : Throwable{ + protected function createEntity(Location $location, Player $thrower) : Throwable{ return new EggEntity( $location->getWorldNonNull(), - EntityFactory::createBaseNBT($location, $velocity, $location->yaw, $location->pitch), + EntityFactory::createBaseNBT($location, null, $location->yaw, $location->pitch), $thrower ); } diff --git a/src/item/EnderPearl.php b/src/item/EnderPearl.php index 19d62da581..4c865cbdca 100644 --- a/src/item/EnderPearl.php +++ b/src/item/EnderPearl.php @@ -27,7 +27,6 @@ use pocketmine\entity\EntityFactory; use pocketmine\entity\Location; use pocketmine\entity\projectile\EnderPearl as EnderPearlEntity; use pocketmine\entity\projectile\Throwable; -use pocketmine\math\Vector3; use pocketmine\player\Player; class EnderPearl extends ProjectileItem{ @@ -36,10 +35,10 @@ class EnderPearl extends ProjectileItem{ return 16; } - protected function createEntity(Location $location, Vector3 $velocity, Player $thrower) : Throwable{ + protected function createEntity(Location $location, Player $thrower) : Throwable{ return new EnderPearlEntity( $location->getWorldNonNull(), - EntityFactory::createBaseNBT($location, $velocity, $location->yaw, $location->pitch), + EntityFactory::createBaseNBT($location, null, $location->yaw, $location->pitch), $thrower ); } diff --git a/src/item/ExperienceBottle.php b/src/item/ExperienceBottle.php index 8d1225bb5f..20af8b56a8 100644 --- a/src/item/ExperienceBottle.php +++ b/src/item/ExperienceBottle.php @@ -27,15 +27,14 @@ use pocketmine\entity\EntityFactory; use pocketmine\entity\Location; use pocketmine\entity\projectile\ExperienceBottle as ExperienceBottleEntity; use pocketmine\entity\projectile\Throwable; -use pocketmine\math\Vector3; use pocketmine\player\Player; class ExperienceBottle extends ProjectileItem{ - protected function createEntity(Location $location, Vector3 $velocity, Player $thrower) : Throwable{ + protected function createEntity(Location $location, Player $thrower) : Throwable{ return new ExperienceBottleEntity( $location->getWorldNonNull(), - EntityFactory::createBaseNBT($location, $velocity, $location->yaw, $location->pitch), + EntityFactory::createBaseNBT($location, null, $location->yaw, $location->pitch), $thrower ); } diff --git a/src/item/ProjectileItem.php b/src/item/ProjectileItem.php index 90ac91315d..8ac5fedc1c 100644 --- a/src/item/ProjectileItem.php +++ b/src/item/ProjectileItem.php @@ -34,13 +34,13 @@ abstract class ProjectileItem extends Item{ abstract public function getThrowForce() : float; - abstract protected function createEntity(Location $location, Vector3 $velocity, Player $thrower) : Throwable; + abstract protected function createEntity(Location $location, Player $thrower) : Throwable; public function onClickAir(Player $player, Vector3 $directionVector) : ItemUseResult{ $location = $player->getLocation(); - $projectile = $this->createEntity(Location::fromObject($player->getEyePos(), $player->getWorld(), $location->yaw, $location->pitch), $directionVector, $player); - $projectile->setMotion($projectile->getMotion()->multiply($this->getThrowForce())); + $projectile = $this->createEntity(Location::fromObject($player->getEyePos(), $player->getWorld(), $location->yaw, $location->pitch), $player); + $projectile->setMotion($directionVector->multiply($this->getThrowForce())); $projectileEv = new ProjectileLaunchEvent($projectile); $projectileEv->call(); diff --git a/src/item/Snowball.php b/src/item/Snowball.php index c0f1b0f321..5dd6856a2b 100644 --- a/src/item/Snowball.php +++ b/src/item/Snowball.php @@ -27,7 +27,6 @@ use pocketmine\entity\EntityFactory; use pocketmine\entity\Location; use pocketmine\entity\projectile\Snowball as SnowballEntity; use pocketmine\entity\projectile\Throwable; -use pocketmine\math\Vector3; use pocketmine\player\Player; class Snowball extends ProjectileItem{ @@ -36,10 +35,10 @@ class Snowball extends ProjectileItem{ return 16; } - protected function createEntity(Location $location, Vector3 $velocity, Player $thrower) : Throwable{ + protected function createEntity(Location $location, Player $thrower) : Throwable{ return new SnowballEntity( $location->getWorldNonNull(), - EntityFactory::createBaseNBT($location, $velocity, $location->yaw, $location->pitch), + EntityFactory::createBaseNBT($location, null, $location->yaw, $location->pitch), $thrower ); } diff --git a/src/item/SplashPotion.php b/src/item/SplashPotion.php index 8a658843c9..9ad5106bc2 100644 --- a/src/item/SplashPotion.php +++ b/src/item/SplashPotion.php @@ -27,7 +27,6 @@ use pocketmine\entity\EntityFactory; use pocketmine\entity\Location; use pocketmine\entity\projectile\SplashPotion as SplashPotionEntity; use pocketmine\entity\projectile\Throwable; -use pocketmine\math\Vector3; use pocketmine\player\Player; class SplashPotion extends ProjectileItem{ @@ -36,10 +35,10 @@ class SplashPotion extends ProjectileItem{ return 1; } - protected function createEntity(Location $location, Vector3 $velocity, Player $thrower) : Throwable{ + protected function createEntity(Location $location, Player $thrower) : Throwable{ $projectile = new SplashPotionEntity( $location->getWorldNonNull(), - EntityFactory::createBaseNBT($location, $velocity, $location->yaw, $location->pitch), + EntityFactory::createBaseNBT($location, null, $location->yaw, $location->pitch), $thrower ); From 1205432c3437454c076bbfc269d5bdef243d7a97 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jun 2020 02:49:24 +0100 Subject: [PATCH 1668/3224] Extract mandatory parameters into constructor parameters the goal is obviously to ditch NBT entirely here, but there's more work to be done before that becomes possible. --- src/block/TNT.php | 10 ++-- src/block/utils/FallableTrait.php | 12 ++-- src/entity/Entity.php | 11 +--- src/entity/EntityFactory.php | 89 +++++++++++++++++++++++----- src/entity/Human.php | 36 ++++++----- src/entity/object/FallingBlock.php | 13 ++-- src/entity/object/ItemEntity.php | 20 +++---- src/entity/object/Painting.php | 18 +++--- src/entity/object/PrimedTNT.php | 11 ++++ src/entity/projectile/Arrow.php | 6 +- src/entity/projectile/Projectile.php | 6 +- src/item/Bow.php | 17 +++--- src/item/Egg.php | 8 +-- src/item/EnderPearl.php | 8 +-- src/item/ExperienceBottle.php | 8 +-- src/item/ItemFactory.php | 8 +-- src/item/PaintingItem.php | 23 +------ src/item/Snowball.php | 8 +-- src/item/SpawnEgg.php | 2 - src/item/SplashPotion.php | 9 +-- src/player/Player.php | 23 ++----- src/world/World.php | 26 ++++---- 22 files changed, 192 insertions(+), 180 deletions(-) diff --git a/src/block/TNT.php b/src/block/TNT.php index 19a6b466ef..da57818a84 100644 --- a/src/block/TNT.php +++ b/src/block/TNT.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\entity\Entity; -use pocketmine\entity\EntityFactory; +use pocketmine\entity\Location; use pocketmine\entity\object\PrimedTNT; use pocketmine\entity\projectile\Arrow; use pocketmine\item\Durable; @@ -32,6 +32,7 @@ use pocketmine\item\enchantment\Enchantment; use pocketmine\item\FlintSteel; use pocketmine\item\Item; use pocketmine\math\Vector3; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\player\Player; use pocketmine\utils\Random; use function cos; @@ -93,10 +94,11 @@ class TNT extends Opaque{ $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::AIR()); $mot = (new Random())->nextSignedFloat() * M_PI * 2; - $nbt = EntityFactory::createBaseNBT($this->pos->add(0.5, 0, 0.5), new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02)); - $nbt->setShort("Fuse", $fuse); - $tnt = new PrimedTNT($this->pos->getWorldNonNull(), $nbt); + $tnt = new PrimedTNT(Location::fromObject($this->pos->add(0.5, 0, 0.5), $this->pos->getWorldNonNull()), new CompoundTag()); + $tnt->setFuse($fuse); + $tnt->setMotion(new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02)); + $tnt->spawnToAll(); } diff --git a/src/block/utils/FallableTrait.php b/src/block/utils/FallableTrait.php index f17fdcfab2..fe88647672 100644 --- a/src/block/utils/FallableTrait.php +++ b/src/block/utils/FallableTrait.php @@ -23,13 +23,16 @@ declare(strict_types=1); namespace pocketmine\block\utils; +use pocketmine\block\Block; use pocketmine\block\BlockLegacyIds; use pocketmine\block\Fire; use pocketmine\block\Liquid; use pocketmine\block\VanillaBlocks; -use pocketmine\entity\EntityFactory; +use pocketmine\entity\Location; use pocketmine\entity\object\FallingBlock; use pocketmine\math\Facing; +use pocketmine\nbt\tag\CompoundTag; +use pocketmine\utils\AssumptionFailedError; use pocketmine\world\Position; /** @@ -51,11 +54,10 @@ trait FallableTrait{ if($down->getId() === BlockLegacyIds::AIR or $down instanceof Liquid or $down instanceof Fire){ $pos->getWorldNonNull()->setBlock($pos, VanillaBlocks::AIR()); - $nbt = EntityFactory::createBaseNBT($pos->add(0.5, 0, 0.5)); - $nbt->setInt("TileID", $this->getId()); - $nbt->setByte("Data", $this->getMeta()); + $block = $this; + if(!($block instanceof Block)) throw new AssumptionFailedError(__TRAIT__ . " should only be used by Blocks"); - $fall = new FallingBlock($pos->getWorldNonNull(), $nbt); + $fall = new FallingBlock(Location::fromObject($pos->add(0.5, 0, 0.5), $pos->getWorldNonNull()), $block, new CompoundTag()); $fall->spawnToAll(); } } diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 883081bcef..b40977450c 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -213,7 +213,7 @@ abstract class Entity{ /** @var int|null */ protected $targetId = null; - public function __construct(World $world, CompoundTag $nbt){ + public function __construct(Location $location, CompoundTag $nbt){ $this->timings = Timings::getEntityTimings($this); $this->temporalVector = new Vector3(); @@ -223,14 +223,9 @@ abstract class Entity{ } $this->id = EntityFactory::nextRuntimeId(); - $this->server = $world->getServer(); + $this->server = $location->getWorldNonNull()->getServer(); - /** @var float[] $pos */ - $pos = $nbt->getListTag("Pos")->getAllValues(); - /** @var float[] $rotation */ - $rotation = $nbt->getListTag("Rotation")->getAllValues(); - - $this->location = new Location($pos[0], $pos[1], $pos[2], $rotation[0], $rotation[1], $world); + $this->location = $location->asLocation(); assert( !is_nan($this->location->x) and !is_infinite($this->location->x) and !is_nan($this->location->y) and !is_infinite($this->location->y) and diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index fc698b9f8b..d74b206acd 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -26,6 +26,7 @@ namespace pocketmine\entity; use DaveRandom\CallbackValidator\CallbackType; use DaveRandom\CallbackValidator\ParameterType; use DaveRandom\CallbackValidator\ReturnType; +use pocketmine\block\BlockFactory; use pocketmine\entity\object\ExperienceOrb; use pocketmine\entity\object\FallingBlock; use pocketmine\entity\object\ItemEntity; @@ -38,7 +39,11 @@ use pocketmine\entity\projectile\EnderPearl; use pocketmine\entity\projectile\ExperienceBottle; use pocketmine\entity\projectile\Snowball; use pocketmine\entity\projectile\SplashPotion; +use pocketmine\item\Item; +use pocketmine\math\Facing; use pocketmine\math\Vector3; +use pocketmine\nbt\NBT; +use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\FloatTag; @@ -50,6 +55,7 @@ use pocketmine\utils\SingletonTrait; use pocketmine\utils\Utils; use pocketmine\world\World; use function array_keys; +use function count; use function in_array; use function reset; @@ -84,63 +90,85 @@ final class EntityFactory{ //TODO: index them by version to allow proper multi-save compatibility $this->register(Arrow::class, function(World $world, CompoundTag $nbt) : Arrow{ - return new Arrow($world, $nbt); + return new Arrow(self::parseLocation($nbt, $world), null, false, $nbt); //TODO: missing critical flag }, ['Arrow', 'minecraft:arrow'], EntityLegacyIds::ARROW); $this->register(Egg::class, function(World $world, CompoundTag $nbt) : Egg{ - return new Egg($world, $nbt); + return new Egg(self::parseLocation($nbt, $world), null, $nbt); }, ['Egg', 'minecraft:egg'], EntityLegacyIds::EGG); $this->register(EnderPearl::class, function(World $world, CompoundTag $nbt) : EnderPearl{ - return new EnderPearl($world, $nbt); + return new EnderPearl(self::parseLocation($nbt, $world), null, $nbt); }, ['ThrownEnderpearl', 'minecraft:ender_pearl'], EntityLegacyIds::ENDER_PEARL); $this->register(ExperienceBottle::class, function(World $world, CompoundTag $nbt) : ExperienceBottle{ - return new ExperienceBottle($world, $nbt); + return new ExperienceBottle(self::parseLocation($nbt, $world), null, $nbt); }, ['ThrownExpBottle', 'minecraft:xp_bottle'], EntityLegacyIds::XP_BOTTLE); $this->register(ExperienceOrb::class, function(World $world, CompoundTag $nbt) : ExperienceOrb{ - return new ExperienceOrb($world, $nbt); + return new ExperienceOrb(self::parseLocation($nbt, $world), $nbt); }, ['XPOrb', 'minecraft:xp_orb'], EntityLegacyIds::XP_ORB); $this->register(FallingBlock::class, function(World $world, CompoundTag $nbt) : FallingBlock{ - return new FallingBlock($world, $nbt); + return new FallingBlock(self::parseLocation($nbt, $world), FallingBlock::parseBlockNBT(BlockFactory::getInstance(), $nbt), $nbt); }, ['FallingSand', 'minecraft:falling_block'], EntityLegacyIds::FALLING_BLOCK); $this->register(ItemEntity::class, function(World $world, CompoundTag $nbt) : ItemEntity{ - return new ItemEntity($world, $nbt); + $itemTag = $nbt->getCompoundTag("Item"); + if($itemTag === null){ + throw new \UnexpectedValueException("Expected \"Item\" NBT tag not found"); + } + + $item = Item::nbtDeserialize($itemTag); + if($item->isNull()){ + throw new \UnexpectedValueException("Item is invalid"); + } + return new ItemEntity(self::parseLocation($nbt, $world), $item, $nbt); }, ['Item', 'minecraft:item'], EntityLegacyIds::ITEM); $this->register(Painting::class, function(World $world, CompoundTag $nbt) : Painting{ - return new Painting($world, $nbt); + $motive = PaintingMotive::getMotiveByName($nbt->getString("Motive")); + if($motive === null){ + throw new \UnexpectedValueException("Unknown painting motive"); + } + $blockIn = new Vector3($nbt->getInt("TileX"), $nbt->getInt("TileY"), $nbt->getInt("TileZ")); + if($nbt->hasTag("Direction", ByteTag::class)){ + $facing = Painting::DATA_TO_FACING[$nbt->getByte("Direction")] ?? Facing::NORTH; + }elseif($nbt->hasTag("Facing", ByteTag::class)){ + $facing = Painting::DATA_TO_FACING[$nbt->getByte("Facing")] ?? Facing::NORTH; + }else{ + throw new \UnexpectedValueException("Missing facing info"); + } + + return new Painting(self::parseLocation($nbt, $world), $blockIn, $facing, $motive, $nbt); }, ['Painting', 'minecraft:painting'], EntityLegacyIds::PAINTING); $this->register(PrimedTNT::class, function(World $world, CompoundTag $nbt) : PrimedTNT{ - return new PrimedTNT($world, $nbt); + return new PrimedTNT(self::parseLocation($nbt, $world), $nbt); }, ['PrimedTnt', 'PrimedTNT', 'minecraft:tnt'], EntityLegacyIds::TNT); $this->register(Snowball::class, function(World $world, CompoundTag $nbt) : Snowball{ - return new Snowball($world, $nbt); + return new Snowball(self::parseLocation($nbt, $world), null, $nbt); }, ['Snowball', 'minecraft:snowball'], EntityLegacyIds::SNOWBALL); $this->register(SplashPotion::class, function(World $world, CompoundTag $nbt) : SplashPotion{ - return new SplashPotion($world, $nbt); + return new SplashPotion(self::parseLocation($nbt, $world), null, $nbt); }, ['ThrownPotion', 'minecraft:potion', 'thrownpotion'], EntityLegacyIds::SPLASH_POTION); $this->register(Squid::class, function(World $world, CompoundTag $nbt) : Squid{ - return new Squid($world, $nbt); + return new Squid(self::parseLocation($nbt, $world), $nbt); }, ['Squid', 'minecraft:squid'], EntityLegacyIds::SQUID); $this->register(Villager::class, function(World $world, CompoundTag $nbt) : Villager{ - return new Villager($world, $nbt); + return new Villager(self::parseLocation($nbt, $world), $nbt); }, ['Villager', 'minecraft:villager'], EntityLegacyIds::VILLAGER); $this->register(Zombie::class, function(World $world, CompoundTag $nbt) : Zombie{ - return new Zombie($world, $nbt); + return new Zombie(self::parseLocation($nbt, $world), $nbt); }, ['Zombie', 'minecraft:zombie'], EntityLegacyIds::ZOMBIE); $this->register(Human::class, function(World $world, CompoundTag $nbt) : Human{ - return new Human($world, $nbt); + return new Human(self::parseLocation($nbt, $world), Human::parseSkinNBT($nbt), $nbt); }, ['Human']); PaintingMotive::init(); @@ -247,6 +275,37 @@ final class EntityFactory{ throw new \InvalidArgumentException("Entity $class is not registered"); } + public static function parseLocation(CompoundTag $nbt, World $world) : Location{ + $pos = self::parseVec3($nbt, "Pos", false); + + $yawPitch = $nbt->getTag("Rotation"); + if(!($yawPitch instanceof ListTag) or $yawPitch->getTagType() !== NBT::TAG_Float){ + throw new \UnexpectedValueException("'Rotation' should be a List"); + } + $values = $yawPitch->getValue(); + if(count($values) !== 2){ + throw new \UnexpectedValueException("Expected exactly 2 entries for 'Rotation'"); + } + + return Location::fromObject($pos, $world, $values[0]->getValue(), $values[1]->getValue()); + } + + private static function parseVec3(CompoundTag $nbt, string $tagName, bool $optional) : Vector3{ + $pos = $nbt->getTag($tagName); + if($pos === null and $optional){ + return new Vector3(0, 0, 0); + } + if(!($pos instanceof ListTag) or $pos->getTagType() !== NBT::TAG_Double){ + throw new \UnexpectedValueException("'$tagName' should be a List"); + } + /** @var DoubleTag[] $values */ + $values = $pos->getValue(); + if(count($values) !== 3){ + throw new \UnexpectedValueException("Expected exactly 3 entries in '$tagName' tag"); + } + return new Vector3($values[0]->getValue(), $values[1]->getValue(), $values[2]->getValue()); + } + /** * Helper function which creates minimal NBT needed to spawn an entity. */ diff --git a/src/entity/Human.php b/src/entity/Human.php index 2e5e7756ed..77b37d618f 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -55,7 +55,6 @@ use pocketmine\player\Player; use pocketmine\utils\Limits; use pocketmine\uuid\UUID; use pocketmine\world\sound\TotemUseSound; -use pocketmine\world\World; use function array_filter; use function array_merge; use function array_values; @@ -94,22 +93,27 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ protected $baseOffset = 1.62; - public function __construct(World $world, CompoundTag $nbt){ - if($this->skin === null){ - $skinTag = $nbt->getCompoundTag("Skin"); - if($skinTag === null){ - throw new \InvalidStateException((new \ReflectionClass($this))->getShortName() . " must have a valid skin set"); - } - $this->skin = new Skin( //this throws if the skin is invalid - $skinTag->getString("Name"), - $skinTag->hasTag("Data", StringTag::class) ? $skinTag->getString("Data") : $skinTag->getByteArray("Data"), //old data (this used to be saved as a StringTag in older versions of PM) - $skinTag->getByteArray("CapeData", ""), - $skinTag->getString("GeometryName", ""), - $skinTag->getByteArray("GeometryData", "") - ); - } + public function __construct(Location $location, Skin $skin, CompoundTag $nbt){ + $this->skin = $skin; + parent::__construct($location, $nbt); + } - parent::__construct($world, $nbt); + /** + * @throws InvalidSkinException + * @throws \UnexpectedValueException + */ + public static function parseSkinNBT(CompoundTag $nbt) : Skin{ + $skinTag = $nbt->getCompoundTag("Skin"); + if($skinTag === null){ + throw new \UnexpectedValueException("Missing skin data"); + } + return new Skin( //this throws if the skin is invalid + $skinTag->getString("Name"), + $skinTag->hasTag("Data", StringTag::class) ? $skinTag->getString("Data") : $skinTag->getByteArray("Data"), //old data (this used to be saved as a StringTag in older versions of PM) + $skinTag->getByteArray("CapeData", ""), + $skinTag->getString("GeometryName", ""), + $skinTag->getByteArray("GeometryData", "") + ); } public function getUniqueId() : UUID{ diff --git a/src/entity/object/FallingBlock.php b/src/entity/object/FallingBlock.php index 765d20b63b..fef9b434ac 100644 --- a/src/entity/object/FallingBlock.php +++ b/src/entity/object/FallingBlock.php @@ -27,6 +27,7 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\utils\Fallable; use pocketmine\entity\Entity; +use pocketmine\entity\Location; use pocketmine\event\entity\EntityBlockChangeEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\nbt\tag\ByteTag; @@ -36,7 +37,6 @@ use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use function abs; -use function get_class; class FallingBlock extends Entity{ @@ -55,9 +55,12 @@ class FallingBlock extends Entity{ public $canCollide = false; - protected function initEntity(CompoundTag $nbt) : void{ - parent::initEntity($nbt); + public function __construct(Location $location, Block $block, CompoundTag $nbt){ + $this->block = $block; + parent::__construct($location, $nbt); + } + public static function parseBlockNBT(BlockFactory $factory, CompoundTag $nbt) : Block{ $blockId = 0; //TODO: 1.8+ save format @@ -68,12 +71,12 @@ class FallingBlock extends Entity{ } if($blockId === 0){ - throw new \UnexpectedValueException("Invalid " . get_class($this) . " entity: block ID is 0 or missing"); + throw new \UnexpectedValueException("Missing block info from NBT"); } $damage = $nbt->getByte("Data", 0); - $this->block = BlockFactory::getInstance()->get($blockId, $damage); + return $factory->get($blockId, $damage); } public function canCollideWith(Entity $entity) : bool{ diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index d933e978d8..778a363fa0 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity\object; use pocketmine\entity\Entity; +use pocketmine\entity\Location; use pocketmine\event\entity\ItemDespawnEvent; use pocketmine\event\entity\ItemSpawnEvent; use pocketmine\event\inventory\InventoryPickupItemEvent; @@ -33,7 +34,6 @@ use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\AddItemActorPacket; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\player\Player; -use function get_class; use function max; class ItemEntity extends Entity{ @@ -65,6 +65,14 @@ class ItemEntity extends Entity{ /** @var int */ protected $despawnDelay = self::DEFAULT_DESPAWN_DELAY; + public function __construct(Location $location, Item $item, CompoundTag $nbt){ + if($item->isNull()){ + throw new \InvalidArgumentException("Item entity must have a non-air item with a count of at least 1"); + } + $this->item = $item; + parent::__construct($location, $nbt); + } + protected function initEntity(CompoundTag $nbt) : void{ parent::initEntity($nbt); @@ -81,16 +89,6 @@ class ItemEntity extends Entity{ $this->owner = $nbt->getString("Owner", $this->owner); $this->thrower = $nbt->getString("Thrower", $this->thrower); - $itemTag = $nbt->getCompoundTag("Item"); - if($itemTag === null){ - throw new \UnexpectedValueException("Invalid " . get_class($this) . " entity: expected \"Item\" NBT tag not found"); - } - - $this->item = Item::nbtDeserialize($itemTag); - if($this->item->isNull()){ - throw new \UnexpectedValueException("Item for " . get_class($this) . " is invalid"); - } - (new ItemSpawnEvent($this))->call(); } diff --git a/src/entity/object/Painting.php b/src/entity/object/Painting.php index f2d9f21e68..ac69cd3a04 100644 --- a/src/entity/object/Painting.php +++ b/src/entity/object/Painting.php @@ -25,12 +25,12 @@ namespace pocketmine\entity\object; use pocketmine\block\VanillaBlocks; use pocketmine\entity\Entity; +use pocketmine\entity\Location; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\item\VanillaItems; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\AddPaintingPacket; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; @@ -42,7 +42,7 @@ use function ceil; class Painting extends Entity{ public static function getNetworkTypeId() : int{ return EntityLegacyIds::PAINTING; } - private const DATA_TO_FACING = [ + public const DATA_TO_FACING = [ 0 => Facing::SOUTH, 1 => Facing::WEST, 2 => Facing::NORTH, @@ -73,15 +73,11 @@ class Painting extends Entity{ /** @var string */ protected $motive; - public function __construct(World $world, CompoundTag $nbt){ - $this->motive = $nbt->getString("Motive"); - $this->blockIn = new Vector3($nbt->getInt("TileX"), $nbt->getInt("TileY"), $nbt->getInt("TileZ")); - if($nbt->hasTag("Direction", ByteTag::class)){ - $this->facing = self::DATA_TO_FACING[$nbt->getByte("Direction")] ?? Facing::NORTH; - }elseif($nbt->hasTag("Facing", ByteTag::class)){ - $this->facing = self::DATA_TO_FACING[$nbt->getByte("Facing")] ?? Facing::NORTH; - } - parent::__construct($world, $nbt); + public function __construct(Location $location, Vector3 $blockIn, int $facing, PaintingMotive $motive, CompoundTag $nbt){ + $this->motive = $motive->getName(); //TODO: use motive directly + $this->blockIn = $blockIn->asVector3(); + $this->facing = $facing; + parent::__construct($location, $nbt); } protected function initEntity(CompoundTag $nbt) : void{ diff --git a/src/entity/object/PrimedTNT.php b/src/entity/object/PrimedTNT.php index b38f8a68f3..1a22d030b4 100644 --- a/src/entity/object/PrimedTNT.php +++ b/src/entity/object/PrimedTNT.php @@ -53,6 +53,17 @@ class PrimedTNT extends Entity implements Explosive{ public $canCollide = false; + public function getFuse() : int{ + return $this->fuse; + } + + public function setFuse(int $fuse) : void{ + if($fuse < 0 or $fuse > 32767){ + throw new \InvalidArgumentException("Fuse must be in the range 0-32767"); + } + $this->fuse = $fuse; + } + public function attack(EntityDamageEvent $source) : void{ if($source->getCause() === EntityDamageEvent::CAUSE_VOID){ parent::attack($source); diff --git a/src/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php index 6609453ee9..a5b631cc53 100644 --- a/src/entity/projectile/Arrow.php +++ b/src/entity/projectile/Arrow.php @@ -26,6 +26,7 @@ namespace pocketmine\entity\projectile; use pocketmine\block\Block; use pocketmine\entity\animation\ArrowShakeAnimation; use pocketmine\entity\Entity; +use pocketmine\entity\Location; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\event\inventory\InventoryPickupArrowEvent; use pocketmine\item\VanillaItems; @@ -36,7 +37,6 @@ use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\player\Player; use pocketmine\world\sound\ArrowHitSound; -use pocketmine\world\World; use function mt_rand; use function sqrt; @@ -71,8 +71,8 @@ class Arrow extends Projectile{ /** @var bool */ protected $critical = false; - public function __construct(World $world, CompoundTag $nbt, ?Entity $shootingEntity = null, bool $critical = false){ - parent::__construct($world, $nbt, $shootingEntity); + public function __construct(Location $location, ?Entity $shootingEntity, bool $critical, CompoundTag $nbt){ + parent::__construct($location, $shootingEntity, $nbt); $this->setCritical($critical); } diff --git a/src/entity/projectile/Projectile.php b/src/entity/projectile/Projectile.php index 018d28a515..9f2dee5c8a 100644 --- a/src/entity/projectile/Projectile.php +++ b/src/entity/projectile/Projectile.php @@ -27,6 +27,7 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\entity\Entity; use pocketmine\entity\Living; +use pocketmine\entity\Location; use pocketmine\event\entity\EntityCombustByEntityEvent; use pocketmine\event\entity\EntityDamageByChildEntityEvent; use pocketmine\event\entity\EntityDamageByEntityEvent; @@ -41,7 +42,6 @@ use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\timings\Timings; -use pocketmine\world\World; use function assert; use function atan2; use function ceil; @@ -57,8 +57,8 @@ abstract class Projectile extends Entity{ /** @var Block|null */ protected $blockHit; - public function __construct(World $world, CompoundTag $nbt, ?Entity $shootingEntity = null){ - parent::__construct($world, $nbt); + public function __construct(Location $location, ?Entity $shootingEntity, CompoundTag $nbt){ + parent::__construct($location, $nbt); if($shootingEntity !== null){ $this->setOwningEntity($shootingEntity); } diff --git a/src/item/Bow.php b/src/item/Bow.php index f5fe19e47a..d54d194d8c 100644 --- a/src/item/Bow.php +++ b/src/item/Bow.php @@ -23,12 +23,13 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\EntityFactory; +use pocketmine\entity\Location; use pocketmine\entity\projectile\Arrow as ArrowEntity; use pocketmine\entity\projectile\Projectile; use pocketmine\event\entity\EntityShootBowEvent; use pocketmine\event\entity\ProjectileLaunchEvent; use pocketmine\item\enchantment\Enchantment; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\player\Player; use pocketmine\world\sound\BowShootSound; use function intdiv; @@ -51,18 +52,18 @@ class Bow extends Tool{ } $location = $player->getLocation(); - $nbt = EntityFactory::createBaseNBT( - $player->getEyePos(), - $player->getDirectionVector(), - ($location->yaw > 180 ? 360 : 0) - $location->yaw, - -$location->pitch - ); $diff = $player->getItemUseDuration(); $p = $diff / 20; $baseForce = min((($p ** 2) + $p * 2) / 3, 1); - $entity = new ArrowEntity($location->getWorldNonNull(), $nbt, $player, $baseForce >= 1); + $entity = new ArrowEntity(Location::fromObject( + $player->getEyePos(), + $player->getWorld(), + ($location->yaw > 180 ? 360 : 0) - $location->yaw, + -$location->pitch + ), $player, $baseForce >= 1, new CompoundTag()); + $entity->setMotion($player->getDirectionVector()); $infinity = $this->hasEnchantment(Enchantment::INFINITY()); if($infinity){ diff --git a/src/item/Egg.php b/src/item/Egg.php index 6ad22172eb..a441f72913 100644 --- a/src/item/Egg.php +++ b/src/item/Egg.php @@ -23,10 +23,10 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\EntityFactory; use pocketmine\entity\Location; use pocketmine\entity\projectile\Egg as EggEntity; use pocketmine\entity\projectile\Throwable; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\player\Player; class Egg extends ProjectileItem{ @@ -36,11 +36,7 @@ class Egg extends ProjectileItem{ } protected function createEntity(Location $location, Player $thrower) : Throwable{ - return new EggEntity( - $location->getWorldNonNull(), - EntityFactory::createBaseNBT($location, null, $location->yaw, $location->pitch), - $thrower - ); + return new EggEntity($location, $thrower, new CompoundTag()); } public function getThrowForce() : float{ diff --git a/src/item/EnderPearl.php b/src/item/EnderPearl.php index 4c865cbdca..502e52f355 100644 --- a/src/item/EnderPearl.php +++ b/src/item/EnderPearl.php @@ -23,10 +23,10 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\EntityFactory; use pocketmine\entity\Location; use pocketmine\entity\projectile\EnderPearl as EnderPearlEntity; use pocketmine\entity\projectile\Throwable; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\player\Player; class EnderPearl extends ProjectileItem{ @@ -36,11 +36,7 @@ class EnderPearl extends ProjectileItem{ } protected function createEntity(Location $location, Player $thrower) : Throwable{ - return new EnderPearlEntity( - $location->getWorldNonNull(), - EntityFactory::createBaseNBT($location, null, $location->yaw, $location->pitch), - $thrower - ); + return new EnderPearlEntity($location, $thrower, new CompoundTag()); } public function getThrowForce() : float{ diff --git a/src/item/ExperienceBottle.php b/src/item/ExperienceBottle.php index 20af8b56a8..d9de8628f4 100644 --- a/src/item/ExperienceBottle.php +++ b/src/item/ExperienceBottle.php @@ -23,20 +23,16 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\EntityFactory; use pocketmine\entity\Location; use pocketmine\entity\projectile\ExperienceBottle as ExperienceBottleEntity; use pocketmine\entity\projectile\Throwable; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\player\Player; class ExperienceBottle extends ProjectileItem{ protected function createEntity(Location $location, Player $thrower) : Throwable{ - return new ExperienceBottleEntity( - $location->getWorldNonNull(), - EntityFactory::createBaseNBT($location, null, $location->yaw, $location->pitch), - $thrower - ); + return new ExperienceBottleEntity($location, $thrower, new CompoundTag()); } public function getThrowForce() : float{ diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 2c286bc57e..23b63f604f 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -30,7 +30,7 @@ use pocketmine\block\utils\SkullType; use pocketmine\block\utils\TreeType; use pocketmine\block\VanillaBlocks; use pocketmine\entity\Entity; -use pocketmine\entity\EntityFactory; +use pocketmine\entity\Location; use pocketmine\entity\Squid; use pocketmine\entity\Villager; use pocketmine\entity\Zombie; @@ -319,17 +319,17 @@ class ItemFactory{ //TODO: the meta values should probably be hardcoded; they won't change, but the EntityLegacyIds might $this->register(new class(ItemIds::SPAWN_EGG, EntityLegacyIds::ZOMBIE, "Zombie Spawn Egg") extends SpawnEgg{ protected function createEntity(World $world, Vector3 $pos, float $yaw, float $pitch) : Entity{ - return new Zombie($world, EntityFactory::createBaseNBT($pos, null, $yaw, $pitch)); + return new Zombie(Location::fromObject($pos, $world, $yaw, $pitch), new CompoundTag()); } }); $this->register(new class(ItemIds::SPAWN_EGG, EntityLegacyIds::SQUID, "Squid Spawn Egg") extends SpawnEgg{ public function createEntity(World $world, Vector3 $pos, float $yaw, float $pitch) : Entity{ - return new Squid($world, EntityFactory::createBaseNBT($pos, null, $yaw, $pitch)); + return new Squid(Location::fromObject($pos, $world, $yaw, $pitch), new CompoundTag()); } }); $this->register(new class(ItemIds::SPAWN_EGG, EntityLegacyIds::VILLAGER, "Villager Spawn Egg") extends SpawnEgg{ public function createEntity(World $world, Vector3 $pos, float $yaw, float $pitch) : Entity{ - return new Villager($world, EntityFactory::createBaseNBT($pos, null, $yaw, $pitch)); + return new Villager(Location::fromObject($pos, $world, $yaw, $pitch), new CompoundTag()); } }); } diff --git a/src/item/PaintingItem.php b/src/item/PaintingItem.php index 16de653354..c4442a8f94 100644 --- a/src/item/PaintingItem.php +++ b/src/item/PaintingItem.php @@ -24,11 +24,12 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\block\Block; -use pocketmine\entity\EntityFactory; +use pocketmine\entity\Location; use pocketmine\entity\object\Painting; use pocketmine\entity\object\PaintingMotive; use pocketmine\math\Facing; use pocketmine\math\Vector3; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\player\Player; use pocketmine\world\sound\PaintingPlaceSound; use function array_rand; @@ -72,28 +73,10 @@ class PaintingItem extends Item{ /** @var PaintingMotive $motive */ $motive = $motives[array_rand($motives)]; - static $directions = [ - Facing::SOUTH => 0, - Facing::WEST => 1, - Facing::NORTH => 2, - Facing::EAST => 3 - ]; - - $direction = $directions[$face] ?? -1; - if($direction === -1){ - return ItemUseResult::NONE(); - } - $replacePos = $blockReplace->getPos(); $clickedPos = $blockClicked->getPos(); - $nbt = EntityFactory::createBaseNBT($replacePos, null, $direction * 90, 0); - $nbt->setByte("Direction", $direction); - $nbt->setString("Motive", $motive->getName()); - $nbt->setInt("TileX", $clickedPos->getFloorX()); - $nbt->setInt("TileY", $clickedPos->getFloorY()); - $nbt->setInt("TileZ", $clickedPos->getFloorZ()); - $entity = new Painting($replacePos->getWorldNonNull(), $nbt); + $entity = new Painting(Location::fromObject($replacePos, $replacePos->getWorldNonNull()), $clickedPos, $face, $motive, new CompoundTag()); $this->pop(); $entity->spawnToAll(); diff --git a/src/item/Snowball.php b/src/item/Snowball.php index 5dd6856a2b..36ab539840 100644 --- a/src/item/Snowball.php +++ b/src/item/Snowball.php @@ -23,10 +23,10 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\EntityFactory; use pocketmine\entity\Location; use pocketmine\entity\projectile\Snowball as SnowballEntity; use pocketmine\entity\projectile\Throwable; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\player\Player; class Snowball extends ProjectileItem{ @@ -36,11 +36,7 @@ class Snowball extends ProjectileItem{ } protected function createEntity(Location $location, Player $thrower) : Throwable{ - return new SnowballEntity( - $location->getWorldNonNull(), - EntityFactory::createBaseNBT($location, null, $location->yaw, $location->pitch), - $thrower - ); + return new SnowballEntity($location, $thrower, new CompoundTag()); } public function getThrowForce() : float{ diff --git a/src/item/SpawnEgg.php b/src/item/SpawnEgg.php index 330bd11286..9748bfe722 100644 --- a/src/item/SpawnEgg.php +++ b/src/item/SpawnEgg.php @@ -25,10 +25,8 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\entity\Entity; -use pocketmine\entity\EntityFactory; use pocketmine\math\Vector3; use pocketmine\player\Player; -use pocketmine\utils\Utils; use pocketmine\world\World; use function lcg_value; diff --git a/src/item/SplashPotion.php b/src/item/SplashPotion.php index 9ad5106bc2..f9662755a7 100644 --- a/src/item/SplashPotion.php +++ b/src/item/SplashPotion.php @@ -23,10 +23,10 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\EntityFactory; use pocketmine\entity\Location; use pocketmine\entity\projectile\SplashPotion as SplashPotionEntity; use pocketmine\entity\projectile\Throwable; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\player\Player; class SplashPotion extends ProjectileItem{ @@ -36,12 +36,7 @@ class SplashPotion extends ProjectileItem{ } protected function createEntity(Location $location, Player $thrower) : Throwable{ - $projectile = new SplashPotionEntity( - $location->getWorldNonNull(), - EntityFactory::createBaseNBT($location, null, $location->yaw, $location->pitch), - $thrower - ); - + $projectile = new SplashPotionEntity($location, $thrower, new CompoundTag()); $projectile->setPotionId($this->meta); return $projectile; } diff --git a/src/player/Player.php b/src/player/Player.php index 6843d2c4d6..3a7695af6e 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -267,7 +267,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->networkSession = $session; $this->playerInfo = $playerInfo; $this->authenticated = $authenticated; - $this->skin = $this->playerInfo->getSkin(); $this->username = $username; $this->displayName = $this->username; @@ -282,16 +281,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $namedtag = $this->server->getOfflinePlayerData($this->username); //TODO: make this async - $spawnReset = false; - if($namedtag !== null and ($world = $this->server->getWorldManager()->getWorldByName($namedtag->getString("Level", ""))) !== null){ - /** @var float[] $pos */ - $pos = $namedtag->getListTag("Pos")->getAllValues(); - $spawn = new Vector3($pos[0], $pos[1], $pos[2]); + $spawn = EntityFactory::parseLocation($namedtag, $world); }else{ - $world = $this->server->getWorldManager()->getDefaultWorld(); //TODO: default world might be null - $spawn = $world->getSafeSpawn(); - $spawnReset = true; + $world = $this->server->getWorldManager()->getDefaultWorld(); + $spawn = Location::fromObject($world->getSafeSpawn(), $world); } //load the spawn chunk so we can see the terrain @@ -300,20 +294,13 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->usedChunks[World::chunkHash($spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4)] = UsedChunkStatus::NEEDED(); if($namedtag === null){ - $namedtag = EntityFactory::createBaseNBT($spawn); + $namedtag = new CompoundTag(); $namedtag->setByte("OnGround", 1); //TODO: this hack is needed for new players in-air ticks - they don't get detected as on-ground until they move //TODO: old code had a TODO for SpawnForced - - }elseif($spawnReset){ - $namedtag->setTag("Pos", new ListTag([ - new DoubleTag($spawn->x), - new DoubleTag($spawn->y), - new DoubleTag($spawn->z) - ])); } - parent::__construct($world, $namedtag); + parent::__construct($spawn, $this->playerInfo->getSkin(), $namedtag); $ev = new PlayerLoginEvent($this, "Plugin reason"); $ev->call(); diff --git a/src/world/World.php b/src/world/World.php index d1a7b0c561..2154b94cca 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -34,7 +34,7 @@ use pocketmine\block\tile\Spawnable; use pocketmine\block\tile\Tile; use pocketmine\block\UnknownBlock; use pocketmine\entity\Entity; -use pocketmine\entity\EntityFactory; +use pocketmine\entity\Location; use pocketmine\entity\object\ExperienceOrb; use pocketmine\entity\object\ItemEntity; use pocketmine\event\block\BlockBreakEvent; @@ -52,6 +52,7 @@ use pocketmine\item\ItemUseResult; use pocketmine\item\LegacyStringToItemParser; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\BlockActorDataPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; @@ -1385,16 +1386,13 @@ class World implements ChunkManager{ return null; } - $motion = $motion ?? new Vector3(lcg_value() * 0.2 - 0.1, 0.2, lcg_value() * 0.2 - 0.1); - $nbt = EntityFactory::createBaseNBT($source, $motion, lcg_value() * 360, 0); - $nbt->setShort("Health", 5); - $nbt->setShort("PickupDelay", $delay); - $nbt->setTag("Item", $item->nbtSerialize()); + $itemEntity = new ItemEntity(Location::fromObject($source, $this, lcg_value() * 360, 0), $item, new CompoundTag()); - $itemEntity = new ItemEntity($this, $nbt); + $itemEntity->setPickupDelay($delay); + $itemEntity->setMotion($motion ?? new Vector3(lcg_value() * 0.2 - 0.1, 0.2, lcg_value() * 0.2 - 0.1)); $itemEntity->spawnToAll(); - return $itemEntity; + return $itemEntity; } /** @@ -1407,16 +1405,12 @@ class World implements ChunkManager{ $orbs = []; foreach(ExperienceOrb::splitIntoOrbSizes($amount) as $split){ - $nbt = EntityFactory::createBaseNBT( - $pos, - $this->temporalVector->setComponents((lcg_value() * 0.2 - 0.1) * 2, lcg_value() * 0.4, (lcg_value() * 0.2 - 0.1) * 2), - lcg_value() * 360, - 0 - ); - $nbt->setShort(ExperienceOrb::TAG_VALUE_PC, $split); + $orb = new ExperienceOrb(Location::fromObject($pos, $this,lcg_value() * 360, 0), new CompoundTag()); - $orb = new ExperienceOrb($this, $nbt); + $orb->setXpValue($split); + $orb->setMotion($this->temporalVector->setComponents((lcg_value() * 0.2 - 0.1) * 2, lcg_value() * 0.4, (lcg_value() * 0.2 - 0.1) * 2)); $orb->spawnToAll(); + $orbs[] = $orb; } From 0a1bb0041bc6f03ea986ef181c1e5102cc04a8d8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jun 2020 09:26:13 +0100 Subject: [PATCH 1669/3224] Player: avoid using NBT for onGround hack --- src/player/Player.php | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 3a7695af6e..ec67c09e54 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -283,9 +283,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($namedtag !== null and ($world = $this->server->getWorldManager()->getWorldByName($namedtag->getString("Level", ""))) !== null){ $spawn = EntityFactory::parseLocation($namedtag, $world); + $onGround = $namedtag->getByte("OnGround", 1) === 1; }else{ $world = $this->server->getWorldManager()->getDefaultWorld(); $spawn = Location::fromObject($world->getSafeSpawn(), $world); + $onGround = true; } //load the spawn chunk so we can see the terrain @@ -293,14 +295,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $world->registerChunkListener($this, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4); $this->usedChunks[World::chunkHash($spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4)] = UsedChunkStatus::NEEDED(); - if($namedtag === null){ - $namedtag = new CompoundTag(); - - $namedtag->setByte("OnGround", 1); //TODO: this hack is needed for new players in-air ticks - they don't get detected as on-ground until they move - //TODO: old code had a TODO for SpawnForced - } - - parent::__construct($spawn, $this->playerInfo->getSkin(), $namedtag); + parent::__construct($spawn, $this->playerInfo->getSkin(), $namedtag ?? new CompoundTag()); + $this->onGround = $onGround; //TODO: this hack is needed for new players in-air ticks - they don't get detected as on-ground until they move $ev = new PlayerLoginEvent($this, "Plugin reason"); $ev->call(); From 4b528aa637bf20179f4e73c70fae5260401a6199 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jun 2020 09:49:06 +0100 Subject: [PATCH 1670/3224] NBT is no longer needed to create an entity it's still able to be provided, but shouldn't be needed in the majority of cases (constructor args and/or API methods should be sufficient). --- src/block/TNT.php | 3 +-- src/block/utils/FallableTrait.php | 3 +-- src/entity/Entity.php | 6 +++--- src/entity/Human.php | 2 +- src/entity/object/FallingBlock.php | 2 +- src/entity/object/ItemEntity.php | 2 +- src/entity/object/Painting.php | 2 +- src/entity/projectile/Arrow.php | 2 +- src/entity/projectile/Projectile.php | 2 +- src/item/Bow.php | 3 +-- src/item/ItemFactory.php | 6 +++--- src/item/PaintingItem.php | 3 +-- src/player/Player.php | 2 +- src/world/World.php | 5 ++--- 14 files changed, 19 insertions(+), 24 deletions(-) diff --git a/src/block/TNT.php b/src/block/TNT.php index da57818a84..a07634d54d 100644 --- a/src/block/TNT.php +++ b/src/block/TNT.php @@ -32,7 +32,6 @@ use pocketmine\item\enchantment\Enchantment; use pocketmine\item\FlintSteel; use pocketmine\item\Item; use pocketmine\math\Vector3; -use pocketmine\nbt\tag\CompoundTag; use pocketmine\player\Player; use pocketmine\utils\Random; use function cos; @@ -95,7 +94,7 @@ class TNT extends Opaque{ $mot = (new Random())->nextSignedFloat() * M_PI * 2; - $tnt = new PrimedTNT(Location::fromObject($this->pos->add(0.5, 0, 0.5), $this->pos->getWorldNonNull()), new CompoundTag()); + $tnt = new PrimedTNT(Location::fromObject($this->pos->add(0.5, 0, 0.5), $this->pos->getWorldNonNull())); $tnt->setFuse($fuse); $tnt->setMotion(new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02)); diff --git a/src/block/utils/FallableTrait.php b/src/block/utils/FallableTrait.php index fe88647672..be51117a0a 100644 --- a/src/block/utils/FallableTrait.php +++ b/src/block/utils/FallableTrait.php @@ -31,7 +31,6 @@ use pocketmine\block\VanillaBlocks; use pocketmine\entity\Location; use pocketmine\entity\object\FallingBlock; use pocketmine\math\Facing; -use pocketmine\nbt\tag\CompoundTag; use pocketmine\utils\AssumptionFailedError; use pocketmine\world\Position; @@ -57,7 +56,7 @@ trait FallableTrait{ $block = $this; if(!($block instanceof Block)) throw new AssumptionFailedError(__TRAIT__ . " should only be used by Blocks"); - $fall = new FallingBlock(Location::fromObject($pos->add(0.5, 0, 0.5), $pos->getWorldNonNull()), $block, new CompoundTag()); + $fall = new FallingBlock(Location::fromObject($pos->add(0.5, 0, 0.5), $pos->getWorldNonNull()), $block); $fall->spawnToAll(); } } diff --git a/src/entity/Entity.php b/src/entity/Entity.php index b40977450c..f44ba784cb 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -213,7 +213,7 @@ abstract class Entity{ /** @var int|null */ protected $targetId = null; - public function __construct(Location $location, CompoundTag $nbt){ + public function __construct(Location $location, ?CompoundTag $nbt = null){ $this->timings = Timings::getEntityTimings($this); $this->temporalVector = new Vector3(); @@ -241,7 +241,7 @@ abstract class Entity{ } $this->motion = new Vector3(0, 0, 0); - if($nbt->hasTag("Motion", ListTag::class)){ + if($nbt !== null and $nbt->hasTag("Motion", ListTag::class)){ /** @var float[] $motion */ $motion = $nbt->getListTag("Motion")->getAllValues(); $this->setMotion($this->temporalVector->setComponents(...$motion)); @@ -254,7 +254,7 @@ abstract class Entity{ $this->attributeMap = new AttributeMap(); $this->addAttributes(); - $this->initEntity($nbt); + $this->initEntity($nbt ?? new CompoundTag()); $this->chunk->addEntity($this); $this->getWorld()->addEntity($this); diff --git a/src/entity/Human.php b/src/entity/Human.php index 77b37d618f..04c5a38e40 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -93,7 +93,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ protected $baseOffset = 1.62; - public function __construct(Location $location, Skin $skin, CompoundTag $nbt){ + public function __construct(Location $location, Skin $skin, ?CompoundTag $nbt = null){ $this->skin = $skin; parent::__construct($location, $nbt); } diff --git a/src/entity/object/FallingBlock.php b/src/entity/object/FallingBlock.php index fef9b434ac..a3d78e785e 100644 --- a/src/entity/object/FallingBlock.php +++ b/src/entity/object/FallingBlock.php @@ -55,7 +55,7 @@ class FallingBlock extends Entity{ public $canCollide = false; - public function __construct(Location $location, Block $block, CompoundTag $nbt){ + public function __construct(Location $location, Block $block, ?CompoundTag $nbt = null){ $this->block = $block; parent::__construct($location, $nbt); } diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index 778a363fa0..3c835c0f4a 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -65,7 +65,7 @@ class ItemEntity extends Entity{ /** @var int */ protected $despawnDelay = self::DEFAULT_DESPAWN_DELAY; - public function __construct(Location $location, Item $item, CompoundTag $nbt){ + public function __construct(Location $location, Item $item, ?CompoundTag $nbt = null){ if($item->isNull()){ throw new \InvalidArgumentException("Item entity must have a non-air item with a count of at least 1"); } diff --git a/src/entity/object/Painting.php b/src/entity/object/Painting.php index ac69cd3a04..9282199f10 100644 --- a/src/entity/object/Painting.php +++ b/src/entity/object/Painting.php @@ -73,7 +73,7 @@ class Painting extends Entity{ /** @var string */ protected $motive; - public function __construct(Location $location, Vector3 $blockIn, int $facing, PaintingMotive $motive, CompoundTag $nbt){ + public function __construct(Location $location, Vector3 $blockIn, int $facing, PaintingMotive $motive, ?CompoundTag $nbt = null){ $this->motive = $motive->getName(); //TODO: use motive directly $this->blockIn = $blockIn->asVector3(); $this->facing = $facing; diff --git a/src/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php index a5b631cc53..d94679747e 100644 --- a/src/entity/projectile/Arrow.php +++ b/src/entity/projectile/Arrow.php @@ -71,7 +71,7 @@ class Arrow extends Projectile{ /** @var bool */ protected $critical = false; - public function __construct(Location $location, ?Entity $shootingEntity, bool $critical, CompoundTag $nbt){ + public function __construct(Location $location, ?Entity $shootingEntity, bool $critical, ?CompoundTag $nbt = null){ parent::__construct($location, $shootingEntity, $nbt); $this->setCritical($critical); } diff --git a/src/entity/projectile/Projectile.php b/src/entity/projectile/Projectile.php index 9f2dee5c8a..f4aa9aa1b3 100644 --- a/src/entity/projectile/Projectile.php +++ b/src/entity/projectile/Projectile.php @@ -57,7 +57,7 @@ abstract class Projectile extends Entity{ /** @var Block|null */ protected $blockHit; - public function __construct(Location $location, ?Entity $shootingEntity, CompoundTag $nbt){ + public function __construct(Location $location, ?Entity $shootingEntity, ?CompoundTag $nbt = null){ parent::__construct($location, $nbt); if($shootingEntity !== null){ $this->setOwningEntity($shootingEntity); diff --git a/src/item/Bow.php b/src/item/Bow.php index d54d194d8c..0f68e1410e 100644 --- a/src/item/Bow.php +++ b/src/item/Bow.php @@ -29,7 +29,6 @@ use pocketmine\entity\projectile\Projectile; use pocketmine\event\entity\EntityShootBowEvent; use pocketmine\event\entity\ProjectileLaunchEvent; use pocketmine\item\enchantment\Enchantment; -use pocketmine\nbt\tag\CompoundTag; use pocketmine\player\Player; use pocketmine\world\sound\BowShootSound; use function intdiv; @@ -62,7 +61,7 @@ class Bow extends Tool{ $player->getWorld(), ($location->yaw > 180 ? 360 : 0) - $location->yaw, -$location->pitch - ), $player, $baseForce >= 1, new CompoundTag()); + ), $player, $baseForce >= 1); $entity->setMotion($player->getDirectionVector()); $infinity = $this->hasEnchantment(Enchantment::INFINITY()); diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 23b63f604f..e06094da1c 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -319,17 +319,17 @@ class ItemFactory{ //TODO: the meta values should probably be hardcoded; they won't change, but the EntityLegacyIds might $this->register(new class(ItemIds::SPAWN_EGG, EntityLegacyIds::ZOMBIE, "Zombie Spawn Egg") extends SpawnEgg{ protected function createEntity(World $world, Vector3 $pos, float $yaw, float $pitch) : Entity{ - return new Zombie(Location::fromObject($pos, $world, $yaw, $pitch), new CompoundTag()); + return new Zombie(Location::fromObject($pos, $world, $yaw, $pitch)); } }); $this->register(new class(ItemIds::SPAWN_EGG, EntityLegacyIds::SQUID, "Squid Spawn Egg") extends SpawnEgg{ public function createEntity(World $world, Vector3 $pos, float $yaw, float $pitch) : Entity{ - return new Squid(Location::fromObject($pos, $world, $yaw, $pitch), new CompoundTag()); + return new Squid(Location::fromObject($pos, $world, $yaw, $pitch)); } }); $this->register(new class(ItemIds::SPAWN_EGG, EntityLegacyIds::VILLAGER, "Villager Spawn Egg") extends SpawnEgg{ public function createEntity(World $world, Vector3 $pos, float $yaw, float $pitch) : Entity{ - return new Villager(Location::fromObject($pos, $world, $yaw, $pitch), new CompoundTag()); + return new Villager(Location::fromObject($pos, $world, $yaw, $pitch)); } }); } diff --git a/src/item/PaintingItem.php b/src/item/PaintingItem.php index c4442a8f94..6c6b1f25e4 100644 --- a/src/item/PaintingItem.php +++ b/src/item/PaintingItem.php @@ -29,7 +29,6 @@ use pocketmine\entity\object\Painting; use pocketmine\entity\object\PaintingMotive; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\nbt\tag\CompoundTag; use pocketmine\player\Player; use pocketmine\world\sound\PaintingPlaceSound; use function array_rand; @@ -76,7 +75,7 @@ class PaintingItem extends Item{ $replacePos = $blockReplace->getPos(); $clickedPos = $blockClicked->getPos(); - $entity = new Painting(Location::fromObject($replacePos, $replacePos->getWorldNonNull()), $clickedPos, $face, $motive, new CompoundTag()); + $entity = new Painting(Location::fromObject($replacePos, $replacePos->getWorldNonNull()), $clickedPos, $face, $motive); $this->pop(); $entity->spawnToAll(); diff --git a/src/player/Player.php b/src/player/Player.php index ec67c09e54..9c3abb9c77 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -295,7 +295,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $world->registerChunkListener($this, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4); $this->usedChunks[World::chunkHash($spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4)] = UsedChunkStatus::NEEDED(); - parent::__construct($spawn, $this->playerInfo->getSkin(), $namedtag ?? new CompoundTag()); + parent::__construct($spawn, $this->playerInfo->getSkin(), $namedtag); $this->onGround = $onGround; //TODO: this hack is needed for new players in-air ticks - they don't get detected as on-ground until they move $ev = new PlayerLoginEvent($this, "Plugin reason"); diff --git a/src/world/World.php b/src/world/World.php index 2154b94cca..1b29d812fd 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -52,7 +52,6 @@ use pocketmine\item\ItemUseResult; use pocketmine\item\LegacyStringToItemParser; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; -use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\BlockActorDataPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; @@ -1386,7 +1385,7 @@ class World implements ChunkManager{ return null; } - $itemEntity = new ItemEntity(Location::fromObject($source, $this, lcg_value() * 360, 0), $item, new CompoundTag()); + $itemEntity = new ItemEntity(Location::fromObject($source, $this, lcg_value() * 360, 0), $item); $itemEntity->setPickupDelay($delay); $itemEntity->setMotion($motion ?? new Vector3(lcg_value() * 0.2 - 0.1, 0.2, lcg_value() * 0.2 - 0.1)); @@ -1405,7 +1404,7 @@ class World implements ChunkManager{ $orbs = []; foreach(ExperienceOrb::splitIntoOrbSizes($amount) as $split){ - $orb = new ExperienceOrb(Location::fromObject($pos, $this,lcg_value() * 360, 0), new CompoundTag()); + $orb = new ExperienceOrb(Location::fromObject($pos, $this, lcg_value() * 360, 0)); $orb->setXpValue($split); $orb->setMotion($this->temporalVector->setComponents((lcg_value() * 0.2 - 0.1) * 2, lcg_value() * 0.4, (lcg_value() * 0.2 - 0.1) * 2)); From 60a6b4b10ddbc59ec3606f4e698633a597eb4195 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jun 2020 10:18:31 +0100 Subject: [PATCH 1671/3224] Entity: use EntityFactory helper function to deserialize Motion --- src/entity/Entity.php | 10 ++++------ src/entity/EntityFactory.php | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index f44ba784cb..f529db4893 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -41,7 +41,6 @@ use pocketmine\math\Facing; use pocketmine\math\Vector2; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\protocol\AddActorPacket; use pocketmine\network\mcpe\protocol\MoveActorAbsolutePacket; @@ -240,11 +239,10 @@ abstract class Entity{ throw new \InvalidStateException("Cannot create entities in unloaded chunks"); } - $this->motion = new Vector3(0, 0, 0); - if($nbt !== null and $nbt->hasTag("Motion", ListTag::class)){ - /** @var float[] $motion */ - $motion = $nbt->getListTag("Motion")->getAllValues(); - $this->setMotion($this->temporalVector->setComponents(...$motion)); + if($nbt !== null){ + $this->motion = EntityFactory::parseVec3($nbt, "Motion", true); + }else{ + $this->motion = new Vector3(0, 0, 0); } $this->resetLastMovements(); diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index d74b206acd..ef0bbcb2b5 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -290,7 +290,7 @@ final class EntityFactory{ return Location::fromObject($pos, $world, $values[0]->getValue(), $values[1]->getValue()); } - private static function parseVec3(CompoundTag $nbt, string $tagName, bool $optional) : Vector3{ + public static function parseVec3(CompoundTag $nbt, string $tagName, bool $optional) : Vector3{ $pos = $nbt->getTag($tagName); if($pos === null and $optional){ return new Vector3(0, 0, 0); From 4b0bf34adbea1d49586500f5dfdbc094af2fec29 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jun 2020 11:17:20 +0100 Subject: [PATCH 1672/3224] Location: add native typehints --- src/entity/Location.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/entity/Location.php b/src/entity/Location.php index efd9bb4118..f9a59c50e9 100644 --- a/src/entity/Location.php +++ b/src/entity/Location.php @@ -34,12 +34,7 @@ class Location extends Position{ /** @var float */ public $pitch; - /** - * @param float|int $x - * @param float|int $y - * @param float|int $z - */ - public function __construct($x = 0, $y = 0, $z = 0, float $yaw = 0.0, float $pitch = 0.0, ?World $world = null){ + public function __construct(float $x = 0, float $y = 0, float $z = 0, float $yaw = 0.0, float $pitch = 0.0, ?World $world = null){ $this->yaw = $yaw; $this->pitch = $pitch; parent::__construct($x, $y, $z, $world); From 9f89f2887a329a20808ae6c5b384f9d8d5a0bea0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jun 2020 11:19:05 +0100 Subject: [PATCH 1673/3224] Location: x,y,z parameters are now mandatory --- src/entity/Location.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entity/Location.php b/src/entity/Location.php index f9a59c50e9..2ff9171ac4 100644 --- a/src/entity/Location.php +++ b/src/entity/Location.php @@ -34,7 +34,7 @@ class Location extends Position{ /** @var float */ public $pitch; - public function __construct(float $x = 0, float $y = 0, float $z = 0, float $yaw = 0.0, float $pitch = 0.0, ?World $world = null){ + public function __construct(float $x, float $y, float $z, float $yaw = 0.0, float $pitch = 0.0, ?World $world = null){ $this->yaw = $yaw; $this->pitch = $pitch; parent::__construct($x, $y, $z, $world); From fb4a99a0efacd121146d5494cbfded399d8999db Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jun 2020 11:21:47 +0100 Subject: [PATCH 1674/3224] Position: x,y,z parameters are now mandatory --- src/world/Position.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/Position.php b/src/world/Position.php index c295a585f1..3642d8d3cd 100644 --- a/src/world/Position.php +++ b/src/world/Position.php @@ -37,7 +37,7 @@ class Position extends Vector3{ * @param float|int $y * @param float|int $z */ - public function __construct($x = 0, $y = 0, $z = 0, ?World $world = null){ + public function __construct($x, $y, $z, ?World $world = null){ parent::__construct($x, $y, $z); if($world !== null and $world->isClosed()){ throw new \InvalidArgumentException("Specified world has been unloaded and cannot be used"); From 954e8e6e6f673295c5a10063e2ae87533f252371 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jun 2020 11:33:10 +0100 Subject: [PATCH 1675/3224] update pocketmine/math dependency --- composer.lock | 8 ++++---- src/entity/Entity.php | 2 +- .../protocol/types/inventory/UseItemTransactionData.php | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 0ab79499ec..53ad2dfb53 100644 --- a/composer.lock +++ b/composer.lock @@ -552,12 +552,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "666175cd9a6561217d436902c666405b790a1a86" + "reference": "d46310a42ab5535296ded0b9368e5642af723f47" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/666175cd9a6561217d436902c666405b790a1a86", - "reference": "666175cd9a6561217d436902c666405b790a1a86", + "url": "https://api.github.com/repos/pmmp/Math/zipball/d46310a42ab5535296ded0b9368e5642af723f47", + "reference": "d46310a42ab5535296ded0b9368e5642af723f47", "shasum": "" }, "require": { @@ -579,7 +579,7 @@ "LGPL-3.0" ], "description": "PHP library containing math related code used in PocketMine-MP", - "time": "2020-06-15T21:21:46+00:00" + "time": "2020-06-19T10:25:24+00:00" }, { "name": "pocketmine/nbt", diff --git a/src/entity/Entity.php b/src/entity/Entity.php index f529db4893..bdd7b79f62 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -215,7 +215,7 @@ abstract class Entity{ public function __construct(Location $location, ?CompoundTag $nbt = null){ $this->timings = Timings::getEntityTimings($this); - $this->temporalVector = new Vector3(); + $this->temporalVector = new Vector3(0, 0, 0); if($this->eyeHeight === null){ $this->eyeHeight = $this->height / 2 + 0.1; diff --git a/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php b/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php index 17d5ad627c..6b59c403c1 100644 --- a/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php @@ -87,7 +87,7 @@ class UseItemTransactionData extends TransactionData{ protected function decodeData(PacketSerializer $stream) : void{ $this->actionType = $stream->getUnsignedVarInt(); - $this->blockPos = new Vector3(); + $this->blockPos = new Vector3(0, 0, 0); $stream->getBlockPosition($this->blockPos->x, $this->blockPos->y, $this->blockPos->z); $this->face = $stream->getVarInt(); $this->hotbarSlot = $stream->getVarInt(); From 6d3750994b143e41d61f118afeb5c1d961f2825b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jun 2020 21:42:38 +0100 Subject: [PATCH 1676/3224] EntityFactory: remove dead function --- src/entity/EntityFactory.php | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index ef0bbcb2b5..a4d9fbfe66 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -54,7 +54,6 @@ use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\utils\SingletonTrait; use pocketmine\utils\Utils; use pocketmine\world\World; -use function array_keys; use function count; use function in_array; use function reset; @@ -224,16 +223,6 @@ final class EntityFactory{ $this->saveNames[$className] = $saveNames; } - /** - * Returns an array of all registered entity classpaths. - * - * @return string[] - * @return class-string[] - */ - public function getKnownTypes() : array{ - return array_keys($this->creationFuncs); - } - /** * Returns a new runtime entity ID for a new entity. */ From 012acdd4cbac8d70ba30822dce17cdd3eca29532 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jun 2020 21:55:49 +0100 Subject: [PATCH 1677/3224] move runtime entity ID counter from EntityFactory back to Entity EntityFactory is specialized for the purpose of deserializing data from worlds, and runtime ID assignment isn't related. --- src/entity/Entity.php | 12 +++++++++++- src/entity/EntityFactory.php | 10 ---------- src/world/particle/FloatingTextParticle.php | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index bdd7b79f62..b55c4a0086 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -77,6 +77,16 @@ abstract class Entity{ public const MOTION_THRESHOLD = 0.00001; + /** @var int */ + private static $entityCount = 1; + + /** + * Returns a new runtime entity ID for a new entity. + */ + public static function nextRuntimeId() : int{ + return self::$entityCount++; + } + /** @var Player[] */ protected $hasSpawned = []; @@ -221,7 +231,7 @@ abstract class Entity{ $this->eyeHeight = $this->height / 2 + 0.1; } - $this->id = EntityFactory::nextRuntimeId(); + $this->id = self::nextRuntimeId(); $this->server = $location->getWorldNonNull()->getServer(); $this->location = $location->asLocation(); diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index a4d9fbfe66..97d3cfedda 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -65,9 +65,6 @@ use function reset; final class EntityFactory{ use SingletonTrait; - /** @var int */ - private static $entityCount = 1; - /** * @var \Closure[] base class => creator function * @phpstan-var array, \Closure(World, CompoundTag) : Entity> @@ -223,13 +220,6 @@ final class EntityFactory{ $this->saveNames[$className] = $saveNames; } - /** - * Returns a new runtime entity ID for a new entity. - */ - public static function nextRuntimeId() : int{ - return self::$entityCount++; - } - /** * Creates an entity from data stored on a chunk. * diff --git a/src/world/particle/FloatingTextParticle.php b/src/world/particle/FloatingTextParticle.php index 5a99f9df08..5b787580a5 100644 --- a/src/world/particle/FloatingTextParticle.php +++ b/src/world/particle/FloatingTextParticle.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\particle; -use pocketmine\entity\EntityFactory; +use pocketmine\entity\Entity; use pocketmine\entity\Skin; use pocketmine\math\Vector3; use pocketmine\network\mcpe\convert\SkinAdapterSingleton; @@ -84,7 +84,7 @@ class FloatingTextParticle implements Particle{ $p = []; if($this->entityId === null){ - $this->entityId = EntityFactory::nextRuntimeId(); + $this->entityId = Entity::nextRuntimeId(); }else{ $p[] = RemoveActorPacket::create($this->entityId); } From 1a3445f4b56f98941220cc82a37eb6002d95c2e5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jun 2020 21:56:50 +0100 Subject: [PATCH 1678/3224] EntityFactory: drop automatic provisioning of short class name as save ID --- src/entity/EntityFactory.php | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index 97d3cfedda..11473ffeb2 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -55,7 +55,6 @@ use pocketmine\utils\SingletonTrait; use pocketmine\utils\Utils; use pocketmine\world\World; use function count; -use function in_array; use function reset; /** @@ -190,26 +189,24 @@ final class EntityFactory{ * * @param string $className Class that extends Entity * @param \Closure $creationFunc - * @param string[] $saveNames An array of save names which this entity might be saved under. Defaults to the short name of the class itself if empty. + * @param string[] $saveNames An array of save names which this entity might be saved under. * @phpstan-param class-string $className + * @phpstan-param list $saveNames * @phpstan-param \Closure(World $world, CompoundTag $nbt) : Entity $creationFunc * - * NOTE: The first save name in the $saveNames array will be used when saving the entity to disk. The reflection - * name of the class will be appended to the end and only used if no other save names are specified. + * NOTE: The first save name in the $saveNames array will be used when saving the entity to disk. * * @throws \InvalidArgumentException */ public function register(string $className, \Closure $creationFunc, array $saveNames, ?int $legacyMcpeSaveId = null) : void{ + if(count($saveNames) === 0){ + throw new \InvalidArgumentException("At least one save name must be provided"); + } Utils::testValidInstance($className, Entity::class); self::validateCreationFunc($className, $creationFunc); $this->creationFuncs[$className] = $creationFunc; - $shortName = (new \ReflectionClass($className))->getShortName(); - if(!in_array($shortName, $saveNames, true)){ - $saveNames[] = $shortName; - } - foreach($saveNames as $name){ $this->knownEntities[$name] = $className; } From 47baaf4c72d7eeaa45ee0348b27e4a059715b822 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jun 2020 22:04:04 +0100 Subject: [PATCH 1679/3224] move NBT helper functions from EntityFactory to EntityDataHelper --- src/entity/Entity.php | 4 +- src/entity/EntityDataHelper.php | 92 +++++++++++++++++++++++++++++++++ src/entity/EntityFactory.php | 86 ++++++------------------------ src/player/Player.php | 4 +- 4 files changed, 111 insertions(+), 75 deletions(-) create mode 100644 src/entity/EntityDataHelper.php diff --git a/src/entity/Entity.php b/src/entity/Entity.php index b55c4a0086..0ec443ebec 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -250,7 +250,7 @@ abstract class Entity{ } if($nbt !== null){ - $this->motion = EntityFactory::parseVec3($nbt, "Motion", true); + $this->motion = EntityDataHelper::parseVec3($nbt, "Motion", true); }else{ $this->motion = new Vector3(0, 0, 0); } @@ -461,7 +461,7 @@ abstract class Entity{ } public function saveNBT() : CompoundTag{ - $nbt = EntityFactory::createBaseNBT($this->location, $this->motion, $this->location->yaw, $this->location->pitch); + $nbt = EntityDataHelper::createBaseNBT($this->location, $this->motion, $this->location->yaw, $this->location->pitch); if(!($this instanceof Player)){ $nbt->setString("id", EntityFactory::getInstance()->getSaveId(get_class($this))); diff --git a/src/entity/EntityDataHelper.php b/src/entity/EntityDataHelper.php new file mode 100644 index 0000000000..cf70e29eb1 --- /dev/null +++ b/src/entity/EntityDataHelper.php @@ -0,0 +1,92 @@ +getTag("Rotation"); + if(!($yawPitch instanceof ListTag) or $yawPitch->getTagType() !== NBT::TAG_Float){ + throw new \UnexpectedValueException("'Rotation' should be a List"); + } + $values = $yawPitch->getValue(); + if(count($values) !== 2){ + throw new \UnexpectedValueException("Expected exactly 2 entries for 'Rotation'"); + } + + return Location::fromObject($pos, $world, $values[0]->getValue(), $values[1]->getValue()); + } + + public static function parseVec3(CompoundTag $nbt, string $tagName, bool $optional) : Vector3{ + $pos = $nbt->getTag($tagName); + if($pos === null and $optional){ + return new Vector3(0, 0, 0); + } + if(!($pos instanceof ListTag) or $pos->getTagType() !== NBT::TAG_Double){ + throw new \UnexpectedValueException("'$tagName' should be a List"); + } + /** @var DoubleTag[] $values */ + $values = $pos->getValue(); + if(count($values) !== 3){ + throw new \UnexpectedValueException("Expected exactly 3 entries in '$tagName' tag"); + } + return new Vector3($values[0]->getValue(), $values[1]->getValue(), $values[2]->getValue()); + } + + /** + * Helper function which creates minimal NBT needed to spawn an entity. + */ + public static function createBaseNBT(Vector3 $pos, ?Vector3 $motion = null, float $yaw = 0.0, float $pitch = 0.0) : CompoundTag{ + return CompoundTag::create() + ->setTag("Pos", new ListTag([ + new DoubleTag($pos->x), + new DoubleTag($pos->y), + new DoubleTag($pos->z) + ])) + ->setTag("Motion", new ListTag([ + new DoubleTag($motion !== null ? $motion->x : 0.0), + new DoubleTag($motion !== null ? $motion->y : 0.0), + new DoubleTag($motion !== null ? $motion->z : 0.0) + ])) + ->setTag("Rotation", new ListTag([ + new FloatTag($yaw), + new FloatTag($pitch) + ])); + } +} diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index 11473ffeb2..e5d2dd4900 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -42,13 +42,9 @@ use pocketmine\entity\projectile\SplashPotion; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\nbt\NBT; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\DoubleTag; -use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\IntTag; -use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\utils\SingletonTrait; @@ -85,27 +81,27 @@ final class EntityFactory{ //TODO: index them by version to allow proper multi-save compatibility $this->register(Arrow::class, function(World $world, CompoundTag $nbt) : Arrow{ - return new Arrow(self::parseLocation($nbt, $world), null, false, $nbt); //TODO: missing critical flag + return new Arrow(EntityDataHelper::parseLocation($nbt, $world), null, false, $nbt); //TODO: missing critical flag }, ['Arrow', 'minecraft:arrow'], EntityLegacyIds::ARROW); $this->register(Egg::class, function(World $world, CompoundTag $nbt) : Egg{ - return new Egg(self::parseLocation($nbt, $world), null, $nbt); + return new Egg(EntityDataHelper::parseLocation($nbt, $world), null, $nbt); }, ['Egg', 'minecraft:egg'], EntityLegacyIds::EGG); $this->register(EnderPearl::class, function(World $world, CompoundTag $nbt) : EnderPearl{ - return new EnderPearl(self::parseLocation($nbt, $world), null, $nbt); + return new EnderPearl(EntityDataHelper::parseLocation($nbt, $world), null, $nbt); }, ['ThrownEnderpearl', 'minecraft:ender_pearl'], EntityLegacyIds::ENDER_PEARL); $this->register(ExperienceBottle::class, function(World $world, CompoundTag $nbt) : ExperienceBottle{ - return new ExperienceBottle(self::parseLocation($nbt, $world), null, $nbt); + return new ExperienceBottle(EntityDataHelper::parseLocation($nbt, $world), null, $nbt); }, ['ThrownExpBottle', 'minecraft:xp_bottle'], EntityLegacyIds::XP_BOTTLE); $this->register(ExperienceOrb::class, function(World $world, CompoundTag $nbt) : ExperienceOrb{ - return new ExperienceOrb(self::parseLocation($nbt, $world), $nbt); + return new ExperienceOrb(EntityDataHelper::parseLocation($nbt, $world), $nbt); }, ['XPOrb', 'minecraft:xp_orb'], EntityLegacyIds::XP_ORB); $this->register(FallingBlock::class, function(World $world, CompoundTag $nbt) : FallingBlock{ - return new FallingBlock(self::parseLocation($nbt, $world), FallingBlock::parseBlockNBT(BlockFactory::getInstance(), $nbt), $nbt); + return new FallingBlock(EntityDataHelper::parseLocation($nbt, $world), FallingBlock::parseBlockNBT(BlockFactory::getInstance(), $nbt), $nbt); }, ['FallingSand', 'minecraft:falling_block'], EntityLegacyIds::FALLING_BLOCK); $this->register(ItemEntity::class, function(World $world, CompoundTag $nbt) : ItemEntity{ @@ -118,7 +114,7 @@ final class EntityFactory{ if($item->isNull()){ throw new \UnexpectedValueException("Item is invalid"); } - return new ItemEntity(self::parseLocation($nbt, $world), $item, $nbt); + return new ItemEntity(EntityDataHelper::parseLocation($nbt, $world), $item, $nbt); }, ['Item', 'minecraft:item'], EntityLegacyIds::ITEM); $this->register(Painting::class, function(World $world, CompoundTag $nbt) : Painting{ @@ -135,35 +131,35 @@ final class EntityFactory{ throw new \UnexpectedValueException("Missing facing info"); } - return new Painting(self::parseLocation($nbt, $world), $blockIn, $facing, $motive, $nbt); + return new Painting(EntityDataHelper::parseLocation($nbt, $world), $blockIn, $facing, $motive, $nbt); }, ['Painting', 'minecraft:painting'], EntityLegacyIds::PAINTING); $this->register(PrimedTNT::class, function(World $world, CompoundTag $nbt) : PrimedTNT{ - return new PrimedTNT(self::parseLocation($nbt, $world), $nbt); + return new PrimedTNT(EntityDataHelper::parseLocation($nbt, $world), $nbt); }, ['PrimedTnt', 'PrimedTNT', 'minecraft:tnt'], EntityLegacyIds::TNT); $this->register(Snowball::class, function(World $world, CompoundTag $nbt) : Snowball{ - return new Snowball(self::parseLocation($nbt, $world), null, $nbt); + return new Snowball(EntityDataHelper::parseLocation($nbt, $world), null, $nbt); }, ['Snowball', 'minecraft:snowball'], EntityLegacyIds::SNOWBALL); $this->register(SplashPotion::class, function(World $world, CompoundTag $nbt) : SplashPotion{ - return new SplashPotion(self::parseLocation($nbt, $world), null, $nbt); + return new SplashPotion(EntityDataHelper::parseLocation($nbt, $world), null, $nbt); }, ['ThrownPotion', 'minecraft:potion', 'thrownpotion'], EntityLegacyIds::SPLASH_POTION); $this->register(Squid::class, function(World $world, CompoundTag $nbt) : Squid{ - return new Squid(self::parseLocation($nbt, $world), $nbt); + return new Squid(EntityDataHelper::parseLocation($nbt, $world), $nbt); }, ['Squid', 'minecraft:squid'], EntityLegacyIds::SQUID); $this->register(Villager::class, function(World $world, CompoundTag $nbt) : Villager{ - return new Villager(self::parseLocation($nbt, $world), $nbt); + return new Villager(EntityDataHelper::parseLocation($nbt, $world), $nbt); }, ['Villager', 'minecraft:villager'], EntityLegacyIds::VILLAGER); $this->register(Zombie::class, function(World $world, CompoundTag $nbt) : Zombie{ - return new Zombie(self::parseLocation($nbt, $world), $nbt); + return new Zombie(EntityDataHelper::parseLocation($nbt, $world), $nbt); }, ['Zombie', 'minecraft:zombie'], EntityLegacyIds::ZOMBIE); $this->register(Human::class, function(World $world, CompoundTag $nbt) : Human{ - return new Human(self::parseLocation($nbt, $world), Human::parseSkinNBT($nbt), $nbt); + return new Human(EntityDataHelper::parseLocation($nbt, $world), Human::parseSkinNBT($nbt), $nbt); }, ['Human']); PaintingMotive::init(); @@ -250,56 +246,4 @@ final class EntityFactory{ } throw new \InvalidArgumentException("Entity $class is not registered"); } - - public static function parseLocation(CompoundTag $nbt, World $world) : Location{ - $pos = self::parseVec3($nbt, "Pos", false); - - $yawPitch = $nbt->getTag("Rotation"); - if(!($yawPitch instanceof ListTag) or $yawPitch->getTagType() !== NBT::TAG_Float){ - throw new \UnexpectedValueException("'Rotation' should be a List"); - } - $values = $yawPitch->getValue(); - if(count($values) !== 2){ - throw new \UnexpectedValueException("Expected exactly 2 entries for 'Rotation'"); - } - - return Location::fromObject($pos, $world, $values[0]->getValue(), $values[1]->getValue()); - } - - public static function parseVec3(CompoundTag $nbt, string $tagName, bool $optional) : Vector3{ - $pos = $nbt->getTag($tagName); - if($pos === null and $optional){ - return new Vector3(0, 0, 0); - } - if(!($pos instanceof ListTag) or $pos->getTagType() !== NBT::TAG_Double){ - throw new \UnexpectedValueException("'$tagName' should be a List"); - } - /** @var DoubleTag[] $values */ - $values = $pos->getValue(); - if(count($values) !== 3){ - throw new \UnexpectedValueException("Expected exactly 3 entries in '$tagName' tag"); - } - return new Vector3($values[0]->getValue(), $values[1]->getValue(), $values[2]->getValue()); - } - - /** - * Helper function which creates minimal NBT needed to spawn an entity. - */ - public static function createBaseNBT(Vector3 $pos, ?Vector3 $motion = null, float $yaw = 0.0, float $pitch = 0.0) : CompoundTag{ - return CompoundTag::create() - ->setTag("Pos", new ListTag([ - new DoubleTag($pos->x), - new DoubleTag($pos->y), - new DoubleTag($pos->z) - ])) - ->setTag("Motion", new ListTag([ - new DoubleTag($motion !== null ? $motion->x : 0.0), - new DoubleTag($motion !== null ? $motion->y : 0.0), - new DoubleTag($motion !== null ? $motion->z : 0.0) - ])) - ->setTag("Rotation", new ListTag([ - new FloatTag($yaw), - new FloatTag($pitch) - ])); - } } diff --git a/src/player/Player.php b/src/player/Player.php index 9c3abb9c77..a0a76d0951 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -34,7 +34,7 @@ use pocketmine\entity\animation\ArmSwingAnimation; use pocketmine\entity\animation\CriticalHitAnimation; use pocketmine\entity\effect\VanillaEffects; use pocketmine\entity\Entity; -use pocketmine\entity\EntityFactory; +use pocketmine\entity\EntityDataHelper; use pocketmine\entity\Human; use pocketmine\entity\Living; use pocketmine\entity\Location; @@ -282,7 +282,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $namedtag = $this->server->getOfflinePlayerData($this->username); //TODO: make this async if($namedtag !== null and ($world = $this->server->getWorldManager()->getWorldByName($namedtag->getString("Level", ""))) !== null){ - $spawn = EntityFactory::parseLocation($namedtag, $world); + $spawn = EntityDataHelper::parseLocation($namedtag, $world); $onGround = $namedtag->getByte("OnGround", 1) === 1; }else{ $world = $this->server->getWorldManager()->getDefaultWorld(); From 0a43fd816cb9ea0c0ca6ba5212b990141ab2b7f9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jun 2020 22:10:35 +0100 Subject: [PATCH 1680/3224] EntityFactory: drop unnecessary @param --- src/entity/EntityFactory.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index e5d2dd4900..e0532c7604 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -184,7 +184,6 @@ final class EntityFactory{ * Registers an entity type into the index. * * @param string $className Class that extends Entity - * @param \Closure $creationFunc * @param string[] $saveNames An array of save names which this entity might be saved under. * @phpstan-param class-string $className * @phpstan-param list $saveNames From 4e8e10ca45f2688eb244b729852485a9956b68be Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jun 2020 22:18:42 +0100 Subject: [PATCH 1681/3224] EntityFactory: remove obsolete indirection (class mappings are redundant here now) --- src/entity/EntityFactory.php | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index e0532c7604..95bc44ec86 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -61,15 +61,10 @@ final class EntityFactory{ use SingletonTrait; /** - * @var \Closure[] base class => creator function - * @phpstan-var array, \Closure(World, CompoundTag) : Entity> + * @var \Closure[] save ID => creator function + * @phpstan-var array */ private $creationFuncs = []; - /** - * @var string[] - * @phpstan-var array> - */ - private $knownEntities = []; /** * @var string[][] * @phpstan-var array, list> @@ -198,15 +193,13 @@ final class EntityFactory{ throw new \InvalidArgumentException("At least one save name must be provided"); } Utils::testValidInstance($className, Entity::class); - self::validateCreationFunc($className, $creationFunc); - $this->creationFuncs[$className] = $creationFunc; foreach($saveNames as $name){ - $this->knownEntities[$name] = $className; + $this->creationFuncs[$name] = $creationFunc; } if($legacyMcpeSaveId !== null){ - $this->knownEntities[$legacyMcpeSaveId] = $className; + $this->creationFuncs[$legacyMcpeSaveId] = $creationFunc; } $this->saveNames[$className] = $saveNames; @@ -220,16 +213,15 @@ final class EntityFactory{ */ public function createFromData(World $world, CompoundTag $nbt) : ?Entity{ $saveId = $nbt->getTag("id") ?? $nbt->getTag("identifier"); - $baseClass = null; + $func = null; if($saveId instanceof StringTag){ - $baseClass = $this->knownEntities[$saveId->getValue()] ?? null; + $func = $this->creationFuncs[$saveId->getValue()] ?? null; }elseif($saveId instanceof IntTag){ //legacy MCPE format - $baseClass = $this->knownEntities[$saveId->getValue() & 0xff] ?? null; + $func = $this->creationFuncs[$saveId->getValue() & 0xff] ?? null; } - if($baseClass === null){ + if($func === null){ return null; } - $func = $this->creationFuncs[$baseClass]; /** @var Entity $entity */ $entity = $func($world, $nbt); From d62d0762ffa268904504b7b9d440e806c23f8230 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Jun 2020 22:59:19 +0100 Subject: [PATCH 1682/3224] item: remove some unnecessary CompoundTag usages --- src/item/Egg.php | 3 +-- src/item/EnderPearl.php | 3 +-- src/item/ExperienceBottle.php | 3 +-- src/item/Snowball.php | 3 +-- src/item/SplashPotion.php | 3 +-- 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/item/Egg.php b/src/item/Egg.php index a441f72913..afacbf5679 100644 --- a/src/item/Egg.php +++ b/src/item/Egg.php @@ -26,7 +26,6 @@ namespace pocketmine\item; use pocketmine\entity\Location; use pocketmine\entity\projectile\Egg as EggEntity; use pocketmine\entity\projectile\Throwable; -use pocketmine\nbt\tag\CompoundTag; use pocketmine\player\Player; class Egg extends ProjectileItem{ @@ -36,7 +35,7 @@ class Egg extends ProjectileItem{ } protected function createEntity(Location $location, Player $thrower) : Throwable{ - return new EggEntity($location, $thrower, new CompoundTag()); + return new EggEntity($location, $thrower); } public function getThrowForce() : float{ diff --git a/src/item/EnderPearl.php b/src/item/EnderPearl.php index 502e52f355..1cd9d9d0f4 100644 --- a/src/item/EnderPearl.php +++ b/src/item/EnderPearl.php @@ -26,7 +26,6 @@ namespace pocketmine\item; use pocketmine\entity\Location; use pocketmine\entity\projectile\EnderPearl as EnderPearlEntity; use pocketmine\entity\projectile\Throwable; -use pocketmine\nbt\tag\CompoundTag; use pocketmine\player\Player; class EnderPearl extends ProjectileItem{ @@ -36,7 +35,7 @@ class EnderPearl extends ProjectileItem{ } protected function createEntity(Location $location, Player $thrower) : Throwable{ - return new EnderPearlEntity($location, $thrower, new CompoundTag()); + return new EnderPearlEntity($location, $thrower); } public function getThrowForce() : float{ diff --git a/src/item/ExperienceBottle.php b/src/item/ExperienceBottle.php index d9de8628f4..f764971516 100644 --- a/src/item/ExperienceBottle.php +++ b/src/item/ExperienceBottle.php @@ -26,13 +26,12 @@ namespace pocketmine\item; use pocketmine\entity\Location; use pocketmine\entity\projectile\ExperienceBottle as ExperienceBottleEntity; use pocketmine\entity\projectile\Throwable; -use pocketmine\nbt\tag\CompoundTag; use pocketmine\player\Player; class ExperienceBottle extends ProjectileItem{ protected function createEntity(Location $location, Player $thrower) : Throwable{ - return new ExperienceBottleEntity($location, $thrower, new CompoundTag()); + return new ExperienceBottleEntity($location, $thrower); } public function getThrowForce() : float{ diff --git a/src/item/Snowball.php b/src/item/Snowball.php index 36ab539840..a1cb0ced69 100644 --- a/src/item/Snowball.php +++ b/src/item/Snowball.php @@ -26,7 +26,6 @@ namespace pocketmine\item; use pocketmine\entity\Location; use pocketmine\entity\projectile\Snowball as SnowballEntity; use pocketmine\entity\projectile\Throwable; -use pocketmine\nbt\tag\CompoundTag; use pocketmine\player\Player; class Snowball extends ProjectileItem{ @@ -36,7 +35,7 @@ class Snowball extends ProjectileItem{ } protected function createEntity(Location $location, Player $thrower) : Throwable{ - return new SnowballEntity($location, $thrower, new CompoundTag()); + return new SnowballEntity($location, $thrower); } public function getThrowForce() : float{ diff --git a/src/item/SplashPotion.php b/src/item/SplashPotion.php index f9662755a7..445590e281 100644 --- a/src/item/SplashPotion.php +++ b/src/item/SplashPotion.php @@ -26,7 +26,6 @@ namespace pocketmine\item; use pocketmine\entity\Location; use pocketmine\entity\projectile\SplashPotion as SplashPotionEntity; use pocketmine\entity\projectile\Throwable; -use pocketmine\nbt\tag\CompoundTag; use pocketmine\player\Player; class SplashPotion extends ProjectileItem{ @@ -36,7 +35,7 @@ class SplashPotion extends ProjectileItem{ } protected function createEntity(Location $location, Player $thrower) : Throwable{ - $projectile = new SplashPotionEntity($location, $thrower, new CompoundTag()); + $projectile = new SplashPotionEntity($location, $thrower); $projectile->setPotionId($this->meta); return $projectile; } From 62e7b0e2b17a5d36e08deebd933b90a9796eb6ee Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Jun 2020 09:31:06 +0100 Subject: [PATCH 1683/3224] (Splash)Potion: do not assume that META == potion ID it probably will be, but meta might not be accessible anymore soon. --- src/item/ItemFactory.php | 4 ++-- src/item/Potion.php | 10 +++++++++- src/item/SplashPotion.php | 10 +++++++++- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index e06094da1c..a03c3caed2 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -252,8 +252,8 @@ class ItemFactory{ } foreach(Potion::ALL as $type){ - $this->register(new Potion(ItemIds::POTION, $type, "Potion")); - $this->register(new SplashPotion(ItemIds::SPLASH_POTION, $type, "Splash Potion")); + $this->register(new Potion(ItemIds::POTION, $type, "Potion", $type)); + $this->register(new SplashPotion(ItemIds::SPLASH_POTION, $type, "Splash Potion", $type)); } foreach(TreeType::getAll() as $type){ diff --git a/src/item/Potion.php b/src/item/Potion.php index 54806da720..a8e66bc1ff 100644 --- a/src/item/Potion.php +++ b/src/item/Potion.php @@ -253,6 +253,14 @@ class Potion extends Item implements Consumable{ return []; } + /** @var int */ + private $potionId; + + public function __construct(int $id, int $variant, string $name, int $potionId){ + parent::__construct($id, $variant, $name); + $this->potionId = $potionId; + } + public function getMaxStackSize() : int{ return 1; } @@ -263,7 +271,7 @@ class Potion extends Item implements Consumable{ public function getAdditionalEffects() : array{ //TODO: check CustomPotionEffects NBT - return self::getPotionEffectsById($this->meta); + return self::getPotionEffectsById($this->potionId); } public function getResidue(){ diff --git a/src/item/SplashPotion.php b/src/item/SplashPotion.php index 445590e281..20c09aa4e4 100644 --- a/src/item/SplashPotion.php +++ b/src/item/SplashPotion.php @@ -30,13 +30,21 @@ use pocketmine\player\Player; class SplashPotion extends ProjectileItem{ + /** @var int */ + private $potionId; + + public function __construct(int $id, int $variant, string $name, int $potionId){ + parent::__construct($id, $variant, $name); + $this->potionId = $potionId; + } + public function getMaxStackSize() : int{ return 1; } protected function createEntity(Location $location, Player $thrower) : Throwable{ $projectile = new SplashPotionEntity($location, $thrower); - $projectile->setPotionId($this->meta); + $projectile->setPotionId($this->potionId); return $projectile; } From d2089afbc33ef03026490a5f325fc16b95604dba Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Jun 2020 09:52:02 +0100 Subject: [PATCH 1684/3224] ItemBlock: get rid of -1 meta check (meta is never -1 in this code path now) --- src/item/ItemBlock.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/item/ItemBlock.php b/src/item/ItemBlock.php index aa207e9249..ab79803543 100644 --- a/src/item/ItemBlock.php +++ b/src/item/ItemBlock.php @@ -50,7 +50,7 @@ class ItemBlock extends Item{ } public function getBlock() : Block{ - return BlockFactory::getInstance()->get($this->blockId, $this->meta === -1 ? 0 : $this->meta & 0xf); + return BlockFactory::getInstance()->get($this->blockId, $this->meta & 0xf); } public function getFuelTime() : int{ From d5db163208ef67028ddb9c59139c85d12a052f68 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Jun 2020 11:18:42 +0100 Subject: [PATCH 1685/3224] protocol: added proper object wrappers for gamerules --- .../mcpe/handler/PreSpawnPacketHandler.php | 4 ++ .../mcpe/protocol/GameRulesChangedPacket.php | 5 +- src/network/mcpe/protocol/StartGamePacket.php | 10 ++-- .../protocol/serializer/PacketSerializer.php | 60 +++++++------------ .../mcpe/protocol/types/BoolGameRule.php | 52 ++++++++++++++++ .../mcpe/protocol/types/FloatGameRule.php | 51 ++++++++++++++++ src/network/mcpe/protocol/types/GameRule.php | 33 ++++++++++ .../mcpe/protocol/types/IntGameRule.php | 52 ++++++++++++++++ tests/phpstan/configs/l7-baseline.neon | 15 ----- 9 files changed, 221 insertions(+), 61 deletions(-) create mode 100644 src/network/mcpe/protocol/types/BoolGameRule.php create mode 100644 src/network/mcpe/protocol/types/FloatGameRule.php create mode 100644 src/network/mcpe/protocol/types/GameRule.php create mode 100644 src/network/mcpe/protocol/types/IntGameRule.php diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index 007da0fb72..c4ee4c0229 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -29,6 +29,7 @@ use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; use pocketmine\network\mcpe\protocol\StartGamePacket; +use pocketmine\network\mcpe\protocol\types\BoolGameRule; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\StaticPacketCache; use pocketmine\player\Player; @@ -76,6 +77,9 @@ class PreSpawnPacketHandler extends PacketHandler{ $pk->rainLevel = 0; //TODO: implement these properly $pk->lightningLevel = 0; $pk->commandsEnabled = true; + $pk->gameRules = [ + "naturalregeneration" => new BoolGameRule(false) //Hack for client side regeneration + ]; $pk->levelId = ""; $pk->worldName = $this->server->getMotd(); $pk->blockTable = RuntimeBlockMapping::getInstance()->getStartGamePaletteCache(); diff --git a/src/network/mcpe/protocol/GameRulesChangedPacket.php b/src/network/mcpe/protocol/GameRulesChangedPacket.php index d9647ea896..35aa036ba8 100644 --- a/src/network/mcpe/protocol/GameRulesChangedPacket.php +++ b/src/network/mcpe/protocol/GameRulesChangedPacket.php @@ -26,13 +26,14 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; +use pocketmine\network\mcpe\protocol\types\GameRule; class GameRulesChangedPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::GAME_RULES_CHANGED_PACKET; /** - * @var mixed[][] - * @phpstan-var array + * @var GameRule[] + * @phpstan-var array */ public $gameRules = []; diff --git a/src/network/mcpe/protocol/StartGamePacket.php b/src/network/mcpe/protocol/StartGamePacket.php index 9e4911f213..809214dbb7 100644 --- a/src/network/mcpe/protocol/StartGamePacket.php +++ b/src/network/mcpe/protocol/StartGamePacket.php @@ -30,7 +30,7 @@ use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\CacheableNbt; use pocketmine\network\mcpe\protocol\types\EducationEditionOffer; -use pocketmine\network\mcpe\protocol\types\GameRuleType; +use pocketmine\network\mcpe\protocol\types\GameRule; use pocketmine\network\mcpe\protocol\types\GeneratorType; use pocketmine\network\mcpe\protocol\types\MultiplayerGameVisibility; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; @@ -97,12 +97,10 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{ /** @var bool */ public $isTexturePacksRequired = true; /** - * @var mixed[][] - * @phpstan-var array + * @var GameRule[] + * @phpstan-var array */ - public $gameRules = [ //TODO: implement this - "naturalregeneration" => [GameRuleType::BOOL, false] //Hack for client side regeneration - ]; + public $gameRules = []; /** @var bool */ public $hasBonusChestEnabled = false; /** @var bool */ diff --git a/src/network/mcpe/protocol/serializer/PacketSerializer.php b/src/network/mcpe/protocol/serializer/PacketSerializer.php index 5c40a49041..dc9bb2efe9 100644 --- a/src/network/mcpe/protocol/serializer/PacketSerializer.php +++ b/src/network/mcpe/protocol/serializer/PacketSerializer.php @@ -30,6 +30,7 @@ use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\protocol\PacketDecodeException; +use pocketmine\network\mcpe\protocol\types\BoolGameRule; use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; use pocketmine\network\mcpe\protocol\types\entity\Attribute; use pocketmine\network\mcpe\protocol\types\entity\BlockPosMetadataProperty; @@ -44,7 +45,10 @@ use pocketmine\network\mcpe\protocol\types\entity\ShortMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\StringMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\Vec3MetadataProperty; use pocketmine\network\mcpe\protocol\types\FixedItemIds; +use pocketmine\network\mcpe\protocol\types\FloatGameRule; +use pocketmine\network\mcpe\protocol\types\GameRule; use pocketmine\network\mcpe\protocol\types\GameRuleType; +use pocketmine\network\mcpe\protocol\types\IntGameRule; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\protocol\types\PersonaPieceTintColor; use pocketmine\network\mcpe\protocol\types\PersonaSkinPiece; @@ -533,12 +537,21 @@ class PacketSerializer extends BinaryStream{ $this->putByte((int) ($rotation / (360 / 256))); } + private function readGameRule(int $type) : GameRule{ + switch($type){ + case GameRuleType::BOOL: return BoolGameRule::decode($this); + case GameRuleType::INT: return IntGameRule::decode($this); + case GameRuleType::FLOAT: return FloatGameRule::decode($this); + default: + throw new PacketDecodeException("Unknown gamerule type $type"); + } + } + /** * Reads gamerules - * TODO: implement this properly * - * @return mixed[][], members are in the structure [name => [type, value]] - * @phpstan-return array + * @return GameRule[] game rule name => value + * @phpstan-return array * * @throws PacketDecodeException * @throws BinaryDataException @@ -549,53 +562,24 @@ class PacketSerializer extends BinaryStream{ for($i = 0; $i < $count; ++$i){ $name = $this->getString(); $type = $this->getUnsignedVarInt(); - $value = null; - switch($type){ - case GameRuleType::BOOL: - $value = $this->getBool(); - break; - case GameRuleType::INT: - $value = $this->getUnsignedVarInt(); - break; - case GameRuleType::FLOAT: - $value = $this->getLFloat(); - break; - default: - throw new PacketDecodeException("Unknown gamerule type $type"); - } - - $rules[$name] = [$type, $value]; + $rules[$name] = $this->readGameRule($type); } return $rules; } /** - * Writes a gamerule array, members should be in the structure [name => [type, value]] - * TODO: implement this properly + * Writes a gamerule array * - * @param mixed[][] $rules - * - * @phpstan-param array $rules + * @param GameRule[] $rules + * @phpstan-param array $rules */ public function putGameRules(array $rules) : void{ $this->putUnsignedVarInt(count($rules)); foreach($rules as $name => $rule){ $this->putString($name); - $this->putUnsignedVarInt($rule[0]); - switch($rule[0]){ - case GameRuleType::BOOL: - $this->putBool($rule[1]); - break; - case GameRuleType::INT: - $this->putUnsignedVarInt($rule[1]); - break; - case GameRuleType::FLOAT: - $this->putLFloat($rule[1]); - break; - default: - throw new \InvalidArgumentException("Invalid gamerule type " . $rule[0]); - } + $this->putUnsignedVarInt($rule->getType()); + $rule->encode($this); } } diff --git a/src/network/mcpe/protocol/types/BoolGameRule.php b/src/network/mcpe/protocol/types/BoolGameRule.php new file mode 100644 index 0000000000..c4fbe7290c --- /dev/null +++ b/src/network/mcpe/protocol/types/BoolGameRule.php @@ -0,0 +1,52 @@ +value = $value; + } + + public function getType() : int{ + return GameRuleType::BOOL; + } + + public function getValue() : bool{ + return $this->value; + } + + public function encode(PacketSerializer $out) : void{ + $out->putBool($this->value); + } + + public static function decode(PacketSerializer $in) : self{ + return new self($in->getBool()); + } +} diff --git a/src/network/mcpe/protocol/types/FloatGameRule.php b/src/network/mcpe/protocol/types/FloatGameRule.php new file mode 100644 index 0000000000..d614d36a21 --- /dev/null +++ b/src/network/mcpe/protocol/types/FloatGameRule.php @@ -0,0 +1,51 @@ +value = $value; + } + + public function getType() : int{ + return GameRuleType::FLOAT; + } + + public function getValue() : float{ + return $this->value; + } + + public function encode(PacketSerializer $out) : void{ + $out->putLFloat($this->value); + } + + public static function decode(PacketSerializer $in) : self{ + return new self($in->getLFloat()); + } +} diff --git a/src/network/mcpe/protocol/types/GameRule.php b/src/network/mcpe/protocol/types/GameRule.php new file mode 100644 index 0000000000..b578524a26 --- /dev/null +++ b/src/network/mcpe/protocol/types/GameRule.php @@ -0,0 +1,33 @@ +value = $value; + } + + public function getType() : int{ + return GameRuleType::INT; + } + + public function getValue() : int{ + return $this->value; + } + + public function encode(PacketSerializer $out) : void{ + $out->putUnsignedVarInt($this->value); + } + + public static function decode(PacketSerializer $in) : self{ + return new self($in->getUnsignedVarInt()); + } +} diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index da5dfc1504..d371e9184a 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -640,21 +640,6 @@ parameters: count: 1 path: ../../../src/network/mcpe/encryption/EncryptionUtils.php - - - message: "#^Parameter \\#1 \\$v of method pocketmine\\\\utils\\\\BinaryStream\\:\\:putBool\\(\\) expects bool, bool\\|float\\|int given\\.$#" - count: 1 - path: ../../../src/network/mcpe/protocol/serializer/PacketSerializer.php - - - - message: "#^Parameter \\#1 \\$v of method pocketmine\\\\utils\\\\BinaryStream\\:\\:putUnsignedVarInt\\(\\) expects int, bool\\|float\\|int given\\.$#" - count: 1 - path: ../../../src/network/mcpe/protocol/serializer/PacketSerializer.php - - - - message: "#^Parameter \\#1 \\$v of method pocketmine\\\\utils\\\\BinaryStream\\:\\:putLFloat\\(\\) expects float, bool\\|float\\|int given\\.$#" - count: 1 - path: ../../../src/network/mcpe/protocol/serializer/PacketSerializer.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:putSignedBlockPosition\\(\\) expects int, float\\|int given\\.$#" count: 1 From 6be56de3ed0b8a6173778be89fad1f2bb7478999 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Jun 2020 11:21:29 +0100 Subject: [PATCH 1686/3224] clean some newly fixed errors from phpstan baselines --- tests/phpstan/configs/l7-baseline.neon | 5 ----- tests/phpstan/configs/l8-baseline.neon | 17 +---------------- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index d371e9184a..d709955a45 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -605,11 +605,6 @@ parameters: count: 1 path: ../../../src/item/Item.php - - - message: "#^Parameter \\#4 \\$entityClass of class pocketmine\\\\item\\\\SpawnEgg constructor expects class\\-string\\, pocketmine\\\\entity\\\\Living\\|string given\\.$#" - count: 1 - path: ../../../src/item/ItemFactory.php - - message: "#^Parameter \\#2 \\$input1 of function array_map expects array, array\\|false given\\.$#" count: 1 diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index b8b48f9778..fff34f177b 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -155,11 +155,6 @@ parameters: count: 1 path: ../../../src/command/defaults/TimeCommand.php - - - message: "#^Cannot call method getAllValues\\(\\) on pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null\\.$#" - count: 3 - path: ../../../src/entity/Entity.php - - message: "#^Cannot call method addEntity\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" count: 1 @@ -530,11 +525,6 @@ parameters: count: 1 path: ../../../src/permission/DefaultPermissions.php - - - message: "#^Cannot call method getAllValues\\(\\) on pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - message: "#^Cannot call method getSafeSpawn\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" count: 2 @@ -550,11 +540,6 @@ parameters: count: 1 path: ../../../src/player/Player.php - - - message: "#^Parameter \\#1 \\$world of method pocketmine\\\\entity\\\\Human\\:\\:__construct\\(\\) expects pocketmine\\\\world\\\\World, pocketmine\\\\world\\\\World\\|null given\\.$#" - count: 1 - path: ../../../src/player/Player.php - - message: "#^Cannot call method syncAdventureSettings\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" count: 4 @@ -812,7 +797,7 @@ parameters: - message: "#^Cannot access property \\$details_url on pocketmine\\\\updater\\\\UpdateInfo\\|null\\.$#" - count: 2 + count: 1 path: ../../../src/updater/AutoUpdater.php - From 032dc5709072fe906fb34fd2aff2817bb028c9ef Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Jun 2020 11:29:45 +0100 Subject: [PATCH 1687/3224] phpstan recognizes the existence of parallel\bootstrap now --- tests/phpstan/configs/actual-problems.neon | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/phpstan/configs/actual-problems.neon b/tests/phpstan/configs/actual-problems.neon index 2ea03ede6b..492dce500c 100644 --- a/tests/phpstan/configs/actual-problems.neon +++ b/tests/phpstan/configs/actual-problems.neon @@ -5,11 +5,6 @@ parameters: count: 1 path: ../../../src/CrashDump.php - - - message: "#^Function parallel\\\\bootstrap not found\\.$#" - count: 1 - path: ../../../src/PocketMine.php - - message: "#^Instanceof between pocketmine\\\\plugin\\\\PluginManager and pocketmine\\\\plugin\\\\PluginManager will always evaluate to true\\.$#" count: 1 From 0784bfa2fb9fb962f3c8644526439682908d6781 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Jun 2020 11:30:14 +0100 Subject: [PATCH 1688/3224] phpstan: drop another pattern that was fixed by recent changes --- tests/phpstan/configs/runtime-type-checks.neon | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/phpstan/configs/runtime-type-checks.neon b/tests/phpstan/configs/runtime-type-checks.neon index de922a304f..608060b117 100644 --- a/tests/phpstan/configs/runtime-type-checks.neon +++ b/tests/phpstan/configs/runtime-type-checks.neon @@ -10,11 +10,6 @@ parameters: count: 2 path: ../../../src/block/tile/TileFactory.php - - - message: "#^Call to function assert\\(\\) with bool will always evaluate to true\\.$#" - count: 2 - path: ../../../src/entity/EntityFactory.php - - message: "#^Instanceof between pocketmine\\\\event\\\\RegisteredListener and pocketmine\\\\event\\\\RegisteredListener will always evaluate to true\\.$#" count: 1 From a988578ee0115fc869d92f00a9f3082e64b38647 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Jun 2020 11:43:47 +0100 Subject: [PATCH 1689/3224] protocol: move PotionType and PotionContainerChange recipes to types/recipe namespace --- src/network/mcpe/protocol/CraftingDataPacket.php | 4 ++-- .../types/{ => recipe}/PotionContainerChangeRecipe.php | 2 +- .../mcpe/protocol/types/{ => recipe}/PotionTypeRecipe.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename src/network/mcpe/protocol/types/{ => recipe}/PotionContainerChangeRecipe.php (95%) rename src/network/mcpe/protocol/types/{ => recipe}/PotionTypeRecipe.php (96%) diff --git a/src/network/mcpe/protocol/CraftingDataPacket.php b/src/network/mcpe/protocol/CraftingDataPacket.php index 335c7efe6e..393e893580 100644 --- a/src/network/mcpe/protocol/CraftingDataPacket.php +++ b/src/network/mcpe/protocol/CraftingDataPacket.php @@ -26,10 +26,10 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\PotionContainerChangeRecipe; -use pocketmine\network\mcpe\protocol\types\PotionTypeRecipe; use pocketmine\network\mcpe\protocol\types\recipe\FurnaceRecipe; use pocketmine\network\mcpe\protocol\types\recipe\MultiRecipe; +use pocketmine\network\mcpe\protocol\types\recipe\PotionContainerChangeRecipe; +use pocketmine\network\mcpe\protocol\types\recipe\PotionTypeRecipe; use pocketmine\network\mcpe\protocol\types\recipe\RecipeWithTypeId; use pocketmine\network\mcpe\protocol\types\recipe\ShapedRecipe; use pocketmine\network\mcpe\protocol\types\recipe\ShapelessRecipe; diff --git a/src/network/mcpe/protocol/types/PotionContainerChangeRecipe.php b/src/network/mcpe/protocol/types/recipe/PotionContainerChangeRecipe.php similarity index 95% rename from src/network/mcpe/protocol/types/PotionContainerChangeRecipe.php rename to src/network/mcpe/protocol/types/recipe/PotionContainerChangeRecipe.php index 16855e27ee..eb0bb65320 100644 --- a/src/network/mcpe/protocol/types/PotionContainerChangeRecipe.php +++ b/src/network/mcpe/protocol/types/recipe/PotionContainerChangeRecipe.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\recipe; class PotionContainerChangeRecipe{ /** @var int */ diff --git a/src/network/mcpe/protocol/types/PotionTypeRecipe.php b/src/network/mcpe/protocol/types/recipe/PotionTypeRecipe.php similarity index 96% rename from src/network/mcpe/protocol/types/PotionTypeRecipe.php rename to src/network/mcpe/protocol/types/recipe/PotionTypeRecipe.php index 642e156a9b..2da7bf07a0 100644 --- a/src/network/mcpe/protocol/types/PotionTypeRecipe.php +++ b/src/network/mcpe/protocol/types/recipe/PotionTypeRecipe.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\recipe; class PotionTypeRecipe{ /** @var int */ From d38c17835d0cc0771d2ddc7f37ef0b0afdda6994 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Jun 2020 13:43:31 +0100 Subject: [PATCH 1690/3224] Properly switch to string entity IDs --- src/entity/Entity.php | 5 +- src/entity/Human.php | 5 +- src/entity/Squid.php | 4 +- src/entity/Villager.php | 4 +- src/entity/Zombie.php | 4 +- src/entity/object/ExperienceOrb.php | 4 +- src/entity/object/FallingBlock.php | 4 +- src/entity/object/ItemEntity.php | 4 +- src/entity/object/Painting.php | 4 +- src/entity/object/PrimedTNT.php | 4 +- src/entity/projectile/Arrow.php | 4 +- src/entity/projectile/Egg.php | 4 +- src/entity/projectile/EnderPearl.php | 4 +- src/entity/projectile/ExperienceBottle.php | 4 +- src/entity/projectile/Snowball.php | 4 +- src/entity/projectile/SplashPotion.php | 4 +- .../mcpe/protocol/types/entity/EntityIds.php | 144 ++++++++++++++++++ src/world/sound/EntityLandSound.php | 4 +- src/world/sound/EntityLongFallSound.php | 4 +- src/world/sound/EntityShortFallSound.php | 4 +- 20 files changed, 179 insertions(+), 43 deletions(-) create mode 100644 src/network/mcpe/protocol/types/entity/EntityIds.php diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 0ec443ebec..0c367a28c3 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -28,7 +28,6 @@ namespace pocketmine\entity; use pocketmine\block\Block; use pocketmine\block\Water; -use pocketmine\data\bedrock\LegacyEntityIdToStringIdMap; use pocketmine\entity\animation\Animation; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDespawnEvent; @@ -1475,7 +1474,7 @@ abstract class Entity{ return $this->hasSpawned; } - abstract public static function getNetworkTypeId() : int; + abstract public static function getNetworkTypeId() : string; /** * Called by spawnTo() to send whatever packets needed to spawn the entity to the client. @@ -1483,7 +1482,7 @@ abstract class Entity{ protected function sendSpawnPacket(Player $player) : void{ $pk = new AddActorPacket(); $pk->entityRuntimeId = $this->getId(); - $pk->type = LegacyEntityIdToStringIdMap::getInstance()->legacyToString(static::getNetworkTypeId()); + $pk->type = static::getNetworkTypeId(); $pk->position = $this->location->asVector3(); $pk->motion = $this->getMotion(); $pk->yaw = $this->location->yaw; diff --git a/src/entity/Human.php b/src/entity/Human.php index 04c5a38e40..676b105abd 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -48,6 +48,7 @@ use pocketmine\network\mcpe\protocol\AddPlayerPacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\PlayerSkinPacket; +use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\entity\StringMetadataProperty; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; @@ -63,9 +64,7 @@ use function random_int; class Human extends Living implements ProjectileSource, InventoryHolder{ - public static function getNetworkTypeId() : int{ - return -1; //TODO: ideally we shouldn't have to specify this at all here ... - } + public static function getNetworkTypeId() : string{ return EntityIds::PLAYER; } /** @var PlayerInventory */ protected $inventory; diff --git a/src/entity/Squid.php b/src/entity/Squid.php index 209f63a8bb..b39913bfa5 100644 --- a/src/entity/Squid.php +++ b/src/entity/Squid.php @@ -29,7 +29,7 @@ use pocketmine\event\entity\EntityDamageEvent; use pocketmine\item\VanillaItems; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use function atan2; use function mt_rand; use function sqrt; @@ -37,7 +37,7 @@ use const M_PI; class Squid extends WaterAnimal{ - public static function getNetworkTypeId() : int{ return EntityLegacyIds::SQUID; } + public static function getNetworkTypeId() : string{ return EntityIds::SQUID; } public $width = 0.95; public $height = 0.95; diff --git a/src/entity/Villager.php b/src/entity/Villager.php index bdc0e33ae0..f4329ade67 100644 --- a/src/entity/Villager.php +++ b/src/entity/Villager.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; @@ -36,7 +36,7 @@ class Villager extends Living implements Ageable{ public const PROFESSION_BLACKSMITH = 3; public const PROFESSION_BUTCHER = 4; - public static function getNetworkTypeId() : int{ return EntityLegacyIds::VILLAGER; } + public static function getNetworkTypeId() : string{ return EntityIds::VILLAGER; } public $width = 0.6; public $height = 1.8; diff --git a/src/entity/Zombie.php b/src/entity/Zombie.php index 307d9d5744..91a43b11c0 100644 --- a/src/entity/Zombie.php +++ b/src/entity/Zombie.php @@ -24,12 +24,12 @@ declare(strict_types=1); namespace pocketmine\entity; use pocketmine\item\VanillaItems; -use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use function mt_rand; class Zombie extends Living{ - public static function getNetworkTypeId() : int{ return EntityLegacyIds::ZOMBIE; } + public static function getNetworkTypeId() : string{ return EntityIds::ZOMBIE; } public $width = 0.6; public $height = 1.8; diff --git a/src/entity/object/ExperienceOrb.php b/src/entity/object/ExperienceOrb.php index a58ba10343..6594369b86 100644 --- a/src/entity/object/ExperienceOrb.php +++ b/src/entity/object/ExperienceOrb.php @@ -28,7 +28,7 @@ use pocketmine\entity\Human; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ShortTag; -use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\player\Player; @@ -36,7 +36,7 @@ use function sqrt; class ExperienceOrb extends Entity{ - public static function getNetworkTypeId() : int{ return EntityLegacyIds::XP_ORB; } + public static function getNetworkTypeId() : string{ return EntityIds::XP_ORB; } public const TAG_VALUE_PC = "Value"; //short public const TAG_VALUE_PE = "experience value"; //int (WTF?) diff --git a/src/entity/object/FallingBlock.php b/src/entity/object/FallingBlock.php index a3d78e785e..0ad553ae9b 100644 --- a/src/entity/object/FallingBlock.php +++ b/src/entity/object/FallingBlock.php @@ -33,14 +33,14 @@ use pocketmine\event\entity\EntityDamageEvent; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; -use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use function abs; class FallingBlock extends Entity{ - public static function getNetworkTypeId() : int{ return EntityLegacyIds::FALLING_BLOCK; } + public static function getNetworkTypeId() : string{ return EntityIds::FALLING_BLOCK; } public $width = 0.98; public $height = 0.98; diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index 3c835c0f4a..23c32c688c 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -32,13 +32,13 @@ use pocketmine\item\Item; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\AddItemActorPacket; -use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\player\Player; use function max; class ItemEntity extends Entity{ - public static function getNetworkTypeId() : int{ return EntityLegacyIds::ITEM; } + public static function getNetworkTypeId() : string{ return EntityIds::ITEM; } public const DEFAULT_DESPAWN_DELAY = 6000; //5 minutes public const NEVER_DESPAWN = -1; diff --git a/src/entity/object/Painting.php b/src/entity/object/Painting.php index 9282199f10..8aa53f6aa8 100644 --- a/src/entity/object/Painting.php +++ b/src/entity/object/Painting.php @@ -33,14 +33,14 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\AddPaintingPacket; -use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\player\Player; use pocketmine\world\particle\DestroyBlockParticle; use pocketmine\world\World; use function ceil; class Painting extends Entity{ - public static function getNetworkTypeId() : int{ return EntityLegacyIds::PAINTING; } + public static function getNetworkTypeId() : string{ return EntityIds::PAINTING; } public const DATA_TO_FACING = [ 0 => Facing::SOUTH, diff --git a/src/entity/object/PrimedTNT.php b/src/entity/object/PrimedTNT.php index 1a22d030b4..76244509c9 100644 --- a/src/entity/object/PrimedTNT.php +++ b/src/entity/object/PrimedTNT.php @@ -28,7 +28,7 @@ use pocketmine\entity\Explosive; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\ExplosionPrimeEvent; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; @@ -38,7 +38,7 @@ use pocketmine\world\sound\IgniteSound; class PrimedTNT extends Entity implements Explosive{ - public static function getNetworkTypeId() : int{ return EntityLegacyIds::TNT; } + public static function getNetworkTypeId() : string{ return EntityIds::TNT; } public $width = 0.98; public $height = 0.98; diff --git a/src/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php index d94679747e..a5961dc2c2 100644 --- a/src/entity/projectile/Arrow.php +++ b/src/entity/projectile/Arrow.php @@ -32,7 +32,7 @@ use pocketmine\event\inventory\InventoryPickupArrowEvent; use pocketmine\item\VanillaItems; use pocketmine\math\RayTraceResult; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\player\Player; @@ -42,7 +42,7 @@ use function sqrt; class Arrow extends Projectile{ - public static function getNetworkTypeId() : int{ return EntityLegacyIds::ARROW; } + public static function getNetworkTypeId() : string{ return EntityIds::ARROW; } public const PICKUP_NONE = 0; public const PICKUP_ANY = 1; diff --git a/src/entity/projectile/Egg.php b/src/entity/projectile/Egg.php index a2ccbb41aa..c12af4731e 100644 --- a/src/entity/projectile/Egg.php +++ b/src/entity/projectile/Egg.php @@ -25,11 +25,11 @@ namespace pocketmine\entity\projectile; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\item\VanillaItems; -use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\world\particle\ItemBreakParticle; class Egg extends Throwable{ - public static function getNetworkTypeId() : int{ return EntityLegacyIds::EGG; } + public static function getNetworkTypeId() : string{ return EntityIds::EGG; } //TODO: spawn chickens on collision diff --git a/src/entity/projectile/EnderPearl.php b/src/entity/projectile/EnderPearl.php index 3789525215..2714ab81d9 100644 --- a/src/entity/projectile/EnderPearl.php +++ b/src/entity/projectile/EnderPearl.php @@ -25,12 +25,12 @@ namespace pocketmine\entity\projectile; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\ProjectileHitEvent; -use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\world\particle\EndermanTeleportParticle; use pocketmine\world\sound\EndermanTeleportSound; class EnderPearl extends Throwable{ - public static function getNetworkTypeId() : int{ return EntityLegacyIds::ENDER_PEARL; } + public static function getNetworkTypeId() : string{ return EntityIds::ENDER_PEARL; } protected function onHit(ProjectileHitEvent $event) : void{ $owner = $this->getOwningEntity(); diff --git a/src/entity/projectile/ExperienceBottle.php b/src/entity/projectile/ExperienceBottle.php index 0c787a04e0..e6c026af35 100644 --- a/src/entity/projectile/ExperienceBottle.php +++ b/src/entity/projectile/ExperienceBottle.php @@ -24,13 +24,13 @@ declare(strict_types=1); namespace pocketmine\entity\projectile; use pocketmine\event\entity\ProjectileHitEvent; -use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\world\particle\PotionSplashParticle; use pocketmine\world\sound\PotionSplashSound; use function mt_rand; class ExperienceBottle extends Throwable{ - public static function getNetworkTypeId() : int{ return EntityLegacyIds::XP_BOTTLE; } + public static function getNetworkTypeId() : string{ return EntityIds::XP_BOTTLE; } protected $gravity = 0.07; diff --git a/src/entity/projectile/Snowball.php b/src/entity/projectile/Snowball.php index b758505b6e..54c18b6e35 100644 --- a/src/entity/projectile/Snowball.php +++ b/src/entity/projectile/Snowball.php @@ -24,11 +24,11 @@ declare(strict_types=1); namespace pocketmine\entity\projectile; use pocketmine\event\entity\ProjectileHitEvent; -use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\world\particle\SnowballPoofParticle; class Snowball extends Throwable{ - public static function getNetworkTypeId() : int{ return EntityLegacyIds::SNOWBALL; } + public static function getNetworkTypeId() : string{ return EntityIds::SNOWBALL; } protected function onHit(ProjectileHitEvent $event) : void{ for($i = 0; $i < 6; ++$i){ diff --git a/src/entity/projectile/SplashPotion.php b/src/entity/projectile/SplashPotion.php index a6f2cf0b4f..f4f0c14434 100644 --- a/src/entity/projectile/SplashPotion.php +++ b/src/entity/projectile/SplashPotion.php @@ -34,7 +34,7 @@ use pocketmine\event\entity\ProjectileHitEntityEvent; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\item\Potion; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; +use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; @@ -46,7 +46,7 @@ use function sqrt; class SplashPotion extends Throwable{ - public static function getNetworkTypeId() : int{ return EntityLegacyIds::SPLASH_POTION; } + public static function getNetworkTypeId() : string{ return EntityIds::SPLASH_POTION; } protected $gravity = 0.05; protected $drag = 0.01; diff --git a/src/network/mcpe/protocol/types/entity/EntityIds.php b/src/network/mcpe/protocol/types/entity/EntityIds.php new file mode 100644 index 0000000000..22bd834900 --- /dev/null +++ b/src/network/mcpe/protocol/types/entity/EntityIds.php @@ -0,0 +1,144 @@ +blockLandedOn->getRuntimeId(), - $this->entity instanceof Player ? "minecraft:player" : LegacyEntityIdToStringIdMap::getInstance()->legacyToString($this->entity::getNetworkTypeId()) //TODO: bad hack, stuff depends on players having a -1 network ID :( + $this->entity::getNetworkTypeId() //TODO: does isBaby have any relevance here? ); } diff --git a/src/world/sound/EntityLongFallSound.php b/src/world/sound/EntityLongFallSound.php index 896cc8f0be..93378e218d 100644 --- a/src/world/sound/EntityLongFallSound.php +++ b/src/world/sound/EntityLongFallSound.php @@ -23,11 +23,9 @@ declare(strict_types=1); namespace pocketmine\world\sound; -use pocketmine\data\bedrock\LegacyEntityIdToStringIdMap; use pocketmine\entity\Entity; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; -use pocketmine\player\Player; /** * Played when an entity hits ground after falling a long distance (damage). @@ -47,7 +45,7 @@ class EntityLongFallSound implements Sound{ LevelSoundEventPacket::SOUND_FALL_BIG, $pos, -1, - $this->entity instanceof Player ? "minecraft:player" : LegacyEntityIdToStringIdMap::getInstance()->legacyToString($this->entity::getNetworkTypeId()) //TODO: bad hack, stuff depends on players having a -1 network ID :( + $this->entity::getNetworkTypeId() //TODO: is isBaby relevant here? ); } diff --git a/src/world/sound/EntityShortFallSound.php b/src/world/sound/EntityShortFallSound.php index ff1f1bbb1b..d1f096ce2e 100644 --- a/src/world/sound/EntityShortFallSound.php +++ b/src/world/sound/EntityShortFallSound.php @@ -23,11 +23,9 @@ declare(strict_types=1); namespace pocketmine\world\sound; -use pocketmine\data\bedrock\LegacyEntityIdToStringIdMap; use pocketmine\entity\Entity; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; -use pocketmine\player\Player; /** * Played when an entity hits the ground after falling a short distance. @@ -46,7 +44,7 @@ class EntityShortFallSound implements Sound{ LevelSoundEventPacket::SOUND_FALL_SMALL, $pos, -1, - $this->entity instanceof Player ? "minecraft:player" : LegacyEntityIdToStringIdMap::getInstance()->legacyToString($this->entity::getNetworkTypeId()) //TODO: bad hack, stuff depends on players having a -1 network ID :( + $this->entity::getNetworkTypeId() //TODO: does isBaby have any relevance here? ); } From 42637f97c61916dc909bbac6d43144eca750cf19 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Jun 2020 21:32:24 +0100 Subject: [PATCH 1691/3224] Liquid: eliminate some unnecessary Vector3 field mutations --- src/block/Liquid.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/block/Liquid.php b/src/block/Liquid.php index 3cf4916406..14371b3bca 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -168,7 +168,7 @@ abstract class Liquid extends Transparent{ return $this->flowVector; } - $vector = new Vector3(0, 0, 0); + $vX = $vY = $vZ = 0; $decay = $this->getEffectiveFlowDecay($this); @@ -200,20 +200,22 @@ abstract class Liquid extends Transparent{ if($blockDecay >= 0){ $realDecay = $blockDecay - ($decay - 8); - $vector->x += ($x - $this->pos->x) * $realDecay; - $vector->y += ($y - $this->pos->y) * $realDecay; - $vector->z += ($z - $this->pos->z) * $realDecay; + $vX += ($x - $this->pos->x) * $realDecay; + $vY += ($y - $this->pos->y) * $realDecay; + $vZ += ($z - $this->pos->z) * $realDecay; } continue; }else{ $realDecay = $blockDecay - $decay; - $vector->x += ($x - $this->pos->x) * $realDecay; - $vector->y += ($y - $this->pos->y) * $realDecay; - $vector->z += ($z - $this->pos->z) * $realDecay; + $vX += ($x - $this->pos->x) * $realDecay; + $vY += ($y - $this->pos->y) * $realDecay; + $vZ += ($z - $this->pos->z) * $realDecay; } } + $vector = new Vector3($vX, $vY, $vZ); + if($this->falling){ if( !$this->canFlowInto($this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1)) or From 80e150c80377741485446ce56f19039dcd139451 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Jun 2020 21:41:19 +0100 Subject: [PATCH 1692/3224] Entity: get rid of temporalVector mutation except for checkBlockCollision, these are all cold paths ... this gets us one step closer to immutable Vector3 --- src/entity/Entity.php | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 0c367a28c3..c7288db272 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -115,9 +115,6 @@ abstract class Entity{ /** @var bool */ protected $forceMovementUpdate = false; - /** @var Vector3 */ - public $temporalVector; - /** @var AxisAlignedBB */ public $boundingBox; /** @var bool */ @@ -224,8 +221,6 @@ abstract class Entity{ public function __construct(Location $location, ?CompoundTag $nbt = null){ $this->timings = Timings::getEntityTimings($this); - $this->temporalVector = new Vector3(0, 0, 0); - if($this->eyeHeight === null){ $this->eyeHeight = $this->height / 2 + 0.1; } @@ -918,7 +913,7 @@ abstract class Entity{ $x = -$xz * sin(deg2rad($this->location->yaw)); $z = $xz * cos(deg2rad($this->location->yaw)); - return $this->temporalVector->setComponents($x, $y, $z)->normalize(); + return (new Vector3($x, $y, $z))->normalize(); } public function getDirectionPlane() : Vector2{ @@ -1267,7 +1262,7 @@ abstract class Entity{ } protected function checkBlockCollision() : void{ - $vector = $this->temporalVector->setComponents(0, 0, 0); + $vector = new Vector3(0, 0, 0); foreach($this->getBlocksAround() as $block){ $block->onEntityInside($this); @@ -1423,7 +1418,7 @@ abstract class Entity{ } $pos = $ev->getTo(); - $this->setMotion($this->temporalVector->setComponents(0, 0, 0)); + $this->setMotion(new Vector3(0, 0, 0)); if($this->setPositionAndRotation($pos, $yaw ?? $this->location->yaw, $pitch ?? $this->location->pitch)){ $this->resetFallDistance(); $this->setForceMovementUpdate(); From fc7672c6bad62d84783861935f8a13eab5333e54 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Jun 2020 21:44:05 +0100 Subject: [PATCH 1693/3224] World: remove temporalVector (premature cold path optimisation again) --- src/world/World.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 1b29d812fd..90d1c6e92b 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -227,8 +227,6 @@ class World implements ChunkManager{ /** @var Position */ private $temporalPosition; - /** @var Vector3 */ - private $temporalVector; /** @var int */ private $sleepTicks = 0; @@ -369,7 +367,6 @@ class World implements ChunkManager{ $this->timings = new WorldTimings($this); $this->temporalPosition = new Position(0, 0, 0, $this); - $this->temporalVector = new Vector3(0, 0, 0); } public function getTickRateTime() : float{ @@ -1407,7 +1404,7 @@ class World implements ChunkManager{ $orb = new ExperienceOrb(Location::fromObject($pos, $this, lcg_value() * 360, 0)); $orb->setXpValue($split); - $orb->setMotion($this->temporalVector->setComponents((lcg_value() * 0.2 - 0.1) * 2, lcg_value() * 0.4, (lcg_value() * 0.2 - 0.1) * 2)); + $orb->setMotion(new Vector3((lcg_value() * 0.2 - 0.1) * 2, lcg_value() * 0.4, (lcg_value() * 0.2 - 0.1) * 2)); $orb->spawnToAll(); $orbs[] = $orb; From bf5c06f285a9353966dfba5925bebeb2256e8934 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Jun 2020 21:45:35 +0100 Subject: [PATCH 1694/3224] World: get rid of temporalPosition too (entirely unused) --- src/world/World.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 90d1c6e92b..2fa0c1e1d2 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -225,9 +225,6 @@ class World implements ChunkManager{ /** @var bool */ private $autoSave = true; - /** @var Position */ - private $temporalPosition; - /** @var int */ private $sleepTicks = 0; @@ -366,7 +363,6 @@ class World implements ChunkManager{ } $this->timings = new WorldTimings($this); - $this->temporalPosition = new Position(0, 0, 0, $this); } public function getTickRateTime() : float{ @@ -435,7 +431,6 @@ class World implements ChunkManager{ $this->provider->close(); $this->provider = null; $this->blockCache = []; - $this->temporalPosition = null; $this->closed = true; } From a16de8747e040d85011a9998a2eee8870f56a127 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Jun 2020 22:19:37 +0100 Subject: [PATCH 1695/3224] Explosion: stop using Vector3->setComponents() this kills two birds with one stone: this inlined version of the logic should be faster than the vector-abusing version. --- src/world/Explosion.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/world/Explosion.php b/src/world/Explosion.php index b75b9c7618..63760c1b8d 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -43,6 +43,7 @@ use pocketmine\world\utils\SubChunkIteratorManager; use function ceil; use function floor; use function mt_rand; +use function sqrt; class Explosion{ /** @var int */ @@ -92,7 +93,6 @@ class Explosion{ return false; } - $vector = new Vector3(0, 0, 0); $blockFactory = BlockFactory::getInstance(); $currentChunk = null; @@ -103,8 +103,10 @@ class Explosion{ for($j = 0; $j < $this->rays; ++$j){ for($k = 0; $k < $this->rays; ++$k){ if($i === 0 or $i === $mRays or $j === 0 or $j === $mRays or $k === 0 or $k === $mRays){ - $vector->setComponents($i / $mRays * 2 - 1, $j / $mRays * 2 - 1, $k / $mRays * 2 - 1); - $vector->setComponents(($vector->x / ($len = $vector->length())) * $this->stepLen, ($vector->y / $len) * $this->stepLen, ($vector->z / $len) * $this->stepLen); + //this could be written as new Vector3(...)->normalize()->multiply(stepLen), but we're avoiding Vector3 for performance here + [$shiftX, $shiftY, $shiftZ] = [$i / $mRays * 2 - 1, $j / $mRays * 2 - 1, $k / $mRays * 2 - 1]; + $len = sqrt($shiftX ** 2 + $shiftY ** 2 + $shiftZ ** 2); + [$shiftX, $shiftY, $shiftZ] = [($shiftX / $len) * $this->stepLen, ($shiftY / $len) * $this->stepLen, ($shiftZ / $len) * $this->stepLen]; $pointerX = $this->source->x; $pointerY = $this->source->y; $pointerZ = $this->source->z; @@ -117,9 +119,9 @@ class Explosion{ $vBlockY = $pointerY >= $y ? $y : $y - 1; $vBlockZ = $pointerZ >= $z ? $z : $z - 1; - $pointerX += $vector->x; - $pointerY += $vector->y; - $pointerZ += $vector->z; + $pointerX += $shiftX; + $pointerY += $shiftY; + $pointerZ += $shiftZ; if(!$this->subChunkHandler->moveTo($vBlockX, $vBlockY, $vBlockZ, false)){ continue; From 1ef6e5e17b072ccfd3e731a2bb25e57d2865fd71 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 21 Jun 2020 00:47:02 +0100 Subject: [PATCH 1696/3224] TileFactory now only manages loading tiles from NBT, not direct creation my objective is to make this use proper constructors like entities, but there's a couple of obstacles to get around first. --- src/block/Block.php | 7 ++++- src/block/tile/TileFactory.php | 52 ---------------------------------- 2 files changed, 6 insertions(+), 53 deletions(-) diff --git a/src/block/Block.php b/src/block/Block.php index b2fda913d3..c6cb3ed995 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -163,7 +163,12 @@ class Block{ } } if($oldTile === null and $tileType !== null){ - $this->pos->getWorldNonNull()->addTile(TileFactory::getInstance()->create($tileType, $this->pos->getWorldNonNull(), $this->pos->asVector3())); + /** + * @var Tile $tile + * @see Tile::__construct() + */ + $tile = new $tileType($this->pos->getWorldNonNull(), $this->pos->asVector3()); + $this->pos->getWorldNonNull()->addTile($tile); } } diff --git a/src/block/tile/TileFactory.php b/src/block/tile/TileFactory.php index 19f4fcb2ae..3036d30798 100644 --- a/src/block/tile/TileFactory.php +++ b/src/block/tile/TileFactory.php @@ -46,11 +46,6 @@ final class TileFactory{ * @phpstan-var array, list> */ private $saveNames = []; - /** - * @var string[] base class => overridden class - * @phpstan-var array, class-string> - */ - private $classMapping = []; public function __construct(){ $this->register(Banner::class, ["Banner", "minecraft:banner"]); @@ -102,8 +97,6 @@ final class TileFactory{ public function register(string $className, array $saveNames = []) : void{ Utils::testValidInstance($className, Tile::class); - $this->classMapping[$className] = $className; - $shortName = (new \ReflectionClass($className))->getShortName(); if(!in_array($shortName, $saveNames, true)){ $saveNames[] = $shortName; @@ -116,51 +109,6 @@ final class TileFactory{ $this->saveNames[$className] = $saveNames; } - /** - * @param string $baseClass Already-registered tile class to override - * @param string $newClass Class which extends the base class - * - * TODO: use an explicit template for param1 - * @phpstan-param class-string $baseClass - * @phpstan-param class-string $newClass - * - * @throws \InvalidArgumentException if the base class is not a registered tile - */ - public function override(string $baseClass, string $newClass) : void{ - if(!isset($this->classMapping[$baseClass])){ - throw new \InvalidArgumentException("Class $baseClass is not a registered tile"); - } - - Utils::testValidInstance($newClass, $baseClass); - $this->classMapping[$baseClass] = $newClass; - } - - /** - * @phpstan-template TTile of Tile - * @phpstan-param class-string $baseClass - * - * @return Tile (will be an instanceof $baseClass) - * @phpstan-return TTile - * - * @throws \InvalidArgumentException if the specified class is not a registered tile - */ - public function create(string $baseClass, World $world, Vector3 $pos) : Tile{ - if(isset($this->classMapping[$baseClass])){ - $class = $this->classMapping[$baseClass]; - assert(is_a($class, $baseClass, true)); - /** - * @var Tile $tile - * @phpstan-var TTile $tile - * @see Tile::__construct() - */ - $tile = new $class($world, $pos); - - return $tile; - } - - throw new \InvalidArgumentException("Class $baseClass is not a registered tile"); - } - /** * @internal */ From a920baa2957fa6cca3391ed875c3bb5489ac9473 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 21 Jun 2020 18:47:27 +0100 Subject: [PATCH 1697/3224] resource packs: use JsonMapper for manifest parsing --- src/resourcepacks/ZippedResourcePack.php | 32 ++++------- src/resourcepacks/json/Manifest.php | 46 ++++++++++++++++ src/resourcepacks/json/ManifestHeader.php | 54 +++++++++++++++++++ .../json/ManifestModuleEntry.php | 51 ++++++++++++++++++ 4 files changed, 162 insertions(+), 21 deletions(-) create mode 100644 src/resourcepacks/json/Manifest.php create mode 100644 src/resourcepacks/json/ManifestHeader.php create mode 100644 src/resourcepacks/json/ManifestModuleEntry.php diff --git a/src/resourcepacks/ZippedResourcePack.php b/src/resourcepacks/ZippedResourcePack.php index 89b9a97a77..c9acd2a272 100644 --- a/src/resourcepacks/ZippedResourcePack.php +++ b/src/resourcepacks/ZippedResourcePack.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\resourcepacks; use Ahc\Json\Comment as CommentedJsonDecoder; +use pocketmine\resourcepacks\json\Manifest; use function assert; -use function count; use function fclose; use function feof; use function file_exists; @@ -41,28 +41,10 @@ use function strlen; class ZippedResourcePack implements ResourcePack{ - /** - * Performs basic validation checks on a resource pack's manifest.json. - * TODO: add more manifest validation - */ - public static function verifyManifest(\stdClass $manifest) : bool{ - if(!isset($manifest->format_version) or !isset($manifest->header) or !isset($manifest->modules)){ - return false; - } - - //Right now we don't care about anything else, only the stuff we're sending to clients. - return - isset($manifest->header->description) and - isset($manifest->header->name) and - isset($manifest->header->uuid) and - isset($manifest->header->version) and - count($manifest->header->version) === 3; - } - /** @var string */ protected $path; - /** @var \stdClass */ + /** @var Manifest */ protected $manifest; /** @var string|null */ @@ -121,7 +103,15 @@ class ZippedResourcePack implements ResourcePack{ if(!($manifest instanceof \stdClass)){ throw new ResourcePackException("manifest.json should contain a JSON object, not " . gettype($manifest)); } - if(!self::verifyManifest($manifest)){ + + $mapper = new \JsonMapper(); + $mapper->bExceptionOnUndefinedProperty = true; + $mapper->bExceptionOnMissingData = true; + + try{ + /** @var Manifest $manifest */ + $manifest = $mapper->map($manifest, new Manifest()); + }catch(\JsonMapper_Exception $e){ throw new ResourcePackException("manifest.json is missing required fields"); } diff --git a/src/resourcepacks/json/Manifest.php b/src/resourcepacks/json/Manifest.php new file mode 100644 index 0000000000..dee929a804 --- /dev/null +++ b/src/resourcepacks/json/Manifest.php @@ -0,0 +1,46 @@ + Date: Sun, 21 Jun 2020 23:19:15 +0100 Subject: [PATCH 1698/3224] Resource packs: modules field is required in manifest.json --- src/resourcepacks/json/Manifest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/resourcepacks/json/Manifest.php b/src/resourcepacks/json/Manifest.php index dee929a804..dbc87bd381 100644 --- a/src/resourcepacks/json/Manifest.php +++ b/src/resourcepacks/json/Manifest.php @@ -41,6 +41,7 @@ final class Manifest{ /** * @var ManifestModuleEntry[] + * @required */ public $modules; } From 137605ab8cf6340c491366c7472e90ff6e78693e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 22 Jun 2020 14:15:27 +0100 Subject: [PATCH 1699/3224] Position: make World constructor parameter required --- src/world/Position.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/Position.php b/src/world/Position.php index 3642d8d3cd..c670da0861 100644 --- a/src/world/Position.php +++ b/src/world/Position.php @@ -37,7 +37,7 @@ class Position extends Vector3{ * @param float|int $y * @param float|int $z */ - public function __construct($x, $y, $z, ?World $world = null){ + public function __construct($x, $y, $z, ?World $world){ parent::__construct($x, $y, $z); if($world !== null and $world->isClosed()){ throw new \InvalidArgumentException("Specified world has been unloaded and cannot be used"); From 5c3d39f4e23b47bb95aabf988c2c8e5a7de4195b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 22 Jun 2020 19:56:00 +0100 Subject: [PATCH 1700/3224] phpstan: clean out some level 8 error patterns that no longer apply --- tests/phpstan/configs/l8-baseline.neon | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index fff34f177b..7be98450ca 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -160,11 +160,6 @@ parameters: count: 1 path: ../../../src/entity/Entity.php - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\AddActorPacket\\:\\:\\$type \\(string\\) does not accept string\\|null\\.$#" - count: 1 - path: ../../../src/entity/Entity.php - - message: "#^Parameter \\#1 \\$attribute of method pocketmine\\\\entity\\\\AttributeMap\\:\\:add\\(\\) expects pocketmine\\\\entity\\\\Attribute, pocketmine\\\\entity\\\\Attribute\\|null given\\.$#" count: 1 @@ -1205,21 +1200,6 @@ parameters: count: 1 path: ../../../src/world/light/SkyLightUpdate.php - - - message: "#^Parameter \\#4 \\$entityType of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\LevelSoundEventPacket\\:\\:create\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: ../../../src/world/sound/EntityLandSound.php - - - - message: "#^Parameter \\#4 \\$entityType of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\LevelSoundEventPacket\\:\\:create\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: ../../../src/world/sound/EntityLongFallSound.php - - - - message: "#^Parameter \\#4 \\$entityType of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\LevelSoundEventPacket\\:\\:create\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: ../../../src/world/sound/EntityShortFallSound.php - - message: "#^Property pocketmine\\\\event\\\\HandlerListManagerTest\\:\\:\\$isValidFunc \\(Closure\\) does not accept Closure\\|null\\.$#" count: 1 From 097fc7e6cb2009c38d245302a01a85775799d380 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 22 Jun 2020 19:59:57 +0100 Subject: [PATCH 1701/3224] phpstan: clean out some more dead error patterns --- tests/phpstan/configs/gc-hacks.neon | 5 ----- tests/phpstan/configs/runtime-type-checks.neon | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/phpstan/configs/gc-hacks.neon b/tests/phpstan/configs/gc-hacks.neon index d5814ad90f..1923857181 100644 --- a/tests/phpstan/configs/gc-hacks.neon +++ b/tests/phpstan/configs/gc-hacks.neon @@ -80,8 +80,3 @@ parameters: count: 1 path: ../../../src/world/World.php - - - message: "#^Property pocketmine\\\\world\\\\World\\:\\:\\$temporalPosition \\(pocketmine\\\\world\\\\Position\\) does not accept null\\.$#" - count: 1 - path: ../../../src/world/World.php - diff --git a/tests/phpstan/configs/runtime-type-checks.neon b/tests/phpstan/configs/runtime-type-checks.neon index 608060b117..dc7695d48b 100644 --- a/tests/phpstan/configs/runtime-type-checks.neon +++ b/tests/phpstan/configs/runtime-type-checks.neon @@ -7,7 +7,7 @@ parameters: - message: "#^Call to function assert\\(\\) with bool will always evaluate to true\\.$#" - count: 2 + count: 1 path: ../../../src/block/tile/TileFactory.php - From 52fd1a8c1d86b54d53cceb99ec07892130ca136b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 22 Jun 2020 20:05:23 +0100 Subject: [PATCH 1702/3224] CommandSender: export getLanguage() this currently serves as a proxy to the server main language, but it can be used by third party implementations to choose a non-Server language. --- src/Server.php | 2 +- src/command/Command.php | 4 ++-- src/command/CommandSender.php | 3 +++ src/command/ConsoleCommandSender.php | 9 +++++++-- src/command/SimpleCommandMap.php | 2 +- src/command/defaults/KillCommand.php | 4 ++-- src/command/defaults/TimeCommand.php | 12 ++++++------ src/command/defaults/WhitelistCommand.php | 2 +- src/network/mcpe/NetworkSession.php | 2 +- src/player/Player.php | 13 +++++++++---- 10 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/Server.php b/src/Server.php index 02c3da5972..89b06da5c8 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1290,7 +1290,7 @@ class Server{ return true; } - $sender->sendMessage($this->getLanguage()->translateString(TextFormat::RED . "%commands.generic.notFound")); + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.notFound")); return false; } diff --git a/src/command/Command.php b/src/command/Command.php index 4e8f93ecaf..86c43e4bbd 100644 --- a/src/command/Command.php +++ b/src/command/Command.php @@ -108,7 +108,7 @@ abstract class Command{ } if($this->permissionMessage === null){ - $target->sendMessage($target->getServer()->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + $target->sendMessage($target->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); }elseif($this->permissionMessage !== ""){ $target->sendMessage(str_replace("", $this->permission, $this->permissionMessage)); } @@ -229,7 +229,7 @@ abstract class Command{ public static function broadcastCommandMessage(CommandSender $source, $message, bool $sendToSource = true) : void{ $users = PermissionManager::getInstance()->getPermissionSubscriptions(Server::BROADCAST_CHANNEL_ADMINISTRATIVE); if($message instanceof TranslationContainer){ - $formatted = "[" . $source->getName() . ": " . ($source->getServer()->getLanguage()->get($message->getText()) !== $message->getText() ? "%" : "") . $message->getText() . "]"; + $formatted = "[" . $source->getName() . ": " . ($source->getLanguage()->get($message->getText()) !== $message->getText() ? "%" : "") . $message->getText() . "]"; $result = new TranslationContainer($formatted, $message->getParameters()); $colored = new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . $formatted, $message->getParameters()); diff --git a/src/command/CommandSender.php b/src/command/CommandSender.php index 9d2f38cf74..3c19565fed 100644 --- a/src/command/CommandSender.php +++ b/src/command/CommandSender.php @@ -23,12 +23,15 @@ declare(strict_types=1); namespace pocketmine\command; +use pocketmine\lang\Language; use pocketmine\lang\TranslationContainer; use pocketmine\permission\Permissible; use pocketmine\Server; interface CommandSender extends Permissible{ + public function getLanguage() : Language; + /** * @param TranslationContainer|string $message */ diff --git a/src/command/ConsoleCommandSender.php b/src/command/ConsoleCommandSender.php index f4dbf2264e..df79777162 100644 --- a/src/command/ConsoleCommandSender.php +++ b/src/command/ConsoleCommandSender.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\command; +use pocketmine\lang\Language; use pocketmine\lang\TranslationContainer; use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissibleDelegateTrait; @@ -48,15 +49,19 @@ class ConsoleCommandSender implements CommandSender{ return $this->server; } + public function getLanguage() : Language{ + return $this->server->getLanguage(); + } + /** * @param TranslationContainer|string $message */ public function sendMessage($message) : void{ $server = $this->getServer(); if($message instanceof TranslationContainer){ - $message = $server->getLanguage()->translate($message); + $message = $this->getLanguage()->translate($message); }else{ - $message = $server->getLanguage()->translateString($message); + $message = $this->getLanguage()->translateString($message); } foreach(explode("\n", trim($message)) as $line){ diff --git a/src/command/SimpleCommandMap.php b/src/command/SimpleCommandMap.php index 2ee001b1a8..2f850b146b 100644 --- a/src/command/SimpleCommandMap.php +++ b/src/command/SimpleCommandMap.php @@ -243,7 +243,7 @@ class SimpleCommandMap implements CommandMap{ try{ $target->execute($sender, $sentCommandLabel, $args); }catch(InvalidCommandSyntaxException $e){ - $sender->sendMessage($this->server->getLanguage()->translateString("commands.generic.usage", [$target->getUsage()])); + $sender->sendMessage($sender->getLanguage()->translateString("commands.generic.usage", [$target->getUsage()])); }finally{ $target->timings->stopTiming(); } diff --git a/src/command/defaults/KillCommand.php b/src/command/defaults/KillCommand.php index ee5ed3ecfe..16a6e8e42a 100644 --- a/src/command/defaults/KillCommand.php +++ b/src/command/defaults/KillCommand.php @@ -55,7 +55,7 @@ class KillCommand extends VanillaCommand{ if(count($args) === 1){ if(!$sender->hasPermission("pocketmine.command.kill.other")){ - $sender->sendMessage($sender->getServer()->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); return true; } @@ -74,7 +74,7 @@ class KillCommand extends VanillaCommand{ if($sender instanceof Player){ if(!$sender->hasPermission("pocketmine.command.kill.self")){ - $sender->sendMessage($sender->getServer()->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); return true; } diff --git a/src/command/defaults/TimeCommand.php b/src/command/defaults/TimeCommand.php index 7fea174388..f98fdee5e6 100644 --- a/src/command/defaults/TimeCommand.php +++ b/src/command/defaults/TimeCommand.php @@ -50,7 +50,7 @@ class TimeCommand extends VanillaCommand{ if($args[0] === "start"){ if(!$sender->hasPermission("pocketmine.command.time.start")){ - $sender->sendMessage($sender->getServer()->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); return true; } @@ -61,7 +61,7 @@ class TimeCommand extends VanillaCommand{ return true; }elseif($args[0] === "stop"){ if(!$sender->hasPermission("pocketmine.command.time.stop")){ - $sender->sendMessage($sender->getServer()->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); return true; } @@ -72,7 +72,7 @@ class TimeCommand extends VanillaCommand{ return true; }elseif($args[0] === "query"){ if(!$sender->hasPermission("pocketmine.command.time.query")){ - $sender->sendMessage($sender->getServer()->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); return true; } @@ -81,7 +81,7 @@ class TimeCommand extends VanillaCommand{ }else{ $world = $sender->getServer()->getWorldManager()->getDefaultWorld(); } - $sender->sendMessage($sender->getServer()->getLanguage()->translateString("commands.time.query", [$world->getTime()])); + $sender->sendMessage($sender->getLanguage()->translateString("commands.time.query", [$world->getTime()])); return true; } @@ -91,7 +91,7 @@ class TimeCommand extends VanillaCommand{ if($args[0] === "set"){ if(!$sender->hasPermission("pocketmine.command.time.set")){ - $sender->sendMessage($sender->getServer()->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); return true; } @@ -126,7 +126,7 @@ class TimeCommand extends VanillaCommand{ Command::broadcastCommandMessage($sender, new TranslationContainer("commands.time.set", [$value])); }elseif($args[0] === "add"){ if(!$sender->hasPermission("pocketmine.command.time.add")){ - $sender->sendMessage($sender->getServer()->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); return true; } diff --git a/src/command/defaults/WhitelistCommand.php b/src/command/defaults/WhitelistCommand.php index 622f69bde0..aeea227f82 100644 --- a/src/command/defaults/WhitelistCommand.php +++ b/src/command/defaults/WhitelistCommand.php @@ -117,7 +117,7 @@ class WhitelistCommand extends VanillaCommand{ "off" => "disable" ]; if(!$sender->hasPermission("pocketmine.command.whitelist." . ($map[$subcommand] ?? $subcommand))){ - $sender->sendMessage($sender->getServer()->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); return true; } diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 43f555bda8..cd057666fa 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -768,7 +768,7 @@ class NetworkSession{ $data = new CommandData( $lname, //TODO: commands containing uppercase letters in the name crash 1.9.0 client - $this->server->getLanguage()->translateString($command->getDescription()), + $this->player->getLanguage()->translateString($command->getDescription()), 0, 0, $aliasObj, diff --git a/src/player/Player.php b/src/player/Player.php index a0a76d0951..074aac2553 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -78,6 +78,7 @@ use pocketmine\item\enchantment\EnchantmentInstance; use pocketmine\item\enchantment\MeleeWeaponEnchantment; use pocketmine\item\Item; use pocketmine\item\ItemUseResult; +use pocketmine\lang\Language; use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; @@ -634,6 +635,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->locale; } + public function getLanguage() : Language{ + return $this->server->getLanguage(); + } + /** * Called when a player changes their skin. * Plugin developers should not use this, use setSkin() and sendSkin() instead. @@ -1859,7 +1864,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return; } - $this->networkSession->onRawChatMessage($this->server->getLanguage()->translateString($message)); + $this->networkSession->onRawChatMessage($this->getLanguage()->translateString($message)); } /** @@ -1868,11 +1873,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, public function sendTranslation(string $message, array $parameters = []) : void{ if(!$this->server->isLanguageForced()){ foreach($parameters as $i => $p){ - $parameters[$i] = $this->server->getLanguage()->translateString($p, [], "pocketmine."); + $parameters[$i] = $this->getLanguage()->translateString($p, [], "pocketmine."); } - $this->networkSession->onTranslatedChatMessage($this->server->getLanguage()->translateString($message, $parameters, "pocketmine."), $parameters); + $this->networkSession->onTranslatedChatMessage($this->getLanguage()->translateString($message, $parameters, "pocketmine."), $parameters); }else{ - $this->sendMessage($this->server->getLanguage()->translateString($message, $parameters)); + $this->sendMessage($this->getLanguage()->translateString($message, $parameters)); } } From d8a8f5b77a3afe5d52298b16aeb1dbd020ef109c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Jun 2020 13:54:30 +0100 Subject: [PATCH 1703/3224] phpstan: ignore a new error caused by 52fd1a8c1d86b54d53cceb99ec07892130ca136b --- tests/phpstan/configs/l8-baseline.neon | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 7be98450ca..670f93a9b4 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -415,6 +415,11 @@ parameters: count: 1 path: ../../../src/network/mcpe/NetworkSession.php + - + message: "#^Cannot call method getLanguage\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + - message: "#^Cannot call method getLocation\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" count: 2 From 9f323bc48022b457efee1c27a7b8356fc34e1938 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Jun 2020 22:25:09 +0100 Subject: [PATCH 1704/3224] phpstorm, stop messing with my code pls --- src/network/mcpe/handler/InGamePacketHandler.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 9bd0c9996d..26ba21a967 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -752,8 +752,7 @@ class InGamePacketHandler extends PacketHandler{ $inQuotes = true; }else{ $backslashes = 0; - for(; $backslashes < $i && $raw[$i - $backslashes - 1] === "\\"; ++$backslashes){ - } + for(; $backslashes < $i && $raw[$i - $backslashes - 1] === "\\"; ++$backslashes){} if(($backslashes % 2) === 0){ //unescaped quote $inQuotes = false; } From 45b4e3cd7a407335e7187e0e5a6dabaf63bd836d Mon Sep 17 00:00:00 2001 From: alvin0319 Date: Sat, 27 Jun 2020 18:04:23 +0900 Subject: [PATCH 1705/3224] EmoteListPacket can be ServerboundPacket (#3635) --- src/network/mcpe/protocol/EmoteListPacket.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/protocol/EmoteListPacket.php b/src/network/mcpe/protocol/EmoteListPacket.php index 1072611273..1847d92118 100644 --- a/src/network/mcpe/protocol/EmoteListPacket.php +++ b/src/network/mcpe/protocol/EmoteListPacket.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\uuid\UUID; use function count; -class EmoteListPacket extends DataPacket implements ClientboundPacket{ +class EmoteListPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::EMOTE_LIST_PACKET; /** @var int */ From f039a077cd02fd3020c92a92e597078c9293afa8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Jun 2020 00:46:53 +0100 Subject: [PATCH 1706/3224] ItemFrame: fixed a phpstan level 8 error --- src/block/ItemFrame.php | 2 +- tests/phpstan/configs/l8-baseline.neon | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/block/ItemFrame.php b/src/block/ItemFrame.php index 625a5c3880..621e322508 100644 --- a/src/block/ItemFrame.php +++ b/src/block/ItemFrame.php @@ -142,7 +142,7 @@ class ItemFrame extends Flowable{ return false; } if(lcg_value() <= $this->itemDropChance){ - $this->pos->getWorldNonNull()->dropItem($this->pos->add(0.5, 0.5, 0.5), $this->getFramedItem()); + $this->pos->getWorldNonNull()->dropItem($this->pos->add(0.5, 0.5, 0.5), clone $this->framedItem); } $this->setFramedItem(null); $this->pos->getWorldNonNull()->setBlock($this->pos, $this); diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 9dc31452c3..5591073842 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -20,11 +20,6 @@ parameters: count: 1 path: ../../../src/block/Block.php - - - message: "#^Parameter \\#2 \\$item of method pocketmine\\\\world\\\\World\\:\\:dropItem\\(\\) expects pocketmine\\\\item\\\\Item, pocketmine\\\\item\\\\Item\\|null given\\.$#" - count: 1 - path: ../../../src/block/ItemFrame.php - - message: "#^Parameter \\#2 \\$value of method pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\:\\:setInt\\(\\) expects int, int\\|null given\\.$#" count: 4 From 9484220bd5af8ac6837803c11b0dcc83e860ca75 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Jun 2020 01:00:25 +0100 Subject: [PATCH 1707/3224] ContainerTrait: use a static-analysis-friendly way to read NBT, fixes 4 phpstan level 8 errors --- src/block/tile/ContainerTrait.php | 4 +--- tests/phpstan/configs/l8-baseline.neon | 20 -------------------- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/src/block/tile/ContainerTrait.php b/src/block/tile/ContainerTrait.php index f76944a6ad..b23c944eb3 100644 --- a/src/block/tile/ContainerTrait.php +++ b/src/block/tile/ContainerTrait.php @@ -44,9 +44,7 @@ trait ContainerTrait{ abstract public function getRealInventory(); protected function loadItems(CompoundTag $tag) : void{ - if($tag->hasTag(Container::TAG_ITEMS, ListTag::class)){ - $inventoryTag = $tag->getListTag(Container::TAG_ITEMS); - + if(($inventoryTag = $tag->getTag(Container::TAG_ITEMS)) instanceof ListTag){ $inventory = $this->getRealInventory(); $listeners = $inventory->getListeners()->toArray(); $inventory->getListeners()->remove(...$listeners); //prevent any events being fired by initialization diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 5591073842..da9f714777 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -45,26 +45,6 @@ parameters: count: 1 path: ../../../src/block/tile/Chest.php - - - message: "#^Argument of an invalid type pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null supplied for foreach, only iterables are supported\\.$#" - count: 1 - path: ../../../src/block/tile/Chest.php - - - - message: "#^Argument of an invalid type pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null supplied for foreach, only iterables are supported\\.$#" - count: 1 - path: ../../../src/block/tile/BrewingStand.php - - - - message: "#^Argument of an invalid type pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null supplied for foreach, only iterables are supported\\.$#" - count: 1 - path: ../../../src/block/tile/Furnace.php - - - - message: "#^Argument of an invalid type pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null supplied for foreach, only iterables are supported\\.$#" - count: 1 - path: ../../../src/block/tile/Hopper.php - - message: "#^Parameter \\#1 \\$nbt of method pocketmine\\\\block\\\\tile\\\\Tile\\:\\:readSaveData\\(\\) expects pocketmine\\\\nbt\\\\tag\\\\CompoundTag, pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null given\\.$#" count: 1 From 7e391a812348f93f4cc9b89a18226c7b7f51a25e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Jun 2020 01:03:20 +0100 Subject: [PATCH 1708/3224] Tile: use phpstan-friendly way to pass block NBT fixes 1 level 8 error --- src/block/tile/Tile.php | 4 ++-- tests/phpstan/configs/l8-baseline.neon | 5 ----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/block/tile/Tile.php b/src/block/tile/Tile.php index 4afcd3f23e..5fb12b184a 100644 --- a/src/block/tile/Tile.php +++ b/src/block/tile/Tile.php @@ -89,8 +89,8 @@ abstract class Tile{ * @throws \RuntimeException */ public function copyDataFromItem(Item $item) : void{ - if($item->hasCustomBlockData()){ //TODO: check item root tag (MCPE doesn't use BlockEntityTag) - $this->readSaveData($item->getCustomBlockData()); + if(($blockNbt = $item->getCustomBlockData()) !== null){ //TODO: check item root tag (MCPE doesn't use BlockEntityTag) + $this->readSaveData($blockNbt); } } diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index da9f714777..1d158dd678 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -45,11 +45,6 @@ parameters: count: 1 path: ../../../src/block/tile/Chest.php - - - message: "#^Parameter \\#1 \\$nbt of method pocketmine\\\\block\\\\tile\\\\Tile\\:\\:readSaveData\\(\\) expects pocketmine\\\\nbt\\\\tag\\\\CompoundTag, pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null given\\.$#" - count: 1 - path: ../../../src/block/tile/Tile.php - - message: "#^Parameter \\#2 \\$replace of function str_replace expects array\\|string, string\\|null given\\.$#" count: 1 From 3c1b8b83f5b5323fb80ebdcb493151203c4a38ca Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Jun 2020 01:20:03 +0100 Subject: [PATCH 1709/3224] HungerManager: use AttributeMap->mustGet() fixes 2 errors on phpstan level 8 --- src/entity/HungerManager.php | 2 +- tests/phpstan/configs/l8-baseline.neon | 10 ---------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/entity/HungerManager.php b/src/entity/HungerManager.php index 77eb87d113..f0e0e9d8e0 100644 --- a/src/entity/HungerManager.php +++ b/src/entity/HungerManager.php @@ -57,7 +57,7 @@ class HungerManager{ } private static function fetchAttribute(Entity $entity, string $attributeId) : Attribute{ - $attribute = AttributeFactory::getInstance()->get($attributeId); + $attribute = AttributeFactory::getInstance()->mustGet($attributeId); $entity->getAttributeMap()->add($attribute); return $attribute; } diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 1d158dd678..d7379254a9 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -130,16 +130,6 @@ parameters: count: 1 path: ../../../src/entity/Entity.php - - - message: "#^Parameter \\#1 \\$attribute of method pocketmine\\\\entity\\\\AttributeMap\\:\\:add\\(\\) expects pocketmine\\\\entity\\\\Attribute, pocketmine\\\\entity\\\\Attribute\\|null given\\.$#" - count: 1 - path: ../../../src/entity/HungerManager.php - - - - message: "#^Method pocketmine\\\\entity\\\\HungerManager\\:\\:fetchAttribute\\(\\) should return pocketmine\\\\entity\\\\Attribute but returns pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 1 - path: ../../../src/entity/HungerManager.php - - message: "#^Cannot call method getEffectLevel\\(\\) on pocketmine\\\\entity\\\\effect\\\\EffectInstance\\|null\\.$#" count: 3 From b7b5ea6fc9696e13878f34cea125198e01060e78 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Jun 2020 12:12:09 +0100 Subject: [PATCH 1710/3224] Painting: use motive directly internally this is cleaner and also fixes a phpstan level 8 error --- src/entity/object/Painting.php | 10 +++++----- tests/phpstan/configs/l8-baseline.neon | 5 ----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/entity/object/Painting.php b/src/entity/object/Painting.php index 8aa53f6aa8..3ccb6b1002 100644 --- a/src/entity/object/Painting.php +++ b/src/entity/object/Painting.php @@ -70,11 +70,11 @@ class Painting extends Entity{ protected $blockIn; /** @var int */ protected $facing = Facing::NORTH; - /** @var string */ + /** @var PaintingMotive */ protected $motive; public function __construct(Location $location, Vector3 $blockIn, int $facing, PaintingMotive $motive, ?CompoundTag $nbt = null){ - $this->motive = $motive->getName(); //TODO: use motive directly + $this->motive = $motive; $this->blockIn = $blockIn->asVector3(); $this->facing = $facing; parent::__construct($location, $nbt); @@ -95,7 +95,7 @@ class Painting extends Entity{ $nbt->setByte("Facing", self::FACING_TO_DATA[$this->facing]); $nbt->setByte("Direction", self::FACING_TO_DATA[$this->facing]); //Save both for full compatibility - $nbt->setString("Motive", $this->motive); + $nbt->setString("Motive", $this->motive->getName()); return $nbt; } @@ -153,7 +153,7 @@ class Painting extends Entity{ ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2 ); $pk->direction = self::FACING_TO_DATA[$this->facing]; - $pk->title = $this->motive; + $pk->title = $this->motive->getName(); $player->getNetworkSession()->sendDataPacket($pk); } @@ -162,7 +162,7 @@ class Painting extends Entity{ * Returns the painting motive (which image is displayed on the painting) */ public function getMotive() : PaintingMotive{ - return PaintingMotive::getMotiveByName($this->motive); + return $this->motive; } public function getFacing() : int{ diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index d7379254a9..f25a714931 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -145,11 +145,6 @@ parameters: count: 1 path: ../../../src/entity/Living.php - - - message: "#^Method pocketmine\\\\entity\\\\object\\\\Painting\\:\\:getMotive\\(\\) should return pocketmine\\\\entity\\\\object\\\\PaintingMotive but returns pocketmine\\\\entity\\\\object\\\\PaintingMotive\\|null\\.$#" - count: 1 - path: ../../../src/entity/object/Painting.php - - message: "#^Cannot call method getEffectLevel\\(\\) on pocketmine\\\\entity\\\\effect\\\\EffectInstance\\|null\\.$#" count: 2 From 9e6f1c9a5a64e7b889473f0d98f8233fd559ecf7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Jun 2020 12:13:54 +0100 Subject: [PATCH 1711/3224] Living: check if damager is null before trying to use it --- src/entity/Living.php | 4 ++-- tests/phpstan/configs/l8-baseline.neon | 10 ---------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/entity/Living.php b/src/entity/Living.php index 593c8f05a1..b812884df9 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -391,7 +391,7 @@ abstract class Living extends Entity{ $this->setAbsorption(max(0, $this->getAbsorption() + $source->getModifier(EntityDamageEvent::MODIFIER_ABSORPTION))); $this->damageArmor($source->getBaseDamage()); - if($source instanceof EntityDamageByEntityEvent){ + if($source instanceof EntityDamageByEntityEvent and ($attacker = $source->getDamager()) !== null){ $damage = 0; foreach($this->armorInventory->getContents() as $k => $item){ if($item instanceof Armor and ($thornsLevel = $item->getEnchantmentLevel(Enchantment::THORNS())) > 0){ @@ -407,7 +407,7 @@ abstract class Living extends Entity{ } if($damage > 0){ - $source->getDamager()->attack(new EntityDamageByEntityEvent($this, $source->getDamager(), EntityDamageEvent::CAUSE_MAGIC, $damage)); + $attacker->attack(new EntityDamageByEntityEvent($this, $attacker, EntityDamageEvent::CAUSE_MAGIC, $damage)); } } } diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index f25a714931..a89b8e9559 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -135,16 +135,6 @@ parameters: count: 3 path: ../../../src/entity/Living.php - - - message: "#^Cannot call method attack\\(\\) on pocketmine\\\\entity\\\\Entity\\|null\\.$#" - count: 1 - path: ../../../src/entity/Living.php - - - - message: "#^Parameter \\#2 \\$entity of class pocketmine\\\\event\\\\entity\\\\EntityDamageByEntityEvent constructor expects pocketmine\\\\entity\\\\Entity, pocketmine\\\\entity\\\\Entity\\|null given\\.$#" - count: 1 - path: ../../../src/entity/Living.php - - message: "#^Cannot call method getEffectLevel\\(\\) on pocketmine\\\\entity\\\\effect\\\\EffectInstance\\|null\\.$#" count: 2 From 7e331c590d2d1924f504acfd6845d1b85da71838 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Jun 2020 13:08:36 +0100 Subject: [PATCH 1712/3224] Use static-analysis-friendly method for getting effects from EffectManager fixes 5 phpstan level 8 errors --- src/entity/Living.php | 8 ++++---- src/event/entity/EntityDamageByEntityEvent.php | 8 ++++---- tests/phpstan/configs/l8-baseline.neon | 10 ---------- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/entity/Living.php b/src/entity/Living.php index b812884df9..3c13b7fea5 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -281,7 +281,7 @@ abstract class Living extends Entity{ * Returns the initial upwards velocity of a jumping entity in blocks/tick, including additional velocity due to effects. */ public function getJumpVelocity() : float{ - return $this->jumpVelocity + ($this->effectManager->has(VanillaEffects::JUMP_BOOST()) ? ($this->effectManager->get(VanillaEffects::JUMP_BOOST())->getEffectLevel() / 10) : 0); + return $this->jumpVelocity + ((($jumpBoost = $this->effectManager->get(VanillaEffects::JUMP_BOOST())) !== null ? $jumpBoost->getEffectLevel() : 0) / 10); } /** @@ -294,7 +294,7 @@ abstract class Living extends Entity{ } public function fall(float $fallDistance) : void{ - $damage = ceil($fallDistance - 3 - ($this->effectManager->has(VanillaEffects::JUMP_BOOST()) ? $this->effectManager->get(VanillaEffects::JUMP_BOOST())->getEffectLevel() : 0)); + $damage = ceil($fallDistance - 3 - (($jumpBoost = $this->effectManager->get(VanillaEffects::JUMP_BOOST())) !== null ? $jumpBoost->getEffectLevel() : 0)); if($damage > 0){ $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FALL, $damage); $this->attack($ev); @@ -367,8 +367,8 @@ abstract class Living extends Entity{ } $cause = $source->getCause(); - if($this->effectManager->has(VanillaEffects::RESISTANCE()) and $cause !== EntityDamageEvent::CAUSE_VOID and $cause !== EntityDamageEvent::CAUSE_SUICIDE){ - $source->setModifier(-$source->getFinalDamage() * min(1, 0.2 * $this->effectManager->get(VanillaEffects::RESISTANCE())->getEffectLevel()), EntityDamageEvent::MODIFIER_RESISTANCE); + if(($resistance = $this->effectManager->get(VanillaEffects::RESISTANCE())) !== null and $cause !== EntityDamageEvent::CAUSE_VOID and $cause !== EntityDamageEvent::CAUSE_SUICIDE){ + $source->setModifier(-$source->getFinalDamage() * min(1, 0.2 * $resistance->getEffectLevel()), EntityDamageEvent::MODIFIER_RESISTANCE); } $totalEpf = 0; diff --git a/src/event/entity/EntityDamageByEntityEvent.php b/src/event/entity/EntityDamageByEntityEvent.php index 6774e808ee..90d487c704 100644 --- a/src/event/entity/EntityDamageByEntityEvent.php +++ b/src/event/entity/EntityDamageByEntityEvent.php @@ -49,12 +49,12 @@ class EntityDamageByEntityEvent extends EntityDamageEvent{ protected function addAttackerModifiers(Entity $damager) : void{ if($damager instanceof Living){ //TODO: move this to entity classes $effects = $damager->getEffects(); - if($effects->has(VanillaEffects::STRENGTH())){ - $this->setModifier($this->getBaseDamage() * 0.3 * $effects->get(VanillaEffects::STRENGTH())->getEffectLevel(), self::MODIFIER_STRENGTH); + if(($strength = $effects->get(VanillaEffects::STRENGTH())) !== null){ + $this->setModifier($this->getBaseDamage() * 0.3 * $strength->getEffectLevel(), self::MODIFIER_STRENGTH); } - if($effects->has(VanillaEffects::WEAKNESS())){ - $this->setModifier(-($this->getBaseDamage() * 0.2 * $effects->get(VanillaEffects::WEAKNESS())->getEffectLevel()), self::MODIFIER_WEAKNESS); + if(($weakness = $effects->get(VanillaEffects::WEAKNESS())) !== null){ + $this->setModifier(-($this->getBaseDamage() * 0.2 * $weakness->getEffectLevel()), self::MODIFIER_WEAKNESS); } } } diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index a89b8e9559..2ee317c4f0 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -130,16 +130,6 @@ parameters: count: 1 path: ../../../src/entity/Entity.php - - - message: "#^Cannot call method getEffectLevel\\(\\) on pocketmine\\\\entity\\\\effect\\\\EffectInstance\\|null\\.$#" - count: 3 - path: ../../../src/entity/Living.php - - - - message: "#^Cannot call method getEffectLevel\\(\\) on pocketmine\\\\entity\\\\effect\\\\EffectInstance\\|null\\.$#" - count: 2 - path: ../../../src/event/entity/EntityDamageByEntityEvent.php - - message: "#^Parameter \\#2 \\$oldContents of method pocketmine\\\\inventory\\\\InventoryListener\\:\\:onContentChange\\(\\) expects array\\, array\\ given\\.$#" count: 1 From 0000783926f5e5c0bbba4bc78a83217ca3c209f7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Jun 2020 13:34:08 +0100 Subject: [PATCH 1713/3224] Item: make nbt field non-nullable --- src/item/Item.php | 12 ++++-------- tests/phpstan/configs/l8-baseline.neon | 5 ----- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/item/Item.php b/src/item/Item.php index b8f1864794..e3c73ef869 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -68,8 +68,8 @@ class Item implements \JsonSerializable{ protected $id; /** @var int */ protected $meta; - /** @var CompoundTag|null */ - private $nbt = null; + /** @var CompoundTag */ + private $nbt; /** @var int */ protected $count = 1; /** @var string */ @@ -115,6 +115,7 @@ class Item implements \JsonSerializable{ $this->canPlaceOn = new Set(); $this->canDestroy = new Set(); + $this->nbt = new CompoundTag(); } public function hasCustomBlockData() : bool{ @@ -234,9 +235,6 @@ class Item implements \JsonSerializable{ * object is returned to allow the caller to manipulate and apply back to the item. */ public function getNamedTag() : CompoundTag{ - if($this->nbt === null){ - $this->nbt = new CompoundTag(); - } $this->serializeCompoundTag($this->nbt); return $this->nbt; } @@ -686,9 +684,7 @@ class Item implements \JsonSerializable{ } public function __clone(){ - if($this->nbt !== null){ - $this->nbt = clone $this->nbt; - } + $this->nbt = clone $this->nbt; if($this->blockEntityTag !== null){ $this->blockEntityTag = clone $this->blockEntityTag; } diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 2ee317c4f0..9d9e600dac 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -145,11 +145,6 @@ parameters: count: 1 path: ../../../src/inventory/transaction/CraftingTransaction.php - - - message: "#^Method pocketmine\\\\item\\\\Item\\:\\:getNamedTag\\(\\) should return pocketmine\\\\nbt\\\\tag\\\\CompoundTag but returns pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 1 - path: ../../../src/item/Item.php - - message: "#^Cannot clone pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" count: 1 From c040248dbd0eb22f6564544b8ec215094c13ef30 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Jun 2020 13:46:04 +0100 Subject: [PATCH 1714/3224] Item: use static-analysis-friendly method for retrieving custom block data fixes 2 phpstan level 8 errors --- src/item/Item.php | 4 ++-- tests/phpstan/configs/l8-baseline.neon | 10 ---------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/item/Item.php b/src/item/Item.php index e3c73ef869..e61891f99d 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -351,8 +351,8 @@ class Item implements \JsonSerializable{ $tag->removeTag(self::TAG_ENCH); } - $this->hasCustomBlockData() ? - $tag->setTag(self::TAG_BLOCK_ENTITY_TAG, clone $this->getCustomBlockData()) : + ($blockData = $this->getCustomBlockData()) !== null ? + $tag->setTag(self::TAG_BLOCK_ENTITY_TAG, clone $blockData) : $tag->removeTag(self::TAG_BLOCK_ENTITY_TAG); if(!$this->canPlaceOn->isEmpty()){ diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 9d9e600dac..e02e2fc7c8 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -145,16 +145,6 @@ parameters: count: 1 path: ../../../src/inventory/transaction/CraftingTransaction.php - - - message: "#^Cannot clone pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 1 - path: ../../../src/item/Item.php - - - - message: "#^Parameter \\#2 \\$tag of method pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\:\\:setTag\\(\\) expects pocketmine\\\\nbt\\\\tag\\\\Tag, pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null given\\.$#" - count: 1 - path: ../../../src/item/Item.php - - message: "#^Parameter \\#1 \\$object of function get_class expects object, pocketmine\\\\nbt\\\\tag\\\\Tag\\|null given\\.$#" count: 1 From ff00595a482e3f98864b029dbc0ff73f1353fade Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Jun 2020 20:58:02 +0100 Subject: [PATCH 1715/3224] Remove some more Vector3 mutations --- src/entity/Entity.php | 9 ++------- src/entity/object/ExperienceOrb.php | 6 +----- src/entity/projectile/Projectile.php | 2 +- src/player/Player.php | 2 +- 4 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index c7288db272..e28cb59cd0 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1270,11 +1270,8 @@ abstract class Entity{ } if($vector->lengthSquared() > 0){ - $vector = $vector->normalize(); $d = 0.014; - $this->motion->x += $vector->x * $d; - $this->motion->y += $vector->y * $d; - $this->motion->z += $vector->z * $d; + $this->motion = $this->motion->addVector($vector->normalize()->multiply($d)); } } @@ -1392,9 +1389,7 @@ abstract class Entity{ * Adds the given values to the entity's motion vector. */ public function addMotion(float $x, float $y, float $z) : void{ - $this->motion->x += $x; - $this->motion->y += $y; - $this->motion->z += $z; + $this->motion = $this->motion->add($x, $y, $z); } public function isOnGround() : bool{ diff --git a/src/entity/object/ExperienceOrb.php b/src/entity/object/ExperienceOrb.php index 6594369b86..c928d4c167 100644 --- a/src/entity/object/ExperienceOrb.php +++ b/src/entity/object/ExperienceOrb.php @@ -195,11 +195,7 @@ class ExperienceOrb extends Entity{ $distance = $vector->lengthSquared(); if($distance < 1){ - $diff = $vector->normalize()->multiply(0.2 * (1 - sqrt($distance)) ** 2); - - $this->motion->x += $diff->x; - $this->motion->y += $diff->y; - $this->motion->z += $diff->z; + $this->motion = $this->motion->addVector($vector->normalize()->multiply(0.2 * (1 - sqrt($distance)) ** 2)); } if($currentTarget->getXpManager()->canPickupXp() and $this->boundingBox->intersectsWith($currentTarget->getBoundingBox())){ diff --git a/src/entity/projectile/Projectile.php b/src/entity/projectile/Projectile.php index f4aa9aa1b3..4a3d8f95ec 100644 --- a/src/entity/projectile/Projectile.php +++ b/src/entity/projectile/Projectile.php @@ -247,7 +247,7 @@ abstract class Projectile extends Entity{ } $this->isCollided = $this->onGround = true; - $this->motion->x = $this->motion->y = $this->motion->z = 0; + $this->motion = new Vector3(0, 0, 0); }else{ $this->isCollided = $this->onGround = false; $this->blockHit = null; diff --git a/src/player/Player.php b/src/player/Player.php index 074aac2553..92f7821b24 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1340,7 +1340,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if($this->spawned){ $this->processMostRecentMovements(); - $this->motion->x = $this->motion->y = $this->motion->z = 0; //TODO: HACK! (Fixes player knockback being messed up) + $this->motion = new Vector3(0, 0, 0); //TODO: HACK! (Fixes player knockback being messed up) if($this->onGround){ $this->inAirTicks = 0; }else{ From f1048aeaa3da0046291aa5712be91f78da9b957f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Jun 2020 21:38:24 +0100 Subject: [PATCH 1716/3224] Block: rework addVelocityToEntity() to avoid vector3 mutation --- composer.lock | 8 ++++---- src/block/Block.php | 4 ++-- src/block/Liquid.php | 8 +++----- src/entity/Entity.php | 7 +++++-- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/composer.lock b/composer.lock index c820118688..62fdc423c0 100644 --- a/composer.lock +++ b/composer.lock @@ -552,12 +552,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "d46310a42ab5535296ded0b9368e5642af723f47" + "reference": "a0118ce3026929e11cc05cdf776bb18cdcd1b822" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/d46310a42ab5535296ded0b9368e5642af723f47", - "reference": "d46310a42ab5535296ded0b9368e5642af723f47", + "url": "https://api.github.com/repos/pmmp/Math/zipball/a0118ce3026929e11cc05cdf776bb18cdcd1b822", + "reference": "a0118ce3026929e11cc05cdf776bb18cdcd1b822", "shasum": "" }, "require": { @@ -579,7 +579,7 @@ "LGPL-3.0" ], "description": "PHP library containing math related code used in PocketMine-MP", - "time": "2020-06-19T10:25:24+00:00" + "time": "2020-06-27T19:45:51+00:00" }, { "name": "pocketmine/nbt", diff --git a/src/block/Block.php b/src/block/Block.php index c6cb3ed995..be64be8244 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -338,8 +338,8 @@ class Block{ return false; } - public function addVelocityToEntity(Entity $entity, Vector3 $vector) : void{ - + public function addVelocityToEntity(Entity $entity) : ?Vector3{ + return null; } final public function getPos() : Position{ diff --git a/src/block/Liquid.php b/src/block/Liquid.php index 14371b3bca..195b62529a 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -234,13 +234,11 @@ abstract class Liquid extends Transparent{ return $this->flowVector = $vector->normalize(); } - public function addVelocityToEntity(Entity $entity, Vector3 $vector) : void{ + public function addVelocityToEntity(Entity $entity) : ?Vector3{ if($entity->canBeMovedByCurrents()){ - $flow = $this->getFlowVector(); - $vector->x += $flow->x; - $vector->y += $flow->y; - $vector->z += $flow->z; + return $this->getFlowVector(); } + return null; } abstract public function tickRate() : int; diff --git a/src/entity/Entity.php b/src/entity/Entity.php index e28cb59cd0..908e1d1382 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1262,13 +1262,16 @@ abstract class Entity{ } protected function checkBlockCollision() : void{ - $vector = new Vector3(0, 0, 0); + $vectors = []; foreach($this->getBlocksAround() as $block){ $block->onEntityInside($this); - $block->addVelocityToEntity($this, $vector); + if(($v = $block->addVelocityToEntity($this)) !== null){ + $vectors[] = $v; + } } + $vector = Vector3::sum(...$vectors); if($vector->lengthSquared() > 0){ $d = 0.014; $this->motion = $this->motion->addVector($vector->normalize()->multiply($d)); From 1f0ea0c2c7e88177909c672a47a9b6d0dd9a8e68 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Jun 2020 21:51:42 +0100 Subject: [PATCH 1717/3224] Living: stop mutating Vector3 --- src/entity/Living.php | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/entity/Living.php b/src/entity/Living.php index 3c13b7fea5..27cf829aa4 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -503,20 +503,18 @@ abstract class Living extends Entity{ if(mt_rand() / mt_getrandmax() > $this->knockbackResistanceAttr->getValue()){ $f = 1 / $f; - $motion = clone $this->motion; + $motionX = $this->motion->x / 2; + $motionY = $this->motion->y / 2; + $motionZ = $this->motion->z / 2; + $motionX += $x * $f * $base; + $motionY += $base; + $motionZ += $z * $f * $base; - $motion->x /= 2; - $motion->y /= 2; - $motion->z /= 2; - $motion->x += $x * $f * $base; - $motion->y += $base; - $motion->z += $z * $f * $base; - - if($motion->y > $base){ - $motion->y = $base; + if($motionY > $base){ + $motionY = $base; } - $this->setMotion($motion); + $this->setMotion(new Vector3($motionX, $motionY, $motionZ)); } } From 87ce92d87ee31678a4118e306f8510b489f6f25c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Jun 2020 23:16:04 +0100 Subject: [PATCH 1718/3224] Entity: some cleanup of network position hacks --- src/entity/Entity.php | 5 +---- src/entity/Human.php | 7 +++++-- src/entity/object/FallingBlock.php | 7 +++++-- src/entity/object/ItemEntity.php | 6 +++++- src/entity/object/PrimedTNT.php | 7 +++++-- src/player/Player.php | 6 ------ 6 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 908e1d1382..826f269b23 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -128,9 +128,6 @@ abstract class Entity{ /** @var float */ public $width; - /** @var float */ - protected $baseOffset = 0.0; - /** @var float */ private $health = 20.0; /** @var int */ @@ -724,7 +721,7 @@ abstract class Entity{ } public function getOffsetPosition(Vector3 $vector3) : Vector3{ - return new Vector3($vector3->x, $vector3->y + $this->baseOffset, $vector3->z); + return $vector3; } protected function broadcastMovement(bool $teleport = false) : void{ diff --git a/src/entity/Human.php b/src/entity/Human.php index 676b105abd..b694f9013f 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -37,6 +37,7 @@ use pocketmine\item\enchantment\Enchantment; use pocketmine\item\FoodSource; use pocketmine\item\Item; use pocketmine\item\Totem; +use pocketmine\math\Vector3; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; @@ -90,8 +91,6 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ /** @var int */ protected $xpSeed; - protected $baseOffset = 1.62; - public function __construct(Location $location, Skin $skin, ?CompoundTag $nbt = null){ $this->skin = $skin; parent::__construct($location, $nbt); @@ -414,6 +413,10 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ } } + public function getOffsetPosition(Vector3 $vector3) : Vector3{ + return $vector3->add(0, 1.621, 0); //TODO: +0.001 hack for MCPE falling underground + } + public function broadcastMovement(bool $teleport = false) : void{ //TODO: workaround 1.14.30 bug: MoveActor(Absolute|Delta)Packet don't work on players anymore :( $pk = new MovePlayerPacket(); diff --git a/src/entity/object/FallingBlock.php b/src/entity/object/FallingBlock.php index 0ad553ae9b..4b955fc7ac 100644 --- a/src/entity/object/FallingBlock.php +++ b/src/entity/object/FallingBlock.php @@ -30,6 +30,7 @@ use pocketmine\entity\Entity; use pocketmine\entity\Location; use pocketmine\event\entity\EntityBlockChangeEvent; use pocketmine\event\entity\EntityDamageEvent; +use pocketmine\math\Vector3; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; @@ -45,8 +46,6 @@ class FallingBlock extends Entity{ public $width = 0.98; public $height = 0.98; - protected $baseOffset = 0.49; - protected $gravity = 0.04; protected $drag = 0.02; @@ -149,4 +148,8 @@ class FallingBlock extends Entity{ $properties->setInt(EntityMetadataProperties::VARIANT, $this->block->getRuntimeId()); } + + public function getOffsetPosition(Vector3 $vector3) : Vector3{ + return $vector3->add(0, 0.49, 0); //TODO: check if height affects this + } } diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index 23c32c688c..f2d104e51e 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -29,6 +29,7 @@ use pocketmine\event\entity\ItemDespawnEvent; use pocketmine\event\entity\ItemSpawnEvent; use pocketmine\event\inventory\InventoryPickupItemEvent; use pocketmine\item\Item; +use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\AddItemActorPacket; @@ -55,7 +56,6 @@ class ItemEntity extends Entity{ public $width = 0.25; public $height = 0.25; - protected $baseOffset = 0.125; protected $gravity = 0.04; protected $drag = 0.02; @@ -215,6 +215,10 @@ class ItemEntity extends Entity{ $player->getNetworkSession()->sendDataPacket($pk); } + public function getOffsetPosition(Vector3 $vector3) : Vector3{ + return $vector3->add(0, 0.125, 0); + } + public function onCollideWithPlayer(Player $player) : void{ if($this->getPickupDelay() !== 0){ return; diff --git a/src/entity/object/PrimedTNT.php b/src/entity/object/PrimedTNT.php index 76244509c9..13c4ab8507 100644 --- a/src/entity/object/PrimedTNT.php +++ b/src/entity/object/PrimedTNT.php @@ -27,6 +27,7 @@ use pocketmine\entity\Entity; use pocketmine\entity\Explosive; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\ExplosionPrimeEvent; +use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; @@ -43,8 +44,6 @@ class PrimedTNT extends Entity implements Explosive{ public $width = 0.98; public $height = 0.98; - protected $baseOffset = 0.49; - protected $gravity = 0.04; protected $drag = 0.02; @@ -126,4 +125,8 @@ class PrimedTNT extends Entity implements Explosive{ $properties->setGenericFlag(EntityMetadataFlags::IGNITED, true); $properties->setInt(EntityMetadataProperties::FUSE_LENGTH, $this->fuse); } + + public function getOffsetPosition(Vector3 $vector3) : Vector3{ + return $vector3->add(0, 0.49, 0); + } } diff --git a/src/player/Player.php b/src/player/Player.php index 92f7821b24..7d6a37f1c6 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2219,12 +2219,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, parent::broadcastAnimation($animation, $targets); } - public function getOffsetPosition(Vector3 $vector3) : Vector3{ - $result = parent::getOffsetPosition($vector3); - $result->y += 0.001; //Hack for MCPE falling underground for no good reason (TODO: find out why it's doing this) - return $result; - } - /** * TODO: remove this */ From 2a9586f6fd0c3a5ad5cd6443c993c6f0b00270a0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Jun 2020 23:17:27 +0100 Subject: [PATCH 1719/3224] Explosion: fixed assert failure on explodeB() --- src/world/Explosion.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/world/Explosion.php b/src/world/Explosion.php index 64ae9ca674..db17c93d00 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -134,6 +134,7 @@ class Explosion{ if($blastForce > 0){ if(!isset($this->affectedBlocks[World::blockHash($vBlockX, $vBlockY, $vBlockZ)])){ $_block = $blockFactory->fromFullBlock($state); + $_block->position($this->world, $vBlockX, $vBlockY, $vBlockZ); foreach($_block->getAffectedBlocks() as $_affectedBlock){ $_affectedBlockPos = $_affectedBlock->getPos(); $this->affectedBlocks[World::blockHash($_affectedBlockPos->x, $_affectedBlockPos->y, $_affectedBlockPos->z)] = $_affectedBlock; From 2104b2d32b45f4b628c05a186d12e2d17f9968bd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Jun 2020 23:28:03 +0100 Subject: [PATCH 1720/3224] Entity: defer kill() until post-construct this fixes crashes and various bugs with death logic executing during the creation of entities, as well as an age-old Player crash after quitting the server when dying. --- src/entity/Entity.php | 9 +++++++-- src/player/Player.php | 3 --- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 826f269b23..878e6c9eda 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -554,7 +554,7 @@ abstract class Entity{ } if($amount <= 0){ - if($this->isAlive()){ + if($this->isAlive() and !$this->justCreated){ $this->kill(); } }elseif($amount <= $this->getMaxHealth() or $amount < $this->health){ @@ -591,7 +591,12 @@ abstract class Entity{ protected function entityBaseTick(int $tickDiff = 1) : bool{ //TODO: check vehicles - $this->justCreated = false; + if($this->justCreated){ + $this->justCreated = false; + if(!$this->isAlive()){ + $this->kill(); + } + } $changedProperties = $this->getSyncedNetworkData(true); if(count($changedProperties) > 0){ diff --git a/src/player/Player.php b/src/player/Player.php index 7d6a37f1c6..c4891d1557 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2105,9 +2105,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } protected function onDeath() : void{ - if(!$this->spawned){ //TODO: drop this hack - return; - } //Crafting grid must always be evacuated even if keep-inventory is true. This dumps the contents into the //main inventory and drops the rest on the ground. $this->doCloseInventory(); From 0d13a3fbdb6a70c622fcfcf6bde3c3b83f17d51b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 28 Jun 2020 17:34:34 +0100 Subject: [PATCH 1721/3224] NetworkSession: do not respond to death before player spawn, fixes #3513 there's a few changes that can be made to avoid this problem, the primary one being to separate this API from NetworkSession and abstract it away... but this is a reasonable, although not great, solution. --- src/network/mcpe/NetworkSession.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index b078922a45..b1d09ea510 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -645,7 +645,9 @@ class NetworkSession{ } public function onDeath() : void{ - $this->setHandler(new DeathPacketHandler($this->player, $this)); + if($this->handler instanceof InGamePacketHandler){ //TODO: this is a bad fix for pre-spawn death, this shouldn't be reachable at all at this stage :( + $this->setHandler(new DeathPacketHandler($this->player, $this)); + } } public function onRespawn() : void{ From 74b0c411c4579e064fea36b2359f6bef02519549 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 28 Jun 2020 17:37:25 +0100 Subject: [PATCH 1722/3224] regenerated network entity ID constants --- src/network/mcpe/protocol/types/entity/EntityIds.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/network/mcpe/protocol/types/entity/EntityIds.php b/src/network/mcpe/protocol/types/entity/EntityIds.php index 22bd834900..4d60a66533 100644 --- a/src/network/mcpe/protocol/types/entity/EntityIds.php +++ b/src/network/mcpe/protocol/types/entity/EntityIds.php @@ -74,6 +74,7 @@ final class EntityIds{ public const FOX = "minecraft:fox"; public const GHAST = "minecraft:ghast"; public const GUARDIAN = "minecraft:guardian"; + public const HOGLIN = "minecraft:hoglin"; public const HOPPER_MINECART = "minecraft:hopper_minecart"; public const HORSE = "minecraft:horse"; public const HUSK = "minecraft:husk"; @@ -96,6 +97,7 @@ final class EntityIds{ public const PARROT = "minecraft:parrot"; public const PHANTOM = "minecraft:phantom"; public const PIG = "minecraft:pig"; + public const PIGLIN = "minecraft:piglin"; public const PILLAGER = "minecraft:pillager"; public const PLAYER = "minecraft:player"; public const POLAR_BEAR = "minecraft:polar_bear"; @@ -117,6 +119,7 @@ final class EntityIds{ public const SPLASH_POTION = "minecraft:splash_potion"; public const SQUID = "minecraft:squid"; public const STRAY = "minecraft:stray"; + public const STRIDER = "minecraft:strider"; public const THROWN_TRIDENT = "minecraft:thrown_trident"; public const TNT = "minecraft:tnt"; public const TNT_MINECART = "minecraft:tnt_minecart"; @@ -136,6 +139,7 @@ final class EntityIds{ public const WOLF = "minecraft:wolf"; public const XP_BOTTLE = "minecraft:xp_bottle"; public const XP_ORB = "minecraft:xp_orb"; + public const ZOGLIN = "minecraft:zoglin"; public const ZOMBIE = "minecraft:zombie"; public const ZOMBIE_HORSE = "minecraft:zombie_horse"; public const ZOMBIE_PIGMAN = "minecraft:zombie_pigman"; From 27511ac3ec04b824838f03c5b536cf02d8ed9040 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 28 Jun 2020 17:37:51 +0100 Subject: [PATCH 1723/3224] updated network item ID constants --- .../mcpe/protocol/types/FixedItemIds.php | 109 +++++++++++++++++- 1 file changed, 108 insertions(+), 1 deletion(-) diff --git a/src/network/mcpe/protocol/types/FixedItemIds.php b/src/network/mcpe/protocol/types/FixedItemIds.php index 5b145e1512..d7fa56c51a 100644 --- a/src/network/mcpe/protocol/types/FixedItemIds.php +++ b/src/network/mcpe/protocol/types/FixedItemIds.php @@ -37,6 +37,88 @@ final class FixedItemIds{ //NOOP } + public const QUARTZ_BRICKS = -304; + public const CRACKED_NETHER_BRICKS = -303; + public const CHISELED_NETHER_BRICKS = -302; + public const STRIPPED_WARPED_HYPHAE = -301; + public const STRIPPED_CRIMSON_HYPHAE = -300; + public const CRIMSON_HYPHAE = -299; + public const WARPED_HYPHAE = -298; + public const POLISHED_BLACKSTONE_WALL = -297; + public const POLISHED_BLACKSTONE_BUTTON = -296; + public const POLISHED_BLACKSTONE_PRESSURE_PLATE = -295; + public const POLISHED_BLACKSTONE_DOUBLE_SLAB = -294; + public const POLISHED_BLACKSTONE_SLAB = -293; + public const POLISHED_BLACKSTONE_STAIRS = -292; + public const POLISHED_BLACKSTONE = -291; + public const ITEM_SOUL_CAMPFIRE = -290; + public const CRYING_OBSIDIAN = -289; + public const NETHER_GOLD_ORE = -288; + public const TWISTING_VINES = -287; + public const ITEM_CHAIN = -286; + public const POLISHED_BLACKSTONE_BRICK_DOUBLE_SLAB = -285; + public const POLISHED_BLACKSTONE_BRICK_SLAB = -284; + public const BLACKSTONE_DOUBLE_SLAB = -283; + public const BLACKSTONE_SLAB = -282; + public const GILDED_BLACKSTONE = -281; + public const CRACKED_POLISHED_BLACKSTONE_BRICKS = -280; + public const CHISELED_POLISHED_BLACKSTONE = -279; + public const POLISHED_BLACKSTONE_BRICK_WALL = -278; + public const BLACKSTONE_WALL = -277; + public const BLACKSTONE_STAIRS = -276; + public const POLISHED_BLACKSTONE_BRICK_STAIRS = -275; + public const POLISHED_BLACKSTONE_BRICKS = -274; + public const BLACKSTONE = -273; + public const RESPAWN_ANCHOR = -272; + public const ANCIENT_DEBRIS = -271; + public const NETHERITE_BLOCK = -270; + public const SOUL_LANTERN = -269; + public const SOUL_TORCH = -268; + public const WARPED_DOUBLE_SLAB = -267; + public const CRIMSON_DOUBLE_SLAB = -266; + public const WARPED_SLAB = -265; + public const CRIMSON_SLAB = -264; + public const WARPED_PRESSURE_PLATE = -263; + public const CRIMSON_PRESSURE_PLATE = -262; + public const WARPED_BUTTON = -261; + public const CRIMSON_BUTTON = -260; + public const WARPED_FENCE_GATE = -259; + public const CRIMSON_FENCE_GATE = -258; + public const WARPED_FENCE = -257; + public const CRIMSON_FENCE = -256; + public const WARPED_STAIRS = -255; + public const CRIMSON_STAIRS = -254; + public const WARPED_WALL_SIGN = -253; + public const CRIMSON_WALL_SIGN = -252; + public const WARPED_STANDING_SIGN = -251; + public const CRIMSON_STANDING_SIGN = -250; + + public const WARPED_TRAPDOOR = -247; + public const CRIMSON_TRAPDOOR = -246; + public const ITEM_WARPED_DOOR = -245; + public const ITEM_CRIMSON_DOOR = -244; + public const WARPED_PLANKS = -243; + public const CRIMSON_PLANKS = -242; + public const STRIPPED_WARPED_STEM = -241; + public const STRIPPED_CRIMSON_STEM = -240; + public const TARGET = -239; + public const ITEM_NETHER_SPROUTS = -238; + public const SOUL_FIRE = -237; + public const SOUL_SOIL = -236; + public const POLISHED_BASALT = -235; + public const BASALT = -234; + public const WARPED_NYLIUM = -233; + public const CRIMSON_NYLIUM = -232; + public const WEEPING_VINES = -231; + public const SHROOMLIGHT = -230; + public const WARPED_FUNGUS = -229; + public const CRIMSON_FUNGUS = -228; + public const WARPED_WART_BLOCK = -227; + public const WARPED_STEM = -226; + public const CRIMSON_STEM = -225; + public const WARPED_ROOTS = -224; + public const CRIMSON_ROOTS = -223; + public const LODESTONE = -222; public const HONEYCOMB_BLOCK = -221; public const HONEY_BLOCK = -220; public const BEEHIVE = -219; @@ -467,7 +549,9 @@ final class FixedItemIds{ public const FROSTED_ICE = 207; public const END_ROD = 208; public const END_GATEWAY = 209; - + public const ALLOW = 210; + public const DENY = 211; + public const BORDER_BLOCK = 212; public const MAGMA = 213; public const NETHER_WART_BLOCK = 214; public const RED_NETHER_BRICK = 215; @@ -754,4 +838,27 @@ final class FixedItemIds{ public const HONEYCOMB = 736; public const HONEY_BOTTLE = 737; + + public const LODESTONECOMPASS = 741; + public const NETHERITE_INGOT = 742; + public const NETHERITE_SWORD = 743; + public const NETHERITE_SHOVEL = 744; + public const NETHERITE_PICKAXE = 745; + public const NETHERITE_AXE = 746; + public const NETHERITE_HOE = 747; + public const NETHERITE_HELMET = 748; + public const NETHERITE_CHESTPLATE = 749; + public const NETHERITE_LEGGINGS = 750; + public const NETHERITE_BOOTS = 751; + public const NETHERITE_SCRAP = 752; + public const CRIMSON_SIGN = 753; + public const WARPED_SIGN = 754; + public const CRIMSON_DOOR = 755; + public const WARPED_DOOR = 756; + public const WARPED_FUNGUS_ON_A_STICK = 757; + public const CHAIN = 758; + public const RECORD_PIGSTEP = 759; + public const NETHER_SPROUTS = 760; + + public const SOUL_CAMPFIRE = 801; } From 01d221b794d344ad4cebdd192a23f2fb7f3f90cd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 28 Jun 2020 17:50:49 +0100 Subject: [PATCH 1724/3224] imports cleanup --- src/block/Block.php | 1 - src/network/mcpe/handler/InGamePacketHandler.php | 1 - src/network/mcpe/protocol/types/inventory/ItemStackWrapper.php | 1 - 3 files changed, 3 deletions(-) diff --git a/src/block/Block.php b/src/block/Block.php index be64be8244..f4a8e8054e 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -28,7 +28,6 @@ namespace pocketmine\block; use pocketmine\block\tile\Spawnable; use pocketmine\block\tile\Tile; -use pocketmine\block\tile\TileFactory; use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\entity\Entity; use pocketmine\item\enchantment\Enchantment; diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 26ba21a967..9e34ef0578 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -82,7 +82,6 @@ use pocketmine\network\mcpe\protocol\ShowCreditsPacket; use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket; use pocketmine\network\mcpe\protocol\SubClientLoginPacket; use pocketmine\network\mcpe\protocol\TextPacket; -use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; use pocketmine\network\mcpe\protocol\types\inventory\MismatchTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\NetworkInventoryAction; use pocketmine\network\mcpe\protocol\types\inventory\NormalTransactionData; diff --git a/src/network/mcpe/protocol/types/inventory/ItemStackWrapper.php b/src/network/mcpe/protocol/types/inventory/ItemStackWrapper.php index 8524bdf36d..63c1d9896d 100644 --- a/src/network/mcpe/protocol/types/inventory/ItemStackWrapper.php +++ b/src/network/mcpe/protocol/types/inventory/ItemStackWrapper.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\inventory; -use pocketmine\item\Item; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; final class ItemStackWrapper{ From d585081c22cd31d7ef57fe7cfafbe9fe6c6a6cc4 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Sun, 28 Jun 2020 17:53:03 +0100 Subject: [PATCH 1725/3224] Separate consumable item interfaces from general consumable interfaces (#3595) I wonder if there's a way to generalise item consuming beyond just eating/drinking. Stuff like lava bucket in a furnace needs the same kind of "leftover" logic. --- src/block/Cake.php | 2 +- src/{item => entity}/Consumable.php | 13 +------ src/{item => entity}/FoodSource.php | 2 +- src/entity/Human.php | 2 - src/entity/Living.php | 1 - src/item/BeetrootSoup.php | 2 +- src/item/ConsumableItem.php | 38 +++++++++++++++++++ src/item/Food.php | 8 ++-- src/item/FoodSourceItem.php | 30 +++++++++++++++ src/item/MilkBucket.php | 4 +- src/item/MushroomStew.php | 2 +- src/item/Potion.php | 4 +- src/item/RabbitStew.php | 2 +- src/player/Player.php | 4 +- .../check-explicit-mixed-baseline.neon | 5 --- 15 files changed, 83 insertions(+), 36 deletions(-) rename src/{item => entity}/Consumable.php (76%) rename src/{item => entity}/FoodSource.php (97%) create mode 100644 src/item/ConsumableItem.php create mode 100644 src/item/FoodSourceItem.php diff --git a/src/block/Cake.php b/src/block/Cake.php index 200d2e2a39..4554c71a0c 100644 --- a/src/block/Cake.php +++ b/src/block/Cake.php @@ -25,8 +25,8 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; use pocketmine\entity\effect\EffectInstance; +use pocketmine\entity\FoodSource; use pocketmine\entity\Living; -use pocketmine\item\FoodSource; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; diff --git a/src/item/Consumable.php b/src/entity/Consumable.php similarity index 76% rename from src/item/Consumable.php rename to src/entity/Consumable.php index c4b809adcb..650c1dd08a 100644 --- a/src/item/Consumable.php +++ b/src/entity/Consumable.php @@ -21,25 +21,14 @@ declare(strict_types=1); -namespace pocketmine\item; +namespace pocketmine\entity; -use pocketmine\block\Block; use pocketmine\entity\effect\EffectInstance; -use pocketmine\entity\Living; /** * Interface implemented by objects that can be consumed by mobs. */ interface Consumable{ - - /** - * Returns the leftover that this Consumable produces when it is consumed. For Items, this is usually air, but could - * be an Item to add to a Player's inventory afterwards (such as a bowl). - * - * @return Item|Block|mixed - */ - public function getResidue(); - /** * @return EffectInstance[] */ diff --git a/src/item/FoodSource.php b/src/entity/FoodSource.php similarity index 97% rename from src/item/FoodSource.php rename to src/entity/FoodSource.php index ddddb4a943..e30ece5d3e 100644 --- a/src/item/FoodSource.php +++ b/src/entity/FoodSource.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\item; +namespace pocketmine\entity; /** * Interface implemented by objects that can be consumed by players, giving them food and saturation. diff --git a/src/entity/Human.php b/src/entity/Human.php index b694f9013f..9233b25d3c 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -32,9 +32,7 @@ use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\player\PlayerExhaustEvent; use pocketmine\inventory\InventoryHolder; use pocketmine\inventory\PlayerInventory; -use pocketmine\item\Consumable; use pocketmine\item\enchantment\Enchantment; -use pocketmine\item\FoodSource; use pocketmine\item\Item; use pocketmine\item\Totem; use pocketmine\math\Vector3; diff --git a/src/entity/Living.php b/src/entity/Living.php index 27cf829aa4..8675dd00ad 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -39,7 +39,6 @@ use pocketmine\inventory\ArmorInventory; use pocketmine\inventory\CallbackInventoryListener; use pocketmine\inventory\Inventory; use pocketmine\item\Armor; -use pocketmine\item\Consumable; use pocketmine\item\Durable; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\Item; diff --git a/src/item/BeetrootSoup.php b/src/item/BeetrootSoup.php index 2671317392..4ddab67f22 100644 --- a/src/item/BeetrootSoup.php +++ b/src/item/BeetrootSoup.php @@ -37,7 +37,7 @@ class BeetrootSoup extends Food{ return 7.2; } - public function getResidue(){ + public function getResidue() : Item{ return VanillaItems::BOWL(); } } diff --git a/src/item/ConsumableItem.php b/src/item/ConsumableItem.php new file mode 100644 index 0000000000..54e661877e --- /dev/null +++ b/src/item/ConsumableItem.php @@ -0,0 +1,38 @@ +potionId); } - public function getResidue(){ + public function getResidue() : Item{ return VanillaItems::GLASS_BOTTLE(); } } diff --git a/src/item/RabbitStew.php b/src/item/RabbitStew.php index 6117a0be14..294cc772bc 100644 --- a/src/item/RabbitStew.php +++ b/src/item/RabbitStew.php @@ -37,7 +37,7 @@ class RabbitStew extends Food{ return 12; } - public function getResidue(){ + public function getResidue() : Item{ return VanillaItems::BOWL(); } } diff --git a/src/player/Player.php b/src/player/Player.php index c4891d1557..3041352309 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -73,7 +73,7 @@ use pocketmine\form\Form; use pocketmine\form\FormValidationException; use pocketmine\inventory\Inventory; use pocketmine\inventory\PlayerCursorInventory; -use pocketmine\item\Consumable; +use pocketmine\item\ConsumableItem; use pocketmine\item\enchantment\EnchantmentInstance; use pocketmine\item\enchantment\MeleeWeaponEnchantment; use pocketmine\item\Item; @@ -1489,7 +1489,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, */ public function consumeHeldItem() : bool{ $slot = $this->inventory->getItemInHand(); - if($slot instanceof Consumable){ + if($slot instanceof ConsumableItem){ $ev = new PlayerItemConsumeEvent($this, $slot); if($this->hasItemCooldown($slot)){ $ev->setCancelled(); diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index 0bcbced942..2d1b552683 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -180,11 +180,6 @@ parameters: count: 1 path: ../../../src/player/Player.php - - - message: "#^Parameter \\#1 \\.\\.\\.\\$slots of method pocketmine\\\\inventory\\\\BaseInventory\\:\\:addItem\\(\\) expects pocketmine\\\\item\\\\Item, mixed given\\.$#" - count: 1 - path: ../../../src/player/Player.php - - message: "#^Parameter \\#1 \\$description of method pocketmine\\\\command\\\\Command\\:\\:setDescription\\(\\) expects string, mixed given\\.$#" count: 1 From 78c270a96e4d65524eb752ff6bf61e8608f6577b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 28 Jun 2020 18:10:00 +0100 Subject: [PATCH 1726/3224] PopulationTask: check the correct instance --- src/world/generator/PopulationTask.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index e1a488b89b..72eee84bb7 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -27,7 +27,6 @@ use pocketmine\block\BlockFactory; use pocketmine\scheduler\AsyncTask; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\FastChunkSerializer; -use pocketmine\world\SimpleChunkManager; use pocketmine\world\World; class PopulationTask extends AsyncTask{ @@ -75,7 +74,7 @@ class PopulationTask extends AsyncTask{ public function onRun() : void{ $manager = $this->worker->getFromThreadStore("generation.world{$this->worldId}.manager"); $generator = $this->worker->getFromThreadStore("generation.world{$this->worldId}.generator"); - if(!($manager instanceof SimpleChunkManager) or !($generator instanceof Generator)){ + if(!($manager instanceof GeneratorChunkManager) or !($generator instanceof Generator)){ $this->state = false; return; } From db8e094d11247a637467c3a969b822ea45ea8e92 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 28 Jun 2020 18:45:11 +0100 Subject: [PATCH 1727/3224] Extract a Gaussian unit from Normal generator --- src/world/generator/Gaussian.php | 51 ++++++++++++++++++++++++++ src/world/generator/normal/Normal.php | 31 +++------------- tests/phpstan/configs/l8-baseline.neon | 7 +++- 3 files changed, 63 insertions(+), 26 deletions(-) create mode 100644 src/world/generator/Gaussian.php diff --git a/src/world/generator/Gaussian.php b/src/world/generator/Gaussian.php new file mode 100644 index 0000000000..61b0f86d96 --- /dev/null +++ b/src/world/generator/Gaussian.php @@ -0,0 +1,51 @@ +smoothSize = $smoothSize; + + $bellSize = 1 / $this->smoothSize; + $bellHeight = 2 * $this->smoothSize; + + for($sx = -$this->smoothSize; $sx <= $this->smoothSize; ++$sx){ + $this->kernel[$sx + $this->smoothSize] = []; + + for($sz = -$this->smoothSize; $sz <= $this->smoothSize; ++$sz){ + $bx = $bellSize * $sx; + $bz = $bellSize * $sz; + $this->kernel[$sx + $this->smoothSize][$sz + $this->smoothSize] = $bellHeight * exp(-($bx * $bx + $bz * $bz) / 2); + } + } + } +} diff --git a/src/world/generator/normal/Normal.php b/src/world/generator/normal/Normal.php index d7e6a9e146..9cd9cc7e7d 100644 --- a/src/world/generator/normal/Normal.php +++ b/src/world/generator/normal/Normal.php @@ -27,6 +27,7 @@ use pocketmine\block\VanillaBlocks; use pocketmine\world\biome\Biome; use pocketmine\world\ChunkManager; use pocketmine\world\generator\biome\BiomeSelector; +use pocketmine\world\generator\Gaussian; use pocketmine\world\generator\Generator; use pocketmine\world\generator\InvalidGeneratorOptionsException; use pocketmine\world\generator\noise\Simplex; @@ -35,7 +36,6 @@ use pocketmine\world\generator\populator\GroundCover; use pocketmine\world\generator\populator\Ore; use pocketmine\world\generator\populator\Populator; use pocketmine\world\World; -use function exp; class Normal extends Generator{ @@ -52,10 +52,8 @@ class Normal extends Generator{ /** @var BiomeSelector */ private $selector; - /** @var float[][]|null */ + /** @var Gaussian|null */ private static $GAUSSIAN_KERNEL = null; - /** @var int */ - private static $SMOOTH_SIZE = 2; /** * @param mixed[] $options @@ -66,7 +64,7 @@ class Normal extends Generator{ public function __construct(ChunkManager $world, int $seed, array $options = []){ parent::__construct($world, $seed, $options); if(self::$GAUSSIAN_KERNEL === null){ - self::generateKernel(); + self::$GAUSSIAN_KERNEL = new Gaussian(2); } $this->noiseBase = new Simplex($this->random, 4, 1 / 4, 1 / 32); @@ -132,23 +130,6 @@ class Normal extends Generator{ $this->populators[] = $ores; } - private static function generateKernel() : void{ - self::$GAUSSIAN_KERNEL = []; - - $bellSize = 1 / self::$SMOOTH_SIZE; - $bellHeight = 2 * self::$SMOOTH_SIZE; - - for($sx = -self::$SMOOTH_SIZE; $sx <= self::$SMOOTH_SIZE; ++$sx){ - self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE] = []; - - for($sz = -self::$SMOOTH_SIZE; $sz <= self::$SMOOTH_SIZE; ++$sz){ - $bx = $bellSize * $sx; - $bz = $bellSize * $sz; - self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE][$sz + self::$SMOOTH_SIZE] = $bellHeight * exp(-($bx * $bx + $bz * $bz) / 2); - } - } - } - private function pickBiome(int $x, int $z) : Biome{ $hash = $x * 2345803 ^ $z * 9236449 ^ $this->seed; $hash *= $hash + 223; @@ -186,10 +167,10 @@ class Normal extends Generator{ $biome = $this->pickBiome($chunkX * 16 + $x, $chunkZ * 16 + $z); $chunk->setBiomeId($x, $z, $biome->getId()); - for($sx = -self::$SMOOTH_SIZE; $sx <= self::$SMOOTH_SIZE; ++$sx){ - for($sz = -self::$SMOOTH_SIZE; $sz <= self::$SMOOTH_SIZE; ++$sz){ + for($sx = -self::$GAUSSIAN_KERNEL->smoothSize; $sx <= self::$GAUSSIAN_KERNEL->smoothSize; ++$sx){ + for($sz = -self::$GAUSSIAN_KERNEL->smoothSize; $sz <= self::$GAUSSIAN_KERNEL->smoothSize; ++$sz){ - $weight = self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE][$sz + self::$SMOOTH_SIZE]; + $weight = self::$GAUSSIAN_KERNEL->kernel[$sx + self::$GAUSSIAN_KERNEL->smoothSize][$sz + self::$GAUSSIAN_KERNEL->smoothSize]; if($sx === 0 and $sz === 0){ $adjacent = $biome; diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index e02e2fc7c8..7c36abf19b 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -1041,7 +1041,12 @@ parameters: path: ../../../src/world/generator/normal/Normal.php - - message: "#^Offset int does not exist on array\\\\>\\|null\\.$#" + message: "#^Cannot access property \\$smoothSize on pocketmine\\\\world\\\\generator\\\\Gaussian\\|null\\.$#" + count: 6 + path: ../../../src/world/generator/normal/Normal.php + + - + message: "#^Cannot access property \\$kernel on pocketmine\\\\world\\\\generator\\\\Gaussian\\|null\\.$#" count: 1 path: ../../../src/world/generator/normal/Normal.php From 5a56f68991eaf6781c129174e3cf057f813249ce Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 28 Jun 2020 19:08:18 +0100 Subject: [PATCH 1728/3224] Normal: make gaussian non-static this allows each generator to (potentially) have a different gaussian curve for biome blending, as well as fixing a few phpstan level 7 errors. --- src/world/generator/normal/Normal.php | 15 +++++++-------- tests/phpstan/configs/l8-baseline.neon | 10 ---------- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/src/world/generator/normal/Normal.php b/src/world/generator/normal/Normal.php index 9cd9cc7e7d..647cf7453a 100644 --- a/src/world/generator/normal/Normal.php +++ b/src/world/generator/normal/Normal.php @@ -52,8 +52,8 @@ class Normal extends Generator{ /** @var BiomeSelector */ private $selector; - /** @var Gaussian|null */ - private static $GAUSSIAN_KERNEL = null; + /** @var Gaussian */ + private $gaussian; /** * @param mixed[] $options @@ -63,9 +63,8 @@ class Normal extends Generator{ */ public function __construct(ChunkManager $world, int $seed, array $options = []){ parent::__construct($world, $seed, $options); - if(self::$GAUSSIAN_KERNEL === null){ - self::$GAUSSIAN_KERNEL = new Gaussian(2); - } + + $this->gaussian = new Gaussian(2); $this->noiseBase = new Simplex($this->random, 4, 1 / 4, 1 / 32); $this->random->setSeed($this->seed); @@ -167,10 +166,10 @@ class Normal extends Generator{ $biome = $this->pickBiome($chunkX * 16 + $x, $chunkZ * 16 + $z); $chunk->setBiomeId($x, $z, $biome->getId()); - for($sx = -self::$GAUSSIAN_KERNEL->smoothSize; $sx <= self::$GAUSSIAN_KERNEL->smoothSize; ++$sx){ - for($sz = -self::$GAUSSIAN_KERNEL->smoothSize; $sz <= self::$GAUSSIAN_KERNEL->smoothSize; ++$sz){ + for($sx = -$this->gaussian->smoothSize; $sx <= $this->gaussian->smoothSize; ++$sx){ + for($sz = -$this->gaussian->smoothSize; $sz <= $this->gaussian->smoothSize; ++$sz){ - $weight = self::$GAUSSIAN_KERNEL->kernel[$sx + self::$GAUSSIAN_KERNEL->smoothSize][$sz + self::$GAUSSIAN_KERNEL->smoothSize]; + $weight = $this->gaussian->kernel[$sx + $this->gaussian->smoothSize][$sz + $this->gaussian->smoothSize]; if($sx === 0 and $sz === 0){ $adjacent = $biome; diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 7c36abf19b..5cf4354472 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -1040,16 +1040,6 @@ parameters: count: 1 path: ../../../src/world/generator/normal/Normal.php - - - message: "#^Cannot access property \\$smoothSize on pocketmine\\\\world\\\\generator\\\\Gaussian\\|null\\.$#" - count: 6 - path: ../../../src/world/generator/normal/Normal.php - - - - message: "#^Cannot access property \\$kernel on pocketmine\\\\world\\\\generator\\\\Gaussian\\|null\\.$#" - count: 1 - path: ../../../src/world/generator/normal/Normal.php - - message: "#^Cannot call method setFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" count: 3 From cbfdfe87cf00c9c9fff831a194b513a654ba5612 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 28 Jun 2020 19:40:10 +0100 Subject: [PATCH 1729/3224] phpstan: drop some obsolete bootstrap constants --- tests/phpstan/bootstrap.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/phpstan/bootstrap.php b/tests/phpstan/bootstrap.php index b852e304fa..9850a602f6 100644 --- a/tests/phpstan/bootstrap.php +++ b/tests/phpstan/bootstrap.php @@ -25,8 +25,6 @@ define('pocketmine\_PHPSTAN_ANALYSIS', true); //TODO: these need to be defined properly or removed define('pocketmine\COMPOSER_AUTOLOADER_PATH', dirname(__DIR__, 2) . '/vendor/autoload.php'); -define('pocketmine\DATA', ''); define('pocketmine\GIT_COMMIT', str_repeat('00', 20)); define('pocketmine\PLUGIN_PATH', ''); -define('pocketmine\START_TIME', microtime(true)); define('pocketmine\VERSION', '9.9.9'); From 4fc134bd0453e86c464f4d04988f4c27aee0d561 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jun 2020 12:16:34 +0100 Subject: [PATCH 1730/3224] Separate item ID/meta to ItemIdentifier structure --- src/item/Armor.php | 4 +- src/item/Banner.php | 4 +- src/item/Bed.php | 4 +- src/item/Boat.php | 4 +- src/item/Dye.php | 4 +- src/item/Item.php | 28 +-- src/item/ItemBlock.php | 21 +- src/item/ItemFactory.php | 459 +++++++++++++++++----------------- src/item/LiquidBucket.php | 4 +- src/item/Potion.php | 4 +- src/item/Skull.php | 4 +- src/item/SplashPotion.php | 4 +- src/item/TieredTool.php | 4 +- src/item/WritableBookBase.php | 4 +- 14 files changed, 274 insertions(+), 278 deletions(-) diff --git a/src/item/Armor.php b/src/item/Armor.php index b10ae3ab93..039abe89b7 100644 --- a/src/item/Armor.php +++ b/src/item/Armor.php @@ -47,8 +47,8 @@ class Armor extends Durable{ /** @var Color|null */ protected $customColor = null; - public function __construct(int $id, int $variant, string $name, ArmorTypeInfo $info){ - parent::__construct($id, $variant, $name); + public function __construct(ItemIdentifier $identifier, string $name, ArmorTypeInfo $info){ + parent::__construct($identifier, $name); $this->armorInfo = $info; } diff --git a/src/item/Banner.php b/src/item/Banner.php index fa91c2c668..e534a5109c 100644 --- a/src/item/Banner.php +++ b/src/item/Banner.php @@ -46,8 +46,8 @@ class Banner extends Item{ */ private $patterns; - public function __construct(int $id, int $variant, string $name, DyeColor $color){ - parent::__construct($id, $variant, $name); + public function __construct(ItemIdentifier $identifier, string $name, DyeColor $color){ + parent::__construct($identifier, $name); $this->color = $color; $this->patterns = new Deque(); diff --git a/src/item/Bed.php b/src/item/Bed.php index a061129f98..9c286de5a4 100644 --- a/src/item/Bed.php +++ b/src/item/Bed.php @@ -32,8 +32,8 @@ class Bed extends Item{ /** @var DyeColor */ private $color; - public function __construct(int $id, int $variant, string $name, DyeColor $color){ - parent::__construct($id, $variant, $name); + public function __construct(ItemIdentifier $identifier, string $name, DyeColor $color){ + parent::__construct($identifier, $name); $this->color = $color; } diff --git a/src/item/Boat.php b/src/item/Boat.php index 3f75abd4f8..c23f691460 100644 --- a/src/item/Boat.php +++ b/src/item/Boat.php @@ -29,8 +29,8 @@ class Boat extends Item{ /** @var TreeType */ private $woodType; - public function __construct(int $id, int $variant, string $name, TreeType $woodType){ - parent::__construct($id, $variant, $name); + public function __construct(ItemIdentifier $identifier, string $name, TreeType $woodType){ + parent::__construct($identifier, $name); $this->woodType = $woodType; } diff --git a/src/item/Dye.php b/src/item/Dye.php index 0df19d7158..dcd6c9955d 100644 --- a/src/item/Dye.php +++ b/src/item/Dye.php @@ -30,8 +30,8 @@ class Dye extends Item{ /** @var DyeColor */ private $color; - public function __construct(int $id, int $variant, string $name, DyeColor $color){ - parent::__construct($id, $variant, $name); + public function __construct(ItemIdentifier $identifier, string $name, DyeColor $color){ + parent::__construct($identifier, $name); $this->color = $color; } diff --git a/src/item/Item.php b/src/item/Item.php index e61891f99d..579fe0622a 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -64,10 +64,8 @@ class Item implements \JsonSerializable{ public const TAG_DISPLAY_NAME = "Name"; public const TAG_DISPLAY_LORE = "Lore"; - /** @var int */ - protected $id; - /** @var int */ - protected $meta; + /** @var ItemIdentifier */ + private $identifier; /** @var CompoundTag */ private $nbt; /** @var int */ @@ -105,12 +103,8 @@ class Item implements \JsonSerializable{ * NOTE: This should NOT BE USED for creating items to set into an inventory. Use {@link ItemFactory#get} for that * purpose. */ - public function __construct(int $id, int $variant = 0, string $name = "Unknown"){ - if($id < -0x8000 or $id > 0x7fff){ //signed short range - throw new \InvalidArgumentException("ID must be in range " . -0x8000 . " - " . 0x7fff); - } - $this->id = $id; - $this->meta = $variant !== -1 ? $variant & 0x7FFF : -1; + public function __construct(ItemIdentifier $identifier, string $name = "Unknown"){ + $this->identifier = $identifier; $this->name = $name; $this->canPlaceOn = new Set(); @@ -408,7 +402,7 @@ class Item implements \JsonSerializable{ } public function isNull() : bool{ - return $this->count <= 0 or $this->id === ItemIds::AIR; + return $this->count <= 0 or $this->getId() === ItemIds::AIR; } /** @@ -437,11 +431,11 @@ class Item implements \JsonSerializable{ } final public function getId() : int{ - return $this->id; + return $this->identifier->getId(); } public function getMeta() : int{ - return $this->meta; + return $this->identifier->getMeta(); } /** @@ -449,7 +443,7 @@ class Item implements \JsonSerializable{ * Used in crafting recipes which accept multiple variants of the same item, for example crafting tables recipes. */ public function hasAnyDamageValue() : bool{ - return $this->meta === -1; + return $this->identifier->getMeta() === -1; } /** @@ -554,7 +548,7 @@ class Item implements \JsonSerializable{ * @param bool $checkCompound Whether to verify that the items' NBT match. */ final public function equals(Item $item, bool $checkDamage = true, bool $checkCompound = true) : bool{ - return $this->id === $item->getId() and + return $this->getId() === $item->getId() and (!$checkDamage or $this->getMeta() === $item->getMeta()) and (!$checkCompound or $this->getNamedTag()->equals($item->getNamedTag())); } @@ -567,7 +561,7 @@ class Item implements \JsonSerializable{ } final public function __toString() : string{ - return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->getMeta()) . ")x" . $this->count . ($this->hasNamedTag() ? " tags:0x" . base64_encode((new LittleEndianNbtSerializer())->write(new TreeRoot($this->getNamedTag()))) : ""); + return "Item " . $this->name . " (" . $this->getId() . ":" . ($this->hasAnyDamageValue() ? "?" : $this->getMeta()) . ")x" . $this->count . ($this->hasNamedTag() ? " tags:0x" . base64_encode((new LittleEndianNbtSerializer())->write(new TreeRoot($this->getNamedTag()))) : ""); } /** @@ -634,7 +628,7 @@ class Item implements \JsonSerializable{ */ public function nbtSerialize(int $slot = -1) : CompoundTag{ $result = CompoundTag::create() - ->setShort("id", $this->id) + ->setShort("id", $this->getId()) ->setByte("Count", Binary::signByte($this->count)) ->setShort("Damage", $this->getMeta()); diff --git a/src/item/ItemBlock.php b/src/item/ItemBlock.php index ab79803543..86d4ecbd71 100644 --- a/src/item/ItemBlock.php +++ b/src/item/ItemBlock.php @@ -32,25 +32,26 @@ use pocketmine\block\BlockFactory; class ItemBlock extends Item{ /** @var int */ protected $blockId; + /** @var int */ + protected $blockMeta; /** - * @param int $meta usually 0-15 (placed blocks may only have meta values 0-15) + * @param int $blockId + * @param int $blockMeta usually 0-15 (placed blocks may only have meta values 0-15) + * @param ItemIdentifier $identifier */ - public function __construct(int $blockId, int $meta = 0, ?int $itemId = null){ - if($blockId < 0){ //extended blocks - if($itemId === null){ - $itemId = $blockId; - } - $blockId = 255 - $blockId; + public function __construct(int $blockId, int $blockMeta, ItemIdentifier $identifier){ + if($blockMeta < 0 || $blockMeta > 15){ + throw new \InvalidArgumentException("Block meta value may only be between 0 and 15"); } $this->blockId = $blockId; - $this->meta = $meta; + $this->blockMeta = $blockMeta; - parent::__construct($itemId ?? $blockId, $meta, $this->getBlock()->getName()); + parent::__construct($identifier, $this->getBlock()->getName()); } public function getBlock() : Block{ - return BlockFactory::getInstance()->get($this->blockId, $this->meta & 0xf); + return BlockFactory::getInstance()->get($this->blockId, $this->blockMeta); } public function getFuelTime() : int{ diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index a03c3caed2..c7bcee89ba 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -58,183 +58,183 @@ class ItemFactory{ $this->registerSpawnEggs(); $this->registerTierToolItems(); - $this->register(new Apple(ItemIds::APPLE, 0, "Apple")); - $this->register(new Arrow(ItemIds::ARROW, 0, "Arrow")); + $this->register(new Apple(new ItemIdentifier(ItemIds::APPLE, 0), "Apple")); + $this->register(new Arrow(new ItemIdentifier(ItemIds::ARROW, 0), "Arrow")); - $this->register(new BakedPotato(ItemIds::BAKED_POTATO, 0, "Baked Potato")); - $this->register(new Beetroot(ItemIds::BEETROOT, 0, "Beetroot")); - $this->register(new BeetrootSeeds(ItemIds::BEETROOT_SEEDS, 0, "Beetroot Seeds")); - $this->register(new BeetrootSoup(ItemIds::BEETROOT_SOUP, 0, "Beetroot Soup")); - $this->register(new BlazeRod(ItemIds::BLAZE_ROD, 0, "Blaze Rod")); - $this->register(new Book(ItemIds::BOOK, 0, "Book")); - $this->register(new Bow(ItemIds::BOW, 0, "Bow")); - $this->register(new Bowl(ItemIds::BOWL, 0, "Bowl")); - $this->register(new Bread(ItemIds::BREAD, 0, "Bread")); - $this->register(new Bucket(ItemIds::BUCKET, 0, "Bucket")); - $this->register(new Carrot(ItemIds::CARROT, 0, "Carrot")); - $this->register(new ChorusFruit(ItemIds::CHORUS_FRUIT, 0, "Chorus Fruit")); - $this->register(new Clock(ItemIds::CLOCK, 0, "Clock")); - $this->register(new Clownfish(ItemIds::CLOWNFISH, 0, "Clownfish")); - $this->register(new Coal(ItemIds::COAL, 0, "Coal")); - $this->register(new Coal(ItemIds::COAL, 1, "Charcoal")); - $this->register(new CocoaBeans(ItemIds::DYE, 3, "Cocoa Beans")); - $this->register(new Compass(ItemIds::COMPASS, 0, "Compass")); - $this->register(new CookedChicken(ItemIds::COOKED_CHICKEN, 0, "Cooked Chicken")); - $this->register(new CookedFish(ItemIds::COOKED_FISH, 0, "Cooked Fish")); - $this->register(new CookedMutton(ItemIds::COOKED_MUTTON, 0, "Cooked Mutton")); - $this->register(new CookedPorkchop(ItemIds::COOKED_PORKCHOP, 0, "Cooked Porkchop")); - $this->register(new CookedRabbit(ItemIds::COOKED_RABBIT, 0, "Cooked Rabbit")); - $this->register(new CookedSalmon(ItemIds::COOKED_SALMON, 0, "Cooked Salmon")); - $this->register(new Cookie(ItemIds::COOKIE, 0, "Cookie")); - $this->register(new DriedKelp(ItemIds::DRIED_KELP, 0, "Dried Kelp")); - $this->register(new Egg(ItemIds::EGG, 0, "Egg")); - $this->register(new EnderPearl(ItemIds::ENDER_PEARL, 0, "Ender Pearl")); - $this->register(new ExperienceBottle(ItemIds::EXPERIENCE_BOTTLE, 0, "Bottle o' Enchanting")); - $this->register(new Fertilizer(ItemIds::DYE, 15, "Bone Meal")); - $this->register(new FishingRod(ItemIds::FISHING_ROD, 0, "Fishing Rod")); - $this->register(new FlintSteel(ItemIds::FLINT_STEEL, 0, "Flint and Steel")); - $this->register(new GlassBottle(ItemIds::GLASS_BOTTLE, 0, "Glass Bottle")); - $this->register(new GoldenApple(ItemIds::GOLDEN_APPLE, 0, "Golden Apple")); - $this->register(new GoldenAppleEnchanted(ItemIds::ENCHANTED_GOLDEN_APPLE, 0, "Enchanted Golden Apple")); - $this->register(new GoldenCarrot(ItemIds::GOLDEN_CARROT, 0, "Golden Carrot")); - $this->register(new Item(ItemIds::BLAZE_POWDER, 0, "Blaze Powder")); - $this->register(new Item(ItemIds::BLEACH, 0, "Bleach")); //EDU - $this->register(new Item(ItemIds::BONE, 0, "Bone")); - $this->register(new Item(ItemIds::BRICK, 0, "Brick")); - $this->register(new Item(ItemIds::CHORUS_FRUIT_POPPED, 0, "Popped Chorus Fruit")); - $this->register(new Item(ItemIds::CLAY_BALL, 0, "Clay")); - $this->register(new Item(ItemIds::COMPOUND, 0, "Salt")); - $this->register(new Item(ItemIds::COMPOUND, 1, "Sodium Oxide")); - $this->register(new Item(ItemIds::COMPOUND, 2, "Sodium Hydroxide")); - $this->register(new Item(ItemIds::COMPOUND, 3, "Magnesium Nitrate")); - $this->register(new Item(ItemIds::COMPOUND, 4, "Iron Sulphide")); - $this->register(new Item(ItemIds::COMPOUND, 5, "Lithium Hydride")); - $this->register(new Item(ItemIds::COMPOUND, 6, "Sodium Hydride")); - $this->register(new Item(ItemIds::COMPOUND, 7, "Calcium Bromide")); - $this->register(new Item(ItemIds::COMPOUND, 8, "Magnesium Oxide")); - $this->register(new Item(ItemIds::COMPOUND, 9, "Sodium Acetate")); - $this->register(new Item(ItemIds::COMPOUND, 10, "Luminol")); - $this->register(new Item(ItemIds::COMPOUND, 11, "Charcoal")); //??? maybe bug - $this->register(new Item(ItemIds::COMPOUND, 12, "Sugar")); //??? maybe bug - $this->register(new Item(ItemIds::COMPOUND, 13, "Aluminium Oxide")); - $this->register(new Item(ItemIds::COMPOUND, 14, "Boron Trioxide")); - $this->register(new Item(ItemIds::COMPOUND, 15, "Soap")); - $this->register(new Item(ItemIds::COMPOUND, 16, "Polyethylene")); - $this->register(new Item(ItemIds::COMPOUND, 17, "Rubbish")); - $this->register(new Item(ItemIds::COMPOUND, 18, "Magnesium Salts")); - $this->register(new Item(ItemIds::COMPOUND, 19, "Sulphate")); - $this->register(new Item(ItemIds::COMPOUND, 20, "Barium Sulphate")); - $this->register(new Item(ItemIds::COMPOUND, 21, "Potassium Chloride")); - $this->register(new Item(ItemIds::COMPOUND, 22, "Mercuric Chloride")); - $this->register(new Item(ItemIds::COMPOUND, 23, "Cerium Chloride")); - $this->register(new Item(ItemIds::COMPOUND, 24, "Tungsten Chloride")); - $this->register(new Item(ItemIds::COMPOUND, 25, "Calcium Chloride")); - $this->register(new Item(ItemIds::COMPOUND, 26, "Water")); //??? - $this->register(new Item(ItemIds::COMPOUND, 27, "Glue")); - $this->register(new Item(ItemIds::COMPOUND, 28, "Hypochlorite")); - $this->register(new Item(ItemIds::COMPOUND, 29, "Crude Oil")); - $this->register(new Item(ItemIds::COMPOUND, 30, "Latex")); - $this->register(new Item(ItemIds::COMPOUND, 31, "Potassium Iodide")); - $this->register(new Item(ItemIds::COMPOUND, 32, "Sodium Fluoride")); - $this->register(new Item(ItemIds::COMPOUND, 33, "Benzene")); - $this->register(new Item(ItemIds::COMPOUND, 34, "Ink")); - $this->register(new Item(ItemIds::COMPOUND, 35, "Hydrogen Peroxide")); - $this->register(new Item(ItemIds::COMPOUND, 36, "Ammonia")); - $this->register(new Item(ItemIds::COMPOUND, 37, "Sodium Hypochlorite")); - $this->register(new Item(ItemIds::DIAMOND, 0, "Diamond")); - $this->register(new Item(ItemIds::DRAGON_BREATH, 0, "Dragon's Breath")); - $this->register(new Item(ItemIds::DYE, 0, "Ink Sac")); - $this->register(new Item(ItemIds::DYE, 4, "Lapis Lazuli")); - $this->register(new Item(ItemIds::EMERALD, 0, "Emerald")); - $this->register(new Item(ItemIds::FEATHER, 0, "Feather")); - $this->register(new Item(ItemIds::FERMENTED_SPIDER_EYE, 0, "Fermented Spider Eye")); - $this->register(new Item(ItemIds::FLINT, 0, "Flint")); - $this->register(new Item(ItemIds::GHAST_TEAR, 0, "Ghast Tear")); - $this->register(new Item(ItemIds::GLISTERING_MELON, 0, "Glistering Melon")); - $this->register(new Item(ItemIds::GLOWSTONE_DUST, 0, "Glowstone Dust")); - $this->register(new Item(ItemIds::GOLD_INGOT, 0, "Gold Ingot")); - $this->register(new Item(ItemIds::GOLD_NUGGET, 0, "Gold Nugget")); - $this->register(new Item(ItemIds::GUNPOWDER, 0, "Gunpowder")); - $this->register(new Item(ItemIds::HEART_OF_THE_SEA, 0, "Heart of the Sea")); - $this->register(new Item(ItemIds::IRON_INGOT, 0, "Iron Ingot")); - $this->register(new Item(ItemIds::IRON_NUGGET, 0, "Iron Nugget")); - $this->register(new Item(ItemIds::LEATHER, 0, "Leather")); - $this->register(new Item(ItemIds::MAGMA_CREAM, 0, "Magma Cream")); - $this->register(new Item(ItemIds::NAUTILUS_SHELL, 0, "Nautilus Shell")); - $this->register(new Item(ItemIds::NETHER_BRICK, 0, "Nether Brick")); - $this->register(new Item(ItemIds::NETHER_QUARTZ, 0, "Nether Quartz")); - $this->register(new Item(ItemIds::NETHER_STAR, 0, "Nether Star")); - $this->register(new Item(ItemIds::PAPER, 0, "Paper")); - $this->register(new Item(ItemIds::PRISMARINE_CRYSTALS, 0, "Prismarine Crystals")); - $this->register(new Item(ItemIds::PRISMARINE_SHARD, 0, "Prismarine Shard")); - $this->register(new Item(ItemIds::RABBIT_FOOT, 0, "Rabbit's Foot")); - $this->register(new Item(ItemIds::RABBIT_HIDE, 0, "Rabbit Hide")); - $this->register(new Item(ItemIds::SHULKER_SHELL, 0, "Shulker Shell")); - $this->register(new Item(ItemIds::SLIME_BALL, 0, "Slimeball")); - $this->register(new Item(ItemIds::SUGAR, 0, "Sugar")); - $this->register(new Item(ItemIds::TURTLE_SHELL_PIECE, 0, "Scute")); - $this->register(new Item(ItemIds::WHEAT, 0, "Wheat")); - $this->register(new ItemBlock(BlockLegacyIds::ACACIA_DOOR_BLOCK, 0, ItemIds::ACACIA_DOOR)); - $this->register(new ItemBlock(BlockLegacyIds::BIRCH_DOOR_BLOCK, 0, ItemIds::BIRCH_DOOR)); - $this->register(new ItemBlock(BlockLegacyIds::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND)); - $this->register(new ItemBlock(BlockLegacyIds::CAKE_BLOCK, 0, ItemIds::CAKE)); - $this->register(new ItemBlock(BlockLegacyIds::CAULDRON_BLOCK, 0, ItemIds::CAULDRON)); - $this->register(new ItemBlock(BlockLegacyIds::COMPARATOR_BLOCK, 0, ItemIds::COMPARATOR)); - $this->register(new ItemBlock(BlockLegacyIds::DARK_OAK_DOOR_BLOCK, 0, ItemIds::DARK_OAK_DOOR)); - $this->register(new ItemBlock(BlockLegacyIds::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT)); - $this->register(new ItemBlock(BlockLegacyIds::HOPPER_BLOCK, 0, ItemIds::HOPPER)); - $this->register(new ItemBlock(BlockLegacyIds::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR)); - $this->register(new ItemBlock(BlockLegacyIds::ITEM_FRAME_BLOCK, 0, ItemIds::ITEM_FRAME)); - $this->register(new ItemBlock(BlockLegacyIds::JUNGLE_DOOR_BLOCK, 0, ItemIds::JUNGLE_DOOR)); - $this->register(new ItemBlock(BlockLegacyIds::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART)); - $this->register(new ItemBlock(BlockLegacyIds::OAK_DOOR_BLOCK, 0, ItemIds::OAK_DOOR)); - $this->register(new ItemBlock(BlockLegacyIds::REPEATER_BLOCK, 0, ItemIds::REPEATER)); - $this->register(new ItemBlock(BlockLegacyIds::SPRUCE_DOOR_BLOCK, 0, ItemIds::SPRUCE_DOOR)); - $this->register(new ItemBlock(BlockLegacyIds::SUGARCANE_BLOCK, 0, ItemIds::SUGARCANE)); + $this->register(new BakedPotato(new ItemIdentifier(ItemIds::BAKED_POTATO, 0), "Baked Potato")); + $this->register(new Beetroot(new ItemIdentifier(ItemIds::BEETROOT, 0), "Beetroot")); + $this->register(new BeetrootSeeds(new ItemIdentifier(ItemIds::BEETROOT_SEEDS, 0), "Beetroot Seeds")); + $this->register(new BeetrootSoup(new ItemIdentifier(ItemIds::BEETROOT_SOUP, 0), "Beetroot Soup")); + $this->register(new BlazeRod(new ItemIdentifier(ItemIds::BLAZE_ROD, 0), "Blaze Rod")); + $this->register(new Book(new ItemIdentifier(ItemIds::BOOK, 0), "Book")); + $this->register(new Bow(new ItemIdentifier(ItemIds::BOW, 0), "Bow")); + $this->register(new Bowl(new ItemIdentifier(ItemIds::BOWL, 0), "Bowl")); + $this->register(new Bread(new ItemIdentifier(ItemIds::BREAD, 0), "Bread")); + $this->register(new Bucket(new ItemIdentifier(ItemIds::BUCKET, 0), "Bucket")); + $this->register(new Carrot(new ItemIdentifier(ItemIds::CARROT, 0), "Carrot")); + $this->register(new ChorusFruit(new ItemIdentifier(ItemIds::CHORUS_FRUIT, 0), "Chorus Fruit")); + $this->register(new Clock(new ItemIdentifier(ItemIds::CLOCK, 0), "Clock")); + $this->register(new Clownfish(new ItemIdentifier(ItemIds::CLOWNFISH, 0), "Clownfish")); + $this->register(new Coal(new ItemIdentifier(ItemIds::COAL, 0), "Coal")); + $this->register(new Coal(new ItemIdentifier(ItemIds::COAL, 1), "Charcoal")); + $this->register(new CocoaBeans(new ItemIdentifier(ItemIds::DYE, 3), "Cocoa Beans")); + $this->register(new Compass(new ItemIdentifier(ItemIds::COMPASS, 0), "Compass")); + $this->register(new CookedChicken(new ItemIdentifier(ItemIds::COOKED_CHICKEN, 0), "Cooked Chicken")); + $this->register(new CookedFish(new ItemIdentifier(ItemIds::COOKED_FISH, 0), "Cooked Fish")); + $this->register(new CookedMutton(new ItemIdentifier(ItemIds::COOKED_MUTTON, 0), "Cooked Mutton")); + $this->register(new CookedPorkchop(new ItemIdentifier(ItemIds::COOKED_PORKCHOP, 0), "Cooked Porkchop")); + $this->register(new CookedRabbit(new ItemIdentifier(ItemIds::COOKED_RABBIT, 0), "Cooked Rabbit")); + $this->register(new CookedSalmon(new ItemIdentifier(ItemIds::COOKED_SALMON, 0), "Cooked Salmon")); + $this->register(new Cookie(new ItemIdentifier(ItemIds::COOKIE, 0), "Cookie")); + $this->register(new DriedKelp(new ItemIdentifier(ItemIds::DRIED_KELP, 0), "Dried Kelp")); + $this->register(new Egg(new ItemIdentifier(ItemIds::EGG, 0), "Egg")); + $this->register(new EnderPearl(new ItemIdentifier(ItemIds::ENDER_PEARL, 0), "Ender Pearl")); + $this->register(new ExperienceBottle(new ItemIdentifier(ItemIds::EXPERIENCE_BOTTLE, 0), "Bottle o' Enchanting")); + $this->register(new Fertilizer(new ItemIdentifier(ItemIds::DYE, 15), "Bone Meal")); + $this->register(new FishingRod(new ItemIdentifier(ItemIds::FISHING_ROD, 0), "Fishing Rod")); + $this->register(new FlintSteel(new ItemIdentifier(ItemIds::FLINT_STEEL, 0), "Flint and Steel")); + $this->register(new GlassBottle(new ItemIdentifier(ItemIds::GLASS_BOTTLE, 0), "Glass Bottle")); + $this->register(new GoldenApple(new ItemIdentifier(ItemIds::GOLDEN_APPLE, 0), "Golden Apple")); + $this->register(new GoldenAppleEnchanted(new ItemIdentifier(ItemIds::ENCHANTED_GOLDEN_APPLE, 0), "Enchanted Golden Apple")); + $this->register(new GoldenCarrot(new ItemIdentifier(ItemIds::GOLDEN_CARROT, 0), "Golden Carrot")); + $this->register(new Item(new ItemIdentifier(ItemIds::BLAZE_POWDER, 0), "Blaze Powder")); + $this->register(new Item(new ItemIdentifier(ItemIds::BLEACH, 0), "Bleach")); //EDU + $this->register(new Item(new ItemIdentifier(ItemIds::BONE, 0), "Bone")); + $this->register(new Item(new ItemIdentifier(ItemIds::BRICK, 0), "Brick")); + $this->register(new Item(new ItemIdentifier(ItemIds::CHORUS_FRUIT_POPPED, 0), "Popped Chorus Fruit")); + $this->register(new Item(new ItemIdentifier(ItemIds::CLAY_BALL, 0), "Clay")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 0), "Salt")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 1), "Sodium Oxide")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 2), "Sodium Hydroxide")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 3), "Magnesium Nitrate")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 4), "Iron Sulphide")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 5), "Lithium Hydride")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 6), "Sodium Hydride")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 7), "Calcium Bromide")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 8), "Magnesium Oxide")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 9), "Sodium Acetate")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 10), "Luminol")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 11), "Charcoal")); //??? maybe bug + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 12), "Sugar")); //??? maybe bug + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 13), "Aluminium Oxide")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 14), "Boron Trioxide")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 15), "Soap")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 16), "Polyethylene")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 17), "Rubbish")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 18), "Magnesium Salts")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 19), "Sulphate")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 20), "Barium Sulphate")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 21), "Potassium Chloride")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 22), "Mercuric Chloride")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 23), "Cerium Chloride")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 24), "Tungsten Chloride")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 25), "Calcium Chloride")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 26), "Water")); //??? + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 27), "Glue")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 28), "Hypochlorite")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 29), "Crude Oil")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 30), "Latex")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 31), "Potassium Iodide")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 32), "Sodium Fluoride")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 33), "Benzene")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 34), "Ink")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 35), "Hydrogen Peroxide")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 36), "Ammonia")); + $this->register(new Item(new ItemIdentifier(ItemIds::COMPOUND, 37), "Sodium Hypochlorite")); + $this->register(new Item(new ItemIdentifier(ItemIds::DIAMOND, 0), "Diamond")); + $this->register(new Item(new ItemIdentifier(ItemIds::DRAGON_BREATH, 0), "Dragon's Breath")); + $this->register(new Item(new ItemIdentifier(ItemIds::DYE, 0), "Ink Sac")); + $this->register(new Item(new ItemIdentifier(ItemIds::DYE, 4), "Lapis Lazuli")); + $this->register(new Item(new ItemIdentifier(ItemIds::EMERALD, 0), "Emerald")); + $this->register(new Item(new ItemIdentifier(ItemIds::FEATHER, 0), "Feather")); + $this->register(new Item(new ItemIdentifier(ItemIds::FERMENTED_SPIDER_EYE, 0), "Fermented Spider Eye")); + $this->register(new Item(new ItemIdentifier(ItemIds::FLINT, 0), "Flint")); + $this->register(new Item(new ItemIdentifier(ItemIds::GHAST_TEAR, 0), "Ghast Tear")); + $this->register(new Item(new ItemIdentifier(ItemIds::GLISTERING_MELON, 0), "Glistering Melon")); + $this->register(new Item(new ItemIdentifier(ItemIds::GLOWSTONE_DUST, 0), "Glowstone Dust")); + $this->register(new Item(new ItemIdentifier(ItemIds::GOLD_INGOT, 0), "Gold Ingot")); + $this->register(new Item(new ItemIdentifier(ItemIds::GOLD_NUGGET, 0), "Gold Nugget")); + $this->register(new Item(new ItemIdentifier(ItemIds::GUNPOWDER, 0), "Gunpowder")); + $this->register(new Item(new ItemIdentifier(ItemIds::HEART_OF_THE_SEA, 0), "Heart of the Sea")); + $this->register(new Item(new ItemIdentifier(ItemIds::IRON_INGOT, 0), "Iron Ingot")); + $this->register(new Item(new ItemIdentifier(ItemIds::IRON_NUGGET, 0), "Iron Nugget")); + $this->register(new Item(new ItemIdentifier(ItemIds::LEATHER, 0), "Leather")); + $this->register(new Item(new ItemIdentifier(ItemIds::MAGMA_CREAM, 0), "Magma Cream")); + $this->register(new Item(new ItemIdentifier(ItemIds::NAUTILUS_SHELL, 0), "Nautilus Shell")); + $this->register(new Item(new ItemIdentifier(ItemIds::NETHER_BRICK, 0), "Nether Brick")); + $this->register(new Item(new ItemIdentifier(ItemIds::NETHER_QUARTZ, 0), "Nether Quartz")); + $this->register(new Item(new ItemIdentifier(ItemIds::NETHER_STAR, 0), "Nether Star")); + $this->register(new Item(new ItemIdentifier(ItemIds::PAPER, 0), "Paper")); + $this->register(new Item(new ItemIdentifier(ItemIds::PRISMARINE_CRYSTALS, 0), "Prismarine Crystals")); + $this->register(new Item(new ItemIdentifier(ItemIds::PRISMARINE_SHARD, 0), "Prismarine Shard")); + $this->register(new Item(new ItemIdentifier(ItemIds::RABBIT_FOOT, 0), "Rabbit's Foot")); + $this->register(new Item(new ItemIdentifier(ItemIds::RABBIT_HIDE, 0), "Rabbit Hide")); + $this->register(new Item(new ItemIdentifier(ItemIds::SHULKER_SHELL, 0), "Shulker Shell")); + $this->register(new Item(new ItemIdentifier(ItemIds::SLIME_BALL, 0), "Slimeball")); + $this->register(new Item(new ItemIdentifier(ItemIds::SUGAR, 0), "Sugar")); + $this->register(new Item(new ItemIdentifier(ItemIds::TURTLE_SHELL_PIECE, 0), "Scute")); + $this->register(new Item(new ItemIdentifier(ItemIds::WHEAT, 0), "Wheat")); + $this->register(new ItemBlock(BlockLegacyIds::ACACIA_DOOR_BLOCK, 0, new ItemIdentifier(ItemIds::ACACIA_DOOR, 0))); + $this->register(new ItemBlock(BlockLegacyIds::BIRCH_DOOR_BLOCK, 0, new ItemIdentifier(ItemIds::BIRCH_DOOR, 0))); + $this->register(new ItemBlock(BlockLegacyIds::BREWING_STAND_BLOCK, 0, new ItemIdentifier(ItemIds::BREWING_STAND, 0))); + $this->register(new ItemBlock(BlockLegacyIds::CAKE_BLOCK, 0, new ItemIdentifier(ItemIds::CAKE, 0))); + $this->register(new ItemBlock(BlockLegacyIds::CAULDRON_BLOCK, 0, new ItemIdentifier(ItemIds::CAULDRON, 0))); + $this->register(new ItemBlock(BlockLegacyIds::COMPARATOR_BLOCK, 0, new ItemIdentifier(ItemIds::COMPARATOR, 0))); + $this->register(new ItemBlock(BlockLegacyIds::DARK_OAK_DOOR_BLOCK, 0, new ItemIdentifier(ItemIds::DARK_OAK_DOOR, 0))); + $this->register(new ItemBlock(BlockLegacyIds::FLOWER_POT_BLOCK, 0, new ItemIdentifier(ItemIds::FLOWER_POT, 0))); + $this->register(new ItemBlock(BlockLegacyIds::HOPPER_BLOCK, 0, new ItemIdentifier(ItemIds::HOPPER, 0))); + $this->register(new ItemBlock(BlockLegacyIds::IRON_DOOR_BLOCK, 0, new ItemIdentifier(ItemIds::IRON_DOOR, 0))); + $this->register(new ItemBlock(BlockLegacyIds::ITEM_FRAME_BLOCK, 0, new ItemIdentifier(ItemIds::ITEM_FRAME, 0))); + $this->register(new ItemBlock(BlockLegacyIds::JUNGLE_DOOR_BLOCK, 0, new ItemIdentifier(ItemIds::JUNGLE_DOOR, 0))); + $this->register(new ItemBlock(BlockLegacyIds::NETHER_WART_PLANT, 0, new ItemIdentifier(ItemIds::NETHER_WART, 0))); + $this->register(new ItemBlock(BlockLegacyIds::OAK_DOOR_BLOCK, 0, new ItemIdentifier(ItemIds::OAK_DOOR, 0))); + $this->register(new ItemBlock(BlockLegacyIds::REPEATER_BLOCK, 0, new ItemIdentifier(ItemIds::REPEATER, 0))); + $this->register(new ItemBlock(BlockLegacyIds::SPRUCE_DOOR_BLOCK, 0, new ItemIdentifier(ItemIds::SPRUCE_DOOR, 0))); + $this->register(new ItemBlock(BlockLegacyIds::SUGARCANE_BLOCK, 0, new ItemIdentifier(ItemIds::SUGARCANE, 0))); //TODO: fix metadata for buckets with still liquid in them //the meta values are intentionally hardcoded because block IDs will change in the future - $this->register(new LiquidBucket(ItemIds::BUCKET, 8, "Water Bucket", VanillaBlocks::WATER())); - $this->register(new LiquidBucket(ItemIds::BUCKET, 10, "Lava Bucket", VanillaBlocks::LAVA())); - $this->register(new Melon(ItemIds::MELON, 0, "Melon")); - $this->register(new MelonSeeds(ItemIds::MELON_SEEDS, 0, "Melon Seeds")); - $this->register(new MilkBucket(ItemIds::BUCKET, 1, "Milk Bucket")); - $this->register(new Minecart(ItemIds::MINECART, 0, "Minecart")); - $this->register(new MushroomStew(ItemIds::MUSHROOM_STEW, 0, "Mushroom Stew")); - $this->register(new PaintingItem(ItemIds::PAINTING, 0, "Painting")); - $this->register(new PoisonousPotato(ItemIds::POISONOUS_POTATO, 0, "Poisonous Potato")); - $this->register(new Potato(ItemIds::POTATO, 0, "Potato")); - $this->register(new Pufferfish(ItemIds::PUFFERFISH, 0, "Pufferfish")); - $this->register(new PumpkinPie(ItemIds::PUMPKIN_PIE, 0, "Pumpkin Pie")); - $this->register(new PumpkinSeeds(ItemIds::PUMPKIN_SEEDS, 0, "Pumpkin Seeds")); - $this->register(new RabbitStew(ItemIds::RABBIT_STEW, 0, "Rabbit Stew")); - $this->register(new RawBeef(ItemIds::RAW_BEEF, 0, "Raw Beef")); - $this->register(new RawChicken(ItemIds::RAW_CHICKEN, 0, "Raw Chicken")); - $this->register(new RawFish(ItemIds::RAW_FISH, 0, "Raw Fish")); - $this->register(new RawMutton(ItemIds::RAW_MUTTON, 0, "Raw Mutton")); - $this->register(new RawPorkchop(ItemIds::RAW_PORKCHOP, 0, "Raw Porkchop")); - $this->register(new RawRabbit(ItemIds::RAW_RABBIT, 0, "Raw Rabbit")); - $this->register(new RawSalmon(ItemIds::RAW_SALMON, 0, "Raw Salmon")); - $this->register(new Redstone(ItemIds::REDSTONE, 0, "Redstone")); - $this->register(new RottenFlesh(ItemIds::ROTTEN_FLESH, 0, "Rotten Flesh")); - $this->register(new Shears(ItemIds::SHEARS, 0, "Shears")); - $this->register(new Sign(BlockLegacyIds::STANDING_SIGN, 0, ItemIds::SIGN)); - $this->register(new Sign(BlockLegacyIds::SPRUCE_STANDING_SIGN, 0, ItemIds::SPRUCE_SIGN)); - $this->register(new Sign(BlockLegacyIds::BIRCH_STANDING_SIGN, 0, ItemIds::BIRCH_SIGN)); - $this->register(new Sign(BlockLegacyIds::JUNGLE_STANDING_SIGN, 0, ItemIds::JUNGLE_SIGN)); - $this->register(new Sign(BlockLegacyIds::ACACIA_STANDING_SIGN, 0, ItemIds::ACACIA_SIGN)); - $this->register(new Sign(BlockLegacyIds::DARKOAK_STANDING_SIGN, 0, ItemIds::DARKOAK_SIGN)); - $this->register(new Snowball(ItemIds::SNOWBALL, 0, "Snowball")); - $this->register(new SpiderEye(ItemIds::SPIDER_EYE, 0, "Spider Eye")); - $this->register(new Steak(ItemIds::STEAK, 0, "Steak")); - $this->register(new Stick(ItemIds::STICK, 0, "Stick")); - $this->register(new StringItem(ItemIds::STRING, 0, "String")); - $this->register(new Totem(ItemIds::TOTEM, 0, "Totem of Undying")); - $this->register(new WheatSeeds(ItemIds::WHEAT_SEEDS, 0, "Wheat Seeds")); - $this->register(new WritableBook(ItemIds::WRITABLE_BOOK, 0, "Book & Quill")); - $this->register(new WrittenBook(ItemIds::WRITTEN_BOOK, 0, "Written Book")); + $this->register(new LiquidBucket(new ItemIdentifier(ItemIds::BUCKET, 8), "Water Bucket", VanillaBlocks::WATER())); + $this->register(new LiquidBucket(new ItemIdentifier(ItemIds::BUCKET, 10), "Lava Bucket", VanillaBlocks::LAVA())); + $this->register(new Melon(new ItemIdentifier(ItemIds::MELON, 0), "Melon")); + $this->register(new MelonSeeds(new ItemIdentifier(ItemIds::MELON_SEEDS, 0), "Melon Seeds")); + $this->register(new MilkBucket(new ItemIdentifier(ItemIds::BUCKET, 1), "Milk Bucket")); + $this->register(new Minecart(new ItemIdentifier(ItemIds::MINECART, 0), "Minecart")); + $this->register(new MushroomStew(new ItemIdentifier(ItemIds::MUSHROOM_STEW, 0), "Mushroom Stew")); + $this->register(new PaintingItem(new ItemIdentifier(ItemIds::PAINTING, 0), "Painting")); + $this->register(new PoisonousPotato(new ItemIdentifier(ItemIds::POISONOUS_POTATO, 0), "Poisonous Potato")); + $this->register(new Potato(new ItemIdentifier(ItemIds::POTATO, 0), "Potato")); + $this->register(new Pufferfish(new ItemIdentifier(ItemIds::PUFFERFISH, 0), "Pufferfish")); + $this->register(new PumpkinPie(new ItemIdentifier(ItemIds::PUMPKIN_PIE, 0), "Pumpkin Pie")); + $this->register(new PumpkinSeeds(new ItemIdentifier(ItemIds::PUMPKIN_SEEDS, 0), "Pumpkin Seeds")); + $this->register(new RabbitStew(new ItemIdentifier(ItemIds::RABBIT_STEW, 0), "Rabbit Stew")); + $this->register(new RawBeef(new ItemIdentifier(ItemIds::RAW_BEEF, 0), "Raw Beef")); + $this->register(new RawChicken(new ItemIdentifier(ItemIds::RAW_CHICKEN, 0), "Raw Chicken")); + $this->register(new RawFish(new ItemIdentifier(ItemIds::RAW_FISH, 0), "Raw Fish")); + $this->register(new RawMutton(new ItemIdentifier(ItemIds::RAW_MUTTON, 0), "Raw Mutton")); + $this->register(new RawPorkchop(new ItemIdentifier(ItemIds::RAW_PORKCHOP, 0), "Raw Porkchop")); + $this->register(new RawRabbit(new ItemIdentifier(ItemIds::RAW_RABBIT, 0), "Raw Rabbit")); + $this->register(new RawSalmon(new ItemIdentifier(ItemIds::RAW_SALMON, 0), "Raw Salmon")); + $this->register(new Redstone(new ItemIdentifier(ItemIds::REDSTONE, 0), "Redstone")); + $this->register(new RottenFlesh(new ItemIdentifier(ItemIds::ROTTEN_FLESH, 0), "Rotten Flesh")); + $this->register(new Shears(new ItemIdentifier(ItemIds::SHEARS, 0), "Shears")); + $this->register(new Sign(BlockLegacyIds::STANDING_SIGN, 0, new ItemIdentifier(ItemIds::SIGN, 0))); + $this->register(new Sign(BlockLegacyIds::SPRUCE_STANDING_SIGN, 0, new ItemIdentifier(ItemIds::SPRUCE_SIGN, 0))); + $this->register(new Sign(BlockLegacyIds::BIRCH_STANDING_SIGN, 0, new ItemIdentifier(ItemIds::BIRCH_SIGN, 0))); + $this->register(new Sign(BlockLegacyIds::JUNGLE_STANDING_SIGN, 0, new ItemIdentifier(ItemIds::JUNGLE_SIGN, 0))); + $this->register(new Sign(BlockLegacyIds::ACACIA_STANDING_SIGN, 0, new ItemIdentifier(ItemIds::ACACIA_SIGN, 0))); + $this->register(new Sign(BlockLegacyIds::DARKOAK_STANDING_SIGN, 0, new ItemIdentifier(ItemIds::DARKOAK_SIGN, 0))); + $this->register(new Snowball(new ItemIdentifier(ItemIds::SNOWBALL, 0), "Snowball")); + $this->register(new SpiderEye(new ItemIdentifier(ItemIds::SPIDER_EYE, 0), "Spider Eye")); + $this->register(new Steak(new ItemIdentifier(ItemIds::STEAK, 0), "Steak")); + $this->register(new Stick(new ItemIdentifier(ItemIds::STICK, 0), "Stick")); + $this->register(new StringItem(new ItemIdentifier(ItemIds::STRING, 0), "String")); + $this->register(new Totem(new ItemIdentifier(ItemIds::TOTEM, 0), "Totem of Undying")); + $this->register(new WheatSeeds(new ItemIdentifier(ItemIds::WHEAT_SEEDS, 0), "Wheat Seeds")); + $this->register(new WritableBook(new ItemIdentifier(ItemIds::WRITABLE_BOOK, 0), "Book & Quill")); + $this->register(new WrittenBook(new ItemIdentifier(ItemIds::WRITTEN_BOOK, 0), "Written Book")); foreach(SkullType::getAll() as $skullType){ - $this->register(new Skull(ItemIds::SKULL, $skullType->getMagicNumber(), $skullType->getDisplayName(), $skullType)); + $this->register(new Skull(new ItemIdentifier(ItemIds::SKULL, $skullType->getMagicNumber()), $skullType->getDisplayName(), $skullType)); } $dyeMap = [ @@ -246,18 +246,18 @@ class ItemFactory{ foreach(DyeColor::getAll() as $color){ //TODO: use colour object directly //TODO: add interface to dye-colour objects - $this->register(new Dye(ItemIds::DYE, $dyeMap[$color->id()] ?? $color->getInvertedMagicNumber(), $color->getDisplayName() . " Dye", $color)); - $this->register(new Bed(ItemIds::BED, $color->getMagicNumber(), $color->getDisplayName() . " Bed", $color)); - $this->register(new Banner(ItemIds::BANNER, $color->getInvertedMagicNumber(), $color->getDisplayName() . " Banner", $color)); + $this->register(new Dye(new ItemIdentifier(ItemIds::DYE, $dyeMap[$color->id()] ?? $color->getInvertedMagicNumber()), $color->getDisplayName() . " Dye", $color)); + $this->register(new Bed(new ItemIdentifier(ItemIds::BED, $color->getMagicNumber()), $color->getDisplayName() . " Bed", $color)); + $this->register(new Banner(new ItemIdentifier(ItemIds::BANNER, $color->getInvertedMagicNumber()), $color->getDisplayName() . " Banner", $color)); } foreach(Potion::ALL as $type){ - $this->register(new Potion(ItemIds::POTION, $type, "Potion", $type)); - $this->register(new SplashPotion(ItemIds::SPLASH_POTION, $type, "Splash Potion", $type)); + $this->register(new Potion(new ItemIdentifier(ItemIds::POTION, $type), "Potion", $type)); + $this->register(new SplashPotion(new ItemIdentifier(ItemIds::SPLASH_POTION, $type), "Splash Potion", $type)); } foreach(TreeType::getAll() as $type){ - $this->register(new Boat(ItemIds::BOAT, $type->getMagicNumber(), $type->getDisplayName() . " Boat", $type)); + $this->register(new Boat(new ItemIdentifier(ItemIds::BOAT, $type->getMagicNumber()), $type->getDisplayName() . " Boat", $type)); } //region --- auto-generated TODOs --- @@ -317,17 +317,17 @@ class ItemFactory{ private function registerSpawnEggs() : void{ //TODO: the meta values should probably be hardcoded; they won't change, but the EntityLegacyIds might - $this->register(new class(ItemIds::SPAWN_EGG, EntityLegacyIds::ZOMBIE, "Zombie Spawn Egg") extends SpawnEgg{ + $this->register(new class(new ItemIdentifier(ItemIds::SPAWN_EGG, EntityLegacyIds::ZOMBIE), "Zombie Spawn Egg") extends SpawnEgg{ protected function createEntity(World $world, Vector3 $pos, float $yaw, float $pitch) : Entity{ return new Zombie(Location::fromObject($pos, $world, $yaw, $pitch)); } }); - $this->register(new class(ItemIds::SPAWN_EGG, EntityLegacyIds::SQUID, "Squid Spawn Egg") extends SpawnEgg{ + $this->register(new class(new ItemIdentifier(ItemIds::SPAWN_EGG, EntityLegacyIds::SQUID), "Squid Spawn Egg") extends SpawnEgg{ public function createEntity(World $world, Vector3 $pos, float $yaw, float $pitch) : Entity{ return new Squid(Location::fromObject($pos, $world, $yaw, $pitch)); } }); - $this->register(new class(ItemIds::SPAWN_EGG, EntityLegacyIds::VILLAGER, "Villager Spawn Egg") extends SpawnEgg{ + $this->register(new class(new ItemIdentifier(ItemIds::SPAWN_EGG, EntityLegacyIds::VILLAGER), "Villager Spawn Egg") extends SpawnEgg{ public function createEntity(World $world, Vector3 $pos, float $yaw, float $pitch) : Entity{ return new Villager(Location::fromObject($pos, $world, $yaw, $pitch)); } @@ -335,54 +335,54 @@ class ItemFactory{ } private function registerTierToolItems() : void{ - $this->register(new Axe(ItemIds::DIAMOND_AXE, "Diamond Axe", ToolTier::DIAMOND())); - $this->register(new Axe(ItemIds::GOLDEN_AXE, "Golden Axe", ToolTier::GOLD())); - $this->register(new Axe(ItemIds::IRON_AXE, "Iron Axe", ToolTier::IRON())); - $this->register(new Axe(ItemIds::STONE_AXE, "Stone Axe", ToolTier::STONE())); - $this->register(new Axe(ItemIds::WOODEN_AXE, "Wooden Axe", ToolTier::WOOD())); - $this->register(new Hoe(ItemIds::DIAMOND_HOE, "Diamond Hoe", ToolTier::DIAMOND())); - $this->register(new Hoe(ItemIds::GOLDEN_HOE, "Golden Hoe", ToolTier::GOLD())); - $this->register(new Hoe(ItemIds::IRON_HOE, "Iron Hoe", ToolTier::IRON())); - $this->register(new Hoe(ItemIds::STONE_HOE, "Stone Hoe", ToolTier::STONE())); - $this->register(new Hoe(ItemIds::WOODEN_HOE, "Wooden Hoe", ToolTier::WOOD())); - $this->register(new Pickaxe(ItemIds::DIAMOND_PICKAXE, "Diamond Pickaxe", ToolTier::DIAMOND())); - $this->register(new Pickaxe(ItemIds::GOLDEN_PICKAXE, "Golden Pickaxe", ToolTier::GOLD())); - $this->register(new Pickaxe(ItemIds::IRON_PICKAXE, "Iron Pickaxe", ToolTier::IRON())); - $this->register(new Pickaxe(ItemIds::STONE_PICKAXE, "Stone Pickaxe", ToolTier::STONE())); - $this->register(new Pickaxe(ItemIds::WOODEN_PICKAXE, "Wooden Pickaxe", ToolTier::WOOD())); - $this->register(new Shovel(ItemIds::DIAMOND_SHOVEL, "Diamond Shovel", ToolTier::DIAMOND())); - $this->register(new Shovel(ItemIds::GOLDEN_SHOVEL, "Golden Shovel", ToolTier::GOLD())); - $this->register(new Shovel(ItemIds::IRON_SHOVEL, "Iron Shovel", ToolTier::IRON())); - $this->register(new Shovel(ItemIds::STONE_SHOVEL, "Stone Shovel", ToolTier::STONE())); - $this->register(new Shovel(ItemIds::WOODEN_SHOVEL, "Wooden Shovel", ToolTier::WOOD())); - $this->register(new Sword(ItemIds::DIAMOND_SWORD, "Diamond Sword", ToolTier::DIAMOND())); - $this->register(new Sword(ItemIds::GOLDEN_SWORD, "Golden Sword", ToolTier::GOLD())); - $this->register(new Sword(ItemIds::IRON_SWORD, "Iron Sword", ToolTier::IRON())); - $this->register(new Sword(ItemIds::STONE_SWORD, "Stone Sword", ToolTier::STONE())); - $this->register(new Sword(ItemIds::WOODEN_SWORD, "Wooden Sword", ToolTier::WOOD())); + $this->register(new Axe(new ItemIdentifier(ItemIds::DIAMOND_AXE, 0), "Diamond Axe", ToolTier::DIAMOND())); + $this->register(new Axe(new ItemIdentifier(ItemIds::GOLDEN_AXE, 0), "Golden Axe", ToolTier::GOLD())); + $this->register(new Axe(new ItemIdentifier(ItemIds::IRON_AXE, 0), "Iron Axe", ToolTier::IRON())); + $this->register(new Axe(new ItemIdentifier(ItemIds::STONE_AXE, 0), "Stone Axe", ToolTier::STONE())); + $this->register(new Axe(new ItemIdentifier(ItemIds::WOODEN_AXE, 0), "Wooden Axe", ToolTier::WOOD())); + $this->register(new Hoe(new ItemIdentifier(ItemIds::DIAMOND_HOE, 0), "Diamond Hoe", ToolTier::DIAMOND())); + $this->register(new Hoe(new ItemIdentifier(ItemIds::GOLDEN_HOE, 0), "Golden Hoe", ToolTier::GOLD())); + $this->register(new Hoe(new ItemIdentifier(ItemIds::IRON_HOE, 0), "Iron Hoe", ToolTier::IRON())); + $this->register(new Hoe(new ItemIdentifier(ItemIds::STONE_HOE, 0), "Stone Hoe", ToolTier::STONE())); + $this->register(new Hoe(new ItemIdentifier(ItemIds::WOODEN_HOE, 0), "Wooden Hoe", ToolTier::WOOD())); + $this->register(new Pickaxe(new ItemIdentifier(ItemIds::DIAMOND_PICKAXE, 0), "Diamond Pickaxe", ToolTier::DIAMOND())); + $this->register(new Pickaxe(new ItemIdentifier(ItemIds::GOLDEN_PICKAXE, 0), "Golden Pickaxe", ToolTier::GOLD())); + $this->register(new Pickaxe(new ItemIdentifier(ItemIds::IRON_PICKAXE, 0), "Iron Pickaxe", ToolTier::IRON())); + $this->register(new Pickaxe(new ItemIdentifier(ItemIds::STONE_PICKAXE, 0), "Stone Pickaxe", ToolTier::STONE())); + $this->register(new Pickaxe(new ItemIdentifier(ItemIds::WOODEN_PICKAXE, 0), "Wooden Pickaxe", ToolTier::WOOD())); + $this->register(new Shovel(new ItemIdentifier(ItemIds::DIAMOND_SHOVEL, 0), "Diamond Shovel", ToolTier::DIAMOND())); + $this->register(new Shovel(new ItemIdentifier(ItemIds::GOLDEN_SHOVEL, 0), "Golden Shovel", ToolTier::GOLD())); + $this->register(new Shovel(new ItemIdentifier(ItemIds::IRON_SHOVEL, 0), "Iron Shovel", ToolTier::IRON())); + $this->register(new Shovel(new ItemIdentifier(ItemIds::STONE_SHOVEL, 0), "Stone Shovel", ToolTier::STONE())); + $this->register(new Shovel(new ItemIdentifier(ItemIds::WOODEN_SHOVEL, 0), "Wooden Shovel", ToolTier::WOOD())); + $this->register(new Sword(new ItemIdentifier(ItemIds::DIAMOND_SWORD, 0), "Diamond Sword", ToolTier::DIAMOND())); + $this->register(new Sword(new ItemIdentifier(ItemIds::GOLDEN_SWORD, 0), "Golden Sword", ToolTier::GOLD())); + $this->register(new Sword(new ItemIdentifier(ItemIds::IRON_SWORD, 0), "Iron Sword", ToolTier::IRON())); + $this->register(new Sword(new ItemIdentifier(ItemIds::STONE_SWORD, 0), "Stone Sword", ToolTier::STONE())); + $this->register(new Sword(new ItemIdentifier(ItemIds::WOODEN_SWORD, 0), "Wooden Sword", ToolTier::WOOD())); } private function registerArmorItems() : void{ - $this->register(new Armor(ItemIds::CHAIN_BOOTS, 0, "Chainmail Boots", new ArmorTypeInfo(1, 196, ArmorInventory::SLOT_FEET))); - $this->register(new Armor(ItemIds::DIAMOND_BOOTS, 0, "Diamond Boots", new ArmorTypeInfo(3, 430, ArmorInventory::SLOT_FEET))); - $this->register(new Armor(ItemIds::GOLDEN_BOOTS, 0, "Golden Boots", new ArmorTypeInfo(1, 92, ArmorInventory::SLOT_FEET))); - $this->register(new Armor(ItemIds::IRON_BOOTS, 0, "Iron Boots", new ArmorTypeInfo(2, 196, ArmorInventory::SLOT_FEET))); - $this->register(new Armor(ItemIds::LEATHER_BOOTS, 0, "Leather Boots", new ArmorTypeInfo(1, 66, ArmorInventory::SLOT_FEET))); - $this->register(new Armor(ItemIds::CHAIN_CHESTPLATE, 0, "Chainmail Chestplate", new ArmorTypeInfo(5, 241, ArmorInventory::SLOT_CHEST))); - $this->register(new Armor(ItemIds::DIAMOND_CHESTPLATE, 0, "Diamond Chestplate", new ArmorTypeInfo(8, 529, ArmorInventory::SLOT_CHEST))); - $this->register(new Armor(ItemIds::GOLDEN_CHESTPLATE, 0, "Golden Chestplate", new ArmorTypeInfo(5, 113, ArmorInventory::SLOT_CHEST))); - $this->register(new Armor(ItemIds::IRON_CHESTPLATE, 0, "Iron Chestplate", new ArmorTypeInfo(6, 241, ArmorInventory::SLOT_CHEST))); - $this->register(new Armor(ItemIds::LEATHER_CHESTPLATE, 0, "Leather Tunic", new ArmorTypeInfo(3, 81, ArmorInventory::SLOT_CHEST))); - $this->register(new Armor(ItemIds::CHAIN_HELMET, 0, "Chainmail Helmet", new ArmorTypeInfo(2, 166, ArmorInventory::SLOT_HEAD))); - $this->register(new Armor(ItemIds::DIAMOND_HELMET, 0, "Diamond Helmet", new ArmorTypeInfo(3, 364, ArmorInventory::SLOT_HEAD))); - $this->register(new Armor(ItemIds::GOLDEN_HELMET, 0, "Golden Helmet", new ArmorTypeInfo(2, 78, ArmorInventory::SLOT_HEAD))); - $this->register(new Armor(ItemIds::IRON_HELMET, 0, "Iron Helmet", new ArmorTypeInfo(2, 166, ArmorInventory::SLOT_HEAD))); - $this->register(new Armor(ItemIds::LEATHER_HELMET, 0, "Leather Cap", new ArmorTypeInfo(1, 56, ArmorInventory::SLOT_HEAD))); - $this->register(new Armor(ItemIds::CHAIN_LEGGINGS, 0, "Chainmail Leggings", new ArmorTypeInfo(4, 226, ArmorInventory::SLOT_LEGS))); - $this->register(new Armor(ItemIds::DIAMOND_LEGGINGS, 0, "Diamond Leggings", new ArmorTypeInfo(6, 496, ArmorInventory::SLOT_LEGS))); - $this->register(new Armor(ItemIds::GOLDEN_LEGGINGS, 0, "Golden Leggings", new ArmorTypeInfo(3, 106, ArmorInventory::SLOT_LEGS))); - $this->register(new Armor(ItemIds::IRON_LEGGINGS, 0, "Iron Leggings", new ArmorTypeInfo(5, 226, ArmorInventory::SLOT_LEGS))); - $this->register(new Armor(ItemIds::LEATHER_LEGGINGS, 0, "Leather Pants", new ArmorTypeInfo(2, 76, ArmorInventory::SLOT_LEGS))); + $this->register(new Armor(new ItemIdentifier(ItemIds::CHAIN_BOOTS, 0), "Chainmail Boots", new ArmorTypeInfo(1, 196, ArmorInventory::SLOT_FEET))); + $this->register(new Armor(new ItemIdentifier(ItemIds::DIAMOND_BOOTS, 0), "Diamond Boots", new ArmorTypeInfo(3, 430, ArmorInventory::SLOT_FEET))); + $this->register(new Armor(new ItemIdentifier(ItemIds::GOLDEN_BOOTS, 0), "Golden Boots", new ArmorTypeInfo(1, 92, ArmorInventory::SLOT_FEET))); + $this->register(new Armor(new ItemIdentifier(ItemIds::IRON_BOOTS, 0), "Iron Boots", new ArmorTypeInfo(2, 196, ArmorInventory::SLOT_FEET))); + $this->register(new Armor(new ItemIdentifier(ItemIds::LEATHER_BOOTS, 0), "Leather Boots", new ArmorTypeInfo(1, 66, ArmorInventory::SLOT_FEET))); + $this->register(new Armor(new ItemIdentifier(ItemIds::CHAIN_CHESTPLATE, 0), "Chainmail Chestplate", new ArmorTypeInfo(5, 241, ArmorInventory::SLOT_CHEST))); + $this->register(new Armor(new ItemIdentifier(ItemIds::DIAMOND_CHESTPLATE, 0), "Diamond Chestplate", new ArmorTypeInfo(8, 529, ArmorInventory::SLOT_CHEST))); + $this->register(new Armor(new ItemIdentifier(ItemIds::GOLDEN_CHESTPLATE, 0), "Golden Chestplate", new ArmorTypeInfo(5, 113, ArmorInventory::SLOT_CHEST))); + $this->register(new Armor(new ItemIdentifier(ItemIds::IRON_CHESTPLATE, 0), "Iron Chestplate", new ArmorTypeInfo(6, 241, ArmorInventory::SLOT_CHEST))); + $this->register(new Armor(new ItemIdentifier(ItemIds::LEATHER_CHESTPLATE, 0), "Leather Tunic", new ArmorTypeInfo(3, 81, ArmorInventory::SLOT_CHEST))); + $this->register(new Armor(new ItemIdentifier(ItemIds::CHAIN_HELMET, 0), "Chainmail Helmet", new ArmorTypeInfo(2, 166, ArmorInventory::SLOT_HEAD))); + $this->register(new Armor(new ItemIdentifier(ItemIds::DIAMOND_HELMET, 0), "Diamond Helmet", new ArmorTypeInfo(3, 364, ArmorInventory::SLOT_HEAD))); + $this->register(new Armor(new ItemIdentifier(ItemIds::GOLDEN_HELMET, 0), "Golden Helmet", new ArmorTypeInfo(2, 78, ArmorInventory::SLOT_HEAD))); + $this->register(new Armor(new ItemIdentifier(ItemIds::IRON_HELMET, 0), "Iron Helmet", new ArmorTypeInfo(2, 166, ArmorInventory::SLOT_HEAD))); + $this->register(new Armor(new ItemIdentifier(ItemIds::LEATHER_HELMET, 0), "Leather Cap", new ArmorTypeInfo(1, 56, ArmorInventory::SLOT_HEAD))); + $this->register(new Armor(new ItemIdentifier(ItemIds::CHAIN_LEGGINGS, 0), "Chainmail Leggings", new ArmorTypeInfo(4, 226, ArmorInventory::SLOT_LEGS))); + $this->register(new Armor(new ItemIdentifier(ItemIds::DIAMOND_LEGGINGS, 0), "Diamond Leggings", new ArmorTypeInfo(6, 496, ArmorInventory::SLOT_LEGS))); + $this->register(new Armor(new ItemIdentifier(ItemIds::GOLDEN_LEGGINGS, 0), "Golden Leggings", new ArmorTypeInfo(3, 106, ArmorInventory::SLOT_LEGS))); + $this->register(new Armor(new ItemIdentifier(ItemIds::IRON_LEGGINGS, 0), "Iron Leggings", new ArmorTypeInfo(5, 226, ArmorInventory::SLOT_LEGS))); + $this->register(new Armor(new ItemIdentifier(ItemIds::LEATHER_LEGGINGS, 0), "Leather Pants", new ArmorTypeInfo(2, 76, ArmorInventory::SLOT_LEGS))); } /** @@ -423,16 +423,17 @@ class ItemFactory{ try{ $item->setDamage($meta); }catch(\InvalidArgumentException $e){ - $item = new Item($id, $meta); + $item = new Item(new ItemIdentifier($id, $meta)); } }elseif($id < 256){ //intentionally includes negatives, for extended block IDs - $item = new ItemBlock($id, $meta); + //TODO: do not assume that item IDs and block IDs are the same or related + $item = new ItemBlock($id < 0 ? 255 - $id : $id, $meta, new ItemIdentifier($id, $meta)); } } if($item === null){ //negative damage values will fallthru to here, to avoid crazy shit with crafting wildcard hacks - $item = new Item($id, $meta); + $item = new Item(new ItemIdentifier($id, $meta)); } $item->setCount($count); diff --git a/src/item/LiquidBucket.php b/src/item/LiquidBucket.php index ec759b2910..88fe7663f5 100644 --- a/src/item/LiquidBucket.php +++ b/src/item/LiquidBucket.php @@ -35,8 +35,8 @@ class LiquidBucket extends Item{ /** @var Liquid */ private $liquid; - public function __construct(int $id, int $meta, string $name, Liquid $liquid){ - parent::__construct($id, $meta, $name); + public function __construct(ItemIdentifier $identifier, string $name, Liquid $liquid){ + parent::__construct($identifier, $name); $this->liquid = $liquid; } diff --git a/src/item/Potion.php b/src/item/Potion.php index b21e4d828e..4d4dd1b34f 100644 --- a/src/item/Potion.php +++ b/src/item/Potion.php @@ -256,8 +256,8 @@ class Potion extends Item implements ConsumableItem{ /** @var int */ private $potionId; - public function __construct(int $id, int $variant, string $name, int $potionId){ - parent::__construct($id, $variant, $name); + public function __construct(ItemIdentifier $identifier, string $name, int $potionId){ + parent::__construct($identifier, $name); $this->potionId = $potionId; } diff --git a/src/item/Skull.php b/src/item/Skull.php index 62d008662b..700d13039e 100644 --- a/src/item/Skull.php +++ b/src/item/Skull.php @@ -32,8 +32,8 @@ class Skull extends Item{ /** @var SkullType */ private $skullType; - public function __construct(int $id, int $variant, string $name, SkullType $skullType){ - parent::__construct($id, $variant, $name); + public function __construct(ItemIdentifier $identifier, string $name, SkullType $skullType){ + parent::__construct($identifier, $name); $this->skullType = $skullType; } diff --git a/src/item/SplashPotion.php b/src/item/SplashPotion.php index 20c09aa4e4..72d553e2f0 100644 --- a/src/item/SplashPotion.php +++ b/src/item/SplashPotion.php @@ -33,8 +33,8 @@ class SplashPotion extends ProjectileItem{ /** @var int */ private $potionId; - public function __construct(int $id, int $variant, string $name, int $potionId){ - parent::__construct($id, $variant, $name); + public function __construct(ItemIdentifier $identifier, string $name, int $potionId){ + parent::__construct($identifier, $name); $this->potionId = $potionId; } diff --git a/src/item/TieredTool.php b/src/item/TieredTool.php index eb1998fe38..cf4647481f 100644 --- a/src/item/TieredTool.php +++ b/src/item/TieredTool.php @@ -28,8 +28,8 @@ abstract class TieredTool extends Tool{ /** @var ToolTier */ protected $tier; - public function __construct(int $id, string $name, ToolTier $tier){ - parent::__construct($id, 0, $name); + public function __construct(ItemIdentifier $identifier, string $name, ToolTier $tier){ + parent::__construct($identifier, $name); $this->tier = $tier; } diff --git a/src/item/WritableBookBase.php b/src/item/WritableBookBase.php index 75e997bf90..4eda371054 100644 --- a/src/item/WritableBookBase.php +++ b/src/item/WritableBookBase.php @@ -40,8 +40,8 @@ abstract class WritableBookBase extends Item{ */ private $pages; - public function __construct(int $id, int $variant, string $name){ - parent::__construct($id, $variant, $name); + public function __construct(ItemIdentifier $identifier, string $name){ + parent::__construct($identifier, $name); $this->pages = new Deque(); } From 0b05fd198733ac5d4eebf4cfa720c63a9efa070b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jun 2020 18:54:47 +0100 Subject: [PATCH 1731/3224] added missing file --- src/block/utils/BlockStateBinaryEncoder.php | 28 ++++++++++++ src/item/ItemIdentifier.php | 48 +++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 src/block/utils/BlockStateBinaryEncoder.php create mode 100644 src/item/ItemIdentifier.php diff --git a/src/block/utils/BlockStateBinaryEncoder.php b/src/block/utils/BlockStateBinaryEncoder.php new file mode 100644 index 0000000000..27b0510831 --- /dev/null +++ b/src/block/utils/BlockStateBinaryEncoder.php @@ -0,0 +1,28 @@ + 0x7fff){ //signed short range + throw new \InvalidArgumentException("ID must be in range " . -0x8000 . " - " . 0x7fff); + } + $this->id = $id; + $this->meta = $meta !== -1 ? $meta & 0x7FFF : -1; + } + + public function getId() : int{ + return $this->id; + } + + public function getMeta() : int{ + return $this->meta; + } +} From dae2a4ffce2f90dbc762eef514c43c0cfb9e3170 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jun 2020 19:35:09 +0100 Subject: [PATCH 1732/3224] SignText: added failing test case for index omission in constructor --- tests/phpunit/block/utils/SignTextTest.php | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 tests/phpunit/block/utils/SignTextTest.php diff --git a/tests/phpunit/block/utils/SignTextTest.php b/tests/phpunit/block/utils/SignTextTest.php new file mode 100644 index 0000000000..3d0c611a12 --- /dev/null +++ b/tests/phpunit/block/utils/SignTextTest.php @@ -0,0 +1,37 @@ + "test"]); + self::assertSame("", $text->getLine(0)); + self::assertSame("test", $text->getLine(1)); + self::assertSame("", $text->getLine(2)); + self::assertSame("", $text->getLine(3)); + } +} From 42f543b40525a5edbdc73aae05eead20948cd336 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jun 2020 19:35:38 +0100 Subject: [PATCH 1733/3224] SignText: fixed crash when fetching lines of text if not all lines were provided to the constructor --- src/block/utils/SignText.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/block/utils/SignText.php b/src/block/utils/SignText.php index a4ab838bbf..896f2b8276 100644 --- a/src/block/utils/SignText.php +++ b/src/block/utils/SignText.php @@ -43,7 +43,10 @@ class SignText{ * @throws \InvalidArgumentException */ public function __construct(?array $lines = null){ - $this->setLines($lines ?? array_fill(0, self::LINE_COUNT, "")); + $this->lines = array_fill(0, self::LINE_COUNT, ""); + if($lines !== null){ + $this->setLines($lines); + } } /** From e61a08a56bb71c77c49cb070feeefa83e86397a2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jun 2020 20:18:10 +0100 Subject: [PATCH 1734/3224] Make SignText immutable --- src/block/tile/Sign.php | 5 ++-- src/block/utils/SignText.php | 54 ++++++++++++------------------------ 2 files changed, 20 insertions(+), 39 deletions(-) diff --git a/src/block/tile/Sign.php b/src/block/tile/Sign.php index fdb8dab468..8d16eb48e0 100644 --- a/src/block/tile/Sign.php +++ b/src/block/tile/Sign.php @@ -62,13 +62,14 @@ class Sign extends Spawnable{ if($nbt->hasTag(self::TAG_TEXT_BLOB, StringTag::class)){ //MCPE 1.2 save format $this->text = SignText::fromBlob(mb_scrub($nbt->getString(self::TAG_TEXT_BLOB), 'UTF-8')); }else{ - $this->text = new SignText(); + $text = []; for($i = 0; $i < SignText::LINE_COUNT; ++$i){ $textKey = sprintf(self::TAG_TEXT_LINE, $i + 1); if($nbt->hasTag($textKey, StringTag::class)){ - $this->text->setLine($i, mb_scrub($nbt->getString($textKey), 'UTF-8')); + $text[$i] = mb_scrub($nbt->getString($textKey), 'UTF-8'); } } + $this->text = new SignText($text); } } diff --git a/src/block/utils/SignText.php b/src/block/utils/SignText.php index 896f2b8276..753e25bb3a 100644 --- a/src/block/utils/SignText.php +++ b/src/block/utils/SignText.php @@ -39,13 +39,27 @@ class SignText{ private $lines; /** - * @param string[] $lines - * @throws \InvalidArgumentException + * @param string[]|null $lines index-sensitive; omitting an index will leave it unchanged + * + * @throws \InvalidArgumentException if the array size is greater than 4 + * @throws \InvalidArgumentException if invalid keys (out of bounds or string) are found in the array + * @throws \InvalidArgumentException if any line is not valid UTF-8 or contains a newline */ public function __construct(?array $lines = null){ $this->lines = array_fill(0, self::LINE_COUNT, ""); if($lines !== null){ - $this->setLines($lines); + if(count($lines) > self::LINE_COUNT){ + throw new \InvalidArgumentException("Expected at most 4 lines, got " . count($lines)); + } + foreach($lines as $k => $line){ + $this->checkLineIndex($k); + Utils::checkUTF8($line); + if(strpos($line, "\n") !== false){ + throw new \InvalidArgumentException("Line must not contain newlines"); + } + //TODO: add length checks + $this->lines[$k] = $line; + } } } @@ -68,24 +82,6 @@ class SignText{ return $this->lines; } - /** - * Sets the sign text. - * - * @param string[] $lines index-sensitive; omitting an index will leave it unchanged - * - * @throws \InvalidArgumentException if the array size is greater than 4 - * @throws \InvalidArgumentException if invalid keys (out of bounds or string) are found in the array - */ - public function setLines(array $lines) : void{ - if(count($lines) > self::LINE_COUNT){ - throw new \InvalidArgumentException("Expected at most 4 lines, got " . count($lines)); - } - foreach($lines as $k => $line){ - $this->checkLineIndex($k); - $this->setLine($k, $line); - } - } - /** * @param int|string $index */ @@ -107,20 +103,4 @@ class SignText{ $this->checkLineIndex($index); return $this->lines[$index]; } - - /** - * Sets the line at the given offset. - * - * @throws \InvalidArgumentException if the text is not valid UTF-8 - * @throws \InvalidArgumentException if the text contains a newline - */ - public function setLine(int $index, string $line) : void{ - $this->checkLineIndex($index); - Utils::checkUTF8($line); - if(strpos($line, "\n") !== false){ - throw new \InvalidArgumentException("Line must not contain newlines"); - } - //TODO: add length checks - $this->lines[$index] = $line; - } } From 43ae1a5cb4e746808ab6cda3bc7ed174f17bdd59 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jun 2020 20:54:51 +0100 Subject: [PATCH 1735/3224] Block: make getAllSides() and getHorizontalSides() return generators --- src/block/Block.php | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/src/block/Block.php b/src/block/Block.php index f4a8e8054e..bed56f3d20 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -43,7 +43,6 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use pocketmine\world\Position; use pocketmine\world\World; -use function array_merge; use function assert; use function count; use function dechex; @@ -489,30 +488,26 @@ class Block{ /** * Returns the 4 blocks on the horizontal axes around the block (north, south, east, west) * - * @return Block[] + * @return Block[]|\Generator + * @phpstan-return \Generator */ - public function getHorizontalSides() : array{ - return [ - $this->getSide(Facing::NORTH), - $this->getSide(Facing::SOUTH), - $this->getSide(Facing::WEST), - $this->getSide(Facing::EAST) - ]; + public function getHorizontalSides() : \Generator{ + yield $this->getSide(Facing::NORTH); + yield $this->getSide(Facing::SOUTH); + yield $this->getSide(Facing::WEST); + yield $this->getSide(Facing::EAST); } /** * Returns the six blocks around this block. * - * @return Block[] + * @return Block[]|\Generator + * @phpstan-return \Generator */ - public function getAllSides() : array{ - return array_merge( - [ - $this->getSide(Facing::DOWN), - $this->getSide(Facing::UP) - ], - $this->getHorizontalSides() - ); + public function getAllSides() : \Generator{ + yield $this->getSide(Facing::DOWN); + yield $this->getSide(Facing::UP); + yield from $this->getHorizontalSides(); } /** From fc22fd80d8463ceb7ad497a6c204c5937cbd7e4d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jun 2020 21:03:55 +0100 Subject: [PATCH 1736/3224] Eradicate remaining usages of Position->getWorld() --- src/block/Block.php | 2 +- src/player/Player.php | 2 +- src/world/Position.php | 2 +- src/world/World.php | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/block/Block.php b/src/block/Block.php index bed56f3d20..cb131fcc0b 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -79,7 +79,7 @@ class Block{ } public function __clone(){ - $this->pos = Position::fromObject($this->pos, $this->pos->getWorld()); + $this->pos = Position::fromObject($this->pos, $this->pos->getWorldNonNull()); } public function getIdInfo() : BlockIdentifier{ diff --git a/src/player/Player.php b/src/player/Player.php index 3041352309..df03dc55dd 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -713,7 +713,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } protected function switchWorld(World $targetWorld) : bool{ - $oldWorld = $this->location->getWorld(); + $oldWorld = $this->location->isValid() ? $this->location->getWorldNonNull() : null; if(parent::switchWorld($targetWorld)){ if($oldWorld !== null){ foreach($this->usedChunks as $index => $status){ diff --git a/src/world/Position.php b/src/world/Position.php index c670da0861..0d8c4914c6 100644 --- a/src/world/Position.php +++ b/src/world/Position.php @@ -119,7 +119,7 @@ class Position extends Vector3{ public function equals(Vector3 $v) : bool{ if($v instanceof Position){ - return parent::equals($v) and $v->getWorld() === $this->getWorld(); + return parent::equals($v) and $v->world === $this->world; } return parent::equals($v); } diff --git a/src/world/World.php b/src/world/World.php index 2fa0c1e1d2..31f1298419 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2043,7 +2043,7 @@ class World implements ChunkManager{ throw new \InvalidArgumentException("Attempted to add a garbage closed Tile to world"); } $pos = $tile->getPos(); - if($pos->getWorld() !== $this){ + if(!$pos->isValid() || $pos->getWorldNonNull() !== $this){ throw new \InvalidArgumentException("Invalid Tile world"); } @@ -2065,7 +2065,7 @@ class World implements ChunkManager{ */ public function removeTile(Tile $tile) : void{ $pos = $tile->getPos(); - if($pos->getWorld() !== $this){ + if(!$pos->isValid() || $pos->getWorldNonNull() !== $this){ throw new \InvalidArgumentException("Invalid Tile world"); } From 670ad9eb9dfa07cb4d141aaf67aa64b3f091ebf0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jun 2020 21:19:46 +0100 Subject: [PATCH 1737/3224] Position: rename getWorldNonNull() to getWorld(), remove original getWorld() --- src/block/Banner.php | 6 +- src/block/BaseRail.php | 8 +-- src/block/Bed.php | 10 +-- src/block/Block.php | 18 ++--- src/block/BrewingStand.php | 2 +- src/block/Button.php | 10 +-- src/block/Cactus.php | 12 ++-- src/block/Cake.php | 4 +- src/block/Carpet.php | 2 +- src/block/Chest.php | 6 +- src/block/CoarseDirt.php | 2 +- src/block/CocoaBlock.php | 6 +- src/block/ConcretePowder.php | 2 +- src/block/Crops.php | 6 +- src/block/DaylightSensor.php | 10 +-- src/block/DeadBush.php | 2 +- src/block/Dirt.php | 2 +- src/block/Door.php | 8 +-- src/block/DoublePlant.php | 2 +- src/block/DragonEgg.php | 8 +-- src/block/EnderChest.php | 2 +- src/block/Farmland.php | 10 +-- src/block/FenceGate.php | 6 +- src/block/Fire.php | 12 ++-- src/block/Flower.php | 2 +- src/block/FlowerPot.php | 8 +-- src/block/FrostedIce.php | 18 ++--- src/block/Furnace.php | 6 +- src/block/Grass.php | 20 +++--- src/block/GrassPath.php | 2 +- src/block/Hopper.php | 2 +- src/block/Ice.php | 6 +- src/block/ItemFrame.php | 12 ++-- src/block/Ladder.php | 2 +- src/block/Lantern.php | 8 +-- src/block/Leaves.php | 8 +-- src/block/Lever.php | 6 +- src/block/Liquid.php | 66 +++++++++---------- src/block/Mycelium.php | 4 +- src/block/NetherWartPlant.php | 4 +- src/block/Note.php | 4 +- src/block/RedMushroom.php | 2 +- src/block/RedstoneComparator.php | 8 +-- src/block/RedstoneOre.php | 6 +- src/block/RedstoneRepeater.php | 4 +- src/block/Sapling.php | 10 +-- src/block/Sign.php | 8 +-- src/block/Skull.php | 4 +- src/block/SnowLayer.php | 4 +- src/block/Stem.php | 4 +- src/block/Sugarcane.php | 16 ++--- src/block/TNT.php | 4 +- src/block/TallGrass.php | 2 +- src/block/Torch.php | 2 +- src/block/Trapdoor.php | 4 +- src/block/Vine.php | 4 +- src/block/WaterLily.php | 2 +- src/block/inventory/ChestInventory.php | 6 +- src/block/tile/BrewingStand.php | 2 +- src/block/tile/Chest.php | 6 +- src/block/tile/ContainerTrait.php | 2 +- src/block/tile/Furnace.php | 8 +-- src/block/tile/Tile.php | 4 +- src/block/utils/FallableTrait.php | 6 +- src/command/defaults/ParticleCommand.php | 2 +- src/command/defaults/SeedCommand.php | 2 +- src/command/defaults/SetWorldSpawnCommand.php | 2 +- src/command/defaults/SpawnpointCommand.php | 2 +- src/command/defaults/TeleportCommand.php | 2 +- src/entity/Entity.php | 10 +-- src/entity/Location.php | 2 +- src/item/Bow.php | 2 +- src/item/PaintingItem.php | 2 +- src/item/ProjectileItem.php | 2 +- src/network/mcpe/NetworkSession.php | 4 +- .../mcpe/handler/InGamePacketHandler.php | 4 +- .../mcpe/handler/PreSpawnPacketHandler.php | 4 +- src/player/Player.php | 8 +-- src/world/Explosion.php | 2 +- src/world/Position.php | 28 ++------ src/world/World.php | 4 +- 81 files changed, 259 insertions(+), 275 deletions(-) diff --git a/src/block/Banner.php b/src/block/Banner.php index 2be5e82e7a..c9ba9c5c92 100644 --- a/src/block/Banner.php +++ b/src/block/Banner.php @@ -99,7 +99,7 @@ class Banner extends Transparent{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->pos->getWorldNonNull()->getTile($this->pos); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileBanner){ $this->baseColor = $tile->getBaseColor(); $this->setPatterns($tile->getPatterns()); @@ -108,7 +108,7 @@ class Banner extends Transparent{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->pos->getWorldNonNull()->getTile($this->pos); + $tile = $this->pos->getWorld()->getTile($this->pos); assert($tile instanceof TileBanner); $tile->setBaseColor($this->baseColor); $tile->setPatterns($this->patterns); @@ -171,7 +171,7 @@ class Banner extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::opposite($this->facing))->getId() === BlockLegacyIds::AIR){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/BaseRail.php b/src/block/BaseRail.php index 4278c2700c..017a3953ba 100644 --- a/src/block/BaseRail.php +++ b/src/block/BaseRail.php @@ -255,7 +255,7 @@ abstract class BaseRail extends Flowable{ if(isset($otherPossible[$otherSide])){ $otherConnections[] = $otherSide; $other->setConnections($otherConnections); - $this->pos->getWorldNonNull()->setBlock($other->pos, $other); + $this->pos->getWorld()->setBlock($other->pos, $other); $changed = true; $thisConnections[] = $thisSide; @@ -268,7 +268,7 @@ abstract class BaseRail extends Flowable{ if($changed){ $this->setConnections($thisConnections); - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } } @@ -287,11 +287,11 @@ abstract class BaseRail extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); }else{ foreach($this->connections as $connection){ if(($connection & self::FLAG_ASCEND) !== 0 and $this->getSide($connection & ~self::FLAG_ASCEND)->isTransparent()){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); break; } } diff --git a/src/block/Bed.php b/src/block/Bed.php index a5176d1b45..57c643fef0 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -73,7 +73,7 @@ class Bed extends Transparent{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); //read extra state information from the tile - this is an ugly hack - $tile = $this->pos->getWorldNonNull()->getTile($this->pos); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileBed){ $this->color = $tile->getColor(); } @@ -82,7 +82,7 @@ class Bed extends Transparent{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); //extra block properties storage hack - $tile = $this->pos->getWorldNonNull()->getTile($this->pos); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileBed){ $tile->setColor($this->color); } @@ -105,11 +105,11 @@ class Bed extends Transparent{ public function setOccupied(bool $occupied = true) : void{ $this->occupied = $occupied; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this, false); + $this->pos->getWorld()->setBlock($this->pos, $this, false); if(($other = $this->getOtherHalf()) !== null){ $other->occupied = $occupied; - $this->pos->getWorldNonNull()->setBlock($other->pos, $other, false); + $this->pos->getWorld()->setBlock($other->pos, $other, false); } } @@ -139,7 +139,7 @@ class Bed extends Transparent{ return true; } - $time = $this->pos->getWorldNonNull()->getTimeOfDay(); + $time = $this->pos->getWorld()->getTimeOfDay(); $isNight = ($time >= World::TIME_NIGHT and $time < World::TIME_SUNRISE); diff --git a/src/block/Block.php b/src/block/Block.php index cb131fcc0b..46123eaab5 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -79,7 +79,7 @@ class Block{ } public function __clone(){ - $this->pos = Position::fromObject($this->pos, $this->pos->getWorldNonNull()); + $this->pos = Position::fromObject($this->pos, $this->pos->getWorld()); } public function getIdInfo() : BlockIdentifier{ @@ -148,10 +148,10 @@ class Block{ } public function writeStateToWorld() : void{ - $this->pos->getWorldNonNull()->getChunkAtPosition($this->pos)->setFullBlock($this->pos->x & 0xf, $this->pos->y, $this->pos->z & 0xf, $this->getFullId()); + $this->pos->getWorld()->getChunkAtPosition($this->pos)->setFullBlock($this->pos->x & 0xf, $this->pos->y, $this->pos->z & 0xf, $this->getFullId()); $tileType = $this->idInfo->getTileClass(); - $oldTile = $this->pos->getWorldNonNull()->getTile($this->pos); + $oldTile = $this->pos->getWorld()->getTile($this->pos); if($oldTile !== null){ if($tileType === null or !($oldTile instanceof $tileType)){ $oldTile->close(); @@ -165,8 +165,8 @@ class Block{ * @var Tile $tile * @see Tile::__construct() */ - $tile = new $tileType($this->pos->getWorldNonNull(), $this->pos->asVector3()); - $this->pos->getWorldNonNull()->addTile($tile); + $tile = new $tileType($this->pos->getWorld(), $this->pos->asVector3()); + $this->pos->getWorld()->addTile($tile); } } @@ -225,10 +225,10 @@ class Block{ * Do the actions needed so the block is broken with the Item */ public function onBreak(Item $item, ?Player $player = null) : bool{ - if(($t = $this->pos->getWorldNonNull()->getTile($this->pos)) !== null){ + if(($t = $this->pos->getWorld()->getTile($this->pos)) !== null){ $t->onBlockDestroyed(); } - $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::AIR()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); return true; } @@ -417,7 +417,7 @@ class Block{ public function getPickedItem(bool $addUserData = false) : Item{ $item = $this->asItem(); if($addUserData){ - $tile = $this->pos->getWorldNonNull()->getTile($this->pos); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof Tile){ $nbt = $tile->getCleanedNBT(); if($nbt instanceof CompoundTag){ @@ -479,7 +479,7 @@ class Block{ */ public function getSide(int $side, int $step = 1){ if($this->pos->isValid()){ - return $this->pos->getWorldNonNull()->getBlock($this->pos->getSide($side, $step)); + return $this->pos->getWorld()->getBlock($this->pos->getSide($side, $step)); } throw new \InvalidStateException("Block does not have a valid world"); diff --git a/src/block/BrewingStand.php b/src/block/BrewingStand.php index 5f6d6436fb..f4ae81b2b8 100644 --- a/src/block/BrewingStand.php +++ b/src/block/BrewingStand.php @@ -60,7 +60,7 @@ class BrewingStand extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $stand = $this->pos->getWorldNonNull()->getTile($this->pos); + $stand = $this->pos->getWorld()->getTile($this->pos); if($stand instanceof TileBrewingStand and $stand->canOpenWith($item->getCustomName())){ $player->setCurrentWindow($stand->getInventory()); } diff --git a/src/block/Button.php b/src/block/Button.php index d9c5bf4789..23657d7646 100644 --- a/src/block/Button.php +++ b/src/block/Button.php @@ -64,9 +64,9 @@ abstract class Button extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$this->powered){ $this->powered = true; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); - $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, $this->getActivationTime()); - $this->pos->getWorldNonNull()->addSound($this->pos->add(0.5, 0.5, 0.5), new RedstonePowerOnSound()); + $this->pos->getWorld()->setBlock($this->pos, $this); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, $this->getActivationTime()); + $this->pos->getWorld()->addSound($this->pos->add(0.5, 0.5, 0.5), new RedstonePowerOnSound()); } return true; @@ -75,8 +75,8 @@ abstract class Button extends Flowable{ public function onScheduledUpdate() : void{ if($this->powered){ $this->powered = false; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); - $this->pos->getWorldNonNull()->addSound($this->pos->add(0.5, 0.5, 0.5), new RedstonePowerOffSound()); + $this->pos->getWorld()->setBlock($this->pos, $this); + $this->pos->getWorld()->addSound($this->pos->add(0.5, 0.5, 0.5), new RedstonePowerOffSound()); } } } diff --git a/src/block/Cactus.php b/src/block/Cactus.php index 1521c078c7..9516666237 100644 --- a/src/block/Cactus.php +++ b/src/block/Cactus.php @@ -76,12 +76,12 @@ class Cactus extends Transparent{ public function onNearbyBlockChange() : void{ $down = $this->getSide(Facing::DOWN); if($down->getId() !== BlockLegacyIds::SAND and !$down->isSameType($this)){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); }else{ foreach(Facing::HORIZONTAL as $side){ $b = $this->getSide($side); if($b->isSolid()){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); break; } } @@ -96,23 +96,23 @@ class Cactus extends Transparent{ if(!$this->getSide(Facing::DOWN)->isSameType($this)){ if($this->age === 15){ for($y = 1; $y < 3; ++$y){ - $b = $this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z); + $b = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z); if($b->getId() === BlockLegacyIds::AIR){ $ev = new BlockGrowEvent($b, VanillaBlocks::CACTUS()); $ev->call(); if($ev->isCancelled()){ break; } - $this->pos->getWorldNonNull()->setBlock($b->pos, $ev->getNewState()); + $this->pos->getWorld()->setBlock($b->pos, $ev->getNewState()); }else{ break; } } $this->age = 0; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); }else{ ++$this->age; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } } } diff --git a/src/block/Cake.php b/src/block/Cake.php index 4554c71a0c..4575cd99e6 100644 --- a/src/block/Cake.php +++ b/src/block/Cake.php @@ -78,7 +78,7 @@ class Cake extends Transparent implements FoodSource{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ //Replace with common break method - $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::AIR()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); } } @@ -127,6 +127,6 @@ class Cake extends Transparent implements FoodSource{ } public function onConsume(Living $consumer) : void{ - $this->pos->getWorldNonNull()->setBlock($this->pos, $this->getResidue()); + $this->pos->getWorld()->setBlock($this->pos, $this->getResidue()); } } diff --git a/src/block/Carpet.php b/src/block/Carpet.php index 65a7bc853d..0a430b023e 100644 --- a/src/block/Carpet.php +++ b/src/block/Carpet.php @@ -58,7 +58,7 @@ class Carpet extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/Chest.php b/src/block/Chest.php index 2f13028e63..523812a389 100644 --- a/src/block/Chest.php +++ b/src/block/Chest.php @@ -70,7 +70,7 @@ class Chest extends Transparent{ } public function onPostPlace() : void{ - $tile = $this->pos->getWorldNonNull()->getTile($this->pos); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileChest){ foreach([ Facing::rotateY($this->facing, true), @@ -78,7 +78,7 @@ class Chest extends Transparent{ ] as $side){ $c = $this->getSide($side); if($c instanceof Chest and $c->isSameType($this) and $c->facing === $this->facing){ - $pair = $this->pos->getWorldNonNull()->getTile($c->pos); + $pair = $this->pos->getWorld()->getTile($c->pos); if($pair instanceof TileChest and !$pair->isPaired()){ $pair->pairWith($tile); $tile->pairWith($pair); @@ -92,7 +92,7 @@ class Chest extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $chest = $this->pos->getWorldNonNull()->getTile($this->pos); + $chest = $this->pos->getWorld()->getTile($this->pos); if($chest instanceof TileChest){ if( !$this->getSide(Facing::UP)->isTransparent() or diff --git a/src/block/CoarseDirt.php b/src/block/CoarseDirt.php index 05ed9dd947..d6e6630a5d 100644 --- a/src/block/CoarseDirt.php +++ b/src/block/CoarseDirt.php @@ -34,7 +34,7 @@ class CoarseDirt extends Dirt{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP and $item instanceof Hoe){ $item->applyDamage(1); - $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::DIRT()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::DIRT()); return true; } diff --git a/src/block/CocoaBlock.php b/src/block/CocoaBlock.php index 02534a10a2..5191f61c4f 100644 --- a/src/block/CocoaBlock.php +++ b/src/block/CocoaBlock.php @@ -85,7 +85,7 @@ class CocoaBlock extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($this->age < 2 and $item instanceof Fertilizer){ $this->age++; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); $item->pop(); @@ -98,7 +98,7 @@ class CocoaBlock extends Transparent{ public function onNearbyBlockChange() : void{ $side = $this->getSide(Facing::opposite($this->facing)); if(!($side instanceof Wood) or !$side->getTreeType()->equals(TreeType::JUNGLE())){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } @@ -109,7 +109,7 @@ class CocoaBlock extends Transparent{ public function onRandomTick() : void{ if($this->age < 2 and mt_rand(1, 5) === 1){ $this->age++; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } } diff --git a/src/block/ConcretePowder.php b/src/block/ConcretePowder.php index 2154acce13..5813965863 100644 --- a/src/block/ConcretePowder.php +++ b/src/block/ConcretePowder.php @@ -38,7 +38,7 @@ class ConcretePowder extends Opaque implements Fallable{ public function onNearbyBlockChange() : void{ if(($block = $this->checkAdjacentWater()) !== null){ - $this->pos->getWorldNonNull()->setBlock($this->pos, $block); + $this->pos->getWorld()->setBlock($this->pos, $block); }else{ $this->startFalling(); } diff --git a/src/block/Crops.php b/src/block/Crops.php index 1d96ff210c..ff0570d878 100644 --- a/src/block/Crops.php +++ b/src/block/Crops.php @@ -72,7 +72,7 @@ abstract class Crops extends Flowable{ $ev = new BlockGrowEvent($this, $block); $ev->call(); if(!$ev->isCancelled()){ - $this->pos->getWorldNonNull()->setBlock($this->pos, $ev->getNewState()); + $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); } $item->pop(); @@ -85,7 +85,7 @@ abstract class Crops extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::FARMLAND){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } @@ -100,7 +100,7 @@ abstract class Crops extends Flowable{ $ev = new BlockGrowEvent($this, $block); $ev->call(); if(!$ev->isCancelled()){ - $this->pos->getWorldNonNull()->setBlock($this->pos, $ev->getNewState()); + $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); } } } diff --git a/src/block/DaylightSensor.php b/src/block/DaylightSensor.php index a890a97052..5892bf0abc 100644 --- a/src/block/DaylightSensor.php +++ b/src/block/DaylightSensor.php @@ -91,7 +91,7 @@ class DaylightSensor extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->inverted = !$this->inverted; $this->power = $this->recalculatePower(); - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); return true; } @@ -99,18 +99,18 @@ class DaylightSensor extends Transparent{ $newPower = $this->recalculatePower(); if($this->power !== $newPower){ $this->power = $newPower; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } - $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, 20); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 20); } private function recalculatePower() : int{ - $lightLevel = $this->pos->getWorldNonNull()->getRealBlockSkyLightAt($this->pos->x, $this->pos->y, $this->pos->z); + $lightLevel = $this->pos->getWorld()->getRealBlockSkyLightAt($this->pos->x, $this->pos->y, $this->pos->z); if($this->inverted){ return 15 - $lightLevel; } - $sunAngle = $this->pos->getWorldNonNull()->getSunAnglePercentage(); + $sunAngle = $this->pos->getWorld()->getSunAnglePercentage(); return max(0, (int) round($lightLevel * cos(($sunAngle + ((($sunAngle < 0.5 ? 0 : 1) - $sunAngle) / 5)) * 2 * M_PI))); } diff --git a/src/block/DeadBush.php b/src/block/DeadBush.php index 611c675961..e4de2c8abf 100644 --- a/src/block/DeadBush.php +++ b/src/block/DeadBush.php @@ -47,7 +47,7 @@ class DeadBush extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/Dirt.php b/src/block/Dirt.php index b368526ea8..7dab9b0093 100644 --- a/src/block/Dirt.php +++ b/src/block/Dirt.php @@ -38,7 +38,7 @@ class Dirt extends Opaque{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP and $item instanceof Hoe){ $item->applyDamage(1); - $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::FARMLAND()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::FARMLAND()); return true; } diff --git a/src/block/Door.php b/src/block/Door.php index c119356626..ab4ad13e8d 100644 --- a/src/block/Door.php +++ b/src/block/Door.php @@ -99,7 +99,7 @@ class Door extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ //Replace with common break method - $this->pos->getWorldNonNull()->useBreakOn($this->pos); //this will delete both halves if they exist + $this->pos->getWorld()->useBreakOn($this->pos); //this will delete both halves if they exist } } @@ -138,11 +138,11 @@ class Door extends Transparent{ $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); if($other instanceof Door and $other->isSameType($this)){ $other->open = $this->open; - $this->pos->getWorldNonNull()->setBlock($other->pos, $other); + $this->pos->getWorld()->setBlock($other->pos, $other); } - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); - $this->pos->getWorldNonNull()->addSound($this->pos, new DoorSound()); + $this->pos->getWorld()->setBlock($this->pos, $this); + $this->pos->getWorld()->addSound($this->pos, new DoorSound()); return true; } diff --git a/src/block/DoublePlant.php b/src/block/DoublePlant.php index d96a537fa2..3505e1ac6b 100644 --- a/src/block/DoublePlant.php +++ b/src/block/DoublePlant.php @@ -77,7 +77,7 @@ class DoublePlant extends Flowable{ public function onNearbyBlockChange() : void{ if(!$this->isValidHalfPlant() or (!$this->top and $this->getSide(Facing::DOWN)->isTransparent())){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/DragonEgg.php b/src/block/DragonEgg.php index 52d6158a64..17546b3f2a 100644 --- a/src/block/DragonEgg.php +++ b/src/block/DragonEgg.php @@ -63,7 +63,7 @@ class DragonEgg extends Transparent implements Fallable{ public function teleport() : void{ for($tries = 0; $tries < 16; ++$tries){ - $block = $this->pos->getWorldNonNull()->getBlockAt( + $block = $this->pos->getWorld()->getBlockAt( $this->pos->x + mt_rand(-16, 16), max(0, min(World::Y_MAX - 1, $this->pos->y + mt_rand(-8, 8))), $this->pos->z + mt_rand(-16, 16) @@ -76,9 +76,9 @@ class DragonEgg extends Transparent implements Fallable{ } $blockPos = $ev->getTo(); - $this->pos->getWorldNonNull()->addParticle($this->pos, new DragonEggTeleportParticle($this->pos->x - $blockPos->x, $this->pos->y - $blockPos->y, $this->pos->z - $blockPos->z)); - $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::AIR()); - $this->pos->getWorldNonNull()->setBlock($blockPos, $this); + $this->pos->getWorld()->addParticle($this->pos, new DragonEggTeleportParticle($this->pos->x - $blockPos->x, $this->pos->y - $blockPos->y, $this->pos->z - $blockPos->z)); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); + $this->pos->getWorld()->setBlock($blockPos, $this); break; } } diff --git a/src/block/EnderChest.php b/src/block/EnderChest.php index 83eb164f6e..fbb498f9a6 100644 --- a/src/block/EnderChest.php +++ b/src/block/EnderChest.php @@ -75,7 +75,7 @@ class EnderChest extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $enderChest = $this->pos->getWorldNonNull()->getTile($this->pos); + $enderChest = $this->pos->getWorld()->getTile($this->pos); if($enderChest instanceof TileEnderChest and $this->getSide(Facing::UP)->isTransparent()){ $player->getEnderChestInventory()->setHolderPosition($this->pos); $player->setCurrentWindow($player->getEnderChestInventory()); diff --git a/src/block/Farmland.php b/src/block/Farmland.php index a18d6119fd..f715f7d815 100644 --- a/src/block/Farmland.php +++ b/src/block/Farmland.php @@ -58,7 +58,7 @@ class Farmland extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::UP)->isSolid()){ - $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::DIRT()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::DIRT()); } } @@ -70,13 +70,13 @@ class Farmland extends Transparent{ if(!$this->canHydrate()){ if($this->wetness > 0){ $this->wetness--; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this, false); + $this->pos->getWorld()->setBlock($this->pos, $this, false); }else{ - $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::DIRT()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::DIRT()); } }elseif($this->wetness < 7){ $this->wetness = 7; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this, false); + $this->pos->getWorld()->setBlock($this->pos, $this, false); } } @@ -87,7 +87,7 @@ class Farmland extends Transparent{ for($y = $start->y; $y <= $end->y; ++$y){ for($z = $start->z; $z <= $end->z; ++$z){ for($x = $start->x; $x <= $end->x; ++$x){ - if($this->pos->getWorldNonNull()->getBlockAt($x, $y, $z) instanceof Water){ + if($this->pos->getWorld()->getBlockAt($x, $y, $z) instanceof Water){ return true; } } diff --git a/src/block/FenceGate.php b/src/block/FenceGate.php index 88acabe730..8fc695e7cb 100644 --- a/src/block/FenceGate.php +++ b/src/block/FenceGate.php @@ -88,7 +88,7 @@ class FenceGate extends Transparent{ $inWall = $this->checkInWall(); if($inWall !== $this->inWall){ $this->inWall = $inWall; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } } @@ -101,8 +101,8 @@ class FenceGate extends Transparent{ } } - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); - $this->pos->getWorldNonNull()->addSound($this->pos, new DoorSound()); + $this->pos->getWorld()->setBlock($this->pos, $this); + $this->pos->getWorld()->addSound($this->pos, new DoorSound()); return true; } diff --git a/src/block/Fire.php b/src/block/Fire.php index 7adb39584f..c1b019a483 100644 --- a/src/block/Fire.php +++ b/src/block/Fire.php @@ -88,9 +88,9 @@ class Fire extends Flowable{ public function onNearbyBlockChange() : void{ if(!$this->getSide(Facing::DOWN)->isSolid() and !$this->hasAdjacentFlammableBlocks()){ - $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::AIR()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); }else{ - $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, mt_rand(30, 40)); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(30, 40)); } } @@ -124,10 +124,10 @@ class Fire extends Flowable{ } if($result !== null){ - $this->pos->getWorldNonNull()->setBlock($this->pos, $result); + $this->pos->getWorld()->setBlock($this->pos, $result); } - $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, mt_rand(30, 40)); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(30, 40)); if($canSpread){ //TODO: raise upper bound for chance in humid biomes @@ -168,9 +168,9 @@ class Fire extends Flowable{ if(mt_rand(0, $this->age + 9) < 5){ //TODO: check rain $fire = clone $this; $fire->age = min(15, $fire->age + (mt_rand(0, 4) >> 2)); - $this->pos->getWorldNonNull()->setBlock($block->pos, $fire); + $this->pos->getWorld()->setBlock($block->pos, $fire); }else{ - $this->pos->getWorldNonNull()->setBlock($block->pos, VanillaBlocks::AIR()); + $this->pos->getWorld()->setBlock($block->pos, VanillaBlocks::AIR()); } } } diff --git a/src/block/Flower.php b/src/block/Flower.php index da81a90d27..5640085855 100644 --- a/src/block/Flower.php +++ b/src/block/Flower.php @@ -46,7 +46,7 @@ class Flower extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/FlowerPot.php b/src/block/FlowerPot.php index a60e8bc09f..d547bf0b5e 100644 --- a/src/block/FlowerPot.php +++ b/src/block/FlowerPot.php @@ -61,7 +61,7 @@ class FlowerPot extends Flowable{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->pos->getWorldNonNull()->getTile($this->pos); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileFlowerPot){ $this->setPlant($tile->getPlant()); }else{ @@ -72,7 +72,7 @@ class FlowerPot extends Flowable{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->pos->getWorldNonNull()->getTile($this->pos); + $tile = $this->pos->getWorld()->getTile($this->pos); assert($tile instanceof TileFlowerPot); $tile->setPlant($this->plant); } @@ -122,7 +122,7 @@ class FlowerPot extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } @@ -134,7 +134,7 @@ class FlowerPot extends Flowable{ $this->setPlant($plant); $item->pop(); - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); return true; } diff --git a/src/block/FrostedIce.php b/src/block/FrostedIce.php index 2f140cad81..9d957d5fcf 100644 --- a/src/block/FrostedIce.php +++ b/src/block/FrostedIce.php @@ -50,17 +50,17 @@ class FrostedIce extends Ice{ public function onNearbyBlockChange() : void{ if(!$this->checkAdjacentBlocks(2)){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); }else{ - $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, mt_rand(20, 40)); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(20, 40)); } } public function onRandomTick() : void{ if((!$this->checkAdjacentBlocks(4) or mt_rand(0, 2) === 0) and max( //TODO: move this to World - $this->pos->getWorldNonNull()->getHighestAdjacentBlockLight($this->pos->x, $this->pos->y, $this->pos->z), - $this->pos->getWorldNonNull()->getHighestAdjacentBlockSkyLight($this->pos->x, $this->pos->y, $this->pos->z) - $this->pos->getWorldNonNull()->getSkyLightReduction() + $this->pos->getWorld()->getHighestAdjacentBlockLight($this->pos->x, $this->pos->y, $this->pos->z), + $this->pos->getWorld()->getHighestAdjacentBlockSkyLight($this->pos->x, $this->pos->y, $this->pos->z) - $this->pos->getWorld()->getSkyLightReduction() ) >= 12 - $this->age){ if($this->tryMelt()){ foreach($this->getAllSides() as $block){ @@ -70,7 +70,7 @@ class FrostedIce extends Ice{ } } }else{ - $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, mt_rand(20, 40)); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(20, 40)); } } @@ -86,7 +86,7 @@ class FrostedIce extends Ice{ continue; } if( - $this->pos->getWorldNonNull()->getBlockAt($this->pos->x + $x, $this->pos->y, $this->pos->z + $z) instanceof FrostedIce and + $this->pos->getWorld()->getBlockAt($this->pos->x + $x, $this->pos->y, $this->pos->z + $z) instanceof FrostedIce and ++$found >= $requirement ){ return true; @@ -103,13 +103,13 @@ class FrostedIce extends Ice{ */ private function tryMelt() : bool{ if($this->age >= 3){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); return true; } $this->age++; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); - $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, mt_rand(20, 40)); + $this->pos->getWorld()->setBlock($this->pos, $this); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(20, 40)); return false; } } diff --git a/src/block/Furnace.php b/src/block/Furnace.php index f7444dab5f..70ffde36d5 100644 --- a/src/block/Furnace.php +++ b/src/block/Furnace.php @@ -88,7 +88,7 @@ class Furnace extends Opaque{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $furnace = $this->pos->getWorldNonNull()->getTile($this->pos); + $furnace = $this->pos->getWorld()->getTile($this->pos); if($furnace instanceof TileFurnace and $furnace->canOpenWith($item->getCustomName())){ $player->setCurrentWindow($furnace->getInventory()); } @@ -98,9 +98,9 @@ class Furnace extends Opaque{ } public function onScheduledUpdate() : void{ - $furnace = $this->pos->getWorldNonNull()->getTile($this->pos); + $furnace = $this->pos->getWorld()->getTile($this->pos); if($furnace instanceof TileFurnace and $furnace->onUpdate()){ - $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, 1); //TODO: check this + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 1); //TODO: check this } } } diff --git a/src/block/Grass.php b/src/block/Grass.php index 67bbcfb0f3..becdf86de2 100644 --- a/src/block/Grass.php +++ b/src/block/Grass.php @@ -56,13 +56,13 @@ class Grass extends Opaque{ } public function onRandomTick() : void{ - $lightAbove = $this->pos->getWorldNonNull()->getFullLightAt($this->pos->x, $this->pos->y + 1, $this->pos->z); - if($lightAbove < 4 and $this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z)->getLightFilter() >= 2){ + $lightAbove = $this->pos->getWorld()->getFullLightAt($this->pos->x, $this->pos->y + 1, $this->pos->z); + if($lightAbove < 4 and $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z)->getLightFilter() >= 2){ //grass dies $ev = new BlockSpreadEvent($this, $this, VanillaBlocks::DIRT()); $ev->call(); if(!$ev->isCancelled()){ - $this->pos->getWorldNonNull()->setBlock($this->pos, $ev->getNewState(), false); + $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState(), false); } }elseif($lightAbove >= 9){ //try grass spread @@ -71,12 +71,12 @@ class Grass extends Opaque{ $y = mt_rand($this->pos->y - 3, $this->pos->y + 1); $z = mt_rand($this->pos->z - 1, $this->pos->z + 1); - $b = $this->pos->getWorldNonNull()->getBlockAt($x, $y, $z); + $b = $this->pos->getWorld()->getBlockAt($x, $y, $z); if( !($b instanceof Dirt) or $b instanceof CoarseDirt or - $this->pos->getWorldNonNull()->getFullLightAt($x, $y + 1, $z) < 4 or - $this->pos->getWorldNonNull()->getBlockAt($x, $y + 1, $z)->getLightFilter() >= 2 + $this->pos->getWorld()->getFullLightAt($x, $y + 1, $z) < 4 or + $this->pos->getWorld()->getBlockAt($x, $y + 1, $z)->getLightFilter() >= 2 ){ continue; } @@ -84,7 +84,7 @@ class Grass extends Opaque{ $ev = new BlockSpreadEvent($b, $this, VanillaBlocks::GRASS()); $ev->call(); if(!$ev->isCancelled()){ - $this->pos->getWorldNonNull()->setBlock($b->pos, $ev->getNewState(), false); + $this->pos->getWorld()->setBlock($b->pos, $ev->getNewState(), false); } } } @@ -96,17 +96,17 @@ class Grass extends Opaque{ } if($item instanceof Fertilizer){ $item->pop(); - TallGrassObject::growGrass($this->pos->getWorldNonNull(), $this->pos, new Random(mt_rand()), 8, 2); + TallGrassObject::growGrass($this->pos->getWorld(), $this->pos, new Random(mt_rand()), 8, 2); return true; }elseif($item instanceof Hoe){ $item->applyDamage(1); - $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::FARMLAND()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::FARMLAND()); return true; }elseif($item instanceof Shovel and $this->getSide(Facing::UP)->getId() === BlockLegacyIds::AIR){ $item->applyDamage(1); - $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::GRASS_PATH()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::GRASS_PATH()); return true; } diff --git a/src/block/GrassPath.php b/src/block/GrassPath.php index 011d0525b9..f94fcba542 100644 --- a/src/block/GrassPath.php +++ b/src/block/GrassPath.php @@ -42,7 +42,7 @@ class GrassPath extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::UP)->isSolid()){ - $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::DIRT()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::DIRT()); } } diff --git a/src/block/Hopper.php b/src/block/Hopper.php index cb402bc285..be6a4b6de2 100644 --- a/src/block/Hopper.php +++ b/src/block/Hopper.php @@ -76,7 +76,7 @@ class Hopper extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ - $tile = $this->pos->getWorldNonNull()->getTile($this->pos); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileHopper){ //TODO: find a way to have inventories open on click without this boilerplate in every block $player->setCurrentWindow($tile->getInventory()); } diff --git a/src/block/Ice.php b/src/block/Ice.php index b825991ab0..ef29179971 100644 --- a/src/block/Ice.php +++ b/src/block/Ice.php @@ -43,7 +43,7 @@ class Ice extends Transparent{ public function onBreak(Item $item, ?Player $player = null) : bool{ if(($player === null or $player->isSurvival()) and !$item->hasEnchantment(Enchantment::SILK_TOUCH())){ - $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::WATER()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::WATER()); return true; } return parent::onBreak($item, $player); @@ -54,8 +54,8 @@ class Ice extends Transparent{ } public function onRandomTick() : void{ - if($this->pos->getWorldNonNull()->getHighestAdjacentBlockLight($this->pos->x, $this->pos->y, $this->pos->z) >= 12){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + if($this->pos->getWorld()->getHighestAdjacentBlockLight($this->pos->x, $this->pos->y, $this->pos->z) >= 12){ + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/ItemFrame.php b/src/block/ItemFrame.php index 621e322508..084030dd8f 100644 --- a/src/block/ItemFrame.php +++ b/src/block/ItemFrame.php @@ -61,7 +61,7 @@ class ItemFrame extends Flowable{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->pos->getWorldNonNull()->getTile($this->pos); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileItemFrame){ $this->framedItem = $tile->getItem(); if($this->framedItem->isNull()){ @@ -74,7 +74,7 @@ class ItemFrame extends Flowable{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->pos->getWorldNonNull()->getTile($this->pos); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileItemFrame){ $tile->setItem($this->framedItem); $tile->setItemRotation($this->itemRotation); @@ -132,7 +132,7 @@ class ItemFrame extends Flowable{ return true; } - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); return true; } @@ -142,16 +142,16 @@ class ItemFrame extends Flowable{ return false; } if(lcg_value() <= $this->itemDropChance){ - $this->pos->getWorldNonNull()->dropItem($this->pos->add(0.5, 0.5, 0.5), clone $this->framedItem); + $this->pos->getWorld()->dropItem($this->pos->add(0.5, 0.5, 0.5), clone $this->framedItem); } $this->setFramedItem(null); - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); return true; } public function onNearbyBlockChange() : void{ if(!$this->getSide(Facing::opposite($this->facing))->isSolid()){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/Ladder.php b/src/block/Ladder.php index 5d74adaa89..8ff08707e1 100644 --- a/src/block/Ladder.php +++ b/src/block/Ladder.php @@ -90,7 +90,7 @@ class Ladder extends Transparent{ public function onNearbyBlockChange() : void{ if(!$this->getSide(Facing::opposite($this->facing))->isSolid()){ //Replace with common break method - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } } diff --git a/src/block/Lantern.php b/src/block/Lantern.php index 99a441bc31..7f5d790c58 100644 --- a/src/block/Lantern.php +++ b/src/block/Lantern.php @@ -69,17 +69,17 @@ class Lantern extends Transparent{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canAttachTo($this->pos->getWorldNonNull()->getBlock($blockReplace->getPos()->up())) and !$this->canAttachTo($this->pos->getWorldNonNull()->getBlock($blockReplace->getPos()->down()))){ + if(!$this->canAttachTo($this->pos->getWorld()->getBlock($blockReplace->getPos()->up())) and !$this->canAttachTo($this->pos->getWorld()->getBlock($blockReplace->getPos()->down()))){ return false; } - $this->hanging = ($face === Facing::DOWN or !$this->canAttachTo($this->pos->getWorldNonNull()->getBlock($blockReplace->getPos()->down()))); + $this->hanging = ($face === Facing::DOWN or !$this->canAttachTo($this->pos->getWorld()->getBlock($blockReplace->getPos()->down()))); return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onNearbyBlockChange() : void{ - if(!$this->canAttachTo($this->pos->getWorldNonNull()->getBlock($this->hanging ? $this->pos->up() : $this->pos->down()))){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + if(!$this->canAttachTo($this->pos->getWorld()->getBlock($this->hanging ? $this->pos->up() : $this->pos->down()))){ + $this->pos->getWorld()->useBreakOn($this->pos); } } } diff --git a/src/block/Leaves.php b/src/block/Leaves.php index 07bd70ff0c..27da9fa7d8 100644 --- a/src/block/Leaves.php +++ b/src/block/Leaves.php @@ -78,7 +78,7 @@ class Leaves extends Transparent{ } $visited[$index] = true; - $block = $this->pos->getWorldNonNull()->getBlock($pos); + $block = $this->pos->getWorld()->getBlock($pos); if($block instanceof Wood){ //type doesn't matter return true; } @@ -97,7 +97,7 @@ class Leaves extends Transparent{ public function onNearbyBlockChange() : void{ if(!$this->noDecay and !$this->checkDecay){ $this->checkDecay = true; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this, false); + $this->pos->getWorld()->setBlock($this->pos, $this, false); } } @@ -111,9 +111,9 @@ class Leaves extends Transparent{ $ev->call(); if($ev->isCancelled() or $this->findLog($this->pos)){ $this->checkDecay = false; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this, false); + $this->pos->getWorld()->setBlock($this->pos, $this, false); }else{ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } } diff --git a/src/block/Lever.php b/src/block/Lever.php index 67c65e899c..d4d7bf6f50 100644 --- a/src/block/Lever.php +++ b/src/block/Lever.php @@ -107,14 +107,14 @@ class Lever extends Flowable{ } if(!$this->getSide($face)->isSolid()){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->powered = !$this->powered; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); - $this->pos->getWorldNonNull()->addSound( + $this->pos->getWorld()->setBlock($this->pos, $this); + $this->pos->getWorld()->addSound( $this->pos->add(0.5, 0.5, 0.5), $this->powered ? new RedstonePowerOnSound() : new RedstonePowerOffSound() ); diff --git a/src/block/Liquid.php b/src/block/Liquid.php index 195b62529a..ac7b5a95f0 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -188,7 +188,7 @@ abstract class Liquid extends Transparent{ ++$z; } - $sideBlock = $this->pos->getWorldNonNull()->getBlockAt($x, $y, $z); + $sideBlock = $this->pos->getWorld()->getBlockAt($x, $y, $z); $blockDecay = $this->getEffectiveFlowDecay($sideBlock); if($blockDecay < 0){ @@ -196,7 +196,7 @@ abstract class Liquid extends Transparent{ continue; } - $blockDecay = $this->getEffectiveFlowDecay($this->pos->getWorldNonNull()->getBlockAt($x, $y - 1, $z)); + $blockDecay = $this->getEffectiveFlowDecay($this->pos->getWorld()->getBlockAt($x, $y - 1, $z)); if($blockDecay >= 0){ $realDecay = $blockDecay - ($decay - 8); @@ -218,14 +218,14 @@ abstract class Liquid extends Transparent{ if($this->falling){ if( - !$this->canFlowInto($this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1)) or - !$this->canFlowInto($this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z + 1)) or - !$this->canFlowInto($this->pos->getWorldNonNull()->getBlockAt($this->pos->x - 1, $this->pos->y, $this->pos->z)) or - !$this->canFlowInto($this->pos->getWorldNonNull()->getBlockAt($this->pos->x + 1, $this->pos->y, $this->pos->z)) or - !$this->canFlowInto($this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z - 1)) or - !$this->canFlowInto($this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z + 1)) or - !$this->canFlowInto($this->pos->getWorldNonNull()->getBlockAt($this->pos->x - 1, $this->pos->y + 1, $this->pos->z)) or - !$this->canFlowInto($this->pos->getWorldNonNull()->getBlockAt($this->pos->x + 1, $this->pos->y + 1, $this->pos->z)) + !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1)) or + !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z + 1)) or + !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x - 1, $this->pos->y, $this->pos->z)) or + !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x + 1, $this->pos->y, $this->pos->z)) or + !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z - 1)) or + !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z + 1)) or + !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x - 1, $this->pos->y + 1, $this->pos->z)) or + !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x + 1, $this->pos->y + 1, $this->pos->z)) ){ $vector = $vector->normalize()->add(0, -6, 0); } @@ -252,7 +252,7 @@ abstract class Liquid extends Transparent{ public function onNearbyBlockChange() : void{ if(!$this->checkForHarden()){ - $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, $this->tickRate()); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, $this->tickRate()); } } @@ -262,10 +262,10 @@ abstract class Liquid extends Transparent{ if(!$this->isSource()){ $smallestFlowDecay = -100; $this->adjacentSources = 0; - $smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1), $smallestFlowDecay); - $smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z + 1), $smallestFlowDecay); - $smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorldNonNull()->getBlockAt($this->pos->x - 1, $this->pos->y, $this->pos->z), $smallestFlowDecay); - $smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorldNonNull()->getBlockAt($this->pos->x + 1, $this->pos->y, $this->pos->z), $smallestFlowDecay); + $smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1), $smallestFlowDecay); + $smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z + 1), $smallestFlowDecay); + $smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorld()->getBlockAt($this->pos->x - 1, $this->pos->y, $this->pos->z), $smallestFlowDecay); + $smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorld()->getBlockAt($this->pos->x + 1, $this->pos->y, $this->pos->z), $smallestFlowDecay); $newDecay = $smallestFlowDecay + $multiplier; $falling = false; @@ -274,12 +274,12 @@ abstract class Liquid extends Transparent{ $newDecay = -1; } - if($this->getEffectiveFlowDecay($this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z)) >= 0){ + if($this->getEffectiveFlowDecay($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z)) >= 0){ $falling = true; } if($this->adjacentSources >= 2 and $this instanceof Water){ - $bottomBlock = $this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y - 1, $this->pos->z); + $bottomBlock = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y - 1, $this->pos->z); if($bottomBlock->isSolid() or ($bottomBlock instanceof Water and $bottomBlock->isSource())){ $newDecay = 0; $falling = false; @@ -288,17 +288,17 @@ abstract class Liquid extends Transparent{ if($falling !== $this->falling or (!$falling and $newDecay !== $this->decay)){ if(!$falling and $newDecay < 0){ - $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::AIR()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); return; } $this->falling = $falling; $this->decay = $falling ? 0 : $newDecay; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); //local block update will cause an update to be scheduled + $this->pos->getWorld()->setBlock($this->pos, $this); //local block update will cause an update to be scheduled } } - $bottomBlock = $this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y - 1, $this->pos->z); + $bottomBlock = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y - 1, $this->pos->z); $this->flowIntoBlock($bottomBlock, 0, true); @@ -313,19 +313,19 @@ abstract class Liquid extends Transparent{ $flags = $this->getOptimalFlowDirections(); if($flags[0]){ - $this->flowIntoBlock($this->pos->getWorldNonNull()->getBlockAt($this->pos->x - 1, $this->pos->y, $this->pos->z), $adjacentDecay, false); + $this->flowIntoBlock($this->pos->getWorld()->getBlockAt($this->pos->x - 1, $this->pos->y, $this->pos->z), $adjacentDecay, false); } if($flags[1]){ - $this->flowIntoBlock($this->pos->getWorldNonNull()->getBlockAt($this->pos->x + 1, $this->pos->y, $this->pos->z), $adjacentDecay, false); + $this->flowIntoBlock($this->pos->getWorld()->getBlockAt($this->pos->x + 1, $this->pos->y, $this->pos->z), $adjacentDecay, false); } if($flags[2]){ - $this->flowIntoBlock($this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1), $adjacentDecay, false); + $this->flowIntoBlock($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1), $adjacentDecay, false); } if($flags[3]){ - $this->flowIntoBlock($this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z + 1), $adjacentDecay, false); + $this->flowIntoBlock($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z + 1), $adjacentDecay, false); } } } @@ -343,10 +343,10 @@ abstract class Liquid extends Transparent{ $ev->call(); if(!$ev->isCancelled()){ if($block->getId() > 0){ - $this->pos->getWorldNonNull()->useBreakOn($block->pos); + $this->pos->getWorld()->useBreakOn($block->pos); } - $this->pos->getWorldNonNull()->setBlock($block->pos, $ev->getNewState()); + $this->pos->getWorld()->setBlock($block->pos, $ev->getNewState()); } } } @@ -374,10 +374,10 @@ abstract class Liquid extends Transparent{ } if(!isset($this->flowCostVisited[$hash = World::blockHash($x, $y, $z)])){ - $blockSide = $this->pos->getWorldNonNull()->getBlockAt($x, $y, $z); + $blockSide = $this->pos->getWorld()->getBlockAt($x, $y, $z); if(!$this->canFlowInto($blockSide)){ $this->flowCostVisited[$hash] = self::BLOCKED; - }elseif($this->pos->getWorldNonNull()->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ + }elseif($this->pos->getWorld()->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ $this->flowCostVisited[$hash] = self::CAN_FLOW_DOWN; }else{ $this->flowCostVisited[$hash] = self::CAN_FLOW; @@ -426,12 +426,12 @@ abstract class Liquid extends Transparent{ }elseif($j === 3){ ++$z; } - $block = $this->pos->getWorldNonNull()->getBlockAt($x, $y, $z); + $block = $this->pos->getWorld()->getBlockAt($x, $y, $z); if(!$this->canFlowInto($block)){ $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::BLOCKED; continue; - }elseif($this->pos->getWorldNonNull()->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ + }elseif($this->pos->getWorld()->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::CAN_FLOW_DOWN; $flowCost[$j] = $maxCost = 0; }elseif($maxCost > 0){ @@ -478,13 +478,13 @@ abstract class Liquid extends Transparent{ $ev = new BlockFormEvent($this, $result); $ev->call(); if(!$ev->isCancelled()){ - $this->pos->getWorldNonNull()->setBlock($this->pos, $ev->getNewState()); - $this->pos->getWorldNonNull()->addSound($this->pos->add(0.5, 0.5, 0.5), new FizzSound(2.6 + (lcg_value() - lcg_value()) * 0.8)); + $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); + $this->pos->getWorld()->addSound($this->pos->add(0.5, 0.5, 0.5), new FizzSound(2.6 + (lcg_value() - lcg_value()) * 0.8)); } return true; } protected function canFlowInto(Block $block) : bool{ - return $this->pos->getWorldNonNull()->isInWorld($block->pos->x, $block->pos->y, $block->pos->z) and $block->canBeFlowedInto() and !($block instanceof Liquid and $block->isSource()); //TODO: I think this should only be liquids of the same type + return $this->pos->getWorld()->isInWorld($block->pos->x, $block->pos->y, $block->pos->z) and $block->canBeFlowedInto() and !($block instanceof Liquid and $block->isSource()); //TODO: I think this should only be liquids of the same type } } diff --git a/src/block/Mycelium.php b/src/block/Mycelium.php index d3dce32f9f..8308875efb 100644 --- a/src/block/Mycelium.php +++ b/src/block/Mycelium.php @@ -53,13 +53,13 @@ class Mycelium extends Opaque{ $x = mt_rand($this->pos->x - 1, $this->pos->x + 1); $y = mt_rand($this->pos->y - 2, $this->pos->y + 2); $z = mt_rand($this->pos->z - 1, $this->pos->z + 1); - $block = $this->pos->getWorldNonNull()->getBlockAt($x, $y, $z); + $block = $this->pos->getWorld()->getBlockAt($x, $y, $z); if($block->getId() === BlockLegacyIds::DIRT){ if($block->getSide(Facing::UP) instanceof Transparent){ $ev = new BlockSpreadEvent($block, $this, VanillaBlocks::MYCELIUM()); $ev->call(); if(!$ev->isCancelled()){ - $this->pos->getWorldNonNull()->setBlock($block->pos, $ev->getNewState()); + $this->pos->getWorld()->setBlock($block->pos, $ev->getNewState()); } } } diff --git a/src/block/NetherWartPlant.php b/src/block/NetherWartPlant.php index da44b7bde3..7ca38d72f4 100644 --- a/src/block/NetherWartPlant.php +++ b/src/block/NetherWartPlant.php @@ -64,7 +64,7 @@ class NetherWartPlant extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::SOUL_SAND){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } @@ -79,7 +79,7 @@ class NetherWartPlant extends Flowable{ $ev = new BlockGrowEvent($this, $block); $ev->call(); if(!$ev->isCancelled()){ - $this->pos->getWorldNonNull()->setBlock($this->pos, $ev->getNewState()); + $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); } } } diff --git a/src/block/Note.php b/src/block/Note.php index 54fcf7a1d0..3e027c220b 100644 --- a/src/block/Note.php +++ b/src/block/Note.php @@ -39,7 +39,7 @@ class Note extends Opaque{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->pos->getWorldNonNull()->getTile($this->pos); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileNote){ $this->pitch = $tile->getPitch(); }else{ @@ -49,7 +49,7 @@ class Note extends Opaque{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->pos->getWorldNonNull()->getTile($this->pos); + $tile = $this->pos->getWorld()->getTile($this->pos); assert($tile instanceof TileNote); $tile->setPitch($this->pitch); } diff --git a/src/block/RedMushroom.php b/src/block/RedMushroom.php index c5e643f21b..72d3bb5ec7 100644 --- a/src/block/RedMushroom.php +++ b/src/block/RedMushroom.php @@ -41,7 +41,7 @@ class RedMushroom extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/RedstoneComparator.php b/src/block/RedstoneComparator.php index cae56d03fb..7372ab99a2 100644 --- a/src/block/RedstoneComparator.php +++ b/src/block/RedstoneComparator.php @@ -72,7 +72,7 @@ class RedstoneComparator extends Flowable{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->pos->getWorldNonNull()->getTile($this->pos); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof Comparator){ $this->signalStrength = $tile->getSignalStrength(); } @@ -80,7 +80,7 @@ class RedstoneComparator extends Flowable{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->pos->getWorldNonNull()->getTile($this->pos); + $tile = $this->pos->getWorld()->getTile($this->pos); assert($tile instanceof Comparator); $tile->setSignalStrength($this->signalStrength); } @@ -143,13 +143,13 @@ class RedstoneComparator extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->isSubtractMode = !$this->isSubtractMode; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); return true; } public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/RedstoneOre.php b/src/block/RedstoneOre.php index 5981b19ad3..9cfb07da57 100644 --- a/src/block/RedstoneOre.php +++ b/src/block/RedstoneOre.php @@ -68,7 +68,7 @@ class RedstoneOre extends Opaque{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$this->lit){ $this->lit = true; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); //no return here - this shouldn't prevent block placement + $this->pos->getWorld()->setBlock($this->pos, $this); //no return here - this shouldn't prevent block placement } return false; } @@ -76,7 +76,7 @@ class RedstoneOre extends Opaque{ public function onNearbyBlockChange() : void{ if(!$this->lit){ $this->lit = true; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } } @@ -87,7 +87,7 @@ class RedstoneOre extends Opaque{ public function onRandomTick() : void{ if($this->lit){ $this->lit = false; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } } diff --git a/src/block/RedstoneRepeater.php b/src/block/RedstoneRepeater.php index af15cc322a..82af3f53d1 100644 --- a/src/block/RedstoneRepeater.php +++ b/src/block/RedstoneRepeater.php @@ -99,13 +99,13 @@ class RedstoneRepeater extends Flowable{ if(++$this->delay > 4){ $this->delay = 1; } - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); return true; } public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/Sapling.php b/src/block/Sapling.php index c6e8a227fc..8b0e74f542 100644 --- a/src/block/Sapling.php +++ b/src/block/Sapling.php @@ -69,7 +69,7 @@ class Sapling extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof Fertilizer){ - Tree::growTree($this->pos->getWorldNonNull(), $this->pos->x, $this->pos->y, $this->pos->z, new Random(mt_rand()), $this->treeType); + Tree::growTree($this->pos->getWorld(), $this->pos->x, $this->pos->y, $this->pos->z, new Random(mt_rand()), $this->treeType); $item->pop(); @@ -81,7 +81,7 @@ class Sapling extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } @@ -90,12 +90,12 @@ class Sapling extends Flowable{ } public function onRandomTick() : void{ - if($this->pos->getWorldNonNull()->getFullLightAt($this->pos->x, $this->pos->y, $this->pos->z) >= 8 and mt_rand(1, 7) === 1){ + if($this->pos->getWorld()->getFullLightAt($this->pos->x, $this->pos->y, $this->pos->z) >= 8 and mt_rand(1, 7) === 1){ if($this->ready){ - Tree::growTree($this->pos->getWorldNonNull(), $this->pos->x, $this->pos->y, $this->pos->z, new Random(mt_rand()), $this->treeType); + Tree::growTree($this->pos->getWorld(), $this->pos->x, $this->pos->y, $this->pos->z, new Random(mt_rand()), $this->treeType); }else{ $this->ready = true; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } } } diff --git a/src/block/Sign.php b/src/block/Sign.php index 6c137a222c..17bad1f3ac 100644 --- a/src/block/Sign.php +++ b/src/block/Sign.php @@ -86,7 +86,7 @@ class Sign extends Transparent{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->pos->getWorldNonNull()->getTile($this->pos); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileSign){ $this->text = $tile->getText(); } @@ -94,7 +94,7 @@ class Sign extends Transparent{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->pos->getWorldNonNull()->getTile($this->pos); + $tile = $this->pos->getWorld()->getTile($this->pos); assert($tile instanceof TileSign); $tile->setText($this->text); } @@ -129,7 +129,7 @@ class Sign extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::opposite($this->facing))->getId() === BlockLegacyIds::AIR){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } @@ -161,7 +161,7 @@ class Sign extends Transparent{ $ev->call(); if(!$ev->isCancelled()){ $this->text = clone $ev->getNewText(); - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); return true; } diff --git a/src/block/Skull.php b/src/block/Skull.php index 1aaeda4e05..8b60f5deab 100644 --- a/src/block/Skull.php +++ b/src/block/Skull.php @@ -67,7 +67,7 @@ class Skull extends Flowable{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->pos->getWorldNonNull()->getTile($this->pos); + $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileSkull){ $this->skullType = $tile->getSkullType(); $this->rotation = $tile->getRotation(); @@ -77,7 +77,7 @@ class Skull extends Flowable{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); //extra block properties storage hack - $tile = $this->pos->getWorldNonNull()->getTile($this->pos); + $tile = $this->pos->getWorld()->getTile($this->pos); assert($tile instanceof TileSkull); $tile->setRotation($this->rotation); $tile->setSkullType($this->skullType); diff --git a/src/block/SnowLayer.php b/src/block/SnowLayer.php index fb225f491a..228ebb5f04 100644 --- a/src/block/SnowLayer.php +++ b/src/block/SnowLayer.php @@ -94,8 +94,8 @@ class SnowLayer extends Flowable implements Fallable{ } public function onRandomTick() : void{ - if($this->pos->getWorldNonNull()->getBlockLightAt($this->pos->x, $this->pos->y, $this->pos->z) >= 12){ - $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::AIR(), false); + if($this->pos->getWorld()->getBlockLightAt($this->pos->x, $this->pos->y, $this->pos->z) >= 12){ + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR(), false); } } diff --git a/src/block/Stem.php b/src/block/Stem.php index 66a9e62680..6ef52f1658 100644 --- a/src/block/Stem.php +++ b/src/block/Stem.php @@ -45,7 +45,7 @@ abstract class Stem extends Crops{ $ev = new BlockGrowEvent($this, $block); $ev->call(); if(!$ev->isCancelled()){ - $this->pos->getWorldNonNull()->setBlock($this->pos, $ev->getNewState()); + $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); } }else{ $grow = $this->getPlant(); @@ -61,7 +61,7 @@ abstract class Stem extends Crops{ $ev = new BlockGrowEvent($side, $grow); $ev->call(); if(!$ev->isCancelled()){ - $this->pos->getWorldNonNull()->setBlock($side->pos, $ev->getNewState()); + $this->pos->getWorld()->setBlock($side->pos, $ev->getNewState()); } } } diff --git a/src/block/Sugarcane.php b/src/block/Sugarcane.php index bc90d89ae9..d3444052f3 100644 --- a/src/block/Sugarcane.php +++ b/src/block/Sugarcane.php @@ -57,20 +57,20 @@ class Sugarcane extends Flowable{ if($item instanceof Fertilizer){ if(!$this->getSide(Facing::DOWN)->isSameType($this)){ for($y = 1; $y < 3; ++$y){ - $b = $this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z); + $b = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z); if($b->getId() === BlockLegacyIds::AIR){ $ev = new BlockGrowEvent($b, VanillaBlocks::SUGARCANE()); $ev->call(); if($ev->isCancelled()){ break; } - $this->pos->getWorldNonNull()->setBlock($b->pos, $ev->getNewState()); + $this->pos->getWorld()->setBlock($b->pos, $ev->getNewState()); }else{ break; } } $this->age = 0; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } $item->pop(); @@ -84,7 +84,7 @@ class Sugarcane extends Flowable{ public function onNearbyBlockChange() : void{ $down = $this->getSide(Facing::DOWN); if($down->isTransparent() and !$down->isSameType($this)){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } @@ -96,17 +96,17 @@ class Sugarcane extends Flowable{ if(!$this->getSide(Facing::DOWN)->isSameType($this)){ if($this->age === 15){ for($y = 1; $y < 3; ++$y){ - $b = $this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z); + $b = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z); if($b->getId() === BlockLegacyIds::AIR){ - $this->pos->getWorldNonNull()->setBlock($b->pos, VanillaBlocks::SUGARCANE()); + $this->pos->getWorld()->setBlock($b->pos, VanillaBlocks::SUGARCANE()); break; } } $this->age = 0; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); }else{ ++$this->age; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } } } diff --git a/src/block/TNT.php b/src/block/TNT.php index a07634d54d..201b5c5dc0 100644 --- a/src/block/TNT.php +++ b/src/block/TNT.php @@ -90,11 +90,11 @@ class TNT extends Opaque{ } public function ignite(int $fuse = 80) : void{ - $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::AIR()); + $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); $mot = (new Random())->nextSignedFloat() * M_PI * 2; - $tnt = new PrimedTNT(Location::fromObject($this->pos->add(0.5, 0, 0.5), $this->pos->getWorldNonNull())); + $tnt = new PrimedTNT(Location::fromObject($this->pos->add(0.5, 0, 0.5), $this->pos->getWorld())); $tnt->setFuse($fuse); $tnt->setMotion(new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02)); diff --git a/src/block/TallGrass.php b/src/block/TallGrass.php index 99880c4462..88b3ac6cee 100644 --- a/src/block/TallGrass.php +++ b/src/block/TallGrass.php @@ -52,7 +52,7 @@ class TallGrass extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ //Replace with common break method - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/Torch.php b/src/block/Torch.php index f97ef7d2ce..001fbba6f4 100644 --- a/src/block/Torch.php +++ b/src/block/Torch.php @@ -60,7 +60,7 @@ class Torch extends Flowable{ $face = Facing::opposite($this->facing); if($this->getSide($face)->isTransparent() and !($face === Facing::DOWN and ($below->getId() === BlockLegacyIds::FENCE or $below->getId() === BlockLegacyIds::COBBLESTONE_WALL))){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/Trapdoor.php b/src/block/Trapdoor.php index b0205dadb3..ab1d75f538 100644 --- a/src/block/Trapdoor.php +++ b/src/block/Trapdoor.php @@ -77,8 +77,8 @@ class Trapdoor extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->open = !$this->open; - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); - $this->pos->getWorldNonNull()->addSound($this->pos, new DoorSound()); + $this->pos->getWorld()->setBlock($this->pos, $this); + $this->pos->getWorld()->addSound($this->pos, new DoorSound()); return true; } } diff --git a/src/block/Vine.php b/src/block/Vine.php index 9af86636b2..b590c740d6 100644 --- a/src/block/Vine.php +++ b/src/block/Vine.php @@ -115,9 +115,9 @@ class Vine extends Flowable{ if($changed){ if(count($this->faces) === 0){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); }else{ - $this->pos->getWorldNonNull()->setBlock($this->pos, $this); + $this->pos->getWorld()->setBlock($this->pos, $this); } } } diff --git a/src/block/WaterLily.php b/src/block/WaterLily.php index 87abbc5e53..e4648d3781 100644 --- a/src/block/WaterLily.php +++ b/src/block/WaterLily.php @@ -56,7 +56,7 @@ class WaterLily extends Flowable{ public function onNearbyBlockChange() : void{ if(!($this->getSide(Facing::DOWN) instanceof Water)){ - $this->pos->getWorldNonNull()->useBreakOn($this->pos); + $this->pos->getWorld()->useBreakOn($this->pos); } } } diff --git a/src/block/inventory/ChestInventory.php b/src/block/inventory/ChestInventory.php index 377703ebd1..5675f28b75 100644 --- a/src/block/inventory/ChestInventory.php +++ b/src/block/inventory/ChestInventory.php @@ -51,7 +51,7 @@ class ChestInventory extends BlockInventory{ if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){ //TODO: this crap really shouldn't be managed by the inventory $this->broadcastBlockEventPacket(true); - $this->getHolder()->getWorldNonNull()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getOpenSound()); + $this->getHolder()->getWorld()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getOpenSound()); } } @@ -59,7 +59,7 @@ class ChestInventory extends BlockInventory{ if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){ //TODO: this crap really shouldn't be managed by the inventory $this->broadcastBlockEventPacket(false); - $this->getHolder()->getWorldNonNull()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getCloseSound()); + $this->getHolder()->getWorld()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getCloseSound()); } parent::onClose($who); } @@ -68,6 +68,6 @@ class ChestInventory extends BlockInventory{ $holder = $this->getHolder(); //event ID is always 1 for a chest - $holder->getWorldNonNull()->broadcastPacketToViewers($holder, BlockEventPacket::create(1, $isOpen ? 1 : 0, $holder->asVector3())); + $holder->getWorld()->broadcastPacketToViewers($holder, BlockEventPacket::create(1, $isOpen ? 1 : 0, $holder->asVector3())); } } diff --git a/src/block/tile/BrewingStand.php b/src/block/tile/BrewingStand.php index d6571f6301..8977d36b19 100644 --- a/src/block/tile/BrewingStand.php +++ b/src/block/tile/BrewingStand.php @@ -55,7 +55,7 @@ class BrewingStand extends Spawnable implements Container, Nameable{ parent::__construct($world, $pos); $this->inventory = new BrewingStandInventory($this->pos); $this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange(function(Inventory $unused) : void{ - $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, 1); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 1); })); } diff --git a/src/block/tile/Chest.php b/src/block/tile/Chest.php index e197685e43..896cafead3 100644 --- a/src/block/tile/Chest.php +++ b/src/block/tile/Chest.php @@ -99,7 +99,7 @@ class Chest extends Spawnable implements Container, Nameable{ $this->inventory->removeAllViewers(); if($this->doubleInventory !== null){ - if($this->isPaired() and $this->pos->getWorldNonNull()->isChunkLoaded($this->pairX >> 4, $this->pairZ >> 4)){ + if($this->isPaired() and $this->pos->getWorld()->isChunkLoaded($this->pairX >> 4, $this->pairZ >> 4)){ $this->doubleInventory->removeAllViewers(); if(($pair = $this->getPair()) !== null){ $pair->doubleInventory = null; @@ -137,7 +137,7 @@ class Chest extends Spawnable implements Container, Nameable{ } protected function checkPairing() : void{ - if($this->isPaired() and !$this->pos->getWorldNonNull()->isInLoadedTerrain(new Vector3($this->pairX, $this->pos->y, $this->pairZ))){ + if($this->isPaired() and !$this->pos->getWorld()->isInLoadedTerrain(new Vector3($this->pairX, $this->pos->y, $this->pairZ))){ //paired to a tile in an unloaded chunk $this->doubleInventory = null; @@ -173,7 +173,7 @@ class Chest extends Spawnable implements Container, Nameable{ public function getPair() : ?Chest{ if($this->isPaired()){ - $tile = $this->pos->getWorldNonNull()->getTileAt($this->pairX, $this->pos->y, $this->pairZ); + $tile = $this->pos->getWorld()->getTileAt($this->pairX, $this->pos->y, $this->pairZ); if($tile instanceof Chest){ return $tile; } diff --git a/src/block/tile/ContainerTrait.php b/src/block/tile/ContainerTrait.php index b23c944eb3..2968c54909 100644 --- a/src/block/tile/ContainerTrait.php +++ b/src/block/tile/ContainerTrait.php @@ -94,7 +94,7 @@ trait ContainerTrait{ $pos = $this->getPos(); foreach($inv->getContents() as $k => $item){ - $pos->getWorldNonNull()->dropItem($pos->add(0.5, 0.5, 0.5), $item); + $pos->getWorld()->dropItem($pos->add(0.5, 0.5, 0.5), $item); } $inv->clearAll(); } diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index d80809b751..7f2ec36c4b 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -60,7 +60,7 @@ class Furnace extends Spawnable implements Container, Nameable{ $this->inventory = new FurnaceInventory($this->pos); $this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange( function(Inventory $unused) : void{ - $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, 1); + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 1); }) ); } @@ -129,7 +129,7 @@ class Furnace extends Spawnable implements Container, Nameable{ $block = $this->getBlock(); if($block instanceof BlockFurnace and !$block->isLit()){ $block->setLit(true); - $this->pos->getWorldNonNull()->setBlock($block->getPos(), $block); + $this->pos->getWorld()->setBlock($block->getPos(), $block); } if($this->remainingFuelTime > 0 and $ev->isBurning()){ @@ -155,7 +155,7 @@ class Furnace extends Spawnable implements Container, Nameable{ $fuel = $this->inventory->getFuel(); $raw = $this->inventory->getSmelting(); $product = $this->inventory->getResult(); - $smelt = $this->pos->getWorldNonNull()->getServer()->getCraftingManager()->getFurnaceRecipeManager()->match($raw); + $smelt = $this->pos->getWorld()->getServer()->getCraftingManager()->getFurnaceRecipeManager()->match($raw); $canSmelt = ($smelt instanceof FurnaceRecipe and $raw->getCount() > 0 and (($smelt->getResult()->equals($product) and $product->getCount() < $product->getMaxStackSize()) or $product->isNull())); if($this->remainingFuelTime <= 0 and $canSmelt and $fuel->getFuelTime() > 0 and $fuel->getCount() > 0){ @@ -192,7 +192,7 @@ class Furnace extends Spawnable implements Container, Nameable{ $block = $this->getBlock(); if($block instanceof BlockFurnace and $block->isLit()){ $block->setLit(false); - $this->pos->getWorldNonNull()->setBlock($block->getPos(), $block); + $this->pos->getWorld()->setBlock($block->getPos(), $block); } $this->remainingFuelTime = $this->cookTime = $this->maxFuelTime = 0; } diff --git a/src/block/tile/Tile.php b/src/block/tile/Tile.php index 5fb12b184a..dac7635700 100644 --- a/src/block/tile/Tile.php +++ b/src/block/tile/Tile.php @@ -95,7 +95,7 @@ abstract class Tile{ } public function getBlock() : Block{ - return $this->pos->getWorldNonNull()->getBlock($this->pos); + return $this->pos->getWorld()->getBlock($this->pos); } public function getPos() : Position{ @@ -130,7 +130,7 @@ abstract class Tile{ $this->closed = true; if($this->pos->isValid()){ - $this->pos->getWorldNonNull()->removeTile($this); + $this->pos->getWorld()->removeTile($this); } $this->pos = null; } diff --git a/src/block/utils/FallableTrait.php b/src/block/utils/FallableTrait.php index be51117a0a..c0d2760573 100644 --- a/src/block/utils/FallableTrait.php +++ b/src/block/utils/FallableTrait.php @@ -49,14 +49,14 @@ trait FallableTrait{ public function onNearbyBlockChange() : void{ $pos = $this->getPos(); - $down = $pos->getWorldNonNull()->getBlock($pos->getSide(Facing::DOWN)); + $down = $pos->getWorld()->getBlock($pos->getSide(Facing::DOWN)); if($down->getId() === BlockLegacyIds::AIR or $down instanceof Liquid or $down instanceof Fire){ - $pos->getWorldNonNull()->setBlock($pos, VanillaBlocks::AIR()); + $pos->getWorld()->setBlock($pos, VanillaBlocks::AIR()); $block = $this; if(!($block instanceof Block)) throw new AssumptionFailedError(__TRAIT__ . " should only be used by Blocks"); - $fall = new FallingBlock(Location::fromObject($pos->add(0.5, 0, 0.5), $pos->getWorldNonNull()), $block); + $fall = new FallingBlock(Location::fromObject($pos->add(0.5, 0, 0.5), $pos->getWorld()), $block); $fall->spawnToAll(); } } diff --git a/src/command/defaults/ParticleCommand.php b/src/command/defaults/ParticleCommand.php index 7b617f15ab..a9c5806456 100644 --- a/src/command/defaults/ParticleCommand.php +++ b/src/command/defaults/ParticleCommand.php @@ -94,7 +94,7 @@ class ParticleCommand extends VanillaCommand{ if($sender instanceof Player){ $senderPos = $sender->getPosition(); - $world = $senderPos->getWorldNonNull(); + $world = $senderPos->getWorld(); $pos = new Vector3( $this->getRelativeDouble($senderPos->getX(), $sender, $args[1]), $this->getRelativeDouble($senderPos->getY(), $sender, $args[2], 0, World::Y_MAX), diff --git a/src/command/defaults/SeedCommand.php b/src/command/defaults/SeedCommand.php index 4f92150bb6..29017edb51 100644 --- a/src/command/defaults/SeedCommand.php +++ b/src/command/defaults/SeedCommand.php @@ -44,7 +44,7 @@ class SeedCommand extends VanillaCommand{ } if($sender instanceof Player){ - $seed = $sender->getPosition()->getWorldNonNull()->getSeed(); + $seed = $sender->getPosition()->getWorld()->getSeed(); }else{ $seed = $sender->getServer()->getWorldManager()->getDefaultWorld()->getSeed(); } diff --git a/src/command/defaults/SetWorldSpawnCommand.php b/src/command/defaults/SetWorldSpawnCommand.php index 36241ea8a6..45534184ac 100644 --- a/src/command/defaults/SetWorldSpawnCommand.php +++ b/src/command/defaults/SetWorldSpawnCommand.php @@ -52,7 +52,7 @@ class SetWorldSpawnCommand extends VanillaCommand{ if(count($args) === 0){ if($sender instanceof Player){ $location = $sender->getPosition(); - $world = $location->getWorldNonNull(); + $world = $location->getWorld(); $pos = $location->asVector3()->round(); }else{ $sender->sendMessage(TextFormat::RED . "You can only perform this command as a player"); diff --git a/src/command/defaults/SpawnpointCommand.php b/src/command/defaults/SpawnpointCommand.php index 3879ced838..91813c24c8 100644 --- a/src/command/defaults/SpawnpointCommand.php +++ b/src/command/defaults/SpawnpointCommand.php @@ -83,7 +83,7 @@ class SpawnpointCommand extends VanillaCommand{ }elseif(count($args) <= 1){ if($sender instanceof Player){ $cpos = $sender->getPosition(); - $pos = Position::fromObject($cpos->floor(), $cpos->getWorldNonNull()); + $pos = Position::fromObject($cpos->floor(), $cpos->getWorld()); $target->setSpawn($pos); Command::broadcastCommandMessage($sender, new TranslationContainer("commands.spawnpoint.success", [$target->getName(), round($pos->x, 2), round($pos->y, 2), round($pos->z, 2)])); diff --git a/src/command/defaults/TeleportCommand.php b/src/command/defaults/TeleportCommand.php index ed86dd413b..ff302bd8cc 100644 --- a/src/command/defaults/TeleportCommand.php +++ b/src/command/defaults/TeleportCommand.php @@ -112,7 +112,7 @@ class TeleportCommand extends VanillaCommand{ $x = $this->getRelativeDouble($base->x, $sender, $targetArgs[0]); $y = $this->getRelativeDouble($base->y, $sender, $targetArgs[1], 0, 256); $z = $this->getRelativeDouble($base->z, $sender, $targetArgs[2]); - $targetLocation = new Location($x, $y, $z, $yaw, $pitch, $base->getWorldNonNull()); + $targetLocation = new Location($x, $y, $z, $yaw, $pitch, $base->getWorld()); $subject->teleport($targetLocation); Command::broadcastCommandMessage($sender, new TranslationContainer("commands.tp.success.coordinates", [ diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 878e6c9eda..cd5f42a07b 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -223,7 +223,7 @@ abstract class Entity{ } $this->id = self::nextRuntimeId(); - $this->server = $location->getWorldNonNull()->getServer(); + $this->server = $location->getWorld()->getServer(); $this->location = $location->asLocation(); assert( @@ -1289,7 +1289,7 @@ abstract class Entity{ } public function getWorld() : World{ - return $this->location->getWorldNonNull(); + return $this->location->getWorld(); } protected function setPosition(Vector3 $pos) : bool{ @@ -1297,8 +1297,8 @@ abstract class Entity{ return false; } - if($pos instanceof Position and $pos->isValid() and $pos->getWorldNonNull() !== $this->getWorld()){ - if(!$this->switchWorld($pos->getWorldNonNull())){ + if($pos instanceof Position and $pos->isValid() and $pos->getWorld() !== $this->getWorld()){ + if(!$this->switchWorld($pos->getWorld())){ return false; } } @@ -1410,7 +1410,7 @@ abstract class Entity{ $pitch = $pitch ?? $pos->pitch; } $from = $this->location->asPosition(); - $to = Position::fromObject($pos, $pos instanceof Position ? $pos->getWorldNonNull() : $this->getWorld()); + $to = Position::fromObject($pos, $pos instanceof Position ? $pos->getWorld() : $this->getWorld()); $ev = new EntityTeleportEvent($this, $from, $to); $ev->call(); if($ev->isCancelled()){ diff --git a/src/entity/Location.php b/src/entity/Location.php index 2ff9171ac4..2ff7f3b078 100644 --- a/src/entity/Location.php +++ b/src/entity/Location.php @@ -63,7 +63,7 @@ class Location extends Position{ } public function __toString(){ - return "Location (world=" . ($this->isValid() ? $this->getWorldNonNull()->getDisplayName() : "null") . ", x=$this->x, y=$this->y, z=$this->z, yaw=$this->yaw, pitch=$this->pitch)"; + return "Location (world=" . ($this->isValid() ? $this->getWorld()->getDisplayName() : "null") . ", x=$this->x, y=$this->y, z=$this->z, yaw=$this->yaw, pitch=$this->pitch)"; } public function equals(Vector3 $v) : bool{ diff --git a/src/item/Bow.php b/src/item/Bow.php index 0f68e1410e..2dcbb5b010 100644 --- a/src/item/Bow.php +++ b/src/item/Bow.php @@ -103,7 +103,7 @@ class Bow extends Tool{ } $ev->getProjectile()->spawnToAll(); - $location->getWorldNonNull()->addSound($location, new BowShootSound()); + $location->getWorld()->addSound($location, new BowShootSound()); }else{ $entity->spawnToAll(); } diff --git a/src/item/PaintingItem.php b/src/item/PaintingItem.php index 6c6b1f25e4..114a94b1c9 100644 --- a/src/item/PaintingItem.php +++ b/src/item/PaintingItem.php @@ -75,7 +75,7 @@ class PaintingItem extends Item{ $replacePos = $blockReplace->getPos(); $clickedPos = $blockClicked->getPos(); - $entity = new Painting(Location::fromObject($replacePos, $replacePos->getWorldNonNull()), $clickedPos, $face, $motive); + $entity = new Painting(Location::fromObject($replacePos, $replacePos->getWorld()), $clickedPos, $face, $motive); $this->pop(); $entity->spawnToAll(); diff --git a/src/item/ProjectileItem.php b/src/item/ProjectileItem.php index 8ac5fedc1c..f8fb55673c 100644 --- a/src/item/ProjectileItem.php +++ b/src/item/ProjectileItem.php @@ -51,7 +51,7 @@ abstract class ProjectileItem extends Item{ $projectile->spawnToAll(); - $location->getWorldNonNull()->addSound($location, new ThrowSound()); + $location->getWorld()->addSound($location, new ThrowSound()); $this->pop(); diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index b1d09ea510..0f9bfad876 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -822,7 +822,7 @@ class NetworkSession{ public function startUsingChunk(int $chunkX, int $chunkZ, \Closure $onCompletion) : void{ Utils::validateCallableSignature(function(int $chunkX, int $chunkZ) : void{}, $onCompletion); - $world = $this->player->getLocation()->getWorldNonNull(); + $world = $this->player->getLocation()->getWorld(); ChunkCache::getInstance($world, $this->compressor)->request($chunkX, $chunkZ)->onResolve( //this callback may be called synchronously or asynchronously, depending on whether the promise is resolved yet @@ -830,7 +830,7 @@ class NetworkSession{ if(!$this->isConnected()){ return; } - $currentWorld = $this->player->getLocation()->getWorldNonNull(); + $currentWorld = $this->player->getLocation()->getWorld(); if($world !== $currentWorld or !$this->player->isUsingChunk($chunkX, $chunkZ)){ $this->logger->debug("Tried to send no-longer-active chunk $chunkX $chunkZ in world " . $world->getFolderName()); return; diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 9e34ef0578..30a5995837 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -359,7 +359,7 @@ class InGamePacketHandler extends PacketHandler{ }else{ $blocks[] = $blockPos; } - $this->player->getLocation()->getWorldNonNull()->sendBlocks([$this->player], $blocks); + $this->player->getLocation()->getWorld()->sendBlocks([$this->player], $blocks); } } @@ -563,7 +563,7 @@ class InGamePacketHandler extends PacketHandler{ return false; } - $block = $this->player->getLocation()->getWorldNonNull()->getBlock($pos); + $block = $this->player->getLocation()->getWorld()->getBlock($pos); $nbt = $packet->namedtag->getRoot(); if(!($nbt instanceof CompoundTag)) throw new AssumptionFailedError("PHPStan should ensure this is a CompoundTag"); //for phpstorm's benefit diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index 4371dc8537..560fbf5446 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -68,12 +68,12 @@ class PreSpawnPacketHandler extends PacketHandler{ $pk->seed = -1; $pk->spawnSettings = new SpawnSettings(SpawnSettings::BIOME_TYPE_DEFAULT, "", DimensionIds::OVERWORLD); //TODO: implement this properly $pk->worldGamemode = TypeConverter::getInstance()->coreGameModeToProtocol($this->server->getGamemode()); - $pk->difficulty = $location->getWorldNonNull()->getDifficulty(); + $pk->difficulty = $location->getWorld()->getDifficulty(); $pk->spawnX = $spawnPosition->getFloorX(); $pk->spawnY = $spawnPosition->getFloorY(); $pk->spawnZ = $spawnPosition->getFloorZ(); $pk->hasAchievementsDisabled = true; - $pk->time = $location->getWorldNonNull()->getTime(); + $pk->time = $location->getWorld()->getTime(); $pk->eduEditionOffer = 0; $pk->rainLevel = 0; //TODO: implement these properly $pk->lightningLevel = 0; diff --git a/src/player/Player.php b/src/player/Player.php index df03dc55dd..a13ed87d67 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -713,7 +713,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } protected function switchWorld(World $targetWorld) : bool{ - $oldWorld = $this->location->isValid() ? $this->location->getWorldNonNull() : null; + $oldWorld = $this->location->isValid() ? $this->location->getWorld() : null; if(parent::switchWorld($targetWorld)){ if($oldWorld !== null){ foreach($this->usedChunks as $index => $status){ @@ -959,7 +959,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, if(!($pos instanceof Position)){ $world = $this->getWorld(); }else{ - $world = $pos->getWorldNonNull(); + $world = $pos->getWorld(); } $this->spawnPosition = new Position($pos->x, $pos->y, $pos->z, $world); $this->networkSession->syncPlayerSpawnPoint($this->spawnPosition); @@ -2082,7 +2082,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } if($this->hasValidSpawnPosition()){ - $nbt->setString("SpawnLevel", $this->spawnPosition->getWorldNonNull()->getFolderName()); + $nbt->setString("SpawnLevel", $this->spawnPosition->getWorld()->getFolderName()); $nbt->setInt("SpawnX", $this->spawnPosition->getFloorX()); $nbt->setInt("SpawnY", $this->spawnPosition->getFloorY()); $nbt->setInt("SpawnZ", $this->spawnPosition->getFloorZ()); @@ -2152,7 +2152,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $ev = new PlayerRespawnEvent($this, $this->getSpawn()); $ev->call(); - $realSpawn = Position::fromObject($ev->getRespawnPosition()->add(0.5, 0, 0.5), $ev->getRespawnPosition()->getWorldNonNull()); + $realSpawn = Position::fromObject($ev->getRespawnPosition()->add(0.5, 0, 0.5), $ev->getRespawnPosition()->getWorld()); $this->teleport($realSpawn); $this->setSprinting(false); diff --git a/src/world/Explosion.php b/src/world/Explosion.php index db17c93d00..a409f00ab2 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -73,7 +73,7 @@ class Explosion{ throw new \InvalidArgumentException("Position does not have a valid world"); } $this->source = $center; - $this->world = $center->getWorldNonNull(); + $this->world = $center->getWorld(); if($size <= 0){ throw new \InvalidArgumentException("Explosion radius must be greater than 0, got $size"); diff --git a/src/world/Position.php b/src/world/Position.php index 0d8c4914c6..9d2f362991 100644 --- a/src/world/Position.php +++ b/src/world/Position.php @@ -61,32 +61,16 @@ class Position extends Vector3{ } /** - * Returns the target world, or null if the target is not valid. - * If a reference exists to a world which is closed, the reference will be destroyed and null will be returned. - * - * @return World|null - */ - public function getWorld(){ - if($this->world !== null and $this->world->isClosed()){ - \GlobalLogger::get()->debug("Position was holding a reference to an unloaded world"); - $this->world = null; - } - - return $this->world; - } - - /** - * Returns the position's world if valid. Throws an error if the world is unexpectedly null. + * Returns the position's world if valid. Throws an error if the world is unexpectedly invalid. * * @throws AssumptionFailedError */ - public function getWorldNonNull() : World{ - $world = $this->getWorld(); - if($world === null){ - throw new AssumptionFailedError("Position world is null"); + public function getWorld() : World{ + if($this->world === null || $this->world->isClosed()){ + throw new AssumptionFailedError("Position world is null or has been unloaded"); } - return $world; + return $this->world; } /** @@ -114,7 +98,7 @@ class Position extends Vector3{ } public function __toString(){ - return "Position(level=" . ($this->isValid() ? $this->getWorldNonNull()->getDisplayName() : "null") . ",x=" . $this->x . ",y=" . $this->y . ",z=" . $this->z . ")"; + return "Position(level=" . ($this->isValid() ? $this->getWorld()->getDisplayName() : "null") . ",x=" . $this->x . ",y=" . $this->y . ",z=" . $this->z . ")"; } public function equals(Vector3 $v) : bool{ diff --git a/src/world/World.php b/src/world/World.php index 31f1298419..bd1c6530bc 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2043,7 +2043,7 @@ class World implements ChunkManager{ throw new \InvalidArgumentException("Attempted to add a garbage closed Tile to world"); } $pos = $tile->getPos(); - if(!$pos->isValid() || $pos->getWorldNonNull() !== $this){ + if(!$pos->isValid() || $pos->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Tile world"); } @@ -2065,7 +2065,7 @@ class World implements ChunkManager{ */ public function removeTile(Tile $tile) : void{ $pos = $tile->getPos(); - if(!$pos->isValid() || $pos->getWorldNonNull() !== $this){ + if(!$pos->isValid() || $pos->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Tile world"); } From 8673a4872e7ac180c5621612fea078f0f884c884 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jun 2020 21:55:21 +0100 Subject: [PATCH 1738/3224] InventoryEvent: fix wrong return type on getViewers() --- src/event/inventory/InventoryEvent.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/event/inventory/InventoryEvent.php b/src/event/inventory/InventoryEvent.php index 7c00c35fe1..ac19d37055 100644 --- a/src/event/inventory/InventoryEvent.php +++ b/src/event/inventory/InventoryEvent.php @@ -26,9 +26,9 @@ declare(strict_types=1); */ namespace pocketmine\event\inventory; -use pocketmine\entity\Human; use pocketmine\event\Event; use pocketmine\inventory\Inventory; +use pocketmine\player\Player; abstract class InventoryEvent extends Event{ /** @var Inventory */ @@ -43,7 +43,7 @@ abstract class InventoryEvent extends Event{ } /** - * @return Human[] + * @return Player[] */ public function getViewers() : array{ return $this->inventory->getViewers(); From da3f0752a61f323e413f8d7d50b17bb1567cf94a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jun 2020 22:13:07 +0100 Subject: [PATCH 1739/3224] Block: make getAllSides() and getHorizontalSides() use underlying Vector3 generators --- src/block/Block.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/block/Block.php b/src/block/Block.php index 46123eaab5..584d38aefd 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -492,10 +492,10 @@ class Block{ * @phpstan-return \Generator */ public function getHorizontalSides() : \Generator{ - yield $this->getSide(Facing::NORTH); - yield $this->getSide(Facing::SOUTH); - yield $this->getSide(Facing::WEST); - yield $this->getSide(Facing::EAST); + $world = $this->pos->getWorld(); + foreach($this->pos->sidesAroundAxis(Facing::AXIS_Y) as $vector3){ + yield $world->getBlock($vector3); + } } /** @@ -505,9 +505,10 @@ class Block{ * @phpstan-return \Generator */ public function getAllSides() : \Generator{ - yield $this->getSide(Facing::DOWN); - yield $this->getSide(Facing::UP); - yield from $this->getHorizontalSides(); + $world = $this->pos->getWorld(); + foreach($this->pos->sides() as $vector3){ + yield $world->getBlock($vector3); + } } /** From 69fb2786c62990e16056e683eebcae46014ade93 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jun 2020 22:32:00 +0100 Subject: [PATCH 1740/3224] Player: fixed spawn position sticking to old world spawn when new world spawn is set this will still take effect for preexisting data because the server will still see previously set spawns as custom, but for new players, their spawns will follow the world spawn unless they sleep in a bed. --- src/player/Player.php | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index a13ed87d67..2d8feec1e0 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -347,12 +347,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->setNameTagAlwaysVisible(); $this->setCanClimb(); - if(!$this->hasValidSpawnPosition()){ - if(($world = $this->server->getWorldManager()->getWorldByName($nbt->getString("SpawnLevel", ""))) instanceof World){ - $this->spawnPosition = new Position($nbt->getInt("SpawnX"), $nbt->getInt("SpawnY"), $nbt->getInt("SpawnZ"), $world); - }else{ - $this->spawnPosition = $this->getWorld()->getSafeSpawn(); - } + if(($world = $this->server->getWorldManager()->getWorldByName($nbt->getString("SpawnLevel", ""))) instanceof World){ + $this->spawnPosition = new Position($nbt->getInt("SpawnX"), $nbt->getInt("SpawnY"), $nbt->getInt("SpawnZ"), $world); } } @@ -936,7 +932,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * @return Position */ public function getSpawn(){ - if($this->hasValidSpawnPosition()){ + if($this->hasValidCustomSpawn()){ return $this->spawnPosition; }else{ $world = $this->server->getWorldManager()->getDefaultWorld(); @@ -945,7 +941,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } - public function hasValidSpawnPosition() : bool{ + public function hasValidCustomSpawn() : bool{ return $this->spawnPosition !== null and $this->spawnPosition->isValid(); } @@ -2081,20 +2077,21 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $nbt->setString("Level", $this->getWorld()->getFolderName()); } - if($this->hasValidSpawnPosition()){ + if($this->hasValidCustomSpawn()){ $nbt->setString("SpawnLevel", $this->spawnPosition->getWorld()->getFolderName()); $nbt->setInt("SpawnX", $this->spawnPosition->getFloorX()); $nbt->setInt("SpawnY", $this->spawnPosition->getFloorY()); $nbt->setInt("SpawnZ", $this->spawnPosition->getFloorZ()); + } - if(!$this->isAlive()){ - //hack for respawn after quit - $nbt->setTag("Pos", new ListTag([ - new DoubleTag($this->spawnPosition->x), - new DoubleTag($this->spawnPosition->y), - new DoubleTag($this->spawnPosition->z) - ])); - } + if(!$this->isAlive()){ + $spawn = $this->getSpawn(); + //hack for respawn after quit + $nbt->setTag("Pos", new ListTag([ + new DoubleTag($spawn->getFloorX()), + new DoubleTag($spawn->getFloorY()), + new DoubleTag($spawn->getFloorZ()) + ])); } $nbt->setInt("playerGameType", $this->gamemode->getMagicNumber()); From 2cd67aed72462cacfd04bb7fcad5ac2d692eb3fe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jun 2020 22:40:35 +0100 Subject: [PATCH 1741/3224] Block: fixed crash on block factory clone --- src/block/Block.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/Block.php b/src/block/Block.php index 584d38aefd..873be4e9e5 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -79,7 +79,7 @@ class Block{ } public function __clone(){ - $this->pos = Position::fromObject($this->pos, $this->pos->getWorld()); + $this->pos = clone $this->pos; } public function getIdInfo() : BlockIdentifier{ From fc60abe5e52ff4a20e712318363c1593ed865e9f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jun 2020 22:41:17 +0100 Subject: [PATCH 1742/3224] Player: fixed a few phpstan level 8 warnings --- src/player/Player.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 2d8feec1e0..a110daacd4 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2078,10 +2078,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } if($this->hasValidCustomSpawn()){ - $nbt->setString("SpawnLevel", $this->spawnPosition->getWorld()->getFolderName()); - $nbt->setInt("SpawnX", $this->spawnPosition->getFloorX()); - $nbt->setInt("SpawnY", $this->spawnPosition->getFloorY()); - $nbt->setInt("SpawnZ", $this->spawnPosition->getFloorZ()); + $spawn = $this->getSpawn(); + $nbt->setString("SpawnLevel", $spawn->getWorld()->getFolderName()); + $nbt->setInt("SpawnX", $spawn->getFloorX()); + $nbt->setInt("SpawnY", $spawn->getFloorY()); + $nbt->setInt("SpawnZ", $spawn->getFloorZ()); } if(!$this->isAlive()){ From c0af05fcad97f8c486d7a12c20ae39e41a46527f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jun 2020 22:42:46 +0100 Subject: [PATCH 1743/3224] phpstan: clean some errors from level 8 baseline --- tests/phpstan/configs/l8-baseline.neon | 35 -------------------------- 1 file changed, 35 deletions(-) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 5cf4354472..02ba4b5e18 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -595,41 +595,6 @@ parameters: count: 1 path: ../../../src/player/Player.php - - - message: "#^Cannot call method getWorldNonNull\\(\\) on pocketmine\\\\world\\\\Position\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method getFloorX\\(\\) on pocketmine\\\\world\\\\Position\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method getFloorY\\(\\) on pocketmine\\\\world\\\\Position\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method getFloorZ\\(\\) on pocketmine\\\\world\\\\Position\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot access property \\$x on pocketmine\\\\world\\\\Position\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot access property \\$y on pocketmine\\\\world\\\\Position\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot access property \\$z on pocketmine\\\\world\\\\Position\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - message: "#^Cannot call method onDeath\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" count: 1 From 8b87cf73b9a2c8a781bb44a4c11db469bf722655 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jun 2020 22:51:02 +0100 Subject: [PATCH 1744/3224] Player->setSpawn() now accepts NULL (fallback to world spawn) --- src/player/Player.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index a110daacd4..937f68c198 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -949,16 +949,20 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, * Sets the spawnpoint of the player (and the compass direction) to a Vector3, or set it on another world with a * Position object * - * @param Vector3|Position $pos + * @param Vector3|Position|null $pos */ - public function setSpawn(Vector3 $pos) : void{ - if(!($pos instanceof Position)){ - $world = $this->getWorld(); + public function setSpawn(?Vector3 $pos) : void{ + if($pos !== null){ + if(!($pos instanceof Position)){ + $world = $this->getWorld(); + }else{ + $world = $pos->getWorld(); + } + $this->spawnPosition = new Position($pos->x, $pos->y, $pos->z, $world); }else{ - $world = $pos->getWorld(); + $this->spawnPosition = null; } - $this->spawnPosition = new Position($pos->x, $pos->y, $pos->z, $world); - $this->networkSession->syncPlayerSpawnPoint($this->spawnPosition); + $this->networkSession->syncPlayerSpawnPoint($this->getSpawn()); } public function isSleeping() : bool{ From 74a919353fd5263ceb0346916bfa963eceac1e71 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Jun 2020 22:52:04 +0100 Subject: [PATCH 1745/3224] Food: remove unused import --- src/item/Food.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/item/Food.php b/src/item/Food.php index fccce4068c..ff737e3299 100644 --- a/src/item/Food.php +++ b/src/item/Food.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\FoodSource; use pocketmine\entity\Living; abstract class Food extends Item implements FoodSourceItem{ From 7f81507ea1db41fe496e5f7916f2b15abcd3c0cb Mon Sep 17 00:00:00 2001 From: Govdim <50422762+Govdim@users.noreply.github.com> Date: Tue, 30 Jun 2020 23:09:10 +0300 Subject: [PATCH 1746/3224] Add Releasable interface (#3664) closes #3301 --- src/item/Bow.php | 2 +- src/item/ConsumableItem.php | 2 +- src/item/Releasable.php | 31 +++++++++++++++++++++++++++++++ src/player/Player.php | 4 ++-- 4 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 src/item/Releasable.php diff --git a/src/item/Bow.php b/src/item/Bow.php index 2dcbb5b010..2c660354e0 100644 --- a/src/item/Bow.php +++ b/src/item/Bow.php @@ -34,7 +34,7 @@ use pocketmine\world\sound\BowShootSound; use function intdiv; use function min; -class Bow extends Tool{ +class Bow extends Tool implements Releasable{ public function getFuelTime() : int{ return 200; diff --git a/src/item/ConsumableItem.php b/src/item/ConsumableItem.php index 54e661877e..77344de64c 100644 --- a/src/item/ConsumableItem.php +++ b/src/item/ConsumableItem.php @@ -28,7 +28,7 @@ use pocketmine\entity\Consumable; /** * Interface implemented by objects that can be consumed by mobs. */ -interface ConsumableItem extends Consumable{ +interface ConsumableItem extends Consumable, Releasable{ /** * Returns the leftover that this Consumable produces when it is consumed. For Items, this is usually air, but could diff --git a/src/item/Releasable.php b/src/item/Releasable.php new file mode 100644 index 0000000000..07e77cf28c --- /dev/null +++ b/src/item/Releasable.php @@ -0,0 +1,31 @@ +inventory->setItemInHand($item); } - //TODO: check if item has a release action - if it doesn't, this shouldn't be set - $this->setUsingItem(true); + $this->setUsingItem($item instanceof Releasable); return true; } From 96541763f1b4beff7a38d03f114a35133ada07ab Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 1 Jul 2020 13:06:59 +0100 Subject: [PATCH 1747/3224] ConsoleCommandSender: inject Language via constructor --- src/Server.php | 2 +- src/command/ConsoleCommandSender.php | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Server.php b/src/Server.php index 89b06da5c8..bc0caeff18 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1059,7 +1059,7 @@ class Server{ $this->logger->info($this->getLanguage()->translateString("pocketmine.server.startFinished", [round(microtime(true) - $this->startTime, 3)])); //TODO: move console parts to a separate component - $consoleSender = new ConsoleCommandSender($this); + $consoleSender = new ConsoleCommandSender($this, $this->language); PermissionManager::getInstance()->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $consoleSender); PermissionManager::getInstance()->subscribeToPermission(Server::BROADCAST_CHANNEL_USERS, $consoleSender); diff --git a/src/command/ConsoleCommandSender.php b/src/command/ConsoleCommandSender.php index df79777162..4a803a0451 100644 --- a/src/command/ConsoleCommandSender.php +++ b/src/command/ConsoleCommandSender.php @@ -39,10 +39,13 @@ class ConsoleCommandSender implements CommandSender{ private $server; /** @var int|null */ protected $lineHeight = null; + /** @var Language */ + private $language; - public function __construct(Server $server){ + public function __construct(Server $server, Language $language){ $this->server = $server; $this->perm = new PermissibleBase($this); + $this->language = $language; } public function getServer() : Server{ @@ -50,7 +53,7 @@ class ConsoleCommandSender implements CommandSender{ } public function getLanguage() : Language{ - return $this->server->getLanguage(); + return $this->language; } /** From 29612cded3cf394487fbf33ec891185a6c0c6cdc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 1 Jul 2020 13:29:58 +0100 Subject: [PATCH 1748/3224] CraftingTransaction: make CraftingManager injectable this becomes a bit easier to unit-test. --- src/inventory/transaction/CraftingTransaction.php | 11 ++++++++++- src/network/mcpe/handler/InGamePacketHandler.php | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/inventory/transaction/CraftingTransaction.php b/src/inventory/transaction/CraftingTransaction.php index db9428447c..35f592f730 100644 --- a/src/inventory/transaction/CraftingTransaction.php +++ b/src/inventory/transaction/CraftingTransaction.php @@ -23,9 +23,11 @@ declare(strict_types=1); namespace pocketmine\inventory\transaction; +use pocketmine\crafting\CraftingManager; use pocketmine\crafting\CraftingRecipe; use pocketmine\event\inventory\CraftItemEvent; use pocketmine\item\Item; +use pocketmine\player\Player; use function array_pop; use function count; use function intdiv; @@ -55,6 +57,13 @@ class CraftingTransaction extends InventoryTransaction{ protected $inputs = []; /** @var Item[] */ protected $outputs = []; + /** @var CraftingManager */ + private $craftingManager; + + public function __construct(Player $source, CraftingManager $craftingManager, array $actions = []){ + parent::__construct($source, $actions); + $this->craftingManager = $craftingManager; + } /** * @param Item[] $txItems @@ -126,7 +135,7 @@ class CraftingTransaction extends InventoryTransaction{ $this->matchItems($this->outputs, $this->inputs); $failed = 0; - foreach($this->source->getServer()->getCraftingManager()->matchRecipeByOutputs($this->outputs) as $recipe){ + foreach($this->craftingManager->matchRecipeByOutputs($this->outputs) as $recipe){ try{ //compute number of times recipe was crafted $this->repetitions = $this->matchRecipeItems($this->outputs, $recipe->getResultsFor($this->source->getCraftingGrid()), false); diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 30a5995837..0906e08a94 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -236,7 +236,7 @@ class InGamePacketHandler extends PacketHandler{ //trying to execute it if($this->craftingTransaction === null){ - $this->craftingTransaction = new CraftingTransaction($this->player, $actions); + $this->craftingTransaction = new CraftingTransaction($this->player, $this->player->getServer()->getCraftingManager(), $actions); }else{ foreach($actions as $action){ $this->craftingTransaction->addAction($action); From 30591d047c82d9903efb3f5b049285e1131ff8d4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 1 Jul 2020 13:35:34 +0100 Subject: [PATCH 1749/3224] PacketBatch: added a getPackets() method which encapsulates some logic --- src/network/mcpe/NetworkSession.php | 29 ++++----- .../mcpe/protocol/serializer/PacketBatch.php | 14 +++++ .../protocol/serializer/PacketBatchTest.php | 62 +++++++++++++++++++ 3 files changed, 87 insertions(+), 18 deletions(-) create mode 100644 tests/phpunit/network/mcpe/protocol/serializer/PacketBatchTest.php diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 0f9bfad876..9ce7ca0572 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -98,7 +98,6 @@ use pocketmine\player\Player; use pocketmine\player\PlayerInfo; use pocketmine\Server; use pocketmine\timings\Timings; -use pocketmine\utils\BinaryDataException; use pocketmine\utils\TextFormat; use pocketmine\utils\Utils; use pocketmine\world\Position; @@ -328,24 +327,18 @@ class NetworkSession{ Timings::$playerNetworkReceiveDecompressTimer->stopTiming(); } - $count = 0; - while(!$stream->feof() and $this->connected){ - if($count++ >= 500){ - throw new BadPacketException("Too many packets in a single batch"); - } - try{ - $pk = $stream->getPacket($this->packetPool); - }catch(BinaryDataException $e){ - $this->logger->debug("Packet batch: " . base64_encode($stream->getBuffer())); - throw BadPacketException::wrap($e, "Packet batch decode error"); - } - - try{ - $this->handleDataPacket($pk); - }catch(BadPacketException $e){ - $this->logger->debug($pk->getName() . ": " . base64_encode($pk->getSerializer()->getBuffer())); - throw BadPacketException::wrap($e, "Error processing " . $pk->getName()); + try{ + foreach($stream->getPackets($this->packetPool, 500) as $packet){ + try{ + $this->handleDataPacket($packet); + }catch(BadPacketException $e){ + $this->logger->debug($packet->getName() . ": " . base64_encode($packet->getSerializer()->getBuffer())); + throw BadPacketException::wrap($e, "Error processing " . $packet->getName()); + } } + }catch(PacketDecodeException $e){ + $this->logger->logException($e); + throw BadPacketException::wrap($e, "Packet batch decode error"); } } diff --git a/src/network/mcpe/protocol/serializer/PacketBatch.php b/src/network/mcpe/protocol/serializer/PacketBatch.php index a242a2b6f8..98a41fd048 100644 --- a/src/network/mcpe/protocol/serializer/PacketBatch.php +++ b/src/network/mcpe/protocol/serializer/PacketBatch.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\serializer; use pocketmine\network\mcpe\protocol\Packet; +use pocketmine\network\mcpe\protocol\PacketDecodeException; use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\utils\BinaryDataException; @@ -48,6 +49,19 @@ class PacketBatch{ return $packetPool->getPacket($this->serializer->getString()); } + /** + * @return \Generator|Packet[] + * @phpstan-return \Generator + */ + public function getPackets(PacketPool $packetPool, int $max) : \Generator{ + for($c = 0; $c < $max and !$this->serializer->feof(); ++$c){ + yield $c => $packetPool->getPacket($this->serializer->getString()); + } + if(!$this->serializer->feof()){ + throw new PacketDecodeException("Reached limit of $max packets in a single batch"); + } + } + /** * Constructs a packet batch from the given list of packets. * diff --git a/tests/phpunit/network/mcpe/protocol/serializer/PacketBatchTest.php b/tests/phpunit/network/mcpe/protocol/serializer/PacketBatchTest.php new file mode 100644 index 0000000000..217914d319 --- /dev/null +++ b/tests/phpunit/network/mcpe/protocol/serializer/PacketBatchTest.php @@ -0,0 +1,62 @@ +putPacket(new TestPacket()); + } + $read = new PacketBatch($write->getBuffer()); + $this->expectException(PacketDecodeException::class); + $readCount = 0; + foreach($read->getPackets(PacketPool::getInstance(), $limit) as $packet){ + $readCount++; + } + } + + public function testDecodeAtLimit() : void{ + $limit = 10; + $write = new PacketBatch(); + for($i = 0; $i < $limit; $i++){ + $write->putPacket(new TestPacket()); + } + $read = new PacketBatch($write->getBuffer()); + $readCount = 0; + foreach($read->getPackets(PacketPool::getInstance(), $limit) as $packet){ + $readCount++; + } + self::assertSame($limit, $readCount); + } +} From cf5e31c61911a2a8d1d1a239df56aab00d5de17e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 1 Jul 2020 14:08:28 +0100 Subject: [PATCH 1750/3224] InventoryTransaction::execute() now throws exceptions instead of returning true/false --- .../transaction/InventoryTransaction.php | 28 ++++------------- .../TransactionCancelledException.php | 31 +++++++++++++++++++ .../transaction/TransactionException.php | 31 +++++++++++++++++++ .../TransactionValidationException.php | 5 ++- .../mcpe/handler/InGamePacketHandler.php | 14 +++++++-- 5 files changed, 83 insertions(+), 26 deletions(-) create mode 100644 src/inventory/transaction/TransactionCancelledException.php create mode 100644 src/inventory/transaction/TransactionException.php diff --git a/src/inventory/transaction/InventoryTransaction.php b/src/inventory/transaction/InventoryTransaction.php index d6680c284e..e7b4a6d3fc 100644 --- a/src/inventory/transaction/InventoryTransaction.php +++ b/src/inventory/transaction/InventoryTransaction.php @@ -269,12 +269,6 @@ class InventoryTransaction{ } } - protected function sendInventories() : void{ - foreach($this->inventories as $inventory){ - $this->source->getNetworkSession()->getInvManager()->syncContents($inventory); - } - } - protected function callExecuteEvent() : bool{ $ev = new InventoryTransactionEvent($this); $ev->call(); @@ -284,32 +278,24 @@ class InventoryTransaction{ /** * Executes the group of actions, returning whether the transaction executed successfully or not. * - * @throws TransactionValidationException + * @throws TransactionException */ - public function execute() : bool{ + public function execute() : void{ if($this->hasExecuted()){ - $this->sendInventories(); - return false; + throw new TransactionValidationException("Transaction has already been executed"); } $this->shuffleActions(); - try{ - $this->validate(); - }catch(TransactionValidationException $e){ - $this->sendInventories(); - throw $e; - } + $this->validate(); if(!$this->callExecuteEvent()){ - $this->sendInventories(); - return false; + throw new TransactionCancelledException("Transaction event cancelled"); } foreach($this->actions as $action){ if(!$action->onPreExecute($this->source)){ - $this->sendInventories(); - return false; + throw new TransactionCancelledException("One of the actions in this transaction was cancelled"); } } @@ -318,8 +304,6 @@ class InventoryTransaction{ } $this->hasExecuted = true; - - return true; } public function hasExecuted() : bool{ diff --git a/src/inventory/transaction/TransactionCancelledException.php b/src/inventory/transaction/TransactionCancelledException.php new file mode 100644 index 0000000000..7db33ed3a4 --- /dev/null +++ b/src/inventory/transaction/TransactionCancelledException.php @@ -0,0 +1,31 @@ +session->getInvManager()->onTransactionStart($this->craftingTransaction); $this->craftingTransaction->execute(); - }catch(TransactionValidationException $e){ + }catch(TransactionException $e){ $this->session->getLogger()->debug("Failed to execute crafting transaction: " . $e->getMessage()); + //TODO: only sync slots that the client tried to change + foreach($this->craftingTransaction->getInventories() as $inventory){ + $this->session->getInvManager()->syncContents($inventory); + } /* * TODO: HACK! * we can't resend the contents of the crafting window, so we force the client to close it instead. @@ -280,11 +284,15 @@ class InGamePacketHandler extends PacketHandler{ $this->session->getInvManager()->onTransactionStart($transaction); try{ $transaction->execute(); - }catch(TransactionValidationException $e){ + }catch(TransactionException $e){ $logger = $this->session->getLogger(); $logger->debug("Failed to execute inventory transaction: " . $e->getMessage()); $logger->debug("Actions: " . json_encode($data->getActions())); + foreach($transaction->getInventories() as $inventory){ + $this->session->getInvManager()->syncContents($inventory); + } + return false; } } From 1d18662d9b018bde32d8e3a117fecc54f4646278 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 4 Jul 2020 19:38:34 +0100 Subject: [PATCH 1751/3224] InventoryAction: replace isValid() with validate() which throws TransactionValidationException --- .../transaction/InventoryTransaction.php | 6 ++++-- .../transaction/action/CreateItemAction.php | 10 ++++++++-- .../transaction/action/DestroyItemAction.php | 7 +++++-- .../transaction/action/DropItemAction.php | 7 +++++-- .../transaction/action/InventoryAction.php | 5 ++++- .../transaction/action/SlotChangeAction.php | 15 ++++++++++----- 6 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/inventory/transaction/InventoryTransaction.php b/src/inventory/transaction/InventoryTransaction.php index e7b4a6d3fc..ea506e388c 100644 --- a/src/inventory/transaction/InventoryTransaction.php +++ b/src/inventory/transaction/InventoryTransaction.php @@ -142,8 +142,10 @@ class InventoryTransaction{ $needItems[] = $action->getTargetItem(); } - if(!$action->isValid($this->source)){ - throw new TransactionValidationException("Action " . get_class($action) . " is not valid in the current transaction"); + try{ + $action->validate($this->source); + }catch(TransactionValidationException $e){ + throw new TransactionValidationException(get_class($action) . ": " . $e->getMessage(), 0, $e); } if(!$action->getSourceItem()->isNull()){ diff --git a/src/inventory/transaction/action/CreateItemAction.php b/src/inventory/transaction/action/CreateItemAction.php index 18cd4a5368..dbe02798ee 100644 --- a/src/inventory/transaction/action/CreateItemAction.php +++ b/src/inventory/transaction/action/CreateItemAction.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\inventory\transaction\action; use pocketmine\inventory\CreativeInventory; +use pocketmine\inventory\transaction\TransactionValidationException; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\player\Player; @@ -38,8 +39,13 @@ class CreateItemAction extends InventoryAction{ parent::__construct($sourceItem, ItemFactory::air()); } - public function isValid(Player $source) : bool{ - return !$source->hasFiniteResources() and CreativeInventory::getInstance()->contains($this->sourceItem); + public function validate(Player $source) : void{ + if($source->hasFiniteResources()){ + throw new TransactionValidationException("Player has finite resources, cannot create items"); + } + if(!CreativeInventory::getInstance()->contains($this->sourceItem)){ + throw new TransactionValidationException("Creative inventory does not contain requested item"); + } } public function execute(Player $source) : void{ diff --git a/src/inventory/transaction/action/DestroyItemAction.php b/src/inventory/transaction/action/DestroyItemAction.php index d59485c072..6edd30af2a 100644 --- a/src/inventory/transaction/action/DestroyItemAction.php +++ b/src/inventory/transaction/action/DestroyItemAction.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\inventory\transaction\action; +use pocketmine\inventory\transaction\TransactionValidationException; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\player\Player; @@ -37,8 +38,10 @@ class DestroyItemAction extends InventoryAction{ parent::__construct(ItemFactory::air(), $targetItem); } - public function isValid(Player $source) : bool{ - return !$source->hasFiniteResources(); + public function validate(Player $source) : void{ + if($source->hasFiniteResources()){ + throw new TransactionValidationException("Player has finite resources, cannot destroy items"); + } } public function execute(Player $source) : void{ diff --git a/src/inventory/transaction/action/DropItemAction.php b/src/inventory/transaction/action/DropItemAction.php index a15e3fdd05..2e20d5f93d 100644 --- a/src/inventory/transaction/action/DropItemAction.php +++ b/src/inventory/transaction/action/DropItemAction.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\inventory\transaction\action; use pocketmine\event\player\PlayerDropItemEvent; +use pocketmine\inventory\transaction\TransactionValidationException; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\player\Player; @@ -37,8 +38,10 @@ class DropItemAction extends InventoryAction{ parent::__construct(ItemFactory::air(), $targetItem); } - public function isValid(Player $source) : bool{ - return !$this->targetItem->isNull(); + public function validate(Player $source) : void{ + if($this->targetItem->isNull()){ + throw new TransactionValidationException("Cannot drop an empty itemstack"); + } } public function onPreExecute(Player $source) : bool{ diff --git a/src/inventory/transaction/action/InventoryAction.php b/src/inventory/transaction/action/InventoryAction.php index 5b1e8db5db..4fa3ac15e5 100644 --- a/src/inventory/transaction/action/InventoryAction.php +++ b/src/inventory/transaction/action/InventoryAction.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\inventory\transaction\action; use pocketmine\inventory\transaction\InventoryTransaction; +use pocketmine\inventory\transaction\TransactionValidationException; use pocketmine\item\Item; use pocketmine\player\Player; @@ -57,8 +58,10 @@ abstract class InventoryAction{ /** * Returns whether this action is currently valid. This should perform any necessary sanity checks. + * + * @throws TransactionValidationException */ - abstract public function isValid(Player $source) : bool; + abstract public function validate(Player $source) : void; /** * Called when the action is added to the specified InventoryTransaction. diff --git a/src/inventory/transaction/action/SlotChangeAction.php b/src/inventory/transaction/action/SlotChangeAction.php index eda92b4579..1686c261bb 100644 --- a/src/inventory/transaction/action/SlotChangeAction.php +++ b/src/inventory/transaction/action/SlotChangeAction.php @@ -25,6 +25,7 @@ namespace pocketmine\inventory\transaction\action; use pocketmine\inventory\Inventory; use pocketmine\inventory\transaction\InventoryTransaction; +use pocketmine\inventory\transaction\TransactionValidationException; use pocketmine\item\Item; use pocketmine\player\Player; @@ -60,12 +61,16 @@ class SlotChangeAction extends InventoryAction{ /** * Checks if the item in the inventory at the specified slot is the same as this action's source item. + * + * @throws TransactionValidationException */ - public function isValid(Player $source) : bool{ - return ( - $this->inventory->slotExists($this->inventorySlot) and - $this->inventory->getItem($this->inventorySlot)->equalsExact($this->sourceItem) - ); + public function validate(Player $source) : void{ + if(!$this->inventory->slotExists($this->inventorySlot)){ + throw new TransactionValidationException("Slot does not exist"); + } + if(!$this->inventory->getItem($this->inventorySlot)->equalsExact($this->sourceItem)){ + throw new TransactionValidationException("Slot does not contain expected original item"); + } } /** From ae179e503999041d9e2e3259c00443a1b2eaf1e2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 4 Jul 2020 23:46:26 +0100 Subject: [PATCH 1752/3224] fix interacting with anvil & enchanting table inventories --- src/network/mcpe/convert/TypeConverter.php | 52 ++++++++++++++++------ 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index 088f202fd4..11a83d6625 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -22,7 +22,10 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\convert; +use pocketmine\block\inventory\AnvilInventory; +use pocketmine\block\inventory\EnchantInventory; use pocketmine\crafting\CraftingGrid; +use pocketmine\inventory\Inventory; use pocketmine\inventory\transaction\action\CreateItemAction; use pocketmine\inventory\transaction\action\DestroyItemAction; use pocketmine\inventory\transaction\action\DropItemAction; @@ -157,6 +160,22 @@ class TypeConverter{ ); } + /** + * @param int[] $test + * @phpstan-param array $test + * @phpstan-param \Closure(Inventory) : bool $c + * @phpstan-return array{int, Inventory} + */ + protected function mapUIInventory(int $slot, array $test, ?Inventory $inventory, \Closure $c) : ?array{ + if($inventory === null){ + return null; + } + if(array_key_exists($slot, $test) && $c($inventory)){ + return [$test[$slot], $inventory]; + } + return null; + } + /** * @throws \UnexpectedValueException */ @@ -173,21 +192,26 @@ class TypeConverter{ if($action->inventorySlot === UIInventorySlotOffset::CREATED_ITEM_OUTPUT){ return null; //useless noise } - if(array_key_exists($action->inventorySlot, UIInventorySlotOffset::CRAFTING2X2_INPUT)){ - $window = $player->getCraftingGrid(); - if($window->getGridWidth() !== CraftingGrid::SIZE_SMALL){ - throw new \UnexpectedValueException("Expected small crafting grid"); - } - $slot = UIInventorySlotOffset::CRAFTING2X2_INPUT[$action->inventorySlot]; - }elseif(array_key_exists($action->inventorySlot, UIInventorySlotOffset::CRAFTING3X3_INPUT)){ - $window = $player->getCraftingGrid(); - if($window->getGridWidth() !== CraftingGrid::SIZE_BIG){ - throw new \UnexpectedValueException("Expected big crafting grid"); - } - $slot = UIInventorySlotOffset::CRAFTING3X3_INPUT[$action->inventorySlot]; - }else{ - throw new \UnexpectedValueException("Unhandled magic UI slot offset $action->inventorySlot"); + $pSlot = $action->inventorySlot; + + $craftingGrid = $player->getCraftingGrid(); + $mapped = + $this->mapUIInventory($pSlot, UIInventorySlotOffset::CRAFTING2X2_INPUT, $craftingGrid, + function(Inventory $i) : bool{ return $i instanceof CraftingGrid && $i->getGridWidth() === CraftingGrid::SIZE_SMALL; }) ?? + $this->mapUIInventory($pSlot, UIInventorySlotOffset::CRAFTING3X3_INPUT, $craftingGrid, + function(Inventory $i) : bool{ return $i instanceof CraftingGrid && $i->getGridWidth() === CraftingGrid::SIZE_BIG; }); + if($mapped === null){ + $current = $player->getCurrentWindow(); + $mapped = + $this->mapUIInventory($pSlot, UIInventorySlotOffset::ANVIL, $current, + function(Inventory $i) : bool{ return $i instanceof AnvilInventory; }) ?? + $this->mapUIInventory($pSlot, UIInventorySlotOffset::ENCHANTING_TABLE, $current, + function(Inventory $i) : bool{ return $i instanceof EnchantInventory; }); } + if($mapped === null){ + throw new \UnexpectedValueException("Unmatched UI inventory slot offset $pSlot"); + } + [$slot, $window] = $mapped; }else{ $window = $player->getNetworkSession()->getInvManager()->getWindow($action->windowId); $slot = $action->inventorySlot; From 2219f61ea0dd44303487f27ff5c85da995493897 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Jul 2020 11:13:29 +0100 Subject: [PATCH 1753/3224] BlockLegacyMetadata: added constants for chemistry table variants --- src/block/BlockLegacyMetadata.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/block/BlockLegacyMetadata.php b/src/block/BlockLegacyMetadata.php index 016057c4e1..91f85e0eba 100644 --- a/src/block/BlockLegacyMetadata.php +++ b/src/block/BlockLegacyMetadata.php @@ -53,6 +53,11 @@ final class BlockLegacyMetadata{ public const BUTTON_FLAG_POWERED = 0x08; + public const CHEMISTRY_COMPOUND_CREATOR = 0; + public const CHEMISTRY_MATERIAL_REDUCER = 4; + public const CHEMISTRY_ELEMENT_CONSTRUCTOR = 8; + public const CHEMISTRY_LAB_TABLE = 12; + public const COLORED_TORCH_BP_BLUE = 0; public const COLORED_TORCH_BP_PURPLE = 8; public const COLORED_TORCH_RG_RED = 0; From eddb2b7fdd0a087d4593838f662cbb5783b75446 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Jul 2020 16:52:42 +0100 Subject: [PATCH 1754/3224] Moved some legacyID mapping code to a separate BlockLegacyIdHelper this makes the code more reusable and will facilitate getting rid of legacy IDs from within the core code. --- src/block/BlockFactory.php | 78 ++------------- src/block/BlockLegacyIdHelper.php | 161 ++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+), 71 deletions(-) create mode 100644 src/block/BlockLegacyIdHelper.php diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 7306fd088c..2c68bd7067 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -41,7 +41,6 @@ use pocketmine\block\tile\Hopper as TileHopper; use pocketmine\block\tile\ItemFrame as TileItemFrame; use pocketmine\block\tile\MonsterSpawner as TileMonsterSpawner; use pocketmine\block\tile\Note as TileNote; -use pocketmine\block\tile\Sign as TileSign; use pocketmine\block\tile\Skull as TileSkull; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\InvalidBlockStateException; @@ -409,69 +408,6 @@ class BlockFactory{ $this->register(new WeightedPressurePlateLight(new BID(Ids::LIGHT_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Light")); $this->register(new Wheat(new BID(Ids::WHEAT_BLOCK), "Wheat Block")); - //region ugly treetype -> blockID mapping tables - $woodenStairIds = [ - TreeType::OAK()->id() => Ids::OAK_STAIRS, - TreeType::SPRUCE()->id() => Ids::SPRUCE_STAIRS, - TreeType::BIRCH()->id() => Ids::BIRCH_STAIRS, - TreeType::JUNGLE()->id() => Ids::JUNGLE_STAIRS, - TreeType::ACACIA()->id() => Ids::ACACIA_STAIRS, - TreeType::DARK_OAK()->id() => Ids::DARK_OAK_STAIRS - ]; - $fenceGateIds = [ - TreeType::OAK()->id() => Ids::OAK_FENCE_GATE, - TreeType::SPRUCE()->id() => Ids::SPRUCE_FENCE_GATE, - TreeType::BIRCH()->id() => Ids::BIRCH_FENCE_GATE, - TreeType::JUNGLE()->id() => Ids::JUNGLE_FENCE_GATE, - TreeType::ACACIA()->id() => Ids::ACACIA_FENCE_GATE, - TreeType::DARK_OAK()->id() => Ids::DARK_OAK_FENCE_GATE - ]; - - /** @var BID[] $woodenDoorIds */ - $woodenDoorIds = [ - TreeType::OAK()->id() => new BID(Ids::OAK_DOOR_BLOCK, 0, ItemIds::OAK_DOOR), - TreeType::SPRUCE()->id() => new BID(Ids::SPRUCE_DOOR_BLOCK, 0, ItemIds::SPRUCE_DOOR), - TreeType::BIRCH()->id() => new BID(Ids::BIRCH_DOOR_BLOCK, 0, ItemIds::BIRCH_DOOR), - TreeType::JUNGLE()->id() => new BID(Ids::JUNGLE_DOOR_BLOCK, 0, ItemIds::JUNGLE_DOOR), - TreeType::ACACIA()->id() => new BID(Ids::ACACIA_DOOR_BLOCK, 0, ItemIds::ACACIA_DOOR), - TreeType::DARK_OAK()->id() => new BID(Ids::DARK_OAK_DOOR_BLOCK, 0, ItemIds::DARK_OAK_DOOR) - ]; - $woodenPressurePlateIds = [ - TreeType::OAK()->id() => Ids::WOODEN_PRESSURE_PLATE, - TreeType::SPRUCE()->id() => Ids::SPRUCE_PRESSURE_PLATE, - TreeType::BIRCH()->id() => Ids::BIRCH_PRESSURE_PLATE, - TreeType::JUNGLE()->id() => Ids::JUNGLE_PRESSURE_PLATE, - TreeType::ACACIA()->id() => Ids::ACACIA_PRESSURE_PLATE, - TreeType::DARK_OAK()->id() => Ids::DARK_OAK_PRESSURE_PLATE - ]; - $woodenButtonIds = [ - TreeType::OAK()->id() => Ids::WOODEN_BUTTON, - TreeType::SPRUCE()->id() => Ids::SPRUCE_BUTTON, - TreeType::BIRCH()->id() => Ids::BIRCH_BUTTON, - TreeType::JUNGLE()->id() => Ids::JUNGLE_BUTTON, - TreeType::ACACIA()->id() => Ids::ACACIA_BUTTON, - TreeType::DARK_OAK()->id() => Ids::DARK_OAK_BUTTON - ]; - $woodenTrapdoorIds = [ - TreeType::OAK()->id() => Ids::WOODEN_TRAPDOOR, - TreeType::SPRUCE()->id() => Ids::SPRUCE_TRAPDOOR, - TreeType::BIRCH()->id() => Ids::BIRCH_TRAPDOOR, - TreeType::JUNGLE()->id() => Ids::JUNGLE_TRAPDOOR, - TreeType::ACACIA()->id() => Ids::ACACIA_TRAPDOOR, - TreeType::DARK_OAK()->id() => Ids::DARK_OAK_TRAPDOOR - ]; - - /** @var BIDFlattened[] $woodenSignIds */ - $woodenSignIds = [ - TreeType::OAK()->id() => new BIDFlattened(Ids::SIGN_POST, Ids::WALL_SIGN, 0, ItemIds::SIGN, TileSign::class), - TreeType::SPRUCE()->id() => new BIDFlattened(Ids::SPRUCE_STANDING_SIGN, Ids::SPRUCE_WALL_SIGN, 0, ItemIds::SPRUCE_SIGN, TileSign::class), - TreeType::BIRCH()->id() => new BIDFlattened(Ids::BIRCH_STANDING_SIGN, Ids::BIRCH_WALL_SIGN, 0, ItemIds::BIRCH_SIGN, TileSign::class), - TreeType::JUNGLE()->id() => new BIDFlattened(Ids::JUNGLE_STANDING_SIGN, Ids::JUNGLE_WALL_SIGN, 0, ItemIds::JUNGLE_SIGN, TileSign::class), - TreeType::ACACIA()->id() => new BIDFlattened(Ids::ACACIA_STANDING_SIGN, Ids::ACACIA_WALL_SIGN, 0, ItemIds::ACACIA_SIGN, TileSign::class), - TreeType::DARK_OAK()->id() => new BIDFlattened(Ids::DARKOAK_STANDING_SIGN, Ids::DARKOAK_WALL_SIGN, 0, ItemIds::DARKOAK_SIGN, TileSign::class) - ]; - //endregion - foreach(TreeType::getAll() as $treeType){ $magicNumber = $treeType->getMagicNumber(); $name = $treeType->getDisplayName(); @@ -488,15 +424,15 @@ class BlockFactory{ $this->register($wood); $this->remap($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, ($magicNumber & 0x03) | 0b1100, $wood); - $this->register(new FenceGate(new BID($fenceGateIds[$treeType->id()]), $treeType->getDisplayName() . " Fence Gate")); - $this->register(new WoodenStairs(new BID($woodenStairIds[$treeType->id()]), $treeType->getDisplayName() . " Stairs")); - $this->register(new WoodenDoor($woodenDoorIds[$treeType->id()], $treeType->getDisplayName() . " Door")); + $this->register(new FenceGate(BlockLegacyIdHelper::getWoodenFenceIdentifier($treeType), $treeType->getDisplayName() . " Fence Gate")); + $this->register(new WoodenStairs(BlockLegacyIdHelper::getWoodenStairsIdentifier($treeType), $treeType->getDisplayName() . " Stairs")); + $this->register(new WoodenDoor(BlockLegacyIdHelper::getWoodenDoorIdentifier($treeType), $treeType->getDisplayName() . " Door")); - $this->register(new WoodenButton(new BID($woodenButtonIds[$treeType->id()]), $treeType->getDisplayName() . " Button")); - $this->register(new WoodenPressurePlate(new BID($woodenPressurePlateIds[$treeType->id()]), $treeType->getDisplayName() . " Pressure Plate")); - $this->register(new WoodenTrapdoor(new BID($woodenTrapdoorIds[$treeType->id()]), $treeType->getDisplayName() . " Trapdoor")); + $this->register(new WoodenButton(BlockLegacyIdHelper::getWoodenButtonIdentifier($treeType), $treeType->getDisplayName() . " Button")); + $this->register(new WoodenPressurePlate(BlockLegacyIdHelper::getWoodenPressurePlateIdentifier($treeType), $treeType->getDisplayName() . " Pressure Plate")); + $this->register(new WoodenTrapdoor(BlockLegacyIdHelper::getWoodenTrapdoorIdentifier($treeType), $treeType->getDisplayName() . " Trapdoor")); - $this->register(new Sign($woodenSignIds[$treeType->id()], $treeType->getDisplayName() . " Sign")); + $this->register(new Sign(BlockLegacyIdHelper::getWoodenSignIdentifier($treeType), $treeType->getDisplayName() . " Sign")); } static $sandstoneTypes = [ diff --git a/src/block/BlockLegacyIdHelper.php b/src/block/BlockLegacyIdHelper.php new file mode 100644 index 0000000000..6288afa393 --- /dev/null +++ b/src/block/BlockLegacyIdHelper.php @@ -0,0 +1,161 @@ +id()){ + case TreeType::OAK()->id(): + return new BIDFlattened(Ids::SIGN_POST, Ids::WALL_SIGN, 0, ItemIds::SIGN, TileSign::class); + case TreeType::SPRUCE()->id(): + return new BIDFlattened(Ids::SPRUCE_STANDING_SIGN, Ids::SPRUCE_WALL_SIGN, 0, ItemIds::SPRUCE_SIGN, TileSign::class); + case TreeType::BIRCH()->id(): + return new BIDFlattened(Ids::BIRCH_STANDING_SIGN, Ids::BIRCH_WALL_SIGN, 0, ItemIds::BIRCH_SIGN, TileSign::class); + case TreeType::JUNGLE()->id(): + return new BIDFlattened(Ids::JUNGLE_STANDING_SIGN, Ids::JUNGLE_WALL_SIGN, 0, ItemIds::JUNGLE_SIGN, TileSign::class); + case TreeType::ACACIA()->id(): + return new BIDFlattened(Ids::ACACIA_STANDING_SIGN, Ids::ACACIA_WALL_SIGN, 0, ItemIds::ACACIA_SIGN, TileSign::class); + case TreeType::DARK_OAK()->id(): + return new BIDFlattened(Ids::DARKOAK_STANDING_SIGN, Ids::DARKOAK_WALL_SIGN, 0, ItemIds::DARKOAK_SIGN, TileSign::class); + } + throw new AssumptionFailedError("Switch should cover all wood types"); + } + + public static function getWoodenTrapdoorIdentifier(TreeType $treeType) : BlockIdentifier{ + switch($treeType->id()){ + case TreeType::OAK()->id(): + return new BlockIdentifier(Ids::WOODEN_TRAPDOOR); + case TreeType::SPRUCE()->id(): + return new BlockIdentifier(Ids::SPRUCE_TRAPDOOR); + case TreeType::BIRCH()->id(): + return new BlockIdentifier(Ids::BIRCH_TRAPDOOR); + case TreeType::JUNGLE()->id(): + return new BlockIdentifier(Ids::JUNGLE_TRAPDOOR); + case TreeType::ACACIA()->id(): + return new BlockIdentifier(Ids::ACACIA_TRAPDOOR); + case TreeType::DARK_OAK()->id(): + return new BlockIdentifier(Ids::DARK_OAK_TRAPDOOR); + } + throw new AssumptionFailedError("Switch should cover all wood types"); + } + + public static function getWoodenButtonIdentifier(TreeType $treeType) : BlockIdentifier{ + switch($treeType->id()){ + case TreeType::OAK()->id(): + return new BlockIdentifier(Ids::WOODEN_BUTTON); + case TreeType::SPRUCE()->id(): + return new BlockIdentifier(Ids::SPRUCE_BUTTON); + case TreeType::BIRCH()->id(): + return new BlockIdentifier(Ids::BIRCH_BUTTON); + case TreeType::JUNGLE()->id(): + return new BlockIdentifier(Ids::JUNGLE_BUTTON); + case TreeType::ACACIA()->id(): + return new BlockIdentifier(Ids::ACACIA_BUTTON); + case TreeType::DARK_OAK()->id(): + return new BlockIdentifier(Ids::DARK_OAK_BUTTON); + } + throw new AssumptionFailedError("Switch should cover all wood types"); + } + + public static function getWoodenPressurePlateIdentifier(TreeType $treeType) : BlockIdentifier{ + switch($treeType->id()){ + case TreeType::OAK()->id(): + return new BlockIdentifier(Ids::WOODEN_PRESSURE_PLATE); + case TreeType::SPRUCE()->id(): + return new BlockIdentifier(Ids::SPRUCE_PRESSURE_PLATE); + case TreeType::BIRCH()->id(): + return new BlockIdentifier(Ids::BIRCH_PRESSURE_PLATE); + case TreeType::JUNGLE()->id(): + return new BlockIdentifier(Ids::JUNGLE_PRESSURE_PLATE); + case TreeType::ACACIA()->id(): + return new BlockIdentifier(Ids::ACACIA_PRESSURE_PLATE); + case TreeType::DARK_OAK()->id(): + return new BlockIdentifier(Ids::DARK_OAK_PRESSURE_PLATE); + } + throw new AssumptionFailedError("Switch should cover all wood types"); + } + + public static function getWoodenDoorIdentifier(TreeType $treeType) : BlockIdentifier{ + switch($treeType->id()){ + case TreeType::OAK()->id(): + return new BID(Ids::OAK_DOOR_BLOCK, 0, ItemIds::OAK_DOOR); + case TreeType::SPRUCE()->id(): + return new BID(Ids::SPRUCE_DOOR_BLOCK, 0, ItemIds::SPRUCE_DOOR); + case TreeType::BIRCH()->id(): + return new BID(Ids::BIRCH_DOOR_BLOCK, 0, ItemIds::BIRCH_DOOR); + case TreeType::JUNGLE()->id(): + return new BID(Ids::JUNGLE_DOOR_BLOCK, 0, ItemIds::JUNGLE_DOOR); + case TreeType::ACACIA()->id(): + return new BID(Ids::ACACIA_DOOR_BLOCK, 0, ItemIds::ACACIA_DOOR); + case TreeType::DARK_OAK()->id(): + return new BID(Ids::DARK_OAK_DOOR_BLOCK, 0, ItemIds::DARK_OAK_DOOR); + } + throw new AssumptionFailedError("Switch should cover all wood types"); + } + + public static function getWoodenFenceIdentifier(TreeType $treeType) : BlockIdentifier{ + switch($treeType->id()){ + case TreeType::OAK()->id(): + return new BlockIdentifier(Ids::OAK_FENCE_GATE); + case TreeType::SPRUCE()->id(): + return new BlockIdentifier(Ids::SPRUCE_FENCE_GATE); + case TreeType::BIRCH()->id(): + return new BlockIdentifier(Ids::BIRCH_FENCE_GATE); + case TreeType::JUNGLE()->id(): + return new BlockIdentifier(Ids::JUNGLE_FENCE_GATE); + case TreeType::ACACIA()->id(): + return new BlockIdentifier(Ids::ACACIA_FENCE_GATE); + case TreeType::DARK_OAK()->id(): + return new BlockIdentifier(Ids::DARK_OAK_FENCE_GATE); + } + throw new AssumptionFailedError("Switch should cover all wood types"); + } + + public static function getWoodenStairsIdentifier(TreeType $treeType) : BlockIdentifier{ + switch($treeType->id()){ + case TreeType::OAK()->id(): + return new BlockIdentifier(Ids::OAK_STAIRS); + case TreeType::SPRUCE()->id(): + return new BlockIdentifier(Ids::SPRUCE_STAIRS); + case TreeType::BIRCH()->id(): + return new BlockIdentifier(Ids::BIRCH_STAIRS); + case TreeType::JUNGLE()->id(): + return new BlockIdentifier(Ids::JUNGLE_STAIRS); + case TreeType::ACACIA()->id(): + return new BlockIdentifier(Ids::ACACIA_STAIRS); + case TreeType::DARK_OAK()->id(): + return new BlockIdentifier(Ids::DARK_OAK_STAIRS); + } + throw new AssumptionFailedError("Switch should cover all wood types"); + } +} From 79d8bf898ac888b37bfa1099323f30893e8078d1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Jul 2020 18:20:41 +0100 Subject: [PATCH 1755/3224] Moved glazed-terracotta ID-mapping table to BlockLegacyIdHelper --- src/block/BlockFactory.php | 24 +------------------ src/block/BlockLegacyIdHelper.php | 39 +++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 2c68bd7067..a13120a7a4 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -451,35 +451,13 @@ class BlockFactory{ $this->register(new Opaque(new BID(Ids::RED_SANDSTONE, $variant), $prefix . "Red Sandstone", $sandstoneBreakInfo)); } - //region ugly glazed-terracotta colour -> ID mapping table - /** @var int[] */ - $glazedTerracottaIds = [ - DyeColor::WHITE()->id() => Ids::WHITE_GLAZED_TERRACOTTA, - DyeColor::ORANGE()->id() => Ids::ORANGE_GLAZED_TERRACOTTA, - DyeColor::MAGENTA()->id() => Ids::MAGENTA_GLAZED_TERRACOTTA, - DyeColor::LIGHT_BLUE()->id() => Ids::LIGHT_BLUE_GLAZED_TERRACOTTA, - DyeColor::YELLOW()->id() => Ids::YELLOW_GLAZED_TERRACOTTA, - DyeColor::LIME()->id() => Ids::LIME_GLAZED_TERRACOTTA, - DyeColor::PINK()->id() => Ids::PINK_GLAZED_TERRACOTTA, - DyeColor::GRAY()->id() => Ids::GRAY_GLAZED_TERRACOTTA, - DyeColor::LIGHT_GRAY()->id() => Ids::SILVER_GLAZED_TERRACOTTA, - DyeColor::CYAN()->id() => Ids::CYAN_GLAZED_TERRACOTTA, - DyeColor::PURPLE()->id() => Ids::PURPLE_GLAZED_TERRACOTTA, - DyeColor::BLUE()->id() => Ids::BLUE_GLAZED_TERRACOTTA, - DyeColor::BROWN()->id() => Ids::BROWN_GLAZED_TERRACOTTA, - DyeColor::GREEN()->id() => Ids::GREEN_GLAZED_TERRACOTTA, - DyeColor::RED()->id() => Ids::RED_GLAZED_TERRACOTTA, - DyeColor::BLACK()->id() => Ids::BLACK_GLAZED_TERRACOTTA - ]; - //endregion - foreach(DyeColor::getAll() as $color){ $this->register(new Carpet(new BID(Ids::CARPET, $color->getMagicNumber()), $color->getDisplayName() . " Carpet")); $this->register(new Concrete(new BID(Ids::CONCRETE, $color->getMagicNumber()), $color->getDisplayName() . " Concrete")); $this->register(new ConcretePowder(new BID(Ids::CONCRETE_POWDER, $color->getMagicNumber()), $color->getDisplayName() . " Concrete Powder")); $this->register(new Glass(new BID(Ids::STAINED_GLASS, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass")); $this->register(new GlassPane(new BID(Ids::STAINED_GLASS_PANE, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass Pane")); - $this->register(new GlazedTerracotta(new BID($glazedTerracottaIds[$color->id()]), $color->getDisplayName() . " Glazed Terracotta")); + $this->register(new GlazedTerracotta(BlockLegacyIdHelper::getGlazedTerracottaIdentifier($color), $color->getDisplayName() . " Glazed Terracotta")); $this->register(new HardenedClay(new BID(Ids::STAINED_CLAY, $color->getMagicNumber()), $color->getDisplayName() . " Stained Clay")); $this->register(new HardenedGlass(new BID(Ids::HARD_STAINED_GLASS, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass")); $this->register(new HardenedGlassPane(new BID(Ids::HARD_STAINED_GLASS_PANE, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass Pane")); diff --git a/src/block/BlockLegacyIdHelper.php b/src/block/BlockLegacyIdHelper.php index 6288afa393..549e4ac85c 100644 --- a/src/block/BlockLegacyIdHelper.php +++ b/src/block/BlockLegacyIdHelper.php @@ -27,6 +27,7 @@ use pocketmine\block\BlockIdentifier as BID; use pocketmine\block\BlockIdentifierFlattened as BIDFlattened; use pocketmine\block\BlockLegacyIds as Ids; use pocketmine\block\tile\Sign as TileSign; +use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\TreeType; use pocketmine\item\ItemIds; use pocketmine\utils\AssumptionFailedError; @@ -158,4 +159,42 @@ final class BlockLegacyIdHelper{ } throw new AssumptionFailedError("Switch should cover all wood types"); } + + public static function getGlazedTerracottaIdentifier(DyeColor $color) : BlockIdentifier{ + switch($color->id()){ + case DyeColor::WHITE()->id(): + return new BlockIdentifier(Ids::WHITE_GLAZED_TERRACOTTA); + case DyeColor::ORANGE()->id(): + return new BlockIdentifier(Ids::ORANGE_GLAZED_TERRACOTTA); + case DyeColor::MAGENTA()->id(): + return new BlockIdentifier(Ids::MAGENTA_GLAZED_TERRACOTTA); + case DyeColor::LIGHT_BLUE()->id(): + return new BlockIdentifier(Ids::LIGHT_BLUE_GLAZED_TERRACOTTA); + case DyeColor::YELLOW()->id(): + return new BlockIdentifier(Ids::YELLOW_GLAZED_TERRACOTTA); + case DyeColor::LIME()->id(): + return new BlockIdentifier(Ids::LIME_GLAZED_TERRACOTTA); + case DyeColor::PINK()->id(): + return new BlockIdentifier(Ids::PINK_GLAZED_TERRACOTTA); + case DyeColor::GRAY()->id(): + return new BlockIdentifier(Ids::GRAY_GLAZED_TERRACOTTA); + case DyeColor::LIGHT_GRAY()->id(): + return new BlockIdentifier(Ids::SILVER_GLAZED_TERRACOTTA); + case DyeColor::CYAN()->id(): + return new BlockIdentifier(Ids::CYAN_GLAZED_TERRACOTTA); + case DyeColor::PURPLE()->id(): + return new BlockIdentifier(Ids::PURPLE_GLAZED_TERRACOTTA); + case DyeColor::BLUE()->id(): + return new BlockIdentifier(Ids::BLUE_GLAZED_TERRACOTTA); + case DyeColor::BROWN()->id(): + return new BlockIdentifier(Ids::BROWN_GLAZED_TERRACOTTA); + case DyeColor::GREEN()->id(): + return new BlockIdentifier(Ids::GREEN_GLAZED_TERRACOTTA); + case DyeColor::RED()->id(): + return new BlockIdentifier(Ids::RED_GLAZED_TERRACOTTA); + case DyeColor::BLACK()->id(): + return new BlockIdentifier(Ids::BLACK_GLAZED_TERRACOTTA); + } + throw new AssumptionFailedError("Switch should cover all wood types"); + } } From bf5da596f73be3471f3ca47a7daa48c4ca5283da Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Jul 2020 18:27:10 +0100 Subject: [PATCH 1756/3224] Get rid of WALL metadata mapping --- src/block/BlockFactory.php | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index a13120a7a4..1864f5dd96 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -464,25 +464,20 @@ class BlockFactory{ $this->register(new Wool(new BID(Ids::WOOL, $color->getMagicNumber()), $color->getDisplayName() . " Wool")); } - static $wallTypes = [ - Meta::WALL_ANDESITE => "Andesite", - Meta::WALL_BRICK => "Brick", - Meta::WALL_DIORITE => "Diorite", - Meta::WALL_END_STONE_BRICK => "End Stone Brick", - Meta::WALL_GRANITE => "Granite", - Meta::WALL_MOSSY_STONE_BRICK => "Mossy Stone Brick", - Meta::WALL_MOSSY_COBBLESTONE => "Mossy Cobblestone", - Meta::WALL_NETHER_BRICK => "Nether Brick", - Meta::WALL_COBBLESTONE => "Cobblestone", - Meta::WALL_PRISMARINE => "Prismarine", - Meta::WALL_RED_NETHER_BRICK => "Red Nether Brick", - Meta::WALL_RED_SANDSTONE => "Red Sandstone", - Meta::WALL_SANDSTONE => "Sandstone", - Meta::WALL_STONE_BRICK => "Stone Brick" - ]; - foreach($wallTypes as $magicNumber => $prefix){ - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, $magicNumber), $prefix . " Wall")); - } + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_ANDESITE), "Andesite Wall")); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_BRICK), "Brick Wall")); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_DIORITE), "Diorite Wall")); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_END_STONE_BRICK), "End Stone Brick Wall")); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_GRANITE), "Granite Wall")); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_MOSSY_STONE_BRICK), "Mossy Stone Brick Wall")); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_MOSSY_COBBLESTONE), "Mossy Cobblestone Wall")); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_NETHER_BRICK), "Nether Brick Wall")); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_COBBLESTONE), "Cobblestone Wall")); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_PRISMARINE), "Prismarine Wall")); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_RED_NETHER_BRICK), "Red Nether Brick Wall")); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_RED_SANDSTONE), "Red Sandstone Wall")); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_SANDSTONE), "Sandstone Wall")); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_STONE_BRICK), "Stone Brick Wall")); $this->registerElements(); From 68c408268c9f00dbbac080eb56f85b6f49f67e02 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Jul 2020 19:04:22 +0100 Subject: [PATCH 1757/3224] Separate dye colour ID management from DyeColor enum --- src/block/Banner.php | 3 +- src/block/Bed.php | 3 +- src/block/BlockFactory.php | 20 +++---- src/block/tile/Banner.php | 16 +++--- src/block/tile/Bed.php | 7 +-- src/block/utils/DyeColor.php | 71 ++++++------------------- src/data/bedrock/DyeColorIdMap.php | 83 ++++++++++++++++++++++++++++++ src/item/Banner.php | 7 ++- src/item/ItemFactory.php | 8 +-- 9 files changed, 139 insertions(+), 79 deletions(-) create mode 100644 src/data/bedrock/DyeColorIdMap.php diff --git a/src/block/Banner.php b/src/block/Banner.php index c9ba9c5c92..683b90051f 100644 --- a/src/block/Banner.php +++ b/src/block/Banner.php @@ -28,6 +28,7 @@ use pocketmine\block\tile\Banner as TileBanner; use pocketmine\block\utils\BannerPattern; use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\DyeColor; +use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\item\Banner as ItemBanner; use pocketmine\item\Item; use pocketmine\item\ItemFactory; @@ -176,7 +177,7 @@ class Banner extends Transparent{ } public function asItem() : Item{ - return ItemFactory::getInstance()->get(ItemIds::BANNER, $this->baseColor->getInvertedMagicNumber()); + return ItemFactory::getInstance()->get(ItemIds::BANNER, DyeColorIdMap::getInstance()->toInvertedId($this->baseColor)); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/block/Bed.php b/src/block/Bed.php index 57c643fef0..5c457641cf 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\block\tile\Bed as TileBed; use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\DyeColor; +use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\item\Bed as ItemBed; use pocketmine\item\Item; use pocketmine\item\ItemFactory; @@ -193,7 +194,7 @@ class Bed extends Transparent{ } public function asItem() : Item{ - return ItemFactory::getInstance()->get($this->idInfo->getItemId(), $this->color->getMagicNumber()); + return ItemFactory::getInstance()->get($this->idInfo->getItemId(), DyeColorIdMap::getInstance()->toId($this->color)); } public function getAffectedBlocks() : array{ diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 1864f5dd96..32b7f2f8ae 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -46,6 +46,7 @@ use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\block\utils\PillarRotationTrait; use pocketmine\block\utils\TreeType; +use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\item\Item; use pocketmine\item\ItemIds; use pocketmine\item\ToolTier; @@ -451,17 +452,18 @@ class BlockFactory{ $this->register(new Opaque(new BID(Ids::RED_SANDSTONE, $variant), $prefix . "Red Sandstone", $sandstoneBreakInfo)); } + $colorIdMap = DyeColorIdMap::getInstance(); foreach(DyeColor::getAll() as $color){ - $this->register(new Carpet(new BID(Ids::CARPET, $color->getMagicNumber()), $color->getDisplayName() . " Carpet")); - $this->register(new Concrete(new BID(Ids::CONCRETE, $color->getMagicNumber()), $color->getDisplayName() . " Concrete")); - $this->register(new ConcretePowder(new BID(Ids::CONCRETE_POWDER, $color->getMagicNumber()), $color->getDisplayName() . " Concrete Powder")); - $this->register(new Glass(new BID(Ids::STAINED_GLASS, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass")); - $this->register(new GlassPane(new BID(Ids::STAINED_GLASS_PANE, $color->getMagicNumber()), $color->getDisplayName() . " Stained Glass Pane")); + $this->register(new Carpet(new BID(Ids::CARPET, $colorIdMap->toId($color)), $color->getDisplayName() . " Carpet")); + $this->register(new Concrete(new BID(Ids::CONCRETE, $colorIdMap->toId($color)), $color->getDisplayName() . " Concrete")); + $this->register(new ConcretePowder(new BID(Ids::CONCRETE_POWDER, $colorIdMap->toId($color)), $color->getDisplayName() . " Concrete Powder")); + $this->register(new Glass(new BID(Ids::STAINED_GLASS, $colorIdMap->toId($color)), $color->getDisplayName() . " Stained Glass")); + $this->register(new GlassPane(new BID(Ids::STAINED_GLASS_PANE, $colorIdMap->toId($color)), $color->getDisplayName() . " Stained Glass Pane")); $this->register(new GlazedTerracotta(BlockLegacyIdHelper::getGlazedTerracottaIdentifier($color), $color->getDisplayName() . " Glazed Terracotta")); - $this->register(new HardenedClay(new BID(Ids::STAINED_CLAY, $color->getMagicNumber()), $color->getDisplayName() . " Stained Clay")); - $this->register(new HardenedGlass(new BID(Ids::HARD_STAINED_GLASS, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass")); - $this->register(new HardenedGlassPane(new BID(Ids::HARD_STAINED_GLASS_PANE, $color->getMagicNumber()), "Hardened " . $color->getDisplayName() . " Stained Glass Pane")); - $this->register(new Wool(new BID(Ids::WOOL, $color->getMagicNumber()), $color->getDisplayName() . " Wool")); + $this->register(new HardenedClay(new BID(Ids::STAINED_CLAY, $colorIdMap->toId($color)), $color->getDisplayName() . " Stained Clay")); + $this->register(new HardenedGlass(new BID(Ids::HARD_STAINED_GLASS, $colorIdMap->toId($color)), "Hardened " . $color->getDisplayName() . " Stained Glass")); + $this->register(new HardenedGlassPane(new BID(Ids::HARD_STAINED_GLASS_PANE, $colorIdMap->toId($color)), "Hardened " . $color->getDisplayName() . " Stained Glass Pane")); + $this->register(new Wool(new BID(Ids::WOOL, $colorIdMap->toId($color)), $color->getDisplayName() . " Wool")); } $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_ANDESITE), "Andesite Wall")); diff --git a/src/block/tile/Banner.php b/src/block/tile/Banner.php index e72ee276df..ec9d17ca81 100644 --- a/src/block/tile/Banner.php +++ b/src/block/tile/Banner.php @@ -26,6 +26,7 @@ namespace pocketmine\block\tile; use Ds\Deque; use pocketmine\block\utils\BannerPattern; use pocketmine\block\utils\DyeColor; +use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; @@ -59,38 +60,41 @@ class Banner extends Spawnable{ } public function readSaveData(CompoundTag $nbt) : void{ + $colorIdMap = DyeColorIdMap::getInstance(); if($nbt->hasTag(self::TAG_BASE, IntTag::class)){ - $this->baseColor = DyeColor::fromMagicNumber($nbt->getInt(self::TAG_BASE), true); + $this->baseColor = $colorIdMap->fromInvertedId($nbt->getInt(self::TAG_BASE)); } $patterns = $nbt->getListTag(self::TAG_PATTERNS); if($patterns !== null){ /** @var CompoundTag $pattern */ foreach($patterns as $pattern){ - $this->patterns[] = new BannerPattern($pattern->getString(self::TAG_PATTERN_NAME), DyeColor::fromMagicNumber($pattern->getInt(self::TAG_PATTERN_COLOR), true)); + $this->patterns[] = new BannerPattern($pattern->getString(self::TAG_PATTERN_NAME), $colorIdMap->fromInvertedId($pattern->getInt(self::TAG_PATTERN_COLOR))); } } } protected function writeSaveData(CompoundTag $nbt) : void{ - $nbt->setInt(self::TAG_BASE, $this->baseColor->getInvertedMagicNumber()); + $colorIdMap = DyeColorIdMap::getInstance(); + $nbt->setInt(self::TAG_BASE, $colorIdMap->toInvertedId($this->baseColor)); $patterns = new ListTag(); foreach($this->patterns as $pattern){ $patterns->push(CompoundTag::create() ->setString(self::TAG_PATTERN_NAME, $pattern->getId()) - ->setInt(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) + ->setInt(self::TAG_PATTERN_COLOR, $colorIdMap->toInvertedId($pattern->getColor())) ); } $nbt->setTag(self::TAG_PATTERNS, $patterns); } protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ - $nbt->setInt(self::TAG_BASE, $this->baseColor->getInvertedMagicNumber()); + $colorIdMap = DyeColorIdMap::getInstance(); + $nbt->setInt(self::TAG_BASE, $colorIdMap->toInvertedId($this->baseColor)); $patterns = new ListTag(); foreach($this->patterns as $pattern){ $patterns->push(CompoundTag::create() ->setString(self::TAG_PATTERN_NAME, $pattern->getId()) - ->setInt(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) + ->setInt(self::TAG_PATTERN_COLOR, $colorIdMap->toInvertedId($pattern->getColor())) ); } $nbt->setTag(self::TAG_PATTERNS, $patterns); diff --git a/src/block/tile/Bed.php b/src/block/tile/Bed.php index 28b68ee623..b41489787a 100644 --- a/src/block/tile/Bed.php +++ b/src/block/tile/Bed.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block\tile; use pocketmine\block\utils\DyeColor; +use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\math\Vector3; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; @@ -49,15 +50,15 @@ class Bed extends Spawnable{ public function readSaveData(CompoundTag $nbt) : void{ if($nbt->hasTag(self::TAG_COLOR, ByteTag::class)){ - $this->color = DyeColor::fromMagicNumber($nbt->getByte(self::TAG_COLOR)); + $this->color = DyeColorIdMap::getInstance()->fromId($nbt->getByte(self::TAG_COLOR)); } } protected function writeSaveData(CompoundTag $nbt) : void{ - $nbt->setByte(self::TAG_COLOR, $this->color->getMagicNumber()); + $nbt->setByte(self::TAG_COLOR, DyeColorIdMap::getInstance()->toId($this->color)); } protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ - $nbt->setByte(self::TAG_COLOR, $this->color->getMagicNumber()); + $nbt->setByte(self::TAG_COLOR, DyeColorIdMap::getInstance()->toId($this->color)); } } diff --git a/src/block/utils/DyeColor.php b/src/block/utils/DyeColor.php index 855f8659cd..0c0761d61d 100644 --- a/src/block/utils/DyeColor.php +++ b/src/block/utils/DyeColor.php @@ -50,67 +50,38 @@ use pocketmine\utils\EnumTrait; */ final class DyeColor{ use EnumTrait { - register as Enum_register; __construct as Enum___construct; } - /** @var DyeColor[] */ - private static $numericIdMap = []; - protected static function setup() : void{ self::registerAll( - new DyeColor("white", "White", 0, new Color(0xf0, 0xf0, 0xf0)), - new DyeColor("orange", "Orange", 1, new Color(0xf9, 0x80, 0x1d)), - new DyeColor("magenta", "Magenta", 2, new Color(0xc7, 0x4e, 0xbd)), - new DyeColor("light_blue", "Light Blue", 3, new Color(0x3a, 0xb3, 0xda)), - new DyeColor("yellow", "Yellow", 4, new Color(0xfe, 0xd8, 0x3d)), - new DyeColor("lime", "Lime", 5, new Color(0x80, 0xc7, 0x1f)), - new DyeColor("pink", "Pink", 6, new Color(0xf3, 0x8b, 0xaa)), - new DyeColor("gray", "Gray", 7, new Color(0x47, 0x4f, 0x52)), - new DyeColor("light_gray", "Light Gray", 8, new Color(0x9d, 0x9d, 0x97)), - new DyeColor("cyan", "Cyan", 9, new Color(0x16, 0x9c, 0x9c)), - new DyeColor("purple", "Purple", 10, new Color(0x89, 0x32, 0xb8)), - new DyeColor("blue", "Blue", 11, new Color(0x3c, 0x44, 0xaa)), - new DyeColor("brown", "Brown", 12, new Color(0x83, 0x54, 0x32)), - new DyeColor("green", "Green", 13, new Color(0x5e, 0x7c, 0x16)), - new DyeColor("red", "Red", 14, new Color(0xb0, 0x2e, 0x26)), - new DyeColor("black", "Black", 15, new Color(0x1d, 0x1d, 0x21)) + new DyeColor("white", "White", new Color(0xf0, 0xf0, 0xf0)), + new DyeColor("orange", "Orange", new Color(0xf9, 0x80, 0x1d)), + new DyeColor("magenta", "Magenta", new Color(0xc7, 0x4e, 0xbd)), + new DyeColor("light_blue", "Light Blue", new Color(0x3a, 0xb3, 0xda)), + new DyeColor("yellow", "Yellow", new Color(0xfe, 0xd8, 0x3d)), + new DyeColor("lime", "Lime", new Color(0x80, 0xc7, 0x1f)), + new DyeColor("pink", "Pink", new Color(0xf3, 0x8b, 0xaa)), + new DyeColor("gray", "Gray", new Color(0x47, 0x4f, 0x52)), + new DyeColor("light_gray", "Light Gray", new Color(0x9d, 0x9d, 0x97)), + new DyeColor("cyan", "Cyan", new Color(0x16, 0x9c, 0x9c)), + new DyeColor("purple", "Purple", new Color(0x89, 0x32, 0xb8)), + new DyeColor("blue", "Blue", new Color(0x3c, 0x44, 0xaa)), + new DyeColor("brown", "Brown", new Color(0x83, 0x54, 0x32)), + new DyeColor("green", "Green", new Color(0x5e, 0x7c, 0x16)), + new DyeColor("red", "Red", new Color(0xb0, 0x2e, 0x26)), + new DyeColor("black", "Black", new Color(0x1d, 0x1d, 0x21)) ); } - protected static function register(DyeColor $color) : void{ - self::Enum_register($color); - self::$numericIdMap[$color->getMagicNumber()] = $color; - } - - /** - * Returns a DyeColor object matching the given magic number - * @internal - * - * @param bool $inverted Invert the ID before using it (useful for actual dye magic IDs) - * - * @throws \InvalidArgumentException - */ - public static function fromMagicNumber(int $magicNumber, bool $inverted = false) : DyeColor{ - self::checkInit(); - $real = $inverted ? ~$magicNumber & 0xf : $magicNumber; - if(!isset(self::$numericIdMap[$real])){ - throw new \InvalidArgumentException("Unknown dye colour magic number $magicNumber"); - } - return self::$numericIdMap[$real]; - } - /** @var string */ private $displayName; - /** @var int */ - private $magicNumber; /** @var Color */ private $rgbValue; - private function __construct(string $enumName, string $displayName, int $magicNumber, Color $rgbValue){ + private function __construct(string $enumName, string $displayName, Color $rgbValue){ $this->Enum___construct($enumName); $this->displayName = $displayName; - $this->magicNumber = $magicNumber; $this->rgbValue = $rgbValue; } @@ -121,12 +92,4 @@ final class DyeColor{ public function getRgbValue() : Color{ return $this->rgbValue; } - - public function getMagicNumber() : int{ - return $this->magicNumber; - } - - public function getInvertedMagicNumber() : int{ - return ~$this->magicNumber & 0xf; - } } diff --git a/src/data/bedrock/DyeColorIdMap.php b/src/data/bedrock/DyeColorIdMap.php new file mode 100644 index 0000000000..a96b19f65e --- /dev/null +++ b/src/data/bedrock/DyeColorIdMap.php @@ -0,0 +1,83 @@ + + */ + private $idToEnum = []; + + /** + * @var int[] + * @phpstan-var array + */ + private $enumToId = []; + + private function __construct(){ + $this->register(0, DyeColor::WHITE()); + $this->register(1, DyeColor::ORANGE()); + $this->register(2, DyeColor::MAGENTA()); + $this->register(3, DyeColor::LIGHT_BLUE()); + $this->register(4, DyeColor::YELLOW()); + $this->register(5, DyeColor::LIME()); + $this->register(6, DyeColor::PINK()); + $this->register(7, DyeColor::GRAY()); + $this->register(8, DyeColor::LIGHT_GRAY()); + $this->register(9, DyeColor::CYAN()); + $this->register(10, DyeColor::PURPLE()); + $this->register(11, DyeColor::BLUE()); + $this->register(12, DyeColor::BROWN()); + $this->register(13, DyeColor::GREEN()); + $this->register(14, DyeColor::RED()); + $this->register(15, DyeColor::BLACK()); + } + + private function register(int $id, DyeColor $color) : void{ + $this->idToEnum[$id] = $color; + $this->enumToId[$color->id()] = $id; + } + + public function toId(DyeColor $color) : int{ + return $this->enumToId[$color->id()]; //TODO: is it possible for this to be missing? + } + + public function toInvertedId(DyeColor $color) : int{ + return ~$this->toId($color) & 0xf; + } + + public function fromId(int $id) : DyeColor{ + return $this->idToEnum[$id]; //TODO: this might not be present (e.g. corrupted data) + } + + public function fromInvertedId(int $id) : DyeColor{ + return $this->fromId(~$id & 0xf); + } +} diff --git a/src/item/Banner.php b/src/item/Banner.php index e534a5109c..3a659fa081 100644 --- a/src/item/Banner.php +++ b/src/item/Banner.php @@ -29,6 +29,7 @@ use pocketmine\block\tile\Banner as TileBanner; use pocketmine\block\utils\BannerPattern; use pocketmine\block\utils\DyeColor; use pocketmine\block\VanillaBlocks; +use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; @@ -93,11 +94,12 @@ class Banner extends Item{ $this->patterns = new Deque(); + $colorIdMap = DyeColorIdMap::getInstance(); $patterns = $tag->getListTag(self::TAG_PATTERNS); if($patterns !== null){ /** @var CompoundTag $t */ foreach($patterns as $t){ - $this->patterns->push(new BannerPattern($t->getString(self::TAG_PATTERN_NAME), DyeColor::fromMagicNumber($t->getInt(self::TAG_PATTERN_COLOR), true))); + $this->patterns->push(new BannerPattern($t->getString(self::TAG_PATTERN_NAME), $colorIdMap->fromInvertedId($t->getInt(self::TAG_PATTERN_COLOR)))); } } } @@ -107,11 +109,12 @@ class Banner extends Item{ if(!$this->patterns->isEmpty()){ $patterns = new ListTag(); + $colorIdMap = DyeColorIdMap::getInstance(); /** @var BannerPattern $pattern */ foreach($this->patterns as $pattern){ $patterns->push(CompoundTag::create() ->setString(self::TAG_PATTERN_NAME, $pattern->getId()) - ->setInt(self::TAG_PATTERN_COLOR, $pattern->getColor()->getInvertedMagicNumber()) + ->setInt(self::TAG_PATTERN_COLOR, $colorIdMap->toInvertedId($pattern->getColor())) ); } diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index c7bcee89ba..479fe661ce 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -29,6 +29,7 @@ use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\SkullType; use pocketmine\block\utils\TreeType; use pocketmine\block\VanillaBlocks; +use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\entity\Entity; use pocketmine\entity\Location; use pocketmine\entity\Squid; @@ -243,12 +244,13 @@ class ItemFactory{ DyeColor::BLUE()->id() => 18, DyeColor::WHITE()->id() => 19 ]; + $colorIdMap = DyeColorIdMap::getInstance(); foreach(DyeColor::getAll() as $color){ //TODO: use colour object directly //TODO: add interface to dye-colour objects - $this->register(new Dye(new ItemIdentifier(ItemIds::DYE, $dyeMap[$color->id()] ?? $color->getInvertedMagicNumber()), $color->getDisplayName() . " Dye", $color)); - $this->register(new Bed(new ItemIdentifier(ItemIds::BED, $color->getMagicNumber()), $color->getDisplayName() . " Bed", $color)); - $this->register(new Banner(new ItemIdentifier(ItemIds::BANNER, $color->getInvertedMagicNumber()), $color->getDisplayName() . " Banner", $color)); + $this->register(new Dye(new ItemIdentifier(ItemIds::DYE, $dyeMap[$color->id()] ?? $colorIdMap->toInvertedId($color)), $color->getDisplayName() . " Dye", $color)); + $this->register(new Bed(new ItemIdentifier(ItemIds::BED, $colorIdMap->toId($color)), $color->getDisplayName() . " Bed", $color)); + $this->register(new Banner(new ItemIdentifier(ItemIds::BANNER, $colorIdMap->toInvertedId($color)), $color->getDisplayName() . " Banner", $color)); } foreach(Potion::ALL as $type){ From 0188323d74c72af081e81d79a10eca99318373b0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Jul 2020 20:59:47 +0100 Subject: [PATCH 1758/3224] fixed a bunch of NBT-related phpstan level 8 errors --- src/world/format/io/data/JavaWorldData.php | 5 +- .../io/region/LegacyAnvilChunkTrait.php | 9 +- src/world/format/io/region/McRegion.php | 10 +- tests/phpstan/configs/l8-baseline.neon | 110 ------------------ 4 files changed, 12 insertions(+), 122 deletions(-) diff --git a/src/world/format/io/data/JavaWorldData.php b/src/world/format/io/data/JavaWorldData.php index 279c99c9b5..59e15bacc9 100644 --- a/src/world/format/io/data/JavaWorldData.php +++ b/src/world/format/io/data/JavaWorldData.php @@ -93,10 +93,11 @@ class JavaWorldData extends BaseNbtWorldData{ throw new CorruptedWorldException($e->getMessage(), 0, $e); } - if(!$worldData->hasTag("Data", CompoundTag::class)){ + $dataTag = $worldData->getTag("Data"); + if(!($dataTag instanceof CompoundTag)){ throw new CorruptedWorldException("Missing 'Data' key or wrong type"); } - return $worldData->getCompoundTag("Data"); + return $dataTag; } protected function fix() : void{ diff --git a/src/world/format/io/region/LegacyAnvilChunkTrait.php b/src/world/format/io/region/LegacyAnvilChunkTrait.php index ae5521e7b9..1026286fa0 100644 --- a/src/world/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/world/format/io/region/LegacyAnvilChunkTrait.php @@ -65,12 +65,11 @@ trait LegacyAnvilChunkTrait{ }catch(NbtDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } - if(!$chunk->hasTag("Level")){ + $chunk = $chunk->getTag("Level"); + if(!($chunk instanceof CompoundTag)){ throw new CorruptedChunkException("'Level' key is missing from chunk NBT"); } - $chunk = $chunk->getCompoundTag("Level"); - $subChunks = []; $subChunksTag = $chunk->getListTag("Sections") ?? []; foreach($subChunksTag as $subChunk){ @@ -97,8 +96,8 @@ trait LegacyAnvilChunkTrait{ $chunk->getInt("xPos"), $chunk->getInt("zPos"), $subChunks, - $chunk->hasTag("Entities", ListTag::class) ? self::getCompoundList("Entities", $chunk->getListTag("Entities")) : [], - $chunk->hasTag("TileEntities", ListTag::class) ? self::getCompoundList("TileEntities", $chunk->getListTag("TileEntities")) : [], + ($entitiesTag = $chunk->getTag("Entities")) instanceof ListTag ? self::getCompoundList("Entities", $entitiesTag) : [], + ($tilesTag = $chunk->getTag("TileEntities")) instanceof ListTag ? self::getCompoundList("TileEntities", $tilesTag) : [], $biomeArray ); $result->setPopulated($chunk->getByte("TerrainPopulated", 0) !== 0); diff --git a/src/world/format/io/region/McRegion.php b/src/world/format/io/region/McRegion.php index 73f24e021b..d78eca5a06 100644 --- a/src/world/format/io/region/McRegion.php +++ b/src/world/format/io/region/McRegion.php @@ -27,6 +27,7 @@ use pocketmine\block\BlockLegacyIds; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\ByteArrayTag; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntArrayTag; use pocketmine\nbt\tag\ListTag; use pocketmine\world\format\BiomeArray; @@ -61,12 +62,11 @@ class McRegion extends RegionWorldProvider{ }catch(NbtDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } - if(!$chunk->hasTag("Level")){ + $chunk = $chunk->getTag("Level"); + if(!($chunk instanceof CompoundTag)){ throw new CorruptedChunkException("'Level' key is missing from chunk NBT"); } - $chunk = $chunk->getCompoundTag("Level"); - $subChunks = []; $fullIds = $chunk->hasTag("Blocks", ByteArrayTag::class) ? $chunk->getByteArray("Blocks") : str_repeat("\x00", 32768); $fullData = $chunk->hasTag("Data", ByteArrayTag::class) ? $chunk->getByteArray("Data") : str_repeat("\x00", 16384); @@ -93,8 +93,8 @@ class McRegion extends RegionWorldProvider{ $chunk->getInt("xPos"), $chunk->getInt("zPos"), $subChunks, - $chunk->hasTag("Entities", ListTag::class) ? self::getCompoundList("Entities", $chunk->getListTag("Entities")) : [], - $chunk->hasTag("TileEntities", ListTag::class) ? self::getCompoundList("TileEntities", $chunk->getListTag("TileEntities")) : [], + ($entitiesTag = $chunk->getTag("Entities")) instanceof ListTag ? self::getCompoundList("Entities", $entitiesTag) : [], + ($tilesTag = $chunk->getTag("TileEntities")) instanceof ListTag ? self::getCompoundList("TileEntities", $tilesTag) : [], $biomeIds ); $result->setPopulated($chunk->getByte("TerrainPopulated", 0) !== 0); diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 02ba4b5e18..2189ee5677 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -785,116 +785,6 @@ parameters: count: 1 path: ../../../src/world/format/HeightArray.php - - - message: "#^Method pocketmine\\\\world\\\\format\\\\io\\\\data\\\\JavaWorldData\\:\\:load\\(\\) should return pocketmine\\\\nbt\\\\tag\\\\CompoundTag but returns pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 1 - path: ../../../src/world/format/io/data/JavaWorldData.php - - - - message: "#^Cannot call method getListTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 3 - path: ../../../src/world/format/io/region/Anvil.php - - - - message: "#^Cannot call method hasTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 4 - path: ../../../src/world/format/io/region/Anvil.php - - - - message: "#^Cannot call method getIntArray\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 1 - path: ../../../src/world/format/io/region/Anvil.php - - - - message: "#^Cannot call method getByteArray\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 1 - path: ../../../src/world/format/io/region/Anvil.php - - - - message: "#^Cannot call method getInt\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 2 - path: ../../../src/world/format/io/region/Anvil.php - - - - message: "#^Parameter \\#2 \\$list of static method pocketmine\\\\world\\\\format\\\\io\\\\region\\\\RegionWorldProvider\\:\\:getCompoundList\\(\\) expects pocketmine\\\\nbt\\\\tag\\\\ListTag, pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null given\\.$#" - count: 2 - path: ../../../src/world/format/io/region/Anvil.php - - - - message: "#^Cannot call method getByte\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 1 - path: ../../../src/world/format/io/region/Anvil.php - - - - message: "#^Cannot call method getListTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 3 - path: ../../../src/world/format/io/region/PMAnvil.php - - - - message: "#^Cannot call method hasTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 4 - path: ../../../src/world/format/io/region/PMAnvil.php - - - - message: "#^Cannot call method getIntArray\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 1 - path: ../../../src/world/format/io/region/PMAnvil.php - - - - message: "#^Cannot call method getByteArray\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 1 - path: ../../../src/world/format/io/region/PMAnvil.php - - - - message: "#^Cannot call method getInt\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 2 - path: ../../../src/world/format/io/region/PMAnvil.php - - - - message: "#^Parameter \\#2 \\$list of static method pocketmine\\\\world\\\\format\\\\io\\\\region\\\\RegionWorldProvider\\:\\:getCompoundList\\(\\) expects pocketmine\\\\nbt\\\\tag\\\\ListTag, pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null given\\.$#" - count: 2 - path: ../../../src/world/format/io/region/PMAnvil.php - - - - message: "#^Cannot call method getByte\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 1 - path: ../../../src/world/format/io/region/PMAnvil.php - - - - message: "#^Cannot call method getByteArray\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 3 - path: ../../../src/world/format/io/region/McRegion.php - - - - message: "#^Cannot call method hasTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 6 - path: ../../../src/world/format/io/region/McRegion.php - - - - message: "#^Cannot call method getIntArray\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 1 - path: ../../../src/world/format/io/region/McRegion.php - - - - message: "#^Cannot call method getInt\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 2 - path: ../../../src/world/format/io/region/McRegion.php - - - - message: "#^Cannot call method getListTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 2 - path: ../../../src/world/format/io/region/McRegion.php - - - - message: "#^Parameter \\#2 \\$list of static method pocketmine\\\\world\\\\format\\\\io\\\\region\\\\RegionWorldProvider\\:\\:getCompoundList\\(\\) expects pocketmine\\\\nbt\\\\tag\\\\ListTag, pocketmine\\\\nbt\\\\tag\\\\ListTag\\|null given\\.$#" - count: 2 - path: ../../../src/world/format/io/region/McRegion.php - - - - message: "#^Cannot call method getByte\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 1 - path: ../../../src/world/format/io/region/McRegion.php - - message: "#^Cannot call method readChunk\\(\\) on pocketmine\\\\world\\\\format\\\\io\\\\region\\\\RegionLoader\\|null\\.$#" count: 1 From ad99dc5884f197966cf16d918226d3cf444d99d0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Jul 2020 22:00:42 +0100 Subject: [PATCH 1759/3224] ChunkSerializer micro optimisation: reduce indirections when writing runtime IDs --- src/network/mcpe/serializer/ChunkSerializer.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index cbe0d075fa..4b730757e8 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\serializer; use pocketmine\block\tile\Spawnable; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; +use pocketmine\utils\Binary; use pocketmine\utils\BinaryStream; use pocketmine\world\format\Chunk; use function count; @@ -70,7 +71,7 @@ final class ChunkSerializer{ //zigzag and just shift directly. $stream->putUnsignedVarInt(count($palette) << 1); //yes, this is intentionally zigzag foreach($palette as $p){ - $stream->putUnsignedVarInt($blockMapper->toRuntimeId($p >> 4, $p & 0xf) << 1); + $stream->put(Binary::writeUnsignedVarInt($blockMapper->toRuntimeId($p >> 4, $p & 0xf) << 1)); } } } From 909f3f39de0faf9d34c5932f6d3da47987a8a01d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 6 Jul 2020 11:18:29 +0100 Subject: [PATCH 1760/3224] Block: get rid of getRuntimeId() the runtime ID mapping should be non-global in case of multiple protocols. --- src/block/Block.php | 8 -------- src/entity/object/FallingBlock.php | 3 ++- src/world/World.php | 3 ++- src/world/particle/BlockPunchParticle.php | 3 ++- src/world/particle/DestroyBlockParticle.php | 3 ++- src/world/particle/TerrainParticle.php | 3 ++- src/world/sound/BlockBreakSound.php | 3 ++- src/world/sound/BlockPlaceSound.php | 3 ++- src/world/sound/BlockPunchSound.php | 3 ++- src/world/sound/EntityLandSound.php | 3 ++- 10 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/block/Block.php b/src/block/Block.php index 873be4e9e5..097b85fb44 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -38,7 +38,6 @@ use pocketmine\math\Facing; use pocketmine\math\RayTraceResult; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use pocketmine\world\Position; @@ -105,13 +104,6 @@ class Block{ return ItemFactory::getInstance()->get($this->idInfo->getItemId(), $this->idInfo->getVariant()); } - /** - * @internal - */ - public function getRuntimeId() : int{ - return RuntimeBlockMapping::getInstance()->toRuntimeId($this->getId(), $this->getMeta()); - } - public function getMeta() : int{ $stateMeta = $this->writeStateToMeta(); assert(($stateMeta & ~$this->getStateBitmask()) === 0); diff --git a/src/entity/object/FallingBlock.php b/src/entity/object/FallingBlock.php index 4b955fc7ac..69e43b800b 100644 --- a/src/entity/object/FallingBlock.php +++ b/src/entity/object/FallingBlock.php @@ -34,6 +34,7 @@ use pocketmine\math\Vector3; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; +use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; @@ -146,7 +147,7 @@ class FallingBlock extends Entity{ protected function syncNetworkData(EntityMetadataCollection $properties) : void{ parent::syncNetworkData($properties); - $properties->setInt(EntityMetadataProperties::VARIANT, $this->block->getRuntimeId()); + $properties->setInt(EntityMetadataProperties::VARIANT, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getId(), $this->block->getMeta())); } public function getOffsetPosition(Vector3 $vector3) : Vector3{ diff --git a/src/world/World.php b/src/world/World.php index bd1c6530bc..66892f0952 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -52,6 +52,7 @@ use pocketmine\item\ItemUseResult; use pocketmine\item\LegacyStringToItemParser; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; +use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\BlockActorDataPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; @@ -829,7 +830,7 @@ class World implements ChunkManager{ } $fullBlock = $this->getBlockAt($b->x, $b->y, $b->z); - $packets[] = UpdateBlockPacket::create($b->x, $b->y, $b->z, $fullBlock->getRuntimeId()); + $packets[] = UpdateBlockPacket::create($b->x, $b->y, $b->z, RuntimeBlockMapping::getInstance()->toRuntimeId($fullBlock->getId(), $fullBlock->getMeta())); $tile = $this->getTileAt($b->x, $b->y, $b->z); if($tile instanceof Spawnable){ diff --git a/src/world/particle/BlockPunchParticle.php b/src/world/particle/BlockPunchParticle.php index 11d23bcf68..a932099a61 100644 --- a/src/world/particle/BlockPunchParticle.php +++ b/src/world/particle/BlockPunchParticle.php @@ -25,6 +25,7 @@ namespace pocketmine\world\particle; use pocketmine\block\Block; use pocketmine\math\Vector3; +use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\LevelEventPacket; /** @@ -43,6 +44,6 @@ class BlockPunchParticle implements Particle{ } public function encode(Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_PUNCH_BLOCK, $this->block->getRuntimeId() | ($this->face << 24), $pos); + return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_PUNCH_BLOCK, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getId(), $this->block->getMeta()) | ($this->face << 24), $pos); } } diff --git a/src/world/particle/DestroyBlockParticle.php b/src/world/particle/DestroyBlockParticle.php index 3039fbe408..0d4d962747 100644 --- a/src/world/particle/DestroyBlockParticle.php +++ b/src/world/particle/DestroyBlockParticle.php @@ -25,6 +25,7 @@ namespace pocketmine\world\particle; use pocketmine\block\Block; use pocketmine\math\Vector3; +use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\LevelEventPacket; class DestroyBlockParticle implements Particle{ @@ -37,6 +38,6 @@ class DestroyBlockParticle implements Particle{ } public function encode(Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_DESTROY, $this->block->getRuntimeId(), $pos); + return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_DESTROY, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getId(), $this->block->getMeta()), $pos); } } diff --git a/src/world/particle/TerrainParticle.php b/src/world/particle/TerrainParticle.php index 997c2e76b2..e96ad680b4 100644 --- a/src/world/particle/TerrainParticle.php +++ b/src/world/particle/TerrainParticle.php @@ -25,6 +25,7 @@ namespace pocketmine\world\particle; use pocketmine\block\Block; use pocketmine\math\Vector3; +use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\types\ParticleIds; @@ -37,6 +38,6 @@ class TerrainParticle implements Particle{ } public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::TERRAIN, $this->block->getRuntimeId(), $pos); + return LevelEventPacket::standardParticle(ParticleIds::TERRAIN, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getId(), $this->block->getMeta()), $pos); } } diff --git a/src/world/sound/BlockBreakSound.php b/src/world/sound/BlockBreakSound.php index 8beed8cd7f..4d5e6a76e3 100644 --- a/src/world/sound/BlockBreakSound.php +++ b/src/world/sound/BlockBreakSound.php @@ -25,6 +25,7 @@ namespace pocketmine\world\sound; use pocketmine\block\Block; use pocketmine\math\Vector3; +use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BlockBreakSound implements Sound{ @@ -37,6 +38,6 @@ class BlockBreakSound implements Sound{ } public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BREAK, $pos, $this->block->getRuntimeId()); + return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BREAK, $pos, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getId(), $this->block->getMeta())); } } diff --git a/src/world/sound/BlockPlaceSound.php b/src/world/sound/BlockPlaceSound.php index ae8e2e277b..d6d9eef299 100644 --- a/src/world/sound/BlockPlaceSound.php +++ b/src/world/sound/BlockPlaceSound.php @@ -25,6 +25,7 @@ namespace pocketmine\world\sound; use pocketmine\block\Block; use pocketmine\math\Vector3; +use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BlockPlaceSound implements Sound{ @@ -37,6 +38,6 @@ class BlockPlaceSound implements Sound{ } public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_PLACE, $pos, $this->block->getRuntimeId()); + return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_PLACE, $pos, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getId(), $this->block->getMeta())); } } diff --git a/src/world/sound/BlockPunchSound.php b/src/world/sound/BlockPunchSound.php index 75b23e02cf..ef9930285e 100644 --- a/src/world/sound/BlockPunchSound.php +++ b/src/world/sound/BlockPunchSound.php @@ -25,6 +25,7 @@ namespace pocketmine\world\sound; use pocketmine\block\Block; use pocketmine\math\Vector3; +use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; /** @@ -43,7 +44,7 @@ class BlockPunchSound implements Sound{ return LevelSoundEventPacket::create( LevelSoundEventPacket::SOUND_HIT, $pos, - $this->block->getRuntimeId() + RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getId(), $this->block->getMeta()) ); } } diff --git a/src/world/sound/EntityLandSound.php b/src/world/sound/EntityLandSound.php index 113c89d9bc..53b2d033b7 100644 --- a/src/world/sound/EntityLandSound.php +++ b/src/world/sound/EntityLandSound.php @@ -26,6 +26,7 @@ namespace pocketmine\world\sound; use pocketmine\block\Block; use pocketmine\entity\Entity; use pocketmine\math\Vector3; +use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; /** @@ -47,7 +48,7 @@ class EntityLandSound implements Sound{ return LevelSoundEventPacket::create( LevelSoundEventPacket::SOUND_LAND, $pos, - $this->blockLandedOn->getRuntimeId(), + RuntimeBlockMapping::getInstance()->toRuntimeId($this->blockLandedOn->getId(), $this->blockLandedOn->getMeta()), $this->entity::getNetworkTypeId() //TODO: does isBaby have any relevance here? ); From 7106ff575cafe72514bb1c480a7a843666d8908c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Jul 2020 19:42:47 +0100 Subject: [PATCH 1761/3224] End abuse of PluginCommand by making it final PluginCommand should be better-named CommandExecutorCommand or perhaps CallbackCommand. It's not supposed to be extended by plugins. --- src/command/PluginCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command/PluginCommand.php b/src/command/PluginCommand.php index d4c0abf64c..2453f4025a 100644 --- a/src/command/PluginCommand.php +++ b/src/command/PluginCommand.php @@ -28,7 +28,7 @@ use pocketmine\plugin\Plugin; use pocketmine\plugin\PluginOwned; use pocketmine\plugin\PluginOwnedTrait; -class PluginCommand extends Command implements PluginOwned{ +final class PluginCommand extends Command implements PluginOwned{ use PluginOwnedTrait; /** @var CommandExecutor */ From b79aa045303f3646ce5c4d697c0a60305f20d36a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Jul 2020 21:21:13 +0100 Subject: [PATCH 1762/3224] remove unused FileWriteTask --- src/scheduler/FileWriteTask.php | 49 --------------------------------- 1 file changed, 49 deletions(-) delete mode 100644 src/scheduler/FileWriteTask.php diff --git a/src/scheduler/FileWriteTask.php b/src/scheduler/FileWriteTask.php deleted file mode 100644 index 788a8f7d56..0000000000 --- a/src/scheduler/FileWriteTask.php +++ /dev/null @@ -1,49 +0,0 @@ -path = $path; - $this->contents = $contents; - $this->flags = $flags; - } - - public function onRun() : void{ - file_put_contents($this->path, $this->contents, $this->flags); - } -} From a71b111b503538e01fe6c774c6cb0a8e9259bd74 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 8 Jul 2020 11:49:43 +0100 Subject: [PATCH 1763/3224] TaskScheduler: get rid of cancelTask() developers should be using TaskHandler->cancel() instead. --- src/scheduler/TaskScheduler.php | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/scheduler/TaskScheduler.php b/src/scheduler/TaskScheduler.php index 41fd9d1e4f..dea28832db 100644 --- a/src/scheduler/TaskScheduler.php +++ b/src/scheduler/TaskScheduler.php @@ -72,19 +72,9 @@ class TaskScheduler{ return $this->addTask($task, $delay, $period); } - public function cancelTask(int $taskId) : void{ - if(isset($this->tasks[$taskId])){ - try{ - $this->tasks[$taskId]->cancel(); - }finally{ - unset($this->tasks[$taskId]); - } - } - } - public function cancelAllTasks() : void{ foreach($this->tasks as $id => $task){ - $this->cancelTask($id); + $task->cancel(); } $this->tasks = []; while(!$this->queue->isEmpty()){ From dca4bf424e7e40822f82b49d562ac184fa38bb76 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 8 Jul 2020 11:53:47 +0100 Subject: [PATCH 1764/3224] TaskHandler: change isQueued() to accept TaskHandler instead of int --- src/scheduler/TaskScheduler.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/scheduler/TaskScheduler.php b/src/scheduler/TaskScheduler.php index dea28832db..1275d3a11e 100644 --- a/src/scheduler/TaskScheduler.php +++ b/src/scheduler/TaskScheduler.php @@ -83,8 +83,8 @@ class TaskScheduler{ $this->ids = 1; } - public function isQueued(int $taskId) : bool{ - return isset($this->tasks[$taskId]); + public function isQueued(TaskHandler $task) : bool{ + return isset($this->tasks[$task->getTaskId()]); } /** From d738504e24af6b6d81e7a2740eae0426a4aa8228 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 8 Jul 2020 11:57:48 +0100 Subject: [PATCH 1765/3224] TaskScheduler: use a Ds\Set to index tasks internally this removes all remaining use-cases for taskID. --- src/scheduler/TaskScheduler.php | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/scheduler/TaskScheduler.php b/src/scheduler/TaskScheduler.php index 1275d3a11e..63a37e1466 100644 --- a/src/scheduler/TaskScheduler.php +++ b/src/scheduler/TaskScheduler.php @@ -27,6 +27,7 @@ declare(strict_types=1); namespace pocketmine\scheduler; +use Ds\Set; use pocketmine\utils\ReversePriorityQueue; class TaskScheduler{ @@ -42,8 +43,11 @@ class TaskScheduler{ */ protected $queue; - /** @var TaskHandler[] */ - protected $tasks = []; + /** + * @var Set|TaskHandler[] + * @phpstan-var Set + */ + protected $tasks; /** @var int */ private $ids = 1; @@ -54,6 +58,7 @@ class TaskScheduler{ public function __construct(?string $owner = null){ $this->owner = $owner; $this->queue = new ReversePriorityQueue(); + $this->tasks = new Set(); } public function scheduleTask(Task $task) : TaskHandler{ @@ -76,7 +81,7 @@ class TaskScheduler{ foreach($this->tasks as $id => $task){ $task->cancel(); } - $this->tasks = []; + $this->tasks->clear(); while(!$this->queue->isEmpty()){ $this->queue->extract(); } @@ -84,7 +89,7 @@ class TaskScheduler{ } public function isQueued(TaskHandler $task) : bool{ - return isset($this->tasks[$task->getTaskId()]); + return $this->tasks->contains($task); } /** @@ -116,7 +121,7 @@ class TaskScheduler{ } $handler->setNextRun($nextRun); - $this->tasks[$handler->getTaskId()] = $handler; + $this->tasks->add($handler); $this->queue->insert($handler, $nextRun); return $handler; @@ -137,7 +142,7 @@ class TaskScheduler{ /** @var TaskHandler $task */ $task = $this->queue->extract(); if($task->isCancelled()){ - unset($this->tasks[$task->getTaskId()]); + $this->tasks->remove($task); continue; } $task->run(); @@ -146,7 +151,7 @@ class TaskScheduler{ $this->queue->insert($task, $this->currentTick + $task->getPeriod()); }else{ $task->remove(); - unset($this->tasks[$task->getTaskId()]); + $this->tasks->remove($task); } } } From 6bca38999d0528d6adb1f6d28d9b4477c379af2c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 8 Jul 2020 12:01:48 +0100 Subject: [PATCH 1766/3224] scheduler: removing task IDs These no longer serve any purpose that can't be replaced with a structure like Ds\Set, SplObjectStorage, or just using spl_object_id(). --- src/scheduler/Task.php | 8 -------- src/scheduler/TaskHandler.php | 10 +--------- src/scheduler/TaskScheduler.php | 10 +--------- 3 files changed, 2 insertions(+), 26 deletions(-) diff --git a/src/scheduler/Task.php b/src/scheduler/Task.php index 85c0da6c72..af50cd5f4d 100644 --- a/src/scheduler/Task.php +++ b/src/scheduler/Task.php @@ -37,14 +37,6 @@ abstract class Task{ return $this->taskHandler; } - final public function getTaskId() : int{ - if($this->taskHandler !== null){ - return $this->taskHandler->getTaskId(); - } - - return -1; - } - public function getName() : string{ return Utils::getNiceClassName($this); } diff --git a/src/scheduler/TaskHandler.php b/src/scheduler/TaskHandler.php index 7d3b6b1089..73fa159400 100644 --- a/src/scheduler/TaskHandler.php +++ b/src/scheduler/TaskHandler.php @@ -31,9 +31,6 @@ class TaskHandler{ /** @var Task */ protected $task; - /** @var int */ - protected $taskId; - /** @var int */ protected $delay; @@ -54,12 +51,11 @@ class TaskHandler{ /** @var string */ private $ownerName; - public function __construct(Task $task, int $taskId, int $delay = -1, int $period = -1, ?string $ownerName = null){ + public function __construct(Task $task, int $delay = -1, int $period = -1, ?string $ownerName = null){ if($task->getHandler() !== null){ throw new \InvalidArgumentException("Cannot assign multiple handlers to the same task"); } $this->task = $task; - $this->taskId = $taskId; $this->delay = $delay; $this->period = $period; $this->taskName = $task->getName(); @@ -80,10 +76,6 @@ class TaskHandler{ $this->nextRun = $ticks; } - public function getTaskId() : int{ - return $this->taskId; - } - public function getTask() : Task{ return $this->task; } diff --git a/src/scheduler/TaskScheduler.php b/src/scheduler/TaskScheduler.php index 63a37e1466..32d2d27848 100644 --- a/src/scheduler/TaskScheduler.php +++ b/src/scheduler/TaskScheduler.php @@ -49,9 +49,6 @@ class TaskScheduler{ */ protected $tasks; - /** @var int */ - private $ids = 1; - /** @var int */ protected $currentTick = 0; @@ -85,7 +82,6 @@ class TaskScheduler{ while(!$this->queue->isEmpty()){ $this->queue->extract(); } - $this->ids = 1; } public function isQueued(TaskHandler $task) : bool{ @@ -110,7 +106,7 @@ class TaskScheduler{ $period = 1; } - return $this->handle(new TaskHandler($task, $this->nextId(), $delay, $period, $this->owner)); + return $this->handle(new TaskHandler($task, $delay, $period, $this->owner)); } private function handle(TaskHandler $handler) : TaskHandler{ @@ -159,8 +155,4 @@ class TaskScheduler{ private function isReady(int $currentTick) : bool{ return !$this->queue->isEmpty() and $this->queue->current()->getNextRun() <= $currentTick; } - - private function nextId() : int{ - return $this->ids++; - } } From 92f69676651e282944222574eca5b51a997b91ae Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 8 Jul 2020 13:50:38 +0100 Subject: [PATCH 1767/3224] Command: validate permissions, require permission registration in advance of commands using them this fixes #3200. This causes permissions to be registered before plugin load, which changes some behaviour, but after discussions on #internals-dev we couldn't see any reason to keep the behaviour the way it was, and several reasons to change it to be something like this. --- src/Server.php | 3 ++- src/command/Command.php | 7 +++++++ src/plugin/PluginManager.php | 13 +++++-------- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/Server.php b/src/Server.php index bc0caeff18..3fad9f6f78 100644 --- a/src/Server.php +++ b/src/Server.php @@ -931,6 +931,8 @@ class Server{ TimingsHandler::setEnabled((bool) $this->configGroup->getProperty("settings.enable-profiling", false)); $this->profilingTickRate = (float) $this->configGroup->getProperty("settings.profile-report-trigger", 20); + DefaultPermissions::registerCorePermissions(); + $this->commandMap = new SimpleCommandMap($this); Enchantment::init(); @@ -1268,7 +1270,6 @@ class Server{ if($type->equals(PluginLoadOrder::POSTWORLD())){ $this->commandMap->registerServerAliases(); - DefaultPermissions::registerCorePermissions(); } } diff --git a/src/command/Command.php b/src/command/Command.php index 86c43e4bbd..4ab99e0a54 100644 --- a/src/command/Command.php +++ b/src/command/Command.php @@ -99,6 +99,13 @@ abstract class Command{ } public function setPermission(?string $permission) : void{ + if($permission !== null){ + foreach(explode(";", $permission) as $perm){ + if(PermissionManager::getInstance()->getPermission($perm) === null){ + throw new \InvalidArgumentException("Cannot use non-existing permission \"$perm\""); + } + } + } $this->permission = $permission; } diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 90185862d2..15002bbdd3 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -161,6 +161,11 @@ class PluginManager{ return null; } + $permManager = PermissionManager::getInstance(); + foreach($description->getPermissions() as $perm){ + $permManager->addPermission($perm); + } + /** * @var Plugin $plugin * @see Plugin::__construct() @@ -364,10 +369,6 @@ class PluginManager{ if(!$plugin->isEnabled()){ $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.plugin.enable", [$plugin->getDescription()->getFullName()])); - $permManager = PermissionManager::getInstance(); - foreach($plugin->getDescription()->getPermissions() as $perm){ - $permManager->addPermission($perm); - } $plugin->getScheduler()->setEnabled(true); $plugin->onEnableStateChange(true); @@ -393,10 +394,6 @@ class PluginManager{ $plugin->onEnableStateChange(false); $plugin->getScheduler()->shutdown(); HandlerListManager::global()->unregisterAll($plugin); - $permManager = PermissionManager::getInstance(); - foreach($plugin->getDescription()->getPermissions() as $perm){ - $permManager->removePermission($perm); - } } } From 31fd427710b1a325f6f3b27097a3c20a6a02ad3e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 8 Jul 2020 20:29:30 +0100 Subject: [PATCH 1768/3224] Entity: remove usages of Chunk->getX()/getZ() --- src/entity/Entity.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index cd5f42a07b..0f01a031c3 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -97,6 +97,10 @@ abstract class Entity{ /** @var Chunk|null */ public $chunk; + /** @var int */ + private $chunkX; + /** @var int */ + private $chunkZ; /** @var EntityDamageEvent|null */ protected $lastDamageCause = null; @@ -239,6 +243,8 @@ abstract class Entity{ if($this->chunk === null){ throw new \InvalidStateException("Cannot create entities in unloaded chunks"); } + $this->chunkX = $this->location->getFloorX() >> 4; + $this->chunkZ = $this->location->getFloorZ() >> 4; if($nbt !== null){ $this->motion = EntityDataHelper::parseVec3($nbt, "Motion", true); @@ -1335,11 +1341,13 @@ abstract class Entity{ protected function checkChunks() : void{ $chunkX = $this->location->getFloorX() >> 4; $chunkZ = $this->location->getFloorZ() >> 4; - if($this->chunk === null or ($this->chunk->getX() !== $chunkX or $this->chunk->getZ() !== $chunkZ)){ + if($this->chunk === null or $chunkX !== $this->chunkX or $chunkZ !== $this->chunkZ){ if($this->chunk !== null){ $this->chunk->removeEntity($this); } $this->chunk = $this->getWorld()->getChunk($chunkX, $chunkZ, true); + $this->chunkX = $chunkX; + $this->chunkZ = $chunkZ; if(!$this->justCreated){ $newChunk = $this->getWorld()->getViewersForPosition($this->location); From a5d77d510664cc34b5489cfa29fb65e98f8f296e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 8 Jul 2020 23:24:54 +0100 Subject: [PATCH 1769/3224] LevelDB: remove unused function --- src/world/format/io/leveldb/LevelDB.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 769c7faafa..3842279e82 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -489,10 +489,6 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ return Binary::writeLInt($chunkX) . Binary::writeLInt($chunkZ); } - private function chunkExists(int $chunkX, int $chunkZ) : bool{ - return $this->db->get(LevelDB::chunkIndex($chunkX, $chunkZ) . self::TAG_VERSION) !== false; - } - public function doGarbageCollection() : void{ } From 36727aabf757ab7c5426504c607c8a9c1e0203a3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 Jul 2020 11:42:12 +0100 Subject: [PATCH 1770/3224] Extracted a ChunkSelector unit from Player if anyone asks me why not use a static method, it's because I want to make this more dynamic going forward, and statics are anything but. --- src/player/ChunkSelector.php | 68 ++++++++++++++++++++++++++++++++++++ src/player/Player.php | 42 +++------------------- 2 files changed, 72 insertions(+), 38 deletions(-) create mode 100644 src/player/ChunkSelector.php diff --git a/src/player/ChunkSelector.php b/src/player/ChunkSelector.php new file mode 100644 index 0000000000..31bbf08e45 --- /dev/null +++ b/src/player/ChunkSelector.php @@ -0,0 +1,68 @@ + + */ + public function selectChunks(int $radius, int $centerX, int $centerZ) : \Generator{ + $radiusSquared = $radius ** 2; + + for($x = 0; $x < $radius; ++$x){ + for($z = 0; $z <= $x; ++$z){ + if(($x ** 2 + $z ** 2) > $radiusSquared){ + break; //skip to next band + } + + //If the chunk is in the radius, others at the same offsets in different quadrants are also guaranteed to be. + + /* Top right quadrant */ + yield World::chunkHash($centerX + $x, $centerZ + $z); + /* Top left quadrant */ + yield World::chunkHash($centerX - $x - 1, $centerZ + $z); + /* Bottom right quadrant */ + yield World::chunkHash($centerX + $x, $centerZ - $z - 1); + /* Bottom left quadrant */ + yield World::chunkHash($centerX - $x - 1, $centerZ - $z - 1); + + if($x !== $z){ + /* Top right quadrant mirror */ + yield World::chunkHash($centerX + $z, $centerZ + $x); + /* Top left quadrant mirror */ + yield World::chunkHash($centerX - $z - 1, $centerZ + $x); + /* Bottom right quadrant mirror */ + yield World::chunkHash($centerX + $z, $centerZ - $x - 1); + /* Bottom left quadrant mirror */ + yield World::chunkHash($centerX - $z - 1, $centerZ - $x - 1); + } + } + } + } +} diff --git a/src/player/Player.php b/src/player/Player.php index b586425fc0..db486f9d9b 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -211,6 +211,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, protected $spawnChunkLoadCount = 0; /** @var int */ protected $chunksPerTick; + /** @var ChunkSelector */ + protected $chunkSelector; /** @var bool[] map: raw UUID (string) => bool */ protected $hiddenPlayers = []; @@ -280,6 +282,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->perm = new PermissibleBase($this); $this->chunksPerTick = (int) $this->server->getConfigGroup()->getProperty("chunk-sending.per-tick", 4); $this->spawnThreshold = (int) (($this->server->getConfigGroup()->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); + $this->chunkSelector = new ChunkSelector(); $namedtag = $this->server->getOfflinePlayerData($this->username); //TODO: make this async @@ -838,43 +841,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } } - /** - * @return \Generator - */ - protected function selectChunks(int $radius, int $centerX, int $centerZ) : \Generator{ - $radiusSquared = $radius ** 2; - - for($x = 0; $x < $radius; ++$x){ - for($z = 0; $z <= $x; ++$z){ - if(($x ** 2 + $z ** 2) > $radiusSquared){ - break; //skip to next band - } - - //If the chunk is in the radius, others at the same offsets in different quadrants are also guaranteed to be. - - /* Top right quadrant */ - yield World::chunkHash($centerX + $x, $centerZ + $z); - /* Top left quadrant */ - yield World::chunkHash($centerX - $x - 1, $centerZ + $z); - /* Bottom right quadrant */ - yield World::chunkHash($centerX + $x, $centerZ - $z - 1); - /* Bottom left quadrant */ - yield World::chunkHash($centerX - $x - 1, $centerZ - $z - 1); - - if($x !== $z){ - /* Top right quadrant mirror */ - yield World::chunkHash($centerX + $z, $centerZ + $x); - /* Top left quadrant mirror */ - yield World::chunkHash($centerX - $z - 1, $centerZ + $x); - /* Bottom right quadrant mirror */ - yield World::chunkHash($centerX + $z, $centerZ - $x - 1); - /* Bottom left quadrant mirror */ - yield World::chunkHash($centerX - $z - 1, $centerZ - $x - 1); - } - } - } - } - protected function orderChunks() : void{ if(!$this->isConnected() or $this->viewDistance === -1){ return; @@ -885,7 +851,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $newOrder = []; $unloadChunks = $this->usedChunks; - foreach($this->selectChunks( + foreach($this->chunkSelector->selectChunks( $this->server->getAllowedViewDistance($this->viewDistance), $this->location->getFloorX() >> 4, $this->location->getFloorZ() >> 4 From 874fec0a35b91c94cd3759aca722db4fb3d832b9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 Jul 2020 12:35:45 +0100 Subject: [PATCH 1771/3224] Switch back to PM3 spawn-chunk handling, fix pre-spawn death bug caused by 939dfd9269df0feaff5b96d0dd628055b9706b95, close #3513 (properly this time) --- src/player/Player.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index db486f9d9b..3852ce2258 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -790,10 +790,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->networkSession->startUsingChunk($X, $Z, function(int $chunkX, int $chunkZ) use ($index) : void{ $this->usedChunks[$index] = UsedChunkStatus::SENT(); - if($this->spawned){ + if($this->spawnChunkLoadCount === -1){ $this->spawnEntitiesOnChunk($chunkX, $chunkZ); }elseif($this->spawnChunkLoadCount++ === $this->spawnThreshold){ - $this->spawned = true; + $this->spawnChunkLoadCount = -1; foreach($this->usedChunks as $chunkHash => $status){ if($status->equals(UsedChunkStatus::SENT())){ @@ -811,6 +811,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } public function doFirstSpawn() : void{ + if($this->spawned){ + return; + } + $this->spawned = true; if($this->hasPermission(Server::BROADCAST_CHANNEL_USERS)){ PermissionManager::getInstance()->subscribeToPermission(Server::BROADCAST_CHANNEL_USERS, $this); } From f2cf453cd06b3389f3d628672e741ec8c06657b1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 Jul 2020 12:53:16 +0100 Subject: [PATCH 1772/3224] World: remove one more unnecessary vector3 field mutation --- src/world/World.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 66892f0952..aa4d4159d5 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2235,6 +2235,7 @@ class World implements ChunkManager{ $v = $spawn->floor(); $chunk = $this->getChunkAtPosition($v, false); $x = (int) $v->x; + $y = $v->y; $z = (int) $v->z; if($chunk !== null and $chunk->isGenerated()){ $y = (int) min($max - 2, $v->y); @@ -2259,11 +2260,9 @@ class World implements ChunkManager{ ++$y; } } - - $v->y = $y; } - return new Position($spawn->x, $v->y, $spawn->z, $this); + return new Position($spawn->x, $y, $spawn->z, $this); } /** From b22cc4875e590470dac267b48754caee68d06f06 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 Jul 2020 13:09:46 +0100 Subject: [PATCH 1773/3224] Player: Accept NBT data in constructor, instead of asking for it from the server directly this allows custom implementations to provide custom data to the constructor (or none at all). --- src/network/mcpe/NetworkSession.php | 6 +++++- src/player/Player.php | 4 +--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 9ce7ca0572..56768ef2a8 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -224,11 +224,15 @@ class NetworkSession{ $ev->call(); $class = $ev->getPlayerClass(); + //TODO: make this async + //TODO: this really has no business being in NetworkSession at all - what about allowing it to be provided by PlayerCreationEvent? + $namedtag = $this->server->getOfflinePlayerData($this->info->getUsername()); + /** * @var Player $player * @see Player::__construct() */ - $this->player = new $class($this->server, $this, $this->info, $this->authenticated); + $this->player = new $class($this->server, $this, $this->info, $this->authenticated, $namedtag); $this->invManager = new InventoryManager($this->player, $this); diff --git a/src/player/Player.php b/src/player/Player.php index 0f3b6e859a..caf9057494 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -263,7 +263,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, /** @var SurvivalBlockBreakHandler|null */ protected $blockBreakHandler = null; - public function __construct(Server $server, NetworkSession $session, PlayerInfo $playerInfo, bool $authenticated){ + public function __construct(Server $server, NetworkSession $session, PlayerInfo $playerInfo, bool $authenticated, ?CompoundTag $namedtag){ $username = TextFormat::clean($playerInfo->getUsername()); $this->logger = new \PrefixedLogger($server->getLogger(), "Player: $username"); @@ -284,8 +284,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->spawnThreshold = (int) (($this->server->getConfigGroup()->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); $this->chunkSelector = new ChunkSelector(); - $namedtag = $this->server->getOfflinePlayerData($this->username); //TODO: make this async - if($namedtag !== null and ($world = $this->server->getWorldManager()->getWorldByName($namedtag->getString("Level", ""))) !== null){ $spawn = EntityDataHelper::parseLocation($namedtag, $world); $onGround = $namedtag->getByte("OnGround", 1) === 1; From 600ef033abeb819132560cc10e013053e53cf503 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 Jul 2020 13:24:31 +0100 Subject: [PATCH 1774/3224] PlayerSkinPacket: added ::create() --- src/entity/Human.php | 7 +++---- src/network/mcpe/protocol/PlayerSkinPacket.php | 7 +++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/entity/Human.php b/src/entity/Human.php index 9233b25d3c..ddf0994a55 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -138,10 +138,9 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ * @param Player[]|null $targets */ public function sendSkin(?array $targets = null) : void{ - $pk = new PlayerSkinPacket(); - $pk->uuid = $this->getUniqueId(); - $pk->skin = SkinAdapterSingleton::get()->toSkinData($this->skin); - $this->server->broadcastPackets($targets ?? $this->hasSpawned, [$pk]); + $this->server->broadcastPackets($targets ?? $this->hasSpawned, [ + PlayerSkinPacket::create($this->getUniqueId(), SkinAdapterSingleton::get()->toSkinData($this->skin)) + ]); } public function jump() : void{ diff --git a/src/network/mcpe/protocol/PlayerSkinPacket.php b/src/network/mcpe/protocol/PlayerSkinPacket.php index f13fe08aa6..99295e9e82 100644 --- a/src/network/mcpe/protocol/PlayerSkinPacket.php +++ b/src/network/mcpe/protocol/PlayerSkinPacket.php @@ -41,6 +41,13 @@ class PlayerSkinPacket extends DataPacket implements ClientboundPacket, Serverbo /** @var SkinData */ public $skin; + public static function create(UUID $uuid, SkinData $skinData) : self{ + $result = new self; + $result->uuid = $uuid; + $result->skin = $skinData; + return $result; + } + protected function decodePayload(PacketSerializer $in) : void{ $this->uuid = $in->getUUID(); $this->skin = $in->getSkin(); From c1a815a458204a53b41ef1a560ccab4fbba0b3f7 Mon Sep 17 00:00:00 2001 From: Frago9876543210 Date: Thu, 9 Jul 2020 12:43:42 +0000 Subject: [PATCH 1775/3224] Sign (block): added setText() (#3100) --- src/block/Sign.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/block/Sign.php b/src/block/Sign.php index 17bad1f3ac..b14203b67e 100644 --- a/src/block/Sign.php +++ b/src/block/Sign.php @@ -140,6 +140,10 @@ class Sign extends Transparent{ return $this->text; } + public function setText(SignText $text) : void{ + $this->text = $text; + } + /** * Called by the player controller (network session) to update the sign text, firing events as appropriate. * @@ -160,7 +164,7 @@ class Sign extends Transparent{ }, $text->getLines()))); $ev->call(); if(!$ev->isCancelled()){ - $this->text = clone $ev->getNewText(); + $this->setText($ev->getNewText()); $this->pos->getWorld()->setBlock($this->pos, $this); return true; } From c762ec13191cf0083c2e23bc3e15b16ab00b81b3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 Jul 2020 14:10:37 +0100 Subject: [PATCH 1776/3224] Entity: removed unused field --- src/entity/Entity.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 0f01a031c3..ee28cac992 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -170,8 +170,6 @@ abstract class Entity{ public $noDamageTicks = 0; /** @var bool */ protected $justCreated = true; - /** @var bool */ - private $invulnerable = false; /** @var AttributeMap */ protected $attributeMap; @@ -472,7 +470,6 @@ abstract class Entity{ $nbt->setFloat("FallDistance", $this->fallDistance); $nbt->setShort("Fire", $this->fireTicks); $nbt->setByte("OnGround", $this->onGround ? 1 : 0); - $nbt->setByte("Invulnerable", $this->invulnerable ? 1 : 0); return $nbt; } @@ -481,7 +478,6 @@ abstract class Entity{ $this->fireTicks = $nbt->getShort("Fire", 0); $this->onGround = $nbt->getByte("OnGround", 0) !== 0; - $this->invulnerable = $nbt->getByte("Invulnerable", 0) !== 0; $this->fallDistance = $nbt->getFloat("FallDistance", 0.0); From 91b028c2083aeae08b81b2ff1a7fefd98b2e7085 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 10 Jul 2020 20:06:26 +0100 Subject: [PATCH 1777/3224] WorldManager: use ChunkSelector to find stuff to pre-generate --- src/world/WorldManager.php | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 57bf4ac6fb..974a57422e 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -27,6 +27,7 @@ use pocketmine\entity\Entity; use pocketmine\event\world\WorldInitEvent; use pocketmine\event\world\WorldLoadEvent; use pocketmine\event\world\WorldUnloadEvent; +use pocketmine\player\ChunkSelector; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\Limits; @@ -42,7 +43,6 @@ use pocketmine\world\generator\GeneratorManager; use pocketmine\world\generator\normal\Normal; use function array_keys; use function array_shift; -use function asort; use function assert; use function count; use function implode; @@ -282,21 +282,7 @@ class WorldManager{ $centerX = $spawnLocation->getFloorX() >> 4; $centerZ = $spawnLocation->getFloorZ() >> 4; - $order = []; - - for($X = -3; $X <= 3; ++$X){ - for($Z = -3; $Z <= 3; ++$Z){ - $distance = $X ** 2 + $Z ** 2; - $chunkX = $X + $centerX; - $chunkZ = $Z + $centerZ; - $index = World::chunkHash($chunkX, $chunkZ); - $order[$index] = $distance; - } - } - - asort($order); - - foreach($order as $index => $distance){ + foreach((new ChunkSelector())->selectChunks(3, $centerX, $centerZ) as $index){ World::getXZ($index, $chunkX, $chunkZ); $world->populateChunk($chunkX, $chunkZ, true); } From 279abb871d09f7d5e1a2c5b831a96b3d1d83b884 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 10 Jul 2020 21:01:43 +0100 Subject: [PATCH 1778/3224] Remove all usages of CompoundTag->hasTag() in pretty much every case, these usages really wanted to read the tag's contents anyway, which can be combined with a getTag() and instanceof call for more concise and static analysis friendly code. In the few cases where the tag contents wasn't needed, it still wanted to check the type, which, again, can be done in a more static analysis friendly way by just using getTag() and instanceof. --- src/block/tile/Banner.php | 4 ++-- src/block/tile/Bed.php | 4 ++-- src/block/tile/Chest.php | 6 +++--- src/block/tile/ContainerTrait.php | 4 ++-- src/block/tile/FlowerPot.php | 4 ++-- src/block/tile/MonsterSpawner.php | 8 ++++---- src/block/tile/NameableTrait.php | 4 ++-- src/block/tile/Sign.php | 8 ++++---- src/block/tile/Skull.php | 4 ++-- src/entity/Entity.php | 8 ++++---- src/entity/EntityFactory.php | 8 ++++---- src/entity/Human.php | 10 +++++----- src/entity/Living.php | 12 ++++++------ src/entity/object/ExperienceOrb.php | 8 ++++---- src/entity/object/FallingBlock.php | 8 ++++---- src/entity/projectile/Projectile.php | 12 ++++++------ src/item/Armor.php | 4 ++-- src/item/Item.php | 2 +- src/network/mcpe/convert/TypeConverter.php | 4 ++-- src/network/mcpe/handler/InGamePacketHandler.php | 4 ++-- src/player/OfflinePlayer.php | 4 ++-- src/player/Player.php | 6 +++--- src/world/format/io/data/BaseNbtWorldData.php | 4 ++-- src/world/format/io/data/BedrockWorldData.php | 11 ++++++----- src/world/format/io/data/JavaWorldData.php | 15 ++++++++------- .../format/io/region/LegacyAnvilChunkTrait.php | 8 ++++---- src/world/format/io/region/McRegion.php | 12 ++++++------ 27 files changed, 94 insertions(+), 92 deletions(-) diff --git a/src/block/tile/Banner.php b/src/block/tile/Banner.php index ec9d17ca81..7c00b98ba6 100644 --- a/src/block/tile/Banner.php +++ b/src/block/tile/Banner.php @@ -61,8 +61,8 @@ class Banner extends Spawnable{ public function readSaveData(CompoundTag $nbt) : void{ $colorIdMap = DyeColorIdMap::getInstance(); - if($nbt->hasTag(self::TAG_BASE, IntTag::class)){ - $this->baseColor = $colorIdMap->fromInvertedId($nbt->getInt(self::TAG_BASE)); + if(($baseColorTag = $nbt->getTag(self::TAG_BASE)) instanceof IntTag){ + $this->baseColor = $colorIdMap->fromInvertedId($baseColorTag->getValue()); } $patterns = $nbt->getListTag(self::TAG_PATTERNS); diff --git a/src/block/tile/Bed.php b/src/block/tile/Bed.php index b41489787a..95c12e524b 100644 --- a/src/block/tile/Bed.php +++ b/src/block/tile/Bed.php @@ -49,8 +49,8 @@ class Bed extends Spawnable{ } public function readSaveData(CompoundTag $nbt) : void{ - if($nbt->hasTag(self::TAG_COLOR, ByteTag::class)){ - $this->color = DyeColorIdMap::getInstance()->fromId($nbt->getByte(self::TAG_COLOR)); + if(($colorTag = $nbt->getTag(self::TAG_COLOR)) instanceof ByteTag){ + $this->color = DyeColorIdMap::getInstance()->fromId($colorTag->getValue()); } } diff --git a/src/block/tile/Chest.php b/src/block/tile/Chest.php index 896cafead3..40ba79cd58 100644 --- a/src/block/tile/Chest.php +++ b/src/block/tile/Chest.php @@ -59,9 +59,9 @@ class Chest extends Spawnable implements Container, Nameable{ } public function readSaveData(CompoundTag $nbt) : void{ - if($nbt->hasTag(self::TAG_PAIRX, IntTag::class) and $nbt->hasTag(self::TAG_PAIRZ, IntTag::class)){ - $pairX = $nbt->getInt(self::TAG_PAIRX); - $pairZ = $nbt->getInt(self::TAG_PAIRZ); + if(($pairXTag = $nbt->getTag(self::TAG_PAIRX)) instanceof IntTag and ($pairZTag = $nbt->getTag(self::TAG_PAIRZ)) instanceof IntTag){ + $pairX = $pairXTag->getValue(); + $pairZ = $pairZTag->getValue(); if( ($this->pos->x === $pairX and abs($this->pos->z - $pairZ) === 1) or ($this->pos->z === $pairZ and abs($this->pos->x - $pairX) === 1) diff --git a/src/block/tile/ContainerTrait.php b/src/block/tile/ContainerTrait.php index 2968c54909..b01aa59445 100644 --- a/src/block/tile/ContainerTrait.php +++ b/src/block/tile/ContainerTrait.php @@ -56,8 +56,8 @@ trait ContainerTrait{ $inventory->getListeners()->add(...$listeners); } - if($tag->hasTag(Container::TAG_LOCK, StringTag::class)){ - $this->lock = $tag->getString(Container::TAG_LOCK); + if(($lockTag = $tag->getTag(Container::TAG_LOCK)) instanceof StringTag){ + $this->lock = $lockTag->getValue(); } } diff --git a/src/block/tile/FlowerPot.php b/src/block/tile/FlowerPot.php index 279041303b..f44e73e37c 100644 --- a/src/block/tile/FlowerPot.php +++ b/src/block/tile/FlowerPot.php @@ -42,9 +42,9 @@ class FlowerPot extends Spawnable{ private $plant = null; public function readSaveData(CompoundTag $nbt) : void{ - if($nbt->hasTag(self::TAG_ITEM, ShortTag::class) and $nbt->hasTag(self::TAG_ITEM_DATA, IntTag::class)){ + if(($itemIdTag = $nbt->getTag(self::TAG_ITEM)) instanceof ShortTag and ($itemMetaTag = $nbt->getTag(self::TAG_ITEM_DATA)) instanceof IntTag){ try{ - $this->setPlant(BlockFactory::getInstance()->get($nbt->getShort(self::TAG_ITEM), $nbt->getInt(self::TAG_ITEM_DATA))); + $this->setPlant(BlockFactory::getInstance()->get($itemIdTag->getValue(), $itemMetaTag->getValue())); }catch(\InvalidArgumentException $e){ //noop } diff --git a/src/block/tile/MonsterSpawner.php b/src/block/tile/MonsterSpawner.php index 2ee3cf55c1..8b6d0eeca1 100644 --- a/src/block/tile/MonsterSpawner.php +++ b/src/block/tile/MonsterSpawner.php @@ -95,11 +95,11 @@ class MonsterSpawner extends Spawnable{ private $requiredPlayerRange = self::DEFAULT_REQUIRED_PLAYER_RANGE; public function readSaveData(CompoundTag $nbt) : void{ - if($nbt->hasTag(self::TAG_LEGACY_ENTITY_TYPE_ID, IntTag::class)){ + if(($legacyIdTag = $nbt->getTag(self::TAG_LEGACY_ENTITY_TYPE_ID)) instanceof IntTag){ //TODO: this will cause unexpected results when there's no mapping for the entity - $this->entityTypeId = LegacyEntityIdToStringIdMap::getInstance()->legacyToString($nbt->getInt(self::TAG_LEGACY_ENTITY_TYPE_ID)) ?? ":"; - }elseif($nbt->hasTag(self::TAG_ENTITY_TYPE_ID, StringTag::class)){ - $this->entityTypeId = $nbt->getString(self::TAG_ENTITY_TYPE_ID); + $this->entityTypeId = LegacyEntityIdToStringIdMap::getInstance()->legacyToString($legacyIdTag->getValue()) ?? ":"; + }elseif(($idTag = $nbt->getTag(self::TAG_ENTITY_TYPE_ID)) instanceof StringTag){ + $this->entityTypeId = $idTag->getValue(); }else{ $this->entityTypeId = ":"; //default - TODO: replace this with a constant } diff --git a/src/block/tile/NameableTrait.php b/src/block/tile/NameableTrait.php index 74631a25f3..4a43e8aef3 100644 --- a/src/block/tile/NameableTrait.php +++ b/src/block/tile/NameableTrait.php @@ -59,8 +59,8 @@ trait NameableTrait{ } protected function loadName(CompoundTag $tag) : void{ - if($tag->hasTag(Nameable::TAG_CUSTOM_NAME, StringTag::class)){ - $this->customName = $tag->getString(Nameable::TAG_CUSTOM_NAME); + if(($customNameTag = $tag->getTag(Nameable::TAG_CUSTOM_NAME)) instanceof StringTag){ + $this->customName = $customNameTag->getValue(); } } diff --git a/src/block/tile/Sign.php b/src/block/tile/Sign.php index 8d16eb48e0..f09940b352 100644 --- a/src/block/tile/Sign.php +++ b/src/block/tile/Sign.php @@ -59,14 +59,14 @@ class Sign extends Spawnable{ } public function readSaveData(CompoundTag $nbt) : void{ - if($nbt->hasTag(self::TAG_TEXT_BLOB, StringTag::class)){ //MCPE 1.2 save format - $this->text = SignText::fromBlob(mb_scrub($nbt->getString(self::TAG_TEXT_BLOB), 'UTF-8')); + if(($textBlobTag = $nbt->getTag(self::TAG_TEXT_BLOB)) instanceof StringTag){ //MCPE 1.2 save format + $this->text = SignText::fromBlob(mb_scrub($textBlobTag->getValue(), 'UTF-8')); }else{ $text = []; for($i = 0; $i < SignText::LINE_COUNT; ++$i){ $textKey = sprintf(self::TAG_TEXT_LINE, $i + 1); - if($nbt->hasTag($textKey, StringTag::class)){ - $text[$i] = mb_scrub($nbt->getString($textKey), 'UTF-8'); + if(($lineTag = $nbt->getTag($textKey)) instanceof StringTag){ + $text[$i] = mb_scrub($lineTag->getValue(), 'UTF-8'); } } $this->text = new SignText($text); diff --git a/src/block/tile/Skull.php b/src/block/tile/Skull.php index 13de524cf4..4db9ebd930 100644 --- a/src/block/tile/Skull.php +++ b/src/block/tile/Skull.php @@ -51,9 +51,9 @@ class Skull extends Spawnable{ } public function readSaveData(CompoundTag $nbt) : void{ - if($nbt->hasTag(self::TAG_SKULL_TYPE, ByteTag::class)){ + if(($skullTypeTag = $nbt->getTag(self::TAG_SKULL_TYPE)) instanceof ByteTag){ try{ - $this->skullType = SkullType::fromMagicNumber($nbt->getByte(self::TAG_SKULL_TYPE)); + $this->skullType = SkullType::fromMagicNumber($skullTypeTag->getValue()); }catch(\InvalidArgumentException $e){ //bad data, drop it } diff --git a/src/entity/Entity.php b/src/entity/Entity.php index ee28cac992..3fdcc1fae3 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -481,12 +481,12 @@ abstract class Entity{ $this->fallDistance = $nbt->getFloat("FallDistance", 0.0); - if($nbt->hasTag("CustomName", StringTag::class)){ - $this->setNameTag($nbt->getString("CustomName")); + if(($customNameTag = $nbt->getTag("CustomName")) instanceof StringTag){ + $this->setNameTag($customNameTag->getValue()); - if($nbt->hasTag("CustomNameVisible", StringTag::class)){ + if(($customNameVisibleTag = $nbt->getTag("CustomNameVisible")) instanceof StringTag){ //Older versions incorrectly saved this as a string (see 890f72dbf23a77f294169b79590770470041adc4) - $this->setNameTagVisible($nbt->getString("CustomNameVisible") !== ""); + $this->setNameTagVisible($customNameVisibleTag->getValue() !== ""); }else{ $this->setNameTagVisible($nbt->getByte("CustomNameVisible", 1) !== 0); } diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index 95bc44ec86..a032c088fa 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -118,10 +118,10 @@ final class EntityFactory{ throw new \UnexpectedValueException("Unknown painting motive"); } $blockIn = new Vector3($nbt->getInt("TileX"), $nbt->getInt("TileY"), $nbt->getInt("TileZ")); - if($nbt->hasTag("Direction", ByteTag::class)){ - $facing = Painting::DATA_TO_FACING[$nbt->getByte("Direction")] ?? Facing::NORTH; - }elseif($nbt->hasTag("Facing", ByteTag::class)){ - $facing = Painting::DATA_TO_FACING[$nbt->getByte("Facing")] ?? Facing::NORTH; + if(($directionTag = $nbt->getTag("Direction")) instanceof ByteTag){ + $facing = Painting::DATA_TO_FACING[$directionTag->getValue()] ?? Facing::NORTH; + }elseif(($facingTag = $nbt->getTag("Facing")) instanceof ByteTag){ + $facing = Painting::DATA_TO_FACING[$facingTag->getValue()] ?? Facing::NORTH; }else{ throw new \UnexpectedValueException("Missing facing info"); } diff --git a/src/entity/Human.php b/src/entity/Human.php index ddf0994a55..b00787c227 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -105,7 +105,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ } return new Skin( //this throws if the skin is invalid $skinTag->getString("Name"), - $skinTag->hasTag("Data", StringTag::class) ? $skinTag->getString("Data") : $skinTag->getByteArray("Data"), //old data (this used to be saved as a StringTag in older versions of PM) + ($skinDataTag = $skinTag->getTag("Data")) instanceof StringTag ? $skinDataTag->getValue() : $skinTag->getByteArray("Data"), //old data (this used to be saved as a StringTag in older versions of PM) $skinTag->getByteArray("CapeData", ""), $skinTag->getString("GeometryName", ""), $skinTag->getByteArray("GeometryData", "") @@ -194,8 +194,8 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ * For Human entities which are not players, sets their properties such as nametag, skin and UUID from NBT. */ protected function initHumanData(CompoundTag $nbt) : void{ - if($nbt->hasTag("NameTag", StringTag::class)){ - $this->setNameTag($nbt->getString("NameTag")); + if(($nameTagTag = $nbt->getTag("NameTag")) instanceof StringTag){ + $this->setNameTag($nameTagTag->getValue()); } $this->uuid = UUID::fromData((string) $this->getId(), $this->skin->getSkinData(), $this->getNameTag()); @@ -251,8 +251,8 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $nbt->getFloat("XpP", 0.0)); $this->xpManager->setLifetimeTotalXp($nbt->getInt("XpTotal", 0)); - if($nbt->hasTag("XpSeed", IntTag::class)){ - $this->xpSeed = $nbt->getInt("XpSeed"); + if(($xpSeedTag = $nbt->getTag("XpSeed")) instanceof IntTag){ + $this->xpSeed = $xpSeedTag->getValue(); }else{ $this->xpSeed = random_int(Limits::INT32_MIN, Limits::INT32_MAX); } diff --git a/src/entity/Living.php b/src/entity/Living.php index 8675dd00ad..dab60300ce 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -134,12 +134,12 @@ abstract class Living extends Entity{ $health = $this->getMaxHealth(); - if($nbt->hasTag("HealF", FloatTag::class)){ - $health = $nbt->getFloat("HealF"); - }elseif($nbt->hasTag("Health", ShortTag::class)){ - $health = $nbt->getShort("Health"); //Older versions of PocketMine-MP incorrectly saved this as a short instead of a float - }elseif($nbt->hasTag("Health", FloatTag::class)){ - $health = $nbt->getFloat("Health"); + if(($healFTag = $nbt->getTag("HealF")) instanceof FloatTag){ + $health = $healFTag->getValue(); + }elseif(($healthTag = $nbt->getTag("Health")) instanceof ShortTag){ + $health = $healthTag->getValue(); //Older versions of PocketMine-MP incorrectly saved this as a short instead of a float + }elseif(($healthTag = $nbt->getTag("Health")) instanceof FloatTag){ + $health = $healthTag->getValue(); } $this->setHealth($health); diff --git a/src/entity/object/ExperienceOrb.php b/src/entity/object/ExperienceOrb.php index c928d4c167..3953eda2f0 100644 --- a/src/entity/object/ExperienceOrb.php +++ b/src/entity/object/ExperienceOrb.php @@ -108,10 +108,10 @@ class ExperienceOrb extends Entity{ $this->age = $nbt->getShort("Age", 0); $value = 1; - if($nbt->hasTag(self::TAG_VALUE_PC, ShortTag::class)){ //PC - $value = $nbt->getShort(self::TAG_VALUE_PC); - }elseif($nbt->hasTag(self::TAG_VALUE_PE, IntTag::class)){ //PE save format - $value = $nbt->getInt(self::TAG_VALUE_PE); + if(($valuePcTag = $nbt->getTag(self::TAG_VALUE_PC)) instanceof ShortTag){ //PC + $value = $valuePcTag->getValue(); + }elseif(($valuePeTag = $nbt->getTag(self::TAG_VALUE_PE)) instanceof IntTag){ //PE save format + $value = $valuePeTag->getValue(); } $this->setXpValue($value); diff --git a/src/entity/object/FallingBlock.php b/src/entity/object/FallingBlock.php index 69e43b800b..cfca869ea7 100644 --- a/src/entity/object/FallingBlock.php +++ b/src/entity/object/FallingBlock.php @@ -64,10 +64,10 @@ class FallingBlock extends Entity{ $blockId = 0; //TODO: 1.8+ save format - if($nbt->hasTag("TileID", IntTag::class)){ - $blockId = $nbt->getInt("TileID"); - }elseif($nbt->hasTag("Tile", ByteTag::class)){ - $blockId = $nbt->getByte("Tile"); + if(($tileIdTag = $nbt->getTag("TileID")) instanceof IntTag){ + $blockId = $tileIdTag->getValue(); + }elseif(($tileTag = $nbt->getTag("Tile")) instanceof ByteTag){ + $blockId = $tileTag->getValue(); } if($blockId === 0){ diff --git a/src/entity/projectile/Projectile.php b/src/entity/projectile/Projectile.php index 4a3d8f95ec..a6c0f810d8 100644 --- a/src/entity/projectile/Projectile.php +++ b/src/entity/projectile/Projectile.php @@ -82,20 +82,20 @@ abstract class Projectile extends Entity{ $blockId = null; $blockData = null; - if($nbt->hasTag("tileX", IntTag::class) and $nbt->hasTag("tileY", IntTag::class) and $nbt->hasTag("tileZ", IntTag::class)){ - $blockPos = new Vector3($nbt->getInt("tileX"), $nbt->getInt("tileY"), $nbt->getInt("tileZ")); + if(($tileXTag = $nbt->getTag("tileX")) instanceof IntTag and ($tileYTag = $nbt->getTag("tileY")) instanceof IntTag and ($tileZTag = $nbt->getTag("tileZ")) instanceof IntTag){ + $blockPos = new Vector3($tileXTag->getValue(), $tileYTag->getValue(), $tileZTag->getValue()); }else{ break; } - if($nbt->hasTag("blockId", IntTag::class)){ - $blockId = $nbt->getInt("blockId"); + if(($blockIdTag = $nbt->getTag("blockId")) instanceof IntTag){ + $blockId = $blockIdTag->getValue(); }else{ break; } - if($nbt->hasTag("blockData", ByteTag::class)){ - $blockData = $nbt->getByte("blockData"); + if(($blockDataTag = $nbt->getTag("blockData")) instanceof ByteTag){ + $blockData = $blockDataTag->getValue(); }else{ break; } diff --git a/src/item/Armor.php b/src/item/Armor.php index 039abe89b7..4f79d9c618 100644 --- a/src/item/Armor.php +++ b/src/item/Armor.php @@ -133,8 +133,8 @@ class Armor extends Durable{ protected function deserializeCompoundTag(CompoundTag $tag) : void{ parent::deserializeCompoundTag($tag); - if($tag->hasTag(self::TAG_CUSTOM_COLOR, IntTag::class)){ - $this->customColor = Color::fromARGB(Binary::unsignInt($tag->getInt(self::TAG_CUSTOM_COLOR))); + if(($colorTag = $tag->getTag(self::TAG_CUSTOM_COLOR)) instanceof IntTag){ + $this->customColor = Color::fromARGB(Binary::unsignInt($colorTag->getValue())); }else{ $this->customColor = null; } diff --git a/src/item/Item.php b/src/item/Item.php index 579fe0622a..17dc9dc295 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -647,7 +647,7 @@ class Item implements \JsonSerializable{ * Deserializes an Item from an NBT CompoundTag */ public static function nbtDeserialize(CompoundTag $tag) : Item{ - if(!$tag->hasTag("id") or !$tag->hasTag("Count")){ + if($tag->getTag("id") === null or $tag->getTag("Count") === null){ return ItemFactory::getInstance()->get(0); } diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index 11a83d6625..b404588c3c 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -137,8 +137,8 @@ class TypeConverter{ if($compound !== null){ $compound = clone $compound; - if($compound->hasTag(self::DAMAGE_TAG, IntTag::class)){ - $meta = $compound->getInt(self::DAMAGE_TAG); + if(($damageTag = $compound->getTag(self::DAMAGE_TAG)) instanceof IntTag){ + $meta = $damageTag->getValue(); $compound->removeTag(self::DAMAGE_TAG); if($compound->count() === 0){ $compound = null; diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 3b0218105e..4fd580a419 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -598,9 +598,9 @@ class InGamePacketHandler extends PacketHandler{ if(!($nbt instanceof CompoundTag)) throw new AssumptionFailedError("PHPStan should ensure this is a CompoundTag"); //for phpstorm's benefit if($block instanceof Sign){ - if($nbt->hasTag("Text", StringTag::class)){ + if(($textBlobTag = $nbt->getTag("Text")) instanceof StringTag){ try{ - $text = SignText::fromBlob($nbt->getString("Text")); + $text = SignText::fromBlob($textBlobTag->getValue()); }catch(\InvalidArgumentException $e){ throw BadPacketException::wrap($e, "Invalid sign text update"); } diff --git a/src/player/OfflinePlayer.php b/src/player/OfflinePlayer.php index a85b657c95..a484a4c756 100644 --- a/src/player/OfflinePlayer.php +++ b/src/player/OfflinePlayer.php @@ -99,11 +99,11 @@ class OfflinePlayer implements IPlayer{ } public function getFirstPlayed() : ?int{ - return ($this->namedtag !== null and $this->namedtag->hasTag("firstPlayed", LongTag::class)) ? $this->namedtag->getLong("firstPlayed") : null; + return ($this->namedtag !== null and ($firstPlayedTag = $this->namedtag->getTag("firstPlayed")) instanceof LongTag) ? $firstPlayedTag->getValue() : null; } public function getLastPlayed() : ?int{ - return ($this->namedtag !== null and $this->namedtag->hasTag("lastPlayed", LongTag::class)) ? $this->namedtag->getLong("lastPlayed") : null; + return ($this->namedtag !== null and ($lastPlayedTag = $this->namedtag->getTag("lastPlayed")) instanceof LongTag) ? $lastPlayedTag->getValue() : null; } public function hasPlayedBefore() : bool{ diff --git a/src/player/Player.php b/src/player/Player.php index caf9057494..cd887dcf2e 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -334,10 +334,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->firstPlayed = $nbt->getLong("firstPlayed", $now = (int) (microtime(true) * 1000)); $this->lastPlayed = $nbt->getLong("lastPlayed", $now); - if($this->server->getForceGamemode() or !$nbt->hasTag("playerGameType", IntTag::class)){ - $this->internalSetGameMode($this->server->getGamemode()); + if(!$this->server->getForceGamemode() and ($gameModeTag = $nbt->getTag("playerGameType")) instanceof IntTag){ + $this->internalSetGameMode(GameMode::fromMagicNumber($gameModeTag->getValue() & 0x03)); //TODO: bad hack here to avoid crashes on corrupted data }else{ - $this->internalSetGameMode(GameMode::fromMagicNumber($nbt->getInt("playerGameType") & 0x03)); //TODO: bad hack here to avoid crashes on corrupted data + $this->internalSetGameMode($this->server->getGamemode()); } $this->keepMovement = true; diff --git a/src/world/format/io/data/BaseNbtWorldData.php b/src/world/format/io/data/BaseNbtWorldData.php index b1092130f1..c7de29477f 100644 --- a/src/world/format/io/data/BaseNbtWorldData.php +++ b/src/world/format/io/data/BaseNbtWorldData.php @@ -125,8 +125,8 @@ abstract class BaseNbtWorldData implements WorldData{ } public function getTime() : int{ - if($this->compoundTag->hasTag("Time", IntTag::class)){ //some older PM worlds had this in the wrong format - return $this->compoundTag->getInt("Time"); + if(($timeTag = $this->compoundTag->getTag("Time")) instanceof IntTag){ //some older PM worlds had this in the wrong format + return $timeTag->getValue(); } return $this->compoundTag->getLong("Time", 0); } diff --git a/src/world/format/io/data/BedrockWorldData.php b/src/world/format/io/data/BedrockWorldData.php index a3139a90c9..6ae3103081 100644 --- a/src/world/format/io/data/BedrockWorldData.php +++ b/src/world/format/io/data/BedrockWorldData.php @@ -134,9 +134,10 @@ class BedrockWorldData extends BaseNbtWorldData{ } protected function fix() : void{ - if(!$this->compoundTag->hasTag("generatorName", StringTag::class)){ - if($this->compoundTag->hasTag("Generator", IntTag::class)){ - switch($this->compoundTag->getInt("Generator")){ //Detect correct generator from MCPE data + $generatorNameTag = $this->compoundTag->getTag("generatorName"); + if(!($generatorNameTag instanceof StringTag)){ + if(($mcpeGeneratorTypeTag = $this->compoundTag->getTag("Generator")) instanceof IntTag){ + switch($mcpeGeneratorTypeTag->getValue()){ //Detect correct generator from MCPE data case self::GENERATOR_FLAT: $this->compoundTag->setString("generatorName", "flat"); $this->compoundTag->setString("generatorOptions", "2;7,3,3,2;1"); @@ -154,11 +155,11 @@ class BedrockWorldData extends BaseNbtWorldData{ }else{ $this->compoundTag->setString("generatorName", "default"); } - }elseif(($generatorName = self::hackyFixForGeneratorClasspathInLevelDat($this->compoundTag->getString("generatorName"))) !== null){ + }elseif(($generatorName = self::hackyFixForGeneratorClasspathInLevelDat($generatorNameTag->getValue())) !== null){ $this->compoundTag->setString("generatorName", $generatorName); } - if(!$this->compoundTag->hasTag("generatorOptions", StringTag::class)){ + if(!($this->compoundTag->getTag("generatorOptions")) instanceof StringTag){ $this->compoundTag->setString("generatorOptions", ""); } } diff --git a/src/world/format/io/data/JavaWorldData.php b/src/world/format/io/data/JavaWorldData.php index 59e15bacc9..197b62fa9c 100644 --- a/src/world/format/io/data/JavaWorldData.php +++ b/src/world/format/io/data/JavaWorldData.php @@ -101,13 +101,14 @@ class JavaWorldData extends BaseNbtWorldData{ } protected function fix() : void{ - if(!$this->compoundTag->hasTag("generatorName", StringTag::class)){ + $generatorNameTag = $this->compoundTag->getTag("generatorName"); + if(!($generatorNameTag instanceof StringTag)){ $this->compoundTag->setString("generatorName", "default"); - }elseif(($generatorName = self::hackyFixForGeneratorClasspathInLevelDat($this->compoundTag->getString("generatorName"))) !== null){ + }elseif(($generatorName = self::hackyFixForGeneratorClasspathInLevelDat($generatorNameTag->getValue())) !== null){ $this->compoundTag->setString("generatorName", $generatorName); } - if(!$this->compoundTag->hasTag("generatorOptions", StringTag::class)){ + if(!($this->compoundTag->getTag("generatorOptions") instanceof StringTag)){ $this->compoundTag->setString("generatorOptions", ""); } } @@ -135,8 +136,8 @@ class JavaWorldData extends BaseNbtWorldData{ } public function getRainLevel() : float{ - if($this->compoundTag->hasTag("rainLevel", FloatTag::class)){ //PocketMine/MCPE - return $this->compoundTag->getFloat("rainLevel"); + if(($rainLevelTag = $this->compoundTag->getTag("rainLevel")) instanceof FloatTag){ //PocketMine/MCPE + return $rainLevelTag->getValue(); } return (float) $this->compoundTag->getByte("raining", 0); //PC vanilla @@ -156,8 +157,8 @@ class JavaWorldData extends BaseNbtWorldData{ } public function getLightningLevel() : float{ - if($this->compoundTag->hasTag("lightningLevel", FloatTag::class)){ //PocketMine/MCPE - return $this->compoundTag->getFloat("lightningLevel"); + if(($lightningLevelTag = $this->compoundTag->getTag("lightningLevel")) instanceof FloatTag){ //PocketMine/MCPE + return $lightningLevelTag->getValue(); } return (float) $this->compoundTag->getByte("thundering", 0); //PC vanilla diff --git a/src/world/format/io/region/LegacyAnvilChunkTrait.php b/src/world/format/io/region/LegacyAnvilChunkTrait.php index 1026286fa0..96c5e41803 100644 --- a/src/world/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/world/format/io/region/LegacyAnvilChunkTrait.php @@ -86,10 +86,10 @@ trait LegacyAnvilChunkTrait{ } }; $biomeArray = null; - if($chunk->hasTag("BiomeColors", IntArrayTag::class)){ - $biomeArray = $makeBiomeArray(ChunkUtils::convertBiomeColors($chunk->getIntArray("BiomeColors"))); //Convert back to original format - }elseif($chunk->hasTag("Biomes", ByteArrayTag::class)){ - $biomeArray = $makeBiomeArray($chunk->getByteArray("Biomes")); + if(($biomeColorsTag = $chunk->getTag("BiomeColors")) instanceof IntArrayTag){ + $biomeArray = $makeBiomeArray(ChunkUtils::convertBiomeColors($biomeColorsTag->getValue())); //Convert back to original format + }elseif(($biomesTag = $chunk->getTag("Biomes")) instanceof ByteArrayTag){ + $biomeArray = $makeBiomeArray($biomesTag->getValue()); } $result = new Chunk( diff --git a/src/world/format/io/region/McRegion.php b/src/world/format/io/region/McRegion.php index d78eca5a06..6f5ce48824 100644 --- a/src/world/format/io/region/McRegion.php +++ b/src/world/format/io/region/McRegion.php @@ -68,8 +68,8 @@ class McRegion extends RegionWorldProvider{ } $subChunks = []; - $fullIds = $chunk->hasTag("Blocks", ByteArrayTag::class) ? $chunk->getByteArray("Blocks") : str_repeat("\x00", 32768); - $fullData = $chunk->hasTag("Data", ByteArrayTag::class) ? $chunk->getByteArray("Data") : str_repeat("\x00", 16384); + $fullIds = ($fullIdsTag = $chunk->getTag("Blocks")) instanceof ByteArrayTag ? $fullIdsTag->getValue() : str_repeat("\x00", 32768); + $fullData = ($fullDataTag = $chunk->getTag("Data")) instanceof ByteArrayTag ? $fullDataTag->getValue() : str_repeat("\x00", 16384); for($y = 0; $y < 8; ++$y){ $subChunks[$y] = new SubChunk(BlockLegacyIds::AIR << 4, [SubChunkConverter::convertSubChunkFromLegacyColumn($fullIds, $fullData, $y)]); @@ -83,10 +83,10 @@ class McRegion extends RegionWorldProvider{ } }; $biomeIds = null; - if($chunk->hasTag("BiomeColors", IntArrayTag::class)){ - $biomeIds = $makeBiomeArray(ChunkUtils::convertBiomeColors($chunk->getIntArray("BiomeColors"))); //Convert back to original format - }elseif($chunk->hasTag("Biomes", ByteArrayTag::class)){ - $biomeIds = $makeBiomeArray($chunk->getByteArray("Biomes")); + if(($biomeColorsTag = $chunk->getTag("BiomeColors")) instanceof IntArrayTag){ + $biomeIds = $makeBiomeArray(ChunkUtils::convertBiomeColors($biomeColorsTag->getValue())); //Convert back to original format + }elseif(($biomesTag = $chunk->getTag("Biomes")) instanceof ByteArrayTag){ + $biomeIds = $makeBiomeArray($biomesTag->getValue()); } $result = new Chunk( From 9b52af62b6f469771f2355a964b35ecffa5117d9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 10 Jul 2020 21:32:39 +0100 Subject: [PATCH 1779/3224] Item: skip a step when decoding PC itemstacks --- src/item/Item.php | 9 ++++----- src/item/LegacyStringToItemParser.php | 5 +++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/item/Item.php b/src/item/Item.php index 17dc9dc295..d58089201f 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -658,13 +658,12 @@ class Item implements \JsonSerializable{ if($idTag instanceof ShortTag){ $item = ItemFactory::getInstance()->get($idTag->getValue(), $meta, $count); }elseif($idTag instanceof StringTag){ //PC item save format - try{ - $item = LegacyStringToItemParser::getInstance()->parse($idTag->getValue() . ":$meta"); - }catch(\InvalidArgumentException $e){ - //TODO: improve error handling + //TODO: this isn't a very good mapping source, we need a dedicated mapping for PC + $id = LegacyStringToItemParser::getInstance()->parseId($idTag->getValue()); + if($id === null){ return ItemFactory::air(); } - $item->setCount($count); + $item = ItemFactory::getInstance()->get($id, $meta, $count); }else{ throw new \InvalidArgumentException("Item CompoundTag ID must be an instance of StringTag or ShortTag, " . get_class($idTag) . " given"); } diff --git a/src/item/LegacyStringToItemParser.php b/src/item/LegacyStringToItemParser.php index ea5eb5c228..6eaa62ff92 100644 --- a/src/item/LegacyStringToItemParser.php +++ b/src/item/LegacyStringToItemParser.php @@ -32,6 +32,7 @@ use function is_int; use function is_numeric; use function is_string; use function json_decode; +use function mb_strtolower; use function str_replace; use function strtolower; use function trim; @@ -78,6 +79,10 @@ final class LegacyStringToItemParser{ $this->map[$alias] = $id; } + public function parseId(string $input) : ?int{ + return $this->map[mb_strtolower($this->reprocess($input))] ?? null; + } + /** * Tries to parse the specified string into Item types. * From 62815f6c9bc80de4e3252064080749fef4e16d70 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 10 Jul 2020 21:38:29 +0100 Subject: [PATCH 1780/3224] Furnace: get rid of entirely unnecessary ItemFactory usage --- src/block/tile/Furnace.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index 7f2ec36c4b..f07e24c7ba 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -31,7 +31,6 @@ use pocketmine\event\inventory\FurnaceSmeltEvent; use pocketmine\inventory\CallbackInventoryListener; use pocketmine\inventory\Inventory; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\ContainerSetDataPacket; @@ -169,7 +168,7 @@ class Furnace extends Spawnable implements Container, Nameable{ ++$this->cookTime; if($this->cookTime >= 200){ //10 seconds - $product = ItemFactory::getInstance()->get($smelt->getResult()->getId(), $smelt->getResult()->getMeta(), $product->getCount() + 1); + $product = $smelt->getResult()->setCount($product->getCount() + 1); $ev = new FurnaceSmeltEvent($this, $raw, $product); $ev->call(); From d4f6dc8179de0902da5bda2cc88f5c1cdce6bf67 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 11 Jul 2020 10:50:02 +0100 Subject: [PATCH 1781/3224] BlockFactory: make color block registration slightly less painful to look at --- src/block/BlockFactory.php | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 32b7f2f8ae..e01b541e70 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -454,16 +454,19 @@ class BlockFactory{ $colorIdMap = DyeColorIdMap::getInstance(); foreach(DyeColor::getAll() as $color){ - $this->register(new Carpet(new BID(Ids::CARPET, $colorIdMap->toId($color)), $color->getDisplayName() . " Carpet")); - $this->register(new Concrete(new BID(Ids::CONCRETE, $colorIdMap->toId($color)), $color->getDisplayName() . " Concrete")); - $this->register(new ConcretePowder(new BID(Ids::CONCRETE_POWDER, $colorIdMap->toId($color)), $color->getDisplayName() . " Concrete Powder")); - $this->register(new Glass(new BID(Ids::STAINED_GLASS, $colorIdMap->toId($color)), $color->getDisplayName() . " Stained Glass")); - $this->register(new GlassPane(new BID(Ids::STAINED_GLASS_PANE, $colorIdMap->toId($color)), $color->getDisplayName() . " Stained Glass Pane")); - $this->register(new GlazedTerracotta(BlockLegacyIdHelper::getGlazedTerracottaIdentifier($color), $color->getDisplayName() . " Glazed Terracotta")); - $this->register(new HardenedClay(new BID(Ids::STAINED_CLAY, $colorIdMap->toId($color)), $color->getDisplayName() . " Stained Clay")); - $this->register(new HardenedGlass(new BID(Ids::HARD_STAINED_GLASS, $colorIdMap->toId($color)), "Hardened " . $color->getDisplayName() . " Stained Glass")); - $this->register(new HardenedGlassPane(new BID(Ids::HARD_STAINED_GLASS_PANE, $colorIdMap->toId($color)), "Hardened " . $color->getDisplayName() . " Stained Glass Pane")); - $this->register(new Wool(new BID(Ids::WOOL, $colorIdMap->toId($color)), $color->getDisplayName() . " Wool")); + $coloredName = function(string $name) use($color) : string{ + return $color->getDisplayName() . " " . $name; + }; + $this->register(new Carpet(new BID(Ids::CARPET, $colorIdMap->toId($color)), $coloredName("Carpet"))); + $this->register(new Concrete(new BID(Ids::CONCRETE, $colorIdMap->toId($color)), $coloredName("Concrete"))); + $this->register(new ConcretePowder(new BID(Ids::CONCRETE_POWDER, $colorIdMap->toId($color)), $coloredName("Concrete Powder"))); + $this->register(new Glass(new BID(Ids::STAINED_GLASS, $colorIdMap->toId($color)), $coloredName("Stained Glass"))); + $this->register(new GlassPane(new BID(Ids::STAINED_GLASS_PANE, $colorIdMap->toId($color)), $coloredName("Stained Glass Pane"))); + $this->register(new GlazedTerracotta(BlockLegacyIdHelper::getGlazedTerracottaIdentifier($color), $coloredName("Glazed Terracotta"))); + $this->register(new HardenedClay(new BID(Ids::STAINED_CLAY, $colorIdMap->toId($color)), $coloredName("Stained Clay"))); + $this->register(new HardenedGlass(new BID(Ids::HARD_STAINED_GLASS, $colorIdMap->toId($color)), "Hardened " . $coloredName("Stained Glass"))); + $this->register(new HardenedGlassPane(new BID(Ids::HARD_STAINED_GLASS_PANE, $colorIdMap->toId($color)), "Hardened " . $coloredName("Stained Glass Pane"))); + $this->register(new Wool(new BID(Ids::WOOL, $colorIdMap->toId($color)), $coloredName("Wool"))); } $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_ANDESITE), "Andesite Wall")); From 81b38cda5db15b7b6c508987ff89b1bbe039f200 Mon Sep 17 00:00:00 2001 From: SOFe Date: Sun, 12 Jul 2020 00:42:15 +0800 Subject: [PATCH 1782/3224] Removed `setCancelled` from `Cancellable` (#3685) * Removed `setCancelled` from `Cancellable` Before anyone screams, THIS CHANGE WILL NOT AFFECT MOST PLUGINS (although it allows future changes to break some). This commit rewrites the documentation of `Cancellable`, clarifying the concept of "cancelled" from the perspective of the event framework. This commit also removes the `setCancelled` method from `Cancellable`. This does not affect plugins using the (originally standard) `setCancelled` method on events directly, since the implementation on classes was not removed. On the other hand, it no longer requires `Cancellable` events to implement this method, allowing flexibility on cancelation conditions, e.g. subclasses may require additional parameters for cancellation without needing to use hacks to check that the user cancelled the event in the correct way. --- src/event/Cancellable.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/event/Cancellable.php b/src/event/Cancellable.php index 023549023d..e01d0b52d6 100644 --- a/src/event/Cancellable.php +++ b/src/event/Cancellable.php @@ -24,10 +24,18 @@ declare(strict_types=1); namespace pocketmine\event; /** - * Events that can be cancelled must use the interface Cancellable + * This interface is implemented by an Event subclass if and only if it can be cancelled. + * + * The cancellation of an event directly affects whether downstream event handlers + * without `@handleCancelled` will be called with this event. + * Implementations may provide a direct setter for cancellation (typically by using `CancellableTrait`) + * or implement an alternative logic (such as a function on another data field) for `isCancelled()`. */ interface Cancellable{ + /** + * Returns whether this instance of the event is currently cancelled. + * + * If it is cancelled, only downstream handlers that declare `@handleCancelled` will be called with this event. + */ public function isCancelled() : bool; - - public function setCancelled(bool $value = true) : void; } From 2226efd7a007e7a0b1c49c8ba75ed076a5851334 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 11 Jul 2020 17:44:22 +0100 Subject: [PATCH 1783/3224] added base data handling for Lab Table, Compound Creator, Element Constructor and Material Reducer these also have a blockentity which needs to be implemented as well. --- src/block/BlockFactory.php | 7 ++++- src/block/ChemistryTable.php | 61 ++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/block/ChemistryTable.php diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index e01b541e70..fd2c622033 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -486,6 +486,12 @@ class BlockFactory{ $this->registerElements(); + $chemistryTableBreakInfo = new BlockBreakInfo(2.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()); + $this->register(new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_COMPOUND_CREATOR), "Compound Creator", $chemistryTableBreakInfo)); + $this->register(new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_ELEMENT_CONSTRUCTOR), "Element Constructor", $chemistryTableBreakInfo)); + $this->register(new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_LAB_TABLE), "Lab Table", $chemistryTableBreakInfo)); + $this->register(new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_MATERIAL_REDUCER), "Material Reducer", $chemistryTableBreakInfo)); + //region --- auto-generated TODOs --- //TODO: minecraft:bamboo //TODO: minecraft:bamboo_sapling @@ -499,7 +505,6 @@ class BlockFactory{ //TODO: minecraft:cauldron //TODO: minecraft:chain_command_block //TODO: minecraft:chemical_heat - //TODO: minecraft:chemistry_table //TODO: minecraft:chorus_flower //TODO: minecraft:chorus_plant //TODO: minecraft:command_block diff --git a/src/block/ChemistryTable.php b/src/block/ChemistryTable.php new file mode 100644 index 0000000000..d3b3d6d77a --- /dev/null +++ b/src/block/ChemistryTable.php @@ -0,0 +1,61 @@ +facing = Facing::opposite(BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x3)); + } + + protected function writeStateToMeta() : int{ + return BlockDataSerializer::writeLegacyHorizontalFacing(Facing::opposite($this->facing)); + } + + public function getStateBitmask() : int{ + return 0b0011; + } + + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($player !== null){ + $this->facing = Facing::opposite($player->getHorizontalFacing()); + } + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + //TODO + return false; + } +} From 923ea4647633a56ec25448c015ce13274f3d3514 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 11 Jul 2020 17:47:53 +0100 Subject: [PATCH 1784/3224] PlayerPreLoginEvent: implement Cancellable again --- src/event/player/PlayerPreLoginEvent.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/event/player/PlayerPreLoginEvent.php b/src/event/player/PlayerPreLoginEvent.php index 040c827709..66cf550d2b 100644 --- a/src/event/player/PlayerPreLoginEvent.php +++ b/src/event/player/PlayerPreLoginEvent.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\event\player; +use pocketmine\event\Cancellable; use pocketmine\event\Event; use pocketmine\player\PlayerInfo; use function array_keys; @@ -38,7 +39,7 @@ use function count; * WARNING: Any information about the player CANNOT be trusted at this stage, because they are not authenticated and * could be a hacker posing as another player. */ -class PlayerPreLoginEvent extends Event{ +class PlayerPreLoginEvent extends Event implements Cancellable{ public const KICK_REASON_PLUGIN = 0; public const KICK_REASON_SERVER_FULL = 1; public const KICK_REASON_SERVER_WHITELISTED = 2; @@ -167,4 +168,8 @@ class PlayerPreLoginEvent extends Event{ return ""; } + + public function isCancelled() : bool{ + return !$this->isAllowed(); + } } From 180c0e4999f950b9fe0e5a7f4f74c43e908a7ebb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 11 Jul 2020 18:20:32 +0100 Subject: [PATCH 1785/3224] World: rely on Player being a ChunkListener instead of ChunkLoader ChunkListeners are less dangerous, and also make more sense considering the usages. Ideally we want to not have to care if a listener is a Player at all, but that's still some work away yet. --- src/world/World.php | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index aa4d4159d5..04c0f48d4a 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -165,11 +165,11 @@ class World implements ChunkManager{ private $loaderCounter = []; /** @var ChunkLoader[][] */ private $chunkLoaders = []; - /** @var Player[][] */ - private $playerLoaders = []; /** @var ChunkListener[][] */ private $chunkListeners = []; + /** @var Player[][] */ + private $playerChunkListeners = []; /** @var ClientboundPacket[][] */ private $chunkPackets = []; @@ -499,7 +499,7 @@ class World implements ChunkManager{ * @return Player[] */ public function getChunkPlayers(int $chunkX, int $chunkZ) : array{ - return $this->playerLoaders[World::chunkHash($chunkX, $chunkZ)] ?? []; + return $this->playerChunkListeners[World::chunkHash($chunkX, $chunkZ)] ?? []; } /** @@ -536,15 +536,11 @@ class World implements ChunkManager{ if(!isset($this->chunkLoaders[$chunkHash = World::chunkHash($chunkX, $chunkZ)])){ $this->chunkLoaders[$chunkHash] = []; - $this->playerLoaders[$chunkHash] = []; }elseif(isset($this->chunkLoaders[$chunkHash][$loaderId])){ return; } $this->chunkLoaders[$chunkHash][$loaderId] = $loader; - if($loader instanceof Player){ - $this->playerLoaders[$chunkHash][$loaderId] = $loader; - } if(!isset($this->loaders[$loaderId])){ $this->loaderCounter[$loaderId] = 1; @@ -565,10 +561,8 @@ class World implements ChunkManager{ $loaderId = spl_object_id($loader); if(isset($this->chunkLoaders[$chunkHash][$loaderId])){ unset($this->chunkLoaders[$chunkHash][$loaderId]); - unset($this->playerLoaders[$chunkHash][$loaderId]); if(count($this->chunkLoaders[$chunkHash]) === 0){ unset($this->chunkLoaders[$chunkHash]); - unset($this->playerLoaders[$chunkHash]); $this->unloadChunkRequest($chunkX, $chunkZ, true); } @@ -589,6 +583,9 @@ class World implements ChunkManager{ }else{ $this->chunkListeners[$hash] = [spl_object_id($listener) => $listener]; } + if($listener instanceof Player){ + $this->playerChunkListeners[$hash][spl_object_id($listener)] = $listener; + } } /** @@ -600,8 +597,10 @@ class World implements ChunkManager{ $hash = World::chunkHash($chunkX, $chunkZ); if(isset($this->chunkListeners[$hash])){ unset($this->chunkListeners[$hash][spl_object_id($listener)]); + unset($this->playerChunkListeners[$hash][spl_object_id($listener)]); if(count($this->chunkListeners[$hash]) === 0){ unset($this->chunkListeners[$hash]); + unset($this->playerChunkListeners[$hash]); } } } From 217f9c574a8155e764ddaf89cf4dc788874c1390 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 11 Jul 2020 18:48:10 +0100 Subject: [PATCH 1786/3224] Player no longer implements ChunkLoader this stops plugins from misusing Player as a ChunkLoader in ways it doesn't know about, causing leaks and god knows what else. --- src/player/Player.php | 30 ++++++------------- src/player/TickingChunkLoader.php | 49 +++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 21 deletions(-) create mode 100644 src/player/TickingChunkLoader.php diff --git a/src/player/Player.php b/src/player/Player.php index cd887dcf2e..ece67dcc7f 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -134,7 +134,7 @@ use const PHP_INT_MAX; /** * Main class that handles networking, recovery, and packet sending to the server part */ -class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, IPlayer{ +class Player extends Human implements CommandSender, ChunkListener, IPlayer{ use PermissibleDelegateTrait { recalculatePermissions as private delegateRecalculatePermissions; } @@ -213,6 +213,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, protected $chunksPerTick; /** @var ChunkSelector */ protected $chunkSelector; + /** @var TickingChunkLoader */ + protected $chunkLoader; /** @var bool[] map: raw UUID (string) => bool */ protected $hiddenPlayers = []; @@ -293,8 +295,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $onGround = true; } + $this->chunkLoader = new TickingChunkLoader($spawn); + //load the spawn chunk so we can see the terrain - $world->registerChunkLoader($this, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4, true); + $world->registerChunkLoader($this->chunkLoader, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4, true); $world->registerChunkListener($this, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4); $this->usedChunks[World::chunkHash($spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4)] = UsedChunkStatus::NEEDED(); @@ -742,7 +746,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->networkSession->stopUsingChunk($x, $z); unset($this->usedChunks[$index]); } - $world->unregisterChunkLoader($this, $x, $z); + $world->unregisterChunkLoader($this->chunkLoader, $x, $z); $world->unregisterChunkListener($this, $x, $z); unset($this->loadQueue[$index]); } @@ -776,7 +780,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, ++$count; $this->usedChunks[$index] = UsedChunkStatus::NEEDED(); - $this->getWorld()->registerChunkLoader($this, $X, $Z, true); + $this->getWorld()->registerChunkLoader($this->chunkLoader, $X, $Z, true); $this->getWorld()->registerChunkListener($this, $X, $Z); if(!$this->getWorld()->populateChunk($X, $Z)){ @@ -871,6 +875,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->loadQueue = $newOrder; if(count($this->loadQueue) > 0 or count($unloadChunks) > 0){ + $this->chunkLoader->setCurrentLocation($this->location); $this->networkSession->syncViewAreaCenterPoint($this->location, $this->viewDistance); } @@ -2338,21 +2343,4 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->nextChunkOrderRun = 0; } } - - /** - * @see ChunkLoader::getX() - * @return float - */ - public function getX(){ - return $this->location->getX(); - } - - /** - * @see ChunkLoader::getZ() - * @return float - */ - public function getZ(){ - return $this->location->getZ(); - } - } diff --git a/src/player/TickingChunkLoader.php b/src/player/TickingChunkLoader.php new file mode 100644 index 0000000000..0a95240b43 --- /dev/null +++ b/src/player/TickingChunkLoader.php @@ -0,0 +1,49 @@ +currentLocation = $currentLocation; + } + + public function setCurrentLocation(Vector3 $currentLocation) : void{ + $this->currentLocation = $currentLocation; + } + + public function getX(){ + return $this->currentLocation->getFloorX(); + } + + public function getZ(){ + return $this->currentLocation->getFloorZ(); + } +} From d3c90c4dce32d29a113a97787c925337914512f4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 11 Jul 2020 18:54:35 +0100 Subject: [PATCH 1787/3224] update block factory consistency check --- tests/phpunit/block/block_factory_consistency_check.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index c7cf034a7a..912a8dfdeb 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From e199f403dcfe432a58a3f2587163f3134b363586 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 13 Jul 2020 11:08:03 +0100 Subject: [PATCH 1788/3224] MemoryManager: remove useless information from object dumps --- src/MemoryManager.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/MemoryManager.php b/src/MemoryManager.php index 90acbc9397..b6718774c8 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -406,14 +406,6 @@ class MemoryManager{ "properties" => [] ]; - if(($parent = $reflection->getParentClass()) !== false){ - $info["parent"] = $parent->getName(); - } - - if(count($reflection->getInterfaceNames()) > 0){ - $info["implements"] = implode(", ", $reflection->getInterfaceNames()); - } - for($original = $reflection; $reflection !== false; $reflection = $reflection->getParentClass()){ foreach($reflection->getProperties() as $property){ if($property->isStatic()){ From 46c4c6502273994516114a361ef1aa933f06b440 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 13 Jul 2020 11:10:22 +0100 Subject: [PATCH 1789/3224] MemoryManager: remove duplicated information from memory dump --- src/MemoryManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MemoryManager.php b/src/MemoryManager.php index b6718774c8..d0ccf40109 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -424,7 +424,7 @@ class MemoryManager{ } } - fwrite($obData, "$hash@$className: " . json_encode($info, JSON_UNESCAPED_SLASHES) . "\n"); + fwrite($obData, json_encode($info, JSON_UNESCAPED_SLASHES) . "\n"); } }while($continue); From efd67a132ed432b47a74c8b98211597557c419d5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 13 Jul 2020 11:44:21 +0100 Subject: [PATCH 1790/3224] MemoryDump: fixed duplicated properties, reduce useless noise --- src/MemoryManager.php | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/MemoryManager.php b/src/MemoryManager.php index d0ccf40109..df1feac92d 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -406,22 +406,16 @@ class MemoryManager{ "properties" => [] ]; - for($original = $reflection; $reflection !== false; $reflection = $reflection->getParentClass()){ - foreach($reflection->getProperties() as $property){ - if($property->isStatic()){ - continue; - } - - $name = $property->getName(); - if($reflection !== $original and !$property->isPublic()){ - $name = $reflection->getName() . ":" . $name; - } - if(!$property->isPublic()){ - $property->setAccessible(true); - } - - $info["properties"][$name] = self::continueDump($property->getValue($object), $objects, $refCounts, 0, $maxNesting, $maxStringSize); + foreach($reflection->getProperties() as $property){ + if($property->isStatic()){ + continue; } + + if(!$property->isPublic()){ + $property->setAccessible(true); + } + + $info["properties"][$property->getName()] = self::continueDump($property->getValue($object), $objects, $refCounts, 0, $maxNesting, $maxStringSize); } fwrite($obData, json_encode($info, JSON_UNESCAPED_SLASHES) . "\n"); From 10504851648b559d92db0acf59e4cefa41c1b8ee Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 13 Jul 2020 11:51:25 +0100 Subject: [PATCH 1791/3224] MemoryManager: remove class name from object references it's possible to see this information by looking up the hash, which it's necessary to do in order to see any interesting information anyway. --- src/MemoryManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MemoryManager.php b/src/MemoryManager.php index df1feac92d..9cd87d0f02 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -461,7 +461,7 @@ class MemoryManager{ ++$refCounts[$hash]; - $data = "(object) $hash@" . get_class($from); + $data = "(object) $hash"; }elseif(is_array($from)){ if($recursion >= 5){ return "(error) ARRAY RECURSION LIMIT REACHED"; From b09b619a301b8d01ca79364a610db29164c159cd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 17 Jul 2020 14:23:32 +0100 Subject: [PATCH 1792/3224] updated VanillaBlocks --- src/block/VanillaBlocks.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index faf49a9033..487d70f0e1 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -129,6 +129,7 @@ use function assert; * @method static Wall COBBLESTONE_WALL() * @method static Cobweb COBWEB() * @method static CocoaBlock COCOA_POD() + * @method static ChemistryTable COMPOUND_CREATOR() * @method static Flower CORNFLOWER() * @method static Opaque CRACKED_STONE_BRICKS() * @method static CraftingTable CRAFTING_TABLE() @@ -198,6 +199,7 @@ use function assert; * @method static Element ELEMENT_CHLORINE() * @method static Element ELEMENT_CHROMIUM() * @method static Element ELEMENT_COBALT() + * @method static ChemistryTable ELEMENT_CONSTRUCTOR() * @method static Element ELEMENT_COPERNICIUM() * @method static Element ELEMENT_COPPER() * @method static Element ELEMENT_CURIUM() @@ -409,6 +411,7 @@ use function assert; * @method static WoodenStairs JUNGLE_STAIRS() * @method static WoodenTrapdoor JUNGLE_TRAPDOOR() * @method static Wood JUNGLE_WOOD() + * @method static ChemistryTable LAB_TABLE() * @method static Ladder LADDER() * @method static Lantern LANTERN() * @method static Opaque LAPIS_LAZULI() @@ -454,6 +457,7 @@ use function assert; * @method static GlassPane MAGENTA_STAINED_GLASS_PANE() * @method static Wool MAGENTA_WOOL() * @method static Magma MAGMA() + * @method static ChemistryTable MATERIAL_REDUCER() * @method static Melon MELON() * @method static MelonStem MELON_STEM() * @method static Skull MOB_HEAD() @@ -790,6 +794,7 @@ final class VanillaBlocks{ self::register("cobblestone_wall", $factory->get(139)); self::register("cobweb", $factory->get(30)); self::register("cocoa_pod", $factory->get(127)); + self::register("compound_creator", $factory->get(238)); self::register("cornflower", $factory->get(38, 9)); self::register("cracked_stone_bricks", $factory->get(98, 2)); self::register("crafting_table", $factory->get(58)); @@ -859,6 +864,7 @@ final class VanillaBlocks{ self::register("element_chlorine", $factory->get(283)); self::register("element_chromium", $factory->get(290)); self::register("element_cobalt", $factory->get(293)); + self::register("element_constructor", $factory->get(238, 8)); self::register("element_copernicium", $factory->get(378)); self::register("element_copper", $factory->get(295)); self::register("element_curium", $factory->get(362)); @@ -1070,6 +1076,7 @@ final class VanillaBlocks{ self::register("jungle_stairs", $factory->get(136)); self::register("jungle_trapdoor", $factory->get(403)); self::register("jungle_wood", $factory->get(467, 3)); + self::register("lab_table", $factory->get(238, 12)); self::register("ladder", $factory->get(65, 2)); self::register("lantern", $factory->get(463)); self::register("lapis_lazuli", $factory->get(22)); @@ -1115,6 +1122,7 @@ final class VanillaBlocks{ self::register("magenta_stained_glass_pane", $factory->get(160, 2)); self::register("magenta_wool", $factory->get(35, 2)); self::register("magma", $factory->get(213)); + self::register("material_reducer", $factory->get(238, 4)); self::register("melon", $factory->get(103)); self::register("melon_stem", $factory->get(105)); self::register("mob_head", $factory->get(144, 2)); From 9872bb4cb883ddd533c5853925bcdecdf3d1b13c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 17 Jul 2020 14:41:04 +0100 Subject: [PATCH 1793/3224] Enchantment: remove dead classes --- src/item/enchantment/EnchantmentEntry.php | 58 ----------------------- src/item/enchantment/EnchantmentList.php | 49 ------------------- 2 files changed, 107 deletions(-) delete mode 100644 src/item/enchantment/EnchantmentEntry.php delete mode 100644 src/item/enchantment/EnchantmentList.php diff --git a/src/item/enchantment/EnchantmentEntry.php b/src/item/enchantment/EnchantmentEntry.php deleted file mode 100644 index 50fd4301e2..0000000000 --- a/src/item/enchantment/EnchantmentEntry.php +++ /dev/null @@ -1,58 +0,0 @@ -enchantments = $enchantments; - $this->cost = $cost; - $this->randomName = $randomName; - } - - /** - * @return Enchantment[] - */ - public function getEnchantments() : array{ - return $this->enchantments; - } - - public function getCost() : int{ - return $this->cost; - } - - public function getRandomName() : string{ - return $this->randomName; - } -} diff --git a/src/item/enchantment/EnchantmentList.php b/src/item/enchantment/EnchantmentList.php deleted file mode 100644 index 103d3c1a63..0000000000 --- a/src/item/enchantment/EnchantmentList.php +++ /dev/null @@ -1,49 +0,0 @@ - - */ - private $enchantments; - - public function __construct(int $size){ - $this->enchantments = new \SplFixedArray($size); - } - - public function setSlot(int $slot, EnchantmentEntry $entry) : void{ - $this->enchantments[$slot] = $entry; - } - - public function getSlot(int $slot) : EnchantmentEntry{ - return $this->enchantments[$slot]; - } - - public function getSize() : int{ - return $this->enchantments->getSize(); - } -} From 915d63a2e8a9a54c8e96629dd1ce21bc29ff4f9a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 17 Jul 2020 14:54:51 +0100 Subject: [PATCH 1794/3224] Button: rename powered property to pressed --- src/block/Button.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/block/Button.php b/src/block/Button.php index 23657d7646..e868fe86f7 100644 --- a/src/block/Button.php +++ b/src/block/Button.php @@ -37,16 +37,16 @@ abstract class Button extends Flowable{ /** @var int */ protected $facing = Facing::DOWN; /** @var bool */ - protected $powered = false; + protected $pressed = false; protected function writeStateToMeta() : int{ - return BlockDataSerializer::writeFacing($this->facing) | ($this->powered ? BlockLegacyMetadata::BUTTON_FLAG_POWERED : 0); + return BlockDataSerializer::writeFacing($this->facing) | ($this->pressed ? BlockLegacyMetadata::BUTTON_FLAG_POWERED : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ //TODO: in PC it's (6 - facing) for every meta except 0 (down) $this->facing = BlockDataSerializer::readFacing($stateMeta & 0x07); - $this->powered = ($stateMeta & BlockLegacyMetadata::BUTTON_FLAG_POWERED) !== 0; + $this->pressed = ($stateMeta & BlockLegacyMetadata::BUTTON_FLAG_POWERED) !== 0; } public function getStateBitmask() : int{ @@ -62,8 +62,8 @@ abstract class Button extends Flowable{ abstract protected function getActivationTime() : int; public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->powered){ - $this->powered = true; + if(!$this->pressed){ + $this->pressed = true; $this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, $this->getActivationTime()); $this->pos->getWorld()->addSound($this->pos->add(0.5, 0.5, 0.5), new RedstonePowerOnSound()); @@ -73,8 +73,8 @@ abstract class Button extends Flowable{ } public function onScheduledUpdate() : void{ - if($this->powered){ - $this->powered = false; + if($this->pressed){ + $this->pressed = false; $this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorld()->addSound($this->pos->add(0.5, 0.5, 0.5), new RedstonePowerOffSound()); } From 5f70b960815499f823ca47f17b0d72f424a94cb1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 17 Jul 2020 23:03:10 +0100 Subject: [PATCH 1795/3224] ResourcePack: do not export getPath() a resource pack is not required to come from a location on disk (although it's currently the only practical option). --- src/resourcepacks/ResourcePack.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/resourcepacks/ResourcePack.php b/src/resourcepacks/ResourcePack.php index aee9cf2c2c..a1abfc227e 100644 --- a/src/resourcepacks/ResourcePack.php +++ b/src/resourcepacks/ResourcePack.php @@ -25,11 +25,6 @@ namespace pocketmine\resourcepacks; interface ResourcePack{ - /** - * Returns the path to the resource pack. This might be a file or a directory, depending on the type of pack. - */ - public function getPath() : string; - /** * Returns the human-readable name of the resource pack */ From 3e2cfd28ccf370ade351c3858482b06f0291502f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 17 Jul 2020 23:07:37 +0100 Subject: [PATCH 1796/3224] ResourcePackManager: change validity check to is_string() --- src/resourcepacks/ResourcePackManager.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/resourcepacks/ResourcePackManager.php b/src/resourcepacks/ResourcePackManager.php index bbe83ca3c6..1b6af4549b 100644 --- a/src/resourcepacks/ResourcePackManager.php +++ b/src/resourcepacks/ResourcePackManager.php @@ -31,6 +31,7 @@ use function file_exists; use function gettype; use function is_array; use function is_dir; +use function is_string; use function mkdir; use function strtolower; use const DIRECTORY_SEPARATOR; @@ -78,14 +79,11 @@ class ResourcePackManager{ } foreach($resourceStack as $pos => $pack){ - try{ - $pack = (string) $pack; - }catch(\ErrorException $e){ + if(!is_string($pack)){ $logger->critical("Found invalid entry in resource pack list at offset $pos of type " . gettype($pack)); continue; } try{ - /** @var string $pack */ $packPath = $this->path . DIRECTORY_SEPARATOR . $pack; if(!file_exists($packPath)){ throw new ResourcePackException("File or directory not found"); From 1ba32c98c74d80f7ca234ea9f6cbc3ce225cd96f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 17 Jul 2020 23:19:33 +0100 Subject: [PATCH 1797/3224] protocol: avoid potential constructor refactoring packet decode bug if the order of the constructor parameters were changed, it would cause these statements to be reordered, causing packet fields to be decoded in the wrong order. --- .../resourcepacks/ResourcePackInfoEntry.php | 17 ++++++++--------- .../resourcepacks/ResourcePackStackEntry.php | 9 ++++----- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php index e2ed65901d..0e0308ece1 100644 --- a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php +++ b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php @@ -91,14 +91,13 @@ class ResourcePackInfoEntry{ } public static function read(PacketSerializer $in) : self{ - return new self( - $uuid = $in->getString(), - $version = $in->getString(), - $sizeBytes = $in->getLLong(), - $encryptionKey = $in->getString(), - $subPackName = $in->getString(), - $contentId = $in->getString(), - $hasScripts = $in->getBool() - ); + $uuid = $in->getString(); + $version = $in->getString(); + $sizeBytes = $in->getLLong(); + $encryptionKey = $in->getString(); + $subPackName = $in->getString(); + $contentId = $in->getString(); + $hasScripts = $in->getBool(); + return new self($uuid, $version, $sizeBytes, $encryptionKey, $subPackName, $contentId, $hasScripts); } } diff --git a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php index 2e809fb7ed..1151d37d56 100644 --- a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php +++ b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php @@ -59,10 +59,9 @@ class ResourcePackStackEntry{ } public static function read(PacketSerializer $in) : self{ - return new self( - $packId = $in->getString(), - $version = $in->getString(), - $subPackName = $in->getString() - ); + $packId = $in->getString(); + $version = $in->getString(); + $subPackName = $in->getString(); + return new self($packId, $version, $subPackName); } } From 213afa42dd8a8f9068e814e903e61254d2bd0fcb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 19 Jul 2020 13:09:48 +0100 Subject: [PATCH 1798/3224] BlockFactory: make registerElements() a bit less wide --- src/block/BlockFactory.php | 239 +++++++++++++++++++------------------ 1 file changed, 120 insertions(+), 119 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index fd2c622033..c9c2fe61d2 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -558,126 +558,127 @@ class BlockFactory{ } private function registerElements() : void{ - $this->register(new Opaque(new BID(Ids::ELEMENT_0), "???", BlockBreakInfo::instant())); + $instaBreak = BlockBreakInfo::instant(); + $this->register(new Opaque(new BID(Ids::ELEMENT_0), "???", $instaBreak)); - $this->register(new Element(new BID(Ids::ELEMENT_1), "Hydrogen", BlockBreakInfo::instant(), "h", 1, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_2), "Helium", BlockBreakInfo::instant(), "he", 2, 7)); - $this->register(new Element(new BID(Ids::ELEMENT_3), "Lithium", BlockBreakInfo::instant(), "li", 3, 0)); - $this->register(new Element(new BID(Ids::ELEMENT_4), "Beryllium", BlockBreakInfo::instant(), "be", 4, 1)); - $this->register(new Element(new BID(Ids::ELEMENT_5), "Boron", BlockBreakInfo::instant(), "b", 5, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_6), "Carbon", BlockBreakInfo::instant(), "c", 6, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_7), "Nitrogen", BlockBreakInfo::instant(), "n", 7, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_8), "Oxygen", BlockBreakInfo::instant(), "o", 8, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_9), "Fluorine", BlockBreakInfo::instant(), "f", 9, 6)); - $this->register(new Element(new BID(Ids::ELEMENT_10), "Neon", BlockBreakInfo::instant(), "ne", 10, 7)); - $this->register(new Element(new BID(Ids::ELEMENT_11), "Sodium", BlockBreakInfo::instant(), "na", 11, 0)); - $this->register(new Element(new BID(Ids::ELEMENT_12), "Magnesium", BlockBreakInfo::instant(), "mg", 12, 1)); - $this->register(new Element(new BID(Ids::ELEMENT_13), "Aluminum", BlockBreakInfo::instant(), "al", 13, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_14), "Silicon", BlockBreakInfo::instant(), "si", 14, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_15), "Phosphorus", BlockBreakInfo::instant(), "p", 15, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_16), "Sulfur", BlockBreakInfo::instant(), "s", 16, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_17), "Chlorine", BlockBreakInfo::instant(), "cl", 17, 6)); - $this->register(new Element(new BID(Ids::ELEMENT_18), "Argon", BlockBreakInfo::instant(), "ar", 18, 7)); - $this->register(new Element(new BID(Ids::ELEMENT_19), "Potassium", BlockBreakInfo::instant(), "k", 19, 0)); - $this->register(new Element(new BID(Ids::ELEMENT_20), "Calcium", BlockBreakInfo::instant(), "ca", 20, 1)); - $this->register(new Element(new BID(Ids::ELEMENT_21), "Scandium", BlockBreakInfo::instant(), "sc", 21, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_22), "Titanium", BlockBreakInfo::instant(), "ti", 22, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_23), "Vanadium", BlockBreakInfo::instant(), "v", 23, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_24), "Chromium", BlockBreakInfo::instant(), "cr", 24, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_25), "Manganese", BlockBreakInfo::instant(), "mn", 25, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_26), "Iron", BlockBreakInfo::instant(), "fe", 26, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_27), "Cobalt", BlockBreakInfo::instant(), "co", 27, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_28), "Nickel", BlockBreakInfo::instant(), "ni", 28, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_29), "Copper", BlockBreakInfo::instant(), "cu", 29, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_30), "Zinc", BlockBreakInfo::instant(), "zn", 30, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_31), "Gallium", BlockBreakInfo::instant(), "ga", 31, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_32), "Germanium", BlockBreakInfo::instant(), "ge", 32, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_33), "Arsenic", BlockBreakInfo::instant(), "as", 33, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_34), "Selenium", BlockBreakInfo::instant(), "se", 34, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_35), "Bromine", BlockBreakInfo::instant(), "br", 35, 6)); - $this->register(new Element(new BID(Ids::ELEMENT_36), "Krypton", BlockBreakInfo::instant(), "kr", 36, 7)); - $this->register(new Element(new BID(Ids::ELEMENT_37), "Rubidium", BlockBreakInfo::instant(), "rb", 37, 0)); - $this->register(new Element(new BID(Ids::ELEMENT_38), "Strontium", BlockBreakInfo::instant(), "sr", 38, 1)); - $this->register(new Element(new BID(Ids::ELEMENT_39), "Yttrium", BlockBreakInfo::instant(), "y", 39, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_40), "Zirconium", BlockBreakInfo::instant(), "zr", 40, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_41), "Niobium", BlockBreakInfo::instant(), "nb", 41, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_42), "Molybdenum", BlockBreakInfo::instant(), "mo", 42, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_43), "Technetium", BlockBreakInfo::instant(), "tc", 43, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_44), "Ruthenium", BlockBreakInfo::instant(), "ru", 44, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_45), "Rhodium", BlockBreakInfo::instant(), "rh", 45, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_46), "Palladium", BlockBreakInfo::instant(), "pd", 46, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_47), "Silver", BlockBreakInfo::instant(), "ag", 47, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_48), "Cadmium", BlockBreakInfo::instant(), "cd", 48, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_49), "Indium", BlockBreakInfo::instant(), "in", 49, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_50), "Tin", BlockBreakInfo::instant(), "sn", 50, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_51), "Antimony", BlockBreakInfo::instant(), "sb", 51, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_52), "Tellurium", BlockBreakInfo::instant(), "te", 52, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_53), "Iodine", BlockBreakInfo::instant(), "i", 53, 6)); - $this->register(new Element(new BID(Ids::ELEMENT_54), "Xenon", BlockBreakInfo::instant(), "xe", 54, 7)); - $this->register(new Element(new BID(Ids::ELEMENT_55), "Cesium", BlockBreakInfo::instant(), "cs", 55, 0)); - $this->register(new Element(new BID(Ids::ELEMENT_56), "Barium", BlockBreakInfo::instant(), "ba", 56, 1)); - $this->register(new Element(new BID(Ids::ELEMENT_57), "Lanthanum", BlockBreakInfo::instant(), "la", 57, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_58), "Cerium", BlockBreakInfo::instant(), "ce", 58, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_59), "Praseodymium", BlockBreakInfo::instant(), "pr", 59, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_60), "Neodymium", BlockBreakInfo::instant(), "nd", 60, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_61), "Promethium", BlockBreakInfo::instant(), "pm", 61, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_62), "Samarium", BlockBreakInfo::instant(), "sm", 62, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_63), "Europium", BlockBreakInfo::instant(), "eu", 63, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_64), "Gadolinium", BlockBreakInfo::instant(), "gd", 64, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_65), "Terbium", BlockBreakInfo::instant(), "tb", 65, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_66), "Dysprosium", BlockBreakInfo::instant(), "dy", 66, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_67), "Holmium", BlockBreakInfo::instant(), "ho", 67, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_68), "Erbium", BlockBreakInfo::instant(), "er", 68, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_69), "Thulium", BlockBreakInfo::instant(), "tm", 69, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_70), "Ytterbium", BlockBreakInfo::instant(), "yb", 70, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_71), "Lutetium", BlockBreakInfo::instant(), "lu", 71, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_72), "Hafnium", BlockBreakInfo::instant(), "hf", 72, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_73), "Tantalum", BlockBreakInfo::instant(), "ta", 73, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_74), "Tungsten", BlockBreakInfo::instant(), "w", 74, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_75), "Rhenium", BlockBreakInfo::instant(), "re", 75, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_76), "Osmium", BlockBreakInfo::instant(), "os", 76, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_77), "Iridium", BlockBreakInfo::instant(), "ir", 77, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_78), "Platinum", BlockBreakInfo::instant(), "pt", 78, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_79), "Gold", BlockBreakInfo::instant(), "au", 79, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_80), "Mercury", BlockBreakInfo::instant(), "hg", 80, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_81), "Thallium", BlockBreakInfo::instant(), "tl", 81, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_82), "Lead", BlockBreakInfo::instant(), "pb", 82, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_83), "Bismuth", BlockBreakInfo::instant(), "bi", 83, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_84), "Polonium", BlockBreakInfo::instant(), "po", 84, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_85), "Astatine", BlockBreakInfo::instant(), "at", 85, 6)); - $this->register(new Element(new BID(Ids::ELEMENT_86), "Radon", BlockBreakInfo::instant(), "rn", 86, 7)); - $this->register(new Element(new BID(Ids::ELEMENT_87), "Francium", BlockBreakInfo::instant(), "fr", 87, 0)); - $this->register(new Element(new BID(Ids::ELEMENT_88), "Radium", BlockBreakInfo::instant(), "ra", 88, 1)); - $this->register(new Element(new BID(Ids::ELEMENT_89), "Actinium", BlockBreakInfo::instant(), "ac", 89, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_90), "Thorium", BlockBreakInfo::instant(), "th", 90, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_91), "Protactinium", BlockBreakInfo::instant(), "pa", 91, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_92), "Uranium", BlockBreakInfo::instant(), "u", 92, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_93), "Neptunium", BlockBreakInfo::instant(), "np", 93, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_94), "Plutonium", BlockBreakInfo::instant(), "pu", 94, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_95), "Americium", BlockBreakInfo::instant(), "am", 95, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_96), "Curium", BlockBreakInfo::instant(), "cm", 96, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_97), "Berkelium", BlockBreakInfo::instant(), "bk", 97, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_98), "Californium", BlockBreakInfo::instant(), "cf", 98, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_99), "Einsteinium", BlockBreakInfo::instant(), "es", 99, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_100), "Fermium", BlockBreakInfo::instant(), "fm", 100, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_101), "Mendelevium", BlockBreakInfo::instant(), "md", 101, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_102), "Nobelium", BlockBreakInfo::instant(), "no", 102, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_103), "Lawrencium", BlockBreakInfo::instant(), "lr", 103, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_104), "Rutherfordium", BlockBreakInfo::instant(), "rf", 104, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_105), "Dubnium", BlockBreakInfo::instant(), "db", 105, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_106), "Seaborgium", BlockBreakInfo::instant(), "sg", 106, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_107), "Bohrium", BlockBreakInfo::instant(), "bh", 107, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_108), "Hassium", BlockBreakInfo::instant(), "hs", 108, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_109), "Meitnerium", BlockBreakInfo::instant(), "mt", 109, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_110), "Darmstadtium", BlockBreakInfo::instant(), "ds", 110, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_111), "Roentgenium", BlockBreakInfo::instant(), "rg", 111, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_112), "Copernicium", BlockBreakInfo::instant(), "cn", 112, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_113), "Nihonium", BlockBreakInfo::instant(), "nh", 113, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_114), "Flerovium", BlockBreakInfo::instant(), "fl", 114, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_115), "Moscovium", BlockBreakInfo::instant(), "mc", 115, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_116), "Livermorium", BlockBreakInfo::instant(), "lv", 116, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_117), "Tennessine", BlockBreakInfo::instant(), "ts", 117, 6)); - $this->register(new Element(new BID(Ids::ELEMENT_118), "Oganesson", BlockBreakInfo::instant(), "og", 118, 7)); + $this->register(new Element(new BID(Ids::ELEMENT_1), "Hydrogen", $instaBreak, "h", 1, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_2), "Helium", $instaBreak, "he", 2, 7)); + $this->register(new Element(new BID(Ids::ELEMENT_3), "Lithium", $instaBreak, "li", 3, 0)); + $this->register(new Element(new BID(Ids::ELEMENT_4), "Beryllium", $instaBreak, "be", 4, 1)); + $this->register(new Element(new BID(Ids::ELEMENT_5), "Boron", $instaBreak, "b", 5, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_6), "Carbon", $instaBreak, "c", 6, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_7), "Nitrogen", $instaBreak, "n", 7, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_8), "Oxygen", $instaBreak, "o", 8, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_9), "Fluorine", $instaBreak, "f", 9, 6)); + $this->register(new Element(new BID(Ids::ELEMENT_10), "Neon", $instaBreak, "ne", 10, 7)); + $this->register(new Element(new BID(Ids::ELEMENT_11), "Sodium", $instaBreak, "na", 11, 0)); + $this->register(new Element(new BID(Ids::ELEMENT_12), "Magnesium", $instaBreak, "mg", 12, 1)); + $this->register(new Element(new BID(Ids::ELEMENT_13), "Aluminum", $instaBreak, "al", 13, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_14), "Silicon", $instaBreak, "si", 14, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_15), "Phosphorus", $instaBreak, "p", 15, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_16), "Sulfur", $instaBreak, "s", 16, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_17), "Chlorine", $instaBreak, "cl", 17, 6)); + $this->register(new Element(new BID(Ids::ELEMENT_18), "Argon", $instaBreak, "ar", 18, 7)); + $this->register(new Element(new BID(Ids::ELEMENT_19), "Potassium", $instaBreak, "k", 19, 0)); + $this->register(new Element(new BID(Ids::ELEMENT_20), "Calcium", $instaBreak, "ca", 20, 1)); + $this->register(new Element(new BID(Ids::ELEMENT_21), "Scandium", $instaBreak, "sc", 21, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_22), "Titanium", $instaBreak, "ti", 22, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_23), "Vanadium", $instaBreak, "v", 23, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_24), "Chromium", $instaBreak, "cr", 24, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_25), "Manganese", $instaBreak, "mn", 25, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_26), "Iron", $instaBreak, "fe", 26, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_27), "Cobalt", $instaBreak, "co", 27, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_28), "Nickel", $instaBreak, "ni", 28, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_29), "Copper", $instaBreak, "cu", 29, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_30), "Zinc", $instaBreak, "zn", 30, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_31), "Gallium", $instaBreak, "ga", 31, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_32), "Germanium", $instaBreak, "ge", 32, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_33), "Arsenic", $instaBreak, "as", 33, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_34), "Selenium", $instaBreak, "se", 34, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_35), "Bromine", $instaBreak, "br", 35, 6)); + $this->register(new Element(new BID(Ids::ELEMENT_36), "Krypton", $instaBreak, "kr", 36, 7)); + $this->register(new Element(new BID(Ids::ELEMENT_37), "Rubidium", $instaBreak, "rb", 37, 0)); + $this->register(new Element(new BID(Ids::ELEMENT_38), "Strontium", $instaBreak, "sr", 38, 1)); + $this->register(new Element(new BID(Ids::ELEMENT_39), "Yttrium", $instaBreak, "y", 39, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_40), "Zirconium", $instaBreak, "zr", 40, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_41), "Niobium", $instaBreak, "nb", 41, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_42), "Molybdenum", $instaBreak, "mo", 42, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_43), "Technetium", $instaBreak, "tc", 43, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_44), "Ruthenium", $instaBreak, "ru", 44, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_45), "Rhodium", $instaBreak, "rh", 45, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_46), "Palladium", $instaBreak, "pd", 46, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_47), "Silver", $instaBreak, "ag", 47, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_48), "Cadmium", $instaBreak, "cd", 48, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_49), "Indium", $instaBreak, "in", 49, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_50), "Tin", $instaBreak, "sn", 50, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_51), "Antimony", $instaBreak, "sb", 51, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_52), "Tellurium", $instaBreak, "te", 52, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_53), "Iodine", $instaBreak, "i", 53, 6)); + $this->register(new Element(new BID(Ids::ELEMENT_54), "Xenon", $instaBreak, "xe", 54, 7)); + $this->register(new Element(new BID(Ids::ELEMENT_55), "Cesium", $instaBreak, "cs", 55, 0)); + $this->register(new Element(new BID(Ids::ELEMENT_56), "Barium", $instaBreak, "ba", 56, 1)); + $this->register(new Element(new BID(Ids::ELEMENT_57), "Lanthanum", $instaBreak, "la", 57, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_58), "Cerium", $instaBreak, "ce", 58, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_59), "Praseodymium", $instaBreak, "pr", 59, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_60), "Neodymium", $instaBreak, "nd", 60, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_61), "Promethium", $instaBreak, "pm", 61, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_62), "Samarium", $instaBreak, "sm", 62, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_63), "Europium", $instaBreak, "eu", 63, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_64), "Gadolinium", $instaBreak, "gd", 64, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_65), "Terbium", $instaBreak, "tb", 65, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_66), "Dysprosium", $instaBreak, "dy", 66, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_67), "Holmium", $instaBreak, "ho", 67, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_68), "Erbium", $instaBreak, "er", 68, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_69), "Thulium", $instaBreak, "tm", 69, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_70), "Ytterbium", $instaBreak, "yb", 70, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_71), "Lutetium", $instaBreak, "lu", 71, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_72), "Hafnium", $instaBreak, "hf", 72, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_73), "Tantalum", $instaBreak, "ta", 73, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_74), "Tungsten", $instaBreak, "w", 74, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_75), "Rhenium", $instaBreak, "re", 75, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_76), "Osmium", $instaBreak, "os", 76, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_77), "Iridium", $instaBreak, "ir", 77, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_78), "Platinum", $instaBreak, "pt", 78, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_79), "Gold", $instaBreak, "au", 79, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_80), "Mercury", $instaBreak, "hg", 80, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_81), "Thallium", $instaBreak, "tl", 81, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_82), "Lead", $instaBreak, "pb", 82, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_83), "Bismuth", $instaBreak, "bi", 83, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_84), "Polonium", $instaBreak, "po", 84, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_85), "Astatine", $instaBreak, "at", 85, 6)); + $this->register(new Element(new BID(Ids::ELEMENT_86), "Radon", $instaBreak, "rn", 86, 7)); + $this->register(new Element(new BID(Ids::ELEMENT_87), "Francium", $instaBreak, "fr", 87, 0)); + $this->register(new Element(new BID(Ids::ELEMENT_88), "Radium", $instaBreak, "ra", 88, 1)); + $this->register(new Element(new BID(Ids::ELEMENT_89), "Actinium", $instaBreak, "ac", 89, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_90), "Thorium", $instaBreak, "th", 90, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_91), "Protactinium", $instaBreak, "pa", 91, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_92), "Uranium", $instaBreak, "u", 92, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_93), "Neptunium", $instaBreak, "np", 93, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_94), "Plutonium", $instaBreak, "pu", 94, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_95), "Americium", $instaBreak, "am", 95, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_96), "Curium", $instaBreak, "cm", 96, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_97), "Berkelium", $instaBreak, "bk", 97, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_98), "Californium", $instaBreak, "cf", 98, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_99), "Einsteinium", $instaBreak, "es", 99, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_100), "Fermium", $instaBreak, "fm", 100, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_101), "Mendelevium", $instaBreak, "md", 101, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_102), "Nobelium", $instaBreak, "no", 102, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_103), "Lawrencium", $instaBreak, "lr", 103, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_104), "Rutherfordium", $instaBreak, "rf", 104, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_105), "Dubnium", $instaBreak, "db", 105, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_106), "Seaborgium", $instaBreak, "sg", 106, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_107), "Bohrium", $instaBreak, "bh", 107, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_108), "Hassium", $instaBreak, "hs", 108, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_109), "Meitnerium", $instaBreak, "mt", 109, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_110), "Darmstadtium", $instaBreak, "ds", 110, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_111), "Roentgenium", $instaBreak, "rg", 111, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_112), "Copernicium", $instaBreak, "cn", 112, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_113), "Nihonium", $instaBreak, "nh", 113, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_114), "Flerovium", $instaBreak, "fl", 114, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_115), "Moscovium", $instaBreak, "mc", 115, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_116), "Livermorium", $instaBreak, "lv", 116, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_117), "Tennessine", $instaBreak, "ts", 117, 6)); + $this->register(new Element(new BID(Ids::ELEMENT_118), "Oganesson", $instaBreak, "og", 118, 7)); } /** From ff54eae4b2e32146927e1fc11406fdf44f6fc50c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 21 Jul 2020 11:59:47 +0100 Subject: [PATCH 1799/3224] updated composer dependencies --- composer.lock | 462 +++++++++++++++++++++++++++----------------------- 1 file changed, 250 insertions(+), 212 deletions(-) diff --git a/composer.lock b/composer.lock index 62fdc423c0..bc93f3c601 100644 --- a/composer.lock +++ b/composer.lock @@ -552,12 +552,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "a0118ce3026929e11cc05cdf776bb18cdcd1b822" + "reference": "2a1a1783123c365a755f1f6d1023466d27d52795" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/a0118ce3026929e11cc05cdf776bb18cdcd1b822", - "reference": "a0118ce3026929e11cc05cdf776bb18cdcd1b822", + "url": "https://api.github.com/repos/pmmp/Math/zipball/2a1a1783123c365a755f1f6d1023466d27d52795", + "reference": "2a1a1783123c365a755f1f6d1023466d27d52795", "shasum": "" }, "require": { @@ -579,7 +579,7 @@ "LGPL-3.0" ], "description": "PHP library containing math related code used in PocketMine-MP", - "time": "2020-06-27T19:45:51+00:00" + "time": "2020-07-09T19:58:18+00:00" }, { "name": "pocketmine/nbt", @@ -810,16 +810,16 @@ }, { "name": "respect/validation", - "version": "2.0.10", + "version": "2.0.13", "source": { "type": "git", "url": "https://github.com/Respect/Validation.git", - "reference": "80f236bb900e5bc5e790737a31806f4d10c560ba" + "reference": "78d1ce404cee8a25e2577ee5b829ee88e7ea1e4a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Respect/Validation/zipball/80f236bb900e5bc5e790737a31806f4d10c560ba", - "reference": "80f236bb900e5bc5e790737a31806f4d10c560ba", + "url": "https://api.github.com/repos/Respect/Validation/zipball/78d1ce404cee8a25e2577ee5b829ee88e7ea1e4a", + "reference": "78d1ce404cee8a25e2577ee5b829ee88e7ea1e4a", "shasum": "" }, "require": { @@ -872,20 +872,20 @@ "validation", "validator" ], - "time": "2020-06-07T00:14:45+00:00" + "time": "2020-07-19T00:20:19+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.17.0", + "version": "v1.18.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "fa79b11539418b02fc5e1897267673ba2c19419c" + "reference": "a6977d63bf9a0ad4c65cd352709e230876f9904a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fa79b11539418b02fc5e1897267673ba2c19419c", - "reference": "fa79b11539418b02fc5e1897267673ba2c19419c", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/a6977d63bf9a0ad4c65cd352709e230876f9904a", + "reference": "a6977d63bf9a0ad4c65cd352709e230876f9904a", "shasum": "" }, "require": { @@ -897,7 +897,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.17-dev" + "dev-master": "1.18-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -945,7 +949,7 @@ "type": "tidelift" } ], - "time": "2020-05-12T16:47:27+00:00" + "time": "2020-07-14T12:35:20+00:00" } ], "packages-dev": [ @@ -1007,20 +1011,20 @@ }, { "name": "myclabs/deep-copy", - "version": "1.9.5", + "version": "1.10.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef" + "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/b2c28789e80a97badd14145fda39b545d83ca3ef", - "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", + "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", "shasum": "" }, "require": { - "php": "^7.1" + "php": "^7.1 || ^8.0" }, "replace": { "myclabs/deep-copy": "self.version" @@ -1051,7 +1055,13 @@ "object", "object graph" ], - "time": "2020-01-17T21:11:47+00:00" + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2020-06-29T13:22:24+00:00" }, { "name": "phar-io/manifest", @@ -1157,25 +1167,25 @@ }, { "name": "phpdocumentor/reflection-common", - "version": "2.1.0", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b" + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/6568f4687e5b41b054365f9ae03fcb1ed5f2069b", - "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", "shasum": "" }, "require": { - "php": ">=7.1" + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev" + "dev-2.x": "2.x-dev" } }, "autoload": { @@ -1202,32 +1212,31 @@ "reflection", "static analysis" ], - "time": "2020-04-27T09:25:28+00:00" + "time": "2020-06-27T09:03:43+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.1.0", + "version": "5.2.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e" + "reference": "3170448f5769fe19f456173d833734e0ff1b84df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e", - "reference": "cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/3170448f5769fe19f456173d833734e0ff1b84df", + "reference": "3170448f5769fe19f456173d833734e0ff1b84df", "shasum": "" }, "require": { - "ext-filter": "^7.1", - "php": "^7.2", - "phpdocumentor/reflection-common": "^2.0", - "phpdocumentor/type-resolver": "^1.0", - "webmozart/assert": "^1" + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" }, "require-dev": { - "doctrine/instantiator": "^1", - "mockery/mockery": "^1" + "mockery/mockery": "~1.3.2" }, "type": "library", "extra": { @@ -1255,34 +1264,33 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2020-02-22T12:28:44+00:00" + "time": "2020-07-20T20:05:34+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.1.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "7462d5f123dfc080dfdf26897032a6513644fc95" + "reference": "e878a14a65245fbe78f8080eba03b47c3b705651" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/7462d5f123dfc080dfdf26897032a6513644fc95", - "reference": "7462d5f123dfc080dfdf26897032a6513644fc95", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e878a14a65245fbe78f8080eba03b47c3b705651", + "reference": "e878a14a65245fbe78f8080eba03b47c3b705651", "shasum": "" }, "require": { - "php": "^7.2", + "php": "^7.2 || ^8.0", "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { - "ext-tokenizer": "^7.2", - "mockery/mockery": "~1" + "ext-tokenizer": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.x-dev" + "dev-1.x": "1.x-dev" } }, "autoload": { @@ -1301,37 +1309,37 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2020-02-18T18:59:58+00:00" + "time": "2020-06-27T10:12:23+00:00" }, { "name": "phpspec/prophecy", - "version": "v1.10.3", + "version": "1.11.1", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "451c3cd1418cf640de218914901e51b064abb093" + "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093", - "reference": "451c3cd1418cf640de218914901e51b064abb093", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/b20034be5efcdab4fb60ca3a29cba2949aead160", + "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", - "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" + "doctrine/instantiator": "^1.2", + "php": "^7.2", + "phpdocumentor/reflection-docblock": "^5.0", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" }, "require-dev": { - "phpspec/phpspec": "^2.5 || ^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + "phpspec/phpspec": "^6.0", + "phpunit/phpunit": "^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.10.x-dev" + "dev-master": "1.11.x-dev" } }, "autoload": { @@ -1364,7 +1372,7 @@ "spy", "stub" ], - "time": "2020-03-05T15:02:03+00:00" + "time": "2020-07-08T12:44:21+00:00" }, { "name": "phpstan/phpstan", @@ -1480,16 +1488,16 @@ }, { "name": "phpstan/phpstan-strict-rules", - "version": "0.12.2", + "version": "0.12.3", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-strict-rules.git", - "reference": "a670a59aff7cf96f75d21b974860ada10e25b2ee" + "reference": "937283265620af9e2005743134ebb4e197b12d8e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/a670a59aff7cf96f75d21b974860ada10e25b2ee", - "reference": "a670a59aff7cf96f75d21b974860ada10e25b2ee", + "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/937283265620af9e2005743134ebb4e197b12d8e", + "reference": "937283265620af9e2005743134ebb4e197b12d8e", "shasum": "" }, "require": { @@ -1498,7 +1506,7 @@ }, "require-dev": { "consistence/coding-standard": "^3.0.1", - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "ergebnis/composer-normalize": "^2.0.2", "jakub-onderka/php-parallel-lint": "^1.0", "phing/phing": "^2.16.0", @@ -1527,7 +1535,7 @@ "MIT" ], "description": "Extra strict and opinionated rules for PHPStan", - "time": "2020-01-20T13:08:52+00:00" + "time": "2020-07-16T08:58:37+00:00" }, { "name": "phpunit/php-code-coverage", @@ -1601,20 +1609,20 @@ }, { "name": "phpunit/php-file-iterator", - "version": "3.0.2", + "version": "3.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "eba15e538f2bb3fe018b7bbb47d2fe32d404bfd2" + "reference": "25fefc5b19835ca653877fe081644a3f8c1d915e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/eba15e538f2bb3fe018b7bbb47d2fe32d404bfd2", - "reference": "eba15e538f2bb3fe018b7bbb47d2fe32d404bfd2", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/25fefc5b19835ca653877fe081644a3f8c1d915e", + "reference": "25fefc5b19835ca653877fe081644a3f8c1d915e", "shasum": "" }, "require": { - "php": "^7.3" + "php": "^7.3 || ^8.0" }, "require-dev": { "phpunit/phpunit": "^9.0" @@ -1653,24 +1661,24 @@ "type": "github" } ], - "time": "2020-06-15T12:54:35+00:00" + "time": "2020-07-11T05:18:21+00:00" }, { "name": "phpunit/php-invoker", - "version": "3.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "62f696ad0d140e0e513e69eaafdebb674d622b4c" + "reference": "f6eedfed1085dd1f4c599629459a0277d25f9a66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/62f696ad0d140e0e513e69eaafdebb674d622b4c", - "reference": "62f696ad0d140e0e513e69eaafdebb674d622b4c", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f6eedfed1085dd1f4c599629459a0277d25f9a66", + "reference": "f6eedfed1085dd1f4c599629459a0277d25f9a66", "shasum": "" }, "require": { - "php": "^7.3" + "php": "^7.3 || ^8.0" }, "require-dev": { "ext-pcntl": "*", @@ -1712,24 +1720,24 @@ "type": "github" } ], - "time": "2020-06-15T13:10:07+00:00" + "time": "2020-06-26T11:53:53+00:00" }, { "name": "phpunit/php-text-template", - "version": "2.0.1", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "0c69cbf965d5317ba33f24a352539f354a25db09" + "reference": "6ff9c8ea4d3212b88fcf74e25e516e2c51c99324" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c69cbf965d5317ba33f24a352539f354a25db09", - "reference": "0c69cbf965d5317ba33f24a352539f354a25db09", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/6ff9c8ea4d3212b88fcf74e25e516e2c51c99324", + "reference": "6ff9c8ea4d3212b88fcf74e25e516e2c51c99324", "shasum": "" }, "require": { - "php": "^7.3" + "php": "^7.3 || ^8.0" }, "require-dev": { "phpunit/phpunit": "^9.0" @@ -1767,24 +1775,24 @@ "type": "github" } ], - "time": "2020-06-15T12:52:43+00:00" + "time": "2020-06-26T11:55:37+00:00" }, { "name": "phpunit/php-timer", - "version": "5.0.0", + "version": "5.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "b0d089de001ba60ffa3be36b23e1b8150d072238" + "reference": "cc49734779cbb302bf51a44297dab8c4bbf941e7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/b0d089de001ba60ffa3be36b23e1b8150d072238", - "reference": "b0d089de001ba60ffa3be36b23e1b8150d072238", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/cc49734779cbb302bf51a44297dab8c4bbf941e7", + "reference": "cc49734779cbb302bf51a44297dab8c4bbf941e7", "shasum": "" }, "require": { - "php": "^7.3" + "php": "^7.3 || ^8.0" }, "require-dev": { "phpunit/phpunit": "^9.2" @@ -1822,25 +1830,25 @@ "type": "github" } ], - "time": "2020-06-07T12:05:53+00:00" + "time": "2020-06-26T11:58:13+00:00" }, { "name": "phpunit/php-token-stream", - "version": "4.0.2", + "version": "4.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "e61c593e9734b47ef462340c24fca8d6a57da14e" + "reference": "5672711b6b07b14d5ab694e700c62eeb82fcf374" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e61c593e9734b47ef462340c24fca8d6a57da14e", - "reference": "e61c593e9734b47ef462340c24fca8d6a57da14e", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/5672711b6b07b14d5ab694e700c62eeb82fcf374", + "reference": "5672711b6b07b14d5ab694e700c62eeb82fcf374", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": "^7.3" + "php": "^7.3 || ^8.0" }, "require-dev": { "phpunit/phpunit": "^9.0" @@ -1877,50 +1885,50 @@ "type": "github" } ], - "time": "2020-06-16T07:00:44+00:00" + "time": "2020-06-27T06:36:25+00:00" }, { "name": "phpunit/phpunit", - "version": "9.2.3", + "version": "9.2.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "c1b1d62095ef78427f112a7a1c1502d4607e3c00" + "reference": "1c6a9e4312e209e659f1fce3ce88dd197c2448f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c1b1d62095ef78427f112a7a1c1502d4607e3c00", - "reference": "c1b1d62095ef78427f112a7a1c1502d4607e3c00", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1c6a9e4312e209e659f1fce3ce88dd197c2448f6", + "reference": "1c6a9e4312e209e659f1fce3ce88dd197c2448f6", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.2.0", + "doctrine/instantiator": "^1.3.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.9.1", + "myclabs/deep-copy": "^1.9.5", "phar-io/manifest": "^1.0.3", "phar-io/version": "^2.0.1", "php": "^7.3", - "phpspec/prophecy": "^1.8.1", - "phpunit/php-code-coverage": "^8.0.1", - "phpunit/php-file-iterator": "^3.0", - "phpunit/php-invoker": "^3.0", - "phpunit/php-text-template": "^2.0", - "phpunit/php-timer": "^5.0", - "sebastian/code-unit": "^1.0.2", - "sebastian/comparator": "^4.0", - "sebastian/diff": "^4.0", - "sebastian/environment": "^5.0.1", - "sebastian/exporter": "^4.0", + "phpspec/prophecy": "^1.10.3", + "phpunit/php-code-coverage": "^8.0.2", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-invoker": "^3.0.2", + "phpunit/php-text-template": "^2.0.2", + "phpunit/php-timer": "^5.0.1", + "sebastian/code-unit": "^1.0.5", + "sebastian/comparator": "^4.0.3", + "sebastian/diff": "^4.0.1", + "sebastian/environment": "^5.1.2", + "sebastian/exporter": "^4.0.2", "sebastian/global-state": "^4.0", - "sebastian/object-enumerator": "^4.0", - "sebastian/resource-operations": "^3.0", - "sebastian/type": "^2.1", - "sebastian/version": "^3.0" + "sebastian/object-enumerator": "^4.0.2", + "sebastian/resource-operations": "^3.0.2", + "sebastian/type": "^2.1.1", + "sebastian/version": "^3.0.1" }, "require-dev": { "ext-pdo": "*", @@ -1975,24 +1983,24 @@ "type": "github" } ], - "time": "2020-06-15T10:51:34+00:00" + "time": "2020-07-13T17:55:55+00:00" }, { "name": "sebastian/code-unit", - "version": "1.0.3", + "version": "1.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "d650ef9b1fece15ed4d6eaed6e6b469b7b81183a" + "reference": "c1e2df332c905079980b119c4db103117e5e5c90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/d650ef9b1fece15ed4d6eaed6e6b469b7b81183a", - "reference": "d650ef9b1fece15ed4d6eaed6e6b469b7b81183a", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/c1e2df332c905079980b119c4db103117e5e5c90", + "reference": "c1e2df332c905079980b119c4db103117e5e5c90", "shasum": "" }, "require": { - "php": "^7.3" + "php": "^7.3 || ^8.0" }, "require-dev": { "phpunit/phpunit": "^9.0" @@ -2027,24 +2035,24 @@ "type": "github" } ], - "time": "2020-06-15T13:11:26+00:00" + "time": "2020-06-26T12:50:45+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.1", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "c771130f0e8669104a4320b7101a81c2cc2963ef" + "reference": "ee51f9bb0c6d8a43337055db3120829fa14da819" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c771130f0e8669104a4320b7101a81c2cc2963ef", - "reference": "c771130f0e8669104a4320b7101a81c2cc2963ef", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ee51f9bb0c6d8a43337055db3120829fa14da819", + "reference": "ee51f9bb0c6d8a43337055db3120829fa14da819", "shasum": "" }, "require": { - "php": "^7.3" + "php": "^7.3 || ^8.0" }, "require-dev": { "phpunit/phpunit": "^9.0" @@ -2078,24 +2086,24 @@ "type": "github" } ], - "time": "2020-06-15T12:56:39+00:00" + "time": "2020-06-26T12:04:00+00:00" }, { "name": "sebastian/comparator", - "version": "4.0.2", + "version": "4.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "266d85ef789da8c41f06af4093c43e9798af2784" + "reference": "dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/266d85ef789da8c41f06af4093c43e9798af2784", - "reference": "266d85ef789da8c41f06af4093c43e9798af2784", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f", + "reference": "dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f", "shasum": "" }, "require": { - "php": "^7.3", + "php": "^7.3 || ^8.0", "sebastian/diff": "^4.0", "sebastian/exporter": "^4.0" }, @@ -2148,24 +2156,24 @@ "type": "github" } ], - "time": "2020-06-15T15:04:48+00:00" + "time": "2020-06-26T12:05:46+00:00" }, { "name": "sebastian/diff", - "version": "4.0.1", + "version": "4.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3e523c576f29dacecff309f35e4cc5a5c168e78a" + "reference": "1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3e523c576f29dacecff309f35e4cc5a5c168e78a", - "reference": "3e523c576f29dacecff309f35e4cc5a5c168e78a", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113", + "reference": "1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113", "shasum": "" }, "require": { - "php": "^7.3" + "php": "^7.3 || ^8.0" }, "require-dev": { "phpunit/phpunit": "^9.0", @@ -2210,24 +2218,24 @@ "type": "github" } ], - "time": "2020-05-08T05:01:12+00:00" + "time": "2020-06-30T04:46:02+00:00" }, { "name": "sebastian/environment", - "version": "5.1.1", + "version": "5.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "16eb0fa43e29c33d7f2117ed23072e26fc5ab34e" + "reference": "0a757cab9d5b7ef49a619f1143e6c9c1bc0fe9d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/16eb0fa43e29c33d7f2117ed23072e26fc5ab34e", - "reference": "16eb0fa43e29c33d7f2117ed23072e26fc5ab34e", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/0a757cab9d5b7ef49a619f1143e6c9c1bc0fe9d2", + "reference": "0a757cab9d5b7ef49a619f1143e6c9c1bc0fe9d2", "shasum": "" }, "require": { - "php": "^7.3" + "php": "^7.3 || ^8.0" }, "require-dev": { "phpunit/phpunit": "^9.0" @@ -2269,29 +2277,29 @@ "type": "github" } ], - "time": "2020-06-15T13:00:01+00:00" + "time": "2020-06-26T12:07:24+00:00" }, { "name": "sebastian/exporter", - "version": "4.0.1", + "version": "4.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "d12fbca85da932d01d941b59e4b71a0d559db091" + "reference": "571d721db4aec847a0e59690b954af33ebf9f023" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d12fbca85da932d01d941b59e4b71a0d559db091", - "reference": "d12fbca85da932d01d941b59e4b71a0d559db091", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/571d721db4aec847a0e59690b954af33ebf9f023", + "reference": "571d721db4aec847a0e59690b954af33ebf9f023", "shasum": "" }, "require": { - "php": "^7.3", + "php": "^7.3 || ^8.0", "sebastian/recursion-context": "^4.0" }, "require-dev": { "ext-mbstring": "*", - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.2" }, "type": "library", "extra": { @@ -2342,7 +2350,7 @@ "type": "github" } ], - "time": "2020-06-15T13:12:44+00:00" + "time": "2020-06-26T12:08:55+00:00" }, { "name": "sebastian/global-state", @@ -2400,20 +2408,20 @@ }, { "name": "sebastian/object-enumerator", - "version": "4.0.1", + "version": "4.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "15f319d67c49fc55ebcdbffb3377433125588455" + "reference": "074fed2d0a6d08e1677dd8ce9d32aecb384917b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/15f319d67c49fc55ebcdbffb3377433125588455", - "reference": "15f319d67c49fc55ebcdbffb3377433125588455", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/074fed2d0a6d08e1677dd8ce9d32aecb384917b8", + "reference": "074fed2d0a6d08e1677dd8ce9d32aecb384917b8", "shasum": "" }, "require": { - "php": "^7.3", + "php": "^7.3 || ^8.0", "sebastian/object-reflector": "^2.0", "sebastian/recursion-context": "^4.0" }, @@ -2449,24 +2457,24 @@ "type": "github" } ], - "time": "2020-06-15T13:15:25+00:00" + "time": "2020-06-26T12:11:32+00:00" }, { "name": "sebastian/object-reflector", - "version": "2.0.1", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "14e04b3c25b821cc0702d4837803fe497680b062" + "reference": "127a46f6b057441b201253526f81d5406d6c7840" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/14e04b3c25b821cc0702d4837803fe497680b062", - "reference": "14e04b3c25b821cc0702d4837803fe497680b062", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/127a46f6b057441b201253526f81d5406d6c7840", + "reference": "127a46f6b057441b201253526f81d5406d6c7840", "shasum": "" }, "require": { - "php": "^7.3" + "php": "^7.3 || ^8.0" }, "require-dev": { "phpunit/phpunit": "^9.0" @@ -2500,24 +2508,24 @@ "type": "github" } ], - "time": "2020-06-15T13:08:02+00:00" + "time": "2020-06-26T12:12:55+00:00" }, { "name": "sebastian/recursion-context", - "version": "4.0.1", + "version": "4.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "a32789e5f0157c10cf216ce6c5136db12a12b847" + "reference": "062231bf61d2b9448c4fa5a7643b5e1829c11d63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/a32789e5f0157c10cf216ce6c5136db12a12b847", - "reference": "a32789e5f0157c10cf216ce6c5136db12a12b847", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/062231bf61d2b9448c4fa5a7643b5e1829c11d63", + "reference": "062231bf61d2b9448c4fa5a7643b5e1829c11d63", "shasum": "" }, "require": { - "php": "^7.3" + "php": "^7.3 || ^8.0" }, "require-dev": { "phpunit/phpunit": "^9.0" @@ -2559,24 +2567,24 @@ "type": "github" } ], - "time": "2020-06-15T13:06:44+00:00" + "time": "2020-06-26T12:14:17+00:00" }, { "name": "sebastian/resource-operations", - "version": "3.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "71421c1745788de4facae1b79af923650bd3ec15" + "reference": "0653718a5a629b065e91f774595267f8dc32e213" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/71421c1745788de4facae1b79af923650bd3ec15", - "reference": "71421c1745788de4facae1b79af923650bd3ec15", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0653718a5a629b065e91f774595267f8dc32e213", + "reference": "0653718a5a629b065e91f774595267f8dc32e213", "shasum": "" }, "require": { - "php": "^7.3" + "php": "^7.3 || ^8.0" }, "require-dev": { "phpunit/phpunit": "^9.0" @@ -2610,24 +2618,24 @@ "type": "github" } ], - "time": "2020-06-15T13:17:14+00:00" + "time": "2020-06-26T12:16:22+00:00" }, { "name": "sebastian/type", - "version": "2.1.0", + "version": "2.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "bad49207c6f854e7a25cef0ea948ac8ebe3ef9d8" + "reference": "86991e2b33446cd96e648c18bcdb1e95afb2c05a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/bad49207c6f854e7a25cef0ea948ac8ebe3ef9d8", - "reference": "bad49207c6f854e7a25cef0ea948ac8ebe3ef9d8", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/86991e2b33446cd96e648c18bcdb1e95afb2c05a", + "reference": "86991e2b33446cd96e648c18bcdb1e95afb2c05a", "shasum": "" }, "require": { - "php": "^7.3" + "php": "^7.3 || ^8.0" }, "require-dev": { "phpunit/phpunit": "^9.2" @@ -2635,7 +2643,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } }, "autoload": { @@ -2662,24 +2670,24 @@ "type": "github" } ], - "time": "2020-06-01T12:21:09+00:00" + "time": "2020-07-05T08:31:53+00:00" }, { "name": "sebastian/version", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "0411bde656dce64202b39c2f4473993a9081d39e" + "reference": "626586115d0ed31cb71483be55beb759b5af5a3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/0411bde656dce64202b39c2f4473993a9081d39e", - "reference": "0411bde656dce64202b39c2f4473993a9081d39e", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/626586115d0ed31cb71483be55beb759b5af5a3c", + "reference": "626586115d0ed31cb71483be55beb759b5af5a3c", "shasum": "" }, "require": { - "php": "^7.3" + "php": "^7.3 || ^8.0" }, "type": "library", "extra": { @@ -2705,20 +2713,26 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2020-01-21T06:36:37+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-06-26T12:18:43+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.17.0", + "version": "v1.18.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9" + "reference": "1c302646f6efc070cd46856e600e5e0684d6b454" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e94c8b1bbe2bc77507a1056cdb06451c75b427f9", - "reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1c302646f6efc070cd46856e600e5e0684d6b454", + "reference": "1c302646f6efc070cd46856e600e5e0684d6b454", "shasum": "" }, "require": { @@ -2730,7 +2744,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.17-dev" + "dev-master": "1.18-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -2763,27 +2781,41 @@ "polyfill", "portable" ], - "time": "2020-05-12T16:14:59+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-07-14T12:35:20+00:00" }, { "name": "theseer/tokenizer", - "version": "1.1.3", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9" + "reference": "75a63c33a8577608444246075ea0af0d052e452a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9", - "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", + "reference": "75a63c33a8577608444246075ea0af0d052e452a", "shasum": "" }, "require": { "ext-dom": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", - "php": "^7.0" + "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { @@ -2803,24 +2835,30 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2019-06-13T22:48:21+00:00" + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2020-07-12T23:59:07+00:00" }, { "name": "webmozart/assert", - "version": "1.9.0", + "version": "1.9.1", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "9dc4f203e36f2b486149058bade43c851dd97451" + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/9dc4f203e36f2b486149058bade43c851dd97451", - "reference": "9dc4f203e36f2b486149058bade43c851dd97451", + "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0", + "php": "^5.3.3 || ^7.0 || ^8.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { @@ -2852,7 +2890,7 @@ "check", "validate" ], - "time": "2020-06-16T10:16:42+00:00" + "time": "2020-07-08T17:02:28+00:00" } ], "aliases": [], From 92afad5e6fd12c583159b3842cc0e9a93d58038e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 21 Jul 2020 16:18:14 +0100 Subject: [PATCH 1800/3224] Updated RakLib to pmmp/RakLib@6fbccdb6a7cf47ebcb411803aa023cf688aae8c7 --- composer.lock | 8 ++++---- src/network/mcpe/raklib/RakLibInterface.php | 21 +++++++++++++-------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/composer.lock b/composer.lock index bc93f3c601..42932f3a8f 100644 --- a/composer.lock +++ b/composer.lock @@ -623,12 +623,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "31e2b2259404399cac7f50ae4a9bbdfdd8c1035e" + "reference": "6fbccdb6a7cf47ebcb411803aa023cf688aae8c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/31e2b2259404399cac7f50ae4a9bbdfdd8c1035e", - "reference": "31e2b2259404399cac7f50ae4a9bbdfdd8c1035e", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/6fbccdb6a7cf47ebcb411803aa023cf688aae8c7", + "reference": "6fbccdb6a7cf47ebcb411803aa023cf688aae8c7", "shasum": "" }, "require": { @@ -654,7 +654,7 @@ "GPL-3.0" ], "description": "A RakNet server implementation written in PHP", - "time": "2020-06-17T12:01:42+00:00" + "time": "2020-07-21T12:33:41+00:00" }, { "name": "pocketmine/snooze", diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 70f754b20c..63913b8591 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -43,6 +43,7 @@ use raklib\utils\InternetAddress; use function addcslashes; use function bin2hex; use function implode; +use function microtime; use function mt_rand; use function random_bytes; use function rtrim; @@ -82,9 +83,13 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ /** @var SleeperNotifier */ private $sleeper; + /** @var float */ + private $lastBandwidthReport; + public function __construct(Server $server){ $this->server = $server; $this->rakServerId = mt_rand(0, PHP_INT_MAX); + $this->lastBandwidthReport = microtime(true); $this->sleeper = new SleeperNotifier(); @@ -221,7 +226,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ public function setName(string $name) : void{ $info = $this->server->getQueryInformation(); - $this->interface->setOption("name", implode(";", + $this->interface->setName(implode(";", [ "MCPE", rtrim(addcslashes($name, ";"), '\\'), @@ -237,18 +242,18 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ } public function setPortCheck(bool $name) : void{ - $this->interface->setOption("portChecking", $name); + $this->interface->setPortCheck($name); } public function setPacketLimit(int $limit) : void{ - $this->interface->setOption("packetLimit", $limit); + $this->interface->setPacketsPerTickLimit($limit); } - public function handleOption(string $option, string $value) : void{ - if($option === "bandwidth"){ - $v = unserialize($value); - $this->network->addStatistics($v["up"], $v["down"]); - } + public function handleBandwidthStats(int $bytesSentDiff, int $bytesReceivedDiff) : void{ + $now = microtime(true); + $diff = $now - $this->lastBandwidthReport; + $this->lastBandwidthReport = $now; + $this->network->addStatistics($bytesSentDiff / $diff, $bytesReceivedDiff / $diff); } public function putPacket(int $sessionId, string $payload, bool $immediate = true) : void{ From bc52a3892224a6133b829fd83fd388be85cf0a6c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 21 Jul 2020 19:21:27 +0100 Subject: [PATCH 1801/3224] Improved network bandwidth data collection --- src/Server.php | 7 +- src/command/defaults/StatusCommand.php | 5 +- src/network/BandwidthStatsTracker.php | 74 +++++++++++++++++++ .../BidirectionalBandwidthStatsTracker.php | 59 +++++++++++++++ src/network/Network.php | 25 +------ src/network/mcpe/raklib/RakLibInterface.php | 10 +-- 6 files changed, 145 insertions(+), 35 deletions(-) create mode 100644 src/network/BandwidthStatsTracker.php create mode 100644 src/network/BidirectionalBandwidthStatsTracker.php diff --git a/src/Server.php b/src/Server.php index 3fad9f6f78..fd71837151 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1587,14 +1587,15 @@ class Server{ $online = count($this->playerList); $connecting = $this->network->getConnectionCount() - $online; + $bandwidthStats = $this->network->getBandwidthTracker(); echo "\x1b]0;" . $this->getName() . " " . $this->getPocketMineVersion() . " | Online $online/" . $this->getMaxPlayers() . ($connecting > 0 ? " (+$connecting connecting)" : "") . " | Memory " . $usage . - " | U " . round($this->network->getUpload() / 1024, 2) . - " D " . round($this->network->getDownload() / 1024, 2) . + " | U " . round($bandwidthStats->getSend()->getAverageBytes() / 1024, 2) . + " D " . round($bandwidthStats->getReceive()->getAverageBytes() / 1024, 2) . " kB/s | TPS " . $this->getTicksPerSecondAverage() . " | Load " . $this->getTickUsageAverage() . "%\x07"; @@ -1640,7 +1641,7 @@ class Server{ $this->queryInfo = $queryRegenerateEvent->getQueryInfo(); $this->network->updateName(); - $this->network->resetStatistics(); + $this->network->getBandwidthTracker()->rotateAverageHistory(); } if($this->sendUsageTicker > 0 and --$this->sendUsageTicker === 0){ diff --git a/src/command/defaults/StatusCommand.php b/src/command/defaults/StatusCommand.php index 8c8d71af89..f0c7911923 100644 --- a/src/command/defaults/StatusCommand.php +++ b/src/command/defaults/StatusCommand.php @@ -91,8 +91,9 @@ class StatusCommand extends VanillaCommand{ $sender->sendMessage(TextFormat::GOLD . "Current TPS: {$tpsColor}{$server->getTicksPerSecond()} ({$server->getTickUsage()}%)"); $sender->sendMessage(TextFormat::GOLD . "Average TPS: {$tpsColor}{$server->getTicksPerSecondAverage()} ({$server->getTickUsageAverage()}%)"); - $sender->sendMessage(TextFormat::GOLD . "Network upload: " . TextFormat::RED . round($server->getNetwork()->getUpload() / 1024, 2) . " kB/s"); - $sender->sendMessage(TextFormat::GOLD . "Network download: " . TextFormat::RED . round($server->getNetwork()->getDownload() / 1024, 2) . " kB/s"); + $bandwidth = $server->getNetwork()->getBandwidthTracker(); + $sender->sendMessage(TextFormat::GOLD . "Network upload: " . TextFormat::RED . round($bandwidth->getSend()->getAverageBytes() / 1024, 2) . " kB/s"); + $sender->sendMessage(TextFormat::GOLD . "Network download: " . TextFormat::RED . round($bandwidth->getReceive()->getAverageBytes() / 1024, 2) . " kB/s"); $sender->sendMessage(TextFormat::GOLD . "Thread count: " . TextFormat::RED . Process::getThreadCount()); diff --git a/src/network/BandwidthStatsTracker.php b/src/network/BandwidthStatsTracker.php new file mode 100644 index 0000000000..0f0358dd19 --- /dev/null +++ b/src/network/BandwidthStatsTracker.php @@ -0,0 +1,74 @@ +history = array_fill(0, $historySize, 0); + } + + public function add(int $bytes) : void{ + $this->totalBytes += $bytes; + $this->bytesSinceLastRotation += $bytes; + } + + public function getTotalBytes() : int{ return $this->totalBytes; } + + /** + * Adds the bytes tracked since the last rotation to the history array, overwriting an old entry. + * This should be called on a regular interval that you want to collect average measurements over + * (e.g. if you want bytes per second, call this every second). + */ + public function rotateHistory() : void{ + $this->history[$this->nextHistoryIndex] = $this->bytesSinceLastRotation; + $this->bytesSinceLastRotation = 0; + $this->nextHistoryIndex = ($this->nextHistoryIndex + 1) % count($this->history); + } + + /** + * Returns the average of all the tracked history values. + */ + public function getAverageBytes() : float{ + return array_sum($this->history) / count($this->history); + } + + public function resetHistory() : void{ + $this->history = array_fill(0, count($this->history), 0); + } +} diff --git a/src/network/BidirectionalBandwidthStatsTracker.php b/src/network/BidirectionalBandwidthStatsTracker.php new file mode 100644 index 0000000000..a4cf3f6a49 --- /dev/null +++ b/src/network/BidirectionalBandwidthStatsTracker.php @@ -0,0 +1,59 @@ +send = new BandwidthStatsTracker($historySize); + $this->receive = new BandwidthStatsTracker($historySize); + } + + public function getSend() : BandwidthStatsTracker{ return $this->send; } + + public function getReceive() : BandwidthStatsTracker{ return $this->receive; } + + public function add(int $sendBytes, int $recvBytes) : void{ + $this->send->add($sendBytes); + $this->receive->add($recvBytes); + } + + /** @see BandwidthStatsTracker::rotateHistory() */ + public function rotateAverageHistory() : void{ + $this->send->rotateHistory(); + $this->receive->rotateHistory(); + } + + /** @see BandwidthStatsTracker::resetHistory() */ + public function resetHistory() : void{ + $this->send->resetHistory(); + $this->receive->resetHistory(); + } +} diff --git a/src/network/Network.php b/src/network/Network.php index 2f671df3ca..24944dcd51 100644 --- a/src/network/Network.php +++ b/src/network/Network.php @@ -48,10 +48,8 @@ class Network{ /** @var int[] */ private $bannedIps = []; - /** @var float */ - private $upload = 0; - /** @var float */ - private $download = 0; + /** @var BandwidthStatsTracker */ + private $bandwidthTracker; /** @var string */ private $name; @@ -65,25 +63,10 @@ class Network{ public function __construct(\Logger $logger){ $this->sessionManager = new NetworkSessionManager(); $this->logger = $logger; + $this->bandwidthTracker = new BidirectionalBandwidthStatsTracker(5); } - public function addStatistics(float $upload, float $download) : void{ - $this->upload += $upload; - $this->download += $download; - } - - public function getUpload() : float{ - return $this->upload; - } - - public function getDownload() : float{ - return $this->download; - } - - public function resetStatistics() : void{ - $this->upload = 0; - $this->download = 0; - } + public function getBandwidthTracker() : BidirectionalBandwidthStatsTracker{ return $this->bandwidthTracker; } /** * @return NetworkInterface[] diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 63913b8591..459ae94b77 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -43,7 +43,6 @@ use raklib\utils\InternetAddress; use function addcslashes; use function bin2hex; use function implode; -use function microtime; use function mt_rand; use function random_bytes; use function rtrim; @@ -83,13 +82,9 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ /** @var SleeperNotifier */ private $sleeper; - /** @var float */ - private $lastBandwidthReport; - public function __construct(Server $server){ $this->server = $server; $this->rakServerId = mt_rand(0, PHP_INT_MAX); - $this->lastBandwidthReport = microtime(true); $this->sleeper = new SleeperNotifier(); @@ -250,10 +245,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ } public function handleBandwidthStats(int $bytesSentDiff, int $bytesReceivedDiff) : void{ - $now = microtime(true); - $diff = $now - $this->lastBandwidthReport; - $this->lastBandwidthReport = $now; - $this->network->addStatistics($bytesSentDiff / $diff, $bytesReceivedDiff / $diff); + $this->network->getBandwidthTracker()->add($bytesSentDiff, $bytesReceivedDiff); } public function putPacket(int $sessionId, string $payload, bool $immediate = true) : void{ From 93e6d7e1a245832c682c25b2614593c87993de91 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 21 Jul 2020 19:23:30 +0100 Subject: [PATCH 1802/3224] thanks for nothing phpstorm --- src/network/Network.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/Network.php b/src/network/Network.php index 24944dcd51..5bfbd3c026 100644 --- a/src/network/Network.php +++ b/src/network/Network.php @@ -48,7 +48,7 @@ class Network{ /** @var int[] */ private $bannedIps = []; - /** @var BandwidthStatsTracker */ + /** @var BidirectionalBandwidthStatsTracker */ private $bandwidthTracker; /** @var string */ From ed144a17096d002a8ef88fe2708cc042a8d1698c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 21 Jul 2020 19:29:12 +0100 Subject: [PATCH 1803/3224] remove unused imports --- src/network/mcpe/raklib/RakLibInterface.php | 1 - src/player/Player.php | 1 - 2 files changed, 2 deletions(-) diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 459ae94b77..43547c91f7 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -47,7 +47,6 @@ use function mt_rand; use function random_bytes; use function rtrim; use function substr; -use function unserialize; use const PTHREADS_INHERIT_CONSTANTS; class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ diff --git a/src/player/Player.php b/src/player/Player.php index ece67dcc7f..f018f6b746 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -102,7 +102,6 @@ use pocketmine\utils\TextFormat; use pocketmine\uuid\UUID; use pocketmine\world\ChunkListener; use pocketmine\world\ChunkListenerNoOpTrait; -use pocketmine\world\ChunkLoader; use pocketmine\world\format\Chunk; use pocketmine\world\Position; use pocketmine\world\sound\EntityAttackNoDamageSound; From 2fcee432c1eab4d49690b14fec0dfe086cf5c20e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 22 Jul 2020 15:18:01 +0100 Subject: [PATCH 1804/3224] NetworkSession: store Packet[] for buffering instead of PacketBatch this reduces memory allocations for buffering (in theory). --- src/network/mcpe/NetworkSession.php | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 56768ef2a8..71832e7fcf 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -151,8 +151,8 @@ class NetworkSession{ /** @var EncryptionContext */ private $cipher; - /** @var PacketBatch|null */ - private $sendBuffer; + /** @var Packet[] */ + private $sendBuffer = []; /** * @var \SplQueue|CompressBatchPromise[] @@ -416,10 +416,7 @@ class NetworkSession{ $timings = Timings::getSendDataPacketTimings($packet); $timings->startTiming(); try{ - if($this->sendBuffer === null){ - $this->sendBuffer = new PacketBatch(); - } - $this->sendBuffer->putPacket($packet); + $this->sendBuffer[] = $packet; $this->manager->scheduleUpdate($this); //schedule flush at end of tick }finally{ $timings->stopTiming(); @@ -427,9 +424,9 @@ class NetworkSession{ } private function flushSendBuffer(bool $immediate = false) : void{ - if($this->sendBuffer !== null){ - $promise = $this->server->prepareBatch($this->sendBuffer, $this->compressor, $immediate); - $this->sendBuffer = null; + if(count($this->sendBuffer) > 0){ + $promise = $this->server->prepareBatch(PacketBatch::fromPackets(...$this->sendBuffer), $this->compressor, $immediate); + $this->sendBuffer = []; $this->queueCompressed($promise, $immediate); } } @@ -944,9 +941,7 @@ class NetworkSession{ return true; //keep ticking until timeout } - if($this->sendBuffer !== null){ - $this->flushSendBuffer(); - } + $this->flushSendBuffer(); return false; } From 798efc370cec1283fdbee26fc2a2655dd8654a99 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 22 Jul 2020 15:24:08 +0100 Subject: [PATCH 1805/3224] PacketBatch: get rid of putPacket() --- .../mcpe/protocol/serializer/PacketBatch.php | 8 ++------ .../mcpe/protocol/serializer/PacketBatchTest.php | 14 ++++---------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/src/network/mcpe/protocol/serializer/PacketBatch.php b/src/network/mcpe/protocol/serializer/PacketBatch.php index 98a41fd048..3e2e277a92 100644 --- a/src/network/mcpe/protocol/serializer/PacketBatch.php +++ b/src/network/mcpe/protocol/serializer/PacketBatch.php @@ -37,11 +37,6 @@ class PacketBatch{ $this->serializer = new PacketSerializer($buffer ?? ""); } - public function putPacket(Packet $packet) : void{ - $packet->encode(); - $this->serializer->putString($packet->getSerializer()->getBuffer()); - } - /** * @throws BinaryDataException */ @@ -72,7 +67,8 @@ class PacketBatch{ public static function fromPackets(Packet ...$packets) : self{ $result = new self(); foreach($packets as $packet){ - $result->putPacket($packet); + $packet->encode(); + $result->serializer->putString($packet->getSerializer()->getBuffer()); } return $result; } diff --git a/tests/phpunit/network/mcpe/protocol/serializer/PacketBatchTest.php b/tests/phpunit/network/mcpe/protocol/serializer/PacketBatchTest.php index 217914d319..28d01dc8c3 100644 --- a/tests/phpunit/network/mcpe/protocol/serializer/PacketBatchTest.php +++ b/tests/phpunit/network/mcpe/protocol/serializer/PacketBatchTest.php @@ -23,21 +23,18 @@ declare(strict_types=1); namespace pocketmine\mcpe\protocol\serializer; -use pocketmine\network\mcpe\protocol\Packet; +use PHPUnit\Framework\TestCase; use pocketmine\network\mcpe\protocol\PacketDecodeException; use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; -use PHPUnit\Framework\TestCase; use pocketmine\network\mcpe\protocol\TestPacket; +use function array_fill; class PacketBatchTest extends TestCase{ public function testDecodeTooBig() : void{ $limit = 10; - $write = new PacketBatch(); - for($i = 0; $i < $limit + 1; $i++){ - $write->putPacket(new TestPacket()); - } + $write = PacketBatch::fromPackets(...array_fill(0, $limit + 1, new TestPacket())); $read = new PacketBatch($write->getBuffer()); $this->expectException(PacketDecodeException::class); $readCount = 0; @@ -48,10 +45,7 @@ class PacketBatchTest extends TestCase{ public function testDecodeAtLimit() : void{ $limit = 10; - $write = new PacketBatch(); - for($i = 0; $i < $limit; $i++){ - $write->putPacket(new TestPacket()); - } + $write = PacketBatch::fromPackets(...array_fill(0, $limit, new TestPacket())); $read = new PacketBatch($write->getBuffer()); $readCount = 0; foreach($read->getPackets(PacketPool::getInstance(), $limit) as $packet){ From 8402465fd2a40fdba219f924ec48fbbf5336c620 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 22 Jul 2020 15:37:06 +0100 Subject: [PATCH 1806/3224] PacketBatch is now immutable --- .../mcpe/protocol/serializer/PacketBatch.php | 34 +++++++------------ 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/network/mcpe/protocol/serializer/PacketBatch.php b/src/network/mcpe/protocol/serializer/PacketBatch.php index 3e2e277a92..3e1c9c213e 100644 --- a/src/network/mcpe/protocol/serializer/PacketBatch.php +++ b/src/network/mcpe/protocol/serializer/PacketBatch.php @@ -30,18 +30,11 @@ use pocketmine\utils\BinaryDataException; class PacketBatch{ - /** @var PacketSerializer */ - private $serializer; + /** @var string */ + private $buffer; - public function __construct(?string $buffer = null){ - $this->serializer = new PacketSerializer($buffer ?? ""); - } - - /** - * @throws BinaryDataException - */ - public function getPacket(PacketPool $packetPool) : Packet{ - return $packetPool->getPacket($this->serializer->getString()); + public function __construct(string $buffer){ + $this->buffer = $buffer; } /** @@ -49,10 +42,11 @@ class PacketBatch{ * @phpstan-return \Generator */ public function getPackets(PacketPool $packetPool, int $max) : \Generator{ - for($c = 0; $c < $max and !$this->serializer->feof(); ++$c){ - yield $c => $packetPool->getPacket($this->serializer->getString()); + $serializer = new PacketSerializer($this->buffer); + for($c = 0; $c < $max and !$serializer->feof(); ++$c){ + yield $c => $packetPool->getPacket($serializer->getString()); } - if(!$this->serializer->feof()){ + if(!$serializer->feof()){ throw new PacketDecodeException("Reached limit of $max packets in a single batch"); } } @@ -65,19 +59,15 @@ class PacketBatch{ * @return PacketBatch */ public static function fromPackets(Packet ...$packets) : self{ - $result = new self(); + $serializer = new PacketSerializer(); foreach($packets as $packet){ $packet->encode(); - $result->serializer->putString($packet->getSerializer()->getBuffer()); + $serializer->putString($packet->getSerializer()->getBuffer()); } - return $result; + return new self($serializer->getBuffer()); } public function getBuffer() : string{ - return $this->serializer->getBuffer(); - } - - public function feof() : bool{ - return $this->serializer->feof(); + return $this->buffer; } } From 5910905e954f98fd1b1d24190ca26aa727a54a1d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 22 Jul 2020 15:38:24 +0100 Subject: [PATCH 1807/3224] PacketBatch::getPackets() may throw PacketDecodeException --- src/network/mcpe/protocol/serializer/PacketBatch.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/mcpe/protocol/serializer/PacketBatch.php b/src/network/mcpe/protocol/serializer/PacketBatch.php index 3e1c9c213e..1192103758 100644 --- a/src/network/mcpe/protocol/serializer/PacketBatch.php +++ b/src/network/mcpe/protocol/serializer/PacketBatch.php @@ -40,6 +40,7 @@ class PacketBatch{ /** * @return \Generator|Packet[] * @phpstan-return \Generator + * @throws PacketDecodeException */ public function getPackets(PacketPool $packetPool, int $max) : \Generator{ $serializer = new PacketSerializer($this->buffer); From 2645b196178309627c30f6eb63bb0b8d924a7e7e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 25 Jul 2020 19:00:48 +0100 Subject: [PATCH 1808/3224] Convert VersionInfo into a final class this allows it to be loaded by the autoloader without additional changes. --- build/make-release.php | 12 ++++++------ composer.json | 3 +-- phpstan.neon.dist | 2 +- src/CrashDump.php | 8 ++++---- src/PocketMine.php | 4 ++-- src/Server.php | 18 +++++++++--------- src/VersionInfo.php | 19 ++++++++----------- src/stats/SendUsageTask.php | 3 ++- src/updater/AutoUpdater.php | 7 ++++--- src/utils/Internet.php | 3 ++- src/wizard/SetupWizard.php | 11 ++++++----- 11 files changed, 45 insertions(+), 45 deletions(-) diff --git a/build/make-release.php b/build/make-release.php index eed343d89b..a89b22383b 100644 --- a/build/make-release.php +++ b/build/make-release.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\build\make_release; use pocketmine\utils\VersionString; +use pocketmine\VersionInfo; use function dirname; use function fgets; use function file_get_contents; @@ -32,7 +33,6 @@ use function preg_replace; use function sleep; use function sprintf; use function system; -use const pocketmine\BASE_VERSION; use const STDIN; require_once dirname(__DIR__) . '/vendor/autoload.php'; @@ -41,13 +41,13 @@ require_once dirname(__DIR__) . '/vendor/autoload.php'; function replaceVersion(string $versionInfoPath, string $newVersion, bool $isDev) : void{ $versionInfo = file_get_contents($versionInfoPath); $versionInfo = preg_replace( - $pattern = '/^const BASE_VERSION = "(\d+)\.(\d+)\.(\d+)(?:-(.*))?";$/m', - 'const BASE_VERSION = "' . $newVersion . '";', + $pattern = '/^([\t ]*public )?const BASE_VERSION = "(\d+)\.(\d+)\.(\d+)(?:-(.*))?";$/m', + '$1const BASE_VERSION = "' . $newVersion . '";', $versionInfo ); $versionInfo = preg_replace( - '/^const IS_DEVELOPMENT_BUILD = (?:true|false);$/m', - 'const IS_DEVELOPMENT_BUILD = ' . ($isDev ? 'true' : 'false') . ';', + '/^([\t ]*public )?const IS_DEVELOPMENT_BUILD = (?:true|false);$/m', + '$1const IS_DEVELOPMENT_BUILD = ' . ($isDev ? 'true' : 'false') . ';', $versionInfo ); file_put_contents($versionInfoPath, $versionInfo); @@ -61,7 +61,7 @@ function main(array $argv) : void{ if(isset($argv[1])){ $currentVer = new VersionString($argv[1]); }else{ - $currentVer = new VersionString(BASE_VERSION); + $currentVer = new VersionString(VersionInfo::BASE_VERSION); } $nextVer = new VersionString(sprintf( "%u.%u.%u", diff --git a/composer.json b/composer.json index a00691351a..2facf10184 100644 --- a/composer.json +++ b/composer.json @@ -60,8 +60,7 @@ "pocketmine\\": "src/" }, "files": [ - "src/CoreConstants.php", - "src/VersionInfo.php" + "src/CoreConstants.php" ] }, "autoload-dev": { diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 75f06d92ed..3f7c79404c 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -35,7 +35,7 @@ parameters: - build/server-phar.php - tests/phpunit dynamicConstantNames: - - pocketmine\IS_DEVELOPMENT_BUILD + - pocketmine\VersionInfo::IS_DEVELOPMENT_BUILD - pocketmine\DEBUG stubFiles: - tests/phpstan/stubs/JsonMapper.stub diff --git a/src/CrashDump.php b/src/CrashDump.php index 469b3e4b88..adea192f96 100644 --- a/src/CrashDump.php +++ b/src/CrashDump.php @@ -308,12 +308,12 @@ class CrashDump{ } private function generalData() : void{ - $version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER); + $version = new VersionString(VersionInfo::BASE_VERSION, VersionInfo::IS_DEVELOPMENT_BUILD, VersionInfo::BUILD_NUMBER); $this->data["general"] = []; $this->data["general"]["name"] = $this->server->getName(); - $this->data["general"]["base_version"] = \pocketmine\BASE_VERSION; - $this->data["general"]["build"] = \pocketmine\BUILD_NUMBER; - $this->data["general"]["is_dev"] = \pocketmine\IS_DEVELOPMENT_BUILD; + $this->data["general"]["base_version"] = VersionInfo::BASE_VERSION; + $this->data["general"]["build"] = VersionInfo::BUILD_NUMBER; + $this->data["general"]["is_dev"] = VersionInfo::IS_DEVELOPMENT_BUILD; $this->data["general"]["protocol"] = ProtocolInfo::CURRENT_PROTOCOL; $this->data["general"]["git"] = \pocketmine\GIT_COMMIT; $this->data["general"]["uname"] = php_uname("a"); diff --git a/src/PocketMine.php b/src/PocketMine.php index 530815eb68..78c3f6cda7 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -197,7 +197,7 @@ namespace pocketmine { ErrorToExceptionHandler::set(); - $version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER); + $version = new VersionString(VersionInfo::BASE_VERSION, VersionInfo::IS_DEVELOPMENT_BUILD, VersionInfo::BUILD_NUMBER); define('pocketmine\VERSION', $version->getFullVersion(true)); $gitHash = str_repeat("00", 20); @@ -225,7 +225,7 @@ namespace pocketmine { $lockFilePath = $dataPath . '/server.lock'; if(($pid = Filesystem::createLockFile($lockFilePath)) !== null){ - critical_error("Another " . \pocketmine\NAME . " instance (PID $pid) is already using this folder (" . realpath($dataPath) . ")."); + critical_error("Another " . VersionInfo::NAME . " instance (PID $pid) is already using this folder (" . realpath($dataPath) . ")."); critical_error("Please stop the other server first before running a new one."); exit(1); } diff --git a/src/Server.php b/src/Server.php index fd71837151..e4e025b9ec 100644 --- a/src/Server.php +++ b/src/Server.php @@ -280,7 +280,7 @@ class Server{ private $playerList = []; public function getName() : string{ - return \pocketmine\NAME; + return VersionInfo::NAME; } public function isRunning() : bool{ @@ -296,7 +296,7 @@ class Server{ } public function getApiVersion() : string{ - return \pocketmine\BASE_VERSION; + return VersionInfo::BASE_VERSION; } public function getFilePath() : string{ @@ -385,7 +385,7 @@ class Server{ } public function getMotd() : string{ - return $this->configGroup->getConfigString("motd", \pocketmine\NAME . " Server"); + return $this->configGroup->getConfigString("motd", VersionInfo::NAME . " Server"); } /** @@ -778,7 +778,7 @@ class Server{ $this->logger->info("Loading server configuration"); if(!file_exists($this->dataPath . "pocketmine.yml")){ $content = file_get_contents(\pocketmine\RESOURCE_PATH . "pocketmine.yml"); - if(\pocketmine\IS_DEVELOPMENT_BUILD){ + if(VersionInfo::IS_DEVELOPMENT_BUILD){ $content = str_replace("preferred-channel: stable", "preferred-channel: beta", $content); } @file_put_contents($this->dataPath . "pocketmine.yml", $content); @@ -787,7 +787,7 @@ class Server{ $this->configGroup = new ServerConfigGroup( new Config($this->dataPath . "pocketmine.yml", Config::YAML, []), new Config($this->dataPath . "server.properties", Config::PROPERTIES, [ - "motd" => \pocketmine\NAME . " Server", + "motd" => VersionInfo::NAME . " Server", "server-port" => 19132, "white-list" => false, "max-players" => 20, @@ -829,9 +829,9 @@ class Server{ $this->logger->info($this->getLanguage()->translateString("language.selected", [$this->getLanguage()->getName(), $this->getLanguage()->getLang()])); - if(\pocketmine\IS_DEVELOPMENT_BUILD){ + if(VersionInfo::IS_DEVELOPMENT_BUILD){ if(!((bool) $this->configGroup->getProperty("settings.enable-dev-builds", false))){ - $this->logger->emergency($this->language->translateString("pocketmine.server.devBuild.error1", [\pocketmine\NAME])); + $this->logger->emergency($this->language->translateString("pocketmine.server.devBuild.error1", [VersionInfo::NAME])); $this->logger->emergency($this->language->translateString("pocketmine.server.devBuild.error2")); $this->logger->emergency($this->language->translateString("pocketmine.server.devBuild.error3")); $this->logger->emergency($this->language->translateString("pocketmine.server.devBuild.error4", ["settings.enable-dev-builds"])); @@ -842,7 +842,7 @@ class Server{ } $this->logger->warning(str_repeat("-", 40)); - $this->logger->warning($this->language->translateString("pocketmine.server.devBuild.warning1", [\pocketmine\NAME])); + $this->logger->warning($this->language->translateString("pocketmine.server.devBuild.warning1", [VersionInfo::NAME])); $this->logger->warning($this->language->translateString("pocketmine.server.devBuild.warning2")); $this->logger->warning($this->language->translateString("pocketmine.server.devBuild.warning3")); $this->logger->warning(str_repeat("-", 40)); @@ -923,7 +923,7 @@ class Server{ $this->logger->info($this->getLanguage()->translateString("pocketmine.server.info", [ $this->getName(), - (\pocketmine\IS_DEVELOPMENT_BUILD ? TextFormat::YELLOW : "") . $this->getPocketMineVersion() . TextFormat::RESET + (VersionInfo::IS_DEVELOPMENT_BUILD ? TextFormat::YELLOW : "") . $this->getPocketMineVersion() . TextFormat::RESET ])); $this->logger->info($this->getLanguage()->translateString("pocketmine.server.license", [$this->getName()])); diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 4a8f59fb74..67ac227acc 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -23,16 +23,13 @@ declare(strict_types=1); namespace pocketmine; -use function defined; +final class VersionInfo{ + public const NAME = "PocketMine-MP"; + public const BASE_VERSION = "4.0.0"; + public const IS_DEVELOPMENT_BUILD = true; + public const BUILD_NUMBER = 0; -// composer autoload doesn't use require_once and also pthreads can inherit things -// TODO: drop this file and use a final class with constants -if(defined('pocketmine\_VERSION_INFO_INCLUDED')){ - return; + private function __construct(){ + //NOOP + } } -const _VERSION_INFO_INCLUDED = true; - -const NAME = "PocketMine-MP"; -const BASE_VERSION = "4.0.0"; -const IS_DEVELOPMENT_BUILD = true; -const BUILD_NUMBER = 0; diff --git a/src/stats/SendUsageTask.php b/src/stats/SendUsageTask.php index b88e517b43..15753ff52c 100644 --- a/src/stats/SendUsageTask.php +++ b/src/stats/SendUsageTask.php @@ -33,6 +33,7 @@ use pocketmine\utils\Process; use pocketmine\utils\Utils; use pocketmine\utils\VersionString; use pocketmine\uuid\UUID; +use pocketmine\VersionInfo; use function array_map; use function array_values; use function count; @@ -71,7 +72,7 @@ class SendUsageTask extends AsyncTask{ case self::TYPE_OPEN: $data["event"] = "open"; - $version = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER); + $version = new VersionString(VersionInfo::BASE_VERSION, VersionInfo::IS_DEVELOPMENT_BUILD, VersionInfo::BUILD_NUMBER); $data["server"] = [ "port" => $server->getPort(), diff --git a/src/updater/AutoUpdater.php b/src/updater/AutoUpdater.php index 662dc3d778..51497ee33f 100644 --- a/src/updater/AutoUpdater.php +++ b/src/updater/AutoUpdater.php @@ -28,6 +28,7 @@ use pocketmine\player\Player; use pocketmine\Server; use pocketmine\utils\TextFormat; use pocketmine\utils\VersionString; +use pocketmine\VersionInfo; use function date; use function sprintf; use function str_repeat; @@ -75,9 +76,9 @@ class AutoUpdater{ $this->showConsoleUpdate(); } }else{ - if(!\pocketmine\IS_DEVELOPMENT_BUILD and $this->getChannel() !== "stable"){ + if(!VersionInfo::IS_DEVELOPMENT_BUILD and $this->getChannel() !== "stable"){ $this->showChannelSuggestionStable(); - }elseif(\pocketmine\IS_DEVELOPMENT_BUILD and $this->getChannel() === "stable"){ + }elseif(VersionInfo::IS_DEVELOPMENT_BUILD and $this->getChannel() === "stable"){ $this->showChannelSuggestionBeta(); } } @@ -159,7 +160,7 @@ class AutoUpdater{ if($this->updateInfo === null){ return; } - $currentVersion = new VersionString(\pocketmine\BASE_VERSION, \pocketmine\IS_DEVELOPMENT_BUILD, \pocketmine\BUILD_NUMBER); + $currentVersion = new VersionString(VersionInfo::BASE_VERSION, VersionInfo::IS_DEVELOPMENT_BUILD, VersionInfo::BUILD_NUMBER); try{ $newVersion = new VersionString($this->updateInfo->base_version, $this->updateInfo->is_dev, $this->updateInfo->build); }catch(\InvalidArgumentException $e){ diff --git a/src/utils/Internet.php b/src/utils/Internet.php index 1fba58924a..de66a8a318 100644 --- a/src/utils/Internet.php +++ b/src/utils/Internet.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\utils; +use pocketmine\VersionInfo; use function array_merge; use function curl_close; use function curl_error; @@ -223,7 +224,7 @@ class Internet{ CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT_MS => (int) ($timeout * 1000), CURLOPT_TIMEOUT_MS => (int) ($timeout * 1000), - CURLOPT_HTTPHEADER => array_merge(["User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0 " . \pocketmine\NAME . "/" . \pocketmine\VERSION], $extraHeaders), + CURLOPT_HTTPHEADER => array_merge(["User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0 " . VersionInfo::NAME . "/" . \pocketmine\VERSION], $extraHeaders), CURLOPT_HEADER => true ]); try{ diff --git a/src/wizard/SetupWizard.php b/src/wizard/SetupWizard.php index 66862b9f99..1fb63b3de9 100644 --- a/src/wizard/SetupWizard.php +++ b/src/wizard/SetupWizard.php @@ -33,6 +33,7 @@ use pocketmine\player\GameMode; use pocketmine\utils\Config; use pocketmine\utils\Internet; use pocketmine\utils\InternetException; +use pocketmine\VersionInfo; use function fgets; use function sleep; use function strtolower; @@ -41,7 +42,7 @@ use const PHP_EOL; use const STDIN; class SetupWizard{ - public const DEFAULT_NAME = \pocketmine\NAME . " Server"; + public const DEFAULT_NAME = VersionInfo::NAME . " Server"; public const DEFAULT_PORT = 19132; public const DEFAULT_PLAYERS = 20; @@ -55,7 +56,7 @@ class SetupWizard{ } public function run() : bool{ - $this->message(\pocketmine\NAME . " set-up wizard"); + $this->message(VersionInfo::NAME . " set-up wizard"); try{ $langs = Language::getLanguageList(); @@ -107,7 +108,7 @@ class SetupWizard{ } private function showLicense() : bool{ - $this->message($this->lang->translateString("welcome_to_pocketmine", [\pocketmine\NAME])); + $this->message($this->lang->translateString("welcome_to_pocketmine", [VersionInfo::NAME])); echo <<writeLine(); if(strtolower($this->getInput($this->lang->get("accept_license"), "n", "y/N")) !== "y"){ - $this->error($this->lang->translateString("you_have_to_accept_the_license", [\pocketmine\NAME])); + $this->error($this->lang->translateString("you_have_to_accept_the_license", [VersionInfo::NAME])); sleep(5); return false; @@ -220,7 +221,7 @@ LICENSE; private function endWizard() : void{ $this->message($this->lang->get("you_have_finished")); $this->message($this->lang->get("pocketmine_plugins")); - $this->message($this->lang->translateString("pocketmine_will_start", [\pocketmine\NAME])); + $this->message($this->lang->translateString("pocketmine_will_start", [VersionInfo::NAME])); $this->writeLine(); $this->writeLine(); From 2c29634d03659013b58697d55e64c4b3582aa579 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 25 Jul 2020 19:17:33 +0100 Subject: [PATCH 1809/3224] Remove VERSION and GIT_COMMIT constants these are now lazily computed in VersionInfo as needed. --- build/make-release.php | 2 +- src/CrashDump.php | 7 ++-- src/PocketMine.php | 17 --------- src/Server.php | 4 +- src/VersionInfo.php | 37 +++++++++++++++++++ src/stats/SendUsageTask.php | 3 +- src/updater/AutoUpdater.php | 2 +- src/utils/Internet.php | 2 +- tests/phpstan/bootstrap.php | 2 - .../check-explicit-mixed-baseline.neon | 10 ++--- 10 files changed, 51 insertions(+), 35 deletions(-) diff --git a/build/make-release.php b/build/make-release.php index a89b22383b..f79675ef59 100644 --- a/build/make-release.php +++ b/build/make-release.php @@ -61,7 +61,7 @@ function main(array $argv) : void{ if(isset($argv[1])){ $currentVer = new VersionString($argv[1]); }else{ - $currentVer = new VersionString(VersionInfo::BASE_VERSION); + $currentVer = VersionInfo::getVersionObj(); } $nextVer = new VersionString(sprintf( "%u.%u.%u", diff --git a/src/CrashDump.php b/src/CrashDump.php index adea192f96..8fb1f96241 100644 --- a/src/CrashDump.php +++ b/src/CrashDump.php @@ -30,7 +30,6 @@ use pocketmine\plugin\PluginBase; use pocketmine\plugin\PluginManager; use pocketmine\utils\Filesystem; use pocketmine\utils\Utils; -use pocketmine\utils\VersionString; use function base64_encode; use function date; use function error_get_last; @@ -308,14 +307,14 @@ class CrashDump{ } private function generalData() : void{ - $version = new VersionString(VersionInfo::BASE_VERSION, VersionInfo::IS_DEVELOPMENT_BUILD, VersionInfo::BUILD_NUMBER); + $version = VersionInfo::getVersionObj(); $this->data["general"] = []; $this->data["general"]["name"] = $this->server->getName(); $this->data["general"]["base_version"] = VersionInfo::BASE_VERSION; $this->data["general"]["build"] = VersionInfo::BUILD_NUMBER; $this->data["general"]["is_dev"] = VersionInfo::IS_DEVELOPMENT_BUILD; $this->data["general"]["protocol"] = ProtocolInfo::CURRENT_PROTOCOL; - $this->data["general"]["git"] = \pocketmine\GIT_COMMIT; + $this->data["general"]["git"] = VersionInfo::getGitHash(); $this->data["general"]["uname"] = php_uname("a"); $this->data["general"]["php"] = phpversion(); $this->data["general"]["zend"] = zend_version(); @@ -323,7 +322,7 @@ class CrashDump{ $this->data["general"]["os"] = Utils::getOS(); $this->data["general"]["composer_libraries"] = Versions::VERSIONS; $this->addLine($this->server->getName() . " version: " . $version->getFullVersion(true) . " [Protocol " . ProtocolInfo::CURRENT_PROTOCOL . "]"); - $this->addLine("Git commit: " . \pocketmine\GIT_COMMIT); + $this->addLine("Git commit: " . VersionInfo::getGitHash()); $this->addLine("uname -a: " . php_uname("a")); $this->addLine("PHP Version: " . phpversion()); $this->addLine("Zend version: " . zend_version()); diff --git a/src/PocketMine.php b/src/PocketMine.php index 78c3f6cda7..d5b842d305 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -197,23 +197,6 @@ namespace pocketmine { ErrorToExceptionHandler::set(); - $version = new VersionString(VersionInfo::BASE_VERSION, VersionInfo::IS_DEVELOPMENT_BUILD, VersionInfo::BUILD_NUMBER); - define('pocketmine\VERSION', $version->getFullVersion(true)); - - $gitHash = str_repeat("00", 20); - - if(\Phar::running(true) === ""){ - $gitHash = Git::getRepositoryStatePretty(\pocketmine\PATH); - }else{ - $phar = new \Phar(\Phar::running(false)); - $meta = $phar->getMetadata(); - if(isset($meta["git"])){ - $gitHash = $meta["git"]; - } - } - - define('pocketmine\GIT_COMMIT', $gitHash); - $opts = getopt("", ["data:", "plugins:", "no-wizard", "enable-ansi", "disable-ansi"]); $dataPath = isset($opts["data"]) ? $opts["data"] . DIRECTORY_SEPARATOR : realpath(getcwd()) . DIRECTORY_SEPARATOR; diff --git a/src/Server.php b/src/Server.php index e4e025b9ec..1a9dd31e9e 100644 --- a/src/Server.php +++ b/src/Server.php @@ -288,7 +288,7 @@ class Server{ } public function getPocketMineVersion() : string{ - return \pocketmine\VERSION; + return VersionInfo::getVersionObj()->getFullVersion(true); } public function getVersion() : string{ @@ -1455,7 +1455,7 @@ class Server{ $report = false; } - if(strrpos(\pocketmine\GIT_COMMIT, "-dirty") !== false or \pocketmine\GIT_COMMIT === str_repeat("00", 20)){ + if(strrpos(VersionInfo::getGitHash(), "-dirty") !== false or VersionInfo::getGitHash() === str_repeat("00", 20)){ $this->logger->debug("Not sending crashdump due to locally modified"); $report = false; //Don't send crashdumps for locally modified builds } diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 67ac227acc..e4daaf30f1 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -23,6 +23,10 @@ declare(strict_types=1); namespace pocketmine; +use pocketmine\utils\Git; +use pocketmine\utils\VersionString; +use function str_repeat; + final class VersionInfo{ public const NAME = "PocketMine-MP"; public const BASE_VERSION = "4.0.0"; @@ -32,4 +36,37 @@ final class VersionInfo{ private function __construct(){ //NOOP } + + /** @var string|null */ + private static $gitHash = null; + + public static function getGitHash() : string{ + if(self::$gitHash === null){ + $gitHash = str_repeat("00", 20); + + if(\Phar::running(true) === ""){ + $gitHash = Git::getRepositoryStatePretty(\pocketmine\PATH); + }else{ + $phar = new \Phar(\Phar::running(false)); + $meta = $phar->getMetadata(); + if(isset($meta["git"])){ + $gitHash = $meta["git"]; + } + } + + self::$gitHash = $gitHash; + } + + return self::$gitHash; + } + + /** @var VersionString|null */ + private static $fullVersion = null; + + public static function getVersionObj() : VersionString{ + if(self::$fullVersion === null){ + self::$fullVersion = new VersionString(self::BASE_VERSION, self::IS_DEVELOPMENT_BUILD, self::BUILD_NUMBER); + } + return self::$fullVersion; + } } diff --git a/src/stats/SendUsageTask.php b/src/stats/SendUsageTask.php index 15753ff52c..4fe3394df0 100644 --- a/src/stats/SendUsageTask.php +++ b/src/stats/SendUsageTask.php @@ -31,7 +31,6 @@ use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Internet; use pocketmine\utils\Process; use pocketmine\utils\Utils; -use pocketmine\utils\VersionString; use pocketmine\uuid\UUID; use pocketmine\VersionInfo; use function array_map; @@ -72,7 +71,7 @@ class SendUsageTask extends AsyncTask{ case self::TYPE_OPEN: $data["event"] = "open"; - $version = new VersionString(VersionInfo::BASE_VERSION, VersionInfo::IS_DEVELOPMENT_BUILD, VersionInfo::BUILD_NUMBER); + $version = VersionInfo::getVersionObj(); $data["server"] = [ "port" => $server->getPort(), diff --git a/src/updater/AutoUpdater.php b/src/updater/AutoUpdater.php index 51497ee33f..9ca12b85e2 100644 --- a/src/updater/AutoUpdater.php +++ b/src/updater/AutoUpdater.php @@ -160,7 +160,7 @@ class AutoUpdater{ if($this->updateInfo === null){ return; } - $currentVersion = new VersionString(VersionInfo::BASE_VERSION, VersionInfo::IS_DEVELOPMENT_BUILD, VersionInfo::BUILD_NUMBER); + $currentVersion = VersionInfo::getVersionObj(); try{ $newVersion = new VersionString($this->updateInfo->base_version, $this->updateInfo->is_dev, $this->updateInfo->build); }catch(\InvalidArgumentException $e){ diff --git a/src/utils/Internet.php b/src/utils/Internet.php index de66a8a318..4b7ad926f4 100644 --- a/src/utils/Internet.php +++ b/src/utils/Internet.php @@ -224,7 +224,7 @@ class Internet{ CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT_MS => (int) ($timeout * 1000), CURLOPT_TIMEOUT_MS => (int) ($timeout * 1000), - CURLOPT_HTTPHEADER => array_merge(["User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0 " . VersionInfo::NAME . "/" . \pocketmine\VERSION], $extraHeaders), + CURLOPT_HTTPHEADER => array_merge(["User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0 " . VersionInfo::NAME . "/" . VersionInfo::getVersionObj()->getFullVersion(true)], $extraHeaders), CURLOPT_HEADER => true ]); try{ diff --git a/tests/phpstan/bootstrap.php b/tests/phpstan/bootstrap.php index 9850a602f6..21459e92ce 100644 --- a/tests/phpstan/bootstrap.php +++ b/tests/phpstan/bootstrap.php @@ -25,6 +25,4 @@ define('pocketmine\_PHPSTAN_ANALYSIS', true); //TODO: these need to be defined properly or removed define('pocketmine\COMPOSER_AUTOLOADER_PATH', dirname(__DIR__, 2) . '/vendor/autoload.php'); -define('pocketmine\GIT_COMMIT', str_repeat('00', 20)); define('pocketmine\PLUGIN_PATH', ''); -define('pocketmine\VERSION', '9.9.9'); diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index 2d1b552683..856de86a75 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -30,11 +30,6 @@ parameters: count: 7 path: ../../../src/MemoryManager.php - - - message: "#^Cannot access offset 'git' on mixed\\.$#" - count: 2 - path: ../../../src/PocketMine.php - - message: "#^Cannot cast mixed to int\\.$#" count: 6 @@ -90,6 +85,11 @@ parameters: count: 1 path: ../../../src/ServerConfigGroup.php + - + message: "#^Cannot access offset 'git' on mixed\\.$#" + count: 2 + path: ../../../src/VersionInfo.php + - message: "#^Cannot cast mixed to string\\.$#" count: 1 From 1500668d4e987099003cd9527c2abf58111158fb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 25 Jul 2020 19:21:22 +0100 Subject: [PATCH 1810/3224] imports cleanup --- src/MemoryManager.php | 1 - src/network/mcpe/protocol/serializer/PacketBatch.php | 1 - 2 files changed, 2 deletions(-) diff --git a/src/MemoryManager.php b/src/MemoryManager.php index 9cd87d0f02..81fbeb8420 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -42,7 +42,6 @@ use function gc_disable; use function gc_enable; use function get_class; use function get_declared_classes; -use function implode; use function ini_get; use function ini_set; use function is_array; diff --git a/src/network/mcpe/protocol/serializer/PacketBatch.php b/src/network/mcpe/protocol/serializer/PacketBatch.php index 1192103758..13f3716e46 100644 --- a/src/network/mcpe/protocol/serializer/PacketBatch.php +++ b/src/network/mcpe/protocol/serializer/PacketBatch.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\protocol\serializer; use pocketmine\network\mcpe\protocol\Packet; use pocketmine\network\mcpe\protocol\PacketDecodeException; use pocketmine\network\mcpe\protocol\PacketPool; -use pocketmine\utils\BinaryDataException; class PacketBatch{ From f4efaff73efd5aa1535f0b0266e85414d491fae8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 25 Jul 2020 19:21:45 +0100 Subject: [PATCH 1811/3224] phpstan: drop some obsolete baselined error patterns --- .../phpstan/configs/check-explicit-mixed-baseline.neon | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index 856de86a75..0e66f32e78 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -155,16 +155,6 @@ parameters: count: 1 path: ../../../src/network/mcpe/raklib/RakLibInterface.php - - - message: "#^Cannot access offset 'down' on mixed\\.$#" - count: 1 - path: ../../../src/network/mcpe/raklib/RakLibInterface.php - - - - message: "#^Cannot access offset 'up' on mixed\\.$#" - count: 1 - path: ../../../src/network/mcpe/raklib/RakLibInterface.php - - message: "#^Parameter \\#1 \\$value of static method pocketmine\\\\permission\\\\PermissionParser\\:\\:defaultFromString\\(\\) expects bool\\|string, mixed given\\.$#" count: 1 From 9873f53e0c9d12b3f2beb5b19e323b12e334b453 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 1 Aug 2020 16:02:42 +0100 Subject: [PATCH 1812/3224] make-release: added missing import --- build/make-release.php | 1 + 1 file changed, 1 insertion(+) diff --git a/build/make-release.php b/build/make-release.php index f79675ef59..4ee5ec590d 100644 --- a/build/make-release.php +++ b/build/make-release.php @@ -25,6 +25,7 @@ namespace pocketmine\build\make_release; use pocketmine\utils\VersionString; use pocketmine\VersionInfo; +use function defined; use function dirname; use function fgets; use function file_get_contents; From 32134ef1ac316b425f4f091feb7734343ee4ff81 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 1 Aug 2020 16:06:05 +0100 Subject: [PATCH 1813/3224] make-release: remove extra newline --- build/make-release.php | 1 - 1 file changed, 1 deletion(-) diff --git a/build/make-release.php b/build/make-release.php index 4ee5ec590d..98f103deea 100644 --- a/build/make-release.php +++ b/build/make-release.php @@ -38,7 +38,6 @@ use const STDIN; require_once dirname(__DIR__) . '/vendor/autoload.php'; - function replaceVersion(string $versionInfoPath, string $newVersion, bool $isDev) : void{ $versionInfo = file_get_contents($versionInfoPath); $versionInfo = preg_replace( From 2e0f7102e835b3fdf78fd76c7bd88a476e8d0a19 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 1 Aug 2020 16:06:38 +0100 Subject: [PATCH 1814/3224] ItemBlock: remove superfluous doc comments generated by PhpStorm --- src/item/ItemBlock.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/item/ItemBlock.php b/src/item/ItemBlock.php index 86d4ecbd71..2ee5d138ce 100644 --- a/src/item/ItemBlock.php +++ b/src/item/ItemBlock.php @@ -36,9 +36,7 @@ class ItemBlock extends Item{ protected $blockMeta; /** - * @param int $blockId * @param int $blockMeta usually 0-15 (placed blocks may only have meta values 0-15) - * @param ItemIdentifier $identifier */ public function __construct(int $blockId, int $blockMeta, ItemIdentifier $identifier){ if($blockMeta < 0 || $blockMeta > 15){ From 1525001565887594b8db3754854e6a870b3b36a4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 2 Aug 2020 23:22:39 +0100 Subject: [PATCH 1815/3224] protocol ItemStack: added equals() method to compare net itemstacks directly this will be needed for more than just this little check once item NBT gets cleaned out properly, since we'll need to compare object equality by network layer stuff instead of internals (where different network objects might deserialize to the same internal items). --- src/network/mcpe/convert/TypeConverter.php | 6 +++--- .../mcpe/protocol/types/inventory/ItemStack.php | 13 +++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index b404588c3c..3fd3a90037 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -180,12 +180,12 @@ class TypeConverter{ * @throws \UnexpectedValueException */ public function createInventoryAction(NetworkInventoryAction $action, Player $player) : ?InventoryAction{ - $old = TypeConverter::getInstance()->netItemStackToCore($action->oldItem); - $new = TypeConverter::getInstance()->netItemStackToCore($action->newItem); - if($old->equalsExact($new)){ + if($action->oldItem->equals($action->newItem)){ //filter out useless noise in 1.13 return null; } + $old = TypeConverter::getInstance()->netItemStackToCore($action->oldItem); + $new = TypeConverter::getInstance()->netItemStackToCore($action->newItem); switch($action->sourceType){ case NetworkInventoryAction::SOURCE_CONTAINER: if($action->windowId === ContainerIds::UI and $action->inventorySlot > 0){ diff --git a/src/network/mcpe/protocol/types/inventory/ItemStack.php b/src/network/mcpe/protocol/types/inventory/ItemStack.php index f43905a054..9233086f25 100644 --- a/src/network/mcpe/protocol/types/inventory/ItemStack.php +++ b/src/network/mcpe/protocol/types/inventory/ItemStack.php @@ -97,4 +97,17 @@ final class ItemStack{ public function getShieldBlockingTick() : ?int{ return $this->shieldBlockingTick; } + + public function equals(ItemStack $itemStack) : bool{ + return + $this->id === $itemStack->id && + $this->meta === $itemStack->meta && + $this->count === $itemStack->count && + $this->canPlaceOn === $itemStack->canPlaceOn && + $this->canDestroy === $itemStack->canDestroy && + $this->shieldBlockingTick === $itemStack->shieldBlockingTick && ( + $this->nbt === $itemStack->nbt || //this covers null === null and fast object identity + ($this->nbt !== null && $itemStack->nbt !== null && $this->nbt->equals($itemStack->nbt)) + ); + } } From 164c1552d1782a9a0e34c0eb0412940b85188946 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 3 Aug 2020 16:48:34 +0100 Subject: [PATCH 1816/3224] Add test to make sure DyeColorIdMap recognizes all colours this will be useful for integrity testing if more colours get added. --- .../data/bedrock/DyeColorIdMapTest.php | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 tests/phpunit/data/bedrock/DyeColorIdMapTest.php diff --git a/tests/phpunit/data/bedrock/DyeColorIdMapTest.php b/tests/phpunit/data/bedrock/DyeColorIdMapTest.php new file mode 100644 index 0000000000..156c06b72d --- /dev/null +++ b/tests/phpunit/data/bedrock/DyeColorIdMapTest.php @@ -0,0 +1,38 @@ +toId($color); + $color2 = DyeColorIdMap::getInstance()->fromId($id); + self::assertTrue($color->equals($color2)); + } + } +} From abbc2b94949dae195dbaccaedacd23160976a947 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 3 Aug 2020 20:19:27 +0100 Subject: [PATCH 1817/3224] phpstan: drop obsolete explict mixed ignoreError pattern this got lost in merge resolution --- tests/phpstan/configs/check-explicit-mixed-baseline.neon | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index 0e66f32e78..cf84722c52 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -115,11 +115,6 @@ parameters: count: 1 path: ../../../src/command/defaults/VanillaCommand.php - - - message: "#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#" - count: 1 - path: ../../../src/crafting/CraftingManagerFromDataHelper.php - - message: "#^Method pocketmine\\\\event\\\\EventPriority\\:\\:fromString\\(\\) should return int but returns mixed\\.$#" count: 1 From 35e8fd01ff36a10487c1049d7813e388df10976a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 3 Aug 2020 20:22:09 +0100 Subject: [PATCH 1818/3224] phpstan: drop some obsolete level 8 baseline errors --- tests/phpstan/configs/l8-baseline.neon | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 2189ee5677..7721ba8048 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -145,11 +145,6 @@ parameters: count: 1 path: ../../../src/inventory/transaction/CraftingTransaction.php - - - message: "#^Parameter \\#1 \\$object of function get_class expects object, pocketmine\\\\nbt\\\\tag\\\\Tag\\|null given\\.$#" - count: 1 - path: ../../../src/item/Item.php - - message: "#^Method pocketmine\\\\item\\\\enchantment\\\\Enchantment\\:\\:BLAST_PROTECTION\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\Enchantment but returns pocketmine\\\\item\\\\enchantment\\\\Enchantment\\|null\\.$#" count: 1 @@ -245,11 +240,6 @@ parameters: count: 1 path: ../../../src/item/enchantment/Enchantment.php - - - message: "#^Method pocketmine\\\\item\\\\enchantment\\\\EnchantmentList\\:\\:getSlot\\(\\) should return pocketmine\\\\item\\\\enchantment\\\\EnchantmentEntry but returns pocketmine\\\\item\\\\enchantment\\\\EnchantmentEntry\\|null\\.$#" - count: 1 - path: ../../../src/item/enchantment/EnchantmentList.php - - message: "#^Cannot call method getUsername\\(\\) on pocketmine\\\\player\\\\PlayerInfo\\|null\\.$#" count: 1 From 764f92c4563d56f4080bf0f53498af1714ed4d29 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 3 Aug 2020 23:59:06 +0100 Subject: [PATCH 1819/3224] BlockLegacyIdHelper: fixed a mistake in exception message --- src/block/BlockLegacyIdHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/BlockLegacyIdHelper.php b/src/block/BlockLegacyIdHelper.php index 549e4ac85c..ba140fadea 100644 --- a/src/block/BlockLegacyIdHelper.php +++ b/src/block/BlockLegacyIdHelper.php @@ -195,6 +195,6 @@ final class BlockLegacyIdHelper{ case DyeColor::BLACK()->id(): return new BlockIdentifier(Ids::BLACK_GLAZED_TERRACOTTA); } - throw new AssumptionFailedError("Switch should cover all wood types"); + throw new AssumptionFailedError("Switch should cover all colours"); } } From 060c300d509685c5ad74b141270b73f2b0e50918 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Aug 2020 20:59:59 +0100 Subject: [PATCH 1820/3224] Bed::setOccupied() no longer sets itself into the world setting itself into the world is very annoying when trying to simply set up a blockstate. --- src/block/Bed.php | 13 +++++++------ src/player/Player.php | 2 ++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/block/Bed.php b/src/block/Bed.php index 5c457641cf..73b61953fc 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -106,12 +106,6 @@ class Bed extends Transparent{ public function setOccupied(bool $occupied = true) : void{ $this->occupied = $occupied; - $this->pos->getWorld()->setBlock($this->pos, $this, false); - - if(($other = $this->getOtherHalf()) !== null){ - $other->occupied = $occupied; - $this->pos->getWorld()->setBlock($other->pos, $other, false); - } } private function getOtherHalfSide() : int{ @@ -165,6 +159,13 @@ class Bed extends Transparent{ } + public function onNearbyBlockChange() : void{ + if(($other = $this->getOtherHalf()) !== null and $other->occupied !== $this->occupied){ + $this->occupied = $other->occupied; + $this->pos->getWorld()->setBlock($this->pos, $this); + } + } + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof ItemBed){ //TODO: the item should do this $this->color = $item->getColor(); diff --git a/src/player/Player.php b/src/player/Player.php index f018f6b746..134d69d47b 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -954,6 +954,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ if($b instanceof Bed){ $b->setOccupied(); + $this->getWorld()->setBlock($pos, $b); } $this->sleeping = $pos; @@ -970,6 +971,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $b = $this->getWorld()->getBlock($this->sleeping); if($b instanceof Bed){ $b->setOccupied(false); + $this->getWorld()->setBlock($this->sleeping, $b); } (new PlayerBedLeaveEvent($this, $b))->call(); From 56ae3d01dac10dcdca8cc57cc0ae78a7c48ca69a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Aug 2020 21:17:03 +0100 Subject: [PATCH 1821/3224] block: added HorizontalFacingTrait and AnyFacingTrait these are primarily intended for deduplication of code and ability to cross-reference. Don't expect this API to remain the same. --- src/block/Anvil.php | 5 ++- src/block/Bed.php | 4 +-- src/block/Button.php | 4 +-- src/block/CarvedPumpkin.php | 5 ++- src/block/ChemistryTable.php | 5 ++- src/block/Chest.php | 5 ++- src/block/CocoaBlock.php | 4 +-- src/block/Door.php | 5 +-- src/block/EndPortalFrame.php | 4 +-- src/block/EndRod.php | 5 ++- src/block/EnderChest.php | 5 ++- src/block/FenceGate.php | 5 +-- src/block/Furnace.php | 5 +-- src/block/GlazedTerracotta.php | 5 ++- src/block/ItemFrame.php | 13 ++----- src/block/Ladder.php | 5 ++- src/block/RedstoneComparator.php | 19 ++-------- src/block/RedstoneRepeater.php | 5 +-- src/block/Stair.php | 4 +-- src/block/Trapdoor.php | 4 +-- src/block/TripwireHook.php | 4 +-- src/block/utils/AnyFacingTrait.php | 40 +++++++++++++++++++++ src/block/utils/HorizontalFacingTrait.php | 43 +++++++++++++++++++++++ 23 files changed, 131 insertions(+), 72 deletions(-) create mode 100644 src/block/utils/AnyFacingTrait.php create mode 100644 src/block/utils/HorizontalFacingTrait.php diff --git a/src/block/Anvil.php b/src/block/Anvil.php index 68f1a7392e..fe8a8bc561 100644 --- a/src/block/Anvil.php +++ b/src/block/Anvil.php @@ -27,6 +27,7 @@ use pocketmine\block\inventory\AnvilInventory; use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\Fallable; use pocketmine\block\utils\FallableTrait; +use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; use pocketmine\item\ToolTier; use pocketmine\math\AxisAlignedBB; @@ -37,9 +38,7 @@ use pocketmine\world\BlockTransaction; class Anvil extends Transparent implements Fallable{ use FallableTrait; - - /** @var int */ - protected $facing = Facing::NORTH; + use HorizontalFacingTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 6000.0)); diff --git a/src/block/Bed.php b/src/block/Bed.php index 73b61953fc..c3e9ad0511 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\block\tile\Bed as TileBed; use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\DyeColor; +use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\item\Bed as ItemBed; use pocketmine\item\Item; @@ -40,9 +41,8 @@ use pocketmine\world\BlockTransaction; use pocketmine\world\World; class Bed extends Transparent{ + use HorizontalFacingTrait; - /** @var int */ - protected $facing = Facing::NORTH; /** @var bool */ protected $occupied = false; /** @var bool */ diff --git a/src/block/Button.php b/src/block/Button.php index e868fe86f7..c3d0c4d236 100644 --- a/src/block/Button.php +++ b/src/block/Button.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\AnyFacingTrait; use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\math\Facing; @@ -33,9 +34,8 @@ use pocketmine\world\sound\RedstonePowerOffSound; use pocketmine\world\sound\RedstonePowerOnSound; abstract class Button extends Flowable{ + use AnyFacingTrait; - /** @var int */ - protected $facing = Facing::DOWN; /** @var bool */ protected $pressed = false; diff --git a/src/block/CarvedPumpkin.php b/src/block/CarvedPumpkin.php index 9219c32332..e5284bf49a 100644 --- a/src/block/CarvedPumpkin.php +++ b/src/block/CarvedPumpkin.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -31,9 +32,7 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class CarvedPumpkin extends Opaque{ - - /** @var int */ - protected $facing = Facing::NORTH; + use HorizontalFacingTrait; public function readStateFromData(int $id, int $stateMeta) : void{ $this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03); diff --git a/src/block/ChemistryTable.php b/src/block/ChemistryTable.php index d3b3d6d77a..e33159762c 100644 --- a/src/block/ChemistryTable.php +++ b/src/block/ChemistryTable.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -31,9 +32,7 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; final class ChemistryTable extends Opaque{ - - /** @var int */ - private $facing = Facing::NORTH; + use HorizontalFacingTrait; public function readStateFromData(int $id, int $stateMeta) : void{ $this->facing = Facing::opposite(BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x3)); diff --git a/src/block/Chest.php b/src/block/Chest.php index 523812a389..9ac729408e 100644 --- a/src/block/Chest.php +++ b/src/block/Chest.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\block\tile\Chest as TileChest; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -33,9 +34,7 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Chest extends Transparent{ - - /** @var int */ - protected $facing = Facing::NORTH; + use HorizontalFacingTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.5, BlockToolType::AXE)); diff --git a/src/block/CocoaBlock.php b/src/block/CocoaBlock.php index 5191f61c4f..0665ff00d6 100644 --- a/src/block/CocoaBlock.php +++ b/src/block/CocoaBlock.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\block\utils\TreeType; use pocketmine\item\Fertilizer; use pocketmine\item\Item; @@ -36,9 +37,8 @@ use pocketmine\world\BlockTransaction; use function mt_rand; class CocoaBlock extends Transparent{ + use HorizontalFacingTrait; - /** @var int */ - protected $facing = Facing::NORTH; /** @var int */ protected $age = 0; diff --git a/src/block/Door.php b/src/block/Door.php index ab4ad13e8d..1d0e175f44 100644 --- a/src/block/Door.php +++ b/src/block/Door.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -33,8 +34,8 @@ use pocketmine\world\BlockTransaction; use pocketmine\world\sound\DoorSound; class Door extends Transparent{ - /** @var int */ - protected $facing = Facing::NORTH; + use HorizontalFacingTrait; + /** @var bool */ protected $top = false; /** @var bool */ diff --git a/src/block/EndPortalFrame.php b/src/block/EndPortalFrame.php index 7c94e419dc..254bac34bf 100644 --- a/src/block/EndPortalFrame.php +++ b/src/block/EndPortalFrame.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -32,9 +33,8 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class EndPortalFrame extends Opaque{ + use HorizontalFacingTrait; - /** @var int */ - protected $facing = Facing::NORTH; /** @var bool */ protected $eye = false; diff --git a/src/block/EndRod.php b/src/block/EndRod.php index 6e5fd32c0d..17a967c20d 100644 --- a/src/block/EndRod.php +++ b/src/block/EndRod.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\AnyFacingTrait; use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; @@ -32,9 +33,7 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class EndRod extends Flowable{ - - /** @var int */ - protected $facing = Facing::DOWN; + use AnyFacingTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); diff --git a/src/block/EnderChest.php b/src/block/EnderChest.php index fbb498f9a6..da88d9a24a 100644 --- a/src/block/EnderChest.php +++ b/src/block/EnderChest.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\block\tile\EnderChest as TileEnderChest; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; use pocketmine\item\ToolTier; use pocketmine\math\AxisAlignedBB; @@ -34,9 +35,7 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class EnderChest extends Transparent{ - - /** @var int */ - protected $facing = Facing::NORTH; + use HorizontalFacingTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(22.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 3000.0)); diff --git a/src/block/FenceGate.php b/src/block/FenceGate.php index 8fc695e7cb..5191c3d162 100644 --- a/src/block/FenceGate.php +++ b/src/block/FenceGate.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -33,10 +34,10 @@ use pocketmine\world\BlockTransaction; use pocketmine\world\sound\DoorSound; class FenceGate extends Transparent{ + use HorizontalFacingTrait; + /** @var bool */ protected $open = false; - /** @var int */ - protected $facing = Facing::NORTH; /** @var bool */ protected $inWall = false; diff --git a/src/block/Furnace.php b/src/block/Furnace.php index 70ffde36d5..6d5b772138 100644 --- a/src/block/Furnace.php +++ b/src/block/Furnace.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\block\tile\Furnace as TileFurnace; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; use pocketmine\item\ToolTier; use pocketmine\math\Facing; @@ -33,11 +34,11 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Furnace extends Opaque{ + use HorizontalFacingTrait; + /** @var BlockIdentifierFlattened */ protected $idInfo; - /** @var int */ - protected $facing = Facing::NORTH; /** @var bool */ protected $lit = false; //this is set based on the blockID diff --git a/src/block/GlazedTerracotta.php b/src/block/GlazedTerracotta.php index a9335ad6b2..390d7b73ea 100644 --- a/src/block/GlazedTerracotta.php +++ b/src/block/GlazedTerracotta.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; use pocketmine\item\ToolTier; use pocketmine\math\Facing; @@ -32,9 +33,7 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class GlazedTerracotta extends Opaque{ - - /** @var int */ - protected $facing = Facing::NORTH; + use HorizontalFacingTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.4, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); diff --git a/src/block/ItemFrame.php b/src/block/ItemFrame.php index 084030dd8f..5616cc5e24 100644 --- a/src/block/ItemFrame.php +++ b/src/block/ItemFrame.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\block\tile\ItemFrame as TileItemFrame; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -33,10 +34,10 @@ use pocketmine\world\BlockTransaction; use function lcg_value; class ItemFrame extends Flowable{ + use HorizontalFacingTrait; + public const ROTATIONS = 8; - /** @var int */ - protected $facing = Facing::NORTH; /** @var bool */ protected $hasMap = false; //makes frame appear large if set /** @var Item|null */ @@ -86,14 +87,6 @@ class ItemFrame extends Flowable{ return 0b111; } - public function getFacing() : int{ - return $this->facing; - } - - public function setFacing(int $facing) : void{ - $this->facing = $facing; - } - public function getFramedItem() : ?Item{ return $this->framedItem !== null ? clone $this->framedItem : null; } diff --git a/src/block/Ladder.php b/src/block/Ladder.php index 16b21bdf96..5e742b3078 100644 --- a/src/block/Ladder.php +++ b/src/block/Ladder.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\entity\Entity; use pocketmine\entity\Living; use pocketmine\item\Item; @@ -34,9 +35,7 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Ladder extends Transparent{ - - /** @var int */ - protected $facing = Facing::NORTH; + use HorizontalFacingTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.4, BlockToolType::AXE)); diff --git a/src/block/RedstoneComparator.php b/src/block/RedstoneComparator.php index 7372ab99a2..cd7c0ebdf0 100644 --- a/src/block/RedstoneComparator.php +++ b/src/block/RedstoneComparator.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\block\tile\Comparator; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -34,11 +35,11 @@ use pocketmine\world\BlockTransaction; use function assert; class RedstoneComparator extends Flowable{ + use HorizontalFacingTrait; + /** @var BlockIdentifierFlattened */ protected $idInfo; - /** @var int */ - protected $facing = Facing::NORTH; /** @var bool */ protected $isSubtractMode = false; /** @var bool */ @@ -85,20 +86,6 @@ class RedstoneComparator extends Flowable{ $tile->setSignalStrength($this->signalStrength); } - /** - * TODO: ad hoc, move to interface - */ - public function getFacing() : int{ - return $this->facing; - } - - /** - * TODO: ad hoc, move to interface - */ - public function setFacing(int $facing) : void{ - $this->facing = $facing; - } - public function isSubtractMode() : bool{ return $this->isSubtractMode; } diff --git a/src/block/RedstoneRepeater.php b/src/block/RedstoneRepeater.php index 82af3f53d1..f777ad41b0 100644 --- a/src/block/RedstoneRepeater.php +++ b/src/block/RedstoneRepeater.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -32,14 +33,14 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class RedstoneRepeater extends Flowable{ + use HorizontalFacingTrait; + /** @var BlockIdentifierFlattened */ protected $idInfo; /** @var bool */ protected $powered = false; /** @var int */ - protected $facing = Facing::NORTH; - /** @var int */ protected $delay = 1; public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ diff --git a/src/block/Stair.php b/src/block/Stair.php index efd6b8a3b4..c70dc77730 100644 --- a/src/block/Stair.php +++ b/src/block/Stair.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\block\utils\StairShape; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; @@ -33,9 +34,8 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Stair extends Transparent{ + use HorizontalFacingTrait; - /** @var int */ - protected $facing = Facing::NORTH; /** @var bool */ protected $upsideDown = false; diff --git a/src/block/Trapdoor.php b/src/block/Trapdoor.php index ab1d75f538..f80593a527 100644 --- a/src/block/Trapdoor.php +++ b/src/block/Trapdoor.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -33,9 +34,8 @@ use pocketmine\world\BlockTransaction; use pocketmine\world\sound\DoorSound; class Trapdoor extends Transparent{ + use HorizontalFacingTrait; - /** @var int */ - protected $facing = Facing::NORTH; /** @var bool */ protected $open = false; /** @var bool */ diff --git a/src/block/TripwireHook.php b/src/block/TripwireHook.php index 69eb116b2d..9b3112bea7 100644 --- a/src/block/TripwireHook.php +++ b/src/block/TripwireHook.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -31,9 +32,8 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class TripwireHook extends Flowable{ + use HorizontalFacingTrait; - /** @var int */ - protected $facing = Facing::NORTH; /** @var bool */ protected $connected = false; /** @var bool */ diff --git a/src/block/utils/AnyFacingTrait.php b/src/block/utils/AnyFacingTrait.php new file mode 100644 index 0000000000..751e673781 --- /dev/null +++ b/src/block/utils/AnyFacingTrait.php @@ -0,0 +1,40 @@ +facing; } + + /** @return $this */ + public function setFacing(int $facing) : self{ + Facing::validate($this->facing); + $this->facing = $facing; + return $this; + } +} diff --git a/src/block/utils/HorizontalFacingTrait.php b/src/block/utils/HorizontalFacingTrait.php new file mode 100644 index 0000000000..4a68f8a6c4 --- /dev/null +++ b/src/block/utils/HorizontalFacingTrait.php @@ -0,0 +1,43 @@ +facing; } + + /** @return $this */ + public function setFacing(int $facing) : self{ + if(!in_array($facing, Facing::HORIZONTAL, true)){ + throw new \InvalidArgumentException("Facing must be horizontal"); + } + $this->facing = $facing; + return $this; + } +} From b725fcbdf28a916a5b25dd2d22ffde5ea4137fab Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 Aug 2020 22:01:41 +0100 Subject: [PATCH 1822/3224] IPlayer: remove circular dependency on Player and remove useless Player->getPlayer() --- src/player/IPlayer.php | 2 -- src/player/Player.php | 4 ---- 2 files changed, 6 deletions(-) diff --git a/src/player/IPlayer.php b/src/player/IPlayer.php index 66609474a9..607033f5d0 100644 --- a/src/player/IPlayer.php +++ b/src/player/IPlayer.php @@ -39,8 +39,6 @@ interface IPlayer extends ServerOperator{ public function setWhitelisted(bool $value) : void; - public function getPlayer() : ?Player; - public function getFirstPlayed() : ?int; public function getLastPlayed() : ?int; diff --git a/src/player/Player.php b/src/player/Player.php index 134d69d47b..a4fb358b81 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -426,10 +426,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return parent::getUniqueId(); } - public function getPlayer() : ?Player{ - return $this; - } - /** * TODO: not sure this should be nullable */ From aa682a865e1475a91d36e445e371da11e41a90b4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Aug 2020 12:46:07 +0100 Subject: [PATCH 1823/3224] Allow injecting arbitrary preimage block for ore generation this will be useful for nether ore generation. --- src/world/generator/Flat.php | 17 +++++++++-------- src/world/generator/normal/Normal.php | 17 +++++++++-------- src/world/generator/object/Ore.php | 5 ++--- src/world/generator/object/OreType.php | 5 ++++- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/world/generator/Flat.php b/src/world/generator/Flat.php index 716986c577..a21c026a42 100644 --- a/src/world/generator/Flat.php +++ b/src/world/generator/Flat.php @@ -73,15 +73,16 @@ class Flat extends Generator{ if(isset($this->options["decoration"])){ $ores = new Ore(); + $stone = VanillaBlocks::STONE(); $ores->setOreTypes([ - new OreType(VanillaBlocks::COAL_ORE(), 20, 16, 0, 128), - new OreType(VanillaBlocks::IRON_ORE(), 20, 8, 0, 64), - new OreType(VanillaBlocks::REDSTONE_ORE(), 8, 7, 0, 16), - new OreType(VanillaBlocks::LAPIS_LAZULI_ORE(), 1, 6, 0, 32), - new OreType(VanillaBlocks::GOLD_ORE(), 2, 8, 0, 32), - new OreType(VanillaBlocks::DIAMOND_ORE(), 1, 7, 0, 16), - new OreType(VanillaBlocks::DIRT(), 20, 32, 0, 128), - new OreType(VanillaBlocks::GRAVEL(), 10, 16, 0, 128) + new OreType(VanillaBlocks::COAL_ORE(), $stone, 20, 16, 0, 128), + new OreType(VanillaBlocks::IRON_ORE(), $stone, 20, 8, 0, 64), + new OreType(VanillaBlocks::REDSTONE_ORE(), $stone, 8, 7, 0, 16), + new OreType(VanillaBlocks::LAPIS_LAZULI_ORE(), $stone, 1, 6, 0, 32), + new OreType(VanillaBlocks::GOLD_ORE(), $stone, 2, 8, 0, 32), + new OreType(VanillaBlocks::DIAMOND_ORE(), $stone, 1, 7, 0, 16), + new OreType(VanillaBlocks::DIRT(), $stone, 20, 32, 0, 128), + new OreType(VanillaBlocks::GRAVEL(), $stone, 10, 16, 0, 128) ]); $this->populators[] = $ores; } diff --git a/src/world/generator/normal/Normal.php b/src/world/generator/normal/Normal.php index 647cf7453a..52bc2c8373 100644 --- a/src/world/generator/normal/Normal.php +++ b/src/world/generator/normal/Normal.php @@ -116,15 +116,16 @@ class Normal extends Generator{ $this->generationPopulators[] = $cover; $ores = new Ore(); + $stone = VanillaBlocks::STONE(); $ores->setOreTypes([ - new OreType(VanillaBlocks::COAL_ORE(), 20, 16, 0, 128), - new OreType(VanillaBlocks::IRON_ORE(), 20, 8, 0, 64), - new OreType(VanillaBlocks::REDSTONE_ORE(), 8, 7, 0, 16), - new OreType(VanillaBlocks::LAPIS_LAZULI_ORE(), 1, 6, 0, 32), - new OreType(VanillaBlocks::GOLD_ORE(), 2, 8, 0, 32), - new OreType(VanillaBlocks::DIAMOND_ORE(), 1, 7, 0, 16), - new OreType(VanillaBlocks::DIRT(), 20, 32, 0, 128), - new OreType(VanillaBlocks::GRAVEL(), 10, 16, 0, 128) + new OreType(VanillaBlocks::COAL_ORE(), $stone, 20, 16, 0, 128), + new OreType(VanillaBlocks::IRON_ORE(), $stone, 20, 8, 0, 64), + new OreType(VanillaBlocks::REDSTONE_ORE(), $stone, 8, 7, 0, 16), + new OreType(VanillaBlocks::LAPIS_LAZULI_ORE(), $stone, 1, 6, 0, 32), + new OreType(VanillaBlocks::GOLD_ORE(), $stone, 2, 8, 0, 32), + new OreType(VanillaBlocks::DIAMOND_ORE(), $stone, 1, 7, 0, 16), + new OreType(VanillaBlocks::DIRT(), $stone, 20, 32, 0, 128), + new OreType(VanillaBlocks::GRAVEL(), $stone, 10, 16, 0, 128) ]); $this->populators[] = $ores; } diff --git a/src/world/generator/object/Ore.php b/src/world/generator/object/Ore.php index d0b8dc649c..aad9cc0349 100644 --- a/src/world/generator/object/Ore.php +++ b/src/world/generator/object/Ore.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\world\generator\object; -use pocketmine\block\BlockLegacyIds; use pocketmine\math\VectorMath; use pocketmine\utils\Random; use pocketmine\world\ChunkManager; @@ -46,7 +45,7 @@ class Ore{ } public function canPlaceObject(ChunkManager $world, int $x, int $y, int $z) : bool{ - return $world->getBlockAt($x, $y, $z)->getId() === BlockLegacyIds::STONE; + return $world->getBlockAt($x, $y, $z)->isSameType($this->type->replaces); } public function placeObject(ChunkManager $world, int $x, int $y, int $z) : void{ @@ -86,7 +85,7 @@ class Ore{ $sizeZ = ($zz + 0.5 - $seedZ) / $size; $sizeZ *= $sizeZ; - if(($sizeX + $sizeY + $sizeZ) < 1 and $world->getBlockAt($xx, $yy, $zz)->getId() === BlockLegacyIds::STONE){ + if(($sizeX + $sizeY + $sizeZ) < 1 and $world->getBlockAt($xx, $yy, $zz)->isSameType($this->type->replaces)){ $world->setBlockAt($xx, $yy, $zz, $this->type->material); } } diff --git a/src/world/generator/object/OreType.php b/src/world/generator/object/OreType.php index 1f10ea7b9f..e9ea680c71 100644 --- a/src/world/generator/object/OreType.php +++ b/src/world/generator/object/OreType.php @@ -28,6 +28,8 @@ use pocketmine\block\Block; class OreType{ /** @var Block */ public $material; + /** @var Block */ + public $replaces; /** @var int */ public $clusterCount; /** @var int */ @@ -37,8 +39,9 @@ class OreType{ /** @var int */ public $minHeight; - public function __construct(Block $material, int $clusterCount, int $clusterSize, int $minHeight, int $maxHeight){ + public function __construct(Block $material, Block $replaces, int $clusterCount, int $clusterSize, int $minHeight, int $maxHeight){ $this->material = $material; + $this->replaces = $replaces; $this->clusterCount = $clusterCount; $this->clusterSize = $clusterSize; $this->maxHeight = $maxHeight; From de9856151a47ec3f2ef9da45e54393a048c1deef Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Aug 2020 12:58:08 +0100 Subject: [PATCH 1824/3224] Flat: remove useless field --- src/world/generator/Flat.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/world/generator/Flat.php b/src/world/generator/Flat.php index a21c026a42..86d6baa71c 100644 --- a/src/world/generator/Flat.php +++ b/src/world/generator/Flat.php @@ -47,8 +47,6 @@ class Flat extends Generator{ */ private $structure; /** @var int */ - private $floorLevel; - /** @var int */ private $biome; /** @var string */ private $preset; @@ -128,8 +126,6 @@ class Flat extends Generator{ $options = $preset[3] ?? ""; $this->structure = self::parseLayers($blocks); - $this->floorLevel = count($this->structure); - //TODO: more error checking preg_match_all('#(([0-9a-z_]{1,})\(?([0-9a-z_ =:]{0,})\)?),?#', $options, $matches); foreach($matches[2] as $i => $option){ From 7bcfece11e0cb2a45da1395d4e3067ae94af9784 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Aug 2020 12:58:49 +0100 Subject: [PATCH 1825/3224] Flat: use block names instead of legacy block IDs for hardcoded preset --- src/world/generator/Flat.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/generator/Flat.php b/src/world/generator/Flat.php index 86d6baa71c..5715ffb660 100644 --- a/src/world/generator/Flat.php +++ b/src/world/generator/Flat.php @@ -63,8 +63,8 @@ class Flat extends Generator{ if(isset($this->options["preset"]) and $this->options["preset"] != ""){ $this->preset = $this->options["preset"]; }else{ - $this->preset = "2;7,2x3,2;1;"; - //$this->preset = "2;7,59x1,3x3,2;1;spawn(radius=10 block=89),decoration(treecount=80 grasscount=45)"; + $this->preset = "2;bedrock,2xdirt,grass;1;"; + //$this->preset = "2;bedrock,59xstone,3xdirt,grass;1;spawn(radius=10 block=89),decoration(treecount=80 grasscount=45)"; } $this->parsePreset(); From 3d4470ed8dd726ea59a8cc439da24ffd92492223 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Aug 2020 13:23:03 +0100 Subject: [PATCH 1826/3224] added nether quartz ore to nether generation --- src/world/generator/hell/Nether.php | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/world/generator/hell/Nether.php b/src/world/generator/hell/Nether.php index 261483f39a..cd9d35ae5b 100644 --- a/src/world/generator/hell/Nether.php +++ b/src/world/generator/hell/Nether.php @@ -29,6 +29,8 @@ use pocketmine\world\ChunkManager; use pocketmine\world\generator\Generator; use pocketmine\world\generator\InvalidGeneratorOptionsException; use pocketmine\world\generator\noise\Simplex; +use pocketmine\world\generator\object\OreType; +use pocketmine\world\generator\populator\Ore; use pocketmine\world\generator\populator\Populator; use function abs; @@ -62,18 +64,11 @@ class Nether extends Generator{ $this->noiseBase = new Simplex($this->random, 4, 1 / 4, 1 / 64); $this->random->setSeed($this->seed); - /*$ores = new Ore(); + $ores = new Ore(); $ores->setOreTypes([ - new OreType(new CoalOre(), 20, 16, 0, 128), - new OreType(new IronOre(), 20, 8, 0, 64), - new OreType(new RedstoneOre(), 8, 7, 0, 16), - new OreType(new LapisOre(), 1, 6, 0, 32), - new OreType(new GoldOre(), 2, 8, 0, 32), - new OreType(new DiamondOre(), 1, 7, 0, 16), - new OreType(new Dirt(), 20, 32, 0, 128), - new OreType(new Gravel(), 10, 16, 0, 128) + new OreType(VanillaBlocks::NETHER_QUARTZ_ORE(), VanillaBlocks::NETHERRACK(), 16, 14, 10, 117) ]); - $this->populators[] = $ores;*/ + $this->populators[] = $ores; } public function generateChunk(int $chunkX, int $chunkZ) : void{ From 7399e6944e89ef5e50a912683de2a725c4e09381 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Aug 2020 13:46:08 +0100 Subject: [PATCH 1827/3224] Consistent fluency for block property setters --- src/block/Banner.php | 4 +++- src/block/Bed.php | 4 +++- src/block/FlowerPot.php | 4 +++- src/block/ItemFrame.php | 12 +++++++++--- src/block/NetherPortal.php | 4 +++- src/block/Note.php | 4 +++- src/block/RedstoneComparator.php | 12 +++++++++--- src/block/Sign.php | 4 +++- 8 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/block/Banner.php b/src/block/Banner.php index 683b90051f..d160d430f5 100644 --- a/src/block/Banner.php +++ b/src/block/Banner.php @@ -137,13 +137,15 @@ class Banner extends Transparent{ /** * @param Deque|BannerPattern[] $patterns * @phpstan-param Deque $patterns + * @return $this */ - public function setPatterns(Deque $patterns) : void{ + public function setPatterns(Deque $patterns) : self{ $checked = $patterns->filter(function($v) : bool{ return $v instanceof BannerPattern; }); if($checked->count() !== $patterns->count()){ throw new \TypeError("Deque must only contain " . BannerPattern::class . " objects"); } $this->patterns = $checked; + return $this; } /** diff --git a/src/block/Bed.php b/src/block/Bed.php index c3e9ad0511..dec2485768 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -104,8 +104,10 @@ class Bed extends Transparent{ return $this->occupied; } - public function setOccupied(bool $occupied = true) : void{ + /** @return $this */ + public function setOccupied(bool $occupied = true) : self{ $this->occupied = $occupied; + return $this; } private function getOtherHalfSide() : int{ diff --git a/src/block/FlowerPot.php b/src/block/FlowerPot.php index d547bf0b5e..ce787ae021 100644 --- a/src/block/FlowerPot.php +++ b/src/block/FlowerPot.php @@ -81,13 +81,15 @@ class FlowerPot extends Flowable{ return $this->plant; } - public function setPlant(?Block $plant) : void{ + /** @return $this */ + public function setPlant(?Block $plant) : self{ if($plant === null or $plant instanceof Air){ $this->plant = null; }else{ $this->plant = clone $plant; } $this->occupied = $this->plant !== null; + return $this; } public function canAddPlant(Block $block) : bool{ diff --git a/src/block/ItemFrame.php b/src/block/ItemFrame.php index 5616cc5e24..0ab780480f 100644 --- a/src/block/ItemFrame.php +++ b/src/block/ItemFrame.php @@ -91,29 +91,35 @@ class ItemFrame extends Flowable{ return $this->framedItem !== null ? clone $this->framedItem : null; } - public function setFramedItem(?Item $item) : void{ + /** @return $this */ + public function setFramedItem(?Item $item) : self{ if($item === null or $item->isNull()){ $this->framedItem = null; $this->itemRotation = 0; }else{ $this->framedItem = clone $item; } + return $this; } public function getItemRotation() : int{ return $this->itemRotation; } - public function setItemRotation(int $itemRotation) : void{ + /** @return $this */ + public function setItemRotation(int $itemRotation) : self{ $this->itemRotation = $itemRotation; + return $this; } public function getItemDropChance() : float{ return $this->itemDropChance; } - public function setItemDropChance(float $itemDropChance) : void{ + /** @return $this */ + public function setItemDropChance(float $itemDropChance) : self{ $this->itemDropChance = $itemDropChance; + return $this; } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ diff --git a/src/block/NetherPortal.php b/src/block/NetherPortal.php index 0eb9efc052..8af227b538 100644 --- a/src/block/NetherPortal.php +++ b/src/block/NetherPortal.php @@ -54,12 +54,14 @@ class NetherPortal extends Transparent{ /** * @throws \InvalidArgumentException + * @return $this */ - public function setAxis(int $axis) : void{ + public function setAxis(int $axis) : self{ if($axis !== Facing::AXIS_X and $axis !== Facing::AXIS_Z){ throw new \InvalidArgumentException("Invalid axis"); } $this->axis = $axis; + return $this; } public function getLightLevel() : int{ diff --git a/src/block/Note.php b/src/block/Note.php index 3e027c220b..846a4dfe5b 100644 --- a/src/block/Note.php +++ b/src/block/Note.php @@ -62,11 +62,13 @@ class Note extends Opaque{ return $this->pitch; } - public function setPitch(int $pitch) : void{ + /** @return $this */ + public function setPitch(int $pitch) : self{ if($pitch < self::MIN_PITCH or $pitch > self::MAX_PITCH){ throw new \InvalidArgumentException("Pitch must be in range " . self::MIN_PITCH . " - " . self::MAX_PITCH); } $this->pitch = $pitch; + return $this; } //TODO diff --git a/src/block/RedstoneComparator.php b/src/block/RedstoneComparator.php index cd7c0ebdf0..f640a7c585 100644 --- a/src/block/RedstoneComparator.php +++ b/src/block/RedstoneComparator.php @@ -90,24 +90,30 @@ class RedstoneComparator extends Flowable{ return $this->isSubtractMode; } - public function setSubtractMode(bool $isSubtractMode) : void{ + /** @return $this */ + public function setSubtractMode(bool $isSubtractMode) : self{ $this->isSubtractMode = $isSubtractMode; + return $this; } public function isPowered() : bool{ return $this->powered; } - public function setPowered(bool $powered) : void{ + /** @return $this */ + public function setPowered(bool $powered) : self{ $this->powered = $powered; + return $this; } public function getSignalStrength() : int{ return $this->signalStrength; } - public function setSignalStrength(int $signalStrength) : void{ + /** @return $this */ + public function setSignalStrength(int $signalStrength) : self{ $this->signalStrength = $signalStrength; + return $this; } /** diff --git a/src/block/Sign.php b/src/block/Sign.php index b14203b67e..45640e9686 100644 --- a/src/block/Sign.php +++ b/src/block/Sign.php @@ -140,8 +140,10 @@ class Sign extends Transparent{ return $this->text; } - public function setText(SignText $text) : void{ + /** @return $this */ + public function setText(SignText $text) : self{ $this->text = $text; + return $this; } /** From 2b044195a58618aecf8b8a464c7575de3382b294 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Aug 2020 14:38:31 +0100 Subject: [PATCH 1828/3224] Update for pocketmine/math Axis refactor --- build/php | 2 +- composer.lock | 8 ++++---- src/block/Block.php | 4 ++-- src/block/CocoaBlock.php | 3 ++- src/block/EndRod.php | 5 +++-- src/block/Fence.php | 5 +++-- src/block/Ladder.php | 3 ++- src/block/Lantern.php | 5 +++-- src/block/Lever.php | 7 ++++--- src/block/NetherPortal.php | 10 +++++----- src/block/Thin.php | 5 +++-- src/block/TripwireHook.php | 3 ++- src/block/Vine.php | 3 ++- src/block/Wall.php | 1 + src/block/utils/BlockDataSerializer.php | 5 +++-- src/block/utils/PillarRotationTrait.php | 15 ++++++++------- src/item/PaintingItem.php | 3 ++- 17 files changed, 50 insertions(+), 37 deletions(-) diff --git a/build/php b/build/php index 2f422db397..fadde8d5b2 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit 2f422db397509fd9d7161b0c388401ec5be5a46f +Subproject commit fadde8d5b2ee97f41f4647ff2c0a97e8aa9d7af0 diff --git a/composer.lock b/composer.lock index 42932f3a8f..2035f9c0f2 100644 --- a/composer.lock +++ b/composer.lock @@ -552,12 +552,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "2a1a1783123c365a755f1f6d1023466d27d52795" + "reference": "a7c9da52c7efcd3383073357c10d3a989bfbb3f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/2a1a1783123c365a755f1f6d1023466d27d52795", - "reference": "2a1a1783123c365a755f1f6d1023466d27d52795", + "url": "https://api.github.com/repos/pmmp/Math/zipball/a7c9da52c7efcd3383073357c10d3a989bfbb3f2", + "reference": "a7c9da52c7efcd3383073357c10d3a989bfbb3f2", "shasum": "" }, "require": { @@ -579,7 +579,7 @@ "LGPL-3.0" ], "description": "PHP library containing math related code used in PocketMine-MP", - "time": "2020-07-09T19:58:18+00:00" + "time": "2020-08-06T13:19:36+00:00" }, { "name": "pocketmine/nbt", diff --git a/src/block/Block.php b/src/block/Block.php index 097b85fb44..f48ed982d7 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -33,8 +33,8 @@ use pocketmine\entity\Entity; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\math\Axis; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Facing; use pocketmine\math\RayTraceResult; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; @@ -485,7 +485,7 @@ class Block{ */ public function getHorizontalSides() : \Generator{ $world = $this->pos->getWorld(); - foreach($this->pos->sidesAroundAxis(Facing::AXIS_Y) as $vector3){ + foreach($this->pos->sidesAroundAxis(Axis::Y) as $vector3){ yield $world->getBlock($vector3); } } diff --git a/src/block/CocoaBlock.php b/src/block/CocoaBlock.php index 0665ff00d6..696a2dd97d 100644 --- a/src/block/CocoaBlock.php +++ b/src/block/CocoaBlock.php @@ -29,6 +29,7 @@ use pocketmine\block\utils\TreeType; use pocketmine\item\Fertilizer; use pocketmine\item\Item; use pocketmine\item\VanillaItems; +use pocketmine\math\Axis; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -74,7 +75,7 @@ class CocoaBlock extends Transparent{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(Facing::axis($face) !== Facing::AXIS_Y and $blockClicked instanceof Wood and $blockClicked->getTreeType()->equals(TreeType::JUNGLE())){ + if(Facing::axis($face) !== Axis::Y and $blockClicked instanceof Wood and $blockClicked->getTreeType()->equals(TreeType::JUNGLE())){ $this->facing = $face; return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/block/EndRod.php b/src/block/EndRod.php index 17a967c20d..a943e07c1a 100644 --- a/src/block/EndRod.php +++ b/src/block/EndRod.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\block\utils\AnyFacingTrait; use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; +use pocketmine\math\Axis; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -41,7 +42,7 @@ class EndRod extends Flowable{ protected function writeStateToMeta() : int{ $result = BlockDataSerializer::writeFacing($this->facing); - if(Facing::axis($this->facing) !== Facing::AXIS_Y){ + if(Facing::axis($this->facing) !== Axis::Y){ $result ^= 1; //TODO: in PC this is always the same as facing, just PE is stupid } @@ -84,7 +85,7 @@ class EndRod extends Flowable{ $myAxis = Facing::axis($this->facing); $bb = AxisAlignedBB::one(); - foreach([Facing::AXIS_Y, Facing::AXIS_Z, Facing::AXIS_X] as $axis){ + foreach([Axis::Y, Axis::Z, Axis::X] as $axis){ if($axis === $myAxis){ continue; } diff --git a/src/block/Fence.php b/src/block/Fence.php index 2c99279b48..1eeffc3a1b 100644 --- a/src/block/Fence.php +++ b/src/block/Fence.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\math\Axis; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use function count; @@ -63,7 +64,7 @@ class Fence extends Transparent{ if($connectWest or $connectEast){ //X axis (west/east) $bbs[] = AxisAlignedBB::one() - ->squash(Facing::AXIS_Z, $inset) + ->squash(Axis::Z, $inset) ->extend(Facing::UP, 0.5) ->trim(Facing::WEST, $connectWest ? 0 : $inset) ->trim(Facing::EAST, $connectEast ? 0 : $inset); @@ -75,7 +76,7 @@ class Fence extends Transparent{ if($connectNorth or $connectSouth){ //Z axis (north/south) $bbs[] = AxisAlignedBB::one() - ->squash(Facing::AXIS_X, $inset) + ->squash(Axis::X, $inset) ->extend(Facing::UP, 0.5) ->trim(Facing::NORTH, $connectNorth ? 0 : $inset) ->trim(Facing::SOUTH, $connectSouth ? 0 : $inset); diff --git a/src/block/Ladder.php b/src/block/Ladder.php index 5e742b3078..3ef3f073e3 100644 --- a/src/block/Ladder.php +++ b/src/block/Ladder.php @@ -28,6 +28,7 @@ use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\entity\Entity; use pocketmine\entity\Living; use pocketmine\item\Item; +use pocketmine\math\Axis; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -80,7 +81,7 @@ class Ladder extends Transparent{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$blockClicked->isTransparent() and Facing::axis($face) !== Facing::AXIS_Y){ + if(!$blockClicked->isTransparent() and Facing::axis($face) !== Axis::Y){ $this->facing = $face; return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/block/Lantern.php b/src/block/Lantern.php index 7f5d790c58..717911544c 100644 --- a/src/block/Lantern.php +++ b/src/block/Lantern.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; +use pocketmine\math\Axis; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -59,8 +60,8 @@ class Lantern extends Transparent{ AxisAlignedBB::one() ->trim(Facing::UP, $this->hanging ? 6 / 16 : 8 / 16) ->trim(Facing::DOWN, $this->hanging ? 2 / 16 : 0) - ->squash(Facing::AXIS_X, 5 / 16) - ->squash(Facing::AXIS_Z, 5 / 16) + ->squash(Axis::X, 5 / 16) + ->squash(Axis::Z, 5 / 16) ]; } diff --git a/src/block/Lever.php b/src/block/Lever.php index d4d7bf6f50..4dd69b18ba 100644 --- a/src/block/Lever.php +++ b/src/block/Lever.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; +use pocketmine\math\Axis; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -50,9 +51,9 @@ class Lever extends Flowable{ protected function writeStateToMeta() : int{ if($this->leverPos === self::BOTTOM){ - $rotationMeta = Facing::axis($this->facing) === Facing::AXIS_Z ? 7 : 0; + $rotationMeta = Facing::axis($this->facing) === Axis::Z ? 7 : 0; }elseif($this->leverPos === self::TOP){ - $rotationMeta = Facing::axis($this->facing) === Facing::AXIS_Z ? 5 : 6; + $rotationMeta = Facing::axis($this->facing) === Axis::Z ? 5 : 6; }else{ $rotationMeta = 6 - BlockDataSerializer::writeHorizontalFacing($this->facing); } @@ -84,7 +85,7 @@ class Lever extends Flowable{ return false; } - if(Facing::axis($face) === Facing::AXIS_Y){ + if(Facing::axis($face) === Axis::Y){ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); } diff --git a/src/block/NetherPortal.php b/src/block/NetherPortal.php index 8af227b538..c2003958f0 100644 --- a/src/block/NetherPortal.php +++ b/src/block/NetherPortal.php @@ -25,23 +25,23 @@ namespace pocketmine\block; use pocketmine\entity\Entity; use pocketmine\item\Item; +use pocketmine\math\Axis; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Facing; class NetherPortal extends Transparent{ /** @var int */ - protected $axis = Facing::AXIS_X; + protected $axis = Axis::X; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::indestructible(0.0)); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->axis = $stateMeta === BlockLegacyMetadata::NETHER_PORTAL_AXIS_Z ? Facing::AXIS_Z : Facing::AXIS_X; //mojang u dumb + $this->axis = $stateMeta === BlockLegacyMetadata::NETHER_PORTAL_AXIS_Z ? Axis::Z : Axis::X; //mojang u dumb } protected function writeStateToMeta() : int{ - return $this->axis === Facing::AXIS_Z ? BlockLegacyMetadata::NETHER_PORTAL_AXIS_Z : BlockLegacyMetadata::NETHER_PORTAL_AXIS_X; + return $this->axis === Axis::Z ? BlockLegacyMetadata::NETHER_PORTAL_AXIS_Z : BlockLegacyMetadata::NETHER_PORTAL_AXIS_X; } public function getStateBitmask() : int{ @@ -57,7 +57,7 @@ class NetherPortal extends Transparent{ * @return $this */ public function setAxis(int $axis) : self{ - if($axis !== Facing::AXIS_X and $axis !== Facing::AXIS_Z){ + if($axis !== Axis::X and $axis !== Axis::Z){ throw new \InvalidArgumentException("Invalid axis"); } $this->axis = $axis; diff --git a/src/block/Thin.php b/src/block/Thin.php index 1df7726988..060bf667c7 100644 --- a/src/block/Thin.php +++ b/src/block/Thin.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\math\Axis; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use function count; @@ -51,7 +52,7 @@ class Thin extends Transparent{ $bbs = []; if(isset($this->connections[Facing::WEST]) or isset($this->connections[Facing::EAST])){ - $bb = AxisAlignedBB::one()->squash(Facing::AXIS_Z, $inset); + $bb = AxisAlignedBB::one()->squash(Axis::Z, $inset); if(!isset($this->connections[Facing::WEST])){ $bb->trim(Facing::WEST, $inset); @@ -62,7 +63,7 @@ class Thin extends Transparent{ } if(isset($this->connections[Facing::NORTH]) or isset($this->connections[Facing::SOUTH])){ - $bb = AxisAlignedBB::one()->squash(Facing::AXIS_X, $inset); + $bb = AxisAlignedBB::one()->squash(Axis::X, $inset); if(!isset($this->connections[Facing::NORTH])){ $bb->trim(Facing::NORTH, $inset); diff --git a/src/block/TripwireHook.php b/src/block/TripwireHook.php index 9b3112bea7..ac1c8df9ae 100644 --- a/src/block/TripwireHook.php +++ b/src/block/TripwireHook.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; +use pocketmine\math\Axis; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -60,7 +61,7 @@ class TripwireHook extends Flowable{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(Facing::axis($face) !== Facing::AXIS_Y){ + if(Facing::axis($face) !== Axis::Y){ //TODO: check face is valid $this->facing = $face; return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/block/Vine.php b/src/block/Vine.php index b590c740d6..ec86d57aba 100644 --- a/src/block/Vine.php +++ b/src/block/Vine.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\entity\Entity; use pocketmine\item\Item; +use pocketmine\math\Axis; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -89,7 +90,7 @@ class Vine extends Flowable{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$blockClicked->isSolid() or Facing::axis($face) === Facing::AXIS_Y){ + if(!$blockClicked->isSolid() or Facing::axis($face) === Axis::Y){ return false; } diff --git a/src/block/Wall.php b/src/block/Wall.php index 073a6a2702..b2ca11db98 100644 --- a/src/block/Wall.php +++ b/src/block/Wall.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\ToolTier; +use pocketmine\math\Axis; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; diff --git a/src/block/utils/BlockDataSerializer.php b/src/block/utils/BlockDataSerializer.php index 95849dac22..1459e74f29 100644 --- a/src/block/utils/BlockDataSerializer.php +++ b/src/block/utils/BlockDataSerializer.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block\utils; +use pocketmine\math\Axis; use pocketmine\math\Facing; final class BlockDataSerializer{ @@ -69,14 +70,14 @@ final class BlockDataSerializer{ */ public static function readHorizontalFacing(int $facing) : int{ $facing = self::readFacing($facing); - if(Facing::axis($facing) === Facing::AXIS_Y){ + if(Facing::axis($facing) === Axis::Y){ throw new InvalidBlockStateException("Invalid Y-axis facing $facing"); } return $facing; } public static function writeHorizontalFacing(int $facing) : int{ - if(Facing::axis($facing) === Facing::AXIS_Y){ + if(Facing::axis($facing) === Axis::Y){ throw new \InvalidArgumentException("Invalid Y-axis facing"); } return self::writeFacing($facing); diff --git a/src/block/utils/PillarRotationTrait.php b/src/block/utils/PillarRotationTrait.php index fa7de1a4e1..8685ddb573 100644 --- a/src/block/utils/PillarRotationTrait.php +++ b/src/block/utils/PillarRotationTrait.php @@ -25,6 +25,7 @@ namespace pocketmine\block\utils; use pocketmine\block\Block; use pocketmine\item\Item; +use pocketmine\math\Axis; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -33,7 +34,7 @@ use pocketmine\world\BlockTransaction; trait PillarRotationTrait{ /** @var int */ - protected $axis = Facing::AXIS_Y; + protected $axis = Axis::Y; protected function getAxisMetaShift() : int{ return 2; //default @@ -62,9 +63,9 @@ trait PillarRotationTrait{ protected function readAxisFromMeta(int $meta) : void{ static $map = [ - 0 => Facing::AXIS_Y, - 1 => Facing::AXIS_X, - 2 => Facing::AXIS_Z + 0 => Axis::Y, + 1 => Axis::X, + 2 => Axis::Z ]; $axis = $meta >> $this->getAxisMetaShift(); if(!isset($map[$axis])){ @@ -75,9 +76,9 @@ trait PillarRotationTrait{ protected function writeAxisToMeta() : int{ static $bits = [ - Facing::AXIS_Y => 0, - Facing::AXIS_Z => 2, - Facing::AXIS_X => 1 + Axis::Y => 0, + Axis::Z => 2, + Axis::X => 1 ]; return $bits[$this->axis] << $this->getAxisMetaShift(); } diff --git a/src/item/PaintingItem.php b/src/item/PaintingItem.php index 114a94b1c9..5bbac2d7ba 100644 --- a/src/item/PaintingItem.php +++ b/src/item/PaintingItem.php @@ -27,6 +27,7 @@ use pocketmine\block\Block; use pocketmine\entity\Location; use pocketmine\entity\object\Painting; use pocketmine\entity\object\PaintingMotive; +use pocketmine\math\Axis; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -37,7 +38,7 @@ use function count; class PaintingItem extends Item{ public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ - if(Facing::axis($face) === Facing::AXIS_Y){ + if(Facing::axis($face) === Axis::Y){ return ItemUseResult::NONE(); } From 2545897fc2a373f91df179aa35698eaeb7eb33c9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 Aug 2020 14:53:47 +0100 Subject: [PATCH 1829/3224] HorizontalFacingTrait: use a cheaper check for horizontal facing --- src/block/utils/HorizontalFacingTrait.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/block/utils/HorizontalFacingTrait.php b/src/block/utils/HorizontalFacingTrait.php index 4a68f8a6c4..54cac0cda3 100644 --- a/src/block/utils/HorizontalFacingTrait.php +++ b/src/block/utils/HorizontalFacingTrait.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\block\utils; +use pocketmine\math\Axis; use pocketmine\math\Facing; -use function in_array; trait HorizontalFacingTrait{ /** @var int */ @@ -34,7 +34,8 @@ trait HorizontalFacingTrait{ /** @return $this */ public function setFacing(int $facing) : self{ - if(!in_array($facing, Facing::HORIZONTAL, true)){ + $axis = Facing::axis($facing); + if($axis !== Axis::X && $axis !== Axis::Z){ throw new \InvalidArgumentException("Facing must be horizontal"); } $this->facing = $facing; From ff2a3baa8e5812562728cbeb1c5ac317e71d7d74 Mon Sep 17 00:00:00 2001 From: Jack Honour Date: Fri, 7 Aug 2020 21:07:58 +0100 Subject: [PATCH 1830/3224] Implemented Jukebox & Records (#3742) Co-authored-by: Dylan K. Taylor --- src/block/BlockFactory.php | 2 + src/block/Jukebox.php | 121 ++++++++++++++++++ src/block/VanillaBlocks.php | 2 + src/block/tile/Jukebox.php | 65 ++++++++++ src/block/tile/TileFactory.php | 1 + src/block/utils/RecordType.php | 95 ++++++++++++++ src/item/ItemFactory.php | 26 ++-- src/item/Record.php | 44 +++++++ src/item/VanillaItems.php | 24 ++++ src/network/mcpe/NetworkSession.php | 7 + src/player/Player.php | 9 ++ src/world/sound/RecordSound.php | 42 ++++++ src/world/sound/RecordStopSound.php | 34 +++++ .../block_factory_consistency_check.json | 2 +- 14 files changed, 461 insertions(+), 13 deletions(-) create mode 100644 src/block/Jukebox.php create mode 100644 src/block/tile/Jukebox.php create mode 100644 src/block/utils/RecordType.php create mode 100644 src/item/Record.php create mode 100644 src/world/sound/RecordSound.php create mode 100644 src/world/sound/RecordStopSound.php diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index c9c2fe61d2..d7ec1f88b1 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -39,6 +39,7 @@ use pocketmine\block\tile\FlowerPot as TileFlowerPot; use pocketmine\block\tile\Furnace as TileFurnace; use pocketmine\block\tile\Hopper as TileHopper; use pocketmine\block\tile\ItemFrame as TileItemFrame; +use pocketmine\block\tile\Jukebox as TileJukebox; use pocketmine\block\tile\MonsterSpawner as TileMonsterSpawner; use pocketmine\block\tile\Note as TileNote; use pocketmine\block\tile\Skull as TileSkull; @@ -230,6 +231,7 @@ class BlockFactory{ $this->register(new Opaque(new BID(Ids::IRON_ORE), "Iron Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); $this->register(new Trapdoor(new BID(Ids::IRON_TRAPDOOR), "Iron Trapdoor", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0))); $this->register(new ItemFrame(new BID(Ids::FRAME_BLOCK, 0, ItemIds::FRAME, TileItemFrame::class), "Item Frame")); + $this->register(new Jukebox(new BID(Ids::JUKEBOX, 0, ItemIds::JUKEBOX, TileJukebox::class), "Jukebox")); $this->register(new Ladder(new BID(Ids::LADDER), "Ladder")); $this->register(new Lantern(new BID(Ids::LANTERN), "Lantern", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); $this->register(new Opaque(new BID(Ids::LAPIS_BLOCK), "Lapis Lazuli Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); diff --git a/src/block/Jukebox.php b/src/block/Jukebox.php new file mode 100644 index 0000000000..608e9194c1 --- /dev/null +++ b/src/block/Jukebox.php @@ -0,0 +1,121 @@ +record !== null){ + $this->ejectRecord(); + }elseif($item instanceof Record){ + $player->sendJukeboxPopup("record.nowPlaying", ["%" . $item->getRecordType()->getTranslationKey()]); + $this->insertRecord($item->pop()); + } + } + + $this->pos->getWorld()->setBlock($this->pos, $this); + + return true; + } + + public function getRecord() : ?Record{ + return $this->record; + } + + public function ejectRecord() : void{ + if($this->record !== null){ + $this->getPos()->getWorld()->dropItem($this->getPos()->add(0.5, 1, 0.5), $this->record); + $this->record = null; + $this->stopSound(); + } + } + + public function insertRecord(Record $record) : void{ + if($this->record === null){ + $this->record = $record; + $this->startSound(); + } + } + + public function startSound() : void{ + if($this->record !== null){ + $this->getPos()->getWorld()->addSound($this->getPos(), new RecordSound($this->record->getRecordType())); + } + } + + public function stopSound() : void{ + $this->getPos()->getWorld()->addSound($this->getPos(), new RecordStopSound()); + } + + public function onBreak(Item $item, ?Player $player = null) : bool{ + $this->stopSound(); + return parent::onBreak($item, $player); + } + + public function getDropsForCompatibleTool(Item $item) : array{ + $drops = parent::getDropsForCompatibleTool($item); + if($this->record !== null){ + $drops[] = $this->record; + } + return $drops; + } + + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); + $jukebox = $this->pos->getWorld()->getTile($this->pos); + if($jukebox instanceof JukeboxTile){ + $this->record = $jukebox->getRecord(); + } + } + + public function writeStateToWorld() : void{ + parent::writeStateToWorld(); + $jukebox = $this->pos->getWorld()->getTile($this->pos); + if($jukebox instanceof JukeboxTile){ + $jukebox->setRecord($this->record); + } + } + + //TODO: Jukebox has redstone effects, they are not implemented. +} diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 487d70f0e1..6f7fb15cde 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -397,6 +397,7 @@ use function assert; * @method static Opaque IRON_ORE() * @method static Trapdoor IRON_TRAPDOOR() * @method static ItemFrame ITEM_FRAME() + * @method static Jukebox JUKEBOX() * @method static WoodenButton JUNGLE_BUTTON() * @method static WoodenDoor JUNGLE_DOOR() * @method static WoodenFence JUNGLE_FENCE() @@ -1062,6 +1063,7 @@ final class VanillaBlocks{ self::register("iron_ore", $factory->get(15)); self::register("iron_trapdoor", $factory->get(167)); self::register("item_frame", $factory->get(199)); + self::register("jukebox", $factory->get(84)); self::register("jungle_button", $factory->get(398)); self::register("jungle_door", $factory->get(195)); self::register("jungle_fence", $factory->get(85, 3)); diff --git a/src/block/tile/Jukebox.php b/src/block/tile/Jukebox.php new file mode 100644 index 0000000000..35242ed8d5 --- /dev/null +++ b/src/block/tile/Jukebox.php @@ -0,0 +1,65 @@ +record; + } + + public function setRecord(?Record $record) : void{ + $this->record = $record; + } + + public function readSaveData(CompoundTag $nbt) : void{ + if(($tag = $nbt->getCompoundTag(self::TAG_RECORD)) !== null){ + $record = Item::nbtDeserialize($tag); + if($record instanceof Record){ + $this->record = $record; + } + } + } + + protected function writeSaveData(CompoundTag $nbt) : void{ + if($this->record !== null){ + $nbt->setTag(self::TAG_RECORD, $this->record->nbtSerialize()); + } + } + + protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ + //this is needed for the note particles to show on the client side + if($this->record !== null){ + $nbt->setTag(self::TAG_RECORD, $this->record->nbtSerialize()); + } + } +} diff --git a/src/block/tile/TileFactory.php b/src/block/tile/TileFactory.php index 3036d30798..011f71c887 100644 --- a/src/block/tile/TileFactory.php +++ b/src/block/tile/TileFactory.php @@ -60,6 +60,7 @@ final class TileFactory{ $this->register(Furnace::class, ["Furnace", "minecraft:furnace"]); $this->register(Hopper::class, ["Hopper", "minecraft:hopper"]); $this->register(ItemFrame::class, ["ItemFrame"]); //this is an entity in PC + $this->register(Jukebox::class, ["Jukebox", "RecordPlayer", "minecraft:jukebox"]); $this->register(MonsterSpawner::class, ["MobSpawner", "minecraft:mob_spawner"]); $this->register(Note::class, ["Music", "minecraft:noteblock"]); $this->register(Sign::class, ["Sign", "minecraft:sign"]); diff --git a/src/block/utils/RecordType.php b/src/block/utils/RecordType.php new file mode 100644 index 0000000000..9846e3716e --- /dev/null +++ b/src/block/utils/RecordType.php @@ -0,0 +1,95 @@ +Enum___construct($enumName); + $this->soundName = $soundName; + $this->soundId = $soundId; + $this->translationKey = $translationKey; + } + + public function getSoundName() : string{ + return $this->soundName; + } + + public function getSoundId() : int{ + return $this->soundId; + } + + public function getTranslationKey() : string{ + return $this->translationKey; + } +} diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 479fe661ce..7c3ec826c2 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -26,6 +26,7 @@ namespace pocketmine\item; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\DyeColor; +use pocketmine\block\utils\RecordType; use pocketmine\block\utils\SkullType; use pocketmine\block\utils\TreeType; use pocketmine\block\VanillaBlocks; @@ -215,6 +216,18 @@ class ItemFactory{ $this->register(new RawPorkchop(new ItemIdentifier(ItemIds::RAW_PORKCHOP, 0), "Raw Porkchop")); $this->register(new RawRabbit(new ItemIdentifier(ItemIds::RAW_RABBIT, 0), "Raw Rabbit")); $this->register(new RawSalmon(new ItemIdentifier(ItemIds::RAW_SALMON, 0), "Raw Salmon")); + $this->register(new Record(new ItemIdentifier(ItemIds::RECORD_13, 0), RecordType::DISK_13(), "Record 13")); + $this->register(new Record(new ItemIdentifier(ItemIds::RECORD_CAT, 0), RecordType::DISK_CAT(), "Record Cat")); + $this->register(new Record(new ItemIdentifier(ItemIds::RECORD_BLOCKS, 0), RecordType::DISK_BLOCKS(), "Record Blocks")); + $this->register(new Record(new ItemIdentifier(ItemIds::RECORD_CHIRP, 0), RecordType::DISK_CHIRP(), "Record Chirp")); + $this->register(new Record(new ItemIdentifier(ItemIds::RECORD_FAR, 0), RecordType::DISK_FAR(), "Record Far")); + $this->register(new Record(new ItemIdentifier(ItemIds::RECORD_MALL, 0), RecordType::DISK_MALL(), "Record Mall")); + $this->register(new Record(new ItemIdentifier(ItemIds::RECORD_MELLOHI, 0), RecordType::DISK_MELLOHI(), "Record Mellohi")); + $this->register(new Record(new ItemIdentifier(ItemIds::RECORD_STAL, 0), RecordType::DISK_STAL(), "Record Stal")); + $this->register(new Record(new ItemIdentifier(ItemIds::RECORD_STRAD, 0), RecordType::DISK_STRAD(), "Record Strad")); + $this->register(new Record(new ItemIdentifier(ItemIds::RECORD_WARD, 0), RecordType::DISK_WARD(), "Record Ward")); + $this->register(new Record(new ItemIdentifier(ItemIds::RECORD_11, 0), RecordType::DISK_11(), "Record 11")); + $this->register(new Record(new ItemIdentifier(ItemIds::RECORD_WAIT, 0), RecordType::DISK_WAIT(), "Record Wait")); $this->register(new Redstone(new ItemIdentifier(ItemIds::REDSTONE, 0), "Redstone")); $this->register(new RottenFlesh(new ItemIdentifier(ItemIds::ROTTEN_FLESH, 0), "Rotten Flesh")); $this->register(new Shears(new ItemIdentifier(ItemIds::SHEARS, 0), "Shears")); @@ -294,18 +307,7 @@ class ItemFactory{ //TODO: minecraft:name_tag //TODO: minecraft:phantom_membrane //TODO: minecraft:rapid_fertilizer - //TODO: minecraft:record_11 - //TODO: minecraft:record_13 - //TODO: minecraft:record_blocks - //TODO: minecraft:record_cat - //TODO: minecraft:record_chirp - //TODO: minecraft:record_far - //TODO: minecraft:record_mall - //TODO: minecraft:record_mellohi - //TODO: minecraft:record_stal - //TODO: minecraft:record_strad - //TODO: minecraft:record_wait - //TODO: minecraft:record_ward + //TODO: minecraft:record_pigstep //TODO: minecraft:saddle //TODO: minecraft:shield //TODO: minecraft:sparkler diff --git a/src/item/Record.php b/src/item/Record.php new file mode 100644 index 0000000000..35c56bb675 --- /dev/null +++ b/src/item/Record.php @@ -0,0 +1,44 @@ +recordType = $recordType; + parent::__construct($identifier, $name); + } + + public function getRecordType() : RecordType{ + return $this->recordType; + } + + public function getMaxStackSize() : int{ + return 1; + } +} diff --git a/src/item/VanillaItems.php b/src/item/VanillaItems.php index e44aa31b7d..ba5cd091c8 100644 --- a/src/item/VanillaItems.php +++ b/src/item/VanillaItems.php @@ -247,6 +247,18 @@ use function assert; * @method static RawPorkchop RAW_PORKCHOP() * @method static RawRabbit RAW_RABBIT() * @method static RawSalmon RAW_SALMON() + * @method static Record RECORD_11() + * @method static Record RECORD_13() + * @method static Record RECORD_BLOCKS() + * @method static Record RECORD_CAT() + * @method static Record RECORD_CHIRP() + * @method static Record RECORD_FAR() + * @method static Record RECORD_MALL() + * @method static Record RECORD_MELLOHI() + * @method static Record RECORD_STAL() + * @method static Record RECORD_STRAD() + * @method static Record RECORD_WAIT() + * @method static Record RECORD_WARD() * @method static Banner RED_BANNER() * @method static Bed RED_BED() * @method static Dye RED_DYE() @@ -535,6 +547,18 @@ final class VanillaItems{ self::register("raw_porkchop", $factory->get(319)); self::register("raw_rabbit", $factory->get(411)); self::register("raw_salmon", $factory->get(460)); + self::register("record_11", $factory->get(510)); + self::register("record_13", $factory->get(500)); + self::register("record_blocks", $factory->get(502)); + self::register("record_cat", $factory->get(501)); + self::register("record_chirp", $factory->get(503)); + self::register("record_far", $factory->get(504)); + self::register("record_mall", $factory->get(505)); + self::register("record_mellohi", $factory->get(506)); + self::register("record_stal", $factory->get(507)); + self::register("record_strad", $factory->get(508)); + self::register("record_wait", $factory->get(511)); + self::register("record_ward", $factory->get(509)); self::register("red_banner", $factory->get(446, 1)); self::register("red_bed", $factory->get(355, 14)); self::register("red_dye", $factory->get(351, 1)); diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 71832e7fcf..a8f5e85029 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -792,6 +792,13 @@ class NetworkSession{ $this->sendDataPacket(TextPacket::translation($key, $parameters)); } + /** + * @param string[] $parameters + */ + public function onJukeboxPopup(string $key, array $parameters) : void{ + $this->sendDataPacket(TextPacket::jukeboxPopup($key, $parameters)); + } + public function onPopup(string $message) : void{ $this->sendDataPacket(TextPacket::popup($message)); } diff --git a/src/player/Player.php b/src/player/Player.php index a4fb358b81..c146068ca1 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1851,6 +1851,15 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } } + /** + * @param string[] $args + */ + public function sendJukeboxPopup(string $key, array $args) : void{ + if($this->networkSession !== null){ + $this->networkSession->onJukeboxPopup($key, $args); + } + } + /** * Sends a popup message to the player * diff --git a/src/world/sound/RecordSound.php b/src/world/sound/RecordSound.php new file mode 100644 index 0000000000..1ec5c23ca3 --- /dev/null +++ b/src/world/sound/RecordSound.php @@ -0,0 +1,42 @@ +recordType = $recordType; + } + + public function encode(?Vector3 $pos){ + return LevelSoundEventPacket::create($this->recordType->getSoundId(), $pos); + } +} diff --git a/src/world/sound/RecordStopSound.php b/src/world/sound/RecordStopSound.php new file mode 100644 index 0000000000..b5f87f87f6 --- /dev/null +++ b/src/world/sound/RecordStopSound.php @@ -0,0 +1,34 @@ + Date: Fri, 7 Aug 2020 21:43:19 +0100 Subject: [PATCH 1831/3224] Move code & docblock generation methods out of RegistryTrait this allows generating a docblock / code for a registry without the class needing to exist or be populated yet, which makes code generation significantly less cumbersome. --- src/utils/RegistryTrait.php | 51 ----------------------- src/utils/RegistryUtils.php | 80 +++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 51 deletions(-) create mode 100644 src/utils/RegistryUtils.php diff --git a/src/utils/RegistryTrait.php b/src/utils/RegistryTrait.php index 9be348d686..9aff738f1b 100644 --- a/src/utils/RegistryTrait.php +++ b/src/utils/RegistryTrait.php @@ -112,55 +112,4 @@ trait RegistryTrait{ return self::preprocessMember($o); }, self::$members); } - - /** - * Generates code for static methods for all known registry members. - */ - public static function _generateGetters() : string{ - $lines = []; - - static $fnTmpl = ' -public static function %1$s() : %2$s{ - return self::fromString("%1$s"); -}'; - - foreach(self::_registryGetAll() as $name => $member){ - $lines[] = sprintf($fnTmpl, $name, '\\' . get_class($member)); - } - return "//region auto-generated code\n" . implode("\n", $lines) . "\n\n//endregion\n"; - } - - /** - * Generates a block of @ method annotations for accessors for this registry's known members. - */ - public static function _generateMethodAnnotations() : string{ - $traitName = (new \ReflectionClass(__TRAIT__))->getShortName(); - $fnName = (new \ReflectionMethod(__METHOD__))->getShortName(); - $lines = ["/**"]; - $lines[] = " * This doc-block is generated automatically, do not modify it manually."; - $lines[] = " * This must be regenerated whenever registry members are added, removed or changed."; - $lines[] = " * @see $traitName::$fnName()"; - $lines[] = " *"; - static $lineTmpl = " * @method static %2\$s %s()"; - - $thisNamespace = (new \ReflectionClass(__CLASS__))->getNamespaceName(); - foreach(self::_registryGetAll() as $name => $member){ - $reflect = new \ReflectionClass($member); - while($reflect !== false and $reflect->isAnonymous()){ - $reflect = $reflect->getParentClass(); - } - if($reflect === false){ - $typehint = "object"; - }elseif($reflect->getName() === __CLASS__){ - $typehint = "self"; - }elseif(strpos($reflect->getName(), $thisNamespace) === 0){ - $typehint = substr($reflect->getName(), strlen($thisNamespace . '\\')); - }else{ - $typehint = '\\' . $reflect->getName(); - } - $lines[] = sprintf($lineTmpl, $name, $typehint); - } - $lines[] = " */\n"; - return implode("\n", $lines); - } } diff --git a/src/utils/RegistryUtils.php b/src/utils/RegistryUtils.php new file mode 100644 index 0000000000..12e3a978da --- /dev/null +++ b/src/utils/RegistryUtils.php @@ -0,0 +1,80 @@ + $member){ + $lines[] = sprintf($fnTmpl, mb_strtoupper($name), '\\' . get_class($member)); + } + return "//region auto-generated code\n" . implode("\n", $lines) . "\n\n//endregion\n"; + } + + /** + * Generates a block of @ method annotations for accessors for this registry's known members. + * + * @param object[] $members + */ + public static function _generateMethodAnnotations(string $namespaceName, array $members) : string{ + $selfName = __METHOD__; + $lines = ["/**"]; + $lines[] = " * This doc-block is generated automatically, do not modify it manually."; + $lines[] = " * This must be regenerated whenever registry members are added, removed or changed."; + $lines[] = " * @see \\$selfName()"; + $lines[] = " *"; + + static $lineTmpl = " * @method static %2\$s %s()"; + foreach($members as $name => $member){ + $reflect = new \ReflectionClass($member); + while($reflect !== false and $reflect->isAnonymous()){ + $reflect = $reflect->getParentClass(); + } + if($reflect === false){ + $typehint = "object"; + }elseif($reflect->getNamespaceName() === $namespaceName){ + $typehint = $reflect->getShortName(); + }else{ + $typehint = '\\' . $reflect->getName(); + } + $lines[] = sprintf($lineTmpl, mb_strtoupper($name), $typehint); + } + $lines[] = " */"; + return implode("\n", $lines); + } +} From 6920deac2c8ef09ca781916b2144e99d7bf7d188 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 15 Aug 2020 19:47:38 +0100 Subject: [PATCH 1832/3224] BlockFactory: regenerated TODO lists --- src/block/BlockFactory.php | 105 ++++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 2 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index d7ec1f88b1..85141add38 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -494,7 +494,7 @@ class BlockFactory{ $this->register(new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_LAB_TABLE), "Lab Table", $chemistryTableBreakInfo)); $this->register(new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_MATERIAL_REDUCER), "Material Reducer", $chemistryTableBreakInfo)); - //region --- auto-generated TODOs --- + //region --- auto-generated TODOs for bedrock-1.11.0 --- //TODO: minecraft:bamboo //TODO: minecraft:bamboo_sapling //TODO: minecraft:barrel @@ -526,7 +526,6 @@ class BlockFactory{ //TODO: minecraft:fletching_table //TODO: minecraft:grindstone //TODO: minecraft:jigsaw - //TODO: minecraft:jukebox //TODO: minecraft:kelp //TODO: minecraft:lava_cauldron //TODO: minecraft:lectern @@ -557,6 +556,108 @@ class BlockFactory{ //TODO: minecraft:turtle_egg //TODO: minecraft:undyed_shulker_box //endregion + + //region --- auto-generated TODOs for bedrock-1.13.0 --- + //TODO: minecraft:camera + //TODO: minecraft:light_block + //TODO: minecraft:stickyPistonArmCollision + //TODO: minecraft:structure_void + //TODO: minecraft:wither_rose + //endregion + + //region --- auto-generated TODOs for bedrock-1.14.0 --- + //TODO: minecraft:bee_nest + //TODO: minecraft:beehive + //TODO: minecraft:honey_block + //TODO: minecraft:honeycomb_block + //endregion + + //region --- auto-generated TODOs for bedrock-1.16.0 --- + //TODO: minecraft:allow + //TODO: minecraft:ancient_debris + //TODO: minecraft:basalt + //TODO: minecraft:blackstone + //TODO: minecraft:blackstone_double_slab + //TODO: minecraft:blackstone_slab + //TODO: minecraft:blackstone_stairs + //TODO: minecraft:blackstone_wall + //TODO: minecraft:border_block + //TODO: minecraft:chain + //TODO: minecraft:chiseled_nether_bricks + //TODO: minecraft:chiseled_polished_blackstone + //TODO: minecraft:cracked_nether_bricks + //TODO: minecraft:cracked_polished_blackstone_bricks + //TODO: minecraft:crimson_button + //TODO: minecraft:crimson_door + //TODO: minecraft:crimson_double_slab + //TODO: minecraft:crimson_fence + //TODO: minecraft:crimson_fence_gate + //TODO: minecraft:crimson_fungus + //TODO: minecraft:crimson_hyphae + //TODO: minecraft:crimson_nylium + //TODO: minecraft:crimson_planks + //TODO: minecraft:crimson_pressure_plate + //TODO: minecraft:crimson_roots + //TODO: minecraft:crimson_slab + //TODO: minecraft:crimson_stairs + //TODO: minecraft:crimson_standing_sign + //TODO: minecraft:crimson_stem + //TODO: minecraft:crimson_trapdoor + //TODO: minecraft:crimson_wall_sign + //TODO: minecraft:crying_obsidian + //TODO: minecraft:deny + //TODO: minecraft:gilded_blackstone + //TODO: minecraft:lodestone + //TODO: minecraft:nether_gold_ore + //TODO: minecraft:nether_sprouts + //TODO: minecraft:netherite_block + //TODO: minecraft:polished_basalt + //TODO: minecraft:polished_blackstone + //TODO: minecraft:polished_blackstone_brick_double_slab + //TODO: minecraft:polished_blackstone_brick_slab + //TODO: minecraft:polished_blackstone_brick_stairs + //TODO: minecraft:polished_blackstone_brick_wall + //TODO: minecraft:polished_blackstone_bricks + //TODO: minecraft:polished_blackstone_button + //TODO: minecraft:polished_blackstone_double_slab + //TODO: minecraft:polished_blackstone_pressure_plate + //TODO: minecraft:polished_blackstone_slab + //TODO: minecraft:polished_blackstone_stairs + //TODO: minecraft:polished_blackstone_wall + //TODO: minecraft:quartz_bricks + //TODO: minecraft:respawn_anchor + //TODO: minecraft:shroomlight + //TODO: minecraft:soul_campfire + //TODO: minecraft:soul_fire + //TODO: minecraft:soul_lantern + //TODO: minecraft:soul_soil + //TODO: minecraft:soul_torch + //TODO: minecraft:stripped_crimson_hyphae + //TODO: minecraft:stripped_crimson_stem + //TODO: minecraft:stripped_warped_hyphae + //TODO: minecraft:stripped_warped_stem + //TODO: minecraft:target + //TODO: minecraft:twisting_vines + //TODO: minecraft:warped_button + //TODO: minecraft:warped_door + //TODO: minecraft:warped_double_slab + //TODO: minecraft:warped_fence + //TODO: minecraft:warped_fence_gate + //TODO: minecraft:warped_fungus + //TODO: minecraft:warped_hyphae + //TODO: minecraft:warped_nylium + //TODO: minecraft:warped_planks + //TODO: minecraft:warped_pressure_plate + //TODO: minecraft:warped_roots + //TODO: minecraft:warped_slab + //TODO: minecraft:warped_stairs + //TODO: minecraft:warped_standing_sign + //TODO: minecraft:warped_stem + //TODO: minecraft:warped_trapdoor + //TODO: minecraft:warped_wall_sign + //TODO: minecraft:warped_wart_block + //TODO: minecraft:weeping_vines + //endregion } private function registerElements() : void{ From 93fdc1cb963c7379e181b85c1adeed28c9e7cf4a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 15 Aug 2020 20:23:42 +0100 Subject: [PATCH 1833/3224] Updated composer dependencies --- composer.lock | 442 +++++++++++++++++++++++++++++++------------------- 1 file changed, 277 insertions(+), 165 deletions(-) diff --git a/composer.lock b/composer.lock index 5426d03d34..9162e4b273 100644 --- a/composer.lock +++ b/composer.lock @@ -294,12 +294,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/BinaryUtils.git", - "reference": "f126c8babe63220ca7141ff696761751c19ca756" + "reference": "b7e1b94b8ad6d987224b7770f5d451e2776adccc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/f126c8babe63220ca7141ff696761751c19ca756", - "reference": "f126c8babe63220ca7141ff696761751c19ca756", + "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/b7e1b94b8ad6d987224b7770f5d451e2776adccc", + "reference": "b7e1b94b8ad6d987224b7770f5d451e2776adccc", "shasum": "" }, "require": { @@ -320,7 +320,7 @@ "LGPL-3.0" ], "description": "Classes and methods for conveniently handling binary data", - "time": "2020-06-17T12:14:53+00:00" + "time": "2020-08-01T15:26:01+00:00" }, { "name": "pocketmine/callback-validator", @@ -552,12 +552,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "a7c9da52c7efcd3383073357c10d3a989bfbb3f2" + "reference": "a036719cc0106ca03084211c622d2312d6b70674" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/a7c9da52c7efcd3383073357c10d3a989bfbb3f2", - "reference": "a7c9da52c7efcd3383073357c10d3a989bfbb3f2", + "url": "https://api.github.com/repos/pmmp/Math/zipball/a036719cc0106ca03084211c622d2312d6b70674", + "reference": "a036719cc0106ca03084211c622d2312d6b70674", "shasum": "" }, "require": { @@ -579,7 +579,7 @@ "LGPL-3.0" ], "description": "PHP library containing math related code used in PocketMine-MP", - "time": "2020-08-06T13:19:36+00:00" + "time": "2020-08-06T13:25:43+00:00" }, { "name": "pocketmine/nbt", @@ -587,12 +587,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "b99216a32b96109db8f43c039c2f705c0ecd730a" + "reference": "0248f64793c36bbde9437c8271b75ebdf4a50326" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/b99216a32b96109db8f43c039c2f705c0ecd730a", - "reference": "b99216a32b96109db8f43c039c2f705c0ecd730a", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/0248f64793c36bbde9437c8271b75ebdf4a50326", + "reference": "0248f64793c36bbde9437c8271b75ebdf4a50326", "shasum": "" }, "require": { @@ -601,8 +601,8 @@ "pocketmine/binaryutils": "dev-master" }, "require-dev": { - "irstea/phpunit-shim": "^7.5", - "phpstan/phpstan": "^0.12.11" + "irstea/phpunit-shim": "^7.5 || ^8.0", + "phpstan/phpstan": "^0.12.29" }, "type": "library", "autoload": { @@ -615,7 +615,7 @@ "LGPL-3.0" ], "description": "PHP library for working with Named Binary Tags", - "time": "2020-06-17T13:22:22+00:00" + "time": "2020-08-01T15:53:15+00:00" }, { "name": "pocketmine/raklib", @@ -623,12 +623,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "6fbccdb6a7cf47ebcb411803aa023cf688aae8c7" + "reference": "9e66d5b194d2d483854d791c54409057855810f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/6fbccdb6a7cf47ebcb411803aa023cf688aae8c7", - "reference": "6fbccdb6a7cf47ebcb411803aa023cf688aae8c7", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/9e66d5b194d2d483854d791c54409057855810f3", + "reference": "9e66d5b194d2d483854d791c54409057855810f3", "shasum": "" }, "require": { @@ -654,7 +654,7 @@ "GPL-3.0" ], "description": "A RakNet server implementation written in PHP", - "time": "2020-07-21T12:33:41+00:00" + "time": "2020-08-02T14:51:48+00:00" }, { "name": "pocketmine/snooze", @@ -810,16 +810,16 @@ }, { "name": "respect/validation", - "version": "2.0.13", + "version": "2.0.16", "source": { "type": "git", "url": "https://github.com/Respect/Validation.git", - "reference": "78d1ce404cee8a25e2577ee5b829ee88e7ea1e4a" + "reference": "fc14c6c6695c3f870ad8810a2acddccec015841d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Respect/Validation/zipball/78d1ce404cee8a25e2577ee5b829ee88e7ea1e4a", - "reference": "78d1ce404cee8a25e2577ee5b829ee88e7ea1e4a", + "url": "https://api.github.com/repos/Respect/Validation/zipball/fc14c6c6695c3f870ad8810a2acddccec015841d", + "reference": "fc14c6c6695c3f870ad8810a2acddccec015841d", "shasum": "" }, "require": { @@ -828,7 +828,6 @@ "symfony/polyfill-mbstring": "^1.2" }, "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0", "egulias/email-validator": "^2.1", "malukenho/docheader": "^0.1", "mikey179/vfsstream": "^1.6", @@ -836,7 +835,7 @@ "phpstan/phpstan-deprecation-rules": "^0.11.0", "phpstan/phpstan-phpunit": "^0.11.0", "phpunit/phpunit": "^7.5", - "respect/coding-standard": "^1.0", + "respect/coding-standard": "^2.1", "squizlabs/php_codesniffer": "^3.5", "symfony/validator": "^3.0||^4.0", "zendframework/zend-validator": "^2.1" @@ -872,11 +871,11 @@ "validation", "validator" ], - "time": "2020-07-19T00:20:19+00:00" + "time": "2020-07-25T18:34:16+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.18.0", + "version": "v1.18.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", @@ -1064,29 +1063,82 @@ "time": "2020-06-29T13:22:24+00:00" }, { - "name": "phar-io/manifest", - "version": "1.0.3", + "name": "nikic/php-parser", + "version": "v4.8.0", "source": { "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "8c58eb4cd4f3883f82611abeac2efbc3dbed787e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8c58eb4cd4f3883f82611abeac2efbc3dbed787e", + "reference": "8c58eb4cd4f3883f82611abeac2efbc3dbed787e", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.6", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.8-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "time": "2020-08-09T10:23:20+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", + "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", "shasum": "" }, "require": { "ext-dom": "*", "ext-phar": "*", - "phar-io/version": "^2.0", - "php": "^5.6 || ^7.0" + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -1116,24 +1168,24 @@ } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2018-07-08T19:23:20+00:00" + "time": "2020-06-27T14:33:11+00:00" }, { "name": "phar-io/version", - "version": "2.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" + "reference": "c6bb6825def89e0a32220f88337f8ceaf1975fa0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "url": "https://api.github.com/repos/phar-io/version/zipball/c6bb6825def89e0a32220f88337f8ceaf1975fa0", + "reference": "c6bb6825def89e0a32220f88337f8ceaf1975fa0", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { @@ -1163,7 +1215,7 @@ } ], "description": "Library for handling version information and constraints", - "time": "2018-07-08T19:19:57+00:00" + "time": "2020-06-27T14:39:04+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -1216,16 +1268,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.2.0", + "version": "5.2.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "3170448f5769fe19f456173d833734e0ff1b84df" + "reference": "d870572532cd70bc3fab58f2e23ad423c8404c44" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/3170448f5769fe19f456173d833734e0ff1b84df", - "reference": "3170448f5769fe19f456173d833734e0ff1b84df", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d870572532cd70bc3fab58f2e23ad423c8404c44", + "reference": "d870572532cd70bc3fab58f2e23ad423c8404c44", "shasum": "" }, "require": { @@ -1264,7 +1316,7 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2020-07-20T20:05:34+00:00" + "time": "2020-08-15T11:14:08+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -1432,28 +1484,28 @@ }, { "name": "phpstan/phpstan-phpunit", - "version": "0.12.11", + "version": "0.12.16", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-phpunit.git", - "reference": "ab783a8ea634ea23305a8818c4750603e714489b" + "reference": "1dd916d181b0539dea5cd37e91546afb8b107e17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/ab783a8ea634ea23305a8818c4750603e714489b", - "reference": "ab783a8ea634ea23305a8818c4750603e714489b", + "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/1dd916d181b0539dea5cd37e91546afb8b107e17", + "reference": "1dd916d181b0539dea5cd37e91546afb8b107e17", "shasum": "" }, "require": { - "php": "~7.1", - "phpstan/phpstan": "^0.12.20" + "php": "^7.1 || ^8.0", + "phpstan/phpstan": "^0.12.33" }, "conflict": { "phpunit/phpunit": "<7.0" }, "require-dev": { "consistence/coding-standard": "^3.5", - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "ergebnis/composer-normalize": "^2.0.2", "jakub-onderka/php-parallel-lint": "^1.0", "phing/phing": "^2.16.0", @@ -1484,25 +1536,25 @@ "MIT" ], "description": "PHPUnit extensions and rules for PHPStan", - "time": "2020-06-01T16:43:31+00:00" + "time": "2020-08-05T13:28:50+00:00" }, { "name": "phpstan/phpstan-strict-rules", - "version": "0.12.3", + "version": "0.12.4", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-strict-rules.git", - "reference": "937283265620af9e2005743134ebb4e197b12d8e" + "reference": "9b86e1eb77c796628e239820a01a2d327d607a5e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/937283265620af9e2005743134ebb4e197b12d8e", - "reference": "937283265620af9e2005743134ebb4e197b12d8e", + "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/9b86e1eb77c796628e239820a01a2d327d607a5e", + "reference": "9b86e1eb77c796628e239820a01a2d327d607a5e", "shasum": "" }, "require": { - "php": "~7.1", - "phpstan/phpstan": "^0.12.6" + "php": "^7.1 || ^8.0", + "phpstan/phpstan": "^0.12.33" }, "require-dev": { "consistence/coding-standard": "^3.0.1", @@ -1535,36 +1587,39 @@ "MIT" ], "description": "Extra strict and opinionated rules for PHPStan", - "time": "2020-07-16T08:58:37+00:00" + "time": "2020-07-21T14:49:47+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "8.0.2", + "version": "9.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "ca6647ffddd2add025ab3f21644a441d7c146cdc" + "reference": "4422fca28c3634e2de8c7c373af97a104dd1a45f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca6647ffddd2add025ab3f21644a441d7c146cdc", - "reference": "ca6647ffddd2add025ab3f21644a441d7c146cdc", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4422fca28c3634e2de8c7c373af97a104dd1a45f", + "reference": "4422fca28c3634e2de8c7c373af97a104dd1a45f", "shasum": "" }, "require": { "ext-dom": "*", + "ext-libxml": "*", "ext-xmlwriter": "*", - "php": "^7.3", - "phpunit/php-file-iterator": "^3.0", - "phpunit/php-text-template": "^2.0", - "phpunit/php-token-stream": "^4.0", - "sebastian/code-unit-reverse-lookup": "^2.0", - "sebastian/environment": "^5.0", - "sebastian/version": "^3.0", - "theseer/tokenizer": "^1.1.3" + "nikic/php-parser": "^4.8", + "php": "^7.3 || ^8.0", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "suggest": { "ext-pcov": "*", @@ -1573,7 +1628,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "8.0-dev" + "dev-master": "9.1-dev" } }, "autoload": { @@ -1605,7 +1660,7 @@ "type": "github" } ], - "time": "2020-05-23T08:02:54+00:00" + "time": "2020-08-13T15:04:53+00:00" }, { "name": "phpunit/php-file-iterator", @@ -1665,16 +1720,16 @@ }, { "name": "phpunit/php-invoker", - "version": "3.0.2", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "f6eedfed1085dd1f4c599629459a0277d25f9a66" + "reference": "7a85b66acc48cacffdf87dadd3694e7123674298" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f6eedfed1085dd1f4c599629459a0277d25f9a66", - "reference": "f6eedfed1085dd1f4c599629459a0277d25f9a66", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/7a85b66acc48cacffdf87dadd3694e7123674298", + "reference": "7a85b66acc48cacffdf87dadd3694e7123674298", "shasum": "" }, "require": { @@ -1690,7 +1745,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -1720,7 +1775,7 @@ "type": "github" } ], - "time": "2020-06-26T11:53:53+00:00" + "time": "2020-08-06T07:04:15+00:00" }, { "name": "phpunit/php-text-template", @@ -1832,73 +1887,18 @@ ], "time": "2020-06-26T11:58:13+00:00" }, - { - "name": "phpunit/php-token-stream", - "version": "4.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "5672711b6b07b14d5ab694e700c62eeb82fcf374" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/5672711b6b07b14d5ab694e700c62eeb82fcf374", - "reference": "5672711b6b07b14d5ab694e700c62eeb82fcf374", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-06-27T06:36:25+00:00" - }, { "name": "phpunit/phpunit", - "version": "9.2.6", + "version": "9.3.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "1c6a9e4312e209e659f1fce3ce88dd197c2448f6" + "reference": "c638a0cac77347980352485912de48c99b42ad00" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1c6a9e4312e209e659f1fce3ce88dd197c2448f6", - "reference": "1c6a9e4312e209e659f1fce3ce88dd197c2448f6", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c638a0cac77347980352485912de48c99b42ad00", + "reference": "c638a0cac77347980352485912de48c99b42ad00", "shasum": "" }, "require": { @@ -1909,30 +1909,30 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.9.5", - "phar-io/manifest": "^1.0.3", - "phar-io/version": "^2.0.1", - "php": "^7.3", - "phpspec/prophecy": "^1.10.3", - "phpunit/php-code-coverage": "^8.0.2", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-invoker": "^3.0.2", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.1", + "phar-io/version": "^3.0.2", + "php": "^7.3 || ^8.0", + "phpspec/prophecy": "^1.11.1", + "phpunit/php-code-coverage": "^9.1.1", + "phpunit/php-file-iterator": "^3.0.4", + "phpunit/php-invoker": "^3.1", "phpunit/php-text-template": "^2.0.2", "phpunit/php-timer": "^5.0.1", "sebastian/code-unit": "^1.0.5", "sebastian/comparator": "^4.0.3", - "sebastian/diff": "^4.0.1", + "sebastian/diff": "^4.0.2", "sebastian/environment": "^5.1.2", "sebastian/exporter": "^4.0.2", - "sebastian/global-state": "^4.0", + "sebastian/global-state": "^5.0", "sebastian/object-enumerator": "^4.0.2", "sebastian/resource-operations": "^3.0.2", - "sebastian/type": "^2.1.1", + "sebastian/type": "^2.2.1", "sebastian/version": "^3.0.1" }, "require-dev": { "ext-pdo": "*", - "phpspec/prophecy-phpunit": "^2.0" + "phpspec/prophecy-phpunit": "^2.0.1" }, "suggest": { "ext-soap": "*", @@ -1944,7 +1944,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.2-dev" + "dev-master": "9.3-dev" } }, "autoload": { @@ -1983,7 +1983,7 @@ "type": "github" } ], - "time": "2020-07-13T17:55:55+00:00" + "time": "2020-08-11T15:36:12+00:00" }, { "name": "sebastian/code-unit", @@ -2158,6 +2158,59 @@ ], "time": "2020-06-26T12:05:46+00:00" }, + { + "name": "sebastian/complexity", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "33fcd6a26656c6546f70871244ecba4b4dced097" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/33fcd6a26656c6546f70871244ecba4b4dced097", + "reference": "33fcd6a26656c6546f70871244ecba4b4dced097", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.7", + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-07-25T14:01:34+00:00" + }, { "name": "sebastian/diff", "version": "4.0.2", @@ -2354,26 +2407,26 @@ }, { "name": "sebastian/global-state", - "version": "4.0.0", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bdb1e7c79e592b8c82cb1699be3c8743119b8a72" + "reference": "22ae663c951bdc39da96603edc3239ed3a299097" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bdb1e7c79e592b8c82cb1699be3c8743119b8a72", - "reference": "bdb1e7c79e592b8c82cb1699be3c8743119b8a72", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/22ae663c951bdc39da96603edc3239ed3a299097", + "reference": "22ae663c951bdc39da96603edc3239ed3a299097", "shasum": "" }, "require": { - "php": "^7.3", + "php": "^7.3 || ^8.0", "sebastian/object-reflector": "^2.0", "sebastian/recursion-context": "^4.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "suggest": { "ext-uopz": "*" @@ -2381,7 +2434,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -2404,7 +2457,66 @@ "keywords": [ "global state" ], - "time": "2020-02-07T06:11:37+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-08-07T04:09:03+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "e02bf626f404b5daec382a7b8a6a4456e49017e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e02bf626f404b5daec382a7b8a6a4456e49017e5", + "reference": "e02bf626f404b5daec382a7b8a6a4456e49017e5", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-07-22T18:33:42+00:00" }, { "name": "sebastian/object-enumerator", @@ -2723,7 +2835,7 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.18.0", + "version": "v1.18.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", From ec1adb58869df07c272f42cd16f81d2fec464dae Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 15 Aug 2020 20:24:12 +0100 Subject: [PATCH 1834/3224] Updated build/php submodule to pmmp/php-build-scripts@7a0fbfa9bb9b985cb076266277ab0aca2b55d2f3 --- build/php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/php b/build/php index fadde8d5b2..7a0fbfa9bb 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit fadde8d5b2ee97f41f4647ff2c0a97e8aa9d7af0 +Subproject commit 7a0fbfa9bb9b985cb076266277ab0aca2b55d2f3 From 050690587521a033980410787f5082116e382f5f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 16 Aug 2020 00:58:55 +0100 Subject: [PATCH 1835/3224] clean up unused imports --- src/utils/RegistryTrait.php | 6 ------ src/utils/RegistryUtils.php | 3 +++ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/utils/RegistryTrait.php b/src/utils/RegistryTrait.php index 9aff738f1b..31c2116f10 100644 --- a/src/utils/RegistryTrait.php +++ b/src/utils/RegistryTrait.php @@ -25,13 +25,7 @@ namespace pocketmine\utils; use function array_map; use function count; -use function get_class; -use function implode; use function mb_strtoupper; -use function sprintf; -use function strlen; -use function strpos; -use function substr; trait RegistryTrait{ /** @var object[] */ diff --git a/src/utils/RegistryUtils.php b/src/utils/RegistryUtils.php index 12e3a978da..3394f2b9f5 100644 --- a/src/utils/RegistryUtils.php +++ b/src/utils/RegistryUtils.php @@ -23,7 +23,10 @@ declare(strict_types=1); namespace pocketmine\utils; +use function get_class; +use function implode; use function mb_strtoupper; +use function sprintf; final class RegistryUtils{ From bf401421fa2dfff4de89ebddfce6aedd37836ae6 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Sun, 16 Aug 2020 20:39:51 +0100 Subject: [PATCH 1836/3224] Implemented bamboo (#3762) --- src/block/Bamboo.php | 235 ++++++++++++++++++ src/block/BambooSapling.php | 123 +++++++++ src/block/Block.php | 12 +- src/block/BlockFactory.php | 2 + src/block/VanillaBlocks.php | 7 +- src/item/Bamboo.php | 38 +++ src/item/ItemFactory.php | 1 + .../block_factory_consistency_check.json | 2 +- 8 files changed, 416 insertions(+), 4 deletions(-) create mode 100644 src/block/Bamboo.php create mode 100644 src/block/BambooSapling.php create mode 100644 src/item/Bamboo.php diff --git a/src/block/Bamboo.php b/src/block/Bamboo.php new file mode 100644 index 0000000000..c1848cf229 --- /dev/null +++ b/src/block/Bamboo.php @@ -0,0 +1,235 @@ +thick = ($stateMeta & BlockLegacyMetadata::BAMBOO_FLAG_THICK) !== 0; + $this->leafSize = BlockDataSerializer::readBoundedInt("leafSize", ($stateMeta >> BlockLegacyMetadata::BAMBOO_LEAF_SIZE_SHIFT) & BlockLegacyMetadata::BAMBOO_LEAF_SIZE_MASK, self::NO_LEAVES, self::LARGE_LEAVES); + $this->ready = ($stateMeta & BlockLegacyMetadata::BAMBOO_FLAG_READY) !== 0; + } + + public function writeStateToMeta() : int{ + return ($this->thick ? BlockLegacyMetadata::BAMBOO_FLAG_THICK : 0) | ($this->leafSize << BlockLegacyMetadata::BAMBOO_LEAF_SIZE_SHIFT) | ($this->ready ? BlockLegacyMetadata::BAMBOO_FLAG_READY : 0); + } + + public function getStateBitmask() : int{ + return 0b1111; + } + + public function isThick() : bool{ return $this->thick; } + + /** @return $this */ + public function setThick(bool $thick) : self{ + $this->thick = $thick; + return $this; + } + + public function isReady() : bool{ return $this->ready; } + + /** @return $this */ + public function setReady(bool $ready) : self{ + $this->ready = $ready; + return $this; + } + + public function getLeafSize() : int{ return $this->leafSize; } + + /** @return $this */ + public function setLeafSize(int $leafSize) : self{ + $this->leafSize = $leafSize; + return $this; + } + + /** + * @return AxisAlignedBB[] + */ + protected function recalculateCollisionBoxes() : array{ + //this places the BB at the northwest corner, not the center + $inset = 1 - (($this->thick ? 3 : 2) / 16); + return [AxisAlignedBB::one()->trim(Facing::SOUTH, $inset)->trim(Facing::EAST, $inset)]; + } + + private static function getOffsetSeed(int $x, int $y, int $z) : int{ + $p1 = gmp_mul($z, 0x6ebfff5); + $p2 = gmp_mul($x, 0x2fc20f); + $p3 = $y; + + $xord = gmp_xor(gmp_xor($p1, $p2), $p3); + + $fullResult = gmp_mul(gmp_add(gmp_mul($xord, 0x285b825), 0xb), $xord); + return gmp_intval(gmp_and($fullResult, 0xffffffff)); + } + + private static function getMaxHeight(int $x, int $z) : int{ + return 12 + (self::getOffsetSeed($x, 0, $z) % 5); + } + + public function getPosOffset() : ?Vector3{ + $seed = self::getOffsetSeed($this->pos->getFloorX(), 0, $this->pos->getFloorZ()); + $retX = (($seed % 12) + 1) / 16; + $retZ = ((($seed >> 8) % 12) + 1) / 16; + return new Vector3($retX, 0, $retZ); + } + + private function canBeSupportedBy(Block $block) : bool{ + //TODO: tags would be better for this + return + $block instanceof Dirt || + $block instanceof Grass || + $block instanceof Gravel || + $block instanceof Sand || + $block instanceof Mycelium || + $block instanceof Podzol; + } + + private function seekToTop() : Bamboo{ + $world = $this->pos->getWorld(); + $top = $this; + while(($next = $world->getBlock($top->pos->up())) instanceof Bamboo && $next->isSameType($this)){ + $top = $next; + } + return $top; + } + + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($item instanceof Fertilizer){ + $top = $this->seekToTop(); + if($top->grow(self::getMaxHeight($top->pos->getFloorX(), $top->pos->getFloorZ()), mt_rand(1, 2))){ + $item->pop(); + return true; + } + }elseif($item instanceof ItemBamboo){ + if($this->seekToTop()->grow(PHP_INT_MAX, 1)){ + $item->pop(); + return true; + } + } + return false; + } + + public function onNearbyBlockChange() : void{ + $below = $this->pos->getWorld()->getBlock($this->pos->down()); + if(!$this->canBeSupportedBy($below) and !$below->isSameType($this)){ + $this->pos->getWorld()->useBreakOn($this->pos); + } + } + + private function grow(int $maxHeight, int $growAmount) : bool{ + $world = $this->pos->getWorld(); + if(!$world->getBlock($this->pos->up())->canBeReplaced()){ + return false; + } + + $height = 1; + while($world->getBlock($this->pos->subtract(0, $height, 0))->isSameType($this)){ + if(++$height >= $maxHeight){ + return false; + } + } + + $newHeight = $height + $growAmount; + + $stemBlock = (clone $this)->setReady(false)->setLeafSize(self::NO_LEAVES); + if($newHeight >= 4 && !$stemBlock->isThick()){ //don't change it to false if height is less, because it might have been chopped + $stemBlock = $stemBlock->setThick(true); + } + $smallLeavesBlock = (clone $stemBlock)->setLeafSize(self::SMALL_LEAVES); + $bigLeavesBlock = (clone $stemBlock)->setLeafSize(self::LARGE_LEAVES); + + $newBlocks = []; + if($newHeight === 2){ + $newBlocks[] = $smallLeavesBlock; + }elseif($newHeight === 3){ + $newBlocks[] = $smallLeavesBlock; + $newBlocks[] = $smallLeavesBlock; + }elseif($newHeight === 4){ + $newBlocks[] = $bigLeavesBlock; + $newBlocks[] = $smallLeavesBlock; + $newBlocks[] = $stemBlock; + $newBlocks[] = $stemBlock; + }elseif($newHeight > 4){ + $newBlocks[] = $bigLeavesBlock; + $newBlocks[] = $bigLeavesBlock; + $newBlocks[] = $smallLeavesBlock; + for($i = 0, $max = min($growAmount, $newHeight - count($newBlocks)); $i < $max; ++$i){ + $newBlocks[] = $stemBlock; //to replace the bottom blocks that currently have leaves + } + } + + $tx = new BlockTransaction($this->pos->getWorld()); + foreach($newBlocks as $idx => $newBlock){ + $tx->addBlock($this->pos->subtract(0, $idx - $growAmount, 0), $newBlock); + } + return $tx->apply(); + } + + public function ticksRandomly() : bool{ + return true; + } + + public function onRandomTick() : void{ + $world = $this->pos->getWorld(); + if($this->ready){ + $this->ready = false; + if($world->getFullLight($this->pos) < 9 || !$this->grow(self::getMaxHeight($this->pos->getFloorX(), $this->pos->getFloorZ()), 1)){ + $world->setBlock($this->pos, $this); + } + }elseif($world->getBlock($this->pos->up())->canBeReplaced()){ + $this->ready = true; + $world->setBlock($this->pos, $this); + } + } +} diff --git a/src/block/BambooSapling.php b/src/block/BambooSapling.php new file mode 100644 index 0000000000..880e4349c7 --- /dev/null +++ b/src/block/BambooSapling.php @@ -0,0 +1,123 @@ +ready = ($stateMeta & BlockLegacyMetadata::SAPLING_FLAG_READY) !== 0; + } + + protected function writeStateToMeta() : int{ + return $this->ready ? BlockLegacyMetadata::SAPLING_FLAG_READY : 0; + } + + public function getStateBitmask() : int{ return 0b1000; } + + public function isReady() : bool{ return $this->ready; } + + /** @return $this */ + public function setReady(bool $ready) : self{ + $this->ready = $ready; + return $this; + } + + private function canBeSupportedBy(Block $block) : bool{ + //TODO: tags would be better for this + return + $block instanceof Dirt || + $block instanceof Grass || + $block instanceof Gravel || + $block instanceof Sand || + $block instanceof Mycelium || + $block instanceof Podzol; + } + + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if(!$this->canBeSupportedBy($blockReplace->pos->getWorld()->getBlock($blockReplace->pos->down()))){ + return false; + } + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($item instanceof Fertilizer || $item instanceof ItemBamboo){ + if($this->grow()){ + $item->pop(); + return true; + } + } + return false; + } + + public function onNearbyBlockChange() : void{ + if(!$this->canBeSupportedBy($this->pos->getWorld()->getBlock($this->pos->down()))){ + $this->pos->getWorld()->useBreakOn($this->pos); + } + } + + private function grow() : bool{ + $world = $this->pos->getWorld(); + if(!$world->getBlock($this->pos->up())->canBeReplaced()){ + return false; + } + + $tx = new BlockTransaction($world); + $bamboo = VanillaBlocks::BAMBOO(); + $tx->addBlock($this->pos, $bamboo) + ->addBlock($this->pos->up(), (clone $bamboo)->setLeafSize(Bamboo::SMALL_LEAVES)); + return $tx->apply(); + } + + public function ticksRandomly() : bool{ + return true; + } + + public function onRandomTick() : void{ + $world = $this->pos->getWorld(); + if($this->ready){ + $this->ready = false; + if($world->getFullLight($this->pos) < 9 || !$this->grow()){ + $world->setBlock($this->pos, $this); + } + }elseif($world->getBlock($this->pos->up())->canBeReplaced()){ + $this->ready = true; + $world->setBlock($this->pos, $this); + } + } + + public function asItem() : Item{ + return VanillaBlocks::BAMBOO()->asItem(); + } +} diff --git a/src/block/Block.php b/src/block/Block.php index f48ed982d7..ee07c9c4b9 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -547,14 +547,24 @@ class Block{ final public function getCollisionBoxes() : array{ if($this->collisionBoxes === null){ $this->collisionBoxes = $this->recalculateCollisionBoxes(); + $extraOffset = $this->getPosOffset(); + $offset = $extraOffset !== null ? $this->pos->addVector($extraOffset) : $this->pos; foreach($this->collisionBoxes as $bb){ - $bb->offset($this->pos->x, $this->pos->y, $this->pos->z); + $bb->offset($offset->x, $offset->y, $offset->z); } } return $this->collisionBoxes; } + /** + * Returns an additional fractional vector to shift the block's effective position by based on the current position. + * Used to randomize position of things like bamboo canes and tall grass. + */ + public function getPosOffset() : ?Vector3{ + return null; + } + /** * @return AxisAlignedBB[] */ diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 85141add38..6951c52a21 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -97,6 +97,8 @@ class BlockFactory{ $this->register(new Anvil(new BID(Ids::ANVIL, Meta::ANVIL_NORMAL), "Anvil")); $this->register(new Anvil(new BID(Ids::ANVIL, Meta::ANVIL_SLIGHTLY_DAMAGED), "Slightly Damaged Anvil")); $this->register(new Anvil(new BID(Ids::ANVIL, Meta::ANVIL_VERY_DAMAGED), "Very Damaged Anvil")); + $this->register(new Bamboo(new BID(Ids::BAMBOO), "Bamboo", new BlockBreakInfo(2.0 /* 1.0 in PC */, BlockToolType::AXE))); + $this->register(new BambooSapling(new BID(Ids::BAMBOO_SAPLING), "Bamboo Sapling", BlockBreakInfo::instant())); $this->register(new Banner(new BIDFlattened(Ids::STANDING_BANNER, Ids::WALL_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Banner")); $this->register(new Transparent(new BID(Ids::BARRIER), "Barrier", BlockBreakInfo::indestructible())); $this->register(new Bed(new BID(Ids::BED_BLOCK, 0, ItemIds::BED, TileBed::class), "Bed Block")); diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 6f7fb15cde..8aa8a188de 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -24,13 +24,12 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\utils\CloningRegistryTrait; -use pocketmine\utils\RegistryTrait; use function assert; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see RegistryTrait::_generateMethodAnnotations() + * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * * @method static WoodenButton ACACIA_BUTTON() * @method static WoodenDoor ACACIA_DOOR() @@ -55,6 +54,8 @@ use function assert; * @method static Wall ANDESITE_WALL() * @method static Anvil ANVIL() * @method static Flower AZURE_BLUET() + * @method static Bamboo BAMBOO() + * @method static BambooSapling BAMBOO_SAPLING() * @method static Banner BANNER() * @method static Transparent BARRIER() * @method static Bed BED() @@ -721,6 +722,8 @@ final class VanillaBlocks{ self::register("andesite_wall", $factory->get(139, 4)); self::register("anvil", $factory->get(145)); self::register("azure_bluet", $factory->get(38, 3)); + self::register("bamboo", $factory->get(418)); + self::register("bamboo_sapling", $factory->get(419)); self::register("banner", $factory->get(176)); self::register("barrier", $factory->get(416)); self::register("bed", $factory->get(26)); diff --git a/src/item/Bamboo.php b/src/item/Bamboo.php new file mode 100644 index 0000000000..96103d0581 --- /dev/null +++ b/src/item/Bamboo.php @@ -0,0 +1,38 @@ +register(new Arrow(new ItemIdentifier(ItemIds::ARROW, 0), "Arrow")); $this->register(new BakedPotato(new ItemIdentifier(ItemIds::BAKED_POTATO, 0), "Baked Potato")); + $this->register(new Bamboo(new ItemIdentifier(ItemIds::BAMBOO, 0), "Bamboo"), true); $this->register(new Beetroot(new ItemIdentifier(ItemIds::BEETROOT, 0), "Beetroot")); $this->register(new BeetrootSeeds(new ItemIdentifier(ItemIds::BEETROOT_SEEDS, 0), "Beetroot Seeds")); $this->register(new BeetrootSoup(new ItemIdentifier(ItemIds::BEETROOT_SOUP, 0), "Beetroot Soup")); diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 8c2681befe..47a3f148af 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From 40d49b88dd24c23937bc9311897f7549492143fc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 17 Aug 2020 13:20:34 +0100 Subject: [PATCH 1837/3224] EntityFactory: remove requirement for $className as return type on creation funcs since the removal of EntityFactory::create() this isn't needed anymore, since these creation functions are only used for creating entities loaded from disk. --- src/entity/EntityFactory.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index a032c088fa..060e152da8 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -161,12 +161,11 @@ final class EntityFactory{ } /** - * @phpstan-param class-string $baseClass * @phpstan-param \Closure(World, CompoundTag) : Entity $creationFunc */ - private static function validateCreationFunc(string $baseClass, \Closure $creationFunc) : void{ + private static function validateCreationFunc(\Closure $creationFunc) : void{ $sig = new CallbackType( - new ReturnType($baseClass), + new ReturnType(Entity::class), new ParameterType("world", World::class), new ParameterType("nbt", CompoundTag::class) ); @@ -193,7 +192,7 @@ final class EntityFactory{ throw new \InvalidArgumentException("At least one save name must be provided"); } Utils::testValidInstance($className, Entity::class); - self::validateCreationFunc($className, $creationFunc); + self::validateCreationFunc($creationFunc); foreach($saveNames as $name){ $this->creationFuncs[$name] = $creationFunc; From ddc5694b7067fbd3db3fb935e53122f4e23b942d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 17 Aug 2020 20:25:30 +0100 Subject: [PATCH 1838/3224] remove file accidentally committed in 0b05fd198733ac5d4eebf4cfa720c63a9efa070b --- src/block/utils/BlockStateBinaryEncoder.php | 28 --------------------- 1 file changed, 28 deletions(-) delete mode 100644 src/block/utils/BlockStateBinaryEncoder.php diff --git a/src/block/utils/BlockStateBinaryEncoder.php b/src/block/utils/BlockStateBinaryEncoder.php deleted file mode 100644 index 27b0510831..0000000000 --- a/src/block/utils/BlockStateBinaryEncoder.php +++ /dev/null @@ -1,28 +0,0 @@ - Date: Fri, 21 Aug 2020 17:46:44 +0100 Subject: [PATCH 1839/3224] BlockLegacyMetadata: added some coral constants --- src/block/BlockLegacyMetadata.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/block/BlockLegacyMetadata.php b/src/block/BlockLegacyMetadata.php index 91f85e0eba..b04d8278de 100644 --- a/src/block/BlockLegacyMetadata.php +++ b/src/block/BlockLegacyMetadata.php @@ -63,6 +63,25 @@ final class BlockLegacyMetadata{ public const COLORED_TORCH_RG_RED = 0; public const COLORED_TORCH_RG_GREEN = 8; + public const CORAL_BLOCK_FLAG_DEAD = 0x8; + + public const CORAL_FAN_EAST_WEST = 0; + public const CORAL_FAN_NORTH_SOUTH = 1; + + public const CORAL_FAN_HANG_FLAG_DEAD = 0x2; + + public const CORAL_FAN_HANG_TUBE = 0; + public const CORAL_FAN_HANG_BRAIN = 1; + public const CORAL_FAN_HANG2_BUBBLE = 0; + public const CORAL_FAN_HANG2_FIRE = 1; + public const CORAL_FAN_HANG3_HORN = 0; + + public const CORAL_VARIANT_TUBE = 0; + public const CORAL_VARIANT_BRAIN = 1; + public const CORAL_VARIANT_BUBBLE = 2; + public const CORAL_VARIANT_FIRE = 3; + public const CORAL_VARIANT_HORN = 4; + public const DIRT_NORMAL = 0; public const DIRT_COARSE = 1; From 4ed59ea43f0188fe4e50a90876f0a5ba3f191a86 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 21 Aug 2020 21:46:28 +0100 Subject: [PATCH 1840/3224] updated DevTools submodule to pmmp/DevTools@75c2774cc76ab51b2fa35419dd37802970cdcd8f --- tests/plugins/DevTools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/plugins/DevTools b/tests/plugins/DevTools index 5d02f043be..75c2774cc7 160000 --- a/tests/plugins/DevTools +++ b/tests/plugins/DevTools @@ -1 +1 @@ -Subproject commit 5d02f043bec539cca41cf4eb3c774fbe8e0629e8 +Subproject commit 75c2774cc76ab51b2fa35419dd37802970cdcd8f From 220c6dd41b037546cf1f7a549dab491444fc808c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 21 Aug 2020 22:13:46 +0100 Subject: [PATCH 1841/3224] Updated composer dependencies --- composer.lock | 77 ++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/composer.lock b/composer.lock index 9162e4b273..45d38e3a3a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a518c2e67a38a7f2e4b5de64b602a8e2", + "content-hash": "f76900efadf8b19b39bbef9b1382851a", "packages": [ { "name": "adhocore/json-comment", @@ -324,16 +324,16 @@ }, { "name": "pocketmine/callback-validator", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", - "url": "https://github.com/pmmp/CallbackValidator.git", - "reference": "4aef6bb25f97d0b830ba0b4f66834b1a9c86fc9a" + "url": "git@github.com:pmmp/CallbackValidator.git", + "reference": "8321aa3ccfe63639b0d08f0cbf270755cfc99fe2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/CallbackValidator/zipball/4aef6bb25f97d0b830ba0b4f66834b1a9c86fc9a", - "reference": "4aef6bb25f97d0b830ba0b4f66834b1a9c86fc9a", + "url": "https://api.github.com/repos/pmmp/CallbackValidator/zipball/8321aa3ccfe63639b0d08f0cbf270755cfc99fe2", + "reference": "8321aa3ccfe63639b0d08f0cbf270755cfc99fe2", "shasum": "" }, "require": { @@ -344,6 +344,9 @@ "daverandom/callback-validator": "*" }, "require-dev": { + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "0.12.38", + "phpstan/phpstan-strict-rules": "^0.12.4", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.0" }, "type": "library", @@ -363,7 +366,7 @@ } ], "description": "Fork of daverandom/callback-validator - Tools for validating callback signatures", - "time": "2020-03-17T12:04:22+00:00" + "time": "2020-08-21T19:51:42+00:00" }, { "name": "pocketmine/classloader", @@ -371,12 +374,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/ClassLoader.git", - "reference": "70ab2a59217c4ebd33a58388ce87c86d770edfc3" + "reference": "a9e7f20efc7af2ecb6c5d3a29b9ce53e5bdcb7a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/70ab2a59217c4ebd33a58388ce87c86d770edfc3", - "reference": "70ab2a59217c4ebd33a58388ce87c86d770edfc3", + "url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/a9e7f20efc7af2ecb6c5d3a29b9ce53e5bdcb7a4", + "reference": "a9e7f20efc7af2ecb6c5d3a29b9ce53e5bdcb7a4", "shasum": "" }, "require": { @@ -388,7 +391,7 @@ "pocketmine/spl": "<0.4" }, "require-dev": { - "phpstan/phpstan": "^0.12.8" + "phpstan/phpstan": "0.12.38" }, "type": "library", "autoload": { @@ -401,7 +404,7 @@ "LGPL-3.0" ], "description": "Ad-hoc autoloading components used by PocketMine-MP", - "time": "2020-01-31T14:26:22+00:00" + "time": "2020-08-21T17:22:02+00:00" }, { "name": "pocketmine/color", @@ -552,12 +555,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "a036719cc0106ca03084211c622d2312d6b70674" + "reference": "5e34660aaf7d6d13ec5b8d0c9f7675b49bed5903" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/a036719cc0106ca03084211c622d2312d6b70674", - "reference": "a036719cc0106ca03084211c622d2312d6b70674", + "url": "https://api.github.com/repos/pmmp/Math/zipball/5e34660aaf7d6d13ec5b8d0c9f7675b49bed5903", + "reference": "5e34660aaf7d6d13ec5b8d0c9f7675b49bed5903", "shasum": "" }, "require": { @@ -566,7 +569,7 @@ }, "require-dev": { "irstea/phpunit-shim": "^7.5", - "phpstan/phpstan": "^0.12.25" + "phpstan/phpstan": "0.12.37" }, "type": "library", "autoload": { @@ -579,7 +582,7 @@ "LGPL-3.0" ], "description": "PHP library containing math related code used in PocketMine-MP", - "time": "2020-08-06T13:25:43+00:00" + "time": "2020-08-16T18:42:45+00:00" }, { "name": "pocketmine/nbt", @@ -587,12 +590,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "0248f64793c36bbde9437c8271b75ebdf4a50326" + "reference": "590733fbaa40efe210e00ca8207489a528b6ecc5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/0248f64793c36bbde9437c8271b75ebdf4a50326", - "reference": "0248f64793c36bbde9437c8271b75ebdf4a50326", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/590733fbaa40efe210e00ca8207489a528b6ecc5", + "reference": "590733fbaa40efe210e00ca8207489a528b6ecc5", "shasum": "" }, "require": { @@ -615,7 +618,7 @@ "LGPL-3.0" ], "description": "PHP library for working with Named Binary Tags", - "time": "2020-08-01T15:53:15+00:00" + "time": "2020-08-17T16:36:10+00:00" }, { "name": "pocketmine/raklib", @@ -623,12 +626,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "9e66d5b194d2d483854d791c54409057855810f3" + "reference": "d20db2fc790d1a45492455ae0be4d9f59d56d45e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/9e66d5b194d2d483854d791c54409057855810f3", - "reference": "9e66d5b194d2d483854d791c54409057855810f3", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/d20db2fc790d1a45492455ae0be4d9f59d56d45e", + "reference": "d20db2fc790d1a45492455ae0be4d9f59d56d45e", "shasum": "" }, "require": { @@ -654,7 +657,7 @@ "GPL-3.0" ], "description": "A RakNet server implementation written in PHP", - "time": "2020-08-02T14:51:48+00:00" + "time": "2020-08-21T21:03:31+00:00" }, { "name": "pocketmine/snooze", @@ -1064,16 +1067,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.8.0", + "version": "v4.9.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "8c58eb4cd4f3883f82611abeac2efbc3dbed787e" + "reference": "aaee038b912e567780949787d5fe1977be11a778" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8c58eb4cd4f3883f82611abeac2efbc3dbed787e", - "reference": "8c58eb4cd4f3883f82611abeac2efbc3dbed787e", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/aaee038b912e567780949787d5fe1977be11a778", + "reference": "aaee038b912e567780949787d5fe1977be11a778", "shasum": "" }, "require": { @@ -1081,7 +1084,7 @@ "php": ">=7.0" }, "require-dev": { - "ircmaxell/php-yacc": "^0.0.6", + "ircmaxell/php-yacc": "^0.0.7", "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" }, "bin": [ @@ -1090,7 +1093,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.8-dev" + "dev-master": "4.9-dev" } }, "autoload": { @@ -1112,7 +1115,7 @@ "parser", "php" ], - "time": "2020-08-09T10:23:20+00:00" + "time": "2020-08-18T19:48:01+00:00" }, { "name": "phar-io/manifest", @@ -1428,16 +1431,16 @@ }, { "name": "phpstan/phpstan", - "version": "0.12.36", + "version": "0.12.37", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "eaeff985e395ff4e7aebf3251a43fca6c9be1af3" + "reference": "5e16d83e6eb2dd784fbdaeaece5e2bca72e4f68a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/eaeff985e395ff4e7aebf3251a43fca6c9be1af3", - "reference": "eaeff985e395ff4e7aebf3251a43fca6c9be1af3", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/5e16d83e6eb2dd784fbdaeaece5e2bca72e4f68a", + "reference": "5e16d83e6eb2dd784fbdaeaece5e2bca72e4f68a", "shasum": "" }, "require": { @@ -1480,7 +1483,7 @@ "type": "tidelift" } ], - "time": "2020-08-05T09:29:40+00:00" + "time": "2020-08-09T14:32:41+00:00" }, { "name": "phpstan/phpstan-phpunit", From e87760c218e493784b5e67c8b57ff016baa2c048 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 4 Sep 2020 01:05:48 +0100 Subject: [PATCH 1842/3224] composer: do not install packages with min version higher than 7.3.0 running composer update on 7.4 will generate a lock file using the newest dependencies which work for the current PHP version, which usually isn't desirable for a project like this where developers might be using newer PHP versions than users. --- composer.json | 5 ++ composer.lock | 210 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 144 insertions(+), 71 deletions(-) diff --git a/composer.json b/composer.json index f500c51ac3..6ccdacf4ee 100644 --- a/composer.json +++ b/composer.json @@ -68,5 +68,10 @@ "pocketmine\\": "tests/phpunit/", "pocketmine\\phpstan\\rules\\": "tests/phpstan/rules" } + }, + "config": { + "platform": { + "php": "7.3.0" + } } } diff --git a/composer.lock b/composer.lock index 6ed7bbe460..edd142f56f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7ec1bf61515c3b157a1347560b551826", + "content-hash": "3a8f754965da97b4e3237fd32168a6aa", "packages": [ { "name": "adhocore/json-comment", @@ -294,12 +294,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/BinaryUtils.git", - "reference": "b7e1b94b8ad6d987224b7770f5d451e2776adccc" + "reference": "0e25f4baab948cfb88de94375d04df20330957d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/b7e1b94b8ad6d987224b7770f5d451e2776adccc", - "reference": "b7e1b94b8ad6d987224b7770f5d451e2776adccc", + "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/0e25f4baab948cfb88de94375d04df20330957d7", + "reference": "0e25f4baab948cfb88de94375d04df20330957d7", "shasum": "" }, "require": { @@ -307,7 +307,9 @@ "php-64bit": "*" }, "require-dev": { - "phpstan/phpstan": "^0.12.8" + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "0.12.40", + "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", "autoload": { @@ -320,7 +322,7 @@ "LGPL-3.0" ], "description": "Classes and methods for conveniently handling binary data", - "time": "2020-08-01T15:26:01+00:00" + "time": "2020-08-28T20:45:19+00:00" }, { "name": "pocketmine/callback-validator", @@ -374,12 +376,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/ClassLoader.git", - "reference": "a9e7f20efc7af2ecb6c5d3a29b9ce53e5bdcb7a4" + "reference": "14871a77ac5a7c4c0571391ad404b89bc15a3513" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/a9e7f20efc7af2ecb6c5d3a29b9ce53e5bdcb7a4", - "reference": "a9e7f20efc7af2ecb6c5d3a29b9ce53e5bdcb7a4", + "url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/14871a77ac5a7c4c0571391ad404b89bc15a3513", + "reference": "14871a77ac5a7c4c0571391ad404b89bc15a3513", "shasum": "" }, "require": { @@ -391,7 +393,9 @@ "pocketmine/spl": "<0.4" }, "require-dev": { - "phpstan/phpstan": "0.12.38" + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "0.12.40", + "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", "autoload": { @@ -404,7 +408,7 @@ "LGPL-3.0" ], "description": "Ad-hoc autoloading components used by PocketMine-MP", - "time": "2020-08-21T17:22:02+00:00" + "time": "2020-08-27T11:43:41+00:00" }, { "name": "pocketmine/color", @@ -480,12 +484,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Log.git", - "reference": "23895dce020076e0217b2fbee50b39f523080b4f" + "reference": "cfac4a3ba23efa2f94802868787cf6f449255082" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Log/zipball/23895dce020076e0217b2fbee50b39f523080b4f", - "reference": "23895dce020076e0217b2fbee50b39f523080b4f", + "url": "https://api.github.com/repos/pmmp/Log/zipball/cfac4a3ba23efa2f94802868787cf6f449255082", + "reference": "cfac4a3ba23efa2f94802868787cf6f449255082", "shasum": "" }, "require": { @@ -495,7 +499,7 @@ "pocketmine/spl": "<0.4" }, "require-dev": { - "phpstan/phpstan": "^0.12.8", + "phpstan/phpstan": "0.12.40", "phpstan/phpstan-strict-rules": "^0.12.2" }, "type": "library", @@ -509,7 +513,7 @@ "LGPL-3.0" ], "description": "Logging components used by PocketMine-MP and related projects", - "time": "2020-03-31T17:06:15+00:00" + "time": "2020-08-28T20:50:44+00:00" }, { "name": "pocketmine/log-pthreads", @@ -517,12 +521,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/LogPthreads.git", - "reference": "88ea500715908dfc5c99a0bbde8e823bae0534df" + "reference": "343333f45a1041641de36d9f9285fbc5349a2571" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/88ea500715908dfc5c99a0bbde8e823bae0534df", - "reference": "88ea500715908dfc5c99a0bbde8e823bae0534df", + "url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/343333f45a1041641de36d9f9285fbc5349a2571", + "reference": "343333f45a1041641de36d9f9285fbc5349a2571", "shasum": "" }, "require": { @@ -534,7 +538,9 @@ "pocketmine/spl": "<0.4" }, "require-dev": { - "phpstan/phpstan": "^0.12.18" + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "0.12.38", + "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", "autoload": { @@ -547,7 +553,7 @@ "LGPL-3.0" ], "description": "Logging components specialized for pthreads used by PocketMine-MP and related projects", - "time": "2020-03-31T18:31:56+00:00" + "time": "2020-08-22T12:07:54+00:00" }, { "name": "pocketmine/math", @@ -555,12 +561,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "5e34660aaf7d6d13ec5b8d0c9f7675b49bed5903" + "reference": "d88b421571edf3b4a26ffb4c0b2df7cc3f7145ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/5e34660aaf7d6d13ec5b8d0c9f7675b49bed5903", - "reference": "5e34660aaf7d6d13ec5b8d0c9f7675b49bed5903", + "url": "https://api.github.com/repos/pmmp/Math/zipball/d88b421571edf3b4a26ffb4c0b2df7cc3f7145ac", + "reference": "d88b421571edf3b4a26ffb4c0b2df7cc3f7145ac", "shasum": "" }, "require": { @@ -569,7 +575,9 @@ }, "require-dev": { "irstea/phpunit-shim": "^7.5", - "phpstan/phpstan": "0.12.37" + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "0.12.40", + "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", "autoload": { @@ -582,7 +590,7 @@ "LGPL-3.0" ], "description": "PHP library containing math related code used in PocketMine-MP", - "time": "2020-08-16T18:42:45+00:00" + "time": "2020-08-28T20:57:04+00:00" }, { "name": "pocketmine/nbt", @@ -590,12 +598,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "590733fbaa40efe210e00ca8207489a528b6ecc5" + "reference": "7f715bd87e42a9b44cf5a8022e66a4a05280602d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/590733fbaa40efe210e00ca8207489a528b6ecc5", - "reference": "590733fbaa40efe210e00ca8207489a528b6ecc5", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/7f715bd87e42a9b44cf5a8022e66a4a05280602d", + "reference": "7f715bd87e42a9b44cf5a8022e66a4a05280602d", "shasum": "" }, "require": { @@ -605,7 +613,9 @@ }, "require-dev": { "irstea/phpunit-shim": "^7.5 || ^8.0", - "phpstan/phpstan": "^0.12.29" + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "0.12.40", + "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", "autoload": { @@ -618,7 +628,7 @@ "LGPL-3.0" ], "description": "PHP library for working with Named Binary Tags", - "time": "2020-08-17T16:36:10+00:00" + "time": "2020-08-28T21:02:57+00:00" }, { "name": "pocketmine/raklib", @@ -626,12 +636,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "d20db2fc790d1a45492455ae0be4d9f59d56d45e" + "reference": "a40cf8a90c3081166b555826bc1def8a7a5c5cb9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/d20db2fc790d1a45492455ae0be4d9f59d56d45e", - "reference": "d20db2fc790d1a45492455ae0be4d9f59d56d45e", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/a40cf8a90c3081166b555826bc1def8a7a5c5cb9", + "reference": "a40cf8a90c3081166b555826bc1def8a7a5c5cb9", "shasum": "" }, "require": { @@ -643,7 +653,7 @@ "pocketmine/log": "dev-master" }, "require-dev": { - "phpstan/phpstan": "^0.12.18", + "phpstan/phpstan": "0.12.40", "phpstan/phpstan-strict-rules": "^0.12.2" }, "type": "library", @@ -657,20 +667,20 @@ "GPL-3.0" ], "description": "A RakNet server implementation written in PHP", - "time": "2020-08-21T21:03:31+00:00" + "time": "2020-08-28T22:11:37+00:00" }, { "name": "pocketmine/snooze", - "version": "0.1.2", + "version": "0.1.3", "source": { "type": "git", "url": "https://github.com/pmmp/Snooze.git", - "reference": "88420da3d9335dbcb3ee2decfd5e5453d057dcdf" + "reference": "849510fa62e57512b8467e3694e9b3add97038fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Snooze/zipball/88420da3d9335dbcb3ee2decfd5e5453d057dcdf", - "reference": "88420da3d9335dbcb3ee2decfd5e5453d057dcdf", + "url": "https://api.github.com/repos/pmmp/Snooze/zipball/849510fa62e57512b8467e3694e9b3add97038fd", + "reference": "849510fa62e57512b8467e3694e9b3add97038fd", "shasum": "" }, "require": { @@ -678,7 +688,9 @@ "php-64bit": ">=7.2.0" }, "require-dev": { - "phpstan/phpstan": "^0.12.8" + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "0.12.40", + "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", "autoload": { @@ -691,7 +703,7 @@ "LGPL-3.0" ], "description": "Thread notification management library for code using the pthreads extension", - "time": "2020-01-28T19:08:10+00:00" + "time": "2020-08-28T22:19:21+00:00" }, { "name": "pocketmine/spl", @@ -813,16 +825,16 @@ }, { "name": "respect/validation", - "version": "2.0.16", + "version": "2.0.17", "source": { "type": "git", "url": "https://github.com/Respect/Validation.git", - "reference": "fc14c6c6695c3f870ad8810a2acddccec015841d" + "reference": "314aa36e37dd3812b7d80c7bda3e83da5ee22d11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Respect/Validation/zipball/fc14c6c6695c3f870ad8810a2acddccec015841d", - "reference": "fc14c6c6695c3f870ad8810a2acddccec015841d", + "url": "https://api.github.com/repos/Respect/Validation/zipball/314aa36e37dd3812b7d80c7bda3e83da5ee22d11", + "reference": "314aa36e37dd3812b7d80c7bda3e83da5ee22d11", "shasum": "" }, "require": { @@ -834,9 +846,9 @@ "egulias/email-validator": "^2.1", "malukenho/docheader": "^0.1", "mikey179/vfsstream": "^1.6", - "phpstan/phpstan": "^0.11", - "phpstan/phpstan-deprecation-rules": "^0.11.0", - "phpstan/phpstan-phpunit": "^0.11.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-deprecation-rules": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", "phpunit/phpunit": "^7.5", "respect/coding-standard": "^2.1", "squizlabs/php_codesniffer": "^3.5", @@ -874,7 +886,7 @@ "validation", "validator" ], - "time": "2020-07-25T18:34:16+00:00" + "time": "2020-08-23T00:24:43+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -1067,16 +1079,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.9.0", + "version": "v4.9.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "aaee038b912e567780949787d5fe1977be11a778" + "reference": "88e519766fc58bd46b8265561fb79b54e2e00b28" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/aaee038b912e567780949787d5fe1977be11a778", - "reference": "aaee038b912e567780949787d5fe1977be11a778", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/88e519766fc58bd46b8265561fb79b54e2e00b28", + "reference": "88e519766fc58bd46b8265561fb79b54e2e00b28", "shasum": "" }, "require": { @@ -1115,7 +1127,7 @@ "parser", "php" ], - "time": "2020-08-18T19:48:01+00:00" + "time": "2020-08-30T16:15:20+00:00" }, { "name": "phar-io/manifest", @@ -1543,16 +1555,16 @@ }, { "name": "phpstan/phpstan-strict-rules", - "version": "0.12.4", + "version": "0.12.5", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-strict-rules.git", - "reference": "9b86e1eb77c796628e239820a01a2d327d607a5e" + "reference": "334898a32217e4605e0f9cfa3d3fc3101bda26be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/9b86e1eb77c796628e239820a01a2d327d607a5e", - "reference": "9b86e1eb77c796628e239820a01a2d327d607a5e", + "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/334898a32217e4605e0f9cfa3d3fc3101bda26be", + "reference": "334898a32217e4605e0f9cfa3d3fc3101bda26be", "shasum": "" }, "require": { @@ -1590,20 +1602,20 @@ "MIT" ], "description": "Extra strict and opinionated rules for PHPStan", - "time": "2020-07-21T14:49:47+00:00" + "time": "2020-08-30T15:42:06+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.1.4", + "version": "9.1.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "4422fca28c3634e2de8c7c373af97a104dd1a45f" + "reference": "2ef92bec3186a827faf7362ff92ae4e8ec2e49d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4422fca28c3634e2de8c7c373af97a104dd1a45f", - "reference": "4422fca28c3634e2de8c7c373af97a104dd1a45f", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2ef92bec3186a827faf7362ff92ae4e8ec2e49d2", + "reference": "2ef92bec3186a827faf7362ff92ae4e8ec2e49d2", "shasum": "" }, "require": { @@ -1663,7 +1675,7 @@ "type": "github" } ], - "time": "2020-08-13T15:04:53+00:00" + "time": "2020-09-03T07:09:19+00:00" }, { "name": "phpunit/php-file-iterator", @@ -1892,16 +1904,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.3.7", + "version": "9.3.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "c638a0cac77347980352485912de48c99b42ad00" + "reference": "93d78d8e2a06393a0d0c1ead6fe9984f1af1f88c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c638a0cac77347980352485912de48c99b42ad00", - "reference": "c638a0cac77347980352485912de48c99b42ad00", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/93d78d8e2a06393a0d0c1ead6fe9984f1af1f88c", + "reference": "93d78d8e2a06393a0d0c1ead6fe9984f1af1f88c", "shasum": "" }, "require": { @@ -1917,11 +1929,12 @@ "phar-io/version": "^3.0.2", "php": "^7.3 || ^8.0", "phpspec/prophecy": "^1.11.1", - "phpunit/php-code-coverage": "^9.1.1", + "phpunit/php-code-coverage": "^9.1.5", "phpunit/php-file-iterator": "^3.0.4", "phpunit/php-invoker": "^3.1", "phpunit/php-text-template": "^2.0.2", "phpunit/php-timer": "^5.0.1", + "sebastian/cli-parser": "^1.0", "sebastian/code-unit": "^1.0.5", "sebastian/comparator": "^4.0.3", "sebastian/diff": "^4.0.2", @@ -1986,7 +1999,59 @@ "type": "github" } ], - "time": "2020-08-11T15:36:12+00:00" + "time": "2020-08-27T06:30:58+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "2a4a38c56e62f7295bedb8b1b7439ad523d4ea82" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2a4a38c56e62f7295bedb8b1b7439ad523d4ea82", + "reference": "2a4a38c56e62f7295bedb8b1b7439ad523d4ea82", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-08-12T10:49:21+00:00" }, { "name": "sebastian/code-unit", @@ -3050,5 +3115,8 @@ "ext-zlib": ">=1.2.11" }, "platform-dev": [], + "platform-overrides": { + "php": "7.3.0" + }, "plugin-api-version": "1.1.0" } From 5a80f6e20117f46e26122063e9bff1a361f615b5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 4 Sep 2020 01:07:32 +0100 Subject: [PATCH 1843/3224] Updated build/php submodule to pmmp/php-build-scripts@d88132ee556e0049d2caa8f57a7832a784308e62 --- build/php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/php b/build/php index 7a0fbfa9bb..d88132ee55 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit 7a0fbfa9bb9b985cb076266277ab0aca2b55d2f3 +Subproject commit d88132ee556e0049d2caa8f57a7832a784308e62 From 101dc1e1d716f5bb57d7be93df117177de1015c0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 4 Sep 2020 01:44:21 +0100 Subject: [PATCH 1844/3224] fixed a couple of new phpstan errors --- src/entity/Entity.php | 1 + src/entity/EntityDataHelper.php | 1 + 2 files changed, 2 insertions(+) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index c3ac151094..c90930eeda 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1645,6 +1645,7 @@ abstract class Entity{ /** * @return MetadataProperty[] + * @phpstan-return array */ final protected function getSyncedNetworkData(bool $dirtyOnly) : array{ $this->syncNetworkData($this->networkProperties); diff --git a/src/entity/EntityDataHelper.php b/src/entity/EntityDataHelper.php index cf70e29eb1..e4632aa076 100644 --- a/src/entity/EntityDataHelper.php +++ b/src/entity/EntityDataHelper.php @@ -45,6 +45,7 @@ final class EntityDataHelper{ if(!($yawPitch instanceof ListTag) or $yawPitch->getTagType() !== NBT::TAG_Float){ throw new \UnexpectedValueException("'Rotation' should be a List"); } + /** @var FloatTag[] $values */ $values = $yawPitch->getValue(); if(count($values) !== 2){ throw new \UnexpectedValueException("Expected exactly 2 entries for 'Rotation'"); From b81cc671e99585b527a0648b504a87343b54c85b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 4 Sep 2020 15:51:33 +0100 Subject: [PATCH 1845/3224] Major performance improvement to basic sky light calculation this was degraded whenever it was I decided to make chunks always be allocated. This commit uses a fast path for light filling in subchunks which are completely clear of the heightmap, which returns the performance back to its old fast levels. --- src/world/format/Chunk.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 517e4170b0..d6ea71e83e 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -308,11 +308,18 @@ class Chunk{ * TODO: fast adjacent light spread */ public function populateSkyLight(\SplFixedArray $lightFilters) : void{ - $this->setAllBlockSkyLight(0); + $highestHeightMap = max($this->heightMap->getValues()); + $lowestFullyLitSubChunk = ($highestHeightMap >> 4) + (($highestHeightMap & 0xf) !== 0 ? 1 : 0); + for($y = 0; $y < $lowestFullyLitSubChunk; $y++){ + $this->getSubChunk($y)->setBlockSkyLightArray(LightArray::fill(0)); + } + for($y = $lowestFullyLitSubChunk, $yMax = $this->subChunks->count(); $y < $yMax; $y++){ + $this->getSubChunk($y)->setBlockSkyLightArray(LightArray::fill(15)); + } for($x = 0; $x < 16; ++$x){ for($z = 0; $z < 16; ++$z){ - $y = ($this->subChunks->count() * 16) - 1; + $y = ($lowestFullyLitSubChunk * 16) - 1; $heightMap = $this->getHeightMap($x, $z); for(; $y >= $heightMap; --$y){ From a68b0b1f930e04e82ed61c362166b64dc7c98660 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 4 Sep 2020 17:23:23 +0100 Subject: [PATCH 1846/3224] LightArray: make collectGarbage() more preload-friendly opcache preloading doesn't store non-class constants, but it does store class constants. Class constants that reference non-class constants are pre-resolved into values before storing in opcache SHM, so class constants are OK to use, but non-class constants will come back as undefined. --- src/world/format/LightArray.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/world/format/LightArray.php b/src/world/format/LightArray.php index cbe7cd25f7..8752e84941 100644 --- a/src/world/format/LightArray.php +++ b/src/world/format/LightArray.php @@ -82,10 +82,10 @@ final class LightArray{ * reference to the const instead of duplicating the whole string. The string will only be duplicated when * modified, which is perfect for this purpose. */ - if($this->data === ZERO_NIBBLE_ARRAY){ - $this->data = ZERO_NIBBLE_ARRAY; - }elseif($this->data === FIFTEEN_NIBBLE_ARRAY){ - $this->data = FIFTEEN_NIBBLE_ARRAY; + if($this->data === self::ZERO){ + $this->data = self::ZERO; + }elseif($this->data === self::FIFTEEN){ + $this->data = self::FIFTEEN; } } From 2e45398072b38e352867ca67974bd42210fffdc9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 4 Sep 2020 18:08:42 +0100 Subject: [PATCH 1847/3224] World: skip random block ticking on chunks that don't have any light typically this is a state that only lasts for a tick or so, but it's a race condition that is regardless very commonly encountered. If you were very unlucky, you might have noticed grass randomly dying when you were spawning or flying around, even though it was in full sky light. --- src/world/World.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index 04c0f48d4a..eed6459f6a 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -894,6 +894,9 @@ class World implements ChunkManager{ $dz = mt_rand(-$randRange, $randRange); $hash = World::chunkHash($dx + $chunkX, $dz + $chunkZ); if(!isset($chunkTickList[$hash]) and isset($this->chunks[$hash])){ + if(!$this->chunks[$hash]->isLightPopulated()){ + continue; + } //check adjacent chunks are loaded for($cx = -1; $cx <= 1; ++$cx){ for($cz = -1; $cz <= 1; ++$cz){ From e1816bd41581c128e46d2f610eedb6411b5296c3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 4 Sep 2020 22:10:42 +0100 Subject: [PATCH 1848/3224] SubChunkInterface: clarify documentation of isEmptyFast() --- src/world/format/SubChunkInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/format/SubChunkInterface.php b/src/world/format/SubChunkInterface.php index 8c0af17664..d2daa72fe3 100644 --- a/src/world/format/SubChunkInterface.php +++ b/src/world/format/SubChunkInterface.php @@ -34,7 +34,7 @@ interface SubChunkInterface{ /** * Returns a non-authoritative bool to indicate whether the chunk contains any blocks. - * This is a fast check, but may be inaccurate if the chunk has been modified and not garbage-collected. + * This may report non-empty erroneously if the chunk has been modified and not garbage-collected. */ public function isEmptyFast() : bool; From 6b6f77f8af4ad9a1161985a6c9b09ac7eec9e10f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 5 Sep 2020 00:16:07 +0100 Subject: [PATCH 1849/3224] Chunk: improved heightmap calculation performance recalculateHeightMapColumn is stateless, so it can't make any assumptions about which subchunks to check for blocks. However, in most the average case (6 allocated subchunks), this causes 2500+ useless SubChunk->getHighestBlockAt() calls (10 per column). Since we're calculating in bulk, we can figure out which subchunks are empty one time and ignore them for all 256 columns. In the average case, this produced a 50-60% performance improvement for heightmap calculation (~1.1 ms -> 0.5 ms). In extreme cases where the height is extremely varied, this produces no observable performance benefit, but for most cases with flattish terrain, it's an improvement. It can likely be further improved, but further performance improvements are outside the scope of this commit and will likely result in more complexity increases. --- src/world/format/Chunk.php | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index d6ea71e83e..cf11ad540a 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -266,9 +266,38 @@ class Chunk{ * @phpstan-param \SplFixedArray $lightDiffusers */ public function recalculateHeightMap(\SplFixedArray $lightFilters, \SplFixedArray $lightDiffusers) : void{ + $maxSubChunkY = $this->subChunks->count() - 1; + for(; $maxSubChunkY >= 0; $maxSubChunkY--){ + if(!$this->getSubChunk($maxSubChunkY)->isEmptyFast()){ + break; + } + } + if($maxSubChunkY === -1){ //whole column is definitely empty + $this->setHeightMapArray(array_fill(0, 256, 0)); + return; + } + for($z = 0; $z < 16; ++$z){ for($x = 0; $x < 16; ++$x){ - $this->recalculateHeightMapColumn($x, $z, $lightFilters, $lightDiffusers); + $y = null; + for($subChunkY = $maxSubChunkY; $subChunkY >= 0; $subChunkY--){ + $subHighestBlockY = $this->getSubChunk($subChunkY)->getHighestBlockAt($x, $z); + if($subHighestBlockY !== -1){ + $y = ($subChunkY * 16) + $subHighestBlockY; + break; + } + } + + if($y === null){ //no blocks in the column + $this->setHeightMap($x, $z, 0); + }else{ + for(; $y >= 0; --$y){ + if($lightFilters[$state = $this->getFullBlock($x, $y, $z)] > 1 or $lightDiffusers[$state]){ + $this->setHeightMap($x, $z, $y + 1); + break; + } + } + } } } } From b96565faa4b2a1e38252b42e4d50a248ee9dcae6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 5 Sep 2020 18:39:47 +0100 Subject: [PATCH 1850/3224] Drop some obviously useless static function variables these are better suited as constant literals. --- src/block/Rail.php | 15 ++++++--------- src/block/Torch.php | 5 ++--- src/utils/EnumTrait.php | 3 +-- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/block/Rail.php b/src/block/Rail.php index 219faf6322..c906470ca1 100644 --- a/src/block/Rail.php +++ b/src/block/Rail.php @@ -61,18 +61,15 @@ class Rail extends BaseRail{ } protected function getPossibleConnectionDirectionsOneConstraint(int $constraint) : array{ - /** @var int[] $horizontal */ - static $horizontal = [ - Facing::NORTH, - Facing::SOUTH, - Facing::WEST, - Facing::EAST - ]; - $possible = parent::getPossibleConnectionDirectionsOneConstraint($constraint); if(($constraint & self::FLAG_ASCEND) === 0){ - foreach($horizontal as $d){ + foreach([ + Facing::NORTH, + Facing::SOUTH, + Facing::WEST, + Facing::EAST + ] as $d){ if($constraint !== $d){ $possible[$d] = true; } diff --git a/src/block/Torch.php b/src/block/Torch.php index 001fbba6f4..570c11aa66 100644 --- a/src/block/Torch.php +++ b/src/block/Torch.php @@ -72,14 +72,13 @@ class Torch extends Flowable{ $this->facing = $face; return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); }else{ - static $faces = [ + foreach([ Facing::SOUTH, Facing::WEST, Facing::NORTH, Facing::EAST, Facing::DOWN - ]; - foreach($faces as $side){ + ] as $side){ $block = $this->getSide($side); if(!$block->isTransparent()){ $this->facing = Facing::opposite($side); diff --git a/src/utils/EnumTrait.php b/src/utils/EnumTrait.php index 8eb2a10755..7136980064 100644 --- a/src/utils/EnumTrait.php +++ b/src/utils/EnumTrait.php @@ -82,8 +82,7 @@ trait EnumTrait{ * @throws \InvalidArgumentException */ private function __construct(string $enumName){ - static $pattern = '/^\D[A-Za-z\d_]+$/u'; - if(preg_match($pattern, $enumName, $matches) === 0){ + if(preg_match('/^\D[A-Za-z\d_]+$/u', $enumName, $matches) === 0){ throw new \InvalidArgumentException("Invalid enum member name \"$enumName\", should only contain letters, numbers and underscores, and must not start with a number"); } $this->enumName = $enumName; From 6054104ecb2d5e872a5fa05ee8224db57ccc6675 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 5 Sep 2020 18:43:22 +0100 Subject: [PATCH 1851/3224] drop a few more useless static variables phpstan is better able to understand constant literals, since it knows their types will never change. --- src/block/utils/BlockDataSerializer.php | 32 ++++++++++++------------- src/block/utils/PillarRotationTrait.php | 15 ++++++------ 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/block/utils/BlockDataSerializer.php b/src/block/utils/BlockDataSerializer.php index 1459e74f29..5a9eaadffc 100644 --- a/src/block/utils/BlockDataSerializer.php +++ b/src/block/utils/BlockDataSerializer.php @@ -36,33 +36,33 @@ final class BlockDataSerializer{ * @throws InvalidBlockStateException */ public static function readFacing(int $raw) : int{ - static $map = [ //this is for redundancy, for when/if the FACING constant values change + $result = [ //this is for redundancy, for when/if the FACING constant values change 0 => Facing::DOWN, 1 => Facing::UP, 2 => Facing::NORTH, 3 => Facing::SOUTH, 4 => Facing::WEST, 5 => Facing::EAST - ]; - if(!isset($map[$raw])){ + ][$raw] ?? null; + if($result === null){ throw new InvalidBlockStateException("Invalid facing $raw"); } - return $map[$raw]; + return $result; } public static function writeFacing(int $facing) : int{ - static $map = [ //again, for redundancy + $result = [ //again, for redundancy Facing::DOWN => 0, Facing::UP => 1, Facing::NORTH => 2, Facing::SOUTH => 3, Facing::WEST => 4, Facing::EAST => 5 - ]; - if(!isset($map[$facing])){ + ][$facing] ?? null; + if($result === null){ throw new \InvalidArgumentException("Invalid facing $facing"); } - return $map[$facing]; + return $result; } /** @@ -87,29 +87,29 @@ final class BlockDataSerializer{ * @throws InvalidBlockStateException */ public static function readLegacyHorizontalFacing(int $raw) : int{ - static $map = [ //again, for redundancy + $result = [ //again, for redundancy 0 => Facing::SOUTH, 1 => Facing::WEST, 2 => Facing::NORTH, 3 => Facing::EAST - ]; - if(!isset($map[$raw])){ + ][$raw] ?? null; + if($result === null){ throw new InvalidBlockStateException("Invalid legacy facing $raw"); } - return $map[$raw]; + return $result; } public static function writeLegacyHorizontalFacing(int $facing) : int{ - static $map = [ + $result = [ Facing::SOUTH => 0, Facing::WEST => 1, Facing::NORTH => 2, Facing::EAST => 3 - ]; - if(!isset($map[$facing])){ + ][$facing] ?? null; + if($result === null){ throw new \InvalidArgumentException("Invalid Y-axis facing"); } - return $map[$facing]; + return $result; } /** diff --git a/src/block/utils/PillarRotationTrait.php b/src/block/utils/PillarRotationTrait.php index 8685ddb573..7ae8f8cc69 100644 --- a/src/block/utils/PillarRotationTrait.php +++ b/src/block/utils/PillarRotationTrait.php @@ -62,25 +62,24 @@ trait PillarRotationTrait{ } protected function readAxisFromMeta(int $meta) : void{ - static $map = [ + $axis = $meta >> $this->getAxisMetaShift(); + $mapped = [ 0 => Axis::Y, 1 => Axis::X, 2 => Axis::Z - ]; - $axis = $meta >> $this->getAxisMetaShift(); - if(!isset($map[$axis])){ + ][$axis] ?? null; + if($mapped === null){ throw new InvalidBlockStateException("Invalid axis meta $axis"); } - $this->axis = $map[$axis]; + $this->axis = $mapped; } protected function writeAxisToMeta() : int{ - static $bits = [ + return [ Axis::Y => 0, Axis::Z => 2, Axis::X => 1 - ]; - return $bits[$this->axis] << $this->getAxisMetaShift(); + ][$this->axis] << $this->getAxisMetaShift(); } /** From 15299735e9c94db37771dff64907d6f36a29b736 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 5 Sep 2020 22:22:19 +0100 Subject: [PATCH 1852/3224] Do not create chunks during light propagation/removal this used to be necessary to trigger subchunk creation so that light arrays would be available for use. With 02ff8d671b93ec5911576643e9b03f2049f31c81, this is no longer necessary. --- src/world/light/LightUpdate.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/light/LightUpdate.php b/src/world/light/LightUpdate.php index 5bba96bf32..914f62a908 100644 --- a/src/world/light/LightUpdate.php +++ b/src/world/light/LightUpdate.php @@ -145,7 +145,7 @@ abstract class LightUpdate{ ]; foreach($points as list($cx, $cy, $cz)){ - if($this->subChunkHandler->moveTo($cx, $cy, $cz, true)){ + if($this->subChunkHandler->moveTo($cx, $cy, $cz, false)){ $this->computeRemoveLight($cx, $cy, $cz, $oldAdjacentLight); }elseif($this->getEffectiveLight($cx, $cy, $cz) > 0 and !isset($this->spreadVisited[$index = World::blockHash($cx, $cy, $cz)])){ $this->spreadVisited[$index] = true; @@ -174,7 +174,7 @@ abstract class LightUpdate{ ]; foreach($points as list($cx, $cy, $cz)){ - if($this->subChunkHandler->moveTo($cx, $cy, $cz, true)){ + if($this->subChunkHandler->moveTo($cx, $cy, $cz, false)){ $this->computeSpreadLight($cx, $cy, $cz, $newAdjacentLight); } } From 94d8f59484230ac81a8086d719fdc566be7e7089 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 5 Sep 2020 22:25:42 +0100 Subject: [PATCH 1853/3224] LightUpdate::execute() now returns the number of visits made to blocks in total this is useful for performance profiling. --- src/world/light/LightUpdate.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/world/light/LightUpdate.php b/src/world/light/LightUpdate.php index 914f62a908..03a70ad5cf 100644 --- a/src/world/light/LightUpdate.php +++ b/src/world/light/LightUpdate.php @@ -129,10 +129,12 @@ abstract class LightUpdate{ } } - public function execute() : void{ + public function execute() : int{ $this->prepareNodes(); + $touched = 0; while(!$this->removalQueue->isEmpty()){ + $touched++; list($x, $y, $z, $oldAdjacentLight) = $this->removalQueue->dequeue(); $points = [ @@ -155,6 +157,7 @@ abstract class LightUpdate{ } while(!$this->spreadQueue->isEmpty()){ + $touched++; list($x, $y, $z) = $this->spreadQueue->dequeue(); unset($this->spreadVisited[World::blockHash($x, $y, $z)]); @@ -179,6 +182,8 @@ abstract class LightUpdate{ } } } + + return $touched; } protected function computeRemoveLight(int $x, int $y, int $z, int $oldAdjacentLevel) : void{ From f45316d2d614e0f90265ede6ab24316d4225a195 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 6 Sep 2020 16:12:24 +0100 Subject: [PATCH 1854/3224] Leaves: fixed phpstan type doc error for some reason this isn't reported unless bleeding edge is enabled. --- src/block/Leaves.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/Leaves.php b/src/block/Leaves.php index 27da9fa7d8..0ed48c3a9a 100644 --- a/src/block/Leaves.php +++ b/src/block/Leaves.php @@ -69,7 +69,7 @@ class Leaves extends Transparent{ /** * @param true[] $visited reference parameter - * @phpstan-param array $visited + * @phpstan-param array $visited */ protected function findLog(Vector3 $pos, array &$visited = [], int $distance = 0) : bool{ $index = World::blockHash($pos->x, $pos->y, $pos->z); From fb4b92d1f41c4494d43dc1e9be969515342f51fe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 6 Sep 2020 16:12:54 +0100 Subject: [PATCH 1855/3224] HandlerListManager: fixed missing null type flag --- src/event/HandlerListManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/event/HandlerListManager.php b/src/event/HandlerListManager.php index 4bd61f8023..942b794670 100644 --- a/src/event/HandlerListManager.php +++ b/src/event/HandlerListManager.php @@ -28,7 +28,7 @@ use pocketmine\utils\Utils; class HandlerListManager{ - /** @var HandlerListManager */ + /** @var HandlerListManager|null */ private static $globalInstance = null; public static function global() : self{ From be0cec531acdfc2e46462797939af4dbc1d2c610 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 6 Sep 2020 16:13:41 +0100 Subject: [PATCH 1856/3224] ResourcePackInfoEntry: remove useless null coalesce operators these fields are never null. these errors aren't reported unless bleeding-edge is enabled. --- .../protocol/types/resourcepacks/ResourcePackInfoEntry.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php index 0e0308ece1..5ea031b5cc 100644 --- a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php +++ b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php @@ -84,9 +84,9 @@ class ResourcePackInfoEntry{ $out->putString($this->packId); $out->putString($this->version); $out->putLLong($this->sizeBytes); - $out->putString($this->encryptionKey ?? ""); - $out->putString($this->subPackName ?? ""); - $out->putString($this->contentId ?? ""); + $out->putString($this->encryptionKey); + $out->putString($this->subPackName); + $out->putString($this->contentId); $out->putBool($this->hasScripts); } From 5fbc842f7abdd02345d8cecd632c4d526453bb44 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 6 Sep 2020 16:18:47 +0100 Subject: [PATCH 1857/3224] LightArray: do not accept NULL in the constructor it makes more sense to pass LightArray::ZERO or just use LightArray::fill(0) if a zeroed light array is desired. --- src/world/format/LightArray.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/world/format/LightArray.php b/src/world/format/LightArray.php index 8752e84941..38137b9207 100644 --- a/src/world/format/LightArray.php +++ b/src/world/format/LightArray.php @@ -45,12 +45,12 @@ final class LightArray{ /** @var string */ private $data; - public function __construct(?string $payload){ - if($payload !== null and ($len = strlen($payload)) !== 2048){ + public function __construct(string $payload){ + if(($len = strlen($payload)) !== 2048){ throw new \InvalidArgumentException("Payload size must be 2048 bytes, but got $len bytes"); } - $this->data = $payload ?? self::ZERO; + $this->data = $payload; $this->collectGarbage(); } From 01f8116cdd025e524e287c36a6af9299739da62e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 7 Sep 2020 14:43:26 +0100 Subject: [PATCH 1858/3224] Fix some of the implicit immutability issues of EmptySubChunk it's useful to have an immutable stub around for the sake of feeding back dummy read values, but for write values it has to barf instead of being quiet. There's still some issues with LightArray which I don't currently have a solution for, but I'm thinking about separating light storage from chunks anyway. --- src/world/format/Chunk.php | 21 ++++++++++++++------- src/world/format/EmptySubChunk.php | 12 ------------ src/world/format/SubChunkInterface.php | 6 ------ src/world/generator/Flat.php | 2 +- src/world/light/LightPopulationTask.php | 4 ++-- tests/phpstan/configs/l8-baseline.neon | 5 +++++ 6 files changed, 22 insertions(+), 28 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index cf11ad540a..e842fef96d 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -152,7 +152,7 @@ class Chunk{ * Sets the blockstate at the given coordinate by internal ID. */ public function setFullBlock(int $x, int $y, int $z, int $block) : void{ - $this->getSubChunk($y >> 4)->setFullBlock($x, $y & 0xf, $z, $block); + $this->getWritableSubChunk($y >> 4)->setFullBlock($x, $y & 0xf, $z, $block); $this->dirtyFlags |= self::DIRTY_FLAG_TERRAIN; } @@ -178,12 +178,12 @@ class Chunk{ * @param int $level 0-15 */ public function setBlockSkyLight(int $x, int $y, int $z, int $level) : void{ - $this->getSubChunk($y >> 4)->getBlockSkyLightArray()->set($x & 0xf, $y & 0x0f, $z & 0xf, $level); + $this->getWritableSubChunk($y >> 4)->getBlockSkyLightArray()->set($x & 0xf, $y & 0x0f, $z & 0xf, $level); } public function setAllBlockSkyLight(int $level) : void{ for($y = $this->subChunks->count() - 1; $y >= 0; --$y){ - $this->getSubChunk($y)->setBlockSkyLightArray(LightArray::fill($level)); + $this->getWritableSubChunk($y)->setBlockSkyLightArray(LightArray::fill($level)); } } @@ -209,12 +209,12 @@ class Chunk{ * @param int $level 0-15 */ public function setBlockLight(int $x, int $y, int $z, int $level) : void{ - $this->getSubChunk($y >> 4)->getBlockLightArray()->set($x & 0xf, $y & 0x0f, $z & 0xf, $level); + $this->getWritableSubChunk($y >> 4)->getBlockLightArray()->set($x & 0xf, $y & 0x0f, $z & 0xf, $level); } public function setAllBlockLight(int $level) : void{ for($y = $this->subChunks->count() - 1; $y >= 0; --$y){ - $this->getSubChunk($y)->setBlockLightArray(LightArray::fill($level)); + $this->getWritableSubChunk($y)->setBlockLightArray(LightArray::fill($level)); } } @@ -340,10 +340,10 @@ class Chunk{ $highestHeightMap = max($this->heightMap->getValues()); $lowestFullyLitSubChunk = ($highestHeightMap >> 4) + (($highestHeightMap & 0xf) !== 0 ? 1 : 0); for($y = 0; $y < $lowestFullyLitSubChunk; $y++){ - $this->getSubChunk($y)->setBlockSkyLightArray(LightArray::fill(0)); + $this->getWritableSubChunk($y)->setBlockSkyLightArray(LightArray::fill(0)); } for($y = $lowestFullyLitSubChunk, $yMax = $this->subChunks->count(); $y < $yMax; $y++){ - $this->getSubChunk($y)->setBlockSkyLightArray(LightArray::fill(15)); + $this->getWritableSubChunk($y)->setBlockSkyLightArray(LightArray::fill(15)); } for($x = 0; $x < 16; ++$x){ @@ -623,6 +623,13 @@ class Chunk{ return $this->subChunks[$y]; } + public function getWritableSubChunk(int $y) : SubChunk{ + if($y < 0 || $y >= $this->subChunks->getSize()){ + throw new \InvalidArgumentException("Cannot get subchunk $y for writing"); + } + return $this->subChunks[$y]; + } + /** * Sets a subchunk in the chunk index */ diff --git a/src/world/format/EmptySubChunk.php b/src/world/format/EmptySubChunk.php index d4beb19312..b28450b0a5 100644 --- a/src/world/format/EmptySubChunk.php +++ b/src/world/format/EmptySubChunk.php @@ -47,10 +47,6 @@ class EmptySubChunk implements SubChunkInterface{ return 0; } - public function setFullBlock(int $x, int $y, int $z, int $block) : void{ - - } - public function getBlockLayers() : array{ return []; } @@ -63,15 +59,7 @@ class EmptySubChunk implements SubChunkInterface{ return new LightArray(LightArray::ZERO); } - public function setBlockLightArray(LightArray $data) : void{ - - } - public function getBlockSkyLightArray() : LightArray{ return new LightArray(LightArray::FIFTEEN); } - - public function setBlockSkyLightArray(LightArray $data) : void{ - - } } diff --git a/src/world/format/SubChunkInterface.php b/src/world/format/SubChunkInterface.php index d2daa72fe3..25f4cce287 100644 --- a/src/world/format/SubChunkInterface.php +++ b/src/world/format/SubChunkInterface.php @@ -40,8 +40,6 @@ interface SubChunkInterface{ public function getFullBlock(int $x, int $y, int $z) : int; - public function setFullBlock(int $x, int $y, int $z, int $block) : void; - /** * @return PalettedBlockArray[] */ @@ -51,9 +49,5 @@ interface SubChunkInterface{ public function getBlockSkyLightArray() : LightArray; - public function setBlockSkyLightArray(LightArray $data) : void; - public function getBlockLightArray() : LightArray; - - public function setBlockLightArray(LightArray $data) : void; } diff --git a/src/world/generator/Flat.php b/src/world/generator/Flat.php index 5715ffb660..87b8b3fe2f 100644 --- a/src/world/generator/Flat.php +++ b/src/world/generator/Flat.php @@ -156,7 +156,7 @@ class Flat extends Generator{ $count = count($this->structure); for($sy = 0; $sy < $count; $sy += 16){ - $subchunk = $this->chunk->getSubChunk($sy >> 4); + $subchunk = $this->chunk->getWritableSubChunk($sy >> 4); for($y = 0; $y < 16 and isset($this->structure[$y | $sy]); ++$y){ $id = $this->structure[$y | $sy]; diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index 8fa5776e99..b4b33ff86e 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -94,10 +94,10 @@ class LightPopulationTask extends AsyncTask{ $blockLightArrays = igbinary_unserialize($this->resultBlockLightArrays); foreach($skyLightArrays as $y => $array){ - $chunk->getSubChunk($y)->setBlockSkyLightArray($array); + $chunk->getWritableSubChunk($y)->setBlockSkyLightArray($array); } foreach($blockLightArrays as $y => $array){ - $chunk->getSubChunk($y)->setBlockLightArray($array); + $chunk->getWritableSubChunk($y)->setBlockLightArray($array); } $chunk->setLightPopulated(); } diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 506fef3bf7..d6678176e1 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -760,6 +760,11 @@ parameters: count: 1 path: ../../../src/world/format/Chunk.php + - + message: "#^Method pocketmine\\\\world\\\\format\\\\Chunk\\:\\:getWritableSubChunk\\(\\) should return pocketmine\\\\world\\\\format\\\\SubChunk but returns pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" + count: 1 + path: ../../../src/world/format/Chunk.php + - message: "#^Method pocketmine\\\\world\\\\format\\\\HeightArray\\:\\:get\\(\\) should return int but returns int\\|null\\.$#" count: 1 From 0fd3d9103826e9c3fe7cb195f0518302619cd1ef Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 8 Sep 2020 15:13:58 +0100 Subject: [PATCH 1859/3224] LightArray: hide constants ZERO and FIFTEEN from the API this makes it easier to implement this in C++ with the same API. Since the C++ version doesn't use strings, these constants aren't needed anyway. --- src/world/format/EmptySubChunk.php | 4 ++-- src/world/format/LightArray.php | 4 ++-- src/world/format/SubChunk.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/world/format/EmptySubChunk.php b/src/world/format/EmptySubChunk.php index b28450b0a5..e1bac91186 100644 --- a/src/world/format/EmptySubChunk.php +++ b/src/world/format/EmptySubChunk.php @@ -56,10 +56,10 @@ class EmptySubChunk implements SubChunkInterface{ } public function getBlockLightArray() : LightArray{ - return new LightArray(LightArray::ZERO); + return LightArray::fill(0); } public function getBlockSkyLightArray() : LightArray{ - return new LightArray(LightArray::FIFTEEN); + return LightArray::fill(15); } } diff --git a/src/world/format/LightArray.php b/src/world/format/LightArray.php index 38137b9207..885e9ddc98 100644 --- a/src/world/format/LightArray.php +++ b/src/world/format/LightArray.php @@ -39,8 +39,8 @@ if(!defined(__NAMESPACE__ . '\FIFTEEN_NIBBLE_ARRAY')){ final class LightArray{ - public const ZERO = ZERO_NIBBLE_ARRAY; - public const FIFTEEN = FIFTEEN_NIBBLE_ARRAY; + private const ZERO = ZERO_NIBBLE_ARRAY; + private const FIFTEEN = FIFTEEN_NIBBLE_ARRAY; /** @var string */ private $data; diff --git a/src/world/format/SubChunk.php b/src/world/format/SubChunk.php index d4514403e3..e9c4e6c5f1 100644 --- a/src/world/format/SubChunk.php +++ b/src/world/format/SubChunk.php @@ -46,8 +46,8 @@ class SubChunk implements SubChunkInterface{ $this->defaultBlock = $default; $this->blockLayers = $blocks; - $this->skyLight = $skyLight ?? new LightArray(LightArray::FIFTEEN); - $this->blockLight = $blockLight ?? new LightArray(LightArray::ZERO); + $this->skyLight = $skyLight ?? LightArray::fill(15); + $this->blockLight = $blockLight ?? LightArray::fill(0); } public function isEmptyAuthoritative() : bool{ From 205617f29e8f3b991f9927a5da6173fcefb60c48 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 8 Sep 2020 18:14:06 +0100 Subject: [PATCH 1860/3224] Untether LightUpdate and children from BlockFactory --- src/block/BlockFactory.php | 7 +++++++ src/world/World.php | 5 +++-- src/world/light/BlockLightUpdate.php | 22 ++++++++++++++++++++-- src/world/light/LightUpdate.php | 17 ++++++++++++++--- src/world/light/SkyLightUpdate.php | 24 +++++++++++++++++++++--- 5 files changed, 65 insertions(+), 10 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 6951c52a21..b3283f2aa6 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -69,6 +69,11 @@ class BlockFactory{ */ private $fullList; + /** + * @var \SplFixedArray|int[] + * @phpstan-var \SplFixedArray + */ + public $light; /** * @var \SplFixedArray|int[] * @phpstan-var \SplFixedArray @@ -88,6 +93,7 @@ class BlockFactory{ public function __construct(){ $this->fullList = new \SplFixedArray(16384); + $this->light = \SplFixedArray::fromArray(array_fill(0, 16384, 0)); $this->lightFilter = \SplFixedArray::fromArray(array_fill(0, 16384, 1)); $this->diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 16384, false)); $this->blastResistance = \SplFixedArray::fromArray(array_fill(0, 16384, 0.0)); @@ -850,6 +856,7 @@ class BlockFactory{ private function fillStaticArrays(int $index, Block $block) : void{ $this->fullList[$index] = $block; + $this->light[$index] = $block->getLightLevel(); $this->lightFilter[$index] = min(15, $block->getLightFilter() + 1); //opacity plus 1 standard light filter $this->diffusesSkyLight[$index] = $block->diffusesSkyLight(); $this->blastResistance[$index] = $block->getBreakInfo()->getBlastResistance(); diff --git a/src/world/World.php b/src/world/World.php index eed6459f6a..04d19825c8 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1162,16 +1162,17 @@ class World implements ChunkManager{ } public function updateAllLight(int $x, int $y, int $z) : void{ + $blockFactory = BlockFactory::getInstance(); $this->timings->doBlockSkyLightUpdates->startTiming(); if($this->skyLightUpdate === null){ - $this->skyLightUpdate = new SkyLightUpdate($this); + $this->skyLightUpdate = new SkyLightUpdate($this, $blockFactory->lightFilter, $blockFactory->diffusesSkyLight); } $this->skyLightUpdate->recalculateNode($x, $y, $z); $this->timings->doBlockSkyLightUpdates->stopTiming(); $this->timings->doBlockLightUpdates->startTiming(); if($this->blockLightUpdate === null){ - $this->blockLightUpdate = new BlockLightUpdate($this); + $this->blockLightUpdate = new BlockLightUpdate($this, $blockFactory->lightFilter, $blockFactory->light); } $this->blockLightUpdate->recalculateNode($x, $y, $z); $this->timings->doBlockLightUpdates->stopTiming(); diff --git a/src/world/light/BlockLightUpdate.php b/src/world/light/BlockLightUpdate.php index 266e84f4bc..d1e2273b70 100644 --- a/src/world/light/BlockLightUpdate.php +++ b/src/world/light/BlockLightUpdate.php @@ -23,16 +23,34 @@ declare(strict_types=1); namespace pocketmine\world\light; -use pocketmine\block\BlockFactory; +use pocketmine\world\ChunkManager; use function max; class BlockLightUpdate extends LightUpdate{ + + /** + * @var \SplFixedArray|int[] + * @phpstan-var \SplFixedArray + */ + private $lightEmitters; + + /** + * @param \SplFixedArray|int[] $lightFilters + * @param \SplFixedArray|int[] $lightEmitters + * @phpstan-param \SplFixedArray $lightFilters + * @phpstan-param \SplFixedArray $lightEmitters + */ + public function __construct(ChunkManager $world, \SplFixedArray $lightFilters, \SplFixedArray $lightEmitters){ + parent::__construct($world, $lightFilters); + $this->lightEmitters = $lightEmitters; + } + protected function updateLightArrayRef() : void{ $this->currentLightArray = $this->subChunkHandler->currentSubChunk->getBlockLightArray(); } public function recalculateNode(int $x, int $y, int $z) : void{ $block = $this->world->getBlockAt($x, $y, $z); - $this->setAndUpdateLight($x, $y, $z, max($block->getLightLevel(), $this->getHighestAdjacentLight($x, $y, $z) - BlockFactory::getInstance()->lightFilter[$block->getFullId()])); + $this->setAndUpdateLight($x, $y, $z, max($block->getLightLevel(), $this->getHighestAdjacentLight($x, $y, $z) - $this->lightFilters[$block->getFullId()])); } } diff --git a/src/world/light/LightUpdate.php b/src/world/light/LightUpdate.php index 03a70ad5cf..e1159bea5a 100644 --- a/src/world/light/LightUpdate.php +++ b/src/world/light/LightUpdate.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\world\light; -use pocketmine\block\BlockFactory; use pocketmine\world\ChunkManager; use pocketmine\world\format\LightArray; use pocketmine\world\utils\SubChunkIteratorManager; @@ -36,6 +35,12 @@ abstract class LightUpdate{ /** @var ChunkManager */ protected $world; + /** + * @var \SplFixedArray|int[] + * @phpstan-var \SplFixedArray + */ + protected $lightFilters; + /** * @var int[][] blockhash => [x, y, z, new light level] * @phpstan-var array @@ -69,8 +74,14 @@ abstract class LightUpdate{ /** @var LightArray|null */ protected $currentLightArray = null; - public function __construct(ChunkManager $world){ + /** + * @param \SplFixedArray|int[] $lightFilters + * @phpstan-param \SplFixedArray $lightFilters + */ + public function __construct(ChunkManager $world, \SplFixedArray $lightFilters){ $this->world = $world; + $this->lightFilters = $lightFilters; + $this->removalQueue = new \SplQueue(); $this->spreadQueue = new \SplQueue(); @@ -208,7 +219,7 @@ abstract class LightUpdate{ protected function computeSpreadLight(int $x, int $y, int $z, int $newAdjacentLevel) : void{ $current = $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); - $potentialLight = $newAdjacentLevel - BlockFactory::getInstance()->lightFilter[$this->subChunkHandler->currentSubChunk->getFullBlock($x & 0x0f, $y & 0x0f, $z & 0x0f)]; + $potentialLight = $newAdjacentLevel - $this->lightFilters[$this->subChunkHandler->currentSubChunk->getFullBlock($x & 0x0f, $y & 0x0f, $z & 0x0f)]; if($current < $potentialLight){ $this->currentLightArray->set($x & 0xf, $y & 0xf, $z & 0xf, $potentialLight); diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index 290537da94..7c1d5634ec 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -23,11 +23,29 @@ declare(strict_types=1); namespace pocketmine\world\light; -use pocketmine\block\BlockFactory; +use pocketmine\world\ChunkManager; use pocketmine\world\World; use function max; class SkyLightUpdate extends LightUpdate{ + + /** + * @var \SplFixedArray|bool[] + * @phpstan-var \SplFixedArray + */ + private $lightDiffusers; + + /** + * @param \SplFixedArray|int[] $lightFilters + * @param \SplFixedArray|bool[] $lightDiffusers + * @phpstan-param \SplFixedArray $lightFilters + * @phpstan-param \SplFixedArray $lightDiffusers + */ + public function __construct(ChunkManager $world, \SplFixedArray $lightFilters, \SplFixedArray $lightDiffusers){ + parent::__construct($world, $lightFilters); + $this->lightDiffusers = $lightDiffusers; + } + protected function updateLightArrayRef() : void{ $this->currentLightArray = $this->subChunkHandler->currentSubChunk->getBlockSkyLightArray(); } @@ -51,7 +69,7 @@ class SkyLightUpdate extends LightUpdate{ $yPlusOne = $y + 1; if($yPlusOne === $oldHeightMap){ //Block changed directly beneath the heightmap. Check if a block was removed or changed to a different light-filter. - $newHeightMap = $chunk->recalculateHeightMapColumn($x & 0x0f, $z & 0x0f, BlockFactory::getInstance()->lightFilter, BlockFactory::getInstance()->diffusesSkyLight); + $newHeightMap = $chunk->recalculateHeightMapColumn($x & 0x0f, $z & 0x0f, $this->lightFilters, $this->lightDiffusers); }elseif($yPlusOne > $oldHeightMap){ //Block changed above the heightmap. if($source->getLightFilter() > 0 or $source->diffusesSkyLight()){ $chunk->setHeightMap($x & 0xf, $z & 0xf, $yPlusOne); @@ -72,7 +90,7 @@ class SkyLightUpdate extends LightUpdate{ $this->setAndUpdateLight($x, $i, $z, 15); } }else{ //No heightmap change, block changed "underground" - $this->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentLight($x, $y, $z) - BlockFactory::getInstance()->lightFilter[$source->getFullId()])); + $this->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentLight($x, $y, $z) - $this->lightFilters[$source->getFullId()])); } } } From ec6ac59b9c5c0415f5ca9545b61e03dfdd44a330 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 8 Sep 2020 18:20:53 +0100 Subject: [PATCH 1861/3224] BlockLightUpdate: actually use lightEmitters I accidentally added this during a separation of my local changes, but it's useful anyway, so we should use it. This removes BlockLightUpdate's implicit dependency on Block, which is a step towards native light. --- src/world/light/BlockLightUpdate.php | 6 ++++-- tests/phpstan/configs/l8-baseline.neon | 10 ++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/world/light/BlockLightUpdate.php b/src/world/light/BlockLightUpdate.php index d1e2273b70..fc48e27bb9 100644 --- a/src/world/light/BlockLightUpdate.php +++ b/src/world/light/BlockLightUpdate.php @@ -50,7 +50,9 @@ class BlockLightUpdate extends LightUpdate{ } public function recalculateNode(int $x, int $y, int $z) : void{ - $block = $this->world->getBlockAt($x, $y, $z); - $this->setAndUpdateLight($x, $y, $z, max($block->getLightLevel(), $this->getHighestAdjacentLight($x, $y, $z) - $this->lightFilters[$block->getFullId()])); + if($this->subChunkHandler->moveTo($x, $y, $z, false)){ + $block = $this->subChunkHandler->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf); + $this->setAndUpdateLight($x, $y, $z, max($this->lightEmitters[$block], $this->getHighestAdjacentLight($x, $y, $z) - $this->lightFilters[$block])); + } } } diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index d6678176e1..76320628ec 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -910,11 +910,21 @@ parameters: count: 1 path: ../../../src/world/light/BlockLightUpdate.php + - + message: "#^Cannot call method getFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" + count: 1 + path: ../../../src/world/light/BlockLightUpdate.php + - message: "#^Only numeric types are allowed in \\-, int\\|null given on the right side\\.$#" count: 1 path: ../../../src/world/light/BlockLightUpdate.php + - + message: "#^Parameter \\#4 \\$newLevel of method pocketmine\\\\world\\\\light\\\\LightUpdate\\:\\:setAndUpdateLight\\(\\) expects int, int\\|null given\\.$#" + count: 1 + path: ../../../src/world/light/BlockLightUpdate.php + - message: "#^Cannot call method get\\(\\) on pocketmine\\\\world\\\\format\\\\LightArray\\|null\\.$#" count: 4 From 773069d1ccfedfed9e741ccb4ada69ff44661198 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 8 Sep 2020 21:09:39 +0100 Subject: [PATCH 1862/3224] fix travis build --- tests/travis/setup-php.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/travis/setup-php.yml b/tests/travis/setup-php.yml index e276d6f221..9105418dbb 100644 --- a/tests/travis/setup-php.yml +++ b/tests/travis/setup-php.yml @@ -38,7 +38,7 @@ before_script: - cd .. - git clone https://github.com/pmmp/ext-chunkutils2.git chunkutils - cd chunkutils - - git checkout d8d762a597ac0da6f333f862096d6af0e6286b75 + - git checkout -f d8d762a597ac0da6f333f862096d6af0e6286b75 - phpize - ./configure && make && make install - cd .. From c7070788f964d7fc4eab8f049b9fa8280aea501c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 8 Sep 2020 22:37:58 +0100 Subject: [PATCH 1863/3224] Rename and repurpose Block->diffusesSkyLight to blocksDirectSkyLight this new form allows skipping some useless checks during sky light calculation and also allows getting rid of the last hard dependency on core Block classes. We're getting real close to native light now. --- src/block/Block.php | 12 ++++++------ src/block/BlockFactory.php | 6 +++--- src/block/Cobweb.php | 2 +- src/block/Leaves.php | 2 +- src/world/World.php | 2 +- src/world/generator/PopulationTask.php | 2 +- src/world/light/LightPopulationTask.php | 2 +- src/world/light/SkyLightUpdate.php | 23 ++++++++++++----------- tests/phpstan/configs/l8-baseline.neon | 25 +++++++++++++++++++++++++ 9 files changed, 51 insertions(+), 25 deletions(-) diff --git a/src/block/Block.php b/src/block/Block.php index ee07c9c4b9..2022a55be7 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -292,14 +292,14 @@ class Block{ } /** - * Returns whether this block will diffuse sky light passing through it vertically. - * Diffusion means that full-strength sky light passing through this block will not be reduced, but will start being filtered below the block. - * Examples of this behaviour include leaves and cobwebs. + * Returns whether this block blocks direct sky light from passing through it. This is independent from the light + * filter value, which is used during propagation. * - * Light-diffusing blocks are included by the heightmap. + * In most cases, this is the same as isTransparent(); however, some special cases exist such as leaves and cobwebs, + * which don't have any additional effect on light propagation, but don't allow direct sky light to pass through. */ - public function diffusesSkyLight() : bool{ - return false; + public function blocksDirectSkyLight() : bool{ + return $this->getLightFilter() > 0; } public function isTransparent() : bool{ diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index b3283f2aa6..1097dc0f7e 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -83,7 +83,7 @@ class BlockFactory{ * @var \SplFixedArray|bool[] * @phpstan-var \SplFixedArray */ - public $diffusesSkyLight; + public $blocksDirectSkyLight; /** * @var \SplFixedArray|float[] * @phpstan-var \SplFixedArray @@ -95,7 +95,7 @@ class BlockFactory{ $this->light = \SplFixedArray::fromArray(array_fill(0, 16384, 0)); $this->lightFilter = \SplFixedArray::fromArray(array_fill(0, 16384, 1)); - $this->diffusesSkyLight = \SplFixedArray::fromArray(array_fill(0, 16384, false)); + $this->blocksDirectSkyLight = \SplFixedArray::fromArray(array_fill(0, 16384, false)); $this->blastResistance = \SplFixedArray::fromArray(array_fill(0, 16384, 0.0)); $this->register(new ActivatorRail(new BID(Ids::ACTIVATOR_RAIL), "Activator Rail")); @@ -858,7 +858,7 @@ class BlockFactory{ $this->fullList[$index] = $block; $this->light[$index] = $block->getLightLevel(); $this->lightFilter[$index] = min(15, $block->getLightFilter() + 1); //opacity plus 1 standard light filter - $this->diffusesSkyLight[$index] = $block->diffusesSkyLight(); + $this->blocksDirectSkyLight[$index] = $block->blocksDirectSkyLight(); $this->blastResistance[$index] = $block->getBreakInfo()->getBlastResistance(); } diff --git a/src/block/Cobweb.php b/src/block/Cobweb.php index e28bf19a7e..e93641d7d8 100644 --- a/src/block/Cobweb.php +++ b/src/block/Cobweb.php @@ -51,7 +51,7 @@ class Cobweb extends Flowable{ return true; } - public function diffusesSkyLight() : bool{ + public function blocksDirectSkyLight() : bool{ return true; } } diff --git a/src/block/Leaves.php b/src/block/Leaves.php index 0ed48c3a9a..058cdb5f9f 100644 --- a/src/block/Leaves.php +++ b/src/block/Leaves.php @@ -63,7 +63,7 @@ class Leaves extends Transparent{ return 0b1100; } - public function diffusesSkyLight() : bool{ + public function blocksDirectSkyLight() : bool{ return true; } diff --git a/src/world/World.php b/src/world/World.php index 04d19825c8..a457f5cb60 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1165,7 +1165,7 @@ class World implements ChunkManager{ $blockFactory = BlockFactory::getInstance(); $this->timings->doBlockSkyLightUpdates->startTiming(); if($this->skyLightUpdate === null){ - $this->skyLightUpdate = new SkyLightUpdate($this, $blockFactory->lightFilter, $blockFactory->diffusesSkyLight); + $this->skyLightUpdate = new SkyLightUpdate($this, $blockFactory->lightFilter, $blockFactory->blocksDirectSkyLight); } $this->skyLightUpdate->recalculateNode($x, $y, $z); $this->timings->doBlockSkyLightUpdates->stopTiming(); diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 72eee84bb7..979909119b 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -119,7 +119,7 @@ class PopulationTask extends AsyncTask{ $chunk->setPopulated(); $blockFactory = BlockFactory::getInstance(); - $chunk->recalculateHeightMap($blockFactory->lightFilter, $blockFactory->diffusesSkyLight); + $chunk->recalculateHeightMap($blockFactory->lightFilter, $blockFactory->blocksDirectSkyLight); $chunk->populateSkyLight($blockFactory->lightFilter); $chunk->setLightPopulated(); diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index b4b33ff86e..e066c2f2af 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -61,7 +61,7 @@ class LightPopulationTask extends AsyncTask{ $chunk = FastChunkSerializer::deserialize($this->chunk); $blockFactory = BlockFactory::getInstance(); - $chunk->recalculateHeightMap($blockFactory->lightFilter, $blockFactory->diffusesSkyLight); + $chunk->recalculateHeightMap($blockFactory->lightFilter, $blockFactory->blocksDirectSkyLight); $chunk->populateSkyLight($blockFactory->lightFilter); $chunk->setLightPopulated(); diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index 7c1d5634ec..ac2054339b 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -33,17 +33,17 @@ class SkyLightUpdate extends LightUpdate{ * @var \SplFixedArray|bool[] * @phpstan-var \SplFixedArray */ - private $lightDiffusers; + private $directSkyLightBlockers; /** * @param \SplFixedArray|int[] $lightFilters - * @param \SplFixedArray|bool[] $lightDiffusers + * @param \SplFixedArray|bool[] $directSkyLightBlockers * @phpstan-param \SplFixedArray $lightFilters - * @phpstan-param \SplFixedArray $lightDiffusers + * @phpstan-param \SplFixedArray $directSkyLightBlockers */ - public function __construct(ChunkManager $world, \SplFixedArray $lightFilters, \SplFixedArray $lightDiffusers){ + public function __construct(ChunkManager $world, \SplFixedArray $lightFilters, \SplFixedArray $directSkyLightBlockers){ parent::__construct($world, $lightFilters); - $this->lightDiffusers = $lightDiffusers; + $this->directSkyLightBlockers = $directSkyLightBlockers; } protected function updateLightArrayRef() : void{ @@ -59,19 +59,20 @@ class SkyLightUpdate extends LightUpdate{ } public function recalculateNode(int $x, int $y, int $z) : void{ - $chunk = $this->world->getChunk($x >> 4, $z >> 4); - if($chunk === null){ + if(!$this->subChunkHandler->moveTo($x, $y, $z, false)){ return; } + $chunk = $this->subChunkHandler->currentChunk; + $oldHeightMap = $chunk->getHeightMap($x & 0xf, $z & 0xf); - $source = $this->world->getBlockAt($x, $y, $z); + $source = $this->subChunkHandler->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf); $yPlusOne = $y + 1; if($yPlusOne === $oldHeightMap){ //Block changed directly beneath the heightmap. Check if a block was removed or changed to a different light-filter. - $newHeightMap = $chunk->recalculateHeightMapColumn($x & 0x0f, $z & 0x0f, $this->lightFilters, $this->lightDiffusers); + $newHeightMap = $chunk->recalculateHeightMapColumn($x & 0x0f, $z & 0x0f, $this->lightFilters, $this->directSkyLightBlockers); }elseif($yPlusOne > $oldHeightMap){ //Block changed above the heightmap. - if($source->getLightFilter() > 0 or $source->diffusesSkyLight()){ + if($this->directSkyLightBlockers[$source]){ $chunk->setHeightMap($x & 0xf, $z & 0xf, $yPlusOne); $newHeightMap = $yPlusOne; }else{ //Block changed which has no effect on direct sky light, for example placing or removing glass. @@ -90,7 +91,7 @@ class SkyLightUpdate extends LightUpdate{ $this->setAndUpdateLight($x, $i, $z, 15); } }else{ //No heightmap change, block changed "underground" - $this->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentLight($x, $y, $z) - $this->lightFilters[$source->getFullId()])); + $this->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentLight($x, $y, $z) - $this->lightFilters[$source])); } } } diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 76320628ec..8550477dbd 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -950,6 +950,31 @@ parameters: count: 1 path: ../../../src/world/light/SkyLightUpdate.php + - + message: "#^Cannot call method getHeightMap\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/light/SkyLightUpdate.php + + - + message: "#^Cannot call method getFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" + count: 1 + path: ../../../src/world/light/SkyLightUpdate.php + + - + message: "#^Cannot call method recalculateHeightMapColumn\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/light/SkyLightUpdate.php + + - + message: "#^Only booleans are allowed in an if condition, bool\\|null given\\.$#" + count: 1 + path: ../../../src/world/light/SkyLightUpdate.php + + - + message: "#^Cannot call method setHeightMap\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/light/SkyLightUpdate.php + - message: "#^Only numeric types are allowed in \\-, int\\|null given on the right side\\.$#" count: 1 From 03de2bcc670528219044138013da4404871a5ca7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 8 Sep 2020 23:03:52 +0100 Subject: [PATCH 1864/3224] Chunk: simplify heightmap calculation --- src/world/format/Chunk.php | 20 ++++++++------------ src/world/generator/PopulationTask.php | 2 +- src/world/light/LightPopulationTask.php | 2 +- src/world/light/SkyLightUpdate.php | 2 +- tests/phpstan/configs/l8-baseline.neon | 5 +++++ 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index e842fef96d..0b76f00768 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -260,12 +260,10 @@ class Chunk{ /** * Recalculates the heightmap for the whole chunk. * - * @param \SplFixedArray|int[] $lightFilters - * @param \SplFixedArray|bool[] $lightDiffusers - * @phpstan-param \SplFixedArray $lightFilters - * @phpstan-param \SplFixedArray $lightDiffusers + * @param \SplFixedArray|bool[] $directSkyLightBlockers + * @phpstan-param \SplFixedArray $directSkyLightBlockers */ - public function recalculateHeightMap(\SplFixedArray $lightFilters, \SplFixedArray $lightDiffusers) : void{ + public function recalculateHeightMap(\SplFixedArray $directSkyLightBlockers) : void{ $maxSubChunkY = $this->subChunks->count() - 1; for(; $maxSubChunkY >= 0; $maxSubChunkY--){ if(!$this->getSubChunk($maxSubChunkY)->isEmptyFast()){ @@ -292,7 +290,7 @@ class Chunk{ $this->setHeightMap($x, $z, 0); }else{ for(; $y >= 0; --$y){ - if($lightFilters[$state = $this->getFullBlock($x, $y, $z)] > 1 or $lightDiffusers[$state]){ + if($directSkyLightBlockers[$this->getFullBlock($x, $y, $z)]){ $this->setHeightMap($x, $z, $y + 1); break; } @@ -307,17 +305,15 @@ class Chunk{ * * @param int $x 0-15 * @param int $z 0-15 - * @param \SplFixedArray|int[] $lightFilters - * @param \SplFixedArray|bool[] $lightDiffusers - * @phpstan-param \SplFixedArray $lightFilters - * @phpstan-param \SplFixedArray $lightDiffusers + * @param \SplFixedArray|bool[] $directSkyLightBlockers + * @phpstan-param \SplFixedArray $directSkyLightBlockers * * @return int New calculated heightmap value (0-256 inclusive) */ - public function recalculateHeightMapColumn(int $x, int $z, \SplFixedArray $lightFilters, \SplFixedArray $lightDiffusers) : int{ + public function recalculateHeightMapColumn(int $x, int $z, \SplFixedArray $directSkyLightBlockers) : int{ $y = $this->getHighestBlockAt($x, $z); for(; $y >= 0; --$y){ - if($lightFilters[$state = $this->getFullBlock($x, $y, $z)] > 1 or $lightDiffusers[$state]){ + if($directSkyLightBlockers[$this->getFullBlock($x, $y, $z)]){ break; } } diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 979909119b..f4f3df3acb 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -119,7 +119,7 @@ class PopulationTask extends AsyncTask{ $chunk->setPopulated(); $blockFactory = BlockFactory::getInstance(); - $chunk->recalculateHeightMap($blockFactory->lightFilter, $blockFactory->blocksDirectSkyLight); + $chunk->recalculateHeightMap($blockFactory->blocksDirectSkyLight); $chunk->populateSkyLight($blockFactory->lightFilter); $chunk->setLightPopulated(); diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index e066c2f2af..bd734202f4 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -61,7 +61,7 @@ class LightPopulationTask extends AsyncTask{ $chunk = FastChunkSerializer::deserialize($this->chunk); $blockFactory = BlockFactory::getInstance(); - $chunk->recalculateHeightMap($blockFactory->lightFilter, $blockFactory->blocksDirectSkyLight); + $chunk->recalculateHeightMap($blockFactory->blocksDirectSkyLight); $chunk->populateSkyLight($blockFactory->lightFilter); $chunk->setLightPopulated(); diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index ac2054339b..4c63bbc2db 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -70,7 +70,7 @@ class SkyLightUpdate extends LightUpdate{ $yPlusOne = $y + 1; if($yPlusOne === $oldHeightMap){ //Block changed directly beneath the heightmap. Check if a block was removed or changed to a different light-filter. - $newHeightMap = $chunk->recalculateHeightMapColumn($x & 0x0f, $z & 0x0f, $this->lightFilters, $this->directSkyLightBlockers); + $newHeightMap = $chunk->recalculateHeightMapColumn($x & 0x0f, $z & 0x0f, $this->directSkyLightBlockers); }elseif($yPlusOne > $oldHeightMap){ //Block changed above the heightmap. if($this->directSkyLightBlockers[$source]){ $chunk->setHeightMap($x & 0xf, $z & 0xf, $yPlusOne); diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 8550477dbd..37b22a9ded 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -755,6 +755,11 @@ parameters: count: 1 path: ../../../src/world/biome/BiomeRegistry.php + - + message: "#^Only booleans are allowed in an if condition, bool\\|null given\\.$#" + count: 2 + path: ../../../src/world/format/Chunk.php + - message: "#^Method pocketmine\\\\world\\\\format\\\\Chunk\\:\\:getSubChunk\\(\\) should return pocketmine\\\\world\\\\format\\\\SubChunkInterface but returns pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" count: 1 From bde24d927941252da96278470055efbf293eff41 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 8 Sep 2020 23:14:10 +0100 Subject: [PATCH 1865/3224] LightUpdate: remove unused field --- src/world/light/LightUpdate.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/world/light/LightUpdate.php b/src/world/light/LightUpdate.php index e1159bea5a..8a6056c1b9 100644 --- a/src/world/light/LightUpdate.php +++ b/src/world/light/LightUpdate.php @@ -32,9 +32,6 @@ use function max; //TODO: make light updates asynchronous abstract class LightUpdate{ - /** @var ChunkManager */ - protected $world; - /** * @var \SplFixedArray|int[] * @phpstan-var \SplFixedArray @@ -79,13 +76,12 @@ abstract class LightUpdate{ * @phpstan-param \SplFixedArray $lightFilters */ public function __construct(ChunkManager $world, \SplFixedArray $lightFilters){ - $this->world = $world; $this->lightFilters = $lightFilters; $this->removalQueue = new \SplQueue(); $this->spreadQueue = new \SplQueue(); - $this->subChunkHandler = new SubChunkIteratorManager($this->world); + $this->subChunkHandler = new SubChunkIteratorManager($world); $this->subChunkHandler->onSubChunkChange(\Closure::fromCallable([$this, 'updateLightArrayRef'])); } From c20ac82fe62fd161727e2e5c40fe2fa9c46c3bcd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 9 Sep 2020 01:06:09 +0100 Subject: [PATCH 1866/3224] LightUpdate: Move propagation-specific state to a separate unit this solves multiple architectural issues: - improves reusability by avoiding having old state info stick around to fuck stuff up - prevents access to propagation state from outside of propagation this also reduces the latent memory usage of light-updates after they have been used. TODO: we could probably change LightPropagationContext to LightPropagator and move all the propagation-specific code into it if we can solve the subchunk-iterator and effective light problems. --- src/world/light/LightPropagationContext.php | 54 +++++++++++++ src/world/light/LightUpdate.php | 84 ++++++++------------- 2 files changed, 85 insertions(+), 53 deletions(-) create mode 100644 src/world/light/LightPropagationContext.php diff --git a/src/world/light/LightPropagationContext.php b/src/world/light/LightPropagationContext.php new file mode 100644 index 0000000000..a13e5ae200 --- /dev/null +++ b/src/world/light/LightPropagationContext.php @@ -0,0 +1,54 @@ + + */ + public $spreadQueue; + /** + * @var true[] + * @phpstan-var array + */ + public $spreadVisited = []; + + /** + * @var \SplQueue + * @phpstan-var \SplQueue + */ + public $removalQueue; + /** + * @var true[] + * @phpstan-var array + */ + public $removalVisited = []; + + public function __construct(){ + $this->removalQueue = new \SplQueue(); + $this->spreadQueue = new \SplQueue(); + } +} diff --git a/src/world/light/LightUpdate.php b/src/world/light/LightUpdate.php index 8a6056c1b9..f3c6c5eb4d 100644 --- a/src/world/light/LightUpdate.php +++ b/src/world/light/LightUpdate.php @@ -44,27 +44,6 @@ abstract class LightUpdate{ */ protected $updateNodes = []; - /** - * @var \SplQueue - * @phpstan-var \SplQueue - */ - protected $spreadQueue; - /** - * @var true[] - * @phpstan-var array - */ - protected $spreadVisited = []; - - /** - * @var \SplQueue - * @phpstan-var \SplQueue - */ - protected $removalQueue; - /** - * @var true[] - * @phpstan-var array - */ - protected $removalVisited = []; /** @var SubChunkIteratorManager */ protected $subChunkHandler; @@ -78,9 +57,6 @@ abstract class LightUpdate{ public function __construct(ChunkManager $world, \SplFixedArray $lightFilters){ $this->lightFilters = $lightFilters; - $this->removalQueue = new \SplQueue(); - $this->spreadQueue = new \SplQueue(); - $this->subChunkHandler = new SubChunkIteratorManager($world); $this->subChunkHandler->onSubChunkChange(\Closure::fromCallable([$this, 'updateLightArrayRef'])); } @@ -117,7 +93,8 @@ abstract class LightUpdate{ $this->updateNodes[World::blockHash($x, $y, $z)] = [$x, $y, $z, $newLevel]; } - private function prepareNodes() : void{ + private function prepareNodes() : LightPropagationContext{ + $context = new LightPropagationContext(); foreach($this->updateNodes as $blockHash => [$x, $y, $z, $newLevel]){ if($this->subChunkHandler->moveTo($x, $y, $z, false)){ $oldLevel = $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); @@ -125,24 +102,25 @@ abstract class LightUpdate{ if($oldLevel !== $newLevel){ $this->currentLightArray->set($x & 0xf, $y & 0xf, $z & 0xf, $newLevel); if($oldLevel < $newLevel){ //light increased - $this->spreadVisited[$blockHash] = true; - $this->spreadQueue->enqueue([$x, $y, $z]); + $context->spreadVisited[$blockHash] = true; + $context->spreadQueue->enqueue([$x, $y, $z]); }else{ //light removed - $this->removalVisited[$blockHash] = true; - $this->removalQueue->enqueue([$x, $y, $z, $oldLevel]); + $context->removalVisited[$blockHash] = true; + $context->removalQueue->enqueue([$x, $y, $z, $oldLevel]); } } } } + return $context; } public function execute() : int{ - $this->prepareNodes(); + $context = $this->prepareNodes(); $touched = 0; - while(!$this->removalQueue->isEmpty()){ + while(!$context->removalQueue->isEmpty()){ $touched++; - list($x, $y, $z, $oldAdjacentLight) = $this->removalQueue->dequeue(); + [$x, $y, $z, $oldAdjacentLight] = $context->removalQueue->dequeue(); $points = [ [$x + 1, $y, $z], @@ -153,21 +131,21 @@ abstract class LightUpdate{ [$x, $y, $z - 1] ]; - foreach($points as list($cx, $cy, $cz)){ + foreach($points as [$cx, $cy, $cz]){ if($this->subChunkHandler->moveTo($cx, $cy, $cz, false)){ - $this->computeRemoveLight($cx, $cy, $cz, $oldAdjacentLight); - }elseif($this->getEffectiveLight($cx, $cy, $cz) > 0 and !isset($this->spreadVisited[$index = World::blockHash($cx, $cy, $cz)])){ - $this->spreadVisited[$index] = true; - $this->spreadQueue->enqueue([$cx, $cy, $cz]); + $this->computeRemoveLight($cx, $cy, $cz, $oldAdjacentLight, $context); + }elseif($this->getEffectiveLight($cx, $cy, $cz) > 0 and !isset($context->spreadVisited[$index = World::blockHash($cx, $cy, $cz)])){ + $context->spreadVisited[$index] = true; + $context->spreadQueue->enqueue([$cx, $cy, $cz]); } } } - while(!$this->spreadQueue->isEmpty()){ + while(!$context->spreadQueue->isEmpty()){ $touched++; - list($x, $y, $z) = $this->spreadQueue->dequeue(); + [$x, $y, $z] = $context->spreadQueue->dequeue(); - unset($this->spreadVisited[World::blockHash($x, $y, $z)]); + unset($context->spreadVisited[World::blockHash($x, $y, $z)]); $newAdjacentLight = $this->getEffectiveLight($x, $y, $z); if($newAdjacentLight <= 0){ @@ -183,9 +161,9 @@ abstract class LightUpdate{ [$x, $y, $z - 1] ]; - foreach($points as list($cx, $cy, $cz)){ + foreach($points as [$cx, $cy, $cz]){ if($this->subChunkHandler->moveTo($cx, $cy, $cz, false)){ - $this->computeSpreadLight($cx, $cy, $cz, $newAdjacentLight); + $this->computeSpreadLight($cx, $cy, $cz, $newAdjacentLight, $context); } } } @@ -193,36 +171,36 @@ abstract class LightUpdate{ return $touched; } - protected function computeRemoveLight(int $x, int $y, int $z, int $oldAdjacentLevel) : void{ + protected function computeRemoveLight(int $x, int $y, int $z, int $oldAdjacentLevel, LightPropagationContext $context) : void{ $current = $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); if($current !== 0 and $current < $oldAdjacentLevel){ $this->currentLightArray->set($x & 0xf, $y & 0xf, $z & 0xf, 0); - if(!isset($this->removalVisited[$index = World::blockHash($x, $y, $z)])){ - $this->removalVisited[$index] = true; + if(!isset($context->removalVisited[$index = World::blockHash($x, $y, $z)])){ + $context->removalVisited[$index] = true; if($current > 1){ - $this->removalQueue->enqueue([$x, $y, $z, $current]); + $context->removalQueue->enqueue([$x, $y, $z, $current]); } } }elseif($current >= $oldAdjacentLevel){ - if(!isset($this->spreadVisited[$index = World::blockHash($x, $y, $z)])){ - $this->spreadVisited[$index] = true; - $this->spreadQueue->enqueue([$x, $y, $z]); + if(!isset($context->spreadVisited[$index = World::blockHash($x, $y, $z)])){ + $context->spreadVisited[$index] = true; + $context->spreadQueue->enqueue([$x, $y, $z]); } } } - protected function computeSpreadLight(int $x, int $y, int $z, int $newAdjacentLevel) : void{ + protected function computeSpreadLight(int $x, int $y, int $z, int $newAdjacentLevel, LightPropagationContext $context) : void{ $current = $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); $potentialLight = $newAdjacentLevel - $this->lightFilters[$this->subChunkHandler->currentSubChunk->getFullBlock($x & 0x0f, $y & 0x0f, $z & 0x0f)]; if($current < $potentialLight){ $this->currentLightArray->set($x & 0xf, $y & 0xf, $z & 0xf, $potentialLight); - if(!isset($this->spreadVisited[$index = World::blockHash($x, $y, $z)]) and $potentialLight > 1){ - $this->spreadVisited[$index] = true; - $this->spreadQueue->enqueue([$x, $y, $z]); + if(!isset($context->spreadVisited[$index = World::blockHash($x, $y, $z)]) and $potentialLight > 1){ + $context->spreadVisited[$index] = true; + $context->spreadQueue->enqueue([$x, $y, $z]); } } } From 9d0ac297bbeb4b9a4330685b24c4045f7fb0c5e9 Mon Sep 17 00:00:00 2001 From: SOFe Date: Thu, 10 Sep 2020 16:48:52 +0800 Subject: [PATCH 1867/3224] Improved documentation for `CancellableTrait` --- src/event/CancellableTrait.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/event/CancellableTrait.php b/src/event/CancellableTrait.php index 0fe5186ed2..c4eae42902 100644 --- a/src/event/CancellableTrait.php +++ b/src/event/CancellableTrait.php @@ -24,7 +24,11 @@ declare(strict_types=1); namespace pocketmine\event; /** - * This trait implements Cancellable components for events. + * This trait provides a basic boolean-setter-style implementation for `Cancellable` to reduce boilerplate. + * The precise meaning of `setCancelled` is subject to definition by the class using this trait. + * + * Implementors of `Cancellable` are not required to use this trait. + * * @see Cancellable */ trait CancellableTrait{ From 2281df8c97fbb2319115e54aa225bdb00fcb389d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 20 Sep 2020 12:01:24 +0100 Subject: [PATCH 1868/3224] Updated build/php submodule to pmmp/php-build-scripts@0eb28b8b66bef892c04b7d1d7bf9059b4e2ca600 --- build/php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/php b/build/php index d88132ee55..0eb28b8b66 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit d88132ee556e0049d2caa8f57a7832a784308e62 +Subproject commit 0eb28b8b66bef892c04b7d1d7bf9059b4e2ca600 From 5661d0496f37d0565a0aa2861843faaa5e93d669 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 20 Sep 2020 12:16:11 +0100 Subject: [PATCH 1869/3224] RuntimeBlockMapping::toRuntimeId() now accepts a single integer instead of id/meta the expectation is that eventually this will receive arbitrary internal runtime IDs instead of static id/meta, and RuntimeBlockMapping doesn't really care about this crap anyway. --- src/entity/object/FallingBlock.php | 2 +- src/network/mcpe/convert/RuntimeBlockMapping.php | 16 +++++----------- src/network/mcpe/serializer/ChunkSerializer.php | 2 +- src/world/World.php | 2 +- src/world/particle/BlockPunchParticle.php | 2 +- src/world/particle/DestroyBlockParticle.php | 2 +- src/world/particle/TerrainParticle.php | 2 +- src/world/sound/BlockBreakSound.php | 2 +- src/world/sound/BlockPlaceSound.php | 2 +- src/world/sound/BlockPunchSound.php | 2 +- src/world/sound/EntityLandSound.php | 2 +- 11 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/entity/object/FallingBlock.php b/src/entity/object/FallingBlock.php index cfca869ea7..7841233530 100644 --- a/src/entity/object/FallingBlock.php +++ b/src/entity/object/FallingBlock.php @@ -147,7 +147,7 @@ class FallingBlock extends Entity{ protected function syncNetworkData(EntityMetadataCollection $properties) : void{ parent::syncNetworkData($properties); - $properties->setInt(EntityMetadataProperties::VARIANT, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getId(), $this->block->getMeta())); + $properties->setInt(EntityMetadataProperties::VARIANT, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId())); } public function getOffsetPosition(Vector3 $vector3) : Vector3{ diff --git a/src/network/mcpe/convert/RuntimeBlockMapping.php b/src/network/mcpe/convert/RuntimeBlockMapping.php index 805d6bb798..3f17ebd1e9 100644 --- a/src/network/mcpe/convert/RuntimeBlockMapping.php +++ b/src/network/mcpe/convert/RuntimeBlockMapping.php @@ -135,21 +135,15 @@ final class RuntimeBlockMapping{ return $table; } - public function toRuntimeId(int $id, int $meta = 0) : int{ - /* - * try id+meta first - * if not found, try id+0 (strip meta) - * if still not found, return update! block - */ - return $this->legacyToRuntimeMap[($id << 4) | $meta] ?? $this->legacyToRuntimeMap[$id << 4] ?? $this->legacyToRuntimeMap[BlockLegacyIds::INFO_UPDATE << 4]; + public function toRuntimeId(int $internalStateId) : int{ + return $this->legacyToRuntimeMap[$internalStateId] ?? $this->legacyToRuntimeMap[BlockLegacyIds::INFO_UPDATE << 4]; } /** - * @return int[] [id, meta] + * @return int */ - public function fromRuntimeId(int $runtimeId) : array{ - $v = $this->runtimeToLegacyMap[$runtimeId]; - return [$v >> 4, $v & 0xf]; + public function fromRuntimeId(int $runtimeId) : int{ + return $this->runtimeToLegacyMap[$runtimeId]; } private function registerMapping(int $staticRuntimeId, int $legacyId, int $legacyMeta) : void{ diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index 4b730757e8..abf0e1b25c 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -71,7 +71,7 @@ final class ChunkSerializer{ //zigzag and just shift directly. $stream->putUnsignedVarInt(count($palette) << 1); //yes, this is intentionally zigzag foreach($palette as $p){ - $stream->put(Binary::writeUnsignedVarInt($blockMapper->toRuntimeId($p >> 4, $p & 0xf) << 1)); + $stream->put(Binary::writeUnsignedVarInt($blockMapper->toRuntimeId($p) << 1)); } } } diff --git a/src/world/World.php b/src/world/World.php index a457f5cb60..95de642d98 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -829,7 +829,7 @@ class World implements ChunkManager{ } $fullBlock = $this->getBlockAt($b->x, $b->y, $b->z); - $packets[] = UpdateBlockPacket::create($b->x, $b->y, $b->z, RuntimeBlockMapping::getInstance()->toRuntimeId($fullBlock->getId(), $fullBlock->getMeta())); + $packets[] = UpdateBlockPacket::create($b->x, $b->y, $b->z, RuntimeBlockMapping::getInstance()->toRuntimeId($fullBlock->getFullId())); $tile = $this->getTileAt($b->x, $b->y, $b->z); if($tile instanceof Spawnable){ diff --git a/src/world/particle/BlockPunchParticle.php b/src/world/particle/BlockPunchParticle.php index a932099a61..be99c9452b 100644 --- a/src/world/particle/BlockPunchParticle.php +++ b/src/world/particle/BlockPunchParticle.php @@ -44,6 +44,6 @@ class BlockPunchParticle implements Particle{ } public function encode(Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_PUNCH_BLOCK, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getId(), $this->block->getMeta()) | ($this->face << 24), $pos); + return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_PUNCH_BLOCK, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()) | ($this->face << 24), $pos); } } diff --git a/src/world/particle/DestroyBlockParticle.php b/src/world/particle/DestroyBlockParticle.php index 0d4d962747..d43b848508 100644 --- a/src/world/particle/DestroyBlockParticle.php +++ b/src/world/particle/DestroyBlockParticle.php @@ -38,6 +38,6 @@ class DestroyBlockParticle implements Particle{ } public function encode(Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_DESTROY, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getId(), $this->block->getMeta()), $pos); + return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_DESTROY, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()), $pos); } } diff --git a/src/world/particle/TerrainParticle.php b/src/world/particle/TerrainParticle.php index e96ad680b4..4b9f07c66a 100644 --- a/src/world/particle/TerrainParticle.php +++ b/src/world/particle/TerrainParticle.php @@ -38,6 +38,6 @@ class TerrainParticle implements Particle{ } public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::TERRAIN, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getId(), $this->block->getMeta()), $pos); + return LevelEventPacket::standardParticle(ParticleIds::TERRAIN, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()), $pos); } } diff --git a/src/world/sound/BlockBreakSound.php b/src/world/sound/BlockBreakSound.php index 4d5e6a76e3..81809e1267 100644 --- a/src/world/sound/BlockBreakSound.php +++ b/src/world/sound/BlockBreakSound.php @@ -38,6 +38,6 @@ class BlockBreakSound implements Sound{ } public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BREAK, $pos, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getId(), $this->block->getMeta())); + return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BREAK, $pos, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId())); } } diff --git a/src/world/sound/BlockPlaceSound.php b/src/world/sound/BlockPlaceSound.php index d6d9eef299..9441e5bc97 100644 --- a/src/world/sound/BlockPlaceSound.php +++ b/src/world/sound/BlockPlaceSound.php @@ -38,6 +38,6 @@ class BlockPlaceSound implements Sound{ } public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_PLACE, $pos, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getId(), $this->block->getMeta())); + return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_PLACE, $pos, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId())); } } diff --git a/src/world/sound/BlockPunchSound.php b/src/world/sound/BlockPunchSound.php index ef9930285e..33a15cce58 100644 --- a/src/world/sound/BlockPunchSound.php +++ b/src/world/sound/BlockPunchSound.php @@ -44,7 +44,7 @@ class BlockPunchSound implements Sound{ return LevelSoundEventPacket::create( LevelSoundEventPacket::SOUND_HIT, $pos, - RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getId(), $this->block->getMeta()) + RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()) ); } } diff --git a/src/world/sound/EntityLandSound.php b/src/world/sound/EntityLandSound.php index 53b2d033b7..47e9736ab1 100644 --- a/src/world/sound/EntityLandSound.php +++ b/src/world/sound/EntityLandSound.php @@ -48,7 +48,7 @@ class EntityLandSound implements Sound{ return LevelSoundEventPacket::create( LevelSoundEventPacket::SOUND_LAND, $pos, - RuntimeBlockMapping::getInstance()->toRuntimeId($this->blockLandedOn->getId(), $this->blockLandedOn->getMeta()), + RuntimeBlockMapping::getInstance()->toRuntimeId($this->blockLandedOn->getFullId()), $this->entity::getNetworkTypeId() //TODO: does isBaby have any relevance here? ); From 4879df626dc19c6fc795926f37e96211cf32c3ca Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 20 Sep 2020 12:41:53 +0100 Subject: [PATCH 1870/3224] Reduced LightUpdate dependency on ChunkManager to indirect this opens the gateway for alternative SubChunkIteratorManager implementations which don't use ChunkManager at all. --- src/world/World.php | 5 +++-- src/world/light/BlockLightUpdate.php | 6 +++--- src/world/light/LightUpdate.php | 5 ++--- src/world/light/SkyLightUpdate.php | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 95de642d98..6cfd66eed6 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -77,6 +77,7 @@ use pocketmine\world\particle\DestroyBlockParticle; use pocketmine\world\particle\Particle; use pocketmine\world\sound\BlockPlaceSound; use pocketmine\world\sound\Sound; +use pocketmine\world\utils\SubChunkIteratorManager; use function abs; use function array_fill_keys; use function array_map; @@ -1165,14 +1166,14 @@ class World implements ChunkManager{ $blockFactory = BlockFactory::getInstance(); $this->timings->doBlockSkyLightUpdates->startTiming(); if($this->skyLightUpdate === null){ - $this->skyLightUpdate = new SkyLightUpdate($this, $blockFactory->lightFilter, $blockFactory->blocksDirectSkyLight); + $this->skyLightUpdate = new SkyLightUpdate(new SubChunkIteratorManager($this), $blockFactory->lightFilter, $blockFactory->blocksDirectSkyLight); } $this->skyLightUpdate->recalculateNode($x, $y, $z); $this->timings->doBlockSkyLightUpdates->stopTiming(); $this->timings->doBlockLightUpdates->startTiming(); if($this->blockLightUpdate === null){ - $this->blockLightUpdate = new BlockLightUpdate($this, $blockFactory->lightFilter, $blockFactory->light); + $this->blockLightUpdate = new BlockLightUpdate(new SubChunkIteratorManager($this), $blockFactory->lightFilter, $blockFactory->light); } $this->blockLightUpdate->recalculateNode($x, $y, $z); $this->timings->doBlockLightUpdates->stopTiming(); diff --git a/src/world/light/BlockLightUpdate.php b/src/world/light/BlockLightUpdate.php index fc48e27bb9..ff6125a74d 100644 --- a/src/world/light/BlockLightUpdate.php +++ b/src/world/light/BlockLightUpdate.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\light; -use pocketmine\world\ChunkManager; +use pocketmine\world\utils\SubChunkIteratorManager; use function max; class BlockLightUpdate extends LightUpdate{ @@ -40,8 +40,8 @@ class BlockLightUpdate extends LightUpdate{ * @phpstan-param \SplFixedArray $lightFilters * @phpstan-param \SplFixedArray $lightEmitters */ - public function __construct(ChunkManager $world, \SplFixedArray $lightFilters, \SplFixedArray $lightEmitters){ - parent::__construct($world, $lightFilters); + public function __construct(SubChunkIteratorManager $subChunkHandler, \SplFixedArray $lightFilters, \SplFixedArray $lightEmitters){ + parent::__construct($subChunkHandler, $lightFilters); $this->lightEmitters = $lightEmitters; } diff --git a/src/world/light/LightUpdate.php b/src/world/light/LightUpdate.php index f3c6c5eb4d..e0b325a84e 100644 --- a/src/world/light/LightUpdate.php +++ b/src/world/light/LightUpdate.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\world\light; -use pocketmine\world\ChunkManager; use pocketmine\world\format\LightArray; use pocketmine\world\utils\SubChunkIteratorManager; use pocketmine\world\World; @@ -54,10 +53,10 @@ abstract class LightUpdate{ * @param \SplFixedArray|int[] $lightFilters * @phpstan-param \SplFixedArray $lightFilters */ - public function __construct(ChunkManager $world, \SplFixedArray $lightFilters){ + public function __construct(SubChunkIteratorManager $subChunkHandler, \SplFixedArray $lightFilters){ $this->lightFilters = $lightFilters; - $this->subChunkHandler = new SubChunkIteratorManager($world); + $this->subChunkHandler = $subChunkHandler; $this->subChunkHandler->onSubChunkChange(\Closure::fromCallable([$this, 'updateLightArrayRef'])); } diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index 4c63bbc2db..abf84f80ff 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\light; -use pocketmine\world\ChunkManager; +use pocketmine\world\utils\SubChunkIteratorManager; use pocketmine\world\World; use function max; @@ -41,8 +41,8 @@ class SkyLightUpdate extends LightUpdate{ * @phpstan-param \SplFixedArray $lightFilters * @phpstan-param \SplFixedArray $directSkyLightBlockers */ - public function __construct(ChunkManager $world, \SplFixedArray $lightFilters, \SplFixedArray $directSkyLightBlockers){ - parent::__construct($world, $lightFilters); + public function __construct(SubChunkIteratorManager $subChunkHandler, \SplFixedArray $lightFilters, \SplFixedArray $directSkyLightBlockers){ + parent::__construct($subChunkHandler, $lightFilters); $this->directSkyLightBlockers = $directSkyLightBlockers; } From c9d2edcb4d8d8b1568c8f8385817b4b2a5282f67 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 20 Sep 2020 12:47:44 +0100 Subject: [PATCH 1871/3224] Rename SubChunkIteratorManager -> SubChunkExplorer --- src/world/Explosion.php | 12 +++++----- src/world/SimpleChunkManager.php | 6 ++--- src/world/World.php | 6 ++--- src/world/light/BlockLightUpdate.php | 12 +++++----- src/world/light/LightUpdate.php | 22 +++++++++---------- src/world/light/SkyLightUpdate.php | 16 +++++++------- ...eratorManager.php => SubChunkExplorer.php} | 2 +- 7 files changed, 38 insertions(+), 38 deletions(-) rename src/world/utils/{SubChunkIteratorManager.php => SubChunkExplorer.php} (98%) diff --git a/src/world/Explosion.php b/src/world/Explosion.php index 9df27e8ae5..49952a3063 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -39,7 +39,7 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\world\particle\HugeExplodeSeedParticle; use pocketmine\world\sound\ExplodeSound; -use pocketmine\world\utils\SubChunkIteratorManager; +use pocketmine\world\utils\SubChunkExplorer; use function ceil; use function floor; use function mt_rand; @@ -62,8 +62,8 @@ class Explosion{ /** @var Entity|Block|null */ private $what; - /** @var SubChunkIteratorManager */ - private $subChunkHandler; + /** @var SubChunkExplorer */ + private $subChunkExplorer; /** * @param Entity|Block|null $what @@ -81,7 +81,7 @@ class Explosion{ $this->size = $size; $this->what = $what; - $this->subChunkHandler = new SubChunkIteratorManager($this->world); + $this->subChunkExplorer = new SubChunkExplorer($this->world); } /** @@ -123,11 +123,11 @@ class Explosion{ $pointerY += $shiftY; $pointerZ += $shiftZ; - if(!$this->subChunkHandler->moveTo($vBlockX, $vBlockY, $vBlockZ, false)){ + if(!$this->subChunkExplorer->moveTo($vBlockX, $vBlockY, $vBlockZ, false)){ continue; } - $state = $this->subChunkHandler->currentSubChunk->getFullBlock($vBlockX & 0x0f, $vBlockY & 0x0f, $vBlockZ & 0x0f); + $state = $this->subChunkExplorer->currentSubChunk->getFullBlock($vBlockX & 0x0f, $vBlockY & 0x0f, $vBlockZ & 0x0f); if($state !== 0){ $blastForce -= ($blockFactory->blastResistance[$state] / 5 + 0.3) * $this->stepLen; diff --git a/src/world/SimpleChunkManager.php b/src/world/SimpleChunkManager.php index 754142e5be..9ffeab3345 100644 --- a/src/world/SimpleChunkManager.php +++ b/src/world/SimpleChunkManager.php @@ -28,7 +28,7 @@ use pocketmine\block\BlockFactory; use pocketmine\block\VanillaBlocks; use pocketmine\utils\Limits; use pocketmine\world\format\Chunk; -use pocketmine\world\utils\SubChunkIteratorManager; +use pocketmine\world\utils\SubChunkExplorer; class SimpleChunkManager implements ChunkManager{ @@ -38,7 +38,7 @@ class SimpleChunkManager implements ChunkManager{ /** @var int */ protected $worldHeight; - /** @var SubChunkIteratorManager */ + /** @var SubChunkExplorer */ protected $terrainPointer; /** @@ -46,7 +46,7 @@ class SimpleChunkManager implements ChunkManager{ */ public function __construct(int $worldHeight = World::Y_MAX){ $this->worldHeight = $worldHeight; - $this->terrainPointer = new SubChunkIteratorManager($this); + $this->terrainPointer = new SubChunkExplorer($this); } public function getBlockAt(int $x, int $y, int $z) : Block{ diff --git a/src/world/World.php b/src/world/World.php index 6cfd66eed6..6f736233ea 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -77,7 +77,7 @@ use pocketmine\world\particle\DestroyBlockParticle; use pocketmine\world\particle\Particle; use pocketmine\world\sound\BlockPlaceSound; use pocketmine\world\sound\Sound; -use pocketmine\world\utils\SubChunkIteratorManager; +use pocketmine\world\utils\SubChunkExplorer; use function abs; use function array_fill_keys; use function array_map; @@ -1166,14 +1166,14 @@ class World implements ChunkManager{ $blockFactory = BlockFactory::getInstance(); $this->timings->doBlockSkyLightUpdates->startTiming(); if($this->skyLightUpdate === null){ - $this->skyLightUpdate = new SkyLightUpdate(new SubChunkIteratorManager($this), $blockFactory->lightFilter, $blockFactory->blocksDirectSkyLight); + $this->skyLightUpdate = new SkyLightUpdate(new SubChunkExplorer($this), $blockFactory->lightFilter, $blockFactory->blocksDirectSkyLight); } $this->skyLightUpdate->recalculateNode($x, $y, $z); $this->timings->doBlockSkyLightUpdates->stopTiming(); $this->timings->doBlockLightUpdates->startTiming(); if($this->blockLightUpdate === null){ - $this->blockLightUpdate = new BlockLightUpdate(new SubChunkIteratorManager($this), $blockFactory->lightFilter, $blockFactory->light); + $this->blockLightUpdate = new BlockLightUpdate(new SubChunkExplorer($this), $blockFactory->lightFilter, $blockFactory->light); } $this->blockLightUpdate->recalculateNode($x, $y, $z); $this->timings->doBlockLightUpdates->stopTiming(); diff --git a/src/world/light/BlockLightUpdate.php b/src/world/light/BlockLightUpdate.php index ff6125a74d..6a1fbfc73e 100644 --- a/src/world/light/BlockLightUpdate.php +++ b/src/world/light/BlockLightUpdate.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\light; -use pocketmine\world\utils\SubChunkIteratorManager; +use pocketmine\world\utils\SubChunkExplorer; use function max; class BlockLightUpdate extends LightUpdate{ @@ -40,18 +40,18 @@ class BlockLightUpdate extends LightUpdate{ * @phpstan-param \SplFixedArray $lightFilters * @phpstan-param \SplFixedArray $lightEmitters */ - public function __construct(SubChunkIteratorManager $subChunkHandler, \SplFixedArray $lightFilters, \SplFixedArray $lightEmitters){ - parent::__construct($subChunkHandler, $lightFilters); + public function __construct(SubChunkExplorer $subChunkExplorer, \SplFixedArray $lightFilters, \SplFixedArray $lightEmitters){ + parent::__construct($subChunkExplorer, $lightFilters); $this->lightEmitters = $lightEmitters; } protected function updateLightArrayRef() : void{ - $this->currentLightArray = $this->subChunkHandler->currentSubChunk->getBlockLightArray(); + $this->currentLightArray = $this->subChunkExplorer->currentSubChunk->getBlockLightArray(); } public function recalculateNode(int $x, int $y, int $z) : void{ - if($this->subChunkHandler->moveTo($x, $y, $z, false)){ - $block = $this->subChunkHandler->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf); + if($this->subChunkExplorer->moveTo($x, $y, $z, false)){ + $block = $this->subChunkExplorer->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf); $this->setAndUpdateLight($x, $y, $z, max($this->lightEmitters[$block], $this->getHighestAdjacentLight($x, $y, $z) - $this->lightFilters[$block])); } } diff --git a/src/world/light/LightUpdate.php b/src/world/light/LightUpdate.php index e0b325a84e..afa029ed33 100644 --- a/src/world/light/LightUpdate.php +++ b/src/world/light/LightUpdate.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\world\light; use pocketmine\world\format\LightArray; -use pocketmine\world\utils\SubChunkIteratorManager; +use pocketmine\world\utils\SubChunkExplorer; use pocketmine\world\World; use function max; @@ -43,8 +43,8 @@ abstract class LightUpdate{ */ protected $updateNodes = []; - /** @var SubChunkIteratorManager */ - protected $subChunkHandler; + /** @var SubChunkExplorer */ + protected $subChunkExplorer; /** @var LightArray|null */ protected $currentLightArray = null; @@ -53,11 +53,11 @@ abstract class LightUpdate{ * @param \SplFixedArray|int[] $lightFilters * @phpstan-param \SplFixedArray $lightFilters */ - public function __construct(SubChunkIteratorManager $subChunkHandler, \SplFixedArray $lightFilters){ + public function __construct(SubChunkExplorer $subChunkExplorer, \SplFixedArray $lightFilters){ $this->lightFilters = $lightFilters; - $this->subChunkHandler = $subChunkHandler; - $this->subChunkHandler->onSubChunkChange(\Closure::fromCallable([$this, 'updateLightArrayRef'])); + $this->subChunkExplorer = $subChunkExplorer; + $this->subChunkExplorer->onSubChunkChange(\Closure::fromCallable([$this, 'updateLightArrayRef'])); } abstract protected function updateLightArrayRef() : void; @@ -65,7 +65,7 @@ abstract class LightUpdate{ abstract public function recalculateNode(int $x, int $y, int $z) : void; protected function getEffectiveLight(int $x, int $y, int $z) : int{ - if($this->subChunkHandler->moveTo($x, $y, $z, false)){ + if($this->subChunkExplorer->moveTo($x, $y, $z, false)){ return $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); } return 0; @@ -95,7 +95,7 @@ abstract class LightUpdate{ private function prepareNodes() : LightPropagationContext{ $context = new LightPropagationContext(); foreach($this->updateNodes as $blockHash => [$x, $y, $z, $newLevel]){ - if($this->subChunkHandler->moveTo($x, $y, $z, false)){ + if($this->subChunkExplorer->moveTo($x, $y, $z, false)){ $oldLevel = $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); if($oldLevel !== $newLevel){ @@ -131,7 +131,7 @@ abstract class LightUpdate{ ]; foreach($points as [$cx, $cy, $cz]){ - if($this->subChunkHandler->moveTo($cx, $cy, $cz, false)){ + if($this->subChunkExplorer->moveTo($cx, $cy, $cz, false)){ $this->computeRemoveLight($cx, $cy, $cz, $oldAdjacentLight, $context); }elseif($this->getEffectiveLight($cx, $cy, $cz) > 0 and !isset($context->spreadVisited[$index = World::blockHash($cx, $cy, $cz)])){ $context->spreadVisited[$index] = true; @@ -161,7 +161,7 @@ abstract class LightUpdate{ ]; foreach($points as [$cx, $cy, $cz]){ - if($this->subChunkHandler->moveTo($cx, $cy, $cz, false)){ + if($this->subChunkExplorer->moveTo($cx, $cy, $cz, false)){ $this->computeSpreadLight($cx, $cy, $cz, $newAdjacentLight, $context); } } @@ -192,7 +192,7 @@ abstract class LightUpdate{ protected function computeSpreadLight(int $x, int $y, int $z, int $newAdjacentLevel, LightPropagationContext $context) : void{ $current = $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); - $potentialLight = $newAdjacentLevel - $this->lightFilters[$this->subChunkHandler->currentSubChunk->getFullBlock($x & 0x0f, $y & 0x0f, $z & 0x0f)]; + $potentialLight = $newAdjacentLevel - $this->lightFilters[$this->subChunkExplorer->currentSubChunk->getFullBlock($x & 0x0f, $y & 0x0f, $z & 0x0f)]; if($current < $potentialLight){ $this->currentLightArray->set($x & 0xf, $y & 0xf, $z & 0xf, $potentialLight); diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index abf84f80ff..02189a8e26 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\light; -use pocketmine\world\utils\SubChunkIteratorManager; +use pocketmine\world\utils\SubChunkExplorer; use pocketmine\world\World; use function max; @@ -41,31 +41,31 @@ class SkyLightUpdate extends LightUpdate{ * @phpstan-param \SplFixedArray $lightFilters * @phpstan-param \SplFixedArray $directSkyLightBlockers */ - public function __construct(SubChunkIteratorManager $subChunkHandler, \SplFixedArray $lightFilters, \SplFixedArray $directSkyLightBlockers){ - parent::__construct($subChunkHandler, $lightFilters); + public function __construct(SubChunkExplorer $subChunkExplorer, \SplFixedArray $lightFilters, \SplFixedArray $directSkyLightBlockers){ + parent::__construct($subChunkExplorer, $lightFilters); $this->directSkyLightBlockers = $directSkyLightBlockers; } protected function updateLightArrayRef() : void{ - $this->currentLightArray = $this->subChunkHandler->currentSubChunk->getBlockSkyLightArray(); + $this->currentLightArray = $this->subChunkExplorer->currentSubChunk->getBlockSkyLightArray(); } protected function getEffectiveLight(int $x, int $y, int $z) : int{ if($y >= World::Y_MAX){ - $this->subChunkHandler->invalidate(); + $this->subChunkExplorer->invalidate(); return 15; } return parent::getEffectiveLight($x, $y, $z); } public function recalculateNode(int $x, int $y, int $z) : void{ - if(!$this->subChunkHandler->moveTo($x, $y, $z, false)){ + if(!$this->subChunkExplorer->moveTo($x, $y, $z, false)){ return; } - $chunk = $this->subChunkHandler->currentChunk; + $chunk = $this->subChunkExplorer->currentChunk; $oldHeightMap = $chunk->getHeightMap($x & 0xf, $z & 0xf); - $source = $this->subChunkHandler->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf); + $source = $this->subChunkExplorer->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf); $yPlusOne = $y + 1; diff --git a/src/world/utils/SubChunkIteratorManager.php b/src/world/utils/SubChunkExplorer.php similarity index 98% rename from src/world/utils/SubChunkIteratorManager.php rename to src/world/utils/SubChunkExplorer.php index 453093017b..7dd1fc0db3 100644 --- a/src/world/utils/SubChunkIteratorManager.php +++ b/src/world/utils/SubChunkExplorer.php @@ -29,7 +29,7 @@ use pocketmine\world\format\Chunk; use pocketmine\world\format\SubChunk; use function assert; -class SubChunkIteratorManager{ +class SubChunkExplorer{ /** @var ChunkManager */ public $world; From 5096741b2948abe33a0e9c897d7601ae3bab32e4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 20 Sep 2020 13:29:09 +0100 Subject: [PATCH 1872/3224] World::getChunk() behaviour now matches that of a regular ChunkManager Various bugs existed for a while with stuff using chunk managers instead of worlds when interacting with terrain due to a behavioural inconsistency between World::getChunk() (return from cache or load from disk), and SimpleChunkManager::getChunk() (return from cache only). This change brings the two in line. World::getOrLoadChunk() has been added as a replacement, which has the same behaviour as the old getChunk() and also makes it more obvious that there is an issue with code using it during refactoring. --- src/entity/Entity.php | 2 +- src/network/mcpe/ChunkCache.php | 2 +- src/player/Player.php | 4 +-- src/world/World.php | 46 +++++++++++++++---------- src/world/light/LightPopulationTask.php | 2 +- 5 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index c90930eeda..550852f40c 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1351,7 +1351,7 @@ abstract class Entity{ if($this->chunk !== null){ $this->chunk->removeEntity($this); } - $this->chunk = $this->getWorld()->getChunk($chunkX, $chunkZ, true); + $this->chunk = $this->getWorld()->getOrLoadChunk($chunkX, $chunkZ, true); $this->chunkX = $chunkX; $this->chunkZ = $chunkZ; diff --git a/src/network/mcpe/ChunkCache.php b/src/network/mcpe/ChunkCache.php index 5985b9e3c7..22817b3ecf 100644 --- a/src/network/mcpe/ChunkCache.php +++ b/src/network/mcpe/ChunkCache.php @@ -110,7 +110,7 @@ class ChunkCache implements ChunkListener{ new ChunkRequestTask( $chunkX, $chunkZ, - $this->world->getChunk($chunkX, $chunkZ), + $this->world->getOrLoadChunk($chunkX, $chunkZ), $this->caches[$chunkHash], $this->compressor, function() use ($chunkX, $chunkZ) : void{ diff --git a/src/player/Player.php b/src/player/Player.php index 1a00dc2c22..c8cb135f31 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -733,7 +733,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $world = $world ?? $this->getWorld(); $index = World::chunkHash($x, $z); if(isset($this->usedChunks[$index])){ - foreach($world->getChunk($x, $z)->getEntities() as $entity){ + foreach($world->getOrLoadChunk($x, $z)->getEntities() as $entity){ if($entity !== $this){ $entity->despawnFrom($this); } @@ -747,7 +747,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } protected function spawnEntitiesOnChunk(int $chunkX, int $chunkZ) : void{ - foreach($this->getWorld()->getChunk($chunkX, $chunkZ)->getEntities() as $entity){ + foreach($this->getWorld()->getOrLoadChunk($chunkX, $chunkZ)->getEntities() as $entity){ if($entity !== $this and !$entity->isFlaggedForDespawn()){ $entity->spawnTo($this); } diff --git a/src/world/World.php b/src/world/World.php index 6f736233ea..c2d8306f25 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -754,7 +754,7 @@ class World implements ChunkManager{ } World::getXZ($index, $chunkX, $chunkZ); if(count($blocks) > 512){ - $chunk = $this->getChunk($chunkX, $chunkZ); + $chunk = $this->getOrLoadChunk($chunkX, $chunkZ); foreach($this->getChunkPlayers($chunkX, $chunkZ) as $p){ $p->onChunkChanged($chunk); } @@ -1241,7 +1241,7 @@ class World implements ChunkManager{ * @return int bitmap, (id << 4) | data */ public function getFullBlock(int $x, int $y, int $z) : int{ - return $this->getChunk($x >> 4, $z >> 4, false)->getFullBlock($x & 0x0f, $y, $z & 0x0f); + return $this->getOrLoadChunk($x >> 4, $z >> 4, false)->getFullBlock($x & 0x0f, $y, $z & 0x0f); } public function isInWorld(int $x, int $y, int $z) : bool{ @@ -1653,7 +1653,7 @@ class World implements ChunkManager{ if(!$this->isChunkLoaded($x, $z)){ continue; } - foreach($this->getChunk($x, $z)->getEntities() as $ent){ + foreach($this->getOrLoadChunk($x, $z)->getEntities() as $ent){ /** @var Entity|null $entity */ if($ent->canBeCollidedWith() and ($entity === null or ($ent !== $entity and $entity->canCollideWith($ent))) and $ent->boundingBox->intersectsWith($bb)){ $nearby[] = $ent; @@ -1684,7 +1684,7 @@ class World implements ChunkManager{ if(!$this->isChunkLoaded($x, $z)){ continue; } - foreach($this->getChunk($x, $z)->getEntities() as $ent){ + foreach($this->getOrLoadChunk($x, $z)->getEntities() as $ent){ if($ent !== $entity and $ent->boundingBox->intersectsWith($bb)){ $nearby[] = $ent; } @@ -1727,7 +1727,7 @@ class World implements ChunkManager{ if(!$this->isChunkLoaded($x, $z)){ continue; } - foreach($this->getChunk($x, $z)->getEntities() as $entity){ + foreach($this->getOrLoadChunk($x, $z)->getEntities() as $entity){ if(!($entity instanceof $entityType) or $entity->isFlaggedForDespawn() or (!$includeDead and !$entity->isAlive())){ continue; } @@ -1773,7 +1773,7 @@ class World implements ChunkManager{ * Returns the tile at the specified x,y,z coordinates, or null if it does not exist. */ public function getTileAt(int $x, int $y, int $z) : ?Tile{ - return ($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null ? $chunk->getTile($x & 0x0f, $y, $z & 0x0f) : null; + return ($chunk = $this->getOrLoadChunk($x >> 4, $z >> 4)) !== null ? $chunk->getTile($x & 0x0f, $y, $z & 0x0f) : null; } /** @@ -1782,7 +1782,7 @@ class World implements ChunkManager{ * @return int 0-15 */ public function getBlockSkyLightAt(int $x, int $y, int $z) : int{ - return $this->getChunk($x >> 4, $z >> 4, true)->getBlockSkyLight($x & 0x0f, $y, $z & 0x0f); + return $this->getOrLoadChunk($x >> 4, $z >> 4, true)->getBlockSkyLight($x & 0x0f, $y, $z & 0x0f); } /** @@ -1791,11 +1791,11 @@ class World implements ChunkManager{ * @return int 0-15 */ public function getBlockLightAt(int $x, int $y, int $z) : int{ - return $this->getChunk($x >> 4, $z >> 4, true)->getBlockLight($x & 0x0f, $y, $z & 0x0f); + return $this->getOrLoadChunk($x >> 4, $z >> 4, true)->getBlockLight($x & 0x0f, $y, $z & 0x0f); } public function getBiomeId(int $x, int $z) : int{ - return $this->getChunk($x >> 4, $z >> 4, true)->getBiomeId($x & 0x0f, $z & 0x0f); + return $this->getOrLoadChunk($x >> 4, $z >> 4, true)->getBiomeId($x & 0x0f, $z & 0x0f); } public function getBiome(int $x, int $z) : Biome{ @@ -1803,7 +1803,7 @@ class World implements ChunkManager{ } public function setBiomeId(int $x, int $z, int $biomeId) : void{ - $this->getChunk($x >> 4, $z >> 4, true)->setBiomeId($x & 0x0f, $z & 0x0f, $biomeId); + $this->getOrLoadChunk($x >> 4, $z >> 4, true)->setBiomeId($x & 0x0f, $z & 0x0f, $biomeId); } /** @@ -1819,7 +1819,7 @@ class World implements ChunkManager{ * * @param bool $create Whether to create an empty chunk as a placeholder if the chunk does not exist */ - public function getChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk{ + public function getOrLoadChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk{ if(isset($this->chunks[$index = World::chunkHash($chunkX, $chunkZ)])){ return $this->chunks[$index]; }elseif($this->loadChunk($chunkX, $chunkZ, $create)){ @@ -1829,11 +1829,19 @@ class World implements ChunkManager{ return null; } + public function getChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk{ + $hash = World::chunkHash($chunkX, $chunkZ); + if(isset($this->chunks[$hash])){ + return $this->chunks[$hash]; + } + return $create ? ($this->chunks[$hash] = new Chunk($chunkX, $chunkZ)) : null; + } + /** * Returns the chunk containing the given Vector3 position. */ public function getChunkAtPosition(Vector3 $pos, bool $create = false) : ?Chunk{ - return $this->getChunk($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4, $create); + return $this->getOrLoadChunk($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4, $create); } /** @@ -1849,7 +1857,7 @@ class World implements ChunkManager{ if($i === 4){ continue; //center chunk } - $result[$i] = $this->getChunk($x + $xx - 1, $z + $zz - 1, false); + $result[$i] = $this->getOrLoadChunk($x + $xx - 1, $z + $zz - 1, false); } } @@ -1883,7 +1891,7 @@ class World implements ChunkManager{ unset($this->chunkPopulationQueue[$index]); if($chunk !== null){ - $oldChunk = $this->getChunk($x, $z, false); + $oldChunk = $this->getOrLoadChunk($x, $z, false); $this->setChunk($x, $z, $chunk, false); if(($oldChunk === null or !$oldChunk->isPopulated()) and $chunk->isPopulated()){ (new ChunkPopulateEvent($this, $chunk))->call(); @@ -1916,7 +1924,7 @@ class World implements ChunkManager{ $chunk->setZ($chunkZ); $chunkHash = World::chunkHash($chunkX, $chunkZ); - $oldChunk = $this->getChunk($chunkX, $chunkZ, false); + $oldChunk = $this->getOrLoadChunk($chunkX, $chunkZ, false); if($oldChunk !== null and $oldChunk !== $chunk){ if($deleteEntitiesAndTiles){ foreach($oldChunk->getEntities() as $player){ @@ -1964,7 +1972,7 @@ class World implements ChunkManager{ * @return int 0-255 */ public function getHighestBlockAt(int $x, int $z) : int{ - return $this->getChunk($x >> 4, $z >> 4, true)->getHighestBlockAt($x & 0x0f, $z & 0x0f); + return $this->getOrLoadChunk($x >> 4, $z >> 4, true)->getHighestBlockAt($x & 0x0f, $z & 0x0f); } /** @@ -1979,12 +1987,12 @@ class World implements ChunkManager{ } public function isChunkGenerated(int $x, int $z) : bool{ - $chunk = $this->getChunk($x, $z); + $chunk = $this->getOrLoadChunk($x, $z); return $chunk !== null ? $chunk->isGenerated() : false; } public function isChunkPopulated(int $x, int $z) : bool{ - $chunk = $this->getChunk($x, $z); + $chunk = $this->getOrLoadChunk($x, $z); return $chunk !== null ? $chunk->isPopulated() : false; } @@ -2360,7 +2368,7 @@ class World implements ChunkManager{ } } - $chunk = $this->getChunk($x, $z, true); + $chunk = $this->getOrLoadChunk($x, $z, true); if(!$chunk->isPopulated()){ Timings::$populationTimer->startTiming(); diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index bd734202f4..af3499ea7e 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -81,7 +81,7 @@ class LightPopulationTask extends AsyncTask{ $world = $this->fetchLocal(self::TLS_KEY_WORLD); if(!$world->isClosed() and $world->isChunkLoaded($this->chunkX, $this->chunkZ)){ /** @var Chunk $chunk */ - $chunk = $world->getChunk($this->chunkX, $this->chunkZ); + $chunk = $world->getOrLoadChunk($this->chunkX, $this->chunkZ); //TODO: calculated light information might not be valid if the terrain changed during light calculation /** @var int[] $heightMapArray */ From 716de4d9d676c9bc8047d55f04526412d904e335 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 20 Sep 2020 13:32:54 +0100 Subject: [PATCH 1873/3224] ChunkCache: we have no business autoloading chunks during sending if the chunk isn't loaded, this is a bug and it should crash. --- src/network/mcpe/ChunkCache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/ChunkCache.php b/src/network/mcpe/ChunkCache.php index 22817b3ecf..5985b9e3c7 100644 --- a/src/network/mcpe/ChunkCache.php +++ b/src/network/mcpe/ChunkCache.php @@ -110,7 +110,7 @@ class ChunkCache implements ChunkListener{ new ChunkRequestTask( $chunkX, $chunkZ, - $this->world->getOrLoadChunk($chunkX, $chunkZ), + $this->world->getChunk($chunkX, $chunkZ), $this->caches[$chunkHash], $this->compressor, function() use ($chunkX, $chunkZ) : void{ From 7f43164776afbfc3e3ea54aa018c941fef88587d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 20 Sep 2020 13:39:31 +0100 Subject: [PATCH 1874/3224] Player: Loading chunks during unloading chunks is a BIG nope this should never happen, but it could have happened if there was a bug in the code for some reason. Readers note: I know this looks lik I'm undoing the changes I just did, but what really happened is a name change. --- src/player/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index c8cb135f31..9d9f8b607b 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -733,7 +733,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $world = $world ?? $this->getWorld(); $index = World::chunkHash($x, $z); if(isset($this->usedChunks[$index])){ - foreach($world->getOrLoadChunk($x, $z)->getEntities() as $entity){ + foreach($world->getChunk($x, $z)->getEntities() as $entity){ if($entity !== $this){ $entity->despawnFrom($this); } From b7471fc77b53c0cddcc52fe6bdf630e446167e55 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 20 Sep 2020 13:40:44 +0100 Subject: [PATCH 1875/3224] Player: Loading chunks to spawn entities is a bug again, this would never happen except in bug circumstances, but if there was a bug, it should crash instead of trying to load chunks to paper over it. --- src/player/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index 9d9f8b607b..1a00dc2c22 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -747,7 +747,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } protected function spawnEntitiesOnChunk(int $chunkX, int $chunkZ) : void{ - foreach($this->getWorld()->getOrLoadChunk($chunkX, $chunkZ)->getEntities() as $entity){ + foreach($this->getWorld()->getChunk($chunkX, $chunkZ)->getEntities() as $entity){ if($entity !== $this and !$entity->isFlaggedForDespawn()){ $entity->spawnTo($this); } From b252c18d34004c28b3a3469296683561f7db346e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 20 Sep 2020 13:42:27 +0100 Subject: [PATCH 1876/3224] World: Loading chunks to sync block updates is a bug again, this should never happen, because chunk unloading cleans this stuff out. But if it did happen, loading chunks is not the way to take care of it. --- src/world/World.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index c2d8306f25..ee6aa1a7ce 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -754,7 +754,7 @@ class World implements ChunkManager{ } World::getXZ($index, $chunkX, $chunkZ); if(count($blocks) > 512){ - $chunk = $this->getOrLoadChunk($chunkX, $chunkZ); + $chunk = $this->getChunk($chunkX, $chunkZ); foreach($this->getChunkPlayers($chunkX, $chunkZ) as $p){ $p->onChunkChanged($chunk); } From ae9e931849685e02f57cece02caf3f61d6fc9ed4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 20 Sep 2020 13:44:02 +0100 Subject: [PATCH 1877/3224] LightPopulationTask: Simplify check for chunk loading in onCompletion() we have no business loading chunks here either, although the isChunkLoaded() check should prevent that from happening. --- src/world/light/LightPopulationTask.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index af3499ea7e..adfa769831 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -79,9 +79,7 @@ class LightPopulationTask extends AsyncTask{ public function onCompletion() : void{ /** @var World $world */ $world = $this->fetchLocal(self::TLS_KEY_WORLD); - if(!$world->isClosed() and $world->isChunkLoaded($this->chunkX, $this->chunkZ)){ - /** @var Chunk $chunk */ - $chunk = $world->getOrLoadChunk($this->chunkX, $this->chunkZ); + if(!$world->isClosed() and ($chunk = $world->getChunk($this->chunkX, $this->chunkZ)) !== null){ //TODO: calculated light information might not be valid if the terrain changed during light calculation /** @var int[] $heightMapArray */ From 8e12693494878d3725e7fd620525aa65a1278fe3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 25 Sep 2020 16:35:59 +0100 Subject: [PATCH 1878/3224] Entity: Invalid blocksAround cache when something happens during onEntityInside() this fixes TNT spawning multiple entities when lit by flaming arrows. The problem here is a bit more complex (entities aren't immediately notified when local block updates happen, so they cache stuff that becomes unusable). The simplest option would be to just lose the cache, but that would have some impacts on performance. Barring a rethink of the block updating mechanism, this solution seems usable for now. --- src/block/Block.php | 7 +++++-- src/block/Cactus.php | 3 ++- src/block/Cobweb.php | 3 ++- src/block/Fire.php | 3 ++- src/block/Ladder.php | 3 ++- src/block/Lava.php | 3 ++- src/block/Magma.php | 3 ++- src/block/NetherPortal.php | 3 ++- src/block/TNT.php | 4 +++- src/block/Vine.php | 3 ++- src/block/Water.php | 3 ++- src/entity/Entity.php | 4 +++- 12 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/block/Block.php b/src/block/Block.php index 2022a55be7..dae39760f8 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -536,9 +536,12 @@ class Block{ /** * Called when an entity's bounding box clips inside this block's cell. Note that the entity may not be intersecting * with the collision box or bounding box. + * + * @return bool Whether the block is still the same after the intersection. If it changed (e.g. due to an explosive + * being ignited), this should return false. */ - public function onEntityInside(Entity $entity) : void{ - + public function onEntityInside(Entity $entity) : bool{ + return true; } /** diff --git a/src/block/Cactus.php b/src/block/Cactus.php index 9516666237..6a24b8c2ef 100644 --- a/src/block/Cactus.php +++ b/src/block/Cactus.php @@ -68,9 +68,10 @@ class Cactus extends Transparent{ return [AxisAlignedBB::one()->contract($shrinkSize, 0, $shrinkSize)->trim(Facing::UP, $shrinkSize)]; } - public function onEntityInside(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : bool{ $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_CONTACT, 1); $entity->attack($ev); + return true; } public function onNearbyBlockChange() : void{ diff --git a/src/block/Cobweb.php b/src/block/Cobweb.php index e93641d7d8..1f042ed299 100644 --- a/src/block/Cobweb.php +++ b/src/block/Cobweb.php @@ -37,8 +37,9 @@ class Cobweb extends Flowable{ return true; } - public function onEntityInside(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : bool{ $entity->resetFallDistance(); + return true; } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/block/Fire.php b/src/block/Fire.php index c1b019a483..be94f8ab35 100644 --- a/src/block/Fire.php +++ b/src/block/Fire.php @@ -68,7 +68,7 @@ class Fire extends Flowable{ return true; } - public function onEntityInside(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : bool{ $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1); $entity->attack($ev); @@ -80,6 +80,7 @@ class Fire extends Flowable{ if(!$ev->isCancelled()){ $entity->setOnFire($ev->getDuration()); } + return true; } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/block/Ladder.php b/src/block/Ladder.php index 3ef3f073e3..b696d8daa4 100644 --- a/src/block/Ladder.php +++ b/src/block/Ladder.php @@ -66,11 +66,12 @@ class Ladder extends Transparent{ return true; } - public function onEntityInside(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : bool{ if($entity instanceof Living && $entity->getPosition()->floor()->distanceSquared($this->pos) < 1){ //entity coordinates must be inside block $entity->resetFallDistance(); $entity->onGround = true; } + return true; } /** diff --git a/src/block/Lava.php b/src/block/Lava.php index aa1dec0757..004049c00b 100644 --- a/src/block/Lava.php +++ b/src/block/Lava.php @@ -87,7 +87,7 @@ class Lava extends Liquid{ } } - public function onEntityInside(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : bool{ $entity->fallDistance *= 0.5; $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_LAVA, 4); @@ -100,5 +100,6 @@ class Lava extends Liquid{ } $entity->resetFallDistance(); + return true; } } diff --git a/src/block/Magma.php b/src/block/Magma.php index d16ae056be..2993e1e6b9 100644 --- a/src/block/Magma.php +++ b/src/block/Magma.php @@ -43,11 +43,12 @@ class Magma extends Opaque{ return true; } - public function onEntityInside(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : bool{ if($entity instanceof Living and !$entity->isSneaking()){ $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1); $entity->attack($ev); } + return true; } public function burnsForever() : bool{ diff --git a/src/block/NetherPortal.php b/src/block/NetherPortal.php index c2003958f0..70260994ad 100644 --- a/src/block/NetherPortal.php +++ b/src/block/NetherPortal.php @@ -83,7 +83,8 @@ class NetherPortal extends Transparent{ return []; } - public function onEntityInside(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : bool{ //TODO + return true; } } diff --git a/src/block/TNT.php b/src/block/TNT.php index 201b5c5dc0..f9325afd15 100644 --- a/src/block/TNT.php +++ b/src/block/TNT.php @@ -83,10 +83,12 @@ class TNT extends Opaque{ return true; } - public function onEntityInside(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : bool{ if($entity instanceof Arrow and $entity->isOnFire()){ $this->ignite(); + return false; } + return true; } public function ignite(int $fuse = 80) : void{ diff --git a/src/block/Vine.php b/src/block/Vine.php index ec86d57aba..ac76a81b57 100644 --- a/src/block/Vine.php +++ b/src/block/Vine.php @@ -81,8 +81,9 @@ class Vine extends Flowable{ return true; } - public function onEntityInside(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : bool{ $entity->resetFallDistance(); + return true; } protected function recalculateCollisionBoxes() : array{ diff --git a/src/block/Water.php b/src/block/Water.php index d2d85baadd..a516d40647 100644 --- a/src/block/Water.php +++ b/src/block/Water.php @@ -46,10 +46,11 @@ class Water extends Liquid{ return 5; } - public function onEntityInside(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : bool{ $entity->resetFallDistance(); if($entity->isOnFire()){ $entity->extinguish(); } + return true; } } diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 550852f40c..e855c1b573 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1279,7 +1279,9 @@ abstract class Entity{ $vectors = []; foreach($this->getBlocksAround() as $block){ - $block->onEntityInside($this); + if(!$block->onEntityInside($this)){ + $this->blocksAround = null; + } if(($v = $block->addVelocityToEntity($this)) !== null){ $vectors[] = $v; } From 3556f26e00277dbe8f1627e2ae4f017342c8d9d8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 25 Sep 2020 16:39:55 +0100 Subject: [PATCH 1879/3224] Entity: Rename getBlocksAround() -> getBlocksAroundWithEntityInsideActions() this name is more long-winded, but much less misleading. --- src/entity/Entity.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index e855c1b573..f9081dcae5 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1233,12 +1233,9 @@ abstract class Entity{ } /** - * @deprecated WARNING: Despite what its name implies, this function DOES NOT return all the blocks around the entity. - * Instead, it returns blocks which have reactions for an entity intersecting with them. - * * @return Block[] */ - public function getBlocksAround() : array{ + public function getBlocksAroundWithEntityInsideActions() : array{ if($this->blocksAround === null){ $inset = 0.001; //Offset against floating-point errors @@ -1278,7 +1275,7 @@ abstract class Entity{ protected function checkBlockCollision() : void{ $vectors = []; - foreach($this->getBlocksAround() as $block){ + foreach($this->getBlocksAroundWithEntityInsideActions() as $block){ if(!$block->onEntityInside($this)){ $this->blocksAround = null; } From a5e21bfaa976ebdb5b0024b392cd9c42f952dcaf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 25 Sep 2020 16:40:30 +0100 Subject: [PATCH 1880/3224] Entity: protect getBlocksAroundWithEntityInsideActions() --- src/entity/Entity.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index f9081dcae5..8c9dcd31c8 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1235,7 +1235,7 @@ abstract class Entity{ /** * @return Block[] */ - public function getBlocksAroundWithEntityInsideActions() : array{ + protected function getBlocksAroundWithEntityInsideActions() : array{ if($this->blocksAround === null){ $inset = 0.001; //Offset against floating-point errors From 7c192f85e24f124bcbad13531dc78a5caba804b1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 25 Sep 2020 17:41:12 +0100 Subject: [PATCH 1881/3224] protocol: remove final remaining Vector3 mutations this really should be replaced with a network layer BlockPos structure in the absence of a general int-vector structure in math. --- .../mcpe/protocol/types/entity/BlockPosMetadataProperty.php | 6 +++--- .../protocol/types/inventory/UseItemTransactionData.php | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php b/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php index 628b545bee..0770f0bd5e 100644 --- a/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php +++ b/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php @@ -44,9 +44,9 @@ final class BlockPosMetadataProperty implements MetadataProperty{ } public static function read(PacketSerializer $in) : self{ - $vec = new Vector3(0, 0, 0); - $in->getSignedBlockPosition($vec->x, $vec->y, $vec->z); - return new self($vec); + $x = $y = $z = 0; + $in->getSignedBlockPosition($x, $y, $z); + return new self(new Vector3($x, $y, $z)); } public function write(PacketSerializer $out) : void{ diff --git a/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php b/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php index 6b59c403c1..0ef87c0322 100644 --- a/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php +++ b/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php @@ -87,8 +87,9 @@ class UseItemTransactionData extends TransactionData{ protected function decodeData(PacketSerializer $stream) : void{ $this->actionType = $stream->getUnsignedVarInt(); - $this->blockPos = new Vector3(0, 0, 0); - $stream->getBlockPosition($this->blockPos->x, $this->blockPos->y, $this->blockPos->z); + $x = $y = $z = 0; + $stream->getBlockPosition($x, $y, $z); + $this->blockPos = new Vector3($x, $y, $z); $this->face = $stream->getVarInt(); $this->hotbarSlot = $stream->getVarInt(); $this->itemInHand = $stream->getSlot(); From 3b4e9eea9677e8e432dd6354a26f3e40d3ed386d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 25 Sep 2020 17:43:00 +0100 Subject: [PATCH 1882/3224] RuntimeBlockMapping: drop useless doc comment --- src/network/mcpe/convert/RuntimeBlockMapping.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/network/mcpe/convert/RuntimeBlockMapping.php b/src/network/mcpe/convert/RuntimeBlockMapping.php index 3f17ebd1e9..1de7e60e3a 100644 --- a/src/network/mcpe/convert/RuntimeBlockMapping.php +++ b/src/network/mcpe/convert/RuntimeBlockMapping.php @@ -139,9 +139,6 @@ final class RuntimeBlockMapping{ return $this->legacyToRuntimeMap[$internalStateId] ?? $this->legacyToRuntimeMap[BlockLegacyIds::INFO_UPDATE << 4]; } - /** - * @return int - */ public function fromRuntimeId(int $runtimeId) : int{ return $this->runtimeToLegacyMap[$runtimeId]; } From 38b97dd0b76d6a456fc4a077f558e889cfc8b7b6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 25 Sep 2020 18:11:24 +0100 Subject: [PATCH 1883/3224] Entity: remove useless function --- src/entity/Entity.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 8c9dcd31c8..397e3c7241 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -772,10 +772,6 @@ abstract class Entity{ return false; } - protected function applyGravity() : void{ - $this->motion->y -= $this->gravity; - } - protected function tryChangeMovement() : void{ $friction = 1 - $this->drag; @@ -784,7 +780,7 @@ abstract class Entity{ } if($this->gravityEnabled){ - $this->applyGravity(); + $this->motion->y -= $this->gravity; } if(!$this->applyDragBeforeGravity()){ From 9dda99f8448c43becc8ac2a665c8867e0291834d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 25 Sep 2020 18:36:45 +0100 Subject: [PATCH 1884/3224] Updated composer dependencies --- composer.lock | 66 +++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/composer.lock b/composer.lock index a23295a644..3c9835c7fc 100644 --- a/composer.lock +++ b/composer.lock @@ -561,12 +561,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "d88b421571edf3b4a26ffb4c0b2df7cc3f7145ac" + "reference": "fd3a016cfee1939869e6f0bc320a7c99bd2f440d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/d88b421571edf3b4a26ffb4c0b2df7cc3f7145ac", - "reference": "d88b421571edf3b4a26ffb4c0b2df7cc3f7145ac", + "url": "https://api.github.com/repos/pmmp/Math/zipball/fd3a016cfee1939869e6f0bc320a7c99bd2f440d", + "reference": "fd3a016cfee1939869e6f0bc320a7c99bd2f440d", "shasum": "" }, "require": { @@ -576,7 +576,7 @@ "require-dev": { "irstea/phpunit-shim": "^7.5", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "0.12.40", + "phpstan/phpstan": "0.12.44", "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", @@ -590,7 +590,7 @@ "LGPL-3.0" ], "description": "PHP library containing math related code used in PocketMine-MP", - "time": "2020-08-28T20:57:04+00:00" + "time": "2020-09-25T17:32:58+00:00" }, { "name": "pocketmine/nbt", @@ -1079,16 +1079,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.9.1", + "version": "v4.10.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "88e519766fc58bd46b8265561fb79b54e2e00b28" + "reference": "1b479e7592812411c20c34d9ed33db3957bde66e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/88e519766fc58bd46b8265561fb79b54e2e00b28", - "reference": "88e519766fc58bd46b8265561fb79b54e2e00b28", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1b479e7592812411c20c34d9ed33db3957bde66e", + "reference": "1b479e7592812411c20c34d9ed33db3957bde66e", "shasum": "" }, "require": { @@ -1127,7 +1127,7 @@ "parser", "php" ], - "time": "2020-08-30T16:15:20+00:00" + "time": "2020-09-23T18:23:49+00:00" }, { "name": "phar-io/manifest", @@ -1283,16 +1283,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.2.1", + "version": "5.2.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "d870572532cd70bc3fab58f2e23ad423c8404c44" + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d870572532cd70bc3fab58f2e23ad423c8404c44", - "reference": "d870572532cd70bc3fab58f2e23ad423c8404c44", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", "shasum": "" }, "require": { @@ -1331,20 +1331,20 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2020-08-15T11:14:08+00:00" + "time": "2020-09-03T19:13:55+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.3.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "e878a14a65245fbe78f8080eba03b47c3b705651" + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e878a14a65245fbe78f8080eba03b47c3b705651", - "reference": "e878a14a65245fbe78f8080eba03b47c3b705651", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", "shasum": "" }, "require": { @@ -1376,7 +1376,7 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2020-06-27T10:12:23+00:00" + "time": "2020-09-17T18:55:26+00:00" }, { "name": "phpspec/prophecy", @@ -1606,16 +1606,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.1.7", + "version": "9.1.11", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "2ef92bec3186a827faf7362ff92ae4e8ec2e49d2" + "reference": "c9394cb9d07ecfa9351b96f2e296bad473195f4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2ef92bec3186a827faf7362ff92ae4e8ec2e49d2", - "reference": "2ef92bec3186a827faf7362ff92ae4e8ec2e49d2", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c9394cb9d07ecfa9351b96f2e296bad473195f4d", + "reference": "c9394cb9d07ecfa9351b96f2e296bad473195f4d", "shasum": "" }, "require": { @@ -1623,7 +1623,7 @@ "ext-libxml": "*", "ext-xmlwriter": "*", "nikic/php-parser": "^4.8", - "php": "^7.3 || ^8.0", + "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", "sebastian/code-unit-reverse-lookup": "^2.0.2", @@ -1675,7 +1675,7 @@ "type": "github" } ], - "time": "2020-09-03T07:09:19+00:00" + "time": "2020-09-19T05:29:17+00:00" }, { "name": "phpunit/php-file-iterator", @@ -1904,16 +1904,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.3.8", + "version": "9.3.11", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "93d78d8e2a06393a0d0c1ead6fe9984f1af1f88c" + "reference": "f7316ea106df7c9507f4fdaa88c47bc10a3b27a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/93d78d8e2a06393a0d0c1ead6fe9984f1af1f88c", - "reference": "93d78d8e2a06393a0d0c1ead6fe9984f1af1f88c", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f7316ea106df7c9507f4fdaa88c47bc10a3b27a1", + "reference": "f7316ea106df7c9507f4fdaa88c47bc10a3b27a1", "shasum": "" }, "require": { @@ -1927,9 +1927,9 @@ "myclabs/deep-copy": "^1.10.1", "phar-io/manifest": "^2.0.1", "phar-io/version": "^3.0.2", - "php": "^7.3 || ^8.0", + "php": ">=7.3", "phpspec/prophecy": "^1.11.1", - "phpunit/php-code-coverage": "^9.1.5", + "phpunit/php-code-coverage": "^9.1.11", "phpunit/php-file-iterator": "^3.0.4", "phpunit/php-invoker": "^3.1", "phpunit/php-text-template": "^2.0.2", @@ -1999,7 +1999,7 @@ "type": "github" } ], - "time": "2020-08-27T06:30:58+00:00" + "time": "2020-09-24T08:08:49+00:00" }, { "name": "sebastian/cli-parser", From 25566c2f1a8ea69b23084c318fe15402f9bd497e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 25 Sep 2020 18:37:29 +0100 Subject: [PATCH 1885/3224] Entity: avoid direct Vector3 mutations in tryChangeMovement() --- src/entity/Entity.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 397e3c7241..cb93cf9c02 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -775,24 +775,25 @@ abstract class Entity{ protected function tryChangeMovement() : void{ $friction = 1 - $this->drag; + $mY = $this->motion->y; + if($this->applyDragBeforeGravity()){ - $this->motion->y *= $friction; + $mY *= $friction; } if($this->gravityEnabled){ - $this->motion->y -= $this->gravity; + $mY -= $this->gravity; } if(!$this->applyDragBeforeGravity()){ - $this->motion->y *= $friction; + $mY *= $friction; } if($this->onGround){ $friction *= $this->getWorld()->getBlockAt((int) floor($this->location->x), (int) floor($this->location->y - 1), (int) floor($this->location->z))->getFrictionFactor(); } - $this->motion->x *= $friction; - $this->motion->z *= $friction; + $this->motion = new Vector3($this->motion->x * $friction, $mY, $this->motion->z * $friction); } protected function checkObstruction(float $x, float $y, float $z) : bool{ From 1d8e7abdd438999ff1919ad7f91ba30896ba3cb4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 25 Sep 2020 18:38:41 +0100 Subject: [PATCH 1886/3224] Entity: avoid direct mutation of Vector3 in checkObstruction(), use withComponents() instead this ugly code can be simplified quite a lot further, but that's a job for later. --- src/entity/Entity.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index cb93cf9c02..f1d7bc7e6a 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -853,37 +853,37 @@ abstract class Entity{ $force = lcg_value() * 0.2 + 0.1; if($direction === Facing::WEST){ - $this->motion->x = -$force; + $this->motion = $this->motion->withComponents(-$force, null, null); return true; } if($direction === Facing::EAST){ - $this->motion->x = $force; + $this->motion = $this->motion->withComponents($force, null, null); return true; } if($direction === Facing::DOWN){ - $this->motion->y = -$force; + $this->motion = $this->motion->withComponents(null, -$force, null); return true; } if($direction === Facing::UP){ - $this->motion->y = $force; + $this->motion = $this->motion->withComponents(null, $force, null); return true; } if($direction === Facing::NORTH){ - $this->motion->z = -$force; + $this->motion = $this->motion->withComponents(null, null, -$force); return true; } if($direction === Facing::SOUTH){ - $this->motion->z = $force; + $this->motion = $this->motion->withComponents(null, null, $force); return true; } From db7fb25196fb002b473a64ca3efb08316b2829d1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 25 Sep 2020 18:40:13 +0100 Subject: [PATCH 1887/3224] Avoid more Vector3 mutations using withComponents() --- src/entity/Entity.php | 30 ++++++++++-------------------- src/entity/Living.php | 2 +- src/entity/Squid.php | 2 +- 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index f1d7bc7e6a..b02f877e3b 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -953,15 +953,11 @@ abstract class Entity{ if($this->hasMovementUpdate()){ $this->tryChangeMovement(); - if(abs($this->motion->x) <= self::MOTION_THRESHOLD){ - $this->motion->x = 0; - } - if(abs($this->motion->y) <= self::MOTION_THRESHOLD){ - $this->motion->y = 0; - } - if(abs($this->motion->z) <= self::MOTION_THRESHOLD){ - $this->motion->z = 0; - } + $this->motion = $this->motion->withComponents( + abs($this->motion->x) <= self::MOTION_THRESHOLD ? 0 : null, + abs($this->motion->y) <= self::MOTION_THRESHOLD ? 0 : null, + abs($this->motion->z) <= self::MOTION_THRESHOLD ? 0 : null + ); if($this->motion->x != 0 or $this->motion->y != 0 or $this->motion->z != 0){ $this->move($this->motion->x, $this->motion->y, $this->motion->z); @@ -1205,17 +1201,11 @@ abstract class Entity{ $this->checkGroundState($movX, $movY, $movZ, $dx, $dy, $dz); $this->updateFallState($dy, $this->onGround); - if($movX != $dx){ - $this->motion->x = 0; - } - - if($movY != $dy){ - $this->motion->y = 0; - } - - if($movZ != $dz){ - $this->motion->z = 0; - } + $this->motion = $this->motion->withComponents( + $movX != $dx ? 0 : null, + $movY != $dy ? 0 : null, + $movZ != $dz ? 0 : null + ); //TODO: vehicle collision events (first we need to spawn them!) diff --git a/src/entity/Living.php b/src/entity/Living.php index dab60300ce..85dbc6a059 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -288,7 +288,7 @@ abstract class Living extends Entity{ */ public function jump() : void{ if($this->onGround){ - $this->motion->y = $this->getJumpVelocity(); //Y motion should already be 0 if we're jumping from the ground. + $this->motion = $this->motion->withComponents(null, $this->getJumpVelocity(), null); //Y motion should already be 0 if we're jumping from the ground. } } diff --git a/src/entity/Squid.php b/src/entity/Squid.php index b39913bfa5..04b81d4fc7 100644 --- a/src/entity/Squid.php +++ b/src/entity/Squid.php @@ -97,7 +97,7 @@ class Squid extends WaterAnimal{ if($this->isAlive()){ if($this->location->y > 62 and $this->swimDirection !== null){ - $this->swimDirection->y = -0.5; + $this->swimDirection = $this->swimDirection->withComponents(null, -0.5, null); } $inWater = $this->isUnderwater(); From 626680c6c1b347a460cab9e56a15232eb166a7c7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 25 Sep 2020 18:43:49 +0100 Subject: [PATCH 1888/3224] Use new Location objects instead of mutating Entity->location directly I'm actually not a big fan of needing to recreate the whole thing just to modify the coordinates. This seems kind of stupid. --- src/entity/Entity.php | 20 ++++++++++++++------ src/entity/projectile/Projectile.php | 9 ++++++--- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index b02f877e3b..c6fdc0c767 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1192,9 +1192,14 @@ abstract class Entity{ $this->boundingBox = $moveBB; } - $this->location->x = ($this->boundingBox->minX + $this->boundingBox->maxX) / 2; - $this->location->y = $this->boundingBox->minY - $this->ySize; - $this->location->z = ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2; + $this->location = new Location( + ($this->boundingBox->minX + $this->boundingBox->maxX) / 2, + $this->boundingBox->minY - $this->ySize, + ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2, + $this->location->yaw, + $this->location->pitch, + $this->location->world + ); $this->checkChunks(); $this->checkBlockCollision(); @@ -1301,9 +1306,12 @@ abstract class Entity{ } } - $this->location->x = $pos->x; - $this->location->y = $pos->y; - $this->location->z = $pos->z; + $this->location = Location::fromObject( + $pos, + $this->location->world, + $this->location->yaw, + $this->location->pitch + ); $this->recalculateBoundingBox(); diff --git a/src/entity/projectile/Projectile.php b/src/entity/projectile/Projectile.php index a6c0f810d8..49d386578b 100644 --- a/src/entity/projectile/Projectile.php +++ b/src/entity/projectile/Projectile.php @@ -219,9 +219,12 @@ abstract class Projectile extends Entity{ } } - $this->location->x = $end->x; - $this->location->y = $end->y; - $this->location->z = $end->z; + $this->location = Location::fromObject( + $end, + $this->location->world, + $this->location->yaw, + $this->location->pitch + ); $this->recalculateBoundingBox(); if($hitResult !== null){ From b727972c769b2080f15d10c264e7a9d3677c55e2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Sep 2020 12:52:28 +0100 Subject: [PATCH 1889/3224] World: remove useless isLightPopulated() check chunks are never light populated when loaded from disk now. --- src/world/World.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index ee6aa1a7ce..ef37149d92 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2143,7 +2143,7 @@ class World implements ChunkManager{ (new ChunkLoadEvent($this, $chunk, !$chunk->isGenerated()))->call(); - if(!$chunk->isLightPopulated() and $chunk->isPopulated()){ + if($chunk->isPopulated()){ $this->getServer()->getAsyncPool()->submitTask(new LightPopulationTask($this, $chunk)); } From 89cce4c7498bffe0695e416f53543845381bc210 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Sep 2020 13:13:12 +0100 Subject: [PATCH 1890/3224] performance: only calculate light for chunks inside ticking areas this produces a major performance improvement for large render distances, and reduces the impact of lighting calculation to zero on servers which have random blockupdates turned off. --- src/world/World.php | 12 +++++++----- src/world/format/Chunk.php | 6 +++--- src/world/format/io/FastChunkSerializer.php | 2 +- src/world/light/LightPopulationTask.php | 1 + 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index ef37149d92..f21fdbd632 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -895,7 +895,13 @@ class World implements ChunkManager{ $dz = mt_rand(-$randRange, $randRange); $hash = World::chunkHash($dx + $chunkX, $dz + $chunkZ); if(!isset($chunkTickList[$hash]) and isset($this->chunks[$hash])){ - if(!$this->chunks[$hash]->isLightPopulated()){ + //TODO: this might need to be checked after adjacent chunks are loaded in future + $lightPopulatedState = $this->chunks[$hash]->isLightPopulated(); + if($lightPopulatedState !== true){ + if($lightPopulatedState === false){ + $this->chunks[$hash]->setLightPopulated(null); + $this->server->getAsyncPool()->submitTask(new LightPopulationTask($this, $this->chunks[$hash])); + } continue; } //check adjacent chunks are loaded @@ -2143,10 +2149,6 @@ class World implements ChunkManager{ (new ChunkLoadEvent($this, $chunk, !$chunk->isGenerated()))->call(); - if($chunk->isPopulated()){ - $this->getServer()->getAsyncPool()->submitTask(new LightPopulationTask($this, $chunk)); - } - if(!$this->isChunkInUse($x, $z)){ $this->logger->debug("Newly loaded chunk $x $z has no loaders registered, will be unloaded at next available opportunity"); $this->unloadChunkRequest($x, $z); diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 0b76f00768..59602ce5a1 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -58,7 +58,7 @@ class Chunk{ /** @var int */ private $dirtyFlags = 0; - /** @var bool */ + /** @var bool|null */ protected $lightPopulated = false; /** @var bool */ protected $terrainGenerated = false; @@ -387,11 +387,11 @@ class Chunk{ $this->dirtyFlags |= self::DIRTY_FLAG_BIOMES; } - public function isLightPopulated() : bool{ + public function isLightPopulated() : ?bool{ return $this->lightPopulated; } - public function setLightPopulated(bool $value = true) : void{ + public function setLightPopulated(?bool $value = true) : void{ $this->lightPopulated = $value; } diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index 242caebb85..a69ee4cbb5 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -59,7 +59,7 @@ final class FastChunkSerializer{ * TODO: tiles and entities */ public static function serialize(Chunk $chunk, bool $includeLight = true) : string{ - $includeLight = $includeLight && $chunk->isLightPopulated(); + $includeLight = $includeLight && $chunk->isLightPopulated() === true; $stream = new BinaryStream(); $stream->putInt($chunk->getX()); diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index adfa769831..61d839be7a 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -53,6 +53,7 @@ class LightPopulationTask extends AsyncTask{ public function __construct(World $world, Chunk $chunk){ $this->storeLocal(self::TLS_KEY_WORLD, $world); [$this->chunkX, $this->chunkZ] = [$chunk->getX(), $chunk->getZ()]; + $chunk->setLightPopulated(null); $this->chunk = FastChunkSerializer::serialize($chunk); } From 05a94f35d6d4c670f8d8c6d0ae9a8fe3b4193929 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Sep 2020 13:17:54 +0100 Subject: [PATCH 1891/3224] Updated composer dependencies --- composer.json | 2 +- composer.lock | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/composer.json b/composer.json index c226a88f1a..c9f5468234 100644 --- a/composer.json +++ b/composer.json @@ -50,7 +50,7 @@ "respect/validation": "^2.0" }, "require-dev": { - "phpstan/phpstan": "0.12.42", + "phpstan/phpstan": "0.12.44", "phpstan/phpstan-phpunit": "^0.12.6", "phpstan/phpstan-strict-rules": "^0.12.2", "phpunit/phpunit": "^9.2" diff --git a/composer.lock b/composer.lock index 3c9835c7fc..350ea84c4c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "adc74d30203a9378694bc478baf7a142", + "content-hash": "13b64be4a6f2487487d1acbcfafcb82f", "packages": [ { "name": "adhocore/json-comment", @@ -1079,16 +1079,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.10.1", + "version": "v4.10.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "1b479e7592812411c20c34d9ed33db3957bde66e" + "reference": "658f1be311a230e0907f5dfe0213742aff0596de" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1b479e7592812411c20c34d9ed33db3957bde66e", - "reference": "1b479e7592812411c20c34d9ed33db3957bde66e", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/658f1be311a230e0907f5dfe0213742aff0596de", + "reference": "658f1be311a230e0907f5dfe0213742aff0596de", "shasum": "" }, "require": { @@ -1127,7 +1127,7 @@ "parser", "php" ], - "time": "2020-09-23T18:23:49+00:00" + "time": "2020-09-26T10:30:38+00:00" }, { "name": "phar-io/manifest", @@ -1443,16 +1443,16 @@ }, { "name": "phpstan/phpstan", - "version": "0.12.42", + "version": "0.12.44", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "7c43b7c2d5ca6554f6231e82e342a710163ac5f4" + "reference": "330b45776ea77f167b150e24787412414a8fa469" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/7c43b7c2d5ca6554f6231e82e342a710163ac5f4", - "reference": "7c43b7c2d5ca6554f6231e82e342a710163ac5f4", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/330b45776ea77f167b150e24787412414a8fa469", + "reference": "330b45776ea77f167b150e24787412414a8fa469", "shasum": "" }, "require": { @@ -1495,7 +1495,7 @@ "type": "tidelift" } ], - "time": "2020-09-02T13:14:53+00:00" + "time": "2020-09-24T15:28:47+00:00" }, { "name": "phpstan/phpstan-phpunit", From 7b02cc3efdadb6a25882dccc4e84536ada6b9b63 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Sep 2020 14:31:56 +0100 Subject: [PATCH 1892/3224] Implemented #3836: Replace setCancelled() in events with cancel() and uncancel() The motivation for this is to prevent passing a dynamic argument to cancellation, which in almost all cases is a bug in user code. This same mistake also appears in a few places in the PM core (as seen in this commit), but in those cases the mistakes were mostly harmless since they were taking place before the event was actually called. closes #3836 --- src/Server.php | 4 +++- src/block/Fire.php | 2 +- src/entity/Living.php | 6 +++--- src/entity/effect/EffectManager.php | 4 +++- src/entity/projectile/Arrow.php | 2 +- src/event/CancellableTrait.php | 8 ++++++-- src/event/entity/EntityEffectRemoveEvent.php | 4 ++-- src/item/Bow.php | 2 +- src/player/Player.php | 18 ++++++++++-------- src/world/World.php | 14 +++++++++----- src/world/WorldManager.php | 2 +- .../src/pmmp/TesterPlugin/Main.php | 2 +- 12 files changed, 41 insertions(+), 27 deletions(-) diff --git a/src/Server.php b/src/Server.php index 1a9dd31e9e..0d13ba0433 100644 --- a/src/Server.php +++ b/src/Server.php @@ -549,7 +549,9 @@ class Server{ public function saveOfflinePlayerData(string $name, CompoundTag $nbtTag) : void{ $ev = new PlayerDataSaveEvent($nbtTag, $name); - $ev->setCancelled(!$this->shouldSavePlayerData()); + if(!$this->shouldSavePlayerData()){ + $ev->cancel(); + } $ev->call(); diff --git a/src/block/Fire.php b/src/block/Fire.php index be94f8ab35..4e31baf826 100644 --- a/src/block/Fire.php +++ b/src/block/Fire.php @@ -74,7 +74,7 @@ class Fire extends Flowable{ $ev = new EntityCombustByBlockEvent($this, $entity, 8); if($entity instanceof Arrow){ - $ev->setCancelled(); + $ev->cancel(); } $ev->call(); if(!$ev->isCancelled()){ diff --git a/src/entity/Living.php b/src/entity/Living.php index 85dbc6a059..89d26927f7 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -356,7 +356,7 @@ abstract class Living extends Entity{ public function applyDamageModifiers(EntityDamageEvent $source) : void{ if($this->lastDamageCause !== null and $this->attackTime > 0){ if($this->lastDamageCause->getBaseDamage() >= $source->getBaseDamage()){ - $source->setCancelled(); + $source->cancel(); } $source->setModifier(-$this->lastDamageCause->getBaseDamage(), EntityDamageEvent::MODIFIER_PREVIOUS_DAMAGE_COOLDOWN); } @@ -437,7 +437,7 @@ abstract class Living extends Entity{ public function attack(EntityDamageEvent $source) : void{ if($this->noDamageTicks > 0){ - $source->setCancelled(); + $source->cancel(); } if($this->effectManager->has(VanillaEffects::FIRE_RESISTANCE()) and ( @@ -446,7 +446,7 @@ abstract class Living extends Entity{ or $source->getCause() === EntityDamageEvent::CAUSE_LAVA ) ){ - $source->setCancelled(); + $source->cancel(); } $this->applyDamageModifiers($source); diff --git a/src/entity/effect/EffectManager.php b/src/entity/effect/EffectManager.php index 842447ae3c..d5343b7779 100644 --- a/src/entity/effect/EffectManager.php +++ b/src/entity/effect/EffectManager.php @@ -146,7 +146,9 @@ class EffectManager{ } $ev = new EntityEffectAddEvent($this->entity, $effect, $oldEffect); - $ev->setCancelled($cancelled); + if($cancelled){ + $ev->cancel(); + } $ev->call(); if($ev->isCancelled()){ diff --git a/src/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php index a5961dc2c2..39f62fa916 100644 --- a/src/entity/projectile/Arrow.php +++ b/src/entity/projectile/Arrow.php @@ -178,7 +178,7 @@ class Arrow extends Projectile{ $ev = new InventoryPickupArrowEvent($playerInventory, $this); if($this->pickupMode === self::PICKUP_NONE or ($this->pickupMode === self::PICKUP_CREATIVE and !$player->isCreative())){ - $ev->setCancelled(); + $ev->cancel(); } $ev->call(); diff --git a/src/event/CancellableTrait.php b/src/event/CancellableTrait.php index c4eae42902..313c499288 100644 --- a/src/event/CancellableTrait.php +++ b/src/event/CancellableTrait.php @@ -39,7 +39,11 @@ trait CancellableTrait{ return $this->isCancelled; } - public function setCancelled(bool $value = true) : void{ - $this->isCancelled = $value; + public function cancel() : void{ + $this->isCancelled = true; + } + + public function uncancel() : void{ + $this->isCancelled = false; } } diff --git a/src/event/entity/EntityEffectRemoveEvent.php b/src/event/entity/EntityEffectRemoveEvent.php index 56099e958c..afd2ef631b 100644 --- a/src/event/entity/EntityEffectRemoveEvent.php +++ b/src/event/entity/EntityEffectRemoveEvent.php @@ -27,10 +27,10 @@ namespace pocketmine\event\entity; * Called when an effect is removed from an entity. */ class EntityEffectRemoveEvent extends EntityEffectEvent{ - public function setCancelled(bool $value = true) : void{ + public function cancel() : void{ if($this->getEffect()->getDuration() <= 0){ throw new \InvalidStateException("Removal of expired effects cannot be cancelled"); } - parent::setCancelled($value); + parent::cancel(); } } diff --git a/src/item/Bow.php b/src/item/Bow.php index 2c660354e0..d57bff29b7 100644 --- a/src/item/Bow.php +++ b/src/item/Bow.php @@ -80,7 +80,7 @@ class Bow extends Tool implements Releasable{ $ev = new EntityShootBowEvent($player, $this, $entity, $baseForce * 3); if($baseForce < 0.1 or $diff < 5 or $player->isSpectator()){ - $ev->setCancelled(); + $ev->cancel(); } $ev->call(); diff --git a/src/player/Player.php b/src/player/Player.php index 1a00dc2c22..d7f1c1786d 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1428,7 +1428,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $ev = new PlayerItemUseEvent($this, $item, $directionVector); if($this->hasItemCooldown($item) or $this->isSpectator()){ - $ev->setCancelled(); + $ev->cancel(); } $ev->call(); @@ -1462,7 +1462,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ if($slot instanceof ConsumableItem){ $ev = new PlayerItemConsumeEvent($this, $slot); if($this->hasItemCooldown($slot)){ - $ev->setCancelled(); + $ev->cancel(); } $ev->call(); @@ -1521,7 +1521,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $ev = new PlayerBlockPickEvent($this, $block, $item); $existingSlot = $this->inventory->first($item); if($existingSlot === -1 and $this->hasFiniteResources()){ - $ev->setCancelled(); + $ev->cancel(); } $ev->call(); @@ -1563,7 +1563,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $ev = new PlayerInteractEvent($this, $this->inventory->getItemInHand(), $target, null, $face, PlayerInteractEvent::LEFT_CLICK_BLOCK); if($this->isSpectator()){ - $ev->setCancelled(); + $ev->cancel(); } $ev->call(); if($ev->isCancelled()){ @@ -1669,7 +1669,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $ev = new EntityDamageByEntityEvent($this, $entity, EntityDamageEvent::CAUSE_ENTITY_ATTACK, $heldItem->getAttackPoints()); if($this->isSpectator() or !$this->canInteract($entity->getLocation(), 8) or ($entity instanceof Player and !$this->server->getConfigGroup()->getConfigBool("pvp"))){ - $ev->setCancelled(); + $ev->cancel(); } $meleeEnchantmentDamage = 0; @@ -1751,7 +1751,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ public function toggleFlight(bool $fly) : bool{ $ev = new PlayerToggleFlightEvent($this, $fly); - $ev->setCancelled(!$this->allowFlight); + if(!$this->allowFlight){ + $ev->cancel(); + } $ev->call(); if($ev->isCancelled()){ return false; @@ -2175,9 +2177,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ and $source->getCause() !== EntityDamageEvent::CAUSE_SUICIDE and $source->getCause() !== EntityDamageEvent::CAUSE_VOID ){ - $source->setCancelled(); + $source->cancel(); }elseif($this->allowFlight and $source->getCause() === EntityDamageEvent::CAUSE_FALL){ - $source->setCancelled(); + $source->cancel(); } parent::attack($source); diff --git a/src/world/World.php b/src/world/World.php index f21fdbd632..8620a55b46 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1448,7 +1448,7 @@ class World implements ChunkManager{ $ev = new BlockBreakEvent($player, $target, $item, $player->isCreative(), $drops, $xpDrop); if($target instanceof Air or ($player->isSurvival() and !$target->getBreakInfo()->isBreakable()) or $player->isSpectator()){ - $ev->setCancelled(); + $ev->cancel(); } if($player->isAdventure(true) and !$ev->isCancelled()){ @@ -1462,7 +1462,9 @@ class World implements ChunkManager{ } } - $ev->setCancelled(!$canBreak); + if(!$canBreak){ + $ev->cancel(); + } } $ev->call(); @@ -1538,7 +1540,7 @@ class World implements ChunkManager{ if($player !== null){ $ev = new PlayerInteractEvent($player, $item, $blockClicked, $clickVector, $face, PlayerInteractEvent::RIGHT_CLICK_BLOCK); if($player->isSpectator()){ - $ev->setCancelled(); //set it to cancelled so plugins can bypass this + $ev->cancel(); //set it to cancelled so plugins can bypass this } $ev->call(); @@ -1581,7 +1583,7 @@ class World implements ChunkManager{ if($player !== null){ $ev = new BlockPlaceEvent($player, $hand, $blockReplace, $blockClicked, $item); if($player->isSpectator()){ - $ev->setCancelled(); + $ev->cancel(); } if($player->isAdventure(true) and !$ev->isCancelled()){ @@ -1595,7 +1597,9 @@ class World implements ChunkManager{ } } - $ev->setCancelled(!$canPlace); + if(!$canPlace){ + $ev->cancel(); + } } $ev->call(); diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 974a57422e..dbf1e6c7ba 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -141,7 +141,7 @@ class WorldManager{ $ev = new WorldUnloadEvent($world); if($world === $this->defaultWorld and !$forceUnload){ - $ev->setCancelled(true); + $ev->cancel(); } $ev->call(); diff --git a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/Main.php b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/Main.php index 85af44b726..a9de8cdf5b 100644 --- a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/Main.php +++ b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/Main.php @@ -51,7 +51,7 @@ class Main extends PluginBase implements Listener{ //be asynchronous tests running. Instead we cancel this and stop the server of our own accord once all tests //have completed. if($event->getCommand() === "stop"){ - $event->setCancelled(); + $event->cancel(); } } From b8e1bdbed4c29896a462a2a00ba55c29074a2103 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Sep 2020 15:11:47 +0100 Subject: [PATCH 1893/3224] MemoryManager: Look inside Closure objects to resolve dependencies the lack of closure analysis allowed several memory leaks to be unable to be debugged using memory dumps. --- src/MemoryManager.php | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/MemoryManager.php b/src/MemoryManager.php index e2c33e2a4e..9d7e3d4c89 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -399,24 +399,37 @@ class MemoryManager{ } $objects[$hash] = true; - - $reflection = new \ReflectionObject($object); - $info = [ "information" => "$hash@$className", - "properties" => [] ]; - - foreach($reflection->getProperties() as $property){ - if($property->isStatic()){ - continue; + if($object instanceof \Closure){ + $info["definition"] = Utils::getNiceClosureName($object); + $info["referencedVars"] = []; + $reflect = new \ReflectionFunction($object); + if(($closureThis = $reflect->getClosureThis()) !== null){ + $info["this"] = self::continueDump($closureThis, $objects, $refCounts, 0, $maxNesting, $maxStringSize); } - if(!$property->isPublic()){ - $property->setAccessible(true); + //TODO: scan non-closures for statics as well + foreach($reflect->getStaticVariables() as $name => $variable){ + $info["referencedVars"][$name] = self::continueDump($variable, $objects, $refCounts, 0, $maxNesting, $maxStringSize); } + }else{ + $reflection = new \ReflectionObject($object); - $info["properties"][$property->getName()] = self::continueDump($property->getValue($object), $objects, $refCounts, 0, $maxNesting, $maxStringSize); + $info["properties"] = []; + + foreach($reflection->getProperties() as $property){ + if($property->isStatic()){ + continue; + } + + if(!$property->isPublic()){ + $property->setAccessible(true); + } + + $info["properties"][$property->getName()] = self::continueDump($property->getValue($object), $objects, $refCounts, 0, $maxNesting, $maxStringSize); + } } fwrite($obData, json_encode($info, JSON_UNESCAPED_SLASHES) . "\n"); From e192c75019f4c666aaf9f7ee3a05a1f52195c1a3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Sep 2020 15:18:34 +0100 Subject: [PATCH 1894/3224] MemoryManager: Analyze contents of function/method static variables it's possible for stuff to hide inside these things that would cause leaks. --- src/MemoryManager.php | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/MemoryManager.php b/src/MemoryManager.php index 9d7e3d4c89..0dcafa1c3e 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -43,6 +43,7 @@ use function gc_enable; use function gc_mem_caches; use function get_class; use function get_declared_classes; +use function get_defined_functions; use function ini_get; use function ini_set; use function is_array; @@ -328,6 +329,9 @@ class MemoryManager{ $staticProperties = []; $staticCount = 0; + $functionStaticVars = []; + $functionStaticVarsCount = 0; + foreach(get_declared_classes() as $className){ $reflection = new \ReflectionClass($className); $staticProperties[$className] = []; @@ -347,6 +351,20 @@ class MemoryManager{ if(count($staticProperties[$className]) === 0){ unset($staticProperties[$className]); } + + foreach($reflection->getMethods() as $method){ + if($method->getDeclaringClass()->getName() !== $reflection->getName()){ + continue; + } + $methodStatics = []; + foreach($method->getStaticVariables() as $name => $variable){ + $methodStatics[$name] = self::continueDump($variable, $objects, $refCounts, 0, $maxNesting, $maxStringSize); + } + if(count($methodStatics) > 0){ + $functionStaticVars[$className . "::" . $method->getName()] = $methodStatics; + $functionStaticVarsCount += count($functionStaticVars); + } + } } file_put_contents($outputFolder . "/staticProperties.js", json_encode($staticProperties, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); @@ -381,6 +399,21 @@ class MemoryManager{ $logger->info("Wrote $globalCount global variables"); } + foreach(get_defined_functions()["user"] as $function){ + $reflect = new \ReflectionFunction($function); + + $vars = []; + foreach($reflect->getStaticVariables() as $varName => $variable){ + $vars[$varName] = self::continueDump($variable, $objects, $refCounts, 0, $maxNesting, $maxStringSize); + } + if(count($vars) > 0){ + $functionStaticVars[$function] = $vars; + $functionStaticVarsCount += count($vars); + } + } + file_put_contents($outputFolder . '/functionStaticVars.js', json_encode($functionStaticVars, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); + $logger->info("Wrote $functionStaticVarsCount function static variables"); + $data = self::continueDump($startingObject, $objects, $refCounts, 0, $maxNesting, $maxStringSize); do{ @@ -410,7 +443,6 @@ class MemoryManager{ $info["this"] = self::continueDump($closureThis, $objects, $refCounts, 0, $maxNesting, $maxStringSize); } - //TODO: scan non-closures for statics as well foreach($reflect->getStaticVariables() as $name => $variable){ $info["referencedVars"][$name] = self::continueDump($variable, $objects, $refCounts, 0, $maxNesting, $maxStringSize); } From ec7c5fd669a99892cc21b0dc0cedc96f8b126e17 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Sep 2020 17:20:02 +0100 Subject: [PATCH 1895/3224] Added a BrewingStandSlot enum --- src/block/BrewingStand.php | 68 ++++++++++++--- src/block/utils/BrewingStandSlot.php | 47 ++++++++++ tests/phpunit/block/BrewingStandTest.php | 104 +++++++++++++++++++++++ 3 files changed, 207 insertions(+), 12 deletions(-) create mode 100644 src/block/utils/BrewingStandSlot.php create mode 100644 tests/phpunit/block/BrewingStandTest.php diff --git a/src/block/BrewingStand.php b/src/block/BrewingStand.php index f4ae81b2b8..8fca8f216f 100644 --- a/src/block/BrewingStand.php +++ b/src/block/BrewingStand.php @@ -24,40 +24,84 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\tile\BrewingStand as TileBrewingStand; +use pocketmine\block\utils\BrewingStandSlot; use pocketmine\item\Item; use pocketmine\item\ToolTier; use pocketmine\math\Vector3; use pocketmine\player\Player; +use function array_key_exists; class BrewingStand extends Transparent{ - /** @var bool */ - protected $eastSlot = false; - /** @var bool */ - protected $northwestSlot = false; - /** @var bool */ - protected $southwestSlot = false; + /** + * @var BrewingStandSlot[] + * @phpstan-var array + */ + protected $slots = []; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); } protected function writeStateToMeta() : int{ - return ($this->eastSlot ? BlockLegacyMetadata::BREWING_STAND_FLAG_EAST : 0) | - ($this->southwestSlot ? BlockLegacyMetadata::BREWING_STAND_FLAG_SOUTHWEST : 0) | - ($this->northwestSlot ? BlockLegacyMetadata::BREWING_STAND_FLAG_NORTHWEST : 0); + $flags = 0; + foreach([ + BlockLegacyMetadata::BREWING_STAND_FLAG_EAST => BrewingStandSlot::EAST(), + BlockLegacyMetadata::BREWING_STAND_FLAG_NORTHWEST => BrewingStandSlot::NORTHWEST(), + BlockLegacyMetadata::BREWING_STAND_FLAG_SOUTHWEST => BrewingStandSlot::SOUTHWEST(), + ] as $flag => $slot){ + $flags |= (array_key_exists($slot->id(), $this->slots) ? $flag : 0); + } + return $flags; } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->eastSlot = ($stateMeta & BlockLegacyMetadata::BREWING_STAND_FLAG_EAST) !== 0; - $this->southwestSlot = ($stateMeta & BlockLegacyMetadata::BREWING_STAND_FLAG_SOUTHWEST) !== 0; - $this->northwestSlot = ($stateMeta & BlockLegacyMetadata::BREWING_STAND_FLAG_NORTHWEST) !== 0; + $this->slots = []; + foreach([ + BlockLegacyMetadata::BREWING_STAND_FLAG_EAST => BrewingStandSlot::EAST(), + BlockLegacyMetadata::BREWING_STAND_FLAG_NORTHWEST => BrewingStandSlot::NORTHWEST(), + BlockLegacyMetadata::BREWING_STAND_FLAG_SOUTHWEST => BrewingStandSlot::SOUTHWEST(), + ] as $flag => $slot){ + if(($stateMeta & $flag) !== 0){ + $this->slots[$slot->id()] = $slot; + } + } } public function getStateBitmask() : int{ return 0b111; } + public function hasSlot(BrewingStandSlot $slot) : bool{ + return array_key_exists($slot->id(), $this->slots); + } + + public function setSlot(BrewingStandSlot $slot, bool $occupied) : self{ + if($occupied){ + $this->slots[$slot->id()] = $slot; + }else{ + unset($this->slots[$slot->id()]); + } + return $this; + } + + /** + * @return BrewingStandSlot[] + * @phpstan-return array + */ + public function getSlots() : array{ + return $this->slots; + } + + /** @param BrewingStandSlot[] $slots */ + public function setSlots(array $slots) : self{ + $this->slots = []; + foreach($slots as $slot){ + $this->slots[$slot->id()] = $slot; + } + return $this; + } + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ $stand = $this->pos->getWorld()->getTile($this->pos); diff --git a/src/block/utils/BrewingStandSlot.php b/src/block/utils/BrewingStandSlot.php new file mode 100644 index 0000000000..7d257e9add --- /dev/null +++ b/src/block/utils/BrewingStandSlot.php @@ -0,0 +1,47 @@ +}, void, void> + */ + public function slotsProvider() : \Generator{ + yield [BrewingStandSlot::getAll()]; + yield [[BrewingStandSlot::EAST()]]; + yield [[BrewingStandSlot::EAST(), BrewingStandSlot::NORTHWEST()]]; + } + + /** + * + * @dataProvider slotsProvider + * + * @param BrewingStandSlot[] $slots + * @phpstan-param list $slots + */ + public function testHasAndSetSlot(array $slots) : void{ + $block = VanillaBlocks::BREWING_STAND(); + foreach($slots as $slot){ + $block->setSlot($slot, true); + } + foreach($slots as $slot){ + self::assertTrue($block->hasSlot($slot)); + } + + foreach($slots as $slot){ + $block->setSlot($slot, false); + } + foreach($slots as $slot){ + self::assertFalse($block->hasSlot($slot)); + } + } + + /** + * @dataProvider slotsProvider + * + * @param BrewingStandSlot[] $slots + * @phpstan-param list $slots + */ + public function testGetSlots(array $slots) : void{ + $block = VanillaBlocks::BREWING_STAND(); + + foreach($slots as $slot){ + $block->setSlot($slot, true); + } + + self::assertCount(count($slots), $block->getSlots()); + + foreach($slots as $slot){ + $block->setSlot($slot, false); + } + self::assertCount(0, $block->getSlots()); + } + + /** + * @dataProvider slotsProvider + * + * @param BrewingStandSlot[] $slots + * @phpstan-param list $slots + */ + public function testSetSlots(array $slots) : void{ + $block = VanillaBlocks::BREWING_STAND(); + + $block->setSlots($slots); + foreach($slots as $slot){ + self::assertTrue($block->hasSlot($slot)); + } + $block->setSlots([]); + self::assertCount(0, $block->getSlots()); + foreach($slots as $slot){ + self::assertFalse($block->hasSlot($slot)); + } + } +} From 9e3ff21aeab178ef5cab2d3480f3f1e28dc992d8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Sep 2020 17:26:54 +0100 Subject: [PATCH 1896/3224] Wall: remove unused import --- src/block/Wall.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/block/Wall.php b/src/block/Wall.php index b2ca11db98..073a6a2702 100644 --- a/src/block/Wall.php +++ b/src/block/Wall.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\ToolTier; -use pocketmine\math\Axis; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; From 12087c9850e607690ba0e960cc9f7ea8b54231c3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Sep 2020 17:41:00 +0100 Subject: [PATCH 1897/3224] Wall: use facing as value as well as key in connections --- src/block/Wall.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/block/Wall.php b/src/block/Wall.php index 073a6a2702..462835e0b4 100644 --- a/src/block/Wall.php +++ b/src/block/Wall.php @@ -29,7 +29,7 @@ use pocketmine\math\Facing; class Wall extends Transparent{ - /** @var bool[] facing => dummy */ + /** @var int[] facing => facing */ protected $connections = []; /** @var bool */ protected $up = false; @@ -44,7 +44,7 @@ class Wall extends Transparent{ foreach(Facing::HORIZONTAL as $facing){ $block = $this->getSide($facing); if($block instanceof static or $block instanceof FenceGate or ($block->isSolid() and !$block->isTransparent())){ - $this->connections[$facing] = true; + $this->connections[$facing] = $facing; }else{ unset($this->connections[$facing]); } From 14c156b162138148ac1663e3b3904a6517f4446a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 1 Oct 2020 14:46:14 +0100 Subject: [PATCH 1898/3224] Added ChemicalHeat block stub --- src/block/BlockFactory.php | 1 + src/block/ChemicalHeat.php | 32 ++++++++++++++++++++++++++++++++ src/block/VanillaBlocks.php | 2 ++ 3 files changed, 35 insertions(+) create mode 100644 src/block/ChemicalHeat.php diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 1097dc0f7e..d37b478ed0 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -502,6 +502,7 @@ class BlockFactory{ $this->register(new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_LAB_TABLE), "Lab Table", $chemistryTableBreakInfo)); $this->register(new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_MATERIAL_REDUCER), "Material Reducer", $chemistryTableBreakInfo)); + $this->register(new ChemicalHeat(new BID(Ids::CHEMICAL_HEAT), "Heat Block", $chemistryTableBreakInfo)); //region --- auto-generated TODOs for bedrock-1.11.0 --- //TODO: minecraft:bamboo //TODO: minecraft:bamboo_sapling diff --git a/src/block/ChemicalHeat.php b/src/block/ChemicalHeat.php new file mode 100644 index 0000000000..55cc7b9e04 --- /dev/null +++ b/src/block/ChemicalHeat.php @@ -0,0 +1,32 @@ +get(92)); self::register("carrots", $factory->get(141)); self::register("carved_pumpkin", $factory->get(410)); + self::register("chemical_heat", $factory->get(192)); self::register("chest", $factory->get(54, 2)); self::register("chiseled_quartz", $factory->get(155, 1)); self::register("chiseled_red_sandstone", $factory->get(179, 1)); From 84feec954f84fa20168b92e167136b24408071bf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 1 Oct 2020 21:41:46 +0100 Subject: [PATCH 1899/3224] BlockLegacyMetadata: Added constants for mushroom block variants --- src/block/BlockLegacyMetadata.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/block/BlockLegacyMetadata.php b/src/block/BlockLegacyMetadata.php index b04d8278de..f9da4c53c5 100644 --- a/src/block/BlockLegacyMetadata.php +++ b/src/block/BlockLegacyMetadata.php @@ -138,6 +138,21 @@ final class BlockLegacyMetadata{ public const LIQUID_FLAG_FALLING = 0x08; + public const MUSHROOM_BLOCK_ALL_PORES = 0; + public const MUSHROOM_BLOCK_CAP_NORTHWEST_CORNER = 1; + public const MUSHROOM_BLOCK_CAP_NORTH_SIDE = 2; + public const MUSHROOM_BLOCK_CAP_NORTHEAST_CORNER = 3; + public const MUSHROOM_BLOCK_CAP_WEST_SIDE = 4; + public const MUSHROOM_BLOCK_CAP_TOP_ONLY = 5; + public const MUSHROOM_BLOCK_CAP_EAST_SIDE = 6; + public const MUSHROOM_BLOCK_CAP_SOUTHWEST_CORNER = 7; + public const MUSHROOM_BLOCK_CAP_SOUTH_SIDE = 8; + public const MUSHROOM_BLOCK_CAP_SOUTHEAST_CORNER = 9; + public const MUSHROOM_BLOCK_STEM = 10; + //11, 12 and 13 appear the same as 0 + public const MUSHROOM_BLOCK_ALL_CAP = 14; + public const MUSHROOM_BLOCK_ALL_STEM = 15; + public const NETHER_PORTAL_AXIS_X = 1; public const NETHER_PORTAL_AXIS_Z = 2; From 201bdc069c29efc2df07aa91edd70505ba5839a0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 1 Oct 2020 22:07:43 +0100 Subject: [PATCH 1900/3224] phpstan 0.12.47 --- composer.json | 2 +- composer.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index c9f5468234..dfde4eaf02 100644 --- a/composer.json +++ b/composer.json @@ -50,7 +50,7 @@ "respect/validation": "^2.0" }, "require-dev": { - "phpstan/phpstan": "0.12.44", + "phpstan/phpstan": "0.12.47", "phpstan/phpstan-phpunit": "^0.12.6", "phpstan/phpstan-strict-rules": "^0.12.2", "phpunit/phpunit": "^9.2" diff --git a/composer.lock b/composer.lock index 350ea84c4c..19b11a86ab 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "13b64be4a6f2487487d1acbcfafcb82f", + "content-hash": "3e1dac93b1419cf95ea65babb8aa44d9", "packages": [ { "name": "adhocore/json-comment", @@ -1443,16 +1443,16 @@ }, { "name": "phpstan/phpstan", - "version": "0.12.44", + "version": "0.12.47", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "330b45776ea77f167b150e24787412414a8fa469" + "reference": "74325a6ae15378db0df71b969ded245378d2e058" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/330b45776ea77f167b150e24787412414a8fa469", - "reference": "330b45776ea77f167b150e24787412414a8fa469", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/74325a6ae15378db0df71b969ded245378d2e058", + "reference": "74325a6ae15378db0df71b969ded245378d2e058", "shasum": "" }, "require": { @@ -1495,7 +1495,7 @@ "type": "tidelift" } ], - "time": "2020-09-24T15:28:47+00:00" + "time": "2020-09-29T13:35:39+00:00" }, { "name": "phpstan/phpstan-phpunit", From 7a436dc47c771162b1983fe685580979a8bed19c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 1 Oct 2020 22:10:02 +0100 Subject: [PATCH 1901/3224] updated blockfactory consistency check --- tests/phpunit/block/block_factory_consistency_check.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 47a3f148af..b19b1a8d52 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From 6734dcc79f629f1031ea4b7f34eda6b4f655f2c1 Mon Sep 17 00:00:00 2001 From: Tayyab R <32965703+Ifera@users.noreply.github.com> Date: Fri, 2 Oct 2020 02:23:02 +0500 Subject: [PATCH 1902/3224] Introduce PlayerDisplayNameChangeEvent (listen only) (#3847) --- .../player/PlayerDisplayNameChangeEvent.php | 48 +++++++++++++++++++ src/player/Player.php | 6 ++- 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 src/event/player/PlayerDisplayNameChangeEvent.php diff --git a/src/event/player/PlayerDisplayNameChangeEvent.php b/src/event/player/PlayerDisplayNameChangeEvent.php new file mode 100644 index 0000000000..27de577c8e --- /dev/null +++ b/src/event/player/PlayerDisplayNameChangeEvent.php @@ -0,0 +1,48 @@ +player = $player; + $this->oldName = $oldName; + $this->newName = $newName; + } + + public function getOldName() : string{ + return $this->oldName; + } + + public function getNewName() : string{ + return $this->newName; + } +} \ No newline at end of file diff --git a/src/player/Player.php b/src/player/Player.php index d7f1c1786d..fd9d64800f 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -52,6 +52,7 @@ use pocketmine\event\player\PlayerChangeSkinEvent; use pocketmine\event\player\PlayerChatEvent; use pocketmine\event\player\PlayerCommandPreprocessEvent; use pocketmine\event\player\PlayerDeathEvent; +use pocketmine\event\player\PlayerDisplayNameChangeEvent; use pocketmine\event\player\PlayerExhaustEvent; use pocketmine\event\player\PlayerGameModeChangeEvent; use pocketmine\event\player\PlayerInteractEvent; @@ -622,7 +623,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } public function setDisplayName(string $name) : void{ - $this->displayName = $name; + $ev = new PlayerDisplayNameChangeEvent($this, $this->displayName, $name); + $ev->call(); + + $this->displayName = $ev->getNewName(); } /** From 5807a385cc61fa6e117075081bd9e92c1c166ef8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 2 Oct 2020 00:59:53 +0100 Subject: [PATCH 1903/3224] Added stub classes for Beacon this doesn't do anything yet, it's intended solely to prevent further loss of data. --- src/block/Beacon.php | 33 ++++++++++ src/block/BlockFactory.php | 2 + src/block/VanillaBlocks.php | 2 + src/block/tile/Beacon.php | 60 +++++++++++++++++++ .../block_factory_consistency_check.json | 2 +- 5 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 src/block/Beacon.php create mode 100644 src/block/tile/Beacon.php diff --git a/src/block/Beacon.php b/src/block/Beacon.php new file mode 100644 index 0000000000..ef09968bb4 --- /dev/null +++ b/src/block/Beacon.php @@ -0,0 +1,33 @@ +register(new BambooSapling(new BID(Ids::BAMBOO_SAPLING), "Bamboo Sapling", BlockBreakInfo::instant())); $this->register(new Banner(new BIDFlattened(Ids::STANDING_BANNER, Ids::WALL_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Banner")); $this->register(new Transparent(new BID(Ids::BARRIER), "Barrier", BlockBreakInfo::indestructible())); + $this->register(new Beacon(new BID(Ids::BEACON, 0, null, TileBeacon::class), "Beacon", new BlockBreakInfo(3.0))); $this->register(new Bed(new BID(Ids::BED_BLOCK, 0, ItemIds::BED, TileBed::class), "Bed Block")); $this->register(new Bedrock(new BID(Ids::BEDROCK), "Bedrock")); $this->register(new Beetroot(new BID(Ids::BEETROOT_BLOCK), "Beetroot Block")); diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index c812a7c683..d1b625e4db 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -58,6 +58,7 @@ use function assert; * @method static BambooSapling BAMBOO_SAPLING() * @method static Banner BANNER() * @method static Transparent BARRIER() + * @method static Beacon BEACON() * @method static Bed BED() * @method static Bedrock BEDROCK() * @method static Beetroot BEETROOTS() @@ -727,6 +728,7 @@ final class VanillaBlocks{ self::register("bamboo_sapling", $factory->get(419)); self::register("banner", $factory->get(176)); self::register("barrier", $factory->get(416)); + self::register("beacon", $factory->get(138)); self::register("bed", $factory->get(26)); self::register("bedrock", $factory->get(7)); self::register("beetroots", $factory->get(244)); diff --git a/src/block/tile/Beacon.php b/src/block/tile/Beacon.php new file mode 100644 index 0000000000..c2bb605f06 --- /dev/null +++ b/src/block/tile/Beacon.php @@ -0,0 +1,60 @@ +setInt(self::TAG_PRIMARY, $this->primaryEffect); + $nbt->setInt(self::TAG_SECONDARY, $this->secondaryEffect); + } + + public function readSaveData(CompoundTag $nbt) : void{ + //TODO: PC uses Primary and Secondary (capitalized first letter), we don't read them here because the IDs would be different + $this->primaryEffect = $nbt->getInt(self::TAG_PRIMARY); + $this->secondaryEffect = $nbt->getInt(self::TAG_SECONDARY); + } + + protected function writeSaveData(CompoundTag $nbt) : void{ + $nbt->setInt(self::TAG_PRIMARY, $this->primaryEffect); + $nbt->setInt(self::TAG_SECONDARY, $this->secondaryEffect); + } + + public function getPrimaryEffect() : int{ return $this->primaryEffect; } + + public function setPrimaryEffect(int $primaryEffect) : void{ $this->primaryEffect = $primaryEffect; } + + public function getSecondaryEffect() : int{ return $this->secondaryEffect; } + + public function setSecondaryEffect(int $secondaryEffect) : void{ $this->secondaryEffect = $secondaryEffect; } +} diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index b19b1a8d52..7beae1d0fd 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From a77970448e13af2b5123ee2dc7a8bc63232a300d Mon Sep 17 00:00:00 2001 From: IceCruelStuff <50642756+IceCruelStuff@users.noreply.github.com> Date: Fri, 2 Oct 2020 04:07:49 -0700 Subject: [PATCH 1904/3224] Emerald ore in Mountains biome (#3750) --- src/world/biome/MountainsBiome.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/world/biome/MountainsBiome.php b/src/world/biome/MountainsBiome.php index 0d9a8a0e26..fb820034e5 100644 --- a/src/world/biome/MountainsBiome.php +++ b/src/world/biome/MountainsBiome.php @@ -23,6 +23,9 @@ declare(strict_types=1); namespace pocketmine\world\biome; +use pocketmine\block\VanillaBlocks; +use pocketmine\world\generator\object\OreType; +use pocketmine\world\generator\populator\Ore; use pocketmine\world\generator\populator\TallGrass; use pocketmine\world\generator\populator\Tree; @@ -40,7 +43,12 @@ class MountainsBiome extends GrassyBiome{ $this->addPopulator($tallGrass); - //TODO: add emerald + $ores = new Ore(); + $ores->setOreTypes([ + new OreType(VanillaBlocks::EMERALD_ORE(), 11, 1, 0, 32) + ]); + + $this->addPopulator($ores); $this->setElevation(63, 127); From d0213f99ac401ad3b2be9d3234300f8765bbb12d Mon Sep 17 00:00:00 2001 From: Dylan T Date: Fri, 2 Oct 2020 12:24:18 +0100 Subject: [PATCH 1905/3224] MountainsBiome: fix error from stale PR merge --- src/world/biome/MountainsBiome.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/biome/MountainsBiome.php b/src/world/biome/MountainsBiome.php index fb820034e5..47986a8aa3 100644 --- a/src/world/biome/MountainsBiome.php +++ b/src/world/biome/MountainsBiome.php @@ -45,7 +45,7 @@ class MountainsBiome extends GrassyBiome{ $ores = new Ore(); $ores->setOreTypes([ - new OreType(VanillaBlocks::EMERALD_ORE(), 11, 1, 0, 32) + new OreType(VanillaBlocks::EMERALD_ORE(), VanillaBlocks::STONE(), 11, 1, 0, 32) ]); $this->addPopulator($ores); From 9191e75392d9e7144269e6ca40d6674155976123 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 3 Oct 2020 16:41:26 +0100 Subject: [PATCH 1906/3224] LevelDB: quick and dirty hack for air with bad metadata this needs a proper solution, but this is a pressing issue that can't wait. --- src/world/format/io/leveldb/LevelDB.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 3842279e82..25512b341e 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -169,6 +169,11 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $id = $idMap->stringToLegacy($tag->getString("name")) ?? BlockLegacyIds::INFO_UPDATE; $data = $tag->getShort("val"); + if($id === BlockLegacyIds::AIR){ + //TODO: quick and dirty hack for artifacts left behind by broken world editors + //we really need a proper state fixer, but this is a pressing issue. + $data = 0; + } $palette[] = ($id << 4) | $data; } From 388a19ef5d52768229ace10f65cb082ca24832c9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 4 Oct 2020 11:38:24 +0100 Subject: [PATCH 1907/3224] Persistent block metadata may now have mutable parts Not allowing this makes stuff like anvil damage, colour, wood type, live/dead bit, wet/dry etc all too much hassle to deal with. Naturally I want to get rid of this shit altogether, but first it's necessary to construct a new system that we can shift into before all this bullshit can be addressed fully, so for now we have to work within the bounds of the old system. This change will permit dynamic colours for concrete/concrete powder etc, dynamic wood types where the wood type isn't embedded in the legacy ID, and so forth. Allowing full flexibility requires either more old system hacks or completing the migration to a new system which doesn't have these limitations. I prefer to do the latter, but this change will make it somewhat easier to do. --- src/block/Anvil.php | 12 ++++++++++-- src/block/Block.php | 9 ++++++++- src/block/BlockFactory.php | 6 ++---- src/block/Torch.php | 3 ++- src/block/VanillaBlocks.php | 4 ---- .../block/block_factory_consistency_check.json | 2 +- 6 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/block/Anvil.php b/src/block/Anvil.php index fe8a8bc561..14b2a8379f 100644 --- a/src/block/Anvil.php +++ b/src/block/Anvil.php @@ -40,19 +40,27 @@ class Anvil extends Transparent implements Fallable{ use FallableTrait; use HorizontalFacingTrait; + /** @var int */ + private $damage = 0; + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 6000.0)); } protected function writeStateToMeta() : int{ - return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing); + return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) | ($this->damage << 2); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta); + $this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x3); + $this->damage = BlockDataSerializer::readBoundedInt("damage", $stateMeta >> 2, 0, 2); } public function getStateBitmask() : int{ + return 0b1111; + } + + public function getNonPersistentStateBitmask() : int{ return 0b11; } diff --git a/src/block/Block.php b/src/block/Block.php index dae39760f8..d81d143d88 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -101,7 +101,10 @@ class Block{ } public function asItem() : Item{ - return ItemFactory::getInstance()->get($this->idInfo->getItemId(), $this->idInfo->getVariant()); + return ItemFactory::getInstance()->get( + $this->idInfo->getItemId(), + $this->idInfo->getVariant() | ($this->writeStateToMeta() & ~$this->getNonPersistentStateBitmask()) + ); } public function getMeta() : int{ @@ -117,6 +120,10 @@ class Block{ return 0; } + public function getNonPersistentStateBitmask() : int{ + return $this->getStateBitmask(); + } + protected function writeStateToMeta() : int{ return 0; } diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 47d5e4de6f..2b1241d37a 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -101,9 +101,7 @@ class BlockFactory{ $this->register(new ActivatorRail(new BID(Ids::ACTIVATOR_RAIL), "Activator Rail")); $this->register(new Air(new BID(Ids::AIR), "Air")); - $this->register(new Anvil(new BID(Ids::ANVIL, Meta::ANVIL_NORMAL), "Anvil")); - $this->register(new Anvil(new BID(Ids::ANVIL, Meta::ANVIL_SLIGHTLY_DAMAGED), "Slightly Damaged Anvil")); - $this->register(new Anvil(new BID(Ids::ANVIL, Meta::ANVIL_VERY_DAMAGED), "Very Damaged Anvil")); + $this->register(new Anvil(new BID(Ids::ANVIL), "Anvil")); $this->register(new Bamboo(new BID(Ids::BAMBOO), "Bamboo", new BlockBreakInfo(2.0 /* 1.0 in PC */, BlockToolType::AXE))); $this->register(new BambooSapling(new BID(Ids::BAMBOO_SAPLING), "Bamboo Sapling", BlockBreakInfo::instant())); $this->register(new Banner(new BIDFlattened(Ids::STANDING_BANNER, Ids::WALL_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Banner")); @@ -833,7 +831,7 @@ class BlockFactory{ $v = clone $block; try{ - $v->readStateFromData($id, $m & $stateMask); + $v->readStateFromData($id, $m); if($v->getMeta() !== $m){ throw new InvalidBlockStateException("Corrupted meta"); //don't register anything that isn't the same when we read it back again } diff --git a/src/block/Torch.php b/src/block/Torch.php index 570c11aa66..2a8b200322 100644 --- a/src/block/Torch.php +++ b/src/block/Torch.php @@ -44,7 +44,8 @@ class Torch extends Flowable{ } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = $stateMeta === 5 ? Facing::UP : BlockDataSerializer::readHorizontalFacing(6 - $stateMeta); + $facingMeta = $stateMeta & 0x7; + $this->facing = $facingMeta === 5 ? Facing::UP : BlockDataSerializer::readHorizontalFacing(6 - $facingMeta); } public function getStateBitmask() : int{ diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index d1b625e4db..5215751216 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -600,7 +600,6 @@ use function assert; * @method static Wall SANDSTONE_WALL() * @method static SeaLantern SEA_LANTERN() * @method static SeaPickle SEA_PICKLE() - * @method static Anvil SLIGHTLY_DAMAGED_ANVIL() * @method static Opaque SMOOTH_QUARTZ() * @method static Slab SMOOTH_QUARTZ_SLAB() * @method static Stair SMOOTH_QUARTZ_STAIRS() @@ -648,7 +647,6 @@ use function assert; * @method static Tripwire TRIPWIRE() * @method static TripwireHook TRIPWIRE_HOOK() * @method static UnderwaterTorch UNDERWATER_TORCH() - * @method static Anvil VERY_DAMAGED_ANVIL() * @method static Vine VINES() * @method static Water WATER() * @method static WeightedPressurePlateHeavy WEIGHTED_PRESSURE_PLATE_HEAVY() @@ -1270,7 +1268,6 @@ final class VanillaBlocks{ self::register("sandstone_wall", $factory->get(139, 5)); self::register("sea_lantern", $factory->get(169)); self::register("sea_pickle", $factory->get(411)); - self::register("slightly_damaged_anvil", $factory->get(145, 4)); self::register("smooth_quartz", $factory->get(155, 3)); self::register("smooth_quartz_slab", $factory->get(421, 1)); self::register("smooth_quartz_stairs", $factory->get(440)); @@ -1318,7 +1315,6 @@ final class VanillaBlocks{ self::register("tripwire", $factory->get(132)); self::register("tripwire_hook", $factory->get(131)); self::register("underwater_torch", $factory->get(239, 5)); - self::register("very_damaged_anvil", $factory->get(145, 8)); self::register("vines", $factory->get(106)); self::register("water", $factory->get(8)); self::register("weighted_pressure_plate_heavy", $factory->get(148)); diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 7beae1d0fd..26ed5c79e4 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Slightly Damaged Anvil","2325":"Slightly Damaged Anvil","2326":"Slightly Damaged Anvil","2327":"Slightly Damaged Anvil","2328":"Very Damaged Anvil","2329":"Very Damaged Anvil","2330":"Very Damaged Anvil","2331":"Very Damaged Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From e6bf7278fc82b6fc6bfd69776b258659b481c6bc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 4 Oct 2020 17:24:40 +0100 Subject: [PATCH 1908/3224] Sign: remove obsolete clone hook this is no longer required because SignText is not mutable anymore. --- src/block/Sign.php | 5 ----- src/item/ItemBlockWallOrFloor.php | 28 ++++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 src/item/ItemBlockWallOrFloor.php diff --git a/src/block/Sign.php b/src/block/Sign.php index 45640e9686..2994759ddb 100644 --- a/src/block/Sign.php +++ b/src/block/Sign.php @@ -59,11 +59,6 @@ class Sign extends Transparent{ $this->text = new SignText(); } - public function __clone(){ - parent::__clone(); - $this->text = clone $this->text; - } - public function getId() : int{ return $this->facing === Facing::UP ? parent::getId() : $this->idInfo->getSecondId(); } diff --git a/src/item/ItemBlockWallOrFloor.php b/src/item/ItemBlockWallOrFloor.php new file mode 100644 index 0000000000..763d60e03a --- /dev/null +++ b/src/item/ItemBlockWallOrFloor.php @@ -0,0 +1,28 @@ + Date: Sun, 4 Oct 2020 17:52:23 +0100 Subject: [PATCH 1909/3224] Revert back to separated floor/wall sign the conditionally useless properties are problematic. --- src/block/{Sign.php => BaseSign.php} | 52 ++------------- src/block/BlockFactory.php | 3 +- src/block/BlockLegacyIdHelper.php | 32 +++++++--- src/block/FloorSign.php | 63 +++++++++++++++++++ src/block/VanillaBlocks.php | 24 +++++-- src/block/WallSign.php | 61 ++++++++++++++++++ src/block/tile/Sign.php | 2 +- src/event/block/SignChangeEvent.php | 8 +-- src/item/Bamboo.php | 2 +- src/item/Banner.php | 2 +- src/item/Bed.php | 2 +- src/item/BeetrootSeeds.php | 2 +- src/item/Carrot.php | 2 +- src/item/CocoaBeans.php | 2 +- src/item/Item.php | 2 +- src/item/ItemBlock.php | 2 +- src/item/ItemBlockWallOrFloor.php | 28 ++++++++- src/item/ItemFactory.php | 13 ++-- src/item/MelonSeeds.php | 2 +- src/item/Potato.php | 2 +- src/item/PumpkinSeeds.php | 2 +- src/item/Redstone.php | 2 +- src/item/Sign.php | 2 +- src/item/Skull.php | 2 +- src/item/StringItem.php | 2 +- src/item/WheatSeeds.php | 2 +- .../mcpe/handler/InGamePacketHandler.php | 4 +- src/world/World.php | 2 +- .../block_factory_consistency_check.json | 2 +- 29 files changed, 232 insertions(+), 94 deletions(-) rename src/block/{Sign.php => BaseSign.php} (68%) create mode 100644 src/block/FloorSign.php create mode 100644 src/block/WallSign.php diff --git a/src/block/Sign.php b/src/block/BaseSign.php similarity index 68% rename from src/block/Sign.php rename to src/block/BaseSign.php index 2994759ddb..a2b0ffc96d 100644 --- a/src/block/Sign.php +++ b/src/block/BaseSign.php @@ -39,46 +39,17 @@ use function assert; use function floor; use function strlen; -class Sign extends Transparent{ - /** @var BlockIdentifierFlattened */ - protected $idInfo; - +abstract class BaseSign extends Transparent{ //TODO: conditionally useless properties, find a way to fix - /** @var int */ - protected $rotation = 0; - - /** @var int */ - protected $facing = Facing::UP; - /** @var SignText */ protected $text; - public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0, BlockToolType::AXE)); $this->text = new SignText(); } - public function getId() : int{ - return $this->facing === Facing::UP ? parent::getId() : $this->idInfo->getSecondId(); - } - - protected function writeStateToMeta() : int{ - if($this->facing === Facing::UP){ - return $this->rotation; - } - return BlockDataSerializer::writeHorizontalFacing($this->facing); - } - - public function readStateFromData(int $id, int $stateMeta) : void{ - if($id === $this->idInfo->getSecondId()){ - $this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta); - }else{ - $this->facing = Facing::UP; - $this->rotation = $stateMeta; - } - } - public function readStateFromWorld() : void{ parent::readStateFromWorld(); $tile = $this->pos->getWorld()->getTile($this->pos); @@ -94,10 +65,6 @@ class Sign extends Transparent{ $tile->setText($this->text); } - public function getStateBitmask() : int{ - return 0b1111; - } - public function isSolid() : bool{ return false; } @@ -109,21 +76,10 @@ class Sign extends Transparent{ return []; } - public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($face !== Facing::DOWN){ - $this->facing = $face; - if($face === Facing::UP){ - $this->rotation = $player !== null ? ((int) floor((($player->getLocation()->getYaw() + 180) * 16 / 360) + 0.5)) & 0x0f : 0; - } - - return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); - } - - return false; - } + abstract protected function getSupportingFace() : int; public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::opposite($this->facing))->getId() === BlockLegacyIds::AIR){ + if($this->getSide($this->getSupportingFace())->getId() === BlockLegacyIds::AIR){ $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 2b1241d37a..c0d02d9319 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -443,7 +443,8 @@ class BlockFactory{ $this->register(new WoodenPressurePlate(BlockLegacyIdHelper::getWoodenPressurePlateIdentifier($treeType), $treeType->getDisplayName() . " Pressure Plate")); $this->register(new WoodenTrapdoor(BlockLegacyIdHelper::getWoodenTrapdoorIdentifier($treeType), $treeType->getDisplayName() . " Trapdoor")); - $this->register(new Sign(BlockLegacyIdHelper::getWoodenSignIdentifier($treeType), $treeType->getDisplayName() . " Sign")); + $this->register(new FloorSign(BlockLegacyIdHelper::getWoodenFloorSignIdentifier($treeType), $treeType->getDisplayName() . " Sign")); + $this->register(new WallSign(BlockLegacyIdHelper::getWoodenWallSignIdentifier($treeType), $treeType->getDisplayName() . " Wall Sign")); } static $sandstoneTypes = [ diff --git a/src/block/BlockLegacyIdHelper.php b/src/block/BlockLegacyIdHelper.php index ba140fadea..ec37e6ae84 100644 --- a/src/block/BlockLegacyIdHelper.php +++ b/src/block/BlockLegacyIdHelper.php @@ -34,20 +34,38 @@ use pocketmine\utils\AssumptionFailedError; final class BlockLegacyIdHelper{ - public static function getWoodenSignIdentifier(TreeType $treeType) : BIDFlattened{ + public static function getWoodenFloorSignIdentifier(TreeType $treeType) : BID{ switch($treeType->id()){ case TreeType::OAK()->id(): - return new BIDFlattened(Ids::SIGN_POST, Ids::WALL_SIGN, 0, ItemIds::SIGN, TileSign::class); + return new BID(Ids::SIGN_POST, 0, ItemIds::SIGN, TileSign::class); case TreeType::SPRUCE()->id(): - return new BIDFlattened(Ids::SPRUCE_STANDING_SIGN, Ids::SPRUCE_WALL_SIGN, 0, ItemIds::SPRUCE_SIGN, TileSign::class); + return new BID(Ids::SPRUCE_STANDING_SIGN, 0, ItemIds::SPRUCE_SIGN, TileSign::class); case TreeType::BIRCH()->id(): - return new BIDFlattened(Ids::BIRCH_STANDING_SIGN, Ids::BIRCH_WALL_SIGN, 0, ItemIds::BIRCH_SIGN, TileSign::class); + return new BID(Ids::BIRCH_STANDING_SIGN, 0, ItemIds::BIRCH_SIGN, TileSign::class); case TreeType::JUNGLE()->id(): - return new BIDFlattened(Ids::JUNGLE_STANDING_SIGN, Ids::JUNGLE_WALL_SIGN, 0, ItemIds::JUNGLE_SIGN, TileSign::class); + return new BID(Ids::JUNGLE_STANDING_SIGN, 0, ItemIds::JUNGLE_SIGN, TileSign::class); case TreeType::ACACIA()->id(): - return new BIDFlattened(Ids::ACACIA_STANDING_SIGN, Ids::ACACIA_WALL_SIGN, 0, ItemIds::ACACIA_SIGN, TileSign::class); + return new BID(Ids::ACACIA_STANDING_SIGN,0, ItemIds::ACACIA_SIGN, TileSign::class); case TreeType::DARK_OAK()->id(): - return new BIDFlattened(Ids::DARKOAK_STANDING_SIGN, Ids::DARKOAK_WALL_SIGN, 0, ItemIds::DARKOAK_SIGN, TileSign::class); + return new BID(Ids::DARKOAK_STANDING_SIGN, 0, ItemIds::DARKOAK_SIGN, TileSign::class); + } + throw new AssumptionFailedError("Switch should cover all wood types"); + } + + public static function getWoodenWallSignIdentifier(TreeType $treeType) : BID{ + switch($treeType->id()){ + case TreeType::OAK()->id(): + return new BID(Ids::WALL_SIGN, 0, ItemIds::SIGN, TileSign::class); + case TreeType::SPRUCE()->id(): + return new BID(Ids::SPRUCE_WALL_SIGN, 0, ItemIds::SPRUCE_SIGN, TileSign::class); + case TreeType::BIRCH()->id(): + return new BID(Ids::BIRCH_WALL_SIGN, 0, ItemIds::BIRCH_SIGN, TileSign::class); + case TreeType::JUNGLE()->id(): + return new BID(Ids::JUNGLE_WALL_SIGN, 0, ItemIds::JUNGLE_SIGN, TileSign::class); + case TreeType::ACACIA()->id(): + return new BID(Ids::ACACIA_WALL_SIGN, 0, ItemIds::ACACIA_SIGN, TileSign::class); + case TreeType::DARK_OAK()->id(): + return new BID(Ids::DARKOAK_WALL_SIGN, 0, ItemIds::DARKOAK_SIGN, TileSign::class); } throw new AssumptionFailedError("Switch should cover all wood types"); } diff --git a/src/block/FloorSign.php b/src/block/FloorSign.php new file mode 100644 index 0000000000..4544afeed9 --- /dev/null +++ b/src/block/FloorSign.php @@ -0,0 +1,63 @@ +rotation = $stateMeta; + } + + protected function writeStateToMeta() : int{ + return $this->rotation; + } + + public function getStateBitmask() : int{ + return 0b1111; + } + + protected function getSupportingFace() : int{ + return Facing::DOWN; + } + + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($face !== Facing::UP){ + return false; + } + + if($player !== null){ + $this->rotation = ((int) floor((($player->getLocation()->getYaw() + 180) * 16 / 360) + 0.5)) & 0x0f; + } + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } +} diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 5215751216..4634742015 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -40,10 +40,11 @@ use function assert; * @method static Planks ACACIA_PLANKS() * @method static WoodenPressurePlate ACACIA_PRESSURE_PLATE() * @method static Sapling ACACIA_SAPLING() - * @method static Sign ACACIA_SIGN() + * @method static FloorSign ACACIA_SIGN() * @method static WoodenSlab ACACIA_SLAB() * @method static WoodenStairs ACACIA_STAIRS() * @method static WoodenTrapdoor ACACIA_TRAPDOOR() + * @method static WallSign ACACIA_WALL_SIGN() * @method static Wood ACACIA_WOOD() * @method static ActivatorRail ACTIVATOR_RAIL() * @method static Air AIR() @@ -71,10 +72,11 @@ use function assert; * @method static Planks BIRCH_PLANKS() * @method static WoodenPressurePlate BIRCH_PRESSURE_PLATE() * @method static Sapling BIRCH_SAPLING() - * @method static Sign BIRCH_SIGN() + * @method static FloorSign BIRCH_SIGN() * @method static WoodenSlab BIRCH_SLAB() * @method static WoodenStairs BIRCH_STAIRS() * @method static WoodenTrapdoor BIRCH_TRAPDOOR() + * @method static WallSign BIRCH_WALL_SIGN() * @method static Wood BIRCH_WOOD() * @method static Carpet BLACK_CARPET() * @method static Concrete BLACK_CONCRETE() @@ -158,10 +160,11 @@ use function assert; * @method static Planks DARK_OAK_PLANKS() * @method static WoodenPressurePlate DARK_OAK_PRESSURE_PLATE() * @method static Sapling DARK_OAK_SAPLING() - * @method static Sign DARK_OAK_SIGN() + * @method static FloorSign DARK_OAK_SIGN() * @method static WoodenSlab DARK_OAK_SLAB() * @method static WoodenStairs DARK_OAK_STAIRS() * @method static WoodenTrapdoor DARK_OAK_TRAPDOOR() + * @method static WallSign DARK_OAK_WALL_SIGN() * @method static Wood DARK_OAK_WOOD() * @method static Opaque DARK_PRISMARINE() * @method static Slab DARK_PRISMARINE_SLAB() @@ -410,10 +413,11 @@ use function assert; * @method static Planks JUNGLE_PLANKS() * @method static WoodenPressurePlate JUNGLE_PRESSURE_PLATE() * @method static Sapling JUNGLE_SAPLING() - * @method static Sign JUNGLE_SIGN() + * @method static FloorSign JUNGLE_SIGN() * @method static WoodenSlab JUNGLE_SLAB() * @method static WoodenStairs JUNGLE_STAIRS() * @method static WoodenTrapdoor JUNGLE_TRAPDOOR() + * @method static WallSign JUNGLE_WALL_SIGN() * @method static Wood JUNGLE_WOOD() * @method static ChemistryTable LAB_TABLE() * @method static Ladder LADDER() @@ -496,10 +500,11 @@ use function assert; * @method static Planks OAK_PLANKS() * @method static WoodenPressurePlate OAK_PRESSURE_PLATE() * @method static Sapling OAK_SAPLING() - * @method static Sign OAK_SIGN() + * @method static FloorSign OAK_SIGN() * @method static WoodenSlab OAK_SLAB() * @method static WoodenStairs OAK_STAIRS() * @method static WoodenTrapdoor OAK_TRAPDOOR() + * @method static WallSign OAK_WALL_SIGN() * @method static Wood OAK_WOOD() * @method static Opaque OBSIDIAN() * @method static Carpet ORANGE_CARPET() @@ -624,10 +629,11 @@ use function assert; * @method static Planks SPRUCE_PLANKS() * @method static WoodenPressurePlate SPRUCE_PRESSURE_PLATE() * @method static Sapling SPRUCE_SAPLING() - * @method static Sign SPRUCE_SIGN() + * @method static FloorSign SPRUCE_SIGN() * @method static WoodenSlab SPRUCE_SLAB() * @method static WoodenStairs SPRUCE_STAIRS() * @method static WoodenTrapdoor SPRUCE_TRAPDOOR() + * @method static WallSign SPRUCE_WALL_SIGN() * @method static Wood SPRUCE_WOOD() * @method static Opaque STONE() * @method static Slab STONE_BRICK_SLAB() @@ -712,6 +718,7 @@ final class VanillaBlocks{ self::register("acacia_slab", $factory->get(158, 4)); self::register("acacia_stairs", $factory->get(163)); self::register("acacia_trapdoor", $factory->get(400)); + self::register("acacia_wall_sign", $factory->get(446, 2)); self::register("acacia_wood", $factory->get(467, 4)); self::register("activator_rail", $factory->get(126)); self::register("air", $factory->get(0)); @@ -743,6 +750,7 @@ final class VanillaBlocks{ self::register("birch_slab", $factory->get(158, 2)); self::register("birch_stairs", $factory->get(135)); self::register("birch_trapdoor", $factory->get(401)); + self::register("birch_wall_sign", $factory->get(442, 2)); self::register("birch_wood", $factory->get(467, 2)); self::register("black_carpet", $factory->get(171, 15)); self::register("black_concrete", $factory->get(236, 15)); @@ -830,6 +838,7 @@ final class VanillaBlocks{ self::register("dark_oak_slab", $factory->get(158, 5)); self::register("dark_oak_stairs", $factory->get(164)); self::register("dark_oak_trapdoor", $factory->get(402)); + self::register("dark_oak_wall_sign", $factory->get(448, 2)); self::register("dark_oak_wood", $factory->get(467, 5)); self::register("dark_prismarine", $factory->get(168, 1)); self::register("dark_prismarine_slab", $factory->get(182, 3)); @@ -1082,6 +1091,7 @@ final class VanillaBlocks{ self::register("jungle_slab", $factory->get(158, 3)); self::register("jungle_stairs", $factory->get(136)); self::register("jungle_trapdoor", $factory->get(403)); + self::register("jungle_wall_sign", $factory->get(444, 2)); self::register("jungle_wood", $factory->get(467, 3)); self::register("lab_table", $factory->get(238, 12)); self::register("ladder", $factory->get(65, 2)); @@ -1168,6 +1178,7 @@ final class VanillaBlocks{ self::register("oak_slab", $factory->get(158)); self::register("oak_stairs", $factory->get(53)); self::register("oak_trapdoor", $factory->get(96)); + self::register("oak_wall_sign", $factory->get(68, 2)); self::register("oak_wood", $factory->get(467)); self::register("obsidian", $factory->get(49)); self::register("orange_carpet", $factory->get(171, 1)); @@ -1296,6 +1307,7 @@ final class VanillaBlocks{ self::register("spruce_slab", $factory->get(158, 1)); self::register("spruce_stairs", $factory->get(134)); self::register("spruce_trapdoor", $factory->get(404)); + self::register("spruce_wall_sign", $factory->get(437, 2)); self::register("spruce_wood", $factory->get(467, 1)); self::register("stone", $factory->get(1)); self::register("stone_brick_slab", $factory->get(44, 5)); diff --git a/src/block/WallSign.php b/src/block/WallSign.php new file mode 100644 index 0000000000..0f094ae300 --- /dev/null +++ b/src/block/WallSign.php @@ -0,0 +1,61 @@ +facing); + } + + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta); + } + + public function getStateBitmask() : int{ + return 0b111; + } + + protected function getSupportingFace() : int{ + return Facing::opposite($this->facing); + } + + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if(Facing::axis($face) === Axis::Y){ + return false; + } + $this->facing = $face; + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } +} diff --git a/src/block/tile/Sign.php b/src/block/tile/Sign.php index f09940b352..8701d4a0b6 100644 --- a/src/block/tile/Sign.php +++ b/src/block/tile/Sign.php @@ -37,7 +37,7 @@ use function sprintf; /** * @deprecated - * @see \pocketmine\block\Sign + * @see \pocketmine\block\BaseSign */ class Sign extends Spawnable{ public const TAG_TEXT_BLOB = "Text"; diff --git a/src/event/block/SignChangeEvent.php b/src/event/block/SignChangeEvent.php index 63357c2381..4864eb7522 100644 --- a/src/event/block/SignChangeEvent.php +++ b/src/event/block/SignChangeEvent.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\event\block; -use pocketmine\block\Sign; +use pocketmine\block\BaseSign; use pocketmine\block\utils\SignText; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; @@ -35,7 +35,7 @@ use pocketmine\player\Player; class SignChangeEvent extends BlockEvent implements Cancellable{ use CancellableTrait; - /** @var Sign */ + /** @var BaseSign */ private $sign; /** @var Player */ @@ -44,14 +44,14 @@ class SignChangeEvent extends BlockEvent implements Cancellable{ /** @var SignText */ private $text; - public function __construct(Sign $sign, Player $player, SignText $text){ + public function __construct(BaseSign $sign, Player $player, SignText $text){ parent::__construct($sign); $this->sign = $sign; $this->player = $player; $this->text = $text; } - public function getSign() : Sign{ + public function getSign() : BaseSign{ return $this->sign; } diff --git a/src/item/Bamboo.php b/src/item/Bamboo.php index 96103d0581..daf911dc4c 100644 --- a/src/item/Bamboo.php +++ b/src/item/Bamboo.php @@ -32,7 +32,7 @@ final class Bamboo extends Item{ return 50; } - public function getBlock() : Block{ + public function getBlock(?int $clickedFace = null) : Block{ return VanillaBlocks::BAMBOO_SAPLING(); } } diff --git a/src/item/Banner.php b/src/item/Banner.php index 3a659fa081..1d0acf1df4 100644 --- a/src/item/Banner.php +++ b/src/item/Banner.php @@ -58,7 +58,7 @@ class Banner extends Item{ return $this->color; } - public function getBlock() : Block{ + public function getBlock(?int $clickedFace = null) : Block{ return VanillaBlocks::BANNER(); } diff --git a/src/item/Bed.php b/src/item/Bed.php index 9c286de5a4..887ff6130a 100644 --- a/src/item/Bed.php +++ b/src/item/Bed.php @@ -41,7 +41,7 @@ class Bed extends Item{ return $this->color; } - public function getBlock() : Block{ + public function getBlock(?int $clickedFace = null) : Block{ return VanillaBlocks::BED(); } diff --git a/src/item/BeetrootSeeds.php b/src/item/BeetrootSeeds.php index 2ef2250da6..e85d2cace0 100644 --- a/src/item/BeetrootSeeds.php +++ b/src/item/BeetrootSeeds.php @@ -28,7 +28,7 @@ use pocketmine\block\VanillaBlocks; class BeetrootSeeds extends Item{ - public function getBlock() : Block{ + public function getBlock(?int $clickedFace = null) : Block{ return VanillaBlocks::BEETROOTS(); } } diff --git a/src/item/Carrot.php b/src/item/Carrot.php index ec5d476996..75782ae490 100644 --- a/src/item/Carrot.php +++ b/src/item/Carrot.php @@ -28,7 +28,7 @@ use pocketmine\block\VanillaBlocks; class Carrot extends Food{ - public function getBlock() : Block{ + public function getBlock(?int $clickedFace = null) : Block{ return VanillaBlocks::CARROTS(); } diff --git a/src/item/CocoaBeans.php b/src/item/CocoaBeans.php index bd6ac2d1c1..d0659a28b9 100644 --- a/src/item/CocoaBeans.php +++ b/src/item/CocoaBeans.php @@ -28,7 +28,7 @@ use pocketmine\block\VanillaBlocks; class CocoaBeans extends Item{ - public function getBlock() : Block{ + public function getBlock(?int $clickedFace = null) : Block{ return VanillaBlocks::COCOA_POD(); } } diff --git a/src/item/Item.php b/src/item/Item.php index d58089201f..7cbbddb543 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -426,7 +426,7 @@ class Item implements \JsonSerializable{ /** * Returns the block corresponding to this Item. */ - public function getBlock() : Block{ + public function getBlock(?int $clickedFace = null) : Block{ return VanillaBlocks::AIR(); } diff --git a/src/item/ItemBlock.php b/src/item/ItemBlock.php index 2ee5d138ce..8c8cfcd04d 100644 --- a/src/item/ItemBlock.php +++ b/src/item/ItemBlock.php @@ -48,7 +48,7 @@ class ItemBlock extends Item{ parent::__construct($identifier, $this->getBlock()->getName()); } - public function getBlock() : Block{ + public function getBlock(?int $clickedFace = null) : Block{ return BlockFactory::getInstance()->get($this->blockId, $this->blockMeta); } diff --git a/src/item/ItemBlockWallOrFloor.php b/src/item/ItemBlockWallOrFloor.php index 763d60e03a..fa157c61a2 100644 --- a/src/item/ItemBlockWallOrFloor.php +++ b/src/item/ItemBlockWallOrFloor.php @@ -23,6 +23,32 @@ declare(strict_types=1); namespace pocketmine\item; -final class ItemBlockWallOrFloor{ +use pocketmine\block\Block; +use pocketmine\block\BlockFactory; +use pocketmine\math\Axis; +use pocketmine\math\Facing; +class ItemBlockWallOrFloor extends Item{ + + /** @var int */ + private $floorVariant; + /** @var int */ + private $wallVariant; + + public function __construct(ItemIdentifier $identifier, Block $floorVariant, Block $wallVariant){ + parent::__construct($identifier, $floorVariant->getName()); + $this->floorVariant = $floorVariant->getFullId(); + $this->wallVariant = $wallVariant->getFullId(); + } + + public function getBlock(?int $clickedFace = null) : Block{ + if($clickedFace !== null && Facing::axis($clickedFace) !== Axis::Y){ + return BlockFactory::getInstance()->fromFullBlock($this->wallVariant); + } + return BlockFactory::getInstance()->fromFullBlock($this->floorVariant); + } + + public function getFuelTime() : int{ + return $this->getBlock()->getFuelTime(); + } } diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index ca49ee3dc3..99a9a854f5 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\DyeColor; @@ -232,12 +233,12 @@ class ItemFactory{ $this->register(new Redstone(new ItemIdentifier(ItemIds::REDSTONE, 0), "Redstone")); $this->register(new RottenFlesh(new ItemIdentifier(ItemIds::ROTTEN_FLESH, 0), "Rotten Flesh")); $this->register(new Shears(new ItemIdentifier(ItemIds::SHEARS, 0), "Shears")); - $this->register(new Sign(BlockLegacyIds::STANDING_SIGN, 0, new ItemIdentifier(ItemIds::SIGN, 0))); - $this->register(new Sign(BlockLegacyIds::SPRUCE_STANDING_SIGN, 0, new ItemIdentifier(ItemIds::SPRUCE_SIGN, 0))); - $this->register(new Sign(BlockLegacyIds::BIRCH_STANDING_SIGN, 0, new ItemIdentifier(ItemIds::BIRCH_SIGN, 0))); - $this->register(new Sign(BlockLegacyIds::JUNGLE_STANDING_SIGN, 0, new ItemIdentifier(ItemIds::JUNGLE_SIGN, 0))); - $this->register(new Sign(BlockLegacyIds::ACACIA_STANDING_SIGN, 0, new ItemIdentifier(ItemIds::ACACIA_SIGN, 0))); - $this->register(new Sign(BlockLegacyIds::DARKOAK_STANDING_SIGN, 0, new ItemIdentifier(ItemIds::DARKOAK_SIGN, 0))); + $this->register(new Sign(new ItemIdentifier(ItemIds::SIGN, 0), VanillaBlocks::OAK_SIGN(), VanillaBlocks::OAK_WALL_SIGN())); + $this->register(new Sign(new ItemIdentifier(ItemIds::SPRUCE_SIGN, 0), VanillaBlocks::SPRUCE_SIGN(), VanillaBlocks::SPRUCE_WALL_SIGN())); + $this->register(new Sign(new ItemIdentifier(ItemIds::BIRCH_SIGN, 0), VanillaBlocks::BIRCH_SIGN(), VanillaBlocks::BIRCH_WALL_SIGN())); + $this->register(new Sign(new ItemIdentifier(ItemIds::JUNGLE_SIGN, 0), VanillaBlocks::JUNGLE_SIGN(), VanillaBlocks::JUNGLE_WALL_SIGN())); + $this->register(new Sign(new ItemIdentifier(ItemIds::ACACIA_SIGN, 0), VanillaBlocks::ACACIA_SIGN(), VanillaBlocks::ACACIA_WALL_SIGN())); + $this->register(new Sign(new ItemIdentifier(ItemIds::DARKOAK_SIGN, 0), VanillaBlocks::DARK_OAK_SIGN(), VanillaBlocks::DARK_OAK_WALL_SIGN())); $this->register(new Snowball(new ItemIdentifier(ItemIds::SNOWBALL, 0), "Snowball")); $this->register(new SpiderEye(new ItemIdentifier(ItemIds::SPIDER_EYE, 0), "Spider Eye")); $this->register(new Steak(new ItemIdentifier(ItemIds::STEAK, 0), "Steak")); diff --git a/src/item/MelonSeeds.php b/src/item/MelonSeeds.php index ee397fdba2..c475673a6e 100644 --- a/src/item/MelonSeeds.php +++ b/src/item/MelonSeeds.php @@ -28,7 +28,7 @@ use pocketmine\block\VanillaBlocks; class MelonSeeds extends Item{ - public function getBlock() : Block{ + public function getBlock(?int $clickedFace = null) : Block{ return VanillaBlocks::MELON_STEM(); } } diff --git a/src/item/Potato.php b/src/item/Potato.php index f5bae0227d..d4aff32fe8 100644 --- a/src/item/Potato.php +++ b/src/item/Potato.php @@ -28,7 +28,7 @@ use pocketmine\block\VanillaBlocks; class Potato extends Food{ - public function getBlock() : Block{ + public function getBlock(?int $clickedFace = null) : Block{ return VanillaBlocks::POTATOES(); } diff --git a/src/item/PumpkinSeeds.php b/src/item/PumpkinSeeds.php index f192ba90be..561355419c 100644 --- a/src/item/PumpkinSeeds.php +++ b/src/item/PumpkinSeeds.php @@ -28,7 +28,7 @@ use pocketmine\block\VanillaBlocks; class PumpkinSeeds extends Item{ - public function getBlock() : Block{ + public function getBlock(?int $clickedFace = null) : Block{ return VanillaBlocks::PUMPKIN_STEM(); } } diff --git a/src/item/Redstone.php b/src/item/Redstone.php index b4b5d0a975..1a4107d9a0 100644 --- a/src/item/Redstone.php +++ b/src/item/Redstone.php @@ -28,7 +28,7 @@ use pocketmine\block\VanillaBlocks; class Redstone extends Item{ - public function getBlock() : Block{ + public function getBlock(?int $clickedFace = null) : Block{ return VanillaBlocks::REDSTONE_WIRE(); } } diff --git a/src/item/Sign.php b/src/item/Sign.php index 69aa82aabb..f95240e371 100644 --- a/src/item/Sign.php +++ b/src/item/Sign.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\item; -class Sign extends ItemBlock{ +class Sign extends ItemBlockWallOrFloor{ public function getMaxStackSize() : int{ return 16; diff --git a/src/item/Skull.php b/src/item/Skull.php index 700d13039e..77f4b5f9ac 100644 --- a/src/item/Skull.php +++ b/src/item/Skull.php @@ -37,7 +37,7 @@ class Skull extends Item{ $this->skullType = $skullType; } - public function getBlock() : Block{ + public function getBlock(?int $clickedFace = null) : Block{ return VanillaBlocks::MOB_HEAD(); } diff --git a/src/item/StringItem.php b/src/item/StringItem.php index 366adfd12e..2ebcae63bb 100644 --- a/src/item/StringItem.php +++ b/src/item/StringItem.php @@ -28,7 +28,7 @@ use pocketmine\block\VanillaBlocks; class StringItem extends Item{ - public function getBlock() : Block{ + public function getBlock(?int $clickedFace = null) : Block{ return VanillaBlocks::TRIPWIRE(); } } diff --git a/src/item/WheatSeeds.php b/src/item/WheatSeeds.php index 0a2478aeff..72196e2345 100644 --- a/src/item/WheatSeeds.php +++ b/src/item/WheatSeeds.php @@ -28,7 +28,7 @@ use pocketmine\block\VanillaBlocks; class WheatSeeds extends Item{ - public function getBlock() : Block{ + public function getBlock(?int $clickedFace = null) : Block{ return VanillaBlocks::WHEAT(); } } diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 4641218ca1..61cda4ba30 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\handler; use pocketmine\block\BlockLegacyIds; use pocketmine\block\ItemFrame; -use pocketmine\block\Sign; +use pocketmine\block\BaseSign; use pocketmine\block\utils\SignText; use pocketmine\entity\animation\ConsumingItemAnimation; use pocketmine\entity\InvalidSkinException; @@ -606,7 +606,7 @@ class InGamePacketHandler extends PacketHandler{ $nbt = $packet->namedtag->getRoot(); if(!($nbt instanceof CompoundTag)) throw new AssumptionFailedError("PHPStan should ensure this is a CompoundTag"); //for phpstorm's benefit - if($block instanceof Sign){ + if($block instanceof BaseSign){ if(($textBlobTag = $nbt->getTag("Text")) instanceof StringTag){ try{ $text = SignText::fromBlob($textBlobTag->getValue()); diff --git a/src/world/World.php b/src/world/World.php index 8620a55b46..f649a27d7b 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1561,7 +1561,7 @@ class World implements ChunkManager{ } if($item->canBePlaced()){ - $hand = $item->getBlock(); + $hand = $item->getBlock($face); $hand->position($this, $blockReplace->getPos()->x, $blockReplace->getPos()->y, $blockReplace->getPos()->z); }else{ return false; diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 26ed5c79e4..81da2ef3c8 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Sign","1090":"Oak Sign","1091":"Oak Sign","1092":"Oak Sign","1093":"Oak Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Sign","6994":"Spruce Sign","6995":"Spruce Sign","6996":"Spruce Sign","6997":"Spruce Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Sign","7074":"Birch Sign","7075":"Birch Sign","7076":"Birch Sign","7077":"Birch Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Sign","7106":"Jungle Sign","7107":"Jungle Sign","7108":"Jungle Sign","7109":"Jungle Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Sign","7138":"Acacia Sign","7139":"Acacia Sign","7140":"Acacia Sign","7141":"Acacia Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Sign","7170":"Dark Oak Sign","7171":"Dark Oak Sign","7172":"Dark Oak Sign","7173":"Dark Oak Sign","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From 7ef794d725e45031787edd2e124bda61746b8e03 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 4 Oct 2020 18:22:07 +0100 Subject: [PATCH 1910/3224] imports cleanup --- src/block/BaseSign.php | 6 ------ src/block/BlockLegacyIdHelper.php | 1 - src/network/mcpe/handler/InGamePacketHandler.php | 2 +- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/block/BaseSign.php b/src/block/BaseSign.php index a2b0ffc96d..a1d2d69449 100644 --- a/src/block/BaseSign.php +++ b/src/block/BaseSign.php @@ -24,19 +24,13 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\tile\Sign as TileSign; -use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\SignText; use pocketmine\event\block\SignChangeEvent; -use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Facing; -use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\utils\TextFormat; -use pocketmine\world\BlockTransaction; use function array_map; use function assert; -use function floor; use function strlen; abstract class BaseSign extends Transparent{ diff --git a/src/block/BlockLegacyIdHelper.php b/src/block/BlockLegacyIdHelper.php index ec37e6ae84..3bd806b146 100644 --- a/src/block/BlockLegacyIdHelper.php +++ b/src/block/BlockLegacyIdHelper.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\BlockIdentifier as BID; -use pocketmine\block\BlockIdentifierFlattened as BIDFlattened; use pocketmine\block\BlockLegacyIds as Ids; use pocketmine\block\tile\Sign as TileSign; use pocketmine\block\utils\DyeColor; diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 61cda4ba30..4f5498486e 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; +use pocketmine\block\BaseSign; use pocketmine\block\BlockLegacyIds; use pocketmine\block\ItemFrame; -use pocketmine\block\BaseSign; use pocketmine\block\utils\SignText; use pocketmine\entity\animation\ConsumingItemAnimation; use pocketmine\entity\InvalidSkinException; From c42a6d7552de8e56bce4a7a629050d2dd7942765 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 4 Oct 2020 18:27:20 +0100 Subject: [PATCH 1911/3224] ItemBlock no longer depends on legacy ID/metadata --- src/item/ItemBlock.php | 20 +++++--------------- src/item/ItemFactory.php | 36 +++++++++++++++++------------------- 2 files changed, 22 insertions(+), 34 deletions(-) diff --git a/src/item/ItemBlock.php b/src/item/ItemBlock.php index 8c8cfcd04d..4e3941429d 100644 --- a/src/item/ItemBlock.php +++ b/src/item/ItemBlock.php @@ -31,25 +31,15 @@ use pocketmine\block\BlockFactory; */ class ItemBlock extends Item{ /** @var int */ - protected $blockId; - /** @var int */ - protected $blockMeta; + private $blockFullId; - /** - * @param int $blockMeta usually 0-15 (placed blocks may only have meta values 0-15) - */ - public function __construct(int $blockId, int $blockMeta, ItemIdentifier $identifier){ - if($blockMeta < 0 || $blockMeta > 15){ - throw new \InvalidArgumentException("Block meta value may only be between 0 and 15"); - } - $this->blockId = $blockId; - $this->blockMeta = $blockMeta; - - parent::__construct($identifier, $this->getBlock()->getName()); + public function __construct(ItemIdentifier $identifier, Block $block){ + parent::__construct($identifier, $block->getName()); + $this->blockFullId = $block->getFullId(); } public function getBlock(?int $clickedFace = null) : Block{ - return BlockFactory::getInstance()->get($this->blockId, $this->blockMeta); + return BlockFactory::getInstance()->fromFullBlock($this->blockFullId); } public function getFuelTime() : int{ diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 99a9a854f5..2d4df058a4 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -25,7 +25,6 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; -use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\RecordType; use pocketmine\block\utils\SkullType; @@ -178,23 +177,22 @@ class ItemFactory{ $this->register(new Item(new ItemIdentifier(ItemIds::SUGAR, 0), "Sugar")); $this->register(new Item(new ItemIdentifier(ItemIds::TURTLE_SHELL_PIECE, 0), "Scute")); $this->register(new Item(new ItemIdentifier(ItemIds::WHEAT, 0), "Wheat")); - $this->register(new ItemBlock(BlockLegacyIds::ACACIA_DOOR_BLOCK, 0, new ItemIdentifier(ItemIds::ACACIA_DOOR, 0))); - $this->register(new ItemBlock(BlockLegacyIds::BIRCH_DOOR_BLOCK, 0, new ItemIdentifier(ItemIds::BIRCH_DOOR, 0))); - $this->register(new ItemBlock(BlockLegacyIds::BREWING_STAND_BLOCK, 0, new ItemIdentifier(ItemIds::BREWING_STAND, 0))); - $this->register(new ItemBlock(BlockLegacyIds::CAKE_BLOCK, 0, new ItemIdentifier(ItemIds::CAKE, 0))); - $this->register(new ItemBlock(BlockLegacyIds::CAULDRON_BLOCK, 0, new ItemIdentifier(ItemIds::CAULDRON, 0))); - $this->register(new ItemBlock(BlockLegacyIds::COMPARATOR_BLOCK, 0, new ItemIdentifier(ItemIds::COMPARATOR, 0))); - $this->register(new ItemBlock(BlockLegacyIds::DARK_OAK_DOOR_BLOCK, 0, new ItemIdentifier(ItemIds::DARK_OAK_DOOR, 0))); - $this->register(new ItemBlock(BlockLegacyIds::FLOWER_POT_BLOCK, 0, new ItemIdentifier(ItemIds::FLOWER_POT, 0))); - $this->register(new ItemBlock(BlockLegacyIds::HOPPER_BLOCK, 0, new ItemIdentifier(ItemIds::HOPPER, 0))); - $this->register(new ItemBlock(BlockLegacyIds::IRON_DOOR_BLOCK, 0, new ItemIdentifier(ItemIds::IRON_DOOR, 0))); - $this->register(new ItemBlock(BlockLegacyIds::ITEM_FRAME_BLOCK, 0, new ItemIdentifier(ItemIds::ITEM_FRAME, 0))); - $this->register(new ItemBlock(BlockLegacyIds::JUNGLE_DOOR_BLOCK, 0, new ItemIdentifier(ItemIds::JUNGLE_DOOR, 0))); - $this->register(new ItemBlock(BlockLegacyIds::NETHER_WART_PLANT, 0, new ItemIdentifier(ItemIds::NETHER_WART, 0))); - $this->register(new ItemBlock(BlockLegacyIds::OAK_DOOR_BLOCK, 0, new ItemIdentifier(ItemIds::OAK_DOOR, 0))); - $this->register(new ItemBlock(BlockLegacyIds::REPEATER_BLOCK, 0, new ItemIdentifier(ItemIds::REPEATER, 0))); - $this->register(new ItemBlock(BlockLegacyIds::SPRUCE_DOOR_BLOCK, 0, new ItemIdentifier(ItemIds::SPRUCE_DOOR, 0))); - $this->register(new ItemBlock(BlockLegacyIds::SUGARCANE_BLOCK, 0, new ItemIdentifier(ItemIds::SUGARCANE, 0))); + $this->register(new ItemBlock(new ItemIdentifier(ItemIds::ACACIA_DOOR, 0), VanillaBlocks::ACACIA_DOOR())); + $this->register(new ItemBlock(new ItemIdentifier(ItemIds::BIRCH_DOOR, 0), VanillaBlocks::BIRCH_DOOR())); + $this->register(new ItemBlock(new ItemIdentifier(ItemIds::BREWING_STAND, 0), VanillaBlocks::BREWING_STAND())); + $this->register(new ItemBlock(new ItemIdentifier(ItemIds::CAKE, 0), VanillaBlocks::CAKE())); + $this->register(new ItemBlock(new ItemIdentifier(ItemIds::COMPARATOR, 0), VanillaBlocks::REDSTONE_COMPARATOR())); + $this->register(new ItemBlock(new ItemIdentifier(ItemIds::DARK_OAK_DOOR, 0), VanillaBlocks::DARK_OAK_DOOR())); + $this->register(new ItemBlock(new ItemIdentifier(ItemIds::FLOWER_POT, 0), VanillaBlocks::FLOWER_POT())); + $this->register(new ItemBlock(new ItemIdentifier(ItemIds::HOPPER, 0), VanillaBlocks::HOPPER())); + $this->register(new ItemBlock(new ItemIdentifier(ItemIds::IRON_DOOR, 0), VanillaBlocks::IRON_DOOR())); + $this->register(new ItemBlock(new ItemIdentifier(ItemIds::ITEM_FRAME, 0), VanillaBlocks::ITEM_FRAME())); + $this->register(new ItemBlock(new ItemIdentifier(ItemIds::JUNGLE_DOOR, 0), VanillaBlocks::JUNGLE_DOOR())); + $this->register(new ItemBlock(new ItemIdentifier(ItemIds::NETHER_WART, 0), VanillaBlocks::NETHER_WART())); + $this->register(new ItemBlock(new ItemIdentifier(ItemIds::OAK_DOOR, 0), VanillaBlocks::OAK_DOOR())); + $this->register(new ItemBlock(new ItemIdentifier(ItemIds::REPEATER, 0), VanillaBlocks::REDSTONE_REPEATER())); + $this->register(new ItemBlock(new ItemIdentifier(ItemIds::SPRUCE_DOOR, 0), VanillaBlocks::SPRUCE_DOOR())); + $this->register(new ItemBlock(new ItemIdentifier(ItemIds::SUGARCANE, 0), VanillaBlocks::SUGARCANE())); //TODO: fix metadata for buckets with still liquid in them //the meta values are intentionally hardcoded because block IDs will change in the future $this->register(new LiquidBucket(new ItemIdentifier(ItemIds::BUCKET, 8), "Water Bucket", VanillaBlocks::WATER())); @@ -433,7 +431,7 @@ class ItemFactory{ } }elseif($id < 256){ //intentionally includes negatives, for extended block IDs //TODO: do not assume that item IDs and block IDs are the same or related - $item = new ItemBlock($id < 0 ? 255 - $id : $id, $meta, new ItemIdentifier($id, $meta)); + $item = new ItemBlock(new ItemIdentifier($id, $meta), BlockFactory::getInstance()->get($id < 0 ? 255 - $id : $id, $meta & 0xf)); } } From 505d4e402f48d2cf2397aca2305cc4b8a5689e0c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 4 Oct 2020 18:36:46 +0100 Subject: [PATCH 1912/3224] ItemFactory: do not reuse the same itemstack instance for air() this is mutable, so it's possible for plugins to mess with it and break everything that references it. --- src/item/ItemFactory.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 2d4df058a4..80ea9810bf 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -52,9 +52,6 @@ class ItemFactory{ /** @var Item[] */ private $list = []; - /** @var Item|null */ - private static $air = null; - public function __construct(){ $this->registerArmorItems(); $this->registerSpawnEggs(); @@ -448,7 +445,7 @@ class ItemFactory{ } public static function air() : Item{ - return self::$air ?? (self::$air = self::getInstance()->get(ItemIds::AIR, 0, 0)); + return self::getInstance()->get(ItemIds::AIR, 0, 0); } /** From 7f9c4355f03b879e41e5ad75b83c36a53b58c561 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 4 Oct 2020 19:05:43 +0100 Subject: [PATCH 1913/3224] Revert back to floor/wall banner variants this code largely duplicates the same code in FloorSign/WallSign and needs to be de-duplicated. --- src/block/{Banner.php => BaseBanner.php} | 53 +++----------------- src/block/BlockFactory.php | 3 +- src/block/FloorBanner.php | 62 ++++++++++++++++++++++++ src/block/VanillaBlocks.php | 4 +- src/block/WallBanner.php | 61 +++++++++++++++++++++++ src/block/tile/Banner.php | 2 +- src/block/utils/BannerPattern.php | 4 +- src/item/Banner.php | 18 ++++--- src/item/ItemFactory.php | 6 ++- src/item/VanillaItems.php | 34 +------------ 10 files changed, 155 insertions(+), 92 deletions(-) rename src/block/{Banner.php => BaseBanner.php} (75%) create mode 100644 src/block/FloorBanner.php create mode 100644 src/block/WallBanner.php diff --git a/src/block/Banner.php b/src/block/BaseBanner.php similarity index 75% rename from src/block/Banner.php rename to src/block/BaseBanner.php index d160d430f5..dd5ac3f934 100644 --- a/src/block/Banner.php +++ b/src/block/BaseBanner.php @@ -41,18 +41,7 @@ use pocketmine\world\BlockTransaction; use function assert; use function floor; -class Banner extends Transparent{ - /** @var BlockIdentifierFlattened */ - protected $idInfo; - - //TODO: conditionally useless properties, find a way to fix - - /** @var int */ - protected $rotation = 0; - - /** @var int */ - protected $facing = Facing::UP; - +abstract class BaseBanner extends Transparent{ /** @var DyeColor */ protected $baseColor; @@ -62,7 +51,7 @@ class Banner extends Transparent{ */ protected $patterns; - public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0, BlockToolType::AXE)); $this->baseColor = DyeColor::BLACK(); $this->patterns = new Deque(); @@ -74,30 +63,6 @@ class Banner extends Transparent{ $this->patterns = $this->patterns->copy(); } - public function getId() : int{ - return $this->facing === Facing::UP ? parent::getId() : $this->idInfo->getSecondId(); - } - - protected function writeStateToMeta() : int{ - if($this->facing === Facing::UP){ - return $this->rotation; - } - return BlockDataSerializer::writeHorizontalFacing($this->facing); - } - - public function readStateFromData(int $id, int $stateMeta) : void{ - if($id === $this->idInfo->getSecondId()){ - $this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta); - }else{ - $this->facing = Facing::UP; - $this->rotation = $stateMeta; - } - } - - public function getStateBitmask() : int{ - return 0b1111; - } - public function readStateFromWorld() : void{ parent::readStateFromWorld(); $tile = $this->pos->getWorld()->getTile($this->pos); @@ -160,20 +125,14 @@ class Banner extends Transparent{ $this->baseColor = $item->getColor(); $this->setPatterns($item->getPatterns()); } - if($face !== Facing::DOWN){ - $this->facing = $face; - if($face === Facing::UP){ - $this->rotation = $player !== null ? ((int) floor((($player->getLocation()->getYaw() + 180) * 16 / 360) + 0.5)) & 0x0f : 0; - } - return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); - } - - return false; + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } + abstract protected function getSupportingFace() : int; + public function onNearbyBlockChange() : void{ - if($this->getSide(Facing::opposite($this->facing))->getId() === BlockLegacyIds::AIR){ + if($this->getSide($this->getSupportingFace())->getId() === BlockLegacyIds::AIR){ $this->pos->getWorld()->useBreakOn($this->pos); } } diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index c0d02d9319..bc2c34bb4e 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -104,7 +104,8 @@ class BlockFactory{ $this->register(new Anvil(new BID(Ids::ANVIL), "Anvil")); $this->register(new Bamboo(new BID(Ids::BAMBOO), "Bamboo", new BlockBreakInfo(2.0 /* 1.0 in PC */, BlockToolType::AXE))); $this->register(new BambooSapling(new BID(Ids::BAMBOO_SAPLING), "Bamboo Sapling", BlockBreakInfo::instant())); - $this->register(new Banner(new BIDFlattened(Ids::STANDING_BANNER, Ids::WALL_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Banner")); + $this->register(new FloorBanner(new BID(Ids::STANDING_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Banner")); + $this->register(new WallBanner(new BID(Ids::WALL_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Wall Banner")); $this->register(new Transparent(new BID(Ids::BARRIER), "Barrier", BlockBreakInfo::indestructible())); $this->register(new Beacon(new BID(Ids::BEACON, 0, null, TileBeacon::class), "Beacon", new BlockBreakInfo(3.0))); $this->register(new Bed(new BID(Ids::BED_BLOCK, 0, ItemIds::BED, TileBed::class), "Bed Block")); diff --git a/src/block/FloorBanner.php b/src/block/FloorBanner.php new file mode 100644 index 0000000000..06323009c2 --- /dev/null +++ b/src/block/FloorBanner.php @@ -0,0 +1,62 @@ +rotation = $stateMeta; + } + + protected function writeStateToMeta() : int{ + return $this->rotation; + } + + public function getStateBitmask() : int{ + return 0b1111; + } + + protected function getSupportingFace() : int{ + return Facing::DOWN; + } + + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($face !== Facing::UP){ + return false; + } + + if($player !== null){ + $this->rotation = ((int) floor((($player->getLocation()->getYaw() + 180) * 16 / 360) + 0.5)) & 0x0f; + } + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } +} diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 4634742015..bf5f10735e 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -57,7 +57,7 @@ use function assert; * @method static Flower AZURE_BLUET() * @method static Bamboo BAMBOO() * @method static BambooSapling BAMBOO_SAPLING() - * @method static Banner BANNER() + * @method static FloorBanner BANNER() * @method static Transparent BARRIER() * @method static Beacon BEACON() * @method static Bed BED() @@ -654,6 +654,7 @@ use function assert; * @method static TripwireHook TRIPWIRE_HOOK() * @method static UnderwaterTorch UNDERWATER_TORCH() * @method static Vine VINES() + * @method static WallBanner WALL_BANNER() * @method static Water WATER() * @method static WeightedPressurePlateHeavy WEIGHTED_PRESSURE_PLATE_HEAVY() * @method static WeightedPressurePlateLight WEIGHTED_PRESSURE_PLATE_LIGHT() @@ -1328,6 +1329,7 @@ final class VanillaBlocks{ self::register("tripwire_hook", $factory->get(131)); self::register("underwater_torch", $factory->get(239, 5)); self::register("vines", $factory->get(106)); + self::register("wall_banner", $factory->get(177, 2)); self::register("water", $factory->get(8)); self::register("weighted_pressure_plate_heavy", $factory->get(148)); self::register("weighted_pressure_plate_light", $factory->get(147)); diff --git a/src/block/WallBanner.php b/src/block/WallBanner.php new file mode 100644 index 0000000000..2ac473fb4d --- /dev/null +++ b/src/block/WallBanner.php @@ -0,0 +1,61 @@ +facing); + } + + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta); + } + + public function getStateBitmask() : int{ + return 0b111; + } + + protected function getSupportingFace() : int{ + return Facing::opposite($this->facing); + } + + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if(Facing::axis($face) === Axis::Y){ + return false; + } + $this->facing = $face; + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } +} diff --git a/src/block/tile/Banner.php b/src/block/tile/Banner.php index 7c00b98ba6..2ee93b2a4a 100644 --- a/src/block/tile/Banner.php +++ b/src/block/tile/Banner.php @@ -35,7 +35,7 @@ use pocketmine\world\World; /** * @deprecated - * @see \pocketmine\block\Banner + * @see \pocketmine\block\BaseBanner */ class Banner extends Spawnable{ diff --git a/src/block/utils/BannerPattern.php b/src/block/utils/BannerPattern.php index 5d77cde81e..f53cefbdc1 100644 --- a/src/block/utils/BannerPattern.php +++ b/src/block/utils/BannerPattern.php @@ -23,11 +23,11 @@ declare(strict_types=1); namespace pocketmine\block\utils; -use pocketmine\block\Banner; +use pocketmine\block\BaseBanner; /** * Contains information about a pattern layer on a banner. - * @see Banner + * @see BaseBanner */ class BannerPattern{ public const BORDER = "bo"; diff --git a/src/item/Banner.php b/src/item/Banner.php index 1d0acf1df4..a86adec2d4 100644 --- a/src/item/Banner.php +++ b/src/item/Banner.php @@ -33,7 +33,7 @@ use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; -class Banner extends Item{ +class Banner extends ItemBlockWallOrFloor{ public const TAG_PATTERNS = TileBanner::TAG_PATTERNS; public const TAG_PATTERN_COLOR = TileBanner::TAG_PATTERN_COLOR; public const TAG_PATTERN_NAME = TileBanner::TAG_PATTERN_NAME; @@ -47,9 +47,9 @@ class Banner extends Item{ */ private $patterns; - public function __construct(ItemIdentifier $identifier, string $name, DyeColor $color){ - parent::__construct($identifier, $name); - $this->color = $color; + public function __construct(ItemIdentifier $identifier, Block $floorVariant, Block $wallVariant){ + parent::__construct($identifier, $floorVariant, $wallVariant); + $this->color = DyeColor::BLACK(); $this->patterns = new Deque(); } @@ -58,8 +58,14 @@ class Banner extends Item{ return $this->color; } - public function getBlock(?int $clickedFace = null) : Block{ - return VanillaBlocks::BANNER(); + /** @return $this */ + public function setColor(DyeColor $color) : self{ + $this->color = $color; + return $this; + } + + public function getMeta() : int{ + return DyeColorIdMap::getInstance()->toInvertedId($this->color); } public function getMaxStackSize() : int{ diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 80ea9810bf..fca99016ab 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -260,7 +260,11 @@ class ItemFactory{ //TODO: add interface to dye-colour objects $this->register(new Dye(new ItemIdentifier(ItemIds::DYE, $dyeMap[$color->id()] ?? $colorIdMap->toInvertedId($color)), $color->getDisplayName() . " Dye", $color)); $this->register(new Bed(new ItemIdentifier(ItemIds::BED, $colorIdMap->toId($color)), $color->getDisplayName() . " Bed", $color)); - $this->register(new Banner(new ItemIdentifier(ItemIds::BANNER, $colorIdMap->toInvertedId($color)), $color->getDisplayName() . " Banner", $color)); + $this->register((new Banner( + new ItemIdentifier(ItemIds::BANNER, 0), + VanillaBlocks::BANNER(), + VanillaBlocks::WALL_BANNER() + ))->setColor($color)); } foreach(Potion::ALL as $type){ diff --git a/src/item/VanillaItems.php b/src/item/VanillaItems.php index ba5cd091c8..1ff4f944cf 100644 --- a/src/item/VanillaItems.php +++ b/src/item/VanillaItems.php @@ -30,7 +30,7 @@ use function assert; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see RegistryTrait::_generateMethodAnnotations() + * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * * @method static Boat ACACIA_BOAT() * @method static Apple APPLE() @@ -40,13 +40,11 @@ use function assert; * @method static BeetrootSeeds BEETROOT_SEEDS() * @method static BeetrootSoup BEETROOT_SOUP() * @method static Boat BIRCH_BOAT() - * @method static Banner BLACK_BANNER() * @method static Bed BLACK_BED() * @method static Dye BLACK_DYE() * @method static Item BLAZE_POWDER() * @method static BlazeRod BLAZE_ROD() * @method static Item BLEACH() - * @method static Banner BLUE_BANNER() * @method static Bed BLUE_BED() * @method static Dye BLUE_DYE() * @method static Item BONE() @@ -56,7 +54,6 @@ use function assert; * @method static Bowl BOWL() * @method static Bread BREAD() * @method static Item BRICK() - * @method static Banner BROWN_BANNER() * @method static Bed BROWN_BED() * @method static Dye BROWN_DYE() * @method static Bucket BUCKET() @@ -120,7 +117,6 @@ use function assert; * @method static CookedSalmon COOKED_SALMON() * @method static Cookie COOKIE() * @method static Skull CREEPER_HEAD() - * @method static Banner CYAN_BANNER() * @method static Bed CYAN_BED() * @method static Dye CYAN_DYE() * @method static Boat DARK_OAK_BOAT() @@ -164,10 +160,8 @@ use function assert; * @method static Pickaxe GOLDEN_PICKAXE() * @method static Shovel GOLDEN_SHOVEL() * @method static Sword GOLDEN_SWORD() - * @method static Banner GRAY_BANNER() * @method static Bed GRAY_BED() * @method static Dye GRAY_DYE() - * @method static Banner GREEN_BANNER() * @method static Bed GREEN_BED() * @method static Dye GREEN_DYE() * @method static Item GUNPOWDER() @@ -192,16 +186,12 @@ use function assert; * @method static Armor LEATHER_CAP() * @method static Armor LEATHER_PANTS() * @method static Armor LEATHER_TUNIC() - * @method static Banner LIGHT_BLUE_BANNER() * @method static Bed LIGHT_BLUE_BED() * @method static Dye LIGHT_BLUE_DYE() - * @method static Banner LIGHT_GRAY_BANNER() * @method static Bed LIGHT_GRAY_BED() * @method static Dye LIGHT_GRAY_DYE() - * @method static Banner LIME_BANNER() * @method static Bed LIME_BED() * @method static Dye LIME_DYE() - * @method static Banner MAGENTA_BANNER() * @method static Bed MAGENTA_BED() * @method static Dye MAGENTA_DYE() * @method static Item MAGMA_CREAM() @@ -216,12 +206,10 @@ use function assert; * @method static Item NETHER_STAR() * @method static ItemBlock NETHER_WART() * @method static Boat OAK_BOAT() - * @method static Banner ORANGE_BANNER() * @method static Bed ORANGE_BED() * @method static Dye ORANGE_DYE() * @method static PaintingItem PAINTING() * @method static Item PAPER() - * @method static Banner PINK_BANNER() * @method static Bed PINK_BED() * @method static Dye PINK_DYE() * @method static Skull PLAYER_HEAD() @@ -234,7 +222,6 @@ use function assert; * @method static Pufferfish PUFFERFISH() * @method static PumpkinPie PUMPKIN_PIE() * @method static PumpkinSeeds PUMPKIN_SEEDS() - * @method static Banner PURPLE_BANNER() * @method static Bed PURPLE_BED() * @method static Dye PURPLE_DYE() * @method static Item RABBIT_FOOT() @@ -259,7 +246,6 @@ use function assert; * @method static Record RECORD_STRAD() * @method static Record RECORD_WAIT() * @method static Record RECORD_WARD() - * @method static Banner RED_BANNER() * @method static Bed RED_BED() * @method static Dye RED_DYE() * @method static Redstone REDSTONE_DUST() @@ -287,7 +273,6 @@ use function assert; * @method static LiquidBucket WATER_BUCKET() * @method static Item WHEAT() * @method static WheatSeeds WHEAT_SEEDS() - * @method static Banner WHITE_BANNER() * @method static Bed WHITE_BED() * @method static Dye WHITE_DYE() * @method static Skull WITHER_SKELETON_SKULL() @@ -298,7 +283,6 @@ use function assert; * @method static Sword WOODEN_SWORD() * @method static WritableBook WRITABLE_BOOK() * @method static WrittenBook WRITTEN_BOOK() - * @method static Banner YELLOW_BANNER() * @method static Bed YELLOW_BED() * @method static Dye YELLOW_DYE() * @method static Skull ZOMBIE_HEAD() @@ -340,13 +324,11 @@ final class VanillaItems{ self::register("beetroot_seeds", $factory->get(458)); self::register("beetroot_soup", $factory->get(459)); self::register("birch_boat", $factory->get(333, 2)); - self::register("black_banner", $factory->get(446)); self::register("black_bed", $factory->get(355, 15)); self::register("black_dye", $factory->get(351, 16)); self::register("blaze_powder", $factory->get(377)); self::register("blaze_rod", $factory->get(369)); self::register("bleach", $factory->get(451)); - self::register("blue_banner", $factory->get(446, 4)); self::register("blue_bed", $factory->get(355, 11)); self::register("blue_dye", $factory->get(351, 18)); self::register("bone", $factory->get(352)); @@ -356,7 +338,6 @@ final class VanillaItems{ self::register("bowl", $factory->get(281)); self::register("bread", $factory->get(297)); self::register("brick", $factory->get(336)); - self::register("brown_banner", $factory->get(446, 3)); self::register("brown_bed", $factory->get(355, 12)); self::register("brown_dye", $factory->get(351, 17)); self::register("bucket", $factory->get(325)); @@ -420,7 +401,6 @@ final class VanillaItems{ self::register("cooked_salmon", $factory->get(463)); self::register("cookie", $factory->get(357)); self::register("creeper_head", $factory->get(397, 4)); - self::register("cyan_banner", $factory->get(446, 6)); self::register("cyan_bed", $factory->get(355, 9)); self::register("cyan_dye", $factory->get(351, 6)); self::register("dark_oak_boat", $factory->get(333, 5)); @@ -464,10 +444,8 @@ final class VanillaItems{ self::register("golden_pickaxe", $factory->get(285)); self::register("golden_shovel", $factory->get(284)); self::register("golden_sword", $factory->get(283)); - self::register("gray_banner", $factory->get(446, 8)); self::register("gray_bed", $factory->get(355, 7)); self::register("gray_dye", $factory->get(351, 8)); - self::register("green_banner", $factory->get(446, 2)); self::register("green_bed", $factory->get(355, 13)); self::register("green_dye", $factory->get(351, 2)); self::register("gunpowder", $factory->get(289)); @@ -492,16 +470,12 @@ final class VanillaItems{ self::register("leather_cap", $factory->get(298)); self::register("leather_pants", $factory->get(300)); self::register("leather_tunic", $factory->get(299)); - self::register("light_blue_banner", $factory->get(446, 12)); self::register("light_blue_bed", $factory->get(355, 3)); self::register("light_blue_dye", $factory->get(351, 12)); - self::register("light_gray_banner", $factory->get(446, 7)); self::register("light_gray_bed", $factory->get(355, 8)); self::register("light_gray_dye", $factory->get(351, 7)); - self::register("lime_banner", $factory->get(446, 10)); self::register("lime_bed", $factory->get(355, 5)); self::register("lime_dye", $factory->get(351, 10)); - self::register("magenta_banner", $factory->get(446, 13)); self::register("magenta_bed", $factory->get(355, 2)); self::register("magenta_dye", $factory->get(351, 13)); self::register("magma_cream", $factory->get(378)); @@ -516,12 +490,10 @@ final class VanillaItems{ self::register("nether_star", $factory->get(399)); self::register("nether_wart", $factory->get(372)); self::register("oak_boat", $factory->get(333)); - self::register("orange_banner", $factory->get(446, 14)); self::register("orange_bed", $factory->get(355, 1)); self::register("orange_dye", $factory->get(351, 14)); self::register("painting", $factory->get(321)); self::register("paper", $factory->get(339)); - self::register("pink_banner", $factory->get(446, 9)); self::register("pink_bed", $factory->get(355, 6)); self::register("pink_dye", $factory->get(351, 9)); self::register("player_head", $factory->get(397, 3)); @@ -534,7 +506,6 @@ final class VanillaItems{ self::register("pufferfish", $factory->get(462)); self::register("pumpkin_pie", $factory->get(400)); self::register("pumpkin_seeds", $factory->get(361)); - self::register("purple_banner", $factory->get(446, 5)); self::register("purple_bed", $factory->get(355, 10)); self::register("purple_dye", $factory->get(351, 5)); self::register("rabbit_foot", $factory->get(414)); @@ -559,7 +530,6 @@ final class VanillaItems{ self::register("record_strad", $factory->get(508)); self::register("record_wait", $factory->get(511)); self::register("record_ward", $factory->get(509)); - self::register("red_banner", $factory->get(446, 1)); self::register("red_bed", $factory->get(355, 14)); self::register("red_dye", $factory->get(351, 1)); self::register("redstone_dust", $factory->get(331)); @@ -587,7 +557,6 @@ final class VanillaItems{ self::register("water_bucket", $factory->get(325, 8)); self::register("wheat", $factory->get(296)); self::register("wheat_seeds", $factory->get(295)); - self::register("white_banner", $factory->get(446, 15)); self::register("white_bed", $factory->get(355)); self::register("white_dye", $factory->get(351, 19)); self::register("wither_skeleton_skull", $factory->get(397, 1)); @@ -598,7 +567,6 @@ final class VanillaItems{ self::register("wooden_sword", $factory->get(268)); self::register("writable_book", $factory->get(386)); self::register("written_book", $factory->get(387)); - self::register("yellow_banner", $factory->get(446, 11)); self::register("yellow_bed", $factory->get(355, 4)); self::register("yellow_dye", $factory->get(351, 11)); self::register("zombie_head", $factory->get(397, 2)); From 6fb45de405525bd5bf5639c9cbeb66bd1c4735cb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 4 Oct 2020 19:12:04 +0100 Subject: [PATCH 1914/3224] fixed phpstan baseline --- tests/phpstan/configs/runtime-type-checks.neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpstan/configs/runtime-type-checks.neon b/tests/phpstan/configs/runtime-type-checks.neon index dc7695d48b..023d06b897 100644 --- a/tests/phpstan/configs/runtime-type-checks.neon +++ b/tests/phpstan/configs/runtime-type-checks.neon @@ -3,7 +3,7 @@ parameters: - message: "#^Instanceof between pocketmine\\\\block\\\\utils\\\\BannerPattern and pocketmine\\\\block\\\\utils\\\\BannerPattern will always evaluate to true\\.$#" count: 1 - path: ../../../src/block/Banner.php + path: ../../../src/block/BaseBanner.php - message: "#^Call to function assert\\(\\) with bool will always evaluate to true\\.$#" From 309d23acfbb2363834f8d371298110485b0de4e1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 4 Oct 2020 19:12:36 +0100 Subject: [PATCH 1915/3224] regenerated blockfactory consistency check --- tests/phpunit/block/block_factory_consistency_check.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 81da2ef3c8..6ce444bc87 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Banner","2834":"Banner","2835":"Banner","2836":"Banner","2837":"Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From fc1084d65cbcb00ba47df202f22cb84649a0e5ab Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 4 Oct 2020 19:42:29 +0100 Subject: [PATCH 1916/3224] Sponge: fixed wet/dry state not persisting in inventory --- src/block/Sponge.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/block/Sponge.php b/src/block/Sponge.php index 486fbff28c..a1328ab69a 100644 --- a/src/block/Sponge.php +++ b/src/block/Sponge.php @@ -43,4 +43,8 @@ class Sponge extends Opaque{ public function getStateBitmask() : int{ return 0b1; } + + public function getNonPersistentStateBitmask() : int{ + return 0; + } } From dfee8b7fa589e2860a9743a6a2252df78b1d07af Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 4 Oct 2020 21:09:45 +0100 Subject: [PATCH 1917/3224] Added SignLikeRotationTrait --- src/block/FloorBanner.php | 6 +-- src/block/FloorSign.php | 7 ++-- src/block/utils/SignLikeRotationTrait.php | 46 +++++++++++++++++++++++ 3 files changed, 52 insertions(+), 7 deletions(-) create mode 100644 src/block/utils/SignLikeRotationTrait.php diff --git a/src/block/FloorBanner.php b/src/block/FloorBanner.php index 06323009c2..466bce5cb8 100644 --- a/src/block/FloorBanner.php +++ b/src/block/FloorBanner.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\SignLikeRotationTrait; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -30,8 +31,7 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; final class FloorBanner extends BaseBanner{ - /** @var int */ - protected $rotation = 0; + use SignLikeRotationTrait; public function readStateFromData(int $id, int $stateMeta) : void{ $this->rotation = $stateMeta; @@ -55,7 +55,7 @@ final class FloorBanner extends BaseBanner{ } if($player !== null){ - $this->rotation = ((int) floor((($player->getLocation()->getYaw() + 180) * 16 / 360) + 0.5)) & 0x0f; + $this->rotation = self::getRotationFromYaw($player->getLocation()->getYaw()); } return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/block/FloorSign.php b/src/block/FloorSign.php index 4544afeed9..7ee4880dd3 100644 --- a/src/block/FloorSign.php +++ b/src/block/FloorSign.php @@ -23,16 +23,15 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\SignLikeRotationTrait; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\world\BlockTransaction; -use function floor; final class FloorSign extends BaseSign{ - /** @var int */ - protected $rotation = 0; + use SignLikeRotationTrait; public function readStateFromData(int $id, int $stateMeta) : void{ $this->rotation = $stateMeta; @@ -56,7 +55,7 @@ final class FloorSign extends BaseSign{ } if($player !== null){ - $this->rotation = ((int) floor((($player->getLocation()->getYaw() + 180) * 16 / 360) + 0.5)) & 0x0f; + $this->rotation = self::getRotationFromYaw($player->getLocation()->getYaw()); } return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/block/utils/SignLikeRotationTrait.php b/src/block/utils/SignLikeRotationTrait.php new file mode 100644 index 0000000000..fd09a824f2 --- /dev/null +++ b/src/block/utils/SignLikeRotationTrait.php @@ -0,0 +1,46 @@ +rotation; } + + /** @return $this */ + public function setRotation(int $rotation) : self{ + if($rotation < 0 || $rotation > 15){ + throw new \InvalidArgumentException("Rotation must be in range 0-15"); + } + $this->rotation = $rotation; + return $this; + } + + private static function getRotationFromYaw(float $yaw) : int{ + return ((int) floor((($yaw + 180) * 16 / 360) + 0.5)) & 0xf; + } +} From e39d2c46217b9e5fb4b77777654833127a2fbf7e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 6 Oct 2020 13:40:49 +0100 Subject: [PATCH 1918/3224] Beacon: fixed crash in PC worlds --- src/block/tile/Beacon.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/block/tile/Beacon.php b/src/block/tile/Beacon.php index c2bb605f06..4d4b8cf6d6 100644 --- a/src/block/tile/Beacon.php +++ b/src/block/tile/Beacon.php @@ -41,8 +41,8 @@ final class Beacon extends Spawnable{ public function readSaveData(CompoundTag $nbt) : void{ //TODO: PC uses Primary and Secondary (capitalized first letter), we don't read them here because the IDs would be different - $this->primaryEffect = $nbt->getInt(self::TAG_PRIMARY); - $this->secondaryEffect = $nbt->getInt(self::TAG_SECONDARY); + $this->primaryEffect = $nbt->getInt(self::TAG_PRIMARY, 0); + $this->secondaryEffect = $nbt->getInt(self::TAG_SECONDARY, 0); } protected function writeSaveData(CompoundTag $nbt) : void{ From 78bddac823d4ac519e9b35d1418a9482607b785c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 6 Oct 2020 14:00:23 +0100 Subject: [PATCH 1919/3224] Player: remove removeFormat, chat formatting is now unconditionally available This change was made after exploring turning this into a permission. It occurred to me that this feature is entirely superfluous because it's non-vanilla, can be done by plugins, and is usually considered as a bug. In addition, disabling this behaviour required third party code just for this one thing because it was not able to be managed by a permissions plugin. Instead, it's better to produce a plugin which implements this behaviour if it's desired, by making use of SignChangeEvent and PlayerChatEvent/PlayerCommandPreprocessEvent. close #3856, close #2288 --- src/block/BaseSign.php | 5 ++--- src/player/Player.php | 15 +-------------- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/src/block/BaseSign.php b/src/block/BaseSign.php index a1d2d69449..1709e4a8a6 100644 --- a/src/block/BaseSign.php +++ b/src/block/BaseSign.php @@ -105,9 +105,8 @@ abstract class BaseSign extends Transparent{ if($size > 1000){ throw new \UnexpectedValueException($author->getName() . " tried to write $size bytes of text onto a sign (bigger than max 1000)"); } - $removeFormat = $author->getRemoveFormat(); - $ev = new SignChangeEvent($this, $author, new SignText(array_map(function(string $line) use ($removeFormat) : string{ - return TextFormat::clean($line, $removeFormat); + $ev = new SignChangeEvent($this, $author, new SignText(array_map(function(string $line) : string{ + return TextFormat::clean($line, false); }, $text->getLines()))); $ev->call(); if(!$ev->isCancelled()){ diff --git a/src/player/Player.php b/src/player/Player.php index fd9d64800f..5b8cd628e3 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -183,8 +183,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ /** @var int */ protected $messageCounter = 2; - /** @var bool */ - protected $removeFormat = true; /** @var int */ protected $firstPlayed; @@ -345,9 +343,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } $this->keepMovement = true; - if($this->isOp()){ - $this->setRemoveFormat(false); - } $this->setNameTagVisible(); $this->setNameTagAlwaysVisible(); @@ -485,14 +480,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return $this->server; } - public function getRemoveFormat() : bool{ - return $this->removeFormat; - } - - public function setRemoveFormat(bool $remove = true) : void{ - $this->removeFormat = $remove; - } - public function getScreenLineHeight() : int{ return $this->lineHeight ?? 7; } @@ -1370,7 +1357,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ public function chat(string $message) : bool{ $this->doCloseInventory(); - $message = TextFormat::clean($message, $this->removeFormat); + $message = TextFormat::clean($message, false); foreach(explode("\n", $message) as $messagePart){ if(trim($messagePart) !== "" and strlen($messagePart) <= 255 and $this->messageCounter-- > 0){ if(strpos($messagePart, './') === 0){ From b172c93e45e60ee3dbfd8a2efbede60b894673a3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 6 Oct 2020 17:27:17 +0100 Subject: [PATCH 1920/3224] World: do not group broadcasted packets by chunk, broadcast directly instead Grouping packets to batch by chunk instead of by player reduces bandwidth efficiency, because the number of active chunks is almost always larger than the number of active players. With the old mechanism, a batch of packets for each active chunk (which could be dozens, or hundreds... or thousands) would be created once, and then sent to many players. This makes the compression load factor O(nActiveChunks). Broadcasting directly is simpler and changes the load factor to O(nActivePlayers), which usually means a smaller number of larger batches are created, achieving better compression ratios for approximately the same cost (the same amount of data is being compressed, just in a different way). --- src/world/World.php | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index f649a27d7b..02c11558cf 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -172,9 +172,6 @@ class World implements ChunkManager{ /** @var Player[][] */ private $playerChunkListeners = []; - /** @var ClientboundPacket[][] */ - private $chunkPackets = []; - /** @var float[] */ private $unloadQueue = []; @@ -525,11 +522,7 @@ class World implements ChunkManager{ * Broadcasts a packet to every player who has the target position within their view distance. */ public function broadcastPacketToViewers(Vector3 $pos, ClientboundPacket $packet) : void{ - if(!isset($this->chunkPackets[$index = World::chunkHash($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4)])){ - $this->chunkPackets[$index] = [$packet]; - }else{ - $this->chunkPackets[$index][] = $packet; - } + $this->server->broadcastPackets($this->getChunkPlayers($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4), [$packet]); } public function registerChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ, bool $autoLoad = true) : void{ @@ -775,16 +768,6 @@ class World implements ChunkManager{ if($this->sleepTicks > 0 and --$this->sleepTicks <= 0){ $this->checkSleep(); } - - foreach($this->chunkPackets as $index => $entries){ - World::getXZ($index, $chunkX, $chunkZ); - $chunkPlayers = $this->getChunkPlayers($chunkX, $chunkZ); - if(count($chunkPlayers) > 0){ - $this->server->broadcastPackets($chunkPlayers, $entries); - } - } - - $this->chunkPackets = []; } public function checkSleep() : void{ From 49d611168f22e2878a088e7f4f7316ad18ffdb58 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 6 Oct 2020 17:54:44 +0100 Subject: [PATCH 1921/3224] Player: fix documented type of disconnect $quitMessage --- src/player/Player.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 5b8cd628e3..73c9a97de4 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1950,8 +1950,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ * Note for plugin developers: Prefer kick() instead of this method. * That way other plugins can have a say in whether the player is removed or not. * - * @param string $reason Shown to the player, usually this will appear on their disconnect screen. - * @param TranslationContainer|string $quitMessage Message to broadcast to online players (null will use default) + * @param string $reason Shown to the player, usually this will appear on their disconnect screen. + * @param TranslationContainer|string|null $quitMessage Message to broadcast to online players (null will use default) */ public function disconnect(string $reason, $quitMessage = null, bool $notify = true) : void{ if(!$this->isConnected()){ From 945a2598b741726c11cd6cc611f6d38b47f366c4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 6 Oct 2020 17:55:32 +0100 Subject: [PATCH 1922/3224] Player: fix documented type of kick $quitMessage --- src/player/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index 73c9a97de4..5ffe4fffbf 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1925,7 +1925,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ /** * Kicks a player from the server * - * @param TranslationContainer|string $quitMessage + * @param TranslationContainer|string|null $quitMessage */ public function kick(string $reason = "", $quitMessage = null) : bool{ $ev = new PlayerKickEvent($this, $reason, $quitMessage ?? $this->getLeaveMessage()); From 15eac8a65acc8b001d079190840a092c255a5718 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 6 Oct 2020 18:06:48 +0100 Subject: [PATCH 1923/3224] NetworkSession: renamed some instructions to imperative instead of onWhatever() these aren't listening to events, they are telling the client that an event has taken place. --- src/network/mcpe/NetworkSession.php | 6 +++--- src/player/Player.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index a8f5e85029..cdf0296f05 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -610,11 +610,11 @@ class NetworkSession{ $this->logger->debug("Initiating resource packs phase"); $this->setHandler(new ResourcePacksPacketHandler($this, $this->server->getResourcePackManager(), function() : void{ - $this->onResourcePacksDone(); + $this->beginSpawnSequence(); })); } - private function onResourcePacksDone() : void{ + private function beginSpawnSequence() : void{ $this->createPlayer(); $this->setHandler(new PreSpawnPacketHandler($this->server, $this->player, $this)); @@ -623,7 +623,7 @@ class NetworkSession{ $this->logger->debug("Waiting for spawn chunks"); } - public function onTerrainReady() : void{ + public function notifyTerrainReady() : void{ $this->logger->debug("Sending spawn notification, waiting for spawn response"); $this->sendDataPacket(PlayStatusPacket::create(PlayStatusPacket::PLAYER_SPAWN)); $this->setHandler(new SpawnResponsePacketHandler(function() : void{ diff --git a/src/player/Player.php b/src/player/Player.php index 5ffe4fffbf..8161b3826a 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -790,7 +790,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } } - $this->networkSession->onTerrainReady(); + $this->networkSession->notifyTerrainReady(); } }); } From cc3947058acc862d90ababb4821dc46e9522a76a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 6 Oct 2020 18:11:13 +0100 Subject: [PATCH 1924/3224] updated phpstan baseline --- tests/phpstan/configs/l8-baseline.neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 37b22a9ded..e6b46e0ded 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -476,7 +476,7 @@ parameters: path: ../../../src/player/Player.php - - message: "#^Cannot call method onTerrainReady\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + message: "#^Cannot call method notifyTerrainReady\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" count: 1 path: ../../../src/player/Player.php From d7f7e1c4ffd99d90a84b493102d19656291732f4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 6 Oct 2020 18:14:46 +0100 Subject: [PATCH 1925/3224] InventoryManager: remove useless repeated code --- src/network/mcpe/InventoryManager.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index 1b288a1898..a2cf22a258 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -216,13 +216,7 @@ class InventoryManager{ } public function syncCreative() : void{ - $items = []; $typeConverter = TypeConverter::getInstance(); - if(!$this->player->isSpectator()){ //fill it for all gamemodes except spectator - foreach(CreativeInventory::getInstance()->getAll() as $i => $item){ - $items[$i] = $typeConverter->coreItemStackToNet($item); - } - } $nextEntryId = 1; $this->session->sendDataPacket(CreativeContentPacket::create(array_map(function(Item $item) use($typeConverter, &$nextEntryId) : CreativeContentEntry{ From 531c6344fe6bd920ef2b6639b7ff649cfe8bf11c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 6 Oct 2020 18:22:46 +0100 Subject: [PATCH 1926/3224] Entity: stop using broadcastPacketToViewers for movement / motion this is now effectively identical to sending packets to each of hasSpawned, with the exception that it won't send packets to itself if it's a player. --- src/entity/Entity.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index d746c0a2fd..4265037850 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -753,11 +753,11 @@ abstract class Entity{ $pk->flags |= MoveActorAbsolutePacket::FLAG_GROUND; } - $this->getWorld()->broadcastPacketToViewers($this->location, $pk); + $this->server->broadcastPackets($this->hasSpawned, [$pk]); } protected function broadcastMotion() : void{ - $this->getWorld()->broadcastPacketToViewers($this->location, SetActorMotionPacket::create($this->id, $this->getMotion())); + $this->server->broadcastPackets($this->hasSpawned, [SetActorMotionPacket::create($this->id, $this->getMotion())]); } public function hasGravity() : bool{ From 69cad3e694d309b4bd640a1d585b7b20fccea4f1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 6 Oct 2020 18:26:57 +0100 Subject: [PATCH 1927/3224] InGamePacketHandler: Ignore LevelSoundEventPacket completely --- .../mcpe/handler/InGamePacketHandler.php | 17 ----------------- .../mcpe/protocol/LevelSoundEventPacket.php | 2 +- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 4f5498486e..412135728a 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -817,23 +817,6 @@ class InGamePacketHandler extends PacketHandler{ return false; //TODO } - public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{ - //TODO: we want to block out this packet completely, but we don't yet know the full scope of sounds that the client sends us from here - switch($packet->sound){ - case LevelSoundEventPacket::SOUND_ATTACK: - case LevelSoundEventPacket::SOUND_ATTACK_NODAMAGE: - case LevelSoundEventPacket::SOUND_ATTACK_STRONG: //TODO: reassess this, seems like the regular attack is never used ?? - case LevelSoundEventPacket::SOUND_HIT: //block punch, maybe entity attack too? - case LevelSoundEventPacket::SOUND_LAND: - case LevelSoundEventPacket::SOUND_FALL: - case LevelSoundEventPacket::SOUND_FALL_SMALL: - case LevelSoundEventPacket::SOUND_FALL_BIG: - return true; - } - $this->player->getWorld()->broadcastPacketToViewers($this->player->getPosition(), $packet); - return true; - } - public function handleNetworkStackLatency(NetworkStackLatencyPacket $packet) : bool{ return true; //TODO: implement this properly - this is here to silence debug spam from MCPE dev builds } diff --git a/src/network/mcpe/protocol/LevelSoundEventPacket.php b/src/network/mcpe/protocol/LevelSoundEventPacket.php index 6c1311a8a8..5115f0f9bf 100644 --- a/src/network/mcpe/protocol/LevelSoundEventPacket.php +++ b/src/network/mcpe/protocol/LevelSoundEventPacket.php @@ -28,7 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -class LevelSoundEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ +class LevelSoundEventPacket extends DataPacket implements ClientboundPacket, GarbageServerboundPacket{ public const NETWORK_ID = ProtocolInfo::LEVEL_SOUND_EVENT_PACKET; public const SOUND_ITEM_USE_ON = 0; From d8ee657d2037825baa28f67a9a1143be87712e0a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 6 Oct 2020 18:34:38 +0100 Subject: [PATCH 1928/3224] MoveActorAbsolutePacket: added ::create() method --- src/network/mcpe/protocol/MoveActorAbsolutePacket.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/network/mcpe/protocol/MoveActorAbsolutePacket.php b/src/network/mcpe/protocol/MoveActorAbsolutePacket.php index 2844b3a5be..a987cc51fd 100644 --- a/src/network/mcpe/protocol/MoveActorAbsolutePacket.php +++ b/src/network/mcpe/protocol/MoveActorAbsolutePacket.php @@ -48,6 +48,17 @@ class MoveActorAbsolutePacket extends DataPacket implements ClientboundPacket, S /** @var float */ public $zRot; + public static function create(int $entityRuntimeId, Vector3 $pos, float $xRot, float $yRot, float $zRot, int $flags = 0) : self{ + $result = new self; + $result->entityRuntimeId = $entityRuntimeId; + $result->position = $pos->asVector3(); + $result->xRot = $xRot; + $result->yRot = $yRot; + $result->zRot = $zRot; + $result->flags = $flags; + return $result; + } + protected function decodePayload(PacketSerializer $in) : void{ $this->entityRuntimeId = $in->getEntityRuntimeId(); $this->flags = $in->getByte(); From cbc6ebebad2b4df8aa29085b85f3eac41c17dc12 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 6 Oct 2020 18:35:02 +0100 Subject: [PATCH 1929/3224] Entity: make use of MoveActorAbsolutePacket::create() --- src/entity/Entity.php | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 4265037850..fd6d72a362 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -735,25 +735,21 @@ abstract class Entity{ } protected function broadcastMovement(bool $teleport = false) : void{ - $pk = new MoveActorAbsolutePacket(); - $pk->entityRuntimeId = $this->id; - $pk->position = $this->getOffsetPosition($this->location); + $this->server->broadcastPackets($this->hasSpawned, [MoveActorAbsolutePacket::create( + $this->id, + $this->getOffsetPosition($this->location), - //this looks very odd but is correct as of 1.5.0.7 - //for arrows this is actually x/y/z rotation - //for mobs x and z are used for pitch and yaw, and y is used for headyaw - $pk->xRot = $this->location->pitch; - $pk->yRot = $this->location->yaw; //TODO: head yaw - $pk->zRot = $this->location->yaw; - - if($teleport){ - $pk->flags |= MoveActorAbsolutePacket::FLAG_TELEPORT; - } - if($this->onGround){ - $pk->flags |= MoveActorAbsolutePacket::FLAG_GROUND; - } - - $this->server->broadcastPackets($this->hasSpawned, [$pk]); + //this looks very odd but is correct as of 1.5.0.7 + //for arrows this is actually x/y/z rotation + //for mobs x and z are used for pitch and yaw, and y is used for headyaw + $this->location->pitch, + $this->location->yaw, + $this->location->yaw, + ( + ($teleport ? MoveActorAbsolutePacket::FLAG_TELEPORT : 0) | + ($this->onGround ? MoveActorAbsolutePacket::FLAG_GROUND : 0) + ) + )]); } protected function broadcastMotion() : void{ From df7bafe2bcd58bc79b2e87fbfca79585945e251e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 7 Oct 2020 15:16:27 +0100 Subject: [PATCH 1930/3224] TileFactory: fixed missing Beacon tile registration I had this locally but forgot to commit it ... --- src/block/tile/TileFactory.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/block/tile/TileFactory.php b/src/block/tile/TileFactory.php index 011f71c887..62875c0866 100644 --- a/src/block/tile/TileFactory.php +++ b/src/block/tile/TileFactory.php @@ -49,6 +49,7 @@ final class TileFactory{ public function __construct(){ $this->register(Banner::class, ["Banner", "minecraft:banner"]); + $this->register(Beacon::class, ["Beacon", "minecraft:beacon"]); $this->register(Bed::class, ["Bed", "minecraft:bed"]); $this->register(BrewingStand::class, ["BrewingStand", "minecraft:brewing_stand"]); $this->register(Chest::class, ["Chest", "minecraft:chest"]); From 94c58c00b5ee0a4e2a7b87928db44c58c7cad078 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 8 Oct 2020 14:36:02 +0100 Subject: [PATCH 1931/3224] NetworkSession: Restore PM3 unexpected XUID handling behaviour (removes XUID instead of kicking the player) close #3861, close #3089 --- src/network/mcpe/NetworkSession.php | 14 +++++++++----- src/player/PlayerInfo.php | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index cdf0296f05..8c370f6e61 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -561,8 +561,6 @@ class NetworkSession{ if($error === null){ if($authenticated and $this->info->getXuid() === ""){ $error = "Expected XUID but none found"; - }elseif(!$authenticated and $this->info->getXuid() !== ""){ - $error = "Unexpected XUID for non-XBOX-authenticated player"; }elseif($clientPubKey === null){ $error = "Missing client public key"; //failsafe } @@ -576,9 +574,15 @@ class NetworkSession{ $this->authenticated = $authenticated; - if(!$this->authenticated and $authRequired){ - $this->disconnect("disconnectionScreen.notAuthenticated"); - return; + if(!$this->authenticated){ + if($authRequired){ + $this->disconnect("disconnectionScreen.notAuthenticated"); + return; + } + if($this->info->hasXboxData()){ + $this->logger->warning("Discarding unexpected XUID for non-authenticated player"); + $this->info = $this->info->withoutXboxData(); + } } $this->logger->debug("Xbox Live authenticated: " . ($this->authenticated ? "YES" : "NO")); diff --git a/src/player/PlayerInfo.php b/src/player/PlayerInfo.php index dee690aa1d..52e9b2f7a4 100644 --- a/src/player/PlayerInfo.php +++ b/src/player/PlayerInfo.php @@ -88,4 +88,23 @@ class PlayerInfo{ public function getExtraData() : array{ return $this->extraData; } + + public function hasXboxData() : bool{ + return $this->xuid !== ""; + } + + /** + * Returns a new PlayerInfo with XBL player info stripped. This is used to ensure that non-XBL players can't spoof + * XBL data. + */ + public function withoutXboxData() : self{ + return new self( + $this->username, + $this->uuid, + $this->skin, + $this->locale, + "", + $this->extraData + ); + } } From 01b44ab0bc2de7b3dcd397f7fbe66776ff6daa68 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 8 Oct 2020 21:20:57 +0100 Subject: [PATCH 1932/3224] protocol: moved skin data types to their own namespace --- src/network/mcpe/convert/LegacySkinAdapter.php | 4 ++-- src/network/mcpe/convert/SkinAdapter.php | 2 +- src/network/mcpe/protocol/PlayerSkinPacket.php | 2 +- .../mcpe/protocol/serializer/PacketSerializer.php | 10 +++++----- src/network/mcpe/protocol/types/PlayerListEntry.php | 1 + .../types/login/ClientDataToSkinDataHelper.php | 10 +++++----- .../types/{ => skin}/PersonaPieceTintColor.php | 2 +- .../protocol/types/{ => skin}/PersonaSkinPiece.php | 4 ++-- .../mcpe/protocol/types/{ => skin}/SkinAnimation.php | 2 +- .../mcpe/protocol/types/{ => skin}/SkinData.php | 2 +- .../mcpe/protocol/types/{ => skin}/SkinImage.php | 2 +- 11 files changed, 21 insertions(+), 20 deletions(-) rename src/network/mcpe/protocol/types/{ => skin}/PersonaPieceTintColor.php (96%) rename src/network/mcpe/protocol/types/{ => skin}/PersonaSkinPiece.php (97%) rename src/network/mcpe/protocol/types/{ => skin}/SkinAnimation.php (96%) rename src/network/mcpe/protocol/types/{ => skin}/SkinData.php (98%) rename src/network/mcpe/protocol/types/{ => skin}/SkinImage.php (97%) diff --git a/src/network/mcpe/convert/LegacySkinAdapter.php b/src/network/mcpe/convert/LegacySkinAdapter.php index 93e476d864..8980366972 100644 --- a/src/network/mcpe/convert/LegacySkinAdapter.php +++ b/src/network/mcpe/convert/LegacySkinAdapter.php @@ -25,8 +25,8 @@ namespace pocketmine\network\mcpe\convert; use pocketmine\entity\InvalidSkinException; use pocketmine\entity\Skin; -use pocketmine\network\mcpe\protocol\types\SkinData; -use pocketmine\network\mcpe\protocol\types\SkinImage; +use pocketmine\network\mcpe\protocol\types\skin\SkinData; +use pocketmine\network\mcpe\protocol\types\skin\SkinImage; use function is_array; use function is_string; use function json_decode; diff --git a/src/network/mcpe/convert/SkinAdapter.php b/src/network/mcpe/convert/SkinAdapter.php index b77b846e2b..14ffc386db 100644 --- a/src/network/mcpe/convert/SkinAdapter.php +++ b/src/network/mcpe/convert/SkinAdapter.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\convert; use pocketmine\entity\InvalidSkinException; use pocketmine\entity\Skin; -use pocketmine\network\mcpe\protocol\types\SkinData; +use pocketmine\network\mcpe\protocol\types\skin\SkinData; /** * Used to convert new skin data to the skin entity or old skin entity to skin data. diff --git a/src/network/mcpe/protocol/PlayerSkinPacket.php b/src/network/mcpe/protocol/PlayerSkinPacket.php index 99295e9e82..f97e783e39 100644 --- a/src/network/mcpe/protocol/PlayerSkinPacket.php +++ b/src/network/mcpe/protocol/PlayerSkinPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\SkinData; +use pocketmine\network\mcpe\protocol\types\skin\SkinData; use pocketmine\uuid\UUID; class PlayerSkinPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ diff --git a/src/network/mcpe/protocol/serializer/PacketSerializer.php b/src/network/mcpe/protocol/serializer/PacketSerializer.php index 1efd9fecbb..9700336660 100644 --- a/src/network/mcpe/protocol/serializer/PacketSerializer.php +++ b/src/network/mcpe/protocol/serializer/PacketSerializer.php @@ -50,12 +50,12 @@ use pocketmine\network\mcpe\protocol\types\GameRule; use pocketmine\network\mcpe\protocol\types\GameRuleType; use pocketmine\network\mcpe\protocol\types\IntGameRule; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\network\mcpe\protocol\types\PersonaPieceTintColor; -use pocketmine\network\mcpe\protocol\types\PersonaSkinPiece; use pocketmine\network\mcpe\protocol\types\recipe\RecipeIngredient; -use pocketmine\network\mcpe\protocol\types\SkinAnimation; -use pocketmine\network\mcpe\protocol\types\SkinData; -use pocketmine\network\mcpe\protocol\types\SkinImage; +use pocketmine\network\mcpe\protocol\types\skin\PersonaPieceTintColor; +use pocketmine\network\mcpe\protocol\types\skin\PersonaSkinPiece; +use pocketmine\network\mcpe\protocol\types\skin\SkinAnimation; +use pocketmine\network\mcpe\protocol\types\skin\SkinData; +use pocketmine\network\mcpe\protocol\types\skin\SkinImage; use pocketmine\network\mcpe\protocol\types\StructureEditorData; use pocketmine\network\mcpe\protocol\types\StructureSettings; use pocketmine\utils\BinaryDataException; diff --git a/src/network/mcpe/protocol/types/PlayerListEntry.php b/src/network/mcpe/protocol/types/PlayerListEntry.php index d904410620..9e9aa712b5 100644 --- a/src/network/mcpe/protocol/types/PlayerListEntry.php +++ b/src/network/mcpe/protocol/types/PlayerListEntry.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types; +use pocketmine\network\mcpe\protocol\types\skin\SkinData; use pocketmine\uuid\UUID; class PlayerListEntry{ diff --git a/src/network/mcpe/protocol/types/login/ClientDataToSkinDataHelper.php b/src/network/mcpe/protocol/types/login/ClientDataToSkinDataHelper.php index 2ed495eb87..78af52ec93 100644 --- a/src/network/mcpe/protocol/types/login/ClientDataToSkinDataHelper.php +++ b/src/network/mcpe/protocol/types/login/ClientDataToSkinDataHelper.php @@ -23,11 +23,11 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\login; -use pocketmine\network\mcpe\protocol\types\PersonaPieceTintColor; -use pocketmine\network\mcpe\protocol\types\PersonaSkinPiece; -use pocketmine\network\mcpe\protocol\types\SkinAnimation; -use pocketmine\network\mcpe\protocol\types\SkinData; -use pocketmine\network\mcpe\protocol\types\SkinImage; +use pocketmine\network\mcpe\protocol\types\skin\PersonaPieceTintColor; +use pocketmine\network\mcpe\protocol\types\skin\PersonaSkinPiece; +use pocketmine\network\mcpe\protocol\types\skin\SkinAnimation; +use pocketmine\network\mcpe\protocol\types\skin\SkinData; +use pocketmine\network\mcpe\protocol\types\skin\SkinImage; use pocketmine\utils\SingletonTrait; use function array_map; use function base64_decode; diff --git a/src/network/mcpe/protocol/types/PersonaPieceTintColor.php b/src/network/mcpe/protocol/types/skin/PersonaPieceTintColor.php similarity index 96% rename from src/network/mcpe/protocol/types/PersonaPieceTintColor.php rename to src/network/mcpe/protocol/types/skin/PersonaPieceTintColor.php index 05231d3f1b..2eaaa1fa38 100644 --- a/src/network/mcpe/protocol/types/PersonaPieceTintColor.php +++ b/src/network/mcpe/protocol/types/skin/PersonaPieceTintColor.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\skin; final class PersonaPieceTintColor{ diff --git a/src/network/mcpe/protocol/types/PersonaSkinPiece.php b/src/network/mcpe/protocol/types/skin/PersonaSkinPiece.php similarity index 97% rename from src/network/mcpe/protocol/types/PersonaSkinPiece.php rename to src/network/mcpe/protocol/types/skin/PersonaSkinPiece.php index bb22a13507..e198da964d 100644 --- a/src/network/mcpe/protocol/types/PersonaSkinPiece.php +++ b/src/network/mcpe/protocol/types/skin/PersonaSkinPiece.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\skin; final class PersonaSkinPiece{ @@ -74,4 +74,4 @@ final class PersonaSkinPiece{ public function getProductId() : string{ return $this->productId; } -} \ No newline at end of file +} diff --git a/src/network/mcpe/protocol/types/SkinAnimation.php b/src/network/mcpe/protocol/types/skin/SkinAnimation.php similarity index 96% rename from src/network/mcpe/protocol/types/SkinAnimation.php rename to src/network/mcpe/protocol/types/skin/SkinAnimation.php index 40a9e96247..54f206a3e7 100644 --- a/src/network/mcpe/protocol/types/SkinAnimation.php +++ b/src/network/mcpe/protocol/types/skin/SkinAnimation.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\skin; class SkinAnimation{ diff --git a/src/network/mcpe/protocol/types/SkinData.php b/src/network/mcpe/protocol/types/skin/SkinData.php similarity index 98% rename from src/network/mcpe/protocol/types/SkinData.php rename to src/network/mcpe/protocol/types/skin/SkinData.php index 4831c384f1..3ad4e1e676 100644 --- a/src/network/mcpe/protocol/types/SkinData.php +++ b/src/network/mcpe/protocol/types/skin/SkinData.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\skin; use pocketmine\uuid\UUID; diff --git a/src/network/mcpe/protocol/types/SkinImage.php b/src/network/mcpe/protocol/types/skin/SkinImage.php similarity index 97% rename from src/network/mcpe/protocol/types/SkinImage.php rename to src/network/mcpe/protocol/types/skin/SkinImage.php index e6201524df..fa797cd7fe 100644 --- a/src/network/mcpe/protocol/types/SkinImage.php +++ b/src/network/mcpe/protocol/types/skin/SkinImage.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types; +namespace pocketmine\network\mcpe\protocol\types\skin; use function strlen; From b0b08d45d5e4551d51fb345e71adfefc84a01b2a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 8 Oct 2020 21:35:36 +0100 Subject: [PATCH 1933/3224] Entity: clean up sendData() handling, remove send-to-self hack --- src/entity/Entity.php | 22 +++++-------------- src/entity/Human.php | 2 +- src/network/mcpe/NetworkSession.php | 3 +-- .../mcpe/handler/InGamePacketHandler.php | 8 +++---- .../mcpe/handler/PreSpawnPacketHandler.php | 2 +- src/player/Player.php | 8 +++++++ 6 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index fd6d72a362..72b9e02b93 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -605,7 +605,7 @@ abstract class Entity{ $changedProperties = $this->getSyncedNetworkData(true); if(count($changedProperties) > 0){ - $this->sendData($this->hasSpawned, $changedProperties); + $this->sendData(null, $changedProperties); $this->networkProperties->clearDirtyProperties(); } @@ -1609,28 +1609,18 @@ abstract class Entity{ } /** - * @param Player[]|Player $player + * @param Player[]|null $targets * @param MetadataProperty[] $data Properly formatted entity data, defaults to everything + * * @phpstan-param array $data */ - public function sendData($player, ?array $data = null) : void{ - if(!is_array($player)){ - $player = [$player]; - } - + public function sendData(?array $targets, ?array $data = null) : void{ + $targets = $targets ?? $this->hasSpawned; $data = $data ?? $this->getSyncedNetworkData(false); - foreach($player as $p){ - if($p === $this){ - continue; - } + foreach($targets as $p){ $p->getNetworkSession()->syncActorData($this, $data); } - - if($this instanceof Player){ - //TODO: bad hack, remove - $this->getNetworkSession()->syncActorData($this, $data); - } } /** diff --git a/src/entity/Human.php b/src/entity/Human.php index b00787c227..f85e0ab855 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -401,7 +401,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $player->getNetworkSession()->sendDataPacket($pk); //TODO: Hack for MCPE 1.2.13: DATA_NAMETAG is useless in AddPlayerPacket, so it has to be sent separately - $this->sendData($player, [EntityMetadataProperties::NAMETAG => new StringMetadataProperty($this->getNameTag())]); + $this->sendData([$player], [EntityMetadataProperties::NAMETAG => new StringMetadataProperty($this->getNameTag())]); $player->getNetworkSession()->onMobArmorChange($this); diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 8c370f6e61..4610620568 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -649,8 +649,7 @@ class NetworkSession{ } public function onRespawn() : void{ - $this->player->sendData($this->player); - $this->player->sendData($this->player->getViewers()); + $this->player->sendData(null); $this->syncAdventureSettings($this->player); $this->invManager->syncAll(); diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 412135728a..450445c873 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -506,22 +506,22 @@ class InGamePacketHandler extends PacketHandler{ return true; case PlayerActionPacket::ACTION_START_SPRINT: if(!$this->player->toggleSprint(true)){ - $this->player->sendData($this->player); + $this->player->sendData([$this->player]); } return true; case PlayerActionPacket::ACTION_STOP_SPRINT: if(!$this->player->toggleSprint(false)){ - $this->player->sendData($this->player); + $this->player->sendData([$this->player]); } return true; case PlayerActionPacket::ACTION_START_SNEAK: if(!$this->player->toggleSneak(true)){ - $this->player->sendData($this->player); + $this->player->sendData([$this->player]); } return true; case PlayerActionPacket::ACTION_STOP_SNEAK: if(!$this->player->toggleSneak(false)){ - $this->player->sendData($this->player); + $this->player->sendData([$this->player]); } return true; case PlayerActionPacket::ACTION_START_GLIDE: diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index 560fbf5446..5a552b7851 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -95,7 +95,7 @@ class PreSpawnPacketHandler extends PacketHandler{ foreach($this->player->getEffects()->all() as $effect){ $this->session->onEntityEffectAdded($this->player, $effect, false); } - $this->player->sendData($this->player); + $this->player->sendData([$this->player]); $this->session->getInvManager()->syncAll(); $this->session->getInvManager()->syncCreative(); diff --git a/src/player/Player.php b/src/player/Player.php index 8161b3826a..a019071202 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2185,6 +2185,14 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $properties->setBlockPos(EntityMetadataProperties::PLAYER_BED_POSITION, $this->sleeping ?? new Vector3(0, 0, 0)); } + public function sendData(?array $targets, ?array $data = null) : void{ + if($targets === null){ + $targets = $this->getViewers(); + $targets[] = $this; + } + parent::sendData($targets, $data); + } + public function broadcastAnimation(Animation $animation, ?array $targets = null) : void{ if($this->spawned and $targets === null){ $targets = $this->getViewers(); From 15a2fd6e4f110725a15bc33a7cf3c47ae5ccdd56 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 8 Oct 2020 21:42:07 +0100 Subject: [PATCH 1934/3224] LegacySkinAdapter: check return value of json_encode() for resource patch --- src/network/mcpe/convert/LegacySkinAdapter.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/network/mcpe/convert/LegacySkinAdapter.php b/src/network/mcpe/convert/LegacySkinAdapter.php index 8980366972..3a930095b4 100644 --- a/src/network/mcpe/convert/LegacySkinAdapter.php +++ b/src/network/mcpe/convert/LegacySkinAdapter.php @@ -31,6 +31,7 @@ use function is_array; use function is_string; use function json_decode; use function json_encode; +use function json_last_error_msg; use function random_bytes; use function str_repeat; @@ -43,9 +44,13 @@ class LegacySkinAdapter implements SkinAdapter{ if($geometryName === ""){ $geometryName = "geometry.humanoid.custom"; } + $resourcePatch = json_encode(["geometry" => ["default" => $geometryName]]); + if($resourcePatch === false){ + throw new \RuntimeException("json_encode() failed: " . json_last_error_msg()); + } return new SkinData( $skin->getSkinId(), - json_encode(["geometry" => ["default" => $geometryName]]), + $resourcePatch, SkinImage::fromLegacy($skin->getSkinData()), [], $capeImage, $skin->getGeometryData() From a91710b199a0e73e3639b89643f2535b2e4cd751 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 8 Oct 2020 21:56:08 +0100 Subject: [PATCH 1935/3224] Fixed player knockback not working since 531c6344fe6bd920ef2b6639b7ff649cfe8bf11c player knockback silently depended on the chunk packet broadcast system sending the player's motion back to itself, which broadcasting to hasSpawned will not do. --- src/player/Player.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/player/Player.php b/src/player/Player.php index a019071202..5c97049fb5 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -90,6 +90,7 @@ use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; +use pocketmine\network\mcpe\protocol\SetActorMotionPacket; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; @@ -1261,6 +1262,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ public function setMotion(Vector3 $motion) : bool{ if(parent::setMotion($motion)){ $this->broadcastMotion(); + $this->networkSession->sendDataPacket(SetActorMotionPacket::create($this->id, $motion)); return true; } From 15cd354b983fb019f6c510a20e31474404400748 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 8 Oct 2020 21:58:22 +0100 Subject: [PATCH 1936/3224] fixed phpstan run again --- tests/phpstan/configs/l8-baseline.neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index e6b46e0ded..6858f2259e 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -497,7 +497,7 @@ parameters: - message: "#^Cannot call method sendDataPacket\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 + count: 2 path: ../../../src/player/Player.php - From 40fca0936f29aafc38b51ad3f04378d48d071752 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 9 Oct 2020 18:03:20 +0100 Subject: [PATCH 1937/3224] Internet: make getURL() and postURL() return InternetRequestResult objects this reduces the amount of reference parameters, and generally reduces the number of parameters, while guaranteeing consistency of the APIs. --- src/Server.php | 2 +- src/updater/UpdateCheckTask.php | 4 +- src/utils/Internet.php | 54 ++++++++++----------------- src/utils/InternetRequestResult.php | 57 +++++++++++++++++++++++++++++ src/utils/Timezone.php | 4 +- 5 files changed, 82 insertions(+), 39 deletions(-) create mode 100644 src/utils/InternetRequestResult.php diff --git a/src/Server.php b/src/Server.php index 0d13ba0433..ef43c9d5ae 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1472,7 +1472,7 @@ class Server{ "reportPaste" => base64_encode($dump->getEncodedData()) ], 10, [], $postUrlError); - if($reply !== false and ($data = json_decode($reply)) !== null){ + if($reply !== null and ($data = json_decode($reply->getBody())) !== null){ if(isset($data->crashId) and isset($data->crashUrl)){ $reportId = $data->crashId; $reportUrl = $data->crashUrl; diff --git a/src/updater/UpdateCheckTask.php b/src/updater/UpdateCheckTask.php index 22b1f5acba..67b5a49e71 100644 --- a/src/updater/UpdateCheckTask.php +++ b/src/updater/UpdateCheckTask.php @@ -50,8 +50,8 @@ class UpdateCheckTask extends AsyncTask{ $response = Internet::getURL($this->endpoint . "?channel=" . $this->channel, 4, [], $error); $this->error = $error; - if($response !== false){ - $response = json_decode($response, true); + if($response !== null){ + $response = json_decode($response->getBody(), true); if(is_array($response)){ if(isset($response["error"]) and is_string($response["error"])){ $this->error = $response["error"]; diff --git a/src/utils/Internet.php b/src/utils/Internet.php index 4b7ad926f4..987fa95b7e 100644 --- a/src/utils/Internet.php +++ b/src/utils/Internet.php @@ -84,28 +84,28 @@ class Internet{ } $ip = self::getURL("http://api.ipify.org/"); - if($ip !== false){ - return self::$ip = $ip; + if($ip !== null){ + return self::$ip = $ip->getBody(); } $ip = self::getURL("http://checkip.dyndns.org/"); - if($ip !== false and preg_match('#Current IP Address\: ([0-9a-fA-F\:\.]*)#', trim(strip_tags($ip)), $matches) > 0){ + if($ip !== null and preg_match('#Current IP Address\: ([0-9a-fA-F\:\.]*)#', trim(strip_tags($ip->getBody())), $matches) > 0){ return self::$ip = $matches[1]; } $ip = self::getURL("http://www.checkip.org/"); - if($ip !== false and preg_match('#">([0-9a-fA-F\:\.]*)#', $ip, $matches) > 0){ + if($ip !== null and preg_match('#">([0-9a-fA-F\:\.]*)#', $ip->getBody(), $matches) > 0){ return self::$ip = $matches[1]; } $ip = self::getURL("http://checkmyip.org/"); - if($ip !== false and preg_match('#Your IP address is ([0-9a-fA-F\:\.]*)#', $ip, $matches) > 0){ + if($ip !== null and preg_match('#Your IP address is ([0-9a-fA-F\:\.]*)#', $ip->getBody(), $matches) > 0){ return self::$ip = $matches[1]; } $ip = self::getURL("http://ifconfig.me/ip"); - if($ip !== false and trim($ip) != ""){ - return self::$ip = trim($ip); + if($ip !== null and ($addr = trim($ip->getBody())) != ""){ + return self::$ip = $addr; } return false; @@ -139,23 +139,17 @@ class Internet{ * GETs an URL using cURL * NOTE: This is a blocking operation and can take a significant amount of time. It is inadvisable to use this method on the main thread. * - * @param int $timeout default 10 - * @param string[] $extraHeaders - * @param string $err reference parameter, will be set to the output of curl_error(). Use this to retrieve errors that occured during the operation. - * @param string[] $headers reference parameter - * @param int $httpCode reference parameter + * @param int $timeout default 10 + * @param string[] $extraHeaders + * @param string|null $err reference parameter, will be set to the output of curl_error(). Use this to retrieve errors that occured during the operation. * @phpstan-param list $extraHeaders - * @phpstan-param array $headers - * - * @return string|false */ - public static function getURL(string $page, int $timeout = 10, array $extraHeaders = [], &$err = null, &$headers = null, &$httpCode = null){ + public static function getURL(string $page, int $timeout = 10, array $extraHeaders = [], &$err = null) : ?InternetRequestResult{ try{ - list($ret, $headers, $httpCode) = self::simpleCurl($page, $timeout, $extraHeaders); - return $ret; + return self::simpleCurl($page, $timeout, $extraHeaders); }catch(InternetException $ex){ $err = $ex->getMessage(); - return false; + return null; } } @@ -165,25 +159,19 @@ class Internet{ * * @param string[]|string $args * @param string[] $extraHeaders - * @param string $err reference parameter, will be set to the output of curl_error(). Use this to retrieve errors that occured during the operation. - * @param string[] $headers reference parameter - * @param int $httpCode reference parameter + * @param string|null $err reference parameter, will be set to the output of curl_error(). Use this to retrieve errors that occured during the operation. * @phpstan-param string|array $args * @phpstan-param list $extraHeaders - * @phpstan-param array $headers - * - * @return string|false */ - public static function postURL(string $page, $args, int $timeout = 10, array $extraHeaders = [], &$err = null, &$headers = null, &$httpCode = null){ + public static function postURL(string $page, $args, int $timeout = 10, array $extraHeaders = [], &$err = null) : ?InternetRequestResult{ try{ - list($ret, $headers, $httpCode) = self::simpleCurl($page, $timeout, $extraHeaders, [ + return self::simpleCurl($page, $timeout, $extraHeaders, [ CURLOPT_POST => 1, CURLOPT_POSTFIELDS => $args ]); - return $ret; }catch(InternetException $ex){ $err = $ex->getMessage(); - return false; + return null; } } @@ -199,12 +187,9 @@ class Internet{ * @phpstan-param list $extraHeaders * @phpstan-param (\Closure(resource) : void)|null $onSuccess * - * @return array a plain array of three [result body : string, headers : string[][], HTTP response code : int]. Headers are grouped by requests with strtolower(header name) as keys and header value as values - * @phpstan-return array{string, list>, int} - * * @throws InternetException if a cURL error occurs */ - public static function simpleCurl(string $page, $timeout = 10, array $extraHeaders = [], array $extraOpts = [], ?\Closure $onSuccess = null) : array{ + public static function simpleCurl(string $page, $timeout = 10, array $extraHeaders = [], array $extraOpts = [], ?\Closure $onSuccess = null) : InternetRequestResult{ if(!self::$online){ throw new InternetException("Cannot execute web request while offline"); } @@ -233,6 +218,7 @@ class Internet{ throw new InternetException(curl_error($ch)); } if(!is_string($raw)) throw new AssumptionFailedError("curl_exec() should return string|false when CURLOPT_RETURNTRANSFER is set"); + /** @var int $httpCode */ $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); $rawHeaders = substr($raw, 0, $headerSize); @@ -251,7 +237,7 @@ class Internet{ if($onSuccess !== null){ $onSuccess($ch); } - return [$body, $headers, $httpCode]; + return new InternetRequestResult($headers, $body, $httpCode); }finally{ curl_close($ch); } diff --git a/src/utils/InternetRequestResult.php b/src/utils/InternetRequestResult.php new file mode 100644 index 0000000000..481ceedb38 --- /dev/null +++ b/src/utils/InternetRequestResult.php @@ -0,0 +1,57 @@ +> + */ + private $headers; + /** @var string */ + private $body; + /** @var int */ + private $code; + + /** + * @param string[][] $headers + * @phpstan-param list> $headers + */ + public function __construct(array $headers, string $body, int $code){ + $this->headers = $headers; + $this->body = $body; + $this->code = $code; + } + + /** + * @return string[][] + * @phpstan-return list> + */ + public function getHeaders() : array{ return $this->headers; } + + public function getBody() : string{ return $this->body; } + + public function getCode() : int{ return $this->code; } +} diff --git a/src/utils/Timezone.php b/src/utils/Timezone.php index d5f62986eb..673671ec53 100644 --- a/src/utils/Timezone.php +++ b/src/utils/Timezone.php @@ -83,8 +83,8 @@ abstract class Timezone{ return; } - if($response = Internet::getURL("http://ip-api.com/json") //If system timezone detection fails or timezone is an invalid value. - and $ip_geolocation_data = json_decode($response, true) + if(($response = Internet::getURL("http://ip-api.com/json")) !== null //If system timezone detection fails or timezone is an invalid value. + and $ip_geolocation_data = json_decode($response->getBody(), true) and $ip_geolocation_data['status'] !== 'fail' and date_default_timezone_set($ip_geolocation_data['timezone']) ){ From e11dbf03e213ff0a4596ea85b72c2b30a8a3b6a3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 9 Oct 2020 18:06:33 +0100 Subject: [PATCH 1938/3224] Process: apply native typehint to kill() --- src/utils/Process.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/utils/Process.php b/src/utils/Process.php index 37f751d1c6..b489ffd25f 100644 --- a/src/utils/Process.php +++ b/src/utils/Process.php @@ -123,10 +123,7 @@ final class Process{ return count(ThreadManager::getInstance()->getAll()) + 2; //MainLogger + Main Thread } - /** - * @param int $pid - */ - public static function kill($pid) : void{ + public static function kill(int $pid) : void{ $logger = \GlobalLogger::get(); if($logger instanceof MainLogger){ $logger->syncFlushBuffer(); From 46c57e4e244a31ffeb5462752b52f0c886729a1e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 11 Oct 2020 11:35:03 +0100 Subject: [PATCH 1939/3224] TimingsCommand: fixed crash on result handling since AsyncTask->getResult() returns mixed, phpstan has no idea what is being returned here, so it doesn't report any errors. --- src/command/defaults/TimingsCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command/defaults/TimingsCommand.php b/src/command/defaults/TimingsCommand.php index c953438f1b..98204167a9 100644 --- a/src/command/defaults/TimingsCommand.php +++ b/src/command/defaults/TimingsCommand.php @@ -163,7 +163,7 @@ class TimingsCommand extends VanillaCommand{ $sender->getServer()->getLogger()->logException($result); return; } - $response = json_decode($result[0], true); + $response = json_decode($result->getBody(), true); if(is_array($response) && isset($response["id"])){ Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.command.timings.timingsRead", ["https://" . $this->host . "/?id=" . $response["id"]])); From 2e3940e8f54164af3e07af0952eea64f4fd8de36 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 11 Oct 2020 12:22:52 +0100 Subject: [PATCH 1940/3224] NetworkSession: remove circular dependency between queueCompressed() and flushSendBuffer() this cycle makes the code fragile and prone to infinite looping bugs when modified, as well as making the code harder to follow. --- src/network/mcpe/NetworkSession.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 4610620568..214cc78632 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -427,7 +427,7 @@ class NetworkSession{ if(count($this->sendBuffer) > 0){ $promise = $this->server->prepareBatch(PacketBatch::fromPackets(...$this->sendBuffer), $this->compressor, $immediate); $this->sendBuffer = []; - $this->queueCompressed($promise, $immediate); + $this->queueCompressedNoBufferFlush($promise, $immediate); } } @@ -437,6 +437,10 @@ class NetworkSession{ public function queueCompressed(CompressBatchPromise $payload, bool $immediate = false) : void{ $this->flushSendBuffer($immediate); //Maintain ordering if possible + $this->queueCompressedNoBufferFlush($payload, $immediate); + } + + private function queueCompressedNoBufferFlush(CompressBatchPromise $payload, bool $immediate = false) : void{ if($immediate){ //Skips all queues $this->sendEncoded($payload->getResult(), true); From bd3bf3d0ce5238989a54b7d5ecaff9b2c6b2aaaf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 11 Oct 2020 14:55:54 +0100 Subject: [PATCH 1941/3224] Revert "World: do not group broadcasted packets by chunk, broadcast directly instead" This reverts commit b172c93e45e60ee3dbfd8a2efbede60b894673a3. I made a significant mistake with this change: the scaling factor of batch-by-chunk is O(nSendBytes), while the scaling factor of sending directly to players is O(nSendBytes * nActivePlayers). It seems like the real problem is that this system isn't getting enough usage. While it does reduce compression efficiency in some cases, it falls back to letting the sessions do individual compression when the amount of data is less than 256 bytes anyway (compression-threshold in pocketmine.yml). My motivation for scrapping this system was to reduce the broadcast system's complexity to make it easier to thread the living shit out of compression, but it seems like this change was a step in the wrong direction for performance. A few steps can be taken to improve the usefulness of this system (and also improve output bandwidth): - Make general entity updates use this system. Movement and velocity already kinda used this system, but crucially, players did not, because we couldn't prevent the player from receiving its own movement updates if we did that, which caused all kinds of problems. - Therefore, we need to reintroduce static "self" entity IDs, like we had in the shoghi days when entity ID 0 referred to the "self" player. - However, since entity ID 0 has a variety of interesting bugs since it usually refers to "no entity" in MCPE, it would be better to use 1 (or 2, like MiNET does). - The fixed ID used should be close to zero to maximize varint encoding efficiency. - We assumed that changes to player's position and velocity would be ignored by the client. This assumption depends on the client and could be broken at any time, so it's best not to rely on it. - Make block updates use this system (when chunk updates are not sent). Currently, block updates use a separate mechanism which creates a second batch for every active chunk, which wastes CPU, and decreases bandwidth efficiency on multiple fronts (reduced compression efficiency, more cross-thread interactions, more bytes wasted on RakNet packet headers). --- src/world/World.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index 02c11558cf..f649a27d7b 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -172,6 +172,9 @@ class World implements ChunkManager{ /** @var Player[][] */ private $playerChunkListeners = []; + /** @var ClientboundPacket[][] */ + private $chunkPackets = []; + /** @var float[] */ private $unloadQueue = []; @@ -522,7 +525,11 @@ class World implements ChunkManager{ * Broadcasts a packet to every player who has the target position within their view distance. */ public function broadcastPacketToViewers(Vector3 $pos, ClientboundPacket $packet) : void{ - $this->server->broadcastPackets($this->getChunkPlayers($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4), [$packet]); + if(!isset($this->chunkPackets[$index = World::chunkHash($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4)])){ + $this->chunkPackets[$index] = [$packet]; + }else{ + $this->chunkPackets[$index][] = $packet; + } } public function registerChunkLoader(ChunkLoader $loader, int $chunkX, int $chunkZ, bool $autoLoad = true) : void{ @@ -768,6 +775,16 @@ class World implements ChunkManager{ if($this->sleepTicks > 0 and --$this->sleepTicks <= 0){ $this->checkSleep(); } + + foreach($this->chunkPackets as $index => $entries){ + World::getXZ($index, $chunkX, $chunkZ); + $chunkPlayers = $this->getChunkPlayers($chunkX, $chunkZ); + if(count($chunkPlayers) > 0){ + $this->server->broadcastPackets($chunkPlayers, $entries); + } + } + + $this->chunkPackets = []; } public function checkSleep() : void{ From a05b1fec7e56cc8be89b9eccc43b86eadabc3aa7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 11 Oct 2020 15:18:57 +0100 Subject: [PATCH 1942/3224] World: rename chunkPackets -> packetBuffersByChunk --- src/world/World.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index f649a27d7b..9b02eb1836 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -173,7 +173,7 @@ class World implements ChunkManager{ private $playerChunkListeners = []; /** @var ClientboundPacket[][] */ - private $chunkPackets = []; + private $packetBuffersByChunk = []; /** @var float[] */ private $unloadQueue = []; @@ -525,10 +525,10 @@ class World implements ChunkManager{ * Broadcasts a packet to every player who has the target position within their view distance. */ public function broadcastPacketToViewers(Vector3 $pos, ClientboundPacket $packet) : void{ - if(!isset($this->chunkPackets[$index = World::chunkHash($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4)])){ - $this->chunkPackets[$index] = [$packet]; + if(!isset($this->packetBuffersByChunk[$index = World::chunkHash($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4)])){ + $this->packetBuffersByChunk[$index] = [$packet]; }else{ - $this->chunkPackets[$index][] = $packet; + $this->packetBuffersByChunk[$index][] = $packet; } } @@ -776,7 +776,7 @@ class World implements ChunkManager{ $this->checkSleep(); } - foreach($this->chunkPackets as $index => $entries){ + foreach($this->packetBuffersByChunk as $index => $entries){ World::getXZ($index, $chunkX, $chunkZ); $chunkPlayers = $this->getChunkPlayers($chunkX, $chunkZ); if(count($chunkPlayers) > 0){ @@ -784,7 +784,7 @@ class World implements ChunkManager{ } } - $this->chunkPackets = []; + $this->packetBuffersByChunk = []; } public function checkSleep() : void{ From ca9f3020b43146479b21ef189ca331a8ab02733d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 11 Oct 2020 15:21:15 +0100 Subject: [PATCH 1943/3224] World: added private broadcastPacketToPlayersUsingChunk() this is equivalent to the old addChunkPacket, but private and with a less stupid name. --- src/world/World.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index 9b02eb1836..837498e9b9 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -525,7 +525,11 @@ class World implements ChunkManager{ * Broadcasts a packet to every player who has the target position within their view distance. */ public function broadcastPacketToViewers(Vector3 $pos, ClientboundPacket $packet) : void{ - if(!isset($this->packetBuffersByChunk[$index = World::chunkHash($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4)])){ + $this->broadcastPacketToPlayersUsingChunk($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4, $packet); + } + + private function broadcastPacketToPlayersUsingChunk(int $chunkX, int $chunkZ, ClientboundPacket $packet) : void{ + if(!isset($this->packetBuffersByChunk[$index = World::chunkHash($chunkX, $chunkZ)])){ $this->packetBuffersByChunk[$index] = [$packet]; }else{ $this->packetBuffersByChunk[$index][] = $packet; From eabfd2a37bbe81bc967c643dcf430b9ca6a43379 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 11 Oct 2020 16:30:54 +0100 Subject: [PATCH 1944/3224] World: replace sendBlocks() with createBlockUpdatePackets() this allows the caller to decide how the packets should be sent. --- src/network/mcpe/handler/InGamePacketHandler.php | 8 ++++++-- src/world/World.php | 11 +++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 450445c873..5c25d54228 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -390,7 +390,9 @@ class InGamePacketHandler extends PacketHandler{ }else{ $blocks[] = $blockPos; } - $this->player->getLocation()->getWorld()->sendBlocks([$this->player], $blocks); + foreach($this->player->getWorld()->createBlockUpdatePackets($blocks) as $packet){ + $this->session->sendDataPacket($packet); + } } } @@ -616,7 +618,9 @@ class InGamePacketHandler extends PacketHandler{ try{ if(!$block->updateText($this->player, $text)){ - $this->player->getWorld()->sendBlocks([$this->player], [$pos]); + foreach($this->player->getWorld()->createBlockUpdatePackets([$pos]) as $updatePacket){ + $this->session->sendDataPacket($updatePacket); + } } }catch(\UnexpectedValueException $e){ throw BadPacketException::wrap($e); diff --git a/src/world/World.php b/src/world/World.php index 837498e9b9..eeb85d567e 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -763,7 +763,9 @@ class World implements ChunkManager{ $p->onChunkChanged($chunk); } }else{ - $this->sendBlocks($this->getChunkPlayers($chunkX, $chunkZ), $blocks); + foreach($this->createBlockUpdatePackets($blocks) as $packet){ + $this->broadcastPacketToPlayersUsingChunk($chunkX, $chunkZ, $packet); + } } } } @@ -822,10 +824,11 @@ class World implements ChunkManager{ } /** - * @param Player[] $target * @param Vector3[] $blocks + * + * @return ClientboundPacket[] */ - public function sendBlocks(array $target, array $blocks) : void{ + public function createBlockUpdatePackets(array $blocks) : array{ $packets = []; foreach($blocks as $b){ @@ -842,7 +845,7 @@ class World implements ChunkManager{ } } - $this->server->broadcastPackets($target, $packets); + return $packets; } public function clearCache(bool $force = false) : void{ From 03837c1b716dbc29bfe79d86ca039af3b4e8c910 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 13 Oct 2020 17:30:27 +0100 Subject: [PATCH 1945/3224] ZlibCompressor: use libdeflate if available I may make libdeflate mandatory later on, but right now we haven't been able to ship it on all platforms yet. --- src/network/mcpe/compression/ZlibCompressor.php | 7 +++++++ tests/phpstan/bootstrap.php | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/src/network/mcpe/compression/ZlibCompressor.php b/src/network/mcpe/compression/ZlibCompressor.php index 61115f22d8..961f3558b2 100644 --- a/src/network/mcpe/compression/ZlibCompressor.php +++ b/src/network/mcpe/compression/ZlibCompressor.php @@ -24,6 +24,8 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\compression; use pocketmine\utils\SingletonTrait; +use function function_exists; +use function libdeflate_deflate_compress; use function strlen; use function zlib_decode; use function zlib_encode; @@ -72,6 +74,11 @@ final class ZlibCompressor implements Compressor{ } public function compress(string $payload) : string{ + if(function_exists('libdeflate_deflate_compress')){ + return $this->willCompress($payload) ? + libdeflate_deflate_compress($payload, $this->level) : + zlib_encode($payload, ZLIB_ENCODING_RAW, 0); + } return zlib_encode($payload, ZLIB_ENCODING_RAW, $this->willCompress($payload) ? $this->level : 0); } } diff --git a/tests/phpstan/bootstrap.php b/tests/phpstan/bootstrap.php index 21459e92ce..a962d4ac87 100644 --- a/tests/phpstan/bootstrap.php +++ b/tests/phpstan/bootstrap.php @@ -23,6 +23,10 @@ declare(strict_types=1); define('pocketmine\_PHPSTAN_ANALYSIS', true); +if(!extension_loaded('libdeflate')){ + function libdeflate_deflate_compress(string $data, int $level = 6) : string{} +} + //TODO: these need to be defined properly or removed define('pocketmine\COMPOSER_AUTOLOADER_PATH', dirname(__DIR__, 2) . '/vendor/autoload.php'); define('pocketmine\PLUGIN_PATH', ''); From 0186468e478d0b7a8bd6fc231bf9bd0a233607d4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 13 Oct 2020 17:38:06 +0100 Subject: [PATCH 1946/3224] updated composer dependencies --- composer.lock | 367 +++++++++++++++++++++++++------------------------- 1 file changed, 184 insertions(+), 183 deletions(-) diff --git a/composer.lock b/composer.lock index 19b11a86ab..caffb42ad5 100644 --- a/composer.lock +++ b/composer.lock @@ -825,20 +825,20 @@ }, { "name": "respect/validation", - "version": "2.0.17", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/Respect/Validation.git", - "reference": "314aa36e37dd3812b7d80c7bda3e83da5ee22d11" + "reference": "6c3aed92137836788c8ce654b9c35763c5e98b54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Respect/Validation/zipball/314aa36e37dd3812b7d80c7bda3e83da5ee22d11", - "reference": "314aa36e37dd3812b7d80c7bda3e83da5ee22d11", + "url": "https://api.github.com/repos/Respect/Validation/zipball/6c3aed92137836788c8ce654b9c35763c5e98b54", + "reference": "6c3aed92137836788c8ce654b9c35763c5e98b54", "shasum": "" }, "require": { - "php": ">=7.2", + "php": "^7.3 || ^8.0", "respect/stringifier": "^0.2.0", "symfony/polyfill-mbstring": "^1.2" }, @@ -849,8 +849,9 @@ "phpstan/phpstan": "^0.12", "phpstan/phpstan-deprecation-rules": "^0.12", "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^7.5", - "respect/coding-standard": "^2.1", + "phpunit/phpunit": "^9.3", + "psr/http-message": "^1.0", + "respect/coding-standard": "^3.0", "squizlabs/php_codesniffer": "^3.5", "symfony/validator": "^3.0||^4.0", "zendframework/zend-validator": "^2.1" @@ -886,7 +887,7 @@ "validation", "validator" ], - "time": "2020-08-23T00:24:43+00:00" + "time": "2020-10-04T12:09:34+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -1380,28 +1381,28 @@ }, { "name": "phpspec/prophecy", - "version": "1.11.1", + "version": "1.12.1", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160" + "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/b20034be5efcdab4fb60ca3a29cba2949aead160", - "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/8ce87516be71aae9b956f81906aaf0338e0d8a2d", + "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d", "shasum": "" }, "require": { "doctrine/instantiator": "^1.2", - "php": "^7.2", - "phpdocumentor/reflection-docblock": "^5.0", + "php": "^7.2 || ~8.0, <8.1", + "phpdocumentor/reflection-docblock": "^5.2", "sebastian/comparator": "^3.0 || ^4.0", "sebastian/recursion-context": "^3.0 || ^4.0" }, "require-dev": { "phpspec/phpspec": "^6.0", - "phpunit/phpunit": "^8.0" + "phpunit/phpunit": "^8.0 || ^9.0 <9.3" }, "type": "library", "extra": { @@ -1439,7 +1440,7 @@ "spy", "stub" ], - "time": "2020-07-08T12:44:21+00:00" + "time": "2020-09-29T09:10:42+00:00" }, { "name": "phpstan/phpstan", @@ -1606,16 +1607,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.1.11", + "version": "9.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "c9394cb9d07ecfa9351b96f2e296bad473195f4d" + "reference": "53a4b737e83be724efd2bc4e7b929b9a30c48972" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c9394cb9d07ecfa9351b96f2e296bad473195f4d", - "reference": "c9394cb9d07ecfa9351b96f2e296bad473195f4d", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/53a4b737e83be724efd2bc4e7b929b9a30c48972", + "reference": "53a4b737e83be724efd2bc4e7b929b9a30c48972", "shasum": "" }, "require": { @@ -1643,7 +1644,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.1-dev" + "dev-master": "9.2-dev" } }, "autoload": { @@ -1675,27 +1676,27 @@ "type": "github" } ], - "time": "2020-09-19T05:29:17+00:00" + "time": "2020-10-02T03:37:32+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "3.0.4", + "version": "3.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "25fefc5b19835ca653877fe081644a3f8c1d915e" + "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/25fefc5b19835ca653877fe081644a3f8c1d915e", - "reference": "25fefc5b19835ca653877fe081644a3f8c1d915e", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8", + "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -1731,28 +1732,28 @@ "type": "github" } ], - "time": "2020-07-11T05:18:21+00:00" + "time": "2020-09-28T05:57:25+00:00" }, { "name": "phpunit/php-invoker", - "version": "3.1.0", + "version": "3.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "7a85b66acc48cacffdf87dadd3694e7123674298" + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/7a85b66acc48cacffdf87dadd3694e7123674298", - "reference": "7a85b66acc48cacffdf87dadd3694e7123674298", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "suggest": { "ext-pcntl": "*" @@ -1790,27 +1791,27 @@ "type": "github" } ], - "time": "2020-08-06T07:04:15+00:00" + "time": "2020-09-28T05:58:55+00:00" }, { "name": "phpunit/php-text-template", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "6ff9c8ea4d3212b88fcf74e25e516e2c51c99324" + "reference": "18c887016e60e52477e54534956d7b47bc52cd84" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/6ff9c8ea4d3212b88fcf74e25e516e2c51c99324", - "reference": "6ff9c8ea4d3212b88fcf74e25e516e2c51c99324", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/18c887016e60e52477e54534956d7b47bc52cd84", + "reference": "18c887016e60e52477e54534956d7b47bc52cd84", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -1845,27 +1846,27 @@ "type": "github" } ], - "time": "2020-06-26T11:55:37+00:00" + "time": "2020-09-28T06:03:05+00:00" }, { "name": "phpunit/php-timer", - "version": "5.0.1", + "version": "5.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "cc49734779cbb302bf51a44297dab8c4bbf941e7" + "reference": "c9ff14f493699e2f6adee9fd06a0245b276643b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/cc49734779cbb302bf51a44297dab8c4bbf941e7", - "reference": "cc49734779cbb302bf51a44297dab8c4bbf941e7", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/c9ff14f493699e2f6adee9fd06a0245b276643b7", + "reference": "c9ff14f493699e2f6adee9fd06a0245b276643b7", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.2" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -1900,20 +1901,20 @@ "type": "github" } ], - "time": "2020-06-26T11:58:13+00:00" + "time": "2020-09-28T06:00:25+00:00" }, { "name": "phpunit/phpunit", - "version": "9.3.11", + "version": "9.4.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "f7316ea106df7c9507f4fdaa88c47bc10a3b27a1" + "reference": "1f09a12726593737e8a228ebb1c8647305d07c41" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f7316ea106df7c9507f4fdaa88c47bc10a3b27a1", - "reference": "f7316ea106df7c9507f4fdaa88c47bc10a3b27a1", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1f09a12726593737e8a228ebb1c8647305d07c41", + "reference": "1f09a12726593737e8a228ebb1c8647305d07c41", "shasum": "" }, "require": { @@ -1928,23 +1929,23 @@ "phar-io/manifest": "^2.0.1", "phar-io/version": "^3.0.2", "php": ">=7.3", - "phpspec/prophecy": "^1.11.1", - "phpunit/php-code-coverage": "^9.1.11", - "phpunit/php-file-iterator": "^3.0.4", - "phpunit/php-invoker": "^3.1", - "phpunit/php-text-template": "^2.0.2", - "phpunit/php-timer": "^5.0.1", - "sebastian/cli-parser": "^1.0", - "sebastian/code-unit": "^1.0.5", - "sebastian/comparator": "^4.0.3", - "sebastian/diff": "^4.0.2", - "sebastian/environment": "^5.1.2", - "sebastian/exporter": "^4.0.2", - "sebastian/global-state": "^5.0", - "sebastian/object-enumerator": "^4.0.2", - "sebastian/resource-operations": "^3.0.2", - "sebastian/type": "^2.2.1", - "sebastian/version": "^3.0.1" + "phpspec/prophecy": "^1.12.1", + "phpunit/php-code-coverage": "^9.2", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.5", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.3", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^2.3", + "sebastian/version": "^3.0.2" }, "require-dev": { "ext-pdo": "*", @@ -1960,7 +1961,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.3-dev" + "dev-master": "9.4-dev" } }, "autoload": { @@ -1999,24 +2000,24 @@ "type": "github" } ], - "time": "2020-09-24T08:08:49+00:00" + "time": "2020-10-11T07:41:19+00:00" }, { "name": "sebastian/cli-parser", - "version": "1.0.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "2a4a38c56e62f7295bedb8b1b7439ad523d4ea82" + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2a4a38c56e62f7295bedb8b1b7439ad523d4ea82", - "reference": "2a4a38c56e62f7295bedb8b1b7439ad523d4ea82", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.3" @@ -2051,27 +2052,27 @@ "type": "github" } ], - "time": "2020-08-12T10:49:21+00:00" + "time": "2020-09-28T06:08:49+00:00" }, { "name": "sebastian/code-unit", - "version": "1.0.5", + "version": "1.0.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "c1e2df332c905079980b119c4db103117e5e5c90" + "reference": "59236be62b1bb9919e6d7f60b0b832dc05cef9ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/c1e2df332c905079980b119c4db103117e5e5c90", - "reference": "c1e2df332c905079980b119c4db103117e5e5c90", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/59236be62b1bb9919e6d7f60b0b832dc05cef9ab", + "reference": "59236be62b1bb9919e6d7f60b0b832dc05cef9ab", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -2103,27 +2104,27 @@ "type": "github" } ], - "time": "2020-06-26T12:50:45+00:00" + "time": "2020-10-02T14:47:54+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ee51f9bb0c6d8a43337055db3120829fa14da819" + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ee51f9bb0c6d8a43337055db3120829fa14da819", - "reference": "ee51f9bb0c6d8a43337055db3120829fa14da819", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -2154,29 +2155,29 @@ "type": "github" } ], - "time": "2020-06-26T12:04:00+00:00" + "time": "2020-09-28T05:30:19+00:00" }, { "name": "sebastian/comparator", - "version": "4.0.3", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f" + "reference": "7a8ff306445707539c1a6397372a982a1ec55120" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f", - "reference": "dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/7a8ff306445707539c1a6397372a982a1ec55120", + "reference": "7a8ff306445707539c1a6397372a982a1ec55120", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0", + "php": ">=7.3", "sebastian/diff": "^4.0", "sebastian/exporter": "^4.0" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -2224,28 +2225,28 @@ "type": "github" } ], - "time": "2020-06-26T12:05:46+00:00" + "time": "2020-09-30T06:47:25+00:00" }, { "name": "sebastian/complexity", - "version": "2.0.0", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "33fcd6a26656c6546f70871244ecba4b4dced097" + "reference": "ba8cc2da0c0bfbc813d03b56406734030c7f1eff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/33fcd6a26656c6546f70871244ecba4b4dced097", - "reference": "33fcd6a26656c6546f70871244ecba4b4dced097", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ba8cc2da0c0bfbc813d03b56406734030c7f1eff", + "reference": "ba8cc2da0c0bfbc813d03b56406734030c7f1eff", "shasum": "" }, "require": { "nikic/php-parser": "^4.7", - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.2" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -2277,27 +2278,27 @@ "type": "github" } ], - "time": "2020-07-25T14:01:34+00:00" + "time": "2020-09-28T06:05:03+00:00" }, { "name": "sebastian/diff", - "version": "4.0.2", + "version": "4.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113" + "reference": "ffc949a1a2aae270ea064453d7535b82e4c32092" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113", - "reference": "1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ffc949a1a2aae270ea064453d7535b82e4c32092", + "reference": "ffc949a1a2aae270ea064453d7535b82e4c32092", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.0", + "phpunit/phpunit": "^9.3", "symfony/process": "^4.2 || ^5" }, "type": "library", @@ -2339,27 +2340,27 @@ "type": "github" } ], - "time": "2020-06-30T04:46:02+00:00" + "time": "2020-09-28T05:32:55+00:00" }, { "name": "sebastian/environment", - "version": "5.1.2", + "version": "5.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "0a757cab9d5b7ef49a619f1143e6c9c1bc0fe9d2" + "reference": "388b6ced16caa751030f6a69e588299fa09200ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/0a757cab9d5b7ef49a619f1143e6c9c1bc0fe9d2", - "reference": "0a757cab9d5b7ef49a619f1143e6c9c1bc0fe9d2", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", + "reference": "388b6ced16caa751030f6a69e588299fa09200ac", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "suggest": { "ext-posix": "*" @@ -2367,7 +2368,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -2398,29 +2399,29 @@ "type": "github" } ], - "time": "2020-06-26T12:07:24+00:00" + "time": "2020-09-28T05:52:38+00:00" }, { "name": "sebastian/exporter", - "version": "4.0.2", + "version": "4.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "571d721db4aec847a0e59690b954af33ebf9f023" + "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/571d721db4aec847a0e59690b954af33ebf9f023", - "reference": "571d721db4aec847a0e59690b954af33ebf9f023", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d89cc98761b8cb5a1a235a6b703ae50d34080e65", + "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0", + "php": ">=7.3", "sebastian/recursion-context": "^4.0" }, "require-dev": { "ext-mbstring": "*", - "phpunit/phpunit": "^9.2" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -2471,24 +2472,24 @@ "type": "github" } ], - "time": "2020-06-26T12:08:55+00:00" + "time": "2020-09-28T05:24:23+00:00" }, { "name": "sebastian/global-state", - "version": "5.0.0", + "version": "5.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "22ae663c951bdc39da96603edc3239ed3a299097" + "reference": "ea779cb749a478b22a2564ac41cd7bda79c78dc7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/22ae663c951bdc39da96603edc3239ed3a299097", - "reference": "22ae663c951bdc39da96603edc3239ed3a299097", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/ea779cb749a478b22a2564ac41cd7bda79c78dc7", + "reference": "ea779cb749a478b22a2564ac41cd7bda79c78dc7", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0", + "php": ">=7.3", "sebastian/object-reflector": "^2.0", "sebastian/recursion-context": "^4.0" }, @@ -2531,28 +2532,28 @@ "type": "github" } ], - "time": "2020-08-07T04:09:03+00:00" + "time": "2020-09-28T05:54:06+00:00" }, { "name": "sebastian/lines-of-code", - "version": "1.0.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "e02bf626f404b5daec382a7b8a6a4456e49017e5" + "reference": "6514b8f21906b8b46f520d1fbd17a4523fa59a54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e02bf626f404b5daec382a7b8a6a4456e49017e5", - "reference": "e02bf626f404b5daec382a7b8a6a4456e49017e5", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/6514b8f21906b8b46f520d1fbd17a4523fa59a54", + "reference": "6514b8f21906b8b46f520d1fbd17a4523fa59a54", "shasum": "" }, "require": { "nikic/php-parser": "^4.6", - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.2" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -2584,29 +2585,29 @@ "type": "github" } ], - "time": "2020-07-22T18:33:42+00:00" + "time": "2020-09-28T06:07:27+00:00" }, { "name": "sebastian/object-enumerator", - "version": "4.0.2", + "version": "4.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "074fed2d0a6d08e1677dd8ce9d32aecb384917b8" + "reference": "f6f5957013d84725427d361507e13513702888a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/074fed2d0a6d08e1677dd8ce9d32aecb384917b8", - "reference": "074fed2d0a6d08e1677dd8ce9d32aecb384917b8", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f6f5957013d84725427d361507e13513702888a4", + "reference": "f6f5957013d84725427d361507e13513702888a4", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0", + "php": ">=7.3", "sebastian/object-reflector": "^2.0", "sebastian/recursion-context": "^4.0" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -2637,27 +2638,27 @@ "type": "github" } ], - "time": "2020-06-26T12:11:32+00:00" + "time": "2020-09-28T05:55:06+00:00" }, { "name": "sebastian/object-reflector", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "127a46f6b057441b201253526f81d5406d6c7840" + "reference": "d9d0ab3b12acb1768bc1e0a89b23c90d2043cbe5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/127a46f6b057441b201253526f81d5406d6c7840", - "reference": "127a46f6b057441b201253526f81d5406d6c7840", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/d9d0ab3b12acb1768bc1e0a89b23c90d2043cbe5", + "reference": "d9d0ab3b12acb1768bc1e0a89b23c90d2043cbe5", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -2688,27 +2689,27 @@ "type": "github" } ], - "time": "2020-06-26T12:12:55+00:00" + "time": "2020-09-28T05:56:16+00:00" }, { "name": "sebastian/recursion-context", - "version": "4.0.2", + "version": "4.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "062231bf61d2b9448c4fa5a7643b5e1829c11d63" + "reference": "ed8c9cd355089134bc9cba421b5cfdd58f0eaef7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/062231bf61d2b9448c4fa5a7643b5e1829c11d63", - "reference": "062231bf61d2b9448c4fa5a7643b5e1829c11d63", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/ed8c9cd355089134bc9cba421b5cfdd58f0eaef7", + "reference": "ed8c9cd355089134bc9cba421b5cfdd58f0eaef7", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -2747,24 +2748,24 @@ "type": "github" } ], - "time": "2020-06-26T12:14:17+00:00" + "time": "2020-09-28T05:17:32+00:00" }, { "name": "sebastian/resource-operations", - "version": "3.0.2", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0653718a5a629b065e91f774595267f8dc32e213" + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0653718a5a629b065e91f774595267f8dc32e213", - "reference": "0653718a5a629b065e91f774595267f8dc32e213", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.0" @@ -2798,32 +2799,32 @@ "type": "github" } ], - "time": "2020-06-26T12:16:22+00:00" + "time": "2020-09-28T06:45:17+00:00" }, { "name": "sebastian/type", - "version": "2.2.1", + "version": "2.3.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "86991e2b33446cd96e648c18bcdb1e95afb2c05a" + "reference": "fa592377f3923946cb90bf1f6a71ba2e5f229909" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/86991e2b33446cd96e648c18bcdb1e95afb2c05a", - "reference": "86991e2b33446cd96e648c18bcdb1e95afb2c05a", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fa592377f3923946cb90bf1f6a71ba2e5f229909", + "reference": "fa592377f3923946cb90bf1f6a71ba2e5f229909", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.2" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-master": "2.3-dev" } }, "autoload": { @@ -2850,24 +2851,24 @@ "type": "github" } ], - "time": "2020-07-05T08:31:53+00:00" + "time": "2020-10-06T08:41:03+00:00" }, { "name": "sebastian/version", - "version": "3.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "626586115d0ed31cb71483be55beb759b5af5a3c" + "reference": "c6c1022351a901512170118436c764e473f6de8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/626586115d0ed31cb71483be55beb759b5af5a3c", - "reference": "626586115d0ed31cb71483be55beb759b5af5a3c", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "type": "library", "extra": { @@ -2899,7 +2900,7 @@ "type": "github" } ], - "time": "2020-06-26T12:18:43+00:00" + "time": "2020-09-28T06:39:44+00:00" }, { "name": "symfony/polyfill-ctype", From aa00bd5e3112b6058a104a21325a120325e9374e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 13 Oct 2020 17:39:24 +0100 Subject: [PATCH 1947/3224] Updated phpstan to 0.12.49 --- composer.json | 2 +- composer.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index dfde4eaf02..112f65676f 100644 --- a/composer.json +++ b/composer.json @@ -50,7 +50,7 @@ "respect/validation": "^2.0" }, "require-dev": { - "phpstan/phpstan": "0.12.47", + "phpstan/phpstan": "0.12.49", "phpstan/phpstan-phpunit": "^0.12.6", "phpstan/phpstan-strict-rules": "^0.12.2", "phpunit/phpunit": "^9.2" diff --git a/composer.lock b/composer.lock index caffb42ad5..a2552124f8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3e1dac93b1419cf95ea65babb8aa44d9", + "content-hash": "7fdb5abb5388f1e92229efff1f783d40", "packages": [ { "name": "adhocore/json-comment", @@ -1444,16 +1444,16 @@ }, { "name": "phpstan/phpstan", - "version": "0.12.47", + "version": "0.12.49", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "74325a6ae15378db0df71b969ded245378d2e058" + "reference": "9a6136c2b39d5214da78de37128d5fe08e5d5b05" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/74325a6ae15378db0df71b969ded245378d2e058", - "reference": "74325a6ae15378db0df71b969ded245378d2e058", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9a6136c2b39d5214da78de37128d5fe08e5d5b05", + "reference": "9a6136c2b39d5214da78de37128d5fe08e5d5b05", "shasum": "" }, "require": { @@ -1496,7 +1496,7 @@ "type": "tidelift" } ], - "time": "2020-09-29T13:35:39+00:00" + "time": "2020-10-12T14:10:44+00:00" }, { "name": "phpstan/phpstan-phpunit", From e8ec65766c653b6a24603e8ea46f1b04fb3388ab Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 13 Oct 2020 17:52:47 +0100 Subject: [PATCH 1948/3224] Updated resources/locale to pmmp/Language@884a0496c3c1099b8ded991cb6708dbe8cbbf53e --- resources/locale | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/locale b/resources/locale index 157abfa5a2..884a0496c3 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 157abfa5a2ae85325fb254ec3ca19373116bb6af +Subproject commit 884a0496c3c1099b8ded991cb6708dbe8cbbf53e From cc91cbd8c5dc316634f36c61b2bf9cbd927eba72 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 13 Oct 2020 17:53:31 +0100 Subject: [PATCH 1949/3224] Updated build/php submodule to pmmp/php-build-scripts@bc8e1cf0015d9c74feaecdb5bf6c3bf9b9e80489 --- build/php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/php b/build/php index 0eb28b8b66..bc8e1cf001 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit 0eb28b8b66bef892c04b7d1d7bf9059b4e2ca600 +Subproject commit bc8e1cf0015d9c74feaecdb5bf6c3bf9b9e80489 From 3aca03d262527b567a72ad616e251d89b473f05d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 13 Oct 2020 18:17:12 +0100 Subject: [PATCH 1950/3224] Player: clean up refs when forced chunk unload is detected this might happen because of a plugin, or low memory condition. --- src/player/Player.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/player/Player.php b/src/player/Player.php index 5c97049fb5..c7704d690d 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2348,6 +2348,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ use ChunkListenerNoOpTrait { onChunkChanged as private; + onChunkUnloaded as private; } public function onChunkChanged(Chunk $chunk) : void{ @@ -2356,4 +2357,11 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->nextChunkOrderRun = 0; } } + + public function onChunkUnloaded(Chunk $chunk) : void{ + if($this->isUsingChunk($chunk->getX(), $chunk->getZ())){ + $this->logger->debug("Detected forced unload of chunk " . $chunk->getX() . " " . $chunk->getZ()); + $this->unloadChunk($chunk->getX(), $chunk->getZ()); + } + } } From 0ef0848c44bc9f667cd4d80fcde5658835355b42 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Oct 2020 14:25:15 +0100 Subject: [PATCH 1951/3224] Concrete and ConcretePowder colour is now dynamic --- src/block/BlockFactory.php | 4 +- src/block/Concrete.php | 2 + src/block/ConcretePowder.php | 4 +- src/block/VanillaBlocks.php | 68 ++----------------- src/block/utils/ColorInMetadataTrait.php | 59 ++++++++++++++++ src/block/utils/ColoredTrait.php | 37 ++++++++++ .../block_factory_consistency_check.json | 2 +- 7 files changed, 108 insertions(+), 68 deletions(-) create mode 100644 src/block/utils/ColorInMetadataTrait.php create mode 100644 src/block/utils/ColoredTrait.php diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index bc2c34bb4e..988f2672ea 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -470,8 +470,6 @@ class BlockFactory{ return $color->getDisplayName() . " " . $name; }; $this->register(new Carpet(new BID(Ids::CARPET, $colorIdMap->toId($color)), $coloredName("Carpet"))); - $this->register(new Concrete(new BID(Ids::CONCRETE, $colorIdMap->toId($color)), $coloredName("Concrete"))); - $this->register(new ConcretePowder(new BID(Ids::CONCRETE_POWDER, $colorIdMap->toId($color)), $coloredName("Concrete Powder"))); $this->register(new Glass(new BID(Ids::STAINED_GLASS, $colorIdMap->toId($color)), $coloredName("Stained Glass"))); $this->register(new GlassPane(new BID(Ids::STAINED_GLASS_PANE, $colorIdMap->toId($color)), $coloredName("Stained Glass Pane"))); $this->register(new GlazedTerracotta(BlockLegacyIdHelper::getGlazedTerracottaIdentifier($color), $coloredName("Glazed Terracotta"))); @@ -480,6 +478,8 @@ class BlockFactory{ $this->register(new HardenedGlassPane(new BID(Ids::HARD_STAINED_GLASS_PANE, $colorIdMap->toId($color)), "Hardened " . $coloredName("Stained Glass Pane"))); $this->register(new Wool(new BID(Ids::WOOL, $colorIdMap->toId($color)), $coloredName("Wool"))); } + $this->register(new Concrete(new BID(Ids::CONCRETE), "Concrete")); + $this->register(new ConcretePowder(new BID(Ids::CONCRETE_POWDER), "Concrete Powder")); $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_ANDESITE), "Andesite Wall")); $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_BRICK), "Brick Wall")); diff --git a/src/block/Concrete.php b/src/block/Concrete.php index 67c18a4c85..1201c9c2b0 100644 --- a/src/block/Concrete.php +++ b/src/block/Concrete.php @@ -23,9 +23,11 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\ColorInMetadataTrait; use pocketmine\item\ToolTier; class Concrete extends Opaque{ + use ColorInMetadataTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); diff --git a/src/block/ConcretePowder.php b/src/block/ConcretePowder.php index 5813965863..ab44e9491f 100644 --- a/src/block/ConcretePowder.php +++ b/src/block/ConcretePowder.php @@ -23,11 +23,13 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\ColorInMetadataTrait; use pocketmine\block\utils\Fallable; use pocketmine\block\utils\FallableTrait; use pocketmine\math\Facing; class ConcretePowder extends Opaque implements Fallable{ + use ColorInMetadataTrait; use FallableTrait { onNearbyBlockChange as protected startFalling; } @@ -54,7 +56,7 @@ class ConcretePowder extends Opaque implements Fallable{ continue; } if($this->getSide($i) instanceof Water){ - return BlockFactory::getInstance()->get(BlockLegacyIds::CONCRETE, $this->idInfo->getVariant()); + return VanillaBlocks::CONCRETE()->setColor($this->color); } } diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index bf5f10735e..ca722ac9d4 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -79,16 +79,12 @@ use function assert; * @method static WallSign BIRCH_WALL_SIGN() * @method static Wood BIRCH_WOOD() * @method static Carpet BLACK_CARPET() - * @method static Concrete BLACK_CONCRETE() - * @method static ConcretePowder BLACK_CONCRETE_POWDER() * @method static GlazedTerracotta BLACK_GLAZED_TERRACOTTA() * @method static HardenedClay BLACK_STAINED_CLAY() * @method static Glass BLACK_STAINED_GLASS() * @method static GlassPane BLACK_STAINED_GLASS_PANE() * @method static Wool BLACK_WOOL() * @method static Carpet BLUE_CARPET() - * @method static Concrete BLUE_CONCRETE() - * @method static ConcretePowder BLUE_CONCRETE_POWDER() * @method static GlazedTerracotta BLUE_GLAZED_TERRACOTTA() * @method static BlueIce BLUE_ICE() * @method static Flower BLUE_ORCHID() @@ -105,8 +101,6 @@ use function assert; * @method static Wall BRICK_WALL() * @method static Opaque BRICKS() * @method static Carpet BROWN_CARPET() - * @method static Concrete BROWN_CONCRETE() - * @method static ConcretePowder BROWN_CONCRETE_POWDER() * @method static GlazedTerracotta BROWN_GLAZED_TERRACOTTA() * @method static BrownMushroom BROWN_MUSHROOM() * @method static BrownMushroomBlock BROWN_MUSHROOM_BLOCK() @@ -135,6 +129,8 @@ use function assert; * @method static Cobweb COBWEB() * @method static CocoaBlock COCOA_POD() * @method static ChemistryTable COMPOUND_CREATOR() + * @method static Concrete CONCRETE() + * @method static ConcretePowder CONCRETE_POWDER() * @method static Flower CORNFLOWER() * @method static Opaque CRACKED_STONE_BRICKS() * @method static CraftingTable CRAFTING_TABLE() @@ -143,8 +139,6 @@ use function assert; * @method static Opaque CUT_SANDSTONE() * @method static Slab CUT_SANDSTONE_SLAB() * @method static Carpet CYAN_CARPET() - * @method static Concrete CYAN_CONCRETE() - * @method static ConcretePowder CYAN_CONCRETE_POWDER() * @method static GlazedTerracotta CYAN_GLAZED_TERRACOTTA() * @method static HardenedClay CYAN_STAINED_CLAY() * @method static Glass CYAN_STAINED_GLASS() @@ -334,16 +328,12 @@ use function assert; * @method static GrassPath GRASS_PATH() * @method static Gravel GRAVEL() * @method static Carpet GRAY_CARPET() - * @method static Concrete GRAY_CONCRETE() - * @method static ConcretePowder GRAY_CONCRETE_POWDER() * @method static GlazedTerracotta GRAY_GLAZED_TERRACOTTA() * @method static HardenedClay GRAY_STAINED_CLAY() * @method static Glass GRAY_STAINED_GLASS() * @method static GlassPane GRAY_STAINED_GLASS_PANE() * @method static Wool GRAY_WOOL() * @method static Carpet GREEN_CARPET() - * @method static Concrete GREEN_CONCRETE() - * @method static ConcretePowder GREEN_CONCRETE_POWDER() * @method static GlazedTerracotta GREEN_GLAZED_TERRACOTTA() * @method static HardenedClay GREEN_STAINED_CLAY() * @method static Glass GREEN_STAINED_GLASS() @@ -429,16 +419,12 @@ use function assert; * @method static Opaque LEGACY_STONECUTTER() * @method static Lever LEVER() * @method static Carpet LIGHT_BLUE_CARPET() - * @method static Concrete LIGHT_BLUE_CONCRETE() - * @method static ConcretePowder LIGHT_BLUE_CONCRETE_POWDER() * @method static GlazedTerracotta LIGHT_BLUE_GLAZED_TERRACOTTA() * @method static HardenedClay LIGHT_BLUE_STAINED_CLAY() * @method static Glass LIGHT_BLUE_STAINED_GLASS() * @method static GlassPane LIGHT_BLUE_STAINED_GLASS_PANE() * @method static Wool LIGHT_BLUE_WOOL() * @method static Carpet LIGHT_GRAY_CARPET() - * @method static Concrete LIGHT_GRAY_CONCRETE() - * @method static ConcretePowder LIGHT_GRAY_CONCRETE_POWDER() * @method static GlazedTerracotta LIGHT_GRAY_GLAZED_TERRACOTTA() * @method static HardenedClay LIGHT_GRAY_STAINED_CLAY() * @method static Glass LIGHT_GRAY_STAINED_GLASS() @@ -448,8 +434,6 @@ use function assert; * @method static Flower LILY_OF_THE_VALLEY() * @method static WaterLily LILY_PAD() * @method static Carpet LIME_CARPET() - * @method static Concrete LIME_CONCRETE() - * @method static ConcretePowder LIME_CONCRETE_POWDER() * @method static GlazedTerracotta LIME_GLAZED_TERRACOTTA() * @method static HardenedClay LIME_STAINED_CLAY() * @method static Glass LIME_STAINED_GLASS() @@ -457,8 +441,6 @@ use function assert; * @method static Wool LIME_WOOL() * @method static LitPumpkin LIT_PUMPKIN() * @method static Carpet MAGENTA_CARPET() - * @method static Concrete MAGENTA_CONCRETE() - * @method static ConcretePowder MAGENTA_CONCRETE_POWDER() * @method static GlazedTerracotta MAGENTA_GLAZED_TERRACOTTA() * @method static HardenedClay MAGENTA_STAINED_CLAY() * @method static Glass MAGENTA_STAINED_GLASS() @@ -508,8 +490,6 @@ use function assert; * @method static Wood OAK_WOOD() * @method static Opaque OBSIDIAN() * @method static Carpet ORANGE_CARPET() - * @method static Concrete ORANGE_CONCRETE() - * @method static ConcretePowder ORANGE_CONCRETE_POWDER() * @method static GlazedTerracotta ORANGE_GLAZED_TERRACOTTA() * @method static HardenedClay ORANGE_STAINED_CLAY() * @method static Glass ORANGE_STAINED_GLASS() @@ -520,8 +500,6 @@ use function assert; * @method static PackedIce PACKED_ICE() * @method static DoublePlant PEONY() * @method static Carpet PINK_CARPET() - * @method static Concrete PINK_CONCRETE() - * @method static ConcretePowder PINK_CONCRETE_POWDER() * @method static GlazedTerracotta PINK_GLAZED_TERRACOTTA() * @method static HardenedClay PINK_STAINED_CLAY() * @method static Glass PINK_STAINED_GLASS() @@ -551,8 +529,6 @@ use function assert; * @method static Opaque PUMPKIN() * @method static PumpkinStem PUMPKIN_STEM() * @method static Carpet PURPLE_CARPET() - * @method static Concrete PURPLE_CONCRETE() - * @method static ConcretePowder PURPLE_CONCRETE_POWDER() * @method static GlazedTerracotta PURPLE_GLAZED_TERRACOTTA() * @method static HardenedClay PURPLE_STAINED_CLAY() * @method static Glass PURPLE_STAINED_GLASS() @@ -569,8 +545,6 @@ use function assert; * @method static Stair QUARTZ_STAIRS() * @method static Rail RAIL() * @method static Carpet RED_CARPET() - * @method static Concrete RED_CONCRETE() - * @method static ConcretePowder RED_CONCRETE_POWDER() * @method static GlazedTerracotta RED_GLAZED_TERRACOTTA() * @method static RedMushroom RED_MUSHROOM() * @method static RedMushroomBlock RED_MUSHROOM_BLOCK() @@ -660,8 +634,6 @@ use function assert; * @method static WeightedPressurePlateLight WEIGHTED_PRESSURE_PLATE_LIGHT() * @method static Wheat WHEAT() * @method static Carpet WHITE_CARPET() - * @method static Concrete WHITE_CONCRETE() - * @method static ConcretePowder WHITE_CONCRETE_POWDER() * @method static GlazedTerracotta WHITE_GLAZED_TERRACOTTA() * @method static HardenedClay WHITE_STAINED_CLAY() * @method static Glass WHITE_STAINED_GLASS() @@ -669,8 +641,6 @@ use function assert; * @method static Flower WHITE_TULIP() * @method static Wool WHITE_WOOL() * @method static Carpet YELLOW_CARPET() - * @method static Concrete YELLOW_CONCRETE() - * @method static ConcretePowder YELLOW_CONCRETE_POWDER() * @method static GlazedTerracotta YELLOW_GLAZED_TERRACOTTA() * @method static HardenedClay YELLOW_STAINED_CLAY() * @method static Glass YELLOW_STAINED_GLASS() @@ -754,16 +724,12 @@ final class VanillaBlocks{ self::register("birch_wall_sign", $factory->get(442, 2)); self::register("birch_wood", $factory->get(467, 2)); self::register("black_carpet", $factory->get(171, 15)); - self::register("black_concrete", $factory->get(236, 15)); - self::register("black_concrete_powder", $factory->get(237, 15)); self::register("black_glazed_terracotta", $factory->get(235, 2)); self::register("black_stained_clay", $factory->get(159, 15)); self::register("black_stained_glass", $factory->get(241, 15)); self::register("black_stained_glass_pane", $factory->get(160, 15)); self::register("black_wool", $factory->get(35, 15)); self::register("blue_carpet", $factory->get(171, 11)); - self::register("blue_concrete", $factory->get(236, 11)); - self::register("blue_concrete_powder", $factory->get(237, 11)); self::register("blue_glazed_terracotta", $factory->get(231, 2)); self::register("blue_ice", $factory->get(266)); self::register("blue_orchid", $factory->get(38, 1)); @@ -780,8 +746,6 @@ final class VanillaBlocks{ self::register("brick_wall", $factory->get(139, 6)); self::register("bricks", $factory->get(45)); self::register("brown_carpet", $factory->get(171, 12)); - self::register("brown_concrete", $factory->get(236, 12)); - self::register("brown_concrete_powder", $factory->get(237, 12)); self::register("brown_glazed_terracotta", $factory->get(232, 2)); self::register("brown_mushroom", $factory->get(39)); self::register("brown_mushroom_block", $factory->get(99)); @@ -810,6 +774,8 @@ final class VanillaBlocks{ self::register("cobweb", $factory->get(30)); self::register("cocoa_pod", $factory->get(127)); self::register("compound_creator", $factory->get(238)); + self::register("concrete", $factory->get(236)); + self::register("concrete_powder", $factory->get(237)); self::register("cornflower", $factory->get(38, 9)); self::register("cracked_stone_bricks", $factory->get(98, 2)); self::register("crafting_table", $factory->get(58)); @@ -818,8 +784,6 @@ final class VanillaBlocks{ self::register("cut_sandstone", $factory->get(24, 2)); self::register("cut_sandstone_slab", $factory->get(421, 3)); self::register("cyan_carpet", $factory->get(171, 9)); - self::register("cyan_concrete", $factory->get(236, 9)); - self::register("cyan_concrete_powder", $factory->get(237, 9)); self::register("cyan_glazed_terracotta", $factory->get(229, 2)); self::register("cyan_stained_clay", $factory->get(159, 9)); self::register("cyan_stained_glass", $factory->get(241, 9)); @@ -1009,16 +973,12 @@ final class VanillaBlocks{ self::register("grass_path", $factory->get(198)); self::register("gravel", $factory->get(13)); self::register("gray_carpet", $factory->get(171, 7)); - self::register("gray_concrete", $factory->get(236, 7)); - self::register("gray_concrete_powder", $factory->get(237, 7)); self::register("gray_glazed_terracotta", $factory->get(227, 2)); self::register("gray_stained_clay", $factory->get(159, 7)); self::register("gray_stained_glass", $factory->get(241, 7)); self::register("gray_stained_glass_pane", $factory->get(160, 7)); self::register("gray_wool", $factory->get(35, 7)); self::register("green_carpet", $factory->get(171, 13)); - self::register("green_concrete", $factory->get(236, 13)); - self::register("green_concrete_powder", $factory->get(237, 13)); self::register("green_glazed_terracotta", $factory->get(233, 2)); self::register("green_stained_clay", $factory->get(159, 13)); self::register("green_stained_glass", $factory->get(241, 13)); @@ -1104,16 +1064,12 @@ final class VanillaBlocks{ self::register("legacy_stonecutter", $factory->get(245)); self::register("lever", $factory->get(69)); self::register("light_blue_carpet", $factory->get(171, 3)); - self::register("light_blue_concrete", $factory->get(236, 3)); - self::register("light_blue_concrete_powder", $factory->get(237, 3)); self::register("light_blue_glazed_terracotta", $factory->get(223, 2)); self::register("light_blue_stained_clay", $factory->get(159, 3)); self::register("light_blue_stained_glass", $factory->get(241, 3)); self::register("light_blue_stained_glass_pane", $factory->get(160, 3)); self::register("light_blue_wool", $factory->get(35, 3)); self::register("light_gray_carpet", $factory->get(171, 8)); - self::register("light_gray_concrete", $factory->get(236, 8)); - self::register("light_gray_concrete_powder", $factory->get(237, 8)); self::register("light_gray_glazed_terracotta", $factory->get(228, 2)); self::register("light_gray_stained_clay", $factory->get(159, 8)); self::register("light_gray_stained_glass", $factory->get(241, 8)); @@ -1123,8 +1079,6 @@ final class VanillaBlocks{ self::register("lily_of_the_valley", $factory->get(38, 10)); self::register("lily_pad", $factory->get(111)); self::register("lime_carpet", $factory->get(171, 5)); - self::register("lime_concrete", $factory->get(236, 5)); - self::register("lime_concrete_powder", $factory->get(237, 5)); self::register("lime_glazed_terracotta", $factory->get(225, 2)); self::register("lime_stained_clay", $factory->get(159, 5)); self::register("lime_stained_glass", $factory->get(241, 5)); @@ -1132,8 +1086,6 @@ final class VanillaBlocks{ self::register("lime_wool", $factory->get(35, 5)); self::register("lit_pumpkin", $factory->get(91)); self::register("magenta_carpet", $factory->get(171, 2)); - self::register("magenta_concrete", $factory->get(236, 2)); - self::register("magenta_concrete_powder", $factory->get(237, 2)); self::register("magenta_glazed_terracotta", $factory->get(222, 2)); self::register("magenta_stained_clay", $factory->get(159, 2)); self::register("magenta_stained_glass", $factory->get(241, 2)); @@ -1183,8 +1135,6 @@ final class VanillaBlocks{ self::register("oak_wood", $factory->get(467)); self::register("obsidian", $factory->get(49)); self::register("orange_carpet", $factory->get(171, 1)); - self::register("orange_concrete", $factory->get(236, 1)); - self::register("orange_concrete_powder", $factory->get(237, 1)); self::register("orange_glazed_terracotta", $factory->get(221, 2)); self::register("orange_stained_clay", $factory->get(159, 1)); self::register("orange_stained_glass", $factory->get(241, 1)); @@ -1195,8 +1145,6 @@ final class VanillaBlocks{ self::register("packed_ice", $factory->get(174)); self::register("peony", $factory->get(175, 5)); self::register("pink_carpet", $factory->get(171, 6)); - self::register("pink_concrete", $factory->get(236, 6)); - self::register("pink_concrete_powder", $factory->get(237, 6)); self::register("pink_glazed_terracotta", $factory->get(226, 2)); self::register("pink_stained_clay", $factory->get(159, 6)); self::register("pink_stained_glass", $factory->get(241, 6)); @@ -1226,8 +1174,6 @@ final class VanillaBlocks{ self::register("pumpkin", $factory->get(86)); self::register("pumpkin_stem", $factory->get(104)); self::register("purple_carpet", $factory->get(171, 10)); - self::register("purple_concrete", $factory->get(236, 10)); - self::register("purple_concrete_powder", $factory->get(237, 10)); self::register("purple_glazed_terracotta", $factory->get(219, 2)); self::register("purple_stained_clay", $factory->get(159, 10)); self::register("purple_stained_glass", $factory->get(241, 10)); @@ -1244,8 +1190,6 @@ final class VanillaBlocks{ self::register("quartz_stairs", $factory->get(156)); self::register("rail", $factory->get(66)); self::register("red_carpet", $factory->get(171, 14)); - self::register("red_concrete", $factory->get(236, 14)); - self::register("red_concrete_powder", $factory->get(237, 14)); self::register("red_glazed_terracotta", $factory->get(234, 2)); self::register("red_mushroom", $factory->get(40)); self::register("red_mushroom_block", $factory->get(100)); @@ -1335,8 +1279,6 @@ final class VanillaBlocks{ self::register("weighted_pressure_plate_light", $factory->get(147)); self::register("wheat", $factory->get(59)); self::register("white_carpet", $factory->get(171)); - self::register("white_concrete", $factory->get(236)); - self::register("white_concrete_powder", $factory->get(237)); self::register("white_glazed_terracotta", $factory->get(220, 2)); self::register("white_stained_clay", $factory->get(159)); self::register("white_stained_glass", $factory->get(241)); @@ -1344,8 +1286,6 @@ final class VanillaBlocks{ self::register("white_tulip", $factory->get(38, 6)); self::register("white_wool", $factory->get(35)); self::register("yellow_carpet", $factory->get(171, 4)); - self::register("yellow_concrete", $factory->get(236, 4)); - self::register("yellow_concrete_powder", $factory->get(237, 4)); self::register("yellow_glazed_terracotta", $factory->get(224, 2)); self::register("yellow_stained_clay", $factory->get(159, 4)); self::register("yellow_stained_glass", $factory->get(241, 4)); diff --git a/src/block/utils/ColorInMetadataTrait.php b/src/block/utils/ColorInMetadataTrait.php new file mode 100644 index 0000000000..7687bbb715 --- /dev/null +++ b/src/block/utils/ColorInMetadataTrait.php @@ -0,0 +1,59 @@ +color = DyeColorIdMap::getInstance()->fromId($stateMeta); + } + + /** + * @see Block::writeStateToMeta() + */ + protected function writeStateToMeta() : int{ + return DyeColorIdMap::getInstance()->toId($this->color); + } + + /** + * @see Block::getStateBitmask() + */ + public function getStateBitmask() : int{ + return 0b1111; + } + + /** + * @see Block::getNonPersistentStateBitmask() + */ + public function getNonPersistentStateBitmask() : int{ + return 0; + } +} diff --git a/src/block/utils/ColoredTrait.php b/src/block/utils/ColoredTrait.php new file mode 100644 index 0000000000..922245f9f7 --- /dev/null +++ b/src/block/utils/ColoredTrait.php @@ -0,0 +1,37 @@ +color; } + + /** @return $this */ + public function setColor(DyeColor $color) : self{ + $this->color = $color; + return $this; + } +} diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 6ce444bc87..d4a7304a91 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"White Concrete","3777":"Orange Concrete","3778":"Magenta Concrete","3779":"Light Blue Concrete","3780":"Yellow Concrete","3781":"Lime Concrete","3782":"Pink Concrete","3783":"Gray Concrete","3784":"Light Gray Concrete","3785":"Cyan Concrete","3786":"Purple Concrete","3787":"Blue Concrete","3788":"Brown Concrete","3789":"Green Concrete","3790":"Red Concrete","3791":"Black Concrete","3792":"White Concrete Powder","3793":"Orange Concrete Powder","3794":"Magenta Concrete Powder","3795":"Light Blue Concrete Powder","3796":"Yellow Concrete Powder","3797":"Lime Concrete Powder","3798":"Pink Concrete Powder","3799":"Gray Concrete Powder","3800":"Light Gray Concrete Powder","3801":"Cyan Concrete Powder","3802":"Purple Concrete Powder","3803":"Blue Concrete Powder","3804":"Brown Concrete Powder","3805":"Green Concrete Powder","3806":"Red Concrete Powder","3807":"Black Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From 792f38f4746baf2299f72ae31445680d3f6455e4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Oct 2020 14:45:01 +0100 Subject: [PATCH 1952/3224] Carpet and Wool now have dynamic colours --- src/block/BlockFactory.php | 4 +- src/block/Carpet.php | 2 + src/block/VanillaBlocks.php | 68 ++----------------- src/block/Wool.php | 2 + .../block_factory_consistency_check.json | 2 +- 5 files changed, 11 insertions(+), 67 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 988f2672ea..6466b8c4db 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -469,17 +469,17 @@ class BlockFactory{ $coloredName = function(string $name) use($color) : string{ return $color->getDisplayName() . " " . $name; }; - $this->register(new Carpet(new BID(Ids::CARPET, $colorIdMap->toId($color)), $coloredName("Carpet"))); $this->register(new Glass(new BID(Ids::STAINED_GLASS, $colorIdMap->toId($color)), $coloredName("Stained Glass"))); $this->register(new GlassPane(new BID(Ids::STAINED_GLASS_PANE, $colorIdMap->toId($color)), $coloredName("Stained Glass Pane"))); $this->register(new GlazedTerracotta(BlockLegacyIdHelper::getGlazedTerracottaIdentifier($color), $coloredName("Glazed Terracotta"))); $this->register(new HardenedClay(new BID(Ids::STAINED_CLAY, $colorIdMap->toId($color)), $coloredName("Stained Clay"))); $this->register(new HardenedGlass(new BID(Ids::HARD_STAINED_GLASS, $colorIdMap->toId($color)), "Hardened " . $coloredName("Stained Glass"))); $this->register(new HardenedGlassPane(new BID(Ids::HARD_STAINED_GLASS_PANE, $colorIdMap->toId($color)), "Hardened " . $coloredName("Stained Glass Pane"))); - $this->register(new Wool(new BID(Ids::WOOL, $colorIdMap->toId($color)), $coloredName("Wool"))); } + $this->register(new Carpet(new BID(Ids::CARPET), "Carpet")); $this->register(new Concrete(new BID(Ids::CONCRETE), "Concrete")); $this->register(new ConcretePowder(new BID(Ids::CONCRETE_POWDER), "Concrete Powder")); + $this->register(new Wool(new BID(Ids::WOOL), "Wool")); $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_ANDESITE), "Andesite Wall")); $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_BRICK), "Brick Wall")); diff --git a/src/block/Carpet.php b/src/block/Carpet.php index 0a430b023e..ba6d243511 100644 --- a/src/block/Carpet.php +++ b/src/block/Carpet.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\ColorInMetadataTrait; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -31,6 +32,7 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Carpet extends Flowable{ + use ColorInMetadataTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.1)); diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index ca722ac9d4..02c4c5a11a 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -78,13 +78,10 @@ use function assert; * @method static WoodenTrapdoor BIRCH_TRAPDOOR() * @method static WallSign BIRCH_WALL_SIGN() * @method static Wood BIRCH_WOOD() - * @method static Carpet BLACK_CARPET() * @method static GlazedTerracotta BLACK_GLAZED_TERRACOTTA() * @method static HardenedClay BLACK_STAINED_CLAY() * @method static Glass BLACK_STAINED_GLASS() * @method static GlassPane BLACK_STAINED_GLASS_PANE() - * @method static Wool BLACK_WOOL() - * @method static Carpet BLUE_CARPET() * @method static GlazedTerracotta BLUE_GLAZED_TERRACOTTA() * @method static BlueIce BLUE_ICE() * @method static Flower BLUE_ORCHID() @@ -92,7 +89,6 @@ use function assert; * @method static Glass BLUE_STAINED_GLASS() * @method static GlassPane BLUE_STAINED_GLASS_PANE() * @method static Torch BLUE_TORCH() - * @method static Wool BLUE_WOOL() * @method static BoneBlock BONE_BLOCK() * @method static Bookshelf BOOKSHELF() * @method static BrewingStand BREWING_STAND() @@ -100,16 +96,15 @@ use function assert; * @method static Stair BRICK_STAIRS() * @method static Wall BRICK_WALL() * @method static Opaque BRICKS() - * @method static Carpet BROWN_CARPET() * @method static GlazedTerracotta BROWN_GLAZED_TERRACOTTA() * @method static BrownMushroom BROWN_MUSHROOM() * @method static BrownMushroomBlock BROWN_MUSHROOM_BLOCK() * @method static HardenedClay BROWN_STAINED_CLAY() * @method static Glass BROWN_STAINED_GLASS() * @method static GlassPane BROWN_STAINED_GLASS_PANE() - * @method static Wool BROWN_WOOL() * @method static Cactus CACTUS() * @method static Cake CAKE() + * @method static Carpet CARPET() * @method static Carrot CARROTS() * @method static CarvedPumpkin CARVED_PUMPKIN() * @method static ChemicalHeat CHEMICAL_HEAT() @@ -138,12 +133,10 @@ use function assert; * @method static Slab CUT_RED_SANDSTONE_SLAB() * @method static Opaque CUT_SANDSTONE() * @method static Slab CUT_SANDSTONE_SLAB() - * @method static Carpet CYAN_CARPET() * @method static GlazedTerracotta CYAN_GLAZED_TERRACOTTA() * @method static HardenedClay CYAN_STAINED_CLAY() * @method static Glass CYAN_STAINED_GLASS() * @method static GlassPane CYAN_STAINED_GLASS_PANE() - * @method static Wool CYAN_WOOL() * @method static Flower DANDELION() * @method static WoodenButton DARK_OAK_BUTTON() * @method static WoodenDoor DARK_OAK_DOOR() @@ -327,19 +320,15 @@ use function assert; * @method static Grass GRASS() * @method static GrassPath GRASS_PATH() * @method static Gravel GRAVEL() - * @method static Carpet GRAY_CARPET() * @method static GlazedTerracotta GRAY_GLAZED_TERRACOTTA() * @method static HardenedClay GRAY_STAINED_CLAY() * @method static Glass GRAY_STAINED_GLASS() * @method static GlassPane GRAY_STAINED_GLASS_PANE() - * @method static Wool GRAY_WOOL() - * @method static Carpet GREEN_CARPET() * @method static GlazedTerracotta GREEN_GLAZED_TERRACOTTA() * @method static HardenedClay GREEN_STAINED_CLAY() * @method static Glass GREEN_STAINED_GLASS() * @method static GlassPane GREEN_STAINED_GLASS_PANE() * @method static Torch GREEN_TORCH() - * @method static Wool GREEN_WOOL() * @method static HardenedGlass HARDENED_BLACK_STAINED_GLASS() * @method static HardenedGlassPane HARDENED_BLACK_STAINED_GLASS_PANE() * @method static HardenedGlass HARDENED_BLUE_STAINED_GLASS() @@ -418,34 +407,26 @@ use function assert; * @method static Lava LAVA() * @method static Opaque LEGACY_STONECUTTER() * @method static Lever LEVER() - * @method static Carpet LIGHT_BLUE_CARPET() * @method static GlazedTerracotta LIGHT_BLUE_GLAZED_TERRACOTTA() * @method static HardenedClay LIGHT_BLUE_STAINED_CLAY() * @method static Glass LIGHT_BLUE_STAINED_GLASS() * @method static GlassPane LIGHT_BLUE_STAINED_GLASS_PANE() - * @method static Wool LIGHT_BLUE_WOOL() - * @method static Carpet LIGHT_GRAY_CARPET() * @method static GlazedTerracotta LIGHT_GRAY_GLAZED_TERRACOTTA() * @method static HardenedClay LIGHT_GRAY_STAINED_CLAY() * @method static Glass LIGHT_GRAY_STAINED_GLASS() * @method static GlassPane LIGHT_GRAY_STAINED_GLASS_PANE() - * @method static Wool LIGHT_GRAY_WOOL() * @method static DoublePlant LILAC() * @method static Flower LILY_OF_THE_VALLEY() * @method static WaterLily LILY_PAD() - * @method static Carpet LIME_CARPET() * @method static GlazedTerracotta LIME_GLAZED_TERRACOTTA() * @method static HardenedClay LIME_STAINED_CLAY() * @method static Glass LIME_STAINED_GLASS() * @method static GlassPane LIME_STAINED_GLASS_PANE() - * @method static Wool LIME_WOOL() * @method static LitPumpkin LIT_PUMPKIN() - * @method static Carpet MAGENTA_CARPET() * @method static GlazedTerracotta MAGENTA_GLAZED_TERRACOTTA() * @method static HardenedClay MAGENTA_STAINED_CLAY() * @method static Glass MAGENTA_STAINED_GLASS() * @method static GlassPane MAGENTA_STAINED_GLASS_PANE() - * @method static Wool MAGENTA_WOOL() * @method static Magma MAGMA() * @method static ChemistryTable MATERIAL_REDUCER() * @method static Melon MELON() @@ -489,23 +470,19 @@ use function assert; * @method static WallSign OAK_WALL_SIGN() * @method static Wood OAK_WOOD() * @method static Opaque OBSIDIAN() - * @method static Carpet ORANGE_CARPET() * @method static GlazedTerracotta ORANGE_GLAZED_TERRACOTTA() * @method static HardenedClay ORANGE_STAINED_CLAY() * @method static Glass ORANGE_STAINED_GLASS() * @method static GlassPane ORANGE_STAINED_GLASS_PANE() * @method static Flower ORANGE_TULIP() - * @method static Wool ORANGE_WOOL() * @method static Flower OXEYE_DAISY() * @method static PackedIce PACKED_ICE() * @method static DoublePlant PEONY() - * @method static Carpet PINK_CARPET() * @method static GlazedTerracotta PINK_GLAZED_TERRACOTTA() * @method static HardenedClay PINK_STAINED_CLAY() * @method static Glass PINK_STAINED_GLASS() * @method static GlassPane PINK_STAINED_GLASS_PANE() * @method static Flower PINK_TULIP() - * @method static Wool PINK_WOOL() * @method static Podzol PODZOL() * @method static Opaque POLISHED_ANDESITE() * @method static Slab POLISHED_ANDESITE_SLAB() @@ -528,13 +505,11 @@ use function assert; * @method static Wall PRISMARINE_WALL() * @method static Opaque PUMPKIN() * @method static PumpkinStem PUMPKIN_STEM() - * @method static Carpet PURPLE_CARPET() * @method static GlazedTerracotta PURPLE_GLAZED_TERRACOTTA() * @method static HardenedClay PURPLE_STAINED_CLAY() * @method static Glass PURPLE_STAINED_GLASS() * @method static GlassPane PURPLE_STAINED_GLASS_PANE() * @method static Torch PURPLE_TORCH() - * @method static Wool PURPLE_WOOL() * @method static Opaque PURPUR() * @method static Opaque PURPUR_PILLAR() * @method static Slab PURPUR_SLAB() @@ -544,7 +519,6 @@ use function assert; * @method static Slab QUARTZ_SLAB() * @method static Stair QUARTZ_STAIRS() * @method static Rail RAIL() - * @method static Carpet RED_CARPET() * @method static GlazedTerracotta RED_GLAZED_TERRACOTTA() * @method static RedMushroom RED_MUSHROOM() * @method static RedMushroomBlock RED_MUSHROOM_BLOCK() @@ -562,7 +536,6 @@ use function assert; * @method static GlassPane RED_STAINED_GLASS_PANE() * @method static Torch RED_TORCH() * @method static Flower RED_TULIP() - * @method static Wool RED_WOOL() * @method static Redstone REDSTONE() * @method static RedstoneComparator REDSTONE_COMPARATOR() * @method static RedstoneLamp REDSTONE_LAMP() @@ -633,19 +606,16 @@ use function assert; * @method static WeightedPressurePlateHeavy WEIGHTED_PRESSURE_PLATE_HEAVY() * @method static WeightedPressurePlateLight WEIGHTED_PRESSURE_PLATE_LIGHT() * @method static Wheat WHEAT() - * @method static Carpet WHITE_CARPET() * @method static GlazedTerracotta WHITE_GLAZED_TERRACOTTA() * @method static HardenedClay WHITE_STAINED_CLAY() * @method static Glass WHITE_STAINED_GLASS() * @method static GlassPane WHITE_STAINED_GLASS_PANE() * @method static Flower WHITE_TULIP() - * @method static Wool WHITE_WOOL() - * @method static Carpet YELLOW_CARPET() + * @method static Wool WOOL() * @method static GlazedTerracotta YELLOW_GLAZED_TERRACOTTA() * @method static HardenedClay YELLOW_STAINED_CLAY() * @method static Glass YELLOW_STAINED_GLASS() * @method static GlassPane YELLOW_STAINED_GLASS_PANE() - * @method static Wool YELLOW_WOOL() */ final class VanillaBlocks{ use CloningRegistryTrait; @@ -723,13 +693,10 @@ final class VanillaBlocks{ self::register("birch_trapdoor", $factory->get(401)); self::register("birch_wall_sign", $factory->get(442, 2)); self::register("birch_wood", $factory->get(467, 2)); - self::register("black_carpet", $factory->get(171, 15)); self::register("black_glazed_terracotta", $factory->get(235, 2)); self::register("black_stained_clay", $factory->get(159, 15)); self::register("black_stained_glass", $factory->get(241, 15)); self::register("black_stained_glass_pane", $factory->get(160, 15)); - self::register("black_wool", $factory->get(35, 15)); - self::register("blue_carpet", $factory->get(171, 11)); self::register("blue_glazed_terracotta", $factory->get(231, 2)); self::register("blue_ice", $factory->get(266)); self::register("blue_orchid", $factory->get(38, 1)); @@ -737,7 +704,6 @@ final class VanillaBlocks{ self::register("blue_stained_glass", $factory->get(241, 11)); self::register("blue_stained_glass_pane", $factory->get(160, 11)); self::register("blue_torch", $factory->get(204, 5)); - self::register("blue_wool", $factory->get(35, 11)); self::register("bone_block", $factory->get(216)); self::register("bookshelf", $factory->get(47)); self::register("brewing_stand", $factory->get(117)); @@ -745,16 +711,15 @@ final class VanillaBlocks{ self::register("brick_stairs", $factory->get(108)); self::register("brick_wall", $factory->get(139, 6)); self::register("bricks", $factory->get(45)); - self::register("brown_carpet", $factory->get(171, 12)); self::register("brown_glazed_terracotta", $factory->get(232, 2)); self::register("brown_mushroom", $factory->get(39)); self::register("brown_mushroom_block", $factory->get(99)); self::register("brown_stained_clay", $factory->get(159, 12)); self::register("brown_stained_glass", $factory->get(241, 12)); self::register("brown_stained_glass_pane", $factory->get(160, 12)); - self::register("brown_wool", $factory->get(35, 12)); self::register("cactus", $factory->get(81)); self::register("cake", $factory->get(92)); + self::register("carpet", $factory->get(171)); self::register("carrots", $factory->get(141)); self::register("carved_pumpkin", $factory->get(410)); self::register("chemical_heat", $factory->get(192)); @@ -783,12 +748,10 @@ final class VanillaBlocks{ self::register("cut_red_sandstone_slab", $factory->get(421, 4)); self::register("cut_sandstone", $factory->get(24, 2)); self::register("cut_sandstone_slab", $factory->get(421, 3)); - self::register("cyan_carpet", $factory->get(171, 9)); self::register("cyan_glazed_terracotta", $factory->get(229, 2)); self::register("cyan_stained_clay", $factory->get(159, 9)); self::register("cyan_stained_glass", $factory->get(241, 9)); self::register("cyan_stained_glass_pane", $factory->get(160, 9)); - self::register("cyan_wool", $factory->get(35, 9)); self::register("dandelion", $factory->get(37)); self::register("dark_oak_button", $factory->get(397)); self::register("dark_oak_door", $factory->get(197)); @@ -972,19 +935,15 @@ final class VanillaBlocks{ self::register("grass", $factory->get(2)); self::register("grass_path", $factory->get(198)); self::register("gravel", $factory->get(13)); - self::register("gray_carpet", $factory->get(171, 7)); self::register("gray_glazed_terracotta", $factory->get(227, 2)); self::register("gray_stained_clay", $factory->get(159, 7)); self::register("gray_stained_glass", $factory->get(241, 7)); self::register("gray_stained_glass_pane", $factory->get(160, 7)); - self::register("gray_wool", $factory->get(35, 7)); - self::register("green_carpet", $factory->get(171, 13)); self::register("green_glazed_terracotta", $factory->get(233, 2)); self::register("green_stained_clay", $factory->get(159, 13)); self::register("green_stained_glass", $factory->get(241, 13)); self::register("green_stained_glass_pane", $factory->get(160, 13)); self::register("green_torch", $factory->get(202, 13)); - self::register("green_wool", $factory->get(35, 13)); self::register("hardened_black_stained_glass", $factory->get(254, 15)); self::register("hardened_black_stained_glass_pane", $factory->get(191, 15)); self::register("hardened_blue_stained_glass", $factory->get(254, 11)); @@ -1063,34 +1022,26 @@ final class VanillaBlocks{ self::register("lava", $factory->get(10)); self::register("legacy_stonecutter", $factory->get(245)); self::register("lever", $factory->get(69)); - self::register("light_blue_carpet", $factory->get(171, 3)); self::register("light_blue_glazed_terracotta", $factory->get(223, 2)); self::register("light_blue_stained_clay", $factory->get(159, 3)); self::register("light_blue_stained_glass", $factory->get(241, 3)); self::register("light_blue_stained_glass_pane", $factory->get(160, 3)); - self::register("light_blue_wool", $factory->get(35, 3)); - self::register("light_gray_carpet", $factory->get(171, 8)); self::register("light_gray_glazed_terracotta", $factory->get(228, 2)); self::register("light_gray_stained_clay", $factory->get(159, 8)); self::register("light_gray_stained_glass", $factory->get(241, 8)); self::register("light_gray_stained_glass_pane", $factory->get(160, 8)); - self::register("light_gray_wool", $factory->get(35, 8)); self::register("lilac", $factory->get(175, 1)); self::register("lily_of_the_valley", $factory->get(38, 10)); self::register("lily_pad", $factory->get(111)); - self::register("lime_carpet", $factory->get(171, 5)); self::register("lime_glazed_terracotta", $factory->get(225, 2)); self::register("lime_stained_clay", $factory->get(159, 5)); self::register("lime_stained_glass", $factory->get(241, 5)); self::register("lime_stained_glass_pane", $factory->get(160, 5)); - self::register("lime_wool", $factory->get(35, 5)); self::register("lit_pumpkin", $factory->get(91)); - self::register("magenta_carpet", $factory->get(171, 2)); self::register("magenta_glazed_terracotta", $factory->get(222, 2)); self::register("magenta_stained_clay", $factory->get(159, 2)); self::register("magenta_stained_glass", $factory->get(241, 2)); self::register("magenta_stained_glass_pane", $factory->get(160, 2)); - self::register("magenta_wool", $factory->get(35, 2)); self::register("magma", $factory->get(213)); self::register("material_reducer", $factory->get(238, 4)); self::register("melon", $factory->get(103)); @@ -1134,23 +1085,19 @@ final class VanillaBlocks{ self::register("oak_wall_sign", $factory->get(68, 2)); self::register("oak_wood", $factory->get(467)); self::register("obsidian", $factory->get(49)); - self::register("orange_carpet", $factory->get(171, 1)); self::register("orange_glazed_terracotta", $factory->get(221, 2)); self::register("orange_stained_clay", $factory->get(159, 1)); self::register("orange_stained_glass", $factory->get(241, 1)); self::register("orange_stained_glass_pane", $factory->get(160, 1)); self::register("orange_tulip", $factory->get(38, 5)); - self::register("orange_wool", $factory->get(35, 1)); self::register("oxeye_daisy", $factory->get(38, 8)); self::register("packed_ice", $factory->get(174)); self::register("peony", $factory->get(175, 5)); - self::register("pink_carpet", $factory->get(171, 6)); self::register("pink_glazed_terracotta", $factory->get(226, 2)); self::register("pink_stained_clay", $factory->get(159, 6)); self::register("pink_stained_glass", $factory->get(241, 6)); self::register("pink_stained_glass_pane", $factory->get(160, 6)); self::register("pink_tulip", $factory->get(38, 7)); - self::register("pink_wool", $factory->get(35, 6)); self::register("podzol", $factory->get(243)); self::register("polished_andesite", $factory->get(1, 6)); self::register("polished_andesite_slab", $factory->get(417, 2)); @@ -1173,13 +1120,11 @@ final class VanillaBlocks{ self::register("prismarine_wall", $factory->get(139, 11)); self::register("pumpkin", $factory->get(86)); self::register("pumpkin_stem", $factory->get(104)); - self::register("purple_carpet", $factory->get(171, 10)); self::register("purple_glazed_terracotta", $factory->get(219, 2)); self::register("purple_stained_clay", $factory->get(159, 10)); self::register("purple_stained_glass", $factory->get(241, 10)); self::register("purple_stained_glass_pane", $factory->get(160, 10)); self::register("purple_torch", $factory->get(204, 13)); - self::register("purple_wool", $factory->get(35, 10)); self::register("purpur", $factory->get(201)); self::register("purpur_pillar", $factory->get(201, 2)); self::register("purpur_slab", $factory->get(182, 1)); @@ -1189,7 +1134,6 @@ final class VanillaBlocks{ self::register("quartz_slab", $factory->get(44, 6)); self::register("quartz_stairs", $factory->get(156)); self::register("rail", $factory->get(66)); - self::register("red_carpet", $factory->get(171, 14)); self::register("red_glazed_terracotta", $factory->get(234, 2)); self::register("red_mushroom", $factory->get(40)); self::register("red_mushroom_block", $factory->get(100)); @@ -1207,7 +1151,6 @@ final class VanillaBlocks{ self::register("red_stained_glass_pane", $factory->get(160, 14)); self::register("red_torch", $factory->get(202, 5)); self::register("red_tulip", $factory->get(38, 4)); - self::register("red_wool", $factory->get(35, 14)); self::register("redstone", $factory->get(152)); self::register("redstone_comparator", $factory->get(149)); self::register("redstone_lamp", $factory->get(123)); @@ -1278,18 +1221,15 @@ final class VanillaBlocks{ self::register("weighted_pressure_plate_heavy", $factory->get(148)); self::register("weighted_pressure_plate_light", $factory->get(147)); self::register("wheat", $factory->get(59)); - self::register("white_carpet", $factory->get(171)); self::register("white_glazed_terracotta", $factory->get(220, 2)); self::register("white_stained_clay", $factory->get(159)); self::register("white_stained_glass", $factory->get(241)); self::register("white_stained_glass_pane", $factory->get(160)); self::register("white_tulip", $factory->get(38, 6)); - self::register("white_wool", $factory->get(35)); - self::register("yellow_carpet", $factory->get(171, 4)); + self::register("wool", $factory->get(35)); self::register("yellow_glazed_terracotta", $factory->get(224, 2)); self::register("yellow_stained_clay", $factory->get(159, 4)); self::register("yellow_stained_glass", $factory->get(241, 4)); self::register("yellow_stained_glass_pane", $factory->get(160, 4)); - self::register("yellow_wool", $factory->get(35, 4)); } } diff --git a/src/block/Wool.php b/src/block/Wool.php index 0154424842..5a30defb1a 100644 --- a/src/block/Wool.php +++ b/src/block/Wool.php @@ -23,9 +23,11 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\ColorInMetadataTrait; use pocketmine\item\Item; class Wool extends Opaque{ + use ColorInMetadataTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new class(0.8, BlockToolType::SHEARS) extends BlockBreakInfo{ diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index d4a7304a91..d7b41b1b8c 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"White Wool","561":"Orange Wool","562":"Magenta Wool","563":"Light Blue Wool","564":"Yellow Wool","565":"Lime Wool","566":"Pink Wool","567":"Gray Wool","568":"Light Gray Wool","569":"Cyan Wool","570":"Purple Wool","571":"Blue Wool","572":"Brown Wool","573":"Green Wool","574":"Red Wool","575":"Black Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"White Carpet","2737":"Orange Carpet","2738":"Magenta Carpet","2739":"Light Blue Carpet","2740":"Yellow Carpet","2741":"Lime Carpet","2742":"Pink Carpet","2743":"Gray Carpet","2744":"Light Gray Carpet","2745":"Cyan Carpet","2746":"Purple Carpet","2747":"Blue Carpet","2748":"Brown Carpet","2749":"Green Carpet","2750":"Red Carpet","2751":"Black Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From d38791e27dcd028579b15c78bc5ede3171be73f4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 16 Oct 2020 21:10:57 +0100 Subject: [PATCH 1953/3224] Listener: Drop support for @softDepend annotation literally nobody uses this. I don't think anyone even knows it exists. It's also an obstacle to separating event handler registration from PluginManager. --- src/event/Listener.php | 3 --- src/plugin/PluginManager.php | 15 +++------------ 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/event/Listener.php b/src/event/Listener.php index 00d12c3f59..e39d0dcd99 100644 --- a/src/event/Listener.php +++ b/src/event/Listener.php @@ -43,9 +43,6 @@ use pocketmine\plugin\PluginManager; * Functions which meet the criteria can have the following annotations in their doc comments: * * - `@notHandler`: Marks a function as NOT being an event handler. Only needed if the function meets the above criteria. - * - `@softDepend [PluginName]`: Handler WILL NOT be registered if its event doesn't exist. Useful for soft-depending - * on plugin events. Plugin name is optional. - * Example: `@softDepend SimpleAuth` * - `@handleCancelled`: Cancelled events will STILL invoke this handler. * - `@priority `: Sets the priority at which this event handler will receive events. * Example: `@priority HIGHEST` diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 15002bbdd3..d1a0325f71 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -433,22 +433,13 @@ class PluginManager{ continue; } - $handlerClosure = $method->getClosure($listener); - - try{ - $eventClass = $parameters[0]->getClass(); - }catch(\ReflectionException $e){ //class doesn't exist - if(isset($tags["softDepend"]) && !isset($this->plugins[$tags["softDepend"]])){ - $this->server->getLogger()->debug("Not registering @softDepend listener " . Utils::getNiceClosureName($handlerClosure) . "() because plugin \"" . $tags["softDepend"] . "\" not found"); - continue; - } - - throw $e; - } + $eventClass = $parameters[0]->getClass(); if($eventClass === null or !$eventClass->isSubclassOf(Event::class)){ continue; } + $handlerClosure = $method->getClosure($listener); + try{ $priority = isset($tags["priority"]) ? EventPriority::fromString($tags["priority"]) : EventPriority::NORMAL; }catch(\InvalidArgumentException $e){ From de6d260b760e8c9e29fe6d9835f5b4d351af84e2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 17 Oct 2020 15:05:55 +0100 Subject: [PATCH 1954/3224] Fixed cactus and sugarcane trying to grow past the top of the world --- src/block/Cactus.php | 3 +++ src/block/Sugarcane.php | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/block/Cactus.php b/src/block/Cactus.php index 6a24b8c2ef..3062dbb823 100644 --- a/src/block/Cactus.php +++ b/src/block/Cactus.php @@ -97,6 +97,9 @@ class Cactus extends Transparent{ if(!$this->getSide(Facing::DOWN)->isSameType($this)){ if($this->age === 15){ for($y = 1; $y < 3; ++$y){ + if(!$this->pos->getWorld()->isInWorld($this->pos->x, $this->pos->y + $y, $this->pos->z)){ + break; + } $b = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z); if($b->getId() === BlockLegacyIds::AIR){ $ev = new BlockGrowEvent($b, VanillaBlocks::CACTUS()); diff --git a/src/block/Sugarcane.php b/src/block/Sugarcane.php index d66c84bfbd..4014f138bc 100644 --- a/src/block/Sugarcane.php +++ b/src/block/Sugarcane.php @@ -57,6 +57,9 @@ class Sugarcane extends Flowable{ if($item instanceof Fertilizer){ if(!$this->getSide(Facing::DOWN)->isSameType($this)){ for($y = 1; $y < 3; ++$y){ + if(!$this->pos->getWorld()->isInWorld($this->pos->x, $this->pos->y + $y, $this->pos->z)){ + break; + } $b = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z); if($b->getId() === BlockLegacyIds::AIR){ $ev = new BlockGrowEvent($b, VanillaBlocks::SUGARCANE()); From 2d839db47e6bf180401d7e9242b2f9ecd8f1a928 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 17 Oct 2020 16:05:38 +0100 Subject: [PATCH 1955/3224] fixed build failure --- tests/phpstan/configs/l7-baseline.neon | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index b32e55fa7f..5471627494 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -90,6 +90,21 @@ parameters: count: 1 path: ../../../src/block/Block.php + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Cactus.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Cactus.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Cactus.php + - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 1 @@ -395,6 +410,21 @@ parameters: count: 1 path: ../../../src/block/SnowLayer.php + - + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Sugarcane.php + + - + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Sugarcane.php + + - + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" + count: 1 + path: ../../../src/block/Sugarcane.php + - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 2 From 0f9d5f70113fded96aa823d2881f1edc9914f987 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 17 Oct 2020 16:09:30 +0100 Subject: [PATCH 1956/3224] ext-morton is now required and used for World::chunkHash() and World::chunkBlockHash() --- build/php | 2 +- build/preprocessor | 2 +- composer.json | 1 + composer.lock | 3 ++- src/PocketMine.php | 1 + src/world/World.php | 12 ++++++++---- tests/travis/setup-php.yml | 9 +++++++++ 7 files changed, 23 insertions(+), 7 deletions(-) diff --git a/build/php b/build/php index bc8e1cf001..7da8425e67 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit bc8e1cf0015d9c74feaecdb5bf6c3bf9b9e80489 +Subproject commit 7da8425e677c68d8884788f2917fee2804f25c5a diff --git a/build/preprocessor b/build/preprocessor index 0400f85329..c8c0557ddf 160000 --- a/build/preprocessor +++ b/build/preprocessor @@ -1 +1 @@ -Subproject commit 0400f85329092be8ffaaca1b6921a18fae7848e1 +Subproject commit c8c0557ddf159413352de2a74a013d40fbfe3a69 diff --git a/composer.json b/composer.json index 112f65676f..ea0faa1e88 100644 --- a/composer.json +++ b/composer.json @@ -20,6 +20,7 @@ "ext-json": "*", "ext-leveldb": "^0.2.1", "ext-mbstring": "*", + "ext-morton": "^0.1.0", "ext-openssl": "*", "ext-pcre": "*", "ext-phar": "*", diff --git a/composer.lock b/composer.lock index a2552124f8..50163622fb 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7fdb5abb5388f1e92229efff1f783d40", + "content-hash": "cfc91763774445e65e366642b2efdde1", "packages": [ { "name": "adhocore/json-comment", @@ -3104,6 +3104,7 @@ "ext-json": "*", "ext-leveldb": "^0.2.1", "ext-mbstring": "*", + "ext-morton": "^0.1.0", "ext-openssl": "*", "ext-pcre": "*", "ext-phar": "*", diff --git a/src/PocketMine.php b/src/PocketMine.php index d5b842d305..3f6212a18f 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -88,6 +88,7 @@ namespace pocketmine { "json" => "JSON", "leveldb" => "LevelDB", "mbstring" => "Multibyte String", + "morton" => "morton", "openssl" => "OpenSSL", "pcre" => "PCRE", "phar" => "Phar", diff --git a/src/world/World.php b/src/world/World.php index eeb85d567e..757ef04cfe 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -96,6 +96,9 @@ use function lcg_value; use function max; use function microtime; use function min; +use function morton2d_decode; +use function morton2d_encode; +use function morton3d_encode; use function mt_rand; use function spl_object_id; use function strtolower; @@ -268,10 +271,11 @@ class World implements ChunkManager{ private $logger; public static function chunkHash(int $x, int $z) : int{ - return (($x & 0xFFFFFFFF) << 32) | ($z & 0xFFFFFFFF); + return morton2d_encode($x, $z); } public static function blockHash(int $x, int $y, int $z) : int{ + //TODO: switch this to use morton3d (21 bits each only allows for 2M blocks, but Y would have 12 spare bits) $shiftedY = $y - self::HALF_Y_MAX; if($shiftedY < -512 or $shiftedY >= 512){ throw new \InvalidArgumentException("Y coordinate $y is out of range!"); @@ -283,18 +287,18 @@ class World implements ChunkManager{ * Computes a small index relative to chunk base from the given coordinates. */ public static function chunkBlockHash(int $x, int $y, int $z) : int{ - return ($y << 8) | (($z & 0xf) << 4) | ($x & 0xf); + return morton3d_encode($x, $y, $z); } public static function getBlockXYZ(int $hash, ?int &$x, ?int &$y, ?int &$z) : void{ + //TODO: switch this to use morton3d $x = $hash >> 37; $y = ($hash << 27 >> 54) + self::HALF_Y_MAX; $z = $hash << 37 >> 37; } public static function getXZ(int $hash, ?int &$x, ?int &$z) : void{ - $x = $hash >> 32; - $z = ($hash & 0xFFFFFFFF) << 32 >> 32; + [$x, $z] = morton2d_decode($hash); } public static function getDifficultyFromString(string $str) : int{ diff --git a/tests/travis/setup-php.yml b/tests/travis/setup-php.yml index e2d8aac52d..ae47c2ae2c 100644 --- a/tests/travis/setup-php.yml +++ b/tests/travis/setup-php.yml @@ -55,9 +55,18 @@ before_script: - make - make install - cd .. + - | + git clone https://github.com/pmmp/ext-morton.git -b 0.1.0 --depth=1 + cd ext-morton + phpize + ./configure + make + make install + cd .. - echo "extension=pthreads.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini - echo "extension=chunkutils2.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini - echo "extension=leveldb.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini + - echo "extension=morton.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini cache: - leveldb-mcpe From 095449e86a541e464d8df30db0291dd1274513e4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 17 Oct 2020 19:24:01 +0100 Subject: [PATCH 1957/3224] Normal (generator): micro optimisations (and readability improvements) --- src/world/generator/normal/Normal.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/world/generator/normal/Normal.php b/src/world/generator/normal/Normal.php index 52bc2c8373..df0e028988 100644 --- a/src/world/generator/normal/Normal.php +++ b/src/world/generator/normal/Normal.php @@ -158,13 +158,17 @@ class Normal extends Generator{ $stillWater = VanillaBlocks::WATER()->getFullId(); $stone = VanillaBlocks::STONE()->getFullId(); + $baseX = $chunkX * 16; + $baseZ = $chunkZ * 16; for($x = 0; $x < 16; ++$x){ + $absoluteX = $baseX + $x; for($z = 0; $z < 16; ++$z){ + $absoluteZ = $baseZ + $z; $minSum = 0; $maxSum = 0; $weightSum = 0; - $biome = $this->pickBiome($chunkX * 16 + $x, $chunkZ * 16 + $z); + $biome = $this->pickBiome($absoluteX, $absoluteZ); $chunk->setBiomeId($x, $z, $biome->getId()); for($sx = -$this->gaussian->smoothSize; $sx <= $this->gaussian->smoothSize; ++$sx){ @@ -175,11 +179,11 @@ class Normal extends Generator{ if($sx === 0 and $sz === 0){ $adjacent = $biome; }else{ - $index = World::chunkHash($chunkX * 16 + $x + $sx, $chunkZ * 16 + $z + $sz); + $index = World::chunkHash($absoluteX + $sx, $absoluteZ + $sz); if(isset($biomeCache[$index])){ $adjacent = $biomeCache[$index]; }else{ - $biomeCache[$index] = $adjacent = $this->pickBiome($chunkX * 16 + $x + $sx, $chunkZ * 16 + $z + $sz); + $biomeCache[$index] = $adjacent = $this->pickBiome($absoluteX + $sx, $absoluteZ + $sz); } } From 9a282e26462026658e66839556222abf07cc7ddf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 17 Oct 2020 20:03:19 +0100 Subject: [PATCH 1958/3224] Noise: Improve fastNoise3D performance by ~25-30% --- src/world/generator/noise/Noise.php | 39 +++++++++++++++++++---------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/world/generator/noise/Noise.php b/src/world/generator/noise/Noise.php index 55e6f172c6..f4d722f2d2 100644 --- a/src/world/generator/noise/Noise.php +++ b/src/world/generator/noise/Noise.php @@ -294,34 +294,47 @@ abstract class Noise{ } } + + /** + * The following code originally called trilinearLerp() in a loop, but it was later inlined to elide function + * call overhead. + * Later, it became apparent that some of the logic was being repeated unnecessarily in the inner loop, so the + * code was changed further to avoid this, which produced visible performance improvements. + * + * In any language with a compiler, a compiler would most likely have noticed that these optimisations could be + * made and made these changes automatically, but in PHP we don't have a compiler, so the task falls to us. + * + * @see Noise::trilinearLerp() + */ for($xx = 0; $xx < $xSize; ++$xx){ + $nx = (int) ($xx / $xSamplingRate) * $xSamplingRate; + $nnx = $nx + $xSamplingRate; + + $dx1 = (($nnx - $xx) / ($nnx - $nx)); + $dx2 = (($xx - $nx) / ($nnx - $nx)); + for($zz = 0; $zz < $zSize; ++$zz){ + $nz = (int) ($zz / $zSamplingRate) * $zSamplingRate; + $nnz = $nz + $zSamplingRate; + + $dz1 = ($nnz - $zz) / ($nnz - $nz); + $dz2 = ($zz - $nz) / ($nnz - $nz); + for($yy = 0; $yy < $ySize; ++$yy){ if($xx % $xSamplingRate !== 0 or $zz % $zSamplingRate !== 0 or $yy % $ySamplingRate !== 0){ - $nx = (int) ($xx / $xSamplingRate) * $xSamplingRate; $ny = (int) ($yy / $ySamplingRate) * $ySamplingRate; - $nz = (int) ($zz / $zSamplingRate) * $zSamplingRate; - - $nnx = $nx + $xSamplingRate; $nny = $ny + $ySamplingRate; - $nnz = $nz + $zSamplingRate; - /** - * This code has been manually inlined. - * @see Noise::trilinearLerp() - */ - $dx1 = (($nnx - $xx) / ($nnx - $nx)); - $dx2 = (($xx - $nx) / ($nnx - $nx)); $dy1 = (($nny - $yy) / ($nny - $ny)); $dy2 = (($yy - $ny) / ($nny - $ny)); - $noiseArray[$xx][$zz][$yy] = (($nnz - $zz) / ($nnz - $nz)) * ( + $noiseArray[$xx][$zz][$yy] = $dz1 * ( $dy1 * ( $dx1 * $noiseArray[$nx][$nz][$ny] + $dx2 * $noiseArray[$nnx][$nz][$ny] ) + $dy2 * ( $dx1 * $noiseArray[$nx][$nz][$nny] + $dx2 * $noiseArray[$nnx][$nz][$nny] ) - ) + (($zz - $nz) / ($nnz - $nz)) * ( + ) + $dz2 * ( $dy1 * ( $dx1 * $noiseArray[$nx][$nnz][$ny] + $dx2 * $noiseArray[$nnx][$nnz][$ny] ) + $dy2 * ( From 4684333deeafce1f8564397175c61feb630c4376 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 18 Oct 2020 20:14:08 +0100 Subject: [PATCH 1959/3224] Updated build/php to pmmp/php-build-scripts@eee477802a5e89bc9ec9adff42058aed36825475 --- build/php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/php b/build/php index 7da8425e67..eee477802a 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit 7da8425e677c68d8884788f2917fee2804f25c5a +Subproject commit eee477802a5e89bc9ec9adff42058aed36825475 From 286ac2a97597a1d52424ec77a9e17e4155f190d9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 20 Oct 2020 20:31:10 +0100 Subject: [PATCH 1960/3224] Rework World::blockHash() to use morton3d this uses the unused bits on the Y component to expand the X/Z axes to 2^27 blocks long instead of 2^21 permitted by a regular morton3d code. It does require the sacrifice of an additional bit on the Y axis, but the performance advantages are more than worth it. I'm exploring how realistic it would be to just eliminate blockHash global usage (currently in lighting updates and explosions). This would allow scaling up to 2^32 without larger hashes (morton2d for chunks). --- src/world/World.php | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 757ef04cfe..93b2fa60dd 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -98,6 +98,7 @@ use function microtime; use function min; use function morton2d_decode; use function morton2d_encode; +use function morton3d_decode; use function morton3d_encode; use function mt_rand; use function spl_object_id; @@ -274,13 +275,31 @@ class World implements ChunkManager{ return morton2d_encode($x, $z); } + private const MORTON3D_BIT_SIZE = 21; + private const BLOCKHASH_Y_BITS = 9; + private const BLOCKHASH_Y_MASK = (1 << self::BLOCKHASH_Y_BITS) - 1; + private const BLOCKHASH_XZ_MASK = (1 << self::MORTON3D_BIT_SIZE) - 1; + private const BLOCKHASH_XZ_EXTRA_BITS = 6; + private const BLOCKHASH_XZ_EXTRA_MASK = (1 << self::BLOCKHASH_XZ_EXTRA_BITS) - 1; + private const BLOCKHASH_XZ_SIGN_SHIFT = 64 - self::MORTON3D_BIT_SIZE - self::BLOCKHASH_XZ_EXTRA_BITS; + private const BLOCKHASH_X_SHIFT = self::BLOCKHASH_Y_BITS; + private const BLOCKHASH_Z_SHIFT = self::BLOCKHASH_X_SHIFT + self::BLOCKHASH_XZ_EXTRA_BITS; + public static function blockHash(int $x, int $y, int $z) : int{ - //TODO: switch this to use morton3d (21 bits each only allows for 2M blocks, but Y would have 12 spare bits) - $shiftedY = $y - self::HALF_Y_MAX; - if($shiftedY < -512 or $shiftedY >= 512){ + $shiftedY = $y + self::HALF_Y_MAX; + if(($shiftedY & (~0 << self::BLOCKHASH_Y_BITS)) !== 0){ throw new \InvalidArgumentException("Y coordinate $y is out of range!"); } - return (($x & 0x7ffffff) << 37) | (($shiftedY & 0x3ff) << 27) | ($z & 0x7ffffff); + //morton3d gives us 21 bits on each axis, but the Y axis only requires 9 + //so we use the extra space on Y (12 bits) and add 6 extra bits from X and Z instead. + //if we ever need more space for Y (e.g. due to expansion), take bits from X/Z to compensate. + return morton3d_encode( + $x & self::BLOCKHASH_XZ_MASK, + ($shiftedY /* & self::BLOCKHASH_Y_MASK */) | + ((($x >> self::MORTON3D_BIT_SIZE) & self::BLOCKHASH_XZ_EXTRA_MASK) << self::BLOCKHASH_X_SHIFT) | + ((($z >> self::MORTON3D_BIT_SIZE) & self::BLOCKHASH_XZ_EXTRA_MASK) << self::BLOCKHASH_Z_SHIFT), + $z & self::BLOCKHASH_XZ_MASK + ); } /** @@ -291,10 +310,14 @@ class World implements ChunkManager{ } public static function getBlockXYZ(int $hash, ?int &$x, ?int &$y, ?int &$z) : void{ - //TODO: switch this to use morton3d - $x = $hash >> 37; - $y = ($hash << 27 >> 54) + self::HALF_Y_MAX; - $z = $hash << 37 >> 37; + [$baseX, $baseY, $baseZ] = morton3d_decode($hash); + + $extraX = ((($baseY >> self::BLOCKHASH_X_SHIFT) & self::BLOCKHASH_XZ_EXTRA_MASK) << self::MORTON3D_BIT_SIZE); + $extraZ = ((($baseY >> self::BLOCKHASH_Z_SHIFT) & self::BLOCKHASH_XZ_EXTRA_MASK) << self::MORTON3D_BIT_SIZE); + + $x = (($baseX & self::BLOCKHASH_XZ_MASK) | $extraX) << self::BLOCKHASH_XZ_SIGN_SHIFT >> self::BLOCKHASH_XZ_SIGN_SHIFT; + $y = ($baseY & self::BLOCKHASH_Y_MASK) - self::HALF_Y_MAX; + $z = (($baseZ & self::BLOCKHASH_XZ_MASK) | $extraZ) << self::BLOCKHASH_XZ_SIGN_SHIFT >> self::BLOCKHASH_XZ_SIGN_SHIFT; } public static function getXZ(int $hash, ?int &$x, ?int &$z) : void{ From f5e033ad5d297f9d9a586299f94d01f5243a4922 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 23 Oct 2020 13:25:52 +0100 Subject: [PATCH 1961/3224] AsyncPool: fixed stable merge error --- src/scheduler/AsyncPool.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/scheduler/AsyncPool.php b/src/scheduler/AsyncPool.php index 5c9d710e3e..f7606c7c3c 100644 --- a/src/scheduler/AsyncPool.php +++ b/src/scheduler/AsyncPool.php @@ -25,6 +25,7 @@ namespace pocketmine\scheduler; use pocketmine\utils\Utils; use function array_keys; +use function array_map; use function assert; use function count; use function spl_object_id; @@ -269,7 +270,7 @@ class AsyncPool{ * @phpstan-return array */ public function getTaskQueueSizes() : array{ - return $this->workerUsage; + return array_map(function(\SplQueue $queue) : int{ return $queue->count(); }, $this->taskQueues); } public function shutdownUnusedWorkers() : int{ From e9038336e33827a87548d20598d3ad281cf20dd0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 23 Oct 2020 20:14:37 +0100 Subject: [PATCH 1962/3224] EventPriority: hardcode name -> value mapping instead of using constant() this would have caught fire if additional non-priority constants were added, or if the constants were renamed. --- src/event/EventPriority.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/event/EventPriority.php b/src/event/EventPriority.php index fc52d99c22..1ef6e9da37 100644 --- a/src/event/EventPriority.php +++ b/src/event/EventPriority.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\event; -use function constant; -use function defined; use function mb_strtoupper; /** @@ -84,10 +82,16 @@ final class EventPriority{ * @throws \InvalidArgumentException */ public static function fromString(string $name) : int{ - $name = mb_strtoupper($name); - $const = self::class . "::" . $name; - if($name !== "ALL" and defined($const)){ - return constant($const); + $value = [ + "LOWEST" => self::LOWEST, + "LOW" => self::LOW, + "NORMAL" => self::NORMAL, + "HIGH" => self::HIGH, + "HIGHEST" => self::HIGHEST, + "MONITOR" => self::MONITOR + ][mb_strtoupper($name)] ?? null; + if($value !== null){ + return $value; } throw new \InvalidArgumentException("Unable to resolve priority \"$name\""); From a01c086481da988ab3409bc399d82f72ed9134ce Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 23 Oct 2020 20:48:19 +0100 Subject: [PATCH 1963/3224] Introduced VanillaEnchantments registry --- src/Server.php | 2 - src/block/Block.php | 6 +- src/block/Ice.php | 4 +- src/block/TNT.php | 4 +- src/command/defaults/EnchantCommand.php | 5 +- src/entity/ExperienceManager.php | 6 +- src/entity/Human.php | 4 +- src/entity/Living.php | 9 +- src/item/Armor.php | 4 +- src/item/Bow.php | 10 +- src/item/Durable.php | 4 +- src/item/Item.php | 4 +- src/item/Tool.php | 4 +- src/item/enchantment/Enchantment.php | 146 ------------------- src/item/enchantment/VanillaEnchantments.php | 137 +++++++++++++++++ tests/phpunit/item/ItemTest.php | 46 +++--- 16 files changed, 191 insertions(+), 204 deletions(-) create mode 100644 src/item/enchantment/VanillaEnchantments.php diff --git a/src/Server.php b/src/Server.php index 1dc6d86ae6..419ffdb9b4 100644 --- a/src/Server.php +++ b/src/Server.php @@ -39,7 +39,6 @@ use pocketmine\event\player\PlayerDataSaveEvent; use pocketmine\event\server\CommandEvent; use pocketmine\event\server\DataPacketSendEvent; use pocketmine\event\server\QueryRegenerateEvent; -use pocketmine\item\enchantment\Enchantment; use pocketmine\lang\Language; use pocketmine\lang\LanguageNotFoundException; use pocketmine\lang\TranslationContainer; @@ -937,7 +936,6 @@ class Server{ $this->commandMap = new SimpleCommandMap($this); - Enchantment::init(); Biome::init(); $this->craftingManager = CraftingManagerFromDataHelper::make(\pocketmine\RESOURCE_PATH . '/vanilla/recipes.json'); diff --git a/src/block/Block.php b/src/block/Block.php index d81d143d88..6ac38de9ff 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -30,7 +30,7 @@ use pocketmine\block\tile\Spawnable; use pocketmine\block\tile\Tile; use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\entity\Entity; -use pocketmine\item\enchantment\Enchantment; +use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\math\Axis; @@ -357,7 +357,7 @@ class Block{ */ public function getDrops(Item $item) : array{ if($this->breakInfo->isToolCompatible($item)){ - if($this->isAffectedBySilkTouch() and $item->hasEnchantment(Enchantment::SILK_TOUCH())){ + if($this->isAffectedBySilkTouch() and $item->hasEnchantment(VanillaEnchantments::SILK_TOUCH())){ return $this->getSilkTouchDrops($item); } @@ -389,7 +389,7 @@ class Block{ * Returns how much XP will be dropped by breaking this block with the given item. */ public function getXpDropForTool(Item $item) : int{ - if($item->hasEnchantment(Enchantment::SILK_TOUCH()) or !$this->breakInfo->isToolCompatible($item)){ + if($item->hasEnchantment(VanillaEnchantments::SILK_TOUCH()) or !$this->breakInfo->isToolCompatible($item)){ return 0; } diff --git a/src/block/Ice.php b/src/block/Ice.php index ef29179971..b22278fb06 100644 --- a/src/block/Ice.php +++ b/src/block/Ice.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\enchantment\Enchantment; +use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\item\Item; use pocketmine\player\Player; @@ -42,7 +42,7 @@ class Ice extends Transparent{ } public function onBreak(Item $item, ?Player $player = null) : bool{ - if(($player === null or $player->isSurvival()) and !$item->hasEnchantment(Enchantment::SILK_TOUCH())){ + if(($player === null or $player->isSurvival()) and !$item->hasEnchantment(VanillaEnchantments::SILK_TOUCH())){ $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::WATER()); return true; } diff --git a/src/block/TNT.php b/src/block/TNT.php index f9325afd15..46256f9298 100644 --- a/src/block/TNT.php +++ b/src/block/TNT.php @@ -28,7 +28,7 @@ use pocketmine\entity\Location; use pocketmine\entity\object\PrimedTNT; use pocketmine\entity\projectile\Arrow; use pocketmine\item\Durable; -use pocketmine\item\enchantment\Enchantment; +use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\item\FlintSteel; use pocketmine\item\Item; use pocketmine\math\Vector3; @@ -68,7 +68,7 @@ class TNT extends Opaque{ } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($item instanceof FlintSteel or $item->hasEnchantment(Enchantment::FIRE_ASPECT())){ + if($item instanceof FlintSteel or $item->hasEnchantment(VanillaEnchantments::FIRE_ASPECT())){ if($item instanceof Durable){ $item->applyDamage(1); } diff --git a/src/command/defaults/EnchantCommand.php b/src/command/defaults/EnchantCommand.php index bd8b71bd6c..05cec32ee6 100644 --- a/src/command/defaults/EnchantCommand.php +++ b/src/command/defaults/EnchantCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\EnchantmentInstance; +use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\lang\TranslationContainer; use pocketmine\utils\TextFormat; use function count; @@ -67,9 +68,9 @@ class EnchantCommand extends VanillaCommand{ } if(is_numeric($args[1])){ - $enchantment = Enchantment::get((int) $args[1]); + $enchantment = VanillaEnchantments::byMcpeId((int) $args[1]); }else{ - $enchantment = Enchantment::fromString($args[1]); + $enchantment = VanillaEnchantments::fromString($args[1]); } if(!($enchantment instanceof Enchantment)){ diff --git a/src/entity/ExperienceManager.php b/src/entity/ExperienceManager.php index 9e973bc3da..223ad5ee1d 100644 --- a/src/entity/ExperienceManager.php +++ b/src/entity/ExperienceManager.php @@ -26,7 +26,7 @@ namespace pocketmine\entity; use pocketmine\entity\utils\ExperienceUtils; use pocketmine\event\player\PlayerExperienceChangeEvent; use pocketmine\item\Durable; -use pocketmine\item\enchantment\Enchantment; +use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\world\sound\XpCollectSound; use pocketmine\world\sound\XpLevelUpSound; use function array_rand; @@ -244,12 +244,12 @@ class ExperienceManager{ /** @var Durable[] $equipment */ $equipment = []; - if(($item = $this->entity->getInventory()->getItemInHand()) instanceof Durable and $item->hasEnchantment(Enchantment::MENDING())){ + if(($item = $this->entity->getInventory()->getItemInHand()) instanceof Durable and $item->hasEnchantment(VanillaEnchantments::MENDING())){ $equipment[$mainHandIndex] = $item; } //TODO: check offhand foreach($this->entity->getArmorInventory()->getContents() as $k => $armorItem){ - if($armorItem instanceof Durable and $armorItem->hasEnchantment(Enchantment::MENDING())){ + if($armorItem instanceof Durable and $armorItem->hasEnchantment(VanillaEnchantments::MENDING())){ $equipment[$k] = $armorItem; } } diff --git a/src/entity/Human.php b/src/entity/Human.php index f85e0ab855..39a671e090 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -32,7 +32,7 @@ use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\player\PlayerExhaustEvent; use pocketmine\inventory\InventoryHolder; use pocketmine\inventory\PlayerInventory; -use pocketmine\item\enchantment\Enchantment; +use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\item\Item; use pocketmine\item\Totem; use pocketmine\math\Vector3; @@ -310,7 +310,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ return array_filter(array_merge( $this->inventory !== null ? array_values($this->inventory->getContents()) : [], $this->armorInventory !== null ? array_values($this->armorInventory->getContents()) : [] - ), function(Item $item) : bool{ return !$item->hasEnchantment(Enchantment::VANISHING()); }); + ), function(Item $item) : bool{ return !$item->hasEnchantment(VanillaEnchantments::VANISHING()); }); } public function saveNBT() : CompoundTag{ diff --git a/src/entity/Living.php b/src/entity/Living.php index 89d26927f7..cc9a0334ff 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -41,6 +41,7 @@ use pocketmine\inventory\Inventory; use pocketmine\item\Armor; use pocketmine\item\Durable; use pocketmine\item\enchantment\Enchantment; +use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\math\VoxelRayTrace; @@ -346,7 +347,7 @@ abstract class Living extends Entity{ } public function setOnFire(int $seconds) : void{ - parent::setOnFire($seconds - (int) min($seconds, $seconds * $this->getHighestArmorEnchantmentLevel(Enchantment::FIRE_PROTECTION()) * 0.15)); + parent::setOnFire($seconds - (int) min($seconds, $seconds * $this->getHighestArmorEnchantmentLevel(VanillaEnchantments::FIRE_PROTECTION()) * 0.15)); } /** @@ -393,7 +394,7 @@ abstract class Living extends Entity{ if($source instanceof EntityDamageByEntityEvent and ($attacker = $source->getDamager()) !== null){ $damage = 0; foreach($this->armorInventory->getContents() as $k => $item){ - if($item instanceof Armor and ($thornsLevel = $item->getEnchantmentLevel(Enchantment::THORNS())) > 0){ + if($item instanceof Armor and ($thornsLevel = $item->getEnchantmentLevel(VanillaEnchantments::THORNS())) > 0){ if(mt_rand(0, 99) < $thornsLevel * 15){ $this->damageItem($item, 3); $damage += ($thornsLevel > 10 ? $thornsLevel - 10 : 1 + mt_rand(0, 3)); @@ -458,7 +459,7 @@ abstract class Living extends Entity{ //TODO: knockback should not just apply for entity damage sources //this doesn't matter for TNT right now because the PrimedTNT entity is considered the source, not the block. $base = $source->getKnockBack(); - $source->setKnockBack($base - min($base, $base * $this->getHighestArmorEnchantmentLevel(Enchantment::BLAST_PROTECTION()) * 0.15)); + $source->setKnockBack($base - min($base, $base * $this->getHighestArmorEnchantmentLevel(VanillaEnchantments::BLAST_PROTECTION()) * 0.15)); } parent::attack($source); @@ -588,7 +589,7 @@ abstract class Living extends Entity{ if(!$this->canBreathe()){ $this->setBreathing(false); - if(($respirationLevel = $this->armorInventory->getHelmet()->getEnchantmentLevel(Enchantment::RESPIRATION())) <= 0 or + if(($respirationLevel = $this->armorInventory->getHelmet()->getEnchantmentLevel(VanillaEnchantments::RESPIRATION())) <= 0 or lcg_value() <= (1 / ($respirationLevel + 1)) ){ $ticks -= $tickDiff; diff --git a/src/item/Armor.php b/src/item/Armor.php index 4f79d9c618..a3e235ded5 100644 --- a/src/item/Armor.php +++ b/src/item/Armor.php @@ -27,8 +27,8 @@ use pocketmine\block\Block; use pocketmine\color\Color; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\inventory\ArmorInventory; -use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\ProtectionEnchantment; +use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; @@ -106,7 +106,7 @@ class Armor extends Durable{ } protected function getUnbreakingDamageReduction(int $amount) : int{ - if(($unbreakingLevel = $this->getEnchantmentLevel(Enchantment::UNBREAKING())) > 0){ + if(($unbreakingLevel = $this->getEnchantmentLevel(VanillaEnchantments::UNBREAKING())) > 0){ $negated = 0; $chance = 1 / ($unbreakingLevel + 1); diff --git a/src/item/Bow.php b/src/item/Bow.php index d57bff29b7..c86438b3b6 100644 --- a/src/item/Bow.php +++ b/src/item/Bow.php @@ -28,7 +28,7 @@ use pocketmine\entity\projectile\Arrow as ArrowEntity; use pocketmine\entity\projectile\Projectile; use pocketmine\event\entity\EntityShootBowEvent; use pocketmine\event\entity\ProjectileLaunchEvent; -use pocketmine\item\enchantment\Enchantment; +use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\player\Player; use pocketmine\world\sound\BowShootSound; use function intdiv; @@ -64,17 +64,17 @@ class Bow extends Tool implements Releasable{ ), $player, $baseForce >= 1); $entity->setMotion($player->getDirectionVector()); - $infinity = $this->hasEnchantment(Enchantment::INFINITY()); + $infinity = $this->hasEnchantment(VanillaEnchantments::INFINITY()); if($infinity){ $entity->setPickupMode(ArrowEntity::PICKUP_CREATIVE); } - if(($punchLevel = $this->getEnchantmentLevel(Enchantment::PUNCH())) > 0){ + if(($punchLevel = $this->getEnchantmentLevel(VanillaEnchantments::PUNCH())) > 0){ $entity->setPunchKnockback($punchLevel); } - if(($powerLevel = $this->getEnchantmentLevel(Enchantment::POWER())) > 0){ + if(($powerLevel = $this->getEnchantmentLevel(VanillaEnchantments::POWER())) > 0){ $entity->setBaseDamage($entity->getBaseDamage() + (($powerLevel + 1) / 2)); } - if($this->hasEnchantment(Enchantment::FLAME())){ + if($this->hasEnchantment(VanillaEnchantments::FLAME())){ $entity->setOnFire(intdiv($entity->getFireTicks(), 20) + 100); } $ev = new EntityShootBowEvent($player, $this, $entity, $baseForce * 3); diff --git a/src/item/Durable.php b/src/item/Durable.php index a84956d0bf..004525808c 100644 --- a/src/item/Durable.php +++ b/src/item/Durable.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\item\enchantment\Enchantment; +use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\nbt\tag\CompoundTag; use function lcg_value; use function min; @@ -89,7 +89,7 @@ abstract class Durable extends Item{ } protected function getUnbreakingDamageReduction(int $amount) : int{ - if(($unbreakingLevel = $this->getEnchantmentLevel(Enchantment::UNBREAKING())) > 0){ + if(($unbreakingLevel = $this->getEnchantmentLevel(VanillaEnchantments::UNBREAKING())) > 0){ $negated = 0; $chance = 1 / ($unbreakingLevel + 1); diff --git a/src/item/Item.php b/src/item/Item.php index 7cbbddb543..7228c15cd3 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -32,8 +32,8 @@ use pocketmine\block\BlockBreakInfo; use pocketmine\block\BlockToolType; use pocketmine\block\VanillaBlocks; use pocketmine\entity\Entity; -use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\EnchantmentInstance; +use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\math\Vector3; use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\NBT; @@ -285,7 +285,7 @@ class Item implements \JsonSerializable{ if($level <= 0){ continue; } - $type = Enchantment::get($magicNumber); + $type = VanillaEnchantments::byMcpeId($magicNumber); if($type !== null){ $this->addEnchantment(new EnchantmentInstance($type, $level)); } diff --git a/src/item/Tool.php b/src/item/Tool.php index 47a9b651b9..d6cc1a061d 100644 --- a/src/item/Tool.php +++ b/src/item/Tool.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\item\enchantment\Enchantment; +use pocketmine\item\enchantment\VanillaEnchantments; abstract class Tool extends Durable{ @@ -35,7 +35,7 @@ abstract class Tool extends Durable{ $efficiency = 1; if($isCorrectTool){ $efficiency = $this->getBaseMiningEfficiency(); - if(($enchantmentLevel = $this->getEnchantmentLevel(Enchantment::EFFICIENCY())) > 0){ + if(($enchantmentLevel = $this->getEnchantmentLevel(VanillaEnchantments::EFFICIENCY())) > 0){ $efficiency += ($enchantmentLevel ** 2 + 1); } } diff --git a/src/item/enchantment/Enchantment.php b/src/item/enchantment/Enchantment.php index 50ac2d4066..85c321d367 100644 --- a/src/item/enchantment/Enchantment.php +++ b/src/item/enchantment/Enchantment.php @@ -23,10 +23,7 @@ declare(strict_types=1); namespace pocketmine\item\enchantment; -use pocketmine\event\entity\EntityDamageEvent; use function constant; -use function defined; -use function mb_strtoupper; /** * Manages enchantment type data. @@ -98,149 +95,6 @@ class Enchantment{ public const SLOT_ELYTRA = 0x4000; public const SLOT_TRIDENT = 0x8000; - /** @var Enchantment[] */ - protected static $enchantments = []; - - public static function init() : void{ - self::register(new ProtectionEnchantment(self::PROTECTION, "%enchantment.protect.all", self::RARITY_COMMON, self::SLOT_ARMOR, self::SLOT_NONE, 4, 0.75, null)); - self::register(new ProtectionEnchantment(self::FIRE_PROTECTION, "%enchantment.protect.fire", self::RARITY_UNCOMMON, self::SLOT_ARMOR, self::SLOT_NONE, 4, 1.25, [ - EntityDamageEvent::CAUSE_FIRE, - EntityDamageEvent::CAUSE_FIRE_TICK, - EntityDamageEvent::CAUSE_LAVA - //TODO: check fireballs - ])); - self::register(new ProtectionEnchantment(self::FEATHER_FALLING, "%enchantment.protect.fall", self::RARITY_UNCOMMON, self::SLOT_FEET, self::SLOT_NONE, 4, 2.5, [ - EntityDamageEvent::CAUSE_FALL - ])); - self::register(new ProtectionEnchantment(self::BLAST_PROTECTION, "%enchantment.protect.explosion", self::RARITY_RARE, self::SLOT_ARMOR, self::SLOT_NONE, 4, 1.5, [ - EntityDamageEvent::CAUSE_BLOCK_EXPLOSION, - EntityDamageEvent::CAUSE_ENTITY_EXPLOSION - ])); - self::register(new ProtectionEnchantment(self::PROJECTILE_PROTECTION, "%enchantment.protect.projectile", self::RARITY_UNCOMMON, self::SLOT_ARMOR, self::SLOT_NONE, 4, 1.5, [ - EntityDamageEvent::CAUSE_PROJECTILE - ])); - self::register(new Enchantment(self::THORNS, "%enchantment.thorns", self::RARITY_MYTHIC, self::SLOT_TORSO, self::SLOT_HEAD | self::SLOT_LEGS | self::SLOT_FEET, 3)); - self::register(new Enchantment(self::RESPIRATION, "%enchantment.oxygen", self::RARITY_RARE, self::SLOT_HEAD, self::SLOT_NONE, 3)); - - self::register(new SharpnessEnchantment(self::SHARPNESS, "%enchantment.damage.all", self::RARITY_COMMON, self::SLOT_SWORD, self::SLOT_AXE, 5)); - //TODO: smite, bane of arthropods (these don't make sense now because their applicable mobs don't exist yet) - - self::register(new KnockbackEnchantment(self::KNOCKBACK, "%enchantment.knockback", self::RARITY_UNCOMMON, self::SLOT_SWORD, self::SLOT_NONE, 2)); - self::register(new FireAspectEnchantment(self::FIRE_ASPECT, "%enchantment.fire", self::RARITY_RARE, self::SLOT_SWORD, self::SLOT_NONE, 2)); - - self::register(new Enchantment(self::EFFICIENCY, "%enchantment.digging", self::RARITY_COMMON, self::SLOT_DIG, self::SLOT_SHEARS, 5)); - self::register(new Enchantment(self::SILK_TOUCH, "%enchantment.untouching", self::RARITY_MYTHIC, self::SLOT_DIG, self::SLOT_SHEARS, 1)); - self::register(new Enchantment(self::UNBREAKING, "%enchantment.durability", self::RARITY_UNCOMMON, self::SLOT_DIG | self::SLOT_ARMOR | self::SLOT_FISHING_ROD | self::SLOT_BOW, self::SLOT_TOOL | self::SLOT_CARROT_STICK | self::SLOT_ELYTRA, 3)); - - self::register(new Enchantment(self::POWER, "%enchantment.arrowDamage", self::RARITY_COMMON, self::SLOT_BOW, self::SLOT_NONE, 5)); - self::register(new Enchantment(self::PUNCH, "%enchantment.arrowKnockback", self::RARITY_RARE, self::SLOT_BOW, self::SLOT_NONE, 2)); - self::register(new Enchantment(self::FLAME, "%enchantment.arrowFire", self::RARITY_RARE, self::SLOT_BOW, self::SLOT_NONE, 1)); - self::register(new Enchantment(self::INFINITY, "%enchantment.arrowInfinite", self::RARITY_MYTHIC, self::SLOT_BOW, self::SLOT_NONE, 1)); - - self::register(new Enchantment(self::MENDING, "%enchantment.mending", self::RARITY_RARE, self::SLOT_NONE, self::SLOT_ALL, 1)); - - self::register(new Enchantment(self::VANISHING, "%enchantment.curse.vanishing", self::RARITY_MYTHIC, self::SLOT_NONE, self::SLOT_ALL, 1)); - } - - //region --- auto-generated code --- - - public static function BLAST_PROTECTION() : Enchantment{ - return self::get(self::BLAST_PROTECTION); - } - - public static function EFFICIENCY() : Enchantment{ - return self::get(self::EFFICIENCY); - } - - public static function FEATHER_FALLING() : Enchantment{ - return self::get(self::FEATHER_FALLING); - } - - public static function FIRE_ASPECT() : Enchantment{ - return self::get(self::FIRE_ASPECT); - } - - public static function FIRE_PROTECTION() : Enchantment{ - return self::get(self::FIRE_PROTECTION); - } - - public static function FLAME() : Enchantment{ - return self::get(self::FLAME); - } - - public static function INFINITY() : Enchantment{ - return self::get(self::INFINITY); - } - - public static function KNOCKBACK() : Enchantment{ - return self::get(self::KNOCKBACK); - } - - public static function MENDING() : Enchantment{ - return self::get(self::MENDING); - } - - public static function POWER() : Enchantment{ - return self::get(self::POWER); - } - - public static function PROJECTILE_PROTECTION() : Enchantment{ - return self::get(self::PROJECTILE_PROTECTION); - } - - public static function PROTECTION() : Enchantment{ - return self::get(self::PROTECTION); - } - - public static function PUNCH() : Enchantment{ - return self::get(self::PUNCH); - } - - public static function RESPIRATION() : Enchantment{ - return self::get(self::RESPIRATION); - } - - public static function SHARPNESS() : Enchantment{ - return self::get(self::SHARPNESS); - } - - public static function SILK_TOUCH() : Enchantment{ - return self::get(self::SILK_TOUCH); - } - - public static function THORNS() : Enchantment{ - return self::get(self::THORNS); - } - - public static function UNBREAKING() : Enchantment{ - return self::get(self::UNBREAKING); - } - - public static function VANISHING() : Enchantment{ - return self::get(self::VANISHING); - } - - //endregion - - /** - * Registers an enchantment type. - */ - public static function register(Enchantment $enchantment) : void{ - self::$enchantments[$enchantment->getId()] = clone $enchantment; - } - - public static function get(int $id) : ?Enchantment{ - return self::$enchantments[$id] ?? null; - } - - public static function fromString(string $name) : ?Enchantment{ - $const = Enchantment::class . "::" . mb_strtoupper($name); - if(defined($const)){ - return self::get(constant($const)); - } - return null; - } - /** @var int */ private $id; /** @var string */ diff --git a/src/item/enchantment/VanillaEnchantments.php b/src/item/enchantment/VanillaEnchantments.php new file mode 100644 index 0000000000..8bbdd87f33 --- /dev/null +++ b/src/item/enchantment/VanillaEnchantments.php @@ -0,0 +1,137 @@ + + */ + private static $mcpeIdMap = []; + + protected static function setup() : void{ + self::register("PROTECTION", new ProtectionEnchantment(Enchantment::PROTECTION, "%enchantment.protect.all", Enchantment::RARITY_COMMON, Enchantment::SLOT_ARMOR, Enchantment::SLOT_NONE, 4, 0.75, null)); + self::register("FIRE_PROTECTION", new ProtectionEnchantment(Enchantment::FIRE_PROTECTION, "%enchantment.protect.fire", Enchantment::RARITY_UNCOMMON, Enchantment::SLOT_ARMOR, Enchantment::SLOT_NONE, 4, 1.25, [ + EntityDamageEvent::CAUSE_FIRE, + EntityDamageEvent::CAUSE_FIRE_TICK, + EntityDamageEvent::CAUSE_LAVA + //TODO: check fireballs + ])); + self::register("FEATHER_FALLING", new ProtectionEnchantment(Enchantment::FEATHER_FALLING, "%enchantment.protect.fall", Enchantment::RARITY_UNCOMMON, Enchantment::SLOT_FEET, Enchantment::SLOT_NONE, 4, 2.5, [ + EntityDamageEvent::CAUSE_FALL + ])); + self::register("BLAST_PROTECTION", new ProtectionEnchantment(Enchantment::BLAST_PROTECTION, "%enchantment.protect.explosion", Enchantment::RARITY_RARE, Enchantment::SLOT_ARMOR, Enchantment::SLOT_NONE, 4, 1.5, [ + EntityDamageEvent::CAUSE_BLOCK_EXPLOSION, + EntityDamageEvent::CAUSE_ENTITY_EXPLOSION + ])); + self::register("PROJECTILE_PROTECTION", new ProtectionEnchantment(Enchantment::PROJECTILE_PROTECTION, "%enchantment.protect.projectile", Enchantment::RARITY_UNCOMMON, Enchantment::SLOT_ARMOR, Enchantment::SLOT_NONE, 4, 1.5, [ + EntityDamageEvent::CAUSE_PROJECTILE + ])); + self::register("THORNS", new Enchantment(Enchantment::THORNS, "%enchantment.thorns", Enchantment::RARITY_MYTHIC, Enchantment::SLOT_TORSO, Enchantment::SLOT_HEAD | Enchantment::SLOT_LEGS | Enchantment::SLOT_FEET, 3)); + self::register("RESPIRATION", new Enchantment(Enchantment::RESPIRATION, "%enchantment.oxygen", Enchantment::RARITY_RARE, Enchantment::SLOT_HEAD, Enchantment::SLOT_NONE, 3)); + + self::register("SHARPNESS", new SharpnessEnchantment(Enchantment::SHARPNESS, "%enchantment.damage.all", Enchantment::RARITY_COMMON, Enchantment::SLOT_SWORD, Enchantment::SLOT_AXE, 5)); + //TODO: smite, bane of arthropods (these don't make sense now because their applicable mobs don't exist yet) + + self::register("KNOCKBACK", new KnockbackEnchantment(Enchantment::KNOCKBACK, "%enchantment.knockback", Enchantment::RARITY_UNCOMMON, Enchantment::SLOT_SWORD, Enchantment::SLOT_NONE, 2)); + self::register("FIRE_ASPECT", new FireAspectEnchantment(Enchantment::FIRE_ASPECT, "%enchantment.fire", Enchantment::RARITY_RARE, Enchantment::SLOT_SWORD, Enchantment::SLOT_NONE, 2)); + + self::register("EFFICIENCY", new Enchantment(Enchantment::EFFICIENCY, "%enchantment.digging", Enchantment::RARITY_COMMON, Enchantment::SLOT_DIG, Enchantment::SLOT_SHEARS, 5)); + self::register("SILK_TOUCH", new Enchantment(Enchantment::SILK_TOUCH, "%enchantment.untouching", Enchantment::RARITY_MYTHIC, Enchantment::SLOT_DIG, Enchantment::SLOT_SHEARS, 1)); + self::register("UNBREAKING", new Enchantment(Enchantment::UNBREAKING, "%enchantment.durability", Enchantment::RARITY_UNCOMMON, Enchantment::SLOT_DIG | Enchantment::SLOT_ARMOR | Enchantment::SLOT_FISHING_ROD | Enchantment::SLOT_BOW, Enchantment::SLOT_TOOL | Enchantment::SLOT_CARROT_STICK | Enchantment::SLOT_ELYTRA, 3)); + + self::register("POWER", new Enchantment(Enchantment::POWER, "%enchantment.arrowDamage", Enchantment::RARITY_COMMON, Enchantment::SLOT_BOW, Enchantment::SLOT_NONE, 5)); + self::register("PUNCH", new Enchantment(Enchantment::PUNCH, "%enchantment.arrowKnockback", Enchantment::RARITY_RARE, Enchantment::SLOT_BOW, Enchantment::SLOT_NONE, 2)); + self::register("FLAME", new Enchantment(Enchantment::FLAME, "%enchantment.arrowFire", Enchantment::RARITY_RARE, Enchantment::SLOT_BOW, Enchantment::SLOT_NONE, 1)); + self::register("INFINITY", new Enchantment(Enchantment::INFINITY, "%enchantment.arrowInfinite", Enchantment::RARITY_MYTHIC, Enchantment::SLOT_BOW, Enchantment::SLOT_NONE, 1)); + + self::register("MENDING", new Enchantment(Enchantment::MENDING, "%enchantment.mending", Enchantment::RARITY_RARE, Enchantment::SLOT_NONE, Enchantment::SLOT_ALL, 1)); + + self::register("VANISHING", new Enchantment(Enchantment::VANISHING, "%enchantment.curse.vanishing", Enchantment::RARITY_MYTHIC, Enchantment::SLOT_NONE, Enchantment::SLOT_ALL, 1)); + } + + protected static function register(string $name, Enchantment $member) : void{ + if(array_key_exists($member->getId(), self::$mcpeIdMap)){ + throw new \InvalidArgumentException("MCPE enchantment ID " . $member->getId() . " is already assigned"); + } + self::_registryRegister($name, $member); + self::$mcpeIdMap[$member->getId()] = $member; + } + + public static function byMcpeId(int $id) : ?Enchantment{ + //TODO: this shouldn't be in here, it's unnecessarily limiting + self::checkInit(); + return self::$mcpeIdMap[$id] ?? null; + } + + /** + * @return Enchantment[] + * @phpstan-return array + */ + public static function getAll() : array{ + /** + * @var Enchantment[] $result + * @phpstan-var array $result + */ + $result = self::_registryGetAll(); + return $result; + } + + public static function fromString(string $name) : Enchantment{ + /** @var Enchantment $result */ + $result = self::_registryFromString($name); + return $result; + } +} diff --git a/tests/phpunit/item/ItemTest.php b/tests/phpunit/item/ItemTest.php index 6a7f14dade..2340ff97de 100644 --- a/tests/phpunit/item/ItemTest.php +++ b/tests/phpunit/item/ItemTest.php @@ -24,15 +24,11 @@ declare(strict_types=1); namespace pocketmine\item; use PHPUnit\Framework\TestCase; -use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\EnchantmentInstance; +use pocketmine\item\enchantment\VanillaEnchantments; class ItemTest extends TestCase{ - public static function setUpBeforeClass() : void{ - Enchantment::init(); - } - /** @var Item */ private $item; @@ -75,27 +71,27 @@ class ItemTest extends TestCase{ } public function testHasEnchantment() : void{ - $this->item->addEnchantment(new EnchantmentInstance(Enchantment::EFFICIENCY(), 5)); - self::assertTrue($this->item->hasEnchantment(Enchantment::EFFICIENCY())); - self::assertTrue($this->item->hasEnchantment(Enchantment::EFFICIENCY(), 5)); + $this->item->addEnchantment(new EnchantmentInstance(VanillaEnchantments::EFFICIENCY(), 5)); + self::assertTrue($this->item->hasEnchantment(VanillaEnchantments::EFFICIENCY())); + self::assertTrue($this->item->hasEnchantment(VanillaEnchantments::EFFICIENCY(), 5)); } public function testHasEnchantments() : void{ self::assertFalse($this->item->hasEnchantments()); - $this->item->addEnchantment(new EnchantmentInstance(Enchantment::FIRE_ASPECT())); + $this->item->addEnchantment(new EnchantmentInstance(VanillaEnchantments::FIRE_ASPECT())); self::assertTrue($this->item->hasEnchantments()); } public function testGetEnchantmentLevel() : void{ - $this->item->addEnchantment(new EnchantmentInstance(Enchantment::EFFICIENCY(), 5)); - self::assertSame(5, $this->item->getEnchantmentLevel(Enchantment::EFFICIENCY())); + $this->item->addEnchantment(new EnchantmentInstance(VanillaEnchantments::EFFICIENCY(), 5)); + self::assertSame(5, $this->item->getEnchantmentLevel(VanillaEnchantments::EFFICIENCY())); } public function testGetEnchantments() : void{ /** @var EnchantmentInstance[] $enchantments */ $enchantments = [ - new EnchantmentInstance(Enchantment::EFFICIENCY(), 5), - new EnchantmentInstance(Enchantment::SHARPNESS(), 1) + new EnchantmentInstance(VanillaEnchantments::EFFICIENCY(), 5), + new EnchantmentInstance(VanillaEnchantments::SHARPNESS(), 1) ]; foreach($enchantments as $enchantment){ $this->item->addEnchantment($enchantment); @@ -113,31 +109,31 @@ class ItemTest extends TestCase{ } public function testOverwriteEnchantment() : void{ - $this->item->addEnchantment(new EnchantmentInstance(Enchantment::SHARPNESS())); - $this->item->addEnchantment(new EnchantmentInstance(Enchantment::SHARPNESS(), 5)); - self::assertSame(5, $this->item->getEnchantmentLevel(Enchantment::SHARPNESS())); + $this->item->addEnchantment(new EnchantmentInstance(VanillaEnchantments::SHARPNESS())); + $this->item->addEnchantment(new EnchantmentInstance(VanillaEnchantments::SHARPNESS(), 5)); + self::assertSame(5, $this->item->getEnchantmentLevel(VanillaEnchantments::SHARPNESS())); } public function testRemoveAllEnchantments() : void{ - $this->item->addEnchantment(new EnchantmentInstance(Enchantment::FIRE_ASPECT())); + $this->item->addEnchantment(new EnchantmentInstance(VanillaEnchantments::FIRE_ASPECT())); self::assertCount(1, $this->item->getEnchantments()); $this->item->removeEnchantments(); self::assertEmpty($this->item->getEnchantments()); } public function testRemoveEnchantment() : void{ - $this->item->addEnchantment(new EnchantmentInstance(Enchantment::KNOCKBACK())); - $this->item->addEnchantment(new EnchantmentInstance(Enchantment::SHARPNESS())); + $this->item->addEnchantment(new EnchantmentInstance(VanillaEnchantments::KNOCKBACK())); + $this->item->addEnchantment(new EnchantmentInstance(VanillaEnchantments::SHARPNESS())); self::assertCount(2, $this->item->getEnchantments()); - $this->item->removeEnchantment(Enchantment::SHARPNESS()); - self::assertFalse($this->item->hasEnchantment(Enchantment::SHARPNESS())); + $this->item->removeEnchantment(VanillaEnchantments::SHARPNESS()); + self::assertFalse($this->item->hasEnchantment(VanillaEnchantments::SHARPNESS())); } public function testRemoveEnchantmentLevel() : void{ - $this->item->addEnchantment(new EnchantmentInstance(Enchantment::FIRE_ASPECT(), 2)); - $this->item->addEnchantment(new EnchantmentInstance(Enchantment::UNBREAKING())); + $this->item->addEnchantment(new EnchantmentInstance(VanillaEnchantments::FIRE_ASPECT(), 2)); + $this->item->addEnchantment(new EnchantmentInstance(VanillaEnchantments::UNBREAKING())); self::assertCount(2, $this->item->getEnchantments()); - $this->item->removeEnchantment(Enchantment::FIRE_ASPECT(), 2); - self::assertFalse($this->item->hasEnchantment(Enchantment::FIRE_ASPECT())); + $this->item->removeEnchantment(VanillaEnchantments::FIRE_ASPECT(), 2); + self::assertFalse($this->item->hasEnchantment(VanillaEnchantments::FIRE_ASPECT())); } } From 9947e131211bab07a7b7d7bf816ba871e1fbb873 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 23 Oct 2020 21:04:27 +0100 Subject: [PATCH 1964/3224] Yank constants out of Enchantment base class --- src/item/enchantment/Enchantment.php | 65 ------------------ src/item/enchantment/EnchantmentIds.php | 69 ++++++++++++++++++++ src/item/enchantment/ItemFlags.php | 55 ++++++++++++++++ src/item/enchantment/Rarity.php | 35 ++++++++++ src/item/enchantment/VanillaEnchantments.php | 38 +++++------ 5 files changed, 178 insertions(+), 84 deletions(-) create mode 100644 src/item/enchantment/EnchantmentIds.php create mode 100644 src/item/enchantment/ItemFlags.php create mode 100644 src/item/enchantment/Rarity.php diff --git a/src/item/enchantment/Enchantment.php b/src/item/enchantment/Enchantment.php index 85c321d367..f2a9101da1 100644 --- a/src/item/enchantment/Enchantment.php +++ b/src/item/enchantment/Enchantment.php @@ -30,71 +30,6 @@ use function constant; */ class Enchantment{ - public const PROTECTION = 0; - public const FIRE_PROTECTION = 1; - public const FEATHER_FALLING = 2; - public const BLAST_PROTECTION = 3; - public const PROJECTILE_PROTECTION = 4; - public const THORNS = 5; - public const RESPIRATION = 6; - public const DEPTH_STRIDER = 7; - public const AQUA_AFFINITY = 8; - public const SHARPNESS = 9; - public const SMITE = 10; - public const BANE_OF_ARTHROPODS = 11; - public const KNOCKBACK = 12; - public const FIRE_ASPECT = 13; - public const LOOTING = 14; - public const EFFICIENCY = 15; - public const SILK_TOUCH = 16; - public const UNBREAKING = 17; - public const FORTUNE = 18; - public const POWER = 19; - public const PUNCH = 20; - public const FLAME = 21; - public const INFINITY = 22; - public const LUCK_OF_THE_SEA = 23; - public const LURE = 24; - public const FROST_WALKER = 25; - public const MENDING = 26; - public const BINDING = 27; - public const VANISHING = 28; - public const IMPALING = 29; - public const RIPTIDE = 30; - public const LOYALTY = 31; - public const CHANNELING = 32; - public const MULTISHOT = 33; - public const PIERCING = 34; - public const QUICK_CHARGE = 35; - public const SOUL_SPEED = 36; - - public const RARITY_COMMON = 10; - public const RARITY_UNCOMMON = 5; - public const RARITY_RARE = 2; - public const RARITY_MYTHIC = 1; - - public const SLOT_NONE = 0x0; - public const SLOT_ALL = 0xffff; - public const SLOT_ARMOR = self::SLOT_HEAD | self::SLOT_TORSO | self::SLOT_LEGS | self::SLOT_FEET; - public const SLOT_HEAD = 0x1; - public const SLOT_TORSO = 0x2; - public const SLOT_LEGS = 0x4; - public const SLOT_FEET = 0x8; - public const SLOT_SWORD = 0x10; - public const SLOT_BOW = 0x20; - public const SLOT_TOOL = self::SLOT_HOE | self::SLOT_SHEARS | self::SLOT_FLINT_AND_STEEL; - public const SLOT_HOE = 0x40; - public const SLOT_SHEARS = 0x80; - public const SLOT_FLINT_AND_STEEL = 0x100; - public const SLOT_DIG = self::SLOT_AXE | self::SLOT_PICKAXE | self::SLOT_SHOVEL; - public const SLOT_AXE = 0x200; - public const SLOT_PICKAXE = 0x400; - public const SLOT_SHOVEL = 0x800; - public const SLOT_FISHING_ROD = 0x1000; - public const SLOT_CARROT_STICK = 0x2000; - public const SLOT_ELYTRA = 0x4000; - public const SLOT_TRIDENT = 0x8000; - /** @var int */ private $id; /** @var string */ diff --git a/src/item/enchantment/EnchantmentIds.php b/src/item/enchantment/EnchantmentIds.php new file mode 100644 index 0000000000..cf64bb5694 --- /dev/null +++ b/src/item/enchantment/EnchantmentIds.php @@ -0,0 +1,69 @@ + Date: Sat, 24 Oct 2020 10:43:14 +0500 Subject: [PATCH 1965/3224] Handle InvalidArgumentException thrown by VanillaEnchantments::fromString (#3878) --- src/command/defaults/EnchantCommand.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/command/defaults/EnchantCommand.php b/src/command/defaults/EnchantCommand.php index 05cec32ee6..89a252fcba 100644 --- a/src/command/defaults/EnchantCommand.php +++ b/src/command/defaults/EnchantCommand.php @@ -69,13 +69,17 @@ class EnchantCommand extends VanillaCommand{ if(is_numeric($args[1])){ $enchantment = VanillaEnchantments::byMcpeId((int) $args[1]); + if(!($enchantment instanceof Enchantment)){ + $sender->sendMessage(new TranslationContainer("commands.enchant.notFound", [$args[1]])); + return true; + } }else{ - $enchantment = VanillaEnchantments::fromString($args[1]); - } - - if(!($enchantment instanceof Enchantment)){ - $sender->sendMessage(new TranslationContainer("commands.enchant.notFound", [$args[1]])); - return true; + try{ + $enchantment = VanillaEnchantments::fromString($args[1]); + }catch(\InvalidArgumentException $e){ + $sender->sendMessage(new TranslationContainer("commands.enchant.notFound", [$args[1]])); + return true; + } } $level = 1; From 2e1239f77aef44f8ba2b905ca955c41a4fdb9ff2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 24 Oct 2020 17:33:17 +0100 Subject: [PATCH 1966/3224] EnchantCommand no longer accepts numeric enchantment IDs --- src/command/defaults/EnchantCommand.php | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/command/defaults/EnchantCommand.php b/src/command/defaults/EnchantCommand.php index 89a252fcba..8ae0d43d1d 100644 --- a/src/command/defaults/EnchantCommand.php +++ b/src/command/defaults/EnchantCommand.php @@ -25,13 +25,11 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; -use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\EnchantmentInstance; use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\lang\TranslationContainer; use pocketmine\utils\TextFormat; use function count; -use function is_numeric; class EnchantCommand extends VanillaCommand{ @@ -67,19 +65,11 @@ class EnchantCommand extends VanillaCommand{ return true; } - if(is_numeric($args[1])){ - $enchantment = VanillaEnchantments::byMcpeId((int) $args[1]); - if(!($enchantment instanceof Enchantment)){ - $sender->sendMessage(new TranslationContainer("commands.enchant.notFound", [$args[1]])); - return true; - } - }else{ - try{ - $enchantment = VanillaEnchantments::fromString($args[1]); - }catch(\InvalidArgumentException $e){ - $sender->sendMessage(new TranslationContainer("commands.enchant.notFound", [$args[1]])); - return true; - } + try{ + $enchantment = VanillaEnchantments::fromString($args[1]); + }catch(\InvalidArgumentException $e){ + $sender->sendMessage(new TranslationContainer("commands.enchant.notFound", [$args[1]])); + return true; } $level = 1; From 47976bac34bb03453ea3258d35b1bce808ee3a87 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 24 Oct 2020 17:59:46 +0100 Subject: [PATCH 1967/3224] Moved enchantment ID handling to pocketmine/data/bedrock package this permits plugins to register their own enchantments mapped to MCPE IDs again. --- src/data/bedrock/EnchantmentIdMap.php | 95 +++++++++++++++++++ src/item/Item.php | 6 +- src/item/ItemEnchantmentHandlingTrait.php | 8 +- src/item/enchantment/Enchantment.php | 13 +-- src/item/enchantment/EnchantmentInstance.php | 7 +- .../enchantment/ProtectionEnchantment.php | 4 +- src/item/enchantment/VanillaEnchantments.php | 17 ---- .../data/bedrock/EnchantmentIdMapTest.php | 38 ++++++++ 8 files changed, 153 insertions(+), 35 deletions(-) create mode 100644 src/data/bedrock/EnchantmentIdMap.php create mode 100644 tests/phpunit/data/bedrock/EnchantmentIdMapTest.php diff --git a/src/data/bedrock/EnchantmentIdMap.php b/src/data/bedrock/EnchantmentIdMap.php new file mode 100644 index 0000000000..6b7c8bd19a --- /dev/null +++ b/src/data/bedrock/EnchantmentIdMap.php @@ -0,0 +1,95 @@ + + */ + private $idToEnch = []; + /** + * @var int[] + * @phpstan-var array + */ + private $enchToId = []; + + private function __construct(){ + $this->register(EnchantmentIds::PROTECTION, VanillaEnchantments::PROTECTION()); + $this->register(EnchantmentIds::FIRE_PROTECTION, VanillaEnchantments::FIRE_PROTECTION()); + $this->register(EnchantmentIds::FEATHER_FALLING, VanillaEnchantments::FEATHER_FALLING()); + $this->register(EnchantmentIds::BLAST_PROTECTION, VanillaEnchantments::BLAST_PROTECTION()); + $this->register(EnchantmentIds::PROJECTILE_PROTECTION, VanillaEnchantments::PROJECTILE_PROTECTION()); + $this->register(EnchantmentIds::THORNS, VanillaEnchantments::THORNS()); + $this->register(EnchantmentIds::RESPIRATION, VanillaEnchantments::RESPIRATION()); + + $this->register(EnchantmentIds::SHARPNESS, VanillaEnchantments::SHARPNESS()); + //TODO: smite, bane of arthropods (these don't make sense now because their applicable mobs don't exist yet) + + $this->register(EnchantmentIds::KNOCKBACK, VanillaEnchantments::KNOCKBACK()); + $this->register(EnchantmentIds::FIRE_ASPECT, VanillaEnchantments::FIRE_ASPECT()); + + $this->register(EnchantmentIds::EFFICIENCY, VanillaEnchantments::EFFICIENCY()); + $this->register(EnchantmentIds::SILK_TOUCH, VanillaEnchantments::SILK_TOUCH()); + $this->register(EnchantmentIds::UNBREAKING, VanillaEnchantments::UNBREAKING()); + + $this->register(EnchantmentIds::POWER, VanillaEnchantments::POWER()); + $this->register(EnchantmentIds::PUNCH, VanillaEnchantments::PUNCH()); + $this->register(EnchantmentIds::FLAME, VanillaEnchantments::FLAME()); + $this->register(EnchantmentIds::INFINITY, VanillaEnchantments::INFINITY()); + + $this->register(EnchantmentIds::MENDING, VanillaEnchantments::MENDING()); + + $this->register(EnchantmentIds::VANISHING, VanillaEnchantments::VANISHING()); + } + + public function register(int $mcpeId, Enchantment $enchantment) : void{ + $this->idToEnch[$mcpeId] = $enchantment; + $this->enchToId[$enchantment->getRuntimeId()] = $mcpeId; + } + + public function fromId(int $id) : ?Enchantment{ + //we might not have all the enchantment IDs registered + return $this->idToEnch[$id] ?? null; + } + + public function toId(Enchantment $enchantment) : int{ + if(!array_key_exists($enchantment->getRuntimeId(), $this->enchToId)){ + //this should never happen, so we treat it as an exceptional condition + throw new \InvalidArgumentException("Enchantment does not have a mapped ID"); + } + return $this->enchToId[$enchantment->getRuntimeId()]; + } +} diff --git a/src/item/Item.php b/src/item/Item.php index 7228c15cd3..10f270cce8 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -31,9 +31,9 @@ use pocketmine\block\Block; use pocketmine\block\BlockBreakInfo; use pocketmine\block\BlockToolType; use pocketmine\block\VanillaBlocks; +use pocketmine\data\bedrock\EnchantmentIdMap; use pocketmine\entity\Entity; use pocketmine\item\enchantment\EnchantmentInstance; -use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\math\Vector3; use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\NBT; @@ -285,7 +285,7 @@ class Item implements \JsonSerializable{ if($level <= 0){ continue; } - $type = VanillaEnchantments::byMcpeId($magicNumber); + $type = EnchantmentIdMap::getInstance()->fromId($magicNumber); if($type !== null){ $this->addEnchantment(new EnchantmentInstance($type, $level)); } @@ -336,7 +336,7 @@ class Item implements \JsonSerializable{ $ench = new ListTag(); foreach($this->getEnchantments() as $enchantmentInstance){ $ench->push(CompoundTag::create() - ->setShort("id", $enchantmentInstance->getType()->getId()) + ->setShort("id", EnchantmentIdMap::getInstance()->toId($enchantmentInstance->getType())) ->setShort("lvl", $enchantmentInstance->getLevel()) ); } diff --git a/src/item/ItemEnchantmentHandlingTrait.php b/src/item/ItemEnchantmentHandlingTrait.php index 9ef8c6ceea..8d44f0a07d 100644 --- a/src/item/ItemEnchantmentHandlingTrait.php +++ b/src/item/ItemEnchantmentHandlingTrait.php @@ -40,12 +40,12 @@ trait ItemEnchantmentHandlingTrait{ } public function hasEnchantment(Enchantment $enchantment, int $level = -1) : bool{ - $id = $enchantment->getId(); + $id = $enchantment->getRuntimeId(); return isset($this->enchantments[$id]) and ($level === -1 or $this->enchantments[$id]->getLevel() === $level); } public function getEnchantment(Enchantment $enchantment) : ?EnchantmentInstance{ - return $this->enchantments[$enchantment->getId()] ?? null; + return $this->enchantments[$enchantment->getRuntimeId()] ?? null; } /** @@ -54,7 +54,7 @@ trait ItemEnchantmentHandlingTrait{ public function removeEnchantment(Enchantment $enchantment, int $level = -1) : self{ $instance = $this->getEnchantment($enchantment); if($instance !== null and ($level === -1 or $instance->getLevel() === $level)){ - unset($this->enchantments[$enchantment->getId()]); + unset($this->enchantments[$enchantment->getRuntimeId()]); } return $this; @@ -72,7 +72,7 @@ trait ItemEnchantmentHandlingTrait{ * @return $this */ public function addEnchantment(EnchantmentInstance $enchantment) : self{ - $this->enchantments[$enchantment->getId()] = $enchantment; + $this->enchantments[$enchantment->getRuntimeId()] = $enchantment; return $this; } diff --git a/src/item/enchantment/Enchantment.php b/src/item/enchantment/Enchantment.php index f2a9101da1..c4081af967 100644 --- a/src/item/enchantment/Enchantment.php +++ b/src/item/enchantment/Enchantment.php @@ -31,7 +31,7 @@ use function constant; class Enchantment{ /** @var int */ - private $id; + private $internalRuntimeId; /** @var string */ private $name; /** @var int */ @@ -43,8 +43,8 @@ class Enchantment{ /** @var int */ private $maxLevel; - public function __construct(int $id, string $name, int $rarity, int $primaryItemFlags, int $secondaryItemFlags, int $maxLevel){ - $this->id = $id; + public function __construct(int $internalRuntimeId, string $name, int $rarity, int $primaryItemFlags, int $secondaryItemFlags, int $maxLevel){ + $this->internalRuntimeId = $internalRuntimeId; $this->name = $name; $this->rarity = $rarity; $this->primaryItemFlags = $primaryItemFlags; @@ -53,10 +53,11 @@ class Enchantment{ } /** - * Returns the ID of this enchantment as per Minecraft PE + * Returns the internal runtime ID of this enchantment. + * WARNING: DO NOT STORE THIS IDENTIFIER - IT MAY CHANGE AFTER RESTART */ - public function getId() : int{ - return $this->id; + public function getRuntimeId() : int{ + return $this->internalRuntimeId; } /** diff --git a/src/item/enchantment/EnchantmentInstance.php b/src/item/enchantment/EnchantmentInstance.php index f25c05d75a..443c33913f 100644 --- a/src/item/enchantment/EnchantmentInstance.php +++ b/src/item/enchantment/EnchantmentInstance.php @@ -53,10 +53,11 @@ final class EnchantmentInstance{ } /** - * Returns the type identifier of this enchantment instance. + * Returns the runtime type identifier of this enchantment instance. + * WARNING: DO NOT STORE THIS IDENTIFIER - IT MAY CHANGE AFTER SERVER RESTART */ - public function getId() : int{ - return $this->enchantment->getId(); + public function getRuntimeId() : int{ + return $this->enchantment->getRuntimeId(); } /** diff --git a/src/item/enchantment/ProtectionEnchantment.php b/src/item/enchantment/ProtectionEnchantment.php index 8fc603aa97..141678b07c 100644 --- a/src/item/enchantment/ProtectionEnchantment.php +++ b/src/item/enchantment/ProtectionEnchantment.php @@ -38,8 +38,8 @@ class ProtectionEnchantment extends Enchantment{ * * @param int[]|null $applicableDamageTypes EntityDamageEvent::CAUSE_* constants which this enchantment type applies to, or null if it applies to all types of damage. */ - public function __construct(int $id, string $name, int $rarity, int $primaryItemFlags, int $secondaryItemFlags, int $maxLevel, float $typeModifier, ?array $applicableDamageTypes){ - parent::__construct($id, $name, $rarity, $primaryItemFlags, $secondaryItemFlags, $maxLevel); + public function __construct(int $internalRuntimeId, string $name, int $rarity, int $primaryItemFlags, int $secondaryItemFlags, int $maxLevel, float $typeModifier, ?array $applicableDamageTypes){ + parent::__construct($internalRuntimeId, $name, $rarity, $primaryItemFlags, $secondaryItemFlags, $maxLevel); $this->typeModifier = $typeModifier; if($applicableDamageTypes !== null){ diff --git a/src/item/enchantment/VanillaEnchantments.php b/src/item/enchantment/VanillaEnchantments.php index eca5f7abb7..965b7316ca 100644 --- a/src/item/enchantment/VanillaEnchantments.php +++ b/src/item/enchantment/VanillaEnchantments.php @@ -25,7 +25,6 @@ namespace pocketmine\item\enchantment; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\utils\RegistryTrait; -use function array_key_exists; /** * This doc-block is generated automatically, do not modify it manually. @@ -55,12 +54,6 @@ use function array_key_exists; final class VanillaEnchantments{ use RegistryTrait; - /** - * @var Enchantment[] - * @phpstan-var array - */ - private static $mcpeIdMap = []; - protected static function setup() : void{ self::register("PROTECTION", new ProtectionEnchantment(EnchantmentIds::PROTECTION, "%enchantment.protect.all", Rarity::COMMON, ItemFlags::ARMOR, ItemFlags::NONE, 4, 0.75, null)); self::register("FIRE_PROTECTION", new ProtectionEnchantment(EnchantmentIds::FIRE_PROTECTION, "%enchantment.protect.fire", Rarity::UNCOMMON, ItemFlags::ARMOR, ItemFlags::NONE, 4, 1.25, [ @@ -103,17 +96,7 @@ final class VanillaEnchantments{ } protected static function register(string $name, Enchantment $member) : void{ - if(array_key_exists($member->getId(), self::$mcpeIdMap)){ - throw new \InvalidArgumentException("MCPE enchantment ID " . $member->getId() . " is already assigned"); - } self::_registryRegister($name, $member); - self::$mcpeIdMap[$member->getId()] = $member; - } - - public static function byMcpeId(int $id) : ?Enchantment{ - //TODO: this shouldn't be in here, it's unnecessarily limiting - self::checkInit(); - return self::$mcpeIdMap[$id] ?? null; } /** diff --git a/tests/phpunit/data/bedrock/EnchantmentIdMapTest.php b/tests/phpunit/data/bedrock/EnchantmentIdMapTest.php new file mode 100644 index 0000000000..eb1f35381a --- /dev/null +++ b/tests/phpunit/data/bedrock/EnchantmentIdMapTest.php @@ -0,0 +1,38 @@ +toId($enchantment); + $enchantment2 = EnchantmentIdMap::getInstance()->fromId($id); + self::assertTrue($enchantment === $enchantment2); + } + } +} From f3f7ff92379c3c9d3f44140636e5c2806863e590 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 24 Oct 2020 18:21:31 +0100 Subject: [PATCH 1968/3224] Enchantment internal IDs are now dynamic --- src/item/enchantment/VanillaEnchantments.php | 46 ++++++++++++-------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/src/item/enchantment/VanillaEnchantments.php b/src/item/enchantment/VanillaEnchantments.php index 965b7316ca..ef892499a8 100644 --- a/src/item/enchantment/VanillaEnchantments.php +++ b/src/item/enchantment/VanillaEnchantments.php @@ -54,45 +54,53 @@ use pocketmine\utils\RegistryTrait; final class VanillaEnchantments{ use RegistryTrait; + /** @var int|null */ + private static $nextRtId = 0; + + private static function newRtId() : int{ + //TODO: this functionality should probably be generalized + return self::$nextRtId++; + } + protected static function setup() : void{ - self::register("PROTECTION", new ProtectionEnchantment(EnchantmentIds::PROTECTION, "%enchantment.protect.all", Rarity::COMMON, ItemFlags::ARMOR, ItemFlags::NONE, 4, 0.75, null)); - self::register("FIRE_PROTECTION", new ProtectionEnchantment(EnchantmentIds::FIRE_PROTECTION, "%enchantment.protect.fire", Rarity::UNCOMMON, ItemFlags::ARMOR, ItemFlags::NONE, 4, 1.25, [ + self::register("PROTECTION", new ProtectionEnchantment(self::newRtId(), "%enchantment.protect.all", Rarity::COMMON, ItemFlags::ARMOR, ItemFlags::NONE, 4, 0.75, null)); + self::register("FIRE_PROTECTION", new ProtectionEnchantment(self::newRtId(), "%enchantment.protect.fire", Rarity::UNCOMMON, ItemFlags::ARMOR, ItemFlags::NONE, 4, 1.25, [ EntityDamageEvent::CAUSE_FIRE, EntityDamageEvent::CAUSE_FIRE_TICK, EntityDamageEvent::CAUSE_LAVA //TODO: check fireballs ])); - self::register("FEATHER_FALLING", new ProtectionEnchantment(EnchantmentIds::FEATHER_FALLING, "%enchantment.protect.fall", Rarity::UNCOMMON, ItemFlags::FEET, ItemFlags::NONE, 4, 2.5, [ + self::register("FEATHER_FALLING", new ProtectionEnchantment(self::newRtId(), "%enchantment.protect.fall", Rarity::UNCOMMON, ItemFlags::FEET, ItemFlags::NONE, 4, 2.5, [ EntityDamageEvent::CAUSE_FALL ])); - self::register("BLAST_PROTECTION", new ProtectionEnchantment(EnchantmentIds::BLAST_PROTECTION, "%enchantment.protect.explosion", Rarity::RARE, ItemFlags::ARMOR, ItemFlags::NONE, 4, 1.5, [ + self::register("BLAST_PROTECTION", new ProtectionEnchantment(self::newRtId(), "%enchantment.protect.explosion", Rarity::RARE, ItemFlags::ARMOR, ItemFlags::NONE, 4, 1.5, [ EntityDamageEvent::CAUSE_BLOCK_EXPLOSION, EntityDamageEvent::CAUSE_ENTITY_EXPLOSION ])); - self::register("PROJECTILE_PROTECTION", new ProtectionEnchantment(EnchantmentIds::PROJECTILE_PROTECTION, "%enchantment.protect.projectile", Rarity::UNCOMMON, ItemFlags::ARMOR, ItemFlags::NONE, 4, 1.5, [ + self::register("PROJECTILE_PROTECTION", new ProtectionEnchantment(self::newRtId(), "%enchantment.protect.projectile", Rarity::UNCOMMON, ItemFlags::ARMOR, ItemFlags::NONE, 4, 1.5, [ EntityDamageEvent::CAUSE_PROJECTILE ])); - self::register("THORNS", new Enchantment(EnchantmentIds::THORNS, "%enchantment.thorns", Rarity::MYTHIC, ItemFlags::TORSO, ItemFlags::HEAD | ItemFlags::LEGS | ItemFlags::FEET, 3)); - self::register("RESPIRATION", new Enchantment(EnchantmentIds::RESPIRATION, "%enchantment.oxygen", Rarity::RARE, ItemFlags::HEAD, ItemFlags::NONE, 3)); + self::register("THORNS", new Enchantment(self::newRtId(), "%enchantment.thorns", Rarity::MYTHIC, ItemFlags::TORSO, ItemFlags::HEAD | ItemFlags::LEGS | ItemFlags::FEET, 3)); + self::register("RESPIRATION", new Enchantment(self::newRtId(), "%enchantment.oxygen", Rarity::RARE, ItemFlags::HEAD, ItemFlags::NONE, 3)); - self::register("SHARPNESS", new SharpnessEnchantment(EnchantmentIds::SHARPNESS, "%enchantment.damage.all", Rarity::COMMON, ItemFlags::SWORD, ItemFlags::AXE, 5)); + self::register("SHARPNESS", new SharpnessEnchantment(self::newRtId(), "%enchantment.damage.all", Rarity::COMMON, ItemFlags::SWORD, ItemFlags::AXE, 5)); //TODO: smite, bane of arthropods (these don't make sense now because their applicable mobs don't exist yet) - self::register("KNOCKBACK", new KnockbackEnchantment(EnchantmentIds::KNOCKBACK, "%enchantment.knockback", Rarity::UNCOMMON, ItemFlags::SWORD, ItemFlags::NONE, 2)); - self::register("FIRE_ASPECT", new FireAspectEnchantment(EnchantmentIds::FIRE_ASPECT, "%enchantment.fire", Rarity::RARE, ItemFlags::SWORD, ItemFlags::NONE, 2)); + self::register("KNOCKBACK", new KnockbackEnchantment(self::newRtId(), "%enchantment.knockback", Rarity::UNCOMMON, ItemFlags::SWORD, ItemFlags::NONE, 2)); + self::register("FIRE_ASPECT", new FireAspectEnchantment(self::newRtId(), "%enchantment.fire", Rarity::RARE, ItemFlags::SWORD, ItemFlags::NONE, 2)); - self::register("EFFICIENCY", new Enchantment(EnchantmentIds::EFFICIENCY, "%enchantment.digging", Rarity::COMMON, ItemFlags::DIG, ItemFlags::SHEARS, 5)); - self::register("SILK_TOUCH", new Enchantment(EnchantmentIds::SILK_TOUCH, "%enchantment.untouching", Rarity::MYTHIC, ItemFlags::DIG, ItemFlags::SHEARS, 1)); - self::register("UNBREAKING", new Enchantment(EnchantmentIds::UNBREAKING, "%enchantment.durability", Rarity::UNCOMMON, ItemFlags::DIG | ItemFlags::ARMOR | ItemFlags::FISHING_ROD | ItemFlags::BOW, ItemFlags::TOOL | ItemFlags::CARROT_STICK | ItemFlags::ELYTRA, 3)); + self::register("EFFICIENCY", new Enchantment(self::newRtId(), "%enchantment.digging", Rarity::COMMON, ItemFlags::DIG, ItemFlags::SHEARS, 5)); + self::register("SILK_TOUCH", new Enchantment(self::newRtId(), "%enchantment.untouching", Rarity::MYTHIC, ItemFlags::DIG, ItemFlags::SHEARS, 1)); + self::register("UNBREAKING", new Enchantment(self::newRtId(), "%enchantment.durability", Rarity::UNCOMMON, ItemFlags::DIG | ItemFlags::ARMOR | ItemFlags::FISHING_ROD | ItemFlags::BOW, ItemFlags::TOOL | ItemFlags::CARROT_STICK | ItemFlags::ELYTRA, 3)); - self::register("POWER", new Enchantment(EnchantmentIds::POWER, "%enchantment.arrowDamage", Rarity::COMMON, ItemFlags::BOW, ItemFlags::NONE, 5)); - self::register("PUNCH", new Enchantment(EnchantmentIds::PUNCH, "%enchantment.arrowKnockback", Rarity::RARE, ItemFlags::BOW, ItemFlags::NONE, 2)); - self::register("FLAME", new Enchantment(EnchantmentIds::FLAME, "%enchantment.arrowFire", Rarity::RARE, ItemFlags::BOW, ItemFlags::NONE, 1)); - self::register("INFINITY", new Enchantment(EnchantmentIds::INFINITY, "%enchantment.arrowInfinite", Rarity::MYTHIC, ItemFlags::BOW, ItemFlags::NONE, 1)); + self::register("POWER", new Enchantment(self::newRtId(), "%enchantment.arrowDamage", Rarity::COMMON, ItemFlags::BOW, ItemFlags::NONE, 5)); + self::register("PUNCH", new Enchantment(self::newRtId(), "%enchantment.arrowKnockback", Rarity::RARE, ItemFlags::BOW, ItemFlags::NONE, 2)); + self::register("FLAME", new Enchantment(self::newRtId(), "%enchantment.arrowFire", Rarity::RARE, ItemFlags::BOW, ItemFlags::NONE, 1)); + self::register("INFINITY", new Enchantment(self::newRtId(), "%enchantment.arrowInfinite", Rarity::MYTHIC, ItemFlags::BOW, ItemFlags::NONE, 1)); - self::register("MENDING", new Enchantment(EnchantmentIds::MENDING, "%enchantment.mending", Rarity::RARE, ItemFlags::NONE, ItemFlags::ALL, 1)); + self::register("MENDING", new Enchantment(self::newRtId(), "%enchantment.mending", Rarity::RARE, ItemFlags::NONE, ItemFlags::ALL, 1)); - self::register("VANISHING", new Enchantment(EnchantmentIds::VANISHING, "%enchantment.curse.vanishing", Rarity::MYTHIC, ItemFlags::NONE, ItemFlags::ALL, 1)); + self::register("VANISHING", new Enchantment(self::newRtId(), "%enchantment.curse.vanishing", Rarity::MYTHIC, ItemFlags::NONE, ItemFlags::ALL, 1)); } protected static function register(string $name, Enchantment $member) : void{ From c5b925a2137692952bc7e9bab149807f3b557657 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 24 Oct 2020 18:24:39 +0100 Subject: [PATCH 1969/3224] Moved EnchantmentIds to pocketmine/data/bedrock package --- src/data/bedrock/EnchantmentIdMap.php | 1 - src/{item/enchantment => data/bedrock}/EnchantmentIds.php | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) rename src/{item/enchantment => data/bedrock}/EnchantmentIds.php (98%) diff --git a/src/data/bedrock/EnchantmentIdMap.php b/src/data/bedrock/EnchantmentIdMap.php index 6b7c8bd19a..9c9a783f2d 100644 --- a/src/data/bedrock/EnchantmentIdMap.php +++ b/src/data/bedrock/EnchantmentIdMap.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\data\bedrock; use pocketmine\item\enchantment\Enchantment; -use pocketmine\item\enchantment\EnchantmentIds; use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\utils\SingletonTrait; use function array_key_exists; diff --git a/src/item/enchantment/EnchantmentIds.php b/src/data/bedrock/EnchantmentIds.php similarity index 98% rename from src/item/enchantment/EnchantmentIds.php rename to src/data/bedrock/EnchantmentIds.php index cf64bb5694..51b076c11d 100644 --- a/src/item/enchantment/EnchantmentIds.php +++ b/src/data/bedrock/EnchantmentIds.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\item\enchantment; +namespace pocketmine\data\bedrock; final class EnchantmentIds{ From cf7f50af06c5dad06b34441bed74f6eabf072873 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 24 Oct 2020 18:25:42 +0100 Subject: [PATCH 1970/3224] Fixed test failure --- src/item/enchantment/VanillaEnchantments.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/item/enchantment/VanillaEnchantments.php b/src/item/enchantment/VanillaEnchantments.php index ef892499a8..42f074db60 100644 --- a/src/item/enchantment/VanillaEnchantments.php +++ b/src/item/enchantment/VanillaEnchantments.php @@ -54,7 +54,7 @@ use pocketmine\utils\RegistryTrait; final class VanillaEnchantments{ use RegistryTrait; - /** @var int|null */ + /** @var int */ private static $nextRtId = 0; private static function newRtId() : int{ From 3f254bd49c87b8bc25ff4848fa21d7ad64993bb2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 24 Oct 2020 18:52:20 +0100 Subject: [PATCH 1971/3224] Separated effects' MCPE ID registration from VanillaEffects --- src/data/bedrock/EffectIdMap.php | 97 +++++++++++++++++++ src/data/bedrock/EffectIds.php | 61 ++++++++++++ src/entity/Living.php | 5 +- src/entity/effect/Effect.php | 15 +-- src/entity/effect/EffectInstance.php | 4 - src/entity/effect/EffectManager.php | 8 +- src/entity/effect/PoisonEffect.php | 4 +- src/entity/effect/VanillaEffects.php | 10 -- src/network/mcpe/NetworkSession.php | 6 +- .../phpunit/data/bedrock/EffectIdMapTest.php | 38 ++++++++ 10 files changed, 217 insertions(+), 31 deletions(-) create mode 100644 src/data/bedrock/EffectIdMap.php create mode 100644 src/data/bedrock/EffectIds.php create mode 100644 tests/phpunit/data/bedrock/EffectIdMapTest.php diff --git a/src/data/bedrock/EffectIdMap.php b/src/data/bedrock/EffectIdMap.php new file mode 100644 index 0000000000..b9ccf24715 --- /dev/null +++ b/src/data/bedrock/EffectIdMap.php @@ -0,0 +1,97 @@ + + */ + private $idToEffect = []; + + /** + * @var int[] + * @phpstan-var array + */ + private $effectToId = []; + + private function __construct(){ + $this->register(EffectIds::SPEED, VanillaEffects::SPEED()); + $this->register(EffectIds::SLOWNESS, VanillaEffects::SLOWNESS()); + $this->register(EffectIds::HASTE, VanillaEffects::HASTE()); + $this->register(EffectIds::MINING_FATIGUE, VanillaEffects::MINING_FATIGUE()); + $this->register(EffectIds::STRENGTH, VanillaEffects::STRENGTH()); + $this->register(EffectIds::INSTANT_HEALTH, VanillaEffects::INSTANT_HEALTH()); + $this->register(EffectIds::INSTANT_DAMAGE, VanillaEffects::INSTANT_DAMAGE()); + $this->register(EffectIds::JUMP_BOOST, VanillaEffects::JUMP_BOOST()); + $this->register(EffectIds::NAUSEA, VanillaEffects::NAUSEA()); + $this->register(EffectIds::REGENERATION, VanillaEffects::REGENERATION()); + $this->register(EffectIds::RESISTANCE, VanillaEffects::RESISTANCE()); + $this->register(EffectIds::FIRE_RESISTANCE, VanillaEffects::FIRE_RESISTANCE()); + $this->register(EffectIds::WATER_BREATHING, VanillaEffects::WATER_BREATHING()); + $this->register(EffectIds::INVISIBILITY, VanillaEffects::INVISIBILITY()); + $this->register(EffectIds::BLINDNESS, VanillaEffects::BLINDNESS()); + $this->register(EffectIds::NIGHT_VISION, VanillaEffects::NIGHT_VISION()); + $this->register(EffectIds::HUNGER, VanillaEffects::HUNGER()); + $this->register(EffectIds::WEAKNESS, VanillaEffects::WEAKNESS()); + $this->register(EffectIds::POISON, VanillaEffects::POISON()); + $this->register(EffectIds::WITHER, VanillaEffects::WITHER()); + $this->register(EffectIds::HEALTH_BOOST, VanillaEffects::HEALTH_BOOST()); + $this->register(EffectIds::ABSORPTION, VanillaEffects::ABSORPTION()); + $this->register(EffectIds::SATURATION, VanillaEffects::SATURATION()); + $this->register(EffectIds::LEVITATION, VanillaEffects::LEVITATION()); + $this->register(EffectIds::FATAL_POISON, VanillaEffects::FATAL_POISON()); + $this->register(EffectIds::CONDUIT_POWER, VanillaEffects::CONDUIT_POWER()); + //TODO: SLOW_FALLING + //TODO: BAD_OMEN + //TODO: VILLAGE_HERO + } + + //TODO: not a big fan of the code duplication here :( + + public function register(int $mcpeId, Effect $effect) : void{ + $this->idToEffect[$mcpeId] = $effect; + $this->effectToId[$effect->getRuntimeId()] = $mcpeId; + } + + public function fromId(int $id) : ?Effect{ + //we might not have all the effect IDs registered + return $this->idToEffect[$id] ?? null; + } + + public function toId(Effect $effect) : int{ + if(!array_key_exists($effect->getRuntimeId(), $this->effectToId)){ + //this should never happen, so we treat it as an exceptional condition + throw new \InvalidArgumentException("Effect does not have a mapped ID"); + } + return $this->effectToId[$effect->getRuntimeId()]; + } +} diff --git a/src/data/bedrock/EffectIds.php b/src/data/bedrock/EffectIds.php new file mode 100644 index 0000000000..a54000f7f9 --- /dev/null +++ b/src/data/bedrock/EffectIds.php @@ -0,0 +1,61 @@ +getListTag("ActiveEffects"); if($activeEffectsTag !== null){ foreach($activeEffectsTag as $e){ - $effect = VanillaEffects::byMcpeId($e->getByte("Id")); + $effect = EffectIdMap::getInstance()->fromId($e->getByte("Id")); if($effect === null){ continue; } @@ -240,7 +241,7 @@ abstract class Living extends Entity{ $effects = []; foreach($this->effectManager->all() as $effect){ $effects[] = CompoundTag::create() - ->setByte("Id", $effect->getId()) + ->setByte("Id", EffectIdMap::getInstance()->toId($effect->getType())) ->setByte("Amplifier", Binary::signByte($effect->getAmplifier())) ->setInt("Duration", $effect->getDuration()) ->setByte("Ambient", $effect->isAmbient() ? 1 : 0) diff --git a/src/entity/effect/Effect.php b/src/entity/effect/Effect.php index a6b85ea062..277b16972d 100644 --- a/src/entity/effect/Effect.php +++ b/src/entity/effect/Effect.php @@ -30,7 +30,7 @@ use pocketmine\entity\Living; class Effect{ /** @var int */ - protected $id; + protected $internalRuntimeId; /** @var string */ protected $name; /** @var Color */ @@ -41,14 +41,14 @@ class Effect{ protected $hasBubbles; /** - * @param int $id Effect ID as per Minecraft PE + * @param int $internalRuntimeId Internal runtime ID, unique to this effect type. Used for comparisons. * @param string $name Translation key used for effect name * @param Color $color Color of bubbles given by this effect * @param bool $isBad Whether the effect is harmful * @param bool $hasBubbles Whether the effect has potion bubbles. Some do not (e.g. Instant Damage has its own particles instead of bubbles) */ - public function __construct(int $id, string $name, Color $color, bool $isBad = false, bool $hasBubbles = true){ - $this->id = $id; + public function __construct(int $internalRuntimeId, string $name, Color $color, bool $isBad = false, bool $hasBubbles = true){ + $this->internalRuntimeId = $internalRuntimeId; $this->name = $name; $this->color = $color; $this->bad = $isBad; @@ -56,10 +56,11 @@ class Effect{ } /** - * Returns the effect ID as per Minecraft PE + * Returns a unique identifier for this effect type + * WARNING: DO NOT STORE THIS - IT MAY CHANGE BETWEEN RESTARTS */ - public function getId() : int{ - return $this->id; + public function getRuntimeId() : int{ + return $this->internalRuntimeId; } /** diff --git a/src/entity/effect/EffectInstance.php b/src/entity/effect/EffectInstance.php index c006275e78..c908c7ec7a 100644 --- a/src/entity/effect/EffectInstance.php +++ b/src/entity/effect/EffectInstance.php @@ -58,10 +58,6 @@ class EffectInstance{ $this->color = $overrideColor ?? $effectType->getColor(); } - public function getId() : int{ - return $this->effectType->getId(); - } - public function getType() : Effect{ return $this->effectType; } diff --git a/src/entity/effect/EffectManager.php b/src/entity/effect/EffectManager.php index d5343b7779..93404120a0 100644 --- a/src/entity/effect/EffectManager.php +++ b/src/entity/effect/EffectManager.php @@ -83,7 +83,7 @@ class EffectManager{ * Removes the effect with the specified ID from the mob. */ public function remove(Effect $effectType) : void{ - $index = $effectType->getId(); + $index = $effectType->getRuntimeId(); if(isset($this->effects[$index])){ $effect = $this->effects[$index]; $hasExpired = $effect->hasExpired(); @@ -113,14 +113,14 @@ class EffectManager{ * effect. */ public function get(Effect $effect) : ?EffectInstance{ - return $this->effects[$effect->getId()] ?? null; + return $this->effects[$effect->getRuntimeId()] ?? null; } /** * Returns whether the specified effect is active on the mob. */ public function has(Effect $effect) : bool{ - return isset($this->effects[$effect->getId()]); + return isset($this->effects[$effect->getRuntimeId()]); } /** @@ -134,7 +134,7 @@ class EffectManager{ $oldEffect = null; $cancelled = false; - $index = $effect->getType()->getId(); + $index = $effect->getType()->getRuntimeId(); if(isset($this->effects[$index])){ $oldEffect = $this->effects[$index]; if( diff --git a/src/entity/effect/PoisonEffect.php b/src/entity/effect/PoisonEffect.php index 5c977be27b..e55da697ce 100644 --- a/src/entity/effect/PoisonEffect.php +++ b/src/entity/effect/PoisonEffect.php @@ -33,8 +33,8 @@ class PoisonEffect extends Effect{ /** @var bool */ private $fatal; - public function __construct(int $id, string $name, Color $color, bool $isBad = false, bool $hasBubbles = true, bool $fatal = false){ - parent::__construct($id, $name, $color, $isBad, $hasBubbles); + public function __construct(int $internalRuntimeId, string $name, Color $color, bool $isBad = false, bool $hasBubbles = true, bool $fatal = false){ + parent::__construct($internalRuntimeId, $name, $color, $isBad, $hasBubbles); $this->fatal = $fatal; } diff --git a/src/entity/effect/VanillaEffects.php b/src/entity/effect/VanillaEffects.php index 3458fc5874..562682dad8 100644 --- a/src/entity/effect/VanillaEffects.php +++ b/src/entity/effect/VanillaEffects.php @@ -62,9 +62,6 @@ use function assert; final class VanillaEffects{ use RegistryTrait; - /** @var Effect[] */ - private static $mcpeIdMap = []; - protected static function setup() : void{ self::register("absorption", new AbsorptionEffect(22, "%potion.absorption", new Color(0x25, 0x52, 0xa5))); //TODO: bad_omen @@ -99,13 +96,6 @@ final class VanillaEffects{ protected static function register(string $name, Effect $member) : void{ self::_registryRegister($name, $member); - assert(!isset(self::$mcpeIdMap[$member->getId()])); - self::$mcpeIdMap[$member->getId()] = $member; - } - - public static function byMcpeId(int $id) : ?Effect{ - self::checkInit(); - return self::$mcpeIdMap[$id] ?? null; } /** diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 214cc78632..51be7de817 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe; use Ds\Set; use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; +use pocketmine\data\bedrock\EffectIdMap; use pocketmine\entity\Attribute; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\Entity; @@ -742,11 +743,12 @@ class NetworkSession{ } public function onEntityEffectAdded(Living $entity, EffectInstance $effect, bool $replacesOldEffect) : void{ - $this->sendDataPacket(MobEffectPacket::add($entity->getId(), $replacesOldEffect, $effect->getId(), $effect->getAmplifier(), $effect->isVisible(), $effect->getDuration())); + //TODO: we may need yet another effect <=> ID map in the future depending on protocol changes + $this->sendDataPacket(MobEffectPacket::add($entity->getId(), $replacesOldEffect, EffectIdMap::getInstance()->toId($effect->getType()), $effect->getAmplifier(), $effect->isVisible(), $effect->getDuration())); } public function onEntityEffectRemoved(Living $entity, EffectInstance $effect) : void{ - $this->sendDataPacket(MobEffectPacket::remove($entity->getId(), $effect->getId())); + $this->sendDataPacket(MobEffectPacket::remove($entity->getId(), EffectIdMap::getInstance()->toId($effect->getType()))); } public function onEntityRemoved(Entity $entity) : void{ diff --git a/tests/phpunit/data/bedrock/EffectIdMapTest.php b/tests/phpunit/data/bedrock/EffectIdMapTest.php new file mode 100644 index 0000000000..51b5c4d74b --- /dev/null +++ b/tests/phpunit/data/bedrock/EffectIdMapTest.php @@ -0,0 +1,38 @@ +toId($e); + $e2 = EffectIdMap::getInstance()->fromId($id); + self::assertTrue($e === $e2); + } + } +} From 4c0c2ebd24162e1d75e486619f3ab36af379eb63 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 26 Oct 2020 15:56:30 +0000 Subject: [PATCH 1972/3224] CS cleanup --- src/block/BaseBanner.php | 3 --- src/entity/Entity.php | 2 +- src/item/Banner.php | 1 - src/item/VanillaItems.php | 1 - src/network/mcpe/handler/InGamePacketHandler.php | 1 - src/world/format/Chunk.php | 1 + src/world/generator/noise/Noise.php | 1 - 7 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/block/BaseBanner.php b/src/block/BaseBanner.php index dd5ac3f934..e09f72dbb8 100644 --- a/src/block/BaseBanner.php +++ b/src/block/BaseBanner.php @@ -26,7 +26,6 @@ namespace pocketmine\block; use Ds\Deque; use pocketmine\block\tile\Banner as TileBanner; use pocketmine\block\utils\BannerPattern; -use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\DyeColor; use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\item\Banner as ItemBanner; @@ -34,12 +33,10 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\ItemIds; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\world\BlockTransaction; use function assert; -use function floor; abstract class BaseBanner extends Transparent{ /** @var DyeColor */ diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 22e94962af..d49e9c0d58 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -63,8 +63,8 @@ use function cos; use function count; use function deg2rad; use function floor; +use function fmod; use function get_class; -use function is_array; use function is_infinite; use function is_nan; use function lcg_value; diff --git a/src/item/Banner.php b/src/item/Banner.php index a86adec2d4..1ceeeb369b 100644 --- a/src/item/Banner.php +++ b/src/item/Banner.php @@ -28,7 +28,6 @@ use pocketmine\block\Block; use pocketmine\block\tile\Banner as TileBanner; use pocketmine\block\utils\BannerPattern; use pocketmine\block\utils\DyeColor; -use pocketmine\block\VanillaBlocks; use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; diff --git a/src/item/VanillaItems.php b/src/item/VanillaItems.php index 1ff4f944cf..581b27d194 100644 --- a/src/item/VanillaItems.php +++ b/src/item/VanillaItems.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\utils\CloningRegistryTrait; -use pocketmine\utils\RegistryTrait; use function assert; /** diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 5c25d54228..1c253d90eb 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -64,7 +64,6 @@ use pocketmine\network\mcpe\protocol\InteractPacket; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket; use pocketmine\network\mcpe\protocol\LabTablePacket; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacketV1; use pocketmine\network\mcpe\protocol\MapInfoRequestPacket; use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket; diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 59602ce5a1..f2a89b7ef4 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -40,6 +40,7 @@ use function array_fill; use function array_filter; use function array_map; use function count; +use function max; use function str_repeat; class Chunk{ diff --git a/src/world/generator/noise/Noise.php b/src/world/generator/noise/Noise.php index f4d722f2d2..fde81d10b1 100644 --- a/src/world/generator/noise/Noise.php +++ b/src/world/generator/noise/Noise.php @@ -294,7 +294,6 @@ abstract class Noise{ } } - /** * The following code originally called trilinearLerp() in a loop, but it was later inlined to elide function * call overhead. From 8bab9cc108bdb357e66d3fbdd04fe4ec1d32539a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 26 Oct 2020 15:34:32 +0000 Subject: [PATCH 1973/3224] RegionWorldProvider: use morton2d directly instead of abusing chunkHash() while these currently do the same thing, it's very confusing and creates an unnecessary dependency on World. --- src/world/format/io/region/RegionWorldProvider.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index 7203d4cbad..06c259f371 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -33,12 +33,12 @@ use pocketmine\world\format\io\data\JavaWorldData; use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\WorldData; use pocketmine\world\generator\Generator; -use pocketmine\world\World; use function assert; use function file_exists; use function is_dir; use function is_int; use function mkdir; +use function morton2d_encode; use function rename; use function scandir; use function strrpos; @@ -118,7 +118,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ } protected function getRegion(int $regionX, int $regionZ) : ?RegionLoader{ - return $this->regions[World::chunkHash($regionX, $regionZ)] ?? null; + return $this->regions[morton2d_encode($regionX, $regionZ)] ?? null; } /** @@ -129,7 +129,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ } protected function loadRegion(int $regionX, int $regionZ) : void{ - if(!isset($this->regions[$index = World::chunkHash($regionX, $regionZ)])){ + if(!isset($this->regions[$index = morton2d_encode($regionX, $regionZ)])){ $path = $this->pathToRegion($regionX, $regionZ); $region = new RegionLoader($path); @@ -154,7 +154,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ } protected function unloadRegion(int $regionX, int $regionZ) : void{ - if(isset($this->regions[$hash = World::chunkHash($regionX, $regionZ)])){ + if(isset($this->regions[$hash = morton2d_encode($regionX, $regionZ)])){ $this->regions[$hash]->close(); unset($this->regions[$hash]); } From 390bc631c83b98c0895529bbaefa2e9b0150d4c4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 26 Oct 2020 16:04:31 +0000 Subject: [PATCH 1974/3224] SubChunk: added moveToChunk() --- src/world/utils/SubChunkExplorer.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/world/utils/SubChunkExplorer.php b/src/world/utils/SubChunkExplorer.php index 7dd1fc0db3..a50226bbb2 100644 --- a/src/world/utils/SubChunkExplorer.php +++ b/src/world/utils/SubChunkExplorer.php @@ -86,6 +86,11 @@ class SubChunkExplorer{ return true; } + public function moveToChunk(int $chunkX, int $chunkY, int $chunkZ, bool $create) : bool{ + //this is a cold path, so we don't care much if it's a bit slower (extra fcall overhead) + return $this->moveTo($chunkX << 4, $chunkY << 4, $chunkZ << 4, $create); + } + /** * @phpstan-param \Closure() : void $callback */ From 31c2c3abb5badb414539c8640d6cf2868854bcaf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 26 Oct 2020 16:25:21 +0000 Subject: [PATCH 1975/3224] SubChunkExplorer::moveTo() now returns a status this can be used by SubChunkExplorer subclasses to implement specialized logic. --- src/world/Explosion.php | 3 +- src/world/SimpleChunkManager.php | 5 +-- src/world/light/BlockLightUpdate.php | 3 +- src/world/light/LightUpdate.php | 9 +++--- src/world/light/SkyLightUpdate.php | 3 +- src/world/utils/SubChunkExplorer.php | 17 +++++++--- src/world/utils/SubChunkExplorerStatus.php | 37 ++++++++++++++++++++++ 7 files changed, 63 insertions(+), 14 deletions(-) create mode 100644 src/world/utils/SubChunkExplorerStatus.php diff --git a/src/world/Explosion.php b/src/world/Explosion.php index 49952a3063..41e24ed6de 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -40,6 +40,7 @@ use pocketmine\math\Vector3; use pocketmine\world\particle\HugeExplodeSeedParticle; use pocketmine\world\sound\ExplodeSound; use pocketmine\world\utils\SubChunkExplorer; +use pocketmine\world\utils\SubChunkExplorerStatus; use function ceil; use function floor; use function mt_rand; @@ -123,7 +124,7 @@ class Explosion{ $pointerY += $shiftY; $pointerZ += $shiftZ; - if(!$this->subChunkExplorer->moveTo($vBlockX, $vBlockY, $vBlockZ, false)){ + if($this->subChunkExplorer->moveTo($vBlockX, $vBlockY, $vBlockZ, false) === SubChunkExplorerStatus::INVALID){ continue; } diff --git a/src/world/SimpleChunkManager.php b/src/world/SimpleChunkManager.php index 9ffeab3345..5540ad51b0 100644 --- a/src/world/SimpleChunkManager.php +++ b/src/world/SimpleChunkManager.php @@ -29,6 +29,7 @@ use pocketmine\block\VanillaBlocks; use pocketmine\utils\Limits; use pocketmine\world\format\Chunk; use pocketmine\world\utils\SubChunkExplorer; +use pocketmine\world\utils\SubChunkExplorerStatus; class SimpleChunkManager implements ChunkManager{ @@ -50,14 +51,14 @@ class SimpleChunkManager implements ChunkManager{ } public function getBlockAt(int $x, int $y, int $z) : Block{ - if($this->terrainPointer->moveTo($x, $y, $z, false)){ + if($this->terrainPointer->moveTo($x, $y, $z, false) !== SubChunkExplorerStatus::INVALID){ return BlockFactory::getInstance()->fromFullBlock($this->terrainPointer->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf)); } return VanillaBlocks::AIR(); } public function setBlockAt(int $x, int $y, int $z, Block $block) : void{ - if($this->terrainPointer->moveTo($x, $y, $z, true)){ + if($this->terrainPointer->moveTo($x, $y, $z, true) !== SubChunkExplorerStatus::INVALID){ $this->terrainPointer->currentSubChunk->setFullBlock($x & 0xf, $y & 0xf, $z & 0xf, $block->getFullId()); $this->terrainPointer->currentChunk->setDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN, true); }else{ diff --git a/src/world/light/BlockLightUpdate.php b/src/world/light/BlockLightUpdate.php index 6a1fbfc73e..323e5cd36d 100644 --- a/src/world/light/BlockLightUpdate.php +++ b/src/world/light/BlockLightUpdate.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\world\light; use pocketmine\world\utils\SubChunkExplorer; +use pocketmine\world\utils\SubChunkExplorerStatus; use function max; class BlockLightUpdate extends LightUpdate{ @@ -50,7 +51,7 @@ class BlockLightUpdate extends LightUpdate{ } public function recalculateNode(int $x, int $y, int $z) : void{ - if($this->subChunkExplorer->moveTo($x, $y, $z, false)){ + if($this->subChunkExplorer->moveTo($x, $y, $z, false) !== SubChunkExplorerStatus::INVALID){ $block = $this->subChunkExplorer->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf); $this->setAndUpdateLight($x, $y, $z, max($this->lightEmitters[$block], $this->getHighestAdjacentLight($x, $y, $z) - $this->lightFilters[$block])); } diff --git a/src/world/light/LightUpdate.php b/src/world/light/LightUpdate.php index afa029ed33..639e3416ac 100644 --- a/src/world/light/LightUpdate.php +++ b/src/world/light/LightUpdate.php @@ -25,6 +25,7 @@ namespace pocketmine\world\light; use pocketmine\world\format\LightArray; use pocketmine\world\utils\SubChunkExplorer; +use pocketmine\world\utils\SubChunkExplorerStatus; use pocketmine\world\World; use function max; @@ -65,7 +66,7 @@ abstract class LightUpdate{ abstract public function recalculateNode(int $x, int $y, int $z) : void; protected function getEffectiveLight(int $x, int $y, int $z) : int{ - if($this->subChunkExplorer->moveTo($x, $y, $z, false)){ + if($this->subChunkExplorer->moveTo($x, $y, $z, false) !== SubChunkExplorerStatus::INVALID){ return $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); } return 0; @@ -95,7 +96,7 @@ abstract class LightUpdate{ private function prepareNodes() : LightPropagationContext{ $context = new LightPropagationContext(); foreach($this->updateNodes as $blockHash => [$x, $y, $z, $newLevel]){ - if($this->subChunkExplorer->moveTo($x, $y, $z, false)){ + if($this->subChunkExplorer->moveTo($x, $y, $z, false) !== SubChunkExplorerStatus::INVALID){ $oldLevel = $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); if($oldLevel !== $newLevel){ @@ -131,7 +132,7 @@ abstract class LightUpdate{ ]; foreach($points as [$cx, $cy, $cz]){ - if($this->subChunkExplorer->moveTo($cx, $cy, $cz, false)){ + if($this->subChunkExplorer->moveTo($cx, $cy, $cz, false) !== SubChunkExplorerStatus::INVALID){ $this->computeRemoveLight($cx, $cy, $cz, $oldAdjacentLight, $context); }elseif($this->getEffectiveLight($cx, $cy, $cz) > 0 and !isset($context->spreadVisited[$index = World::blockHash($cx, $cy, $cz)])){ $context->spreadVisited[$index] = true; @@ -161,7 +162,7 @@ abstract class LightUpdate{ ]; foreach($points as [$cx, $cy, $cz]){ - if($this->subChunkExplorer->moveTo($cx, $cy, $cz, false)){ + if($this->subChunkExplorer->moveTo($cx, $cy, $cz, false) !== SubChunkExplorerStatus::INVALID){ $this->computeSpreadLight($cx, $cy, $cz, $newAdjacentLight, $context); } } diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index 02189a8e26..6927463cbb 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\world\light; use pocketmine\world\utils\SubChunkExplorer; +use pocketmine\world\utils\SubChunkExplorerStatus; use pocketmine\world\World; use function max; @@ -59,7 +60,7 @@ class SkyLightUpdate extends LightUpdate{ } public function recalculateNode(int $x, int $y, int $z) : void{ - if(!$this->subChunkExplorer->moveTo($x, $y, $z, false)){ + if($this->subChunkExplorer->moveTo($x, $y, $z, false) === SubChunkExplorerStatus::INVALID){ return; } $chunk = $this->subChunkExplorer->currentChunk; diff --git a/src/world/utils/SubChunkExplorer.php b/src/world/utils/SubChunkExplorer.php index a50226bbb2..18f9b3b7d1 100644 --- a/src/world/utils/SubChunkExplorer.php +++ b/src/world/utils/SubChunkExplorer.php @@ -55,7 +55,10 @@ class SubChunkExplorer{ $this->world = $world; } - public function moveTo(int $x, int $y, int $z, bool $create) : bool{ + /** + * @phpstan-return SubChunkExplorerStatus::* + */ + public function moveTo(int $x, int $y, int $z, bool $create) : int{ if($this->currentChunk === null or $this->currentX !== ($x >> 4) or $this->currentZ !== ($z >> 4)){ $this->currentX = $x >> 4; $this->currentZ = $z >> 4; @@ -63,7 +66,7 @@ class SubChunkExplorer{ $this->currentChunk = $this->world->getChunk($this->currentX, $this->currentZ, $create); if($this->currentChunk === null){ - return false; + return SubChunkExplorerStatus::INVALID; } } @@ -72,7 +75,7 @@ class SubChunkExplorer{ if($this->currentY < 0 or $this->currentY >= $this->currentChunk->getHeight()){ $this->currentSubChunk = null; - return false; + return SubChunkExplorerStatus::INVALID; } $newSubChunk = $this->currentChunk->getSubChunk($y >> 4); @@ -81,12 +84,16 @@ class SubChunkExplorer{ if($this->onSubChunkChangeFunc !== null){ ($this->onSubChunkChangeFunc)(); } + return SubChunkExplorerStatus::MOVED; } - return true; + return SubChunkExplorerStatus::OK; } - public function moveToChunk(int $chunkX, int $chunkY, int $chunkZ, bool $create) : bool{ + /** + * @phpstan-return SubChunkExplorerStatus::* + */ + public function moveToChunk(int $chunkX, int $chunkY, int $chunkZ, bool $create) : int{ //this is a cold path, so we don't care much if it's a bit slower (extra fcall overhead) return $this->moveTo($chunkX << 4, $chunkY << 4, $chunkZ << 4, $create); } diff --git a/src/world/utils/SubChunkExplorerStatus.php b/src/world/utils/SubChunkExplorerStatus.php new file mode 100644 index 0000000000..43b32f1fa7 --- /dev/null +++ b/src/world/utils/SubChunkExplorerStatus.php @@ -0,0 +1,37 @@ + Date: Tue, 27 Oct 2020 17:03:57 +0000 Subject: [PATCH 1976/3224] PopulationTask: do not calculate lighting for chunks we do this ondemand now, which means this is just wasting CPU for the vast majority of generated chunks. --- src/world/generator/PopulationTask.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index f4f3df3acb..a35197084f 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\world\generator; -use pocketmine\block\BlockFactory; use pocketmine\scheduler\AsyncTask; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\FastChunkSerializer; @@ -118,11 +117,6 @@ class PopulationTask extends AsyncTask{ $chunk = $manager->getChunk($chunk->getX(), $chunk->getZ()); $chunk->setPopulated(); - $blockFactory = BlockFactory::getInstance(); - $chunk->recalculateHeightMap($blockFactory->blocksDirectSkyLight); - $chunk->populateSkyLight($blockFactory->lightFilter); - $chunk->setLightPopulated(); - $this->chunk = FastChunkSerializer::serialize($chunk); foreach($chunks as $i => $c){ From 0ecd68e4a777a570cacf35d02f7ba5d2dd678c47 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 27 Oct 2020 18:01:31 +0000 Subject: [PATCH 1977/3224] LightUpdate: remove premature optimisation which breaks when mass-update lighting is used when setBlockSkyLightArray/setBlockLightArray was used, currentLightArray would retain a reference to the old light array, which would cause false readings if SubChunkExplorer didn't move away from that subchunk and back. This causes a small degradation of performance, but I think it can be implemented differently anyway. This also fixes #3816. --- src/world/light/BlockLightUpdate.php | 5 +++-- src/world/light/LightUpdate.php | 23 +++++++++++------------ src/world/light/SkyLightUpdate.php | 5 +++-- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/world/light/BlockLightUpdate.php b/src/world/light/BlockLightUpdate.php index 323e5cd36d..6cd86e4d74 100644 --- a/src/world/light/BlockLightUpdate.php +++ b/src/world/light/BlockLightUpdate.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\light; +use pocketmine\world\format\LightArray; use pocketmine\world\utils\SubChunkExplorer; use pocketmine\world\utils\SubChunkExplorerStatus; use function max; @@ -46,8 +47,8 @@ class BlockLightUpdate extends LightUpdate{ $this->lightEmitters = $lightEmitters; } - protected function updateLightArrayRef() : void{ - $this->currentLightArray = $this->subChunkExplorer->currentSubChunk->getBlockLightArray(); + protected function getCurrentLightArray() : LightArray{ + return $this->subChunkExplorer->currentSubChunk->getBlockLightArray(); } public function recalculateNode(int $x, int $y, int $z) : void{ diff --git a/src/world/light/LightUpdate.php b/src/world/light/LightUpdate.php index 639e3416ac..8fb5569e27 100644 --- a/src/world/light/LightUpdate.php +++ b/src/world/light/LightUpdate.php @@ -47,9 +47,6 @@ abstract class LightUpdate{ /** @var SubChunkExplorer */ protected $subChunkExplorer; - /** @var LightArray|null */ - protected $currentLightArray = null; - /** * @param \SplFixedArray|int[] $lightFilters * @phpstan-param \SplFixedArray $lightFilters @@ -58,16 +55,15 @@ abstract class LightUpdate{ $this->lightFilters = $lightFilters; $this->subChunkExplorer = $subChunkExplorer; - $this->subChunkExplorer->onSubChunkChange(\Closure::fromCallable([$this, 'updateLightArrayRef'])); } - abstract protected function updateLightArrayRef() : void; + abstract protected function getCurrentLightArray() : LightArray; abstract public function recalculateNode(int $x, int $y, int $z) : void; protected function getEffectiveLight(int $x, int $y, int $z) : int{ if($this->subChunkExplorer->moveTo($x, $y, $z, false) !== SubChunkExplorerStatus::INVALID){ - return $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); + return $this->getCurrentLightArray()->get($x & 0xf, $y & 0xf, $z & 0xf); } return 0; } @@ -97,10 +93,11 @@ abstract class LightUpdate{ $context = new LightPropagationContext(); foreach($this->updateNodes as $blockHash => [$x, $y, $z, $newLevel]){ if($this->subChunkExplorer->moveTo($x, $y, $z, false) !== SubChunkExplorerStatus::INVALID){ - $oldLevel = $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); + $lightArray = $this->getCurrentLightArray(); + $oldLevel = $lightArray->get($x & 0xf, $y & 0xf, $z & 0xf); if($oldLevel !== $newLevel){ - $this->currentLightArray->set($x & 0xf, $y & 0xf, $z & 0xf, $newLevel); + $lightArray->set($x & 0xf, $y & 0xf, $z & 0xf, $newLevel); if($oldLevel < $newLevel){ //light increased $context->spreadVisited[$blockHash] = true; $context->spreadQueue->enqueue([$x, $y, $z]); @@ -172,10 +169,11 @@ abstract class LightUpdate{ } protected function computeRemoveLight(int $x, int $y, int $z, int $oldAdjacentLevel, LightPropagationContext $context) : void{ - $current = $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); + $lightArray = $this->getCurrentLightArray(); + $current = $lightArray->get($x & 0xf, $y & 0xf, $z & 0xf); if($current !== 0 and $current < $oldAdjacentLevel){ - $this->currentLightArray->set($x & 0xf, $y & 0xf, $z & 0xf, 0); + $lightArray->set($x & 0xf, $y & 0xf, $z & 0xf, 0); if(!isset($context->removalVisited[$index = World::blockHash($x, $y, $z)])){ $context->removalVisited[$index] = true; @@ -192,11 +190,12 @@ abstract class LightUpdate{ } protected function computeSpreadLight(int $x, int $y, int $z, int $newAdjacentLevel, LightPropagationContext $context) : void{ - $current = $this->currentLightArray->get($x & 0xf, $y & 0xf, $z & 0xf); + $lightArray = $this->getCurrentLightArray(); + $current = $lightArray->get($x & 0xf, $y & 0xf, $z & 0xf); $potentialLight = $newAdjacentLevel - $this->lightFilters[$this->subChunkExplorer->currentSubChunk->getFullBlock($x & 0x0f, $y & 0x0f, $z & 0x0f)]; if($current < $potentialLight){ - $this->currentLightArray->set($x & 0xf, $y & 0xf, $z & 0xf, $potentialLight); + $lightArray->set($x & 0xf, $y & 0xf, $z & 0xf, $potentialLight); if(!isset($context->spreadVisited[$index = World::blockHash($x, $y, $z)]) and $potentialLight > 1){ $context->spreadVisited[$index] = true; diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index 6927463cbb..daaa992395 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\light; +use pocketmine\world\format\LightArray; use pocketmine\world\utils\SubChunkExplorer; use pocketmine\world\utils\SubChunkExplorerStatus; use pocketmine\world\World; @@ -47,8 +48,8 @@ class SkyLightUpdate extends LightUpdate{ $this->directSkyLightBlockers = $directSkyLightBlockers; } - protected function updateLightArrayRef() : void{ - $this->currentLightArray = $this->subChunkExplorer->currentSubChunk->getBlockSkyLightArray(); + protected function getCurrentLightArray() : LightArray{ + return $this->subChunkExplorer->currentSubChunk->getBlockSkyLightArray(); } protected function getEffectiveLight(int $x, int $y, int $z) : int{ From 014317381fffa89257b5c6fb5ccbeb9abf9b3bc7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 27 Oct 2020 18:05:41 +0000 Subject: [PATCH 1978/3224] Sugarcane: deduplicate growth code this also fixes sugarcane attempting to grow past the top of the world (closes #3883). --- src/block/Sugarcane.php | 55 +++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/src/block/Sugarcane.php b/src/block/Sugarcane.php index 4014f138bc..c87926d8bf 100644 --- a/src/block/Sugarcane.php +++ b/src/block/Sugarcane.php @@ -53,27 +53,31 @@ class Sugarcane extends Flowable{ return 0b1111; } + private function grow() : void{ + for($y = 1; $y < 3; ++$y){ + if(!$this->pos->getWorld()->isInWorld($this->pos->x, $this->pos->y + $y, $this->pos->z)){ + break; + } + $b = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z); + if($b->getId() === BlockLegacyIds::AIR){ + $ev = new BlockGrowEvent($b, VanillaBlocks::SUGARCANE()); + $ev->call(); + if($ev->isCancelled()){ + break; + } + $this->pos->getWorld()->setBlock($b->pos, $ev->getNewState()); + }else{ + break; + } + } + $this->age = 0; + $this->pos->getWorld()->setBlock($this->pos, $this); + } + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof Fertilizer){ if(!$this->getSide(Facing::DOWN)->isSameType($this)){ - for($y = 1; $y < 3; ++$y){ - if(!$this->pos->getWorld()->isInWorld($this->pos->x, $this->pos->y + $y, $this->pos->z)){ - break; - } - $b = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z); - if($b->getId() === BlockLegacyIds::AIR){ - $ev = new BlockGrowEvent($b, VanillaBlocks::SUGARCANE()); - $ev->call(); - if($ev->isCancelled()){ - break; - } - $this->pos->getWorld()->setBlock($b->pos, $ev->getNewState()); - }else{ - break; - } - } - $this->age = 0; - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->grow(); } $item->pop(); @@ -98,20 +102,7 @@ class Sugarcane extends Flowable{ public function onRandomTick() : void{ if(!$this->getSide(Facing::DOWN)->isSameType($this)){ if($this->age === 15){ - for($y = 1; $y < 3; ++$y){ - $b = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z); - if($b->getId() === BlockLegacyIds::AIR){ - $ev = new BlockGrowEvent($b, VanillaBlocks::SUGARCANE()); - $ev->call(); - if($ev->isCancelled()){ - break; - } - $this->pos->getWorld()->setBlock($b->pos, $ev->getNewState()); - break; - } - } - $this->age = 0; - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->grow(); }else{ ++$this->age; $this->pos->getWorld()->setBlock($this->pos, $this); From 1859dac7895c8d7e92ce6011d566279f074a5b56 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 27 Oct 2020 18:29:32 +0000 Subject: [PATCH 1979/3224] Implemented self-contained (pass 1) chunk relighting this doesn't handle propagating light across chunk borders yet, since that's much more complex to implement. --- src/world/format/Chunk.php | 42 ---------------- src/world/light/BlockLightUpdate.php | 45 +++++++++++++++++ src/world/light/LightPopulationTask.php | 15 +++++- src/world/light/LightUpdate.php | 6 +++ src/world/light/SkyLightUpdate.php | 64 +++++++++++++++++++++++++ 5 files changed, 128 insertions(+), 44 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index f2a89b7ef4..0010063e41 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -40,7 +40,6 @@ use function array_fill; use function array_filter; use function array_map; use function count; -use function max; use function str_repeat; class Chunk{ @@ -323,47 +322,6 @@ class Chunk{ return $y + 1; } - /** - * Performs basic sky light population on the chunk. - * This does not cater for adjacent sky light, this performs direct sky light population only. This may cause some strange visual artifacts - * if the chunk is light-populated after being terrain-populated. - * - * @param \SplFixedArray|int[] $lightFilters - * @phpstan-param \SplFixedArray $lightFilters - * - * TODO: fast adjacent light spread - */ - public function populateSkyLight(\SplFixedArray $lightFilters) : void{ - $highestHeightMap = max($this->heightMap->getValues()); - $lowestFullyLitSubChunk = ($highestHeightMap >> 4) + (($highestHeightMap & 0xf) !== 0 ? 1 : 0); - for($y = 0; $y < $lowestFullyLitSubChunk; $y++){ - $this->getWritableSubChunk($y)->setBlockSkyLightArray(LightArray::fill(0)); - } - for($y = $lowestFullyLitSubChunk, $yMax = $this->subChunks->count(); $y < $yMax; $y++){ - $this->getWritableSubChunk($y)->setBlockSkyLightArray(LightArray::fill(15)); - } - - for($x = 0; $x < 16; ++$x){ - for($z = 0; $z < 16; ++$z){ - $y = ($lowestFullyLitSubChunk * 16) - 1; - $heightMap = $this->getHeightMap($x, $z); - - for(; $y >= $heightMap; --$y){ - $this->setBlockSkyLight($x, $y, $z, 15); - } - - $light = 15; - for(; $y >= 0; --$y){ - $light -= $lightFilters[$this->getFullBlock($x, $y, $z)]; - if($light <= 0){ - break; - } - $this->setBlockSkyLight($x, $y, $z, $light); - } - } - } - } - /** * Returns the biome ID at the specified X/Z chunk block coordinates * diff --git a/src/world/light/BlockLightUpdate.php b/src/world/light/BlockLightUpdate.php index 6cd86e4d74..d97b87d533 100644 --- a/src/world/light/BlockLightUpdate.php +++ b/src/world/light/BlockLightUpdate.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\world\light; use pocketmine\world\format\LightArray; +use pocketmine\world\format\SubChunk; use pocketmine\world\utils\SubChunkExplorer; use pocketmine\world\utils\SubChunkExplorerStatus; use function max; @@ -57,4 +58,48 @@ class BlockLightUpdate extends LightUpdate{ $this->setAndUpdateLight($x, $y, $z, max($this->lightEmitters[$block], $this->getHighestAdjacentLight($x, $y, $z) - $this->lightFilters[$block])); } } + + public function recalculateChunk(int $chunkX, int $chunkZ) : int{ + if($this->subChunkExplorer->moveToChunk($chunkX, 0, $chunkZ, false) === SubChunkExplorerStatus::INVALID){ + throw new \InvalidArgumentException("Chunk $chunkX $chunkZ does not exist"); + } + $chunk = $this->subChunkExplorer->currentChunk; + + $lightSources = 0; + foreach($chunk->getSubChunks() as $subChunkY => $subChunk){ + $subChunk->setBlockLightArray(LightArray::fill(0)); + + foreach($subChunk->getBlockLayers() as $layer){ + foreach($layer->getPalette() as $state){ + if($this->lightEmitters[$state] > 0){ + $lightSources += $this->scanForLightEmittingBlocks($subChunk, $chunkX << 4, $subChunkY << 4, $chunkZ << 4); + break 2; + } + } + } + } + + return $lightSources; + } + + private function scanForLightEmittingBlocks(SubChunk $subChunk, int $baseX, int $baseY, int $baseZ) : int{ + $lightSources = 0; + for($x = 0; $x < 16; ++$x){ + for($z = 0; $z < 16; ++$z){ + for($y = 0; $y < 16; ++$y){ + $light = $this->lightEmitters[$subChunk->getFullBlock($x, $y, $z)]; + if($light > 0){ + $this->setAndUpdateLight( + $baseX + $x, + $baseY + $y, + $baseZ + $z, + $light + ); + $lightSources++; + } + } + } + } + return $lightSources; + } } diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index 61d839be7a..896c7a645d 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -28,6 +28,8 @@ use pocketmine\scheduler\AsyncTask; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\FastChunkSerializer; use pocketmine\world\format\LightArray; +use pocketmine\world\SimpleChunkManager; +use pocketmine\world\utils\SubChunkExplorer; use pocketmine\world\World; use function igbinary_serialize; use function igbinary_unserialize; @@ -61,9 +63,18 @@ class LightPopulationTask extends AsyncTask{ /** @var Chunk $chunk */ $chunk = FastChunkSerializer::deserialize($this->chunk); + $manager = new SimpleChunkManager(); + $manager->setChunk($this->chunkX, $this->chunkZ, $chunk); + $blockFactory = BlockFactory::getInstance(); - $chunk->recalculateHeightMap($blockFactory->blocksDirectSkyLight); - $chunk->populateSkyLight($blockFactory->lightFilter); + foreach([ + "Block" => new BlockLightUpdate(new SubChunkExplorer($manager), $blockFactory->lightFilter, $blockFactory->light), + "Sky" => new SkyLightUpdate(new SubChunkExplorer($manager), $blockFactory->lightFilter, $blockFactory->blocksDirectSkyLight), + ] as $name => $update){ + $update->recalculateChunk($this->chunkX, $this->chunkZ); + $update->execute(); + } + $chunk->setLightPopulated(); $this->resultHeightMap = igbinary_serialize($chunk->getHeightMapArray()); diff --git a/src/world/light/LightUpdate.php b/src/world/light/LightUpdate.php index 8fb5569e27..8fac2e378a 100644 --- a/src/world/light/LightUpdate.php +++ b/src/world/light/LightUpdate.php @@ -61,6 +61,12 @@ abstract class LightUpdate{ abstract public function recalculateNode(int $x, int $y, int $z) : void; + /** + * Scans for all light sources in the target chunk and adds them to the propagation queue. + * This erases preexisting light in the chunk. + */ + abstract public function recalculateChunk(int $chunkX, int $chunkZ) : int; + protected function getEffectiveLight(int $x, int $y, int $z) : int{ if($this->subChunkExplorer->moveTo($x, $y, $z, false) !== SubChunkExplorerStatus::INVALID){ return $this->getCurrentLightArray()->get($x & 0xf, $y & 0xf, $z & 0xf); diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index daaa992395..9b7674646f 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -96,4 +96,68 @@ class SkyLightUpdate extends LightUpdate{ $this->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentLight($x, $y, $z) - $this->lightFilters[$source])); } } + + public function recalculateChunk(int $chunkX, int $chunkZ) : int{ + if($this->subChunkExplorer->moveToChunk($chunkX, 0, $chunkZ, false) === SubChunkExplorerStatus::INVALID){ + throw new \InvalidArgumentException("Chunk $chunkX $chunkZ does not exist"); + } + $chunk = $this->subChunkExplorer->currentChunk; + + $chunk->recalculateHeightMap($this->directSkyLightBlockers); + + //setAndUpdateLight() won't bother propagating from nodes that are already what we want to change them to, so we + //have to avoid filling full light for any subchunk that contains a heightmap Y coordinate + $highestHeightMapPlusOne = max($chunk->getHeightMapArray()) + 1; + $lowestClearSubChunk = ($highestHeightMapPlusOne >> 4) + (($highestHeightMapPlusOne & 0xf) !== 0 ? 1 : 0); + $chunkHeight = $chunk->getSubChunks()->count(); + for($y = 0; $y < $lowestClearSubChunk && $y < $chunkHeight; $y++){ + $chunk->getWritableSubChunk($y)->setBlockSkyLightArray(LightArray::fill(0)); + } + for($y = $lowestClearSubChunk, $yMax = $chunkHeight; $y < $yMax; $y++){ + $chunk->getWritableSubChunk($y)->setBlockSkyLightArray(LightArray::fill(15)); + } + + $lightSources = 0; + + $baseX = $chunkX << 4; + $baseZ = $chunkZ << 4; + for($x = 0; $x < 16; ++$x){ + for($z = 0; $z < 16; ++$z){ + $currentHeight = $chunk->getHeightMap($x, $z); + $maxAdjacentHeight = 0; + if($x !== 0){ + $maxAdjacentHeight = max($maxAdjacentHeight, $chunk->getHeightMap($x - 1, $z)); + } + if($x !== 15){ + $maxAdjacentHeight = max($maxAdjacentHeight, $chunk->getHeightMap($x + 1, $z)); + } + if($z !== 0){ + $maxAdjacentHeight = max($maxAdjacentHeight, $chunk->getHeightMap($x, $z - 1)); + } + if($z !== 15){ + $maxAdjacentHeight = max($maxAdjacentHeight, $chunk->getHeightMap($x, $z + 1)); + } + + /* + * We skip the top two blocks between current height and max adjacent (if there's a difference) because: + * - the block next to the highest adjacent will do nothing during propagation (it's surrounded by 15s) + * - the block below that block will do the same as the node in the highest adjacent + * NOTE: If block opacity becomes direction-aware in the future, the second point will become invalid. + */ + $nodeColumnEnd = max($currentHeight, $maxAdjacentHeight - 2); + + for($y = $currentHeight; $y <= $nodeColumnEnd; $y++){ + $this->setAndUpdateLight($x + $baseX, $y, $z + $baseZ, 15); + $lightSources++; + } + for($y = $nodeColumnEnd + 1, $yMax = $lowestClearSubChunk * 16; $y < $yMax; $y++){ + if($this->subChunkExplorer->moveTo($x + $baseX, $y, $z + $baseZ, false) !== SubChunkExplorerStatus::INVALID){ + $this->getCurrentLightArray()->set($x, $y & 0xf, $z, 15); + } + } + } + } + + return $lightSources; + } } From 797e0996f4ce8af85e52d51714b77ea0ec0269eb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 27 Oct 2020 18:42:30 +0000 Subject: [PATCH 1980/3224] PopulationTask: Do not include light when serializing chunks (either way) non-populated chunks shouldn't be light-populated anyway, but in some cases they are (bug or plugin interference). chunks which were already populated might get modified by adjacent chunk populations, which should invalidate their lighting because generation doesn't track which blocks were changed, so the whole chunk should be recalculated. --- src/world/generator/PopulationTask.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index a35197084f..2ead5ece6e 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -61,10 +61,10 @@ class PopulationTask extends AsyncTask{ public function __construct(World $world, Chunk $chunk){ $this->state = true; $this->worldId = $world->getId(); - $this->chunk = FastChunkSerializer::serialize($chunk); + $this->chunk = FastChunkSerializer::serializeWithoutLight($chunk); foreach($world->getAdjacentChunks($chunk->getX(), $chunk->getZ()) as $i => $c){ - $this->{"chunk$i"} = $c !== null ? FastChunkSerializer::serialize($c) : null; + $this->{"chunk$i"} = $c !== null ? FastChunkSerializer::serializeWithoutLight($c) : null; } $this->storeLocal(self::TLS_KEY_WORLD, $world); @@ -117,10 +117,10 @@ class PopulationTask extends AsyncTask{ $chunk = $manager->getChunk($chunk->getX(), $chunk->getZ()); $chunk->setPopulated(); - $this->chunk = FastChunkSerializer::serialize($chunk); + $this->chunk = FastChunkSerializer::serializeWithoutLight($chunk); foreach($chunks as $i => $c){ - $this->{"chunk$i"} = $c->isDirty() ? FastChunkSerializer::serialize($c) : null; + $this->{"chunk$i"} = $c->isDirty() ? FastChunkSerializer::serializeWithoutLight($c) : null; } $manager->cleanChunks(); From 587a4c0095c9d064f60ba77b6c6cdd5841c264e6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 27 Oct 2020 19:35:03 +0000 Subject: [PATCH 1981/3224] non-exhaustive updates to changelog [ci skip] --- changelogs/4.0-snapshot.md | 84 +++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 32 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index ffac9f1389..58c79953e9 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -7,6 +7,7 @@ This major version features substantial changes throughout the core, including s - A new "plugin greylist" feature has been introduced, which allows whitelisting or blacklisting plugins from loading. - The `/reload` command has been removed. - The `/effect` command no longer supports numeric IDs - it's now required to use names. +- The `/enchant` command no longer supports numeric IDs - it's now required to use names. - Remote console (RCON) has been removed. The [RconServer](https://github.com/pmmp/RconServer) plugin is provided as a substitute. - Spawn protection has been removed. The [BasicSpawnProtection](https://github.com/pmmp/BasicSpawnProtection) plugin is provided as a substitute. - CTRL+C signal handling has been removed. The [PcntlSignalHandler](https://github.com/pmmp/PcntlSignalHandler) plugin is provided as a substitute. @@ -15,6 +16,7 @@ This major version features substantial changes throughout the core, including s - New PHP extensions are required by this version: - [ds](https://github.com/php-ds/ext-ds) - [chunkutils2](https://github.com/pmmp/ext-chunkutils2) + - [morton](https://github.com/pmmp/ext-morton) ### World handling #### Functional @@ -28,10 +30,12 @@ This major version features substantial changes throughout the core, including s - Extended blocks are now supported (facilitated by automatic conversion). - Unsupported world formats no longer causes a crash, but a graceful shutdown instead. - World corruption no longer causes a crash, but a graceful shutdown instead. +- Lighting is no longer stored or loaded from disk - instead, it's calculated on the fly as-needed. This fixes many long-standing bugs. #### Performance - `leveldb` is now the primary supported world format. It is inherently faster than region-based formats thanks to better design. - Partial chunk saves (only saving modified subcomponents of chunks) has been implemented. This drastically reduces the amount of data that is usually necessary to write on chunk save, which in turn **drastically reduces the time to complete world saves**. This is possible thanks to the modular design of the `leveldb` world format - this enhancement is not possible with region-based formats. +- Lighting is no longer guaranteed to be available on every chunk. It's now calculated on the fly as-needed. ### Logger revamp - Many components now have a dedicated logger which automatically adds [prefixes] to their messages. @@ -237,13 +241,19 @@ This version features substantial changes to the network system, improving coher - `SlownessEffect` - `SpeedEffect` - `WitherEffect` +- `VanillaEffects` class has been added. This exposes all vanilla effect types as static methods, replacing the old `Effect::getEffect()` nastiness. + - Example: `Effect::getEffect(Effect::NIGHT_VISION)` can be replaced by `VanillaEffects::NIGHT_VISION()`. - Negative effect amplifiers are now explicitly disallowed due to undefined behaviour they created. -- The following API methods have been renamed: - - `Effect::registerEffect()` -> `Effect::register()` - - `Effect::getEffect()` -> `Effect::get()` - - `Effect::getEffectByName()` -> `Effect::fromString()` -- Static getter methods for all registered enchantment types have been added. `Effect::getEffect(Effect::WHATEVER)` should be replaced by `VanillaEffects::WHATEVER()`. -- All effect registry functionality has been removed from the `Effect` base class and migrated to the `VanillaEffects` class. +- The boundaries between MCPE effect IDs and PocketMine-MP internals are now more clear. + - ID handling is moved to `pocketmine\data\bedrock\EffectIdMap`. + - All effect ID constants have been removed from `Effect`. `pocketmine\data\bedrock\EffectIds` if you still need legacy effect IDs for some reason. +- The following API methods have been moved: + - `Effect->getId()` -> `EffectIdMap->toId()` + - `Effect::registerEffect()` -> `EffectIdMap->register()` + - `Effect::getEffect()` -> `EffectIdMap->fromId()` + - `Effect::getEffectByName()` -> `VanillaEffects::fromString()` +- The following API methods have been added: + - `Effect->getRuntimeId()`: this is a **dynamic ID** which can be used for effect type comparisons. **This cannot be stored, so don't use it in configs or NBT!** #### Removal of runtime entity NBT - Entities no longer keep their NBT alive at runtime. @@ -252,21 +262,21 @@ This version features substantial changes to the network system, improving coher - `Entity->initEntity()` now accepts a `CompoundTag` parameter. #### Entity creation -- Entity class overriding is now explicitly supported, without needing to touch save IDs. - - Entity classes can be overridden using `EntityFactory::override()`. The provided replacement class **must** be a subclass of the existing class. If the existing class isn't there, an exception will be thrown. - - Attempting to register an entity to a save ID that is already registered will now cause an exception to be thrown. +- Runtime entity creation no longer requires `EntityFactory` - just use `new YourEntity` instead. +- Entity constructors no longer require `CompoundTag`. You can now make your entity constructors have any signature you want. +- `EntityFactory` now requires a creation callback (usually a closure) with the signature `function(World, CompoundTag) : Entity` to construct entities loaded from disk. This is required to allow entity classes to have custom constructor signatures. This callback should do any necessary actions to transform NBT into constructor parameters. + - Example: `ItemEntity` now requires an `Item` in its constructor, so its creation callback decodes the `Item` from the NBT to be passed to the constructor. + - Example: `Painting` now requires a `PaintingMotive` in its constructor, so its creation callback decides which `PaintingMotive` to provide based on the NBT it receives. + - See `EntityFactory` for more examples. +- `EntityFactory`'s responsibility as runtime entity creator has been removed. It's now solely responsible for restoring entities saved on disk. - Registering entities will now throw exceptions on error cases instead of returning `false`. -- Entity creation has now been split into two paths: - - `EntityFactory::create()`: Creates an entity by the given class. This accepts arguments to be passed to the entity constructor. This function is guaranteed to return an entity which is an instanceof the given class. - - `EntityFactory::createFromData()`: Creates an entity from save data. This may return any `Entity` class or `NULL`. This function is internal and shouldn't be used by plugins. -- It is no longer possible to directly create an entity by save ID. This is discouraged because save IDs are internal and format-dependent. - The following API methods have been moved: - `Entity::registerEntity()` -> `EntityFactory::register()` - - `Entity::createEntity()` -> `EntityFactory::create()` - - `Entity::getKnownEntityTypes()` -> `EntityFactory::getKnownTypes()` - - `Entity::createBaseNBT()` -> `EntityFactory::createBaseNBT()` + - `Entity::createBaseNBT()` -> `EntityDataHelper::createBaseNBT()` - The following API methods have been removed: - `Entity->getSaveId()` + - `Entity::getKnownEntityTypes()` + - `Entity::createEntity()`: use `new YourEntity` instead (to be reviewed) #### WIP removal of entity network metadata - All network metadata related constants have been removed from the `Entity` class and moved to the protocol layer. It is intended to remove network metadata from the API entirely, but this has not yet been completed. @@ -372,8 +382,15 @@ This version features substantial changes to the network system, improving coher - `InventoryChangeListener`: allows listening (but not interfering with) events in an inventory. - `transaction\CreateItemAction` - `transaction\DestroyItemAction` -- The following classes have been renamed: - - `ContainerInventory` -> `BlockInventory` +- The following classes have been renamed / moved: + - `ContainerInventory` -> `pocketmine\block\inventory\BlockInventory` +- The following classes have been moved to the `pocketmine\block\inventory` namespace: + - `AnvilInventory` + - `ChestInventory` + - `DoubleChestInventory` + - `EnchantInventory` + - `EnderChestInventory` + - `FurnaceInventory` - The following classes have been removed: - `CustomInventory` - `InventoryEventProcessor` @@ -484,11 +501,21 @@ This version features substantial changes to the network system, improving coher - It's planned to remove runtime NBT from items completely, but this currently presents unresolved backwards-compatibility problems. #### Enchantment -- The following API methods have been renamed: - - `Enchantment::registerEnchantment()` -> `Enchantment::register()` - - `Enchantment::getEnchantment()` -> `Enchantment::get()` - - `Enchantment::getEnchantmentByName()` -> `Enchantment::fromString()` -- Static getter methods for all registered enchantment types have been added. `Enchantment::getEnchantment(Enchantment::WHATEVER)` should be replaced by `Enchantment::WHATEVER()`. +- `VanillaEffects` class has been added. This exposes all vanilla enchantment types as static methods, replacing the old `Enchantment::get()` nastiness. + - Example: `Enchantment::get(Enchantment::PROTECTION)` is replaced by `VanillaEnchantments::PROTECTION()` + - These methods also provide proper type information to static analysers instead of just generic `Enchantment`, making them easier to code with. +- The boundaries between MCPE enchantment IDs and PocketMine-MP internals are now more clear. + - ID handling is moved to `pocketmine\data\bedrock\EnchantmentIdMap`. + - All enchantment ID constants have been removed from `Enchantment`. `pocketmine\data\bedrock\EnchantmentIds` if you still need legacy effect IDs for some reason. +- `Enchantment::RARITY_*` constants were moved to `Rarity` class, and the `RARITY_` prefixes removed. +- `Enchantment::SLOT_*` constants were moved to `ItemFlags` class, and the `SLOT_` prefixes removed. +- The following API methods have been moved: + - `Enchantment::registerEnchantment()` -> `EnchantmentIdMap->register()` + - `Enchantment::getEnchantment()` -> `EnchantmentIdMap->fromId()` + - `Enchantment->getId()` -> `EnchantmentIdMap->toId()` + - `Enchantment::getEnchantmentByName()` -> `VanillaEnchantments::fromString()` +- The following API methods have been added: + - `Enchantment->getRuntimeId()`: this is a **dynamic ID** which can be used for enchantment type comparisons. **This cannot be stored, so don't use it in configs or NBT!** ### Lang - The following classes have been renamed: @@ -742,6 +769,8 @@ This version features substantial changes to the network system, improving coher - `XpLevelUpSound` ### Utils +- The `Color` class was removed. It's now found as `pocketmine\color\Color` in the [`pocketmine/color`](https://github.com/pmmp/Color) package. +- The `UUID` class was removed. It's now found as `pocketmine\uuid\UUID` in the [`pocketmine/uuid`](https://github.com/pmmp/UUID) package. - `Terminal::hasFormattingCodes()` no longer auto-detects the availability of formatting codes. Instead it's necessary to use `Terminal::init()` with no parameters to initialize, or `true` or `false` to override. - `Config->save()` no longer catches exceptions thrown during emitting to disk. - The following new classes have been added: @@ -749,7 +778,6 @@ This version features substantial changes to the network system, improving coher - `Internet` - `Process` - The following API methods have been added: - - `Color::fromRGBA()` - `Config->getPath()`: returns the path to the config on disk - `Terminal::write()`: emits a Minecraft-formatted text line without newline - `Terminal::writeLine()`: emits a Minecraft-formatted text line with newline @@ -769,14 +797,6 @@ This version features substantial changes to the network system, improving coher - `Utils::$online` - `Utils::$os` - The following API methods have signature changes: - - `Color::mix()` now requires the first parameter. Previously, it was possible to pass zero arguments, which would raise an `ArgumentCountError` (not static analysis friendly). - `Internet::simpleCurl()` now requires a `Closure` for its `onSuccess` parameter instead of `callable`. - The following API methods have been removed: - - `Color->setA()` - - `Color->setR()` - - `Color->setG()` - - `Color->setB()` - - `Color->toABGR()` - - `Color->toBGRA()` - - `Color::fromABGR()` - `Utils::getCallableIdentifier()` From ddc0f137e7b4876bc52beb65fb2bfa9edf400cc9 Mon Sep 17 00:00:00 2001 From: Stephen B <17461354+buchwasa@users.noreply.github.com> Date: Tue, 27 Oct 2020 17:51:55 -0400 Subject: [PATCH 1982/3224] changelog: VanillaEffects -> VanillaEnchantments (#3884) [ci skip] --- changelogs/4.0-snapshot.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 58c79953e9..4c051190d3 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -501,7 +501,7 @@ This version features substantial changes to the network system, improving coher - It's planned to remove runtime NBT from items completely, but this currently presents unresolved backwards-compatibility problems. #### Enchantment -- `VanillaEffects` class has been added. This exposes all vanilla enchantment types as static methods, replacing the old `Enchantment::get()` nastiness. +- `VanillaEnchantments` class has been added. This exposes all vanilla enchantment types as static methods, replacing the old `Enchantment::get()` nastiness. - Example: `Enchantment::get(Enchantment::PROTECTION)` is replaced by `VanillaEnchantments::PROTECTION()` - These methods also provide proper type information to static analysers instead of just generic `Enchantment`, making them easier to code with. - The boundaries between MCPE enchantment IDs and PocketMine-MP internals are now more clear. From 3e1263eb79321ecfb6d309b6a76f745ebe951eff Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 29 Oct 2020 12:10:41 +0000 Subject: [PATCH 1983/3224] Chunk: remove all proxy APIs to lighting information these aren't used by internals and they shouldn't be used by plugins either. --- src/world/World.php | 4 +-- src/world/format/Chunk.php | 62 -------------------------------------- 2 files changed, 2 insertions(+), 64 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 93b2fa60dd..f059f589b1 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1826,7 +1826,7 @@ class World implements ChunkManager{ * @return int 0-15 */ public function getBlockSkyLightAt(int $x, int $y, int $z) : int{ - return $this->getOrLoadChunk($x >> 4, $z >> 4, true)->getBlockSkyLight($x & 0x0f, $y, $z & 0x0f); + return $this->getOrLoadChunk($x >> 4, $z >> 4, true)->getSubChunk($y >> 4)->getBlockSkyLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); } /** @@ -1835,7 +1835,7 @@ class World implements ChunkManager{ * @return int 0-15 */ public function getBlockLightAt(int $x, int $y, int $z) : int{ - return $this->getOrLoadChunk($x >> 4, $z >> 4, true)->getBlockLight($x & 0x0f, $y, $z & 0x0f); + return $this->getOrLoadChunk($x >> 4, $z >> 4, true)->getSubChunk($y >> 4)->getBlockLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); } public function getBiomeId(int $x, int $z) : int{ diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 0010063e41..95e2afba51 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -156,68 +156,6 @@ class Chunk{ $this->dirtyFlags |= self::DIRTY_FLAG_TERRAIN; } - /** - * Returns the sky light level at the specified chunk block coordinates - * - * @param int $x 0-15 - * @param int $y 0-255 - * @param int $z 0-15 - * - * @return int 0-15 - */ - public function getBlockSkyLight(int $x, int $y, int $z) : int{ - return $this->getSubChunk($y >> 4)->getBlockSkyLightArray()->get($x & 0xf, $y & 0x0f, $z & 0xf); - } - - /** - * Sets the sky light level at the specified chunk block coordinates - * - * @param int $x 0-15 - * @param int $y 0-255 - * @param int $z 0-15 - * @param int $level 0-15 - */ - public function setBlockSkyLight(int $x, int $y, int $z, int $level) : void{ - $this->getWritableSubChunk($y >> 4)->getBlockSkyLightArray()->set($x & 0xf, $y & 0x0f, $z & 0xf, $level); - } - - public function setAllBlockSkyLight(int $level) : void{ - for($y = $this->subChunks->count() - 1; $y >= 0; --$y){ - $this->getWritableSubChunk($y)->setBlockSkyLightArray(LightArray::fill($level)); - } - } - - /** - * Returns the block light level at the specified chunk block coordinates - * - * @param int $x 0-15 - * @param int $y 0-255 - * @param int $z 0-15 - * - * @return int 0-15 - */ - public function getBlockLight(int $x, int $y, int $z) : int{ - return $this->getSubChunk($y >> 4)->getBlockLightArray()->get($x & 0xf, $y & 0x0f, $z & 0xf); - } - - /** - * Sets the block light level at the specified chunk block coordinates - * - * @param int $x 0-15 - * @param int $y 0-255 - * @param int $z 0-15 - * @param int $level 0-15 - */ - public function setBlockLight(int $x, int $y, int $z, int $level) : void{ - $this->getWritableSubChunk($y >> 4)->getBlockLightArray()->set($x & 0xf, $y & 0x0f, $z & 0xf, $level); - } - - public function setAllBlockLight(int $level) : void{ - for($y = $this->subChunks->count() - 1; $y >= 0; --$y){ - $this->getWritableSubChunk($y)->setBlockLightArray(LightArray::fill($level)); - } - } - /** * Returns the Y coordinate of the highest non-air block at the specified X/Z chunk block coordinates * From 092a69e4156d32207ced5bec8c7143fa27093009 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 29 Oct 2020 12:18:29 +0000 Subject: [PATCH 1984/3224] update phpstan baseline --- tests/phpstan/configs/l8-baseline.neon | 65 ++++++++++++++------------ 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 30f530c233..e07ad407c0 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -556,13 +556,8 @@ parameters: path: ../../../src/world/World.php - - message: "#^Cannot call method getBlockSkyLight\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/world/World.php - - - - message: "#^Cannot call method getBlockLight\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 1 + message: "#^Cannot call method getSubChunk\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 2 path: ../../../src/world/World.php - @@ -676,22 +671,7 @@ parameters: path: ../../../src/world/generator/PopulationTask.php - - message: "#^Cannot call method recalculateHeightMap\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/world/generator/PopulationTask.php - - - - message: "#^Cannot call method populateSkyLight\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/world/generator/PopulationTask.php - - - - message: "#^Cannot call method setLightPopulated\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/world/generator/PopulationTask.php - - - - message: "#^Parameter \\#1 \\$chunk of static method pocketmine\\\\world\\\\format\\\\io\\\\FastChunkSerializer\\:\\:serialize\\(\\) expects pocketmine\\\\world\\\\format\\\\Chunk, pocketmine\\\\world\\\\format\\\\Chunk\\|null given\\.$#" + message: "#^Parameter \\#1 \\$chunk of static method pocketmine\\\\world\\\\format\\\\io\\\\FastChunkSerializer\\:\\:serializeWithoutLight\\(\\) expects pocketmine\\\\world\\\\format\\\\Chunk, pocketmine\\\\world\\\\format\\\\Chunk\\|null given\\.$#" count: 2 path: ../../../src/world/generator/PopulationTask.php @@ -776,14 +756,14 @@ parameters: path: ../../../src/world/light/BlockLightUpdate.php - - message: "#^Cannot call method get\\(\\) on pocketmine\\\\world\\\\format\\\\LightArray\\|null\\.$#" - count: 4 - path: ../../../src/world/light/LightUpdate.php + message: "#^Cannot call method getSubChunks\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/light/BlockLightUpdate.php - - message: "#^Cannot call method set\\(\\) on pocketmine\\\\world\\\\format\\\\LightArray\\|null\\.$#" - count: 3 - path: ../../../src/world/light/LightUpdate.php + message: "#^Parameter \\#4 \\$newLevel of method pocketmine\\\\world\\\\light\\\\LightUpdate\\:\\:setAndUpdateLight\\(\\) expects int, int\\<1, max\\>\\|null given\\.$#" + count: 1 + path: ../../../src/world/light/BlockLightUpdate.php - message: "#^Cannot call method getFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" @@ -802,7 +782,7 @@ parameters: - message: "#^Cannot call method getHeightMap\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 1 + count: 6 path: ../../../src/world/light/SkyLightUpdate.php - @@ -830,6 +810,31 @@ parameters: count: 1 path: ../../../src/world/light/SkyLightUpdate.php + - + message: "#^Cannot call method recalculateHeightMap\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/light/SkyLightUpdate.php + + - + message: "#^Cannot call method getHeightMapArray\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/light/SkyLightUpdate.php + + - + message: "#^Only numeric types are allowed in \\+, int\\|false given on the left side\\.$#" + count: 1 + path: ../../../src/world/light/SkyLightUpdate.php + + - + message: "#^Cannot call method getSubChunks\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/light/SkyLightUpdate.php + + - + message: "#^Cannot call method getWritableSubChunk\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 2 + path: ../../../src/world/light/SkyLightUpdate.php + - message: "#^Property pocketmine\\\\event\\\\HandlerListManagerTest\\:\\:\\$isValidFunc \\(Closure\\) does not accept Closure\\|null\\.$#" count: 1 From 3c892182fd31f75bd263973bbe7e41079d7b2908 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 29 Oct 2020 12:57:33 +0000 Subject: [PATCH 1985/3224] World: change some usages of getOrLoadChunk() to getChunk() these usages don't require getOrLoadChunk() because they already check for unloaded chunks anyway. --- src/world/World.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index f059f589b1..4681372024 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1697,7 +1697,7 @@ class World implements ChunkManager{ if(!$this->isChunkLoaded($x, $z)){ continue; } - foreach($this->getOrLoadChunk($x, $z)->getEntities() as $ent){ + foreach($this->getChunk($x, $z)->getEntities() as $ent){ /** @var Entity|null $entity */ if($ent->canBeCollidedWith() and ($entity === null or ($ent !== $entity and $entity->canCollideWith($ent))) and $ent->boundingBox->intersectsWith($bb)){ $nearby[] = $ent; @@ -1728,7 +1728,7 @@ class World implements ChunkManager{ if(!$this->isChunkLoaded($x, $z)){ continue; } - foreach($this->getOrLoadChunk($x, $z)->getEntities() as $ent){ + foreach($this->getChunk($x, $z)->getEntities() as $ent){ if($ent !== $entity and $ent->boundingBox->intersectsWith($bb)){ $nearby[] = $ent; } @@ -1771,7 +1771,7 @@ class World implements ChunkManager{ if(!$this->isChunkLoaded($x, $z)){ continue; } - foreach($this->getOrLoadChunk($x, $z)->getEntities() as $entity){ + foreach($this->getChunk($x, $z)->getEntities() as $entity){ if(!($entity instanceof $entityType) or $entity->isFlaggedForDespawn() or (!$includeDead and !$entity->isAlive())){ continue; } From b079772d32abd439847d22c6de3a3258b3c7349f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 29 Oct 2020 13:05:25 +0000 Subject: [PATCH 1986/3224] World: do not include unloaded or unlit chunks in getHighestAdjacentBlock(Sky)Light() --- src/world/World.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 4681372024..e0ad8cda42 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1232,7 +1232,11 @@ class World implements ChunkManager{ [$x, $y, $z + 1], [$x, $y, $z - 1] ] as [$x1, $y1, $z1]){ - if(!$this->isInWorld($x1, $y1, $z1)){ + if( + !$this->isInWorld($x1, $y1, $z1) || + ($chunk = $this->getChunk($x1 >> 4, $z1 >> 4)) === null || + !$chunk->isLightPopulated() + ){ continue; } $max = max($max, $this->getBlockSkyLightAt($x1, $y1, $z1)); @@ -1253,7 +1257,11 @@ class World implements ChunkManager{ [$x, $y, $z + 1], [$x, $y, $z - 1] ] as [$x1, $y1, $z1]){ - if(!$this->isInWorld($x1, $y1, $z1)){ + if( + !$this->isInWorld($x1, $y1, $z1) || + ($chunk = $this->getChunk($x1 >> 4, $z1 >> 4)) === null || + !$chunk->isLightPopulated() + ){ continue; } $max = max($max, $this->getBlockLightAt($x1, $y1, $z1)); From cfb9cc8999f9e6e50578e19afa749521b67e0771 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 29 Oct 2020 13:22:35 +0000 Subject: [PATCH 1987/3224] fix build failure --- src/world/World.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index e0ad8cda42..9b0975aa2b 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1235,7 +1235,7 @@ class World implements ChunkManager{ if( !$this->isInWorld($x1, $y1, $z1) || ($chunk = $this->getChunk($x1 >> 4, $z1 >> 4)) === null || - !$chunk->isLightPopulated() + $chunk->isLightPopulated() !== true ){ continue; } @@ -1260,7 +1260,7 @@ class World implements ChunkManager{ if( !$this->isInWorld($x1, $y1, $z1) || ($chunk = $this->getChunk($x1 >> 4, $z1 >> 4)) === null || - !$chunk->isLightPopulated() + $chunk->isLightPopulated() !== true ){ continue; } From 058bb3a91a9cdc69e124b42e57224bc42c296a68 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 29 Oct 2020 13:37:14 +0000 Subject: [PATCH 1988/3224] World: do not execute neighbour block updates on unloaded chunks we might also need to delay this if any adjacent chunk is also not loaded, in case the block wants to access adjacent blocks during its neighbour update. --- src/world/World.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index 9b0975aa2b..cc42b65931 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -740,6 +740,9 @@ class World implements ChunkManager{ while($this->neighbourBlockUpdateQueue->count() > 0){ $index = $this->neighbourBlockUpdateQueue->dequeue(); World::getBlockXYZ($index, $x, $y, $z); + if(!$this->isChunkLoaded($x >> 4, $z >> 4)){ + continue; + } $block = $this->getBlockAt($x, $y, $z); $block->readStateFromWorld(); //for blocks like fences, force recalculation of connected AABBs From 0cbc5c9a4af9f4de00c24ab224180bd436331de5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 15:37:06 +0000 Subject: [PATCH 1989/3224] region: harden handling of ByteArrayTag previously this would just explode if the wrong length of data was given. --- src/world/format/io/region/Anvil.php | 5 ++++- src/world/format/io/region/McRegion.php | 5 ++--- src/world/format/io/region/PMAnvil.php | 5 ++++- src/world/format/io/region/RegionWorldProvider.php | 14 ++++++++++++++ 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/world/format/io/region/Anvil.php b/src/world/format/io/region/Anvil.php index 1bd9450f81..88951c92bf 100644 --- a/src/world/format/io/region/Anvil.php +++ b/src/world/format/io/region/Anvil.php @@ -36,7 +36,10 @@ class Anvil extends RegionWorldProvider{ } protected function deserializeSubChunk(CompoundTag $subChunk) : SubChunk{ - return new SubChunk(BlockLegacyIds::AIR << 4, [SubChunkConverter::convertSubChunkYZX($subChunk->getByteArray("Blocks"), $subChunk->getByteArray("Data"))]); + return new SubChunk(BlockLegacyIds::AIR << 4, [SubChunkConverter::convertSubChunkYZX( + self::readFixedSizeByteArray($subChunk, "Blocks", 4096), + self::readFixedSizeByteArray($subChunk, "Data", 2048) + )]); //ignore legacy light information } diff --git a/src/world/format/io/region/McRegion.php b/src/world/format/io/region/McRegion.php index 6f5ce48824..78288b6993 100644 --- a/src/world/format/io/region/McRegion.php +++ b/src/world/format/io/region/McRegion.php @@ -36,7 +36,6 @@ use pocketmine\world\format\io\ChunkUtils; use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\SubChunkConverter; use pocketmine\world\format\SubChunk; -use function str_repeat; use function zlib_decode; class McRegion extends RegionWorldProvider{ @@ -68,8 +67,8 @@ class McRegion extends RegionWorldProvider{ } $subChunks = []; - $fullIds = ($fullIdsTag = $chunk->getTag("Blocks")) instanceof ByteArrayTag ? $fullIdsTag->getValue() : str_repeat("\x00", 32768); - $fullData = ($fullDataTag = $chunk->getTag("Data")) instanceof ByteArrayTag ? $fullDataTag->getValue() : str_repeat("\x00", 16384); + $fullIds = self::readFixedSizeByteArray($chunk, "Blocks", 32768); + $fullData = self::readFixedSizeByteArray($chunk, "Data", 16384); for($y = 0; $y < 8; ++$y){ $subChunks[$y] = new SubChunk(BlockLegacyIds::AIR << 4, [SubChunkConverter::convertSubChunkFromLegacyColumn($fullIds, $fullData, $y)]); diff --git a/src/world/format/io/region/PMAnvil.php b/src/world/format/io/region/PMAnvil.php index 557026a9d3..960dd53691 100644 --- a/src/world/format/io/region/PMAnvil.php +++ b/src/world/format/io/region/PMAnvil.php @@ -36,7 +36,10 @@ class PMAnvil extends RegionWorldProvider{ use LegacyAnvilChunkTrait; protected function deserializeSubChunk(CompoundTag $subChunk) : SubChunk{ - return new SubChunk(BlockLegacyIds::AIR << 4, [SubChunkConverter::convertSubChunkXZY($subChunk->getByteArray("Blocks"), $subChunk->getByteArray("Data"))]); + return new SubChunk(BlockLegacyIds::AIR << 4, [SubChunkConverter::convertSubChunkXZY( + self::readFixedSizeByteArray($subChunk, "Blocks", 4096), + self::readFixedSizeByteArray($subChunk, "Data", 2048) + )]); } protected static function getRegionFileExtension() : string{ diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index 06c259f371..fa2162fe11 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\world\format\io\region; use pocketmine\nbt\NBT; +use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; use pocketmine\utils\Utils; @@ -41,6 +42,7 @@ use function mkdir; use function morton2d_encode; use function rename; use function scandir; +use function strlen; use function strrpos; use function substr; use function time; @@ -196,6 +198,18 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ return $result; } + protected static function readFixedSizeByteArray(CompoundTag $chunk, string $tagName, int $length) : string{ + $tag = $chunk->getTag($tagName); + if(!($tag instanceof ByteArrayTag)){ + throw new CorruptedChunkException("Expected TAG_ByteArray for '$tagName'"); + } + $data = $tag->getValue(); + if(strlen($data) !== $length){ + throw new CorruptedChunkException("Expected '$tagName' payload to have exactly $length bytes, but have " . strlen($data)); + } + return $data; + } + /** * @throws CorruptedChunkException */ From 5a320f22b7eaa20e94e02e3c3250bc3cad17ccad Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 15:48:46 +0000 Subject: [PATCH 1990/3224] Sound::encode() now always returns an array --- src/world/World.php | 3 --- src/world/sound/AnvilBreakSound.php | 4 ++-- src/world/sound/AnvilFallSound.php | 4 ++-- src/world/sound/AnvilUseSound.php | 4 ++-- src/world/sound/ArrowHitSound.php | 4 ++-- src/world/sound/BlazeShootSound.php | 4 ++-- src/world/sound/BlockBreakSound.php | 4 ++-- src/world/sound/BlockPlaceSound.php | 4 ++-- src/world/sound/BlockPunchSound.php | 6 +++--- src/world/sound/BowShootSound.php | 4 ++-- src/world/sound/BucketEmptyLavaSound.php | 4 ++-- src/world/sound/BucketEmptyWaterSound.php | 4 ++-- src/world/sound/BucketFillLavaSound.php | 4 ++-- src/world/sound/BucketFillWaterSound.php | 4 ++-- src/world/sound/ChestCloseSound.php | 4 ++-- src/world/sound/ChestOpenSound.php | 4 ++-- src/world/sound/ClickSound.php | 4 ++-- src/world/sound/DoorBumpSound.php | 4 ++-- src/world/sound/DoorCrashSound.php | 4 ++-- src/world/sound/DoorSound.php | 4 ++-- src/world/sound/EnderChestCloseSound.php | 4 ++-- src/world/sound/EnderChestOpenSound.php | 4 ++-- src/world/sound/EndermanTeleportSound.php | 4 ++-- src/world/sound/EntityAttackNoDamageSound.php | 6 +++--- src/world/sound/EntityAttackSound.php | 6 +++--- src/world/sound/EntityLandSound.php | 6 +++--- src/world/sound/EntityLongFallSound.php | 6 +++--- src/world/sound/EntityShortFallSound.php | 6 +++--- src/world/sound/ExplodeSound.php | 4 ++-- src/world/sound/FizzSound.php | 4 ++-- src/world/sound/FlintSteelSound.php | 4 ++-- src/world/sound/GhastShootSound.php | 4 ++-- src/world/sound/GhastSound.php | 4 ++-- src/world/sound/IgniteSound.php | 4 ++-- src/world/sound/ItemBreakSound.php | 4 ++-- src/world/sound/LaunchSound.php | 4 ++-- src/world/sound/NoteSound.php | 4 ++-- src/world/sound/PaintingPlaceSound.php | 4 ++-- src/world/sound/PopSound.php | 4 ++-- src/world/sound/PotionSplashSound.php | 4 ++-- src/world/sound/RecordSound.php | 4 ++-- src/world/sound/RecordStopSound.php | 4 ++-- src/world/sound/RedstonePowerOffSound.php | 4 ++-- src/world/sound/RedstonePowerOnSound.php | 4 ++-- src/world/sound/Sound.php | 4 ++-- src/world/sound/ThrowSound.php | 4 ++-- src/world/sound/TotemUseSound.php | 4 ++-- src/world/sound/XpCollectSound.php | 4 ++-- src/world/sound/XpLevelUpSound.php | 4 ++-- 49 files changed, 102 insertions(+), 105 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index cc42b65931..ed1e3da1e3 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -477,9 +477,6 @@ class World implements ChunkManager{ */ public function addSound(Vector3 $pos, Sound $sound, ?array $players = null) : void{ $pk = $sound->encode($pos); - if(!is_array($pk)){ - $pk = [$pk]; - } if(count($pk) > 0){ if($players === null){ foreach($pk as $e){ diff --git a/src/world/sound/AnvilBreakSound.php b/src/world/sound/AnvilBreakSound.php index 0e12bdc355..9da378b35d 100644 --- a/src/world/sound/AnvilBreakSound.php +++ b/src/world/sound/AnvilBreakSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class AnvilBreakSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ANVIL_BREAK, 0, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ANVIL_BREAK, 0, $pos)]; } } diff --git a/src/world/sound/AnvilFallSound.php b/src/world/sound/AnvilFallSound.php index 338b5e0f9c..7abf3f6ceb 100644 --- a/src/world/sound/AnvilFallSound.php +++ b/src/world/sound/AnvilFallSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class AnvilFallSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ANVIL_FALL, 0, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ANVIL_FALL, 0, $pos)]; } } diff --git a/src/world/sound/AnvilUseSound.php b/src/world/sound/AnvilUseSound.php index cb9c9841db..93c0b64ee3 100644 --- a/src/world/sound/AnvilUseSound.php +++ b/src/world/sound/AnvilUseSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class AnvilUseSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ANVIL_USE, 0, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ANVIL_USE, 0, $pos)]; } } diff --git a/src/world/sound/ArrowHitSound.php b/src/world/sound/ArrowHitSound.php index 84899ab594..1927b0c2cf 100644 --- a/src/world/sound/ArrowHitSound.php +++ b/src/world/sound/ArrowHitSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ArrowHitSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BOW_HIT, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BOW_HIT, $pos)]; } } diff --git a/src/world/sound/BlazeShootSound.php b/src/world/sound/BlazeShootSound.php index ed9335e3b4..3924784d0d 100644 --- a/src/world/sound/BlazeShootSound.php +++ b/src/world/sound/BlazeShootSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class BlazeShootSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_BLAZE_SHOOT, 0, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_BLAZE_SHOOT, 0, $pos)]; } } diff --git a/src/world/sound/BlockBreakSound.php b/src/world/sound/BlockBreakSound.php index 81809e1267..b5c9a11b91 100644 --- a/src/world/sound/BlockBreakSound.php +++ b/src/world/sound/BlockBreakSound.php @@ -37,7 +37,7 @@ class BlockBreakSound implements Sound{ $this->block = $block; } - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BREAK, $pos, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId())); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BREAK, $pos, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()))]; } } diff --git a/src/world/sound/BlockPlaceSound.php b/src/world/sound/BlockPlaceSound.php index 9441e5bc97..8635588b4b 100644 --- a/src/world/sound/BlockPlaceSound.php +++ b/src/world/sound/BlockPlaceSound.php @@ -37,7 +37,7 @@ class BlockPlaceSound implements Sound{ $this->block = $block; } - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_PLACE, $pos, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId())); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_PLACE, $pos, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()))]; } } diff --git a/src/world/sound/BlockPunchSound.php b/src/world/sound/BlockPunchSound.php index 33a15cce58..0637c4133b 100644 --- a/src/world/sound/BlockPunchSound.php +++ b/src/world/sound/BlockPunchSound.php @@ -40,11 +40,11 @@ class BlockPunchSound implements Sound{ $this->block = $block; } - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create( + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create( LevelSoundEventPacket::SOUND_HIT, $pos, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()) - ); + )]; } } diff --git a/src/world/sound/BowShootSound.php b/src/world/sound/BowShootSound.php index ddbc310e90..09f644bfb1 100644 --- a/src/world/sound/BowShootSound.php +++ b/src/world/sound/BowShootSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BowShootSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BOW, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BOW, $pos)]; } } diff --git a/src/world/sound/BucketEmptyLavaSound.php b/src/world/sound/BucketEmptyLavaSound.php index da9f4a703b..2764cc8239 100644 --- a/src/world/sound/BucketEmptyLavaSound.php +++ b/src/world/sound/BucketEmptyLavaSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BucketEmptyLavaSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BUCKET_EMPTY_LAVA, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BUCKET_EMPTY_LAVA, $pos)]; } } diff --git a/src/world/sound/BucketEmptyWaterSound.php b/src/world/sound/BucketEmptyWaterSound.php index 6c50d9ef7d..b3b847721c 100644 --- a/src/world/sound/BucketEmptyWaterSound.php +++ b/src/world/sound/BucketEmptyWaterSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BucketEmptyWaterSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BUCKET_EMPTY_WATER, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BUCKET_EMPTY_WATER, $pos)]; } } diff --git a/src/world/sound/BucketFillLavaSound.php b/src/world/sound/BucketFillLavaSound.php index a20601ef7b..c8dbba3008 100644 --- a/src/world/sound/BucketFillLavaSound.php +++ b/src/world/sound/BucketFillLavaSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BucketFillLavaSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BUCKET_FILL_LAVA, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BUCKET_FILL_LAVA, $pos)]; } } diff --git a/src/world/sound/BucketFillWaterSound.php b/src/world/sound/BucketFillWaterSound.php index 29e05e697e..0661a5da03 100644 --- a/src/world/sound/BucketFillWaterSound.php +++ b/src/world/sound/BucketFillWaterSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BucketFillWaterSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BUCKET_FILL_WATER, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BUCKET_FILL_WATER, $pos)]; } } diff --git a/src/world/sound/ChestCloseSound.php b/src/world/sound/ChestCloseSound.php index e3476e47d4..744305b1bd 100644 --- a/src/world/sound/ChestCloseSound.php +++ b/src/world/sound/ChestCloseSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ChestCloseSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_CHEST_CLOSED, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_CHEST_CLOSED, $pos)]; } } diff --git a/src/world/sound/ChestOpenSound.php b/src/world/sound/ChestOpenSound.php index 2668b8e8d2..86a7ea8fc5 100644 --- a/src/world/sound/ChestOpenSound.php +++ b/src/world/sound/ChestOpenSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ChestOpenSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_CHEST_OPEN, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_CHEST_OPEN, $pos)]; } } diff --git a/src/world/sound/ClickSound.php b/src/world/sound/ClickSound.php index 67d904784b..dad9e325ac 100644 --- a/src/world/sound/ClickSound.php +++ b/src/world/sound/ClickSound.php @@ -39,7 +39,7 @@ class ClickSound implements Sound{ return $this->pitch; } - public function encode(?Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_CLICK, (int) ($this->pitch * 1000), $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_CLICK, (int) ($this->pitch * 1000), $pos)]; } } diff --git a/src/world/sound/DoorBumpSound.php b/src/world/sound/DoorBumpSound.php index 3d03176f2f..2d13b0ad89 100644 --- a/src/world/sound/DoorBumpSound.php +++ b/src/world/sound/DoorBumpSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class DoorBumpSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_DOOR_BUMP, 0, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_DOOR_BUMP, 0, $pos)]; } } diff --git a/src/world/sound/DoorCrashSound.php b/src/world/sound/DoorCrashSound.php index 833d4e9e3c..fa9524a74d 100644 --- a/src/world/sound/DoorCrashSound.php +++ b/src/world/sound/DoorCrashSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class DoorCrashSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_DOOR_CRASH, 0, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_DOOR_CRASH, 0, $pos)]; } } diff --git a/src/world/sound/DoorSound.php b/src/world/sound/DoorSound.php index 57f2ba6f9f..9eca4181d4 100644 --- a/src/world/sound/DoorSound.php +++ b/src/world/sound/DoorSound.php @@ -39,7 +39,7 @@ class DoorSound implements Sound{ return $this->pitch; } - public function encode(?Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_DOOR, (int) ($this->pitch * 1000), $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_DOOR, (int) ($this->pitch * 1000), $pos)]; } } diff --git a/src/world/sound/EnderChestCloseSound.php b/src/world/sound/EnderChestCloseSound.php index 021d6c3570..07073b523b 100644 --- a/src/world/sound/EnderChestCloseSound.php +++ b/src/world/sound/EnderChestCloseSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class EnderChestCloseSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_ENDERCHEST_CLOSED, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_ENDERCHEST_CLOSED, $pos)]; } } diff --git a/src/world/sound/EnderChestOpenSound.php b/src/world/sound/EnderChestOpenSound.php index 13788a6e8a..17e6fef9bb 100644 --- a/src/world/sound/EnderChestOpenSound.php +++ b/src/world/sound/EnderChestOpenSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class EnderChestOpenSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_ENDERCHEST_OPEN, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_ENDERCHEST_OPEN, $pos)]; } } diff --git a/src/world/sound/EndermanTeleportSound.php b/src/world/sound/EndermanTeleportSound.php index 5f6b2372d0..544ffcd216 100644 --- a/src/world/sound/EndermanTeleportSound.php +++ b/src/world/sound/EndermanTeleportSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class EndermanTeleportSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ENDERMAN_TELEPORT, 0, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ENDERMAN_TELEPORT, 0, $pos)]; } } diff --git a/src/world/sound/EntityAttackNoDamageSound.php b/src/world/sound/EntityAttackNoDamageSound.php index 5684adf6bc..edd39483cc 100644 --- a/src/world/sound/EntityAttackNoDamageSound.php +++ b/src/world/sound/EntityAttackNoDamageSound.php @@ -31,12 +31,12 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; */ class EntityAttackNoDamageSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create( + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create( LevelSoundEventPacket::SOUND_ATTACK_NODAMAGE, $pos, -1, "minecraft:player" - ); + )]; } } diff --git a/src/world/sound/EntityAttackSound.php b/src/world/sound/EntityAttackSound.php index 102e458d6f..04b461f491 100644 --- a/src/world/sound/EntityAttackSound.php +++ b/src/world/sound/EntityAttackSound.php @@ -31,12 +31,12 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; */ class EntityAttackSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create( + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create( LevelSoundEventPacket::SOUND_ATTACK_STRONG, //TODO: seems like ATTACK is dysfunctional $pos, -1, "minecraft:player" - ); + )]; } } diff --git a/src/world/sound/EntityLandSound.php b/src/world/sound/EntityLandSound.php index 47e9736ab1..983c0d2e61 100644 --- a/src/world/sound/EntityLandSound.php +++ b/src/world/sound/EntityLandSound.php @@ -44,13 +44,13 @@ class EntityLandSound implements Sound{ $this->blockLandedOn = $blockLandedOn; } - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create( + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create( LevelSoundEventPacket::SOUND_LAND, $pos, RuntimeBlockMapping::getInstance()->toRuntimeId($this->blockLandedOn->getFullId()), $this->entity::getNetworkTypeId() //TODO: does isBaby have any relevance here? - ); + )]; } } diff --git a/src/world/sound/EntityLongFallSound.php b/src/world/sound/EntityLongFallSound.php index 93378e218d..2e95b9e8cf 100644 --- a/src/world/sound/EntityLongFallSound.php +++ b/src/world/sound/EntityLongFallSound.php @@ -40,13 +40,13 @@ class EntityLongFallSound implements Sound{ $this->entity = $entity; } - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create( + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create( LevelSoundEventPacket::SOUND_FALL_BIG, $pos, -1, $this->entity::getNetworkTypeId() //TODO: is isBaby relevant here? - ); + )]; } } diff --git a/src/world/sound/EntityShortFallSound.php b/src/world/sound/EntityShortFallSound.php index d1f096ce2e..de16c58b0c 100644 --- a/src/world/sound/EntityShortFallSound.php +++ b/src/world/sound/EntityShortFallSound.php @@ -39,13 +39,13 @@ class EntityShortFallSound implements Sound{ $this->entity = $entity; } - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create( + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create( LevelSoundEventPacket::SOUND_FALL_SMALL, $pos, -1, $this->entity::getNetworkTypeId() //TODO: does isBaby have any relevance here? - ); + )]; } } diff --git a/src/world/sound/ExplodeSound.php b/src/world/sound/ExplodeSound.php index 7e9ee4715d..86ed9b3420 100644 --- a/src/world/sound/ExplodeSound.php +++ b/src/world/sound/ExplodeSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ExplodeSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_EXPLODE, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_EXPLODE, $pos)]; } } diff --git a/src/world/sound/FizzSound.php b/src/world/sound/FizzSound.php index 1f10bd22a0..0e7b42ffb8 100644 --- a/src/world/sound/FizzSound.php +++ b/src/world/sound/FizzSound.php @@ -39,7 +39,7 @@ class FizzSound implements Sound{ return $this->pitch; } - public function encode(?Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_FIZZ, (int) ($this->pitch * 1000), $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_FIZZ, (int) ($this->pitch * 1000), $pos)]; } } diff --git a/src/world/sound/FlintSteelSound.php b/src/world/sound/FlintSteelSound.php index eb4fe3e934..1852169593 100644 --- a/src/world/sound/FlintSteelSound.php +++ b/src/world/sound/FlintSteelSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class FlintSteelSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_IGNITE, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_IGNITE, $pos)]; } } diff --git a/src/world/sound/GhastShootSound.php b/src/world/sound/GhastShootSound.php index 0029553ef6..40f6a47cc6 100644 --- a/src/world/sound/GhastShootSound.php +++ b/src/world/sound/GhastShootSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class GhastShootSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_GHAST_SHOOT, 0, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_GHAST_SHOOT, 0, $pos)]; } } diff --git a/src/world/sound/GhastSound.php b/src/world/sound/GhastSound.php index 484080397f..b49a9c374c 100644 --- a/src/world/sound/GhastSound.php +++ b/src/world/sound/GhastSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class GhastSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_GHAST, 0, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_GHAST, 0, $pos)]; } } diff --git a/src/world/sound/IgniteSound.php b/src/world/sound/IgniteSound.php index 4066ef1894..dd72342daa 100644 --- a/src/world/sound/IgniteSound.php +++ b/src/world/sound/IgniteSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class IgniteSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_IGNITE, 0, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_IGNITE, 0, $pos)]; } } diff --git a/src/world/sound/ItemBreakSound.php b/src/world/sound/ItemBreakSound.php index 7dd7de43b1..fbe9aef778 100644 --- a/src/world/sound/ItemBreakSound.php +++ b/src/world/sound/ItemBreakSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ItemBreakSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BREAK, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BREAK, $pos)]; } } diff --git a/src/world/sound/LaunchSound.php b/src/world/sound/LaunchSound.php index e84a4a1de4..e6772f1c9f 100644 --- a/src/world/sound/LaunchSound.php +++ b/src/world/sound/LaunchSound.php @@ -39,7 +39,7 @@ class LaunchSound implements Sound{ return $this->pitch; } - public function encode(?Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_SHOOT, (int) ($this->pitch * 1000), $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_SHOOT, (int) ($this->pitch * 1000), $pos)]; } } diff --git a/src/world/sound/NoteSound.php b/src/world/sound/NoteSound.php index d81db980d9..70228021ea 100644 --- a/src/world/sound/NoteSound.php +++ b/src/world/sound/NoteSound.php @@ -41,7 +41,7 @@ class NoteSound implements Sound{ $this->note = $note; } - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_NOTE, $pos, ($this->instrument->getMagicNumber() << 8) | $this->note); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_NOTE, $pos, ($this->instrument->getMagicNumber() << 8) | $this->note)]; } } diff --git a/src/world/sound/PaintingPlaceSound.php b/src/world/sound/PaintingPlaceSound.php index cf64b248b9..c836e0842c 100644 --- a/src/world/sound/PaintingPlaceSound.php +++ b/src/world/sound/PaintingPlaceSound.php @@ -28,8 +28,8 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class PaintingPlaceSound implements Sound{ - public function encode(?Vector3 $pos){ + public function encode(?Vector3 $pos) : array{ //item frame and painting have the same sound - return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ITEMFRAME_PLACE, 0, $pos); + return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ITEMFRAME_PLACE, 0, $pos)]; } } diff --git a/src/world/sound/PopSound.php b/src/world/sound/PopSound.php index 6bec571a95..5bce1145f1 100644 --- a/src/world/sound/PopSound.php +++ b/src/world/sound/PopSound.php @@ -39,7 +39,7 @@ class PopSound implements Sound{ return $this->pitch; } - public function encode(?Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_POP, (int) ($this->pitch * 1000), $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_POP, (int) ($this->pitch * 1000), $pos)]; } } diff --git a/src/world/sound/PotionSplashSound.php b/src/world/sound/PotionSplashSound.php index 97c1dab083..96a2f6ead9 100644 --- a/src/world/sound/PotionSplashSound.php +++ b/src/world/sound/PotionSplashSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class PotionSplashSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_GLASS, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_GLASS, $pos)]; } } diff --git a/src/world/sound/RecordSound.php b/src/world/sound/RecordSound.php index 1ec5c23ca3..9f8bb15d14 100644 --- a/src/world/sound/RecordSound.php +++ b/src/world/sound/RecordSound.php @@ -36,7 +36,7 @@ class RecordSound implements Sound{ $this->recordType = $recordType; } - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create($this->recordType->getSoundId(), $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create($this->recordType->getSoundId(), $pos)]; } } diff --git a/src/world/sound/RecordStopSound.php b/src/world/sound/RecordStopSound.php index b5f87f87f6..ccb139f828 100644 --- a/src/world/sound/RecordStopSound.php +++ b/src/world/sound/RecordStopSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class RecordStopSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_STOP_RECORD, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_STOP_RECORD, $pos)]; } } diff --git a/src/world/sound/RedstonePowerOffSound.php b/src/world/sound/RedstonePowerOffSound.php index f8ea474f3b..d1363ed544 100644 --- a/src/world/sound/RedstonePowerOffSound.php +++ b/src/world/sound/RedstonePowerOffSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class RedstonePowerOffSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_POWER_OFF, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_POWER_OFF, $pos)]; } } diff --git a/src/world/sound/RedstonePowerOnSound.php b/src/world/sound/RedstonePowerOnSound.php index c01ee10b4b..eaea5f6173 100644 --- a/src/world/sound/RedstonePowerOnSound.php +++ b/src/world/sound/RedstonePowerOnSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class RedstonePowerOnSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_POWER_ON, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_POWER_ON, $pos)]; } } diff --git a/src/world/sound/Sound.php b/src/world/sound/Sound.php index e44c0ecce0..84121db6a1 100644 --- a/src/world/sound/Sound.php +++ b/src/world/sound/Sound.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\ClientboundPacket; interface Sound{ /** - * @return ClientboundPacket|ClientboundPacket[] + * @return ClientboundPacket[] */ - public function encode(?Vector3 $pos); + public function encode(?Vector3 $pos) : array; } diff --git a/src/world/sound/ThrowSound.php b/src/world/sound/ThrowSound.php index feb0ca7249..65c5079aff 100644 --- a/src/world/sound/ThrowSound.php +++ b/src/world/sound/ThrowSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ThrowSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_THROW, $pos, -1, "minecraft:player"); + public function encode(?Vector3 $pos) : array{ + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_THROW, $pos, -1, "minecraft:player")]; } } diff --git a/src/world/sound/TotemUseSound.php b/src/world/sound/TotemUseSound.php index 064008942d..baa04275cf 100644 --- a/src/world/sound/TotemUseSound.php +++ b/src/world/sound/TotemUseSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class TotemUseSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_TOTEM, 0, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_TOTEM, 0, $pos)]; } } diff --git a/src/world/sound/XpCollectSound.php b/src/world/sound/XpCollectSound.php index f87c2719ff..71a304f30c 100644 --- a/src/world/sound/XpCollectSound.php +++ b/src/world/sound/XpCollectSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class XpCollectSound implements Sound{ - public function encode(?Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ORB, 0, $pos); + public function encode(?Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ORB, 0, $pos)]; } } diff --git a/src/world/sound/XpLevelUpSound.php b/src/world/sound/XpLevelUpSound.php index 837067446e..abc41fef74 100644 --- a/src/world/sound/XpLevelUpSound.php +++ b/src/world/sound/XpLevelUpSound.php @@ -41,9 +41,9 @@ class XpLevelUpSound implements Sound{ return $this->xpLevel; } - public function encode(?Vector3 $pos){ + public function encode(?Vector3 $pos) : array{ //No idea why such odd numbers, but this works... //TODO: check arbitrary volume - return LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_LEVELUP, $pos, 0x10000000 * intdiv(min(30, $this->xpLevel), 5)); + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_LEVELUP, $pos, 0x10000000 * intdiv(min(30, $this->xpLevel), 5))]; } } From 66edf5a1650f87d33de8cc5badcdbd25d5c13af0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 15:51:17 +0000 Subject: [PATCH 1991/3224] Particle::encode() now always returns ClientboundPacket[] --- src/world/World.php | 3 --- src/world/particle/AngryVillagerParticle.php | 4 ++-- src/world/particle/BlockForceFieldParticle.php | 4 ++-- src/world/particle/BlockPunchParticle.php | 4 ++-- src/world/particle/BubbleParticle.php | 4 ++-- src/world/particle/CriticalParticle.php | 4 ++-- src/world/particle/DestroyBlockParticle.php | 4 ++-- src/world/particle/DragonEggTeleportParticle.php | 4 ++-- src/world/particle/DustParticle.php | 4 ++-- src/world/particle/EnchantParticle.php | 4 ++-- src/world/particle/EnchantmentTableParticle.php | 4 ++-- src/world/particle/EndermanTeleportParticle.php | 4 ++-- src/world/particle/EntityFlameParticle.php | 4 ++-- src/world/particle/ExplodeParticle.php | 4 ++-- src/world/particle/FlameParticle.php | 4 ++-- src/world/particle/FloatingTextParticle.php | 2 +- src/world/particle/HappyVillagerParticle.php | 4 ++-- src/world/particle/HeartParticle.php | 4 ++-- src/world/particle/HugeExplodeParticle.php | 4 ++-- src/world/particle/HugeExplodeSeedParticle.php | 4 ++-- src/world/particle/InkParticle.php | 4 ++-- src/world/particle/InstantEnchantParticle.php | 4 ++-- src/world/particle/ItemBreakParticle.php | 4 ++-- src/world/particle/LavaDripParticle.php | 4 ++-- src/world/particle/LavaParticle.php | 4 ++-- src/world/particle/MobSpawnParticle.php | 4 ++-- src/world/particle/Particle.php | 4 ++-- src/world/particle/PortalParticle.php | 4 ++-- src/world/particle/PotionSplashParticle.php | 4 ++-- src/world/particle/RainSplashParticle.php | 4 ++-- src/world/particle/RedstoneParticle.php | 4 ++-- src/world/particle/SmokeParticle.php | 4 ++-- src/world/particle/SnowballPoofParticle.php | 4 ++-- src/world/particle/SplashParticle.php | 4 ++-- src/world/particle/SporeParticle.php | 4 ++-- src/world/particle/TerrainParticle.php | 4 ++-- src/world/particle/WaterDripParticle.php | 4 ++-- src/world/particle/WaterParticle.php | 4 ++-- 38 files changed, 73 insertions(+), 76 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index ed1e3da1e3..8bfa1cf106 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -493,9 +493,6 @@ class World implements ChunkManager{ */ public function addParticle(Vector3 $pos, Particle $particle, ?array $players = null) : void{ $pk = $particle->encode($pos); - if(!is_array($pk)){ - $pk = [$pk]; - } if(count($pk) > 0){ if($players === null){ foreach($pk as $e){ diff --git a/src/world/particle/AngryVillagerParticle.php b/src/world/particle/AngryVillagerParticle.php index 5ea0ea2041..67e7805ab1 100644 --- a/src/world/particle/AngryVillagerParticle.php +++ b/src/world/particle/AngryVillagerParticle.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\types\ParticleIds; class AngryVillagerParticle implements Particle{ - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::VILLAGER_ANGRY, 0, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::VILLAGER_ANGRY, 0, $pos)]; } } diff --git a/src/world/particle/BlockForceFieldParticle.php b/src/world/particle/BlockForceFieldParticle.php index 24d07d30fb..cfd2d0b2a4 100644 --- a/src/world/particle/BlockForceFieldParticle.php +++ b/src/world/particle/BlockForceFieldParticle.php @@ -36,7 +36,7 @@ class BlockForceFieldParticle implements Particle{ $this->data = $data; //TODO: proper encode/decode of data } - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::BLOCK_FORCE_FIELD, $this->data, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::BLOCK_FORCE_FIELD, $this->data, $pos)]; } } diff --git a/src/world/particle/BlockPunchParticle.php b/src/world/particle/BlockPunchParticle.php index be99c9452b..e0a7eaaf8d 100644 --- a/src/world/particle/BlockPunchParticle.php +++ b/src/world/particle/BlockPunchParticle.php @@ -43,7 +43,7 @@ class BlockPunchParticle implements Particle{ $this->face = $face; } - public function encode(Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_PUNCH_BLOCK, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()) | ($this->face << 24), $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_PUNCH_BLOCK, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()) | ($this->face << 24), $pos)]; } } diff --git a/src/world/particle/BubbleParticle.php b/src/world/particle/BubbleParticle.php index 62deede8a2..90336a9235 100644 --- a/src/world/particle/BubbleParticle.php +++ b/src/world/particle/BubbleParticle.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\types\ParticleIds; class BubbleParticle implements Particle{ - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::BUBBLE, 0, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::BUBBLE, 0, $pos)]; } } diff --git a/src/world/particle/CriticalParticle.php b/src/world/particle/CriticalParticle.php index 9705645852..477d1c7e5f 100644 --- a/src/world/particle/CriticalParticle.php +++ b/src/world/particle/CriticalParticle.php @@ -35,7 +35,7 @@ class CriticalParticle implements Particle{ $this->scale = $scale; } - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::CRITICAL, $this->scale, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::CRITICAL, $this->scale, $pos)]; } } diff --git a/src/world/particle/DestroyBlockParticle.php b/src/world/particle/DestroyBlockParticle.php index d43b848508..aeda3f4849 100644 --- a/src/world/particle/DestroyBlockParticle.php +++ b/src/world/particle/DestroyBlockParticle.php @@ -37,7 +37,7 @@ class DestroyBlockParticle implements Particle{ $this->block = $b; } - public function encode(Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_DESTROY, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()), $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_DESTROY, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()), $pos)]; } } diff --git a/src/world/particle/DragonEggTeleportParticle.php b/src/world/particle/DragonEggTeleportParticle.php index b8a615f8e3..5c17650da3 100644 --- a/src/world/particle/DragonEggTeleportParticle.php +++ b/src/world/particle/DragonEggTeleportParticle.php @@ -49,7 +49,7 @@ class DragonEggTeleportParticle implements Particle{ return $v; } - public function encode(Vector3 $pos){ + public function encode(Vector3 $pos) : array{ $data = ($this->zDiff < 0 ? 1 << 26 : 0) | ($this->yDiff < 0 ? 1 << 25 : 0) | ($this->xDiff < 0 ? 1 << 24 : 0) | @@ -57,6 +57,6 @@ class DragonEggTeleportParticle implements Particle{ (abs($this->yDiff) << 8) | abs($this->zDiff); - return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_DRAGON_EGG_TELEPORT, $data, $pos); + return [LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_DRAGON_EGG_TELEPORT, $data, $pos)]; } } diff --git a/src/world/particle/DustParticle.php b/src/world/particle/DustParticle.php index 27a7d742fd..4e0564910a 100644 --- a/src/world/particle/DustParticle.php +++ b/src/world/particle/DustParticle.php @@ -36,7 +36,7 @@ class DustParticle implements Particle{ $this->color = $color; } - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::DUST, $this->color->toARGB(), $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::DUST, $this->color->toARGB(), $pos)]; } } diff --git a/src/world/particle/EnchantParticle.php b/src/world/particle/EnchantParticle.php index db42ea3097..48f223ae92 100644 --- a/src/world/particle/EnchantParticle.php +++ b/src/world/particle/EnchantParticle.php @@ -37,7 +37,7 @@ class EnchantParticle implements Particle{ $this->color = $color; } - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::MOB_SPELL, $this->color->toARGB(), $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::MOB_SPELL, $this->color->toARGB(), $pos)]; } } diff --git a/src/world/particle/EnchantmentTableParticle.php b/src/world/particle/EnchantmentTableParticle.php index 15ac7d14b5..86a86f572c 100644 --- a/src/world/particle/EnchantmentTableParticle.php +++ b/src/world/particle/EnchantmentTableParticle.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\types\ParticleIds; class EnchantmentTableParticle implements Particle{ - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::ENCHANTMENT_TABLE, 0, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::ENCHANTMENT_TABLE, 0, $pos)]; } } diff --git a/src/world/particle/EndermanTeleportParticle.php b/src/world/particle/EndermanTeleportParticle.php index 18689d9a99..274d1540e6 100644 --- a/src/world/particle/EndermanTeleportParticle.php +++ b/src/world/particle/EndermanTeleportParticle.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class EndermanTeleportParticle implements Particle{ - public function encode(Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_ENDERMAN_TELEPORT, 0, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_ENDERMAN_TELEPORT, 0, $pos)]; } } diff --git a/src/world/particle/EntityFlameParticle.php b/src/world/particle/EntityFlameParticle.php index 66c4ba4c29..3f5a98740f 100644 --- a/src/world/particle/EntityFlameParticle.php +++ b/src/world/particle/EntityFlameParticle.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\types\ParticleIds; class EntityFlameParticle implements Particle{ - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::MOB_FLAME, 0, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::MOB_FLAME, 0, $pos)]; } } diff --git a/src/world/particle/ExplodeParticle.php b/src/world/particle/ExplodeParticle.php index 8a51a13de0..d3e8b566ca 100644 --- a/src/world/particle/ExplodeParticle.php +++ b/src/world/particle/ExplodeParticle.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\types\ParticleIds; class ExplodeParticle implements Particle{ - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::EXPLODE, 0, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::EXPLODE, 0, $pos)]; } } diff --git a/src/world/particle/FlameParticle.php b/src/world/particle/FlameParticle.php index f78681c8ec..d713df67c3 100644 --- a/src/world/particle/FlameParticle.php +++ b/src/world/particle/FlameParticle.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\types\ParticleIds; class FlameParticle implements Particle{ - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::FLAME, 0, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::FLAME, 0, $pos)]; } } diff --git a/src/world/particle/FloatingTextParticle.php b/src/world/particle/FloatingTextParticle.php index 5b787580a5..bca6013893 100644 --- a/src/world/particle/FloatingTextParticle.php +++ b/src/world/particle/FloatingTextParticle.php @@ -80,7 +80,7 @@ class FloatingTextParticle implements Particle{ $this->invisible = $value; } - public function encode(Vector3 $pos){ + public function encode(Vector3 $pos) : array{ $p = []; if($this->entityId === null){ diff --git a/src/world/particle/HappyVillagerParticle.php b/src/world/particle/HappyVillagerParticle.php index d6e03881be..d405a6037b 100644 --- a/src/world/particle/HappyVillagerParticle.php +++ b/src/world/particle/HappyVillagerParticle.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\types\ParticleIds; class HappyVillagerParticle implements Particle{ - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::VILLAGER_HAPPY, 0, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::VILLAGER_HAPPY, 0, $pos)]; } } diff --git a/src/world/particle/HeartParticle.php b/src/world/particle/HeartParticle.php index b3a76baa5e..4d2dddbfe5 100644 --- a/src/world/particle/HeartParticle.php +++ b/src/world/particle/HeartParticle.php @@ -35,7 +35,7 @@ class HeartParticle implements Particle{ $this->scale = $scale; } - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::HEART, $this->scale, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::HEART, $this->scale, $pos)]; } } diff --git a/src/world/particle/HugeExplodeParticle.php b/src/world/particle/HugeExplodeParticle.php index 5f9b0c6e72..3f1c109f93 100644 --- a/src/world/particle/HugeExplodeParticle.php +++ b/src/world/particle/HugeExplodeParticle.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\types\ParticleIds; class HugeExplodeParticle implements Particle{ - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::HUGE_EXPLODE, 0, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::HUGE_EXPLODE, 0, $pos)]; } } diff --git a/src/world/particle/HugeExplodeSeedParticle.php b/src/world/particle/HugeExplodeSeedParticle.php index d27db88750..e35fbc94f8 100644 --- a/src/world/particle/HugeExplodeSeedParticle.php +++ b/src/world/particle/HugeExplodeSeedParticle.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\types\ParticleIds; class HugeExplodeSeedParticle implements Particle{ - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::HUGE_EXPLODE_SEED, 0, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::HUGE_EXPLODE_SEED, 0, $pos)]; } } diff --git a/src/world/particle/InkParticle.php b/src/world/particle/InkParticle.php index c99c07ce8e..dfe6a5fd72 100644 --- a/src/world/particle/InkParticle.php +++ b/src/world/particle/InkParticle.php @@ -35,7 +35,7 @@ class InkParticle implements Particle{ $this->scale = $scale; } - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::INK, $this->scale, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::INK, $this->scale, $pos)]; } } diff --git a/src/world/particle/InstantEnchantParticle.php b/src/world/particle/InstantEnchantParticle.php index 17156d1ef9..695a4780ae 100644 --- a/src/world/particle/InstantEnchantParticle.php +++ b/src/world/particle/InstantEnchantParticle.php @@ -36,7 +36,7 @@ class InstantEnchantParticle implements Particle{ $this->color = $color; } - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::MOB_SPELL_INSTANTANEOUS, $this->color->toARGB(), $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::MOB_SPELL_INSTANTANEOUS, $this->color->toARGB(), $pos)]; } } diff --git a/src/world/particle/ItemBreakParticle.php b/src/world/particle/ItemBreakParticle.php index 7ebee7b0e3..1a4865a6a5 100644 --- a/src/world/particle/ItemBreakParticle.php +++ b/src/world/particle/ItemBreakParticle.php @@ -36,7 +36,7 @@ class ItemBreakParticle implements Particle{ $this->item = $item; } - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::ITEM_BREAK, ($this->item->getId() << 16) | $this->item->getMeta(), $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::ITEM_BREAK, ($this->item->getId() << 16) | $this->item->getMeta(), $pos)]; } } diff --git a/src/world/particle/LavaDripParticle.php b/src/world/particle/LavaDripParticle.php index 485c8004bf..904d5257b1 100644 --- a/src/world/particle/LavaDripParticle.php +++ b/src/world/particle/LavaDripParticle.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\types\ParticleIds; class LavaDripParticle implements Particle{ - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::DRIP_LAVA, 0, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::DRIP_LAVA, 0, $pos)]; } } diff --git a/src/world/particle/LavaParticle.php b/src/world/particle/LavaParticle.php index fede3825e4..dcf9572a9a 100644 --- a/src/world/particle/LavaParticle.php +++ b/src/world/particle/LavaParticle.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\types\ParticleIds; class LavaParticle implements Particle{ - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::LAVA, 0, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::LAVA, 0, $pos)]; } } diff --git a/src/world/particle/MobSpawnParticle.php b/src/world/particle/MobSpawnParticle.php index 6ebe243a2a..bdc2f01449 100644 --- a/src/world/particle/MobSpawnParticle.php +++ b/src/world/particle/MobSpawnParticle.php @@ -38,7 +38,7 @@ class MobSpawnParticle implements Particle{ $this->height = $height; } - public function encode(Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_SPAWN, ($this->width & 0xff) | (($this->height & 0xff) << 8), $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_SPAWN, ($this->width & 0xff) | (($this->height & 0xff) << 8), $pos)]; } } diff --git a/src/world/particle/Particle.php b/src/world/particle/Particle.php index 4ed80a7c05..009bb948dc 100644 --- a/src/world/particle/Particle.php +++ b/src/world/particle/Particle.php @@ -29,8 +29,8 @@ use pocketmine\network\mcpe\protocol\ClientboundPacket; interface Particle{ /** - * @return ClientboundPacket|ClientboundPacket[] + * @return ClientboundPacket[] */ - public function encode(Vector3 $pos); + public function encode(Vector3 $pos) : array; } diff --git a/src/world/particle/PortalParticle.php b/src/world/particle/PortalParticle.php index c45c8eaa38..627ff969ae 100644 --- a/src/world/particle/PortalParticle.php +++ b/src/world/particle/PortalParticle.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\types\ParticleIds; class PortalParticle implements Particle{ - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::PORTAL, 0, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::PORTAL, 0, $pos)]; } } diff --git a/src/world/particle/PotionSplashParticle.php b/src/world/particle/PotionSplashParticle.php index 6c7fc67c33..83ad8c699a 100644 --- a/src/world/particle/PotionSplashParticle.php +++ b/src/world/particle/PotionSplashParticle.php @@ -49,7 +49,7 @@ class PotionSplashParticle implements Particle{ return $this->color; } - public function encode(Vector3 $pos){ - return LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_SPLASH, $this->color->toARGB(), $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_SPLASH, $this->color->toARGB(), $pos)]; } } diff --git a/src/world/particle/RainSplashParticle.php b/src/world/particle/RainSplashParticle.php index 1178557d61..8ba67a4ed2 100644 --- a/src/world/particle/RainSplashParticle.php +++ b/src/world/particle/RainSplashParticle.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\types\ParticleIds; class RainSplashParticle implements Particle{ - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::RAIN_SPLASH, 0, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::RAIN_SPLASH, 0, $pos)]; } } diff --git a/src/world/particle/RedstoneParticle.php b/src/world/particle/RedstoneParticle.php index 4336f01f96..f969bcaabc 100644 --- a/src/world/particle/RedstoneParticle.php +++ b/src/world/particle/RedstoneParticle.php @@ -35,7 +35,7 @@ class RedstoneParticle implements Particle{ $this->lifetime = $lifetime; } - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::REDSTONE, $this->lifetime, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::REDSTONE, $this->lifetime, $pos)]; } } diff --git a/src/world/particle/SmokeParticle.php b/src/world/particle/SmokeParticle.php index 3d9f3f9fae..999f7ffd29 100644 --- a/src/world/particle/SmokeParticle.php +++ b/src/world/particle/SmokeParticle.php @@ -35,7 +35,7 @@ class SmokeParticle implements Particle{ $this->scale = $scale; } - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::SMOKE, $this->scale, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::SMOKE, $this->scale, $pos)]; } } diff --git a/src/world/particle/SnowballPoofParticle.php b/src/world/particle/SnowballPoofParticle.php index e82726d1c0..1d764238ea 100644 --- a/src/world/particle/SnowballPoofParticle.php +++ b/src/world/particle/SnowballPoofParticle.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\types\ParticleIds; class SnowballPoofParticle implements Particle{ - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::SNOWBALL_POOF, 0, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::SNOWBALL_POOF, 0, $pos)]; } } diff --git a/src/world/particle/SplashParticle.php b/src/world/particle/SplashParticle.php index 171e1b3cbf..dbc397122e 100644 --- a/src/world/particle/SplashParticle.php +++ b/src/world/particle/SplashParticle.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\types\ParticleIds; class SplashParticle implements Particle{ - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::WATER_SPLASH, 0, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::WATER_SPLASH, 0, $pos)]; } } diff --git a/src/world/particle/SporeParticle.php b/src/world/particle/SporeParticle.php index d8ef499c8b..472cb6b1b1 100644 --- a/src/world/particle/SporeParticle.php +++ b/src/world/particle/SporeParticle.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\types\ParticleIds; class SporeParticle implements Particle{ - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::TOWN_AURA, 0, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::TOWN_AURA, 0, $pos)]; } } diff --git a/src/world/particle/TerrainParticle.php b/src/world/particle/TerrainParticle.php index 4b9f07c66a..5805662e9c 100644 --- a/src/world/particle/TerrainParticle.php +++ b/src/world/particle/TerrainParticle.php @@ -37,7 +37,7 @@ class TerrainParticle implements Particle{ $this->block = $b; } - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::TERRAIN, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()), $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::TERRAIN, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()), $pos)]; } } diff --git a/src/world/particle/WaterDripParticle.php b/src/world/particle/WaterDripParticle.php index 71677252a2..a1072dc6e2 100644 --- a/src/world/particle/WaterDripParticle.php +++ b/src/world/particle/WaterDripParticle.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\types\ParticleIds; class WaterDripParticle implements Particle{ - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::DRIP_WATER, 0, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::DRIP_WATER, 0, $pos)]; } } diff --git a/src/world/particle/WaterParticle.php b/src/world/particle/WaterParticle.php index 71beaaab3b..93ef6efb74 100644 --- a/src/world/particle/WaterParticle.php +++ b/src/world/particle/WaterParticle.php @@ -29,7 +29,7 @@ use pocketmine\network\mcpe\protocol\types\ParticleIds; class WaterParticle implements Particle{ - public function encode(Vector3 $pos){ - return LevelEventPacket::standardParticle(ParticleIds::WATER_WAKE, 0, $pos); + public function encode(Vector3 $pos) : array{ + return [LevelEventPacket::standardParticle(ParticleIds::WATER_WAKE, 0, $pos)]; } } From 8be0c0da0d15815cb76d74b1788d388a62ec7aa2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 16:07:18 +0000 Subject: [PATCH 1992/3224] Implemented a silent property on entities and Entity->broadcastSound() fixes #3516 --- src/entity/Entity.php | 22 ++++++++++++++++++++++ src/entity/ExperienceManager.php | 6 +++--- src/entity/Human.php | 2 +- src/entity/Living.php | 6 +++--- src/entity/object/PrimedTNT.php | 2 +- src/entity/projectile/Arrow.php | 2 +- src/entity/projectile/ExperienceBottle.php | 2 +- src/entity/projectile/SplashPotion.php | 2 +- 8 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index d49e9c0d58..aa5d511189 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -55,6 +55,7 @@ use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; use pocketmine\world\format\Chunk; use pocketmine\world\Position; +use pocketmine\world\sound\Sound; use pocketmine\world\World; use function abs; use function array_map; @@ -214,6 +215,8 @@ abstract class Entity{ protected $immobile = false; /** @var bool */ protected $invisible = false; + /** @var bool */ + protected $silent = false; /** @var int|null */ protected $ownerId = null; @@ -356,6 +359,14 @@ abstract class Entity{ $this->invisible = $value; } + public function isSilent() : bool{ + return $this->silent; + } + + public function setSilent(bool $value = true) : void{ + $this->silent = $value; + } + /** * Returns whether the entity is able to climb blocks such as ladders or vines. */ @@ -1656,6 +1667,7 @@ abstract class Entity{ $properties->setGenericFlag(EntityMetadataFlags::HAS_COLLISION, true); $properties->setGenericFlag(EntityMetadataFlags::IMMOBILE, $this->immobile); $properties->setGenericFlag(EntityMetadataFlags::INVISIBLE, $this->invisible); + $properties->setGenericFlag(EntityMetadataFlags::SILENT, $this->silent); $properties->setGenericFlag(EntityMetadataFlags::ONFIRE, $this->isOnFire()); $properties->setGenericFlag(EntityMetadataFlags::WALLCLIMBING, $this->canClimbWalls); } @@ -1667,6 +1679,16 @@ abstract class Entity{ $this->server->broadcastPackets($targets ?? $this->getViewers(), $animation->encode()); } + /** + * Broadcasts a sound caused by the entity. If the entity is considered "silent", the sound will be dropped. + * @param Player[]|null $targets + */ + public function broadcastSound(Sound $sound, ?array $targets = null) : void{ + if(!$this->silent){ + $this->server->broadcastPackets($targets ?? $this->getViewers(), $sound->encode($this->location)); + } + } + public function __destruct(){ $this->close(); } diff --git a/src/entity/ExperienceManager.php b/src/entity/ExperienceManager.php index 223ad5ee1d..4571877456 100644 --- a/src/entity/ExperienceManager.php +++ b/src/entity/ExperienceManager.php @@ -87,7 +87,7 @@ class ExperienceManager{ if($playSound){ $newLevel = $this->getXpLevel(); if((int) ($newLevel / 5) > (int) ($oldLevel / 5)){ - $this->entity->getWorld()->addSound($this->entity->getPosition(), new XpLevelUpSound($newLevel)); + $this->entity->broadcastSound(new XpLevelUpSound($newLevel)); } } @@ -161,9 +161,9 @@ class ExperienceManager{ if($playSound){ $newLevel = $this->getXpLevel(); if((int) ($newLevel / 5) > (int) ($oldLevel / 5)){ - $this->entity->getWorld()->addSound($this->entity->getPosition(), new XpLevelUpSound($newLevel)); + $this->entity->broadcastSound(new XpLevelUpSound($newLevel)); }elseif($this->getCurrentTotalXp() > $oldTotal){ - $this->entity->getWorld()->addSound($this->entity->getPosition(), new XpCollectSound()); + $this->entity->broadcastSound(new XpCollectSound()); } } diff --git a/src/entity/Human.php b/src/entity/Human.php index 39a671e090..daac796a25 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -296,7 +296,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $this->effectManager->add(new EffectInstance(VanillaEffects::ABSORPTION(), 5 * 20, 1)); $this->broadcastAnimation(new TotemUseAnimation($this)); - $this->getWorld()->addSound($this->location->add(0, $this->eyeHeight, 0), new TotemUseSound()); + $this->broadcastSound(new TotemUseSound()); $hand = $this->inventory->getItemInHand(); if($hand instanceof Totem){ diff --git a/src/entity/Living.php b/src/entity/Living.php index 2926cce532..18b86fe081 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -300,7 +300,7 @@ abstract class Living extends Entity{ $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FALL, $damage); $this->attack($ev); - $this->getWorld()->addSound($this->location, $damage > 4 ? + $this->broadcastSound($damage > 4 ? new EntityLongFallSound($this) : new EntityShortFallSound($this) ); @@ -312,7 +312,7 @@ abstract class Living extends Entity{ $fallBlock = $this->getWorld()->getBlock($fallBlockPos); } if($fallBlock->getId() !== BlockLegacyIds::AIR){ - $this->getWorld()->addSound($this->location, new EntityLandSound($this, $fallBlock)); + $this->broadcastSound(new EntityLandSound($this, $fallBlock)); } } } @@ -433,7 +433,7 @@ abstract class Living extends Entity{ private function damageItem(Durable $item, int $durabilityRemoved) : void{ $item->applyDamage($durabilityRemoved); if($item->isBroken()){ - $this->getWorld()->addSound($this->location, new ItemBreakSound()); + $this->broadcastSound(new ItemBreakSound()); } } diff --git a/src/entity/object/PrimedTNT.php b/src/entity/object/PrimedTNT.php index 13c4ab8507..48affa0ba4 100644 --- a/src/entity/object/PrimedTNT.php +++ b/src/entity/object/PrimedTNT.php @@ -74,7 +74,7 @@ class PrimedTNT extends Entity implements Explosive{ $this->fuse = $nbt->getShort("Fuse", 80); - $this->getWorld()->addSound($this->location, new IgniteSound()); + $this->broadcastSound(new IgniteSound()); } public function canCollideWith(Entity $entity) : bool{ diff --git a/src/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php index 39f62fa916..503f55cf43 100644 --- a/src/entity/projectile/Arrow.php +++ b/src/entity/projectile/Arrow.php @@ -137,7 +137,7 @@ class Arrow extends Projectile{ protected function onHit(ProjectileHitEvent $event) : void{ $this->setCritical(false); - $this->getWorld()->addSound($this->location, new ArrowHitSound()); + $this->broadcastSound(new ArrowHitSound()); } protected function onHitBlock(Block $blockHit, RayTraceResult $hitResult) : void{ diff --git a/src/entity/projectile/ExperienceBottle.php b/src/entity/projectile/ExperienceBottle.php index e6c026af35..eb69b0edfa 100644 --- a/src/entity/projectile/ExperienceBottle.php +++ b/src/entity/projectile/ExperienceBottle.php @@ -40,7 +40,7 @@ class ExperienceBottle extends Throwable{ public function onHit(ProjectileHitEvent $event) : void{ $this->getWorld()->addParticle($this->location, new PotionSplashParticle(PotionSplashParticle::DEFAULT_COLOR())); - $this->getWorld()->addSound($this->location, new PotionSplashSound()); + $this->broadcastSound(new PotionSplashSound()); $this->getWorld()->dropExperience($this->location, mt_rand(3, 11)); } diff --git a/src/entity/projectile/SplashPotion.php b/src/entity/projectile/SplashPotion.php index f4f0c14434..a800ee5559 100644 --- a/src/entity/projectile/SplashPotion.php +++ b/src/entity/projectile/SplashPotion.php @@ -92,7 +92,7 @@ class SplashPotion extends Throwable{ } $this->getWorld()->addParticle($this->location, $particle); - $this->getWorld()->addSound($this->location, new PotionSplashSound()); + $this->broadcastSound(new PotionSplashSound()); if($hasEffects){ if(!$this->willLinger()){ From 0b92e96e14a30fd3537ff35cc4cd0edd506ba75a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 16:10:02 +0000 Subject: [PATCH 1993/3224] Player: set silent flag in spectator --- src/player/Player.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/player/Player.php b/src/player/Player.php index c7704d690d..4bc7070e16 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -983,6 +983,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ if($this->isSpectator()){ $this->setFlying(true); + $this->setSilent(); $this->onGround = false; //TODO: HACK! this syncs the onground flag with the client so that flying works properly @@ -992,6 +993,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ if($this->isSurvival()){ $this->setFlying(false); } + $this->setSilent(false); $this->checkGroundState(0, 0, 0, 0, 0, 0); } } From 241a50387b625c548fe5fd5af15fe0801e19b3c5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 16:44:42 +0000 Subject: [PATCH 1994/3224] World: added getHighestAdjacentRealBlockSkyLight() this is the same as its 'non-real' counterpart, but it accounts for time of day. --- src/block/FrostedIce.php | 2 +- src/world/World.php | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/block/FrostedIce.php b/src/block/FrostedIce.php index 9d957d5fcf..e28ba84275 100644 --- a/src/block/FrostedIce.php +++ b/src/block/FrostedIce.php @@ -60,7 +60,7 @@ class FrostedIce extends Ice{ if((!$this->checkAdjacentBlocks(4) or mt_rand(0, 2) === 0) and max( //TODO: move this to World $this->pos->getWorld()->getHighestAdjacentBlockLight($this->pos->x, $this->pos->y, $this->pos->z), - $this->pos->getWorld()->getHighestAdjacentBlockSkyLight($this->pos->x, $this->pos->y, $this->pos->z) - $this->pos->getWorld()->getSkyLightReduction() + $this->pos->getWorld()->getHighestAdjacentRealBlockSkyLight($this->pos->x, $this->pos->y, $this->pos->z) ) >= 12 - $this->age){ if($this->tryMelt()){ foreach($this->getAllSides() as $block){ diff --git a/src/world/World.php b/src/world/World.php index 8bfa1cf106..8e3526832e 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1241,6 +1241,14 @@ class World implements ChunkManager{ return $max; } + /** + * Returns the highest block sky light available in the positions adjacent to the given coordinates, adjusted for + * the world's current time of day and weather conditions. + */ + public function getHighestAdjacentRealBlockSkyLight(int $x, int $y, int $z) : int{ + return $this->getHighestAdjacentBlockSkyLight($x, $y, $z) - $this->skyLightReduction; + } + /** * Returns the highest block light level available in the positions adjacent to the specified block coordinates. */ From 5f7b0994b9426c2218bc35f1921b84c6e245f0bd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 16:47:34 +0000 Subject: [PATCH 1995/3224] World: rename get(HighestAdjacent)BlockSkyLight(At) to make it clear these are **potentials**, not the actual light level --- src/world/World.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 8e3526832e..74342b68d6 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1195,7 +1195,7 @@ class World implements ChunkManager{ * @return int 0-15 */ public function getRealBlockSkyLightAt(int $x, int $y, int $z) : int{ - $light = $this->getBlockSkyLightAt($x, $y, $z) - $this->skyLightReduction; + $light = $this->getPotentialBlockSkyLightAt($x, $y, $z) - $this->skyLightReduction; return $light < 0 ? 0 : $light; } @@ -1219,7 +1219,7 @@ class World implements ChunkManager{ /** * Returns the highest block light level available in the positions adjacent to the specified block coordinates. */ - public function getHighestAdjacentBlockSkyLight(int $x, int $y, int $z) : int{ + public function getHighestAdjacentPotentialBlockSkyLight(int $x, int $y, int $z) : int{ $max = 0; foreach([ [$x + 1, $y, $z], @@ -1236,7 +1236,7 @@ class World implements ChunkManager{ ){ continue; } - $max = max($max, $this->getBlockSkyLightAt($x1, $y1, $z1)); + $max = max($max, $this->getPotentialBlockSkyLightAt($x1, $y1, $z1)); } return $max; } @@ -1246,7 +1246,7 @@ class World implements ChunkManager{ * the world's current time of day and weather conditions. */ public function getHighestAdjacentRealBlockSkyLight(int $x, int $y, int $z) : int{ - return $this->getHighestAdjacentBlockSkyLight($x, $y, $z) - $this->skyLightReduction; + return $this->getHighestAdjacentPotentialBlockSkyLight($x, $y, $z) - $this->skyLightReduction; } /** @@ -1838,7 +1838,7 @@ class World implements ChunkManager{ * * @return int 0-15 */ - public function getBlockSkyLightAt(int $x, int $y, int $z) : int{ + public function getPotentialBlockSkyLightAt(int $x, int $y, int $z) : int{ return $this->getOrLoadChunk($x >> 4, $z >> 4, true)->getSubChunk($y >> 4)->getBlockSkyLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); } From f67ab094f2c0474fbaca4a997c5bb33673107883 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 16:51:14 +0000 Subject: [PATCH 1996/3224] fix build --- tests/phpstan/configs/l7-baseline.neon | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index 0bfaaab033..1673a1c195 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -196,17 +196,17 @@ parameters: path: ../../../src/block/FrostedIce.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentBlockSkyLight\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentRealBlockSkyLight\\(\\) expects int, float\\|int given\\.$#" count: 1 path: ../../../src/block/FrostedIce.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentBlockSkyLight\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentRealBlockSkyLight\\(\\) expects int, float\\|int given\\.$#" count: 1 path: ../../../src/block/FrostedIce.php - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentBlockSkyLight\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentRealBlockSkyLight\\(\\) expects int, float\\|int given\\.$#" count: 1 path: ../../../src/block/FrostedIce.php From 68f5eada3299299bd9b4e551e4c8230739fb1251 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 20:18:06 +0000 Subject: [PATCH 1997/3224] added fire extinguishing sound, closes #2777 --- src/player/Player.php | 2 ++ src/world/sound/FireExtinguishSound.php | 34 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/world/sound/FireExtinguishSound.php diff --git a/src/player/Player.php b/src/player/Player.php index 4bc7070e16..d70a9c2f5d 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -108,6 +108,7 @@ use pocketmine\world\format\Chunk; use pocketmine\world\Position; use pocketmine\world\sound\EntityAttackNoDamageSound; use pocketmine\world\sound\EntityAttackSound; +use pocketmine\world\sound\FireExtinguishSound; use pocketmine\world\World; use function abs; use function assert; @@ -1572,6 +1573,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $block = $target->getSide($face); if($block->getId() === BlockLegacyIds::FIRE){ $this->getWorld()->setBlock($block->getPos(), VanillaBlocks::AIR()); + $this->getWorld()->addSound($block->getPos()->add(0.5, 0.5, 0.5), new FireExtinguishSound()); return true; } diff --git a/src/world/sound/FireExtinguishSound.php b/src/world/sound/FireExtinguishSound.php new file mode 100644 index 0000000000..0c0707911b --- /dev/null +++ b/src/world/sound/FireExtinguishSound.php @@ -0,0 +1,34 @@ + Date: Sat, 31 Oct 2020 20:38:15 +0000 Subject: [PATCH 1998/3224] World: don't try to load chunks to read light levels sync chunk load is useless here because lighting isn't immediately calculated anyway and it isn't available directly from the chunk when loaded. --- src/world/World.php | 10 ++++++++-- tests/phpstan/configs/l8-baseline.neon | 5 ----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 74342b68d6..01dab44493 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1839,7 +1839,10 @@ class World implements ChunkManager{ * @return int 0-15 */ public function getPotentialBlockSkyLightAt(int $x, int $y, int $z) : int{ - return $this->getOrLoadChunk($x >> 4, $z >> 4, true)->getSubChunk($y >> 4)->getBlockSkyLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); + if(($chunk = $this->getChunk($x >> 4, $z >> 4, false)) !== null){ + return $chunk->getSubChunk($y >> 4)->getBlockSkyLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); + } + return 0; //TODO: this should probably throw instead (light not calculated yet) } /** @@ -1848,7 +1851,10 @@ class World implements ChunkManager{ * @return int 0-15 */ public function getBlockLightAt(int $x, int $y, int $z) : int{ - return $this->getOrLoadChunk($x >> 4, $z >> 4, true)->getSubChunk($y >> 4)->getBlockLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); + if(($chunk = $this->getChunk($x >> 4, $z >> 4, false)) !== null){ + return $chunk->getSubChunk($y >> 4)->getBlockLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); + } + return 0; //TODO: this should probably throw instead (light not calculated yet) } public function getBiomeId(int $x, int $z) : int{ diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index e07ad407c0..f98b36f586 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -555,11 +555,6 @@ parameters: count: 3 path: ../../../src/world/World.php - - - message: "#^Cannot call method getSubChunk\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 2 - path: ../../../src/world/World.php - - message: "#^Cannot call method getBiomeId\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" count: 1 From de867f1b86b3631bb206a17ad17057fde59b1a60 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 21:27:16 +0000 Subject: [PATCH 1999/3224] World: don't create an empty chunk just for accessing the highest block this is pointless since the chunk will not be generated anyway, so it serves no end to create it. --- src/world/World.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 01dab44493..40c2438696 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2032,10 +2032,13 @@ class World implements ChunkManager{ /** * Gets the highest block Y value at a specific $x and $z * - * @return int 0-255 + * @return int 0-255, or -1 if the chunk is not generated */ public function getHighestBlockAt(int $x, int $z) : int{ - return $this->getOrLoadChunk($x >> 4, $z >> 4, true)->getHighestBlockAt($x & 0x0f, $z & 0x0f); + if(($chunk = $this->getOrLoadChunk($x >> 4, $z >> 4, false)) !== null){ + return $chunk->getHighestBlockAt($x & 0x0f, $z & 0x0f); + } + return -1; //TODO: this should probably throw an exception (terrain not generated yet) } /** From dec235abab5f7e024b954be21941b88b26d07b45 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 21:29:39 +0000 Subject: [PATCH 2000/3224] World: don't create a new chunk just to read biome info the chunk won't be generated, so we can provide the default result without creating a new chunk for no reason. --- src/world/World.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index 40c2438696..a2b6a7feaf 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1858,7 +1858,10 @@ class World implements ChunkManager{ } public function getBiomeId(int $x, int $z) : int{ - return $this->getOrLoadChunk($x >> 4, $z >> 4, true)->getBiomeId($x & 0x0f, $z & 0x0f); + if(($chunk = $this->getOrLoadChunk($x >> 4, $z >> 4, false)) !== null){ + return $chunk->getBiomeId($x & 0x0f, $z & 0x0f); + } + return Biome::OCEAN; //TODO: this should probably throw instead (terrain not generated yet) } public function getBiome(int $x, int $z) : Biome{ From ddda2d1e641fd0427b3dc7ef6f0797a868888fcc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 21:54:51 +0000 Subject: [PATCH 2001/3224] Remove $create parameter from ChunkManager::getChunk() this restores SimpleChunkManager's behaviour to PM3, removing the need for GeneratorChunkManager (although I'm dubious whether SubChunkExplorer makes any sense in there any more now that we have morton in the mix). --- src/world/ChunkManager.php | 2 +- src/world/Explosion.php | 2 +- src/world/SimpleChunkManager.php | 9 ++--- src/world/World.php | 12 ++---- src/world/generator/GeneratorChunkManager.php | 38 ------------------- src/world/generator/GeneratorRegisterTask.php | 3 +- src/world/generator/PopulationTask.php | 3 +- src/world/light/BlockLightUpdate.php | 4 +- src/world/light/LightUpdate.php | 8 ++-- src/world/light/SkyLightUpdate.php | 6 +-- src/world/utils/SubChunkExplorer.php | 8 ++-- 11 files changed, 27 insertions(+), 68 deletions(-) delete mode 100644 src/world/generator/GeneratorChunkManager.php diff --git a/src/world/ChunkManager.php b/src/world/ChunkManager.php index 97ef38a307..50ec60b234 100644 --- a/src/world/ChunkManager.php +++ b/src/world/ChunkManager.php @@ -40,7 +40,7 @@ interface ChunkManager{ */ public function setBlockAt(int $x, int $y, int $z, Block $block) : void; - public function getChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk; + public function getChunk(int $chunkX, int $chunkZ) : ?Chunk; public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk) : void; diff --git a/src/world/Explosion.php b/src/world/Explosion.php index 41e24ed6de..cca2373eba 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -124,7 +124,7 @@ class Explosion{ $pointerY += $shiftY; $pointerZ += $shiftZ; - if($this->subChunkExplorer->moveTo($vBlockX, $vBlockY, $vBlockZ, false) === SubChunkExplorerStatus::INVALID){ + if($this->subChunkExplorer->moveTo($vBlockX, $vBlockY, $vBlockZ) === SubChunkExplorerStatus::INVALID){ continue; } diff --git a/src/world/SimpleChunkManager.php b/src/world/SimpleChunkManager.php index 5540ad51b0..7911158b09 100644 --- a/src/world/SimpleChunkManager.php +++ b/src/world/SimpleChunkManager.php @@ -51,14 +51,14 @@ class SimpleChunkManager implements ChunkManager{ } public function getBlockAt(int $x, int $y, int $z) : Block{ - if($this->terrainPointer->moveTo($x, $y, $z, false) !== SubChunkExplorerStatus::INVALID){ + if($this->terrainPointer->moveTo($x, $y, $z) !== SubChunkExplorerStatus::INVALID){ return BlockFactory::getInstance()->fromFullBlock($this->terrainPointer->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf)); } return VanillaBlocks::AIR(); } public function setBlockAt(int $x, int $y, int $z, Block $block) : void{ - if($this->terrainPointer->moveTo($x, $y, $z, true) !== SubChunkExplorerStatus::INVALID){ + if($this->terrainPointer->moveTo($x, $y, $z) !== SubChunkExplorerStatus::INVALID){ $this->terrainPointer->currentSubChunk->setFullBlock($x & 0xf, $y & 0xf, $z & 0xf, $block->getFullId()); $this->terrainPointer->currentChunk->setDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN, true); }else{ @@ -66,9 +66,8 @@ class SimpleChunkManager implements ChunkManager{ } } - public function getChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk{ - $hash = World::chunkHash($chunkX, $chunkZ); - return $this->chunks[$hash] ?? ($create ? $this->chunks[$hash] = new Chunk($chunkX, $chunkZ) : null); + public function getChunk(int $chunkX, int $chunkZ) : ?Chunk{ + return $this->chunks[World::chunkHash($chunkX, $chunkZ)] ?? null; } public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk) : void{ diff --git a/src/world/World.php b/src/world/World.php index a2b6a7feaf..8f2af6cdf9 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1839,7 +1839,7 @@ class World implements ChunkManager{ * @return int 0-15 */ public function getPotentialBlockSkyLightAt(int $x, int $y, int $z) : int{ - if(($chunk = $this->getChunk($x >> 4, $z >> 4, false)) !== null){ + if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ return $chunk->getSubChunk($y >> 4)->getBlockSkyLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); } return 0; //TODO: this should probably throw instead (light not calculated yet) @@ -1851,7 +1851,7 @@ class World implements ChunkManager{ * @return int 0-15 */ public function getBlockLightAt(int $x, int $y, int $z) : int{ - if(($chunk = $this->getChunk($x >> 4, $z >> 4, false)) !== null){ + if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ return $chunk->getSubChunk($y >> 4)->getBlockLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); } return 0; //TODO: this should probably throw instead (light not calculated yet) @@ -1895,12 +1895,8 @@ class World implements ChunkManager{ return null; } - public function getChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk{ - $hash = World::chunkHash($chunkX, $chunkZ); - if(isset($this->chunks[$hash])){ - return $this->chunks[$hash]; - } - return $create ? ($this->chunks[$hash] = new Chunk($chunkX, $chunkZ)) : null; + public function getChunk(int $chunkX, int $chunkZ) : ?Chunk{ + return $this->chunks[World::chunkHash($chunkX, $chunkZ)] ?? null; } /** diff --git a/src/world/generator/GeneratorChunkManager.php b/src/world/generator/GeneratorChunkManager.php deleted file mode 100644 index 312bf182e0..0000000000 --- a/src/world/generator/GeneratorChunkManager.php +++ /dev/null @@ -1,38 +0,0 @@ -chunks[World::chunkHash($chunkX, $chunkZ)])){ - throw new \InvalidArgumentException("Chunk does not exist"); - } - return parent::getChunk($chunkX, $chunkZ, $create); - } -} diff --git a/src/world/generator/GeneratorRegisterTask.php b/src/world/generator/GeneratorRegisterTask.php index 25f4777d6b..06060ae0bf 100644 --- a/src/world/generator/GeneratorRegisterTask.php +++ b/src/world/generator/GeneratorRegisterTask.php @@ -25,6 +25,7 @@ namespace pocketmine\world\generator; use pocketmine\scheduler\AsyncTask; use pocketmine\world\biome\Biome; +use pocketmine\world\SimpleChunkManager; use pocketmine\world\World; use function igbinary_serialize; use function igbinary_unserialize; @@ -56,7 +57,7 @@ class GeneratorRegisterTask extends AsyncTask{ public function onRun() : void{ Biome::init(); - $manager = new GeneratorChunkManager($this->worldHeight); + $manager = new SimpleChunkManager($this->worldHeight); $this->worker->saveToThreadStore("generation.world{$this->worldId}.manager", $manager); /** diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 2ead5ece6e..dd1f152ca2 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -26,6 +26,7 @@ namespace pocketmine\world\generator; use pocketmine\scheduler\AsyncTask; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\FastChunkSerializer; +use pocketmine\world\SimpleChunkManager; use pocketmine\world\World; class PopulationTask extends AsyncTask{ @@ -73,7 +74,7 @@ class PopulationTask extends AsyncTask{ public function onRun() : void{ $manager = $this->worker->getFromThreadStore("generation.world{$this->worldId}.manager"); $generator = $this->worker->getFromThreadStore("generation.world{$this->worldId}.generator"); - if(!($manager instanceof GeneratorChunkManager) or !($generator instanceof Generator)){ + if(!($manager instanceof SimpleChunkManager) or !($generator instanceof Generator)){ $this->state = false; return; } diff --git a/src/world/light/BlockLightUpdate.php b/src/world/light/BlockLightUpdate.php index d97b87d533..ed1bf5d272 100644 --- a/src/world/light/BlockLightUpdate.php +++ b/src/world/light/BlockLightUpdate.php @@ -53,14 +53,14 @@ class BlockLightUpdate extends LightUpdate{ } public function recalculateNode(int $x, int $y, int $z) : void{ - if($this->subChunkExplorer->moveTo($x, $y, $z, false) !== SubChunkExplorerStatus::INVALID){ + if($this->subChunkExplorer->moveTo($x, $y, $z) !== SubChunkExplorerStatus::INVALID){ $block = $this->subChunkExplorer->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf); $this->setAndUpdateLight($x, $y, $z, max($this->lightEmitters[$block], $this->getHighestAdjacentLight($x, $y, $z) - $this->lightFilters[$block])); } } public function recalculateChunk(int $chunkX, int $chunkZ) : int{ - if($this->subChunkExplorer->moveToChunk($chunkX, 0, $chunkZ, false) === SubChunkExplorerStatus::INVALID){ + if($this->subChunkExplorer->moveToChunk($chunkX, 0, $chunkZ) === SubChunkExplorerStatus::INVALID){ throw new \InvalidArgumentException("Chunk $chunkX $chunkZ does not exist"); } $chunk = $this->subChunkExplorer->currentChunk; diff --git a/src/world/light/LightUpdate.php b/src/world/light/LightUpdate.php index 8fac2e378a..bc98e5b53a 100644 --- a/src/world/light/LightUpdate.php +++ b/src/world/light/LightUpdate.php @@ -68,7 +68,7 @@ abstract class LightUpdate{ abstract public function recalculateChunk(int $chunkX, int $chunkZ) : int; protected function getEffectiveLight(int $x, int $y, int $z) : int{ - if($this->subChunkExplorer->moveTo($x, $y, $z, false) !== SubChunkExplorerStatus::INVALID){ + if($this->subChunkExplorer->moveTo($x, $y, $z) !== SubChunkExplorerStatus::INVALID){ return $this->getCurrentLightArray()->get($x & 0xf, $y & 0xf, $z & 0xf); } return 0; @@ -98,7 +98,7 @@ abstract class LightUpdate{ private function prepareNodes() : LightPropagationContext{ $context = new LightPropagationContext(); foreach($this->updateNodes as $blockHash => [$x, $y, $z, $newLevel]){ - if($this->subChunkExplorer->moveTo($x, $y, $z, false) !== SubChunkExplorerStatus::INVALID){ + if($this->subChunkExplorer->moveTo($x, $y, $z) !== SubChunkExplorerStatus::INVALID){ $lightArray = $this->getCurrentLightArray(); $oldLevel = $lightArray->get($x & 0xf, $y & 0xf, $z & 0xf); @@ -135,7 +135,7 @@ abstract class LightUpdate{ ]; foreach($points as [$cx, $cy, $cz]){ - if($this->subChunkExplorer->moveTo($cx, $cy, $cz, false) !== SubChunkExplorerStatus::INVALID){ + if($this->subChunkExplorer->moveTo($cx, $cy, $cz) !== SubChunkExplorerStatus::INVALID){ $this->computeRemoveLight($cx, $cy, $cz, $oldAdjacentLight, $context); }elseif($this->getEffectiveLight($cx, $cy, $cz) > 0 and !isset($context->spreadVisited[$index = World::blockHash($cx, $cy, $cz)])){ $context->spreadVisited[$index] = true; @@ -165,7 +165,7 @@ abstract class LightUpdate{ ]; foreach($points as [$cx, $cy, $cz]){ - if($this->subChunkExplorer->moveTo($cx, $cy, $cz, false) !== SubChunkExplorerStatus::INVALID){ + if($this->subChunkExplorer->moveTo($cx, $cy, $cz) !== SubChunkExplorerStatus::INVALID){ $this->computeSpreadLight($cx, $cy, $cz, $newAdjacentLight, $context); } } diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index 9b7674646f..4408a97e5a 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -61,7 +61,7 @@ class SkyLightUpdate extends LightUpdate{ } public function recalculateNode(int $x, int $y, int $z) : void{ - if($this->subChunkExplorer->moveTo($x, $y, $z, false) === SubChunkExplorerStatus::INVALID){ + if($this->subChunkExplorer->moveTo($x, $y, $z) === SubChunkExplorerStatus::INVALID){ return; } $chunk = $this->subChunkExplorer->currentChunk; @@ -98,7 +98,7 @@ class SkyLightUpdate extends LightUpdate{ } public function recalculateChunk(int $chunkX, int $chunkZ) : int{ - if($this->subChunkExplorer->moveToChunk($chunkX, 0, $chunkZ, false) === SubChunkExplorerStatus::INVALID){ + if($this->subChunkExplorer->moveToChunk($chunkX, 0, $chunkZ) === SubChunkExplorerStatus::INVALID){ throw new \InvalidArgumentException("Chunk $chunkX $chunkZ does not exist"); } $chunk = $this->subChunkExplorer->currentChunk; @@ -151,7 +151,7 @@ class SkyLightUpdate extends LightUpdate{ $lightSources++; } for($y = $nodeColumnEnd + 1, $yMax = $lowestClearSubChunk * 16; $y < $yMax; $y++){ - if($this->subChunkExplorer->moveTo($x + $baseX, $y, $z + $baseZ, false) !== SubChunkExplorerStatus::INVALID){ + if($this->subChunkExplorer->moveTo($x + $baseX, $y, $z + $baseZ) !== SubChunkExplorerStatus::INVALID){ $this->getCurrentLightArray()->set($x, $y & 0xf, $z, 15); } } diff --git a/src/world/utils/SubChunkExplorer.php b/src/world/utils/SubChunkExplorer.php index 18f9b3b7d1..0905473e3f 100644 --- a/src/world/utils/SubChunkExplorer.php +++ b/src/world/utils/SubChunkExplorer.php @@ -58,13 +58,13 @@ class SubChunkExplorer{ /** * @phpstan-return SubChunkExplorerStatus::* */ - public function moveTo(int $x, int $y, int $z, bool $create) : int{ + public function moveTo(int $x, int $y, int $z) : int{ if($this->currentChunk === null or $this->currentX !== ($x >> 4) or $this->currentZ !== ($z >> 4)){ $this->currentX = $x >> 4; $this->currentZ = $z >> 4; $this->currentSubChunk = null; - $this->currentChunk = $this->world->getChunk($this->currentX, $this->currentZ, $create); + $this->currentChunk = $this->world->getChunk($this->currentX, $this->currentZ); if($this->currentChunk === null){ return SubChunkExplorerStatus::INVALID; } @@ -93,9 +93,9 @@ class SubChunkExplorer{ /** * @phpstan-return SubChunkExplorerStatus::* */ - public function moveToChunk(int $chunkX, int $chunkY, int $chunkZ, bool $create) : int{ + public function moveToChunk(int $chunkX, int $chunkY, int $chunkZ) : int{ //this is a cold path, so we don't care much if it's a bit slower (extra fcall overhead) - return $this->moveTo($chunkX << 4, $chunkY << 4, $chunkZ << 4, $create); + return $this->moveTo($chunkX << 4, $chunkY << 4, $chunkZ << 4); } /** From d0470a80ab662601b6fbee48ae674b71b9d80a15 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 22:02:36 +0000 Subject: [PATCH 2002/3224] SimpleChunkManager: remove post-mature optimisation these methods are not used in hot paths and are inherently slow anyway, not to mention the introduction of morton codes eliminating the hashtable indexing problem. --- src/world/SimpleChunkManager.php | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/world/SimpleChunkManager.php b/src/world/SimpleChunkManager.php index 7911158b09..17325ad0fb 100644 --- a/src/world/SimpleChunkManager.php +++ b/src/world/SimpleChunkManager.php @@ -28,8 +28,6 @@ use pocketmine\block\BlockFactory; use pocketmine\block\VanillaBlocks; use pocketmine\utils\Limits; use pocketmine\world\format\Chunk; -use pocketmine\world\utils\SubChunkExplorer; -use pocketmine\world\utils\SubChunkExplorerStatus; class SimpleChunkManager implements ChunkManager{ @@ -39,28 +37,23 @@ class SimpleChunkManager implements ChunkManager{ /** @var int */ protected $worldHeight; - /** @var SubChunkExplorer */ - protected $terrainPointer; - /** * SimpleChunkManager constructor. */ public function __construct(int $worldHeight = World::Y_MAX){ $this->worldHeight = $worldHeight; - $this->terrainPointer = new SubChunkExplorer($this); } public function getBlockAt(int $x, int $y, int $z) : Block{ - if($this->terrainPointer->moveTo($x, $y, $z) !== SubChunkExplorerStatus::INVALID){ - return BlockFactory::getInstance()->fromFullBlock($this->terrainPointer->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf)); + if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ + return BlockFactory::getInstance()->fromFullBlock($chunk->getFullBlock($x & 0xf, $y, $z)); } return VanillaBlocks::AIR(); } public function setBlockAt(int $x, int $y, int $z, Block $block) : void{ - if($this->terrainPointer->moveTo($x, $y, $z) !== SubChunkExplorerStatus::INVALID){ - $this->terrainPointer->currentSubChunk->setFullBlock($x & 0xf, $y & 0xf, $z & 0xf, $block->getFullId()); - $this->terrainPointer->currentChunk->setDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN, true); + if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ + $chunk->setFullBlock($x & 0xf, $y, $z & 0xf, $block->getFullId()); }else{ throw new \InvalidArgumentException("Cannot set block at coordinates x=$x,y=$y,z=$z, terrain is not loaded or out of bounds"); } From f5807ac0498f0953b9ddc53d2eb0de496248cf00 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 22:22:02 +0000 Subject: [PATCH 2003/3224] World::getBlockAt() now doesn't assume that AIR has a fullStateId of 0 --- src/world/World.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 8f2af6cdf9..999ad614d1 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -33,6 +33,7 @@ use pocketmine\block\BlockLegacyIds; use pocketmine\block\tile\Spawnable; use pocketmine\block\tile\Tile; use pocketmine\block\UnknownBlock; +use pocketmine\block\VanillaBlocks; use pocketmine\entity\Entity; use pocketmine\entity\Location; use pocketmine\entity\object\ExperienceOrb; @@ -1329,7 +1330,6 @@ class World implements ChunkManager{ * @param bool $addToCache Whether to cache the block object created by this method call. */ public function getBlockAt(int $x, int $y, int $z, bool $cached = true, bool $addToCache = true) : Block{ - $fullState = 0; $relativeBlockHash = null; $chunkHash = World::chunkHash($x >> 4, $z >> 4); @@ -1342,13 +1342,15 @@ class World implements ChunkManager{ $chunk = $this->chunks[$chunkHash] ?? null; if($chunk !== null){ - $fullState = $chunk->getFullBlock($x & 0x0f, $y, $z & 0x0f); + $block = BlockFactory::getInstance()->fromFullBlock($chunk->getFullBlock($x & 0x0f, $y, $z & 0x0f)); }else{ $addToCache = false; + $block = VanillaBlocks::AIR(); } + }else{ + $block = VanillaBlocks::AIR(); } - $block = BlockFactory::getInstance()->fromFullBlock($fullState); $block->position($this, $x, $y, $z); static $dynamicStateRead = false; From 5701e733cc256999c64e6c49eb74d48d69bd9b53 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 22:36:12 +0000 Subject: [PATCH 2004/3224] World: fixed a crash in getFullBlock() when used on ungenerated terrain --- src/world/World.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index 999ad614d1..03a99cce75 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1295,7 +1295,10 @@ class World implements ChunkManager{ * @return int bitmap, (id << 4) | data */ public function getFullBlock(int $x, int $y, int $z) : int{ - return $this->getOrLoadChunk($x >> 4, $z >> 4, false)->getFullBlock($x & 0x0f, $y, $z & 0x0f); + if(($chunk = $this->getOrLoadChunk($x >> 4, $z >> 4, false)) !== null){ + return $chunk->getFullBlock($x & 0x0f, $y, $z & 0x0f); + } + return BlockLegacyIds::AIR << 4; //TODO: this should throw (ungenerated chunk) } public function isInWorld(int $x, int $y, int $z) : bool{ From b2700291615637dc338aa080babf1804f140d129 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 22:46:33 +0000 Subject: [PATCH 2005/3224] Rename Chunk::getWritableSubChunk() -> Chunk::getSubChunkChecked() this is not specific to 'writable', it's just an opt-in to checked bounds so that an EmptySubChunk will never be received. --- src/world/format/Chunk.php | 6 +++--- src/world/generator/Flat.php | 2 +- src/world/light/LightPopulationTask.php | 4 ++-- src/world/light/SkyLightUpdate.php | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 95e2afba51..30f95e792e 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -152,7 +152,7 @@ class Chunk{ * Sets the blockstate at the given coordinate by internal ID. */ public function setFullBlock(int $x, int $y, int $z, int $block) : void{ - $this->getWritableSubChunk($y >> 4)->setFullBlock($x, $y & 0xf, $z, $block); + $this->getSubChunkChecked($y >> 4)->setFullBlock($x, $y & 0xf, $z, $block); $this->dirtyFlags |= self::DIRTY_FLAG_TERRAIN; } @@ -516,9 +516,9 @@ class Chunk{ return $this->subChunks[$y]; } - public function getWritableSubChunk(int $y) : SubChunk{ + public function getSubChunkChecked(int $y) : SubChunk{ if($y < 0 || $y >= $this->subChunks->getSize()){ - throw new \InvalidArgumentException("Cannot get subchunk $y for writing"); + throw new \InvalidArgumentException("Invalid subchunk Y coordinate $y"); } return $this->subChunks[$y]; } diff --git a/src/world/generator/Flat.php b/src/world/generator/Flat.php index 87b8b3fe2f..62dcf65908 100644 --- a/src/world/generator/Flat.php +++ b/src/world/generator/Flat.php @@ -156,7 +156,7 @@ class Flat extends Generator{ $count = count($this->structure); for($sy = 0; $sy < $count; $sy += 16){ - $subchunk = $this->chunk->getWritableSubChunk($sy >> 4); + $subchunk = $this->chunk->getSubChunkChecked($sy >> 4); for($y = 0; $y < 16 and isset($this->structure[$y | $sy]); ++$y){ $id = $this->structure[$y | $sy]; diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index 896c7a645d..b171d06e9d 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -104,10 +104,10 @@ class LightPopulationTask extends AsyncTask{ $blockLightArrays = igbinary_unserialize($this->resultBlockLightArrays); foreach($skyLightArrays as $y => $array){ - $chunk->getWritableSubChunk($y)->setBlockSkyLightArray($array); + $chunk->getSubChunkChecked($y)->setBlockSkyLightArray($array); } foreach($blockLightArrays as $y => $array){ - $chunk->getWritableSubChunk($y)->setBlockLightArray($array); + $chunk->getSubChunkChecked($y)->setBlockLightArray($array); } $chunk->setLightPopulated(); } diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index 4408a97e5a..d6bbdca5f8 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -111,10 +111,10 @@ class SkyLightUpdate extends LightUpdate{ $lowestClearSubChunk = ($highestHeightMapPlusOne >> 4) + (($highestHeightMapPlusOne & 0xf) !== 0 ? 1 : 0); $chunkHeight = $chunk->getSubChunks()->count(); for($y = 0; $y < $lowestClearSubChunk && $y < $chunkHeight; $y++){ - $chunk->getWritableSubChunk($y)->setBlockSkyLightArray(LightArray::fill(0)); + $chunk->getSubChunkChecked($y)->setBlockSkyLightArray(LightArray::fill(0)); } for($y = $lowestClearSubChunk, $yMax = $chunkHeight; $y < $yMax; $y++){ - $chunk->getWritableSubChunk($y)->setBlockSkyLightArray(LightArray::fill(15)); + $chunk->getSubChunkChecked($y)->setBlockSkyLightArray(LightArray::fill(15)); } $lightSources = 0; From 01001dca7493fe944790f6f7514a3f06cc140014 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 22:48:41 +0000 Subject: [PATCH 2006/3224] Use Chunk::getSubChunkChecked() in places where we know that an invalid coordinate cannot be requested --- src/network/mcpe/serializer/ChunkSerializer.php | 4 ++-- src/world/format/Chunk.php | 6 +++--- src/world/utils/SubChunkExplorer.php | 5 +---- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index abf0e1b25c..b661a20ea4 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -43,7 +43,7 @@ final class ChunkSerializer{ */ public static function getSubChunkCount(Chunk $chunk) : int{ for($count = $chunk->getSubChunks()->count(); $count > 0; --$count){ - if($chunk->getSubChunk($count - 1)->isEmptyFast()){ + if($chunk->getSubChunkChecked($count - 1)->isEmptyFast()){ continue; } return $count; @@ -56,7 +56,7 @@ final class ChunkSerializer{ $stream = new PacketSerializer(); $subChunkCount = self::getSubChunkCount($chunk); for($y = 0; $y < $subChunkCount; ++$y){ - $layers = $chunk->getSubChunk($y)->getBlockLayers(); + $layers = $chunk->getSubChunkChecked($y)->getBlockLayers(); $stream->putByte(8); //version $stream->putByte(count($layers)); diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 30f95e792e..6fc74fc2f3 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -166,7 +166,7 @@ class Chunk{ */ public function getHighestBlockAt(int $x, int $z) : int{ for($y = $this->subChunks->count() - 1; $y >= 0; --$y){ - $height = $this->getSubChunk($y)->getHighestBlockAt($x, $z) | ($y << 4); + $height = $this->getSubChunkChecked($y)->getHighestBlockAt($x, $z) | ($y << 4); if($height !== -1){ return $height; } @@ -204,7 +204,7 @@ class Chunk{ public function recalculateHeightMap(\SplFixedArray $directSkyLightBlockers) : void{ $maxSubChunkY = $this->subChunks->count() - 1; for(; $maxSubChunkY >= 0; $maxSubChunkY--){ - if(!$this->getSubChunk($maxSubChunkY)->isEmptyFast()){ + if(!$this->getSubChunkChecked($maxSubChunkY)->isEmptyFast()){ break; } } @@ -217,7 +217,7 @@ class Chunk{ for($x = 0; $x < 16; ++$x){ $y = null; for($subChunkY = $maxSubChunkY; $subChunkY >= 0; $subChunkY--){ - $subHighestBlockY = $this->getSubChunk($subChunkY)->getHighestBlockAt($x, $z); + $subHighestBlockY = $this->getSubChunkChecked($subChunkY)->getHighestBlockAt($x, $z); if($subHighestBlockY !== -1){ $y = ($subChunkY * 16) + $subHighestBlockY; break; diff --git a/src/world/utils/SubChunkExplorer.php b/src/world/utils/SubChunkExplorer.php index 0905473e3f..69ce4d6cb4 100644 --- a/src/world/utils/SubChunkExplorer.php +++ b/src/world/utils/SubChunkExplorer.php @@ -27,7 +27,6 @@ use pocketmine\utils\Utils; use pocketmine\world\ChunkManager; use pocketmine\world\format\Chunk; use pocketmine\world\format\SubChunk; -use function assert; class SubChunkExplorer{ /** @var ChunkManager */ @@ -78,9 +77,7 @@ class SubChunkExplorer{ return SubChunkExplorerStatus::INVALID; } - $newSubChunk = $this->currentChunk->getSubChunk($y >> 4); - assert($newSubChunk instanceof SubChunk, "chunk inside valid bounds should always be a SubChunk instance"); - $this->currentSubChunk = $newSubChunk; + $this->currentSubChunk = $this->currentChunk->getSubChunkChecked($y >> 4); if($this->onSubChunkChangeFunc !== null){ ($this->onSubChunkChangeFunc)(); } From d94877f5d20ae84db1d7841f48222a8187fc9490 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 22:51:24 +0000 Subject: [PATCH 2007/3224] fix build --- tests/phpstan/configs/l8-baseline.neon | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index f98b36f586..78a7d033c0 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -601,7 +601,7 @@ parameters: path: ../../../src/world/format/Chunk.php - - message: "#^Method pocketmine\\\\world\\\\format\\\\Chunk\\:\\:getWritableSubChunk\\(\\) should return pocketmine\\\\world\\\\format\\\\SubChunk but returns pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" + message: "#^Method pocketmine\\\\world\\\\format\\\\Chunk\\:\\:getSubChunkChecked\\(\\) should return pocketmine\\\\world\\\\format\\\\SubChunk but returns pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" count: 1 path: ../../../src/world/format/Chunk.php @@ -826,7 +826,7 @@ parameters: path: ../../../src/world/light/SkyLightUpdate.php - - message: "#^Cannot call method getWritableSubChunk\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + message: "#^Cannot call method getSubChunkChecked\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" count: 2 path: ../../../src/world/light/SkyLightUpdate.php From 40f9cd16cb57dbfcdb81239246864ebc40e378e4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 22:52:00 +0000 Subject: [PATCH 2008/3224] phpstan: drop a bunch of obsolete ignoredErrors from l8 baseline --- tests/phpstan/configs/l8-baseline.neon | 30 -------------------------- 1 file changed, 30 deletions(-) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 78a7d033c0..f62f06b1dd 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -525,51 +525,21 @@ parameters: count: 1 path: ../../../src/world/Explosion.php - - - message: "#^Cannot call method getFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" - count: 1 - path: ../../../src/world/SimpleChunkManager.php - - - - message: "#^Cannot call method setFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" - count: 1 - path: ../../../src/world/SimpleChunkManager.php - - - - message: "#^Cannot call method setDirtyFlag\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/world/SimpleChunkManager.php - - message: "#^Parameter \\#1 \\$chunk of method pocketmine\\\\player\\\\Player\\:\\:onChunkChanged\\(\\) expects pocketmine\\\\world\\\\format\\\\Chunk, pocketmine\\\\world\\\\format\\\\Chunk\\|null given\\.$#" count: 1 path: ../../../src/world/World.php - - - message: "#^Cannot call method getFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/world/World.php - - message: "#^Cannot call method getEntities\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" count: 3 path: ../../../src/world/World.php - - - message: "#^Cannot call method getBiomeId\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/world/World.php - - message: "#^Cannot call method setBiomeId\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" count: 1 path: ../../../src/world/World.php - - - message: "#^Cannot call method getHighestBlockAt\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/world/World.php - - message: "#^Cannot call method isPopulated\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" count: 1 From 8ee70dc30aa567e67b5dca533c76e2dea73f2eda Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 22:55:56 +0000 Subject: [PATCH 2009/3224] SimpleChunkManager: fix missing mask in getBlockAt() --- src/world/SimpleChunkManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/SimpleChunkManager.php b/src/world/SimpleChunkManager.php index 17325ad0fb..1eb6ef17ba 100644 --- a/src/world/SimpleChunkManager.php +++ b/src/world/SimpleChunkManager.php @@ -46,7 +46,7 @@ class SimpleChunkManager implements ChunkManager{ public function getBlockAt(int $x, int $y, int $z) : Block{ if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ - return BlockFactory::getInstance()->fromFullBlock($chunk->getFullBlock($x & 0xf, $y, $z)); + return BlockFactory::getInstance()->fromFullBlock($chunk->getFullBlock($x & 0xf, $y, $z & 0xf)); } return VanillaBlocks::AIR(); } From bacfcf258e66c14590ecb926eff1fba794577a42 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 23:00:27 +0000 Subject: [PATCH 2010/3224] World: remove unused function --- src/world/World.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 03a99cce75..85ed9822bc 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1291,16 +1291,6 @@ class World implements ChunkManager{ } } - /** - * @return int bitmap, (id << 4) | data - */ - public function getFullBlock(int $x, int $y, int $z) : int{ - if(($chunk = $this->getOrLoadChunk($x >> 4, $z >> 4, false)) !== null){ - return $chunk->getFullBlock($x & 0x0f, $y, $z & 0x0f); - } - return BlockLegacyIds::AIR << 4; //TODO: this should throw (ungenerated chunk) - } - public function isInWorld(int $x, int $y, int $z) : bool{ return ( $x <= Limits::INT32_MAX and $x >= Limits::INT32_MIN and From f50be1ba63426a72c76684118c8f275049f374c7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 23:06:12 +0000 Subject: [PATCH 2011/3224] Chunk: Use getSubChunkChecked() in getFullBlock() --- src/world/SimpleChunkManager.php | 2 +- src/world/format/Chunk.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/SimpleChunkManager.php b/src/world/SimpleChunkManager.php index 1eb6ef17ba..cfa67f9a5a 100644 --- a/src/world/SimpleChunkManager.php +++ b/src/world/SimpleChunkManager.php @@ -45,7 +45,7 @@ class SimpleChunkManager implements ChunkManager{ } public function getBlockAt(int $x, int $y, int $z) : Block{ - if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ + if($this->isInWorld($x, $y, $z) && ($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ return BlockFactory::getInstance()->fromFullBlock($chunk->getFullBlock($x & 0xf, $y, $z & 0xf)); } return VanillaBlocks::AIR(); diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 6fc74fc2f3..7f3f061626 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -145,7 +145,7 @@ class Chunk{ * @return int bitmap, (id << 4) | meta */ public function getFullBlock(int $x, int $y, int $z) : int{ - return $this->getSubChunk($y >> 4)->getFullBlock($x, $y & 0x0f, $z); + return $this->getSubChunkChecked($y >> 4)->getFullBlock($x, $y & 0x0f, $z); } /** From 13d7b7ee1aeb5900e658a651f39c44d5b776eaf4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 23:07:36 +0000 Subject: [PATCH 2012/3224] Removed final remaining usages of Chunk::getSubChunk() this clears the way to get rid of EmptySubChunk. --- src/world/World.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 85ed9822bc..ba7a4d8239 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1834,8 +1834,11 @@ class World implements ChunkManager{ * @return int 0-15 */ public function getPotentialBlockSkyLightAt(int $x, int $y, int $z) : int{ + if(!$this->isInWorld($x, $y, $z)){ + return $y >= self::Y_MAX ? 15 : 0; + } if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ - return $chunk->getSubChunk($y >> 4)->getBlockSkyLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); + return $chunk->getSubChunkChecked($y >> 4)->getBlockSkyLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); } return 0; //TODO: this should probably throw instead (light not calculated yet) } @@ -1846,8 +1849,11 @@ class World implements ChunkManager{ * @return int 0-15 */ public function getBlockLightAt(int $x, int $y, int $z) : int{ + if(!$this->isInWorld($x, $y, $z)){ + return 0; + } if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ - return $chunk->getSubChunk($y >> 4)->getBlockLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); + return $chunk->getSubChunkChecked($y >> 4)->getBlockLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); } return 0; //TODO: this should probably throw instead (light not calculated yet) } From e09d78238f27b40efb71ce64d15bdb3f9f349f0d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 23:10:31 +0000 Subject: [PATCH 2013/3224] Removed EmptySubChunk and SubChunkInterface --- src/world/format/Chunk.php | 11 ----- src/world/format/EmptySubChunk.php | 65 -------------------------- src/world/format/SubChunk.php | 11 ++++- src/world/format/SubChunkInterface.php | 53 --------------------- 4 files changed, 10 insertions(+), 130 deletions(-) delete mode 100644 src/world/format/EmptySubChunk.php delete mode 100644 src/world/format/SubChunkInterface.php diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 7f3f061626..9ba58e829d 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -505,17 +505,6 @@ class Chunk{ $this->dirtyFlags = 0; } - /** - * Returns the subchunk at the specified subchunk Y coordinate, or an empty, unmodifiable stub if it does not exist or the coordinate is out of range. - */ - public function getSubChunk(int $y) : SubChunkInterface{ - if($y < 0 or $y >= $this->subChunks->getSize()){ - return EmptySubChunk::getInstance(); //TODO: drop this and throw an exception here - } - - return $this->subChunks[$y]; - } - public function getSubChunkChecked(int $y) : SubChunk{ if($y < 0 || $y >= $this->subChunks->getSize()){ throw new \InvalidArgumentException("Invalid subchunk Y coordinate $y"); diff --git a/src/world/format/EmptySubChunk.php b/src/world/format/EmptySubChunk.php deleted file mode 100644 index e1bac91186..0000000000 --- a/src/world/format/EmptySubChunk.php +++ /dev/null @@ -1,65 +0,0 @@ -blockLight = $blockLight ?? LightArray::fill(0); } + /** + * Returns whether this subchunk contains any non-air blocks. + * This function will do a slow check, usually by garbage collecting first. + * This is typically useful for disk saving. + */ public function isEmptyAuthoritative() : bool{ $this->collectGarbage(); return $this->isEmptyFast(); } + /** + * Returns a non-authoritative bool to indicate whether the chunk contains any blocks. + * This may report non-empty erroneously if the chunk has been modified and not garbage-collected. + */ public function isEmptyFast() : bool{ return count($this->blockLayers) === 0; } diff --git a/src/world/format/SubChunkInterface.php b/src/world/format/SubChunkInterface.php deleted file mode 100644 index 25f4cce287..0000000000 --- a/src/world/format/SubChunkInterface.php +++ /dev/null @@ -1,53 +0,0 @@ - Date: Sat, 31 Oct 2020 23:12:03 +0000 Subject: [PATCH 2014/3224] Rename Chunk::getSubChunkChecked() -> getSubChunk() --- src/network/mcpe/serializer/ChunkSerializer.php | 4 ++-- src/world/World.php | 4 ++-- src/world/format/Chunk.php | 12 ++++++------ src/world/generator/Flat.php | 2 +- src/world/light/LightPopulationTask.php | 4 ++-- src/world/light/SkyLightUpdate.php | 4 ++-- src/world/utils/SubChunkExplorer.php | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index b661a20ea4..abf0e1b25c 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -43,7 +43,7 @@ final class ChunkSerializer{ */ public static function getSubChunkCount(Chunk $chunk) : int{ for($count = $chunk->getSubChunks()->count(); $count > 0; --$count){ - if($chunk->getSubChunkChecked($count - 1)->isEmptyFast()){ + if($chunk->getSubChunk($count - 1)->isEmptyFast()){ continue; } return $count; @@ -56,7 +56,7 @@ final class ChunkSerializer{ $stream = new PacketSerializer(); $subChunkCount = self::getSubChunkCount($chunk); for($y = 0; $y < $subChunkCount; ++$y){ - $layers = $chunk->getSubChunkChecked($y)->getBlockLayers(); + $layers = $chunk->getSubChunk($y)->getBlockLayers(); $stream->putByte(8); //version $stream->putByte(count($layers)); diff --git a/src/world/World.php b/src/world/World.php index ba7a4d8239..a3a05d98e4 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1838,7 +1838,7 @@ class World implements ChunkManager{ return $y >= self::Y_MAX ? 15 : 0; } if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ - return $chunk->getSubChunkChecked($y >> 4)->getBlockSkyLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); + return $chunk->getSubChunk($y >> 4)->getBlockSkyLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); } return 0; //TODO: this should probably throw instead (light not calculated yet) } @@ -1853,7 +1853,7 @@ class World implements ChunkManager{ return 0; } if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ - return $chunk->getSubChunkChecked($y >> 4)->getBlockLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); + return $chunk->getSubChunk($y >> 4)->getBlockLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); } return 0; //TODO: this should probably throw instead (light not calculated yet) } diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 9ba58e829d..c6d0fd6680 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -145,14 +145,14 @@ class Chunk{ * @return int bitmap, (id << 4) | meta */ public function getFullBlock(int $x, int $y, int $z) : int{ - return $this->getSubChunkChecked($y >> 4)->getFullBlock($x, $y & 0x0f, $z); + return $this->getSubChunk($y >> 4)->getFullBlock($x, $y & 0x0f, $z); } /** * Sets the blockstate at the given coordinate by internal ID. */ public function setFullBlock(int $x, int $y, int $z, int $block) : void{ - $this->getSubChunkChecked($y >> 4)->setFullBlock($x, $y & 0xf, $z, $block); + $this->getSubChunk($y >> 4)->setFullBlock($x, $y & 0xf, $z, $block); $this->dirtyFlags |= self::DIRTY_FLAG_TERRAIN; } @@ -166,7 +166,7 @@ class Chunk{ */ public function getHighestBlockAt(int $x, int $z) : int{ for($y = $this->subChunks->count() - 1; $y >= 0; --$y){ - $height = $this->getSubChunkChecked($y)->getHighestBlockAt($x, $z) | ($y << 4); + $height = $this->getSubChunk($y)->getHighestBlockAt($x, $z) | ($y << 4); if($height !== -1){ return $height; } @@ -204,7 +204,7 @@ class Chunk{ public function recalculateHeightMap(\SplFixedArray $directSkyLightBlockers) : void{ $maxSubChunkY = $this->subChunks->count() - 1; for(; $maxSubChunkY >= 0; $maxSubChunkY--){ - if(!$this->getSubChunkChecked($maxSubChunkY)->isEmptyFast()){ + if(!$this->getSubChunk($maxSubChunkY)->isEmptyFast()){ break; } } @@ -217,7 +217,7 @@ class Chunk{ for($x = 0; $x < 16; ++$x){ $y = null; for($subChunkY = $maxSubChunkY; $subChunkY >= 0; $subChunkY--){ - $subHighestBlockY = $this->getSubChunkChecked($subChunkY)->getHighestBlockAt($x, $z); + $subHighestBlockY = $this->getSubChunk($subChunkY)->getHighestBlockAt($x, $z); if($subHighestBlockY !== -1){ $y = ($subChunkY * 16) + $subHighestBlockY; break; @@ -505,7 +505,7 @@ class Chunk{ $this->dirtyFlags = 0; } - public function getSubChunkChecked(int $y) : SubChunk{ + public function getSubChunk(int $y) : SubChunk{ if($y < 0 || $y >= $this->subChunks->getSize()){ throw new \InvalidArgumentException("Invalid subchunk Y coordinate $y"); } diff --git a/src/world/generator/Flat.php b/src/world/generator/Flat.php index 62dcf65908..5715ffb660 100644 --- a/src/world/generator/Flat.php +++ b/src/world/generator/Flat.php @@ -156,7 +156,7 @@ class Flat extends Generator{ $count = count($this->structure); for($sy = 0; $sy < $count; $sy += 16){ - $subchunk = $this->chunk->getSubChunkChecked($sy >> 4); + $subchunk = $this->chunk->getSubChunk($sy >> 4); for($y = 0; $y < 16 and isset($this->structure[$y | $sy]); ++$y){ $id = $this->structure[$y | $sy]; diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index b171d06e9d..80f814cefd 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -104,10 +104,10 @@ class LightPopulationTask extends AsyncTask{ $blockLightArrays = igbinary_unserialize($this->resultBlockLightArrays); foreach($skyLightArrays as $y => $array){ - $chunk->getSubChunkChecked($y)->setBlockSkyLightArray($array); + $chunk->getSubChunk($y)->setBlockSkyLightArray($array); } foreach($blockLightArrays as $y => $array){ - $chunk->getSubChunkChecked($y)->setBlockLightArray($array); + $chunk->getSubChunk($y)->setBlockLightArray($array); } $chunk->setLightPopulated(); } diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index d6bbdca5f8..d733ce4bb4 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -111,10 +111,10 @@ class SkyLightUpdate extends LightUpdate{ $lowestClearSubChunk = ($highestHeightMapPlusOne >> 4) + (($highestHeightMapPlusOne & 0xf) !== 0 ? 1 : 0); $chunkHeight = $chunk->getSubChunks()->count(); for($y = 0; $y < $lowestClearSubChunk && $y < $chunkHeight; $y++){ - $chunk->getSubChunkChecked($y)->setBlockSkyLightArray(LightArray::fill(0)); + $chunk->getSubChunk($y)->setBlockSkyLightArray(LightArray::fill(0)); } for($y = $lowestClearSubChunk, $yMax = $chunkHeight; $y < $yMax; $y++){ - $chunk->getSubChunkChecked($y)->setBlockSkyLightArray(LightArray::fill(15)); + $chunk->getSubChunk($y)->setBlockSkyLightArray(LightArray::fill(15)); } $lightSources = 0; diff --git a/src/world/utils/SubChunkExplorer.php b/src/world/utils/SubChunkExplorer.php index 69ce4d6cb4..44d2c20f64 100644 --- a/src/world/utils/SubChunkExplorer.php +++ b/src/world/utils/SubChunkExplorer.php @@ -77,7 +77,7 @@ class SubChunkExplorer{ return SubChunkExplorerStatus::INVALID; } - $this->currentSubChunk = $this->currentChunk->getSubChunkChecked($y >> 4); + $this->currentSubChunk = $this->currentChunk->getSubChunk($y >> 4); if($this->onSubChunkChangeFunc !== null){ ($this->onSubChunkChangeFunc)(); } From 05470d062185417c76853cb5c41679152a5fab60 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 23:17:03 +0000 Subject: [PATCH 2015/3224] phpstan: regenerate level 8 baseline (again) --- tests/phpstan/configs/l8-baseline.neon | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index f62f06b1dd..5c9b44a513 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -566,12 +566,7 @@ parameters: path: ../../../src/world/format/Chunk.php - - message: "#^Method pocketmine\\\\world\\\\format\\\\Chunk\\:\\:getSubChunk\\(\\) should return pocketmine\\\\world\\\\format\\\\SubChunkInterface but returns pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" - count: 1 - path: ../../../src/world/format/Chunk.php - - - - message: "#^Method pocketmine\\\\world\\\\format\\\\Chunk\\:\\:getSubChunkChecked\\(\\) should return pocketmine\\\\world\\\\format\\\\SubChunk but returns pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" + message: "#^Method pocketmine\\\\world\\\\format\\\\Chunk\\:\\:getSubChunk\\(\\) should return pocketmine\\\\world\\\\format\\\\SubChunk but returns pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" count: 1 path: ../../../src/world/format/Chunk.php @@ -796,7 +791,7 @@ parameters: path: ../../../src/world/light/SkyLightUpdate.php - - message: "#^Cannot call method getSubChunkChecked\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + message: "#^Cannot call method getSubChunk\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" count: 2 path: ../../../src/world/light/SkyLightUpdate.php From 59a3e8c0962d562740b300ecab6a20f2b169b017 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 23:22:42 +0000 Subject: [PATCH 2016/3224] BiomeArray: added ::fill() --- src/world/format/BiomeArray.php | 5 +++++ src/world/format/Chunk.php | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/world/format/BiomeArray.php b/src/world/format/BiomeArray.php index ca91fbea05..30a5d2cb0f 100644 --- a/src/world/format/BiomeArray.php +++ b/src/world/format/BiomeArray.php @@ -25,6 +25,7 @@ namespace pocketmine\world\format; use function chr; use function ord; +use function str_repeat; use function strlen; final class BiomeArray{ @@ -42,6 +43,10 @@ final class BiomeArray{ $this->payload = $payload; } + public static function fill(int $biomeId) : self{ + return new BiomeArray(str_repeat(chr($biomeId), 256)); + } + private static function idx(int $x, int $z) : int{ if($x < 0 or $x >= 16 or $z < 0 or $z >= 16){ throw new \InvalidArgumentException("x and z must be in the range 0-15"); diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index c6d0fd6680..2863258078 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -35,12 +35,12 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\StringTag; use pocketmine\player\Player; +use pocketmine\world\biome\Biome; use pocketmine\world\World; use function array_fill; use function array_filter; use function array_map; use function count; -use function str_repeat; class Chunk{ public const DIRTY_FLAG_TERRAIN = 1 << 0; @@ -106,7 +106,7 @@ class Chunk{ $val = ($this->subChunks->getSize() * 16); $this->heightMap = $heightMap ?? new HeightArray(array_fill(0, 256, $val)); - $this->biomeIds = $biomeIds ?? new BiomeArray(str_repeat("\x00", 256)); + $this->biomeIds = $biomeIds ?? BiomeArray::fill(Biome::OCEAN); $this->NBTtiles = $tiles; $this->NBTentities = $entities; From c39a1407a2e4ea5a8855e2cdabea5845a56a3163 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 23:34:04 +0000 Subject: [PATCH 2017/3224] Move heightmap calculation logic to SkyLightUpdate --- src/world/format/Chunk.php | 65 ----------------------- src/world/light/SkyLightUpdate.php | 71 +++++++++++++++++++++++++- tests/phpstan/configs/l8-baseline.neon | 11 ++-- 3 files changed, 72 insertions(+), 75 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 2863258078..de5b215776 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -195,71 +195,6 @@ class Chunk{ $this->heightMap->set($x, $z, $value); } - /** - * Recalculates the heightmap for the whole chunk. - * - * @param \SplFixedArray|bool[] $directSkyLightBlockers - * @phpstan-param \SplFixedArray $directSkyLightBlockers - */ - public function recalculateHeightMap(\SplFixedArray $directSkyLightBlockers) : void{ - $maxSubChunkY = $this->subChunks->count() - 1; - for(; $maxSubChunkY >= 0; $maxSubChunkY--){ - if(!$this->getSubChunk($maxSubChunkY)->isEmptyFast()){ - break; - } - } - if($maxSubChunkY === -1){ //whole column is definitely empty - $this->setHeightMapArray(array_fill(0, 256, 0)); - return; - } - - for($z = 0; $z < 16; ++$z){ - for($x = 0; $x < 16; ++$x){ - $y = null; - for($subChunkY = $maxSubChunkY; $subChunkY >= 0; $subChunkY--){ - $subHighestBlockY = $this->getSubChunk($subChunkY)->getHighestBlockAt($x, $z); - if($subHighestBlockY !== -1){ - $y = ($subChunkY * 16) + $subHighestBlockY; - break; - } - } - - if($y === null){ //no blocks in the column - $this->setHeightMap($x, $z, 0); - }else{ - for(; $y >= 0; --$y){ - if($directSkyLightBlockers[$this->getFullBlock($x, $y, $z)]){ - $this->setHeightMap($x, $z, $y + 1); - break; - } - } - } - } - } - } - - /** - * Recalculates the heightmap for the block column at the specified X/Z chunk coordinates - * - * @param int $x 0-15 - * @param int $z 0-15 - * @param \SplFixedArray|bool[] $directSkyLightBlockers - * @phpstan-param \SplFixedArray $directSkyLightBlockers - * - * @return int New calculated heightmap value (0-256 inclusive) - */ - public function recalculateHeightMapColumn(int $x, int $z, \SplFixedArray $directSkyLightBlockers) : int{ - $y = $this->getHighestBlockAt($x, $z); - for(; $y >= 0; --$y){ - if($directSkyLightBlockers[$this->getFullBlock($x, $y, $z)]){ - break; - } - } - - $this->setHeightMap($x, $z, $y + 1); - return $y + 1; - } - /** * Returns the biome ID at the specified X/Z chunk block coordinates * diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index d733ce4bb4..5c8153dc1f 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -23,10 +23,12 @@ declare(strict_types=1); namespace pocketmine\world\light; +use pocketmine\world\format\Chunk; use pocketmine\world\format\LightArray; use pocketmine\world\utils\SubChunkExplorer; use pocketmine\world\utils\SubChunkExplorerStatus; use pocketmine\world\World; +use function array_fill; use function max; class SkyLightUpdate extends LightUpdate{ @@ -72,7 +74,7 @@ class SkyLightUpdate extends LightUpdate{ $yPlusOne = $y + 1; if($yPlusOne === $oldHeightMap){ //Block changed directly beneath the heightmap. Check if a block was removed or changed to a different light-filter. - $newHeightMap = $chunk->recalculateHeightMapColumn($x & 0x0f, $z & 0x0f, $this->directSkyLightBlockers); + $newHeightMap = self::recalculateHeightMapColumn($chunk, $x & 0x0f, $z & 0x0f, $this->directSkyLightBlockers); }elseif($yPlusOne > $oldHeightMap){ //Block changed above the heightmap. if($this->directSkyLightBlockers[$source]){ $chunk->setHeightMap($x & 0xf, $z & 0xf, $yPlusOne); @@ -103,7 +105,7 @@ class SkyLightUpdate extends LightUpdate{ } $chunk = $this->subChunkExplorer->currentChunk; - $chunk->recalculateHeightMap($this->directSkyLightBlockers); + self::recalculateHeightMap($chunk, $this->directSkyLightBlockers); //setAndUpdateLight() won't bother propagating from nodes that are already what we want to change them to, so we //have to avoid filling full light for any subchunk that contains a heightmap Y coordinate @@ -160,4 +162,69 @@ class SkyLightUpdate extends LightUpdate{ return $lightSources; } + + /** + * Recalculates the heightmap for the whole chunk. + * + * @param \SplFixedArray|bool[] $directSkyLightBlockers + * @phpstan-param \SplFixedArray $directSkyLightBlockers + */ + private static function recalculateHeightMap(Chunk $chunk, \SplFixedArray $directSkyLightBlockers) : void{ + $maxSubChunkY = $chunk->getSubChunks()->count() - 1; + for(; $maxSubChunkY >= 0; $maxSubChunkY--){ + if(!$chunk->getSubChunk($maxSubChunkY)->isEmptyFast()){ + break; + } + } + if($maxSubChunkY === -1){ //whole column is definitely empty + $chunk->setHeightMapArray(array_fill(0, 256, 0)); + return; + } + + for($z = 0; $z < 16; ++$z){ + for($x = 0; $x < 16; ++$x){ + $y = null; + for($subChunkY = $maxSubChunkY; $subChunkY >= 0; $subChunkY--){ + $subHighestBlockY = $chunk->getSubChunk($subChunkY)->getHighestBlockAt($x, $z); + if($subHighestBlockY !== -1){ + $y = ($subChunkY * 16) + $subHighestBlockY; + break; + } + } + + if($y === null){ //no blocks in the column + $chunk->setHeightMap($x, $z, 0); + }else{ + for(; $y >= 0; --$y){ + if($directSkyLightBlockers[$chunk->getFullBlock($x, $y, $z)]){ + $chunk->setHeightMap($x, $z, $y + 1); + break; + } + } + } + } + } + } + + /** + * Recalculates the heightmap for the block column at the specified X/Z chunk coordinates + * + * @param int $x 0-15 + * @param int $z 0-15 + * @param \SplFixedArray|bool[] $directSkyLightBlockers + * @phpstan-param \SplFixedArray $directSkyLightBlockers + * + * @return int New calculated heightmap value (0-256 inclusive) + */ + private static function recalculateHeightMapColumn(Chunk $chunk, int $x, int $z, \SplFixedArray $directSkyLightBlockers) : int{ + $y = $chunk->getHighestBlockAt($x, $z); + for(; $y >= 0; --$y){ + if($directSkyLightBlockers[$chunk->getFullBlock($x, $y, $z)]){ + break; + } + } + + $chunk->setHeightMap($x, $z, $y + 1); + return $y + 1; + } } diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 5c9b44a513..8059b88b45 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -560,11 +560,6 @@ parameters: count: 1 path: ../../../src/world/biome/BiomeRegistry.php - - - message: "#^Only booleans are allowed in an if condition, bool\\|null given\\.$#" - count: 2 - path: ../../../src/world/format/Chunk.php - - message: "#^Method pocketmine\\\\world\\\\format\\\\Chunk\\:\\:getSubChunk\\(\\) should return pocketmine\\\\world\\\\format\\\\SubChunk but returns pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" count: 1 @@ -751,13 +746,13 @@ parameters: path: ../../../src/world/light/SkyLightUpdate.php - - message: "#^Cannot call method recalculateHeightMapColumn\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + message: "#^Parameter \\#1 \\$chunk of static method pocketmine\\\\world\\\\light\\\\SkyLightUpdate\\:\\:recalculateHeightMapColumn\\(\\) expects pocketmine\\\\world\\\\format\\\\Chunk, pocketmine\\\\world\\\\format\\\\Chunk\\|null given\\.$#" count: 1 path: ../../../src/world/light/SkyLightUpdate.php - message: "#^Only booleans are allowed in an if condition, bool\\|null given\\.$#" - count: 1 + count: 3 path: ../../../src/world/light/SkyLightUpdate.php - @@ -771,7 +766,7 @@ parameters: path: ../../../src/world/light/SkyLightUpdate.php - - message: "#^Cannot call method recalculateHeightMap\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + message: "#^Parameter \\#1 \\$chunk of static method pocketmine\\\\world\\\\light\\\\SkyLightUpdate\\:\\:recalculateHeightMap\\(\\) expects pocketmine\\\\world\\\\format\\\\Chunk, pocketmine\\\\world\\\\format\\\\Chunk\\|null given\\.$#" count: 1 path: ../../../src/world/light/SkyLightUpdate.php From 817372c55b612d01eff34d39fb5286988ea19d77 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 23:42:32 +0000 Subject: [PATCH 2018/3224] SkyLightUpdate: make heightmap calculation routines pure --- src/world/format/HeightArray.php | 5 +++++ src/world/light/SkyLightUpdate.php | 18 ++++++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/world/format/HeightArray.php b/src/world/format/HeightArray.php index 3025d6f620..54c8e19f33 100644 --- a/src/world/format/HeightArray.php +++ b/src/world/format/HeightArray.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\format; +use function array_fill; use function count; final class HeightArray{ @@ -44,6 +45,10 @@ final class HeightArray{ $this->array = \SplFixedArray::fromArray($values); } + public static function fill(int $value) : self{ + return new self(array_fill(0, 256, $value)); + } + private static function idx(int $x, int $z) : int{ if($x < 0 or $x >= 16 or $z < 0 or $z >= 16){ throw new \InvalidArgumentException("x and z must be in the range 0-15"); diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index 5c8153dc1f..7ca2c1274d 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -24,11 +24,11 @@ declare(strict_types=1); namespace pocketmine\world\light; use pocketmine\world\format\Chunk; +use pocketmine\world\format\HeightArray; use pocketmine\world\format\LightArray; use pocketmine\world\utils\SubChunkExplorer; use pocketmine\world\utils\SubChunkExplorerStatus; use pocketmine\world\World; -use function array_fill; use function max; class SkyLightUpdate extends LightUpdate{ @@ -75,6 +75,7 @@ class SkyLightUpdate extends LightUpdate{ if($yPlusOne === $oldHeightMap){ //Block changed directly beneath the heightmap. Check if a block was removed or changed to a different light-filter. $newHeightMap = self::recalculateHeightMapColumn($chunk, $x & 0x0f, $z & 0x0f, $this->directSkyLightBlockers); + $chunk->setHeightMap($x & 0xf, $z & 0xf, $newHeightMap); }elseif($yPlusOne > $oldHeightMap){ //Block changed above the heightmap. if($this->directSkyLightBlockers[$source]){ $chunk->setHeightMap($x & 0xf, $z & 0xf, $yPlusOne); @@ -105,7 +106,8 @@ class SkyLightUpdate extends LightUpdate{ } $chunk = $this->subChunkExplorer->currentChunk; - self::recalculateHeightMap($chunk, $this->directSkyLightBlockers); + $newHeightMap = self::recalculateHeightMap($chunk, $this->directSkyLightBlockers); + $chunk->setHeightMapArray($newHeightMap->getValues()); //setAndUpdateLight() won't bother propagating from nodes that are already what we want to change them to, so we //have to avoid filling full light for any subchunk that contains a heightmap Y coordinate @@ -169,16 +171,16 @@ class SkyLightUpdate extends LightUpdate{ * @param \SplFixedArray|bool[] $directSkyLightBlockers * @phpstan-param \SplFixedArray $directSkyLightBlockers */ - private static function recalculateHeightMap(Chunk $chunk, \SplFixedArray $directSkyLightBlockers) : void{ + private static function recalculateHeightMap(Chunk $chunk, \SplFixedArray $directSkyLightBlockers) : HeightArray{ $maxSubChunkY = $chunk->getSubChunks()->count() - 1; for(; $maxSubChunkY >= 0; $maxSubChunkY--){ if(!$chunk->getSubChunk($maxSubChunkY)->isEmptyFast()){ break; } } + $result = HeightArray::fill(0); if($maxSubChunkY === -1){ //whole column is definitely empty - $chunk->setHeightMapArray(array_fill(0, 256, 0)); - return; + return $result; } for($z = 0; $z < 16; ++$z){ @@ -193,17 +195,18 @@ class SkyLightUpdate extends LightUpdate{ } if($y === null){ //no blocks in the column - $chunk->setHeightMap($x, $z, 0); + $result->set($x, $z, 0); }else{ for(; $y >= 0; --$y){ if($directSkyLightBlockers[$chunk->getFullBlock($x, $y, $z)]){ - $chunk->setHeightMap($x, $z, $y + 1); + $result->set($x, $z, $y + 1); break; } } } } } + return $result; } /** @@ -224,7 +227,6 @@ class SkyLightUpdate extends LightUpdate{ } } - $chunk->setHeightMap($x, $z, $y + 1); return $y + 1; } } From c1a451f3b1a671206ecc1edfb87f73612ca3a540 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 31 Oct 2020 23:46:27 +0000 Subject: [PATCH 2019/3224] SubChunkExplorer: ditch subChunkChangeFunc this is better implemented by checking the moveTo() result, which also won't have circular dependencies. --- src/world/utils/SubChunkExplorer.php | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/world/utils/SubChunkExplorer.php b/src/world/utils/SubChunkExplorer.php index 44d2c20f64..80fb4b3846 100644 --- a/src/world/utils/SubChunkExplorer.php +++ b/src/world/utils/SubChunkExplorer.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\world\utils; -use pocketmine\utils\Utils; use pocketmine\world\ChunkManager; use pocketmine\world\format\Chunk; use pocketmine\world\format\SubChunk; @@ -44,12 +43,6 @@ class SubChunkExplorer{ /** @var int */ protected $currentZ; - /** - * @var \Closure|null - * @phpstan-var (\Closure() : void)|null - */ - private $onSubChunkChangeFunc = null; - public function __construct(ChunkManager $world){ $this->world = $world; } @@ -78,9 +71,6 @@ class SubChunkExplorer{ } $this->currentSubChunk = $this->currentChunk->getSubChunk($y >> 4); - if($this->onSubChunkChangeFunc !== null){ - ($this->onSubChunkChangeFunc)(); - } return SubChunkExplorerStatus::MOVED; } @@ -95,14 +85,6 @@ class SubChunkExplorer{ return $this->moveTo($chunkX << 4, $chunkY << 4, $chunkZ << 4); } - /** - * @phpstan-param \Closure() : void $callback - */ - public function onSubChunkChange(\Closure $callback) : void{ - Utils::validateCallableSignature(function() : void{}, $callback); - $this->onSubChunkChangeFunc = $callback; - } - /** * Returns whether we currently have a valid terrain pointer. */ From c312c8ddd6e23161156dae1476a171269f58b8dc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 1 Nov 2020 00:11:41 +0000 Subject: [PATCH 2020/3224] fix build --- tests/phpstan/configs/l8-baseline.neon | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 8059b88b45..47ebfdf528 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -751,13 +751,13 @@ parameters: path: ../../../src/world/light/SkyLightUpdate.php - - message: "#^Only booleans are allowed in an if condition, bool\\|null given\\.$#" - count: 3 + message: "#^Cannot call method setHeightMap\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 2 path: ../../../src/world/light/SkyLightUpdate.php - - message: "#^Cannot call method setHeightMap\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 1 + message: "#^Only booleans are allowed in an if condition, bool\\|null given\\.$#" + count: 3 path: ../../../src/world/light/SkyLightUpdate.php - @@ -770,6 +770,11 @@ parameters: count: 1 path: ../../../src/world/light/SkyLightUpdate.php + - + message: "#^Cannot call method setHeightMapArray\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 1 + path: ../../../src/world/light/SkyLightUpdate.php + - message: "#^Cannot call method getHeightMapArray\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" count: 1 From d6d9dde0b2c3d3295e4f88cdee9762c368b6fc83 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 1 Nov 2020 14:23:21 +0000 Subject: [PATCH 2021/3224] imports cleanup --- src/CrashDump.php | 2 +- src/world/World.php | 1 - tests/phpunit/block/BrewingStandTest.php | 1 + tests/phpunit/plugin/ApiVersionTest.php | 1 + tests/phpunit/utils/CloningRegistryTraitTest.php | 1 - 5 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/CrashDump.php b/src/CrashDump.php index 0c3de647a1..5d813eb0e1 100644 --- a/src/CrashDump.php +++ b/src/CrashDump.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine; -use pocketmine\errorhandler\ErrorTypeToStringMap; use Composer\InstalledVersions; +use pocketmine\errorhandler\ErrorTypeToStringMap; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\plugin\PluginBase; use pocketmine\plugin\PluginManager; diff --git a/src/world/World.php b/src/world/World.php index a3a05d98e4..eb5a6e39ec 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -91,7 +91,6 @@ use function floor; use function get_class; use function gettype; use function is_a; -use function is_array; use function is_object; use function lcg_value; use function max; diff --git a/tests/phpunit/block/BrewingStandTest.php b/tests/phpunit/block/BrewingStandTest.php index 62eb497d80..092a34ead0 100644 --- a/tests/phpunit/block/BrewingStandTest.php +++ b/tests/phpunit/block/BrewingStandTest.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use PHPUnit\Framework\TestCase; use pocketmine\block\utils\BrewingStandSlot; +use function count; class BrewingStandTest extends TestCase{ diff --git a/tests/phpunit/plugin/ApiVersionTest.php b/tests/phpunit/plugin/ApiVersionTest.php index c6d8d37431..ecc3a8a2bf 100644 --- a/tests/phpunit/plugin/ApiVersionTest.php +++ b/tests/phpunit/plugin/ApiVersionTest.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\plugin; use PHPUnit\Framework\TestCase; +use function sort; class ApiVersionTest extends TestCase{ diff --git a/tests/phpunit/utils/CloningRegistryTraitTest.php b/tests/phpunit/utils/CloningRegistryTraitTest.php index 8151481a35..69ca0a4110 100644 --- a/tests/phpunit/utils/CloningRegistryTraitTest.php +++ b/tests/phpunit/utils/CloningRegistryTraitTest.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\utils; use PHPUnit\Framework\TestCase; -use pocketmine\block\VanillaBlocks; final class CloningRegistryTraitTest extends TestCase{ From be1da07ee53e72e818a5c2af594d64469968290e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 1 Nov 2020 14:23:44 +0000 Subject: [PATCH 2022/3224] tests: phpdoc cleanup --- tests/phpunit/block/BrewingStandTest.php | 1 - tests/phpunit/event/HandlerListManagerTest.php | 5 ----- tests/phpunit/item/LegacyStringToItemParserTest.php | 3 --- tests/phpunit/plugin/ApiVersionTest.php | 4 ---- 4 files changed, 13 deletions(-) diff --git a/tests/phpunit/block/BrewingStandTest.php b/tests/phpunit/block/BrewingStandTest.php index 092a34ead0..9f4a8d5e3d 100644 --- a/tests/phpunit/block/BrewingStandTest.php +++ b/tests/phpunit/block/BrewingStandTest.php @@ -39,7 +39,6 @@ class BrewingStandTest extends TestCase{ } /** - * * @dataProvider slotsProvider * * @param BrewingStandSlot[] $slots diff --git a/tests/phpunit/event/HandlerListManagerTest.php b/tests/phpunit/event/HandlerListManagerTest.php index 01de9ff84c..fd827c6983 100644 --- a/tests/phpunit/event/HandlerListManagerTest.php +++ b/tests/phpunit/event/HandlerListManagerTest.php @@ -54,9 +54,6 @@ class HandlerListManagerTest extends TestCase{ /** * @dataProvider isValidClassProvider * - * @param \ReflectionClass $class - * @param bool $isValid - * @param string $reason * @phpstan-param \ReflectionClass $class */ public function testIsValidClass(\ReflectionClass $class, bool $isValid, string $reason) : void{ @@ -77,8 +74,6 @@ class HandlerListManagerTest extends TestCase{ /** * @dataProvider resolveParentClassProvider * - * @param \ReflectionClass $class - * @param \ReflectionClass|null $expect * @phpstan-param \ReflectionClass $class * @phpstan-param \ReflectionClass|null $expect */ diff --git a/tests/phpunit/item/LegacyStringToItemParserTest.php b/tests/phpunit/item/LegacyStringToItemParserTest.php index 56e3565528..546a383bfd 100644 --- a/tests/phpunit/item/LegacyStringToItemParserTest.php +++ b/tests/phpunit/item/LegacyStringToItemParserTest.php @@ -45,9 +45,6 @@ class LegacyStringToItemParserTest extends TestCase{ /** * @dataProvider itemFromStringProvider - * @param string $string - * @param int $id - * @param int $meta */ public function testFromStringSingle(string $string, int $id, int $meta) : void{ $item = LegacyStringToItemParser::getInstance()->parse($string); diff --git a/tests/phpunit/plugin/ApiVersionTest.php b/tests/phpunit/plugin/ApiVersionTest.php index ecc3a8a2bf..4d348ee0db 100644 --- a/tests/phpunit/plugin/ApiVersionTest.php +++ b/tests/phpunit/plugin/ApiVersionTest.php @@ -49,10 +49,6 @@ class ApiVersionTest extends TestCase{ /** * @dataProvider compatibleApiProvider - * - * @param string $myVersion - * @param string $wantVersion - * @param bool $expected */ public function testCompatibleApi(string $myVersion, string $wantVersion, bool $expected) : void{ self::assertSame($expected, ApiVersion::isCompatible($myVersion, [$wantVersion]), "my version: $myVersion, their version: $wantVersion, expect " . ($expected ? "yes" : "no")); From 19bc879dc12acdccd4005a2c41368d1124ad15c0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 1 Nov 2020 14:24:02 +0000 Subject: [PATCH 2023/3224] lose useless blank line --- tests/phpunit/event/HandlerListManagerTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/phpunit/event/HandlerListManagerTest.php b/tests/phpunit/event/HandlerListManagerTest.php index fd827c6983..1eacf423fa 100644 --- a/tests/phpunit/event/HandlerListManagerTest.php +++ b/tests/phpunit/event/HandlerListManagerTest.php @@ -32,7 +32,6 @@ class HandlerListManagerTest extends TestCase{ /** @var \Closure */ private $resolveParentFunc; - public function setUp() : void{ /** @see HandlerListManager::isValidClass() */ $this->isValidFunc = (new \ReflectionMethod(HandlerListManager::class, 'isValidClass'))->getClosure(); From 3e21e47b7a9fd85d674d287f5c22ac1e67541fba Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 1 Nov 2020 14:39:59 +0000 Subject: [PATCH 2024/3224] Liquid: make getFlowVector() slightly less cancerous to read --- src/block/Liquid.php | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/block/Liquid.php b/src/block/Liquid.php index ac7b5a95f0..6de3e98d98 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -172,6 +172,8 @@ abstract class Liquid extends Transparent{ $decay = $this->getEffectiveFlowDecay($this); + $world = $this->pos->getWorld(); + for($j = 0; $j < 4; ++$j){ $x = $this->pos->x; @@ -188,7 +190,7 @@ abstract class Liquid extends Transparent{ ++$z; } - $sideBlock = $this->pos->getWorld()->getBlockAt($x, $y, $z); + $sideBlock = $world->getBlockAt($x, $y, $z); $blockDecay = $this->getEffectiveFlowDecay($sideBlock); if($blockDecay < 0){ @@ -196,7 +198,7 @@ abstract class Liquid extends Transparent{ continue; } - $blockDecay = $this->getEffectiveFlowDecay($this->pos->getWorld()->getBlockAt($x, $y - 1, $z)); + $blockDecay = $this->getEffectiveFlowDecay($world->getBlockAt($x, $y - 1, $z)); if($blockDecay >= 0){ $realDecay = $blockDecay - ($decay - 8); @@ -218,14 +220,14 @@ abstract class Liquid extends Transparent{ if($this->falling){ if( - !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1)) or - !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z + 1)) or - !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x - 1, $this->pos->y, $this->pos->z)) or - !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x + 1, $this->pos->y, $this->pos->z)) or - !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z - 1)) or - !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z + 1)) or - !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x - 1, $this->pos->y + 1, $this->pos->z)) or - !$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x + 1, $this->pos->y + 1, $this->pos->z)) + !$this->canFlowInto($world->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1)) or + !$this->canFlowInto($world->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z + 1)) or + !$this->canFlowInto($world->getBlockAt($this->pos->x - 1, $this->pos->y, $this->pos->z)) or + !$this->canFlowInto($world->getBlockAt($this->pos->x + 1, $this->pos->y, $this->pos->z)) or + !$this->canFlowInto($world->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z - 1)) or + !$this->canFlowInto($world->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z + 1)) or + !$this->canFlowInto($world->getBlockAt($this->pos->x - 1, $this->pos->y + 1, $this->pos->z)) or + !$this->canFlowInto($world->getBlockAt($this->pos->x + 1, $this->pos->y + 1, $this->pos->z)) ){ $vector = $vector->normalize()->add(0, -6, 0); } From 11434f3a27946b7da4fcb8bec1a746e3fda90610 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 1 Nov 2020 14:59:22 +0000 Subject: [PATCH 2025/3224] World::setBiomeId() now bails when trying to modify a non-generated chunk (or chunk locked for generation) --- src/world/World.php | 13 ++++++++++++- tests/phpstan/configs/l8-baseline.neon | 5 ----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index eb5a6e39ec..36f24273ab 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1869,7 +1869,18 @@ class World implements ChunkManager{ } public function setBiomeId(int $x, int $z, int $biomeId) : void{ - $this->getOrLoadChunk($x >> 4, $z >> 4, true)->setBiomeId($x & 0x0f, $z & 0x0f, $biomeId); + $chunkX = $x >> 4; + $chunkZ = $z >> 4; + if($this->isChunkLocked($chunkX, $chunkZ)){ + //the changes would be overwritten when the generation finishes + throw new WorldException("Chunk is currently locked for async generation/population"); + } + if(($chunk = $this->getOrLoadChunk($chunkX, $chunkZ, false)) !== null){ + $chunk->setBiomeId($x & 0x0f, $z & 0x0f, $biomeId); + }else{ + //if we allowed this, the modifications would be lost when the chunk is created + throw new WorldException("Cannot set biome in a non-generated chunk"); + } } /** diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 47ebfdf528..ccba8426ed 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -535,11 +535,6 @@ parameters: count: 3 path: ../../../src/world/World.php - - - message: "#^Cannot call method setBiomeId\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/world/World.php - - message: "#^Cannot call method isPopulated\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" count: 1 From ef542880def228cb425ba201f4d73ee372fda651 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 1 Nov 2020 15:21:15 +0000 Subject: [PATCH 2026/3224] WorldManager: allow different World instances to have different AsyncPool instances instead of being forced to use the Server async pool right now the intent of this is to reduce (and ultimately eliminate) the dependency of World on Server, but it might come in useful for other stuff too, for example a chunkserver-based generator implementation which blocks on network instead of eating CPU (it would just waste CPU for other tasks). --- src/world/World.php | 20 ++++++++++++-------- src/world/WorldManager.php | 4 ++-- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 36f24273ab..393fc8d249 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -58,6 +58,7 @@ use pocketmine\network\mcpe\protocol\BlockActorDataPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; use pocketmine\player\Player; +use pocketmine\scheduler\AsyncPool; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\Limits; @@ -271,6 +272,9 @@ class World implements ChunkManager{ /** @var \Logger */ private $logger; + /** @var AsyncPool */ + private $workerPool; + public static function chunkHash(int $x, int $z) : int{ return morton2d_encode($x, $z); } @@ -353,11 +357,12 @@ class World implements ChunkManager{ /** * Init the default world data */ - public function __construct(Server $server, string $name, WritableWorldProvider $provider){ + public function __construct(Server $server, string $name, WritableWorldProvider $provider, AsyncPool $workerPool){ $this->worldId = static::$worldIdCounter++; $this->server = $server; $this->provider = $provider; + $this->workerPool = $workerPool; $this->displayName = $this->provider->getWorldData()->getName(); $this->logger = new \PrefixedLogger($server->getLogger(), "World: $this->displayName"); @@ -400,14 +405,13 @@ class World implements ChunkManager{ public function registerGeneratorToWorker(int $worker) : void{ $this->generatorRegisteredWorkers[$worker] = true; - $this->server->getAsyncPool()->submitTaskToWorker(new GeneratorRegisterTask($this, $this->generator, $this->provider->getWorldData()->getGeneratorOptions()), $worker); + $this->workerPool->submitTaskToWorker(new GeneratorRegisterTask($this, $this->generator, $this->provider->getWorldData()->getGeneratorOptions()), $worker); } public function unregisterGenerator() : void{ - $pool = $this->server->getAsyncPool(); - foreach($pool->getRunningWorkers() as $i){ + foreach($this->workerPool->getRunningWorkers() as $i){ if(isset($this->generatorRegisteredWorkers[$i])){ - $pool->submitTaskToWorker(new GeneratorUnregisterTask($this), $i); + $this->workerPool->submitTaskToWorker(new GeneratorUnregisterTask($this), $i); } } $this->generatorRegisteredWorkers = []; @@ -931,7 +935,7 @@ class World implements ChunkManager{ if($lightPopulatedState !== true){ if($lightPopulatedState === false){ $this->chunks[$hash]->setLightPopulated(null); - $this->server->getAsyncPool()->submitTask(new LightPopulationTask($this, $this->chunks[$hash])); + $this->workerPool->submitTask(new LightPopulationTask($this, $this->chunks[$hash])); } continue; } @@ -2452,11 +2456,11 @@ class World implements ChunkManager{ } $task = new PopulationTask($this, $chunk); - $workerId = $this->server->getAsyncPool()->selectWorker(); + $workerId = $this->workerPool->selectWorker(); if(!isset($this->generatorRegisteredWorkers[$workerId])){ $this->registerGeneratorToWorker($workerId); } - $this->server->getAsyncPool()->submitTaskToWorker($task, $workerId); + $this->workerPool->submitTaskToWorker($task, $workerId); Timings::$populationTimer->stopTiming(); return false; diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index dbf1e6c7ba..dc597b84f6 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -230,7 +230,7 @@ class WorldManager{ $this->server->getLogger()->notice("Upgraded world \"$name\" to new format successfully. Backed up pre-conversion world at " . $converter->getBackupPath()); } - $world = new World($this->server, $name, $provider); + $world = new World($this->server, $name, $provider, $this->server->getAsyncPool()); $this->worlds[$world->getId()] = $world; $world->setAutoSave($this->autoSave); @@ -266,7 +266,7 @@ class WorldManager{ $providerClass::generate($path, $name, $seed, $generator, $options); /** @see WritableWorldProvider::__construct() */ - $world = new World($this->server, $name, new $providerClass($path)); + $world = new World($this->server, $name, new $providerClass($path), $this->server->getAsyncPool()); $this->worlds[$world->getId()] = $world; $world->setAutoSave($this->autoSave); From 2684ee96f7d7c4850c0acbc28e149006a22b33a7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 1 Nov 2020 15:53:50 +0000 Subject: [PATCH 2027/3224] World: do not perform base lighting calculation on non-generated chunks this was causing twice as many light calculations for freshly generated chunks. --- src/world/World.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index 393fc8d249..934ca83cab 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -930,6 +930,13 @@ class World implements ChunkManager{ $dz = mt_rand(-$randRange, $randRange); $hash = World::chunkHash($dx + $chunkX, $dz + $chunkZ); if(!isset($chunkTickList[$hash]) and isset($this->chunks[$hash])){ + if( + !$this->chunks[$hash]->isGenerated() || + !$this->chunks[$hash]->isPopulated() || + $this->isChunkLocked($dx + $chunkX, $dz + $chunkZ) + ){ + continue; + } //TODO: this might need to be checked after adjacent chunks are loaded in future $lightPopulatedState = $this->chunks[$hash]->isLightPopulated(); if($lightPopulatedState !== true){ From 315962c12c5c1b0fbf4008c85ffefe4ae8ac4d9e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 1 Nov 2020 16:14:25 +0000 Subject: [PATCH 2028/3224] Added __clone() for Chunk and SubChunk we need this because the flatworld generator uses clone to produce new chunks, so we don't want the chunks getting fucked up. --- src/world/format/Chunk.php | 9 ++++ src/world/format/SubChunk.php | 10 +++++ tests/phpunit/world/format/ChunkTest.php | 45 +++++++++++++++++++ tests/phpunit/world/format/SubChunkTest.php | 50 +++++++++++++++++++++ 4 files changed, 114 insertions(+) create mode 100644 tests/phpunit/world/format/ChunkTest.php create mode 100644 tests/phpunit/world/format/SubChunkTest.php diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index de5b215776..833e31902a 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -476,6 +476,15 @@ class Chunk{ } } + public function __clone(){ + //we don't bother cloning entities or tiles since it's impractical to do so (too many dependencies) + $this->subChunks = \SplFixedArray::fromArray(array_map(function(SubChunk $subChunk) : SubChunk{ + return clone $subChunk; + }, $this->subChunks->toArray())); + $this->heightMap = clone $this->heightMap; + $this->biomeIds = clone $this->biomeIds; + } + /** * Hashes the given chunk block coordinates into a single integer. * diff --git a/src/world/format/SubChunk.php b/src/world/format/SubChunk.php index 46026b8332..5328d816a4 100644 --- a/src/world/format/SubChunk.php +++ b/src/world/format/SubChunk.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\format; +use function array_map; use function array_values; use function count; @@ -141,4 +142,13 @@ class SubChunk{ $this->skyLight->collectGarbage(); $this->blockLight->collectGarbage(); } + + public function __clone(){ + $this->blockLayers = array_map(function(PalettedBlockArray $array) : PalettedBlockArray{ + return clone $array; + }, $this->blockLayers); + + $this->skyLight = clone $this->skyLight; + $this->blockLight = clone $this->blockLight; + } } diff --git a/tests/phpunit/world/format/ChunkTest.php b/tests/phpunit/world/format/ChunkTest.php new file mode 100644 index 0000000000..17d277b528 --- /dev/null +++ b/tests/phpunit/world/format/ChunkTest.php @@ -0,0 +1,45 @@ +setFullBlock(0, 0, 0, 1); + $chunk->setBiomeId(0, 0, 1); + $chunk->setHeightMap(0, 0, 1); + + $chunk2 = clone $chunk; + $chunk2->setFullBlock(0, 0, 0, 2); + $chunk2->setBiomeId(0, 0, 2); + $chunk2->setHeightMap(0, 0, 2); + + self::assertNotSame($chunk->getFullBlock(0, 0, 0), $chunk2->getFullBlock(0, 0, 0)); + self::assertNotSame($chunk->getBiomeId(0, 0), $chunk2->getBiomeId(0, 0)); + self::assertNotSame($chunk->getHeightMap(0, 0), $chunk2->getHeightMap(0, 0)); + } +} diff --git a/tests/phpunit/world/format/SubChunkTest.php b/tests/phpunit/world/format/SubChunkTest.php new file mode 100644 index 0000000000..61fd9dee19 --- /dev/null +++ b/tests/phpunit/world/format/SubChunkTest.php @@ -0,0 +1,50 @@ +setFullBlock(0, 0, 0, 1); + $sub1->getBlockLightArray()->set(0, 0, 0, 1); + $sub1->getBlockSkyLightArray()->set(0, 0, 0, 1); + + $sub2 = clone $sub1; + + $sub2->setFullBlock(0, 0, 0, 2); + $sub2->getBlockLightArray()->set(0, 0, 0, 2); + $sub2->getBlockSkyLightArray()->set(0, 0, 0, 2); + + self::assertNotSame($sub1->getFullBlock(0, 0, 0), $sub2->getFullBlock(0, 0, 0)); + self::assertNotSame($sub1->getBlockLightArray()->get(0, 0, 0), $sub2->getBlockLightArray()->get(0, 0, 0)); + self::assertNotSame($sub1->getBlockSkyLightArray()->get(0, 0, 0), $sub2->getBlockSkyLightArray()->get(0, 0, 0)); + } +} From f991961d9a957df6d054a3dc55c3ad4830936448 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 1 Nov 2020 16:34:56 +0000 Subject: [PATCH 2029/3224] Generator no longer requires a ChunkManager to construct this allows injection of arbitrary ChunkManagers into a single Generator instance. The objective here was to remove the requirement to cache a SimpleChunkManager instance in worker-local storage, because that requires that the chunks it stores be manually removed to avoid memory leaks. However, there are some other obstacles, primarily the worldHeight which is not retained anywhere else. --- src/world/generator/Flat.php | 12 ++++++------ src/world/generator/Generator.php | 11 +++-------- src/world/generator/GeneratorRegisterTask.php | 2 +- src/world/generator/PopulationTask.php | 6 +++--- src/world/generator/hell/Nether.php | 18 +++++++++--------- src/world/generator/normal/Normal.php | 18 +++++++++--------- 6 files changed, 31 insertions(+), 36 deletions(-) diff --git a/src/world/generator/Flat.php b/src/world/generator/Flat.php index 5715ffb660..dfa045820c 100644 --- a/src/world/generator/Flat.php +++ b/src/world/generator/Flat.php @@ -57,8 +57,8 @@ class Flat extends Generator{ * * @throws InvalidGeneratorOptionsException */ - public function __construct(ChunkManager $world, int $seed, array $options = []){ - parent::__construct($world, $seed, $options); + public function __construct(int $seed, array $options = []){ + parent::__construct($seed, $options); if(isset($this->options["preset"]) and $this->options["preset"] != ""){ $this->preset = $this->options["preset"]; @@ -169,17 +169,17 @@ class Flat extends Generator{ } } - public function generateChunk(int $chunkX, int $chunkZ) : void{ + public function generateChunk(ChunkManager $world, int $chunkX, int $chunkZ) : void{ $chunk = clone $this->chunk; $chunk->setX($chunkX); $chunk->setZ($chunkZ); - $this->world->setChunk($chunkX, $chunkZ, $chunk); + $world->setChunk($chunkX, $chunkZ, $chunk); } - public function populateChunk(int $chunkX, int $chunkZ) : void{ + public function populateChunk(ChunkManager $world, int $chunkX, int $chunkZ) : void{ $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed); foreach($this->populators as $populator){ - $populator->populate($this->world, $chunkX, $chunkZ, $this->random); + $populator->populate($world, $chunkX, $chunkZ, $this->random); } } diff --git a/src/world/generator/Generator.php b/src/world/generator/Generator.php index b3221a6922..fa78f6abeb 100644 --- a/src/world/generator/Generator.php +++ b/src/world/generator/Generator.php @@ -48,8 +48,6 @@ abstract class Generator{ return $convertedSeed; } - /** @var ChunkManager */ - protected $world; /** @var int */ protected $seed; /** @@ -62,19 +60,16 @@ abstract class Generator{ protected $random; /** - * @throws InvalidGeneratorOptionsException - * * @param mixed[] $options * @phpstan-param array $options */ - public function __construct(ChunkManager $world, int $seed, array $options = []){ - $this->world = $world; + public function __construct(int $seed, array $options = []){ $this->seed = $seed; $this->options = $options; $this->random = new Random($seed); } - abstract public function generateChunk(int $chunkX, int $chunkZ) : void; + abstract public function generateChunk(ChunkManager $world, int $chunkX, int $chunkZ) : void; - abstract public function populateChunk(int $chunkX, int $chunkZ) : void; + abstract public function populateChunk(ChunkManager $world, int $chunkX, int $chunkZ) : void; } diff --git a/src/world/generator/GeneratorRegisterTask.php b/src/world/generator/GeneratorRegisterTask.php index 831dc78527..e4782eb6c8 100644 --- a/src/world/generator/GeneratorRegisterTask.php +++ b/src/world/generator/GeneratorRegisterTask.php @@ -68,7 +68,7 @@ class GeneratorRegisterTask extends AsyncTask{ * @var Generator $generator * @see Generator::__construct() */ - $generator = new $this->generatorClass($manager, $this->seed, igbinary_unserialize($this->settings)); + $generator = new $this->generatorClass($this->seed, igbinary_unserialize($this->settings)); $this->worker->saveToThreadStore("generation.world{$this->worldId}.generator", $generator); } } diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index dd1f152ca2..9b5d107ce9 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -100,7 +100,7 @@ class PopulationTask extends AsyncTask{ $manager->setChunk($chunk->getX(), $chunk->getZ(), $chunk); if(!$chunk->isGenerated()){ - $generator->generateChunk($chunk->getX(), $chunk->getZ()); + $generator->generateChunk($manager, $chunk->getX(), $chunk->getZ()); $chunk = $manager->getChunk($chunk->getX(), $chunk->getZ()); $chunk->setGenerated(); } @@ -108,13 +108,13 @@ class PopulationTask extends AsyncTask{ foreach($chunks as $i => $c){ $manager->setChunk($c->getX(), $c->getZ(), $c); if(!$c->isGenerated()){ - $generator->generateChunk($c->getX(), $c->getZ()); + $generator->generateChunk($manager, $c->getX(), $c->getZ()); $chunks[$i] = $manager->getChunk($c->getX(), $c->getZ()); $chunks[$i]->setGenerated(); } } - $generator->populateChunk($chunk->getX(), $chunk->getZ()); + $generator->populateChunk($manager, $chunk->getX(), $chunk->getZ()); $chunk = $manager->getChunk($chunk->getX(), $chunk->getZ()); $chunk->setPopulated(); diff --git a/src/world/generator/hell/Nether.php b/src/world/generator/hell/Nether.php index cd9d35ae5b..4fe82c0014 100644 --- a/src/world/generator/hell/Nether.php +++ b/src/world/generator/hell/Nether.php @@ -58,8 +58,8 @@ class Nether extends Generator{ * * @throws InvalidGeneratorOptionsException */ - public function __construct(ChunkManager $world, int $seed, array $options = []){ - parent::__construct($world, $seed, $options); + public function __construct(int $seed, array $options = []){ + parent::__construct($seed, $options); $this->noiseBase = new Simplex($this->random, 4, 1 / 4, 1 / 64); $this->random->setSeed($this->seed); @@ -71,12 +71,12 @@ class Nether extends Generator{ $this->populators[] = $ores; } - public function generateChunk(int $chunkX, int $chunkZ) : void{ + public function generateChunk(ChunkManager $world, int $chunkX, int $chunkZ) : void{ $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed); $noise = $this->noiseBase->getFastNoise3D(16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16); - $chunk = $this->world->getChunk($chunkX, $chunkZ); + $chunk = $world->getChunk($chunkX, $chunkZ); $bedrock = VanillaBlocks::BEDROCK()->getFullId(); $netherrack = VanillaBlocks::NETHERRACK()->getFullId(); @@ -106,18 +106,18 @@ class Nether extends Generator{ } foreach($this->generationPopulators as $populator){ - $populator->populate($this->world, $chunkX, $chunkZ, $this->random); + $populator->populate($world, $chunkX, $chunkZ, $this->random); } } - public function populateChunk(int $chunkX, int $chunkZ) : void{ + public function populateChunk(ChunkManager $world, int $chunkX, int $chunkZ) : void{ $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed); foreach($this->populators as $populator){ - $populator->populate($this->world, $chunkX, $chunkZ, $this->random); + $populator->populate($world, $chunkX, $chunkZ, $this->random); } - $chunk = $this->world->getChunk($chunkX, $chunkZ); + $chunk = $world->getChunk($chunkX, $chunkZ); $biome = Biome::getBiome($chunk->getBiomeId(7, 7)); - $biome->populateChunk($this->world, $chunkX, $chunkZ, $this->random); + $biome->populateChunk($world, $chunkX, $chunkZ, $this->random); } } diff --git a/src/world/generator/normal/Normal.php b/src/world/generator/normal/Normal.php index df0e028988..d677d3eed5 100644 --- a/src/world/generator/normal/Normal.php +++ b/src/world/generator/normal/Normal.php @@ -61,8 +61,8 @@ class Normal extends Generator{ * * @throws InvalidGeneratorOptionsException */ - public function __construct(ChunkManager $world, int $seed, array $options = []){ - parent::__construct($world, $seed, $options); + public function __construct(int $seed, array $options = []){ + parent::__construct($seed, $options); $this->gaussian = new Gaussian(2); @@ -145,12 +145,12 @@ class Normal extends Generator{ return $this->selector->pickBiome($x + $xNoise - 1, $z + $zNoise - 1); } - public function generateChunk(int $chunkX, int $chunkZ) : void{ + public function generateChunk(ChunkManager $world, int $chunkX, int $chunkZ) : void{ $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed); $noise = $this->noiseBase->getFastNoise3D(16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16); - $chunk = $this->world->getChunk($chunkX, $chunkZ); + $chunk = $world->getChunk($chunkX, $chunkZ); $biomeCache = []; @@ -216,18 +216,18 @@ class Normal extends Generator{ } foreach($this->generationPopulators as $populator){ - $populator->populate($this->world, $chunkX, $chunkZ, $this->random); + $populator->populate($world, $chunkX, $chunkZ, $this->random); } } - public function populateChunk(int $chunkX, int $chunkZ) : void{ + public function populateChunk(ChunkManager $world, int $chunkX, int $chunkZ) : void{ $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed); foreach($this->populators as $populator){ - $populator->populate($this->world, $chunkX, $chunkZ, $this->random); + $populator->populate($world, $chunkX, $chunkZ, $this->random); } - $chunk = $this->world->getChunk($chunkX, $chunkZ); + $chunk = $world->getChunk($chunkX, $chunkZ); $biome = Biome::getBiome($chunk->getBiomeId(7, 7)); - $biome->populateChunk($this->world, $chunkX, $chunkZ, $this->random); + $biome->populateChunk($world, $chunkX, $chunkZ, $this->random); } } From b176f4c12f1defe329bea185dc573ae413389f30 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 1 Nov 2020 16:47:13 +0000 Subject: [PATCH 2030/3224] Switch to BiomeRegistry I accidentally committed this in c869a7f099237ca189dc574fe3df6e7630eeec51 and didn't notice. I intended to use it and never noticed. --- src/Server.php | 3 -- src/world/World.php | 3 +- src/world/biome/Biome.php | 38 ------------------- src/world/generator/GeneratorRegisterTask.php | 2 - src/world/generator/biome/BiomeSelector.php | 4 +- src/world/generator/hell/Nether.php | 7 ++-- src/world/generator/normal/Normal.php | 3 +- src/world/generator/populator/GroundCover.php | 5 ++- 8 files changed, 13 insertions(+), 52 deletions(-) diff --git a/src/Server.php b/src/Server.php index 459ac1f63c..b517bf1505 100644 --- a/src/Server.php +++ b/src/Server.php @@ -90,7 +90,6 @@ use pocketmine\utils\Terminal; use pocketmine\utils\TextFormat; use pocketmine\utils\Utils; use pocketmine\uuid\UUID; -use pocketmine\world\biome\Biome; use pocketmine\world\format\io\WorldProviderManager; use pocketmine\world\format\io\WritableWorldProvider; use pocketmine\world\generator\Generator; @@ -936,8 +935,6 @@ class Server{ $this->commandMap = new SimpleCommandMap($this); - Biome::init(); - $this->craftingManager = CraftingManagerFromDataHelper::make(\pocketmine\RESOURCE_PATH . '/vanilla/recipes.json'); $this->resourceManager = new ResourcePackManager($this->getDataPath() . "resource_packs" . DIRECTORY_SEPARATOR, $this->logger); diff --git a/src/world/World.php b/src/world/World.php index 58b2cddb64..9a4c2522d2 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -64,6 +64,7 @@ use pocketmine\timings\Timings; use pocketmine\utils\Limits; use pocketmine\utils\ReversePriorityQueue; use pocketmine\world\biome\Biome; +use pocketmine\world\biome\BiomeRegistry; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\WritableWorldProvider; @@ -1879,7 +1880,7 @@ class World implements ChunkManager{ } public function getBiome(int $x, int $z) : Biome{ - return Biome::getBiome($this->getBiomeId($x, $z)); + return BiomeRegistry::getInstance()->getBiome($this->getBiomeId($x, $z)); } public function setBiomeId(int $x, int $z, int $biomeId) : void{ diff --git a/src/world/biome/Biome.php b/src/world/biome/Biome.php index c605658366..0c644bf543 100644 --- a/src/world/biome/Biome.php +++ b/src/world/biome/Biome.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\world\biome; use pocketmine\block\Block; -use pocketmine\block\utils\TreeType; use pocketmine\utils\Random; use pocketmine\world\ChunkManager; use pocketmine\world\generator\populator\Populator; @@ -50,12 +49,6 @@ abstract class Biome{ public const MAX_BIOMES = 256; - /** - * @var Biome[]|\SplFixedArray - * @phpstan-var \SplFixedArray - */ - private static $biomes; - /** @var int */ private $id; /** @var bool */ @@ -77,37 +70,6 @@ abstract class Biome{ /** @var float */ protected $temperature = 0.5; - protected static function register(int $id, Biome $biome) : void{ - self::$biomes[$id] = $biome; - $biome->setId($id); - } - - public static function init() : void{ - self::$biomes = new \SplFixedArray(self::MAX_BIOMES); - - self::register(self::OCEAN, new OceanBiome()); - self::register(self::PLAINS, new PlainBiome()); - self::register(self::DESERT, new DesertBiome()); - self::register(self::MOUNTAINS, new MountainsBiome()); - self::register(self::FOREST, new ForestBiome()); - self::register(self::TAIGA, new TaigaBiome()); - self::register(self::SWAMP, new SwampBiome()); - self::register(self::RIVER, new RiverBiome()); - - self::register(self::ICE_PLAINS, new IcePlainsBiome()); - - self::register(self::SMALL_MOUNTAINS, new SmallMountainsBiome()); - - self::register(self::BIRCH_FOREST, new ForestBiome(TreeType::BIRCH())); - } - - public static function getBiome(int $id) : Biome{ - if(self::$biomes[$id] === null){ - self::register($id, new UnknownBiome()); - } - return self::$biomes[$id]; - } - public function clearPopulators() : void{ $this->populators = []; } diff --git a/src/world/generator/GeneratorRegisterTask.php b/src/world/generator/GeneratorRegisterTask.php index e4782eb6c8..31b038791e 100644 --- a/src/world/generator/GeneratorRegisterTask.php +++ b/src/world/generator/GeneratorRegisterTask.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\world\generator; use pocketmine\scheduler\AsyncTask; -use pocketmine\world\biome\Biome; use pocketmine\world\SimpleChunkManager; use pocketmine\world\World; use function igbinary_serialize; @@ -60,7 +59,6 @@ class GeneratorRegisterTask extends AsyncTask{ } public function onRun() : void{ - Biome::init(); $manager = new SimpleChunkManager($this->worldHeight); $this->worker->saveToThreadStore("generation.world{$this->worldId}.manager", $manager); diff --git a/src/world/generator/biome/BiomeSelector.php b/src/world/generator/biome/BiomeSelector.php index 6b53dfaf94..903673e5fc 100644 --- a/src/world/generator/biome/BiomeSelector.php +++ b/src/world/generator/biome/BiomeSelector.php @@ -25,6 +25,7 @@ namespace pocketmine\world\generator\biome; use pocketmine\utils\Random; use pocketmine\world\biome\Biome; +use pocketmine\world\biome\BiomeRegistry; use pocketmine\world\biome\UnknownBiome; use pocketmine\world\generator\noise\Simplex; @@ -55,9 +56,10 @@ abstract class BiomeSelector{ public function recalculate() : void{ $this->map = new \SplFixedArray(64 * 64); + $biomeRegistry = BiomeRegistry::getInstance(); for($i = 0; $i < 64; ++$i){ for($j = 0; $j < 64; ++$j){ - $biome = Biome::getBiome($this->lookup($i / 63, $j / 63)); + $biome = $biomeRegistry->getBiome($this->lookup($i / 63, $j / 63)); if($biome instanceof UnknownBiome){ throw new \RuntimeException("Unknown biome returned by selector with ID " . $biome->getId()); } diff --git a/src/world/generator/hell/Nether.php b/src/world/generator/hell/Nether.php index 4fe82c0014..4c60dcbbba 100644 --- a/src/world/generator/hell/Nether.php +++ b/src/world/generator/hell/Nether.php @@ -25,6 +25,7 @@ namespace pocketmine\world\generator\hell; use pocketmine\block\VanillaBlocks; use pocketmine\world\biome\Biome; +use pocketmine\world\biome\BiomeRegistry; use pocketmine\world\ChunkManager; use pocketmine\world\generator\Generator; use pocketmine\world\generator\InvalidGeneratorOptionsException; @@ -84,9 +85,7 @@ class Nether extends Generator{ for($x = 0; $x < 16; ++$x){ for($z = 0; $z < 16; ++$z){ - - $biome = Biome::getBiome(Biome::HELL); - $chunk->setBiomeId($x, $z, $biome->getId()); + $chunk->setBiomeId($x, $z, Biome::HELL); for($y = 0; $y < 128; ++$y){ if($y === 0 or $y === 127){ @@ -117,7 +116,7 @@ class Nether extends Generator{ } $chunk = $world->getChunk($chunkX, $chunkZ); - $biome = Biome::getBiome($chunk->getBiomeId(7, 7)); + $biome = BiomeRegistry::getInstance()->getBiome($chunk->getBiomeId(7, 7)); $biome->populateChunk($world, $chunkX, $chunkZ, $this->random); } } diff --git a/src/world/generator/normal/Normal.php b/src/world/generator/normal/Normal.php index d677d3eed5..5c814bcf6f 100644 --- a/src/world/generator/normal/Normal.php +++ b/src/world/generator/normal/Normal.php @@ -25,6 +25,7 @@ namespace pocketmine\world\generator\normal; use pocketmine\block\VanillaBlocks; use pocketmine\world\biome\Biome; +use pocketmine\world\biome\BiomeRegistry; use pocketmine\world\ChunkManager; use pocketmine\world\generator\biome\BiomeSelector; use pocketmine\world\generator\Gaussian; @@ -227,7 +228,7 @@ class Normal extends Generator{ } $chunk = $world->getChunk($chunkX, $chunkZ); - $biome = Biome::getBiome($chunk->getBiomeId(7, 7)); + $biome = BiomeRegistry::getInstance()->getBiome($chunk->getBiomeId(7, 7)); $biome->populateChunk($world, $chunkX, $chunkZ, $this->random); } } diff --git a/src/world/generator/populator/GroundCover.php b/src/world/generator/populator/GroundCover.php index 98bb73faec..718f2cd39d 100644 --- a/src/world/generator/populator/GroundCover.php +++ b/src/world/generator/populator/GroundCover.php @@ -27,7 +27,7 @@ use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\block\Liquid; use pocketmine\utils\Random; -use pocketmine\world\biome\Biome; +use pocketmine\world\biome\BiomeRegistry; use pocketmine\world\ChunkManager; use function count; use function min; @@ -37,9 +37,10 @@ class GroundCover extends Populator{ public function populate(ChunkManager $world, int $chunkX, int $chunkZ, Random $random) : void{ $chunk = $world->getChunk($chunkX, $chunkZ); $factory = BlockFactory::getInstance(); + $biomeRegistry = BiomeRegistry::getInstance(); for($x = 0; $x < 16; ++$x){ for($z = 0; $z < 16; ++$z){ - $biome = Biome::getBiome($chunk->getBiomeId($x, $z)); + $biome = $biomeRegistry->getBiome($chunk->getBiomeId($x, $z)); $cover = $biome->getGroundCover(); if(count($cover) > 0){ $diffY = 0; From 4231bfdc7e87738458543f49ecdafc64d679e4d0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 1 Nov 2020 16:53:06 +0000 Subject: [PATCH 2031/3224] Relocate biome ID constants to pocketmine\data\bedrock package --- src/data/bedrock/BiomeIds.php | 48 +++++++++++++++++++++++++++ src/world/World.php | 3 +- src/world/biome/Biome.php | 17 ---------- src/world/biome/BiomeRegistry.php | 23 +++++++------ src/world/format/Chunk.php | 4 +-- src/world/generator/hell/Nether.php | 4 +-- src/world/generator/normal/Normal.php | 25 +++++++------- 7 files changed, 79 insertions(+), 45 deletions(-) create mode 100644 src/data/bedrock/BiomeIds.php diff --git a/src/data/bedrock/BiomeIds.php b/src/data/bedrock/BiomeIds.php new file mode 100644 index 0000000000..9513a0dd31 --- /dev/null +++ b/src/data/bedrock/BiomeIds.php @@ -0,0 +1,48 @@ +getOrLoadChunk($x >> 4, $z >> 4, false)) !== null){ return $chunk->getBiomeId($x & 0x0f, $z & 0x0f); } - return Biome::OCEAN; //TODO: this should probably throw instead (terrain not generated yet) + return BiomeIds::OCEAN; //TODO: this should probably throw instead (terrain not generated yet) } public function getBiome(int $x, int $z) : Biome{ diff --git a/src/world/biome/Biome.php b/src/world/biome/Biome.php index 0c644bf543..ea79a048e4 100644 --- a/src/world/biome/Biome.php +++ b/src/world/biome/Biome.php @@ -30,23 +30,6 @@ use pocketmine\world\generator\populator\Populator; abstract class Biome{ - public const OCEAN = 0; - public const PLAINS = 1; - public const DESERT = 2; - public const MOUNTAINS = 3; - public const FOREST = 4; - public const TAIGA = 5; - public const SWAMP = 6; - public const RIVER = 7; - - public const HELL = 8; - - public const ICE_PLAINS = 12; - - public const SMALL_MOUNTAINS = 20; - - public const BIRCH_FOREST = 27; - public const MAX_BIOMES = 256; /** @var int */ diff --git a/src/world/biome/BiomeRegistry.php b/src/world/biome/BiomeRegistry.php index 83e4023ea3..98812a64b7 100644 --- a/src/world/biome/BiomeRegistry.php +++ b/src/world/biome/BiomeRegistry.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\world\biome; use pocketmine\block\utils\TreeType; +use pocketmine\data\bedrock\BiomeIds; use pocketmine\utils\SingletonTrait; final class BiomeRegistry{ @@ -38,20 +39,20 @@ final class BiomeRegistry{ public function __construct(){ $this->biomes = new \SplFixedArray(Biome::MAX_BIOMES); - $this->register(Biome::OCEAN, new OceanBiome()); - $this->register(Biome::PLAINS, new PlainBiome()); - $this->register(Biome::DESERT, new DesertBiome()); - $this->register(Biome::MOUNTAINS, new MountainsBiome()); - $this->register(Biome::FOREST, new ForestBiome()); - $this->register(Biome::TAIGA, new TaigaBiome()); - $this->register(Biome::SWAMP, new SwampBiome()); - $this->register(Biome::RIVER, new RiverBiome()); + $this->register(BiomeIds::OCEAN, new OceanBiome()); + $this->register(BiomeIds::PLAINS, new PlainBiome()); + $this->register(BiomeIds::DESERT, new DesertBiome()); + $this->register(BiomeIds::MOUNTAINS, new MountainsBiome()); + $this->register(BiomeIds::FOREST, new ForestBiome()); + $this->register(BiomeIds::TAIGA, new TaigaBiome()); + $this->register(BiomeIds::SWAMP, new SwampBiome()); + $this->register(BiomeIds::RIVER, new RiverBiome()); - $this->register(Biome::ICE_PLAINS, new IcePlainsBiome()); + $this->register(BiomeIds::ICE_PLAINS, new IcePlainsBiome()); - $this->register(Biome::SMALL_MOUNTAINS, new SmallMountainsBiome()); + $this->register(BiomeIds::SMALL_MOUNTAINS, new SmallMountainsBiome()); - $this->register(Biome::BIRCH_FOREST, new ForestBiome(TreeType::BIRCH())); + $this->register(BiomeIds::BIRCH_FOREST, new ForestBiome(TreeType::BIRCH())); } public function register(int $id, Biome $biome) : void{ diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 833e31902a..1c7fab7f43 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -29,13 +29,13 @@ namespace pocketmine\world\format; use pocketmine\block\BlockLegacyIds; use pocketmine\block\tile\Tile; use pocketmine\block\tile\TileFactory; +use pocketmine\data\bedrock\BiomeIds; use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\StringTag; use pocketmine\player\Player; -use pocketmine\world\biome\Biome; use pocketmine\world\World; use function array_fill; use function array_filter; @@ -106,7 +106,7 @@ class Chunk{ $val = ($this->subChunks->getSize() * 16); $this->heightMap = $heightMap ?? new HeightArray(array_fill(0, 256, $val)); - $this->biomeIds = $biomeIds ?? BiomeArray::fill(Biome::OCEAN); + $this->biomeIds = $biomeIds ?? BiomeArray::fill(BiomeIds::OCEAN); $this->NBTtiles = $tiles; $this->NBTentities = $entities; diff --git a/src/world/generator/hell/Nether.php b/src/world/generator/hell/Nether.php index 4c60dcbbba..b4b5c5837a 100644 --- a/src/world/generator/hell/Nether.php +++ b/src/world/generator/hell/Nether.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\world\generator\hell; use pocketmine\block\VanillaBlocks; -use pocketmine\world\biome\Biome; +use pocketmine\data\bedrock\BiomeIds; use pocketmine\world\biome\BiomeRegistry; use pocketmine\world\ChunkManager; use pocketmine\world\generator\Generator; @@ -85,7 +85,7 @@ class Nether extends Generator{ for($x = 0; $x < 16; ++$x){ for($z = 0; $z < 16; ++$z){ - $chunk->setBiomeId($x, $z, Biome::HELL); + $chunk->setBiomeId($x, $z, BiomeIds::HELL); for($y = 0; $y < 128; ++$y){ if($y === 0 or $y === 127){ diff --git a/src/world/generator/normal/Normal.php b/src/world/generator/normal/Normal.php index 5c814bcf6f..ceec94cc74 100644 --- a/src/world/generator/normal/Normal.php +++ b/src/world/generator/normal/Normal.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\world\generator\normal; use pocketmine\block\VanillaBlocks; +use pocketmine\data\bedrock\BiomeIds; use pocketmine\world\biome\Biome; use pocketmine\world\biome\BiomeRegistry; use pocketmine\world\ChunkManager; @@ -74,38 +75,38 @@ class Normal extends Generator{ protected function lookup(float $temperature, float $rainfall) : int{ if($rainfall < 0.25){ if($temperature < 0.7){ - return Biome::OCEAN; + return BiomeIds::OCEAN; }elseif($temperature < 0.85){ - return Biome::RIVER; + return BiomeIds::RIVER; }else{ - return Biome::SWAMP; + return BiomeIds::SWAMP; } }elseif($rainfall < 0.60){ if($temperature < 0.25){ - return Biome::ICE_PLAINS; + return BiomeIds::ICE_PLAINS; }elseif($temperature < 0.75){ - return Biome::PLAINS; + return BiomeIds::PLAINS; }else{ - return Biome::DESERT; + return BiomeIds::DESERT; } }elseif($rainfall < 0.80){ if($temperature < 0.25){ - return Biome::TAIGA; + return BiomeIds::TAIGA; }elseif($temperature < 0.75){ - return Biome::FOREST; + return BiomeIds::FOREST; }else{ - return Biome::BIRCH_FOREST; + return BiomeIds::BIRCH_FOREST; } }else{ //FIXME: This will always cause River to be used since the rainfall is always greater than 0.8 if we //reached this branch. However I don't think that substituting temperature for rainfall is correct given //that mountain biomes are supposed to be pretty cold. if($rainfall < 0.25){ - return Biome::MOUNTAINS; + return BiomeIds::MOUNTAINS; }elseif($rainfall < 0.70){ - return Biome::SMALL_MOUNTAINS; + return BiomeIds::SMALL_MOUNTAINS; }else{ - return Biome::RIVER; + return BiomeIds::RIVER; } } } From 0ae17af1e0b26589c8df57315a25d9f345d32e08 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 1 Nov 2020 16:53:42 +0000 Subject: [PATCH 2032/3224] BiomeRegistry: fixed EOF newline --- src/world/biome/BiomeRegistry.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/biome/BiomeRegistry.php b/src/world/biome/BiomeRegistry.php index 98812a64b7..c488770d01 100644 --- a/src/world/biome/BiomeRegistry.php +++ b/src/world/biome/BiomeRegistry.php @@ -67,4 +67,4 @@ final class BiomeRegistry{ return $this->biomes[$id]; } -} \ No newline at end of file +} From 1f2bc8cb690e803916b284d83838153fa9e79208 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 1 Nov 2020 17:05:57 +0000 Subject: [PATCH 2033/3224] World: remove rogue import --- .../protocol/types/entity => data/bedrock}/EntityLegacyIds.php | 0 src/world/World.php | 1 - 2 files changed, 1 deletion(-) rename src/{network/mcpe/protocol/types/entity => data/bedrock}/EntityLegacyIds.php (100%) diff --git a/src/network/mcpe/protocol/types/entity/EntityLegacyIds.php b/src/data/bedrock/EntityLegacyIds.php similarity index 100% rename from src/network/mcpe/protocol/types/entity/EntityLegacyIds.php rename to src/data/bedrock/EntityLegacyIds.php diff --git a/src/world/World.php b/src/world/World.php index c15a2fd2bd..1dbaa88225 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -106,7 +106,6 @@ use function mt_rand; use function spl_object_id; use function strtolower; use function trim; -use function var_dump; use const M_PI; use const PHP_INT_MAX; use const PHP_INT_MIN; From 12e185e3f67521a0266fe998fb2fe3681b0384d4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 1 Nov 2020 17:07:34 +0000 Subject: [PATCH 2034/3224] Relocate EntityLegacyIds to pocketmine\data\bedrock package --- src/data/bedrock/EntityLegacyIds.php | 2 +- src/entity/EntityFactory.php | 2 +- src/item/ItemFactory.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/data/bedrock/EntityLegacyIds.php b/src/data/bedrock/EntityLegacyIds.php index a0745e7ee9..41ff259c3e 100644 --- a/src/data/bedrock/EntityLegacyIds.php +++ b/src/data/bedrock/EntityLegacyIds.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\protocol\types\entity; +namespace pocketmine\data\bedrock; final class EntityLegacyIds{ diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index 060e152da8..ad9c2e510f 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -27,6 +27,7 @@ use DaveRandom\CallbackValidator\CallbackType; use DaveRandom\CallbackValidator\ParameterType; use DaveRandom\CallbackValidator\ReturnType; use pocketmine\block\BlockFactory; +use pocketmine\data\bedrock\EntityLegacyIds; use pocketmine\entity\object\ExperienceOrb; use pocketmine\entity\object\FallingBlock; use pocketmine\entity\object\ItemEntity; @@ -46,7 +47,6 @@ use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\StringTag; -use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\utils\SingletonTrait; use pocketmine\utils\Utils; use pocketmine\world\World; diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index fca99016ab..999b57e761 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -31,6 +31,7 @@ use pocketmine\block\utils\SkullType; use pocketmine\block\utils\TreeType; use pocketmine\block\VanillaBlocks; use pocketmine\data\bedrock\DyeColorIdMap; +use pocketmine\data\bedrock\EntityLegacyIds; use pocketmine\entity\Entity; use pocketmine\entity\Location; use pocketmine\entity\Squid; @@ -39,7 +40,6 @@ use pocketmine\entity\Zombie; use pocketmine\inventory\ArmorInventory; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds; use pocketmine\utils\SingletonTrait; use pocketmine\world\World; From b7690fed045cfb2b6ca37c66e4338a9d75d1fedd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 1 Nov 2020 17:09:10 +0000 Subject: [PATCH 2035/3224] BiomeSelector: replace phpdoc with typehints --- src/world/generator/biome/BiomeSelector.php | 22 +++------------------ 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/src/world/generator/biome/BiomeSelector.php b/src/world/generator/biome/BiomeSelector.php index 903673e5fc..f61f534ce6 100644 --- a/src/world/generator/biome/BiomeSelector.php +++ b/src/world/generator/biome/BiomeSelector.php @@ -68,31 +68,15 @@ abstract class BiomeSelector{ } } - /** - * @param float $x - * @param float $z - * - * @return float - */ - public function getTemperature($x, $z){ + public function getTemperature(float $x, float $z) : float{ return ($this->temperature->noise2D($x, $z, true) + 1) / 2; } - /** - * @param float $x - * @param float $z - * - * @return float - */ - public function getRainfall($x, $z){ + public function getRainfall(float $x, float $z) : float{ return ($this->rainfall->noise2D($x, $z, true) + 1) / 2; } - /** - * @param int $x - * @param int $z - */ - public function pickBiome($x, $z) : Biome{ + public function pickBiome(float $x, float $z) : Biome{ $temperature = (int) ($this->getTemperature($x, $z) * 63); $rainfall = (int) ($this->getRainfall($x, $z) * 63); From 0bb37b5065220de969389bc436e833fa34b4a7ab Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 1 Nov 2020 17:24:09 +0000 Subject: [PATCH 2036/3224] World: formalize setBlockAt()'s refusal to modify un-generated chunks closes #2631 --- src/world/World.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index 1dbaa88225..083dcada4c 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1401,6 +1401,14 @@ class World implements ChunkManager{ if(!$this->isInWorld($x, $y, $z)){ throw new \InvalidArgumentException("Pos x=$x,y=$y,z=$z is outside of the world bounds"); } + $chunkX = $x >> 4; + $chunkZ = $z >> 4; + if($this->isChunkLocked($chunkX, $chunkZ)){ + throw new WorldException("Terrain is locked for generation/population"); + } + if(!$this->loadChunk($chunkX, $chunkZ, false)){ //current expected behaviour is to try to load the terrain synchronously + throw new WorldException("Cannot set a block in un-generated terrain"); + } $this->timings->setBlock->startTiming(); From 61112e4912cad109329ad42bdd2547fa54ebf03d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 1 Nov 2020 17:36:56 +0000 Subject: [PATCH 2037/3224] World: make create params of loadChunk and getOrLoadChunk mandatory differences in the default values almost caused me to miss some bugs while trying to remove them. --- src/world/World.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 083dcada4c..4ac97246fa 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -586,7 +586,7 @@ class World implements ChunkManager{ $this->cancelUnloadChunkRequest($chunkX, $chunkZ); if($autoLoad){ - $this->loadChunk($chunkX, $chunkZ); + $this->loadChunk($chunkX, $chunkZ, true); } } @@ -1847,7 +1847,7 @@ class World implements ChunkManager{ * Returns the tile at the specified x,y,z coordinates, or null if it does not exist. */ public function getTileAt(int $x, int $y, int $z) : ?Tile{ - return ($chunk = $this->getOrLoadChunk($x >> 4, $z >> 4)) !== null ? $chunk->getTile($x & 0x0f, $y, $z & 0x0f) : null; + return ($chunk = $this->getOrLoadChunk($x >> 4, $z >> 4, false)) !== null ? $chunk->getTile($x & 0x0f, $y, $z & 0x0f) : null; } /** @@ -1919,7 +1919,7 @@ class World implements ChunkManager{ * * @param bool $create Whether to create an empty chunk as a placeholder if the chunk does not exist */ - public function getOrLoadChunk(int $chunkX, int $chunkZ, bool $create = false) : ?Chunk{ + public function getOrLoadChunk(int $chunkX, int $chunkZ, bool $create) : ?Chunk{ if(isset($this->chunks[$index = World::chunkHash($chunkX, $chunkZ)])){ return $this->chunks[$index]; }elseif($this->loadChunk($chunkX, $chunkZ, $create)){ @@ -2086,12 +2086,12 @@ class World implements ChunkManager{ } public function isChunkGenerated(int $x, int $z) : bool{ - $chunk = $this->getOrLoadChunk($x, $z); + $chunk = $this->getOrLoadChunk($x, $z, false); return $chunk !== null ? $chunk->isGenerated() : false; } public function isChunkPopulated(int $x, int $z) : bool{ - $chunk = $this->getOrLoadChunk($x, $z); + $chunk = $this->getOrLoadChunk($x, $z, false); return $chunk !== null ? $chunk->isPopulated() : false; } @@ -2205,7 +2205,7 @@ class World implements ChunkManager{ * * @throws \InvalidStateException */ - public function loadChunk(int $x, int $z, bool $create = true) : bool{ + public function loadChunk(int $x, int $z, bool $create) : bool{ if(isset($this->chunks[$chunkHash = World::chunkHash($x, $z)])){ return true; } From 2e9b2d4aae470021457846d78eda025e2ec702cb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 1 Nov 2020 17:41:58 +0000 Subject: [PATCH 2038/3224] World: fixed false unload events firing on chunk replacement when tiles and entities are deleted --- src/world/World.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 4ac97246fa..cc9ff5bc36 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2023,16 +2023,18 @@ class World implements ChunkManager{ $oldChunk = $this->getOrLoadChunk($chunkX, $chunkZ, false); if($oldChunk !== null and $oldChunk !== $chunk){ if($deleteEntitiesAndTiles){ - foreach($oldChunk->getEntities() as $player){ - if(!($player instanceof Player)){ - continue; + foreach($oldChunk->getEntities() as $entity){ + if($entity instanceof Player){ + $chunk->addEntity($entity); + $oldChunk->removeEntity($entity); + $entity->chunk = $chunk; + }else{ + $entity->close(); } - $chunk->addEntity($player); - $oldChunk->removeEntity($player); - $player->chunk = $chunk; } - //TODO: this causes chunkloaders to receive false "unloaded" notifications - $this->unloadChunk($chunkX, $chunkZ, false, false); + foreach($oldChunk->getTiles() as $tile){ + $tile->close(); + } }else{ foreach($oldChunk->getEntities() as $entity){ $chunk->addEntity($entity); From bd78d0bff8ea2955ea7d96eb88b028edbfcff27b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Nov 2020 14:11:28 +0000 Subject: [PATCH 2039/3224] Player: added getItemCooldownExpiry() --- changelogs/4.0-snapshot.md | 1 + src/player/Player.php | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 4c051190d3..d1938caaf5 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -575,6 +575,7 @@ This version features substantial changes to the network system, improving coher - `Player->breakBlock()`: destroy the target block in the current world (immediately) - `Player->consumeHeldItem()`: consume the previously activated item, e.g. eating food - `Player->continueBreakBlock()`: punch the target block during destruction in survival, advancing break animation and creating particles + - `Player->getItemCooldownExpiry()`: returns the tick on which the player's cooldown for a given item expires - `Player->hasFiniteResources()` - `Player->interactBlock()`: interact (right click) the target block in the current world - `Player->interactEntity()`: interact (right click) the target entity, e.g. to apply a nametag (not implemented yet) diff --git a/src/player/Player.php b/src/player/Player.php index d70a9c2f5d..d489d81a99 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -111,6 +111,7 @@ use pocketmine\world\sound\EntityAttackSound; use pocketmine\world\sound\FireExtinguishSound; use pocketmine\world\World; use function abs; +use function array_key_exists; use function assert; use function count; use function explode; @@ -675,6 +676,14 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return $this->startAction === -1 ? -1 : ($this->server->getTick() - $this->startAction); } + /** + * Returns the server tick on which the player's cooldown period expires for the given item. + */ + public function getItemCooldownExpiry(Item $item) : int{ + $this->checkItemCooldowns(); + return $this->usedItemsCooldown[$item->getId()] ?? 0; + } + /** * Returns whether the player has a cooldown period left before it can use the given item again. */ From 5cc2a9c3dd738c316d3fc3e9c6e48d17463e6314 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Nov 2020 14:12:47 +0000 Subject: [PATCH 2040/3224] World: rename getChunkAtPosition() to getOrLoadChunkAtPosition() this more accurately reflects what it does. --- src/block/Block.php | 2 +- src/entity/Entity.php | 2 +- src/world/World.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/block/Block.php b/src/block/Block.php index 6ac38de9ff..4b82a0cb9e 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -147,7 +147,7 @@ class Block{ } public function writeStateToWorld() : void{ - $this->pos->getWorld()->getChunkAtPosition($this->pos)->setFullBlock($this->pos->x & 0xf, $this->pos->y, $this->pos->z & 0xf, $this->getFullId()); + $this->pos->getWorld()->getOrLoadChunkAtPosition($this->pos)->setFullBlock($this->pos->x & 0xf, $this->pos->y, $this->pos->z & 0xf, $this->getFullId()); $tileType = $this->idInfo->getTileClass(); $oldTile = $this->pos->getWorld()->getTile($this->pos); diff --git a/src/entity/Entity.php b/src/entity/Entity.php index aa5d511189..4f971bd555 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -243,7 +243,7 @@ abstract class Entity{ $this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0); $this->recalculateBoundingBox(); - $this->chunk = $this->getWorld()->getChunkAtPosition($this->location, false); + $this->chunk = $this->getWorld()->getOrLoadChunkAtPosition($this->location, false); if($this->chunk === null){ throw new \InvalidStateException("Cannot create entities in unloaded chunks"); } diff --git a/src/world/World.php b/src/world/World.php index cc9ff5bc36..ae6edce2eb 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1936,7 +1936,7 @@ class World implements ChunkManager{ /** * Returns the chunk containing the given Vector3 position. */ - public function getChunkAtPosition(Vector3 $pos, bool $create = false) : ?Chunk{ + public function getOrLoadChunkAtPosition(Vector3 $pos, bool $create = false) : ?Chunk{ return $this->getOrLoadChunk($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4, $create); } @@ -2342,7 +2342,7 @@ class World implements ChunkManager{ $max = $this->worldHeight; $v = $spawn->floor(); - $chunk = $this->getChunkAtPosition($v, false); + $chunk = $this->getOrLoadChunkAtPosition($v, false); $x = (int) $v->x; $y = $v->y; $z = (int) $v->z; From a05f67bc77e385fa358b068b458bd6036cbd8446 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Nov 2020 14:33:26 +0000 Subject: [PATCH 2041/3224] Position::fromObject() world parameter is now mandatory (although still nullable) --- src/entity/Location.php | 2 +- src/world/Position.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/entity/Location.php b/src/entity/Location.php index 2ff7f3b078..156062a417 100644 --- a/src/entity/Location.php +++ b/src/entity/Location.php @@ -43,7 +43,7 @@ class Location extends Position{ /** * @return Location */ - public static function fromObject(Vector3 $pos, ?World $world = null, float $yaw = 0.0, float $pitch = 0.0){ + public static function fromObject(Vector3 $pos, ?World $world, float $yaw = 0.0, float $pitch = 0.0){ return new Location($pos->x, $pos->y, $pos->z, $yaw, $pitch, $world ?? (($pos instanceof Position) ? $pos->world : null)); } diff --git a/src/world/Position.php b/src/world/Position.php index 9d2f362991..0f83b6fd05 100644 --- a/src/world/Position.php +++ b/src/world/Position.php @@ -49,7 +49,7 @@ class Position extends Vector3{ /** * @return Position */ - public static function fromObject(Vector3 $pos, ?World $world = null){ + public static function fromObject(Vector3 $pos, ?World $world){ return new Position($pos->x, $pos->y, $pos->z, $world); } From 5c5fe154830a87c389148d4522697b90552c006b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Nov 2020 14:42:29 +0000 Subject: [PATCH 2042/3224] tests: remove unused script --- tests/build-leveldb.sh | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100755 tests/build-leveldb.sh diff --git a/tests/build-leveldb.sh b/tests/build-leveldb.sh deleted file mode 100755 index a4fcd3439a..0000000000 --- a/tests/build-leveldb.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -set -e - -LEVELDB_VERSION="$1" -if [ ! -f "./leveldb-mcpe/built_version" ] || [ $(cat "./leveldb-mcpe/built_version") != "$LEVELDB_VERSION" ]; then - echo "Building new LevelDB" - rm -rf "./leveldb-mcpe" || true - mkdir "./leveldb-mcpe" - - curl -fsSL "https://github.com/pmmp/leveldb-mcpe/archive/$LEVELDB_VERSION.tar.gz" | tar -zx - mv "./leveldb-mcpe-$LEVELDB_VERSION" leveldb-mcpe-build - cd leveldb-mcpe-build - make -j4 sharedlibs - - #put the artifacts in a separate dir, to avoid bloating travis cache" - mv out-shared/libleveldb.* ../leveldb-mcpe - mv include ../leveldb-mcpe - cd ../leveldb-mcpe - echo "$LEVELDB_VERSION" > "./built_version" - cd .. -else - echo "Using cached build for LevelDB version $LEVELDB_VERSION" -fi From c3af0eff93c50d99c479b717d629d55ac4ef631a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Nov 2020 17:56:15 +0000 Subject: [PATCH 2043/3224] travis: use pmmp/leveldb --- tests/travis/setup-php.yml | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/tests/travis/setup-php.yml b/tests/travis/setup-php.yml index 7c2b770736..cac532476e 100644 --- a/tests/travis/setup-php.yml +++ b/tests/travis/setup-php.yml @@ -9,30 +9,37 @@ before_script: - | set -e - LEVELDB_VERSION="10f59b56bec1db3ffe42ff265afe22182073e0e2" + LEVELDB_VERSION="f520e1d607759b00e335e332469c9c1b13e05f41" if [ ! -f "./leveldb-mcpe/built_version" ] || [ $(cat "./leveldb-mcpe/built_version") != "$LEVELDB_VERSION" ]; then echo "Building new LevelDB" rm -rf "./leveldb-mcpe" || true mkdir "./leveldb-mcpe" - curl -fsSL "https://github.com/pmmp/leveldb-mcpe/archive/$LEVELDB_VERSION.tar.gz" | tar -zx - mv "./leveldb-mcpe-$LEVELDB_VERSION" leveldb-mcpe-build + curl -fsSL "https://github.com/pmmp/leveldb/archive/$LEVELDB_VERSION.tar.gz" | tar -zx + mv "./leveldb-$LEVELDB_VERSION" leveldb-mcpe-build + DIR=$(pwd)/leveldb-mcpe cd leveldb-mcpe-build - make -j4 sharedlibs + CFLAGS="-fPIC" CXXFLAGS="-fPIC" cmake . \ + -DCMAKE_INSTALL_PREFIX="$DIR" \ + -DCMAKE_PREFIX_PATH="$DIR" \ + -DCMAKE_INSTALL_LIBDIR=lib \ + -DLEVELDB_BUILD_TESTS=OFF \ + -DLEVELDB_BUILD_BENCHMARKS=OFF \ + -DLEVELDB_SNAPPY=OFF \ + -DLEVELDB_ZSTD=OFF \ + -DLEVELDB_TCMALLOC=OFF \ + -DCMAKE_BUILD_TYPE=Release + make -j4 install - #put the artifacts in a separate dir, to avoid bloating travis cache" - mv out-shared/libleveldb.* ../leveldb-mcpe - mv include ../leveldb-mcpe - cd ../leveldb-mcpe echo "$LEVELDB_VERSION" > "./built_version" cd .. else echo "Using cached build for LevelDB version $LEVELDB_VERSION" fi - - git clone https://github.com/reeze/php-leveldb.git leveldb + - git clone https://github.com/pmmp/php-leveldb.git leveldb - cd leveldb - - git checkout 9bcae79f71b81a5c3ea6f67e45ae9ae9fb2775a5 + - git checkout bed651cf74e83139d97ebbcacc749fa7752b7782 - phpize - ./configure --with-leveldb=../leveldb-mcpe && make && make install - cd .. From bcedbc364b13599e8f84b48339a50aee90a70b2e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Nov 2020 18:41:12 +0000 Subject: [PATCH 2044/3224] BlockDataSerializer: added methods to read/write coral facing --- src/block/utils/BlockDataSerializer.php | 26 +++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/block/utils/BlockDataSerializer.php b/src/block/utils/BlockDataSerializer.php index 5a9eaadffc..e0b7f1b3bf 100644 --- a/src/block/utils/BlockDataSerializer.php +++ b/src/block/utils/BlockDataSerializer.php @@ -123,6 +123,32 @@ final class BlockDataSerializer{ return 5 - self::writeHorizontalFacing($value); } + public static function readCoralFacing(int $value) : int{ + $result = [ + 0 => Facing::WEST, + 1 => Facing::EAST, + 2 => Facing::NORTH, + 3 => Facing::SOUTH + ][$value] ?? null; + if($result === null){ + throw new \InvalidArgumentException("Invalid coral facing $value"); + } + return $result; + } + + public static function writeCoralFacing(int $value) : int{ + $result = [ + Facing::WEST => 0, + Facing::EAST => 1, + Facing::NORTH => 2, + Facing::SOUTH => 3 + ][$value] ?? null; + if($result === null){ + throw new \InvalidArgumentException("Invalid Y-axis facing $value"); + } + return $result; + } + public static function readBoundedInt(string $name, int $v, int $min, int $max) : int{ if($v < $min or $v > $max){ throw new InvalidBlockStateException("$name should be in range $min - $max, got $v"); From 0a8dc3edd30871f2fa675aa904c8b209d4f868b0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Nov 2020 18:42:40 +0000 Subject: [PATCH 2045/3224] Fixed users of ColorInMetadataTrait having uninitialized default colours --- src/block/Carpet.php | 2 ++ src/block/Concrete.php | 2 ++ src/block/ConcretePowder.php | 2 ++ src/block/Wool.php | 2 ++ 4 files changed, 8 insertions(+) diff --git a/src/block/Carpet.php b/src/block/Carpet.php index ba6d243511..19de695e66 100644 --- a/src/block/Carpet.php +++ b/src/block/Carpet.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\ColorInMetadataTrait; +use pocketmine\block\utils\DyeColor; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -35,6 +36,7 @@ class Carpet extends Flowable{ use ColorInMetadataTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + $this->color = DyeColor::WHITE(); parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.1)); } diff --git a/src/block/Concrete.php b/src/block/Concrete.php index 1201c9c2b0..6735c8dce6 100644 --- a/src/block/Concrete.php +++ b/src/block/Concrete.php @@ -24,12 +24,14 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\ColorInMetadataTrait; +use pocketmine\block\utils\DyeColor; use pocketmine\item\ToolTier; class Concrete extends Opaque{ use ColorInMetadataTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + $this->color = DyeColor::WHITE(); parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); } } diff --git a/src/block/ConcretePowder.php b/src/block/ConcretePowder.php index ab44e9491f..826230983e 100644 --- a/src/block/ConcretePowder.php +++ b/src/block/ConcretePowder.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\ColorInMetadataTrait; +use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\Fallable; use pocketmine\block\utils\FallableTrait; use pocketmine\math\Facing; @@ -35,6 +36,7 @@ class ConcretePowder extends Opaque implements Fallable{ } public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + $this->color = DyeColor::WHITE(); parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::SHOVEL)); } diff --git a/src/block/Wool.php b/src/block/Wool.php index 5a30defb1a..14345c3454 100644 --- a/src/block/Wool.php +++ b/src/block/Wool.php @@ -24,12 +24,14 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\ColorInMetadataTrait; +use pocketmine\block\utils\DyeColor; use pocketmine\item\Item; class Wool extends Opaque{ use ColorInMetadataTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + $this->color = DyeColor::WHITE(); parent::__construct($idInfo, $name, $breakInfo ?? new class(0.8, BlockToolType::SHEARS) extends BlockBreakInfo{ public function getBreakTime(Item $item) : float{ $time = parent::getBreakTime($item); From 32929925aa1df27e4ccc1d5f146551726fe43656 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Nov 2020 19:13:32 +0000 Subject: [PATCH 2046/3224] Block: added a bunch of state manipulation APIs --- src/block/Anvil.php | 11 +++++++++ src/block/Bed.php | 6 +++++ src/block/Bedrock.php | 6 +++++ src/block/Button.php | 8 +++++++ src/block/Cactus.php | 11 +++++++++ src/block/Cake.php | 11 +++++++++ src/block/CocoaBlock.php | 11 +++++++++ src/block/Crops.php | 11 +++++++++ src/block/Door.php | 24 +++++++++++++++++++ src/block/DoublePlant.php | 8 +++++++ src/block/EndPortalFrame.php | 8 +++++++ src/block/Farmland.php | 11 +++++++++ src/block/FenceGate.php | 16 +++++++++++++ src/block/Fire.php | 11 +++++++++ src/block/FrostedIce.php | 11 +++++++++ src/block/ItemFrame.php | 13 ++++++++++ src/block/Lantern.php | 8 +++++++ src/block/Leaves.php | 16 +++++++++++++ src/block/Liquid.php | 16 +++++++++++++ src/block/NetherWartPlant.php | 11 +++++++++ src/block/Sapling.php | 8 +++++++ src/block/SeaPickle.php | 19 +++++++++++++++ src/block/SnowLayer.php | 11 +++++++++ src/block/Sponge.php | 8 +++++++ src/block/Stair.php | 16 +++++++++++++ src/block/Sugarcane.php | 11 +++++++++ src/block/Trapdoor.php | 16 +++++++++++++ src/block/Tripwire.php | 32 +++++++++++++++++++++++++ src/block/TripwireHook.php | 16 +++++++++++++ src/block/utils/PillarRotationTrait.php | 9 +++++++ 30 files changed, 374 insertions(+) diff --git a/src/block/Anvil.php b/src/block/Anvil.php index 14b2a8379f..313e6ef8c7 100644 --- a/src/block/Anvil.php +++ b/src/block/Anvil.php @@ -64,6 +64,17 @@ class Anvil extends Transparent implements Fallable{ return 0b11; } + public function getDamage() : int{ return $this->damage; } + + /** @return $this */ + public function setDamage(int $damage) : self{ + if($damage < 0 || $damage > 2){ + throw new \InvalidArgumentException("Damage must be in range 0-2"); + } + $this->damage = $damage; + return $this; + } + /** * @return AxisAlignedBB[] */ diff --git a/src/block/Bed.php b/src/block/Bed.php index dec2485768..958f771ddd 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -100,6 +100,12 @@ class Bed extends Transparent{ return $this->head; } + /** @return $this */ + public function setHead(bool $head) : self{ + $this->head = $head; + return $this; + } + public function isOccupied() : bool{ return $this->occupied; } diff --git a/src/block/Bedrock.php b/src/block/Bedrock.php index b7765bcb20..c9429d1a8f 100644 --- a/src/block/Bedrock.php +++ b/src/block/Bedrock.php @@ -47,4 +47,10 @@ class Bedrock extends Opaque{ public function burnsForever() : bool{ return $this->burnsForever; } + + /** @return $this */ + public function setBurnsForever(bool $burnsForever) : self{ + $this->burnsForever = $burnsForever; + return $this; + } } diff --git a/src/block/Button.php b/src/block/Button.php index c3d0c4d236..0f50778ec8 100644 --- a/src/block/Button.php +++ b/src/block/Button.php @@ -53,6 +53,14 @@ abstract class Button extends Flowable{ return 0b1111; } + public function isPressed() : bool{ return $this->pressed; } + + /** @return $this */ + public function setPressed(bool $pressed) : self{ + $this->pressed = $pressed; + return $this; + } + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ //TODO: check valid target block $this->facing = $face; diff --git a/src/block/Cactus.php b/src/block/Cactus.php index 3062dbb823..dde4dac4d8 100644 --- a/src/block/Cactus.php +++ b/src/block/Cactus.php @@ -56,6 +56,17 @@ class Cactus extends Transparent{ return 0b1111; } + public function getAge() : int{ return $this->age; } + + /** @return $this */ + public function setAge(int $age) : self{ + if($age < 0 || $age > 15){ + throw new \InvalidArgumentException("Age must be in range 0-15"); + } + $this->age = $age; + return $this; + } + public function hasEntityCollision() : bool{ return true; } diff --git a/src/block/Cake.php b/src/block/Cake.php index 4575cd99e6..53f44a423b 100644 --- a/src/block/Cake.php +++ b/src/block/Cake.php @@ -67,6 +67,17 @@ class Cake extends Transparent implements FoodSource{ ]; } + public function getBites() : int{ return $this->bites; } + + /** @return $this */ + public function setBites(int $bites) : self{ + if($bites < 0 || $bites > 6){ + throw new \InvalidArgumentException("Bites must be in range 0-6"); + } + $this->bites = $bites; + return $this; + } + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() !== BlockLegacyIds::AIR){ diff --git a/src/block/CocoaBlock.php b/src/block/CocoaBlock.php index 696a2dd97d..daf612df5a 100644 --- a/src/block/CocoaBlock.php +++ b/src/block/CocoaBlock.php @@ -60,6 +60,17 @@ class CocoaBlock extends Transparent{ return 0b1111; } + public function getAge() : int{ return $this->age; } + + /** @return $this */ + public function setAge(int $age) : self{ + if($age < 0 || $age > 2){ + throw new \InvalidArgumentException("Age must be in range 0-2"); + } + $this->age = $age; + return $this; + } + /** * @return AxisAlignedBB[] */ diff --git a/src/block/Crops.php b/src/block/Crops.php index ff0570d878..67f98df950 100644 --- a/src/block/Crops.php +++ b/src/block/Crops.php @@ -53,6 +53,17 @@ abstract class Crops extends Flowable{ return 0b111; } + public function getAge() : int{ return $this->age; } + + /** @return $this */ + public function setAge(int $age) : self{ + if($age < 0 || $age > 7){ + throw new \InvalidArgumentException("Age must be in range 0-7"); + } + $this->age = $age; + return $this; + } + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($blockReplace->getSide(Facing::DOWN)->getId() === BlockLegacyIds::FARMLAND){ return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/block/Door.php b/src/block/Door.php index 1d0e175f44..ee0bc63bb1 100644 --- a/src/block/Door.php +++ b/src/block/Door.php @@ -87,6 +87,30 @@ class Door extends Transparent{ } } + public function isTop() : bool{ return $this->top; } + + /** @return $this */ + public function setTop(bool $top) : self{ + $this->top = $top; + return $this; + } + + public function isHingeRight() : bool{ return $this->hingeRight; } + + /** @return $this */ + public function setHingeRight(bool $hingeRight) : self{ + $this->hingeRight = $hingeRight; + return $this; + } + + public function isOpen() : bool{ return $this->open; } + + /** @return $this */ + public function setOpen(bool $open) : self{ + $this->open = $open; + return $this; + } + public function isSolid() : bool{ return false; } diff --git a/src/block/DoublePlant.php b/src/block/DoublePlant.php index 3505e1ac6b..b558ff756e 100644 --- a/src/block/DoublePlant.php +++ b/src/block/DoublePlant.php @@ -50,6 +50,14 @@ class DoublePlant extends Flowable{ return 0b1000; } + public function isTop() : bool{ return $this->top; } + + /** @return $this */ + public function setTop(bool $top) : self{ + $this->top = $top; + return $this; + } + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $id = $blockReplace->getSide(Facing::DOWN)->getId(); if(($id === BlockLegacyIds::GRASS or $id === BlockLegacyIds::DIRT) and $blockReplace->getSide(Facing::UP)->canBeReplaced()){ diff --git a/src/block/EndPortalFrame.php b/src/block/EndPortalFrame.php index 254bac34bf..221b206d0c 100644 --- a/src/block/EndPortalFrame.php +++ b/src/block/EndPortalFrame.php @@ -55,6 +55,14 @@ class EndPortalFrame extends Opaque{ return 0b111; } + public function hasEye() : bool{ return $this->eye; } + + /** @return $this */ + public function setEye(bool $eye) : self{ + $this->eye = $eye; + return $this; + } + public function getLightLevel() : int{ return 1; } diff --git a/src/block/Farmland.php b/src/block/Farmland.php index f715f7d815..65a0f77b21 100644 --- a/src/block/Farmland.php +++ b/src/block/Farmland.php @@ -49,6 +49,17 @@ class Farmland extends Transparent{ return 0b111; } + public function getWetness() : int{ return $this->wetness; } + + /** @return $this */ + public function setWetness(int $wetness) : self{ + if($wetness < 0 || $wetness > 7){ + throw new \InvalidArgumentException("Wetness must be in range 0-7"); + } + $this->wetness = $wetness; + return $this; + } + /** * @return AxisAlignedBB[] */ diff --git a/src/block/FenceGate.php b/src/block/FenceGate.php index 5191c3d162..2f97c41058 100644 --- a/src/block/FenceGate.php +++ b/src/block/FenceGate.php @@ -61,6 +61,22 @@ class FenceGate extends Transparent{ return 0b1111; } + public function isOpen() : bool{ return $this->open; } + + /** @return $this */ + public function setOpen(bool $open) : self{ + $this->open = $open; + return $this; + } + + public function isInWall() : bool{ return $this->inWall; } + + /** @return $this */ + public function setInWall(bool $inWall) : self{ + $this->inWall = $inWall; + return $this; + } + /** * @return AxisAlignedBB[] */ diff --git a/src/block/Fire.php b/src/block/Fire.php index 4e31baf826..45f3f8f6ee 100644 --- a/src/block/Fire.php +++ b/src/block/Fire.php @@ -56,6 +56,17 @@ class Fire extends Flowable{ return 0b1111; } + public function getAge() : int{ return $this->age; } + + /** @return $this */ + public function setAge(int $age) : self{ + if($age < 0 || $age > 15){ + throw new \InvalidArgumentException("Age must be in range 0-15"); + } + $this->age = $age; + return $this; + } + public function hasEntityCollision() : bool{ return true; } diff --git a/src/block/FrostedIce.php b/src/block/FrostedIce.php index e28ba84275..70563050a8 100644 --- a/src/block/FrostedIce.php +++ b/src/block/FrostedIce.php @@ -48,6 +48,17 @@ class FrostedIce extends Ice{ return 0b11; } + public function getAge() : int{ return $this->age; } + + /** @return $this */ + public function setAge(int $age) : self{ + if($age < 0 || $age > 3){ + throw new \InvalidArgumentException("Age must be in range 0-3"); + } + $this->age = $age; + return $this; + } + public function onNearbyBlockChange() : void{ if(!$this->checkAdjacentBlocks(2)){ $this->pos->getWorld()->useBreakOn($this->pos); diff --git a/src/block/ItemFrame.php b/src/block/ItemFrame.php index 0ab780480f..3b8a32eba3 100644 --- a/src/block/ItemFrame.php +++ b/src/block/ItemFrame.php @@ -122,6 +122,19 @@ class ItemFrame extends Flowable{ return $this; } + public function hasMap() : bool{ return $this->hasMap; } + + /** + * This can be set irrespective of whether the frame actually contains a map or not. When set, the frame stretches + * to the edges of the block without leaving space around the edges. + * + * @return $this + */ + public function setHasMap(bool $hasMap) : self{ + $this->hasMap = $hasMap; + return $this; + } + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($this->framedItem !== null){ $this->itemRotation = ($this->itemRotation + 1) % self::ROTATIONS; diff --git a/src/block/Lantern.php b/src/block/Lantern.php index 717911544c..aa0a4fe039 100644 --- a/src/block/Lantern.php +++ b/src/block/Lantern.php @@ -48,6 +48,14 @@ class Lantern extends Transparent{ return 0b1; } + public function isHanging() : bool{ return $this->hanging; } + + /** @return $this */ + public function setHanging(bool $hanging) : self{ + $this->hanging = $hanging; + return $this; + } + public function getLightLevel() : int{ return 15; } diff --git a/src/block/Leaves.php b/src/block/Leaves.php index 058cdb5f9f..c9408b0c65 100644 --- a/src/block/Leaves.php +++ b/src/block/Leaves.php @@ -63,6 +63,22 @@ class Leaves extends Transparent{ return 0b1100; } + public function isNoDecay() : bool{ return $this->noDecay; } + + /** @return $this */ + public function setNoDecay(bool $noDecay) : self{ + $this->noDecay = $noDecay; + return $this; + } + + public function isCheckDecay() : bool{ return $this->checkDecay; } + + /** @return $this */ + public function setCheckDecay(bool $checkDecay) : self{ + $this->checkDecay = $checkDecay; + return $this; + } + public function blocksDirectSkyLight() : bool{ return true; } diff --git a/src/block/Liquid.php b/src/block/Liquid.php index 6de3e98d98..1dd1957150 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -84,6 +84,22 @@ abstract class Liquid extends Transparent{ return 0b1111; } + public function isFalling() : bool{ return $this->falling; } + + /** @return $this */ + public function setFalling(bool $falling) : self{ + $this->falling = $falling; + return $this; + } + + public function getDecay() : int{ return $this->decay; } + + /** @return $this */ + public function setDecay(int $decay) : self{ + $this->decay = $decay; + return $this; + } + public function hasEntityCollision() : bool{ return true; } diff --git a/src/block/NetherWartPlant.php b/src/block/NetherWartPlant.php index 7ca38d72f4..5f635f3ad8 100644 --- a/src/block/NetherWartPlant.php +++ b/src/block/NetherWartPlant.php @@ -53,6 +53,17 @@ class NetherWartPlant extends Flowable{ return 0b11; } + public function getAge() : int{ return $this->age; } + + /** @return $this */ + public function setAge(int $age) : self{ + if($age < 0 || $age > 3){ + throw new \InvalidArgumentException("Age must be in range 0-3"); + } + $this->age = $age; + return $this; + } + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === BlockLegacyIds::SOUL_SAND){ diff --git a/src/block/Sapling.php b/src/block/Sapling.php index 8b0e74f542..f9d004de38 100644 --- a/src/block/Sapling.php +++ b/src/block/Sapling.php @@ -58,6 +58,14 @@ class Sapling extends Flowable{ return 0b1000; } + public function isReady() : bool{ return $this->ready; } + + /** @return $this */ + public function setReady(bool $ready) : self{ + $this->ready = $ready; + return $this; + } + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === BlockLegacyIds::GRASS or $down->getId() === BlockLegacyIds::DIRT or $down->getId() === BlockLegacyIds::FARMLAND){ diff --git a/src/block/SeaPickle.php b/src/block/SeaPickle.php index 87edd0cf53..e96beb1313 100644 --- a/src/block/SeaPickle.php +++ b/src/block/SeaPickle.php @@ -52,6 +52,25 @@ class SeaPickle extends Transparent{ return 0b111; } + public function getCount() : int{ return $this->count; } + + /** @return $this */ + public function setCount(int $count) : self{ + if($count < 1 || $count > 4){ + throw new \InvalidArgumentException("Count must be in range 1-4"); + } + $this->count = $count; + return $this; + } + + public function isUnderwater() : bool{ return $this->underwater; } + + /** @return $this */ + public function setUnderwater(bool $underwater) : self{ + $this->underwater = $underwater; + return $this; + } + public function isSolid() : bool{ return false; } diff --git a/src/block/SnowLayer.php b/src/block/SnowLayer.php index 228ebb5f04..1781497ae0 100644 --- a/src/block/SnowLayer.php +++ b/src/block/SnowLayer.php @@ -59,6 +59,17 @@ class SnowLayer extends Flowable implements Fallable{ return 0b111; } + public function getLayers() : int{ return $this->layers; } + + /** @return $this */ + public function setLayers(int $layers) : self{ + if($layers < 1 || $layers > 8){ + throw new \InvalidArgumentException("Layers must be in range 1-8"); + } + $this->layers = $layers; + return $this; + } + public function canBeReplaced() : bool{ return $this->layers < 8; } diff --git a/src/block/Sponge.php b/src/block/Sponge.php index a1328ab69a..dd6491e7a1 100644 --- a/src/block/Sponge.php +++ b/src/block/Sponge.php @@ -47,4 +47,12 @@ class Sponge extends Opaque{ public function getNonPersistentStateBitmask() : int{ return 0; } + + public function isWet() : bool{ return $this->wet; } + + /** @return $this */ + public function setWet(bool $wet) : self{ + $this->wet = $wet; + return $this; + } } diff --git a/src/block/Stair.php b/src/block/Stair.php index c70dc77730..9b477e5141 100644 --- a/src/block/Stair.php +++ b/src/block/Stair.php @@ -73,6 +73,22 @@ class Stair extends Transparent{ } } + public function isUpsideDown() : bool{ return $this->upsideDown; } + + /** @return $this */ + public function setUpsideDown(bool $upsideDown) : self{ + $this->upsideDown = $upsideDown; + return $this; + } + + public function getShape() : StairShape{ return $this->shape; } + + /** @return $this */ + public function setShape(StairShape $shape) : self{ + $this->shape = $shape; + return $this; + } + protected function recalculateCollisionBoxes() : array{ $topStepFace = $this->upsideDown ? Facing::DOWN : Facing::UP; $bbs = [ diff --git a/src/block/Sugarcane.php b/src/block/Sugarcane.php index c87926d8bf..5165e820da 100644 --- a/src/block/Sugarcane.php +++ b/src/block/Sugarcane.php @@ -74,6 +74,17 @@ class Sugarcane extends Flowable{ $this->pos->getWorld()->setBlock($this->pos, $this); } + public function getAge() : int{ return $this->age; } + + /** @return $this */ + public function setAge(int $age) : self{ + if($age < 0 || $age > 15){ + throw new \InvalidArgumentException("Age must be in range 0-15"); + } + $this->age = $age; + return $this; + } + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof Fertilizer){ if(!$this->getSide(Facing::DOWN)->isSameType($this)){ diff --git a/src/block/Trapdoor.php b/src/block/Trapdoor.php index f80593a527..7e82f725bc 100644 --- a/src/block/Trapdoor.php +++ b/src/block/Trapdoor.php @@ -57,6 +57,22 @@ class Trapdoor extends Transparent{ return 0b1111; } + public function isOpen() : bool{ return $this->open; } + + /** @return $this */ + public function setOpen(bool $open) : self{ + $this->open = $open; + return $this; + } + + public function isTop() : bool{ return $this->top; } + + /** @return $this */ + public function setTop(bool $top) : self{ + $this->top = $top; + return $this; + } + /** * @return AxisAlignedBB[] */ diff --git a/src/block/Tripwire.php b/src/block/Tripwire.php index 6aa56ce30d..e1d8c431f1 100644 --- a/src/block/Tripwire.php +++ b/src/block/Tripwire.php @@ -55,4 +55,36 @@ class Tripwire extends Flowable{ public function getStateBitmask() : int{ return 0b1111; } + + public function isTriggered() : bool{ return $this->triggered; } + + /** @return $this */ + public function setTriggered(bool $triggered) : self{ + $this->triggered = $triggered; + return $this; + } + + public function isSuspended() : bool{ return $this->suspended; } + + /** @return $this */ + public function setSuspended(bool $suspended) : self{ + $this->suspended = $suspended; + return $this; + } + + public function isConnected() : bool{ return $this->connected; } + + /** @return $this */ + public function setConnected(bool $connected) : self{ + $this->connected = $connected; + return $this; + } + + public function isDisarmed() : bool{ return $this->disarmed; } + + /** @return $this */ + public function setDisarmed(bool $disarmed) : self{ + $this->disarmed = $disarmed; + return $this; + } } diff --git a/src/block/TripwireHook.php b/src/block/TripwireHook.php index ac1c8df9ae..e7c61c5a0e 100644 --- a/src/block/TripwireHook.php +++ b/src/block/TripwireHook.php @@ -60,6 +60,22 @@ class TripwireHook extends Flowable{ return 0b1111; } + public function isConnected() : bool{ return $this->connected; } + + /** @return $this */ + public function setConnected(bool $connected) : self{ + $this->connected = $connected; + return $this; + } + + public function isPowered() : bool{ return $this->powered; } + + /** @return $this */ + public function setPowered(bool $powered) : self{ + $this->powered = $powered; + return $this; + } + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(Facing::axis($face) !== Axis::Y){ //TODO: check face is valid diff --git a/src/block/utils/PillarRotationTrait.php b/src/block/utils/PillarRotationTrait.php index 7ae8f8cc69..77144c4eb7 100644 --- a/src/block/utils/PillarRotationTrait.php +++ b/src/block/utils/PillarRotationTrait.php @@ -82,6 +82,15 @@ trait PillarRotationTrait{ ][$this->axis] << $this->getAxisMetaShift(); } + /** @see Axis */ + public function getAxis() : int{ return $this->axis; } + + /** @return $this */ + public function setAxis(int $axis) : self{ + $this->axis = $axis; + return $this; + } + /** * @see Block::place() */ From 518a7827a63bed7dd27b8d935367eaef5f2cd441 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Nov 2020 19:28:32 +0000 Subject: [PATCH 2047/3224] BlockFactory: make slab registration slightly less awful to look at --- src/block/BlockFactory.php | 58 +++++++++++++++---------------- src/block/BlockLegacyIdHelper.php | 13 +++++++ 2 files changed, 42 insertions(+), 29 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 6466b8c4db..31b2404d81 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -366,35 +366,35 @@ class BlockFactory{ //TODO: in the future this won't be the same for all the types $stoneSlabBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_BRICK), "Brick", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_COBBLESTONE), "Cobblestone", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_FAKE_WOODEN), "Fake Wooden", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_NETHER_BRICK), "Nether Brick", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_QUARTZ), "Quartz", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_SANDSTONE), "Sandstone", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_SMOOTH_STONE), "Smooth Stone", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB, Meta::STONE_SLAB_STONE_BRICK), "Stone Brick", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_DARK_PRISMARINE), "Dark Prismarine", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_MOSSY_COBBLESTONE), "Mossy Cobblestone", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_PRISMARINE), "Prismarine", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_PRISMARINE_BRICKS), "Prismarine Bricks", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_PURPUR), "Purpur", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_RED_NETHER_BRICK), "Red Nether Brick", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_RED_SANDSTONE), "Red Sandstone", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2, Meta::STONE_SLAB2_SMOOTH_SANDSTONE), "Smooth Sandstone", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_ANDESITE), "Andesite", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_DIORITE), "Diorite", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_END_STONE_BRICK), "End Stone Brick", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_GRANITE), "Granite", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_POLISHED_ANDESITE), "Polished Andesite", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_POLISHED_DIORITE), "Polished Diorite", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_POLISHED_GRANITE), "Polished Granite", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3, Meta::STONE_SLAB3_SMOOTH_RED_SANDSTONE), "Smooth Red Sandstone", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_CUT_RED_SANDSTONE), "Cut Red Sandstone", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_CUT_SANDSTONE), "Cut Sandstone", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_MOSSY_STONE_BRICK), "Mossy Stone Brick", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_SMOOTH_QUARTZ), "Smooth Quartz", $stoneSlabBreakInfo)); - $this->register(new Slab(new BIDFlattened(Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4, Meta::STONE_SLAB4_STONE), "Stone", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_BRICK), "Brick", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_COBBLESTONE), "Cobblestone", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_FAKE_WOODEN), "Fake Wooden", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_NETHER_BRICK), "Nether Brick", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_QUARTZ), "Quartz", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_SANDSTONE), "Sandstone", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_SMOOTH_STONE), "Smooth Stone", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_STONE_BRICK), "Stone Brick", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_DARK_PRISMARINE), "Dark Prismarine", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_MOSSY_COBBLESTONE), "Mossy Cobblestone", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_PRISMARINE), "Prismarine", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_PRISMARINE_BRICKS), "Prismarine Bricks", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_PURPUR), "Purpur", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_RED_NETHER_BRICK), "Red Nether Brick", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_RED_SANDSTONE), "Red Sandstone", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_SMOOTH_SANDSTONE), "Smooth Sandstone", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_ANDESITE), "Andesite", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_DIORITE), "Diorite", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_END_STONE_BRICK), "End Stone Brick", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_GRANITE), "Granite", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_POLISHED_ANDESITE), "Polished Andesite", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_POLISHED_DIORITE), "Polished Diorite", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_POLISHED_GRANITE), "Polished Granite", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_SMOOTH_RED_SANDSTONE), "Smooth Red Sandstone", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_CUT_RED_SANDSTONE), "Cut Red Sandstone", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_CUT_SANDSTONE), "Cut Sandstone", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_MOSSY_STONE_BRICK), "Mossy Stone Brick", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_SMOOTH_QUARTZ), "Smooth Quartz", $stoneSlabBreakInfo)); + $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_STONE), "Stone", $stoneSlabBreakInfo)); $this->register(new Opaque(new BID(Ids::STONECUTTER), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); $this->register(new Sugarcane(new BID(Ids::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane")); $this->register(new TNT(new BID(Ids::TNT), "TNT")); diff --git a/src/block/BlockLegacyIdHelper.php b/src/block/BlockLegacyIdHelper.php index 3bd806b146..2b32e56f73 100644 --- a/src/block/BlockLegacyIdHelper.php +++ b/src/block/BlockLegacyIdHelper.php @@ -214,4 +214,17 @@ final class BlockLegacyIdHelper{ } throw new AssumptionFailedError("Switch should cover all colours"); } + + public static function getStoneSlabIdentifier(int $stoneSlabId, int $meta) : BlockIdentifierFlattened{ + $id = [ + 1 => [Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB], + 2 => [Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2], + 3 => [Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3], + 4 => [Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4] + ][$stoneSlabId] ?? null; + if($id === null){ + throw new \InvalidArgumentException("Stone slab type should be 1, 2, 3 or 4"); + } + return new BlockIdentifierFlattened($id[0], $id[1], $meta); + } } From 142102a054b5cdd9e870051c081e397159cd01f0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Nov 2020 19:44:57 +0000 Subject: [PATCH 2048/3224] ItemFactory: remap bucket:9 and bucket:11 to their appropriate counterparts --- src/item/ItemFactory.php | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 999b57e761..74364bc2e0 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -190,10 +190,14 @@ class ItemFactory{ $this->register(new ItemBlock(new ItemIdentifier(ItemIds::REPEATER, 0), VanillaBlocks::REDSTONE_REPEATER())); $this->register(new ItemBlock(new ItemIdentifier(ItemIds::SPRUCE_DOOR, 0), VanillaBlocks::SPRUCE_DOOR())); $this->register(new ItemBlock(new ItemIdentifier(ItemIds::SUGARCANE, 0), VanillaBlocks::SUGARCANE())); - //TODO: fix metadata for buckets with still liquid in them - //the meta values are intentionally hardcoded because block IDs will change in the future - $this->register(new LiquidBucket(new ItemIdentifier(ItemIds::BUCKET, 8), "Water Bucket", VanillaBlocks::WATER())); - $this->register(new LiquidBucket(new ItemIdentifier(ItemIds::BUCKET, 10), "Lava Bucket", VanillaBlocks::LAVA())); + + //the meta values for buckets are intentionally hardcoded because block IDs will change in the future + $waterBucket = new LiquidBucket(new ItemIdentifier(ItemIds::BUCKET, 8), "Water Bucket", VanillaBlocks::WATER()); + $this->register($waterBucket); + $this->remap(new ItemIdentifier(ItemIds::BUCKET, 9), $waterBucket); + $lavaBucket = new LiquidBucket(new ItemIdentifier(ItemIds::BUCKET, 10), "Lava Bucket", VanillaBlocks::LAVA()); + $this->register($lavaBucket); + $this->remap(new ItemIdentifier(ItemIds::BUCKET, 11), $lavaBucket); $this->register(new Melon(new ItemIdentifier(ItemIds::MELON, 0), "Melon")); $this->register(new MelonSeeds(new ItemIdentifier(ItemIds::MELON_SEEDS, 0), "Melon Seeds")); $this->register(new MilkBucket(new ItemIdentifier(ItemIds::BUCKET, 1), "Milk Bucket")); @@ -411,6 +415,14 @@ class ItemFactory{ $this->list[self::getListOffset($id, $variant)] = clone $item; } + public function remap(ItemIdentifier $identifier, Item $item, bool $override = false) : void{ + if(!$override && $this->isRegistered($identifier->getId(), $identifier->getMeta())){ + throw new \RuntimeException("Trying to overwrite an already registered item"); + } + + $this->list[self::getListOffset($identifier->getId(), $identifier->getMeta())] = clone $item; + } + /** * Returns an instance of the Item with the specified id, meta, count and NBT. * From 72ace3951e33075f63ef31f548901e9350ef0c6d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Nov 2020 22:56:20 +0000 Subject: [PATCH 2049/3224] InGamePacketHandler: fixed crafting table breaking when clicked while sneaking --- src/network/mcpe/handler/InGamePacketHandler.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 1c253d90eb..ccb9c9f37a 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -24,9 +24,9 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; use pocketmine\block\BaseSign; -use pocketmine\block\BlockLegacyIds; use pocketmine\block\ItemFrame; use pocketmine\block\utils\SignText; +use pocketmine\crafting\CraftingGrid; use pocketmine\entity\animation\ConsumingItemAnimation; use pocketmine\entity\InvalidSkinException; use pocketmine\event\player\PlayerEditBookEvent; @@ -339,8 +339,8 @@ class InGamePacketHandler extends PacketHandler{ if(!$this->player->interactBlock($blockPos, $data->getFace(), $clickPos)){ $this->onFailedBlockAction($blockPos, $data->getFace()); }elseif( - $this->player->getWorld()->getBlock($blockPos)->getId() === BlockLegacyIds::CRAFTING_TABLE && - !array_key_exists($windowId = InventoryManager::HARDCODED_CRAFTING_GRID_WINDOW_ID, $this->openHardcodedWindows) + !array_key_exists($windowId = InventoryManager::HARDCODED_CRAFTING_GRID_WINDOW_ID, $this->openHardcodedWindows) && + $this->player->getCraftingGrid()->getGridWidth() === CraftingGrid::SIZE_BIG ){ //TODO: HACK! crafting grid doesn't fit very well into the current PM container system, so this hack //allows it to carry on working approximately the same way as it did in 1.14 From 8762d445061d48444ee2ab88449db35f58c7cbe4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Nov 2020 17:50:16 +0000 Subject: [PATCH 2050/3224] World: skip lighting updates on chunks which are not yet light populated --- src/world/World.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index ae6edce2eb..9bca29e896 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1215,6 +1215,11 @@ class World implements ChunkManager{ } public function updateAllLight(int $x, int $y, int $z) : void{ + if(($chunk = $this->getChunk($x >> 4, $z >> 4)) === null || $chunk->isLightPopulated() !== true){ + $this->logger->debug("Skipped runtime light update of x=$x,y=$y,z=$z because the target area has not received base light calculation"); + return; + } + $blockFactory = BlockFactory::getInstance(); $this->timings->doBlockSkyLightUpdates->startTiming(); if($this->skyLightUpdate === null){ From 058a3b3fa6e8d3021d3463bcff464305d8996dc4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 5 Nov 2020 14:28:36 +0000 Subject: [PATCH 2051/3224] relocate some world-specific logic from Chunk to World --- src/world/World.php | 52 +++++++++++++++++++++++++++++++++- src/world/format/Chunk.php | 58 ++------------------------------------ 2 files changed, 53 insertions(+), 57 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 9bca29e896..c162a7bf50 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -32,10 +32,12 @@ use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; use pocketmine\block\tile\Spawnable; use pocketmine\block\tile\Tile; +use pocketmine\block\tile\TileFactory; use pocketmine\block\UnknownBlock; use pocketmine\block\VanillaBlocks; use pocketmine\data\bedrock\BiomeIds; use pocketmine\entity\Entity; +use pocketmine\entity\EntityFactory; use pocketmine\entity\Location; use pocketmine\entity\object\ExperienceOrb; use pocketmine\entity\object\ItemEntity; @@ -54,6 +56,8 @@ use pocketmine\item\ItemUseResult; use pocketmine\item\LegacyStringToItemParser; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; +use pocketmine\nbt\tag\IntTag; +use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\BlockActorDataPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; @@ -2245,7 +2249,7 @@ class World implements ChunkManager{ $this->chunks[$chunkHash] = $chunk; unset($this->blockCache[$chunkHash]); - $chunk->initChunk($this); + $this->initChunk($chunk); (new ChunkLoadEvent($this, $chunk, !$chunk->isGenerated()))->call(); @@ -2262,6 +2266,52 @@ class World implements ChunkManager{ return true; } + private function initChunk(Chunk $chunk) : void{ + if($chunk->NBTentities !== null){ + $chunk->setDirtyFlag(Chunk::DIRTY_FLAG_ENTITIES, true); + $this->timings->syncChunkLoadEntitiesTimer->startTiming(); + $entityFactory = EntityFactory::getInstance(); + foreach($chunk->NBTentities as $nbt){ + try{ + $entity = $entityFactory->createFromData($this, $nbt); + if(!($entity instanceof Entity)){ + $saveIdTag = $nbt->getTag("id") ?? $nbt->getTag("identifier"); + $saveId = ""; + if($saveIdTag instanceof StringTag){ + $saveId = $saveIdTag->getValue(); + }elseif($saveIdTag instanceof IntTag){ //legacy MCPE format + $saveId = "legacy(" . $saveIdTag->getValue() . ")"; + } + $this->getLogger()->warning("Chunk " . $chunk->getX() . " " . $chunk->getZ() . ": Deleted unknown entity type $saveId"); + continue; + } + }catch(\Exception $t){ //TODO: this shouldn't be here + $this->getLogger()->logException($t); + continue; + } + } + + $chunk->NBTentities = null; + $this->timings->syncChunkLoadEntitiesTimer->stopTiming(); + } + if($chunk->NBTtiles !== null){ + $chunk->setDirtyFlag(Chunk::DIRTY_FLAG_TILES, true); + $this->timings->syncChunkLoadTileEntitiesTimer->startTiming(); + $tileFactory = TileFactory::getInstance(); + foreach($chunk->NBTtiles as $nbt){ + if(($tile = $tileFactory->createFromData($this, $nbt)) !== null){ + $this->addTile($tile); + }else{ + $this->getLogger()->warning("Chunk " . $chunk->getX() . " " . $chunk->getZ() . ": Deleted unknown tile entity type " . $nbt->getString("id", "")); + continue; + } + } + + $chunk->NBTtiles = null; + $this->timings->syncChunkLoadTileEntitiesTimer->stopTiming(); + } + } + private function queueUnloadChunk(int $x, int $z) : void{ $this->unloadQueue[World::chunkHash($x, $z)] = microtime(true); } diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 1c7fab7f43..c18dc06542 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -28,15 +28,10 @@ namespace pocketmine\world\format; use pocketmine\block\BlockLegacyIds; use pocketmine\block\tile\Tile; -use pocketmine\block\tile\TileFactory; use pocketmine\data\bedrock\BiomeIds; use pocketmine\entity\Entity; -use pocketmine\entity\EntityFactory; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\IntTag; -use pocketmine\nbt\tag\StringTag; use pocketmine\player\Player; -use pocketmine\world\World; use function array_fill; use function array_filter; use function array_map; @@ -84,10 +79,10 @@ class Chunk{ protected $biomeIds; /** @var CompoundTag[]|null */ - protected $NBTtiles; + public $NBTtiles; /** @var CompoundTag[]|null */ - protected $NBTentities; + public $NBTentities; /** * @param SubChunk[] $subChunks @@ -345,55 +340,6 @@ class Chunk{ return $this->NBTentities ?? array_map(function(Entity $entity) : CompoundTag{ return $entity->saveNBT(); }, $this->getSavableEntities()); } - /** - * Deserializes tiles and entities from NBT - */ - public function initChunk(World $world) : void{ - if($this->NBTentities !== null){ - $this->dirtyFlags |= self::DIRTY_FLAG_ENTITIES; - $world->timings->syncChunkLoadEntitiesTimer->startTiming(); - $entityFactory = EntityFactory::getInstance(); - foreach($this->NBTentities as $nbt){ - try{ - $entity = $entityFactory->createFromData($world, $nbt); - if(!($entity instanceof Entity)){ - $saveIdTag = $nbt->getTag("id") ?? $nbt->getTag("identifier"); - $saveId = ""; - if($saveIdTag instanceof StringTag){ - $saveId = $saveIdTag->getValue(); - }elseif($saveIdTag instanceof IntTag){ //legacy MCPE format - $saveId = "legacy(" . $saveIdTag->getValue() . ")"; - } - $world->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown entity type $saveId"); - continue; - } - }catch(\Exception $t){ //TODO: this shouldn't be here - $world->getLogger()->logException($t); - continue; - } - } - - $this->NBTentities = null; - $world->timings->syncChunkLoadEntitiesTimer->stopTiming(); - } - if($this->NBTtiles !== null){ - $this->dirtyFlags |= self::DIRTY_FLAG_TILES; - $world->timings->syncChunkLoadTileEntitiesTimer->startTiming(); - $tileFactory = TileFactory::getInstance(); - foreach($this->NBTtiles as $nbt){ - if(($tile = $tileFactory->createFromData($world, $nbt)) !== null){ - $world->addTile($tile); - }else{ - $world->getLogger()->warning("Chunk $this->x $this->z: Deleted unknown tile entity type " . $nbt->getString("id", "")); - continue; - } - } - - $this->NBTtiles = null; - $world->timings->syncChunkLoadTileEntitiesTimer->stopTiming(); - } - } - public function getBiomeIdArray() : string{ return $this->biomeIds->getData(); } From 4b46549cd1f897c420209452bbd069af000a943c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 5 Nov 2020 14:35:23 +0000 Subject: [PATCH 2052/3224] fix PHPStan failure setDirtyFlag has a void return type, so PHPStan assumes it's non-pure and invalidates the type info. --- src/world/World.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index c162a7bf50..86152574ed 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2268,7 +2268,6 @@ class World implements ChunkManager{ private function initChunk(Chunk $chunk) : void{ if($chunk->NBTentities !== null){ - $chunk->setDirtyFlag(Chunk::DIRTY_FLAG_ENTITIES, true); $this->timings->syncChunkLoadEntitiesTimer->startTiming(); $entityFactory = EntityFactory::getInstance(); foreach($chunk->NBTentities as $nbt){ @@ -2291,11 +2290,11 @@ class World implements ChunkManager{ } } + $chunk->setDirtyFlag(Chunk::DIRTY_FLAG_ENTITIES, true); $chunk->NBTentities = null; $this->timings->syncChunkLoadEntitiesTimer->stopTiming(); } if($chunk->NBTtiles !== null){ - $chunk->setDirtyFlag(Chunk::DIRTY_FLAG_TILES, true); $this->timings->syncChunkLoadTileEntitiesTimer->startTiming(); $tileFactory = TileFactory::getInstance(); foreach($chunk->NBTtiles as $nbt){ @@ -2307,6 +2306,7 @@ class World implements ChunkManager{ } } + $chunk->setDirtyFlag(Chunk::DIRTY_FLAG_TILES, true); $chunk->NBTtiles = null; $this->timings->syncChunkLoadTileEntitiesTimer->stopTiming(); } From e6348bbd34242e5a032281cb7d0a41f008fde80c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 5 Nov 2020 15:01:57 +0000 Subject: [PATCH 2053/3224] Entity: do not assume that save IDs are always strings this is only the first of many changes needed to make entity savedata fully format-agnostic, but it's a start. --- src/entity/Entity.php | 2 +- src/entity/EntityFactory.php | 8 ++++++++ tests/phpstan/configs/l7-baseline.neon | 5 +++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 4f971bd555..adfb5b7562 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -473,7 +473,7 @@ abstract class Entity{ $nbt = EntityDataHelper::createBaseNBT($this->location, $this->motion, $this->location->yaw, $this->location->pitch); if(!($this instanceof Player)){ - $nbt->setString("id", EntityFactory::getInstance()->getSaveId(get_class($this))); + EntityFactory::getInstance()->injectSaveId(get_class($this), $nbt); if($this->getNameTag() !== ""){ $nbt->setString("CustomName", $this->getNameTag()); diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index ad9c2e510f..ee04566925 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -227,6 +227,14 @@ final class EntityFactory{ return $entity; } + public function injectSaveId(string $class, CompoundTag $saveData) : void{ + if(isset($this->saveNames[$class])){ + $saveData->setTag("id", new StringTag(reset($this->saveNames[$class]))); + }else{ + throw new \InvalidArgumentException("Entity $class is not registered"); + } + } + /** * @phpstan-param class-string $class */ diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index 85e86f2f8d..3558ec9f2c 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -530,6 +530,11 @@ parameters: count: 1 path: ../../../src/data/bedrock/LegacyToStringBidirectionalIdMap.php + - + message: "#^Parameter \\#1 \\$value of class pocketmine\\\\nbt\\\\tag\\\\StringTag constructor expects string, string\\|false given\\.$#" + count: 1 + path: ../../../src/entity/EntityFactory.php + - message: "#^Method pocketmine\\\\entity\\\\EntityFactory\\:\\:getSaveId\\(\\) should return string but returns string\\|false\\.$#" count: 1 From 3aa902ff779464d8833dc202fa8075b514e18657 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 6 Nov 2020 13:07:28 +0000 Subject: [PATCH 2054/3224] Updated composer dependencies --- composer.lock | 62 +++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/composer.lock b/composer.lock index 578e348a28..9eff808489 100644 --- a/composer.lock +++ b/composer.lock @@ -1698,23 +1698,23 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.0", + "version": "9.2.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "53a4b737e83be724efd2bc4e7b929b9a30c48972" + "reference": "6b20e2055f7c29b56cb3870b3de7cc463d7add41" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/53a4b737e83be724efd2bc4e7b929b9a30c48972", - "reference": "53a4b737e83be724efd2bc4e7b929b9a30c48972", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6b20e2055f7c29b56cb3870b3de7cc463d7add41", + "reference": "6b20e2055f7c29b56cb3870b3de7cc463d7add41", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.8", + "nikic/php-parser": "^4.10.2", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -1763,7 +1763,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.0" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.3" }, "funding": [ { @@ -1771,7 +1771,7 @@ "type": "github" } ], - "time": "2020-10-02T03:37:32+00:00" + "time": "2020-10-30T10:46:41+00:00" }, { "name": "phpunit/php-file-iterator", @@ -2286,16 +2286,16 @@ }, { "name": "sebastian/comparator", - "version": "4.0.5", + "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "7a8ff306445707539c1a6397372a982a1ec55120" + "reference": "55f4261989e546dc112258c7a75935a81a7ce382" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/7a8ff306445707539c1a6397372a982a1ec55120", - "reference": "7a8ff306445707539c1a6397372a982a1ec55120", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", + "reference": "55f4261989e546dc112258c7a75935a81a7ce382", "shasum": "" }, "require": { @@ -2348,7 +2348,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.5" + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" }, "funding": [ { @@ -2356,20 +2356,20 @@ "type": "github" } ], - "time": "2020-09-30T06:47:25+00:00" + "time": "2020-10-26T15:49:45+00:00" }, { "name": "sebastian/complexity", - "version": "2.0.1", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "ba8cc2da0c0bfbc813d03b56406734030c7f1eff" + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ba8cc2da0c0bfbc813d03b56406734030c7f1eff", - "reference": "ba8cc2da0c0bfbc813d03b56406734030c7f1eff", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", "shasum": "" }, "require": { @@ -2405,7 +2405,7 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.1" + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" }, "funding": [ { @@ -2413,7 +2413,7 @@ "type": "github" } ], - "time": "2020-09-28T06:05:03+00:00" + "time": "2020-10-26T15:52:27+00:00" }, { "name": "sebastian/diff", @@ -2623,16 +2623,16 @@ }, { "name": "sebastian/global-state", - "version": "5.0.1", + "version": "5.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "ea779cb749a478b22a2564ac41cd7bda79c78dc7" + "reference": "a90ccbddffa067b51f574dea6eb25d5680839455" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/ea779cb749a478b22a2564ac41cd7bda79c78dc7", - "reference": "ea779cb749a478b22a2564ac41cd7bda79c78dc7", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/a90ccbddffa067b51f574dea6eb25d5680839455", + "reference": "a90ccbddffa067b51f574dea6eb25d5680839455", "shasum": "" }, "require": { @@ -2675,7 +2675,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.1" + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.2" }, "funding": [ { @@ -2683,20 +2683,20 @@ "type": "github" } ], - "time": "2020-09-28T05:54:06+00:00" + "time": "2020-10-26T15:55:19+00:00" }, { "name": "sebastian/lines-of-code", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "6514b8f21906b8b46f520d1fbd17a4523fa59a54" + "reference": "acf76492a65401babcf5283296fa510782783a7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/6514b8f21906b8b46f520d1fbd17a4523fa59a54", - "reference": "6514b8f21906b8b46f520d1fbd17a4523fa59a54", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/acf76492a65401babcf5283296fa510782783a7a", + "reference": "acf76492a65401babcf5283296fa510782783a7a", "shasum": "" }, "require": { @@ -2732,7 +2732,7 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.1" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.2" }, "funding": [ { @@ -2740,7 +2740,7 @@ "type": "github" } ], - "time": "2020-09-28T06:07:27+00:00" + "time": "2020-10-26T17:03:56+00:00" }, { "name": "sebastian/object-enumerator", From 528726068e021b9306e424c72d6792657aeab612 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 6 Nov 2020 13:09:04 +0000 Subject: [PATCH 2055/3224] phpstan 0.12.54 --- composer.json | 2 +- composer.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index 9e06eb09b8..a880d5245a 100644 --- a/composer.json +++ b/composer.json @@ -51,7 +51,7 @@ "composer-runtime-api": "^2.0" }, "require-dev": { - "phpstan/phpstan": "0.12.51", + "phpstan/phpstan": "0.12.54", "phpstan/phpstan-phpunit": "^0.12.6", "phpstan/phpstan-strict-rules": "^0.12.2", "phpunit/phpunit": "^9.2" diff --git a/composer.lock b/composer.lock index 9eff808489..4d206763b7 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b10d217d35fdd27c553e2b98ffff747c", + "content-hash": "2ebc35f61a45aaa7bb3e6185b6bfbf90", "packages": [ { "name": "adhocore/json-comment", @@ -1523,16 +1523,16 @@ }, { "name": "phpstan/phpstan", - "version": "0.12.51", + "version": "0.12.54", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "b430527cd7b956324bcd554fb85a5e2fd43177d6" + "reference": "45c7b999a4b7dd9ac5558bdaaf23dcebbef88223" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/b430527cd7b956324bcd554fb85a5e2fd43177d6", - "reference": "b430527cd7b956324bcd554fb85a5e2fd43177d6", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/45c7b999a4b7dd9ac5558bdaaf23dcebbef88223", + "reference": "45c7b999a4b7dd9ac5558bdaaf23dcebbef88223", "shasum": "" }, "require": { @@ -1563,7 +1563,7 @@ "description": "PHPStan - PHP Static Analysis Tool", "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/0.12.51" + "source": "https://github.com/phpstan/phpstan/tree/0.12.54" }, "funding": [ { @@ -1579,7 +1579,7 @@ "type": "tidelift" } ], - "time": "2020-10-23T11:58:04+00:00" + "time": "2020-11-05T13:36:26+00:00" }, { "name": "phpstan/phpstan-phpunit", From b059e0b475b50db0fb2a47df4a7a0bbb3e400555 Mon Sep 17 00:00:00 2001 From: David <30806420+davidgamingzz@users.noreply.github.com> Date: Fri, 6 Nov 2020 20:25:37 -0500 Subject: [PATCH 2056/3224] Item: fixed wrong tag being removed during serialization of custom name (#3894) --- src/item/Item.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/item/Item.php b/src/item/Item.php index 10f270cce8..14c10a5703 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -317,7 +317,7 @@ class Item implements \JsonSerializable{ $this->hasCustomName() ? $display->setString(self::TAG_DISPLAY_NAME, $this->getCustomName()) : - $display->removeTag(self::TAG_DISPLAY); + $display->removeTag(self::TAG_DISPLAY_NAME); if(count($this->lore) > 0){ $loreTag = new ListTag(); From ffff0a6244264dd0132228ab95599a42eb44018e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 8 Nov 2020 13:31:07 +0000 Subject: [PATCH 2057/3224] NetworkSession: remove obsolete TODO --- src/network/mcpe/NetworkSession.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 51be7de817..1307e372fe 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -326,7 +326,6 @@ class NetworkSession{ $stream = new PacketBatch($this->compressor->decompress($payload)); }catch(DecompressionException $e){ $this->logger->debug("Failed to decompress packet: " . base64_encode($payload)); - //TODO: this isn't incompatible game version if we already established protocol version throw BadPacketException::wrap($e, "Compressed packet batch decode error"); }finally{ Timings::$playerNetworkReceiveDecompressTimer->stopTiming(); From 4ae7efbfbca7772751e5255e6a54971044bf66a2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 8 Nov 2020 14:02:58 +0000 Subject: [PATCH 2058/3224] [ci skip] add some documentation to Player internals --- src/player/Player.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/player/Player.php b/src/player/Player.php index 8ae7ac732e..2a5371ab94 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -756,6 +756,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } } + /** + * Requests chunks from the world to be sent, up to a set limit every tick. This operates on the results of the most recent chunk + * order. + */ protected function requestChunks() : void{ if(!$this->isConnected()){ return; @@ -809,6 +813,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ Timings::$playerChunkSendTimer->stopTiming(); } + /** + * Called by the network system when the pre-spawn sequence is completed (e.g. after sending spawn chunks). + * This fires join events and broadcasts join messages to other online players. + */ public function doFirstSpawn() : void{ if($this->spawned){ return; @@ -844,6 +852,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } } + /** + * Calculates which new chunks this player needs to use, and which currently-used chunks it needs to stop using. + * This is based on factors including the player's current render radius and current position. + */ protected function orderChunks() : void{ if(!$this->isConnected() or $this->viewDistance === -1){ return; @@ -879,15 +891,25 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ Timings::$playerChunkOrderTimer->stopTiming(); } + /** + * Returns whether the player is using the chunk with the given coordinates, irrespective of whether the chunk has + * been sent yet. + */ public function isUsingChunk(int $chunkX, int $chunkZ) : bool{ return isset($this->usedChunks[World::chunkHash($chunkX, $chunkZ)]); } + /** + * Returns whether the target chunk has been sent to this player. + */ public function hasReceivedChunk(int $chunkX, int $chunkZ) : bool{ $status = $this->usedChunks[World::chunkHash($chunkX, $chunkZ)] ?? null; return $status !== null and $status->equals(UsedChunkStatus::SENT()); } + /** + * Ticks the chunk-requesting mechanism. + */ public function doChunkRequests() : void{ if($this->nextChunkOrderRun !== PHP_INT_MAX and $this->nextChunkOrderRun-- <= 0){ $this->nextChunkOrderRun = PHP_INT_MAX; From 64afb6f2e2d14403e606f8ef3ab3d391064ac89b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 8 Nov 2020 14:14:43 +0000 Subject: [PATCH 2059/3224] Move responsibility of firing chunk requests from World to NetworkSession this is, after all, all about sending chunks ... --- src/network/mcpe/NetworkSession.php | 6 +++++- src/world/World.php | 4 ---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 1307e372fe..04f1fc92ad 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -956,8 +956,12 @@ class NetworkSession{ return true; //keep ticking until timeout } + if($this->player !== null){ + $this->player->doChunkRequests(); + } + $this->flushSendBuffer(); - return false; + return true; } } diff --git a/src/world/World.php b/src/world/World.php index 86152574ed..c837c77b83 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -810,10 +810,6 @@ class World implements ChunkManager{ } - foreach($this->players as $p){ - $p->doChunkRequests(); - } - if($this->sleepTicks > 0 and --$this->sleepTicks <= 0){ $this->checkSleep(); } From f43d20b47aec91f1ea6136f9ad01bb5777f83a65 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 8 Nov 2020 14:15:11 +0000 Subject: [PATCH 2060/3224] Move attribute net sync to NetworkSession --- src/network/mcpe/NetworkSession.php | 8 ++++++++ src/player/Player.php | 7 ------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 04f1fc92ad..60b97b209e 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -958,6 +958,14 @@ class NetworkSession{ if($this->player !== null){ $this->player->doChunkRequests(); + + $dirtyAttributes = $this->player->getAttributeMap()->needSend(); + $this->syncAttributes($this->player, $dirtyAttributes); + foreach($dirtyAttributes as $attribute){ + //TODO: we might need to send these to other players in the future + //if that happens, this will need to become more complex than a flag on the attribute itself + $attribute->markSynchronized(); + } } $this->flushSendBuffer(); diff --git a/src/player/Player.php b/src/player/Player.php index 2a5371ab94..1976dedb53 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1322,13 +1322,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->lastUpdate = $currentTick; - //TODO: move this to network session ticking (this is specifically related to net sync) - $dirtyAttributes = $this->attributeMap->needSend(); - $this->networkSession->syncAttributes($this, $dirtyAttributes); - foreach($dirtyAttributes as $attribute){ - $attribute->markSynchronized(); - } - if(!$this->isAlive() and $this->spawned){ $this->onDeathUpdate($tickDiff); return true; From 4e91009492272b0eefae0ae0813ca115fb62fff5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 9 Nov 2020 12:47:36 +0000 Subject: [PATCH 2061/3224] Armor: fixed equipping when right-clicking air instead of a block this action (which is more accurately referred to as 'activate item' or 'use item' in other areas) always fires on right-click when holding any item, whether aiming at a block or not. --- src/item/Armor.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/item/Armor.php b/src/item/Armor.php index a3e235ded5..804763e656 100644 --- a/src/item/Armor.php +++ b/src/item/Armor.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\block\Block; use pocketmine\color\Color; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\inventory\ArmorInventory; @@ -122,7 +121,7 @@ class Armor extends Durable{ return 0; } - public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ + public function onClickAir(Player $player, Vector3 $directionVector) : ItemUseResult{ $existing = $player->getArmorInventory()->getItem($this->getArmorSlot()); if(!$existing->isNull()){ return ItemUseResult::FAIL(); From 3c6a64f91b8e5c8d8c727fc57953c39365532128 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 9 Nov 2020 13:32:12 +0000 Subject: [PATCH 2062/3224] Fixed armour equipment logic, close #3896 this isn't perfect because the client expects to be the boss here and is also inconsistent. --- src/item/Armor.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/item/Armor.php b/src/item/Armor.php index 804763e656..2838982722 100644 --- a/src/item/Armor.php +++ b/src/item/Armor.php @@ -123,10 +123,13 @@ class Armor extends Durable{ public function onClickAir(Player $player, Vector3 $directionVector) : ItemUseResult{ $existing = $player->getArmorInventory()->getItem($this->getArmorSlot()); - if(!$existing->isNull()){ - return ItemUseResult::FAIL(); - } $player->getArmorInventory()->setItem($this->getArmorSlot(), $this->pop()); + if($this->getCount() === 0){ + $player->getInventory()->setItemInHand($existing); + }else{ //if the stack size was bigger than 1 (usually won't happen, but might be caused by plugins + $player->getInventory()->setItemInHand($this); + $player->getInventory()->addItem($existing); + } return ItemUseResult::SUCCESS(); } From 66955d4b9934f4fa1221dca09b1cddf836af3abb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 9 Nov 2020 13:41:46 +0000 Subject: [PATCH 2063/3224] World: make loadChunk() more useful, drop useless proxy function getOrLoadChunk() --- src/entity/Entity.php | 2 +- src/world/World.php | 53 ++++++++++++++++--------------------------- 2 files changed, 20 insertions(+), 35 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index adfb5b7562..a9fcba9f16 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1358,7 +1358,7 @@ abstract class Entity{ if($this->chunk !== null){ $this->chunk->removeEntity($this); } - $this->chunk = $this->getWorld()->getOrLoadChunk($chunkX, $chunkZ, true); + $this->chunk = $this->getWorld()->loadChunk($chunkX, $chunkZ, true); $this->chunkX = $chunkX; $this->chunkZ = $chunkZ; diff --git a/src/world/World.php b/src/world/World.php index c837c77b83..4d15d8a1ee 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1411,7 +1411,7 @@ class World implements ChunkManager{ if($this->isChunkLocked($chunkX, $chunkZ)){ throw new WorldException("Terrain is locked for generation/population"); } - if(!$this->loadChunk($chunkX, $chunkZ, false)){ //current expected behaviour is to try to load the terrain synchronously + if($this->loadChunk($chunkX, $chunkZ, false) === null){ //current expected behaviour is to try to load the terrain synchronously throw new WorldException("Cannot set a block in un-generated terrain"); } @@ -1852,7 +1852,7 @@ class World implements ChunkManager{ * Returns the tile at the specified x,y,z coordinates, or null if it does not exist. */ public function getTileAt(int $x, int $y, int $z) : ?Tile{ - return ($chunk = $this->getOrLoadChunk($x >> 4, $z >> 4, false)) !== null ? $chunk->getTile($x & 0x0f, $y, $z & 0x0f) : null; + return ($chunk = $this->loadChunk($x >> 4, $z >> 4, false)) !== null ? $chunk->getTile($x & 0x0f, $y, $z & 0x0f) : null; } /** @@ -1886,7 +1886,7 @@ class World implements ChunkManager{ } public function getBiomeId(int $x, int $z) : int{ - if(($chunk = $this->getOrLoadChunk($x >> 4, $z >> 4, false)) !== null){ + if(($chunk = $this->loadChunk($x >> 4, $z >> 4, false)) !== null){ return $chunk->getBiomeId($x & 0x0f, $z & 0x0f); } return BiomeIds::OCEAN; //TODO: this should probably throw instead (terrain not generated yet) @@ -1903,7 +1903,7 @@ class World implements ChunkManager{ //the changes would be overwritten when the generation finishes throw new WorldException("Chunk is currently locked for async generation/population"); } - if(($chunk = $this->getOrLoadChunk($chunkX, $chunkZ, false)) !== null){ + if(($chunk = $this->loadChunk($chunkX, $chunkZ, false)) !== null){ $chunk->setBiomeId($x & 0x0f, $z & 0x0f, $biomeId); }else{ //if we allowed this, the modifications would be lost when the chunk is created @@ -1918,22 +1918,6 @@ class World implements ChunkManager{ return $this->chunks; } - /** - * Returns the chunk at the specified X/Z coordinates. If the chunk is not loaded, attempts to (synchronously!!!) - * load it. - * - * @param bool $create Whether to create an empty chunk as a placeholder if the chunk does not exist - */ - public function getOrLoadChunk(int $chunkX, int $chunkZ, bool $create) : ?Chunk{ - if(isset($this->chunks[$index = World::chunkHash($chunkX, $chunkZ)])){ - return $this->chunks[$index]; - }elseif($this->loadChunk($chunkX, $chunkZ, $create)){ - return $this->chunks[$index]; - } - - return null; - } - public function getChunk(int $chunkX, int $chunkZ) : ?Chunk{ return $this->chunks[World::chunkHash($chunkX, $chunkZ)] ?? null; } @@ -1942,7 +1926,7 @@ class World implements ChunkManager{ * Returns the chunk containing the given Vector3 position. */ public function getOrLoadChunkAtPosition(Vector3 $pos, bool $create = false) : ?Chunk{ - return $this->getOrLoadChunk($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4, $create); + return $this->loadChunk($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4, $create); } /** @@ -1958,7 +1942,7 @@ class World implements ChunkManager{ if($i === 4){ continue; //center chunk } - $result[$i] = $this->getOrLoadChunk($x + $xx - 1, $z + $zz - 1, false); + $result[$i] = $this->loadChunk($x + $xx - 1, $z + $zz - 1, false); } } @@ -1992,7 +1976,7 @@ class World implements ChunkManager{ unset($this->chunkPopulationQueue[$index]); if($chunk !== null){ - $oldChunk = $this->getOrLoadChunk($x, $z, false); + $oldChunk = $this->loadChunk($x, $z, false); $this->setChunk($x, $z, $chunk, false); if(($oldChunk === null or !$oldChunk->isPopulated()) and $chunk->isPopulated()){ (new ChunkPopulateEvent($this, $chunk))->call(); @@ -2025,7 +2009,7 @@ class World implements ChunkManager{ $chunk->setZ($chunkZ); $chunkHash = World::chunkHash($chunkX, $chunkZ); - $oldChunk = $this->getOrLoadChunk($chunkX, $chunkZ, false); + $oldChunk = $this->loadChunk($chunkX, $chunkZ, false); if($oldChunk !== null and $oldChunk !== $chunk){ if($deleteEntitiesAndTiles){ foreach($oldChunk->getEntities() as $entity){ @@ -2075,7 +2059,7 @@ class World implements ChunkManager{ * @return int 0-255, or -1 if the chunk is not generated */ public function getHighestBlockAt(int $x, int $z) : int{ - if(($chunk = $this->getOrLoadChunk($x >> 4, $z >> 4, false)) !== null){ + if(($chunk = $this->loadChunk($x >> 4, $z >> 4, false)) !== null){ return $chunk->getHighestBlockAt($x & 0x0f, $z & 0x0f); } return -1; //TODO: this should probably throw an exception (terrain not generated yet) @@ -2093,12 +2077,12 @@ class World implements ChunkManager{ } public function isChunkGenerated(int $x, int $z) : bool{ - $chunk = $this->getOrLoadChunk($x, $z, false); + $chunk = $this->loadChunk($x, $z, false); return $chunk !== null ? $chunk->isGenerated() : false; } public function isChunkPopulated(int $x, int $z) : bool{ - $chunk = $this->getOrLoadChunk($x, $z, false); + $chunk = $this->loadChunk($x, $z, false); return $chunk !== null ? $chunk->isPopulated() : false; } @@ -2204,17 +2188,18 @@ class World implements ChunkManager{ } /** - * Attempts to load a chunk from the world provider (if not already loaded). + * Attempts to load a chunk from the world provider (if not already loaded). If the chunk is already loaded, it is + * returned directly. * * @param bool $create Whether to create an empty chunk to load if the chunk cannot be loaded from disk. * - * @return bool if loading the chunk was successful + * @return Chunk|null the requested chunk, or null on failure. * * @throws \InvalidStateException */ - public function loadChunk(int $x, int $z, bool $create) : bool{ + public function loadChunk(int $x, int $z, bool $create) : ?Chunk{ if(isset($this->chunks[$chunkHash = World::chunkHash($x, $z)])){ - return true; + return $this->chunks[$chunkHash]; } $this->timings->syncChunkLoadTimer->startTiming(); @@ -2239,7 +2224,7 @@ class World implements ChunkManager{ if($chunk === null){ $this->timings->syncChunkLoadTimer->stopTiming(); - return false; + return null; } $this->chunks[$chunkHash] = $chunk; @@ -2259,7 +2244,7 @@ class World implements ChunkManager{ $this->timings->syncChunkLoadTimer->stopTiming(); - return true; + return $chunk; } private function initChunk(Chunk $chunk) : void{ @@ -2516,7 +2501,7 @@ class World implements ChunkManager{ } } - $chunk = $this->getOrLoadChunk($x, $z, true); + $chunk = $this->loadChunk($x, $z, true); if(!$chunk->isPopulated()){ Timings::$populationTimer->startTiming(); From 1d02829d6f0ad161cef8901ac61c0f398d539a2a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 9 Nov 2020 14:01:27 +0000 Subject: [PATCH 2064/3224] [ci skip] more detail for World API changes on PM4 --- changelogs/4.0-snapshot.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index d1938caaf5..cb253ab091 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -707,12 +707,41 @@ This version features substantial changes to the network system, improving coher - `BlockTransaction`: allows creating batch commits of block changes with validation conditions - if any block can't be applied, the whole transaction fails to apply. - `ChunkListenerNoOpTrait`: contains default no-op stubs for chunk listener implementations - `ChunkListener`: interface allowing subscribing to events happening on a given chunk +- The following classes have been renamed: + - `pocketmine\world\utils\SubChunkIteratorManager` -> `pocketmine\world\utils\SubChunkExplorer` - The following API methods have been added: - `World->registerChunkListener()` - `World->unregisterChunkListener()` - The following API methods have been removed: - `ChunkLoader->getLoaderId()` (now object ID is used) - `World->isFullBlock()` + - `World->getFullBlock()` + - `World->getBlockIdAt()` + - `World->setBlockIdAt()` + - `World->getBlockDataAt()` + - `World->setBlockDataAt()` + - `World->setBlockLightAt()` + - `World->setBlockSkyLightAt()` + - `World->getBlockSkyLightAt()` (use `World->getRealBlockSkyLightAt()` or `World->getPotentialBlockSkyLightAt()`, depending on use-case) + - `World->getHeightMap()` (misleading name, only actually useful for sky light calculation - you probably want `getHighestBlockAt()` instead) + - `World->setHeightMap()` (misleading name, only actually useful for sky light calculation) + - `World->getChunkEntities()` + - `World->getChunkTiles()` + - `World->getTileById()` + - `World->checkSpawnProtection()` + - `World->updateBlockLight()` + - `World->updateSkyLight()` + - `World->isFullBlock()` (use `Block->isFullCube()` instead) + - `World->sendBlocks()` + - `World->sendTime()` + - `World->addGlobalPacket()` + - `World->broadcastGlobalPacket()` + - `World->addChunkPacket()` + - `World->broadcastLevelSoundEvent()` + - `World->broadcastLevelEvent()` + - `World->getTickRate()` + - `World->setTickRate()` + - `World::generateChunkLoaderId()` - The following API methods have changed signatures: - `World->addParticle()` now has the signature `addParticle(Vector3 $pos, Particle $particle, ?Player[] $players = null) : void` - `World->addSound()` now has the signature `addSound(?Vector3 $pos, Sound $sound, ?Player[] $players = null) : void` @@ -720,8 +749,12 @@ This version features substantial changes to the network system, improving coher - `World->addRandomTickedBlock()` now accepts `Block` instead of `int, int`. - `World->removeRandomTickedBlock()` now accepts `Block` instead of `int, int`. - `World->setBlock()` has had the `$direct` parameter removed. + - `World->loadChunk()` now returns `?Chunk`, and the `$create` parameter is mandatory. + - `World->getChunk()` no longer accepts a `$create` parameter. + - `World->updateAllLight()` now accepts `int, int, int` instead of `Vector3`. - The following API methods have been renamed / moved: - `Level->getCollisionCubes()` -> `World->getCollisionBoxes()` + - `World->getName()` -> `World->getDisplayName()` - Extracted a unit `pocketmine\world\format\io\FastChunkSerializer` from `Chunk`: - `Chunk->fastDeserialize()` -> `FastChunkSerializer::deserialize()` - `Chunk->fastSerialize()` -> `FastChunkSerializer::serialize()` From 2bcb398db98b4bb210697b8092b5dca0eef3beef Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 9 Nov 2020 19:05:00 +0000 Subject: [PATCH 2065/3224] ItemStack: added jsonSerialize --- .../protocol/types/inventory/ItemStack.php | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/network/mcpe/protocol/types/inventory/ItemStack.php b/src/network/mcpe/protocol/types/inventory/ItemStack.php index 9233086f25..75c89937be 100644 --- a/src/network/mcpe/protocol/types/inventory/ItemStack.php +++ b/src/network/mcpe/protocol/types/inventory/ItemStack.php @@ -24,9 +24,13 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\inventory; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\TreeRoot; +use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; use pocketmine\network\mcpe\protocol\types\FixedItemIds; +use function base64_encode; +use function count; -final class ItemStack{ +final class ItemStack implements \JsonSerializable{ /** @var int */ private $id; @@ -110,4 +114,25 @@ final class ItemStack{ ($this->nbt !== null && $itemStack->nbt !== null && $this->nbt->equals($itemStack->nbt)) ); } + + public function jsonSerialize() : array{ + $result = [ + "id" => $this->id, + "meta" => $this->meta, + "count" => $this->count, + ]; + if(count($this->canPlaceOn) > 0){ + $result["canPlaceOn"] = $this->canPlaceOn; + } + if(count($this->canDestroy) > 0){ + $result["canDestroy"] = $this->canDestroy; + } + if($this->shieldBlockingTick !== null){ + $result["shieldBlockingTick"] = $this->shieldBlockingTick; + } + if($this->nbt !== null){ + $result["nbt"] = base64_encode((new NetworkNbtSerializer())->write(new TreeRoot($this->nbt))); + } + return $result; + } } From e573226025f8dc5efb395ec2ebda39a216f7f5a9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 9 Nov 2020 19:10:02 +0000 Subject: [PATCH 2066/3224] ItemStack: fixed phpstan failure --- src/network/mcpe/protocol/types/inventory/ItemStack.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/mcpe/protocol/types/inventory/ItemStack.php b/src/network/mcpe/protocol/types/inventory/ItemStack.php index 75c89937be..70ce023a47 100644 --- a/src/network/mcpe/protocol/types/inventory/ItemStack.php +++ b/src/network/mcpe/protocol/types/inventory/ItemStack.php @@ -115,6 +115,7 @@ final class ItemStack implements \JsonSerializable{ ); } + /** @return mixed[] */ public function jsonSerialize() : array{ $result = [ "id" => $this->id, From 8c480ffab9a243ec3cc816fb96ee00e7fa851388 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 9 Nov 2020 19:31:48 +0000 Subject: [PATCH 2067/3224] Player: fix a few more cases of held-item getting trashed after some events --- src/player/Player.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 1976dedb53..a8e663c1b5 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1445,6 +1445,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ public function useHeldItem() : bool{ $directionVector = $this->getDirectionVector(); $item = $this->inventory->getItemInHand(); + $oldItem = clone $item; $ev = new PlayerItemUseEvent($this, $item, $directionVector); if($this->hasItemCooldown($item) or $this->isSpectator()){ @@ -1463,7 +1464,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } $this->resetItemCooldown($item); - if($this->hasFiniteResources()){ + if($this->hasFiniteResources() and !$item->equalsExact($oldItem) and $oldItem->equalsExact($this->inventory->getItemInHand())){ $this->inventory->setItemInHand($item); } @@ -1480,6 +1481,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ public function consumeHeldItem() : bool{ $slot = $this->inventory->getItemInHand(); if($slot instanceof ConsumableItem){ + $oldItem = clone $slot; + $ev = new PlayerItemConsumeEvent($this, $slot); if($this->hasItemCooldown($slot)){ $ev->cancel(); @@ -1493,7 +1496,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->setUsingItem(false); $this->resetItemCooldown($slot); - if($this->hasFiniteResources()){ + if($this->hasFiniteResources() and !$slot->equalsExact($oldItem) and $oldItem->equalsExact($this->inventory->getItemInHand())){ $slot->pop(); $this->inventory->setItemInHand($slot); $this->inventory->addItem($slot->getResidue()); @@ -1517,10 +1520,14 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return false; } + $oldItem = clone $item; + $result = $item->onReleaseUsing($this); if($result->equals(ItemUseResult::SUCCESS())){ $this->resetItemCooldown($item); - $this->inventory->setItemInHand($item); + if(!$item->equalsExact($oldItem) and $oldItem->equalsExact($this->inventory->getItemInHand())){ + $this->inventory->setItemInHand($item); + } return true; } From 6cf875ca3ade645fce6104de0847ea8aab45e320 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 9 Nov 2020 19:33:13 +0000 Subject: [PATCH 2068/3224] Item: rename onActivate() to onInteractBlock() --- src/item/Bucket.php | 2 +- src/item/FlintSteel.php | 2 +- src/item/Item.php | 2 +- src/item/LiquidBucket.php | 2 +- src/item/PaintingItem.php | 2 +- src/item/SpawnEgg.php | 2 +- src/world/World.php | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/item/Bucket.php b/src/item/Bucket.php index 649c45a2bc..2cf0ac55ff 100644 --- a/src/item/Bucket.php +++ b/src/item/Bucket.php @@ -36,7 +36,7 @@ class Bucket extends Item{ return 16; } - public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ + public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ //TODO: move this to generic placement logic if($blockClicked instanceof Liquid and $blockClicked->isSource()){ $stack = clone $this; diff --git a/src/item/FlintSteel.php b/src/item/FlintSteel.php index 0ddac5cc2d..d5088e6415 100644 --- a/src/item/FlintSteel.php +++ b/src/item/FlintSteel.php @@ -32,7 +32,7 @@ use pocketmine\world\sound\FlintSteelSound; class FlintSteel extends Tool{ - public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ + public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ if($blockReplace->getId() === BlockLegacyIds::AIR){ $world = $player->getWorld(); $world->setBlock($blockReplace->getPos(), VanillaBlocks::FIRE()); diff --git a/src/item/Item.php b/src/item/Item.php index 14c10a5703..7e559c4dbb 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -500,7 +500,7 @@ class Item implements \JsonSerializable{ /** * Called when a player uses this item on a block. */ - public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ + public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ return ItemUseResult::NONE(); } diff --git a/src/item/LiquidBucket.php b/src/item/LiquidBucket.php index 88fe7663f5..dfaa2172d4 100644 --- a/src/item/LiquidBucket.php +++ b/src/item/LiquidBucket.php @@ -52,7 +52,7 @@ class LiquidBucket extends Item{ return 0; } - public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ + public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ if(!$blockReplace->canBeReplaced()){ return ItemUseResult::NONE(); } diff --git a/src/item/PaintingItem.php b/src/item/PaintingItem.php index 5bbac2d7ba..d640e061ef 100644 --- a/src/item/PaintingItem.php +++ b/src/item/PaintingItem.php @@ -37,7 +37,7 @@ use function count; class PaintingItem extends Item{ - public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ + public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ if(Facing::axis($face) === Axis::Y){ return ItemUseResult::NONE(); } diff --git a/src/item/SpawnEgg.php b/src/item/SpawnEgg.php index 9748bfe722..e41e3997d0 100644 --- a/src/item/SpawnEgg.php +++ b/src/item/SpawnEgg.php @@ -34,7 +34,7 @@ abstract class SpawnEgg extends Item{ abstract protected function createEntity(World $world, Vector3 $pos, float $yaw, float $pitch) : Entity; - public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ + public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ $entity = $this->createEntity($player->getWorld(), $blockReplace->getPos()->add(0.5, 0, 0.5), lcg_value() * 360, 0); if($this->hasCustomName()){ diff --git a/src/world/World.php b/src/world/World.php index 4d15d8a1ee..4a2e2f78fa 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1618,7 +1618,7 @@ class World implements ChunkManager{ return true; } - $result = $item->onActivate($player, $blockReplace, $blockClicked, $face, $clickVector); + $result = $item->onInteractBlock($player, $blockReplace, $blockClicked, $face, $clickVector); if(!$result->equals(ItemUseResult::NONE())){ return $result->equals(ItemUseResult::SUCCESS()); } From 463bc044df382d2f6d8caa8414cffe7daa965d29 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 9 Nov 2020 20:28:08 +0000 Subject: [PATCH 2069/3224] Rename PluginLoadOrder -> PluginEnableOrder this more accurately describes its real purpose. --- src/Server.php | 10 +++++----- src/plugin/PluginDescription.php | 8 ++++---- .../{PluginLoadOrder.php => PluginEnableOrder.php} | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) rename src/plugin/{PluginLoadOrder.php => PluginEnableOrder.php} (97%) diff --git a/src/Server.php b/src/Server.php index b517bf1505..97c438e150 100644 --- a/src/Server.php +++ b/src/Server.php @@ -69,7 +69,7 @@ use pocketmine\player\Player; use pocketmine\plugin\PharPluginLoader; use pocketmine\plugin\Plugin; use pocketmine\plugin\PluginGraylist; -use pocketmine\plugin\PluginLoadOrder; +use pocketmine\plugin\PluginEnableOrder; use pocketmine\plugin\PluginManager; use pocketmine\plugin\PluginOwned; use pocketmine\plugin\ScriptPluginLoader; @@ -976,7 +976,7 @@ class Server{ register_shutdown_function([$this, "crashDump"]); $this->pluginManager->loadPlugins($this->pluginPath); - $this->enablePlugins(PluginLoadOrder::STARTUP()); + $this->enablePlugins(PluginEnableOrder::STARTUP()); foreach((array) $this->configGroup->getProperty("worlds", []) as $name => $options){ if($options === null){ @@ -1025,7 +1025,7 @@ class Server{ $this->worldManager->setDefaultWorld($world); } - $this->enablePlugins(PluginLoadOrder::POSTWORLD()); + $this->enablePlugins(PluginEnableOrder::POSTWORLD()); $this->network->registerInterface(new RakLibInterface($this)); $this->logger->info($this->getLanguage()->translateString("pocketmine.server.networkStart", [$this->getIp(), $this->getPort()])); @@ -1258,14 +1258,14 @@ class Server{ } } - public function enablePlugins(PluginLoadOrder $type) : void{ + public function enablePlugins(PluginEnableOrder $type) : void{ foreach($this->pluginManager->getPlugins() as $plugin){ if(!$plugin->isEnabled() and $plugin->getDescription()->getOrder()->equals($type)){ $this->pluginManager->enablePlugin($plugin); } } - if($type->equals(PluginLoadOrder::POSTWORLD())){ + if($type->equals(PluginEnableOrder::POSTWORLD())){ $this->commandMap->registerServerAliases(); } } diff --git a/src/plugin/PluginDescription.php b/src/plugin/PluginDescription.php index e0632eae2d..ad56adaaf7 100644 --- a/src/plugin/PluginDescription.php +++ b/src/plugin/PluginDescription.php @@ -80,7 +80,7 @@ class PluginDescription{ private $website = ""; /** @var string */ private $prefix = ""; - /** @var PluginLoadOrder */ + /** @var PluginEnableOrder */ private $order; /** @var Permission[] */ @@ -146,12 +146,12 @@ class PluginDescription{ if(isset($plugin["load"])){ try{ - $this->order = PluginLoadOrder::fromString($plugin["load"]); + $this->order = PluginEnableOrder::fromString($plugin["load"]); }catch(\InvalidArgumentException $e){ throw new PluginException("Invalid Plugin \"load\""); } }else{ - $this->order = PluginLoadOrder::POSTWORLD(); + $this->order = PluginEnableOrder::POSTWORLD(); } $this->authors = []; @@ -281,7 +281,7 @@ class PluginDescription{ return $this->name; } - public function getOrder() : PluginLoadOrder{ + public function getOrder() : PluginEnableOrder{ return $this->order; } diff --git a/src/plugin/PluginLoadOrder.php b/src/plugin/PluginEnableOrder.php similarity index 97% rename from src/plugin/PluginLoadOrder.php rename to src/plugin/PluginEnableOrder.php index fa99eeba98..b79b19d90f 100644 --- a/src/plugin/PluginLoadOrder.php +++ b/src/plugin/PluginEnableOrder.php @@ -33,7 +33,7 @@ use pocketmine\utils\EnumTrait; * @method static self STARTUP() * @method static self POSTWORLD() */ -final class PluginLoadOrder{ +final class PluginEnableOrder{ use EnumTrait; protected static function setup() : void{ From 6c02bac4377a52114b307261fa14b705f5fb6bca Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 9 Nov 2020 20:30:22 +0000 Subject: [PATCH 2070/3224] Updated DevTools submodule to 66b8f7dfd77f78478a180e40137e17606301233e --- tests/plugins/DevTools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/plugins/DevTools b/tests/plugins/DevTools index 75c2774cc7..66b8f7dfd7 160000 --- a/tests/plugins/DevTools +++ b/tests/plugins/DevTools @@ -1 +1 @@ -Subproject commit 75c2774cc76ab51b2fa35419dd37802970cdcd8f +Subproject commit 66b8f7dfd77f78478a180e40137e17606301233e From c43f14a2d2df86f4738e8efa152597d2443e94a5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 10 Nov 2020 14:06:13 +0000 Subject: [PATCH 2071/3224] Updated phpstan checkExplicitMixed baseline to account for changes in 463bc044df382d2f6d8caa8414cffe7daa965d29 --- tests/phpstan/configs/check-explicit-mixed-baseline.neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index 87dbbc975f..c682bd133d 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -206,7 +206,7 @@ parameters: path: ../../../src/plugin/PluginDescription.php - - message: "#^Parameter \\#1 \\$name of static method pocketmine\\\\plugin\\\\PluginLoadOrder\\:\\:fromString\\(\\) expects string, mixed given\\.$#" + message: "#^Parameter \\#1 \\$name of static method pocketmine\\\\plugin\\\\PluginEnableOrder\\:\\:fromString\\(\\) expects string, mixed given\\.$#" count: 1 path: ../../../src/plugin/PluginDescription.php From 6a266bcbd1937d007a82b6019596408031eb183d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 10 Nov 2020 14:25:08 +0000 Subject: [PATCH 2072/3224] Separated XUID stuff from PlayerInfo into its own XboxLivePlayerInfo --- src/network/mcpe/NetworkSession.php | 5 +- .../mcpe/handler/LoginPacketHandler.php | 27 ++++++--- src/player/Player.php | 2 +- src/player/PlayerInfo.php | 28 +-------- src/player/XboxLivePlayerInfo.php | 59 +++++++++++++++++++ 5 files changed, 83 insertions(+), 38 deletions(-) create mode 100644 src/player/XboxLivePlayerInfo.php diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 60b97b209e..a3b40af357 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -97,6 +97,7 @@ use pocketmine\network\NetworkSessionManager; use pocketmine\player\GameMode; use pocketmine\player\Player; use pocketmine\player\PlayerInfo; +use pocketmine\player\XboxLivePlayerInfo; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\TextFormat; @@ -563,7 +564,7 @@ class NetworkSession{ return; } if($error === null){ - if($authenticated and $this->info->getXuid() === ""){ + if($authenticated and !($this->info instanceof XboxLivePlayerInfo)){ $error = "Expected XUID but none found"; }elseif($clientPubKey === null){ $error = "Missing client public key"; //failsafe @@ -583,7 +584,7 @@ class NetworkSession{ $this->disconnect("disconnectionScreen.notAuthenticated"); return; } - if($this->info->hasXboxData()){ + if($this->info instanceof XboxLivePlayerInfo){ $this->logger->warning("Discarding unexpected XUID for non-authenticated player"); $this->info = $this->info->withoutXboxData(); } diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index b9b072fa74..b9e81b2537 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -41,6 +41,7 @@ use pocketmine\network\mcpe\protocol\types\login\ClientDataToSkinDataHelper; use pocketmine\network\mcpe\protocol\types\login\JwtChain; use pocketmine\player\Player; use pocketmine\player\PlayerInfo; +use pocketmine\player\XboxLivePlayerInfo; use pocketmine\Server; use pocketmine\uuid\UUID; use function is_array; @@ -116,14 +117,24 @@ class LoginPacketHandler extends PacketHandler{ }catch(\InvalidArgumentException $e){ throw BadPacketException::wrap($e, "Failed to parse login UUID"); } - $playerInfo = new PlayerInfo( - $extraData->displayName, - $uuid, - $skin, - $clientData->LanguageCode, - $extraData->XUID, - (array) $clientData - ); + if($extraData->XUID !== ""){ + $playerInfo = new XboxLivePlayerInfo( + $extraData->XUID, + $extraData->displayName, + $uuid, + $skin, + $clientData->LanguageCode, + (array) $clientData + ); + }else{ + $playerInfo = new PlayerInfo( + $extraData->displayName, + $uuid, + $skin, + $clientData->LanguageCode, + (array) $clientData + ); + } ($this->playerInfoConsumer)($playerInfo); $ev = new PlayerPreLoginEvent( diff --git a/src/player/Player.php b/src/player/Player.php index a8e663c1b5..ea964dfa51 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -280,7 +280,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->locale = $this->playerInfo->getLocale(); $this->uuid = $this->playerInfo->getUuid(); - $this->xuid = $this->playerInfo->getXuid(); + $this->xuid = $this->playerInfo instanceof XboxLivePlayerInfo ? $this->playerInfo->getXuid() : ""; $this->perm = new PermissibleBase($this); $this->chunksPerTick = (int) $this->server->getConfigGroup()->getProperty("chunk-sending.per-tick", 4); diff --git a/src/player/PlayerInfo.php b/src/player/PlayerInfo.php index 52e9b2f7a4..787042e806 100644 --- a/src/player/PlayerInfo.php +++ b/src/player/PlayerInfo.php @@ -40,8 +40,6 @@ class PlayerInfo{ private $skin; /** @var string */ private $locale; - /** @var string */ - private $xuid; /** * @var mixed[] * @phpstan-var array @@ -52,12 +50,11 @@ class PlayerInfo{ * @param mixed[] $extraData * @phpstan-param array $extraData */ - public function __construct(string $username, UUID $uuid, Skin $skin, string $locale, string $xuid, array $extraData = []){ + public function __construct(string $username, UUID $uuid, Skin $skin, string $locale, array $extraData = []){ $this->username = TextFormat::clean($username); $this->uuid = $uuid; $this->skin = $skin; $this->locale = $locale; - $this->xuid = $xuid; $this->extraData = $extraData; } @@ -77,10 +74,6 @@ class PlayerInfo{ return $this->locale; } - public function getXuid() : string{ - return $this->xuid; - } - /** * @return mixed[] * @phpstan-return array @@ -88,23 +81,4 @@ class PlayerInfo{ public function getExtraData() : array{ return $this->extraData; } - - public function hasXboxData() : bool{ - return $this->xuid !== ""; - } - - /** - * Returns a new PlayerInfo with XBL player info stripped. This is used to ensure that non-XBL players can't spoof - * XBL data. - */ - public function withoutXboxData() : self{ - return new self( - $this->username, - $this->uuid, - $this->skin, - $this->locale, - "", - $this->extraData - ); - } } diff --git a/src/player/XboxLivePlayerInfo.php b/src/player/XboxLivePlayerInfo.php new file mode 100644 index 0000000000..a0e3a2cbcf --- /dev/null +++ b/src/player/XboxLivePlayerInfo.php @@ -0,0 +1,59 @@ +xuid = $xuid; + } + + public function getXuid() : string{ + return $this->xuid; + } + + /** + * Returns a new PlayerInfo with XBL player info stripped. This is used to ensure that non-XBL players can't spoof + * XBL data. + */ + public function withoutXboxData() : PlayerInfo{ + return new PlayerInfo( + $this->getUsername(), + $this->getUuid(), + $this->getSkin(), + $this->getLocale(), + $this->getExtraData() + ); + } +} From e23379c34bb3ca741f36fe6bfc443bbe42f16d3a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 10 Nov 2020 14:45:19 +0000 Subject: [PATCH 2073/3224] EncryptionContext: provide the packet ID in the exception message --- src/network/mcpe/encryption/EncryptionContext.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/network/mcpe/encryption/EncryptionContext.php b/src/network/mcpe/encryption/EncryptionContext.php index 4c98f2b22f..1fc0ce0311 100644 --- a/src/network/mcpe/encryption/EncryptionContext.php +++ b/src/network/mcpe/encryption/EncryptionContext.php @@ -75,8 +75,10 @@ class EncryptionContext{ $decrypted = $this->decryptCipher->decryptUpdate($encrypted); $payload = substr($decrypted, 0, -8); - if(($expected = $this->calculateChecksum($this->decryptCounter++, $payload)) !== ($actual = substr($decrypted, -8))){ - throw new DecryptionException("Encrypted payload has invalid checksum (expected " . bin2hex($expected) . ", got " . bin2hex($actual) . ")"); + $packetCounter = $this->decryptCounter++; + + if(($expected = $this->calculateChecksum($packetCounter, $payload)) !== ($actual = substr($decrypted, -8))){ + throw new DecryptionException("Encrypted packet $packetCounter has invalid checksum (expected " . bin2hex($expected) . ", got " . bin2hex($actual) . ")"); } return $payload; From 75f2f12b998014e6fb13ae1a98697aa188c4d002 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 10 Nov 2020 15:01:48 +0000 Subject: [PATCH 2074/3224] NetworkSession: rename some badly-named hooks --- src/network/mcpe/NetworkSession.php | 14 +++++++------- src/player/Player.php | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index a3b40af357..81c399b3ac 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -602,17 +602,17 @@ class NetworkSession{ $this->cipher = new EncryptionContext($encryptionKey); $this->setHandler(new HandshakePacketHandler(function() : void{ - $this->onLoginSuccess(); + $this->onServerLoginSuccess(); })); $this->logger->debug("Enabled encryption"); })); }else{ - $this->onLoginSuccess(); + $this->onServerLoginSuccess(); } } } - private function onLoginSuccess() : void{ + private function onServerLoginSuccess() : void{ $this->loggedIn = true; $this->sendDataPacket(PlayStatusPacket::create(PlayStatusPacket::LOGIN_SUCCESS)); @@ -636,24 +636,24 @@ class NetworkSession{ $this->logger->debug("Sending spawn notification, waiting for spawn response"); $this->sendDataPacket(PlayStatusPacket::create(PlayStatusPacket::PLAYER_SPAWN)); $this->setHandler(new SpawnResponsePacketHandler(function() : void{ - $this->onSpawn(); + $this->onClientSpawnResponse(); })); } - private function onSpawn() : void{ + private function onClientSpawnResponse() : void{ $this->logger->debug("Received spawn response, entering in-game phase"); $this->player->setImmobile(false); //TODO: HACK: we set this during the spawn sequence to prevent the client sending junk movements $this->player->doFirstSpawn(); $this->setHandler(new InGamePacketHandler($this->player, $this)); } - public function onDeath() : void{ + public function onServerDeath() : void{ if($this->handler instanceof InGamePacketHandler){ //TODO: this is a bad fix for pre-spawn death, this shouldn't be reachable at all at this stage :( $this->setHandler(new DeathPacketHandler($this->player, $this)); } } - public function onRespawn() : void{ + public function onServerRespawn() : void{ $this->player->sendData(null); $this->syncAdventureSettings($this->player); diff --git a/src/player/Player.php b/src/player/Player.php index ea964dfa51..eb38968ce0 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2149,7 +2149,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->startDeathAnimation(); - $this->networkSession->onDeath(); + $this->networkSession->onServerDeath(); } protected function onDeathUpdate(int $tickDiff) : bool{ @@ -2187,7 +2187,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->spawnToAll(); $this->scheduleUpdate(); - $this->networkSession->onRespawn(); + $this->networkSession->onServerRespawn(); } protected function applyPostDamageEffects(EntityDamageEvent $source) : void{ From 21d37623f8f59aaa104e994ec69137c8dea5df54 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 10 Nov 2020 22:46:15 +0000 Subject: [PATCH 2075/3224] sync phpstan level 8 baseline with 75f2f12b998014e6fb13ae1a98697aa188c4d002 --- tests/phpstan/configs/l8-baseline.neon | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index ccba8426ed..daa109950a 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -426,12 +426,12 @@ parameters: path: ../../../src/player/Player.php - - message: "#^Cannot call method onDeath\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + message: "#^Cannot call method onServerDeath\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" count: 1 path: ../../../src/player/Player.php - - message: "#^Cannot call method onRespawn\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + message: "#^Cannot call method onServerRespawn\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" count: 1 path: ../../../src/player/Player.php From 8f36957c1044e6abd5514ccaed795f97c160f85b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 10 Nov 2020 22:46:30 +0000 Subject: [PATCH 2076/3224] phpstan: drop some dead level 8 ignoreErrors --- tests/phpstan/configs/l8-baseline.neon | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index daa109950a..2ed212f934 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -355,11 +355,6 @@ parameters: count: 1 path: ../../../src/player/Player.php - - - message: "#^Cannot call method syncAttributes\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - message: "#^Cannot call method onTitle\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" count: 1 @@ -545,11 +540,6 @@ parameters: count: 1 path: ../../../src/world/World.php - - - message: "#^Method pocketmine\\\\world\\\\biome\\\\Biome\\:\\:getBiome\\(\\) should return pocketmine\\\\world\\\\biome\\\\Biome but returns pocketmine\\\\world\\\\biome\\\\Biome\\|null\\.$#" - count: 1 - path: ../../../src/world/biome/Biome.php - - message: "#^Method pocketmine\\\\world\\\\biome\\\\BiomeRegistry\\:\\:getBiome\\(\\) should return pocketmine\\\\world\\\\biome\\\\Biome but returns pocketmine\\\\world\\\\biome\\\\Biome\\|null\\.$#" count: 1 From c4d35d52e879c38ea70b8d506d9a375075f52de3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 11 Nov 2020 18:20:03 +0000 Subject: [PATCH 2077/3224] Do not store a pre-compressed cache for crafting data this reduces bandwidth efficiency because it can't be compressed with everything else this way. If we want to cache stuff sent during the login sequence, it's better to stuff a bunch of stuff into a batch (e.g. crafting, creative, actor ids, biome defs) and pre-compress that as one big package instead. --- src/crafting/CraftingManager.php | 32 +++++++------------ .../mcpe/handler/PreSpawnPacketHandler.php | 2 +- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index 63af6fc261..14d312de6c 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -24,11 +24,8 @@ declare(strict_types=1); namespace pocketmine\crafting; use pocketmine\item\Item; -use pocketmine\network\mcpe\compression\CompressBatchPromise; -use pocketmine\network\mcpe\compression\Compressor; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\CraftingDataPacket; -use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\protocol\types\recipe\FurnaceRecipe as ProtocolFurnaceRecipe; use pocketmine\network\mcpe\protocol\types\recipe\RecipeIngredient; @@ -39,7 +36,6 @@ use pocketmine\utils\Binary; use pocketmine\uuid\UUID; use function array_map; use function json_encode; -use function spl_object_id; use function str_repeat; use function usort; @@ -52,20 +48,20 @@ class CraftingManager{ /** @var FurnaceRecipeManager */ protected $furnaceRecipeManager; - /** @var CompressBatchPromise[] */ - private $craftingDataCaches = []; + /** @var CraftingDataPacket|null */ + private $craftingDataCache = null; public function __construct(){ $this->furnaceRecipeManager = new FurnaceRecipeManager(); $this->furnaceRecipeManager->getRecipeRegisteredCallbacks()->add(function(FurnaceRecipe $recipe) : void{ - $this->craftingDataCaches = []; + $this->craftingDataCache = null; }); } /** * Rebuilds the cached CraftingDataPacket. */ - private function buildCraftingDataCache(Compressor $compressor) : CompressBatchPromise{ + private function buildCraftingDataCache() : CraftingDataPacket{ Timings::$craftingDataCacheRebuildTimer->startTiming(); $pk = new CraftingDataPacket(); $pk->cleanRecipes = true; @@ -126,24 +122,18 @@ class CraftingManager{ ); } - $promise = new CompressBatchPromise(); - $promise->resolve($compressor->compress(PacketBatch::fromPackets($pk)->getBuffer())); - - Timings::$craftingDataCacheRebuildTimer->stopTiming(); - return $promise; + return $pk; } /** * Returns a pre-compressed CraftingDataPacket for sending to players. Rebuilds the cache if it is not found. */ - public function getCraftingDataPacket(Compressor $compressor) : CompressBatchPromise{ - $compressorId = spl_object_id($compressor); - - if(!isset($this->craftingDataCaches[$compressorId])){ - $this->craftingDataCaches[$compressorId] = $this->buildCraftingDataCache($compressor); + public function getCraftingDataPacket() : CraftingDataPacket{ + if($this->craftingDataCache === null){ + $this->craftingDataCache = $this->buildCraftingDataCache(); } - return $this->craftingDataCaches[$compressorId]; + return $this->craftingDataCache; } /** @@ -215,13 +205,13 @@ class CraftingManager{ public function registerShapedRecipe(ShapedRecipe $recipe) : void{ $this->shapedRecipes[self::hashOutputs($recipe->getResults())][] = $recipe; - $this->craftingDataCaches = []; + $this->craftingDataCache = null; } public function registerShapelessRecipe(ShapelessRecipe $recipe) : void{ $this->shapelessRecipes[self::hashOutputs($recipe->getResults())][] = $recipe; - $this->craftingDataCaches = []; + $this->craftingDataCache = null; } /** diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index 5a552b7851..0e20bc8471 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -100,7 +100,7 @@ class PreSpawnPacketHandler extends PacketHandler{ $this->session->getInvManager()->syncAll(); $this->session->getInvManager()->syncCreative(); $this->session->getInvManager()->syncSelectedHotbarSlot(); - $this->session->queueCompressed($this->server->getCraftingManager()->getCraftingDataPacket($this->session->getCompressor())); + $this->session->sendDataPacket($this->server->getCraftingManager()->getCraftingDataPacket()); $this->session->syncPlayerList($this->server->getOnlinePlayers()); } From 5efd0eba13e8a065b755b312c7901f95c3292926 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Nov 2020 17:11:34 +0000 Subject: [PATCH 2078/3224] Imports cleanup --- src/PocketMine.php | 2 -- src/Server.php | 2 +- src/player/Player.php | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index 3f6212a18f..ee6515b3de 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -26,13 +26,11 @@ namespace pocketmine { use pocketmine\errorhandler\ErrorToExceptionHandler; use pocketmine\thread\ThreadManager; use pocketmine\utils\Filesystem; - use pocketmine\utils\Git; use pocketmine\utils\MainLogger; use pocketmine\utils\Process; use pocketmine\utils\ServerKiller; use pocketmine\utils\Terminal; use pocketmine\utils\Timezone; - use pocketmine\utils\VersionString; use pocketmine\wizard\SetupWizard; require_once __DIR__ . '/VersionInfo.php'; diff --git a/src/Server.php b/src/Server.php index 97c438e150..a35c66a20b 100644 --- a/src/Server.php +++ b/src/Server.php @@ -68,8 +68,8 @@ use pocketmine\player\OfflinePlayer; use pocketmine\player\Player; use pocketmine\plugin\PharPluginLoader; use pocketmine\plugin\Plugin; -use pocketmine\plugin\PluginGraylist; use pocketmine\plugin\PluginEnableOrder; +use pocketmine\plugin\PluginGraylist; use pocketmine\plugin\PluginManager; use pocketmine\plugin\PluginOwned; use pocketmine\plugin\ScriptPluginLoader; diff --git a/src/player/Player.php b/src/player/Player.php index eb38968ce0..e9635d2d20 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -111,7 +111,6 @@ use pocketmine\world\sound\EntityAttackSound; use pocketmine\world\sound\FireExtinguishSound; use pocketmine\world\World; use function abs; -use function array_key_exists; use function assert; use function count; use function explode; From afbef242c6e4bda4a33881b86dfb36c67f29b13d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Nov 2020 17:12:08 +0000 Subject: [PATCH 2079/3224] bootstrap: remove useless phpdoc --- src/PocketMine.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index ee6515b3de..bc0f68ecb3 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -130,7 +130,6 @@ namespace pocketmine { } /** - * @param \Logger $logger * @return void */ function emit_performance_warnings(\Logger $logger){ From 31089ce3b2bb5d717db379b2531f8ea2fb9da04c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Nov 2020 17:53:07 +0000 Subject: [PATCH 2080/3224] Timings: added broadcastPackets timer the body of this function is potentially very expensive and isn't currently recorded by any timer. --- src/Server.php | 80 +++++++++++++++++++++-------------------- src/timings/Timings.php | 5 +++ 2 files changed, 46 insertions(+), 39 deletions(-) diff --git a/src/Server.php b/src/Server.php index a35c66a20b..c046858779 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1182,54 +1182,56 @@ class Server{ throw new \InvalidArgumentException("Cannot broadcast empty list of packets"); } - /** @var NetworkSession[] $recipients */ - $recipients = []; - foreach($players as $player){ - if($player->isConnected()){ - $recipients[] = $player->getNetworkSession(); + return Timings::$broadcastPackets->time(function() use ($players, $packets) : bool{ + /** @var NetworkSession[] $recipients */ + $recipients = []; + foreach($players as $player){ + if($player->isConnected()){ + $recipients[] = $player->getNetworkSession(); + } + } + if(count($recipients) === 0){ + return false; } - } - if(count($recipients) === 0){ - return false; - } - $ev = new DataPacketSendEvent($recipients, $packets); - $ev->call(); - if($ev->isCancelled()){ - return false; - } - $recipients = $ev->getTargets(); + $ev = new DataPacketSendEvent($recipients, $packets); + $ev->call(); + if($ev->isCancelled()){ + return false; + } + $recipients = $ev->getTargets(); - $stream = PacketBatch::fromPackets(...$ev->getPackets()); + $stream = PacketBatch::fromPackets(...$ev->getPackets()); - /** @var Compressor[] $compressors */ - $compressors = []; - /** @var NetworkSession[][] $compressorTargets */ - $compressorTargets = []; - foreach($recipients as $recipient){ - $compressor = $recipient->getCompressor(); - $compressorId = spl_object_id($compressor); - //TODO: different compressors might be compatible, it might not be necessary to split them up by object - $compressors[$compressorId] = $compressor; - $compressorTargets[$compressorId][] = $recipient; - } + /** @var Compressor[] $compressors */ + $compressors = []; + /** @var NetworkSession[][] $compressorTargets */ + $compressorTargets = []; + foreach($recipients as $recipient){ + $compressor = $recipient->getCompressor(); + $compressorId = spl_object_id($compressor); + //TODO: different compressors might be compatible, it might not be necessary to split them up by object + $compressors[$compressorId] = $compressor; + $compressorTargets[$compressorId][] = $recipient; + } - foreach($compressors as $compressorId => $compressor){ - if(!$compressor->willCompress($stream->getBuffer())){ - foreach($compressorTargets[$compressorId] as $target){ - foreach($ev->getPackets() as $pk){ - $target->addToSendBuffer($pk); + foreach($compressors as $compressorId => $compressor){ + if(!$compressor->willCompress($stream->getBuffer())){ + foreach($compressorTargets[$compressorId] as $target){ + foreach($ev->getPackets() as $pk){ + $target->addToSendBuffer($pk); + } + } + }else{ + $promise = $this->prepareBatch($stream, $compressor); + foreach($compressorTargets[$compressorId] as $target){ + $target->queueCompressed($promise); } } - }else{ - $promise = $this->prepareBatch($stream, $compressor); - foreach($compressorTargets[$compressorId] as $target){ - $target->queueCompressed($promise); - } } - } - return true; + return true; + }); } /** diff --git a/src/timings/Timings.php b/src/timings/Timings.php index ff1ede1119..d267798dcf 100644 --- a/src/timings/Timings.php +++ b/src/timings/Timings.php @@ -118,6 +118,9 @@ abstract class Timings{ /** @var TimingsHandler[] */ public static $pluginTaskTimingMap = []; + /** @var TimingsHandler */ + public static $broadcastPackets; + public static function init() : void{ if(self::$initialized){ return; @@ -138,6 +141,8 @@ abstract class Timings{ self::$playerNetworkReceiveDecompressTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Player Network Receive - Decompression", self::$playerNetworkReceiveTimer); self::$playerNetworkReceiveDecryptTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Player Network Receive - Decryption", self::$playerNetworkReceiveTimer); + self::$broadcastPackets = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Broadcast Packets", self::$playerNetworkSendTimer); + self::$playerChunkOrderTimer = new TimingsHandler("Player Order Chunks"); self::$playerChunkSendTimer = new TimingsHandler("Player Send Chunks"); self::$connectionTimer = new TimingsHandler("Connection Handler"); From 0d9561c93fdea99f22f829c4f9efbd5131a2c69c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Nov 2020 21:30:59 +0000 Subject: [PATCH 2081/3224] Removed crafting data cache from CraftingManager --- src/crafting/CraftingManager.php | 115 +++------------ src/network/mcpe/CraftingDataCache.php | 132 ++++++++++++++++++ .../mcpe/handler/PreSpawnPacketHandler.php | 3 +- src/utils/DestructorCallbackTrait.php | 52 +++++++ 4 files changed, 207 insertions(+), 95 deletions(-) create mode 100644 src/network/mcpe/CraftingDataCache.php create mode 100644 src/utils/DestructorCallbackTrait.php diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index 14d312de6c..b6720a3e9c 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -23,23 +23,15 @@ declare(strict_types=1); namespace pocketmine\crafting; +use Ds\Set; use pocketmine\item\Item; -use pocketmine\network\mcpe\convert\TypeConverter; -use pocketmine\network\mcpe\protocol\CraftingDataPacket; -use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\network\mcpe\protocol\types\recipe\FurnaceRecipe as ProtocolFurnaceRecipe; -use pocketmine\network\mcpe\protocol\types\recipe\RecipeIngredient; -use pocketmine\network\mcpe\protocol\types\recipe\ShapedRecipe as ProtocolShapedRecipe; -use pocketmine\network\mcpe\protocol\types\recipe\ShapelessRecipe as ProtocolShapelessRecipe; -use pocketmine\timings\Timings; -use pocketmine\utils\Binary; -use pocketmine\uuid\UUID; -use function array_map; +use pocketmine\utils\DestructorCallbackTrait; use function json_encode; -use function str_repeat; use function usort; class CraftingManager{ + use DestructorCallbackTrait; + /** @var ShapedRecipe[][] */ protected $shapedRecipes = []; /** @var ShapelessRecipe[][] */ @@ -48,93 +40,24 @@ class CraftingManager{ /** @var FurnaceRecipeManager */ protected $furnaceRecipeManager; - /** @var CraftingDataPacket|null */ - private $craftingDataCache = null; + /** + * @var Set + * @phpstan-var Set<\Closure() : void> + */ + private $recipeRegisteredCallbacks; public function __construct(){ + $this->recipeRegisteredCallbacks = new Set(); $this->furnaceRecipeManager = new FurnaceRecipeManager(); $this->furnaceRecipeManager->getRecipeRegisteredCallbacks()->add(function(FurnaceRecipe $recipe) : void{ - $this->craftingDataCache = null; + foreach($this->recipeRegisteredCallbacks as $callback){ + $callback(); + } }); } - /** - * Rebuilds the cached CraftingDataPacket. - */ - private function buildCraftingDataCache() : CraftingDataPacket{ - Timings::$craftingDataCacheRebuildTimer->startTiming(); - $pk = new CraftingDataPacket(); - $pk->cleanRecipes = true; - - $counter = 0; - $nullUUID = UUID::fromData(str_repeat("\x00", 16)); - $converter = TypeConverter::getInstance(); - foreach($this->shapelessRecipes as $list){ - foreach($list as $recipe){ - $pk->entries[] = new ProtocolShapelessRecipe( - CraftingDataPacket::ENTRY_SHAPELESS, - Binary::writeInt($counter++), - array_map(function(Item $item) use ($converter) : RecipeIngredient{ - return $converter->coreItemStackToRecipeIngredient($item); - }, $recipe->getIngredientList()), - array_map(function(Item $item) use ($converter) : ItemStack{ - return $converter->coreItemStackToNet($item); - }, $recipe->getResults()), - $nullUUID, - "crafting_table", - 50, - $counter - ); - } - } - foreach($this->shapedRecipes as $list){ - foreach($list as $recipe){ - $inputs = []; - - for($row = 0, $height = $recipe->getHeight(); $row < $height; ++$row){ - for($column = 0, $width = $recipe->getWidth(); $column < $width; ++$column){ - $inputs[$row][$column] = $converter->coreItemStackToRecipeIngredient($recipe->getIngredient($column, $row)); - } - } - $pk->entries[] = $r = new ProtocolShapedRecipe( - CraftingDataPacket::ENTRY_SHAPED, - Binary::writeInt($counter++), - $inputs, - array_map(function(Item $item) use ($converter) : ItemStack{ - return $converter->coreItemStackToNet($item); - }, $recipe->getResults()), - $nullUUID, - "crafting_table", - 50, - $counter - ); - } - } - - foreach($this->furnaceRecipeManager->getAll() as $recipe){ - $input = $converter->coreItemStackToNet($recipe->getInput()); - $pk->entries[] = new ProtocolFurnaceRecipe( - CraftingDataPacket::ENTRY_FURNACE_DATA, - $input->getId(), - $input->getMeta(), - $converter->coreItemStackToNet($recipe->getResult()), - "furnace" - ); - } - - return $pk; - } - - /** - * Returns a pre-compressed CraftingDataPacket for sending to players. Rebuilds the cache if it is not found. - */ - public function getCraftingDataPacket() : CraftingDataPacket{ - if($this->craftingDataCache === null){ - $this->craftingDataCache = $this->buildCraftingDataCache(); - } - - return $this->craftingDataCache; - } + /** @phpstan-return Set<\Closure() : void> */ + public function getRecipeRegisteredCallbacks() : Set{ return $this->recipeRegisteredCallbacks; } /** * Function used to arrange Shapeless Recipe ingredient lists into a consistent order. @@ -205,13 +128,17 @@ class CraftingManager{ public function registerShapedRecipe(ShapedRecipe $recipe) : void{ $this->shapedRecipes[self::hashOutputs($recipe->getResults())][] = $recipe; - $this->craftingDataCache = null; + foreach($this->recipeRegisteredCallbacks as $callback){ + $callback(); + } } public function registerShapelessRecipe(ShapelessRecipe $recipe) : void{ $this->shapelessRecipes[self::hashOutputs($recipe->getResults())][] = $recipe; - $this->craftingDataCache = null; + foreach($this->recipeRegisteredCallbacks as $callback){ + $callback(); + } } /** diff --git a/src/network/mcpe/CraftingDataCache.php b/src/network/mcpe/CraftingDataCache.php new file mode 100644 index 0000000000..84b7e490c6 --- /dev/null +++ b/src/network/mcpe/CraftingDataCache.php @@ -0,0 +1,132 @@ + + */ + private $caches = []; + + public function getCache(CraftingManager $manager) : CraftingDataPacket{ + $id = spl_object_id($manager); + if(!isset($this->caches[$id])){ + $manager->getDestructorCallbacks()->add(function() use ($id) : void{ + unset($this->caches[$id]); + }); + $manager->getRecipeRegisteredCallbacks()->add(function() use ($id) : void{ + unset($this->caches[$id]); + }); + $this->caches[$id] = $this->buildCraftingDataCache($manager); + } + return $this->caches[$id]; + } + + /** + * Rebuilds the cached CraftingDataPacket. + */ + private function buildCraftingDataCache(CraftingManager $manager) : CraftingDataPacket{ + Timings::$craftingDataCacheRebuildTimer->startTiming(); + $pk = new CraftingDataPacket(); + $pk->cleanRecipes = true; + + $counter = 0; + $nullUUID = UUID::fromData(str_repeat("\x00", 16)); + $converter = TypeConverter::getInstance(); + foreach($manager->getShapelessRecipes() as $list){ + foreach($list as $recipe){ + $pk->entries[] = new ProtocolShapelessRecipe( + CraftingDataPacket::ENTRY_SHAPELESS, + Binary::writeInt($counter++), + array_map(function(Item $item) use ($converter) : RecipeIngredient{ + return $converter->coreItemStackToRecipeIngredient($item); + }, $recipe->getIngredientList()), + array_map(function(Item $item) use ($converter) : ItemStack{ + return $converter->coreItemStackToNet($item); + }, $recipe->getResults()), + $nullUUID, + "crafting_table", + 50, + $counter + ); + } + } + foreach($manager->getShapedRecipes() as $list){ + foreach($list as $recipe){ + $inputs = []; + + for($row = 0, $height = $recipe->getHeight(); $row < $height; ++$row){ + for($column = 0, $width = $recipe->getWidth(); $column < $width; ++$column){ + $inputs[$row][$column] = $converter->coreItemStackToRecipeIngredient($recipe->getIngredient($column, $row)); + } + } + $pk->entries[] = $r = new ProtocolShapedRecipe( + CraftingDataPacket::ENTRY_SHAPED, + Binary::writeInt($counter++), + $inputs, + array_map(function(Item $item) use ($converter) : ItemStack{ + return $converter->coreItemStackToNet($item); + }, $recipe->getResults()), + $nullUUID, + "crafting_table", + 50, + $counter + ); + } + } + + foreach($manager->getFurnaceRecipeManager()->getAll() as $recipe){ + $input = $converter->coreItemStackToNet($recipe->getInput()); + $pk->entries[] = new ProtocolFurnaceRecipe( + CraftingDataPacket::ENTRY_FURNACE_DATA, + $input->getId(), + $input->getMeta(), + $converter->coreItemStackToNet($recipe->getResult()), + "furnace" + ); + } + + return $pk; + } +} diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index 0e20bc8471..f40dc13a1d 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\handler; use pocketmine\data\bedrock\LegacyItemIdToStringIdMap; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\convert\TypeConverter; +use pocketmine\network\mcpe\CraftingDataCache; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; use pocketmine\network\mcpe\protocol\StartGamePacket; @@ -100,7 +101,7 @@ class PreSpawnPacketHandler extends PacketHandler{ $this->session->getInvManager()->syncAll(); $this->session->getInvManager()->syncCreative(); $this->session->getInvManager()->syncSelectedHotbarSlot(); - $this->session->sendDataPacket($this->server->getCraftingManager()->getCraftingDataPacket()); + $this->session->sendDataPacket(CraftingDataCache::getInstance()->getCache($this->server->getCraftingManager())); $this->session->syncPlayerList($this->server->getOnlinePlayers()); } diff --git a/src/utils/DestructorCallbackTrait.php b/src/utils/DestructorCallbackTrait.php new file mode 100644 index 0000000000..63e3e34024 --- /dev/null +++ b/src/utils/DestructorCallbackTrait.php @@ -0,0 +1,52 @@ +|null + */ + private $destructorCallbacks = null; + + /** @phpstan-return Set<\Closure() : void> */ + public function getDestructorCallbacks() : Set{ + return $this->destructorCallbacks === null ? ($this->destructorCallbacks = new Set()) : $this->destructorCallbacks; + } + + public function __destruct(){ + if($this->destructorCallbacks !== null){ + foreach($this->destructorCallbacks as $callback){ + $callback(); + } + } + } +} From 04b038ff4b82c936c405c8dbdf547e4659863502 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Nov 2020 21:34:12 +0000 Subject: [PATCH 2082/3224] [ci skip] more detail to PM4 changelog --- changelogs/4.0-snapshot.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index cb253ab091..a9ad15279c 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -699,6 +699,7 @@ This version features substantial changes to the network system, improving coher - `Server->isLevelGenerated()` -> `WorldManager->isWorldGenerated()` - `Server->isLevelLoaded()` -> `WorldManager->isWorldLoaded()` - `Server->loadLevel()` -> `WorldManager->loadWorld()` + - `WorldManager->loadWorld()` may convert worlds if requested (the `$autoUpgrade` parameter must be provided). - `Server->setAutoSave()` -> `WorldManager->setAutoSave()` - `Server->setDefaultLevel()` -> `WorldManager->setDefaultWorld()` - `Server->unloadLevel()` -> `WorldManager->unloadWorld()` @@ -714,6 +715,9 @@ This version features substantial changes to the network system, improving coher - `World->unregisterChunkListener()` - The following API methods have been removed: - `ChunkLoader->getLoaderId()` (now object ID is used) + - `ChunkLoader->isLoaderActive()` + - `ChunkLoader->getPosition()` + - `ChunkLoader->getLevel()` - `World->isFullBlock()` - `World->getFullBlock()` - `World->getBlockIdAt()` @@ -755,6 +759,8 @@ This version features substantial changes to the network system, improving coher - The following API methods have been renamed / moved: - `Level->getCollisionCubes()` -> `World->getCollisionBoxes()` - `World->getName()` -> `World->getDisplayName()` +- The following API methods have changed behaviour: + - `World->getChunk()` no longer tries to load chunks from disk. If the chunk is not already in memory, null is returned. (This behaviour now properly matches other `ChunkManager` implementations.) - Extracted a unit `pocketmine\world\format\io\FastChunkSerializer` from `Chunk`: - `Chunk->fastDeserialize()` -> `FastChunkSerializer::deserialize()` - `Chunk->fastSerialize()` -> `FastChunkSerializer::serialize()` From 41a8007c47220a8b1a294c4e927c10a4b6aeb5f7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Nov 2020 22:26:04 +0000 Subject: [PATCH 2083/3224] phpstan: drop some error counts to account for recent Sugarcane changes --- tests/phpstan/configs/l7-baseline.neon | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index 99f510fc3f..3b68bbde5e 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -427,17 +427,17 @@ parameters: - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" - count: 2 + count: 1 path: ../../../src/block/Sugarcane.php - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" - count: 2 + count: 1 path: ../../../src/block/Sugarcane.php - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" - count: 2 + count: 1 path: ../../../src/block/Sugarcane.php - From 7469f28f247b01ecc1a47c53b499414f98f50c9f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 14 Nov 2020 15:49:41 +0000 Subject: [PATCH 2084/3224] Server: rename getPlayer() to getPlayerByPrefix() closes #3910 the existing naming was misleading, and many plugin devs assumed that it returns an exact match. However, this is not guaranteed, and it's possible for two different players to match the same prefix. - There is no defined behaviour for what happens when multiple players can equally match a prefix (e.g. 'fr' could match 'fred' or 'frog' equally, because the name lengths are the same) - A prefix might match a different player at a different time (e.g. 'fr' could match 'freddie' before 'fred' joins, after which it will match 'fred' instead) With these flaws in mind, it's better to break compatibility on this to make the intent more clear, and to make plugin developers reassess their usages of this method. In most non-command use cases, they should likely be using getPlayerExact() instead. --- changelogs/4.0-snapshot.md | 2 ++ src/Server.php | 2 +- src/command/defaults/BanIpCommand.php | 2 +- src/command/defaults/EffectCommand.php | 2 +- src/command/defaults/EnchantCommand.php | 2 +- src/command/defaults/GamemodeCommand.php | 2 +- src/command/defaults/GiveCommand.php | 2 +- src/command/defaults/KickCommand.php | 2 +- src/command/defaults/KillCommand.php | 2 +- src/command/defaults/SpawnpointCommand.php | 2 +- src/command/defaults/TeleportCommand.php | 2 +- src/command/defaults/TellCommand.php | 2 +- src/command/defaults/TitleCommand.php | 2 +- 13 files changed, 14 insertions(+), 12 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index a9ad15279c..2328392f07 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -681,6 +681,8 @@ This version features substantial changes to the network system, improving coher - `getGamemodeFromString()` - replaced by `GameMode::fromString()` - The following API methods have changed: - `getOfflinePlayerData()` no longer creates data when it doesn't exist. +- The following API methods have been renamed: + - `getPlayer()` -> `getPlayerByPrefix()` (consider using `getPlayerExact()` instead where possible) ### Level / World #### General diff --git a/src/Server.php b/src/Server.php index c046858779..f75371cc18 100644 --- a/src/Server.php +++ b/src/Server.php @@ -570,7 +570,7 @@ class Server{ * * @see Server::getPlayerExact() */ - public function getPlayer(string $name) : ?Player{ + public function getPlayerByPrefix(string $name) : ?Player{ $found = null; $name = strtolower($name); $delta = PHP_INT_MAX; diff --git a/src/command/defaults/BanIpCommand.php b/src/command/defaults/BanIpCommand.php index b70d1ff71b..4737ac6b74 100644 --- a/src/command/defaults/BanIpCommand.php +++ b/src/command/defaults/BanIpCommand.php @@ -61,7 +61,7 @@ class BanIpCommand extends VanillaCommand{ Command::broadcastCommandMessage($sender, new TranslationContainer("commands.banip.success", [$value])); }else{ - if(($player = $sender->getServer()->getPlayer($value)) instanceof Player){ + if(($player = $sender->getServer()->getPlayerByPrefix($value)) instanceof Player){ $ip = $player->getNetworkSession()->getIp(); $this->processIPBan($ip, $sender, $reason); diff --git a/src/command/defaults/EffectCommand.php b/src/command/defaults/EffectCommand.php index d6d38a3417..df704ba728 100644 --- a/src/command/defaults/EffectCommand.php +++ b/src/command/defaults/EffectCommand.php @@ -53,7 +53,7 @@ class EffectCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $player = $sender->getServer()->getPlayer($args[0]); + $player = $sender->getServer()->getPlayerByPrefix($args[0]); if($player === null){ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); diff --git a/src/command/defaults/EnchantCommand.php b/src/command/defaults/EnchantCommand.php index 8ae0d43d1d..4c44165678 100644 --- a/src/command/defaults/EnchantCommand.php +++ b/src/command/defaults/EnchantCommand.php @@ -51,7 +51,7 @@ class EnchantCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $player = $sender->getServer()->getPlayer($args[0]); + $player = $sender->getServer()->getPlayerByPrefix($args[0]); if($player === null){ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); diff --git a/src/command/defaults/GamemodeCommand.php b/src/command/defaults/GamemodeCommand.php index eb239c2069..c6cc022043 100644 --- a/src/command/defaults/GamemodeCommand.php +++ b/src/command/defaults/GamemodeCommand.php @@ -60,7 +60,7 @@ class GamemodeCommand extends VanillaCommand{ } if(isset($args[1])){ - $target = $sender->getServer()->getPlayer($args[1]); + $target = $sender->getServer()->getPlayerByPrefix($args[1]); if($target === null){ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); diff --git a/src/command/defaults/GiveCommand.php b/src/command/defaults/GiveCommand.php index a3632fa4cb..1812e6c0c9 100644 --- a/src/command/defaults/GiveCommand.php +++ b/src/command/defaults/GiveCommand.php @@ -55,7 +55,7 @@ class GiveCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $player = $sender->getServer()->getPlayer($args[0]); + $player = $sender->getServer()->getPlayerByPrefix($args[0]); if($player === null){ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); return true; diff --git a/src/command/defaults/KickCommand.php b/src/command/defaults/KickCommand.php index f9cb617601..f90592e4e9 100644 --- a/src/command/defaults/KickCommand.php +++ b/src/command/defaults/KickCommand.php @@ -57,7 +57,7 @@ class KickCommand extends VanillaCommand{ $name = array_shift($args); $reason = trim(implode(" ", $args)); - if(($player = $sender->getServer()->getPlayer($name)) instanceof Player){ + if(($player = $sender->getServer()->getPlayerByPrefix($name)) instanceof Player){ $player->kick("Kicked by admin." . ($reason !== "" ? "Reason: " . $reason : "")); if($reason !== ""){ Command::broadcastCommandMessage($sender, new TranslationContainer("commands.kick.success.reason", [$player->getName(), $reason])); diff --git a/src/command/defaults/KillCommand.php b/src/command/defaults/KillCommand.php index 16a6e8e42a..f717719163 100644 --- a/src/command/defaults/KillCommand.php +++ b/src/command/defaults/KillCommand.php @@ -60,7 +60,7 @@ class KillCommand extends VanillaCommand{ return true; } - $player = $sender->getServer()->getPlayer($args[0]); + $player = $sender->getServer()->getPlayerByPrefix($args[0]); if($player instanceof Player){ $player->attack(new EntityDamageEvent($player, EntityDamageEvent::CAUSE_SUICIDE, 1000)); diff --git a/src/command/defaults/SpawnpointCommand.php b/src/command/defaults/SpawnpointCommand.php index 91813c24c8..3fe4538441 100644 --- a/src/command/defaults/SpawnpointCommand.php +++ b/src/command/defaults/SpawnpointCommand.php @@ -61,7 +61,7 @@ class SpawnpointCommand extends VanillaCommand{ return true; } }else{ - $target = $sender->getServer()->getPlayer($args[0]); + $target = $sender->getServer()->getPlayerByPrefix($args[0]); if($target === null){ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); diff --git a/src/command/defaults/TeleportCommand.php b/src/command/defaults/TeleportCommand.php index ff302bd8cc..5dd3d9b144 100644 --- a/src/command/defaults/TeleportCommand.php +++ b/src/command/defaults/TeleportCommand.php @@ -48,7 +48,7 @@ class TeleportCommand extends VanillaCommand{ } private function findPlayer(CommandSender $sender, string $playerName) : ?Player{ - $subject = $sender->getServer()->getPlayer($playerName); + $subject = $sender->getServer()->getPlayerByPrefix($playerName); if($subject === null){ $sender->sendMessage(TextFormat::RED . "Can't find player " . $playerName); return null; diff --git a/src/command/defaults/TellCommand.php b/src/command/defaults/TellCommand.php index 443d1e9794..27f9d811c6 100644 --- a/src/command/defaults/TellCommand.php +++ b/src/command/defaults/TellCommand.php @@ -54,7 +54,7 @@ class TellCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $player = $sender->getServer()->getPlayer(array_shift($args)); + $player = $sender->getServer()->getPlayerByPrefix(array_shift($args)); if($player === $sender){ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.message.sameTarget")); diff --git a/src/command/defaults/TitleCommand.php b/src/command/defaults/TitleCommand.php index 030888912b..f03123fdbb 100644 --- a/src/command/defaults/TitleCommand.php +++ b/src/command/defaults/TitleCommand.php @@ -50,7 +50,7 @@ class TitleCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $player = $sender->getServer()->getPlayer($args[0]); + $player = $sender->getServer()->getPlayerByPrefix($args[0]); if($player === null){ $sender->sendMessage(new TranslationContainer("commands.generic.player.notFound")); return true; From 06efad94b64e1c625552717d473cc1221bdb6d3f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 14 Nov 2020 16:21:50 +0000 Subject: [PATCH 2085/3224] Separated metadata handling from PillarRotationTrait --- src/block/BlockFactory.php | 8 +- src/block/BoneBlock.php | 4 +- src/block/HayBale.php | 4 +- src/block/Log.php | 4 +- .../utils/PillarRotationInMetadataTrait.php | 76 +++++++++++++++++++ src/block/utils/PillarRotationTrait.php | 46 ----------- 6 files changed, 86 insertions(+), 56 deletions(-) create mode 100644 src/block/utils/PillarRotationInMetadataTrait.php diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 31b2404d81..36e618068b 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -46,7 +46,7 @@ use pocketmine\block\tile\Note as TileNote; use pocketmine\block\tile\Skull as TileSkull; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\InvalidBlockStateException; -use pocketmine\block\utils\PillarRotationTrait; +use pocketmine\block\utils\PillarRotationInMetadataTrait; use pocketmine\block\utils\TreeType; use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\item\Item; @@ -293,7 +293,7 @@ class BlockFactory{ $purpurBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); $this->register(new Opaque(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_NORMAL), "Purpur Block", $purpurBreakInfo)); $this->register(new class(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_PILLAR), "Purpur Pillar", $purpurBreakInfo) extends Opaque{ - use PillarRotationTrait; + use PillarRotationInMetadataTrait; }); $this->register(new Stair(new BID(Ids::PURPUR_STAIRS), "Purpur Stairs", $purpurBreakInfo)); @@ -301,10 +301,10 @@ class BlockFactory{ $this->register(new Opaque(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_NORMAL), "Quartz Block", $quartzBreakInfo)); $this->register(new Stair(new BID(Ids::QUARTZ_STAIRS), "Quartz Stairs", $quartzBreakInfo)); $this->register(new class(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_CHISELED), "Chiseled Quartz Block", $quartzBreakInfo) extends Opaque{ - use PillarRotationTrait; + use PillarRotationInMetadataTrait; }); $this->register(new class(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_PILLAR), "Quartz Pillar", $quartzBreakInfo) extends Opaque{ - use PillarRotationTrait; + use PillarRotationInMetadataTrait; }); $this->register(new Opaque(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_SMOOTH), "Smooth Quartz Block", $quartzBreakInfo)); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) $this->register(new Stair(new BID(Ids::SMOOTH_QUARTZ_STAIRS), "Smooth Quartz Stairs", $quartzBreakInfo)); diff --git a/src/block/BoneBlock.php b/src/block/BoneBlock.php index 4581038529..49ca51f9bd 100644 --- a/src/block/BoneBlock.php +++ b/src/block/BoneBlock.php @@ -23,11 +23,11 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\PillarRotationTrait; +use pocketmine\block\utils\PillarRotationInMetadataTrait; use pocketmine\item\ToolTier; class BoneBlock extends Opaque{ - use PillarRotationTrait; + use PillarRotationInMetadataTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); diff --git a/src/block/HayBale.php b/src/block/HayBale.php index d6c1be2860..6d70a82309 100644 --- a/src/block/HayBale.php +++ b/src/block/HayBale.php @@ -23,10 +23,10 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\PillarRotationTrait; +use pocketmine\block\utils\PillarRotationInMetadataTrait; class HayBale extends Opaque{ - use PillarRotationTrait; + use PillarRotationInMetadataTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5)); diff --git a/src/block/Log.php b/src/block/Log.php index ca9346cab9..06364c746b 100644 --- a/src/block/Log.php +++ b/src/block/Log.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\PillarRotationTrait; +use pocketmine\block\utils\PillarRotationInMetadataTrait; class Log extends Wood{ - use PillarRotationTrait; + use PillarRotationInMetadataTrait; } diff --git a/src/block/utils/PillarRotationInMetadataTrait.php b/src/block/utils/PillarRotationInMetadataTrait.php new file mode 100644 index 0000000000..42adf7120c --- /dev/null +++ b/src/block/utils/PillarRotationInMetadataTrait.php @@ -0,0 +1,76 @@ +writeAxisToMeta(); + } + + /** + * @see Block::readStateFromData() + */ + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->readAxisFromMeta($stateMeta); + } + + /** + * @see Block::getStateBitmask() + */ + public function getStateBitmask() : int{ + return 0b11 << $this->getAxisMetaShift(); + } + + protected function readAxisFromMeta(int $meta) : void{ + $axis = $meta >> $this->getAxisMetaShift(); + $mapped = [ + 0 => Axis::Y, + 1 => Axis::X, + 2 => Axis::Z + ][$axis] ?? null; + if($mapped === null){ + throw new InvalidBlockStateException("Invalid axis meta $axis"); + } + $this->axis = $mapped; + } + + protected function writeAxisToMeta() : int{ + return [ + Axis::Y => 0, + Axis::Z => 2, + Axis::X => 1 + ][$this->axis] << $this->getAxisMetaShift(); + } +} diff --git a/src/block/utils/PillarRotationTrait.php b/src/block/utils/PillarRotationTrait.php index 77144c4eb7..806782db8f 100644 --- a/src/block/utils/PillarRotationTrait.php +++ b/src/block/utils/PillarRotationTrait.php @@ -36,52 +36,6 @@ trait PillarRotationTrait{ /** @var int */ protected $axis = Axis::Y; - protected function getAxisMetaShift() : int{ - return 2; //default - } - - /** - * @see Block::writeStateToMeta() - */ - protected function writeStateToMeta() : int{ - return $this->writeAxisToMeta(); - } - - /** - * @see Block::readStateFromData() - */ - public function readStateFromData(int $id, int $stateMeta) : void{ - $this->readAxisFromMeta($stateMeta); - } - - /** - * @see Block::getStateBitmask() - */ - public function getStateBitmask() : int{ - return 0b11 << $this->getAxisMetaShift(); - } - - protected function readAxisFromMeta(int $meta) : void{ - $axis = $meta >> $this->getAxisMetaShift(); - $mapped = [ - 0 => Axis::Y, - 1 => Axis::X, - 2 => Axis::Z - ][$axis] ?? null; - if($mapped === null){ - throw new InvalidBlockStateException("Invalid axis meta $axis"); - } - $this->axis = $mapped; - } - - protected function writeAxisToMeta() : int{ - return [ - Axis::Y => 0, - Axis::Z => 2, - Axis::X => 1 - ][$this->axis] << $this->getAxisMetaShift(); - } - /** @see Axis */ public function getAxis() : int{ return $this->axis; } From 4ade7b62250b7cf3530a520538cd036284da25c2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 14 Nov 2020 16:24:13 +0000 Subject: [PATCH 2086/3224] added CoralType enum --- src/block/utils/CoralType.php | 69 +++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/block/utils/CoralType.php diff --git a/src/block/utils/CoralType.php b/src/block/utils/CoralType.php new file mode 100644 index 0000000000..8849ae3535 --- /dev/null +++ b/src/block/utils/CoralType.php @@ -0,0 +1,69 @@ +Enum___construct($name); + $this->magicNumber = $magicNumber; //TODO: remove this + $this->displayName = $displayName; + } + + public function getDisplayName() : string{ return $this->displayName; } + + /** @deprecated */ + public function getMagicNumber() : int{ return $this->magicNumber; } +} From b534ae050eeb6ffd552f6f694e759d7c14dc635a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 14 Nov 2020 16:51:13 +0000 Subject: [PATCH 2087/3224] DisallowEnumComparisonRule: detect bugs involving union types (Enum|null compared to Enum|null) --- .../rules/DisallowEnumComparisonRule.php | 54 +++++++++++++------ 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/tests/phpstan/rules/DisallowEnumComparisonRule.php b/tests/phpstan/rules/DisallowEnumComparisonRule.php index 5370d158dc..726c4cfbfe 100644 --- a/tests/phpstan/rules/DisallowEnumComparisonRule.php +++ b/tests/phpstan/rules/DisallowEnumComparisonRule.php @@ -31,6 +31,8 @@ use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\ObjectType; +use PHPStan\Type\Type; +use PHPStan\Type\UnionType; use PHPStan\Type\VerbosityLevel; use pocketmine\utils\EnumTrait; use function sprintf; @@ -48,23 +50,41 @@ class DisallowEnumComparisonRule implements Rule{ if(!($node instanceof Identical) and !($node instanceof NotIdentical)){ return []; } - - $result = []; - foreach([$node->left, $node->right] as $n){ - $type = $scope->getType($n); - if(!($type instanceof ObjectType)){ - continue; - } - $class = $type->getClassReflection(); - if($class === null or !$class->hasTraitUse(EnumTrait::class)){ - continue; - } - $result[] = RuleErrorBuilder::message(sprintf( - 'Strict comparison using %s involving enum %s is not reliable.', + + $leftType = $scope->getType($node->left); + $rightType = $scope->getType($node->right); + $leftEnum = $this->checkForEnumTypes($leftType); + $rightEnum = $this->checkForEnumTypes($rightType); + if($leftEnum && $rightEnum){ + return [RuleErrorBuilder::message(sprintf( + 'Strict comparison using %s involving enum types %s and %s is not reliable.', $node instanceof Identical ? '===' : '!==', - $type->describe(VerbosityLevel::value()) - ))->build(); + $leftType->describe(VerbosityLevel::value()), + $rightType->describe(VerbosityLevel::value()) + ))->build()]; } - return $result; + return []; } -} \ No newline at end of file + + private function checkForEnumTypes(Type $comparedType) : bool{ + //TODO: what we really want to do here is iterate over the contained types, but there's no universal way to + //do that. This might break with other circumstances. + if($comparedType instanceof ObjectType){ + $types = [$comparedType]; + }elseif($comparedType instanceof UnionType){ + $types = $comparedType->getTypes(); + }else{ + return false; + } + foreach($types as $containedType){ + if(!($containedType instanceof ObjectType)){ + continue; + } + $class = $containedType->getClassReflection(); + if($class !== null and $class->hasTraitUse(EnumTrait::class)){ + return true; + } + } + return false; + } +} From 1cf3a500f826a32e00c85acfd7de8a04f01f102c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 16 Nov 2020 16:59:19 +0000 Subject: [PATCH 2088/3224] Clean up ChestInventory handling longer term I want to rip this crap out completely, but right now this provides minor maintainability benefits, while also making it slightly less nasty to deal with other containers which animate their blocks, such as barrels and shulker boxes. --- .../inventory/AnimatedBlockInventory.php | 56 +++++++++++++++++++ src/block/inventory/ChestInventory.php | 25 +-------- src/block/inventory/DoubleChestInventory.php | 18 +----- 3 files changed, 61 insertions(+), 38 deletions(-) create mode 100644 src/block/inventory/AnimatedBlockInventory.php diff --git a/src/block/inventory/AnimatedBlockInventory.php b/src/block/inventory/AnimatedBlockInventory.php new file mode 100644 index 0000000000..fcc8e6699f --- /dev/null +++ b/src/block/inventory/AnimatedBlockInventory.php @@ -0,0 +1,56 @@ +getViewers()) === 1 and $this->getHolder()->isValid()){ + //TODO: this crap really shouldn't be managed by the inventory + $this->animateBlock(true); + $this->getHolder()->getWorld()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getOpenSound()); + } + } + + abstract protected function animateBlock(bool $isOpen) : void; + + public function onClose(Player $who) : void{ + if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){ + //TODO: this crap really shouldn't be managed by the inventory + $this->animateBlock(false); + $this->getHolder()->getWorld()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getCloseSound()); + } + parent::onClose($who); + } +} diff --git a/src/block/inventory/ChestInventory.php b/src/block/inventory/ChestInventory.php index 5675f28b75..2f73269e84 100644 --- a/src/block/inventory/ChestInventory.php +++ b/src/block/inventory/ChestInventory.php @@ -24,14 +24,12 @@ declare(strict_types=1); namespace pocketmine\block\inventory; use pocketmine\network\mcpe\protocol\BlockEventPacket; -use pocketmine\player\Player; use pocketmine\world\Position; use pocketmine\world\sound\ChestCloseSound; use pocketmine\world\sound\ChestOpenSound; use pocketmine\world\sound\Sound; -use function count; -class ChestInventory extends BlockInventory{ +class ChestInventory extends AnimatedBlockInventory{ public function __construct(Position $holder){ parent::__construct($holder, 27); @@ -45,26 +43,7 @@ class ChestInventory extends BlockInventory{ return new ChestCloseSound(); } - public function onOpen(Player $who) : void{ - parent::onOpen($who); - - if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){ - //TODO: this crap really shouldn't be managed by the inventory - $this->broadcastBlockEventPacket(true); - $this->getHolder()->getWorld()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getOpenSound()); - } - } - - public function onClose(Player $who) : void{ - if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){ - //TODO: this crap really shouldn't be managed by the inventory - $this->broadcastBlockEventPacket(false); - $this->getHolder()->getWorld()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getCloseSound()); - } - parent::onClose($who); - } - - protected function broadcastBlockEventPacket(bool $isOpen) : void{ + protected function animateBlock(bool $isOpen) : void{ $holder = $this->getHolder(); //event ID is always 1 for a chest diff --git a/src/block/inventory/DoubleChestInventory.php b/src/block/inventory/DoubleChestInventory.php index 1998f18229..978d132b0a 100644 --- a/src/block/inventory/DoubleChestInventory.php +++ b/src/block/inventory/DoubleChestInventory.php @@ -26,9 +26,7 @@ namespace pocketmine\block\inventory; use pocketmine\inventory\BaseInventory; use pocketmine\inventory\InventoryHolder; use pocketmine\item\Item; -use pocketmine\player\Player; use pocketmine\world\Position; -use function count; class DoubleChestInventory extends ChestInventory implements InventoryHolder{ /** @var ChestInventory */ @@ -74,19 +72,9 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ return $result; } - public function onOpen(Player $who) : void{ - parent::onOpen($who); - - if(count($this->getViewers()) === 1 and $this->right->getHolder()->isValid()){ - $this->right->broadcastBlockEventPacket(true); - } - } - - public function onClose(Player $who) : void{ - if(count($this->getViewers()) === 1 and $this->right->getHolder()->isValid()){ - $this->right->broadcastBlockEventPacket(false); - } - parent::onClose($who); + protected function animateBlock(bool $isOpen) : void{ + $this->left->animateBlock($isOpen); + $this->right->animateBlock($isOpen); } public function getLeftSide() : ChestInventory{ From b2765f32e996e11ace01a5cd12ad313f1fca4b1f Mon Sep 17 00:00:00 2001 From: Aericio <16523741+Aericio@users.noreply.github.com> Date: Mon, 16 Nov 2020 17:26:07 +0000 Subject: [PATCH 2089/3224] Implemented Barrels, closes #3672 --- src/block/Barrel.php | 105 ++++++++++++++++++ src/block/BlockFactory.php | 3 +- src/block/BlockLegacyMetadata.php | 2 + src/block/inventory/BarrelInventory.php | 53 +++++++++ src/block/tile/Barrel.php | 78 +++++++++++++ src/block/tile/TileFactory.php | 2 +- src/world/sound/BarrelCloseSound.php | 34 ++++++ src/world/sound/BarrelOpenSound.php | 34 ++++++ tests/phpstan/configs/gc-hacks.neon | 5 + .../block_factory_consistency_check.json | 2 +- 10 files changed, 315 insertions(+), 3 deletions(-) create mode 100644 src/block/Barrel.php create mode 100644 src/block/inventory/BarrelInventory.php create mode 100644 src/block/tile/Barrel.php create mode 100644 src/world/sound/BarrelCloseSound.php create mode 100644 src/world/sound/BarrelOpenSound.php diff --git a/src/block/Barrel.php b/src/block/Barrel.php new file mode 100644 index 0000000000..277cd92992 --- /dev/null +++ b/src/block/Barrel.php @@ -0,0 +1,105 @@ +facing) | ($this->open ? BlockLegacyMetadata::BARREL_FLAG_OPEN : 0); + } + + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataSerializer::readFacing($stateMeta & 0x07); + $this->open = ($stateMeta & BlockLegacyMetadata::BARREL_FLAG_OPEN) === BlockLegacyMetadata::BARREL_FLAG_OPEN; + } + + public function getStateBitmask() : int{ + return 0b1111; + } + + public function isOpen() : bool{ + return $this->open; + } + + public function setOpen(bool $open) : Barrel{ + $this->open = $open; + return $this; + } + + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($player !== null){ + if(abs($player->getPosition()->getX() - $this->pos->getX()) < 2 && abs($player->getPosition()->getZ() - $this->pos->getZ()) < 2){ + $y = $player->getEyePos()->getY(); + + if($y - $this->pos->getY() > 2){ + $this->facing = Facing::UP; + }elseif($this->pos->getY() - $y > 0){ + $this->facing = Facing::DOWN; + }else{ + $this->facing = Facing::opposite($player->getHorizontalFacing()); + } + }else{ + $this->facing = Facing::opposite($player->getHorizontalFacing()); + } + } + + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($player instanceof Player){ + $barrel = $this->pos->getWorld()->getTile($this->pos); + if($barrel instanceof TileBarrel){ + if(!$barrel->canOpenWith($item->getCustomName())){ + return true; + } + + $player->setCurrentWindow($barrel->getInventory()); + } + } + + return true; + } + + public function getFuelTime() : int{ + return 300; + } +} diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 36e618068b..7744d6d3c8 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -28,6 +28,7 @@ use pocketmine\block\BlockIdentifierFlattened as BIDFlattened; use pocketmine\block\BlockLegacyIds as Ids; use pocketmine\block\BlockLegacyMetadata as Meta; use pocketmine\block\tile\Banner as TileBanner; +use pocketmine\block\tile\Barrel as TileBarrel; use pocketmine\block\tile\Beacon as TileBeacon; use pocketmine\block\tile\Bed as TileBed; use pocketmine\block\tile\BrewingStand as TileBrewingStand; @@ -106,6 +107,7 @@ class BlockFactory{ $this->register(new BambooSapling(new BID(Ids::BAMBOO_SAPLING), "Bamboo Sapling", BlockBreakInfo::instant())); $this->register(new FloorBanner(new BID(Ids::STANDING_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Banner")); $this->register(new WallBanner(new BID(Ids::WALL_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Wall Banner")); + $this->register(new Barrel(new BID(Ids::BARREL, 0, null, TileBarrel::class), "Barrel")); $this->register(new Transparent(new BID(Ids::BARRIER), "Barrier", BlockBreakInfo::indestructible())); $this->register(new Beacon(new BID(Ids::BEACON, 0, null, TileBeacon::class), "Beacon", new BlockBreakInfo(3.0))); $this->register(new Bed(new BID(Ids::BED_BLOCK, 0, ItemIds::BED, TileBed::class), "Bed Block")); @@ -508,7 +510,6 @@ class BlockFactory{ //region --- auto-generated TODOs for bedrock-1.11.0 --- //TODO: minecraft:bamboo //TODO: minecraft:bamboo_sapling - //TODO: minecraft:barrel //TODO: minecraft:beacon //TODO: minecraft:bell //TODO: minecraft:blast_furnace diff --git a/src/block/BlockLegacyMetadata.php b/src/block/BlockLegacyMetadata.php index f9da4c53c5..bbc1485fc8 100644 --- a/src/block/BlockLegacyMetadata.php +++ b/src/block/BlockLegacyMetadata.php @@ -42,6 +42,8 @@ final class BlockLegacyMetadata{ public const BAMBOO_LEAF_SIZE_SHIFT = 1; public const BAMBOO_LEAF_SIZE_MASK = 0x03; + public const BARREL_FLAG_OPEN = 0x08; + public const BED_FLAG_HEAD = 0x08; public const BED_FLAG_OCCUPIED = 0x04; diff --git a/src/block/inventory/BarrelInventory.php b/src/block/inventory/BarrelInventory.php new file mode 100644 index 0000000000..bb05d1c9c9 --- /dev/null +++ b/src/block/inventory/BarrelInventory.php @@ -0,0 +1,53 @@ +getHolder(); + $block = $holder->getWorld()->getBlock($holder); + if($block instanceof Barrel){ + $holder->getWorld()->setBlock($holder, $block->setOpen($isOpen)); + } + } +} diff --git a/src/block/tile/Barrel.php b/src/block/tile/Barrel.php new file mode 100644 index 0000000000..ae8d6dfa8b --- /dev/null +++ b/src/block/tile/Barrel.php @@ -0,0 +1,78 @@ +inventory = new BarrelInventory($this->pos); + } + + public function readSaveData(CompoundTag $nbt) : void{ + $this->loadName($nbt); + $this->loadItems($nbt); + } + + protected function writeSaveData(CompoundTag $nbt) : void{ + $this->saveName($nbt); + $this->saveItems($nbt); + } + + public function close() : void{ + if(!$this->closed){ + $this->inventory->removeAllViewers(); + $this->inventory = null; + parent::close(); + } + } + + /** + * @return BarrelInventory + */ + public function getInventory(){ + return $this->inventory; + } + + /** + * @return BarrelInventory + */ + public function getRealInventory(){ + return $this->inventory; + } + + public function getDefaultName() : string{ + return "Barrel"; + } +} diff --git a/src/block/tile/TileFactory.php b/src/block/tile/TileFactory.php index 42b663b719..df67b18016 100644 --- a/src/block/tile/TileFactory.php +++ b/src/block/tile/TileFactory.php @@ -48,6 +48,7 @@ final class TileFactory{ private $saveNames = []; public function __construct(){ + $this->register(Barrel::class, ["Barrel", "minecraft:barrel"]); $this->register(Banner::class, ["Banner", "minecraft:banner"]); $this->register(Beacon::class, ["Beacon", "minecraft:beacon"]); $this->register(Bed::class, ["Bed", "minecraft:bed"]); @@ -67,7 +68,6 @@ final class TileFactory{ $this->register(Sign::class, ["Sign", "minecraft:sign"]); $this->register(Skull::class, ["Skull", "minecraft:skull"]); - //TODO: Barrel //TODO: Beacon //TODO: Bell //TODO: BlastFurnace diff --git a/src/world/sound/BarrelCloseSound.php b/src/world/sound/BarrelCloseSound.php new file mode 100644 index 0000000000..a493305117 --- /dev/null +++ b/src/world/sound/BarrelCloseSound.php @@ -0,0 +1,34 @@ + Date: Mon, 16 Nov 2020 17:29:24 +0000 Subject: [PATCH 2090/3224] Barrel: added @return $this to setOpen() --- src/block/Barrel.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/block/Barrel.php b/src/block/Barrel.php index 277cd92992..344f7a43a0 100644 --- a/src/block/Barrel.php +++ b/src/block/Barrel.php @@ -59,6 +59,7 @@ class Barrel extends Opaque{ return $this->open; } + /** @return $this */ public function setOpen(bool $open) : Barrel{ $this->open = $open; return $this; From 55a9ce46b98cf4b90dcf061e37bf7e24a20d4fda Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 16 Nov 2020 17:56:13 +0000 Subject: [PATCH 2091/3224] VanillaBlocks: added BARREL --- src/block/VanillaBlocks.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 02c4c5a11a..95236e113c 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -58,6 +58,7 @@ use function assert; * @method static Bamboo BAMBOO() * @method static BambooSapling BAMBOO_SAPLING() * @method static FloorBanner BANNER() + * @method static Barrel BARREL() * @method static Transparent BARRIER() * @method static Beacon BEACON() * @method static Bed BED() @@ -673,6 +674,7 @@ final class VanillaBlocks{ self::register("bamboo", $factory->get(418)); self::register("bamboo_sapling", $factory->get(419)); self::register("banner", $factory->get(176)); + self::register("barrel", $factory->get(458)); self::register("barrier", $factory->get(416)); self::register("beacon", $factory->get(138)); self::register("bed", $factory->get(26)); From 1eee24f1fa83c0e9fdbb3a9c78335872fb278c44 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 16 Nov 2020 18:05:39 +0000 Subject: [PATCH 2092/3224] Implemented coral blocks there are some complications with coral plants due to the fact we're stuck with R12 worlds right now - and also coral fans are a major pain to implement due to how messed up the metadata is. --- src/block/BlockFactory.php | 2 +- src/block/CoralBlock.php | 106 ++++++++++++++++++ src/block/VanillaBlocks.php | 2 + src/data/bedrock/CoralTypeIdMap.php | 68 +++++++++++ .../block_factory_consistency_check.json | 2 +- 5 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 src/block/CoralBlock.php create mode 100644 src/data/bedrock/CoralTypeIdMap.php diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 7744d6d3c8..d84941021c 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -141,6 +141,7 @@ class BlockFactory{ $this->register(new Cobweb(new BID(Ids::COBWEB), "Cobweb")); $this->register(new CocoaBlock(new BID(Ids::COCOA), "Cocoa Block")); + $this->register(new CoralBlock(new BID(Ids::CORAL_BLOCK), "Coral Block", new BlockBreakInfo(7.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); $this->register(new CraftingTable(new BID(Ids::CRAFTING_TABLE), "Crafting Table")); $this->register(new DaylightSensor(new BIDFlattened(Ids::DAYLIGHT_DETECTOR, Ids::DAYLIGHT_DETECTOR_INVERTED, 0, null, TileDaylightSensor::class), "Daylight Sensor")); $this->register(new DeadBush(new BID(Ids::DEADBUSH), "Dead Bush")); @@ -525,7 +526,6 @@ class BlockFactory{ //TODO: minecraft:composter //TODO: minecraft:conduit //TODO: minecraft:coral - //TODO: minecraft:coral_block //TODO: minecraft:coral_fan //TODO: minecraft:coral_fan_dead //TODO: minecraft:coral_fan_hang diff --git a/src/block/CoralBlock.php b/src/block/CoralBlock.php new file mode 100644 index 0000000000..9ea7db623c --- /dev/null +++ b/src/block/CoralBlock.php @@ -0,0 +1,106 @@ +coralType = CoralType::TUBE(); + parent::__construct($idInfo, $name, $breakInfo); + } + + public function readStateFromData(int $id, int $stateMeta) : void{ + $coralType = CoralTypeIdMap::getInstance()->fromId($stateMeta & 0x7); + if($coralType === null){ + throw new InvalidBlockStateException("No such coral type"); + } + $this->coralType = $coralType; + $this->dead = ($stateMeta & BlockLegacyMetadata::CORAL_BLOCK_FLAG_DEAD) !== 0; + } + + protected function writeStateToMeta() : int{ + return ($this->dead ? BlockLegacyMetadata::CORAL_BLOCK_FLAG_DEAD : 0) | CoralTypeIdMap::getInstance()->toId($this->coralType); + } + + public function getStateBitmask() : int{ + return 0b1111; + } + + public function getNonPersistentStateBitmask() : int{ + return 0; + } + + public function getCoralType() : CoralType{ return $this->coralType; } + + public function isDead() : bool{ return $this->dead; } + + /** @return $this */ + public function setDead(bool $dead) : self{ + $this->dead = $dead; + return $this; + } + + public function onNearbyBlockChange() : void{ + if(!$this->dead){ + $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(40, 200)); + } + } + + public function onScheduledUpdate() : void{ + if(!$this->dead){ + $world = $this->pos->getWorld(); + + $hasWater = false; + foreach($this->pos->sides() as $vector3){ + if($world->getBlock($vector3) instanceof Water){ + $hasWater = true; + break; + } + } + if(!$hasWater){ + $world->setBlock($this->pos, $this->setDead(true)); + } + } + } + + public function getDropsForCompatibleTool(Item $item) : array{ + return [$this->setDead(true)->asItem()]; + } + + public function isAffectedBySilkTouch() : bool{ + return true; + } +} diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 95236e113c..1c87871b1f 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -127,6 +127,7 @@ use function assert; * @method static ChemistryTable COMPOUND_CREATOR() * @method static Concrete CONCRETE() * @method static ConcretePowder CONCRETE_POWDER() + * @method static CoralBlock CORAL_BLOCK() * @method static Flower CORNFLOWER() * @method static Opaque CRACKED_STONE_BRICKS() * @method static CraftingTable CRAFTING_TABLE() @@ -743,6 +744,7 @@ final class VanillaBlocks{ self::register("compound_creator", $factory->get(238)); self::register("concrete", $factory->get(236)); self::register("concrete_powder", $factory->get(237)); + self::register("coral_block", $factory->get(387)); self::register("cornflower", $factory->get(38, 9)); self::register("cracked_stone_bricks", $factory->get(98, 2)); self::register("crafting_table", $factory->get(58)); diff --git a/src/data/bedrock/CoralTypeIdMap.php b/src/data/bedrock/CoralTypeIdMap.php new file mode 100644 index 0000000000..98f820cca9 --- /dev/null +++ b/src/data/bedrock/CoralTypeIdMap.php @@ -0,0 +1,68 @@ + + */ + private $idToEnum = []; + /** + * @var int[] + * @phpstan-var array + */ + private $enumToId = []; + + public function __construct(){ + $this->register(BlockLegacyMetadata::CORAL_VARIANT_TUBE, CoralType::TUBE()); + $this->register(BlockLegacyMetadata::CORAL_VARIANT_BRAIN, CoralType::BRAIN()); + $this->register(BlockLegacyMetadata::CORAL_VARIANT_BUBBLE, CoralType::BUBBLE()); + $this->register(BlockLegacyMetadata::CORAL_VARIANT_FIRE, CoralType::FIRE()); + $this->register(BlockLegacyMetadata::CORAL_VARIANT_HORN, CoralType::HORN()); + } + + public function register(int $id, CoralType $type) : void{ + $this->idToEnum[$id] = $type; + $this->enumToId[$type->id()] = $id; + } + + public function fromId(int $id) : ?CoralType{ + return $this->idToEnum[$id] ?? null; + } + + public function toId(CoralType $type) : int{ + if(!array_key_exists($type->id(), $this->enumToId)){ + throw new \InvalidArgumentException("Coral type does not have a mapped ID"); //this should never happen + } + return $this->enumToId[$type->id()]; + } +} diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 9e06b8e057..2977e8778a 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From fd88c78d3acd9a970850cb00a8385f770fb948cd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 16 Nov 2020 18:12:01 +0000 Subject: [PATCH 2093/3224] added test for CoralTypeIdMap we really need a better way to guarantee exhaustiveness for this ... --- .../data/bedrock/CoralTypeIdMapTest.php | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 tests/phpunit/data/bedrock/CoralTypeIdMapTest.php diff --git a/tests/phpunit/data/bedrock/CoralTypeIdMapTest.php b/tests/phpunit/data/bedrock/CoralTypeIdMapTest.php new file mode 100644 index 0000000000..9a71a369c1 --- /dev/null +++ b/tests/phpunit/data/bedrock/CoralTypeIdMapTest.php @@ -0,0 +1,38 @@ +toId($type); + $type2 = CoralTypeIdMap::getInstance()->fromId($id); + self::assertTrue($type->equals($type2)); + } + } +} From 563336cdc9b0f177660779c3d2889e8a87478336 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 16 Nov 2020 18:12:38 +0000 Subject: [PATCH 2094/3224] CoralType: remove unused magicNumber stuff --- src/block/utils/CoralType.php | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/block/utils/CoralType.php b/src/block/utils/CoralType.php index 8849ae3535..0b84c7a061 100644 --- a/src/block/utils/CoralType.php +++ b/src/block/utils/CoralType.php @@ -41,29 +41,23 @@ final class CoralType{ __construct as Enum___construct; } - /** @var int */ - private $magicNumber; /** @var string */ private $displayName; protected static function setup() : void{ self::registerAll( - new self("tube", "Tube", 0), - new self("brain", "Brain", 1), - new self("bubble", "Bubble", 2), - new self("fire", "Fire", 3), - new self("horn", "Horn", 4), + new self("tube", "Tube"), + new self("brain", "Brain"), + new self("bubble", "Bubble"), + new self("fire", "Fire"), + new self("horn", "Horn"), ); } - private function __construct(string $name, string $displayName, int $magicNumber){ + private function __construct(string $name, string $displayName){ $this->Enum___construct($name); - $this->magicNumber = $magicNumber; //TODO: remove this $this->displayName = $displayName; } public function getDisplayName() : string{ return $this->displayName; } - - /** @deprecated */ - public function getMagicNumber() : int{ return $this->magicNumber; } } From 430d16e5f5da4d0408ce48599acfb25b257693e4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 16 Nov 2020 18:17:04 +0000 Subject: [PATCH 2095/3224] fixed borked test --- tests/phpunit/data/bedrock/CoralTypeIdMapTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/data/bedrock/CoralTypeIdMapTest.php b/tests/phpunit/data/bedrock/CoralTypeIdMapTest.php index 9a71a369c1..e0e77297e5 100644 --- a/tests/phpunit/data/bedrock/CoralTypeIdMapTest.php +++ b/tests/phpunit/data/bedrock/CoralTypeIdMapTest.php @@ -32,7 +32,7 @@ class CoralTypeIdMapTest extends TestCase{ foreach(CoralType::getAll() as $type){ $id = CoralTypeIdMap::getInstance()->toId($type); $type2 = CoralTypeIdMap::getInstance()->fromId($id); - self::assertTrue($type->equals($type2)); + self::assertTrue($type2 !== null && $type->equals($type2)); } } } From a9faed71711aa955fd16a001c9179be2be3ed322 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 16 Nov 2020 18:23:01 +0000 Subject: [PATCH 2096/3224] [ci skip] update BlockFactory TODOs --- src/block/BlockFactory.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index d84941021c..36dcd30ab5 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -509,9 +509,6 @@ class BlockFactory{ $this->register(new ChemicalHeat(new BID(Ids::CHEMICAL_HEAT), "Heat Block", $chemistryTableBreakInfo)); //region --- auto-generated TODOs for bedrock-1.11.0 --- - //TODO: minecraft:bamboo - //TODO: minecraft:bamboo_sapling - //TODO: minecraft:beacon //TODO: minecraft:bell //TODO: minecraft:blast_furnace //TODO: minecraft:bubble_column @@ -519,7 +516,6 @@ class BlockFactory{ //TODO: minecraft:cartography_table //TODO: minecraft:cauldron //TODO: minecraft:chain_command_block - //TODO: minecraft:chemical_heat //TODO: minecraft:chorus_flower //TODO: minecraft:chorus_plant //TODO: minecraft:command_block From de40ad80a63779a4387bc79b7fb986c47376a510 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 16 Nov 2020 18:33:28 +0000 Subject: [PATCH 2097/3224] Updated DevTools submodule to pmmp/DevTools@0c46527bee72324e5fee0c4ed2c7f5a324b6a4d0 --- tests/plugins/DevTools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/plugins/DevTools b/tests/plugins/DevTools index 66b8f7dfd7..0c46527bee 160000 --- a/tests/plugins/DevTools +++ b/tests/plugins/DevTools @@ -1 +1 @@ -Subproject commit 66b8f7dfd77f78478a180e40137e17606301233e +Subproject commit 0c46527bee72324e5fee0c4ed2c7f5a324b6a4d0 From 16b71a265f82a9b81c5fffecace74efe69d85f1a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 16 Nov 2020 19:09:59 +0000 Subject: [PATCH 2098/3224] Barrel: added missing function import --- src/block/Barrel.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/block/Barrel.php b/src/block/Barrel.php index 344f7a43a0..2c939c43a3 100644 --- a/src/block/Barrel.php +++ b/src/block/Barrel.php @@ -31,6 +31,7 @@ use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\world\BlockTransaction; +use function abs; class Barrel extends Opaque{ use AnyFacingTrait; From ca6a89283421f4480475c154396eb11af082c2ab Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 16 Nov 2020 19:10:27 +0000 Subject: [PATCH 2099/3224] [ci skip] NetworkSession: added some extra TODOs --- src/network/mcpe/NetworkSession.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 81c399b3ac..b7cfdd44b1 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -864,6 +864,8 @@ class NetworkSession{ $world = $this->player->getWorld(); $this->syncWorldTime($world->getTime()); $this->syncWorldDifficulty($world->getDifficulty()); + //TODO: weather needs to be synced here (when implemented) + //TODO: world spawn needs to be synced here } public function syncWorldTime(int $worldTime) : void{ From 869c9dabf14c30c8d26f8766b5a4613f9bce6b20 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 16 Nov 2020 19:11:10 +0000 Subject: [PATCH 2100/3224] SetCommandsEnabledPacket: added ::create() --- src/network/mcpe/protocol/SetCommandsEnabledPacket.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/network/mcpe/protocol/SetCommandsEnabledPacket.php b/src/network/mcpe/protocol/SetCommandsEnabledPacket.php index bf094e2bf6..ad5269907b 100644 --- a/src/network/mcpe/protocol/SetCommandsEnabledPacket.php +++ b/src/network/mcpe/protocol/SetCommandsEnabledPacket.php @@ -33,6 +33,12 @@ class SetCommandsEnabledPacket extends DataPacket implements ClientboundPacket{ /** @var bool */ public $enabled; + public static function create(bool $enabled) : self{ + $result = new self; + $result->enabled = $enabled; + return $result; + } + protected function decodePayload(PacketSerializer $in) : void{ $this->enabled = $in->getBool(); } From 1d272255539e97ad45a809644f6254de7540f295 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 16 Nov 2020 19:39:30 +0000 Subject: [PATCH 2101/3224] Relocate cache-related classes to mcpe\cache namespace --- src/network/mcpe/NetworkSession.php | 1 + src/network/mcpe/{ => cache}/ChunkCache.php | 3 ++- src/network/mcpe/{ => cache}/CraftingDataCache.php | 2 +- src/network/mcpe/{ => cache}/StaticPacketCache.php | 4 ++-- src/network/mcpe/handler/PreSpawnPacketHandler.php | 4 ++-- 5 files changed, 8 insertions(+), 6 deletions(-) rename src/network/mcpe/{ => cache}/ChunkCache.php (98%) rename src/network/mcpe/{ => cache}/CraftingDataCache.php (99%) rename src/network/mcpe/{ => cache}/StaticPacketCache.php (98%) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index b7cfdd44b1..6ece36ac1d 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -37,6 +37,7 @@ use pocketmine\event\server\DataPacketSendEvent; use pocketmine\form\Form; use pocketmine\math\Vector3; use pocketmine\network\BadPacketException; +use pocketmine\network\mcpe\cache\ChunkCache; use pocketmine\network\mcpe\compression\CompressBatchPromise; use pocketmine\network\mcpe\compression\Compressor; use pocketmine\network\mcpe\compression\DecompressionException; diff --git a/src/network/mcpe/ChunkCache.php b/src/network/mcpe/cache/ChunkCache.php similarity index 98% rename from src/network/mcpe/ChunkCache.php rename to src/network/mcpe/cache/ChunkCache.php index 5985b9e3c7..790a14a663 100644 --- a/src/network/mcpe/ChunkCache.php +++ b/src/network/mcpe/cache/ChunkCache.php @@ -21,9 +21,10 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe; +namespace pocketmine\network\mcpe\cache; use pocketmine\math\Vector3; +use pocketmine\network\mcpe\ChunkRequestTask; use pocketmine\network\mcpe\compression\CompressBatchPromise; use pocketmine\network\mcpe\compression\Compressor; use pocketmine\world\ChunkListener; diff --git a/src/network/mcpe/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php similarity index 99% rename from src/network/mcpe/CraftingDataCache.php rename to src/network/mcpe/cache/CraftingDataCache.php index 84b7e490c6..1f1c810a65 100644 --- a/src/network/mcpe/CraftingDataCache.php +++ b/src/network/mcpe/cache/CraftingDataCache.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe; +namespace pocketmine\network\mcpe\cache; use pocketmine\crafting\CraftingManager; use pocketmine\item\Item; diff --git a/src/network/mcpe/StaticPacketCache.php b/src/network/mcpe/cache/StaticPacketCache.php similarity index 98% rename from src/network/mcpe/StaticPacketCache.php rename to src/network/mcpe/cache/StaticPacketCache.php index 6ef7e8aedd..51bc879e08 100644 --- a/src/network/mcpe/StaticPacketCache.php +++ b/src/network/mcpe/cache/StaticPacketCache.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe; +namespace pocketmine\network\mcpe\cache; use pocketmine\network\mcpe\protocol\AvailableActorIdentifiersPacket; use pocketmine\network\mcpe\protocol\BiomeDefinitionListPacket; @@ -66,4 +66,4 @@ class StaticPacketCache{ public function getAvailableActorIdentifiers() : AvailableActorIdentifiersPacket{ return $this->availableActorIdentifiers; } -} \ No newline at end of file +} diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index f40dc13a1d..4d74fe8545 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -24,16 +24,16 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; use pocketmine\data\bedrock\LegacyItemIdToStringIdMap; +use pocketmine\network\mcpe\cache\CraftingDataCache; +use pocketmine\network\mcpe\cache\StaticPacketCache; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\convert\TypeConverter; -use pocketmine\network\mcpe\CraftingDataCache; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; use pocketmine\network\mcpe\protocol\StartGamePacket; use pocketmine\network\mcpe\protocol\types\BoolGameRule; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\protocol\types\SpawnSettings; -use pocketmine\network\mcpe\StaticPacketCache; use pocketmine\player\Player; use pocketmine\Server; From 37299ab8045ab51a574a932db50c5aebc9586791 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 16 Nov 2020 19:45:46 +0000 Subject: [PATCH 2102/3224] ChunkCache: explicitly check for requesting of unloaded chunk NetworkSession will never do this, but other things might. --- src/network/mcpe/cache/ChunkCache.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/network/mcpe/cache/ChunkCache.php b/src/network/mcpe/cache/ChunkCache.php index 790a14a663..afd1a41220 100644 --- a/src/network/mcpe/cache/ChunkCache.php +++ b/src/network/mcpe/cache/ChunkCache.php @@ -94,6 +94,10 @@ class ChunkCache implements ChunkListener{ */ public function request(int $chunkX, int $chunkZ) : CompressBatchPromise{ $this->world->registerChunkListener($this, $chunkX, $chunkZ); + $chunk = $this->world->getChunk($chunkX, $chunkZ); + if($chunk === null){ + throw new \InvalidArgumentException("Cannot request an unloaded chunk"); + } $chunkHash = World::chunkHash($chunkX, $chunkZ); if(isset($this->caches[$chunkHash])){ @@ -111,7 +115,7 @@ class ChunkCache implements ChunkListener{ new ChunkRequestTask( $chunkX, $chunkZ, - $this->world->getChunk($chunkX, $chunkZ), + $chunk, $this->caches[$chunkHash], $this->compressor, function() use ($chunkX, $chunkZ) : void{ From c3c647d51e8acfd32aa262bd440115f210763f51 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 16 Nov 2020 22:13:48 +0000 Subject: [PATCH 2103/3224] NetworkSession: remove useless disconnect() call this can't execute here because of the disconnectGuard, so this call always does nothing. --- src/network/mcpe/NetworkSession.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 6ece36ac1d..26bcb5e276 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -520,7 +520,6 @@ class NetworkSession{ public function transfer(string $ip, int $port, string $reason = "transfer") : void{ $this->tryDisconnect(function() use ($ip, $port, $reason) : void{ $this->sendDataPacket(TransferPacket::create($ip, $port), true); - $this->disconnect($reason, false); if($this->player !== null){ $this->player->disconnect($reason, null, false); } From 09b22c1e79a5855a4f258eb2cfaf501cde4e57f2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 16 Nov 2020 22:51:03 +0000 Subject: [PATCH 2104/3224] NetworkSession: drop @var doc comment referring to nonexisting variable --- src/network/mcpe/NetworkSession.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 26bcb5e276..7fa48f3924 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -231,10 +231,7 @@ class NetworkSession{ //TODO: this really has no business being in NetworkSession at all - what about allowing it to be provided by PlayerCreationEvent? $namedtag = $this->server->getOfflinePlayerData($this->info->getUsername()); - /** - * @var Player $player - * @see Player::__construct() - */ + /** @see Player::__construct() */ $this->player = new $class($this->server, $this, $this->info, $this->authenticated, $namedtag); $this->invManager = new InventoryManager($this->player, $this); From 62b9d9706023103a710f65dc4da5c9a44df0b2be Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 16 Nov 2020 23:05:56 +0000 Subject: [PATCH 2105/3224] Break circular dependency in Player->disconnect() usages none of these usages require onPlayerDestroyed() to be fired since they are all being called during disconnects anyway. --- src/network/mcpe/NetworkSession.php | 14 +++++++------- src/player/Player.php | 20 ++++++++++++++++++-- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 7fa48f3924..3a6f4e4ef1 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -258,7 +258,7 @@ class NetworkSession{ } public function isConnected() : bool{ - return $this->connected; + return $this->connected && !$this->disconnectGuard; } public function getIp() : string{ @@ -503,7 +503,7 @@ class NetworkSession{ public function disconnect(string $reason, bool $notify = true) : void{ $this->tryDisconnect(function() use ($reason, $notify) : void{ if($this->player !== null){ - $this->player->disconnect($reason, null, $notify); + $this->player->onPostDisconnect($reason, null); } $this->doServerDisconnect($reason, $notify); }, $reason); @@ -518,7 +518,7 @@ class NetworkSession{ $this->tryDisconnect(function() use ($ip, $port, $reason) : void{ $this->sendDataPacket(TransferPacket::create($ip, $port), true); if($this->player !== null){ - $this->player->disconnect($reason, null, false); + $this->player->onPostDisconnect($reason, null); } $this->doServerDisconnect($reason, false); }, $reason); @@ -527,9 +527,9 @@ class NetworkSession{ /** * Called by the Player when it is closed (for example due to getting kicked). */ - public function onPlayerDestroyed(string $reason, bool $notify = true) : void{ - $this->tryDisconnect(function() use ($reason, $notify) : void{ - $this->doServerDisconnect($reason, $notify); + public function onPlayerDestroyed(string $reason) : void{ + $this->tryDisconnect(function() use ($reason) : void{ + $this->doServerDisconnect($reason, true); }, $reason); } @@ -551,7 +551,7 @@ class NetworkSession{ public function onClientDisconnect(string $reason) : void{ $this->tryDisconnect(function() use ($reason) : void{ if($this->player !== null){ - $this->player->disconnect($reason, null, false); + $this->player->onPostDisconnect($reason, null); } }, $reason); } diff --git a/src/player/Player.php b/src/player/Player.php index e9635d2d20..3d41716831 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1986,15 +1986,31 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ * Note for plugin developers: Prefer kick() instead of this method. * That way other plugins can have a say in whether the player is removed or not. * + * Note for internals developers: Do not call this from network sessions. It will cause a feedback loop. + * * @param string $reason Shown to the player, usually this will appear on their disconnect screen. * @param TranslationContainer|string|null $quitMessage Message to broadcast to online players (null will use default) */ - public function disconnect(string $reason, $quitMessage = null, bool $notify = true) : void{ + public function disconnect(string $reason, $quitMessage = null) : void{ if(!$this->isConnected()){ return; } - $this->networkSession->onPlayerDestroyed($reason, $notify); + $this->networkSession->onPlayerDestroyed($reason); + $this->onPostDisconnect($reason, $quitMessage); + } + + /** + * @internal + * This method executes post-disconnect actions and cleanups. + * + * @param string $reason Shown to the player, usually this will appear on their disconnect screen. + * @param TranslationContainer|string|null $quitMessage Message to broadcast to online players (null will use default) + */ + public function onPostDisconnect(string $reason, $quitMessage) : void{ + if($this->isConnected()){ + throw new \InvalidStateException("Player is still connected"); + } //prevent the player receiving their own disconnect message PermissionManager::getInstance()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this); From 6a1f551aabefc6048572757158a95fe04723c4fb Mon Sep 17 00:00:00 2001 From: ipad54 <63200545+ipad54@users.noreply.github.com> Date: Tue, 17 Nov 2020 14:04:26 +0300 Subject: [PATCH 2106/3224] [ci skip] update TileFactory TODOs (#3912) --- src/block/tile/TileFactory.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/block/tile/TileFactory.php b/src/block/tile/TileFactory.php index df67b18016..84fc99e57c 100644 --- a/src/block/tile/TileFactory.php +++ b/src/block/tile/TileFactory.php @@ -68,7 +68,6 @@ final class TileFactory{ $this->register(Sign::class, ["Sign", "minecraft:sign"]); $this->register(Skull::class, ["Skull", "minecraft:skull"]); - //TODO: Beacon //TODO: Bell //TODO: BlastFurnace //TODO: Campfire @@ -82,7 +81,6 @@ final class TileFactory{ //TODO: EndGateway //TODO: EndPortal //TODO: JigsawBlock - //TODO: Jukebox //TODO: Lectern //TODO: MovingBlock //TODO: NetherReactor From 28335e3c45fd4948ee482077b2378399cb74bfc7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 17 Nov 2020 20:23:33 +0000 Subject: [PATCH 2107/3224] Player: fixed self-defeating condition in item consuming this was giving players infinite food and potions. --- src/player/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index 3d41716831..766929296a 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1495,7 +1495,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->setUsingItem(false); $this->resetItemCooldown($slot); - if($this->hasFiniteResources() and !$slot->equalsExact($oldItem) and $oldItem->equalsExact($this->inventory->getItemInHand())){ + if($this->hasFiniteResources() && $oldItem->equalsExact($this->inventory->getItemInHand())){ $slot->pop(); $this->inventory->setItemInHand($slot); $this->inventory->addItem($slot->getResidue()); From 870d237260854662790f0cba9707d243c1d0bc90 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 18 Nov 2020 00:50:01 +0000 Subject: [PATCH 2108/3224] BlockFactory::get() second parameter is now mandatory --- src/block/BlockFactory.php | 2 +- src/block/VanillaBlocks.php | 712 +++++++++++------------ src/command/defaults/ParticleCommand.php | 2 +- tests/phpunit/block/BlockTest.php | 10 +- 4 files changed, 363 insertions(+), 363 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 36dcd30ab5..e699c62abb 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -865,7 +865,7 @@ class BlockFactory{ /** * Returns a new Block instance with the specified ID, meta and position. */ - public function get(int $id, int $meta = 0) : Block{ + public function get(int $id, int $meta) : Block{ if($meta < 0 or $meta > 0xf){ throw new \InvalidArgumentException("Block meta value $meta is out of bounds"); } diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 1c87871b1f..7eebf4a9ed 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -648,52 +648,52 @@ final class VanillaBlocks{ protected static function setup() : void{ $factory = BlockFactory::getInstance(); - self::register("acacia_button", $factory->get(395)); - self::register("acacia_door", $factory->get(196)); + self::register("acacia_button", $factory->get(395, 0)); + self::register("acacia_door", $factory->get(196, 0)); self::register("acacia_fence", $factory->get(85, 4)); - self::register("acacia_fence_gate", $factory->get(187)); - self::register("acacia_leaves", $factory->get(161)); - self::register("acacia_log", $factory->get(162)); + self::register("acacia_fence_gate", $factory->get(187, 0)); + self::register("acacia_leaves", $factory->get(161, 0)); + self::register("acacia_log", $factory->get(162, 0)); self::register("acacia_planks", $factory->get(5, 4)); - self::register("acacia_pressure_plate", $factory->get(405)); + self::register("acacia_pressure_plate", $factory->get(405, 0)); self::register("acacia_sapling", $factory->get(6, 4)); - self::register("acacia_sign", $factory->get(445)); + self::register("acacia_sign", $factory->get(445, 0)); self::register("acacia_slab", $factory->get(158, 4)); - self::register("acacia_stairs", $factory->get(163)); - self::register("acacia_trapdoor", $factory->get(400)); + self::register("acacia_stairs", $factory->get(163, 0)); + self::register("acacia_trapdoor", $factory->get(400, 0)); self::register("acacia_wall_sign", $factory->get(446, 2)); self::register("acacia_wood", $factory->get(467, 4)); - self::register("activator_rail", $factory->get(126)); - self::register("air", $factory->get(0)); + self::register("activator_rail", $factory->get(126, 0)); + self::register("air", $factory->get(0, 0)); self::register("allium", $factory->get(38, 2)); self::register("andesite", $factory->get(1, 5)); self::register("andesite_slab", $factory->get(417, 3)); - self::register("andesite_stairs", $factory->get(426)); + self::register("andesite_stairs", $factory->get(426, 0)); self::register("andesite_wall", $factory->get(139, 4)); - self::register("anvil", $factory->get(145)); + self::register("anvil", $factory->get(145, 0)); self::register("azure_bluet", $factory->get(38, 3)); - self::register("bamboo", $factory->get(418)); - self::register("bamboo_sapling", $factory->get(419)); - self::register("banner", $factory->get(176)); - self::register("barrel", $factory->get(458)); - self::register("barrier", $factory->get(416)); - self::register("beacon", $factory->get(138)); - self::register("bed", $factory->get(26)); - self::register("bedrock", $factory->get(7)); - self::register("beetroots", $factory->get(244)); - self::register("birch_button", $factory->get(396)); - self::register("birch_door", $factory->get(194)); + self::register("bamboo", $factory->get(418, 0)); + self::register("bamboo_sapling", $factory->get(419, 0)); + self::register("banner", $factory->get(176, 0)); + self::register("barrel", $factory->get(458, 0)); + self::register("barrier", $factory->get(416, 0)); + self::register("beacon", $factory->get(138, 0)); + self::register("bed", $factory->get(26, 0)); + self::register("bedrock", $factory->get(7, 0)); + self::register("beetroots", $factory->get(244, 0)); + self::register("birch_button", $factory->get(396, 0)); + self::register("birch_door", $factory->get(194, 0)); self::register("birch_fence", $factory->get(85, 2)); - self::register("birch_fence_gate", $factory->get(184)); + self::register("birch_fence_gate", $factory->get(184, 0)); self::register("birch_leaves", $factory->get(18, 2)); self::register("birch_log", $factory->get(17, 2)); self::register("birch_planks", $factory->get(5, 2)); - self::register("birch_pressure_plate", $factory->get(406)); + self::register("birch_pressure_plate", $factory->get(406, 0)); self::register("birch_sapling", $factory->get(6, 2)); - self::register("birch_sign", $factory->get(441)); + self::register("birch_sign", $factory->get(441, 0)); self::register("birch_slab", $factory->get(158, 2)); - self::register("birch_stairs", $factory->get(135)); - self::register("birch_trapdoor", $factory->get(401)); + self::register("birch_stairs", $factory->get(135, 0)); + self::register("birch_trapdoor", $factory->get(401, 0)); self::register("birch_wall_sign", $factory->get(442, 2)); self::register("birch_wood", $factory->get(467, 2)); self::register("black_glazed_terracotta", $factory->get(235, 2)); @@ -701,53 +701,53 @@ final class VanillaBlocks{ self::register("black_stained_glass", $factory->get(241, 15)); self::register("black_stained_glass_pane", $factory->get(160, 15)); self::register("blue_glazed_terracotta", $factory->get(231, 2)); - self::register("blue_ice", $factory->get(266)); + self::register("blue_ice", $factory->get(266, 0)); self::register("blue_orchid", $factory->get(38, 1)); self::register("blue_stained_clay", $factory->get(159, 11)); self::register("blue_stained_glass", $factory->get(241, 11)); self::register("blue_stained_glass_pane", $factory->get(160, 11)); self::register("blue_torch", $factory->get(204, 5)); - self::register("bone_block", $factory->get(216)); - self::register("bookshelf", $factory->get(47)); - self::register("brewing_stand", $factory->get(117)); + self::register("bone_block", $factory->get(216, 0)); + self::register("bookshelf", $factory->get(47, 0)); + self::register("brewing_stand", $factory->get(117, 0)); self::register("brick_slab", $factory->get(44, 4)); - self::register("brick_stairs", $factory->get(108)); + self::register("brick_stairs", $factory->get(108, 0)); self::register("brick_wall", $factory->get(139, 6)); - self::register("bricks", $factory->get(45)); + self::register("bricks", $factory->get(45, 0)); self::register("brown_glazed_terracotta", $factory->get(232, 2)); - self::register("brown_mushroom", $factory->get(39)); - self::register("brown_mushroom_block", $factory->get(99)); + self::register("brown_mushroom", $factory->get(39, 0)); + self::register("brown_mushroom_block", $factory->get(99, 0)); self::register("brown_stained_clay", $factory->get(159, 12)); self::register("brown_stained_glass", $factory->get(241, 12)); self::register("brown_stained_glass_pane", $factory->get(160, 12)); - self::register("cactus", $factory->get(81)); - self::register("cake", $factory->get(92)); - self::register("carpet", $factory->get(171)); - self::register("carrots", $factory->get(141)); - self::register("carved_pumpkin", $factory->get(410)); - self::register("chemical_heat", $factory->get(192)); + self::register("cactus", $factory->get(81, 0)); + self::register("cake", $factory->get(92, 0)); + self::register("carpet", $factory->get(171, 0)); + self::register("carrots", $factory->get(141, 0)); + self::register("carved_pumpkin", $factory->get(410, 0)); + self::register("chemical_heat", $factory->get(192, 0)); self::register("chest", $factory->get(54, 2)); self::register("chiseled_quartz", $factory->get(155, 1)); self::register("chiseled_red_sandstone", $factory->get(179, 1)); self::register("chiseled_sandstone", $factory->get(24, 1)); self::register("chiseled_stone_bricks", $factory->get(98, 3)); - self::register("clay", $factory->get(82)); - self::register("coal", $factory->get(173)); - self::register("coal_ore", $factory->get(16)); + self::register("clay", $factory->get(82, 0)); + self::register("coal", $factory->get(173, 0)); + self::register("coal_ore", $factory->get(16, 0)); self::register("coarse_dirt", $factory->get(3, 1)); - self::register("cobblestone", $factory->get(4)); + self::register("cobblestone", $factory->get(4, 0)); self::register("cobblestone_slab", $factory->get(44, 3)); - self::register("cobblestone_stairs", $factory->get(67)); - self::register("cobblestone_wall", $factory->get(139)); - self::register("cobweb", $factory->get(30)); - self::register("cocoa_pod", $factory->get(127)); - self::register("compound_creator", $factory->get(238)); - self::register("concrete", $factory->get(236)); - self::register("concrete_powder", $factory->get(237)); - self::register("coral_block", $factory->get(387)); + self::register("cobblestone_stairs", $factory->get(67, 0)); + self::register("cobblestone_wall", $factory->get(139, 0)); + self::register("cobweb", $factory->get(30, 0)); + self::register("cocoa_pod", $factory->get(127, 0)); + self::register("compound_creator", $factory->get(238, 0)); + self::register("concrete", $factory->get(236, 0)); + self::register("concrete_powder", $factory->get(237, 0)); + self::register("coral_block", $factory->get(387, 0)); self::register("cornflower", $factory->get(38, 9)); self::register("cracked_stone_bricks", $factory->get(98, 2)); - self::register("crafting_table", $factory->get(58)); + self::register("crafting_table", $factory->get(58, 0)); self::register("cut_red_sandstone", $factory->get(179, 2)); self::register("cut_red_sandstone_slab", $factory->get(421, 4)); self::register("cut_sandstone", $factory->get(24, 2)); @@ -756,189 +756,189 @@ final class VanillaBlocks{ self::register("cyan_stained_clay", $factory->get(159, 9)); self::register("cyan_stained_glass", $factory->get(241, 9)); self::register("cyan_stained_glass_pane", $factory->get(160, 9)); - self::register("dandelion", $factory->get(37)); - self::register("dark_oak_button", $factory->get(397)); - self::register("dark_oak_door", $factory->get(197)); + self::register("dandelion", $factory->get(37, 0)); + self::register("dark_oak_button", $factory->get(397, 0)); + self::register("dark_oak_door", $factory->get(197, 0)); self::register("dark_oak_fence", $factory->get(85, 5)); - self::register("dark_oak_fence_gate", $factory->get(186)); + self::register("dark_oak_fence_gate", $factory->get(186, 0)); self::register("dark_oak_leaves", $factory->get(161, 1)); self::register("dark_oak_log", $factory->get(162, 1)); self::register("dark_oak_planks", $factory->get(5, 5)); - self::register("dark_oak_pressure_plate", $factory->get(407)); + self::register("dark_oak_pressure_plate", $factory->get(407, 0)); self::register("dark_oak_sapling", $factory->get(6, 5)); - self::register("dark_oak_sign", $factory->get(447)); + self::register("dark_oak_sign", $factory->get(447, 0)); self::register("dark_oak_slab", $factory->get(158, 5)); - self::register("dark_oak_stairs", $factory->get(164)); - self::register("dark_oak_trapdoor", $factory->get(402)); + self::register("dark_oak_stairs", $factory->get(164, 0)); + self::register("dark_oak_trapdoor", $factory->get(402, 0)); self::register("dark_oak_wall_sign", $factory->get(448, 2)); self::register("dark_oak_wood", $factory->get(467, 5)); self::register("dark_prismarine", $factory->get(168, 1)); self::register("dark_prismarine_slab", $factory->get(182, 3)); - self::register("dark_prismarine_stairs", $factory->get(258)); - self::register("daylight_sensor", $factory->get(151)); - self::register("dead_bush", $factory->get(32)); - self::register("detector_rail", $factory->get(28)); - self::register("diamond", $factory->get(57)); - self::register("diamond_ore", $factory->get(56)); + self::register("dark_prismarine_stairs", $factory->get(258, 0)); + self::register("daylight_sensor", $factory->get(151, 0)); + self::register("dead_bush", $factory->get(32, 0)); + self::register("detector_rail", $factory->get(28, 0)); + self::register("diamond", $factory->get(57, 0)); + self::register("diamond_ore", $factory->get(56, 0)); self::register("diorite", $factory->get(1, 3)); self::register("diorite_slab", $factory->get(417, 4)); - self::register("diorite_stairs", $factory->get(425)); + self::register("diorite_stairs", $factory->get(425, 0)); self::register("diorite_wall", $factory->get(139, 3)); - self::register("dirt", $factory->get(3)); + self::register("dirt", $factory->get(3, 0)); self::register("double_tallgrass", $factory->get(175, 2)); - self::register("dragon_egg", $factory->get(122)); - self::register("dried_kelp", $factory->get(394)); - self::register("element_actinium", $factory->get(355)); - self::register("element_aluminum", $factory->get(279)); - self::register("element_americium", $factory->get(361)); - self::register("element_antimony", $factory->get(317)); - self::register("element_argon", $factory->get(284)); - self::register("element_arsenic", $factory->get(299)); - self::register("element_astatine", $factory->get(351)); - self::register("element_barium", $factory->get(322)); - self::register("element_berkelium", $factory->get(363)); - self::register("element_beryllium", $factory->get(270)); - self::register("element_bismuth", $factory->get(349)); - self::register("element_bohrium", $factory->get(373)); - self::register("element_boron", $factory->get(271)); - self::register("element_bromine", $factory->get(301)); - self::register("element_cadmium", $factory->get(314)); - self::register("element_calcium", $factory->get(286)); - self::register("element_californium", $factory->get(364)); - self::register("element_carbon", $factory->get(272)); - self::register("element_cerium", $factory->get(324)); - self::register("element_cesium", $factory->get(321)); - self::register("element_chlorine", $factory->get(283)); - self::register("element_chromium", $factory->get(290)); - self::register("element_cobalt", $factory->get(293)); + self::register("dragon_egg", $factory->get(122, 0)); + self::register("dried_kelp", $factory->get(394, 0)); + self::register("element_actinium", $factory->get(355, 0)); + self::register("element_aluminum", $factory->get(279, 0)); + self::register("element_americium", $factory->get(361, 0)); + self::register("element_antimony", $factory->get(317, 0)); + self::register("element_argon", $factory->get(284, 0)); + self::register("element_arsenic", $factory->get(299, 0)); + self::register("element_astatine", $factory->get(351, 0)); + self::register("element_barium", $factory->get(322, 0)); + self::register("element_berkelium", $factory->get(363, 0)); + self::register("element_beryllium", $factory->get(270, 0)); + self::register("element_bismuth", $factory->get(349, 0)); + self::register("element_bohrium", $factory->get(373, 0)); + self::register("element_boron", $factory->get(271, 0)); + self::register("element_bromine", $factory->get(301, 0)); + self::register("element_cadmium", $factory->get(314, 0)); + self::register("element_calcium", $factory->get(286, 0)); + self::register("element_californium", $factory->get(364, 0)); + self::register("element_carbon", $factory->get(272, 0)); + self::register("element_cerium", $factory->get(324, 0)); + self::register("element_cesium", $factory->get(321, 0)); + self::register("element_chlorine", $factory->get(283, 0)); + self::register("element_chromium", $factory->get(290, 0)); + self::register("element_cobalt", $factory->get(293, 0)); self::register("element_constructor", $factory->get(238, 8)); - self::register("element_copernicium", $factory->get(378)); - self::register("element_copper", $factory->get(295)); - self::register("element_curium", $factory->get(362)); - self::register("element_darmstadtium", $factory->get(376)); - self::register("element_dubnium", $factory->get(371)); - self::register("element_dysprosium", $factory->get(332)); - self::register("element_einsteinium", $factory->get(365)); - self::register("element_erbium", $factory->get(334)); - self::register("element_europium", $factory->get(329)); - self::register("element_fermium", $factory->get(366)); - self::register("element_flerovium", $factory->get(380)); - self::register("element_fluorine", $factory->get(275)); - self::register("element_francium", $factory->get(353)); - self::register("element_gadolinium", $factory->get(330)); - self::register("element_gallium", $factory->get(297)); - self::register("element_germanium", $factory->get(298)); - self::register("element_gold", $factory->get(345)); - self::register("element_hafnium", $factory->get(338)); - self::register("element_hassium", $factory->get(374)); - self::register("element_helium", $factory->get(268)); - self::register("element_holmium", $factory->get(333)); - self::register("element_hydrogen", $factory->get(267)); - self::register("element_indium", $factory->get(315)); - self::register("element_iodine", $factory->get(319)); - self::register("element_iridium", $factory->get(343)); - self::register("element_iron", $factory->get(292)); - self::register("element_krypton", $factory->get(302)); - self::register("element_lanthanum", $factory->get(323)); - self::register("element_lawrencium", $factory->get(369)); - self::register("element_lead", $factory->get(348)); - self::register("element_lithium", $factory->get(269)); - self::register("element_livermorium", $factory->get(382)); - self::register("element_lutetium", $factory->get(337)); - self::register("element_magnesium", $factory->get(278)); - self::register("element_manganese", $factory->get(291)); - self::register("element_meitnerium", $factory->get(375)); - self::register("element_mendelevium", $factory->get(367)); - self::register("element_mercury", $factory->get(346)); - self::register("element_molybdenum", $factory->get(308)); - self::register("element_moscovium", $factory->get(381)); - self::register("element_neodymium", $factory->get(326)); - self::register("element_neon", $factory->get(276)); - self::register("element_neptunium", $factory->get(359)); - self::register("element_nickel", $factory->get(294)); - self::register("element_nihonium", $factory->get(379)); - self::register("element_niobium", $factory->get(307)); - self::register("element_nitrogen", $factory->get(273)); - self::register("element_nobelium", $factory->get(368)); - self::register("element_oganesson", $factory->get(384)); - self::register("element_osmium", $factory->get(342)); - self::register("element_oxygen", $factory->get(274)); - self::register("element_palladium", $factory->get(312)); - self::register("element_phosphorus", $factory->get(281)); - self::register("element_platinum", $factory->get(344)); - self::register("element_plutonium", $factory->get(360)); - self::register("element_polonium", $factory->get(350)); - self::register("element_potassium", $factory->get(285)); - self::register("element_praseodymium", $factory->get(325)); - self::register("element_promethium", $factory->get(327)); - self::register("element_protactinium", $factory->get(357)); - self::register("element_radium", $factory->get(354)); - self::register("element_radon", $factory->get(352)); - self::register("element_rhenium", $factory->get(341)); - self::register("element_rhodium", $factory->get(311)); - self::register("element_roentgenium", $factory->get(377)); - self::register("element_rubidium", $factory->get(303)); - self::register("element_ruthenium", $factory->get(310)); - self::register("element_rutherfordium", $factory->get(370)); - self::register("element_samarium", $factory->get(328)); - self::register("element_scandium", $factory->get(287)); - self::register("element_seaborgium", $factory->get(372)); - self::register("element_selenium", $factory->get(300)); - self::register("element_silicon", $factory->get(280)); - self::register("element_silver", $factory->get(313)); - self::register("element_sodium", $factory->get(277)); - self::register("element_strontium", $factory->get(304)); - self::register("element_sulfur", $factory->get(282)); - self::register("element_tantalum", $factory->get(339)); - self::register("element_technetium", $factory->get(309)); - self::register("element_tellurium", $factory->get(318)); - self::register("element_tennessine", $factory->get(383)); - self::register("element_terbium", $factory->get(331)); - self::register("element_thallium", $factory->get(347)); - self::register("element_thorium", $factory->get(356)); - self::register("element_thulium", $factory->get(335)); - self::register("element_tin", $factory->get(316)); - self::register("element_titanium", $factory->get(288)); - self::register("element_tungsten", $factory->get(340)); - self::register("element_uranium", $factory->get(358)); - self::register("element_vanadium", $factory->get(289)); - self::register("element_xenon", $factory->get(320)); - self::register("element_ytterbium", $factory->get(336)); - self::register("element_yttrium", $factory->get(305)); - self::register("element_zero", $factory->get(36)); - self::register("element_zinc", $factory->get(296)); - self::register("element_zirconium", $factory->get(306)); - self::register("emerald", $factory->get(133)); - self::register("emerald_ore", $factory->get(129)); - self::register("enchanting_table", $factory->get(116)); - self::register("end_portal_frame", $factory->get(120)); - self::register("end_rod", $factory->get(208)); - self::register("end_stone", $factory->get(121)); - self::register("end_stone_brick_slab", $factory->get(417)); - self::register("end_stone_brick_stairs", $factory->get(433)); + self::register("element_copernicium", $factory->get(378, 0)); + self::register("element_copper", $factory->get(295, 0)); + self::register("element_curium", $factory->get(362, 0)); + self::register("element_darmstadtium", $factory->get(376, 0)); + self::register("element_dubnium", $factory->get(371, 0)); + self::register("element_dysprosium", $factory->get(332, 0)); + self::register("element_einsteinium", $factory->get(365, 0)); + self::register("element_erbium", $factory->get(334, 0)); + self::register("element_europium", $factory->get(329, 0)); + self::register("element_fermium", $factory->get(366, 0)); + self::register("element_flerovium", $factory->get(380, 0)); + self::register("element_fluorine", $factory->get(275, 0)); + self::register("element_francium", $factory->get(353, 0)); + self::register("element_gadolinium", $factory->get(330, 0)); + self::register("element_gallium", $factory->get(297, 0)); + self::register("element_germanium", $factory->get(298, 0)); + self::register("element_gold", $factory->get(345, 0)); + self::register("element_hafnium", $factory->get(338, 0)); + self::register("element_hassium", $factory->get(374, 0)); + self::register("element_helium", $factory->get(268, 0)); + self::register("element_holmium", $factory->get(333, 0)); + self::register("element_hydrogen", $factory->get(267, 0)); + self::register("element_indium", $factory->get(315, 0)); + self::register("element_iodine", $factory->get(319, 0)); + self::register("element_iridium", $factory->get(343, 0)); + self::register("element_iron", $factory->get(292, 0)); + self::register("element_krypton", $factory->get(302, 0)); + self::register("element_lanthanum", $factory->get(323, 0)); + self::register("element_lawrencium", $factory->get(369, 0)); + self::register("element_lead", $factory->get(348, 0)); + self::register("element_lithium", $factory->get(269, 0)); + self::register("element_livermorium", $factory->get(382, 0)); + self::register("element_lutetium", $factory->get(337, 0)); + self::register("element_magnesium", $factory->get(278, 0)); + self::register("element_manganese", $factory->get(291, 0)); + self::register("element_meitnerium", $factory->get(375, 0)); + self::register("element_mendelevium", $factory->get(367, 0)); + self::register("element_mercury", $factory->get(346, 0)); + self::register("element_molybdenum", $factory->get(308, 0)); + self::register("element_moscovium", $factory->get(381, 0)); + self::register("element_neodymium", $factory->get(326, 0)); + self::register("element_neon", $factory->get(276, 0)); + self::register("element_neptunium", $factory->get(359, 0)); + self::register("element_nickel", $factory->get(294, 0)); + self::register("element_nihonium", $factory->get(379, 0)); + self::register("element_niobium", $factory->get(307, 0)); + self::register("element_nitrogen", $factory->get(273, 0)); + self::register("element_nobelium", $factory->get(368, 0)); + self::register("element_oganesson", $factory->get(384, 0)); + self::register("element_osmium", $factory->get(342, 0)); + self::register("element_oxygen", $factory->get(274, 0)); + self::register("element_palladium", $factory->get(312, 0)); + self::register("element_phosphorus", $factory->get(281, 0)); + self::register("element_platinum", $factory->get(344, 0)); + self::register("element_plutonium", $factory->get(360, 0)); + self::register("element_polonium", $factory->get(350, 0)); + self::register("element_potassium", $factory->get(285, 0)); + self::register("element_praseodymium", $factory->get(325, 0)); + self::register("element_promethium", $factory->get(327, 0)); + self::register("element_protactinium", $factory->get(357, 0)); + self::register("element_radium", $factory->get(354, 0)); + self::register("element_radon", $factory->get(352, 0)); + self::register("element_rhenium", $factory->get(341, 0)); + self::register("element_rhodium", $factory->get(311, 0)); + self::register("element_roentgenium", $factory->get(377, 0)); + self::register("element_rubidium", $factory->get(303, 0)); + self::register("element_ruthenium", $factory->get(310, 0)); + self::register("element_rutherfordium", $factory->get(370, 0)); + self::register("element_samarium", $factory->get(328, 0)); + self::register("element_scandium", $factory->get(287, 0)); + self::register("element_seaborgium", $factory->get(372, 0)); + self::register("element_selenium", $factory->get(300, 0)); + self::register("element_silicon", $factory->get(280, 0)); + self::register("element_silver", $factory->get(313, 0)); + self::register("element_sodium", $factory->get(277, 0)); + self::register("element_strontium", $factory->get(304, 0)); + self::register("element_sulfur", $factory->get(282, 0)); + self::register("element_tantalum", $factory->get(339, 0)); + self::register("element_technetium", $factory->get(309, 0)); + self::register("element_tellurium", $factory->get(318, 0)); + self::register("element_tennessine", $factory->get(383, 0)); + self::register("element_terbium", $factory->get(331, 0)); + self::register("element_thallium", $factory->get(347, 0)); + self::register("element_thorium", $factory->get(356, 0)); + self::register("element_thulium", $factory->get(335, 0)); + self::register("element_tin", $factory->get(316, 0)); + self::register("element_titanium", $factory->get(288, 0)); + self::register("element_tungsten", $factory->get(340, 0)); + self::register("element_uranium", $factory->get(358, 0)); + self::register("element_vanadium", $factory->get(289, 0)); + self::register("element_xenon", $factory->get(320, 0)); + self::register("element_ytterbium", $factory->get(336, 0)); + self::register("element_yttrium", $factory->get(305, 0)); + self::register("element_zero", $factory->get(36, 0)); + self::register("element_zinc", $factory->get(296, 0)); + self::register("element_zirconium", $factory->get(306, 0)); + self::register("emerald", $factory->get(133, 0)); + self::register("emerald_ore", $factory->get(129, 0)); + self::register("enchanting_table", $factory->get(116, 0)); + self::register("end_portal_frame", $factory->get(120, 0)); + self::register("end_rod", $factory->get(208, 0)); + self::register("end_stone", $factory->get(121, 0)); + self::register("end_stone_brick_slab", $factory->get(417, 0)); + self::register("end_stone_brick_stairs", $factory->get(433, 0)); self::register("end_stone_brick_wall", $factory->get(139, 10)); - self::register("end_stone_bricks", $factory->get(206)); + self::register("end_stone_bricks", $factory->get(206, 0)); self::register("ender_chest", $factory->get(130, 2)); self::register("fake_wooden_slab", $factory->get(44, 2)); - self::register("farmland", $factory->get(60)); + self::register("farmland", $factory->get(60, 0)); self::register("fern", $factory->get(31, 2)); - self::register("fire", $factory->get(51)); - self::register("flower_pot", $factory->get(140)); - self::register("frosted_ice", $factory->get(207)); + self::register("fire", $factory->get(51, 0)); + self::register("flower_pot", $factory->get(140, 0)); + self::register("frosted_ice", $factory->get(207, 0)); self::register("furnace", $factory->get(61, 2)); - self::register("glass", $factory->get(20)); - self::register("glass_pane", $factory->get(102)); - self::register("glowing_obsidian", $factory->get(246)); - self::register("glowstone", $factory->get(89)); - self::register("gold", $factory->get(41)); - self::register("gold_ore", $factory->get(14)); + self::register("glass", $factory->get(20, 0)); + self::register("glass_pane", $factory->get(102, 0)); + self::register("glowing_obsidian", $factory->get(246, 0)); + self::register("glowstone", $factory->get(89, 0)); + self::register("gold", $factory->get(41, 0)); + self::register("gold_ore", $factory->get(14, 0)); self::register("granite", $factory->get(1, 1)); self::register("granite_slab", $factory->get(417, 6)); - self::register("granite_stairs", $factory->get(424)); + self::register("granite_stairs", $factory->get(424, 0)); self::register("granite_wall", $factory->get(139, 2)); - self::register("grass", $factory->get(2)); - self::register("grass_path", $factory->get(198)); - self::register("gravel", $factory->get(13)); + self::register("grass", $factory->get(2, 0)); + self::register("grass_path", $factory->get(198, 0)); + self::register("gravel", $factory->get(13, 0)); self::register("gray_glazed_terracotta", $factory->get(227, 2)); self::register("gray_stained_clay", $factory->get(159, 7)); self::register("gray_stained_glass", $factory->get(241, 7)); @@ -954,11 +954,11 @@ final class VanillaBlocks{ self::register("hardened_blue_stained_glass_pane", $factory->get(191, 11)); self::register("hardened_brown_stained_glass", $factory->get(254, 12)); self::register("hardened_brown_stained_glass_pane", $factory->get(191, 12)); - self::register("hardened_clay", $factory->get(172)); + self::register("hardened_clay", $factory->get(172, 0)); self::register("hardened_cyan_stained_glass", $factory->get(254, 9)); self::register("hardened_cyan_stained_glass_pane", $factory->get(191, 9)); - self::register("hardened_glass", $factory->get(253)); - self::register("hardened_glass_pane", $factory->get(190)); + self::register("hardened_glass", $factory->get(253, 0)); + self::register("hardened_glass_pane", $factory->get(190, 0)); self::register("hardened_gray_stained_glass", $factory->get(254, 7)); self::register("hardened_gray_stained_glass_pane", $factory->get(191, 7)); self::register("hardened_green_stained_glass", $factory->get(254, 13)); @@ -979,53 +979,53 @@ final class VanillaBlocks{ self::register("hardened_purple_stained_glass_pane", $factory->get(191, 10)); self::register("hardened_red_stained_glass", $factory->get(254, 14)); self::register("hardened_red_stained_glass_pane", $factory->get(191, 14)); - self::register("hardened_white_stained_glass", $factory->get(254)); - self::register("hardened_white_stained_glass_pane", $factory->get(191)); + self::register("hardened_white_stained_glass", $factory->get(254, 0)); + self::register("hardened_white_stained_glass_pane", $factory->get(191, 0)); self::register("hardened_yellow_stained_glass", $factory->get(254, 4)); self::register("hardened_yellow_stained_glass_pane", $factory->get(191, 4)); - self::register("hay_bale", $factory->get(170)); - self::register("hopper", $factory->get(154)); - self::register("ice", $factory->get(79)); + self::register("hay_bale", $factory->get(170, 0)); + self::register("hopper", $factory->get(154, 0)); + self::register("ice", $factory->get(79, 0)); self::register("infested_chiseled_stone_brick", $factory->get(97, 5)); self::register("infested_cobblestone", $factory->get(97, 1)); self::register("infested_cracked_stone_brick", $factory->get(97, 4)); self::register("infested_mossy_stone_brick", $factory->get(97, 3)); - self::register("infested_stone", $factory->get(97)); + self::register("infested_stone", $factory->get(97, 0)); self::register("infested_stone_brick", $factory->get(97, 2)); - self::register("info_update", $factory->get(248)); - self::register("info_update2", $factory->get(249)); - self::register("invisible_bedrock", $factory->get(95)); - self::register("iron", $factory->get(42)); - self::register("iron_bars", $factory->get(101)); - self::register("iron_door", $factory->get(71)); - self::register("iron_ore", $factory->get(15)); - self::register("iron_trapdoor", $factory->get(167)); - self::register("item_frame", $factory->get(199)); - self::register("jukebox", $factory->get(84)); - self::register("jungle_button", $factory->get(398)); - self::register("jungle_door", $factory->get(195)); + self::register("info_update", $factory->get(248, 0)); + self::register("info_update2", $factory->get(249, 0)); + self::register("invisible_bedrock", $factory->get(95, 0)); + self::register("iron", $factory->get(42, 0)); + self::register("iron_bars", $factory->get(101, 0)); + self::register("iron_door", $factory->get(71, 0)); + self::register("iron_ore", $factory->get(15, 0)); + self::register("iron_trapdoor", $factory->get(167, 0)); + self::register("item_frame", $factory->get(199, 0)); + self::register("jukebox", $factory->get(84, 0)); + self::register("jungle_button", $factory->get(398, 0)); + self::register("jungle_door", $factory->get(195, 0)); self::register("jungle_fence", $factory->get(85, 3)); - self::register("jungle_fence_gate", $factory->get(185)); + self::register("jungle_fence_gate", $factory->get(185, 0)); self::register("jungle_leaves", $factory->get(18, 3)); self::register("jungle_log", $factory->get(17, 3)); self::register("jungle_planks", $factory->get(5, 3)); - self::register("jungle_pressure_plate", $factory->get(408)); + self::register("jungle_pressure_plate", $factory->get(408, 0)); self::register("jungle_sapling", $factory->get(6, 3)); - self::register("jungle_sign", $factory->get(443)); + self::register("jungle_sign", $factory->get(443, 0)); self::register("jungle_slab", $factory->get(158, 3)); - self::register("jungle_stairs", $factory->get(136)); - self::register("jungle_trapdoor", $factory->get(403)); + self::register("jungle_stairs", $factory->get(136, 0)); + self::register("jungle_trapdoor", $factory->get(403, 0)); self::register("jungle_wall_sign", $factory->get(444, 2)); self::register("jungle_wood", $factory->get(467, 3)); self::register("lab_table", $factory->get(238, 12)); self::register("ladder", $factory->get(65, 2)); - self::register("lantern", $factory->get(463)); - self::register("lapis_lazuli", $factory->get(22)); - self::register("lapis_lazuli_ore", $factory->get(21)); + self::register("lantern", $factory->get(463, 0)); + self::register("lapis_lazuli", $factory->get(22, 0)); + self::register("lapis_lazuli_ore", $factory->get(21, 0)); self::register("large_fern", $factory->get(175, 3)); - self::register("lava", $factory->get(10)); - self::register("legacy_stonecutter", $factory->get(245)); - self::register("lever", $factory->get(69)); + self::register("lava", $factory->get(10, 0)); + self::register("legacy_stonecutter", $factory->get(245, 0)); + self::register("lever", $factory->get(69, 0)); self::register("light_blue_glazed_terracotta", $factory->get(223, 2)); self::register("light_blue_stained_clay", $factory->get(159, 3)); self::register("light_blue_stained_glass", $factory->get(241, 3)); @@ -1036,201 +1036,201 @@ final class VanillaBlocks{ self::register("light_gray_stained_glass_pane", $factory->get(160, 8)); self::register("lilac", $factory->get(175, 1)); self::register("lily_of_the_valley", $factory->get(38, 10)); - self::register("lily_pad", $factory->get(111)); + self::register("lily_pad", $factory->get(111, 0)); self::register("lime_glazed_terracotta", $factory->get(225, 2)); self::register("lime_stained_clay", $factory->get(159, 5)); self::register("lime_stained_glass", $factory->get(241, 5)); self::register("lime_stained_glass_pane", $factory->get(160, 5)); - self::register("lit_pumpkin", $factory->get(91)); + self::register("lit_pumpkin", $factory->get(91, 0)); self::register("magenta_glazed_terracotta", $factory->get(222, 2)); self::register("magenta_stained_clay", $factory->get(159, 2)); self::register("magenta_stained_glass", $factory->get(241, 2)); self::register("magenta_stained_glass_pane", $factory->get(160, 2)); - self::register("magma", $factory->get(213)); + self::register("magma", $factory->get(213, 0)); self::register("material_reducer", $factory->get(238, 4)); - self::register("melon", $factory->get(103)); - self::register("melon_stem", $factory->get(105)); + self::register("melon", $factory->get(103, 0)); + self::register("melon_stem", $factory->get(105, 0)); self::register("mob_head", $factory->get(144, 2)); - self::register("monster_spawner", $factory->get(52)); - self::register("mossy_cobblestone", $factory->get(48)); + self::register("monster_spawner", $factory->get(52, 0)); + self::register("mossy_cobblestone", $factory->get(48, 0)); self::register("mossy_cobblestone_slab", $factory->get(182, 5)); - self::register("mossy_cobblestone_stairs", $factory->get(434)); + self::register("mossy_cobblestone_stairs", $factory->get(434, 0)); self::register("mossy_cobblestone_wall", $factory->get(139, 1)); - self::register("mossy_stone_brick_slab", $factory->get(421)); - self::register("mossy_stone_brick_stairs", $factory->get(430)); + self::register("mossy_stone_brick_slab", $factory->get(421, 0)); + self::register("mossy_stone_brick_stairs", $factory->get(430, 0)); self::register("mossy_stone_brick_wall", $factory->get(139, 8)); self::register("mossy_stone_bricks", $factory->get(98, 1)); - self::register("mycelium", $factory->get(110)); - self::register("nether_brick_fence", $factory->get(113)); + self::register("mycelium", $factory->get(110, 0)); + self::register("nether_brick_fence", $factory->get(113, 0)); self::register("nether_brick_slab", $factory->get(44, 7)); - self::register("nether_brick_stairs", $factory->get(114)); + self::register("nether_brick_stairs", $factory->get(114, 0)); self::register("nether_brick_wall", $factory->get(139, 9)); - self::register("nether_bricks", $factory->get(112)); + self::register("nether_bricks", $factory->get(112, 0)); self::register("nether_portal", $factory->get(90, 1)); - self::register("nether_quartz_ore", $factory->get(153)); - self::register("nether_reactor_core", $factory->get(247)); - self::register("nether_wart", $factory->get(115)); - self::register("nether_wart_block", $factory->get(214)); - self::register("netherrack", $factory->get(87)); - self::register("note_block", $factory->get(25)); - self::register("oak_button", $factory->get(143)); - self::register("oak_door", $factory->get(64)); - self::register("oak_fence", $factory->get(85)); - self::register("oak_fence_gate", $factory->get(107)); - self::register("oak_leaves", $factory->get(18)); - self::register("oak_log", $factory->get(17)); - self::register("oak_planks", $factory->get(5)); - self::register("oak_pressure_plate", $factory->get(72)); - self::register("oak_sapling", $factory->get(6)); - self::register("oak_sign", $factory->get(63)); - self::register("oak_slab", $factory->get(158)); - self::register("oak_stairs", $factory->get(53)); - self::register("oak_trapdoor", $factory->get(96)); + self::register("nether_quartz_ore", $factory->get(153, 0)); + self::register("nether_reactor_core", $factory->get(247, 0)); + self::register("nether_wart", $factory->get(115, 0)); + self::register("nether_wart_block", $factory->get(214, 0)); + self::register("netherrack", $factory->get(87, 0)); + self::register("note_block", $factory->get(25, 0)); + self::register("oak_button", $factory->get(143, 0)); + self::register("oak_door", $factory->get(64, 0)); + self::register("oak_fence", $factory->get(85, 0)); + self::register("oak_fence_gate", $factory->get(107, 0)); + self::register("oak_leaves", $factory->get(18, 0)); + self::register("oak_log", $factory->get(17, 0)); + self::register("oak_planks", $factory->get(5, 0)); + self::register("oak_pressure_plate", $factory->get(72, 0)); + self::register("oak_sapling", $factory->get(6, 0)); + self::register("oak_sign", $factory->get(63, 0)); + self::register("oak_slab", $factory->get(158, 0)); + self::register("oak_stairs", $factory->get(53, 0)); + self::register("oak_trapdoor", $factory->get(96, 0)); self::register("oak_wall_sign", $factory->get(68, 2)); - self::register("oak_wood", $factory->get(467)); - self::register("obsidian", $factory->get(49)); + self::register("oak_wood", $factory->get(467, 0)); + self::register("obsidian", $factory->get(49, 0)); self::register("orange_glazed_terracotta", $factory->get(221, 2)); self::register("orange_stained_clay", $factory->get(159, 1)); self::register("orange_stained_glass", $factory->get(241, 1)); self::register("orange_stained_glass_pane", $factory->get(160, 1)); self::register("orange_tulip", $factory->get(38, 5)); self::register("oxeye_daisy", $factory->get(38, 8)); - self::register("packed_ice", $factory->get(174)); + self::register("packed_ice", $factory->get(174, 0)); self::register("peony", $factory->get(175, 5)); self::register("pink_glazed_terracotta", $factory->get(226, 2)); self::register("pink_stained_clay", $factory->get(159, 6)); self::register("pink_stained_glass", $factory->get(241, 6)); self::register("pink_stained_glass_pane", $factory->get(160, 6)); self::register("pink_tulip", $factory->get(38, 7)); - self::register("podzol", $factory->get(243)); + self::register("podzol", $factory->get(243, 0)); self::register("polished_andesite", $factory->get(1, 6)); self::register("polished_andesite_slab", $factory->get(417, 2)); - self::register("polished_andesite_stairs", $factory->get(429)); + self::register("polished_andesite_stairs", $factory->get(429, 0)); self::register("polished_diorite", $factory->get(1, 4)); self::register("polished_diorite_slab", $factory->get(417, 5)); - self::register("polished_diorite_stairs", $factory->get(428)); + self::register("polished_diorite_stairs", $factory->get(428, 0)); self::register("polished_granite", $factory->get(1, 2)); self::register("polished_granite_slab", $factory->get(417, 7)); - self::register("polished_granite_stairs", $factory->get(427)); - self::register("poppy", $factory->get(38)); - self::register("potatoes", $factory->get(142)); - self::register("powered_rail", $factory->get(27)); - self::register("prismarine", $factory->get(168)); + self::register("polished_granite_stairs", $factory->get(427, 0)); + self::register("poppy", $factory->get(38, 0)); + self::register("potatoes", $factory->get(142, 0)); + self::register("powered_rail", $factory->get(27, 0)); + self::register("prismarine", $factory->get(168, 0)); self::register("prismarine_bricks", $factory->get(168, 2)); self::register("prismarine_bricks_slab", $factory->get(182, 4)); - self::register("prismarine_bricks_stairs", $factory->get(259)); + self::register("prismarine_bricks_stairs", $factory->get(259, 0)); self::register("prismarine_slab", $factory->get(182, 2)); - self::register("prismarine_stairs", $factory->get(257)); + self::register("prismarine_stairs", $factory->get(257, 0)); self::register("prismarine_wall", $factory->get(139, 11)); - self::register("pumpkin", $factory->get(86)); - self::register("pumpkin_stem", $factory->get(104)); + self::register("pumpkin", $factory->get(86, 0)); + self::register("pumpkin_stem", $factory->get(104, 0)); self::register("purple_glazed_terracotta", $factory->get(219, 2)); self::register("purple_stained_clay", $factory->get(159, 10)); self::register("purple_stained_glass", $factory->get(241, 10)); self::register("purple_stained_glass_pane", $factory->get(160, 10)); self::register("purple_torch", $factory->get(204, 13)); - self::register("purpur", $factory->get(201)); + self::register("purpur", $factory->get(201, 0)); self::register("purpur_pillar", $factory->get(201, 2)); self::register("purpur_slab", $factory->get(182, 1)); - self::register("purpur_stairs", $factory->get(203)); - self::register("quartz", $factory->get(155)); + self::register("purpur_stairs", $factory->get(203, 0)); + self::register("quartz", $factory->get(155, 0)); self::register("quartz_pillar", $factory->get(155, 2)); self::register("quartz_slab", $factory->get(44, 6)); - self::register("quartz_stairs", $factory->get(156)); - self::register("rail", $factory->get(66)); + self::register("quartz_stairs", $factory->get(156, 0)); + self::register("rail", $factory->get(66, 0)); self::register("red_glazed_terracotta", $factory->get(234, 2)); - self::register("red_mushroom", $factory->get(40)); - self::register("red_mushroom_block", $factory->get(100)); + self::register("red_mushroom", $factory->get(40, 0)); + self::register("red_mushroom_block", $factory->get(100, 0)); self::register("red_nether_brick_slab", $factory->get(182, 7)); - self::register("red_nether_brick_stairs", $factory->get(439)); + self::register("red_nether_brick_stairs", $factory->get(439, 0)); self::register("red_nether_brick_wall", $factory->get(139, 13)); - self::register("red_nether_bricks", $factory->get(215)); + self::register("red_nether_bricks", $factory->get(215, 0)); self::register("red_sand", $factory->get(12, 1)); - self::register("red_sandstone", $factory->get(179)); - self::register("red_sandstone_slab", $factory->get(182)); - self::register("red_sandstone_stairs", $factory->get(180)); + self::register("red_sandstone", $factory->get(179, 0)); + self::register("red_sandstone_slab", $factory->get(182, 0)); + self::register("red_sandstone_stairs", $factory->get(180, 0)); self::register("red_sandstone_wall", $factory->get(139, 12)); self::register("red_stained_clay", $factory->get(159, 14)); self::register("red_stained_glass", $factory->get(241, 14)); self::register("red_stained_glass_pane", $factory->get(160, 14)); self::register("red_torch", $factory->get(202, 5)); self::register("red_tulip", $factory->get(38, 4)); - self::register("redstone", $factory->get(152)); - self::register("redstone_comparator", $factory->get(149)); - self::register("redstone_lamp", $factory->get(123)); - self::register("redstone_ore", $factory->get(73)); - self::register("redstone_repeater", $factory->get(93)); + self::register("redstone", $factory->get(152, 0)); + self::register("redstone_comparator", $factory->get(149, 0)); + self::register("redstone_lamp", $factory->get(123, 0)); + self::register("redstone_ore", $factory->get(73, 0)); + self::register("redstone_repeater", $factory->get(93, 0)); self::register("redstone_torch", $factory->get(76, 5)); - self::register("redstone_wire", $factory->get(55)); - self::register("reserved6", $factory->get(255)); + self::register("redstone_wire", $factory->get(55, 0)); + self::register("reserved6", $factory->get(255, 0)); self::register("rose_bush", $factory->get(175, 4)); - self::register("sand", $factory->get(12)); - self::register("sandstone", $factory->get(24)); + self::register("sand", $factory->get(12, 0)); + self::register("sandstone", $factory->get(24, 0)); self::register("sandstone_slab", $factory->get(44, 1)); - self::register("sandstone_stairs", $factory->get(128)); + self::register("sandstone_stairs", $factory->get(128, 0)); self::register("sandstone_wall", $factory->get(139, 5)); - self::register("sea_lantern", $factory->get(169)); - self::register("sea_pickle", $factory->get(411)); + self::register("sea_lantern", $factory->get(169, 0)); + self::register("sea_pickle", $factory->get(411, 0)); self::register("smooth_quartz", $factory->get(155, 3)); self::register("smooth_quartz_slab", $factory->get(421, 1)); - self::register("smooth_quartz_stairs", $factory->get(440)); + self::register("smooth_quartz_stairs", $factory->get(440, 0)); self::register("smooth_red_sandstone", $factory->get(179, 3)); self::register("smooth_red_sandstone_slab", $factory->get(417, 1)); - self::register("smooth_red_sandstone_stairs", $factory->get(431)); + self::register("smooth_red_sandstone_stairs", $factory->get(431, 0)); self::register("smooth_sandstone", $factory->get(24, 3)); self::register("smooth_sandstone_slab", $factory->get(182, 6)); - self::register("smooth_sandstone_stairs", $factory->get(432)); - self::register("smooth_stone", $factory->get(438)); - self::register("smooth_stone_slab", $factory->get(44)); - self::register("snow", $factory->get(80)); - self::register("snow_layer", $factory->get(78)); - self::register("soul_sand", $factory->get(88)); - self::register("sponge", $factory->get(19)); - self::register("spruce_button", $factory->get(399)); - self::register("spruce_door", $factory->get(193)); + self::register("smooth_sandstone_stairs", $factory->get(432, 0)); + self::register("smooth_stone", $factory->get(438, 0)); + self::register("smooth_stone_slab", $factory->get(44, 0)); + self::register("snow", $factory->get(80, 0)); + self::register("snow_layer", $factory->get(78, 0)); + self::register("soul_sand", $factory->get(88, 0)); + self::register("sponge", $factory->get(19, 0)); + self::register("spruce_button", $factory->get(399, 0)); + self::register("spruce_door", $factory->get(193, 0)); self::register("spruce_fence", $factory->get(85, 1)); - self::register("spruce_fence_gate", $factory->get(183)); + self::register("spruce_fence_gate", $factory->get(183, 0)); self::register("spruce_leaves", $factory->get(18, 1)); self::register("spruce_log", $factory->get(17, 1)); self::register("spruce_planks", $factory->get(5, 1)); - self::register("spruce_pressure_plate", $factory->get(409)); + self::register("spruce_pressure_plate", $factory->get(409, 0)); self::register("spruce_sapling", $factory->get(6, 1)); - self::register("spruce_sign", $factory->get(436)); + self::register("spruce_sign", $factory->get(436, 0)); self::register("spruce_slab", $factory->get(158, 1)); - self::register("spruce_stairs", $factory->get(134)); - self::register("spruce_trapdoor", $factory->get(404)); + self::register("spruce_stairs", $factory->get(134, 0)); + self::register("spruce_trapdoor", $factory->get(404, 0)); self::register("spruce_wall_sign", $factory->get(437, 2)); self::register("spruce_wood", $factory->get(467, 1)); - self::register("stone", $factory->get(1)); + self::register("stone", $factory->get(1, 0)); self::register("stone_brick_slab", $factory->get(44, 5)); - self::register("stone_brick_stairs", $factory->get(109)); + self::register("stone_brick_stairs", $factory->get(109, 0)); self::register("stone_brick_wall", $factory->get(139, 7)); - self::register("stone_bricks", $factory->get(98)); - self::register("stone_button", $factory->get(77)); - self::register("stone_pressure_plate", $factory->get(70)); + self::register("stone_bricks", $factory->get(98, 0)); + self::register("stone_button", $factory->get(77, 0)); + self::register("stone_pressure_plate", $factory->get(70, 0)); self::register("stone_slab", $factory->get(421, 2)); - self::register("stone_stairs", $factory->get(435)); - self::register("sugarcane", $factory->get(83)); - self::register("sunflower", $factory->get(175)); + self::register("stone_stairs", $factory->get(435, 0)); + self::register("sugarcane", $factory->get(83, 0)); + self::register("sunflower", $factory->get(175, 0)); self::register("tall_grass", $factory->get(31, 1)); - self::register("tnt", $factory->get(46)); + self::register("tnt", $factory->get(46, 0)); self::register("torch", $factory->get(50, 5)); self::register("trapped_chest", $factory->get(146, 2)); - self::register("tripwire", $factory->get(132)); - self::register("tripwire_hook", $factory->get(131)); + self::register("tripwire", $factory->get(132, 0)); + self::register("tripwire_hook", $factory->get(131, 0)); self::register("underwater_torch", $factory->get(239, 5)); - self::register("vines", $factory->get(106)); + self::register("vines", $factory->get(106, 0)); self::register("wall_banner", $factory->get(177, 2)); - self::register("water", $factory->get(8)); - self::register("weighted_pressure_plate_heavy", $factory->get(148)); - self::register("weighted_pressure_plate_light", $factory->get(147)); - self::register("wheat", $factory->get(59)); + self::register("water", $factory->get(8, 0)); + self::register("weighted_pressure_plate_heavy", $factory->get(148, 0)); + self::register("weighted_pressure_plate_light", $factory->get(147, 0)); + self::register("wheat", $factory->get(59, 0)); self::register("white_glazed_terracotta", $factory->get(220, 2)); - self::register("white_stained_clay", $factory->get(159)); - self::register("white_stained_glass", $factory->get(241)); - self::register("white_stained_glass_pane", $factory->get(160)); + self::register("white_stained_clay", $factory->get(159, 0)); + self::register("white_stained_glass", $factory->get(241, 0)); + self::register("white_stained_glass_pane", $factory->get(160, 0)); self::register("white_tulip", $factory->get(38, 6)); - self::register("wool", $factory->get(35)); + self::register("wool", $factory->get(35, 0)); self::register("yellow_glazed_terracotta", $factory->get(224, 2)); self::register("yellow_stained_clay", $factory->get(159, 4)); self::register("yellow_stained_glass", $factory->get(241, 4)); diff --git a/src/command/defaults/ParticleCommand.php b/src/command/defaults/ParticleCommand.php index a9c5806456..0296b148b9 100644 --- a/src/command/defaults/ParticleCommand.php +++ b/src/command/defaults/ParticleCommand.php @@ -186,7 +186,7 @@ class ParticleCommand extends VanillaCommand{ break; case "terrain": if($data !== null and $data !== 0){ - return new TerrainParticle(BlockFactory::getInstance()->get($data)); + return new TerrainParticle(BlockFactory::getInstance()->get($data, 0)); } break; case "heart": diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index a628a6dc5b..5d7d28dba9 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -51,7 +51,7 @@ class BlockTest extends TestCase{ public function testDeliberateOverrideBlock() : void{ $block = new MyCustomBlock(new BlockIdentifier(BlockLegacyIds::COBBLESTONE), "Cobblestone", BlockBreakInfo::instant()); $this->blockFactory->register($block, true); - self::assertInstanceOf(MyCustomBlock::class, $this->blockFactory->get($block->getId())); + self::assertInstanceOf(MyCustomBlock::class, $this->blockFactory->get($block->getId(), 0)); } /** @@ -62,7 +62,7 @@ class BlockTest extends TestCase{ if(!$this->blockFactory->isRegistered($i)){ $b = new StrangeNewBlock(new BlockIdentifier($i), "Strange New Block", BlockBreakInfo::instant()); $this->blockFactory->register($b); - self::assertInstanceOf(StrangeNewBlock::class, $this->blockFactory->get($b->getId())); + self::assertInstanceOf(StrangeNewBlock::class, $this->blockFactory->get($b->getId(), 0)); return; } } @@ -93,8 +93,8 @@ class BlockTest extends TestCase{ */ public function testBlockFactoryClone() : void{ for($i = 0; $i < 256; ++$i){ - $b1 = $this->blockFactory->get($i); - $b2 = $this->blockFactory->get($i); + $b1 = $this->blockFactory->get($i, 0); + $b2 = $this->blockFactory->get($i, 0); self::assertNotSame($b1, $b2); } } @@ -126,7 +126,7 @@ class BlockTest extends TestCase{ public function testBlockIds() : void{ for($i = 0; $i < 256; ++$i){ - $b = $this->blockFactory->get($i); + $b = $this->blockFactory->get($i, 0); self::assertContains($i, $b->getIdInfo()->getAllBlockIds()); } } From f2bdbb0c357d66b93fb3647050db74861bbb4bc8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 20 Nov 2020 21:31:06 +0000 Subject: [PATCH 2109/3224] TypeConverter: fix using singleton to get its own context I guess this must have been refactored from some other class?... --- src/network/mcpe/convert/TypeConverter.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index 3fd3a90037..2540ed1a7b 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -184,8 +184,8 @@ class TypeConverter{ //filter out useless noise in 1.13 return null; } - $old = TypeConverter::getInstance()->netItemStackToCore($action->oldItem); - $new = TypeConverter::getInstance()->netItemStackToCore($action->newItem); + $old = $this->netItemStackToCore($action->oldItem); + $new = $this->netItemStackToCore($action->newItem); switch($action->sourceType){ case NetworkInventoryAction::SOURCE_CONTAINER: if($action->windowId === ContainerIds::UI and $action->inventorySlot > 0){ From d2b593edf86c79c493998a36baeaf92527630340 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Nov 2020 17:47:54 +0000 Subject: [PATCH 2110/3224] Updated composer dependencies --- composer.lock | 12 +++--- .../mcpe/convert/SkinAdapterSingleton.php | 43 ------------------- 2 files changed, 6 insertions(+), 49 deletions(-) delete mode 100644 src/network/mcpe/convert/SkinAdapterSingleton.php diff --git a/composer.lock b/composer.lock index d816ae0741..35289d574b 100644 --- a/composer.lock +++ b/composer.lock @@ -1068,16 +1068,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.10.1", + "version": "1.10.2", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5" + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", - "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", "shasum": "" }, "require": { @@ -1114,7 +1114,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.x" + "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" }, "funding": [ { @@ -1122,7 +1122,7 @@ "type": "tidelift" } ], - "time": "2020-06-29T13:22:24+00:00" + "time": "2020-11-13T09:40:50+00:00" }, { "name": "nikic/php-parser", diff --git a/src/network/mcpe/convert/SkinAdapterSingleton.php b/src/network/mcpe/convert/SkinAdapterSingleton.php deleted file mode 100644 index c49d3a780c..0000000000 --- a/src/network/mcpe/convert/SkinAdapterSingleton.php +++ /dev/null @@ -1,43 +0,0 @@ - Date: Sat, 21 Nov 2020 17:55:32 +0000 Subject: [PATCH 2111/3224] Updated composer dependencies --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index d816ae0741..35289d574b 100644 --- a/composer.lock +++ b/composer.lock @@ -1068,16 +1068,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.10.1", + "version": "1.10.2", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5" + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", - "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", "shasum": "" }, "require": { @@ -1114,7 +1114,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.x" + "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" }, "funding": [ { @@ -1122,7 +1122,7 @@ "type": "tidelift" } ], - "time": "2020-06-29T13:22:24+00:00" + "time": "2020-11-13T09:40:50+00:00" }, { "name": "nikic/php-parser", From bc208e11f44fbdde1619a40e1e827164005e4a7f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Nov 2020 18:07:14 +0000 Subject: [PATCH 2112/3224] phpstan 0.12.57 --- composer.json | 2 +- composer.lock | 14 +++++++------- .../mcpe/encryption/PrepareEncryptionTask.php | 4 ++++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index 8c291d43a3..02037def1a 100644 --- a/composer.json +++ b/composer.json @@ -51,7 +51,7 @@ "composer-runtime-api": "^2.0" }, "require-dev": { - "phpstan/phpstan": "0.12.54", + "phpstan/phpstan": "0.12.57", "phpstan/phpstan-phpunit": "^0.12.6", "phpstan/phpstan-strict-rules": "^0.12.2", "phpunit/phpunit": "^9.2" diff --git a/composer.lock b/composer.lock index 35289d574b..6e2090ba6f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2ebc35f61a45aaa7bb3e6185b6bfbf90", + "content-hash": "b96dbf17a1d0fed7b4545e72afbae5b4", "packages": [ { "name": "adhocore/json-comment", @@ -1518,16 +1518,16 @@ }, { "name": "phpstan/phpstan", - "version": "0.12.54", + "version": "0.12.57", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "45c7b999a4b7dd9ac5558bdaaf23dcebbef88223" + "reference": "f9909d1d0c44b4cbaf72babcf80e8f14d6fdd55b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/45c7b999a4b7dd9ac5558bdaaf23dcebbef88223", - "reference": "45c7b999a4b7dd9ac5558bdaaf23dcebbef88223", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/f9909d1d0c44b4cbaf72babcf80e8f14d6fdd55b", + "reference": "f9909d1d0c44b4cbaf72babcf80e8f14d6fdd55b", "shasum": "" }, "require": { @@ -1558,7 +1558,7 @@ "description": "PHPStan - PHP Static Analysis Tool", "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/0.12.54" + "source": "https://github.com/phpstan/phpstan/tree/0.12.57" }, "funding": [ { @@ -1574,7 +1574,7 @@ "type": "tidelift" } ], - "time": "2020-11-05T13:36:26+00:00" + "time": "2020-11-21T12:53:28+00:00" }, { "name": "phpstan/phpstan-phpunit", diff --git a/src/network/mcpe/encryption/PrepareEncryptionTask.php b/src/network/mcpe/encryption/PrepareEncryptionTask.php index aae8968537..883947e043 100644 --- a/src/network/mcpe/encryption/PrepareEncryptionTask.php +++ b/src/network/mcpe/encryption/PrepareEncryptionTask.php @@ -27,6 +27,7 @@ use Mdanter\Ecc\Crypto\Key\PrivateKeyInterface; use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; use Mdanter\Ecc\EccFactory; use pocketmine\scheduler\AsyncTask; +use pocketmine\utils\AssumptionFailedError; use function random_bytes; class PrepareEncryptionTask extends AsyncTask{ @@ -74,6 +75,9 @@ class PrepareEncryptionTask extends AsyncTask{ * @phpstan-var \Closure(string $encryptionKey, string $handshakeJwt) : void $callback */ $callback = $this->fetchLocal(self::TLS_KEY_ON_COMPLETION); + if($this->aesKey === null || $this->handshakeJwt === null){ + throw new AssumptionFailedError("Something strange happened here ..."); + } $callback($this->aesKey, $this->handshakeJwt); } } From 4520e425c1376369724cab5045d4e865da57908f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Nov 2020 21:17:23 +0000 Subject: [PATCH 2113/3224] Sync BedrockData submodule with merge I forgot to commit this in the merge ... --- resources/vanilla | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/vanilla b/resources/vanilla index afc885ccca..14f4a765eb 160000 --- a/resources/vanilla +++ b/resources/vanilla @@ -1 +1 @@ -Subproject commit afc885cccae38048d309911f2c5ddcdcb6af8152 +Subproject commit 14f4a765eba40b2c65c6dcd061cbfea6e1d3d4cc From fd99445c5bbd2a5a6fdd0109d8a196ea6160e0a3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 26 Nov 2020 19:36:33 +0000 Subject: [PATCH 2114/3224] World->getSafeSpawn() now throws if the target is in ungenerated terrain, instead of silently returning the default this WILL cause crashes in some cases on slower machines (#2724), but it's better than randomly spawning at the top of the map. --- src/world/World.php | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 4a2e2f78fa..47cbbc0bfd 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2371,6 +2371,9 @@ class World implements ChunkManager{ return abs($X - $spawnX) <= 1 and abs($Z - $spawnZ) <= 1; } + /** + * @throws WorldException if the terrain is not generated + */ public function getSafeSpawn(?Vector3 $spawn = null) : Position{ if(!($spawn instanceof Vector3) or $spawn->y < 1){ $spawn = $this->getSpawnLocation(); @@ -2379,31 +2382,31 @@ class World implements ChunkManager{ $max = $this->worldHeight; $v = $spawn->floor(); $chunk = $this->getOrLoadChunkAtPosition($v, false); + if($chunk === null || !$chunk->isGenerated()){ + throw new WorldException("Cannot find a safe spawn point in non-generated terrain"); + } $x = (int) $v->x; - $y = $v->y; $z = (int) $v->z; - if($chunk !== null and $chunk->isGenerated()){ - $y = (int) min($max - 2, $v->y); - $wasAir = $this->getBlockAt($x, $y - 1, $z)->getId() === BlockLegacyIds::AIR; //TODO: bad hack, clean up - for(; $y > 0; --$y){ - if($this->getBlockAt($x, $y, $z)->isFullCube()){ - if($wasAir){ - $y++; - break; - } - }else{ - $wasAir = true; + $y = (int) min($max - 2, $v->y); + $wasAir = $this->getBlockAt($x, $y - 1, $z)->getId() === BlockLegacyIds::AIR; //TODO: bad hack, clean up + for(; $y > 0; --$y){ + if($this->getBlockAt($x, $y, $z)->isFullCube()){ + if($wasAir){ + $y++; + break; } + }else{ + $wasAir = true; } + } - for(; $y >= 0 and $y < $max; ++$y){ - if(!$this->getBlockAt($x, $y + 1, $z)->isFullCube()){ - if(!$this->getBlockAt($x, $y, $z)->isFullCube()){ - return new Position($spawn->x, $y === (int) $spawn->y ? $spawn->y : $y, $spawn->z, $this); - } - }else{ - ++$y; + for(; $y >= 0 and $y < $max; ++$y){ + if(!$this->getBlockAt($x, $y + 1, $z)->isFullCube()){ + if(!$this->getBlockAt($x, $y, $z)->isFullCube()){ + return new Position($spawn->x, $y === (int) $spawn->y ? $spawn->y : $y, $spawn->z, $this); } + }else{ + ++$y; } } From 4ea5401d72f1cb3d75b7663349e6a4fd94fc414f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 26 Nov 2020 19:44:22 +0000 Subject: [PATCH 2115/3224] World->getHighestBlockAt() now throws an exception instead of returning -1 in ungenerated terrain --- src/world/World.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 47cbbc0bfd..ef7bdf17de 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2056,13 +2056,14 @@ class World implements ChunkManager{ /** * Gets the highest block Y value at a specific $x and $z * - * @return int 0-255, or -1 if the chunk is not generated + * @return int 0-255 + * @throws WorldException if the terrain is not generated */ public function getHighestBlockAt(int $x, int $z) : int{ if(($chunk = $this->loadChunk($x >> 4, $z >> 4, false)) !== null){ return $chunk->getHighestBlockAt($x & 0x0f, $z & 0x0f); } - return -1; //TODO: this should probably throw an exception (terrain not generated yet) + throw new WorldException("Cannot get highest block in an ungenerated chunk"); } /** From 0be60fe1eb0beeaf49d864a6ffca45882222e207 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 26 Nov 2020 23:39:19 +0000 Subject: [PATCH 2116/3224] NetworkSession: Force use of async compression during the login sequence when latency doesn't matter closes #3907 this reduces the impact of compression on the login sequence by about 90%; however, since compression only accounted for about 30% of said overhead at most, it's not really a massive difference. --- src/Server.php | 11 +++++++---- src/network/mcpe/NetworkSession.php | 11 ++++++++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/Server.php b/src/Server.php index f75371cc18..5eedb66e44 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1236,18 +1236,21 @@ class Server{ /** * Broadcasts a list of packets in a batch to a list of players + * + * @param bool|null $sync Compression on the main thread (true) or workers (false). Default is automatic (null). */ - public function prepareBatch(PacketBatch $stream, Compressor $compressor, bool $forceSync = false) : CompressBatchPromise{ + public function prepareBatch(PacketBatch $stream, Compressor $compressor, ?bool $sync = null) : CompressBatchPromise{ try{ Timings::$playerNetworkSendCompressTimer->startTiming(); $buffer = $stream->getBuffer(); - if(!$compressor->willCompress($buffer)){ - $forceSync = true; + + if($sync === null){ + $sync = !($this->networkCompressionAsync && $compressor->willCompress($buffer)); } $promise = new CompressBatchPromise(); - if(!$forceSync and $this->networkCompressionAsync){ + if(!$sync){ $task = new CompressBatchTask($buffer, $promise, $compressor); $this->asyncPool->submitTask($task); }else{ diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index ef8faefc4d..2bd9799e7f 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -164,6 +164,8 @@ class NetworkSession{ private $compressedQueue; /** @var Compressor */ private $compressor; + /** @var bool */ + private $forceAsyncCompression = true; /** @var PacketPool */ private $packetPool; @@ -424,7 +426,13 @@ class NetworkSession{ private function flushSendBuffer(bool $immediate = false) : void{ if(count($this->sendBuffer) > 0){ - $promise = $this->server->prepareBatch(PacketBatch::fromPackets(...$this->sendBuffer), $this->compressor, $immediate); + $syncMode = null; //automatic + if($immediate){ + $syncMode = true; + }elseif($this->forceAsyncCompression){ + $syncMode = false; + } + $promise = $this->server->prepareBatch(PacketBatch::fromPackets(...$this->sendBuffer), $this->compressor, $syncMode); $this->sendBuffer = []; $this->queueCompressedNoBufferFlush($promise, $immediate); } @@ -641,6 +649,7 @@ class NetworkSession{ $this->logger->debug("Received spawn response, entering in-game phase"); $this->player->setImmobile(false); //TODO: HACK: we set this during the spawn sequence to prevent the client sending junk movements $this->player->doFirstSpawn(); + $this->forceAsyncCompression = false; $this->setHandler(new InGamePacketHandler($this->player, $this)); } From 37ace198577704d8dce57d3ce7952ae5fe6e6e08 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 26 Nov 2020 23:39:57 +0000 Subject: [PATCH 2117/3224] Updated netresearch/jsonmapper to 3.1.1 --- composer.json | 2 +- composer.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index 02037def1a..2fe93d2b28 100644 --- a/composer.json +++ b/composer.json @@ -46,7 +46,7 @@ "pocketmine/uuid": "^0.1.0", "pocketmine/color": "^0.1.0", "adhocore/json-comment": "^0.1.0", - "netresearch/jsonmapper": "^2.0", + "netresearch/jsonmapper": "^3.1.1", "respect/validation": "^2.0", "composer-runtime-api": "^2.0" }, diff --git a/composer.lock b/composer.lock index 6e2090ba6f..8867810eaf 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b96dbf17a1d0fed7b4545e72afbae5b4", + "content-hash": "0c3e5c9b592778a5c4421bde7dd12d4a", "packages": [ { "name": "adhocore/json-comment", @@ -207,16 +207,16 @@ }, { "name": "netresearch/jsonmapper", - "version": "v2.1.0", + "version": "v3.1.1", "source": { "type": "git", "url": "https://github.com/cweiske/jsonmapper.git", - "reference": "e0f1e33a71587aca81be5cffbb9746510e1fe04e" + "reference": "ba09f0e456d4f00cef84e012da5715625594407c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/e0f1e33a71587aca81be5cffbb9746510e1fe04e", - "reference": "e0f1e33a71587aca81be5cffbb9746510e1fe04e", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/ba09f0e456d4f00cef84e012da5715625594407c", + "reference": "ba09f0e456d4f00cef84e012da5715625594407c", "shasum": "" }, "require": { @@ -252,9 +252,9 @@ "support": { "email": "cweiske@cweiske.de", "issues": "https://github.com/cweiske/jsonmapper/issues", - "source": "https://github.com/cweiske/jsonmapper/tree/master" + "source": "https://github.com/cweiske/jsonmapper/tree/v3.1.1" }, - "time": "2020-04-16T18:48:43+00:00" + "time": "2020-11-02T19:19:54+00:00" }, { "name": "pocketmine/binaryutils", From 4d42f0c3db6ee8544afaa4373894e2a70c28380a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Nov 2020 00:02:34 +0000 Subject: [PATCH 2118/3224] Timings: added timers for player data I/O --- src/Server.php | 60 ++++++++++++++++++++++------------------- src/timings/Timings.php | 8 ++++++ 2 files changed, 40 insertions(+), 28 deletions(-) diff --git a/src/Server.php b/src/Server.php index 5eedb66e44..00199b3fee 100644 --- a/src/Server.php +++ b/src/Server.php @@ -519,30 +519,32 @@ class Server{ } public function getOfflinePlayerData(string $name) : ?CompoundTag{ - $name = strtolower($name); - $path = $this->getPlayerDataPath($name); + return Timings::$syncPlayerDataLoad->time(function() use ($name) : ?CompoundTag{ + $name = strtolower($name); + $path = $this->getPlayerDataPath($name); - if(file_exists($path)){ - $contents = @file_get_contents($path); - if($contents === false){ - throw new \RuntimeException("Failed to read player data file \"$path\" (permission denied?)"); - } - $decompressed = @zlib_decode($contents); - if($decompressed === false){ - $this->logger->debug("Failed to decompress raw player data for \"$name\""); - $this->handleCorruptedPlayerData($name); - return null; - } + if(file_exists($path)){ + $contents = @file_get_contents($path); + if($contents === false){ + throw new \RuntimeException("Failed to read player data file \"$path\" (permission denied?)"); + } + $decompressed = @zlib_decode($contents); + if($decompressed === false){ + $this->logger->debug("Failed to decompress raw player data for \"$name\""); + $this->handleCorruptedPlayerData($name); + return null; + } - try{ - return (new BigEndianNbtSerializer())->read($decompressed)->mustGetCompoundTag(); - }catch(NbtDataException $e){ //zlib decode error / corrupt data - $this->logger->debug("Failed to decode NBT data for \"$name\": " . $e->getMessage()); - $this->handleCorruptedPlayerData($name); - return null; + try{ + return (new BigEndianNbtSerializer())->read($decompressed)->mustGetCompoundTag(); + }catch(NbtDataException $e){ //zlib decode error / corrupt data + $this->logger->debug("Failed to decode NBT data for \"$name\": " . $e->getMessage()); + $this->handleCorruptedPlayerData($name); + return null; + } } - } - return null; + return null; + }); } public function saveOfflinePlayerData(string $name, CompoundTag $nbtTag) : void{ @@ -554,13 +556,15 @@ class Server{ $ev->call(); if(!$ev->isCancelled()){ - $nbt = new BigEndianNbtSerializer(); - try{ - file_put_contents($this->getPlayerDataPath($name), zlib_encode($nbt->write(new TreeRoot($ev->getSaveData())), ZLIB_ENCODING_GZIP)); - }catch(\ErrorException $e){ - $this->logger->critical($this->getLanguage()->translateString("pocketmine.data.saveError", [$name, $e->getMessage()])); - $this->logger->logException($e); - } + Timings::$syncPlayerDataSave->time(function() use ($name, $ev) : void{ + $nbt = new BigEndianNbtSerializer(); + try{ + file_put_contents($this->getPlayerDataPath($name), zlib_encode($nbt->write(new TreeRoot($ev->getSaveData())), ZLIB_ENCODING_GZIP)); + }catch(\ErrorException $e){ + $this->logger->critical($this->getLanguage()->translateString("pocketmine.data.saveError", [$name, $e->getMessage()])); + $this->logger->logException($e); + } + }); } } diff --git a/src/timings/Timings.php b/src/timings/Timings.php index d267798dcf..69dd54505d 100644 --- a/src/timings/Timings.php +++ b/src/timings/Timings.php @@ -107,6 +107,11 @@ abstract class Timings{ /** @var TimingsHandler */ public static $craftingDataCacheRebuildTimer; + /** @var TimingsHandler */ + public static $syncPlayerDataLoad; + /** @var TimingsHandler */ + public static $syncPlayerDataSave; + /** @var TimingsHandler[] */ public static $entityTypeTimingMap = []; /** @var TimingsHandler[] */ @@ -155,6 +160,9 @@ abstract class Timings{ self::$permissibleCalculationTimer = new TimingsHandler("Permissible Calculation"); self::$permissionDefaultTimer = new TimingsHandler("Default Permission Calculation"); + self::$syncPlayerDataLoad = new TimingsHandler("Player Data Load"); + self::$syncPlayerDataSave = new TimingsHandler("Player Data Save"); + self::$entityMoveTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "entityMove"); self::$playerCheckNearEntitiesTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "checkNearEntities"); self::$tickEntityTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "tickEntity"); From 4e94025b3bd575b231798d481e3e64f9e6df52f6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Nov 2020 13:33:25 +0000 Subject: [PATCH 2119/3224] SubChunk: rename defaultBlock -> emptyBlockId this better describes the purpose, which is to identify air. though, it might make more sense to make air just always have zero as air's runtime ID, since this parameter is apparently making plugin devs think that this is suitable to fill a chunk with a specific block ... --- src/world/format/SubChunk.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/world/format/SubChunk.php b/src/world/format/SubChunk.php index 5328d816a4..c461f1b70a 100644 --- a/src/world/format/SubChunk.php +++ b/src/world/format/SubChunk.php @@ -29,7 +29,7 @@ use function count; class SubChunk{ /** @var int */ - private $defaultBlock; + private $emptyBlockId; /** @var PalettedBlockArray[] */ private $blockLayers; @@ -43,8 +43,8 @@ class SubChunk{ * * @param PalettedBlockArray[] $blocks */ - public function __construct(int $default, array $blocks, ?LightArray $skyLight = null, ?LightArray $blockLight = null){ - $this->defaultBlock = $default; + public function __construct(int $emptyBlockId, array $blocks, ?LightArray $skyLight = null, ?LightArray $blockLight = null){ + $this->emptyBlockId = $emptyBlockId; $this->blockLayers = $blocks; $this->skyLight = $skyLight ?? LightArray::fill(15); @@ -71,14 +71,14 @@ class SubChunk{ public function getFullBlock(int $x, int $y, int $z) : int{ if(count($this->blockLayers) === 0){ - return $this->defaultBlock; + return $this->emptyBlockId; } return $this->blockLayers[0]->get($x, $y, $z); } public function setFullBlock(int $x, int $y, int $z, int $block) : void{ if(count($this->blockLayers) === 0){ - $this->blockLayers[] = new PalettedBlockArray($this->defaultBlock); + $this->blockLayers[] = new PalettedBlockArray($this->emptyBlockId); } $this->blockLayers[0]->set($x, $y, $z, $block); } @@ -95,7 +95,7 @@ class SubChunk{ return -1; } for($y = 15; $y >= 0; --$y){ - if($this->blockLayers[0]->get($x, $y, $z) !== $this->defaultBlock){ + if($this->blockLayers[0]->get($x, $y, $z) !== $this->emptyBlockId){ return $y; } } @@ -131,7 +131,7 @@ class SubChunk{ $layer->collectGarbage(); foreach($layer->getPalette() as $p){ - if($p !== $this->defaultBlock){ + if($p !== $this->emptyBlockId){ continue 2; } } From 0a7d81a2b0e01dfe8507c471d8810d5bb8065611 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Nov 2020 13:41:35 +0000 Subject: [PATCH 2120/3224] FastChunkSerializer: retain emptyBlock on subchunks I think we should probably get rid of this considering the potential for inconsistencies within a chunk, but not retaining this is a bug nonetheless, even though it doesn't have any effect in PM itself since we always use BlockLegacyIds << 4 as the empty block ID. so, this is only really aiding (ab)use cases which weren't intended anyway ... --- src/world/format/SubChunk.php | 6 ++++++ src/world/format/io/FastChunkSerializer.php | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/world/format/SubChunk.php b/src/world/format/SubChunk.php index c461f1b70a..e784aa6501 100644 --- a/src/world/format/SubChunk.php +++ b/src/world/format/SubChunk.php @@ -69,6 +69,12 @@ class SubChunk{ return count($this->blockLayers) === 0; } + /** + * Returns the block used as the default. This is assumed to refer to air. + * If all the blocks in a subchunk layer are equal to this block, the layer is assumed to be empty. + */ + public function getEmptyBlockId() : int{ return $this->emptyBlockId; } + public function getFullBlock(int $x, int $y, int $z) : int{ if(count($this->blockLayers) === 0){ return $this->emptyBlockId; diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index 16883a40ef..b180c75bb9 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\world\format\io; -use pocketmine\block\BlockLegacyIds; use pocketmine\utils\BinaryStream; use pocketmine\world\format\BiomeArray; use pocketmine\world\format\Chunk; @@ -77,6 +76,7 @@ final class FastChunkSerializer{ foreach($subChunks as $y => $subChunk){ $stream->putByte($y); + $stream->putInt($subChunk->getEmptyBlockId()); $layers = $subChunk->getBlockLayers(); $stream->putByte(count($layers)); foreach($layers as $blocks){ @@ -126,6 +126,7 @@ final class FastChunkSerializer{ $count = $stream->getByte(); for($subCount = 0; $subCount < $count; ++$subCount){ $y = $stream->getByte(); + $airBlockId = $stream->getInt(); /** @var PalettedBlockArray[] $layers */ $layers = []; @@ -137,7 +138,7 @@ final class FastChunkSerializer{ $layers[] = PalettedBlockArray::fromData($bitsPerBlock, $words, $palette); } $subChunks[$y] = new SubChunk( - BlockLegacyIds::AIR << 4, $layers, $lightPopulated ? new LightArray($stream->get(2048)) : null, $lightPopulated ? new LightArray($stream->get(2048)) : null + $airBlockId, $layers, $lightPopulated ? new LightArray($stream->get(2048)) : null, $lightPopulated ? new LightArray($stream->get(2048)) : null ); } From 5142281cfaf9cf5bea7fec45e61e3b2fc40429ba Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Nov 2020 17:57:52 +0000 Subject: [PATCH 2121/3224] [ci skip] Server: remove misleading comment --- src/Server.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Server.php b/src/Server.php index 00199b3fee..5288a39881 100644 --- a/src/Server.php +++ b/src/Server.php @@ -537,7 +537,7 @@ class Server{ try{ return (new BigEndianNbtSerializer())->read($decompressed)->mustGetCompoundTag(); - }catch(NbtDataException $e){ //zlib decode error / corrupt data + }catch(NbtDataException $e){ //corrupt data $this->logger->debug("Failed to decode NBT data for \"$name\": " . $e->getMessage()); $this->handleCorruptedPlayerData($name); return null; From 5e44d5f75e20a1e515da44e88220350b4e9fb716 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Nov 2020 18:06:59 +0000 Subject: [PATCH 2122/3224] Do not load playerdata from disk just to op/deop/whitelist/dewhitelist this is an impressively dumb idea. the playerdata is not used here in any capacity so it doesn't make sense to load it, especially considering that it takes a significant amount of time. --- src/command/defaults/DeopCommand.php | 7 +++---- src/command/defaults/OpCommand.php | 7 +++---- src/command/defaults/WhitelistCommand.php | 4 ++-- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/command/defaults/DeopCommand.php b/src/command/defaults/DeopCommand.php index c9f052f120..8448f27ac6 100644 --- a/src/command/defaults/DeopCommand.php +++ b/src/command/defaults/DeopCommand.php @@ -57,12 +57,11 @@ class DeopCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $player = $sender->getServer()->getOfflinePlayer($name); - $player->setOp(false); - if($player instanceof Player){ + $sender->getServer()->removeOp($name); + if(($player = $sender->getServer()->getPlayerExact($name)) !== null){ $player->sendMessage(TextFormat::GRAY . "You are no longer op!"); } - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.deop.success", [$player->getName()])); + Command::broadcastCommandMessage($sender, new TranslationContainer("commands.deop.success", [$name])); return true; } diff --git a/src/command/defaults/OpCommand.php b/src/command/defaults/OpCommand.php index fd711d98c2..0b4537d2cc 100644 --- a/src/command/defaults/OpCommand.php +++ b/src/command/defaults/OpCommand.php @@ -57,12 +57,11 @@ class OpCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $player = $sender->getServer()->getOfflinePlayer($name); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.op.success", [$player->getName()])); - if($player instanceof Player){ + $sender->getServer()->addOp($name); + if(($player = $sender->getServer()->getPlayerExact($name)) !== null){ $player->sendMessage(TextFormat::GRAY . "You are now op!"); } - $player->setOp(true); + Command::broadcastCommandMessage($sender, new TranslationContainer("commands.op.success", [$name])); return true; } } diff --git a/src/command/defaults/WhitelistCommand.php b/src/command/defaults/WhitelistCommand.php index ed53ee575b..1a9547c37a 100644 --- a/src/command/defaults/WhitelistCommand.php +++ b/src/command/defaults/WhitelistCommand.php @@ -99,12 +99,12 @@ class WhitelistCommand extends VanillaCommand{ } switch(strtolower($args[0])){ case "add": - $sender->getServer()->getOfflinePlayer($args[1])->setWhitelisted(true); + $sender->getServer()->addWhitelist($args[1]); Command::broadcastCommandMessage($sender, new TranslationContainer("commands.whitelist.add.success", [$args[1]])); return true; case "remove": - $sender->getServer()->getOfflinePlayer($args[1])->setWhitelisted(false); + $sender->getServer()->removeWhitelist($args[1]); Command::broadcastCommandMessage($sender, new TranslationContainer("commands.whitelist.remove.success", [$args[1]])); return true; From 9969c928a84ac58a9409b7ddeeca4430ada68402 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Nov 2020 18:37:42 +0000 Subject: [PATCH 2123/3224] Player: Improved hardcore death handling it's now possible to cancel the banning by cancelling PlayerKickEvent. In addition, the disconnect message will now properly explain why the player is banned instead of just saying 'You have been banned', and also banned-players.txt will show 'Died in hardcore mode' as the reason instead of being completely blank (seriously, we couldn't tell the difference between real bans and hardcore bans????) --- src/player/Player.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index 766929296a..46fc4385e2 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2174,7 +2174,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ public function respawn() : void{ if($this->server->isHardcore()){ - $this->setBanned(true); + if($this->kick("You have been banned because you died in hardcore mode")){ //this allows plugins to prevent the ban by cancelling PlayerKickEvent + $this->server->getNameBans()->addBan($this->getName(), "Died in hardcore mode"); + } return; } From c4544416468c87ff402d7f309dd23993e3680a0c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Nov 2020 18:54:09 +0000 Subject: [PATCH 2124/3224] [ci skip] updated changelog --- changelogs/4.0-snapshot.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 2328392f07..9193de3e54 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -36,6 +36,7 @@ This major version features substantial changes throughout the core, including s - `leveldb` is now the primary supported world format. It is inherently faster than region-based formats thanks to better design. - Partial chunk saves (only saving modified subcomponents of chunks) has been implemented. This drastically reduces the amount of data that is usually necessary to write on chunk save, which in turn **drastically reduces the time to complete world saves**. This is possible thanks to the modular design of the `leveldb` world format - this enhancement is not possible with region-based formats. - Lighting is no longer guaranteed to be available on every chunk. It's now calculated on the fly as-needed. +- `/op`, `/deop`, `/whitelist add` and `/whitelist remove` no longer cause player data to be loaded from disk for no reason. ### Logger revamp - Many components now have a dedicated logger which automatically adds [prefixes] to their messages. @@ -763,6 +764,9 @@ This version features substantial changes to the network system, improving coher - `World->getName()` -> `World->getDisplayName()` - The following API methods have changed behaviour: - `World->getChunk()` no longer tries to load chunks from disk. If the chunk is not already in memory, null is returned. (This behaviour now properly matches other `ChunkManager` implementations.) + - The following methods now throw `WorldException` when targeting ungenerated terrain: + - `World->getSafeSpawn()` (previously it just silently returned the input position) + - `World->getHighestBlockAt()` (previously it returned -1) - Extracted a unit `pocketmine\world\format\io\FastChunkSerializer` from `Chunk`: - `Chunk->fastDeserialize()` -> `FastChunkSerializer::deserialize()` - `Chunk->fastSerialize()` -> `FastChunkSerializer::serialize()` From 1de486733aedfbfe5c687ed9c6b7aff721d48282 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Nov 2020 19:56:39 +0000 Subject: [PATCH 2125/3224] Permission: remove dead code Bukkit CCC at its finest... what the fuck this was doing anyway I have no idea an addChild() method would have made far more sense, especially considering that addParent() doesn't actually mutate the child. --- src/permission/Permission.php | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/permission/Permission.php b/src/permission/Permission.php index 9361dea24e..02066b26da 100644 --- a/src/permission/Permission.php +++ b/src/permission/Permission.php @@ -116,27 +116,4 @@ class Permission{ $p->recalculatePermissions(); } } - - /** - * @param string|Permission $name - * - * @return Permission|null Permission if $name is a string, null if it's a Permission - */ - public function addParent($name, bool $value) : ?Permission{ - if($name instanceof Permission){ - $name->getChildren()[$this->getName()] = $value; - $name->recalculatePermissibles(); - return null; - }else{ - $perm = PermissionManager::getInstance()->getPermission($name); - if($perm === null){ - $perm = new Permission($name); - PermissionManager::getInstance()->addPermission($perm); - } - - $this->addParent($perm, $value); - - return $perm; - } - } } From f0e43a6b22ce78488430d79b630433492da7ebf1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Nov 2020 19:59:49 +0000 Subject: [PATCH 2126/3224] DefaultPermissions: remove ridiculous recursion this line is totally useless since the recursion does exactly the same thing as if it wasn't there. --- src/permission/DefaultPermissions.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/permission/DefaultPermissions.php b/src/permission/DefaultPermissions.php index 28432e1267..5fa38c9e99 100644 --- a/src/permission/DefaultPermissions.php +++ b/src/permission/DefaultPermissions.php @@ -29,8 +29,6 @@ abstract class DefaultPermissions{ public static function registerPermission(Permission $perm, ?Permission $parent = null) : Permission{ if($parent instanceof Permission){ $parent->getChildren()[$perm->getName()] = true; - - return self::registerPermission($perm); } PermissionManager::getInstance()->addPermission($perm); From 3849756993bfd4c4b51146c1eb9737442514d628 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Nov 2020 20:28:36 +0000 Subject: [PATCH 2127/3224] Do not mutate the result of Permission->getChildren() --- src/permission/DefaultPermissions.php | 2 +- src/permission/Permission.php | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/permission/DefaultPermissions.php b/src/permission/DefaultPermissions.php index 5fa38c9e99..f6de4ec07a 100644 --- a/src/permission/DefaultPermissions.php +++ b/src/permission/DefaultPermissions.php @@ -28,7 +28,7 @@ abstract class DefaultPermissions{ public static function registerPermission(Permission $perm, ?Permission $parent = null) : Permission{ if($parent instanceof Permission){ - $parent->getChildren()[$perm->getName()] = true; + $parent->addChild($perm->getName(), true); } PermissionManager::getInstance()->addPermission($perm); diff --git a/src/permission/Permission.php b/src/permission/Permission.php index 02066b26da..ad28f7d55a 100644 --- a/src/permission/Permission.php +++ b/src/permission/Permission.php @@ -116,4 +116,9 @@ class Permission{ $p->recalculatePermissions(); } } + + public function addChild(string $name, bool $value) : void{ + $this->children[$name] = $value; + $this->recalculatePermissibles(); + } } From aa67c4894ff7586ca8de437c78c20d8dbf8b2911 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Nov 2020 20:31:24 +0000 Subject: [PATCH 2128/3224] Permission: added removeChild() this probably isn't useful at all, but it's best to provide alternatives for all the stuff that getChildren() could have been used for ... --- src/permission/Permission.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/permission/Permission.php b/src/permission/Permission.php index ad28f7d55a..b5f8e9dd9a 100644 --- a/src/permission/Permission.php +++ b/src/permission/Permission.php @@ -121,4 +121,10 @@ class Permission{ $this->children[$name] = $value; $this->recalculatePermissibles(); } + + public function removeChild(string $name) : void{ + unset($this->children[$name]); + $this->recalculatePermissibles(); + + } } From ecbc4e94335c2317a94035daec75a3146a0638d0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Nov 2020 20:31:59 +0000 Subject: [PATCH 2129/3224] Permission->getChildren() no longer returns by-ref --- src/permission/Permission.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/permission/Permission.php b/src/permission/Permission.php index b5f8e9dd9a..21043fdedc 100644 --- a/src/permission/Permission.php +++ b/src/permission/Permission.php @@ -77,7 +77,7 @@ class Permission{ * @return bool[] * @phpstan-return array */ - public function &getChildren() : array{ + public function getChildren() : array{ return $this->children; } From 70b0d832583c162484458e1ef4dbc70c174ea7b4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 28 Nov 2020 13:01:10 +0000 Subject: [PATCH 2130/3224] Removed Server->broadcast() this method has an explicit dependency on permission subscriptions, which I plan to eradicate. The method's functionality can be replaced using Server->broadcastMessage() with a custom recipients array. --- src/Server.php | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/src/Server.php b/src/Server.php index 5288a39881..b3348c7366 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1090,7 +1090,12 @@ class Server{ */ public function broadcastMessage($message, ?array $recipients = null) : int{ if(!is_array($recipients)){ - return $this->broadcast($message, self::BROADCAST_CHANNEL_USERS); + $recipients = []; + foreach(PermissionManager::getInstance()->getPermissionSubscriptions(self::BROADCAST_CHANNEL_USERS) as $permissible){ + if($permissible instanceof CommandSender and $permissible->hasPermission(self::BROADCAST_CHANNEL_USERS)){ + $recipients[spl_object_id($permissible)] = $permissible; // do not send messages directly, or some might be repeated + } + } } foreach($recipients as $recipient){ @@ -1156,27 +1161,6 @@ class Server{ return count($recipients); } - /** - * @param TranslationContainer|string $message - */ - public function broadcast($message, string $permissions) : int{ - /** @var CommandSender[] $recipients */ - $recipients = []; - foreach(explode(";", $permissions) as $permission){ - foreach(PermissionManager::getInstance()->getPermissionSubscriptions($permission) as $permissible){ - if($permissible instanceof CommandSender and $permissible->hasPermission($permission)){ - $recipients[spl_object_id($permissible)] = $permissible; // do not send messages directly, or some might be repeated - } - } - } - - foreach($recipients as $recipient){ - $recipient->sendMessage($message); - } - - return count($recipients); - } - /** * @param Player[] $players * @param ClientboundPacket[] $packets From 8cf589eeddd2340d471743dc32509513c8d7183d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 28 Nov 2020 15:36:46 +0000 Subject: [PATCH 2131/3224] Strip some junk out of IPlayer these methods have better pathways through Server directly. Also, setBanned() does not allow customising the reason for banning or the duration, nor does isBanned() account for IP bans because the code is so old ... better to force dependence on a central code path to avoid these inconsistencies. I want to do the same thing for OP, but that's a separate problem due to its effects on the permission system. --- changelogs/4.0-snapshot.md | 5 ++++- src/player/IPlayer.php | 8 -------- src/player/OfflinePlayer.php | 24 ------------------------ src/player/Player.php | 25 ------------------------- 4 files changed, 4 insertions(+), 58 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 9193de3e54..94354649ce 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -597,7 +597,10 @@ This version features substantial changes to the network system, improving coher - `Player->updatePing()`: moved to `NetworkSession` - `Player->dataPacket()`: replaced by `NetworkSession->sendDataPacket()` - `Player->sendDataPacket()`: replaced by `NetworkSession->sendDataPacket()` - + - `IPlayer->isWhitelisted()`: use `Server->isWhitelisted()` instead + - `IPlayer->setWhitelisted()`: use `Server->setWhitelisted()` instead + - `IPlayer->isBanned()`: this was unreliable because it only checked name bans and didn't account for plugin custom ban systems. Use `Server->getNameBans()->isBanned()` and `Server->getIPBans()->isBanned()` instead. + - `IPlayer->setBanned()`: use `Server` APIs instead ### Plugin - API version checks are now more strict. It is no longer legal to declare multiple minimum versions on the same major version. Doing so will now cause the plugin to fail to load with the message `Multiple minimum API versions found for some major versions`. diff --git a/src/player/IPlayer.php b/src/player/IPlayer.php index 607033f5d0..c5c8430c9b 100644 --- a/src/player/IPlayer.php +++ b/src/player/IPlayer.php @@ -31,14 +31,6 @@ interface IPlayer extends ServerOperator{ public function getName() : string; - public function isBanned() : bool; - - public function setBanned(bool $banned) : void; - - public function isWhitelisted() : bool; - - public function setWhitelisted(bool $value) : void; - public function getFirstPlayed() : ?int; public function getLastPlayed() : ?int; diff --git a/src/player/OfflinePlayer.php b/src/player/OfflinePlayer.php index a484a4c756..8aa42c9988 100644 --- a/src/player/OfflinePlayer.php +++ b/src/player/OfflinePlayer.php @@ -70,30 +70,6 @@ class OfflinePlayer implements IPlayer{ } } - public function isBanned() : bool{ - return $this->server->getNameBans()->isBanned($this->name); - } - - public function setBanned(bool $banned) : void{ - if($banned){ - $this->server->getNameBans()->addBan($this->name, null, null, null); - }else{ - $this->server->getNameBans()->remove($this->name); - } - } - - public function isWhitelisted() : bool{ - return $this->server->isWhitelisted($this->name); - } - - public function setWhitelisted(bool $value) : void{ - if($value){ - $this->server->addWhitelist($this->name); - }else{ - $this->server->removeWhitelist($this->name); - } - } - public function getPlayer() : ?Player{ return $this->server->getPlayerExact($this->name); } diff --git a/src/player/Player.php b/src/player/Player.php index 46fc4385e2..708a25109a 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -368,31 +368,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return ""; } - public function isBanned() : bool{ - return $this->server->getNameBans()->isBanned($this->username); - } - - public function setBanned(bool $banned) : void{ - if($banned){ - $this->server->getNameBans()->addBan($this->getName(), null, null, null); - $this->kick("You have been banned"); - }else{ - $this->server->getNameBans()->remove($this->getName()); - } - } - - public function isWhitelisted() : bool{ - return $this->server->isWhitelisted($this->username); - } - - public function setWhitelisted(bool $value) : void{ - if($value){ - $this->server->addWhitelist($this->username); - }else{ - $this->server->removeWhitelist($this->username); - } - } - public function isAuthenticated() : bool{ return $this->authenticated; } From c7961bfe905c4f7caf5981f128f6b4547bae3079 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 28 Nov 2020 18:22:59 +0000 Subject: [PATCH 2132/3224] Toss ServerOperator; PermissibleBase now tracks its own op status as well as being simpler, this also allows some nice features, such as granting memory-only op state that goes away when the player quits the server. --- src/Server.php | 4 +-- src/command/ConsoleCommandSender.php | 8 ++--- src/permission/Permissible.php | 6 +++- src/permission/PermissibleBase.php | 22 ++++++------- src/permission/PermissibleDelegateTrait.php | 8 +++++ src/permission/ServerOperator.php | 36 --------------------- src/player/IPlayer.php | 4 +-- src/player/Player.php | 22 ++----------- 8 files changed, 32 insertions(+), 78 deletions(-) delete mode 100644 src/permission/ServerOperator.php diff --git a/src/Server.php b/src/Server.php index b3348c7366..137b65f194 100644 --- a/src/Server.php +++ b/src/Server.php @@ -677,7 +677,7 @@ class Server{ $this->operators->set(strtolower($name), true); if(($player = $this->getPlayerExact($name)) !== null){ - $player->recalculatePermissions(); + $player->onOpStatusChange(true); } $this->operators->save(); } @@ -686,7 +686,7 @@ class Server{ $this->operators->remove(strtolower($name)); if(($player = $this->getPlayerExact($name)) !== null){ - $player->recalculatePermissions(); + $player->onOpStatusChange(false); } $this->operators->save(); } diff --git a/src/command/ConsoleCommandSender.php b/src/command/ConsoleCommandSender.php index 4a803a0451..49b25efa58 100644 --- a/src/command/ConsoleCommandSender.php +++ b/src/command/ConsoleCommandSender.php @@ -44,7 +44,7 @@ class ConsoleCommandSender implements CommandSender{ public function __construct(Server $server, Language $language){ $this->server = $server; - $this->perm = new PermissibleBase($this); + $this->perm = new PermissibleBase($this, true); $this->language = $language; } @@ -76,11 +76,7 @@ class ConsoleCommandSender implements CommandSender{ return "CONSOLE"; } - public function isOp() : bool{ - return true; - } - - public function setOp(bool $value) : void{ + public function onOpStatusChange(bool $value) : void{ } diff --git a/src/permission/Permissible.php b/src/permission/Permissible.php index a9be574e26..0a27590254 100644 --- a/src/permission/Permissible.php +++ b/src/permission/Permissible.php @@ -25,7 +25,11 @@ namespace pocketmine\permission; use pocketmine\plugin\Plugin; -interface Permissible extends ServerOperator{ +interface Permissible{ + + public function isOp() : bool; + + public function onOpStatusChange(bool $value) : void; /** * Checks if this instance has a permission overridden diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index fa75143329..fcff5e01cb 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -29,11 +29,11 @@ use pocketmine\timings\Timings; use function spl_object_id; class PermissibleBase implements Permissible{ - /** @var ServerOperator */ - private $opable; + /** @var bool */ + private $op; /** @var Permissible|null */ - private $parent = null; + private $parent; /** @var PermissionAttachment[] */ private $attachments = []; @@ -41,19 +41,19 @@ class PermissibleBase implements Permissible{ /** @var PermissionAttachmentInfo[] */ private $permissions = []; - public function __construct(ServerOperator $opable){ - $this->opable = $opable; - if($opable instanceof Permissible){ - $this->parent = $opable; - } + public function __construct(?Permissible $permissible, bool $isOp){ + $this->parent = $permissible; + $this->op = $isOp; + //TODO: permissions need to be recalculated here, or inherited permissions won't work } public function isOp() : bool{ - return $this->opable->isOp(); + return $this->op; } - public function setOp(bool $value) : void{ - $this->opable->setOp($value); + public function onOpStatusChange(bool $value) : void{ + $this->op = $value; + $this->recalculatePermissions(); } /** diff --git a/src/permission/PermissibleDelegateTrait.php b/src/permission/PermissibleDelegateTrait.php index a2cba9544d..f488a6f396 100644 --- a/src/permission/PermissibleDelegateTrait.php +++ b/src/permission/PermissibleDelegateTrait.php @@ -30,6 +30,14 @@ trait PermissibleDelegateTrait{ /** @var PermissibleBase */ private $perm; + public function isOp() : bool{ + return $this->perm->isOp(); + } + + public function onOpStatusChange(bool $value) : void{ + $this->perm->onOpStatusChange($value); + } + /** * @param Permission|string $name */ diff --git a/src/permission/ServerOperator.php b/src/permission/ServerOperator.php deleted file mode 100644 index bc5f233f23..0000000000 --- a/src/permission/ServerOperator.php +++ /dev/null @@ -1,36 +0,0 @@ -uuid = $this->playerInfo->getUuid(); $this->xuid = $this->playerInfo instanceof XboxLivePlayerInfo ? $this->playerInfo->getXuid() : ""; - $this->perm = new PermissibleBase($this); + $this->perm = new PermissibleBase($this, $this->server->isOp($this->username)); $this->chunksPerTick = (int) $this->server->getConfigGroup()->getProperty("chunk-sending.per-tick", 4); $this->spawnThreshold = (int) (($this->server->getConfigGroup()->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); $this->chunkSelector = new ChunkSelector(); @@ -523,24 +523,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return $this->isConnected(); } - public function isOp() : bool{ - return $this->server->isOp($this->getName()); - } - - public function setOp(bool $value) : void{ - if($value === $this->isOp()){ - return; - } - - if($value){ - $this->server->addOp($this->getName()); - }else{ - $this->server->removeOp($this->getName()); - } - - $this->networkSession->syncAdventureSettings($this); - } - public function recalculatePermissions() : void{ $permManager = PermissionManager::getInstance(); $permManager->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this); @@ -552,6 +534,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->delegateRecalculatePermissions(); + $this->networkSession->syncAdventureSettings($this); + if($this->spawned){ if($this->hasPermission(Server::BROADCAST_CHANNEL_USERS)){ $permManager->subscribeToPermission(Server::BROADCAST_CHANNEL_USERS, $this); From b40720749bf5cd1f3e8e98018f38eb12a7f904d6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 28 Nov 2020 18:29:13 +0000 Subject: [PATCH 2133/3224] ZippedResourcePack: improved exception error on invalid manifest contents --- src/resourcepacks/ZippedResourcePack.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/resourcepacks/ZippedResourcePack.php b/src/resourcepacks/ZippedResourcePack.php index c9acd2a272..9f2593c845 100644 --- a/src/resourcepacks/ZippedResourcePack.php +++ b/src/resourcepacks/ZippedResourcePack.php @@ -112,7 +112,7 @@ class ZippedResourcePack implements ResourcePack{ /** @var Manifest $manifest */ $manifest = $mapper->map($manifest, new Manifest()); }catch(\JsonMapper_Exception $e){ - throw new ResourcePackException("manifest.json is missing required fields"); + throw new ResourcePackException("Invalid manifest.json contents: " . $e->getMessage(), 0, $e); } $this->manifest = $manifest; From 011d1713c03482c125cf9bd74caf2f53a2e40bc1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 28 Nov 2020 18:33:08 +0000 Subject: [PATCH 2134/3224] [ci skip] changelog updates --- changelogs/4.0-snapshot.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 94354649ce..093669d0fa 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -552,8 +552,14 @@ This version features substantial changes to the network system, improving coher - `Permission::loadPermission()` -> `PermissionParser::loadPermission()` - The following API methods have been added: - `PermissionParser::emitPermissions()` + - `Permission->addChild()` + - `Permission->removeChild()` +- The following API methods have been removed: + - `Permission->addParent()` - The following API methods have changes: - `PermissionParser::defaultFromString()` now throws `InvalidArgumentException` on unknown values. +- The following classes have been removed: + - `ServerOperator` ### Player - The following classes have moved to the new `pocketmine\player` namespace: @@ -601,6 +607,8 @@ This version features substantial changes to the network system, improving coher - `IPlayer->setWhitelisted()`: use `Server->setWhitelisted()` instead - `IPlayer->isBanned()`: this was unreliable because it only checked name bans and didn't account for plugin custom ban systems. Use `Server->getNameBans()->isBanned()` and `Server->getIPBans()->isBanned()` instead. - `IPlayer->setBanned()`: use `Server` APIs instead + - `IPlayer->isOp()`: use `Server` APIs instead + - `IPlayer->setOp()`: use `Server` APIs instead ### Plugin - API version checks are now more strict. It is no longer legal to declare multiple minimum versions on the same major version. Doing so will now cause the plugin to fail to load with the message `Multiple minimum API versions found for some major versions`. From ee7fad2271c9c0cf549b4297219d36a1c57f7d8d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 28 Nov 2020 19:22:30 +0000 Subject: [PATCH 2135/3224] PermissibleBase: fixed root permissible being unaware of changes in some cases for example, Player->recalculatePermissions() was not called when a player's op status changed, nor when a permission attachment altered permissions (potential secvuln for broadcasting). --- src/permission/PermissibleBase.php | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index fcff5e01cb..31ac423fc9 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -47,13 +47,17 @@ class PermissibleBase implements Permissible{ //TODO: permissions need to be recalculated here, or inherited permissions won't work } + private function getRootPermissible() : Permissible{ + return $this->parent ?? $this; + } + public function isOp() : bool{ return $this->op; } public function onOpStatusChange(bool $value) : void{ $this->op = $value; - $this->recalculatePermissions(); + $this->getRootPermissible()->recalculatePermissions(); } /** @@ -93,13 +97,13 @@ class PermissibleBase implements Permissible{ throw new PluginException("Plugin " . $plugin->getDescription()->getName() . " is disabled"); } - $result = new PermissionAttachment($plugin, $this->parent ?? $this); + $result = new PermissionAttachment($plugin, $this->getRootPermissible()); $this->attachments[spl_object_id($result)] = $result; if($name !== null and $value !== null){ $result->setPermission($name, $value); } - $this->recalculatePermissions(); + $this->getRootPermissible()->recalculatePermissions(); return $result; } @@ -111,7 +115,7 @@ class PermissibleBase implements Permissible{ $ex->attachmentRemoved($attachment); } - $this->recalculatePermissions(); + $this->getRootPermissible()->recalculatePermissions(); } @@ -123,12 +127,12 @@ class PermissibleBase implements Permissible{ $this->clearPermissions(); $permManager = PermissionManager::getInstance(); $defaults = $permManager->getDefaultPermissions($this->isOp()); - $permManager->subscribeToDefaultPerms($this->isOp(), $this->parent ?? $this); + $permManager->subscribeToDefaultPerms($this->isOp(), $this->getRootPermissible()); foreach($defaults as $perm){ $name = $perm->getName(); - $this->permissions[$name] = new PermissionAttachmentInfo($this->parent ?? $this, $name, null, true); - $permManager->subscribeToPermission($name, $this->parent ?? $this); + $this->permissions[$name] = new PermissionAttachmentInfo($this->getRootPermissible(), $name, null, true); + $permManager->subscribeToPermission($name, $this->getRootPermissible()); $this->calculateChildPermissions($perm->getChildren(), false, null); } @@ -141,10 +145,10 @@ class PermissibleBase implements Permissible{ public function clearPermissions() : void{ $permManager = PermissionManager::getInstance(); - $permManager->unsubscribeFromAllPermissions($this->parent ?? $this); + $permManager->unsubscribeFromAllPermissions($this->getRootPermissible()); - $permManager->unsubscribeFromDefaultPerms(false, $this->parent ?? $this); - $permManager->unsubscribeFromDefaultPerms(true, $this->parent ?? $this); + $permManager->unsubscribeFromDefaultPerms(false, $this->getRootPermissible()); + $permManager->unsubscribeFromDefaultPerms(true, $this->getRootPermissible()); $this->permissions = []; } @@ -157,8 +161,8 @@ class PermissibleBase implements Permissible{ foreach($children as $name => $v){ $perm = $permManager->getPermission($name); $value = ($v xor $invert); - $this->permissions[$name] = new PermissionAttachmentInfo($this->parent ?? $this, $name, $attachment, $value); - $permManager->subscribeToPermission($name, $this->parent ?? $this); + $this->permissions[$name] = new PermissionAttachmentInfo($this->getRootPermissible(), $name, $attachment, $value); + $permManager->subscribeToPermission($name, $this->getRootPermissible()); if($perm instanceof Permission){ $this->calculateChildPermissions($perm->getChildren(), !$value, $attachment); From dd200ca8cd544f2e4deda13c67e9c40da99d5340 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 28 Nov 2020 19:28:47 +0000 Subject: [PATCH 2136/3224] Rewrite message broadcasting system to not depend on PermissionManager subscriptions relying on permission subscriptions for this was unreliable (a permissible is not always subscribed to a permission even when it does have it), and also difficult to control (for example there have been various bugs in the past where a Player ended up subscribed to broadcast permissions when it didn't expect to be, thanks to permission recalculation happening too early). In addition, we might in the future want to have broadcast receivers which are not permissibles (i.e. a more general interface than CommandSender (why does a broadcast receiver need to also be a command sender, anyway?)), which the permission system wouldn't be suitable for. --- src/Server.php | 73 +++++++++++++++++++++------- src/command/Command.php | 12 ++--- src/event/player/PlayerChatEvent.php | 15 +----- src/player/Player.php | 19 +++----- 4 files changed, 70 insertions(+), 49 deletions(-) diff --git a/src/Server.php b/src/Server.php index 137b65f194..ddcb05027e 100644 --- a/src/Server.php +++ b/src/Server.php @@ -62,7 +62,6 @@ use pocketmine\network\query\QueryInfo; use pocketmine\network\upnp\UPnP; use pocketmine\permission\BanList; use pocketmine\permission\DefaultPermissions; -use pocketmine\permission\PermissionManager; use pocketmine\player\GameMode; use pocketmine\player\OfflinePlayer; use pocketmine\player\Player; @@ -277,6 +276,12 @@ class Server{ /** @var Player[] */ private $playerList = []; + /** + * @var CommandSender[][] + * @phpstan-var array> + */ + private $broadcastSubscribers = []; + public function getName() : string{ return VersionInfo::NAME; } @@ -1063,8 +1068,8 @@ class Server{ //TODO: move console parts to a separate component $consoleSender = new ConsoleCommandSender($this, $this->language); - PermissionManager::getInstance()->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $consoleSender); - PermissionManager::getInstance()->subscribeToPermission(Server::BROADCAST_CHANNEL_USERS, $consoleSender); + $this->subscribeToBroadcastChannel(self::BROADCAST_CHANNEL_ADMINISTRATIVE, $consoleSender); + $this->subscribeToBroadcastChannel(self::BROADCAST_CHANNEL_USERS, $consoleSender); $consoleNotifier = new SleeperNotifier(); $this->console = new CommandReader($consoleNotifier); @@ -1084,19 +1089,51 @@ class Server{ } } + /** + * Subscribes to a particular message broadcast channel. + * The channel ID can be any arbitrary string. + */ + public function subscribeToBroadcastChannel(string $channelId, CommandSender $subscriber) : void{ + $this->broadcastSubscribers[$channelId][spl_object_id($subscriber)] = $subscriber; + } + + /** + * Unsubscribes from a particular message broadcast channel. + */ + public function unsubscribeFromBroadcastChannel(string $channelId, CommandSender $subscriber) : void{ + if(isset($this->broadcastSubscribers[$channelId][spl_object_id($subscriber)])){ + unset($this->broadcastSubscribers[$channelId][spl_object_id($subscriber)]); + if(count($this->broadcastSubscribers[$channelId]) === 0){ + unset($this->broadcastSubscribers[$channelId]); + } + } + } + + /** + * Unsubscribes from all broadcast channels. + */ + public function unsubscribeFromAllBroadcastChannels(CommandSender $subscriber) : void{ + foreach($this->broadcastSubscribers as $channelId => $recipients){ + $this->unsubscribeFromBroadcastChannel($channelId, $subscriber); + } + } + + /** + * Returns a list of all the CommandSenders subscribed to the given broadcast channel. + * + * @return CommandSender[] + * @phpstan-return array + */ + public function getBroadcastChannelSubscribers(string $channelId) : array{ + return $this->broadcastSubscribers[$channelId] ?? []; + } + /** * @param TranslationContainer|string $message * @param CommandSender[]|null $recipients */ public function broadcastMessage($message, ?array $recipients = null) : int{ - if(!is_array($recipients)){ - $recipients = []; - foreach(PermissionManager::getInstance()->getPermissionSubscriptions(self::BROADCAST_CHANNEL_USERS) as $permissible){ - if($permissible instanceof CommandSender and $permissible->hasPermission(self::BROADCAST_CHANNEL_USERS)){ - $recipients[spl_object_id($permissible)] = $permissible; // do not send messages directly, or some might be repeated - } - } - } + $recipients = $recipients ?? $this->getBroadcastChannelSubscribers(self::BROADCAST_CHANNEL_USERS); foreach($recipients as $recipient){ $recipient->sendMessage($message); @@ -1108,12 +1145,12 @@ class Server{ /** * @return Player[] */ - private function selectPermittedPlayers(string $permission) : array{ + private function getPlayerBroadcastSubscribers(string $channelId) : array{ /** @var Player[] $players */ $players = []; - foreach(PermissionManager::getInstance()->getPermissionSubscriptions($permission) as $permissible){ - if($permissible instanceof Player and $permissible->hasPermission($permission)){ - $players[spl_object_id($permissible)] = $permissible; //prevent duplication + foreach($this->broadcastSubscribers[$channelId] as $subscriber){ + if($subscriber instanceof Player){ + $players[spl_object_id($subscriber)] = $subscriber; } } return $players; @@ -1123,7 +1160,7 @@ class Server{ * @param Player[]|null $recipients */ public function broadcastTip(string $tip, ?array $recipients = null) : int{ - $recipients = $recipients ?? $this->selectPermittedPlayers(self::BROADCAST_CHANNEL_USERS); + $recipients = $recipients ?? $this->getPlayerBroadcastSubscribers(self::BROADCAST_CHANNEL_USERS); foreach($recipients as $recipient){ $recipient->sendTip($tip); @@ -1136,7 +1173,7 @@ class Server{ * @param Player[]|null $recipients */ public function broadcastPopup(string $popup, ?array $recipients = null) : int{ - $recipients = $recipients ?? $this->selectPermittedPlayers(self::BROADCAST_CHANNEL_USERS); + $recipients = $recipients ?? $this->getPlayerBroadcastSubscribers(self::BROADCAST_CHANNEL_USERS); foreach($recipients as $recipient){ $recipient->sendPopup($popup); @@ -1152,7 +1189,7 @@ class Server{ * @param Player[]|null $recipients */ public function broadcastTitle(string $title, string $subtitle = "", int $fadeIn = -1, int $stay = -1, int $fadeOut = -1, ?array $recipients = null) : int{ - $recipients = $recipients ?? $this->selectPermittedPlayers(self::BROADCAST_CHANNEL_USERS); + $recipients = $recipients ?? $this->getPlayerBroadcastSubscribers(self::BROADCAST_CHANNEL_USERS); foreach($recipients as $recipient){ $recipient->sendTitle($title, $subtitle, $fadeIn, $stay, $fadeOut); diff --git a/src/command/Command.php b/src/command/Command.php index 4ab99e0a54..3c52ed4d4e 100644 --- a/src/command/Command.php +++ b/src/command/Command.php @@ -234,7 +234,7 @@ abstract class Command{ * @param TranslationContainer|string $message */ public static function broadcastCommandMessage(CommandSender $source, $message, bool $sendToSource = true) : void{ - $users = PermissionManager::getInstance()->getPermissionSubscriptions(Server::BROADCAST_CHANNEL_ADMINISTRATIVE); + $users = $source->getServer()->getBroadcastChannelSubscribers(Server::BROADCAST_CHANNEL_ADMINISTRATIVE); if($message instanceof TranslationContainer){ $formatted = "[" . $source->getName() . ": " . ($source->getLanguage()->get($message->getText()) !== $message->getText() ? "%" : "") . $message->getText() . "]"; @@ -250,12 +250,10 @@ abstract class Command{ } foreach($users as $user){ - if($user instanceof CommandSender){ - if($user instanceof ConsoleCommandSender){ - $user->sendMessage($result); - }elseif($user !== $source){ - $user->sendMessage($colored); - } + if($user instanceof ConsoleCommandSender){ + $user->sendMessage($result); + }elseif($user !== $source){ + $user->sendMessage($colored); } } } diff --git a/src/event/player/PlayerChatEvent.php b/src/event/player/PlayerChatEvent.php index 33d56daeba..138410357e 100644 --- a/src/event/player/PlayerChatEvent.php +++ b/src/event/player/PlayerChatEvent.php @@ -26,11 +26,8 @@ namespace pocketmine\event\player; use pocketmine\command\CommandSender; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\permission\PermissionManager; use pocketmine\player\Player; -use pocketmine\Server; use pocketmine\utils\Utils; -use function spl_object_id; /** * Called when a player chats something @@ -50,21 +47,13 @@ class PlayerChatEvent extends PlayerEvent implements Cancellable{ /** * @param CommandSender[] $recipients */ - public function __construct(Player $player, string $message, string $format = "chat.type.text", ?array $recipients = null){ + public function __construct(Player $player, string $message, array $recipients, string $format = "chat.type.text"){ $this->player = $player; $this->message = $message; $this->format = $format; - if($recipients === null){ - foreach(PermissionManager::getInstance()->getPermissionSubscriptions(Server::BROADCAST_CHANNEL_USERS) as $permissible){ - if($permissible instanceof CommandSender){ - $this->recipients[spl_object_id($permissible)] = $permissible; - } - } - }else{ - $this->recipients = $recipients; - } + $this->recipients = $recipients; } public function getMessage() : string{ diff --git a/src/player/Player.php b/src/player/Player.php index aaca80951b..bbafa43028 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -97,7 +97,6 @@ use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\entity\PlayerMetadataFlags; use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissibleDelegateTrait; -use pocketmine\permission\PermissionManager; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\TextFormat; @@ -524,9 +523,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } public function recalculatePermissions() : void{ - $permManager = PermissionManager::getInstance(); - $permManager->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this); - $permManager->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this); + $this->server->unsubscribeFromBroadcastChannel(Server::BROADCAST_CHANNEL_USERS, $this); + $this->server->unsubscribeFromBroadcastChannel(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this); if($this->perm === null){ return; @@ -538,10 +536,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ if($this->spawned){ if($this->hasPermission(Server::BROADCAST_CHANNEL_USERS)){ - $permManager->subscribeToPermission(Server::BROADCAST_CHANNEL_USERS, $this); + $this->server->subscribeToBroadcastChannel(Server::BROADCAST_CHANNEL_USERS, $this); } if($this->hasPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE)){ - $permManager->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this); + $this->server->subscribeToBroadcastChannel(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this); } $this->networkSession->syncAvailableCommands(); @@ -781,10 +779,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } $this->spawned = true; if($this->hasPermission(Server::BROADCAST_CHANNEL_USERS)){ - PermissionManager::getInstance()->subscribeToPermission(Server::BROADCAST_CHANNEL_USERS, $this); + $this->server->subscribeToBroadcastChannel(Server::BROADCAST_CHANNEL_USERS, $this); } if($this->hasPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE)){ - PermissionManager::getInstance()->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this); + $this->server->subscribeToBroadcastChannel(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this); } $ev = new PlayerJoinEvent($this, @@ -1363,7 +1361,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->server->dispatchCommand($ev->getPlayer(), substr($ev->getMessage(), 1)); Timings::$playerCommandTimer->stopTiming(); }else{ - $ev = new PlayerChatEvent($this, $ev->getMessage()); + $ev = new PlayerChatEvent($this, $ev->getMessage(), $this->server->getBroadcastChannelSubscribers(Server::BROADCAST_CHANNEL_USERS)); $ev->call(); if(!$ev->isCancelled()){ $this->server->broadcastMessage($this->getServer()->getLanguage()->translateString($ev->getFormat(), [$ev->getPlayer()->getDisplayName(), $ev->getMessage()]), $ev->getRecipients()); @@ -1972,8 +1970,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } //prevent the player receiving their own disconnect message - PermissionManager::getInstance()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this); - PermissionManager::getInstance()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this); + $this->server->unsubscribeFromAllBroadcastChannels($this); $ev = new PlayerQuitEvent($this, $quitMessage ?? $this->getLeaveMessage(), $reason); $ev->call(); From 986742411722c8fdef9e9643e6f613144f6b18fa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 28 Nov 2020 19:35:12 +0000 Subject: [PATCH 2137/3224] [ci skip] reflect today's changes to Server in changelog --- changelogs/4.0-snapshot.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 093669d0fa..e022613d3e 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -674,6 +674,11 @@ This version features substantial changes to the network system, improving coher - `AsyncTask->saveToThreadStore()`: use `AsyncTask->worker->saveToThreadStore()` ### Server +- The following API methods have been added: + - `subscribeToBroadcastChannel()` - allows subscribing a `CommandSender` to receive chat messages (and other message types) on any channel + - `unsubscribeFromBroadcastChannel()` + - `unsubscribeFromAllBroadcastChannels()` + - `getBroadcastChannelSubscribers()` - The following API methods have been removed: - `reloadWhitelist()` - `getLevelMetadata()` @@ -691,6 +696,7 @@ This version features substantial changes to the network system, improving coher - `getGamemodeString()` - replaced by `pocketmine\player\GameMode->getTranslationKey()` - `getGamemodeName()` - replaced by `pocketmine\player\GameMode->name()` - `getGamemodeFromString()` - replaced by `GameMode::fromString()` + - `broadcast()` - use `broadcastMessage()` instead - The following API methods have changed: - `getOfflinePlayerData()` no longer creates data when it doesn't exist. - The following API methods have been renamed: From 3e9a37ca77fa5396960ef313774e4345b15f4243 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 28 Nov 2020 20:51:09 +0000 Subject: [PATCH 2138/3224] PermissionParser: remove unmaintained code --- src/permission/PermissionParser.php | 40 ----------------------------- 1 file changed, 40 deletions(-) diff --git a/src/permission/PermissionParser.php b/src/permission/PermissionParser.php index 17cee102d2..80e2c2631c 100644 --- a/src/permission/PermissionParser.php +++ b/src/permission/PermissionParser.php @@ -119,44 +119,4 @@ class PermissionParser{ return new Permission($name, $desc, $default, $children); } - - /** - * @param Permission[] $permissions - * - * @return mixed[] - * @phpstan-return array> - */ - public static function emitPermissions(array $permissions) : array{ - $result = []; - foreach($permissions as $permission){ - $result[$permission->getName()] = self::emitPermission($permission); - } - ksort($result); - return $result; - } - - /** - * @return mixed[] - * @phpstan-return array - */ - private static function emitPermission(Permission $permission) : array{ - $result = [ - "description" => $permission->getDescription(), - "default" => $permission->getDefault() - ]; - $children = []; - foreach($permission->getChildren() as $name => $bool){ - //TODO: really? wtf??? this system is so overengineered it makes my head hurt... - $child = PermissionManager::getInstance()->getPermission($name); - if($child === null){ - throw new \UnexpectedValueException("Permission child should be a registered permission"); - } - $children[$name] = self::emitPermission($child); - } - if(count($children) > 0){ - ksort($children); - $result["children"] = $children; - } - return $result; - } } From c102477f91b27da7ef1ec8f67b2fac5fb8deab37 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 28 Nov 2020 21:16:04 +0000 Subject: [PATCH 2139/3224] OfflinePlayer: remove more useless junk to obtain an OfflinePlayer instance you had to have a server instance to start with, which means getServer() is pointless, and also that isOp() and setOp() (which can be removed thanks to the fact that OfflinePlayer is not a Permissible) can be done by just asking the server. --- src/player/OfflinePlayer.php | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/player/OfflinePlayer.php b/src/player/OfflinePlayer.php index 8aa42c9988..a91ae87429 100644 --- a/src/player/OfflinePlayer.php +++ b/src/player/OfflinePlayer.php @@ -50,26 +50,6 @@ class OfflinePlayer implements IPlayer{ return $this->name; } - public function getServer() : Server{ - return $this->server; - } - - public function isOp() : bool{ - return $this->server->isOp($this->name); - } - - public function setOp(bool $value) : void{ - if($value === $this->isOp()){ - return; - } - - if($value){ - $this->server->addOp($this->name); - }else{ - $this->server->removeOp($this->name); - } - } - public function getPlayer() : ?Player{ return $this->server->getPlayerExact($this->name); } From 614891f8a275a53af16b0c7ab14e97223d879b99 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 28 Nov 2020 21:29:41 +0000 Subject: [PATCH 2140/3224] OfflinePlayer no longer depends on Server it also doesn't provide stuff like isOnline() (you had to have a Server reference to get an OfflinePlayer anyway, just ask the Server if the player is online ...) and getPlayer(). --- src/Server.php | 2 +- src/player/IPlayer.php | 2 -- src/player/OfflinePlayer.php | 18 +++--------------- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/src/Server.php b/src/Server.php index ddcb05027e..0f496ee80a 100644 --- a/src/Server.php +++ b/src/Server.php @@ -500,7 +500,7 @@ class Server{ $result = $this->getPlayerExact($name); if($result === null){ - $result = new OfflinePlayer($this, $name); + $result = new OfflinePlayer($name, $this->getOfflinePlayerData($name)); } return $result; diff --git a/src/player/IPlayer.php b/src/player/IPlayer.php index 43af6d3afd..4fa30141e4 100644 --- a/src/player/IPlayer.php +++ b/src/player/IPlayer.php @@ -25,8 +25,6 @@ namespace pocketmine\player; interface IPlayer{ - public function isOnline() : bool; - public function getName() : string; public function getFirstPlayed() : ?int; diff --git a/src/player/OfflinePlayer.php b/src/player/OfflinePlayer.php index a91ae87429..a90047b5d0 100644 --- a/src/player/OfflinePlayer.php +++ b/src/player/OfflinePlayer.php @@ -25,35 +25,23 @@ namespace pocketmine\player; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\LongTag; -use pocketmine\Server; class OfflinePlayer implements IPlayer{ /** @var string */ private $name; - /** @var Server */ - private $server; /** @var CompoundTag|null */ - private $namedtag = null; + private $namedtag; - public function __construct(Server $server, string $name){ - $this->server = $server; + public function __construct(string $name, ?CompoundTag $namedtag){ $this->name = $name; - $this->namedtag = $this->server->getOfflinePlayerData($this->name); - } - - public function isOnline() : bool{ - return $this->getPlayer() !== null; + $this->namedtag = $namedtag; } public function getName() : string{ return $this->name; } - public function getPlayer() : ?Player{ - return $this->server->getPlayerExact($this->name); - } - public function getFirstPlayed() : ?int{ return ($this->namedtag !== null and ($firstPlayedTag = $this->namedtag->getTag("firstPlayed")) instanceof LongTag) ? $firstPlayedTag->getValue() : null; } From 97a4d80854f613208e5b6d1f783e58b74db19d7f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 28 Nov 2020 21:43:23 +0000 Subject: [PATCH 2141/3224] PlayerDataSaveEvent: provide online player if possible, otherwise don't load offline data from disk for no reason (we already have it, that's the whole point of the event ...) --- src/Server.php | 2 +- src/event/player/PlayerDataSaveEvent.php | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Server.php b/src/Server.php index 0f496ee80a..ff0c055f35 100644 --- a/src/Server.php +++ b/src/Server.php @@ -553,7 +553,7 @@ class Server{ } public function saveOfflinePlayerData(string $name, CompoundTag $nbtTag) : void{ - $ev = new PlayerDataSaveEvent($nbtTag, $name); + $ev = new PlayerDataSaveEvent($nbtTag, $name, $this->getPlayerExact($name)); if(!$this->shouldSavePlayerData()){ $ev->cancel(); } diff --git a/src/event/player/PlayerDataSaveEvent.php b/src/event/player/PlayerDataSaveEvent.php index ad49aba2b7..70e7443044 100644 --- a/src/event/player/PlayerDataSaveEvent.php +++ b/src/event/player/PlayerDataSaveEvent.php @@ -27,8 +27,7 @@ use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\event\Event; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\player\IPlayer; -use pocketmine\Server; +use pocketmine\player\Player; /** * Called when a player's data is about to be saved to disk. @@ -40,10 +39,13 @@ class PlayerDataSaveEvent extends Event implements Cancellable{ protected $data; /** @var string */ protected $playerName; + /** @var Player|null */ + private $player; - public function __construct(CompoundTag $nbt, string $playerName){ + public function __construct(CompoundTag $nbt, string $playerName, ?Player $player){ $this->data = $nbt; $this->playerName = $playerName; + $this->player = $player; } /** @@ -65,10 +67,10 @@ class PlayerDataSaveEvent extends Event implements Cancellable{ } /** - * Returns the player whose data is being saved. This may be a Player or an OfflinePlayer. - * @return IPlayer (Player or OfflinePlayer) + * Returns the player whose data is being saved, if online. + * If null, this data is for an offline player (possibly just disconnected). */ - public function getPlayer() : IPlayer{ - return Server::getInstance()->getOfflinePlayer($this->playerName); + public function getPlayer() : ?Player{ + return $this->player; } } From d56cf35385f8654653e10a25a32679b70a66db54 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 28 Nov 2020 21:55:26 +0000 Subject: [PATCH 2142/3224] Permissions are now always false when permission calculation hasn't been done yet lack of permission calculation means that child permissions might not have been set correctly, so this might lead to users being able to access things they aren't supposed to. --- src/Server.php | 1 + src/permission/PermissibleBase.php | 9 +-------- src/player/Player.php | 2 ++ 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/Server.php b/src/Server.php index ff0c055f35..59cacb5f0e 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1068,6 +1068,7 @@ class Server{ //TODO: move console parts to a separate component $consoleSender = new ConsoleCommandSender($this, $this->language); + $consoleSender->recalculatePermissions(); $this->subscribeToBroadcastChannel(self::BROADCAST_CHANNEL_ADMINISTRATIVE, $consoleSender); $this->subscribeToBroadcastChannel(self::BROADCAST_CHANNEL_USERS, $consoleSender); diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index 31ac423fc9..8a83d1aba2 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -79,14 +79,7 @@ class PermissibleBase implements Permissible{ return $this->permissions[$name]->getValue(); } - if(($perm = PermissionManager::getInstance()->getPermission($name)) !== null){ - $perm = $perm->getDefault(); - - return $perm === Permission::DEFAULT_TRUE or ($this->isOp() and $perm === Permission::DEFAULT_OP) or (!$this->isOp() and $perm === Permission::DEFAULT_NOT_OP); - }else{ - return Permission::$DEFAULT_PERMISSION === Permission::DEFAULT_TRUE or ($this->isOp() and Permission::$DEFAULT_PERMISSION === Permission::DEFAULT_OP) or (!$this->isOp() and Permission::$DEFAULT_PERMISSION === Permission::DEFAULT_NOT_OP); - } - + return false; } /** diff --git a/src/player/Player.php b/src/player/Player.php index bbafa43028..74753cbc24 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -312,6 +312,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return; } + $this->perm->recalculatePermissions(); + $this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logIn", [ TextFormat::AQUA . $this->username . TextFormat::WHITE, $this->networkSession->getIp(), From 1eabc3fe75666214242ab7277b1b12a27fe4ae58 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 30 Nov 2020 21:29:51 +0000 Subject: [PATCH 2143/3224] NetworkStackLatencyPacket: added named constructors --- .../mcpe/protocol/NetworkStackLatencyPacket.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/network/mcpe/protocol/NetworkStackLatencyPacket.php b/src/network/mcpe/protocol/NetworkStackLatencyPacket.php index 559f4c5287..11211fea47 100644 --- a/src/network/mcpe/protocol/NetworkStackLatencyPacket.php +++ b/src/network/mcpe/protocol/NetworkStackLatencyPacket.php @@ -35,6 +35,20 @@ class NetworkStackLatencyPacket extends DataPacket implements ClientboundPacket, /** @var bool */ public $needResponse; + public static function request(int $timestampNs) : self{ + $result = new self; + $result->timestamp = $timestampNs; + $result->needResponse = true; + return $result; + } + + public static function response(int $timestampNs) : self{ + $result = new self; + $result->timestamp = $timestampNs; + $result->needResponse = false; + return $result; + } + protected function decodePayload(PacketSerializer $in) : void{ $this->timestamp = $in->getLLong(); $this->needResponse = $in->getBool(); From 6d8833ccd36ad3ddfc26bb78355905e5c2c64293 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Tue, 1 Dec 2020 17:13:54 +0000 Subject: [PATCH 2144/3224] Removal of permission defaults (in favour of permission cascading) (#3937) --- src/Server.php | 4 +- src/command/ConsoleCommandSender.php | 4 - src/network/mcpe/NetworkSession.php | 6 +- src/permission/DefaultPermissions.php | 157 ++++++++++---------- src/permission/Permissible.php | 20 ++- src/permission/PermissibleBase.php | 50 ++++--- src/permission/PermissibleDelegateTrait.php | 14 +- src/permission/Permission.php | 27 +--- src/permission/PermissionManager.php | 78 ---------- src/permission/PermissionParser.php | 53 ++++--- src/plugin/PluginDescription.php | 8 +- src/plugin/PluginManager.php | 30 +++- tests/phpstan/configs/l8-baseline.neon | 5 + 13 files changed, 215 insertions(+), 241 deletions(-) diff --git a/src/Server.php b/src/Server.php index 59cacb5f0e..e62d8865a8 100644 --- a/src/Server.php +++ b/src/Server.php @@ -682,7 +682,7 @@ class Server{ $this->operators->set(strtolower($name), true); if(($player = $this->getPlayerExact($name)) !== null){ - $player->onOpStatusChange(true); + $player->setBasePermission(DefaultPermissions::ROOT_OPERATOR, true); } $this->operators->save(); } @@ -691,7 +691,7 @@ class Server{ $this->operators->remove(strtolower($name)); if(($player = $this->getPlayerExact($name)) !== null){ - $player->onOpStatusChange(false); + $player->unsetBasePermission(DefaultPermissions::ROOT_OPERATOR); } $this->operators->save(); } diff --git a/src/command/ConsoleCommandSender.php b/src/command/ConsoleCommandSender.php index 49b25efa58..70c9fb409a 100644 --- a/src/command/ConsoleCommandSender.php +++ b/src/command/ConsoleCommandSender.php @@ -76,10 +76,6 @@ class ConsoleCommandSender implements CommandSender{ return "CONSOLE"; } - public function onOpStatusChange(bool $value) : void{ - - } - public function getScreenLineHeight() : int{ return $this->lineHeight ?? PHP_INT_MAX; } diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 2bd9799e7f..86d3d49a16 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -95,6 +95,7 @@ use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; use pocketmine\network\NetworkSessionManager; +use pocketmine\permission\DefaultPermissions; use pocketmine\player\GameMode; use pocketmine\player\Player; use pocketmine\player\PlayerInfo; @@ -722,8 +723,9 @@ class NetworkSession{ //TODO: permission flags - $pk->commandPermission = ($for->isOp() ? AdventureSettingsPacket::PERMISSION_OPERATOR : AdventureSettingsPacket::PERMISSION_NORMAL); - $pk->playerPermission = ($for->isOp() ? PlayerPermissions::OPERATOR : PlayerPermissions::MEMBER); + $isOp = $for->hasPermission(DefaultPermissions::ROOT_OPERATOR); + $pk->commandPermission = ($isOp ? AdventureSettingsPacket::PERMISSION_OPERATOR : AdventureSettingsPacket::PERMISSION_NORMAL); + $pk->playerPermission = ($isOp ? PlayerPermissions::OPERATOR : PlayerPermissions::MEMBER); $pk->entityUniqueId = $for->getId(); $this->sendDataPacket($pk); diff --git a/src/permission/DefaultPermissions.php b/src/permission/DefaultPermissions.php index f6de4ec07a..b9f9956929 100644 --- a/src/permission/DefaultPermissions.php +++ b/src/permission/DefaultPermissions.php @@ -26,98 +26,103 @@ namespace pocketmine\permission; abstract class DefaultPermissions{ public const ROOT = "pocketmine"; - public static function registerPermission(Permission $perm, ?Permission $parent = null) : Permission{ - if($parent instanceof Permission){ - $parent->addChild($perm->getName(), true); - } - PermissionManager::getInstance()->addPermission($perm); + public const ROOT_OPERATOR = "pocketmine.group.operator"; + public const ROOT_USER = "pocketmine.group.user"; - return PermissionManager::getInstance()->getPermission($perm->getName()); + /** + * @param Permission[] $grantedBy + * @param Permission[] $deniedBy + */ + public static function registerPermission(Permission $candidate, array $grantedBy = [], array $deniedBy = []) : Permission{ + foreach($grantedBy as $permission){ + $permission->addChild($candidate->getName(), true); + } + foreach($deniedBy as $permission){ + $permission->addChild($candidate->getName(), false); + } + PermissionManager::getInstance()->addPermission($candidate); + + return PermissionManager::getInstance()->getPermission($candidate->getName()); } public static function registerCorePermissions() : void{ $parent = self::registerPermission(new Permission(self::ROOT, "Allows using all PocketMine commands and utilities")); - $broadcasts = self::registerPermission(new Permission(self::ROOT . ".broadcast", "Allows the user to receive all broadcast messages"), $parent); - self::registerPermission(new Permission(self::ROOT . ".broadcast.admin", "Allows the user to receive administrative broadcasts", Permission::DEFAULT_OP), $broadcasts); - self::registerPermission(new Permission(self::ROOT . ".broadcast.user", "Allows the user to receive user broadcasts", Permission::DEFAULT_TRUE), $broadcasts); - $broadcasts->recalculatePermissibles(); + $operatorRoot = self::registerPermission(new Permission(self::ROOT_OPERATOR, "Grants all operator permissions"), [$parent]); + $everyoneRoot = self::registerPermission(new Permission(self::ROOT_USER, "Grants all non-sensitive permissions that everyone gets by default"), [$operatorRoot]); - $commands = self::registerPermission(new Permission(self::ROOT . ".command", "Allows using all PocketMine commands"), $parent); + $broadcastRoot = self::registerPermission(new Permission(self::ROOT . ".broadcast", "Allows the user to receive all broadcast messages"), [$parent]); - $whitelist = self::registerPermission(new Permission(self::ROOT . ".command.whitelist", "Allows the user to modify the server whitelist", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.whitelist.add", "Allows the user to add a player to the server whitelist"), $whitelist); - self::registerPermission(new Permission(self::ROOT . ".command.whitelist.remove", "Allows the user to remove a player from the server whitelist"), $whitelist); - self::registerPermission(new Permission(self::ROOT . ".command.whitelist.reload", "Allows the user to reload the server whitelist"), $whitelist); - self::registerPermission(new Permission(self::ROOT . ".command.whitelist.enable", "Allows the user to enable the server whitelist"), $whitelist); - self::registerPermission(new Permission(self::ROOT . ".command.whitelist.disable", "Allows the user to disable the server whitelist"), $whitelist); - self::registerPermission(new Permission(self::ROOT . ".command.whitelist.list", "Allows the user to list all players on the server whitelist"), $whitelist); - $whitelist->recalculatePermissibles(); + self::registerPermission(new Permission(self::ROOT . ".broadcast.admin", "Allows the user to receive administrative broadcasts"), [$operatorRoot, $broadcastRoot]); + self::registerPermission(new Permission(self::ROOT . ".broadcast.user", "Allows the user to receive user broadcasts"), [$everyoneRoot, $broadcastRoot]); - $ban = self::registerPermission(new Permission(self::ROOT . ".command.ban", "Allows the user to ban people", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.ban.player", "Allows the user to ban players"), $ban); - self::registerPermission(new Permission(self::ROOT . ".command.ban.ip", "Allows the user to ban IP addresses"), $ban); - self::registerPermission(new Permission(self::ROOT . ".command.ban.list", "Allows the user to list banned players"), $ban); - $ban->recalculatePermissibles(); + //this allows using ALL commands if assigned, irrespective of what group the player is in + $commandRoot = self::registerPermission(new Permission(self::ROOT . ".command", "Allows using all PocketMine commands"), [$parent]); + $operatorCommand = [$commandRoot, $operatorRoot]; + $everyoneCommand = [$commandRoot, $everyoneRoot]; - $unban = self::registerPermission(new Permission(self::ROOT . ".command.unban", "Allows the user to unban people", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.unban.player", "Allows the user to unban players"), $unban); - self::registerPermission(new Permission(self::ROOT . ".command.unban.ip", "Allows the user to unban IP addresses"), $unban); - $unban->recalculatePermissibles(); + $whitelist = self::registerPermission(new Permission(self::ROOT . ".command.whitelist", "Allows the user to modify the server whitelist"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.whitelist.add", "Allows the user to add a player to the server whitelist"), [$whitelist]); + self::registerPermission(new Permission(self::ROOT . ".command.whitelist.remove", "Allows the user to remove a player from the server whitelist"), [$whitelist]); + self::registerPermission(new Permission(self::ROOT . ".command.whitelist.reload", "Allows the user to reload the server whitelist"), [$whitelist]); + self::registerPermission(new Permission(self::ROOT . ".command.whitelist.enable", "Allows the user to enable the server whitelist"), [$whitelist]); + self::registerPermission(new Permission(self::ROOT . ".command.whitelist.disable", "Allows the user to disable the server whitelist"), [$whitelist]); + self::registerPermission(new Permission(self::ROOT . ".command.whitelist.list", "Allows the user to list all players on the server whitelist"), [$whitelist]); - $op = self::registerPermission(new Permission(self::ROOT . ".command.op", "Allows the user to change operators", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.op.give", "Allows the user to give a player operator status"), $op); - self::registerPermission(new Permission(self::ROOT . ".command.op.take", "Allows the user to take a player's operator status"), $op); - $op->recalculatePermissibles(); + $ban = self::registerPermission(new Permission(self::ROOT . ".command.ban", "Allows the user to ban people"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.ban.player", "Allows the user to ban players"), [$ban]); + self::registerPermission(new Permission(self::ROOT . ".command.ban.ip", "Allows the user to ban IP addresses"), [$ban]); + self::registerPermission(new Permission(self::ROOT . ".command.ban.list", "Allows the user to list banned players"), [$ban]); - $save = self::registerPermission(new Permission(self::ROOT . ".command.save", "Allows the user to save the worlds", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.save.enable", "Allows the user to enable automatic saving"), $save); - self::registerPermission(new Permission(self::ROOT . ".command.save.disable", "Allows the user to disable automatic saving"), $save); - self::registerPermission(new Permission(self::ROOT . ".command.save.perform", "Allows the user to perform a manual save"), $save); - $save->recalculatePermissibles(); + $unban = self::registerPermission(new Permission(self::ROOT . ".command.unban", "Allows the user to unban people"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.unban.player", "Allows the user to unban players"), [$unban]); + self::registerPermission(new Permission(self::ROOT . ".command.unban.ip", "Allows the user to unban IP addresses"), [$unban]); - $time = self::registerPermission(new Permission(self::ROOT . ".command.time", "Allows the user to alter the time", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.time.add", "Allows the user to fast-forward time"), $time); - self::registerPermission(new Permission(self::ROOT . ".command.time.set", "Allows the user to change the time"), $time); - self::registerPermission(new Permission(self::ROOT . ".command.time.start", "Allows the user to restart the time"), $time); - self::registerPermission(new Permission(self::ROOT . ".command.time.stop", "Allows the user to stop the time"), $time); - self::registerPermission(new Permission(self::ROOT . ".command.time.query", "Allows the user query the time"), $time); - $time->recalculatePermissibles(); + $op = self::registerPermission(new Permission(self::ROOT . ".command.op", "Allows the user to change operators"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.op.give", "Allows the user to give a player operator status"), [$op]); + self::registerPermission(new Permission(self::ROOT . ".command.op.take", "Allows the user to take a player's operator status"), [$op]); - $kill = self::registerPermission(new Permission(self::ROOT . ".command.kill", "Allows the user to kill players", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.kill.self", "Allows the user to commit suicide", Permission::DEFAULT_TRUE), $kill); - self::registerPermission(new Permission(self::ROOT . ".command.kill.other", "Allows the user to kill other players"), $kill); - $kill->recalculatePermissibles(); + $save = self::registerPermission(new Permission(self::ROOT . ".command.save", "Allows the user to save the worlds"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.save.enable", "Allows the user to enable automatic saving"), [$save]); + self::registerPermission(new Permission(self::ROOT . ".command.save.disable", "Allows the user to disable automatic saving"), [$save]); + self::registerPermission(new Permission(self::ROOT . ".command.save.perform", "Allows the user to perform a manual save"), [$save]); - self::registerPermission(new Permission(self::ROOT . ".command.me", "Allows the user to perform a chat action", Permission::DEFAULT_TRUE), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.tell", "Allows the user to privately message another player", Permission::DEFAULT_TRUE), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.say", "Allows the user to talk as the console", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.give", "Allows the user to give items to players", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.effect", "Allows the user to give/take potion effects", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.enchant", "Allows the user to enchant items", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.particle", "Allows the user to create particle effects", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.teleport", "Allows the user to teleport players", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.kick", "Allows the user to kick players", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.stop", "Allows the user to stop the server", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.list", "Allows the user to list all online players", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.help", "Allows the user to view the help menu", Permission::DEFAULT_TRUE), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.plugins", "Allows the user to view the list of plugins", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.version", "Allows the user to view the version of the server", Permission::DEFAULT_TRUE), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.gamemode", "Allows the user to change the gamemode of players", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.defaultgamemode", "Allows the user to change the default gamemode", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.seed", "Allows the user to view the seed of the world", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.status", "Allows the user to view the server performance", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.gc", "Allows the user to fire garbage collection tasks", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.dumpmemory", "Allows the user to dump memory contents", Permission::DEFAULT_FALSE), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.timings", "Allows the user to records timings for all plugin events", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.spawnpoint", "Allows the user to change player's spawnpoint", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.setworldspawn", "Allows the user to change the world spawn", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.transferserver", "Allows the user to transfer self to another server", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.title", "Allows the user to send a title to the specified player", Permission::DEFAULT_OP), $commands); - self::registerPermission(new Permission(self::ROOT . ".command.difficulty", "Allows the user to change the game difficulty", Permission::DEFAULT_OP), $commands); + $time = self::registerPermission(new Permission(self::ROOT . ".command.time", "Allows the user to alter the time"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.time.add", "Allows the user to fast-forward time"), [$time]); + self::registerPermission(new Permission(self::ROOT . ".command.time.set", "Allows the user to change the time"), [$time]); + self::registerPermission(new Permission(self::ROOT . ".command.time.start", "Allows the user to restart the time"), [$time]); + self::registerPermission(new Permission(self::ROOT . ".command.time.stop", "Allows the user to stop the time"), [$time]); + self::registerPermission(new Permission(self::ROOT . ".command.time.query", "Allows the user query the time"), [$time]); - $commands->recalculatePermissibles(); + $kill = self::registerPermission(new Permission(self::ROOT . ".command.kill", "Allows the user to kill players"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.kill.self", "Allows the user to commit suicide"), [$kill, $everyoneRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.kill.other", "Allows the user to kill other players"), [$kill]); - $parent->recalculatePermissibles(); + self::registerPermission(new Permission(self::ROOT . ".command.me", "Allows the user to perform a chat action"), $everyoneCommand); + self::registerPermission(new Permission(self::ROOT . ".command.tell", "Allows the user to privately message another player"), $everyoneCommand); + self::registerPermission(new Permission(self::ROOT . ".command.say", "Allows the user to talk as the console"), [$commandRoot, $operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.give", "Allows the user to give items to players"), [$commandRoot, $operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.effect", "Allows the user to give/take potion effects"), [$commandRoot, $operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.enchant", "Allows the user to enchant items"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.particle", "Allows the user to create particle effects"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.teleport", "Allows the user to teleport players"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.kick", "Allows the user to kick players"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.stop", "Allows the user to stop the server"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.list", "Allows the user to list all online players"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.help", "Allows the user to view the help menu"), $everyoneCommand); + self::registerPermission(new Permission(self::ROOT . ".command.plugins", "Allows the user to view the list of plugins"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.version", "Allows the user to view the version of the server"), $everyoneCommand); + self::registerPermission(new Permission(self::ROOT . ".command.gamemode", "Allows the user to change the gamemode of players"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.defaultgamemode", "Allows the user to change the default gamemode"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.seed", "Allows the user to view the seed of the world"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.status", "Allows the user to view the server performance"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.gc", "Allows the user to fire garbage collection tasks"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.dumpmemory", "Allows the user to dump memory contents"), [$commandRoot]); //TODO: this should be exclusively granted to CONSOLE + self::registerPermission(new Permission(self::ROOT . ".command.timings", "Allows the user to records timings for all plugin events"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.spawnpoint", "Allows the user to change player's spawnpoint"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.setworldspawn", "Allows the user to change the world spawn"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.transferserver", "Allows the user to transfer self to another server"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.title", "Allows the user to send a title to the specified player"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.difficulty", "Allows the user to change the game difficulty"), $operatorCommand); } } diff --git a/src/permission/Permissible.php b/src/permission/Permissible.php index 0a27590254..26ba2b1ed9 100644 --- a/src/permission/Permissible.php +++ b/src/permission/Permissible.php @@ -27,9 +27,25 @@ use pocketmine\plugin\Plugin; interface Permissible{ - public function isOp() : bool; + /** + * Assigns a baseline permission to the permissible. This is **always** calculated before anything else, which means + * that permissions set using addAttachment() will always override base permissions. + * You probably don't want to use this if you're not assigning (denying) operator permissions. + * + * @internal + * @see Permissible::addAttachment() for normal permission assignments + * @param Permission|string $name + */ + public function setBasePermission($name, bool $grant) : void; - public function onOpStatusChange(bool $value) : void; + /** + * Unsets a baseline permission previously set. If it wasn't already set, this will have no effect. + * Note that this might have different results than setting the permission to false. + * + * @internal + * @param Permission|string $name + */ + public function unsetBasePermission($name) : void; /** * Checks if this instance has a permission overridden diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index 8a83d1aba2..b7613006f5 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -29,12 +29,17 @@ use pocketmine\timings\Timings; use function spl_object_id; class PermissibleBase implements Permissible{ - /** @var bool */ - private $op; - /** @var Permissible|null */ private $parent; + /** + * @var bool[] + * @phpstan-var array + */ + private $rootPermissions = [ + DefaultPermissions::ROOT_USER => true + ]; + /** @var PermissionAttachment[] */ private $attachments = []; @@ -43,7 +48,12 @@ class PermissibleBase implements Permissible{ public function __construct(?Permissible $permissible, bool $isOp){ $this->parent = $permissible; - $this->op = $isOp; + + //TODO: we can't setBasePermission here directly due to bad architecture that causes recalculatePermissions to explode + //so, this hack has to be done here to prevent permission recalculations until it's fixed... + if($isOp){ + $this->rootPermissions[DefaultPermissions::ROOT_OPERATOR] = true; + } //TODO: permissions need to be recalculated here, or inherited permissions won't work } @@ -51,12 +61,16 @@ class PermissibleBase implements Permissible{ return $this->parent ?? $this; } - public function isOp() : bool{ - return $this->op; + public function setBasePermission($name, bool $grant) : void{ + if($name instanceof Permission){ + $name = $name->getName(); + } + $this->rootPermissions[$name] = $grant; + $this->getRootPermissible()->recalculatePermissions(); } - public function onOpStatusChange(bool $value) : void{ - $this->op = $value; + public function unsetBasePermission($name) : void{ + unset($this->rootPermissions[$name instanceof Permission ? $name->getName() : $name]); $this->getRootPermissible()->recalculatePermissions(); } @@ -117,14 +131,16 @@ class PermissibleBase implements Permissible{ public function recalculatePermissions() : void{ Timings::$permissibleCalculationTimer->startTiming(); - $this->clearPermissions(); $permManager = PermissionManager::getInstance(); - $defaults = $permManager->getDefaultPermissions($this->isOp()); - $permManager->subscribeToDefaultPerms($this->isOp(), $this->getRootPermissible()); + $permManager->unsubscribeFromAllPermissions($this->getRootPermissible()); + $this->permissions = []; - foreach($defaults as $perm){ - $name = $perm->getName(); - $this->permissions[$name] = new PermissionAttachmentInfo($this->getRootPermissible(), $name, null, true); + foreach($this->rootPermissions as $name => $isGranted){ + $perm = $permManager->getPermission($name); + if($perm === null){ + throw new \InvalidStateException("Unregistered root permission $name"); + } + $this->permissions[$name] = new PermissionAttachmentInfo($this->getRootPermissible(), $name, null, $isGranted); $permManager->subscribeToPermission($name, $this->getRootPermissible()); $this->calculateChildPermissions($perm->getChildren(), false, null); } @@ -137,11 +153,7 @@ class PermissibleBase implements Permissible{ } public function clearPermissions() : void{ - $permManager = PermissionManager::getInstance(); - $permManager->unsubscribeFromAllPermissions($this->getRootPermissible()); - - $permManager->unsubscribeFromDefaultPerms(false, $this->getRootPermissible()); - $permManager->unsubscribeFromDefaultPerms(true, $this->getRootPermissible()); + PermissionManager::getInstance()->unsubscribeFromAllPermissions($this->getRootPermissible()); $this->permissions = []; } diff --git a/src/permission/PermissibleDelegateTrait.php b/src/permission/PermissibleDelegateTrait.php index f488a6f396..9d1b57d74d 100644 --- a/src/permission/PermissibleDelegateTrait.php +++ b/src/permission/PermissibleDelegateTrait.php @@ -30,12 +30,18 @@ trait PermissibleDelegateTrait{ /** @var PermissibleBase */ private $perm; - public function isOp() : bool{ - return $this->perm->isOp(); + /** + * @param Permission|string $name + */ + public function setBasePermission($name, bool $value) : void{ + $this->perm->setBasePermission($name, $value); } - public function onOpStatusChange(bool $value) : void{ - $this->perm->onOpStatusChange($value); + /** + * @param Permission|string $name + */ + public function unsetBasePermission($name) : void{ + $this->perm->unsetBasePermission($name); } /** diff --git a/src/permission/Permission.php b/src/permission/Permission.php index 21043fdedc..df42876d3e 100644 --- a/src/permission/Permission.php +++ b/src/permission/Permission.php @@ -31,14 +31,6 @@ namespace pocketmine\permission; * Represents a permission */ class Permission{ - public const DEFAULT_OP = "op"; - public const DEFAULT_NOT_OP = "notop"; - public const DEFAULT_TRUE = "true"; - public const DEFAULT_FALSE = "false"; - - /** @var string */ - public static $DEFAULT_PERMISSION = self::DEFAULT_OP; - /** @var string */ private $name; @@ -51,19 +43,15 @@ class Permission{ */ private $children; - /** @var string */ - private $defaultValue; - /** * Creates a new Permission object to be attached to Permissible objects * * @param bool[] $children * @phpstan-param array $children */ - public function __construct(string $name, ?string $description = null, ?string $defaultValue = null, array $children = []){ + public function __construct(string $name, ?string $description = null, array $children = []){ $this->name = $name; $this->description = $description ?? ""; - $this->defaultValue = $defaultValue ?? self::$DEFAULT_PERMISSION; $this->children = $children; $this->recalculatePermissibles(); @@ -81,17 +69,6 @@ class Permission{ return $this->children; } - public function getDefault() : string{ - return $this->defaultValue; - } - - public function setDefault(string $value) : void{ - if($value !== $this->defaultValue){ - $this->defaultValue = $value; - $this->recalculatePermissibles(); - } - } - public function getDescription() : string{ return $this->description; } @@ -110,8 +87,6 @@ class Permission{ public function recalculatePermissibles() : void{ $perms = $this->getPermissibles(); - PermissionManager::getInstance()->recalculatePermissionDefaults($this); - foreach($perms as $p){ $p->recalculatePermissions(); } diff --git a/src/permission/PermissionManager.php b/src/permission/PermissionManager.php index 6781281594..a50db07e29 100644 --- a/src/permission/PermissionManager.php +++ b/src/permission/PermissionManager.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\permission; -use pocketmine\timings\Timings; use function count; use function spl_object_id; @@ -41,16 +40,8 @@ class PermissionManager{ /** @var Permission[] */ protected $permissions = []; - /** @var Permission[] */ - protected $defaultPerms = []; - /** @var Permission[] */ - protected $defaultPermsOp = []; /** @var Permissible[][] */ protected $permSubs = []; - /** @var Permissible[] */ - protected $defSubs = []; - /** @var Permissible[] */ - protected $defSubsOp = []; public function getPermission(string $name) : ?Permission{ return $this->permissions[$name] ?? null; @@ -59,7 +50,6 @@ class PermissionManager{ public function addPermission(Permission $permission) : bool{ if(!isset($this->permissions[$permission->getName()])){ $this->permissions[$permission->getName()] = $permission; - $this->calculatePermissionDefault($permission); return true; } @@ -78,45 +68,6 @@ class PermissionManager{ } } - /** - * @return Permission[] - */ - public function getDefaultPermissions(bool $op) : array{ - if($op){ - return $this->defaultPermsOp; - }else{ - return $this->defaultPerms; - } - } - - public function recalculatePermissionDefaults(Permission $permission) : void{ - if(isset($this->permissions[$permission->getName()])){ - unset($this->defaultPermsOp[$permission->getName()]); - unset($this->defaultPerms[$permission->getName()]); - $this->calculatePermissionDefault($permission); - } - } - - private function calculatePermissionDefault(Permission $permission) : void{ - Timings::$permissionDefaultTimer->startTiming(); - if($permission->getDefault() === Permission::DEFAULT_OP or $permission->getDefault() === Permission::DEFAULT_TRUE){ - $this->defaultPermsOp[$permission->getName()] = $permission; - $this->dirtyPermissibles(true); - } - - if($permission->getDefault() === Permission::DEFAULT_NOT_OP or $permission->getDefault() === Permission::DEFAULT_TRUE){ - $this->defaultPerms[$permission->getName()] = $permission; - $this->dirtyPermissibles(false); - } - Timings::$permissionDefaultTimer->stopTiming(); - } - - private function dirtyPermissibles(bool $op) : void{ - foreach($this->getDefaultPermSubscriptions($op) as $p){ - $p->recalculatePermissions(); - } - } - public function subscribeToPermission(string $permission, Permissible $permissible) : void{ if(!isset($this->permSubs[$permission])){ $this->permSubs[$permission] = []; @@ -149,33 +100,6 @@ class PermissionManager{ return $this->permSubs[$permission] ?? []; } - public function subscribeToDefaultPerms(bool $op, Permissible $permissible) : void{ - if($op){ - $this->defSubsOp[spl_object_id($permissible)] = $permissible; - }else{ - $this->defSubs[spl_object_id($permissible)] = $permissible; - } - } - - public function unsubscribeFromDefaultPerms(bool $op, Permissible $permissible) : void{ - if($op){ - unset($this->defSubsOp[spl_object_id($permissible)]); - }else{ - unset($this->defSubs[spl_object_id($permissible)]); - } - } - - /** - * @return Permissible[] - */ - public function getDefaultPermSubscriptions(bool $op) : array{ - if($op){ - return $this->defSubsOp; - } - - return $this->defSubs; - } - /** * @return Permission[] */ @@ -185,7 +109,5 @@ class PermissionManager{ public function clearPermissions() : void{ $this->permissions = []; - $this->defaultPerms = []; - $this->defaultPermsOp = []; } } diff --git a/src/permission/PermissionParser.php b/src/permission/PermissionParser.php index 80e2c2631c..b88244426c 100644 --- a/src/permission/PermissionParser.php +++ b/src/permission/PermissionParser.php @@ -23,31 +23,34 @@ declare(strict_types=1); namespace pocketmine\permission; -use function count; use function is_array; use function is_bool; -use function ksort; use function strtolower; class PermissionParser{ + public const DEFAULT_OP = "op"; + public const DEFAULT_NOT_OP = "notop"; + public const DEFAULT_TRUE = "true"; + public const DEFAULT_FALSE = "false"; + public const DEFAULT_STRING_MAP = [ - "op" => Permission::DEFAULT_OP, - "isop" => Permission::DEFAULT_OP, - "operator" => Permission::DEFAULT_OP, - "isoperator" => Permission::DEFAULT_OP, - "admin" => Permission::DEFAULT_OP, - "isadmin" => Permission::DEFAULT_OP, + "op" => self::DEFAULT_OP, + "isop" => self::DEFAULT_OP, + "operator" => self::DEFAULT_OP, + "isoperator" => self::DEFAULT_OP, + "admin" => self::DEFAULT_OP, + "isadmin" => self::DEFAULT_OP, - "!op" => Permission::DEFAULT_NOT_OP, - "notop" => Permission::DEFAULT_NOT_OP, - "!operator" => Permission::DEFAULT_NOT_OP, - "notoperator" => Permission::DEFAULT_NOT_OP, - "!admin" => Permission::DEFAULT_NOT_OP, - "notadmin" => Permission::DEFAULT_NOT_OP, + "!op" => self::DEFAULT_NOT_OP, + "notop" => self::DEFAULT_NOT_OP, + "!operator" => self::DEFAULT_NOT_OP, + "notoperator" => self::DEFAULT_NOT_OP, + "!admin" => self::DEFAULT_NOT_OP, + "notadmin" => self::DEFAULT_NOT_OP, - "true" => Permission::DEFAULT_TRUE, - "false" => Permission::DEFAULT_FALSE, + "true" => self::DEFAULT_TRUE, + "false" => self::DEFAULT_FALSE, ]; /** @@ -75,25 +78,27 @@ class PermissionParser{ * @param mixed[][] $data * @phpstan-param array> $data * - * @return Permission[] + * @return Permission[][] + * @phpstan-return array> */ - public static function loadPermissions(array $data, string $default = Permission::DEFAULT_OP) : array{ + public static function loadPermissions(array $data, string $default = self::DEFAULT_OP) : array{ $result = []; foreach($data as $key => $entry){ - $result[] = self::loadPermission($key, $entry, $default, $result); + self::loadPermission($key, $entry, $default, $result); } return $result; } /** - * @param mixed[] $data - * @param Permission[] $output reference parameter + * @param mixed[] $data + * @param Permission[][] $output reference parameter * @phpstan-param array $data + * @phpstan-param array> $output * * @throws \Exception */ - public static function loadPermission(string $name, array $data, string $default = Permission::DEFAULT_OP, array &$output = []) : Permission{ + public static function loadPermission(string $name, array $data, string $default = self::DEFAULT_OP, array &$output = []) : void{ $desc = null; $children = []; if(isset($data["default"])){ @@ -104,7 +109,7 @@ class PermissionParser{ if(is_array($data["children"])){ foreach($data["children"] as $k => $v){ if(is_array($v)){ - $output[] = self::loadPermission($k, $v, $default, $output); + self::loadPermission($k, $v, $default, $output); } $children[$k] = true; } @@ -117,6 +122,6 @@ class PermissionParser{ $desc = $data["description"]; } - return new Permission($name, $desc, $default, $children); + $output[$default][] = new Permission($name, $desc, $children); } } diff --git a/src/plugin/PluginDescription.php b/src/plugin/PluginDescription.php index ad56adaaf7..91f4c03816 100644 --- a/src/plugin/PluginDescription.php +++ b/src/plugin/PluginDescription.php @@ -83,7 +83,10 @@ class PluginDescription{ /** @var PluginEnableOrder */ private $order; - /** @var Permission[] */ + /** + * @var Permission[][] + * @phpstan-var array> + */ private $permissions = []; /** @@ -286,7 +289,8 @@ class PluginDescription{ } /** - * @return Permission[] + * @return Permission[][] + * @phpstan-return array> */ public function getPermissions() : array{ return $this->permissions; diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index d1a0325f71..c879c5dc91 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -31,7 +31,9 @@ use pocketmine\event\plugin\PluginDisableEvent; use pocketmine\event\plugin\PluginEnableEvent; use pocketmine\event\RegisteredListener; use pocketmine\network\mcpe\protocol\ProtocolInfo; +use pocketmine\permission\DefaultPermissions; use pocketmine\permission\PermissionManager; +use pocketmine\permission\PermissionParser; use pocketmine\Server; use pocketmine\timings\TimingsHandler; use pocketmine\utils\AssumptionFailedError; @@ -162,8 +164,32 @@ class PluginManager{ } $permManager = PermissionManager::getInstance(); - foreach($description->getPermissions() as $perm){ - $permManager->addPermission($perm); + $opRoot = $permManager->getPermission(DefaultPermissions::ROOT_OPERATOR); + $everyoneRoot = $permManager->getPermission(DefaultPermissions::ROOT_USER); + foreach($description->getPermissions() as $default => $perms){ + foreach($perms as $perm){ + $permManager->addPermission($perm); + switch($default){ + case PermissionParser::DEFAULT_TRUE: + $everyoneRoot->addChild($perm->getName(), true); + break; + case PermissionParser::DEFAULT_OP: + $opRoot->addChild($perm->getName(), true); + break; + case PermissionParser::DEFAULT_NOT_OP: + //TODO: I don't think anyone uses this, and it currently relies on some magic inside PermissibleBase + //to ensure that the operator override actually applies. + //Explore getting rid of this. + //The following grants this permission to anyone who has the "everyone" root permission. + //However, if the operator root node (which has higher priority) is present, the + //permission will be denied instead. + $everyoneRoot->addChild($perm->getName(), true); + $opRoot->addChild($perm->getName(), false); + break; + default: + break; + } + } } /** diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 2ed212f934..00c0c45020 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -445,6 +445,11 @@ parameters: count: 1 path: ../../../src/plugin/PluginBase.php + - + message: "#^Cannot call method addChild\\(\\) on pocketmine\\\\permission\\\\Permission\\|null\\.$#" + count: 4 + path: ../../../src/plugin/PluginManager.php + - message: "#^Parameter \\#1 \\$closure of static method pocketmine\\\\utils\\\\Utils\\:\\:getNiceClosureName\\(\\) expects Closure, Closure\\|null given\\.$#" count: 2 From f28bdb5aa27121c35648ad9f755939443c287572 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 1 Dec 2020 17:24:38 +0000 Subject: [PATCH 2145/3224] [ci skip] update changelog to reflect permission changes --- changelogs/4.0-snapshot.md | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index e022613d3e..2aceb99eaa 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -545,19 +545,47 @@ This version features substantial changes to the network system, improving coher - `upnp\UPnP` has significant changes. It's now a network component instead of a pair of static methods. ### Permission +- The following new permission nodes have been introduced: + - `pocketmine.group.everyone`: granted to everyone by default + - `pocketmine.group.operator`: granted to operator players and the console + These permission nodes can be assigned and overridden by permission attachments just like any other, which means it's now possible to grant **temporary operator** status which goes away when the player disconnects (or the attachment is removed). +- Permissions are now always false if they haven't been set explictly, or granted implicitly by another permission. +- Undefined permissions are now always `false` instead of following the value of `Permission::$DEFAULT_PERMISSION`. +- Permissions internally no longer have default values. Instead, they are now assigned as a child of one of the `pocketmine.group` permissions: + - `true`: add as child to `pocketmine.group.everyone` with value `true` + - `false`: do not add to any permission + - `op`: add as child to `pocketmine.group.operator` with value `true` + - `notop`: add as child to `pocketmine.group.everyone` with value `true`, and to `pocketmine.group.operator` with value `false` + However, the `default` key in `plugin.yml` permission definitions continues to be supported. - Added `PermissibleDelegateTrait` to reduce boilerplate for users of `PermissibleBase`. This trait is used by `ConsoleCommandSender` and `Player`. - The following API methods have been moved: - `Permission::getByName()` -> `PermissionParser::defaultFromString()` - `Permission::loadPermissions()` -> `PermissionParser::loadPermissions()` - `Permission::loadPermission()` -> `PermissionParser::loadPermission()` +- The following constants have been moved: + - `Permission::DEFAULT_FALSE` -> `PermissionParser::DEFAULT_FALSE` + - `Permission::DEFAULT_TRUE` -> `PermissionParser::DEFAULT_TRUE` + - `Permission::DEFAULT_OP` -> `PermissionParser::DEFAULT_OP` + - `Permission::DEFAULT_NOT_OP` -> `PermissionParser::DEFAULT_NOT_OP` - The following API methods have been added: - - `PermissionParser::emitPermissions()` - `Permission->addChild()` - `Permission->removeChild()` - The following API methods have been removed: + - `Permissible->isOp()`: use `Permissible->hasPermission(DefaultPermissions::ROOT_OPERATOR)` instead, **but you really shouldn't directly depend on a player's op status, add your own permissions instead!** + - `Permissible->setOp()`: use `addAttachment($plugin, DefaultPermissions::ROOT_OPERATOR, true)` instead to add, and `removeAttachment()` to remove it (or addAttachment() with false to explicitly deny it, just like any other permission) - `Permission->addParent()` + - `Permission->getDefault()` + - `Permission->setDefault()` + - `PermissionManager->getDefaultPermissions()` + - `PermissionManager->recalculatePermissionDefaults()` + - `PermissionManager->subscribeToDefaultPerms()` + - `PermissionManager->unsubscribeFromDefaultPerms()` + - `PermissionManager->getDefaultPermSubscriptions()` +- The following fields have been removed: + - `Permission::$DEFAULT_PERMISSION` - The following API methods have changes: - `PermissionParser::defaultFromString()` now throws `InvalidArgumentException` on unknown values. + - `Permission->__construct()` no longer accepts a `$defaultValue` parameter (see notes above about defaults refactor).you should add your permission as a child of `pocketmine.group.everyone` or `pocketmine.group.operator` instead). - The following classes have been removed: - `ServerOperator` From d60254794156e51bc387d1980060bdd0441aefb3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 1 Dec 2020 17:38:30 +0000 Subject: [PATCH 2146/3224] PermissionAttachmentInfo no longer references Permissible since the only way to obtain PermissionAttachmentInfo via the API is from the Permissible API, it makes zero sense to ask the attachmentinfo for its permissible, since we obviously already had it to be able to get the info in the first place. Therefore, this is just another useless reference stopping Permissibles from being garbage-collected. --- src/permission/PermissibleBase.php | 4 ++-- src/permission/PermissionAttachmentInfo.php | 10 +--------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index b7613006f5..249b12436f 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -140,7 +140,7 @@ class PermissibleBase implements Permissible{ if($perm === null){ throw new \InvalidStateException("Unregistered root permission $name"); } - $this->permissions[$name] = new PermissionAttachmentInfo($this->getRootPermissible(), $name, null, $isGranted); + $this->permissions[$name] = new PermissionAttachmentInfo($name, null, $isGranted); $permManager->subscribeToPermission($name, $this->getRootPermissible()); $this->calculateChildPermissions($perm->getChildren(), false, null); } @@ -166,7 +166,7 @@ class PermissibleBase implements Permissible{ foreach($children as $name => $v){ $perm = $permManager->getPermission($name); $value = ($v xor $invert); - $this->permissions[$name] = new PermissionAttachmentInfo($this->getRootPermissible(), $name, $attachment, $value); + $this->permissions[$name] = new PermissionAttachmentInfo($name, $attachment, $value); $permManager->subscribeToPermission($name, $this->getRootPermissible()); if($perm instanceof Permission){ diff --git a/src/permission/PermissionAttachmentInfo.php b/src/permission/PermissionAttachmentInfo.php index 0ed5e003a6..3bb4f0c5b3 100644 --- a/src/permission/PermissionAttachmentInfo.php +++ b/src/permission/PermissionAttachmentInfo.php @@ -24,9 +24,6 @@ declare(strict_types=1); namespace pocketmine\permission; class PermissionAttachmentInfo{ - /** @var Permissible */ - private $permissible; - /** @var string */ private $permission; @@ -36,17 +33,12 @@ class PermissionAttachmentInfo{ /** @var bool */ private $value; - public function __construct(Permissible $permissible, string $permission, ?PermissionAttachment $attachment, bool $value){ - $this->permissible = $permissible; + public function __construct(string $permission, ?PermissionAttachment $attachment, bool $value){ $this->permission = $permission; $this->attachment = $attachment; $this->value = $value; } - public function getPermissible() : Permissible{ - return $this->permissible; - } - public function getPermission() : string{ return $this->permission; } From 87033592b1c0727b26828d7ff4e58eeb7eedd411 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 1 Dec 2020 17:40:09 +0000 Subject: [PATCH 2147/3224] Timings: remove obsolete timings handler --- src/timings/Timings.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/timings/Timings.php b/src/timings/Timings.php index 69dd54505d..7ceca6c6b5 100644 --- a/src/timings/Timings.php +++ b/src/timings/Timings.php @@ -79,8 +79,6 @@ abstract class Timings{ public static $generationCallbackTimer; /** @var TimingsHandler */ public static $permissibleCalculationTimer; - /** @var TimingsHandler */ - public static $permissionDefaultTimer; /** @var TimingsHandler */ public static $entityMoveTimer; @@ -158,7 +156,6 @@ abstract class Timings{ self::$populationTimer = new TimingsHandler("World Population"); self::$generationCallbackTimer = new TimingsHandler("World Generation Callback"); self::$permissibleCalculationTimer = new TimingsHandler("Permissible Calculation"); - self::$permissionDefaultTimer = new TimingsHandler("Default Permission Calculation"); self::$syncPlayerDataLoad = new TimingsHandler("Player Data Load"); self::$syncPlayerDataSave = new TimingsHandler("Player Data Save"); From c20893aa4b51a5ec7c97ab27abd818df048c4aac Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 1 Dec 2020 17:57:55 +0000 Subject: [PATCH 2148/3224] PermissibleBase: more robust cycle destruction --- src/permission/PermissibleBase.php | 13 +++++++------ src/player/Player.php | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index 249b12436f..da4ebf5139 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -152,12 +152,6 @@ class PermissibleBase implements Permissible{ Timings::$permissibleCalculationTimer->stopTiming(); } - public function clearPermissions() : void{ - PermissionManager::getInstance()->unsubscribeFromAllPermissions($this->getRootPermissible()); - - $this->permissions = []; - } - /** * @param bool[] $children */ @@ -181,4 +175,11 @@ class PermissibleBase implements Permissible{ public function getEffectivePermissions() : array{ return $this->permissions; } + + public function destroyCycles() : void{ + PermissionManager::getInstance()->unsubscribeFromAllPermissions($this->getRootPermissible()); + $this->permissions = []; //PermissionAttachmentInfo doesn't reference Permissible anymore, but it references PermissionAttachment which does + $this->attachments = []; //this might still be a problem if the attachments are still referenced, but we can't do anything about that + $this->parent = null; + } } diff --git a/src/player/Player.php b/src/player/Player.php index 74753cbc24..fb1e45e335 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2008,7 +2008,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->removeCurrentWindow(); $this->removePermanentInventories(); - $this->perm->clearPermissions(); + $this->perm->destroyCycles(); $this->flagForDespawn(); } From 8fb74258f49d3c63f115ab054b63c1aece6e7195 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 1 Dec 2020 18:23:42 +0000 Subject: [PATCH 2149/3224] Implemented a better method for detecting permission recalculation this allows anyone to listen to permissions being recalculated, which is useful for stuff like broadcast channel subscriptions. --- src/network/mcpe/NetworkSession.php | 10 +++++ src/permission/Permissible.php | 7 +++ src/permission/PermissibleBase.php | 21 +++++++++ src/permission/PermissibleDelegateTrait.php | 9 ++++ src/player/Player.php | 48 +++++++-------------- tests/phpstan/configs/l8-baseline.neon | 17 +++----- 6 files changed, 68 insertions(+), 44 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 86d3d49a16..6e45c2f7ad 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -250,6 +250,16 @@ class NetworkSession{ $effectManager->getEffectAddHooks()->remove($effectAddHook); $effectManager->getEffectRemoveHooks()->remove($effectRemoveHook); }); + + $permissionHooks = $this->player->getPermissionRecalculationCallbacks(); + $permissionHooks->add($permHook = function() : void{ + $this->logger->debug("Syncing available commands and adventure settings due to permission recalculation"); + $this->syncAdventureSettings($this->player); + $this->syncAvailableCommands(); + }); + $this->disposeHooks->add(static function() use ($permissionHooks, $permHook) : void{ + $permissionHooks->remove($permHook); + }); } public function getPlayer() : ?Player{ diff --git a/src/permission/Permissible.php b/src/permission/Permissible.php index 26ba2b1ed9..db7cb7431a 100644 --- a/src/permission/Permissible.php +++ b/src/permission/Permissible.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\permission; +use Ds\Set; use pocketmine\plugin\Plugin; interface Permissible{ @@ -67,6 +68,12 @@ interface Permissible{ public function recalculatePermissions() : void; + /** + * @return Set|\Closure[] + * @phpstan-return Set<\Closure() : void> + */ + public function getPermissionRecalculationCallbacks() : Set; + /** * @return PermissionAttachmentInfo[] */ diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index da4ebf5139..c144bd8521 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\permission; +use Ds\Set; use pocketmine\plugin\Plugin; use pocketmine\plugin\PluginException; use pocketmine\timings\Timings; @@ -46,7 +47,15 @@ class PermissibleBase implements Permissible{ /** @var PermissionAttachmentInfo[] */ private $permissions = []; + /** + * @var Set|\Closure[] + * @phpstan-var Set<\Closure() : void> + */ + private $permissionRecalculationCallbacks; + public function __construct(?Permissible $permissible, bool $isOp){ + $this->permissionRecalculationCallbacks = new Set(); + $this->parent = $permissible; //TODO: we can't setBasePermission here directly due to bad architecture that causes recalculatePermissions to explode @@ -149,6 +158,11 @@ class PermissibleBase implements Permissible{ $this->calculateChildPermissions($attachment->getPermissions(), false, $attachment); } + foreach($this->permissionRecalculationCallbacks as $closure){ + //TODO: provide a diff of permissions + $closure(); + } + Timings::$permissibleCalculationTimer->stopTiming(); } @@ -169,6 +183,12 @@ class PermissibleBase implements Permissible{ } } + /** + * @return \Closure[]|Set + * @phpstan-return Set<\Closure() : void> + */ + public function getPermissionRecalculationCallbacks() : Set{ return $this->permissionRecalculationCallbacks; } + /** * @return PermissionAttachmentInfo[] */ @@ -181,5 +201,6 @@ class PermissibleBase implements Permissible{ $this->permissions = []; //PermissionAttachmentInfo doesn't reference Permissible anymore, but it references PermissionAttachment which does $this->attachments = []; //this might still be a problem if the attachments are still referenced, but we can't do anything about that $this->parent = null; + $this->permissionRecalculationCallbacks->clear(); } } diff --git a/src/permission/PermissibleDelegateTrait.php b/src/permission/PermissibleDelegateTrait.php index 9d1b57d74d..d1850f02fe 100644 --- a/src/permission/PermissibleDelegateTrait.php +++ b/src/permission/PermissibleDelegateTrait.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\permission; +use Ds\Set; use pocketmine\plugin\Plugin; trait PermissibleDelegateTrait{ @@ -70,6 +71,14 @@ trait PermissibleDelegateTrait{ $this->perm->recalculatePermissions(); } + /** + * @return Set|\Closure[] + * @phpstan-return Set<\Closure() : void> + */ + public function getPermissionRecalculationCallbacks() : Set{ + return $this->perm->getPermissionRecalculationCallbacks(); + } + /** * @return PermissionAttachmentInfo[] */ diff --git a/src/player/Player.php b/src/player/Player.php index fb1e45e335..fca4a5ae1e 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -136,9 +136,7 @@ use const PHP_INT_MAX; * Main class that handles networking, recovery, and packet sending to the server part */ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ - use PermissibleDelegateTrait { - recalculatePermissions as private delegateRecalculatePermissions; - } + use PermissibleDelegateTrait; private const MOVES_PER_TICK = 2; private const MOVE_BACKLOG_SIZE = 100 * self::MOVES_PER_TICK; //100 ticks backlog (5 seconds) @@ -524,30 +522,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return $this->isConnected(); } - public function recalculatePermissions() : void{ - $this->server->unsubscribeFromBroadcastChannel(Server::BROADCAST_CHANNEL_USERS, $this); - $this->server->unsubscribeFromBroadcastChannel(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this); - - if($this->perm === null){ - return; - } - - $this->delegateRecalculatePermissions(); - - $this->networkSession->syncAdventureSettings($this); - - if($this->spawned){ - if($this->hasPermission(Server::BROADCAST_CHANNEL_USERS)){ - $this->server->subscribeToBroadcastChannel(Server::BROADCAST_CHANNEL_USERS, $this); - } - if($this->hasPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE)){ - $this->server->subscribeToBroadcastChannel(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this); - } - - $this->networkSession->syncAvailableCommands(); - } - } - public function isConnected() : bool{ return $this->networkSession !== null and $this->networkSession->isConnected(); } @@ -771,6 +745,16 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ Timings::$playerChunkSendTimer->stopTiming(); } + private function recheckBroadcastPermissions() : void{ + foreach([Server::BROADCAST_CHANNEL_USERS, Server::BROADCAST_CHANNEL_ADMINISTRATIVE] as $channel){ + if($this->hasPermission($channel)){ + $this->server->subscribeToBroadcastChannel($channel, $this); + }else{ + $this->server->unsubscribeFromBroadcastChannel($channel, $this); + } + } + } + /** * Called by the network system when the pre-spawn sequence is completed (e.g. after sending spawn chunks). * This fires join events and broadcasts join messages to other online players. @@ -780,12 +764,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return; } $this->spawned = true; - if($this->hasPermission(Server::BROADCAST_CHANNEL_USERS)){ - $this->server->subscribeToBroadcastChannel(Server::BROADCAST_CHANNEL_USERS, $this); - } - if($this->hasPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE)){ - $this->server->subscribeToBroadcastChannel(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this); - } + $this->recheckBroadcastPermissions(); + $this->getPermissionRecalculationCallbacks()->add(function() : void{ + $this->recheckBroadcastPermissions(); + }); $ev = new PlayerJoinEvent($this, new TranslationContainer(TextFormat::YELLOW . "%multiplayer.player.joined", [ diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 00c0c45020..ef7fd7b38c 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -120,6 +120,11 @@ parameters: count: 1 path: ../../../src/network/mcpe/NetworkSession.php + - + message: "#^Parameter \\#1 \\$for of method pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:syncAdventureSettings\\(\\) expects pocketmine\\\\player\\\\Player, pocketmine\\\\player\\\\Player\\|null given\\.$#" + count: 3 + path: ../../../src/network/mcpe/NetworkSession.php + - message: "#^Parameter \\#1 \\$clientPub of class pocketmine\\\\network\\\\mcpe\\\\encryption\\\\PrepareEncryptionTask constructor expects Mdanter\\\\Ecc\\\\Crypto\\\\Key\\\\PublicKeyInterface, Mdanter\\\\Ecc\\\\Crypto\\\\Key\\\\PublicKeyInterface\\|null given\\.$#" count: 1 @@ -155,11 +160,6 @@ parameters: count: 1 path: ../../../src/network/mcpe/NetworkSession.php - - - message: "#^Parameter \\#1 \\$for of method pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:syncAdventureSettings\\(\\) expects pocketmine\\\\player\\\\Player, pocketmine\\\\player\\\\Player\\|null given\\.$#" - count: 2 - path: ../../../src/network/mcpe/NetworkSession.php - - message: "#^Cannot call method syncAll\\(\\) on pocketmine\\\\network\\\\mcpe\\\\InventoryManager\\|null\\.$#" count: 1 @@ -287,7 +287,7 @@ parameters: - message: "#^Cannot call method syncAdventureSettings\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 4 + count: 3 path: ../../../src/player/Player.php - @@ -295,11 +295,6 @@ parameters: count: 1 path: ../../../src/player/Player.php - - - message: "#^Cannot call method syncAvailableCommands\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - message: "#^Method pocketmine\\\\player\\\\Player\\:\\:getNetworkSession\\(\\) should return pocketmine\\\\network\\\\mcpe\\\\NetworkSession but returns pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" count: 1 From 341d8747b773d49b83cbd6e14935b87acd525494 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 1 Dec 2020 18:27:10 +0000 Subject: [PATCH 2150/3224] Living: wipe out effect add/remove hooks onDispose() --- src/entity/Living.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/entity/Living.php b/src/entity/Living.php index 18b86fe081..8475983ec3 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -784,6 +784,8 @@ abstract class Living extends Entity{ protected function onDispose() : void{ $this->armorInventory->removeAllViewers(); + $this->effectManager->getEffectAddHooks()->clear(); + $this->effectManager->getEffectRemoveHooks()->clear(); parent::onDispose(); } From 1905c01c87b2efea2d4c87721b885d7b9c582344 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 1 Dec 2020 18:46:39 +0000 Subject: [PATCH 2151/3224] PermissibleBase no longer circularly references its parent permissible this was used for 2 things: - to notify parent permissibles on recalculate permissions (not needed anymore thanks to callbacks) - subscription to chat broadcast permissions (now handled separately, again using callbacks) therefore, it's no longer needed for PermissibleBase to reference its parent, meaning that we can have one less circular dependency in our lives. --- src/command/ConsoleCommandSender.php | 2 +- src/permission/PermissibleBase.php | 30 ++++++++++------------------ src/player/Player.php | 2 +- 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/command/ConsoleCommandSender.php b/src/command/ConsoleCommandSender.php index 70c9fb409a..aeccc887bc 100644 --- a/src/command/ConsoleCommandSender.php +++ b/src/command/ConsoleCommandSender.php @@ -44,7 +44,7 @@ class ConsoleCommandSender implements CommandSender{ public function __construct(Server $server, Language $language){ $this->server = $server; - $this->perm = new PermissibleBase($this, true); + $this->perm = new PermissibleBase(true); $this->language = $language; } diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index c144bd8521..a459028159 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -30,9 +30,6 @@ use pocketmine\timings\Timings; use function spl_object_id; class PermissibleBase implements Permissible{ - /** @var Permissible|null */ - private $parent; - /** * @var bool[] * @phpstan-var array @@ -53,11 +50,9 @@ class PermissibleBase implements Permissible{ */ private $permissionRecalculationCallbacks; - public function __construct(?Permissible $permissible, bool $isOp){ + public function __construct(bool $isOp){ $this->permissionRecalculationCallbacks = new Set(); - $this->parent = $permissible; - //TODO: we can't setBasePermission here directly due to bad architecture that causes recalculatePermissions to explode //so, this hack has to be done here to prevent permission recalculations until it's fixed... if($isOp){ @@ -66,21 +61,17 @@ class PermissibleBase implements Permissible{ //TODO: permissions need to be recalculated here, or inherited permissions won't work } - private function getRootPermissible() : Permissible{ - return $this->parent ?? $this; - } - public function setBasePermission($name, bool $grant) : void{ if($name instanceof Permission){ $name = $name->getName(); } $this->rootPermissions[$name] = $grant; - $this->getRootPermissible()->recalculatePermissions(); + $this->recalculatePermissions(); } public function unsetBasePermission($name) : void{ unset($this->rootPermissions[$name instanceof Permission ? $name->getName() : $name]); - $this->getRootPermissible()->recalculatePermissions(); + $this->recalculatePermissions(); } /** @@ -113,13 +104,13 @@ class PermissibleBase implements Permissible{ throw new PluginException("Plugin " . $plugin->getDescription()->getName() . " is disabled"); } - $result = new PermissionAttachment($plugin, $this->getRootPermissible()); + $result = new PermissionAttachment($plugin, $this); $this->attachments[spl_object_id($result)] = $result; if($name !== null and $value !== null){ $result->setPermission($name, $value); } - $this->getRootPermissible()->recalculatePermissions(); + $this->recalculatePermissions(); return $result; } @@ -131,7 +122,7 @@ class PermissibleBase implements Permissible{ $ex->attachmentRemoved($attachment); } - $this->getRootPermissible()->recalculatePermissions(); + $this->recalculatePermissions(); } @@ -141,7 +132,7 @@ class PermissibleBase implements Permissible{ Timings::$permissibleCalculationTimer->startTiming(); $permManager = PermissionManager::getInstance(); - $permManager->unsubscribeFromAllPermissions($this->getRootPermissible()); + $permManager->unsubscribeFromAllPermissions($this); $this->permissions = []; foreach($this->rootPermissions as $name => $isGranted){ @@ -150,7 +141,7 @@ class PermissibleBase implements Permissible{ throw new \InvalidStateException("Unregistered root permission $name"); } $this->permissions[$name] = new PermissionAttachmentInfo($name, null, $isGranted); - $permManager->subscribeToPermission($name, $this->getRootPermissible()); + $permManager->subscribeToPermission($name, $this); $this->calculateChildPermissions($perm->getChildren(), false, null); } @@ -175,7 +166,7 @@ class PermissibleBase implements Permissible{ $perm = $permManager->getPermission($name); $value = ($v xor $invert); $this->permissions[$name] = new PermissionAttachmentInfo($name, $attachment, $value); - $permManager->subscribeToPermission($name, $this->getRootPermissible()); + $permManager->subscribeToPermission($name, $this); if($perm instanceof Permission){ $this->calculateChildPermissions($perm->getChildren(), !$value, $attachment); @@ -197,10 +188,9 @@ class PermissibleBase implements Permissible{ } public function destroyCycles() : void{ - PermissionManager::getInstance()->unsubscribeFromAllPermissions($this->getRootPermissible()); + PermissionManager::getInstance()->unsubscribeFromAllPermissions($this); $this->permissions = []; //PermissionAttachmentInfo doesn't reference Permissible anymore, but it references PermissionAttachment which does $this->attachments = []; //this might still be a problem if the attachments are still referenced, but we can't do anything about that - $this->parent = null; $this->permissionRecalculationCallbacks->clear(); } } diff --git a/src/player/Player.php b/src/player/Player.php index fca4a5ae1e..5219b3a637 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -278,7 +278,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->uuid = $this->playerInfo->getUuid(); $this->xuid = $this->playerInfo instanceof XboxLivePlayerInfo ? $this->playerInfo->getXuid() : ""; - $this->perm = new PermissibleBase($this, $this->server->isOp($this->username)); + $this->perm = new PermissibleBase($this->server->isOp($this->username)); $this->chunksPerTick = (int) $this->server->getConfigGroup()->getProperty("chunk-sending.per-tick", 4); $this->spawnThreshold = (int) (($this->server->getConfigGroup()->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); $this->chunkSelector = new ChunkSelector(); From cc473184acc8abdda4c9eeecafc1dfadb0602679 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 1 Dec 2020 19:40:22 +0000 Subject: [PATCH 2152/3224] Player: added API method getUsedChunks() --- src/player/Player.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/player/Player.php b/src/player/Player.php index 5219b3a637..6216622e04 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -839,6 +839,14 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return isset($this->usedChunks[World::chunkHash($chunkX, $chunkZ)]); } + /** + * @return UsedChunkStatus[] chunkHash => status + * @phpstan-return array + */ + public function getUsedChunks() : array{ + return $this->usedChunks; + } + /** * Returns whether the target chunk has been sent to this player. */ From 541cfee615e1a37c6c8f75d7e1bcb0dec04ca74a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 1 Dec 2020 22:31:55 +0000 Subject: [PATCH 2153/3224] RakLibServer: do not try to export exceptions across threads (they might contain Threaded objects whose references get invalidated) --- src/network/mcpe/raklib/RakLibInterface.php | 2 +- src/network/mcpe/raklib/RakLibServer.php | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 43547c91f7..8decc4fc02 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -125,7 +125,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ if(!$this->rakLib->isRunning()){ $e = $this->rakLib->getCrashInfo(); if($e !== null){ - throw $e; + throw new \RuntimeException("RakLib crashed: $e"); } throw new \Exception("RakLib Thread crashed without crash information"); } diff --git a/src/network/mcpe/raklib/RakLibServer.php b/src/network/mcpe/raklib/RakLibServer.php index ec335cf3cc..aefac3357a 100644 --- a/src/network/mcpe/raklib/RakLibServer.php +++ b/src/network/mcpe/raklib/RakLibServer.php @@ -69,7 +69,7 @@ class RakLibServer extends Thread{ /** @var SleeperNotifier */ protected $mainThreadNotifier; - /** @var \Throwable|null */ + /** @var string|null */ public $crashInfo = null; /** @@ -111,22 +111,22 @@ class RakLibServer extends Thread{ if($error !== null){ $this->logger->emergency("Fatal error: " . $error["message"] . " in " . $error["file"] . " on line " . $error["line"]); - $this->setCrashInfo(new \ErrorException($error['message'], 0, $error['type'], $error['file'], $error['line'])); + $this->setCrashInfo($error['message']); }else{ $this->logger->emergency("RakLib shutdown unexpectedly"); } } } - public function getCrashInfo() : ?\Throwable{ + public function getCrashInfo() : ?string{ return $this->crashInfo; } - private function setCrashInfo(\Throwable $e) : void{ - $this->synchronized(function(\Throwable $e) : void{ - $this->crashInfo = $e; + private function setCrashInfo(string $info) : void{ + $this->synchronized(function(string $info) : void{ + $this->crashInfo = $info; $this->notify(); - }, $e); + }, $info); } public function startAndWait(int $options = PTHREADS_INHERIT_NONE) : void{ @@ -136,7 +136,7 @@ class RakLibServer extends Thread{ $this->wait(); } if($this->crashInfo !== null){ - throw $this->crashInfo; + throw new \RuntimeException("RakLib failed to start: $this->crashInfo"); } }); } @@ -167,7 +167,7 @@ class RakLibServer extends Thread{ $manager->run(); $this->cleanShutdown = true; }catch(\Throwable $e){ - $this->setCrashInfo($e); + $this->setCrashInfo($e->getMessage()); $this->logger->logException($e); } } From 6d6f8c3c3854de6777a4bd7133d535aec46f6985 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 1 Dec 2020 22:32:59 +0000 Subject: [PATCH 2154/3224] custom threads: use PTHREADS_INHERIT_NONE by default this has the most reliable behaviour, because some stuff like respect/validation likes to include files unconditionally which declare functions that are already declared, which breaks due to the lack of function autoloading. --- src/thread/Thread.php | 4 ++-- src/thread/Worker.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/thread/Thread.php b/src/thread/Thread.php index caf2edd26a..22f2e09861 100644 --- a/src/thread/Thread.php +++ b/src/thread/Thread.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\thread; -use const PTHREADS_INHERIT_ALL; +use const PTHREADS_INHERIT_NONE; /** * This class must be extended by all custom threading classes @@ -31,7 +31,7 @@ use const PTHREADS_INHERIT_ALL; abstract class Thread extends \Thread{ use CommonThreadPartsTrait; - public function start(int $options = PTHREADS_INHERIT_ALL) : bool{ + public function start(int $options = PTHREADS_INHERIT_NONE) : bool{ //this is intentionally not traitified ThreadManager::getInstance()->add($this); diff --git a/src/thread/Worker.php b/src/thread/Worker.php index e3e4acdf34..fde80805cf 100644 --- a/src/thread/Worker.php +++ b/src/thread/Worker.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\thread; -use const PTHREADS_INHERIT_ALL; +use const PTHREADS_INHERIT_NONE; /** * This class must be extended by all custom threading classes @@ -31,7 +31,7 @@ use const PTHREADS_INHERIT_ALL; abstract class Worker extends \Worker{ use CommonThreadPartsTrait; - public function start(int $options = PTHREADS_INHERIT_ALL) : bool{ + public function start(int $options = PTHREADS_INHERIT_NONE) : bool{ //this is intentionally not traitified ThreadManager::getInstance()->add($this); From 10067c104333db1c246eb5ac56482844054190a1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 1 Dec 2020 23:31:38 +0000 Subject: [PATCH 2155/3224] Improve painting performance these really shouldn't hit the CPU at all considering they are simply static objects ... --- src/entity/Entity.php | 8 ++++++++ src/entity/object/Painting.php | 4 ++++ src/world/World.php | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index a9fcba9f16..2af2883f73 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -998,6 +998,14 @@ abstract class Entity{ $this->scheduleUpdate(); } + /** + * Called when a random update is performed on the chunk the entity is in. This happens when the chunk is within the + * ticking chunk range of a player (or chunk loader). + */ + public function onRandomUpdate() : void{ + $this->scheduleUpdate(); + } + /** * Flags the entity as needing a movement update on the next tick. Setting this forces a movement update even if the * entity's motion is zero. Used to trigger movement updates when blocks change near entities. diff --git a/src/entity/object/Painting.php b/src/entity/object/Painting.php index 3ccb6b1002..91d9a014d0 100644 --- a/src/entity/object/Painting.php +++ b/src/entity/object/Painting.php @@ -132,6 +132,10 @@ class Painting extends Entity{ } } + public function onRandomUpdate() : void{ + //NOOP + } + public function hasMovementUpdate() : bool{ return false; } diff --git a/src/world/World.php b/src/world/World.php index ef7bdf17de..398ccc7f76 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -968,7 +968,7 @@ class World implements ChunkManager{ $chunk = $this->chunks[$index]; foreach($chunk->getEntities() as $entity){ - $entity->scheduleUpdate(); + $entity->onRandomUpdate(); } foreach($chunk->getSubChunks() as $Y => $subChunk){ From 07dc0f2dd56c07b3c52e6bec976e12ad8b071250 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 1 Dec 2020 23:37:36 +0000 Subject: [PATCH 2156/3224] resource packs: added metadata to manifest models --- src/resourcepacks/json/Manifest.php | 3 ++ src/resourcepacks/json/ManifestMetadata.php | 33 +++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/resourcepacks/json/ManifestMetadata.php diff --git a/src/resourcepacks/json/Manifest.php b/src/resourcepacks/json/Manifest.php index dbc87bd381..2891255a4d 100644 --- a/src/resourcepacks/json/Manifest.php +++ b/src/resourcepacks/json/Manifest.php @@ -44,4 +44,7 @@ final class Manifest{ * @required */ public $modules; + + /** @var ManifestMetadata */ + public $metadata; } diff --git a/src/resourcepacks/json/ManifestMetadata.php b/src/resourcepacks/json/ManifestMetadata.php new file mode 100644 index 0000000000..5eb0c99960 --- /dev/null +++ b/src/resourcepacks/json/ManifestMetadata.php @@ -0,0 +1,33 @@ + Date: Wed, 2 Dec 2020 00:00:21 +0000 Subject: [PATCH 2157/3224] Remove useless group permission nodes the only value these have is for convenience, and a permission manager plugin can easily generate them by parsing the permission IDs. --- src/permission/DefaultPermissions.php | 120 +++++++++++--------------- 1 file changed, 52 insertions(+), 68 deletions(-) diff --git a/src/permission/DefaultPermissions.php b/src/permission/DefaultPermissions.php index b9f9956929..cd95a3e998 100644 --- a/src/permission/DefaultPermissions.php +++ b/src/permission/DefaultPermissions.php @@ -46,83 +46,67 @@ abstract class DefaultPermissions{ } public static function registerCorePermissions() : void{ - $parent = self::registerPermission(new Permission(self::ROOT, "Allows using all PocketMine commands and utilities")); - - $operatorRoot = self::registerPermission(new Permission(self::ROOT_OPERATOR, "Grants all operator permissions"), [$parent]); + $operatorRoot = self::registerPermission(new Permission(self::ROOT_OPERATOR, "Grants all operator permissions")); $everyoneRoot = self::registerPermission(new Permission(self::ROOT_USER, "Grants all non-sensitive permissions that everyone gets by default"), [$operatorRoot]); - $broadcastRoot = self::registerPermission(new Permission(self::ROOT . ".broadcast", "Allows the user to receive all broadcast messages"), [$parent]); + self::registerPermission(new Permission(self::ROOT . ".broadcast.admin", "Allows the user to receive administrative broadcasts"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".broadcast.user", "Allows the user to receive user broadcasts"), [$everyoneRoot]); - self::registerPermission(new Permission(self::ROOT . ".broadcast.admin", "Allows the user to receive administrative broadcasts"), [$operatorRoot, $broadcastRoot]); - self::registerPermission(new Permission(self::ROOT . ".broadcast.user", "Allows the user to receive user broadcasts"), [$everyoneRoot, $broadcastRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.whitelist.add", "Allows the user to add a player to the server whitelist"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.whitelist.remove", "Allows the user to remove a player from the server whitelist"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.whitelist.reload", "Allows the user to reload the server whitelist"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.whitelist.enable", "Allows the user to enable the server whitelist"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.whitelist.disable", "Allows the user to disable the server whitelist"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.whitelist.list", "Allows the user to list all players on the server whitelist"), [$operatorRoot]); - //this allows using ALL commands if assigned, irrespective of what group the player is in - $commandRoot = self::registerPermission(new Permission(self::ROOT . ".command", "Allows using all PocketMine commands"), [$parent]); - $operatorCommand = [$commandRoot, $operatorRoot]; - $everyoneCommand = [$commandRoot, $everyoneRoot]; + self::registerPermission(new Permission(self::ROOT . ".command.ban.player", "Allows the user to ban players"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.ban.ip", "Allows the user to ban IP addresses"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.ban.list", "Allows the user to list banned players"), [$operatorRoot]); - $whitelist = self::registerPermission(new Permission(self::ROOT . ".command.whitelist", "Allows the user to modify the server whitelist"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.whitelist.add", "Allows the user to add a player to the server whitelist"), [$whitelist]); - self::registerPermission(new Permission(self::ROOT . ".command.whitelist.remove", "Allows the user to remove a player from the server whitelist"), [$whitelist]); - self::registerPermission(new Permission(self::ROOT . ".command.whitelist.reload", "Allows the user to reload the server whitelist"), [$whitelist]); - self::registerPermission(new Permission(self::ROOT . ".command.whitelist.enable", "Allows the user to enable the server whitelist"), [$whitelist]); - self::registerPermission(new Permission(self::ROOT . ".command.whitelist.disable", "Allows the user to disable the server whitelist"), [$whitelist]); - self::registerPermission(new Permission(self::ROOT . ".command.whitelist.list", "Allows the user to list all players on the server whitelist"), [$whitelist]); + self::registerPermission(new Permission(self::ROOT . ".command.unban.player", "Allows the user to unban players"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.unban.ip", "Allows the user to unban IP addresses"), [$operatorRoot]); - $ban = self::registerPermission(new Permission(self::ROOT . ".command.ban", "Allows the user to ban people"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.ban.player", "Allows the user to ban players"), [$ban]); - self::registerPermission(new Permission(self::ROOT . ".command.ban.ip", "Allows the user to ban IP addresses"), [$ban]); - self::registerPermission(new Permission(self::ROOT . ".command.ban.list", "Allows the user to list banned players"), [$ban]); + self::registerPermission(new Permission(self::ROOT . ".command.op.give", "Allows the user to give a player operator status"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.op.take", "Allows the user to take a player's operator status"), [$operatorRoot]); - $unban = self::registerPermission(new Permission(self::ROOT . ".command.unban", "Allows the user to unban people"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.unban.player", "Allows the user to unban players"), [$unban]); - self::registerPermission(new Permission(self::ROOT . ".command.unban.ip", "Allows the user to unban IP addresses"), [$unban]); + self::registerPermission(new Permission(self::ROOT . ".command.save.enable", "Allows the user to enable automatic saving"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.save.disable", "Allows the user to disable automatic saving"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.save.perform", "Allows the user to perform a manual save"), [$operatorRoot]); - $op = self::registerPermission(new Permission(self::ROOT . ".command.op", "Allows the user to change operators"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.op.give", "Allows the user to give a player operator status"), [$op]); - self::registerPermission(new Permission(self::ROOT . ".command.op.take", "Allows the user to take a player's operator status"), [$op]); + self::registerPermission(new Permission(self::ROOT . ".command.time.add", "Allows the user to fast-forward time"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.time.set", "Allows the user to change the time"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.time.start", "Allows the user to restart the time"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.time.stop", "Allows the user to stop the time"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.time.query", "Allows the user query the time"), [$operatorRoot]); - $save = self::registerPermission(new Permission(self::ROOT . ".command.save", "Allows the user to save the worlds"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.save.enable", "Allows the user to enable automatic saving"), [$save]); - self::registerPermission(new Permission(self::ROOT . ".command.save.disable", "Allows the user to disable automatic saving"), [$save]); - self::registerPermission(new Permission(self::ROOT . ".command.save.perform", "Allows the user to perform a manual save"), [$save]); + self::registerPermission(new Permission(self::ROOT . ".command.kill.self", "Allows the user to commit suicide"), [$everyoneRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.kill.other", "Allows the user to kill other players"), [$operatorRoot]); - $time = self::registerPermission(new Permission(self::ROOT . ".command.time", "Allows the user to alter the time"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.time.add", "Allows the user to fast-forward time"), [$time]); - self::registerPermission(new Permission(self::ROOT . ".command.time.set", "Allows the user to change the time"), [$time]); - self::registerPermission(new Permission(self::ROOT . ".command.time.start", "Allows the user to restart the time"), [$time]); - self::registerPermission(new Permission(self::ROOT . ".command.time.stop", "Allows the user to stop the time"), [$time]); - self::registerPermission(new Permission(self::ROOT . ".command.time.query", "Allows the user query the time"), [$time]); - - $kill = self::registerPermission(new Permission(self::ROOT . ".command.kill", "Allows the user to kill players"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.kill.self", "Allows the user to commit suicide"), [$kill, $everyoneRoot]); - self::registerPermission(new Permission(self::ROOT . ".command.kill.other", "Allows the user to kill other players"), [$kill]); - - self::registerPermission(new Permission(self::ROOT . ".command.me", "Allows the user to perform a chat action"), $everyoneCommand); - self::registerPermission(new Permission(self::ROOT . ".command.tell", "Allows the user to privately message another player"), $everyoneCommand); - self::registerPermission(new Permission(self::ROOT . ".command.say", "Allows the user to talk as the console"), [$commandRoot, $operatorRoot]); - self::registerPermission(new Permission(self::ROOT . ".command.give", "Allows the user to give items to players"), [$commandRoot, $operatorRoot]); - self::registerPermission(new Permission(self::ROOT . ".command.effect", "Allows the user to give/take potion effects"), [$commandRoot, $operatorRoot]); - self::registerPermission(new Permission(self::ROOT . ".command.enchant", "Allows the user to enchant items"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.particle", "Allows the user to create particle effects"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.teleport", "Allows the user to teleport players"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.kick", "Allows the user to kick players"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.stop", "Allows the user to stop the server"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.list", "Allows the user to list all online players"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.help", "Allows the user to view the help menu"), $everyoneCommand); - self::registerPermission(new Permission(self::ROOT . ".command.plugins", "Allows the user to view the list of plugins"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.version", "Allows the user to view the version of the server"), $everyoneCommand); - self::registerPermission(new Permission(self::ROOT . ".command.gamemode", "Allows the user to change the gamemode of players"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.defaultgamemode", "Allows the user to change the default gamemode"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.seed", "Allows the user to view the seed of the world"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.status", "Allows the user to view the server performance"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.gc", "Allows the user to fire garbage collection tasks"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.dumpmemory", "Allows the user to dump memory contents"), [$commandRoot]); //TODO: this should be exclusively granted to CONSOLE - self::registerPermission(new Permission(self::ROOT . ".command.timings", "Allows the user to records timings for all plugin events"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.spawnpoint", "Allows the user to change player's spawnpoint"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.setworldspawn", "Allows the user to change the world spawn"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.transferserver", "Allows the user to transfer self to another server"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.title", "Allows the user to send a title to the specified player"), $operatorCommand); - self::registerPermission(new Permission(self::ROOT . ".command.difficulty", "Allows the user to change the game difficulty"), $operatorCommand); + self::registerPermission(new Permission(self::ROOT . ".command.me", "Allows the user to perform a chat action"), [$everyoneRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.tell", "Allows the user to privately message another player"), [$everyoneRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.say", "Allows the user to talk as the console"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.give", "Allows the user to give items to players"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.effect", "Allows the user to give/take potion effects"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.enchant", "Allows the user to enchant items"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.particle", "Allows the user to create particle effects"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.teleport", "Allows the user to teleport players"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.kick", "Allows the user to kick players"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.stop", "Allows the user to stop the server"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.list", "Allows the user to list all online players"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.help", "Allows the user to view the help menu"), [$everyoneRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.plugins", "Allows the user to view the list of plugins"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.version", "Allows the user to view the version of the server"), [$everyoneRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.gamemode", "Allows the user to change the gamemode of players"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.defaultgamemode", "Allows the user to change the default gamemode"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.seed", "Allows the user to view the seed of the world"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.status", "Allows the user to view the server performance"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.gc", "Allows the user to fire garbage collection tasks"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.dumpmemory", "Allows the user to dump memory contents"), []); //TODO: this should be exclusively granted to CONSOLE + self::registerPermission(new Permission(self::ROOT . ".command.timings", "Allows the user to records timings for all plugin events"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.spawnpoint", "Allows the user to change player's spawnpoint"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.setworldspawn", "Allows the user to change the world spawn"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.transferserver", "Allows the user to transfer self to another server"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.title", "Allows the user to send a title to the specified player"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.difficulty", "Allows the user to change the game difficulty"), [$operatorRoot]); } } From 0634426c26c6ff0f9366f6f16438a98af17a391e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 2 Dec 2020 01:09:29 +0000 Subject: [PATCH 2158/3224] PermissibleBase: compute permission diff, do not fire callbacks when diff is empty this fixes AvailableCommandsPacket getting sent twice when adding a PermissionAttachment. --- src/permission/Permissible.php | 2 +- src/permission/PermissibleBase.php | 36 +++++++++++++++++---- src/permission/PermissibleDelegateTrait.php | 2 +- src/player/Player.php | 6 ++-- src/timings/Timings.php | 6 ++++ 5 files changed, 42 insertions(+), 10 deletions(-) diff --git a/src/permission/Permissible.php b/src/permission/Permissible.php index db7cb7431a..926ecb0266 100644 --- a/src/permission/Permissible.php +++ b/src/permission/Permissible.php @@ -70,7 +70,7 @@ interface Permissible{ /** * @return Set|\Closure[] - * @phpstan-return Set<\Closure() : void> + * @phpstan-return Set<\Closure(array $changedPermissionsOldValues) : void> */ public function getPermissionRecalculationCallbacks() : Set; diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index a459028159..646d8db110 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -27,6 +27,7 @@ use Ds\Set; use pocketmine\plugin\Plugin; use pocketmine\plugin\PluginException; use pocketmine\timings\Timings; +use function count; use function spl_object_id; class PermissibleBase implements Permissible{ @@ -46,7 +47,7 @@ class PermissibleBase implements Permissible{ /** * @var Set|\Closure[] - * @phpstan-var Set<\Closure() : void> + * @phpstan-var Set<\Closure(array $changedPermissionsOldValues) : void> */ private $permissionRecalculationCallbacks; @@ -133,6 +134,7 @@ class PermissibleBase implements Permissible{ $permManager = PermissionManager::getInstance(); $permManager->unsubscribeFromAllPermissions($this); + $oldPermissions = $this->permissions; $this->permissions = []; foreach($this->rootPermissions as $name => $isGranted){ @@ -149,10 +151,32 @@ class PermissibleBase implements Permissible{ $this->calculateChildPermissions($attachment->getPermissions(), false, $attachment); } - foreach($this->permissionRecalculationCallbacks as $closure){ - //TODO: provide a diff of permissions - $closure(); - } + $diff = []; + Timings::$permissibleCalculationDiffTimer->time(function() use ($oldPermissions, &$diff) : void{ + foreach($this->permissions as $permissionAttachmentInfo){ + $name = $permissionAttachmentInfo->getPermission(); + if(!isset($oldPermissions[$name])){ + $diff[$name] = false; + }elseif($oldPermissions[$name]->getValue() !== $permissionAttachmentInfo->getValue()){ + //permission was previously unset OR the value of the permission changed + //we don't care who assigned the permission, only that the result is different + $diff[$name] = $oldPermissions[$name]->getValue(); + } + unset($oldPermissions[$name]); + } + //oldPermissions now only contains permissions that are no longer set after recalculation + foreach($oldPermissions as $permissionAttachmentInfo){ + $diff[$permissionAttachmentInfo->getPermission()] = $permissionAttachmentInfo->getValue(); + } + }); + + Timings::$permissibleCalculationCallbackTimer->time(function() use ($diff) : void{ + if(count($diff) > 0){ + foreach($this->permissionRecalculationCallbacks as $closure){ + $closure($diff); + } + } + }); Timings::$permissibleCalculationTimer->stopTiming(); } @@ -176,7 +200,7 @@ class PermissibleBase implements Permissible{ /** * @return \Closure[]|Set - * @phpstan-return Set<\Closure() : void> + * @phpstan-return Set<\Closure(array $changedPermissionsOldValues) : void> */ public function getPermissionRecalculationCallbacks() : Set{ return $this->permissionRecalculationCallbacks; } diff --git a/src/permission/PermissibleDelegateTrait.php b/src/permission/PermissibleDelegateTrait.php index d1850f02fe..2988ad160f 100644 --- a/src/permission/PermissibleDelegateTrait.php +++ b/src/permission/PermissibleDelegateTrait.php @@ -73,7 +73,7 @@ trait PermissibleDelegateTrait{ /** * @return Set|\Closure[] - * @phpstan-return Set<\Closure() : void> + * @phpstan-return Set<\Closure(array $changedPermissionsOldValues) : void> */ public function getPermissionRecalculationCallbacks() : Set{ return $this->perm->getPermissionRecalculationCallbacks(); diff --git a/src/player/Player.php b/src/player/Player.php index 6216622e04..11283cab2d 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -765,8 +765,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } $this->spawned = true; $this->recheckBroadcastPermissions(); - $this->getPermissionRecalculationCallbacks()->add(function() : void{ - $this->recheckBroadcastPermissions(); + $this->getPermissionRecalculationCallbacks()->add(function(array $changedPermissionsOldValues) : void{ + if(isset($changedPermissionsOldValues[Server::BROADCAST_CHANNEL_ADMINISTRATIVE]) || isset($changedPermissionsOldValues[Server::BROADCAST_CHANNEL_USERS])){ + $this->recheckBroadcastPermissions(); + } }); $ev = new PlayerJoinEvent($this, diff --git a/src/timings/Timings.php b/src/timings/Timings.php index 7ceca6c6b5..586a0c1a6c 100644 --- a/src/timings/Timings.php +++ b/src/timings/Timings.php @@ -79,6 +79,10 @@ abstract class Timings{ public static $generationCallbackTimer; /** @var TimingsHandler */ public static $permissibleCalculationTimer; + /** @var TimingsHandler */ + public static $permissibleCalculationDiffTimer; + /** @var TimingsHandler */ + public static $permissibleCalculationCallbackTimer; /** @var TimingsHandler */ public static $entityMoveTimer; @@ -156,6 +160,8 @@ abstract class Timings{ self::$populationTimer = new TimingsHandler("World Population"); self::$generationCallbackTimer = new TimingsHandler("World Generation Callback"); self::$permissibleCalculationTimer = new TimingsHandler("Permissible Calculation"); + self::$permissibleCalculationDiffTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Permissible Calculation - Diff", self::$permissibleCalculationTimer); + self::$permissibleCalculationCallbackTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Permissible Calculation - Callbacks", self::$permissibleCalculationTimer); self::$syncPlayerDataLoad = new TimingsHandler("Player Data Load"); self::$syncPlayerDataSave = new TimingsHandler("Player Data Save"); From f5bb5c120822fd97adaaf24405c08e477133f065 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 2 Dec 2020 01:13:19 +0000 Subject: [PATCH 2159/3224] Permissible->recalculatePermissions() now returns a map of changed permissions with their old values --- src/permission/Permissible.php | 6 +++++- src/permission/PermissibleBase.php | 3 ++- src/permission/PermissibleDelegateTrait.php | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/permission/Permissible.php b/src/permission/Permissible.php index 926ecb0266..5fca2b14f7 100644 --- a/src/permission/Permissible.php +++ b/src/permission/Permissible.php @@ -66,7 +66,11 @@ interface Permissible{ public function removeAttachment(PermissionAttachment $attachment) : void; - public function recalculatePermissions() : void; + /** + * @return bool[] changed permission name => old value + * @phpstan-return array + */ + public function recalculatePermissions() : array; /** * @return Set|\Closure[] diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index 646d8db110..b65fcf78c4 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -129,7 +129,7 @@ class PermissibleBase implements Permissible{ } - public function recalculatePermissions() : void{ + public function recalculatePermissions() : array{ Timings::$permissibleCalculationTimer->startTiming(); $permManager = PermissionManager::getInstance(); @@ -179,6 +179,7 @@ class PermissibleBase implements Permissible{ }); Timings::$permissibleCalculationTimer->stopTiming(); + return $diff; } /** diff --git a/src/permission/PermissibleDelegateTrait.php b/src/permission/PermissibleDelegateTrait.php index 2988ad160f..e38762efe6 100644 --- a/src/permission/PermissibleDelegateTrait.php +++ b/src/permission/PermissibleDelegateTrait.php @@ -67,8 +67,8 @@ trait PermissibleDelegateTrait{ $this->perm->removeAttachment($attachment); } - public function recalculatePermissions() : void{ - $this->perm->recalculatePermissions(); + public function recalculatePermissions() : array{ + return $this->perm->recalculatePermissions(); } /** From 13e8854ec0a1c0381f0b5d8b58ccea13073658f0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 2 Dec 2020 01:39:43 +0000 Subject: [PATCH 2160/3224] PermissibleBase: fixed express denying of a root permission not working this only took effect when a permission was applied as a root. When overridden with a permission attachment, the problem did not manifest. --- src/permission/PermissibleBase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index b65fcf78c4..1907e469df 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -144,7 +144,7 @@ class PermissibleBase implements Permissible{ } $this->permissions[$name] = new PermissionAttachmentInfo($name, null, $isGranted); $permManager->subscribeToPermission($name, $this); - $this->calculateChildPermissions($perm->getChildren(), false, null); + $this->calculateChildPermissions($perm->getChildren(), !$isGranted, null); } foreach($this->attachments as $attachment){ From 880635603c5091bf4139d034119b03c8ad48aff1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 2 Dec 2020 10:12:40 +0000 Subject: [PATCH 2161/3224] PermissibleBase: allow injecting more dynamic base permissions --- src/command/ConsoleCommandSender.php | 3 ++- src/permission/PermissibleBase.php | 10 +++++++--- src/player/Player.php | 3 ++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/command/ConsoleCommandSender.php b/src/command/ConsoleCommandSender.php index aeccc887bc..ebe05d45cd 100644 --- a/src/command/ConsoleCommandSender.php +++ b/src/command/ConsoleCommandSender.php @@ -25,6 +25,7 @@ namespace pocketmine\command; use pocketmine\lang\Language; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissions; use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissibleDelegateTrait; use pocketmine\Server; @@ -44,7 +45,7 @@ class ConsoleCommandSender implements CommandSender{ public function __construct(Server $server, Language $language){ $this->server = $server; - $this->perm = new PermissibleBase(true); + $this->perm = new PermissibleBase([DefaultPermissions::ROOT_OPERATOR => true]); $this->language = $language; } diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index 1907e469df..cfab34bc3a 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -51,13 +51,17 @@ class PermissibleBase implements Permissible{ */ private $permissionRecalculationCallbacks; - public function __construct(bool $isOp){ + /** + * @param bool[] $basePermissions + * @phpstan-param array $basePermissions + */ + public function __construct(array $basePermissions){ $this->permissionRecalculationCallbacks = new Set(); //TODO: we can't setBasePermission here directly due to bad architecture that causes recalculatePermissions to explode //so, this hack has to be done here to prevent permission recalculations until it's fixed... - if($isOp){ - $this->rootPermissions[DefaultPermissions::ROOT_OPERATOR] = true; + foreach($basePermissions as $permission => $isGranted){ + $this->rootPermissions[$permission] = $isGranted; } //TODO: permissions need to be recalculated here, or inherited permissions won't work } diff --git a/src/player/Player.php b/src/player/Player.php index 11283cab2d..007a74d2c0 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -95,6 +95,7 @@ use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\entity\PlayerMetadataFlags; +use pocketmine\permission\DefaultPermissions; use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissibleDelegateTrait; use pocketmine\Server; @@ -278,7 +279,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->uuid = $this->playerInfo->getUuid(); $this->xuid = $this->playerInfo instanceof XboxLivePlayerInfo ? $this->playerInfo->getXuid() : ""; - $this->perm = new PermissibleBase($this->server->isOp($this->username)); + $this->perm = new PermissibleBase($this->server->isOp($this->username) ? [DefaultPermissions::ROOT_OPERATOR => true] : [DefaultPermissions::ROOT_USER => true]); $this->chunksPerTick = (int) $this->server->getConfigGroup()->getProperty("chunk-sending.per-tick", 4); $this->spawnThreshold = (int) (($this->server->getConfigGroup()->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); $this->chunkSelector = new ChunkSelector(); From 506e76917e0f7aed2528aaf3795d15710d14e6f6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 2 Dec 2020 11:23:35 +0000 Subject: [PATCH 2162/3224] PermissionAttachmentInfo now includes a reference to the PermissionAttachmentInfo that caused its assignment (if any) this allows plugins to easily identify which permission group caused a permission to be assigned (particularly if multiple groups might cause it). --- src/permission/PermissibleBase.php | 12 ++++++------ src/permission/PermissionAttachmentInfo.php | 12 +++++++++++- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index cfab34bc3a..2856ed75fb 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -146,13 +146,13 @@ class PermissibleBase implements Permissible{ if($perm === null){ throw new \InvalidStateException("Unregistered root permission $name"); } - $this->permissions[$name] = new PermissionAttachmentInfo($name, null, $isGranted); + $this->permissions[$name] = new PermissionAttachmentInfo($name, null, $isGranted, null); $permManager->subscribeToPermission($name, $this); - $this->calculateChildPermissions($perm->getChildren(), !$isGranted, null); + $this->calculateChildPermissions($perm->getChildren(), !$isGranted, null, $this->permissions[$name]); } foreach($this->attachments as $attachment){ - $this->calculateChildPermissions($attachment->getPermissions(), false, $attachment); + $this->calculateChildPermissions($attachment->getPermissions(), false, $attachment, null); } $diff = []; @@ -189,16 +189,16 @@ class PermissibleBase implements Permissible{ /** * @param bool[] $children */ - private function calculateChildPermissions(array $children, bool $invert, ?PermissionAttachment $attachment) : void{ + private function calculateChildPermissions(array $children, bool $invert, ?PermissionAttachment $attachment, ?PermissionAttachmentInfo $parent) : void{ $permManager = PermissionManager::getInstance(); foreach($children as $name => $v){ $perm = $permManager->getPermission($name); $value = ($v xor $invert); - $this->permissions[$name] = new PermissionAttachmentInfo($name, $attachment, $value); + $this->permissions[$name] = new PermissionAttachmentInfo($name, $attachment, $value, $parent); $permManager->subscribeToPermission($name, $this); if($perm instanceof Permission){ - $this->calculateChildPermissions($perm->getChildren(), !$value, $attachment); + $this->calculateChildPermissions($perm->getChildren(), !$value, $attachment, $this->permissions[$name]); } } } diff --git a/src/permission/PermissionAttachmentInfo.php b/src/permission/PermissionAttachmentInfo.php index 3bb4f0c5b3..b786d567e6 100644 --- a/src/permission/PermissionAttachmentInfo.php +++ b/src/permission/PermissionAttachmentInfo.php @@ -33,10 +33,14 @@ class PermissionAttachmentInfo{ /** @var bool */ private $value; - public function __construct(string $permission, ?PermissionAttachment $attachment, bool $value){ + /** @var PermissionAttachmentInfo|null */ + private $groupPermission; + + public function __construct(string $permission, ?PermissionAttachment $attachment, bool $value, ?PermissionAttachmentInfo $groupPermission){ $this->permission = $permission; $this->attachment = $attachment; $this->value = $value; + $this->groupPermission = $groupPermission; } public function getPermission() : string{ @@ -50,4 +54,10 @@ class PermissionAttachmentInfo{ public function getValue() : bool{ return $this->value; } + + /** + * Returns the info of the permission group that caused this permission to be set, if any. + * If null, the permission was set explicitly, either by a permission attachment or base permission. + */ + public function getGroupPermissionInfo() : ?PermissionAttachmentInfo{ return $this->groupPermission; } } From c5e12bb11f6b810e1059e580fda9fb726cda6284 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 2 Dec 2020 11:29:45 +0000 Subject: [PATCH 2163/3224] PermissibleBase: simplify diff calculation --- src/permission/PermissibleBase.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index 2856ed75fb..041057e8a5 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -162,13 +162,11 @@ class PermissibleBase implements Permissible{ if(!isset($oldPermissions[$name])){ $diff[$name] = false; }elseif($oldPermissions[$name]->getValue() !== $permissionAttachmentInfo->getValue()){ - //permission was previously unset OR the value of the permission changed - //we don't care who assigned the permission, only that the result is different - $diff[$name] = $oldPermissions[$name]->getValue(); + continue; } unset($oldPermissions[$name]); } - //oldPermissions now only contains permissions that are no longer set after recalculation + //oldPermissions now only contains permissions that changed or are no longer set foreach($oldPermissions as $permissionAttachmentInfo){ $diff[$permissionAttachmentInfo->getPermission()] = $permissionAttachmentInfo->getValue(); } From b51c6e89b34e38f62866b641edc61ccf9e7e4b84 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 2 Dec 2020 13:35:48 +0000 Subject: [PATCH 2164/3224] Introduced pocketmine.group.console this is only used for /dumpmemory right now, but it's planned to be used for more stuff. --- src/command/ConsoleCommandSender.php | 2 +- src/permission/DefaultPermissions.php | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/command/ConsoleCommandSender.php b/src/command/ConsoleCommandSender.php index ebe05d45cd..5649f9f4c9 100644 --- a/src/command/ConsoleCommandSender.php +++ b/src/command/ConsoleCommandSender.php @@ -45,7 +45,7 @@ class ConsoleCommandSender implements CommandSender{ public function __construct(Server $server, Language $language){ $this->server = $server; - $this->perm = new PermissibleBase([DefaultPermissions::ROOT_OPERATOR => true]); + $this->perm = new PermissibleBase([DefaultPermissions::ROOT_CONSOLE => true]); $this->language = $language; } diff --git a/src/permission/DefaultPermissions.php b/src/permission/DefaultPermissions.php index cd95a3e998..1d8a5ebcb1 100644 --- a/src/permission/DefaultPermissions.php +++ b/src/permission/DefaultPermissions.php @@ -26,6 +26,7 @@ namespace pocketmine\permission; abstract class DefaultPermissions{ public const ROOT = "pocketmine"; + public const ROOT_CONSOLE = "pocketmine.group.console"; public const ROOT_OPERATOR = "pocketmine.group.operator"; public const ROOT_USER = "pocketmine.group.user"; @@ -46,7 +47,8 @@ abstract class DefaultPermissions{ } public static function registerCorePermissions() : void{ - $operatorRoot = self::registerPermission(new Permission(self::ROOT_OPERATOR, "Grants all operator permissions")); + $consoleRoot = self::registerPermission(new Permission(self::ROOT_CONSOLE, "Grants all console permissions")); + $operatorRoot = self::registerPermission(new Permission(self::ROOT_OPERATOR, "Grants all operator permissions"), [$consoleRoot]); $everyoneRoot = self::registerPermission(new Permission(self::ROOT_USER, "Grants all non-sensitive permissions that everyone gets by default"), [$operatorRoot]); self::registerPermission(new Permission(self::ROOT . ".broadcast.admin", "Allows the user to receive administrative broadcasts"), [$operatorRoot]); @@ -101,7 +103,7 @@ abstract class DefaultPermissions{ self::registerPermission(new Permission(self::ROOT . ".command.seed", "Allows the user to view the seed of the world"), [$operatorRoot]); self::registerPermission(new Permission(self::ROOT . ".command.status", "Allows the user to view the server performance"), [$operatorRoot]); self::registerPermission(new Permission(self::ROOT . ".command.gc", "Allows the user to fire garbage collection tasks"), [$operatorRoot]); - self::registerPermission(new Permission(self::ROOT . ".command.dumpmemory", "Allows the user to dump memory contents"), []); //TODO: this should be exclusively granted to CONSOLE + self::registerPermission(new Permission(self::ROOT . ".command.dumpmemory", "Allows the user to dump memory contents"), [$consoleRoot]); self::registerPermission(new Permission(self::ROOT . ".command.timings", "Allows the user to records timings for all plugin events"), [$operatorRoot]); self::registerPermission(new Permission(self::ROOT . ".command.spawnpoint", "Allows the user to change player's spawnpoint"), [$operatorRoot]); self::registerPermission(new Permission(self::ROOT . ".command.setworldspawn", "Allows the user to change the world spawn"), [$operatorRoot]); From 05c52fef4672d371e74a60a09f2047237e48f0f6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 2 Dec 2020 14:41:28 +0000 Subject: [PATCH 2165/3224] Updated DevTools submodule to pmmp/DevTools@7c2d05cafc52328f57b50daab5d58672501baad6 --- tests/plugins/DevTools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/plugins/DevTools b/tests/plugins/DevTools index 0c46527bee..7c2d05cafc 160000 --- a/tests/plugins/DevTools +++ b/tests/plugins/DevTools @@ -1 +1 @@ -Subproject commit 0c46527bee72324e5fee0c4ed2c7f5a324b6a4d0 +Subproject commit 7c2d05cafc52328f57b50daab5d58672501baad6 From 807474b3fbe8a10f527598110376e88c87fbfb9c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 2 Dec 2020 15:56:54 +0000 Subject: [PATCH 2166/3224] PermissibleBase: do not assign any permissions by default there is no longer such a thing as a permission granted to 'everyone', since we're no longer limited to true/false/op/notop, and regular players are now assigned the pocketmine.group.user permission. It's possible we might want to add more restricted groups than 'user' in the future, in which case it would be behaviour-BC-breaking to change the default assigned permissions when creating a new PermissibleBase. Therefore, it's better to not assign any permissions at all and let the caller decide. In addition, this solves the problem of implied permission subscriptions and leak on PermissibleBase construction - if base permissions are provided, it should be expected that the permissible will subscribe to those permissions. --- src/permission/PermissibleBase.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index 041057e8a5..3cff6afc18 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -35,9 +35,7 @@ class PermissibleBase implements Permissible{ * @var bool[] * @phpstan-var array */ - private $rootPermissions = [ - DefaultPermissions::ROOT_USER => true - ]; + private $rootPermissions; /** @var PermissionAttachment[] */ private $attachments = []; @@ -60,9 +58,7 @@ class PermissibleBase implements Permissible{ //TODO: we can't setBasePermission here directly due to bad architecture that causes recalculatePermissions to explode //so, this hack has to be done here to prevent permission recalculations until it's fixed... - foreach($basePermissions as $permission => $isGranted){ - $this->rootPermissions[$permission] = $isGranted; - } + $this->rootPermissions = $basePermissions; //TODO: permissions need to be recalculated here, or inherited permissions won't work } From 6001f69d52e4bc3cf03e24e11ef07e23de54ad45 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 2 Dec 2020 16:16:04 +0000 Subject: [PATCH 2167/3224] Network->registerInterface() now returns whether the registration succeeded or not --- src/network/Network.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/network/Network.php b/src/network/Network.php index 5bfbd3c026..54a78a365a 100644 --- a/src/network/Network.php +++ b/src/network/Network.php @@ -91,7 +91,7 @@ class Network{ $this->sessionManager->tick(); } - public function registerInterface(NetworkInterface $interface) : void{ + public function registerInterface(NetworkInterface $interface) : bool{ $ev = new NetworkInterfaceRegisterEvent($interface); $ev->call(); if(!$ev->isCancelled()){ @@ -105,7 +105,9 @@ class Network{ } } $interface->setName($this->name); + return true; } + return false; } /** From 687ad28fa677ef8c41d32a753d76551f51872194 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 2 Dec 2020 16:34:14 +0000 Subject: [PATCH 2168/3224] Added a PacketBroadcaster interface this gives a bit more control over how packets are broadcasted, which might be useful if the batch format changes (e.g. adding a length prefix) for multi version. This really ought to be unique to a protocol context instead of a network interface, but for now this is the best we can do. --- src/Server.php | 35 +++------ src/network/mcpe/NetworkSession.php | 8 ++- src/network/mcpe/PacketBroadcaster.php | 35 +++++++++ .../mcpe/StandardPacketBroadcaster.php | 71 +++++++++++++++++++ src/network/mcpe/raklib/RakLibInterface.php | 8 +++ 5 files changed, 131 insertions(+), 26 deletions(-) create mode 100644 src/network/mcpe/PacketBroadcaster.php create mode 100644 src/network/mcpe/StandardPacketBroadcaster.php diff --git a/src/Server.php b/src/Server.php index e62d8865a8..5ed46004dd 100644 --- a/src/Server.php +++ b/src/Server.php @@ -52,6 +52,7 @@ use pocketmine\network\mcpe\compression\Compressor; use pocketmine\network\mcpe\compression\ZlibCompressor; use pocketmine\network\mcpe\encryption\EncryptionContext; use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\PacketBroadcaster; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; @@ -1227,33 +1228,17 @@ class Server{ } $recipients = $ev->getTargets(); - $stream = PacketBatch::fromPackets(...$ev->getPackets()); - - /** @var Compressor[] $compressors */ - $compressors = []; - /** @var NetworkSession[][] $compressorTargets */ - $compressorTargets = []; + /** @var PacketBroadcaster[] $broadcasters */ + $broadcasters = []; + /** @var NetworkSession[][] $broadcasterTargets */ + $broadcasterTargets = []; foreach($recipients as $recipient){ - $compressor = $recipient->getCompressor(); - $compressorId = spl_object_id($compressor); - //TODO: different compressors might be compatible, it might not be necessary to split them up by object - $compressors[$compressorId] = $compressor; - $compressorTargets[$compressorId][] = $recipient; + $broadcaster = $recipient->getBroadcaster(); + $broadcasters[spl_object_id($broadcaster)] = $broadcaster; + $broadcasterTargets[spl_object_id($broadcaster)][] = $recipient; } - - foreach($compressors as $compressorId => $compressor){ - if(!$compressor->willCompress($stream->getBuffer())){ - foreach($compressorTargets[$compressorId] as $target){ - foreach($ev->getPackets() as $pk){ - $target->addToSendBuffer($pk); - } - } - }else{ - $promise = $this->prepareBatch($stream, $compressor); - foreach($compressorTargets[$compressorId] as $target){ - $target->queueCompressed($promise); - } - } + foreach($broadcasters as $broadcaster){ + $broadcaster->broadcastPackets($broadcasterTargets[spl_object_id($broadcaster)], $packets); } return true; diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 6e45c2f7ad..0bf104bb91 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -177,16 +177,20 @@ class NetworkSession{ /** @var PacketSender */ private $sender; + /** @var PacketBroadcaster */ + private $broadcaster; + /** * @var \Closure[]|Set * @phpstan-var Set<\Closure() : void> */ private $disposeHooks; - public function __construct(Server $server, NetworkSessionManager $manager, PacketPool $packetPool, PacketSender $sender, Compressor $compressor, string $ip, int $port){ + public function __construct(Server $server, NetworkSessionManager $manager, PacketPool $packetPool, PacketSender $sender, PacketBroadcaster $broadcaster, Compressor $compressor, string $ip, int $port){ $this->server = $server; $this->manager = $manager; $this->sender = $sender; + $this->broadcaster = $broadcaster; $this->ip = $ip; $this->port = $port; @@ -449,6 +453,8 @@ class NetworkSession{ } } + public function getBroadcaster() : PacketBroadcaster{ return $this->broadcaster; } + public function getCompressor() : Compressor{ return $this->compressor; } diff --git a/src/network/mcpe/PacketBroadcaster.php b/src/network/mcpe/PacketBroadcaster.php new file mode 100644 index 0000000000..8a23fac750 --- /dev/null +++ b/src/network/mcpe/PacketBroadcaster.php @@ -0,0 +1,35 @@ +server = $server; + } + + public function broadcastPackets(array $recipients, array $packets) : void{ + $stream = PacketBatch::fromPackets(...$packets); + + /** @var Compressor[] $compressors */ + $compressors = []; + /** @var NetworkSession[][] $compressorTargets */ + $compressorTargets = []; + foreach($recipients as $recipient){ + $compressor = $recipient->getCompressor(); + $compressorId = spl_object_id($compressor); + //TODO: different compressors might be compatible, it might not be necessary to split them up by object + $compressors[$compressorId] = $compressor; + $compressorTargets[$compressorId][] = $recipient; + } + + foreach($compressors as $compressorId => $compressor){ + if(!$compressor->willCompress($stream->getBuffer())){ + foreach($compressorTargets[$compressorId] as $target){ + foreach($packets as $pk){ + $target->addToSendBuffer($pk); + } + } + }else{ + $promise = $this->server->prepareBatch($stream, $compressor); + foreach($compressorTargets[$compressorId] as $target){ + $target->queueCompressed($promise); + } + } + } + + } +} diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 8decc4fc02..41d6f1176f 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -27,8 +27,10 @@ use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\compression\ZlibCompressor; use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\PacketBroadcaster; use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\network\mcpe\protocol\ProtocolInfo; +use pocketmine\network\mcpe\StandardPacketBroadcaster; use pocketmine\network\Network; use pocketmine\Server; use pocketmine\snooze\SleeperNotifier; @@ -81,6 +83,9 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ /** @var SleeperNotifier */ private $sleeper; + /** @var PacketBroadcaster */ + private $broadcaster; + public function __construct(Server $server){ $this->server = $server; $this->rakServerId = mt_rand(0, PHP_INT_MAX); @@ -106,6 +111,8 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ $this->interface = new UserToRakLibThreadMessageSender( new PthreadsChannelWriter($mainToThreadBuffer) ); + + $this->broadcaster = new StandardPacketBroadcaster($this->server); } public function start() : void{ @@ -158,6 +165,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ $this->network->getSessionManager(), PacketPool::getInstance(), new RakLibPacketSender($sessionId, $this), + $this->broadcaster, ZlibCompressor::getInstance(), //TODO: this shouldn't be hardcoded, but we might need the RakNet protocol version to select it $address, $port From bc2fafca271783ca13bf54228a577a6356a5a4c5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 2 Dec 2020 17:04:37 +0000 Subject: [PATCH 2169/3224] Fixed players losing all permissions when being de-opped after joining as op --- src/player/Player.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index 007a74d2c0..7051290b6f 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -279,7 +279,11 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->uuid = $this->playerInfo->getUuid(); $this->xuid = $this->playerInfo instanceof XboxLivePlayerInfo ? $this->playerInfo->getXuid() : ""; - $this->perm = new PermissibleBase($this->server->isOp($this->username) ? [DefaultPermissions::ROOT_OPERATOR => true] : [DefaultPermissions::ROOT_USER => true]); + $rootPermissions = [DefaultPermissions::ROOT_USER => true]; + if($this->server->isOp($this->username)){ + $rootPermissions[DefaultPermissions::ROOT_OPERATOR] = true; + } + $this->perm = new PermissibleBase($rootPermissions); $this->chunksPerTick = (int) $this->server->getConfigGroup()->getProperty("chunk-sending.per-tick", 4); $this->spawnThreshold = (int) (($this->server->getConfigGroup()->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); $this->chunkSelector = new ChunkSelector(); From 0574b59df970c5f6b04d3b477f2b1d2325397f31 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 2 Dec 2020 17:11:15 +0000 Subject: [PATCH 2170/3224] Network: fixed interfaces registered after raw packet handlers not respecting raw packet handler filters --- src/network/Network.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/network/Network.php b/src/network/Network.php index 54a78a365a..886d047d1e 100644 --- a/src/network/Network.php +++ b/src/network/Network.php @@ -103,6 +103,9 @@ class Network{ foreach($this->bannedIps as $ip => $until){ $interface->blockAddress($ip); } + foreach($this->rawPacketHandlers as $handler){ + $interface->addRawPacketFilter($handler->getPattern()); + } } $interface->setName($this->name); return true; From 1775fb669b551d64ba2e28382a5025539253b0d4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 2 Dec 2020 18:56:39 +0000 Subject: [PATCH 2171/3224] SurvivalBlockBreakHandler: fixed block break effects stopping beyond 4 blocks distance this was actually intended to be 16 blocks ... --- src/player/SurvivalBlockBreakHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player/SurvivalBlockBreakHandler.php b/src/player/SurvivalBlockBreakHandler.php index f715ec896f..3992e8fa5e 100644 --- a/src/player/SurvivalBlockBreakHandler.php +++ b/src/player/SurvivalBlockBreakHandler.php @@ -101,7 +101,7 @@ final class SurvivalBlockBreakHandler{ public function update() : bool{ if( - $this->player->getPosition()->distanceSquared($this->blockPos->add(0.5, 0.5, 0.5)) > $this->maxPlayerDistance){ + $this->player->getPosition()->distanceSquared($this->blockPos->add(0.5, 0.5, 0.5)) > $this->maxPlayerDistance ** 2){ return false; } From 29f6ed3f688e527bb7a4454fb24b3d18627a603e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 2 Dec 2020 19:34:34 +0000 Subject: [PATCH 2172/3224] Use Snooze to improve AsyncTask collection times regardless of how long an async task takes to run, it will take a multiple of 50ms to get the result processed. This delay causes issues in some cases for stuff like generation, which causes locking of adjacent chunks, and async packet compression, which experiences elevated latency because of this problem. This is not an ideal solution for packet compression since it will cause the sleeper handler to get hammered, but since it's already getting hammered by every packet from RakLib, I don't think that's a big problem. --- src/Server.php | 2 +- src/scheduler/AsyncPool.php | 87 ++++++++++++++--------- src/scheduler/AsyncTask.php | 1 + src/scheduler/AsyncWorker.php | 11 ++- tests/phpstan/configs/l8-baseline.neon | 5 ++ tests/phpunit/scheduler/AsyncPoolTest.php | 3 +- 6 files changed, 73 insertions(+), 36 deletions(-) diff --git a/src/Server.php b/src/Server.php index 5ed46004dd..0e2084762f 100644 --- a/src/Server.php +++ b/src/Server.php @@ -873,7 +873,7 @@ class Server{ $poolSize = max(1, (int) $poolSize); } - $this->asyncPool = new AsyncPool($poolSize, max(-1, (int) $this->configGroup->getProperty("memory.async-worker-hard-limit", 256)), $this->autoloader, $this->logger); + $this->asyncPool = new AsyncPool($poolSize, max(-1, (int) $this->configGroup->getProperty("memory.async-worker-hard-limit", 256)), $this->autoloader, $this->logger, $this->tickSleeper); $netCompressionThreshold = -1; if($this->configGroup->getProperty("network.batch-threshold", 256) >= 0){ diff --git a/src/scheduler/AsyncPool.php b/src/scheduler/AsyncPool.php index f7606c7c3c..9eb7126efa 100644 --- a/src/scheduler/AsyncPool.php +++ b/src/scheduler/AsyncPool.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\scheduler; +use pocketmine\snooze\SleeperHandler; +use pocketmine\snooze\SleeperNotifier; use pocketmine\utils\Utils; use function array_keys; use function array_map; @@ -73,11 +75,15 @@ class AsyncPool{ */ private $workerStartHooks = []; - public function __construct(int $size, int $workerMemoryLimit, \ClassLoader $classLoader, \ThreadedLogger $logger){ + /** @var SleeperHandler */ + private $eventLoop; + + public function __construct(int $size, int $workerMemoryLimit, \ClassLoader $classLoader, \ThreadedLogger $logger, SleeperHandler $eventLoop){ $this->size = $size; $this->workerMemoryLimit = $workerMemoryLimit; $this->classLoader = $classLoader; $this->logger = $logger; + $this->eventLoop = $eventLoop; } /** @@ -136,8 +142,11 @@ class AsyncPool{ */ private function getWorker(int $worker) : AsyncWorker{ if(!isset($this->workers[$worker])){ - - $this->workers[$worker] = new AsyncWorker($this->logger, $worker, $this->workerMemoryLimit); + $notifier = new SleeperNotifier(); + $this->workers[$worker] = new AsyncWorker($this->logger, $worker, $this->workerMemoryLimit, $notifier); + $this->eventLoop->addNotifier($notifier, function() use ($worker) : void{ + $this->collectTasksFromWorker($worker); + }); $this->workers[$worker]->setClassLoader($this->classLoader); $this->workers[$worker]->start(self::WORKER_START_OPTIONS); @@ -226,39 +235,49 @@ class AsyncPool{ public function collectTasks() : bool{ $more = false; foreach($this->taskQueues as $worker => $queue){ - $doGC = false; - while(!$queue->isEmpty()){ - /** @var AsyncTask $task */ - $task = $queue->bottom(); - $task->checkProgressUpdates(); - if($task->isFinished()){ //make sure the task actually executed before trying to collect - $doGC = true; - $queue->dequeue(); + $more = $this->collectTasksFromWorker($worker) || $more; + } + return $more; + } - if($task->isCrashed()){ - $this->logger->critical("Could not execute asynchronous task " . (new \ReflectionClass($task))->getShortName() . ": Task crashed"); - $task->onError(); - }elseif(!$task->hasCancelledRun()){ - /* - * It's possible for a task to submit a progress update and then finish before the progress - * update is detected by the parent thread, so here we consume any missed updates. - * - * When this happens, it's possible for a progress update to arrive between the previous - * checkProgressUpdates() call and the next isGarbage() call, causing progress updates to be - * lost. Thus, it's necessary to do one last check here to make sure all progress updates have - * been consumed before completing. - */ - $task->checkProgressUpdates(); - $task->onCompletion(); - } - }else{ - $more = true; - break; //current task is still running, skip to next worker + public function collectTasksFromWorker(int $worker) : bool{ + if(!isset($this->taskQueues[$worker])){ + throw new \InvalidArgumentException("No such worker $worker"); + } + $queue = $this->taskQueues[$worker]; + $doGC = false; + $more = false; + while(!$queue->isEmpty()){ + /** @var AsyncTask $task */ + $task = $queue->bottom(); + $task->checkProgressUpdates(); + if($task->isFinished()){ //make sure the task actually executed before trying to collect + $doGC = true; + $queue->dequeue(); + + if($task->isCrashed()){ + $this->logger->critical("Could not execute asynchronous task " . (new \ReflectionClass($task))->getShortName() . ": Task crashed"); + $task->onError(); + }elseif(!$task->hasCancelledRun()){ + /* + * It's possible for a task to submit a progress update and then finish before the progress + * update is detected by the parent thread, so here we consume any missed updates. + * + * When this happens, it's possible for a progress update to arrive between the previous + * checkProgressUpdates() call and the next isGarbage() call, causing progress updates to be + * lost. Thus, it's necessary to do one last check here to make sure all progress updates have + * been consumed before completing. + */ + $task->checkProgressUpdates(); + $task->onCompletion(); } + }else{ + $more = true; + break; //current task is still running, skip to next worker } - if($doGC){ - $this->workers[$worker]->collect(); - } + } + if($doGC){ + $this->workers[$worker]->collect(); } return $more; } @@ -279,6 +298,7 @@ class AsyncPool{ foreach($this->taskQueues as $i => $queue){ if((!isset($this->workerLastUsed[$i]) or $this->workerLastUsed[$i] + 300 < $time) and $queue->isEmpty()){ $this->workers[$i]->quit(); + $this->eventLoop->removeNotifier($this->workers[$i]->getNotifier()); unset($this->workers[$i], $this->taskQueues[$i], $this->workerLastUsed[$i]); $ret++; } @@ -309,6 +329,7 @@ class AsyncPool{ foreach($this->workers as $worker){ $worker->quit(); + $this->eventLoop->removeNotifier($worker->getNotifier()); } $this->workers = []; $this->taskQueues = []; diff --git a/src/scheduler/AsyncTask.php b/src/scheduler/AsyncTask.php index cd79e6f409..b58f1fddb9 100644 --- a/src/scheduler/AsyncTask.php +++ b/src/scheduler/AsyncTask.php @@ -89,6 +89,7 @@ abstract class AsyncTask extends \Threaded{ } $this->finished = true; + $this->worker->getNotifier()->wakeupSleeper(); } public function isCrashed() : bool{ diff --git a/src/scheduler/AsyncWorker.php b/src/scheduler/AsyncWorker.php index 51bdfd06ef..eedb7ea5c3 100644 --- a/src/scheduler/AsyncWorker.php +++ b/src/scheduler/AsyncWorker.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\scheduler; +use pocketmine\snooze\SleeperNotifier; use pocketmine\thread\Worker; use function gc_enable; use function ini_set; @@ -39,10 +40,18 @@ class AsyncWorker extends Worker{ /** @var int */ private $memoryLimit; - public function __construct(\ThreadedLogger $logger, int $id, int $memoryLimit){ + /** @var SleeperNotifier */ + private $notifier; + + public function __construct(\ThreadedLogger $logger, int $id, int $memoryLimit, SleeperNotifier $notifier){ $this->logger = $logger; $this->id = $id; $this->memoryLimit = $memoryLimit; + $this->notifier = $notifier; + } + + public function getNotifier() : SleeperNotifier{ + return $this->notifier; } protected function onRun() : void{ diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index ef7fd7b38c..e7f7642c47 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -460,6 +460,11 @@ parameters: count: 1 path: ../../../src/scheduler/AsyncTask.php + - + message: "#^Cannot call method getNotifier\\(\\) on pocketmine\\\\scheduler\\\\AsyncWorker\\|null\\.$#" + count: 1 + path: ../../../src/scheduler/AsyncTask.php + - message: "#^Cannot call method count\\(\\) on ArrayObject\\\\>\\|null\\.$#" count: 1 diff --git a/tests/phpunit/scheduler/AsyncPoolTest.php b/tests/phpunit/scheduler/AsyncPoolTest.php index f2a521ead5..ab2bc5a29d 100644 --- a/tests/phpunit/scheduler/AsyncPoolTest.php +++ b/tests/phpunit/scheduler/AsyncPoolTest.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\scheduler; use PHPUnit\Framework\TestCase; +use pocketmine\snooze\SleeperHandler; use pocketmine\utils\MainLogger; use pocketmine\utils\Terminal; use function define; @@ -44,7 +45,7 @@ class AsyncPoolTest extends TestCase{ Terminal::init(); @define('pocketmine\\COMPOSER_AUTOLOADER_PATH', dirname(__DIR__, 3) . '/vendor/autoload.php'); $this->mainLogger = new MainLogger(tempnam(sys_get_temp_dir(), "pmlog")); - $this->pool = new AsyncPool(2, 1024, new \BaseClassLoader(), $this->mainLogger); + $this->pool = new AsyncPool(2, 1024, new \BaseClassLoader(), $this->mainLogger, new SleeperHandler()); } public function tearDown() : void{ From 5197707d32107ca02a9669fa692083e265fabca4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 3 Dec 2020 15:45:49 +0000 Subject: [PATCH 2173/3224] Separated TimingsRecord from TimingsHandler (different lifetimes) this fixes #3906. TimingsHandler will now be automatically destroyed when there are no TimingsRecord referencing it and its owner has no references left to it. TimingsRecord will be automatically destroyed at the end of the timings session (if active). This fixes records from temporary timers being lost after the timings handlers are removed, while also fixing TimingsHandlers piling up regardless of whether timings are running or not. This opens the doors to have more volatile timers, such as per-player/per-session timers, which are destroyed on player quit, but which won't result in the timings disappearing from the final timings result. --- src/command/Command.php | 3 - src/event/RegisteredListener.php | 4 - src/timings/TimingsHandler.php | 91 +++++++--------------- src/timings/TimingsRecord.php | 125 +++++++++++++++++++++++++++++++ 4 files changed, 152 insertions(+), 71 deletions(-) create mode 100644 src/timings/TimingsRecord.php diff --git a/src/command/Command.php b/src/command/Command.php index 3c52ed4d4e..740571e638 100644 --- a/src/command/Command.php +++ b/src/command/Command.php @@ -144,9 +144,6 @@ abstract class Command{ public function setLabel(string $name) : bool{ $this->nextLabel = $name; if(!$this->isRegistered()){ - if($this->timings instanceof TimingsHandler){ - $this->timings->remove(); - } $this->timings = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Command: " . $name); $this->label = $name; diff --git a/src/event/RegisteredListener.php b/src/event/RegisteredListener.php index 6d95660e74..cc22a0511a 100644 --- a/src/event/RegisteredListener.php +++ b/src/event/RegisteredListener.php @@ -76,10 +76,6 @@ class RegisteredListener{ $this->timings->stopTiming(); } - public function __destruct(){ - $this->timings->remove(); - } - public function isHandlingCancelled() : bool{ return $this->handleCancelled; } diff --git a/src/timings/TimingsHandler.php b/src/timings/TimingsHandler.php index d69ef84ddf..6fc07adf8b 100644 --- a/src/timings/TimingsHandler.php +++ b/src/timings/TimingsHandler.php @@ -29,13 +29,9 @@ use function count; use function fwrite; use function microtime; use function round; -use function spl_object_id; use const PHP_EOL; class TimingsHandler{ - - /** @var TimingsHandler[] */ - private static $HANDLERS = []; /** @var bool */ private static $enabled = false; /** @var float */ @@ -47,16 +43,17 @@ class TimingsHandler{ public static function printTimings($fp) : void{ fwrite($fp, "Minecraft" . PHP_EOL); - foreach(self::$HANDLERS as $timings){ - $time = $timings->totalTime; - $count = $timings->count; + foreach(TimingsRecord::getAll() as $timings){ + $time = $timings->getTotalTime(); + $count = $timings->getCount(); if($count === 0){ + //this should never happen - a timings record shouldn't exist if it hasn't been used continue; } $avg = $time / $count; - fwrite($fp, " " . $timings->name . " Time: " . round($time * 1000000000) . " Count: " . $count . " Avg: " . round($avg * 1000000000) . " Violations: " . $timings->violations . PHP_EOL); + fwrite($fp, " " . $timings->getName() . " Time: " . round($time * 1000000000) . " Count: " . $count . " Avg: " . round($avg * 1000000000) . " Violations: " . $timings->getViolations() . PHP_EOL); } fwrite($fp, "# Version " . Server::getInstance()->getVersion() . PHP_EOL); @@ -94,35 +91,15 @@ class TimingsHandler{ } public static function reload() : void{ + TimingsRecord::clearRecords(); if(self::$enabled){ - foreach(self::$HANDLERS as $timings){ - $timings->reset(); - } self::$timingStart = microtime(true); } } public static function tick(bool $measure = true) : void{ if(self::$enabled){ - if($measure){ - foreach(self::$HANDLERS as $timings){ - if($timings->curTickTotal > 0.05){ - $timings->violations += (int) round($timings->curTickTotal / 0.05); - } - $timings->curTickTotal = 0; - $timings->curCount = 0; - $timings->timingDepth = 0; - } - }else{ - foreach(self::$HANDLERS as $timings){ - $timings->totalTime -= $timings->curTickTotal; - $timings->count -= $timings->curCount; - - $timings->curTickTotal = 0; - $timings->curCount = 0; - $timings->timingDepth = 0; - } - } + TimingsRecord::tick($measure); } } @@ -131,27 +108,19 @@ class TimingsHandler{ /** @var TimingsHandler|null */ private $parent = null; - /** @var int */ - private $count = 0; - /** @var int */ - private $curCount = 0; - /** @var float */ - private $start = 0; + /** @var TimingsRecord|null */ + private $record = null; + /** @var int */ private $timingDepth = 0; - /** @var float */ - private $totalTime = 0; - /** @var float */ - private $curTickTotal = 0; - /** @var int */ - private $violations = 0; public function __construct(string $name, ?TimingsHandler $parent = null){ $this->name = $name; $this->parent = $parent; - - self::$HANDLERS[spl_object_id($this)] = $this; } + + public function getName() : string{ return $this->name; } + public function startTiming() : void{ if(self::$enabled){ $this->internalStartTiming(microtime(true)); @@ -160,7 +129,10 @@ class TimingsHandler{ private function internalStartTiming(float $now) : void{ if(++$this->timingDepth === 1){ - $this->start = $now; + if($this->record === null){ + $this->record = new TimingsRecord($this); + } + $this->record->startTiming($now); if($this->parent !== null){ $this->parent->internalStartTiming($now); } @@ -180,16 +152,14 @@ class TimingsHandler{ //usefulness of bailing here anyway, we don't currently bother. return; } - if(--$this->timingDepth !== 0 or $this->start == 0){ + if(--$this->timingDepth !== 0){ return; } - $diff = $now - $this->start; - $this->totalTime += $diff; - $this->curTickTotal += $diff; - ++$this->curCount; - ++$this->count; - $this->start = 0; + if($this->record !== null){ + //this might be null if a timings reset occurred while the timer was running + $this->record->stopTiming($now); + } if($this->parent !== null){ $this->parent->internalStopTiming($now); } @@ -211,17 +181,10 @@ class TimingsHandler{ } } - public function reset() : void{ - $this->count = 0; - $this->curCount = 0; - $this->violations = 0; - $this->curTickTotal = 0; - $this->totalTime = 0; - $this->start = 0; - $this->timingDepth = 0; - } - - public function remove() : void{ - unset(self::$HANDLERS[spl_object_id($this)]); + /** + * @internal + */ + public function destroyCycles() : void{ + $this->record = null; } } diff --git a/src/timings/TimingsRecord.php b/src/timings/TimingsRecord.php new file mode 100644 index 0000000000..106ad3772c --- /dev/null +++ b/src/timings/TimingsRecord.php @@ -0,0 +1,125 @@ + + */ + private static $records = []; + + public static function clearRecords() : void{ + foreach(self::$records as $record){ + $record->handler->destroyCycles(); + } + self::$records = []; + } + + /** + * @return self[] + * @phpstan-return array + */ + public static function getAll() : array{ return self::$records; } + + public static function tick(bool $measure = true) : void{ + if($measure){ + foreach(self::$records as $record){ + if($record->curTickTotal > 0.05){ + $record->violations += (int) round($record->curTickTotal / 0.05); + } + $record->curTickTotal = 0; + $record->curCount = 0; + } + }else{ + foreach(self::$records as $record){ + $record->totalTime -= $record->curTickTotal; + $record->count -= $record->curCount; + + $record->curTickTotal = 0; + $record->curCount = 0; + } + } + } + + /** @var TimingsHandler */ + private $handler; + + /** @var int */ + private $count = 0; + /** @var int */ + private $curCount = 0; + /** @var float */ + private $start = 0; + /** @var float */ + private $totalTime = 0; + /** @var float */ + private $curTickTotal = 0; + /** @var int */ + private $violations = 0; + + public function __construct(TimingsHandler $handler){ + self::$records[spl_object_id($this)] = $this; + //I'm not the biggest fan of this cycle, but it seems to be the most effective way to avoid leaking anything. + $this->handler = $handler; + } + + public function getName() : string{ return $this->handler->getName(); } + + public function getCount() : int{ return $this->count; } + + public function getCurCount() : int{ return $this->curCount; } + + public function getStart() : float{ return $this->start; } + + public function getTotalTime() : float{ return $this->totalTime; } + + public function getCurTickTotal() : float{ return $this->curTickTotal; } + + public function getViolations() : int{ return $this->violations; } + + public function startTiming(float $now) : void{ + $this->start = $now; + } + + public function stopTiming(float $now) : void{ + if($this->start == 0){ + return; + } + $diff = $now - $this->start; + $this->totalTime += $diff; + $this->curTickTotal += $diff; + ++$this->curCount; + ++$this->count; + $this->start = 0; + } +} From 74744fd4983927df68ba8f483b70281ce7a833d9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 3 Dec 2020 18:15:09 +0000 Subject: [PATCH 2174/3224] World: fire ChunkLoadEvent in setChunk() if the chunk did not previously exist I'm of two minds whether this should continue to fire onChunkChanged() on chunk loaders or not, since the chunks won't be referenced by any chunk loader anyway by virtue of not existing ... --- src/world/World.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index 398ccc7f76..f8286d17a2 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2048,6 +2048,14 @@ class World implements ChunkManager{ $this->unloadChunkRequest($chunkX, $chunkZ); } + if($oldChunk === null){ + (new ChunkLoadEvent($this, $chunk, true))->call(); + + foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){ + $listener->onChunkLoaded($chunk); + } + } + foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){ $listener->onChunkChanged($chunk); } From fa9be2477d94d16cfccb8852ec74e226194e5b55 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 3 Dec 2020 18:20:43 +0000 Subject: [PATCH 2175/3224] World: do not fire ChunkListener->onChunkChanged() when a new chunk is set the documentation expressly describes a chunk being _replaced_ by a new chunk. This doesn't fit when the chunk didn't exist to begin with. --- src/world/World.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index f8286d17a2..e0bb919825 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2054,10 +2054,10 @@ class World implements ChunkManager{ foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){ $listener->onChunkLoaded($chunk); } - } - - foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){ - $listener->onChunkChanged($chunk); + }else{ + foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){ + $listener->onChunkChanged($chunk); + } } } From ec2feeffcbcd38d71ca15c6130333348158c45ec Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 3 Dec 2020 18:23:03 +0000 Subject: [PATCH 2176/3224] World->populateChunk() no longer causes ChunkLoadEvent to fire with an empty chunk instead, it will fire when the chunk comes out of PopulationTask and is set into the world using setChunk(). There is still one place left where auto-creation of empty chunks is used by the core, and that's an issue i'm still deciding how to deal with. --- src/world/World.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index e0bb919825..c14d6da09c 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2513,7 +2513,10 @@ class World implements ChunkManager{ } } - $chunk = $this->loadChunk($x, $z, true); + $chunk = $this->loadChunk($x, $z, false); + if($chunk === null){ + $chunk = new Chunk($x, $z); + } if(!$chunk->isPopulated()){ Timings::$populationTimer->startTiming(); From 1e7f9214cc2025ad1c12a9967200a35b63155e5d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 3 Dec 2020 18:36:54 +0000 Subject: [PATCH 2177/3224] Entity: flag for despawn if entering ungenerated terrain previously this created an empty chunk for the entity to hang around in until the terrain was generated, but that's problematic for several reasons, most importantly the fact that non-generated chunks are not saved. --- src/entity/Entity.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 2af2883f73..75e7502026 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1366,7 +1366,16 @@ abstract class Entity{ if($this->chunk !== null){ $this->chunk->removeEntity($this); } - $this->chunk = $this->getWorld()->loadChunk($chunkX, $chunkZ, true); + $this->chunk = $this->getWorld()->loadChunk($chunkX, $chunkZ, false); + if($this->chunk === null){ + //TODO: this is a non-ideal solution for a hard problem + //when this happens the entity won't be tracked by any chunk, so we can't have it hanging around in memory + //we also can't allow this to cause chunk generation, nor can we just create an empty ungenerated chunk + //for it, because an empty chunk won't get saved, so the entity will vanish anyway. Therefore, this is + //the cleanest way to make sure this doesn't result in leaks. + $this->getWorld()->getLogger()->debug("Entity $this->id is in ungenerated terrain, flagging for despawn"); + $this->flagForDespawn(); + } $this->chunkX = $chunkX; $this->chunkZ = $chunkZ; From a67f0d1f7583933245dc5794a881b397aec869e5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 3 Dec 2020 18:41:53 +0000 Subject: [PATCH 2178/3224] World->registerChunkLoader() no longer causes creation of an empty chunk this only made sense to work around the server crashing when creating a player in ungenerated terrain, but spawning at y=256 is hardly preferable, and it'll crash since fd99445c5bbd2a5a6fdd0109d8a196ea6160e0a3 anyway ... --- src/world/World.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index c14d6da09c..314a510838 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -590,7 +590,7 @@ class World implements ChunkManager{ $this->cancelUnloadChunkRequest($chunkX, $chunkZ); if($autoLoad){ - $this->loadChunk($chunkX, $chunkZ, true); + $this->loadChunk($chunkX, $chunkZ, false); } } From 999defd20d1db6e3dc27d97390ede160ead060c8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 3 Dec 2020 18:49:14 +0000 Subject: [PATCH 2179/3224] World: remove create params from loadChunk() and loadChunkAtPosition() --- src/entity/Entity.php | 4 ++-- src/world/World.php | 40 +++++++++++++++++----------------------- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 75e7502026..adf689f730 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -243,7 +243,7 @@ abstract class Entity{ $this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0); $this->recalculateBoundingBox(); - $this->chunk = $this->getWorld()->getOrLoadChunkAtPosition($this->location, false); + $this->chunk = $this->getWorld()->getOrLoadChunkAtPosition($this->location); if($this->chunk === null){ throw new \InvalidStateException("Cannot create entities in unloaded chunks"); } @@ -1366,7 +1366,7 @@ abstract class Entity{ if($this->chunk !== null){ $this->chunk->removeEntity($this); } - $this->chunk = $this->getWorld()->loadChunk($chunkX, $chunkZ, false); + $this->chunk = $this->getWorld()->loadChunk($chunkX, $chunkZ); if($this->chunk === null){ //TODO: this is a non-ideal solution for a hard problem //when this happens the entity won't be tracked by any chunk, so we can't have it hanging around in memory diff --git a/src/world/World.php b/src/world/World.php index 314a510838..6f9d4e23e6 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -590,7 +590,7 @@ class World implements ChunkManager{ $this->cancelUnloadChunkRequest($chunkX, $chunkZ); if($autoLoad){ - $this->loadChunk($chunkX, $chunkZ, false); + $this->loadChunk($chunkX, $chunkZ); } } @@ -1411,7 +1411,7 @@ class World implements ChunkManager{ if($this->isChunkLocked($chunkX, $chunkZ)){ throw new WorldException("Terrain is locked for generation/population"); } - if($this->loadChunk($chunkX, $chunkZ, false) === null){ //current expected behaviour is to try to load the terrain synchronously + if($this->loadChunk($chunkX, $chunkZ) === null){ //current expected behaviour is to try to load the terrain synchronously throw new WorldException("Cannot set a block in un-generated terrain"); } @@ -1852,7 +1852,7 @@ class World implements ChunkManager{ * Returns the tile at the specified x,y,z coordinates, or null if it does not exist. */ public function getTileAt(int $x, int $y, int $z) : ?Tile{ - return ($chunk = $this->loadChunk($x >> 4, $z >> 4, false)) !== null ? $chunk->getTile($x & 0x0f, $y, $z & 0x0f) : null; + return ($chunk = $this->loadChunk($x >> 4, $z >> 4)) !== null ? $chunk->getTile($x & 0x0f, $y, $z & 0x0f) : null; } /** @@ -1886,7 +1886,7 @@ class World implements ChunkManager{ } public function getBiomeId(int $x, int $z) : int{ - if(($chunk = $this->loadChunk($x >> 4, $z >> 4, false)) !== null){ + if(($chunk = $this->loadChunk($x >> 4, $z >> 4)) !== null){ return $chunk->getBiomeId($x & 0x0f, $z & 0x0f); } return BiomeIds::OCEAN; //TODO: this should probably throw instead (terrain not generated yet) @@ -1903,7 +1903,7 @@ class World implements ChunkManager{ //the changes would be overwritten when the generation finishes throw new WorldException("Chunk is currently locked for async generation/population"); } - if(($chunk = $this->loadChunk($chunkX, $chunkZ, false)) !== null){ + if(($chunk = $this->loadChunk($chunkX, $chunkZ)) !== null){ $chunk->setBiomeId($x & 0x0f, $z & 0x0f, $biomeId); }else{ //if we allowed this, the modifications would be lost when the chunk is created @@ -1925,8 +1925,8 @@ class World implements ChunkManager{ /** * Returns the chunk containing the given Vector3 position. */ - public function getOrLoadChunkAtPosition(Vector3 $pos, bool $create = false) : ?Chunk{ - return $this->loadChunk($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4, $create); + public function getOrLoadChunkAtPosition(Vector3 $pos) : ?Chunk{ + return $this->loadChunk($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4); } /** @@ -1942,7 +1942,7 @@ class World implements ChunkManager{ if($i === 4){ continue; //center chunk } - $result[$i] = $this->loadChunk($x + $xx - 1, $z + $zz - 1, false); + $result[$i] = $this->loadChunk($x + $xx - 1, $z + $zz - 1); } } @@ -1976,7 +1976,7 @@ class World implements ChunkManager{ unset($this->chunkPopulationQueue[$index]); if($chunk !== null){ - $oldChunk = $this->loadChunk($x, $z, false); + $oldChunk = $this->loadChunk($x, $z); $this->setChunk($x, $z, $chunk, false); if(($oldChunk === null or !$oldChunk->isPopulated()) and $chunk->isPopulated()){ (new ChunkPopulateEvent($this, $chunk))->call(); @@ -2009,7 +2009,7 @@ class World implements ChunkManager{ $chunk->setZ($chunkZ); $chunkHash = World::chunkHash($chunkX, $chunkZ); - $oldChunk = $this->loadChunk($chunkX, $chunkZ, false); + $oldChunk = $this->loadChunk($chunkX, $chunkZ); if($oldChunk !== null and $oldChunk !== $chunk){ if($deleteEntitiesAndTiles){ foreach($oldChunk->getEntities() as $entity){ @@ -2068,7 +2068,7 @@ class World implements ChunkManager{ * @throws WorldException if the terrain is not generated */ public function getHighestBlockAt(int $x, int $z) : int{ - if(($chunk = $this->loadChunk($x >> 4, $z >> 4, false)) !== null){ + if(($chunk = $this->loadChunk($x >> 4, $z >> 4)) !== null){ return $chunk->getHighestBlockAt($x & 0x0f, $z & 0x0f); } throw new WorldException("Cannot get highest block in an ungenerated chunk"); @@ -2086,12 +2086,12 @@ class World implements ChunkManager{ } public function isChunkGenerated(int $x, int $z) : bool{ - $chunk = $this->loadChunk($x, $z, false); + $chunk = $this->loadChunk($x, $z); return $chunk !== null ? $chunk->isGenerated() : false; } public function isChunkPopulated(int $x, int $z) : bool{ - $chunk = $this->loadChunk($x, $z, false); + $chunk = $this->loadChunk($x, $z); return $chunk !== null ? $chunk->isPopulated() : false; } @@ -2200,13 +2200,11 @@ class World implements ChunkManager{ * Attempts to load a chunk from the world provider (if not already loaded). If the chunk is already loaded, it is * returned directly. * - * @param bool $create Whether to create an empty chunk to load if the chunk cannot be loaded from disk. - * * @return Chunk|null the requested chunk, or null on failure. * * @throws \InvalidStateException */ - public function loadChunk(int $x, int $z, bool $create) : ?Chunk{ + public function loadChunk(int $x, int $z) : ?Chunk{ if(isset($this->chunks[$chunkHash = World::chunkHash($x, $z)])){ return $this->chunks[$chunkHash]; } @@ -2225,10 +2223,6 @@ class World implements ChunkManager{ $this->logger->critical("Failed to load chunk x=$x z=$z: " . $e->getMessage()); } - if($chunk === null and $create){ - $chunk = new Chunk($x, $z); - } - $this->timings->syncChunkLoadDataTimer->stopTiming(); if($chunk === null){ @@ -2241,7 +2235,7 @@ class World implements ChunkManager{ $this->initChunk($chunk); - (new ChunkLoadEvent($this, $chunk, !$chunk->isGenerated()))->call(); + (new ChunkLoadEvent($this, $chunk, false))->call(); if(!$this->isChunkInUse($x, $z)){ $this->logger->debug("Newly loaded chunk $x $z has no loaders registered, will be unloaded at next available opportunity"); @@ -2390,7 +2384,7 @@ class World implements ChunkManager{ $max = $this->worldHeight; $v = $spawn->floor(); - $chunk = $this->getOrLoadChunkAtPosition($v, false); + $chunk = $this->getOrLoadChunkAtPosition($v); if($chunk === null || !$chunk->isGenerated()){ throw new WorldException("Cannot find a safe spawn point in non-generated terrain"); } @@ -2513,7 +2507,7 @@ class World implements ChunkManager{ } } - $chunk = $this->loadChunk($x, $z, false); + $chunk = $this->loadChunk($x, $z); if($chunk === null){ $chunk = new Chunk($x, $z); } From dde2e7e66faa16ace79af9aec6488b64f1d8d0b5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 3 Dec 2020 19:28:22 +0000 Subject: [PATCH 2180/3224] generation: drop AsyncWorker thread-local storage in favour of a more specialized storage --- src/world/generator/GeneratorRegisterTask.php | 4 +- .../generator/GeneratorUnregisterTask.php | 3 +- src/world/generator/PopulationTask.php | 7 ++- .../generator/ThreadLocalGeneratorContext.php | 63 +++++++++++++++++++ 4 files changed, 69 insertions(+), 8 deletions(-) create mode 100644 src/world/generator/ThreadLocalGeneratorContext.php diff --git a/src/world/generator/GeneratorRegisterTask.php b/src/world/generator/GeneratorRegisterTask.php index 31b038791e..62958b60db 100644 --- a/src/world/generator/GeneratorRegisterTask.php +++ b/src/world/generator/GeneratorRegisterTask.php @@ -60,13 +60,11 @@ class GeneratorRegisterTask extends AsyncTask{ public function onRun() : void{ $manager = new SimpleChunkManager($this->worldHeight); - $this->worker->saveToThreadStore("generation.world{$this->worldId}.manager", $manager); - /** * @var Generator $generator * @see Generator::__construct() */ $generator = new $this->generatorClass($this->seed, igbinary_unserialize($this->settings)); - $this->worker->saveToThreadStore("generation.world{$this->worldId}.generator", $generator); + ThreadLocalGeneratorContext::register(new ThreadLocalGeneratorContext($generator, $manager), $this->worldId); } } diff --git a/src/world/generator/GeneratorUnregisterTask.php b/src/world/generator/GeneratorUnregisterTask.php index 5a4d91387a..c9022e9e2b 100644 --- a/src/world/generator/GeneratorUnregisterTask.php +++ b/src/world/generator/GeneratorUnregisterTask.php @@ -36,7 +36,6 @@ class GeneratorUnregisterTask extends AsyncTask{ } public function onRun() : void{ - $this->worker->removeFromThreadStore("generation.world{$this->worldId}.manager"); - $this->worker->removeFromThreadStore("generation.world{$this->worldId}.generator"); + ThreadLocalGeneratorContext::unregister($this->worldId); } } diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 9b5d107ce9..8c6c22dc6e 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -72,12 +72,13 @@ class PopulationTask extends AsyncTask{ } public function onRun() : void{ - $manager = $this->worker->getFromThreadStore("generation.world{$this->worldId}.manager"); - $generator = $this->worker->getFromThreadStore("generation.world{$this->worldId}.generator"); - if(!($manager instanceof SimpleChunkManager) or !($generator instanceof Generator)){ + $context = ThreadLocalGeneratorContext::fetch($this->worldId); + if($context === null){ $this->state = false; return; } + $generator = $context->getGenerator(); + $manager = $context->getChunkManager(); /** @var Chunk[] $chunks */ $chunks = []; diff --git a/src/world/generator/ThreadLocalGeneratorContext.php b/src/world/generator/ThreadLocalGeneratorContext.php new file mode 100644 index 0000000000..9a240f5018 --- /dev/null +++ b/src/world/generator/ThreadLocalGeneratorContext.php @@ -0,0 +1,63 @@ + + */ + private static $contexts = []; + + public static function register(self $context, int $worldId) : void{ + self::$contexts[$worldId] = $context; + } + + public static function unregister(int $worldId) : void{ + unset(self::$contexts[$worldId]); + } + + public static function fetch(int $worldId) : ?self{ + return self::$contexts[$worldId] ?? null; + } + + /** @var Generator */ + private $generator; + /** @var SimpleChunkManager */ + private $chunkManager; + + public function __construct(Generator $generator, SimpleChunkManager $chunkManager){ + $this->generator = $generator; + $this->chunkManager = $chunkManager; + } + + public function getGenerator() : Generator{ return $this->generator; } + + public function getChunkManager() : SimpleChunkManager{ return $this->chunkManager; } +} From 7edfa3713b892ebd516f225f9b4fad850e72e998 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 3 Dec 2020 19:46:23 +0000 Subject: [PATCH 2181/3224] Do not persist SimpleChunkManager between async tasks this is just asking for memory leaks. --- src/world/generator/GeneratorRegisterTask.php | 4 +--- src/world/generator/PopulationTask.php | 4 +--- src/world/generator/ThreadLocalGeneratorContext.php | 12 +++++------- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/world/generator/GeneratorRegisterTask.php b/src/world/generator/GeneratorRegisterTask.php index 62958b60db..79957df50a 100644 --- a/src/world/generator/GeneratorRegisterTask.php +++ b/src/world/generator/GeneratorRegisterTask.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\world\generator; use pocketmine\scheduler\AsyncTask; -use pocketmine\world\SimpleChunkManager; use pocketmine\world\World; use function igbinary_serialize; use function igbinary_unserialize; @@ -59,12 +58,11 @@ class GeneratorRegisterTask extends AsyncTask{ } public function onRun() : void{ - $manager = new SimpleChunkManager($this->worldHeight); /** * @var Generator $generator * @see Generator::__construct() */ $generator = new $this->generatorClass($this->seed, igbinary_unserialize($this->settings)); - ThreadLocalGeneratorContext::register(new ThreadLocalGeneratorContext($generator, $manager), $this->worldId); + ThreadLocalGeneratorContext::register(new ThreadLocalGeneratorContext($generator, $this->worldHeight), $this->worldId); } } diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 8c6c22dc6e..377acc34ec 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -78,7 +78,7 @@ class PopulationTask extends AsyncTask{ return; } $generator = $context->getGenerator(); - $manager = $context->getChunkManager(); + $manager = new SimpleChunkManager($context->getWorldHeight()); /** @var Chunk[] $chunks */ $chunks = []; @@ -124,8 +124,6 @@ class PopulationTask extends AsyncTask{ foreach($chunks as $i => $c){ $this->{"chunk$i"} = $c->isDirty() ? FastChunkSerializer::serializeWithoutLight($c) : null; } - - $manager->cleanChunks(); } public function onCompletion() : void{ diff --git a/src/world/generator/ThreadLocalGeneratorContext.php b/src/world/generator/ThreadLocalGeneratorContext.php index 9a240f5018..ebdd8ee274 100644 --- a/src/world/generator/ThreadLocalGeneratorContext.php +++ b/src/world/generator/ThreadLocalGeneratorContext.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\world\generator; -use pocketmine\world\SimpleChunkManager; - /** * Manages thread-local caches for generators and the things needed to support them */ @@ -49,15 +47,15 @@ final class ThreadLocalGeneratorContext{ /** @var Generator */ private $generator; - /** @var SimpleChunkManager */ - private $chunkManager; + /** @var int */ + private $worldHeight; - public function __construct(Generator $generator, SimpleChunkManager $chunkManager){ + public function __construct(Generator $generator, int $worldHeight){ $this->generator = $generator; - $this->chunkManager = $chunkManager; + $this->worldHeight = $worldHeight; } public function getGenerator() : Generator{ return $this->generator; } - public function getChunkManager() : SimpleChunkManager{ return $this->chunkManager; } + public function getWorldHeight() : int{ return $this->worldHeight; } } From 5b1fa25dffdf7956ccf8de377a4006aaba7cb0bc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 3 Dec 2020 20:29:41 +0000 Subject: [PATCH 2182/3224] LightPopulationTask: remove useless @var --- src/world/light/LightPopulationTask.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index 80f814cefd..25828b1175 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -60,7 +60,6 @@ class LightPopulationTask extends AsyncTask{ } public function onRun() : void{ - /** @var Chunk $chunk */ $chunk = FastChunkSerializer::deserialize($this->chunk); $manager = new SimpleChunkManager(); From 1f5998d24c89e8a160685e3e9c96f4e95dc3dcda Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 3 Dec 2020 20:52:33 +0000 Subject: [PATCH 2183/3224] FastChunkSerializer no longer encodes chunk coordinates in cases like PopulationTask it makes more sense to store the coordinates separately where they can be stored more efficiently (once instead of 9 times) In addition, PopulationTask shouldn't need to serialize an empty chunk just to copy coordinates. I've made changes like this in other areas already in preparation for the day when chunks no longer contain their coordinates, so this brings us one step closer to that goal. --- src/network/mcpe/ChunkRequestTask.php | 2 +- src/world/format/io/FastChunkSerializer.php | 8 ++----- src/world/generator/PopulationTask.php | 25 +++++++++++++++------ src/world/light/LightPopulationTask.php | 2 +- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php index d90e0cd32d..395a536b20 100644 --- a/src/network/mcpe/ChunkRequestTask.php +++ b/src/network/mcpe/ChunkRequestTask.php @@ -66,7 +66,7 @@ class ChunkRequestTask extends AsyncTask{ } public function onRun() : void{ - $chunk = FastChunkSerializer::deserialize($this->chunk); + $chunk = FastChunkSerializer::deserialize($this->chunk, $this->chunkX, $this->chunkZ); $subCount = ChunkSerializer::getSubChunkCount($chunk); $payload = ChunkSerializer::serialize($chunk, RuntimeBlockMapping::getInstance(), $this->tiles); $this->setResult($this->compressor->compress(PacketBatch::fromPackets(LevelChunkPacket::withoutCache($this->chunkX, $this->chunkZ, $subCount, $payload))->getBuffer())); diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index b180c75bb9..3151a7bb6c 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -61,8 +61,6 @@ final class FastChunkSerializer{ $includeLight = $includeLight && $chunk->isLightPopulated() === true; $stream = new BinaryStream(); - $stream->putInt($chunk->getX()); - $stream->putInt($chunk->getZ()); $stream->putByte( ($includeLight ? self::FLAG_HAS_LIGHT : 0) | ($chunk->isPopulated() ? self::FLAG_POPULATED : 0) | @@ -109,11 +107,9 @@ final class FastChunkSerializer{ /** * Deserializes a fast-serialized chunk */ - public static function deserialize(string $data) : Chunk{ + public static function deserialize(string $data, int $chunkX, int $chunkZ) : Chunk{ $stream = new BinaryStream($data); - $x = $stream->getInt(); - $z = $stream->getInt(); $flags = $stream->getByte(); $lightPopulated = (bool) ($flags & self::FLAG_HAS_LIGHT); $terrainPopulated = (bool) ($flags & self::FLAG_POPULATED); @@ -148,7 +144,7 @@ final class FastChunkSerializer{ } } - $chunk = new Chunk($x, $z, $subChunks, null, null, $biomeIds, $heightMap); + $chunk = new Chunk($chunkX, $chunkZ, $subChunks, null, null, $biomeIds, $heightMap); $chunk->setGenerated($terrainGenerated); $chunk->setPopulated($terrainPopulated); $chunk->setLightPopulated($lightPopulated); diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 377acc34ec..fcee7cd241 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -28,6 +28,7 @@ use pocketmine\world\format\Chunk; use pocketmine\world\format\io\FastChunkSerializer; use pocketmine\world\SimpleChunkManager; use pocketmine\world\World; +use function intdiv; class PopulationTask extends AsyncTask{ private const TLS_KEY_WORLD = "world"; @@ -36,6 +37,11 @@ class PopulationTask extends AsyncTask{ public $state; /** @var int */ public $worldId; + /** @var int */ + private $chunkX; + /** @var int */ + private $chunkZ; + /** @var string */ public $chunk; @@ -62,6 +68,8 @@ class PopulationTask extends AsyncTask{ public function __construct(World $world, Chunk $chunk){ $this->state = true; $this->worldId = $world->getId(); + $this->chunkX = $chunk->getX(); + $this->chunkZ = $chunk->getZ(); $this->chunk = FastChunkSerializer::serializeWithoutLight($chunk); foreach($world->getAdjacentChunks($chunk->getX(), $chunk->getZ()) as $i => $c){ @@ -83,7 +91,7 @@ class PopulationTask extends AsyncTask{ /** @var Chunk[] $chunks */ $chunks = []; - $chunk = FastChunkSerializer::deserialize($this->chunk); + $chunk = FastChunkSerializer::deserialize($this->chunk, $this->chunkX, $this->chunkZ); for($i = 0; $i < 9; ++$i){ if($i === 4){ @@ -93,9 +101,9 @@ class PopulationTask extends AsyncTask{ $zz = -1 + (int) ($i / 3); $ck = $this->{"chunk$i"}; if($ck === null){ - $chunks[$i] = new Chunk($chunk->getX() + $xx, $chunk->getZ() + $zz); + $chunks[$i] = new Chunk($this->chunkX + $xx, $this->chunkZ + $zz); }else{ - $chunks[$i] = FastChunkSerializer::deserialize($ck); + $chunks[$i] = FastChunkSerializer::deserialize($ck, $this->chunkX + $xx, $this->chunkZ + $zz); } } @@ -134,7 +142,7 @@ class PopulationTask extends AsyncTask{ $world->registerGeneratorToWorker($this->worker->getAsyncWorkerId()); } - $chunk = FastChunkSerializer::deserialize($this->chunk); + $chunk = FastChunkSerializer::deserialize($this->chunk, $this->chunkX, $this->chunkZ); for($i = 0; $i < 9; ++$i){ if($i === 4){ @@ -142,12 +150,15 @@ class PopulationTask extends AsyncTask{ } $c = $this->{"chunk$i"}; if($c !== null){ - $c = FastChunkSerializer::deserialize($c); - $world->generateChunkCallback($c->getX(), $c->getZ(), $this->state ? $c : null); + $xx = -1 + $i % 3; + $zz = -1 + intdiv($i, 3); + + $c = FastChunkSerializer::deserialize($c, $this->chunkX + $xx, $this->chunkZ + $zz); + $world->generateChunkCallback($this->chunkX + $xx, $this->chunkZ + $zz, $this->state ? $c : null); } } - $world->generateChunkCallback($chunk->getX(), $chunk->getZ(), $this->state ? $chunk : null); + $world->generateChunkCallback($this->chunkX, $this->chunkZ, $this->state ? $chunk : null); } } } diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index 25828b1175..3f5c59a292 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -60,7 +60,7 @@ class LightPopulationTask extends AsyncTask{ } public function onRun() : void{ - $chunk = FastChunkSerializer::deserialize($this->chunk); + $chunk = FastChunkSerializer::deserialize($this->chunk, $this->chunkX, $this->chunkZ); $manager = new SimpleChunkManager(); $manager->setChunk($this->chunkX, $this->chunkZ, $chunk); From c808095978d2699f49180230b747dc8167a2f1cf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 3 Dec 2020 21:59:30 +0000 Subject: [PATCH 2184/3224] Chunks no longer contain their own coordinates --- src/event/world/ChunkEvent.php | 12 ++++- src/event/world/ChunkLoadEvent.php | 4 +- src/network/mcpe/ChunkRequestTask.php | 2 +- src/network/mcpe/cache/ChunkCache.php | 10 ++-- src/player/Player.php | 12 ++--- src/world/ChunkListener.php | 8 +-- src/world/ChunkListenerNoOpTrait.php | 8 +-- src/world/World.php | 49 +++++++++---------- src/world/format/Chunk.php | 26 +--------- src/world/format/io/BaseWorldProvider.php | 6 +-- src/world/format/io/FastChunkSerializer.php | 4 +- src/world/format/io/FormatConverter.php | 5 +- src/world/format/io/WorldProvider.php | 1 + src/world/format/io/WritableWorldProvider.php | 2 +- src/world/format/io/leveldb/LevelDB.php | 8 ++- .../io/region/LegacyAnvilChunkTrait.php | 2 - src/world/format/io/region/McRegion.php | 2 - .../format/io/region/RegionWorldProvider.php | 7 +-- src/world/generator/Flat.php | 7 +-- src/world/generator/PopulationTask.php | 38 +++++++------- src/world/light/LightPopulationTask.php | 6 +-- tests/phpstan/configs/l8-baseline.neon | 12 +---- tests/phpunit/world/format/ChunkTest.php | 2 +- 23 files changed, 99 insertions(+), 134 deletions(-) diff --git a/src/event/world/ChunkEvent.php b/src/event/world/ChunkEvent.php index 2c5cb5e512..ebdc2be913 100644 --- a/src/event/world/ChunkEvent.php +++ b/src/event/world/ChunkEvent.php @@ -32,13 +32,23 @@ use pocketmine\world\World; abstract class ChunkEvent extends WorldEvent{ /** @var Chunk */ private $chunk; + /** @var int */ + private $chunkX; + /** @var int */ + private $chunkZ; - public function __construct(World $world, Chunk $chunk){ + public function __construct(World $world, int $chunkX, int $chunkZ, Chunk $chunk){ parent::__construct($world); $this->chunk = $chunk; + $this->chunkX = $chunkX; + $this->chunkZ = $chunkZ; } public function getChunk() : Chunk{ return $this->chunk; } + + public function getChunkX() : int{ return $this->chunkX; } + + public function getChunkZ() : int{ return $this->chunkZ; } } diff --git a/src/event/world/ChunkLoadEvent.php b/src/event/world/ChunkLoadEvent.php index a03c4ad159..f8f1ef7765 100644 --- a/src/event/world/ChunkLoadEvent.php +++ b/src/event/world/ChunkLoadEvent.php @@ -33,8 +33,8 @@ class ChunkLoadEvent extends ChunkEvent{ /** @var bool */ private $newChunk; - public function __construct(World $world, Chunk $chunk, bool $newChunk){ - parent::__construct($world, $chunk); + public function __construct(World $world, int $chunkX, int $chunkZ, Chunk $chunk, bool $newChunk){ + parent::__construct($world, $chunkX, $chunkZ, $chunk); $this->newChunk = $newChunk; } diff --git a/src/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php index 395a536b20..d90e0cd32d 100644 --- a/src/network/mcpe/ChunkRequestTask.php +++ b/src/network/mcpe/ChunkRequestTask.php @@ -66,7 +66,7 @@ class ChunkRequestTask extends AsyncTask{ } public function onRun() : void{ - $chunk = FastChunkSerializer::deserialize($this->chunk, $this->chunkX, $this->chunkZ); + $chunk = FastChunkSerializer::deserialize($this->chunk); $subCount = ChunkSerializer::getSubChunkCount($chunk); $payload = ChunkSerializer::serialize($chunk, RuntimeBlockMapping::getInstance(), $this->tiles); $this->setResult($this->compressor->compress(PacketBatch::fromPackets(LevelChunkPacket::withoutCache($this->chunkX, $this->chunkZ, $subCount, $payload))->getBuffer())); diff --git a/src/network/mcpe/cache/ChunkCache.php b/src/network/mcpe/cache/ChunkCache.php index afd1a41220..8dd8b85156 100644 --- a/src/network/mcpe/cache/ChunkCache.php +++ b/src/network/mcpe/cache/ChunkCache.php @@ -183,9 +183,9 @@ class ChunkCache implements ChunkListener{ /** * @see ChunkListener::onChunkChanged() */ - public function onChunkChanged(Chunk $chunk) : void{ + public function onChunkChanged(int $chunkX, int $chunkZ, Chunk $chunk) : void{ //FIXME: this gets fired for stuff that doesn't change terrain related things (like lighting updates) - $this->destroyOrRestart($chunk->getX(), $chunk->getZ()); + $this->destroyOrRestart($chunkX, $chunkZ); } /** @@ -200,9 +200,9 @@ class ChunkCache implements ChunkListener{ /** * @see ChunkListener::onChunkUnloaded() */ - public function onChunkUnloaded(Chunk $chunk) : void{ - $this->destroy($chunk->getX(), $chunk->getZ()); - $this->world->unregisterChunkListener($this, $chunk->getX(), $chunk->getZ()); + public function onChunkUnloaded(int $chunkX, int $chunkZ, Chunk $chunk) : void{ + $this->destroy($chunkX, $chunkZ); + $this->world->unregisterChunkListener($this, $chunkX, $chunkZ); } /** diff --git a/src/player/Player.php b/src/player/Player.php index 7051290b6f..c80c0b2b42 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2358,18 +2358,18 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ onChunkUnloaded as private; } - public function onChunkChanged(Chunk $chunk) : void{ - $status = $this->usedChunks[$hash = World::chunkHash($chunk->getX(), $chunk->getZ())] ?? null; + public function onChunkChanged(int $chunkX, int $chunkZ, Chunk $chunk) : void{ + $status = $this->usedChunks[$hash = World::chunkHash($chunkX, $chunkZ)] ?? null; if($status !== null && !$status->equals(UsedChunkStatus::NEEDED())){ $this->usedChunks[$hash] = UsedChunkStatus::NEEDED(); $this->nextChunkOrderRun = 0; } } - public function onChunkUnloaded(Chunk $chunk) : void{ - if($this->isUsingChunk($chunk->getX(), $chunk->getZ())){ - $this->logger->debug("Detected forced unload of chunk " . $chunk->getX() . " " . $chunk->getZ()); - $this->unloadChunk($chunk->getX(), $chunk->getZ()); + public function onChunkUnloaded(int $chunkX, int $chunkZ, Chunk $chunk) : void{ + if($this->isUsingChunk($chunkX, $chunkZ)){ + $this->logger->debug("Detected forced unload of chunk " . $chunkX . " " . $chunkZ); + $this->unloadChunk($chunkX, $chunkZ); } } } diff --git a/src/world/ChunkListener.php b/src/world/ChunkListener.php index 937cd0c8bf..8fafd73b00 100644 --- a/src/world/ChunkListener.php +++ b/src/world/ChunkListener.php @@ -43,23 +43,23 @@ interface ChunkListener{ /** * This method will be called when a Chunk is replaced by a new one */ - public function onChunkChanged(Chunk $chunk) : void; + public function onChunkChanged(int $chunkX, int $chunkZ, Chunk $chunk) : void; /** * This method will be called when a registered chunk is loaded */ - public function onChunkLoaded(Chunk $chunk) : void; + public function onChunkLoaded(int $chunkX, int $chunkZ, Chunk $chunk) : void; /** * This method will be called when a registered chunk is unloaded */ - public function onChunkUnloaded(Chunk $chunk) : void; + public function onChunkUnloaded(int $chunkX, int $chunkZ, Chunk $chunk) : void; /** * This method will be called when a registered chunk is populated * Usually it'll be sent with another call to onChunkChanged() */ - public function onChunkPopulated(Chunk $chunk) : void; + public function onChunkPopulated(int $chunkX, int $chunkZ, Chunk $chunk) : void; /** * This method will be called when a block changes in a registered chunk diff --git a/src/world/ChunkListenerNoOpTrait.php b/src/world/ChunkListenerNoOpTrait.php index 1d7134bcbe..b48a9659c6 100644 --- a/src/world/ChunkListenerNoOpTrait.php +++ b/src/world/ChunkListenerNoOpTrait.php @@ -32,19 +32,19 @@ use pocketmine\world\format\Chunk; */ trait ChunkListenerNoOpTrait/* implements ChunkListener*/{ - public function onChunkChanged(Chunk $chunk) : void{ + public function onChunkChanged(int $chunkX, int $chunkZ, Chunk $chunk) : void{ //NOOP } - public function onChunkLoaded(Chunk $chunk) : void{ + public function onChunkLoaded(int $chunkX, int $chunkZ, Chunk $chunk) : void{ //NOOP } - public function onChunkUnloaded(Chunk $chunk) : void{ + public function onChunkUnloaded(int $chunkX, int $chunkZ, Chunk $chunk) : void{ //NOOP } - public function onChunkPopulated(Chunk $chunk) : void{ + public function onChunkPopulated(int $chunkX, int $chunkZ, Chunk $chunk) : void{ //NOOP } diff --git a/src/world/World.php b/src/world/World.php index 6f9d4e23e6..c3b677b20c 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -461,8 +461,9 @@ class World implements ChunkManager{ } $this->unloadCallbacks = []; - foreach($this->chunks as $chunk){ - $this->unloadChunk($chunk->getX(), $chunk->getZ(), false); + foreach($this->chunks as $chunkHash => $chunk){ + self::getXZ($chunkHash, $chunkX, $chunkZ); + $this->unloadChunk($chunkX, $chunkZ, false); } $this->save(); @@ -796,7 +797,7 @@ class World implements ChunkManager{ if(count($blocks) > 512){ $chunk = $this->getChunk($chunkX, $chunkZ); foreach($this->getChunkPlayers($chunkX, $chunkZ) as $p){ - $p->onChunkChanged($chunk); + $p->onChunkChanged($chunkX, $chunkZ, $chunk); } }else{ foreach($this->createBlockUpdatePackets($blocks) as $packet){ @@ -946,7 +947,7 @@ class World implements ChunkManager{ if($lightPopulatedState !== true){ if($lightPopulatedState === false){ $this->chunks[$hash]->setLightPopulated(null); - $this->workerPool->submitTask(new LightPopulationTask($this, $this->chunks[$hash])); + $this->workerPool->submitTask(new LightPopulationTask($this, $dx + $chunkX, $dz + $chunkZ, $this->chunks[$hash])); } continue; } @@ -1023,9 +1024,10 @@ class World implements ChunkManager{ public function saveChunks() : void{ $this->timings->syncChunkSaveTimer->startTiming(); try{ - foreach($this->chunks as $chunk){ + foreach($this->chunks as $chunkHash => $chunk){ if($chunk->isDirty() and $chunk->isGenerated()){ - $this->provider->saveChunk($chunk); + self::getXZ($chunkHash, $chunkX, $chunkZ); + $this->provider->saveChunk($chunkX, $chunkZ, $chunk); $chunk->clearDirtyFlags(); } } @@ -1979,10 +1981,10 @@ class World implements ChunkManager{ $oldChunk = $this->loadChunk($x, $z); $this->setChunk($x, $z, $chunk, false); if(($oldChunk === null or !$oldChunk->isPopulated()) and $chunk->isPopulated()){ - (new ChunkPopulateEvent($this, $chunk))->call(); + (new ChunkPopulateEvent($this, $x, $z, $chunk))->call(); foreach($this->getChunkListeners($x, $z) as $listener){ - $listener->onChunkPopulated($chunk); + $listener->onChunkPopulated($x, $z, $chunk); } } } @@ -2005,9 +2007,6 @@ class World implements ChunkManager{ return; } - $chunk->setX($chunkX); - $chunk->setZ($chunkZ); - $chunkHash = World::chunkHash($chunkX, $chunkZ); $oldChunk = $this->loadChunk($chunkX, $chunkZ); if($oldChunk !== null and $oldChunk !== $chunk){ @@ -2049,14 +2048,14 @@ class World implements ChunkManager{ } if($oldChunk === null){ - (new ChunkLoadEvent($this, $chunk, true))->call(); + (new ChunkLoadEvent($this, $chunkX, $chunkZ, $chunk, true))->call(); foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){ - $listener->onChunkLoaded($chunk); + $listener->onChunkLoaded($chunkX, $chunkZ, $chunk); } }else{ foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){ - $listener->onChunkChanged($chunk); + $listener->onChunkChanged($chunkX, $chunkZ, $chunk); } } } @@ -2233,16 +2232,16 @@ class World implements ChunkManager{ $this->chunks[$chunkHash] = $chunk; unset($this->blockCache[$chunkHash]); - $this->initChunk($chunk); + $this->initChunk($x, $z, $chunk); - (new ChunkLoadEvent($this, $chunk, false))->call(); + (new ChunkLoadEvent($this, $x, $z, $chunk, false))->call(); if(!$this->isChunkInUse($x, $z)){ $this->logger->debug("Newly loaded chunk $x $z has no loaders registered, will be unloaded at next available opportunity"); $this->unloadChunkRequest($x, $z); } foreach($this->getChunkListeners($x, $z) as $listener){ - $listener->onChunkLoaded($chunk); + $listener->onChunkLoaded($x, $z, $chunk); } $this->timings->syncChunkLoadTimer->stopTiming(); @@ -2250,7 +2249,7 @@ class World implements ChunkManager{ return $chunk; } - private function initChunk(Chunk $chunk) : void{ + private function initChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ if($chunk->NBTentities !== null){ $this->timings->syncChunkLoadEntitiesTimer->startTiming(); $entityFactory = EntityFactory::getInstance(); @@ -2265,7 +2264,7 @@ class World implements ChunkManager{ }elseif($saveIdTag instanceof IntTag){ //legacy MCPE format $saveId = "legacy(" . $saveIdTag->getValue() . ")"; } - $this->getLogger()->warning("Chunk " . $chunk->getX() . " " . $chunk->getZ() . ": Deleted unknown entity type $saveId"); + $this->getLogger()->warning("Chunk $chunkX $chunkZ: Deleted unknown entity type $saveId"); continue; } }catch(\Exception $t){ //TODO: this shouldn't be here @@ -2285,7 +2284,7 @@ class World implements ChunkManager{ if(($tile = $tileFactory->createFromData($this, $nbt)) !== null){ $this->addTile($tile); }else{ - $this->getLogger()->warning("Chunk " . $chunk->getX() . " " . $chunk->getZ() . ": Deleted unknown tile entity type " . $nbt->getString("id", "")); + $this->getLogger()->warning("Chunk $chunkX $chunkZ: Deleted unknown tile entity type " . $nbt->getString("id", "")); continue; } } @@ -2330,7 +2329,7 @@ class World implements ChunkManager{ $chunk = $this->chunks[$chunkHash] ?? null; if($chunk !== null){ - $ev = new ChunkUnloadEvent($this, $chunk); + $ev = new ChunkUnloadEvent($this, $x, $z, $chunk); $ev->call(); if($ev->isCancelled()){ $this->timings->doChunkUnload->stopTiming(); @@ -2341,14 +2340,14 @@ class World implements ChunkManager{ if($trySave and $this->getAutoSave() and $chunk->isGenerated() and $chunk->isDirty()){ $this->timings->syncChunkSaveTimer->startTiming(); try{ - $this->provider->saveChunk($chunk); + $this->provider->saveChunk($x, $z, $chunk); }finally{ $this->timings->syncChunkSaveTimer->stopTiming(); } } foreach($this->getChunkListeners($x, $z) as $listener){ - $listener->onChunkUnloaded($chunk); + $listener->onChunkUnloaded($x, $z, $chunk); } $chunk->onUnload(); @@ -2509,7 +2508,7 @@ class World implements ChunkManager{ $chunk = $this->loadChunk($x, $z); if($chunk === null){ - $chunk = new Chunk($x, $z); + $chunk = new Chunk(); } if(!$chunk->isPopulated()){ Timings::$populationTimer->startTiming(); @@ -2521,7 +2520,7 @@ class World implements ChunkManager{ } } - $task = new PopulationTask($this, $chunk); + $task = new PopulationTask($this, $x, $z, $chunk); $workerId = $this->workerPool->selectWorker(); if(!isset($this->generatorRegisteredWorkers[$workerId])){ $this->registerGeneratorToWorker($workerId); diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index c18dc06542..beb2155440 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -45,11 +45,6 @@ class Chunk{ public const MAX_SUBCHUNKS = 16; - /** @var int */ - protected $x; - /** @var int */ - protected $z; - /** @var int */ private $dirtyFlags = 0; @@ -89,10 +84,7 @@ class Chunk{ * @param CompoundTag[] $entities * @param CompoundTag[] $tiles */ - public function __construct(int $chunkX, int $chunkZ, array $subChunks = [], ?array $entities = null, ?array $tiles = null, ?BiomeArray $biomeIds = null, ?HeightArray $heightMap = null){ - $this->x = $chunkX; - $this->z = $chunkZ; - + public function __construct(array $subChunks = [], ?array $entities = null, ?array $tiles = null, ?BiomeArray $biomeIds = null, ?HeightArray $heightMap = null){ $this->subChunks = new \SplFixedArray(Chunk::MAX_SUBCHUNKS); foreach($this->subChunks as $y => $null){ @@ -107,22 +99,6 @@ class Chunk{ $this->NBTentities = $entities; } - public function getX() : int{ - return $this->x; - } - - public function getZ() : int{ - return $this->z; - } - - public function setX(int $x) : void{ - $this->x = $x; - } - - public function setZ(int $z) : void{ - $this->z = $z; - } - /** * Returns the chunk height in count of subchunks. */ diff --git a/src/world/format/io/BaseWorldProvider.php b/src/world/format/io/BaseWorldProvider.php index c44bf73056..cc73a81451 100644 --- a/src/world/format/io/BaseWorldProvider.php +++ b/src/world/format/io/BaseWorldProvider.php @@ -66,11 +66,11 @@ abstract class BaseWorldProvider implements WorldProvider{ return $this->readChunk($chunkX, $chunkZ); } - public function saveChunk(Chunk $chunk) : void{ + public function saveChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ if(!$chunk->isGenerated()){ throw new \InvalidStateException("Cannot save un-generated chunk"); } - $this->writeChunk($chunk); + $this->writeChunk($chunkX, $chunkZ, $chunk); } /** @@ -78,5 +78,5 @@ abstract class BaseWorldProvider implements WorldProvider{ */ abstract protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk; - abstract protected function writeChunk(Chunk $chunk) : void; + abstract protected function writeChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void; } diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index 3151a7bb6c..16ef05d04a 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -107,7 +107,7 @@ final class FastChunkSerializer{ /** * Deserializes a fast-serialized chunk */ - public static function deserialize(string $data, int $chunkX, int $chunkZ) : Chunk{ + public static function deserialize(string $data) : Chunk{ $stream = new BinaryStream($data); $flags = $stream->getByte(); @@ -144,7 +144,7 @@ final class FastChunkSerializer{ } } - $chunk = new Chunk($chunkX, $chunkZ, $subChunks, null, null, $biomeIds, $heightMap); + $chunk = new Chunk($subChunks, null, null, $biomeIds, $heightMap); $chunk->setGenerated($terrainGenerated); $chunk->setPopulated($terrainPopulated); $chunk->setLightPopulated($lightPopulated); diff --git a/src/world/format/io/FormatConverter.php b/src/world/format/io/FormatConverter.php index 70f83cf791..7e5bb47029 100644 --- a/src/world/format/io/FormatConverter.php +++ b/src/world/format/io/FormatConverter.php @@ -138,9 +138,10 @@ class FormatConverter{ $start = microtime(true); $thisRound = $start; - foreach($this->oldProvider->getAllChunks(true, $this->logger) as $chunk){ + foreach($this->oldProvider->getAllChunks(true, $this->logger) as $coords => $chunk){ + [$chunkX, $chunkZ] = $coords; $chunk->setDirty(); - $new->saveChunk($chunk); + $new->saveChunk($chunkX, $chunkZ, $chunk); $counter++; if(($counter % $this->chunksPerProgressUpdate) === 0){ $time = microtime(true); diff --git a/src/world/format/io/WorldProvider.php b/src/world/format/io/WorldProvider.php index a81e0e5dfe..d2c858475c 100644 --- a/src/world/format/io/WorldProvider.php +++ b/src/world/format/io/WorldProvider.php @@ -75,6 +75,7 @@ interface WorldProvider{ * Returns a generator which yields all the chunks in this world. * * @return \Generator|Chunk[] + * @phpstan-return \Generator * @throws CorruptedChunkException */ public function getAllChunks(bool $skipCorrupted = false, ?\Logger $logger = null) : \Generator; diff --git a/src/world/format/io/WritableWorldProvider.php b/src/world/format/io/WritableWorldProvider.php index 82c127f3c9..58ceef4426 100644 --- a/src/world/format/io/WritableWorldProvider.php +++ b/src/world/format/io/WritableWorldProvider.php @@ -39,5 +39,5 @@ interface WritableWorldProvider extends WorldProvider{ /** * Saves a chunk (usually to disk). */ - public function saveChunk(Chunk $chunk) : void; + public function saveChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void; } diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 25512b341e..e54e51f049 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -398,8 +398,6 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ } $chunk = new Chunk( - $chunkX, - $chunkZ, $subChunks, $entities, $tiles, @@ -417,9 +415,9 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ return $chunk; } - protected function writeChunk(Chunk $chunk) : void{ + protected function writeChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ $idMap = LegacyBlockIdToStringIdMap::getInstance(); - $index = LevelDB::chunkIndex($chunk->getX(), $chunk->getZ()); + $index = LevelDB::chunkIndex($chunkX, $chunkZ); $write = new \LevelDBWriteBatch(); $write->put($index . self::TAG_VERSION, chr(self::CURRENT_LEVEL_CHUNK_VERSION)); @@ -509,7 +507,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $chunkZ = Binary::readLInt(substr($key, 4, 4)); try{ if(($chunk = $this->loadChunk($chunkX, $chunkZ)) !== null){ - yield $chunk; + yield [$chunkX, $chunkZ] => $chunk; } }catch(CorruptedChunkException $e){ if(!$skipCorrupted){ diff --git a/src/world/format/io/region/LegacyAnvilChunkTrait.php b/src/world/format/io/region/LegacyAnvilChunkTrait.php index 96c5e41803..893db968ef 100644 --- a/src/world/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/world/format/io/region/LegacyAnvilChunkTrait.php @@ -93,8 +93,6 @@ trait LegacyAnvilChunkTrait{ } $result = new Chunk( - $chunk->getInt("xPos"), - $chunk->getInt("zPos"), $subChunks, ($entitiesTag = $chunk->getTag("Entities")) instanceof ListTag ? self::getCompoundList("Entities", $entitiesTag) : [], ($tilesTag = $chunk->getTag("TileEntities")) instanceof ListTag ? self::getCompoundList("TileEntities", $tilesTag) : [], diff --git a/src/world/format/io/region/McRegion.php b/src/world/format/io/region/McRegion.php index 78288b6993..d912202d21 100644 --- a/src/world/format/io/region/McRegion.php +++ b/src/world/format/io/region/McRegion.php @@ -89,8 +89,6 @@ class McRegion extends RegionWorldProvider{ } $result = new Chunk( - $chunk->getInt("xPos"), - $chunk->getInt("zPos"), $subChunks, ($entitiesTag = $chunk->getTag("Entities")) instanceof ListTag ? self::getCompoundList("Entities", $entitiesTag) : [], ($tilesTag = $chunk->getTag("TileEntities")) instanceof ListTag ? self::getCompoundList("TileEntities", $tilesTag) : [], diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index fa2162fe11..bfd505197d 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -228,10 +228,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ return null; } - protected function writeChunk(Chunk $chunk) : void{ - $chunkX = $chunk->getX(); - $chunkZ = $chunk->getZ(); - + protected function writeChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ); $this->loadRegion($regionX, $regionZ); @@ -263,7 +260,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ try{ $chunk = $this->loadChunk($chunkX, $chunkZ); if($chunk !== null){ - yield $chunk; + yield [$chunkX, $chunkZ] => $chunk; } }catch(CorruptedChunkException $e){ if(!$skipCorrupted){ diff --git a/src/world/generator/Flat.php b/src/world/generator/Flat.php index dfa045820c..2bd8b9c507 100644 --- a/src/world/generator/Flat.php +++ b/src/world/generator/Flat.php @@ -145,7 +145,7 @@ class Flat extends Generator{ } protected function generateBaseChunk() : void{ - $this->chunk = new Chunk(0, 0); + $this->chunk = new Chunk(); $this->chunk->setGenerated(); for($Z = 0; $Z < 16; ++$Z){ @@ -170,10 +170,7 @@ class Flat extends Generator{ } public function generateChunk(ChunkManager $world, int $chunkX, int $chunkZ) : void{ - $chunk = clone $this->chunk; - $chunk->setX($chunkX); - $chunk->setZ($chunkZ); - $world->setChunk($chunkX, $chunkZ, $chunk); + $world->setChunk($chunkX, $chunkZ, clone $this->chunk); } public function populateChunk(ChunkManager $world, int $chunkX, int $chunkZ) : void{ diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index fcee7cd241..a3caf538af 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -65,14 +65,14 @@ class PopulationTask extends AsyncTask{ /** @var string */ public $chunk8; - public function __construct(World $world, Chunk $chunk){ + public function __construct(World $world, int $chunkX, int $chunkZ, Chunk $chunk){ $this->state = true; $this->worldId = $world->getId(); - $this->chunkX = $chunk->getX(); - $this->chunkZ = $chunk->getZ(); + $this->chunkX = $chunkX; + $this->chunkZ = $chunkZ; $this->chunk = FastChunkSerializer::serializeWithoutLight($chunk); - foreach($world->getAdjacentChunks($chunk->getX(), $chunk->getZ()) as $i => $c){ + foreach($world->getAdjacentChunks($chunkX, $chunkZ) as $i => $c){ $this->{"chunk$i"} = $c !== null ? FastChunkSerializer::serializeWithoutLight($c) : null; } @@ -91,40 +91,40 @@ class PopulationTask extends AsyncTask{ /** @var Chunk[] $chunks */ $chunks = []; - $chunk = FastChunkSerializer::deserialize($this->chunk, $this->chunkX, $this->chunkZ); + $chunk = FastChunkSerializer::deserialize($this->chunk); for($i = 0; $i < 9; ++$i){ if($i === 4){ continue; } - $xx = -1 + $i % 3; - $zz = -1 + (int) ($i / 3); $ck = $this->{"chunk$i"}; if($ck === null){ - $chunks[$i] = new Chunk($this->chunkX + $xx, $this->chunkZ + $zz); + $chunks[$i] = new Chunk(); }else{ - $chunks[$i] = FastChunkSerializer::deserialize($ck, $this->chunkX + $xx, $this->chunkZ + $zz); + $chunks[$i] = FastChunkSerializer::deserialize($ck); } } - $manager->setChunk($chunk->getX(), $chunk->getZ(), $chunk); + $manager->setChunk($this->chunkX, $this->chunkZ, $chunk); if(!$chunk->isGenerated()){ - $generator->generateChunk($manager, $chunk->getX(), $chunk->getZ()); - $chunk = $manager->getChunk($chunk->getX(), $chunk->getZ()); + $generator->generateChunk($manager, $this->chunkX, $this->chunkZ); + $chunk = $manager->getChunk($this->chunkX, $this->chunkZ); $chunk->setGenerated(); } foreach($chunks as $i => $c){ - $manager->setChunk($c->getX(), $c->getZ(), $c); + $cX = (-1 + $i % 3) + $this->chunkX; + $cZ = (-1 + intdiv($i, 3)) + $this->chunkZ; + $manager->setChunk($cX, $cZ, $c); if(!$c->isGenerated()){ - $generator->generateChunk($manager, $c->getX(), $c->getZ()); - $chunks[$i] = $manager->getChunk($c->getX(), $c->getZ()); + $generator->generateChunk($manager, $cX, $cZ); + $chunks[$i] = $manager->getChunk($cX, $cZ); $chunks[$i]->setGenerated(); } } - $generator->populateChunk($manager, $chunk->getX(), $chunk->getZ()); - $chunk = $manager->getChunk($chunk->getX(), $chunk->getZ()); + $generator->populateChunk($manager, $this->chunkX, $this->chunkZ); + $chunk = $manager->getChunk($this->chunkX, $this->chunkZ); $chunk->setPopulated(); $this->chunk = FastChunkSerializer::serializeWithoutLight($chunk); @@ -142,7 +142,7 @@ class PopulationTask extends AsyncTask{ $world->registerGeneratorToWorker($this->worker->getAsyncWorkerId()); } - $chunk = FastChunkSerializer::deserialize($this->chunk, $this->chunkX, $this->chunkZ); + $chunk = FastChunkSerializer::deserialize($this->chunk); for($i = 0; $i < 9; ++$i){ if($i === 4){ @@ -153,7 +153,7 @@ class PopulationTask extends AsyncTask{ $xx = -1 + $i % 3; $zz = -1 + intdiv($i, 3); - $c = FastChunkSerializer::deserialize($c, $this->chunkX + $xx, $this->chunkZ + $zz); + $c = FastChunkSerializer::deserialize($c); $world->generateChunkCallback($this->chunkX + $xx, $this->chunkZ + $zz, $this->state ? $c : null); } } diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index 3f5c59a292..f69ac46a9b 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -52,15 +52,15 @@ class LightPopulationTask extends AsyncTask{ /** @var string */ private $resultBlockLightArrays; - public function __construct(World $world, Chunk $chunk){ + public function __construct(World $world, int $chunkX, int $chunkZ, Chunk $chunk){ $this->storeLocal(self::TLS_KEY_WORLD, $world); - [$this->chunkX, $this->chunkZ] = [$chunk->getX(), $chunk->getZ()]; + [$this->chunkX, $this->chunkZ] = [$chunkX, $chunkZ]; $chunk->setLightPopulated(null); $this->chunk = FastChunkSerializer::serialize($chunk); } public function onRun() : void{ - $chunk = FastChunkSerializer::deserialize($this->chunk, $this->chunkX, $this->chunkZ); + $chunk = FastChunkSerializer::deserialize($this->chunk); $manager = new SimpleChunkManager(); $manager->setChunk($this->chunkX, $this->chunkZ, $chunk); diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index e7f7642c47..baca76de0b 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -526,7 +526,7 @@ parameters: path: ../../../src/world/Explosion.php - - message: "#^Parameter \\#1 \\$chunk of method pocketmine\\\\player\\\\Player\\:\\:onChunkChanged\\(\\) expects pocketmine\\\\world\\\\format\\\\Chunk, pocketmine\\\\world\\\\format\\\\Chunk\\|null given\\.$#" + message: "#^Parameter \\#3 \\$chunk of method pocketmine\\\\player\\\\Player\\:\\:onChunkChanged\\(\\) expects pocketmine\\\\world\\\\format\\\\Chunk, pocketmine\\\\world\\\\format\\\\Chunk\\|null given\\.$#" count: 1 path: ../../../src/world/World.php @@ -595,16 +595,6 @@ parameters: count: 2 path: ../../../src/world/generator/PopulationTask.php - - - message: "#^Cannot call method getX\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 5 - path: ../../../src/world/generator/PopulationTask.php - - - - message: "#^Cannot call method getZ\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 5 - path: ../../../src/world/generator/PopulationTask.php - - message: "#^Cannot call method isGenerated\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" count: 1 diff --git a/tests/phpunit/world/format/ChunkTest.php b/tests/phpunit/world/format/ChunkTest.php index 17d277b528..c557c65c3e 100644 --- a/tests/phpunit/world/format/ChunkTest.php +++ b/tests/phpunit/world/format/ChunkTest.php @@ -28,7 +28,7 @@ use PHPUnit\Framework\TestCase; class ChunkTest extends TestCase{ public function testClone() : void{ - $chunk = new Chunk(0, 0); + $chunk = new Chunk(); $chunk->setFullBlock(0, 0, 0, 1); $chunk->setBiomeId(0, 0, 1); $chunk->setHeightMap(0, 0, 1); From 05ab44f768e29cbc4aa65a11231432fa7d677986 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 3 Dec 2020 22:12:42 +0000 Subject: [PATCH 2185/3224] PopulationTask no longer creates chunks if they don't exist creating a throwaway empty chunk on the main thread is pointless. --- src/world/World.php | 5 +---- src/world/generator/PopulationTask.php | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index c3b677b20c..0c3ea599cb 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2507,10 +2507,7 @@ class World implements ChunkManager{ } $chunk = $this->loadChunk($x, $z); - if($chunk === null){ - $chunk = new Chunk(); - } - if(!$chunk->isPopulated()){ + if($chunk === null || !$chunk->isPopulated()){ Timings::$populationTimer->startTiming(); $this->chunkPopulationQueue[$index] = true; diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index a3caf538af..2745d19a14 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -42,35 +42,35 @@ class PopulationTask extends AsyncTask{ /** @var int */ private $chunkZ; - /** @var string */ + /** @var string|null */ public $chunk; - /** @var string */ + /** @var string|null */ public $chunk0; - /** @var string */ + /** @var string|null */ public $chunk1; - /** @var string */ + /** @var string|null */ public $chunk2; - /** @var string */ + /** @var string|null */ public $chunk3; //center chunk - /** @var string */ + /** @var string|null */ public $chunk5; - /** @var string */ + /** @var string|null */ public $chunk6; - /** @var string */ + /** @var string|null */ public $chunk7; - /** @var string */ + /** @var string|null */ public $chunk8; - public function __construct(World $world, int $chunkX, int $chunkZ, Chunk $chunk){ + public function __construct(World $world, int $chunkX, int $chunkZ, ?Chunk $chunk){ $this->state = true; $this->worldId = $world->getId(); $this->chunkX = $chunkX; $this->chunkZ = $chunkZ; - $this->chunk = FastChunkSerializer::serializeWithoutLight($chunk); + $this->chunk = $chunk !== null ? FastChunkSerializer::serializeWithoutLight($chunk) : null; foreach($world->getAdjacentChunks($chunkX, $chunkZ) as $i => $c){ $this->{"chunk$i"} = $c !== null ? FastChunkSerializer::serializeWithoutLight($c) : null; @@ -91,7 +91,7 @@ class PopulationTask extends AsyncTask{ /** @var Chunk[] $chunks */ $chunks = []; - $chunk = FastChunkSerializer::deserialize($this->chunk); + $chunk = $this->chunk !== null ? FastChunkSerializer::deserialize($this->chunk) : new Chunk(); for($i = 0; $i < 9; ++$i){ if($i === 4){ @@ -142,7 +142,7 @@ class PopulationTask extends AsyncTask{ $world->registerGeneratorToWorker($this->worker->getAsyncWorkerId()); } - $chunk = FastChunkSerializer::deserialize($this->chunk); + $chunk = $this->chunk !== null ? FastChunkSerializer::deserialize($this->chunk) : null; for($i = 0; $i < 9; ++$i){ if($i === 4){ From b9cd633ceedb18005f113eab3d024132867b785e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 3 Dec 2020 22:28:43 +0000 Subject: [PATCH 2186/3224] Chunks no longer exist in un-generated state a non-generated chunk is now always represented by NULL. This forces the case of ungenerated chunks to be handled by all code, which is necessary because ungenerated chunks cannot be interacted with or modified in any meaningful way. --- src/world/World.php | 10 +- src/world/format/Chunk.php | 11 --- src/world/format/io/BaseWorldProvider.php | 3 - src/world/format/io/FastChunkSerializer.php | 95 +++++++++---------- src/world/format/io/leveldb/LevelDB.php | 1 - .../io/region/LegacyAnvilChunkTrait.php | 1 - src/world/format/io/region/McRegion.php | 1 - src/world/generator/Flat.php | 1 - src/world/generator/PopulationTask.php | 14 +-- tests/phpstan/configs/l8-baseline.neon | 19 +--- 10 files changed, 59 insertions(+), 97 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 0c3ea599cb..fe6d4c2c2e 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -936,7 +936,6 @@ class World implements ChunkManager{ $hash = World::chunkHash($dx + $chunkX, $dz + $chunkZ); if(!isset($chunkTickList[$hash]) and isset($this->chunks[$hash])){ if( - !$this->chunks[$hash]->isGenerated() || !$this->chunks[$hash]->isPopulated() || $this->isChunkLocked($dx + $chunkX, $dz + $chunkZ) ){ @@ -1025,7 +1024,7 @@ class World implements ChunkManager{ $this->timings->syncChunkSaveTimer->startTiming(); try{ foreach($this->chunks as $chunkHash => $chunk){ - if($chunk->isDirty() and $chunk->isGenerated()){ + if($chunk->isDirty()){ self::getXZ($chunkHash, $chunkX, $chunkZ); $this->provider->saveChunk($chunkX, $chunkZ, $chunk); $chunk->clearDirtyFlags(); @@ -2085,8 +2084,7 @@ class World implements ChunkManager{ } public function isChunkGenerated(int $x, int $z) : bool{ - $chunk = $this->loadChunk($x, $z); - return $chunk !== null ? $chunk->isGenerated() : false; + return $this->loadChunk($x, $z) !== null; } public function isChunkPopulated(int $x, int $z) : bool{ @@ -2337,7 +2335,7 @@ class World implements ChunkManager{ return false; } - if($trySave and $this->getAutoSave() and $chunk->isGenerated() and $chunk->isDirty()){ + if($trySave and $this->getAutoSave() and $chunk->isDirty()){ $this->timings->syncChunkSaveTimer->startTiming(); try{ $this->provider->saveChunk($x, $z, $chunk); @@ -2384,7 +2382,7 @@ class World implements ChunkManager{ $max = $this->worldHeight; $v = $spawn->floor(); $chunk = $this->getOrLoadChunkAtPosition($v); - if($chunk === null || !$chunk->isGenerated()){ + if($chunk === null){ throw new WorldException("Cannot find a safe spawn point in non-generated terrain"); } $x = (int) $v->x; diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index beb2155440..13570b6659 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -51,8 +51,6 @@ class Chunk{ /** @var bool|null */ protected $lightPopulated = false; /** @var bool */ - protected $terrainGenerated = false; - /** @var bool */ protected $terrainPopulated = false; /** @@ -207,15 +205,6 @@ class Chunk{ $this->dirtyFlags |= self::DIRTY_FLAG_TERRAIN; } - public function isGenerated() : bool{ - return $this->terrainGenerated; - } - - public function setGenerated(bool $value = true) : void{ - $this->terrainGenerated = $value; - $this->dirtyFlags |= self::DIRTY_FLAG_TERRAIN; - } - public function addEntity(Entity $entity) : void{ if($entity->isClosed()){ throw new \InvalidArgumentException("Attempted to add a garbage closed Entity to a chunk"); diff --git a/src/world/format/io/BaseWorldProvider.php b/src/world/format/io/BaseWorldProvider.php index cc73a81451..4726402830 100644 --- a/src/world/format/io/BaseWorldProvider.php +++ b/src/world/format/io/BaseWorldProvider.php @@ -67,9 +67,6 @@ abstract class BaseWorldProvider implements WorldProvider{ } public function saveChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ - if(!$chunk->isGenerated()){ - throw new \InvalidStateException("Cannot save un-generated chunk"); - } $this->writeChunk($chunkX, $chunkZ, $chunk); } diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index 16ef05d04a..7a0f59346c 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -63,44 +63,42 @@ final class FastChunkSerializer{ $stream = new BinaryStream(); $stream->putByte( ($includeLight ? self::FLAG_HAS_LIGHT : 0) | - ($chunk->isPopulated() ? self::FLAG_POPULATED : 0) | - ($chunk->isGenerated() ? self::FLAG_GENERATED : 0) + ($chunk->isPopulated() ? self::FLAG_POPULATED : 0) ); - if($chunk->isGenerated()){ - //subchunks - $subChunks = $chunk->getSubChunks(); - $count = $subChunks->count(); - $stream->putByte($count); - foreach($subChunks as $y => $subChunk){ - $stream->putByte($y); - $stream->putInt($subChunk->getEmptyBlockId()); - $layers = $subChunk->getBlockLayers(); - $stream->putByte(count($layers)); - foreach($layers as $blocks){ - $wordArray = $blocks->getWordArray(); - $palette = $blocks->getPalette(); + //subchunks + $subChunks = $chunk->getSubChunks(); + $count = $subChunks->count(); + $stream->putByte($count); - $stream->putByte($blocks->getBitsPerBlock()); - $stream->put($wordArray); - $serialPalette = pack("L*", ...$palette); - $stream->putInt(strlen($serialPalette)); - $stream->put($serialPalette); - } + foreach($subChunks as $y => $subChunk){ + $stream->putByte($y); + $stream->putInt($subChunk->getEmptyBlockId()); + $layers = $subChunk->getBlockLayers(); + $stream->putByte(count($layers)); + foreach($layers as $blocks){ + $wordArray = $blocks->getWordArray(); + $palette = $blocks->getPalette(); - if($includeLight){ - $stream->put($subChunk->getBlockSkyLightArray()->getData()); - $stream->put($subChunk->getBlockLightArray()->getData()); - } + $stream->putByte($blocks->getBitsPerBlock()); + $stream->put($wordArray); + $serialPalette = pack("L*", ...$palette); + $stream->putInt(strlen($serialPalette)); + $stream->put($serialPalette); } - //biomes - $stream->put($chunk->getBiomeIdArray()); if($includeLight){ - $stream->put(pack("S*", ...$chunk->getHeightMapArray())); + $stream->put($subChunk->getBlockSkyLightArray()->getData()); + $stream->put($subChunk->getBlockLightArray()->getData()); } } + //biomes + $stream->put($chunk->getBiomeIdArray()); + if($includeLight){ + $stream->put(pack("S*", ...$chunk->getHeightMapArray())); + } + return $stream->getBuffer(); } @@ -113,39 +111,36 @@ final class FastChunkSerializer{ $flags = $stream->getByte(); $lightPopulated = (bool) ($flags & self::FLAG_HAS_LIGHT); $terrainPopulated = (bool) ($flags & self::FLAG_POPULATED); - $terrainGenerated = (bool) ($flags & self::FLAG_GENERATED); $subChunks = []; $biomeIds = null; $heightMap = null; - if($terrainGenerated){ - $count = $stream->getByte(); - for($subCount = 0; $subCount < $count; ++$subCount){ - $y = $stream->getByte(); - $airBlockId = $stream->getInt(); - /** @var PalettedBlockArray[] $layers */ - $layers = []; - for($i = 0, $layerCount = $stream->getByte(); $i < $layerCount; ++$i){ - $bitsPerBlock = $stream->getByte(); - $words = $stream->get(PalettedBlockArray::getExpectedWordArraySize($bitsPerBlock)); - $palette = array_values(unpack("L*", $stream->get($stream->getInt()))); + $count = $stream->getByte(); + for($subCount = 0; $subCount < $count; ++$subCount){ + $y = $stream->getByte(); + $airBlockId = $stream->getInt(); - $layers[] = PalettedBlockArray::fromData($bitsPerBlock, $words, $palette); - } - $subChunks[$y] = new SubChunk( - $airBlockId, $layers, $lightPopulated ? new LightArray($stream->get(2048)) : null, $lightPopulated ? new LightArray($stream->get(2048)) : null - ); + /** @var PalettedBlockArray[] $layers */ + $layers = []; + for($i = 0, $layerCount = $stream->getByte(); $i < $layerCount; ++$i){ + $bitsPerBlock = $stream->getByte(); + $words = $stream->get(PalettedBlockArray::getExpectedWordArraySize($bitsPerBlock)); + $palette = array_values(unpack("L*", $stream->get($stream->getInt()))); + + $layers[] = PalettedBlockArray::fromData($bitsPerBlock, $words, $palette); } + $subChunks[$y] = new SubChunk( + $airBlockId, $layers, $lightPopulated ? new LightArray($stream->get(2048)) : null, $lightPopulated ? new LightArray($stream->get(2048)) : null + ); + } - $biomeIds = new BiomeArray($stream->get(256)); - if($lightPopulated){ - $heightMap = new HeightArray(array_values(unpack("S*", $stream->get(512)))); - } + $biomeIds = new BiomeArray($stream->get(256)); + if($lightPopulated){ + $heightMap = new HeightArray(array_values(unpack("S*", $stream->get(512)))); } $chunk = new Chunk($subChunks, null, null, $biomeIds, $heightMap); - $chunk->setGenerated($terrainGenerated); $chunk->setPopulated($terrainPopulated); $chunk->setLightPopulated($lightPopulated); $chunk->clearDirtyFlags(); diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index e54e51f049..762d5d728a 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -406,7 +406,6 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ //TODO: tile ticks, biome states (?) - $chunk->setGenerated(); $chunk->setPopulated(); if($hasBeenUpgraded){ $chunk->setDirty(); //trigger rewriting chunk to disk if it was converted from an older format diff --git a/src/world/format/io/region/LegacyAnvilChunkTrait.php b/src/world/format/io/region/LegacyAnvilChunkTrait.php index 893db968ef..c61914e397 100644 --- a/src/world/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/world/format/io/region/LegacyAnvilChunkTrait.php @@ -99,7 +99,6 @@ trait LegacyAnvilChunkTrait{ $biomeArray ); $result->setPopulated($chunk->getByte("TerrainPopulated", 0) !== 0); - $result->setGenerated(); return $result; } diff --git a/src/world/format/io/region/McRegion.php b/src/world/format/io/region/McRegion.php index d912202d21..3e5633e0bc 100644 --- a/src/world/format/io/region/McRegion.php +++ b/src/world/format/io/region/McRegion.php @@ -95,7 +95,6 @@ class McRegion extends RegionWorldProvider{ $biomeIds ); $result->setPopulated($chunk->getByte("TerrainPopulated", 0) !== 0); - $result->setGenerated(true); return $result; } diff --git a/src/world/generator/Flat.php b/src/world/generator/Flat.php index 2bd8b9c507..0b3cb869ea 100644 --- a/src/world/generator/Flat.php +++ b/src/world/generator/Flat.php @@ -146,7 +146,6 @@ class Flat extends Generator{ protected function generateBaseChunk() : void{ $this->chunk = new Chunk(); - $this->chunk->setGenerated(); for($Z = 0; $Z < 16; ++$Z){ for($X = 0; $X < 16; ++$X){ diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 2745d19a14..f100dc173a 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -91,7 +91,7 @@ class PopulationTask extends AsyncTask{ /** @var Chunk[] $chunks */ $chunks = []; - $chunk = $this->chunk !== null ? FastChunkSerializer::deserialize($this->chunk) : new Chunk(); + $chunk = $this->chunk !== null ? FastChunkSerializer::deserialize($this->chunk) : null; for($i = 0; $i < 9; ++$i){ if($i === 4){ @@ -99,27 +99,29 @@ class PopulationTask extends AsyncTask{ } $ck = $this->{"chunk$i"}; if($ck === null){ - $chunks[$i] = new Chunk(); + $chunks[$i] = null; }else{ $chunks[$i] = FastChunkSerializer::deserialize($ck); } } $manager->setChunk($this->chunkX, $this->chunkZ, $chunk); - if(!$chunk->isGenerated()){ + if($chunk === null){ $generator->generateChunk($manager, $this->chunkX, $this->chunkZ); $chunk = $manager->getChunk($this->chunkX, $this->chunkZ); - $chunk->setGenerated(); + $chunk->setDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN, true); + $chunk->setDirtyFlag(Chunk::DIRTY_FLAG_BIOMES, true); } foreach($chunks as $i => $c){ $cX = (-1 + $i % 3) + $this->chunkX; $cZ = (-1 + intdiv($i, 3)) + $this->chunkZ; $manager->setChunk($cX, $cZ, $c); - if(!$c->isGenerated()){ + if($c === null){ $generator->generateChunk($manager, $cX, $cZ); $chunks[$i] = $manager->getChunk($cX, $cZ); - $chunks[$i]->setGenerated(); + $chunks[$i]->setDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN, true); + $chunks[$i]->setDirtyFlag(Chunk::DIRTY_FLAG_BIOMES, true); } } diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index baca76de0b..0c79f23e11 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -535,16 +535,6 @@ parameters: count: 3 path: ../../../src/world/World.php - - - message: "#^Cannot call method isPopulated\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/world/World.php - - - - message: "#^Parameter \\#2 \\$chunk of class pocketmine\\\\world\\\\generator\\\\PopulationTask constructor expects pocketmine\\\\world\\\\format\\\\Chunk, pocketmine\\\\world\\\\format\\\\Chunk\\|null given\\.$#" - count: 1 - path: ../../../src/world/World.php - - message: "#^Method pocketmine\\\\world\\\\biome\\\\BiomeRegistry\\:\\:getBiome\\(\\) should return pocketmine\\\\world\\\\biome\\\\Biome but returns pocketmine\\\\world\\\\biome\\\\Biome\\|null\\.$#" count: 1 @@ -591,13 +581,8 @@ parameters: path: ../../../src/world/generator/PopulationTask.php - - message: "#^Cannot call method setGenerated\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 2 - path: ../../../src/world/generator/PopulationTask.php - - - - message: "#^Cannot call method isGenerated\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 1 + message: "#^Cannot call method setDirtyFlag\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" + count: 4 path: ../../../src/world/generator/PopulationTask.php - From 5f55cdfa76710aee86dc82e7a74a82d8c674fa21 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 3 Dec 2020 22:44:03 +0000 Subject: [PATCH 2187/3224] Cleaned out dead error patterns from phpstan level 8 baseline --- tests/phpstan/configs/l8-baseline.neon | 40 -------------------------- 1 file changed, 40 deletions(-) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 0c79f23e11..f6022b3038 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -105,11 +105,6 @@ parameters: count: 1 path: ../../../src/network/NetworkSessionManager.php - - - message: "#^Parameter \\#3 \\$chunk of class pocketmine\\\\network\\\\mcpe\\\\ChunkRequestTask constructor expects pocketmine\\\\world\\\\format\\\\Chunk, pocketmine\\\\world\\\\format\\\\Chunk\\|null given\\.$#" - count: 1 - path: ../../../src/network/mcpe/ChunkCache.php - - message: "#^Parameter \\#1 \\$entity of method pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:onEntityEffectAdded\\(\\) expects pocketmine\\\\entity\\\\Living, pocketmine\\\\player\\\\Player\\|null given\\.$#" count: 1 @@ -200,16 +195,6 @@ parameters: count: 1 path: ../../../src/network/mcpe/NetworkSession.php - - - message: "#^Cannot call method getString\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" - count: 1 - path: ../../../src/network/mcpe/convert/RuntimeBlockMapping.php - - - - message: "#^Parameter \\#1 \\$that of method pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\:\\:equals\\(\\) expects pocketmine\\\\nbt\\\\tag\\\\Tag, pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null given\\.$#" - count: 1 - path: ../../../src/network/mcpe/convert/RuntimeBlockMapping.php - - message: "#^Cannot call method getTag\\(\\) on pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\|null\\.$#" count: 1 @@ -225,16 +210,6 @@ parameters: count: 1 path: ../../../src/network/mcpe/convert/TypeConverter.php - - - message: "#^Parameter \\#1 \\$\\$encryptionKey of closure expects string, string\\|null given\\.$#" - count: 1 - path: ../../../src/network/mcpe/encryption/PrepareEncryptionTask.php - - - - message: "#^Parameter \\#2 \\$\\$handshakeJwt of closure expects string, string\\|null given\\.$#" - count: 1 - path: ../../../src/network/mcpe/encryption/PrepareEncryptionTask.php - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\LevelSoundEventPacket\\:\\:\\$position \\(pocketmine\\\\math\\\\Vector3\\) does not accept pocketmine\\\\math\\\\Vector3\\|null\\.$#" count: 1 @@ -565,21 +540,6 @@ parameters: count: 1 path: ../../../src/world/format/io/region/RegionWorldProvider.php - - - message: "#^Cannot call method saveToThreadStore\\(\\) on pocketmine\\\\scheduler\\\\AsyncWorker\\|null\\.$#" - count: 2 - path: ../../../src/world/generator/GeneratorRegisterTask.php - - - - message: "#^Cannot call method removeFromThreadStore\\(\\) on pocketmine\\\\scheduler\\\\AsyncWorker\\|null\\.$#" - count: 2 - path: ../../../src/world/generator/GeneratorUnregisterTask.php - - - - message: "#^Cannot call method getFromThreadStore\\(\\) on pocketmine\\\\scheduler\\\\AsyncWorker\\|null\\.$#" - count: 2 - path: ../../../src/world/generator/PopulationTask.php - - message: "#^Cannot call method setDirtyFlag\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" count: 4 From 5ba09b6a25b154bb45c48b2a2ab9136a62d70db7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 3 Dec 2020 23:48:40 +0000 Subject: [PATCH 2188/3224] fix PopulationTask crash --- src/world/generator/PopulationTask.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index f100dc173a..9e82ac6f21 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -105,7 +105,7 @@ class PopulationTask extends AsyncTask{ } } - $manager->setChunk($this->chunkX, $this->chunkZ, $chunk); + $manager->setChunk($this->chunkX, $this->chunkZ, $chunk ?? new Chunk()); if($chunk === null){ $generator->generateChunk($manager, $this->chunkX, $this->chunkZ); $chunk = $manager->getChunk($this->chunkX, $this->chunkZ); @@ -116,7 +116,7 @@ class PopulationTask extends AsyncTask{ foreach($chunks as $i => $c){ $cX = (-1 + $i % 3) + $this->chunkX; $cZ = (-1 + intdiv($i, 3)) + $this->chunkZ; - $manager->setChunk($cX, $cZ, $c); + $manager->setChunk($cX, $cZ, $c ?? new Chunk()); if($c === null){ $generator->generateChunk($manager, $cX, $cZ); $chunks[$i] = $manager->getChunk($cX, $cZ); From e056456dd121856cc2db2e3d8bc9a6dbcbd99662 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 4 Dec 2020 15:36:43 +0000 Subject: [PATCH 2189/3224] Player: fixed crash when stopping using a chunk before it's finished being generated --- src/player/Player.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index c80c0b2b42..e5e2031bce 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -672,9 +672,12 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $world = $world ?? $this->getWorld(); $index = World::chunkHash($x, $z); if(isset($this->usedChunks[$index])){ - foreach($world->getChunk($x, $z)->getEntities() as $entity){ - if($entity !== $this){ - $entity->despawnFrom($this); + $chunk = $world->getChunk($x, $z); + if($chunk !== null){ //this might be a chunk that hasn't been generated yet + foreach($chunk->getEntities() as $entity){ + if($entity !== $this){ + $entity->despawnFrom($this); + } } } $this->networkSession->stopUsingChunk($x, $z); From bacdb7bde551e058410e0de823f15a1ac868d56d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 4 Dec 2020 15:44:17 +0000 Subject: [PATCH 2190/3224] Make sure generator gets preemptively registered when a worker restart is detected if a PopulationTask took place after the target worker was garbage collected, the population would fail and the chunks it used would be copied for nothing. This change marks workers as having unregistered generators when detecting that a worker that previously had a generator registered is restarted. --- src/world/World.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index fe6d4c2c2e..0f403dc2d2 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -87,6 +87,7 @@ use pocketmine\world\sound\Sound; use pocketmine\world\utils\SubChunkExplorer; use function abs; use function array_fill_keys; +use function array_key_exists; use function array_map; use function array_merge; use function array_sum; @@ -405,6 +406,16 @@ class World implements ChunkManager{ } $this->timings = new WorldTimings($this); + + $this->workerPool->addWorkerStartHook($workerStartHook = function(int $workerId) : void{ + if(array_key_exists($workerId, $this->generatorRegisteredWorkers)){ + $this->logger->debug("Worker $workerId with previously registered generator restarted, flagging as unregistered"); + unset($this->generatorRegisteredWorkers[$workerId]); + } + }); + $this->addOnUnloadCallback(function() use ($workerStartHook) : void{ + $this->workerPool->removeWorkerStartHook($workerStartHook); + }); } public function getTickRateTime() : float{ @@ -412,8 +423,9 @@ class World implements ChunkManager{ } public function registerGeneratorToWorker(int $worker) : void{ - $this->generatorRegisteredWorkers[$worker] = true; + $this->logger->debug("Registering generator on worker $worker"); $this->workerPool->submitTaskToWorker(new GeneratorRegisterTask($this, $this->generator, $this->provider->getWorldData()->getGeneratorOptions()), $worker); + $this->generatorRegisteredWorkers[$worker] = true; } public function unregisterGenerator() : void{ From 1c49cedc8cc378a8a1cc62cd25ef33efa7110bbc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 4 Dec 2020 15:49:35 +0000 Subject: [PATCH 2191/3224] World: disallow block placement and breaking in unloaded, ungenerated and locked chunks --- src/world/World.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index 0f403dc2d2..8200010aa5 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1509,6 +1509,13 @@ class World implements ChunkManager{ */ public function useBreakOn(Vector3 $vector, Item &$item = null, ?Player $player = null, bool $createParticles = false) : bool{ $vector = $vector->floor(); + + $chunkX = $vector->getFloorX() >> 4; + $chunkZ = $vector->getFloorZ() >> 4; + if(!$this->isChunkLoaded($chunkX, $chunkZ) || !$this->isChunkGenerated($chunkX, $chunkZ) || $this->isChunkLocked($chunkX, $chunkZ)){ + return false; + } + $target = $this->getBlock($vector); $affectedBlocks = $target->getAffectedBlocks(); @@ -1614,6 +1621,11 @@ class World implements ChunkManager{ //TODO: build height limit messages for custom world heights and mcregion cap return false; } + $chunkX = $blockReplace->getPos()->getFloorX() >> 4; + $chunkZ = $blockReplace->getPos()->getFloorZ() >> 4; + if(!$this->isChunkLoaded($chunkX, $chunkZ) || !$this->isChunkGenerated($chunkX, $chunkZ) || $this->isChunkLocked($chunkX, $chunkZ)){ + return false; + } if($blockClicked->getId() === BlockLegacyIds::AIR){ return false; From 37b969484512ca1757343dd921a3d7cb6a6d5456 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 4 Dec 2020 20:44:03 +0000 Subject: [PATCH 2192/3224] ConsumingItemAnimation: fixed itemID translation for 1.16.100 --- src/entity/animation/ConsumingItemAnimation.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/entity/animation/ConsumingItemAnimation.php b/src/entity/animation/ConsumingItemAnimation.php index 767d22caf9..4f3e34ba4c 100644 --- a/src/entity/animation/ConsumingItemAnimation.php +++ b/src/entity/animation/ConsumingItemAnimation.php @@ -25,6 +25,7 @@ namespace pocketmine\entity\animation; use pocketmine\entity\Human; use pocketmine\item\Item; +use pocketmine\network\mcpe\convert\ItemTranslator; use pocketmine\network\mcpe\protocol\ActorEventPacket; final class ConsumingItemAnimation implements Animation{ @@ -41,9 +42,10 @@ final class ConsumingItemAnimation implements Animation{ } public function encode() : array{ + [$netId, $netData] = ItemTranslator::getInstance()->toNetworkId($this->item->getId(), $this->item->getMeta()); return [ //TODO: need to check the data values - ActorEventPacket::create($this->human->getId(), ActorEventPacket::EATING_ITEM, ($this->item->getId() << 16) | $this->item->getMeta()) + ActorEventPacket::create($this->human->getId(), ActorEventPacket::EATING_ITEM, ($netId << 16) | $netData) ]; } } From 03b1ea766aa5821ebc18eee86506317bd91a7d32 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Fri, 4 Dec 2020 21:21:25 +0000 Subject: [PATCH 2193/3224] Added a DedicatedQueryNetworkInterface to ensure Query functionality when RakLibInterface is disabled (#3942) --- src/Server.php | 10 +- .../query/DedicatedQueryNetworkInterface.php | 163 ++++++++++++++++++ 2 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 src/network/query/DedicatedQueryNetworkInterface.php diff --git a/src/Server.php b/src/Server.php index 0e2084762f..c1be895c91 100644 --- a/src/Server.php +++ b/src/Server.php @@ -60,6 +60,7 @@ use pocketmine\network\mcpe\raklib\RakLibInterface; use pocketmine\network\Network; use pocketmine\network\query\QueryHandler; use pocketmine\network\query\QueryInfo; +use pocketmine\network\query\DedicatedQueryNetworkInterface; use pocketmine\network\upnp\UPnP; use pocketmine\permission\BanList; use pocketmine\permission\DefaultPermissions; @@ -1037,10 +1038,15 @@ class Server{ $this->enablePlugins(PluginEnableOrder::POSTWORLD()); - $this->network->registerInterface(new RakLibInterface($this)); + $useQuery = $this->configGroup->getConfigBool("enable-query", true); + if(!$this->network->registerInterface(new RakLibInterface($this)) && $useQuery){ + //RakLib would normally handle the transport for Query packets + //if it's not registered we need to make sure Query still works + $this->network->registerInterface(new DedicatedQueryNetworkInterface($this->getIp(), $this->getPort(), new \PrefixedLogger($this->logger, "Dedicated Query Interface"))); + } $this->logger->info($this->getLanguage()->translateString("pocketmine.server.networkStart", [$this->getIp(), $this->getPort()])); - if($this->configGroup->getConfigBool("enable-query", true)){ + if($useQuery){ $this->network->registerRawPacketHandler(new QueryHandler($this)); } diff --git a/src/network/query/DedicatedQueryNetworkInterface.php b/src/network/query/DedicatedQueryNetworkInterface.php new file mode 100644 index 0000000000..5a083a9e34 --- /dev/null +++ b/src/network/query/DedicatedQueryNetworkInterface.php @@ -0,0 +1,163 @@ + timeout time + * @phpstan-var array + */ + private $blockedIps = []; + /** @var string[] */ + private $rawPacketPatterns = []; + + public function __construct(string $ip, int $port, \Logger $logger){ + $this->ip = $ip; + $this->port = $port; + $this->logger = $logger; + + $socket = @socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); + if($socket === false){ + throw new \RuntimeException("Failed to create socket"); + } + $this->socket = $socket; + } + + public function start() : void{ + if(!@socket_bind($this->socket, $this->ip, $this->port)){ + $error = socket_last_error($this->socket); + if($error === SOCKET_EADDRINUSE){ //platform error messages aren't consistent + throw new \RuntimeException("Failed to bind socket: Something else is already running on $this->ip $this->port", $error); + } + throw new \RuntimeException("Failed to bind to $this->ip $this->port: " . trim(socket_strerror($error)), $error); + } + socket_set_nonblock($this->socket); + $this->logger->info("Running on $this->ip $this->port"); + } + + public function setName(string $name) : void{ + //NOOP + } + + public function tick() : void{ + $r = [$this->socket]; + $w = null; + $e = null; + if(@socket_select($r, $w, $e, 0, 0) === 1){ + $address = ""; + $port = 0; + $buffer = ""; + while(true){ + $bytes = @socket_recvfrom($this->socket, $buffer, 65535, 0, $address, $port); + if($bytes !== false){ + if(isset($this->blockedIps[$address]) && $this->blockedIps[$address] > time()){ + $this->logger->debug("Dropped packet from banned address $address"); + continue; + } + foreach($this->rawPacketPatterns as $pattern){ + if(preg_match($pattern, $buffer) === 1){ + $this->network->processRawPacket($this, $address, $port, $buffer); + break; + } + } + }else{ + $errno = socket_last_error($this->socket); + if($errno === SOCKET_EWOULDBLOCK){ + break; + } + if($errno !== SOCKET_ECONNRESET){ //remote peer disappeared unexpectedly, this might spam like crazy so we don't log it + $this->logger->debug("Failed to recv (errno $errno): " . trim(socket_strerror($errno))); + } + } + } + } + } + + public function blockAddress(string $address, int $timeout = 300) : void{ + $this->blockedIps[$address] = $timeout > 0 ? time() + $timeout : PHP_INT_MAX; + } + + public function unblockAddress(string $address) : void{ + unset($this->blockedIps[$address]); + } + + public function setNetwork(Network $network) : void{ + $this->network = $network; + } + + public function sendRawPacket(string $address, int $port, string $payload) : void{ + if(@socket_sendto($this->socket, $payload, strlen($payload), 0, $address, $port) === false){ + $errno = socket_last_error($this->socket); + throw new \RuntimeException("Failed to send to $address $port (errno $errno): " . trim(socket_strerror($errno)), $errno); + } + } + + public function addRawPacketFilter(string $regex) : void{ + $this->rawPacketPatterns[] = $regex; + } + + public function shutdown() : void{ + @socket_close($this->socket); + } +} From d728160a77d5893fa6a9e212e34830a6e3f94f94 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 5 Dec 2020 00:53:22 +0000 Subject: [PATCH 2194/3224] Removed the cycle between Entity and Chunk it's now the World's responsibility to manage adding/removing entities from appropriate chunks. Entities no longer know or care that chunks exist. Entity->checkChunks() remains as-is for backwards compatibility - now it just calls the world to sync its position. --- src/entity/Entity.php | 67 ++++--------------------------------------- src/world/World.php | 56 ++++++++++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 64 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index adf689f730..1931e980c3 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -53,7 +53,6 @@ use pocketmine\player\Player; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; -use pocketmine\world\format\Chunk; use pocketmine\world\Position; use pocketmine\world\sound\Sound; use pocketmine\world\World; @@ -97,12 +96,8 @@ abstract class Entity{ /** @var EntityMetadataCollection */ private $networkProperties; - /** @var Chunk|null */ - public $chunk; - /** @var int */ - private $chunkX; - /** @var int */ - private $chunkZ; + /** @var Location */ + private $worldLastKnownLocation; /** @var EntityDamageEvent|null */ protected $lastDamageCause = null; @@ -234,6 +229,7 @@ abstract class Entity{ $this->server = $location->getWorld()->getServer(); $this->location = $location->asLocation(); + $this->worldLastKnownLocation = $this->location->asLocation(); assert( !is_nan($this->location->x) and !is_infinite($this->location->x) and !is_nan($this->location->y) and !is_infinite($this->location->y) and @@ -243,13 +239,6 @@ abstract class Entity{ $this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0); $this->recalculateBoundingBox(); - $this->chunk = $this->getWorld()->getOrLoadChunkAtPosition($this->location); - if($this->chunk === null){ - throw new \InvalidStateException("Cannot create entities in unloaded chunks"); - } - $this->chunkX = $this->location->getFloorX() >> 4; - $this->chunkZ = $this->location->getFloorZ() >> 4; - if($nbt !== null){ $this->motion = EntityDataHelper::parseVec3($nbt, "Motion", true); }else{ @@ -265,7 +254,6 @@ abstract class Entity{ $this->initEntity($nbt ?? new CompoundTag()); - $this->chunk->addEntity($this); $this->getWorld()->addEntity($this); $this->lastUpdate = $this->server->getTick(); @@ -1360,45 +1348,8 @@ abstract class Entity{ } protected function checkChunks() : void{ - $chunkX = $this->location->getFloorX() >> 4; - $chunkZ = $this->location->getFloorZ() >> 4; - if($this->chunk === null or $chunkX !== $this->chunkX or $chunkZ !== $this->chunkZ){ - if($this->chunk !== null){ - $this->chunk->removeEntity($this); - } - $this->chunk = $this->getWorld()->loadChunk($chunkX, $chunkZ); - if($this->chunk === null){ - //TODO: this is a non-ideal solution for a hard problem - //when this happens the entity won't be tracked by any chunk, so we can't have it hanging around in memory - //we also can't allow this to cause chunk generation, nor can we just create an empty ungenerated chunk - //for it, because an empty chunk won't get saved, so the entity will vanish anyway. Therefore, this is - //the cleanest way to make sure this doesn't result in leaks. - $this->getWorld()->getLogger()->debug("Entity $this->id is in ungenerated terrain, flagging for despawn"); - $this->flagForDespawn(); - } - $this->chunkX = $chunkX; - $this->chunkZ = $chunkZ; - - if(!$this->justCreated){ - $newChunk = $this->getWorld()->getViewersForPosition($this->location); - foreach($this->hasSpawned as $player){ - if(!isset($newChunk[spl_object_id($player)])){ - $this->despawnFrom($player); - }else{ - unset($newChunk[spl_object_id($player)]); - } - } - foreach($newChunk as $player){ - $this->spawnTo($player); - } - } - - if($this->chunk === null){ - return; - } - - $this->chunk->addEntity($this); - } + $this->getWorld()->onEntityMoved($this, $this->worldLastKnownLocation); + $this->worldLastKnownLocation = $this->location->asLocation(); } protected function resetLastMovements() : void{ @@ -1477,9 +1428,6 @@ abstract class Entity{ if($this->location->isValid()){ $this->getWorld()->removeEntity($this); - if($this->chunk !== null){ - $this->chunk->removeEntity($this); - } $this->despawnFromAll(); } @@ -1492,7 +1440,6 @@ abstract class Entity{ $targetWorld ); $this->getWorld()->addEntity($this); - $this->chunk = null; return true; } @@ -1622,9 +1569,6 @@ abstract class Entity{ */ protected function onDispose() : void{ $this->despawnFromAll(); - if($this->chunk !== null){ - $this->chunk->removeEntity($this); - } if($this->location->isValid()){ $this->getWorld()->removeEntity($this); } @@ -1637,7 +1581,6 @@ abstract class Entity{ * It is expected that the object is unusable after this is called. */ protected function destroyCycles() : void{ - $this->chunk = null; $this->location = null; $this->lastDamageCause = null; } diff --git a/src/world/World.php b/src/world/World.php index 8200010aa5..a41982d93a 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2038,7 +2038,6 @@ class World implements ChunkManager{ if($entity instanceof Player){ $chunk->addEntity($entity); $oldChunk->removeEntity($entity); - $entity->chunk = $chunk; }else{ $entity->close(); } @@ -2050,7 +2049,6 @@ class World implements ChunkManager{ foreach($oldChunk->getEntities() as $entity){ $chunk->addEntity($entity); $oldChunk->removeEntity($entity); - $entity->chunk = $chunk; } foreach($oldChunk->getTiles() as $tile){ @@ -2142,6 +2140,11 @@ class World implements ChunkManager{ if($entity->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Entity world"); } + $chunk = $this->getOrLoadChunkAtPosition($entity->getPosition()); + if($chunk === null){ + throw new \InvalidArgumentException("Cannot add an Entity in an ungenerated chunk"); + } + $chunk->addEntity($entity); if($entity instanceof Player){ $this->players[$entity->getId()] = $entity; @@ -2158,6 +2161,11 @@ class World implements ChunkManager{ if($entity->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Entity world"); } + $pos = $entity->getPosition(); + $chunk = $this->getChunk($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4); + if($chunk !== null){ //we don't care if the chunk already went out of scope + $chunk->removeEntity($entity); + } if($entity instanceof Player){ unset($this->players[$entity->getId()]); @@ -2168,6 +2176,50 @@ class World implements ChunkManager{ unset($this->updateEntities[$entity->getId()]); } + /** + * @internal + */ + public function onEntityMoved(Entity $entity, Position $oldPosition) : void{ + $newPosition = $entity->getPosition(); + + $oldChunkX = $oldPosition->getFloorX() >> 4; + $oldChunkZ = $oldPosition->getFloorZ() >> 4; + $newChunkX = $newPosition->getFloorX() >> 4; + $newChunkZ = $newPosition->getFloorZ() >> 4; + + if($oldChunkX !== $newChunkX || $oldChunkZ !== $newChunkZ){ + $oldChunk = $this->getChunk($oldChunkX, $oldChunkZ); + if($oldChunk !== null){ + $oldChunk->removeEntity($entity); + } + $newChunk = $this->loadChunk($newChunkX, $newChunkZ); + if($newChunk === null){ + //TODO: this is a non-ideal solution for a hard problem + //when this happens the entity won't be tracked by any chunk, so we can't have it hanging around in memory + //we also can't allow this to cause chunk generation, nor can we just create an empty ungenerated chunk + //for it, because an empty chunk won't get saved, so the entity will vanish anyway. Therefore, this is + //the cleanest way to make sure this doesn't result in leaks. + $this->logger->debug("Entity " . $entity->getId() . " is in ungenerated terrain, flagging for despawn"); + $entity->flagForDespawn(); + $entity->despawnFromAll(); + }else{ + $newViewers = $this->getViewersForPosition($newPosition); + foreach($entity->getViewers() as $player){ + if(!isset($newViewers[spl_object_id($player)])){ + $entity->despawnFrom($player); + }else{ + unset($newViewers[spl_object_id($player)]); + } + } + foreach($newViewers as $player){ + $entity->spawnTo($player); + } + + $newChunk->addEntity($entity); + } + } + } + /** * @throws \InvalidArgumentException */ From 070d8efda3b76774e2dcfc09a40d876dfe00c4ea Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 5 Dec 2020 01:02:53 +0000 Subject: [PATCH 2195/3224] [ci skip] more world stuff for changelog --- changelogs/4.0-snapshot.md | 47 ++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 2aceb99eaa..7e1546bf37 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -761,11 +761,46 @@ This version features substantial changes to the network system, improving coher - The following API methods have been added: - `World->registerChunkListener()` - `World->unregisterChunkListener()` + - `Chunk->isDirty()` (replacement for `Chunk->hasChanged()`) + - `Chunk->getDirtyFlag()` (more granular component-based chunk dirty-flagging, used to avoid saving unmodified parts of the chunk) + - `Chunk->setDirty()` + - `Chunk->setDirtyFlag()` - The following API methods have been removed: - `ChunkLoader->getLoaderId()` (now object ID is used) - `ChunkLoader->isLoaderActive()` - `ChunkLoader->getPosition()` - `ChunkLoader->getLevel()` + - `Chunk->fastSerialize()` (use `FastChunkSerializer::serialize()` instead) + - `Chunk->getBlockData()` + - `Chunk->getBlockDataColumn()` + - `Chunk->getBlockId()` + - `Chunk->getBlockIdColumn()` + - `Chunk->getBlockLight()` + - `Chunk->getBlockLightColumn()` + - `Chunk->getBlockSkyLight()` + - `Chunk->getBlockSkyLightColumn()` + - `Chunk->getMaxY()` + - `Chunk->getSubChunkSendCount()` (this was specialized for protocol usage) + - `Chunk->getX()` + - `Chunk->getZ()` + - `Chunk->hasChanged()` (use `Chunk->isDirty()` or `Chunk->getDirtyFlag()` instead) + - `Chunk->isGenerated()` + - `Chunk->networkSerialize()` (see `ChunkSerializer` in the `network\mcpe\serializer` package) + - `Chunk->populateSkyLight()` (use `SkyLightUpdate->recalculateChunk()` instead) + - `Chunk->recalculateHeightMap()` (moved to `SkyLightUpdate`) + - `Chunk->recalculateHeightMapColumn()` (moved to `SkyLightUpdate`) + - `Chunk->setAllBlockLight()` + - `Chunk->setAllBlockSkyLight()` + - `Chunk->setBlock()` + - `Chunk->setBlockData()` + - `Chunk->setBlockId()` + - `Chunk->setBlockLight()` + - `Chunk->setBlockSkyLight()` + - `Chunk->setChanged()` (use `Chunk->setDirty()` or `Chunk->setDirtyFlag()` instead) + - `Chunk->setGenerated()` + - `Chunk->setX()` + - `Chunk->setZ()` + - `Chunk::fastDeserialize()` (use `FastChunkSerializer::deserialize()` instead) - `World->isFullBlock()` - `World->getFullBlock()` - `World->getBlockIdAt()` @@ -801,9 +836,12 @@ This version features substantial changes to the network system, improving coher - `World->addRandomTickedBlock()` now accepts `Block` instead of `int, int`. - `World->removeRandomTickedBlock()` now accepts `Block` instead of `int, int`. - `World->setBlock()` has had the `$direct` parameter removed. - - `World->loadChunk()` now returns `?Chunk`, and the `$create` parameter is mandatory. + - `World->loadChunk()` now returns `?Chunk`, and the `$create` parameter has been removed. - `World->getChunk()` no longer accepts a `$create` parameter. - `World->updateAllLight()` now accepts `int, int, int` instead of `Vector3`. + - `Chunk->__construct()` now has the signature `array $subChunks, ?list $entities, ?list $tiles, ?BiomeArray $biomeArray, ?HeightArray $heightArray`. + - `Chunk->getSubChunk()` now returns `SubChunk` instead of `SubChunkInterface|null` (and throws `InvalidArgumentException` on out-of-bounds coordinates). + - `Chunk->setSubChunk()` no longer accepts `SubChunkInterface`, and the `$allowEmpty` parameter has been removed. - The following API methods have been renamed / moved: - `Level->getCollisionCubes()` -> `World->getCollisionBoxes()` - `World->getName()` -> `World->getDisplayName()` @@ -812,9 +850,10 @@ This version features substantial changes to the network system, improving coher - The following methods now throw `WorldException` when targeting ungenerated terrain: - `World->getSafeSpawn()` (previously it just silently returned the input position) - `World->getHighestBlockAt()` (previously it returned -1) -- Extracted a unit `pocketmine\world\format\io\FastChunkSerializer` from `Chunk`: - - `Chunk->fastDeserialize()` -> `FastChunkSerializer::deserialize()` - - `Chunk->fastSerialize()` -> `FastChunkSerializer::serialize()` + - `World->loadChunk()` no longer creates an empty chunk when the target chunk doesn't exist on disk. + - `World->setChunk()` now fires `ChunkLoadEvent` and `ChunkListener->onChunkLoaded()` when replacing a chunk that didn't previously exist. + - `World->useBreakOn()` now returns `false` when the target position is in an ungenerated or unloaded chunk (or chunk locked for generation). + - `World->useItemOn()` now returns `false` when the target position is in an ungenerated or unloaded chunk (or chunk locked for generation). - A `ChunkListener` interface has been extracted from `ChunkLoader`. The following methods have been moved: - `ChunkLoader->onBlockChanged()` -> `ChunkListener->onBlockChanged()` - `ChunkLoader->onChunkChanged()` -> `ChunkListener->onChunkChanged()` From eca0e88471767f2ef503e768d99f0354f4253461 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 5 Dec 2020 01:11:30 +0000 Subject: [PATCH 2196/3224] BaseInventory: fixed passing NULL slots to InventoryListener->onContentChange() as per the documentation, InventoryListener->onContentChange() does not expect to receive NULL in the given array. --- src/inventory/BaseInventory.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/inventory/BaseInventory.php b/src/inventory/BaseInventory.php index 0e6a190dec..70c03f2b06 100644 --- a/src/inventory/BaseInventory.php +++ b/src/inventory/BaseInventory.php @@ -27,6 +27,7 @@ use Ds\Set; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\player\Player; +use function array_map; use function array_slice; use function count; use function max; @@ -95,7 +96,9 @@ abstract class BaseInventory implements Inventory{ $items = array_slice($items, 0, $this->getSize(), true); } - $oldContents = $this->slots->toArray(); + $oldContents = array_map(function(?Item $item) : Item{ + return $item ?? ItemFactory::air(); + }, $this->slots->toArray()); $listeners = $this->listeners->toArray(); $this->listeners->clear(); From b2bab6c2fb87298c3d0aca544500ad63f897e930 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 5 Dec 2020 01:32:23 +0000 Subject: [PATCH 2197/3224] clean dead errors out of phpstan l8 baseline --- tests/phpstan/configs/l8-baseline.neon | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 75b2055b38..f0d3573729 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -75,16 +75,6 @@ parameters: count: 1 path: ../../../src/command/defaults/TimeCommand.php - - - message: "#^Cannot call method addEntity\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/entity/Entity.php - - - - message: "#^Parameter \\#2 \\$oldContents of method pocketmine\\\\inventory\\\\InventoryListener\\:\\:onContentChange\\(\\) expects array\\, array\\ given\\.$#" - count: 1 - path: ../../../src/inventory/BaseInventory.php - - message: "#^Parameter \\#2 \\$recipe of class pocketmine\\\\event\\\\inventory\\\\CraftItemEvent constructor expects pocketmine\\\\crafting\\\\CraftingRecipe, pocketmine\\\\crafting\\\\CraftingRecipe\\|null given\\.$#" count: 1 @@ -266,12 +256,12 @@ parameters: path: ../../../src/player/Player.php - - message: "#^Cannot call method getEntities\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 2 + message: "#^Cannot call method stopUsingChunk\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + count: 1 path: ../../../src/player/Player.php - - message: "#^Cannot call method stopUsingChunk\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" + message: "#^Cannot call method getEntities\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" count: 1 path: ../../../src/player/Player.php From 1f330c0f50eb99ecbfe244ac5f44fbe6f6bbab05 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 5 Dec 2020 17:49:34 +0000 Subject: [PATCH 2198/3224] World: ignore entities calling onEntityMoved() who aren't members of the world this can happen if movement or teleportation occurs during the creation of an entity. --- src/world/World.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index a41982d93a..a65be12d3a 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2180,6 +2180,10 @@ class World implements ChunkManager{ * @internal */ public function onEntityMoved(Entity $entity, Position $oldPosition) : void{ + if(!array_key_exists($entity->getId(), $this->entities)){ + //this can happen if the entity was teleported before addEntity() was called + return; + } $newPosition = $entity->getPosition(); $oldChunkX = $oldPosition->getFloorX() >> 4; From 531c1914312a6aed10ecd393acf48e153a7d28f9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 5 Dec 2020 18:09:23 +0000 Subject: [PATCH 2199/3224] Finalize Utils class --- src/utils/Utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/Utils.php b/src/utils/Utils.php index adba136756..ddec3a5db6 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -82,7 +82,7 @@ use const STR_PAD_RIGHT; /** * Big collection of functions */ -class Utils{ +final class Utils{ public const OS_WINDOWS = "win"; public const OS_IOS = "ios"; public const OS_MACOS = "mac"; From b6df5b974d6da52502a5415179b2a66e06b62137 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 5 Dec 2020 18:14:38 +0000 Subject: [PATCH 2200/3224] World->getHighestBlockAt() may still return -1 if the queried column of blocks is all air --- src/world/World.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index a65be12d3a..36c495f637 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2084,7 +2084,7 @@ class World implements ChunkManager{ /** * Gets the highest block Y value at a specific $x and $z * - * @return int 0-255 + * @return int 0-255, or -1 if the column is empty * @throws WorldException if the terrain is not generated */ public function getHighestBlockAt(int $x, int $z) : int{ From 59cb11dc83511d66944cf65b26c6e34ec89ce247 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 5 Dec 2020 18:54:30 +0000 Subject: [PATCH 2201/3224] ChunkManager->setChunk() no longer accepts NULL --- src/world/ChunkManager.php | 2 +- src/world/SimpleChunkManager.php | 6 +----- src/world/World.php | 6 +----- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/world/ChunkManager.php b/src/world/ChunkManager.php index 50ec60b234..e0bb90f501 100644 --- a/src/world/ChunkManager.php +++ b/src/world/ChunkManager.php @@ -42,7 +42,7 @@ interface ChunkManager{ public function getChunk(int $chunkX, int $chunkZ) : ?Chunk; - public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk) : void; + public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void; /** * Returns the height of the world diff --git a/src/world/SimpleChunkManager.php b/src/world/SimpleChunkManager.php index cfa67f9a5a..2c7fb01c6d 100644 --- a/src/world/SimpleChunkManager.php +++ b/src/world/SimpleChunkManager.php @@ -63,11 +63,7 @@ class SimpleChunkManager implements ChunkManager{ return $this->chunks[World::chunkHash($chunkX, $chunkZ)] ?? null; } - public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk) : void{ - if($chunk === null){ - unset($this->chunks[World::chunkHash($chunkX, $chunkZ)]); - return; - } + public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ $this->chunks[World::chunkHash($chunkX, $chunkZ)] = $chunk; } diff --git a/src/world/World.php b/src/world/World.php index 36c495f637..c82ac7f1dc 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2025,11 +2025,7 @@ class World implements ChunkManager{ /** * @param bool $deleteEntitiesAndTiles Whether to delete entities and tiles on the old chunk, or transfer them to the new one */ - public function setChunk(int $chunkX, int $chunkZ, ?Chunk $chunk, bool $deleteEntitiesAndTiles = true) : void{ - if($chunk === null){ - return; - } - + public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk, bool $deleteEntitiesAndTiles = true) : void{ $chunkHash = World::chunkHash($chunkX, $chunkZ); $oldChunk = $this->loadChunk($chunkX, $chunkZ); if($oldChunk !== null and $oldChunk !== $chunk){ From 0bbceee86d700dfffc53e603602ea5268fd772de Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 5 Dec 2020 21:06:07 +0000 Subject: [PATCH 2202/3224] PermissionParser: give permissions default FALSE if they don't specify their own default --- src/permission/PermissionParser.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/permission/PermissionParser.php b/src/permission/PermissionParser.php index b88244426c..cd32643248 100644 --- a/src/permission/PermissionParser.php +++ b/src/permission/PermissionParser.php @@ -81,7 +81,7 @@ class PermissionParser{ * @return Permission[][] * @phpstan-return array> */ - public static function loadPermissions(array $data, string $default = self::DEFAULT_OP) : array{ + public static function loadPermissions(array $data, string $default = self::DEFAULT_FALSE) : array{ $result = []; foreach($data as $key => $entry){ self::loadPermission($key, $entry, $default, $result); @@ -98,7 +98,7 @@ class PermissionParser{ * * @throws \Exception */ - public static function loadPermission(string $name, array $data, string $default = self::DEFAULT_OP, array &$output = []) : void{ + public static function loadPermission(string $name, array $data, string $default = self::DEFAULT_FALSE, array &$output = []) : void{ $desc = null; $children = []; if(isset($data["default"])){ From d9de775c27109052b987f2feadf714afaf94241e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 5 Dec 2020 22:56:27 +0000 Subject: [PATCH 2203/3224] Updated DevTools submodule to pmmp/DevTools@888d021260efa5456cd7cc0174fb3a2663960811 --- tests/plugins/DevTools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/plugins/DevTools b/tests/plugins/DevTools index 7c2d05cafc..888d021260 160000 --- a/tests/plugins/DevTools +++ b/tests/plugins/DevTools @@ -1 +1 @@ -Subproject commit 7c2d05cafc52328f57b50daab5d58672501baad6 +Subproject commit 888d021260efa5456cd7cc0174fb3a2663960811 From c4b47c6c067528454b685d68af61c705ddd8ce49 Mon Sep 17 00:00:00 2001 From: Ifera Date: Sun, 6 Dec 2020 15:25:44 +0000 Subject: [PATCH 2204/3224] Implemented /clear command (#3854) closes #3854 --- resources/locale | 2 +- src/command/SimpleCommandMap.php | 2 + src/command/defaults/ClearCommand.php | 173 ++++++++++++++++++++++++++ src/permission/DefaultPermissions.php | 3 + 4 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 src/command/defaults/ClearCommand.php diff --git a/resources/locale b/resources/locale index 884a0496c3..3d1c70b9f3 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 884a0496c3c1099b8ded991cb6708dbe8cbbf53e +Subproject commit 3d1c70b9f3d7650cef7cac25db27397a5708d22c diff --git a/src/command/SimpleCommandMap.php b/src/command/SimpleCommandMap.php index 2f850b146b..8d124d748e 100644 --- a/src/command/SimpleCommandMap.php +++ b/src/command/SimpleCommandMap.php @@ -26,6 +26,7 @@ namespace pocketmine\command; use pocketmine\command\defaults\BanCommand; use pocketmine\command\defaults\BanIpCommand; use pocketmine\command\defaults\BanListCommand; +use pocketmine\command\defaults\ClearCommand; use pocketmine\command\defaults\DefaultGamemodeCommand; use pocketmine\command\defaults\DeopCommand; use pocketmine\command\defaults\DifficultyCommand; @@ -95,6 +96,7 @@ class SimpleCommandMap implements CommandMap{ new BanCommand("ban"), new BanIpCommand("ban-ip"), new BanListCommand("banlist"), + new ClearCommand("clear"), new DefaultGamemodeCommand("defaultgamemode"), new DeopCommand("deop"), new DifficultyCommand("difficulty"), diff --git a/src/command/defaults/ClearCommand.php b/src/command/defaults/ClearCommand.php new file mode 100644 index 0000000000..c0342ab924 --- /dev/null +++ b/src/command/defaults/ClearCommand.php @@ -0,0 +1,173 @@ +setPermission("pocketmine.command.clear.self;pocketmine.command.clear.other"); + } + + public function execute(CommandSender $sender, string $commandLabel, array $args){ + if(!$this->testPermission($sender)){ + return true; + } + + if(count($args) > 3){ + throw new InvalidCommandSyntaxException(); + } + + $target = null; + if(isset($args[0])){ + $target = $sender->getServer()->getPlayerByPrefix($args[0]); + if($target === null){ + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); + return true; + } + if($target !== $sender && !$sender->hasPermission("pocketmine.command.clear.other")){ + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + return true; + } + }elseif($sender instanceof Player){ + if(!$sender->hasPermission("pocketmine.command.clear.self")){ + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + return true; + } + + $target = $sender; + }else{ + throw new InvalidCommandSyntaxException(); + } + + $item = null; + $maxCount = -1; + if(isset($args[1])){ + try{ + $item = LegacyStringToItemParser::getInstance()->parse($args[1]); + + if(isset($args[2])){ + $item->setCount($maxCount = $this->getInteger($sender, $args[2], 0)); + } + }catch(InvalidArgumentException $e){ + //vanilla checks this at argument parsing layer, can't come up with a better alternative + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.give.item.notFound", [$args[1]])); + return true; + } + } + + //checking players inventory for all the items matching the criteria + if($item !== null and $maxCount === 0){ + $count = 0; + $contents = array_merge($target->getInventory()->all($item), $target->getArmorInventory()->all($item)); + foreach($contents as $content){ + $count += $content->getCount(); + } + + if($count > 0){ + $sender->sendMessage(new TranslationContainer("%commands.clear.testing", [$target->getName(), $count])); + }else{ + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.clear.failure.no.items", [$target->getName()])); + } + + return true; + } + + $cleared = 0; + + //clear everything from the targets inventory + if($item === null){ + $contents = array_merge($target->getInventory()->getContents(), $target->getArmorInventory()->getContents()); + foreach($contents as $content){ + $cleared += $content->getCount(); + } + + $target->getInventory()->clearAll(); + $target->getArmorInventory()->clearAll(); + //TODO: should the cursor inv be cleared? + }else{ + //clear the item from targets inventory irrelevant of the count + if($maxCount === -1){ + if(($slot = $target->getArmorInventory()->first($item)) !== -1){ + $cleared++; + $target->getArmorInventory()->clear($slot); + } + + foreach($target->getInventory()->all($item) as $index => $i){ + $cleared += $i->getCount(); + $target->getInventory()->clear($index); + } + }else{ + //clear only the given amount of that particular item from targets inventory + if(($slot = $target->getArmorInventory()->first($item)) !== -1){ + $cleared++; + $maxCount--; + $target->getArmorInventory()->clear($slot); + } + + if($maxCount > 0){ + foreach($target->getInventory()->all($item) as $index => $i){ + if($i->getCount() >= $maxCount){ + $i->pop($maxCount); + $cleared += $maxCount; + $target->getInventory()->setItem($index, $i); + break; + } + + if($maxCount <= 0){ + break; + } + + $cleared += $i->getCount(); + $maxCount -= $i->getCount(); + $target->getInventory()->clear($index); + } + } + } + } + + if($cleared > 0){ + Command::broadcastCommandMessage($sender, new TranslationContainer("%commands.clear.success", [$target->getName(), $cleared])); + }else{ + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.clear.failure.no.items", [$target->getName()])); + } + + return true; + } +} diff --git a/src/permission/DefaultPermissions.php b/src/permission/DefaultPermissions.php index 1d8a5ebcb1..c6b7e51cd1 100644 --- a/src/permission/DefaultPermissions.php +++ b/src/permission/DefaultPermissions.php @@ -84,6 +84,9 @@ abstract class DefaultPermissions{ self::registerPermission(new Permission(self::ROOT . ".command.kill.self", "Allows the user to commit suicide"), [$everyoneRoot]); self::registerPermission(new Permission(self::ROOT . ".command.kill.other", "Allows the user to kill other players"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.clear.self", "Allows the user to clear their own inventory"), [$everyoneRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.clear.other", "Allows the user to clear inventory of other players"), [$operatorRoot]); + self::registerPermission(new Permission(self::ROOT . ".command.me", "Allows the user to perform a chat action"), [$everyoneRoot]); self::registerPermission(new Permission(self::ROOT . ".command.tell", "Allows the user to privately message another player"), [$everyoneRoot]); self::registerPermission(new Permission(self::ROOT . ".command.say", "Allows the user to talk as the console"), [$operatorRoot]); From 219cf2126b7c5e19e024084f8d49e062304fc2ee Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 7 Dec 2020 19:04:52 +0000 Subject: [PATCH 2205/3224] RegionWorldProvider: make loadRegion() return RegionLoader, fix 3 PHPStan null-reference errors --- .../format/io/region/RegionWorldProvider.php | 13 +++++-------- tests/phpstan/configs/l8-baseline.neon | 15 --------------- 2 files changed, 5 insertions(+), 23 deletions(-) diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index e993498e49..ebb0f8088e 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -130,7 +130,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ return $this->path . "/region/r.$regionX.$regionZ." . static::getRegionFileExtension(); } - protected function loadRegion(int $regionX, int $regionZ) : void{ + protected function loadRegion(int $regionX, int $regionZ) : RegionLoader{ if(!isset($this->regions[$index = morton2d_encode($regionX, $regionZ)])){ $path = $this->pathToRegion($regionX, $regionZ); @@ -153,6 +153,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ $this->regions[$index] = $region; } + return $this->regions[$index]; } protected function unloadRegion(int $regionX, int $regionZ) : void{ @@ -221,9 +222,8 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ if(!file_exists($this->pathToRegion($regionX, $regionZ))){ return null; } - $this->loadRegion($regionX, $regionZ); - $chunkData = $this->getRegion($regionX, $regionZ)->readChunk($chunkX & 0x1f, $chunkZ & 0x1f); + $chunkData = $this->loadRegion($regionX, $regionZ)->readChunk($chunkX & 0x1f, $chunkZ & 0x1f); if($chunkData !== null){ return $this->deserializeChunk($chunkData); } @@ -233,9 +233,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ protected function writeChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ); - $this->loadRegion($regionX, $regionZ); - - $this->getRegion($regionX, $regionZ)->writeChunk($chunkX & 0x1f, $chunkZ & 0x1f, $this->serializeChunk($chunk)); + $this->loadRegion($regionX, $regionZ)->writeChunk($chunkX & 0x1f, $chunkZ & 0x1f, $this->serializeChunk($chunk)); } private function createRegionIterator() : \RegexIterator{ @@ -285,8 +283,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ foreach($this->createRegionIterator() as $region){ $regionX = ((int) $region[1]); $regionZ = ((int) $region[2]); - $this->loadRegion($regionX, $regionZ); - $count += $this->getRegion($regionX, $regionZ)->calculateChunkCount(); + $count += $this->loadRegion($regionX, $regionZ)->calculateChunkCount(); $this->unloadRegion($regionX, $regionZ); } return $count; diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index f0d3573729..ebd29eff51 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -500,21 +500,6 @@ parameters: count: 1 path: ../../../src/world/format/HeightArray.php - - - message: "#^Cannot call method readChunk\\(\\) on pocketmine\\\\world\\\\format\\\\io\\\\region\\\\RegionLoader\\|null\\.$#" - count: 1 - path: ../../../src/world/format/io/region/RegionWorldProvider.php - - - - message: "#^Cannot call method writeChunk\\(\\) on pocketmine\\\\world\\\\format\\\\io\\\\region\\\\RegionLoader\\|null\\.$#" - count: 1 - path: ../../../src/world/format/io/region/RegionWorldProvider.php - - - - message: "#^Cannot call method calculateChunkCount\\(\\) on pocketmine\\\\world\\\\format\\\\io\\\\region\\\\RegionLoader\\|null\\.$#" - count: 1 - path: ../../../src/world/format/io/region/RegionWorldProvider.php - - message: "#^Cannot call method setDirtyFlag\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" count: 4 From 05a1f45111465afe0665bfad9aa9ee21d5004fb1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 8 Dec 2020 13:38:44 +0000 Subject: [PATCH 2206/3224] PluginGraylist: all fields are mandatory --- src/plugin/PluginGraylist.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugin/PluginGraylist.php b/src/plugin/PluginGraylist.php index 72cbbd4a25..34aad55f12 100644 --- a/src/plugin/PluginGraylist.php +++ b/src/plugin/PluginGraylist.php @@ -71,8 +71,8 @@ class PluginGraylist{ */ public static function fromArray(array $array) : PluginGraylist{ $validator = new Validator( - new Key("mode", new In(['whitelist', 'blacklist'], true), false), - new Key("plugins", new AllOf(new ArrayType(), new Each(new StringType())), false) + new Key("mode", new In(['whitelist', 'blacklist'], true), true), + new Key("plugins", new AllOf(new ArrayType(), new Each(new StringType())), true) ); $validator->setName('plugin_list.yml'); try{ From 794bb0a71d92ba6e41c4ff5cb30f4ec619777504 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 9 Dec 2020 00:32:50 +0000 Subject: [PATCH 2207/3224] PermissionParser: bail on encountering permissions whose names are not strings --- src/permission/PermissionParser.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/permission/PermissionParser.php b/src/permission/PermissionParser.php index cd32643248..a6b2081669 100644 --- a/src/permission/PermissionParser.php +++ b/src/permission/PermissionParser.php @@ -25,6 +25,7 @@ namespace pocketmine\permission; use function is_array; use function is_bool; +use function is_string; use function strtolower; class PermissionParser{ @@ -108,6 +109,9 @@ class PermissionParser{ if(isset($data["children"])){ if(is_array($data["children"])){ foreach($data["children"] as $k => $v){ + if(!is_string($k)){ + throw new \InvalidArgumentException("Permission name should be string"); + } if(is_array($v)){ self::loadPermission($k, $v, $default, $output); } From d39348929f84eedbf99639a962ce9725611be9f1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 9 Dec 2020 20:48:50 +0000 Subject: [PATCH 2208/3224] Removed PLUGIN_PATH constant --- src/PocketMine.php | 5 +++-- src/utils/Filesystem.php | 29 +++++++++++++++++++++++------ tests/phpstan/bootstrap.php | 1 - tests/phpunit/utils/UtilsTest.php | 3 --- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index bc0f68ecb3..de1d860c5c 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -198,7 +198,8 @@ namespace pocketmine { $opts = getopt("", ["data:", "plugins:", "no-wizard", "enable-ansi", "disable-ansi"]); $dataPath = isset($opts["data"]) ? $opts["data"] . DIRECTORY_SEPARATOR : realpath(getcwd()) . DIRECTORY_SEPARATOR; - define('pocketmine\PLUGIN_PATH', isset($opts["plugins"]) ? $opts["plugins"] . DIRECTORY_SEPARATOR : realpath(getcwd()) . DIRECTORY_SEPARATOR . "plugins" . DIRECTORY_SEPARATOR); + $pluginPath = isset($opts["plugins"]) ? $opts["plugins"] . DIRECTORY_SEPARATOR : realpath(getcwd()) . DIRECTORY_SEPARATOR . "plugins" . DIRECTORY_SEPARATOR; + Filesystem::addCleanedPath($pluginPath, Filesystem::CLEAN_PATH_PLUGINS_PREFIX); if(!file_exists($dataPath)){ mkdir($dataPath, 0777, true); @@ -243,7 +244,7 @@ namespace pocketmine { $autoloader = new \BaseClassLoader(); $autoloader->register(false); - new Server($autoloader, $logger, $dataPath, \pocketmine\PLUGIN_PATH); + new Server($autoloader, $logger, $dataPath, $pluginPath); $logger->info("Stopping other threads"); diff --git a/src/utils/Filesystem.php b/src/utils/Filesystem.php index cc3d8d226e..ad5b5b117f 100644 --- a/src/utils/Filesystem.php +++ b/src/utils/Filesystem.php @@ -40,7 +40,9 @@ use function rtrim; use function scandir; use function str_replace; use function stream_get_contents; +use function strlen; use function strpos; +use function uasort; use function unlink; use const DIRECTORY_SEPARATOR; use const LOCK_EX; @@ -52,6 +54,13 @@ use const SCANDIR_SORT_NONE; final class Filesystem{ /** @var resource[] */ private static $lockFileHandles = []; + /** + * @var string[] + * @phpstan-var array + */ + private static $cleanedPaths = [ + \pocketmine\PATH => self::CLEAN_PATH_SRC_PREFIX + ]; public const CLEAN_PATH_SRC_PREFIX = "pmsrc"; public const CLEAN_PATH_PLUGINS_PREFIX = "plugins"; @@ -79,6 +88,19 @@ final class Filesystem{ } } + public static function addCleanedPath(string $path, string $replacement) : void{ + self::$cleanedPaths[$path] = $replacement; + uksort(self::$cleanedPaths, function(string $str1, string $str2) : int{ + return strlen($str2) <=> strlen($str1); //longest first + }); + } + + /** + * @return string[] + * @phpstan-return array + */ + public static function getCleanedPaths() : array{ return self::$cleanedPaths; } + /** * @param string $path * @@ -88,12 +110,7 @@ final class Filesystem{ $result = str_replace([DIRECTORY_SEPARATOR, ".php", "phar://"], ["/", "", ""], $path); //remove relative paths - //TODO: make these paths dynamic so they can be unit-tested against - static $cleanPaths = [ - \pocketmine\PLUGIN_PATH => self::CLEAN_PATH_PLUGINS_PREFIX, //this has to come BEFORE \pocketmine\PATH because it's inside that by default on src installations - \pocketmine\PATH => self::CLEAN_PATH_SRC_PREFIX - ]; - foreach($cleanPaths as $cleanPath => $replacement){ + foreach(self::$cleanedPaths as $cleanPath => $replacement){ $cleanPath = rtrim(str_replace([DIRECTORY_SEPARATOR, "phar://"], ["/", ""], $cleanPath), "/"); if(strpos($result, $cleanPath) === 0){ $result = ltrim(str_replace($cleanPath, $replacement, $result), "/"); diff --git a/tests/phpstan/bootstrap.php b/tests/phpstan/bootstrap.php index 1906c5f47d..9e514ffc5a 100644 --- a/tests/phpstan/bootstrap.php +++ b/tests/phpstan/bootstrap.php @@ -33,4 +33,3 @@ if(!extension_loaded('libdeflate')){ //TODO: these need to be defined properly or removed define('pocketmine\COMPOSER_AUTOLOADER_PATH', dirname(__DIR__, 2) . '/vendor/autoload.php'); -define('pocketmine\PLUGIN_PATH', ''); diff --git a/tests/phpunit/utils/UtilsTest.php b/tests/phpunit/utils/UtilsTest.php index 7662908888..20bb88cdf8 100644 --- a/tests/phpunit/utils/UtilsTest.php +++ b/tests/phpunit/utils/UtilsTest.php @@ -33,9 +33,6 @@ class UtilsTest extends TestCase{ if(!defined('pocketmine\PATH')){ define('pocketmine\PATH', 'dummy'); } - if(!defined('pocketmine\PLUGIN_PATH')){ - define('pocketmine\PLUGIN_PATH', 'dummy'); - } } /** From 58db3531c77ade3674910e8fd3f4e6a7ca507e86 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 9 Dec 2020 22:24:31 +0000 Subject: [PATCH 2209/3224] Use hrtime() for collecting timings this allows nanosecond resolution and generally better accuracy than microtime(), which is subject to floating-point errors. --- src/timings/TimingsHandler.php | 21 ++++++++++----------- src/timings/TimingsRecord.php | 14 +++++++------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/timings/TimingsHandler.php b/src/timings/TimingsHandler.php index 6fc07adf8b..eb7d402cb4 100644 --- a/src/timings/TimingsHandler.php +++ b/src/timings/TimingsHandler.php @@ -27,14 +27,13 @@ use pocketmine\entity\Living; use pocketmine\Server; use function count; use function fwrite; -use function microtime; -use function round; +use function hrtime; use const PHP_EOL; class TimingsHandler{ /** @var bool */ private static $enabled = false; - /** @var float */ + /** @var int */ private static $timingStart = 0; /** @@ -53,7 +52,7 @@ class TimingsHandler{ $avg = $time / $count; - fwrite($fp, " " . $timings->getName() . " Time: " . round($time * 1000000000) . " Count: " . $count . " Avg: " . round($avg * 1000000000) . " Violations: " . $timings->getViolations() . PHP_EOL); + fwrite($fp, " " . $timings->getName() . " Time: $time Count: " . $count . " Avg: $avg Violations: " . $timings->getViolations() . PHP_EOL); } fwrite($fp, "# Version " . Server::getInstance()->getVersion() . PHP_EOL); @@ -73,8 +72,8 @@ class TimingsHandler{ fwrite($fp, "# Entities " . $entities . PHP_EOL); fwrite($fp, "# LivingEntities " . $livingEntities . PHP_EOL); - $sampleTime = microtime(true) - self::$timingStart; - fwrite($fp, "Sample time " . round($sampleTime * 1000000000) . " (" . $sampleTime . "s)" . PHP_EOL); + $sampleTime = hrtime(true) - self::$timingStart; + fwrite($fp, "Sample time $sampleTime (" . ($sampleTime / 1000000000) . "s)" . PHP_EOL); } public static function isEnabled() : bool{ @@ -93,7 +92,7 @@ class TimingsHandler{ public static function reload() : void{ TimingsRecord::clearRecords(); if(self::$enabled){ - self::$timingStart = microtime(true); + self::$timingStart = hrtime(true); } } @@ -123,11 +122,11 @@ class TimingsHandler{ public function startTiming() : void{ if(self::$enabled){ - $this->internalStartTiming(microtime(true)); + $this->internalStartTiming(hrtime(true)); } } - private function internalStartTiming(float $now) : void{ + private function internalStartTiming(int $now) : void{ if(++$this->timingDepth === 1){ if($this->record === null){ $this->record = new TimingsRecord($this); @@ -141,11 +140,11 @@ class TimingsHandler{ public function stopTiming() : void{ if(self::$enabled){ - $this->internalStopTiming(microtime(true)); + $this->internalStopTiming(hrtime(true)); } } - private function internalStopTiming(float $now) : void{ + private function internalStopTiming(int $now) : void{ if($this->timingDepth === 0){ //TODO: it would be nice to bail here, but since we'd have to track timing depth across resets //and enable/disable, it would have a performance impact. Therefore, considering the limited diff --git a/src/timings/TimingsRecord.php b/src/timings/TimingsRecord.php index 106ad3772c..1150e55f41 100644 --- a/src/timings/TimingsRecord.php +++ b/src/timings/TimingsRecord.php @@ -54,8 +54,8 @@ final class TimingsRecord{ public static function tick(bool $measure = true) : void{ if($measure){ foreach(self::$records as $record){ - if($record->curTickTotal > 0.05){ - $record->violations += (int) round($record->curTickTotal / 0.05); + if($record->curTickTotal > 50000000){ + $record->violations += (int) round($record->curTickTotal / 50000000); } $record->curTickTotal = 0; $record->curCount = 0; @@ -78,11 +78,11 @@ final class TimingsRecord{ private $count = 0; /** @var int */ private $curCount = 0; - /** @var float */ + /** @var int */ private $start = 0; - /** @var float */ + /** @var int */ private $totalTime = 0; - /** @var float */ + /** @var int */ private $curTickTotal = 0; /** @var int */ private $violations = 0; @@ -107,11 +107,11 @@ final class TimingsRecord{ public function getViolations() : int{ return $this->violations; } - public function startTiming(float $now) : void{ + public function startTiming(int $now) : void{ $this->start = $now; } - public function stopTiming(float $now) : void{ + public function stopTiming(int $now) : void{ if($this->start == 0){ return; } From 5282ae329834512a6ca497e8c4bdbcb73ec86db2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 9 Dec 2020 22:32:32 +0000 Subject: [PATCH 2210/3224] TimingsHandler::printTimings() now returns a list of strings instead of requiring a resource --- src/command/defaults/TimingsCommand.php | 7 ++++++- src/timings/TimingsHandler.php | 23 ++++++++++------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/command/defaults/TimingsCommand.php b/src/command/defaults/TimingsCommand.php index 98204167a9..d18dc55aab 100644 --- a/src/command/defaults/TimingsCommand.php +++ b/src/command/defaults/TimingsCommand.php @@ -36,6 +36,7 @@ use function fclose; use function file_exists; use function fopen; use function fseek; +use function fwrite; use function http_build_query; use function is_array; use function json_decode; @@ -47,6 +48,7 @@ use const CURLOPT_FOLLOWLOCATION; use const CURLOPT_HTTPHEADER; use const CURLOPT_POST; use const CURLOPT_POSTFIELDS; +use const PHP_EOL; class TimingsCommand extends VanillaCommand{ @@ -110,7 +112,10 @@ class TimingsCommand extends VanillaCommand{ $fileTimings = fopen($timings, "a+b"); } - TimingsHandler::printTimings($fileTimings); + $lines = TimingsHandler::printTimings(); + foreach($lines as $line){ + fwrite($fileTimings, $line . PHP_EOL); + } if($paste){ fseek($fileTimings, 0); diff --git a/src/timings/TimingsHandler.php b/src/timings/TimingsHandler.php index eb7d402cb4..eef7cd0913 100644 --- a/src/timings/TimingsHandler.php +++ b/src/timings/TimingsHandler.php @@ -26,9 +26,7 @@ namespace pocketmine\timings; use pocketmine\entity\Living; use pocketmine\Server; use function count; -use function fwrite; use function hrtime; -use const PHP_EOL; class TimingsHandler{ /** @var bool */ @@ -36,11 +34,9 @@ class TimingsHandler{ /** @var int */ private static $timingStart = 0; - /** - * @param resource $fp - */ - public static function printTimings($fp) : void{ - fwrite($fp, "Minecraft" . PHP_EOL); + /** @return string[] */ + public static function printTimings() : array{ + $result = ["Minecraft"]; foreach(TimingsRecord::getAll() as $timings){ $time = $timings->getTotalTime(); @@ -52,11 +48,11 @@ class TimingsHandler{ $avg = $time / $count; - fwrite($fp, " " . $timings->getName() . " Time: $time Count: " . $count . " Avg: $avg Violations: " . $timings->getViolations() . PHP_EOL); + $result[] = " " . $timings->getName() . " Time: $time Count: " . $count . " Avg: $avg Violations: " . $timings->getViolations(); } - fwrite($fp, "# Version " . Server::getInstance()->getVersion() . PHP_EOL); - fwrite($fp, "# " . Server::getInstance()->getName() . " " . Server::getInstance()->getPocketMineVersion() . PHP_EOL); + $result[] = "# Version " . Server::getInstance()->getVersion(); + $result[] = "# " . Server::getInstance()->getName() . " " . Server::getInstance()->getPocketMineVersion(); $entities = 0; $livingEntities = 0; @@ -69,11 +65,12 @@ class TimingsHandler{ } } - fwrite($fp, "# Entities " . $entities . PHP_EOL); - fwrite($fp, "# LivingEntities " . $livingEntities . PHP_EOL); + $result[] = "# Entities " . $entities; + $result[] = "# LivingEntities " . $livingEntities; $sampleTime = hrtime(true) - self::$timingStart; - fwrite($fp, "Sample time $sampleTime (" . ($sampleTime / 1000000000) . "s)" . PHP_EOL); + $result[] = "Sample time $sampleTime (" . ($sampleTime / 1000000000) . "s)"; + return $result; } public static function isEnabled() : bool{ From e9254237496fe06cc13958056a9ebd70fa39fcdd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 10 Dec 2020 18:13:18 +0000 Subject: [PATCH 2211/3224] Entity: fix chunk tracking consistency issues, fixed attempted chunk loading in origin world when teleporting to a different position in a different world --- src/entity/Entity.php | 52 ++++++++-------------------- src/entity/projectile/Projectile.php | 2 +- src/player/Player.php | 4 +-- src/world/World.php | 10 ++++-- 4 files changed, 25 insertions(+), 43 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 1931e980c3..860dec2b3b 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -96,8 +96,8 @@ abstract class Entity{ /** @var EntityMetadataCollection */ private $networkProperties; - /** @var Location */ - private $worldLastKnownLocation; + /** @var Vector3 */ + public $worldLastKnownLocation; /** @var EntityDamageEvent|null */ protected $lastDamageCause = null; @@ -1210,7 +1210,7 @@ abstract class Entity{ $this->location->world ); - $this->checkChunks(); + $this->getWorld()->onEntityMoved($this); $this->checkBlockCollision(); $this->checkGroundState($movX, $movY, $movZ, $dx, $dy, $dz); $this->updateFallState($dy, $this->onGround); @@ -1309,15 +1309,17 @@ abstract class Entity{ return false; } - if($pos instanceof Position and $pos->isValid() and $pos->getWorld() !== $this->getWorld()){ - if(!$this->switchWorld($pos->getWorld())){ - return false; - } + $oldWorld = $this->getWorld(); + //TODO: staying in the same world when the target is invalid is probably not expected behaviour... this should bail instead + $newWorld = $pos instanceof Position && $pos->isValid() ? $pos->getWorld() : $oldWorld; + if($oldWorld !== $newWorld){ + $this->despawnFromAll(); + $oldWorld->removeEntity($this); } $this->location = Location::fromObject( $pos, - $this->location->world, + $newWorld, $this->location->yaw, $this->location->pitch ); @@ -1326,7 +1328,11 @@ abstract class Entity{ $this->blocksAround = null; - $this->checkChunks(); + if($oldWorld !== $newWorld){ + $newWorld->addEntity($this); + }else{ + $newWorld->onEntityMoved($this); + } return true; } @@ -1347,11 +1353,6 @@ abstract class Entity{ return false; } - protected function checkChunks() : void{ - $this->getWorld()->onEntityMoved($this, $this->worldLastKnownLocation); - $this->worldLastKnownLocation = $this->location->asLocation(); - } - protected function resetLastMovements() : void{ $this->lastLocation = $this->location->asLocation(); $this->lastMotion = clone $this->motion; @@ -1421,29 +1422,6 @@ abstract class Entity{ return false; } - protected function switchWorld(World $targetWorld) : bool{ - if($this->closed){ - return false; - } - - if($this->location->isValid()){ - $this->getWorld()->removeEntity($this); - $this->despawnFromAll(); - } - - $this->location = new Location( - $this->location->x, - $this->location->y, - $this->location->z, - $this->location->yaw, - $this->location->pitch, - $targetWorld - ); - $this->getWorld()->addEntity($this); - - return true; - } - public function getId() : int{ return $this->id; } diff --git a/src/entity/projectile/Projectile.php b/src/entity/projectile/Projectile.php index 49d386578b..c95c38ff08 100644 --- a/src/entity/projectile/Projectile.php +++ b/src/entity/projectile/Projectile.php @@ -261,7 +261,7 @@ abstract class Projectile extends Entity{ $this->location->pitch = (atan2($this->motion->y, $f) * 180 / M_PI); } - $this->checkChunks(); + $this->getWorld()->onEntityMoved($this); $this->checkBlockCollision(); Timings::$entityMoveTimer->stopTiming(); diff --git a/src/player/Player.php b/src/player/Player.php index e5e2031bce..c6adef475e 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -648,9 +648,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } } - protected function switchWorld(World $targetWorld) : bool{ + protected function setPosition(Vector3 $pos) : bool{ $oldWorld = $this->location->isValid() ? $this->location->getWorld() : null; - if(parent::switchWorld($targetWorld)){ + if(parent::setPosition($pos)){ if($oldWorld !== null){ foreach($this->usedChunks as $index => $status){ World::getXZ($index, $X, $Z); diff --git a/src/world/World.php b/src/world/World.php index c82ac7f1dc..05513b8bef 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2136,11 +2136,13 @@ class World implements ChunkManager{ if($entity->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Entity world"); } - $chunk = $this->getOrLoadChunkAtPosition($entity->getPosition()); + $pos = $entity->getPosition()->asVector3(); + $chunk = $this->getOrLoadChunkAtPosition($pos); if($chunk === null){ throw new \InvalidArgumentException("Cannot add an Entity in an ungenerated chunk"); } $chunk->addEntity($entity); + $entity->worldLastKnownLocation = $pos; if($entity instanceof Player){ $this->players[$entity->getId()] = $entity; @@ -2157,7 +2159,7 @@ class World implements ChunkManager{ if($entity->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Entity world"); } - $pos = $entity->getPosition(); + $pos = $entity->worldLastKnownLocation; $chunk = $this->getChunk($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4); if($chunk !== null){ //we don't care if the chunk already went out of scope $chunk->removeEntity($entity); @@ -2175,11 +2177,12 @@ class World implements ChunkManager{ /** * @internal */ - public function onEntityMoved(Entity $entity, Position $oldPosition) : void{ + public function onEntityMoved(Entity $entity) : void{ if(!array_key_exists($entity->getId(), $this->entities)){ //this can happen if the entity was teleported before addEntity() was called return; } + $oldPosition = $entity->worldLastKnownLocation; $newPosition = $entity->getPosition(); $oldChunkX = $oldPosition->getFloorX() >> 4; @@ -2216,6 +2219,7 @@ class World implements ChunkManager{ } $newChunk->addEntity($entity); + $entity->worldLastKnownLocation = $newPosition->asVector3(); } } } From dd58a95ae58da14a651e3b07af53e3c10298cf26 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 10 Dec 2020 18:28:40 +0000 Subject: [PATCH 2212/3224] Move last-known-position tracking to World instead of Entity --- src/entity/Entity.php | 4 ---- src/world/World.php | 16 +++++++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 860dec2b3b..ce18440ab7 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -96,9 +96,6 @@ abstract class Entity{ /** @var EntityMetadataCollection */ private $networkProperties; - /** @var Vector3 */ - public $worldLastKnownLocation; - /** @var EntityDamageEvent|null */ protected $lastDamageCause = null; @@ -229,7 +226,6 @@ abstract class Entity{ $this->server = $location->getWorld()->getServer(); $this->location = $location->asLocation(); - $this->worldLastKnownLocation = $this->location->asLocation(); assert( !is_nan($this->location->x) and !is_infinite($this->location->x) and !is_nan($this->location->y) and !is_infinite($this->location->y) and diff --git a/src/world/World.php b/src/world/World.php index 05513b8bef..435e211aa5 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -148,6 +148,11 @@ class World implements ChunkManager{ /** @var Entity[] */ private $entities = []; + /** + * @var Vector3[] + * @phpstan-var array + */ + private $entityLastKnownPositions = []; /** @var Entity[] */ public $updateEntities = []; @@ -2142,7 +2147,7 @@ class World implements ChunkManager{ throw new \InvalidArgumentException("Cannot add an Entity in an ungenerated chunk"); } $chunk->addEntity($entity); - $entity->worldLastKnownLocation = $pos; + $this->entityLastKnownPositions[$entity->getId()] = $pos; if($entity instanceof Player){ $this->players[$entity->getId()] = $entity; @@ -2159,11 +2164,12 @@ class World implements ChunkManager{ if($entity->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Entity world"); } - $pos = $entity->worldLastKnownLocation; + $pos = $this->entityLastKnownPositions[$entity->getId()]; $chunk = $this->getChunk($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4); if($chunk !== null){ //we don't care if the chunk already went out of scope $chunk->removeEntity($entity); } + unset($this->entityLastKnownPositions[$entity->getId()]); if($entity instanceof Player){ unset($this->players[$entity->getId()]); @@ -2178,11 +2184,11 @@ class World implements ChunkManager{ * @internal */ public function onEntityMoved(Entity $entity) : void{ - if(!array_key_exists($entity->getId(), $this->entities)){ + if(!array_key_exists($entity->getId(), $this->entityLastKnownPositions)){ //this can happen if the entity was teleported before addEntity() was called return; } - $oldPosition = $entity->worldLastKnownLocation; + $oldPosition = $this->entityLastKnownPositions[$entity->getId()]; $newPosition = $entity->getPosition(); $oldChunkX = $oldPosition->getFloorX() >> 4; @@ -2219,9 +2225,9 @@ class World implements ChunkManager{ } $newChunk->addEntity($entity); - $entity->worldLastKnownLocation = $newPosition->asVector3(); } } + $this->entityLastKnownPositions[$entity->getId()] = $newPosition->asVector3(); } /** From bee770ebf54cbc6f910e74bfc909f7b5fd2bccce Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 11 Dec 2020 19:03:52 +0000 Subject: [PATCH 2213/3224] Drop nested permissions support in plugin.yml --- src/permission/PermissionParser.php | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/permission/PermissionParser.php b/src/permission/PermissionParser.php index a6b2081669..dfb4c00692 100644 --- a/src/permission/PermissionParser.php +++ b/src/permission/PermissionParser.php @@ -23,9 +23,7 @@ declare(strict_types=1); namespace pocketmine\permission; -use function is_array; use function is_bool; -use function is_string; use function strtolower; class PermissionParser{ @@ -101,31 +99,18 @@ class PermissionParser{ */ public static function loadPermission(string $name, array $data, string $default = self::DEFAULT_FALSE, array &$output = []) : void{ $desc = null; - $children = []; if(isset($data["default"])){ $default = PermissionParser::defaultFromString($data["default"]); } if(isset($data["children"])){ - if(is_array($data["children"])){ - foreach($data["children"] as $k => $v){ - if(!is_string($k)){ - throw new \InvalidArgumentException("Permission name should be string"); - } - if(is_array($v)){ - self::loadPermission($k, $v, $default, $output); - } - $children[$k] = true; - } - }else{ - throw new \InvalidStateException("'children' key is of wrong type"); - } + throw new \InvalidArgumentException("Nested permission declarations are no longer supported. Declare each permission separately."); } if(isset($data["description"])){ $desc = $data["description"]; } - $output[$default][] = new Permission($name, $desc, $children); + $output[$default][] = new Permission($name, $desc); } } From 61de84373a5fdcbd9c4e29d463865aa4187c6606 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 11 Dec 2020 19:09:01 +0000 Subject: [PATCH 2214/3224] PermissionParser: simplify code --- src/permission/PermissionParser.php | 43 ++++++++++------------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/src/permission/PermissionParser.php b/src/permission/PermissionParser.php index dfb4c00692..7115a5536f 100644 --- a/src/permission/PermissionParser.php +++ b/src/permission/PermissionParser.php @@ -82,35 +82,22 @@ class PermissionParser{ */ public static function loadPermissions(array $data, string $default = self::DEFAULT_FALSE) : array{ $result = []; - foreach($data as $key => $entry){ - self::loadPermission($key, $entry, $default, $result); - } + foreach($data as $name => $entry){ + $desc = null; + if(isset($entry["default"])){ + $default = PermissionParser::defaultFromString($entry["default"]); + } + if(isset($entry["children"])){ + throw new \InvalidArgumentException("Nested permission declarations are no longer supported. Declare each permission separately."); + } + + if(isset($entry["description"])){ + $desc = $entry["description"]; + } + + $result[$default][] = new Permission($name, $desc); + } return $result; } - - /** - * @param mixed[] $data - * @param Permission[][] $output reference parameter - * @phpstan-param array $data - * @phpstan-param array> $output - * - * @throws \Exception - */ - public static function loadPermission(string $name, array $data, string $default = self::DEFAULT_FALSE, array &$output = []) : void{ - $desc = null; - if(isset($data["default"])){ - $default = PermissionParser::defaultFromString($data["default"]); - } - - if(isset($data["children"])){ - throw new \InvalidArgumentException("Nested permission declarations are no longer supported. Declare each permission separately."); - } - - if(isset($data["description"])){ - $desc = $data["description"]; - } - - $output[$default][] = new Permission($name, $desc); - } } From 6a314c7d701577c654eb12b75627d084297a3344 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 11 Dec 2020 22:44:44 +0000 Subject: [PATCH 2215/3224] Updated build/php submodule to pmmp/php-build-scripts@bdce80c6c2e64524b6de56772c16096679abfc8f --- build/php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/php b/build/php index 24388d20a5..bdce80c6c2 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit 24388d20a548d92bb7747a195873f18eefca97a3 +Subproject commit bdce80c6c2e64524b6de56772c16096679abfc8f From 3e0cf30285f7409a0cd7af293deb9b93ced1be9d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 11 Dec 2020 23:00:14 +0000 Subject: [PATCH 2216/3224] fixed phpstan failures caused by 5282ae329834512a6ca497e8c4bdbcb73ec86db2 --- tests/phpstan/configs/check-explicit-mixed-baseline.neon | 2 +- tests/phpstan/configs/l7-baseline.neon | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index c682bd133d..eb753080ca 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -96,7 +96,7 @@ parameters: path: ../../../src/command/CommandReader.php - - message: "#^Parameter \\#2 \\$host of class class@anonymous/src/command/defaults/TimingsCommand\\.php\\:125 constructor expects string, mixed given\\.$#" + message: "#^Parameter \\#2 \\$host of class class@anonymous/src/command/defaults/TimingsCommand\\.php\\:130 constructor expects string, mixed given\\.$#" count: 1 path: ../../../src/command/defaults/TimingsCommand.php diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index 3b68bbde5e..cfc834ca88 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -491,7 +491,7 @@ parameters: path: ../../../src/command/defaults/PardonIpCommand.php - - message: "#^Parameter \\#1 \\$fp of static method pocketmine\\\\timings\\\\TimingsHandler\\:\\:printTimings\\(\\) expects resource, resource\\|false given\\.$#" + message: "#^Parameter \\#1 \\$fp of function fwrite expects resource, resource\\|false given\\.$#" count: 1 path: ../../../src/command/defaults/TimingsCommand.php @@ -511,7 +511,7 @@ parameters: path: ../../../src/command/defaults/TimingsCommand.php - - message: "#^Parameter \\#4 \\$data of class class@anonymous/src/command/defaults/TimingsCommand\\.php\\:125 constructor expects array\\, array\\ given\\.$#" + message: "#^Parameter \\#4 \\$data of class class@anonymous/src/command/defaults/TimingsCommand\\.php\\:130 constructor expects array\\, array\\ given\\.$#" count: 1 path: ../../../src/command/defaults/TimingsCommand.php From f81d061ea95c89a133dd7f95c04d5798fba9614f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 12 Dec 2020 19:06:45 +0000 Subject: [PATCH 2217/3224] Updated to newest RakLib --- composer.lock | 10 +++++----- src/network/mcpe/raklib/RakLibInterface.php | 1 - src/network/mcpe/raklib/RakLibServer.php | 5 ++++- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/composer.lock b/composer.lock index a72cda8383..75fc95c3f2 100644 --- a/composer.lock +++ b/composer.lock @@ -637,12 +637,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "a40cf8a90c3081166b555826bc1def8a7a5c5cb9" + "reference": "4272f15bc47941b59e1d597ca544465f4a59725e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/a40cf8a90c3081166b555826bc1def8a7a5c5cb9", - "reference": "a40cf8a90c3081166b555826bc1def8a7a5c5cb9", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/4272f15bc47941b59e1d597ca544465f4a59725e", + "reference": "4272f15bc47941b59e1d597ca544465f4a59725e", "shasum": "" }, "require": { @@ -654,7 +654,7 @@ "pocketmine/log": "dev-master" }, "require-dev": { - "phpstan/phpstan": "0.12.40", + "phpstan/phpstan": "0.12.59", "phpstan/phpstan-strict-rules": "^0.12.2" }, "type": "library", @@ -672,7 +672,7 @@ "issues": "https://github.com/pmmp/RakLib/issues", "source": "https://github.com/pmmp/RakLib/tree/master" }, - "time": "2020-08-28T22:11:37+00:00" + "time": "2020-12-12T02:09:57+00:00" }, { "name": "pocketmine/snooze", diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 41d6f1176f..4a8c16a0c2 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -155,7 +155,6 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ public function shutdown() : void{ $this->server->getTickSleeper()->removeNotifier($this->sleeper); - $this->interface->shutdown(); $this->rakLib->quit(); } diff --git a/src/network/mcpe/raklib/RakLibServer.php b/src/network/mcpe/raklib/RakLibServer.php index aefac3357a..329f0d5c21 100644 --- a/src/network/mcpe/raklib/RakLibServer.php +++ b/src/network/mcpe/raklib/RakLibServer.php @@ -164,7 +164,10 @@ class RakLibServer extends Thread{ $this->ready = true; $this->notify(); }); - $manager->run(); + while(!$this->isKilled){ + $manager->tickProcessor(); + } + $manager->waitShutdown(); $this->cleanShutdown = true; }catch(\Throwable $e){ $this->setCrashInfo($e->getMessage()); From 5f4ef84d52adb45b8da3b7a27cc6b8ab3a6eb5de Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 12 Dec 2020 19:48:00 +0000 Subject: [PATCH 2218/3224] Clean up imports --- src/Server.php | 2 +- src/network/query/DedicatedQueryNetworkInterface.php | 3 +++ src/utils/Filesystem.php | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Server.php b/src/Server.php index c1be895c91..8ae8b3f023 100644 --- a/src/Server.php +++ b/src/Server.php @@ -58,9 +58,9 @@ use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\raklib\RakLibInterface; use pocketmine\network\Network; +use pocketmine\network\query\DedicatedQueryNetworkInterface; use pocketmine\network\query\QueryHandler; use pocketmine\network\query\QueryInfo; -use pocketmine\network\query\DedicatedQueryNetworkInterface; use pocketmine\network\upnp\UPnP; use pocketmine\permission\BanList; use pocketmine\permission\DefaultPermissions; diff --git a/src/network/query/DedicatedQueryNetworkInterface.php b/src/network/query/DedicatedQueryNetworkInterface.php index 5a083a9e34..500d3e747d 100644 --- a/src/network/query/DedicatedQueryNetworkInterface.php +++ b/src/network/query/DedicatedQueryNetworkInterface.php @@ -33,7 +33,10 @@ use function socket_last_error; use function socket_recvfrom; use function socket_select; use function socket_sendto; +use function socket_set_nonblock; use function socket_strerror; +use function strlen; +use function time; use function trim; use const AF_INET; use const PHP_INT_MAX; diff --git a/src/utils/Filesystem.php b/src/utils/Filesystem.php index ad5b5b117f..01b6f57813 100644 --- a/src/utils/Filesystem.php +++ b/src/utils/Filesystem.php @@ -42,7 +42,7 @@ use function str_replace; use function stream_get_contents; use function strlen; use function strpos; -use function uasort; +use function uksort; use function unlink; use const DIRECTORY_SEPARATOR; use const LOCK_EX; From eaf6e19a6fef36f98a0ad06fd2d3227608237426 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 12 Dec 2020 19:54:17 +0000 Subject: [PATCH 2219/3224] RakLib sync n.2 --- composer.lock | 8 ++++---- src/network/mcpe/raklib/RakLibInterface.php | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/composer.lock b/composer.lock index 75fc95c3f2..2d95ce1479 100644 --- a/composer.lock +++ b/composer.lock @@ -637,12 +637,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "4272f15bc47941b59e1d597ca544465f4a59725e" + "reference": "31e513ee53adf8e32cabad072a50f8572f6dfb12" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/4272f15bc47941b59e1d597ca544465f4a59725e", - "reference": "4272f15bc47941b59e1d597ca544465f4a59725e", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/31e513ee53adf8e32cabad072a50f8572f6dfb12", + "reference": "31e513ee53adf8e32cabad072a50f8572f6dfb12", "shasum": "" }, "require": { @@ -672,7 +672,7 @@ "issues": "https://github.com/pmmp/RakLib/issues", "source": "https://github.com/pmmp/RakLib/tree/master" }, - "time": "2020-12-12T02:09:57+00:00" + "time": "2020-12-12T19:33:03+00:00" }, { "name": "pocketmine/snooze", diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 4a8c16a0c2..337f71ab97 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -138,7 +138,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ } } - public function closeSession(int $sessionId, string $reason) : void{ + public function onClientDisconnect(int $sessionId, string $reason) : void{ if(isset($this->sessions[$sessionId])){ $session = $this->sessions[$sessionId]; unset($this->sessions[$sessionId]); @@ -158,7 +158,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ $this->rakLib->quit(); } - public function openSession(int $sessionId, string $address, int $port, int $clientID) : void{ + public function onClientConnect(int $sessionId, string $address, int $port, int $clientID) : void{ $session = new NetworkSession( $this->server, $this->network->getSessionManager(), @@ -172,7 +172,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ $this->sessions[$sessionId] = $session; } - public function handleEncapsulated(int $sessionId, string $packet) : void{ + public function onPacketReceive(int $sessionId, string $packet) : void{ if(isset($this->sessions[$sessionId])){ if($packet === "" or $packet[0] !== self::MCPE_RAKNET_PACKET_ID){ return; @@ -208,7 +208,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ $this->interface->unblockAddress($address); } - public function handleRaw(string $address, int $port, string $payload) : void{ + public function onRawPacketReceive(string $address, int $port, string $payload) : void{ $this->network->processRawPacket($this, $address, $port, $payload); } @@ -220,7 +220,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ $this->interface->addRawPacketFilter($regex); } - public function notifyACK(int $sessionId, int $identifierACK) : void{ + public function onPacketAck(int $sessionId, int $identifierACK) : void{ } @@ -250,7 +250,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ $this->interface->setPacketsPerTickLimit($limit); } - public function handleBandwidthStats(int $bytesSentDiff, int $bytesReceivedDiff) : void{ + public function onBandwidthStatsUpdate(int $bytesSentDiff, int $bytesReceivedDiff) : void{ $this->network->getBandwidthTracker()->add($bytesSentDiff, $bytesReceivedDiff); } @@ -265,7 +265,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ } } - public function updatePing(int $sessionId, int $pingMS) : void{ + public function onPingMeasure(int $sessionId, int $pingMS) : void{ if(isset($this->sessions[$sessionId])){ $this->sessions[$sessionId]->updatePing($pingMS); } From 1de5fc86c41e3fb87382d11639a376338da9fd1b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Dec 2020 20:00:57 +0000 Subject: [PATCH 2220/3224] PopulationTask: assume that generator has been initialized --- src/world/generator/PopulationTask.php | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 9e82ac6f21..9bcfc85dd1 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\world\generator; use pocketmine\scheduler\AsyncTask; +use pocketmine\utils\AssumptionFailedError; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\FastChunkSerializer; use pocketmine\world\SimpleChunkManager; @@ -33,8 +34,6 @@ use function intdiv; class PopulationTask extends AsyncTask{ private const TLS_KEY_WORLD = "world"; - /** @var bool */ - public $state; /** @var int */ public $worldId; /** @var int */ @@ -66,7 +65,6 @@ class PopulationTask extends AsyncTask{ public $chunk8; public function __construct(World $world, int $chunkX, int $chunkZ, ?Chunk $chunk){ - $this->state = true; $this->worldId = $world->getId(); $this->chunkX = $chunkX; $this->chunkZ = $chunkZ; @@ -82,8 +80,7 @@ class PopulationTask extends AsyncTask{ public function onRun() : void{ $context = ThreadLocalGeneratorContext::fetch($this->worldId); if($context === null){ - $this->state = false; - return; + throw new AssumptionFailedError("Generator context should have been initialized before any PopulationTask execution"); } $generator = $context->getGenerator(); $manager = new SimpleChunkManager($context->getWorldHeight()); @@ -140,10 +137,6 @@ class PopulationTask extends AsyncTask{ /** @var World $world */ $world = $this->fetchLocal(self::TLS_KEY_WORLD); if(!$world->isClosed()){ - if(!$this->state){ - $world->registerGeneratorToWorker($this->worker->getAsyncWorkerId()); - } - $chunk = $this->chunk !== null ? FastChunkSerializer::deserialize($this->chunk) : null; for($i = 0; $i < 9; ++$i){ @@ -156,11 +149,11 @@ class PopulationTask extends AsyncTask{ $zz = -1 + intdiv($i, 3); $c = FastChunkSerializer::deserialize($c); - $world->generateChunkCallback($this->chunkX + $xx, $this->chunkZ + $zz, $this->state ? $c : null); + $world->generateChunkCallback($this->chunkX + $xx, $this->chunkZ + $zz, $c); } } - $world->generateChunkCallback($this->chunkX, $this->chunkZ, $this->state ? $chunk : null); + $world->generateChunkCallback($this->chunkX, $this->chunkZ, $chunk); } } } From 6f09d472e20a647e12ce2ef2b7583c979f626998 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Dec 2020 20:17:46 +0000 Subject: [PATCH 2221/3224] WorldTimings: give timers names that actually make sense --- src/world/WorldTimings.php | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/world/WorldTimings.php b/src/world/WorldTimings.php index 5a4630c8ab..ddc2203a3a 100644 --- a/src/world/WorldTimings.php +++ b/src/world/WorldTimings.php @@ -68,25 +68,25 @@ class WorldTimings{ $name = $world->getFolderName() . " - "; $this->setBlock = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "setBlock"); - $this->doBlockLightUpdates = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "doBlockLightUpdates"); - $this->doBlockSkyLightUpdates = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "doBlockSkyLightUpdates"); + $this->doBlockLightUpdates = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Block Light Updates"); + $this->doBlockSkyLightUpdates = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Sky Light Updates"); - $this->doChunkUnload = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "doChunkUnload"); - $this->doTickPending = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "doTickPending"); - $this->doTickTiles = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "doTickTiles"); - $this->doChunkGC = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "doChunkGC"); - $this->entityTick = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "entityTick"); + $this->doChunkUnload = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Unload Chunks"); + $this->doTickPending = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Scheduled Block Updates"); + $this->doTickTiles = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Random Chunk Updates"); + $this->doChunkGC = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Garbage Collection"); + $this->entityTick = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Tick Entities"); Timings::init(); //make sure the timers we want are available - $this->syncChunkSendTimer = new TimingsHandler("** " . $name . "syncChunkSend", Timings::$playerChunkSendTimer); - $this->syncChunkSendPrepareTimer = new TimingsHandler("** " . $name . "syncChunkSendPrepare", Timings::$playerChunkSendTimer); + $this->syncChunkSendTimer = new TimingsHandler("** " . $name . "Player Send Chunks", Timings::$playerChunkSendTimer); + $this->syncChunkSendPrepareTimer = new TimingsHandler("** " . $name . "Player Send Chunk Prepare", Timings::$playerChunkSendTimer); - $this->syncChunkLoadTimer = new TimingsHandler("** " . $name . "syncChunkLoad", Timings::$worldLoadTimer); - $this->syncChunkLoadDataTimer = new TimingsHandler("** " . $name . "syncChunkLoad - Data"); - $this->syncChunkLoadEntitiesTimer = new TimingsHandler("** " . $name . "syncChunkLoad - Entities"); - $this->syncChunkLoadTileEntitiesTimer = new TimingsHandler("** " . $name . "syncChunkLoad - TileEntities"); - $this->syncChunkSaveTimer = new TimingsHandler("** " . $name . "syncChunkSave", Timings::$worldSaveTimer); + $this->syncChunkLoadTimer = new TimingsHandler("** " . $name . "Chunk Load", Timings::$worldLoadTimer); + $this->syncChunkLoadDataTimer = new TimingsHandler("** " . $name . "Chunk Load - Data"); + $this->syncChunkLoadEntitiesTimer = new TimingsHandler("** " . $name . "Chunk Load - Entities"); + $this->syncChunkLoadTileEntitiesTimer = new TimingsHandler("** " . $name . "Chunk Load - TileEntities"); + $this->syncChunkSaveTimer = new TimingsHandler("** " . $name . "Chunk Save", Timings::$worldSaveTimer); - $this->doTick = new TimingsHandler($name . "doTick"); + $this->doTick = new TimingsHandler($name . "World Tick"); } } From c0438f1ddbbb7dce018659701f46991b85d86689 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Dec 2020 21:20:37 +0000 Subject: [PATCH 2222/3224] Move player creation out of NetworkSession --- src/Server.php | 19 +++++++++++++++++++ src/network/mcpe/NetworkSession.php | 12 +----------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/Server.php b/src/Server.php index 8ae8b3f023..c9f57410c0 100644 --- a/src/Server.php +++ b/src/Server.php @@ -35,6 +35,7 @@ use pocketmine\command\SimpleCommandMap; use pocketmine\crafting\CraftingManager; use pocketmine\crafting\CraftingManagerFromDataHelper; use pocketmine\event\HandlerListManager; +use pocketmine\event\player\PlayerCreationEvent; use pocketmine\event\player\PlayerDataSaveEvent; use pocketmine\event\server\CommandEvent; use pocketmine\event\server\DataPacketSendEvent; @@ -67,6 +68,7 @@ use pocketmine\permission\DefaultPermissions; use pocketmine\player\GameMode; use pocketmine\player\OfflinePlayer; use pocketmine\player\Player; +use pocketmine\player\PlayerInfo; use pocketmine\plugin\PharPluginLoader; use pocketmine\plugin\Plugin; use pocketmine\plugin\PluginEnableOrder; @@ -575,6 +577,23 @@ class Server{ } } + public function createPlayer(NetworkSession $session, PlayerInfo $playerInfo, bool $authenticated) : Player{ + $ev = new PlayerCreationEvent($session); + $ev->call(); + $class = $ev->getPlayerClass(); + + //TODO: make this async + //TODO: what about allowing this to be provided by PlayerCreationEvent? + $namedtag = $this->getOfflinePlayerData($playerInfo->getUsername()); + + /** + * @see Player::__construct() + * @var Player $player + */ + $player = new $class($this, $session, $playerInfo, $authenticated, $namedtag); + return $player; + } + /** * Returns an online player whose name begins with or equals the given string (case insensitive). * The closest match will be returned, or null if there are no online matches. diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 0bf104bb91..f1a298c6a8 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -31,7 +31,6 @@ use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\Entity; use pocketmine\entity\Human; use pocketmine\entity\Living; -use pocketmine\event\player\PlayerCreationEvent; use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\event\server\DataPacketSendEvent; use pocketmine\form\Form; @@ -230,16 +229,7 @@ class NetworkSession{ } protected function createPlayer() : void{ - $ev = new PlayerCreationEvent($this); - $ev->call(); - $class = $ev->getPlayerClass(); - - //TODO: make this async - //TODO: this really has no business being in NetworkSession at all - what about allowing it to be provided by PlayerCreationEvent? - $namedtag = $this->server->getOfflinePlayerData($this->info->getUsername()); - - /** @see Player::__construct() */ - $this->player = new $class($this->server, $this, $this->info, $this->authenticated, $namedtag); + $this->player = $this->server->createPlayer($this, $this->info, $this->authenticated); $this->invManager = new InventoryManager($this->player, $this); From 9e11cc03dec4ca3a23a4c428ffe68052961ff53f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Dec 2020 21:38:11 +0000 Subject: [PATCH 2223/3224] Server: get rid of matchPlayer() the functionality of this API method is too specialized to be of any practical use. In addition, a search on Poggit reveals that the only uses of this API method are abuses or incorrect uses anyway. --- src/Server.php | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/Server.php b/src/Server.php index c9f57410c0..f0ba676bde 100644 --- a/src/Server.php +++ b/src/Server.php @@ -634,27 +634,6 @@ class Server{ return null; } - /** - * Returns a list of online players whose names contain with the given string (case insensitive). - * If an exact match is found, only that match is returned. - * - * @return Player[] - */ - public function matchPlayer(string $partialName) : array{ - $partialName = strtolower($partialName); - $matchedPlayers = []; - foreach($this->getOnlinePlayers() as $player){ - if(strtolower($player->getName()) === $partialName){ - $matchedPlayers = [$player]; - break; - }elseif(stripos($player->getName(), $partialName) !== false){ - $matchedPlayers[] = $player; - } - } - - return $matchedPlayers; - } - /** * Returns the player online with the specified raw UUID, or null if not found */ From 24ac5f8be00a757c5c254848d429352e8ea6764c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Dec 2020 21:41:22 +0000 Subject: [PATCH 2224/3224] Fixed craftingDataCacheRebuildTimer never being stopped --- src/network/mcpe/cache/CraftingDataCache.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/mcpe/cache/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php index 1f1c810a65..68e157499d 100644 --- a/src/network/mcpe/cache/CraftingDataCache.php +++ b/src/network/mcpe/cache/CraftingDataCache.php @@ -127,6 +127,7 @@ final class CraftingDataCache{ ); } + Timings::$craftingDataCacheRebuildTimer->stopTiming(); return $pk; } } From 48623f4e79ea44891f105d41e648d407c3b8d547 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 14 Dec 2020 18:55:52 +0000 Subject: [PATCH 2225/3224] World: add additional checks to addEntity() and removeEntity() --- src/world/World.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index 435e211aa5..ac32e65ab2 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -66,6 +66,7 @@ use pocketmine\player\Player; use pocketmine\scheduler\AsyncPool; use pocketmine\Server; use pocketmine\timings\Timings; +use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Limits; use pocketmine\utils\ReversePriorityQueue; use pocketmine\world\biome\Biome; @@ -2141,6 +2142,13 @@ class World implements ChunkManager{ if($entity->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Entity world"); } + if(array_key_exists($entity->getId(), $this->entities)){ + if($this->entities[$entity->getId()] === $entity){ + throw new \InvalidArgumentException("Entity " . $entity->getId() . " has already been added to this world"); + }else{ + throw new AssumptionFailedError("Found two different entities sharing entity ID " . $entity->getId()); + } + } $pos = $entity->getPosition()->asVector3(); $chunk = $this->getOrLoadChunkAtPosition($pos); if($chunk === null){ @@ -2164,6 +2172,9 @@ class World implements ChunkManager{ if($entity->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Entity world"); } + if(!array_key_exists($entity->getId(), $this->entities)){ + throw new \InvalidArgumentException("Entity is not tracked by this world (possibly already removed?)"); + } $pos = $this->entityLastKnownPositions[$entity->getId()]; $chunk = $this->getChunk($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4); if($chunk !== null){ //we don't care if the chunk already went out of scope From 1e737644de6cdb27d31013a63d3d4064e0836832 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 17 Dec 2020 23:49:37 +0000 Subject: [PATCH 2226/3224] World: split populateChunk() into two functions requestChunkPopulation() respects the queue size, orderChunkPopulation() does not. requestChunkPopulation() should be used for non-essential generation (which mainly includes generation for player use). orderChunkPopulation() should probably be used by plugins. --- src/player/Player.php | 2 +- src/world/World.php | 33 +++++++++++++++++++++++++++++++-- src/world/WorldManager.php | 2 +- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index c6adef475e..85cdaeee01 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -724,7 +724,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->getWorld()->registerChunkLoader($this->chunkLoader, $X, $Z, true); $this->getWorld()->registerChunkListener($this, $X, $Z); - if(!$this->getWorld()->populateChunk($X, $Z)){ + if(!$this->getWorld()->requestChunkPopulation($X, $Z)){ continue; } diff --git a/src/world/World.php b/src/world/World.php index ac32e65ab2..ada7c36704 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2589,8 +2589,37 @@ class World implements ChunkManager{ } } - public function populateChunk(int $x, int $z, bool $force = false) : bool{ - if(isset($this->chunkPopulationQueue[$index = World::chunkHash($x, $z)]) or (count($this->chunkPopulationQueue) >= $this->chunkPopulationQueueSize and !$force)){ + /** + * Attempts to initiate asynchronous generation/population of the target chunk, if it's currently reasonable to do + * so (and if it isn't already generated/populated). + * + * This method can fail for the following reasons: + * - The generation queue for this world is currently full (intended to prevent CPU overload with non-essential generation) + * - The target chunk is already being generated/populated + * - The target chunk is locked for use by another async operation (usually population) + * + * @return bool whether the chunk has been successfully populated already + * TODO: the return values don't make a lot of sense, but currently stuff depends on them :< + */ + public function requestChunkPopulation(int $chunkX, int $chunkZ) : bool{ + if(count($this->chunkPopulationQueue) >= $this->chunkPopulationQueueSize){ + return false; + } + return $this->orderChunkPopulation($chunkX, $chunkZ); + } + + /** + * Initiates asynchronous generation/population of the target chunk, if it's not already generated/populated. + * + * This method can fail for the following reasons: + * - The target chunk is already being generated/populated + * - The target chunk is locked for use by another async operation (usually population) + * + * @return bool whether the chunk has been successfully populated already + * TODO: the return values don't make sense, but currently stuff depends on them :< + */ + public function orderChunkPopulation(int $x, int $z) : bool{ + if(isset($this->chunkPopulationQueue[$index = World::chunkHash($x, $z)])){ return false; } for($xx = -1; $xx <= 1; ++$xx){ diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index dc597b84f6..0d70e96f19 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -284,7 +284,7 @@ class WorldManager{ foreach((new ChunkSelector())->selectChunks(3, $centerX, $centerZ) as $index){ World::getXZ($index, $chunkX, $chunkZ); - $world->populateChunk($chunkX, $chunkZ, true); + $world->orderChunkPopulation($chunkX, $chunkZ); } } From c5693598aaf99d188b143ef881b71ef3803e6c10 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 20 Dec 2020 21:49:55 +0000 Subject: [PATCH 2227/3224] BulkCurlTask constructor now accepts BulkCurlTaskOperation[] instead of shaped arrays --- src/command/defaults/TimingsCommand.php | 11 +-- src/scheduler/BulkCurlTask.php | 11 +-- src/scheduler/BulkCurlTaskOperation.php | 71 +++++++++++++++++++ .../check-explicit-mixed-baseline.neon | 2 +- tests/phpstan/configs/l7-baseline.neon | 2 +- 5 files changed, 87 insertions(+), 10 deletions(-) create mode 100644 src/scheduler/BulkCurlTaskOperation.php diff --git a/src/command/defaults/TimingsCommand.php b/src/command/defaults/TimingsCommand.php index d18dc55aab..6e2ece7237 100644 --- a/src/command/defaults/TimingsCommand.php +++ b/src/command/defaults/TimingsCommand.php @@ -29,6 +29,7 @@ use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; use pocketmine\player\Player; use pocketmine\scheduler\BulkCurlTask; +use pocketmine\scheduler\BulkCurlTaskOperation; use pocketmine\timings\TimingsHandler; use pocketmine\utils\InternetException; use function count; @@ -139,9 +140,11 @@ class TimingsCommand extends VanillaCommand{ */ public function __construct(CommandSender $sender, string $host, string $agent, array $data){ parent::__construct([ - [ - "page" => "https://$host?upload=true", - "extraOpts" => [ + new BulkCurlTaskOperation( + "https://$host?upload=true", + 10, + [], + [ CURLOPT_HTTPHEADER => [ "User-Agent: $agent", "Content-Type: application/x-www-form-urlencoded" @@ -151,7 +154,7 @@ class TimingsCommand extends VanillaCommand{ CURLOPT_AUTOREFERER => false, CURLOPT_FOLLOWLOCATION => false ] - ] + ) ]); $this->host = $host; $this->storeLocal(self::TLS_KEY_SENDER, $sender); diff --git a/src/scheduler/BulkCurlTask.php b/src/scheduler/BulkCurlTask.php index bd9a3b0594..b13bc989ff 100644 --- a/src/scheduler/BulkCurlTask.php +++ b/src/scheduler/BulkCurlTask.php @@ -44,20 +44,23 @@ class BulkCurlTask extends AsyncTask{ * "timeout", "extraHeaders" and "extraOpts". Documentation of these options are same as those in * {@link Utils::simpleCurl}. * - * @param mixed[][] $operations - * @phpstan-param list, extraOpts?: array}> $operations + * @param BulkCurlTaskOperation[] $operations + * @phpstan-param list $operations */ public function __construct(array $operations){ $this->operations = igbinary_serialize($operations); } public function onRun() : void{ - /** @phpstan-var list, extraOpts?: array}> $operations */ + /** + * @var BulkCurlTaskOperation[] $operations + * @phpstan-var list $operations + */ $operations = igbinary_unserialize($this->operations); $results = []; foreach($operations as $op){ try{ - $results[] = Internet::simpleCurl($op["page"], $op["timeout"] ?? 10, $op["extraHeaders"] ?? [], $op["extraOpts"] ?? []); + $results[] = Internet::simpleCurl($op->getPage(), $op->getTimeout(), $op->getExtraHeaders(), $op->getExtraOpts()); }catch(InternetException $e){ $results[] = $e; } diff --git a/src/scheduler/BulkCurlTaskOperation.php b/src/scheduler/BulkCurlTaskOperation.php new file mode 100644 index 0000000000..9050d90ad1 --- /dev/null +++ b/src/scheduler/BulkCurlTaskOperation.php @@ -0,0 +1,71 @@ + + */ + private $extraHeaders; + /** + * @var mixed[] + * @phpstan-var array + */ + private $extraOpts; + + /** + * @param string[] $extraHeaders + * @param mixed[] $extraOpts + * @phpstan-param list $extraHeaders + * @phpstan-param array $extraOpts + */ + public function __construct(string $page, float $timeout = 10, array $extraHeaders = [], array $extraOpts = []){ + $this->page = $page; + $this->timeout = $timeout; + $this->extraHeaders = $extraHeaders; + $this->extraOpts = $extraOpts; + } + + public function getPage() : string{ return $this->page; } + + public function getTimeout() : float{ return $this->timeout; } + + /** + * @return string[] + * @phpstan-return list + */ + public function getExtraHeaders() : array{ return $this->extraHeaders; } + + /** + * @return mixed[] + * @phpstan-return array + */ + public function getExtraOpts() : array{ return $this->extraOpts; } +} diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index eb753080ca..5ffcc29133 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -96,7 +96,7 @@ parameters: path: ../../../src/command/CommandReader.php - - message: "#^Parameter \\#2 \\$host of class class@anonymous/src/command/defaults/TimingsCommand\\.php\\:130 constructor expects string, mixed given\\.$#" + message: "#^Parameter \\#2 \\$host of class class@anonymous/src/command/defaults/TimingsCommand\\.php\\:131 constructor expects string, mixed given\\.$#" count: 1 path: ../../../src/command/defaults/TimingsCommand.php diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index cfc834ca88..7698f09505 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -511,7 +511,7 @@ parameters: path: ../../../src/command/defaults/TimingsCommand.php - - message: "#^Parameter \\#4 \\$data of class class@anonymous/src/command/defaults/TimingsCommand\\.php\\:130 constructor expects array\\, array\\ given\\.$#" + message: "#^Parameter \\#4 \\$data of class class@anonymous/src/command/defaults/TimingsCommand\\.php\\:131 constructor expects array\\, array\\ given\\.$#" count: 1 path: ../../../src/command/defaults/TimingsCommand.php From 2ba47a80a42ff784f84aebbcc2be722537f0dcd8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 20 Dec 2020 22:03:21 +0000 Subject: [PATCH 2228/3224] updated build.sh to build PM4 binaries for gh actions --- tests/gh-actions/build.sh | 70 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/tests/gh-actions/build.sh b/tests/gh-actions/build.sh index 3ead0ab539..27593ac4b3 100755 --- a/tests/gh-actions/build.sh +++ b/tests/gh-actions/build.sh @@ -14,10 +14,68 @@ sudo apt update && sudo apt install -y \ curl -sSL https://www.php.net/distributions/php-$VERSION.tar.gz | tar -xz INSTALL_DIR="$(pwd)/bin/php7" + +function build_leveldb { + local LEVELDB_VERSION="$1" + echo "Building LevelDB" + rm -rf "./leveldb-mcpe" || true + rm -rf "./leveldb-mcpe-build" || true + mkdir "./leveldb-mcpe" + curl -fsSL "https://github.com/pmmp/leveldb/archive/$LEVELDB_VERSION.tar.gz" | tar -zx + mv "./leveldb-$LEVELDB_VERSION" leveldb-mcpe-build + cd leveldb-mcpe-build + CFLAGS="-fPIC" CXXFLAGS="-fPIC" cmake . \ + -DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" \ + -DCMAKE_PREFIX_PATH="$INSTALL_DIR" \ + -DCMAKE_INSTALL_LIBDIR=lib \ + -DLEVELDB_BUILD_TESTS=OFF \ + -DLEVELDB_BUILD_BENCHMARKS=OFF \ + -DLEVELDB_SNAPPY=OFF \ + -DLEVELDB_ZSTD=OFF \ + -DLEVELDB_TCMALLOC=OFF \ + -DCMAKE_BUILD_TYPE=Release + make -j4 install + cd .. +} +build_leveldb 84348b9b826cc280cde659185695d2170b54824c + cd php-$VERSION cd ext/ -curl -sSL https://github.com/pmmp/pthreads/archive/2bcd8b8c10395d58b8a9bc013e3a5328080c867f.tar.gz | tar -xz -curl -sSL https://github.com/php/pecl-file_formats-yaml/archive/2.2.0.tar.gz | tar -xz + +# 1: extension name +# 2: extension version +# 3: URL to get .tar.gz from +# 4: Name of extracted directory to move +function get_extension_tar_gz { + curl -sSL "$3" | tar -zx + mv "$4" "$1" +} + +# 1: extension name +# 2: extension version +# 3: github user name +# 4: github repo name +# 5: version prefix (optional) +function get_github_extension { + get_extension_tar_gz "$1" "$2" "https://github.com/$3/$4/archive/$5$2.tar.gz" "$4-$2" +} + +get_github_extension pthreads 2bcd8b8c10395d58b8a9bc013e3a5328080c867f pmmp pthreads +get_github_extension yaml 2.2.0 php pecl-file_formats-yaml +get_github_extension leveldb 2e3f740b55af1eb6dfc648dd451bcb7d6151c26c pmmp php-leveldb +get_github_extension chunkutils2 5a4dcd6ed74e0db2ca9a54948d4f3a065e386db5 pmmp ext-chunkutils2 +get_github_extension morton 0.1.2 pmmp ext-morton +get_github_extension igbinary 3.1.4 igbinary igbinary +get_github_extension ds 2ddef84d3e9391c37599cb716592184315e23921 php-ds ext-ds + +rm -rf crypto +git clone --recursive https://github.com/bukka/php-crypto.git crypto +cd crypto +git checkout -qf 5f26ac91b0ba96742cc6284cd00f8db69c3788b2 +git submodule update --init --recursive +cd .. + + cd .. CFLAGS="$CFLAGS -march=x86-64" @@ -49,6 +107,12 @@ CXXFLAGS="$CXXFLAGS -march=x86-64" --with-zlib \ --with-zip \ --with-gmp \ - --with-openssl + --with-openssl \ + --with-leveldb="$INSTALL_DIR" \ + --enable-igbinary \ + --enable-morton \ + --enable-chunkutils2 \ + --enable-ds \ + --with-crypto \ make -j8 install From e762b79aaeb12002a35528bc43a59322f13e32ea Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 21 Dec 2020 00:09:49 +0000 Subject: [PATCH 2229/3224] Player: fixed setPosition() resending all the chunks closes #3977 --- src/player/Player.php | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 85cdaeee01..03fc38a7a1 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -651,16 +651,19 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ protected function setPosition(Vector3 $pos) : bool{ $oldWorld = $this->location->isValid() ? $this->location->getWorld() : null; if(parent::setPosition($pos)){ - if($oldWorld !== null){ - foreach($this->usedChunks as $index => $status){ - World::getXZ($index, $X, $Z); - $this->unloadChunk($X, $Z, $oldWorld); + $newWorld = $this->getWorld(); + if($oldWorld !== $newWorld){ + if($oldWorld !== null){ + foreach($this->usedChunks as $index => $status){ + World::getXZ($index, $X, $Z); + $this->unloadChunk($X, $Z, $oldWorld); + } } - } - $this->usedChunks = []; - $this->loadQueue = []; - $this->networkSession->onEnterWorld(); + $this->usedChunks = []; + $this->loadQueue = []; + $this->networkSession->onEnterWorld(); + } return true; } From bcc3e8773068dd0afab343bb79add11ce5b19b40 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 23 Dec 2020 17:52:25 +0000 Subject: [PATCH 2230/3224] Timings: rename core timers to remove 'timer' from the names this makes them shorter and more consistent. --- src/MemoryManager.php | 8 +- src/Server.php | 28 ++-- src/entity/Entity.php | 8 +- src/entity/Living.php | 4 +- src/entity/projectile/Projectile.php | 4 +- src/network/mcpe/NetworkSession.php | 16 +- src/network/mcpe/cache/ChunkCache.php | 4 +- src/network/mcpe/cache/CraftingDataCache.php | 4 +- src/permission/PermissibleBase.php | 8 +- src/player/Player.php | 20 +-- src/timings/Timings.php | 146 +++++++++---------- src/world/World.php | 38 ++--- src/world/WorldManager.php | 4 +- src/world/WorldTimings.php | 28 ++-- 14 files changed, 160 insertions(+), 160 deletions(-) diff --git a/src/MemoryManager.php b/src/MemoryManager.php index 0dcafa1c3e..1625339039 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -228,7 +228,7 @@ class MemoryManager{ * Called every tick to update the memory manager state. */ public function check() : void{ - Timings::$memoryManagerTimer->startTiming(); + Timings::$memoryManager->startTiming(); if(($this->memoryLimit > 0 or $this->globalMemoryLimit > 0) and ++$this->checkTicker >= $this->checkRate){ $this->checkTicker = 0; @@ -261,11 +261,11 @@ class MemoryManager{ $this->triggerGarbageCollector(); } - Timings::$memoryManagerTimer->stopTiming(); + Timings::$memoryManager->stopTiming(); } public function triggerGarbageCollector() : int{ - Timings::$garbageCollectorTimer->startTiming(); + Timings::$garbageCollector->startTiming(); if($this->garbageCollectionAsync){ $pool = $this->server->getAsyncPool(); @@ -280,7 +280,7 @@ class MemoryManager{ $cycles = gc_collect_cycles(); gc_mem_caches(); - Timings::$garbageCollectorTimer->stopTiming(); + Timings::$garbageCollector->stopTiming(); return $cycles; } diff --git a/src/Server.php b/src/Server.php index 9de0e7a328..5280bb482b 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1079,11 +1079,11 @@ class Server{ $consoleNotifier = new SleeperNotifier(); $this->console = new CommandReader($consoleNotifier); $this->tickSleeper->addNotifier($consoleNotifier, function() use ($consoleSender) : void{ - Timings::$serverCommandTimer->startTiming(); + Timings::$serverCommand->startTiming(); while(($line = $this->console->getLine()) !== null){ $this->dispatchCommand($consoleSender, $line); } - Timings::$serverCommandTimer->stopTiming(); + Timings::$serverCommand->stopTiming(); }); $this->console->start(PTHREADS_INHERIT_NONE); @@ -1255,7 +1255,7 @@ class Server{ */ public function prepareBatch(PacketBatch $stream, Compressor $compressor, ?bool $sync = null) : CompressBatchPromise{ try{ - Timings::$playerNetworkSendCompressTimer->startTiming(); + Timings::$playerNetworkSendCompress->startTiming(); $buffer = $stream->getBuffer(); @@ -1273,7 +1273,7 @@ class Server{ return $promise; }finally{ - Timings::$playerNetworkSendCompressTimer->stopTiming(); + Timings::$playerNetworkSendCompress->stopTiming(); } } @@ -1595,7 +1595,7 @@ class Server{ } private function titleTick() : void{ - Timings::$titleTickTimer->startTiming(); + Timings::$titleTick->startTiming(); $d = Process::getRealMemoryUsage(); $u = Process::getAdvancedMemoryUsage(); @@ -1615,7 +1615,7 @@ class Server{ " kB/s | TPS " . $this->getTicksPerSecondAverage() . " | Load " . $this->getTickUsageAverage() . "%\x07"; - Timings::$titleTickTimer->stopTiming(); + Timings::$titleTick->stopTiming(); } /** @@ -1627,23 +1627,23 @@ class Server{ return; } - Timings::$serverTickTimer->startTiming(); + Timings::$serverTick->startTiming(); ++$this->tickCounter; - Timings::$schedulerTimer->startTiming(); + Timings::$scheduler->startTiming(); $this->pluginManager->tickSchedulers($this->tickCounter); - Timings::$schedulerTimer->stopTiming(); + Timings::$scheduler->stopTiming(); - Timings::$schedulerAsyncTimer->startTiming(); + Timings::$schedulerAsync->startTiming(); $this->asyncPool->collectTasks(); - Timings::$schedulerAsyncTimer->stopTiming(); + Timings::$schedulerAsync->stopTiming(); $this->worldManager->tick($this->tickCounter); - Timings::$connectionTimer->startTiming(); + Timings::$connection->startTiming(); $this->network->tick(); - Timings::$connectionTimer->stopTiming(); + Timings::$connection->stopTiming(); if(($this->tickCounter % 20) === 0){ if($this->doTitleTick){ @@ -1677,7 +1677,7 @@ class Server{ $this->getMemoryManager()->check(); - Timings::$serverTickTimer->stopTiming(); + Timings::$serverTick->stopTiming(); $now = microtime(true); $this->currentTPS = min(20, 1 / max(0.001, $now - $tickTime)); diff --git a/src/entity/Entity.php b/src/entity/Entity.php index ce18440ab7..a84c742457 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -959,9 +959,9 @@ abstract class Entity{ $this->updateMovement(); - Timings::$timerEntityBaseTick->startTiming(); + Timings::$entityBaseTick->startTiming(); $hasUpdate = $this->entityBaseTick($tickDiff); - Timings::$timerEntityBaseTick->stopTiming(); + Timings::$entityBaseTick->stopTiming(); $this->timings->stopTiming(); @@ -1073,7 +1073,7 @@ abstract class Entity{ protected function move(float $dx, float $dy, float $dz) : void{ $this->blocksAround = null; - Timings::$entityMoveTimer->startTiming(); + Timings::$entityMove->startTiming(); $movX = $dx; $movY = $dy; @@ -1219,7 +1219,7 @@ abstract class Entity{ //TODO: vehicle collision events (first we need to spawn them!) - Timings::$entityMoveTimer->stopTiming(); + Timings::$entityMove->stopTiming(); } protected function checkGroundState(float $movX, float $movY, float $movZ, float $dx, float $dy, float $dz) : void{ diff --git a/src/entity/Living.php b/src/entity/Living.php index 8475983ec3..08890698e1 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -552,7 +552,7 @@ abstract class Living extends Entity{ } protected function entityBaseTick(int $tickDiff = 1) : bool{ - Timings::$timerLivingEntityBaseTick->startTiming(); + Timings::$livingEntityBaseTick->startTiming(); $hasUpdate = parent::entityBaseTick($tickDiff); @@ -576,7 +576,7 @@ abstract class Living extends Entity{ $this->attackTime -= $tickDiff; } - Timings::$timerLivingEntityBaseTick->stopTiming(); + Timings::$livingEntityBaseTick->stopTiming(); return $hasUpdate; } diff --git a/src/entity/projectile/Projectile.php b/src/entity/projectile/Projectile.php index c95c38ff08..944728452f 100644 --- a/src/entity/projectile/Projectile.php +++ b/src/entity/projectile/Projectile.php @@ -173,7 +173,7 @@ abstract class Projectile extends Entity{ public function move(float $dx, float $dy, float $dz) : void{ $this->blocksAround = null; - Timings::$entityMoveTimer->startTiming(); + Timings::$entityMove->startTiming(); $start = $this->location->asVector3(); $end = $start->addVector($this->motion); @@ -264,7 +264,7 @@ abstract class Projectile extends Entity{ $this->getWorld()->onEntityMoved($this); $this->checkBlockCollision(); - Timings::$entityMoveTimer->stopTiming(); + Timings::$entityMove->stopTiming(); } /** diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index f1a298c6a8..33db8255dc 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -316,25 +316,25 @@ class NetworkSession{ } if($this->cipher !== null){ - Timings::$playerNetworkReceiveDecryptTimer->startTiming(); + Timings::$playerNetworkReceiveDecrypt->startTiming(); try{ $payload = $this->cipher->decrypt($payload); }catch(DecryptionException $e){ $this->logger->debug("Encrypted packet: " . base64_encode($payload)); throw BadPacketException::wrap($e, "Packet decryption error"); }finally{ - Timings::$playerNetworkReceiveDecryptTimer->stopTiming(); + Timings::$playerNetworkReceiveDecrypt->stopTiming(); } } - Timings::$playerNetworkReceiveDecompressTimer->startTiming(); + Timings::$playerNetworkReceiveDecompress->startTiming(); try{ $stream = new PacketBatch($this->compressor->decompress($payload)); }catch(DecompressionException $e){ $this->logger->debug("Failed to decompress packet: " . base64_encode($payload)); throw BadPacketException::wrap($e, "Compressed packet batch decode error"); }finally{ - Timings::$playerNetworkReceiveDecompressTimer->stopTiming(); + Timings::$playerNetworkReceiveDecompress->stopTiming(); } try{ @@ -484,9 +484,9 @@ class NetworkSession{ private function sendEncoded(string $payload, bool $immediate = false) : void{ if($this->cipher !== null){ - Timings::$playerNetworkSendEncryptTimer->startTiming(); + Timings::$playerNetworkSendEncrypt->startTiming(); $payload = $this->cipher->encrypt($payload); - Timings::$playerNetworkSendEncryptTimer->stopTiming(); + Timings::$playerNetworkSendEncrypt->stopTiming(); } $this->sender->send($payload, $immediate); } @@ -859,12 +859,12 @@ class NetworkSession{ $this->logger->debug("Tried to send no-longer-active chunk $chunkX $chunkZ in world " . $world->getFolderName()); return; } - $currentWorld->timings->syncChunkSendTimer->startTiming(); + $currentWorld->timings->syncChunkSend->startTiming(); try{ $this->queueCompressed($promise); $onCompletion($chunkX, $chunkZ); }finally{ - $currentWorld->timings->syncChunkSendTimer->stopTiming(); + $currentWorld->timings->syncChunkSend->stopTiming(); } } ); diff --git a/src/network/mcpe/cache/ChunkCache.php b/src/network/mcpe/cache/ChunkCache.php index 8dd8b85156..dd2f4503f8 100644 --- a/src/network/mcpe/cache/ChunkCache.php +++ b/src/network/mcpe/cache/ChunkCache.php @@ -107,7 +107,7 @@ class ChunkCache implements ChunkListener{ ++$this->misses; - $this->world->timings->syncChunkSendPrepareTimer->startTiming(); + $this->world->timings->syncChunkSendPrepare->startTiming(); try{ $this->caches[$chunkHash] = new CompressBatchPromise(); @@ -128,7 +128,7 @@ class ChunkCache implements ChunkListener{ return $this->caches[$chunkHash]; }finally{ - $this->world->timings->syncChunkSendPrepareTimer->stopTiming(); + $this->world->timings->syncChunkSendPrepare->stopTiming(); } } diff --git a/src/network/mcpe/cache/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php index 68e157499d..55aa2c1f34 100644 --- a/src/network/mcpe/cache/CraftingDataCache.php +++ b/src/network/mcpe/cache/CraftingDataCache.php @@ -67,7 +67,7 @@ final class CraftingDataCache{ * Rebuilds the cached CraftingDataPacket. */ private function buildCraftingDataCache(CraftingManager $manager) : CraftingDataPacket{ - Timings::$craftingDataCacheRebuildTimer->startTiming(); + Timings::$craftingDataCacheRebuild->startTiming(); $pk = new CraftingDataPacket(); $pk->cleanRecipes = true; @@ -127,7 +127,7 @@ final class CraftingDataCache{ ); } - Timings::$craftingDataCacheRebuildTimer->stopTiming(); + Timings::$craftingDataCacheRebuild->stopTiming(); return $pk; } } diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index 3cff6afc18..0f8f82163d 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -130,7 +130,7 @@ class PermissibleBase implements Permissible{ } public function recalculatePermissions() : array{ - Timings::$permissibleCalculationTimer->startTiming(); + Timings::$permissibleCalculation->startTiming(); $permManager = PermissionManager::getInstance(); $permManager->unsubscribeFromAllPermissions($this); @@ -152,7 +152,7 @@ class PermissibleBase implements Permissible{ } $diff = []; - Timings::$permissibleCalculationDiffTimer->time(function() use ($oldPermissions, &$diff) : void{ + Timings::$permissibleCalculationDiff->time(function() use ($oldPermissions, &$diff) : void{ foreach($this->permissions as $permissionAttachmentInfo){ $name = $permissionAttachmentInfo->getPermission(); if(!isset($oldPermissions[$name])){ @@ -168,7 +168,7 @@ class PermissibleBase implements Permissible{ } }); - Timings::$permissibleCalculationCallbackTimer->time(function() use ($diff) : void{ + Timings::$permissibleCalculationCallback->time(function() use ($diff) : void{ if(count($diff) > 0){ foreach($this->permissionRecalculationCallbacks as $closure){ $closure($diff); @@ -176,7 +176,7 @@ class PermissibleBase implements Permissible{ } }); - Timings::$permissibleCalculationTimer->stopTiming(); + Timings::$permissibleCalculation->stopTiming(); return $diff; } diff --git a/src/player/Player.php b/src/player/Player.php index 03fc38a7a1..c60db4b12e 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -708,7 +708,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return; } - Timings::$playerChunkSendTimer->startTiming(); + Timings::$playerChunkSend->startTiming(); $count = 0; foreach($this->loadQueue as $index => $distance){ @@ -753,7 +753,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ }); } - Timings::$playerChunkSendTimer->stopTiming(); + Timings::$playerChunkSend->stopTiming(); } private function recheckBroadcastPermissions() : void{ @@ -814,7 +814,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return; } - Timings::$playerChunkOrderTimer->startTiming(); + Timings::$playerChunkOrder->startTiming(); $newOrder = []; $unloadChunks = $this->usedChunks; @@ -841,7 +841,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->networkSession->syncViewAreaCenterPoint($this->location, $this->viewDistance); } - Timings::$playerChunkOrderTimer->stopTiming(); + Timings::$playerChunkOrder->stopTiming(); } /** @@ -1299,14 +1299,14 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->inAirTicks += $tickDiff; } - Timings::$timerEntityBaseTick->startTiming(); + Timings::$entityBaseTick->startTiming(); $this->entityBaseTick($tickDiff); - Timings::$timerEntityBaseTick->stopTiming(); + Timings::$entityBaseTick->stopTiming(); if(!$this->isSpectator() and $this->isAlive()){ - Timings::$playerCheckNearEntitiesTimer->startTiming(); + Timings::$playerCheckNearEntities->startTiming(); $this->checkNearEntities(); - Timings::$playerCheckNearEntitiesTimer->stopTiming(); + Timings::$playerCheckNearEntities->stopTiming(); } if($this->blockBreakHandler !== null and !$this->blockBreakHandler->update()){ @@ -1362,9 +1362,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } if(strpos($ev->getMessage(), "/") === 0){ - Timings::$playerCommandTimer->startTiming(); + Timings::$playerCommand->startTiming(); $this->server->dispatchCommand($ev->getPlayer(), substr($ev->getMessage(), 1)); - Timings::$playerCommandTimer->stopTiming(); + Timings::$playerCommand->stopTiming(); }else{ $ev = new PlayerChatEvent($this, $ev->getMessage(), $this->server->getBroadcastChannelSubscribers(Server::BROADCAST_CHANNEL_USERS)); $ev->call(); diff --git a/src/timings/Timings.php b/src/timings/Timings.php index 586a0c1a6c..c0176cc604 100644 --- a/src/timings/Timings.php +++ b/src/timings/Timings.php @@ -38,76 +38,76 @@ abstract class Timings{ private static $initialized = false; /** @var TimingsHandler */ - public static $fullTickTimer; + public static $fullTick; /** @var TimingsHandler */ - public static $serverTickTimer; + public static $serverTick; /** @var TimingsHandler */ - public static $memoryManagerTimer; + public static $memoryManager; /** @var TimingsHandler */ - public static $garbageCollectorTimer; + public static $garbageCollector; /** @var TimingsHandler */ - public static $titleTickTimer; + public static $titleTick; /** @var TimingsHandler */ - public static $playerNetworkSendTimer; + public static $playerNetworkSend; /** @var TimingsHandler */ - public static $playerNetworkSendCompressTimer; + public static $playerNetworkSendCompress; /** @var TimingsHandler */ - public static $playerNetworkSendEncryptTimer; + public static $playerNetworkSendEncrypt; /** @var TimingsHandler */ - public static $playerNetworkReceiveTimer; + public static $playerNetworkReceive; /** @var TimingsHandler */ - public static $playerNetworkReceiveDecompressTimer; + public static $playerNetworkReceiveDecompress; /** @var TimingsHandler */ - public static $playerNetworkReceiveDecryptTimer; + public static $playerNetworkReceiveDecrypt; /** @var TimingsHandler */ - public static $playerChunkOrderTimer; + public static $playerChunkOrder; /** @var TimingsHandler */ - public static $playerChunkSendTimer; + public static $playerChunkSend; /** @var TimingsHandler */ - public static $connectionTimer; + public static $connection; /** @var TimingsHandler */ - public static $schedulerTimer; + public static $scheduler; /** @var TimingsHandler */ - public static $serverCommandTimer; + public static $serverCommand; /** @var TimingsHandler */ - public static $worldLoadTimer; + public static $worldLoad; /** @var TimingsHandler */ - public static $worldSaveTimer; + public static $worldSave; /** @var TimingsHandler */ - public static $populationTimer; + public static $population; /** @var TimingsHandler */ - public static $generationCallbackTimer; + public static $generationCallback; /** @var TimingsHandler */ - public static $permissibleCalculationTimer; + public static $permissibleCalculation; /** @var TimingsHandler */ - public static $permissibleCalculationDiffTimer; + public static $permissibleCalculationDiff; /** @var TimingsHandler */ - public static $permissibleCalculationCallbackTimer; + public static $permissibleCalculationCallback; /** @var TimingsHandler */ - public static $entityMoveTimer; + public static $entityMove; /** @var TimingsHandler */ - public static $playerCheckNearEntitiesTimer; + public static $playerCheckNearEntities; /** @var TimingsHandler */ - public static $tickEntityTimer; + public static $tickEntity; /** @var TimingsHandler */ - public static $tickTileEntityTimer; + public static $tickTileEntity; /** @var TimingsHandler */ - public static $timerEntityBaseTick; + public static $entityBaseTick; /** @var TimingsHandler */ - public static $timerLivingEntityBaseTick; + public static $livingEntityBaseTick; /** @var TimingsHandler */ - public static $schedulerSyncTimer; + public static $schedulerSync; /** @var TimingsHandler */ - public static $schedulerAsyncTimer; + public static $schedulerAsync; /** @var TimingsHandler */ - public static $playerCommandTimer; + public static $playerCommand; /** @var TimingsHandler */ - public static $craftingDataCacheRebuildTimer; + public static $craftingDataCacheRebuild; /** @var TimingsHandler */ public static $syncPlayerDataLoad; @@ -134,51 +134,51 @@ abstract class Timings{ } self::$initialized = true; - self::$fullTickTimer = new TimingsHandler("Full Server Tick"); - self::$serverTickTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Full Server Tick", self::$fullTickTimer); - self::$memoryManagerTimer = new TimingsHandler("Memory Manager"); - self::$garbageCollectorTimer = new TimingsHandler("Garbage Collector", self::$memoryManagerTimer); - self::$titleTickTimer = new TimingsHandler("Console Title Tick"); + self::$fullTick = new TimingsHandler("Full Server Tick"); + self::$serverTick = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Full Server Tick", self::$fullTick); + self::$memoryManager = new TimingsHandler("Memory Manager"); + self::$garbageCollector = new TimingsHandler("Garbage Collector", self::$memoryManager); + self::$titleTick = new TimingsHandler("Console Title Tick"); - self::$playerNetworkSendTimer = new TimingsHandler("Player Network Send"); - self::$playerNetworkSendCompressTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Player Network Send - Compression", self::$playerNetworkSendTimer); - self::$playerNetworkSendEncryptTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Player Network Send - Encryption", self::$playerNetworkSendTimer); + self::$playerNetworkSend = new TimingsHandler("Player Network Send"); + self::$playerNetworkSendCompress = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Player Network Send - Compression", self::$playerNetworkSend); + self::$playerNetworkSendEncrypt = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Player Network Send - Encryption", self::$playerNetworkSend); - self::$playerNetworkReceiveTimer = new TimingsHandler("Player Network Receive"); - self::$playerNetworkReceiveDecompressTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Player Network Receive - Decompression", self::$playerNetworkReceiveTimer); - self::$playerNetworkReceiveDecryptTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Player Network Receive - Decryption", self::$playerNetworkReceiveTimer); + self::$playerNetworkReceive = new TimingsHandler("Player Network Receive"); + self::$playerNetworkReceiveDecompress = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Player Network Receive - Decompression", self::$playerNetworkReceive); + self::$playerNetworkReceiveDecrypt = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Player Network Receive - Decryption", self::$playerNetworkReceive); - self::$broadcastPackets = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Broadcast Packets", self::$playerNetworkSendTimer); + self::$broadcastPackets = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Broadcast Packets", self::$playerNetworkSend); - self::$playerChunkOrderTimer = new TimingsHandler("Player Order Chunks"); - self::$playerChunkSendTimer = new TimingsHandler("Player Send Chunks"); - self::$connectionTimer = new TimingsHandler("Connection Handler"); - self::$schedulerTimer = new TimingsHandler("Scheduler"); - self::$serverCommandTimer = new TimingsHandler("Server Command"); - self::$worldLoadTimer = new TimingsHandler("World Load"); - self::$worldSaveTimer = new TimingsHandler("World Save"); - self::$populationTimer = new TimingsHandler("World Population"); - self::$generationCallbackTimer = new TimingsHandler("World Generation Callback"); - self::$permissibleCalculationTimer = new TimingsHandler("Permissible Calculation"); - self::$permissibleCalculationDiffTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Permissible Calculation - Diff", self::$permissibleCalculationTimer); - self::$permissibleCalculationCallbackTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Permissible Calculation - Callbacks", self::$permissibleCalculationTimer); + self::$playerChunkOrder = new TimingsHandler("Player Order Chunks"); + self::$playerChunkSend = new TimingsHandler("Player Send Chunks"); + self::$connection = new TimingsHandler("Connection Handler"); + self::$scheduler = new TimingsHandler("Scheduler"); + self::$serverCommand = new TimingsHandler("Server Command"); + self::$worldLoad = new TimingsHandler("World Load"); + self::$worldSave = new TimingsHandler("World Save"); + self::$population = new TimingsHandler("World Population"); + self::$generationCallback = new TimingsHandler("World Generation Callback"); + self::$permissibleCalculation = new TimingsHandler("Permissible Calculation"); + self::$permissibleCalculationDiff = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Permissible Calculation - Diff", self::$permissibleCalculation); + self::$permissibleCalculationCallback = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Permissible Calculation - Callbacks", self::$permissibleCalculation); self::$syncPlayerDataLoad = new TimingsHandler("Player Data Load"); self::$syncPlayerDataSave = new TimingsHandler("Player Data Save"); - self::$entityMoveTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "entityMove"); - self::$playerCheckNearEntitiesTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "checkNearEntities"); - self::$tickEntityTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "tickEntity"); - self::$tickTileEntityTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "tickTileEntity"); + self::$entityMove = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "entityMove"); + self::$playerCheckNearEntities = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "checkNearEntities"); + self::$tickEntity = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "tickEntity"); + self::$tickTileEntity = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "tickTileEntity"); - self::$timerEntityBaseTick = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "entityBaseTick"); - self::$timerLivingEntityBaseTick = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "livingEntityBaseTick"); + self::$entityBaseTick = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "entityBaseTick"); + self::$livingEntityBaseTick = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "livingEntityBaseTick"); - self::$schedulerSyncTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Scheduler - Sync Tasks"); - self::$schedulerAsyncTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Scheduler - Async Tasks"); + self::$schedulerSync = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Scheduler - Sync Tasks"); + self::$schedulerAsync = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "Scheduler - Async Tasks"); - self::$playerCommandTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "playerCommand"); - self::$craftingDataCacheRebuildTimer = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "craftingDataCacheRebuild"); + self::$playerCommand = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "playerCommand"); + self::$craftingDataCacheRebuild = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "craftingDataCacheRebuild"); } @@ -192,7 +192,7 @@ abstract class Timings{ } if(!isset(self::$pluginTaskTimingMap[$name])){ - self::$pluginTaskTimingMap[$name] = new TimingsHandler($name, self::$schedulerSyncTimer); + self::$pluginTaskTimingMap[$name] = new TimingsHandler($name, self::$schedulerSync); } return self::$pluginTaskTimingMap[$name]; @@ -202,9 +202,9 @@ abstract class Timings{ $entityType = (new \ReflectionClass($entity))->getShortName(); if(!isset(self::$entityTypeTimingMap[$entityType])){ if($entity instanceof Player){ - self::$entityTypeTimingMap[$entityType] = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "tickEntity - EntityPlayer", self::$tickEntityTimer); + self::$entityTypeTimingMap[$entityType] = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "tickEntity - EntityPlayer", self::$tickEntity); }else{ - self::$entityTypeTimingMap[$entityType] = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "tickEntity - " . $entityType, self::$tickEntityTimer); + self::$entityTypeTimingMap[$entityType] = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "tickEntity - " . $entityType, self::$tickEntity); } } @@ -214,7 +214,7 @@ abstract class Timings{ public static function getTileEntityTimings(Tile $tile) : TimingsHandler{ $tileType = (new \ReflectionClass($tile))->getShortName(); if(!isset(self::$tileEntityTypeTimingMap[$tileType])){ - self::$tileEntityTypeTimingMap[$tileType] = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "tickTileEntity - " . $tileType, self::$tickTileEntityTimer); + self::$tileEntityTypeTimingMap[$tileType] = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "tickTileEntity - " . $tileType, self::$tickTileEntity); } return self::$tileEntityTypeTimingMap[$tileType]; @@ -224,7 +224,7 @@ abstract class Timings{ $pid = $pk->pid(); if(!isset(self::$packetReceiveTimingMap[$pid])){ $pkName = (new \ReflectionClass($pk))->getShortName(); - self::$packetReceiveTimingMap[$pid] = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "receivePacket - " . $pkName . " [0x" . dechex($pid) . "]", self::$playerNetworkReceiveTimer); + self::$packetReceiveTimingMap[$pid] = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "receivePacket - " . $pkName . " [0x" . dechex($pid) . "]", self::$playerNetworkReceive); } return self::$packetReceiveTimingMap[$pid]; @@ -234,7 +234,7 @@ abstract class Timings{ $pid = $pk->pid(); if(!isset(self::$packetSendTimingMap[$pid])){ $pkName = (new \ReflectionClass($pk))->getShortName(); - self::$packetSendTimingMap[$pid] = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "sendPacket - " . $pkName . " [0x" . dechex($pid) . "]", self::$playerNetworkSendTimer); + self::$packetSendTimingMap[$pid] = new TimingsHandler(self::INCLUDED_BY_OTHER_TIMINGS_PREFIX . "sendPacket - " . $pkName . " [0x" . dechex($pid) . "]", self::$playerNetworkSend); } return self::$packetSendTimingMap[$pid]; diff --git a/src/world/World.php b/src/world/World.php index ada7c36704..944cdecec1 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -787,7 +787,7 @@ class World implements ChunkManager{ $this->timings->entityTick->startTiming(); //Update entities that need update - Timings::$tickEntityTimer->startTiming(); + Timings::$tickEntity->startTiming(); foreach($this->updateEntities as $id => $entity){ if($entity->isClosed() or !$entity->onUpdate($currentTick)){ unset($this->updateEntities[$id]); @@ -796,7 +796,7 @@ class World implements ChunkManager{ $entity->close(); } } - Timings::$tickEntityTimer->stopTiming(); + Timings::$tickEntity->stopTiming(); $this->timings->entityTick->stopTiming(); $this->timings->doTickTiles->startTiming(); @@ -1039,7 +1039,7 @@ class World implements ChunkManager{ } public function saveChunks() : void{ - $this->timings->syncChunkSaveTimer->startTiming(); + $this->timings->syncChunkSave->startTiming(); try{ foreach($this->chunks as $chunkHash => $chunk){ if($chunk->isDirty()){ @@ -1049,7 +1049,7 @@ class World implements ChunkManager{ } } }finally{ - $this->timings->syncChunkSaveTimer->stopTiming(); + $this->timings->syncChunkSave->stopTiming(); } } @@ -1997,7 +1997,7 @@ class World implements ChunkManager{ } public function generateChunkCallback(int $x, int $z, ?Chunk $chunk) : void{ - Timings::$generationCallbackTimer->startTiming(); + Timings::$generationCallback->startTiming(); if(isset($this->chunkPopulationQueue[$index = World::chunkHash($x, $z)])){ for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ @@ -2025,7 +2025,7 @@ class World implements ChunkManager{ }elseif($chunk !== null){ $this->setChunk($x, $z, $chunk, false); } - Timings::$generationCallbackTimer->stopTiming(); + Timings::$generationCallback->stopTiming(); } /** @@ -2303,11 +2303,11 @@ class World implements ChunkManager{ return $this->chunks[$chunkHash]; } - $this->timings->syncChunkLoadTimer->startTiming(); + $this->timings->syncChunkLoad->startTiming(); $this->cancelUnloadChunkRequest($x, $z); - $this->timings->syncChunkLoadDataTimer->startTiming(); + $this->timings->syncChunkLoadData->startTiming(); $chunk = null; @@ -2317,10 +2317,10 @@ class World implements ChunkManager{ $this->logger->critical("Failed to load chunk x=$x z=$z: " . $e->getMessage()); } - $this->timings->syncChunkLoadDataTimer->stopTiming(); + $this->timings->syncChunkLoadData->stopTiming(); if($chunk === null){ - $this->timings->syncChunkLoadTimer->stopTiming(); + $this->timings->syncChunkLoad->stopTiming(); return null; } @@ -2339,14 +2339,14 @@ class World implements ChunkManager{ $listener->onChunkLoaded($x, $z, $chunk); } - $this->timings->syncChunkLoadTimer->stopTiming(); + $this->timings->syncChunkLoad->stopTiming(); return $chunk; } private function initChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ if($chunk->NBTentities !== null){ - $this->timings->syncChunkLoadEntitiesTimer->startTiming(); + $this->timings->syncChunkLoadEntities->startTiming(); $entityFactory = EntityFactory::getInstance(); foreach($chunk->NBTentities as $nbt){ try{ @@ -2370,10 +2370,10 @@ class World implements ChunkManager{ $chunk->setDirtyFlag(Chunk::DIRTY_FLAG_ENTITIES, true); $chunk->NBTentities = null; - $this->timings->syncChunkLoadEntitiesTimer->stopTiming(); + $this->timings->syncChunkLoadEntities->stopTiming(); } if($chunk->NBTtiles !== null){ - $this->timings->syncChunkLoadTileEntitiesTimer->startTiming(); + $this->timings->syncChunkLoadTileEntities->startTiming(); $tileFactory = TileFactory::getInstance(); foreach($chunk->NBTtiles as $nbt){ if(($tile = $tileFactory->createFromData($this, $nbt)) !== null){ @@ -2386,7 +2386,7 @@ class World implements ChunkManager{ $chunk->setDirtyFlag(Chunk::DIRTY_FLAG_TILES, true); $chunk->NBTtiles = null; - $this->timings->syncChunkLoadTileEntitiesTimer->stopTiming(); + $this->timings->syncChunkLoadTileEntities->stopTiming(); } } @@ -2433,11 +2433,11 @@ class World implements ChunkManager{ } if($trySave and $this->getAutoSave() and $chunk->isDirty()){ - $this->timings->syncChunkSaveTimer->startTiming(); + $this->timings->syncChunkSave->startTiming(); try{ $this->provider->saveChunk($x, $z, $chunk); }finally{ - $this->timings->syncChunkSaveTimer->stopTiming(); + $this->timings->syncChunkSave->stopTiming(); } } @@ -2632,7 +2632,7 @@ class World implements ChunkManager{ $chunk = $this->loadChunk($x, $z); if($chunk === null || !$chunk->isPopulated()){ - Timings::$populationTimer->startTiming(); + Timings::$population->startTiming(); $this->chunkPopulationQueue[$index] = true; for($xx = -1; $xx <= 1; ++$xx){ @@ -2648,7 +2648,7 @@ class World implements ChunkManager{ } $this->workerPool->submitTaskToWorker($task, $workerId); - Timings::$populationTimer->stopTiming(); + Timings::$population->stopTiming(); return false; } diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 0d70e96f19..fe4f992e10 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -374,7 +374,7 @@ class WorldManager{ } private function doAutoSave() : void{ - Timings::$worldSaveTimer->startTiming(); + Timings::$worldSave->startTiming(); foreach($this->worlds as $world){ foreach($world->getPlayers() as $player){ if($player->spawned){ @@ -383,6 +383,6 @@ class WorldManager{ } $world->save(false); } - Timings::$worldSaveTimer->stopTiming(); + Timings::$worldSave->stopTiming(); } } diff --git a/src/world/WorldTimings.php b/src/world/WorldTimings.php index ddc2203a3a..c3e6e98b23 100644 --- a/src/world/WorldTimings.php +++ b/src/world/WorldTimings.php @@ -49,20 +49,20 @@ class WorldTimings{ public $doTick; /** @var TimingsHandler */ - public $syncChunkSendTimer; + public $syncChunkSend; /** @var TimingsHandler */ - public $syncChunkSendPrepareTimer; + public $syncChunkSendPrepare; /** @var TimingsHandler */ - public $syncChunkLoadTimer; + public $syncChunkLoad; /** @var TimingsHandler */ - public $syncChunkLoadDataTimer; + public $syncChunkLoadData; /** @var TimingsHandler */ - public $syncChunkLoadEntitiesTimer; + public $syncChunkLoadEntities; /** @var TimingsHandler */ - public $syncChunkLoadTileEntitiesTimer; + public $syncChunkLoadTileEntities; /** @var TimingsHandler */ - public $syncChunkSaveTimer; + public $syncChunkSave; public function __construct(World $world){ $name = $world->getFolderName() . " - "; @@ -78,14 +78,14 @@ class WorldTimings{ $this->entityTick = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Tick Entities"); Timings::init(); //make sure the timers we want are available - $this->syncChunkSendTimer = new TimingsHandler("** " . $name . "Player Send Chunks", Timings::$playerChunkSendTimer); - $this->syncChunkSendPrepareTimer = new TimingsHandler("** " . $name . "Player Send Chunk Prepare", Timings::$playerChunkSendTimer); + $this->syncChunkSend = new TimingsHandler("** " . $name . "Player Send Chunks", Timings::$playerChunkSend); + $this->syncChunkSendPrepare = new TimingsHandler("** " . $name . "Player Send Chunk Prepare", Timings::$playerChunkSend); - $this->syncChunkLoadTimer = new TimingsHandler("** " . $name . "Chunk Load", Timings::$worldLoadTimer); - $this->syncChunkLoadDataTimer = new TimingsHandler("** " . $name . "Chunk Load - Data"); - $this->syncChunkLoadEntitiesTimer = new TimingsHandler("** " . $name . "Chunk Load - Entities"); - $this->syncChunkLoadTileEntitiesTimer = new TimingsHandler("** " . $name . "Chunk Load - TileEntities"); - $this->syncChunkSaveTimer = new TimingsHandler("** " . $name . "Chunk Save", Timings::$worldSaveTimer); + $this->syncChunkLoad = new TimingsHandler("** " . $name . "Chunk Load", Timings::$worldLoad); + $this->syncChunkLoadData = new TimingsHandler("** " . $name . "Chunk Load - Data"); + $this->syncChunkLoadEntities = new TimingsHandler("** " . $name . "Chunk Load - Entities"); + $this->syncChunkLoadTileEntities = new TimingsHandler("** " . $name . "Chunk Load - TileEntities"); + $this->syncChunkSave = new TimingsHandler("** " . $name . "Chunk Save", Timings::$worldSave); $this->doTick = new TimingsHandler($name . "World Tick"); } From 793081d8034e906812f187765f1539bb2c113ea3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 27 Dec 2020 19:20:37 +0000 Subject: [PATCH 2231/3224] Entity: assume that position has a valid World during setPosition() --- src/entity/Entity.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index a84c742457..b50844d65e 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1306,8 +1306,7 @@ abstract class Entity{ } $oldWorld = $this->getWorld(); - //TODO: staying in the same world when the target is invalid is probably not expected behaviour... this should bail instead - $newWorld = $pos instanceof Position && $pos->isValid() ? $pos->getWorld() : $oldWorld; + $newWorld = $pos instanceof Position ? $pos->getWorld() : $oldWorld; if($oldWorld !== $newWorld){ $this->despawnFromAll(); $oldWorld->removeEntity($this); From e8d319d87d22409fa58a06303f74f0a558210509 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 Jan 2021 18:48:14 +0000 Subject: [PATCH 2232/3224] attempt #2 --- tests/gh-actions/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/gh-actions/build.sh b/tests/gh-actions/build.sh index 19a21fa422..f52d26d439 100755 --- a/tests/gh-actions/build.sh +++ b/tests/gh-actions/build.sh @@ -45,7 +45,7 @@ git clone https://github.com/php-build/php-build.git cd php-build ./install-dependencies.sh echo '"pthreads",,"https://github.com/pmmp/pthreads.git",,,"extension",' >> share/php-build/extension/definition -echo '"leveldb",,"https://github.com/pmmp/php-leveldb.git",,"--with-leveldb=\\"$INSTALL_DIR\\","extension",' >> share/php-build/extension/definition +echo '"leveldb",,"https://github.com/pmmp/php-leveldb.git",,"--with-leveldb=\\"'$INSTALL_DIR'\\"","extension",' >> share/php-build/extension/definition echo '"chunkutils2",,"https://github.com/pmmp/ext-chunkutils2.git",,,"extension",' >> share/php-build/extension/definition echo '"morton",,"https://github.com/pmmp/ext-morton.git",,,"extension",' >> share/php-build/extension/definition PHP_BUILD_INSTALL_EXTENSION="\ From abd9e2dd4c81a9f62a81f26769d6a97ec9fe443b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 Jan 2021 19:41:08 +0000 Subject: [PATCH 2233/3224] ... --- tests/gh-actions/build.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/gh-actions/build.sh b/tests/gh-actions/build.sh index f52d26d439..51b39f294d 100755 --- a/tests/gh-actions/build.sh +++ b/tests/gh-actions/build.sh @@ -41,11 +41,12 @@ function build_leveldb { } build_leveldb 84348b9b826cc280cde659185695d2170b54824c +rm -rf php-build git clone https://github.com/php-build/php-build.git cd php-build ./install-dependencies.sh echo '"pthreads",,"https://github.com/pmmp/pthreads.git",,,"extension",' >> share/php-build/extension/definition -echo '"leveldb",,"https://github.com/pmmp/php-leveldb.git",,"--with-leveldb=\\"'$INSTALL_DIR'\\"","extension",' >> share/php-build/extension/definition +echo '"leveldb",,"https://github.com/pmmp/php-leveldb.git",,"--with-leveldb='$INSTALL_DIR'","extension",' >> share/php-build/extension/definition echo '"chunkutils2",,"https://github.com/pmmp/ext-chunkutils2.git",,,"extension",' >> share/php-build/extension/definition echo '"morton",,"https://github.com/pmmp/ext-morton.git",,,"extension",' >> share/php-build/extension/definition PHP_BUILD_INSTALL_EXTENSION="\ From 555eb464b667db24273febd74f7cfb24f5b410a9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 Jan 2021 20:10:14 +0000 Subject: [PATCH 2234/3224] build.sh: fix formatting --- tests/gh-actions/build.sh | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/gh-actions/build.sh b/tests/gh-actions/build.sh index 51b39f294d..31a0be0a2a 100755 --- a/tests/gh-actions/build.sh +++ b/tests/gh-actions/build.sh @@ -20,24 +20,24 @@ export CXXFLAGS="$CXXFLAGS -march=x86-64" function build_leveldb { local LEVELDB_VERSION="$1" echo "Building LevelDB" - rm -rf "./leveldb-mcpe" || true + rm -rf "./leveldb-mcpe" || true rm -rf "./leveldb-mcpe-build" || true - mkdir "./leveldb-mcpe" - curl -fsSL "https://github.com/pmmp/leveldb/archive/$LEVELDB_VERSION.tar.gz" | tar -zx - mv "./leveldb-$LEVELDB_VERSION" leveldb-mcpe-build - cd leveldb-mcpe-build - CFLAGS="-fPIC" CXXFLAGS="-fPIC" cmake . \ - -DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" \ - -DCMAKE_PREFIX_PATH="$INSTALL_DIR" \ - -DCMAKE_INSTALL_LIBDIR=lib \ - -DLEVELDB_BUILD_TESTS=OFF \ - -DLEVELDB_BUILD_BENCHMARKS=OFF \ - -DLEVELDB_SNAPPY=OFF \ - -DLEVELDB_ZSTD=OFF \ - -DLEVELDB_TCMALLOC=OFF \ - -DCMAKE_BUILD_TYPE=Release - make -j4 install - cd .. + mkdir "./leveldb-mcpe" + curl -fsSL "https://github.com/pmmp/leveldb/archive/$LEVELDB_VERSION.tar.gz" | tar -zx + mv "./leveldb-$LEVELDB_VERSION" leveldb-mcpe-build + cd leveldb-mcpe-build + CFLAGS="-fPIC" CXXFLAGS="-fPIC" cmake . \ + -DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" \ + -DCMAKE_PREFIX_PATH="$INSTALL_DIR" \ + -DCMAKE_INSTALL_LIBDIR=lib \ + -DLEVELDB_BUILD_TESTS=OFF \ + -DLEVELDB_BUILD_BENCHMARKS=OFF \ + -DLEVELDB_SNAPPY=OFF \ + -DLEVELDB_ZSTD=OFF \ + -DLEVELDB_TCMALLOC=OFF \ + -DCMAKE_BUILD_TYPE=Release + make -j4 install + cd .. } build_leveldb 84348b9b826cc280cde659185695d2170b54824c From 82c8fa696a2e8609d8ae086c52f96abe7c7705b6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 7 Jan 2021 20:43:31 +0000 Subject: [PATCH 2235/3224] Relocate teleport ACK checks to InGamePacketHandler --- src/network/mcpe/NetworkSession.php | 4 ++ .../mcpe/handler/InGamePacketHandler.php | 19 ++++++++- src/player/Player.php | 41 ++++--------------- 3 files changed, 31 insertions(+), 33 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 33db8255dc..800869ba90 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -690,6 +690,10 @@ class NetworkSession{ $pk->onGround = $this->player->onGround; $this->sendDataPacket($pk); + + if($this->handler instanceof InGamePacketHandler){ + $this->handler->forceMoveSync = true; + } } } diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index f2011fac8f..2699bf3105 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -127,6 +127,9 @@ class InGamePacketHandler extends PacketHandler{ /** @var Vector3|null */ protected $lastRightClickPos = null; + /** @var bool */ + public $forceMoveSync = false; + /** * TODO: HACK! This tracks GUIs for inventories that the server considers "always open" so that the client can't * open them twice. (1.16 hack) @@ -157,7 +160,21 @@ class InGamePacketHandler extends PacketHandler{ } $this->player->setRotation($yaw, $pitch); - $this->player->updateNextPosition($packet->position->round(4)->subtract(0, 1.62, 0)); + + $curPos = $this->player->getLocation(); + $newPos = $packet->position->subtract(0, 1.62, 0); + + if($this->forceMoveSync and $newPos->distanceSquared($curPos) > 1){ //Tolerate up to 1 block to avoid problems with client-sided physics when spawning in blocks + $this->session->syncMovement($curPos, null, null, MovePlayerPacket::MODE_RESET); + $this->session->getLogger()->debug("Got outdated pre-teleport movement, received " . $newPos . ", expected " . $curPos); + //Still getting movements from before teleport, ignore them + return false; + } + + // Once we get a movement within a reasonable distance, treat it as a teleport ACK and remove position lock + $this->forceMoveSync = false; + + $this->player->handleMovement($newPos); return true; } diff --git a/src/player/Player.php b/src/player/Player.php index c60db4b12e..4adf1bba1d 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -221,8 +221,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ protected $moveRateLimit = 10 * self::MOVES_PER_TICK; /** @var float|null */ protected $lastMovementProcess = null; - /** @var Vector3|null */ - protected $forceMoveSync = null; /** @var int */ protected $inAirTicks = 0; @@ -1106,39 +1104,19 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } } - /** - * Sets the coordinates the player will move to next. This is processed at the end of each tick. Unless you have - * some particularly specialized logic, you probably want to use teleport() instead of this. - * - * This is used for processing movements sent by the player over network. - * - * @param Vector3 $newPos Coordinates of the player's feet, centered horizontally at the base of their bounding box. - * - * @return bool if the - */ - public function updateNextPosition(Vector3 $newPos) : bool{ - //TODO: teleport acks are a network specific thing and shouldn't be here - - $newPos = $newPos->asVector3(); - if($this->forceMoveSync !== null and $newPos->distanceSquared($this->forceMoveSync) > 1){ //Tolerate up to 1 block to avoid problems with client-sided physics when spawning in blocks - $this->sendPosition($this->location, null, null, MovePlayerPacket::MODE_RESET); - $this->logger->debug("Got outdated pre-teleport movement, received " . $newPos . ", expected " . $this->location->asVector3()); - //Still getting movements from before teleport, ignore them - return false; - } - - // Once we get a movement within a reasonable distance, treat it as a teleport ACK and remove position lock - $this->forceMoveSync = null; - - $this->handleMovement($newPos); - return true; - } - public function getInAirTicks() : int{ return $this->inAirTicks; } - protected function handleMovement(Vector3 $newPos) : void{ + /** + * Attempts to move the player to the given coordinates. Unless you have some particularly specialized logic, you + * probably want to use teleport() instead of this. + * + * This is used for processing movements sent by the player over network. + * + * @param Vector3 $newPos Coordinates of the player's feet, centered horizontally at the base of their bounding box. + */ + public function handleMovement(Vector3 $newPos) : void{ $this->moveRateLimit--; if($this->moveRateLimit < 0){ return; @@ -2222,7 +2200,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ public function sendPosition(Vector3 $pos, ?float $yaw = null, ?float $pitch = null, int $mode = MovePlayerPacket::MODE_NORMAL) : void{ $this->networkSession->syncMovement($pos, $yaw, $pitch, $mode); - $this->forceMoveSync = $pos->asVector3(); $this->ySize = 0; } From 5392ddf0b91ef4a2c998df0e14b0fb5022505890 Mon Sep 17 00:00:00 2001 From: Mohamed Date: Thu, 7 Jan 2021 22:18:18 +0100 Subject: [PATCH 2236/3224] Fixed TNT broadcasting ignition sound (#3996) closes #3952 --- src/block/TNT.php | 2 ++ src/entity/object/PrimedTNT.php | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/block/TNT.php b/src/block/TNT.php index 46256f9298..f37b75c2f1 100644 --- a/src/block/TNT.php +++ b/src/block/TNT.php @@ -34,6 +34,7 @@ use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\utils\Random; +use pocketmine\world\sound\IgniteSound; use function cos; use function sin; use const M_PI; @@ -101,6 +102,7 @@ class TNT extends Opaque{ $tnt->setMotion(new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02)); $tnt->spawnToAll(); + $tnt->broadcastSound(new IgniteSound()); } public function getFlameEncouragement() : int{ diff --git a/src/entity/object/PrimedTNT.php b/src/entity/object/PrimedTNT.php index 48affa0ba4..a671da1d58 100644 --- a/src/entity/object/PrimedTNT.php +++ b/src/entity/object/PrimedTNT.php @@ -35,7 +35,6 @@ use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\world\Explosion; use pocketmine\world\Position; -use pocketmine\world\sound\IgniteSound; class PrimedTNT extends Entity implements Explosive{ @@ -73,8 +72,6 @@ class PrimedTNT extends Entity implements Explosive{ parent::initEntity($nbt); $this->fuse = $nbt->getShort("Fuse", 80); - - $this->broadcastSound(new IgniteSound()); } public function canCollideWith(Entity $entity) : bool{ From 7b806e74b84cce201c9b5cf0add5829eb317eb54 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 7 Jan 2021 22:02:43 +0000 Subject: [PATCH 2237/3224] Player: use own logger for movement debug --- src/player/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index 4adf1bba1d..0d3746e4c9 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1209,7 +1209,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } if($exceededRateLimit){ //client and server positions will be out of sync if this happens - $this->server->getLogger()->debug("Player " . $this->getName() . " exceeded movement rate limit, forcing to last accepted position"); + $this->logger->debug("Exceeded movement rate limit, forcing to last accepted position"); $this->sendPosition($this->location, $this->location->getYaw(), $this->location->getPitch(), MovePlayerPacket::MODE_RESET); } } From eaaed79b9398668e748fc30e02fdbb4fa0eff709 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 7 Jan 2021 23:32:35 +0000 Subject: [PATCH 2238/3224] Player: remove useless check from save() this exception is only thrown if the player is closed, which is already unexpected in the first place and will actually crash if it's not kosher. This prevents doing stuff like saving players during onDispose(), which crashes the server if a player is disconnected due to flagForDespawn(). --- src/player/Player.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 0d3746e4c9..57c5c4e6ae 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2033,14 +2033,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ /** * Handles player data saving - * - * @throws \InvalidStateException if the player is closed */ public function save() : void{ - if($this->closed){ - throw new \InvalidStateException("Tried to save closed player"); - } - $nbt = $this->saveNBT(); if($this->location->isValid()){ From a3597e195ae8b1c17470584850d934a91b3d6c2d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 7 Jan 2021 23:37:47 +0000 Subject: [PATCH 2239/3224] Player: extract getSaveData() from save() this allows plugins to request this data whenever they want it (e.g. to save offline any time they want, instead of being confined to the server autosave interval). --- src/player/Player.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 57c5c4e6ae..cdcd24aa86 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2031,10 +2031,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ throw new \BadMethodCallException("Players can't be saved with chunks"); } - /** - * Handles player data saving - */ - public function save() : void{ + public function getSaveData() : CompoundTag{ $nbt = $this->saveNBT(); if($this->location->isValid()){ @@ -2063,7 +2060,14 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $nbt->setLong("firstPlayed", $this->firstPlayed); $nbt->setLong("lastPlayed", (int) floor(microtime(true) * 1000)); - $this->server->saveOfflinePlayerData($this->username, $nbt); + return $nbt; + } + + /** + * Handles player data saving + */ + public function save() : void{ + $this->server->saveOfflinePlayerData($this->username, $this->getSaveData()); } protected function onDeath() : void{ From 574b615b4c44c89e20280b8d710a99c1d4df9ae2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 8 Jan 2021 00:04:05 +0000 Subject: [PATCH 2240/3224] Player: fixed attack sounds being added at the wrong position --- src/player/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index cdcd24aa86..32fcdcd9d2 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1657,7 +1657,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $entity->attack($ev); - $soundPos = $entity->getPosition()->add(0, $entity->width / 2, 0); + $soundPos = $entity->getPosition()->add(0, $entity->height / 2, 0); if($ev->isCancelled()){ $this->getWorld()->addSound($soundPos, new EntityAttackNoDamageSound()); return false; From e53b57732bf66fd533c8fbb71ab43dd6b4babfb3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 8 Jan 2021 00:10:11 +0000 Subject: [PATCH 2241/3224] Entity: replace separate height/width/eyeHeight fields with an EntitySizeInfo structure this will make it easier to implement stuff like sleeping (properly), swimming and gliding without needing to duplicate all the fields. --- src/entity/Entity.php | 31 ++++++----------- src/entity/EntitySizeInfo.php | 53 +++++++++++++++++++++++++++++ src/entity/Human.php | 6 ++-- src/entity/Living.php | 2 +- src/entity/Squid.php | 5 ++- src/entity/Villager.php | 7 ++-- src/entity/Zombie.php | 5 +-- src/entity/object/ExperienceOrb.php | 6 ++-- src/entity/object/FallingBlock.php | 8 ++--- src/entity/object/ItemEntity.php | 6 ++-- src/entity/object/Painting.php | 12 +++---- src/entity/object/PrimedTNT.php | 8 ++--- src/entity/projectile/Arrow.php | 6 ++-- src/entity/projectile/Throwable.php | 6 ++-- src/player/Player.php | 2 +- 15 files changed, 103 insertions(+), 60 deletions(-) create mode 100644 src/entity/EntitySizeInfo.php diff --git a/src/entity/Entity.php b/src/entity/Entity.php index b50844d65e..2c2fa80d1b 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -118,13 +118,8 @@ abstract class Entity{ /** @var bool */ public $onGround = false; - /** @var float */ - public $eyeHeight = null; - - /** @var float */ - public $height; - /** @var float */ - public $width; + /** @var EntitySizeInfo */ + public $size; /** @var float */ private $health = 20.0; @@ -218,9 +213,7 @@ abstract class Entity{ public function __construct(Location $location, ?CompoundTag $nbt = null){ $this->timings = Timings::getEntityTimings($this); - if($this->eyeHeight === null){ - $this->eyeHeight = $this->height / 2 + 0.1; - } + $this->size = $this->getInitialSizeInfo(); $this->id = self::nextRuntimeId(); $this->server = $location->getWorld()->getServer(); @@ -259,6 +252,8 @@ abstract class Entity{ } + abstract protected function getInitialSizeInfo() : EntitySizeInfo; + public function getNameTag() : string{ return $this->nameTag; } @@ -299,11 +294,7 @@ abstract class Entity{ if($value <= 0){ throw new \InvalidArgumentException("Scale must be greater than 0"); } - $multiplier = $value / $this->getScale(); - - $this->width *= $multiplier; - $this->height *= $multiplier; - $this->eyeHeight *= $multiplier; + $this->size = $this->getInitialSizeInfo()->scale($value); $this->scale = $value; @@ -315,14 +306,14 @@ abstract class Entity{ } protected function recalculateBoundingBox() : void{ - $halfWidth = $this->width / 2; + $halfWidth = $this->size->getWidth() / 2; $this->boundingBox = new AxisAlignedBB( $this->location->x - $halfWidth, $this->location->y + $this->ySize, $this->location->z - $halfWidth, $this->location->x + $halfWidth, - $this->location->y + $this->height + $this->ySize, + $this->location->y + $this->size->getHeight() + $this->ySize, $this->location->z + $halfWidth ); } @@ -1042,7 +1033,7 @@ abstract class Entity{ } public function getEyeHeight() : float{ - return $this->eyeHeight; + return $this->size->getEyeHeight(); } public function getEyePos() : Vector3{ @@ -1585,8 +1576,8 @@ abstract class Entity{ protected function syncNetworkData(EntityMetadataCollection $properties) : void{ $properties->setByte(EntityMetadataProperties::ALWAYS_SHOW_NAMETAG, $this->alwaysShowNameTag ? 1 : 0); - $properties->setFloat(EntityMetadataProperties::BOUNDING_BOX_HEIGHT, $this->height); - $properties->setFloat(EntityMetadataProperties::BOUNDING_BOX_WIDTH, $this->width); + $properties->setFloat(EntityMetadataProperties::BOUNDING_BOX_HEIGHT, $this->size->getHeight()); + $properties->setFloat(EntityMetadataProperties::BOUNDING_BOX_WIDTH, $this->size->getWidth()); $properties->setFloat(EntityMetadataProperties::SCALE, $this->scale); $properties->setLong(EntityMetadataProperties::LEAD_HOLDER_EID, -1); $properties->setLong(EntityMetadataProperties::OWNER_EID, $this->ownerId ?? -1); diff --git a/src/entity/EntitySizeInfo.php b/src/entity/EntitySizeInfo.php new file mode 100644 index 0000000000..1456cc2fbe --- /dev/null +++ b/src/entity/EntitySizeInfo.php @@ -0,0 +1,53 @@ +height = $height; + $this->width = $width; + $this->eyeHeight = $eyeHeight ?? min($this->height / 2 + 0.1, $this->height); + } + + public function getHeight() : float{ return $this->height; } + + public function getWidth() : float{ return $this->width; } + + public function getEyeHeight() : float{ return $this->eyeHeight; } + + public function scale(float $newScale) : self{ + return new self( + $this->height * $newScale, + $this->width * $newScale, + $this->eyeHeight * $newScale + ); + } +} diff --git a/src/entity/Human.php b/src/entity/Human.php index 88321e8346..6acb27c293 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -74,10 +74,6 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ /** @var UUID */ protected $uuid; - public $width = 0.6; - public $height = 1.8; - public $eyeHeight = 1.62; - /** @var Skin */ protected $skin; @@ -94,6 +90,8 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ parent::__construct($location, $nbt); } + protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(1.8, 0.6, 1.62); } + /** * @throws InvalidSkinException * @throws \UnexpectedValueException diff --git a/src/entity/Living.php b/src/entity/Living.php index 8db76c63b9..6bedafacff 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -715,7 +715,7 @@ abstract class Living extends Entity{ $blocks = []; $nextIndex = 0; - foreach(VoxelRayTrace::inDirection($this->location->add(0, $this->eyeHeight, 0), $this->getDirectionVector(), $maxDistance) as $vector3){ + foreach(VoxelRayTrace::inDirection($this->location->add(0, $this->size->getEyeHeight(), 0), $this->getDirectionVector(), $maxDistance) as $vector3){ $block = $this->getWorld()->getBlockAt($vector3->x, $vector3->y, $vector3->z); $blocks[$nextIndex++] = $block; diff --git a/src/entity/Squid.php b/src/entity/Squid.php index 04b81d4fc7..1010c5d78d 100644 --- a/src/entity/Squid.php +++ b/src/entity/Squid.php @@ -39,9 +39,6 @@ class Squid extends WaterAnimal{ public static function getNetworkTypeId() : string{ return EntityIds::SQUID; } - public $width = 0.95; - public $height = 0.95; - /** @var Vector3|null */ public $swimDirection = null; /** @var float */ @@ -50,6 +47,8 @@ class Squid extends WaterAnimal{ /** @var int */ private $switchDirectionTicker = 0; + protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.95, 0.95); } + public function initEntity(CompoundTag $nbt) : void{ $this->setMaxHealth(10); parent::initEntity($nbt); diff --git a/src/entity/Villager.php b/src/entity/Villager.php index f4329ade67..ac749735dc 100644 --- a/src/entity/Villager.php +++ b/src/entity/Villager.php @@ -38,14 +38,15 @@ class Villager extends Living implements Ageable{ public static function getNetworkTypeId() : string{ return EntityIds::VILLAGER; } - public $width = 0.6; - public $height = 1.8; - /** @var bool */ private $baby = false; /** @var int */ private $profession = self::PROFESSION_FARMER; + protected function getInitialSizeInfo() : EntitySizeInfo{ + return new EntitySizeInfo(1.8, 0.6); //TODO: eye height?? + } + public function getName() : string{ return "Villager"; } diff --git a/src/entity/Zombie.php b/src/entity/Zombie.php index 91a43b11c0..8cd3adb844 100644 --- a/src/entity/Zombie.php +++ b/src/entity/Zombie.php @@ -31,8 +31,9 @@ class Zombie extends Living{ public static function getNetworkTypeId() : string{ return EntityIds::ZOMBIE; } - public $width = 0.6; - public $height = 1.8; + protected function getInitialSizeInfo() : EntitySizeInfo{ + return new EntitySizeInfo(1.8, 0.6); //TODO: eye height ?? + } public function getName() : string{ return "Zombie"; diff --git a/src/entity/object/ExperienceOrb.php b/src/entity/object/ExperienceOrb.php index 3953eda2f0..260d4f8b2b 100644 --- a/src/entity/object/ExperienceOrb.php +++ b/src/entity/object/ExperienceOrb.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity\object; use pocketmine\entity\Entity; +use pocketmine\entity\EntitySizeInfo; use pocketmine\entity\Human; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; @@ -78,9 +79,6 @@ class ExperienceOrb extends Entity{ return $result; } - public $height = 0.25; - public $width = 0.25; - public $gravity = 0.04; public $drag = 0.02; @@ -102,6 +100,8 @@ class ExperienceOrb extends Entity{ /** @var int */ protected $xpValue = 1; + protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.25, 0.25); } + protected function initEntity(CompoundTag $nbt) : void{ parent::initEntity($nbt); diff --git a/src/entity/object/FallingBlock.php b/src/entity/object/FallingBlock.php index 7841233530..5376b866ed 100644 --- a/src/entity/object/FallingBlock.php +++ b/src/entity/object/FallingBlock.php @@ -27,6 +27,7 @@ use pocketmine\block\Block; use pocketmine\block\BlockFactory; use pocketmine\block\utils\Fallable; use pocketmine\entity\Entity; +use pocketmine\entity\EntitySizeInfo; use pocketmine\entity\Location; use pocketmine\event\entity\EntityBlockChangeEvent; use pocketmine\event\entity\EntityDamageEvent; @@ -44,9 +45,6 @@ class FallingBlock extends Entity{ public static function getNetworkTypeId() : string{ return EntityIds::FALLING_BLOCK; } - public $width = 0.98; - public $height = 0.98; - protected $gravity = 0.04; protected $drag = 0.02; @@ -60,6 +58,8 @@ class FallingBlock extends Entity{ parent::__construct($location, $nbt); } + protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.98, 0.98); } + public static function parseBlockNBT(BlockFactory $factory, CompoundTag $nbt) : Block{ $blockId = 0; @@ -102,7 +102,7 @@ class FallingBlock extends Entity{ if(!$this->isFlaggedForDespawn()){ $world = $this->getWorld(); - $pos = $this->location->add(-$this->width / 2, $this->height, -$this->width / 2)->floor(); + $pos = $this->location->add(-$this->size->getWidth() / 2, $this->size->getHeight(), -$this->size->getWidth() / 2)->floor(); $this->block->position($world, $pos->x, $pos->y, $pos->z); diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index f2d104e51e..6270c8b1be 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity\object; use pocketmine\entity\Entity; +use pocketmine\entity\EntitySizeInfo; use pocketmine\entity\Location; use pocketmine\event\entity\ItemDespawnEvent; use pocketmine\event\entity\ItemSpawnEvent; @@ -54,9 +55,6 @@ class ItemEntity extends Entity{ /** @var Item */ protected $item; - public $width = 0.25; - public $height = 0.25; - protected $gravity = 0.04; protected $drag = 0.02; @@ -73,6 +71,8 @@ class ItemEntity extends Entity{ parent::__construct($location, $nbt); } + protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.25, 0.25); } + protected function initEntity(CompoundTag $nbt) : void{ parent::initEntity($nbt); diff --git a/src/entity/object/Painting.php b/src/entity/object/Painting.php index 91d9a014d0..ab34e7aee9 100644 --- a/src/entity/object/Painting.php +++ b/src/entity/object/Painting.php @@ -25,6 +25,7 @@ namespace pocketmine\entity\object; use pocketmine\block\VanillaBlocks; use pocketmine\entity\Entity; +use pocketmine\entity\EntitySizeInfo; use pocketmine\entity\Location; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\item\VanillaItems; @@ -60,12 +61,6 @@ class Painting extends Entity{ /** @var float */ protected $drag = 1.0; - //these aren't accurate, but it doesn't matter since they aren't used (vanilla PC does something similar) - /** @var float */ - public $height = 0.5; - /** @var float */ - public $width = 0.5; - /** @var Vector3 */ protected $blockIn; /** @var int */ @@ -80,6 +75,11 @@ class Painting extends Entity{ parent::__construct($location, $nbt); } + protected function getInitialSizeInfo() : EntitySizeInfo{ + //these aren't accurate, but it doesn't matter since they aren't used (vanilla PC does something similar) + return new EntitySizeInfo(0.5, 0.5); + } + protected function initEntity(CompoundTag $nbt) : void{ $this->setMaxHealth(1); $this->setHealth(1); diff --git a/src/entity/object/PrimedTNT.php b/src/entity/object/PrimedTNT.php index a671da1d58..93eeeb6b72 100644 --- a/src/entity/object/PrimedTNT.php +++ b/src/entity/object/PrimedTNT.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity\object; use pocketmine\entity\Entity; +use pocketmine\entity\EntitySizeInfo; use pocketmine\entity\Explosive; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\ExplosionPrimeEvent; @@ -40,9 +41,6 @@ class PrimedTNT extends Entity implements Explosive{ public static function getNetworkTypeId() : string{ return EntityIds::TNT; } - public $width = 0.98; - public $height = 0.98; - protected $gravity = 0.04; protected $drag = 0.02; @@ -51,6 +49,8 @@ class PrimedTNT extends Entity implements Explosive{ public $canCollide = false; + protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.98, 0.98); } + public function getFuse() : int{ return $this->fuse; } @@ -108,7 +108,7 @@ class PrimedTNT extends Entity implements Explosive{ $ev = new ExplosionPrimeEvent($this, 4); $ev->call(); if(!$ev->isCancelled()){ - $explosion = new Explosion(Position::fromObject($this->location->add(0, $this->height / 2, 0), $this->getWorld()), $ev->getForce(), $this); + $explosion = new Explosion(Position::fromObject($this->location->add(0, $this->size->getHeight() / 2, 0), $this->getWorld()), $ev->getForce(), $this); if($ev->isBlockBreaking()){ $explosion->explodeA(); } diff --git a/src/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php index 503f55cf43..fc163472e4 100644 --- a/src/entity/projectile/Arrow.php +++ b/src/entity/projectile/Arrow.php @@ -26,6 +26,7 @@ namespace pocketmine\entity\projectile; use pocketmine\block\Block; use pocketmine\entity\animation\ArrowShakeAnimation; use pocketmine\entity\Entity; +use pocketmine\entity\EntitySizeInfo; use pocketmine\entity\Location; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\event\inventory\InventoryPickupArrowEvent; @@ -50,9 +51,6 @@ class Arrow extends Projectile{ private const TAG_PICKUP = "pickup"; //TAG_Byte - public $width = 0.25; - public $height = 0.25; - protected $gravity = 0.05; protected $drag = 0.01; @@ -76,6 +74,8 @@ class Arrow extends Projectile{ $this->setCritical($critical); } + protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.25, 0.25); } + protected function initEntity(CompoundTag $nbt) : void{ parent::initEntity($nbt); diff --git a/src/entity/projectile/Throwable.php b/src/entity/projectile/Throwable.php index 42086aae47..20bf86912a 100644 --- a/src/entity/projectile/Throwable.php +++ b/src/entity/projectile/Throwable.php @@ -24,16 +24,16 @@ declare(strict_types=1); namespace pocketmine\entity\projectile; use pocketmine\block\Block; +use pocketmine\entity\EntitySizeInfo; use pocketmine\math\RayTraceResult; abstract class Throwable extends Projectile{ - public $width = 0.25; - public $height = 0.25; - protected $gravity = 0.03; protected $drag = 0.01; + protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.25, 0.25); } + protected function onHitBlock(Block $blockHit, RayTraceResult $hitResult) : void{ parent::onHitBlock($blockHit, $hitResult); $this->flagForDespawn(); diff --git a/src/player/Player.php b/src/player/Player.php index 32fcdcd9d2..b2cf3dc523 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1657,7 +1657,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $entity->attack($ev); - $soundPos = $entity->getPosition()->add(0, $entity->height / 2, 0); + $soundPos = $entity->getPosition()->add(0, $entity->size->getHeight() / 2, 0); if($ev->isCancelled()){ $this->getWorld()->addSound($soundPos, new EntityAttackNoDamageSound()); return false; From 053a7a1a6155d87acac7f9323f231c1952294dd0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 8 Jan 2021 13:59:52 +0000 Subject: [PATCH 2242/3224] Entity: split getSyncedNetworkData() into two functions to avoid opaque boolean parameters --- src/entity/Entity.php | 18 +++++++++++++----- src/entity/Human.php | 2 +- src/entity/object/ItemEntity.php | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 2c2fa80d1b..825ef27698 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -589,7 +589,7 @@ abstract class Entity{ } } - $changedProperties = $this->getSyncedNetworkData(true); + $changedProperties = $this->getDirtyNetworkData(); if(count($changedProperties) > 0){ $this->sendData(null, $changedProperties); $this->networkProperties->clearDirtyProperties(); @@ -1436,7 +1436,7 @@ abstract class Entity{ $pk->attributes = array_map(function(Attribute $attr) : NetworkAttribute{ return new NetworkAttribute($attr->getId(), $attr->getMinValue(), $attr->getMaxValue(), $attr->getValue(), $attr->getDefaultValue()); }, $this->attributeMap->getAll()); - $pk->metadata = $this->getSyncedNetworkData(false); + $pk->metadata = $this->getAllNetworkData(); $player->getNetworkSession()->sendDataPacket($pk); } @@ -1557,7 +1557,7 @@ abstract class Entity{ */ public function sendData(?array $targets, ?array $data = null) : void{ $targets = $targets ?? $this->hasSpawned; - $data = $data ?? $this->getSyncedNetworkData(false); + $data = $data ?? $this->getAllNetworkData(); foreach($targets as $p){ $p->getNetworkSession()->syncActorData($this, $data); @@ -1568,10 +1568,18 @@ abstract class Entity{ * @return MetadataProperty[] * @phpstan-return array */ - final protected function getSyncedNetworkData(bool $dirtyOnly) : array{ + final protected function getDirtyNetworkData() : array{ $this->syncNetworkData($this->networkProperties); + return $this->networkProperties->getDirty(); + } - return $dirtyOnly ? $this->networkProperties->getDirty() : $this->networkProperties->getAll(); + /** + * @return MetadataProperty[] + * @phpstan-return array + */ + final protected function getAllNetworkData() : array{ + $this->syncNetworkData($this->networkProperties); + return $this->networkProperties->getAll(); } protected function syncNetworkData(EntityMetadataCollection $properties) : void{ diff --git a/src/entity/Human.php b/src/entity/Human.php index 6acb27c293..65f26ebc36 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -399,7 +399,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $pk->yaw = $this->location->yaw; $pk->pitch = $this->location->pitch; $pk->item = TypeConverter::getInstance()->coreItemStackToNet($this->getInventory()->getItemInHand()); - $pk->metadata = $this->getSyncedNetworkData(false); + $pk->metadata = $this->getAllNetworkData(); $player->getNetworkSession()->sendDataPacket($pk); //TODO: Hack for MCPE 1.2.13: DATA_NAMETAG is useless in AddPlayerPacket, so it has to be sent separately diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index 6270c8b1be..d1e306340b 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -210,7 +210,7 @@ class ItemEntity extends Entity{ $pk->position = $this->location->asVector3(); $pk->motion = $this->getMotion(); $pk->item = TypeConverter::getInstance()->coreItemStackToNet($this->getItem()); - $pk->metadata = $this->getSyncedNetworkData(false); + $pk->metadata = $this->getAllNetworkData(); $player->getNetworkSession()->sendDataPacket($pk); } From f383685c9b6815fa1cfc6afc8202b528dad902dc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 8 Jan 2021 19:44:28 +0000 Subject: [PATCH 2243/3224] [ci skip] update changelog --- changelogs/4.0-snapshot.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 7e1546bf37..9ee4bc20e2 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -8,6 +8,7 @@ This major version features substantial changes throughout the core, including s - The `/reload` command has been removed. - The `/effect` command no longer supports numeric IDs - it's now required to use names. - The `/enchant` command no longer supports numeric IDs - it's now required to use names. +- Added `/clear` command with functionality equivalent to that of vanilla Minecraft. - Remote console (RCON) has been removed. The [RconServer](https://github.com/pmmp/RconServer) plugin is provided as a substitute. - Spawn protection has been removed. The [BasicSpawnProtection](https://github.com/pmmp/BasicSpawnProtection) plugin is provided as a substitute. - CTRL+C signal handling has been removed. The [PcntlSignalHandler](https://github.com/pmmp/PcntlSignalHandler) plugin is provided as a substitute. @@ -37,6 +38,7 @@ This major version features substantial changes throughout the core, including s - Partial chunk saves (only saving modified subcomponents of chunks) has been implemented. This drastically reduces the amount of data that is usually necessary to write on chunk save, which in turn **drastically reduces the time to complete world saves**. This is possible thanks to the modular design of the `leveldb` world format - this enhancement is not possible with region-based formats. - Lighting is no longer guaranteed to be available on every chunk. It's now calculated on the fly as-needed. - `/op`, `/deop`, `/whitelist add` and `/whitelist remove` no longer cause player data to be loaded from disk for no reason. +- Timings now use high-resolution timers provided by `hrtime()` to collect more accurate performance metrics. ### Logger revamp - Many components now have a dedicated logger which automatically adds [prefixes] to their messages. @@ -165,6 +167,11 @@ This version features substantial changes to the network system, improving coher ### Entity #### General - `Entity` no longer extends from `Location`. `Entity->getLocation()` and `Entity->getPosition()` should be used instead. +- The following public fields have been removed: + - `Entity->chunk`: Entities no longer know which chunk they are in (the `World` now manages this instead). + - `Entity->height`: moved to `EntitySizeInfo`; use `Entity->size` instead + - `Entity->width`: moved to `EntitySizeInfo`; use `Entity->size` instead + - `Entity->eyeHeight`: moved to `EntitySizeInfo`; use `Entity->size` instead - The following API methods have been added: - `ItemEntity->getDespawnDelay()` - `ItemEntity->setDespawnDelay()` @@ -621,6 +628,7 @@ This version features substantial changes to the network system, improving coher - `Player->toggleFlight()`: tries to start / stop flying (fires events, may be cancelled) - `Player->updateNextPosition()`: sets the player's next attempted move location (fires events, may be cancelled) - `Player->useHeldItem()`: activate the held item, e.g. throwing a snowball + - `Player->getSaveData()`: returns save data generated on the fly - The following API methods have been removed: - `Player->addActionBarMessage()`: replaced by `sendActionBarMessage()` - `Player->addSubTitle()`: replaced by `sendSubTitle()` @@ -631,6 +639,7 @@ This version features substantial changes to the network system, improving coher - `Player->updatePing()`: moved to `NetworkSession` - `Player->dataPacket()`: replaced by `NetworkSession->sendDataPacket()` - `Player->sendDataPacket()`: replaced by `NetworkSession->sendDataPacket()` + - `Player->updateNextPosition()`: use `Player->handleMovement()` instead - `IPlayer->isWhitelisted()`: use `Server->isWhitelisted()` instead - `IPlayer->setWhitelisted()`: use `Server->setWhitelisted()` instead - `IPlayer->isBanned()`: this was unreliable because it only checked name bans and didn't account for plugin custom ban systems. Use `Server->getNameBans()->isBanned()` and `Server->getIPBans()->isBanned()` instead. @@ -690,6 +699,7 @@ This version features substantial changes to the network system, improving coher #### Other changes - `AsyncPool` uses a new, significantly more performant algorithm for task collection. - `BulkCurlTask` has had the `$complexData` constructor parameter removed. +- `BulkCurlTask->__construct()` now accepts `BulkCurlTaskOperation[]` instead of `mixed[]`. - `pocketmine\Collectable` has been removed, and is no longer extended by `AsyncTask`. - The following hooks have been added: - `AsyncTask->onError()`: called on the main thread when an uncontrolled error was detected in the async task, such as a memory failure @@ -839,12 +849,14 @@ This version features substantial changes to the network system, improving coher - `World->loadChunk()` now returns `?Chunk`, and the `$create` parameter has been removed. - `World->getChunk()` no longer accepts a `$create` parameter. - `World->updateAllLight()` now accepts `int, int, int` instead of `Vector3`. + - `ChunkManager->setChunk()` (and its notable implementations in `World` and `SimpleChunkManager` no longer accepts NULL for the `$chunk` parameter. - `Chunk->__construct()` now has the signature `array $subChunks, ?list $entities, ?list $tiles, ?BiomeArray $biomeArray, ?HeightArray $heightArray`. - `Chunk->getSubChunk()` now returns `SubChunk` instead of `SubChunkInterface|null` (and throws `InvalidArgumentException` on out-of-bounds coordinates). - `Chunk->setSubChunk()` no longer accepts `SubChunkInterface`, and the `$allowEmpty` parameter has been removed. - The following API methods have been renamed / moved: - `Level->getCollisionCubes()` -> `World->getCollisionBoxes()` - `World->getName()` -> `World->getDisplayName()` + - `World->populateChunk()` has been split into `World->requestChunkPopulation()` and `World->orderChunkPopulation()`. - The following API methods have changed behaviour: - `World->getChunk()` no longer tries to load chunks from disk. If the chunk is not already in memory, null is returned. (This behaviour now properly matches other `ChunkManager` implementations.) - The following methods now throw `WorldException` when targeting ungenerated terrain: From 80198daba01745844e9ef7da0ba499dd68346998 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 8 Jan 2021 19:53:15 +0000 Subject: [PATCH 2244/3224] [ci skip] changelog: mention changes to Cancellable --- changelogs/4.0-snapshot.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 9ee4bc20e2..6d159e8f42 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -351,7 +351,7 @@ This version features substantial changes to the network system, improving coher #### Other changes - Disconnecting players during events no longer crashes the server (although it might cause other side effects). - `PlayerKickEvent` is no longer fired for disconnects that occur before the player completes the initial login sequence (i.e. completing downloading resource packs). -- Cancellable events must now implement `CancellableTrait` to get the cancellable components needed to satisfy interface requirements. +- Cancellable events must now implement `CancellableTrait` to get the cancellable components needed to satisfy interface requirements. `Event` no longer stubs these methods. - `PlayerInteractEvent` is no longer fired when a player activates an item. This fixes the age-old complaint of `PlayerInteractEvent` firing multiple times when interacting once. The following constants have been removed: - `PlayerInteractEvent::LEFT_CLICK_AIR` - `PlayerInteractEvent::RIGHT_CLICK_AIR` @@ -373,9 +373,10 @@ This version features substantial changes to the network system, improving coher - `PlayerDeathEvent->setXpDropAmount()` - The following API methods have been removed: - `PlayerPreLoginEvent->getPlayer()` + - `Cancellable->setCancelled()`: this allows implementors of `Cancellable` to implement their own cancellation mechanisms, such as the complex one in `PlayerPreLoginEvent` - The following API methods have been moved: - `Event->isCancelled()` -> `CancellableTrait->isCancelled()`: this was a stub which threw `BadMethodCallException` if the class didn't implement `Cancellable`; now this is simply not available on non-cancellable events - - `Event->setCancelled()` -> `CancellableTrait->setCancelled()` + - `Event->setCancelled()` has been split into `cancel()` and `uncancel()`, and moved to `CancellableTrait` - `HandlerList::unregisterAll()` -> `HandlerListManager->unregisterAll()` - `HandlerList::getHandlerListFor()` -> `HandlerListManager->getListFor()` - `HandlerList::getHandlerLists()` -> `HandlerListManager->getAll()` From eb1c59597d6e866efb1dce830e5e373794cdbf98 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 8 Jan 2021 20:51:23 +0000 Subject: [PATCH 2245/3224] [ci skip] changelog: mention newly added blocks and items --- changelogs/4.0-snapshot.md | 43 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 6d159e8f42..d755bb285a 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -943,3 +943,46 @@ This version features substantial changes to the network system, improving coher - `Internet::simpleCurl()` now requires a `Closure` for its `onSuccess` parameter instead of `callable`. - The following API methods have been removed: - `Utils::getCallableIdentifier()` + +## Gameplay +### Blocks +- Implemented the following blocks: + - bamboo + - bamboo sapling + - barrel + - barrier + - blue ice + - carved pumpkin + - coral block + - daylight sensor + - dried kelp + - elements (from Minecraft: Education Edition) + - hard (stained and unstained) glass (from Minecraft: Education Edition) + - hard (stained and unstained) glass pane (from Minecraft: Education Edition) + - jukebox + - note block + - red, green, blue and purple torches (from Minecraft: Education Edition) + - sea pickle + - underwater torches (from Minecraft: Education Edition) + - additional wood variants of the following: + - buttons + - pressure plates + - signs + - trapdoors + - stairs of the following materials: + - andesite (smooth and natural) + - diorite (smooth and natural) + - end stone + - end stone brick + - granite (smooth and natural) + - mossy cobblestone + - prismarine (natural, dark and bricks) + - red nether brick + - red sandstone (and variants) + - stone-line slabs of many variants + +### Items +- Implemented the following items: + - records + - compounds (from Minecraft: Education Edition) + - black, brown, blue and white dyes From f4d81c099737e7a17b84dff50095789fcaef7be8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 8 Jan 2021 20:51:56 +0000 Subject: [PATCH 2246/3224] [ci skip] changelog: mention DedicatedQueryNetworkInterface --- changelogs/4.0-snapshot.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index d755bb285a..f59b8bdbce 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -13,6 +13,7 @@ This major version features substantial changes throughout the core, including s - Spawn protection has been removed. The [BasicSpawnProtection](https://github.com/pmmp/BasicSpawnProtection) plugin is provided as a substitute. - CTRL+C signal handling has been removed. The [PcntlSignalHandler](https://github.com/pmmp/PcntlSignalHandler) plugin is provided as a substitute. - Player movement anti-cheat has been removed. Its corresponding `pocketmine.yml` setting `player.anti-cheat.allow-movement-cheats` has been removed. +- GS4 Query no longer breaks when disabling RakLib. - The `pocketmine_chunkutils` PHP extension has been dropped. - New PHP extensions are required by this version: - [ds](https://github.com/php-ds/ext-ds) From 3dd01781d52122a6998f7079098f99e4e604f2ff Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 8 Jan 2021 20:52:21 +0000 Subject: [PATCH 2247/3224] [ci skip] changelog: PlayerDisplayNameChangeEvent is new in this version --- changelogs/4.0-snapshot.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index f59b8bdbce..aadaaac59b 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -360,6 +360,7 @@ This version features substantial changes to the network system, improving coher - The following events have been added: - `PlayerItemUseEvent`: player activating their held item, for example to throw it. - `BlockTeleportEvent`: block teleporting, for example dragon egg when attacked. + - `PlayerDisplayNameChangeEvent` - The following events have been removed: - `EntityArmorChangeEvent` - `EntityInventoryChangeEvent` From 3ef2a195276e3ba0a4f5e8789d1ea8d8ee147d0f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 8 Jan 2021 20:58:15 +0000 Subject: [PATCH 2248/3224] Player: don't kick for attacking non-attackable entities this is quite out-of-character for PM - it usually handles bad network requests by ignoring them, not by kicking the player off the server. --- src/player/Player.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index b2cf3dc523..459b3ba349 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1626,8 +1626,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return false; } if($entity instanceof ItemEntity or $entity instanceof Arrow){ - $this->kick("Attempting to attack an invalid entity"); - $this->logger->warning($this->getServer()->getLanguage()->translateString("pocketmine.player.invalidEntity", [$this->getName()])); + $this->logger->debug("Attempted to attack non-attackable entity " . get_class($entity)); return false; } From 5e73417fa91aaaf20887c07354643a2b05840bf5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 10 Jan 2021 19:50:13 +0000 Subject: [PATCH 2249/3224] Player::getNetworkSession() now explicitly handles disconnected state by throwing an exception instead of just allowing return of possibly-null networkSession --- src/player/Player.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/player/Player.php b/src/player/Player.php index 459b3ba349..8a1ac07311 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -530,6 +530,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } public function getNetworkSession() : NetworkSession{ + if($this->networkSession === null){ + throw new \InvalidStateException("Player is not connected"); + } return $this->networkSession; } From c4845ab6b1cba33e7a9a78c62345286e5336be77 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 10 Jan 2021 19:51:41 +0000 Subject: [PATCH 2250/3224] Use Player->getNetworkSession() in places where it's assumed the player will be connected --- src/player/Player.php | 66 ++++++------ tests/phpstan/configs/l8-baseline.neon | 140 ------------------------- 2 files changed, 32 insertions(+), 174 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 8a1ac07311..7ce797a36a 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -421,7 +421,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ public function setAllowFlight(bool $value) : void{ $this->allowFlight = $value; - $this->networkSession->syncAdventureSettings($this); + $this->getNetworkSession()->syncAdventureSettings($this); } public function getAllowFlight() : bool{ @@ -432,7 +432,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ if($this->flying !== $value){ $this->flying = $value; $this->resetFallDistance(); - $this->networkSession->syncAdventureSettings($this); + $this->getNetworkSession()->syncAdventureSettings($this); } } @@ -442,7 +442,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ public function setAutoJump(bool $value) : void{ $this->autoJump = $value; - $this->networkSession->syncAdventureSettings($this); + $this->getNetworkSession()->syncAdventureSettings($this); } public function hasAutoJump() : bool{ @@ -516,7 +516,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->nextChunkOrderRun = 0; - $this->networkSession->syncViewAreaRadius($this->viewDistance); + $this->getNetworkSession()->syncViewAreaRadius($this->viewDistance); $this->logger->debug("Setting view distance to " . $this->viewDistance . " (requested " . $distance . ")"); } @@ -663,7 +663,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->usedChunks = []; $this->loadQueue = []; - $this->networkSession->onEnterWorld(); + $this->getNetworkSession()->onEnterWorld(); } return true; @@ -684,7 +684,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } } } - $this->networkSession->stopUsingChunk($x, $z); + $this->getNetworkSession()->stopUsingChunk($x, $z); unset($this->usedChunks[$index]); } $world->unregisterChunkLoader($this->chunkLoader, $x, $z); @@ -735,7 +735,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ unset($this->loadQueue[$index]); $this->usedChunks[$index] = UsedChunkStatus::REQUESTED(); - $this->networkSession->startUsingChunk($X, $Z, function(int $chunkX, int $chunkZ) use ($index) : void{ + $this->getNetworkSession()->startUsingChunk($X, $Z, function(int $chunkX, int $chunkZ) use ($index) : void{ $this->usedChunks[$index] = UsedChunkStatus::SENT(); if($this->spawnChunkLoadCount === -1){ $this->spawnEntitiesOnChunk($chunkX, $chunkZ); @@ -749,7 +749,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } } - $this->networkSession->notifyTerrainReady(); + $this->getNetworkSession()->notifyTerrainReady(); } }); } @@ -839,7 +839,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->loadQueue = $newOrder; if(count($this->loadQueue) > 0 or count($unloadChunks) > 0){ $this->chunkLoader->setCurrentLocation($this->location); - $this->networkSession->syncViewAreaCenterPoint($this->location, $this->viewDistance); + $this->getNetworkSession()->syncViewAreaCenterPoint($this->location, $this->viewDistance); } Timings::$playerChunkOrder->stopTiming(); @@ -917,7 +917,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ }else{ $this->spawnPosition = null; } - $this->networkSession->syncPlayerSpawnPoint($this->getSpawn()); + $this->getNetworkSession()->syncPlayerSpawnPoint($this->getSpawn()); } public function isSleeping() : bool{ @@ -961,7 +961,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->getWorld()->setSleepTicks(0); - $this->networkSession->sendDataPacket(AnimatePacket::create($this->getId(), AnimatePacket::ACTION_STOP_SLEEP)); + $this->getNetworkSession()->sendDataPacket(AnimatePacket::create($this->getId(), AnimatePacket::ACTION_STOP_SLEEP)); } } @@ -1014,7 +1014,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->spawnToAll(); } - $this->networkSession->syncGameMode($this->gamemode); + $this->getNetworkSession()->syncGameMode($this->gamemode); return true; } @@ -1238,7 +1238,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ public function setMotion(Vector3 $motion) : bool{ if(parent::setMotion($motion)){ $this->broadcastMotion(); - $this->networkSession->sendDataPacket(SetActorMotionPacket::create($this->id, $motion)); + $this->getNetworkSession()->sendDataPacket(SetActorMotionPacket::create($this->id, $motion)); return true; } @@ -1753,35 +1753,35 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ if($subtitle !== ""){ $this->sendSubTitle($subtitle); } - $this->networkSession->onTitle($title); + $this->getNetworkSession()->onTitle($title); } /** * Sets the subtitle message, without sending a title. */ public function sendSubTitle(string $subtitle) : void{ - $this->networkSession->onSubTitle($subtitle); + $this->getNetworkSession()->onSubTitle($subtitle); } /** * Adds small text to the user's screen. */ public function sendActionBarMessage(string $message) : void{ - $this->networkSession->onActionBar($message); + $this->getNetworkSession()->onActionBar($message); } /** * Removes the title from the client's screen. */ public function removeTitles() : void{ - $this->networkSession->onClearTitle(); + $this->getNetworkSession()->onClearTitle(); } /** * Resets the title duration settings to defaults and removes any existing titles. */ public function resetTitles() : void{ - $this->networkSession->onResetTitleOptions(); + $this->getNetworkSession()->onResetTitleOptions(); } /** @@ -1793,7 +1793,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ */ public function setTitleDuration(int $fadeIn, int $stay, int $fadeOut) : void{ if($fadeIn >= 0 and $stay >= 0 and $fadeOut >= 0){ - $this->networkSession->onTitleDuration($fadeIn, $stay, $fadeOut); + $this->getNetworkSession()->onTitleDuration($fadeIn, $stay, $fadeOut); } } @@ -1808,7 +1808,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return; } - $this->networkSession->onRawChatMessage($this->getLanguage()->translateString($message)); + $this->getNetworkSession()->onRawChatMessage($this->getLanguage()->translateString($message)); } /** @@ -1819,7 +1819,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ foreach($parameters as $i => $p){ $parameters[$i] = $this->getLanguage()->translateString($p, [], "pocketmine."); } - $this->networkSession->onTranslatedChatMessage($this->getLanguage()->translateString($message, $parameters, "pocketmine."), $parameters); + $this->getNetworkSession()->onTranslatedChatMessage($this->getLanguage()->translateString($message, $parameters, "pocketmine."), $parameters); }else{ $this->sendMessage($this->getLanguage()->translateString($message, $parameters)); } @@ -1829,9 +1829,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ * @param string[] $args */ public function sendJukeboxPopup(string $key, array $args) : void{ - if($this->networkSession !== null){ - $this->networkSession->onJukeboxPopup($key, $args); - } + $this->getNetworkSession()->onJukeboxPopup($key, $args); } /** @@ -1840,11 +1838,11 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ * TODO: add translation type popups */ public function sendPopup(string $message) : void{ - $this->networkSession->onPopup($message); + $this->getNetworkSession()->onPopup($message); } public function sendTip(string $message) : void{ - $this->networkSession->onTip($message); + $this->getNetworkSession()->onTip($message); } /** @@ -1854,7 +1852,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ */ public function sendForm(Form $form) : void{ $id = $this->formIdCounter++; - if($this->networkSession->onFormSent($id, $form)){ + if($this->getNetworkSession()->onFormSent($id, $form)){ $this->forms[$id] = $form; } } @@ -1893,7 +1891,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $ev = new PlayerTransferEvent($this, $address, $port, $message); $ev->call(); if(!$ev->isCancelled()){ - $this->networkSession->transfer($ev->getAddress(), $ev->getPort(), $ev->getMessage()); + $this->getNetworkSession()->transfer($ev->getAddress(), $ev->getPort(), $ev->getMessage()); return true; } @@ -1938,7 +1936,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return; } - $this->networkSession->onPlayerDestroyed($reason); + $this->getNetworkSession()->onPlayerDestroyed($reason); $this->onPostDisconnect($reason, $quitMessage); } @@ -2103,7 +2101,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->startDeathAnimation(); - $this->networkSession->onServerDeath(); + $this->getNetworkSession()->onServerDeath(); } protected function onDeathUpdate(int $tickDiff) : bool{ @@ -2143,7 +2141,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->spawnToAll(); $this->scheduleUpdate(); - $this->networkSession->onServerRespawn(); + $this->getNetworkSession()->onServerRespawn(); } protected function applyPostDamageEffects(EntityDamageEvent $source) : void{ @@ -2198,7 +2196,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ * TODO: remove this */ public function sendPosition(Vector3 $pos, ?float $yaw = null, ?float $pitch = null, int $mode = MovePlayerPacket::MODE_NORMAL) : void{ - $this->networkSession->syncMovement($pos, $yaw, $pitch, $mode); + $this->getNetworkSession()->syncMovement($pos, $yaw, $pitch, $mode); $this->ySize = 0; } @@ -2303,7 +2301,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->removeCurrentWindow(); $this->logger->debug("Opening inventory " . get_class($inventory) . "#" . spl_object_id($inventory)); - $this->networkSession->getInvManager()->onCurrentWindowChange($inventory); + $this->getNetworkSession()->getInvManager()->onCurrentWindowChange($inventory); $inventory->onOpen($this); $this->currentWindow = $inventory; return true; @@ -2316,7 +2314,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->logger->debug("Closing inventory " . get_class($this->currentWindow) . "#" . spl_object_id($this->currentWindow)); $this->currentWindow->onClose($this); if($this->isConnected()){ - $this->networkSession->getInvManager()->onCurrentWindowRemove(); + $this->getNetworkSession()->getInvManager()->onCurrentWindowRemove(); } $this->currentWindow = null; } diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index ebd29eff51..c69e169641 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -235,156 +235,16 @@ parameters: count: 1 path: ../../../src/player/Player.php - - - message: "#^Cannot call method syncAdventureSettings\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 3 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method syncViewAreaRadius\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Method pocketmine\\\\player\\\\Player\\:\\:getNetworkSession\\(\\) should return pocketmine\\\\network\\\\mcpe\\\\NetworkSession but returns pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method onEnterWorld\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method stopUsingChunk\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - message: "#^Cannot call method getEntities\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" count: 1 path: ../../../src/player/Player.php - - - message: "#^Cannot call method startUsingChunk\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method notifyTerrainReady\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method syncViewAreaCenterPoint\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - message: "#^Method pocketmine\\\\player\\\\Player\\:\\:getSpawn\\(\\) should return pocketmine\\\\world\\\\Position but returns pocketmine\\\\world\\\\Position\\|null\\.$#" count: 1 path: ../../../src/player/Player.php - - - message: "#^Cannot call method syncPlayerSpawnPoint\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method sendDataPacket\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 2 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method syncGameMode\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method onTitle\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method onSubTitle\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method onActionBar\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method onClearTitle\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method onResetTitleOptions\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method onTitleDuration\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method onRawChatMessage\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method onTranslatedChatMessage\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method onPopup\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method onTip\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method onFormSent\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method transfer\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method onPlayerDestroyed\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method onServerDeath\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method onServerRespawn\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method syncMovement\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Cannot call method getInvManager\\(\\) on pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\|null\\.$#" - count: 2 - path: ../../../src/player/Player.php - - message: "#^Method pocketmine\\\\plugin\\\\PluginBase\\:\\:getConfig\\(\\) should return pocketmine\\\\utils\\\\Config but returns pocketmine\\\\utils\\\\Config\\|null\\.$#" count: 1 From 01c867b60853511443868724c97ba7ffe28aa74a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 10 Jan 2021 20:30:39 +0000 Subject: [PATCH 2251/3224] Human: make held item sync on inventory content change more consistent before this change, setContents() wouldn't trigger a held item sync, nor would setItem(heldItemIndex, someItem). --- src/entity/Human.php | 23 +++++++++++++++++++++++ src/inventory/PlayerInventory.php | 3 --- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/entity/Human.php b/src/entity/Human.php index 65f26ebc36..7ba3e8e056 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -30,6 +30,8 @@ use pocketmine\entity\effect\VanillaEffects; use pocketmine\entity\projectile\ProjectileSource; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\player\PlayerExhaustEvent; +use pocketmine\inventory\CallbackInventoryListener; +use pocketmine\inventory\Inventory; use pocketmine\inventory\InventoryHolder; use pocketmine\inventory\PlayerInventory; use pocketmine\item\enchantment\VanillaEnchantments; @@ -56,6 +58,7 @@ use pocketmine\utils\Limits; use pocketmine\uuid\UUID; use pocketmine\world\sound\TotemUseSound; use function array_filter; +use function array_key_exists; use function array_merge; use function array_values; use function min; @@ -210,6 +213,23 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $this->xpManager = new ExperienceManager($this); $this->inventory = new PlayerInventory($this); + $syncHeldItem = function() : void{ + foreach($this->getViewers() as $viewer){ + $viewer->getNetworkSession()->onMobEquipmentChange($this); + } + }; + $this->inventory->getListeners()->add(new CallbackInventoryListener( + function(Inventory $unused, int $slot, Item $unused2) use ($syncHeldItem) : void{ + if($slot === $this->inventory->getHeldItemIndex()){ + $syncHeldItem(); + } + }, + function(Inventory $unused, array $oldItems) use ($syncHeldItem) : void{ + if(array_key_exists($this->inventory->getHeldItemIndex(), $oldItems)){ + $syncHeldItem(); + } + } + )); $this->enderChestInventory = new EnderChestInventory(); $this->initHumanData($nbt); @@ -217,6 +237,8 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ if($inventoryTag !== null){ $armorListeners = $this->armorInventory->getListeners()->toArray(); $this->armorInventory->getListeners()->clear(); + $inventoryListeners = $this->inventory->getListeners()->toArray(); + $this->inventory->getListeners()->clear(); /** @var CompoundTag $item */ foreach($inventoryTag as $i => $item){ @@ -231,6 +253,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ } $this->armorInventory->getListeners()->add(...$armorListeners); + $this->inventory->getListeners()->add(...$inventoryListeners); } $enderChestInventoryTag = $nbt->getListTag("EnderChestInventory"); diff --git a/src/inventory/PlayerInventory.php b/src/inventory/PlayerInventory.php index 50d9296730..d3de07a625 100644 --- a/src/inventory/PlayerInventory.php +++ b/src/inventory/PlayerInventory.php @@ -104,9 +104,6 @@ class PlayerInventory extends BaseInventory{ */ public function setItemInHand(Item $item) : void{ $this->setItem($this->getHeldItemIndex(), $item); - foreach($this->holder->getViewers() as $viewer){ - $viewer->getNetworkSession()->onMobEquipmentChange($this->holder); - } } /** From c70c0b55df8df8c8dd4063ec10a2e7161ea6f4b2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 12 Jan 2021 16:44:25 +0000 Subject: [PATCH 2252/3224] Separate held item index change listener logic from PlayerInventory --- src/entity/Human.php | 8 +++++- src/inventory/PlayerInventory.php | 28 +++++++++++++------ src/network/mcpe/InventoryManager.php | 26 +++++++++++++---- .../mcpe/handler/InGamePacketHandler.php | 1 + src/player/Player.php | 2 +- 5 files changed, 48 insertions(+), 17 deletions(-) diff --git a/src/entity/Human.php b/src/entity/Human.php index 7ba3e8e056..73db86ac34 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -264,7 +264,12 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ } } - $this->inventory->setHeldItemIndex($nbt->getInt("SelectedInventorySlot", 0), false); + $this->inventory->setHeldItemIndex($nbt->getInt("SelectedInventorySlot", 0)); + $this->inventory->getHeldItemIndexChangeListeners()->add(function(int $oldIndex) : void{ + foreach($this->getViewers() as $viewer){ + $viewer->getNetworkSession()->onMobEquipmentChange($this); + } + }); $this->hungerManager->setFood((float) $nbt->getInt("foodLevel", (int) $this->hungerManager->getFood())); $this->hungerManager->setExhaustion($nbt->getFloat("foodExhaustionLevel", $this->hungerManager->getExhaustion())); @@ -457,6 +462,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ protected function onDispose() : void{ $this->inventory->removeAllViewers(); + $this->inventory->getHeldItemIndexChangeListeners()->clear(); $this->enderChestInventory->removeAllViewers(); parent::onDispose(); } diff --git a/src/inventory/PlayerInventory.php b/src/inventory/PlayerInventory.php index d3de07a625..07befe054f 100644 --- a/src/inventory/PlayerInventory.php +++ b/src/inventory/PlayerInventory.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\inventory; +use Ds\Set; use pocketmine\entity\Human; use pocketmine\item\Item; use pocketmine\player\Player; @@ -35,8 +36,15 @@ class PlayerInventory extends BaseInventory{ /** @var int */ protected $itemInHandIndex = 0; + /** + * @var \Closure[]|Set + * @phpstan-var Set<\Closure(int $oldIndex) : void> + */ + protected $heldItemIndexChangeListeners; + public function __construct(Human $player){ $this->holder = $player; + $this->heldItemIndexChangeListeners = new Set(); parent::__construct(36); } @@ -73,25 +81,27 @@ class PlayerInventory extends BaseInventory{ /** * Sets which hotbar slot the player is currently loading. * - * @param int $hotbarSlot 0-8 index of the hotbar slot to hold - * @param bool $send Whether to send updates back to the inventory holder. This should usually be true for plugin calls. - * It should only be false to prevent feedback loops of equipment packets between client and server. + * @param int $hotbarSlot 0-8 index of the hotbar slot to hold * * @throws \InvalidArgumentException if the hotbar slot is out of range */ - public function setHeldItemIndex(int $hotbarSlot, bool $send = true) : void{ + public function setHeldItemIndex(int $hotbarSlot) : void{ $this->throwIfNotHotbarSlot($hotbarSlot); + $oldIndex = $this->itemInHandIndex; $this->itemInHandIndex = $hotbarSlot; - if($this->holder instanceof Player and $send){ - $this->holder->getNetworkSession()->getInvManager()->syncSelectedHotbarSlot(); - } - foreach($this->holder->getViewers() as $viewer){ - $viewer->getNetworkSession()->onMobEquipmentChange($this->holder); + foreach($this->heldItemIndexChangeListeners as $callback){ + $callback($oldIndex); } } + /** + * @return \Closure[]|Set + * @phpstan-return Set<\Closure(int $oldIndex) : void> + */ + public function getHeldItemIndexChangeListeners() : Set{ return $this->heldItemIndexChangeListeners; } + /** * Returns the currently-held item. */ diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index 76f6dca2c2..33570e366a 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -76,6 +76,8 @@ class InventoryManager{ * @phpstan-var array> */ private $initiatedSlotChanges = []; + /** @var int */ + private $clientSelectedHotbarSlot = -1; public function __construct(Player $player, NetworkSession $session){ $this->player = $player; @@ -84,6 +86,10 @@ class InventoryManager{ $this->add(ContainerIds::INVENTORY, $this->player->getInventory()); $this->add(ContainerIds::ARMOR, $this->player->getArmorInventory()); $this->add(ContainerIds::UI, $this->player->getCursorInventory()); + + $this->player->getInventory()->getHeldItemIndexChangeListeners()->add(function() : void{ + $this->syncSelectedHotbarSlot(); + }); } private function add(int $id, Inventory $inventory) : void{ @@ -206,13 +212,21 @@ class InventoryManager{ } } + public function onClientSelectHotbarSlot(int $slot) : void{ + $this->clientSelectedHotbarSlot = $slot; + } + public function syncSelectedHotbarSlot() : void{ - $this->session->sendDataPacket(MobEquipmentPacket::create( - $this->player->getId(), - TypeConverter::getInstance()->coreItemStackToNet($this->player->getInventory()->getItemInHand()), - $this->player->getInventory()->getHeldItemIndex(), - ContainerIds::INVENTORY - )); + $selected = $this->player->getInventory()->getHeldItemIndex(); + if($selected !== $this->clientSelectedHotbarSlot){ + $this->session->sendDataPacket(MobEquipmentPacket::create( + $this->player->getId(), + TypeConverter::getInstance()->coreItemStackToNet($this->player->getInventory()->getItemInHand()), + $selected, + ContainerIds::INVENTORY + )); + $this->clientSelectedHotbarSlot = $selected; + } } public function syncCreative() : void{ diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 2699bf3105..4e0c2e6e9b 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -448,6 +448,7 @@ class InGamePacketHandler extends PacketHandler{ } public function handleMobEquipment(MobEquipmentPacket $packet) : bool{ + $this->session->getInvManager()->onClientSelectHotbarSlot($packet->hotbarSlot); if(!$this->player->selectHotbarSlot($packet->hotbarSlot)){ $this->session->getInvManager()->syncSelectedHotbarSlot(); } diff --git a/src/player/Player.php b/src/player/Player.php index 7ce797a36a..6749b82521 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1373,7 +1373,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return false; } - $this->inventory->setHeldItemIndex($hotbarSlot, false); + $this->inventory->setHeldItemIndex($hotbarSlot); $this->setUsingItem(false); return true; From a90f8601d4341a3156ad10bebb3d85832bd02d65 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 12 Jan 2021 21:29:23 +0000 Subject: [PATCH 2253/3224] [ci skip] changelog: fixed typo --- changelogs/4.0-snapshot.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index aadaaac59b..bd7b631096 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -852,7 +852,7 @@ This version features substantial changes to the network system, improving coher - `World->loadChunk()` now returns `?Chunk`, and the `$create` parameter has been removed. - `World->getChunk()` no longer accepts a `$create` parameter. - `World->updateAllLight()` now accepts `int, int, int` instead of `Vector3`. - - `ChunkManager->setChunk()` (and its notable implementations in `World` and `SimpleChunkManager` no longer accepts NULL for the `$chunk` parameter. + - `ChunkManager->setChunk()` (and its notable implementations in `World` and `SimpleChunkManager`) no longer accepts NULL for the `$chunk` parameter. - `Chunk->__construct()` now has the signature `array $subChunks, ?list $entities, ?list $tiles, ?BiomeArray $biomeArray, ?HeightArray $heightArray`. - `Chunk->getSubChunk()` now returns `SubChunk` instead of `SubChunkInterface|null` (and throws `InvalidArgumentException` on out-of-bounds coordinates). - `Chunk->setSubChunk()` no longer accepts `SubChunkInterface`, and the `$allowEmpty` parameter has been removed. From 120b224e419f873681ad185c3a8b53f67a7d3fd5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 12 Jan 2021 21:34:04 +0000 Subject: [PATCH 2254/3224] Updated composer dependencies --- composer.lock | 52 +++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/composer.lock b/composer.lock index 585a519773..4d350dca4d 100644 --- a/composer.lock +++ b/composer.lock @@ -352,12 +352,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/ClassLoader.git", - "reference": "67ad4a426f00bca9f1361d8e4bc99188fbfbf9d9" + "reference": "f5d5e0ae6982686151d744d4c8b31e66c27001f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/67ad4a426f00bca9f1361d8e4bc99188fbfbf9d9", - "reference": "67ad4a426f00bca9f1361d8e4bc99188fbfbf9d9", + "url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/f5d5e0ae6982686151d744d4c8b31e66c27001f4", + "reference": "f5d5e0ae6982686151d744d4c8b31e66c27001f4", "shasum": "" }, "require": { @@ -388,7 +388,7 @@ "issues": "https://github.com/pmmp/ClassLoader/issues", "source": "https://github.com/pmmp/ClassLoader/tree/master" }, - "time": "2020-12-17T17:02:45+00:00" + "time": "2021-01-06T21:09:10+00:00" }, { "name": "pocketmine/color", @@ -513,12 +513,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/LogPthreads.git", - "reference": "a01bd5dd4ea09c0c921c1f2cd74a75e26e69eb75" + "reference": "273e4ba9715c7eb916c6e50e0b92ac43b7ac389e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/a01bd5dd4ea09c0c921c1f2cd74a75e26e69eb75", - "reference": "a01bd5dd4ea09c0c921c1f2cd74a75e26e69eb75", + "url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/273e4ba9715c7eb916c6e50e0b92ac43b7ac389e", + "reference": "273e4ba9715c7eb916c6e50e0b92ac43b7ac389e", "shasum": "" }, "require": { @@ -549,7 +549,7 @@ "issues": "https://github.com/pmmp/LogPthreads/issues", "source": "https://github.com/pmmp/LogPthreads/tree/master" }, - "time": "2020-12-17T16:35:10+00:00" + "time": "2021-01-06T21:23:23+00:00" }, { "name": "pocketmine/math", @@ -640,12 +640,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "bd21d30af4f3b0d9a83e697922cd57dbefeb146f" + "reference": "c2a4f728ab816bde2713345ffaad79410c6eadd4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/bd21d30af4f3b0d9a83e697922cd57dbefeb146f", - "reference": "bd21d30af4f3b0d9a83e697922cd57dbefeb146f", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/c2a4f728ab816bde2713345ffaad79410c6eadd4", + "reference": "c2a4f728ab816bde2713345ffaad79410c6eadd4", "shasum": "" }, "require": { @@ -675,7 +675,7 @@ "issues": "https://github.com/pmmp/RakLib/issues", "source": "https://github.com/pmmp/RakLib/tree/master" }, - "time": "2020-12-17T17:49:46+00:00" + "time": "2021-01-06T20:59:43+00:00" }, { "name": "pocketmine/snooze", @@ -920,16 +920,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.20.0", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "39d483bdf39be819deabf04ec872eb0b2410b531" + "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531", - "reference": "39d483bdf39be819deabf04ec872eb0b2410b531", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f377a3dd1fde44d37b9831d68dc8dea3ffd28e13", + "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13", "shasum": "" }, "require": { @@ -941,7 +941,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -980,7 +980,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.0" }, "funding": [ { @@ -996,7 +996,7 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-01-07T16:49:33+00:00" } ], "packages-dev": [ @@ -3072,16 +3072,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.20.0", + "version": "v1.22.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41" + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", "shasum": "" }, "require": { @@ -3093,7 +3093,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3131,7 +3131,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.0" }, "funding": [ { @@ -3147,7 +3147,7 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "theseer/tokenizer", From 4c0d3d68afcde694cb58ab2a3587d0ec085bc2d3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 12 Jan 2021 21:53:41 +0000 Subject: [PATCH 2255/3224] Bump PHP requirement to 7.4.0 --- .github/workflows/main.yml | 8 ++++---- BUILDING.md | 2 +- composer.json | 4 ++-- composer.lock | 6 +++--- src/PocketMine.php | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 017ef1ece0..4cd3c19c85 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - php: [7.3.25, 7.4.13] + php: [7.4.13] steps: - uses: actions/checkout@v2 #needed for build.sh @@ -34,7 +34,7 @@ jobs: strategy: matrix: - php: [7.3.25, 7.4.13] + php: [7.4.13] steps: - uses: actions/checkout@v2 @@ -78,7 +78,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php: [7.3.25, 7.4.13] + php: [7.4.13] steps: - uses: actions/checkout@v2 @@ -122,7 +122,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php: [7.3.25, 7.4.13] + php: [7.4.13] steps: - uses: actions/checkout@v2 diff --git a/BUILDING.md b/BUILDING.md index 8ba85332fa..4db556bafe 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -2,7 +2,7 @@ ## Pre-requisites - A bash shell (git bash is sufficient for Windows) - [`git`](https://git-scm.com) available in your shell -- PHP 7.3 or newer available in your shell +- PHP 7.4 or newer available in your shell - [`composer`](https://getcomposer.org) available in your shell ## Custom PHP binaries diff --git a/composer.json b/composer.json index 975a6c6b7c..f009ce1447 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,7 @@ "homepage": "https://pmmp.io", "license": "LGPL-3.0", "require": { - "php": ">=7.3.0", + "php": ">=7.4.0", "php-64bit": "*", "ext-chunkutils2": "^0.1.0", "ext-curl": "*", @@ -71,7 +71,7 @@ }, "config": { "platform": { - "php": "7.3.0" + "php": "7.4.0" }, "sort-packages": true }, diff --git a/composer.lock b/composer.lock index f0fe5bb1be..ef45d83a92 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d6467f823dc9f715fd36b79b304e777d", + "content-hash": "37fd93c9897468e5d8683a546ebaf8b6", "packages": [ { "name": "adhocore/json-comment", @@ -3268,7 +3268,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=7.3.0", + "php": ">=7.4.0", "php-64bit": "*", "ext-chunkutils2": "^0.1.0", "ext-curl": "*", @@ -3297,7 +3297,7 @@ }, "platform-dev": [], "platform-overrides": { - "php": "7.3.0" + "php": "7.4.0" }, "plugin-api-version": "2.0.0" } diff --git a/src/PocketMine.php b/src/PocketMine.php index c97474a3f3..15ec49cdde 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -36,7 +36,7 @@ namespace pocketmine { require_once __DIR__ . '/VersionInfo.php'; - const MIN_PHP_VERSION = "7.3.0"; + const MIN_PHP_VERSION = "7.4.0"; /** * @param string $message From a9f8afa0779938068022e602c75a5edcc6266a6e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 15 Jan 2021 00:17:56 +0000 Subject: [PATCH 2256/3224] Banner: remove Deque usages originally I introduced this to make it easier to implement the various APIs addPattern removePattern etc, but those were later removed in favour of simple getPatterns() and setPatterns(), allowing plugin developers to use ext-ds APIs to manipulate patterns. However, ds poses a number of headaches because of mutability combined with by-ref semantics, which make it a pain to use these on the APIs because we can't guarantee that they won't be modified. As much as arrays suck, they have two significant advantages over ext-ds: 1) they have copy-on-write semantics, and 2) they support PHP 8.0 without any extra work from me. --- src/block/BaseBanner.php | 36 +++++++++++++----------------- src/block/tile/Banner.php | 20 ++++++++--------- src/item/Banner.php | 34 ++++++++++------------------ tests/phpstan/configs/ds-bugs.neon | 5 ----- 4 files changed, 36 insertions(+), 59 deletions(-) diff --git a/src/block/BaseBanner.php b/src/block/BaseBanner.php index e09f72dbb8..e89e1b7b90 100644 --- a/src/block/BaseBanner.php +++ b/src/block/BaseBanner.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\block; -use Ds\Deque; use pocketmine\block\tile\Banner as TileBanner; use pocketmine\block\utils\BannerPattern; use pocketmine\block\utils\DyeColor; @@ -36,28 +35,23 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\world\BlockTransaction; +use function array_filter; use function assert; +use function count; abstract class BaseBanner extends Transparent{ /** @var DyeColor */ protected $baseColor; /** - * @var Deque|BannerPattern[] - * @phpstan-var Deque + * @var BannerPattern[] + * @phpstan-var list */ - protected $patterns; + protected $patterns = []; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0, BlockToolType::AXE)); $this->baseColor = DyeColor::BLACK(); - $this->patterns = new Deque(); - } - - public function __clone(){ - parent::__clone(); - //pattern objects are considered immutable, so they don't need to be copied - $this->patterns = $this->patterns->copy(); } public function readStateFromWorld() : void{ @@ -89,21 +83,21 @@ abstract class BaseBanner extends Transparent{ } /** - * @return Deque|BannerPattern[] - * @phpstan-return Deque + * @return BannerPattern[] + * @phpstan-return list */ - public function getPatterns() : Deque{ + public function getPatterns() : array{ return $this->patterns; } /** - * @param Deque|BannerPattern[] $patterns - * @phpstan-param Deque $patterns + * @param BannerPattern[] $patterns + * @phpstan-param list $patterns * @return $this */ - public function setPatterns(Deque $patterns) : self{ - $checked = $patterns->filter(function($v) : bool{ return $v instanceof BannerPattern; }); - if($checked->count() !== $patterns->count()){ + public function setPatterns(array $patterns) : self{ + $checked = array_filter($patterns, fn($v) => $v instanceof BannerPattern); + if(count($checked) !== count($patterns)){ throw new \TypeError("Deque must only contain " . BannerPattern::class . " objects"); } $this->patterns = $checked; @@ -140,7 +134,7 @@ abstract class BaseBanner extends Transparent{ public function getDropsForCompatibleTool(Item $item) : array{ $drop = $this->asItem(); - if($drop instanceof ItemBanner and !$this->patterns->isEmpty()){ + if($drop instanceof ItemBanner and count($this->patterns) > 0){ $drop->setPatterns($this->patterns); } @@ -149,7 +143,7 @@ abstract class BaseBanner extends Transparent{ public function getPickedItem(bool $addUserData = false) : Item{ $result = $this->asItem(); - if($addUserData and $result instanceof ItemBanner and !$this->patterns->isEmpty()){ + if($addUserData and $result instanceof ItemBanner and count($this->patterns) > 0){ $result->setPatterns($this->patterns); } return $result; diff --git a/src/block/tile/Banner.php b/src/block/tile/Banner.php index 2ee93b2a4a..5256dd70dd 100644 --- a/src/block/tile/Banner.php +++ b/src/block/tile/Banner.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\block\tile; -use Ds\Deque; use pocketmine\block\utils\BannerPattern; use pocketmine\block\utils\DyeColor; use pocketmine\data\bedrock\DyeColorIdMap; @@ -48,14 +47,13 @@ class Banner extends Spawnable{ private $baseColor; /** - * @var BannerPattern[]|Deque - * @phpstan-var Deque + * @var BannerPattern[] + * @phpstan-var list */ - private $patterns; + private $patterns = []; public function __construct(World $world, Vector3 $pos){ $this->baseColor = DyeColor::BLACK(); - $this->patterns = new Deque(); parent::__construct($world, $pos); } @@ -115,18 +113,18 @@ class Banner extends Spawnable{ } /** - * @return BannerPattern[]|Deque - * @phpstan-return Deque + * @return BannerPattern[] + * @phpstan-return list */ - public function getPatterns() : Deque{ + public function getPatterns() : array{ return $this->patterns; } /** - * @param BannerPattern[]|Deque $patterns - * @phpstan-param Deque $patterns + * @param BannerPattern[] $patterns + * @phpstan-param list $patterns */ - public function setPatterns(Deque $patterns) : void{ + public function setPatterns(array $patterns) : void{ $this->patterns = $patterns; } diff --git a/src/item/Banner.php b/src/item/Banner.php index 1ceeeb369b..744c6fb890 100644 --- a/src/item/Banner.php +++ b/src/item/Banner.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\item; -use Ds\Deque; use pocketmine\block\Block; use pocketmine\block\tile\Banner as TileBanner; use pocketmine\block\utils\BannerPattern; @@ -41,16 +40,14 @@ class Banner extends ItemBlockWallOrFloor{ private $color; /** - * @var BannerPattern[]|Deque - * @phpstan-var Deque + * @var BannerPattern[] + * @phpstan-var list */ - private $patterns; + private $patterns = []; public function __construct(ItemIdentifier $identifier, Block $floorVariant, Block $wallVariant){ parent::__construct($identifier, $floorVariant, $wallVariant); $this->color = DyeColor::BLACK(); - - $this->patterns = new Deque(); } public function getColor() : DyeColor{ @@ -72,20 +69,20 @@ class Banner extends ItemBlockWallOrFloor{ } /** - * @return Deque|BannerPattern[] - * @phpstan-return Deque + * @return BannerPattern[] + * @phpstan-return list */ - public function getPatterns() : Deque{ + public function getPatterns() : array{ return $this->patterns; } /** - * @param Deque|BannerPattern[] $patterns - * @phpstan-param Deque $patterns + * @param BannerPattern[] $patterns + * @phpstan-param list $patterns * * @return $this */ - public function setPatterns(Deque $patterns) : self{ + public function setPatterns(array $patterns) : self{ $this->patterns = $patterns; return $this; } @@ -97,14 +94,14 @@ class Banner extends ItemBlockWallOrFloor{ protected function deserializeCompoundTag(CompoundTag $tag) : void{ parent::deserializeCompoundTag($tag); - $this->patterns = new Deque(); + $this->patterns = []; $colorIdMap = DyeColorIdMap::getInstance(); $patterns = $tag->getListTag(self::TAG_PATTERNS); if($patterns !== null){ /** @var CompoundTag $t */ foreach($patterns as $t){ - $this->patterns->push(new BannerPattern($t->getString(self::TAG_PATTERN_NAME), $colorIdMap->fromInvertedId($t->getInt(self::TAG_PATTERN_COLOR)))); + $this->patterns[] = new BannerPattern($t->getString(self::TAG_PATTERN_NAME), $colorIdMap->fromInvertedId($t->getInt(self::TAG_PATTERN_COLOR))); } } } @@ -112,10 +109,9 @@ class Banner extends ItemBlockWallOrFloor{ protected function serializeCompoundTag(CompoundTag $tag) : void{ parent::serializeCompoundTag($tag); - if(!$this->patterns->isEmpty()){ + if(count($this->patterns) > 0){ $patterns = new ListTag(); $colorIdMap = DyeColorIdMap::getInstance(); - /** @var BannerPattern $pattern */ foreach($this->patterns as $pattern){ $patterns->push(CompoundTag::create() ->setString(self::TAG_PATTERN_NAME, $pattern->getId()) @@ -128,10 +124,4 @@ class Banner extends ItemBlockWallOrFloor{ $tag->removeTag(self::TAG_PATTERNS); } } - - public function __clone(){ - parent::__clone(); - //we don't need to duplicate the individual patterns because they are immutable - $this->patterns = $this->patterns->copy(); - } } diff --git a/tests/phpstan/configs/ds-bugs.neon b/tests/phpstan/configs/ds-bugs.neon index c12969ee46..48277f766b 100644 --- a/tests/phpstan/configs/ds-bugs.neon +++ b/tests/phpstan/configs/ds-bugs.neon @@ -1,10 +1,5 @@ parameters: ignoreErrors: - - - message: "#^Cannot access an offset on Ds\\\\Deque\\\\.$#" - count: 1 - path: ../../../src/block/tile/Banner.php - - message: "#^Cannot access offset int on Ds\\\\Deque\\\\.$#" count: 2 From 3fb4b30742f336be99a2e347856e6768fac4962c Mon Sep 17 00:00:00 2001 From: SalmonDE Date: Wed, 20 Jan 2021 22:09:59 +0100 Subject: [PATCH 2257/3224] InventoryPickupItemEvent: rename item to itemEntity (#4007) --- src/event/inventory/InventoryPickupItemEvent.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/event/inventory/InventoryPickupItemEvent.php b/src/event/inventory/InventoryPickupItemEvent.php index ed15bbbe12..71a81c57c4 100644 --- a/src/event/inventory/InventoryPickupItemEvent.php +++ b/src/event/inventory/InventoryPickupItemEvent.php @@ -32,14 +32,14 @@ class InventoryPickupItemEvent extends InventoryEvent implements Cancellable{ use CancellableTrait; /** @var ItemEntity */ - private $item; + private $itemEntity; - public function __construct(Inventory $inventory, ItemEntity $item){ - $this->item = $item; + public function __construct(Inventory $inventory, ItemEntity $itemEntity){ + $this->itemEntity = $itemEntity; parent::__construct($inventory); } - public function getItem() : ItemEntity{ - return $this->item; + public function getItemEntity() : ItemEntity{ + return $this->itemEntity; } } From 2064b411f295bc2ce215fafa82ecd9086e99f5c9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Jan 2021 22:53:51 +0000 Subject: [PATCH 2258/3224] fix build --- src/player/Player.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 6749b82521..b9e0db4e34 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -317,8 +317,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logIn", [ TextFormat::AQUA . $this->username . TextFormat::WHITE, - $this->networkSession->getIp(), - $this->networkSession->getPort(), + $session->getIp(), + $session->getPort(), $this->id, $this->getWorld()->getDisplayName(), round($this->location->x, 4), From 74902d9926cd0d8cce2dac54bbb3ab7fc75fff69 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Jan 2021 13:58:08 +0000 Subject: [PATCH 2259/3224] [ci skip] changelog: mention InventoryPickupItemEvent->getItemEntity() rename --- changelogs/4.0-snapshot.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index bd7b631096..5948ef572c 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -348,6 +348,8 @@ This version features substantial changes to the network system, improving coher - The following API methods have been removed: - `PlayerPreLoginEvent->setKickMessage()` - `PlayerPreLoginEvent->getPlayer()` +- The following API methods have been moved / renamed: + - `InventoryPickupItemEvent->getItem()` -> `InventoryPickupItemEvent->getItemEntity()` #### Other changes - Disconnecting players during events no longer crashes the server (although it might cause other side effects). From 269a389a97686e6a15916289127ebc76bf718193 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 25 Jan 2021 18:04:42 +0000 Subject: [PATCH 2260/3224] BlockTransaction: added phpstan return type info for getBlocks() --- src/world/BlockTransaction.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/world/BlockTransaction.php b/src/world/BlockTransaction.php index 996649a5de..1c26166ebe 100644 --- a/src/world/BlockTransaction.php +++ b/src/world/BlockTransaction.php @@ -103,6 +103,7 @@ class BlockTransaction{ /** * @return \Generator|mixed[] [int $x, int $y, int $z, Block $block] + * @phpstan-return \Generator */ public function getBlocks() : \Generator{ foreach($this->blocks as $x => $yLine){ From 5384e2ba9daed266073ab39841a9b9a08e93f68d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Jan 2021 20:26:35 +0000 Subject: [PATCH 2261/3224] Revert "MemoryDump: fixed duplicated properties, reduce useless noise" This reverts commit efd67a132ed432b47a74c8b98211597557c419d5. --- src/MemoryManager.php | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/MemoryManager.php b/src/MemoryManager.php index 1625339039..76a9e4ffc9 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -451,16 +451,22 @@ class MemoryManager{ $info["properties"] = []; - foreach($reflection->getProperties() as $property){ - if($property->isStatic()){ - continue; - } + for($original = $reflection; $reflection !== false; $reflection = $reflection->getParentClass()){ + foreach($reflection->getProperties() as $property){ + if($property->isStatic()){ + continue; + } - if(!$property->isPublic()){ - $property->setAccessible(true); - } + $name = $property->getName(); + if($reflection !== $original and !$property->isPublic()){ + $name = $reflection->getName() . ":" . $name; + } + if(!$property->isPublic()){ + $property->setAccessible(true); + } - $info["properties"][$property->getName()] = self::continueDump($property->getValue($object), $objects, $refCounts, 0, $maxNesting, $maxStringSize); + $info["properties"][$name] = self::continueDump($property->getValue($object), $objects, $refCounts, 0, $maxNesting, $maxStringSize); + } } } From 5a1131d72d718383e53a7c654631dd4cd051fdeb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 27 Jan 2021 21:08:46 +0000 Subject: [PATCH 2262/3224] Populator: require dependencies explicitly, don't make bad assumptions about fields this also leaks ChunkManagers on the worker threads because the generator context is long-lived. --- src/world/generator/populator/TallGrass.php | 19 ++++++++----------- src/world/generator/populator/Tree.php | 11 ++++------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/world/generator/populator/TallGrass.php b/src/world/generator/populator/TallGrass.php index 30a1d8135e..2c2667f8ca 100644 --- a/src/world/generator/populator/TallGrass.php +++ b/src/world/generator/populator/TallGrass.php @@ -29,8 +29,6 @@ use pocketmine\utils\Random; use pocketmine\world\ChunkManager; class TallGrass extends Populator{ - /** @var ChunkManager */ - private $world; /** @var int */ private $randomAmount = 1; /** @var int */ @@ -45,29 +43,28 @@ class TallGrass extends Populator{ } public function populate(ChunkManager $world, int $chunkX, int $chunkZ, Random $random) : void{ - $this->world = $world; $amount = $random->nextRange(0, $this->randomAmount) + $this->baseAmount; $block = VanillaBlocks::TALL_GRASS(); for($i = 0; $i < $amount; ++$i){ $x = $random->nextRange($chunkX * 16, $chunkX * 16 + 15); $z = $random->nextRange($chunkZ * 16, $chunkZ * 16 + 15); - $y = $this->getHighestWorkableBlock($x, $z); + $y = $this->getHighestWorkableBlock($world, $x, $z); - if($y !== -1 and $this->canTallGrassStay($x, $y, $z)){ - $this->world->setBlockAt($x, $y, $z, $block); + if($y !== -1 and $this->canTallGrassStay($world, $x, $y, $z)){ + $world->setBlockAt($x, $y, $z, $block); } } } - private function canTallGrassStay(int $x, int $y, int $z) : bool{ - $b = $this->world->getBlockAt($x, $y, $z)->getId(); - return ($b === BlockLegacyIds::AIR or $b === BlockLegacyIds::SNOW_LAYER) and $this->world->getBlockAt($x, $y - 1, $z)->getId() === BlockLegacyIds::GRASS; + private function canTallGrassStay(ChunkManager $world, int $x, int $y, int $z) : bool{ + $b = $world->getBlockAt($x, $y, $z)->getId(); + return ($b === BlockLegacyIds::AIR or $b === BlockLegacyIds::SNOW_LAYER) and $world->getBlockAt($x, $y - 1, $z)->getId() === BlockLegacyIds::GRASS; } - private function getHighestWorkableBlock(int $x, int $z) : int{ + private function getHighestWorkableBlock(ChunkManager $world, int $x, int $z) : int{ for($y = 127; $y >= 0; --$y){ - $b = $this->world->getBlockAt($x, $y, $z)->getId(); + $b = $world->getBlockAt($x, $y, $z)->getId(); if($b !== BlockLegacyIds::AIR and $b !== BlockLegacyIds::LEAVES and $b !== BlockLegacyIds::LEAVES2 and $b !== BlockLegacyIds::SNOW_LAYER){ return $y + 1; } diff --git a/src/world/generator/populator/Tree.php b/src/world/generator/populator/Tree.php index 8680e0d51f..2e1df68d65 100644 --- a/src/world/generator/populator/Tree.php +++ b/src/world/generator/populator/Tree.php @@ -30,8 +30,6 @@ use pocketmine\world\ChunkManager; use pocketmine\world\generator\object\Tree as ObjectTree; class Tree extends Populator{ - /** @var ChunkManager */ - private $world; /** @var int */ private $randomAmount = 1; /** @var int */ @@ -56,22 +54,21 @@ class Tree extends Populator{ } public function populate(ChunkManager $world, int $chunkX, int $chunkZ, Random $random) : void{ - $this->world = $world; $amount = $random->nextRange(0, $this->randomAmount) + $this->baseAmount; for($i = 0; $i < $amount; ++$i){ $x = $random->nextRange($chunkX << 4, ($chunkX << 4) + 15); $z = $random->nextRange($chunkZ << 4, ($chunkZ << 4) + 15); - $y = $this->getHighestWorkableBlock($x, $z); + $y = $this->getHighestWorkableBlock($world, $x, $z); if($y === -1){ continue; } - ObjectTree::growTree($this->world, $x, $y, $z, $random, $this->type); + ObjectTree::growTree($world, $x, $y, $z, $random, $this->type); } } - private function getHighestWorkableBlock(int $x, int $z) : int{ + private function getHighestWorkableBlock(ChunkManager $world, int $x, int $z) : int{ for($y = 127; $y >= 0; --$y){ - $b = $this->world->getBlockAt($x, $y, $z)->getId(); + $b = $world->getBlockAt($x, $y, $z)->getId(); if($b === BlockLegacyIds::DIRT or $b === BlockLegacyIds::GRASS){ return $y + 1; }elseif($b !== BlockLegacyIds::AIR and $b !== BlockLegacyIds::SNOW_LAYER){ From 02a4f0a170e644a71a966c4158f724848349fd8c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 27 Jan 2021 22:05:43 +0000 Subject: [PATCH 2263/3224] Mark metadata as nullable in resource pack manifest data if the metadata isn't provided, it won't be initialized during decoding. --- src/resourcepacks/json/Manifest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/resourcepacks/json/Manifest.php b/src/resourcepacks/json/Manifest.php index 2891255a4d..94521c1f59 100644 --- a/src/resourcepacks/json/Manifest.php +++ b/src/resourcepacks/json/Manifest.php @@ -45,6 +45,6 @@ final class Manifest{ */ public $modules; - /** @var ManifestMetadata */ - public $metadata; + /** @var ManifestMetadata|null */ + public $metadata = null; } From d4290837f33655fd0de629bbac1228cedd680526 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Feb 2021 13:55:56 +0000 Subject: [PATCH 2264/3224] fix build failure --- tests/phpunit/world/format/io/region/RegionLoaderTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/world/format/io/region/RegionLoaderTest.php b/tests/phpunit/world/format/io/region/RegionLoaderTest.php index c46791875c..f80df791e6 100644 --- a/tests/phpunit/world/format/io/region/RegionLoaderTest.php +++ b/tests/phpunit/world/format/io/region/RegionLoaderTest.php @@ -121,12 +121,12 @@ class RegionLoaderTest extends TestCase{ */ public function testRegionHeaderCachedFilesizeRegression() : void{ $this->region->close(); - $region = new RegionLoader($this->regionPath, 0, 0); //now we have a region, so the header will be verified, triggering two filesize() calls + $region = new RegionLoader($this->regionPath); //now we have a region, so the header will be verified, triggering two filesize() calls $region->open(); $data = str_repeat("hello", 2000); $region->writeChunk(0, 0, $data); //add some data to the end of the file, to make the cached filesize invalid $region->close(); - $region = new RegionLoader($this->regionPath, 0, 0); + $region = new RegionLoader($this->regionPath); $region->open(); self::assertSame($data, $region->readChunk(0, 0)); } From 079e794339107e12d849dbcc7af873fed74344f8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 3 Feb 2021 17:05:01 +0000 Subject: [PATCH 2265/3224] Armor: fixed item disappearing when switching two of the same armour pieces Player->useHeldItem() assumes that if the old item == the new item, we want to set the item back into the inventory if it's modified in-place. Therefore, we don't modify the item in-place to bypass the problem. closes #4022 --- src/item/Armor.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/item/Armor.php b/src/item/Armor.php index 2838982722..39ced43e33 100644 --- a/src/item/Armor.php +++ b/src/item/Armor.php @@ -123,11 +123,13 @@ class Armor extends Durable{ public function onClickAir(Player $player, Vector3 $directionVector) : ItemUseResult{ $existing = $player->getArmorInventory()->getItem($this->getArmorSlot()); - $player->getArmorInventory()->setItem($this->getArmorSlot(), $this->pop()); - if($this->getCount() === 0){ + $thisCopy = clone $this; + $new = $thisCopy->pop(); + $player->getArmorInventory()->setItem($this->getArmorSlot(), $new); + if($thisCopy->getCount() === 0){ $player->getInventory()->setItemInHand($existing); }else{ //if the stack size was bigger than 1 (usually won't happen, but might be caused by plugins - $player->getInventory()->setItemInHand($this); + $player->getInventory()->setItemInHand($thisCopy); $player->getInventory()->addItem($existing); } return ItemUseResult::SUCCESS(); From ae75d73f4894fb792649e7a6af1a63376d162578 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Feb 2021 16:28:49 +0000 Subject: [PATCH 2266/3224] Extract MainLoggerThread unit from MainLogger MainLogger is no longer a Thread, as per the recent changes to pocketmine/log-pthreads. --- composer.lock | 12 +-- phpstan.neon.dist | 1 + src/PocketMine.php | 3 +- src/entity/EntitySizeInfo.php | 2 + src/item/Banner.php | 1 + .../protocol/ClientboundMapItemDataPacket.php | 4 +- src/utils/EnumTrait.php | 1 - src/utils/MainLogger.php | 73 +++---------- src/utils/MainLoggerThread.php | 101 ++++++++++++++++++ tests/phpstan/bootstrap.php | 8 +- .../check-explicit-mixed-baseline.neon | 2 +- .../block/regenerate_consistency_check.php | 8 +- tests/phpunit/scheduler/AsyncPoolTest.php | 3 +- 13 files changed, 140 insertions(+), 79 deletions(-) create mode 100644 src/utils/MainLoggerThread.php diff --git a/composer.lock b/composer.lock index 1b56339b84..a778a5579b 100644 --- a/composer.lock +++ b/composer.lock @@ -513,17 +513,17 @@ "source": { "type": "git", "url": "https://github.com/pmmp/LogPthreads.git", - "reference": "273e4ba9715c7eb916c6e50e0b92ac43b7ac389e" + "reference": "634af620e1cb3b4f3c7ed356cc31d778b00fd717" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/273e4ba9715c7eb916c6e50e0b92ac43b7ac389e", - "reference": "273e4ba9715c7eb916c6e50e0b92ac43b7ac389e", + "url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/634af620e1cb3b4f3c7ed356cc31d778b00fd717", + "reference": "634af620e1cb3b4f3c7ed356cc31d778b00fd717", "shasum": "" }, "require": { "ext-pthreads": "~3.2.0", - "php": ">=7.2", + "php": "^7.2 || ^8.0", "pocketmine/log": "^0.2.0 || dev-master" }, "conflict": { @@ -531,7 +531,7 @@ }, "require-dev": { "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "0.12.63", + "phpstan/phpstan": "0.12.71", "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", @@ -549,7 +549,7 @@ "issues": "https://github.com/pmmp/LogPthreads/issues", "source": "https://github.com/pmmp/LogPthreads/tree/master" }, - "time": "2021-01-06T21:23:23+00:00" + "time": "2021-02-04T15:41:29+00:00" }, { "name": "pocketmine/math", diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 1a61846ff9..6ac4a2b95b 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -18,6 +18,7 @@ includes: rules: - pocketmine\phpstan\rules\DisallowEnumComparisonRule +# - pocketmine\phpstan\rules\ThreadedSupportedTypesRule parameters: level: 8 diff --git a/src/PocketMine.php b/src/PocketMine.php index 15ec49cdde..22357648e8 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -272,8 +272,7 @@ namespace pocketmine { } }while(false); - $logger->shutdown(); - $logger->join(); + $logger->shutdownLogWriterThread(); echo Terminal::$FORMAT_RESET . PHP_EOL; diff --git a/src/entity/EntitySizeInfo.php b/src/entity/EntitySizeInfo.php index 1456cc2fbe..91cf7c5f7b 100644 --- a/src/entity/EntitySizeInfo.php +++ b/src/entity/EntitySizeInfo.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\entity; +use function min; + final class EntitySizeInfo{ /** @var float */ private $height; diff --git a/src/item/Banner.php b/src/item/Banner.php index 744c6fb890..d3c440bee6 100644 --- a/src/item/Banner.php +++ b/src/item/Banner.php @@ -30,6 +30,7 @@ use pocketmine\block\utils\DyeColor; use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; +use function count; class Banner extends ItemBlockWallOrFloor{ public const TAG_PATTERNS = TileBanner::TAG_PATTERNS; diff --git a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php index d92077cf1b..7c0f5a37a7 100644 --- a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php +++ b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php @@ -30,9 +30,9 @@ use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\protocol\types\MapDecoration; use pocketmine\network\mcpe\protocol\types\MapTrackedObject; -use function count; -#ifndef COMPILE use pocketmine\utils\Binary; +#ifndef COMPILE +use function count; #endif class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPacket{ diff --git a/src/utils/EnumTrait.php b/src/utils/EnumTrait.php index dea079738a..163c0b0b26 100644 --- a/src/utils/EnumTrait.php +++ b/src/utils/EnumTrait.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\utils; -use function getmypid; use function preg_match; trait EnumTrait{ diff --git a/src/utils/MainLogger.php b/src/utils/MainLogger.php index 3757d65b87..886c876775 100644 --- a/src/utils/MainLogger.php +++ b/src/utils/MainLogger.php @@ -27,11 +27,7 @@ use LogLevel; use pocketmine\errorhandler\ErrorTypeToStringMap; use pocketmine\thread\Thread; use pocketmine\thread\Worker; -use function fclose; -use function fopen; -use function fwrite; use function get_class; -use function is_resource; use function preg_replace; use function sprintf; use function touch; @@ -43,14 +39,8 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ /** @var string */ protected $logFile; - /** @var \Threaded */ - protected $logStream; - /** @var bool */ - protected $shutdown = false; /** @var bool */ protected $logDebug; - /** @var bool */ - private $syncFlush = false; /** @var string */ private $format = TextFormat::AQUA . "[%s] " . TextFormat::RESET . "%s[%s/%s]: %s" . TextFormat::RESET; @@ -61,6 +51,9 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ /** @var string */ private $timezone; + /** @var MainLoggerThread */ + private $logWriterThread; + /** * @throws \RuntimeException */ @@ -69,13 +62,13 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ touch($logFile); $this->logFile = $logFile; $this->logDebug = $logDebug; - $this->logStream = new \Threaded; //Child threads may not inherit command line arguments, so if there's an override it needs to be recorded here $this->mainThreadHasFormattingCodes = Terminal::hasFormattingCodes(); $this->timezone = Timezone::get(); - $this->start(PTHREADS_INHERIT_NONE); + $this->logWriterThread = new MainLoggerThread($this->logFile); + $this->logWriterThread->start(PTHREADS_INHERIT_NONE); } /** @@ -218,9 +211,12 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ $this->synchronized($c); } - public function shutdown() : void{ - $this->shutdown = true; - $this->notify(); + public function shutdownLogWriterThread() : void{ + if(\Thread::getCurrentThreadId() === $this->logWriterThread->getCreatorId()){ + $this->logWriterThread->shutdown(); + }else{ + throw new \LogicException("Only the creator thread can shutdown the logger thread"); + } } /** @@ -254,54 +250,17 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ $attachment->call($level, $message); } - $this->logStream[] = $time->format("Y-m-d") . " " . TextFormat::clean($message) . PHP_EOL; - $this->notify(); + $this->logWriterThread->write($time->format("Y-m-d") . " " . TextFormat::clean($message) . PHP_EOL); }); } public function syncFlushBuffer() : void{ - $this->syncFlush = true; - $this->synchronized(function() : void{ - $this->notify(); //write immediately - - while($this->syncFlush){ - $this->wait(); //block until it's all been written to disk - } - }); + $this->logWriterThread->syncFlushBuffer(); } - /** - * @param resource $logResource - */ - private function writeLogStream($logResource) : void{ - while($this->logStream->count() > 0){ - $chunk = $this->logStream->shift(); - fwrite($logResource, $chunk); + public function __destruct(){ + if(!$this->logWriterThread->isJoined() && \Thread::getCurrentThreadId() === $this->logWriterThread->getCreatorId()){ + $this->shutdownLogWriterThread(); } - - $this->synchronized(function() : void{ - if($this->syncFlush){ - $this->syncFlush = false; - $this->notify(); //if this was due to a sync flush, tell the caller to stop waiting - } - }); - } - - public function run() : void{ - $logResource = fopen($this->logFile, "ab"); - if(!is_resource($logResource)){ - throw new \RuntimeException("Couldn't open log file"); - } - - while(!$this->shutdown){ - $this->writeLogStream($logResource); - $this->synchronized(function() : void{ - $this->wait(); - }); - } - - $this->writeLogStream($logResource); - - fclose($logResource); } } diff --git a/src/utils/MainLoggerThread.php b/src/utils/MainLoggerThread.php new file mode 100644 index 0000000000..49e4f3e136 --- /dev/null +++ b/src/utils/MainLoggerThread.php @@ -0,0 +1,101 @@ +buffer = new \Threaded(); + $this->logFile = $logFile; + } + + public function write(string $line) : void{ + $this->synchronized(function() use ($line) : void{ + $this->buffer[] = $line; + $this->notify(); + }); + } + + public function syncFlushBuffer() : void{ + $this->syncFlush = true; + $this->synchronized(function() : void{ + $this->notify(); //write immediately + + while($this->syncFlush){ + $this->wait(); //block until it's all been written to disk + } + }); + } + + public function shutdown() : void{ + $this->shutdown = true; + $this->notify(); + $this->join(); + } + + /** + * @param resource $logResource + */ + private function writeLogStream($logResource) : void{ + while($this->buffer->count() > 0){ + $chunk = $this->buffer->shift(); + fwrite($logResource, $chunk); + } + + $this->synchronized(function() : void{ + if($this->syncFlush){ + $this->syncFlush = false; + $this->notify(); //if this was due to a sync flush, tell the caller to stop waiting + } + }); + } + + public function run() : void{ + $logResource = fopen($this->logFile, "ab"); + if(!is_resource($logResource)){ + throw new \RuntimeException("Couldn't open log file"); + } + + while(!$this->shutdown){ + $this->writeLogStream($logResource); + $this->synchronized(function() : void{ + $this->wait(); + }); + } + + $this->writeLogStream($logResource); + + fclose($logResource); + } +} diff --git a/tests/phpstan/bootstrap.php b/tests/phpstan/bootstrap.php index ba8ccd3fc4..d6cbdd166a 100644 --- a/tests/phpstan/bootstrap.php +++ b/tests/phpstan/bootstrap.php @@ -21,13 +21,13 @@ declare(strict_types=1); -if(!defined('LEVELDB_ZLIB_RAW_COMPRESSION')){ +if(!\defined('LEVELDB_ZLIB_RAW_COMPRESSION')){ //leveldb might not be loaded - define('LEVELDB_ZLIB_RAW_COMPRESSION', 4); + \define('LEVELDB_ZLIB_RAW_COMPRESSION', 4); } -if(!extension_loaded('libdeflate')){ +if(!\extension_loaded('libdeflate')){ function libdeflate_deflate_compress(string $data, int $level = 6) : string{} } //TODO: these need to be defined properly or removed -define('pocketmine\COMPOSER_AUTOLOADER_PATH', dirname(__DIR__, 2) . '/vendor/autoload.php'); +\define('pocketmine\COMPOSER_AUTOLOADER_PATH', \dirname(__DIR__, 2) . '/vendor/autoload.php'); diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index 5ffcc29133..63009a2d1f 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -283,7 +283,7 @@ parameters: - message: "#^Parameter \\#2 \\$str of function fwrite expects string, mixed given\\.$#" count: 1 - path: ../../../src/utils/MainLogger.php + path: ../../../src/utils/MainLoggerThread.php - message: "#^Cannot access offset 'status' on mixed\\.$#" diff --git a/tests/phpunit/block/regenerate_consistency_check.php b/tests/phpunit/block/regenerate_consistency_check.php index aac5194c9c..d1ff6c770f 100644 --- a/tests/phpunit/block/regenerate_consistency_check.php +++ b/tests/phpunit/block/regenerate_consistency_check.php @@ -21,14 +21,14 @@ declare(strict_types=1); -require dirname(__DIR__, 3) . '/vendor/autoload.php'; +require \dirname(__DIR__, 3) . '/vendor/autoload.php'; /* This script needs to be re-run after any intentional blockfactory change (adding or removing a block state). */ $factory = new \pocketmine\block\BlockFactory(); -$old = json_decode(file_get_contents(__DIR__ . '/block_factory_consistency_check.json'), true); -$new = array_map( +$old = \json_decode(\file_get_contents(__DIR__ . '/block_factory_consistency_check.json'), true); +$new = \array_map( function(\pocketmine\block\Block $block) : string{ return $block->getName(); }, @@ -46,6 +46,6 @@ foreach($new as $k => $name){ echo "Name changed (" . ($k >> 4) . ":" . ($k & 0xf) . "): " . $old[$k] . " -> " . $name . "\n"; } } -file_put_contents(__DIR__ . '/block_factory_consistency_check.json', json_encode( +\file_put_contents(__DIR__ . '/block_factory_consistency_check.json', \json_encode( $new )); diff --git a/tests/phpunit/scheduler/AsyncPoolTest.php b/tests/phpunit/scheduler/AsyncPoolTest.php index ab2bc5a29d..810e475e9e 100644 --- a/tests/phpunit/scheduler/AsyncPoolTest.php +++ b/tests/phpunit/scheduler/AsyncPoolTest.php @@ -50,8 +50,7 @@ class AsyncPoolTest extends TestCase{ public function tearDown() : void{ $this->pool->shutdown(); - $this->mainLogger->shutdown(); - $this->mainLogger->join(); + $this->mainLogger->shutdownLogWriterThread(); } public function testTaskLeak() : void{ From 6d64fb9af83e9beb710e783bee0c1fe2905cfe17 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Feb 2021 16:51:02 +0000 Subject: [PATCH 2267/3224] MainLogger: remove obsolete logFile field --- src/utils/MainLogger.php | 8 +------- src/utils/MainLoggerThread.php | 2 ++ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/utils/MainLogger.php b/src/utils/MainLogger.php index 886c876775..010cffcdcd 100644 --- a/src/utils/MainLogger.php +++ b/src/utils/MainLogger.php @@ -30,15 +30,11 @@ use pocketmine\thread\Worker; use function get_class; use function preg_replace; use function sprintf; -use function touch; use function trim; use const PHP_EOL; use const PTHREADS_INHERIT_NONE; class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ - - /** @var string */ - protected $logFile; /** @var bool */ protected $logDebug; @@ -59,15 +55,13 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ */ public function __construct(string $logFile, bool $logDebug = false){ parent::__construct(); - touch($logFile); - $this->logFile = $logFile; $this->logDebug = $logDebug; //Child threads may not inherit command line arguments, so if there's an override it needs to be recorded here $this->mainThreadHasFormattingCodes = Terminal::hasFormattingCodes(); $this->timezone = Timezone::get(); - $this->logWriterThread = new MainLoggerThread($this->logFile); + $this->logWriterThread = new MainLoggerThread($logFile); $this->logWriterThread->start(PTHREADS_INHERIT_NONE); } diff --git a/src/utils/MainLoggerThread.php b/src/utils/MainLoggerThread.php index 8a705933b3..b99a105819 100644 --- a/src/utils/MainLoggerThread.php +++ b/src/utils/MainLoggerThread.php @@ -27,6 +27,7 @@ use function fclose; use function fopen; use function fwrite; use function is_resource; +use function touch; final class MainLoggerThread extends \Thread{ @@ -37,6 +38,7 @@ final class MainLoggerThread extends \Thread{ public function __construct(string $logFile){ $this->buffer = new \Threaded(); + touch($logFile); $this->logFile = $logFile; } From 709b4154d75742cc15a84c5b9b18ca77d9b5953c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Feb 2021 19:16:22 +0000 Subject: [PATCH 2268/3224] MainLogger: Require useFormattingCodes as a constructor parameter this avoids needing to call Terminal::init() before starting a MainLogger. Since it inits the formatting codes anyway when log messages are first recorded, it shouldn't be necessary to pre-initialize it. --- src/PocketMine.php | 2 +- src/utils/MainLogger.php | 9 ++++----- tests/phpunit/scheduler/AsyncPoolTest.php | 3 +-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index 22357648e8..daab079eea 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -237,7 +237,7 @@ namespace pocketmine { Terminal::init(); } - $logger = new MainLogger($dataPath . "server.log"); + $logger = new MainLogger($dataPath . "server.log", Terminal::hasFormattingCodes()); \GlobalLogger::set($logger); emit_performance_warnings($logger); diff --git a/src/utils/MainLogger.php b/src/utils/MainLogger.php index 010cffcdcd..ee30da4b4a 100644 --- a/src/utils/MainLogger.php +++ b/src/utils/MainLogger.php @@ -42,7 +42,7 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ private $format = TextFormat::AQUA . "[%s] " . TextFormat::RESET . "%s[%s/%s]: %s" . TextFormat::RESET; /** @var bool */ - private $mainThreadHasFormattingCodes = false; + private $useFormattingCodes = false; /** @var string */ private $timezone; @@ -53,12 +53,11 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ /** * @throws \RuntimeException */ - public function __construct(string $logFile, bool $logDebug = false){ + public function __construct(string $logFile, bool $useFormattingCodes, bool $logDebug = false){ parent::__construct(); $this->logDebug = $logDebug; - //Child threads may not inherit command line arguments, so if there's an override it needs to be recorded here - $this->mainThreadHasFormattingCodes = Terminal::hasFormattingCodes(); + $this->useFormattingCodes = $useFormattingCodes; $this->timezone = Timezone::get(); $this->logWriterThread = new MainLoggerThread($logFile); @@ -234,7 +233,7 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ $message = sprintf($this->format, $time->format("H:i:s.v"), $color, $threadName, $prefix, TextFormat::clean($message, false)); if(!Terminal::isInit()){ - Terminal::init($this->mainThreadHasFormattingCodes); //lazy-init colour codes because we don't know if they've been registered on this thread + Terminal::init($this->useFormattingCodes); //lazy-init colour codes because we don't know if they've been registered on this thread } $this->synchronized(function() use ($message, $level, $time) : void{ diff --git a/tests/phpunit/scheduler/AsyncPoolTest.php b/tests/phpunit/scheduler/AsyncPoolTest.php index 810e475e9e..98cd180b71 100644 --- a/tests/phpunit/scheduler/AsyncPoolTest.php +++ b/tests/phpunit/scheduler/AsyncPoolTest.php @@ -42,9 +42,8 @@ class AsyncPoolTest extends TestCase{ private $mainLogger; public function setUp() : void{ - Terminal::init(); @define('pocketmine\\COMPOSER_AUTOLOADER_PATH', dirname(__DIR__, 3) . '/vendor/autoload.php'); - $this->mainLogger = new MainLogger(tempnam(sys_get_temp_dir(), "pmlog")); + $this->mainLogger = new MainLogger(tempnam(sys_get_temp_dir(), "pmlog"), false); $this->pool = new AsyncPool(2, 1024, new \BaseClassLoader(), $this->mainLogger, new SleeperHandler()); } From 27b1951df74954334e00d47c17c2392637f24ce3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Feb 2021 20:55:50 +0000 Subject: [PATCH 2269/3224] MainLogger: accept main thread name as a constructor parameter --- src/PocketMine.php | 2 +- src/utils/MainLogger.php | 7 +++++-- tests/phpunit/scheduler/AsyncPoolTest.php | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index daab079eea..160204d355 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -237,7 +237,7 @@ namespace pocketmine { Terminal::init(); } - $logger = new MainLogger($dataPath . "server.log", Terminal::hasFormattingCodes()); + $logger = new MainLogger($dataPath . "server.log", Terminal::hasFormattingCodes(), "Server"); \GlobalLogger::set($logger); emit_performance_warnings($logger); diff --git a/src/utils/MainLogger.php b/src/utils/MainLogger.php index ee30da4b4a..f5637dbe9b 100644 --- a/src/utils/MainLogger.php +++ b/src/utils/MainLogger.php @@ -44,6 +44,8 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ /** @var bool */ private $useFormattingCodes = false; + private string $mainThreadName; + /** @var string */ private $timezone; @@ -53,11 +55,12 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ /** * @throws \RuntimeException */ - public function __construct(string $logFile, bool $useFormattingCodes, bool $logDebug = false){ + public function __construct(string $logFile, bool $useFormattingCodes, string $mainThreadName, bool $logDebug = false){ parent::__construct(); $this->logDebug = $logDebug; $this->useFormattingCodes = $useFormattingCodes; + $this->mainThreadName = $mainThreadName; $this->timezone = Timezone::get(); $this->logWriterThread = new MainLoggerThread($logFile); @@ -223,7 +226,7 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ $thread = \Thread::getCurrentThread(); if($thread === null){ - $threadName = "Server thread"; + $threadName = $this->mainThreadName . " thread"; }elseif($thread instanceof Thread or $thread instanceof Worker){ $threadName = $thread->getThreadName() . " thread"; }else{ diff --git a/tests/phpunit/scheduler/AsyncPoolTest.php b/tests/phpunit/scheduler/AsyncPoolTest.php index 98cd180b71..9cba443a0c 100644 --- a/tests/phpunit/scheduler/AsyncPoolTest.php +++ b/tests/phpunit/scheduler/AsyncPoolTest.php @@ -43,7 +43,7 @@ class AsyncPoolTest extends TestCase{ public function setUp() : void{ @define('pocketmine\\COMPOSER_AUTOLOADER_PATH', dirname(__DIR__, 3) . '/vendor/autoload.php'); - $this->mainLogger = new MainLogger(tempnam(sys_get_temp_dir(), "pmlog"), false); + $this->mainLogger = new MainLogger(tempnam(sys_get_temp_dir(), "pmlog"), false, "Main"); $this->pool = new AsyncPool(2, 1024, new \BaseClassLoader(), $this->mainLogger, new SleeperHandler()); } From 54d9342ed9641167a94d27a99d52a32bb58dc360 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Feb 2021 21:43:53 +0000 Subject: [PATCH 2270/3224] AsyncPool: Always collect workers, even if the task queue is empty because of the way async tasks are processed, we might collect results from a task before it's able to be collected by collect(). Therefore, the queue might be empty, even though there are still tasks to be collected. --- src/scheduler/AsyncPool.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/scheduler/AsyncPool.php b/src/scheduler/AsyncPool.php index 9eb7126efa..bf5ecbbf75 100644 --- a/src/scheduler/AsyncPool.php +++ b/src/scheduler/AsyncPool.php @@ -245,14 +245,12 @@ class AsyncPool{ throw new \InvalidArgumentException("No such worker $worker"); } $queue = $this->taskQueues[$worker]; - $doGC = false; $more = false; while(!$queue->isEmpty()){ /** @var AsyncTask $task */ $task = $queue->bottom(); $task->checkProgressUpdates(); if($task->isFinished()){ //make sure the task actually executed before trying to collect - $doGC = true; $queue->dequeue(); if($task->isCrashed()){ @@ -276,9 +274,7 @@ class AsyncPool{ break; //current task is still running, skip to next worker } } - if($doGC){ - $this->workers[$worker]->collect(); - } + $this->workers[$worker]->collect(); return $more; } From 169650dc5ba6ec6a3f9bf465242ca8d1059082bb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Feb 2021 21:50:06 +0000 Subject: [PATCH 2271/3224] MainLogger: accept timezone as a constructor parameter this makes it easier to unit-test, as well as making it independent of Timezone. --- src/PocketMine.php | 2 +- src/utils/MainLogger.php | 4 ++-- tests/phpunit/scheduler/AsyncPoolTest.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index 160204d355..5740b20cf1 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -237,7 +237,7 @@ namespace pocketmine { Terminal::init(); } - $logger = new MainLogger($dataPath . "server.log", Terminal::hasFormattingCodes(), "Server"); + $logger = new MainLogger($dataPath . "server.log", Terminal::hasFormattingCodes(), "Server", new \DateTimeZone(Timezone::get())); \GlobalLogger::set($logger); emit_performance_warnings($logger); diff --git a/src/utils/MainLogger.php b/src/utils/MainLogger.php index f5637dbe9b..f2c1ae1605 100644 --- a/src/utils/MainLogger.php +++ b/src/utils/MainLogger.php @@ -55,13 +55,13 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ /** * @throws \RuntimeException */ - public function __construct(string $logFile, bool $useFormattingCodes, string $mainThreadName, bool $logDebug = false){ + public function __construct(string $logFile, bool $useFormattingCodes, string $mainThreadName, \DateTimeZone $timezone, bool $logDebug = false){ parent::__construct(); $this->logDebug = $logDebug; $this->useFormattingCodes = $useFormattingCodes; $this->mainThreadName = $mainThreadName; - $this->timezone = Timezone::get(); + $this->timezone = $timezone->getName(); $this->logWriterThread = new MainLoggerThread($logFile); $this->logWriterThread->start(PTHREADS_INHERIT_NONE); diff --git a/tests/phpunit/scheduler/AsyncPoolTest.php b/tests/phpunit/scheduler/AsyncPoolTest.php index 9cba443a0c..a152c3ec37 100644 --- a/tests/phpunit/scheduler/AsyncPoolTest.php +++ b/tests/phpunit/scheduler/AsyncPoolTest.php @@ -43,7 +43,7 @@ class AsyncPoolTest extends TestCase{ public function setUp() : void{ @define('pocketmine\\COMPOSER_AUTOLOADER_PATH', dirname(__DIR__, 3) . '/vendor/autoload.php'); - $this->mainLogger = new MainLogger(tempnam(sys_get_temp_dir(), "pmlog"), false, "Main"); + $this->mainLogger = new MainLogger(tempnam(sys_get_temp_dir(), "pmlog"), false, "Main", new \DateTimeZone('UTC')); $this->pool = new AsyncPool(2, 1024, new \BaseClassLoader(), $this->mainLogger, new SleeperHandler()); } From 6ccfe21d576961b4c46c50a2457db7f4588c0827 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Feb 2021 23:10:13 +0000 Subject: [PATCH 2272/3224] Block: improved accuracy of isFullCube() --- src/block/Block.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/Block.php b/src/block/Block.php index 4b82a0cb9e..d54f6ef2b8 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -585,7 +585,7 @@ class Block{ public function isFullCube() : bool{ $bb = $this->getCollisionBoxes(); - return count($bb) === 1 and $bb[0]->getAverageEdgeLength() >= 1; //TODO: average length 1 != cube + return count($bb) === 1 and $bb[0]->getAverageEdgeLength() >= 1 and $bb[0]->isCube(); } public function calculateIntercept(Vector3 $pos1, Vector3 $pos2) : ?RayTraceResult{ From 4fc3bc53f7fa171eb981dd3c480ee959e95b96ba Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 5 Feb 2021 21:25:34 +0000 Subject: [PATCH 2273/3224] Clean up hierarchy of rails detector rail has fundamentally different functionality than activator and powered rails, so it's misleading to present the same APIs for both. detector rail's 'powered' state is better referred to as 'activated', since it means the detector rail is actually _producing_ power, and not _receiving_ power. --- src/block/ActivatorRail.php | 5 ++- src/block/DetectorRail.php | 24 ++++++++++++- src/block/PoweredRail.php | 5 ++- src/block/utils/PoweredByRedstoneTrait.php | 36 +++++++++++++++++++ .../RailPoweredByRedstoneTrait.php} | 8 ++--- 5 files changed, 71 insertions(+), 7 deletions(-) create mode 100644 src/block/utils/PoweredByRedstoneTrait.php rename src/block/{RedstoneRail.php => utils/RailPoweredByRedstoneTrait.php} (90%) diff --git a/src/block/ActivatorRail.php b/src/block/ActivatorRail.php index 063cd6d25c..84538db7b6 100644 --- a/src/block/ActivatorRail.php +++ b/src/block/ActivatorRail.php @@ -23,7 +23,10 @@ declare(strict_types=1); namespace pocketmine\block; -class ActivatorRail extends RedstoneRail{ +use pocketmine\block\utils\RailPoweredByRedstoneTrait; + +class ActivatorRail extends BaseRail{ + use RailPoweredByRedstoneTrait; //TODO } diff --git a/src/block/DetectorRail.php b/src/block/DetectorRail.php index 91f29bcb5e..2ddc4a271a 100644 --- a/src/block/DetectorRail.php +++ b/src/block/DetectorRail.php @@ -23,7 +23,29 @@ declare(strict_types=1); namespace pocketmine\block; -class DetectorRail extends RedstoneRail{ +class DetectorRail extends BaseRail{ + protected bool $activated = false; + + public function isActivated() : bool{ return $this->activated; } + + /** @return $this */ + public function setActivated(bool $activated) : self{ + $this->activated = $activated; + return $this; + } + + protected function writeStateToMeta() : int{ + return parent::writeStateToMeta() | ($this->activated ? BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED : 0); + } + + public function readStateFromData(int $id, int $stateMeta) : void{ + parent::readStateFromData($id, $stateMeta); + $this->activated = ($stateMeta & BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED) !== 0; + } + + protected function getConnectionsFromMeta(int $meta) : ?array{ + return self::CONNECTIONS[$meta & ~BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED] ?? null; + } //TODO } diff --git a/src/block/PoweredRail.php b/src/block/PoweredRail.php index 0a66be5be4..320227619d 100644 --- a/src/block/PoweredRail.php +++ b/src/block/PoweredRail.php @@ -23,5 +23,8 @@ declare(strict_types=1); namespace pocketmine\block; -class PoweredRail extends RedstoneRail{ +use pocketmine\block\utils\RailPoweredByRedstoneTrait; + +class PoweredRail extends BaseRail{ + use RailPoweredByRedstoneTrait; } diff --git a/src/block/utils/PoweredByRedstoneTrait.php b/src/block/utils/PoweredByRedstoneTrait.php new file mode 100644 index 0000000000..683437a4f9 --- /dev/null +++ b/src/block/utils/PoweredByRedstoneTrait.php @@ -0,0 +1,36 @@ +powered; } + + /** @return $this */ + public function setPowered(bool $powered) : self{ + $this->powered = $powered; + return $this; + } +} diff --git a/src/block/RedstoneRail.php b/src/block/utils/RailPoweredByRedstoneTrait.php similarity index 90% rename from src/block/RedstoneRail.php rename to src/block/utils/RailPoweredByRedstoneTrait.php index a9c1e5315b..0314c4bec7 100644 --- a/src/block/RedstoneRail.php +++ b/src/block/utils/RailPoweredByRedstoneTrait.php @@ -21,12 +21,12 @@ declare(strict_types=1); -namespace pocketmine\block; +namespace pocketmine\block\utils; -abstract class RedstoneRail extends BaseRail{ +use pocketmine\block\BlockLegacyMetadata; - /** @var bool */ - protected $powered = false; +trait RailPoweredByRedstoneTrait{ + use PoweredByRedstoneTrait; protected function writeStateToMeta() : int{ return parent::writeStateToMeta() | ($this->powered ? BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED : 0); From 02b0036cbe34a342901cff2882f4818080a8dbe5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Feb 2021 17:47:29 +0000 Subject: [PATCH 2274/3224] DaylightSensor: refactor power -> signalStrength --- src/block/DaylightSensor.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/block/DaylightSensor.php b/src/block/DaylightSensor.php index 5892bf0abc..4c7a404837 100644 --- a/src/block/DaylightSensor.php +++ b/src/block/DaylightSensor.php @@ -39,7 +39,7 @@ class DaylightSensor extends Transparent{ protected $idInfo; /** @var int */ - protected $power = 0; + protected $signalStrength = 0; /** @var bool */ protected $inverted = false; @@ -53,11 +53,11 @@ class DaylightSensor extends Transparent{ } protected function writeStateToMeta() : int{ - return $this->power; + return $this->signalStrength; } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->power = BlockDataSerializer::readBoundedInt("power", $stateMeta, 0, 15); + $this->signalStrength = BlockDataSerializer::readBoundedInt("signalStrength", $stateMeta, 0, 15); $this->inverted = $id === $this->idInfo->getSecondId(); } @@ -90,21 +90,21 @@ class DaylightSensor extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->inverted = !$this->inverted; - $this->power = $this->recalculatePower(); + $this->signalStrength = $this->recalculateSignalStrength(); $this->pos->getWorld()->setBlock($this->pos, $this); return true; } public function onScheduledUpdate() : void{ - $newPower = $this->recalculatePower(); - if($this->power !== $newPower){ - $this->power = $newPower; + $signalStrength = $this->recalculateSignalStrength(); + if($this->signalStrength !== $signalStrength){ + $this->signalStrength = $signalStrength; $this->pos->getWorld()->setBlock($this->pos, $this); } $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 20); } - private function recalculatePower() : int{ + private function recalculateSignalStrength() : int{ $lightLevel = $this->pos->getWorld()->getRealBlockSkyLightAt($this->pos->x, $this->pos->y, $this->pos->z); if($this->inverted){ return 15 - $lightLevel; From 48ef8771cd25e5dcbe04e19090d3b8324b7246b6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Feb 2021 18:33:14 +0000 Subject: [PATCH 2275/3224] Added AnalogRedstoneSignalEmitterTrait --- src/block/DaylightSensor.php | 6 +-- src/block/RedstoneComparator.php | 14 +------ src/block/RedstoneWire.php | 9 ++--- src/block/WeightedPressurePlate.php | 9 ++--- .../AnalogRedstoneSignalEmitterTrait.php | 39 +++++++++++++++++++ 5 files changed, 52 insertions(+), 25 deletions(-) create mode 100644 src/block/utils/AnalogRedstoneSignalEmitterTrait.php diff --git a/src/block/DaylightSensor.php b/src/block/DaylightSensor.php index 4c7a404837..594060bbb1 100644 --- a/src/block/DaylightSensor.php +++ b/src/block/DaylightSensor.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\AnalogRedstoneSignalEmitterTrait; use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; @@ -35,12 +36,11 @@ use function round; use const M_PI; class DaylightSensor extends Transparent{ + use AnalogRedstoneSignalEmitterTrait; + /** @var BlockIdentifierFlattened */ protected $idInfo; - /** @var int */ - protected $signalStrength = 0; - /** @var bool */ protected $inverted = false; diff --git a/src/block/RedstoneComparator.php b/src/block/RedstoneComparator.php index f640a7c585..083046dc31 100644 --- a/src/block/RedstoneComparator.php +++ b/src/block/RedstoneComparator.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\tile\Comparator; +use pocketmine\block\utils\AnalogRedstoneSignalEmitterTrait; use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; @@ -36,6 +37,7 @@ use function assert; class RedstoneComparator extends Flowable{ use HorizontalFacingTrait; + use AnalogRedstoneSignalEmitterTrait; /** @var BlockIdentifierFlattened */ protected $idInfo; @@ -44,8 +46,6 @@ class RedstoneComparator extends Flowable{ protected $isSubtractMode = false; /** @var bool */ protected $powered = false; - /** @var int */ - protected $signalStrength = 0; public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); @@ -106,16 +106,6 @@ class RedstoneComparator extends Flowable{ return $this; } - public function getSignalStrength() : int{ - return $this->signalStrength; - } - - /** @return $this */ - public function setSignalStrength(int $signalStrength) : self{ - $this->signalStrength = $signalStrength; - return $this; - } - /** * @return AxisAlignedBB[] */ diff --git a/src/block/RedstoneWire.php b/src/block/RedstoneWire.php index a59fe563b1..ebc0c221e3 100644 --- a/src/block/RedstoneWire.php +++ b/src/block/RedstoneWire.php @@ -23,23 +23,22 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\AnalogRedstoneSignalEmitterTrait; use pocketmine\block\utils\BlockDataSerializer; class RedstoneWire extends Flowable{ - - /** @var int */ - protected $power = 0; + use AnalogRedstoneSignalEmitterTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->power = BlockDataSerializer::readBoundedInt("power", $stateMeta, 0, 15); + $this->signalStrength = BlockDataSerializer::readBoundedInt("signalStrength", $stateMeta, 0, 15); } protected function writeStateToMeta() : int{ - return $this->power; + return $this->signalStrength; } public function getStateBitmask() : int{ diff --git a/src/block/WeightedPressurePlate.php b/src/block/WeightedPressurePlate.php index a959bf9adc..fa613dac7f 100644 --- a/src/block/WeightedPressurePlate.php +++ b/src/block/WeightedPressurePlate.php @@ -23,19 +23,18 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\AnalogRedstoneSignalEmitterTrait; use pocketmine\block\utils\BlockDataSerializer; abstract class WeightedPressurePlate extends PressurePlate{ - - /** @var int */ - protected $power = 0; + use AnalogRedstoneSignalEmitterTrait; protected function writeStateToMeta() : int{ - return $this->power; + return $this->signalStrength; } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->power = BlockDataSerializer::readBoundedInt("power", $stateMeta, 0, 15); + $this->signalStrength = BlockDataSerializer::readBoundedInt("signalStrength", $stateMeta, 0, 15); } public function getStateBitmask() : int{ diff --git a/src/block/utils/AnalogRedstoneSignalEmitterTrait.php b/src/block/utils/AnalogRedstoneSignalEmitterTrait.php new file mode 100644 index 0000000000..2d5609a989 --- /dev/null +++ b/src/block/utils/AnalogRedstoneSignalEmitterTrait.php @@ -0,0 +1,39 @@ +signalStrength; } + + /** @return $this */ + public function setOutputSignalStrength(int $signalStrength) : self{ + if($signalStrength < 0 || $signalStrength > 15){ + throw new \InvalidArgumentException("Signal strength must be in range 0-15"); + } + $this->signalStrength = $signalStrength; + return $this; + } +} From 5be03c319623318661517e685c2a214e397eaaab Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Feb 2021 18:43:33 +0000 Subject: [PATCH 2276/3224] Make more use of PoweredByRedstoneTrait --- src/block/Door.php | 4 ++-- src/block/Hopper.php | 4 ++-- src/block/RedstoneComparator.php | 14 ++------------ src/block/RedstoneRepeater.php | 16 ++-------------- 4 files changed, 8 insertions(+), 30 deletions(-) diff --git a/src/block/Door.php b/src/block/Door.php index ee0bc63bb1..312c404a0a 100644 --- a/src/block/Door.php +++ b/src/block/Door.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\HorizontalFacingTrait; +use pocketmine\block\utils\PoweredByRedstoneTrait; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -35,6 +36,7 @@ use pocketmine\world\sound\DoorSound; class Door extends Transparent{ use HorizontalFacingTrait; + use PoweredByRedstoneTrait; /** @var bool */ protected $top = false; @@ -43,8 +45,6 @@ class Door extends Transparent{ /** @var bool */ protected $open = false; - /** @var bool */ - protected $powered = false; protected function writeStateToMeta() : int{ if($this->top){ diff --git a/src/block/Hopper.php b/src/block/Hopper.php index be6a4b6de2..e07f800ddb 100644 --- a/src/block/Hopper.php +++ b/src/block/Hopper.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\block\tile\Hopper as TileHopper; use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\InvalidBlockStateException; +use pocketmine\block\utils\PoweredByRedstoneTrait; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -34,11 +35,10 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Hopper extends Transparent{ + use PoweredByRedstoneTrait; /** @var int */ private $facing = Facing::DOWN; - /** @var bool */ - private $powered = false; public function readStateFromData(int $id, int $stateMeta) : void{ $facing = BlockDataSerializer::readFacing($stateMeta & 0x07); diff --git a/src/block/RedstoneComparator.php b/src/block/RedstoneComparator.php index 083046dc31..883a8152e2 100644 --- a/src/block/RedstoneComparator.php +++ b/src/block/RedstoneComparator.php @@ -27,6 +27,7 @@ use pocketmine\block\tile\Comparator; use pocketmine\block\utils\AnalogRedstoneSignalEmitterTrait; use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\HorizontalFacingTrait; +use pocketmine\block\utils\PoweredByRedstoneTrait; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -38,14 +39,13 @@ use function assert; class RedstoneComparator extends Flowable{ use HorizontalFacingTrait; use AnalogRedstoneSignalEmitterTrait; + use PoweredByRedstoneTrait; /** @var BlockIdentifierFlattened */ protected $idInfo; /** @var bool */ protected $isSubtractMode = false; - /** @var bool */ - protected $powered = false; public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); @@ -96,16 +96,6 @@ class RedstoneComparator extends Flowable{ return $this; } - public function isPowered() : bool{ - return $this->powered; - } - - /** @return $this */ - public function setPowered(bool $powered) : self{ - $this->powered = $powered; - return $this; - } - /** * @return AxisAlignedBB[] */ diff --git a/src/block/RedstoneRepeater.php b/src/block/RedstoneRepeater.php index f777ad41b0..7553dc560b 100644 --- a/src/block/RedstoneRepeater.php +++ b/src/block/RedstoneRepeater.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\HorizontalFacingTrait; +use pocketmine\block\utils\PoweredByRedstoneTrait; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -34,12 +35,11 @@ use pocketmine\world\BlockTransaction; class RedstoneRepeater extends Flowable{ use HorizontalFacingTrait; + use PoweredByRedstoneTrait; /** @var BlockIdentifierFlattened */ protected $idInfo; - /** @var bool */ - protected $powered = false; /** @var int */ protected $delay = 1; @@ -72,18 +72,6 @@ class RedstoneRepeater extends Flowable{ return [AxisAlignedBB::one()->trim(Facing::UP, 7 / 8)]; } - public function isPowered() : bool{ - return $this->powered; - } - - /** - * @return $this - */ - public function setPowered(bool $powered = true) : self{ - $this->powered = $powered; - return $this; - } - public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$blockReplace->getSide(Facing::DOWN)->isTransparent()){ if($player !== null){ From 233616aa6aa9a3393b4edaaadccc50bbd759bfb1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Feb 2021 19:02:13 +0000 Subject: [PATCH 2277/3224] RedstoneLamp now uses PoweredByRedstoneTrait --- src/block/RedstoneLamp.php | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/src/block/RedstoneLamp.php b/src/block/RedstoneLamp.php index c09f73b45b..0d538167d7 100644 --- a/src/block/RedstoneLamp.php +++ b/src/block/RedstoneLamp.php @@ -23,39 +23,27 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\PoweredByRedstoneTrait; + class RedstoneLamp extends Opaque{ + use PoweredByRedstoneTrait; /** @var BlockIdentifierFlattened */ protected $idInfo; - /** @var bool */ - protected $lit = false; - public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.3)); } public function getId() : int{ - return $this->lit ? $this->idInfo->getSecondId() : parent::getId(); + return $this->powered ? $this->idInfo->getSecondId() : parent::getId(); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->lit = $id === $this->idInfo->getSecondId(); - } - - public function isLit() : bool{ - return $this->lit; - } - - /** - * @return $this - */ - public function setLit(bool $lit = true) : self{ - $this->lit = $lit; - return $this; + $this->powered = $id === $this->idInfo->getSecondId(); } public function getLightLevel() : int{ - return $this->lit ? 15 : 0; + return $this->powered ? 15 : 0; } } From 9ab3c57789f71f77d14f8d6ba1102a951cfb0b13 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Feb 2021 19:03:33 +0000 Subject: [PATCH 2278/3224] RedstoneRepeater: added getDelay() and setDelay() --- src/block/RedstoneRepeater.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/block/RedstoneRepeater.php b/src/block/RedstoneRepeater.php index 7553dc560b..3740340603 100644 --- a/src/block/RedstoneRepeater.php +++ b/src/block/RedstoneRepeater.php @@ -65,6 +65,17 @@ class RedstoneRepeater extends Flowable{ return 0b1111; } + public function getDelay() : int{ return $this->delay; } + + /** @return $this */ + public function setDelay(int $delay) : self{ + if($delay < 1 || $delay > 4){ + throw new \InvalidArgumentException("Delay must be in range 1-4"); + } + $this->delay = $delay; + return $this; + } + /** * @return AxisAlignedBB[] */ From 82bb83211fdcd2c28d683f33bb5c762880c7bc62 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Feb 2021 19:34:52 +0000 Subject: [PATCH 2279/3224] CocoaBlock: deduplicate attachment condition checking --- src/block/CocoaBlock.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/block/CocoaBlock.php b/src/block/CocoaBlock.php index daf612df5a..c725f50ca5 100644 --- a/src/block/CocoaBlock.php +++ b/src/block/CocoaBlock.php @@ -85,8 +85,12 @@ class CocoaBlock extends Transparent{ ]; } + private function canAttachTo(Block $block) : bool{ + return $block instanceof Wood && $block->getTreeType()->equals(TreeType::JUNGLE()); + } + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(Facing::axis($face) !== Axis::Y and $blockClicked instanceof Wood and $blockClicked->getTreeType()->equals(TreeType::JUNGLE())){ + if(Facing::axis($face) !== Axis::Y and $this->canAttachTo($blockClicked)){ $this->facing = $face; return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -108,8 +112,7 @@ class CocoaBlock extends Transparent{ } public function onNearbyBlockChange() : void{ - $side = $this->getSide(Facing::opposite($this->facing)); - if(!($side instanceof Wood) or !$side->getTreeType()->equals(TreeType::JUNGLE())){ + if(!$this->canAttachTo($this->getSide(Facing::opposite($this->facing)))){ $this->pos->getWorld()->useBreakOn($this->pos); } } From 21bafd9f07480c0d0ae0ab68d7f761442d3f4804 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Feb 2021 20:20:36 +0000 Subject: [PATCH 2280/3224] PluginBase: add void return typehints to onLoad(), onEnable() and onDisable() --- src/plugin/PluginBase.php | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/plugin/PluginBase.php b/src/plugin/PluginBase.php index 56febce912..02d2325343 100644 --- a/src/plugin/PluginBase.php +++ b/src/plugin/PluginBase.php @@ -100,29 +100,23 @@ abstract class PluginBase implements Plugin, CommandExecutor{ /** * Called when the plugin is loaded, before calling onEnable() - * - * @return void */ - protected function onLoad()/* : void /* TODO: uncomment this for next major version */{ + protected function onLoad() : void{ } /** * Called when the plugin is enabled - * - * @return void */ - protected function onEnable()/* : void /* TODO: uncomment this for next major version */{ + protected function onEnable() : void{ } /** * Called when the plugin is disabled * Use this to free open things and finish actions - * - * @return void */ - protected function onDisable()/* : void /* TODO: uncomment this for next major version */{ + protected function onDisable() : void{ } From 9887138ac1dfa1f44d437e4905f55049c5d1a0cd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Feb 2021 20:30:25 +0000 Subject: [PATCH 2281/3224] Get rid of anonymous classes for infested stone --- src/block/BlockFactory.php | 48 ++++++++++--------------------------- src/block/InfestedStone.php | 15 ++++++++++-- 2 files changed, 25 insertions(+), 38 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index e699c62abb..5ef3dd82f3 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -134,7 +134,8 @@ class BlockFactory{ $this->register(new CoarseDirt(new BID(Ids::DIRT, Meta::DIRT_COARSE), "Coarse Dirt")); $cobblestoneBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - $this->register(new Opaque(new BID(Ids::COBBLESTONE), "Cobblestone", $cobblestoneBreakInfo)); + $this->register($cobblestone = new Opaque(new BID(Ids::COBBLESTONE), "Cobblestone", $cobblestoneBreakInfo)); + $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_COBBLESTONE), "Infested Cobblestone", $cobblestone)); $this->register(new Opaque(new BID(Ids::MOSSY_COBBLESTONE), "Mossy Cobblestone", $cobblestoneBreakInfo)); $this->register(new Stair(new BID(Ids::COBBLESTONE_STAIRS), "Cobblestone Stairs", $cobblestoneBreakInfo)); $this->register(new Stair(new BID(Ids::MOSSY_COBBLESTONE_STAIRS), "Mossy Cobblestone Stairs", $cobblestoneBreakInfo)); @@ -202,36 +203,6 @@ class BlockFactory{ $this->register(new HayBale(new BID(Ids::HAY_BALE), "Hay Bale")); $this->register(new Hopper(new BID(Ids::HOPPER_BLOCK, 0, ItemIds::HOPPER, TileHopper::class), "Hopper", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 15.0))); $this->register(new Ice(new BID(Ids::ICE), "Ice")); - $this->register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE), "Infested Stone") extends InfestedStone{ - public function getSilkTouchDrops(Item $item) : array{ - return [VanillaBlocks::STONE()->asItem()]; - } - }); - $this->register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_COBBLESTONE), "Infested Cobblestone") extends InfestedStone{ - public function getSilkTouchDrops(Item $item) : array{ - return [VanillaBlocks::COBBLESTONE()->asItem()]; - } - }); - $this->register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK), "Infested Stone Brick") extends InfestedStone{ - public function getSilkTouchDrops(Item $item) : array{ - return [VanillaBlocks::STONE_BRICKS()->asItem()]; - } - }); - $this->register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_MOSSY), "Infested Mossy Stone Brick") extends InfestedStone{ - public function getSilkTouchDrops(Item $item) : array{ - return [VanillaBlocks::MOSSY_STONE_BRICKS()->asItem()]; - } - }); - $this->register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CRACKED), "Infested Cracked Stone Brick") extends InfestedStone{ - public function getSilkTouchDrops(Item $item) : array{ - return [VanillaBlocks::CRACKED_STONE_BRICKS()->asItem()]; - } - }); - $this->register(new class(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CHISELED), "Infested Chiseled Stone Brick") extends InfestedStone{ - public function getSilkTouchDrops(Item $item) : array{ - return [VanillaBlocks::CHISELED_STONE_BRICKS()->asItem()]; - } - }); $updateBlockBreakInfo = new BlockBreakInfo(1.0); $this->register(new Opaque(new BID(Ids::INFO_UPDATE), "update!", $updateBlockBreakInfo)); @@ -335,7 +306,7 @@ class BlockFactory{ $this->register(new Sponge(new BID(Ids::SPONGE), "Sponge")); $stoneBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - $this->register(new class(new BID(Ids::STONE, Meta::STONE_NORMAL), "Stone", $stoneBreakInfo) extends Opaque{ + $this->register($stone = new class(new BID(Ids::STONE, Meta::STONE_NORMAL), "Stone", $stoneBreakInfo) extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ return [VanillaBlocks::COBBLESTONE()->asItem()]; } @@ -344,6 +315,7 @@ class BlockFactory{ return true; } }); + $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE), "Infested Stone", $stone)); $this->register(new Stair(new BID(Ids::NORMAL_STONE_STAIRS), "Stone Stairs", $stoneBreakInfo)); $this->register(new Opaque(new BID(Ids::SMOOTH_STONE), "Smooth Stone", $stoneBreakInfo)); $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_ANDESITE), "Andesite", $stoneBreakInfo)); @@ -359,11 +331,15 @@ class BlockFactory{ $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_GRANITE), "Polished Granite", $stoneBreakInfo)); $this->register(new Stair(new BID(Ids::POLISHED_GRANITE_STAIRS), "Polished Granite Stairs", $stoneBreakInfo)); $this->register(new Stair(new BID(Ids::STONE_BRICK_STAIRS), "Stone Brick Stairs", $stoneBreakInfo)); - $this->register(new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CHISELED), "Chiseled Stone Bricks", $stoneBreakInfo)); - $this->register(new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CRACKED), "Cracked Stone Bricks", $stoneBreakInfo)); - $this->register(new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_MOSSY), "Mossy Stone Bricks", $stoneBreakInfo)); + $this->register($chiseledStoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CHISELED), "Chiseled Stone Bricks", $stoneBreakInfo)); + $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CHISELED), "Infested Chiseled Stone Brick", $chiseledStoneBrick)); + $this->register($crackedStoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CRACKED), "Cracked Stone Bricks", $stoneBreakInfo)); + $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CRACKED), "Infested Cracked Stone Brick", $crackedStoneBrick)); + $this->register($mossyStoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_MOSSY), "Mossy Stone Bricks", $stoneBreakInfo)); + $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_MOSSY), "Infested Mossy Stone Brick", $mossyStoneBrick)); $this->register(new Stair(new BID(Ids::MOSSY_STONE_BRICK_STAIRS), "Mossy Stone Brick Stairs", $stoneBreakInfo)); - $this->register(new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_NORMAL), "Stone Bricks", $stoneBreakInfo)); + $this->register($stoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_NORMAL), "Stone Bricks", $stoneBreakInfo)); + $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK), "Infested Stone Brick", $stoneBrick)); $this->register(new StoneButton(new BID(Ids::STONE_BUTTON), "Stone Button")); $this->register(new StonePressurePlate(new BID(Ids::STONE_PRESSURE_PLATE), "Stone Pressure Plate")); diff --git a/src/block/InfestedStone.php b/src/block/InfestedStone.php index d19737ebde..00188ff2fb 100644 --- a/src/block/InfestedStone.php +++ b/src/block/InfestedStone.php @@ -25,16 +25,27 @@ namespace pocketmine\block; use pocketmine\item\Item; -abstract class InfestedStone extends Opaque{ +final class InfestedStone extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + private int $imitated; + + public function __construct(BlockIdentifier $idInfo, string $name, Block $imitated, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.75)); + $this->imitated = $imitated->getFullId(); + } + + public function getImitatedBlock() : Block{ + return BlockFactory::getInstance()->fromFullBlock($this->imitated); } public function getDropsForCompatibleTool(Item $item) : array{ return []; } + public function getSilkTouchDrops(Item $item) : array{ + return [$this->getImitatedBlock()->asItem()]; + } + public function isAffectedBySilkTouch() : bool{ return true; } From 7c1f0ecb8b2d17c7689d8e5c428e00b1e0e17a97 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Feb 2021 20:39:23 +0000 Subject: [PATCH 2282/3224] Fixed getAxis()/setAxis() not being seen by static analysers for some blocks when using VanillaBlocks::CHISELED_QUARTZ(), VanillaBlocks::PURPUR_PILLAR() or VanillaBlocks::QUARTZ_PILLAR(), static analysis was unable to detect getAxis() and setAxis(), because these blocks were implemented using anonymous classes. --- src/block/BlockFactory.php | 12 +++--------- src/block/SimplePillar.php | 34 ++++++++++++++++++++++++++++++++++ src/block/VanillaBlocks.php | 6 +++--- 3 files changed, 40 insertions(+), 12 deletions(-) create mode 100644 src/block/SimplePillar.php diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 5ef3dd82f3..7be95bc418 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -266,20 +266,14 @@ class BlockFactory{ $purpurBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); $this->register(new Opaque(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_NORMAL), "Purpur Block", $purpurBreakInfo)); - $this->register(new class(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_PILLAR), "Purpur Pillar", $purpurBreakInfo) extends Opaque{ - use PillarRotationInMetadataTrait; - }); + $this->register(new SimplePillar(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_PILLAR), "Purpur Pillar", $purpurBreakInfo)); $this->register(new Stair(new BID(Ids::PURPUR_STAIRS), "Purpur Stairs", $purpurBreakInfo)); $quartzBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()); $this->register(new Opaque(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_NORMAL), "Quartz Block", $quartzBreakInfo)); $this->register(new Stair(new BID(Ids::QUARTZ_STAIRS), "Quartz Stairs", $quartzBreakInfo)); - $this->register(new class(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_CHISELED), "Chiseled Quartz Block", $quartzBreakInfo) extends Opaque{ - use PillarRotationInMetadataTrait; - }); - $this->register(new class(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_PILLAR), "Quartz Pillar", $quartzBreakInfo) extends Opaque{ - use PillarRotationInMetadataTrait; - }); + $this->register(new SimplePillar(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_CHISELED), "Chiseled Quartz Block", $quartzBreakInfo)); + $this->register(new SimplePillar(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_PILLAR), "Quartz Pillar", $quartzBreakInfo)); $this->register(new Opaque(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_SMOOTH), "Smooth Quartz Block", $quartzBreakInfo)); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) $this->register(new Stair(new BID(Ids::SMOOTH_QUARTZ_STAIRS), "Smooth Quartz Stairs", $quartzBreakInfo)); diff --git a/src/block/SimplePillar.php b/src/block/SimplePillar.php new file mode 100644 index 0000000000..50be03be50 --- /dev/null +++ b/src/block/SimplePillar.php @@ -0,0 +1,34 @@ + Date: Sat, 6 Feb 2021 21:20:38 +0000 Subject: [PATCH 2283/3224] Added isPressed() and setPressed() to PressurePlate --- src/block/SimplePressurePlate.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/block/SimplePressurePlate.php b/src/block/SimplePressurePlate.php index 7a3cbfaa6a..5635dcf36b 100644 --- a/src/block/SimplePressurePlate.php +++ b/src/block/SimplePressurePlate.php @@ -26,17 +26,25 @@ namespace pocketmine\block; abstract class SimplePressurePlate extends PressurePlate{ /** @var bool */ - protected $powered = false; + protected $pressed = false; protected function writeStateToMeta() : int{ - return $this->powered ? BlockLegacyMetadata::PRESSURE_PLATE_FLAG_POWERED : 0; + return $this->pressed ? BlockLegacyMetadata::PRESSURE_PLATE_FLAG_POWERED : 0; } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->powered = ($stateMeta & BlockLegacyMetadata::PRESSURE_PLATE_FLAG_POWERED) !== 0; + $this->pressed = ($stateMeta & BlockLegacyMetadata::PRESSURE_PLATE_FLAG_POWERED) !== 0; } public function getStateBitmask() : int{ return 0b1; } + + public function isPressed() : bool{ return $this->pressed; } + + /** @return $this */ + public function setPressed(bool $pressed) : self{ + $this->pressed = $pressed; + return $this; + } } From 609b21679fbaaf8b539508c02da77f0df29a77ac Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Feb 2021 22:31:36 +0000 Subject: [PATCH 2284/3224] Added Torch::setFacing() and Torch::getFacing() these are not implemented with AnyFacingTrait because it would break LSP to have a setFacing that doesn't accept DOWN. --- src/block/Torch.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/block/Torch.php b/src/block/Torch.php index 2a8b200322..8c8a05d3e8 100644 --- a/src/block/Torch.php +++ b/src/block/Torch.php @@ -52,6 +52,17 @@ class Torch extends Flowable{ return 0b111; } + public function getFacing() : int{ return $this->facing; } + + /** @return $this */ + public function setFacing(int $facing) : self{ + if($facing === Facing::DOWN){ + throw new \InvalidArgumentException("Torch may not face DOWN"); + } + $this->facing = $facing; + return $this; + } + public function getLightLevel() : int{ return 14; } From fd2ebd84b4f99ac26a595400fbf7dded014796f8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Feb 2021 23:37:05 +0000 Subject: [PATCH 2285/3224] Recognize underwater TNT --- src/block/BlockLegacyMetadata.php | 4 +--- src/block/TNT.php | 17 +++++++++++++++-- src/entity/object/PrimedTNT.php | 8 ++++++++ .../block/block_factory_consistency_check.json | 2 +- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/block/BlockLegacyMetadata.php b/src/block/BlockLegacyMetadata.php index bbc1485fc8..57189ffbe9 100644 --- a/src/block/BlockLegacyMetadata.php +++ b/src/block/BlockLegacyMetadata.php @@ -253,10 +253,8 @@ final class BlockLegacyMetadata{ public const TALLGRASS_NORMAL = 1; public const TALLGRASS_FERN = 2; - public const TNT_NORMAL = 0; - public const TNT_UNDERWATER = 2; - public const TNT_FLAG_UNSTABLE = 0x01; + public const TNT_FLAG_UNDERWATER = 0x02; public const TRAPDOOR_FLAG_UPPER = 0x04; public const TRAPDOOR_FLAG_OPEN = 0x08; diff --git a/src/block/TNT.php b/src/block/TNT.php index f37b75c2f1..c2ae6f1b30 100644 --- a/src/block/TNT.php +++ b/src/block/TNT.php @@ -43,6 +43,7 @@ class TNT extends Opaque{ /** @var bool */ protected $unstable = false; //TODO: Usage unclear, seems to be a weird hack in vanilla + protected bool $worksUnderwater = false; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); @@ -50,14 +51,25 @@ class TNT extends Opaque{ public function readStateFromData(int $id, int $stateMeta) : void{ $this->unstable = ($stateMeta & BlockLegacyMetadata::TNT_FLAG_UNSTABLE) !== 0; + $this->worksUnderwater = ($stateMeta & BlockLegacyMetadata::TNT_FLAG_UNDERWATER) !== 0; } protected function writeStateToMeta() : int{ - return $this->unstable ? BlockLegacyMetadata::TNT_FLAG_UNSTABLE : 0; + return ($this->unstable ? BlockLegacyMetadata::TNT_FLAG_UNSTABLE : 0) | ($this->worksUnderwater ? BlockLegacyMetadata::TNT_FLAG_UNDERWATER : 0); } public function getStateBitmask() : int{ - return 0b1; + return 0b11; + } + + public function getNonPersistentStateBitmask() : int{ return 0b1; } + + public function worksUnderwater() : bool{ return $this->worksUnderwater; } + + /** @return $this */ + public function setWorksUnderwater(bool $worksUnderwater) : self{ + $this->worksUnderwater = $worksUnderwater; + return $this; } public function onBreak(Item $item, ?Player $player = null) : bool{ @@ -99,6 +111,7 @@ class TNT extends Opaque{ $tnt = new PrimedTNT(Location::fromObject($this->pos->add(0.5, 0, 0.5), $this->pos->getWorld())); $tnt->setFuse($fuse); + $tnt->setWorksUnderwater($this->worksUnderwater); $tnt->setMotion(new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02)); $tnt->spawnToAll(); diff --git a/src/entity/object/PrimedTNT.php b/src/entity/object/PrimedTNT.php index 93eeeb6b72..d6e728d9dd 100644 --- a/src/entity/object/PrimedTNT.php +++ b/src/entity/object/PrimedTNT.php @@ -47,6 +47,8 @@ class PrimedTNT extends Entity implements Explosive{ /** @var int */ protected $fuse; + protected bool $worksUnderwater = false; + public $canCollide = false; protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.98, 0.98); } @@ -62,6 +64,10 @@ class PrimedTNT extends Entity implements Explosive{ $this->fuse = $fuse; } + public function worksUnderwater() : bool{ return $this->worksUnderwater; } + + public function setWorksUnderwater(bool $worksUnderwater) : void{ $this->worksUnderwater = $worksUnderwater; } + public function attack(EntityDamageEvent $source) : void{ if($source->getCause() === EntityDamageEvent::CAUSE_VOID){ parent::attack($source); @@ -108,6 +114,7 @@ class PrimedTNT extends Entity implements Explosive{ $ev = new ExplosionPrimeEvent($this, 4); $ev->call(); if(!$ev->isCancelled()){ + //TODO: deal with underwater TNT (underwater TNT treats water as if it has a blast resistance of 0) $explosion = new Explosion(Position::fromObject($this->location->add(0, $this->size->getHeight() / 2, 0), $this->getWorld()), $ev->getForce(), $this); if($ev->isBlockBreaking()){ $explosion->explodeA(); @@ -120,6 +127,7 @@ class PrimedTNT extends Entity implements Explosive{ parent::syncNetworkData($properties); $properties->setGenericFlag(EntityMetadataFlags::IGNITED, true); + $properties->setInt(EntityMetadataProperties::VARIANT, $this->worksUnderwater ? 1 : 0); $properties->setInt(EntityMetadataProperties::FUSE_LENGTH, $this->fuse); } diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 2977e8778a..f70a2a50fc 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From bd4ce8d9411db27c77642bf596fda871dc976257 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Feb 2021 23:46:51 +0000 Subject: [PATCH 2286/3224] TNT: expose unstable flag --- src/block/TNT.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/block/TNT.php b/src/block/TNT.php index c2ae6f1b30..d4bce585b8 100644 --- a/src/block/TNT.php +++ b/src/block/TNT.php @@ -64,6 +64,14 @@ class TNT extends Opaque{ public function getNonPersistentStateBitmask() : int{ return 0b1; } + public function isUnstable() : bool{ return $this->unstable; } + + /** @return $this */ + public function setUnstable(bool $unstable) : self{ + $this->unstable = $unstable; + return $this; + } + public function worksUnderwater() : bool{ return $this->worksUnderwater; } /** @return $this */ From da7c97f885a98bbe66fc234afaa951d93055b142 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 7 Feb 2021 17:27:01 +0000 Subject: [PATCH 2287/3224] Updated composer dependencies --- composer.lock | 228 +++++++++++++++++++++++++++++++------------------- 1 file changed, 143 insertions(+), 85 deletions(-) diff --git a/composer.lock b/composer.lock index a778a5579b..1330f34b11 100644 --- a/composer.lock +++ b/composer.lock @@ -262,21 +262,21 @@ "source": { "type": "git", "url": "https://github.com/pmmp/BinaryUtils.git", - "reference": "7fbdf706e29dced2611eb4d01cd4ca60b4138f5a" + "reference": "5959ad1259341fceeed080704a0c5a91ed5a8049" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/7fbdf706e29dced2611eb4d01cd4ca60b4138f5a", - "reference": "7fbdf706e29dced2611eb4d01cd4ca60b4138f5a", + "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/5959ad1259341fceeed080704a0c5a91ed5a8049", + "reference": "5959ad1259341fceeed080704a0c5a91ed5a8049", "shasum": "" }, "require": { - "php": ">=7.2", + "php": "^7.2 || ^8.0", "php-64bit": "*" }, "require-dev": { "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "0.12.63", + "phpstan/phpstan": "0.12.67", "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", @@ -294,7 +294,7 @@ "issues": "https://github.com/pmmp/BinaryUtils/issues", "source": "https://github.com/pmmp/BinaryUtils/tree/master" }, - "time": "2020-12-17T17:42:11+00:00" + "time": "2021-01-15T14:19:25+00:00" }, { "name": "pocketmine/callback-validator", @@ -352,25 +352,25 @@ "source": { "type": "git", "url": "https://github.com/pmmp/ClassLoader.git", - "reference": "f5d5e0ae6982686151d744d4c8b31e66c27001f4" + "reference": "c0133050639cd4a8baefc56a4f334f269c66a7e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/f5d5e0ae6982686151d744d4c8b31e66c27001f4", - "reference": "f5d5e0ae6982686151d744d4c8b31e66c27001f4", + "url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/c0133050639cd4a8baefc56a4f334f269c66a7e0", + "reference": "c0133050639cd4a8baefc56a4f334f269c66a7e0", "shasum": "" }, "require": { "ext-pthreads": "~3.2.0", "ext-reflection": "*", - "php": ">=7.2.0" + "php": "^7.2 || ^8.0" }, "conflict": { "pocketmine/spl": "<0.4" }, "require-dev": { "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "0.12.63", + "phpstan/phpstan": "0.12.66", "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", @@ -388,7 +388,7 @@ "issues": "https://github.com/pmmp/ClassLoader/issues", "source": "https://github.com/pmmp/ClassLoader/tree/master" }, - "time": "2021-01-06T21:09:10+00:00" + "time": "2021-01-15T00:41:29+00:00" }, { "name": "pocketmine/color", @@ -472,22 +472,22 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Log.git", - "reference": "b8509a5f30c6317db42a8511785b781b41c5cdd5" + "reference": "2b514ca0a3143e1d5dbfa30bdf9f7497611bbbda" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Log/zipball/b8509a5f30c6317db42a8511785b781b41c5cdd5", - "reference": "b8509a5f30c6317db42a8511785b781b41c5cdd5", + "url": "https://api.github.com/repos/pmmp/Log/zipball/2b514ca0a3143e1d5dbfa30bdf9f7497611bbbda", + "reference": "2b514ca0a3143e1d5dbfa30bdf9f7497611bbbda", "shasum": "" }, "require": { - "php": ">=7.2" + "php": "^7.2 || ^8.0" }, "conflict": { "pocketmine/spl": "<0.4" }, "require-dev": { - "phpstan/phpstan": "0.12.59", + "phpstan/phpstan": "0.12.67", "phpstan/phpstan-strict-rules": "^0.12.2" }, "type": "library", @@ -505,7 +505,7 @@ "issues": "https://github.com/pmmp/Log/issues", "source": "https://github.com/pmmp/Log/tree/master" }, - "time": "2020-12-11T00:10:43+00:00" + "time": "2021-01-15T14:33:25+00:00" }, { "name": "pocketmine/log-pthreads", @@ -513,12 +513,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/LogPthreads.git", - "reference": "634af620e1cb3b4f3c7ed356cc31d778b00fd717" + "reference": "271ff55ee7cba80b9368d924f3a4c6093a2577fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/634af620e1cb3b4f3c7ed356cc31d778b00fd717", - "reference": "634af620e1cb3b4f3c7ed356cc31d778b00fd717", + "url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/271ff55ee7cba80b9368d924f3a4c6093a2577fb", + "reference": "271ff55ee7cba80b9368d924f3a4c6093a2577fb", "shasum": "" }, "require": { @@ -549,7 +549,7 @@ "issues": "https://github.com/pmmp/LogPthreads/issues", "source": "https://github.com/pmmp/LogPthreads/tree/master" }, - "time": "2021-02-04T15:41:29+00:00" + "time": "2021-02-04T16:22:31+00:00" }, { "name": "pocketmine/math", @@ -557,22 +557,22 @@ "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "58ffaef47bc269b65c4cf6f0c85f563510c2a91d" + "reference": "5c5ddc62725daad773d8c4eda180e6327d45b692" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/58ffaef47bc269b65c4cf6f0c85f563510c2a91d", - "reference": "58ffaef47bc269b65c4cf6f0c85f563510c2a91d", + "url": "https://api.github.com/repos/pmmp/Math/zipball/5c5ddc62725daad773d8c4eda180e6327d45b692", + "reference": "5c5ddc62725daad773d8c4eda180e6327d45b692", "shasum": "" }, "require": { - "php": ">=7.2.0", + "php": "^7.2 || ^8.0", "php-64bit": "*" }, "require-dev": { "irstea/phpunit-shim": "^8.5 || ^9.5", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "0.12.59", + "phpstan/phpstan": "0.12.67", "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", @@ -590,7 +590,7 @@ "issues": "https://github.com/pmmp/Math/issues", "source": "https://github.com/pmmp/Math/tree/master" }, - "time": "2020-12-11T00:18:45+00:00" + "time": "2021-01-15T14:25:59+00:00" }, { "name": "pocketmine/nbt", @@ -598,23 +598,23 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "460b7f21e80323387197e030b1727c2aef12ec1c" + "reference": "3d4fd4ba5d0f4beb5623c5387dc9858242c02edd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/460b7f21e80323387197e030b1727c2aef12ec1c", - "reference": "460b7f21e80323387197e030b1727c2aef12ec1c", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/3d4fd4ba5d0f4beb5623c5387dc9858242c02edd", + "reference": "3d4fd4ba5d0f4beb5623c5387dc9858242c02edd", "shasum": "" }, "require": { - "php": ">=7.2.0", + "php": "^7.2 || ^8.0", "php-64bit": "*", "pocketmine/binaryutils": "dev-master" }, "require-dev": { "irstea/phpunit-shim": "^7.5 || ^8.0", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "0.12.63", + "phpstan/phpstan": "0.12.67", "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", @@ -632,7 +632,7 @@ "issues": "https://github.com/pmmp/NBT/issues", "source": "https://github.com/pmmp/NBT/tree/master" }, - "time": "2020-12-17T17:17:37+00:00" + "time": "2021-01-15T15:29:32+00:00" }, { "name": "pocketmine/raklib", @@ -640,24 +640,24 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "c2a4f728ab816bde2713345ffaad79410c6eadd4" + "reference": "edd403e465b0974ecfcd20d41da98ecada22e6a6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/c2a4f728ab816bde2713345ffaad79410c6eadd4", - "reference": "c2a4f728ab816bde2713345ffaad79410c6eadd4", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/edd403e465b0974ecfcd20d41da98ecada22e6a6", + "reference": "edd403e465b0974ecfcd20d41da98ecada22e6a6", "shasum": "" }, "require": { "ext-sockets": "*", - "php": ">=7.2.0", + "php": "^7.2 || ^8.0", "php-64bit": "*", "php-ipv6": "*", "pocketmine/binaryutils": "dev-master", "pocketmine/log": "dev-master" }, "require-dev": { - "phpstan/phpstan": "0.12.63", + "phpstan/phpstan": "0.12.67", "phpstan/phpstan-strict-rules": "^0.12.2" }, "type": "library", @@ -675,29 +675,29 @@ "issues": "https://github.com/pmmp/RakLib/issues", "source": "https://github.com/pmmp/RakLib/tree/master" }, - "time": "2021-01-06T20:59:43+00:00" + "time": "2021-01-15T16:23:13+00:00" }, { "name": "pocketmine/snooze", - "version": "0.1.3", + "version": "0.1.4", "source": { "type": "git", "url": "https://github.com/pmmp/Snooze.git", - "reference": "849510fa62e57512b8467e3694e9b3add97038fd" + "reference": "382ab149f01ecca0a57f999ff5d7fc9e271c3268" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Snooze/zipball/849510fa62e57512b8467e3694e9b3add97038fd", - "reference": "849510fa62e57512b8467e3694e9b3add97038fd", + "url": "https://api.github.com/repos/pmmp/Snooze/zipball/382ab149f01ecca0a57f999ff5d7fc9e271c3268", + "reference": "382ab149f01ecca0a57f999ff5d7fc9e271c3268", "shasum": "" }, "require": { "ext-pthreads": ">=3.1.7dev", - "php-64bit": ">=7.2.0" + "php-64bit": "^7.2 || ^8.0" }, "require-dev": { "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "0.12.40", + "phpstan/phpstan": "0.12.67", "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", @@ -713,9 +713,9 @@ "description": "Thread notification management library for code using the pthreads extension", "support": { "issues": "https://github.com/pmmp/Snooze/issues", - "source": "https://github.com/pmmp/Snooze/tree/0.1.3" + "source": "https://github.com/pmmp/Snooze/tree/0.1.4" }, - "time": "2020-08-28T22:19:21+00:00" + "time": "2021-01-15T14:44:16+00:00" }, { "name": "pocketmine/spl", @@ -723,21 +723,20 @@ "source": { "type": "git", "url": "https://github.com/pmmp/SPL.git", - "reference": "98589af98ff5662f4f69a76bdbf3129c9e2e3614" + "reference": "b7a8904f912c1f6d38ad867ff1120614ccb80171" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/SPL/zipball/98589af98ff5662f4f69a76bdbf3129c9e2e3614", - "reference": "98589af98ff5662f4f69a76bdbf3129c9e2e3614", + "url": "https://api.github.com/repos/pmmp/SPL/zipball/b7a8904f912c1f6d38ad867ff1120614ccb80171", + "reference": "b7a8904f912c1f6d38ad867ff1120614ccb80171", "shasum": "" }, "require": { - "php": ">=7.2" + "php": "^7.2 || ^8.0" }, "require-dev": { "phpstan/phpstan": "^0.12.8" }, - "default-branch": true, "type": "library", "autoload": { "classmap": [ @@ -753,28 +752,28 @@ "issues": "https://github.com/pmmp/SPL/issues", "source": "https://github.com/pmmp/SPL/tree/master" }, - "time": "2020-05-10T12:05:24+00:00" + "time": "2021-01-15T15:19:34+00:00" }, { "name": "pocketmine/uuid", - "version": "0.1.0", + "version": "0.1.1", "source": { "type": "git", "url": "https://github.com/pmmp/UUID.git", - "reference": "c45c995cb87eafee01a14a06a4b7b517cada03a5" + "reference": "385051ab7919966191d04b0c5c5009639a4b2ba3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/UUID/zipball/c45c995cb87eafee01a14a06a4b7b517cada03a5", - "reference": "c45c995cb87eafee01a14a06a4b7b517cada03a5", + "url": "https://api.github.com/repos/pmmp/UUID/zipball/385051ab7919966191d04b0c5c5009639a4b2ba3", + "reference": "385051ab7919966191d04b0c5c5009639a4b2ba3", "shasum": "" }, "require": { - "php": "^7.3", + "php": "^7.3 || ^8.0", "pocketmine/binaryutils": "^0.1 || dev-master" }, "require-dev": { - "phpstan/phpstan": "^0.12.23", + "phpstan/phpstan": "0.12.66", "phpstan/phpstan-strict-rules": "^0.12.2" }, "type": "library", @@ -790,9 +789,9 @@ "description": "Basic UUID implementation used by PocketMine-MP and related projects", "support": { "issues": "https://github.com/pmmp/UUID/issues", - "source": "https://github.com/pmmp/UUID/tree/master" + "source": "https://github.com/pmmp/UUID/tree/0.1.1" }, - "time": "2020-05-10T12:38:41+00:00" + "time": "2021-01-15T00:33:02+00:00" }, { "name": "respect/stringifier", @@ -850,25 +849,26 @@ }, { "name": "respect/validation", - "version": "2.1.0", + "version": "2.2.1", "source": { "type": "git", "url": "https://github.com/Respect/Validation.git", - "reference": "6c3aed92137836788c8ce654b9c35763c5e98b54" + "reference": "51ad23e24c83f222468174861de61fc8bcde9bfb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Respect/Validation/zipball/6c3aed92137836788c8ce654b9c35763c5e98b54", - "reference": "6c3aed92137836788c8ce654b9c35763c5e98b54", + "url": "https://api.github.com/repos/Respect/Validation/zipball/51ad23e24c83f222468174861de61fc8bcde9bfb", + "reference": "51ad23e24c83f222468174861de61fc8bcde9bfb", "shasum": "" }, "require": { "php": "^7.3 || ^8.0", "respect/stringifier": "^0.2.0", + "sokil/php-isocodes": "^3.3", "symfony/polyfill-mbstring": "^1.2" }, "require-dev": { - "egulias/email-validator": "^2.1", + "egulias/email-validator": "^3.0", "malukenho/docheader": "^0.1", "mikey179/vfsstream": "^1.6", "phpstan/phpstan": "^0.12", @@ -886,6 +886,7 @@ "ext-bcmath": "Arbitrary Precision Mathematics", "ext-fileinfo": "File Information", "ext-mbstring": "Multibyte String Functions", + "sokil/php-isocodes": "To enable ISO codes validations", "symfony/validator": "Use Symfony validator through Respect\\Validation", "zendframework/zend-validator": "Use Zend Framework validator through Respect\\Validation" }, @@ -914,9 +915,66 @@ ], "support": { "issues": "https://github.com/Respect/Validation/issues", - "source": "https://github.com/Respect/Validation/tree/2.1.0" + "source": "https://github.com/Respect/Validation/tree/2.2.1" }, - "time": "2020-10-04T12:09:34+00:00" + "time": "2021-02-06T16:42:11+00:00" + }, + { + "name": "sokil/php-isocodes", + "version": "3.3.3", + "source": { + "type": "git", + "url": "https://github.com/sokil/php-isocodes.git", + "reference": "d05d170a554f61ba793e31a78d2b4b3aaa80907f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sokil/php-isocodes/zipball/d05d170a554f61ba793e31a78d2b4b3aaa80907f", + "reference": "d05d170a554f61ba793e31a78d2b4b3aaa80907f", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=7.1" + }, + "require-dev": { + "ext-gettext": "*", + "php-coveralls/php-coveralls": "^2.1", + "phpmd/phpmd": "@stable", + "phpunit/phpunit": ">=7.5.20", + "squizlabs/php_codesniffer": "^3.4", + "symfony/translation": "^4.4.17|^5.2", + "vimeo/psalm": "^4.3" + }, + "suggest": { + "ext-gettext": "Required for gettext translation driver", + "phpbench/phpbench": "Required to run benchmarks", + "symfony/translation": "Translation driver by Symfont project" + }, + "type": "library", + "autoload": { + "psr-4": { + "Sokil\\IsoCodes\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dmytro Sokil", + "email": "dmytro.sokil@gmail.com" + } + ], + "description": "ISO country, subdivision, language, currency and script definitions and their translations. Based on pythons pycountry and Debian's iso-codes.", + "support": { + "issues": "https://github.com/sokil/php-isocodes/issues", + "source": "https://github.com/sokil/php-isocodes/tree/3.3.3" + }, + "time": "2021-02-02T06:42:33+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -1636,16 +1694,16 @@ }, { "name": "phpstan/phpstan-strict-rules", - "version": "0.12.8", + "version": "0.12.9", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-strict-rules.git", - "reference": "ee0009302ff5312ca6b92a7330a6b66da0c70f12" + "reference": "0705fefc7c9168529fd130e341428f5f10f4f01d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/ee0009302ff5312ca6b92a7330a6b66da0c70f12", - "reference": "ee0009302ff5312ca6b92a7330a6b66da0c70f12", + "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/0705fefc7c9168529fd130e341428f5f10f4f01d", + "reference": "0705fefc7c9168529fd130e341428f5f10f4f01d", "shasum": "" }, "require": { @@ -1681,9 +1739,9 @@ "description": "Extra strict and opinionated rules for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-strict-rules/issues", - "source": "https://github.com/phpstan/phpstan-strict-rules/tree/0.12.8" + "source": "https://github.com/phpstan/phpstan-strict-rules/tree/0.12.9" }, - "time": "2021-01-11T13:36:23+00:00" + "time": "2021-01-13T08:50:28+00:00" }, { "name": "phpunit/php-code-coverage", @@ -2005,16 +2063,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.1", + "version": "9.5.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "e7bdf4085de85a825f4424eae52c99a1cec2f360" + "reference": "f661659747f2f87f9e72095bb207bceb0f151cb4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e7bdf4085de85a825f4424eae52c99a1cec2f360", - "reference": "e7bdf4085de85a825f4424eae52c99a1cec2f360", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f661659747f2f87f9e72095bb207bceb0f151cb4", + "reference": "f661659747f2f87f9e72095bb207bceb0f151cb4", "shasum": "" }, "require": { @@ -2092,7 +2150,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.1" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.2" }, "funding": [ { @@ -2104,7 +2162,7 @@ "type": "github" } ], - "time": "2021-01-17T07:42:25+00:00" + "time": "2021-02-02T14:45:58+00:00" }, { "name": "sebastian/cli-parser", @@ -3204,12 +3262,12 @@ "version": "1.9.1", "source": { "type": "git", - "url": "https://github.com/webmozart/assert.git", + "url": "https://github.com/webmozarts/assert.git", "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", "shasum": "" }, @@ -3247,8 +3305,8 @@ "validate" ], "support": { - "issues": "https://github.com/webmozart/assert/issues", - "source": "https://github.com/webmozart/assert/tree/master" + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.9.1" }, "time": "2020-07-08T17:02:28+00:00" } From f952a6643cbaf3b761a64fbcfc9d7ecf72e01bb9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 7 Feb 2021 17:33:33 +0000 Subject: [PATCH 2288/3224] Accept PHP 8.0 compatible dependency versions in composer.json composer decided that this was a good time to reorganize composer.json for me, and... well, fuck it. --- composer.json | 34 +++++++++++++-------------- composer.lock | 64 +++++++++++++++++++++++++-------------------------- 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/composer.json b/composer.json index 5a5ac2a964..95c59548b6 100644 --- a/composer.json +++ b/composer.json @@ -8,9 +8,9 @@ "php": ">=7.4.0", "php-64bit": "*", "ext-chunkutils2": "^0.1.0", - "ext-curl": "*", "ext-crypto": "^0.3.1", "ext-ctype": "*", + "ext-curl": "*", "ext-date": "*", "ext-ds": "^1.2.7", "ext-gmp": "*", @@ -30,24 +30,24 @@ "ext-yaml": ">=2.0.0", "ext-zip": "*", "ext-zlib": ">=1.2.11", - "mdanter/ecc": "^0.5.0", - "pocketmine/raklib": "dev-master", - "pocketmine/spl": "dev-master", - "pocketmine/binaryutils": "dev-master", - "pocketmine/log": "dev-master", - "pocketmine/nbt": "dev-master", - "pocketmine/math": "dev-master", - "pocketmine/snooze": "^0.1.0", - "pocketmine/classloader": "dev-master", - "pocketmine/log-pthreads": "dev-master", - "pocketmine/callback-validator": "^1.0.2", - "pocketmine/errorhandler": "^0.1.0", - "pocketmine/uuid": "^0.1.0", - "pocketmine/color": "^0.1.0", + "composer-runtime-api": "^2.0", "adhocore/json-comment": "^0.1.0", + "mdanter/ecc": "^1.0", "netresearch/jsonmapper": "^3.1.1", - "respect/validation": "^2.0", - "composer-runtime-api": "^2.0" + "pocketmine/binaryutils": "dev-master", + "pocketmine/callback-validator": "^1.0.2", + "pocketmine/classloader": "dev-master", + "pocketmine/color": "^0.2.0", + "pocketmine/errorhandler": "^0.2.0", + "pocketmine/log": "dev-master", + "pocketmine/log-pthreads": "dev-master", + "pocketmine/math": "dev-master", + "pocketmine/nbt": "dev-master", + "pocketmine/raklib": "dev-master", + "pocketmine/snooze": "^0.1.0", + "pocketmine/spl": "dev-master", + "pocketmine/uuid": "^0.1.0", + "respect/validation": "^2.0" }, "require-dev": { "phpstan/phpstan": "0.12.71", diff --git a/composer.lock b/composer.lock index 1330f34b11..481b3fe578 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4ef66ad9f915fd8a82409bbf2a46c9cf", + "content-hash": "890a26c254ade9c1f4e45228ac71ac28", "packages": [ { "name": "adhocore/json-comment", @@ -131,25 +131,25 @@ }, { "name": "mdanter/ecc", - "version": "v0.5.2", + "version": "v1.0.0", "source": { "type": "git", "url": "https://github.com/phpecc/phpecc.git", - "reference": "b95f25cc1bacc83a9f0ccd375900b7cfd343029e" + "reference": "34e2eec096bf3dcda814e8f66dd91ae87a2db7cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpecc/phpecc/zipball/b95f25cc1bacc83a9f0ccd375900b7cfd343029e", - "reference": "b95f25cc1bacc83a9f0ccd375900b7cfd343029e", + "url": "https://api.github.com/repos/phpecc/phpecc/zipball/34e2eec096bf3dcda814e8f66dd91ae87a2db7cd", + "reference": "34e2eec096bf3dcda814e8f66dd91ae87a2db7cd", "shasum": "" }, "require": { "ext-gmp": "*", "fgrosse/phpasn1": "^2.0", - "php": "^7.0" + "php": "^7.0||^8.0" }, "require-dev": { - "phpunit/phpunit": "^6.0", + "phpunit/phpunit": "^6.0||^8.0||^9.0", "squizlabs/php_codesniffer": "^2.0", "symfony/yaml": "^2.6|^3.0" }, @@ -201,9 +201,9 @@ ], "support": { "issues": "https://github.com/phpecc/phpecc/issues", - "source": "https://github.com/phpecc/phpecc/tree/master" + "source": "https://github.com/phpecc/phpecc/tree/v1.0.0" }, - "time": "2018-12-03T18:17:01+00:00" + "time": "2021-01-16T19:42:14+00:00" }, { "name": "netresearch/jsonmapper", @@ -392,23 +392,23 @@ }, { "name": "pocketmine/color", - "version": "0.1.0", + "version": "0.2.0", "source": { "type": "git", "url": "https://github.com/pmmp/Color.git", - "reference": "10f3453d0eb3eccbccad5cf58a00e42cdaef1772" + "reference": "09be6ea6d76f2e33d6813c39d29c22c46c17e1d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Color/zipball/10f3453d0eb3eccbccad5cf58a00e42cdaef1772", - "reference": "10f3453d0eb3eccbccad5cf58a00e42cdaef1772", + "url": "https://api.github.com/repos/pmmp/Color/zipball/09be6ea6d76f2e33d6813c39d29c22c46c17e1d2", + "reference": "09be6ea6d76f2e33d6813c39d29c22c46c17e1d2", "shasum": "" }, "require": { - "php": "^7.2" + "php": "^7.2 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^0.12.25", + "phpstan/phpstan": "0.12.59", "phpstan/phpstan-strict-rules": "^0.12.2" }, "type": "library", @@ -424,29 +424,29 @@ "description": "Color handling library used by PocketMine-MP and related projects", "support": { "issues": "https://github.com/pmmp/Color/issues", - "source": "https://github.com/pmmp/Color/tree/0.1.0" + "source": "https://github.com/pmmp/Color/tree/0.2.0" }, - "time": "2020-05-14T19:15:33+00:00" + "time": "2020-12-11T01:24:32+00:00" }, { "name": "pocketmine/errorhandler", - "version": "0.1.0", + "version": "0.2.0", "source": { "type": "git", "url": "https://github.com/pmmp/ErrorHandler.git", - "reference": "0503a1929a3934e754114814509ff9152f4908eb" + "reference": "567fa056335efc295c4592c8aad72de66a2fcf34" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/ErrorHandler/zipball/0503a1929a3934e754114814509ff9152f4908eb", - "reference": "0503a1929a3934e754114814509ff9152f4908eb", + "url": "https://api.github.com/repos/pmmp/ErrorHandler/zipball/567fa056335efc295c4592c8aad72de66a2fcf34", + "reference": "567fa056335efc295c4592c8aad72de66a2fcf34", "shasum": "" }, "require": { - "php": "^7.2" + "php": "^7.2 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^0.12.23", + "phpstan/phpstan": "0.12.59", "phpstan/phpstan-strict-rules": "^0.12.2" }, "type": "library", @@ -462,9 +462,9 @@ "description": "Utilities to handle nasty PHP E_* errors in a usable way", "support": { "issues": "https://github.com/pmmp/ErrorHandler/issues", - "source": "https://github.com/pmmp/ErrorHandler/tree/0.1.0" + "source": "https://github.com/pmmp/ErrorHandler/tree/0.2.0" }, - "time": "2020-05-10T11:45:02+00:00" + "time": "2020-12-11T01:06:33+00:00" }, { "name": "pocketmine/log", @@ -3314,14 +3314,14 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "pocketmine/raklib": 20, - "pocketmine/spl": 20, "pocketmine/binaryutils": 20, - "pocketmine/log": 20, - "pocketmine/nbt": 20, - "pocketmine/math": 20, "pocketmine/classloader": 20, - "pocketmine/log-pthreads": 20 + "pocketmine/log": 20, + "pocketmine/log-pthreads": 20, + "pocketmine/math": 20, + "pocketmine/nbt": 20, + "pocketmine/raklib": 20, + "pocketmine/spl": 20 }, "prefer-stable": false, "prefer-lowest": false, @@ -3329,9 +3329,9 @@ "php": ">=7.4.0", "php-64bit": "*", "ext-chunkutils2": "^0.1.0", - "ext-curl": "*", "ext-crypto": "^0.3.1", "ext-ctype": "*", + "ext-curl": "*", "ext-date": "*", "ext-ds": "^1.2.7", "ext-gmp": "*", From c456f21df89a3840c0373090a96eedba97485da5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 7 Feb 2021 17:36:49 +0000 Subject: [PATCH 2289/3224] one more --- composer.json | 2 +- composer.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/composer.json b/composer.json index 95c59548b6..573c66c263 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,7 @@ "composer-runtime-api": "^2.0", "adhocore/json-comment": "^0.1.0", "mdanter/ecc": "^1.0", - "netresearch/jsonmapper": "^3.1.1", + "netresearch/jsonmapper": "^4.0", "pocketmine/binaryutils": "dev-master", "pocketmine/callback-validator": "^1.0.2", "pocketmine/classloader": "dev-master", diff --git a/composer.lock b/composer.lock index 481b3fe578..d9623dbfa1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "890a26c254ade9c1f4e45228ac71ac28", + "content-hash": "d3ee8c7369af4993870e5a3cb907c520", "packages": [ { "name": "adhocore/json-comment", @@ -207,16 +207,16 @@ }, { "name": "netresearch/jsonmapper", - "version": "v3.1.1", + "version": "v4.0.0", "source": { "type": "git", "url": "https://github.com/cweiske/jsonmapper.git", - "reference": "ba09f0e456d4f00cef84e012da5715625594407c" + "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/ba09f0e456d4f00cef84e012da5715625594407c", - "reference": "ba09f0e456d4f00cef84e012da5715625594407c", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d", + "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d", "shasum": "" }, "require": { @@ -224,10 +224,10 @@ "ext-pcre": "*", "ext-reflection": "*", "ext-spl": "*", - "php": ">=5.6" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "~4.8.35 || ~5.7 || ~6.4 || ~7.0", + "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0", "squizlabs/php_codesniffer": "~3.5" }, "type": "library", @@ -252,9 +252,9 @@ "support": { "email": "cweiske@cweiske.de", "issues": "https://github.com/cweiske/jsonmapper/issues", - "source": "https://github.com/cweiske/jsonmapper/tree/v3.1.1" + "source": "https://github.com/cweiske/jsonmapper/tree/v4.0.0" }, - "time": "2020-11-02T19:19:54+00:00" + "time": "2020-12-01T19:48:11+00:00" }, { "name": "pocketmine/binaryutils", From 77453108700972b96c297645e28a336461ba129d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 7 Feb 2021 17:54:38 +0000 Subject: [PATCH 2290/3224] Use native property types for login JSON models this significantly reduces the amount of PHPDoc boilerplate, because the remaining doc comments can mostly be reduced to 1 line. --- .../types/login/AuthenticationData.php | 24 +- .../mcpe/protocol/types/login/ClientData.php | 233 +++++------------- .../types/login/ClientDataAnimationFrame.php | 42 +--- .../login/ClientDataPersonaPieceTintColor.php | 11 +- .../login/ClientDataPersonaSkinPiece.php | 37 +-- .../protocol/types/login/JwtBodyRfc7519.php | 20 +- .../mcpe/protocol/types/login/JwtChain.php | 2 +- .../protocol/types/login/JwtChainLinkBody.php | 5 +- .../mcpe/protocol/types/login/JwtHeader.php | 16 +- 9 files changed, 117 insertions(+), 273 deletions(-) diff --git a/src/network/mcpe/protocol/types/login/AuthenticationData.php b/src/network/mcpe/protocol/types/login/AuthenticationData.php index 6e48143d25..535d8ca43d 100644 --- a/src/network/mcpe/protocol/types/login/AuthenticationData.php +++ b/src/network/mcpe/protocol/types/login/AuthenticationData.php @@ -28,24 +28,14 @@ namespace pocketmine\network\mcpe\protocol\types\login; */ final class AuthenticationData{ - /** - * @var string - * @required - */ - public $displayName; + /** @required */ + public string $displayName; - /** - * @var string - * @required - */ - public $identity; + /** @required */ + public string $identity; - /** @var string */ - public $titleId = ""; //TODO: find out what this is for + public string $titleId = ""; //TODO: find out what this is for - /** - * @var string - * @required - */ - public $XUID; + /** @required */ + public string $XUID; } diff --git a/src/network/mcpe/protocol/types/login/ClientData.php b/src/network/mcpe/protocol/types/login/ClientData.php index b2d9bbc571..c949ffcda2 100644 --- a/src/network/mcpe/protocol/types/login/ClientData.php +++ b/src/network/mcpe/protocol/types/login/ClientData.php @@ -32,212 +32,115 @@ final class ClientData{ * @var ClientDataAnimationFrame[] * @required */ - public $AnimatedImageData; + public array $AnimatedImageData; - /** - * @var string - * @required - */ - public $ArmSize; + /** @required */ + public string $ArmSize; - /** - * @var string - * @required - */ - public $CapeData; + /** @required */ + public string $CapeData; - /** - * @var string - * @required - */ - public $CapeId; + /** @required */ + public string $CapeId; - /** - * @var int - * @required - */ - public $CapeImageHeight; + /** @required */ + public int $CapeImageHeight; - /** - * @var int - * @required - */ - public $CapeImageWidth; + /** @required */ + public int $CapeImageWidth; - /** - * @var bool - * @required - */ - public $CapeOnClassicSkin; + /** @required */ + public bool $CapeOnClassicSkin; - /** - * @var int - * @required - */ - public $ClientRandomId; + /** @required */ + public int $ClientRandomId; - /** - * @var int - * @required - */ - public $CurrentInputMode; + /** @required */ + public int $CurrentInputMode; - /** - * @var int - * @required - */ - public $DefaultInputMode; + /** @required */ + public int $DefaultInputMode; - /** - * @var string - * @required - */ - public $DeviceId; + /** @required */ + public string $DeviceId; - /** - * @var string - * @required - */ - public $DeviceModel; + /** @required */ + public string $DeviceModel; - /** - * @var int - * @required - */ - public $DeviceOS; + /** @required */ + public int $DeviceOS; - /** - * @var string - * @required - */ - public $GameVersion; + /** @required */ + public string $GameVersion; - /** - * @var int - * @required - */ - public $GuiScale; + /** @required */ + public int $GuiScale; - /** - * @var string - * @required - */ - public $LanguageCode; + /** @required */ + public string $LanguageCode; /** * @var ClientDataPersonaSkinPiece[] * @required */ - public $PersonaPieces; + public array $PersonaPieces; - /** - * @var bool - * @required - */ - public $PersonaSkin; + /** @required */ + public bool $PersonaSkin; /** * @var ClientDataPersonaPieceTintColor[] * @required */ - public $PieceTintColors; + public array $PieceTintColors; - /** - * @var string - * @required - */ - public $PlatformOfflineId; + /** @required */ + public string $PlatformOfflineId; - /** - * @var string - * @required - */ - public $PlatformOnlineId; + /** @required */ + public string $PlatformOnlineId; - /** @var string */ - public $PlatformUserId = ""; //xbox-only, apparently + public string $PlatformUserId = ""; //xbox-only, apparently - /** - * @var bool - * @required - */ - public $PremiumSkin = false; + /** @required */ + public bool $PremiumSkin = false; - /** - * @var string - * @required - */ - public $SelfSignedId; + /** @required */ + public string $SelfSignedId; - /** - * @var string - * @required - */ - public $ServerAddress; + /** @required */ + public string $ServerAddress; - /** - * @var string - * @required - */ - public $SkinAnimationData; + /** @required */ + public string $SkinAnimationData; - /** - * @var string - * @required - */ - public $SkinColor; + /** @required */ + public string $SkinColor; - /** - * @var string - * @required - */ - public $SkinData; + /** @required */ + public string $SkinData; - /** - * @var string - * @required - */ - public $SkinGeometryData; + /** @required */ + public string $SkinGeometryData; - /** - * @var string - * @required - */ - public $SkinId; + /** @required */ + public string $SkinId; - /** - * @var int - * @required - */ - public $SkinImageHeight; + /** @required */ + public int $SkinImageHeight; - /** - * @var int - * @required - */ - public $SkinImageWidth; + /** @required */ + public int $SkinImageWidth; - /** - * @var string - * @required - */ - public $SkinResourcePatch; + /** @required */ + public string $SkinResourcePatch; - /** - * @var string - * @required - */ - public $ThirdPartyName; + /** @required */ + public string $ThirdPartyName; - /** - * @var bool - * @required - */ - public $ThirdPartyNameOnly; + /** @required */ + public bool $ThirdPartyNameOnly; - /** - * @var int - * @required - */ - public $UIProfile; + /** @required */ + public int $UIProfile; } diff --git a/src/network/mcpe/protocol/types/login/ClientDataAnimationFrame.php b/src/network/mcpe/protocol/types/login/ClientDataAnimationFrame.php index f1a80f0ca6..843b03ce24 100644 --- a/src/network/mcpe/protocol/types/login/ClientDataAnimationFrame.php +++ b/src/network/mcpe/protocol/types/login/ClientDataAnimationFrame.php @@ -28,39 +28,21 @@ namespace pocketmine\network\mcpe\protocol\types\login; */ final class ClientDataAnimationFrame{ - /** - * @var int - * @required - */ - public $ImageHeight; + /** @required */ + public int $ImageHeight; - /** - * @var int - * @required - */ - public $ImageWidth; + /** @required */ + public int $ImageWidth; - /** - * @var float - * @required - */ - public $Frames; + /** @required */ + public float $Frames; - /** - * @var int - * @required - */ - public $Type; + /** @required */ + public int $Type; - /** - * @var string - * @required - */ - public $Image; + /** @required */ + public string $Image; - /** - * @var int - * @required - */ - public $AnimationExpression; + /** @required */ + public int $AnimationExpression; } diff --git a/src/network/mcpe/protocol/types/login/ClientDataPersonaPieceTintColor.php b/src/network/mcpe/protocol/types/login/ClientDataPersonaPieceTintColor.php index 676e480cb2..7f4ec45389 100644 --- a/src/network/mcpe/protocol/types/login/ClientDataPersonaPieceTintColor.php +++ b/src/network/mcpe/protocol/types/login/ClientDataPersonaPieceTintColor.php @@ -27,15 +27,12 @@ namespace pocketmine\network\mcpe\protocol\types\login; * Model class for LoginPacket JSON data for JsonMapper */ final class ClientDataPersonaPieceTintColor{ - /** - * @var string - * @required - */ - public $PieceType; + /** @required */ + public string $PieceType; /** * @var string[] * @required */ - public $Colors; -} \ No newline at end of file + public array $Colors; +} diff --git a/src/network/mcpe/protocol/types/login/ClientDataPersonaSkinPiece.php b/src/network/mcpe/protocol/types/login/ClientDataPersonaSkinPiece.php index 6efae72892..6be3026621 100644 --- a/src/network/mcpe/protocol/types/login/ClientDataPersonaSkinPiece.php +++ b/src/network/mcpe/protocol/types/login/ClientDataPersonaSkinPiece.php @@ -27,33 +27,18 @@ namespace pocketmine\network\mcpe\protocol\types\login; * Model class for LoginPacket JSON data for JsonMapper */ final class ClientDataPersonaSkinPiece{ - /** - * @var string - * @required - */ - public $PieceId; + /** @required */ + public string $PieceId; - /** - * @var string - * @required - */ - public $PieceType; + /** @required */ + public string $PieceType; - /** - * @var string - * @required - */ - public $PackId; + /** @required */ + public string $PackId; - /** - * @var bool - * @required - */ - public $IsDefault; + /** @required */ + public bool $IsDefault; - /** - * @var string - * @required - */ - public $ProductId; -} \ No newline at end of file + /** @required */ + public string $ProductId; +} diff --git a/src/network/mcpe/protocol/types/login/JwtBodyRfc7519.php b/src/network/mcpe/protocol/types/login/JwtBodyRfc7519.php index 301779401b..b048e2d9fa 100644 --- a/src/network/mcpe/protocol/types/login/JwtBodyRfc7519.php +++ b/src/network/mcpe/protocol/types/login/JwtBodyRfc7519.php @@ -28,18 +28,12 @@ namespace pocketmine\network\mcpe\protocol\types\login; * provided. */ class JwtBodyRfc7519{ - /** @var string */ - public $iss; - /** @var string */ - public $sub; + public string $iss; + public string $sub; /** @var string|string[] */ public $aud; - /** @var int */ - public $exp; - /** @var int */ - public $nbf; - /** @var int */ - public $iat; - /** @var string */ - public $jti; -} \ No newline at end of file + public int $exp; + public int $nbf; + public int $iat; + public string $jti; +} diff --git a/src/network/mcpe/protocol/types/login/JwtChain.php b/src/network/mcpe/protocol/types/login/JwtChain.php index b8dc21d3b4..357558023d 100644 --- a/src/network/mcpe/protocol/types/login/JwtChain.php +++ b/src/network/mcpe/protocol/types/login/JwtChain.php @@ -32,5 +32,5 @@ final class JwtChain{ * @var string[] * @required */ - public $chain; + public array $chain; } diff --git a/src/network/mcpe/protocol/types/login/JwtChainLinkBody.php b/src/network/mcpe/protocol/types/login/JwtChainLinkBody.php index e3c0c5f187..d547f9c08b 100644 --- a/src/network/mcpe/protocol/types/login/JwtChainLinkBody.php +++ b/src/network/mcpe/protocol/types/login/JwtChainLinkBody.php @@ -28,6 +28,5 @@ namespace pocketmine\network\mcpe\protocol\types\login; * TODO: extend this with more complete models */ final class JwtChainLinkBody extends JwtBodyRfc7519{ - /** @var string */ - public $identityPublicKey; -} \ No newline at end of file + public string $identityPublicKey; +} diff --git a/src/network/mcpe/protocol/types/login/JwtHeader.php b/src/network/mcpe/protocol/types/login/JwtHeader.php index 285f4ca786..f768f17c81 100644 --- a/src/network/mcpe/protocol/types/login/JwtHeader.php +++ b/src/network/mcpe/protocol/types/login/JwtHeader.php @@ -24,14 +24,8 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\login; final class JwtHeader{ - /** - * @var string - * @required - */ - public $alg; - /** - * @var string - * @required - */ - public $x5u; -} \ No newline at end of file + /** @required */ + public string $alg; + /** @required */ + public string $x5u; +} From c05779314db79f290f21a2da41a783d1aea796f2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 7 Feb 2021 20:29:37 +0000 Subject: [PATCH 2291/3224] Allow offline player data to be provided from a custom source --- src/Server.php | 8 ++------ src/network/mcpe/NetworkSession.php | 6 +++++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Server.php b/src/Server.php index 5280bb482b..c3ea14a129 100644 --- a/src/Server.php +++ b/src/Server.php @@ -576,20 +576,16 @@ class Server{ } } - public function createPlayer(NetworkSession $session, PlayerInfo $playerInfo, bool $authenticated) : Player{ + public function createPlayer(NetworkSession $session, PlayerInfo $playerInfo, bool $authenticated, ?CompoundTag $offlinePlayerData) : Player{ $ev = new PlayerCreationEvent($session); $ev->call(); $class = $ev->getPlayerClass(); - //TODO: make this async - //TODO: what about allowing this to be provided by PlayerCreationEvent? - $namedtag = $this->getOfflinePlayerData($playerInfo->getUsername()); - /** * @see Player::__construct() * @var Player $player */ - $player = new $class($this, $session, $playerInfo, $authenticated, $namedtag); + $player = new $class($this, $session, $playerInfo, $authenticated, $offlinePlayerData); return $player; } diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 800869ba90..80d4420499 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -229,7 +229,11 @@ class NetworkSession{ } protected function createPlayer() : void{ - $this->player = $this->server->createPlayer($this, $this->info, $this->authenticated); + //TODO: make this async + //TODO: what about allowing this to be provided by PlayerCreationEvent? + $offlinePlayerData = $this->server->getOfflinePlayerData($this->info->getUsername()); + + $this->player = $this->server->createPlayer($this, $this->info, $this->authenticated, $offlinePlayerData); $this->invManager = new InventoryManager($this->player, $this); From e80c1a0ce91a8ea0197825e749afe559a7ce19dc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 7 Feb 2021 22:02:50 +0000 Subject: [PATCH 2292/3224] Split Mushroom Stem away from other mushroom variants mushroom stem (and all-sided stem) are unique blocks, which don't drop anything and which don't stack with other shroom variants when block-picked. They also get mapped to the same block when placed, and there's no distinction between red mushroom stem and brown mushroom stem. --- src/block/BlockFactory.php | 52 ++++++++++++++++++- src/block/MushroomStem.php | 33 ++++++++++++ src/block/RedMushroomBlock.php | 4 -- src/block/VanillaBlocks.php | 4 ++ .../block_factory_consistency_check.json | 2 +- 5 files changed, 88 insertions(+), 7 deletions(-) create mode 100644 src/block/MushroomStem.php diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 7be95bc418..e2dcf19ee3 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -123,7 +123,6 @@ class BlockFactory{ $this->register(new Opaque(new BID(Ids::BRICK_BLOCK), "Bricks", $bricksBreakInfo)); $this->register(new BrownMushroom(new BID(Ids::BROWN_MUSHROOM), "Brown Mushroom")); - $this->register(new BrownMushroomBlock(new BID(Ids::BROWN_MUSHROOM_BLOCK), "Brown Mushroom Block")); $this->register(new Cactus(new BID(Ids::CACTUS), "Cactus")); $this->register(new Cake(new BID(Ids::CAKE_BLOCK, 0, ItemIds::CAKE), "Cake")); $this->register(new Carrot(new BID(Ids::CARROTS), "Carrot Block")); @@ -279,7 +278,6 @@ class BlockFactory{ $this->register(new Rail(new BID(Ids::RAIL), "Rail")); $this->register(new RedMushroom(new BID(Ids::RED_MUSHROOM), "Red Mushroom")); - $this->register(new RedMushroomBlock(new BID(Ids::RED_MUSHROOM_BLOCK), "Red Mushroom Block")); $this->register(new Redstone(new BID(Ids::REDSTONE_BLOCK), "Redstone Block")); $this->register(new RedstoneComparator(new BIDFlattened(Ids::UNPOWERED_COMPARATOR, Ids::POWERED_COMPARATOR, 0, ItemIds::COMPARATOR, TileComparator::class), "Redstone Comparator")); $this->register(new RedstoneLamp(new BIDFlattened(Ids::REDSTONE_LAMP, Ids::LIT_REDSTONE_LAMP), "Redstone Lamp")); @@ -478,6 +476,9 @@ class BlockFactory{ $this->register(new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_MATERIAL_REDUCER), "Material Reducer", $chemistryTableBreakInfo)); $this->register(new ChemicalHeat(new BID(Ids::CHEMICAL_HEAT), "Heat Block", $chemistryTableBreakInfo)); + + $this->registerMushroomBlocks(); + //region --- auto-generated TODOs for bedrock-1.11.0 --- //TODO: minecraft:bell //TODO: minecraft:blast_furnace @@ -638,6 +639,53 @@ class BlockFactory{ //endregion } + private function registerMushroomBlocks() : void{ + //shrooms have to be handled one by one because some metas are variants and others aren't, and they can't be + //separated by a bitmask + + $mushroomBlockBreakInfo = new BlockBreakInfo(0.2, BlockToolType::AXE); + + $mushroomBlocks = [ + new BrownMushroomBlock(new BID(Ids::BROWN_MUSHROOM_BLOCK), "Brown Mushroom Block", $mushroomBlockBreakInfo), + new RedMushroomBlock(new BID(Ids::RED_MUSHROOM_BLOCK), "Red Mushroom Block", $mushroomBlockBreakInfo) + ]; + + //caps + foreach([ + Meta::MUSHROOM_BLOCK_ALL_PORES, + Meta::MUSHROOM_BLOCK_CAP_NORTHWEST_CORNER, + Meta::MUSHROOM_BLOCK_CAP_NORTH_SIDE, + Meta::MUSHROOM_BLOCK_CAP_NORTHEAST_CORNER, + Meta::MUSHROOM_BLOCK_CAP_WEST_SIDE, + Meta::MUSHROOM_BLOCK_CAP_TOP_ONLY, + Meta::MUSHROOM_BLOCK_CAP_EAST_SIDE, + Meta::MUSHROOM_BLOCK_CAP_SOUTHWEST_CORNER, + Meta::MUSHROOM_BLOCK_CAP_SOUTH_SIDE, + Meta::MUSHROOM_BLOCK_CAP_SOUTHEAST_CORNER, + Meta::MUSHROOM_BLOCK_ALL_CAP, + ] as $meta){ + foreach($mushroomBlocks as $block){ + $block->readStateFromData($block->getId(), $meta); + $this->remap($block->getId(), $meta, clone $block); + } + } + + //and the invalid states + for($meta = 11; $meta <= 13; ++$meta){ + foreach($mushroomBlocks as $block){ + $this->remap($block->getId(), $meta, clone $block); + } + } + + //finally, the stems + $mushroomStem = new MushroomStem(new BID(Ids::BROWN_MUSHROOM_BLOCK, Meta::MUSHROOM_BLOCK_STEM), "Mushroom Stem", $mushroomBlockBreakInfo); + $this->remap(Ids::BROWN_MUSHROOM_BLOCK, Meta::MUSHROOM_BLOCK_STEM, $mushroomStem); + $this->remap(Ids::RED_MUSHROOM_BLOCK, Meta::MUSHROOM_BLOCK_STEM, $mushroomStem); + $allSidedMushroomStem = new MushroomStem(new BID(Ids::BROWN_MUSHROOM_BLOCK, Meta::MUSHROOM_BLOCK_ALL_STEM), "All Sided Mushroom Stem", $mushroomBlockBreakInfo); + $this->remap(Ids::BROWN_MUSHROOM_BLOCK, Meta::MUSHROOM_BLOCK_ALL_STEM, $allSidedMushroomStem); + $this->remap(Ids::RED_MUSHROOM_BLOCK, Meta::MUSHROOM_BLOCK_ALL_STEM, $allSidedMushroomStem); + } + private function registerElements() : void{ $instaBreak = BlockBreakInfo::instant(); $this->register(new Opaque(new BID(Ids::ELEMENT_0), "???", $instaBreak)); diff --git a/src/block/MushroomStem.php b/src/block/MushroomStem.php new file mode 100644 index 0000000000..0544a38d80 --- /dev/null +++ b/src/block/MushroomStem.php @@ -0,0 +1,33 @@ +rotationData; } diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 4b42142702..4cd2e40791 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -48,6 +48,7 @@ use function assert; * @method static Wood ACACIA_WOOD() * @method static ActivatorRail ACTIVATOR_RAIL() * @method static Air AIR() + * @method static MushroomStem ALL_SIDED_MUSHROOM_STEM() * @method static Flower ALLIUM() * @method static Opaque ANDESITE() * @method static Slab ANDESITE_SLAB() @@ -443,6 +444,7 @@ use function assert; * @method static Stair MOSSY_STONE_BRICK_STAIRS() * @method static Wall MOSSY_STONE_BRICK_WALL() * @method static Opaque MOSSY_STONE_BRICKS() + * @method static MushroomStem MUSHROOM_STEM() * @method static Mycelium MYCELIUM() * @method static Fence NETHER_BRICK_FENCE() * @method static Slab NETHER_BRICK_SLAB() @@ -665,6 +667,7 @@ final class VanillaBlocks{ self::register("acacia_wood", $factory->get(467, 4)); self::register("activator_rail", $factory->get(126, 0)); self::register("air", $factory->get(0, 0)); + self::register("all_sided_mushroom_stem", $factory->get(99, 15)); self::register("allium", $factory->get(38, 2)); self::register("andesite", $factory->get(1, 5)); self::register("andesite_slab", $factory->get(417, 3)); @@ -1060,6 +1063,7 @@ final class VanillaBlocks{ self::register("mossy_stone_brick_stairs", $factory->get(430, 0)); self::register("mossy_stone_brick_wall", $factory->get(139, 8)); self::register("mossy_stone_bricks", $factory->get(98, 1)); + self::register("mushroom_stem", $factory->get(99, 10)); self::register("mycelium", $factory->get(110, 0)); self::register("nether_brick_fence", $factory->get(113, 0)); self::register("nether_brick_slab", $factory->get(44, 7)); diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index f70a2a50fc..4f20c9daf1 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Brown Mushroom Block","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"Brown Mushroom Block","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Red Mushroom Block","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Mushroom Stem","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"All Sided Mushroom Stem","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From e061028b696c972e66df3537c9694c94fa1c8972 Mon Sep 17 00:00:00 2001 From: Govdim <50422762+Govdim@users.noreply.github.com> Date: Tue, 9 Feb 2021 19:04:05 +0300 Subject: [PATCH 2293/3224] Added Hopper::setFacing() and Hopper::getFacing() (#4030) --- src/block/Hopper.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/block/Hopper.php b/src/block/Hopper.php index e07f800ddb..f05d82a173 100644 --- a/src/block/Hopper.php +++ b/src/block/Hopper.php @@ -57,6 +57,17 @@ class Hopper extends Transparent{ return 0b1111; } + public function getFacing() : int{ return $this->facing; } + + /** @return $this */ + public function setFacing(int $facing) : self{ + if($facing === Facing::UP){ + throw new \InvalidArgumentException("Hopper may not face upward"); + } + $this->facing = $facing; + return $this; + } + protected function recalculateCollisionBoxes() : array{ $result = [ AxisAlignedBB::one()->trim(Facing::UP, 6 / 16) //the empty area around the bottom is currently considered solid From b03ca1953ab5b46c94e76b0b370d45d374993e06 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 11 Feb 2021 14:07:49 +0000 Subject: [PATCH 2294/3224] Remove usage of Ds\Deque from WritableBookBase ext-ds is not well maintained, and also not very well written. I'm planning to drop this extension for stability's sake. --- src/item/WritableBookBase.php | 47 +++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/item/WritableBookBase.php b/src/item/WritableBookBase.php index 4eda371054..b19de34baf 100644 --- a/src/item/WritableBookBase.php +++ b/src/item/WritableBookBase.php @@ -23,11 +23,14 @@ declare(strict_types=1); namespace pocketmine\item; -use Ds\Deque; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; +use function array_push; +use function array_slice; +use function array_values; +use function count; abstract class WritableBookBase extends Item{ public const TAG_PAGES = "pages"; //TAG_List @@ -35,14 +38,13 @@ abstract class WritableBookBase extends Item{ public const TAG_PAGE_PHOTONAME = "photoname"; //TAG_String - TODO /** - * @var WritableBookPage[]|Deque - * @phpstan-var Deque + * @var WritableBookPage[] + * @phpstan-var list */ - private $pages; + private $pages = []; public function __construct(ItemIdentifier $identifier, string $name){ parent::__construct($identifier, $name); - $this->pages = new Deque(); } /** @@ -71,7 +73,7 @@ abstract class WritableBookBase extends Item{ $this->addPage($pageId); } - $this->pages->set($pageId, new WritableBookPage($pageText)); + $this->pages[$pageId] = new WritableBookPage($pageText); return $this; } @@ -86,8 +88,8 @@ abstract class WritableBookBase extends Item{ throw new \InvalidArgumentException("Page number \"$pageId\" is out of range"); } - for($current = $this->pages->count(); $current <= $pageId; $current++){ - $this->pages->push(new WritableBookPage("")); + for($current = count($this->pages); $current <= $pageId; $current++){ + $this->pages[] = new WritableBookPage(""); } return $this; } @@ -98,7 +100,8 @@ abstract class WritableBookBase extends Item{ * @return $this */ public function deletePage(int $pageId) : self{ - $this->pages->remove($pageId); + unset($this->pages[$pageId]); + $this->pages = array_values($this->pages); return $this; } @@ -108,7 +111,13 @@ abstract class WritableBookBase extends Item{ * @return $this */ public function insertPage(int $pageId, string $pageText = "") : self{ - $this->pages->insert($pageId, new WritableBookPage($pageText)); + if($pageId < 0 || $pageId > count($this->pages)){ + throw new \InvalidArgumentException("Page ID must not be negative"); + } + $newPages = array_slice($this->pages, 0, $pageId); + $newPages[] = new WritableBookPage($pageText); + array_push($newPages, ...array_slice($this->pages, $pageId)); + $this->pages = $newPages; return $this; } @@ -137,7 +146,7 @@ abstract class WritableBookBase extends Item{ * @return WritableBookPage[] */ public function getPages() : array{ - return $this->pages->toArray(); + return $this->pages; } /** @@ -146,25 +155,25 @@ abstract class WritableBookBase extends Item{ * @return $this */ public function setPages(array $pages) : self{ - $this->pages = new Deque($pages); + $this->pages = array_values($pages); return $this; } protected function deserializeCompoundTag(CompoundTag $tag) : void{ parent::deserializeCompoundTag($tag); - $this->pages = new Deque(); + $this->pages = []; $pages = $tag->getListTag(self::TAG_PAGES); if($pages !== null){ if($pages->getTagType() === NBT::TAG_Compound){ //PE format /** @var CompoundTag $page */ foreach($pages as $page){ - $this->pages->push(new WritableBookPage($page->getString(self::TAG_PAGE_TEXT), $page->getString(self::TAG_PAGE_PHOTONAME, ""))); + $this->pages[] = new WritableBookPage($page->getString(self::TAG_PAGE_TEXT), $page->getString(self::TAG_PAGE_PHOTONAME, "")); } }elseif($pages->getTagType() === NBT::TAG_String){ //PC format /** @var StringTag $page */ foreach($pages as $page){ - $this->pages->push(new WritableBookPage($page->getValue())); + $this->pages[] = new WritableBookPage($page->getValue()); } } } @@ -172,7 +181,7 @@ abstract class WritableBookBase extends Item{ protected function serializeCompoundTag(CompoundTag $tag) : void{ parent::serializeCompoundTag($tag); - if(!$this->pages->isEmpty()){ + if(count($this->pages) > 0){ $pages = new ListTag(); foreach($this->pages as $page){ $pages->push(CompoundTag::create() @@ -185,10 +194,4 @@ abstract class WritableBookBase extends Item{ $tag->removeTag(self::TAG_PAGES); } } - - public function __clone(){ - parent::__clone(); - //no need to deep-copy each page, the objects are immutable - $this->pages = $this->pages->copy(); - } } From c61f66d973ba4827e6a0a5df462716329de5267d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 11 Feb 2021 15:40:37 +0000 Subject: [PATCH 2295/3224] Removed ext-ds dependency --- composer.json | 1 - composer.lock | 3 +- phpstan.neon.dist | 1 - src/PocketMine.php | 1 - src/crafting/CraftingManager.php | 12 ++-- src/crafting/FurnaceRecipeManager.php | 12 ++-- src/entity/effect/EffectManager.php | 26 ++++---- src/inventory/BaseInventory.php | 10 +-- src/inventory/Inventory.php | 8 +-- src/inventory/PlayerInventory.php | 14 ++--- src/item/Item.php | 61 +++++++++--------- src/network/mcpe/NetworkSession.php | 8 +-- src/permission/Permissible.php | 8 +-- src/permission/PermissibleBase.php | 14 ++--- src/permission/PermissibleDelegateTrait.php | 8 +-- src/scheduler/TaskScheduler.php | 8 +-- src/utils/DestructorCallbackTrait.php | 12 ++-- src/utils/ObjectSet.php | 70 +++++++++++++++++++++ tests/phpstan/configs/phpstan-bugs.neon | 60 ++++++++++++++++++ 19 files changed, 231 insertions(+), 106 deletions(-) create mode 100644 src/utils/ObjectSet.php diff --git a/composer.json b/composer.json index 676553a749..8c82ca36e8 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,6 @@ "ext-ctype": "*", "ext-curl": "*", "ext-date": "*", - "ext-ds": "^1.2.7", "ext-gmp": "*", "ext-hash": "*", "ext-igbinary": "^3.0.1", diff --git a/composer.lock b/composer.lock index 52454f969b..8129a33e7d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "18b4c55f8ac6014140b7fa575b6795bb", + "content-hash": "2032ba311a20918843c0cbffdc6058e4", "packages": [ { "name": "adhocore/json-comment", @@ -3333,7 +3333,6 @@ "ext-ctype": "*", "ext-curl": "*", "ext-date": "*", - "ext-ds": "^1.2.7", "ext-gmp": "*", "ext-hash": "*", "ext-igbinary": "^3.0.1", diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 6ac4a2b95b..4175fb24df 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -2,7 +2,6 @@ includes: - tests/phpstan/configs/actual-problems.neon - tests/phpstan/configs/check-explicit-mixed-baseline.neon - tests/phpstan/configs/com-dotnet-magic.neon - - tests/phpstan/configs/ds-bugs.neon - tests/phpstan/configs/gc-hacks.neon - tests/phpstan/configs/impossible-generics.neon - tests/phpstan/configs/l7-baseline.neon diff --git a/src/PocketMine.php b/src/PocketMine.php index 5740b20cf1..09908d97db 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -79,7 +79,6 @@ namespace pocketmine { "crypto" => "php-crypto", "ctype" => "ctype", "date" => "Date", - "ds" => "Data Structures", "gmp" => "GMP", "hash" => "Hash", "igbinary" => "igbinary", diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index b6720a3e9c..7094805063 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace pocketmine\crafting; -use Ds\Set; use pocketmine\item\Item; use pocketmine\utils\DestructorCallbackTrait; +use pocketmine\utils\ObjectSet; use function json_encode; use function usort; @@ -41,13 +41,13 @@ class CraftingManager{ protected $furnaceRecipeManager; /** - * @var Set - * @phpstan-var Set<\Closure() : void> + * @var ObjectSet + * @phpstan-var ObjectSet<\Closure() : void> */ private $recipeRegisteredCallbacks; public function __construct(){ - $this->recipeRegisteredCallbacks = new Set(); + $this->recipeRegisteredCallbacks = new ObjectSet(); $this->furnaceRecipeManager = new FurnaceRecipeManager(); $this->furnaceRecipeManager->getRecipeRegisteredCallbacks()->add(function(FurnaceRecipe $recipe) : void{ foreach($this->recipeRegisteredCallbacks as $callback){ @@ -56,8 +56,8 @@ class CraftingManager{ }); } - /** @phpstan-return Set<\Closure() : void> */ - public function getRecipeRegisteredCallbacks() : Set{ return $this->recipeRegisteredCallbacks; } + /** @phpstan-return ObjectSet<\Closure() : void> */ + public function getRecipeRegisteredCallbacks() : ObjectSet{ return $this->recipeRegisteredCallbacks; } /** * Function used to arrange Shapeless Recipe ingredient lists into a consistent order. diff --git a/src/crafting/FurnaceRecipeManager.php b/src/crafting/FurnaceRecipeManager.php index 18b5204765..9cb9c6eef1 100644 --- a/src/crafting/FurnaceRecipeManager.php +++ b/src/crafting/FurnaceRecipeManager.php @@ -23,27 +23,27 @@ declare(strict_types=1); namespace pocketmine\crafting; -use Ds\Set; use pocketmine\item\Item; +use pocketmine\utils\ObjectSet; final class FurnaceRecipeManager{ /** @var FurnaceRecipe[] */ protected $furnaceRecipes = []; /** - * @var Set - * @phpstan-var Set<\Closure(FurnaceRecipe) : void> + * @var ObjectSet + * @phpstan-var ObjectSet<\Closure(FurnaceRecipe) : void> */ private $recipeRegisteredCallbacks; public function __construct(){ - $this->recipeRegisteredCallbacks = new Set(); + $this->recipeRegisteredCallbacks = new ObjectSet(); } /** - * @phpstan-return Set<\Closure(FurnaceRecipe) : void> + * @phpstan-return ObjectSet<\Closure(FurnaceRecipe) : void> */ - public function getRecipeRegisteredCallbacks() : Set{ + public function getRecipeRegisteredCallbacks() : ObjectSet{ return $this->recipeRegisteredCallbacks; } diff --git a/src/entity/effect/EffectManager.php b/src/entity/effect/EffectManager.php index 93404120a0..d9933d16dd 100644 --- a/src/entity/effect/EffectManager.php +++ b/src/entity/effect/EffectManager.php @@ -23,11 +23,11 @@ declare(strict_types=1); namespace pocketmine\entity\effect; -use Ds\Set; use pocketmine\color\Color; use pocketmine\entity\Living; use pocketmine\event\entity\EntityEffectAddEvent; use pocketmine\event\entity\EntityEffectRemoveEvent; +use pocketmine\utils\ObjectSet; use function abs; use function count; @@ -45,21 +45,21 @@ class EffectManager{ protected $onlyAmbientEffects = false; /** - * @var \Closure[]|Set - * @phpstan-var Set<\Closure(EffectInstance, bool $replacesOldEffect) : void> + * @var \Closure[]|ObjectSet + * @phpstan-var ObjectSet<\Closure(EffectInstance, bool $replacesOldEffect) : void> */ protected $effectAddHooks; /** - * @var \Closure[]|Set - * @phpstan-var Set<\Closure(EffectInstance) : void> + * @var \Closure[]|ObjectSet + * @phpstan-var ObjectSet<\Closure(EffectInstance) : void> */ protected $effectRemoveHooks; public function __construct(Living $entity){ $this->entity = $entity; $this->bubbleColor = new Color(0, 0, 0, 0); - $this->effectAddHooks = new Set(); - $this->effectRemoveHooks = new Set(); + $this->effectAddHooks = new ObjectSet(); + $this->effectRemoveHooks = new ObjectSet(); } /** @@ -225,18 +225,18 @@ class EffectManager{ } /** - * @return \Closure[]|Set - * @phpstan-return Set<\Closure(EffectInstance, bool $replacesOldEffect) : void> + * @return \Closure[]|ObjectSet + * @phpstan-return ObjectSet<\Closure(EffectInstance, bool $replacesOldEffect) : void> */ - public function getEffectAddHooks() : Set{ + public function getEffectAddHooks() : ObjectSet{ return $this->effectAddHooks; } /** - * @return \Closure[]|Set - * @phpstan-return Set<\Closure(EffectInstance) : void> + * @return \Closure[]|ObjectSet + * @phpstan-return ObjectSet<\Closure(EffectInstance) : void> */ - public function getEffectRemoveHooks() : Set{ + public function getEffectRemoveHooks() : ObjectSet{ return $this->effectRemoveHooks; } } diff --git a/src/inventory/BaseInventory.php b/src/inventory/BaseInventory.php index 70c03f2b06..5e2ed288cc 100644 --- a/src/inventory/BaseInventory.php +++ b/src/inventory/BaseInventory.php @@ -23,10 +23,10 @@ declare(strict_types=1); namespace pocketmine\inventory; -use Ds\Set; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\player\Player; +use pocketmine\utils\ObjectSet; use function array_map; use function array_slice; use function count; @@ -46,14 +46,14 @@ abstract class BaseInventory implements Inventory{ /** @var Player[] */ protected $viewers = []; /** - * @var InventoryListener[]|Set - * @phpstan-var Set + * @var InventoryListener[]|ObjectSet + * @phpstan-var ObjectSet */ protected $listeners; public function __construct(int $size){ $this->slots = new \SplFixedArray($size); - $this->listeners = new Set(); + $this->listeners = new ObjectSet(); } /** @@ -380,7 +380,7 @@ abstract class BaseInventory implements Inventory{ return $slot >= 0 and $slot < $this->slots->getSize(); } - public function getListeners() : Set{ + public function getListeners() : ObjectSet{ return $this->listeners; } } diff --git a/src/inventory/Inventory.php b/src/inventory/Inventory.php index e2226f82fc..0a5e3b7666 100644 --- a/src/inventory/Inventory.php +++ b/src/inventory/Inventory.php @@ -26,9 +26,9 @@ declare(strict_types=1); */ namespace pocketmine\inventory; -use Ds\Set; use pocketmine\item\Item; use pocketmine\player\Player; +use pocketmine\utils\ObjectSet; interface Inventory{ public const MAX_STACK = 64; @@ -156,8 +156,8 @@ interface Inventory{ public function slotExists(int $slot) : bool; /** - * @return InventoryListener[]|Set - * @phpstan-return Set + * @return InventoryListener[]|ObjectSet + * @phpstan-return ObjectSet */ - public function getListeners() : Set; + public function getListeners() : ObjectSet; } diff --git a/src/inventory/PlayerInventory.php b/src/inventory/PlayerInventory.php index 07befe054f..4f76ec258e 100644 --- a/src/inventory/PlayerInventory.php +++ b/src/inventory/PlayerInventory.php @@ -23,10 +23,10 @@ declare(strict_types=1); namespace pocketmine\inventory; -use Ds\Set; use pocketmine\entity\Human; use pocketmine\item\Item; use pocketmine\player\Player; +use pocketmine\utils\ObjectSet; class PlayerInventory extends BaseInventory{ @@ -37,14 +37,14 @@ class PlayerInventory extends BaseInventory{ protected $itemInHandIndex = 0; /** - * @var \Closure[]|Set - * @phpstan-var Set<\Closure(int $oldIndex) : void> + * @var \Closure[]|ObjectSet + * @phpstan-var ObjectSet<\Closure(int $oldIndex) : void> */ protected $heldItemIndexChangeListeners; public function __construct(Human $player){ $this->holder = $player; - $this->heldItemIndexChangeListeners = new Set(); + $this->heldItemIndexChangeListeners = new ObjectSet(); parent::__construct(36); } @@ -97,10 +97,10 @@ class PlayerInventory extends BaseInventory{ } /** - * @return \Closure[]|Set - * @phpstan-return Set<\Closure(int $oldIndex) : void> + * @return \Closure[]|ObjectSet + * @phpstan-return ObjectSet<\Closure(int $oldIndex) : void> */ - public function getHeldItemIndexChangeListeners() : Set{ return $this->heldItemIndexChangeListeners; } + public function getHeldItemIndexChangeListeners() : ObjectSet{ return $this->heldItemIndexChangeListeners; } /** * Returns the currently-held item. diff --git a/src/item/Item.php b/src/item/Item.php index 76989bcc5b..afa34d8c82 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -26,7 +26,6 @@ declare(strict_types=1); */ namespace pocketmine\item; -use Ds\Set; use pocketmine\block\Block; use pocketmine\block\BlockBreakInfo; use pocketmine\block\BlockToolType; @@ -86,13 +85,13 @@ class Item implements \JsonSerializable{ protected $blockEntityTag = null; /** - * @var Set|string[] - * @phpstan-var Set + * @var string[] + * @phpstan-var array */ - protected $canPlaceOn; + protected $canPlaceOn = []; /** - * @var Set|string[] - * @phpstan-var Set + * @var string[] + * @phpstan-var array */ protected $canDestroy; @@ -107,8 +106,8 @@ class Item implements \JsonSerializable{ $this->identifier = $identifier; $this->name = $name; - $this->canPlaceOn = new Set(); - $this->canDestroy = new Set(); + $this->canPlaceOn = []; + $this->canDestroy = []; $this->nbt = new CompoundTag(); } @@ -186,35 +185,39 @@ class Item implements \JsonSerializable{ } /** - * @return Set|string[] - * @phpstan-return Set + * @return string[] + * @phpstan-return array */ - public function getCanPlaceOn() : Set{ + public function getCanPlaceOn() : array{ return $this->canPlaceOn; } /** - * @param Set|string[] $canPlaceOn - * @phpstan-param Set $canPlaceOn + * @param string[] $canPlaceOn */ - public function setCanPlaceOn(Set $canPlaceOn) : void{ - $this->canPlaceOn = $canPlaceOn; + public function setCanPlaceOn(array $canPlaceOn) : void{ + $this->canPlaceOn = []; + foreach($canPlaceOn as $value){ + $this->canPlaceOn[$value] = $value; + } } /** - * @return Set|string[] - * @phpstan-return Set + * @return string[] + * @phpstan-return array */ - public function getCanDestroy() : Set{ + public function getCanDestroy() : array{ return $this->canDestroy; } /** - * @param Set|string[] $canDestroy - * @phpstan-param Set $canDestroy + * @param string[] $canDestroy */ - public function setCanDestroy(Set $canDestroy) : void{ - $this->canDestroy = $canDestroy; + public function setCanDestroy(array $canDestroy) : void{ + $this->canDestroy = []; + foreach($canDestroy as $value){ + $this->canDestroy[$value] = $value; + } } /** @@ -294,20 +297,20 @@ class Item implements \JsonSerializable{ $this->blockEntityTag = $tag->getCompoundTag(self::TAG_BLOCK_ENTITY_TAG); - $this->canPlaceOn = new Set(); + $this->canPlaceOn = []; $canPlaceOn = $tag->getListTag("CanPlaceOn"); if($canPlaceOn !== null){ /** @var StringTag $entry */ foreach($canPlaceOn as $entry){ - $this->canPlaceOn->add($entry->getValue()); + $this->canPlaceOn[$entry->getValue()] = $entry->getValue(); } } - $this->canDestroy = new Set(); + $this->canDestroy = []; $canDestroy = $tag->getListTag("CanDestroy"); if($canDestroy !== null){ /** @var StringTag $entry */ foreach($canDestroy as $entry){ - $this->canDestroy->add($entry->getValue()); + $this->canDestroy[$entry->getValue()] = $entry->getValue(); } } } @@ -349,7 +352,7 @@ class Item implements \JsonSerializable{ $tag->setTag(self::TAG_BLOCK_ENTITY_TAG, clone $blockData) : $tag->removeTag(self::TAG_BLOCK_ENTITY_TAG); - if(!$this->canPlaceOn->isEmpty()){ + if(count($this->canPlaceOn) > 0){ $canPlaceOn = new ListTag(); foreach($this->canPlaceOn as $item){ $canPlaceOn->push(new StringTag($item)); @@ -358,7 +361,7 @@ class Item implements \JsonSerializable{ }else{ $tag->removeTag("CanPlaceOn"); } - if(!$this->canDestroy->isEmpty()){ + if(count($this->canDestroy) > 0){ $canDestroy = new ListTag(); foreach($this->canDestroy as $item){ $canDestroy->push(new StringTag($item)); @@ -691,7 +694,5 @@ class Item implements \JsonSerializable{ if($this->blockEntityTag !== null){ $this->blockEntityTag = clone $this->blockEntityTag; } - $this->canPlaceOn = $this->canPlaceOn->copy(); - $this->canDestroy = $this->canDestroy->copy(); } } diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index cc33695e69..501c5f1be4 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; -use Ds\Set; use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; use pocketmine\data\bedrock\EffectIdMap; use pocketmine\entity\Attribute; @@ -103,6 +102,7 @@ use pocketmine\player\PlayerInfo; use pocketmine\player\XboxLivePlayerInfo; use pocketmine\Server; use pocketmine\timings\Timings; +use pocketmine\utils\ObjectSet; use pocketmine\utils\TextFormat; use pocketmine\utils\Utils; use pocketmine\world\Position; @@ -184,8 +184,8 @@ class NetworkSession{ private $broadcaster; /** - * @var \Closure[]|Set - * @phpstan-var Set<\Closure() : void> + * @var \Closure[]|ObjectSet + * @phpstan-var ObjectSet<\Closure() : void> */ private $disposeHooks; @@ -203,7 +203,7 @@ class NetworkSession{ $this->compressor = $compressor; $this->packetPool = $packetPool; - $this->disposeHooks = new Set(); + $this->disposeHooks = new ObjectSet(); $this->connectTime = time(); diff --git a/src/permission/Permissible.php b/src/permission/Permissible.php index 5fca2b14f7..81fc23fea8 100644 --- a/src/permission/Permissible.php +++ b/src/permission/Permissible.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\permission; -use Ds\Set; use pocketmine\plugin\Plugin; +use pocketmine\utils\ObjectSet; interface Permissible{ @@ -73,10 +73,10 @@ interface Permissible{ public function recalculatePermissions() : array; /** - * @return Set|\Closure[] - * @phpstan-return Set<\Closure(array $changedPermissionsOldValues) : void> + * @return ObjectSet|\Closure[] + * @phpstan-return ObjectSet<\Closure(array $changedPermissionsOldValues) : void> */ - public function getPermissionRecalculationCallbacks() : Set; + public function getPermissionRecalculationCallbacks() : ObjectSet; /** * @return PermissionAttachmentInfo[] diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index 0f8f82163d..a1b43bfd34 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -23,10 +23,10 @@ declare(strict_types=1); namespace pocketmine\permission; -use Ds\Set; use pocketmine\plugin\Plugin; use pocketmine\plugin\PluginException; use pocketmine\timings\Timings; +use pocketmine\utils\ObjectSet; use function count; use function spl_object_id; @@ -44,8 +44,8 @@ class PermissibleBase implements Permissible{ private $permissions = []; /** - * @var Set|\Closure[] - * @phpstan-var Set<\Closure(array $changedPermissionsOldValues) : void> + * @var ObjectSet|\Closure[] + * @phpstan-var ObjectSet<\Closure(array $changedPermissionsOldValues) : void> */ private $permissionRecalculationCallbacks; @@ -54,7 +54,7 @@ class PermissibleBase implements Permissible{ * @phpstan-param array $basePermissions */ public function __construct(array $basePermissions){ - $this->permissionRecalculationCallbacks = new Set(); + $this->permissionRecalculationCallbacks = new ObjectSet(); //TODO: we can't setBasePermission here directly due to bad architecture that causes recalculatePermissions to explode //so, this hack has to be done here to prevent permission recalculations until it's fixed... @@ -198,10 +198,10 @@ class PermissibleBase implements Permissible{ } /** - * @return \Closure[]|Set - * @phpstan-return Set<\Closure(array $changedPermissionsOldValues) : void> + * @return \Closure[]|ObjectSet + * @phpstan-return ObjectSet<\Closure(array $changedPermissionsOldValues) : void> */ - public function getPermissionRecalculationCallbacks() : Set{ return $this->permissionRecalculationCallbacks; } + public function getPermissionRecalculationCallbacks() : ObjectSet{ return $this->permissionRecalculationCallbacks; } /** * @return PermissionAttachmentInfo[] diff --git a/src/permission/PermissibleDelegateTrait.php b/src/permission/PermissibleDelegateTrait.php index e38762efe6..be3e8da91e 100644 --- a/src/permission/PermissibleDelegateTrait.php +++ b/src/permission/PermissibleDelegateTrait.php @@ -23,8 +23,8 @@ declare(strict_types=1); namespace pocketmine\permission; -use Ds\Set; use pocketmine\plugin\Plugin; +use pocketmine\utils\ObjectSet; trait PermissibleDelegateTrait{ @@ -72,10 +72,10 @@ trait PermissibleDelegateTrait{ } /** - * @return Set|\Closure[] - * @phpstan-return Set<\Closure(array $changedPermissionsOldValues) : void> + * @return ObjectSet|\Closure[] + * @phpstan-return ObjectSet<\Closure(array $changedPermissionsOldValues) : void> */ - public function getPermissionRecalculationCallbacks() : Set{ + public function getPermissionRecalculationCallbacks() : ObjectSet{ return $this->perm->getPermissionRecalculationCallbacks(); } diff --git a/src/scheduler/TaskScheduler.php b/src/scheduler/TaskScheduler.php index 32d2d27848..9b1eb9c9f3 100644 --- a/src/scheduler/TaskScheduler.php +++ b/src/scheduler/TaskScheduler.php @@ -27,7 +27,7 @@ declare(strict_types=1); namespace pocketmine\scheduler; -use Ds\Set; +use pocketmine\utils\ObjectSet; use pocketmine\utils\ReversePriorityQueue; class TaskScheduler{ @@ -44,8 +44,8 @@ class TaskScheduler{ protected $queue; /** - * @var Set|TaskHandler[] - * @phpstan-var Set + * @var ObjectSet|TaskHandler[] + * @phpstan-var ObjectSet */ protected $tasks; @@ -55,7 +55,7 @@ class TaskScheduler{ public function __construct(?string $owner = null){ $this->owner = $owner; $this->queue = new ReversePriorityQueue(); - $this->tasks = new Set(); + $this->tasks = new ObjectSet(); } public function scheduleTask(Task $task) : TaskHandler{ diff --git a/src/utils/DestructorCallbackTrait.php b/src/utils/DestructorCallbackTrait.php index 63e3e34024..3653cfa05d 100644 --- a/src/utils/DestructorCallbackTrait.php +++ b/src/utils/DestructorCallbackTrait.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\utils; -use Ds\Set; - /** * This trait provides destructor callback functionality to objects which use it. This enables a weakmap-like system * to function without actually having weak maps. @@ -32,14 +30,14 @@ use Ds\Set; */ trait DestructorCallbackTrait{ /** - * @var Set - * @phpstan-var Set<\Closure() : void>|null + * @var ObjectSet + * @phpstan-var ObjectSet<\Closure() : void>|null */ private $destructorCallbacks = null; - /** @phpstan-return Set<\Closure() : void> */ - public function getDestructorCallbacks() : Set{ - return $this->destructorCallbacks === null ? ($this->destructorCallbacks = new Set()) : $this->destructorCallbacks; + /** @phpstan-return ObjectSet<\Closure() : void> */ + public function getDestructorCallbacks() : ObjectSet{ + return $this->destructorCallbacks === null ? ($this->destructorCallbacks = new ObjectSet()) : $this->destructorCallbacks; } public function __destruct(){ diff --git a/src/utils/ObjectSet.php b/src/utils/ObjectSet.php new file mode 100644 index 0000000000..adb0ad1c27 --- /dev/null +++ b/src/utils/ObjectSet.php @@ -0,0 +1,70 @@ + + */ +final class ObjectSet implements \IteratorAggregate{ + /** + * @var object[] + * @phpstan-var array + */ + private array $objects = []; + + /** @phpstan-param T $object */ + public function add(object $object) : void{ + $this->objects[spl_object_id($object)] = $object; + } + + /** @phpstan-param T $object */ + public function remove(object $object) : void{ + unset($this->objects[spl_object_id($object)]); + } + + public function clear() : void{ + $this->objects = []; + } + + public function contains(object $object) : bool{ + return array_key_exists(spl_object_id($object), $this->objects); + } + + /** @phpstan-return \ArrayIterator */ + public function getIterator() : \ArrayIterator{ + return new \ArrayIterator($this->objects); + } + + /** + * @return object[] + * @phpstan-return array + */ + public function toArray() : array{ + return $this->objects; + } +} diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 815c53ec0f..1b42267f8e 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -15,11 +15,71 @@ parameters: count: 3 path: ../../../src/command/CommandReader.php + - + message: "#^Property pocketmine\\\\crafting\\\\CraftingManager\\:\\:\\$recipeRegisteredCallbacks \\(pocketmine\\\\utils\\\\ObjectSet\\\\) does not accept pocketmine\\\\utils\\\\ObjectSet\\\\.$#" + count: 1 + path: ../../../src/crafting/CraftingManager.php + + - + message: "#^Method pocketmine\\\\crafting\\\\CraftingManager\\:\\:getDestructorCallbacks\\(\\) should return pocketmine\\\\utils\\\\ObjectSet\\ but returns pocketmine\\\\utils\\\\ObjectSet\\\\|pocketmine\\\\utils\\\\ObjectSet\\\\.$#" + count: 1 + path: ../../../src/crafting/CraftingManager.php + + - + message: "#^Property pocketmine\\\\crafting\\\\CraftingManager\\:\\:\\$destructorCallbacks \\(pocketmine\\\\utils\\\\ObjectSet\\\\|null\\) does not accept pocketmine\\\\utils\\\\ObjectSet\\\\.$#" + count: 1 + path: ../../../src/crafting/CraftingManager.php + + - + message: "#^Property pocketmine\\\\crafting\\\\FurnaceRecipeManager\\:\\:\\$recipeRegisteredCallbacks \\(pocketmine\\\\utils\\\\ObjectSet\\\\) does not accept pocketmine\\\\utils\\\\ObjectSet\\\\.$#" + count: 1 + path: ../../../src/crafting/FurnaceRecipeManager.php + + - + message: "#^Undefined variable\\: \\$blockstate$#" + count: 1 + path: ../../../src/data/bedrock/blockstate/BlockStateDeserializerR13.php + + - + message: "#^Property pocketmine\\\\entity\\\\effect\\\\EffectManager\\:\\:\\$effectAddHooks \\(pocketmine\\\\utils\\\\ObjectSet\\\\) does not accept pocketmine\\\\utils\\\\ObjectSet\\\\.$#" + count: 1 + path: ../../../src/entity/effect/EffectManager.php + + - + message: "#^Property pocketmine\\\\entity\\\\effect\\\\EffectManager\\:\\:\\$effectRemoveHooks \\(pocketmine\\\\utils\\\\ObjectSet\\\\) does not accept pocketmine\\\\utils\\\\ObjectSet\\\\.$#" + count: 1 + path: ../../../src/entity/effect/EffectManager.php + - message: "#^Call to function assert\\(\\) with false and 'unknown hit type' will always evaluate to false\\.$#" count: 1 path: ../../../src/entity/projectile/Projectile.php + - + message: "#^Property pocketmine\\\\inventory\\\\BaseInventory\\:\\:\\$listeners \\(pocketmine\\\\utils\\\\ObjectSet\\\\) does not accept pocketmine\\\\utils\\\\ObjectSet\\\\.$#" + count: 1 + path: ../../../src/inventory/BaseInventory.php + + - + message: "#^Property pocketmine\\\\inventory\\\\PlayerInventory\\:\\:\\$heldItemIndexChangeListeners \\(pocketmine\\\\utils\\\\ObjectSet\\\\) does not accept pocketmine\\\\utils\\\\ObjectSet\\\\.$#" + count: 1 + path: ../../../src/inventory/PlayerInventory.php + + - + message: "#^Property pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:\\$disposeHooks \\(pocketmine\\\\utils\\\\ObjectSet\\\\) does not accept pocketmine\\\\utils\\\\ObjectSet\\\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Property pocketmine\\\\permission\\\\PermissibleBase\\:\\:\\$permissionRecalculationCallbacks \\(pocketmine\\\\utils\\\\ObjectSet\\\\)\\: void\\>\\) does not accept pocketmine\\\\utils\\\\ObjectSet\\\\.$#" + count: 1 + path: ../../../src/permission/PermissibleBase.php + + - + message: "#^Property pocketmine\\\\scheduler\\\\TaskScheduler\\:\\:\\$tasks \\(pocketmine\\\\utils\\\\ObjectSet\\\\) does not accept pocketmine\\\\utils\\\\ObjectSet\\\\.$#" + count: 1 + path: ../../../src/scheduler/TaskScheduler.php + - message: "#^Strict comparison using \\=\\=\\= between string and false will always evaluate to false\\.$#" count: 1 From 672622950f861fd7d989208a34469f8dbdeaece1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 11 Feb 2021 15:54:05 +0000 Subject: [PATCH 2296/3224] ObjectSet: make add() and remove() variadic to match ds there are still some variadic usages in the code, which, infuriatingly, phpstan does not detect (phpstan/phpstan#4528). --- src/utils/ObjectSet.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/utils/ObjectSet.php b/src/utils/ObjectSet.php index adb0ad1c27..0b6b0049d6 100644 --- a/src/utils/ObjectSet.php +++ b/src/utils/ObjectSet.php @@ -37,14 +37,18 @@ final class ObjectSet implements \IteratorAggregate{ */ private array $objects = []; - /** @phpstan-param T $object */ - public function add(object $object) : void{ - $this->objects[spl_object_id($object)] = $object; + /** @phpstan-param T ...$objects */ + public function add(object ...$objects) : void{ + foreach($objects as $object){ + $this->objects[spl_object_id($object)] = $object; + } } - /** @phpstan-param T $object */ - public function remove(object $object) : void{ - unset($this->objects[spl_object_id($object)]); + /** @phpstan-param T ...$objects */ + public function remove(object ...$objects) : void{ + foreach($objects as $object){ + unset($this->objects[spl_object_id($object)]); + } } public function clear() : void{ From 298034549ef53d64945c7c5bff3fd9c311a1c453 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 11 Feb 2021 15:56:19 +0000 Subject: [PATCH 2297/3224] actions: drop ext-ds from PHP build --- tests/gh-actions/build.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/gh-actions/build.sh b/tests/gh-actions/build.sh index 35639d22d6..344894a83b 100755 --- a/tests/gh-actions/build.sh +++ b/tests/gh-actions/build.sh @@ -56,7 +56,6 @@ leveldb=@2e3f740b55af1eb6dfc648dd451bcb7d6151c26c \ chunkutils2=@5a4dcd6ed74e0db2ca9a54948d4f3a065e386db5 \ morton=@0.1.2 \ igbinary=3.1.4 \ -ds=1.3.0 \ " PHP_BUILD_ZTS_ENABLE=on PHP_BUILD_CONFIGURE_OPTS='--with-gmp' ./bin/php-build "$VERSION" "$INSTALL_DIR" rm -rf crypto From de0766dbef26f92d8dec73d4ebe434d606ab0d81 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 11 Feb 2021 16:48:10 +0000 Subject: [PATCH 2298/3224] actions: update PM4-specific extensions to PHP 8.0 compatible versions --- tests/gh-actions/build.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/gh-actions/build.sh b/tests/gh-actions/build.sh index 71539a93a6..e99edb0c11 100755 --- a/tests/gh-actions/build.sh +++ b/tests/gh-actions/build.sh @@ -52,16 +52,16 @@ echo '"morton",,"https://github.com/pmmp/ext-morton.git",,,"extension",' >> shar PHP_BUILD_INSTALL_EXTENSION="\ pthreads=@acc6e52b2144c61c434b62a3cb680d537e06828e \ yaml=2.2.1 \ -leveldb=@2e3f740b55af1eb6dfc648dd451bcb7d6151c26c \ -chunkutils2=@5a4dcd6ed74e0db2ca9a54948d4f3a065e386db5 \ +leveldb=@e153cf26de8dc68aed6185ab494892e4b6ce249d \ +chunkutils2=@7aec31a9dfc83ddead8870dc0a29159596939680 \ morton=@0.1.2 \ -igbinary=3.1.4 \ +igbinary=3.2.1 \ " PHP_BUILD_ZTS_ENABLE=on PHP_BUILD_CONFIGURE_OPTS='--with-gmp' ./bin/php-build "$VERSION" "$INSTALL_DIR" rm -rf crypto git clone --recursive https://github.com/bukka/php-crypto.git crypto cd crypto -git checkout -qf 5f26ac91b0ba96742cc6284cd00f8db69c3788b2 +git checkout -qf c8867aa944fa5227eaea9d11a6ce282e64c15af9 git submodule update --init --recursive "$INSTALL_DIR/bin/phpize" ./configure --with-php-config="$INSTALL_DIR/bin/php-config" From c21ec614fc100aa407e899f6b7d8054969f164c4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 11 Feb 2021 16:54:14 +0000 Subject: [PATCH 2299/3224] Fixed PHPStan 0.12.74 error in WorldManager --- src/world/WorldManager.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index fe4f992e10..16ad8b86bf 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -199,11 +199,11 @@ class WorldManager{ } $providerClass = array_shift($providers); - /** - * @var WorldProvider $provider - * @see WorldProvider::__construct() - */ try{ + /** + * @var WorldProvider $provider + * @see WorldProvider::__construct() + */ $provider = new $providerClass($path); }catch(CorruptedWorldException $e){ $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.level.loadError", [$name, "Corruption detected: " . $e->getMessage()])); From fd5141745d9a96c43a18669ad86ee7dd4ba9d4d7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 11 Feb 2021 17:01:10 +0000 Subject: [PATCH 2300/3224] Use a valid commit hash for pmmp/leveldb the previous one pointed to the main repository, and not the pmmp fork. (Why am I maintaining a fork again? ...) --- tests/gh-actions/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/gh-actions/build.sh b/tests/gh-actions/build.sh index e99edb0c11..436d6bc939 100755 --- a/tests/gh-actions/build.sh +++ b/tests/gh-actions/build.sh @@ -52,7 +52,7 @@ echo '"morton",,"https://github.com/pmmp/ext-morton.git",,,"extension",' >> shar PHP_BUILD_INSTALL_EXTENSION="\ pthreads=@acc6e52b2144c61c434b62a3cb680d537e06828e \ yaml=2.2.1 \ -leveldb=@e153cf26de8dc68aed6185ab494892e4b6ce249d \ +leveldb=@60763a09bf5c7a10376d16e25b078b99a35c5c37 \ chunkutils2=@7aec31a9dfc83ddead8870dc0a29159596939680 \ morton=@0.1.2 \ igbinary=3.2.1 \ From 8dd61df7ac5bb7babe444533c26c5f40b1a49477 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 16 Feb 2021 20:38:15 +0000 Subject: [PATCH 2301/3224] Fixed server crash on truncated varint in packet header --- src/network/mcpe/protocol/serializer/PacketBatch.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/network/mcpe/protocol/serializer/PacketBatch.php b/src/network/mcpe/protocol/serializer/PacketBatch.php index 13f3716e46..e64a31b1ea 100644 --- a/src/network/mcpe/protocol/serializer/PacketBatch.php +++ b/src/network/mcpe/protocol/serializer/PacketBatch.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\protocol\serializer; use pocketmine\network\mcpe\protocol\Packet; use pocketmine\network\mcpe\protocol\PacketDecodeException; use pocketmine\network\mcpe\protocol\PacketPool; +use pocketmine\utils\BinaryDataException; class PacketBatch{ @@ -44,7 +45,11 @@ class PacketBatch{ public function getPackets(PacketPool $packetPool, int $max) : \Generator{ $serializer = new PacketSerializer($this->buffer); for($c = 0; $c < $max and !$serializer->feof(); ++$c){ - yield $c => $packetPool->getPacket($serializer->getString()); + try{ + yield $c => $packetPool->getPacket($serializer->getString()); + }catch(BinaryDataException $e){ + throw new PacketDecodeException("Error decoding packet $c of batch: " . $e->getMessage(), 0, $e); + } } if(!$serializer->feof()){ throw new PacketDecodeException("Reached limit of $max packets in a single batch"); From a49ee0d6b01fa34989e04ff7fffc0c3f0d603b42 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 24 Feb 2021 23:42:09 +0000 Subject: [PATCH 2302/3224] World: mark addTile() and removeTile() as @internal --- src/world/World.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index c764bedfe0..51cd90ed9b 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2244,6 +2244,7 @@ class World implements ChunkManager{ } /** + * @internal Tiles are now bound with blocks, and their creation is automatic. They should not be directly added. * @throws \InvalidArgumentException */ public function addTile(Tile $tile) : void{ @@ -2269,6 +2270,7 @@ class World implements ChunkManager{ } /** + * @internal Tiles are now bound with blocks, and their removal is automatic. They should not be directly removed. * @throws \InvalidArgumentException */ public function removeTile(Tile $tile) : void{ From b5361d58318ca9c5d9b084419e48004a36373d67 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 25 Feb 2021 22:36:53 +0000 Subject: [PATCH 2303/3224] Falling lava may not harden fixes #4050 this was not an issue on PM3 because the decay and falling state were both combined into the meta. --- src/block/Lava.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/block/Lava.php b/src/block/Lava.php index 004049c00b..06ee5fd81b 100644 --- a/src/block/Lava.php +++ b/src/block/Lava.php @@ -55,6 +55,9 @@ class Lava extends Liquid{ } protected function checkForHarden() : bool{ + if($this->falling){ + return false; + } $colliding = null; foreach(Facing::ALL as $side){ if($side === Facing::DOWN){ From 72de45f0e9bd72b339627f15cac0d4a366863321 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 16 Mar 2021 23:03:00 +0000 Subject: [PATCH 2304/3224] Drop pocketmine/uuid for ramsey/uuid --- changelogs/4.0-snapshot.md | 7 +- composer.json | 2 +- composer.lock | 378 +++++++++++++----- src/Server.php | 16 +- src/entity/Human.php | 10 +- src/network/mcpe/cache/CraftingDataCache.php | 5 +- .../mcpe/handler/LoginPacketHandler.php | 9 +- src/network/mcpe/protocol/AddPlayerPacket.php | 4 +- .../mcpe/protocol/CraftingEventPacket.php | 4 +- src/network/mcpe/protocol/EmoteListPacket.php | 8 +- .../mcpe/protocol/PlayerSkinPacket.php | 6 +- .../protocol/serializer/PacketSerializer.php | 26 +- .../mcpe/protocol/types/PlayerListEntry.php | 8 +- .../types/command/CommandOriginData.php | 4 +- .../protocol/types/recipe/MultiRecipe.php | 8 +- .../protocol/types/recipe/ShapedRecipe.php | 8 +- .../protocol/types/recipe/ShapelessRecipe.php | 8 +- .../mcpe/protocol/types/skin/SkinData.php | 4 +- src/player/Player.php | 10 +- src/player/PlayerInfo.php | 8 +- src/player/XboxLivePlayerInfo.php | 4 +- src/stats/SendUsageTask.php | 6 +- src/utils/Utils.php | 10 +- src/world/particle/FloatingTextParticle.php | 4 +- 24 files changed, 374 insertions(+), 183 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 5948ef572c..03addc1305 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -917,7 +917,12 @@ This version features substantial changes to the network system, improving coher ### Utils - The `Color` class was removed. It's now found as `pocketmine\color\Color` in the [`pocketmine/color`](https://github.com/pmmp/Color) package. -- The `UUID` class was removed. It's now found as `pocketmine\uuid\UUID` in the [`pocketmine/uuid`](https://github.com/pmmp/UUID) package. +- The `UUID` class was removed. [`ramsey/uuid`](https://github.com/ramsey/uuid) version 4.1 is now used instead. + - `UUID::fromData()` can be replaced by `Ramsey\Uuid\Uuid::uuid3()` + - `UUID::fromRandom()` can be replaced by `Ramsey\Uuid\Uuid::uuid4()` + - `UUID::fromBinary()` can be replaced by `Ramsey\Uuid\Uuid::fromBytes()` (use `Ramsey\Uuid\Uuid::isValid()` to check validity) + - `UUID::toBinary()` is replaced by `Ramsey\Uuid\UuidInterface::getBytes()` + - See the documentation at https://uuid.ramsey.dev/en/latest/introduction.html for more information. - `Terminal::hasFormattingCodes()` no longer auto-detects the availability of formatting codes. Instead it's necessary to use `Terminal::init()` with no parameters to initialize, or `true` or `false` to override. - `Config->save()` no longer catches exceptions thrown during emitting to disk. - The following new classes have been added: diff --git a/composer.json b/composer.json index df788c9007..2f2e35a1ed 100644 --- a/composer.json +++ b/composer.json @@ -46,7 +46,7 @@ "pocketmine/raklib": "dev-master", "pocketmine/snooze": "^0.1.0", "pocketmine/spl": "dev-master", - "pocketmine/uuid": "^0.1.0", + "ramsey/uuid": "^4.1", "respect/validation": "^2.0" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 51021c2890..9d350331d5 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "07097f47ac43ad9568068ea11d65ad15", + "content-hash": "cef3fa0d56c5b31a25c31b0826406ef9", "packages": [ { "name": "adhocore/json-comment", @@ -54,6 +54,62 @@ }, "time": "2020-01-03T13:51:23+00:00" }, + { + "name": "brick/math", + "version": "0.9.2", + "source": { + "type": "git", + "url": "https://github.com/brick/math.git", + "reference": "dff976c2f3487d42c1db75a3b180e2b9f0e72ce0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/brick/math/zipball/dff976c2f3487d42c1db75a3b180e2b9f0e72ce0", + "reference": "dff976c2f3487d42c1db75a3b180e2b9f0e72ce0", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0", + "vimeo/psalm": "4.3.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Brick\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Arbitrary-precision arithmetic library", + "keywords": [ + "Arbitrary-precision", + "BigInteger", + "BigRational", + "arithmetic", + "bigdecimal", + "bignum", + "brick", + "math" + ], + "support": { + "issues": "https://github.com/brick/math/issues", + "source": "https://github.com/brick/math/tree/0.9.2" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/brick/math", + "type": "tidelift" + } + ], + "time": "2021-01-20T22:51:39+00:00" + }, { "name": "fgrosse/phpasn1", "version": "v2.2.0", @@ -755,43 +811,173 @@ "time": "2021-01-15T15:19:34+00:00" }, { - "name": "pocketmine/uuid", - "version": "0.1.1", + "name": "ramsey/collection", + "version": "1.1.3", "source": { "type": "git", - "url": "https://github.com/pmmp/UUID.git", - "reference": "385051ab7919966191d04b0c5c5009639a4b2ba3" + "url": "https://github.com/ramsey/collection.git", + "reference": "28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/UUID/zipball/385051ab7919966191d04b0c5c5009639a4b2ba3", - "reference": "385051ab7919966191d04b0c5c5009639a4b2ba3", + "url": "https://api.github.com/repos/ramsey/collection/zipball/28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1", + "reference": "28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0", - "pocketmine/binaryutils": "^0.1 || dev-master" + "php": "^7.2 || ^8" }, "require-dev": { - "phpstan/phpstan": "0.12.66", - "phpstan/phpstan-strict-rules": "^0.12.2" + "captainhook/captainhook": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "ergebnis/composer-normalize": "^2.6", + "fakerphp/faker": "^1.5", + "hamcrest/hamcrest-php": "^2", + "jangregor/phpstan-prophecy": "^0.8", + "mockery/mockery": "^1.3", + "phpstan/extension-installer": "^1", + "phpstan/phpstan": "^0.12.32", + "phpstan/phpstan-mockery": "^0.12.5", + "phpstan/phpstan-phpunit": "^0.12.11", + "phpunit/phpunit": "^8.5 || ^9", + "psy/psysh": "^0.10.4", + "slevomat/coding-standard": "^6.3", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.4" }, "type": "library", "autoload": { "psr-4": { - "pocketmine\\uuid\\": "src/" + "Ramsey\\Collection\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-3.0" + "MIT" + ], + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "A PHP 7.2+ library for representing and manipulating collections.", + "keywords": [ + "array", + "collection", + "hash", + "map", + "queue", + "set" ], - "description": "Basic UUID implementation used by PocketMine-MP and related projects", "support": { - "issues": "https://github.com/pmmp/UUID/issues", - "source": "https://github.com/pmmp/UUID/tree/0.1.1" + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/1.1.3" }, - "time": "2021-01-15T00:33:02+00:00" + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", + "type": "tidelift" + } + ], + "time": "2021-01-21T17:40:04+00:00" + }, + { + "name": "ramsey/uuid", + "version": "4.1.1", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "cd4032040a750077205918c86049aa0f43d22947" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/cd4032040a750077205918c86049aa0f43d22947", + "reference": "cd4032040a750077205918c86049aa0f43d22947", + "shasum": "" + }, + "require": { + "brick/math": "^0.8 || ^0.9", + "ext-json": "*", + "php": "^7.2 || ^8", + "ramsey/collection": "^1.0", + "symfony/polyfill-ctype": "^1.8" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "codeception/aspect-mock": "^3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7.0", + "doctrine/annotations": "^1.8", + "goaop/framework": "^2", + "mockery/mockery": "^1.3", + "moontoast/math": "^1.1", + "paragonie/random-lib": "^2", + "php-mock/php-mock-mockery": "^1.3", + "php-mock/php-mock-phpunit": "^2.5", + "php-parallel-lint/php-parallel-lint": "^1.1", + "phpbench/phpbench": "^0.17.1", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-mockery": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^8.5", + "psy/psysh": "^0.10.0", + "slevomat/coding-standard": "^6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "3.9.4" + }, + "suggest": { + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-ctype": "Enables faster processing of character classification using ctype functions.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Ramsey\\Uuid\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "homepage": "https://github.com/ramsey/uuid", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "rss": "https://github.com/ramsey/uuid/releases.atom", + "source": "https://github.com/ramsey/uuid" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + } + ], + "time": "2020-08-18T17:17:46+00:00" }, { "name": "respect/stringifier", @@ -976,6 +1162,85 @@ }, "time": "2021-03-02T08:18:52+00:00" }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.22.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-07T16:49:33+00:00" + }, { "name": "symfony/polyfill-mbstring", "version": "v1.22.1", @@ -3128,85 +3393,6 @@ ], "time": "2020-09-28T06:39:44+00:00" }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.22.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", - "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.22-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-01-07T16:49:33+00:00" - }, { "name": "theseer/tokenizer", "version": "1.2.0", diff --git a/src/Server.php b/src/Server.php index a65cd5c301..992d19f6f0 100644 --- a/src/Server.php +++ b/src/Server.php @@ -92,7 +92,6 @@ use pocketmine\utils\Process; use pocketmine\utils\Terminal; use pocketmine\utils\TextFormat; use pocketmine\utils\Utils; -use pocketmine\uuid\UUID; use pocketmine\world\format\io\WorldProviderManager; use pocketmine\world\format\io\WritableWorldProvider; use pocketmine\world\generator\Generator; @@ -100,6 +99,7 @@ use pocketmine\world\generator\GeneratorManager; use pocketmine\world\generator\normal\Normal; use pocketmine\world\World; use pocketmine\world\WorldManager; +use Ramsey\Uuid\UuidInterface; use function array_shift; use function array_sum; use function base64_encode; @@ -254,7 +254,7 @@ class Server{ /** @var bool */ private $forceLanguage = false; - /** @var UUID */ + /** @var UuidInterface */ private $serverID; /** @var \DynamicClassLoader */ @@ -361,7 +361,7 @@ class Server{ } /** - * @return UUID + * @return UuidInterface */ public function getServerUniqueId(){ return $this->serverID; @@ -637,10 +637,10 @@ class Server{ } /** - * Returns the player online with a UUID equivalent to the specified UUID object, or null if not found + * Returns the player online with a UUID equivalent to the specified UuidInterface object, or null if not found */ - public function getPlayerByUUID(UUID $uuid) : ?Player{ - return $this->getPlayerByRawUUID($uuid->toBinary()); + public function getPlayerByUUID(UuidInterface $uuid) : ?Player{ + return $this->getPlayerByRawUUID($uuid->getBytes()); } public function getConfigGroup() : ServerConfigGroup{ @@ -1540,7 +1540,7 @@ class Server{ foreach($this->playerList as $p){ $p->getNetworkSession()->onPlayerAdded($player); } - $rawUUID = $player->getUniqueId()->toBinary(); + $rawUUID = $player->getUniqueId()->getBytes(); $this->playerList[$rawUUID] = $player; if($this->sendUsageTicker > 0){ @@ -1549,7 +1549,7 @@ class Server{ } public function removeOnlinePlayer(Player $player) : void{ - if(isset($this->playerList[$rawUUID = $player->getUniqueId()->toBinary()])){ + if(isset($this->playerList[$rawUUID = $player->getUniqueId()->getBytes()])){ unset($this->playerList[$rawUUID]); foreach($this->playerList as $p){ $p->getNetworkSession()->onPlayerRemoved($player); diff --git a/src/entity/Human.php b/src/entity/Human.php index 73db86ac34..ee48388e5f 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -55,8 +55,9 @@ use pocketmine\network\mcpe\protocol\types\entity\StringMetadataProperty; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\player\Player; use pocketmine\utils\Limits; -use pocketmine\uuid\UUID; use pocketmine\world\sound\TotemUseSound; +use Ramsey\Uuid\Uuid; +use Ramsey\Uuid\UuidInterface; use function array_filter; use function array_key_exists; use function array_merge; @@ -74,7 +75,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ /** @var EnderChestInventory */ protected $enderChestInventory; - /** @var UUID */ + /** @var UuidInterface */ protected $uuid; /** @var Skin */ @@ -113,7 +114,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ ); } - public function getUniqueId() : UUID{ + public function getUniqueId() : UuidInterface{ return $this->uuid; } @@ -203,7 +204,8 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $this->setNameTag($nameTagTag->getValue()); } - $this->uuid = UUID::fromData((string) $this->getId(), $this->skin->getSkinData(), $this->getNameTag()); + //TODO: use of NIL UUID for namespace is a hack; we should provide a proper UUID for the namespace + $this->uuid = Uuid::uuid3(Uuid::NIL, ((string) $this->getId()) . $this->skin->getSkinData() . $this->getNameTag()); } protected function initEntity(CompoundTag $nbt) : void{ diff --git a/src/network/mcpe/cache/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php index 55aa2c1f34..da3c8e18d1 100644 --- a/src/network/mcpe/cache/CraftingDataCache.php +++ b/src/network/mcpe/cache/CraftingDataCache.php @@ -35,10 +35,9 @@ use pocketmine\network\mcpe\protocol\types\recipe\ShapelessRecipe as ProtocolSha use pocketmine\timings\Timings; use pocketmine\utils\Binary; use pocketmine\utils\SingletonTrait; -use pocketmine\uuid\UUID; +use Ramsey\Uuid\Uuid; use function array_map; use function spl_object_id; -use function str_repeat; final class CraftingDataCache{ use SingletonTrait; @@ -72,7 +71,7 @@ final class CraftingDataCache{ $pk->cleanRecipes = true; $counter = 0; - $nullUUID = UUID::fromData(str_repeat("\x00", 16)); + $nullUUID = Uuid::fromString(Uuid::NIL); $converter = TypeConverter::getInstance(); foreach($manager->getShapelessRecipes() as $list){ foreach($list as $recipe){ diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index b9e81b2537..b48bad7658 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -43,7 +43,7 @@ use pocketmine\player\Player; use pocketmine\player\PlayerInfo; use pocketmine\player\XboxLivePlayerInfo; use pocketmine\Server; -use pocketmine\uuid\UUID; +use Ramsey\Uuid\Uuid; use function is_array; /** @@ -112,11 +112,10 @@ class LoginPacketHandler extends PacketHandler{ return true; } - try{ - $uuid = UUID::fromString($extraData->identity); - }catch(\InvalidArgumentException $e){ - throw BadPacketException::wrap($e, "Failed to parse login UUID"); + if(!Uuid::isValid($extraData->identity)){ + throw new BadPacketException("Invalid login UUID"); } + $uuid = Uuid::fromString($extraData->identity); if($extraData->XUID !== ""){ $playerInfo = new XboxLivePlayerInfo( $extraData->XUID, diff --git a/src/network/mcpe/protocol/AddPlayerPacket.php b/src/network/mcpe/protocol/AddPlayerPacket.php index f5b6adeed4..3b1bd7d406 100644 --- a/src/network/mcpe/protocol/AddPlayerPacket.php +++ b/src/network/mcpe/protocol/AddPlayerPacket.php @@ -31,13 +31,13 @@ use pocketmine\network\mcpe\protocol\types\DeviceOS; use pocketmine\network\mcpe\protocol\types\entity\EntityLink; use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\uuid\UUID; +use Ramsey\Uuid\UuidInterface; use function count; class AddPlayerPacket extends DataPacket implements ClientboundPacket{ public const NETWORK_ID = ProtocolInfo::ADD_PLAYER_PACKET; - /** @var UUID */ + /** @var UuidInterface */ public $uuid; /** @var string */ public $username; diff --git a/src/network/mcpe/protocol/CraftingEventPacket.php b/src/network/mcpe/protocol/CraftingEventPacket.php index e2dd9bddce..e49893869a 100644 --- a/src/network/mcpe/protocol/CraftingEventPacket.php +++ b/src/network/mcpe/protocol/CraftingEventPacket.php @@ -27,7 +27,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\uuid\UUID; +use Ramsey\Uuid\UuidInterface; use function count; class CraftingEventPacket extends DataPacket implements ServerboundPacket{ @@ -37,7 +37,7 @@ class CraftingEventPacket extends DataPacket implements ServerboundPacket{ public $windowId; /** @var int */ public $type; - /** @var UUID */ + /** @var UuidInterface */ public $id; /** @var ItemStack[] */ public $input = []; diff --git a/src/network/mcpe/protocol/EmoteListPacket.php b/src/network/mcpe/protocol/EmoteListPacket.php index 1847d92118..f6872eac27 100644 --- a/src/network/mcpe/protocol/EmoteListPacket.php +++ b/src/network/mcpe/protocol/EmoteListPacket.php @@ -26,7 +26,7 @@ namespace pocketmine\network\mcpe\protocol; #include use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\uuid\UUID; +use Ramsey\Uuid\UuidInterface; use function count; class EmoteListPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ @@ -34,11 +34,11 @@ class EmoteListPacket extends DataPacket implements ClientboundPacket, Serverbou /** @var int */ private $playerEntityRuntimeId; - /** @var UUID[] */ + /** @var UuidInterface[] */ private $emoteIds; /** - * @param UUID[] $emoteIds + * @param UuidInterface[] $emoteIds */ public static function create(int $playerEntityRuntimeId, array $emoteIds) : self{ $result = new self; @@ -49,7 +49,7 @@ class EmoteListPacket extends DataPacket implements ClientboundPacket, Serverbou public function getPlayerEntityRuntimeId() : int{ return $this->playerEntityRuntimeId; } - /** @return UUID[] */ + /** @return UuidInterface[] */ public function getEmoteIds() : array{ return $this->emoteIds; } protected function decodePayload(PacketSerializer $in) : void{ diff --git a/src/network/mcpe/protocol/PlayerSkinPacket.php b/src/network/mcpe/protocol/PlayerSkinPacket.php index f97e783e39..3b688e46a0 100644 --- a/src/network/mcpe/protocol/PlayerSkinPacket.php +++ b/src/network/mcpe/protocol/PlayerSkinPacket.php @@ -27,12 +27,12 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\skin\SkinData; -use pocketmine\uuid\UUID; +use Ramsey\Uuid\UuidInterface; class PlayerSkinPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::PLAYER_SKIN_PACKET; - /** @var UUID */ + /** @var UuidInterface */ public $uuid; /** @var string */ public $oldSkinName = ""; @@ -41,7 +41,7 @@ class PlayerSkinPacket extends DataPacket implements ClientboundPacket, Serverbo /** @var SkinData */ public $skin; - public static function create(UUID $uuid, SkinData $skinData) : self{ + public static function create(UuidInterface $uuid, SkinData $skinData) : self{ $result = new self; $result->uuid = $uuid; $result->skin = $skinData; diff --git a/src/network/mcpe/protocol/serializer/PacketSerializer.php b/src/network/mcpe/protocol/serializer/PacketSerializer.php index 0d710ca237..239a38ba3e 100644 --- a/src/network/mcpe/protocol/serializer/PacketSerializer.php +++ b/src/network/mcpe/protocol/serializer/PacketSerializer.php @@ -60,9 +60,11 @@ use pocketmine\network\mcpe\protocol\types\StructureEditorData; use pocketmine\network\mcpe\protocol\types\StructureSettings; use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; -use pocketmine\uuid\UUID; +use Ramsey\Uuid\UuidInterface; use function count; use function strlen; +use function strrev; +use function substr; class PacketSerializer extends BinaryStream{ @@ -81,21 +83,17 @@ class PacketSerializer extends BinaryStream{ /** * @throws BinaryDataException */ - public function getUUID() : UUID{ - //This is actually two little-endian longs: UUID Most followed by UUID Least - $part1 = $this->getLInt(); - $part0 = $this->getLInt(); - $part3 = $this->getLInt(); - $part2 = $this->getLInt(); - - return new UUID($part0, $part1, $part2, $part3); + public function getUUID() : UuidInterface{ + //This is two little-endian longs: bytes 7-0 followed by bytes 15-8 + $p1 = strrev($this->get(8)); + $p2 = strrev($this->get(8)); + return \Ramsey\Uuid\Uuid::fromBytes($p1 . $p2); } - public function putUUID(UUID $uuid) : void{ - $this->putLInt($uuid->getPart(1)); - $this->putLInt($uuid->getPart(0)); - $this->putLInt($uuid->getPart(3)); - $this->putLInt($uuid->getPart(2)); + public function putUUID(UuidInterface $uuid) : void{ + $bytes = $uuid->getBytes(); + $this->put(strrev(substr($bytes, 0, 8))); + $this->put(strrev(substr($bytes, 8, 8))); } public function getSkin() : SkinData{ diff --git a/src/network/mcpe/protocol/types/PlayerListEntry.php b/src/network/mcpe/protocol/types/PlayerListEntry.php index 9e9aa712b5..a50e279b8d 100644 --- a/src/network/mcpe/protocol/types/PlayerListEntry.php +++ b/src/network/mcpe/protocol/types/PlayerListEntry.php @@ -24,11 +24,11 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types; use pocketmine\network\mcpe\protocol\types\skin\SkinData; -use pocketmine\uuid\UUID; +use Ramsey\Uuid\UuidInterface; class PlayerListEntry{ - /** @var UUID */ + /** @var UuidInterface */ public $uuid; /** @var int */ public $entityUniqueId; @@ -47,14 +47,14 @@ class PlayerListEntry{ /** @var bool */ public $isHost = false; - public static function createRemovalEntry(UUID $uuid) : PlayerListEntry{ + public static function createRemovalEntry(UuidInterface $uuid) : PlayerListEntry{ $entry = new PlayerListEntry(); $entry->uuid = $uuid; return $entry; } - public static function createAdditionEntry(UUID $uuid, int $entityUniqueId, string $username, SkinData $skinData, string $xboxUserId = "", string $platformChatId = "", int $buildPlatform = -1, bool $isTeacher = false, bool $isHost = false) : PlayerListEntry{ + public static function createAdditionEntry(UuidInterface $uuid, int $entityUniqueId, string $username, SkinData $skinData, string $xboxUserId = "", string $platformChatId = "", int $buildPlatform = -1, bool $isTeacher = false, bool $isHost = false) : PlayerListEntry{ $entry = new PlayerListEntry(); $entry->uuid = $uuid; $entry->entityUniqueId = $entityUniqueId; diff --git a/src/network/mcpe/protocol/types/command/CommandOriginData.php b/src/network/mcpe/protocol/types/command/CommandOriginData.php index ffea4a4fd3..576a80112e 100644 --- a/src/network/mcpe/protocol/types/command/CommandOriginData.php +++ b/src/network/mcpe/protocol/types/command/CommandOriginData.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\command; -use pocketmine\uuid\UUID; +use Ramsey\Uuid\UuidInterface; class CommandOriginData{ public const ORIGIN_PLAYER = 0; @@ -41,7 +41,7 @@ class CommandOriginData{ /** @var int */ public $type; - /** @var UUID */ + /** @var UuidInterface */ public $uuid; /** @var string */ diff --git a/src/network/mcpe/protocol/types/recipe/MultiRecipe.php b/src/network/mcpe/protocol/types/recipe/MultiRecipe.php index af07d63c03..52b5276ebc 100644 --- a/src/network/mcpe/protocol/types/recipe/MultiRecipe.php +++ b/src/network/mcpe/protocol/types/recipe/MultiRecipe.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\recipe; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\uuid\UUID; +use Ramsey\Uuid\UuidInterface; final class MultiRecipe extends RecipeWithTypeId{ @@ -41,18 +41,18 @@ final class MultiRecipe extends RecipeWithTypeId{ public const TYPE_FIREWORKS = "00000000-0000-0000-0000-000000000002"; public const TYPE_MAP_LOCKING_CARTOGRAPHY = "602234E4-CAC1-4353-8BB7-B1EBFF70024B"; - /** @var UUID */ + /** @var UuidInterface */ private $recipeId; /** @var int */ private $recipeNetId; - public function __construct(int $typeId, UUID $recipeId, int $recipeNetId){ + public function __construct(int $typeId, UuidInterface $recipeId, int $recipeNetId){ parent::__construct($typeId); $this->recipeId = $recipeId; $this->recipeNetId = $recipeNetId; } - public function getRecipeId() : UUID{ + public function getRecipeId() : UuidInterface{ return $this->recipeId; } diff --git a/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php b/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php index e21ba9163c..1a9aee0b89 100644 --- a/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php +++ b/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol\types\recipe; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\uuid\UUID; +use Ramsey\Uuid\UuidInterface; use function count; final class ShapedRecipe extends RecipeWithTypeId{ @@ -36,7 +36,7 @@ final class ShapedRecipe extends RecipeWithTypeId{ private $input; /** @var ItemStack[] */ private $output; - /** @var UUID */ + /** @var UuidInterface */ private $uuid; /** @var string */ private $blockName; @@ -49,7 +49,7 @@ final class ShapedRecipe extends RecipeWithTypeId{ * @param RecipeIngredient[][] $input * @param ItemStack[] $output */ - public function __construct(int $typeId, string $recipeId, array $input, array $output, UUID $uuid, string $blockType, int $priority, int $recipeNetId){ + public function __construct(int $typeId, string $recipeId, array $input, array $output, UuidInterface $uuid, string $blockType, int $priority, int $recipeNetId){ parent::__construct($typeId); $rows = count($input); if($rows < 1 or $rows > 3){ @@ -98,7 +98,7 @@ final class ShapedRecipe extends RecipeWithTypeId{ return $this->output; } - public function getUuid() : UUID{ + public function getUuid() : UuidInterface{ return $this->uuid; } diff --git a/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php b/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php index 58903e4684..0facbab7ce 100644 --- a/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php +++ b/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\protocol\types\recipe; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\uuid\UUID; +use Ramsey\Uuid\UuidInterface; use function count; final class ShapelessRecipe extends RecipeWithTypeId{ @@ -36,7 +36,7 @@ final class ShapelessRecipe extends RecipeWithTypeId{ private $inputs; /** @var ItemStack[] */ private $outputs; - /** @var UUID */ + /** @var UuidInterface */ private $uuid; /** @var string */ private $blockName; @@ -49,7 +49,7 @@ final class ShapelessRecipe extends RecipeWithTypeId{ * @param RecipeIngredient[] $inputs * @param ItemStack[] $outputs */ - public function __construct(int $typeId, string $recipeId, array $inputs, array $outputs, UUID $uuid, string $blockName, int $priority, int $recipeNetId){ + public function __construct(int $typeId, string $recipeId, array $inputs, array $outputs, UuidInterface $uuid, string $blockName, int $priority, int $recipeNetId){ parent::__construct($typeId); $this->recipeId = $recipeId; $this->inputs = $inputs; @@ -78,7 +78,7 @@ final class ShapelessRecipe extends RecipeWithTypeId{ return $this->outputs; } - public function getUuid() : UUID{ + public function getUuid() : UuidInterface{ return $this->uuid; } diff --git a/src/network/mcpe/protocol/types/skin/SkinData.php b/src/network/mcpe/protocol/types/skin/SkinData.php index cb281de755..ccc958e891 100644 --- a/src/network/mcpe/protocol/types/skin/SkinData.php +++ b/src/network/mcpe/protocol/types/skin/SkinData.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol\types\skin; -use pocketmine\uuid\UUID; +use Ramsey\Uuid\Uuid; class SkinData{ @@ -86,7 +86,7 @@ class SkinData{ $this->personaCapeOnClassic = $personaCapeOnClassic; $this->capeId = $capeId; //this has to be unique or the client will do stupid things - $this->fullSkinId = $fullSkinId ?? UUID::fromRandom()->toString(); + $this->fullSkinId = $fullSkinId ?? Uuid::uuid4()->toString(); $this->armSize = $armSize; $this->skinColor = $skinColor; $this->personaPieces = $personaPieces; diff --git a/src/player/Player.php b/src/player/Player.php index ec69add5c5..c6f7e74f3c 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -101,7 +101,6 @@ use pocketmine\permission\PermissibleDelegateTrait; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\TextFormat; -use pocketmine\uuid\UUID; use pocketmine\world\ChunkListener; use pocketmine\world\ChunkListenerNoOpTrait; use pocketmine\world\format\Chunk; @@ -110,6 +109,7 @@ use pocketmine\world\sound\EntityAttackNoDamageSound; use pocketmine\world\sound\EntityAttackSound; use pocketmine\world\sound\FireExtinguishSound; use pocketmine\world\World; +use Ramsey\Uuid\UuidInterface; use function abs; use function assert; use function count; @@ -397,7 +397,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ * as SimpleAuth for authentication. This is NOT SAFE anymore as this UUID is now what was given by the client, NOT * a server-computed UUID.) */ - public function getUniqueId() : UUID{ + public function getUniqueId() : UuidInterface{ return parent::getUniqueId(); } @@ -471,14 +471,14 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } public function canSee(Player $player) : bool{ - return !isset($this->hiddenPlayers[$player->getUniqueId()->toBinary()]); + return !isset($this->hiddenPlayers[$player->getUniqueId()->getBytes()]); } public function hidePlayer(Player $player) : void{ if($player === $this){ return; } - $this->hiddenPlayers[$player->getUniqueId()->toBinary()] = true; + $this->hiddenPlayers[$player->getUniqueId()->getBytes()] = true; $player->despawnFrom($this); } @@ -486,7 +486,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ if($player === $this){ return; } - unset($this->hiddenPlayers[$player->getUniqueId()->toBinary()]); + unset($this->hiddenPlayers[$player->getUniqueId()->getBytes()]); if($player->isOnline()){ $player->spawnTo($this); } diff --git a/src/player/PlayerInfo.php b/src/player/PlayerInfo.php index 787042e806..ca1df8cf6f 100644 --- a/src/player/PlayerInfo.php +++ b/src/player/PlayerInfo.php @@ -25,7 +25,7 @@ namespace pocketmine\player; use pocketmine\entity\Skin; use pocketmine\utils\TextFormat; -use pocketmine\uuid\UUID; +use Ramsey\Uuid\UuidInterface; /** * Encapsulates data needed to create a player. @@ -34,7 +34,7 @@ class PlayerInfo{ /** @var string */ private $username; - /** @var UUID */ + /** @var UuidInterface */ private $uuid; /** @var Skin */ private $skin; @@ -50,7 +50,7 @@ class PlayerInfo{ * @param mixed[] $extraData * @phpstan-param array $extraData */ - public function __construct(string $username, UUID $uuid, Skin $skin, string $locale, array $extraData = []){ + public function __construct(string $username, UuidInterface $uuid, Skin $skin, string $locale, array $extraData = []){ $this->username = TextFormat::clean($username); $this->uuid = $uuid; $this->skin = $skin; @@ -62,7 +62,7 @@ class PlayerInfo{ return $this->username; } - public function getUuid() : UUID{ + public function getUuid() : UuidInterface{ return $this->uuid; } diff --git a/src/player/XboxLivePlayerInfo.php b/src/player/XboxLivePlayerInfo.php index a0e3a2cbcf..94dcc75ae2 100644 --- a/src/player/XboxLivePlayerInfo.php +++ b/src/player/XboxLivePlayerInfo.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\player; use pocketmine\entity\Skin; -use pocketmine\uuid\UUID; +use Ramsey\Uuid\UuidInterface; /** * Encapsulates player info specific to players who are authenticated with XBOX Live. @@ -34,7 +34,7 @@ final class XboxLivePlayerInfo extends PlayerInfo{ /** @var string */ private $xuid; - public function __construct(string $xuid, string $username, UUID $uuid, Skin $skin, string $locale, array $extraData = []){ + public function __construct(string $xuid, string $username, UuidInterface $uuid, Skin $skin, string $locale, array $extraData = []){ parent::__construct($username, $uuid, $skin, $locale, $extraData); $this->xuid = $xuid; } diff --git a/src/stats/SendUsageTask.php b/src/stats/SendUsageTask.php index 4fe3394df0..c29eb60bc5 100644 --- a/src/stats/SendUsageTask.php +++ b/src/stats/SendUsageTask.php @@ -31,8 +31,8 @@ use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Internet; use pocketmine\utils\Process; use pocketmine\utils\Utils; -use pocketmine\uuid\UUID; use pocketmine\VersionInfo; +use Ramsey\Uuid\Uuid; use function array_map; use function array_values; use function count; @@ -65,7 +65,7 @@ class SendUsageTask extends AsyncTask{ $data = []; $data["uniqueServerId"] = $server->getServerUniqueId()->toString(); $data["uniqueMachineId"] = Utils::getMachineUniqueId()->toString(); - $data["uniqueRequestId"] = UUID::fromData($server->getServerUniqueId()->toString(), microtime(false))->toString(); + $data["uniqueRequestId"] = Uuid::uuid3($server->getServerUniqueId()->toString(), microtime(false))->toString(); switch($type){ case self::TYPE_OPEN: @@ -127,7 +127,7 @@ class SendUsageTask extends AsyncTask{ $playerList[$k] = md5($v); } - $players = array_map(function(Player $p) : string{ return md5($p->getUniqueId()->toBinary()); }, $server->getOnlinePlayers()); + $players = array_map(function(Player $p) : string{ return md5($p->getUniqueId()->getBytes()); }, $server->getOnlinePlayers()); $data["players"] = [ "count" => count($players), diff --git a/src/utils/Utils.php b/src/utils/Utils.php index 0772bac270..af4d222482 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -28,7 +28,8 @@ declare(strict_types=1); namespace pocketmine\utils; use DaveRandom\CallbackValidator\CallbackType; -use pocketmine\uuid\UUID; +use Ramsey\Uuid\Uuid; +use Ramsey\Uuid\UuidInterface; use function array_combine; use function array_map; use function array_reverse; @@ -93,7 +94,7 @@ final class Utils{ /** @var string|null */ private static $os; - /** @var UUID|null */ + /** @var UuidInterface|null */ private static $serverUniqueId = null; /** @@ -178,7 +179,7 @@ final class Utils{ * * @param string $extra optional, additional data to identify the machine */ - public static function getMachineUniqueId(string $extra = "") : UUID{ + public static function getMachineUniqueId(string $extra = "") : UuidInterface{ if(self::$serverUniqueId !== null and $extra === ""){ return self::$serverUniqueId; } @@ -234,7 +235,8 @@ final class Utils{ $data .= $ext . ":" . phpversion($ext); } - $uuid = UUID::fromData($machine, $data); + //TODO: use of NIL as namespace is a hack; it works for now, but we should have a proper namespace UUID + $uuid = Uuid::uuid3(Uuid::NIL, $data); if($extra === ""){ self::$serverUniqueId = $uuid; diff --git a/src/world/particle/FloatingTextParticle.php b/src/world/particle/FloatingTextParticle.php index bca6013893..b2caf06065 100644 --- a/src/world/particle/FloatingTextParticle.php +++ b/src/world/particle/FloatingTextParticle.php @@ -36,7 +36,7 @@ use pocketmine\network\mcpe\protocol\types\entity\FloatMetadataProperty; use pocketmine\network\mcpe\protocol\types\entity\LongMetadataProperty; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; use pocketmine\network\mcpe\protocol\types\PlayerListEntry; -use pocketmine\uuid\UUID; +use Ramsey\Uuid\Uuid; use function str_repeat; class FloatingTextParticle implements Particle{ @@ -90,7 +90,7 @@ class FloatingTextParticle implements Particle{ } if(!$this->invisible){ - $uuid = UUID::fromRandom(); + $uuid = Uuid::uuid4(); $name = $this->title . ($this->text !== "" ? "\n" . $this->text : ""); $p[] = PlayerListPacket::add([PlayerListEntry::createAdditionEntry($uuid, $this->entityId, $name, SkinAdapterSingleton::get()->toSkinData(new Skin("Standard_Custom", str_repeat("\x00", 8192))))]); From eba68990657f550dd33b69544a0487e60955a46f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 16 Mar 2021 23:19:33 +0000 Subject: [PATCH 2305/3224] changelog: mention performance improvements caused by morton codes and libdeflate these two things provide a significant performance improvement over PM3, so they should be noted. --- changelogs/4.0-snapshot.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 03addc1305..994eb594e9 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -40,6 +40,8 @@ This major version features substantial changes throughout the core, including s - Lighting is no longer guaranteed to be available on every chunk. It's now calculated on the fly as-needed. - `/op`, `/deop`, `/whitelist add` and `/whitelist remove` no longer cause player data to be loaded from disk for no reason. - Timings now use high-resolution timers provided by `hrtime()` to collect more accurate performance metrics. +- Z-order curves (morton codes) are now used for block and chunk coordinate hashes. This substantially improves performance in many areas by resolving a hashtable key hash collision performance issue. Affected areas include explosions, light calculation, and more. +- [`libdeflate`](https://github.com/ebiggers/libdeflate) is now (optionally) used for outbound Minecraft packet compression. It's more than twice as fast as zlib in most cases, providing significant performance boosts to packet broadcasts and overall network performance. ### Logger revamp - Many components now have a dedicated logger which automatically adds [prefixes] to their messages. From 83d1051a064ff5026500d93d3cf7e3b9c8a49e74 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 16 Mar 2021 23:32:23 +0000 Subject: [PATCH 2306/3224] changelog: mention performance improvements in event handling --- changelogs/4.0-snapshot.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 994eb594e9..ddc77f939c 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -42,6 +42,7 @@ This major version features substantial changes throughout the core, including s - Timings now use high-resolution timers provided by `hrtime()` to collect more accurate performance metrics. - Z-order curves (morton codes) are now used for block and chunk coordinate hashes. This substantially improves performance in many areas by resolving a hashtable key hash collision performance issue. Affected areas include explosions, light calculation, and more. - [`libdeflate`](https://github.com/ebiggers/libdeflate) is now (optionally) used for outbound Minecraft packet compression. It's more than twice as fast as zlib in most cases, providing significant performance boosts to packet broadcasts and overall network performance. +- Closures are now used for internal event handler calls. This provides a performance improvement of 10-20% over the 3.x system, which had to dynamically resolve callables for every event call. ### Logger revamp - Many components now have a dedicated logger which automatically adds [prefixes] to their messages. From dcf53bd06d951e465a440ef2b1c923139ce3683e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 16 Mar 2021 23:38:07 +0000 Subject: [PATCH 2307/3224] BulkCurlTask: fixed reference to removed function [ci skip] --- src/scheduler/BulkCurlTask.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scheduler/BulkCurlTask.php b/src/scheduler/BulkCurlTask.php index b13bc989ff..fa60e2731e 100644 --- a/src/scheduler/BulkCurlTask.php +++ b/src/scheduler/BulkCurlTask.php @@ -42,7 +42,7 @@ class BulkCurlTask extends AsyncTask{ * * $operations accepts an array of arrays. Each member array must contain a string mapped to "page", and optionally, * "timeout", "extraHeaders" and "extraOpts". Documentation of these options are same as those in - * {@link Utils::simpleCurl}. + * {@link Internet::simpleCurl}. * * @param BulkCurlTaskOperation[] $operations * @phpstan-param list $operations From b3c6c11b200ef068487da897b276b41467493197 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 16 Mar 2021 23:56:14 +0000 Subject: [PATCH 2308/3224] BulkCurlTask now accepts a closure callback for onCompletion this requires much less boilerplate code than an anonymous class. --- src/command/defaults/TimingsCommand.php | 60 +++++++------------ src/scheduler/BulkCurlTask.php | 21 ++++++- .../check-explicit-mixed-baseline.neon | 7 +-- 3 files changed, 41 insertions(+), 47 deletions(-) diff --git a/src/command/defaults/TimingsCommand.php b/src/command/defaults/TimingsCommand.php index 6e2ece7237..6016886909 100644 --- a/src/command/defaults/TimingsCommand.php +++ b/src/command/defaults/TimingsCommand.php @@ -32,6 +32,7 @@ use pocketmine\scheduler\BulkCurlTask; use pocketmine\scheduler\BulkCurlTaskOperation; use pocketmine\timings\TimingsHandler; use pocketmine\utils\InternetException; +use pocketmine\utils\InternetRequestResult; use function count; use function fclose; use function file_exists; @@ -128,45 +129,28 @@ class TimingsCommand extends VanillaCommand{ $host = $sender->getServer()->getConfigGroup()->getProperty("timings.host", "timings.pmmp.io"); - $sender->getServer()->getAsyncPool()->submitTask(new class($sender, $host, $agent, $data) extends BulkCurlTask{ - private const TLS_KEY_SENDER = "sender"; - - /** @var string */ - private $host; - - /** - * @param string[] $data - * @phpstan-param array $data - */ - public function __construct(CommandSender $sender, string $host, string $agent, array $data){ - parent::__construct([ - new BulkCurlTaskOperation( - "https://$host?upload=true", - 10, - [], - [ - CURLOPT_HTTPHEADER => [ - "User-Agent: $agent", - "Content-Type: application/x-www-form-urlencoded" - ], - CURLOPT_POST => true, - CURLOPT_POSTFIELDS => http_build_query($data), - CURLOPT_AUTOREFERER => false, - CURLOPT_FOLLOWLOCATION => false - ] - ) - ]); - $this->host = $host; - $this->storeLocal(self::TLS_KEY_SENDER, $sender); - } - - public function onCompletion() : void{ - /** @var CommandSender $sender */ - $sender = $this->fetchLocal(self::TLS_KEY_SENDER); + $sender->getServer()->getAsyncPool()->submitTask(new BulkCurlTask( + [new BulkCurlTaskOperation( + "https://$host?upload=true", + 10, + [], + [ + CURLOPT_HTTPHEADER => [ + "User-Agent: $agent", + "Content-Type: application/x-www-form-urlencoded" + ], + CURLOPT_POST => true, + CURLOPT_POSTFIELDS => http_build_query($data), + CURLOPT_AUTOREFERER => false, + CURLOPT_FOLLOWLOCATION => false + ] + )], + function(array $results) use ($sender, $host) : void{ + /** @phpstan-var array $results */ if($sender instanceof Player and !$sender->isOnline()){ // TODO replace with a more generic API method for checking availability of CommandSender return; } - $result = $this->getResult()[0]; + $result = $results[0]; if($result instanceof InternetException){ $sender->getServer()->getLogger()->logException($result); return; @@ -174,12 +158,12 @@ class TimingsCommand extends VanillaCommand{ $response = json_decode($result->getBody(), true); if(is_array($response) && isset($response["id"])){ Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.command.timings.timingsRead", - ["https://" . $this->host . "/?id=" . $response["id"]])); + ["https://" . $host . "/?id=" . $response["id"]])); }else{ Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.command.timings.pasteError")); } } - }); + )); }else{ fclose($fileTimings); Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.command.timings.timingsWrite", [$timings])); diff --git a/src/scheduler/BulkCurlTask.php b/src/scheduler/BulkCurlTask.php index fa60e2731e..cd35471754 100644 --- a/src/scheduler/BulkCurlTask.php +++ b/src/scheduler/BulkCurlTask.php @@ -25,6 +25,7 @@ namespace pocketmine\scheduler; use pocketmine\utils\Internet; use pocketmine\utils\InternetException; +use pocketmine\utils\InternetRequestResult; use function igbinary_serialize; use function igbinary_unserialize; @@ -34,6 +35,8 @@ use function igbinary_unserialize; * The result of this AsyncTask is an array of arrays (returned from {@link Internet::simpleCurl}) or InternetException objects. */ class BulkCurlTask extends AsyncTask{ + private const TLS_KEY_COMPLETION_CALLBACK = "completionCallback"; + /** @var string */ private $operations; @@ -44,11 +47,12 @@ class BulkCurlTask extends AsyncTask{ * "timeout", "extraHeaders" and "extraOpts". Documentation of these options are same as those in * {@link Internet::simpleCurl}. * - * @param BulkCurlTaskOperation[] $operations - * @phpstan-param list $operations + * @param BulkCurlTaskOperation[] $operations + * @phpstan-param \Closure(list $results) : void $onCompletion */ - public function __construct(array $operations){ + public function __construct(array $operations, \Closure $onCompletion){ $this->operations = igbinary_serialize($operations); + $this->storeLocal(self::TLS_KEY_COMPLETION_CALLBACK, $onCompletion); } public function onRun() : void{ @@ -67,4 +71,15 @@ class BulkCurlTask extends AsyncTask{ } $this->setResult($results); } + + public function onCompletion() : void{ + /** + * @var \Closure + * @phpstan-var \Closure(list) : void + */ + $callback = $this->fetchLocal(self::TLS_KEY_COMPLETION_CALLBACK); + /** @var InternetRequestResult[]|InternetException[] $results */ + $results = $this->getResult(); + $callback($results); + } } diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index 63009a2d1f..70ec278e46 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -96,12 +96,7 @@ parameters: path: ../../../src/command/CommandReader.php - - message: "#^Parameter \\#2 \\$host of class class@anonymous/src/command/defaults/TimingsCommand\\.php\\:131 constructor expects string, mixed given\\.$#" - count: 1 - path: ../../../src/command/defaults/TimingsCommand.php - - - - message: "#^Cannot access offset 0 on mixed\\.$#" + message: "#^Part \\$host \\(mixed\\) of encapsed string cannot be cast to string\\.$#" count: 1 path: ../../../src/command/defaults/TimingsCommand.php From fe3b493cdbc80db2de7c5659610630d70d8538cc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Mar 2021 01:06:05 +0000 Subject: [PATCH 2309/3224] UPnP: restore 'attempting to portforward' log message sometimes this takes a long time (usually in the failure case). --- src/network/upnp/UPnP.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/upnp/UPnP.php b/src/network/upnp/UPnP.php index 1f9d511ccf..4fc43bfdb5 100644 --- a/src/network/upnp/UPnP.php +++ b/src/network/upnp/UPnP.php @@ -209,6 +209,7 @@ class UPnP implements NetworkInterface{ } public function start() : void{ + $this->logger->info("Attempting to portforward..."); $this->serviceURL = self::getServiceUrl(); $body = From 5a59afbe2c915b608362a3d725781279753dcd3b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Mar 2021 01:21:11 +0000 Subject: [PATCH 2310/3224] Place world conversion backups in /backups/worlds instead of /world_conversion_backups --- src/world/WorldManager.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 16ad8b86bf..1cfcfdc8e5 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -51,6 +51,7 @@ use function random_int; use function round; use function sprintf; use function trim; +use const DIRECTORY_SEPARATOR; class WorldManager{ /** @var string */ @@ -224,7 +225,7 @@ class WorldManager{ } $this->server->getLogger()->notice("Upgrading world \"$name\" to new format. This may take a while."); - $converter = new FormatConverter($provider, $this->providerManager->getDefault(), $this->server->getDataPath() . "world_conversion_backups", $this->server->getLogger()); + $converter = new FormatConverter($provider, $this->providerManager->getDefault(), $this->server->getDataPath() . "backups" . DIRECTORY_SEPARATOR . "worlds", $this->server->getLogger()); $provider = $converter->execute(); $this->server->getLogger()->notice("Upgraded world \"$name\" to new format successfully. Backed up pre-conversion world at " . $converter->getBackupPath()); From b844c4266d7b310e720d385e9004dcb5d3231793 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 17 Mar 2021 23:19:49 +0000 Subject: [PATCH 2311/3224] Added World::Y_MIN preparation for Y axis expansion in 1.17 --- src/block/DragonEgg.php | 2 +- src/command/defaults/ParticleCommand.php | 2 +- src/command/defaults/SpawnpointCommand.php | 2 +- src/world/World.php | 11 ++++++----- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/block/DragonEgg.php b/src/block/DragonEgg.php index 17546b3f2a..5ea0657596 100644 --- a/src/block/DragonEgg.php +++ b/src/block/DragonEgg.php @@ -65,7 +65,7 @@ class DragonEgg extends Transparent implements Fallable{ for($tries = 0; $tries < 16; ++$tries){ $block = $this->pos->getWorld()->getBlockAt( $this->pos->x + mt_rand(-16, 16), - max(0, min(World::Y_MAX - 1, $this->pos->y + mt_rand(-8, 8))), + max(World::Y_MIN, min(World::Y_MAX - 1, $this->pos->y + mt_rand(-8, 8))), $this->pos->z + mt_rand(-16, 16) ); if($block instanceof Air){ diff --git a/src/command/defaults/ParticleCommand.php b/src/command/defaults/ParticleCommand.php index 0296b148b9..1420f5d3c4 100644 --- a/src/command/defaults/ParticleCommand.php +++ b/src/command/defaults/ParticleCommand.php @@ -97,7 +97,7 @@ class ParticleCommand extends VanillaCommand{ $world = $senderPos->getWorld(); $pos = new Vector3( $this->getRelativeDouble($senderPos->getX(), $sender, $args[1]), - $this->getRelativeDouble($senderPos->getY(), $sender, $args[2], 0, World::Y_MAX), + $this->getRelativeDouble($senderPos->getY(), $sender, $args[2], World::Y_MIN, World::Y_MAX), $this->getRelativeDouble($senderPos->getZ(), $sender, $args[3]) ); }else{ diff --git a/src/command/defaults/SpawnpointCommand.php b/src/command/defaults/SpawnpointCommand.php index 3fe4538441..3c5cf4f0c8 100644 --- a/src/command/defaults/SpawnpointCommand.php +++ b/src/command/defaults/SpawnpointCommand.php @@ -73,7 +73,7 @@ class SpawnpointCommand extends VanillaCommand{ $world = $target->getWorld(); $pos = $sender instanceof Player ? $sender->getPosition() : $world->getSpawnLocation(); $x = $this->getRelativeDouble($pos->x, $sender, $args[1]); - $y = $this->getRelativeDouble($pos->y, $sender, $args[2], 0, World::Y_MAX); + $y = $this->getRelativeDouble($pos->y, $sender, $args[2], World::Y_MIN, World::Y_MAX); $z = $this->getRelativeDouble($pos->z, $sender, $args[3]); $target->setSpawn(new Position($x, $y, $z, $world)); diff --git a/src/world/World.php b/src/world/World.php index 51cd90ed9b..2fadf68cb4 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -124,9 +124,8 @@ class World implements ChunkManager{ private static $worldIdCounter = 1; public const Y_MASK = 0xFF; - public const Y_MAX = 0x100; //256 - - public const HALF_Y_MAX = self::Y_MAX / 2; + public const Y_MAX = 320; + public const Y_MIN = -64; public const TIME_DAY = 1000; public const TIME_NOON = 6000; @@ -296,6 +295,8 @@ class World implements ChunkManager{ private const MORTON3D_BIT_SIZE = 21; private const BLOCKHASH_Y_BITS = 9; + private const BLOCKHASH_Y_PADDING = 128; //size (in blocks) of padding after both boundaries of the Y axis + private const BLOCKHASH_Y_OFFSET = self::BLOCKHASH_Y_PADDING - self::Y_MIN; private const BLOCKHASH_Y_MASK = (1 << self::BLOCKHASH_Y_BITS) - 1; private const BLOCKHASH_XZ_MASK = (1 << self::MORTON3D_BIT_SIZE) - 1; private const BLOCKHASH_XZ_EXTRA_BITS = 6; @@ -305,7 +306,7 @@ class World implements ChunkManager{ private const BLOCKHASH_Z_SHIFT = self::BLOCKHASH_X_SHIFT + self::BLOCKHASH_XZ_EXTRA_BITS; public static function blockHash(int $x, int $y, int $z) : int{ - $shiftedY = $y + self::HALF_Y_MAX; + $shiftedY = $y + self::BLOCKHASH_Y_OFFSET; if(($shiftedY & (~0 << self::BLOCKHASH_Y_BITS)) !== 0){ throw new \InvalidArgumentException("Y coordinate $y is out of range!"); } @@ -335,7 +336,7 @@ class World implements ChunkManager{ $extraZ = ((($baseY >> self::BLOCKHASH_Z_SHIFT) & self::BLOCKHASH_XZ_EXTRA_MASK) << self::MORTON3D_BIT_SIZE); $x = (($baseX & self::BLOCKHASH_XZ_MASK) | $extraX) << self::BLOCKHASH_XZ_SIGN_SHIFT >> self::BLOCKHASH_XZ_SIGN_SHIFT; - $y = ($baseY & self::BLOCKHASH_Y_MASK) - self::HALF_Y_MAX; + $y = ($baseY & self::BLOCKHASH_Y_MASK) - self::BLOCKHASH_Y_OFFSET; $z = (($baseZ & self::BLOCKHASH_XZ_MASK) | $extraZ) << self::BLOCKHASH_XZ_SIGN_SHIFT >> self::BLOCKHASH_XZ_SIGN_SHIFT; } From eb9a68edeebf1c7c99e576de86b5bbc45362570b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Mar 2021 00:08:16 +0000 Subject: [PATCH 2312/3224] Further refactors to prepare for y=-64 lower limit --- changelogs/4.0-snapshot.md | 1 + src/item/ChorusFruit.php | 2 +- src/world/ChunkManager.php | 9 +++++-- src/world/SimpleChunkManager.php | 22 ++++++++------- src/world/World.php | 27 ++++++++++++------- src/world/format/Chunk.php | 12 ++++----- src/world/format/SubChunk.php | 6 ++--- src/world/format/io/WorldProvider.php | 7 ++++- src/world/format/io/leveldb/LevelDB.php | 6 ++++- src/world/format/io/region/Anvil.php | 6 ++++- src/world/format/io/region/McRegion.php | 6 ++++- src/world/format/io/region/PMAnvil.php | 6 ++++- src/world/generator/GeneratorRegisterTask.php | 9 ++++--- src/world/generator/PopulationTask.php | 2 +- .../generator/ThreadLocalGeneratorContext.php | 16 +++++++---- src/world/light/LightPopulationTask.php | 2 +- src/world/light/SkyLightUpdate.php | 13 +++++---- 17 files changed, 101 insertions(+), 51 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index ddc77f939c..8155d3d900 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -867,6 +867,7 @@ This version features substantial changes to the network system, improving coher - `World->populateChunk()` has been split into `World->requestChunkPopulation()` and `World->orderChunkPopulation()`. - The following API methods have changed behaviour: - `World->getChunk()` no longer tries to load chunks from disk. If the chunk is not already in memory, null is returned. (This behaviour now properly matches other `ChunkManager` implementations.) + - `World->getHighestBlockAt()` now returns `null` instead of `-1` if the target X/Z column contains no blocks. - The following methods now throw `WorldException` when targeting ungenerated terrain: - `World->getSafeSpawn()` (previously it just silently returned the input position) - `World->getHighestBlockAt()` (previously it returned -1) diff --git a/src/item/ChorusFruit.php b/src/item/ChorusFruit.php index 8ba82d2811..7cf621e671 100644 --- a/src/item/ChorusFruit.php +++ b/src/item/ChorusFruit.php @@ -49,7 +49,7 @@ class ChorusFruit extends Food{ $origin = $consumer->getPosition(); $minX = $origin->getFloorX() - 8; - $minY = min($origin->getFloorY(), $consumer->getWorld()->getWorldHeight()) - 8; + $minY = min($origin->getFloorY(), $consumer->getWorld()->getMaxY()) - 8; $minZ = $origin->getFloorZ() - 8; $maxX = $minX + 16; diff --git a/src/world/ChunkManager.php b/src/world/ChunkManager.php index e0bb90f501..e84b88dc09 100644 --- a/src/world/ChunkManager.php +++ b/src/world/ChunkManager.php @@ -45,9 +45,14 @@ interface ChunkManager{ public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void; /** - * Returns the height of the world + * Returns the lowest buildable Y coordinate of the world */ - public function getWorldHeight() : int; + public function getMinY() : int; + + /** + * Returns the highest buildable Y coordinate of the world + */ + public function getMaxY() : int; /** * Returns whether the specified coordinates are within the valid world boundaries, taking world format limitations diff --git a/src/world/SimpleChunkManager.php b/src/world/SimpleChunkManager.php index 2c7fb01c6d..d78e533383 100644 --- a/src/world/SimpleChunkManager.php +++ b/src/world/SimpleChunkManager.php @@ -35,13 +35,13 @@ class SimpleChunkManager implements ChunkManager{ protected $chunks = []; /** @var int */ - protected $worldHeight; + private $minY; + /** @var int */ + private $maxY; - /** - * SimpleChunkManager constructor. - */ - public function __construct(int $worldHeight = World::Y_MAX){ - $this->worldHeight = $worldHeight; + public function __construct(int $minY, int $maxY){ + $this->minY = $minY; + $this->maxY = $maxY; } public function getBlockAt(int $x, int $y, int $z) : Block{ @@ -71,14 +71,18 @@ class SimpleChunkManager implements ChunkManager{ $this->chunks = []; } - public function getWorldHeight() : int{ - return $this->worldHeight; + public function getMinY() : int{ + return $this->minY; + } + + public function getMaxY() : int{ + return $this->maxY; } public function isInWorld(int $x, int $y, int $z) : bool{ return ( $x <= Limits::INT32_MAX and $x >= Limits::INT32_MIN and - $y < $this->worldHeight and $y >= 0 and + $y < $this->maxY and $y >= $this->minY and $z <= Limits::INT32_MAX and $z >= Limits::INT32_MIN ); } diff --git a/src/world/World.php b/src/world/World.php index 2fadf68cb4..123e41d314 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -174,7 +174,9 @@ class World implements ChunkManager{ private $providerGarbageCollectionTicker = 0; /** @var int */ - private $worldHeight; + private $minY; + /** @var int */ + private $maxY; /** @var ChunkLoader[] */ private $loaders = []; @@ -383,7 +385,8 @@ class World implements ChunkManager{ $this->displayName = $this->provider->getWorldData()->getName(); $this->logger = new \PrefixedLogger($server->getLogger(), "World: $this->displayName"); - $this->worldHeight = $this->provider->getWorldHeight(); + $this->minY = $this->provider->getWorldMinY(); + $this->maxY = $this->provider->getWorldMaxY(); $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.level.preparing", [$this->displayName])); $this->generator = GeneratorManager::getInstance()->getGenerator($this->provider->getWorldData()->getGenerator(), true); @@ -1335,7 +1338,7 @@ class World implements ChunkManager{ public function isInWorld(int $x, int $y, int $z) : bool{ return ( $x <= Limits::INT32_MAX and $x >= Limits::INT32_MIN and - $y < $this->worldHeight and $y >= 0 and + $y < $this->maxY and $y >= $this->minY and $z <= Limits::INT32_MAX and $z >= Limits::INT32_MIN ); } @@ -2089,10 +2092,10 @@ class World implements ChunkManager{ /** * Gets the highest block Y value at a specific $x and $z * - * @return int 0-255, or -1 if the column is empty + * @return int|null 0-255, or null if the column is empty * @throws WorldException if the terrain is not generated */ - public function getHighestBlockAt(int $x, int $z) : int{ + public function getHighestBlockAt(int $x, int $z) : ?int{ if(($chunk = $this->loadChunk($x >> 4, $z >> 4)) !== null){ return $chunk->getHighestBlockAt($x & 0x0f, $z & 0x0f); } @@ -2481,7 +2484,7 @@ class World implements ChunkManager{ $spawn = $this->getSpawnLocation(); } - $max = $this->worldHeight; + $max = $this->maxY; $v = $spawn->floor(); $chunk = $this->getOrLoadChunkAtPosition($v); if($chunk === null){ @@ -2491,7 +2494,7 @@ class World implements ChunkManager{ $z = (int) $v->z; $y = (int) min($max - 2, $v->y); $wasAir = $this->getBlockAt($x, $y - 1, $z)->getId() === BlockLegacyIds::AIR; //TODO: bad hack, clean up - for(; $y > 0; --$y){ + for(; $y > $this->minY; --$y){ if($this->getBlockAt($x, $y, $z)->isFullCube()){ if($wasAir){ $y++; @@ -2502,7 +2505,7 @@ class World implements ChunkManager{ } } - for(; $y >= 0 and $y < $max; ++$y){ + for(; $y >= $this->minY and $y < $max; ++$y){ if(!$this->getBlockAt($x, $y + 1, $z)->isFullCube()){ if(!$this->getBlockAt($x, $y, $z)->isFullCube()){ return new Position($spawn->x, $y === (int) $spawn->y ? $spawn->y : $y, $spawn->z, $this); @@ -2575,8 +2578,12 @@ class World implements ChunkManager{ return $this->provider->getWorldData()->getSeed(); } - public function getWorldHeight() : int{ - return $this->worldHeight; + public function getMinY() : int{ + return $this->minY; + } + + public function getMaxY() : int{ + return $this->maxY; } public function getDifficulty() : int{ diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 13570b6659..a625b17270 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -131,17 +131,17 @@ class Chunk{ * @param int $x 0-15 * @param int $z 0-15 * - * @return int 0-255, or -1 if there are no blocks in the column + * @return int|null 0-255, or null if there are no blocks in the column */ - public function getHighestBlockAt(int $x, int $z) : int{ + public function getHighestBlockAt(int $x, int $z) : ?int{ for($y = $this->subChunks->count() - 1; $y >= 0; --$y){ - $height = $this->getSubChunk($y)->getHighestBlockAt($x, $z) | ($y << 4); - if($height !== -1){ - return $height; + $height = $this->getSubChunk($y)->getHighestBlockAt($x, $z); + if($height !== null){ + return $height | ($y << 4); } } - return -1; + return null; } /** diff --git a/src/world/format/SubChunk.php b/src/world/format/SubChunk.php index e784aa6501..2224fe1d5a 100644 --- a/src/world/format/SubChunk.php +++ b/src/world/format/SubChunk.php @@ -96,9 +96,9 @@ class SubChunk{ return $this->blockLayers; } - public function getHighestBlockAt(int $x, int $z) : int{ + public function getHighestBlockAt(int $x, int $z) : ?int{ if(count($this->blockLayers) === 0){ - return -1; + return null; } for($y = 15; $y >= 0; --$y){ if($this->blockLayers[0]->get($x, $y, $z) !== $this->emptyBlockId){ @@ -106,7 +106,7 @@ class SubChunk{ } } - return -1; //highest block not in this subchunk + return null; //highest block not in this subchunk } public function getBlockSkyLightArray() : LightArray{ diff --git a/src/world/format/io/WorldProvider.php b/src/world/format/io/WorldProvider.php index d2c858475c..77f0fa1998 100644 --- a/src/world/format/io/WorldProvider.php +++ b/src/world/format/io/WorldProvider.php @@ -36,10 +36,15 @@ interface WorldProvider{ */ public function __construct(string $path); + /** + * Returns the lowest buildable Y coordinate of this world + */ + public function getWorldMinY() : int; + /** * Gets the build height limit of this world */ - public function getWorldHeight() : int; + public function getWorldMaxY() : int; public function getPath() : string; diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index d428d8b4ef..a84391543c 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -132,7 +132,11 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ return new BedrockWorldData($this->getPath() . DIRECTORY_SEPARATOR . "level.dat"); } - public function getWorldHeight() : int{ + public function getWorldMinY() : int{ + return 0; + } + + public function getWorldMaxY() : int{ return 256; } diff --git a/src/world/format/io/region/Anvil.php b/src/world/format/io/region/Anvil.php index 88951c92bf..dc2c039d4c 100644 --- a/src/world/format/io/region/Anvil.php +++ b/src/world/format/io/region/Anvil.php @@ -51,7 +51,11 @@ class Anvil extends RegionWorldProvider{ return 19133; } - public function getWorldHeight() : int{ + public function getWorldMinY() : int{ + return 0; + } + + public function getWorldMaxY() : int{ //TODO: add world height options return 256; } diff --git a/src/world/format/io/region/McRegion.php b/src/world/format/io/region/McRegion.php index 3e5633e0bc..1a80f90b60 100644 --- a/src/world/format/io/region/McRegion.php +++ b/src/world/format/io/region/McRegion.php @@ -106,7 +106,11 @@ class McRegion extends RegionWorldProvider{ return 19132; } - public function getWorldHeight() : int{ + public function getWorldMinY() : int{ + return 0; + } + + public function getWorldMaxY() : int{ //TODO: add world height options return 128; } diff --git a/src/world/format/io/region/PMAnvil.php b/src/world/format/io/region/PMAnvil.php index 960dd53691..58de81d121 100644 --- a/src/world/format/io/region/PMAnvil.php +++ b/src/world/format/io/region/PMAnvil.php @@ -50,7 +50,11 @@ class PMAnvil extends RegionWorldProvider{ return -1; //Not a PC format, only PocketMine-MP } - public function getWorldHeight() : int{ + public function getWorldMinY() : int{ + return 0; + } + + public function getWorldMaxY() : int{ return 256; } } diff --git a/src/world/generator/GeneratorRegisterTask.php b/src/world/generator/GeneratorRegisterTask.php index 79957df50a..5189adf547 100644 --- a/src/world/generator/GeneratorRegisterTask.php +++ b/src/world/generator/GeneratorRegisterTask.php @@ -42,7 +42,9 @@ class GeneratorRegisterTask extends AsyncTask{ /** @var int */ public $worldId; /** @var int */ - public $worldHeight = World::Y_MAX; + public $worldMinY; + /** @var int */ + public $worldMaxY; /** * @param mixed[] $generatorSettings @@ -54,7 +56,8 @@ class GeneratorRegisterTask extends AsyncTask{ $this->settings = igbinary_serialize($generatorSettings); $this->seed = $world->getSeed(); $this->worldId = $world->getId(); - $this->worldHeight = $world->getWorldHeight(); + $this->worldMinY = $world->getMinY(); + $this->worldMaxY = $world->getMaxY(); } public function onRun() : void{ @@ -63,6 +66,6 @@ class GeneratorRegisterTask extends AsyncTask{ * @see Generator::__construct() */ $generator = new $this->generatorClass($this->seed, igbinary_unserialize($this->settings)); - ThreadLocalGeneratorContext::register(new ThreadLocalGeneratorContext($generator, $this->worldHeight), $this->worldId); + ThreadLocalGeneratorContext::register(new ThreadLocalGeneratorContext($generator, $this->worldMinY, $this->worldMaxY), $this->worldId); } } diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 9bcfc85dd1..13c0126d2c 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -83,7 +83,7 @@ class PopulationTask extends AsyncTask{ throw new AssumptionFailedError("Generator context should have been initialized before any PopulationTask execution"); } $generator = $context->getGenerator(); - $manager = new SimpleChunkManager($context->getWorldHeight()); + $manager = new SimpleChunkManager($context->getWorldMinY(), $context->getWorldMaxY()); /** @var Chunk[] $chunks */ $chunks = []; diff --git a/src/world/generator/ThreadLocalGeneratorContext.php b/src/world/generator/ThreadLocalGeneratorContext.php index ebdd8ee274..56a9b78f6a 100644 --- a/src/world/generator/ThreadLocalGeneratorContext.php +++ b/src/world/generator/ThreadLocalGeneratorContext.php @@ -47,15 +47,21 @@ final class ThreadLocalGeneratorContext{ /** @var Generator */ private $generator; - /** @var int */ - private $worldHeight; - public function __construct(Generator $generator, int $worldHeight){ + /** @var int */ + private $worldMinY; + /** @var int */ + private $worldMaxY; + + public function __construct(Generator $generator, int $worldMinY, int $worldMaxY){ $this->generator = $generator; - $this->worldHeight = $worldHeight; + $this->worldMinY = $worldMinY; + $this->worldMaxY = $worldMaxY; } public function getGenerator() : Generator{ return $this->generator; } - public function getWorldHeight() : int{ return $this->worldHeight; } + public function getWorldMinY() : int{ return $this->worldMinY; } + + public function getWorldMaxY() : int{ return $this->worldMaxY; } } diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index f69ac46a9b..70e55ad79b 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -62,7 +62,7 @@ class LightPopulationTask extends AsyncTask{ public function onRun() : void{ $chunk = FastChunkSerializer::deserialize($this->chunk); - $manager = new SimpleChunkManager(); + $manager = new SimpleChunkManager(World::Y_MIN, World::Y_MAX); $manager->setChunk($this->chunkX, $this->chunkZ, $chunk); $blockFactory = BlockFactory::getInstance(); diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index 7ca2c1274d..e86cf95bb9 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -178,7 +178,7 @@ class SkyLightUpdate extends LightUpdate{ break; } } - $result = HeightArray::fill(0); + $result = HeightArray::fill(World::Y_MIN); if($maxSubChunkY === -1){ //whole column is definitely empty return $result; } @@ -188,16 +188,16 @@ class SkyLightUpdate extends LightUpdate{ $y = null; for($subChunkY = $maxSubChunkY; $subChunkY >= 0; $subChunkY--){ $subHighestBlockY = $chunk->getSubChunk($subChunkY)->getHighestBlockAt($x, $z); - if($subHighestBlockY !== -1){ + if($subHighestBlockY !== null){ $y = ($subChunkY * 16) + $subHighestBlockY; break; } } if($y === null){ //no blocks in the column - $result->set($x, $z, 0); + $result->set($x, $z, World::Y_MIN); }else{ - for(; $y >= 0; --$y){ + for(; $y >= World::Y_MIN; --$y){ if($directSkyLightBlockers[$chunk->getFullBlock($x, $y, $z)]){ $result->set($x, $z, $y + 1); break; @@ -221,7 +221,10 @@ class SkyLightUpdate extends LightUpdate{ */ private static function recalculateHeightMapColumn(Chunk $chunk, int $x, int $z, \SplFixedArray $directSkyLightBlockers) : int{ $y = $chunk->getHighestBlockAt($x, $z); - for(; $y >= 0; --$y){ + if($y === null){ + return World::Y_MIN; + } + for(; $y >= World::Y_MIN; --$y){ if($directSkyLightBlockers[$chunk->getFullBlock($x, $y, $z)]){ break; } From 7f177328ca555dfde5996887e98670131519128e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Mar 2021 20:18:55 +0000 Subject: [PATCH 2313/3224] [ci skip] changelog: fix typo --- changelogs/4.0-snapshot.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 8155d3d900..cefa1c955c 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -992,7 +992,7 @@ This version features substantial changes to the network system, improving coher - prismarine (natural, dark and bricks) - red nether brick - red sandstone (and variants) - - stone-line slabs of many variants + - stone-like slabs of many variants ### Items - Implemented the following items: From 34bb22556642b2e16213c4998de0480b0839a0b2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Mar 2021 21:33:17 +0000 Subject: [PATCH 2314/3224] World: rename some poorly-named fields --- src/world/World.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 123e41d314..f1666fb6a7 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -234,11 +234,11 @@ class World implements ChunkManager{ private $neighbourBlockUpdateQueueIndex = []; /** @var bool[] */ - private $chunkPopulationQueue = []; + private $activeChunkPopulationTasks = []; /** @var bool[] */ private $chunkLock = []; /** @var int */ - private $chunkPopulationQueueSize = 2; + private $maxConcurrentChunkPopulationTasks = 2; /** @var bool[] */ private $generatorRegisteredWorkers = []; @@ -405,7 +405,7 @@ class World implements ChunkManager{ $this->chunkTickRadius = min($this->server->getViewDistance(), max(1, (int) $cfg->getProperty("chunk-ticking.tick-radius", 4))); $this->chunksPerTick = (int) $cfg->getProperty("chunk-ticking.per-tick", 40); $this->tickedBlocksPerSubchunkPerTick = (int) $cfg->getProperty("chunk-ticking.blocks-per-subchunk-per-tick", self::DEFAULT_TICKED_BLOCKS_PER_SUBCHUNK_PER_TICK); - $this->chunkPopulationQueueSize = (int) $cfg->getProperty("chunk-generation.population-queue-size", 2); + $this->maxConcurrentChunkPopulationTasks = (int) $cfg->getProperty("chunk-generation.population-queue-size", 2); $dontTickBlocks = array_fill_keys($cfg->getProperty("chunk-ticking.disable-block-ticking", []), true); @@ -2004,13 +2004,13 @@ class World implements ChunkManager{ public function generateChunkCallback(int $x, int $z, ?Chunk $chunk) : void{ Timings::$generationCallback->startTiming(); - if(isset($this->chunkPopulationQueue[$index = World::chunkHash($x, $z)])){ + if(isset($this->activeChunkPopulationTasks[$index = World::chunkHash($x, $z)])){ for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ $this->unlockChunk($x + $xx, $z + $zz); } } - unset($this->chunkPopulationQueue[$index]); + unset($this->activeChunkPopulationTasks[$index]); if($chunk !== null){ $oldChunk = $this->loadChunk($x, $z); @@ -2614,7 +2614,7 @@ class World implements ChunkManager{ * TODO: the return values don't make a lot of sense, but currently stuff depends on them :< */ public function requestChunkPopulation(int $chunkX, int $chunkZ) : bool{ - if(count($this->chunkPopulationQueue) >= $this->chunkPopulationQueueSize){ + if(count($this->activeChunkPopulationTasks) >= $this->maxConcurrentChunkPopulationTasks){ return false; } return $this->orderChunkPopulation($chunkX, $chunkZ); @@ -2631,7 +2631,7 @@ class World implements ChunkManager{ * TODO: the return values don't make sense, but currently stuff depends on them :< */ public function orderChunkPopulation(int $x, int $z) : bool{ - if(isset($this->chunkPopulationQueue[$index = World::chunkHash($x, $z)])){ + if(isset($this->activeChunkPopulationTasks[$index = World::chunkHash($x, $z)])){ return false; } for($xx = -1; $xx <= 1; ++$xx){ @@ -2646,7 +2646,7 @@ class World implements ChunkManager{ if($chunk === null || !$chunk->isPopulated()){ Timings::$population->startTiming(); - $this->chunkPopulationQueue[$index] = true; + $this->activeChunkPopulationTasks[$index] = true; for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ $this->lockChunk($x + $xx, $z + $zz); From d1387ebd0a2018eb2ef82debadb64c80316a6e1f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Mar 2021 21:56:17 +0000 Subject: [PATCH 2315/3224] World: assume that the primary active chunk is not NULL in generateChunkCallback() --- src/world/World.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index f1666fb6a7..4a651c6237 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2005,6 +2005,9 @@ class World implements ChunkManager{ public function generateChunkCallback(int $x, int $z, ?Chunk $chunk) : void{ Timings::$generationCallback->startTiming(); if(isset($this->activeChunkPopulationTasks[$index = World::chunkHash($x, $z)])){ + if($chunk === null){ + throw new AssumptionFailedError("Primary chunk should never be NULL"); + } for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ $this->unlockChunk($x + $xx, $z + $zz); @@ -2012,15 +2015,13 @@ class World implements ChunkManager{ } unset($this->activeChunkPopulationTasks[$index]); - if($chunk !== null){ - $oldChunk = $this->loadChunk($x, $z); - $this->setChunk($x, $z, $chunk, false); - if(($oldChunk === null or !$oldChunk->isPopulated()) and $chunk->isPopulated()){ - (new ChunkPopulateEvent($this, $x, $z, $chunk))->call(); + $oldChunk = $this->loadChunk($x, $z); + $this->setChunk($x, $z, $chunk, false); + if(($oldChunk === null or !$oldChunk->isPopulated()) and $chunk->isPopulated()){ + (new ChunkPopulateEvent($this, $x, $z, $chunk))->call(); - foreach($this->getChunkListeners($x, $z) as $listener){ - $listener->onChunkPopulated($x, $z, $chunk); - } + foreach($this->getChunkListeners($x, $z) as $listener){ + $listener->onChunkPopulated($x, $z, $chunk); } } }elseif($this->isChunkLocked($x, $z)){ From c092a2e83698b9ca31f1d9e14fd81b82b8b16b94 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Mar 2021 23:19:27 +0000 Subject: [PATCH 2316/3224] Separate TickingChunkLoader from ChunkLoader this makes it possible to keep chunks loaded without ticking them. --- changelogs/4.0-snapshot.md | 3 ++ src/player/Player.php | 4 +- ...gChunkLoader.php => PlayerChunkLoader.php} | 4 +- src/world/ChunkLoader.php | 11 +---- src/world/TickingChunkLoader.php | 42 +++++++++++++++++++ src/world/World.php | 4 ++ 6 files changed, 54 insertions(+), 14 deletions(-) rename src/player/{TickingChunkLoader.php => PlayerChunkLoader.php} (92%) create mode 100644 src/world/TickingChunkLoader.php diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index cefa1c955c..4a4fd57684 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -774,6 +774,9 @@ This version features substantial changes to the network system, improving coher - `BlockTransaction`: allows creating batch commits of block changes with validation conditions - if any block can't be applied, the whole transaction fails to apply. - `ChunkListenerNoOpTrait`: contains default no-op stubs for chunk listener implementations - `ChunkListener`: interface allowing subscribing to events happening on a given chunk + - `TickingChunkLoader`: a `ChunkLoader` specialization that allows ticking chunks +- `ChunkLoader` no longer requires implementing `getX()` and `getZ()`. +- `ChunkLoader` no longer causes chunks to get random updates. If this behaviour is needed, implement `TickingChunkLoader`. - The following classes have been renamed: - `pocketmine\world\utils\SubChunkIteratorManager` -> `pocketmine\world\utils\SubChunkExplorer` - The following API methods have been added: diff --git a/src/player/Player.php b/src/player/Player.php index c6f7e74f3c..62a6b589e7 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -211,7 +211,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ protected $chunksPerTick; /** @var ChunkSelector */ protected $chunkSelector; - /** @var TickingChunkLoader */ + /** @var PlayerChunkLoader */ protected $chunkLoader; /** @var bool[] map: raw UUID (string) => bool */ @@ -295,7 +295,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $onGround = true; } - $this->chunkLoader = new TickingChunkLoader($spawn); + $this->chunkLoader = new PlayerChunkLoader($spawn); //load the spawn chunk so we can see the terrain $world->registerChunkLoader($this->chunkLoader, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4, true); diff --git a/src/player/TickingChunkLoader.php b/src/player/PlayerChunkLoader.php similarity index 92% rename from src/player/TickingChunkLoader.php rename to src/player/PlayerChunkLoader.php index 0a95240b43..597b95d82c 100644 --- a/src/player/TickingChunkLoader.php +++ b/src/player/PlayerChunkLoader.php @@ -24,9 +24,9 @@ declare(strict_types=1); namespace pocketmine\player; use pocketmine\math\Vector3; -use pocketmine\world\ChunkLoader; +use pocketmine\world\TickingChunkLoader; -final class TickingChunkLoader implements ChunkLoader{ +final class PlayerChunkLoader implements TickingChunkLoader{ /** @var Vector3 */ private $currentLocation; diff --git a/src/world/ChunkLoader.php b/src/world/ChunkLoader.php index e68f88b561..a2c1e3b9a4 100644 --- a/src/world/ChunkLoader.php +++ b/src/world/ChunkLoader.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\world; /** - * If you want to keep chunks loaded, implement this interface and register it into World. This will also tick chunks. + * If you want to keep chunks loaded, implement this interface and register it into World. * * @see World::registerChunkLoader() * @see World::unregisterChunkLoader() @@ -34,13 +34,4 @@ namespace pocketmine\world; */ interface ChunkLoader{ - /** - * @return float - */ - public function getX(); - - /** - * @return float - */ - public function getZ(); } diff --git a/src/world/TickingChunkLoader.php b/src/world/TickingChunkLoader.php new file mode 100644 index 0000000000..d6bbf9481d --- /dev/null +++ b/src/world/TickingChunkLoader.php @@ -0,0 +1,42 @@ + $this->chunkTickRadius ? $this->chunkTickRadius : $randRange); foreach($this->loaders as $loader){ + if(!($loader instanceof TickingChunkLoader)){ + //TODO: maybe we should just not track non-ticking chunk loaders here? + continue; + } $chunkX = (int) floor($loader->getX()) >> 4; $chunkZ = (int) floor($loader->getZ()) >> 4; From 69cb0ba1bb7a785a5d5f02391054900ff60ee923 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Mar 2021 01:00:49 +0000 Subject: [PATCH 2317/3224] Entity: don't flag as closed until just before cycle destruction this allows stuff that requires a non-cycle-destroyed state to still operate during onDispose(). --- src/entity/Entity.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 825ef27698..4a7a4df778 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -177,6 +177,7 @@ abstract class Entity{ /** @var bool */ protected $closed = false; + private bool $closeInFlight = false; /** @var bool */ private $needsDespawn = false; @@ -1518,12 +1519,18 @@ abstract class Entity{ * WARNING: Entities are unusable after this has been executed! */ final public function close() : void{ + if($this->closeInFlight){ + return; + } + if(!$this->closed){ - $this->closed = true; + $this->closeInFlight = true; (new EntityDespawnEvent($this))->call(); $this->onDispose(); + $this->closed = true; $this->destroyCycles(); + $this->closeInFlight = false; } } From 5dd0b3ac356c3c5a0cd4343c1c7775bc331c9a9a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Mar 2021 21:12:46 +0000 Subject: [PATCH 2318/3224] OOOPS it's a bit too early for this --- src/world/World.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 2d89831bad..032bac3ebc 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -124,8 +124,8 @@ class World implements ChunkManager{ private static $worldIdCounter = 1; public const Y_MASK = 0xFF; - public const Y_MAX = 320; - public const Y_MIN = -64; + public const Y_MAX = 256; + public const Y_MIN = 0; public const TIME_DAY = 1000; public const TIME_NOON = 6000; From a515b5e1b867db3a60611b3ebf9b17907f8d4a4d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Mar 2021 21:13:56 +0000 Subject: [PATCH 2319/3224] World: remove dead constant Y_MASK --- src/world/World.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index 032bac3ebc..23bf18f8c4 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -123,7 +123,6 @@ class World implements ChunkManager{ /** @var int */ private static $worldIdCounter = 1; - public const Y_MASK = 0xFF; public const Y_MAX = 256; public const Y_MIN = 0; From 90161f24e3318b21a8c2e7e1e839314dab901e25 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 22 Mar 2021 16:00:09 +0000 Subject: [PATCH 2320/3224] Added script to update registry/enum docblocks --- build/generate-registry-annotations.php | 76 +++++++++++++++++++++++++ src/block/utils/DyeColor.php | 36 ++++++------ src/block/utils/RecordType.php | 26 ++++----- src/block/utils/SkullType.php | 16 +++--- src/block/utils/SlabType.php | 10 ++-- src/block/utils/StairShape.php | 14 ++--- src/block/utils/TreeType.php | 16 +++--- src/entity/effect/VanillaEffects.php | 2 +- src/item/ItemUseResult.php | 10 ++-- src/item/ToolTier.php | 12 ++-- src/player/GameMode.php | 12 ++-- src/player/UsedChunkStatus.php | 8 +-- src/plugin/PluginEnableOrder.php | 8 +-- src/world/sound/NoteInstrument.php | 14 ++--- 14 files changed, 168 insertions(+), 92 deletions(-) create mode 100644 build/generate-registry-annotations.php diff --git a/build/generate-registry-annotations.php b/build/generate-registry-annotations.php new file mode 100644 index 0000000000..71397590c0 --- /dev/null +++ b/build/generate-registry-annotations.php @@ -0,0 +1,76 @@ +getDocComment(); + if($docComment === false || (preg_match("/^\s*\*\s*\@see .+::_generateMethodAnnotations\(\)$/m", $docComment) !== 1 && preg_match("/^\s*\*\s*@generate-registry-docblock$/m", $docComment) !== 1)){ + continue; + } + echo "Found registry in $file\n"; + + $replacement = RegistryUtils::_generateMethodAnnotations($matches[1], $className::getAll()); + + $newContents = str_replace($docComment, $replacement, $contents); + if($newContents !== $contents){ + echo "Writing changed file $file\n"; + file_put_contents($file, $newContents); + }else{ + echo "No changes made to file $file\n"; + } +} + diff --git a/src/block/utils/DyeColor.php b/src/block/utils/DyeColor.php index 0c0761d61d..d247758686 100644 --- a/src/block/utils/DyeColor.php +++ b/src/block/utils/DyeColor.php @@ -28,25 +28,25 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. - * This must be regenerated whenever enum members are added, removed or changed. - * @see EnumTrait::_generateMethodAnnotations() + * This must be regenerated whenever registry members are added, removed or changed. + * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static self WHITE() - * @method static self ORANGE() - * @method static self MAGENTA() - * @method static self LIGHT_BLUE() - * @method static self YELLOW() - * @method static self LIME() - * @method static self PINK() - * @method static self GRAY() - * @method static self LIGHT_GRAY() - * @method static self CYAN() - * @method static self PURPLE() - * @method static self BLUE() - * @method static self BROWN() - * @method static self GREEN() - * @method static self RED() - * @method static self BLACK() + * @method static DyeColor WHITE() + * @method static DyeColor ORANGE() + * @method static DyeColor MAGENTA() + * @method static DyeColor LIGHT_BLUE() + * @method static DyeColor YELLOW() + * @method static DyeColor LIME() + * @method static DyeColor PINK() + * @method static DyeColor GRAY() + * @method static DyeColor LIGHT_GRAY() + * @method static DyeColor CYAN() + * @method static DyeColor PURPLE() + * @method static DyeColor BLUE() + * @method static DyeColor BROWN() + * @method static DyeColor GREEN() + * @method static DyeColor RED() + * @method static DyeColor BLACK() */ final class DyeColor{ use EnumTrait { diff --git a/src/block/utils/RecordType.php b/src/block/utils/RecordType.php index 9846e3716e..2ab3a27bd0 100644 --- a/src/block/utils/RecordType.php +++ b/src/block/utils/RecordType.php @@ -29,20 +29,20 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see RegistryTrait::_generateMethodAnnotations() + * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static self DISK_13() - * @method static self DISK_CAT() - * @method static self DISK_BLOCKS() - * @method static self DISK_CHIRP() - * @method static self DISK_FAR() - * @method static self DISK_MALL() - * @method static self DISK_MELLOHI() - * @method static self DISK_STAL() - * @method static self DISK_STRAD() - * @method static self DISK_WARD() - * @method static self DISK_11() - * @method static self DISK_WAIT() + * @method static RecordType DISK_13() + * @method static RecordType DISK_CAT() + * @method static RecordType DISK_BLOCKS() + * @method static RecordType DISK_CHIRP() + * @method static RecordType DISK_FAR() + * @method static RecordType DISK_MALL() + * @method static RecordType DISK_MELLOHI() + * @method static RecordType DISK_STAL() + * @method static RecordType DISK_STRAD() + * @method static RecordType DISK_WARD() + * @method static RecordType DISK_11() + * @method static RecordType DISK_WAIT() */ final class RecordType{ use EnumTrait { diff --git a/src/block/utils/SkullType.php b/src/block/utils/SkullType.php index 43934ff2d1..70757b6fb6 100644 --- a/src/block/utils/SkullType.php +++ b/src/block/utils/SkullType.php @@ -27,15 +27,15 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. - * This must be regenerated whenever enum members are added, removed or changed. - * @see EnumTrait::_generateMethodAnnotations() + * This must be regenerated whenever registry members are added, removed or changed. + * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static self SKELETON() - * @method static self WITHER_SKELETON() - * @method static self ZOMBIE() - * @method static self PLAYER() - * @method static self CREEPER() - * @method static self DRAGON() + * @method static SkullType SKELETON() + * @method static SkullType WITHER_SKELETON() + * @method static SkullType ZOMBIE() + * @method static SkullType PLAYER() + * @method static SkullType CREEPER() + * @method static SkullType DRAGON() */ final class SkullType{ use EnumTrait { diff --git a/src/block/utils/SlabType.php b/src/block/utils/SlabType.php index a56cf7ed4c..287e7626f5 100644 --- a/src/block/utils/SlabType.php +++ b/src/block/utils/SlabType.php @@ -27,12 +27,12 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. - * This must be regenerated whenever enum members are added, removed or changed. - * @see EnumTrait::_generateMethodAnnotations() + * This must be regenerated whenever registry members are added, removed or changed. + * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static self BOTTOM() - * @method static self TOP() - * @method static self DOUBLE() + * @method static SlabType BOTTOM() + * @method static SlabType TOP() + * @method static SlabType DOUBLE() */ final class SlabType{ use EnumTrait; diff --git a/src/block/utils/StairShape.php b/src/block/utils/StairShape.php index b46b19f115..32ed134133 100644 --- a/src/block/utils/StairShape.php +++ b/src/block/utils/StairShape.php @@ -27,14 +27,14 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. - * This must be regenerated whenever enum members are added, removed or changed. - * @see EnumTrait::_generateMethodAnnotations() + * This must be regenerated whenever registry members are added, removed or changed. + * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static self STRAIGHT() - * @method static self INNER_LEFT() - * @method static self INNER_RIGHT() - * @method static self OUTER_LEFT() - * @method static self OUTER_RIGHT() + * @method static StairShape STRAIGHT() + * @method static StairShape INNER_LEFT() + * @method static StairShape INNER_RIGHT() + * @method static StairShape OUTER_LEFT() + * @method static StairShape OUTER_RIGHT() */ final class StairShape{ use EnumTrait; diff --git a/src/block/utils/TreeType.php b/src/block/utils/TreeType.php index b3afdd95ec..cd8443b22e 100644 --- a/src/block/utils/TreeType.php +++ b/src/block/utils/TreeType.php @@ -27,15 +27,15 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. - * This must be regenerated whenever enum members are added, removed or changed. - * @see EnumTrait::_generateMethodAnnotations() + * This must be regenerated whenever registry members are added, removed or changed. + * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static self OAK() - * @method static self SPRUCE() - * @method static self BIRCH() - * @method static self JUNGLE() - * @method static self ACACIA() - * @method static self DARK_OAK() + * @method static TreeType OAK() + * @method static TreeType SPRUCE() + * @method static TreeType BIRCH() + * @method static TreeType JUNGLE() + * @method static TreeType ACACIA() + * @method static TreeType DARK_OAK() */ final class TreeType{ use EnumTrait { diff --git a/src/entity/effect/VanillaEffects.php b/src/entity/effect/VanillaEffects.php index 562682dad8..bef5f7aa93 100644 --- a/src/entity/effect/VanillaEffects.php +++ b/src/entity/effect/VanillaEffects.php @@ -30,7 +30,7 @@ use function assert; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see RegistryTrait::_generateMethodAnnotations() + * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * * @method static AbsorptionEffect ABSORPTION() * @method static Effect BLINDNESS() diff --git a/src/item/ItemUseResult.php b/src/item/ItemUseResult.php index 4469458033..298381131e 100644 --- a/src/item/ItemUseResult.php +++ b/src/item/ItemUseResult.php @@ -27,12 +27,12 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. - * This must be regenerated whenever enum members are added, removed or changed. - * @see EnumTrait::_generateMethodAnnotations() + * This must be regenerated whenever registry members are added, removed or changed. + * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static self NONE() - * @method static self FAIL() - * @method static self SUCCESS() + * @method static ItemUseResult NONE() + * @method static ItemUseResult FAIL() + * @method static ItemUseResult SUCCESS() */ final class ItemUseResult{ use EnumTrait; diff --git a/src/item/ToolTier.php b/src/item/ToolTier.php index 30e184e9fa..08a1c0427a 100644 --- a/src/item/ToolTier.php +++ b/src/item/ToolTier.php @@ -28,13 +28,13 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see RegistryTrait::_generateMethodAnnotations() + * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static self WOOD() - * @method static self GOLD() - * @method static self STONE() - * @method static self IRON() - * @method static self DIAMOND() + * @method static ToolTier WOOD() + * @method static ToolTier GOLD() + * @method static ToolTier STONE() + * @method static ToolTier IRON() + * @method static ToolTier DIAMOND() */ final class ToolTier{ use EnumTrait { diff --git a/src/player/GameMode.php b/src/player/GameMode.php index 7d95513bae..e6f81e4949 100644 --- a/src/player/GameMode.php +++ b/src/player/GameMode.php @@ -27,13 +27,13 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. - * This must be regenerated whenever enum members are added, removed or changed. - * @see EnumTrait::_generateMethodAnnotations() + * This must be regenerated whenever registry members are added, removed or changed. + * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static self SURVIVAL() - * @method static self CREATIVE() - * @method static self ADVENTURE() - * @method static self SPECTATOR() + * @method static GameMode SURVIVAL() + * @method static GameMode CREATIVE() + * @method static GameMode ADVENTURE() + * @method static GameMode SPECTATOR() */ final class GameMode{ use EnumTrait { diff --git a/src/player/UsedChunkStatus.php b/src/player/UsedChunkStatus.php index ce36ab86c1..ff8c03089e 100644 --- a/src/player/UsedChunkStatus.php +++ b/src/player/UsedChunkStatus.php @@ -28,11 +28,11 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see RegistryTrait::_generateMethodAnnotations() + * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static self NEEDED() - * @method static self REQUESTED() - * @method static self SENT() + * @method static UsedChunkStatus NEEDED() + * @method static UsedChunkStatus REQUESTED() + * @method static UsedChunkStatus SENT() */ final class UsedChunkStatus{ use EnumTrait; diff --git a/src/plugin/PluginEnableOrder.php b/src/plugin/PluginEnableOrder.php index b79b19d90f..e544272881 100644 --- a/src/plugin/PluginEnableOrder.php +++ b/src/plugin/PluginEnableOrder.php @@ -27,11 +27,11 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. - * This must be regenerated whenever enum members are added, removed or changed. - * @see EnumTrait::_generateMethodAnnotations() + * This must be regenerated whenever registry members are added, removed or changed. + * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static self STARTUP() - * @method static self POSTWORLD() + * @method static PluginEnableOrder STARTUP() + * @method static PluginEnableOrder POSTWORLD() */ final class PluginEnableOrder{ use EnumTrait; diff --git a/src/world/sound/NoteInstrument.php b/src/world/sound/NoteInstrument.php index cd37df98a4..0ddc0eaef3 100644 --- a/src/world/sound/NoteInstrument.php +++ b/src/world/sound/NoteInstrument.php @@ -27,14 +27,14 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. - * This must be regenerated whenever enum members are added, removed or changed. - * @see EnumTrait::_generateMethodAnnotations() + * This must be regenerated whenever registry members are added, removed or changed. + * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static self PIANO() - * @method static self BASS_DRUM() - * @method static self SNARE() - * @method static self CLICKS_AND_STICKS() - * @method static self DOUBLE_BASS() + * @method static NoteInstrument PIANO() + * @method static NoteInstrument BASS_DRUM() + * @method static NoteInstrument SNARE() + * @method static NoteInstrument CLICKS_AND_STICKS() + * @method static NoteInstrument DOUBLE_BASS() */ final class NoteInstrument{ use EnumTrait { From 49438d360dc00c081b20ba60fae9af1485ab3a19 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 22 Mar 2021 16:16:28 +0000 Subject: [PATCH 2321/3224] RegistryUtils: generate ordered doc comments this makes things easier to find, especially in the large ones like VanillaBlocks. --- src/block/VanillaBlocks.php | 32 ++++++++++---------- src/block/utils/CoralType.php | 2 +- src/block/utils/DyeColor.php | 24 +++++++-------- src/block/utils/RecordType.php | 6 ++-- src/block/utils/SkullType.php | 6 ++-- src/block/utils/SlabType.php | 2 +- src/block/utils/StairShape.php | 2 +- src/block/utils/TreeType.php | 8 ++--- src/item/ItemUseResult.php | 2 +- src/item/ToolTier.php | 8 ++--- src/item/VanillaItems.php | 6 ++-- src/item/enchantment/VanillaEnchantments.php | 26 ++++++++-------- src/player/GameMode.php | 4 +-- src/plugin/PluginEnableOrder.php | 2 +- src/utils/RegistryUtils.php | 10 +++++- src/world/sound/NoteInstrument.php | 4 +-- 16 files changed, 76 insertions(+), 68 deletions(-) diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 4cd2e40791..80596f7d29 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -48,8 +48,8 @@ use function assert; * @method static Wood ACACIA_WOOD() * @method static ActivatorRail ACTIVATOR_RAIL() * @method static Air AIR() - * @method static MushroomStem ALL_SIDED_MUSHROOM_STEM() * @method static Flower ALLIUM() + * @method static MushroomStem ALL_SIDED_MUSHROOM_STEM() * @method static Opaque ANDESITE() * @method static Slab ANDESITE_SLAB() * @method static Stair ANDESITE_STAIRS() @@ -94,10 +94,10 @@ use function assert; * @method static BoneBlock BONE_BLOCK() * @method static Bookshelf BOOKSHELF() * @method static BrewingStand BREWING_STAND() + * @method static Opaque BRICKS() * @method static Slab BRICK_SLAB() * @method static Stair BRICK_STAIRS() * @method static Wall BRICK_WALL() - * @method static Opaque BRICKS() * @method static GlazedTerracotta BROWN_GLAZED_TERRACOTTA() * @method static BrownMushroom BROWN_MUSHROOM() * @method static BrownMushroomBlock BROWN_MUSHROOM_BLOCK() @@ -295,14 +295,14 @@ use function assert; * @method static Opaque EMERALD() * @method static EmeraldOre EMERALD_ORE() * @method static EnchantingTable ENCHANTING_TABLE() + * @method static EnderChest ENDER_CHEST() * @method static EndPortalFrame END_PORTAL_FRAME() * @method static EndRod END_ROD() * @method static Opaque END_STONE() + * @method static Opaque END_STONE_BRICKS() * @method static Slab END_STONE_BRICK_SLAB() * @method static Stair END_STONE_BRICK_STAIRS() * @method static Wall END_STONE_BRICK_WALL() - * @method static Opaque END_STONE_BRICKS() - * @method static EnderChest ENDER_CHEST() * @method static Slab FAKE_WOODEN_SLAB() * @method static Farmland FARMLAND() * @method static TallGrass FERN() @@ -440,23 +440,23 @@ use function assert; * @method static Slab MOSSY_COBBLESTONE_SLAB() * @method static Stair MOSSY_COBBLESTONE_STAIRS() * @method static Wall MOSSY_COBBLESTONE_WALL() + * @method static Opaque MOSSY_STONE_BRICKS() * @method static Slab MOSSY_STONE_BRICK_SLAB() * @method static Stair MOSSY_STONE_BRICK_STAIRS() * @method static Wall MOSSY_STONE_BRICK_WALL() - * @method static Opaque MOSSY_STONE_BRICKS() * @method static MushroomStem MUSHROOM_STEM() * @method static Mycelium MYCELIUM() + * @method static Netherrack NETHERRACK() + * @method static Opaque NETHER_BRICKS() * @method static Fence NETHER_BRICK_FENCE() * @method static Slab NETHER_BRICK_SLAB() * @method static Stair NETHER_BRICK_STAIRS() * @method static Wall NETHER_BRICK_WALL() - * @method static Opaque NETHER_BRICKS() * @method static NetherPortal NETHER_PORTAL() * @method static NetherQuartzOre NETHER_QUARTZ_ORE() * @method static NetherReactor NETHER_REACTOR_CORE() * @method static NetherWartPlant NETHER_WART() * @method static Opaque NETHER_WART_BLOCK() - * @method static Netherrack NETHERRACK() * @method static Note NOTE_BLOCK() * @method static WoodenButton OAK_BUTTON() * @method static WoodenDoor OAK_DOOR() @@ -523,13 +523,20 @@ use function assert; * @method static Slab QUARTZ_SLAB() * @method static Stair QUARTZ_STAIRS() * @method static Rail RAIL() + * @method static Redstone REDSTONE() + * @method static RedstoneComparator REDSTONE_COMPARATOR() + * @method static RedstoneLamp REDSTONE_LAMP() + * @method static RedstoneOre REDSTONE_ORE() + * @method static RedstoneRepeater REDSTONE_REPEATER() + * @method static RedstoneTorch REDSTONE_TORCH() + * @method static RedstoneWire REDSTONE_WIRE() * @method static GlazedTerracotta RED_GLAZED_TERRACOTTA() * @method static RedMushroom RED_MUSHROOM() * @method static RedMushroomBlock RED_MUSHROOM_BLOCK() + * @method static Opaque RED_NETHER_BRICKS() * @method static Slab RED_NETHER_BRICK_SLAB() * @method static Stair RED_NETHER_BRICK_STAIRS() * @method static Wall RED_NETHER_BRICK_WALL() - * @method static Opaque RED_NETHER_BRICKS() * @method static Sand RED_SAND() * @method static Opaque RED_SANDSTONE() * @method static Slab RED_SANDSTONE_SLAB() @@ -540,13 +547,6 @@ use function assert; * @method static GlassPane RED_STAINED_GLASS_PANE() * @method static Torch RED_TORCH() * @method static Flower RED_TULIP() - * @method static Redstone REDSTONE() - * @method static RedstoneComparator REDSTONE_COMPARATOR() - * @method static RedstoneLamp REDSTONE_LAMP() - * @method static RedstoneOre REDSTONE_ORE() - * @method static RedstoneRepeater REDSTONE_REPEATER() - * @method static RedstoneTorch REDSTONE_TORCH() - * @method static RedstoneWire REDSTONE_WIRE() * @method static Reserved6 RESERVED6() * @method static DoublePlant ROSE_BUSH() * @method static Sand SAND() @@ -587,10 +587,10 @@ use function assert; * @method static WallSign SPRUCE_WALL_SIGN() * @method static Wood SPRUCE_WOOD() * @method static Opaque STONE() + * @method static Opaque STONE_BRICKS() * @method static Slab STONE_BRICK_SLAB() * @method static Stair STONE_BRICK_STAIRS() * @method static Wall STONE_BRICK_WALL() - * @method static Opaque STONE_BRICKS() * @method static StoneButton STONE_BUTTON() * @method static StonePressurePlate STONE_PRESSURE_PLATE() * @method static Slab STONE_SLAB() diff --git a/src/block/utils/CoralType.php b/src/block/utils/CoralType.php index 0b84c7a061..fb61a95e58 100644 --- a/src/block/utils/CoralType.php +++ b/src/block/utils/CoralType.php @@ -30,11 +30,11 @@ use pocketmine\utils\EnumTrait; * This must be regenerated whenever registry members are added, removed or changed. * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static CoralType TUBE() * @method static CoralType BRAIN() * @method static CoralType BUBBLE() * @method static CoralType FIRE() * @method static CoralType HORN() + * @method static CoralType TUBE() */ final class CoralType{ use EnumTrait { diff --git a/src/block/utils/DyeColor.php b/src/block/utils/DyeColor.php index d247758686..0bd40c8c3c 100644 --- a/src/block/utils/DyeColor.php +++ b/src/block/utils/DyeColor.php @@ -31,22 +31,22 @@ use pocketmine\utils\EnumTrait; * This must be regenerated whenever registry members are added, removed or changed. * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static DyeColor WHITE() - * @method static DyeColor ORANGE() - * @method static DyeColor MAGENTA() - * @method static DyeColor LIGHT_BLUE() - * @method static DyeColor YELLOW() - * @method static DyeColor LIME() - * @method static DyeColor PINK() - * @method static DyeColor GRAY() - * @method static DyeColor LIGHT_GRAY() - * @method static DyeColor CYAN() - * @method static DyeColor PURPLE() + * @method static DyeColor BLACK() * @method static DyeColor BLUE() * @method static DyeColor BROWN() + * @method static DyeColor CYAN() + * @method static DyeColor GRAY() * @method static DyeColor GREEN() + * @method static DyeColor LIGHT_BLUE() + * @method static DyeColor LIGHT_GRAY() + * @method static DyeColor LIME() + * @method static DyeColor MAGENTA() + * @method static DyeColor ORANGE() + * @method static DyeColor PINK() + * @method static DyeColor PURPLE() * @method static DyeColor RED() - * @method static DyeColor BLACK() + * @method static DyeColor WHITE() + * @method static DyeColor YELLOW() */ final class DyeColor{ use EnumTrait { diff --git a/src/block/utils/RecordType.php b/src/block/utils/RecordType.php index 2ab3a27bd0..57def3b4c9 100644 --- a/src/block/utils/RecordType.php +++ b/src/block/utils/RecordType.php @@ -31,18 +31,18 @@ use pocketmine\utils\EnumTrait; * This must be regenerated whenever registry members are added, removed or changed. * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * + * @method static RecordType DISK_11() * @method static RecordType DISK_13() - * @method static RecordType DISK_CAT() * @method static RecordType DISK_BLOCKS() + * @method static RecordType DISK_CAT() * @method static RecordType DISK_CHIRP() * @method static RecordType DISK_FAR() * @method static RecordType DISK_MALL() * @method static RecordType DISK_MELLOHI() * @method static RecordType DISK_STAL() * @method static RecordType DISK_STRAD() - * @method static RecordType DISK_WARD() - * @method static RecordType DISK_11() * @method static RecordType DISK_WAIT() + * @method static RecordType DISK_WARD() */ final class RecordType{ use EnumTrait { diff --git a/src/block/utils/SkullType.php b/src/block/utils/SkullType.php index 70757b6fb6..72bd94d6c2 100644 --- a/src/block/utils/SkullType.php +++ b/src/block/utils/SkullType.php @@ -30,12 +30,12 @@ use pocketmine\utils\EnumTrait; * This must be regenerated whenever registry members are added, removed or changed. * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * + * @method static SkullType CREEPER() + * @method static SkullType DRAGON() + * @method static SkullType PLAYER() * @method static SkullType SKELETON() * @method static SkullType WITHER_SKELETON() * @method static SkullType ZOMBIE() - * @method static SkullType PLAYER() - * @method static SkullType CREEPER() - * @method static SkullType DRAGON() */ final class SkullType{ use EnumTrait { diff --git a/src/block/utils/SlabType.php b/src/block/utils/SlabType.php index 287e7626f5..806fdf5a45 100644 --- a/src/block/utils/SlabType.php +++ b/src/block/utils/SlabType.php @@ -31,8 +31,8 @@ use pocketmine\utils\EnumTrait; * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * * @method static SlabType BOTTOM() - * @method static SlabType TOP() * @method static SlabType DOUBLE() + * @method static SlabType TOP() */ final class SlabType{ use EnumTrait; diff --git a/src/block/utils/StairShape.php b/src/block/utils/StairShape.php index 32ed134133..5f963728ec 100644 --- a/src/block/utils/StairShape.php +++ b/src/block/utils/StairShape.php @@ -30,11 +30,11 @@ use pocketmine\utils\EnumTrait; * This must be regenerated whenever registry members are added, removed or changed. * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static StairShape STRAIGHT() * @method static StairShape INNER_LEFT() * @method static StairShape INNER_RIGHT() * @method static StairShape OUTER_LEFT() * @method static StairShape OUTER_RIGHT() + * @method static StairShape STRAIGHT() */ final class StairShape{ use EnumTrait; diff --git a/src/block/utils/TreeType.php b/src/block/utils/TreeType.php index cd8443b22e..6896784d51 100644 --- a/src/block/utils/TreeType.php +++ b/src/block/utils/TreeType.php @@ -30,12 +30,12 @@ use pocketmine\utils\EnumTrait; * This must be regenerated whenever registry members are added, removed or changed. * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * + * @method static TreeType ACACIA() + * @method static TreeType BIRCH() + * @method static TreeType DARK_OAK() + * @method static TreeType JUNGLE() * @method static TreeType OAK() * @method static TreeType SPRUCE() - * @method static TreeType BIRCH() - * @method static TreeType JUNGLE() - * @method static TreeType ACACIA() - * @method static TreeType DARK_OAK() */ final class TreeType{ use EnumTrait { diff --git a/src/item/ItemUseResult.php b/src/item/ItemUseResult.php index 298381131e..57eff8e2df 100644 --- a/src/item/ItemUseResult.php +++ b/src/item/ItemUseResult.php @@ -30,8 +30,8 @@ use pocketmine\utils\EnumTrait; * This must be regenerated whenever registry members are added, removed or changed. * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static ItemUseResult NONE() * @method static ItemUseResult FAIL() + * @method static ItemUseResult NONE() * @method static ItemUseResult SUCCESS() */ final class ItemUseResult{ diff --git a/src/item/ToolTier.php b/src/item/ToolTier.php index 08a1c0427a..85e363c3e7 100644 --- a/src/item/ToolTier.php +++ b/src/item/ToolTier.php @@ -30,11 +30,11 @@ use pocketmine\utils\EnumTrait; * This must be regenerated whenever registry members are added, removed or changed. * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static ToolTier WOOD() - * @method static ToolTier GOLD() - * @method static ToolTier STONE() - * @method static ToolTier IRON() * @method static ToolTier DIAMOND() + * @method static ToolTier GOLD() + * @method static ToolTier IRON() + * @method static ToolTier STONE() + * @method static ToolTier WOOD() */ final class ToolTier{ use EnumTrait { diff --git a/src/item/VanillaItems.php b/src/item/VanillaItems.php index 581b27d194..886751907e 100644 --- a/src/item/VanillaItems.php +++ b/src/item/VanillaItems.php @@ -146,8 +146,6 @@ use function assert; * @method static GlassBottle GLASS_BOTTLE() * @method static Item GLISTERING_MELON() * @method static Item GLOWSTONE_DUST() - * @method static Item GOLD_INGOT() - * @method static Item GOLD_NUGGET() * @method static GoldenApple GOLDEN_APPLE() * @method static Axe GOLDEN_AXE() * @method static Armor GOLDEN_BOOTS() @@ -159,6 +157,8 @@ use function assert; * @method static Pickaxe GOLDEN_PICKAXE() * @method static Shovel GOLDEN_SHOVEL() * @method static Sword GOLDEN_SWORD() + * @method static Item GOLD_INGOT() + * @method static Item GOLD_NUGGET() * @method static Bed GRAY_BED() * @method static Dye GRAY_DYE() * @method static Bed GREEN_BED() @@ -245,9 +245,9 @@ use function assert; * @method static Record RECORD_STRAD() * @method static Record RECORD_WAIT() * @method static Record RECORD_WARD() + * @method static Redstone REDSTONE_DUST() * @method static Bed RED_BED() * @method static Dye RED_DYE() - * @method static Redstone REDSTONE_DUST() * @method static RottenFlesh ROTTEN_FLESH() * @method static Item SCUTE() * @method static Shears SHEARS() diff --git a/src/item/enchantment/VanillaEnchantments.php b/src/item/enchantment/VanillaEnchantments.php index 42f074db60..f961f22834 100644 --- a/src/item/enchantment/VanillaEnchantments.php +++ b/src/item/enchantment/VanillaEnchantments.php @@ -31,24 +31,24 @@ use pocketmine\utils\RegistryTrait; * This must be regenerated whenever registry members are added, removed or changed. * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static ProtectionEnchantment PROTECTION() - * @method static ProtectionEnchantment FIRE_PROTECTION() - * @method static ProtectionEnchantment FEATHER_FALLING() * @method static ProtectionEnchantment BLAST_PROTECTION() - * @method static ProtectionEnchantment PROJECTILE_PROTECTION() - * @method static Enchantment THORNS() - * @method static Enchantment RESPIRATION() - * @method static SharpnessEnchantment SHARPNESS() - * @method static KnockbackEnchantment KNOCKBACK() - * @method static FireAspectEnchantment FIRE_ASPECT() * @method static Enchantment EFFICIENCY() - * @method static Enchantment SILK_TOUCH() - * @method static Enchantment UNBREAKING() - * @method static Enchantment POWER() - * @method static Enchantment PUNCH() + * @method static ProtectionEnchantment FEATHER_FALLING() + * @method static FireAspectEnchantment FIRE_ASPECT() + * @method static ProtectionEnchantment FIRE_PROTECTION() * @method static Enchantment FLAME() * @method static Enchantment INFINITY() + * @method static KnockbackEnchantment KNOCKBACK() * @method static Enchantment MENDING() + * @method static Enchantment POWER() + * @method static ProtectionEnchantment PROJECTILE_PROTECTION() + * @method static ProtectionEnchantment PROTECTION() + * @method static Enchantment PUNCH() + * @method static Enchantment RESPIRATION() + * @method static SharpnessEnchantment SHARPNESS() + * @method static Enchantment SILK_TOUCH() + * @method static Enchantment THORNS() + * @method static Enchantment UNBREAKING() * @method static Enchantment VANISHING() */ final class VanillaEnchantments{ diff --git a/src/player/GameMode.php b/src/player/GameMode.php index e6f81e4949..d8e2d28bfe 100644 --- a/src/player/GameMode.php +++ b/src/player/GameMode.php @@ -30,10 +30,10 @@ use pocketmine\utils\EnumTrait; * This must be regenerated whenever registry members are added, removed or changed. * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static GameMode SURVIVAL() - * @method static GameMode CREATIVE() * @method static GameMode ADVENTURE() + * @method static GameMode CREATIVE() * @method static GameMode SPECTATOR() + * @method static GameMode SURVIVAL() */ final class GameMode{ use EnumTrait { diff --git a/src/plugin/PluginEnableOrder.php b/src/plugin/PluginEnableOrder.php index e544272881..ae800decb6 100644 --- a/src/plugin/PluginEnableOrder.php +++ b/src/plugin/PluginEnableOrder.php @@ -30,8 +30,8 @@ use pocketmine\utils\EnumTrait; * This must be regenerated whenever registry members are added, removed or changed. * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static PluginEnableOrder STARTUP() * @method static PluginEnableOrder POSTWORLD() + * @method static PluginEnableOrder STARTUP() */ final class PluginEnableOrder{ use EnumTrait; diff --git a/src/utils/RegistryUtils.php b/src/utils/RegistryUtils.php index 3394f2b9f5..e83cdfaae5 100644 --- a/src/utils/RegistryUtils.php +++ b/src/utils/RegistryUtils.php @@ -27,6 +27,7 @@ use function get_class; use function implode; use function mb_strtoupper; use function sprintf; +use const SORT_STRING; final class RegistryUtils{ @@ -63,6 +64,7 @@ public static function %1$s() : %2$s{ $lines[] = " *"; static $lineTmpl = " * @method static %2\$s %s()"; + $memberLines = []; foreach($members as $name => $member){ $reflect = new \ReflectionClass($member); while($reflect !== false and $reflect->isAnonymous()){ @@ -75,7 +77,13 @@ public static function %1$s() : %2$s{ }else{ $typehint = '\\' . $reflect->getName(); } - $lines[] = sprintf($lineTmpl, mb_strtoupper($name), $typehint); + $accessor = mb_strtoupper($name); + $memberLines[$accessor] = sprintf($lineTmpl, $accessor, $typehint); + } + ksort($memberLines, SORT_STRING); + + foreach($memberLines as $line){ + $lines[] = $line; } $lines[] = " */"; return implode("\n", $lines); diff --git a/src/world/sound/NoteInstrument.php b/src/world/sound/NoteInstrument.php index 0ddc0eaef3..bec080d071 100644 --- a/src/world/sound/NoteInstrument.php +++ b/src/world/sound/NoteInstrument.php @@ -30,11 +30,11 @@ use pocketmine\utils\EnumTrait; * This must be regenerated whenever registry members are added, removed or changed. * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() * - * @method static NoteInstrument PIANO() * @method static NoteInstrument BASS_DRUM() - * @method static NoteInstrument SNARE() * @method static NoteInstrument CLICKS_AND_STICKS() * @method static NoteInstrument DOUBLE_BASS() + * @method static NoteInstrument PIANO() + * @method static NoteInstrument SNARE() */ final class NoteInstrument{ use EnumTrait { From eb9b644447059633de519dbc6a5ad0cb916033e7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 22 Mar 2021 21:54:27 +0000 Subject: [PATCH 2322/3224] PressurePlate: remove collision boxes, closes #4045 --- src/block/PressurePlate.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/block/PressurePlate.php b/src/block/PressurePlate.php index b2914fd3ae..b133e3225e 100644 --- a/src/block/PressurePlate.php +++ b/src/block/PressurePlate.php @@ -29,5 +29,9 @@ abstract class PressurePlate extends Transparent{ return false; } + protected function recalculateCollisionBoxes() : array{ + return []; + } + //TODO } From 8dd900a2c61403921aa1406c83245a64ef831306 Mon Sep 17 00:00:00 2001 From: IceCruelStuff <50642756+IceCruelStuff@users.noreply.github.com> Date: Mon, 22 Mar 2021 17:00:13 -0700 Subject: [PATCH 2323/3224] Sugarcane: allow placement on podzol (#4094) --- src/block/Sugarcane.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/Sugarcane.php b/src/block/Sugarcane.php index 5165e820da..43aa30538f 100644 --- a/src/block/Sugarcane.php +++ b/src/block/Sugarcane.php @@ -125,7 +125,7 @@ class Sugarcane extends Flowable{ $down = $this->getSide(Facing::DOWN); if($down->isSameType($this)){ return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); - }elseif($down->getId() === BlockLegacyIds::GRASS or $down->getId() === BlockLegacyIds::DIRT or $down->getId() === BlockLegacyIds::SAND){ + }elseif($down->getId() === BlockLegacyIds::GRASS or $down->getId() === BlockLegacyIds::DIRT or $down->getId() === BlockLegacyIds::SAND or $down->getId() === BlockLegacyIds::PODZOL){ foreach(Facing::HORIZONTAL as $side){ if($down->getSide($side) instanceof Water){ return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); From 51449265ee98a6d0e36ebf6b9764220a90528c7c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 23 Mar 2021 15:04:51 +0000 Subject: [PATCH 2324/3224] Updated composer dependencies this should also bring the phar back down to a sensible size ... --- composer.lock | 128 +++++++++++++++----------------------------------- 1 file changed, 37 insertions(+), 91 deletions(-) diff --git a/composer.lock b/composer.lock index 9d350331d5..a83cc55b9e 100644 --- a/composer.lock +++ b/composer.lock @@ -696,12 +696,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "edd403e465b0974ecfcd20d41da98ecada22e6a6" + "reference": "3c226482dd0e966ee9bf26fac405f083cb97ea68" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/edd403e465b0974ecfcd20d41da98ecada22e6a6", - "reference": "edd403e465b0974ecfcd20d41da98ecada22e6a6", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/3c226482dd0e966ee9bf26fac405f083cb97ea68", + "reference": "3c226482dd0e966ee9bf26fac405f083cb97ea68", "shasum": "" }, "require": { @@ -713,7 +713,7 @@ "pocketmine/log": "dev-master" }, "require-dev": { - "phpstan/phpstan": "0.12.67", + "phpstan/phpstan": "0.12.81", "phpstan/phpstan-strict-rules": "^0.12.2" }, "type": "library", @@ -731,7 +731,7 @@ "issues": "https://github.com/pmmp/RakLib/issues", "source": "https://github.com/pmmp/RakLib/tree/master" }, - "time": "2021-01-15T16:23:13+00:00" + "time": "2021-03-16T19:35:37+00:00" }, { "name": "pocketmine/snooze", @@ -1035,22 +1035,21 @@ }, { "name": "respect/validation", - "version": "2.2.1", + "version": "2.2.3", "source": { "type": "git", "url": "https://github.com/Respect/Validation.git", - "reference": "51ad23e24c83f222468174861de61fc8bcde9bfb" + "reference": "4c21a7ffc9a4915673cb2c2843963919e664e627" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Respect/Validation/zipball/51ad23e24c83f222468174861de61fc8bcde9bfb", - "reference": "51ad23e24c83f222468174861de61fc8bcde9bfb", + "url": "https://api.github.com/repos/Respect/Validation/zipball/4c21a7ffc9a4915673cb2c2843963919e664e627", + "reference": "4c21a7ffc9a4915673cb2c2843963919e664e627", "shasum": "" }, "require": { "php": "^7.3 || ^8.0", "respect/stringifier": "^0.2.0", - "sokil/php-isocodes": "^3.3", "symfony/polyfill-mbstring": "^1.2" }, "require-dev": { @@ -1072,7 +1071,6 @@ "ext-bcmath": "Arbitrary Precision Mathematics", "ext-fileinfo": "File Information", "ext-mbstring": "Multibyte String Functions", - "sokil/php-isocodes": "To enable ISO codes validations", "symfony/validator": "Use Symfony validator through Respect\\Validation", "zendframework/zend-validator": "Use Zend Framework validator through Respect\\Validation" }, @@ -1101,66 +1099,9 @@ ], "support": { "issues": "https://github.com/Respect/Validation/issues", - "source": "https://github.com/Respect/Validation/tree/2.2.1" + "source": "https://github.com/Respect/Validation/tree/2.2.3" }, - "time": "2021-02-06T16:42:11+00:00" - }, - { - "name": "sokil/php-isocodes", - "version": "3.3.5", - "source": { - "type": "git", - "url": "https://github.com/sokil/php-isocodes.git", - "reference": "1b3d6911c61a8e929f30367ac7fac5b9f48f4d58" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sokil/php-isocodes/zipball/1b3d6911c61a8e929f30367ac7fac5b9f48f4d58", - "reference": "1b3d6911c61a8e929f30367ac7fac5b9f48f4d58", - "shasum": "" - }, - "require": { - "ext-json": "*", - "php": ">=7.1" - }, - "require-dev": { - "ext-gettext": "*", - "php-coveralls/php-coveralls": "^2.1", - "phpmd/phpmd": "@stable", - "phpunit/phpunit": ">=7.5.20", - "squizlabs/php_codesniffer": "^3.4", - "symfony/translation": "^4.4.17|^5.2", - "vimeo/psalm": "^4.3" - }, - "suggest": { - "ext-gettext": "Required for gettext translation driver", - "phpbench/phpbench": "Required to run benchmarks", - "symfony/translation": "Translation driver by Symfont project" - }, - "type": "library", - "autoload": { - "psr-4": { - "Sokil\\IsoCodes\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dmytro Sokil", - "email": "dmytro.sokil@gmail.com" - } - ], - "description": "ISO country, subdivision, language, currency and script definitions and their translations. Based on pythons pycountry and Debian's iso-codes.", - "support": { - "issues": "https://github.com/sokil/php-isocodes/issues", - "source": "https://github.com/sokil/php-isocodes/tree/3.3.5" - }, - "time": "2021-03-02T08:18:52+00:00" + "time": "2021-03-19T14:12:45+00:00" }, { "name": "symfony/polyfill-ctype", @@ -1777,16 +1718,16 @@ }, { "name": "phpspec/prophecy", - "version": "1.12.2", + "version": "1.13.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "245710e971a030f42e08f4912863805570f23d39" + "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/245710e971a030f42e08f4912863805570f23d39", - "reference": "245710e971a030f42e08f4912863805570f23d39", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be1996ed8adc35c3fd795488a653f4b518be70ea", + "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea", "shasum": "" }, "require": { @@ -1838,9 +1779,9 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/1.12.2" + "source": "https://github.com/phpspec/prophecy/tree/1.13.0" }, - "time": "2020-12-19T10:15:11+00:00" + "time": "2021-03-17T13:42:18+00:00" }, { "name": "phpstan/phpstan", @@ -2328,16 +2269,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.2", + "version": "9.5.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "f661659747f2f87f9e72095bb207bceb0f151cb4" + "reference": "c73c6737305e779771147af66c96ca6a7ed8a741" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f661659747f2f87f9e72095bb207bceb0f151cb4", - "reference": "f661659747f2f87f9e72095bb207bceb0f151cb4", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c73c6737305e779771147af66c96ca6a7ed8a741", + "reference": "c73c6737305e779771147af66c96ca6a7ed8a741", "shasum": "" }, "require": { @@ -2415,7 +2356,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.2" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.4" }, "funding": [ { @@ -2427,7 +2368,7 @@ "type": "github" } ], - "time": "2021-02-02T14:45:58+00:00" + "time": "2021-03-23T07:16:29+00:00" }, { "name": "sebastian/cli-parser", @@ -3445,30 +3386,35 @@ }, { "name": "webmozart/assert", - "version": "1.9.1", + "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0 || ^8.0", + "php": "^7.2 || ^8.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<3.9.1" + "vimeo/psalm": "<4.6.1 || 4.6.2" }, "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" + "phpunit/phpunit": "^8.5.13" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" @@ -3492,9 +3438,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.9.1" + "source": "https://github.com/webmozarts/assert/tree/1.10.0" }, - "time": "2020-07-08T17:02:28+00:00" + "time": "2021-03-09T10:59:23+00:00" } ], "aliases": [], From 9ee80357b071a0f11b6bc27ae6d7fb50c5573d7f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 23 Mar 2021 15:24:20 +0000 Subject: [PATCH 2325/3224] phpstan baselines cleanup --- .../check-explicit-mixed-baseline.neon | 12 ++--- tests/phpstan/configs/l7-baseline.neon | 5 -- tests/phpstan/configs/l8-baseline.neon | 10 ---- tests/phpstan/configs/phpstan-bugs.neon | 54 +------------------ 4 files changed, 8 insertions(+), 73 deletions(-) diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index 03a4f7b039..d916a7c1ad 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -295,11 +295,6 @@ parameters: count: 1 path: ../../../src/world/World.php - - - message: "#^Parameter \\#2 \\$value of method pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\:\\:setString\\(\\) expects string, mixed given\\.$#" - count: 1 - path: ../../../src/world/format/io/data/BedrockWorldData.php - - message: "#^Cannot cast mixed to string\\.$#" count: 1 @@ -308,10 +303,15 @@ parameters: - message: "#^Parameter \\#2 \\$value of method pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\:\\:setString\\(\\) expects string, mixed given\\.$#" count: 1 + path: ../../../src/world/format/io/data/BedrockWorldData.php + + - + message: "#^Cannot cast mixed to string\\.$#" + count: 1 path: ../../../src/world/format/io/data/JavaWorldData.php - - message: "#^Cannot cast mixed to string\\.$#" + message: "#^Parameter \\#2 \\$value of method pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\:\\:setString\\(\\) expects string, mixed given\\.$#" count: 1 path: ../../../src/world/format/io/data/JavaWorldData.php diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index 062ae484a9..69a21acb6d 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -495,11 +495,6 @@ parameters: count: 2 path: ../../../src/command/defaults/TimingsCommand.php - - - message: "#^Parameter \\#4 \\$data of class class@anonymous/src/command/defaults/TimingsCommand\\.php\\:131 constructor expects array\\, array\\ given\\.$#" - count: 1 - path: ../../../src/command/defaults/TimingsCommand.php - - message: "#^Method pocketmine\\\\crafting\\\\CraftingManager\\:\\:hashOutputs\\(\\) should return string but returns string\\|false\\.$#" count: 1 diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index a47dced38f..4ecce795e2 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -85,16 +85,6 @@ parameters: count: 1 path: ../../../src/inventory/transaction/CraftingTransaction.php - - - message: "#^Cannot call method getUsername\\(\\) on pocketmine\\\\player\\\\PlayerInfo\\|null\\.$#" - count: 1 - path: ../../../src/network/NetworkSessionManager.php - - - - message: "#^Cannot call method getUuid\\(\\) on pocketmine\\\\player\\\\PlayerInfo\\|null\\.$#" - count: 1 - path: ../../../src/network/NetworkSessionManager.php - - message: "#^Parameter \\#1 \\$entity of method pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:onEntityEffectAdded\\(\\) expects pocketmine\\\\entity\\\\Living, pocketmine\\\\player\\\\Player\\|null given\\.$#" count: 1 diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index a1015584ff..ad2384eede 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -6,9 +6,9 @@ parameters: path: ../../../src/command/CommandReader.php - - message: "#^Property pocketmine\\\\crafting\\\\CraftingManager\\:\\:\\$recipeRegisteredCallbacks \\(pocketmine\\\\utils\\\\ObjectSet\\\\) does not accept pocketmine\\\\utils\\\\ObjectSet\\\\.$#" + message: "#^Call to function assert\\(\\) with false and 'unknown hit type' will always evaluate to false\\.$#" count: 1 - path: ../../../src/crafting/CraftingManager.php + path: ../../../src/entity/projectile/Projectile.php - message: "#^Method pocketmine\\\\crafting\\\\CraftingManager\\:\\:getDestructorCallbacks\\(\\) should return pocketmine\\\\utils\\\\ObjectSet\\ but returns pocketmine\\\\utils\\\\ObjectSet\\\\|pocketmine\\\\utils\\\\ObjectSet\\\\.$#" @@ -20,56 +20,6 @@ parameters: count: 1 path: ../../../src/crafting/CraftingManager.php - - - message: "#^Property pocketmine\\\\crafting\\\\FurnaceRecipeManager\\:\\:\\$recipeRegisteredCallbacks \\(pocketmine\\\\utils\\\\ObjectSet\\\\) does not accept pocketmine\\\\utils\\\\ObjectSet\\\\.$#" - count: 1 - path: ../../../src/crafting/FurnaceRecipeManager.php - - - - message: "#^Undefined variable\\: \\$blockstate$#" - count: 1 - path: ../../../src/data/bedrock/blockstate/BlockStateDeserializerR13.php - - - - message: "#^Property pocketmine\\\\entity\\\\effect\\\\EffectManager\\:\\:\\$effectAddHooks \\(pocketmine\\\\utils\\\\ObjectSet\\\\) does not accept pocketmine\\\\utils\\\\ObjectSet\\\\.$#" - count: 1 - path: ../../../src/entity/effect/EffectManager.php - - - - message: "#^Property pocketmine\\\\entity\\\\effect\\\\EffectManager\\:\\:\\$effectRemoveHooks \\(pocketmine\\\\utils\\\\ObjectSet\\\\) does not accept pocketmine\\\\utils\\\\ObjectSet\\\\.$#" - count: 1 - path: ../../../src/entity/effect/EffectManager.php - - - - message: "#^Call to function assert\\(\\) with false and 'unknown hit type' will always evaluate to false\\.$#" - count: 1 - path: ../../../src/entity/projectile/Projectile.php - - - - message: "#^Property pocketmine\\\\inventory\\\\BaseInventory\\:\\:\\$listeners \\(pocketmine\\\\utils\\\\ObjectSet\\\\) does not accept pocketmine\\\\utils\\\\ObjectSet\\\\.$#" - count: 1 - path: ../../../src/inventory/BaseInventory.php - - - - message: "#^Property pocketmine\\\\inventory\\\\PlayerInventory\\:\\:\\$heldItemIndexChangeListeners \\(pocketmine\\\\utils\\\\ObjectSet\\\\) does not accept pocketmine\\\\utils\\\\ObjectSet\\\\.$#" - count: 1 - path: ../../../src/inventory/PlayerInventory.php - - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:\\$disposeHooks \\(pocketmine\\\\utils\\\\ObjectSet\\\\) does not accept pocketmine\\\\utils\\\\ObjectSet\\\\.$#" - count: 1 - path: ../../../src/network/mcpe/NetworkSession.php - - - - message: "#^Property pocketmine\\\\permission\\\\PermissibleBase\\:\\:\\$permissionRecalculationCallbacks \\(pocketmine\\\\utils\\\\ObjectSet\\\\)\\: void\\>\\) does not accept pocketmine\\\\utils\\\\ObjectSet\\\\.$#" - count: 1 - path: ../../../src/permission/PermissibleBase.php - - - - message: "#^Property pocketmine\\\\scheduler\\\\TaskScheduler\\:\\:\\$tasks \\(pocketmine\\\\utils\\\\ObjectSet\\\\) does not accept pocketmine\\\\utils\\\\ObjectSet\\\\.$#" - count: 1 - path: ../../../src/scheduler/TaskScheduler.php - - message: "#^Strict comparison using \\=\\=\\= between string and false will always evaluate to false\\.$#" count: 1 From 17dd5748146fefa52b8b3d759b949bef76a7fc96 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 23 Mar 2021 20:00:37 +0000 Subject: [PATCH 2326/3224] Fixed composer lockfile --- composer.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.lock b/composer.lock index a83cc55b9e..1479b1827d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "cef3fa0d56c5b31a25c31b0826406ef9", + "content-hash": "824d613db4986bce5882e3460ef32826", "packages": [ { "name": "adhocore/json-comment", @@ -1785,16 +1785,16 @@ }, { "name": "phpstan/phpstan", - "version": "0.12.81", + "version": "0.12.82", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "0dd5b0ebeff568f7000022ea5f04aa86ad3124b8" + "reference": "3920f0fb0aff39263d3a4cb0bca120a67a1a6a11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0dd5b0ebeff568f7000022ea5f04aa86ad3124b8", - "reference": "0dd5b0ebeff568f7000022ea5f04aa86ad3124b8", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/3920f0fb0aff39263d3a4cb0bca120a67a1a6a11", + "reference": "3920f0fb0aff39263d3a4cb0bca120a67a1a6a11", "shasum": "" }, "require": { @@ -1825,7 +1825,7 @@ "description": "PHPStan - PHP Static Analysis Tool", "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/0.12.81" + "source": "https://github.com/phpstan/phpstan/tree/0.12.82" }, "funding": [ { @@ -1841,7 +1841,7 @@ "type": "tidelift" } ], - "time": "2021-03-08T22:03:02+00:00" + "time": "2021-03-19T06:08:17+00:00" }, { "name": "phpstan/phpstan-phpunit", From aa8c13ec45099012df2ec2b8b3e9be638af72198 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 23 Mar 2021 20:23:56 +0000 Subject: [PATCH 2327/3224] Remove dynamic LightArray constants sad, no constexpr functions :( --- src/world/format/LightArray.php | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/world/format/LightArray.php b/src/world/format/LightArray.php index 885e9ddc98..83b1a17dcd 100644 --- a/src/world/format/LightArray.php +++ b/src/world/format/LightArray.php @@ -24,23 +24,14 @@ declare(strict_types=1); namespace pocketmine\world\format; use function chr; -use function define; -use function defined; use function ord; use function str_repeat; use function strlen; -if(!defined(__NAMESPACE__ . '\ZERO_NIBBLE_ARRAY')){ - define(__NAMESPACE__ . '\ZERO_NIBBLE_ARRAY', str_repeat("\x00", 2048)); -} -if(!defined(__NAMESPACE__ . '\FIFTEEN_NIBBLE_ARRAY')){ - define(__NAMESPACE__ . '\FIFTEEN_NIBBLE_ARRAY', str_repeat("\xff", 2048)); -} - final class LightArray{ - private const ZERO = ZERO_NIBBLE_ARRAY; - private const FIFTEEN = FIFTEEN_NIBBLE_ARRAY; + private const ZERO = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; + private const FIFTEEN = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; /** @var string */ private $data; From 0d775f8731c4183adef4fd5bc1dbc4d06b29d844 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 23 Mar 2021 22:21:57 +0000 Subject: [PATCH 2328/3224] Require ext-chunkutils2 at ^0.2.0 --- composer.json | 2 +- composer.lock | 4 +- src/PocketMine.php | 16 ++++++ src/world/format/LightArray.php | 91 --------------------------------- tests/gh-actions/build.sh | 2 +- 5 files changed, 20 insertions(+), 95 deletions(-) delete mode 100644 src/world/format/LightArray.php diff --git a/composer.json b/composer.json index 893b7c364c..f10787b86b 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ "require": { "php": "^7.4 || ^8.0", "php-64bit": "*", - "ext-chunkutils2": "^0.1.0", + "ext-chunkutils2": "^0.2.0", "ext-crypto": "^0.3.1", "ext-ctype": "*", "ext-curl": "*", diff --git a/composer.lock b/composer.lock index 1479b1827d..cc16566795 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "824d613db4986bce5882e3460ef32826", + "content-hash": "7846da3098ad1a3e694ed3dfa5eedda3", "packages": [ { "name": "adhocore/json-comment", @@ -3460,7 +3460,7 @@ "platform": { "php": "^7.4 || ^8.0", "php-64bit": "*", - "ext-chunkutils2": "^0.1.0", + "ext-chunkutils2": "^0.2.0", "ext-crypto": "^0.3.1", "ext-ctype": "*", "ext-curl": "*", diff --git a/src/PocketMine.php b/src/PocketMine.php index 09908d97db..b154a8f123 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -33,6 +33,12 @@ namespace pocketmine { use pocketmine\utils\Terminal; use pocketmine\utils\Timezone; use pocketmine\wizard\SetupWizard; + use function extension_loaded; + use function phpversion; + use function preg_match; + use function preg_quote; + use function strpos; + use function version_compare; require_once __DIR__ . '/VersionInfo.php'; @@ -121,6 +127,16 @@ namespace pocketmine { } } + $chunkutils2_version = phpversion("chunkutils2"); + $wantedVersionLock = "0.2"; + $wantedVersionMin = "$wantedVersionLock.0"; + if($chunkutils2_version !== false && ( + version_compare($chunkutils2_version, $wantedVersionMin) < 0 || + preg_match("/^" . preg_quote($wantedVersionLock, "/") . "\.\d+$/", $chunkutils2_version) === 0 //lock in at ^0.2, optionally at a patch release + )){ + $messages[] = "chunkutils2 ^$wantedVersionMin is required, while you have $chunkutils2_version."; + } + if(extension_loaded("pocketmine")){ $messages[] = "The native PocketMine extension is no longer supported."; } diff --git a/src/world/format/LightArray.php b/src/world/format/LightArray.php deleted file mode 100644 index 83b1a17dcd..0000000000 --- a/src/world/format/LightArray.php +++ /dev/null @@ -1,91 +0,0 @@ -data = $payload; - $this->collectGarbage(); - } - - public static function fill(int $level) : self{ - if($level === 0){ - return new self(self::ZERO); - } - if($level === 15){ - return new self(self::FIFTEEN); - } - return new self(str_repeat(chr(($level & 0x0f) | ($level << 4)), 2048)); - } - - public function get(int $x, int $y, int $z) : int{ - return (ord($this->data[($x << 7) | ($z << 3) | ($y >> 1)]) >> (($y & 1) << 2)) & 0xf; - } - - public function set(int $x, int $y, int $z, int $level) : void{ - $i = ($x << 7) | ($z << 3) | ($y >> 1); - - $shift = ($y & 1) << 2; - $byte = ord($this->data[$i]); - $this->data[$i] = chr(($byte & ~(0xf << $shift)) | (($level & 0xf) << $shift)); - } - - public function collectGarbage() : void{ - /* - * This strange looking code is designed to exploit PHP's copy-on-write behaviour. Assigning will copy a - * reference to the const instead of duplicating the whole string. The string will only be duplicated when - * modified, which is perfect for this purpose. - */ - if($this->data === self::ZERO){ - $this->data = self::ZERO; - }elseif($this->data === self::FIFTEEN){ - $this->data = self::FIFTEEN; - } - } - - public function getData() : string{ - return $this->data; - } - - public function __wakeup(){ - //const refs aren't preserved when unserializing - $this->collectGarbage(); - } -} diff --git a/tests/gh-actions/build.sh b/tests/gh-actions/build.sh index 9355111e87..da7d20aa86 100755 --- a/tests/gh-actions/build.sh +++ b/tests/gh-actions/build.sh @@ -53,7 +53,7 @@ PHP_BUILD_INSTALL_EXTENSION="\ pthreads=@acc6e52b2144c61c434b62a3cb680d537e06828e \ yaml=2.2.1 \ leveldb=@60763a09bf5c7a10376d16e25b078b99a35c5c37 \ -chunkutils2=@7aec31a9dfc83ddead8870dc0a29159596939680 \ +chunkutils2=@0.2.0 \ morton=@0.1.2 \ igbinary=3.2.1 \ " PHP_BUILD_ZTS_ENABLE=on PHP_BUILD_CONFIGURE_OPTS='--with-gmp' ./bin/php-build "$VERSION" "$INSTALL_DIR" || exit 1 From 61bca7cfbcd3a547a1ffcf5fc2e4841d9bf32624 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 25 Mar 2021 01:31:25 +0000 Subject: [PATCH 2329/3224] master supports 7.4 only --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 80449786df..aebc8c5c0a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -189,7 +189,7 @@ jobs: fail-fast: false matrix: image: [ubuntu-20.04] - php: [7.3.27, 7.4.16] + php: [7.4.16] steps: - uses: actions/checkout@v2 From 9c10599c308fbe33a6f213ec23c744822a79648e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 25 Mar 2021 01:33:05 +0000 Subject: [PATCH 2330/3224] Updated PreProcessor to pmmp/PreProcessor@6e223fa9a05b4816c496479fb30a949844513a41 --- build/preprocessor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/preprocessor b/build/preprocessor index 3b5a1d3fdf..6e223fa9a0 160000 --- a/build/preprocessor +++ b/build/preprocessor @@ -1 +1 @@ -Subproject commit 3b5a1d3fdf9c006f1daa286db394d8629848234f +Subproject commit 6e223fa9a05b4816c496479fb30a949844513a41 From d9b548bfdebde535c06fcf89a289c29c87db3295 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 25 Mar 2021 01:37:26 +0000 Subject: [PATCH 2331/3224] Fixed unintentional formatting change introduced by ae75d73f4894fb792649e7a6af1a63376d162578 --- src/network/mcpe/protocol/ClientboundMapItemDataPacket.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php index 7c0f5a37a7..d92077cf1b 100644 --- a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php +++ b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php @@ -30,9 +30,9 @@ use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\protocol\types\MapDecoration; use pocketmine\network\mcpe\protocol\types\MapTrackedObject; -use pocketmine\utils\Binary; -#ifndef COMPILE use function count; +#ifndef COMPILE +use pocketmine\utils\Binary; #endif class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPacket{ From 52ce8ad8ae51383db1f049020e9f28c05f6bc288 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 25 Mar 2021 19:17:16 +0000 Subject: [PATCH 2332/3224] Plugin: removed useless shit Plugin is the interface by which the server core interacts with plugins, so it should be limited only to the stuff that the server actually uses. These methods are still provided by PluginBase, so in 99.9% of cases there will be no BC break. --- changelogs/4.0-snapshot.md | 2 ++ src/plugin/Plugin.php | 4 ---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 4a4fd57684..847a91705f 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -665,6 +665,8 @@ This version features substantial changes to the network system, improving coher - `Plugin->onEnable()`: this is now internalized inside `PluginBase` - `Plugin->onDisable()`: same as above - `Plugin->onLoad()`: same as above + - `Plugin->getServer()` is no longer required to be implemented. It's implemented in `PluginBase` for convenience. + - `Plugin->isDisabled()` was removed (use `Plugin->isEnabled()` instead). - `Plugin` no longer extends `CommandExecutor`. This means that `Plugin` implementations don't need to implement `onCommand()` anymore. - The following hook methods have changed visibility: - `PluginBase->onEnable()` changed from `public` to `protected` diff --git a/src/plugin/Plugin.php b/src/plugin/Plugin.php index 12ed87dde9..da313d07c6 100644 --- a/src/plugin/Plugin.php +++ b/src/plugin/Plugin.php @@ -47,8 +47,6 @@ interface Plugin{ */ public function onEnableStateChange(bool $enabled) : void; - public function isDisabled() : bool; - /** * Gets the plugin's data folder to save files and configuration. * This directory name has a trailing slash. @@ -57,8 +55,6 @@ interface Plugin{ public function getDescription() : PluginDescription; - public function getServer() : Server; - public function getName() : string; public function getLogger() : \AttachableLogger; From 5e9ce92b555b390cc75dee370d5fb91e1cc7023f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 25 Mar 2021 23:17:33 +0000 Subject: [PATCH 2333/3224] Explosion: don't depend on air having stateID 0 --- src/block/Air.php | 2 +- src/world/Explosion.php | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/block/Air.php b/src/block/Air.php index f5408c00bf..ae201328f0 100644 --- a/src/block/Air.php +++ b/src/block/Air.php @@ -31,7 +31,7 @@ use pocketmine\math\AxisAlignedBB; class Air extends Transparent{ public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::indestructible(0.0)); + parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::indestructible(-1.0)); } public function canBeFlowedInto() : bool{ diff --git a/src/world/Explosion.php b/src/world/Explosion.php index d750ee0ac2..db27b472e0 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -130,8 +130,9 @@ class Explosion{ $state = $this->subChunkExplorer->currentSubChunk->getFullBlock($vBlockX & 0x0f, $vBlockY & 0x0f, $vBlockZ & 0x0f); - if($state !== 0){ - $blastForce -= ($blockFactory->blastResistance[$state] / 5 + 0.3) * $this->stepLen; + $blastResistance = $blockFactory->blastResistance[$state]; + if($blastResistance >= 0){ + $blastForce -= ($blastResistance / 5 + 0.3) * $this->stepLen; if($blastForce > 0){ if(!isset($this->affectedBlocks[World::blockHash($vBlockX, $vBlockY, $vBlockZ)])){ $_block = $blockFactory->fromFullBlock($state); From 64886707b234c9ca725ff15fbfb7299b7e3c1345 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 25 Mar 2021 23:36:10 +0000 Subject: [PATCH 2334/3224] SubChunkExplorer: avoid repeated shift-right instructions --- src/world/utils/SubChunkExplorer.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/world/utils/SubChunkExplorer.php b/src/world/utils/SubChunkExplorer.php index 80fb4b3846..a020a658ec 100644 --- a/src/world/utils/SubChunkExplorer.php +++ b/src/world/utils/SubChunkExplorer.php @@ -51,9 +51,11 @@ class SubChunkExplorer{ * @phpstan-return SubChunkExplorerStatus::* */ public function moveTo(int $x, int $y, int $z) : int{ - if($this->currentChunk === null or $this->currentX !== ($x >> 4) or $this->currentZ !== ($z >> 4)){ - $this->currentX = $x >> 4; - $this->currentZ = $z >> 4; + $newChunkX = $x >> 4; + $newChunkZ = $z >> 4; + if($this->currentChunk === null or $this->currentX !== $newChunkX or $this->currentZ !== $newChunkZ){ + $this->currentX = $newChunkX; + $this->currentZ = $newChunkZ; $this->currentSubChunk = null; $this->currentChunk = $this->world->getChunk($this->currentX, $this->currentZ); @@ -62,15 +64,16 @@ class SubChunkExplorer{ } } - if($this->currentSubChunk === null or $this->currentY !== ($y >> 4)){ - $this->currentY = $y >> 4; + $newChunkY = $y >> 4; + if($this->currentSubChunk === null or $this->currentY !== $newChunkY){ + $this->currentY = $newChunkY; if($this->currentY < 0 or $this->currentY >= $this->currentChunk->getHeight()){ $this->currentSubChunk = null; return SubChunkExplorerStatus::INVALID; } - $this->currentSubChunk = $this->currentChunk->getSubChunk($y >> 4); + $this->currentSubChunk = $this->currentChunk->getSubChunk($newChunkY); return SubChunkExplorerStatus::MOVED; } From f047ecfd2d7a50c3a0300ad6a4482b1015fefa18 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Fri, 26 Mar 2021 21:36:27 +0000 Subject: [PATCH 2335/3224] Fixed player spawning in ungenerated terrain (#4087) fixes #4044 fixes #2724 this is significantly more complex than I hoped for, but it's a start... and it works. --- src/Server.php | 46 +++++++-- src/network/mcpe/NetworkSession.php | 17 +++- src/player/Player.php | 73 +++++++------- src/player/PlayerCreationPromise.php | 75 ++++++++++++++ src/world/ChunkPopulationPromise.php | 76 +++++++++++++++ src/world/World.php | 141 ++++++++++++++++++++++----- src/world/WorldManager.php | 2 +- 7 files changed, 355 insertions(+), 75 deletions(-) create mode 100644 src/player/PlayerCreationPromise.php create mode 100644 src/world/ChunkPopulationPromise.php diff --git a/src/Server.php b/src/Server.php index 992d19f6f0..6a31935eaf 100644 --- a/src/Server.php +++ b/src/Server.php @@ -34,6 +34,8 @@ use pocketmine\command\ConsoleCommandSender; use pocketmine\command\SimpleCommandMap; use pocketmine\crafting\CraftingManager; use pocketmine\crafting\CraftingManagerFromDataHelper; +use pocketmine\entity\EntityDataHelper; +use pocketmine\entity\Location; use pocketmine\event\HandlerListManager; use pocketmine\event\player\PlayerCreationEvent; use pocketmine\event\player\PlayerDataSaveEvent; @@ -68,6 +70,7 @@ use pocketmine\permission\DefaultPermissions; use pocketmine\player\GameMode; use pocketmine\player\OfflinePlayer; use pocketmine\player\Player; +use pocketmine\player\PlayerCreationPromise; use pocketmine\player\PlayerInfo; use pocketmine\plugin\PharPluginLoader; use pocketmine\plugin\Plugin; @@ -84,6 +87,7 @@ use pocketmine\stats\SendUsageTask; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; use pocketmine\updater\AutoUpdater; +use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Config; use pocketmine\utils\Filesystem; use pocketmine\utils\Internet; @@ -576,17 +580,45 @@ class Server{ } } - public function createPlayer(NetworkSession $session, PlayerInfo $playerInfo, bool $authenticated, ?CompoundTag $offlinePlayerData) : Player{ + public function createPlayer(NetworkSession $session, PlayerInfo $playerInfo, bool $authenticated, ?CompoundTag $offlinePlayerData) : PlayerCreationPromise{ $ev = new PlayerCreationEvent($session); $ev->call(); $class = $ev->getPlayerClass(); - /** - * @see Player::__construct() - * @var Player $player - */ - $player = new $class($this, $session, $playerInfo, $authenticated, $offlinePlayerData); - return $player; + if($offlinePlayerData !== null and ($world = $this->worldManager->getWorldByName($offlinePlayerData->getString("Level", ""))) !== null){ + $spawn = EntityDataHelper::parseLocation($offlinePlayerData, $world); + $onGround = $offlinePlayerData->getByte("OnGround", 1) === 1; + }else{ + $world = $this->worldManager->getDefaultWorld(); + if($world === null){ + throw new AssumptionFailedError("Default world should always be loaded"); + } + $spawn = Location::fromObject($world->getSafeSpawn(), $world); + $onGround = true; + } + $playerPromise = new PlayerCreationPromise(); + $world->requestChunkPopulation($spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4, null)->onCompletion( + function() use ($playerPromise, $class, $session, $playerInfo, $authenticated, $spawn, $offlinePlayerData, $onGround) : void{ + if(!$session->isConnected()){ + $playerPromise->reject(); + return; + } + /** + * @see Player::__construct() + * @var Player $player + */ + $player = new $class($this, $session, $playerInfo, $authenticated, $spawn, $offlinePlayerData); + $player->onGround = $onGround; //TODO: this hack is needed for new players in-air ticks - they don't get detected as on-ground until they move + $playerPromise->resolve($player); + }, + static function() use ($playerPromise, $session) : void{ + if($session->isConnected()){ + $session->disconnect("Spawn terrain generation failed"); + } + $playerPromise->reject(); + } + ); + return $playerPromise; } /** diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index ba70ed25bb..7d329d0674 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -234,8 +234,18 @@ class NetworkSession{ } protected function createPlayer() : void{ - $this->player = $this->server->createPlayer($this, $this->info, $this->authenticated, $this->cachedOfflinePlayerData); + $this->server->createPlayer($this, $this->info, $this->authenticated, $this->cachedOfflinePlayerData)->onCompletion( + \Closure::fromCallable([$this, 'onPlayerCreated']), + fn() => $this->disconnect("Player creation failed") //TODO: this should never actually occur... right? + ); + } + private function onPlayerCreated(Player $player) : void{ + if(!$this->isConnected()){ + //the remote player might have disconnected before spawn terrain generation was finished + return; + } + $this->player = $player; $this->invManager = new InventoryManager($this->player, $this); $effectManager = $this->player->getEffects(); @@ -259,6 +269,7 @@ class NetworkSession{ $this->disposeHooks->add(static function() use ($permissionHooks, $permHook) : void{ $permissionHooks->remove($permHook); }); + $this->beginSpawnSequence(); } public function getPlayer() : ?Player{ @@ -680,13 +691,11 @@ class NetworkSession{ $this->logger->debug("Initiating resource packs phase"); $this->setHandler(new ResourcePacksPacketHandler($this, $this->server->getResourcePackManager(), function() : void{ - $this->beginSpawnSequence(); + $this->createPlayer(); })); } private function beginSpawnSequence() : void{ - $this->createPlayer(); - $this->setHandler(new PreSpawnPacketHandler($this->server, $this->player, $this)); $this->player->setImmobile(); //TODO: HACK: fix client-side falling pre-spawn diff --git a/src/player/Player.php b/src/player/Player.php index 62a6b589e7..d371423fa3 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -34,7 +34,6 @@ use pocketmine\entity\animation\ArmSwingAnimation; use pocketmine\entity\animation\CriticalHitAnimation; use pocketmine\entity\effect\VanillaEffects; use pocketmine\entity\Entity; -use pocketmine\entity\EntityDataHelper; use pocketmine\entity\Human; use pocketmine\entity\Living; use pocketmine\entity\Location; @@ -261,7 +260,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ /** @var SurvivalBlockBreakHandler|null */ protected $blockBreakHandler = null; - public function __construct(Server $server, NetworkSession $session, PlayerInfo $playerInfo, bool $authenticated, ?CompoundTag $namedtag){ + public function __construct(Server $server, NetworkSession $session, PlayerInfo $playerInfo, bool $authenticated, Location $spawnLocation, ?CompoundTag $namedtag){ $username = TextFormat::clean($playerInfo->getUsername()); $this->logger = new \PrefixedLogger($server->getLogger(), "Player: $username"); @@ -286,24 +285,15 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->spawnThreshold = (int) (($this->server->getConfigGroup()->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); $this->chunkSelector = new ChunkSelector(); - if($namedtag !== null and ($world = $this->server->getWorldManager()->getWorldByName($namedtag->getString("Level", ""))) !== null){ - $spawn = EntityDataHelper::parseLocation($namedtag, $world); - $onGround = $namedtag->getByte("OnGround", 1) === 1; - }else{ - $world = $this->server->getWorldManager()->getDefaultWorld(); - $spawn = Location::fromObject($world->getSafeSpawn(), $world); - $onGround = true; - } - - $this->chunkLoader = new PlayerChunkLoader($spawn); + $this->chunkLoader = new PlayerChunkLoader($spawnLocation); + $world = $spawnLocation->getWorld(); //load the spawn chunk so we can see the terrain - $world->registerChunkLoader($this->chunkLoader, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4, true); - $world->registerChunkListener($this, $spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4); - $this->usedChunks[World::chunkHash($spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4)] = UsedChunkStatus::NEEDED(); + $world->registerChunkLoader($this->chunkLoader, $spawnLocation->getFloorX() >> 4, $spawnLocation->getFloorZ() >> 4, true); + $world->registerChunkListener($this, $spawnLocation->getFloorX() >> 4, $spawnLocation->getFloorZ() >> 4); + $this->usedChunks[World::chunkHash($spawnLocation->getFloorX() >> 4, $spawnLocation->getFloorZ() >> 4)] = UsedChunkStatus::NEEDED(); - parent::__construct($spawn, $this->playerInfo->getSkin(), $namedtag); - $this->onGround = $onGround; //TODO: this hack is needed for new players in-air ticks - they don't get detected as on-ground until they move + parent::__construct($spawnLocation, $this->playerInfo->getSkin(), $namedtag); $ev = new PlayerLoginEvent($this, "Plugin reason"); $ev->call(); @@ -712,6 +702,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ Timings::$playerChunkSend->startTiming(); $count = 0; + $world = $this->getWorld(); foreach($this->loadQueue as $index => $distance){ if($count >= $this->chunksPerTick){ break; @@ -728,30 +719,36 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->getWorld()->registerChunkLoader($this->chunkLoader, $X, $Z, true); $this->getWorld()->registerChunkListener($this, $X, $Z); - if(!$this->getWorld()->requestChunkPopulation($X, $Z)){ - continue; - } - - unset($this->loadQueue[$index]); - $this->usedChunks[$index] = UsedChunkStatus::REQUESTED(); - - $this->getNetworkSession()->startUsingChunk($X, $Z, function(int $chunkX, int $chunkZ) use ($index) : void{ - $this->usedChunks[$index] = UsedChunkStatus::SENT(); - if($this->spawnChunkLoadCount === -1){ - $this->spawnEntitiesOnChunk($chunkX, $chunkZ); - }elseif($this->spawnChunkLoadCount++ === $this->spawnThreshold){ - $this->spawnChunkLoadCount = -1; - - foreach($this->usedChunks as $chunkHash => $status){ - if($status->equals(UsedChunkStatus::SENT())){ - World::getXZ($chunkHash, $_x, $_z); - $this->spawnEntitiesOnChunk($_x, $_z); - } + $this->getWorld()->requestChunkPopulation($X, $Z, $this->chunkLoader)->onCompletion( + function() use ($X, $Z, $index, $world) : void{ + if(!$this->isConnected() || !isset($this->usedChunks[$index]) || $world !== $this->getWorld()){ + return; } + unset($this->loadQueue[$index]); + $this->usedChunks[$index] = UsedChunkStatus::REQUESTED(); - $this->getNetworkSession()->notifyTerrainReady(); + $this->getNetworkSession()->startUsingChunk($X, $Z, function(int $chunkX, int $chunkZ) use ($index) : void{ + $this->usedChunks[$index] = UsedChunkStatus::SENT(); + if($this->spawnChunkLoadCount === -1){ + $this->spawnEntitiesOnChunk($chunkX, $chunkZ); + }elseif($this->spawnChunkLoadCount++ === $this->spawnThreshold){ + $this->spawnChunkLoadCount = -1; + + foreach($this->usedChunks as $chunkHash => $status){ + if($status->equals(UsedChunkStatus::SENT())){ + World::getXZ($chunkHash, $_x, $_z); + $this->spawnEntitiesOnChunk($_x, $_z); + } + } + + $this->getNetworkSession()->notifyTerrainReady(); + } + }); + }, + static function() : void{ + //NOOP: we'll re-request this if it fails anyway } - }); + ); } Timings::$playerChunkSend->stopTiming(); diff --git a/src/player/PlayerCreationPromise.php b/src/player/PlayerCreationPromise.php new file mode 100644 index 0000000000..1d43b7677a --- /dev/null +++ b/src/player/PlayerCreationPromise.php @@ -0,0 +1,75 @@ + + */ + private array $onSuccess = []; + + /** + * @var \Closure[] + * @phpstan-var array + */ + private array $onFailure = []; + + private bool $resolved = false; + private ?Player $result = null; + + /** + * @phpstan-param \Closure(Player) : void $onSuccess + * @phpstan-param \Closure() : void $onFailure + */ + public function onCompletion(\Closure $onSuccess, \Closure $onFailure) : void{ + if($this->resolved){ + $this->result === null ? $onFailure() : $onSuccess($this->result); + }else{ + $this->onSuccess[spl_object_id($onSuccess)] = $onSuccess; + $this->onFailure[spl_object_id($onFailure)] = $onFailure; + } + } + + public function resolve(Player $player) : void{ + $this->resolved = true; + $this->result = $player; + foreach($this->onSuccess as $c){ + $c($player); + } + $this->onSuccess = []; + $this->onFailure = []; + } + + public function reject() : void{ + $this->resolved = true; + foreach($this->onFailure as $c){ + $c(); + } + $this->onSuccess = []; + $this->onFailure = []; + } +} diff --git a/src/world/ChunkPopulationPromise.php b/src/world/ChunkPopulationPromise.php new file mode 100644 index 0000000000..4feee5f75e --- /dev/null +++ b/src/world/ChunkPopulationPromise.php @@ -0,0 +1,76 @@ + + */ + private array $onSuccess = []; + /** + * @var \Closure[] + * @phpstan-var array + */ + private array $onFailure = []; + + private ?bool $success = null; + + /** + * @phpstan-param \Closure() : void $onSuccess + * @phpstan-param \Closure() : void $onFailure + */ + public function onCompletion(\Closure $onSuccess, \Closure $onFailure) : void{ + if($this->success !== null){ + $this->success ? $onSuccess() : $onFailure(); + }else{ + $this->onSuccess[spl_object_id($onSuccess)] = $onSuccess; + $this->onFailure[spl_object_id($onFailure)] = $onFailure; + } + } + + public function resolve() : void{ + $this->success = true; + foreach($this->onSuccess as $callback){ + $callback(); + } + $this->onSuccess = []; + $this->onFailure = []; + } + + public function reject() : void{ + $this->success = false; + foreach($this->onFailure as $callback){ + $callback(); + } + $this->onSuccess = []; + $this->onFailure = []; + } + + public function isCompleted() : bool{ + return $this->success !== null; + } +} diff --git a/src/world/World.php b/src/world/World.php index 23bf18f8c4..f591436fc5 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -238,6 +238,16 @@ class World implements ChunkManager{ private $chunkLock = []; /** @var int */ private $maxConcurrentChunkPopulationTasks = 2; + /** + * @var ChunkPopulationPromise[] chunkHash => promise + * @phpstan-var array + */ + private array $chunkPopulationRequestMap = []; + /** + * @var \SplQueue (queue of chunkHashes) + * @phpstan-var \SplQueue + */ + private \SplQueue $chunkPopulationRequestQueue; /** @var bool[] */ private $generatorRegisteredWorkers = []; @@ -390,6 +400,20 @@ class World implements ChunkManager{ $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.level.preparing", [$this->displayName])); $this->generator = GeneratorManager::getInstance()->getGenerator($this->provider->getWorldData()->getGenerator(), true); //TODO: validate generator options + $this->chunkPopulationRequestQueue = new \SplQueue(); + $this->addOnUnloadCallback(function() : void{ + $this->logger->debug("Cancelling unfulfilled generation requests"); + + foreach($this->chunkPopulationRequestMap as $chunkHash => $promise){ + $promise->reject(); + unset($this->chunkPopulationRequestMap[$chunkHash]); + } + if(count($this->chunkPopulationRequestMap) !== 0){ + //TODO: this might actually get hit because generation rejection callbacks might try to schedule new + //requests, and we can't prevent that right now because there's no way to detect "unloading" state + throw new AssumptionFailedError("New generation requests scheduled during unload"); + } + }); $this->folderName = $name; @@ -626,6 +650,10 @@ class World implements ChunkManager{ if(count($this->chunkLoaders[$chunkHash]) === 0){ unset($this->chunkLoaders[$chunkHash]); $this->unloadChunkRequest($chunkX, $chunkZ, true); + if(isset($this->chunkPopulationRequestMap[$chunkHash]) && !isset($this->activeChunkPopulationTasks[$chunkHash])){ + $this->chunkPopulationRequestMap[$chunkHash]->reject(); + unset($this->chunkPopulationRequestMap[$chunkHash]); + } } if(--$this->loaderCounter[$loaderId] === 0){ @@ -2005,9 +2033,33 @@ class World implements ChunkManager{ return isset($this->chunkLock[World::chunkHash($chunkX, $chunkZ)]); } + private function drainPopulationRequestQueue() : void{ + $failed = []; + while(count($this->activeChunkPopulationTasks) < $this->maxConcurrentChunkPopulationTasks && !$this->chunkPopulationRequestQueue->isEmpty()){ + $nextChunkHash = $this->chunkPopulationRequestQueue->dequeue(); + World::getXZ($nextChunkHash, $nextChunkX, $nextChunkZ); + if(isset($this->chunkPopulationRequestMap[$nextChunkHash])){ + assert(!isset($this->activeChunkPopulationTasks[$nextChunkHash]), "Population for chunk $nextChunkX $nextChunkZ already running"); + $this->logger->debug("Fulfilling population request for chunk $nextChunkX $nextChunkZ"); + $this->orderChunkPopulation($nextChunkX, $nextChunkZ, null); + if(!isset($this->activeChunkPopulationTasks[$nextChunkHash])){ + $failed[] = $nextChunkHash; + } + }else{ + $this->logger->debug("Population request for chunk $nextChunkX $nextChunkZ was discarded before it could be fulfilled"); + } + } + + //these requests failed even though they weren't rate limited; we can't directly re-add them to the back of the + //queue because it would result in an infinite loop + foreach($failed as $hash){ + $this->chunkPopulationRequestQueue->enqueue($hash); + } + } + public function generateChunkCallback(int $x, int $z, ?Chunk $chunk) : void{ Timings::$generationCallback->startTiming(); - if(isset($this->activeChunkPopulationTasks[$index = World::chunkHash($x, $z)])){ + if(isset($this->chunkPopulationRequestMap[$index = World::chunkHash($x, $z)]) && isset($this->activeChunkPopulationTasks[$index])){ if($chunk === null){ throw new AssumptionFailedError("Primary chunk should never be NULL"); } @@ -2016,7 +2068,6 @@ class World implements ChunkManager{ $this->unlockChunk($x + $xx, $z + $zz); } } - unset($this->activeChunkPopulationTasks[$index]); $oldChunk = $this->loadChunk($x, $z); $this->setChunk($x, $z, $chunk, false); @@ -2027,11 +2078,17 @@ class World implements ChunkManager{ $listener->onChunkPopulated($x, $z, $chunk); } } + unset($this->activeChunkPopulationTasks[$index]); + $this->chunkPopulationRequestMap[$index]->resolve(); + unset($this->chunkPopulationRequestMap[$index]); + + $this->drainPopulationRequestQueue(); }elseif($this->isChunkLocked($x, $z)){ $this->unlockChunk($x, $z); if($chunk !== null){ $this->setChunk($x, $z, $chunk, false); } + $this->drainPopulationRequestQueue(); }elseif($chunk !== null){ $this->setChunk($x, $z, $chunk, false); } @@ -2464,6 +2521,11 @@ class World implements ChunkManager{ unset($this->blockCache[$chunkHash]); unset($this->changedBlocks[$chunkHash]); + if(array_key_exists($chunkHash, $this->chunkPopulationRequestMap)){ + $this->chunkPopulationRequestMap[$chunkHash]->reject(); + unset($this->chunkPopulationRequestMap[$chunkHash]); + } + $this->timings->doChunkUnload->stopTiming(); return true; @@ -2605,43 +2667,64 @@ class World implements ChunkManager{ } } + private function enqueuePopulationRequest(int $chunkX, int $chunkZ, ?ChunkLoader $associatedChunkLoader) : ChunkPopulationPromise{ + $chunkHash = World::chunkHash($chunkX, $chunkZ); + $this->chunkPopulationRequestQueue->enqueue($chunkHash); + $promise = $this->chunkPopulationRequestMap[$chunkHash] = new ChunkPopulationPromise(); + if($associatedChunkLoader === null){ + $temporaryLoader = new class implements ChunkLoader{}; + $this->registerChunkLoader($temporaryLoader, $chunkX, $chunkZ); + $promise->onCompletion( + static function() : void{}, + fn() => $this->unregisterChunkLoader($temporaryLoader, $chunkX, $chunkZ) + ); + } + return $promise; + } + /** * Attempts to initiate asynchronous generation/population of the target chunk, if it's currently reasonable to do * so (and if it isn't already generated/populated). + * If the generator is busy, the request will be put into a queue and delayed until a better time. * - * This method can fail for the following reasons: - * - The generation queue for this world is currently full (intended to prevent CPU overload with non-essential generation) - * - The target chunk is already being generated/populated - * - The target chunk is locked for use by another async operation (usually population) - * - * @return bool whether the chunk has been successfully populated already - * TODO: the return values don't make a lot of sense, but currently stuff depends on them :< + * A ChunkLoader can be associated with the generation request to ensure that the generation request is cancelled if + * no loaders are attached to the target chunk. If no loader is provided, one will be assigned (and automatically + * removed when the generation request completes). */ - public function requestChunkPopulation(int $chunkX, int $chunkZ) : bool{ - if(count($this->activeChunkPopulationTasks) >= $this->maxConcurrentChunkPopulationTasks){ - return false; + public function requestChunkPopulation(int $chunkX, int $chunkZ, ?ChunkLoader $associatedChunkLoader) : ChunkPopulationPromise{ + $chunkHash = World::chunkHash($chunkX, $chunkZ); + $promise = $this->chunkPopulationRequestMap[$chunkHash] ?? null; + if($promise !== null && isset($this->activeChunkPopulationTasks[$chunkHash])){ + //generation is already running + return $promise; } - return $this->orderChunkPopulation($chunkX, $chunkZ); + if(count($this->activeChunkPopulationTasks) >= $this->maxConcurrentChunkPopulationTasks){ + //too many chunks are already generating; delay resolution of the request until later + return $promise ?? $this->enqueuePopulationRequest($chunkX, $chunkZ, $associatedChunkLoader); + } + return $this->orderChunkPopulation($chunkX, $chunkZ, $associatedChunkLoader); } /** * Initiates asynchronous generation/population of the target chunk, if it's not already generated/populated. + * If generation has already been requested for the target chunk, the promise for the already active request will be + * returned directly. * - * This method can fail for the following reasons: - * - The target chunk is already being generated/populated - * - The target chunk is locked for use by another async operation (usually population) - * - * @return bool whether the chunk has been successfully populated already - * TODO: the return values don't make sense, but currently stuff depends on them :< + * If the chunk is currently locked (for example due to another chunk using it for async generation), the request + * will be queued and executed at the earliest opportunity. */ - public function orderChunkPopulation(int $x, int $z) : bool{ - if(isset($this->activeChunkPopulationTasks[$index = World::chunkHash($x, $z)])){ - return false; + public function orderChunkPopulation(int $x, int $z, ?ChunkLoader $associatedChunkLoader) : ChunkPopulationPromise{ + $index = World::chunkHash($x, $z); + $promise = $this->chunkPopulationRequestMap[$index] ?? null; + if($promise !== null && isset($this->activeChunkPopulationTasks[$index])){ + //generation is already running + return $promise; } for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ if($this->isChunkLocked($x + $xx, $z + $zz)){ - return false; + //chunk is already in use by another generation request; queue the request for later + return $promise ?? $this->enqueuePopulationRequest($x, $z, $associatedChunkLoader); } } } @@ -2651,6 +2734,11 @@ class World implements ChunkManager{ Timings::$population->startTiming(); $this->activeChunkPopulationTasks[$index] = true; + if($promise === null){ + $promise = new ChunkPopulationPromise(); + $this->chunkPopulationRequestMap[$index] = $promise; + } + for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ $this->lockChunk($x + $xx, $z + $zz); @@ -2665,10 +2753,13 @@ class World implements ChunkManager{ $this->workerPool->submitTaskToWorker($task, $workerId); Timings::$population->stopTiming(); - return false; + return $promise; } - return true; + //chunk is already populated; return a pre-resolved promise that will directly fire callbacks assigned + $result = new ChunkPopulationPromise(); + $result->resolve(); + return $result; } public function doChunkGarbageCollection() : void{ diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 1cfcfdc8e5..86fb3f6ba6 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -285,7 +285,7 @@ class WorldManager{ foreach((new ChunkSelector())->selectChunks(3, $centerX, $centerZ) as $index){ World::getXZ($index, $chunkX, $chunkZ); - $world->orderChunkPopulation($chunkX, $chunkZ); + $world->orderChunkPopulation($chunkX, $chunkZ, null); } } From a223d1cbf3e8a9143383b6497f4d2d5d7ab3202a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Mar 2021 22:00:42 +0000 Subject: [PATCH 2336/3224] NetworkSession: allow Player to handle its own business in chunk sending these checks should appear consistently in all of these async callbacks. --- src/network/mcpe/NetworkSession.php | 5 ----- src/player/Player.php | 6 +++++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 7d329d0674..c0ff2c91f8 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -916,11 +916,6 @@ class NetworkSession{ if(!$this->isConnected()){ return; } - $currentWorld = $this->player->getLocation()->getWorld(); - if($world !== $currentWorld or !$this->player->isUsingChunk($chunkX, $chunkZ)){ - $this->logger->debug("Tried to send no-longer-active chunk $chunkX $chunkZ in world " . $world->getFolderName()); - return; - } $currentWorld->timings->syncChunkSend->startTiming(); try{ $this->queueCompressed($promise); diff --git a/src/player/Player.php b/src/player/Player.php index d371423fa3..66087c66df 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -727,7 +727,11 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ unset($this->loadQueue[$index]); $this->usedChunks[$index] = UsedChunkStatus::REQUESTED(); - $this->getNetworkSession()->startUsingChunk($X, $Z, function(int $chunkX, int $chunkZ) use ($index) : void{ + $this->getNetworkSession()->startUsingChunk($X, $Z, function(int $chunkX, int $chunkZ) use ($index, $world) : void{ + if(!isset($this->usedChunks[$index]) || $world !== $this->getWorld()){ + $this->logger->debug("Tried to send no-longer-active chunk $chunkX $chunkZ in world " . $world->getFolderName()); + return; + } $this->usedChunks[$index] = UsedChunkStatus::SENT(); if($this->spawnChunkLoadCount === -1){ $this->spawnEntitiesOnChunk($chunkX, $chunkZ); From 49cf0090176cb8c3b0212f93dcc8fe436eaff923 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Mar 2021 22:43:21 +0000 Subject: [PATCH 2337/3224] Remove unused variable --- src/network/mcpe/NetworkSession.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index c0ff2c91f8..4dd2e1e303 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -912,7 +912,7 @@ class NetworkSession{ ChunkCache::getInstance($world, $this->compressor)->request($chunkX, $chunkZ)->onResolve( //this callback may be called synchronously or asynchronously, depending on whether the promise is resolved yet - function(CompressBatchPromise $promise) use ($world, $chunkX, $chunkZ, $onCompletion) : void{ + function(CompressBatchPromise $promise) use ($chunkX, $chunkZ, $onCompletion) : void{ if(!$this->isConnected()){ return; } From de49a361c065774c7f4832f0005d0bb754164052 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Mar 2021 22:45:36 +0000 Subject: [PATCH 2338/3224] NetworkSession: Remove parameters from startUsingChunk() callback these can easily be use()d into the closure (which also has slightly better performance, because no type checks - not that anyone will notice). --- src/network/mcpe/NetworkSession.php | 8 ++++---- src/player/Player.php | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 4dd2e1e303..0c1c34e2b2 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -903,23 +903,23 @@ class NetworkSession{ /** * Instructs the networksession to start using the chunk at the given coordinates. This may occur asynchronously. * @param \Closure $onCompletion To be called when chunk sending has completed. - * @phpstan-param \Closure(int $chunkX, int $chunkZ) : void $onCompletion + * @phpstan-param \Closure() : void $onCompletion */ public function startUsingChunk(int $chunkX, int $chunkZ, \Closure $onCompletion) : void{ - Utils::validateCallableSignature(function(int $chunkX, int $chunkZ) : void{}, $onCompletion); + Utils::validateCallableSignature(function() : void{}, $onCompletion); $world = $this->player->getLocation()->getWorld(); ChunkCache::getInstance($world, $this->compressor)->request($chunkX, $chunkZ)->onResolve( //this callback may be called synchronously or asynchronously, depending on whether the promise is resolved yet - function(CompressBatchPromise $promise) use ($chunkX, $chunkZ, $onCompletion) : void{ + function(CompressBatchPromise $promise) use ($onCompletion) : void{ if(!$this->isConnected()){ return; } $currentWorld->timings->syncChunkSend->startTiming(); try{ $this->queueCompressed($promise); - $onCompletion($chunkX, $chunkZ); + $onCompletion(); }finally{ $currentWorld->timings->syncChunkSend->stopTiming(); } diff --git a/src/player/Player.php b/src/player/Player.php index 66087c66df..30eb187b7c 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -727,14 +727,14 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ unset($this->loadQueue[$index]); $this->usedChunks[$index] = UsedChunkStatus::REQUESTED(); - $this->getNetworkSession()->startUsingChunk($X, $Z, function(int $chunkX, int $chunkZ) use ($index, $world) : void{ + $this->getNetworkSession()->startUsingChunk($X, $Z, function() use ($X, $Z, $index, $world) : void{ if(!isset($this->usedChunks[$index]) || $world !== $this->getWorld()){ - $this->logger->debug("Tried to send no-longer-active chunk $chunkX $chunkZ in world " . $world->getFolderName()); + $this->logger->debug("Tried to send no-longer-active chunk $X $Z in world " . $world->getFolderName()); return; } $this->usedChunks[$index] = UsedChunkStatus::SENT(); if($this->spawnChunkLoadCount === -1){ - $this->spawnEntitiesOnChunk($chunkX, $chunkZ); + $this->spawnEntitiesOnChunk($X, $Z); }elseif($this->spawnChunkLoadCount++ === $this->spawnThreshold){ $this->spawnChunkLoadCount = -1; From cdeedbad8bc200e120de7762df0833ac89993b5a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Mar 2021 22:51:56 +0000 Subject: [PATCH 2339/3224] Player: extract some entity spawning logic into a separate function --- src/player/Player.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 30eb187b7c..dcc821878f 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -682,6 +682,15 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ unset($this->loadQueue[$index]); } + protected function spawnEntitiesOnAllChunks() : void{ + foreach($this->usedChunks as $chunkHash => $status){ + if($status->equals(UsedChunkStatus::SENT())){ + World::getXZ($chunkHash, $chunkX, $chunkZ); + $this->spawnEntitiesOnChunk($chunkX, $chunkZ); + } + } + } + protected function spawnEntitiesOnChunk(int $chunkX, int $chunkZ) : void{ foreach($this->getWorld()->getChunk($chunkX, $chunkZ)->getEntities() as $entity){ if($entity !== $this and !$entity->isFlaggedForDespawn()){ @@ -738,12 +747,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ }elseif($this->spawnChunkLoadCount++ === $this->spawnThreshold){ $this->spawnChunkLoadCount = -1; - foreach($this->usedChunks as $chunkHash => $status){ - if($status->equals(UsedChunkStatus::SENT())){ - World::getXZ($chunkHash, $_x, $_z); - $this->spawnEntitiesOnChunk($_x, $_z); - } - } + $this->spawnEntitiesOnAllChunks(); $this->getNetworkSession()->notifyTerrainReady(); } From adbc58f326221081d39d4bc15c1299e3f182c7e7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Mar 2021 22:55:48 +0000 Subject: [PATCH 2340/3224] TickingChunkLoader: use native return types --- src/player/PlayerChunkLoader.php | 4 ++-- src/world/TickingChunkLoader.php | 10 ++-------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/player/PlayerChunkLoader.php b/src/player/PlayerChunkLoader.php index 597b95d82c..deec33780c 100644 --- a/src/player/PlayerChunkLoader.php +++ b/src/player/PlayerChunkLoader.php @@ -39,11 +39,11 @@ final class PlayerChunkLoader implements TickingChunkLoader{ $this->currentLocation = $currentLocation; } - public function getX(){ + public function getX() : float{ return $this->currentLocation->getFloorX(); } - public function getZ(){ + public function getZ() : float{ return $this->currentLocation->getFloorZ(); } } diff --git a/src/world/TickingChunkLoader.php b/src/world/TickingChunkLoader.php index d6bbf9481d..57281c90c2 100644 --- a/src/world/TickingChunkLoader.php +++ b/src/world/TickingChunkLoader.php @@ -30,13 +30,7 @@ namespace pocketmine\world; */ interface TickingChunkLoader extends ChunkLoader{ - /** - * @return float - */ - public function getX(); + public function getX() : float; - /** - * @return float - */ - public function getZ(); + public function getZ() : float; } From 06f20234f7aa86a89a5cc3aeab254902caadfc13 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Mar 2021 22:56:09 +0000 Subject: [PATCH 2341/3224] Scrub unused imports --- build/generate-registry-annotations.php | 1 + src/block/BlockFactory.php | 1 - src/utils/RegistryUtils.php | 1 + tests/phpunit/scheduler/AsyncPoolTest.php | 1 - 4 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/generate-registry-annotations.php b/build/generate-registry-annotations.php index 71397590c0..fe9b444b62 100644 --- a/build/generate-registry-annotations.php +++ b/build/generate-registry-annotations.php @@ -26,6 +26,7 @@ namespace pocketmine\build\update_registry_annotations; use pocketmine\utils\RegistryUtils; use function basename; use function class_exists; +use function count; use function dirname; use function file_get_contents; use function file_put_contents; diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index e2dcf19ee3..f78c2cd3f5 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -47,7 +47,6 @@ use pocketmine\block\tile\Note as TileNote; use pocketmine\block\tile\Skull as TileSkull; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\InvalidBlockStateException; -use pocketmine\block\utils\PillarRotationInMetadataTrait; use pocketmine\block\utils\TreeType; use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\item\Item; diff --git a/src/utils/RegistryUtils.php b/src/utils/RegistryUtils.php index e83cdfaae5..7b76a14f7a 100644 --- a/src/utils/RegistryUtils.php +++ b/src/utils/RegistryUtils.php @@ -25,6 +25,7 @@ namespace pocketmine\utils; use function get_class; use function implode; +use function ksort; use function mb_strtoupper; use function sprintf; use const SORT_STRING; diff --git a/tests/phpunit/scheduler/AsyncPoolTest.php b/tests/phpunit/scheduler/AsyncPoolTest.php index a152c3ec37..e2aedfb939 100644 --- a/tests/phpunit/scheduler/AsyncPoolTest.php +++ b/tests/phpunit/scheduler/AsyncPoolTest.php @@ -26,7 +26,6 @@ namespace pocketmine\scheduler; use PHPUnit\Framework\TestCase; use pocketmine\snooze\SleeperHandler; use pocketmine\utils\MainLogger; -use pocketmine\utils\Terminal; use function define; use function dirname; use function microtime; From 91376669524a6deaea14274dc83cecc5ca0e9eea Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Mar 2021 22:57:21 +0000 Subject: [PATCH 2342/3224] Fixed build --- src/network/mcpe/NetworkSession.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 0c1c34e2b2..ab8c18579c 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -916,12 +916,12 @@ class NetworkSession{ if(!$this->isConnected()){ return; } - $currentWorld->timings->syncChunkSend->startTiming(); + $world->timings->syncChunkSend->startTiming(); try{ $this->queueCompressed($promise); $onCompletion(); }finally{ - $currentWorld->timings->syncChunkSend->stopTiming(); + $world->timings->syncChunkSend->stopTiming(); } } ); From d5549b72de4a8914bae89ff8194807333abee4d1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Mar 2021 00:08:23 +0000 Subject: [PATCH 2343/3224] ... --- src/network/mcpe/NetworkSession.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index ab8c18579c..de550ddd2a 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -912,7 +912,7 @@ class NetworkSession{ ChunkCache::getInstance($world, $this->compressor)->request($chunkX, $chunkZ)->onResolve( //this callback may be called synchronously or asynchronously, depending on whether the promise is resolved yet - function(CompressBatchPromise $promise) use ($onCompletion) : void{ + function(CompressBatchPromise $promise) use ($world, $onCompletion) : void{ if(!$this->isConnected()){ return; } From 25998720cebedc98ddcfb7e2182cc610479cdfc8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 28 Mar 2021 21:11:07 +0100 Subject: [PATCH 2344/3224] Fixed server crash on invalid gamemode in SetPlayerGameTypePacket this really ought to be detected at the decode layer, but right now that's a bit difficult ... --- src/network/mcpe/convert/TypeConverter.php | 4 ++-- src/network/mcpe/handler/InGamePacketHandler.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index 54974cc94a..e856d4a51b 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -91,7 +91,7 @@ class TypeConverter{ } } - public function protocolGameModeToCore(int $gameMode) : GameMode{ + public function protocolGameModeToCore(int $gameMode) : ?GameMode{ switch($gameMode){ case ProtocolGameMode::SURVIVAL: return GameMode::SURVIVAL(); @@ -103,7 +103,7 @@ class TypeConverter{ case ProtocolGameMode::SURVIVAL_VIEWER: return GameMode::SPECTATOR(); default: - throw new \UnexpectedValueException("Unmapped protocol game mode $gameMode"); + return null; } } diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index c43bb5c589..b070a31850 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -667,8 +667,8 @@ class InGamePacketHandler extends PacketHandler{ } public function handleSetPlayerGameType(SetPlayerGameTypePacket $packet) : bool{ - $converter = TypeConverter::getInstance(); - if(!$converter->protocolGameModeToCore($packet->gamemode)->equals($this->player->getGamemode())){ + $gameMode = TypeConverter::getInstance()->protocolGameModeToCore($packet->gamemode); + if($gameMode === null || !$gameMode->equals($this->player->getGamemode())){ //Set this back to default. TODO: handle this properly $this->session->syncGameMode($this->player->getGamemode(), true); } From b7a6c9dc17ec40dc693b01a0e981acee0b76e6ec Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 30 Mar 2021 01:15:28 +0100 Subject: [PATCH 2345/3224] Renamed BadPacketException -> PacketHandlingException this better describes the intent, instead of just vaguely describing a packet as 'bad'. --- src/network/Network.php | 2 +- ...eption.php => PacketHandlingException.php} | 6 ++++- src/network/RawPacketHandler.php | 2 +- src/network/mcpe/NetworkSession.php | 20 ++++++++--------- .../mcpe/handler/InGamePacketHandler.php | 10 ++++----- .../mcpe/handler/LoginPacketHandler.php | 22 +++++++++---------- src/network/mcpe/raklib/RakLibInterface.php | 4 ++-- 7 files changed, 35 insertions(+), 31 deletions(-) rename src/network/{BadPacketException.php => PacketHandlingException.php} (80%) diff --git a/src/network/Network.php b/src/network/Network.php index 886d047d1e..22c1b2f399 100644 --- a/src/network/Network.php +++ b/src/network/Network.php @@ -197,7 +197,7 @@ class Network{ if(preg_match($handler->getPattern(), $packet) === 1){ try{ $handled = $handler->handle($interface, $address, $port, $packet); - }catch(BadPacketException $e){ + }catch(PacketHandlingException $e){ $handled = true; $this->logger->error("Bad raw packet from /$address:$port: " . $e->getMessage()); $this->blockAddress($address, 600); diff --git a/src/network/BadPacketException.php b/src/network/PacketHandlingException.php similarity index 80% rename from src/network/BadPacketException.php rename to src/network/PacketHandlingException.php index ae573c953d..9b305430df 100644 --- a/src/network/BadPacketException.php +++ b/src/network/PacketHandlingException.php @@ -23,7 +23,11 @@ declare(strict_types=1); namespace pocketmine\network; -class BadPacketException extends \RuntimeException{ +/** + * Thrown when an error occurs during packet handling - for example, a message contained invalid options, packet shorter + * than expected, unknown packet, etc. + */ +class PacketHandlingException extends \RuntimeException{ public static function wrap(\Throwable $previous, ?string $prefix = null) : self{ return new self(($prefix !== null ? $prefix . ": " : "") . $previous->getMessage(), 0, $previous); diff --git a/src/network/RawPacketHandler.php b/src/network/RawPacketHandler.php index 5ee01672c0..17f221827c 100644 --- a/src/network/RawPacketHandler.php +++ b/src/network/RawPacketHandler.php @@ -32,7 +32,7 @@ interface RawPacketHandler{ public function getPattern() : string; /** - * @throws BadPacketException + * @throws PacketHandlingException */ public function handle(AdvancedNetworkInterface $interface, string $address, int $port, string $packet) : bool; } diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index de550ddd2a..a8b7432e38 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -37,7 +37,6 @@ use pocketmine\form\Form; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\StringTag; -use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\cache\ChunkCache; use pocketmine\network\mcpe\compression\CompressBatchPromise; use pocketmine\network\mcpe\compression\Compressor; @@ -96,6 +95,7 @@ use pocketmine\network\mcpe\protocol\types\PlayerListEntry; use pocketmine\network\mcpe\protocol\types\PlayerPermissions; use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; use pocketmine\network\NetworkSessionManager; +use pocketmine\network\PacketHandlingException; use pocketmine\permission\DefaultPermissions; use pocketmine\player\GameMode; use pocketmine\player\Player; @@ -324,7 +324,7 @@ class NetworkSession{ } /** - * @throws BadPacketException + * @throws PacketHandlingException */ public function handleEncoded(string $payload) : void{ if(!$this->connected){ @@ -337,7 +337,7 @@ class NetworkSession{ $payload = $this->cipher->decrypt($payload); }catch(DecryptionException $e){ $this->logger->debug("Encrypted packet: " . base64_encode($payload)); - throw BadPacketException::wrap($e, "Packet decryption error"); + throw PacketHandlingException::wrap($e, "Packet decryption error"); }finally{ Timings::$playerNetworkReceiveDecrypt->stopTiming(); } @@ -348,7 +348,7 @@ class NetworkSession{ $stream = new PacketBatch($this->compressor->decompress($payload)); }catch(DecompressionException $e){ $this->logger->debug("Failed to decompress packet: " . base64_encode($payload)); - throw BadPacketException::wrap($e, "Compressed packet batch decode error"); + throw PacketHandlingException::wrap($e, "Compressed packet batch decode error"); }finally{ Timings::$playerNetworkReceiveDecompress->stopTiming(); } @@ -357,19 +357,19 @@ class NetworkSession{ foreach($stream->getPackets($this->packetPool, 500) as $packet){ try{ $this->handleDataPacket($packet); - }catch(BadPacketException $e){ + }catch(PacketHandlingException $e){ $this->logger->debug($packet->getName() . ": " . base64_encode($packet->getSerializer()->getBuffer())); - throw BadPacketException::wrap($e, "Error processing " . $packet->getName()); + throw PacketHandlingException::wrap($e, "Error processing " . $packet->getName()); } } }catch(PacketDecodeException $e){ $this->logger->logException($e); - throw BadPacketException::wrap($e, "Packet batch decode error"); + throw PacketHandlingException::wrap($e, "Packet batch decode error"); } } /** - * @throws BadPacketException + * @throws PacketHandlingException */ public function handleDataPacket(Packet $packet) : void{ if(!($packet instanceof ServerboundPacket)){ @@ -377,7 +377,7 @@ class NetworkSession{ $this->logger->debug("Garbage serverbound " . $packet->getName() . ": " . base64_encode($packet->getSerializer()->getBuffer())); return; } - throw new BadPacketException("Unexpected non-serverbound packet"); + throw new PacketHandlingException("Unexpected non-serverbound packet"); } $timings = Timings::getReceiveDataPacketTimings($packet); @@ -387,7 +387,7 @@ class NetworkSession{ try{ $packet->decode(); }catch(PacketDecodeException $e){ - throw BadPacketException::wrap($e); + throw PacketHandlingException::wrap($e); } $stream = $packet->getSerializer(); if(!$stream->feof()){ diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index b070a31850..f470967154 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -41,7 +41,6 @@ use pocketmine\item\WrittenBook; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\StringTag; -use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\convert\SkinAdapterSingleton; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\InventoryManager; @@ -90,6 +89,7 @@ use pocketmine\network\mcpe\protocol\types\inventory\UIInventorySlotOffset; use pocketmine\network\mcpe\protocol\types\inventory\UseItemOnEntityTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\UseItemTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes; +use pocketmine\network\PacketHandlingException; use pocketmine\player\Player; use pocketmine\utils\AssumptionFailedError; use function array_key_exists; @@ -640,7 +640,7 @@ class InGamePacketHandler extends PacketHandler{ try{ $text = SignText::fromBlob($textBlobTag->getValue()); }catch(\InvalidArgumentException $e){ - throw BadPacketException::wrap($e, "Invalid sign text update"); + throw PacketHandlingException::wrap($e, "Invalid sign text update"); } try{ @@ -650,7 +650,7 @@ class InGamePacketHandler extends PacketHandler{ } } }catch(\UnexpectedValueException $e){ - throw BadPacketException::wrap($e); + throw PacketHandlingException::wrap($e); } return true; @@ -721,7 +721,7 @@ class InGamePacketHandler extends PacketHandler{ try{ $skin = SkinAdapterSingleton::get()->fromSkinData($packet->skin); }catch(InvalidSkinException $e){ - throw BadPacketException::wrap($e, "Invalid skin in PlayerSkinPacket"); + throw PacketHandlingException::wrap($e, "Invalid skin in PlayerSkinPacket"); } return $this->player->changeSkin($skin, $packet->newSkinName, $packet->oldSkinName); } @@ -800,7 +800,7 @@ class InGamePacketHandler extends PacketHandler{ * Hack to work around a stupid bug in Minecraft W10 which causes empty strings to be sent unquoted in form responses. * * @return mixed - * @throws BadPacketException + * @throws PacketHandlingException */ private static function stupid_json_decode(string $json, bool $assoc = false){ if(preg_match('/^\[(.+)\]$/s', $json, $matches) > 0){ diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index b48bad7658..222a67407f 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\handler; use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; use pocketmine\entity\InvalidSkinException; use pocketmine\event\player\PlayerPreLoginEvent; -use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\auth\ProcessLoginTask; use pocketmine\network\mcpe\convert\SkinAdapterSingleton; use pocketmine\network\mcpe\JwtException; @@ -39,6 +38,7 @@ use pocketmine\network\mcpe\protocol\types\login\AuthenticationData; use pocketmine\network\mcpe\protocol\types\login\ClientData; use pocketmine\network\mcpe\protocol\types\login\ClientDataToSkinDataHelper; use pocketmine\network\mcpe\protocol\types\login\JwtChain; +use pocketmine\network\PacketHandlingException; use pocketmine\player\Player; use pocketmine\player\PlayerInfo; use pocketmine\player\XboxLivePlayerInfo; @@ -113,7 +113,7 @@ class LoginPacketHandler extends PacketHandler{ } if(!Uuid::isValid($extraData->identity)){ - throw new BadPacketException("Invalid login UUID"); + throw new PacketHandlingException("Invalid login UUID"); } $uuid = Uuid::fromString($extraData->identity); if($extraData->XUID !== ""){ @@ -164,7 +164,7 @@ class LoginPacketHandler extends PacketHandler{ } /** - * @throws BadPacketException + * @throws PacketHandlingException */ protected function fetchAuthData(JwtChain $chain) : AuthenticationData{ /** @var AuthenticationData|null $extraData */ @@ -174,15 +174,15 @@ class LoginPacketHandler extends PacketHandler{ try{ [, $claims, ] = JwtUtils::parse($jwt); }catch(JwtException $e){ - throw BadPacketException::wrap($e); + throw PacketHandlingException::wrap($e); } if(isset($claims["extraData"])){ if($extraData !== null){ - throw new BadPacketException("Found 'extraData' more than once in chainData"); + throw new PacketHandlingException("Found 'extraData' more than once in chainData"); } if(!is_array($claims["extraData"])){ - throw new BadPacketException("'extraData' key should be an array"); + throw new PacketHandlingException("'extraData' key should be an array"); } $mapper = new \JsonMapper; $mapper->bEnforceMapType = false; //TODO: we don't really need this as an array, but right now we don't have enough models @@ -192,24 +192,24 @@ class LoginPacketHandler extends PacketHandler{ /** @var AuthenticationData $extraData */ $extraData = $mapper->map($claims["extraData"], new AuthenticationData); }catch(\JsonMapper_Exception $e){ - throw BadPacketException::wrap($e); + throw PacketHandlingException::wrap($e); } } } if($extraData === null){ - throw new BadPacketException("'extraData' not found in chain data"); + throw new PacketHandlingException("'extraData' not found in chain data"); } return $extraData; } /** - * @throws BadPacketException + * @throws PacketHandlingException */ protected function parseClientData(string $clientDataJwt) : ClientData{ try{ [, $clientDataClaims, ] = JwtUtils::parse($clientDataJwt); }catch(JwtException $e){ - throw BadPacketException::wrap($e); + throw PacketHandlingException::wrap($e); } $mapper = new \JsonMapper; @@ -219,7 +219,7 @@ class LoginPacketHandler extends PacketHandler{ try{ $clientData = $mapper->map($clientDataClaims, new ClientData); }catch(\JsonMapper_Exception $e){ - throw BadPacketException::wrap($e); + throw PacketHandlingException::wrap($e); } return $clientData; } diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 8ab70c3937..c31b436940 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\raklib; use pocketmine\network\AdvancedNetworkInterface; -use pocketmine\network\BadPacketException; use pocketmine\network\mcpe\compression\ZlibCompressor; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\NetworkSession; @@ -33,6 +32,7 @@ use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\StandardPacketBroadcaster; use pocketmine\network\Network; +use pocketmine\network\PacketHandlingException; use pocketmine\Server; use pocketmine\snooze\SleeperNotifier; use pocketmine\utils\Filesystem; @@ -184,7 +184,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ $buf = substr($packet, 1); try{ $session->handleEncoded($buf); - }catch(BadPacketException $e){ + }catch(PacketHandlingException $e){ $errorId = bin2hex(random_bytes(6)); $logger = $session->getLogger(); From 5e8078f3dd88d7b0bc41d75bce1ad0520c1151f4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 31 Mar 2021 21:39:55 +0100 Subject: [PATCH 2346/3224] PacketSerializer: Improved performance of item serialize/deserialize --- .../mcpe/protocol/serializer/PacketSerializer.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/network/mcpe/protocol/serializer/PacketSerializer.php b/src/network/mcpe/protocol/serializer/PacketSerializer.php index 239a38ba3e..0b44b96b83 100644 --- a/src/network/mcpe/protocol/serializer/PacketSerializer.php +++ b/src/network/mcpe/protocol/serializer/PacketSerializer.php @@ -68,6 +68,13 @@ use function substr; class PacketSerializer extends BinaryStream{ + private int $shieldItemRuntimeId; + + public function __construct(string $buffer = "", int $offset = 0){ + parent::__construct($buffer, $offset); + $this->shieldItemRuntimeId = ItemTypeDictionary::getInstance()->toRuntimeId("minecraft:shield"); + } + /** * @throws BinaryDataException */ @@ -244,7 +251,7 @@ class PacketSerializer extends BinaryStream{ } $shieldBlockingTick = null; - if($id === ItemTypeDictionary::getInstance()->fromStringId("minecraft:shield")){ + if($id === $this->shieldItemRuntimeId){ $shieldBlockingTick = $this->getVarLong(); } @@ -281,7 +288,7 @@ class PacketSerializer extends BinaryStream{ } $blockingTick = $item->getShieldBlockingTick(); - if($item->getId() === ItemTypeDictionary::getInstance()->fromStringId("minecraft:shield")){ + if($item->getId() === $this->shieldItemRuntimeId){ $this->putVarLong($blockingTick ?? 0); } } From cd71fec53d1bddde0f973b052c0d17bb479890d6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 31 Mar 2021 21:41:50 +0100 Subject: [PATCH 2347/3224] fucking phpstorm 2020.3 and its broken autocomplete --- src/network/mcpe/protocol/serializer/PacketSerializer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/protocol/serializer/PacketSerializer.php b/src/network/mcpe/protocol/serializer/PacketSerializer.php index 0b44b96b83..8e8fed2633 100644 --- a/src/network/mcpe/protocol/serializer/PacketSerializer.php +++ b/src/network/mcpe/protocol/serializer/PacketSerializer.php @@ -72,7 +72,7 @@ class PacketSerializer extends BinaryStream{ public function __construct(string $buffer = "", int $offset = 0){ parent::__construct($buffer, $offset); - $this->shieldItemRuntimeId = ItemTypeDictionary::getInstance()->toRuntimeId("minecraft:shield"); + $this->shieldItemRuntimeId = ItemTypeDictionary::getInstance()->fromStringId("minecraft:shield"); } /** From 4eaa600f35691fd45d1b55c58c655e94a2c4feaf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 31 Mar 2021 21:54:27 +0100 Subject: [PATCH 2348/3224] actions: clone submodules in PHPUnit job --- .github/workflows/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 635cc0e649..3d0f572875 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -91,6 +91,8 @@ jobs: steps: - uses: actions/checkout@v2 + with: + submodules: true - name: Restore PHP build cache id: php-build-cache From 1898d4b42cf0466e0d2a17071c567a890f84c932 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 3 Apr 2021 22:20:00 +0100 Subject: [PATCH 2349/3224] Fixed corner case with player spawning in ungenerated terrain we can't get the safe spawn location of a set of coordinates if the coordinates are in an ungenerated chunk. This can happen if doing /setworldspawn and then having a new player join the server. --- src/Server.php | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/Server.php b/src/Server.php index 6a31935eaf..c4c6c4be31 100644 --- a/src/Server.php +++ b/src/Server.php @@ -586,29 +586,40 @@ class Server{ $class = $ev->getPlayerClass(); if($offlinePlayerData !== null and ($world = $this->worldManager->getWorldByName($offlinePlayerData->getString("Level", ""))) !== null){ - $spawn = EntityDataHelper::parseLocation($offlinePlayerData, $world); - $onGround = $offlinePlayerData->getByte("OnGround", 1) === 1; + $playerPos = EntityDataHelper::parseLocation($offlinePlayerData, $world); + $spawn = $playerPos->asVector3(); }else{ $world = $this->worldManager->getDefaultWorld(); if($world === null){ throw new AssumptionFailedError("Default world should always be loaded"); } - $spawn = Location::fromObject($world->getSafeSpawn(), $world); - $onGround = true; + $playerPos = null; + $spawn = $world->getSpawnLocation(); } $playerPromise = new PlayerCreationPromise(); $world->requestChunkPopulation($spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4, null)->onCompletion( - function() use ($playerPromise, $class, $session, $playerInfo, $authenticated, $spawn, $offlinePlayerData, $onGround) : void{ + function() use ($playerPromise, $class, $session, $playerInfo, $authenticated, $world, $playerPos, $spawn, $offlinePlayerData) : void{ if(!$session->isConnected()){ $playerPromise->reject(); return; } + + /* Stick with the original spawn at the time of generation request, even if it changed since then. + * This is because we know for sure that that chunk will be generated, but the one at the new location + * might not be, and it would be much more complex to go back and redo the whole thing. + * + * TODO: this relies on the assumption that getSafeSpawn() will only alter the Y coordinate of the + * provided position. If this assumption is broken, we'll start seeing crashes in here. + */ + /** * @see Player::__construct() * @var Player $player */ - $player = new $class($this, $session, $playerInfo, $authenticated, $spawn, $offlinePlayerData); - $player->onGround = $onGround; //TODO: this hack is needed for new players in-air ticks - they don't get detected as on-ground until they move + $player = new $class($this, $session, $playerInfo, $authenticated, $playerPos ?? Location::fromObject($world->getSafeSpawn($spawn), $world), $offlinePlayerData); + if(!$player->hasPlayedBefore()){ + $player->onGround = true; //TODO: this hack is needed for new players in-air ticks - they don't get detected as on-ground until they move + } $playerPromise->resolve($player); }, static function() use ($playerPromise, $session) : void{ From 7aa336f5e48732c7761a55bfa627cdc7ba866ad8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 7 Apr 2021 19:44:00 +0100 Subject: [PATCH 2350/3224] Remove dead baseline --- tests/phpstan/configs/ds-bugs.neon | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 tests/phpstan/configs/ds-bugs.neon diff --git a/tests/phpstan/configs/ds-bugs.neon b/tests/phpstan/configs/ds-bugs.neon deleted file mode 100644 index 48277f766b..0000000000 --- a/tests/phpstan/configs/ds-bugs.neon +++ /dev/null @@ -1,7 +0,0 @@ -parameters: - ignoreErrors: - - - message: "#^Cannot access offset int on Ds\\\\Deque\\\\.$#" - count: 2 - path: ../../../src/item/WritableBookBase.php - From 19f536d68ad43e26f5b5744f44a0d939beff1840 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 7 Apr 2021 21:54:21 +0100 Subject: [PATCH 2351/3224] ... --- src/network/mcpe/protocol/serializer/PacketSerializer.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/network/mcpe/protocol/serializer/PacketSerializer.php b/src/network/mcpe/protocol/serializer/PacketSerializer.php index 1a5b4aebab..e0f1e462b9 100644 --- a/src/network/mcpe/protocol/serializer/PacketSerializer.php +++ b/src/network/mcpe/protocol/serializer/PacketSerializer.php @@ -25,7 +25,6 @@ namespace pocketmine\network\mcpe\protocol\serializer; #include -use pocketmine\entity\Entity; use pocketmine\math\Vector3; use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\NbtDataException; From 0312b62c8ac6cbc6aff621cd776f19e84c58ec9c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 9 Apr 2021 15:37:58 +0100 Subject: [PATCH 2352/3224] DataPacket no longer keeps its own serializer since a while ago, we're anyway just discarding the internal buffer anyway when the packet is repeatedly encoded, so this doesn't serve any advantage anymore. We do need a system to be able to reuse encoded packet buffers, but right now we're not reusing them anyway. --- src/network/mcpe/NetworkSession.php | 15 +++++----- src/network/mcpe/protocol/DataPacket.php | 29 ++++--------------- src/network/mcpe/protocol/Packet.php | 8 ++--- src/network/mcpe/protocol/PacketPool.php | 9 ++---- .../mcpe/protocol/serializer/PacketBatch.php | 10 ++++--- .../network/mcpe/protocol/DataPacketTest.php | 6 ++-- .../network/mcpe/protocol/LoginPacketTest.php | 2 +- 7 files changed, 29 insertions(+), 50 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 676d244fd9..ce294fa913 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -73,6 +73,7 @@ use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\PlayStatusPacket; use pocketmine\network\mcpe\protocol\RemoveActorPacket; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\ServerboundPacket; use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket; use pocketmine\network\mcpe\protocol\SetActorDataPacket; @@ -355,11 +356,11 @@ class NetworkSession{ } try{ - foreach($stream->getPackets($this->packetPool, 500) as $packet){ + foreach($stream->getPackets($this->packetPool, 500) as [$packet, $buffer]){ try{ - $this->handleDataPacket($packet); + $this->handleDataPacket($packet, $buffer); }catch(PacketHandlingException $e){ - $this->logger->debug($packet->getName() . ": " . base64_encode($packet->getSerializer()->getBuffer())); + $this->logger->debug($packet->getName() . ": " . base64_encode($buffer)); throw PacketHandlingException::wrap($e, "Error processing " . $packet->getName()); } } @@ -372,10 +373,10 @@ class NetworkSession{ /** * @throws PacketHandlingException */ - public function handleDataPacket(Packet $packet) : void{ + public function handleDataPacket(Packet $packet, string $buffer) : void{ if(!($packet instanceof ServerboundPacket)){ if($packet instanceof GarbageServerboundPacket){ - $this->logger->debug("Garbage serverbound " . $packet->getName() . ": " . base64_encode($packet->getSerializer()->getBuffer())); + $this->logger->debug("Garbage serverbound " . $packet->getName() . ": " . base64_encode($buffer)); return; } throw new PacketHandlingException("Unexpected non-serverbound packet"); @@ -385,12 +386,12 @@ class NetworkSession{ $timings->startTiming(); try{ + $stream = new PacketSerializer($buffer); try{ - $packet->decode(); + $packet->decode($stream); }catch(PacketDecodeException $e){ throw PacketHandlingException::wrap($e); } - $stream = $packet->getSerializer(); if(!$stream->feof()){ $remains = substr($stream->getBuffer(), $stream->getOffset()); $this->logger->debug("Still " . strlen($remains) . " bytes unread in " . $packet->getName() . ": " . bin2hex($remains)); diff --git a/src/network/mcpe/protocol/DataPacket.php b/src/network/mcpe/protocol/DataPacket.php index be7904ee69..128d96b2a9 100644 --- a/src/network/mcpe/protocol/DataPacket.php +++ b/src/network/mcpe/protocol/DataPacket.php @@ -44,21 +44,6 @@ abstract class DataPacket implements Packet{ /** @var int */ public $recipientSubId = 0; - /** @var PacketSerializer */ - private $buf; - - public function __construct(){ - $this->buf = new PacketSerializer(); - } - - public function getSerializer() : PacketSerializer{ - return $this->buf; - } - - public function setSerializer(PacketSerializer $serializer) : void{ - $this->buf = $serializer; - } - public function pid() : int{ return $this::NETWORK_ID; } @@ -74,11 +59,10 @@ abstract class DataPacket implements Packet{ /** * @throws PacketDecodeException */ - final public function decode() : void{ - $this->buf->rewind(); + final public function decode(PacketSerializer $in) : void{ try{ - $this->decodeHeader($this->buf); - $this->decodePayload($this->buf); + $this->decodeHeader($in); + $this->decodePayload($in); }catch(BinaryDataException | PacketDecodeException $e){ throw PacketDecodeException::wrap($e, $this->getName()); } @@ -108,10 +92,9 @@ abstract class DataPacket implements Packet{ */ abstract protected function decodePayload(PacketSerializer $in) : void; - final public function encode() : void{ - $this->buf = new PacketSerializer(); - $this->encodeHeader($this->buf); - $this->encodePayload($this->buf); + final public function encode(PacketSerializer $out) : void{ + $this->encodeHeader($out); + $this->encodePayload($out); } protected function encodeHeader(PacketSerializer $out) : void{ diff --git a/src/network/mcpe/protocol/Packet.php b/src/network/mcpe/protocol/Packet.php index 6c84cd97f2..f089901ca3 100644 --- a/src/network/mcpe/protocol/Packet.php +++ b/src/network/mcpe/protocol/Packet.php @@ -27,10 +27,6 @@ use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; interface Packet{ - public function getSerializer() : PacketSerializer; - - public function setSerializer(PacketSerializer $serializer) : void; - public function pid() : int; public function getName() : string; @@ -40,9 +36,9 @@ interface Packet{ /** * @throws PacketDecodeException */ - public function decode() : void; + public function decode(PacketSerializer $in) : void; - public function encode() : void; + public function encode(PacketSerializer $out) : void; /** * Performs handling for this packet. Usually you'll want an appropriately named method in the session handler for diff --git a/src/network/mcpe/protocol/PacketPool.php b/src/network/mcpe/protocol/PacketPool.php index 3b3d3a88ed..dc0713f9c9 100644 --- a/src/network/mcpe/protocol/PacketPool.php +++ b/src/network/mcpe/protocol/PacketPool.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; +use pocketmine\utils\Binary; use pocketmine\utils\BinaryDataException; class PacketPool{ @@ -216,10 +216,7 @@ class PacketPool{ * @throws BinaryDataException */ public function getPacket(string $buffer) : Packet{ - $serializer = new PacketSerializer($buffer); - $pk = $this->getPacketById($serializer->getUnsignedVarInt() & DataPacket::PID_MASK); - $pk->setSerializer($serializer); - - return $pk; + $offset = 0; + return $this->getPacketById(Binary::readUnsignedVarInt($buffer, $offset) & DataPacket::PID_MASK); } } diff --git a/src/network/mcpe/protocol/serializer/PacketBatch.php b/src/network/mcpe/protocol/serializer/PacketBatch.php index e64a31b1ea..86b0a94d64 100644 --- a/src/network/mcpe/protocol/serializer/PacketBatch.php +++ b/src/network/mcpe/protocol/serializer/PacketBatch.php @@ -39,14 +39,15 @@ class PacketBatch{ /** * @return \Generator|Packet[] - * @phpstan-return \Generator + * @phpstan-return \Generator * @throws PacketDecodeException */ public function getPackets(PacketPool $packetPool, int $max) : \Generator{ $serializer = new PacketSerializer($this->buffer); for($c = 0; $c < $max and !$serializer->feof(); ++$c){ try{ - yield $c => $packetPool->getPacket($serializer->getString()); + $buffer = $serializer->getString(); + yield $c => [$packetPool->getPacket($buffer), $buffer]; }catch(BinaryDataException $e){ throw new PacketDecodeException("Error decoding packet $c of batch: " . $e->getMessage(), 0, $e); } @@ -66,8 +67,9 @@ class PacketBatch{ public static function fromPackets(Packet ...$packets) : self{ $serializer = new PacketSerializer(); foreach($packets as $packet){ - $packet->encode(); - $serializer->putString($packet->getSerializer()->getBuffer()); + $subSerializer = new PacketSerializer(); + $packet->encode($subSerializer); + $serializer->putString($subSerializer->getBuffer()); } return new self($serializer->getBuffer()); } diff --git a/tests/phpunit/network/mcpe/protocol/DataPacketTest.php b/tests/phpunit/network/mcpe/protocol/DataPacketTest.php index 52634b4c5b..94bdcb83df 100644 --- a/tests/phpunit/network/mcpe/protocol/DataPacketTest.php +++ b/tests/phpunit/network/mcpe/protocol/DataPacketTest.php @@ -32,11 +32,11 @@ class DataPacketTest extends TestCase{ $pk = new TestPacket(); $pk->senderSubId = 3; $pk->recipientSubId = 2; - $pk->encode(); + $serializer = new PacketSerializer(); + $pk->encode($serializer); $pk2 = new TestPacket(); - $pk2->setSerializer(new PacketSerializer($pk->getSerializer()->getBuffer())); - $pk2->decode(); + $pk2->decode(new PacketSerializer($serializer->getBuffer())); self::assertSame($pk2->senderSubId, 3); self::assertSame($pk2->recipientSubId, 2); } diff --git a/tests/phpunit/network/mcpe/protocol/LoginPacketTest.php b/tests/phpunit/network/mcpe/protocol/LoginPacketTest.php index 00cfaafe06..7ddf34dbeb 100644 --- a/tests/phpunit/network/mcpe/protocol/LoginPacketTest.php +++ b/tests/phpunit/network/mcpe/protocol/LoginPacketTest.php @@ -43,6 +43,6 @@ class LoginPacketTest extends TestCase{ $pk = PacketPool::getInstance()->getPacket($stream->getBuffer()); $this->expectException(PacketDecodeException::class); - $pk->decode(); //bang + $pk->decode(new PacketSerializer($stream->getBuffer())); //bang } } From 66622defae3dbb667506ed07d32432c020eb207b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 11 Apr 2021 16:49:57 +0100 Subject: [PATCH 2353/3224] PacketSerializer: fix merge error --- src/network/mcpe/protocol/serializer/PacketSerializer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/protocol/serializer/PacketSerializer.php b/src/network/mcpe/protocol/serializer/PacketSerializer.php index 603ed607b8..e569599c1b 100644 --- a/src/network/mcpe/protocol/serializer/PacketSerializer.php +++ b/src/network/mcpe/protocol/serializer/PacketSerializer.php @@ -287,7 +287,7 @@ class PacketSerializer extends BinaryStream{ } if(!$extraData->feof()){ - throw new PacketDecodeException("Unexpected trailing extradata for network item $netId"); + throw new PacketDecodeException("Unexpected trailing extradata for network item $id"); } return new ItemStack($id, $meta, $count, $blockRuntimeId, $compound, $canPlaceOn, $canDestroy, $shieldBlockingTick); From e720c001a981ffca36b766e2aa7568ec76f28581 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 11 Apr 2021 17:21:29 +0100 Subject: [PATCH 2354/3224] ConsoleCommandSender: ensure that PermissibleBase doesn't leak if recalculatePermissions() was called, the PermissionManager will reference it, preventing it from being GC'd. --- src/command/ConsoleCommandSender.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/command/ConsoleCommandSender.php b/src/command/ConsoleCommandSender.php index 5649f9f4c9..e94d8483e9 100644 --- a/src/command/ConsoleCommandSender.php +++ b/src/command/ConsoleCommandSender.php @@ -87,4 +87,9 @@ class ConsoleCommandSender implements CommandSender{ } $this->lineHeight = $height; } + + public function __destruct(){ + //permission subscriptions need to be cleaned up explicitly + $this->perm->destroyCycles(); + } } From 4b715aaba7e1e27070719c35728edb007f9bbc93 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 11 Apr 2021 20:59:09 +0100 Subject: [PATCH 2355/3224] Document API changes related to broadcast channels closes #2960 --- changelogs/4.0-snapshot.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 847a91705f..0e6e2a6bc9 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -585,6 +585,7 @@ This version features substantial changes to the network system, improving coher - The following API methods have been added: - `Permission->addChild()` - `Permission->removeChild()` + - `Permissible->getPermissionRecalculationCallbacks()` - allows reacting to changes of permissions, such as new permissions being granted or denied - The following API methods have been removed: - `Permissible->isOp()`: use `Permissible->hasPermission(DefaultPermissions::ROOT_OPERATOR)` instead, **but you really shouldn't directly depend on a player's op status, add your own permissions instead!** - `Permissible->setOp()`: use `addAttachment($plugin, DefaultPermissions::ROOT_OPERATOR, true)` instead to add, and `removeAttachment()` to remove it (or addAttachment() with false to explicitly deny it, just like any other permission) @@ -722,11 +723,16 @@ This version features substantial changes to the network system, improving coher - `AsyncTask->saveToThreadStore()`: use `AsyncTask->worker->saveToThreadStore()` ### Server -- The following API methods have been added: - - `subscribeToBroadcastChannel()` - allows subscribing a `CommandSender` to receive chat messages (and other message types) on any channel - - `unsubscribeFromBroadcastChannel()` - - `unsubscribeFromAllBroadcastChannels()` - - `getBroadcastChannelSubscribers()` +- New chat broadcasting APIs have been implemented, which don't depend on the permission system. + - The following API methods have been added: + - `subscribeToBroadcastChannel()` - allows subscribing a `CommandSender` to receive chat messages (and other message types) on any channel + - `unsubscribeFromBroadcastChannel()` + - `unsubscribeFromAllBroadcastChannels()` + - `getBroadcastChannelSubscribers()` + - Giving `Player` any `pocketmine.broadcast.*` permissions will cause them to automatically subscribe to the corresponding broadcast channel (and removing them will unsubscribe it). + - It's now possible to create and subscribe to custom broadcast channels without using permissions. + - However, `Player`s may automatically unsubscribe themselves from the builtin broadcast channels if they don't have the proper permissions. + - Automatic subscribe/unsubscribe from custom broadcast channels can be implemented using the new `Permissible` permission recalculation callbacks API. - The following API methods have been removed: - `reloadWhitelist()` - `getLevelMetadata()` From 666670bc6f6c013edb3d967fed5d5bfea2af269d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 12 Apr 2021 15:57:24 +0100 Subject: [PATCH 2356/3224] PermissionAttachment may now reference zero or more permissibles this makes PermissionAttachment more and more like Permission, except that it doesn't have a name. Right now, the only value of this API change is that it allows breaking references to dead Permissibles, but in the future it should be possible to reuse a single PermissionAttachment on multiple Permissibles. --- src/permission/PermissibleBase.php | 12 +++-- src/permission/PermissionAttachment.php | 49 ++++++++++++++------ src/permission/PermissionRemovedExecutor.php | 2 +- 3 files changed, 45 insertions(+), 18 deletions(-) diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index a1b43bfd34..87a6ca04c6 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -105,12 +105,14 @@ class PermissibleBase implements Permissible{ throw new PluginException("Plugin " . $plugin->getDescription()->getName() . " is disabled"); } - $result = new PermissionAttachment($plugin, $this); + $result = new PermissionAttachment($plugin); $this->attachments[spl_object_id($result)] = $result; if($name !== null and $value !== null){ $result->setPermission($name, $value); } + $result->subscribePermissible($this); + $this->recalculatePermissions(); return $result; @@ -119,8 +121,9 @@ class PermissibleBase implements Permissible{ public function removeAttachment(PermissionAttachment $attachment) : void{ if(isset($this->attachments[spl_object_id($attachment)])){ unset($this->attachments[spl_object_id($attachment)]); + $attachment->unsubscribePermissible($this); if(($ex = $attachment->getRemovalCallback()) !== null){ - $ex->attachmentRemoved($attachment); + $ex->attachmentRemoved($this, $attachment); } $this->recalculatePermissions(); @@ -213,7 +216,10 @@ class PermissibleBase implements Permissible{ public function destroyCycles() : void{ PermissionManager::getInstance()->unsubscribeFromAllPermissions($this); $this->permissions = []; //PermissionAttachmentInfo doesn't reference Permissible anymore, but it references PermissionAttachment which does - $this->attachments = []; //this might still be a problem if the attachments are still referenced, but we can't do anything about that + foreach($this->attachments as $attachment){ + $attachment->unsubscribePermissible($this); + } + $this->attachments = []; $this->permissionRecalculationCallbacks->clear(); } } diff --git a/src/permission/PermissionAttachment.php b/src/permission/PermissionAttachment.php index 7caad254c6..c66cc7fdfc 100644 --- a/src/permission/PermissionAttachment.php +++ b/src/permission/PermissionAttachment.php @@ -25,6 +25,7 @@ namespace pocketmine\permission; use pocketmine\plugin\Plugin; use pocketmine\plugin\PluginException; +use function spl_object_id; class PermissionAttachment{ /** @var PermissionRemovedExecutor|null */ @@ -33,8 +34,11 @@ class PermissionAttachment{ /** @var bool[] */ private $permissions = []; - /** @var Permissible */ - private $permissible; + /** + * @var Permissible[] + * @phpstan-var array + */ + private $subscribers = []; /** @var Plugin */ private $plugin; @@ -42,12 +46,11 @@ class PermissionAttachment{ /** * @throws PluginException */ - public function __construct(Plugin $plugin, Permissible $permissible){ + public function __construct(Plugin $plugin){ if(!$plugin->isEnabled()){ throw new PluginException("Plugin " . $plugin->getDescription()->getName() . " is disabled"); } - $this->permissible = $permissible; $this->plugin = $plugin; } @@ -63,9 +66,11 @@ class PermissionAttachment{ return $this->removed; } - public function getPermissible() : Permissible{ - return $this->permissible; - } + /** + * @return Permissible[] + * @phpstan-return array + */ + public function getSubscribers() : array{ return $this->subscribers; } /** * @return bool[] @@ -74,9 +79,15 @@ class PermissionAttachment{ return $this->permissions; } + private function recalculatePermissibles() : void{ + foreach($this->subscribers as $permissible){ + $permissible->recalculatePermissions(); + } + } + public function clearPermissions() : void{ $this->permissions = []; - $this->permissible->recalculatePermissions(); + $this->recalculatePermissibles(); } /** @@ -86,7 +97,7 @@ class PermissionAttachment{ foreach($permissions as $key => $value){ $this->permissions[$key] = $value; } - $this->permissible->recalculatePermissions(); + $this->recalculatePermissibles(); } /** @@ -96,7 +107,7 @@ class PermissionAttachment{ foreach($permissions as $node){ unset($this->permissions[$node]); } - $this->permissible->recalculatePermissions(); + $this->recalculatePermissibles(); } /** @@ -120,7 +131,7 @@ class PermissionAttachment{ unset($this->permissions[$name]); } $this->permissions[$name] = $value; - $this->permissible->recalculatePermissions(); + $this->recalculatePermissibles(); } /** @@ -130,11 +141,21 @@ class PermissionAttachment{ $name = $name instanceof Permission ? $name->getName() : $name; if(isset($this->permissions[$name])){ unset($this->permissions[$name]); - $this->permissible->recalculatePermissions(); + $this->recalculatePermissibles(); } } - public function remove() : void{ - $this->permissible->removeAttachment($this); + /** + * @internal + */ + public function subscribePermissible(Permissible $permissible) : void{ + $this->subscribers[spl_object_id($permissible)] = $permissible; + } + + /** + * @internal + */ + public function unsubscribePermissible(Permissible $permissible) : void{ + unset($this->subscribers[spl_object_id($permissible)]); } } diff --git a/src/permission/PermissionRemovedExecutor.php b/src/permission/PermissionRemovedExecutor.php index 606d017ee5..4fbe96ff3f 100644 --- a/src/permission/PermissionRemovedExecutor.php +++ b/src/permission/PermissionRemovedExecutor.php @@ -25,5 +25,5 @@ namespace pocketmine\permission; interface PermissionRemovedExecutor{ - public function attachmentRemoved(PermissionAttachment $attachment) : void; + public function attachmentRemoved(Permissible $permissible, PermissionAttachment $attachment) : void; } From c42a00641f8227ce9ac20c007c56f0d642304c88 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 12 Apr 2021 16:25:50 +0100 Subject: [PATCH 2357/3224] [ci skip] changelog: mention more Permission API changes --- changelogs/4.0-snapshot.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 0e6e2a6bc9..be89cc1401 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -586,6 +586,9 @@ This version features substantial changes to the network system, improving coher - `Permission->addChild()` - `Permission->removeChild()` - `Permissible->getPermissionRecalculationCallbacks()` - allows reacting to changes of permissions, such as new permissions being granted or denied + - `Permissible->setBasePermission()` - used for assigning root permissions like `pocketmine.group.operator`; plugins usually shouldn't use this + - `Permissible->unsetBasePermission()` + - `PermissionAttachmentInfo->getGroupPermissionInfo()` - returns the `PermissionAttachmentInfo` of the permission that caused the current permission value to be set, or null if the permission is explicit - The following API methods have been removed: - `Permissible->isOp()`: use `Permissible->hasPermission(DefaultPermissions::ROOT_OPERATOR)` instead, **but you really shouldn't directly depend on a player's op status, add your own permissions instead!** - `Permissible->setOp()`: use `addAttachment($plugin, DefaultPermissions::ROOT_OPERATOR, true)` instead to add, and `removeAttachment()` to remove it (or addAttachment() with false to explicitly deny it, just like any other permission) @@ -597,6 +600,8 @@ This version features substantial changes to the network system, improving coher - `PermissionManager->subscribeToDefaultPerms()` - `PermissionManager->unsubscribeFromDefaultPerms()` - `PermissionManager->getDefaultPermSubscriptions()` + - `PermissionAttachment->getPermissible()` + - `PermissionAttachmentInfo->getPermissible()` - The following fields have been removed: - `Permission::$DEFAULT_PERMISSION` - The following API methods have changes: From bfa1b4384b9e7a2dd1825fe51e24f897712fdb22 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 13 Apr 2021 15:48:14 +0100 Subject: [PATCH 2358/3224] Updated composer dependencies --- composer.lock | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/composer.lock b/composer.lock index 29dac47c43..87b4f7b317 100644 --- a/composer.lock +++ b/composer.lock @@ -661,12 +661,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "c548a3eb97bd2c14fbea69326e87957e5dfac3e1" + "reference": "59f3c8cd49d4b6a028e4f8176c55e800948ebded" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/c548a3eb97bd2c14fbea69326e87957e5dfac3e1", - "reference": "c548a3eb97bd2c14fbea69326e87957e5dfac3e1", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/59f3c8cd49d4b6a028e4f8176c55e800948ebded", + "reference": "59f3c8cd49d4b6a028e4f8176c55e800948ebded", "shasum": "" }, "require": { @@ -695,7 +695,7 @@ "issues": "https://github.com/pmmp/NBT/issues", "source": "https://github.com/pmmp/NBT/tree/master" }, - "time": "2021-03-14T19:19:46+00:00" + "time": "2021-04-12T22:54:46+00:00" }, { "name": "pocketmine/raklib", @@ -703,12 +703,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "3c226482dd0e966ee9bf26fac405f083cb97ea68" + "reference": "bd8b75396e4585116838435839f7ccd51862663d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/3c226482dd0e966ee9bf26fac405f083cb97ea68", - "reference": "3c226482dd0e966ee9bf26fac405f083cb97ea68", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/bd8b75396e4585116838435839f7ccd51862663d", + "reference": "bd8b75396e4585116838435839f7ccd51862663d", "shasum": "" }, "require": { @@ -738,7 +738,7 @@ "issues": "https://github.com/pmmp/RakLib/issues", "source": "https://github.com/pmmp/RakLib/tree/master" }, - "time": "2021-03-16T19:35:37+00:00" + "time": "2021-04-08T14:24:31+00:00" }, { "name": "pocketmine/snooze", @@ -1958,16 +1958,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.5", + "version": "9.2.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1" + "reference": "f6293e1b30a2354e8428e004689671b83871edde" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f3e026641cc91909d421802dd3ac7827ebfd97e1", - "reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f6293e1b30a2354e8428e004689671b83871edde", + "reference": "f6293e1b30a2354e8428e004689671b83871edde", "shasum": "" }, "require": { @@ -2023,7 +2023,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.5" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.6" }, "funding": [ { @@ -2031,7 +2031,7 @@ "type": "github" } ], - "time": "2020-11-28T06:44:49+00:00" + "time": "2021-03-28T07:26:59+00:00" }, { "name": "phpunit/php-file-iterator", From 6ce15854af608832cb4658d606894f171dcf7f04 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 13 Apr 2021 20:19:53 +0100 Subject: [PATCH 2359/3224] Clean up generator preset handling --- src/world/format/io/FormatConverter.php | 2 +- src/world/format/io/WorldData.php | 6 +---- src/world/format/io/data/BaseNbtWorldData.php | 4 ++-- src/world/generator/Flat.php | 23 +++++++------------ src/world/generator/Generator.php | 15 ++++-------- src/world/generator/GeneratorRegisterTask.php | 10 +++----- src/world/generator/hell/Nether.php | 7 ++---- src/world/generator/normal/Normal.php | 7 ++---- 8 files changed, 23 insertions(+), 51 deletions(-) diff --git a/src/world/format/io/FormatConverter.php b/src/world/format/io/FormatConverter.php index 7e5bb47029..a2ddf9fd25 100644 --- a/src/world/format/io/FormatConverter.php +++ b/src/world/format/io/FormatConverter.php @@ -105,7 +105,7 @@ class FormatConverter{ $this->logger->info("Found previous conversion attempt, deleting..."); Filesystem::recursiveUnlink($convertedOutput); } - $this->newProvider::generate($convertedOutput, $data->getName(), $data->getSeed(), GeneratorManager::getInstance()->getGenerator($data->getGenerator()), $data->getGeneratorOptions()); + $this->newProvider::generate($convertedOutput, $data->getName(), $data->getSeed(), GeneratorManager::getInstance()->getGenerator($data->getGenerator()), ["preset" => $data->getGeneratorOptions()]); /** * @see WritableWorldProvider::__construct() diff --git a/src/world/format/io/WorldData.php b/src/world/format/io/WorldData.php index 46f4086e0c..606e18be21 100644 --- a/src/world/format/io/WorldData.php +++ b/src/world/format/io/WorldData.php @@ -39,11 +39,7 @@ interface WorldData{ */ public function getGenerator() : string; - /** - * @return mixed[] - * @phpstan-return array - */ - public function getGeneratorOptions() : array; + public function getGeneratorOptions() : string; public function getSeed() : int; diff --git a/src/world/format/io/data/BaseNbtWorldData.php b/src/world/format/io/data/BaseNbtWorldData.php index c7de29477f..43016af0a2 100644 --- a/src/world/format/io/data/BaseNbtWorldData.php +++ b/src/world/format/io/data/BaseNbtWorldData.php @@ -116,8 +116,8 @@ abstract class BaseNbtWorldData implements WorldData{ return $this->compoundTag->getString("generatorName", "DEFAULT"); } - public function getGeneratorOptions() : array{ - return ["preset" => $this->compoundTag->getString("generatorOptions", "")]; + public function getGeneratorOptions() : string{ + return $this->compoundTag->getString("generatorOptions", ""); } public function getSeed() : int{ diff --git a/src/world/generator/Flat.php b/src/world/generator/Flat.php index 0b3cb869ea..7706c88f21 100644 --- a/src/world/generator/Flat.php +++ b/src/world/generator/Flat.php @@ -48,25 +48,18 @@ class Flat extends Generator{ private $structure; /** @var int */ private $biome; - /** @var string */ - private $preset; /** - * @param mixed[] $options - * @phpstan-param array $options - * + * @var mixed[] + * @phpstan-var array + */ + private array $options = []; + + /** * @throws InvalidGeneratorOptionsException */ - public function __construct(int $seed, array $options = []){ - parent::__construct($seed, $options); - - if(isset($this->options["preset"]) and $this->options["preset"] != ""){ - $this->preset = $this->options["preset"]; - }else{ - $this->preset = "2;bedrock,2xdirt,grass;1;"; - //$this->preset = "2;bedrock,59xstone,3xdirt,grass;1;spawn(radius=10 block=89),decoration(treecount=80 grasscount=45)"; - } - + public function __construct(int $seed, string $preset){ + parent::__construct($seed, $preset !== "" ? $preset : "2;bedrock,2xdirt,grass;1;"); $this->parsePreset(); if(isset($this->options["decoration"])){ diff --git a/src/world/generator/Generator.php b/src/world/generator/Generator.php index fa78f6abeb..acc8cc88fc 100644 --- a/src/world/generator/Generator.php +++ b/src/world/generator/Generator.php @@ -50,22 +50,15 @@ abstract class Generator{ /** @var int */ protected $seed; - /** - * @var mixed[] - * @phpstan-var array - */ - protected $options; + + protected string $preset; /** @var Random */ protected $random; - /** - * @param mixed[] $options - * @phpstan-param array $options - */ - public function __construct(int $seed, array $options = []){ + public function __construct(int $seed, string $preset){ $this->seed = $seed; - $this->options = $options; + $this->preset = $preset; $this->random = new Random($seed); } diff --git a/src/world/generator/GeneratorRegisterTask.php b/src/world/generator/GeneratorRegisterTask.php index 5189adf547..b8b2ea67d0 100644 --- a/src/world/generator/GeneratorRegisterTask.php +++ b/src/world/generator/GeneratorRegisterTask.php @@ -25,8 +25,6 @@ namespace pocketmine\world\generator; use pocketmine\scheduler\AsyncTask; use pocketmine\world\World; -use function igbinary_serialize; -use function igbinary_unserialize; class GeneratorRegisterTask extends AsyncTask{ @@ -47,13 +45,11 @@ class GeneratorRegisterTask extends AsyncTask{ public $worldMaxY; /** - * @param mixed[] $generatorSettings * @phpstan-param class-string $generatorClass - * @phpstan-param array $generatorSettings */ - public function __construct(World $world, string $generatorClass, array $generatorSettings = []){ + public function __construct(World $world, string $generatorClass, string $generatorSettings){ $this->generatorClass = $generatorClass; - $this->settings = igbinary_serialize($generatorSettings); + $this->settings = $generatorSettings; $this->seed = $world->getSeed(); $this->worldId = $world->getId(); $this->worldMinY = $world->getMinY(); @@ -65,7 +61,7 @@ class GeneratorRegisterTask extends AsyncTask{ * @var Generator $generator * @see Generator::__construct() */ - $generator = new $this->generatorClass($this->seed, igbinary_unserialize($this->settings)); + $generator = new $this->generatorClass($this->seed, $this->settings); ThreadLocalGeneratorContext::register(new ThreadLocalGeneratorContext($generator, $this->worldMinY, $this->worldMaxY), $this->worldId); } } diff --git a/src/world/generator/hell/Nether.php b/src/world/generator/hell/Nether.php index b4b5c5837a..3038f4ffbc 100644 --- a/src/world/generator/hell/Nether.php +++ b/src/world/generator/hell/Nether.php @@ -54,13 +54,10 @@ class Nether extends Generator{ private $noiseBase; /** - * @param mixed[] $options - * @phpstan-param array $options - * * @throws InvalidGeneratorOptionsException */ - public function __construct(int $seed, array $options = []){ - parent::__construct($seed, $options); + public function __construct(int $seed, string $preset){ + parent::__construct($seed, $preset); $this->noiseBase = new Simplex($this->random, 4, 1 / 4, 1 / 64); $this->random->setSeed($this->seed); diff --git a/src/world/generator/normal/Normal.php b/src/world/generator/normal/Normal.php index ceec94cc74..5c3db1729e 100644 --- a/src/world/generator/normal/Normal.php +++ b/src/world/generator/normal/Normal.php @@ -58,13 +58,10 @@ class Normal extends Generator{ private $gaussian; /** - * @param mixed[] $options - * @phpstan-param array $options - * * @throws InvalidGeneratorOptionsException */ - public function __construct(int $seed, array $options = []){ - parent::__construct($seed, $options); + public function __construct(int $seed, string $preset){ + parent::__construct($seed, $preset); $this->gaussian = new Gaussian(2); From 9c1b2744993c2eb442307a8c3fdafdd43d351a81 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 13 Apr 2021 21:03:25 +0100 Subject: [PATCH 2360/3224] WorldManager::createWorld() now accepts WorldCreationOptions instead of mixed[] --- src/Server.php | 39 +++++--- src/world/WorldCreationOptions.php | 98 +++++++++++++++++++ src/world/WorldManager.php | 18 +--- src/world/format/io/FormatConverter.php | 9 +- src/world/format/io/WritableWorldProvider.php | 8 +- src/world/format/io/data/BedrockWorldData.php | 29 +++--- src/world/format/io/data/JavaWorldData.php | 29 +++--- src/world/format/io/leveldb/LevelDB.php | 8 +- .../format/io/region/RegionWorldProvider.php | 2 +- 9 files changed, 165 insertions(+), 75 deletions(-) create mode 100644 src/world/WorldCreationOptions.php diff --git a/src/Server.php b/src/Server.php index c4c6c4be31..b38111dd63 100644 --- a/src/Server.php +++ b/src/Server.php @@ -100,8 +100,8 @@ use pocketmine\world\format\io\WorldProviderManager; use pocketmine\world\format\io\WritableWorldProvider; use pocketmine\world\generator\Generator; use pocketmine\world\generator\GeneratorManager; -use pocketmine\world\generator\normal\Normal; use pocketmine\world\World; +use pocketmine\world\WorldCreationOptions; use pocketmine\world\WorldManager; use Ramsey\Uuid\UuidInterface; use function array_shift; @@ -1031,17 +1031,30 @@ class Server{ continue; } if(!$this->worldManager->loadWorld($name, true)){ + $creationOptions = WorldCreationOptions::create(); + //TODO: error checking + if(isset($options["generator"])){ $generatorOptions = explode(":", $options["generator"]); - $generator = GeneratorManager::getInstance()->getGenerator(array_shift($generatorOptions)); + $creationOptions->setGeneratorClass(GeneratorManager::getInstance()->getGenerator(array_shift($generatorOptions))); if(count($generatorOptions) > 0){ - $options["preset"] = implode(":", $generatorOptions); + $creationOptions->setGeneratorOptions(implode(":", $generatorOptions)); + } + } + if(isset($options["difficulty"]) && is_string($options["difficulty"])){ + $creationOptions->setDifficulty(World::getDifficultyFromString($options["difficulty"])); + } + if(isset($options["preset"]) && is_string($options["preset"])){ + $creationOptions->setGeneratorOptions($options["preset"]); + } + if(isset($options["seed"])){ + $convertedSeed = Generator::convertSeed((string) ($options["seed"] ?? "")); + if($convertedSeed !== null){ + $creationOptions->setSeed($convertedSeed); } - }else{ - $generator = Normal::class; } - $this->worldManager->generateWorld($name, Generator::convertSeed((string) ($options["seed"] ?? "")), $generator, $options); + $this->worldManager->generateWorld($name, $creationOptions); } } @@ -1053,12 +1066,14 @@ class Server{ $this->configGroup->setConfigString("level-name", "world"); } if(!$this->worldManager->loadWorld($default, true)){ - $this->worldManager->generateWorld( - $default, - Generator::convertSeed($this->configGroup->getConfigString("level-seed")), - GeneratorManager::getInstance()->getGenerator($this->configGroup->getConfigString("level-type")), - ["preset" => $this->configGroup->getConfigString("generator-settings")] - ); + $creationOptions = WorldCreationOptions::create() + ->setGeneratorClass(GeneratorManager::getInstance()->getGenerator($this->configGroup->getConfigString("level-type"))) + ->setGeneratorOptions($this->configGroup->getConfigString("generator-settings")); + $convertedSeed = Generator::convertSeed($this->configGroup->getConfigString("level-seed")); + if($convertedSeed !== null){ + $creationOptions->setSeed($convertedSeed); + } + $this->worldManager->generateWorld($default, $creationOptions); } $world = $this->worldManager->getWorldByName($default); diff --git a/src/world/WorldCreationOptions.php b/src/world/WorldCreationOptions.php new file mode 100644 index 0000000000..87304dd5ef --- /dev/null +++ b/src/world/WorldCreationOptions.php @@ -0,0 +1,98 @@ + */ + private string $generatorClass = Normal::class; + private int $seed; + private int $difficulty = World::DIFFICULTY_NORMAL; + private string $generatorOptions = ""; + private Vector3 $spawnPosition; + + public function __construct(){ + $this->seed = random_int(Limits::INT32_MIN, Limits::INT32_MAX); + $this->spawnPosition = new Vector3(256, 70, 256); + } + + public static function create() : self{ + return new self; + } + + /** @phpstan-return class-string */ + public function getGeneratorClass() : string{ return $this->generatorClass; } + + /** + * @phpstan-param class-string $generatorClass + * @return $this + */ + public function setGeneratorClass(string $generatorClass) : self{ + Utils::testValidInstance($generatorClass, Generator::class); + $this->generatorClass = $generatorClass; + return $this; + } + + public function getSeed() : int{ return $this->seed; } + + /** @return $this */ + public function setSeed(int $seed) : self{ + $this->seed = $seed; + return $this; + } + + public function getDifficulty() : int{ return $this->difficulty; } + + /** @return $this */ + public function setDifficulty(int $difficulty) : self{ + $this->difficulty = $difficulty; + return $this; + } + + public function getGeneratorOptions() : string{ return $this->generatorOptions; } + + /** @return $this */ + public function setGeneratorOptions(string $generatorOptions) : self{ + $this->generatorOptions = $generatorOptions; + return $this; + } + + public function getSpawnPosition() : Vector3{ return $this->spawnPosition; } + + /** @return $this */ + public function setSpawnPosition(Vector3 $spawnPosition) : self{ + $this->spawnPosition = $spawnPosition; + return $this; + } +} diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 86fb3f6ba6..fa3f3c94ce 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -30,24 +30,19 @@ use pocketmine\event\world\WorldUnloadEvent; use pocketmine\player\ChunkSelector; use pocketmine\Server; use pocketmine\timings\Timings; -use pocketmine\utils\Limits; -use pocketmine\utils\Utils; use pocketmine\world\format\io\exception\CorruptedWorldException; use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; use pocketmine\world\format\io\FormatConverter; use pocketmine\world\format\io\WorldProvider; use pocketmine\world\format\io\WorldProviderManager; use pocketmine\world\format\io\WritableWorldProvider; -use pocketmine\world\generator\Generator; use pocketmine\world\generator\GeneratorManager; -use pocketmine\world\generator\normal\Normal; use function array_keys; use function array_shift; use function assert; use function count; use function implode; use function microtime; -use function random_int; use function round; use function sprintf; use function trim; @@ -244,27 +239,18 @@ class WorldManager{ /** * Generates a new world if it does not exist * - * @param string $generator Class name that extends pocketmine\world\generator\Generator - * @param mixed[] $options - * @phpstan-param class-string $generator - * @phpstan-param array $options - * * @throws \InvalidArgumentException */ - public function generateWorld(string $name, ?int $seed = null, string $generator = Normal::class, array $options = [], bool $backgroundGeneration = true) : bool{ + public function generateWorld(string $name, ?WorldCreationOptions $options = null, bool $backgroundGeneration = true) : bool{ if(trim($name) === "" or $this->isWorldGenerated($name)){ return false; } - $seed = $seed ?? random_int(Limits::INT32_MIN, Limits::INT32_MAX); - - Utils::testValidInstance($generator, Generator::class); - $providerClass = $this->providerManager->getDefault(); $path = $this->getWorldPath($name); /** @var WritableWorldProvider $providerClass */ - $providerClass::generate($path, $name, $seed, $generator, $options); + $providerClass::generate($path, $name, $options); /** @see WritableWorldProvider::__construct() */ $world = new World($this->server, $name, new $providerClass($path), $this->server->getAsyncPool()); diff --git a/src/world/format/io/FormatConverter.php b/src/world/format/io/FormatConverter.php index a2ddf9fd25..4d5f3eba31 100644 --- a/src/world/format/io/FormatConverter.php +++ b/src/world/format/io/FormatConverter.php @@ -26,6 +26,7 @@ namespace pocketmine\world\format\io; use pocketmine\utils\Filesystem; use pocketmine\utils\Utils; use pocketmine\world\generator\GeneratorManager; +use pocketmine\world\WorldCreationOptions; use function basename; use function crc32; use function file_exists; @@ -105,7 +106,13 @@ class FormatConverter{ $this->logger->info("Found previous conversion attempt, deleting..."); Filesystem::recursiveUnlink($convertedOutput); } - $this->newProvider::generate($convertedOutput, $data->getName(), $data->getSeed(), GeneratorManager::getInstance()->getGenerator($data->getGenerator()), ["preset" => $data->getGeneratorOptions()]); + $this->newProvider::generate($convertedOutput, $data->getName(), WorldCreationOptions::create() + ->setGeneratorClass(GeneratorManager::getInstance()->getGenerator($data->getGenerator())) + ->setGeneratorOptions($data->getGeneratorOptions()) + ->setSeed($data->getSeed()) + ->setSpawnPosition($data->getSpawn()) + ->setDifficulty($data->getDifficulty()) + ); /** * @see WritableWorldProvider::__construct() diff --git a/src/world/format/io/WritableWorldProvider.php b/src/world/format/io/WritableWorldProvider.php index 58ceef4426..de3a69b739 100644 --- a/src/world/format/io/WritableWorldProvider.php +++ b/src/world/format/io/WritableWorldProvider.php @@ -24,17 +24,13 @@ declare(strict_types=1); namespace pocketmine\world\format\io; use pocketmine\world\format\Chunk; -use pocketmine\world\generator\Generator; +use pocketmine\world\WorldCreationOptions; interface WritableWorldProvider extends WorldProvider{ /** * Generate the needed files in the path given - * - * @param mixed[] $options - * @phpstan-param class-string $generator - * @phpstan-param array $options */ - public static function generate(string $path, string $name, int $seed, string $generator, array $options = []) : void; + public static function generate(string $path, string $name, ?WorldCreationOptions $options = null) : void; /** * Saves a chunk (usually to disk). diff --git a/src/world/format/io/data/BedrockWorldData.php b/src/world/format/io/data/BedrockWorldData.php index 6ae3103081..73a6a5be94 100644 --- a/src/world/format/io/data/BedrockWorldData.php +++ b/src/world/format/io/data/BedrockWorldData.php @@ -32,13 +32,13 @@ use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\utils\Binary; use pocketmine\utils\Limits; -use pocketmine\utils\Utils; use pocketmine\world\format\io\exception\CorruptedWorldException; use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; use pocketmine\world\generator\Flat; use pocketmine\world\generator\Generator; use pocketmine\world\generator\GeneratorManager; use pocketmine\world\World; +use pocketmine\world\WorldCreationOptions; use function file_get_contents; use function file_put_contents; use function strlen; @@ -53,14 +53,9 @@ class BedrockWorldData extends BaseNbtWorldData{ public const GENERATOR_INFINITE = 1; public const GENERATOR_FLAT = 2; - /** - * @param mixed[] $options - * @phpstan-param class-string $generator - * @phpstan-param array $options - */ - public static function generate(string $path, string $name, int $seed, string $generator, array $options = []) : void{ - Utils::testValidInstance($generator, Generator::class); - switch($generator){ + public static function generate(string $path, string $name, ?WorldCreationOptions $options = null) : void{ + $options ??= WorldCreationOptions::create(); + switch($options->getGeneratorClass()){ case Flat::class: $generatorType = self::GENERATOR_FLAT; break; @@ -72,7 +67,7 @@ class BedrockWorldData extends BaseNbtWorldData{ $worldData = CompoundTag::create() //Vanilla fields ->setInt("DayCycleStopTime", -1) - ->setInt("Difficulty", World::getDifficultyFromString((string) ($options["difficulty"] ?? "normal"))) + ->setInt("Difficulty", $options->getDifficulty()) ->setByte("ForceGameType", 0) ->setInt("GameType", 0) ->setInt("Generator", $generatorType) @@ -80,10 +75,10 @@ class BedrockWorldData extends BaseNbtWorldData{ ->setString("LevelName", $name) ->setInt("NetworkVersion", ProtocolInfo::CURRENT_PROTOCOL) //->setInt("Platform", 2) //TODO: find out what the possible values are for - ->setLong("RandomSeed", $seed) - ->setInt("SpawnX", 0) - ->setInt("SpawnY", 32767) - ->setInt("SpawnZ", 0) + ->setLong("RandomSeed", $options->getSeed()) + ->setInt("SpawnX", $options->getSpawnPosition()->getFloorX()) + ->setInt("SpawnY", $options->getSpawnPosition()->getFloorY()) + ->setInt("SpawnZ", $options->getSpawnPosition()->getFloorZ()) ->setInt("StorageVersion", self::CURRENT_STORAGE_VERSION) ->setLong("Time", 0) ->setByte("eduLevel", 0) @@ -101,9 +96,9 @@ class BedrockWorldData extends BaseNbtWorldData{ //Additional PocketMine-MP fields ->setTag("GameRules", new CompoundTag()) - ->setByte("hardcore", ($options["hardcore"] ?? false) === true ? 1 : 0) - ->setString("generatorName", GeneratorManager::getInstance()->getGeneratorName($generator)) - ->setString("generatorOptions", $options["preset"] ?? ""); + ->setByte("hardcore", 0) + ->setString("generatorName", GeneratorManager::getInstance()->getGeneratorName($options->getGeneratorClass())) + ->setString("generatorOptions", $options->getGeneratorOptions()); $nbt = new LittleEndianNbtSerializer(); $buffer = $nbt->write(new TreeRoot($worldData)); diff --git a/src/world/format/io/data/JavaWorldData.php b/src/world/format/io/data/JavaWorldData.php index 197b62fa9c..301dce6a56 100644 --- a/src/world/format/io/data/JavaWorldData.php +++ b/src/world/format/io/data/JavaWorldData.php @@ -29,11 +29,10 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\TreeRoot; -use pocketmine\utils\Utils; use pocketmine\world\format\io\exception\CorruptedWorldException; -use pocketmine\world\generator\Generator; use pocketmine\world\generator\GeneratorManager; use pocketmine\world\World; +use pocketmine\world\WorldCreationOptions; use function ceil; use function file_get_contents; use function file_put_contents; @@ -44,31 +43,27 @@ use const ZLIB_ENCODING_GZIP; class JavaWorldData extends BaseNbtWorldData{ - /** - * @param mixed[] $options - * @phpstan-param class-string $generator - * @phpstan-param array $options - */ - public static function generate(string $path, string $name, int $seed, string $generator, array $options = [], int $version = 19133) : void{ - Utils::testValidInstance($generator, Generator::class); + public static function generate(string $path, string $name, ?WorldCreationOptions $options = null, int $version = 19133) : void{ //TODO, add extra details + + $options ??= WorldCreationOptions::create(); $worldData = CompoundTag::create() - ->setByte("hardcore", ($options["hardcore"] ?? false) === true ? 1 : 0) - ->setByte("Difficulty", World::getDifficultyFromString((string) ($options["difficulty"] ?? "normal"))) + ->setByte("hardcore", 0) + ->setByte("Difficulty", $options->getDifficulty()) ->setByte("initialized", 1) ->setInt("GameType", 0) ->setInt("generatorVersion", 1) //2 in MCPE - ->setInt("SpawnX", 256) - ->setInt("SpawnY", 70) - ->setInt("SpawnZ", 256) + ->setInt("SpawnX", $options->getSpawnPosition()->getFloorX()) + ->setInt("SpawnY", $options->getSpawnPosition()->getFloorY()) + ->setInt("SpawnZ", $options->getSpawnPosition()->getFloorZ()) ->setInt("version", $version) ->setInt("DayTime", 0) ->setLong("LastPlayed", (int) (microtime(true) * 1000)) - ->setLong("RandomSeed", $seed) + ->setLong("RandomSeed", $options->getSeed()) ->setLong("SizeOnDisk", 0) ->setLong("Time", 0) - ->setString("generatorName", GeneratorManager::getInstance()->getGeneratorName($generator)) - ->setString("generatorOptions", $options["preset"] ?? "") + ->setString("generatorName", GeneratorManager::getInstance()->getGeneratorName($options->getGeneratorClass())) + ->setString("generatorOptions", $options->getGeneratorOptions()) ->setString("LevelName", $name) ->setTag("GameRules", new CompoundTag()); diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index a84391543c..d7837a7d27 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -32,7 +32,6 @@ use pocketmine\nbt\TreeRoot; use pocketmine\utils\Binary; use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; -use pocketmine\utils\Utils; use pocketmine\world\format\BiomeArray; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\BaseWorldProvider; @@ -46,7 +45,7 @@ use pocketmine\world\format\io\WorldData; use pocketmine\world\format\io\WritableWorldProvider; use pocketmine\world\format\PalettedBlockArray; use pocketmine\world\format\SubChunk; -use pocketmine\world\generator\Generator; +use pocketmine\world\WorldCreationOptions; use function array_map; use function array_values; use function chr; @@ -144,15 +143,14 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ return file_exists($path . "/level.dat") and is_dir($path . "/db/"); } - public static function generate(string $path, string $name, int $seed, string $generator, array $options = []) : void{ - Utils::testValidInstance($generator, Generator::class); + public static function generate(string $path, string $name, ?WorldCreationOptions $options = null) : void{ self::checkForLevelDBExtension(); if(!file_exists($path . "/db")){ mkdir($path . "/db", 0777, true); } - BedrockWorldData::generate($path, $name, $seed, $generator, $options); + BedrockWorldData::generate($path, $name, $options); } protected function deserializePaletted(BinaryStream $stream) : PalettedBlockArray{ diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index ebb0f8088e..c15d3139fb 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -90,7 +90,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ mkdir($path . "/region", 0777); } - JavaWorldData::generate($path, $name, $seed, $generator, $options, static::getPcWorldFormatVersion()); + JavaWorldData::generate($path, $name, null, static::getPcWorldFormatVersion()); } /** @var RegionLoader[] */ From ab176264b45364760817f8e00050987a0b5d8139 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 13 Apr 2021 21:06:37 +0100 Subject: [PATCH 2361/3224] ... --- src/world/format/io/region/RegionWorldProvider.php | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index c15d3139fb..ccb3ab4b35 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -27,13 +27,13 @@ use pocketmine\nbt\NBT; use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; -use pocketmine\utils\Utils; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\BaseWorldProvider; use pocketmine\world\format\io\data\JavaWorldData; use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\WorldData; use pocketmine\world\generator\Generator; +use pocketmine\world\WorldCreationOptions; use function assert; use function file_exists; use function is_dir; @@ -75,13 +75,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ return false; } - /** - * @param mixed[] $options - * @phpstan-param class-string $generator - * @phpstan-param array $options - */ - public static function generate(string $path, string $name, int $seed, string $generator, array $options = []) : void{ - Utils::testValidInstance($generator, Generator::class); + public static function generate(string $path, string $name, ?WorldCreationOptions $options = null) : void{ if(!file_exists($path)){ mkdir($path, 0777, true); } @@ -90,7 +84,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ mkdir($path . "/region", 0777); } - JavaWorldData::generate($path, $name, null, static::getPcWorldFormatVersion()); + JavaWorldData::generate($path, $name, $options, static::getPcWorldFormatVersion()); } /** @var RegionLoader[] */ From c90ca37ea3fcb7542ec217e1bb7f0433deb6188b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 13 Apr 2021 21:10:18 +0100 Subject: [PATCH 2362/3224] Fix CS --- src/world/format/io/region/RegionWorldProvider.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index ccb3ab4b35..8212361da5 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -32,7 +32,6 @@ use pocketmine\world\format\io\BaseWorldProvider; use pocketmine\world\format\io\data\JavaWorldData; use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\WorldData; -use pocketmine\world\generator\Generator; use pocketmine\world\WorldCreationOptions; use function assert; use function file_exists; From 0f3147f49bddc0909f71a35c89ebe01ca3698d98 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 13 Apr 2021 21:28:17 +0100 Subject: [PATCH 2363/3224] WorldManager: Log progress of spawn terrain generation --- src/world/WorldManager.php | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index fa3f3c94ce..ce10401f94 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -41,7 +41,10 @@ use function array_keys; use function array_shift; use function assert; use function count; +use function floor; use function implode; +use function intdiv; +use function iterator_to_array; use function microtime; use function round; use function sprintf; @@ -269,9 +272,22 @@ class WorldManager{ $centerX = $spawnLocation->getFloorX() >> 4; $centerZ = $spawnLocation->getFloorZ() >> 4; - foreach((new ChunkSelector())->selectChunks(3, $centerX, $centerZ) as $index){ + $selected = iterator_to_array((new ChunkSelector())->selectChunks(3, $centerX, $centerZ)); + $done = 0; + $total = count($selected); + foreach($selected as $index){ World::getXZ($index, $chunkX, $chunkZ); - $world->orderChunkPopulation($chunkX, $chunkZ, null); + $world->orderChunkPopulation($chunkX, $chunkZ, null)->onCompletion( + static function() use ($world, &$done, $total) : void{ + $oldProgress = (int) floor(($done / $total) * 100); + $newProgress = (int) floor((++$done / $total) * 100); + if(intdiv($oldProgress, 10) !== intdiv($newProgress, 10) || $done === $total){ + $world->getLogger()->info("Generating spawn terrain chunks: $done / $total ($newProgress%)"); + } + }, + static function() : void{ + //NOOP: we don't care if the world was unloaded + }); } } From ecf6de3430a4556f8df46faac21a0bfc3ca2f8a4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 13 Apr 2021 22:15:47 +0100 Subject: [PATCH 2364/3224] WorldManager: Pre-generate a radius of 8 chunks 3 is absurdly small. 8 is a more realistic estimation of what the average player's render distance will be (it's also the default server.properties limit). 3 doesn't even fill the default spawn-radius setting, meaning that delays during player connection would occur anyway due to generation. --- src/world/WorldManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index ce10401f94..4036a1655f 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -272,7 +272,7 @@ class WorldManager{ $centerX = $spawnLocation->getFloorX() >> 4; $centerZ = $spawnLocation->getFloorZ() >> 4; - $selected = iterator_to_array((new ChunkSelector())->selectChunks(3, $centerX, $centerZ)); + $selected = iterator_to_array((new ChunkSelector())->selectChunks(8, $centerX, $centerZ)); $done = 0; $total = count($selected); foreach($selected as $index){ From 203cc7fcef573d81d02d84365d3e013ec35bc68d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 13 Apr 2021 22:32:00 +0100 Subject: [PATCH 2365/3224] World: Removed noisy debug message --- src/world/World.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index f591436fc5..b0798a18af 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2040,7 +2040,6 @@ class World implements ChunkManager{ World::getXZ($nextChunkHash, $nextChunkX, $nextChunkZ); if(isset($this->chunkPopulationRequestMap[$nextChunkHash])){ assert(!isset($this->activeChunkPopulationTasks[$nextChunkHash]), "Population for chunk $nextChunkX $nextChunkZ already running"); - $this->logger->debug("Fulfilling population request for chunk $nextChunkX $nextChunkZ"); $this->orderChunkPopulation($nextChunkX, $nextChunkZ, null); if(!isset($this->activeChunkPopulationTasks[$nextChunkHash])){ $failed[] = $nextChunkHash; From 7b21fc8e9d17eac2cb2b0c41375acaa2020811a5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 13:54:58 +0100 Subject: [PATCH 2366/3224] WorldCreationOptions are now mandatory during creation of worlds --- src/world/WorldManager.php | 2 +- src/world/format/io/WritableWorldProvider.php | 2 +- src/world/format/io/data/BedrockWorldData.php | 3 +-- src/world/format/io/data/JavaWorldData.php | 3 +-- src/world/format/io/leveldb/LevelDB.php | 2 +- src/world/format/io/region/RegionWorldProvider.php | 2 +- 6 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 4036a1655f..2e8ffe5ee8 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -244,7 +244,7 @@ class WorldManager{ * * @throws \InvalidArgumentException */ - public function generateWorld(string $name, ?WorldCreationOptions $options = null, bool $backgroundGeneration = true) : bool{ + public function generateWorld(string $name, WorldCreationOptions $options, bool $backgroundGeneration = true) : bool{ if(trim($name) === "" or $this->isWorldGenerated($name)){ return false; } diff --git a/src/world/format/io/WritableWorldProvider.php b/src/world/format/io/WritableWorldProvider.php index de3a69b739..3f1652417c 100644 --- a/src/world/format/io/WritableWorldProvider.php +++ b/src/world/format/io/WritableWorldProvider.php @@ -30,7 +30,7 @@ interface WritableWorldProvider extends WorldProvider{ /** * Generate the needed files in the path given */ - public static function generate(string $path, string $name, ?WorldCreationOptions $options = null) : void; + public static function generate(string $path, string $name, WorldCreationOptions $options) : void; /** * Saves a chunk (usually to disk). diff --git a/src/world/format/io/data/BedrockWorldData.php b/src/world/format/io/data/BedrockWorldData.php index 73a6a5be94..e59c066d50 100644 --- a/src/world/format/io/data/BedrockWorldData.php +++ b/src/world/format/io/data/BedrockWorldData.php @@ -53,8 +53,7 @@ class BedrockWorldData extends BaseNbtWorldData{ public const GENERATOR_INFINITE = 1; public const GENERATOR_FLAT = 2; - public static function generate(string $path, string $name, ?WorldCreationOptions $options = null) : void{ - $options ??= WorldCreationOptions::create(); + public static function generate(string $path, string $name, WorldCreationOptions $options) : void{ switch($options->getGeneratorClass()){ case Flat::class: $generatorType = self::GENERATOR_FLAT; diff --git a/src/world/format/io/data/JavaWorldData.php b/src/world/format/io/data/JavaWorldData.php index 301dce6a56..3565799797 100644 --- a/src/world/format/io/data/JavaWorldData.php +++ b/src/world/format/io/data/JavaWorldData.php @@ -43,10 +43,9 @@ use const ZLIB_ENCODING_GZIP; class JavaWorldData extends BaseNbtWorldData{ - public static function generate(string $path, string $name, ?WorldCreationOptions $options = null, int $version = 19133) : void{ + public static function generate(string $path, string $name, WorldCreationOptions $options, int $version = 19133) : void{ //TODO, add extra details - $options ??= WorldCreationOptions::create(); $worldData = CompoundTag::create() ->setByte("hardcore", 0) ->setByte("Difficulty", $options->getDifficulty()) diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index d7837a7d27..56011bee15 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -143,7 +143,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ return file_exists($path . "/level.dat") and is_dir($path . "/db/"); } - public static function generate(string $path, string $name, ?WorldCreationOptions $options = null) : void{ + public static function generate(string $path, string $name, WorldCreationOptions $options) : void{ self::checkForLevelDBExtension(); if(!file_exists($path . "/db")){ diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index 8212361da5..c02f37739b 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -74,7 +74,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ return false; } - public static function generate(string $path, string $name, ?WorldCreationOptions $options = null) : void{ + public static function generate(string $path, string $name, WorldCreationOptions $options) : void{ if(!file_exists($path)){ mkdir($path, 0777, true); } From 3e1ff2a63b0a2c2a740ed14e7e9cbb12a799308a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 13:57:20 +0100 Subject: [PATCH 2367/3224] [ci skip] mention WorldCreationOptions changes in changelog --- changelogs/4.0-snapshot.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index be89cc1401..7df1adca00 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -877,6 +877,7 @@ This version features substantial changes to the network system, improving coher - `Chunk->__construct()` now has the signature `array $subChunks, ?list $entities, ?list $tiles, ?BiomeArray $biomeArray, ?HeightArray $heightArray`. - `Chunk->getSubChunk()` now returns `SubChunk` instead of `SubChunkInterface|null` (and throws `InvalidArgumentException` on out-of-bounds coordinates). - `Chunk->setSubChunk()` no longer accepts `SubChunkInterface`, and the `$allowEmpty` parameter has been removed. + - `WorldManager->generateWorld()` (previously `Server->generateWorld()`) now accepts `WorldCreationOptions` instead of `int $seed, class-string $generator, mixed[] $options`. - The following API methods have been renamed / moved: - `Level->getCollisionCubes()` -> `World->getCollisionBoxes()` - `World->getName()` -> `World->getDisplayName()` From 506a235d7a9631a6e02a5439ab91853399a057cb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 14:00:45 +0100 Subject: [PATCH 2368/3224] [ci skip] changelog: remove mention of ext-ds --- changelogs/4.0-snapshot.md | 1 - 1 file changed, 1 deletion(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 7df1adca00..f1c97558c5 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -16,7 +16,6 @@ This major version features substantial changes throughout the core, including s - GS4 Query no longer breaks when disabling RakLib. - The `pocketmine_chunkutils` PHP extension has been dropped. - New PHP extensions are required by this version: - - [ds](https://github.com/php-ds/ext-ds) - [chunkutils2](https://github.com/pmmp/ext-chunkutils2) - [morton](https://github.com/pmmp/ext-morton) From 8af6b112d2446afbf4f79cffcda857402257c640 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 14:01:28 +0100 Subject: [PATCH 2369/3224] WorldManager: log after first chunk's generation has been completed this is as close as we can get to the actual start of generation. --- src/world/WorldManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 2e8ffe5ee8..b34a3621cb 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -281,7 +281,7 @@ class WorldManager{ static function() use ($world, &$done, $total) : void{ $oldProgress = (int) floor(($done / $total) * 100); $newProgress = (int) floor((++$done / $total) * 100); - if(intdiv($oldProgress, 10) !== intdiv($newProgress, 10) || $done === $total){ + if(intdiv($oldProgress, 10) !== intdiv($newProgress, 10) || $done === $total || $done === 1){ $world->getLogger()->info("Generating spawn terrain chunks: $done / $total ($newProgress%)"); } }, From be190fc41b324144fd1e8570b7181f6206331128 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 15:01:01 +0100 Subject: [PATCH 2370/3224] gitignore: add backups --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c4d362e124..56671bfe28 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ players/* worlds/* world_conversion_backups/* +backups/* plugin_data/* plugins/* bin*/* From e6fb6b1f27048bd5e722c4cdbab01d83c0bf9fab Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 15:15:16 +0100 Subject: [PATCH 2371/3224] BaseLevelProvider: Remove obsolete proxy methods --- src/world/format/io/BaseWorldProvider.php | 20 ------------------- src/world/format/io/leveldb/LevelDB.php | 4 ++-- .../format/io/region/RegionWorldProvider.php | 4 ++-- 3 files changed, 4 insertions(+), 24 deletions(-) diff --git a/src/world/format/io/BaseWorldProvider.php b/src/world/format/io/BaseWorldProvider.php index 4726402830..6404f641b8 100644 --- a/src/world/format/io/BaseWorldProvider.php +++ b/src/world/format/io/BaseWorldProvider.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\world\format\io; -use pocketmine\world\format\Chunk; -use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\exception\CorruptedWorldException; use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; use pocketmine\world\WorldException; @@ -58,22 +56,4 @@ abstract class BaseWorldProvider implements WorldProvider{ public function getWorldData() : WorldData{ return $this->worldData; } - - /** - * @throws CorruptedChunkException - */ - public function loadChunk(int $chunkX, int $chunkZ) : ?Chunk{ - return $this->readChunk($chunkX, $chunkZ); - } - - public function saveChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ - $this->writeChunk($chunkX, $chunkZ, $chunk); - } - - /** - * @throws CorruptedChunkException - */ - abstract protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk; - - abstract protected function writeChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void; } diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 56011bee15..1adf76db94 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -230,7 +230,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ /** * @throws CorruptedChunkException */ - protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk{ + public function loadChunk(int $chunkX, int $chunkZ) : ?Chunk{ $index = LevelDB::chunkIndex($chunkX, $chunkZ); $chunkVersionRaw = $this->db->get($index . self::TAG_VERSION); @@ -418,7 +418,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ return $chunk; } - protected function writeChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ + public function saveChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ $idMap = LegacyBlockIdToStringIdMap::getInstance(); $index = LevelDB::chunkIndex($chunkX, $chunkZ); diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index c02f37739b..a54fce73ef 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -207,7 +207,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ /** * @throws CorruptedChunkException */ - protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk{ + public function loadChunk(int $chunkX, int $chunkZ) : ?Chunk{ $regionX = $regionZ = null; self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ); assert(is_int($regionX) and is_int($regionZ)); @@ -224,7 +224,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ return null; } - protected function writeChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ + public function saveChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ); $this->loadRegion($regionX, $regionZ)->writeChunk($chunkX & 0x1f, $chunkZ & 0x1f, $this->serializeChunk($chunk)); } From 08f0c9a244d6c7904dfd08248f0f658f3752b181 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 15:20:57 +0100 Subject: [PATCH 2372/3224] Separate writable parts of RegionWorldProvider into WritableRegionWorldProvider --- src/world/format/io/region/Anvil.php | 4 -- .../io/region/LegacyAnvilChunkTrait.php | 5 -- src/world/format/io/region/McRegion.php | 8 --- .../format/io/region/RegionWorldProvider.php | 7 --- .../io/region/WritableRegionWorldProvider.php | 58 +++++++++++++++++++ 5 files changed, 58 insertions(+), 24 deletions(-) create mode 100644 src/world/format/io/region/WritableRegionWorldProvider.php diff --git a/src/world/format/io/region/Anvil.php b/src/world/format/io/region/Anvil.php index dc2c039d4c..36fdcfda23 100644 --- a/src/world/format/io/region/Anvil.php +++ b/src/world/format/io/region/Anvil.php @@ -31,10 +31,6 @@ use pocketmine\world\format\SubChunk; class Anvil extends RegionWorldProvider{ use LegacyAnvilChunkTrait; - protected function serializeSubChunk(SubChunk $subChunk) : CompoundTag{ - throw new \RuntimeException("Unsupported"); - } - protected function deserializeSubChunk(CompoundTag $subChunk) : SubChunk{ return new SubChunk(BlockLegacyIds::AIR << 4, [SubChunkConverter::convertSubChunkYZX( self::readFixedSizeByteArray($subChunk, "Blocks", 4096), diff --git a/src/world/format/io/region/LegacyAnvilChunkTrait.php b/src/world/format/io/region/LegacyAnvilChunkTrait.php index c61914e397..c507c86387 100644 --- a/src/world/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/world/format/io/region/LegacyAnvilChunkTrait.php @@ -46,11 +46,6 @@ use function zlib_decode; * @internal */ trait LegacyAnvilChunkTrait{ - - protected function serializeChunk(Chunk $chunk) : string{ - throw new \RuntimeException("Unsupported"); - } - /** * @throws CorruptedChunkException */ diff --git a/src/world/format/io/region/McRegion.php b/src/world/format/io/region/McRegion.php index 1a80f90b60..2b2b683849 100644 --- a/src/world/format/io/region/McRegion.php +++ b/src/world/format/io/region/McRegion.php @@ -39,14 +39,6 @@ use pocketmine\world\format\SubChunk; use function zlib_decode; class McRegion extends RegionWorldProvider{ - - /** - * @throws \RuntimeException - */ - protected function serializeChunk(Chunk $chunk) : string{ - throw new \RuntimeException("Unsupported"); - } - /** * @throws CorruptedChunkException */ diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index a54fce73ef..0ff7925a5c 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -163,8 +163,6 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ } } - abstract protected function serializeChunk(Chunk $chunk) : string; - /** * @throws CorruptedChunkException */ @@ -224,11 +222,6 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ return null; } - public function saveChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ - self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ); - $this->loadRegion($regionX, $regionZ)->writeChunk($chunkX & 0x1f, $chunkZ & 0x1f, $this->serializeChunk($chunk)); - } - private function createRegionIterator() : \RegexIterator{ return new \RegexIterator( new \FilesystemIterator( diff --git a/src/world/format/io/region/WritableRegionWorldProvider.php b/src/world/format/io/region/WritableRegionWorldProvider.php new file mode 100644 index 0000000000..156caa3e61 --- /dev/null +++ b/src/world/format/io/region/WritableRegionWorldProvider.php @@ -0,0 +1,58 @@ +loadRegion($regionX, $regionZ)->writeChunk($chunkX & 0x1f, $chunkZ & 0x1f, $this->serializeChunk($chunk)); + } +} From edb590f681e33f9573dd3e4f66ec95ee0dd1bfa8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 15:23:15 +0100 Subject: [PATCH 2373/3224] missed one ... --- src/world/format/io/region/RegionWorldProvider.php | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index 0ff7925a5c..68ed8f1f6a 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -74,18 +74,6 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ return false; } - public static function generate(string $path, string $name, WorldCreationOptions $options) : void{ - if(!file_exists($path)){ - mkdir($path, 0777, true); - } - - if(!file_exists($path . "/region")){ - mkdir($path . "/region", 0777); - } - - JavaWorldData::generate($path, $name, $options, static::getPcWorldFormatVersion()); - } - /** @var RegionLoader[] */ protected $regions = []; From 32c4a165cff752703ac90e23c63f5081a07478ae Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 15:38:18 +0100 Subject: [PATCH 2374/3224] Removed RegionLoader::open() this is nothing but a source of bugs. --- src/world/format/io/region/RegionLoader.php | 10 ++++------ src/world/format/io/region/RegionWorldProvider.php | 10 ++-------- .../world/format/io/region/RegionLoaderTest.php | 4 ---- tools/compact-regions.php | 4 +--- 4 files changed, 7 insertions(+), 21 deletions(-) diff --git a/src/world/format/io/region/RegionLoader.php b/src/world/format/io/region/RegionLoader.php index 1aa06812fd..746e057f30 100644 --- a/src/world/format/io/region/RegionLoader.php +++ b/src/world/format/io/region/RegionLoader.php @@ -80,15 +80,13 @@ class RegionLoader{ /** @var int */ public $lastUsed = 0; - public function __construct(string $filePath){ - $this->filePath = $filePath; - $this->garbageTable = new RegionGarbageMap([]); - } - /** * @throws CorruptedRegionException */ - public function open() : void{ + public function __construct(string $filePath){ + $this->filePath = $filePath; + $this->garbageTable = new RegionGarbageMap([]); + clearstatcache(false, $this->filePath); $exists = file_exists($this->filePath); if(!$exists){ diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index 68ed8f1f6a..2a16e8ae1a 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -115,24 +115,18 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ if(!isset($this->regions[$index = morton2d_encode($regionX, $regionZ)])){ $path = $this->pathToRegion($regionX, $regionZ); - $region = new RegionLoader($path); try{ - $region->open(); + $this->regions[$index] = new RegionLoader($path); }catch(CorruptedRegionException $e){ $logger = \GlobalLogger::get(); $logger->error("Corrupted region file detected: " . $e->getMessage()); - $region->close(); //Do not write anything to the file - $backupPath = $path . ".bak." . time(); rename($path, $backupPath); $logger->error("Corrupted region file has been backed up to " . $backupPath); - $region = new RegionLoader($path); - $region->open(); //this will create a new empty region to replace the corrupted one + $this->regions[$index] = new RegionLoader($path); //this will create a new empty region to replace the corrupted one } - - $this->regions[$index] = $region; } return $this->regions[$index]; } diff --git a/tests/phpunit/world/format/io/region/RegionLoaderTest.php b/tests/phpunit/world/format/io/region/RegionLoaderTest.php index f80df791e6..2b35f2f196 100644 --- a/tests/phpunit/world/format/io/region/RegionLoaderTest.php +++ b/tests/phpunit/world/format/io/region/RegionLoaderTest.php @@ -44,7 +44,6 @@ class RegionLoaderTest extends TestCase{ unlink($this->regionPath); } $this->region = new RegionLoader($this->regionPath); - $this->region->open(); } public function tearDown() : void{ @@ -65,7 +64,6 @@ class RegionLoaderTest extends TestCase{ $this->region->close(); $r = new RegionLoader($this->regionPath); - $r->open(); self::assertSame($data, $r->readChunk(0, 0)); } @@ -122,12 +120,10 @@ class RegionLoaderTest extends TestCase{ public function testRegionHeaderCachedFilesizeRegression() : void{ $this->region->close(); $region = new RegionLoader($this->regionPath); //now we have a region, so the header will be verified, triggering two filesize() calls - $region->open(); $data = str_repeat("hello", 2000); $region->writeChunk(0, 0, $data); //add some data to the end of the file, to make the cached filesize invalid $region->close(); $region = new RegionLoader($this->regionPath); - $region->open(); self::assertSame($data, $region->readChunk(0, 0)); } } diff --git a/tools/compact-regions.php b/tools/compact-regions.php index 90d3f8ee88..77089ce0dc 100644 --- a/tools/compact-regions.php +++ b/tools/compact-regions.php @@ -107,9 +107,8 @@ function main(array $argv) : int{ $doneCount = 0; $totalCount = count($files); foreach($files as $file => $size){ - $oldRegion = new RegionLoader($file); try{ - $oldRegion->open(); + $oldRegion = new RegionLoader($file); }catch(CorruptedRegionException $e){ $logger->error("Damaged region in file $file (" . $e->getMessage() . "), skipping"); $corruptedFiles[] = $file; @@ -119,7 +118,6 @@ function main(array $argv) : int{ $newFile = $file . ".compacted"; $newRegion = new RegionLoader($newFile); - $newRegion->open(); $emptyRegion = true; $corruption = false; From 8e3f5737a0b828693cc21d32c278b67d36bc05c1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 15:39:08 +0100 Subject: [PATCH 2375/3224] RegionWorldProvider: fix CS --- src/world/format/io/region/RegionWorldProvider.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index 2a16e8ae1a..67d2f362f5 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -32,12 +32,10 @@ use pocketmine\world\format\io\BaseWorldProvider; use pocketmine\world\format\io\data\JavaWorldData; use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\WorldData; -use pocketmine\world\WorldCreationOptions; use function assert; use function file_exists; use function is_dir; use function is_int; -use function mkdir; use function morton2d_encode; use function rename; use function scandir; From a0c3102b054b7837a6bdfdaa474a68c5894ed8c8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 19:14:52 +0100 Subject: [PATCH 2376/3224] FormatConverter: add @phpstan-param for newProvider ctor parameter --- src/world/format/io/FormatConverter.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/world/format/io/FormatConverter.php b/src/world/format/io/FormatConverter.php index 4d5f3eba31..b8d113082e 100644 --- a/src/world/format/io/FormatConverter.php +++ b/src/world/format/io/FormatConverter.php @@ -55,6 +55,10 @@ class FormatConverter{ /** @var int */ private $chunksPerProgressUpdate; + /** + * @phpstan-template TNewProvider of WritableWorldProvider + * @phpstan-param class-string $newProvider + */ public function __construct(WorldProvider $oldProvider, string $newProvider, string $backupPath, \Logger $logger, int $chunksPerProgressUpdate = 256){ $this->oldProvider = $oldProvider; Utils::testValidInstance($newProvider, WritableWorldProvider::class); From ec32848a97b2947784bc5fe71253c79bb42991be Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 19:27:17 +0100 Subject: [PATCH 2377/3224] [ci skip] changelog: world spawn generation progress is now logged --- changelogs/4.0-snapshot.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index f1c97558c5..50a3872b9d 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -20,6 +20,9 @@ This major version features substantial changes throughout the core, including s - [morton](https://github.com/pmmp/ext-morton) ### World handling +#### Interface +- Progress of spawn terrain chunk generation is now logged during initial world creation. + #### Functional - Modern Minecraft Bedrock world formats are now supported. - Automatic conversion of deprecated world formats is now implemented. From 99ed87bc290ea6a3631d44dd69fa784cec3670be Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 19:27:51 +0100 Subject: [PATCH 2378/3224] NetworkSession: changed misleading debug message in beginSpawnSequence() --- src/network/mcpe/NetworkSession.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index ce294fa913..92a41cf168 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -701,7 +701,7 @@ class NetworkSession{ $this->setHandler(new PreSpawnPacketHandler($this->server, $this->player, $this)); $this->player->setImmobile(); //TODO: HACK: fix client-side falling pre-spawn - $this->logger->debug("Waiting for spawn chunks"); + $this->logger->debug("Waiting for chunk radius request"); } public function notifyTerrainReady() : void{ From 9655cb819d85192c0e6f4ca9c9538dd81f56fc1d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 19:41:03 +0100 Subject: [PATCH 2379/3224] World: Remove duplicated code --- src/world/World.php | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index b0798a18af..27da4673cf 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1293,9 +1293,9 @@ class World implements ChunkManager{ } /** - * Returns the highest block light level available in the positions adjacent to the specified block coordinates. + * @phpstan-param \Closure(int $x, int $y, int $z) : int $lightGetter */ - public function getHighestAdjacentPotentialBlockSkyLight(int $x, int $y, int $z) : int{ + private function getHighestAdjacentLight(int $x, int $y, int $z, \Closure $lightGetter) : int{ $max = 0; foreach([ [$x + 1, $y, $z], @@ -1312,11 +1312,18 @@ class World implements ChunkManager{ ){ continue; } - $max = max($max, $this->getPotentialBlockSkyLightAt($x1, $y1, $z1)); + $max = max($max, $lightGetter($x1, $y1, $z1)); } return $max; } + /** + * Returns the highest block light level available in the positions adjacent to the specified block coordinates. + */ + public function getHighestAdjacentPotentialBlockSkyLight(int $x, int $y, int $z) : int{ + return $this->getHighestAdjacentLight($x, $y, $z, \Closure::fromCallable([$this, 'getPotentialBlockSkyLightAt'])); + } + /** * Returns the highest block sky light available in the positions adjacent to the given coordinates, adjusted for * the world's current time of day and weather conditions. @@ -1329,25 +1336,7 @@ class World implements ChunkManager{ * Returns the highest block light level available in the positions adjacent to the specified block coordinates. */ public function getHighestAdjacentBlockLight(int $x, int $y, int $z) : int{ - $max = 0; - foreach([ - [$x + 1, $y, $z], - [$x - 1, $y, $z], - [$x, $y + 1, $z], - [$x, $y - 1, $z], - [$x, $y, $z + 1], - [$x, $y, $z - 1] - ] as [$x1, $y1, $z1]){ - if( - !$this->isInWorld($x1, $y1, $z1) || - ($chunk = $this->getChunk($x1 >> 4, $z1 >> 4)) === null || - $chunk->isLightPopulated() !== true - ){ - continue; - } - $max = max($max, $this->getBlockLightAt($x1, $y1, $z1)); - } - return $max; + return $this->getHighestAdjacentLight($x, $y, $z, \Closure::fromCallable([$this, 'getBlockLightAt'])); } private function executeQueuedLightUpdates() : void{ From 0f14c589f7527f7ab5ef2704c3ed9d373d777489 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 20:48:54 +0100 Subject: [PATCH 2380/3224] [ci skip] changelog: added a table of contents generated using https://ecotrust-canada.github.io/markdown-toc/ --- changelogs/4.0-snapshot.md | 52 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 50a3872b9d..5de84af61d 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -2,6 +2,58 @@ This major version features substantial changes throughout the core, including significant API changes, new world format support, performance improvements and a network revamp. +## Contents +* [Core](#core) + + [General](#general) + + [World handling](#world-handling) + - [Interface](#interface) + - [Functional](#functional) + - [Performance](#performance) + + [Logger revamp](#logger-revamp) + + [Network](#network) + - [Minecraft Bedrock packet encryption](#minecraft-bedrock-packet-encryption) + - [Packet receive error handling has been overhauled](#packet-receive-error-handling-has-been-overhauled) + - [New packet handler system](#new-packet-handler-system) +* [API](#api) + + [General](#general-1) + + [Block](#block) + + [Command](#command) + + [Entity](#entity) + - [General](#general-2) + - [Effect](#effect) + - [Removal of runtime entity NBT](#removal-of-runtime-entity-nbt) + - [Entity creation](#entity-creation) + - [WIP removal of entity network metadata](#wip-removal-of-entity-network-metadata) + + [Event](#event) + - [Internal event system no longer depends on `Listener`s](#internal-event-system-no-longer-depends-on-listeners) + - [Default cancelled handling behaviour has changed](#default-cancelled-handling-behaviour-has-changed) + - [`PlayerPreLoginEvent` changes](#playerpreloginevent-changes) + - [Other changes](#other-changes) + + [Inventory](#inventory) + + [Item](#item) + - [General](#general-3) + - [NBT handling](#nbt-handling) + - [Enchantment](#enchantment) + + [Lang](#lang) + + [Network](#network-1) + + [Permission](#permission) + + [Player](#player) + + [Plugin](#plugin) + + [Scheduler](#scheduler) + - [Thread-local storage for AsyncTasks](#thread-local-storage-for-asynctasks) + - [Other changes](#other-changes-1) + + [Server](#server) + + [Level / World](#level---world) + - [General](#general-4) + - [Particles](#particles) + - [Sounds](#sounds) + + [Utils](#utils) +* [Gameplay](#gameplay) + + [Blocks](#blocks) + + [Items](#items) + +Table of contents generated with markdown-toc + ## Core ### General - A new "plugin greylist" feature has been introduced, which allows whitelisting or blacklisting plugins from loading. From ab9615fb9c3ad1111ae7bd19c8738e2a3378337b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 21:19:58 +0100 Subject: [PATCH 2381/3224] World: fixed documentation for getHighestAdjacentPotentialBlockSkyLight() [ci skip] --- src/world/World.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index 27da4673cf..71a371a354 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1318,7 +1318,7 @@ class World implements ChunkManager{ } /** - * Returns the highest block light level available in the positions adjacent to the specified block coordinates. + * Returns the highest potential level of sky light in the positions adjacent to the specified block coordinates. */ public function getHighestAdjacentPotentialBlockSkyLight(int $x, int $y, int $z) : int{ return $this->getHighestAdjacentLight($x, $y, $z, \Closure::fromCallable([$this, 'getPotentialBlockSkyLightAt'])); From e6ecacbb2b60220b73f11fc5a2251ee5f156017e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 21:21:34 +0100 Subject: [PATCH 2382/3224] World: do not access chunks for light if they aren't yet light-populated --- src/world/World.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 71a371a354..6670ab19c7 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1921,7 +1921,7 @@ class World implements ChunkManager{ if(!$this->isInWorld($x, $y, $z)){ return $y >= self::Y_MAX ? 15 : 0; } - if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ + if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null && $chunk->isLightPopulated() === true){ return $chunk->getSubChunk($y >> 4)->getBlockSkyLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); } return 0; //TODO: this should probably throw instead (light not calculated yet) @@ -1936,7 +1936,7 @@ class World implements ChunkManager{ if(!$this->isInWorld($x, $y, $z)){ return 0; } - if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ + if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null && $chunk->isLightPopulated() === true){ return $chunk->getSubChunk($y >> 4)->getBlockLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); } return 0; //TODO: this should probably throw instead (light not calculated yet) From e8dd4de5c8373cb3fe835b3c2db143c19a556bd5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 21:43:46 +0100 Subject: [PATCH 2383/3224] SubChunk: Lazily allocate LightArrays as needed this is slightly slower, but saves a significant amount of memory (~80 KB per chunk). Since ext-chunkutils2 doesn't do copy-on-write trickery like the PHP impl did, we need this to get the memory advantages back. --- src/world/format/SubChunk.php | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/world/format/SubChunk.php b/src/world/format/SubChunk.php index 2224fe1d5a..e1f354a07a 100644 --- a/src/world/format/SubChunk.php +++ b/src/world/format/SubChunk.php @@ -33,9 +33,9 @@ class SubChunk{ /** @var PalettedBlockArray[] */ private $blockLayers; - /** @var LightArray */ + /** @var LightArray|null */ private $blockLight; - /** @var LightArray */ + /** @var LightArray|null */ private $skyLight; /** @@ -47,8 +47,8 @@ class SubChunk{ $this->emptyBlockId = $emptyBlockId; $this->blockLayers = $blocks; - $this->skyLight = $skyLight ?? LightArray::fill(15); - $this->blockLight = $blockLight ?? LightArray::fill(0); + $this->skyLight = $skyLight; + $this->blockLight = $blockLight; } /** @@ -110,7 +110,7 @@ class SubChunk{ } public function getBlockSkyLightArray() : LightArray{ - return $this->skyLight; + return $this->skyLight ??= LightArray::fill(15); } public function setBlockSkyLightArray(LightArray $data) : void{ @@ -118,7 +118,7 @@ class SubChunk{ } public function getBlockLightArray() : LightArray{ - return $this->blockLight; + return $this->blockLight ??= LightArray::fill(0); } public function setBlockLightArray(LightArray $data) : void{ @@ -145,8 +145,12 @@ class SubChunk{ } $this->blockLayers = array_values($this->blockLayers); - $this->skyLight->collectGarbage(); - $this->blockLight->collectGarbage(); + if($this->skyLight !== null){ + $this->skyLight->collectGarbage(); + } + if($this->blockLight !== null){ + $this->blockLight->collectGarbage(); + } } public function __clone(){ @@ -154,7 +158,11 @@ class SubChunk{ return clone $array; }, $this->blockLayers); - $this->skyLight = clone $this->skyLight; - $this->blockLight = clone $this->blockLight; + if($this->skyLight !== null){ + $this->skyLight = clone $this->skyLight; + } + if($this->blockLight !== null){ + $this->blockLight = clone $this->blockLight; + } } } From 5d83f4670ab787e8b448db1a3752b04d1f52bafa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 21:57:23 +0100 Subject: [PATCH 2384/3224] RegionLoader: Switch to using named constructors this makes the code more self-descriptive, and also helps to detect potential bugs. --- src/world/format/io/region/RegionLoader.php | 43 +++++++++++++------ .../format/io/region/RegionWorldProvider.php | 4 +- .../format/io/region/RegionLoaderTest.php | 27 ++++++++++-- tools/compact-regions.php | 4 +- 4 files changed, 56 insertions(+), 22 deletions(-) diff --git a/src/world/format/io/region/RegionLoader.php b/src/world/format/io/region/RegionLoader.php index 746e057f30..dd50f6c38d 100644 --- a/src/world/format/io/region/RegionLoader.php +++ b/src/world/format/io/region/RegionLoader.php @@ -83,30 +83,45 @@ class RegionLoader{ /** * @throws CorruptedRegionException */ - public function __construct(string $filePath){ + private function __construct(string $filePath){ $this->filePath = $filePath; $this->garbageTable = new RegionGarbageMap([]); - - clearstatcache(false, $this->filePath); - $exists = file_exists($this->filePath); - if(!$exists){ - touch($this->filePath); - }elseif(filesize($this->filePath) % 4096 !== 0){ - throw new CorruptedRegionException("Region file should be padded to a multiple of 4KiB"); - } + $this->lastUsed = time(); $filePointer = fopen($this->filePath, "r+b"); if($filePointer === false) throw new AssumptionFailedError("fopen() should not fail here"); $this->filePointer = $filePointer; stream_set_read_buffer($this->filePointer, 1024 * 16); //16KB stream_set_write_buffer($this->filePointer, 1024 * 16); //16KB - if(!$exists){ - $this->createBlank(); - }else{ - $this->loadLocationTable(); + } + + /** + * @throws CorruptedRegionException + */ + public static function loadExisting(string $filePath) : self{ + clearstatcache(false, $filePath); + if(!file_exists($filePath)){ + throw new \RuntimeException("File $filePath does not exist"); + } + if(filesize($filePath) % 4096 !== 0){ + throw new CorruptedRegionException("Region file should be padded to a multiple of 4KiB"); } - $this->lastUsed = time(); + $result = new self($filePath); + $result->loadLocationTable(); + return $result; + } + + public static function createNew(string $filePath) : self{ + clearstatcache(false, $filePath); + if(file_exists($filePath)){ + throw new \RuntimeException("Region file $filePath already exists"); + } + touch($filePath); + + $result = new self($filePath); + $result->createBlank(); + return $result; } public function __destruct(){ diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index 67d2f362f5..212691b282 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -114,7 +114,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ $path = $this->pathToRegion($regionX, $regionZ); try{ - $this->regions[$index] = new RegionLoader($path); + $this->regions[$index] = RegionLoader::loadExisting($path); }catch(CorruptedRegionException $e){ $logger = \GlobalLogger::get(); $logger->error("Corrupted region file detected: " . $e->getMessage()); @@ -123,7 +123,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ rename($path, $backupPath); $logger->error("Corrupted region file has been backed up to " . $backupPath); - $this->regions[$index] = new RegionLoader($path); //this will create a new empty region to replace the corrupted one + $this->regions[$index] = RegionLoader::createNew($path); } } return $this->regions[$index]; diff --git a/tests/phpunit/world/format/io/region/RegionLoaderTest.php b/tests/phpunit/world/format/io/region/RegionLoaderTest.php index 2b35f2f196..0de5babc1a 100644 --- a/tests/phpunit/world/format/io/region/RegionLoaderTest.php +++ b/tests/phpunit/world/format/io/region/RegionLoaderTest.php @@ -25,11 +25,14 @@ namespace pocketmine\world\format\io\region; use PHPUnit\Framework\TestCase; use pocketmine\world\format\ChunkException; +use function bin2hex; +use function clearstatcache; use function file_exists; use function random_bytes; use function str_repeat; use function sys_get_temp_dir; use function unlink; +use const DIRECTORY_SEPARATOR; class RegionLoaderTest extends TestCase{ @@ -43,7 +46,7 @@ class RegionLoaderTest extends TestCase{ if(file_exists($this->regionPath)){ unlink($this->regionPath); } - $this->region = new RegionLoader($this->regionPath); + $this->region = RegionLoader::createNew($this->regionPath); } public function tearDown() : void{ @@ -63,7 +66,7 @@ class RegionLoaderTest extends TestCase{ $this->region->writeChunk(0, 0, $data); $this->region->close(); - $r = new RegionLoader($this->regionPath); + $r = RegionLoader::loadExisting($this->regionPath); self::assertSame($data, $r->readChunk(0, 0)); } @@ -119,11 +122,27 @@ class RegionLoaderTest extends TestCase{ */ public function testRegionHeaderCachedFilesizeRegression() : void{ $this->region->close(); - $region = new RegionLoader($this->regionPath); //now we have a region, so the header will be verified, triggering two filesize() calls + $region = RegionLoader::loadExisting($this->regionPath); //now we have a region, so the header will be verified, triggering two filesize() calls $data = str_repeat("hello", 2000); $region->writeChunk(0, 0, $data); //add some data to the end of the file, to make the cached filesize invalid $region->close(); - $region = new RegionLoader($this->regionPath); + $region = RegionLoader::loadExisting($this->regionPath); self::assertSame($data, $region->readChunk(0, 0)); } + + public function testCreateNewWithExistingRegion() : void{ + $this->region->close(); + $this->expectException(\RuntimeException::class); + RegionLoader::createNew($this->regionPath); + } + + public function testLoadExistingWithMissingFile() : void{ + clearstatcache(); + + do{ + $randfile = sys_get_temp_dir() . DIRECTORY_SEPARATOR . bin2hex(random_bytes(6)) . ".mca"; + }while(file_exists($randfile)); + $this->expectException(\RuntimeException::class); + RegionLoader::loadExisting($randfile); + } } diff --git a/tools/compact-regions.php b/tools/compact-regions.php index 77089ce0dc..54e6fbe94a 100644 --- a/tools/compact-regions.php +++ b/tools/compact-regions.php @@ -108,7 +108,7 @@ function main(array $argv) : int{ $totalCount = count($files); foreach($files as $file => $size){ try{ - $oldRegion = new RegionLoader($file); + $oldRegion = RegionLoader::loadExisting($file); }catch(CorruptedRegionException $e){ $logger->error("Damaged region in file $file (" . $e->getMessage() . "), skipping"); $corruptedFiles[] = $file; @@ -117,7 +117,7 @@ function main(array $argv) : int{ } $newFile = $file . ".compacted"; - $newRegion = new RegionLoader($newFile); + $newRegion = RegionLoader::createNew($newFile); $emptyRegion = true; $corruption = false; From bf6717050468b6479aeec15533ce104bb71d5df5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 23:22:53 +0100 Subject: [PATCH 2385/3224] SubChunk: don't assume 15 sky light when not allocated closes #2533 at long last... --- src/world/format/SubChunk.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/format/SubChunk.php b/src/world/format/SubChunk.php index e1f354a07a..676c643b81 100644 --- a/src/world/format/SubChunk.php +++ b/src/world/format/SubChunk.php @@ -110,7 +110,7 @@ class SubChunk{ } public function getBlockSkyLightArray() : LightArray{ - return $this->skyLight ??= LightArray::fill(15); + return $this->skyLight ??= LightArray::fill(0); } public function setBlockSkyLightArray(LightArray $data) : void{ From ebd19f5a70b67d26927844552c48fa217aa35efd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Apr 2021 23:32:30 +0100 Subject: [PATCH 2386/3224] SubChunkExplorer: Protect world field --- src/world/utils/SubChunkExplorer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/utils/SubChunkExplorer.php b/src/world/utils/SubChunkExplorer.php index a020a658ec..05685b6cfd 100644 --- a/src/world/utils/SubChunkExplorer.php +++ b/src/world/utils/SubChunkExplorer.php @@ -29,7 +29,7 @@ use pocketmine\world\format\SubChunk; class SubChunkExplorer{ /** @var ChunkManager */ - public $world; + protected $world; /** @var Chunk|null */ public $currentChunk; From b31b097b8e3b24e73776c337cfb8909504aa5584 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 16 Apr 2021 15:41:14 +0100 Subject: [PATCH 2387/3224] LightPopulationTask no longer hard-depends on Server --- src/world/World.php | 27 ++++++++++++- src/world/light/LightPopulationTask.php | 52 ++++++++++--------------- 2 files changed, 46 insertions(+), 33 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 6670ab19c7..54fe5ffedb 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -74,6 +74,7 @@ use pocketmine\world\biome\BiomeRegistry; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\WritableWorldProvider; +use pocketmine\world\format\LightArray; use pocketmine\world\generator\GeneratorManager; use pocketmine\world\generator\GeneratorRegisterTask; use pocketmine\world\generator\GeneratorUnregisterTask; @@ -1001,7 +1002,31 @@ class World implements ChunkManager{ if($lightPopulatedState !== true){ if($lightPopulatedState === false){ $this->chunks[$hash]->setLightPopulated(null); - $this->workerPool->submitTask(new LightPopulationTask($this, $dx + $chunkX, $dz + $chunkZ, $this->chunks[$hash])); + + $this->workerPool->submitTask(new LightPopulationTask( + $this->chunks[$hash], + function(array $blockLight, array $skyLight, array $heightMap) use ($dx, $chunkX, $dz, $chunkZ) : void{ + /** + * TODO: phpstan can't infer these types yet :( + * @phpstan-var array $blockLight + * @phpstan-var array $skyLight + * @phpstan-var array $heightMap + */ + if($this->closed || ($chunk = $this->getChunk($dx + $chunkX, $dz + $chunkZ)) === null || $chunk->isLightPopulated() === true){ + return; + } + //TODO: calculated light information might not be valid if the terrain changed during light calculation + + $chunk->setHeightMapArray($heightMap); + foreach($blockLight as $y => $lightArray){ + $chunk->getSubChunk($y)->setBlockLightArray($lightArray); + } + foreach($skyLight as $y => $lightArray){ + $chunk->getSubChunk($y)->setBlockSkyLightArray($lightArray); + } + $chunk->setLightPopulated(true); + } + )); } continue; } diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index 70e55ad79b..d7cdce64a4 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -35,16 +35,11 @@ use function igbinary_serialize; use function igbinary_unserialize; class LightPopulationTask extends AsyncTask{ - private const TLS_KEY_WORLD = "world"; + private const TLS_KEY_COMPLETION_CALLBACK = "onCompletion"; /** @var string */ public $chunk; - /** @var int */ - private $chunkX; - /** @var int */ - private $chunkZ; - /** @var string */ private $resultHeightMap; /** @var string */ @@ -52,25 +47,26 @@ class LightPopulationTask extends AsyncTask{ /** @var string */ private $resultBlockLightArrays; - public function __construct(World $world, int $chunkX, int $chunkZ, Chunk $chunk){ - $this->storeLocal(self::TLS_KEY_WORLD, $world); - [$this->chunkX, $this->chunkZ] = [$chunkX, $chunkZ]; - $chunk->setLightPopulated(null); + /** + * @phpstan-param \Closure(array $blockLight, array $skyLight, array $heightMap) : void $onCompletion + */ + public function __construct(Chunk $chunk, \Closure $onCompletion){ $this->chunk = FastChunkSerializer::serialize($chunk); + $this->storeLocal(self::TLS_KEY_COMPLETION_CALLBACK, $onCompletion); } public function onRun() : void{ $chunk = FastChunkSerializer::deserialize($this->chunk); $manager = new SimpleChunkManager(World::Y_MIN, World::Y_MAX); - $manager->setChunk($this->chunkX, $this->chunkZ, $chunk); + $manager->setChunk(0, 0, $chunk); $blockFactory = BlockFactory::getInstance(); foreach([ "Block" => new BlockLightUpdate(new SubChunkExplorer($manager), $blockFactory->lightFilter, $blockFactory->light), "Sky" => new SkyLightUpdate(new SubChunkExplorer($manager), $blockFactory->lightFilter, $blockFactory->blocksDirectSkyLight), ] as $name => $update){ - $update->recalculateChunk($this->chunkX, $this->chunkZ); + $update->recalculateChunk(0, 0); $update->execute(); } @@ -88,27 +84,19 @@ class LightPopulationTask extends AsyncTask{ } public function onCompletion() : void{ - /** @var World $world */ - $world = $this->fetchLocal(self::TLS_KEY_WORLD); - if(!$world->isClosed() and ($chunk = $world->getChunk($this->chunkX, $this->chunkZ)) !== null){ - //TODO: calculated light information might not be valid if the terrain changed during light calculation + /** @var int[] $heightMapArray */ + $heightMapArray = igbinary_unserialize($this->resultHeightMap); - /** @var int[] $heightMapArray */ - $heightMapArray = igbinary_unserialize($this->resultHeightMap); - $chunk->setHeightMapArray($heightMapArray); + /** @var LightArray[] $skyLightArrays */ + $skyLightArrays = igbinary_unserialize($this->resultSkyLightArrays); + /** @var LightArray[] $blockLightArrays */ + $blockLightArrays = igbinary_unserialize($this->resultBlockLightArrays); - /** @var LightArray[] $skyLightArrays */ - $skyLightArrays = igbinary_unserialize($this->resultSkyLightArrays); - /** @var LightArray[] $blockLightArrays */ - $blockLightArrays = igbinary_unserialize($this->resultBlockLightArrays); - - foreach($skyLightArrays as $y => $array){ - $chunk->getSubChunk($y)->setBlockSkyLightArray($array); - } - foreach($blockLightArrays as $y => $array){ - $chunk->getSubChunk($y)->setBlockLightArray($array); - } - $chunk->setLightPopulated(); - } + /** + * @var \Closure + * @phpstan-var \Closure(array $blockLight, array $skyLight, array $heightMap>) : void + */ + $callback = $this->fetchLocal(self::TLS_KEY_COMPLETION_CALLBACK); + $callback($blockLightArrays, $skyLightArrays, $heightMapArray); } } From 81ced66bd0f7d61ebb46e70d0ad2c6339689ba09 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 16 Apr 2021 20:14:29 +0100 Subject: [PATCH 2388/3224] BlockIdentifier: variant parameter of constructor is now mandatory --- src/block/BlockFactory.php | 532 ++++++++++++------------- src/block/BlockIdentifier.php | 2 +- src/block/BlockIdentifierFlattened.php | 2 +- src/block/BlockLegacyIdHelper.php | 92 ++--- tests/phpunit/block/BlockTest.php | 10 +- 5 files changed, 319 insertions(+), 319 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index f78c2cd3f5..6c18ce1513 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -99,55 +99,55 @@ class BlockFactory{ $this->blocksDirectSkyLight = \SplFixedArray::fromArray(array_fill(0, 16384, false)); $this->blastResistance = \SplFixedArray::fromArray(array_fill(0, 16384, 0.0)); - $this->register(new ActivatorRail(new BID(Ids::ACTIVATOR_RAIL), "Activator Rail")); - $this->register(new Air(new BID(Ids::AIR), "Air")); - $this->register(new Anvil(new BID(Ids::ANVIL), "Anvil")); - $this->register(new Bamboo(new BID(Ids::BAMBOO), "Bamboo", new BlockBreakInfo(2.0 /* 1.0 in PC */, BlockToolType::AXE))); - $this->register(new BambooSapling(new BID(Ids::BAMBOO_SAPLING), "Bamboo Sapling", BlockBreakInfo::instant())); + $this->register(new ActivatorRail(new BID(Ids::ACTIVATOR_RAIL, 0), "Activator Rail")); + $this->register(new Air(new BID(Ids::AIR, 0), "Air")); + $this->register(new Anvil(new BID(Ids::ANVIL, 0), "Anvil")); + $this->register(new Bamboo(new BID(Ids::BAMBOO, 0), "Bamboo", new BlockBreakInfo(2.0 /* 1.0 in PC */, BlockToolType::AXE))); + $this->register(new BambooSapling(new BID(Ids::BAMBOO_SAPLING, 0), "Bamboo Sapling", BlockBreakInfo::instant())); $this->register(new FloorBanner(new BID(Ids::STANDING_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Banner")); $this->register(new WallBanner(new BID(Ids::WALL_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Wall Banner")); $this->register(new Barrel(new BID(Ids::BARREL, 0, null, TileBarrel::class), "Barrel")); - $this->register(new Transparent(new BID(Ids::BARRIER), "Barrier", BlockBreakInfo::indestructible())); + $this->register(new Transparent(new BID(Ids::BARRIER, 0), "Barrier", BlockBreakInfo::indestructible())); $this->register(new Beacon(new BID(Ids::BEACON, 0, null, TileBeacon::class), "Beacon", new BlockBreakInfo(3.0))); $this->register(new Bed(new BID(Ids::BED_BLOCK, 0, ItemIds::BED, TileBed::class), "Bed Block")); - $this->register(new Bedrock(new BID(Ids::BEDROCK), "Bedrock")); - $this->register(new Beetroot(new BID(Ids::BEETROOT_BLOCK), "Beetroot Block")); - $this->register(new BlueIce(new BID(Ids::BLUE_ICE), "Blue Ice")); - $this->register(new BoneBlock(new BID(Ids::BONE_BLOCK), "Bone Block")); - $this->register(new Bookshelf(new BID(Ids::BOOKSHELF), "Bookshelf")); + $this->register(new Bedrock(new BID(Ids::BEDROCK, 0), "Bedrock")); + $this->register(new Beetroot(new BID(Ids::BEETROOT_BLOCK, 0), "Beetroot Block")); + $this->register(new BlueIce(new BID(Ids::BLUE_ICE, 0), "Blue Ice")); + $this->register(new BoneBlock(new BID(Ids::BONE_BLOCK, 0), "Bone Block")); + $this->register(new Bookshelf(new BID(Ids::BOOKSHELF, 0), "Bookshelf")); $this->register(new BrewingStand(new BID(Ids::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND, TileBrewingStand::class), "Brewing Stand")); $bricksBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - $this->register(new Stair(new BID(Ids::BRICK_STAIRS), "Brick Stairs", $bricksBreakInfo)); - $this->register(new Opaque(new BID(Ids::BRICK_BLOCK), "Bricks", $bricksBreakInfo)); + $this->register(new Stair(new BID(Ids::BRICK_STAIRS, 0), "Brick Stairs", $bricksBreakInfo)); + $this->register(new Opaque(new BID(Ids::BRICK_BLOCK, 0), "Bricks", $bricksBreakInfo)); - $this->register(new BrownMushroom(new BID(Ids::BROWN_MUSHROOM), "Brown Mushroom")); - $this->register(new Cactus(new BID(Ids::CACTUS), "Cactus")); + $this->register(new BrownMushroom(new BID(Ids::BROWN_MUSHROOM, 0), "Brown Mushroom")); + $this->register(new Cactus(new BID(Ids::CACTUS, 0), "Cactus")); $this->register(new Cake(new BID(Ids::CAKE_BLOCK, 0, ItemIds::CAKE), "Cake")); - $this->register(new Carrot(new BID(Ids::CARROTS), "Carrot Block")); + $this->register(new Carrot(new BID(Ids::CARROTS, 0), "Carrot Block")); $this->register(new Chest(new BID(Ids::CHEST, 0, null, TileChest::class), "Chest")); - $this->register(new Clay(new BID(Ids::CLAY_BLOCK), "Clay Block")); - $this->register(new Coal(new BID(Ids::COAL_BLOCK), "Coal Block")); - $this->register(new CoalOre(new BID(Ids::COAL_ORE), "Coal Ore")); + $this->register(new Clay(new BID(Ids::CLAY_BLOCK, 0), "Clay Block")); + $this->register(new Coal(new BID(Ids::COAL_BLOCK, 0), "Coal Block")); + $this->register(new CoalOre(new BID(Ids::COAL_ORE, 0), "Coal Ore")); $this->register(new CoarseDirt(new BID(Ids::DIRT, Meta::DIRT_COARSE), "Coarse Dirt")); $cobblestoneBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - $this->register($cobblestone = new Opaque(new BID(Ids::COBBLESTONE), "Cobblestone", $cobblestoneBreakInfo)); + $this->register($cobblestone = new Opaque(new BID(Ids::COBBLESTONE, 0), "Cobblestone", $cobblestoneBreakInfo)); $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_COBBLESTONE), "Infested Cobblestone", $cobblestone)); - $this->register(new Opaque(new BID(Ids::MOSSY_COBBLESTONE), "Mossy Cobblestone", $cobblestoneBreakInfo)); - $this->register(new Stair(new BID(Ids::COBBLESTONE_STAIRS), "Cobblestone Stairs", $cobblestoneBreakInfo)); - $this->register(new Stair(new BID(Ids::MOSSY_COBBLESTONE_STAIRS), "Mossy Cobblestone Stairs", $cobblestoneBreakInfo)); + $this->register(new Opaque(new BID(Ids::MOSSY_COBBLESTONE, 0), "Mossy Cobblestone", $cobblestoneBreakInfo)); + $this->register(new Stair(new BID(Ids::COBBLESTONE_STAIRS, 0), "Cobblestone Stairs", $cobblestoneBreakInfo)); + $this->register(new Stair(new BID(Ids::MOSSY_COBBLESTONE_STAIRS, 0), "Mossy Cobblestone Stairs", $cobblestoneBreakInfo)); - $this->register(new Cobweb(new BID(Ids::COBWEB), "Cobweb")); - $this->register(new CocoaBlock(new BID(Ids::COCOA), "Cocoa Block")); - $this->register(new CoralBlock(new BID(Ids::CORAL_BLOCK), "Coral Block", new BlockBreakInfo(7.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - $this->register(new CraftingTable(new BID(Ids::CRAFTING_TABLE), "Crafting Table")); + $this->register(new Cobweb(new BID(Ids::COBWEB, 0), "Cobweb")); + $this->register(new CocoaBlock(new BID(Ids::COCOA, 0), "Cocoa Block")); + $this->register(new CoralBlock(new BID(Ids::CORAL_BLOCK, 0), "Coral Block", new BlockBreakInfo(7.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->register(new CraftingTable(new BID(Ids::CRAFTING_TABLE, 0), "Crafting Table")); $this->register(new DaylightSensor(new BIDFlattened(Ids::DAYLIGHT_DETECTOR, Ids::DAYLIGHT_DETECTOR_INVERTED, 0, null, TileDaylightSensor::class), "Daylight Sensor")); - $this->register(new DeadBush(new BID(Ids::DEADBUSH), "Dead Bush")); - $this->register(new DetectorRail(new BID(Ids::DETECTOR_RAIL), "Detector Rail")); + $this->register(new DeadBush(new BID(Ids::DEADBUSH, 0), "Dead Bush")); + $this->register(new DetectorRail(new BID(Ids::DETECTOR_RAIL, 0), "Detector Rail")); - $this->register(new Opaque(new BID(Ids::DIAMOND_BLOCK), "Diamond Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); - $this->register(new DiamondOre(new BID(Ids::DIAMOND_ORE), "Diamond Ore")); + $this->register(new Opaque(new BID(Ids::DIAMOND_BLOCK, 0), "Diamond Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); + $this->register(new DiamondOre(new BID(Ids::DIAMOND_ORE, 0), "Diamond Ore")); $this->register(new Dirt(new BID(Ids::DIRT, Meta::DIRT_NORMAL), "Dirt")); $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_SUNFLOWER), "Sunflower")); $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LILAC), "Lilac")); @@ -155,23 +155,23 @@ class BlockFactory{ $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_PEONY), "Peony")); $this->register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_TALLGRASS), "Double Tallgrass")); $this->register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LARGE_FERN), "Large Fern")); - $this->register(new DragonEgg(new BID(Ids::DRAGON_EGG), "Dragon Egg")); - $this->register(new DriedKelp(new BID(Ids::DRIED_KELP_BLOCK), "Dried Kelp Block", new BlockBreakInfo(0.5, BlockToolType::NONE, 0, 12.5))); - $this->register(new Opaque(new BID(Ids::EMERALD_BLOCK), "Emerald Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); - $this->register(new EmeraldOre(new BID(Ids::EMERALD_ORE), "Emerald Ore")); + $this->register(new DragonEgg(new BID(Ids::DRAGON_EGG, 0), "Dragon Egg")); + $this->register(new DriedKelp(new BID(Ids::DRIED_KELP_BLOCK, 0), "Dried Kelp Block", new BlockBreakInfo(0.5, BlockToolType::NONE, 0, 12.5))); + $this->register(new Opaque(new BID(Ids::EMERALD_BLOCK, 0), "Emerald Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); + $this->register(new EmeraldOre(new BID(Ids::EMERALD_ORE, 0), "Emerald Ore")); $this->register(new EnchantingTable(new BID(Ids::ENCHANTING_TABLE, 0, null, TileEnchantingTable::class), "Enchanting Table")); - $this->register(new EndPortalFrame(new BID(Ids::END_PORTAL_FRAME), "End Portal Frame")); - $this->register(new EndRod(new BID(Ids::END_ROD), "End Rod")); - $this->register(new Opaque(new BID(Ids::END_STONE), "End Stone", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 45.0))); + $this->register(new EndPortalFrame(new BID(Ids::END_PORTAL_FRAME, 0), "End Portal Frame")); + $this->register(new EndRod(new BID(Ids::END_ROD, 0), "End Rod")); + $this->register(new Opaque(new BID(Ids::END_STONE, 0), "End Stone", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 45.0))); $endBrickBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 4.0); - $this->register(new Opaque(new BID(Ids::END_BRICKS), "End Stone Bricks", $endBrickBreakInfo)); - $this->register(new Stair(new BID(Ids::END_BRICK_STAIRS), "End Stone Brick Stairs", $endBrickBreakInfo)); + $this->register(new Opaque(new BID(Ids::END_BRICKS, 0), "End Stone Bricks", $endBrickBreakInfo)); + $this->register(new Stair(new BID(Ids::END_BRICK_STAIRS, 0), "End Stone Brick Stairs", $endBrickBreakInfo)); $this->register(new EnderChest(new BID(Ids::ENDER_CHEST, 0, null, TileEnderChest::class), "Ender Chest")); - $this->register(new Farmland(new BID(Ids::FARMLAND), "Farmland")); - $this->register(new Fire(new BID(Ids::FIRE), "Fire Block")); - $this->register(new Flower(new BID(Ids::DANDELION), "Dandelion")); + $this->register(new Farmland(new BID(Ids::FARMLAND, 0), "Farmland")); + $this->register(new Fire(new BID(Ids::FIRE, 0), "Fire Block")); + $this->register(new Flower(new BID(Ids::DANDELION, 0), "Dandelion")); $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ALLIUM), "Allium")); $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_AZURE_BLUET), "Azure Bluet")); $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_BLUE_ORCHID), "Blue Orchid")); @@ -184,117 +184,117 @@ class BlockFactory{ $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_RED_TULIP), "Red Tulip")); $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_WHITE_TULIP), "White Tulip")); $this->register(new FlowerPot(new BID(Ids::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, TileFlowerPot::class), "Flower Pot")); - $this->register(new FrostedIce(new BID(Ids::FROSTED_ICE), "Frosted Ice")); + $this->register(new FrostedIce(new BID(Ids::FROSTED_ICE, 0), "Frosted Ice")); $this->register(new Furnace(new BIDFlattened(Ids::FURNACE, Ids::LIT_FURNACE, 0, null, TileFurnace::class), "Furnace")); - $this->register(new Glass(new BID(Ids::GLASS), "Glass")); - $this->register(new GlassPane(new BID(Ids::GLASS_PANE), "Glass Pane")); - $this->register(new GlowingObsidian(new BID(Ids::GLOWINGOBSIDIAN), "Glowing Obsidian")); - $this->register(new Glowstone(new BID(Ids::GLOWSTONE), "Glowstone")); - $this->register(new Opaque(new BID(Ids::GOLD_BLOCK), "Gold Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); - $this->register(new Opaque(new BID(Ids::GOLD_ORE), "Gold Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); - $this->register(new Grass(new BID(Ids::GRASS), "Grass")); - $this->register(new GrassPath(new BID(Ids::GRASS_PATH), "Grass Path")); - $this->register(new Gravel(new BID(Ids::GRAVEL), "Gravel")); - $this->register(new HardenedClay(new BID(Ids::HARDENED_CLAY), "Hardened Clay")); - $this->register(new HardenedGlass(new BID(Ids::HARD_GLASS), "Hardened Glass")); - $this->register(new HardenedGlassPane(new BID(Ids::HARD_GLASS_PANE), "Hardened Glass Pane")); - $this->register(new HayBale(new BID(Ids::HAY_BALE), "Hay Bale")); + $this->register(new Glass(new BID(Ids::GLASS, 0), "Glass")); + $this->register(new GlassPane(new BID(Ids::GLASS_PANE, 0), "Glass Pane")); + $this->register(new GlowingObsidian(new BID(Ids::GLOWINGOBSIDIAN, 0), "Glowing Obsidian")); + $this->register(new Glowstone(new BID(Ids::GLOWSTONE, 0), "Glowstone")); + $this->register(new Opaque(new BID(Ids::GOLD_BLOCK, 0), "Gold Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); + $this->register(new Opaque(new BID(Ids::GOLD_ORE, 0), "Gold Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); + $this->register(new Grass(new BID(Ids::GRASS, 0), "Grass")); + $this->register(new GrassPath(new BID(Ids::GRASS_PATH, 0), "Grass Path")); + $this->register(new Gravel(new BID(Ids::GRAVEL, 0), "Gravel")); + $this->register(new HardenedClay(new BID(Ids::HARDENED_CLAY, 0), "Hardened Clay")); + $this->register(new HardenedGlass(new BID(Ids::HARD_GLASS, 0), "Hardened Glass")); + $this->register(new HardenedGlassPane(new BID(Ids::HARD_GLASS_PANE, 0), "Hardened Glass Pane")); + $this->register(new HayBale(new BID(Ids::HAY_BALE, 0), "Hay Bale")); $this->register(new Hopper(new BID(Ids::HOPPER_BLOCK, 0, ItemIds::HOPPER, TileHopper::class), "Hopper", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 15.0))); - $this->register(new Ice(new BID(Ids::ICE), "Ice")); + $this->register(new Ice(new BID(Ids::ICE, 0), "Ice")); $updateBlockBreakInfo = new BlockBreakInfo(1.0); - $this->register(new Opaque(new BID(Ids::INFO_UPDATE), "update!", $updateBlockBreakInfo)); - $this->register(new Opaque(new BID(Ids::INFO_UPDATE2), "ate!upd", $updateBlockBreakInfo)); - $this->register(new Transparent(new BID(Ids::INVISIBLEBEDROCK), "Invisible Bedrock", BlockBreakInfo::indestructible())); - $this->register(new Opaque(new BID(Ids::IRON_BLOCK), "Iron Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel(), 30.0))); - $this->register(new Thin(new BID(Ids::IRON_BARS), "Iron Bars", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0))); + $this->register(new Opaque(new BID(Ids::INFO_UPDATE, 0), "update!", $updateBlockBreakInfo)); + $this->register(new Opaque(new BID(Ids::INFO_UPDATE2, 0), "ate!upd", $updateBlockBreakInfo)); + $this->register(new Transparent(new BID(Ids::INVISIBLEBEDROCK, 0), "Invisible Bedrock", BlockBreakInfo::indestructible())); + $this->register(new Opaque(new BID(Ids::IRON_BLOCK, 0), "Iron Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel(), 30.0))); + $this->register(new Thin(new BID(Ids::IRON_BARS, 0), "Iron Bars", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0))); $this->register(new Door(new BID(Ids::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0))); - $this->register(new Opaque(new BID(Ids::IRON_ORE), "Iron Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); - $this->register(new Trapdoor(new BID(Ids::IRON_TRAPDOOR), "Iron Trapdoor", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0))); + $this->register(new Opaque(new BID(Ids::IRON_ORE, 0), "Iron Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); + $this->register(new Trapdoor(new BID(Ids::IRON_TRAPDOOR, 0), "Iron Trapdoor", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0))); $this->register(new ItemFrame(new BID(Ids::FRAME_BLOCK, 0, ItemIds::FRAME, TileItemFrame::class), "Item Frame")); $this->register(new Jukebox(new BID(Ids::JUKEBOX, 0, ItemIds::JUKEBOX, TileJukebox::class), "Jukebox")); - $this->register(new Ladder(new BID(Ids::LADDER), "Ladder")); - $this->register(new Lantern(new BID(Ids::LANTERN), "Lantern", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - $this->register(new Opaque(new BID(Ids::LAPIS_BLOCK), "Lapis Lazuli Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); - $this->register(new LapisOre(new BID(Ids::LAPIS_ORE), "Lapis Lazuli Ore")); - $this->register(new Lava(new BIDFlattened(Ids::FLOWING_LAVA, Ids::STILL_LAVA), "Lava")); - $this->register(new Lever(new BID(Ids::LEVER), "Lever")); - $this->register(new Magma(new BID(Ids::MAGMA), "Magma Block")); - $this->register(new Melon(new BID(Ids::MELON_BLOCK), "Melon Block")); + $this->register(new Ladder(new BID(Ids::LADDER, 0), "Ladder")); + $this->register(new Lantern(new BID(Ids::LANTERN, 0), "Lantern", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->register(new Opaque(new BID(Ids::LAPIS_BLOCK, 0), "Lapis Lazuli Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); + $this->register(new LapisOre(new BID(Ids::LAPIS_ORE, 0), "Lapis Lazuli Ore")); + $this->register(new Lava(new BIDFlattened(Ids::FLOWING_LAVA, Ids::STILL_LAVA, 0), "Lava")); + $this->register(new Lever(new BID(Ids::LEVER, 0), "Lever")); + $this->register(new Magma(new BID(Ids::MAGMA, 0), "Magma Block")); + $this->register(new Melon(new BID(Ids::MELON_BLOCK, 0), "Melon Block")); $this->register(new MelonStem(new BID(Ids::MELON_STEM, 0, ItemIds::MELON_SEEDS), "Melon Stem")); $this->register(new MonsterSpawner(new BID(Ids::MOB_SPAWNER, 0, null, TileMonsterSpawner::class), "Monster Spawner")); - $this->register(new Mycelium(new BID(Ids::MYCELIUM), "Mycelium")); + $this->register(new Mycelium(new BID(Ids::MYCELIUM, 0), "Mycelium")); $netherBrickBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - $this->register(new Opaque(new BID(Ids::NETHER_BRICK_BLOCK), "Nether Bricks", $netherBrickBreakInfo)); - $this->register(new Opaque(new BID(Ids::RED_NETHER_BRICK), "Red Nether Bricks", $netherBrickBreakInfo)); - $this->register(new Fence(new BID(Ids::NETHER_BRICK_FENCE), "Nether Brick Fence", $netherBrickBreakInfo)); - $this->register(new Stair(new BID(Ids::NETHER_BRICK_STAIRS), "Nether Brick Stairs", $netherBrickBreakInfo)); - $this->register(new Stair(new BID(Ids::RED_NETHER_BRICK_STAIRS), "Red Nether Brick Stairs", $netherBrickBreakInfo)); - $this->register(new NetherPortal(new BID(Ids::PORTAL), "Nether Portal")); - $this->register(new NetherQuartzOre(new BID(Ids::NETHER_QUARTZ_ORE), "Nether Quartz Ore")); - $this->register(new NetherReactor(new BID(Ids::NETHERREACTOR), "Nether Reactor Core")); - $this->register(new Opaque(new BID(Ids::NETHER_WART_BLOCK), "Nether Wart Block", new BlockBreakInfo(1.0))); + $this->register(new Opaque(new BID(Ids::NETHER_BRICK_BLOCK, 0), "Nether Bricks", $netherBrickBreakInfo)); + $this->register(new Opaque(new BID(Ids::RED_NETHER_BRICK, 0), "Red Nether Bricks", $netherBrickBreakInfo)); + $this->register(new Fence(new BID(Ids::NETHER_BRICK_FENCE, 0), "Nether Brick Fence", $netherBrickBreakInfo)); + $this->register(new Stair(new BID(Ids::NETHER_BRICK_STAIRS, 0), "Nether Brick Stairs", $netherBrickBreakInfo)); + $this->register(new Stair(new BID(Ids::RED_NETHER_BRICK_STAIRS, 0), "Red Nether Brick Stairs", $netherBrickBreakInfo)); + $this->register(new NetherPortal(new BID(Ids::PORTAL, 0), "Nether Portal")); + $this->register(new NetherQuartzOre(new BID(Ids::NETHER_QUARTZ_ORE, 0), "Nether Quartz Ore")); + $this->register(new NetherReactor(new BID(Ids::NETHERREACTOR, 0), "Nether Reactor Core")); + $this->register(new Opaque(new BID(Ids::NETHER_WART_BLOCK, 0), "Nether Wart Block", new BlockBreakInfo(1.0))); $this->register(new NetherWartPlant(new BID(Ids::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART), "Nether Wart")); - $this->register(new Netherrack(new BID(Ids::NETHERRACK), "Netherrack")); + $this->register(new Netherrack(new BID(Ids::NETHERRACK, 0), "Netherrack")); $this->register(new Note(new BID(Ids::NOTEBLOCK, 0, null, TileNote::class), "Note Block")); - $this->register(new Opaque(new BID(Ids::OBSIDIAN), "Obsidian", new BlockBreakInfo(35.0 /* 50 in PC */, BlockToolType::PICKAXE, ToolTier::DIAMOND()->getHarvestLevel(), 6000.0))); - $this->register(new PackedIce(new BID(Ids::PACKED_ICE), "Packed Ice")); - $this->register(new Podzol(new BID(Ids::PODZOL), "Podzol")); - $this->register(new Potato(new BID(Ids::POTATOES), "Potato Block")); + $this->register(new Opaque(new BID(Ids::OBSIDIAN, 0), "Obsidian", new BlockBreakInfo(35.0 /* 50 in PC */, BlockToolType::PICKAXE, ToolTier::DIAMOND()->getHarvestLevel(), 6000.0))); + $this->register(new PackedIce(new BID(Ids::PACKED_ICE, 0), "Packed Ice")); + $this->register(new Podzol(new BID(Ids::PODZOL, 0), "Podzol")); + $this->register(new Potato(new BID(Ids::POTATOES, 0), "Potato Block")); $this->register(new PoweredRail(new BID(Ids::GOLDEN_RAIL, Meta::RAIL_STRAIGHT_NORTH_SOUTH), "Powered Rail")); $prismarineBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); $this->register(new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_BRICKS), "Prismarine Bricks", $prismarineBreakInfo)); - $this->register(new Stair(new BID(Ids::PRISMARINE_BRICKS_STAIRS), "Prismarine Bricks Stairs", $prismarineBreakInfo)); + $this->register(new Stair(new BID(Ids::PRISMARINE_BRICKS_STAIRS, 0), "Prismarine Bricks Stairs", $prismarineBreakInfo)); $this->register(new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_DARK), "Dark Prismarine", $prismarineBreakInfo)); - $this->register(new Stair(new BID(Ids::DARK_PRISMARINE_STAIRS), "Dark Prismarine Stairs", $prismarineBreakInfo)); + $this->register(new Stair(new BID(Ids::DARK_PRISMARINE_STAIRS, 0), "Dark Prismarine Stairs", $prismarineBreakInfo)); $this->register(new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_NORMAL), "Prismarine", $prismarineBreakInfo)); - $this->register(new Stair(new BID(Ids::PRISMARINE_STAIRS), "Prismarine Stairs", $prismarineBreakInfo)); + $this->register(new Stair(new BID(Ids::PRISMARINE_STAIRS, 0), "Prismarine Stairs", $prismarineBreakInfo)); $pumpkinBreakInfo = new BlockBreakInfo(1.0, BlockToolType::AXE); - $this->register($pumpkin = new Opaque(new BID(Ids::PUMPKIN), "Pumpkin", $pumpkinBreakInfo)); + $this->register($pumpkin = new Opaque(new BID(Ids::PUMPKIN, 0), "Pumpkin", $pumpkinBreakInfo)); for($i = 1; $i <= 3; ++$i){ $this->remap(Ids::PUMPKIN, $i, $pumpkin); } - $this->register(new CarvedPumpkin(new BID(Ids::CARVED_PUMPKIN), "Carved Pumpkin", $pumpkinBreakInfo)); - $this->register(new LitPumpkin(new BID(Ids::JACK_O_LANTERN), "Jack o'Lantern", $pumpkinBreakInfo)); + $this->register(new CarvedPumpkin(new BID(Ids::CARVED_PUMPKIN, 0), "Carved Pumpkin", $pumpkinBreakInfo)); + $this->register(new LitPumpkin(new BID(Ids::JACK_O_LANTERN, 0), "Jack o'Lantern", $pumpkinBreakInfo)); $this->register(new PumpkinStem(new BID(Ids::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem")); $purpurBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); $this->register(new Opaque(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_NORMAL), "Purpur Block", $purpurBreakInfo)); $this->register(new SimplePillar(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_PILLAR), "Purpur Pillar", $purpurBreakInfo)); - $this->register(new Stair(new BID(Ids::PURPUR_STAIRS), "Purpur Stairs", $purpurBreakInfo)); + $this->register(new Stair(new BID(Ids::PURPUR_STAIRS, 0), "Purpur Stairs", $purpurBreakInfo)); $quartzBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()); $this->register(new Opaque(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_NORMAL), "Quartz Block", $quartzBreakInfo)); - $this->register(new Stair(new BID(Ids::QUARTZ_STAIRS), "Quartz Stairs", $quartzBreakInfo)); + $this->register(new Stair(new BID(Ids::QUARTZ_STAIRS, 0), "Quartz Stairs", $quartzBreakInfo)); $this->register(new SimplePillar(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_CHISELED), "Chiseled Quartz Block", $quartzBreakInfo)); $this->register(new SimplePillar(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_PILLAR), "Quartz Pillar", $quartzBreakInfo)); $this->register(new Opaque(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_SMOOTH), "Smooth Quartz Block", $quartzBreakInfo)); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) - $this->register(new Stair(new BID(Ids::SMOOTH_QUARTZ_STAIRS), "Smooth Quartz Stairs", $quartzBreakInfo)); + $this->register(new Stair(new BID(Ids::SMOOTH_QUARTZ_STAIRS, 0), "Smooth Quartz Stairs", $quartzBreakInfo)); - $this->register(new Rail(new BID(Ids::RAIL), "Rail")); - $this->register(new RedMushroom(new BID(Ids::RED_MUSHROOM), "Red Mushroom")); - $this->register(new Redstone(new BID(Ids::REDSTONE_BLOCK), "Redstone Block")); + $this->register(new Rail(new BID(Ids::RAIL, 0), "Rail")); + $this->register(new RedMushroom(new BID(Ids::RED_MUSHROOM, 0), "Red Mushroom")); + $this->register(new Redstone(new BID(Ids::REDSTONE_BLOCK, 0), "Redstone Block")); $this->register(new RedstoneComparator(new BIDFlattened(Ids::UNPOWERED_COMPARATOR, Ids::POWERED_COMPARATOR, 0, ItemIds::COMPARATOR, TileComparator::class), "Redstone Comparator")); - $this->register(new RedstoneLamp(new BIDFlattened(Ids::REDSTONE_LAMP, Ids::LIT_REDSTONE_LAMP), "Redstone Lamp")); - $this->register(new RedstoneOre(new BIDFlattened(Ids::REDSTONE_ORE, Ids::LIT_REDSTONE_ORE), "Redstone Ore")); + $this->register(new RedstoneLamp(new BIDFlattened(Ids::REDSTONE_LAMP, Ids::LIT_REDSTONE_LAMP, 0), "Redstone Lamp")); + $this->register(new RedstoneOre(new BIDFlattened(Ids::REDSTONE_ORE, Ids::LIT_REDSTONE_ORE, 0), "Redstone Ore")); $this->register(new RedstoneRepeater(new BIDFlattened(Ids::UNPOWERED_REPEATER, Ids::POWERED_REPEATER, 0, ItemIds::REPEATER), "Redstone Repeater")); - $this->register(new RedstoneTorch(new BIDFlattened(Ids::REDSTONE_TORCH, Ids::UNLIT_REDSTONE_TORCH), "Redstone Torch")); + $this->register(new RedstoneTorch(new BIDFlattened(Ids::REDSTONE_TORCH, Ids::UNLIT_REDSTONE_TORCH, 0), "Redstone Torch")); $this->register(new RedstoneWire(new BID(Ids::REDSTONE_WIRE, 0, ItemIds::REDSTONE), "Redstone")); - $this->register(new Reserved6(new BID(Ids::RESERVED6), "reserved6")); - $this->register(new Sand(new BID(Ids::SAND), "Sand")); + $this->register(new Reserved6(new BID(Ids::RESERVED6, 0), "reserved6")); + $this->register(new Sand(new BID(Ids::SAND, 0), "Sand")); $this->register(new Sand(new BID(Ids::SAND, 1), "Red Sand")); - $this->register(new SeaLantern(new BID(Ids::SEALANTERN), "Sea Lantern")); - $this->register(new SeaPickle(new BID(Ids::SEA_PICKLE), "Sea Pickle")); + $this->register(new SeaLantern(new BID(Ids::SEALANTERN, 0), "Sea Lantern")); + $this->register(new SeaPickle(new BID(Ids::SEA_PICKLE, 0), "Sea Pickle")); $this->register(new Skull(new BID(Ids::MOB_HEAD_BLOCK, 0, null, TileSkull::class), "Mob Head")); - $this->register(new Snow(new BID(Ids::SNOW), "Snow Block")); - $this->register(new SnowLayer(new BID(Ids::SNOW_LAYER), "Snow Layer")); - $this->register(new SoulSand(new BID(Ids::SOUL_SAND), "Soul Sand")); - $this->register(new Sponge(new BID(Ids::SPONGE), "Sponge")); + $this->register(new Snow(new BID(Ids::SNOW, 0), "Snow Block")); + $this->register(new SnowLayer(new BID(Ids::SNOW_LAYER, 0), "Snow Layer")); + $this->register(new SoulSand(new BID(Ids::SOUL_SAND, 0), "Soul Sand")); + $this->register(new Sponge(new BID(Ids::SPONGE, 0), "Sponge")); $stoneBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); $this->register($stone = new class(new BID(Ids::STONE, Meta::STONE_NORMAL), "Stone", $stoneBreakInfo) extends Opaque{ @@ -307,32 +307,32 @@ class BlockFactory{ } }); $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE), "Infested Stone", $stone)); - $this->register(new Stair(new BID(Ids::NORMAL_STONE_STAIRS), "Stone Stairs", $stoneBreakInfo)); - $this->register(new Opaque(new BID(Ids::SMOOTH_STONE), "Smooth Stone", $stoneBreakInfo)); + $this->register(new Stair(new BID(Ids::NORMAL_STONE_STAIRS, 0), "Stone Stairs", $stoneBreakInfo)); + $this->register(new Opaque(new BID(Ids::SMOOTH_STONE, 0), "Smooth Stone", $stoneBreakInfo)); $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_ANDESITE), "Andesite", $stoneBreakInfo)); - $this->register(new Stair(new BID(Ids::ANDESITE_STAIRS), "Andesite Stairs", $stoneBreakInfo)); + $this->register(new Stair(new BID(Ids::ANDESITE_STAIRS, 0), "Andesite Stairs", $stoneBreakInfo)); $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_DIORITE), "Diorite", $stoneBreakInfo)); - $this->register(new Stair(new BID(Ids::DIORITE_STAIRS), "Diorite Stairs", $stoneBreakInfo)); + $this->register(new Stair(new BID(Ids::DIORITE_STAIRS, 0), "Diorite Stairs", $stoneBreakInfo)); $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_GRANITE), "Granite", $stoneBreakInfo)); - $this->register(new Stair(new BID(Ids::GRANITE_STAIRS), "Granite Stairs", $stoneBreakInfo)); + $this->register(new Stair(new BID(Ids::GRANITE_STAIRS, 0), "Granite Stairs", $stoneBreakInfo)); $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_ANDESITE), "Polished Andesite", $stoneBreakInfo)); - $this->register(new Stair(new BID(Ids::POLISHED_ANDESITE_STAIRS), "Polished Andesite Stairs", $stoneBreakInfo)); + $this->register(new Stair(new BID(Ids::POLISHED_ANDESITE_STAIRS, 0), "Polished Andesite Stairs", $stoneBreakInfo)); $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_DIORITE), "Polished Diorite", $stoneBreakInfo)); - $this->register(new Stair(new BID(Ids::POLISHED_DIORITE_STAIRS), "Polished Diorite Stairs", $stoneBreakInfo)); + $this->register(new Stair(new BID(Ids::POLISHED_DIORITE_STAIRS, 0), "Polished Diorite Stairs", $stoneBreakInfo)); $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_GRANITE), "Polished Granite", $stoneBreakInfo)); - $this->register(new Stair(new BID(Ids::POLISHED_GRANITE_STAIRS), "Polished Granite Stairs", $stoneBreakInfo)); - $this->register(new Stair(new BID(Ids::STONE_BRICK_STAIRS), "Stone Brick Stairs", $stoneBreakInfo)); + $this->register(new Stair(new BID(Ids::POLISHED_GRANITE_STAIRS, 0), "Polished Granite Stairs", $stoneBreakInfo)); + $this->register(new Stair(new BID(Ids::STONE_BRICK_STAIRS, 0), "Stone Brick Stairs", $stoneBreakInfo)); $this->register($chiseledStoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CHISELED), "Chiseled Stone Bricks", $stoneBreakInfo)); $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CHISELED), "Infested Chiseled Stone Brick", $chiseledStoneBrick)); $this->register($crackedStoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CRACKED), "Cracked Stone Bricks", $stoneBreakInfo)); $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CRACKED), "Infested Cracked Stone Brick", $crackedStoneBrick)); $this->register($mossyStoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_MOSSY), "Mossy Stone Bricks", $stoneBreakInfo)); $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_MOSSY), "Infested Mossy Stone Brick", $mossyStoneBrick)); - $this->register(new Stair(new BID(Ids::MOSSY_STONE_BRICK_STAIRS), "Mossy Stone Brick Stairs", $stoneBreakInfo)); + $this->register(new Stair(new BID(Ids::MOSSY_STONE_BRICK_STAIRS, 0), "Mossy Stone Brick Stairs", $stoneBreakInfo)); $this->register($stoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_NORMAL), "Stone Bricks", $stoneBreakInfo)); $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK), "Infested Stone Brick", $stoneBrick)); - $this->register(new StoneButton(new BID(Ids::STONE_BUTTON), "Stone Button")); - $this->register(new StonePressurePlate(new BID(Ids::STONE_PRESSURE_PLATE), "Stone Pressure Plate")); + $this->register(new StoneButton(new BID(Ids::STONE_BUTTON, 0), "Stone Button")); + $this->register(new StonePressurePlate(new BID(Ids::STONE_PRESSURE_PLATE, 0), "Stone Pressure Plate")); //TODO: in the future this won't be the same for all the types $stoneSlabBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); @@ -365,30 +365,30 @@ class BlockFactory{ $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_MOSSY_STONE_BRICK), "Mossy Stone Brick", $stoneSlabBreakInfo)); $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_SMOOTH_QUARTZ), "Smooth Quartz", $stoneSlabBreakInfo)); $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_STONE), "Stone", $stoneSlabBreakInfo)); - $this->register(new Opaque(new BID(Ids::STONECUTTER), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->register(new Opaque(new BID(Ids::STONECUTTER, 0), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); $this->register(new Sugarcane(new BID(Ids::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane")); - $this->register(new TNT(new BID(Ids::TNT), "TNT")); + $this->register(new TNT(new BID(Ids::TNT, 0), "TNT")); $fern = new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_FERN), "Fern"); $this->register($fern); $this->remap(Ids::TALLGRASS, 0, $fern); $this->remap(Ids::TALLGRASS, 3, $fern); $this->register(new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_NORMAL), "Tall Grass")); - $this->register(new Torch(new BID(Ids::COLORED_TORCH_BP), "Blue Torch")); + $this->register(new Torch(new BID(Ids::COLORED_TORCH_BP, 0), "Blue Torch")); $this->register(new Torch(new BID(Ids::COLORED_TORCH_BP, 8), "Purple Torch")); - $this->register(new Torch(new BID(Ids::COLORED_TORCH_RG), "Red Torch")); + $this->register(new Torch(new BID(Ids::COLORED_TORCH_RG, 0), "Red Torch")); $this->register(new Torch(new BID(Ids::COLORED_TORCH_RG, 8), "Green Torch")); - $this->register(new Torch(new BID(Ids::TORCH), "Torch")); + $this->register(new Torch(new BID(Ids::TORCH, 0), "Torch")); $this->register(new TrappedChest(new BID(Ids::TRAPPED_CHEST, 0, null, TileChest::class), "Trapped Chest")); $this->register(new Tripwire(new BID(Ids::TRIPWIRE, 0, ItemIds::STRING), "Tripwire")); - $this->register(new TripwireHook(new BID(Ids::TRIPWIRE_HOOK), "Tripwire Hook")); - $this->register(new UnderwaterTorch(new BID(Ids::UNDERWATER_TORCH), "Underwater Torch")); - $this->register(new Vine(new BID(Ids::VINE), "Vines")); - $this->register(new Water(new BIDFlattened(Ids::FLOWING_WATER, Ids::STILL_WATER), "Water")); - $this->register(new WaterLily(new BID(Ids::LILY_PAD), "Lily Pad")); - $this->register(new WeightedPressurePlateHeavy(new BID(Ids::HEAVY_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Heavy")); - $this->register(new WeightedPressurePlateLight(new BID(Ids::LIGHT_WEIGHTED_PRESSURE_PLATE), "Weighted Pressure Plate Light")); - $this->register(new Wheat(new BID(Ids::WHEAT_BLOCK), "Wheat Block")); + $this->register(new TripwireHook(new BID(Ids::TRIPWIRE_HOOK, 0), "Tripwire Hook")); + $this->register(new UnderwaterTorch(new BID(Ids::UNDERWATER_TORCH, 0), "Underwater Torch")); + $this->register(new Vine(new BID(Ids::VINE, 0), "Vines")); + $this->register(new Water(new BIDFlattened(Ids::FLOWING_WATER, Ids::STILL_WATER, 0), "Water")); + $this->register(new WaterLily(new BID(Ids::LILY_PAD, 0), "Lily Pad")); + $this->register(new WeightedPressurePlateHeavy(new BID(Ids::HEAVY_WEIGHTED_PRESSURE_PLATE, 0), "Weighted Pressure Plate Heavy")); + $this->register(new WeightedPressurePlateLight(new BID(Ids::LIGHT_WEIGHTED_PRESSURE_PLATE, 0), "Weighted Pressure Plate Light")); + $this->register(new Wheat(new BID(Ids::WHEAT_BLOCK, 0), "Wheat Block")); foreach(TreeType::getAll() as $treeType){ $magicNumber = $treeType->getMagicNumber(); @@ -425,10 +425,10 @@ class BlockFactory{ Meta::SANDSTONE_SMOOTH => "Smooth " ]; $sandstoneBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()); - $this->register(new Stair(new BID(Ids::RED_SANDSTONE_STAIRS), "Red Sandstone Stairs", $sandstoneBreakInfo)); - $this->register(new Stair(new BID(Ids::SMOOTH_RED_SANDSTONE_STAIRS), "Smooth Red Sandstone Stairs", $sandstoneBreakInfo)); - $this->register(new Stair(new BID(Ids::SANDSTONE_STAIRS), "Sandstone Stairs", $sandstoneBreakInfo)); - $this->register(new Stair(new BID(Ids::SMOOTH_SANDSTONE_STAIRS), "Smooth Sandstone Stairs", $sandstoneBreakInfo)); + $this->register(new Stair(new BID(Ids::RED_SANDSTONE_STAIRS, 0), "Red Sandstone Stairs", $sandstoneBreakInfo)); + $this->register(new Stair(new BID(Ids::SMOOTH_RED_SANDSTONE_STAIRS, 0), "Smooth Red Sandstone Stairs", $sandstoneBreakInfo)); + $this->register(new Stair(new BID(Ids::SANDSTONE_STAIRS, 0), "Sandstone Stairs", $sandstoneBreakInfo)); + $this->register(new Stair(new BID(Ids::SMOOTH_SANDSTONE_STAIRS, 0), "Smooth Sandstone Stairs", $sandstoneBreakInfo)); foreach($sandstoneTypes as $variant => $prefix){ $this->register(new Opaque(new BID(Ids::SANDSTONE, $variant), $prefix . "Sandstone", $sandstoneBreakInfo)); $this->register(new Opaque(new BID(Ids::RED_SANDSTONE, $variant), $prefix . "Red Sandstone", $sandstoneBreakInfo)); @@ -446,10 +446,10 @@ class BlockFactory{ $this->register(new HardenedGlass(new BID(Ids::HARD_STAINED_GLASS, $colorIdMap->toId($color)), "Hardened " . $coloredName("Stained Glass"))); $this->register(new HardenedGlassPane(new BID(Ids::HARD_STAINED_GLASS_PANE, $colorIdMap->toId($color)), "Hardened " . $coloredName("Stained Glass Pane"))); } - $this->register(new Carpet(new BID(Ids::CARPET), "Carpet")); - $this->register(new Concrete(new BID(Ids::CONCRETE), "Concrete")); - $this->register(new ConcretePowder(new BID(Ids::CONCRETE_POWDER), "Concrete Powder")); - $this->register(new Wool(new BID(Ids::WOOL), "Wool")); + $this->register(new Carpet(new BID(Ids::CARPET, 0), "Carpet")); + $this->register(new Concrete(new BID(Ids::CONCRETE, 0), "Concrete")); + $this->register(new ConcretePowder(new BID(Ids::CONCRETE_POWDER, 0), "Concrete Powder")); + $this->register(new Wool(new BID(Ids::WOOL, 0), "Wool")); $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_ANDESITE), "Andesite Wall")); $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_BRICK), "Brick Wall")); @@ -474,7 +474,7 @@ class BlockFactory{ $this->register(new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_LAB_TABLE), "Lab Table", $chemistryTableBreakInfo)); $this->register(new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_MATERIAL_REDUCER), "Material Reducer", $chemistryTableBreakInfo)); - $this->register(new ChemicalHeat(new BID(Ids::CHEMICAL_HEAT), "Heat Block", $chemistryTableBreakInfo)); + $this->register(new ChemicalHeat(new BID(Ids::CHEMICAL_HEAT, 0), "Heat Block", $chemistryTableBreakInfo)); $this->registerMushroomBlocks(); @@ -645,8 +645,8 @@ class BlockFactory{ $mushroomBlockBreakInfo = new BlockBreakInfo(0.2, BlockToolType::AXE); $mushroomBlocks = [ - new BrownMushroomBlock(new BID(Ids::BROWN_MUSHROOM_BLOCK), "Brown Mushroom Block", $mushroomBlockBreakInfo), - new RedMushroomBlock(new BID(Ids::RED_MUSHROOM_BLOCK), "Red Mushroom Block", $mushroomBlockBreakInfo) + new BrownMushroomBlock(new BID(Ids::BROWN_MUSHROOM_BLOCK, 0), "Brown Mushroom Block", $mushroomBlockBreakInfo), + new RedMushroomBlock(new BID(Ids::RED_MUSHROOM_BLOCK, 0), "Red Mushroom Block", $mushroomBlockBreakInfo) ]; //caps @@ -687,126 +687,126 @@ class BlockFactory{ private function registerElements() : void{ $instaBreak = BlockBreakInfo::instant(); - $this->register(new Opaque(new BID(Ids::ELEMENT_0), "???", $instaBreak)); + $this->register(new Opaque(new BID(Ids::ELEMENT_0, 0), "???", $instaBreak)); - $this->register(new Element(new BID(Ids::ELEMENT_1), "Hydrogen", $instaBreak, "h", 1, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_2), "Helium", $instaBreak, "he", 2, 7)); - $this->register(new Element(new BID(Ids::ELEMENT_3), "Lithium", $instaBreak, "li", 3, 0)); - $this->register(new Element(new BID(Ids::ELEMENT_4), "Beryllium", $instaBreak, "be", 4, 1)); - $this->register(new Element(new BID(Ids::ELEMENT_5), "Boron", $instaBreak, "b", 5, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_6), "Carbon", $instaBreak, "c", 6, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_7), "Nitrogen", $instaBreak, "n", 7, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_8), "Oxygen", $instaBreak, "o", 8, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_9), "Fluorine", $instaBreak, "f", 9, 6)); - $this->register(new Element(new BID(Ids::ELEMENT_10), "Neon", $instaBreak, "ne", 10, 7)); - $this->register(new Element(new BID(Ids::ELEMENT_11), "Sodium", $instaBreak, "na", 11, 0)); - $this->register(new Element(new BID(Ids::ELEMENT_12), "Magnesium", $instaBreak, "mg", 12, 1)); - $this->register(new Element(new BID(Ids::ELEMENT_13), "Aluminum", $instaBreak, "al", 13, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_14), "Silicon", $instaBreak, "si", 14, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_15), "Phosphorus", $instaBreak, "p", 15, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_16), "Sulfur", $instaBreak, "s", 16, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_17), "Chlorine", $instaBreak, "cl", 17, 6)); - $this->register(new Element(new BID(Ids::ELEMENT_18), "Argon", $instaBreak, "ar", 18, 7)); - $this->register(new Element(new BID(Ids::ELEMENT_19), "Potassium", $instaBreak, "k", 19, 0)); - $this->register(new Element(new BID(Ids::ELEMENT_20), "Calcium", $instaBreak, "ca", 20, 1)); - $this->register(new Element(new BID(Ids::ELEMENT_21), "Scandium", $instaBreak, "sc", 21, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_22), "Titanium", $instaBreak, "ti", 22, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_23), "Vanadium", $instaBreak, "v", 23, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_24), "Chromium", $instaBreak, "cr", 24, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_25), "Manganese", $instaBreak, "mn", 25, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_26), "Iron", $instaBreak, "fe", 26, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_27), "Cobalt", $instaBreak, "co", 27, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_28), "Nickel", $instaBreak, "ni", 28, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_29), "Copper", $instaBreak, "cu", 29, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_30), "Zinc", $instaBreak, "zn", 30, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_31), "Gallium", $instaBreak, "ga", 31, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_32), "Germanium", $instaBreak, "ge", 32, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_33), "Arsenic", $instaBreak, "as", 33, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_34), "Selenium", $instaBreak, "se", 34, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_35), "Bromine", $instaBreak, "br", 35, 6)); - $this->register(new Element(new BID(Ids::ELEMENT_36), "Krypton", $instaBreak, "kr", 36, 7)); - $this->register(new Element(new BID(Ids::ELEMENT_37), "Rubidium", $instaBreak, "rb", 37, 0)); - $this->register(new Element(new BID(Ids::ELEMENT_38), "Strontium", $instaBreak, "sr", 38, 1)); - $this->register(new Element(new BID(Ids::ELEMENT_39), "Yttrium", $instaBreak, "y", 39, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_40), "Zirconium", $instaBreak, "zr", 40, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_41), "Niobium", $instaBreak, "nb", 41, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_42), "Molybdenum", $instaBreak, "mo", 42, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_43), "Technetium", $instaBreak, "tc", 43, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_44), "Ruthenium", $instaBreak, "ru", 44, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_45), "Rhodium", $instaBreak, "rh", 45, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_46), "Palladium", $instaBreak, "pd", 46, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_47), "Silver", $instaBreak, "ag", 47, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_48), "Cadmium", $instaBreak, "cd", 48, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_49), "Indium", $instaBreak, "in", 49, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_50), "Tin", $instaBreak, "sn", 50, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_51), "Antimony", $instaBreak, "sb", 51, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_52), "Tellurium", $instaBreak, "te", 52, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_53), "Iodine", $instaBreak, "i", 53, 6)); - $this->register(new Element(new BID(Ids::ELEMENT_54), "Xenon", $instaBreak, "xe", 54, 7)); - $this->register(new Element(new BID(Ids::ELEMENT_55), "Cesium", $instaBreak, "cs", 55, 0)); - $this->register(new Element(new BID(Ids::ELEMENT_56), "Barium", $instaBreak, "ba", 56, 1)); - $this->register(new Element(new BID(Ids::ELEMENT_57), "Lanthanum", $instaBreak, "la", 57, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_58), "Cerium", $instaBreak, "ce", 58, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_59), "Praseodymium", $instaBreak, "pr", 59, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_60), "Neodymium", $instaBreak, "nd", 60, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_61), "Promethium", $instaBreak, "pm", 61, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_62), "Samarium", $instaBreak, "sm", 62, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_63), "Europium", $instaBreak, "eu", 63, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_64), "Gadolinium", $instaBreak, "gd", 64, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_65), "Terbium", $instaBreak, "tb", 65, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_66), "Dysprosium", $instaBreak, "dy", 66, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_67), "Holmium", $instaBreak, "ho", 67, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_68), "Erbium", $instaBreak, "er", 68, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_69), "Thulium", $instaBreak, "tm", 69, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_70), "Ytterbium", $instaBreak, "yb", 70, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_71), "Lutetium", $instaBreak, "lu", 71, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_72), "Hafnium", $instaBreak, "hf", 72, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_73), "Tantalum", $instaBreak, "ta", 73, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_74), "Tungsten", $instaBreak, "w", 74, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_75), "Rhenium", $instaBreak, "re", 75, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_76), "Osmium", $instaBreak, "os", 76, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_77), "Iridium", $instaBreak, "ir", 77, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_78), "Platinum", $instaBreak, "pt", 78, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_79), "Gold", $instaBreak, "au", 79, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_80), "Mercury", $instaBreak, "hg", 80, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_81), "Thallium", $instaBreak, "tl", 81, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_82), "Lead", $instaBreak, "pb", 82, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_83), "Bismuth", $instaBreak, "bi", 83, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_84), "Polonium", $instaBreak, "po", 84, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_85), "Astatine", $instaBreak, "at", 85, 6)); - $this->register(new Element(new BID(Ids::ELEMENT_86), "Radon", $instaBreak, "rn", 86, 7)); - $this->register(new Element(new BID(Ids::ELEMENT_87), "Francium", $instaBreak, "fr", 87, 0)); - $this->register(new Element(new BID(Ids::ELEMENT_88), "Radium", $instaBreak, "ra", 88, 1)); - $this->register(new Element(new BID(Ids::ELEMENT_89), "Actinium", $instaBreak, "ac", 89, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_90), "Thorium", $instaBreak, "th", 90, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_91), "Protactinium", $instaBreak, "pa", 91, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_92), "Uranium", $instaBreak, "u", 92, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_93), "Neptunium", $instaBreak, "np", 93, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_94), "Plutonium", $instaBreak, "pu", 94, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_95), "Americium", $instaBreak, "am", 95, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_96), "Curium", $instaBreak, "cm", 96, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_97), "Berkelium", $instaBreak, "bk", 97, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_98), "Californium", $instaBreak, "cf", 98, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_99), "Einsteinium", $instaBreak, "es", 99, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_100), "Fermium", $instaBreak, "fm", 100, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_101), "Mendelevium", $instaBreak, "md", 101, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_102), "Nobelium", $instaBreak, "no", 102, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_103), "Lawrencium", $instaBreak, "lr", 103, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_104), "Rutherfordium", $instaBreak, "rf", 104, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_105), "Dubnium", $instaBreak, "db", 105, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_106), "Seaborgium", $instaBreak, "sg", 106, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_107), "Bohrium", $instaBreak, "bh", 107, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_108), "Hassium", $instaBreak, "hs", 108, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_109), "Meitnerium", $instaBreak, "mt", 109, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_110), "Darmstadtium", $instaBreak, "ds", 110, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_111), "Roentgenium", $instaBreak, "rg", 111, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_112), "Copernicium", $instaBreak, "cn", 112, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_113), "Nihonium", $instaBreak, "nh", 113, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_114), "Flerovium", $instaBreak, "fl", 114, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_115), "Moscovium", $instaBreak, "mc", 115, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_116), "Livermorium", $instaBreak, "lv", 116, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_117), "Tennessine", $instaBreak, "ts", 117, 6)); - $this->register(new Element(new BID(Ids::ELEMENT_118), "Oganesson", $instaBreak, "og", 118, 7)); + $this->register(new Element(new BID(Ids::ELEMENT_1, 0), "Hydrogen", $instaBreak, "h", 1, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_2, 0), "Helium", $instaBreak, "he", 2, 7)); + $this->register(new Element(new BID(Ids::ELEMENT_3, 0), "Lithium", $instaBreak, "li", 3, 0)); + $this->register(new Element(new BID(Ids::ELEMENT_4, 0), "Beryllium", $instaBreak, "be", 4, 1)); + $this->register(new Element(new BID(Ids::ELEMENT_5, 0), "Boron", $instaBreak, "b", 5, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_6, 0), "Carbon", $instaBreak, "c", 6, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_7, 0), "Nitrogen", $instaBreak, "n", 7, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_8, 0), "Oxygen", $instaBreak, "o", 8, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_9, 0), "Fluorine", $instaBreak, "f", 9, 6)); + $this->register(new Element(new BID(Ids::ELEMENT_10, 0), "Neon", $instaBreak, "ne", 10, 7)); + $this->register(new Element(new BID(Ids::ELEMENT_11, 0), "Sodium", $instaBreak, "na", 11, 0)); + $this->register(new Element(new BID(Ids::ELEMENT_12, 0), "Magnesium", $instaBreak, "mg", 12, 1)); + $this->register(new Element(new BID(Ids::ELEMENT_13, 0), "Aluminum", $instaBreak, "al", 13, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_14, 0), "Silicon", $instaBreak, "si", 14, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_15, 0), "Phosphorus", $instaBreak, "p", 15, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_16, 0), "Sulfur", $instaBreak, "s", 16, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_17, 0), "Chlorine", $instaBreak, "cl", 17, 6)); + $this->register(new Element(new BID(Ids::ELEMENT_18, 0), "Argon", $instaBreak, "ar", 18, 7)); + $this->register(new Element(new BID(Ids::ELEMENT_19, 0), "Potassium", $instaBreak, "k", 19, 0)); + $this->register(new Element(new BID(Ids::ELEMENT_20, 0), "Calcium", $instaBreak, "ca", 20, 1)); + $this->register(new Element(new BID(Ids::ELEMENT_21, 0), "Scandium", $instaBreak, "sc", 21, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_22, 0), "Titanium", $instaBreak, "ti", 22, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_23, 0), "Vanadium", $instaBreak, "v", 23, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_24, 0), "Chromium", $instaBreak, "cr", 24, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_25, 0), "Manganese", $instaBreak, "mn", 25, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_26, 0), "Iron", $instaBreak, "fe", 26, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_27, 0), "Cobalt", $instaBreak, "co", 27, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_28, 0), "Nickel", $instaBreak, "ni", 28, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_29, 0), "Copper", $instaBreak, "cu", 29, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_30, 0), "Zinc", $instaBreak, "zn", 30, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_31, 0), "Gallium", $instaBreak, "ga", 31, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_32, 0), "Germanium", $instaBreak, "ge", 32, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_33, 0), "Arsenic", $instaBreak, "as", 33, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_34, 0), "Selenium", $instaBreak, "se", 34, 5)); + $this->register(new Element(new BID(Ids::ELEMENT_35, 0), "Bromine", $instaBreak, "br", 35, 6)); + $this->register(new Element(new BID(Ids::ELEMENT_36, 0), "Krypton", $instaBreak, "kr", 36, 7)); + $this->register(new Element(new BID(Ids::ELEMENT_37, 0), "Rubidium", $instaBreak, "rb", 37, 0)); + $this->register(new Element(new BID(Ids::ELEMENT_38, 0), "Strontium", $instaBreak, "sr", 38, 1)); + $this->register(new Element(new BID(Ids::ELEMENT_39, 0), "Yttrium", $instaBreak, "y", 39, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_40, 0), "Zirconium", $instaBreak, "zr", 40, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_41, 0), "Niobium", $instaBreak, "nb", 41, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_42, 0), "Molybdenum", $instaBreak, "mo", 42, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_43, 0), "Technetium", $instaBreak, "tc", 43, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_44, 0), "Ruthenium", $instaBreak, "ru", 44, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_45, 0), "Rhodium", $instaBreak, "rh", 45, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_46, 0), "Palladium", $instaBreak, "pd", 46, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_47, 0), "Silver", $instaBreak, "ag", 47, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_48, 0), "Cadmium", $instaBreak, "cd", 48, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_49, 0), "Indium", $instaBreak, "in", 49, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_50, 0), "Tin", $instaBreak, "sn", 50, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_51, 0), "Antimony", $instaBreak, "sb", 51, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_52, 0), "Tellurium", $instaBreak, "te", 52, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_53, 0), "Iodine", $instaBreak, "i", 53, 6)); + $this->register(new Element(new BID(Ids::ELEMENT_54, 0), "Xenon", $instaBreak, "xe", 54, 7)); + $this->register(new Element(new BID(Ids::ELEMENT_55, 0), "Cesium", $instaBreak, "cs", 55, 0)); + $this->register(new Element(new BID(Ids::ELEMENT_56, 0), "Barium", $instaBreak, "ba", 56, 1)); + $this->register(new Element(new BID(Ids::ELEMENT_57, 0), "Lanthanum", $instaBreak, "la", 57, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_58, 0), "Cerium", $instaBreak, "ce", 58, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_59, 0), "Praseodymium", $instaBreak, "pr", 59, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_60, 0), "Neodymium", $instaBreak, "nd", 60, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_61, 0), "Promethium", $instaBreak, "pm", 61, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_62, 0), "Samarium", $instaBreak, "sm", 62, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_63, 0), "Europium", $instaBreak, "eu", 63, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_64, 0), "Gadolinium", $instaBreak, "gd", 64, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_65, 0), "Terbium", $instaBreak, "tb", 65, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_66, 0), "Dysprosium", $instaBreak, "dy", 66, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_67, 0), "Holmium", $instaBreak, "ho", 67, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_68, 0), "Erbium", $instaBreak, "er", 68, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_69, 0), "Thulium", $instaBreak, "tm", 69, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_70, 0), "Ytterbium", $instaBreak, "yb", 70, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_71, 0), "Lutetium", $instaBreak, "lu", 71, 8)); + $this->register(new Element(new BID(Ids::ELEMENT_72, 0), "Hafnium", $instaBreak, "hf", 72, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_73, 0), "Tantalum", $instaBreak, "ta", 73, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_74, 0), "Tungsten", $instaBreak, "w", 74, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_75, 0), "Rhenium", $instaBreak, "re", 75, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_76, 0), "Osmium", $instaBreak, "os", 76, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_77, 0), "Iridium", $instaBreak, "ir", 77, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_78, 0), "Platinum", $instaBreak, "pt", 78, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_79, 0), "Gold", $instaBreak, "au", 79, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_80, 0), "Mercury", $instaBreak, "hg", 80, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_81, 0), "Thallium", $instaBreak, "tl", 81, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_82, 0), "Lead", $instaBreak, "pb", 82, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_83, 0), "Bismuth", $instaBreak, "bi", 83, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_84, 0), "Polonium", $instaBreak, "po", 84, 4)); + $this->register(new Element(new BID(Ids::ELEMENT_85, 0), "Astatine", $instaBreak, "at", 85, 6)); + $this->register(new Element(new BID(Ids::ELEMENT_86, 0), "Radon", $instaBreak, "rn", 86, 7)); + $this->register(new Element(new BID(Ids::ELEMENT_87, 0), "Francium", $instaBreak, "fr", 87, 0)); + $this->register(new Element(new BID(Ids::ELEMENT_88, 0), "Radium", $instaBreak, "ra", 88, 1)); + $this->register(new Element(new BID(Ids::ELEMENT_89, 0), "Actinium", $instaBreak, "ac", 89, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_90, 0), "Thorium", $instaBreak, "th", 90, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_91, 0), "Protactinium", $instaBreak, "pa", 91, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_92, 0), "Uranium", $instaBreak, "u", 92, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_93, 0), "Neptunium", $instaBreak, "np", 93, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_94, 0), "Plutonium", $instaBreak, "pu", 94, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_95, 0), "Americium", $instaBreak, "am", 95, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_96, 0), "Curium", $instaBreak, "cm", 96, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_97, 0), "Berkelium", $instaBreak, "bk", 97, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_98, 0), "Californium", $instaBreak, "cf", 98, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_99, 0), "Einsteinium", $instaBreak, "es", 99, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_100, 0), "Fermium", $instaBreak, "fm", 100, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_101, 0), "Mendelevium", $instaBreak, "md", 101, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_102, 0), "Nobelium", $instaBreak, "no", 102, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_103, 0), "Lawrencium", $instaBreak, "lr", 103, 9)); + $this->register(new Element(new BID(Ids::ELEMENT_104, 0), "Rutherfordium", $instaBreak, "rf", 104, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_105, 0), "Dubnium", $instaBreak, "db", 105, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_106, 0), "Seaborgium", $instaBreak, "sg", 106, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_107, 0), "Bohrium", $instaBreak, "bh", 107, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_108, 0), "Hassium", $instaBreak, "hs", 108, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_109, 0), "Meitnerium", $instaBreak, "mt", 109, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_110, 0), "Darmstadtium", $instaBreak, "ds", 110, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_111, 0), "Roentgenium", $instaBreak, "rg", 111, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_112, 0), "Copernicium", $instaBreak, "cn", 112, 2)); + $this->register(new Element(new BID(Ids::ELEMENT_113, 0), "Nihonium", $instaBreak, "nh", 113, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_114, 0), "Flerovium", $instaBreak, "fl", 114, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_115, 0), "Moscovium", $instaBreak, "mc", 115, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_116, 0), "Livermorium", $instaBreak, "lv", 116, 3)); + $this->register(new Element(new BID(Ids::ELEMENT_117, 0), "Tennessine", $instaBreak, "ts", 117, 6)); + $this->register(new Element(new BID(Ids::ELEMENT_118, 0), "Oganesson", $instaBreak, "og", 118, 7)); } /** diff --git a/src/block/BlockIdentifier.php b/src/block/BlockIdentifier.php index 1df7d942c0..5b96066430 100644 --- a/src/block/BlockIdentifier.php +++ b/src/block/BlockIdentifier.php @@ -42,7 +42,7 @@ class BlockIdentifier{ /** * @phpstan-param class-string|null $tileClass */ - public function __construct(int $blockId, int $variant = 0, ?int $itemId = null, ?string $tileClass = null){ + public function __construct(int $blockId, int $variant, ?int $itemId = null, ?string $tileClass = null){ $this->blockId = $blockId; $this->variant = $variant; $this->itemId = $itemId; diff --git a/src/block/BlockIdentifierFlattened.php b/src/block/BlockIdentifierFlattened.php index f22c801d71..c3d8278b13 100644 --- a/src/block/BlockIdentifierFlattened.php +++ b/src/block/BlockIdentifierFlattened.php @@ -28,7 +28,7 @@ class BlockIdentifierFlattened extends BlockIdentifier{ /** @var int */ private $secondId; - public function __construct(int $blockId, int $secondId, int $variant = 0, ?int $itemId = null, ?string $tileClass = null){ + public function __construct(int $blockId, int $secondId, int $variant, ?int $itemId = null, ?string $tileClass = null){ parent::__construct($blockId, $variant, $itemId, $tileClass); $this->secondId = $secondId; } diff --git a/src/block/BlockLegacyIdHelper.php b/src/block/BlockLegacyIdHelper.php index 2b32e56f73..7dec143ce8 100644 --- a/src/block/BlockLegacyIdHelper.php +++ b/src/block/BlockLegacyIdHelper.php @@ -72,17 +72,17 @@ final class BlockLegacyIdHelper{ public static function getWoodenTrapdoorIdentifier(TreeType $treeType) : BlockIdentifier{ switch($treeType->id()){ case TreeType::OAK()->id(): - return new BlockIdentifier(Ids::WOODEN_TRAPDOOR); + return new BlockIdentifier(Ids::WOODEN_TRAPDOOR, 0); case TreeType::SPRUCE()->id(): - return new BlockIdentifier(Ids::SPRUCE_TRAPDOOR); + return new BlockIdentifier(Ids::SPRUCE_TRAPDOOR, 0); case TreeType::BIRCH()->id(): - return new BlockIdentifier(Ids::BIRCH_TRAPDOOR); + return new BlockIdentifier(Ids::BIRCH_TRAPDOOR, 0); case TreeType::JUNGLE()->id(): - return new BlockIdentifier(Ids::JUNGLE_TRAPDOOR); + return new BlockIdentifier(Ids::JUNGLE_TRAPDOOR, 0); case TreeType::ACACIA()->id(): - return new BlockIdentifier(Ids::ACACIA_TRAPDOOR); + return new BlockIdentifier(Ids::ACACIA_TRAPDOOR, 0); case TreeType::DARK_OAK()->id(): - return new BlockIdentifier(Ids::DARK_OAK_TRAPDOOR); + return new BlockIdentifier(Ids::DARK_OAK_TRAPDOOR, 0); } throw new AssumptionFailedError("Switch should cover all wood types"); } @@ -90,17 +90,17 @@ final class BlockLegacyIdHelper{ public static function getWoodenButtonIdentifier(TreeType $treeType) : BlockIdentifier{ switch($treeType->id()){ case TreeType::OAK()->id(): - return new BlockIdentifier(Ids::WOODEN_BUTTON); + return new BlockIdentifier(Ids::WOODEN_BUTTON, 0); case TreeType::SPRUCE()->id(): - return new BlockIdentifier(Ids::SPRUCE_BUTTON); + return new BlockIdentifier(Ids::SPRUCE_BUTTON, 0); case TreeType::BIRCH()->id(): - return new BlockIdentifier(Ids::BIRCH_BUTTON); + return new BlockIdentifier(Ids::BIRCH_BUTTON, 0); case TreeType::JUNGLE()->id(): - return new BlockIdentifier(Ids::JUNGLE_BUTTON); + return new BlockIdentifier(Ids::JUNGLE_BUTTON, 0); case TreeType::ACACIA()->id(): - return new BlockIdentifier(Ids::ACACIA_BUTTON); + return new BlockIdentifier(Ids::ACACIA_BUTTON, 0); case TreeType::DARK_OAK()->id(): - return new BlockIdentifier(Ids::DARK_OAK_BUTTON); + return new BlockIdentifier(Ids::DARK_OAK_BUTTON, 0); } throw new AssumptionFailedError("Switch should cover all wood types"); } @@ -108,17 +108,17 @@ final class BlockLegacyIdHelper{ public static function getWoodenPressurePlateIdentifier(TreeType $treeType) : BlockIdentifier{ switch($treeType->id()){ case TreeType::OAK()->id(): - return new BlockIdentifier(Ids::WOODEN_PRESSURE_PLATE); + return new BlockIdentifier(Ids::WOODEN_PRESSURE_PLATE, 0); case TreeType::SPRUCE()->id(): - return new BlockIdentifier(Ids::SPRUCE_PRESSURE_PLATE); + return new BlockIdentifier(Ids::SPRUCE_PRESSURE_PLATE, 0); case TreeType::BIRCH()->id(): - return new BlockIdentifier(Ids::BIRCH_PRESSURE_PLATE); + return new BlockIdentifier(Ids::BIRCH_PRESSURE_PLATE, 0); case TreeType::JUNGLE()->id(): - return new BlockIdentifier(Ids::JUNGLE_PRESSURE_PLATE); + return new BlockIdentifier(Ids::JUNGLE_PRESSURE_PLATE, 0); case TreeType::ACACIA()->id(): - return new BlockIdentifier(Ids::ACACIA_PRESSURE_PLATE); + return new BlockIdentifier(Ids::ACACIA_PRESSURE_PLATE, 0); case TreeType::DARK_OAK()->id(): - return new BlockIdentifier(Ids::DARK_OAK_PRESSURE_PLATE); + return new BlockIdentifier(Ids::DARK_OAK_PRESSURE_PLATE, 0); } throw new AssumptionFailedError("Switch should cover all wood types"); } @@ -144,17 +144,17 @@ final class BlockLegacyIdHelper{ public static function getWoodenFenceIdentifier(TreeType $treeType) : BlockIdentifier{ switch($treeType->id()){ case TreeType::OAK()->id(): - return new BlockIdentifier(Ids::OAK_FENCE_GATE); + return new BlockIdentifier(Ids::OAK_FENCE_GATE, 0); case TreeType::SPRUCE()->id(): - return new BlockIdentifier(Ids::SPRUCE_FENCE_GATE); + return new BlockIdentifier(Ids::SPRUCE_FENCE_GATE, 0); case TreeType::BIRCH()->id(): - return new BlockIdentifier(Ids::BIRCH_FENCE_GATE); + return new BlockIdentifier(Ids::BIRCH_FENCE_GATE, 0); case TreeType::JUNGLE()->id(): - return new BlockIdentifier(Ids::JUNGLE_FENCE_GATE); + return new BlockIdentifier(Ids::JUNGLE_FENCE_GATE, 0); case TreeType::ACACIA()->id(): - return new BlockIdentifier(Ids::ACACIA_FENCE_GATE); + return new BlockIdentifier(Ids::ACACIA_FENCE_GATE, 0); case TreeType::DARK_OAK()->id(): - return new BlockIdentifier(Ids::DARK_OAK_FENCE_GATE); + return new BlockIdentifier(Ids::DARK_OAK_FENCE_GATE, 0); } throw new AssumptionFailedError("Switch should cover all wood types"); } @@ -162,17 +162,17 @@ final class BlockLegacyIdHelper{ public static function getWoodenStairsIdentifier(TreeType $treeType) : BlockIdentifier{ switch($treeType->id()){ case TreeType::OAK()->id(): - return new BlockIdentifier(Ids::OAK_STAIRS); + return new BlockIdentifier(Ids::OAK_STAIRS, 0); case TreeType::SPRUCE()->id(): - return new BlockIdentifier(Ids::SPRUCE_STAIRS); + return new BlockIdentifier(Ids::SPRUCE_STAIRS, 0); case TreeType::BIRCH()->id(): - return new BlockIdentifier(Ids::BIRCH_STAIRS); + return new BlockIdentifier(Ids::BIRCH_STAIRS, 0); case TreeType::JUNGLE()->id(): - return new BlockIdentifier(Ids::JUNGLE_STAIRS); + return new BlockIdentifier(Ids::JUNGLE_STAIRS, 0); case TreeType::ACACIA()->id(): - return new BlockIdentifier(Ids::ACACIA_STAIRS); + return new BlockIdentifier(Ids::ACACIA_STAIRS, 0); case TreeType::DARK_OAK()->id(): - return new BlockIdentifier(Ids::DARK_OAK_STAIRS); + return new BlockIdentifier(Ids::DARK_OAK_STAIRS, 0); } throw new AssumptionFailedError("Switch should cover all wood types"); } @@ -180,37 +180,37 @@ final class BlockLegacyIdHelper{ public static function getGlazedTerracottaIdentifier(DyeColor $color) : BlockIdentifier{ switch($color->id()){ case DyeColor::WHITE()->id(): - return new BlockIdentifier(Ids::WHITE_GLAZED_TERRACOTTA); + return new BlockIdentifier(Ids::WHITE_GLAZED_TERRACOTTA, 0); case DyeColor::ORANGE()->id(): - return new BlockIdentifier(Ids::ORANGE_GLAZED_TERRACOTTA); + return new BlockIdentifier(Ids::ORANGE_GLAZED_TERRACOTTA, 0); case DyeColor::MAGENTA()->id(): - return new BlockIdentifier(Ids::MAGENTA_GLAZED_TERRACOTTA); + return new BlockIdentifier(Ids::MAGENTA_GLAZED_TERRACOTTA, 0); case DyeColor::LIGHT_BLUE()->id(): - return new BlockIdentifier(Ids::LIGHT_BLUE_GLAZED_TERRACOTTA); + return new BlockIdentifier(Ids::LIGHT_BLUE_GLAZED_TERRACOTTA, 0); case DyeColor::YELLOW()->id(): - return new BlockIdentifier(Ids::YELLOW_GLAZED_TERRACOTTA); + return new BlockIdentifier(Ids::YELLOW_GLAZED_TERRACOTTA, 0); case DyeColor::LIME()->id(): - return new BlockIdentifier(Ids::LIME_GLAZED_TERRACOTTA); + return new BlockIdentifier(Ids::LIME_GLAZED_TERRACOTTA, 0); case DyeColor::PINK()->id(): - return new BlockIdentifier(Ids::PINK_GLAZED_TERRACOTTA); + return new BlockIdentifier(Ids::PINK_GLAZED_TERRACOTTA, 0); case DyeColor::GRAY()->id(): - return new BlockIdentifier(Ids::GRAY_GLAZED_TERRACOTTA); + return new BlockIdentifier(Ids::GRAY_GLAZED_TERRACOTTA, 0); case DyeColor::LIGHT_GRAY()->id(): - return new BlockIdentifier(Ids::SILVER_GLAZED_TERRACOTTA); + return new BlockIdentifier(Ids::SILVER_GLAZED_TERRACOTTA, 0); case DyeColor::CYAN()->id(): - return new BlockIdentifier(Ids::CYAN_GLAZED_TERRACOTTA); + return new BlockIdentifier(Ids::CYAN_GLAZED_TERRACOTTA, 0); case DyeColor::PURPLE()->id(): - return new BlockIdentifier(Ids::PURPLE_GLAZED_TERRACOTTA); + return new BlockIdentifier(Ids::PURPLE_GLAZED_TERRACOTTA, 0); case DyeColor::BLUE()->id(): - return new BlockIdentifier(Ids::BLUE_GLAZED_TERRACOTTA); + return new BlockIdentifier(Ids::BLUE_GLAZED_TERRACOTTA, 0); case DyeColor::BROWN()->id(): - return new BlockIdentifier(Ids::BROWN_GLAZED_TERRACOTTA); + return new BlockIdentifier(Ids::BROWN_GLAZED_TERRACOTTA, 0); case DyeColor::GREEN()->id(): - return new BlockIdentifier(Ids::GREEN_GLAZED_TERRACOTTA); + return new BlockIdentifier(Ids::GREEN_GLAZED_TERRACOTTA, 0); case DyeColor::RED()->id(): - return new BlockIdentifier(Ids::RED_GLAZED_TERRACOTTA); + return new BlockIdentifier(Ids::RED_GLAZED_TERRACOTTA, 0); case DyeColor::BLACK()->id(): - return new BlockIdentifier(Ids::BLACK_GLAZED_TERRACOTTA); + return new BlockIdentifier(Ids::BLACK_GLAZED_TERRACOTTA, 0); } throw new AssumptionFailedError("Switch should cover all colours"); } diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index 5d7d28dba9..5150fbda22 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -40,7 +40,7 @@ class BlockTest extends TestCase{ * Test registering a block which would overwrite another block, without forcing it */ public function testAccidentalOverrideBlock() : void{ - $block = new MyCustomBlock(new BlockIdentifier(BlockLegacyIds::COBBLESTONE), "Cobblestone", BlockBreakInfo::instant()); + $block = new MyCustomBlock(new BlockIdentifier(BlockLegacyIds::COBBLESTONE, 0), "Cobblestone", BlockBreakInfo::instant()); $this->expectException(\InvalidArgumentException::class); $this->blockFactory->register($block); } @@ -49,7 +49,7 @@ class BlockTest extends TestCase{ * Test registering a block deliberately overwriting another block works as expected */ public function testDeliberateOverrideBlock() : void{ - $block = new MyCustomBlock(new BlockIdentifier(BlockLegacyIds::COBBLESTONE), "Cobblestone", BlockBreakInfo::instant()); + $block = new MyCustomBlock(new BlockIdentifier(BlockLegacyIds::COBBLESTONE, 0), "Cobblestone", BlockBreakInfo::instant()); $this->blockFactory->register($block, true); self::assertInstanceOf(MyCustomBlock::class, $this->blockFactory->get($block->getId(), 0)); } @@ -60,7 +60,7 @@ class BlockTest extends TestCase{ public function testRegisterNewBlock() : void{ for($i = 0; $i < 256; ++$i){ if(!$this->blockFactory->isRegistered($i)){ - $b = new StrangeNewBlock(new BlockIdentifier($i), "Strange New Block", BlockBreakInfo::instant()); + $b = new StrangeNewBlock(new BlockIdentifier($i, 0), "Strange New Block", BlockBreakInfo::instant()); $this->blockFactory->register($b); self::assertInstanceOf(StrangeNewBlock::class, $this->blockFactory->get($b->getId(), 0)); return; @@ -75,7 +75,7 @@ class BlockTest extends TestCase{ */ public function testRegisterIdTooLarge() : void{ self::expectException(\RuntimeException::class); - $this->blockFactory->register(new OutOfBoundsBlock(new BlockIdentifier(25555), "Out Of Bounds Block", BlockBreakInfo::instant())); + $this->blockFactory->register(new OutOfBoundsBlock(new BlockIdentifier(25555, 0), "Out Of Bounds Block", BlockBreakInfo::instant())); } /** @@ -83,7 +83,7 @@ class BlockTest extends TestCase{ */ public function testRegisterIdTooSmall() : void{ self::expectException(\RuntimeException::class); - $this->blockFactory->register(new OutOfBoundsBlock(new BlockIdentifier(-1), "Out Of Bounds Block", BlockBreakInfo::instant())); + $this->blockFactory->register(new OutOfBoundsBlock(new BlockIdentifier(-1, 0), "Out Of Bounds Block", BlockBreakInfo::instant())); } /** From 607174699391031e8fb94d9d5595928cffe58f62 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 16 Apr 2021 21:16:27 +0100 Subject: [PATCH 2389/3224] Mark ItemFactory::get() and BlockFactory::get() as @deprecated --- src/block/BlockFactory.php | 6 +++++- src/item/ItemFactory.php | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 6c18ce1513..ee5b2c8209 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -880,7 +880,11 @@ class BlockFactory{ } /** - * Returns a new Block instance with the specified ID, meta and position. + * @deprecated This method should ONLY be used for deserializing data, e.g. from a config or database. For all other + * purposes, use VanillaBlocks. + * @see VanillaBlocks + * + * Deserializes a block from the provided legacy ID and legacy meta. */ public function get(int $id, int $meta) : Block{ if($meta < 0 or $meta > 0xf){ diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 74364bc2e0..28b6f1b931 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -424,7 +424,11 @@ class ItemFactory{ } /** - * Returns an instance of the Item with the specified id, meta, count and NBT. + * @deprecated This method should ONLY be used for deserializing data, e.g. from a config or database. For all other + * purposes, use VanillaItems. + * @see VanillaItems + * + * Deserializes an item from the provided legacy ID, legacy meta, count and NBT. * * @throws \InvalidArgumentException */ From c979ab8aa09f55d1d4259039ab79edb565c7bce4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 16 Apr 2021 21:24:16 +0100 Subject: [PATCH 2390/3224] Be more specific with documentation of ItemFactory::register() and BlockFactory::register() --- src/block/BlockFactory.php | 4 ++-- src/item/ItemFactory.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index ee5b2c8209..7d8a24329f 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -810,8 +810,8 @@ class BlockFactory{ } /** - * Registers a block type into the index. Plugins may use this method to register new block types or override - * existing ones. + * Maps a block type to its corresponding ID. This is necessary to ensure that the block is correctly loaded when + * reading from disk storage. * * NOTE: If you are registering a new block type, you will need to add it to the creative inventory yourself - it * will not automatically appear there. diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 28b6f1b931..187c14121e 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -395,8 +395,8 @@ class ItemFactory{ } /** - * Registers an item type into the index. Plugins may use this method to register new item types or override existing - * ones. + * Maps an item type to its corresponding ID. This is necessary to ensure that the item is correctly loaded when + * reading data from disk storage. * * NOTE: If you are registering a new item type, you will need to add it to the creative inventory yourself - it * will not automatically appear there. From da51f106de2bb4301266540e2754067cf951328d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 16 Apr 2021 21:27:28 +0100 Subject: [PATCH 2391/3224] ItemFactory/BlockFactory: give more specific class descriptions these classes both have a very specific purpose now, which is much lesser than it was in PM3. --- src/block/BlockFactory.php | 3 ++- src/item/ItemFactory.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 7d8a24329f..99f83d90ed 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -59,7 +59,8 @@ use function get_class; use function min; /** - * Manages block registration and instance creation + * Manages deserializing block types from their legacy blockIDs and metadata. + * This is primarily needed for loading chunks from disk. */ class BlockFactory{ use SingletonTrait; diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 187c14121e..0002359358 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -44,7 +44,8 @@ use pocketmine\utils\SingletonTrait; use pocketmine\world\World; /** - * Manages Item instance creation and registration + * Manages deserializing item types from their legacy ID/metadata. + * This is primarily needed for loading inventories saved in the world (or playerdata storage). */ class ItemFactory{ use SingletonTrait; From 01c36683759d922cc58edf78ecb05e9a99453b47 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 16 Apr 2021 21:30:48 +0100 Subject: [PATCH 2392/3224] ItemFactory: Check the bounds of durability, instead of trying to catch exceptions --- src/item/ItemFactory.php | 7 +++---- tests/phpunit/item/ItemFactoryTest.php | 5 +++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 0002359358..a98071d6d7 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -440,11 +440,10 @@ class ItemFactory{ if(isset($this->list[$offset = self::getListOffset($id, $meta)])){ $item = clone $this->list[$offset]; }elseif(isset($this->list[$zero = self::getListOffset($id, 0)]) and $this->list[$zero] instanceof Durable){ - /** @var Durable $item */ - $item = clone $this->list[$zero]; - try{ + if($meta <= $this->list[$zero]->getMaxDurability()){ + $item = clone $this->list[$zero]; $item->setDamage($meta); - }catch(\InvalidArgumentException $e){ + }else{ $item = new Item(new ItemIdentifier($id, $meta)); } }elseif($id < 256){ //intentionally includes negatives, for extended block IDs diff --git a/tests/phpunit/item/ItemFactoryTest.php b/tests/phpunit/item/ItemFactoryTest.php index 3ae28fb271..b3716554f0 100644 --- a/tests/phpunit/item/ItemFactoryTest.php +++ b/tests/phpunit/item/ItemFactoryTest.php @@ -48,4 +48,9 @@ class ItemFactoryTest extends TestCase{ /** @var Sword $i2 */ self::assertSame(1, $i2->getDamage()); } + + public function testGetDurableItemWithTooLargeDurability() : void{ + self::assertInstanceOf(Sword::class, ItemFactory::getInstance()->get(ItemIds::WOODEN_SWORD, ToolTier::WOOD()->getMaxDurability())); + self::assertInstanceOf(Item::class, ItemFactory::getInstance()->get(ItemIds::WOODEN_SWORD, ToolTier::WOOD()->getMaxDurability() + 1)); + } } From 9abdcd8ee5b541f09ae7c3beaf288468d1eed286 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 16 Apr 2021 21:45:22 +0100 Subject: [PATCH 2393/3224] shut --- tests/phpunit/item/ItemFactoryTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/item/ItemFactoryTest.php b/tests/phpunit/item/ItemFactoryTest.php index b3716554f0..da8533f669 100644 --- a/tests/phpunit/item/ItemFactoryTest.php +++ b/tests/phpunit/item/ItemFactoryTest.php @@ -51,6 +51,6 @@ class ItemFactoryTest extends TestCase{ public function testGetDurableItemWithTooLargeDurability() : void{ self::assertInstanceOf(Sword::class, ItemFactory::getInstance()->get(ItemIds::WOODEN_SWORD, ToolTier::WOOD()->getMaxDurability())); - self::assertInstanceOf(Item::class, ItemFactory::getInstance()->get(ItemIds::WOODEN_SWORD, ToolTier::WOOD()->getMaxDurability() + 1)); + ItemFactory::getInstance()->get(ItemIds::WOODEN_SWORD, ToolTier::WOOD()->getMaxDurability() + 1); } } From d5e1b4bd39f43e332ea25aacb4292778722fc8d6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 17 Apr 2021 01:36:16 +0100 Subject: [PATCH 2394/3224] Furnace: Separate light/extinguish code into onStartSmelting() and onStopSmelting() hooks this is a preparation for other kinds of furnaces which might not be plain old Furnaces. --- src/block/tile/Furnace.php | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index e46de0bad8..bbe9b998b4 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -124,15 +124,26 @@ class Furnace extends Spawnable implements Container, Nameable{ } $this->maxFuelTime = $this->remainingFuelTime = $ev->getBurnTime(); + $this->onStartSmelting(); + if($this->remainingFuelTime > 0 and $ev->isBurning()){ + $this->inventory->setFuel($fuel->getFuelResidue()); + } + } + + protected function onStartSmelting() : void{ $block = $this->getBlock(); if($block instanceof BlockFurnace and !$block->isLit()){ $block->setLit(true); $this->pos->getWorld()->setBlock($block->getPos(), $block); } + } - if($this->remainingFuelTime > 0 and $ev->isBurning()){ - $this->inventory->setFuel($fuel->getFuelResidue()); + protected function onStopSmelting() : void{ + $block = $this->getBlock(); + if($block instanceof BlockFurnace and $block->isLit()){ + $block->setLit(false); + $this->pos->getWorld()->setBlock($block->getPos(), $block); } } @@ -187,11 +198,7 @@ class Furnace extends Spawnable implements Container, Nameable{ } $ret = true; }else{ - $block = $this->getBlock(); - if($block instanceof BlockFurnace and $block->isLit()){ - $block->setLit(false); - $this->pos->getWorld()->setBlock($block->getPos(), $block); - } + $this->onStopSmelting(); $this->remainingFuelTime = $this->cookTime = $this->maxFuelTime = 0; } From a32eb4ebc3e82d52cd44d4dc03dcd59a965ed75c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 17 Apr 2021 02:04:10 +0100 Subject: [PATCH 2395/3224] Implemented coral and coral fans this implementation is very rough due to having to hack around lots more MCPE bullshit, and currently doesn't allow dynamic coral types; but it's there. We'll clean this up after 1.13 migration is done. --- src/block/BaseCoral.php | 79 +++++++++++++ src/block/BlockFactory.php | 31 ++++- src/block/BlockLegacyIdHelper.php | 12 ++ src/block/Coral.php | 48 ++++++++ src/block/FloorCoralFan.php | 111 ++++++++++++++++++ src/block/VanillaBlocks.php | 30 +++++ src/block/WallCoralFan.php | 78 ++++++++++++ src/item/ItemFactory.php | 5 + .../block_factory_consistency_check.json | 2 +- 9 files changed, 389 insertions(+), 7 deletions(-) create mode 100644 src/block/BaseCoral.php create mode 100644 src/block/Coral.php create mode 100644 src/block/FloorCoralFan.php create mode 100644 src/block/WallCoralFan.php diff --git a/src/block/BaseCoral.php b/src/block/BaseCoral.php new file mode 100644 index 0000000000..68b5e4d0ed --- /dev/null +++ b/src/block/BaseCoral.php @@ -0,0 +1,79 @@ +coralType = $coralType; + } + + public function getCoralType() : CoralType{ return $this->coralType; } + + public function isDead() : bool{ return $this->dead; } + + /** @return $this */ + public function setDead(bool $dead) : self{ + $this->dead = $dead; + return $this; + } + + public function onNearbyBlockChange() : void{ + if(!$this->dead){ + $world = $this->pos->getWorld(); + + $hasWater = false; + foreach($this->pos->sides() as $vector3){ + if($world->getBlock($vector3) instanceof Water){ + $hasWater = true; + break; + } + } + + //TODO: check water inside the block itself (not supported on the API yet) + if(!$hasWater){ + $world->setBlock($this->pos, $this->setDead(true)); + } + } + } + + public function getDropsForCompatibleTool(Item $item) : array{ + return []; + } + + public function isAffectedBySilkTouch() : bool{ + return true; + } + + public function isSolid() : bool{ return false; } + + protected function recalculateCollisionBoxes() : array{ return []; } +} diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 99f83d90ed..bf85505dea 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -45,9 +45,11 @@ use pocketmine\block\tile\Jukebox as TileJukebox; use pocketmine\block\tile\MonsterSpawner as TileMonsterSpawner; use pocketmine\block\tile\Note as TileNote; use pocketmine\block\tile\Skull as TileSkull; +use pocketmine\block\utils\CoralType; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\block\utils\TreeType; +use pocketmine\data\bedrock\CoralTypeIdMap; use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\item\Item; use pocketmine\item\ItemIds; @@ -479,6 +481,29 @@ class BlockFactory{ $this->registerMushroomBlocks(); + foreach(CoralType::getAll() as $coralType){ + $coralTypeId = CoralTypeIdMap::getInstance()->toId($coralType); + $coralTypeName = $coralType->getDisplayName(); + $this->register(new Coral( + new BID(Ids::CORAL, $coralTypeId), + "$coralTypeName Coral", + BlockBreakInfo::instant(), + $coralType + )); + $this->register(new FloorCoralFan( + new BlockIdentifierFlattened(Ids::CORAL_FAN, Ids::CORAL_FAN_DEAD, $coralTypeId, ItemIds::CORAL_FAN), + "$coralTypeName Coral Fan", + BlockBreakInfo::instant(), + $coralType + )); + $this->register(new WallCoralFan( + BlockLegacyIdHelper::getWallCoralFanIdentifier($coralType), + "$coralTypeName Wall Coral Fan", + BlockBreakInfo::instant(), + $coralType + )); + } + //region --- auto-generated TODOs for bedrock-1.11.0 --- //TODO: minecraft:bell //TODO: minecraft:blast_furnace @@ -492,12 +517,6 @@ class BlockFactory{ //TODO: minecraft:command_block //TODO: minecraft:composter //TODO: minecraft:conduit - //TODO: minecraft:coral - //TODO: minecraft:coral_fan - //TODO: minecraft:coral_fan_dead - //TODO: minecraft:coral_fan_hang - //TODO: minecraft:coral_fan_hang2 - //TODO: minecraft:coral_fan_hang3 //TODO: minecraft:dispenser //TODO: minecraft:dropper //TODO: minecraft:end_gateway diff --git a/src/block/BlockLegacyIdHelper.php b/src/block/BlockLegacyIdHelper.php index 7dec143ce8..c9408afb5c 100644 --- a/src/block/BlockLegacyIdHelper.php +++ b/src/block/BlockLegacyIdHelper.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\block\BlockIdentifier as BID; use pocketmine\block\BlockLegacyIds as Ids; use pocketmine\block\tile\Sign as TileSign; +use pocketmine\block\utils\CoralType; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\TreeType; use pocketmine\item\ItemIds; @@ -227,4 +228,15 @@ final class BlockLegacyIdHelper{ } return new BlockIdentifierFlattened($id[0], $id[1], $meta); } + + public static function getWallCoralFanIdentifier(CoralType $type) : BlockIdentifier{ + switch($type->id()){ + case CoralType::TUBE()->id(): return new BID(Ids::CORAL_FAN_HANG, 0, ItemIds::CORAL_FAN); + case CoralType::BRAIN()->id(): return new BID(Ids::CORAL_FAN_HANG, 1, ItemIds::CORAL_FAN); + case CoralType::BUBBLE()->id(): return new BID(Ids::CORAL_FAN_HANG2, 0, ItemIds::CORAL_FAN); + case CoralType::FIRE()->id(): return new BID(Ids::CORAL_FAN_HANG2, 1, ItemIds::CORAL_FAN); + case CoralType::HORN()->id(): return new BID(Ids::CORAL_FAN_HANG3, 0, ItemIds::CORAL_FAN); + } + throw new AssumptionFailedError("Switch should cover all coral types"); + } } diff --git a/src/block/Coral.php b/src/block/Coral.php new file mode 100644 index 0000000000..ad535ec7b5 --- /dev/null +++ b/src/block/Coral.php @@ -0,0 +1,48 @@ +fetchBlock($blockReplace->getPos()->down())->isSolid()){ + return false; + } + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + + public function onNearbyBlockChange() : void{ + $world = $this->pos->getWorld(); + if(!$world->getBlock($this->pos->down())->isSolid()){ + $world->useBreakOn($this->pos); + }else{ + parent::onNearbyBlockChange(); + } + } +} diff --git a/src/block/FloorCoralFan.php b/src/block/FloorCoralFan.php new file mode 100644 index 0000000000..08237f0d7b --- /dev/null +++ b/src/block/FloorCoralFan.php @@ -0,0 +1,111 @@ +dead = $id === $this->idInfo->getSecondId(); + $this->axis = ($stateMeta >> 3) === BlockLegacyMetadata::CORAL_FAN_EAST_WEST ? Axis::X : Axis::Z; + } + + public function getId() : int{ + return $this->dead ? $this->idInfo->getSecondId() : parent::getId(); + } + + public function asItem() : Item{ + //TODO: HACK! workaround dead flag being lost when broken / blockpicked (original impl only uses first ID) + return ItemFactory::getInstance()->get( + $this->dead ? ItemIds::CORAL_FAN_DEAD : ItemIds::CORAL_FAN, + CoralTypeIdMap::getInstance()->toId($this->coralType) + ); + } + + protected function writeStateToMeta() : int{ + return ($this->axis === Axis::X ? BlockLegacyMetadata::CORAL_FAN_EAST_WEST : BlockLegacyMetadata::CORAL_FAN_NORTH_SOUTH) << 3; + } + + public function getStateBitmask() : int{ + return 0b1000; + } + + public function getAxis() : int{ return $this->axis; } + + /** @return $this */ + public function setAxis(int $axis) : self{ + if($axis !== Axis::X && $axis !== Axis::Z){ + throw new \InvalidArgumentException("Axis must be X or Z only"); + } + $this->axis = $axis; + return $this; + } + + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if(!$tx->fetchBlock($blockReplace->getPos()->down())->isSolid()){ + return false; + } + if($player !== null){ + $playerBlockPos = $player->getPosition()->floor(); + $directionVector = $blockReplace->getPos()->subtractVector($playerBlockPos)->normalize(); + $angle = rad2deg(atan2($directionVector->getZ(), $directionVector->getX())); + + if($angle <= 45 || 315 <= $angle || (135 <= $angle && $angle <= 225)){ + //TODO: This produces Z axis 75% of the time, because any negative angle will produce Z axis. + //This is a bug in vanilla. https://bugs.mojang.com/browse/MCPE-125311 + $this->axis = Axis::Z; + } + } + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + + public function onNearbyBlockChange() : void{ + $world = $this->pos->getWorld(); + if(!$world->getBlock($this->pos->down())->isSolid()){ + $world->useBreakOn($this->pos); + }else{ + parent::onNearbyBlockChange(); + } + } + +} diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 80596f7d29..3f23880f9b 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -93,6 +93,9 @@ use function assert; * @method static Torch BLUE_TORCH() * @method static BoneBlock BONE_BLOCK() * @method static Bookshelf BOOKSHELF() + * @method static Coral BRAIN_CORAL() + * @method static FloorCoralFan BRAIN_CORAL_FAN() + * @method static WallCoralFan BRAIN_WALL_CORAL_FAN() * @method static BrewingStand BREWING_STAND() * @method static Opaque BRICKS() * @method static Slab BRICK_SLAB() @@ -104,6 +107,9 @@ use function assert; * @method static HardenedClay BROWN_STAINED_CLAY() * @method static Glass BROWN_STAINED_GLASS() * @method static GlassPane BROWN_STAINED_GLASS_PANE() + * @method static Coral BUBBLE_CORAL() + * @method static FloorCoralFan BUBBLE_CORAL_FAN() + * @method static WallCoralFan BUBBLE_WALL_CORAL_FAN() * @method static Cactus CACTUS() * @method static Cake CAKE() * @method static Carpet CARPET() @@ -307,6 +313,9 @@ use function assert; * @method static Farmland FARMLAND() * @method static TallGrass FERN() * @method static Fire FIRE() + * @method static Coral FIRE_CORAL() + * @method static FloorCoralFan FIRE_CORAL_FAN() + * @method static WallCoralFan FIRE_WALL_CORAL_FAN() * @method static FlowerPot FLOWER_POT() * @method static FrostedIce FROSTED_ICE() * @method static Furnace FURNACE() @@ -369,6 +378,9 @@ use function assert; * @method static HardenedGlassPane HARDENED_YELLOW_STAINED_GLASS_PANE() * @method static HayBale HAY_BALE() * @method static Hopper HOPPER() + * @method static Coral HORN_CORAL() + * @method static FloorCoralFan HORN_CORAL_FAN() + * @method static WallCoralFan HORN_WALL_CORAL_FAN() * @method static Ice ICE() * @method static InfestedStone INFESTED_CHISELED_STONE_BRICK() * @method static InfestedStone INFESTED_COBBLESTONE() @@ -603,6 +615,9 @@ use function assert; * @method static TrappedChest TRAPPED_CHEST() * @method static Tripwire TRIPWIRE() * @method static TripwireHook TRIPWIRE_HOOK() + * @method static Coral TUBE_CORAL() + * @method static FloorCoralFan TUBE_CORAL_FAN() + * @method static WallCoralFan TUBE_WALL_CORAL_FAN() * @method static UnderwaterTorch UNDERWATER_TORCH() * @method static Vine VINES() * @method static WallBanner WALL_BANNER() @@ -712,6 +727,9 @@ final class VanillaBlocks{ self::register("blue_torch", $factory->get(204, 5)); self::register("bone_block", $factory->get(216, 0)); self::register("bookshelf", $factory->get(47, 0)); + self::register("brain_coral", $factory->get(386, 1)); + self::register("brain_coral_fan", $factory->get(388, 1)); + self::register("brain_wall_coral_fan", $factory->get(390, 1)); self::register("brewing_stand", $factory->get(117, 0)); self::register("brick_slab", $factory->get(44, 4)); self::register("brick_stairs", $factory->get(108, 0)); @@ -723,6 +741,9 @@ final class VanillaBlocks{ self::register("brown_stained_clay", $factory->get(159, 12)); self::register("brown_stained_glass", $factory->get(241, 12)); self::register("brown_stained_glass_pane", $factory->get(160, 12)); + self::register("bubble_coral", $factory->get(386, 2)); + self::register("bubble_coral_fan", $factory->get(388, 2)); + self::register("bubble_wall_coral_fan", $factory->get(391, 0)); self::register("cactus", $factory->get(81, 0)); self::register("cake", $factory->get(92, 0)); self::register("carpet", $factory->get(171, 0)); @@ -926,6 +947,9 @@ final class VanillaBlocks{ self::register("farmland", $factory->get(60, 0)); self::register("fern", $factory->get(31, 2)); self::register("fire", $factory->get(51, 0)); + self::register("fire_coral", $factory->get(386, 3)); + self::register("fire_coral_fan", $factory->get(388, 3)); + self::register("fire_wall_coral_fan", $factory->get(391, 1)); self::register("flower_pot", $factory->get(140, 0)); self::register("frosted_ice", $factory->get(207, 0)); self::register("furnace", $factory->get(61, 2)); @@ -988,6 +1012,9 @@ final class VanillaBlocks{ self::register("hardened_yellow_stained_glass_pane", $factory->get(191, 4)); self::register("hay_bale", $factory->get(170, 0)); self::register("hopper", $factory->get(154, 0)); + self::register("horn_coral", $factory->get(386, 4)); + self::register("horn_coral_fan", $factory->get(388, 4)); + self::register("horn_wall_coral_fan", $factory->get(392, 0)); self::register("ice", $factory->get(79, 0)); self::register("infested_chiseled_stone_brick", $factory->get(97, 5)); self::register("infested_cobblestone", $factory->get(97, 1)); @@ -1222,6 +1249,9 @@ final class VanillaBlocks{ self::register("trapped_chest", $factory->get(146, 2)); self::register("tripwire", $factory->get(132, 0)); self::register("tripwire_hook", $factory->get(131, 0)); + self::register("tube_coral", $factory->get(386, 0)); + self::register("tube_coral_fan", $factory->get(388, 0)); + self::register("tube_wall_coral_fan", $factory->get(390, 0)); self::register("underwater_torch", $factory->get(239, 5)); self::register("vines", $factory->get(106, 0)); self::register("wall_banner", $factory->get(177, 2)); diff --git a/src/block/WallCoralFan.php b/src/block/WallCoralFan.php new file mode 100644 index 0000000000..bac64b15b7 --- /dev/null +++ b/src/block/WallCoralFan.php @@ -0,0 +1,78 @@ +facing = BlockDataSerializer::readCoralFacing($stateMeta >> 2); + $this->dead = ($stateMeta & BlockLegacyMetadata::CORAL_FAN_HANG_FLAG_DEAD) !== 0; + } + + public function writeStateToMeta() : int{ + return (BlockDataSerializer::writeCoralFacing($this->facing) << 2) | ($this->dead ? BlockLegacyMetadata::CORAL_FAN_HANG_FLAG_DEAD : 0); + } + + public function getStateBitmask() : int{ + return 0b1110; + } + + public function asItem() : Item{ + return ItemFactory::getInstance()->get( + $this->dead ? ItemIds::CORAL_FAN_DEAD : ItemIds::CORAL_FAN, + CoralTypeIdMap::getInstance()->toId($this->coralType) + ); + } + + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + $axis = Facing::axis($face); + if(($axis !== Axis::X && $axis !== Axis::Z) || !$blockClicked->isSolid()){ + return false; + } + $this->facing = $face; + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + + public function onNearbyBlockChange() : void{ + $world = $this->pos->getWorld(); + if(!$world->getBlock($this->pos->getSide(Facing::opposite($this->facing)))->isSolid()){ + $world->useBreakOn($this->pos); + }else{ + parent::onNearbyBlockChange(); + } + } +} diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index a98071d6d7..02d14b918f 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -77,6 +77,11 @@ class ItemFactory{ $this->register(new Clock(new ItemIdentifier(ItemIds::CLOCK, 0), "Clock")); $this->register(new Clownfish(new ItemIdentifier(ItemIds::CLOWNFISH, 0), "Clownfish")); $this->register(new Coal(new ItemIdentifier(ItemIds::COAL, 0), "Coal")); + $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::CORAL_FAN, 0), VanillaBlocks::TUBE_CORAL_FAN(), VanillaBlocks::TUBE_WALL_CORAL_FAN()), true); + $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::CORAL_FAN, 1), VanillaBlocks::BRAIN_CORAL_FAN(), VanillaBlocks::BRAIN_WALL_CORAL_FAN()), true); + $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::CORAL_FAN, 2), VanillaBlocks::BUBBLE_CORAL_FAN(), VanillaBlocks::BUBBLE_WALL_CORAL_FAN()), true); + $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::CORAL_FAN, 3), VanillaBlocks::FIRE_CORAL_FAN(), VanillaBlocks::FIRE_WALL_CORAL_FAN()), true); + $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::CORAL_FAN, 4), VanillaBlocks::HORN_CORAL_FAN(), VanillaBlocks::HORN_WALL_CORAL_FAN()), true); $this->register(new Coal(new ItemIdentifier(ItemIds::COAL, 1), "Charcoal")); $this->register(new CocoaBeans(new ItemIdentifier(ItemIds::DYE, 3), "Cocoa Beans")); $this->register(new Compass(new ItemIdentifier(ItemIds::COMPASS, 0), "Compass")); diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 4f20c9daf1..042c0cf3f5 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Mushroom Stem","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"All Sided Mushroom Stem","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Mushroom Stem","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"All Sided Mushroom Stem","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Tube Coral","6177":"Brain Coral","6178":"Bubble Coral","6179":"Fire Coral","6180":"Horn Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Tube Coral Fan","6209":"Brain Coral Fan","6210":"Bubble Coral Fan","6211":"Fire Coral Fan","6212":"Horn Coral Fan","6216":"Tube Coral Fan","6217":"Brain Coral Fan","6218":"Bubble Coral Fan","6219":"Fire Coral Fan","6220":"Horn Coral Fan","6224":"Tube Coral Fan","6225":"Brain Coral Fan","6226":"Bubble Coral Fan","6227":"Fire Coral Fan","6228":"Horn Coral Fan","6232":"Tube Coral Fan","6233":"Brain Coral Fan","6234":"Bubble Coral Fan","6235":"Fire Coral Fan","6236":"Horn Coral Fan","6240":"Tube Wall Coral Fan","6241":"Brain Wall Coral Fan","6242":"Tube Wall Coral Fan","6243":"Brain Wall Coral Fan","6244":"Tube Wall Coral Fan","6245":"Brain Wall Coral Fan","6246":"Tube Wall Coral Fan","6247":"Brain Wall Coral Fan","6248":"Tube Wall Coral Fan","6249":"Brain Wall Coral Fan","6250":"Tube Wall Coral Fan","6251":"Brain Wall Coral Fan","6252":"Tube Wall Coral Fan","6253":"Brain Wall Coral Fan","6254":"Tube Wall Coral Fan","6255":"Brain Wall Coral Fan","6256":"Bubble Wall Coral Fan","6257":"Fire Wall Coral Fan","6258":"Bubble Wall Coral Fan","6259":"Fire Wall Coral Fan","6260":"Bubble Wall Coral Fan","6261":"Fire Wall Coral Fan","6262":"Bubble Wall Coral Fan","6263":"Fire Wall Coral Fan","6264":"Bubble Wall Coral Fan","6265":"Fire Wall Coral Fan","6266":"Bubble Wall Coral Fan","6267":"Fire Wall Coral Fan","6268":"Bubble Wall Coral Fan","6269":"Fire Wall Coral Fan","6270":"Bubble Wall Coral Fan","6271":"Fire Wall Coral Fan","6272":"Horn Wall Coral Fan","6274":"Horn Wall Coral Fan","6276":"Horn Wall Coral Fan","6278":"Horn Wall Coral Fan","6280":"Horn Wall Coral Fan","6282":"Horn Wall Coral Fan","6284":"Horn Wall Coral Fan","6286":"Horn Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From 5dfa6a229666ab3d2dcebd946e23ee1415fe0c0d Mon Sep 17 00:00:00 2001 From: Mohamed Date: Sat, 17 Apr 2021 20:11:10 +0200 Subject: [PATCH 2396/3224] Fix dragon egg teleporting in creative (#4180) closes #4179 --- src/block/DragonEgg.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/block/DragonEgg.php b/src/block/DragonEgg.php index 5ea0657596..5a2afff3f6 100644 --- a/src/block/DragonEgg.php +++ b/src/block/DragonEgg.php @@ -29,6 +29,7 @@ use pocketmine\event\block\BlockTeleportEvent; use pocketmine\item\Item; use pocketmine\item\ToolTier; use pocketmine\math\Vector3; +use pocketmine\player\GameMode; use pocketmine\player\Player; use pocketmine\world\particle\DragonEggTeleportParticle; use pocketmine\world\World; @@ -57,8 +58,11 @@ class DragonEgg extends Transparent implements Fallable{ } public function onAttack(Item $item, int $face, ?Player $player = null) : bool{ - $this->teleport(); - return true; + if($player !== null && !$player->getGamemode()->equals(GameMode::CREATIVE())){ + $this->teleport(); + return true; + } + return false; } public function teleport() : void{ From f29ababf8d2a282867f06314416f1831a0605aeb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 18 Apr 2021 20:07:36 +0100 Subject: [PATCH 2397/3224] World: Rearrange some light-related methods these things are all over the place ... --- src/world/World.php | 86 ++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 54fe5ffedb..b3e6e9beb8 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1215,19 +1215,6 @@ class World implements ChunkManager{ return $collides; } - public function getFullLight(Vector3 $pos) : int{ - return $this->getFullLightAt($pos->x, $pos->y, $pos->z); - } - - public function getFullLightAt(int $x, int $y, int $z) : int{ - $skyLight = $this->getRealBlockSkyLightAt($x, $y, $z); - if($skyLight < 15){ - return max($skyLight, $this->getBlockLightAt($x, $y, $z)); - }else{ - return $skyLight; - } - } - /** * Computes the percentage of a circle away from noon the sun is currently at. This can be multiplied by 2 * M_PI to * get an angle in radians, or by 360 to get an angle in degrees. @@ -1285,6 +1272,34 @@ class World implements ChunkManager{ return $this->skyLightReduction; } + public function getFullLight(Vector3 $pos) : int{ + return $this->getFullLightAt($pos->x, $pos->y, $pos->z); + } + + public function getFullLightAt(int $x, int $y, int $z) : int{ + $skyLight = $this->getRealBlockSkyLightAt($x, $y, $z); + if($skyLight < 15){ + return max($skyLight, $this->getBlockLightAt($x, $y, $z)); + }else{ + return $skyLight; + } + } + + /** + * Gets the raw block skylight level + * + * @return int 0-15 + */ + public function getPotentialBlockSkyLightAt(int $x, int $y, int $z) : int{ + if(!$this->isInWorld($x, $y, $z)){ + return $y >= self::Y_MAX ? 15 : 0; + } + if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null && $chunk->isLightPopulated() === true){ + return $chunk->getSubChunk($y >> 4)->getBlockSkyLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); + } + return 0; //TODO: this should probably throw instead (light not calculated yet) + } + /** * Returns the sky light level at the specified coordinates, offset by the current time and weather. * @@ -1295,6 +1310,21 @@ class World implements ChunkManager{ return $light < 0 ? 0 : $light; } + /** + * Gets the raw block light level + * + * @return int 0-15 + */ + public function getBlockLightAt(int $x, int $y, int $z) : int{ + if(!$this->isInWorld($x, $y, $z)){ + return 0; + } + if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null && $chunk->isLightPopulated() === true){ + return $chunk->getSubChunk($y >> 4)->getBlockLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); + } + return 0; //TODO: this should probably throw instead (light not calculated yet) + } + public function updateAllLight(int $x, int $y, int $z) : void{ if(($chunk = $this->getChunk($x >> 4, $z >> 4)) === null || $chunk->isLightPopulated() !== true){ $this->logger->debug("Skipped runtime light update of x=$x,y=$y,z=$z because the target area has not received base light calculation"); @@ -1937,36 +1967,6 @@ class World implements ChunkManager{ return ($chunk = $this->loadChunk($x >> 4, $z >> 4)) !== null ? $chunk->getTile($x & 0x0f, $y, $z & 0x0f) : null; } - /** - * Gets the raw block skylight level - * - * @return int 0-15 - */ - public function getPotentialBlockSkyLightAt(int $x, int $y, int $z) : int{ - if(!$this->isInWorld($x, $y, $z)){ - return $y >= self::Y_MAX ? 15 : 0; - } - if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null && $chunk->isLightPopulated() === true){ - return $chunk->getSubChunk($y >> 4)->getBlockSkyLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); - } - return 0; //TODO: this should probably throw instead (light not calculated yet) - } - - /** - * Gets the raw block light level - * - * @return int 0-15 - */ - public function getBlockLightAt(int $x, int $y, int $z) : int{ - if(!$this->isInWorld($x, $y, $z)){ - return 0; - } - if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null && $chunk->isLightPopulated() === true){ - return $chunk->getSubChunk($y >> 4)->getBlockLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); - } - return 0; //TODO: this should probably throw instead (light not calculated yet) - } - public function getBiomeId(int $x, int $z) : int{ if(($chunk = $this->loadChunk($x >> 4, $z >> 4)) !== null){ return $chunk->getBiomeId($x & 0x0f, $z & 0x0f); From 51b0685881176e2cc78ce916a7d7e3fa9a0ada8c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 18 Apr 2021 20:14:16 +0100 Subject: [PATCH 2398/3224] World: document getFullLight() and getFullLightAt() --- src/world/World.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index b3e6e9beb8..305500bd6f 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1272,10 +1272,18 @@ class World implements ChunkManager{ return $this->skyLightReduction; } + /** + * Returns the highest available level of any type of light at the given coordinates, adjusted for the current + * weather and time of day. + */ public function getFullLight(Vector3 $pos) : int{ return $this->getFullLightAt($pos->x, $pos->y, $pos->z); } + /** + * Returns the highest available level of any type of light at the given coordinates, adjusted for the current + * weather and time of day. + */ public function getFullLightAt(int $x, int $y, int $z) : int{ $skyLight = $this->getRealBlockSkyLightAt($x, $y, $z); if($skyLight < 15){ From 53ebe4f9f95de300d93e700d3fe39577816848fe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 18 Apr 2021 20:20:08 +0100 Subject: [PATCH 2399/3224] World: added getHighestAdjacentFullLightAt() --- src/block/FrostedIce.php | 5 +---- src/world/World.php | 8 ++++++++ tests/phpstan/configs/l7-baseline.neon | 21 +++------------------ 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/block/FrostedIce.php b/src/block/FrostedIce.php index 70563050a8..00ddadbca3 100644 --- a/src/block/FrostedIce.php +++ b/src/block/FrostedIce.php @@ -69,10 +69,7 @@ class FrostedIce extends Ice{ public function onRandomTick() : void{ if((!$this->checkAdjacentBlocks(4) or mt_rand(0, 2) === 0) and - max( //TODO: move this to World - $this->pos->getWorld()->getHighestAdjacentBlockLight($this->pos->x, $this->pos->y, $this->pos->z), - $this->pos->getWorld()->getHighestAdjacentRealBlockSkyLight($this->pos->x, $this->pos->y, $this->pos->z) - ) >= 12 - $this->age){ + $this->pos->getWorld()->getHighestAdjacentFullLightAt($this->pos->x, $this->pos->y, $this->pos->z) >= 12 - $this->age){ if($this->tryMelt()){ foreach($this->getAllSides() as $block){ if($block instanceof FrostedIce){ diff --git a/src/world/World.php b/src/world/World.php index 305500bd6f..384bfc6a0e 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1293,6 +1293,14 @@ class World implements ChunkManager{ } } + /** + * Returns the highest available level of any type of light at, or adjacent to, the given coordinates, adjusted for + * the current weather and time of day. + */ + public function getHighestAdjacentFullLightAt(int $x, int $y, int $z) : int{ + return $this->getHighestAdjacentLight($x, $y, $z, \Closure::fromCallable([$this, 'getFullLightAt'])); + } + /** * Gets the raw block skylight level * diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index 2274d14ac5..e54fab02b5 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -171,12 +171,7 @@ parameters: path: ../../../src/block/FrostedIce.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentBlockLight\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/block/FrostedIce.php - - - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentRealBlockSkyLight\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentFullLightAt\\(\\) expects int, float\\|int given\\.$#" count: 1 path: ../../../src/block/FrostedIce.php @@ -186,12 +181,7 @@ parameters: path: ../../../src/block/FrostedIce.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentBlockLight\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/block/FrostedIce.php - - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentRealBlockSkyLight\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentFullLightAt\\(\\) expects int, float\\|int given\\.$#" count: 1 path: ../../../src/block/FrostedIce.php @@ -201,12 +191,7 @@ parameters: path: ../../../src/block/FrostedIce.php - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentBlockLight\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/block/FrostedIce.php - - - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentRealBlockSkyLight\\(\\) expects int, float\\|int given\\.$#" + message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getHighestAdjacentFullLightAt\\(\\) expects int, float\\|int given\\.$#" count: 1 path: ../../../src/block/FrostedIce.php From caf3ec1b54d932f89cecc9fa8348f94ca29eb411 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 18 Apr 2021 20:31:42 +0100 Subject: [PATCH 2400/3224] World: improve documentation of World::getPotentialBlockSkyLightAt() --- src/world/World.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index 384bfc6a0e..4ded21ddc6 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1302,7 +1302,10 @@ class World implements ChunkManager{ } /** - * Gets the raw block skylight level + * Returns the highest potential level of sky light at the target coordinates, regardless of the time of day or + * weather conditions. + * You usually don't want to use this for vanilla gameplay logic; prefer the real sky light instead. + * @see World::getRealBlockSkyLightAt() * * @return int 0-15 */ From 129c638e2991423b95e2462439378f82e7f43105 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 18 Apr 2021 20:33:49 +0100 Subject: [PATCH 2401/3224] Remove unused import --- src/block/FrostedIce.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/block/FrostedIce.php b/src/block/FrostedIce.php index 00ddadbca3..f98a12d633 100644 --- a/src/block/FrostedIce.php +++ b/src/block/FrostedIce.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; -use function max; use function mt_rand; class FrostedIce extends Ice{ From b4afa46fadef007dfec24f86654ebbae891c9fb2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 18 Apr 2021 23:53:34 +0100 Subject: [PATCH 2402/3224] Player: don't re-request chunks unless they've already been sent if they've been requested, the ChunkCache will take care of rebuilding the chunk packet before sending it. --- src/player/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index dcc821878f..bffee70873 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2345,7 +2345,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ public function onChunkChanged(int $chunkX, int $chunkZ, Chunk $chunk) : void{ $status = $this->usedChunks[$hash = World::chunkHash($chunkX, $chunkZ)] ?? null; - if($status !== null && !$status->equals(UsedChunkStatus::NEEDED())){ + if($status !== null && $status->equals(UsedChunkStatus::SENT())){ $this->usedChunks[$hash] = UsedChunkStatus::NEEDED(); $this->nextChunkOrderRun = 0; } From 025135917987fa5a57be5610782785b6fdf49b8e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Apr 2021 00:20:03 +0100 Subject: [PATCH 2403/3224] ChunkCache: remove outdated TODO comment we don't set the entire chunk during lighting updates anymore, so updating light doesn't trigger onChunkChanged(). --- src/network/mcpe/cache/ChunkCache.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/network/mcpe/cache/ChunkCache.php b/src/network/mcpe/cache/ChunkCache.php index dd2f4503f8..0729a1f8c2 100644 --- a/src/network/mcpe/cache/ChunkCache.php +++ b/src/network/mcpe/cache/ChunkCache.php @@ -184,7 +184,6 @@ class ChunkCache implements ChunkListener{ * @see ChunkListener::onChunkChanged() */ public function onChunkChanged(int $chunkX, int $chunkZ, Chunk $chunk) : void{ - //FIXME: this gets fired for stuff that doesn't change terrain related things (like lighting updates) $this->destroyOrRestart($chunkX, $chunkZ); } From 35a3522b4e4045b833d6485bf1ca985976910ca1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Apr 2021 00:30:34 +0100 Subject: [PATCH 2404/3224] Player: fixed chunks getting spammed like crazy during generation because of the shitty way that the chunk resending is handled, it causes all kinds of problems with the async system because of potential reversions of the state during the process. --- src/player/Player.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/player/Player.php b/src/player/Player.php index bffee70873..2350c38637 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -733,6 +733,13 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ if(!$this->isConnected() || !isset($this->usedChunks[$index]) || $world !== $this->getWorld()){ return; } + if(!$this->usedChunks[$index]->equals(UsedChunkStatus::NEEDED())){ + //TODO: make this an error + //we may have added multiple completion handlers, since the Player keeps re-requesting chunks + //it doesn't have yet (a relic from the old system, but also currently relied on for chunk resends). + //in this event, make sure we don't try to send the chunk multiple times. + return; + } unset($this->loadQueue[$index]); $this->usedChunks[$index] = UsedChunkStatus::REQUESTED(); @@ -741,6 +748,13 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->logger->debug("Tried to send no-longer-active chunk $X $Z in world " . $world->getFolderName()); return; } + if(!$this->usedChunks[$index]->equals(UsedChunkStatus::REQUESTED())){ + //TODO: make this an error + //this could be triggered due to the shitty way that chunk resends are handled + //right now - not because of the spammy re-requesting, but because the chunk status reverts + //to NEEDED if they want to be resent. + return; + } $this->usedChunks[$index] = UsedChunkStatus::SENT(); if($this->spawnChunkLoadCount === -1){ $this->spawnEntitiesOnChunk($X, $Z); From 6d38922af091aca6a4b8483ee8ebb263dd8f5e80 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Apr 2021 00:36:13 +0100 Subject: [PATCH 2405/3224] Undo my -100IQ fuckup with chunk sending precondition the commit I reverted put the preconditions in the completion handler, which is executed AFTER THE CHUNK IS SENT. Revert "NetworkSession: allow Player to handle its own business in chunk sending" This reverts commit a223d1cbf3e8a9143383b6497f4d2d5d7ab3202a. --- src/network/mcpe/NetworkSession.php | 7 ++++++- src/player/Player.php | 6 +----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 92a41cf168..1ae81ff35c 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -914,10 +914,15 @@ class NetworkSession{ ChunkCache::getInstance($world, $this->compressor)->request($chunkX, $chunkZ)->onResolve( //this callback may be called synchronously or asynchronously, depending on whether the promise is resolved yet - function(CompressBatchPromise $promise) use ($world, $onCompletion) : void{ + function(CompressBatchPromise $promise) use ($world, $onCompletion, $chunkX, $chunkZ) : void{ if(!$this->isConnected()){ return; } + $currentWorld = $this->player->getLocation()->getWorld(); + if($world !== $currentWorld or !$this->player->isUsingChunk($chunkX, $chunkZ)){ + $this->logger->debug("Tried to send no-longer-active chunk $chunkX $chunkZ in world " . $world->getFolderName()); + return; + } $world->timings->syncChunkSend->startTiming(); try{ $this->queueCompressed($promise); diff --git a/src/player/Player.php b/src/player/Player.php index 2350c38637..6d459b8d4e 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -743,11 +743,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ unset($this->loadQueue[$index]); $this->usedChunks[$index] = UsedChunkStatus::REQUESTED(); - $this->getNetworkSession()->startUsingChunk($X, $Z, function() use ($X, $Z, $index, $world) : void{ - if(!isset($this->usedChunks[$index]) || $world !== $this->getWorld()){ - $this->logger->debug("Tried to send no-longer-active chunk $X $Z in world " . $world->getFolderName()); - return; - } + $this->getNetworkSession()->startUsingChunk($X, $Z, function() use ($X, $Z, $index) : void{ if(!$this->usedChunks[$index]->equals(UsedChunkStatus::REQUESTED())){ //TODO: make this an error //this could be triggered due to the shitty way that chunk resends are handled From d19c21e2e173a2b4c0fc02d97e1803d0ddfa489d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Apr 2021 00:38:27 +0100 Subject: [PATCH 2406/3224] Updated PHPStan baseline --- tests/phpstan/configs/l8-baseline.neon | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 28e1572e14..e0249525f5 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -97,7 +97,7 @@ parameters: - message: "#^Cannot call method getLocation\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" - count: 1 + count: 2 path: ../../../src/network/mcpe/NetworkSession.php - @@ -105,6 +105,11 @@ parameters: count: 1 path: ../../../src/network/mcpe/NetworkSession.php + - + message: "#^Cannot call method isUsingChunk\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + - message: "#^Cannot call method sendData\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" count: 1 From 09a2402f0117ba1bb5589756cb49630618c307cf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Apr 2021 00:46:27 +0100 Subject: [PATCH 2407/3224] Fixed precondition on double chunk send being useless this is messy, but necessary for now. --- src/network/mcpe/NetworkSession.php | 10 +++++++++- src/player/Player.php | 14 +++++++------- tests/phpstan/configs/l8-baseline.neon | 4 ++-- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 1ae81ff35c..df021acf26 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -102,6 +102,7 @@ use pocketmine\permission\DefaultPermissions; use pocketmine\player\GameMode; use pocketmine\player\Player; use pocketmine\player\PlayerInfo; +use pocketmine\player\UsedChunkStatus; use pocketmine\player\XboxLivePlayerInfo; use pocketmine\Server; use pocketmine\timings\Timings; @@ -919,10 +920,17 @@ class NetworkSession{ return; } $currentWorld = $this->player->getLocation()->getWorld(); - if($world !== $currentWorld or !$this->player->isUsingChunk($chunkX, $chunkZ)){ + if($world !== $currentWorld or ($status = $this->player->getUsedChunkStatus($chunkX, $chunkZ)) === null){ $this->logger->debug("Tried to send no-longer-active chunk $chunkX $chunkZ in world " . $world->getFolderName()); return; } + if(!$status->equals(UsedChunkStatus::REQUESTED())){ + //TODO: make this an error + //this could be triggered due to the shitty way that chunk resends are handled + //right now - not because of the spammy re-requesting, but because the chunk status reverts + //to NEEDED if they want to be resent. + return; + } $world->timings->syncChunkSend->startTiming(); try{ $this->queueCompressed($promise); diff --git a/src/player/Player.php b/src/player/Player.php index 6d459b8d4e..4036944ab8 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -744,13 +744,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->usedChunks[$index] = UsedChunkStatus::REQUESTED(); $this->getNetworkSession()->startUsingChunk($X, $Z, function() use ($X, $Z, $index) : void{ - if(!$this->usedChunks[$index]->equals(UsedChunkStatus::REQUESTED())){ - //TODO: make this an error - //this could be triggered due to the shitty way that chunk resends are handled - //right now - not because of the spammy re-requesting, but because the chunk status reverts - //to NEEDED if they want to be resent. - return; - } $this->usedChunks[$index] = UsedChunkStatus::SENT(); if($this->spawnChunkLoadCount === -1){ $this->spawnEntitiesOnChunk($X, $Z); @@ -876,6 +869,13 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return $this->usedChunks; } + /** + * Returns a usage status of the given chunk, or null if the player is not using the given chunk. + */ + public function getUsedChunkStatus(int $chunkX, int $chunkZ) : ?UsedChunkStatus{ + return $this->usedChunks[World::chunkHash($chunkX, $chunkZ)] ?? null; + } + /** * Returns whether the target chunk has been sent to this player. */ diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index e0249525f5..2ee289468d 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -101,12 +101,12 @@ parameters: path: ../../../src/network/mcpe/NetworkSession.php - - message: "#^Cannot call method getWorld\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" + message: "#^Cannot call method getUsedChunkStatus\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" count: 1 path: ../../../src/network/mcpe/NetworkSession.php - - message: "#^Cannot call method isUsingChunk\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" + message: "#^Cannot call method getWorld\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" count: 1 path: ../../../src/network/mcpe/NetworkSession.php From 4f4069d40361bee139c1bc597f6185af25945dfb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Apr 2021 00:55:42 +0100 Subject: [PATCH 2408/3224] World: remove another noisy debug message --- src/world/World.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 4ded21ddc6..a0e6ad6d93 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2077,8 +2077,6 @@ class World implements ChunkManager{ if(!isset($this->activeChunkPopulationTasks[$nextChunkHash])){ $failed[] = $nextChunkHash; } - }else{ - $this->logger->debug("Population request for chunk $nextChunkX $nextChunkZ was discarded before it could be fulfilled"); } } From 6845cbb2b35d368c237439c4bba988ffbc5850d9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Apr 2021 01:02:22 +0100 Subject: [PATCH 2409/3224] Silence LevelSoundEventPacket noise --- src/network/mcpe/handler/InGamePacketHandler.php | 11 +++++++++++ src/network/mcpe/protocol/LevelSoundEventPacket.php | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index bd49cb54e1..cc45e87c8b 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -62,6 +62,7 @@ use pocketmine\network\mcpe\protocol\InteractPacket; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket; use pocketmine\network\mcpe\protocol\LabTablePacket; +use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacketV1; use pocketmine\network\mcpe\protocol\MapInfoRequestPacket; use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket; @@ -851,4 +852,14 @@ class InGamePacketHandler extends PacketHandler{ public function handleNetworkStackLatency(NetworkStackLatencyPacket $packet) : bool{ return true; //TODO: implement this properly - this is here to silence debug spam from MCPE dev builds } + + public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{ + /* + * We don't handle this - all sounds are handled by the server now. + * However, some plugins find this useful to detect events like left-click-air, which doesn't have any other + * action bound to it. + * In addition, we use this handler to silence debug noise, since this packet is frequently sent by the client. + */ + return true; + } } diff --git a/src/network/mcpe/protocol/LevelSoundEventPacket.php b/src/network/mcpe/protocol/LevelSoundEventPacket.php index cafda0b100..45052d6e08 100644 --- a/src/network/mcpe/protocol/LevelSoundEventPacket.php +++ b/src/network/mcpe/protocol/LevelSoundEventPacket.php @@ -28,7 +28,7 @@ namespace pocketmine\network\mcpe\protocol; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -class LevelSoundEventPacket extends DataPacket implements ClientboundPacket, GarbageServerboundPacket{ +class LevelSoundEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ public const NETWORK_ID = ProtocolInfo::LEVEL_SOUND_EVENT_PACKET; public const SOUND_ITEM_USE_ON = 0; From 66fdf526d4abe0727f1a59c43492365e68f8ff93 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Apr 2021 01:07:21 +0100 Subject: [PATCH 2410/3224] Remove GarbageServerboundPacket it's not the protocol implementation's job to decide what's garbage. It should only indicate that a packet MAY be sent by the client. It should then be up to the handler to decide what to do with it. --- src/network/mcpe/NetworkSession.php | 5 --- .../mcpe/handler/InGamePacketHandler.php | 5 +++ .../protocol/GarbageServerboundPacket.php | 32 ------------------- .../mcpe/protocol/SetActorMotionPacket.php | 5 +-- 4 files changed, 6 insertions(+), 41 deletions(-) delete mode 100644 src/network/mcpe/protocol/GarbageServerboundPacket.php diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index df021acf26..ba0df464b6 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -59,7 +59,6 @@ use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\DisconnectPacket; -use pocketmine\network\mcpe\protocol\GarbageServerboundPacket; use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket; use pocketmine\network\mcpe\protocol\MobEffectPacket; use pocketmine\network\mcpe\protocol\MobEquipmentPacket; @@ -376,10 +375,6 @@ class NetworkSession{ */ public function handleDataPacket(Packet $packet, string $buffer) : void{ if(!($packet instanceof ServerboundPacket)){ - if($packet instanceof GarbageServerboundPacket){ - $this->logger->debug("Garbage serverbound " . $packet->getName() . ": " . base64_encode($buffer)); - return; - } throw new PacketHandlingException("Unexpected non-serverbound packet"); } diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index cc45e87c8b..c7b28d156e 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -76,6 +76,7 @@ use pocketmine\network\mcpe\protocol\PlayerInputPacket; use pocketmine\network\mcpe\protocol\PlayerSkinPacket; use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; use pocketmine\network\mcpe\protocol\ServerSettingsRequestPacket; +use pocketmine\network\mcpe\protocol\SetActorMotionPacket; use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; use pocketmine\network\mcpe\protocol\ShowCreditsPacket; use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket; @@ -581,6 +582,10 @@ class InGamePacketHandler extends PacketHandler{ return true; } + public function handleSetActorMotion(SetActorMotionPacket $packet) : bool{ + return true; //Not used: This packet is (erroneously) sent to the server when the client is riding a vehicle. + } + public function handleAnimate(AnimatePacket $packet) : bool{ return true; //Not used } diff --git a/src/network/mcpe/protocol/GarbageServerboundPacket.php b/src/network/mcpe/protocol/GarbageServerboundPacket.php deleted file mode 100644 index 04870b1252..0000000000 --- a/src/network/mcpe/protocol/GarbageServerboundPacket.php +++ /dev/null @@ -1,32 +0,0 @@ - Date: Mon, 19 Apr 2021 09:41:51 -0300 Subject: [PATCH 2411/3224] Added CancelTaskException (#4186) --- src/scheduler/CancelTaskException.php | 32 +++++++++++++ src/scheduler/Task.php | 2 + src/scheduler/TaskHandler.php | 2 + tests/phpunit/scheduler/TaskSchedulerTest.php | 48 +++++++++++++++++++ 4 files changed, 84 insertions(+) create mode 100644 src/scheduler/CancelTaskException.php create mode 100644 tests/phpunit/scheduler/TaskSchedulerTest.php diff --git a/src/scheduler/CancelTaskException.php b/src/scheduler/CancelTaskException.php new file mode 100644 index 0000000000..a500c4d78f --- /dev/null +++ b/src/scheduler/CancelTaskException.php @@ -0,0 +1,32 @@ +timings->startTiming(); try{ $this->task->onRun(); + }catch(CancelTaskException $e){ + $this->cancel(); }finally{ $this->timings->stopTiming(); } diff --git a/tests/phpunit/scheduler/TaskSchedulerTest.php b/tests/phpunit/scheduler/TaskSchedulerTest.php new file mode 100644 index 0000000000..bcb1ae97e6 --- /dev/null +++ b/tests/phpunit/scheduler/TaskSchedulerTest.php @@ -0,0 +1,48 @@ +scheduler = new TaskScheduler(); + } + + public function tearDown() : void{ + $this->scheduler->shutdown(); + } + + public function testCancel() : void{ + $task = $this->scheduler->scheduleTask(new ClosureTask(function() : void{ + throw new CancelTaskException(); + })); + $this->scheduler->mainThreadHeartbeat(0); + self::assertTrue($task->isCancelled(), "Task was not cancelled"); + } +} From 94928c030aea7f2dd03e226b63bf11a0440142d4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Apr 2021 14:00:23 +0100 Subject: [PATCH 2412/3224] Removed CancellableClosureTask --- src/scheduler/CancellableClosureTask.php | 76 ------------------------ 1 file changed, 76 deletions(-) delete mode 100644 src/scheduler/CancellableClosureTask.php diff --git a/src/scheduler/CancellableClosureTask.php b/src/scheduler/CancellableClosureTask.php deleted file mode 100644 index 68d2fa946c..0000000000 --- a/src/scheduler/CancellableClosureTask.php +++ /dev/null @@ -1,76 +0,0 @@ -scheduleTask(new CancellableClosureTask(function() : bool{ - * echo "HI\n"; - * $continue = false; - * return $continue; //stop repeating - * }); - * ``` - * - * @see ClosureTask - */ -class CancellableClosureTask extends Task{ - public const CONTINUE = true; - public const CANCEL = false; - - /** - * @var \Closure - * @phpstan-var \Closure() : bool - */ - private $closure; - - /** - * CancellableClosureTask constructor. - * - * The closure should follow the signature callback() : bool. The return value will be used to - * decide whether to continue repeating. - * - * @phpstan-param \Closure() : bool $closure - */ - public function __construct(\Closure $closure){ - Utils::validateCallableSignature(function() : bool{ return false; }, $closure); - $this->closure = $closure; - } - - public function getName() : string{ - return Utils::getNiceClosureName($this->closure); - } - - public function onRun() : void{ - if(!($this->closure)()){ - $this->getHandler()->cancel(); - } - } -} From dc51af8b666d690b02ebd7168fd979ee5230cd48 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Apr 2021 14:00:54 +0100 Subject: [PATCH 2413/3224] changelog: mention CancelTaskException addition [ci skip] --- changelogs/4.0-snapshot.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 5de84af61d..9bab171cb1 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -770,6 +770,7 @@ This version features substantial changes to the network system, improving coher - `AsyncPool` uses a new, significantly more performant algorithm for task collection. - `BulkCurlTask` has had the `$complexData` constructor parameter removed. - `BulkCurlTask->__construct()` now accepts `BulkCurlTaskOperation[]` instead of `mixed[]`. +- Added `CancelTaskException`, which can be thrown from `Task::onRun()` to cancel a task (especially useful for `ClosureTask`). - `pocketmine\Collectable` has been removed, and is no longer extended by `AsyncTask`. - The following hooks have been added: - `AsyncTask->onError()`: called on the main thread when an uncontrolled error was detected in the async task, such as a memory failure From 73f913e279463a5c092a1ab7e7f804ab87b234db Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Apr 2021 14:16:05 +0100 Subject: [PATCH 2414/3224] Modernize TesterPlugin --- .../TesterPlugin/CheckTestCompletionTask.php | 50 ------------------- .../src/pmmp/TesterPlugin/Main.php | 25 +++++++--- 2 files changed, 17 insertions(+), 58 deletions(-) delete mode 100644 tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/CheckTestCompletionTask.php diff --git a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/CheckTestCompletionTask.php b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/CheckTestCompletionTask.php deleted file mode 100644 index b7ca749b61..0000000000 --- a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/CheckTestCompletionTask.php +++ /dev/null @@ -1,50 +0,0 @@ -plugin = $plugin; - } - - public function onRun() : void{ - $test = $this->plugin->getCurrentTest(); - if($test === null){ - if(!$this->plugin->startNextTest()){ - $this->getHandler()->cancel(); - $this->plugin->onAllTestsCompleted(); - } - }elseif($test->isFinished() or $test->isTimedOut()){ - $this->plugin->onTestCompleted($test); - }else{ - $test->tick(); - } - } -} diff --git a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/Main.php b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/Main.php index be6e369c32..73535da293 100644 --- a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/Main.php +++ b/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/Main.php @@ -26,6 +26,8 @@ namespace pmmp\TesterPlugin; use pocketmine\event\Listener; use pocketmine\event\server\CommandEvent; use pocketmine\plugin\PluginBase; +use pocketmine\scheduler\CancelTaskException; +use pocketmine\scheduler\ClosureTask; use function array_shift; class Main extends PluginBase implements Listener{ @@ -41,7 +43,18 @@ class Main extends PluginBase implements Listener{ public function onEnable() : void{ $this->getServer()->getPluginManager()->registerEvents($this, $this); - $this->getScheduler()->scheduleRepeatingTask(new CheckTestCompletionTask($this), 10); + $this->getScheduler()->scheduleRepeatingTask(new ClosureTask(function() : void{ + if($this->currentTest === null){ + if(!$this->startNextTest()){ + $this->onAllTestsCompleted(); + throw new CancelTaskException(); + } + }elseif($this->currentTest->isFinished() || $this->currentTest->isTimedOut()){ + $this->onTestCompleted($this->currentTest); + }else{ + $this->currentTest->tick(); + } + }), 10); $this->waitingTests = []; } @@ -56,11 +69,7 @@ class Main extends PluginBase implements Listener{ } } - public function getCurrentTest() : ?Test{ - return $this->currentTest; - } - - public function startNextTest() : bool{ + private function startNextTest() : bool{ $this->currentTest = array_shift($this->waitingTests); if($this->currentTest !== null){ $this->getLogger()->notice("Running test #" . (++$this->currentTestNumber) . " (" . $this->currentTest->getName() . ")"); @@ -71,7 +80,7 @@ class Main extends PluginBase implements Listener{ return false; } - public function onTestCompleted(Test $test) : void{ + private function onTestCompleted(Test $test) : void{ $message = "Finished test #" . $this->currentTestNumber . " (" . $test->getName() . "): "; switch($test->getResult()){ case Test::RESULT_OK: @@ -97,7 +106,7 @@ class Main extends PluginBase implements Listener{ $this->currentTest = null; } - public function onAllTestsCompleted() : void{ + private function onAllTestsCompleted() : void{ $this->getLogger()->notice("All tests finished, stopping the server"); $this->getServer()->shutdown(); } From 4e0bc6c98e29f6e564879a0b771414a725cc24b6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Apr 2021 16:18:22 +0100 Subject: [PATCH 2415/3224] Scrub PHPStan baselines --- .../check-explicit-mixed-baseline.neon | 25 ------------------- tests/phpstan/configs/l7-baseline.neon | 5 ---- tests/phpstan/configs/l8-baseline.neon | 10 -------- 3 files changed, 40 deletions(-) diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index 39cdc58021..0fe171efdb 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -295,26 +295,6 @@ parameters: count: 1 path: ../../../src/world/World.php - - - message: "#^Cannot cast mixed to string\\.$#" - count: 1 - path: ../../../src/world/format/io/data/BedrockWorldData.php - - - - message: "#^Parameter \\#2 \\$value of method pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\:\\:setString\\(\\) expects string, mixed given\\.$#" - count: 1 - path: ../../../src/world/format/io/data/BedrockWorldData.php - - - - message: "#^Cannot cast mixed to string\\.$#" - count: 1 - path: ../../../src/world/format/io/data/JavaWorldData.php - - - - message: "#^Parameter \\#2 \\$value of method pocketmine\\\\nbt\\\\tag\\\\CompoundTag\\:\\:setString\\(\\) expects string, mixed given\\.$#" - count: 1 - path: ../../../src/world/format/io/data/JavaWorldData.php - - message: "#^Cannot access offset 1 on mixed\\.$#" count: 2 @@ -325,11 +305,6 @@ parameters: count: 2 path: ../../../src/world/format/io/region/RegionWorldProvider.php - - - message: "#^Property pocketmine\\\\world\\\\generator\\\\Flat\\:\\:\\$preset \\(string\\) does not accept mixed\\.$#" - count: 1 - path: ../../../src/world/generator/Flat.php - - message: "#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#" count: 1 diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index e54fab02b5..496df83119 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -940,11 +940,6 @@ parameters: count: 2 path: ../../../src/world/format/Chunk.php - - - message: "#^Parameter \\#1 \\$className of static method pocketmine\\\\utils\\\\Utils\\:\\:testValidInstance\\(\\) expects class\\-string, string given\\.$#" - count: 1 - path: ../../../src/world/format/io/FormatConverter.php - - message: "#^Only numeric types are allowed in %%, int\\|false given on the left side\\.$#" count: 1 diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 2ee289468d..b68a7df7a3 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -250,11 +250,6 @@ parameters: count: 1 path: ../../../src/scheduler/AsyncTask.php - - - message: "#^Cannot call method cancel\\(\\) on pocketmine\\\\scheduler\\\\TaskHandler\\|null\\.$#" - count: 1 - path: ../../../src/scheduler/CancellableClosureTask.php - - message: "#^Cannot call method getAsyncWorkerId\\(\\) on pocketmine\\\\scheduler\\\\AsyncWorker\\|null\\.$#" count: 1 @@ -510,8 +505,3 @@ parameters: count: 1 path: ../../phpunit/event/HandlerListManagerTest.php - - - message: "#^Cannot call method cancel\\(\\) on pocketmine\\\\scheduler\\\\TaskHandler\\|null\\.$#" - count: 1 - path: ../../plugins/TesterPlugin/src/pmmp/TesterPlugin/CheckTestCompletionTask.php - From fc01735b6fbd71112412c127ef75537803b600ac Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Apr 2021 23:01:57 +0100 Subject: [PATCH 2416/3224] Fixed infinite loop when placing two coral plants next to each other the dead flag is not persisted in their metadata, so they forget their state when next read from the world. --- src/block/Coral.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/block/Coral.php b/src/block/Coral.php index ad535ec7b5..fd74e69ccc 100644 --- a/src/block/Coral.php +++ b/src/block/Coral.php @@ -30,6 +30,18 @@ use pocketmine\world\BlockTransaction; final class Coral extends BaseCoral{ + public function readStateFromWorld() : void{ + //TODO: this hack ensures correct state of coral plants, because they don't retain their dead flag in metadata + $world = $this->pos->getWorld(); + $this->dead = true; + foreach($this->pos->sides() as $vector3){ + if($world->getBlock($vector3) instanceof Water){ + $this->dead = false; + break; + } + } + } + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$tx->fetchBlock($blockReplace->getPos()->down())->isSolid()){ return false; From 127b57048c920c5e99addeb117f5d4e9b9c23133 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Fri, 23 Apr 2021 19:34:46 +0100 Subject: [PATCH 2417/3224] Allow plugins to use PSR-4 namespace mapping (#4188) * Allow plugins to use PSR-4 namespace mapping this is a reduced implementation which serves the 99% use case without being horribly breakable. Plugins may now specify a `src-namespace-prefix`, which should be set to the namespace of the classes in `src`. If the old system is used, `src-namespace-prefix` can be omitted, or set to an empty string. Examples: - If `src-namespace-prefix` is `dktapps\test`, `dktapps\test\Main` will be searched for in `src/Main.php`, instead of `src/dktapps/test/Main.php`. * Migrate TesterPlugin to PSR-4 --- composer.lock | 10 +++++----- src/plugin/PharPluginLoader.php | 5 ++++- src/plugin/PluginDescription.php | 5 +++++ .../phpstan/configs/check-explicit-mixed-baseline.neon | 5 +++++ tests/plugins/DevTools | 2 +- tests/plugins/TesterPlugin/plugin.yml | 1 + .../TesterPlugin/src/{pmmp/TesterPlugin => }/Main.php | 0 .../TesterPlugin/src/{pmmp/TesterPlugin => }/Test.php | 0 .../{pmmp/TesterPlugin => }/TestFailedException.php | 0 9 files changed, 21 insertions(+), 7 deletions(-) rename tests/plugins/TesterPlugin/src/{pmmp/TesterPlugin => }/Main.php (100%) rename tests/plugins/TesterPlugin/src/{pmmp/TesterPlugin => }/Test.php (100%) rename tests/plugins/TesterPlugin/src/{pmmp/TesterPlugin => }/TestFailedException.php (100%) diff --git a/composer.lock b/composer.lock index 87b4f7b317..c476cc86d3 100644 --- a/composer.lock +++ b/composer.lock @@ -415,12 +415,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/ClassLoader.git", - "reference": "c0133050639cd4a8baefc56a4f334f269c66a7e0" + "reference": "9fb3957cbfe5b37dae8952e072b35540fb4d9aa7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/c0133050639cd4a8baefc56a4f334f269c66a7e0", - "reference": "c0133050639cd4a8baefc56a4f334f269c66a7e0", + "url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/9fb3957cbfe5b37dae8952e072b35540fb4d9aa7", + "reference": "9fb3957cbfe5b37dae8952e072b35540fb4d9aa7", "shasum": "" }, "require": { @@ -433,7 +433,7 @@ }, "require-dev": { "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "0.12.66", + "phpstan/phpstan": "0.12.80", "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", @@ -451,7 +451,7 @@ "issues": "https://github.com/pmmp/ClassLoader/issues", "source": "https://github.com/pmmp/ClassLoader/tree/master" }, - "time": "2021-01-15T00:41:29+00:00" + "time": "2021-04-19T14:36:23+00:00" }, { "name": "pocketmine/color", diff --git a/src/plugin/PharPluginLoader.php b/src/plugin/PharPluginLoader.php index 2907a0e601..d42fa0b5ec 100644 --- a/src/plugin/PharPluginLoader.php +++ b/src/plugin/PharPluginLoader.php @@ -48,7 +48,10 @@ class PharPluginLoader implements PluginLoader{ * Loads the plugin contained in $file */ public function loadPlugin(string $file) : void{ - $this->loader->addPath("$file/src"); + $description = $this->getPluginDescription($file); + if($description !== null){ + $this->loader->addPath($description->getSrcNamespacePrefix(), "$file/src"); + } } /** diff --git a/src/plugin/PluginDescription.php b/src/plugin/PluginDescription.php index 506fe8154c..02a81da480 100644 --- a/src/plugin/PluginDescription.php +++ b/src/plugin/PluginDescription.php @@ -48,6 +48,7 @@ class PluginDescription{ private $name; /** @var string */ private $main; + private string $srcNamespacePrefix = ""; /** @var string[] */ private $api; /** @var int[] */ @@ -114,6 +115,8 @@ class PluginDescription{ throw new PluginException("Invalid Plugin main, cannot start within the PocketMine namespace"); } + $this->srcNamespacePrefix = $plugin["src-namespace-prefix"] ?? ""; + $this->api = array_map("\strval", (array) ($plugin["api"] ?? [])); $this->compatibleMcpeProtocols = array_map("\intval", (array) ($plugin["mcpe-protocol"] ?? [])); $this->compatibleOperatingSystems = array_map("\strval", (array) ($plugin["os"] ?? [])); @@ -284,6 +287,8 @@ class PluginDescription{ return $this->main; } + public function getSrcNamespacePrefix() : string{ return $this->srcNamespacePrefix; } + public function getName() : string{ return $this->name; } diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index 0fe171efdb..d746d6d604 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -210,6 +210,11 @@ parameters: count: 1 path: ../../../src/plugin/PluginDescription.php + - + message: "#^Property pocketmine\\\\plugin\\\\PluginDescription\\:\\:\\$srcNamespacePrefix \\(string\\) does not accept mixed\\.$#" + count: 1 + path: ../../../src/plugin/PluginDescription.php + - message: "#^Parameter \\#1 \\$plugins of class pocketmine\\\\plugin\\\\PluginGraylist constructor expects array\\, mixed given\\.$#" count: 1 diff --git a/tests/plugins/DevTools b/tests/plugins/DevTools index 888d021260..dfbea943e1 160000 --- a/tests/plugins/DevTools +++ b/tests/plugins/DevTools @@ -1 +1 @@ -Subproject commit 888d021260efa5456cd7cc0174fb3a2663960811 +Subproject commit dfbea943e1c64094358acac56013b89065884657 diff --git a/tests/plugins/TesterPlugin/plugin.yml b/tests/plugins/TesterPlugin/plugin.yml index 1cb9f9a1f1..dc00d97c79 100644 --- a/tests/plugins/TesterPlugin/plugin.yml +++ b/tests/plugins/TesterPlugin/plugin.yml @@ -1,5 +1,6 @@ name: TesterPlugin main: pmmp\TesterPlugin\Main +src-namespace-prefix: pmmp\TesterPlugin version: 0.1.0 api: [3.2.0, 4.0.0] load: POSTWORLD diff --git a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/Main.php b/tests/plugins/TesterPlugin/src/Main.php similarity index 100% rename from tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/Main.php rename to tests/plugins/TesterPlugin/src/Main.php diff --git a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/Test.php b/tests/plugins/TesterPlugin/src/Test.php similarity index 100% rename from tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/Test.php rename to tests/plugins/TesterPlugin/src/Test.php diff --git a/tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/TestFailedException.php b/tests/plugins/TesterPlugin/src/TestFailedException.php similarity index 100% rename from tests/plugins/TesterPlugin/src/pmmp/TesterPlugin/TestFailedException.php rename to tests/plugins/TesterPlugin/src/TestFailedException.php From 7ce77713dd37ee7f435934cc45abcfc605973c93 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 27 Apr 2021 14:40:43 +0100 Subject: [PATCH 2418/3224] InventoryManager: add a mechanism to allow plugins to inject their own container open packet creators closes #4008 --- src/network/mcpe/InventoryManager.php | 51 +++++++++++++++++++-------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index 3f66c334e9..fd0e9b2420 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -35,6 +35,7 @@ use pocketmine\inventory\transaction\action\SlotChangeAction; use pocketmine\inventory\transaction\InventoryTransaction; use pocketmine\item\Item; use pocketmine\network\mcpe\convert\TypeConverter; +use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\ContainerClosePacket; use pocketmine\network\mcpe\protocol\ContainerOpenPacket; use pocketmine\network\mcpe\protocol\ContainerSetDataPacket; @@ -47,10 +48,14 @@ use pocketmine\network\mcpe\protocol\types\inventory\CreativeContentEntry; use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper; use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes; use pocketmine\player\Player; +use pocketmine\utils\ObjectSet; use function array_map; use function array_search; use function max; +/** + * @phpstan-type ContainerOpenClosure \Closure(int $id, Inventory $inventory) : list|null + */ class InventoryManager{ //TODO: HACK! @@ -79,10 +84,16 @@ class InventoryManager{ /** @var int */ private $clientSelectedHotbarSlot = -1; + /** @phpstan-var ObjectSet */ + private ObjectSet $containerOpenCallbacks; + public function __construct(Player $player, NetworkSession $session){ $this->player = $player; $this->session = $session; + $this->containerOpenCallbacks = new ObjectSet(); + $this->containerOpenCallbacks->add(\Closure::fromCallable([self::class, 'createContainerOpen'])); + $this->add(ContainerIds::INVENTORY, $this->player->getInventory()); $this->add(ContainerIds::ARMOR, $this->player->getArmorInventory()); $this->add(ContainerIds::UI, $this->player->getCursorInventory()); @@ -125,32 +136,44 @@ class InventoryManager{ $this->onCurrentWindowRemove(); $this->add($this->lastInventoryNetworkId = max(ContainerIds::FIRST, ($this->lastInventoryNetworkId + 1) % self::RESERVED_WINDOW_ID_RANGE_START), $inventory); - $pk = $this->createContainerOpen($this->lastInventoryNetworkId, $inventory); - if($pk !== null){ - $this->session->sendDataPacket($pk); - $this->syncContents($inventory); - }else{ - throw new \UnsupportedOperationException("Unsupported inventory type"); + foreach($this->containerOpenCallbacks as $callback){ + $pks = $callback($this->lastInventoryNetworkId, $inventory); + if($pks !== null){ + foreach($pks as $pk){ + $this->session->sendDataPacket($pk); + } + $this->syncContents($inventory); + } + return; } + throw new \UnsupportedOperationException("Unsupported inventory type"); } - protected function createContainerOpen(int $id, Inventory $inv) : ?ContainerOpenPacket{ - //TODO: allow plugins to inject this + /** @phpstan-return ObjectSet */ + public function getContainerOpenCallbacks() : ObjectSet{ return $this->containerOpenCallbacks; } + + /** + * @return ClientboundPacket[]|null + * @phpstan-return list|null + */ + protected static function createContainerOpen(int $id, Inventory $inv) : ?array{ + //TODO: we should be using some kind of tagging system to identify the types. Instanceof is flaky especially + //if the class isn't final, not to mention being inflexible. if($inv instanceof BlockInventory){ switch(true){ case $inv instanceof FurnaceInventory: //TODO: specialized furnace types - return ContainerOpenPacket::blockInvVec3($id, WindowTypes::FURNACE, $inv->getHolder()); + return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::FURNACE, $inv->getHolder())]; case $inv instanceof EnchantInventory: - return ContainerOpenPacket::blockInvVec3($id, WindowTypes::ENCHANTMENT, $inv->getHolder()); + return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::ENCHANTMENT, $inv->getHolder())]; case $inv instanceof BrewingStandInventory: - return ContainerOpenPacket::blockInvVec3($id, WindowTypes::BREWING_STAND, $inv->getHolder()); + return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::BREWING_STAND, $inv->getHolder())]; case $inv instanceof AnvilInventory: - return ContainerOpenPacket::blockInvVec3($id, WindowTypes::ANVIL, $inv->getHolder()); + return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::ANVIL, $inv->getHolder())]; case $inv instanceof HopperInventory: - return ContainerOpenPacket::blockInvVec3($id, WindowTypes::HOPPER, $inv->getHolder()); + return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::HOPPER, $inv->getHolder())]; default: - return ContainerOpenPacket::blockInvVec3($id, WindowTypes::CONTAINER, $inv->getHolder()); + return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::CONTAINER, $inv->getHolder())]; } } return null; From 8364bc51ac670ea136d6c3190000410d3819aa03 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 27 Apr 2021 14:47:11 +0100 Subject: [PATCH 2419/3224] ... --- src/network/mcpe/InventoryManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index fd0e9b2420..ae71f67dc6 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -54,7 +54,7 @@ use function array_search; use function max; /** - * @phpstan-type ContainerOpenClosure \Closure(int $id, Inventory $inventory) : list|null + * @phpstan-type ContainerOpenClosure \Closure(int $id, Inventory $inventory) : (list|null) */ class InventoryManager{ From 845819123ddefa5417a0856010a787b0e582ae61 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 27 Apr 2021 14:49:26 +0100 Subject: [PATCH 2420/3224] Player: drop perm nulling this is no longer necessary because the PermissibleBase doesn't keep a ref to the Player anymore. --- src/player/Player.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index 4036944ab8..240e7f0bcc 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2018,7 +2018,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->cursorInventory = null; $this->craftingGrid = null; $this->spawnPosition = null; - $this->perm = null; $this->blockBreakHandler = null; parent::destroyCycles(); } From 017ca55a58be689ba4e12dcc13f53f02f5efd5bf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 27 Apr 2021 15:19:55 +0100 Subject: [PATCH 2421/3224] Vine: use facing as both keys and values --- src/block/Vine.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/block/Vine.php b/src/block/Vine.php index ac76a81b57..a247b06e3d 100644 --- a/src/block/Vine.php +++ b/src/block/Vine.php @@ -35,7 +35,7 @@ use function count; class Vine extends Flowable{ - /** @var bool[] */ + /** @var int[] */ protected $faces = []; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ @@ -63,7 +63,7 @@ class Vine extends Flowable{ private function setFaceFromMeta(int $meta, int $flag, int $face) : void{ if(($meta & $flag) !== 0){ - $this->faces[$face] = true; + $this->faces[$face] = $face; }else{ unset($this->faces[$face]); } @@ -96,7 +96,7 @@ class Vine extends Flowable{ } $this->faces = $blockReplace instanceof Vine ? $blockReplace->faces : []; - $this->faces[Facing::opposite($face)] = true; + $this->faces[Facing::opposite($face)] = Facing::opposite($face); return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } @@ -108,7 +108,7 @@ class Vine extends Flowable{ //check which faces have corresponding vines in the block above $supportedFaces = $up instanceof Vine ? array_intersect_key($this->faces, $up->faces) : []; - foreach($this->faces as $face => $bool){ + foreach($this->faces as $face){ if(!isset($supportedFaces[$face]) and !$this->getSide($face)->isSolid()){ unset($this->faces[$face]); $changed = true; From 0aa0d77307dcc52b64c5c69b37aff2b62d124b70 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 27 Apr 2021 19:21:29 +0100 Subject: [PATCH 2422/3224] Skull: recognize noDrops flag --- src/block/BlockLegacyMetadata.php | 2 ++ src/block/Skull.php | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/block/BlockLegacyMetadata.php b/src/block/BlockLegacyMetadata.php index 57189ffbe9..e226a0c654 100644 --- a/src/block/BlockLegacyMetadata.php +++ b/src/block/BlockLegacyMetadata.php @@ -201,6 +201,8 @@ final class BlockLegacyMetadata{ public const SEA_PICKLE_FLAG_NOT_UNDERWATER = 0x04; + public const SKULL_FLAG_NO_DROPS = 0x08; + public const SLAB_FLAG_UPPER = 0x08; public const SPONGE_FLAG_WET = 0x01; diff --git a/src/block/Skull.php b/src/block/Skull.php index 8b60f5deab..80250ff582 100644 --- a/src/block/Skull.php +++ b/src/block/Skull.php @@ -45,6 +45,8 @@ class Skull extends Flowable{ /** @var int */ protected $facing = Facing::NORTH; + protected bool $noDrops = false; + /** @var int */ protected $rotation = 0; //TODO: split this into floor skull and wall skull handling @@ -54,15 +56,17 @@ class Skull extends Flowable{ } protected function writeStateToMeta() : int{ - return $this->facing === Facing::UP ? 1 : BlockDataSerializer::writeHorizontalFacing($this->facing); + return ($this->facing === Facing::UP ? 1 : BlockDataSerializer::writeHorizontalFacing($this->facing)) | + ($this->noDrops ? BlockLegacyMetadata::SKULL_FLAG_NO_DROPS : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ $this->facing = $stateMeta === 1 ? Facing::UP : BlockDataSerializer::readHorizontalFacing($stateMeta); + $this->noDrops = ($stateMeta & BlockLegacyMetadata::SKULL_FLAG_NO_DROPS) !== 0; } public function getStateBitmask() : int{ - return 0b111; + return 0b1111; } public function readStateFromWorld() : void{ From c9cf33b21bd0226e6e038adbfc7b41c5db4ec29b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 27 Apr 2021 19:22:45 +0100 Subject: [PATCH 2423/3224] Skull: added block property APIs I need these for my R13 block deserializer. --- src/block/Skull.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/block/Skull.php b/src/block/Skull.php index 80250ff582..9a3c09aa43 100644 --- a/src/block/Skull.php +++ b/src/block/Skull.php @@ -91,6 +91,25 @@ class Skull extends Flowable{ return $this->skullType; } + public function getFacing() : int{ return $this->facing; } + + /** @return $this */ + public function setFacing(int $facing) : self{ + if($facing === Facing::DOWN){ + throw new \InvalidArgumentException("Skull may not face DOWN"); + } + $this->facing = $facing; + return $this; + } + + public function isNoDrops() : bool{ return $this->noDrops; } + + /** @return $this */ + public function setNoDrops(bool $noDrops) : self{ + $this->noDrops = $noDrops; + return $this; + } + /** * @return AxisAlignedBB[] */ From ed80490234b41e6af3618f14b48cde47f6609d62 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 27 Apr 2021 19:31:08 +0100 Subject: [PATCH 2424/3224] Added more APIs to Skull setRotation() is conditionally useless, but there's not much we can do about this right now; and exposing it like this is better than having plugins interacting with tiles. --- src/block/Skull.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/block/Skull.php b/src/block/Skull.php index 9a3c09aa43..6b5f13adb6 100644 --- a/src/block/Skull.php +++ b/src/block/Skull.php @@ -91,6 +91,12 @@ class Skull extends Flowable{ return $this->skullType; } + /** @return $this */ + public function setSkullType(SkullType $skullType) : self{ + $this->skullType = $skullType; + return $this; + } + public function getFacing() : int{ return $this->facing; } /** @return $this */ @@ -102,6 +108,17 @@ class Skull extends Flowable{ return $this; } + public function getRotation() : int{ return $this->rotation; } + + /** @return $this */ + public function setRotation(int $rotation) : self{ + if($rotation < 0 || $rotation > 15){ + throw new \InvalidArgumentException("Rotation must be a value between 0 and 15"); + } + $this->rotation = $rotation; + return $this; + } + public function isNoDrops() : bool{ return $this->noDrops; } /** @return $this */ From 11263909ab394871c5f5ee72d9f8f0e756d70a0a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 27 Apr 2021 20:35:51 +0100 Subject: [PATCH 2425/3224] Added stripped logs (incomplete) this isn't practical to fully implement right now due to limitations imposed by the legacy shitfest system we're using. To make stripped dynamic, we would need to switch the IDs _and_ variant info dynamically, and I have no idea what bizarre side effects that might have. --- src/block/BlockFactory.php | 5 +++-- src/block/BlockLegacyIdHelper.php | 18 ++++++++++++++++++ src/block/Log.php | 4 ++++ src/block/VanillaBlocks.php | 12 ++++++++++++ src/block/Wood.php | 18 +++++++++++++++++- 5 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index bf85505dea..926bae0df3 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -403,12 +403,13 @@ class BlockFactory{ //TODO: find a better way to deal with this split $this->register(new Leaves(new BID($magicNumber >= 4 ? Ids::LEAVES2 : Ids::LEAVES, $magicNumber & 0x03), $name . " Leaves", $treeType)); - $this->register(new Log(new BID($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, $magicNumber & 0x03), $name . " Log", $treeType)); + $this->register(new Log(new BID($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, $magicNumber & 0x03), $name . " Log", $treeType, false)); - $wood = new Wood(new BID(Ids::WOOD, $magicNumber), $name . " Wood", $treeType); + $wood = new Wood(new BID(Ids::WOOD, $magicNumber), $name . " Wood", $treeType, false); $this->register($wood); $this->remap($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, ($magicNumber & 0x03) | 0b1100, $wood); + $this->register(new Log(BlockLegacyIdHelper::getStrippedLogIdentifier($treeType), "Stripped " . $treeType->getDisplayName() . " Log", $treeType, true)); $this->register(new FenceGate(BlockLegacyIdHelper::getWoodenFenceIdentifier($treeType), $treeType->getDisplayName() . " Fence Gate")); $this->register(new WoodenStairs(BlockLegacyIdHelper::getWoodenStairsIdentifier($treeType), $treeType->getDisplayName() . " Stairs")); $this->register(new WoodenDoor(BlockLegacyIdHelper::getWoodenDoorIdentifier($treeType), $treeType->getDisplayName() . " Door")); diff --git a/src/block/BlockLegacyIdHelper.php b/src/block/BlockLegacyIdHelper.php index c9408afb5c..082f5132a4 100644 --- a/src/block/BlockLegacyIdHelper.php +++ b/src/block/BlockLegacyIdHelper.php @@ -178,6 +178,24 @@ final class BlockLegacyIdHelper{ throw new AssumptionFailedError("Switch should cover all wood types"); } + public static function getStrippedLogIdentifier(TreeType $treeType) : BlockIdentifier{ + switch($treeType->id()){ + case TreeType::OAK()->id(): + return new BlockIdentifier(Ids::STRIPPED_OAK_LOG, 0); + case TreeType::SPRUCE()->id(): + return new BlockIdentifier(Ids::STRIPPED_SPRUCE_LOG, 0); + case TreeType::BIRCH()->id(): + return new BlockIdentifier(Ids::STRIPPED_BIRCH_LOG, 0); + case TreeType::JUNGLE()->id(): + return new BlockIdentifier(Ids::STRIPPED_JUNGLE_LOG, 0); + case TreeType::ACACIA()->id(): + return new BlockIdentifier(Ids::STRIPPED_ACACIA_LOG, 0); + case TreeType::DARK_OAK()->id(): + return new BlockIdentifier(Ids::STRIPPED_DARK_OAK_LOG, 0); + } + throw new AssumptionFailedError("Switch should cover all wood types"); + } + public static function getGlazedTerracottaIdentifier(DyeColor $color) : BlockIdentifier{ switch($color->id()){ case DyeColor::WHITE()->id(): diff --git a/src/block/Log.php b/src/block/Log.php index 06364c746b..eacb817b51 100644 --- a/src/block/Log.php +++ b/src/block/Log.php @@ -27,4 +27,8 @@ use pocketmine\block\utils\PillarRotationInMetadataTrait; class Log extends Wood{ use PillarRotationInMetadataTrait; + + protected function getAxisMetaShift() : int{ + return $this->isStripped() ? 0 : 2; + } } diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 3f23880f9b..7cd2df77e3 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -607,6 +607,12 @@ use function assert; * @method static StonePressurePlate STONE_PRESSURE_PLATE() * @method static Slab STONE_SLAB() * @method static Stair STONE_STAIRS() + * @method static Log STRIPPED_ACACIA_LOG() + * @method static Log STRIPPED_BIRCH_LOG() + * @method static Log STRIPPED_DARK_OAK_LOG() + * @method static Log STRIPPED_JUNGLE_LOG() + * @method static Log STRIPPED_OAK_LOG() + * @method static Log STRIPPED_SPRUCE_LOG() * @method static Sugarcane SUGARCANE() * @method static DoublePlant SUNFLOWER() * @method static TallGrass TALL_GRASS() @@ -1241,6 +1247,12 @@ final class VanillaBlocks{ self::register("stone_pressure_plate", $factory->get(70, 0)); self::register("stone_slab", $factory->get(421, 2)); self::register("stone_stairs", $factory->get(435, 0)); + self::register("stripped_acacia_log", $factory->get(263, 0)); + self::register("stripped_birch_log", $factory->get(261, 0)); + self::register("stripped_dark_oak_log", $factory->get(264, 0)); + self::register("stripped_jungle_log", $factory->get(262, 0)); + self::register("stripped_oak_log", $factory->get(265, 0)); + self::register("stripped_spruce_log", $factory->get(260, 0)); self::register("sugarcane", $factory->get(83, 0)); self::register("sunflower", $factory->get(175, 0)); self::register("tall_grass", $factory->get(31, 1)); diff --git a/src/block/Wood.php b/src/block/Wood.php index 6db53bee07..56cab4cadc 100644 --- a/src/block/Wood.php +++ b/src/block/Wood.php @@ -24,13 +24,19 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\TreeType; +use pocketmine\item\Item; +use pocketmine\math\Vector3; +use pocketmine\player\Player; class Wood extends Opaque{ /** @var TreeType */ private $treeType; - public function __construct(BlockIdentifier $idInfo, string $name, TreeType $treeType, ?BlockBreakInfo $breakInfo = null){ + private bool $stripped; + + public function __construct(BlockIdentifier $idInfo, string $name, TreeType $treeType, bool $stripped, ?BlockBreakInfo $breakInfo = null){ + $this->stripped = $stripped; //TODO: this should be dynamic, but right now legacy shit gets in the way parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::AXE)); $this->treeType = $treeType; } @@ -42,6 +48,8 @@ class Wood extends Opaque{ return $this->treeType; } + public function isStripped() : bool{ return $this->stripped; } + public function getFuelTime() : int{ return 300; } @@ -53,4 +61,12 @@ class Wood extends Opaque{ public function getFlammability() : int{ return 5; } + + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if(!$this->stripped && ($item->getBlockToolType() & BlockToolType::AXE) !== 0){ + //TODO: strip logs; can't implement this yet because of legacy limitations :( + return true; + } + return false; + } } From f204d6b3dd6ef9c35d3c4cf560bf9ab00c86e126 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 27 Apr 2021 20:58:56 +0100 Subject: [PATCH 2426/3224] Make a trait for blocks which share the same horizontal facing metadata logic --- src/block/Chest.php | 17 +------- src/block/EnderChest.php | 17 +------- src/block/Furnace.php | 17 +++----- src/block/GlazedTerracotta.php | 17 +------- src/block/Ladder.php | 17 +------- src/block/WallBanner.php | 17 +------- src/block/WallSign.php | 17 +------- .../NormalHorizontalFacingInMetadataTrait.php | 40 +++++++++++++++++++ 8 files changed, 57 insertions(+), 102 deletions(-) create mode 100644 src/block/utils/NormalHorizontalFacingInMetadataTrait.php diff --git a/src/block/Chest.php b/src/block/Chest.php index 9ac729408e..85feebc24a 100644 --- a/src/block/Chest.php +++ b/src/block/Chest.php @@ -24,8 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\tile\Chest as TileChest; -use pocketmine\block\utils\BlockDataSerializer; -use pocketmine\block\utils\HorizontalFacingTrait; +use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -34,24 +33,12 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Chest extends Transparent{ - use HorizontalFacingTrait; + use NormalHorizontalFacingInMetadataTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.5, BlockToolType::AXE)); } - protected function writeStateToMeta() : int{ - return BlockDataSerializer::writeHorizontalFacing($this->facing); - } - - public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta); - } - - public function getStateBitmask() : int{ - return 0b111; - } - /** * @return AxisAlignedBB[] */ diff --git a/src/block/EnderChest.php b/src/block/EnderChest.php index da88d9a24a..61868cbf5e 100644 --- a/src/block/EnderChest.php +++ b/src/block/EnderChest.php @@ -24,8 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\tile\EnderChest as TileEnderChest; -use pocketmine\block\utils\BlockDataSerializer; -use pocketmine\block\utils\HorizontalFacingTrait; +use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait; use pocketmine\item\Item; use pocketmine\item\ToolTier; use pocketmine\math\AxisAlignedBB; @@ -35,24 +34,12 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class EnderChest extends Transparent{ - use HorizontalFacingTrait; + use NormalHorizontalFacingInMetadataTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(22.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 3000.0)); } - protected function writeStateToMeta() : int{ - return BlockDataSerializer::writeHorizontalFacing($this->facing); - } - - public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta); - } - - public function getStateBitmask() : int{ - return 0b111; - } - public function getLightLevel() : int{ return 7; } diff --git a/src/block/Furnace.php b/src/block/Furnace.php index 6d5b772138..bcf29c1e9a 100644 --- a/src/block/Furnace.php +++ b/src/block/Furnace.php @@ -24,8 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\tile\Furnace as TileFurnace; -use pocketmine\block\utils\BlockDataSerializer; -use pocketmine\block\utils\HorizontalFacingTrait; +use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait; use pocketmine\item\Item; use pocketmine\item\ToolTier; use pocketmine\math\Facing; @@ -34,7 +33,9 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Furnace extends Opaque{ - use HorizontalFacingTrait; + use NormalHorizontalFacingInMetadataTrait { + readStateFromData as readFacingStateFromData; + } /** @var BlockIdentifierFlattened */ protected $idInfo; @@ -50,19 +51,11 @@ class Furnace extends Opaque{ return $this->lit ? $this->idInfo->getSecondId() : parent::getId(); } - protected function writeStateToMeta() : int{ - return BlockDataSerializer::writeHorizontalFacing($this->facing); - } - public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta); + $this->readFacingStateFromData($id, $stateMeta); $this->lit = $id === $this->idInfo->getSecondId(); } - public function getStateBitmask() : int{ - return 0b111; - } - public function getLightLevel() : int{ return $this->lit ? 13 : 0; } diff --git a/src/block/GlazedTerracotta.php b/src/block/GlazedTerracotta.php index 390d7b73ea..6513149ba0 100644 --- a/src/block/GlazedTerracotta.php +++ b/src/block/GlazedTerracotta.php @@ -23,8 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataSerializer; -use pocketmine\block\utils\HorizontalFacingTrait; +use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait; use pocketmine\item\Item; use pocketmine\item\ToolTier; use pocketmine\math\Facing; @@ -33,24 +32,12 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class GlazedTerracotta extends Opaque{ - use HorizontalFacingTrait; + use NormalHorizontalFacingInMetadataTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.4, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); } - protected function writeStateToMeta() : int{ - return BlockDataSerializer::writeHorizontalFacing($this->facing); - } - - public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta); - } - - public function getStateBitmask() : int{ - return 0b111; - } - public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = Facing::opposite($player->getHorizontalFacing()); diff --git a/src/block/Ladder.php b/src/block/Ladder.php index b696d8daa4..eb6f43d384 100644 --- a/src/block/Ladder.php +++ b/src/block/Ladder.php @@ -23,8 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataSerializer; -use pocketmine\block\utils\HorizontalFacingTrait; +use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait; use pocketmine\entity\Entity; use pocketmine\entity\Living; use pocketmine\item\Item; @@ -36,24 +35,12 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Ladder extends Transparent{ - use HorizontalFacingTrait; + use NormalHorizontalFacingInMetadataTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.4, BlockToolType::AXE)); } - protected function writeStateToMeta() : int{ - return BlockDataSerializer::writeHorizontalFacing($this->facing); - } - - public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta); - } - - public function getStateBitmask() : int{ - return 0b111; - } - public function hasEntityCollision() : bool{ return true; } diff --git a/src/block/WallBanner.php b/src/block/WallBanner.php index 2ac473fb4d..1c807461bc 100644 --- a/src/block/WallBanner.php +++ b/src/block/WallBanner.php @@ -23,8 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataSerializer; -use pocketmine\block\utils\HorizontalFacingTrait; +use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait; use pocketmine\item\Item; use pocketmine\math\Axis; use pocketmine\math\Facing; @@ -33,19 +32,7 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; final class WallBanner extends BaseBanner{ - use HorizontalFacingTrait; - - protected function writeStateToMeta() : int{ - return BlockDataSerializer::writeHorizontalFacing($this->facing); - } - - public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta); - } - - public function getStateBitmask() : int{ - return 0b111; - } + use NormalHorizontalFacingInMetadataTrait; protected function getSupportingFace() : int{ return Facing::opposite($this->facing); diff --git a/src/block/WallSign.php b/src/block/WallSign.php index 0f094ae300..38a6264338 100644 --- a/src/block/WallSign.php +++ b/src/block/WallSign.php @@ -23,8 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataSerializer; -use pocketmine\block\utils\HorizontalFacingTrait; +use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait; use pocketmine\item\Item; use pocketmine\math\Axis; use pocketmine\math\Facing; @@ -33,19 +32,7 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; final class WallSign extends BaseSign{ - use HorizontalFacingTrait; - - protected function writeStateToMeta() : int{ - return BlockDataSerializer::writeHorizontalFacing($this->facing); - } - - public function readStateFromData(int $id, int $stateMeta) : void{ - $this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta); - } - - public function getStateBitmask() : int{ - return 0b111; - } + use NormalHorizontalFacingInMetadataTrait; protected function getSupportingFace() : int{ return Facing::opposite($this->facing); diff --git a/src/block/utils/NormalHorizontalFacingInMetadataTrait.php b/src/block/utils/NormalHorizontalFacingInMetadataTrait.php new file mode 100644 index 0000000000..79bb7ac9f1 --- /dev/null +++ b/src/block/utils/NormalHorizontalFacingInMetadataTrait.php @@ -0,0 +1,40 @@ +facing); + } + + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta); + } + + public function getStateBitmask() : int{ + return 0b111; + } +} From 2eb05a24205b36aa84ce91e097998e5522ecb353 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 27 Apr 2021 21:00:22 +0100 Subject: [PATCH 2427/3224] Updated block factory consistency check --- tests/phpunit/block/block_factory_consistency_check.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 042c0cf3f5..d60ae5762d 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Mushroom Stem","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"All Sided Mushroom Stem","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Tube Coral","6177":"Brain Coral","6178":"Bubble Coral","6179":"Fire Coral","6180":"Horn Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Tube Coral Fan","6209":"Brain Coral Fan","6210":"Bubble Coral Fan","6211":"Fire Coral Fan","6212":"Horn Coral Fan","6216":"Tube Coral Fan","6217":"Brain Coral Fan","6218":"Bubble Coral Fan","6219":"Fire Coral Fan","6220":"Horn Coral Fan","6224":"Tube Coral Fan","6225":"Brain Coral Fan","6226":"Bubble Coral Fan","6227":"Fire Coral Fan","6228":"Horn Coral Fan","6232":"Tube Coral Fan","6233":"Brain Coral Fan","6234":"Bubble Coral Fan","6235":"Fire Coral Fan","6236":"Horn Coral Fan","6240":"Tube Wall Coral Fan","6241":"Brain Wall Coral Fan","6242":"Tube Wall Coral Fan","6243":"Brain Wall Coral Fan","6244":"Tube Wall Coral Fan","6245":"Brain Wall Coral Fan","6246":"Tube Wall Coral Fan","6247":"Brain Wall Coral Fan","6248":"Tube Wall Coral Fan","6249":"Brain Wall Coral Fan","6250":"Tube Wall Coral Fan","6251":"Brain Wall Coral Fan","6252":"Tube Wall Coral Fan","6253":"Brain Wall Coral Fan","6254":"Tube Wall Coral Fan","6255":"Brain Wall Coral Fan","6256":"Bubble Wall Coral Fan","6257":"Fire Wall Coral Fan","6258":"Bubble Wall Coral Fan","6259":"Fire Wall Coral Fan","6260":"Bubble Wall Coral Fan","6261":"Fire Wall Coral Fan","6262":"Bubble Wall Coral Fan","6263":"Fire Wall Coral Fan","6264":"Bubble Wall Coral Fan","6265":"Fire Wall Coral Fan","6266":"Bubble Wall Coral Fan","6267":"Fire Wall Coral Fan","6268":"Bubble Wall Coral Fan","6269":"Fire Wall Coral Fan","6270":"Bubble Wall Coral Fan","6271":"Fire Wall Coral Fan","6272":"Horn Wall Coral Fan","6274":"Horn Wall Coral Fan","6276":"Horn Wall Coral Fan","6278":"Horn Wall Coral Fan","6280":"Horn Wall Coral Fan","6282":"Horn Wall Coral Fan","6284":"Horn Wall Coral Fan","6286":"Horn Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Mushroom Stem","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"All Sided Mushroom Stem","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Tube Coral","6177":"Brain Coral","6178":"Bubble Coral","6179":"Fire Coral","6180":"Horn Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Tube Coral Fan","6209":"Brain Coral Fan","6210":"Bubble Coral Fan","6211":"Fire Coral Fan","6212":"Horn Coral Fan","6216":"Tube Coral Fan","6217":"Brain Coral Fan","6218":"Bubble Coral Fan","6219":"Fire Coral Fan","6220":"Horn Coral Fan","6224":"Tube Coral Fan","6225":"Brain Coral Fan","6226":"Bubble Coral Fan","6227":"Fire Coral Fan","6228":"Horn Coral Fan","6232":"Tube Coral Fan","6233":"Brain Coral Fan","6234":"Bubble Coral Fan","6235":"Fire Coral Fan","6236":"Horn Coral Fan","6240":"Tube Wall Coral Fan","6241":"Brain Wall Coral Fan","6242":"Tube Wall Coral Fan","6243":"Brain Wall Coral Fan","6244":"Tube Wall Coral Fan","6245":"Brain Wall Coral Fan","6246":"Tube Wall Coral Fan","6247":"Brain Wall Coral Fan","6248":"Tube Wall Coral Fan","6249":"Brain Wall Coral Fan","6250":"Tube Wall Coral Fan","6251":"Brain Wall Coral Fan","6252":"Tube Wall Coral Fan","6253":"Brain Wall Coral Fan","6254":"Tube Wall Coral Fan","6255":"Brain Wall Coral Fan","6256":"Bubble Wall Coral Fan","6257":"Fire Wall Coral Fan","6258":"Bubble Wall Coral Fan","6259":"Fire Wall Coral Fan","6260":"Bubble Wall Coral Fan","6261":"Fire Wall Coral Fan","6262":"Bubble Wall Coral Fan","6263":"Fire Wall Coral Fan","6264":"Bubble Wall Coral Fan","6265":"Fire Wall Coral Fan","6266":"Bubble Wall Coral Fan","6267":"Fire Wall Coral Fan","6268":"Bubble Wall Coral Fan","6269":"Fire Wall Coral Fan","6270":"Bubble Wall Coral Fan","6271":"Fire Wall Coral Fan","6272":"Horn Wall Coral Fan","6274":"Horn Wall Coral Fan","6276":"Horn Wall Coral Fan","6278":"Horn Wall Coral Fan","6280":"Horn Wall Coral Fan","6282":"Horn Wall Coral Fan","6284":"Horn Wall Coral Fan","6286":"Horn Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From 72045b3d7e5da188d226252e9f14e56b2f832d4b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 27 Apr 2021 21:03:23 +0100 Subject: [PATCH 2428/3224] CoralBlock: added setCoralType() --- src/block/CoralBlock.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/block/CoralBlock.php b/src/block/CoralBlock.php index 9ea7db623c..795621c23e 100644 --- a/src/block/CoralBlock.php +++ b/src/block/CoralBlock.php @@ -32,7 +32,7 @@ use function mt_rand; final class CoralBlock extends Opaque{ /** @var CoralType */ - private $coralType; //TODO: make this dynamic via setter + private $coralType; /** @var bool */ private $dead = false; @@ -65,6 +65,12 @@ final class CoralBlock extends Opaque{ public function getCoralType() : CoralType{ return $this->coralType; } + /** @return $this */ + public function setCoralType(CoralType $coralType) : self{ + $this->coralType = $coralType; + return $this; + } + public function isDead() : bool{ return $this->dead; } /** @return $this */ From 8a3df1212a3f1632715f3f32f68b540ec861bc8e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 27 Apr 2021 21:28:26 +0100 Subject: [PATCH 2429/3224] Added a trait for blocks which face opposite their placing player --- src/block/CarvedPumpkin.php | 14 +----- src/block/ChemistryTable.php | 10 +---- src/block/Chest.php | 11 +---- src/block/EndPortalFrame.php | 13 +----- src/block/EnderChest.php | 10 +---- src/block/Furnace.php | 12 +---- src/block/GlazedTerracotta.php | 15 +------ .../utils/FacesOppositePlacingPlayerTrait.php | 45 +++++++++++++++++++ 8 files changed, 59 insertions(+), 71 deletions(-) create mode 100644 src/block/utils/FacesOppositePlacingPlayerTrait.php diff --git a/src/block/CarvedPumpkin.php b/src/block/CarvedPumpkin.php index e5284bf49a..d4513a08de 100644 --- a/src/block/CarvedPumpkin.php +++ b/src/block/CarvedPumpkin.php @@ -24,14 +24,11 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; use pocketmine\block\utils\HorizontalFacingTrait; -use pocketmine\item\Item; -use pocketmine\math\Facing; -use pocketmine\math\Vector3; -use pocketmine\player\Player; -use pocketmine\world\BlockTransaction; class CarvedPumpkin extends Opaque{ + use FacesOppositePlacingPlayerTrait; use HorizontalFacingTrait; public function readStateFromData(int $id, int $stateMeta) : void{ @@ -45,11 +42,4 @@ class CarvedPumpkin extends Opaque{ public function getStateBitmask() : int{ return 0b11; } - - public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($player !== null){ - $this->facing = Facing::opposite($player->getHorizontalFacing()); - } - return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); - } } diff --git a/src/block/ChemistryTable.php b/src/block/ChemistryTable.php index e33159762c..3ec37718fb 100644 --- a/src/block/ChemistryTable.php +++ b/src/block/ChemistryTable.php @@ -24,14 +24,15 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; -use pocketmine\world\BlockTransaction; final class ChemistryTable extends Opaque{ + use FacesOppositePlacingPlayerTrait; use HorizontalFacingTrait; public function readStateFromData(int $id, int $stateMeta) : void{ @@ -46,13 +47,6 @@ final class ChemistryTable extends Opaque{ return 0b0011; } - public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($player !== null){ - $this->facing = Facing::opposite($player->getHorizontalFacing()); - } - return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); - } - public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ //TODO return false; diff --git a/src/block/Chest.php b/src/block/Chest.php index 85feebc24a..c48d3d1fa4 100644 --- a/src/block/Chest.php +++ b/src/block/Chest.php @@ -24,15 +24,16 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\tile\Chest as TileChest; +use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; -use pocketmine\world\BlockTransaction; class Chest extends Transparent{ + use FacesOppositePlacingPlayerTrait; use NormalHorizontalFacingInMetadataTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ @@ -47,14 +48,6 @@ class Chest extends Transparent{ return [AxisAlignedBB::one()->contract(0.025, 0, 0.025)->trim(Facing::UP, 0.05)]; } - public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($player !== null){ - $this->facing = Facing::opposite($player->getHorizontalFacing()); - } - - return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); - } - public function onPostPlace() : void{ $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileChest){ diff --git a/src/block/EndPortalFrame.php b/src/block/EndPortalFrame.php index 221b206d0c..2a553a2a9e 100644 --- a/src/block/EndPortalFrame.php +++ b/src/block/EndPortalFrame.php @@ -24,15 +24,13 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; use pocketmine\block\utils\HorizontalFacingTrait; -use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; -use pocketmine\math\Vector3; -use pocketmine\player\Player; -use pocketmine\world\BlockTransaction; class EndPortalFrame extends Opaque{ + use FacesOppositePlacingPlayerTrait; use HorizontalFacingTrait; /** @var bool */ @@ -73,11 +71,4 @@ class EndPortalFrame extends Opaque{ protected function recalculateCollisionBoxes() : array{ return [AxisAlignedBB::one()->trim(Facing::UP, 3 / 16)]; } - - public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($player !== null){ - $this->facing = Facing::opposite($player->getHorizontalFacing()); - } - return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); - } } diff --git a/src/block/EnderChest.php b/src/block/EnderChest.php index 61868cbf5e..69dc97a27b 100644 --- a/src/block/EnderChest.php +++ b/src/block/EnderChest.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\tile\EnderChest as TileEnderChest; +use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait; use pocketmine\item\Item; use pocketmine\item\ToolTier; @@ -31,9 +32,9 @@ use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; -use pocketmine\world\BlockTransaction; class EnderChest extends Transparent{ + use FacesOppositePlacingPlayerTrait; use NormalHorizontalFacingInMetadataTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ @@ -52,13 +53,6 @@ class EnderChest extends Transparent{ return [AxisAlignedBB::one()->contract(0.025, 0, 0.025)->trim(Facing::UP, 0.05)]; } - public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($player !== null){ - $this->facing = Facing::opposite($player->getHorizontalFacing()); - } - return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); - } - public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ $enderChest = $this->pos->getWorld()->getTile($this->pos); diff --git a/src/block/Furnace.php b/src/block/Furnace.php index bcf29c1e9a..5977da582d 100644 --- a/src/block/Furnace.php +++ b/src/block/Furnace.php @@ -24,15 +24,15 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\tile\Furnace as TileFurnace; +use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait; use pocketmine\item\Item; use pocketmine\item\ToolTier; -use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; -use pocketmine\world\BlockTransaction; class Furnace extends Opaque{ + use FacesOppositePlacingPlayerTrait; use NormalHorizontalFacingInMetadataTrait { readStateFromData as readFacingStateFromData; } @@ -72,14 +72,6 @@ class Furnace extends Opaque{ return $this; } - public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($player !== null){ - $this->facing = Facing::opposite($player->getHorizontalFacing()); - } - - return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); - } - public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ $furnace = $this->pos->getWorld()->getTile($this->pos); diff --git a/src/block/GlazedTerracotta.php b/src/block/GlazedTerracotta.php index 6513149ba0..5e81b2cc86 100644 --- a/src/block/GlazedTerracotta.php +++ b/src/block/GlazedTerracotta.php @@ -23,26 +23,15 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait; -use pocketmine\item\Item; use pocketmine\item\ToolTier; -use pocketmine\math\Facing; -use pocketmine\math\Vector3; -use pocketmine\player\Player; -use pocketmine\world\BlockTransaction; class GlazedTerracotta extends Opaque{ + use FacesOppositePlacingPlayerTrait; use NormalHorizontalFacingInMetadataTrait; public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.4, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); } - - public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($player !== null){ - $this->facing = Facing::opposite($player->getHorizontalFacing()); - } - - return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); - } } diff --git a/src/block/utils/FacesOppositePlacingPlayerTrait.php b/src/block/utils/FacesOppositePlacingPlayerTrait.php new file mode 100644 index 0000000000..1f566ca304 --- /dev/null +++ b/src/block/utils/FacesOppositePlacingPlayerTrait.php @@ -0,0 +1,45 @@ +facing = Facing::opposite($player->getHorizontalFacing()); + } + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } +} From 2bc0f9f7a2eb0e97c5f8cf947f34d6877702bc3c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 27 Apr 2021 22:39:13 +0100 Subject: [PATCH 2430/3224] TimingsCommand: do not enable timings if they are already enabled this causes timings to be reset, which is potentially undesirable (loss of already-collected timing data). closes #4194 --- resources/locale | 2 +- src/command/defaults/TimingsCommand.php | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/resources/locale b/resources/locale index 3d1c70b9f3..ca7fecaf24 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 3d1c70b9f3d7650cef7cac25db27397a5708d22c +Subproject commit ca7fecaf24d8a8f9b947b69f1a8772475e03c379 diff --git a/src/command/defaults/TimingsCommand.php b/src/command/defaults/TimingsCommand.php index 6016886909..3c3fbf6700 100644 --- a/src/command/defaults/TimingsCommand.php +++ b/src/command/defaults/TimingsCommand.php @@ -75,6 +75,10 @@ class TimingsCommand extends VanillaCommand{ $mode = strtolower($args[0]); if($mode === "on"){ + if(TimingsHandler::isEnabled()){ + $sender->sendMessage(new TranslationContainer("pocketmine.command.timings.alreadyEnabled")); + return true; + } TimingsHandler::setEnabled(); Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.command.timings.enable")); From a44203a3d485ba5cf58127a90b5780b9e2efbae7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 28 Apr 2021 12:47:42 +0100 Subject: [PATCH 2431/3224] Separate BannerPatternLayer from BannerPatternType --- src/block/BaseBanner.php | 19 ++-- src/block/tile/Banner.php | 22 +++-- src/block/utils/BannerPattern.php | 89 ----------------- src/block/utils/BannerPatternLayer.php | 47 +++++++++ src/block/utils/BannerPatternType.php | 128 +++++++++++++++++++++++++ src/item/Banner.php | 20 ++-- 6 files changed, 208 insertions(+), 117 deletions(-) delete mode 100644 src/block/utils/BannerPattern.php create mode 100644 src/block/utils/BannerPatternLayer.php create mode 100644 src/block/utils/BannerPatternType.php diff --git a/src/block/BaseBanner.php b/src/block/BaseBanner.php index e89e1b7b90..9c09012c99 100644 --- a/src/block/BaseBanner.php +++ b/src/block/BaseBanner.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\tile\Banner as TileBanner; -use pocketmine\block\utils\BannerPattern; +use pocketmine\block\utils\BannerPatternLayer; use pocketmine\block\utils\DyeColor; use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\item\Banner as ItemBanner; @@ -44,8 +44,8 @@ abstract class BaseBanner extends Transparent{ protected $baseColor; /** - * @var BannerPattern[] - * @phpstan-var list + * @var BannerPatternLayer[] + * @phpstan-var list */ protected $patterns = []; @@ -83,22 +83,23 @@ abstract class BaseBanner extends Transparent{ } /** - * @return BannerPattern[] - * @phpstan-return list + * @return BannerPatternLayer[] + * @phpstan-return list */ public function getPatterns() : array{ return $this->patterns; } /** - * @param BannerPattern[] $patterns - * @phpstan-param list $patterns + * @param BannerPatternLayer[] $patterns + * + * @phpstan-param list $patterns * @return $this */ public function setPatterns(array $patterns) : self{ - $checked = array_filter($patterns, fn($v) => $v instanceof BannerPattern); + $checked = array_filter($patterns, fn($v) => $v instanceof BannerPatternLayer); if(count($checked) !== count($patterns)){ - throw new \TypeError("Deque must only contain " . BannerPattern::class . " objects"); + throw new \TypeError("Deque must only contain " . BannerPatternLayer::class . " objects"); } $this->patterns = $checked; return $this; diff --git a/src/block/tile/Banner.php b/src/block/tile/Banner.php index 5256dd70dd..9fa6b158c2 100644 --- a/src/block/tile/Banner.php +++ b/src/block/tile/Banner.php @@ -23,7 +23,8 @@ declare(strict_types=1); namespace pocketmine\block\tile; -use pocketmine\block\utils\BannerPattern; +use pocketmine\block\utils\BannerPatternLayer; +use pocketmine\block\utils\BannerPatternType; use pocketmine\block\utils\DyeColor; use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\math\Vector3; @@ -47,8 +48,8 @@ class Banner extends Spawnable{ private $baseColor; /** - * @var BannerPattern[] - * @phpstan-var list + * @var BannerPatternLayer[] + * @phpstan-var list */ private $patterns = []; @@ -67,7 +68,7 @@ class Banner extends Spawnable{ if($patterns !== null){ /** @var CompoundTag $pattern */ foreach($patterns as $pattern){ - $this->patterns[] = new BannerPattern($pattern->getString(self::TAG_PATTERN_NAME), $colorIdMap->fromInvertedId($pattern->getInt(self::TAG_PATTERN_COLOR))); + $this->patterns[] = new BannerPatternLayer(BannerPatternType::fromString($pattern->getString(self::TAG_PATTERN_NAME)), $colorIdMap->fromInvertedId($pattern->getInt(self::TAG_PATTERN_COLOR))); } } } @@ -78,7 +79,7 @@ class Banner extends Spawnable{ $patterns = new ListTag(); foreach($this->patterns as $pattern){ $patterns->push(CompoundTag::create() - ->setString(self::TAG_PATTERN_NAME, $pattern->getId()) + ->setString(self::TAG_PATTERN_NAME, $pattern->getType()->getPatternId()) ->setInt(self::TAG_PATTERN_COLOR, $colorIdMap->toInvertedId($pattern->getColor())) ); } @@ -91,7 +92,7 @@ class Banner extends Spawnable{ $patterns = new ListTag(); foreach($this->patterns as $pattern){ $patterns->push(CompoundTag::create() - ->setString(self::TAG_PATTERN_NAME, $pattern->getId()) + ->setString(self::TAG_PATTERN_NAME, $pattern->getType()->getPatternId()) ->setInt(self::TAG_PATTERN_COLOR, $colorIdMap->toInvertedId($pattern->getColor())) ); } @@ -113,16 +114,17 @@ class Banner extends Spawnable{ } /** - * @return BannerPattern[] - * @phpstan-return list + * @return BannerPatternLayer[] + * @phpstan-return list */ public function getPatterns() : array{ return $this->patterns; } /** - * @param BannerPattern[] $patterns - * @phpstan-param list $patterns + * @param BannerPatternLayer[] $patterns + * + * @phpstan-param list $patterns */ public function setPatterns(array $patterns) : void{ $this->patterns = $patterns; diff --git a/src/block/utils/BannerPattern.php b/src/block/utils/BannerPattern.php deleted file mode 100644 index f53cefbdc1..0000000000 --- a/src/block/utils/BannerPattern.php +++ /dev/null @@ -1,89 +0,0 @@ -id = $id; - $this->color = $color; - } - - public function getId() : string{ - return $this->id; - } - - public function getColor() : DyeColor{ - return $this->color; - } -} diff --git a/src/block/utils/BannerPatternLayer.php b/src/block/utils/BannerPatternLayer.php new file mode 100644 index 0000000000..8095102fcb --- /dev/null +++ b/src/block/utils/BannerPatternLayer.php @@ -0,0 +1,47 @@ +type = $type; + $this->color = $color; + } + + public function getType() : BannerPatternType{ return $this->type; } + + public function getColor() : DyeColor{ + return $this->color; + } +} diff --git a/src/block/utils/BannerPatternType.php b/src/block/utils/BannerPatternType.php new file mode 100644 index 0000000000..e7b7b99a97 --- /dev/null +++ b/src/block/utils/BannerPatternType.php @@ -0,0 +1,128 @@ +Enum___construct($name); + $this->patternId = $patternId; + } + + public function getPatternId() : string{ return $this->patternId; } +} diff --git a/src/item/Banner.php b/src/item/Banner.php index d3c440bee6..36f81801be 100644 --- a/src/item/Banner.php +++ b/src/item/Banner.php @@ -25,7 +25,8 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\tile\Banner as TileBanner; -use pocketmine\block\utils\BannerPattern; +use pocketmine\block\utils\BannerPatternLayer; +use pocketmine\block\utils\BannerPatternType; use pocketmine\block\utils\DyeColor; use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\nbt\tag\CompoundTag; @@ -41,8 +42,8 @@ class Banner extends ItemBlockWallOrFloor{ private $color; /** - * @var BannerPattern[] - * @phpstan-var list + * @var BannerPatternLayer[] + * @phpstan-var list */ private $patterns = []; @@ -70,16 +71,17 @@ class Banner extends ItemBlockWallOrFloor{ } /** - * @return BannerPattern[] - * @phpstan-return list + * @return BannerPatternLayer[] + * @phpstan-return list */ public function getPatterns() : array{ return $this->patterns; } /** - * @param BannerPattern[] $patterns - * @phpstan-param list $patterns + * @param BannerPatternLayer[] $patterns + * + * @phpstan-param list $patterns * * @return $this */ @@ -102,7 +104,7 @@ class Banner extends ItemBlockWallOrFloor{ if($patterns !== null){ /** @var CompoundTag $t */ foreach($patterns as $t){ - $this->patterns[] = new BannerPattern($t->getString(self::TAG_PATTERN_NAME), $colorIdMap->fromInvertedId($t->getInt(self::TAG_PATTERN_COLOR))); + $this->patterns[] = new BannerPatternLayer(BannerPatternType::fromString($t->getString(self::TAG_PATTERN_NAME)), $colorIdMap->fromInvertedId($t->getInt(self::TAG_PATTERN_COLOR))); } } } @@ -115,7 +117,7 @@ class Banner extends ItemBlockWallOrFloor{ $colorIdMap = DyeColorIdMap::getInstance(); foreach($this->patterns as $pattern){ $patterns->push(CompoundTag::create() - ->setString(self::TAG_PATTERN_NAME, $pattern->getId()) + ->setString(self::TAG_PATTERN_NAME, $pattern->getType()->getPatternId()) ->setInt(self::TAG_PATTERN_COLOR, $colorIdMap->toInvertedId($pattern->getColor())) ); } From d5e5a81cff752f198014d0204118a3c3fec88a38 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 28 Apr 2021 13:39:03 +0100 Subject: [PATCH 2432/3224] Don't explode when data contains invalid dye colour IDs --- src/block/tile/Banner.php | 12 +++++++++--- src/block/tile/Bed.php | 9 +++++++-- src/block/utils/ColorInMetadataTrait.php | 6 +++++- src/data/bedrock/DyeColorIdMap.php | 6 +++--- src/item/Banner.php | 3 ++- tests/phpunit/data/bedrock/DyeColorIdMapTest.php | 2 +- 6 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/block/tile/Banner.php b/src/block/tile/Banner.php index 9fa6b158c2..cc020aacb5 100644 --- a/src/block/tile/Banner.php +++ b/src/block/tile/Banner.php @@ -60,15 +60,21 @@ class Banner extends Spawnable{ public function readSaveData(CompoundTag $nbt) : void{ $colorIdMap = DyeColorIdMap::getInstance(); - if(($baseColorTag = $nbt->getTag(self::TAG_BASE)) instanceof IntTag){ - $this->baseColor = $colorIdMap->fromInvertedId($baseColorTag->getValue()); + if( + ($baseColorTag = $nbt->getTag(self::TAG_BASE)) instanceof IntTag && + ($baseColor = $colorIdMap->fromInvertedId($baseColorTag->getValue())) !== null + ){ + $this->baseColor = $baseColor; + }else{ + $this->baseColor = DyeColor::BLACK(); //TODO: this should be an error } $patterns = $nbt->getListTag(self::TAG_PATTERNS); if($patterns !== null){ /** @var CompoundTag $pattern */ foreach($patterns as $pattern){ - $this->patterns[] = new BannerPatternLayer(BannerPatternType::fromString($pattern->getString(self::TAG_PATTERN_NAME)), $colorIdMap->fromInvertedId($pattern->getInt(self::TAG_PATTERN_COLOR))); + $patternColor = $colorIdMap->fromInvertedId($pattern->getInt(self::TAG_PATTERN_COLOR)) ?? DyeColor::BLACK(); //TODO: missing pattern colour should be an error + $this->patterns[] = new BannerPatternLayer(BannerPatternType::fromString($pattern->getString(self::TAG_PATTERN_NAME)), $patternColor); } } } diff --git a/src/block/tile/Bed.php b/src/block/tile/Bed.php index 95c12e524b..77cca1cebc 100644 --- a/src/block/tile/Bed.php +++ b/src/block/tile/Bed.php @@ -49,8 +49,13 @@ class Bed extends Spawnable{ } public function readSaveData(CompoundTag $nbt) : void{ - if(($colorTag = $nbt->getTag(self::TAG_COLOR)) instanceof ByteTag){ - $this->color = DyeColorIdMap::getInstance()->fromId($colorTag->getValue()); + if( + ($colorTag = $nbt->getTag(self::TAG_COLOR)) instanceof ByteTag && + ($color = DyeColorIdMap::getInstance()->fromId($colorTag->getValue())) !== null + ){ + $this->color = $color; + }else{ + $this->color = DyeColor::RED(); //TODO: this should be an error, but we don't have the systems to handle it yet } } diff --git a/src/block/utils/ColorInMetadataTrait.php b/src/block/utils/ColorInMetadataTrait.php index 7687bbb715..95b7292863 100644 --- a/src/block/utils/ColorInMetadataTrait.php +++ b/src/block/utils/ColorInMetadataTrait.php @@ -33,7 +33,11 @@ trait ColorInMetadataTrait{ * @see Block::readStateFromData() */ public function readStateFromData(int $id, int $stateMeta) : void{ - $this->color = DyeColorIdMap::getInstance()->fromId($stateMeta); + $color = DyeColorIdMap::getInstance()->fromId($stateMeta); + if($color === null){ + throw new InvalidBlockStateException("No dye colour corresponds to ID $stateMeta"); + } + $this->color = $color; } /** diff --git a/src/data/bedrock/DyeColorIdMap.php b/src/data/bedrock/DyeColorIdMap.php index a96b19f65e..cb7455b81a 100644 --- a/src/data/bedrock/DyeColorIdMap.php +++ b/src/data/bedrock/DyeColorIdMap.php @@ -73,11 +73,11 @@ final class DyeColorIdMap{ return ~$this->toId($color) & 0xf; } - public function fromId(int $id) : DyeColor{ - return $this->idToEnum[$id]; //TODO: this might not be present (e.g. corrupted data) + public function fromId(int $id) : ?DyeColor{ + return $this->idToEnum[$id]; } - public function fromInvertedId(int $id) : DyeColor{ + public function fromInvertedId(int $id) : ?DyeColor{ return $this->fromId(~$id & 0xf); } } diff --git a/src/item/Banner.php b/src/item/Banner.php index 36f81801be..7f01455e94 100644 --- a/src/item/Banner.php +++ b/src/item/Banner.php @@ -104,7 +104,8 @@ class Banner extends ItemBlockWallOrFloor{ if($patterns !== null){ /** @var CompoundTag $t */ foreach($patterns as $t){ - $this->patterns[] = new BannerPatternLayer(BannerPatternType::fromString($t->getString(self::TAG_PATTERN_NAME)), $colorIdMap->fromInvertedId($t->getInt(self::TAG_PATTERN_COLOR))); + $patternColor = $colorIdMap->fromInvertedId($t->getInt(self::TAG_PATTERN_COLOR)) ?? DyeColor::BLACK(); //TODO: missing pattern colour should be an error + $this->patterns[] = new BannerPatternLayer(BannerPatternType::fromString($t->getString(self::TAG_PATTERN_NAME)), $patternColor); } } } diff --git a/tests/phpunit/data/bedrock/DyeColorIdMapTest.php b/tests/phpunit/data/bedrock/DyeColorIdMapTest.php index 156c06b72d..757cf7921c 100644 --- a/tests/phpunit/data/bedrock/DyeColorIdMapTest.php +++ b/tests/phpunit/data/bedrock/DyeColorIdMapTest.php @@ -32,7 +32,7 @@ class DyeColorIdMapTest extends TestCase{ foreach(DyeColor::getAll() as $color){ $id = DyeColorIdMap::getInstance()->toId($color); $color2 = DyeColorIdMap::getInstance()->fromId($id); - self::assertTrue($color->equals($color2)); + self::assertTrue($color2 !== null && $color->equals($color2)); } } } From b33bf1f433d79204c218408498f7403e2f77b3a0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 28 Apr 2021 18:42:29 +0100 Subject: [PATCH 2433/3224] Unfuck banners ... --- src/block/tile/Banner.php | 16 +++- src/block/utils/BannerPatternType.php | 89 ++++++++--------- src/data/bedrock/BannerPatternTypeIdMap.php | 100 ++++++++++++++++++++ src/item/Banner.php | 12 ++- tests/phpunit/item/BannerTest.php | 50 ++++++++++ 5 files changed, 210 insertions(+), 57 deletions(-) create mode 100644 src/data/bedrock/BannerPatternTypeIdMap.php create mode 100644 tests/phpunit/item/BannerTest.php diff --git a/src/block/tile/Banner.php b/src/block/tile/Banner.php index cc020aacb5..4404a39710 100644 --- a/src/block/tile/Banner.php +++ b/src/block/tile/Banner.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\block\tile; use pocketmine\block\utils\BannerPatternLayer; -use pocketmine\block\utils\BannerPatternType; use pocketmine\block\utils\DyeColor; +use pocketmine\data\bedrock\BannerPatternTypeIdMap; use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; @@ -69,23 +69,30 @@ class Banner extends Spawnable{ $this->baseColor = DyeColor::BLACK(); //TODO: this should be an error } + $patternTypeIdMap = BannerPatternTypeIdMap::getInstance(); + $patterns = $nbt->getListTag(self::TAG_PATTERNS); if($patterns !== null){ /** @var CompoundTag $pattern */ foreach($patterns as $pattern){ $patternColor = $colorIdMap->fromInvertedId($pattern->getInt(self::TAG_PATTERN_COLOR)) ?? DyeColor::BLACK(); //TODO: missing pattern colour should be an error - $this->patterns[] = new BannerPatternLayer(BannerPatternType::fromString($pattern->getString(self::TAG_PATTERN_NAME)), $patternColor); + $patternType = $patternTypeIdMap->fromId($pattern->getString(self::TAG_PATTERN_NAME)); + if($patternType === null){ + continue; //TODO: this should be an error, but right now we don't have the setup to deal with it + } + $this->patterns[] = new BannerPatternLayer($patternType, $patternColor); } } } protected function writeSaveData(CompoundTag $nbt) : void{ $colorIdMap = DyeColorIdMap::getInstance(); + $patternIdMap = BannerPatternTypeIdMap::getInstance(); $nbt->setInt(self::TAG_BASE, $colorIdMap->toInvertedId($this->baseColor)); $patterns = new ListTag(); foreach($this->patterns as $pattern){ $patterns->push(CompoundTag::create() - ->setString(self::TAG_PATTERN_NAME, $pattern->getType()->getPatternId()) + ->setString(self::TAG_PATTERN_NAME, $patternIdMap->toId($pattern->getType())) ->setInt(self::TAG_PATTERN_COLOR, $colorIdMap->toInvertedId($pattern->getColor())) ); } @@ -94,11 +101,12 @@ class Banner extends Spawnable{ protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ $colorIdMap = DyeColorIdMap::getInstance(); + $patternIdMap = BannerPatternTypeIdMap::getInstance(); $nbt->setInt(self::TAG_BASE, $colorIdMap->toInvertedId($this->baseColor)); $patterns = new ListTag(); foreach($this->patterns as $pattern){ $patterns->push(CompoundTag::create() - ->setString(self::TAG_PATTERN_NAME, $pattern->getType()->getPatternId()) + ->setString(self::TAG_PATTERN_NAME, $patternIdMap->toId($pattern->getType())) ->setInt(self::TAG_PATTERN_COLOR, $colorIdMap->toInvertedId($pattern->getColor())) ); } diff --git a/src/block/utils/BannerPatternType.php b/src/block/utils/BannerPatternType.php index e7b7b99a97..51d85f6e43 100644 --- a/src/block/utils/BannerPatternType.php +++ b/src/block/utils/BannerPatternType.php @@ -70,59 +70,48 @@ use pocketmine\utils\EnumTrait; * @method static BannerPatternType TRIANGLE_TOP() */ final class BannerPatternType{ - use EnumTrait { - __construct as Enum___construct; - } + use EnumTrait; protected static function setup() : void{ self::registerAll( - new self("border", "bo"), - new self("bricks", "bri"), - new self("circle", "mc"), - new self("creeper", "cre"), - new self("cross", "cr"), - new self("curly_border", "cbo"), - new self("diagonal_left", "lud"), - new self("diagonal_right", "rd"), - new self("diagonal_up_left", "ld"), - new self("diagonal_up_right", "rud"), - new self("flower", "flo"), - new self("gradient", "gra"), - new self("gradient_up", "gru"), - new self("half_horizontal", "hh"), - new self("half_horizontal_bottom", "hhb"), - new self("half_vertical", "vh"), - new self("half_vertical_right", "vhr"), - new self("mojang", "moj"), - new self("rhombus", "mr"), - new self("skull", "sku"), - new self("small_stripes", "ss"), - new self("square_bottom_left", "bl"), - new self("square_bottom_right", "br"), - new self("square_top_left", "tl"), - new self("square_top_right", "tr"), - new self("straight_cross", "sc"), - new self("stripe_bottom", "bs"), - new self("stripe_center", "cs"), - new self("stripe_downleft", "dls"), - new self("stripe_downright", "drs"), - new self("stripe_left", "ls"), - new self("stripe_middle", "ms"), - new self("stripe_right", "rs"), - new self("stripe_top", "ts"), - new self("triangle_bottom", "bt"), - new self("triangle_top", "tt"), - new self("triangles_bottom", "bts"), - new self("triangles_top", "tts") + new self("border"), + new self("bricks"), + new self("circle"), + new self("creeper"), + new self("cross"), + new self("curly_border"), + new self("diagonal_left"), + new self("diagonal_right"), + new self("diagonal_up_left"), + new self("diagonal_up_right"), + new self("flower"), + new self("gradient"), + new self("gradient_up"), + new self("half_horizontal"), + new self("half_horizontal_bottom"), + new self("half_vertical"), + new self("half_vertical_right"), + new self("mojang"), + new self("rhombus"), + new self("skull"), + new self("small_stripes"), + new self("square_bottom_left"), + new self("square_bottom_right"), + new self("square_top_left"), + new self("square_top_right"), + new self("straight_cross"), + new self("stripe_bottom"), + new self("stripe_center"), + new self("stripe_downleft"), + new self("stripe_downright"), + new self("stripe_left"), + new self("stripe_middle"), + new self("stripe_right"), + new self("stripe_top"), + new self("triangle_bottom"), + new self("triangle_top"), + new self("triangles_bottom"), + new self("triangles_top") ); } - - private string $patternId; - - private function __construct(string $name, string $patternId){ - $this->Enum___construct($name); - $this->patternId = $patternId; - } - - public function getPatternId() : string{ return $this->patternId; } } diff --git a/src/data/bedrock/BannerPatternTypeIdMap.php b/src/data/bedrock/BannerPatternTypeIdMap.php new file mode 100644 index 0000000000..45f6488b8f --- /dev/null +++ b/src/data/bedrock/BannerPatternTypeIdMap.php @@ -0,0 +1,100 @@ + + */ + private array $idToEnum = []; + /** + * @var string[] + * @phpstan-var array + */ + private array $enumToId = []; + + public function __construct(){ + $this->register("bo", BannerPatternType::BORDER()); + $this->register("bri", BannerPatternType::BRICKS()); + $this->register("mc", BannerPatternType::CIRCLE()); + $this->register("cre", BannerPatternType::CREEPER()); + $this->register("cr", BannerPatternType::CROSS()); + $this->register("cbo", BannerPatternType::CURLY_BORDER()); + $this->register("lud", BannerPatternType::DIAGONAL_LEFT()); + $this->register("rd", BannerPatternType::DIAGONAL_RIGHT()); + $this->register("ld", BannerPatternType::DIAGONAL_UP_LEFT()); + $this->register("rud", BannerPatternType::DIAGONAL_UP_RIGHT()); + $this->register("flo", BannerPatternType::FLOWER()); + $this->register("gra", BannerPatternType::GRADIENT()); + $this->register("gru", BannerPatternType::GRADIENT_UP()); + $this->register("hh", BannerPatternType::HALF_HORIZONTAL()); + $this->register("hhb", BannerPatternType::HALF_HORIZONTAL_BOTTOM()); + $this->register("vh", BannerPatternType::HALF_VERTICAL()); + $this->register("vhr", BannerPatternType::HALF_VERTICAL_RIGHT()); + $this->register("moj", BannerPatternType::MOJANG()); + $this->register("mr", BannerPatternType::RHOMBUS()); + $this->register("sku", BannerPatternType::SKULL()); + $this->register("ss", BannerPatternType::SMALL_STRIPES()); + $this->register("bl", BannerPatternType::SQUARE_BOTTOM_LEFT()); + $this->register("br", BannerPatternType::SQUARE_BOTTOM_RIGHT()); + $this->register("tl", BannerPatternType::SQUARE_TOP_LEFT()); + $this->register("tr", BannerPatternType::SQUARE_TOP_RIGHT()); + $this->register("sc", BannerPatternType::STRAIGHT_CROSS()); + $this->register("bs", BannerPatternType::STRIPE_BOTTOM()); + $this->register("cs", BannerPatternType::STRIPE_CENTER()); + $this->register("dls", BannerPatternType::STRIPE_DOWNLEFT()); + $this->register("drs", BannerPatternType::STRIPE_DOWNRIGHT()); + $this->register("ls", BannerPatternType::STRIPE_LEFT()); + $this->register("ms", BannerPatternType::STRIPE_MIDDLE()); + $this->register("rs", BannerPatternType::STRIPE_RIGHT()); + $this->register("ts", BannerPatternType::STRIPE_TOP()); + $this->register("bt", BannerPatternType::TRIANGLE_BOTTOM()); + $this->register("tt", BannerPatternType::TRIANGLE_TOP()); + $this->register("bts", BannerPatternType::TRIANGLES_BOTTOM()); + $this->register("tts", BannerPatternType::TRIANGLES_TOP()); + } + + public function register(string $stringId, BannerPatternType $type) : void{ + $this->idToEnum[$stringId] = $type; + $this->enumToId[$type->id()] = $stringId; + } + + public function fromId(string $id) : ?BannerPatternType{ + return $this->idToEnum[$id] ?? null; + } + + public function toId(BannerPatternType $type) : string{ + if(!array_key_exists($type->id(), $this->enumToId)){ + throw new \InvalidArgumentException("Missing mapping for banner pattern type " . $type->name()); + } + return $this->enumToId[$type->id()]; + } +} diff --git a/src/item/Banner.php b/src/item/Banner.php index 7f01455e94..506af76203 100644 --- a/src/item/Banner.php +++ b/src/item/Banner.php @@ -26,8 +26,8 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\tile\Banner as TileBanner; use pocketmine\block\utils\BannerPatternLayer; -use pocketmine\block\utils\BannerPatternType; use pocketmine\block\utils\DyeColor; +use pocketmine\data\bedrock\BannerPatternTypeIdMap; use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; @@ -100,12 +100,17 @@ class Banner extends ItemBlockWallOrFloor{ $this->patterns = []; $colorIdMap = DyeColorIdMap::getInstance(); + $patternIdMap = BannerPatternTypeIdMap::getInstance(); $patterns = $tag->getListTag(self::TAG_PATTERNS); if($patterns !== null){ /** @var CompoundTag $t */ foreach($patterns as $t){ $patternColor = $colorIdMap->fromInvertedId($t->getInt(self::TAG_PATTERN_COLOR)) ?? DyeColor::BLACK(); //TODO: missing pattern colour should be an error - $this->patterns[] = new BannerPatternLayer(BannerPatternType::fromString($t->getString(self::TAG_PATTERN_NAME)), $patternColor); + $patternType = $patternIdMap->fromId($t->getString(self::TAG_PATTERN_NAME)); + if($patternType === null){ + continue; //TODO: this should be an error + } + $this->patterns[] = new BannerPatternLayer($patternType, $patternColor); } } } @@ -116,9 +121,10 @@ class Banner extends ItemBlockWallOrFloor{ if(count($this->patterns) > 0){ $patterns = new ListTag(); $colorIdMap = DyeColorIdMap::getInstance(); + $patternIdMap = BannerPatternTypeIdMap::getInstance(); foreach($this->patterns as $pattern){ $patterns->push(CompoundTag::create() - ->setString(self::TAG_PATTERN_NAME, $pattern->getType()->getPatternId()) + ->setString(self::TAG_PATTERN_NAME, $patternIdMap->toId($pattern->getType())) ->setInt(self::TAG_PATTERN_COLOR, $colorIdMap->toInvertedId($pattern->getColor())) ); } diff --git a/tests/phpunit/item/BannerTest.php b/tests/phpunit/item/BannerTest.php new file mode 100644 index 0000000000..20b7154e77 --- /dev/null +++ b/tests/phpunit/item/BannerTest.php @@ -0,0 +1,50 @@ +asItem(); + assert($item instanceof Banner); + $item->setPatterns([ + new BannerPatternLayer(BannerPatternType::FLOWER(), DyeColor::RED()) + ]); + $data = $item->nbtSerialize(); + + $item2 = Item::nbtDeserialize($data); + self::assertTrue($item->equalsExact($item2)); + self::assertInstanceOf(Banner::class, $item2); + $patterns = $item2->getPatterns(); + self::assertCount(1, $patterns); + self::assertTrue(BannerPatternType::FLOWER()->equals($patterns[0]->getType())); + } +} From 593a8ac52993fdd7b1a63a1e4676d35acc8528b3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 29 Apr 2021 19:51:09 +0100 Subject: [PATCH 2434/3224] Added Loom blocks these don't support doing patterns yet, but their inventories work. --- src/block/BlockFactory.php | 1 + src/block/Loom.php | 57 +++++++++++++++++++ src/block/VanillaBlocks.php | 2 + src/block/inventory/LoomInventory.php | 46 +++++++++++++++ src/network/mcpe/InventoryManager.php | 3 + src/network/mcpe/convert/TypeConverter.php | 5 +- .../mcpe/handler/InGamePacketHandler.php | 1 + .../block_factory_consistency_check.json | 2 +- 8 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 src/block/Loom.php create mode 100644 src/block/inventory/LoomInventory.php diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 926bae0df3..4fff6b0d23 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -222,6 +222,7 @@ class BlockFactory{ $this->register(new LapisOre(new BID(Ids::LAPIS_ORE, 0), "Lapis Lazuli Ore")); $this->register(new Lava(new BIDFlattened(Ids::FLOWING_LAVA, Ids::STILL_LAVA, 0), "Lava")); $this->register(new Lever(new BID(Ids::LEVER, 0), "Lever")); + $this->register(new Loom(new BID(Ids::LOOM, 0), "Loom", new BlockBreakInfo(2.5, BlockToolType::AXE))); $this->register(new Magma(new BID(Ids::MAGMA, 0), "Magma Block")); $this->register(new Melon(new BID(Ids::MELON_BLOCK, 0), "Melon Block")); $this->register(new MelonStem(new BID(Ids::MELON_STEM, 0, ItemIds::MELON_SEEDS), "Melon Stem")); diff --git a/src/block/Loom.php b/src/block/Loom.php new file mode 100644 index 0000000000..d4efcf1030 --- /dev/null +++ b/src/block/Loom.php @@ -0,0 +1,57 @@ +facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x3); + } + + protected function writeStateToMeta() : int{ + return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing); + } + + public function getStateBitmask() : int{ + return 0b11; + } + + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($player !== null){ + $player->setCurrentWindow(new LoomInventory($this->pos)); + return true; + } + return false; + } +} diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 7cd2df77e3..7dcf895bbe 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -438,6 +438,7 @@ use function assert; * @method static Glass LIME_STAINED_GLASS() * @method static GlassPane LIME_STAINED_GLASS_PANE() * @method static LitPumpkin LIT_PUMPKIN() + * @method static Loom LOOM() * @method static GlazedTerracotta MAGENTA_GLAZED_TERRACOTTA() * @method static HardenedClay MAGENTA_STAINED_CLAY() * @method static Glass MAGENTA_STAINED_GLASS() @@ -1078,6 +1079,7 @@ final class VanillaBlocks{ self::register("lime_stained_glass", $factory->get(241, 5)); self::register("lime_stained_glass_pane", $factory->get(160, 5)); self::register("lit_pumpkin", $factory->get(91, 0)); + self::register("loom", $factory->get(459, 0)); self::register("magenta_glazed_terracotta", $factory->get(222, 2)); self::register("magenta_stained_clay", $factory->get(159, 2)); self::register("magenta_stained_glass", $factory->get(241, 2)); diff --git a/src/block/inventory/LoomInventory.php b/src/block/inventory/LoomInventory.php new file mode 100644 index 0000000000..2a51f0f26a --- /dev/null +++ b/src/block/inventory/LoomInventory.php @@ -0,0 +1,46 @@ +getContents() as $item){ + $who->dropItem($item); + } + $this->clearAll(); + } +} diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index ae71f67dc6..d28e34abca 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -29,6 +29,7 @@ use pocketmine\block\inventory\BrewingStandInventory; use pocketmine\block\inventory\EnchantInventory; use pocketmine\block\inventory\FurnaceInventory; use pocketmine\block\inventory\HopperInventory; +use pocketmine\block\inventory\LoomInventory; use pocketmine\inventory\CreativeInventory; use pocketmine\inventory\Inventory; use pocketmine\inventory\transaction\action\SlotChangeAction; @@ -161,6 +162,8 @@ class InventoryManager{ //if the class isn't final, not to mention being inflexible. if($inv instanceof BlockInventory){ switch(true){ + case $inv instanceof LoomInventory: + return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::LOOM, $inv->getHolder())]; case $inv instanceof FurnaceInventory: //TODO: specialized furnace types return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::FURNACE, $inv->getHolder())]; diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index c0834e5ee6..5ac4c0b0df 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe\convert; use pocketmine\block\BlockLegacyIds; use pocketmine\block\inventory\AnvilInventory; use pocketmine\block\inventory\EnchantInventory; +use pocketmine\block\inventory\LoomInventory; use pocketmine\crafting\CraftingGrid; use pocketmine\inventory\Inventory; use pocketmine\inventory\transaction\action\CreateItemAction; @@ -266,7 +267,9 @@ class TypeConverter{ $this->mapUIInventory($pSlot, UIInventorySlotOffset::ANVIL, $current, function(Inventory $i) : bool{ return $i instanceof AnvilInventory; }) ?? $this->mapUIInventory($pSlot, UIInventorySlotOffset::ENCHANTING_TABLE, $current, - function(Inventory $i) : bool{ return $i instanceof EnchantInventory; }); + function(Inventory $i) : bool{ return $i instanceof EnchantInventory; }) ?? + $this->mapUIInventory($pSlot, UIInventorySlotOffset::LOOM, $current, + fn(Inventory $i) => $i instanceof LoomInventory); } if($mapped === null){ throw new \UnexpectedValueException("Unmatched UI inventory slot offset $pSlot"); diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index c7b28d156e..c499258d21 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -277,6 +277,7 @@ class InGamePacketHandler extends PacketHandler{ if($isCraftingPart){ if($this->craftingTransaction === null){ + //TODO: this might not be crafting if there is a special inventory open (anvil, enchanting, loom etc) $this->craftingTransaction = new CraftingTransaction($this->player, $this->player->getServer()->getCraftingManager(), $actions); }else{ foreach($actions as $action){ diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index d60ae5762d..27708bb9c5 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Mushroom Stem","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"All Sided Mushroom Stem","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Tube Coral","6177":"Brain Coral","6178":"Bubble Coral","6179":"Fire Coral","6180":"Horn Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Tube Coral Fan","6209":"Brain Coral Fan","6210":"Bubble Coral Fan","6211":"Fire Coral Fan","6212":"Horn Coral Fan","6216":"Tube Coral Fan","6217":"Brain Coral Fan","6218":"Bubble Coral Fan","6219":"Fire Coral Fan","6220":"Horn Coral Fan","6224":"Tube Coral Fan","6225":"Brain Coral Fan","6226":"Bubble Coral Fan","6227":"Fire Coral Fan","6228":"Horn Coral Fan","6232":"Tube Coral Fan","6233":"Brain Coral Fan","6234":"Bubble Coral Fan","6235":"Fire Coral Fan","6236":"Horn Coral Fan","6240":"Tube Wall Coral Fan","6241":"Brain Wall Coral Fan","6242":"Tube Wall Coral Fan","6243":"Brain Wall Coral Fan","6244":"Tube Wall Coral Fan","6245":"Brain Wall Coral Fan","6246":"Tube Wall Coral Fan","6247":"Brain Wall Coral Fan","6248":"Tube Wall Coral Fan","6249":"Brain Wall Coral Fan","6250":"Tube Wall Coral Fan","6251":"Brain Wall Coral Fan","6252":"Tube Wall Coral Fan","6253":"Brain Wall Coral Fan","6254":"Tube Wall Coral Fan","6255":"Brain Wall Coral Fan","6256":"Bubble Wall Coral Fan","6257":"Fire Wall Coral Fan","6258":"Bubble Wall Coral Fan","6259":"Fire Wall Coral Fan","6260":"Bubble Wall Coral Fan","6261":"Fire Wall Coral Fan","6262":"Bubble Wall Coral Fan","6263":"Fire Wall Coral Fan","6264":"Bubble Wall Coral Fan","6265":"Fire Wall Coral Fan","6266":"Bubble Wall Coral Fan","6267":"Fire Wall Coral Fan","6268":"Bubble Wall Coral Fan","6269":"Fire Wall Coral Fan","6270":"Bubble Wall Coral Fan","6271":"Fire Wall Coral Fan","6272":"Horn Wall Coral Fan","6274":"Horn Wall Coral Fan","6276":"Horn Wall Coral Fan","6278":"Horn Wall Coral Fan","6280":"Horn Wall Coral Fan","6282":"Horn Wall Coral Fan","6284":"Horn Wall Coral Fan","6286":"Horn Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Mushroom Stem","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"All Sided Mushroom Stem","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Tube Coral","6177":"Brain Coral","6178":"Bubble Coral","6179":"Fire Coral","6180":"Horn Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Tube Coral Fan","6209":"Brain Coral Fan","6210":"Bubble Coral Fan","6211":"Fire Coral Fan","6212":"Horn Coral Fan","6216":"Tube Coral Fan","6217":"Brain Coral Fan","6218":"Bubble Coral Fan","6219":"Fire Coral Fan","6220":"Horn Coral Fan","6224":"Tube Coral Fan","6225":"Brain Coral Fan","6226":"Bubble Coral Fan","6227":"Fire Coral Fan","6228":"Horn Coral Fan","6232":"Tube Coral Fan","6233":"Brain Coral Fan","6234":"Bubble Coral Fan","6235":"Fire Coral Fan","6236":"Horn Coral Fan","6240":"Tube Wall Coral Fan","6241":"Brain Wall Coral Fan","6242":"Tube Wall Coral Fan","6243":"Brain Wall Coral Fan","6244":"Tube Wall Coral Fan","6245":"Brain Wall Coral Fan","6246":"Tube Wall Coral Fan","6247":"Brain Wall Coral Fan","6248":"Tube Wall Coral Fan","6249":"Brain Wall Coral Fan","6250":"Tube Wall Coral Fan","6251":"Brain Wall Coral Fan","6252":"Tube Wall Coral Fan","6253":"Brain Wall Coral Fan","6254":"Tube Wall Coral Fan","6255":"Brain Wall Coral Fan","6256":"Bubble Wall Coral Fan","6257":"Fire Wall Coral Fan","6258":"Bubble Wall Coral Fan","6259":"Fire Wall Coral Fan","6260":"Bubble Wall Coral Fan","6261":"Fire Wall Coral Fan","6262":"Bubble Wall Coral Fan","6263":"Fire Wall Coral Fan","6264":"Bubble Wall Coral Fan","6265":"Fire Wall Coral Fan","6266":"Bubble Wall Coral Fan","6267":"Fire Wall Coral Fan","6268":"Bubble Wall Coral Fan","6269":"Fire Wall Coral Fan","6270":"Bubble Wall Coral Fan","6271":"Fire Wall Coral Fan","6272":"Horn Wall Coral Fan","6274":"Horn Wall Coral Fan","6276":"Horn Wall Coral Fan","6278":"Horn Wall Coral Fan","6280":"Horn Wall Coral Fan","6282":"Horn Wall Coral Fan","6284":"Horn Wall Coral Fan","6286":"Horn Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From 726978b8f13e5e9744ce9a96ecc7d6fbb3e92d3d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 29 Apr 2021 20:11:03 +0100 Subject: [PATCH 2435/3224] Migrate all coloured blocks (except glazed terracotta) to dynamic colours --- src/block/BlockFactory.php | 11 +- src/block/StainedGlass.php | 30 ++++ src/block/StainedGlassPane.php | 30 ++++ src/block/StainedHardenedClay.php | 30 ++++ src/block/StainedHardenedGlass.php | 30 ++++ src/block/StainedHardenedGlassPane.php | 30 ++++ src/block/VanillaBlocks.php | 170 ++---------------- .../block_factory_consistency_check.json | 2 +- 8 files changed, 166 insertions(+), 167 deletions(-) create mode 100644 src/block/StainedGlass.php create mode 100644 src/block/StainedGlassPane.php create mode 100644 src/block/StainedHardenedClay.php create mode 100644 src/block/StainedHardenedGlass.php create mode 100644 src/block/StainedHardenedGlassPane.php diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 4fff6b0d23..28e0a2df91 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -439,18 +439,17 @@ class BlockFactory{ $this->register(new Opaque(new BID(Ids::RED_SANDSTONE, $variant), $prefix . "Red Sandstone", $sandstoneBreakInfo)); } - $colorIdMap = DyeColorIdMap::getInstance(); foreach(DyeColor::getAll() as $color){ $coloredName = function(string $name) use($color) : string{ return $color->getDisplayName() . " " . $name; }; - $this->register(new Glass(new BID(Ids::STAINED_GLASS, $colorIdMap->toId($color)), $coloredName("Stained Glass"))); - $this->register(new GlassPane(new BID(Ids::STAINED_GLASS_PANE, $colorIdMap->toId($color)), $coloredName("Stained Glass Pane"))); $this->register(new GlazedTerracotta(BlockLegacyIdHelper::getGlazedTerracottaIdentifier($color), $coloredName("Glazed Terracotta"))); - $this->register(new HardenedClay(new BID(Ids::STAINED_CLAY, $colorIdMap->toId($color)), $coloredName("Stained Clay"))); - $this->register(new HardenedGlass(new BID(Ids::HARD_STAINED_GLASS, $colorIdMap->toId($color)), "Hardened " . $coloredName("Stained Glass"))); - $this->register(new HardenedGlassPane(new BID(Ids::HARD_STAINED_GLASS_PANE, $colorIdMap->toId($color)), "Hardened " . $coloredName("Stained Glass Pane"))); } + $this->register(new StainedGlass(new BID(Ids::STAINED_GLASS, 0), "Stained Glass")); + $this->register(new StainedGlassPane(new BID(Ids::STAINED_GLASS_PANE, 0), "Stained Glass Pane")); + $this->register(new StainedHardenedClay(new BID(Ids::STAINED_CLAY, 0), "Stained Clay")); + $this->register(new StainedHardenedGlass(new BID(Ids::HARD_STAINED_GLASS, 0), "Stained Hardened Glass")); + $this->register(new StainedHardenedGlassPane(new BID(Ids::HARD_STAINED_GLASS_PANE, 0), "Stained Hardened Glass Pane")); $this->register(new Carpet(new BID(Ids::CARPET, 0), "Carpet")); $this->register(new Concrete(new BID(Ids::CONCRETE, 0), "Concrete")); $this->register(new ConcretePowder(new BID(Ids::CONCRETE_POWDER, 0), "Concrete Powder")); diff --git a/src/block/StainedGlass.php b/src/block/StainedGlass.php new file mode 100644 index 0000000000..ea4ff2d944 --- /dev/null +++ b/src/block/StainedGlass.php @@ -0,0 +1,30 @@ +get(442, 2)); self::register("birch_wood", $factory->get(467, 2)); self::register("black_glazed_terracotta", $factory->get(235, 2)); - self::register("black_stained_clay", $factory->get(159, 15)); - self::register("black_stained_glass", $factory->get(241, 15)); - self::register("black_stained_glass_pane", $factory->get(160, 15)); self::register("blue_glazed_terracotta", $factory->get(231, 2)); self::register("blue_ice", $factory->get(266, 0)); self::register("blue_orchid", $factory->get(38, 1)); - self::register("blue_stained_clay", $factory->get(159, 11)); - self::register("blue_stained_glass", $factory->get(241, 11)); - self::register("blue_stained_glass_pane", $factory->get(160, 11)); self::register("blue_torch", $factory->get(204, 5)); self::register("bone_block", $factory->get(216, 0)); self::register("bookshelf", $factory->get(47, 0)); @@ -745,9 +664,6 @@ final class VanillaBlocks{ self::register("brown_glazed_terracotta", $factory->get(232, 2)); self::register("brown_mushroom", $factory->get(39, 0)); self::register("brown_mushroom_block", $factory->get(99, 0)); - self::register("brown_stained_clay", $factory->get(159, 12)); - self::register("brown_stained_glass", $factory->get(241, 12)); - self::register("brown_stained_glass_pane", $factory->get(160, 12)); self::register("bubble_coral", $factory->get(386, 2)); self::register("bubble_coral_fan", $factory->get(388, 2)); self::register("bubble_wall_coral_fan", $factory->get(391, 0)); @@ -784,9 +700,6 @@ final class VanillaBlocks{ self::register("cut_sandstone", $factory->get(24, 2)); self::register("cut_sandstone_slab", $factory->get(421, 3)); self::register("cyan_glazed_terracotta", $factory->get(229, 2)); - self::register("cyan_stained_clay", $factory->get(159, 9)); - self::register("cyan_stained_glass", $factory->get(241, 9)); - self::register("cyan_stained_glass_pane", $factory->get(160, 9)); self::register("dandelion", $factory->get(37, 0)); self::register("dark_oak_button", $factory->get(397, 0)); self::register("dark_oak_door", $factory->get(197, 0)); @@ -974,49 +887,11 @@ final class VanillaBlocks{ self::register("grass_path", $factory->get(198, 0)); self::register("gravel", $factory->get(13, 0)); self::register("gray_glazed_terracotta", $factory->get(227, 2)); - self::register("gray_stained_clay", $factory->get(159, 7)); - self::register("gray_stained_glass", $factory->get(241, 7)); - self::register("gray_stained_glass_pane", $factory->get(160, 7)); self::register("green_glazed_terracotta", $factory->get(233, 2)); - self::register("green_stained_clay", $factory->get(159, 13)); - self::register("green_stained_glass", $factory->get(241, 13)); - self::register("green_stained_glass_pane", $factory->get(160, 13)); self::register("green_torch", $factory->get(202, 13)); - self::register("hardened_black_stained_glass", $factory->get(254, 15)); - self::register("hardened_black_stained_glass_pane", $factory->get(191, 15)); - self::register("hardened_blue_stained_glass", $factory->get(254, 11)); - self::register("hardened_blue_stained_glass_pane", $factory->get(191, 11)); - self::register("hardened_brown_stained_glass", $factory->get(254, 12)); - self::register("hardened_brown_stained_glass_pane", $factory->get(191, 12)); self::register("hardened_clay", $factory->get(172, 0)); - self::register("hardened_cyan_stained_glass", $factory->get(254, 9)); - self::register("hardened_cyan_stained_glass_pane", $factory->get(191, 9)); self::register("hardened_glass", $factory->get(253, 0)); self::register("hardened_glass_pane", $factory->get(190, 0)); - self::register("hardened_gray_stained_glass", $factory->get(254, 7)); - self::register("hardened_gray_stained_glass_pane", $factory->get(191, 7)); - self::register("hardened_green_stained_glass", $factory->get(254, 13)); - self::register("hardened_green_stained_glass_pane", $factory->get(191, 13)); - self::register("hardened_light_blue_stained_glass", $factory->get(254, 3)); - self::register("hardened_light_blue_stained_glass_pane", $factory->get(191, 3)); - self::register("hardened_light_gray_stained_glass", $factory->get(254, 8)); - self::register("hardened_light_gray_stained_glass_pane", $factory->get(191, 8)); - self::register("hardened_lime_stained_glass", $factory->get(254, 5)); - self::register("hardened_lime_stained_glass_pane", $factory->get(191, 5)); - self::register("hardened_magenta_stained_glass", $factory->get(254, 2)); - self::register("hardened_magenta_stained_glass_pane", $factory->get(191, 2)); - self::register("hardened_orange_stained_glass", $factory->get(254, 1)); - self::register("hardened_orange_stained_glass_pane", $factory->get(191, 1)); - self::register("hardened_pink_stained_glass", $factory->get(254, 6)); - self::register("hardened_pink_stained_glass_pane", $factory->get(191, 6)); - self::register("hardened_purple_stained_glass", $factory->get(254, 10)); - self::register("hardened_purple_stained_glass_pane", $factory->get(191, 10)); - self::register("hardened_red_stained_glass", $factory->get(254, 14)); - self::register("hardened_red_stained_glass_pane", $factory->get(191, 14)); - self::register("hardened_white_stained_glass", $factory->get(254, 0)); - self::register("hardened_white_stained_glass_pane", $factory->get(191, 0)); - self::register("hardened_yellow_stained_glass", $factory->get(254, 4)); - self::register("hardened_yellow_stained_glass_pane", $factory->get(191, 4)); self::register("hay_bale", $factory->get(170, 0)); self::register("hopper", $factory->get(154, 0)); self::register("horn_coral", $factory->get(386, 4)); @@ -1064,26 +939,14 @@ final class VanillaBlocks{ self::register("legacy_stonecutter", $factory->get(245, 0)); self::register("lever", $factory->get(69, 0)); self::register("light_blue_glazed_terracotta", $factory->get(223, 2)); - self::register("light_blue_stained_clay", $factory->get(159, 3)); - self::register("light_blue_stained_glass", $factory->get(241, 3)); - self::register("light_blue_stained_glass_pane", $factory->get(160, 3)); self::register("light_gray_glazed_terracotta", $factory->get(228, 2)); - self::register("light_gray_stained_clay", $factory->get(159, 8)); - self::register("light_gray_stained_glass", $factory->get(241, 8)); - self::register("light_gray_stained_glass_pane", $factory->get(160, 8)); self::register("lilac", $factory->get(175, 1)); self::register("lily_of_the_valley", $factory->get(38, 10)); self::register("lily_pad", $factory->get(111, 0)); self::register("lime_glazed_terracotta", $factory->get(225, 2)); - self::register("lime_stained_clay", $factory->get(159, 5)); - self::register("lime_stained_glass", $factory->get(241, 5)); - self::register("lime_stained_glass_pane", $factory->get(160, 5)); self::register("lit_pumpkin", $factory->get(91, 0)); self::register("loom", $factory->get(459, 0)); self::register("magenta_glazed_terracotta", $factory->get(222, 2)); - self::register("magenta_stained_clay", $factory->get(159, 2)); - self::register("magenta_stained_glass", $factory->get(241, 2)); - self::register("magenta_stained_glass_pane", $factory->get(160, 2)); self::register("magma", $factory->get(213, 0)); self::register("material_reducer", $factory->get(238, 4)); self::register("melon", $factory->get(103, 0)); @@ -1129,17 +992,11 @@ final class VanillaBlocks{ self::register("oak_wood", $factory->get(467, 0)); self::register("obsidian", $factory->get(49, 0)); self::register("orange_glazed_terracotta", $factory->get(221, 2)); - self::register("orange_stained_clay", $factory->get(159, 1)); - self::register("orange_stained_glass", $factory->get(241, 1)); - self::register("orange_stained_glass_pane", $factory->get(160, 1)); self::register("orange_tulip", $factory->get(38, 5)); self::register("oxeye_daisy", $factory->get(38, 8)); self::register("packed_ice", $factory->get(174, 0)); self::register("peony", $factory->get(175, 5)); self::register("pink_glazed_terracotta", $factory->get(226, 2)); - self::register("pink_stained_clay", $factory->get(159, 6)); - self::register("pink_stained_glass", $factory->get(241, 6)); - self::register("pink_stained_glass_pane", $factory->get(160, 6)); self::register("pink_tulip", $factory->get(38, 7)); self::register("podzol", $factory->get(243, 0)); self::register("polished_andesite", $factory->get(1, 6)); @@ -1164,9 +1021,6 @@ final class VanillaBlocks{ self::register("pumpkin", $factory->get(86, 0)); self::register("pumpkin_stem", $factory->get(104, 0)); self::register("purple_glazed_terracotta", $factory->get(219, 2)); - self::register("purple_stained_clay", $factory->get(159, 10)); - self::register("purple_stained_glass", $factory->get(241, 10)); - self::register("purple_stained_glass_pane", $factory->get(160, 10)); self::register("purple_torch", $factory->get(204, 13)); self::register("purpur", $factory->get(201, 0)); self::register("purpur_pillar", $factory->get(201, 2)); @@ -1189,9 +1043,6 @@ final class VanillaBlocks{ self::register("red_sandstone_slab", $factory->get(182, 0)); self::register("red_sandstone_stairs", $factory->get(180, 0)); self::register("red_sandstone_wall", $factory->get(139, 12)); - self::register("red_stained_clay", $factory->get(159, 14)); - self::register("red_stained_glass", $factory->get(241, 14)); - self::register("red_stained_glass_pane", $factory->get(160, 14)); self::register("red_torch", $factory->get(202, 5)); self::register("red_tulip", $factory->get(38, 4)); self::register("redstone", $factory->get(152, 0)); @@ -1240,6 +1091,11 @@ final class VanillaBlocks{ self::register("spruce_trapdoor", $factory->get(404, 0)); self::register("spruce_wall_sign", $factory->get(437, 2)); self::register("spruce_wood", $factory->get(467, 1)); + self::register("stained_clay", $factory->get(159, 0)); + self::register("stained_glass", $factory->get(241, 0)); + self::register("stained_glass_pane", $factory->get(160, 0)); + self::register("stained_hardened_glass", $factory->get(254, 0)); + self::register("stained_hardened_glass_pane", $factory->get(191, 0)); self::register("stone", $factory->get(1, 0)); self::register("stone_brick_slab", $factory->get(44, 5)); self::register("stone_brick_stairs", $factory->get(109, 0)); @@ -1274,14 +1130,8 @@ final class VanillaBlocks{ self::register("weighted_pressure_plate_light", $factory->get(147, 0)); self::register("wheat", $factory->get(59, 0)); self::register("white_glazed_terracotta", $factory->get(220, 2)); - self::register("white_stained_clay", $factory->get(159, 0)); - self::register("white_stained_glass", $factory->get(241, 0)); - self::register("white_stained_glass_pane", $factory->get(160, 0)); self::register("white_tulip", $factory->get(38, 6)); self::register("wool", $factory->get(35, 0)); self::register("yellow_glazed_terracotta", $factory->get(224, 2)); - self::register("yellow_stained_clay", $factory->get(159, 4)); - self::register("yellow_stained_glass", $factory->get(241, 4)); - self::register("yellow_stained_glass_pane", $factory->get(160, 4)); } } diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 27708bb9c5..812ba65102 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Mushroom Stem","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"All Sided Mushroom Stem","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"White Stained Clay","2545":"Orange Stained Clay","2546":"Magenta Stained Clay","2547":"Light Blue Stained Clay","2548":"Yellow Stained Clay","2549":"Lime Stained Clay","2550":"Pink Stained Clay","2551":"Gray Stained Clay","2552":"Light Gray Stained Clay","2553":"Cyan Stained Clay","2554":"Purple Stained Clay","2555":"Blue Stained Clay","2556":"Brown Stained Clay","2557":"Green Stained Clay","2558":"Red Stained Clay","2559":"Black Stained Clay","2560":"White Stained Glass Pane","2561":"Orange Stained Glass Pane","2562":"Magenta Stained Glass Pane","2563":"Light Blue Stained Glass Pane","2564":"Yellow Stained Glass Pane","2565":"Lime Stained Glass Pane","2566":"Pink Stained Glass Pane","2567":"Gray Stained Glass Pane","2568":"Light Gray Stained Glass Pane","2569":"Cyan Stained Glass Pane","2570":"Purple Stained Glass Pane","2571":"Blue Stained Glass Pane","2572":"Brown Stained Glass Pane","2573":"Green Stained Glass Pane","2574":"Red Stained Glass Pane","2575":"Black Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Hardened White Stained Glass Pane","3057":"Hardened Orange Stained Glass Pane","3058":"Hardened Magenta Stained Glass Pane","3059":"Hardened Light Blue Stained Glass Pane","3060":"Hardened Yellow Stained Glass Pane","3061":"Hardened Lime Stained Glass Pane","3062":"Hardened Pink Stained Glass Pane","3063":"Hardened Gray Stained Glass Pane","3064":"Hardened Light Gray Stained Glass Pane","3065":"Hardened Cyan Stained Glass Pane","3066":"Hardened Purple Stained Glass Pane","3067":"Hardened Blue Stained Glass Pane","3068":"Hardened Brown Stained Glass Pane","3069":"Hardened Green Stained Glass Pane","3070":"Hardened Red Stained Glass Pane","3071":"Hardened Black Stained Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"White Stained Glass","3857":"Orange Stained Glass","3858":"Magenta Stained Glass","3859":"Light Blue Stained Glass","3860":"Yellow Stained Glass","3861":"Lime Stained Glass","3862":"Pink Stained Glass","3863":"Gray Stained Glass","3864":"Light Gray Stained Glass","3865":"Cyan Stained Glass","3866":"Purple Stained Glass","3867":"Blue Stained Glass","3868":"Brown Stained Glass","3869":"Green Stained Glass","3870":"Red Stained Glass","3871":"Black Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Hardened White Stained Glass","4065":"Hardened Orange Stained Glass","4066":"Hardened Magenta Stained Glass","4067":"Hardened Light Blue Stained Glass","4068":"Hardened Yellow Stained Glass","4069":"Hardened Lime Stained Glass","4070":"Hardened Pink Stained Glass","4071":"Hardened Gray Stained Glass","4072":"Hardened Light Gray Stained Glass","4073":"Hardened Cyan Stained Glass","4074":"Hardened Purple Stained Glass","4075":"Hardened Blue Stained Glass","4076":"Hardened Brown Stained Glass","4077":"Hardened Green Stained Glass","4078":"Hardened Red Stained Glass","4079":"Hardened Black Stained Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Tube Coral","6177":"Brain Coral","6178":"Bubble Coral","6179":"Fire Coral","6180":"Horn Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Tube Coral Fan","6209":"Brain Coral Fan","6210":"Bubble Coral Fan","6211":"Fire Coral Fan","6212":"Horn Coral Fan","6216":"Tube Coral Fan","6217":"Brain Coral Fan","6218":"Bubble Coral Fan","6219":"Fire Coral Fan","6220":"Horn Coral Fan","6224":"Tube Coral Fan","6225":"Brain Coral Fan","6226":"Bubble Coral Fan","6227":"Fire Coral Fan","6228":"Horn Coral Fan","6232":"Tube Coral Fan","6233":"Brain Coral Fan","6234":"Bubble Coral Fan","6235":"Fire Coral Fan","6236":"Horn Coral Fan","6240":"Tube Wall Coral Fan","6241":"Brain Wall Coral Fan","6242":"Tube Wall Coral Fan","6243":"Brain Wall Coral Fan","6244":"Tube Wall Coral Fan","6245":"Brain Wall Coral Fan","6246":"Tube Wall Coral Fan","6247":"Brain Wall Coral Fan","6248":"Tube Wall Coral Fan","6249":"Brain Wall Coral Fan","6250":"Tube Wall Coral Fan","6251":"Brain Wall Coral Fan","6252":"Tube Wall Coral Fan","6253":"Brain Wall Coral Fan","6254":"Tube Wall Coral Fan","6255":"Brain Wall Coral Fan","6256":"Bubble Wall Coral Fan","6257":"Fire Wall Coral Fan","6258":"Bubble Wall Coral Fan","6259":"Fire Wall Coral Fan","6260":"Bubble Wall Coral Fan","6261":"Fire Wall Coral Fan","6262":"Bubble Wall Coral Fan","6263":"Fire Wall Coral Fan","6264":"Bubble Wall Coral Fan","6265":"Fire Wall Coral Fan","6266":"Bubble Wall Coral Fan","6267":"Fire Wall Coral Fan","6268":"Bubble Wall Coral Fan","6269":"Fire Wall Coral Fan","6270":"Bubble Wall Coral Fan","6271":"Fire Wall Coral Fan","6272":"Horn Wall Coral Fan","6274":"Horn Wall Coral Fan","6276":"Horn Wall Coral Fan","6278":"Horn Wall Coral Fan","6280":"Horn Wall Coral Fan","6282":"Horn Wall Coral Fan","6284":"Horn Wall Coral Fan","6286":"Horn Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Mushroom Stem","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"All Sided Mushroom Stem","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Tube Coral","6177":"Brain Coral","6178":"Bubble Coral","6179":"Fire Coral","6180":"Horn Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Tube Coral Fan","6209":"Brain Coral Fan","6210":"Bubble Coral Fan","6211":"Fire Coral Fan","6212":"Horn Coral Fan","6216":"Tube Coral Fan","6217":"Brain Coral Fan","6218":"Bubble Coral Fan","6219":"Fire Coral Fan","6220":"Horn Coral Fan","6224":"Tube Coral Fan","6225":"Brain Coral Fan","6226":"Bubble Coral Fan","6227":"Fire Coral Fan","6228":"Horn Coral Fan","6232":"Tube Coral Fan","6233":"Brain Coral Fan","6234":"Bubble Coral Fan","6235":"Fire Coral Fan","6236":"Horn Coral Fan","6240":"Tube Wall Coral Fan","6241":"Brain Wall Coral Fan","6242":"Tube Wall Coral Fan","6243":"Brain Wall Coral Fan","6244":"Tube Wall Coral Fan","6245":"Brain Wall Coral Fan","6246":"Tube Wall Coral Fan","6247":"Brain Wall Coral Fan","6248":"Tube Wall Coral Fan","6249":"Brain Wall Coral Fan","6250":"Tube Wall Coral Fan","6251":"Brain Wall Coral Fan","6252":"Tube Wall Coral Fan","6253":"Brain Wall Coral Fan","6254":"Tube Wall Coral Fan","6255":"Brain Wall Coral Fan","6256":"Bubble Wall Coral Fan","6257":"Fire Wall Coral Fan","6258":"Bubble Wall Coral Fan","6259":"Fire Wall Coral Fan","6260":"Bubble Wall Coral Fan","6261":"Fire Wall Coral Fan","6262":"Bubble Wall Coral Fan","6263":"Fire Wall Coral Fan","6264":"Bubble Wall Coral Fan","6265":"Fire Wall Coral Fan","6266":"Bubble Wall Coral Fan","6267":"Fire Wall Coral Fan","6268":"Bubble Wall Coral Fan","6269":"Fire Wall Coral Fan","6270":"Bubble Wall Coral Fan","6271":"Fire Wall Coral Fan","6272":"Horn Wall Coral Fan","6274":"Horn Wall Coral Fan","6276":"Horn Wall Coral Fan","6278":"Horn Wall Coral Fan","6280":"Horn Wall Coral Fan","6282":"Horn Wall Coral Fan","6284":"Horn Wall Coral Fan","6286":"Horn Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From d37016f43bc877a21520ee21ede6b8074366f479 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 30 Apr 2021 13:35:38 +0100 Subject: [PATCH 2436/3224] Vine: added API to get/set faces --- src/block/Vine.php | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/block/Vine.php b/src/block/Vine.php index a247b06e3d..6cbe53700d 100644 --- a/src/block/Vine.php +++ b/src/block/Vine.php @@ -62,11 +62,40 @@ class Vine extends Flowable{ } private function setFaceFromMeta(int $meta, int $flag, int $face) : void{ - if(($meta & $flag) !== 0){ + $this->setFace($face, ($meta & $flag) !== 0); + } + + /** @return int[] */ + public function getFaces() : array{ return $this->faces; } + + /** + * @param int[] $faces + * @phpstan-param list $faces + * @return $this + */ + public function setFaces(array $faces) : self{ + $uniqueFaces = []; + foreach($faces as $face){ + if($face !== Facing::NORTH && $face !== Facing::SOUTH && $face !== Facing::WEST && $face !== Facing::EAST){ + throw new \InvalidArgumentException("Facing can only be north, east, south or west"); + } + $uniqueFaces[$face] = $face; + } + $this->faces = $uniqueFaces; + return $this; + } + + /** @return $this */ + public function setFace(int $face, bool $value) : self{ + if($face !== Facing::NORTH && $face !== Facing::SOUTH && $face !== Facing::WEST && $face !== Facing::EAST){ + throw new \InvalidArgumentException("Facing can only be north, east, south or west"); + } + if($value){ $this->faces[$face] = $face; }else{ unset($this->faces[$face]); } + return $this; } public function hasEntityCollision() : bool{ From f538440bce92a0bfe4cbb9578563017d075620af Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 30 Apr 2021 13:44:39 +0100 Subject: [PATCH 2437/3224] De-spaghettify the hierarchy for chest inventories --- src/block/inventory/DoubleChestInventory.php | 18 +++++++----------- src/block/inventory/EnderChestInventory.php | 12 ++++++++++-- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/block/inventory/DoubleChestInventory.php b/src/block/inventory/DoubleChestInventory.php index 978d132b0a..cab0c2acb4 100644 --- a/src/block/inventory/DoubleChestInventory.php +++ b/src/block/inventory/DoubleChestInventory.php @@ -23,12 +23,11 @@ declare(strict_types=1); namespace pocketmine\block\inventory; -use pocketmine\inventory\BaseInventory; use pocketmine\inventory\InventoryHolder; use pocketmine\item\Item; -use pocketmine\world\Position; +use pocketmine\world\sound\Sound; -class DoubleChestInventory extends ChestInventory implements InventoryHolder{ +class DoubleChestInventory extends AnimatedBlockInventory implements InventoryHolder{ /** @var ChestInventory */ private $left; /** @var ChestInventory */ @@ -37,20 +36,13 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ public function __construct(ChestInventory $left, ChestInventory $right){ $this->left = $left; $this->right = $right; - BaseInventory::__construct($this->left->getSize() + $this->right->getSize()); + parent::__construct($this->left->getHolder(), $this->left->getSize() + $this->right->getSize()); } public function getInventory(){ return $this; } - /** - * @return Position - */ - public function getHolder(){ - return $this->left->getHolder(); - } - public function getItem(int $index) : Item{ return $index < $this->left->getSize() ? $this->left->getItem($index) : $this->right->getItem($index - $this->left->getSize()); } @@ -72,6 +64,10 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ return $result; } + protected function getOpenSound() : Sound{ return $this->left->getOpenSound(); } + + protected function getCloseSound() : Sound{ return $this->left->getCloseSound(); } + protected function animateBlock(bool $isOpen) : void{ $this->left->animateBlock($isOpen); $this->right->animateBlock($isOpen); diff --git a/src/block/inventory/EnderChestInventory.php b/src/block/inventory/EnderChestInventory.php index 1e822aa28e..b176997d96 100644 --- a/src/block/inventory/EnderChestInventory.php +++ b/src/block/inventory/EnderChestInventory.php @@ -23,15 +23,16 @@ declare(strict_types=1); namespace pocketmine\block\inventory; +use pocketmine\network\mcpe\protocol\BlockEventPacket; use pocketmine\world\Position; use pocketmine\world\sound\EnderChestCloseSound; use pocketmine\world\sound\EnderChestOpenSound; use pocketmine\world\sound\Sound; -class EnderChestInventory extends ChestInventory{ +class EnderChestInventory extends AnimatedBlockInventory{ public function __construct(){ - parent::__construct(new Position(0, 0, 0, null)); + parent::__construct(new Position(0, 0, 0, null), 27); } public function setHolderPosition(Position $pos) : void{ @@ -45,4 +46,11 @@ class EnderChestInventory extends ChestInventory{ protected function getCloseSound() : Sound{ return new EnderChestCloseSound(); } + + protected function animateBlock(bool $isOpen) : void{ + $holder = $this->getHolder(); + + //event ID is always 1 for a chest + $holder->getWorld()->broadcastPacketToViewers($holder, BlockEventPacket::create(1, $isOpen ? 1 : 0, $holder->asVector3())); + } } From 9b8f32c58493b8928fadfe49a6ce81151b15580b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 2 May 2021 13:38:49 +0100 Subject: [PATCH 2438/3224] Extract inventory helper methods from BaseInventory to a trait this allows easier alternate implementations of Inventory that don't extend BaseInventory (e.g. double chest, or delegate inventory). --- src/inventory/BaseInventory.php | 199 +------------------ src/inventory/InventoryHelpersTrait.php | 244 ++++++++++++++++++++++++ 2 files changed, 245 insertions(+), 198 deletions(-) create mode 100644 src/inventory/InventoryHelpersTrait.php diff --git a/src/inventory/BaseInventory.php b/src/inventory/BaseInventory.php index 5e2ed288cc..c8e4f5db4d 100644 --- a/src/inventory/BaseInventory.php +++ b/src/inventory/BaseInventory.php @@ -30,11 +30,10 @@ use pocketmine\utils\ObjectSet; use function array_map; use function array_slice; use function count; -use function max; -use function min; use function spl_object_id; abstract class BaseInventory implements Inventory{ + use InventoryHelpersTrait; /** @var int */ protected $maxStackSize = Inventory::MAX_STACK; @@ -140,202 +139,6 @@ abstract class BaseInventory implements Inventory{ $this->onSlotChange($index, $oldItem); } - public function contains(Item $item) : bool{ - $count = max(1, $item->getCount()); - $checkDamage = !$item->hasAnyDamageValue(); - $checkTags = $item->hasNamedTag(); - foreach($this->getContents() as $i){ - if($item->equals($i, $checkDamage, $checkTags)){ - $count -= $i->getCount(); - if($count <= 0){ - return true; - } - } - } - - return false; - } - - public function all(Item $item) : array{ - $slots = []; - $checkDamage = !$item->hasAnyDamageValue(); - $checkTags = $item->hasNamedTag(); - foreach($this->getContents() as $index => $i){ - if($item->equals($i, $checkDamage, $checkTags)){ - $slots[$index] = $i; - } - } - - return $slots; - } - - public function remove(Item $item) : void{ - $checkDamage = !$item->hasAnyDamageValue(); - $checkTags = $item->hasNamedTag(); - - foreach($this->getContents() as $index => $i){ - if($item->equals($i, $checkDamage, $checkTags)){ - $this->clear($index); - } - } - } - - public function first(Item $item, bool $exact = false) : int{ - $count = $exact ? $item->getCount() : max(1, $item->getCount()); - $checkDamage = $exact || !$item->hasAnyDamageValue(); - $checkTags = $exact || $item->hasNamedTag(); - - foreach($this->getContents() as $index => $i){ - if($item->equals($i, $checkDamage, $checkTags) and ($i->getCount() === $count or (!$exact and $i->getCount() > $count))){ - return $index; - } - } - - return -1; - } - - public function firstEmpty() : int{ - foreach($this->slots as $i => $slot){ - if($slot === null or $slot->isNull()){ - return $i; - } - } - - return -1; - } - - public function isSlotEmpty(int $index) : bool{ - return $this->slots[$index] === null or $this->slots[$index]->isNull(); - } - - public function canAddItem(Item $item) : bool{ - $count = $item->getCount(); - for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ - $slot = $this->getItem($i); - if($item->equals($slot)){ - if(($diff = min($slot->getMaxStackSize(), $item->getMaxStackSize()) - $slot->getCount()) > 0){ - $count -= $diff; - } - }elseif($slot->isNull()){ - $count -= min($this->getMaxStackSize(), $item->getMaxStackSize()); - } - - if($count <= 0){ - return true; - } - } - - return false; - } - - public function addItem(Item ...$slots) : array{ - /** @var Item[] $itemSlots */ - /** @var Item[] $slots */ - $itemSlots = []; - foreach($slots as $slot){ - if(!$slot->isNull()){ - $itemSlots[] = clone $slot; - } - } - - $emptySlots = []; - - for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ - $item = $this->getItem($i); - if($item->isNull()){ - $emptySlots[] = $i; - } - - foreach($itemSlots as $index => $slot){ - if($slot->equals($item) and $item->getCount() < $item->getMaxStackSize()){ - $amount = min($item->getMaxStackSize() - $item->getCount(), $slot->getCount(), $this->getMaxStackSize()); - if($amount > 0){ - $slot->setCount($slot->getCount() - $amount); - $item->setCount($item->getCount() + $amount); - $this->setItem($i, $item); - if($slot->getCount() <= 0){ - unset($itemSlots[$index]); - } - } - } - } - - if(count($itemSlots) === 0){ - break; - } - } - - if(count($itemSlots) > 0 and count($emptySlots) > 0){ - foreach($emptySlots as $slotIndex){ - //This loop only gets the first item, then goes to the next empty slot - foreach($itemSlots as $index => $slot){ - $amount = min($slot->getMaxStackSize(), $slot->getCount(), $this->getMaxStackSize()); - $slot->setCount($slot->getCount() - $amount); - $item = clone $slot; - $item->setCount($amount); - $this->setItem($slotIndex, $item); - if($slot->getCount() <= 0){ - unset($itemSlots[$index]); - } - break; - } - } - } - - return $itemSlots; - } - - public function removeItem(Item ...$slots) : array{ - /** @var Item[] $itemSlots */ - /** @var Item[] $slots */ - $itemSlots = []; - foreach($slots as $slot){ - if(!$slot->isNull()){ - $itemSlots[] = clone $slot; - } - } - - for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ - $item = $this->getItem($i); - if($item->isNull()){ - continue; - } - - foreach($itemSlots as $index => $slot){ - if($slot->equals($item, !$slot->hasAnyDamageValue(), $slot->hasNamedTag())){ - $amount = min($item->getCount(), $slot->getCount()); - $slot->setCount($slot->getCount() - $amount); - $item->setCount($item->getCount() - $amount); - $this->setItem($i, $item); - if($slot->getCount() <= 0){ - unset($itemSlots[$index]); - } - } - } - - if(count($itemSlots) === 0){ - break; - } - } - - return $itemSlots; - } - - public function clear(int $index) : void{ - $this->setItem($index, ItemFactory::air()); - } - - public function clearAll() : void{ - $this->setContents([]); - } - - public function swap(int $slot1, int $slot2) : void{ - $i1 = $this->getItem($slot1); - $i2 = $this->getItem($slot2); - $this->setItem($slot1, $i2); - $this->setItem($slot2, $i1); - } - /** * @return Player[] */ diff --git a/src/inventory/InventoryHelpersTrait.php b/src/inventory/InventoryHelpersTrait.php new file mode 100644 index 0000000000..828a817e85 --- /dev/null +++ b/src/inventory/InventoryHelpersTrait.php @@ -0,0 +1,244 @@ +getCount()); + $checkDamage = !$item->hasAnyDamageValue(); + $checkTags = $item->hasNamedTag(); + foreach($this->getContents() as $i){ + if($item->equals($i, $checkDamage, $checkTags)){ + $count -= $i->getCount(); + if($count <= 0){ + return true; + } + } + } + + return false; + } + + public function all(Item $item) : array{ + $slots = []; + $checkDamage = !$item->hasAnyDamageValue(); + $checkTags = $item->hasNamedTag(); + foreach($this->getContents() as $index => $i){ + if($item->equals($i, $checkDamage, $checkTags)){ + $slots[$index] = $i; + } + } + + return $slots; + } + + public function remove(Item $item) : void{ + $checkDamage = !$item->hasAnyDamageValue(); + $checkTags = $item->hasNamedTag(); + + foreach($this->getContents() as $index => $i){ + if($item->equals($i, $checkDamage, $checkTags)){ + $this->clear($index); + } + } + } + + public function first(Item $item, bool $exact = false) : int{ + $count = $exact ? $item->getCount() : max(1, $item->getCount()); + $checkDamage = $exact || !$item->hasAnyDamageValue(); + $checkTags = $exact || $item->hasNamedTag(); + + foreach($this->getContents() as $index => $i){ + if($item->equals($i, $checkDamage, $checkTags) and ($i->getCount() === $count or (!$exact and $i->getCount() > $count))){ + return $index; + } + } + + return -1; + } + + public function firstEmpty() : int{ + foreach($this->getContents(true) as $i => $slot){ + if($slot === null or $slot->isNull()){ + return $i; + } + } + + return -1; + } + + public function isSlotEmpty(int $index) : bool{ + return $this->getItem($index)->isNull(); + } + + public function canAddItem(Item $item) : bool{ + $count = $item->getCount(); + for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ + $slot = $this->getItem($i); + if($item->equals($slot)){ + if(($diff = min($slot->getMaxStackSize(), $item->getMaxStackSize()) - $slot->getCount()) > 0){ + $count -= $diff; + } + }elseif($slot->isNull()){ + $count -= min($this->getMaxStackSize(), $item->getMaxStackSize()); + } + + if($count <= 0){ + return true; + } + } + + return false; + } + + public function addItem(Item ...$slots) : array{ + /** @var Item[] $itemSlots */ + /** @var Item[] $slots */ + $itemSlots = []; + foreach($slots as $slot){ + if(!$slot->isNull()){ + $itemSlots[] = clone $slot; + } + } + + $emptySlots = []; + + for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ + $item = $this->getItem($i); + if($item->isNull()){ + $emptySlots[] = $i; + } + + foreach($itemSlots as $index => $slot){ + if($slot->equals($item) and $item->getCount() < $item->getMaxStackSize()){ + $amount = min($item->getMaxStackSize() - $item->getCount(), $slot->getCount(), $this->getMaxStackSize()); + if($amount > 0){ + $slot->setCount($slot->getCount() - $amount); + $item->setCount($item->getCount() + $amount); + $this->setItem($i, $item); + if($slot->getCount() <= 0){ + unset($itemSlots[$index]); + } + } + } + } + + if(count($itemSlots) === 0){ + break; + } + } + + if(count($itemSlots) > 0 and count($emptySlots) > 0){ + foreach($emptySlots as $slotIndex){ + //This loop only gets the first item, then goes to the next empty slot + foreach($itemSlots as $index => $slot){ + $amount = min($slot->getMaxStackSize(), $slot->getCount(), $this->getMaxStackSize()); + $slot->setCount($slot->getCount() - $amount); + $item = clone $slot; + $item->setCount($amount); + $this->setItem($slotIndex, $item); + if($slot->getCount() <= 0){ + unset($itemSlots[$index]); + } + break; + } + } + } + + return $itemSlots; + } + + public function removeItem(Item ...$slots) : array{ + /** @var Item[] $itemSlots */ + /** @var Item[] $slots */ + $itemSlots = []; + foreach($slots as $slot){ + if(!$slot->isNull()){ + $itemSlots[] = clone $slot; + } + } + + for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ + $item = $this->getItem($i); + if($item->isNull()){ + continue; + } + + foreach($itemSlots as $index => $slot){ + if($slot->equals($item, !$slot->hasAnyDamageValue(), $slot->hasNamedTag())){ + $amount = min($item->getCount(), $slot->getCount()); + $slot->setCount($slot->getCount() - $amount); + $item->setCount($item->getCount() - $amount); + $this->setItem($i, $item); + if($slot->getCount() <= 0){ + unset($itemSlots[$index]); + } + } + } + + if(count($itemSlots) === 0){ + break; + } + } + + return $itemSlots; + } + + public function clear(int $index) : void{ + $this->setItem($index, ItemFactory::air()); + } + + public function clearAll() : void{ + $this->setContents([]); + } + + public function swap(int $slot1, int $slot2) : void{ + $i1 = $this->getItem($slot1); + $i2 = $this->getItem($slot2); + $this->setItem($slot1, $i2); + $this->setItem($slot2, $i1); + } +} From 988c9764592707155723e2ffde3db4d01f26bad0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 2 May 2021 13:40:18 +0100 Subject: [PATCH 2439/3224] Remove unused import --- src/block/BlockFactory.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 28e0a2df91..03e186f2eb 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -50,7 +50,6 @@ use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\block\utils\TreeType; use pocketmine\data\bedrock\CoralTypeIdMap; -use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\item\Item; use pocketmine\item\ItemIds; use pocketmine\item\ToolTier; From 4c783f10378a1fdae37656f3cde2a7334694556a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 2 May 2021 13:43:37 +0100 Subject: [PATCH 2440/3224] shut --- src/inventory/InventoryHelpersTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/inventory/InventoryHelpersTrait.php b/src/inventory/InventoryHelpersTrait.php index 828a817e85..0ce6f22dd2 100644 --- a/src/inventory/InventoryHelpersTrait.php +++ b/src/inventory/InventoryHelpersTrait.php @@ -102,7 +102,7 @@ trait InventoryHelpersTrait{ public function firstEmpty() : int{ foreach($this->getContents(true) as $i => $slot){ - if($slot === null or $slot->isNull()){ + if($slot->isNull()){ return $i; } } From 129ca7fee08b9bac42ce92411bc444092c3b5a7d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 2 May 2021 13:55:32 +0100 Subject: [PATCH 2441/3224] Silence a PHPStan bug I'm not able to reproduce this one on the playground, but it still shows up even when disabling certain phpdocs... --- phpstan.neon.dist | 1 + tests/phpstan/configs/phpstan-bugs.neon | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 20120710e4..06f5907b98 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -22,6 +22,7 @@ parameters: level: 8 checkExplicitMixed: true checkMissingCallableSignature: true + treatPhpDocTypesAsCertain: false bootstrapFiles: - tests/phpstan/bootstrap.php scanDirectories: diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 485bcc6283..4828b333be 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -1,5 +1,10 @@ parameters: ignoreErrors: + - + message: "#^Strict comparison using \\!\\=\\= between 5 and 5 will always evaluate to false\\.$#" + count: 1 + path: ../../../src/block/Vine.php + - message: "#^Call to function is_resource\\(\\) with resource will always evaluate to true\\.$#" count: 3 From b8645f5c15582aef533029abda91c01e21d34688 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 2 May 2021 14:26:27 +0100 Subject: [PATCH 2442/3224] Clean up EnderChestInventory implementation now, EnderChestInventory is just a temporary window, much like anvil/enchanting windows. It provides a gateway to the player's PlayerEnderInventory. This removes one of the remaining obstacles to disallowing null World in Position constructor. --- src/block/EnderChest.php | 4 +- src/block/inventory/EnderChestInventory.php | 53 +++++++++++++++++++-- src/entity/Human.php | 23 ++++----- src/inventory/BaseInventory.php | 22 ++++++--- src/inventory/PlayerEnderInventory.php | 38 +++++++++++++++ tests/phpstan/configs/gc-hacks.neon | 2 +- 6 files changed, 117 insertions(+), 25 deletions(-) create mode 100644 src/inventory/PlayerEnderInventory.php diff --git a/src/block/EnderChest.php b/src/block/EnderChest.php index 69dc97a27b..be96d4443f 100644 --- a/src/block/EnderChest.php +++ b/src/block/EnderChest.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\inventory\EnderChestInventory; use pocketmine\block\tile\EnderChest as TileEnderChest; use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait; @@ -57,8 +58,7 @@ class EnderChest extends Transparent{ if($player instanceof Player){ $enderChest = $this->pos->getWorld()->getTile($this->pos); if($enderChest instanceof TileEnderChest and $this->getSide(Facing::UP)->isTransparent()){ - $player->getEnderChestInventory()->setHolderPosition($this->pos); - $player->setCurrentWindow($player->getEnderChestInventory()); + $player->setCurrentWindow(new EnderChestInventory($this->pos, $player->getEnderInventory())); } } diff --git a/src/block/inventory/EnderChestInventory.php b/src/block/inventory/EnderChestInventory.php index b176997d96..085c7dc4c7 100644 --- a/src/block/inventory/EnderChestInventory.php +++ b/src/block/inventory/EnderChestInventory.php @@ -23,20 +23,57 @@ declare(strict_types=1); namespace pocketmine\block\inventory; +use pocketmine\inventory\CallbackInventoryListener; +use pocketmine\inventory\Inventory; +use pocketmine\inventory\InventoryListener; +use pocketmine\inventory\PlayerEnderInventory; +use pocketmine\item\Item; use pocketmine\network\mcpe\protocol\BlockEventPacket; +use pocketmine\player\Player; use pocketmine\world\Position; use pocketmine\world\sound\EnderChestCloseSound; use pocketmine\world\sound\EnderChestOpenSound; use pocketmine\world\sound\Sound; +/** + * EnderChestInventory is not a real inventory; it's just a gateway to the player's ender inventory. + */ class EnderChestInventory extends AnimatedBlockInventory{ - public function __construct(){ - parent::__construct(new Position(0, 0, 0, null), 27); + private PlayerEnderInventory $inventory; + private InventoryListener $inventoryListener; + + public function __construct(Position $holder, PlayerEnderInventory $inventory){ + parent::__construct($holder, $inventory->getSize()); + $this->inventory = $inventory; + $this->inventory->getListeners()->add($this->inventoryListener = new CallbackInventoryListener( + function(Inventory $unused, int $slot, Item $oldItem) : void{ + $this->onSlotChange($slot, $oldItem); + }, + function(Inventory $unused, array $oldContents) : void{ + $this->onContentChange($oldContents); + } + )); } - public function setHolderPosition(Position $pos) : void{ - $this->holder = $pos->asPosition(); + public function getEnderInventory() : PlayerEnderInventory{ + return $this->inventory; + } + + public function getItem(int $index) : Item{ + return $this->inventory->getItem($index); + } + + public function setItem(int $index, Item $item) : void{ + $this->inventory->setItem($index, $item); + } + + public function getContents(bool $includeEmpty = false) : array{ + return $this->inventory->getContents($includeEmpty); + } + + public function setContents(array $items) : void{ + $this->inventory->setContents($items); } protected function getOpenSound() : Sound{ @@ -53,4 +90,12 @@ class EnderChestInventory extends AnimatedBlockInventory{ //event ID is always 1 for a chest $holder->getWorld()->broadcastPacketToViewers($holder, BlockEventPacket::create(1, $isOpen ? 1 : 0, $holder->asVector3())); } + + public function onClose(Player $who) : void{ + parent::onClose($who); + if($who === $this->inventory->getHolder()){ + $this->inventory->getListeners()->remove($this->inventoryListener); + $this->inventoryListener = CallbackInventoryListener::onAnyChange(static function() : void{}); //break cyclic reference + } + } } diff --git a/src/entity/Human.php b/src/entity/Human.php index 6dc35ccc70..30f12b5a67 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -33,6 +33,7 @@ use pocketmine\event\player\PlayerExhaustEvent; use pocketmine\inventory\CallbackInventoryListener; use pocketmine\inventory\Inventory; use pocketmine\inventory\InventoryHolder; +use pocketmine\inventory\PlayerEnderInventory; use pocketmine\inventory\PlayerInventory; use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\item\Item; @@ -73,8 +74,8 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ /** @var PlayerInventory */ protected $inventory; - /** @var EnderChestInventory */ - protected $enderChestInventory; + /** @var PlayerEnderInventory */ + protected $enderInventory; /** @var UuidInterface */ protected $uuid; @@ -193,8 +194,8 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ return $this->inventory; } - public function getEnderChestInventory() : EnderChestInventory{ - return $this->enderChestInventory; + public function getEnderInventory() : PlayerEnderInventory{ + return $this->enderInventory; } /** @@ -233,7 +234,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ } } )); - $this->enderChestInventory = new EnderChestInventory(); + $this->enderInventory = new PlayerEnderInventory($this); $this->initHumanData($nbt); $inventoryTag = $nbt->getListTag("Inventory"); @@ -263,7 +264,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ if($enderChestInventoryTag !== null){ /** @var CompoundTag $item */ foreach($enderChestInventoryTag as $i => $item){ - $this->enderChestInventory->setItem($item->getByte("Slot"), Item::nbtDeserialize($item)); + $this->enderInventory->setItem($item->getByte("Slot"), Item::nbtDeserialize($item)); } } @@ -382,13 +383,13 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $nbt->setInt("SelectedInventorySlot", $this->inventory->getHeldItemIndex()); } - if($this->enderChestInventory !== null){ + if($this->enderInventory !== null){ /** @var CompoundTag[] $items */ $items = []; - $slotCount = $this->enderChestInventory->getSize(); + $slotCount = $this->enderInventory->getSize(); for($slot = 0; $slot < $slotCount; ++$slot){ - $item = $this->enderChestInventory->getItem($slot); + $item = $this->enderInventory->getItem($slot); if(!$item->isNull()){ $items[] = $item->nbtSerialize($slot); } @@ -466,13 +467,13 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ protected function onDispose() : void{ $this->inventory->removeAllViewers(); $this->inventory->getHeldItemIndexChangeListeners()->clear(); - $this->enderChestInventory->removeAllViewers(); + $this->enderInventory->removeAllViewers(); parent::onDispose(); } protected function destroyCycles() : void{ $this->inventory = null; - $this->enderChestInventory = null; + $this->enderInventory = null; $this->hungerManager = null; $this->xpManager = null; parent::destroyCycles(); diff --git a/src/inventory/BaseInventory.php b/src/inventory/BaseInventory.php index c8e4f5db4d..7c29c4b4ca 100644 --- a/src/inventory/BaseInventory.php +++ b/src/inventory/BaseInventory.php @@ -117,13 +117,7 @@ abstract class BaseInventory implements Inventory{ $this->viewers[$id] = $viewer; } - foreach($this->listeners as $listener){ - $listener->onContentChange($this, $oldContents); - } - - foreach($this->getViewers() as $viewer){ - $viewer->getNetworkSession()->getInvManager()->syncContents($this); - } + $this->onContentChange($oldContents); } public function setItem(int $index, Item $item) : void{ @@ -179,6 +173,20 @@ abstract class BaseInventory implements Inventory{ } } + /** + * @param Item[] $itemsBefore + * @phpstan-param array $itemsBefore + */ + protected function onContentChange(array $itemsBefore) : void{ + foreach($this->listeners as $listener){ + $listener->onContentChange($this, $itemsBefore); + } + + foreach($this->getViewers() as $viewer){ + $viewer->getNetworkSession()->getInvManager()->syncContents($this); + } + } + public function slotExists(int $slot) : bool{ return $slot >= 0 and $slot < $this->slots->getSize(); } diff --git a/src/inventory/PlayerEnderInventory.php b/src/inventory/PlayerEnderInventory.php new file mode 100644 index 0000000000..fb126dd45e --- /dev/null +++ b/src/inventory/PlayerEnderInventory.php @@ -0,0 +1,38 @@ +holder = $holder; + parent::__construct($size); + } + + public function getHolder() : Human{ return $this->holder; } +} diff --git a/tests/phpstan/configs/gc-hacks.neon b/tests/phpstan/configs/gc-hacks.neon index df50eb02a6..e14be2fae5 100644 --- a/tests/phpstan/configs/gc-hacks.neon +++ b/tests/phpstan/configs/gc-hacks.neon @@ -36,7 +36,7 @@ parameters: path: ../../../src/entity/Entity.php - - message: "#^Property pocketmine\\\\entity\\\\Human\\:\\:\\$enderChestInventory \\(pocketmine\\\\block\\\\inventory\\\\EnderChestInventory\\) does not accept null\\.$#" + message: "#^Property pocketmine\\\\entity\\\\Human\\:\\:\\$enderInventory \\(pocketmine\\\\inventory\\\\PlayerEnderInventory\\) does not accept null\\.$#" count: 1 path: ../../../src/entity/Human.php From 176ca3fd2ff9e926b269f699fda44b19ff558779 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 2 May 2021 14:56:56 +0100 Subject: [PATCH 2443/3224] shut --- src/entity/Human.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/entity/Human.php b/src/entity/Human.php index 30f12b5a67..8362671b98 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\entity; -use pocketmine\block\inventory\EnderChestInventory; use pocketmine\entity\animation\TotemUseAnimation; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\VanillaEffects; From 267b49247eca105853a9c0abc7c13ef26e9a6160 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 4 May 2021 22:27:34 +0100 Subject: [PATCH 2444/3224] Updated composer deps (except pocketmine/nbt) --- composer.json | 2 +- composer.lock | 59 ++++++++++++++++++++++++++------------------------- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/composer.json b/composer.json index b344cf242c..ee45b2a7f2 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,7 @@ "pocketmine/callback-validator": "^1.0.2", "pocketmine/classloader": "dev-master", "pocketmine/color": "^0.2.0", - "pocketmine/errorhandler": "^0.2.0", + "pocketmine/errorhandler": "^0.3.0", "pocketmine/log": "dev-master", "pocketmine/log-pthreads": "dev-master", "pocketmine/math": "dev-master", diff --git a/composer.lock b/composer.lock index 7cfc266562..0187525475 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "13e4c2cba14b415edf7c6ba4132211b6", + "content-hash": "74d082e62d264fb0579bf4da87ab6eaf", "packages": [ { "name": "adhocore/json-comment", @@ -119,16 +119,16 @@ }, { "name": "fgrosse/phpasn1", - "version": "v2.2.0", + "version": "v2.3.0", "source": { "type": "git", "url": "https://github.com/fgrosse/PHPASN1.git", - "reference": "d1978f7abd580f3fc33561e7f71d4c12c7531fad" + "reference": "20299033c35f4300eb656e7e8e88cf52d1d6694e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/d1978f7abd580f3fc33561e7f71d4c12c7531fad", - "reference": "d1978f7abd580f3fc33561e7f71d4c12c7531fad", + "url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/20299033c35f4300eb656e7e8e88cf52d1d6694e", + "reference": "20299033c35f4300eb656e7e8e88cf52d1d6694e", "shasum": "" }, "require": { @@ -188,9 +188,9 @@ ], "support": { "issues": "https://github.com/fgrosse/PHPASN1/issues", - "source": "https://github.com/fgrosse/PHPASN1/tree/v2.2.0" + "source": "https://github.com/fgrosse/PHPASN1/tree/v2.3.0" }, - "time": "2020-10-11T16:28:18+00:00" + "time": "2021-04-24T19:01:55+00:00" }, { "name": "mdanter/ecc", @@ -415,12 +415,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/ClassLoader.git", - "reference": "9fb3957cbfe5b37dae8952e072b35540fb4d9aa7" + "reference": "ba70cbabc53d6a36c5d179776e99bc059f21b4a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/9fb3957cbfe5b37dae8952e072b35540fb4d9aa7", - "reference": "9fb3957cbfe5b37dae8952e072b35540fb4d9aa7", + "url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/ba70cbabc53d6a36c5d179776e99bc059f21b4a9", + "reference": "ba70cbabc53d6a36c5d179776e99bc059f21b4a9", "shasum": "" }, "require": { @@ -434,7 +434,8 @@ "require-dev": { "phpstan/extension-installer": "^1.0", "phpstan/phpstan": "0.12.80", - "phpstan/phpstan-strict-rules": "^0.12.4" + "phpstan/phpstan-strict-rules": "^0.12.4", + "phpunit/phpunit": "^8.5 || ^9.5" }, "type": "library", "autoload": { @@ -451,7 +452,7 @@ "issues": "https://github.com/pmmp/ClassLoader/issues", "source": "https://github.com/pmmp/ClassLoader/tree/master" }, - "time": "2021-04-19T14:36:23+00:00" + "time": "2021-04-21T22:05:17+00:00" }, { "name": "pocketmine/color", @@ -493,23 +494,23 @@ }, { "name": "pocketmine/errorhandler", - "version": "0.2.0", + "version": "0.3.0", "source": { "type": "git", "url": "https://github.com/pmmp/ErrorHandler.git", - "reference": "567fa056335efc295c4592c8aad72de66a2fcf34" + "reference": "ec742b209e8056bbe855069c4eff94c9734ea19b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/ErrorHandler/zipball/567fa056335efc295c4592c8aad72de66a2fcf34", - "reference": "567fa056335efc295c4592c8aad72de66a2fcf34", + "url": "https://api.github.com/repos/pmmp/ErrorHandler/zipball/ec742b209e8056bbe855069c4eff94c9734ea19b", + "reference": "ec742b209e8056bbe855069c4eff94c9734ea19b", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "0.12.59", + "phpstan/phpstan": "0.12.75", "phpstan/phpstan-strict-rules": "^0.12.2" }, "type": "library", @@ -525,9 +526,9 @@ "description": "Utilities to handle nasty PHP E_* errors in a usable way", "support": { "issues": "https://github.com/pmmp/ErrorHandler/issues", - "source": "https://github.com/pmmp/ErrorHandler/tree/0.2.0" + "source": "https://github.com/pmmp/ErrorHandler/tree/0.3.0" }, - "time": "2020-12-11T01:06:33+00:00" + "time": "2021-02-12T18:56:22+00:00" }, { "name": "pocketmine/log", @@ -703,12 +704,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "bd8b75396e4585116838435839f7ccd51862663d" + "reference": "d7f30d8c7fb972ec6314c94292252996eef13a16" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/bd8b75396e4585116838435839f7ccd51862663d", - "reference": "bd8b75396e4585116838435839f7ccd51862663d", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/d7f30d8c7fb972ec6314c94292252996eef13a16", + "reference": "d7f30d8c7fb972ec6314c94292252996eef13a16", "shasum": "" }, "require": { @@ -738,7 +739,7 @@ "issues": "https://github.com/pmmp/RakLib/issues", "source": "https://github.com/pmmp/RakLib/tree/master" }, - "time": "2021-04-08T14:24:31+00:00" + "time": "2021-04-29T00:20:58+00:00" }, { "name": "pocketmine/snooze", @@ -1400,16 +1401,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.10.4", + "version": "v4.10.5", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e" + "reference": "4432ba399e47c66624bc73c8c0f811e5c109576f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c6d052fc58cb876152f89f532b95a8d7907e7f0e", - "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4432ba399e47c66624bc73c8c0f811e5c109576f", + "reference": "4432ba399e47c66624bc73c8c0f811e5c109576f", "shasum": "" }, "require": { @@ -1450,9 +1451,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.10.4" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.10.5" }, - "time": "2020-12-20T10:01:03+00:00" + "time": "2021-05-03T19:11:20+00:00" }, { "name": "phar-io/manifest", From e8cb49f7aed207d6dc2eca5886a8ca6542974691 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 May 2021 11:25:11 +0100 Subject: [PATCH 2445/3224] php-cs-fixer fixing php-cs-fixer's own mess --- tests/phpstan/bootstrap.php | 8 ++++---- tests/phpunit/block/regenerate_consistency_check.php | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/phpstan/bootstrap.php b/tests/phpstan/bootstrap.php index d6cbdd166a..ba8ccd3fc4 100644 --- a/tests/phpstan/bootstrap.php +++ b/tests/phpstan/bootstrap.php @@ -21,13 +21,13 @@ declare(strict_types=1); -if(!\defined('LEVELDB_ZLIB_RAW_COMPRESSION')){ +if(!defined('LEVELDB_ZLIB_RAW_COMPRESSION')){ //leveldb might not be loaded - \define('LEVELDB_ZLIB_RAW_COMPRESSION', 4); + define('LEVELDB_ZLIB_RAW_COMPRESSION', 4); } -if(!\extension_loaded('libdeflate')){ +if(!extension_loaded('libdeflate')){ function libdeflate_deflate_compress(string $data, int $level = 6) : string{} } //TODO: these need to be defined properly or removed -\define('pocketmine\COMPOSER_AUTOLOADER_PATH', \dirname(__DIR__, 2) . '/vendor/autoload.php'); +define('pocketmine\COMPOSER_AUTOLOADER_PATH', dirname(__DIR__, 2) . '/vendor/autoload.php'); diff --git a/tests/phpunit/block/regenerate_consistency_check.php b/tests/phpunit/block/regenerate_consistency_check.php index d1ff6c770f..aac5194c9c 100644 --- a/tests/phpunit/block/regenerate_consistency_check.php +++ b/tests/phpunit/block/regenerate_consistency_check.php @@ -21,14 +21,14 @@ declare(strict_types=1); -require \dirname(__DIR__, 3) . '/vendor/autoload.php'; +require dirname(__DIR__, 3) . '/vendor/autoload.php'; /* This script needs to be re-run after any intentional blockfactory change (adding or removing a block state). */ $factory = new \pocketmine\block\BlockFactory(); -$old = \json_decode(\file_get_contents(__DIR__ . '/block_factory_consistency_check.json'), true); -$new = \array_map( +$old = json_decode(file_get_contents(__DIR__ . '/block_factory_consistency_check.json'), true); +$new = array_map( function(\pocketmine\block\Block $block) : string{ return $block->getName(); }, @@ -46,6 +46,6 @@ foreach($new as $k => $name){ echo "Name changed (" . ($k >> 4) . ":" . ($k & 0xf) . "): " . $old[$k] . " -> " . $name . "\n"; } } -\file_put_contents(__DIR__ . '/block_factory_consistency_check.json', \json_encode( +file_put_contents(__DIR__ . '/block_factory_consistency_check.json', json_encode( $new )); From 652de2632a9ddbb4df74fb449e395cba08f09ad8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 May 2021 14:46:51 +0100 Subject: [PATCH 2446/3224] Rough OffHand implementation this doesn't do stuff like taking arrows from offhand yet. --- src/entity/Entity.php | 1 + src/entity/ExperienceManager.php | 7 +++- src/entity/Human.php | 35 +++++++++++++++-- src/inventory/PlayerOffhandInventory.php | 38 +++++++++++++++++++ src/network/mcpe/InventoryManager.php | 1 + src/network/mcpe/NetworkSession.php | 8 +++- .../mcpe/handler/InGamePacketHandler.php | 14 +++++-- src/player/Player.php | 3 ++ tests/phpstan/configs/gc-hacks.neon | 5 +++ 9 files changed, 101 insertions(+), 11 deletions(-) create mode 100644 src/inventory/PlayerOffhandInventory.php diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 4a7a4df778..900ebc6d3c 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1599,6 +1599,7 @@ abstract class Entity{ $properties->setLong(EntityMetadataProperties::TARGET_EID, $this->targetId ?? 0); $properties->setString(EntityMetadataProperties::NAMETAG, $this->nameTag); $properties->setString(EntityMetadataProperties::SCORE_TAG, $this->scoreTag); + $properties->setByte(EntityMetadataProperties::COLOR, 0); $properties->setGenericFlag(EntityMetadataFlags::AFFECTED_BY_GRAVITY, true); $properties->setGenericFlag(EntityMetadataFlags::CAN_CLIMB, $this->canClimb); diff --git a/src/entity/ExperienceManager.php b/src/entity/ExperienceManager.php index 4571877456..7f4d46511d 100644 --- a/src/entity/ExperienceManager.php +++ b/src/entity/ExperienceManager.php @@ -239,6 +239,7 @@ class ExperienceManager{ public function onPickupXp(int $xpValue) : void{ static $mainHandIndex = -1; + static $offHandIndex = -2; //TODO: replace this with a more generic equipment getting/setting interface /** @var Durable[] $equipment */ @@ -247,7 +248,9 @@ class ExperienceManager{ if(($item = $this->entity->getInventory()->getItemInHand()) instanceof Durable and $item->hasEnchantment(VanillaEnchantments::MENDING())){ $equipment[$mainHandIndex] = $item; } - //TODO: check offhand + if(($item = $this->entity->getOffHandInventory()->getItem(0)) instanceof Durable and $item->hasEnchantment(VanillaEnchantments::MENDING())){ + $equipment[$offHandIndex] = $item; + } foreach($this->entity->getArmorInventory()->getContents() as $k => $armorItem){ if($armorItem instanceof Durable and $armorItem->hasEnchantment(VanillaEnchantments::MENDING())){ $equipment[$k] = $armorItem; @@ -263,6 +266,8 @@ class ExperienceManager{ if($k === $mainHandIndex){ $this->entity->getInventory()->setItemInHand($repairItem); + }elseif($k === $offHandIndex){ + $this->entity->getOffHandInventory()->setItem(0, $repairItem); }else{ $this->entity->getArmorInventory()->setItem($k, $repairItem); } diff --git a/src/entity/Human.php b/src/entity/Human.php index 8362671b98..75ac5c056b 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -34,6 +34,7 @@ use pocketmine\inventory\Inventory; use pocketmine\inventory\InventoryHolder; use pocketmine\inventory\PlayerEnderInventory; use pocketmine\inventory\PlayerInventory; +use pocketmine\inventory\PlayerOffHandInventory; use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\item\Item; use pocketmine\item\Totem; @@ -73,6 +74,9 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ /** @var PlayerInventory */ protected $inventory; + /** @var PlayerOffHandInventory */ + protected $offHandInventory; + /** @var PlayerEnderInventory */ protected $enderInventory; @@ -193,6 +197,8 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ return $this->inventory; } + public function getOffHandInventory() : PlayerOffHandInventory{ return $this->offHandInventory; } + public function getEnderInventory() : PlayerEnderInventory{ return $this->enderInventory; } @@ -218,7 +224,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $this->inventory = new PlayerInventory($this); $syncHeldItem = function() : void{ foreach($this->getViewers() as $viewer){ - $viewer->getNetworkSession()->onMobEquipmentChange($this); + $viewer->getNetworkSession()->onMobMainHandItemChange($this); } }; $this->inventory->getListeners()->add(new CallbackInventoryListener( @@ -233,6 +239,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ } } )); + $this->offHandInventory = new PlayerOffHandInventory($this); $this->enderInventory = new PlayerEnderInventory($this); $this->initHumanData($nbt); @@ -258,6 +265,15 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $this->armorInventory->getListeners()->add(...$armorListeners); $this->inventory->getListeners()->add(...$inventoryListeners); } + $offHand = $nbt->getCompoundTag("OffHandItem"); + if($offHand !== null){ + $this->offHandInventory->setItem(0, Item::nbtDeserialize($offHand)); + } + $this->offHandInventory->getListeners()->add(CallbackInventoryListener::onAnyChange(function() : void{ + foreach($this->getViewers() as $viewer){ + $viewer->getNetworkSession()->onMobOffHandItemChange($this); + } + })); $enderChestInventoryTag = $nbt->getListTag("EnderChestInventory"); if($enderChestInventoryTag !== null){ @@ -270,7 +286,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $this->inventory->setHeldItemIndex($nbt->getInt("SelectedInventorySlot", 0)); $this->inventory->getHeldItemIndexChangeListeners()->add(function(int $oldIndex) : void{ foreach($this->getViewers() as $viewer){ - $viewer->getNetworkSession()->onMobEquipmentChange($this); + $viewer->getNetworkSession()->onMobMainHandItemChange($this); } }); @@ -309,7 +325,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $type = $source->getCause(); if($type !== EntityDamageEvent::CAUSE_SUICIDE and $type !== EntityDamageEvent::CAUSE_VOID - and $this->inventory->getItemInHand() instanceof Totem){ //TODO: check offhand as well (when it's implemented) + and ($this->inventory->getItemInHand() instanceof Totem || $this->offHandInventory->getItem(0) instanceof Totem)){ $compensation = $this->getHealth() - $source->getFinalDamage() - 1; if($compensation < 0){ @@ -335,6 +351,9 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ if($hand instanceof Totem){ $hand->pop(); //Plugins could alter max stack size $this->inventory->setItemInHand($hand); + }elseif(($offHand = $this->offHandInventory->getItem(0)) instanceof Totem){ + $offHand->pop(); + $this->offHandInventory->setItem(0, $offHand); } } } @@ -342,7 +361,8 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ public function getDrops() : array{ return array_filter(array_merge( $this->inventory !== null ? array_values($this->inventory->getContents()) : [], - $this->armorInventory !== null ? array_values($this->armorInventory->getContents()) : [] + $this->armorInventory !== null ? array_values($this->armorInventory->getContents()) : [], + $this->offHandInventory !== null ? array_values($this->offHandInventory->getContents()) : [], ), function(Item $item) : bool{ return !$item->hasEnchantment(VanillaEnchantments::VANISHING()); }); } @@ -381,6 +401,10 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $nbt->setInt("SelectedInventorySlot", $this->inventory->getHeldItemIndex()); } + $offHandItem = $this->offHandInventory->getItem(0); + if(!$offHandItem->isNull()){ + $nbt->setTag("OffHandItem", $offHandItem->nbtSerialize()); + } if($this->enderInventory !== null){ /** @var CompoundTag[] $items */ @@ -437,6 +461,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $this->sendData([$player], [EntityMetadataProperties::NAMETAG => new StringMetadataProperty($this->getNameTag())]); $player->getNetworkSession()->onMobArmorChange($this); + $player->getNetworkSession()->onMobOffHandItemChange($this); if(!($this instanceof Player)){ $player->getNetworkSession()->sendDataPacket(PlayerListPacket::remove([PlayerListEntry::createRemovalEntry($this->uuid)])); @@ -466,12 +491,14 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ protected function onDispose() : void{ $this->inventory->removeAllViewers(); $this->inventory->getHeldItemIndexChangeListeners()->clear(); + $this->offHandInventory->removeAllViewers(); $this->enderInventory->removeAllViewers(); parent::onDispose(); } protected function destroyCycles() : void{ $this->inventory = null; + $this->offHandInventory = null; $this->enderInventory = null; $this->hungerManager = null; $this->xpManager = null; diff --git a/src/inventory/PlayerOffhandInventory.php b/src/inventory/PlayerOffhandInventory.php new file mode 100644 index 0000000000..89354ffcf9 --- /dev/null +++ b/src/inventory/PlayerOffhandInventory.php @@ -0,0 +1,38 @@ +holder = $player; + parent::__construct(1); + } + + public function getHolder() : Human{ return $this->holder; } +} diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index d28e34abca..e162687b63 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -96,6 +96,7 @@ class InventoryManager{ $this->containerOpenCallbacks->add(\Closure::fromCallable([self::class, 'createContainerOpen'])); $this->add(ContainerIds::INVENTORY, $this->player->getInventory()); + $this->add(ContainerIds::OFFHAND, $this->player->getOffHandInventory()); $this->add(ContainerIds::ARMOR, $this->player->getArmorInventory()); $this->add(ContainerIds::UI, $this->player->getCursorInventory()); diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index ba0df464b6..88a9307a6d 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -963,14 +963,18 @@ class NetworkSession{ /** * TODO: expand this to more than just humans - * TODO: offhand */ - public function onMobEquipmentChange(Human $mob) : void{ + public function onMobMainHandItemChange(Human $mob) : void{ //TODO: we could send zero for slot here because remote players don't need to know which slot was selected $inv = $mob->getInventory(); $this->sendDataPacket(MobEquipmentPacket::create($mob->getId(), ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($inv->getItemInHand())), $inv->getHeldItemIndex(), ContainerIds::INVENTORY)); } + public function onMobOffHandItemChange(Human $mob) : void{ + $inv = $mob->getOffHandInventory(); + $this->sendDataPacket(MobEquipmentPacket::create($mob->getId(), ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($inv->getItem(0))), 0, ContainerIds::OFFHAND)); + } + public function onMobArmorChange(Living $mob) : void{ $inv = $mob->getArmorInventory(); $converter = TypeConverter::getInstance(); diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index c499258d21..376fa53617 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -463,11 +463,17 @@ class InGamePacketHandler extends PacketHandler{ } public function handleMobEquipment(MobEquipmentPacket $packet) : bool{ - $this->session->getInvManager()->onClientSelectHotbarSlot($packet->hotbarSlot); - if(!$this->player->selectHotbarSlot($packet->hotbarSlot)){ - $this->session->getInvManager()->syncSelectedHotbarSlot(); + if($packet->windowId === ContainerIds::OFFHAND){ + return true; //this happens when we put an item into the offhand } - return true; + if($packet->windowId === ContainerIds::INVENTORY){ + $this->session->getInvManager()->onClientSelectHotbarSlot($packet->hotbarSlot); + if(!$this->player->selectHotbarSlot($packet->hotbarSlot)){ + $this->session->getInvManager()->syncSelectedHotbarSlot(); + } + return true; + } + return false; } public function handleMobArmorEquipment(MobArmorEquipmentPacket $packet) : bool{ diff --git a/src/player/Player.php b/src/player/Player.php index 240e7f0bcc..4b1556d721 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2103,6 +2103,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ if($this->armorInventory !== null){ $this->armorInventory->clearAll(); } + if($this->offHandInventory !== null){ + $this->offHandInventory->clearAll(); + } } $this->getWorld()->dropExperience($this->location, $ev->getXpDropAmount()); diff --git a/tests/phpstan/configs/gc-hacks.neon b/tests/phpstan/configs/gc-hacks.neon index e14be2fae5..357f0d73d6 100644 --- a/tests/phpstan/configs/gc-hacks.neon +++ b/tests/phpstan/configs/gc-hacks.neon @@ -50,6 +50,11 @@ parameters: count: 1 path: ../../../src/entity/Human.php + - + message: "#^Property pocketmine\\\\entity\\\\Human\\:\\:\\$offHandInventory \\(pocketmine\\\\inventory\\\\PlayerOffHandInventory\\) does not accept null\\.$#" + count: 1 + path: ../../../src/entity/Human.php + - message: "#^Property pocketmine\\\\entity\\\\Human\\:\\:\\$xpManager \\(pocketmine\\\\entity\\\\ExperienceManager\\) does not accept null\\.$#" count: 1 From 73420819f63121237d9d500c17e51f7236447fab Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 May 2021 14:51:39 +0100 Subject: [PATCH 2447/3224] Clean PHPStan baselines --- tests/phpstan/configs/actual-problems.neon | 5 --- tests/phpstan/configs/gc-hacks.neon | 5 --- tests/phpstan/configs/phpstan-bugs.neon | 7 +--- .../phpstan/configs/runtime-type-checks.neon | 42 +------------------ 4 files changed, 2 insertions(+), 57 deletions(-) diff --git a/tests/phpstan/configs/actual-problems.neon b/tests/phpstan/configs/actual-problems.neon index 82e6be24d3..21c05e8af9 100644 --- a/tests/phpstan/configs/actual-problems.neon +++ b/tests/phpstan/configs/actual-problems.neon @@ -30,11 +30,6 @@ parameters: count: 1 path: ../../../src/Server.php - - - message: "#^pocketmine\\\\block\\\\inventory\\\\DoubleChestInventory\\:\\:__construct\\(\\) does not call parent constructor from pocketmine\\\\block\\\\inventory\\\\ChestInventory\\.$#" - count: 1 - path: ../../../src/block/inventory/DoubleChestInventory.php - - message: "#^Property pocketmine\\\\event\\\\entity\\\\EntityShootBowEvent\\:\\:\\$projectile \\(pocketmine\\\\entity\\\\projectile\\\\Projectile\\) does not accept pocketmine\\\\entity\\\\Entity\\.$#" count: 1 diff --git a/tests/phpstan/configs/gc-hacks.neon b/tests/phpstan/configs/gc-hacks.neon index 357f0d73d6..adf69ad5db 100644 --- a/tests/phpstan/configs/gc-hacks.neon +++ b/tests/phpstan/configs/gc-hacks.neon @@ -80,11 +80,6 @@ parameters: count: 1 path: ../../../src/player/Player.php - - - message: "#^Property pocketmine\\\\player\\\\Player\\:\\:\\$perm \\(pocketmine\\\\permission\\\\PermissibleBase\\) does not accept null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - message: "#^Property pocketmine\\\\world\\\\World\\:\\:\\$provider \\(pocketmine\\\\world\\\\format\\\\io\\\\WritableWorldProvider\\) does not accept null\\.$#" count: 1 diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 4828b333be..a5f9c1b6b9 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -1,13 +1,8 @@ parameters: ignoreErrors: - - - message: "#^Strict comparison using \\!\\=\\= between 5 and 5 will always evaluate to false\\.$#" - count: 1 - path: ../../../src/block/Vine.php - - message: "#^Call to function is_resource\\(\\) with resource will always evaluate to true\\.$#" - count: 3 + count: 2 path: ../../../src/command/CommandReader.php - diff --git a/tests/phpstan/configs/runtime-type-checks.neon b/tests/phpstan/configs/runtime-type-checks.neon index 0c60ba55b1..12e59f585a 100644 --- a/tests/phpstan/configs/runtime-type-checks.neon +++ b/tests/phpstan/configs/runtime-type-checks.neon @@ -1,18 +1,8 @@ parameters: ignoreErrors: - - - message: "#^Instanceof between pocketmine\\\\event\\\\RegisteredListener and pocketmine\\\\event\\\\RegisteredListener will always evaluate to true\\.$#" - count: 1 - path: ../../../src/event/HandlerList.php - - - - message: "#^Call to function is_string\\(\\) with string will always evaluate to true\\.$#" - count: 1 - path: ../../../src/item/Item.php - - message: "#^Casting to int something that's already int\\.$#" - count: 3 + count: 2 path: ../../../src/item/Item.php - @@ -25,33 +15,3 @@ parameters: count: 1 path: ../../../src/plugin/PluginBase.php - - - message: "#^Call to function is_subclass_of\\(\\) with class\\-string\\ and 'pocketmine\\\\\\\\event\\\\\\\\Event' will always evaluate to true\\.$#" - count: 1 - path: ../../../src/plugin/PluginManager.php - - - - message: "#^If condition is always true\\.$#" - count: 2 - path: ../../../src/thread/ThreadManager.php - - - - message: "#^Instanceof between pocketmine\\\\thread\\\\Worker and pocketmine\\\\thread\\\\Worker will always evaluate to true\\.$#" - count: 2 - path: ../../../src/thread/ThreadManager.php - - - - message: "#^Call to function is_object\\(\\) with \\*NEVER\\* will always evaluate to true\\.$#" - count: 1 - path: ../../../src/world/World.php - - - - message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#" - count: 1 - path: ../../../src/world/World.php - - - - message: "#^Instanceof between pocketmine\\\\math\\\\Vector3 and pocketmine\\\\math\\\\Vector3 will always evaluate to true\\.$#" - count: 1 - path: ../../../src/world/World.php - From cc73571307ccf3c457fa52e777050b82cf51e40b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 May 2021 19:43:39 +0100 Subject: [PATCH 2448/3224] Updated composer dependencies --- composer.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.lock b/composer.lock index 83adc0a697..81b6991395 100644 --- a/composer.lock +++ b/composer.lock @@ -662,12 +662,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "59f3c8cd49d4b6a028e4f8176c55e800948ebded" + "reference": "34bc0cb2f0cc9553ca1a34c5d9d008f914959dd8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/59f3c8cd49d4b6a028e4f8176c55e800948ebded", - "reference": "59f3c8cd49d4b6a028e4f8176c55e800948ebded", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/34bc0cb2f0cc9553ca1a34c5d9d008f914959dd8", + "reference": "34bc0cb2f0cc9553ca1a34c5d9d008f914959dd8", "shasum": "" }, "require": { @@ -678,7 +678,7 @@ "require-dev": { "irstea/phpunit-shim": "^7.5 || ^8.0", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "0.12.80", + "phpstan/phpstan": "0.12.85", "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", @@ -696,7 +696,7 @@ "issues": "https://github.com/pmmp/NBT/issues", "source": "https://github.com/pmmp/NBT/tree/master" }, - "time": "2021-04-12T22:54:46+00:00" + "time": "2021-05-05T18:39:10+00:00" }, { "name": "pocketmine/raklib", From 17bbb9330f4dcbc3fec17e8540886ddfa4cfed6a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 May 2021 21:31:48 +0100 Subject: [PATCH 2449/3224] Updated RakLib, require pocketmine/raklib-ipc --- composer.json | 1 + composer.lock | 57 ++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 096638c97a..6717f395ee 100644 --- a/composer.json +++ b/composer.json @@ -44,6 +44,7 @@ "pocketmine/math": "dev-master", "pocketmine/nbt": "dev-master", "pocketmine/raklib": "dev-master", + "pocketmine/raklib-ipc": "dev-master", "pocketmine/snooze": "^0.1.0", "pocketmine/spl": "dev-master", "ramsey/uuid": "^4.1", diff --git a/composer.lock b/composer.lock index 81b6991395..c0a7aeb81f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6bd8f2ec899a5899fb8196fbd0fff82f", + "content-hash": "91de5b8e3d1e1f64970c03e059a27f8a", "packages": [ { "name": "adhocore/json-comment", @@ -704,24 +704,24 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "d7f30d8c7fb972ec6314c94292252996eef13a16" + "reference": "9d6f564e2843535a0ec621f7396b8b0292506cf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/d7f30d8c7fb972ec6314c94292252996eef13a16", - "reference": "d7f30d8c7fb972ec6314c94292252996eef13a16", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/9d6f564e2843535a0ec621f7396b8b0292506cf8", + "reference": "9d6f564e2843535a0ec621f7396b8b0292506cf8", "shasum": "" }, "require": { "ext-sockets": "*", - "php": "^7.2 || ^8.0", + "php": "^7.4 || ^8.0", "php-64bit": "*", "php-ipv6": "*", "pocketmine/binaryutils": "dev-master", "pocketmine/log": "dev-master" }, "require-dev": { - "phpstan/phpstan": "0.12.81", + "phpstan/phpstan": "0.12.85", "phpstan/phpstan-strict-rules": "^0.12.2" }, "type": "library", @@ -739,7 +739,49 @@ "issues": "https://github.com/pmmp/RakLib/issues", "source": "https://github.com/pmmp/RakLib/tree/master" }, - "time": "2021-04-29T00:20:58+00:00" + "time": "2021-05-05T19:32:05+00:00" + }, + { + "name": "pocketmine/raklib-ipc", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/pmmp/RakLibIpc.git", + "reference": "7fbf66e0f4e31469f42c4b4ff00c24bfbf2bac62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pmmp/RakLibIpc/zipball/7fbf66e0f4e31469f42c4b4ff00c24bfbf2bac62", + "reference": "7fbf66e0f4e31469f42c4b4ff00c24bfbf2bac62", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "php-64bit": "*", + "pocketmine/binaryutils": "dev-master", + "pocketmine/raklib": "dev-master" + }, + "require-dev": { + "phpstan/phpstan": "0.12.81", + "phpstan/phpstan-strict-rules": "^0.12.2" + }, + "default-branch": true, + "type": "library", + "autoload": { + "psr-4": { + "raklib\\server\\ipc\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0" + ], + "description": "Channel-based protocols for inter-thread/inter-process communication with RakLib", + "support": { + "issues": "https://github.com/pmmp/RakLibIpc/issues", + "source": "https://github.com/pmmp/RakLibIpc/tree/master" + }, + "time": "2021-05-05T19:37:07+00:00" }, { "name": "pocketmine/snooze", @@ -3461,6 +3503,7 @@ "pocketmine/math": 20, "pocketmine/nbt": 20, "pocketmine/raklib": 20, + "pocketmine/raklib-ipc": 20, "pocketmine/spl": 20 }, "prefer-stable": false, From 01794adef1df8017a13faf9d70732612bcbd3c29 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 5 May 2021 22:24:23 +0100 Subject: [PATCH 2450/3224] ... --- .../{PlayerOffhandInventory.php => PlayerOffHandInventory.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/inventory/{PlayerOffhandInventory.php => PlayerOffHandInventory.php} (100%) diff --git a/src/inventory/PlayerOffhandInventory.php b/src/inventory/PlayerOffHandInventory.php similarity index 100% rename from src/inventory/PlayerOffhandInventory.php rename to src/inventory/PlayerOffHandInventory.php From c356abb917bcbd8a620797835b3e1ddc0803d476 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 May 2021 14:27:08 +0100 Subject: [PATCH 2451/3224] BlockTransaction: remove cyclic reference to self in callbacks --- src/world/BlockTransaction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/BlockTransaction.php b/src/world/BlockTransaction.php index 1c26166ebe..f30d761f3d 100644 --- a/src/world/BlockTransaction.php +++ b/src/world/BlockTransaction.php @@ -42,7 +42,7 @@ class BlockTransaction{ public function __construct(ChunkManager $world){ $this->world = $world; - $this->addValidator(function(ChunkManager $world, int $x, int $y, int $z) : bool{ + $this->addValidator(static function(ChunkManager $world, int $x, int $y, int $z) : bool{ return $world->isInWorld($x, $y, $z); }); } From 7b2c6c5cebef4ef6c111cd7860ea36480e1d7148 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 May 2021 14:27:56 +0100 Subject: [PATCH 2452/3224] Avoid more $this refs on long-life closures --- src/block/tile/BrewingStand.php | 4 ++-- src/block/tile/Furnace.php | 4 ++-- src/crafting/CraftingManager.php | 6 ++++-- src/world/World.php | 5 +++-- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/block/tile/BrewingStand.php b/src/block/tile/BrewingStand.php index 8977d36b19..f10c47f79d 100644 --- a/src/block/tile/BrewingStand.php +++ b/src/block/tile/BrewingStand.php @@ -54,8 +54,8 @@ class BrewingStand extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); $this->inventory = new BrewingStandInventory($this->pos); - $this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange(function(Inventory $unused) : void{ - $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 1); + $this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange(static function(Inventory $unused) use ($world, $pos) : void{ + $world->scheduleDelayedBlockUpdate($pos, 1); })); } diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index bbe9b998b4..5f31c8dfbf 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -58,8 +58,8 @@ class Furnace extends Spawnable implements Container, Nameable{ parent::__construct($world, $pos); $this->inventory = new FurnaceInventory($this->pos); $this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange( - function(Inventory $unused) : void{ - $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 1); + static function(Inventory $unused) use ($world, $pos) : void{ + $world->scheduleDelayedBlockUpdate($pos, 1); }) ); } diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index 7094805063..50e1cc89a6 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -49,8 +49,10 @@ class CraftingManager{ public function __construct(){ $this->recipeRegisteredCallbacks = new ObjectSet(); $this->furnaceRecipeManager = new FurnaceRecipeManager(); - $this->furnaceRecipeManager->getRecipeRegisteredCallbacks()->add(function(FurnaceRecipe $recipe) : void{ - foreach($this->recipeRegisteredCallbacks as $callback){ + + $recipeRegisteredCallbacks = $this->recipeRegisteredCallbacks; + $this->furnaceRecipeManager->getRecipeRegisteredCallbacks()->add(static function(FurnaceRecipe $recipe) use ($recipeRegisteredCallbacks) : void{ + foreach($recipeRegisteredCallbacks as $callback){ $callback(); } }); diff --git a/src/world/World.php b/src/world/World.php index a0e6ad6d93..081eb1cdbc 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -447,8 +447,9 @@ class World implements ChunkManager{ unset($this->generatorRegisteredWorkers[$workerId]); } }); - $this->addOnUnloadCallback(function() use ($workerStartHook) : void{ - $this->workerPool->removeWorkerStartHook($workerStartHook); + $workerPool = $this->workerPool; + $this->addOnUnloadCallback(static function() use ($workerPool, $workerStartHook) : void{ + $workerPool->removeWorkerStartHook($workerStartHook); }); } From 7d1c4efdfb22751c23266daa143e64e0c97b4ac6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 May 2021 18:17:05 +0100 Subject: [PATCH 2453/3224] Updated composer dependencies --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index c0a7aeb81f..ad0dd501cf 100644 --- a/composer.lock +++ b/composer.lock @@ -747,12 +747,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLibIpc.git", - "reference": "7fbf66e0f4e31469f42c4b4ff00c24bfbf2bac62" + "reference": "cde9f0d0c0a742684ea44cbbc94e8aca97e693cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLibIpc/zipball/7fbf66e0f4e31469f42c4b4ff00c24bfbf2bac62", - "reference": "7fbf66e0f4e31469f42c4b4ff00c24bfbf2bac62", + "url": "https://api.github.com/repos/pmmp/RakLibIpc/zipball/cde9f0d0c0a742684ea44cbbc94e8aca97e693cc", + "reference": "cde9f0d0c0a742684ea44cbbc94e8aca97e693cc", "shasum": "" }, "require": { @@ -781,7 +781,7 @@ "issues": "https://github.com/pmmp/RakLibIpc/issues", "source": "https://github.com/pmmp/RakLibIpc/tree/master" }, - "time": "2021-05-05T19:37:07+00:00" + "time": "2021-05-05T20:36:08+00:00" }, { "name": "pocketmine/snooze", From 742f86e022e2ae8881f59bc9157b6219cf4d4499 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 May 2021 18:33:18 +0100 Subject: [PATCH 2454/3224] Rename DestroyBlockParticle -> BlockBreakParticle closes #3461 literally every other particle/sound has the subject first, followed by the (optional) verb, and finally Particle (or Sound). In addition, we refer to breaking blocks as 'break' everywhere except here, where we refer to it as 'destroy'. --- changelogs/4.0-snapshot.md | 1 + src/entity/object/Painting.php | 4 ++-- src/world/World.php | 4 ++-- .../{DestroyBlockParticle.php => BlockBreakParticle.php} | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) rename src/world/particle/{DestroyBlockParticle.php => BlockBreakParticle.php} (96%) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 9bab171cb1..86a39f10c7 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -956,6 +956,7 @@ This version features substantial changes to the network system, improving coher - `Location` has been moved to `pocketmine\entity\Location`. #### Particles +- `DestroyBlockParticle` has been renamed to `BlockBreakParticle` for consistency. - `DustParticle->__construct()` now accepts a `pocketmine\utils\Color` object instead of `r, g, b, a`. - `pocketmine\world\particle\Particle` no longer extends `pocketmine\math\Vector3`, and has been converted to an interface. - Added the following `Particle` classes: diff --git a/src/entity/object/Painting.php b/src/entity/object/Painting.php index ab34e7aee9..4769df15d2 100644 --- a/src/entity/object/Painting.php +++ b/src/entity/object/Painting.php @@ -36,7 +36,7 @@ use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\AddPaintingPacket; use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\player\Player; -use pocketmine\world\particle\DestroyBlockParticle; +use pocketmine\world\particle\BlockBreakParticle; use pocketmine\world\World; use function ceil; @@ -116,7 +116,7 @@ class Painting extends Entity{ //non-living entities don't have a way to create drops generically yet $this->getWorld()->dropItem($this->location, VanillaItems::PAINTING()); } - $this->getWorld()->addParticle($this->location->add(0.5, 0.5, 0.5), new DestroyBlockParticle(VanillaBlocks::OAK_PLANKS())); + $this->getWorld()->addParticle($this->location->add(0.5, 0.5, 0.5), new BlockBreakParticle(VanillaBlocks::OAK_PLANKS())); } protected function recalculateBoundingBox() : void{ diff --git a/src/world/World.php b/src/world/World.php index 081eb1cdbc..dd76efde02 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -82,7 +82,7 @@ use pocketmine\world\generator\PopulationTask; use pocketmine\world\light\BlockLightUpdate; use pocketmine\world\light\LightPopulationTask; use pocketmine\world\light\SkyLightUpdate; -use pocketmine\world\particle\DestroyBlockParticle; +use pocketmine\world\particle\BlockBreakParticle; use pocketmine\world\particle\Particle; use pocketmine\world\sound\BlockPlaceSound; use pocketmine\world\sound\Sound; @@ -1699,7 +1699,7 @@ class World implements ChunkManager{ private function destroyBlockInternal(Block $target, Item $item, ?Player $player = null, bool $createParticles = false) : void{ if($createParticles){ - $this->addParticle($target->getPos()->add(0.5, 0.5, 0.5), new DestroyBlockParticle($target)); + $this->addParticle($target->getPos()->add(0.5, 0.5, 0.5), new BlockBreakParticle($target)); } $target->onBreak($item, $player); diff --git a/src/world/particle/DestroyBlockParticle.php b/src/world/particle/BlockBreakParticle.php similarity index 96% rename from src/world/particle/DestroyBlockParticle.php rename to src/world/particle/BlockBreakParticle.php index aeda3f4849..bf3c235118 100644 --- a/src/world/particle/DestroyBlockParticle.php +++ b/src/world/particle/BlockBreakParticle.php @@ -28,7 +28,7 @@ use pocketmine\math\Vector3; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\LevelEventPacket; -class DestroyBlockParticle implements Particle{ +class BlockBreakParticle implements Particle{ /** @var Block */ private $block; From 6cb285d4a98baee5e906f92e93fb70eccbd4171e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 6 May 2021 18:40:14 +0100 Subject: [PATCH 2455/3224] Added constants for the handler tag types --- src/event/ListenerMethodTags.php | 34 ++++++++++++++++++++++++++++++++ src/plugin/PluginManager.php | 13 ++++++------ 2 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 src/event/ListenerMethodTags.php diff --git a/src/event/ListenerMethodTags.php b/src/event/ListenerMethodTags.php new file mode 100644 index 0000000000..ba72fc4cf5 --- /dev/null +++ b/src/event/ListenerMethodTags.php @@ -0,0 +1,34 @@ +getMethods(\ReflectionMethod::IS_PUBLIC) as $method){ if(!$method->isStatic() and $method->getDeclaringClass()->implementsInterface(Listener::class)){ $tags = Utils::parseDocComment((string) $method->getDocComment()); - if(isset($tags["notHandler"])){ + if(isset($tags[ListenerMethodTags::NOT_HANDLER])){ continue; } @@ -476,14 +477,14 @@ class PluginManager{ if($handlerClosure === null) throw new AssumptionFailedError("This should never happen"); try{ - $priority = isset($tags["priority"]) ? EventPriority::fromString($tags["priority"]) : EventPriority::NORMAL; + $priority = isset($tags[ListenerMethodTags::PRIORITY]) ? EventPriority::fromString($tags[ListenerMethodTags::PRIORITY]) : EventPriority::NORMAL; }catch(\InvalidArgumentException $e){ - throw new PluginException("Event handler " . Utils::getNiceClosureName($handlerClosure) . "() declares invalid/unknown priority \"" . $tags["priority"] . "\""); + throw new PluginException("Event handler " . Utils::getNiceClosureName($handlerClosure) . "() declares invalid/unknown priority \"" . $tags[ListenerMethodTags::PRIORITY] . "\""); } $handleCancelled = false; - if(isset($tags["handleCancelled"])){ - switch(strtolower($tags["handleCancelled"])){ + if(isset($tags[ListenerMethodTags::HANDLE_CANCELLED])){ + switch(strtolower($tags[ListenerMethodTags::HANDLE_CANCELLED])){ case "true": case "": $handleCancelled = true; @@ -491,7 +492,7 @@ class PluginManager{ case "false": break; default: - throw new PluginException("Event handler " . Utils::getNiceClosureName($handlerClosure) . "() declares invalid @handleCancelled value \"" . $tags["handleCancelled"] . "\""); + throw new PluginException("Event handler " . Utils::getNiceClosureName($handlerClosure) . "() declares invalid @" . ListenerMethodTags::HANDLE_CANCELLED . " value \"" . $tags[ListenerMethodTags::HANDLE_CANCELLED] . "\""); } } From f9bfc0df73a206e509ff7673d7f24819f782e8db Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 May 2021 22:47:06 +0100 Subject: [PATCH 2456/3224] NetworkSession: don't crash on teleporting to other world during PlayerLoginEvent --- src/network/mcpe/NetworkSession.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 88a9307a6d..498fdf6402 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -942,11 +942,13 @@ class NetworkSession{ } public function onEnterWorld() : void{ - $world = $this->player->getWorld(); - $this->syncWorldTime($world->getTime()); - $this->syncWorldDifficulty($world->getDifficulty()); - //TODO: weather needs to be synced here (when implemented) - //TODO: world spawn needs to be synced here + if($this->player !== null){ + $world = $this->player->getWorld(); + $this->syncWorldTime($world->getTime()); + $this->syncWorldDifficulty($world->getDifficulty()); + //TODO: weather needs to be synced here (when implemented) + //TODO: world spawn needs to be synced here + } } public function syncWorldTime(int $worldTime) : void{ From 998a5838153055bfb6c1457f22d6c578ed23826f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 May 2021 23:39:44 +0100 Subject: [PATCH 2457/3224] World: Fixed inverted completion callbacks for chunk population this would have caused any chunk populated by a plugin to remain loaded forever. --- src/world/World.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index dd76efde02..213b769d19 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2706,8 +2706,8 @@ class World implements ChunkManager{ $temporaryLoader = new class implements ChunkLoader{}; $this->registerChunkLoader($temporaryLoader, $chunkX, $chunkZ); $promise->onCompletion( - static function() : void{}, - fn() => $this->unregisterChunkLoader($temporaryLoader, $chunkX, $chunkZ) + fn() => $this->unregisterChunkLoader($temporaryLoader, $chunkX, $chunkZ), + static function() : void{} ); } return $promise; From 6384b6602c261f63eefaa5f5806a8c1135a0eed9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 7 May 2021 23:55:49 +0100 Subject: [PATCH 2458/3224] phpstorm you piece of shit --- tests/phpunit/item/BannerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/item/BannerTest.php b/tests/phpunit/item/BannerTest.php index 20b7154e77..1aafa82a21 100644 --- a/tests/phpunit/item/BannerTest.php +++ b/tests/phpunit/item/BannerTest.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\item; -use PHPStan\Testing\TestCase; +use PHPUnit\Framework\TestCase; use pocketmine\block\utils\BannerPatternLayer; use pocketmine\block\utils\BannerPatternType; use pocketmine\block\utils\DyeColor; From 33eb97da978b050a2d9c916a242c02911c1aec5a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 8 May 2021 15:53:55 +0100 Subject: [PATCH 2459/3224] Remove dead PHPStan pattern --- tests/phpstan/configs/l8-baseline.neon | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index b68a7df7a3..c47c76564e 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -105,11 +105,6 @@ parameters: count: 1 path: ../../../src/network/mcpe/NetworkSession.php - - - message: "#^Cannot call method getWorld\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" - count: 1 - path: ../../../src/network/mcpe/NetworkSession.php - - message: "#^Cannot call method sendData\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" count: 1 From 624495f4d387b6e1e84d1b1649f5aa83bf74ba44 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 8 May 2021 15:57:30 +0100 Subject: [PATCH 2460/3224] Added a generic Promise type I anticipate increasing demand for promises, and since all the libraries I could find suck, we'll stick to our own impl for now. --- src/Server.php | 9 ++- .../Promise.php} | 34 +++++++-- src/world/ChunkPopulationPromise.php | 76 ------------------- src/world/World.php | 28 ++++--- tests/phpstan/configs/phpstan-bugs.neon | 10 +++ 5 files changed, 60 insertions(+), 97 deletions(-) rename src/{player/PlayerCreationPromise.php => utils/Promise.php} (71%) delete mode 100644 src/world/ChunkPopulationPromise.php diff --git a/src/Server.php b/src/Server.php index b38111dd63..f3f1e4e6ad 100644 --- a/src/Server.php +++ b/src/Server.php @@ -70,7 +70,6 @@ use pocketmine\permission\DefaultPermissions; use pocketmine\player\GameMode; use pocketmine\player\OfflinePlayer; use pocketmine\player\Player; -use pocketmine\player\PlayerCreationPromise; use pocketmine\player\PlayerInfo; use pocketmine\plugin\PharPluginLoader; use pocketmine\plugin\Plugin; @@ -93,6 +92,7 @@ use pocketmine\utils\Filesystem; use pocketmine\utils\Internet; use pocketmine\utils\MainLogger; use pocketmine\utils\Process; +use pocketmine\utils\Promise; use pocketmine\utils\Terminal; use pocketmine\utils\TextFormat; use pocketmine\utils\Utils; @@ -580,7 +580,10 @@ class Server{ } } - public function createPlayer(NetworkSession $session, PlayerInfo $playerInfo, bool $authenticated, ?CompoundTag $offlinePlayerData) : PlayerCreationPromise{ + /** + * @phpstan-return Promise + */ + public function createPlayer(NetworkSession $session, PlayerInfo $playerInfo, bool $authenticated, ?CompoundTag $offlinePlayerData) : Promise{ $ev = new PlayerCreationEvent($session); $ev->call(); $class = $ev->getPlayerClass(); @@ -596,7 +599,7 @@ class Server{ $playerPos = null; $spawn = $world->getSpawnLocation(); } - $playerPromise = new PlayerCreationPromise(); + $playerPromise = new Promise(); $world->requestChunkPopulation($spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4, null)->onCompletion( function() use ($playerPromise, $class, $session, $playerInfo, $authenticated, $world, $playerPos, $spawn, $offlinePlayerData) : void{ if(!$session->isConnected()){ diff --git a/src/player/PlayerCreationPromise.php b/src/utils/Promise.php similarity index 71% rename from src/player/PlayerCreationPromise.php rename to src/utils/Promise.php index 1d43b7677a..4ccfc4bc56 100644 --- a/src/player/PlayerCreationPromise.php +++ b/src/utils/Promise.php @@ -21,14 +21,17 @@ declare(strict_types=1); -namespace pocketmine\player; +namespace pocketmine\utils; use function spl_object_id; -final class PlayerCreationPromise{ +/** + * @phpstan-template TValue + */ +final class Promise{ /** * @var \Closure[] - * @phpstan-var array + * @phpstan-var array */ private array $onSuccess = []; @@ -39,10 +42,15 @@ final class PlayerCreationPromise{ private array $onFailure = []; private bool $resolved = false; - private ?Player $result = null; /** - * @phpstan-param \Closure(Player) : void $onSuccess + * @var mixed + * @phpstan-var TValue|null + */ + private $result = null; + + /** + * @phpstan-param \Closure(TValue) : void $onSuccess * @phpstan-param \Closure() : void $onFailure */ public function onCompletion(\Closure $onSuccess, \Closure $onFailure) : void{ @@ -54,17 +62,27 @@ final class PlayerCreationPromise{ } } - public function resolve(Player $player) : void{ + /** + * @param mixed $value + * @phpstan-param TValue $value + */ + public function resolve($value) : void{ + if($this->resolved){ + throw new \InvalidStateException("Promise has already been resolved/rejected"); + } $this->resolved = true; - $this->result = $player; + $this->result = $value; foreach($this->onSuccess as $c){ - $c($player); + $c($value); } $this->onSuccess = []; $this->onFailure = []; } public function reject() : void{ + if($this->resolved){ + throw new \InvalidStateException("Promise has already been resolved/rejected"); + } $this->resolved = true; foreach($this->onFailure as $c){ $c(); diff --git a/src/world/ChunkPopulationPromise.php b/src/world/ChunkPopulationPromise.php deleted file mode 100644 index 4feee5f75e..0000000000 --- a/src/world/ChunkPopulationPromise.php +++ /dev/null @@ -1,76 +0,0 @@ - - */ - private array $onSuccess = []; - /** - * @var \Closure[] - * @phpstan-var array - */ - private array $onFailure = []; - - private ?bool $success = null; - - /** - * @phpstan-param \Closure() : void $onSuccess - * @phpstan-param \Closure() : void $onFailure - */ - public function onCompletion(\Closure $onSuccess, \Closure $onFailure) : void{ - if($this->success !== null){ - $this->success ? $onSuccess() : $onFailure(); - }else{ - $this->onSuccess[spl_object_id($onSuccess)] = $onSuccess; - $this->onFailure[spl_object_id($onFailure)] = $onFailure; - } - } - - public function resolve() : void{ - $this->success = true; - foreach($this->onSuccess as $callback){ - $callback(); - } - $this->onSuccess = []; - $this->onFailure = []; - } - - public function reject() : void{ - $this->success = false; - foreach($this->onFailure as $callback){ - $callback(); - } - $this->onSuccess = []; - $this->onFailure = []; - } - - public function isCompleted() : bool{ - return $this->success !== null; - } -} diff --git a/src/world/World.php b/src/world/World.php index 213b769d19..b27e30c8fc 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -68,6 +68,7 @@ use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Limits; +use pocketmine\utils\Promise; use pocketmine\utils\ReversePriorityQueue; use pocketmine\world\biome\Biome; use pocketmine\world\biome\BiomeRegistry; @@ -240,8 +241,8 @@ class World implements ChunkManager{ /** @var int */ private $maxConcurrentChunkPopulationTasks = 2; /** - * @var ChunkPopulationPromise[] chunkHash => promise - * @phpstan-var array + * @var Promise[] chunkHash => promise + * @phpstan-var array> */ private array $chunkPopulationRequestMap = []; /** @@ -2110,7 +2111,7 @@ class World implements ChunkManager{ } } unset($this->activeChunkPopulationTasks[$index]); - $this->chunkPopulationRequestMap[$index]->resolve(); + $this->chunkPopulationRequestMap[$index]->resolve($chunk); unset($this->chunkPopulationRequestMap[$index]); $this->drainPopulationRequestQueue(); @@ -2698,10 +2699,13 @@ class World implements ChunkManager{ } } - private function enqueuePopulationRequest(int $chunkX, int $chunkZ, ?ChunkLoader $associatedChunkLoader) : ChunkPopulationPromise{ + /** + * @phpstan-return Promise + */ + private function enqueuePopulationRequest(int $chunkX, int $chunkZ, ?ChunkLoader $associatedChunkLoader) : Promise{ $chunkHash = World::chunkHash($chunkX, $chunkZ); $this->chunkPopulationRequestQueue->enqueue($chunkHash); - $promise = $this->chunkPopulationRequestMap[$chunkHash] = new ChunkPopulationPromise(); + $promise = $this->chunkPopulationRequestMap[$chunkHash] = new Promise(); if($associatedChunkLoader === null){ $temporaryLoader = new class implements ChunkLoader{}; $this->registerChunkLoader($temporaryLoader, $chunkX, $chunkZ); @@ -2721,8 +2725,10 @@ class World implements ChunkManager{ * A ChunkLoader can be associated with the generation request to ensure that the generation request is cancelled if * no loaders are attached to the target chunk. If no loader is provided, one will be assigned (and automatically * removed when the generation request completes). + * + * @phpstan-return Promise */ - public function requestChunkPopulation(int $chunkX, int $chunkZ, ?ChunkLoader $associatedChunkLoader) : ChunkPopulationPromise{ + public function requestChunkPopulation(int $chunkX, int $chunkZ, ?ChunkLoader $associatedChunkLoader) : Promise{ $chunkHash = World::chunkHash($chunkX, $chunkZ); $promise = $this->chunkPopulationRequestMap[$chunkHash] ?? null; if($promise !== null && isset($this->activeChunkPopulationTasks[$chunkHash])){ @@ -2743,8 +2749,10 @@ class World implements ChunkManager{ * * If the chunk is currently locked (for example due to another chunk using it for async generation), the request * will be queued and executed at the earliest opportunity. + * + * @phpstan-return Promise */ - public function orderChunkPopulation(int $x, int $z, ?ChunkLoader $associatedChunkLoader) : ChunkPopulationPromise{ + public function orderChunkPopulation(int $x, int $z, ?ChunkLoader $associatedChunkLoader) : Promise{ $index = World::chunkHash($x, $z); $promise = $this->chunkPopulationRequestMap[$index] ?? null; if($promise !== null && isset($this->activeChunkPopulationTasks[$index])){ @@ -2766,7 +2774,7 @@ class World implements ChunkManager{ $this->activeChunkPopulationTasks[$index] = true; if($promise === null){ - $promise = new ChunkPopulationPromise(); + $promise = new Promise(); $this->chunkPopulationRequestMap[$index] = $promise; } @@ -2788,8 +2796,8 @@ class World implements ChunkManager{ } //chunk is already populated; return a pre-resolved promise that will directly fire callbacks assigned - $result = new ChunkPopulationPromise(); - $result->resolve(); + $result = new Promise(); + $result->resolve($chunk); return $result; } diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index a5f9c1b6b9..d4a7743530 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -20,6 +20,16 @@ parameters: count: 1 path: ../../../src/entity/projectile/Projectile.php + - + message: "#^Parameter \\#1 \\$ of closure expects TValue, TValue given\\.$#" + count: 2 + path: ../../../src/utils/Promise.php + + - + message: "#^Property pocketmine\\\\utils\\\\Promise\\\\:\\:\\$result \\(TValue\\|null\\) does not accept TValue\\.$#" + count: 1 + path: ../../../src/utils/Promise.php + - message: "#^Parameter \\#1 \\$ of closure expects TMemberType, TMemberType given\\.$#" count: 1 From 027109075c08382f3cd3686f1b8c6897aeeff270 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 8 May 2021 16:19:22 +0100 Subject: [PATCH 2461/3224] WorldManager: don't recalculate the spawn point for every player teleported during world unload --- src/world/WorldManager.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index b34a3621cb..dc5e0b54cd 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -150,11 +150,12 @@ class WorldManager{ } $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.level.unloading", [$world->getDisplayName()])); + $safeSpawn = $this->defaultWorld->getSafeSpawn(); foreach($world->getPlayers() as $player){ if($world === $this->defaultWorld or $this->defaultWorld === null){ $player->disconnect("Forced default world unload"); }else{ - $player->teleport($this->defaultWorld->getSafeSpawn()); + $player->teleport($safeSpawn); } } From e9f3cefe9423d4a765773b0b34f3ab2ebc1f898c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 8 May 2021 16:21:34 +0100 Subject: [PATCH 2462/3224] Default world might be null --- src/world/WorldManager.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index dc5e0b54cd..f925e9c4c6 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -150,9 +150,9 @@ class WorldManager{ } $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.level.unloading", [$world->getDisplayName()])); - $safeSpawn = $this->defaultWorld->getSafeSpawn(); + $safeSpawn = $this->defaultWorld !== null ? $this->defaultWorld->getSafeSpawn() : null; foreach($world->getPlayers() as $player){ - if($world === $this->defaultWorld or $this->defaultWorld === null){ + if($world === $this->defaultWorld or $safeSpawn === null){ $player->disconnect("Forced default world unload"); }else{ $player->teleport($safeSpawn); From 2ce6a87d05c5ab0d2becd7e9b024a08fa634ddcf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 8 May 2021 16:22:13 +0100 Subject: [PATCH 2463/3224] getSafeSpawn() may throw if the target terrain is not generated --- src/world/WorldManager.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index f925e9c4c6..573a95ab8a 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -150,7 +150,11 @@ class WorldManager{ } $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.level.unloading", [$world->getDisplayName()])); - $safeSpawn = $this->defaultWorld !== null ? $this->defaultWorld->getSafeSpawn() : null; + try{ + $safeSpawn = $this->defaultWorld !== null ? $this->defaultWorld->getSafeSpawn() : null; + }catch(WorldException $e){ + $safeSpawn = null; + } foreach($world->getPlayers() as $player){ if($world === $this->defaultWorld or $safeSpawn === null){ $player->disconnect("Forced default world unload"); From 1003fde2fc91865a53c724ffe8f79f8722c14cbf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 8 May 2021 20:11:16 +0100 Subject: [PATCH 2464/3224] RakLibServer: make all parameters mandatory --- src/network/mcpe/raklib/RakLibServer.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/network/mcpe/raklib/RakLibServer.php b/src/network/mcpe/raklib/RakLibServer.php index 329f0d5c21..9ea0cf654b 100644 --- a/src/network/mcpe/raklib/RakLibServer.php +++ b/src/network/mcpe/raklib/RakLibServer.php @@ -72,18 +72,15 @@ class RakLibServer extends Thread{ /** @var string|null */ public $crashInfo = null; - /** - * @param int|null $overrideProtocolVersion Optional custom protocol version to use, defaults to current RakLib's protocol - */ public function __construct( \ThreadedLogger $logger, \Threaded $mainToThreadBuffer, \Threaded $threadToMainBuffer, InternetAddress $address, int $serverId, - int $maxMtuSize = 1492, - ?int $overrideProtocolVersion = null, - ?SleeperNotifier $sleeper = null + int $maxMtuSize, + int $overrideProtocolVersion, + SleeperNotifier $sleeper ){ $this->address = $address; From 20197e68134d704337d112a89fa5b6ef2cfb5c31 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 8 May 2021 20:13:29 +0100 Subject: [PATCH 2465/3224] RakLibServer: clean up constructor parameters --- src/network/mcpe/raklib/RakLibServer.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/network/mcpe/raklib/RakLibServer.php b/src/network/mcpe/raklib/RakLibServer.php index 9ea0cf654b..05898e5675 100644 --- a/src/network/mcpe/raklib/RakLibServer.php +++ b/src/network/mcpe/raklib/RakLibServer.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\raklib; use pocketmine\snooze\SleeperNotifier; use pocketmine\thread\Thread; use raklib\generic\Socket; -use raklib\RakLib; use raklib\server\ipc\RakLibToUserThreadMessageSender; use raklib\server\ipc\UserToRakLibThreadMessageReceiver; use raklib\server\Server; @@ -79,7 +78,7 @@ class RakLibServer extends Thread{ InternetAddress $address, int $serverId, int $maxMtuSize, - int $overrideProtocolVersion, + int $protocolVersion, SleeperNotifier $sleeper ){ $this->address = $address; @@ -94,7 +93,7 @@ class RakLibServer extends Thread{ $this->mainPath = \pocketmine\PATH; - $this->protocolVersion = $overrideProtocolVersion ?? RakLib::DEFAULT_PROTOCOL_VERSION; + $this->protocolVersion = $protocolVersion; $this->mainThreadNotifier = $sleeper; } From 922164ff2cb37dc3e02d821fca815b2b765f019e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 8 May 2021 21:15:13 +0100 Subject: [PATCH 2466/3224] Updated composer dependencies --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index ad0dd501cf..f1c2e26cb6 100644 --- a/composer.lock +++ b/composer.lock @@ -704,12 +704,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "9d6f564e2843535a0ec621f7396b8b0292506cf8" + "reference": "6c83e0f50e71f654cf24a7d883ee0561e269483a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/9d6f564e2843535a0ec621f7396b8b0292506cf8", - "reference": "9d6f564e2843535a0ec621f7396b8b0292506cf8", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/6c83e0f50e71f654cf24a7d883ee0561e269483a", + "reference": "6c83e0f50e71f654cf24a7d883ee0561e269483a", "shasum": "" }, "require": { @@ -739,7 +739,7 @@ "issues": "https://github.com/pmmp/RakLib/issues", "source": "https://github.com/pmmp/RakLib/tree/master" }, - "time": "2021-05-05T19:32:05+00:00" + "time": "2021-05-08T19:24:13+00:00" }, { "name": "pocketmine/raklib-ipc", From 1533789f3594c68a8099e3157fe2a2b9c8c43520 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 9 May 2021 19:36:36 +0100 Subject: [PATCH 2467/3224] Player: fixed not subscribing to own inventory updates fixes #4211 --- src/player/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index 4b1556d721..e12bbc6df9 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2252,7 +2252,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->cursorInventory = new PlayerCursorInventory($this); $this->craftingGrid = new CraftingGrid($this, CraftingGrid::SIZE_SMALL); - $this->addPermanentInventories($this->inventory, $this->armorInventory, $this->cursorInventory); + $this->addPermanentInventories($this->inventory, $this->armorInventory, $this->cursorInventory, $this->offHandInventory); //TODO: more windows } From f90955752988e08785b84a64fba8a8615726dac1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 9 May 2021 20:50:40 +0100 Subject: [PATCH 2468/3224] Cleaned up implementations for EnderChestInventory/DoubleChestInventory previously, these were forced to extend BaseInventory because of the amount of crap in Inventory's interface. This meant that these inventories had their own slots storage, which would be _mostly_ unused because these inventories aren't real inventories, but rather just delegates. This lead to a variety of bugs in the past, such as certain API methods on BaseInventory not working correctly for DoubleChestInventory in particular. Now, BaseInventory just implements the functional part of the inventory implementation, leaving the storage system up to the implementation. A SimpleInventory class is provided with a simple SplFixedArray storage backing, which is used by most inventories. EnderChestInventory and DoubleChestInventory now extend BaseInventory directly, and implement custom methods for dealing with their delegates. --- ...ry.php => AnimatedBlockInventoryTrait.php} | 9 +- src/block/inventory/AnvilInventory.php | 7 +- src/block/inventory/BarrelInventory.php | 7 +- src/block/inventory/BlockInventory.php | 18 +--- src/block/inventory/BlockInventoryTrait.php | 34 ++++++++ src/block/inventory/BrewingStandInventory.php | 7 +- src/block/inventory/ChestInventory.php | 9 +- src/block/inventory/DoubleChestInventory.php | 39 +++++++-- src/block/inventory/EnchantInventory.php | 7 +- src/block/inventory/EnderChestInventory.php | 19 +++-- src/block/inventory/FurnaceInventory.php | 7 +- src/block/inventory/HopperInventory.php | 7 +- src/block/inventory/LoomInventory.php | 8 +- src/crafting/CraftingGrid.php | 4 +- src/inventory/ArmorInventory.php | 2 +- src/inventory/BaseInventory.php | 57 +++---------- src/inventory/PlayerCursorInventory.php | 2 +- src/inventory/PlayerEnderInventory.php | 2 +- src/inventory/PlayerInventory.php | 2 +- src/inventory/PlayerOffHandInventory.php | 2 +- src/inventory/SimpleInventory.php | 85 +++++++++++++++++++ tests/phpunit/inventory/BaseInventoryTest.php | 2 +- 22 files changed, 237 insertions(+), 99 deletions(-) rename src/block/inventory/{AnimatedBlockInventory.php => AnimatedBlockInventoryTrait.php} (90%) create mode 100644 src/block/inventory/BlockInventoryTrait.php create mode 100644 src/inventory/SimpleInventory.php diff --git a/src/block/inventory/AnimatedBlockInventory.php b/src/block/inventory/AnimatedBlockInventoryTrait.php similarity index 90% rename from src/block/inventory/AnimatedBlockInventory.php rename to src/block/inventory/AnimatedBlockInventoryTrait.php index fcc8e6699f..dd607b1373 100644 --- a/src/block/inventory/AnimatedBlockInventory.php +++ b/src/block/inventory/AnimatedBlockInventoryTrait.php @@ -27,7 +27,14 @@ use pocketmine\player\Player; use pocketmine\world\sound\Sound; use function count; -abstract class AnimatedBlockInventory extends BlockInventory{ +trait AnimatedBlockInventoryTrait{ + use BlockInventoryTrait; + + /** + * @return Player[] + * @phpstan-return array + */ + abstract public function getViewers() : array; abstract protected function getOpenSound() : Sound; diff --git a/src/block/inventory/AnvilInventory.php b/src/block/inventory/AnvilInventory.php index b6ecddf135..18a455863e 100644 --- a/src/block/inventory/AnvilInventory.php +++ b/src/block/inventory/AnvilInventory.php @@ -23,13 +23,16 @@ declare(strict_types=1); namespace pocketmine\block\inventory; +use pocketmine\inventory\SimpleInventory; use pocketmine\player\Player; use pocketmine\world\Position; -class AnvilInventory extends BlockInventory{ +class AnvilInventory extends SimpleInventory implements BlockInventory{ + use BlockInventoryTrait; public function __construct(Position $holder){ - parent::__construct($holder, 2); + $this->holder = $holder; + parent::__construct(2); } public function onClose(Player $who) : void{ diff --git a/src/block/inventory/BarrelInventory.php b/src/block/inventory/BarrelInventory.php index bb05d1c9c9..fe2662e30b 100644 --- a/src/block/inventory/BarrelInventory.php +++ b/src/block/inventory/BarrelInventory.php @@ -24,15 +24,18 @@ declare(strict_types=1); namespace pocketmine\block\inventory; use pocketmine\block\Barrel; +use pocketmine\inventory\SimpleInventory; use pocketmine\world\Position; use pocketmine\world\sound\BarrelCloseSound; use pocketmine\world\sound\BarrelOpenSound; use pocketmine\world\sound\Sound; -class BarrelInventory extends AnimatedBlockInventory{ +class BarrelInventory extends SimpleInventory implements BlockInventory{ + use AnimatedBlockInventoryTrait; public function __construct(Position $holder){ - parent::__construct($holder, 27); + $this->holder = $holder; + parent::__construct(27); } protected function getOpenSound() : Sound{ diff --git a/src/block/inventory/BlockInventory.php b/src/block/inventory/BlockInventory.php index bb346a598a..7712688c15 100644 --- a/src/block/inventory/BlockInventory.php +++ b/src/block/inventory/BlockInventory.php @@ -23,22 +23,8 @@ declare(strict_types=1); namespace pocketmine\block\inventory; -use pocketmine\inventory\BaseInventory; use pocketmine\world\Position; -class BlockInventory extends BaseInventory{ - /** @var Position */ - protected $holder; - - public function __construct(Position $holder, int $size){ - $this->holder = $holder->asPosition(); - parent::__construct($size); - } - - /** - * @return Position - */ - public function getHolder(){ - return $this->holder; - } +interface BlockInventory{ + public function getHolder() : Position; } diff --git a/src/block/inventory/BlockInventoryTrait.php b/src/block/inventory/BlockInventoryTrait.php new file mode 100644 index 0000000000..887e428ad0 --- /dev/null +++ b/src/block/inventory/BlockInventoryTrait.php @@ -0,0 +1,34 @@ +holder; + } +} diff --git a/src/block/inventory/BrewingStandInventory.php b/src/block/inventory/BrewingStandInventory.php index 39d806b33f..d171b59053 100644 --- a/src/block/inventory/BrewingStandInventory.php +++ b/src/block/inventory/BrewingStandInventory.php @@ -23,11 +23,14 @@ declare(strict_types=1); namespace pocketmine\block\inventory; +use pocketmine\inventory\SimpleInventory; use pocketmine\world\Position; -class BrewingStandInventory extends BlockInventory{ +class BrewingStandInventory extends SimpleInventory implements BlockInventory{ + use BlockInventoryTrait; public function __construct(Position $holder, int $size = 5){ - parent::__construct($holder, $size); + $this->holder = $holder; + parent::__construct($size); } } diff --git a/src/block/inventory/ChestInventory.php b/src/block/inventory/ChestInventory.php index 2f73269e84..1f8538e4bd 100644 --- a/src/block/inventory/ChestInventory.php +++ b/src/block/inventory/ChestInventory.php @@ -23,16 +23,19 @@ declare(strict_types=1); namespace pocketmine\block\inventory; +use pocketmine\inventory\SimpleInventory; use pocketmine\network\mcpe\protocol\BlockEventPacket; use pocketmine\world\Position; use pocketmine\world\sound\ChestCloseSound; use pocketmine\world\sound\ChestOpenSound; use pocketmine\world\sound\Sound; -class ChestInventory extends AnimatedBlockInventory{ +class ChestInventory extends SimpleInventory implements BlockInventory{ + use AnimatedBlockInventoryTrait; public function __construct(Position $holder){ - parent::__construct($holder, 27); + $this->holder = $holder; + parent::__construct(27); } protected function getOpenSound() : Sound{ @@ -43,7 +46,7 @@ class ChestInventory extends AnimatedBlockInventory{ return new ChestCloseSound(); } - protected function animateBlock(bool $isOpen) : void{ + public function animateBlock(bool $isOpen) : void{ $holder = $this->getHolder(); //event ID is always 1 for a chest diff --git a/src/block/inventory/DoubleChestInventory.php b/src/block/inventory/DoubleChestInventory.php index cab0c2acb4..9d99f1e2b9 100644 --- a/src/block/inventory/DoubleChestInventory.php +++ b/src/block/inventory/DoubleChestInventory.php @@ -23,11 +23,16 @@ declare(strict_types=1); namespace pocketmine\block\inventory; +use pocketmine\inventory\BaseInventory; use pocketmine\inventory\InventoryHolder; use pocketmine\item\Item; +use pocketmine\world\sound\ChestCloseSound; +use pocketmine\world\sound\ChestOpenSound; use pocketmine\world\sound\Sound; -class DoubleChestInventory extends AnimatedBlockInventory implements InventoryHolder{ +class DoubleChestInventory extends BaseInventory implements BlockInventory, InventoryHolder{ + use AnimatedBlockInventoryTrait; + /** @var ChestInventory */ private $left; /** @var ChestInventory */ @@ -36,21 +41,24 @@ class DoubleChestInventory extends AnimatedBlockInventory implements InventoryHo public function __construct(ChestInventory $left, ChestInventory $right){ $this->left = $left; $this->right = $right; - parent::__construct($this->left->getHolder(), $this->left->getSize() + $this->right->getSize()); + $this->holder = $this->left->getHolder(); + parent::__construct(); } public function getInventory(){ return $this; } + public function getSize() : int{ + return $this->left->getSize() + $this->right->getSize(); + } + public function getItem(int $index) : Item{ return $index < $this->left->getSize() ? $this->left->getItem($index) : $this->right->getItem($index - $this->left->getSize()); } - public function setItem(int $index, Item $item) : void{ - $old = $this->getItem($index); + protected function internalSetItem(int $index, Item $item) : void{ $index < $this->left->getSize() ? $this->left->setItem($index, $item) : $this->right->setItem($index - $this->left->getSize(), $item); - $this->onSlotChange($index, $old); } public function getContents(bool $includeEmpty = false) : array{ @@ -64,9 +72,26 @@ class DoubleChestInventory extends AnimatedBlockInventory implements InventoryHo return $result; } - protected function getOpenSound() : Sound{ return $this->left->getOpenSound(); } + protected function internalSetContents(array $items) : void{ + $leftSize = $this->left->getSize(); - protected function getCloseSound() : Sound{ return $this->left->getCloseSound(); } + $leftContents = []; + $rightContents = []; + + foreach($items as $i => $item){ + if($i < $this->left->getSize()){ + $leftContents[$i] = $item; + }else{ + $rightContents[$i - $leftSize] = $item; + } + } + $this->left->setContents($leftContents); + $this->right->setContents($rightContents); + } + + protected function getOpenSound() : Sound{ return new ChestOpenSound(); } + + protected function getCloseSound() : Sound{ return new ChestCloseSound(); } protected function animateBlock(bool $isOpen) : void{ $this->left->animateBlock($isOpen); diff --git a/src/block/inventory/EnchantInventory.php b/src/block/inventory/EnchantInventory.php index 54be05fc1b..9bd72da27b 100644 --- a/src/block/inventory/EnchantInventory.php +++ b/src/block/inventory/EnchantInventory.php @@ -23,13 +23,16 @@ declare(strict_types=1); namespace pocketmine\block\inventory; +use pocketmine\inventory\SimpleInventory; use pocketmine\player\Player; use pocketmine\world\Position; -class EnchantInventory extends BlockInventory{ +class EnchantInventory extends SimpleInventory implements BlockInventory{ + use BlockInventoryTrait; public function __construct(Position $holder){ - parent::__construct($holder, 2); + $this->holder = $holder; + parent::__construct(2); } public function onClose(Player $who) : void{ diff --git a/src/block/inventory/EnderChestInventory.php b/src/block/inventory/EnderChestInventory.php index 085c7dc4c7..f0c706371a 100644 --- a/src/block/inventory/EnderChestInventory.php +++ b/src/block/inventory/EnderChestInventory.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block\inventory; +use pocketmine\inventory\BaseInventory; use pocketmine\inventory\CallbackInventoryListener; use pocketmine\inventory\Inventory; use pocketmine\inventory\InventoryListener; @@ -38,13 +39,17 @@ use pocketmine\world\sound\Sound; /** * EnderChestInventory is not a real inventory; it's just a gateway to the player's ender inventory. */ -class EnderChestInventory extends AnimatedBlockInventory{ +class EnderChestInventory extends BaseInventory implements BlockInventory{ + use AnimatedBlockInventoryTrait { + onClose as animatedBlockInventoryTrait_onClose; + } private PlayerEnderInventory $inventory; private InventoryListener $inventoryListener; public function __construct(Position $holder, PlayerEnderInventory $inventory){ - parent::__construct($holder, $inventory->getSize()); + parent::__construct(); + $this->holder = $holder; $this->inventory = $inventory; $this->inventory->getListeners()->add($this->inventoryListener = new CallbackInventoryListener( function(Inventory $unused, int $slot, Item $oldItem) : void{ @@ -60,11 +65,15 @@ class EnderChestInventory extends AnimatedBlockInventory{ return $this->inventory; } + public function getSize() : int{ + return $this->inventory->getSize(); + } + public function getItem(int $index) : Item{ return $this->inventory->getItem($index); } - public function setItem(int $index, Item $item) : void{ + protected function internalSetItem(int $index, Item $item) : void{ $this->inventory->setItem($index, $item); } @@ -72,7 +81,7 @@ class EnderChestInventory extends AnimatedBlockInventory{ return $this->inventory->getContents($includeEmpty); } - public function setContents(array $items) : void{ + protected function internalSetContents(array $items) : void{ $this->inventory->setContents($items); } @@ -92,7 +101,7 @@ class EnderChestInventory extends AnimatedBlockInventory{ } public function onClose(Player $who) : void{ - parent::onClose($who); + $this->animatedBlockInventoryTrait_onClose($who); if($who === $this->inventory->getHolder()){ $this->inventory->getListeners()->remove($this->inventoryListener); $this->inventoryListener = CallbackInventoryListener::onAnyChange(static function() : void{}); //break cyclic reference diff --git a/src/block/inventory/FurnaceInventory.php b/src/block/inventory/FurnaceInventory.php index 40abbe954e..eb2f522047 100644 --- a/src/block/inventory/FurnaceInventory.php +++ b/src/block/inventory/FurnaceInventory.php @@ -23,13 +23,16 @@ declare(strict_types=1); namespace pocketmine\block\inventory; +use pocketmine\inventory\SimpleInventory; use pocketmine\item\Item; use pocketmine\world\Position; -class FurnaceInventory extends BlockInventory{ +class FurnaceInventory extends SimpleInventory implements BlockInventory{ + use BlockInventoryTrait; public function __construct(Position $holder){ - parent::__construct($holder, 3); + $this->holder = $holder; + parent::__construct(3); } public function getResult() : Item{ diff --git a/src/block/inventory/HopperInventory.php b/src/block/inventory/HopperInventory.php index ce79ebb904..eb75244c33 100644 --- a/src/block/inventory/HopperInventory.php +++ b/src/block/inventory/HopperInventory.php @@ -23,11 +23,14 @@ declare(strict_types=1); namespace pocketmine\block\inventory; +use pocketmine\inventory\SimpleInventory; use pocketmine\world\Position; -class HopperInventory extends BlockInventory{ +class HopperInventory extends SimpleInventory implements BlockInventory{ + use BlockInventoryTrait; public function __construct(Position $holder, int $size = 5){ - parent::__construct($holder, $size); + $this->holder = $holder; + parent::__construct($size); } } diff --git a/src/block/inventory/LoomInventory.php b/src/block/inventory/LoomInventory.php index 2a51f0f26a..24830329a9 100644 --- a/src/block/inventory/LoomInventory.php +++ b/src/block/inventory/LoomInventory.php @@ -23,16 +23,20 @@ declare(strict_types=1); namespace pocketmine\block\inventory; +use pocketmine\inventory\SimpleInventory; use pocketmine\player\Player; use pocketmine\world\Position; -final class LoomInventory extends BlockInventory{ +final class LoomInventory extends SimpleInventory implements BlockInventory{ + use BlockInventoryTrait; + public const SLOT_BANNER = 0; public const SLOT_DYE = 1; public const SLOT_PATTERN = 2; public function __construct(Position $holder, int $size = 3){ - parent::__construct($holder, $size); + $this->holder = $holder; + parent::__construct($size); } public function onClose(Player $who) : void{ diff --git a/src/crafting/CraftingGrid.php b/src/crafting/CraftingGrid.php index 6b7b952c7b..5c84c9b474 100644 --- a/src/crafting/CraftingGrid.php +++ b/src/crafting/CraftingGrid.php @@ -23,14 +23,14 @@ declare(strict_types=1); namespace pocketmine\crafting; -use pocketmine\inventory\BaseInventory; +use pocketmine\inventory\SimpleInventory; use pocketmine\item\Item; use pocketmine\player\Player; use function max; use function min; use const PHP_INT_MAX; -class CraftingGrid extends BaseInventory{ +class CraftingGrid extends SimpleInventory{ public const SIZE_SMALL = 2; public const SIZE_BIG = 3; diff --git a/src/inventory/ArmorInventory.php b/src/inventory/ArmorInventory.php index 82d8c2e144..4754e3aff0 100644 --- a/src/inventory/ArmorInventory.php +++ b/src/inventory/ArmorInventory.php @@ -26,7 +26,7 @@ namespace pocketmine\inventory; use pocketmine\entity\Living; use pocketmine\item\Item; -class ArmorInventory extends BaseInventory{ +class ArmorInventory extends SimpleInventory{ public const SLOT_HEAD = 0; public const SLOT_CHEST = 1; public const SLOT_LEGS = 2; diff --git a/src/inventory/BaseInventory.php b/src/inventory/BaseInventory.php index 7c29c4b4ca..03bbea73c0 100644 --- a/src/inventory/BaseInventory.php +++ b/src/inventory/BaseInventory.php @@ -27,21 +27,18 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\player\Player; use pocketmine\utils\ObjectSet; -use function array_map; use function array_slice; use function count; use function spl_object_id; +/** + * This class provides everything needed to implement an inventory, minus the underlying storage system. + */ abstract class BaseInventory implements Inventory{ use InventoryHelpersTrait; /** @var int */ protected $maxStackSize = Inventory::MAX_STACK; - /** - * @var \SplFixedArray|(Item|null)[] - * @phpstan-var \SplFixedArray - */ - protected $slots; /** @var Player[] */ protected $viewers = []; /** @@ -50,42 +47,18 @@ abstract class BaseInventory implements Inventory{ */ protected $listeners; - public function __construct(int $size){ - $this->slots = new \SplFixedArray($size); + public function __construct(){ $this->listeners = new ObjectSet(); } - /** - * Returns the size of the inventory. - */ - public function getSize() : int{ - return $this->slots->getSize(); - } - public function getMaxStackSize() : int{ return $this->maxStackSize; } - public function getItem(int $index) : Item{ - return $this->slots[$index] !== null ? clone $this->slots[$index] : ItemFactory::air(); - } - /** - * @return Item[] + * @param Item[] $items */ - public function getContents(bool $includeEmpty = false) : array{ - $contents = []; - - foreach($this->slots as $i => $slot){ - if($slot !== null){ - $contents[$i] = clone $slot; - }elseif($includeEmpty){ - $contents[$i] = ItemFactory::air(); - } - } - - return $contents; - } + abstract protected function internalSetContents(array $items) : void; /** * @param Item[] $items @@ -95,22 +68,14 @@ abstract class BaseInventory implements Inventory{ $items = array_slice($items, 0, $this->getSize(), true); } - $oldContents = array_map(function(?Item $item) : Item{ - return $item ?? ItemFactory::air(); - }, $this->slots->toArray()); + $oldContents = $this->getContents(true); $listeners = $this->listeners->toArray(); $this->listeners->clear(); $viewers = $this->viewers; $this->viewers = []; - for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ - if(!isset($items[$i])){ - $this->clear($i); - }else{ - $this->setItem($i, $items[$i]); - } - } + $this->internalSetContents($items); $this->listeners->add(...$listeners); //don't directly write, in case listeners were added while operation was in progress foreach($viewers as $id => $viewer){ @@ -120,6 +85,8 @@ abstract class BaseInventory implements Inventory{ $this->onContentChange($oldContents); } + abstract protected function internalSetItem(int $index, Item $item) : void; + public function setItem(int $index, Item $item) : void{ if($item->isNull()){ $item = ItemFactory::air(); @@ -129,7 +96,7 @@ abstract class BaseInventory implements Inventory{ $oldItem = $this->getItem($index); - $this->slots[$index] = $item->isNull() ? null : $item; + $this->internalSetItem($index, $item); $this->onSlotChange($index, $oldItem); } @@ -188,7 +155,7 @@ abstract class BaseInventory implements Inventory{ } public function slotExists(int $slot) : bool{ - return $slot >= 0 and $slot < $this->slots->getSize(); + return $slot >= 0 and $slot < $this->getSize(); } public function getListeners() : ObjectSet{ diff --git a/src/inventory/PlayerCursorInventory.php b/src/inventory/PlayerCursorInventory.php index e7d35f6141..9cd948c589 100644 --- a/src/inventory/PlayerCursorInventory.php +++ b/src/inventory/PlayerCursorInventory.php @@ -25,7 +25,7 @@ namespace pocketmine\inventory; use pocketmine\player\Player; -class PlayerCursorInventory extends BaseInventory{ +class PlayerCursorInventory extends SimpleInventory{ /** @var Player */ protected $holder; diff --git a/src/inventory/PlayerEnderInventory.php b/src/inventory/PlayerEnderInventory.php index fb126dd45e..c1282b341d 100644 --- a/src/inventory/PlayerEnderInventory.php +++ b/src/inventory/PlayerEnderInventory.php @@ -25,7 +25,7 @@ namespace pocketmine\inventory; use pocketmine\entity\Human; -final class PlayerEnderInventory extends BaseInventory{ +final class PlayerEnderInventory extends SimpleInventory{ private Human $holder; diff --git a/src/inventory/PlayerInventory.php b/src/inventory/PlayerInventory.php index 4f76ec258e..253ddfdeaf 100644 --- a/src/inventory/PlayerInventory.php +++ b/src/inventory/PlayerInventory.php @@ -28,7 +28,7 @@ use pocketmine\item\Item; use pocketmine\player\Player; use pocketmine\utils\ObjectSet; -class PlayerInventory extends BaseInventory{ +class PlayerInventory extends SimpleInventory{ /** @var Human */ protected $holder; diff --git a/src/inventory/PlayerOffHandInventory.php b/src/inventory/PlayerOffHandInventory.php index 89354ffcf9..1db8d63e0c 100644 --- a/src/inventory/PlayerOffHandInventory.php +++ b/src/inventory/PlayerOffHandInventory.php @@ -25,7 +25,7 @@ namespace pocketmine\inventory; use pocketmine\entity\Human; -final class PlayerOffHandInventory extends BaseInventory{ +final class PlayerOffHandInventory extends SimpleInventory{ /** @var Human */ private $holder; diff --git a/src/inventory/SimpleInventory.php b/src/inventory/SimpleInventory.php new file mode 100644 index 0000000000..f05b527a23 --- /dev/null +++ b/src/inventory/SimpleInventory.php @@ -0,0 +1,85 @@ + + */ + protected \SplFixedArray $slots; + + public function __construct(int $size){ + $this->slots = new \SplFixedArray($size); + parent::__construct(); + } + + /** + * Returns the size of the inventory. + */ + public function getSize() : int{ + return $this->slots->getSize(); + } + + public function getItem(int $index) : Item{ + return $this->slots[$index] !== null ? clone $this->slots[$index] : ItemFactory::air(); + } + + /** + * @return Item[] + */ + public function getContents(bool $includeEmpty = false) : array{ + $contents = []; + + foreach($this->slots as $i => $slot){ + if($slot !== null){ + $contents[$i] = clone $slot; + }elseif($includeEmpty){ + $contents[$i] = ItemFactory::air(); + } + } + + return $contents; + } + + protected function internalSetContents(array $items) : void{ + for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ + if(!isset($items[$i])){ + $this->clear($i); + }else{ + $this->setItem($i, $items[$i]); + } + } + } + + protected function internalSetItem(int $index, Item $item) : void{ + $this->slots[$index] = $item->isNull() ? null : $item; + } +} diff --git a/tests/phpunit/inventory/BaseInventoryTest.php b/tests/phpunit/inventory/BaseInventoryTest.php index 9dec6b9c24..5f3d39b66f 100644 --- a/tests/phpunit/inventory/BaseInventoryTest.php +++ b/tests/phpunit/inventory/BaseInventoryTest.php @@ -30,7 +30,7 @@ use pocketmine\item\ItemIds; class BaseInventoryTest extends TestCase{ public function testAddItemDifferentUserData() : void{ - $inv = new class(1) extends BaseInventory{ + $inv = new class(1) extends SimpleInventory{ }; $item1 = ItemFactory::getInstance()->get(ItemIds::ARROW, 0, 1); From 0ff21557e4402f7565c55b1071e393b27002032e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 10 May 2021 17:20:04 +0100 Subject: [PATCH 2469/3224] World: fixed generation requests being rejected during resolution when a chunk population is ordered, its only chunk loader is the one that the World installed to keep the chunk loaded while it was generated. So, when the resolver removes its chunk loader from the chunk, it triggers the chunk unloading mechanism, which causes the promise to directly be rejected. --- src/world/World.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index b27e30c8fc..cb3acfaaa6 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2111,8 +2111,9 @@ class World implements ChunkManager{ } } unset($this->activeChunkPopulationTasks[$index]); - $this->chunkPopulationRequestMap[$index]->resolve($chunk); + $promise = $this->chunkPopulationRequestMap[$index]; unset($this->chunkPopulationRequestMap[$index]); + $promise->resolve($chunk); $this->drainPopulationRequestQueue(); }elseif($this->isChunkLocked($x, $z)){ From 094c949e86433bfca33e0cd17ca3f8ea6a7cf14d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 11 May 2021 19:08:56 +0100 Subject: [PATCH 2470/3224] Entity: fixed extremely stupid bug with player respawning after ragequit --- src/entity/Entity.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 900ebc6d3c..c3340db50b 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -546,8 +546,12 @@ abstract class Entity{ } if($amount <= 0){ - if($this->isAlive() and !$this->justCreated){ - $this->kill(); + if($this->isAlive()){ + if(!$this->justCreated){ + $this->kill(); + }else{ + $this->health = 0; + } } }elseif($amount <= $this->getMaxHealth() or $amount < $this->health){ $this->health = $amount; From ab0500ae4fa4a128ee356c60c9b64796faa927ca Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 11 May 2021 19:15:31 +0100 Subject: [PATCH 2471/3224] Player: Fixed a multitude of bugs with respawning the following things are changed: - Player->getSpawn() no longer returns a safe spawn by default. Instead, if the player doesn't have a spawn set, it returns the world's stored spawn directly. This allows consistent behaviour of locating safe respawn positions without double calculation of safe spawn position, and also fixes crash issues during the login sequence if the player's spawn position referred to ungenerated terrain. - Player->respawn() is now asynchronous, using the promise returned by orderChunkPopulation() to complete respawn after the terrain is generated. This allows consistently selecting a safe respawn position and fixes crashes when respawning if the spawn location was in ungenerated terrain. There remains a problem that ragequit respawns are still only handled right after PlayerJoinEvent, which leads to the original spawn terrain being sent to the player, which is obviously very wasteful. However, that's a problem for a later commit. --- src/player/Player.php | 65 ++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index e12bbc6df9..abbc2e5fe1 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -810,6 +810,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } if($this->getHealth() <= 0){ + $this->logger->debug("Quit while dead, forcing respawn"); $this->respawn(); } } @@ -907,7 +908,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ }else{ $world = $this->server->getWorldManager()->getDefaultWorld(); - return $world->getSafeSpawn(); + return $world->getSpawnLocation(); } } @@ -2059,16 +2060,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $nbt->setInt("SpawnZ", $spawn->getFloorZ()); } - if(!$this->isAlive()){ - $spawn = $this->getSpawn(); - //hack for respawn after quit - $nbt->setTag("Pos", new ListTag([ - new DoubleTag($spawn->getFloorX()), - new DoubleTag($spawn->getFloorY()), - new DoubleTag($spawn->getFloorZ()) - ])); - } - $nbt->setInt("playerGameType", $this->gamemode->getMagicNumber()); $nbt->setLong("firstPlayed", $this->firstPlayed); $nbt->setLong("lastPlayed", (int) floor(microtime(true) * 1000)); @@ -2133,31 +2124,47 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return; } - $ev = new PlayerRespawnEvent($this, $this->getSpawn()); - $ev->call(); + $this->logger->debug("Waiting for spawn terrain generation for respawn"); + $spawn = $this->getSpawn(); + $spawn->getWorld()->orderChunkPopulation($spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4, null)->onCompletion( + function() use ($spawn) : void{ + if(!$this->isConnected()){ + return; + } + $this->logger->debug("Spawn terrain generation done, completing respawn"); + $spawn = $spawn->getWorld()->getSafeSpawn($spawn); + $ev = new PlayerRespawnEvent($this, $spawn); + $ev->call(); - $realSpawn = Position::fromObject($ev->getRespawnPosition()->add(0.5, 0, 0.5), $ev->getRespawnPosition()->getWorld()); - $this->teleport($realSpawn); + $realSpawn = Position::fromObject($ev->getRespawnPosition()->add(0.5, 0, 0.5), $ev->getRespawnPosition()->getWorld()); + $this->teleport($realSpawn); - $this->setSprinting(false); - $this->setSneaking(false); + $this->setSprinting(false); + $this->setSneaking(false); - $this->extinguish(); - $this->setAirSupplyTicks($this->getMaxAirSupplyTicks()); - $this->deadTicks = 0; - $this->noDamageTicks = 60; + $this->extinguish(); + $this->setAirSupplyTicks($this->getMaxAirSupplyTicks()); + $this->deadTicks = 0; + $this->noDamageTicks = 60; - $this->effectManager->clear(); - $this->setHealth($this->getMaxHealth()); + $this->effectManager->clear(); + $this->setHealth($this->getMaxHealth()); - foreach($this->attributeMap->getAll() as $attr){ - $attr->resetToDefault(); - } + foreach($this->attributeMap->getAll() as $attr){ + $attr->resetToDefault(); + } - $this->spawnToAll(); - $this->scheduleUpdate(); + $this->spawnToAll(); + $this->scheduleUpdate(); - $this->getNetworkSession()->onServerRespawn(); + $this->getNetworkSession()->onServerRespawn(); + }, + function() : void{ + if($this->isConnected()){ + $this->disconnect("Unable to find a respawn position"); + } + } + ); } protected function applyPostDamageEffects(EntityDamageEvent $source) : void{ From dfdd59734cb9fbea638dd388905fa4857ed8b4d4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 11 May 2021 19:26:01 +0100 Subject: [PATCH 2472/3224] [ci skip] update changelog --- changelogs/4.0-snapshot.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 86a39f10c7..d0d5ee5ed6 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -70,6 +70,11 @@ This major version features substantial changes throughout the core, including s - New PHP extensions are required by this version: - [chunkutils2](https://github.com/pmmp/ext-chunkutils2) - [morton](https://github.com/pmmp/ext-morton) +- Many bugs in player respawning have been fixed, including: + - Spawning underneath bedrock when spawn position referred to ungenerated terrain + - Spawning underneath bedrock on first server join on very slow machines (or when the machine was under very high load) + - Spawning inside blocks (or above the ground) when respawning with a custom spawn position set + - Player spawn positions sticking to the old location when world spawn position changed - this was because the world spawn at time of player creation was used as the player's custom spawn, so the bug will persist for older player data, but will work as expected for new players. ### World handling #### Interface @@ -679,6 +684,7 @@ This version features substantial changes to the network system, improving coher - `Player::SPECTATOR` - use `GameMode::SPECTATOR()` - `Player::VIEW` - use `GameMode::SPECTATOR()` - (almost) all packet handlers have been removed from `Player`. They are now encapsulated within the network layer. +- `Player->getSpawn()` no longer returns the world's safe spawn if the player's spawn position isn't set. Returning the safe spawn at the time of call made no sense, because it might not have been safe when actually used. You should pass the result of this function to `World->getSafeSpawn()` to get a safe spawn position instead. - The following API methods have been added: - `Player->attackBlock()`: attack (left click) the target block, e.g. to start destroying it (survival) - `Player->attackEntity()`: melee-attack (left click) the target entity (if within range) From 4a68e0219e2985401ba3dfd7810752ae1c858e91 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 11 May 2021 19:29:30 +0100 Subject: [PATCH 2473/3224] shut --- src/player/Player.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index abbc2e5fe1..c305079397 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -83,9 +83,7 @@ use pocketmine\lang\Language; use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\IntTag; -use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; From 34ee1c2354bf5270e769cfa7a831199bd19cdb02 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 May 2021 12:00:52 +0100 Subject: [PATCH 2474/3224] pocketmine.yml: update preset example for worlds preset is now supported as its own key, and it's less confusing to present it separately, since that's how it's displayed in the server.properties also. --- resources/pocketmine.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/pocketmine.yml b/resources/pocketmine.yml index b154dafd14..f27a6d01c4 100644 --- a/resources/pocketmine.yml +++ b/resources/pocketmine.yml @@ -181,7 +181,8 @@ worlds: #Example: #world: # seed: 404 - # generator: FLAT:2;7,59x1,3x3,2;1;decoration(treecount=80 grasscount=45) + # generator: FLAT + # preset: 2;bedrock,59xstone,3xdirt,grass;1 plugins: #Setting this to true will cause the legacy structure to be used where plugin data is placed inside the --plugins dir. From 42e915b90247c8b9f916112c4aa7c67f22d87207 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 May 2021 12:10:32 +0100 Subject: [PATCH 2475/3224] Player: added locking variable to prevent reentry into respawn() while awaiting spawn terrain generation --- src/player/Player.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/player/Player.php b/src/player/Player.php index c305079397..e36976345d 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -229,6 +229,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ /** @var Position|null */ private $spawnPosition = null; + private bool $respawnLocked = false; + //TODO: Abilities /** @var bool */ protected $autoJump = true; @@ -2115,6 +2117,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } public function respawn() : void{ + if($this->respawnLocked){ + return; + } + $this->respawnLocked = true; if($this->server->isHardcore()){ if($this->kick("You have been banned because you died in hardcore mode")){ //this allows plugins to prevent the ban by cancelling PlayerKickEvent $this->server->getNameBans()->addBan($this->getName(), "Died in hardcore mode"); @@ -2156,6 +2162,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->scheduleUpdate(); $this->getNetworkSession()->onServerRespawn(); + $this->respawnLocked = false; }, function() : void{ if($this->isConnected()){ From 80e4da85df121cfdda5fcd0173745d3f016d8a66 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 May 2021 12:12:29 +0100 Subject: [PATCH 2476/3224] Fixed PHPStan build --- tests/phpstan/configs/l8-baseline.neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index c47c76564e..4dc8a7f587 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -211,7 +211,7 @@ parameters: path: ../../../src/player/Player.php - - message: "#^Cannot call method getSafeSpawn\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" + message: "#^Cannot call method getSpawnLocation\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" count: 1 path: ../../../src/player/Player.php From b2e806e2faaea7aa6ce73d4ea4e264e0406d5148 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 May 2021 12:26:41 +0100 Subject: [PATCH 2477/3224] World: Harden chunk loading against bad data in entity/tile NBT --- src/block/tile/Tile.php | 2 ++ src/block/tile/TileFactory.php | 2 ++ src/entity/EntityFactory.php | 2 ++ src/world/World.php | 49 +++++++++++++++++++++------------- 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/block/tile/Tile.php b/src/block/tile/Tile.php index dac7635700..59406a74ae 100644 --- a/src/block/tile/Tile.php +++ b/src/block/tile/Tile.php @@ -30,6 +30,7 @@ namespace pocketmine\block\tile; use pocketmine\block\Block; use pocketmine\item\Item; use pocketmine\math\Vector3; +use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; @@ -58,6 +59,7 @@ abstract class Tile{ /** * @internal + * @throws NbtDataException * Reads additional data from the CompoundTag on tile creation. */ abstract public function readSaveData(CompoundTag $nbt) : void; diff --git a/src/block/tile/TileFactory.php b/src/block/tile/TileFactory.php index 84fc99e57c..10d144648f 100644 --- a/src/block/tile/TileFactory.php +++ b/src/block/tile/TileFactory.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block\tile; use pocketmine\math\Vector3; +use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\utils\SingletonTrait; use pocketmine\utils\Utils; @@ -111,6 +112,7 @@ final class TileFactory{ /** * @internal + * @throws NbtDataException */ public function createFromData(World $world, CompoundTag $nbt) : ?Tile{ $type = $nbt->getString(Tile::TAG_ID, ""); diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index ebad938512..a7c9c1c0fb 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -43,6 +43,7 @@ use pocketmine\entity\projectile\SplashPotion; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; +use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; @@ -208,6 +209,7 @@ final class EntityFactory{ * Creates an entity from data stored on a chunk. * * @throws \RuntimeException + * @throws NbtDataException * @internal */ public function createFromData(World $world, CompoundTag $nbt) : ?Entity{ diff --git a/src/world/World.php b/src/world/World.php index cb3acfaaa6..b8958aa261 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -56,6 +56,7 @@ use pocketmine\item\ItemUseResult; use pocketmine\item\LegacyStringToItemParser; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; +use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; @@ -2450,24 +2451,26 @@ class World implements ChunkManager{ if($chunk->NBTentities !== null){ $this->timings->syncChunkLoadEntities->startTiming(); $entityFactory = EntityFactory::getInstance(); - foreach($chunk->NBTentities as $nbt){ + foreach($chunk->NBTentities as $k => $nbt){ try{ $entity = $entityFactory->createFromData($this, $nbt); - if(!($entity instanceof Entity)){ - $saveIdTag = $nbt->getTag("id") ?? $nbt->getTag("identifier"); - $saveId = ""; - if($saveIdTag instanceof StringTag){ - $saveId = $saveIdTag->getValue(); - }elseif($saveIdTag instanceof IntTag){ //legacy MCPE format - $saveId = "legacy(" . $saveIdTag->getValue() . ")"; - } - $this->getLogger()->warning("Chunk $chunkX $chunkZ: Deleted unknown entity type $saveId"); - continue; - } - }catch(\Exception $t){ //TODO: this shouldn't be here - $this->getLogger()->logException($t); + }catch(NbtDataException $e){ + $this->getLogger()->error("Chunk $chunkX $chunkZ: Bad entity data at list position $k: " . $e->getMessage()); + $this->getLogger()->logException($e); continue; } + if($entity === null){ + $saveIdTag = $nbt->getTag("id") ?? $nbt->getTag("identifier"); + $saveId = ""; + if($saveIdTag instanceof StringTag){ + $saveId = $saveIdTag->getValue(); + }elseif($saveIdTag instanceof IntTag){ //legacy MCPE format + $saveId = "legacy(" . $saveIdTag->getValue() . ")"; + } + $this->getLogger()->warning("Chunk $chunkX $chunkZ: Deleted unknown entity type $saveId"); + } + //TODO: we can't prevent entities getting added to unloaded chunks if they were saved in the wrong place + //here, because entities currently add themselves to the world } $chunk->setDirtyFlag(Chunk::DIRTY_FLAG_ENTITIES, true); @@ -2477,13 +2480,21 @@ class World implements ChunkManager{ if($chunk->NBTtiles !== null){ $this->timings->syncChunkLoadTileEntities->startTiming(); $tileFactory = TileFactory::getInstance(); - foreach($chunk->NBTtiles as $nbt){ - if(($tile = $tileFactory->createFromData($this, $nbt)) !== null){ - $this->addTile($tile); - }else{ - $this->getLogger()->warning("Chunk $chunkX $chunkZ: Deleted unknown tile entity type " . $nbt->getString("id", "")); + foreach($chunk->NBTtiles as $k => $nbt){ + try{ + $tile = $tileFactory->createFromData($this, $nbt); + }catch(NbtDataException $e){ + $this->getLogger()->error("Chunk $chunkX $chunkZ: Bad tile entity data at list position $k: " . $e->getMessage()); + $this->getLogger()->logException($e); continue; } + if($tile === null){ + $this->getLogger()->warning("Chunk $chunkX $chunkZ: Deleted unknown tile entity type " . $nbt->getString("id", "")); + }elseif(!$this->isChunkLoaded($tile->getPos()->getFloorX() >> 4, $tile->getPos()->getFloorZ() >> 4)){ + $this->logger->error("Chunk $chunkX $chunkZ: Found tile saved on wrong chunk - unable to fix due to correct chunk not loaded"); + }else{ + $this->addTile($tile); + } } $chunk->setDirtyFlag(Chunk::DIRTY_FLAG_TILES, true); From bdce781c6dc353965a7b5b4ea16c55ec9d30722f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 12 May 2021 12:32:36 +0100 Subject: [PATCH 2478/3224] Chunk: do not close preexisting tiles in addTile() if it's desired to actually replace a tile, the old tile should be explicitly removed and closed first. --- src/world/format/Chunk.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index a625b17270..e666a675ed 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -229,7 +229,7 @@ class Chunk{ $pos = $tile->getPos(); if(isset($this->tiles[$index = Chunk::blockHash($pos->x, $pos->y, $pos->z)]) and $this->tiles[$index] !== $tile){ - $this->tiles[$index]->close(); + throw new \InvalidArgumentException("Another tile is already at this location"); } $this->tiles[$index] = $tile; $this->dirtyFlags |= self::DIRTY_FLAG_TILES; From 5a14c1cb89397bb0da8ff620735b3d171637de47 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 17 May 2021 20:05:52 +0100 Subject: [PATCH 2479/3224] Entity: don't rebuild metadata every tick unless an associated property changed this should improve performance back to PM3 levels. --- src/entity/Entity.php | 24 ++++++++++++++++++++++-- src/entity/Living.php | 7 +++++++ src/entity/Villager.php | 1 + src/entity/object/ExperienceOrb.php | 1 + src/entity/object/PrimedTNT.php | 6 +++++- src/entity/projectile/Arrow.php | 1 + src/entity/projectile/SplashPotion.php | 2 ++ src/player/Player.php | 3 +++ 8 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index c3340db50b..4d4442c632 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -184,6 +184,8 @@ abstract class Entity{ /** @var TimingsHandler */ protected $timings; + protected bool $networkPropertiesDirty = false; + /** @var string */ protected $nameTag = ""; /** @var bool */ @@ -269,6 +271,7 @@ abstract class Entity{ public function setNameTag(string $name) : void{ $this->nameTag = $name; + $this->networkPropertiesDirty = true; } public function setNameTagVisible(bool $value = true) : void{ @@ -277,6 +280,7 @@ abstract class Entity{ public function setNameTagAlwaysVisible(bool $value = true) : void{ $this->alwaysShowNameTag = $value; + $this->networkPropertiesDirty = true; } public function getScoreTag() : ?string{ @@ -285,6 +289,7 @@ abstract class Entity{ public function setScoreTag(string $score) : void{ $this->scoreTag = $score; + $this->networkPropertiesDirty = true; } public function getScale() : float{ @@ -300,6 +305,7 @@ abstract class Entity{ $this->scale = $value; $this->recalculateBoundingBox(); + $this->networkPropertiesDirty = true; } public function getBoundingBox() : AxisAlignedBB{ @@ -325,6 +331,7 @@ abstract class Entity{ public function setImmobile(bool $value = true) : void{ $this->immobile = $value; + $this->networkPropertiesDirty = true; } public function isInvisible() : bool{ @@ -333,6 +340,7 @@ abstract class Entity{ public function setInvisible(bool $value = true) : void{ $this->invisible = $value; + $this->networkPropertiesDirty = true; } public function isSilent() : bool{ @@ -341,6 +349,7 @@ abstract class Entity{ public function setSilent(bool $value = true) : void{ $this->silent = $value; + $this->networkPropertiesDirty = true; } /** @@ -355,6 +364,7 @@ abstract class Entity{ */ public function setCanClimb(bool $value = true) : void{ $this->canClimb = $value; + $this->networkPropertiesDirty = true; } /** @@ -369,6 +379,7 @@ abstract class Entity{ */ public function setCanClimbWalls(bool $value = true) : void{ $this->canClimbWalls = $value; + $this->networkPropertiesDirty = true; } /** @@ -398,6 +409,7 @@ abstract class Entity{ }else{ $this->ownerId = $owner->getId(); } + $this->networkPropertiesDirty = true; } /** @@ -428,6 +440,7 @@ abstract class Entity{ }else{ $this->targetId = $target->getId(); } + $this->networkPropertiesDirty = true; } /** @@ -635,6 +648,7 @@ abstract class Entity{ if($ticks > $this->getFireTicks()){ $this->setFireTicks($ticks); } + $this->networkPropertiesDirty = true; } public function getFireTicks() : int{ @@ -1580,7 +1594,10 @@ abstract class Entity{ * @phpstan-return array */ final protected function getDirtyNetworkData() : array{ - $this->syncNetworkData($this->networkProperties); + if($this->networkPropertiesDirty){ + $this->syncNetworkData($this->networkProperties); + $this->networkPropertiesDirty = false; + } return $this->networkProperties->getDirty(); } @@ -1589,7 +1606,10 @@ abstract class Entity{ * @phpstan-return array */ final protected function getAllNetworkData() : array{ - $this->syncNetworkData($this->networkProperties); + if($this->networkPropertiesDirty){ + $this->syncNetworkData($this->networkProperties); + $this->networkPropertiesDirty = false; + } return $this->networkProperties->getAll(); } diff --git a/src/entity/Living.php b/src/entity/Living.php index 6bedafacff..e11b2e5a1e 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -123,6 +123,8 @@ abstract class Living extends Entity{ parent::initEntity($nbt); $this->effectManager = new EffectManager($this); + $this->effectManager->getEffectAddHooks()->add(function() : void{ $this->networkPropertiesDirty = true; }); + $this->effectManager->getEffectRemoveHooks()->add(function() : void{ $this->networkPropertiesDirty = true; }); $this->armorInventory = new ArmorInventory($this); //TODO: load/save armor inventory contents @@ -208,6 +210,7 @@ abstract class Living extends Entity{ public function setSneaking(bool $value = true) : void{ $this->sneaking = $value; + $this->networkPropertiesDirty = true; } public function isSprinting() : bool{ @@ -217,6 +220,7 @@ abstract class Living extends Entity{ public function setSprinting(bool $value = true) : void{ if($value !== $this->isSprinting()){ $this->sprinting = $value; + $this->networkPropertiesDirty = true; $moveSpeed = $this->getMovementSpeed(); $this->setMovementSpeed($value ? ($moveSpeed * 1.3) : ($moveSpeed / 1.3)); $this->moveSpeedAttr->markSynchronized(false); //TODO: reevaluate this hack @@ -643,6 +647,7 @@ abstract class Living extends Entity{ */ public function setBreathing(bool $value = true) : void{ $this->breathing = $value; + $this->networkPropertiesDirty = true; } /** @@ -658,6 +663,7 @@ abstract class Living extends Entity{ */ public function setAirSupplyTicks(int $ticks) : void{ $this->breathTicks = $ticks; + $this->networkPropertiesDirty = true; } /** @@ -672,6 +678,7 @@ abstract class Living extends Entity{ */ public function setMaxAirSupplyTicks(int $ticks) : void{ $this->maxBreathTicks = $ticks; + $this->networkPropertiesDirty = true; } /** diff --git a/src/entity/Villager.php b/src/entity/Villager.php index ac749735dc..d43e4faf9b 100644 --- a/src/entity/Villager.php +++ b/src/entity/Villager.php @@ -76,6 +76,7 @@ class Villager extends Living implements Ageable{ */ public function setProfession(int $profession) : void{ $this->profession = $profession; //TODO: validation + $this->networkPropertiesDirty = true; } public function getProfession() : int{ diff --git a/src/entity/object/ExperienceOrb.php b/src/entity/object/ExperienceOrb.php index 260d4f8b2b..c3f0b63827 100644 --- a/src/entity/object/ExperienceOrb.php +++ b/src/entity/object/ExperienceOrb.php @@ -137,6 +137,7 @@ class ExperienceOrb extends Entity{ throw new \InvalidArgumentException("XP amount must be greater than 0, got $amount"); } $this->xpValue = $amount; + $this->networkPropertiesDirty = true; } public function hasTargetPlayer() : bool{ diff --git a/src/entity/object/PrimedTNT.php b/src/entity/object/PrimedTNT.php index d6e728d9dd..184a30285a 100644 --- a/src/entity/object/PrimedTNT.php +++ b/src/entity/object/PrimedTNT.php @@ -62,11 +62,15 @@ class PrimedTNT extends Entity implements Explosive{ throw new \InvalidArgumentException("Fuse must be in the range 0-32767"); } $this->fuse = $fuse; + $this->networkPropertiesDirty = true; } public function worksUnderwater() : bool{ return $this->worksUnderwater; } - public function setWorksUnderwater(bool $worksUnderwater) : void{ $this->worksUnderwater = $worksUnderwater; } + public function setWorksUnderwater(bool $worksUnderwater) : void{ + $this->worksUnderwater = $worksUnderwater; + $this->networkPropertiesDirty = true; + } public function attack(EntityDamageEvent $source) : void{ if($source->getCause() === EntityDamageEvent::CAUSE_VOID){ diff --git a/src/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php index fc163472e4..d296b4092d 100644 --- a/src/entity/projectile/Arrow.php +++ b/src/entity/projectile/Arrow.php @@ -96,6 +96,7 @@ class Arrow extends Projectile{ public function setCritical(bool $value = true) : void{ $this->critical = $value; + $this->networkPropertiesDirty = true; } public function getResultDamage() : int{ diff --git a/src/entity/projectile/SplashPotion.php b/src/entity/projectile/SplashPotion.php index a800ee5559..7fea391afc 100644 --- a/src/entity/projectile/SplashPotion.php +++ b/src/entity/projectile/SplashPotion.php @@ -150,6 +150,7 @@ class SplashPotion extends Throwable{ public function setPotionId(int $id) : void{ $this->potionId = $id; //TODO: validation + $this->networkPropertiesDirty = true; } /** @@ -164,6 +165,7 @@ class SplashPotion extends Throwable{ */ public function setLinger(bool $value = true) : void{ $this->linger = $value; + $this->networkPropertiesDirty = true; } /** diff --git a/src/player/Player.php b/src/player/Player.php index e36976345d..ed8a706f48 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -594,6 +594,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ public function setUsingItem(bool $value) : void{ $this->startAction = $value ? $this->server->getTick() : -1; + $this->networkPropertiesDirty = true; } /** @@ -956,6 +957,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } $this->sleeping = $pos; + $this->networkPropertiesDirty = true; $this->setSpawn($pos); @@ -974,6 +976,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ (new PlayerBedLeaveEvent($this, $b))->call(); $this->sleeping = null; + $this->networkPropertiesDirty = true; $this->getWorld()->setSleepTicks(0); From 10391be615a7ab69fe199573f2b91f1132481a3e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 17 May 2021 20:06:28 +0100 Subject: [PATCH 2480/3224] Remove useless class --- src/entity/Animal.php | 41 ----------------------------------------- 1 file changed, 41 deletions(-) delete mode 100644 src/entity/Animal.php diff --git a/src/entity/Animal.php b/src/entity/Animal.php deleted file mode 100644 index 17fb750b29..0000000000 --- a/src/entity/Animal.php +++ /dev/null @@ -1,41 +0,0 @@ -baby; - } - - protected function syncNetworkData(EntityMetadataCollection $properties) : void{ - parent::syncNetworkData($properties); - $properties->setGenericFlag(EntityMetadataFlags::BABY, $this->baby); - } -} From bab76f4a6e24e29040b0b45576355770ea930652 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 17 May 2021 20:50:46 +0100 Subject: [PATCH 2481/3224] World: extract some blocks of logic from tickChunks() into their own methods the amount of nested loops, cx/dx/chunkx/etc clusterfuck in this code makes it very difficult to work with... --- src/world/World.php | 109 +++++++++++++++++++++++++------------------- 1 file changed, 61 insertions(+), 48 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index b8958aa261..ed1fe8aa88 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -993,54 +993,7 @@ class World implements ChunkManager{ $dx = mt_rand(-$randRange, $randRange); $dz = mt_rand(-$randRange, $randRange); $hash = World::chunkHash($dx + $chunkX, $dz + $chunkZ); - if(!isset($chunkTickList[$hash]) and isset($this->chunks[$hash])){ - if( - !$this->chunks[$hash]->isPopulated() || - $this->isChunkLocked($dx + $chunkX, $dz + $chunkZ) - ){ - continue; - } - //TODO: this might need to be checked after adjacent chunks are loaded in future - $lightPopulatedState = $this->chunks[$hash]->isLightPopulated(); - if($lightPopulatedState !== true){ - if($lightPopulatedState === false){ - $this->chunks[$hash]->setLightPopulated(null); - - $this->workerPool->submitTask(new LightPopulationTask( - $this->chunks[$hash], - function(array $blockLight, array $skyLight, array $heightMap) use ($dx, $chunkX, $dz, $chunkZ) : void{ - /** - * TODO: phpstan can't infer these types yet :( - * @phpstan-var array $blockLight - * @phpstan-var array $skyLight - * @phpstan-var array $heightMap - */ - if($this->closed || ($chunk = $this->getChunk($dx + $chunkX, $dz + $chunkZ)) === null || $chunk->isLightPopulated() === true){ - return; - } - //TODO: calculated light information might not be valid if the terrain changed during light calculation - - $chunk->setHeightMapArray($heightMap); - foreach($blockLight as $y => $lightArray){ - $chunk->getSubChunk($y)->setBlockLightArray($lightArray); - } - foreach($skyLight as $y => $lightArray){ - $chunk->getSubChunk($y)->setBlockSkyLightArray($lightArray); - } - $chunk->setLightPopulated(true); - } - )); - } - continue; - } - //check adjacent chunks are loaded - for($cx = -1; $cx <= 1; ++$cx){ - for($cz = -1; $cz <= 1; ++$cz){ - if(!isset($this->chunks[World::chunkHash($chunkX + $dx + $cx, $chunkZ + $dz + $cz)])){ - continue 3; - } - } - } + if(!isset($chunkTickList[$hash]) and isset($this->chunks[$hash]) and $this->isChunkTickable($dx + $chunkX, $dz + $chunkZ)){ $chunkTickList[$hash] = true; } } @@ -1081,6 +1034,66 @@ class World implements ChunkManager{ } } + private function isChunkTickable(int $chunkX, int $chunkZ) : bool{ + $chunkHash = World::chunkHash($chunkX, $chunkZ); + if( + !$this->chunks[$chunkHash]->isPopulated() || + $this->isChunkLocked($chunkX, $chunkZ) + ){ + return false; + } + //TODO: this might need to be checked after adjacent chunks are loaded in future + $lightPopulatedState = $this->chunks[$chunkHash]->isLightPopulated(); + if($lightPopulatedState !== true){ + $this->orderLightPopulation($chunkX, $chunkZ); + return false; + } + //check adjacent chunks are loaded + for($cx = -1; $cx <= 1; ++$cx){ + for($cz = -1; $cz <= 1; ++$cz){ + if(!isset($this->chunks[World::chunkHash($chunkX + $cx, $chunkZ + $cz)])){ + return false; + } + } + } + + return true; + } + + private function orderLightPopulation(int $chunkX, int $chunkZ) : void{ + $chunkHash = World::chunkHash($chunkX, $chunkZ); + //TODO: this might need to be checked after adjacent chunks are loaded in future + $lightPopulatedState = $this->chunks[$chunkHash]->isLightPopulated(); + if($lightPopulatedState === false){ + $this->chunks[$chunkHash]->setLightPopulated(null); + + $this->workerPool->submitTask(new LightPopulationTask( + $this->chunks[$chunkHash], + function(array $blockLight, array $skyLight, array $heightMap) use ($chunkX, $chunkZ) : void{ + /** + * TODO: phpstan can't infer these types yet :( + * @phpstan-var array $blockLight + * @phpstan-var array $skyLight + * @phpstan-var array $heightMap + */ + if($this->closed || ($chunk = $this->getChunk($chunkX, $chunkZ)) === null || $chunk->isLightPopulated() === true){ + return; + } + //TODO: calculated light information might not be valid if the terrain changed during light calculation + + $chunk->setHeightMapArray($heightMap); + foreach($blockLight as $y => $lightArray){ + $chunk->getSubChunk($y)->setBlockLightArray($lightArray); + } + foreach($skyLight as $y => $lightArray){ + $chunk->getSubChunk($y)->setBlockSkyLightArray($lightArray); + } + $chunk->setLightPopulated(true); + } + )); + } + } + /** * @return mixed[] */ From 7abf50f50374ca984cd7665139202a1e89c7bf8a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 17 May 2021 20:54:51 +0100 Subject: [PATCH 2482/3224] World: Extracted a tickChunk() method from tickChunks() most of what's left in tickChunks() is just selecting the chunks, rather than actually ticking them. --- src/world/World.php | 65 +++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index ed1fe8aa88..5550d2a25b 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1002,35 +1002,7 @@ class World implements ChunkManager{ foreach($chunkTickList as $index => $_){ World::getXZ($index, $chunkX, $chunkZ); - $chunk = $this->chunks[$index]; - foreach($chunk->getEntities() as $entity){ - $entity->onRandomUpdate(); - } - - foreach($chunk->getSubChunks() as $Y => $subChunk){ - if(!$subChunk->isEmptyFast()){ - $k = 0; - for($i = 0; $i < $this->tickedBlocksPerSubchunkPerTick; ++$i){ - if(($i % 5) === 0){ - //60 bits will be used by 5 blocks (12 bits each) - $k = mt_rand(0, (1 << 60) - 1); - } - $x = $k & 0x0f; - $y = ($k >> 4) & 0x0f; - $z = ($k >> 8) & 0x0f; - $k >>= 12; - - $state = $subChunk->getFullBlock($x, $y, $z); - - if(isset($this->randomTickBlocks[$state])){ - /** @var Block $block */ - $block = BlockFactory::getInstance()->fromFullBlock($state); - $block->position($this, $chunkX * 16 + $x, ($Y << 4) + $y, $chunkZ * 16 + $z); - $block->onRandomTick(); - } - } - } - } + $this->tickChunk($chunkX, $chunkZ); } } @@ -1094,6 +1066,41 @@ class World implements ChunkManager{ } } + private function tickChunk(int $chunkX, int $chunkZ) : void{ + $chunk = $this->getChunk($chunkX, $chunkZ); + if($chunk === null){ + throw new \InvalidArgumentException("Chunk is not loaded"); + } + foreach($chunk->getEntities() as $entity){ + $entity->onRandomUpdate(); + } + + foreach($chunk->getSubChunks() as $Y => $subChunk){ + if(!$subChunk->isEmptyFast()){ + $k = 0; + for($i = 0; $i < $this->tickedBlocksPerSubchunkPerTick; ++$i){ + if(($i % 5) === 0){ + //60 bits will be used by 5 blocks (12 bits each) + $k = mt_rand(0, (1 << 60) - 1); + } + $x = $k & 0x0f; + $y = ($k >> 4) & 0x0f; + $z = ($k >> 8) & 0x0f; + $k >>= 12; + + $state = $subChunk->getFullBlock($x, $y, $z); + + if(isset($this->randomTickBlocks[$state])){ + /** @var Block $block */ + $block = BlockFactory::getInstance()->fromFullBlock($state); + $block->position($this, $chunkX * 16 + $x, ($Y << 4) + $y, $chunkZ * 16 + $z); + $block->onRandomTick(); + } + } + } + } + } + /** * @return mixed[] */ From 643c3ed14e9e5f2c8eb4fd1a384c1f1f1005f97f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 17 May 2021 20:59:40 +0100 Subject: [PATCH 2483/3224] World: Require all adjacent chunks to a ticking chunk candidate to be unlocked, generated, loaded and light-populated this should address the remaining problems with grass spread/death. --- src/world/World.php | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 5550d2a25b..e0a5d9bb02 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1007,23 +1007,18 @@ class World implements ChunkManager{ } private function isChunkTickable(int $chunkX, int $chunkZ) : bool{ - $chunkHash = World::chunkHash($chunkX, $chunkZ); - if( - !$this->chunks[$chunkHash]->isPopulated() || - $this->isChunkLocked($chunkX, $chunkZ) - ){ - return false; - } - //TODO: this might need to be checked after adjacent chunks are loaded in future - $lightPopulatedState = $this->chunks[$chunkHash]->isLightPopulated(); - if($lightPopulatedState !== true){ - $this->orderLightPopulation($chunkX, $chunkZ); - return false; - } - //check adjacent chunks are loaded for($cx = -1; $cx <= 1; ++$cx){ for($cz = -1; $cz <= 1; ++$cz){ - if(!isset($this->chunks[World::chunkHash($chunkX + $cx, $chunkZ + $cz)])){ + if($this->isChunkLocked($chunkX + $cx, $chunkZ + $cz)){ + return false; + } + $adjacentChunk = $this->getChunk($chunkX + $cx, $chunkZ + $cz); + if($adjacentChunk === null || !$adjacentChunk->isPopulated()){ + return false; + } + $lightPopulatedState = $adjacentChunk->isLightPopulated(); + if($lightPopulatedState !== true){ + $this->orderLightPopulation($chunkX + $cx, $chunkZ + $cz); return false; } } From cdaf734470a43433013d176e8e08b729dabab0d0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 17 May 2021 23:07:48 +0100 Subject: [PATCH 2484/3224] World: Clean up ticking chunk loader tracking --- src/world/World.php | 41 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index e0a5d9bb02..c035f28024 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -180,10 +180,10 @@ class World implements ChunkManager{ /** @var int */ private $maxY; - /** @var ChunkLoader[] */ - private $loaders = []; + /** @var TickingChunkLoader[] */ + private $tickingLoaders = []; /** @var int[] */ - private $loaderCounter = []; + private $tickingLoaderCounter = []; /** @var ChunkLoader[][] */ private $chunkLoaders = []; @@ -632,11 +632,13 @@ class World implements ChunkManager{ $this->chunkLoaders[$chunkHash][$loaderId] = $loader; - if(!isset($this->loaders[$loaderId])){ - $this->loaderCounter[$loaderId] = 1; - $this->loaders[$loaderId] = $loader; - }else{ - ++$this->loaderCounter[$loaderId]; + if($loader instanceof TickingChunkLoader){ + if(!isset($this->tickingLoaders[$loaderId])){ + $this->tickingLoaderCounter[$loaderId] = 1; + $this->tickingLoaders[$loaderId] = $loader; + }else{ + ++$this->tickingLoaderCounter[$loaderId]; + } } $this->cancelUnloadChunkRequest($chunkX, $chunkZ); @@ -660,9 +662,9 @@ class World implements ChunkManager{ } } - if(--$this->loaderCounter[$loaderId] === 0){ - unset($this->loaderCounter[$loaderId]); - unset($this->loaders[$loaderId]); + if(isset($this->tickingLoaderCounter[$loaderId]) && --$this->tickingLoaderCounter[$loaderId] === 0){ + unset($this->tickingLoaderCounter[$loaderId]); + unset($this->tickingLoaders[$loaderId]); } } } @@ -970,22 +972,18 @@ class World implements ChunkManager{ } private function tickChunks() : void{ - if($this->chunksPerTick <= 0 or count($this->loaders) === 0){ + if($this->chunksPerTick <= 0 or count($this->tickingLoaders) === 0){ return; } /** @var bool[] $chunkTickList chunkhash => dummy */ $chunkTickList = []; - $chunksPerLoader = min(200, max(1, (int) ((($this->chunksPerTick - count($this->loaders)) / count($this->loaders)) + 0.5))); + $chunksPerLoader = min(200, max(1, (int) ((($this->chunksPerTick - count($this->tickingLoaders)) / count($this->tickingLoaders)) + 0.5))); $randRange = 3 + $chunksPerLoader / 30; $randRange = (int) ($randRange > $this->chunkTickRadius ? $this->chunkTickRadius : $randRange); - foreach($this->loaders as $loader){ - if(!($loader instanceof TickingChunkLoader)){ - //TODO: maybe we should just not track non-ticking chunk loaders here? - continue; - } + foreach($this->tickingLoaders as $loader){ $chunkX = (int) floor($loader->getX()) >> 4; $chunkZ = (int) floor($loader->getZ()) >> 4; @@ -1980,13 +1978,6 @@ class World implements ChunkManager{ return $this->players; } - /** - * @return ChunkLoader[] - */ - public function getLoaders() : array{ - return $this->loaders; - } - /** * Returns the Tile in a position, or null if not found. * From 4736b5968df827b10e1459774510628450e71ac1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 17 May 2021 23:14:30 +0100 Subject: [PATCH 2485/3224] WorldTimings: change some idiotic timer names --- src/world/World.php | 8 ++++---- src/world/WorldTimings.php | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index c035f28024..7401ecb946 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -786,7 +786,7 @@ class World implements ChunkManager{ } //Do block updates - $this->timings->doTickPending->startTiming(); + $this->timings->scheduledBlockUpdates->startTiming(); //Delayed updates while($this->scheduledBlockUpdateQueue->count() > 0 and $this->scheduledBlockUpdateQueue->current()["priority"] <= $currentTick){ @@ -822,7 +822,7 @@ class World implements ChunkManager{ unset($this->neighbourBlockUpdateQueueIndex[$index]); } - $this->timings->doTickPending->stopTiming(); + $this->timings->scheduledBlockUpdates->stopTiming(); $this->timings->entityTick->startTiming(); //Update entities that need update @@ -838,9 +838,9 @@ class World implements ChunkManager{ Timings::$tickEntity->stopTiming(); $this->timings->entityTick->stopTiming(); - $this->timings->doTickTiles->startTiming(); + $this->timings->randomChunkUpdates->startTiming(); $this->tickChunks(); - $this->timings->doTickTiles->stopTiming(); + $this->timings->randomChunkUpdates->stopTiming(); $this->executeQueuedLightUpdates(); diff --git a/src/world/WorldTimings.php b/src/world/WorldTimings.php index c3e6e98b23..012301f526 100644 --- a/src/world/WorldTimings.php +++ b/src/world/WorldTimings.php @@ -38,9 +38,9 @@ class WorldTimings{ /** @var TimingsHandler */ public $doChunkUnload; /** @var TimingsHandler */ - public $doTickPending; + public $scheduledBlockUpdates; /** @var TimingsHandler */ - public $doTickTiles; + public $randomChunkUpdates; /** @var TimingsHandler */ public $doChunkGC; /** @var TimingsHandler */ @@ -72,8 +72,8 @@ class WorldTimings{ $this->doBlockSkyLightUpdates = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Sky Light Updates"); $this->doChunkUnload = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Unload Chunks"); - $this->doTickPending = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Scheduled Block Updates"); - $this->doTickTiles = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Random Chunk Updates"); + $this->scheduledBlockUpdates = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Scheduled Block Updates"); + $this->randomChunkUpdates = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Random Chunk Updates"); $this->doChunkGC = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Garbage Collection"); $this->entityTick = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Tick Entities"); From 7217ff5ff55f3af6b3b7a22afa5ea4666b65c3ce Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 17 May 2021 23:18:56 +0100 Subject: [PATCH 2486/3224] World: added an extra subtiming for random chunk updates --- src/world/World.php | 4 ++++ src/world/WorldTimings.php | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index 7401ecb946..d7df6bf09a 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -976,6 +976,8 @@ class World implements ChunkManager{ return; } + $this->timings->randomChunkUpdatesChunkSelection->startTiming(); + /** @var bool[] $chunkTickList chunkhash => dummy */ $chunkTickList = []; @@ -997,6 +999,8 @@ class World implements ChunkManager{ } } + $this->timings->randomChunkUpdatesChunkSelection->stopTiming(); + foreach($chunkTickList as $index => $_){ World::getXZ($index, $chunkX, $chunkZ); diff --git a/src/world/WorldTimings.php b/src/world/WorldTimings.php index 012301f526..9a5ad804c8 100644 --- a/src/world/WorldTimings.php +++ b/src/world/WorldTimings.php @@ -41,6 +41,7 @@ class WorldTimings{ public $scheduledBlockUpdates; /** @var TimingsHandler */ public $randomChunkUpdates; + public TimingsHandler $randomChunkUpdatesChunkSelection; /** @var TimingsHandler */ public $doChunkGC; /** @var TimingsHandler */ @@ -74,6 +75,7 @@ class WorldTimings{ $this->doChunkUnload = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Unload Chunks"); $this->scheduledBlockUpdates = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Scheduled Block Updates"); $this->randomChunkUpdates = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Random Chunk Updates"); + $this->randomChunkUpdatesChunkSelection = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Random Chunk Updates - Chunk Selection"); $this->doChunkGC = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Garbage Collection"); $this->entityTick = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Tick Entities"); From e4750ad2cd1142f2ae30b081d3786dfcc2ecedd4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 17 May 2021 23:23:46 +0100 Subject: [PATCH 2487/3224] WorldTimings: apply native typehints --- src/world/WorldTimings.php | 48 +++++++++++++------------------------- 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/src/world/WorldTimings.php b/src/world/WorldTimings.php index 9a5ad804c8..2ace793179 100644 --- a/src/world/WorldTimings.php +++ b/src/world/WorldTimings.php @@ -28,42 +28,26 @@ use pocketmine\timings\TimingsHandler; class WorldTimings{ - /** @var TimingsHandler */ - public $setBlock; - /** @var TimingsHandler */ - public $doBlockLightUpdates; - /** @var TimingsHandler */ - public $doBlockSkyLightUpdates; + public TimingsHandler $setBlock; + public TimingsHandler $doBlockLightUpdates; + public TimingsHandler $doBlockSkyLightUpdates; - /** @var TimingsHandler */ - public $doChunkUnload; - /** @var TimingsHandler */ - public $scheduledBlockUpdates; - /** @var TimingsHandler */ - public $randomChunkUpdates; + public TimingsHandler $doChunkUnload; + public TimingsHandler $scheduledBlockUpdates; + public TimingsHandler $randomChunkUpdates; public TimingsHandler $randomChunkUpdatesChunkSelection; - /** @var TimingsHandler */ - public $doChunkGC; - /** @var TimingsHandler */ - public $entityTick; - /** @var TimingsHandler */ - public $doTick; + public TimingsHandler $doChunkGC; + public TimingsHandler $entityTick; + public TimingsHandler $doTick; - /** @var TimingsHandler */ - public $syncChunkSend; - /** @var TimingsHandler */ - public $syncChunkSendPrepare; + public TimingsHandler $syncChunkSend; + public TimingsHandler $syncChunkSendPrepare; - /** @var TimingsHandler */ - public $syncChunkLoad; - /** @var TimingsHandler */ - public $syncChunkLoadData; - /** @var TimingsHandler */ - public $syncChunkLoadEntities; - /** @var TimingsHandler */ - public $syncChunkLoadTileEntities; - /** @var TimingsHandler */ - public $syncChunkSave; + public TimingsHandler $syncChunkLoad; + public TimingsHandler $syncChunkLoadData; + public TimingsHandler $syncChunkLoadEntities; + public TimingsHandler $syncChunkLoadTileEntities; + public TimingsHandler $syncChunkSave; public function __construct(World $world){ $name = $world->getFolderName() . " - "; From f5da91b42a997da189937cde7ccb0401220c5302 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 17 May 2021 23:49:47 +0100 Subject: [PATCH 2488/3224] changelog: added a Configuration section this might be incomplete. [ci skip] --- changelogs/4.0-snapshot.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index d0d5ee5ed6..9ee46b2bbb 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -5,6 +5,7 @@ This major version features substantial changes throughout the core, including s ## Contents * [Core](#core) + [General](#general) + + [Configuration](#configuration) + [World handling](#world-handling) - [Interface](#interface) - [Functional](#functional) @@ -64,7 +65,7 @@ This major version features substantial changes throughout the core, including s - Remote console (RCON) has been removed. The [RconServer](https://github.com/pmmp/RconServer) plugin is provided as a substitute. - Spawn protection has been removed. The [BasicSpawnProtection](https://github.com/pmmp/BasicSpawnProtection) plugin is provided as a substitute. - CTRL+C signal handling has been removed. The [PcntlSignalHandler](https://github.com/pmmp/PcntlSignalHandler) plugin is provided as a substitute. -- Player movement anti-cheat has been removed. Its corresponding `pocketmine.yml` setting `player.anti-cheat.allow-movement-cheats` has been removed. +- Player movement anti-cheat has been removed. - GS4 Query no longer breaks when disabling RakLib. - The `pocketmine_chunkutils` PHP extension has been dropped. - New PHP extensions are required by this version: @@ -76,6 +77,15 @@ This major version features substantial changes throughout the core, including s - Spawning inside blocks (or above the ground) when respawning with a custom spawn position set - Player spawn positions sticking to the old location when world spawn position changed - this was because the world spawn at time of player creation was used as the player's custom spawn, so the bug will persist for older player data, but will work as expected for new players. +### Configuration +- World presets can now be provided as a `preset` key in `pocketmine.yml`, instead of putting them in the `generator` key. +- The following new options have been added to `pocketmine.yml`: + - `chunk-ticking.blocks-per-subchunk-per-tick` (default `3`): Increasing this value will increase the rate at which random block updates happen (e.g. grass growth). + - `network.enable-encryption` (default `true`): Controls whether Minecraft network packets are encrypted or not. +- The following options have been removed from `pocketmine.yml`: + - `chunk-ticking.light-updates`: Since lighting is needed for basic vanilla functionality to work, allowing this to be disabled without disabling chunk ticking made no sense. If you don't want light calculation to occur, you can disable chunk ticking altogether. + - `player.anti-cheat.allow-movement-cheats` + ### World handling #### Interface - Progress of spawn terrain chunk generation is now logged during initial world creation. From 1d8680aaa988fdee29175d394d94b8127fe298a9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 18 May 2021 23:25:19 +0100 Subject: [PATCH 2489/3224] Update to released versions of BinaryUtils, Log, LogPthreads, NBT, RakLib and RakLibIpc these all had to be updated in tandem because of the dependency tree - RakLib, RakLibIpc and NBT -> BinaryUtils, RakLib and LogPthreads -> Log, RakLibIpc -> RakLib. --- composer.json | 12 +++--- composer.lock | 111 +++++++++++++++++++++++--------------------------- 2 files changed, 58 insertions(+), 65 deletions(-) diff --git a/composer.json b/composer.json index 0b804c8a56..1f6dc380dc 100644 --- a/composer.json +++ b/composer.json @@ -34,17 +34,17 @@ "adhocore/json-comment": "^1.1", "mdanter/ecc": "^1.0", "netresearch/jsonmapper": "^4.0", - "pocketmine/binaryutils": "dev-master", + "pocketmine/binaryutils": "^0.2.0", "pocketmine/callback-validator": "^1.0.2", "pocketmine/classloader": "dev-master", "pocketmine/color": "^0.2.0", "pocketmine/errorhandler": "^0.3.0", - "pocketmine/log": "dev-master", - "pocketmine/log-pthreads": "dev-master", + "pocketmine/log": "^0.3.0", + "pocketmine/log-pthreads": "^0.2.0", "pocketmine/math": "dev-master", - "pocketmine/nbt": "dev-master", - "pocketmine/raklib": "dev-master", - "pocketmine/raklib-ipc": "dev-master", + "pocketmine/nbt": "^0.3.0", + "pocketmine/raklib": "^0.13.1", + "pocketmine/raklib-ipc": "^0.1.0", "pocketmine/snooze": "^0.1.0", "pocketmine/spl": "dev-master", "ramsey/uuid": "^4.1", diff --git a/composer.lock b/composer.lock index b4471cb4f2..631c798fed 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "04e955ce26ffda03098344659abcf0e0", + "content-hash": "f2a4e10d62b3a989bac574ac65555ad2", "packages": [ { "name": "adhocore/json-comment", @@ -321,25 +321,25 @@ }, { "name": "pocketmine/binaryutils", - "version": "dev-master", + "version": "0.2.0", "source": { "type": "git", "url": "https://github.com/pmmp/BinaryUtils.git", - "reference": "5959ad1259341fceeed080704a0c5a91ed5a8049" + "reference": "595c4ca4b8056777729c8cc5db9614c731eaf63b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/5959ad1259341fceeed080704a0c5a91ed5a8049", - "reference": "5959ad1259341fceeed080704a0c5a91ed5a8049", + "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/595c4ca4b8056777729c8cc5db9614c731eaf63b", + "reference": "595c4ca4b8056777729c8cc5db9614c731eaf63b", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", + "php": "^7.4 || ^8.0", "php-64bit": "*" }, "require-dev": { "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "0.12.67", + "phpstan/phpstan": "0.12.85", "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", @@ -355,9 +355,9 @@ "description": "Classes and methods for conveniently handling binary data", "support": { "issues": "https://github.com/pmmp/BinaryUtils/issues", - "source": "https://github.com/pmmp/BinaryUtils/tree/master" + "source": "https://github.com/pmmp/BinaryUtils/tree/0.2.0" }, - "time": "2021-01-15T14:19:25+00:00" + "time": "2021-05-18T15:23:45+00:00" }, { "name": "pocketmine/callback-validator", @@ -532,26 +532,26 @@ }, { "name": "pocketmine/log", - "version": "dev-master", + "version": "0.3.0", "source": { "type": "git", "url": "https://github.com/pmmp/Log.git", - "reference": "2b514ca0a3143e1d5dbfa30bdf9f7497611bbbda" + "reference": "03ab1316da0b1978a7a1c8dd73e1c2a973cb62ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Log/zipball/2b514ca0a3143e1d5dbfa30bdf9f7497611bbbda", - "reference": "2b514ca0a3143e1d5dbfa30bdf9f7497611bbbda", + "url": "https://api.github.com/repos/pmmp/Log/zipball/03ab1316da0b1978a7a1c8dd73e1c2a973cb62ec", + "reference": "03ab1316da0b1978a7a1c8dd73e1c2a973cb62ec", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "php": "^7.4 || ^8.0" }, "conflict": { "pocketmine/spl": "<0.4" }, "require-dev": { - "phpstan/phpstan": "0.12.67", + "phpstan/phpstan": "0.12.80", "phpstan/phpstan-strict-rules": "^0.12.2" }, "type": "library", @@ -567,35 +567,35 @@ "description": "Logging components used by PocketMine-MP and related projects", "support": { "issues": "https://github.com/pmmp/Log/issues", - "source": "https://github.com/pmmp/Log/tree/master" + "source": "https://github.com/pmmp/Log/tree/0.3.0" }, - "time": "2021-01-15T14:33:25+00:00" + "time": "2021-05-18T21:00:49+00:00" }, { "name": "pocketmine/log-pthreads", - "version": "dev-master", + "version": "0.2.0", "source": { "type": "git", "url": "https://github.com/pmmp/LogPthreads.git", - "reference": "271ff55ee7cba80b9368d924f3a4c6093a2577fb" + "reference": "6be3445c48c62eba3922f987f000bb20c81d161f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/271ff55ee7cba80b9368d924f3a4c6093a2577fb", - "reference": "271ff55ee7cba80b9368d924f3a4c6093a2577fb", + "url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/6be3445c48c62eba3922f987f000bb20c81d161f", + "reference": "6be3445c48c62eba3922f987f000bb20c81d161f", "shasum": "" }, "require": { "ext-pthreads": "~3.2.0", - "php": "^7.2 || ^8.0", - "pocketmine/log": "^0.2.0 || dev-master" + "php": "^7.4 || ^8.0", + "pocketmine/log": "^0.2.0 || ^0.3.0" }, "conflict": { "pocketmine/spl": "<0.4" }, "require-dev": { "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "0.12.71", + "phpstan/phpstan": "0.12.88", "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", @@ -611,9 +611,9 @@ "description": "Logging components specialized for pthreads used by PocketMine-MP and related projects", "support": { "issues": "https://github.com/pmmp/LogPthreads/issues", - "source": "https://github.com/pmmp/LogPthreads/tree/master" + "source": "https://github.com/pmmp/LogPthreads/tree/0.2.0" }, - "time": "2021-02-04T16:22:31+00:00" + "time": "2021-05-18T22:15:28+00:00" }, { "name": "pocketmine/math", @@ -658,25 +658,25 @@ }, { "name": "pocketmine/nbt", - "version": "dev-master", + "version": "0.3.0", "source": { "type": "git", "url": "https://github.com/pmmp/NBT.git", - "reference": "34bc0cb2f0cc9553ca1a34c5d9d008f914959dd8" + "reference": "98c4a04b55a915e18f83d3b0c9beb24a71abcd31" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/NBT/zipball/34bc0cb2f0cc9553ca1a34c5d9d008f914959dd8", - "reference": "34bc0cb2f0cc9553ca1a34c5d9d008f914959dd8", + "url": "https://api.github.com/repos/pmmp/NBT/zipball/98c4a04b55a915e18f83d3b0c9beb24a71abcd31", + "reference": "98c4a04b55a915e18f83d3b0c9beb24a71abcd31", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", + "php": "^7.4 || ^8.0", "php-64bit": "*", - "pocketmine/binaryutils": "dev-master" + "pocketmine/binaryutils": "^0.2.0" }, "require-dev": { - "irstea/phpunit-shim": "^7.5 || ^8.0", + "irstea/phpunit-shim": "^9.5", "phpstan/extension-installer": "^1.0", "phpstan/phpstan": "0.12.85", "phpstan/phpstan-strict-rules": "^0.12.4" @@ -694,22 +694,22 @@ "description": "PHP library for working with Named Binary Tags", "support": { "issues": "https://github.com/pmmp/NBT/issues", - "source": "https://github.com/pmmp/NBT/tree/master" + "source": "https://github.com/pmmp/NBT/tree/0.3.0" }, - "time": "2021-05-05T18:39:10+00:00" + "time": "2021-05-18T15:46:33+00:00" }, { "name": "pocketmine/raklib", - "version": "dev-master", + "version": "0.13.1", "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "6c83e0f50e71f654cf24a7d883ee0561e269483a" + "reference": "0b2b84f894adebe6a746237f9cc36d80cc4227ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/6c83e0f50e71f654cf24a7d883ee0561e269483a", - "reference": "6c83e0f50e71f654cf24a7d883ee0561e269483a", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/0b2b84f894adebe6a746237f9cc36d80cc4227ab", + "reference": "0b2b84f894adebe6a746237f9cc36d80cc4227ab", "shasum": "" }, "require": { @@ -717,11 +717,11 @@ "php": "^7.4 || ^8.0", "php-64bit": "*", "php-ipv6": "*", - "pocketmine/binaryutils": "dev-master", - "pocketmine/log": "dev-master" + "pocketmine/binaryutils": "^0.2.0", + "pocketmine/log": "^0.3.0" }, "require-dev": { - "phpstan/phpstan": "0.12.85", + "phpstan/phpstan": "0.12.88", "phpstan/phpstan-strict-rules": "^0.12.2" }, "type": "library", @@ -737,35 +737,34 @@ "description": "A RakNet server implementation written in PHP", "support": { "issues": "https://github.com/pmmp/RakLib/issues", - "source": "https://github.com/pmmp/RakLib/tree/master" + "source": "https://github.com/pmmp/RakLib/tree/0.13.1" }, - "time": "2021-05-08T19:24:13+00:00" + "time": "2021-05-18T21:14:20+00:00" }, { "name": "pocketmine/raklib-ipc", - "version": "dev-master", + "version": "0.1.0", "source": { "type": "git", "url": "https://github.com/pmmp/RakLibIpc.git", - "reference": "cde9f0d0c0a742684ea44cbbc94e8aca97e693cc" + "reference": "85f1a4834e34abd6d77f622f14731e8ef06dc7cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLibIpc/zipball/cde9f0d0c0a742684ea44cbbc94e8aca97e693cc", - "reference": "cde9f0d0c0a742684ea44cbbc94e8aca97e693cc", + "url": "https://api.github.com/repos/pmmp/RakLibIpc/zipball/85f1a4834e34abd6d77f622f14731e8ef06dc7cf", + "reference": "85f1a4834e34abd6d77f622f14731e8ef06dc7cf", "shasum": "" }, "require": { "php": "^7.4 || ^8.0", "php-64bit": "*", - "pocketmine/binaryutils": "dev-master", - "pocketmine/raklib": "dev-master" + "pocketmine/binaryutils": "^0.2.0", + "pocketmine/raklib": "^0.13.1" }, "require-dev": { "phpstan/phpstan": "0.12.81", "phpstan/phpstan-strict-rules": "^0.12.2" }, - "default-branch": true, "type": "library", "autoload": { "psr-4": { @@ -779,9 +778,9 @@ "description": "Channel-based protocols for inter-thread/inter-process communication with RakLib", "support": { "issues": "https://github.com/pmmp/RakLibIpc/issues", - "source": "https://github.com/pmmp/RakLibIpc/tree/master" + "source": "https://github.com/pmmp/RakLibIpc/tree/0.1.0" }, - "time": "2021-05-05T20:36:08+00:00" + "time": "2021-05-18T21:19:03+00:00" }, { "name": "pocketmine/snooze", @@ -3496,14 +3495,8 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "pocketmine/binaryutils": 20, "pocketmine/classloader": 20, - "pocketmine/log": 20, - "pocketmine/log-pthreads": 20, "pocketmine/math": 20, - "pocketmine/nbt": 20, - "pocketmine/raklib": 20, - "pocketmine/raklib-ipc": 20, "pocketmine/spl": 20 }, "prefer-stable": false, From 4122517292515a1cf1a73979d1e510a3a7940a7f Mon Sep 17 00:00:00 2001 From: Dylan T Date: Tue, 18 May 2021 23:51:58 +0100 Subject: [PATCH 2490/3224] [ci skip] update changelog --- changelogs/4.0-snapshot.md | 152 +++++++++++++++++++++++++------------ 1 file changed, 103 insertions(+), 49 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 9ee46b2bbb..ae880b7258 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -3,55 +3,58 @@ This major version features substantial changes throughout the core, including significant API changes, new world format support, performance improvements and a network revamp. ## Contents -* [Core](#core) - + [General](#general) - + [Configuration](#configuration) - + [World handling](#world-handling) - - [Interface](#interface) - - [Functional](#functional) - - [Performance](#performance) - + [Logger revamp](#logger-revamp) - + [Network](#network) - - [Minecraft Bedrock packet encryption](#minecraft-bedrock-packet-encryption) - - [Packet receive error handling has been overhauled](#packet-receive-error-handling-has-been-overhauled) - - [New packet handler system](#new-packet-handler-system) -* [API](#api) - + [General](#general-1) - + [Block](#block) - + [Command](#command) - + [Entity](#entity) - - [General](#general-2) - - [Effect](#effect) - - [Removal of runtime entity NBT](#removal-of-runtime-entity-nbt) - - [Entity creation](#entity-creation) - - [WIP removal of entity network metadata](#wip-removal-of-entity-network-metadata) - + [Event](#event) - - [Internal event system no longer depends on `Listener`s](#internal-event-system-no-longer-depends-on-listeners) - - [Default cancelled handling behaviour has changed](#default-cancelled-handling-behaviour-has-changed) - - [`PlayerPreLoginEvent` changes](#playerpreloginevent-changes) - - [Other changes](#other-changes) - + [Inventory](#inventory) - + [Item](#item) - - [General](#general-3) - - [NBT handling](#nbt-handling) - - [Enchantment](#enchantment) - + [Lang](#lang) - + [Network](#network-1) - + [Permission](#permission) - + [Player](#player) - + [Plugin](#plugin) - + [Scheduler](#scheduler) - - [Thread-local storage for AsyncTasks](#thread-local-storage-for-asynctasks) - - [Other changes](#other-changes-1) - + [Server](#server) - + [Level / World](#level---world) - - [General](#general-4) - - [Particles](#particles) - - [Sounds](#sounds) - + [Utils](#utils) -* [Gameplay](#gameplay) - + [Blocks](#blocks) - + [Items](#items) + * [Core](#core) + + [General](#general) + + [Configuration](#configuration) + + [World handling](#world-handling) + - [Interface](#interface) + - [Functional](#functional) + - [Performance](#performance) + + [Logger revamp](#logger-revamp) + + [Network](#network) + - [Minecraft Bedrock packet encryption](#minecraft-bedrock-packet-encryption) + - [Packet receive error handling has been overhauled](#packet-receive-error-handling-has-been-overhauled) + - [New packet handler system](#new-packet-handler-system) + * [API](#api) + + [General](#general-1) + + [Changes to `plugin.yml`](#changes-to-pluginyml) + - [Permission nesting](#permission-nesting) + - [`src-namespace-prefix`](#src-namespace-prefix) + + [Block](#block) + + [Command](#command) + + [Entity](#entity) + - [General](#general-2) + - [Effect](#effect) + - [Removal of runtime entity NBT](#removal-of-runtime-entity-nbt) + - [Entity creation](#entity-creation) + - [WIP removal of entity network metadata](#wip-removal-of-entity-network-metadata) + + [Event](#event) + - [Internal event system no longer depends on `Listener`s](#internal-event-system-no-longer-depends-on-listeners) + - [Default cancelled handling behaviour has changed](#default-cancelled-handling-behaviour-has-changed) + - [`PlayerPreLoginEvent` changes](#playerpreloginevent-changes) + - [Other changes](#other-changes) + + [Inventory](#inventory) + + [Item](#item) + - [General](#general-3) + - [NBT handling](#nbt-handling) + - [Enchantment](#enchantment) + + [Lang](#lang) + + [Network](#network-1) + + [Permission](#permission) + + [Player](#player) + + [Plugin](#plugin) + + [Scheduler](#scheduler) + - [Thread-local storage for AsyncTasks](#thread-local-storage-for-asynctasks) + - [Other changes](#other-changes-1) + + [Server](#server) + + [Level / World](#level--world) + - [General](#general-4) + - [Particles](#particles) + - [Sounds](#sounds) + + [Utils](#utils) + * [Gameplay](#gameplay) + + [Blocks](#blocks) + + [Items](#items) Table of contents generated with markdown-toc @@ -145,6 +148,57 @@ This version features substantial changes to the network system, improving coher - `void` and `?nullable` parameter and return types have been applied in many places. - Everything in the `pocketmine\metadata` namespace and related implementations have been removed. +### Changes to `plugin.yml` +#### Permission nesting +Permission nesting is no longer supported in `plugin.yml`. Grouping permissions (with defaults) in `plugin.yml` had very confusing and inconsistent behaviour. +Instead of nesting permission declarations, they should each be declared separately. + +_Before_: +``` +permissions: + pmmp: + default: op + children: + pmmp.something: + default: op + pmmp.somethingElse + default: op +``` + +_After_: +``` +permissions: + pmmp.something: + default: op + pmmp.somethingElse + default: op +``` + +#### `src-namespace-prefix` +A new directive `src-namespace-prefix` has been introduced. This allows you to get rid of those useless subdirectories in a plugin's structure. +For example, a plugin whose main was `pmmp\TesterPlugin\Main` used to have to be structured like this: +``` +|-- plugin.yml +|-- src/ + |-- pmmp/ + |-- TesterPlugin/ + |-- Main.php + |-- SomeOtherClass.php + |-- SomeNamespace/ + |-- SomeNamespacedClass.php +``` +However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml`, now we can get rid of the useless directories and structure it like this instead: +``` +|-- plugin.yml +|-- src/ + |-- Main.php + |-- SomeOtherClass.php + |-- SomeNamespace/ + |-- SomeNamespacedClass.php +``` + +**Note**: The old structure will also still work just fine. This is not a required change. + ### Block - A new `VanillaBlocks` class has been added, which contains static methods for creating any currently-known block type. This should be preferred instead of use of `BlockFactory::get()` where constants were used. - Blocks now contain their positions instead of extending `Position`. `Block->getPos()` has been added. From f8cfa191ddc513c6d9007bed6d3ca26e81f7427c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 May 2021 00:16:30 +0100 Subject: [PATCH 2491/3224] Fixed confusing hierarchy of BlockGrow/Form/SpreadEvent, closes #2792 --- src/event/block/BaseBlockChangeEvent.php | 46 ++++++++++++++++++++++++ src/event/block/BlockFormEvent.php | 2 +- src/event/block/BlockGrowEvent.php | 16 +-------- src/event/block/BlockSpreadEvent.php | 2 +- 4 files changed, 49 insertions(+), 17 deletions(-) create mode 100644 src/event/block/BaseBlockChangeEvent.php diff --git a/src/event/block/BaseBlockChangeEvent.php b/src/event/block/BaseBlockChangeEvent.php new file mode 100644 index 0000000000..1c01e629cf --- /dev/null +++ b/src/event/block/BaseBlockChangeEvent.php @@ -0,0 +1,46 @@ +newState = $newState; + } + + public function getNewState() : Block{ + return $this->newState; + } +} diff --git a/src/event/block/BlockFormEvent.php b/src/event/block/BlockFormEvent.php index 0f1602d91f..7027d572a1 100644 --- a/src/event/block/BlockFormEvent.php +++ b/src/event/block/BlockFormEvent.php @@ -23,6 +23,6 @@ declare(strict_types=1); namespace pocketmine\event\block; -class BlockFormEvent extends BlockGrowEvent{ +class BlockFormEvent extends BaseBlockChangeEvent{ } diff --git a/src/event/block/BlockGrowEvent.php b/src/event/block/BlockGrowEvent.php index 8786fd4523..09389acbc6 100644 --- a/src/event/block/BlockGrowEvent.php +++ b/src/event/block/BlockGrowEvent.php @@ -23,25 +23,11 @@ declare(strict_types=1); namespace pocketmine\event\block; -use pocketmine\block\Block; use pocketmine\event\Cancellable; -use pocketmine\event\CancellableTrait; /** * Called when plants or crops grow. */ -class BlockGrowEvent extends BlockEvent implements Cancellable{ - use CancellableTrait; +class BlockGrowEvent extends BaseBlockChangeEvent implements Cancellable{ - /** @var Block */ - private $newState; - - public function __construct(Block $block, Block $newState){ - parent::__construct($block); - $this->newState = $newState; - } - - public function getNewState() : Block{ - return $this->newState; - } } diff --git a/src/event/block/BlockSpreadEvent.php b/src/event/block/BlockSpreadEvent.php index 098e2d6d91..bd2517d198 100644 --- a/src/event/block/BlockSpreadEvent.php +++ b/src/event/block/BlockSpreadEvent.php @@ -28,7 +28,7 @@ use pocketmine\block\Block; /** * Called when a block spreads to another block, such as grass spreading to nearby dirt blocks. */ -class BlockSpreadEvent extends BlockFormEvent{ +class BlockSpreadEvent extends BaseBlockChangeEvent{ /** @var Block */ private $source; From 69fa8e8db705adb9d1a45f1dac4835d03a1b83ef Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 May 2021 00:17:32 +0100 Subject: [PATCH 2492/3224] Added documentation to BlockFormEvent --- src/event/block/BlockFormEvent.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/event/block/BlockFormEvent.php b/src/event/block/BlockFormEvent.php index 7027d572a1..f955319c0a 100644 --- a/src/event/block/BlockFormEvent.php +++ b/src/event/block/BlockFormEvent.php @@ -23,6 +23,10 @@ declare(strict_types=1); namespace pocketmine\event\block; +/** + * Called when a new block forms, usually as the result of some action. + * This could be things like obsidian forming due to collision of lava and water. + */ class BlockFormEvent extends BaseBlockChangeEvent{ } From 821c9c550baef753deebd2ec79789ff632868953 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Wed, 19 May 2021 00:48:25 +0100 Subject: [PATCH 2493/3224] github web editor sucks --- changelogs/4.0-snapshot.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index ae880b7258..a8da1fce00 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -183,9 +183,9 @@ For example, a plugin whose main was `pmmp\TesterPlugin\Main` used to have to be |-- pmmp/ |-- TesterPlugin/ |-- Main.php - |-- SomeOtherClass.php - |-- SomeNamespace/ - |-- SomeNamespacedClass.php + |-- SomeOtherClass.php + |-- SomeNamespace/ + |-- SomeNamespacedClass.php ``` However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml`, now we can get rid of the useless directories and structure it like this instead: ``` @@ -193,7 +193,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` |-- src/ |-- Main.php |-- SomeOtherClass.php - |-- SomeNamespace/ + |-- SomeNamespace/ |-- SomeNamespacedClass.php ``` From 4a367b4b0e15edfc7c8bb01def887930e3b8cb4a Mon Sep 17 00:00:00 2001 From: Dylan T Date: Wed, 19 May 2021 00:49:10 +0100 Subject: [PATCH 2494/3224] ... --- changelogs/4.0-snapshot.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index a8da1fce00..19a40950f4 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -194,7 +194,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` |-- Main.php |-- SomeOtherClass.php |-- SomeNamespace/ - |-- SomeNamespacedClass.php + |-- SomeNamespacedClass.php ``` **Note**: The old structure will also still work just fine. This is not a required change. From af678f985d907b29fd01379710dc7185cbca3b24 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 19 May 2021 22:49:44 +0100 Subject: [PATCH 2495/3224] All types of coral now have fully dynamic types --- src/block/BaseCoral.php | 10 +++- src/block/BlockFactory.php | 59 ++++++++----------- src/block/BlockIdentifierFlattened.php | 28 +++++++-- src/block/BlockLegacyIdHelper.php | 14 +---- src/block/BlockLegacyMetadata.php | 2 + src/block/Coral.php | 22 +++++++ src/block/FloorCoralFan.php | 18 ++++-- src/block/VanillaBlocks.php | 36 ++--------- src/block/WallCoralFan.php | 55 ++++++++++++++++- src/item/ItemFactory.php | 11 ++-- .../block_factory_consistency_check.json | 2 +- 11 files changed, 161 insertions(+), 96 deletions(-) diff --git a/src/block/BaseCoral.php b/src/block/BaseCoral.php index 68b5e4d0ed..99af72324c 100644 --- a/src/block/BaseCoral.php +++ b/src/block/BaseCoral.php @@ -31,13 +31,19 @@ abstract class BaseCoral extends Transparent{ protected CoralType $coralType; protected bool $dead = false; - public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo, CoralType $coralType){ + public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ parent::__construct($idInfo, $name, $breakInfo); - $this->coralType = $coralType; + $this->coralType = CoralType::TUBE(); } public function getCoralType() : CoralType{ return $this->coralType; } + /** @return $this */ + public function setCoralType(CoralType $coralType) : self{ + $this->coralType = $coralType; + return $this; + } + public function isDead() : bool{ return $this->dead; } /** @return $this */ diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 03e186f2eb..5554646ad0 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -45,11 +45,9 @@ use pocketmine\block\tile\Jukebox as TileJukebox; use pocketmine\block\tile\MonsterSpawner as TileMonsterSpawner; use pocketmine\block\tile\Note as TileNote; use pocketmine\block\tile\Skull as TileSkull; -use pocketmine\block\utils\CoralType; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\block\utils\TreeType; -use pocketmine\data\bedrock\CoralTypeIdMap; use pocketmine\item\Item; use pocketmine\item\ItemIds; use pocketmine\item\ToolTier; @@ -144,7 +142,7 @@ class BlockFactory{ $this->register(new CocoaBlock(new BID(Ids::COCOA, 0), "Cocoa Block")); $this->register(new CoralBlock(new BID(Ids::CORAL_BLOCK, 0), "Coral Block", new BlockBreakInfo(7.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); $this->register(new CraftingTable(new BID(Ids::CRAFTING_TABLE, 0), "Crafting Table")); - $this->register(new DaylightSensor(new BIDFlattened(Ids::DAYLIGHT_DETECTOR, Ids::DAYLIGHT_DETECTOR_INVERTED, 0, null, TileDaylightSensor::class), "Daylight Sensor")); + $this->register(new DaylightSensor(new BIDFlattened(Ids::DAYLIGHT_DETECTOR, [Ids::DAYLIGHT_DETECTOR_INVERTED], 0, null, TileDaylightSensor::class), "Daylight Sensor")); $this->register(new DeadBush(new BID(Ids::DEADBUSH, 0), "Dead Bush")); $this->register(new DetectorRail(new BID(Ids::DETECTOR_RAIL, 0), "Detector Rail")); @@ -187,7 +185,7 @@ class BlockFactory{ $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_WHITE_TULIP), "White Tulip")); $this->register(new FlowerPot(new BID(Ids::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, TileFlowerPot::class), "Flower Pot")); $this->register(new FrostedIce(new BID(Ids::FROSTED_ICE, 0), "Frosted Ice")); - $this->register(new Furnace(new BIDFlattened(Ids::FURNACE, Ids::LIT_FURNACE, 0, null, TileFurnace::class), "Furnace")); + $this->register(new Furnace(new BIDFlattened(Ids::FURNACE, [Ids::LIT_FURNACE], 0, null, TileFurnace::class), "Furnace")); $this->register(new Glass(new BID(Ids::GLASS, 0), "Glass")); $this->register(new GlassPane(new BID(Ids::GLASS_PANE, 0), "Glass Pane")); $this->register(new GlowingObsidian(new BID(Ids::GLOWINGOBSIDIAN, 0), "Glowing Obsidian")); @@ -219,7 +217,7 @@ class BlockFactory{ $this->register(new Lantern(new BID(Ids::LANTERN, 0), "Lantern", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); $this->register(new Opaque(new BID(Ids::LAPIS_BLOCK, 0), "Lapis Lazuli Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); $this->register(new LapisOre(new BID(Ids::LAPIS_ORE, 0), "Lapis Lazuli Ore")); - $this->register(new Lava(new BIDFlattened(Ids::FLOWING_LAVA, Ids::STILL_LAVA, 0), "Lava")); + $this->register(new Lava(new BIDFlattened(Ids::FLOWING_LAVA, [Ids::STILL_LAVA], 0), "Lava")); $this->register(new Lever(new BID(Ids::LEVER, 0), "Lever")); $this->register(new Loom(new BID(Ids::LOOM, 0), "Loom", new BlockBreakInfo(2.5, BlockToolType::AXE))); $this->register(new Magma(new BID(Ids::MAGMA, 0), "Magma Block")); @@ -281,11 +279,11 @@ class BlockFactory{ $this->register(new Rail(new BID(Ids::RAIL, 0), "Rail")); $this->register(new RedMushroom(new BID(Ids::RED_MUSHROOM, 0), "Red Mushroom")); $this->register(new Redstone(new BID(Ids::REDSTONE_BLOCK, 0), "Redstone Block")); - $this->register(new RedstoneComparator(new BIDFlattened(Ids::UNPOWERED_COMPARATOR, Ids::POWERED_COMPARATOR, 0, ItemIds::COMPARATOR, TileComparator::class), "Redstone Comparator")); - $this->register(new RedstoneLamp(new BIDFlattened(Ids::REDSTONE_LAMP, Ids::LIT_REDSTONE_LAMP, 0), "Redstone Lamp")); - $this->register(new RedstoneOre(new BIDFlattened(Ids::REDSTONE_ORE, Ids::LIT_REDSTONE_ORE, 0), "Redstone Ore")); - $this->register(new RedstoneRepeater(new BIDFlattened(Ids::UNPOWERED_REPEATER, Ids::POWERED_REPEATER, 0, ItemIds::REPEATER), "Redstone Repeater")); - $this->register(new RedstoneTorch(new BIDFlattened(Ids::REDSTONE_TORCH, Ids::UNLIT_REDSTONE_TORCH, 0), "Redstone Torch")); + $this->register(new RedstoneComparator(new BIDFlattened(Ids::UNPOWERED_COMPARATOR, [Ids::POWERED_COMPARATOR], 0, ItemIds::COMPARATOR, TileComparator::class), "Redstone Comparator")); + $this->register(new RedstoneLamp(new BIDFlattened(Ids::REDSTONE_LAMP, [Ids::LIT_REDSTONE_LAMP], 0), "Redstone Lamp")); + $this->register(new RedstoneOre(new BIDFlattened(Ids::REDSTONE_ORE, [Ids::LIT_REDSTONE_ORE], 0), "Redstone Ore")); + $this->register(new RedstoneRepeater(new BIDFlattened(Ids::UNPOWERED_REPEATER, [Ids::POWERED_REPEATER], 0, ItemIds::REPEATER), "Redstone Repeater")); + $this->register(new RedstoneTorch(new BIDFlattened(Ids::REDSTONE_TORCH, [Ids::UNLIT_REDSTONE_TORCH], 0), "Redstone Torch")); $this->register(new RedstoneWire(new BID(Ids::REDSTONE_WIRE, 0, ItemIds::REDSTONE), "Redstone")); $this->register(new Reserved6(new BID(Ids::RESERVED6, 0), "reserved6")); $this->register(new Sand(new BID(Ids::SAND, 0), "Sand")); @@ -387,7 +385,7 @@ class BlockFactory{ $this->register(new TripwireHook(new BID(Ids::TRIPWIRE_HOOK, 0), "Tripwire Hook")); $this->register(new UnderwaterTorch(new BID(Ids::UNDERWATER_TORCH, 0), "Underwater Torch")); $this->register(new Vine(new BID(Ids::VINE, 0), "Vines")); - $this->register(new Water(new BIDFlattened(Ids::FLOWING_WATER, Ids::STILL_WATER, 0), "Water")); + $this->register(new Water(new BIDFlattened(Ids::FLOWING_WATER, [Ids::STILL_WATER], 0), "Water")); $this->register(new WaterLily(new BID(Ids::LILY_PAD, 0), "Lily Pad")); $this->register(new WeightedPressurePlateHeavy(new BID(Ids::HEAVY_WEIGHTED_PRESSURE_PLATE, 0), "Weighted Pressure Plate Heavy")); $this->register(new WeightedPressurePlateLight(new BID(Ids::LIGHT_WEIGHTED_PRESSURE_PLATE, 0), "Weighted Pressure Plate Light")); @@ -399,7 +397,7 @@ class BlockFactory{ $this->register(new Planks(new BID(Ids::PLANKS, $magicNumber), $name . " Planks")); $this->register(new Sapling(new BID(Ids::SAPLING, $magicNumber), $name . " Sapling", $treeType)); $this->register(new WoodenFence(new BID(Ids::FENCE, $magicNumber), $name . " Fence")); - $this->register(new WoodenSlab(new BIDFlattened(Ids::WOODEN_SLAB, Ids::DOUBLE_WOODEN_SLAB, $treeType->getMagicNumber()), $treeType->getDisplayName())); + $this->register(new WoodenSlab(new BIDFlattened(Ids::WOODEN_SLAB, [Ids::DOUBLE_WOODEN_SLAB], $treeType->getMagicNumber()), $treeType->getDisplayName())); //TODO: find a better way to deal with this split $this->register(new Leaves(new BID($magicNumber >= 4 ? Ids::LEAVES2 : Ids::LEAVES, $magicNumber & 0x03), $name . " Leaves", $treeType)); @@ -481,28 +479,21 @@ class BlockFactory{ $this->registerMushroomBlocks(); - foreach(CoralType::getAll() as $coralType){ - $coralTypeId = CoralTypeIdMap::getInstance()->toId($coralType); - $coralTypeName = $coralType->getDisplayName(); - $this->register(new Coral( - new BID(Ids::CORAL, $coralTypeId), - "$coralTypeName Coral", - BlockBreakInfo::instant(), - $coralType - )); - $this->register(new FloorCoralFan( - new BlockIdentifierFlattened(Ids::CORAL_FAN, Ids::CORAL_FAN_DEAD, $coralTypeId, ItemIds::CORAL_FAN), - "$coralTypeName Coral Fan", - BlockBreakInfo::instant(), - $coralType - )); - $this->register(new WallCoralFan( - BlockLegacyIdHelper::getWallCoralFanIdentifier($coralType), - "$coralTypeName Wall Coral Fan", - BlockBreakInfo::instant(), - $coralType - )); - } + $this->register(new Coral( + new BID(Ids::CORAL, 0), + "Coral", + BlockBreakInfo::instant(), + )); + $this->register(new FloorCoralFan( + new BlockIdentifierFlattened(Ids::CORAL_FAN, [Ids::CORAL_FAN_DEAD], 0, ItemIds::CORAL_FAN), + "Coral Fan", + BlockBreakInfo::instant(), + )); + $this->register(new WallCoralFan( + new BlockIdentifierFlattened(Ids::CORAL_FAN_HANG, [Ids::CORAL_FAN_HANG2, Ids::CORAL_FAN_HANG3], 0, ItemIds::CORAL_FAN), + "Wall Coral Fan", + BlockBreakInfo::instant(), + )); //region --- auto-generated TODOs for bedrock-1.11.0 --- //TODO: minecraft:bell diff --git a/src/block/BlockIdentifierFlattened.php b/src/block/BlockIdentifierFlattened.php index c3d8278b13..1eca84d528 100644 --- a/src/block/BlockIdentifierFlattened.php +++ b/src/block/BlockIdentifierFlattened.php @@ -23,21 +23,37 @@ declare(strict_types=1); namespace pocketmine\block; +use function count; + class BlockIdentifierFlattened extends BlockIdentifier{ - /** @var int */ - private $secondId; + /** @var int[] */ + private array $additionalIds; - public function __construct(int $blockId, int $secondId, int $variant, ?int $itemId = null, ?string $tileClass = null){ + /** + * @param int[] $additionalIds + */ + public function __construct(int $blockId, array $additionalIds, int $variant, ?int $itemId = null, ?string $tileClass = null){ + if(count($additionalIds) === 0){ + throw new \InvalidArgumentException("Expected at least 1 additional ID"); + } parent::__construct($blockId, $variant, $itemId, $tileClass); - $this->secondId = $secondId; + + $this->additionalIds = $additionalIds; + } + + public function getAdditionalId(int $index) : int{ + if(!isset($this->additionalIds[$index])){ + throw new \InvalidArgumentException("No such ID at index $index"); + } + return $this->additionalIds[$index]; } public function getSecondId() : int{ - return $this->secondId; + return $this->getAdditionalId(0); } public function getAllBlockIds() : array{ - return [$this->getBlockId(), $this->getSecondId()]; + return [$this->getBlockId(), ...$this->additionalIds]; } } diff --git a/src/block/BlockLegacyIdHelper.php b/src/block/BlockLegacyIdHelper.php index 082f5132a4..945053824e 100644 --- a/src/block/BlockLegacyIdHelper.php +++ b/src/block/BlockLegacyIdHelper.php @@ -26,7 +26,6 @@ namespace pocketmine\block; use pocketmine\block\BlockIdentifier as BID; use pocketmine\block\BlockLegacyIds as Ids; use pocketmine\block\tile\Sign as TileSign; -use pocketmine\block\utils\CoralType; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\TreeType; use pocketmine\item\ItemIds; @@ -244,17 +243,6 @@ final class BlockLegacyIdHelper{ if($id === null){ throw new \InvalidArgumentException("Stone slab type should be 1, 2, 3 or 4"); } - return new BlockIdentifierFlattened($id[0], $id[1], $meta); - } - - public static function getWallCoralFanIdentifier(CoralType $type) : BlockIdentifier{ - switch($type->id()){ - case CoralType::TUBE()->id(): return new BID(Ids::CORAL_FAN_HANG, 0, ItemIds::CORAL_FAN); - case CoralType::BRAIN()->id(): return new BID(Ids::CORAL_FAN_HANG, 1, ItemIds::CORAL_FAN); - case CoralType::BUBBLE()->id(): return new BID(Ids::CORAL_FAN_HANG2, 0, ItemIds::CORAL_FAN); - case CoralType::FIRE()->id(): return new BID(Ids::CORAL_FAN_HANG2, 1, ItemIds::CORAL_FAN); - case CoralType::HORN()->id(): return new BID(Ids::CORAL_FAN_HANG3, 0, ItemIds::CORAL_FAN); - } - throw new AssumptionFailedError("Switch should cover all coral types"); + return new BlockIdentifierFlattened($id[0], [$id[1]], $meta); } } diff --git a/src/block/BlockLegacyMetadata.php b/src/block/BlockLegacyMetadata.php index e226a0c654..06bbe96808 100644 --- a/src/block/BlockLegacyMetadata.php +++ b/src/block/BlockLegacyMetadata.php @@ -69,6 +69,7 @@ final class BlockLegacyMetadata{ public const CORAL_FAN_EAST_WEST = 0; public const CORAL_FAN_NORTH_SOUTH = 1; + public const CORAL_FAN_TYPE_MASK = 0x7; public const CORAL_FAN_HANG_FLAG_DEAD = 0x2; @@ -77,6 +78,7 @@ final class BlockLegacyMetadata{ public const CORAL_FAN_HANG2_BUBBLE = 0; public const CORAL_FAN_HANG2_FIRE = 1; public const CORAL_FAN_HANG3_HORN = 0; + public const CORAL_FAN_HANG_TYPE_MASK = 0x1; public const CORAL_VARIANT_TUBE = 0; public const CORAL_VARIANT_BRAIN = 1; diff --git a/src/block/Coral.php b/src/block/Coral.php index fd74e69ccc..7c9185c1dc 100644 --- a/src/block/Coral.php +++ b/src/block/Coral.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\InvalidBlockStateException; +use pocketmine\data\bedrock\CoralTypeIdMap; use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -30,6 +32,26 @@ use pocketmine\world\BlockTransaction; final class Coral extends BaseCoral{ + public function readStateFromData(int $id, int $stateMeta) : void{ + $coralType = CoralTypeIdMap::getInstance()->fromId($stateMeta); + if($coralType === null){ + throw new InvalidBlockStateException("No such coral type"); + } + $this->coralType = $coralType; + } + + public function writeStateToMeta() : int{ + return CoralTypeIdMap::getInstance()->toId($this->coralType); + } + + public function getStateBitmask() : int{ + return 0b0111; + } + + public function getNonPersistentStateBitmask() : int{ + return 0b0000; + } + public function readStateFromWorld() : void{ //TODO: this hack ensures correct state of coral plants, because they don't retain their dead flag in metadata $world = $this->pos->getWorld(); diff --git a/src/block/FloorCoralFan.php b/src/block/FloorCoralFan.php index 08237f0d7b..21ce87910b 100644 --- a/src/block/FloorCoralFan.php +++ b/src/block/FloorCoralFan.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\CoralType; +use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\data\bedrock\CoralTypeIdMap; use pocketmine\item\Item; use pocketmine\item\ItemFactory; @@ -41,13 +41,18 @@ final class FloorCoralFan extends BaseCoral{ private int $axis = Axis::X; - public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo, CoralType $coralType){ - parent::__construct($idInfo, $name, $breakInfo, $coralType); + public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + parent::__construct($idInfo, $name, $breakInfo); } public function readStateFromData(int $id, int $stateMeta) : void{ $this->dead = $id === $this->idInfo->getSecondId(); $this->axis = ($stateMeta >> 3) === BlockLegacyMetadata::CORAL_FAN_EAST_WEST ? Axis::X : Axis::Z; + $coralType = CoralTypeIdMap::getInstance()->fromId($stateMeta & BlockLegacyMetadata::CORAL_FAN_TYPE_MASK); + if($coralType === null){ + throw new InvalidBlockStateException("No such coral type"); + } + $this->coralType = $coralType; } public function getId() : int{ @@ -63,10 +68,15 @@ final class FloorCoralFan extends BaseCoral{ } protected function writeStateToMeta() : int{ - return ($this->axis === Axis::X ? BlockLegacyMetadata::CORAL_FAN_EAST_WEST : BlockLegacyMetadata::CORAL_FAN_NORTH_SOUTH) << 3; + return (($this->axis === Axis::X ? BlockLegacyMetadata::CORAL_FAN_EAST_WEST : BlockLegacyMetadata::CORAL_FAN_NORTH_SOUTH) << 3) | + CoralTypeIdMap::getInstance()->toId($this->coralType); } public function getStateBitmask() : int{ + return 0b1111; + } + + public function getNonPersistentStateBitmask() : int{ return 0b1000; } diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index c39be33172..798b1dd53b 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -87,9 +87,6 @@ use function assert; * @method static Torch BLUE_TORCH() * @method static BoneBlock BONE_BLOCK() * @method static Bookshelf BOOKSHELF() - * @method static Coral BRAIN_CORAL() - * @method static FloorCoralFan BRAIN_CORAL_FAN() - * @method static WallCoralFan BRAIN_WALL_CORAL_FAN() * @method static BrewingStand BREWING_STAND() * @method static Opaque BRICKS() * @method static Slab BRICK_SLAB() @@ -98,9 +95,6 @@ use function assert; * @method static GlazedTerracotta BROWN_GLAZED_TERRACOTTA() * @method static BrownMushroom BROWN_MUSHROOM() * @method static BrownMushroomBlock BROWN_MUSHROOM_BLOCK() - * @method static Coral BUBBLE_CORAL() - * @method static FloorCoralFan BUBBLE_CORAL_FAN() - * @method static WallCoralFan BUBBLE_WALL_CORAL_FAN() * @method static Cactus CACTUS() * @method static Cake CAKE() * @method static Carpet CARPET() @@ -125,7 +119,9 @@ use function assert; * @method static ChemistryTable COMPOUND_CREATOR() * @method static Concrete CONCRETE() * @method static ConcretePowder CONCRETE_POWDER() + * @method static Coral CORAL() * @method static CoralBlock CORAL_BLOCK() + * @method static FloorCoralFan CORAL_FAN() * @method static Flower CORNFLOWER() * @method static Opaque CRACKED_STONE_BRICKS() * @method static CraftingTable CRAFTING_TABLE() @@ -301,9 +297,6 @@ use function assert; * @method static Farmland FARMLAND() * @method static TallGrass FERN() * @method static Fire FIRE() - * @method static Coral FIRE_CORAL() - * @method static FloorCoralFan FIRE_CORAL_FAN() - * @method static WallCoralFan FIRE_WALL_CORAL_FAN() * @method static FlowerPot FLOWER_POT() * @method static FrostedIce FROSTED_ICE() * @method static Furnace FURNACE() @@ -328,9 +321,6 @@ use function assert; * @method static HardenedGlassPane HARDENED_GLASS_PANE() * @method static HayBale HAY_BALE() * @method static Hopper HOPPER() - * @method static Coral HORN_CORAL() - * @method static FloorCoralFan HORN_CORAL_FAN() - * @method static WallCoralFan HORN_WALL_CORAL_FAN() * @method static Ice ICE() * @method static InfestedStone INFESTED_CHISELED_STONE_BRICK() * @method static InfestedStone INFESTED_COBBLESTONE() @@ -553,12 +543,10 @@ use function assert; * @method static TrappedChest TRAPPED_CHEST() * @method static Tripwire TRIPWIRE() * @method static TripwireHook TRIPWIRE_HOOK() - * @method static Coral TUBE_CORAL() - * @method static FloorCoralFan TUBE_CORAL_FAN() - * @method static WallCoralFan TUBE_WALL_CORAL_FAN() * @method static UnderwaterTorch UNDERWATER_TORCH() * @method static Vine VINES() * @method static WallBanner WALL_BANNER() + * @method static WallCoralFan WALL_CORAL_FAN() * @method static Water WATER() * @method static WeightedPressurePlateHeavy WEIGHTED_PRESSURE_PLATE_HEAVY() * @method static WeightedPressurePlateLight WEIGHTED_PRESSURE_PLATE_LIGHT() @@ -653,9 +641,6 @@ final class VanillaBlocks{ self::register("blue_torch", $factory->get(204, 5)); self::register("bone_block", $factory->get(216, 0)); self::register("bookshelf", $factory->get(47, 0)); - self::register("brain_coral", $factory->get(386, 1)); - self::register("brain_coral_fan", $factory->get(388, 1)); - self::register("brain_wall_coral_fan", $factory->get(390, 1)); self::register("brewing_stand", $factory->get(117, 0)); self::register("brick_slab", $factory->get(44, 4)); self::register("brick_stairs", $factory->get(108, 0)); @@ -664,9 +649,6 @@ final class VanillaBlocks{ self::register("brown_glazed_terracotta", $factory->get(232, 2)); self::register("brown_mushroom", $factory->get(39, 0)); self::register("brown_mushroom_block", $factory->get(99, 0)); - self::register("bubble_coral", $factory->get(386, 2)); - self::register("bubble_coral_fan", $factory->get(388, 2)); - self::register("bubble_wall_coral_fan", $factory->get(391, 0)); self::register("cactus", $factory->get(81, 0)); self::register("cake", $factory->get(92, 0)); self::register("carpet", $factory->get(171, 0)); @@ -691,7 +673,9 @@ final class VanillaBlocks{ self::register("compound_creator", $factory->get(238, 0)); self::register("concrete", $factory->get(236, 0)); self::register("concrete_powder", $factory->get(237, 0)); + self::register("coral", $factory->get(386, 0)); self::register("coral_block", $factory->get(387, 0)); + self::register("coral_fan", $factory->get(388, 0)); self::register("cornflower", $factory->get(38, 9)); self::register("cracked_stone_bricks", $factory->get(98, 2)); self::register("crafting_table", $factory->get(58, 0)); @@ -867,9 +851,6 @@ final class VanillaBlocks{ self::register("farmland", $factory->get(60, 0)); self::register("fern", $factory->get(31, 2)); self::register("fire", $factory->get(51, 0)); - self::register("fire_coral", $factory->get(386, 3)); - self::register("fire_coral_fan", $factory->get(388, 3)); - self::register("fire_wall_coral_fan", $factory->get(391, 1)); self::register("flower_pot", $factory->get(140, 0)); self::register("frosted_ice", $factory->get(207, 0)); self::register("furnace", $factory->get(61, 2)); @@ -894,9 +875,6 @@ final class VanillaBlocks{ self::register("hardened_glass_pane", $factory->get(190, 0)); self::register("hay_bale", $factory->get(170, 0)); self::register("hopper", $factory->get(154, 0)); - self::register("horn_coral", $factory->get(386, 4)); - self::register("horn_coral_fan", $factory->get(388, 4)); - self::register("horn_wall_coral_fan", $factory->get(392, 0)); self::register("ice", $factory->get(79, 0)); self::register("infested_chiseled_stone_brick", $factory->get(97, 5)); self::register("infested_cobblestone", $factory->get(97, 1)); @@ -1119,12 +1097,10 @@ final class VanillaBlocks{ self::register("trapped_chest", $factory->get(146, 2)); self::register("tripwire", $factory->get(132, 0)); self::register("tripwire_hook", $factory->get(131, 0)); - self::register("tube_coral", $factory->get(386, 0)); - self::register("tube_coral_fan", $factory->get(388, 0)); - self::register("tube_wall_coral_fan", $factory->get(390, 0)); self::register("underwater_torch", $factory->get(239, 5)); self::register("vines", $factory->get(106, 0)); self::register("wall_banner", $factory->get(177, 2)); + self::register("wall_coral_fan", $factory->get(390, 0)); self::register("water", $factory->get(8, 0)); self::register("weighted_pressure_plate_heavy", $factory->get(148, 0)); self::register("weighted_pressure_plate_light", $factory->get(147, 0)); diff --git a/src/block/WallCoralFan.php b/src/block/WallCoralFan.php index bac64b15b7..9e4fddf1f2 100644 --- a/src/block/WallCoralFan.php +++ b/src/block/WallCoralFan.php @@ -24,7 +24,9 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\CoralType; use pocketmine\block\utils\HorizontalFacingTrait; +use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\data\bedrock\CoralTypeIdMap; use pocketmine\item\Item; use pocketmine\item\ItemFactory; @@ -33,21 +35,72 @@ use pocketmine\math\Axis; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; +use pocketmine\utils\AssumptionFailedError; use pocketmine\world\BlockTransaction; final class WallCoralFan extends BaseCoral{ use HorizontalFacingTrait; + /** @var BlockIdentifierFlattened */ + protected $idInfo; + + public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + parent::__construct($idInfo, $name, $breakInfo); + } + public function readStateFromData(int $id, int $stateMeta) : void{ $this->facing = BlockDataSerializer::readCoralFacing($stateMeta >> 2); $this->dead = ($stateMeta & BlockLegacyMetadata::CORAL_FAN_HANG_FLAG_DEAD) !== 0; + + $coralTypeFlag = $stateMeta & BlockLegacyMetadata::CORAL_FAN_HANG_TYPE_MASK; + switch($id){ + case $this->idInfo->getBlockId(): + $this->coralType = $coralTypeFlag === BlockLegacyMetadata::CORAL_FAN_HANG_TUBE ? CoralType::TUBE() : CoralType::BRAIN(); + break; + case $this->idInfo->getAdditionalId(0): + $this->coralType = $coralTypeFlag === BlockLegacyMetadata::CORAL_FAN_HANG2_BUBBLE ? CoralType::BUBBLE() : CoralType::FIRE(); + break; + case $this->idInfo->getAdditionalId(1): + if($coralTypeFlag !== BlockLegacyMetadata::CORAL_FAN_HANG3_HORN){ + throw new InvalidBlockStateException("Invalid CORAL_FAN_HANG3 type"); + } + $this->coralType = CoralType::HORN(); + break; + default: + throw new \LogicException("ID/meta doesn't match any CORAL_FAN_HANG type"); + } + } + + public function getId() : int{ + if($this->coralType->equals(CoralType::TUBE()) || $this->coralType->equals(CoralType::BRAIN())){ + return $this->idInfo->getBlockId(); + }elseif($this->coralType->equals(CoralType::BUBBLE()) || $this->coralType->equals(CoralType::FIRE())){ + return $this->idInfo->getAdditionalId(0); + }elseif($this->coralType->equals(CoralType::HORN())){ + return $this->idInfo->getAdditionalId(1); + } + throw new AssumptionFailedError("All types of coral should be covered"); } public function writeStateToMeta() : int{ - return (BlockDataSerializer::writeCoralFacing($this->facing) << 2) | ($this->dead ? BlockLegacyMetadata::CORAL_FAN_HANG_FLAG_DEAD : 0); + $coralTypeFlag = (function() : int{ + switch($this->coralType->id()){ + case CoralType::TUBE()->id(): return BlockLegacyMetadata::CORAL_FAN_HANG_TUBE; + case CoralType::BRAIN()->id(): return BlockLegacyMetadata::CORAL_FAN_HANG_BRAIN; + case CoralType::BUBBLE()->id(): return BlockLegacyMetadata::CORAL_FAN_HANG2_BUBBLE; + case CoralType::FIRE()->id(): return BlockLegacyMetadata::CORAL_FAN_HANG2_FIRE; + case CoralType::HORN()->id(): return BlockLegacyMetadata::CORAL_FAN_HANG3_HORN; + default: throw new AssumptionFailedError("All types of coral should be covered"); + } + })(); + return (BlockDataSerializer::writeCoralFacing($this->facing) << 2) | ($this->dead ? BlockLegacyMetadata::CORAL_FAN_HANG_FLAG_DEAD : 0) | $coralTypeFlag; } public function getStateBitmask() : int{ + return 0b1111; + } + + public function getNonPersistentStateBitmask() : int{ return 0b1110; } diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 02d14b918f..8cfaec10f9 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -25,6 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\utils\CoralType; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\RecordType; use pocketmine\block\utils\SkullType; @@ -77,11 +78,11 @@ class ItemFactory{ $this->register(new Clock(new ItemIdentifier(ItemIds::CLOCK, 0), "Clock")); $this->register(new Clownfish(new ItemIdentifier(ItemIds::CLOWNFISH, 0), "Clownfish")); $this->register(new Coal(new ItemIdentifier(ItemIds::COAL, 0), "Coal")); - $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::CORAL_FAN, 0), VanillaBlocks::TUBE_CORAL_FAN(), VanillaBlocks::TUBE_WALL_CORAL_FAN()), true); - $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::CORAL_FAN, 1), VanillaBlocks::BRAIN_CORAL_FAN(), VanillaBlocks::BRAIN_WALL_CORAL_FAN()), true); - $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::CORAL_FAN, 2), VanillaBlocks::BUBBLE_CORAL_FAN(), VanillaBlocks::BUBBLE_WALL_CORAL_FAN()), true); - $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::CORAL_FAN, 3), VanillaBlocks::FIRE_CORAL_FAN(), VanillaBlocks::FIRE_WALL_CORAL_FAN()), true); - $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::CORAL_FAN, 4), VanillaBlocks::HORN_CORAL_FAN(), VanillaBlocks::HORN_WALL_CORAL_FAN()), true); + $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::CORAL_FAN, 0), VanillaBlocks::CORAL_FAN()->setCoralType(CoralType::TUBE()), VanillaBlocks::WALL_CORAL_FAN()->setCoralType(CoralType::TUBE())), true); + $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::CORAL_FAN, 1), VanillaBlocks::CORAL_FAN()->setCoralType(CoralType::BRAIN()), VanillaBlocks::WALL_CORAL_FAN()->setCoralType(CoralType::BRAIN())), true); + $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::CORAL_FAN, 2), VanillaBlocks::CORAL_FAN()->setCoralType(CoralType::BUBBLE()), VanillaBlocks::WALL_CORAL_FAN()->setCoralType(CoralType::BUBBLE())), true); + $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::CORAL_FAN, 3), VanillaBlocks::CORAL_FAN()->setCoralType(CoralType::FIRE()), VanillaBlocks::WALL_CORAL_FAN()->setCoralType(CoralType::FIRE())), true); + $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::CORAL_FAN, 4), VanillaBlocks::CORAL_FAN()->setCoralType(CoralType::HORN()), VanillaBlocks::WALL_CORAL_FAN()->setCoralType(CoralType::HORN())), true); $this->register(new Coal(new ItemIdentifier(ItemIds::COAL, 1), "Charcoal")); $this->register(new CocoaBeans(new ItemIdentifier(ItemIds::DYE, 3), "Cocoa Beans")); $this->register(new Compass(new ItemIdentifier(ItemIds::COMPASS, 0), "Compass")); diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 812ba65102..d4a75f4d3a 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Mushroom Stem","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"All Sided Mushroom Stem","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Tube Coral","6177":"Brain Coral","6178":"Bubble Coral","6179":"Fire Coral","6180":"Horn Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Tube Coral Fan","6209":"Brain Coral Fan","6210":"Bubble Coral Fan","6211":"Fire Coral Fan","6212":"Horn Coral Fan","6216":"Tube Coral Fan","6217":"Brain Coral Fan","6218":"Bubble Coral Fan","6219":"Fire Coral Fan","6220":"Horn Coral Fan","6224":"Tube Coral Fan","6225":"Brain Coral Fan","6226":"Bubble Coral Fan","6227":"Fire Coral Fan","6228":"Horn Coral Fan","6232":"Tube Coral Fan","6233":"Brain Coral Fan","6234":"Bubble Coral Fan","6235":"Fire Coral Fan","6236":"Horn Coral Fan","6240":"Tube Wall Coral Fan","6241":"Brain Wall Coral Fan","6242":"Tube Wall Coral Fan","6243":"Brain Wall Coral Fan","6244":"Tube Wall Coral Fan","6245":"Brain Wall Coral Fan","6246":"Tube Wall Coral Fan","6247":"Brain Wall Coral Fan","6248":"Tube Wall Coral Fan","6249":"Brain Wall Coral Fan","6250":"Tube Wall Coral Fan","6251":"Brain Wall Coral Fan","6252":"Tube Wall Coral Fan","6253":"Brain Wall Coral Fan","6254":"Tube Wall Coral Fan","6255":"Brain Wall Coral Fan","6256":"Bubble Wall Coral Fan","6257":"Fire Wall Coral Fan","6258":"Bubble Wall Coral Fan","6259":"Fire Wall Coral Fan","6260":"Bubble Wall Coral Fan","6261":"Fire Wall Coral Fan","6262":"Bubble Wall Coral Fan","6263":"Fire Wall Coral Fan","6264":"Bubble Wall Coral Fan","6265":"Fire Wall Coral Fan","6266":"Bubble Wall Coral Fan","6267":"Fire Wall Coral Fan","6268":"Bubble Wall Coral Fan","6269":"Fire Wall Coral Fan","6270":"Bubble Wall Coral Fan","6271":"Fire Wall Coral Fan","6272":"Horn Wall Coral Fan","6274":"Horn Wall Coral Fan","6276":"Horn Wall Coral Fan","6278":"Horn Wall Coral Fan","6280":"Horn Wall Coral Fan","6282":"Horn Wall Coral Fan","6284":"Horn Wall Coral Fan","6286":"Horn Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Mushroom Stem","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"All Sided Mushroom Stem","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6274":"Wall Coral Fan","6276":"Wall Coral Fan","6278":"Wall Coral Fan","6280":"Wall Coral Fan","6282":"Wall Coral Fan","6284":"Wall Coral Fan","6286":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From 376d2c4cd495adb0fc80e48bbb2ce7eff35445db Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 20 May 2021 22:49:51 +0100 Subject: [PATCH 2496/3224] Consistently declare BlockBreakInfo at the constructor call site instead of inside the class --- src/block/Air.php | 4 - src/block/Anvil.php | 5 - src/block/Barrel.php | 4 - src/block/BaseBanner.php | 4 +- src/block/BaseRail.php | 4 - src/block/BaseSign.php | 4 +- src/block/Bed.php | 4 +- src/block/Bedrock.php | 4 - src/block/BlockFactory.php | 405 +++++++++++++---------- src/block/BlueIce.php | 4 - src/block/BoneBlock.php | 5 - src/block/Bookshelf.php | 4 - src/block/BrewingStand.php | 5 - src/block/Cactus.php | 4 - src/block/Cake.php | 4 - src/block/Carpet.php | 4 +- src/block/Chest.php | 4 - src/block/Clay.php | 4 - src/block/Coal.php | 6 - src/block/CoalOre.php | 5 - src/block/Cobweb.php | 4 - src/block/CocoaBlock.php | 4 - src/block/Concrete.php | 5 +- src/block/ConcretePowder.php | 4 +- src/block/CraftingTable.php | 4 - src/block/Crops.php | 4 - src/block/DaylightSensor.php | 4 +- src/block/DeadBush.php | 4 - src/block/DiamondOre.php | 5 - src/block/Dirt.php | 4 - src/block/DoublePlant.php | 4 - src/block/DoubleTallGrass.php | 4 - src/block/DragonEgg.php | 5 - src/block/EmeraldOre.php | 5 - src/block/EnchantingTable.php | 5 - src/block/EndPortalFrame.php | 4 - src/block/EndRod.php | 4 - src/block/EnderChest.php | 5 - src/block/Farmland.php | 4 - src/block/FenceGate.php | 4 - src/block/Fire.php | 4 - src/block/Flower.php | 4 - src/block/FlowerPot.php | 4 - src/block/FrostedIce.php | 4 - src/block/Furnace.php | 5 +- src/block/Glass.php | 4 - src/block/GlassPane.php | 4 - src/block/GlazedTerracotta.php | 5 - src/block/GlowingObsidian.php | 6 - src/block/Glowstone.php | 4 - src/block/Grass.php | 4 - src/block/GrassPath.php | 4 - src/block/Gravel.php | 4 - src/block/HardenedClay.php | 5 - src/block/HardenedGlass.php | 3 - src/block/HardenedGlassPane.php | 3 - src/block/HayBale.php | 4 - src/block/Ice.php | 4 - src/block/InfestedStone.php | 4 +- src/block/ItemFrame.php | 4 - src/block/Jukebox.php | 5 - src/block/Ladder.php | 4 - src/block/LapisOre.php | 5 - src/block/Leaves.php | 4 +- src/block/Lever.php | 4 - src/block/Liquid.php | 4 +- src/block/Magma.php | 5 - src/block/Melon.php | 4 - src/block/MonsterSpawner.php | 5 - src/block/Mycelium.php | 4 - src/block/NetherPortal.php | 4 - src/block/NetherQuartzOre.php | 5 - src/block/NetherReactor.php | 5 - src/block/NetherWartPlant.php | 4 - src/block/Netherrack.php | 6 - src/block/Note.php | 4 - src/block/PackedIce.php | 4 - src/block/Planks.php | 4 - src/block/Podzol.php | 3 - src/block/RedMushroom.php | 4 - src/block/Redstone.php | 5 - src/block/RedstoneComparator.php | 4 +- src/block/RedstoneLamp.php | 4 +- src/block/RedstoneOre.php | 5 +- src/block/RedstoneRepeater.php | 4 +- src/block/RedstoneTorch.php | 4 +- src/block/RedstoneWire.php | 4 - src/block/Reserved6.php | 3 - src/block/Sand.php | 4 - src/block/Sapling.php | 4 +- src/block/SeaLantern.php | 4 - src/block/SeaPickle.php | 4 - src/block/Skull.php | 4 +- src/block/Snow.php | 5 - src/block/SnowLayer.php | 5 - src/block/SoulSand.php | 4 - src/block/Sponge.php | 4 - src/block/Stem.php | 4 - src/block/StoneButton.php | 4 - src/block/StonePressurePlate.php | 5 - src/block/Sugarcane.php | 4 - src/block/TNT.php | 4 - src/block/TallGrass.php | 4 - src/block/Torch.php | 4 - src/block/Tripwire.php | 4 - src/block/TripwireHook.php | 4 - src/block/UnknownBlock.php | 4 +- src/block/Vine.php | 4 - src/block/Wall.php | 5 - src/block/WaterLily.php | 4 - src/block/WeightedPressurePlateHeavy.php | 5 - src/block/WeightedPressurePlateLight.php | 5 - src/block/Wood.php | 4 +- src/block/WoodenButton.php | 4 - src/block/WoodenDoor.php | 3 - src/block/WoodenFence.php | 4 - src/block/WoodenPressurePlate.php | 4 - src/block/WoodenSlab.php | 4 - src/block/WoodenStairs.php | 4 - src/block/WoodenTrapdoor.php | 4 - src/block/Wool.php | 15 +- 121 files changed, 267 insertions(+), 657 deletions(-) diff --git a/src/block/Air.php b/src/block/Air.php index ae201328f0..8e1104bba0 100644 --- a/src/block/Air.php +++ b/src/block/Air.php @@ -30,10 +30,6 @@ use pocketmine\math\AxisAlignedBB; */ class Air extends Transparent{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::indestructible(-1.0)); - } - public function canBeFlowedInto() : bool{ return true; } diff --git a/src/block/Anvil.php b/src/block/Anvil.php index 313e6ef8c7..bc84f55d48 100644 --- a/src/block/Anvil.php +++ b/src/block/Anvil.php @@ -29,7 +29,6 @@ use pocketmine\block\utils\Fallable; use pocketmine\block\utils\FallableTrait; use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\item\Item; -use pocketmine\item\ToolTier; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -43,10 +42,6 @@ class Anvil extends Transparent implements Fallable{ /** @var int */ private $damage = 0; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 6000.0)); - } - protected function writeStateToMeta() : int{ return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) | ($this->damage << 2); } diff --git a/src/block/Barrel.php b/src/block/Barrel.php index 2c939c43a3..27301cee91 100644 --- a/src/block/Barrel.php +++ b/src/block/Barrel.php @@ -39,10 +39,6 @@ class Barrel extends Opaque{ /** @var bool */ protected $open = false; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.5, BlockToolType::AXE)); - } - protected function writeStateToMeta() : int{ return BlockDataSerializer::writeFacing($this->facing) | ($this->open ? BlockLegacyMetadata::BARREL_FLAG_OPEN : 0); } diff --git a/src/block/BaseBanner.php b/src/block/BaseBanner.php index 9c09012c99..e9bf340eca 100644 --- a/src/block/BaseBanner.php +++ b/src/block/BaseBanner.php @@ -49,8 +49,8 @@ abstract class BaseBanner extends Transparent{ */ protected $patterns = []; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0, BlockToolType::AXE)); + public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ + parent::__construct($idInfo, $name, $breakInfo); $this->baseColor = DyeColor::BLACK(); } diff --git a/src/block/BaseRail.php b/src/block/BaseRail.php index 017a3953ba..f78bc98c15 100644 --- a/src/block/BaseRail.php +++ b/src/block/BaseRail.php @@ -74,10 +74,6 @@ abstract class BaseRail extends Flowable{ /** @var int[] */ protected $connections = []; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.7)); - } - protected function writeStateToMeta() : int{ if(count($this->connections) === 0){ return BlockLegacyMetadata::RAIL_STRAIGHT_NORTH_SOUTH; diff --git a/src/block/BaseSign.php b/src/block/BaseSign.php index 3e047c2bdf..21de8f6f70 100644 --- a/src/block/BaseSign.php +++ b/src/block/BaseSign.php @@ -45,8 +45,8 @@ abstract class BaseSign extends Transparent{ /** @var int|null */ protected $editorEntityRuntimeId = null; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0, BlockToolType::AXE)); + public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ + parent::__construct($idInfo, $name, $breakInfo); $this->text = new SignText(); } diff --git a/src/block/Bed.php b/src/block/Bed.php index 958f771ddd..6b581759ed 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -50,8 +50,8 @@ class Bed extends Transparent{ /** @var DyeColor */ protected $color; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2)); + public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ + parent::__construct($idInfo, $name, $breakInfo); $this->color = DyeColor::RED(); } diff --git a/src/block/Bedrock.php b/src/block/Bedrock.php index c9429d1a8f..7cc9624ec8 100644 --- a/src/block/Bedrock.php +++ b/src/block/Bedrock.php @@ -28,10 +28,6 @@ class Bedrock extends Opaque{ /** @var bool */ private $burnsForever = false; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::indestructible()); - } - public function readStateFromData(int $id, int $stateMeta) : void{ $this->burnsForever = ($stateMeta & BlockLegacyMetadata::BEDROCK_FLAG_INFINIBURN) !== 0; } diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 5554646ad0..8dd64ab420 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -99,108 +99,125 @@ class BlockFactory{ $this->blocksDirectSkyLight = \SplFixedArray::fromArray(array_fill(0, 16384, false)); $this->blastResistance = \SplFixedArray::fromArray(array_fill(0, 16384, 0.0)); - $this->register(new ActivatorRail(new BID(Ids::ACTIVATOR_RAIL, 0), "Activator Rail")); - $this->register(new Air(new BID(Ids::AIR, 0), "Air")); - $this->register(new Anvil(new BID(Ids::ANVIL, 0), "Anvil")); + $railBreakInfo = new BlockBreakInfo(0.7); + $this->register(new ActivatorRail(new BID(Ids::ACTIVATOR_RAIL, 0), "Activator Rail", $railBreakInfo)); + $this->register(new Air(new BID(Ids::AIR, 0), "Air", BlockBreakInfo::indestructible(-1.0))); + $this->register(new Anvil(new BID(Ids::ANVIL, 0), "Anvil", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 6000.0))); $this->register(new Bamboo(new BID(Ids::BAMBOO, 0), "Bamboo", new BlockBreakInfo(2.0 /* 1.0 in PC */, BlockToolType::AXE))); $this->register(new BambooSapling(new BID(Ids::BAMBOO_SAPLING, 0), "Bamboo Sapling", BlockBreakInfo::instant())); - $this->register(new FloorBanner(new BID(Ids::STANDING_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Banner")); - $this->register(new WallBanner(new BID(Ids::WALL_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Wall Banner")); - $this->register(new Barrel(new BID(Ids::BARREL, 0, null, TileBarrel::class), "Barrel")); + + $bannerBreakInfo = new BlockBreakInfo(1.0, BlockToolType::AXE); + $this->register(new FloorBanner(new BID(Ids::STANDING_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Banner", $bannerBreakInfo)); + $this->register(new WallBanner(new BID(Ids::WALL_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Wall Banner", $bannerBreakInfo)); + $this->register(new Barrel(new BID(Ids::BARREL, 0, null, TileBarrel::class), "Barrel", new BlockBreakInfo(2.5, BlockToolType::AXE))); $this->register(new Transparent(new BID(Ids::BARRIER, 0), "Barrier", BlockBreakInfo::indestructible())); $this->register(new Beacon(new BID(Ids::BEACON, 0, null, TileBeacon::class), "Beacon", new BlockBreakInfo(3.0))); - $this->register(new Bed(new BID(Ids::BED_BLOCK, 0, ItemIds::BED, TileBed::class), "Bed Block")); - $this->register(new Bedrock(new BID(Ids::BEDROCK, 0), "Bedrock")); - $this->register(new Beetroot(new BID(Ids::BEETROOT_BLOCK, 0), "Beetroot Block")); - $this->register(new BlueIce(new BID(Ids::BLUE_ICE, 0), "Blue Ice")); - $this->register(new BoneBlock(new BID(Ids::BONE_BLOCK, 0), "Bone Block")); - $this->register(new Bookshelf(new BID(Ids::BOOKSHELF, 0), "Bookshelf")); - $this->register(new BrewingStand(new BID(Ids::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND, TileBrewingStand::class), "Brewing Stand")); + $this->register(new Bed(new BID(Ids::BED_BLOCK, 0, ItemIds::BED, TileBed::class), "Bed Block", new BlockBreakInfo(0.2))); + $this->register(new Bedrock(new BID(Ids::BEDROCK, 0), "Bedrock", BlockBreakInfo::indestructible())); + + $this->register(new Beetroot(new BID(Ids::BEETROOT_BLOCK, 0), "Beetroot Block", BlockBreakInfo::instant())); + $this->register(new BlueIce(new BID(Ids::BLUE_ICE, 0), "Blue Ice", new BlockBreakInfo(2.8, BlockToolType::PICKAXE))); + $this->register(new BoneBlock(new BID(Ids::BONE_BLOCK, 0), "Bone Block", new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->register(new Bookshelf(new BID(Ids::BOOKSHELF, 0), "Bookshelf", new BlockBreakInfo(1.5, BlockToolType::AXE))); + $this->register(new BrewingStand(new BID(Ids::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND, TileBrewingStand::class), "Brewing Stand", new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); $bricksBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); $this->register(new Stair(new BID(Ids::BRICK_STAIRS, 0), "Brick Stairs", $bricksBreakInfo)); $this->register(new Opaque(new BID(Ids::BRICK_BLOCK, 0), "Bricks", $bricksBreakInfo)); - $this->register(new BrownMushroom(new BID(Ids::BROWN_MUSHROOM, 0), "Brown Mushroom")); - $this->register(new Cactus(new BID(Ids::CACTUS, 0), "Cactus")); - $this->register(new Cake(new BID(Ids::CAKE_BLOCK, 0, ItemIds::CAKE), "Cake")); - $this->register(new Carrot(new BID(Ids::CARROTS, 0), "Carrot Block")); - $this->register(new Chest(new BID(Ids::CHEST, 0, null, TileChest::class), "Chest")); - $this->register(new Clay(new BID(Ids::CLAY_BLOCK, 0), "Clay Block")); - $this->register(new Coal(new BID(Ids::COAL_BLOCK, 0), "Coal Block")); - $this->register(new CoalOre(new BID(Ids::COAL_ORE, 0), "Coal Ore")); - $this->register(new CoarseDirt(new BID(Ids::DIRT, Meta::DIRT_COARSE), "Coarse Dirt")); + $this->register(new BrownMushroom(new BID(Ids::BROWN_MUSHROOM, 0), "Brown Mushroom", BlockBreakInfo::instant())); + $this->register(new Cactus(new BID(Ids::CACTUS, 0), "Cactus", new BlockBreakInfo(0.4))); + $this->register(new Cake(new BID(Ids::CAKE_BLOCK, 0, ItemIds::CAKE), "Cake", new BlockBreakInfo(0.5))); + $this->register(new Carrot(new BID(Ids::CARROTS, 0), "Carrot Block", BlockBreakInfo::instant())); + + $chestBreakInfo = new BlockBreakInfo(2.5, BlockToolType::AXE); + $this->register(new Chest(new BID(Ids::CHEST, 0, null, TileChest::class), "Chest", $chestBreakInfo)); + $this->register(new Clay(new BID(Ids::CLAY_BLOCK, 0), "Clay Block", new BlockBreakInfo(0.6, BlockToolType::SHOVEL))); + $this->register(new Coal(new BID(Ids::COAL_BLOCK, 0), "Coal Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0))); + $this->register(new CoalOre(new BID(Ids::COAL_ORE, 0), "Coal Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + + $dirtBreakInfo = new BlockBreakInfo(0.5, BlockToolType::SHOVEL); + $this->register(new CoarseDirt(new BID(Ids::DIRT, Meta::DIRT_COARSE), "Coarse Dirt", $dirtBreakInfo)); $cobblestoneBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); $this->register($cobblestone = new Opaque(new BID(Ids::COBBLESTONE, 0), "Cobblestone", $cobblestoneBreakInfo)); - $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_COBBLESTONE), "Infested Cobblestone", $cobblestone)); + $infestedStoneBreakInfo = new BlockBreakInfo(0.75); + $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_COBBLESTONE), "Infested Cobblestone", $infestedStoneBreakInfo, $cobblestone)); $this->register(new Opaque(new BID(Ids::MOSSY_COBBLESTONE, 0), "Mossy Cobblestone", $cobblestoneBreakInfo)); $this->register(new Stair(new BID(Ids::COBBLESTONE_STAIRS, 0), "Cobblestone Stairs", $cobblestoneBreakInfo)); $this->register(new Stair(new BID(Ids::MOSSY_COBBLESTONE_STAIRS, 0), "Mossy Cobblestone Stairs", $cobblestoneBreakInfo)); - $this->register(new Cobweb(new BID(Ids::COBWEB, 0), "Cobweb")); - $this->register(new CocoaBlock(new BID(Ids::COCOA, 0), "Cocoa Block")); + $this->register(new Cobweb(new BID(Ids::COBWEB, 0), "Cobweb", new BlockBreakInfo(4.0, BlockToolType::SWORD | BlockToolType::SHEARS, 1))); + $this->register(new CocoaBlock(new BID(Ids::COCOA, 0), "Cocoa Block", new BlockBreakInfo(0.2, BlockToolType::AXE, 0, 15.0))); $this->register(new CoralBlock(new BID(Ids::CORAL_BLOCK, 0), "Coral Block", new BlockBreakInfo(7.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - $this->register(new CraftingTable(new BID(Ids::CRAFTING_TABLE, 0), "Crafting Table")); - $this->register(new DaylightSensor(new BIDFlattened(Ids::DAYLIGHT_DETECTOR, [Ids::DAYLIGHT_DETECTOR_INVERTED], 0, null, TileDaylightSensor::class), "Daylight Sensor")); - $this->register(new DeadBush(new BID(Ids::DEADBUSH, 0), "Dead Bush")); - $this->register(new DetectorRail(new BID(Ids::DETECTOR_RAIL, 0), "Detector Rail")); + $this->register(new CraftingTable(new BID(Ids::CRAFTING_TABLE, 0), "Crafting Table", new BlockBreakInfo(2.5, BlockToolType::AXE))); + $this->register(new DaylightSensor(new BIDFlattened(Ids::DAYLIGHT_DETECTOR, [Ids::DAYLIGHT_DETECTOR_INVERTED], 0, null, TileDaylightSensor::class), "Daylight Sensor", new BlockBreakInfo(0.2, BlockToolType::AXE))); + $this->register(new DeadBush(new BID(Ids::DEADBUSH, 0), "Dead Bush", BlockBreakInfo::instant(BlockToolType::SHEARS, 1))); + $this->register(new DetectorRail(new BID(Ids::DETECTOR_RAIL, 0), "Detector Rail", $railBreakInfo)); $this->register(new Opaque(new BID(Ids::DIAMOND_BLOCK, 0), "Diamond Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); - $this->register(new DiamondOre(new BID(Ids::DIAMOND_ORE, 0), "Diamond Ore")); - $this->register(new Dirt(new BID(Ids::DIRT, Meta::DIRT_NORMAL), "Dirt")); - $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_SUNFLOWER), "Sunflower")); - $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LILAC), "Lilac")); - $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_ROSE_BUSH), "Rose Bush")); - $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_PEONY), "Peony")); - $this->register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_TALLGRASS), "Double Tallgrass")); - $this->register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LARGE_FERN), "Large Fern")); - $this->register(new DragonEgg(new BID(Ids::DRAGON_EGG, 0), "Dragon Egg")); + $this->register(new DiamondOre(new BID(Ids::DIAMOND_ORE, 0), "Diamond Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); + $this->register(new Dirt(new BID(Ids::DIRT, Meta::DIRT_NORMAL), "Dirt", $dirtBreakInfo)); + $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_SUNFLOWER), "Sunflower", BlockBreakInfo::instant())); + $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LILAC), "Lilac", BlockBreakInfo::instant())); + $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_ROSE_BUSH), "Rose Bush", BlockBreakInfo::instant())); + $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_PEONY), "Peony", BlockBreakInfo::instant())); + $this->register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_TALLGRASS), "Double Tallgrass", BlockBreakInfo::instant(BlockToolType::SHEARS, 1))); + $this->register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LARGE_FERN), "Large Fern", BlockBreakInfo::instant(BlockToolType::SHEARS, 1))); + $this->register(new DragonEgg(new BID(Ids::DRAGON_EGG, 0), "Dragon Egg", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); $this->register(new DriedKelp(new BID(Ids::DRIED_KELP_BLOCK, 0), "Dried Kelp Block", new BlockBreakInfo(0.5, BlockToolType::NONE, 0, 12.5))); $this->register(new Opaque(new BID(Ids::EMERALD_BLOCK, 0), "Emerald Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); - $this->register(new EmeraldOre(new BID(Ids::EMERALD_ORE, 0), "Emerald Ore")); - $this->register(new EnchantingTable(new BID(Ids::ENCHANTING_TABLE, 0, null, TileEnchantingTable::class), "Enchanting Table")); - $this->register(new EndPortalFrame(new BID(Ids::END_PORTAL_FRAME, 0), "End Portal Frame")); - $this->register(new EndRod(new BID(Ids::END_ROD, 0), "End Rod")); + $this->register(new EmeraldOre(new BID(Ids::EMERALD_ORE, 0), "Emerald Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); + $this->register(new EnchantingTable(new BID(Ids::ENCHANTING_TABLE, 0, null, TileEnchantingTable::class), "Enchanting Table", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 6000.0))); + $this->register(new EndPortalFrame(new BID(Ids::END_PORTAL_FRAME, 0), "End Portal Frame", BlockBreakInfo::indestructible())); + $this->register(new EndRod(new BID(Ids::END_ROD, 0), "End Rod", BlockBreakInfo::instant())); $this->register(new Opaque(new BID(Ids::END_STONE, 0), "End Stone", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 45.0))); $endBrickBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 4.0); $this->register(new Opaque(new BID(Ids::END_BRICKS, 0), "End Stone Bricks", $endBrickBreakInfo)); $this->register(new Stair(new BID(Ids::END_BRICK_STAIRS, 0), "End Stone Brick Stairs", $endBrickBreakInfo)); - $this->register(new EnderChest(new BID(Ids::ENDER_CHEST, 0, null, TileEnderChest::class), "Ender Chest")); - $this->register(new Farmland(new BID(Ids::FARMLAND, 0), "Farmland")); - $this->register(new Fire(new BID(Ids::FIRE, 0), "Fire Block")); - $this->register(new Flower(new BID(Ids::DANDELION, 0), "Dandelion")); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ALLIUM), "Allium")); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_AZURE_BLUET), "Azure Bluet")); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_BLUE_ORCHID), "Blue Orchid")); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_CORNFLOWER), "Cornflower")); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_LILY_OF_THE_VALLEY), "Lily of the Valley")); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ORANGE_TULIP), "Orange Tulip")); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_OXEYE_DAISY), "Oxeye Daisy")); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_PINK_TULIP), "Pink Tulip")); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_POPPY), "Poppy")); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_RED_TULIP), "Red Tulip")); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_WHITE_TULIP), "White Tulip")); - $this->register(new FlowerPot(new BID(Ids::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, TileFlowerPot::class), "Flower Pot")); - $this->register(new FrostedIce(new BID(Ids::FROSTED_ICE, 0), "Frosted Ice")); - $this->register(new Furnace(new BIDFlattened(Ids::FURNACE, [Ids::LIT_FURNACE], 0, null, TileFurnace::class), "Furnace")); - $this->register(new Glass(new BID(Ids::GLASS, 0), "Glass")); - $this->register(new GlassPane(new BID(Ids::GLASS_PANE, 0), "Glass Pane")); - $this->register(new GlowingObsidian(new BID(Ids::GLOWINGOBSIDIAN, 0), "Glowing Obsidian")); - $this->register(new Glowstone(new BID(Ids::GLOWSTONE, 0), "Glowstone")); + $this->register(new EnderChest(new BID(Ids::ENDER_CHEST, 0, null, TileEnderChest::class), "Ender Chest", new BlockBreakInfo(22.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 3000.0))); + $this->register(new Farmland(new BID(Ids::FARMLAND, 0), "Farmland", new BlockBreakInfo(0.6, BlockToolType::SHOVEL))); + $this->register(new Fire(new BID(Ids::FIRE, 0), "Fire Block", BlockBreakInfo::instant())); + $this->register(new Flower(new BID(Ids::DANDELION, 0), "Dandelion", BlockBreakInfo::instant())); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ALLIUM), "Allium", BlockBreakInfo::instant())); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_AZURE_BLUET), "Azure Bluet", BlockBreakInfo::instant())); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_BLUE_ORCHID), "Blue Orchid", BlockBreakInfo::instant())); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_CORNFLOWER), "Cornflower", BlockBreakInfo::instant())); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_LILY_OF_THE_VALLEY), "Lily of the Valley", BlockBreakInfo::instant())); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ORANGE_TULIP), "Orange Tulip", BlockBreakInfo::instant())); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_OXEYE_DAISY), "Oxeye Daisy", BlockBreakInfo::instant())); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_PINK_TULIP), "Pink Tulip", BlockBreakInfo::instant())); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_POPPY), "Poppy", BlockBreakInfo::instant())); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_RED_TULIP), "Red Tulip", BlockBreakInfo::instant())); + $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_WHITE_TULIP), "White Tulip", BlockBreakInfo::instant())); + $this->register(new FlowerPot(new BID(Ids::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, TileFlowerPot::class), "Flower Pot", BlockBreakInfo::instant())); + $this->register(new FrostedIce(new BID(Ids::FROSTED_ICE, 0), "Frosted Ice", new BlockBreakInfo(2.5, BlockToolType::PICKAXE))); + $this->register(new Furnace(new BIDFlattened(Ids::FURNACE, [Ids::LIT_FURNACE], 0, null, TileFurnace::class), "Furnace", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + + $glassBreakInfo = new BlockBreakInfo(0.3); + $this->register(new Glass(new BID(Ids::GLASS, 0), "Glass", $glassBreakInfo)); + $this->register(new GlassPane(new BID(Ids::GLASS_PANE, 0), "Glass Pane", $glassBreakInfo)); + $this->register(new GlowingObsidian(new BID(Ids::GLOWINGOBSIDIAN, 0), "Glowing Obsidian", new BlockBreakInfo(10.0, BlockToolType::PICKAXE, ToolTier::DIAMOND()->getHarvestLevel(), 50.0))); + $this->register(new Glowstone(new BID(Ids::GLOWSTONE, 0), "Glowstone", new BlockBreakInfo(0.3, BlockToolType::PICKAXE))); $this->register(new Opaque(new BID(Ids::GOLD_BLOCK, 0), "Gold Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); $this->register(new Opaque(new BID(Ids::GOLD_ORE, 0), "Gold Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); - $this->register(new Grass(new BID(Ids::GRASS, 0), "Grass")); - $this->register(new GrassPath(new BID(Ids::GRASS_PATH, 0), "Grass Path")); - $this->register(new Gravel(new BID(Ids::GRAVEL, 0), "Gravel")); - $this->register(new HardenedClay(new BID(Ids::HARDENED_CLAY, 0), "Hardened Clay")); - $this->register(new HardenedGlass(new BID(Ids::HARD_GLASS, 0), "Hardened Glass")); - $this->register(new HardenedGlassPane(new BID(Ids::HARD_GLASS_PANE, 0), "Hardened Glass Pane")); - $this->register(new HayBale(new BID(Ids::HAY_BALE, 0), "Hay Bale")); + + $grassBreakInfo = new BlockBreakInfo(0.6, BlockToolType::SHOVEL); + $this->register(new Grass(new BID(Ids::GRASS, 0), "Grass", $grassBreakInfo)); + $this->register(new GrassPath(new BID(Ids::GRASS_PATH, 0), "Grass Path", $grassBreakInfo)); + $this->register(new Gravel(new BID(Ids::GRAVEL, 0), "Gravel", new BlockBreakInfo(0.6, BlockToolType::SHOVEL))); + + $hardenedClayBreakInfo = new BlockBreakInfo(1.25, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 21.0); + $this->register(new HardenedClay(new BID(Ids::HARDENED_CLAY, 0), "Hardened Clay", $hardenedClayBreakInfo)); + + $hardenedGlassBreakInfo = new BlockBreakInfo(10.0); + $this->register(new HardenedGlass(new BID(Ids::HARD_GLASS, 0), "Hardened Glass", $hardenedGlassBreakInfo)); + $this->register(new HardenedGlassPane(new BID(Ids::HARD_GLASS_PANE, 0), "Hardened Glass Pane", $hardenedGlassBreakInfo)); + $this->register(new HayBale(new BID(Ids::HAY_BALE, 0), "Hay Bale", new BlockBreakInfo(0.5))); $this->register(new Hopper(new BID(Ids::HOPPER_BLOCK, 0, ItemIds::HOPPER, TileHopper::class), "Hopper", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 15.0))); - $this->register(new Ice(new BID(Ids::ICE, 0), "Ice")); + $this->register(new Ice(new BID(Ids::ICE, 0), "Ice", new BlockBreakInfo(0.5, BlockToolType::PICKAXE))); $updateBlockBreakInfo = new BlockBreakInfo(1.0); $this->register(new Opaque(new BID(Ids::INFO_UPDATE, 0), "update!", $updateBlockBreakInfo)); @@ -211,20 +228,20 @@ class BlockFactory{ $this->register(new Door(new BID(Ids::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0))); $this->register(new Opaque(new BID(Ids::IRON_ORE, 0), "Iron Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); $this->register(new Trapdoor(new BID(Ids::IRON_TRAPDOOR, 0), "Iron Trapdoor", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0))); - $this->register(new ItemFrame(new BID(Ids::FRAME_BLOCK, 0, ItemIds::FRAME, TileItemFrame::class), "Item Frame")); - $this->register(new Jukebox(new BID(Ids::JUKEBOX, 0, ItemIds::JUKEBOX, TileJukebox::class), "Jukebox")); - $this->register(new Ladder(new BID(Ids::LADDER, 0), "Ladder")); + $this->register(new ItemFrame(new BID(Ids::FRAME_BLOCK, 0, ItemIds::FRAME, TileItemFrame::class), "Item Frame", new BlockBreakInfo(0.25))); + $this->register(new Jukebox(new BID(Ids::JUKEBOX, 0, ItemIds::JUKEBOX, TileJukebox::class), "Jukebox", new BlockBreakInfo(0.8, BlockToolType::AXE))); //TODO: in PC the hardness is 2.0, not 0.8, unsure if this is a MCPE bug or not + $this->register(new Ladder(new BID(Ids::LADDER, 0), "Ladder", new BlockBreakInfo(0.4, BlockToolType::AXE))); $this->register(new Lantern(new BID(Ids::LANTERN, 0), "Lantern", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); $this->register(new Opaque(new BID(Ids::LAPIS_BLOCK, 0), "Lapis Lazuli Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); - $this->register(new LapisOre(new BID(Ids::LAPIS_ORE, 0), "Lapis Lazuli Ore")); - $this->register(new Lava(new BIDFlattened(Ids::FLOWING_LAVA, [Ids::STILL_LAVA], 0), "Lava")); - $this->register(new Lever(new BID(Ids::LEVER, 0), "Lever")); + $this->register(new LapisOre(new BID(Ids::LAPIS_ORE, 0), "Lapis Lazuli Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); + $this->register(new Lava(new BIDFlattened(Ids::FLOWING_LAVA, [Ids::STILL_LAVA], 0), "Lava", BlockBreakInfo::indestructible(500.0))); + $this->register(new Lever(new BID(Ids::LEVER, 0), "Lever", new BlockBreakInfo(0.5))); $this->register(new Loom(new BID(Ids::LOOM, 0), "Loom", new BlockBreakInfo(2.5, BlockToolType::AXE))); - $this->register(new Magma(new BID(Ids::MAGMA, 0), "Magma Block")); - $this->register(new Melon(new BID(Ids::MELON_BLOCK, 0), "Melon Block")); - $this->register(new MelonStem(new BID(Ids::MELON_STEM, 0, ItemIds::MELON_SEEDS), "Melon Stem")); - $this->register(new MonsterSpawner(new BID(Ids::MOB_SPAWNER, 0, null, TileMonsterSpawner::class), "Monster Spawner")); - $this->register(new Mycelium(new BID(Ids::MYCELIUM, 0), "Mycelium")); + $this->register(new Magma(new BID(Ids::MAGMA, 0), "Magma Block", new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->register(new Melon(new BID(Ids::MELON_BLOCK, 0), "Melon Block", new BlockBreakInfo(1.0, BlockToolType::AXE))); + $this->register(new MelonStem(new BID(Ids::MELON_STEM, 0, ItemIds::MELON_SEEDS), "Melon Stem", BlockBreakInfo::instant())); + $this->register(new MonsterSpawner(new BID(Ids::MOB_SPAWNER, 0, null, TileMonsterSpawner::class), "Monster Spawner", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->register(new Mycelium(new BID(Ids::MYCELIUM, 0), "Mycelium", new BlockBreakInfo(0.6, BlockToolType::SHOVEL))); $netherBrickBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); $this->register(new Opaque(new BID(Ids::NETHER_BRICK_BLOCK, 0), "Nether Bricks", $netherBrickBreakInfo)); @@ -232,18 +249,18 @@ class BlockFactory{ $this->register(new Fence(new BID(Ids::NETHER_BRICK_FENCE, 0), "Nether Brick Fence", $netherBrickBreakInfo)); $this->register(new Stair(new BID(Ids::NETHER_BRICK_STAIRS, 0), "Nether Brick Stairs", $netherBrickBreakInfo)); $this->register(new Stair(new BID(Ids::RED_NETHER_BRICK_STAIRS, 0), "Red Nether Brick Stairs", $netherBrickBreakInfo)); - $this->register(new NetherPortal(new BID(Ids::PORTAL, 0), "Nether Portal")); - $this->register(new NetherQuartzOre(new BID(Ids::NETHER_QUARTZ_ORE, 0), "Nether Quartz Ore")); - $this->register(new NetherReactor(new BID(Ids::NETHERREACTOR, 0), "Nether Reactor Core")); + $this->register(new NetherPortal(new BID(Ids::PORTAL, 0), "Nether Portal", BlockBreakInfo::indestructible(0.0))); + $this->register(new NetherQuartzOre(new BID(Ids::NETHER_QUARTZ_ORE, 0), "Nether Quartz Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->register(new NetherReactor(new BID(Ids::NETHERREACTOR, 0), "Nether Reactor Core", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); $this->register(new Opaque(new BID(Ids::NETHER_WART_BLOCK, 0), "Nether Wart Block", new BlockBreakInfo(1.0))); - $this->register(new NetherWartPlant(new BID(Ids::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART), "Nether Wart")); - $this->register(new Netherrack(new BID(Ids::NETHERRACK, 0), "Netherrack")); - $this->register(new Note(new BID(Ids::NOTEBLOCK, 0, null, TileNote::class), "Note Block")); + $this->register(new NetherWartPlant(new BID(Ids::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART), "Nether Wart", BlockBreakInfo::instant())); + $this->register(new Netherrack(new BID(Ids::NETHERRACK, 0), "Netherrack", new BlockBreakInfo(0.4, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->register(new Note(new BID(Ids::NOTEBLOCK, 0, null, TileNote::class), "Note Block", new BlockBreakInfo(0.8, BlockToolType::AXE))); $this->register(new Opaque(new BID(Ids::OBSIDIAN, 0), "Obsidian", new BlockBreakInfo(35.0 /* 50 in PC */, BlockToolType::PICKAXE, ToolTier::DIAMOND()->getHarvestLevel(), 6000.0))); - $this->register(new PackedIce(new BID(Ids::PACKED_ICE, 0), "Packed Ice")); - $this->register(new Podzol(new BID(Ids::PODZOL, 0), "Podzol")); - $this->register(new Potato(new BID(Ids::POTATOES, 0), "Potato Block")); - $this->register(new PoweredRail(new BID(Ids::GOLDEN_RAIL, Meta::RAIL_STRAIGHT_NORTH_SOUTH), "Powered Rail")); + $this->register(new PackedIce(new BID(Ids::PACKED_ICE, 0), "Packed Ice", new BlockBreakInfo(0.5, BlockToolType::PICKAXE))); + $this->register(new Podzol(new BID(Ids::PODZOL, 0), "Podzol", new BlockBreakInfo(0.5, BlockToolType::SHOVEL))); + $this->register(new Potato(new BID(Ids::POTATOES, 0), "Potato Block", BlockBreakInfo::instant())); + $this->register(new PoweredRail(new BID(Ids::GOLDEN_RAIL, Meta::RAIL_STRAIGHT_NORTH_SOUTH), "Powered Rail", $railBreakInfo)); $prismarineBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); $this->register(new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_BRICKS), "Prismarine Bricks", $prismarineBreakInfo)); @@ -261,7 +278,7 @@ class BlockFactory{ $this->register(new CarvedPumpkin(new BID(Ids::CARVED_PUMPKIN, 0), "Carved Pumpkin", $pumpkinBreakInfo)); $this->register(new LitPumpkin(new BID(Ids::JACK_O_LANTERN, 0), "Jack o'Lantern", $pumpkinBreakInfo)); - $this->register(new PumpkinStem(new BID(Ids::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem")); + $this->register(new PumpkinStem(new BID(Ids::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem", BlockBreakInfo::instant())); $purpurBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); $this->register(new Opaque(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_NORMAL), "Purpur Block", $purpurBreakInfo)); @@ -276,26 +293,28 @@ class BlockFactory{ $this->register(new Opaque(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_SMOOTH), "Smooth Quartz Block", $quartzBreakInfo)); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) $this->register(new Stair(new BID(Ids::SMOOTH_QUARTZ_STAIRS, 0), "Smooth Quartz Stairs", $quartzBreakInfo)); - $this->register(new Rail(new BID(Ids::RAIL, 0), "Rail")); - $this->register(new RedMushroom(new BID(Ids::RED_MUSHROOM, 0), "Red Mushroom")); - $this->register(new Redstone(new BID(Ids::REDSTONE_BLOCK, 0), "Redstone Block")); - $this->register(new RedstoneComparator(new BIDFlattened(Ids::UNPOWERED_COMPARATOR, [Ids::POWERED_COMPARATOR], 0, ItemIds::COMPARATOR, TileComparator::class), "Redstone Comparator")); - $this->register(new RedstoneLamp(new BIDFlattened(Ids::REDSTONE_LAMP, [Ids::LIT_REDSTONE_LAMP], 0), "Redstone Lamp")); - $this->register(new RedstoneOre(new BIDFlattened(Ids::REDSTONE_ORE, [Ids::LIT_REDSTONE_ORE], 0), "Redstone Ore")); - $this->register(new RedstoneRepeater(new BIDFlattened(Ids::UNPOWERED_REPEATER, [Ids::POWERED_REPEATER], 0, ItemIds::REPEATER), "Redstone Repeater")); - $this->register(new RedstoneTorch(new BIDFlattened(Ids::REDSTONE_TORCH, [Ids::UNLIT_REDSTONE_TORCH], 0), "Redstone Torch")); - $this->register(new RedstoneWire(new BID(Ids::REDSTONE_WIRE, 0, ItemIds::REDSTONE), "Redstone")); - $this->register(new Reserved6(new BID(Ids::RESERVED6, 0), "reserved6")); - $this->register(new Sand(new BID(Ids::SAND, 0), "Sand")); - $this->register(new Sand(new BID(Ids::SAND, 1), "Red Sand")); - $this->register(new SeaLantern(new BID(Ids::SEALANTERN, 0), "Sea Lantern")); - $this->register(new SeaPickle(new BID(Ids::SEA_PICKLE, 0), "Sea Pickle")); - $this->register(new Skull(new BID(Ids::MOB_HEAD_BLOCK, 0, null, TileSkull::class), "Mob Head")); + $this->register(new Rail(new BID(Ids::RAIL, 0), "Rail", $railBreakInfo)); + $this->register(new RedMushroom(new BID(Ids::RED_MUSHROOM, 0), "Red Mushroom", BlockBreakInfo::instant())); + $this->register(new Redstone(new BID(Ids::REDSTONE_BLOCK, 0), "Redstone Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0))); + $this->register(new RedstoneComparator(new BIDFlattened(Ids::UNPOWERED_COMPARATOR, [Ids::POWERED_COMPARATOR], 0, ItemIds::COMPARATOR, TileComparator::class), "Redstone Comparator", BlockBreakInfo::instant())); + $this->register(new RedstoneLamp(new BIDFlattened(Ids::REDSTONE_LAMP, [Ids::LIT_REDSTONE_LAMP], 0), "Redstone Lamp", new BlockBreakInfo(0.3))); + $this->register(new RedstoneOre(new BIDFlattened(Ids::REDSTONE_ORE, [Ids::LIT_REDSTONE_ORE], 0), "Redstone Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); + $this->register(new RedstoneRepeater(new BIDFlattened(Ids::UNPOWERED_REPEATER, [Ids::POWERED_REPEATER], 0, ItemIds::REPEATER), "Redstone Repeater", BlockBreakInfo::instant())); + $this->register(new RedstoneTorch(new BIDFlattened(Ids::REDSTONE_TORCH, [Ids::UNLIT_REDSTONE_TORCH], 0), "Redstone Torch", BlockBreakInfo::instant())); + $this->register(new RedstoneWire(new BID(Ids::REDSTONE_WIRE, 0, ItemIds::REDSTONE), "Redstone", BlockBreakInfo::instant())); + $this->register(new Reserved6(new BID(Ids::RESERVED6, 0), "reserved6", BlockBreakInfo::instant())); - $this->register(new Snow(new BID(Ids::SNOW, 0), "Snow Block")); - $this->register(new SnowLayer(new BID(Ids::SNOW_LAYER, 0), "Snow Layer")); - $this->register(new SoulSand(new BID(Ids::SOUL_SAND, 0), "Soul Sand")); - $this->register(new Sponge(new BID(Ids::SPONGE, 0), "Sponge")); + $sandBreakInfo = new BlockBreakInfo(0.5, BlockToolType::SHOVEL); + $this->register(new Sand(new BID(Ids::SAND, 0), "Sand", $sandBreakInfo)); + $this->register(new Sand(new BID(Ids::SAND, 1), "Red Sand", $sandBreakInfo)); + $this->register(new SeaLantern(new BID(Ids::SEALANTERN, 0), "Sea Lantern", new BlockBreakInfo(0.3))); + $this->register(new SeaPickle(new BID(Ids::SEA_PICKLE, 0), "Sea Pickle", BlockBreakInfo::instant())); + $this->register(new Skull(new BID(Ids::MOB_HEAD_BLOCK, 0, null, TileSkull::class), "Mob Head", new BlockBreakInfo(1.0))); + + $this->register(new Snow(new BID(Ids::SNOW, 0), "Snow Block", new BlockBreakInfo(0.2, BlockToolType::SHOVEL, ToolTier::WOOD()->getHarvestLevel()))); + $this->register(new SnowLayer(new BID(Ids::SNOW_LAYER, 0), "Snow Layer", new BlockBreakInfo(0.1, BlockToolType::SHOVEL, ToolTier::WOOD()->getHarvestLevel()))); + $this->register(new SoulSand(new BID(Ids::SOUL_SAND, 0), "Soul Sand", new BlockBreakInfo(0.5, BlockToolType::SHOVEL))); + $this->register(new Sponge(new BID(Ids::SPONGE, 0), "Sponge", new BlockBreakInfo(0.6, BlockToolType::HOE))); $stoneBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); $this->register($stone = new class(new BID(Ids::STONE, Meta::STONE_NORMAL), "Stone", $stoneBreakInfo) extends Opaque{ @@ -307,7 +326,7 @@ class BlockFactory{ return true; } }); - $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE), "Infested Stone", $stone)); + $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE), "Infested Stone", $infestedStoneBreakInfo, $stone)); $this->register(new Stair(new BID(Ids::NORMAL_STONE_STAIRS, 0), "Stone Stairs", $stoneBreakInfo)); $this->register(new Opaque(new BID(Ids::SMOOTH_STONE, 0), "Smooth Stone", $stoneBreakInfo)); $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_ANDESITE), "Andesite", $stoneBreakInfo)); @@ -324,16 +343,16 @@ class BlockFactory{ $this->register(new Stair(new BID(Ids::POLISHED_GRANITE_STAIRS, 0), "Polished Granite Stairs", $stoneBreakInfo)); $this->register(new Stair(new BID(Ids::STONE_BRICK_STAIRS, 0), "Stone Brick Stairs", $stoneBreakInfo)); $this->register($chiseledStoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CHISELED), "Chiseled Stone Bricks", $stoneBreakInfo)); - $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CHISELED), "Infested Chiseled Stone Brick", $chiseledStoneBrick)); + $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CHISELED), "Infested Chiseled Stone Brick", $infestedStoneBreakInfo, $chiseledStoneBrick)); $this->register($crackedStoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CRACKED), "Cracked Stone Bricks", $stoneBreakInfo)); - $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CRACKED), "Infested Cracked Stone Brick", $crackedStoneBrick)); + $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CRACKED), "Infested Cracked Stone Brick", $infestedStoneBreakInfo, $crackedStoneBrick)); $this->register($mossyStoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_MOSSY), "Mossy Stone Bricks", $stoneBreakInfo)); - $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_MOSSY), "Infested Mossy Stone Brick", $mossyStoneBrick)); + $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_MOSSY), "Infested Mossy Stone Brick", $infestedStoneBreakInfo, $mossyStoneBrick)); $this->register(new Stair(new BID(Ids::MOSSY_STONE_BRICK_STAIRS, 0), "Mossy Stone Brick Stairs", $stoneBreakInfo)); $this->register($stoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_NORMAL), "Stone Bricks", $stoneBreakInfo)); - $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK), "Infested Stone Brick", $stoneBrick)); - $this->register(new StoneButton(new BID(Ids::STONE_BUTTON, 0), "Stone Button")); - $this->register(new StonePressurePlate(new BID(Ids::STONE_PRESSURE_PLATE, 0), "Stone Pressure Plate")); + $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK), "Infested Stone Brick", $infestedStoneBreakInfo, $stoneBrick)); + $this->register(new StoneButton(new BID(Ids::STONE_BUTTON, 0), "Stone Button", new BlockBreakInfo(0.5, BlockToolType::PICKAXE))); + $this->register(new StonePressurePlate(new BID(Ids::STONE_PRESSURE_PLATE, 0), "Stone Pressure Plate", new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); //TODO: in the future this won't be the same for all the types $stoneSlabBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); @@ -367,57 +386,71 @@ class BlockFactory{ $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_SMOOTH_QUARTZ), "Smooth Quartz", $stoneSlabBreakInfo)); $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_STONE), "Stone", $stoneSlabBreakInfo)); $this->register(new Opaque(new BID(Ids::STONECUTTER, 0), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - $this->register(new Sugarcane(new BID(Ids::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane")); - $this->register(new TNT(new BID(Ids::TNT, 0), "TNT")); + $this->register(new Sugarcane(new BID(Ids::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane", BlockBreakInfo::instant())); + $this->register(new TNT(new BID(Ids::TNT, 0), "TNT", BlockBreakInfo::instant())); - $fern = new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_FERN), "Fern"); + $fern = new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_FERN), "Fern", BlockBreakInfo::instant(BlockToolType::SHEARS, 1)); $this->register($fern); $this->remap(Ids::TALLGRASS, 0, $fern); $this->remap(Ids::TALLGRASS, 3, $fern); - $this->register(new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_NORMAL), "Tall Grass")); - $this->register(new Torch(new BID(Ids::COLORED_TORCH_BP, 0), "Blue Torch")); - $this->register(new Torch(new BID(Ids::COLORED_TORCH_BP, 8), "Purple Torch")); - $this->register(new Torch(new BID(Ids::COLORED_TORCH_RG, 0), "Red Torch")); - $this->register(new Torch(new BID(Ids::COLORED_TORCH_RG, 8), "Green Torch")); - $this->register(new Torch(new BID(Ids::TORCH, 0), "Torch")); - $this->register(new TrappedChest(new BID(Ids::TRAPPED_CHEST, 0, null, TileChest::class), "Trapped Chest")); - $this->register(new Tripwire(new BID(Ids::TRIPWIRE, 0, ItemIds::STRING), "Tripwire")); - $this->register(new TripwireHook(new BID(Ids::TRIPWIRE_HOOK, 0), "Tripwire Hook")); - $this->register(new UnderwaterTorch(new BID(Ids::UNDERWATER_TORCH, 0), "Underwater Torch")); - $this->register(new Vine(new BID(Ids::VINE, 0), "Vines")); - $this->register(new Water(new BIDFlattened(Ids::FLOWING_WATER, [Ids::STILL_WATER], 0), "Water")); - $this->register(new WaterLily(new BID(Ids::LILY_PAD, 0), "Lily Pad")); - $this->register(new WeightedPressurePlateHeavy(new BID(Ids::HEAVY_WEIGHTED_PRESSURE_PLATE, 0), "Weighted Pressure Plate Heavy")); - $this->register(new WeightedPressurePlateLight(new BID(Ids::LIGHT_WEIGHTED_PRESSURE_PLATE, 0), "Weighted Pressure Plate Light")); - $this->register(new Wheat(new BID(Ids::WHEAT_BLOCK, 0), "Wheat Block")); + $this->register(new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_NORMAL), "Tall Grass", BlockBreakInfo::instant(BlockToolType::SHEARS, 1))); + $this->register(new Torch(new BID(Ids::COLORED_TORCH_BP, 0), "Blue Torch", BlockBreakInfo::instant())); + $this->register(new Torch(new BID(Ids::COLORED_TORCH_BP, 8), "Purple Torch", BlockBreakInfo::instant())); + $this->register(new Torch(new BID(Ids::COLORED_TORCH_RG, 0), "Red Torch", BlockBreakInfo::instant())); + $this->register(new Torch(new BID(Ids::COLORED_TORCH_RG, 8), "Green Torch", BlockBreakInfo::instant())); + $this->register(new Torch(new BID(Ids::TORCH, 0), "Torch", BlockBreakInfo::instant())); + $this->register(new TrappedChest(new BID(Ids::TRAPPED_CHEST, 0, null, TileChest::class), "Trapped Chest", $chestBreakInfo)); + $this->register(new Tripwire(new BID(Ids::TRIPWIRE, 0, ItemIds::STRING), "Tripwire", BlockBreakInfo::instant())); + $this->register(new TripwireHook(new BID(Ids::TRIPWIRE_HOOK, 0), "Tripwire Hook", BlockBreakInfo::instant())); + $this->register(new UnderwaterTorch(new BID(Ids::UNDERWATER_TORCH, 0), "Underwater Torch", BlockBreakInfo::instant())); + $this->register(new Vine(new BID(Ids::VINE, 0), "Vines", new BlockBreakInfo(0.2, BlockToolType::AXE))); + $this->register(new Water(new BIDFlattened(Ids::FLOWING_WATER, [Ids::STILL_WATER], 0), "Water", BlockBreakInfo::indestructible(500.0))); + $this->register(new WaterLily(new BID(Ids::LILY_PAD, 0), "Lily Pad", new BlockBreakInfo(0.6))); + $weightedPressurePlateBreakInfo = new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()); + $this->register(new WeightedPressurePlateHeavy(new BID(Ids::HEAVY_WEIGHTED_PRESSURE_PLATE, 0), "Weighted Pressure Plate Heavy", $weightedPressurePlateBreakInfo)); + $this->register(new WeightedPressurePlateLight(new BID(Ids::LIGHT_WEIGHTED_PRESSURE_PLATE, 0), "Weighted Pressure Plate Light", $weightedPressurePlateBreakInfo)); + $this->register(new Wheat(new BID(Ids::WHEAT_BLOCK, 0), "Wheat Block", BlockBreakInfo::instant())); + + $fenceGateBreakInfo = new BlockBreakInfo(2.0, BlockToolType::AXE); + $leavesBreakInfo = new BlockBreakInfo(0.2, BlockToolType::SHEARS); + $planksBreakInfo = new BlockBreakInfo(2.0, BlockToolType::AXE, 0, 15.0); + $signBreakInfo = new BlockBreakInfo(1.0, BlockToolType::AXE); + $logBreakInfo = new BlockBreakInfo(2.0, BlockToolType::AXE); + $woodenDoorBreakInfo = new BlockBreakInfo(3.0, BlockToolType::AXE); + $woodenButtonBreakInfo = new BlockBreakInfo(0.5, BlockToolType::AXE); + $woodenFenceBreakInfo = new BlockBreakInfo(2.0, BlockToolType::AXE, 0, 15.0); + $woodenPressurePlateBreakInfo = new BlockBreakInfo(0.5, BlockToolType::AXE); + $woodenSlabBreakInfo = new BlockBreakInfo(2.0, BlockToolType::AXE, 0, 15.0); + $woodenStairsBreakInfo = new BlockBreakInfo(2.0, BlockToolType::AXE, 0, 15.0); + $woodenTrapdoorBreakInfo = new BlockBreakInfo(3.0, BlockToolType::AXE, 0, 15.0); foreach(TreeType::getAll() as $treeType){ $magicNumber = $treeType->getMagicNumber(); $name = $treeType->getDisplayName(); - $this->register(new Planks(new BID(Ids::PLANKS, $magicNumber), $name . " Planks")); - $this->register(new Sapling(new BID(Ids::SAPLING, $magicNumber), $name . " Sapling", $treeType)); - $this->register(new WoodenFence(new BID(Ids::FENCE, $magicNumber), $name . " Fence")); - $this->register(new WoodenSlab(new BIDFlattened(Ids::WOODEN_SLAB, [Ids::DOUBLE_WOODEN_SLAB], $treeType->getMagicNumber()), $treeType->getDisplayName())); + $this->register(new Planks(new BID(Ids::PLANKS, $magicNumber), $name . " Planks", $planksBreakInfo)); + $this->register(new Sapling(new BID(Ids::SAPLING, $magicNumber), $name . " Sapling", BlockBreakInfo::instant(), $treeType)); + $this->register(new WoodenFence(new BID(Ids::FENCE, $magicNumber), $name . " Fence", $woodenFenceBreakInfo)); + $this->register(new WoodenSlab(new BIDFlattened(Ids::WOODEN_SLAB, [Ids::DOUBLE_WOODEN_SLAB], $treeType->getMagicNumber()), $treeType->getDisplayName(), $woodenSlabBreakInfo)); //TODO: find a better way to deal with this split - $this->register(new Leaves(new BID($magicNumber >= 4 ? Ids::LEAVES2 : Ids::LEAVES, $magicNumber & 0x03), $name . " Leaves", $treeType)); - $this->register(new Log(new BID($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, $magicNumber & 0x03), $name . " Log", $treeType, false)); + $this->register(new Leaves(new BID($magicNumber >= 4 ? Ids::LEAVES2 : Ids::LEAVES, $magicNumber & 0x03), $name . " Leaves", $leavesBreakInfo, $treeType)); + $this->register(new Log(new BID($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, $magicNumber & 0x03), $name . " Log", $logBreakInfo, $treeType, false)); - $wood = new Wood(new BID(Ids::WOOD, $magicNumber), $name . " Wood", $treeType, false); + $wood = new Wood(new BID(Ids::WOOD, $magicNumber), $name . " Wood", $logBreakInfo, $treeType, false); $this->register($wood); $this->remap($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, ($magicNumber & 0x03) | 0b1100, $wood); - $this->register(new Log(BlockLegacyIdHelper::getStrippedLogIdentifier($treeType), "Stripped " . $treeType->getDisplayName() . " Log", $treeType, true)); - $this->register(new FenceGate(BlockLegacyIdHelper::getWoodenFenceIdentifier($treeType), $treeType->getDisplayName() . " Fence Gate")); - $this->register(new WoodenStairs(BlockLegacyIdHelper::getWoodenStairsIdentifier($treeType), $treeType->getDisplayName() . " Stairs")); - $this->register(new WoodenDoor(BlockLegacyIdHelper::getWoodenDoorIdentifier($treeType), $treeType->getDisplayName() . " Door")); + $this->register(new Log(BlockLegacyIdHelper::getStrippedLogIdentifier($treeType), "Stripped " . $treeType->getDisplayName() . " Log", $logBreakInfo, $treeType, true)); + $this->register(new FenceGate(BlockLegacyIdHelper::getWoodenFenceIdentifier($treeType), $treeType->getDisplayName() . " Fence Gate", $fenceGateBreakInfo)); + $this->register(new WoodenStairs(BlockLegacyIdHelper::getWoodenStairsIdentifier($treeType), $treeType->getDisplayName() . " Stairs", $woodenStairsBreakInfo)); + $this->register(new WoodenDoor(BlockLegacyIdHelper::getWoodenDoorIdentifier($treeType), $treeType->getDisplayName() . " Door", $woodenDoorBreakInfo)); - $this->register(new WoodenButton(BlockLegacyIdHelper::getWoodenButtonIdentifier($treeType), $treeType->getDisplayName() . " Button")); - $this->register(new WoodenPressurePlate(BlockLegacyIdHelper::getWoodenPressurePlateIdentifier($treeType), $treeType->getDisplayName() . " Pressure Plate")); - $this->register(new WoodenTrapdoor(BlockLegacyIdHelper::getWoodenTrapdoorIdentifier($treeType), $treeType->getDisplayName() . " Trapdoor")); + $this->register(new WoodenButton(BlockLegacyIdHelper::getWoodenButtonIdentifier($treeType), $treeType->getDisplayName() . " Button", $woodenButtonBreakInfo)); + $this->register(new WoodenPressurePlate(BlockLegacyIdHelper::getWoodenPressurePlateIdentifier($treeType), $treeType->getDisplayName() . " Pressure Plate", $woodenPressurePlateBreakInfo)); + $this->register(new WoodenTrapdoor(BlockLegacyIdHelper::getWoodenTrapdoorIdentifier($treeType), $treeType->getDisplayName() . " Trapdoor", $woodenTrapdoorBreakInfo)); - $this->register(new FloorSign(BlockLegacyIdHelper::getWoodenFloorSignIdentifier($treeType), $treeType->getDisplayName() . " Sign")); - $this->register(new WallSign(BlockLegacyIdHelper::getWoodenWallSignIdentifier($treeType), $treeType->getDisplayName() . " Wall Sign")); + $this->register(new FloorSign(BlockLegacyIdHelper::getWoodenFloorSignIdentifier($treeType), $treeType->getDisplayName() . " Sign", $signBreakInfo)); + $this->register(new WallSign(BlockLegacyIdHelper::getWoodenWallSignIdentifier($treeType), $treeType->getDisplayName() . " Wall Sign", $signBreakInfo)); } static $sandstoneTypes = [ @@ -436,36 +469,48 @@ class BlockFactory{ $this->register(new Opaque(new BID(Ids::RED_SANDSTONE, $variant), $prefix . "Red Sandstone", $sandstoneBreakInfo)); } + $glazedTerracottaBreakInfo = new BlockBreakInfo(1.4, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()); foreach(DyeColor::getAll() as $color){ $coloredName = function(string $name) use($color) : string{ return $color->getDisplayName() . " " . $name; }; - $this->register(new GlazedTerracotta(BlockLegacyIdHelper::getGlazedTerracottaIdentifier($color), $coloredName("Glazed Terracotta"))); + $this->register(new GlazedTerracotta(BlockLegacyIdHelper::getGlazedTerracottaIdentifier($color), $coloredName("Glazed Terracotta"), $glazedTerracottaBreakInfo)); } - $this->register(new StainedGlass(new BID(Ids::STAINED_GLASS, 0), "Stained Glass")); - $this->register(new StainedGlassPane(new BID(Ids::STAINED_GLASS_PANE, 0), "Stained Glass Pane")); - $this->register(new StainedHardenedClay(new BID(Ids::STAINED_CLAY, 0), "Stained Clay")); - $this->register(new StainedHardenedGlass(new BID(Ids::HARD_STAINED_GLASS, 0), "Stained Hardened Glass")); - $this->register(new StainedHardenedGlassPane(new BID(Ids::HARD_STAINED_GLASS_PANE, 0), "Stained Hardened Glass Pane")); - $this->register(new Carpet(new BID(Ids::CARPET, 0), "Carpet")); - $this->register(new Concrete(new BID(Ids::CONCRETE, 0), "Concrete")); - $this->register(new ConcretePowder(new BID(Ids::CONCRETE_POWDER, 0), "Concrete Powder")); - $this->register(new Wool(new BID(Ids::WOOL, 0), "Wool")); + $this->register(new StainedGlass(new BID(Ids::STAINED_GLASS, 0), "Stained Glass", $glassBreakInfo)); + $this->register(new StainedGlassPane(new BID(Ids::STAINED_GLASS_PANE, 0), "Stained Glass Pane", $glassBreakInfo)); + $this->register(new StainedHardenedClay(new BID(Ids::STAINED_CLAY, 0), "Stained Clay", $hardenedClayBreakInfo)); + $this->register(new StainedHardenedGlass(new BID(Ids::HARD_STAINED_GLASS, 0), "Stained Hardened Glass", $hardenedGlassBreakInfo)); + $this->register(new StainedHardenedGlassPane(new BID(Ids::HARD_STAINED_GLASS_PANE, 0), "Stained Hardened Glass Pane", $hardenedGlassBreakInfo)); + $this->register(new Carpet(new BID(Ids::CARPET, 0), "Carpet", new BlockBreakInfo(0.1))); + $this->register(new Concrete(new BID(Ids::CONCRETE, 0), "Concrete", new BlockBreakInfo(1.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->register(new ConcretePowder(new BID(Ids::CONCRETE_POWDER, 0), "Concrete Powder", new BlockBreakInfo(0.5, BlockToolType::SHOVEL))); + $this->register(new Wool(new BID(Ids::WOOL, 0), "Wool", new class(0.8, BlockToolType::SHEARS) extends BlockBreakInfo{ + public function getBreakTime(Item $item) : float{ + $time = parent::getBreakTime($item); + if($item->getBlockToolType() === BlockToolType::SHEARS){ + $time *= 3; //shears break compatible blocks 15x faster, but wool 5x + } - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_ANDESITE), "Andesite Wall")); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_BRICK), "Brick Wall")); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_DIORITE), "Diorite Wall")); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_END_STONE_BRICK), "End Stone Brick Wall")); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_GRANITE), "Granite Wall")); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_MOSSY_STONE_BRICK), "Mossy Stone Brick Wall")); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_MOSSY_COBBLESTONE), "Mossy Cobblestone Wall")); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_NETHER_BRICK), "Nether Brick Wall")); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_COBBLESTONE), "Cobblestone Wall")); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_PRISMARINE), "Prismarine Wall")); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_RED_NETHER_BRICK), "Red Nether Brick Wall")); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_RED_SANDSTONE), "Red Sandstone Wall")); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_SANDSTONE), "Sandstone Wall")); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_STONE_BRICK), "Stone Brick Wall")); + return $time; + } + })); + + //TODO: in the future these won't all have the same hardness; they only do now because of the old metadata crap + $wallBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_ANDESITE), "Andesite Wall", $wallBreakInfo)); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_BRICK), "Brick Wall", $wallBreakInfo)); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_DIORITE), "Diorite Wall", $wallBreakInfo)); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_END_STONE_BRICK), "End Stone Brick Wall", $wallBreakInfo)); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_GRANITE), "Granite Wall", $wallBreakInfo)); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_MOSSY_STONE_BRICK), "Mossy Stone Brick Wall", $wallBreakInfo)); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_MOSSY_COBBLESTONE), "Mossy Cobblestone Wall", $wallBreakInfo)); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_NETHER_BRICK), "Nether Brick Wall", $wallBreakInfo)); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_COBBLESTONE), "Cobblestone Wall", $wallBreakInfo)); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_PRISMARINE), "Prismarine Wall", $wallBreakInfo)); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_RED_NETHER_BRICK), "Red Nether Brick Wall", $wallBreakInfo)); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_RED_SANDSTONE), "Red Sandstone Wall", $wallBreakInfo)); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_SANDSTONE), "Sandstone Wall", $wallBreakInfo)); + $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_STONE_BRICK), "Stone Brick Wall", $wallBreakInfo)); $this->registerElements(); @@ -914,7 +959,7 @@ class BlockFactory{ } if($block === null){ - $block = new UnknownBlock(new BID($id, $meta)); + $block = new UnknownBlock(new BID($id, $meta), BlockBreakInfo::instant()); } return $block; diff --git a/src/block/BlueIce.php b/src/block/BlueIce.php index 7339f8271f..bcd39d24cb 100644 --- a/src/block/BlueIce.php +++ b/src/block/BlueIce.php @@ -27,10 +27,6 @@ use pocketmine\item\Item; class BlueIce extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.8, BlockToolType::PICKAXE)); - } - public function getLightLevel() : int{ return 1; } diff --git a/src/block/BoneBlock.php b/src/block/BoneBlock.php index 49ca51f9bd..d00ab63f36 100644 --- a/src/block/BoneBlock.php +++ b/src/block/BoneBlock.php @@ -24,12 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\PillarRotationInMetadataTrait; -use pocketmine\item\ToolTier; class BoneBlock extends Opaque{ use PillarRotationInMetadataTrait; - - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); - } } diff --git a/src/block/Bookshelf.php b/src/block/Bookshelf.php index e72d99b96f..2c4ec12a62 100644 --- a/src/block/Bookshelf.php +++ b/src/block/Bookshelf.php @@ -28,10 +28,6 @@ use pocketmine\item\VanillaItems; class Bookshelf extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.5, BlockToolType::AXE)); - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ VanillaItems::BOOK()->setCount(3) diff --git a/src/block/BrewingStand.php b/src/block/BrewingStand.php index 8fca8f216f..f94f73c2a2 100644 --- a/src/block/BrewingStand.php +++ b/src/block/BrewingStand.php @@ -26,7 +26,6 @@ namespace pocketmine\block; use pocketmine\block\tile\BrewingStand as TileBrewingStand; use pocketmine\block\utils\BrewingStandSlot; use pocketmine\item\Item; -use pocketmine\item\ToolTier; use pocketmine\math\Vector3; use pocketmine\player\Player; use function array_key_exists; @@ -39,10 +38,6 @@ class BrewingStand extends Transparent{ */ protected $slots = []; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); - } - protected function writeStateToMeta() : int{ $flags = 0; foreach([ diff --git a/src/block/Cactus.php b/src/block/Cactus.php index dde4dac4d8..69ea4eb98e 100644 --- a/src/block/Cactus.php +++ b/src/block/Cactus.php @@ -40,10 +40,6 @@ class Cactus extends Transparent{ /** @var int */ protected $age = 0; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.4)); - } - protected function writeStateToMeta() : int{ return $this->age; } diff --git a/src/block/Cake.php b/src/block/Cake.php index 53f44a423b..3926579494 100644 --- a/src/block/Cake.php +++ b/src/block/Cake.php @@ -39,10 +39,6 @@ class Cake extends Transparent implements FoodSource{ /** @var int */ protected $bites = 0; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5)); - } - protected function writeStateToMeta() : int{ return $this->bites; } diff --git a/src/block/Carpet.php b/src/block/Carpet.php index 19de695e66..8878b7b81f 100644 --- a/src/block/Carpet.php +++ b/src/block/Carpet.php @@ -35,9 +35,9 @@ use pocketmine\world\BlockTransaction; class Carpet extends Flowable{ use ColorInMetadataTrait; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ $this->color = DyeColor::WHITE(); - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.1)); + parent::__construct($idInfo, $name, $breakInfo); } public function isSolid() : bool{ diff --git a/src/block/Chest.php b/src/block/Chest.php index c48d3d1fa4..46c5eb5440 100644 --- a/src/block/Chest.php +++ b/src/block/Chest.php @@ -36,10 +36,6 @@ class Chest extends Transparent{ use FacesOppositePlacingPlayerTrait; use NormalHorizontalFacingInMetadataTrait; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.5, BlockToolType::AXE)); - } - /** * @return AxisAlignedBB[] */ diff --git a/src/block/Clay.php b/src/block/Clay.php index 2947a50bef..8e86d4925b 100644 --- a/src/block/Clay.php +++ b/src/block/Clay.php @@ -28,10 +28,6 @@ use pocketmine\item\VanillaItems; class Clay extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::SHOVEL)); - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ VanillaItems::CLAY()->setCount(4) diff --git a/src/block/Coal.php b/src/block/Coal.php index 27e86bc036..821c422ded 100644 --- a/src/block/Coal.php +++ b/src/block/Coal.php @@ -23,14 +23,8 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\ToolTier; - class Coal extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0)); - } - public function getFuelTime() : int{ return 16000; } diff --git a/src/block/CoalOre.php b/src/block/CoalOre.php index 33b514c09a..3c87560b15 100644 --- a/src/block/CoalOre.php +++ b/src/block/CoalOre.php @@ -24,16 +24,11 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; use function mt_rand; class CoalOre extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ VanillaItems::COAL() diff --git a/src/block/Cobweb.php b/src/block/Cobweb.php index 1f042ed299..680af15952 100644 --- a/src/block/Cobweb.php +++ b/src/block/Cobweb.php @@ -29,10 +29,6 @@ use pocketmine\item\VanillaItems; class Cobweb extends Flowable{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(4.0, BlockToolType::SWORD | BlockToolType::SHEARS, 1)); - } - public function hasEntityCollision() : bool{ return true; } diff --git a/src/block/CocoaBlock.php b/src/block/CocoaBlock.php index c725f50ca5..0ccb579784 100644 --- a/src/block/CocoaBlock.php +++ b/src/block/CocoaBlock.php @@ -43,10 +43,6 @@ class CocoaBlock extends Transparent{ /** @var int */ protected $age = 0; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::AXE, 0, 15.0)); - } - protected function writeStateToMeta() : int{ return BlockDataSerializer::writeLegacyHorizontalFacing(Facing::opposite($this->facing)) | ($this->age << 2); } diff --git a/src/block/Concrete.php b/src/block/Concrete.php index 6735c8dce6..9feb5e0933 100644 --- a/src/block/Concrete.php +++ b/src/block/Concrete.php @@ -25,13 +25,12 @@ namespace pocketmine\block; use pocketmine\block\utils\ColorInMetadataTrait; use pocketmine\block\utils\DyeColor; -use pocketmine\item\ToolTier; class Concrete extends Opaque{ use ColorInMetadataTrait; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ $this->color = DyeColor::WHITE(); - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); + parent::__construct($idInfo, $name, $breakInfo); } } diff --git a/src/block/ConcretePowder.php b/src/block/ConcretePowder.php index 826230983e..d65d682d23 100644 --- a/src/block/ConcretePowder.php +++ b/src/block/ConcretePowder.php @@ -35,9 +35,9 @@ class ConcretePowder extends Opaque implements Fallable{ onNearbyBlockChange as protected startFalling; } - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ $this->color = DyeColor::WHITE(); - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::SHOVEL)); + parent::__construct($idInfo, $name, $breakInfo); } public function onNearbyBlockChange() : void{ diff --git a/src/block/CraftingTable.php b/src/block/CraftingTable.php index d4f0259ed7..a3d1dc47fe 100644 --- a/src/block/CraftingTable.php +++ b/src/block/CraftingTable.php @@ -30,10 +30,6 @@ use pocketmine\player\Player; class CraftingTable extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.5, BlockToolType::AXE)); - } - public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ $player->setCraftingGrid(new CraftingGrid($player, CraftingGrid::SIZE_BIG)); diff --git a/src/block/Crops.php b/src/block/Crops.php index 67f98df950..d931fa3713 100644 --- a/src/block/Crops.php +++ b/src/block/Crops.php @@ -37,10 +37,6 @@ abstract class Crops extends Flowable{ /** @var int */ protected $age = 0; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); - } - protected function writeStateToMeta() : int{ return $this->age; } diff --git a/src/block/DaylightSensor.php b/src/block/DaylightSensor.php index 594060bbb1..68d5f6cabc 100644 --- a/src/block/DaylightSensor.php +++ b/src/block/DaylightSensor.php @@ -44,8 +44,8 @@ class DaylightSensor extends Transparent{ /** @var bool */ protected $inverted = false; - public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::AXE)); + public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + parent::__construct($idInfo, $name, $breakInfo); } public function getId() : int{ diff --git a/src/block/DeadBush.php b/src/block/DeadBush.php index e4de2c8abf..3f6f4d8a76 100644 --- a/src/block/DeadBush.php +++ b/src/block/DeadBush.php @@ -33,10 +33,6 @@ use function mt_rand; class DeadBush extends Flowable{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant(BlockToolType::SHEARS, 1)); - } - public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$this->getSide(Facing::DOWN)->isTransparent()){ return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); diff --git a/src/block/DiamondOre.php b/src/block/DiamondOre.php index c6d104ba5d..2307d30c2f 100644 --- a/src/block/DiamondOre.php +++ b/src/block/DiamondOre.php @@ -24,16 +24,11 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; use function mt_rand; class DiamondOre extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel())); - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ VanillaItems::DIAMOND() diff --git a/src/block/Dirt.php b/src/block/Dirt.php index 7dab9b0093..3bc27aa151 100644 --- a/src/block/Dirt.php +++ b/src/block/Dirt.php @@ -31,10 +31,6 @@ use pocketmine\player\Player; class Dirt extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::SHOVEL)); - } - public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP and $item instanceof Hoe){ $item->applyDamage(1); diff --git a/src/block/DoublePlant.php b/src/block/DoublePlant.php index b558ff756e..aade018299 100644 --- a/src/block/DoublePlant.php +++ b/src/block/DoublePlant.php @@ -34,10 +34,6 @@ class DoublePlant extends Flowable{ /** @var bool */ protected $top = false; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); - } - protected function writeStateToMeta() : int{ return ($this->top ? BlockLegacyMetadata::DOUBLE_PLANT_FLAG_TOP : 0); } diff --git a/src/block/DoubleTallGrass.php b/src/block/DoubleTallGrass.php index dedf3dc5f7..7c6769800c 100644 --- a/src/block/DoubleTallGrass.php +++ b/src/block/DoubleTallGrass.php @@ -29,10 +29,6 @@ use function mt_rand; class DoubleTallGrass extends DoublePlant{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant(BlockToolType::SHEARS, 1)); - } - public function canBeReplaced() : bool{ return true; } diff --git a/src/block/DragonEgg.php b/src/block/DragonEgg.php index 5a2afff3f6..8f02a740a8 100644 --- a/src/block/DragonEgg.php +++ b/src/block/DragonEgg.php @@ -27,7 +27,6 @@ use pocketmine\block\utils\Fallable; use pocketmine\block\utils\FallableTrait; use pocketmine\event\block\BlockTeleportEvent; use pocketmine\item\Item; -use pocketmine\item\ToolTier; use pocketmine\math\Vector3; use pocketmine\player\GameMode; use pocketmine\player\Player; @@ -40,10 +39,6 @@ use function mt_rand; class DragonEgg extends Transparent implements Fallable{ use FallableTrait; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); - } - public function getLightLevel() : int{ return 1; } diff --git a/src/block/EmeraldOre.php b/src/block/EmeraldOre.php index ec630c3bba..09d8f3a5a9 100644 --- a/src/block/EmeraldOre.php +++ b/src/block/EmeraldOre.php @@ -24,16 +24,11 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; use function mt_rand; class EmeraldOre extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel())); - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ VanillaItems::EMERALD() diff --git a/src/block/EnchantingTable.php b/src/block/EnchantingTable.php index d59e258dd2..9a402a827e 100644 --- a/src/block/EnchantingTable.php +++ b/src/block/EnchantingTable.php @@ -25,7 +25,6 @@ namespace pocketmine\block; use pocketmine\block\inventory\EnchantInventory; use pocketmine\item\Item; -use pocketmine\item\ToolTier; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -33,10 +32,6 @@ use pocketmine\player\Player; class EnchantingTable extends Transparent{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 6000.0)); - } - /** * @return AxisAlignedBB[] */ diff --git a/src/block/EndPortalFrame.php b/src/block/EndPortalFrame.php index 2a553a2a9e..b1ec84fa64 100644 --- a/src/block/EndPortalFrame.php +++ b/src/block/EndPortalFrame.php @@ -36,10 +36,6 @@ class EndPortalFrame extends Opaque{ /** @var bool */ protected $eye = false; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::indestructible()); - } - protected function writeStateToMeta() : int{ return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) | ($this->eye ? BlockLegacyMetadata::END_PORTAL_FRAME_FLAG_EYE : 0); } diff --git a/src/block/EndRod.php b/src/block/EndRod.php index a943e07c1a..39c28a097f 100644 --- a/src/block/EndRod.php +++ b/src/block/EndRod.php @@ -36,10 +36,6 @@ use pocketmine\world\BlockTransaction; class EndRod extends Flowable{ use AnyFacingTrait; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); - } - protected function writeStateToMeta() : int{ $result = BlockDataSerializer::writeFacing($this->facing); if(Facing::axis($this->facing) !== Axis::Y){ diff --git a/src/block/EnderChest.php b/src/block/EnderChest.php index be96d4443f..f633a12ca2 100644 --- a/src/block/EnderChest.php +++ b/src/block/EnderChest.php @@ -28,7 +28,6 @@ use pocketmine\block\tile\EnderChest as TileEnderChest; use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait; use pocketmine\item\Item; -use pocketmine\item\ToolTier; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -38,10 +37,6 @@ class EnderChest extends Transparent{ use FacesOppositePlacingPlayerTrait; use NormalHorizontalFacingInMetadataTrait; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(22.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 3000.0)); - } - public function getLightLevel() : int{ return 7; } diff --git a/src/block/Farmland.php b/src/block/Farmland.php index 65a0f77b21..fd1aecf076 100644 --- a/src/block/Farmland.php +++ b/src/block/Farmland.php @@ -33,10 +33,6 @@ class Farmland extends Transparent{ /** @var int */ protected $wetness = 0; //"moisture" blockstate property in PC - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::SHOVEL)); - } - protected function writeStateToMeta() : int{ return $this->wetness; } diff --git a/src/block/FenceGate.php b/src/block/FenceGate.php index 2f97c41058..6e1b4defa2 100644 --- a/src/block/FenceGate.php +++ b/src/block/FenceGate.php @@ -41,10 +41,6 @@ class FenceGate extends Transparent{ /** @var bool */ protected $inWall = false; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::AXE)); - } - protected function writeStateToMeta() : int{ return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) | ($this->open ? BlockLegacyMetadata::FENCE_GATE_FLAG_OPEN : 0) | diff --git a/src/block/Fire.php b/src/block/Fire.php index 45f3f8f6ee..14fc8cd6f1 100644 --- a/src/block/Fire.php +++ b/src/block/Fire.php @@ -40,10 +40,6 @@ class Fire extends Flowable{ /** @var int */ protected $age = 0; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); - } - protected function writeStateToMeta() : int{ return $this->age; } diff --git a/src/block/Flower.php b/src/block/Flower.php index 5640085855..7ccef8f771 100644 --- a/src/block/Flower.php +++ b/src/block/Flower.php @@ -31,10 +31,6 @@ use pocketmine\world\BlockTransaction; class Flower extends Flowable{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); - } - public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if($down->getId() === BlockLegacyIds::GRASS or $down->getId() === BlockLegacyIds::DIRT or $down->getId() === BlockLegacyIds::FARMLAND){ diff --git a/src/block/FlowerPot.php b/src/block/FlowerPot.php index ce787ae021..b5f7eedfff 100644 --- a/src/block/FlowerPot.php +++ b/src/block/FlowerPot.php @@ -43,10 +43,6 @@ class FlowerPot extends Flowable{ /** @var Block|null */ protected $plant = null; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); - } - protected function writeStateToMeta() : int{ return $this->occupied ? BlockLegacyMetadata::FLOWER_POT_FLAG_OCCUPIED : 0; } diff --git a/src/block/FrostedIce.php b/src/block/FrostedIce.php index f98a12d633..0099b71cf2 100644 --- a/src/block/FrostedIce.php +++ b/src/block/FrostedIce.php @@ -31,10 +31,6 @@ class FrostedIce extends Ice{ /** @var int */ protected $age = 0; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.5, BlockToolType::PICKAXE)); - } - public function readStateFromData(int $id, int $stateMeta) : void{ $this->age = BlockDataSerializer::readBoundedInt("age", $stateMeta, 0, 3); } diff --git a/src/block/Furnace.php b/src/block/Furnace.php index 5977da582d..6a01b994c1 100644 --- a/src/block/Furnace.php +++ b/src/block/Furnace.php @@ -27,7 +27,6 @@ use pocketmine\block\tile\Furnace as TileFurnace; use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait; use pocketmine\item\Item; -use pocketmine\item\ToolTier; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -43,8 +42,8 @@ class Furnace extends Opaque{ /** @var bool */ protected $lit = false; //this is set based on the blockID - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); + public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + parent::__construct($idInfo, $name, $breakInfo); } public function getId() : int{ diff --git a/src/block/Glass.php b/src/block/Glass.php index 1eb1d35168..dc1e2f9b8a 100644 --- a/src/block/Glass.php +++ b/src/block/Glass.php @@ -27,10 +27,6 @@ use pocketmine\item\Item; class Glass extends Transparent{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.3)); - } - public function getDropsForCompatibleTool(Item $item) : array{ return []; } diff --git a/src/block/GlassPane.php b/src/block/GlassPane.php index a549ef4ccc..06342541d4 100644 --- a/src/block/GlassPane.php +++ b/src/block/GlassPane.php @@ -27,10 +27,6 @@ use pocketmine\item\Item; class GlassPane extends Thin{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.3)); - } - public function getDropsForCompatibleTool(Item $item) : array{ return []; } diff --git a/src/block/GlazedTerracotta.php b/src/block/GlazedTerracotta.php index 5e81b2cc86..6cd41c8f8d 100644 --- a/src/block/GlazedTerracotta.php +++ b/src/block/GlazedTerracotta.php @@ -25,13 +25,8 @@ namespace pocketmine\block; use pocketmine\block\utils\FacesOppositePlacingPlayerTrait; use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait; -use pocketmine\item\ToolTier; class GlazedTerracotta extends Opaque{ use FacesOppositePlacingPlayerTrait; use NormalHorizontalFacingInMetadataTrait; - - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.4, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); - } } diff --git a/src/block/GlowingObsidian.php b/src/block/GlowingObsidian.php index c3a5155956..ff29363f52 100644 --- a/src/block/GlowingObsidian.php +++ b/src/block/GlowingObsidian.php @@ -23,14 +23,8 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\ToolTier; - class GlowingObsidian extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(10.0, BlockToolType::PICKAXE, ToolTier::DIAMOND()->getHarvestLevel(), 50.0)); - } - public function getLightLevel() : int{ return 12; } diff --git a/src/block/Glowstone.php b/src/block/Glowstone.php index aa63125af7..38886405fe 100644 --- a/src/block/Glowstone.php +++ b/src/block/Glowstone.php @@ -29,10 +29,6 @@ use function mt_rand; class Glowstone extends Transparent{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.3, BlockToolType::PICKAXE)); - } - public function getLightLevel() : int{ return 15; } diff --git a/src/block/Grass.php b/src/block/Grass.php index becdf86de2..02c097c187 100644 --- a/src/block/Grass.php +++ b/src/block/Grass.php @@ -37,10 +37,6 @@ use function mt_rand; class Grass extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::SHOVEL)); - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ VanillaBlocks::DIRT()->asItem() diff --git a/src/block/GrassPath.php b/src/block/GrassPath.php index f94fcba542..b3b8f1f4c8 100644 --- a/src/block/GrassPath.php +++ b/src/block/GrassPath.php @@ -29,10 +29,6 @@ use pocketmine\math\Facing; class GrassPath extends Transparent{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::SHOVEL)); - } - /** * @return AxisAlignedBB[] */ diff --git a/src/block/Gravel.php b/src/block/Gravel.php index a3cf7b07ef..9cc7f3fea4 100644 --- a/src/block/Gravel.php +++ b/src/block/Gravel.php @@ -32,10 +32,6 @@ use function mt_rand; class Gravel extends Opaque implements Fallable{ use FallableTrait; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::SHOVEL)); - } - public function getDropsForCompatibleTool(Item $item) : array{ if(mt_rand(1, 10) === 1){ return [ diff --git a/src/block/HardenedClay.php b/src/block/HardenedClay.php index 1617a738c4..d1bcbd4725 100644 --- a/src/block/HardenedClay.php +++ b/src/block/HardenedClay.php @@ -23,11 +23,6 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\ToolTier; - class HardenedClay extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.25, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 21.0)); - } } diff --git a/src/block/HardenedGlass.php b/src/block/HardenedGlass.php index 39a506696e..f9bfdd0861 100644 --- a/src/block/HardenedGlass.php +++ b/src/block/HardenedGlass.php @@ -25,7 +25,4 @@ namespace pocketmine\block; class HardenedGlass extends Transparent{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(10.0)); - } } diff --git a/src/block/HardenedGlassPane.php b/src/block/HardenedGlassPane.php index 2d9173e60b..da6a60f534 100644 --- a/src/block/HardenedGlassPane.php +++ b/src/block/HardenedGlassPane.php @@ -25,7 +25,4 @@ namespace pocketmine\block; class HardenedGlassPane extends Thin{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(10.0)); - } } diff --git a/src/block/HayBale.php b/src/block/HayBale.php index 6d70a82309..abf25e8a12 100644 --- a/src/block/HayBale.php +++ b/src/block/HayBale.php @@ -28,10 +28,6 @@ use pocketmine\block\utils\PillarRotationInMetadataTrait; class HayBale extends Opaque{ use PillarRotationInMetadataTrait; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5)); - } - public function getFlameEncouragement() : int{ return 60; } diff --git a/src/block/Ice.php b/src/block/Ice.php index b22278fb06..3c39f97bdf 100644 --- a/src/block/Ice.php +++ b/src/block/Ice.php @@ -29,10 +29,6 @@ use pocketmine\player\Player; class Ice extends Transparent{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE)); - } - public function getLightFilter() : int{ return 2; } diff --git a/src/block/InfestedStone.php b/src/block/InfestedStone.php index 00188ff2fb..944d0e4565 100644 --- a/src/block/InfestedStone.php +++ b/src/block/InfestedStone.php @@ -29,8 +29,8 @@ final class InfestedStone extends Opaque{ private int $imitated; - public function __construct(BlockIdentifier $idInfo, string $name, Block $imitated, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.75)); + public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo, Block $imitated){ + parent::__construct($idInfo, $name, $breakInfo); $this->imitated = $imitated->getFullId(); } diff --git a/src/block/ItemFrame.php b/src/block/ItemFrame.php index 3b8a32eba3..6737519388 100644 --- a/src/block/ItemFrame.php +++ b/src/block/ItemFrame.php @@ -47,10 +47,6 @@ class ItemFrame extends Flowable{ /** @var float */ protected $itemDropChance = 1.0; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.25)); - } - protected function writeStateToMeta() : int{ return BlockDataSerializer::write5MinusHorizontalFacing($this->facing) | ($this->hasMap ? BlockLegacyMetadata::ITEM_FRAME_FLAG_HAS_MAP : 0); } diff --git a/src/block/Jukebox.php b/src/block/Jukebox.php index 608e9194c1..6d192bbe28 100644 --- a/src/block/Jukebox.php +++ b/src/block/Jukebox.php @@ -35,11 +35,6 @@ class Jukebox extends Opaque{ /** @var Record|null */ private $record = null; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - //TODO: in PC the hardness is 2.0, not 0.8, unsure if this is a MCPE bug or not - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.8, BlockToolType::AXE)); - } - public function getFuelTime() : int{ return 300; } diff --git a/src/block/Ladder.php b/src/block/Ladder.php index eb6f43d384..978d29d654 100644 --- a/src/block/Ladder.php +++ b/src/block/Ladder.php @@ -37,10 +37,6 @@ use pocketmine\world\BlockTransaction; class Ladder extends Transparent{ use NormalHorizontalFacingInMetadataTrait; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.4, BlockToolType::AXE)); - } - public function hasEntityCollision() : bool{ return true; } diff --git a/src/block/LapisOre.php b/src/block/LapisOre.php index fc4accccbd..7dd434c797 100644 --- a/src/block/LapisOre.php +++ b/src/block/LapisOre.php @@ -24,16 +24,11 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; use function mt_rand; class LapisOre extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel())); - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ VanillaItems::LAPIS_LAZULI()->setCount(mt_rand(4, 8)) diff --git a/src/block/Leaves.php b/src/block/Leaves.php index c9408b0c65..5578c6be65 100644 --- a/src/block/Leaves.php +++ b/src/block/Leaves.php @@ -45,8 +45,8 @@ class Leaves extends Transparent{ /** @var bool */ protected $checkDecay = false; - public function __construct(BlockIdentifier $idInfo, string $name, TreeType $treeType, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::SHEARS)); + public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo, TreeType $treeType){ + parent::__construct($idInfo, $name, $breakInfo); $this->treeType = $treeType; } diff --git a/src/block/Lever.php b/src/block/Lever.php index 4dd69b18ba..027ea6525f 100644 --- a/src/block/Lever.php +++ b/src/block/Lever.php @@ -45,10 +45,6 @@ class Lever extends Flowable{ /** @var bool */ protected $powered = false; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5)); - } - protected function writeStateToMeta() : int{ if($this->leverPos === self::BOTTOM){ $rotationMeta = Facing::axis($this->facing) === Axis::Z ? 7 : 0; diff --git a/src/block/Liquid.php b/src/block/Liquid.php index bbcebc2279..4c7f5230bb 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -62,8 +62,8 @@ abstract class Liquid extends Transparent{ /** @var bool */ protected $still = false; - public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::indestructible(500.0)); + public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + parent::__construct($idInfo, $name, $breakInfo); } public function getId() : int{ diff --git a/src/block/Magma.php b/src/block/Magma.php index 2993e1e6b9..e698a6431a 100644 --- a/src/block/Magma.php +++ b/src/block/Magma.php @@ -27,14 +27,9 @@ use pocketmine\entity\Entity; use pocketmine\entity\Living; use pocketmine\event\entity\EntityDamageByBlockEvent; use pocketmine\event\entity\EntityDamageEvent; -use pocketmine\item\ToolTier; class Magma extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); - } - public function getLightLevel() : int{ return 3; } diff --git a/src/block/Melon.php b/src/block/Melon.php index 35502475e7..9536e5c853 100644 --- a/src/block/Melon.php +++ b/src/block/Melon.php @@ -29,10 +29,6 @@ use function mt_rand; class Melon extends Transparent{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0, BlockToolType::AXE)); - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ VanillaItems::MELON()->setCount(mt_rand(3, 7)) diff --git a/src/block/MonsterSpawner.php b/src/block/MonsterSpawner.php index d2599e134b..5ecc202b84 100644 --- a/src/block/MonsterSpawner.php +++ b/src/block/MonsterSpawner.php @@ -24,15 +24,10 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ToolTier; use function mt_rand; class MonsterSpawner extends Transparent{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); - } - public function getDropsForCompatibleTool(Item $item) : array{ return []; } diff --git a/src/block/Mycelium.php b/src/block/Mycelium.php index 8308875efb..940cb00dc2 100644 --- a/src/block/Mycelium.php +++ b/src/block/Mycelium.php @@ -30,10 +30,6 @@ use function mt_rand; class Mycelium extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::SHOVEL)); - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ VanillaBlocks::DIRT()->asItem() diff --git a/src/block/NetherPortal.php b/src/block/NetherPortal.php index 70260994ad..d5cc01cd8a 100644 --- a/src/block/NetherPortal.php +++ b/src/block/NetherPortal.php @@ -32,10 +32,6 @@ class NetherPortal extends Transparent{ /** @var int */ protected $axis = Axis::X; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::indestructible(0.0)); - } - public function readStateFromData(int $id, int $stateMeta) : void{ $this->axis = $stateMeta === BlockLegacyMetadata::NETHER_PORTAL_AXIS_Z ? Axis::Z : Axis::X; //mojang u dumb } diff --git a/src/block/NetherQuartzOre.php b/src/block/NetherQuartzOre.php index eab0898c48..0eb9365ad6 100644 --- a/src/block/NetherQuartzOre.php +++ b/src/block/NetherQuartzOre.php @@ -24,16 +24,11 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; use function mt_rand; class NetherQuartzOre extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ VanillaItems::NETHER_QUARTZ() diff --git a/src/block/NetherReactor.php b/src/block/NetherReactor.php index 632ac39333..f5c4272f61 100644 --- a/src/block/NetherReactor.php +++ b/src/block/NetherReactor.php @@ -25,7 +25,6 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; use pocketmine\item\Item; -use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; class NetherReactor extends Opaque{ @@ -33,10 +32,6 @@ class NetherReactor extends Opaque{ /** @var int */ protected $state = BlockLegacyMetadata::NETHER_REACTOR_INACTIVE; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); - } - protected function writeStateToMeta() : int{ return $this->state; } diff --git a/src/block/NetherWartPlant.php b/src/block/NetherWartPlant.php index 5f635f3ad8..028eba936f 100644 --- a/src/block/NetherWartPlant.php +++ b/src/block/NetherWartPlant.php @@ -37,10 +37,6 @@ class NetherWartPlant extends Flowable{ /** @var int */ protected $age = 0; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); - } - protected function writeStateToMeta() : int{ return $this->age; } diff --git a/src/block/Netherrack.php b/src/block/Netherrack.php index 895a078021..e9fb517282 100644 --- a/src/block/Netherrack.php +++ b/src/block/Netherrack.php @@ -23,14 +23,8 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\ToolTier; - class Netherrack extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.4, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); - } - public function burnsForever() : bool{ return true; } diff --git a/src/block/Note.php b/src/block/Note.php index 846a4dfe5b..ee78207e1c 100644 --- a/src/block/Note.php +++ b/src/block/Note.php @@ -33,10 +33,6 @@ class Note extends Opaque{ /** @var int */ private $pitch = self::MIN_PITCH; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.8, BlockToolType::AXE)); - } - public function readStateFromWorld() : void{ parent::readStateFromWorld(); $tile = $this->pos->getWorld()->getTile($this->pos); diff --git a/src/block/PackedIce.php b/src/block/PackedIce.php index 0d52af4aa7..e6d104f39f 100644 --- a/src/block/PackedIce.php +++ b/src/block/PackedIce.php @@ -27,10 +27,6 @@ use pocketmine\item\Item; class PackedIce extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE)); - } - public function getFrictionFactor() : float{ return 0.98; } diff --git a/src/block/Planks.php b/src/block/Planks.php index e7632f87ad..b34046cdb7 100644 --- a/src/block/Planks.php +++ b/src/block/Planks.php @@ -25,10 +25,6 @@ namespace pocketmine\block; class Planks extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::AXE, 0, 15.0)); - } - public function getFuelTime() : int{ return 300; } diff --git a/src/block/Podzol.php b/src/block/Podzol.php index 47e7c14325..8da535c545 100644 --- a/src/block/Podzol.php +++ b/src/block/Podzol.php @@ -25,7 +25,4 @@ namespace pocketmine\block; class Podzol extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::SHOVEL)); - } } diff --git a/src/block/RedMushroom.php b/src/block/RedMushroom.php index 72d3bb5ec7..3ca1a0bdb5 100644 --- a/src/block/RedMushroom.php +++ b/src/block/RedMushroom.php @@ -31,10 +31,6 @@ use pocketmine\world\BlockTransaction; class RedMushroom extends Flowable{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); - } - public function ticksRandomly() : bool{ return true; } diff --git a/src/block/Redstone.php b/src/block/Redstone.php index 7f06a706cb..c149650d77 100644 --- a/src/block/Redstone.php +++ b/src/block/Redstone.php @@ -23,11 +23,6 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\ToolTier; - class Redstone extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0)); - } } diff --git a/src/block/RedstoneComparator.php b/src/block/RedstoneComparator.php index 883a8152e2..96abcfde93 100644 --- a/src/block/RedstoneComparator.php +++ b/src/block/RedstoneComparator.php @@ -47,8 +47,8 @@ class RedstoneComparator extends Flowable{ /** @var bool */ protected $isSubtractMode = false; - public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); + public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + parent::__construct($idInfo, $name, $breakInfo); } public function getId() : int{ diff --git a/src/block/RedstoneLamp.php b/src/block/RedstoneLamp.php index 0d538167d7..f9694ee39a 100644 --- a/src/block/RedstoneLamp.php +++ b/src/block/RedstoneLamp.php @@ -31,8 +31,8 @@ class RedstoneLamp extends Opaque{ /** @var BlockIdentifierFlattened */ protected $idInfo; - public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.3)); + public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + parent::__construct($idInfo, $name, $breakInfo); } public function getId() : int{ diff --git a/src/block/RedstoneOre.php b/src/block/RedstoneOre.php index 9cfb07da57..ecbb215c82 100644 --- a/src/block/RedstoneOre.php +++ b/src/block/RedstoneOre.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -37,8 +36,8 @@ class RedstoneOre extends Opaque{ /** @var bool */ protected $lit = false; - public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel())); + public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + parent::__construct($idInfo, $name, $breakInfo); } public function getId() : int{ diff --git a/src/block/RedstoneRepeater.php b/src/block/RedstoneRepeater.php index 3740340603..238a5dc428 100644 --- a/src/block/RedstoneRepeater.php +++ b/src/block/RedstoneRepeater.php @@ -43,8 +43,8 @@ class RedstoneRepeater extends Flowable{ /** @var int */ protected $delay = 1; - public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); + public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + parent::__construct($idInfo, $name, $breakInfo); } public function getId() : int{ diff --git a/src/block/RedstoneTorch.php b/src/block/RedstoneTorch.php index c47765b153..1c5a9332c2 100644 --- a/src/block/RedstoneTorch.php +++ b/src/block/RedstoneTorch.php @@ -31,8 +31,8 @@ class RedstoneTorch extends Torch{ /** @var bool */ protected $lit = true; - public function __construct(BlockIdentifierFlattened $idInfo, string $name){ - parent::__construct($idInfo, $name); + public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + parent::__construct($idInfo, $name, $breakInfo); } public function getId() : int{ diff --git a/src/block/RedstoneWire.php b/src/block/RedstoneWire.php index ebc0c221e3..6c21404068 100644 --- a/src/block/RedstoneWire.php +++ b/src/block/RedstoneWire.php @@ -29,10 +29,6 @@ use pocketmine\block\utils\BlockDataSerializer; class RedstoneWire extends Flowable{ use AnalogRedstoneSignalEmitterTrait; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); - } - public function readStateFromData(int $id, int $stateMeta) : void{ $this->signalStrength = BlockDataSerializer::readBoundedInt("signalStrength", $stateMeta, 0, 15); } diff --git a/src/block/Reserved6.php b/src/block/Reserved6.php index 940fbf33e3..e2c6922e28 100644 --- a/src/block/Reserved6.php +++ b/src/block/Reserved6.php @@ -25,7 +25,4 @@ namespace pocketmine\block; class Reserved6 extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); - } } diff --git a/src/block/Sand.php b/src/block/Sand.php index 8516fdca9e..e64b73d22a 100644 --- a/src/block/Sand.php +++ b/src/block/Sand.php @@ -29,10 +29,6 @@ use pocketmine\block\utils\FallableTrait; class Sand extends Opaque implements Fallable{ use FallableTrait; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::SHOVEL)); - } - public function tickFalling() : ?Block{ return null; } diff --git a/src/block/Sapling.php b/src/block/Sapling.php index f9d004de38..64f1f5ad67 100644 --- a/src/block/Sapling.php +++ b/src/block/Sapling.php @@ -41,8 +41,8 @@ class Sapling extends Flowable{ /** @var TreeType */ private $treeType; - public function __construct(BlockIdentifier $idInfo, string $name, TreeType $treeType, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); + public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo, TreeType $treeType){ + parent::__construct($idInfo, $name, $breakInfo); $this->treeType = $treeType; } diff --git a/src/block/SeaLantern.php b/src/block/SeaLantern.php index d222cf0520..ffcf8e7aa4 100644 --- a/src/block/SeaLantern.php +++ b/src/block/SeaLantern.php @@ -28,10 +28,6 @@ use pocketmine\item\VanillaItems; class SeaLantern extends Transparent{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.3)); - } - public function getLightLevel() : int{ return 15; } diff --git a/src/block/SeaPickle.php b/src/block/SeaPickle.php index e96beb1313..22a2b4c217 100644 --- a/src/block/SeaPickle.php +++ b/src/block/SeaPickle.php @@ -35,10 +35,6 @@ class SeaPickle extends Transparent{ /** @var bool */ protected $underwater = false; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); - } - public function readStateFromData(int $id, int $stateMeta) : void{ $this->count = ($stateMeta & 0x03) + 1; $this->underwater = ($stateMeta & BlockLegacyMetadata::SEA_PICKLE_FLAG_NOT_UNDERWATER) === 0; diff --git a/src/block/Skull.php b/src/block/Skull.php index 6b5f13adb6..625b0aa0ef 100644 --- a/src/block/Skull.php +++ b/src/block/Skull.php @@ -50,9 +50,9 @@ class Skull extends Flowable{ /** @var int */ protected $rotation = 0; //TODO: split this into floor skull and wall skull handling - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ $this->skullType = SkullType::SKELETON(); //TODO: this should be a parameter - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(1.0)); + parent::__construct($idInfo, $name, $breakInfo); } protected function writeStateToMeta() : int{ diff --git a/src/block/Snow.php b/src/block/Snow.php index 19077382d6..eabe616ce9 100644 --- a/src/block/Snow.php +++ b/src/block/Snow.php @@ -24,15 +24,10 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\item\Item; -use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; class Snow extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::SHOVEL, ToolTier::WOOD()->getHarvestLevel())); - } - public function getDropsForCompatibleTool(Item $item) : array{ return [ VanillaItems::SNOWBALL()->setCount(4) diff --git a/src/block/SnowLayer.php b/src/block/SnowLayer.php index 1781497ae0..a3bb8f3956 100644 --- a/src/block/SnowLayer.php +++ b/src/block/SnowLayer.php @@ -27,7 +27,6 @@ use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\Fallable; use pocketmine\block\utils\FallableTrait; use pocketmine\item\Item; -use pocketmine\item\ToolTier; use pocketmine\item\VanillaItems; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -43,10 +42,6 @@ class SnowLayer extends Flowable implements Fallable{ /** @var int */ protected $layers = 1; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.1, BlockToolType::SHOVEL, ToolTier::WOOD()->getHarvestLevel())); - } - protected function writeStateToMeta() : int{ return $this->layers - 1; } diff --git a/src/block/SoulSand.php b/src/block/SoulSand.php index 465b79784e..46ec341c7f 100644 --- a/src/block/SoulSand.php +++ b/src/block/SoulSand.php @@ -28,10 +28,6 @@ use pocketmine\math\Facing; class SoulSand extends Opaque{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::SHOVEL)); - } - /** * @return AxisAlignedBB[] */ diff --git a/src/block/Sponge.php b/src/block/Sponge.php index 9d0325b9ae..ea53c0d0d4 100644 --- a/src/block/Sponge.php +++ b/src/block/Sponge.php @@ -28,10 +28,6 @@ class Sponge extends Opaque{ /** @var bool */ protected $wet = false; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6, BlockToolType::HOE)); - } - protected function writeStateToMeta() : int{ return $this->wet ? BlockLegacyMetadata::SPONGE_FLAG_WET : 0; } diff --git a/src/block/Stem.php b/src/block/Stem.php index 6ef52f1658..a70adfc452 100644 --- a/src/block/Stem.php +++ b/src/block/Stem.php @@ -31,10 +31,6 @@ use function mt_rand; abstract class Stem extends Crops{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); - } - abstract protected function getPlant() : Block; public function onRandomTick() : void{ diff --git a/src/block/StoneButton.php b/src/block/StoneButton.php index d92a3552ff..110438b58b 100644 --- a/src/block/StoneButton.php +++ b/src/block/StoneButton.php @@ -25,10 +25,6 @@ namespace pocketmine\block; class StoneButton extends Button{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE)); - } - protected function getActivationTime() : int{ return 20; } diff --git a/src/block/StonePressurePlate.php b/src/block/StonePressurePlate.php index 7635d98c6a..cd8bed86b3 100644 --- a/src/block/StonePressurePlate.php +++ b/src/block/StonePressurePlate.php @@ -23,11 +23,6 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\ToolTier; - class StonePressurePlate extends SimplePressurePlate{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); - } } diff --git a/src/block/Sugarcane.php b/src/block/Sugarcane.php index 43aa30538f..69e11b041a 100644 --- a/src/block/Sugarcane.php +++ b/src/block/Sugarcane.php @@ -37,10 +37,6 @@ class Sugarcane extends Flowable{ /** @var int */ protected $age = 0; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); - } - protected function writeStateToMeta() : int{ return $this->age; } diff --git a/src/block/TNT.php b/src/block/TNT.php index d4bce585b8..1dc00e1a9f 100644 --- a/src/block/TNT.php +++ b/src/block/TNT.php @@ -45,10 +45,6 @@ class TNT extends Opaque{ protected $unstable = false; //TODO: Usage unclear, seems to be a weird hack in vanilla protected bool $worksUnderwater = false; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); - } - public function readStateFromData(int $id, int $stateMeta) : void{ $this->unstable = ($stateMeta & BlockLegacyMetadata::TNT_FLAG_UNSTABLE) !== 0; $this->worksUnderwater = ($stateMeta & BlockLegacyMetadata::TNT_FLAG_UNDERWATER) !== 0; diff --git a/src/block/TallGrass.php b/src/block/TallGrass.php index 88b3ac6cee..fd23ec7204 100644 --- a/src/block/TallGrass.php +++ b/src/block/TallGrass.php @@ -33,10 +33,6 @@ use function mt_rand; class TallGrass extends Flowable{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant(BlockToolType::SHEARS, 1)); - } - public function canBeReplaced() : bool{ return true; } diff --git a/src/block/Torch.php b/src/block/Torch.php index 8c8a05d3e8..478e989fae 100644 --- a/src/block/Torch.php +++ b/src/block/Torch.php @@ -35,10 +35,6 @@ class Torch extends Flowable{ /** @var int */ protected $facing = Facing::UP; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); - } - protected function writeStateToMeta() : int{ return $this->facing === Facing::UP ? 5 : 6 - BlockDataSerializer::writeHorizontalFacing($this->facing); } diff --git a/src/block/Tripwire.php b/src/block/Tripwire.php index e1d8c431f1..bdb0ee8e94 100644 --- a/src/block/Tripwire.php +++ b/src/block/Tripwire.php @@ -34,10 +34,6 @@ class Tripwire extends Flowable{ /** @var bool */ protected $disarmed = false; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); - } - protected function writeStateToMeta() : int{ return ($this->triggered ? BlockLegacyMetadata::TRIPWIRE_FLAG_TRIGGERED : 0) | ($this->suspended ? BlockLegacyMetadata::TRIPWIRE_FLAG_SUSPENDED : 0) | diff --git a/src/block/TripwireHook.php b/src/block/TripwireHook.php index e7c61c5a0e..dbdfebe7b5 100644 --- a/src/block/TripwireHook.php +++ b/src/block/TripwireHook.php @@ -40,10 +40,6 @@ class TripwireHook extends Flowable{ /** @var bool */ protected $powered = false; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? BlockBreakInfo::instant()); - } - protected function writeStateToMeta() : int{ return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) | ($this->connected ? BlockLegacyMetadata::TRIPWIRE_HOOK_FLAG_CONNECTED : 0) | diff --git a/src/block/UnknownBlock.php b/src/block/UnknownBlock.php index ee2974b38b..b13ecb48bb 100644 --- a/src/block/UnknownBlock.php +++ b/src/block/UnknownBlock.php @@ -27,8 +27,8 @@ use pocketmine\item\Item; class UnknownBlock extends Transparent{ - public function __construct(BlockIdentifier $idInfo, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, "Unknown", $breakInfo ?? BlockBreakInfo::instant()); + public function __construct(BlockIdentifier $idInfo, BlockBreakInfo $breakInfo){ + parent::__construct($idInfo, "Unknown", $breakInfo); } public function canBePlaced() : bool{ diff --git a/src/block/Vine.php b/src/block/Vine.php index 6cbe53700d..c67353c5a3 100644 --- a/src/block/Vine.php +++ b/src/block/Vine.php @@ -38,10 +38,6 @@ class Vine extends Flowable{ /** @var int[] */ protected $faces = []; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.2, BlockToolType::AXE)); - } - protected function writeStateToMeta() : int{ return (isset($this->faces[Facing::SOUTH]) ? BlockLegacyMetadata::VINE_FLAG_SOUTH : 0) | diff --git a/src/block/Wall.php b/src/block/Wall.php index 462835e0b4..daa67813a8 100644 --- a/src/block/Wall.php +++ b/src/block/Wall.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\ToolTier; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -34,10 +33,6 @@ class Wall extends Transparent{ /** @var bool */ protected $up = false; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0)); - } - public function readStateFromWorld() : void{ parent::readStateFromWorld(); diff --git a/src/block/WaterLily.php b/src/block/WaterLily.php index e4648d3781..6b7f583e82 100644 --- a/src/block/WaterLily.php +++ b/src/block/WaterLily.php @@ -32,10 +32,6 @@ use pocketmine\world\BlockTransaction; class WaterLily extends Flowable{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.6)); - } - /** * @return AxisAlignedBB[] */ diff --git a/src/block/WeightedPressurePlateHeavy.php b/src/block/WeightedPressurePlateHeavy.php index 33b7fe08c2..acc8068d97 100644 --- a/src/block/WeightedPressurePlateHeavy.php +++ b/src/block/WeightedPressurePlateHeavy.php @@ -23,11 +23,6 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\ToolTier; - class WeightedPressurePlateHeavy extends WeightedPressurePlate{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); - } } diff --git a/src/block/WeightedPressurePlateLight.php b/src/block/WeightedPressurePlateLight.php index 15ea238bf8..877211f625 100644 --- a/src/block/WeightedPressurePlateLight.php +++ b/src/block/WeightedPressurePlateLight.php @@ -23,11 +23,6 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\item\ToolTier; - class WeightedPressurePlateLight extends WeightedPressurePlate{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())); - } } diff --git a/src/block/Wood.php b/src/block/Wood.php index 56cab4cadc..59aab1683a 100644 --- a/src/block/Wood.php +++ b/src/block/Wood.php @@ -35,9 +35,9 @@ class Wood extends Opaque{ private bool $stripped; - public function __construct(BlockIdentifier $idInfo, string $name, TreeType $treeType, bool $stripped, ?BlockBreakInfo $breakInfo = null){ + public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo, TreeType $treeType, bool $stripped){ $this->stripped = $stripped; //TODO: this should be dynamic, but right now legacy shit gets in the way - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::AXE)); + parent::__construct($idInfo, $name, $breakInfo); $this->treeType = $treeType; } diff --git a/src/block/WoodenButton.php b/src/block/WoodenButton.php index 9cfdb0dc71..44f4f867be 100644 --- a/src/block/WoodenButton.php +++ b/src/block/WoodenButton.php @@ -25,10 +25,6 @@ namespace pocketmine\block; class WoodenButton extends Button{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::AXE)); - } - protected function getActivationTime() : int{ return 30; } diff --git a/src/block/WoodenDoor.php b/src/block/WoodenDoor.php index 4edd42a41b..af6c7b25f2 100644 --- a/src/block/WoodenDoor.php +++ b/src/block/WoodenDoor.php @@ -25,7 +25,4 @@ namespace pocketmine\block; class WoodenDoor extends Door{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::AXE)); - } } diff --git a/src/block/WoodenFence.php b/src/block/WoodenFence.php index 070c36a1a8..b128eca0fe 100644 --- a/src/block/WoodenFence.php +++ b/src/block/WoodenFence.php @@ -25,10 +25,6 @@ namespace pocketmine\block; class WoodenFence extends Fence{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::AXE, 0, 15.0)); - } - public function getFuelTime() : int{ return 300; } diff --git a/src/block/WoodenPressurePlate.php b/src/block/WoodenPressurePlate.php index 4e624d2812..99e48c332d 100644 --- a/src/block/WoodenPressurePlate.php +++ b/src/block/WoodenPressurePlate.php @@ -25,10 +25,6 @@ namespace pocketmine\block; class WoodenPressurePlate extends SimplePressurePlate{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(0.5, BlockToolType::AXE)); - } - public function getFuelTime() : int{ return 300; } diff --git a/src/block/WoodenSlab.php b/src/block/WoodenSlab.php index 9c713c2ac2..91ec0f117f 100644 --- a/src/block/WoodenSlab.php +++ b/src/block/WoodenSlab.php @@ -25,10 +25,6 @@ namespace pocketmine\block; class WoodenSlab extends Slab{ - public function __construct(BlockIdentifierFlattened $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::AXE, 0, 15.0)); - } - public function getFuelTime() : int{ return 300; } diff --git a/src/block/WoodenStairs.php b/src/block/WoodenStairs.php index 2550d91a6d..4d90098696 100644 --- a/src/block/WoodenStairs.php +++ b/src/block/WoodenStairs.php @@ -25,10 +25,6 @@ namespace pocketmine\block; class WoodenStairs extends Stair{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(2.0, BlockToolType::AXE, 0, 15.0)); - } - public function getFlameEncouragement() : int{ return 5; } diff --git a/src/block/WoodenTrapdoor.php b/src/block/WoodenTrapdoor.php index 07a73872ca..7f07244520 100644 --- a/src/block/WoodenTrapdoor.php +++ b/src/block/WoodenTrapdoor.php @@ -25,10 +25,6 @@ namespace pocketmine\block; class WoodenTrapdoor extends Trapdoor{ - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ - parent::__construct($idInfo, $name, $breakInfo ?? new BlockBreakInfo(3.0, BlockToolType::AXE, 0, 15.0)); - } - public function getFuelTime() : int{ return 300; } diff --git a/src/block/Wool.php b/src/block/Wool.php index 14345c3454..8dd0f28a3d 100644 --- a/src/block/Wool.php +++ b/src/block/Wool.php @@ -25,24 +25,13 @@ namespace pocketmine\block; use pocketmine\block\utils\ColorInMetadataTrait; use pocketmine\block\utils\DyeColor; -use pocketmine\item\Item; class Wool extends Opaque{ use ColorInMetadataTrait; - public function __construct(BlockIdentifier $idInfo, string $name, ?BlockBreakInfo $breakInfo = null){ + public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ $this->color = DyeColor::WHITE(); - parent::__construct($idInfo, $name, $breakInfo ?? new class(0.8, BlockToolType::SHEARS) extends BlockBreakInfo{ - public function getBreakTime(Item $item) : float{ - $time = parent::getBreakTime($item); - if($item->getBlockToolType() === BlockToolType::SHEARS){ - $time *= 3; //shears break compatible blocks 15x faster, but wool 5x - } - - return $time; - } - } - ); + parent::__construct($idInfo, $name, $breakInfo); } public function getFlameEncouragement() : int{ From 7968a72f0e346411f9a91a2dffbc0dc5994bba8a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 20 May 2021 23:18:33 +0100 Subject: [PATCH 2497/3224] Eliminate some duplicated breakinfos --- src/block/BlockFactory.php | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 8dd64ab420..ce077abd23 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -223,11 +223,14 @@ class BlockFactory{ $this->register(new Opaque(new BID(Ids::INFO_UPDATE, 0), "update!", $updateBlockBreakInfo)); $this->register(new Opaque(new BID(Ids::INFO_UPDATE2, 0), "ate!upd", $updateBlockBreakInfo)); $this->register(new Transparent(new BID(Ids::INVISIBLEBEDROCK, 0), "Invisible Bedrock", BlockBreakInfo::indestructible())); - $this->register(new Opaque(new BID(Ids::IRON_BLOCK, 0), "Iron Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel(), 30.0))); - $this->register(new Thin(new BID(Ids::IRON_BARS, 0), "Iron Bars", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0))); - $this->register(new Door(new BID(Ids::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0))); + + $ironBreakInfo = new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel(), 30.0); + $this->register(new Opaque(new BID(Ids::IRON_BLOCK, 0), "Iron Block", $ironBreakInfo)); + $this->register(new Thin(new BID(Ids::IRON_BARS, 0), "Iron Bars", $ironBreakInfo)); + $ironDoorBreakInfo = new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0); + $this->register(new Door(new BID(Ids::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door", $ironDoorBreakInfo)); + $this->register(new Trapdoor(new BID(Ids::IRON_TRAPDOOR, 0), "Iron Trapdoor", $ironDoorBreakInfo)); $this->register(new Opaque(new BID(Ids::IRON_ORE, 0), "Iron Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); - $this->register(new Trapdoor(new BID(Ids::IRON_TRAPDOOR, 0), "Iron Trapdoor", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0))); $this->register(new ItemFrame(new BID(Ids::FRAME_BLOCK, 0, ItemIds::FRAME, TileItemFrame::class), "Item Frame", new BlockBreakInfo(0.25))); $this->register(new Jukebox(new BID(Ids::JUKEBOX, 0, ItemIds::JUKEBOX, TileJukebox::class), "Jukebox", new BlockBreakInfo(0.8, BlockToolType::AXE))); //TODO: in PC the hardness is 2.0, not 0.8, unsure if this is a MCPE bug or not $this->register(new Ladder(new BID(Ids::LADDER, 0), "Ladder", new BlockBreakInfo(0.4, BlockToolType::AXE))); @@ -412,25 +415,20 @@ class BlockFactory{ $this->register(new WeightedPressurePlateLight(new BID(Ids::LIGHT_WEIGHTED_PRESSURE_PLATE, 0), "Weighted Pressure Plate Light", $weightedPressurePlateBreakInfo)); $this->register(new Wheat(new BID(Ids::WHEAT_BLOCK, 0), "Wheat Block", BlockBreakInfo::instant())); - $fenceGateBreakInfo = new BlockBreakInfo(2.0, BlockToolType::AXE); - $leavesBreakInfo = new BlockBreakInfo(0.2, BlockToolType::SHEARS); $planksBreakInfo = new BlockBreakInfo(2.0, BlockToolType::AXE, 0, 15.0); + $leavesBreakInfo = new BlockBreakInfo(0.2, BlockToolType::SHEARS); $signBreakInfo = new BlockBreakInfo(1.0, BlockToolType::AXE); $logBreakInfo = new BlockBreakInfo(2.0, BlockToolType::AXE); - $woodenDoorBreakInfo = new BlockBreakInfo(3.0, BlockToolType::AXE); + $woodenDoorBreakInfo = new BlockBreakInfo(3.0, BlockToolType::AXE, 0, 15.0); $woodenButtonBreakInfo = new BlockBreakInfo(0.5, BlockToolType::AXE); - $woodenFenceBreakInfo = new BlockBreakInfo(2.0, BlockToolType::AXE, 0, 15.0); $woodenPressurePlateBreakInfo = new BlockBreakInfo(0.5, BlockToolType::AXE); - $woodenSlabBreakInfo = new BlockBreakInfo(2.0, BlockToolType::AXE, 0, 15.0); - $woodenStairsBreakInfo = new BlockBreakInfo(2.0, BlockToolType::AXE, 0, 15.0); - $woodenTrapdoorBreakInfo = new BlockBreakInfo(3.0, BlockToolType::AXE, 0, 15.0); foreach(TreeType::getAll() as $treeType){ $magicNumber = $treeType->getMagicNumber(); $name = $treeType->getDisplayName(); $this->register(new Planks(new BID(Ids::PLANKS, $magicNumber), $name . " Planks", $planksBreakInfo)); $this->register(new Sapling(new BID(Ids::SAPLING, $magicNumber), $name . " Sapling", BlockBreakInfo::instant(), $treeType)); - $this->register(new WoodenFence(new BID(Ids::FENCE, $magicNumber), $name . " Fence", $woodenFenceBreakInfo)); - $this->register(new WoodenSlab(new BIDFlattened(Ids::WOODEN_SLAB, [Ids::DOUBLE_WOODEN_SLAB], $treeType->getMagicNumber()), $treeType->getDisplayName(), $woodenSlabBreakInfo)); + $this->register(new WoodenFence(new BID(Ids::FENCE, $magicNumber), $name . " Fence", $planksBreakInfo)); + $this->register(new WoodenSlab(new BIDFlattened(Ids::WOODEN_SLAB, [Ids::DOUBLE_WOODEN_SLAB], $treeType->getMagicNumber()), $treeType->getDisplayName(), $planksBreakInfo)); //TODO: find a better way to deal with this split $this->register(new Leaves(new BID($magicNumber >= 4 ? Ids::LEAVES2 : Ids::LEAVES, $magicNumber & 0x03), $name . " Leaves", $leavesBreakInfo, $treeType)); @@ -441,13 +439,13 @@ class BlockFactory{ $this->remap($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, ($magicNumber & 0x03) | 0b1100, $wood); $this->register(new Log(BlockLegacyIdHelper::getStrippedLogIdentifier($treeType), "Stripped " . $treeType->getDisplayName() . " Log", $logBreakInfo, $treeType, true)); - $this->register(new FenceGate(BlockLegacyIdHelper::getWoodenFenceIdentifier($treeType), $treeType->getDisplayName() . " Fence Gate", $fenceGateBreakInfo)); - $this->register(new WoodenStairs(BlockLegacyIdHelper::getWoodenStairsIdentifier($treeType), $treeType->getDisplayName() . " Stairs", $woodenStairsBreakInfo)); + $this->register(new FenceGate(BlockLegacyIdHelper::getWoodenFenceIdentifier($treeType), $treeType->getDisplayName() . " Fence Gate", $planksBreakInfo)); + $this->register(new WoodenStairs(BlockLegacyIdHelper::getWoodenStairsIdentifier($treeType), $treeType->getDisplayName() . " Stairs", $planksBreakInfo)); $this->register(new WoodenDoor(BlockLegacyIdHelper::getWoodenDoorIdentifier($treeType), $treeType->getDisplayName() . " Door", $woodenDoorBreakInfo)); $this->register(new WoodenButton(BlockLegacyIdHelper::getWoodenButtonIdentifier($treeType), $treeType->getDisplayName() . " Button", $woodenButtonBreakInfo)); $this->register(new WoodenPressurePlate(BlockLegacyIdHelper::getWoodenPressurePlateIdentifier($treeType), $treeType->getDisplayName() . " Pressure Plate", $woodenPressurePlateBreakInfo)); - $this->register(new WoodenTrapdoor(BlockLegacyIdHelper::getWoodenTrapdoorIdentifier($treeType), $treeType->getDisplayName() . " Trapdoor", $woodenTrapdoorBreakInfo)); + $this->register(new WoodenTrapdoor(BlockLegacyIdHelper::getWoodenTrapdoorIdentifier($treeType), $treeType->getDisplayName() . " Trapdoor", $woodenDoorBreakInfo)); $this->register(new FloorSign(BlockLegacyIdHelper::getWoodenFloorSignIdentifier($treeType), $treeType->getDisplayName() . " Sign", $signBreakInfo)); $this->register(new WallSign(BlockLegacyIdHelper::getWoodenWallSignIdentifier($treeType), $treeType->getDisplayName() . " Wall Sign", $signBreakInfo)); From 2ab751f985493fa05a5cdc07ad648dbaea1f36a9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 21 May 2021 13:09:38 +0100 Subject: [PATCH 2498/3224] World: fixed potential bug scheduling async light updates multiple times --- src/world/World.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index d7df6bf09a..3a5bb716cc 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1020,7 +1020,9 @@ class World implements ChunkManager{ } $lightPopulatedState = $adjacentChunk->isLightPopulated(); if($lightPopulatedState !== true){ - $this->orderLightPopulation($chunkX + $cx, $chunkZ + $cz); + if($lightPopulatedState === false){ + $this->orderLightPopulation($chunkX + $cx, $chunkZ + $cz); + } return false; } } From e7b21cf9dcb9a55717328d6f94a126f1d9545bc0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 21 May 2021 13:10:48 +0100 Subject: [PATCH 2499/3224] World: remove obsolete TODO comment [ci skip] --- src/world/World.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index 3a5bb716cc..fbb351a79b 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1033,7 +1033,6 @@ class World implements ChunkManager{ private function orderLightPopulation(int $chunkX, int $chunkZ) : void{ $chunkHash = World::chunkHash($chunkX, $chunkZ); - //TODO: this might need to be checked after adjacent chunks are loaded in future $lightPopulatedState = $this->chunks[$chunkHash]->isLightPopulated(); if($lightPopulatedState === false){ $this->chunks[$chunkHash]->setLightPopulated(null); From df260034cd370dd0b24319469932da4f21e5cd4a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 21 May 2021 21:08:21 +0100 Subject: [PATCH 2500/3224] BlockFactory: Fill default state for all variants covered by bitmask when mismatch occurs --- src/block/BlockFactory.php | 20 +++++++++++-------- .../block_factory_consistency_check.json | 2 +- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index ce077abd23..407d6eadbb 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -902,25 +902,29 @@ class BlockFactory{ $v = clone $block; try{ $v->readStateFromData($id, $m); - if($v->getMeta() !== $m){ - throw new InvalidBlockStateException("Corrupted meta"); //don't register anything that isn't the same when we read it back again + if($v->getFullId() !== $index){ + //if the fullID comes back different, this is a broken state that we can't rely on; map it to default + throw new InvalidBlockStateException("Corrupted state"); } - }catch(InvalidBlockStateException $e){ //invalid property combination + }catch(InvalidBlockStateException $e){ //invalid property combination, fill the default state + $this->fillStaticArrays($index, $block); continue; } $this->fillStaticArrays($index, $v); } - - if(!$this->isRegistered($id, $variant)){ - $this->fillStaticArrays(($id << 4) | $variant, $block); //register default state mapped to variant, for blocks which don't use 0 as valid state - } } } public function remap(int $id, int $meta, Block $block) : void{ + $index = ($id << 4) | $meta; if($this->isRegistered($id, $meta)){ - throw new \InvalidArgumentException("$id:$meta is already mapped"); + $existing = $this->fullList[$index]; + if($existing->getFullId() === $index){ + throw new \InvalidArgumentException("$id:$meta is already mapped"); + }else{ + //if it's not a match, this was already remapped for some reason; remapping overwrites are OK + } } $this->fillStaticArrays(($id << 4) | $meta, $block); } diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index d4a75f4d3a..ac9e27473a 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","992":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1040":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Mushroom Stem","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"All Sided Mushroom Stem","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2336":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3504":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6274":"Wall Coral Fan","6276":"Wall Coral Fan","6278":"Wall Coral Fan","6280":"Wall Coral Fan","6282":"Wall Coral Fan","6284":"Wall Coral Fan","6286":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","438":"Powered Rail","439":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","446":"Powered Rail","447":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","454":"Detector Rail","455":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","462":"Detector Rail","463":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","696":"Smooth Stone Slab","697":"Sandstone Slab","698":"Fake Wooden Slab","699":"Cobblestone Slab","700":"Brick Slab","701":"Stone Brick Slab","702":"Quartz Slab","703":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","806":"Torch","807":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","865":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","870":"Chest","871":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","977":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","982":"Furnace","983":"Furnace","992":"Furnace","993":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","998":"Furnace","999":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1036":"Oak Door","1037":"Oak Door","1038":"Oak Door","1039":"Oak Door","1040":"Ladder","1041":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1046":"Ladder","1047":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1066":"Rail","1067":"Rail","1068":"Rail","1069":"Rail","1070":"Rail","1071":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1089":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1094":"Oak Wall Sign","1095":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1148":"Iron Door","1149":"Iron Door","1150":"Iron Door","1151":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1206":"Redstone Torch","1207":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1222":"Redstone Torch","1223":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1238":"Stone Button","1239":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1246":"Stone Button","1247":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1443":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1479":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Mushroom Stem","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"All Sided Mushroom Stem","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2022":"Activator Rail","2023":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2030":"Activator Rail","2031":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2044":"Cocoa Block","2045":"Cocoa Block","2046":"Cocoa Block","2047":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2081":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2086":"Ender Chest","2087":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2242":"Flower Pot","2243":"Flower Pot","2244":"Flower Pot","2245":"Flower Pot","2246":"Flower Pot","2247":"Flower Pot","2248":"Flower Pot","2249":"Flower Pot","2250":"Flower Pot","2251":"Flower Pot","2252":"Flower Pot","2253":"Flower Pot","2254":"Flower Pot","2255":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2294":"Oak Button","2295":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2302":"Oak Button","2303":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2310":"Mob Head","2311":"Mob Head","2312":"Mob Head","2313":"Mob Head","2314":"Mob Head","2315":"Mob Head","2316":"Mob Head","2317":"Mob Head","2318":"Mob Head","2319":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2332":"Anvil","2333":"Anvil","2334":"Anvil","2335":"Anvil","2336":"Trapped Chest","2337":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2342":"Trapped Chest","2343":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2401":"Redstone Comparator","2402":"Redstone Comparator","2403":"Redstone Comparator","2404":"Redstone Comparator","2405":"Redstone Comparator","2406":"Redstone Comparator","2407":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2465":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2470":"Hopper","2471":"Hopper","2472":"Hopper","2473":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2478":"Hopper","2479":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2493":"Chiseled Quartz Block","2494":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2520":"Oak Slab","2521":"Spruce Slab","2522":"Birch Slab","2523":"Jungle Slab","2524":"Acacia Slab","2525":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2732":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2833":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2838":"Wall Banner","2839":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2904":"Red Sandstone Slab","2905":"Purpur Slab","2906":"Prismarine Slab","2907":"Dark Prismarine Slab","2908":"Prismarine Bricks Slab","2909":"Mossy Cobblestone Slab","2910":"Smooth Sandstone Slab","2911":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3100":"Spruce Door","3101":"Spruce Door","3102":"Spruce Door","3103":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3116":"Birch Door","3117":"Birch Door","3118":"Birch Door","3119":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3132":"Jungle Door","3133":"Jungle Door","3134":"Jungle Door","3135":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3148":"Acacia Door","3149":"Acacia Door","3150":"Acacia Door","3151":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3164":"Dark Oak Door","3165":"Dark Oak Door","3166":"Dark Oak Door","3167":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3230":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3238":"Red Torch","3239":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3246":"Green Torch","3247":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3270":"Blue Torch","3271":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3278":"Purple Torch","3279":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3334":"End Rod","3335":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3468":"Bone Block","3504":"Purple Glazed Terracotta","3505":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3510":"Purple Glazed Terracotta","3511":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3521":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3526":"White Glazed Terracotta","3527":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3537":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3542":"Orange Glazed Terracotta","3543":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3553":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3558":"Magenta Glazed Terracotta","3559":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3569":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3574":"Light Blue Glazed Terracotta","3575":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3585":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3590":"Yellow Glazed Terracotta","3591":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3601":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3606":"Lime Glazed Terracotta","3607":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3617":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3622":"Pink Glazed Terracotta","3623":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3633":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3638":"Gray Glazed Terracotta","3639":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3649":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3654":"Light Gray Glazed Terracotta","3655":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3665":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3670":"Cyan Glazed Terracotta","3671":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3697":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3702":"Blue Glazed Terracotta","3703":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3713":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3718":"Brown Glazed Terracotta","3719":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3729":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3734":"Green Glazed Terracotta","3735":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3745":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3750":"Red Glazed Terracotta","3751":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3761":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3766":"Black Glazed Terracotta","3767":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3830":"Underwater Torch","3831":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3955":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4163":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4179":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4195":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4211":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4227":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4243":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6181":"Coral","6182":"Coral","6183":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6197":"Coral Block","6198":"Coral Block","6199":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6205":"Coral Block","6206":"Coral Block","6207":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6213":"Coral Fan","6214":"Coral Fan","6215":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6221":"Coral Fan","6222":"Coral Fan","6223":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6229":"Coral Fan","6230":"Coral Fan","6231":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6237":"Coral Fan","6238":"Coral Fan","6239":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6273":"Wall Coral Fan","6274":"Wall Coral Fan","6275":"Wall Coral Fan","6276":"Wall Coral Fan","6277":"Wall Coral Fan","6278":"Wall Coral Fan","6279":"Wall Coral Fan","6280":"Wall Coral Fan","6281":"Wall Coral Fan","6282":"Wall Coral Fan","6283":"Wall Coral Fan","6284":"Wall Coral Fan","6285":"Wall Coral Fan","6286":"Wall Coral Fan","6287":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6326":"Acacia Button","6327":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6334":"Acacia Button","6335":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6342":"Birch Button","6343":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6350":"Birch Button","6351":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6358":"Dark Oak Button","6359":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6366":"Dark Oak Button","6367":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6374":"Jungle Button","6375":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6382":"Jungle Button","6383":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6390":"Spruce Button","6391":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6398":"Spruce Button","6399":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6694":"Bamboo","6695":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6702":"Bamboo","6703":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6760":"End Stone Brick Slab","6761":"Smooth Red Sandstone Slab","6762":"Polished Andesite Slab","6763":"Andesite Slab","6764":"Diorite Slab","6765":"Polished Diorite Slab","6766":"Granite Slab","6767":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6776":"Mossy Stone Brick Slab","6777":"Smooth Quartz Slab","6778":"Stone Slab","6779":"Cut Sandstone Slab","6780":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6993":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","6998":"Spruce Wall Sign","6999":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7073":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7078":"Birch Wall Sign","7079":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7105":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7110":"Jungle Wall Sign","7111":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7137":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7142":"Acacia Wall Sign","7143":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7169":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7174":"Dark Oak Wall Sign","7175":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7334":"Barrel","7335":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7342":"Barrel","7343":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From 24405b63c135a7dc22f41568f5f776f7cce22e66 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 21 May 2021 21:36:49 +0100 Subject: [PATCH 2501/3224] Coarse is now a state of Dirt, instead of a separate block --- src/block/BlockFactory.php | 5 +-- src/block/BlockLegacyMetadata.php | 3 +- src/block/CoarseDirt.php | 43 ------------------- src/block/Dirt.php | 28 +++++++++++- src/block/Grass.php | 2 +- src/block/VanillaBlocks.php | 2 - .../block_factory_consistency_check.json | 2 +- 7 files changed, 31 insertions(+), 54 deletions(-) delete mode 100644 src/block/CoarseDirt.php diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 407d6eadbb..775cc8f2c0 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -136,9 +136,6 @@ class BlockFactory{ $this->register(new Coal(new BID(Ids::COAL_BLOCK, 0), "Coal Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0))); $this->register(new CoalOre(new BID(Ids::COAL_ORE, 0), "Coal Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - $dirtBreakInfo = new BlockBreakInfo(0.5, BlockToolType::SHOVEL); - $this->register(new CoarseDirt(new BID(Ids::DIRT, Meta::DIRT_COARSE), "Coarse Dirt", $dirtBreakInfo)); - $cobblestoneBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); $this->register($cobblestone = new Opaque(new BID(Ids::COBBLESTONE, 0), "Cobblestone", $cobblestoneBreakInfo)); $infestedStoneBreakInfo = new BlockBreakInfo(0.75); @@ -157,7 +154,7 @@ class BlockFactory{ $this->register(new Opaque(new BID(Ids::DIAMOND_BLOCK, 0), "Diamond Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); $this->register(new DiamondOre(new BID(Ids::DIAMOND_ORE, 0), "Diamond Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); - $this->register(new Dirt(new BID(Ids::DIRT, Meta::DIRT_NORMAL), "Dirt", $dirtBreakInfo)); + $this->register(new Dirt(new BID(Ids::DIRT, 0), "Dirt", new BlockBreakInfo(0.5, BlockToolType::SHOVEL))); $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_SUNFLOWER), "Sunflower", BlockBreakInfo::instant())); $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LILAC), "Lilac", BlockBreakInfo::instant())); $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_ROSE_BUSH), "Rose Bush", BlockBreakInfo::instant())); diff --git a/src/block/BlockLegacyMetadata.php b/src/block/BlockLegacyMetadata.php index 06bbe96808..34b57944f9 100644 --- a/src/block/BlockLegacyMetadata.php +++ b/src/block/BlockLegacyMetadata.php @@ -86,8 +86,7 @@ final class BlockLegacyMetadata{ public const CORAL_VARIANT_FIRE = 3; public const CORAL_VARIANT_HORN = 4; - public const DIRT_NORMAL = 0; - public const DIRT_COARSE = 1; + public const DIRT_FLAG_COARSE = 0x1; public const DOOR_FLAG_TOP = 0x08; public const DOOR_BOTTOM_FLAG_OPEN = 0x04; diff --git a/src/block/CoarseDirt.php b/src/block/CoarseDirt.php deleted file mode 100644 index d6e6630a5d..0000000000 --- a/src/block/CoarseDirt.php +++ /dev/null @@ -1,43 +0,0 @@ -applyDamage(1); - $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::DIRT()); - return true; - } - - return false; - } -} diff --git a/src/block/Dirt.php b/src/block/Dirt.php index 3bc27aa151..b357c95bf2 100644 --- a/src/block/Dirt.php +++ b/src/block/Dirt.php @@ -31,10 +31,36 @@ use pocketmine\player\Player; class Dirt extends Opaque{ + protected bool $coarse = false; + + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->coarse = ($stateMeta & BlockLegacyMetadata::DIRT_FLAG_COARSE) !== 0; + } + + protected function writeStateToMeta() : int{ + return $this->coarse ? BlockLegacyMetadata::DIRT_FLAG_COARSE : 0; + } + + public function getStateBitmask() : int{ + return 0b1; + } + + public function getNonPersistentStateBitmask() : int{ + return 0; + } + + public function isCoarse() : bool{ return $this->coarse; } + + /** @return $this */ + public function setCoarse(bool $coarse) : self{ + $this->coarse = $coarse; + return $this; + } + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP and $item instanceof Hoe){ $item->applyDamage(1); - $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::FARMLAND()); + $this->pos->getWorld()->setBlock($this->pos, $this->coarse ? VanillaBlocks::DIRT() : VanillaBlocks::FARMLAND()); return true; } diff --git a/src/block/Grass.php b/src/block/Grass.php index 02c097c187..e95c967eff 100644 --- a/src/block/Grass.php +++ b/src/block/Grass.php @@ -70,7 +70,7 @@ class Grass extends Opaque{ $b = $this->pos->getWorld()->getBlockAt($x, $y, $z); if( !($b instanceof Dirt) or - $b instanceof CoarseDirt or + $b->isCoarse() or $this->pos->getWorld()->getFullLightAt($x, $y + 1, $z) < 4 or $this->pos->getWorld()->getBlockAt($x, $y + 1, $z)->getLightFilter() >= 2 ){ diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 798b1dd53b..c5ae9dacbc 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -109,7 +109,6 @@ use function assert; * @method static Clay CLAY() * @method static Coal COAL() * @method static CoalOre COAL_ORE() - * @method static CoarseDirt COARSE_DIRT() * @method static Opaque COBBLESTONE() * @method static Slab COBBLESTONE_SLAB() * @method static Stair COBBLESTONE_STAIRS() @@ -663,7 +662,6 @@ final class VanillaBlocks{ self::register("clay", $factory->get(82, 0)); self::register("coal", $factory->get(173, 0)); self::register("coal_ore", $factory->get(16, 0)); - self::register("coarse_dirt", $factory->get(3, 1)); self::register("cobblestone", $factory->get(4, 0)); self::register("cobblestone_slab", $factory->get(44, 3)); self::register("cobblestone_stairs", $factory->get(67, 0)); diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index ac9e27473a..b421a96aba 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Coarse Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","438":"Powered Rail","439":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","446":"Powered Rail","447":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","454":"Detector Rail","455":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","462":"Detector Rail","463":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","696":"Smooth Stone Slab","697":"Sandstone Slab","698":"Fake Wooden Slab","699":"Cobblestone Slab","700":"Brick Slab","701":"Stone Brick Slab","702":"Quartz Slab","703":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","806":"Torch","807":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","865":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","870":"Chest","871":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","977":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","982":"Furnace","983":"Furnace","992":"Furnace","993":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","998":"Furnace","999":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1036":"Oak Door","1037":"Oak Door","1038":"Oak Door","1039":"Oak Door","1040":"Ladder","1041":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1046":"Ladder","1047":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1066":"Rail","1067":"Rail","1068":"Rail","1069":"Rail","1070":"Rail","1071":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1089":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1094":"Oak Wall Sign","1095":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1148":"Iron Door","1149":"Iron Door","1150":"Iron Door","1151":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1206":"Redstone Torch","1207":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1222":"Redstone Torch","1223":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1238":"Stone Button","1239":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1246":"Stone Button","1247":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1443":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1479":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Mushroom Stem","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"All Sided Mushroom Stem","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2022":"Activator Rail","2023":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2030":"Activator Rail","2031":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2044":"Cocoa Block","2045":"Cocoa Block","2046":"Cocoa Block","2047":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2081":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2086":"Ender Chest","2087":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2242":"Flower Pot","2243":"Flower Pot","2244":"Flower Pot","2245":"Flower Pot","2246":"Flower Pot","2247":"Flower Pot","2248":"Flower Pot","2249":"Flower Pot","2250":"Flower Pot","2251":"Flower Pot","2252":"Flower Pot","2253":"Flower Pot","2254":"Flower Pot","2255":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2294":"Oak Button","2295":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2302":"Oak Button","2303":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2310":"Mob Head","2311":"Mob Head","2312":"Mob Head","2313":"Mob Head","2314":"Mob Head","2315":"Mob Head","2316":"Mob Head","2317":"Mob Head","2318":"Mob Head","2319":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2332":"Anvil","2333":"Anvil","2334":"Anvil","2335":"Anvil","2336":"Trapped Chest","2337":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2342":"Trapped Chest","2343":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2401":"Redstone Comparator","2402":"Redstone Comparator","2403":"Redstone Comparator","2404":"Redstone Comparator","2405":"Redstone Comparator","2406":"Redstone Comparator","2407":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2465":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2470":"Hopper","2471":"Hopper","2472":"Hopper","2473":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2478":"Hopper","2479":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2493":"Chiseled Quartz Block","2494":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2520":"Oak Slab","2521":"Spruce Slab","2522":"Birch Slab","2523":"Jungle Slab","2524":"Acacia Slab","2525":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2732":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2833":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2838":"Wall Banner","2839":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2904":"Red Sandstone Slab","2905":"Purpur Slab","2906":"Prismarine Slab","2907":"Dark Prismarine Slab","2908":"Prismarine Bricks Slab","2909":"Mossy Cobblestone Slab","2910":"Smooth Sandstone Slab","2911":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3100":"Spruce Door","3101":"Spruce Door","3102":"Spruce Door","3103":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3116":"Birch Door","3117":"Birch Door","3118":"Birch Door","3119":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3132":"Jungle Door","3133":"Jungle Door","3134":"Jungle Door","3135":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3148":"Acacia Door","3149":"Acacia Door","3150":"Acacia Door","3151":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3164":"Dark Oak Door","3165":"Dark Oak Door","3166":"Dark Oak Door","3167":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3230":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3238":"Red Torch","3239":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3246":"Green Torch","3247":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3270":"Blue Torch","3271":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3278":"Purple Torch","3279":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3334":"End Rod","3335":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3468":"Bone Block","3504":"Purple Glazed Terracotta","3505":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3510":"Purple Glazed Terracotta","3511":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3521":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3526":"White Glazed Terracotta","3527":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3537":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3542":"Orange Glazed Terracotta","3543":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3553":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3558":"Magenta Glazed Terracotta","3559":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3569":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3574":"Light Blue Glazed Terracotta","3575":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3585":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3590":"Yellow Glazed Terracotta","3591":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3601":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3606":"Lime Glazed Terracotta","3607":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3617":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3622":"Pink Glazed Terracotta","3623":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3633":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3638":"Gray Glazed Terracotta","3639":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3649":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3654":"Light Gray Glazed Terracotta","3655":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3665":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3670":"Cyan Glazed Terracotta","3671":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3697":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3702":"Blue Glazed Terracotta","3703":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3713":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3718":"Brown Glazed Terracotta","3719":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3729":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3734":"Green Glazed Terracotta","3735":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3745":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3750":"Red Glazed Terracotta","3751":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3761":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3766":"Black Glazed Terracotta","3767":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3830":"Underwater Torch","3831":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3955":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4163":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4179":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4195":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4211":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4227":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4243":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6181":"Coral","6182":"Coral","6183":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6197":"Coral Block","6198":"Coral Block","6199":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6205":"Coral Block","6206":"Coral Block","6207":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6213":"Coral Fan","6214":"Coral Fan","6215":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6221":"Coral Fan","6222":"Coral Fan","6223":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6229":"Coral Fan","6230":"Coral Fan","6231":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6237":"Coral Fan","6238":"Coral Fan","6239":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6273":"Wall Coral Fan","6274":"Wall Coral Fan","6275":"Wall Coral Fan","6276":"Wall Coral Fan","6277":"Wall Coral Fan","6278":"Wall Coral Fan","6279":"Wall Coral Fan","6280":"Wall Coral Fan","6281":"Wall Coral Fan","6282":"Wall Coral Fan","6283":"Wall Coral Fan","6284":"Wall Coral Fan","6285":"Wall Coral Fan","6286":"Wall Coral Fan","6287":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6326":"Acacia Button","6327":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6334":"Acacia Button","6335":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6342":"Birch Button","6343":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6350":"Birch Button","6351":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6358":"Dark Oak Button","6359":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6366":"Dark Oak Button","6367":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6374":"Jungle Button","6375":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6382":"Jungle Button","6383":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6390":"Spruce Button","6391":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6398":"Spruce Button","6399":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6694":"Bamboo","6695":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6702":"Bamboo","6703":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6760":"End Stone Brick Slab","6761":"Smooth Red Sandstone Slab","6762":"Polished Andesite Slab","6763":"Andesite Slab","6764":"Diorite Slab","6765":"Polished Diorite Slab","6766":"Granite Slab","6767":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6776":"Mossy Stone Brick Slab","6777":"Smooth Quartz Slab","6778":"Stone Slab","6779":"Cut Sandstone Slab","6780":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6993":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","6998":"Spruce Wall Sign","6999":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7073":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7078":"Birch Wall Sign","7079":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7105":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7110":"Jungle Wall Sign","7111":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7137":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7142":"Acacia Wall Sign","7143":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7169":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7174":"Dark Oak Wall Sign","7175":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7334":"Barrel","7335":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7342":"Barrel","7343":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","438":"Powered Rail","439":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","446":"Powered Rail","447":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","454":"Detector Rail","455":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","462":"Detector Rail","463":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","696":"Smooth Stone Slab","697":"Sandstone Slab","698":"Fake Wooden Slab","699":"Cobblestone Slab","700":"Brick Slab","701":"Stone Brick Slab","702":"Quartz Slab","703":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","806":"Torch","807":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","865":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","870":"Chest","871":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","977":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","982":"Furnace","983":"Furnace","992":"Furnace","993":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","998":"Furnace","999":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1036":"Oak Door","1037":"Oak Door","1038":"Oak Door","1039":"Oak Door","1040":"Ladder","1041":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1046":"Ladder","1047":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1066":"Rail","1067":"Rail","1068":"Rail","1069":"Rail","1070":"Rail","1071":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1089":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1094":"Oak Wall Sign","1095":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1148":"Iron Door","1149":"Iron Door","1150":"Iron Door","1151":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1206":"Redstone Torch","1207":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1222":"Redstone Torch","1223":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1238":"Stone Button","1239":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1246":"Stone Button","1247":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1443":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1479":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Mushroom Stem","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"All Sided Mushroom Stem","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2022":"Activator Rail","2023":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2030":"Activator Rail","2031":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2044":"Cocoa Block","2045":"Cocoa Block","2046":"Cocoa Block","2047":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2081":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2086":"Ender Chest","2087":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2242":"Flower Pot","2243":"Flower Pot","2244":"Flower Pot","2245":"Flower Pot","2246":"Flower Pot","2247":"Flower Pot","2248":"Flower Pot","2249":"Flower Pot","2250":"Flower Pot","2251":"Flower Pot","2252":"Flower Pot","2253":"Flower Pot","2254":"Flower Pot","2255":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2294":"Oak Button","2295":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2302":"Oak Button","2303":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2310":"Mob Head","2311":"Mob Head","2312":"Mob Head","2313":"Mob Head","2314":"Mob Head","2315":"Mob Head","2316":"Mob Head","2317":"Mob Head","2318":"Mob Head","2319":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2332":"Anvil","2333":"Anvil","2334":"Anvil","2335":"Anvil","2336":"Trapped Chest","2337":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2342":"Trapped Chest","2343":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2401":"Redstone Comparator","2402":"Redstone Comparator","2403":"Redstone Comparator","2404":"Redstone Comparator","2405":"Redstone Comparator","2406":"Redstone Comparator","2407":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2465":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2470":"Hopper","2471":"Hopper","2472":"Hopper","2473":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2478":"Hopper","2479":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2493":"Chiseled Quartz Block","2494":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2520":"Oak Slab","2521":"Spruce Slab","2522":"Birch Slab","2523":"Jungle Slab","2524":"Acacia Slab","2525":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2732":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2833":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2838":"Wall Banner","2839":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2904":"Red Sandstone Slab","2905":"Purpur Slab","2906":"Prismarine Slab","2907":"Dark Prismarine Slab","2908":"Prismarine Bricks Slab","2909":"Mossy Cobblestone Slab","2910":"Smooth Sandstone Slab","2911":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3100":"Spruce Door","3101":"Spruce Door","3102":"Spruce Door","3103":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3116":"Birch Door","3117":"Birch Door","3118":"Birch Door","3119":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3132":"Jungle Door","3133":"Jungle Door","3134":"Jungle Door","3135":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3148":"Acacia Door","3149":"Acacia Door","3150":"Acacia Door","3151":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3164":"Dark Oak Door","3165":"Dark Oak Door","3166":"Dark Oak Door","3167":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3230":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3238":"Red Torch","3239":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3246":"Green Torch","3247":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3270":"Blue Torch","3271":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3278":"Purple Torch","3279":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3334":"End Rod","3335":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3468":"Bone Block","3504":"Purple Glazed Terracotta","3505":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3510":"Purple Glazed Terracotta","3511":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3521":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3526":"White Glazed Terracotta","3527":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3537":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3542":"Orange Glazed Terracotta","3543":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3553":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3558":"Magenta Glazed Terracotta","3559":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3569":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3574":"Light Blue Glazed Terracotta","3575":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3585":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3590":"Yellow Glazed Terracotta","3591":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3601":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3606":"Lime Glazed Terracotta","3607":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3617":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3622":"Pink Glazed Terracotta","3623":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3633":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3638":"Gray Glazed Terracotta","3639":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3649":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3654":"Light Gray Glazed Terracotta","3655":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3665":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3670":"Cyan Glazed Terracotta","3671":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3697":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3702":"Blue Glazed Terracotta","3703":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3713":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3718":"Brown Glazed Terracotta","3719":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3729":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3734":"Green Glazed Terracotta","3735":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3745":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3750":"Red Glazed Terracotta","3751":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3761":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3766":"Black Glazed Terracotta","3767":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3830":"Underwater Torch","3831":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3955":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4163":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4179":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4195":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4211":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4227":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4243":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6181":"Coral","6182":"Coral","6183":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6197":"Coral Block","6198":"Coral Block","6199":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6205":"Coral Block","6206":"Coral Block","6207":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6213":"Coral Fan","6214":"Coral Fan","6215":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6221":"Coral Fan","6222":"Coral Fan","6223":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6229":"Coral Fan","6230":"Coral Fan","6231":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6237":"Coral Fan","6238":"Coral Fan","6239":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6273":"Wall Coral Fan","6274":"Wall Coral Fan","6275":"Wall Coral Fan","6276":"Wall Coral Fan","6277":"Wall Coral Fan","6278":"Wall Coral Fan","6279":"Wall Coral Fan","6280":"Wall Coral Fan","6281":"Wall Coral Fan","6282":"Wall Coral Fan","6283":"Wall Coral Fan","6284":"Wall Coral Fan","6285":"Wall Coral Fan","6286":"Wall Coral Fan","6287":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6326":"Acacia Button","6327":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6334":"Acacia Button","6335":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6342":"Birch Button","6343":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6350":"Birch Button","6351":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6358":"Dark Oak Button","6359":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6366":"Dark Oak Button","6367":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6374":"Jungle Button","6375":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6382":"Jungle Button","6383":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6390":"Spruce Button","6391":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6398":"Spruce Button","6399":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6694":"Bamboo","6695":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6702":"Bamboo","6703":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6760":"End Stone Brick Slab","6761":"Smooth Red Sandstone Slab","6762":"Polished Andesite Slab","6763":"Andesite Slab","6764":"Diorite Slab","6765":"Polished Diorite Slab","6766":"Granite Slab","6767":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6776":"Mossy Stone Brick Slab","6777":"Smooth Quartz Slab","6778":"Stone Slab","6779":"Cut Sandstone Slab","6780":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6993":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","6998":"Spruce Wall Sign","6999":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7073":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7078":"Birch Wall Sign","7079":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7105":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7110":"Jungle Wall Sign","7111":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7137":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7142":"Acacia Wall Sign","7143":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7169":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7174":"Dark Oak Wall Sign","7175":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7334":"Barrel","7335":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7342":"Barrel","7343":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file From ac04911e8881b0dcbafd1ff2a9a00e9a74bd5a05 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 21 May 2021 21:44:17 +0100 Subject: [PATCH 2502/3224] BlockFactory: fix potential crash --- src/block/BlockFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 775cc8f2c0..7613c03e90 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -917,7 +917,7 @@ class BlockFactory{ $index = ($id << 4) | $meta; if($this->isRegistered($id, $meta)){ $existing = $this->fullList[$index]; - if($existing->getFullId() === $index){ + if($existing !== null && $existing->getFullId() === $index){ throw new \InvalidArgumentException("$id:$meta is already mapped"); }else{ //if it's not a match, this was already remapped for some reason; remapping overwrites are OK From f655d262be55f705b0408edadcb8b7b32fbe10bf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 22 May 2021 12:43:07 +0100 Subject: [PATCH 2503/3224] Added stripped all-sided-log variants again, these should be dynamic; but right now it's not possible. --- src/block/BlockFactory.php | 1 + src/block/BlockLegacyMetadata.php | 2 ++ src/block/VanillaBlocks.php | 12 ++++++++++++ .../block/block_factory_consistency_check.json | 2 +- 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 7613c03e90..64c6c16b5e 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -434,6 +434,7 @@ class BlockFactory{ $wood = new Wood(new BID(Ids::WOOD, $magicNumber), $name . " Wood", $logBreakInfo, $treeType, false); $this->register($wood); $this->remap($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, ($magicNumber & 0x03) | 0b1100, $wood); + $this->register(new Wood(new BID(Ids::WOOD, $magicNumber | BlockLegacyMetadata::WOOD_FLAG_STRIPPED), "Stripped $name Wood", $logBreakInfo, $treeType, true)); $this->register(new Log(BlockLegacyIdHelper::getStrippedLogIdentifier($treeType), "Stripped " . $treeType->getDisplayName() . " Log", $logBreakInfo, $treeType, true)); $this->register(new FenceGate(BlockLegacyIdHelper::getWoodenFenceIdentifier($treeType), $treeType->getDisplayName() . " Fence Gate", $planksBreakInfo)); diff --git a/src/block/BlockLegacyMetadata.php b/src/block/BlockLegacyMetadata.php index 34b57944f9..2b4fb17d28 100644 --- a/src/block/BlockLegacyMetadata.php +++ b/src/block/BlockLegacyMetadata.php @@ -289,4 +289,6 @@ final class BlockLegacyMetadata{ public const WALL_PRISMARINE = 11; public const WALL_RED_SANDSTONE = 12; public const WALL_RED_NETHER_BRICK = 13; + + public const WOOD_FLAG_STRIPPED = 0x8; } diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index c5ae9dacbc..eb8cf97312 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -529,11 +529,17 @@ use function assert; * @method static Slab STONE_SLAB() * @method static Stair STONE_STAIRS() * @method static Log STRIPPED_ACACIA_LOG() + * @method static Wood STRIPPED_ACACIA_WOOD() * @method static Log STRIPPED_BIRCH_LOG() + * @method static Wood STRIPPED_BIRCH_WOOD() * @method static Log STRIPPED_DARK_OAK_LOG() + * @method static Wood STRIPPED_DARK_OAK_WOOD() * @method static Log STRIPPED_JUNGLE_LOG() + * @method static Wood STRIPPED_JUNGLE_WOOD() * @method static Log STRIPPED_OAK_LOG() + * @method static Wood STRIPPED_OAK_WOOD() * @method static Log STRIPPED_SPRUCE_LOG() + * @method static Wood STRIPPED_SPRUCE_WOOD() * @method static Sugarcane SUGARCANE() * @method static DoublePlant SUNFLOWER() * @method static TallGrass TALL_GRASS() @@ -1082,11 +1088,17 @@ final class VanillaBlocks{ self::register("stone_slab", $factory->get(421, 2)); self::register("stone_stairs", $factory->get(435, 0)); self::register("stripped_acacia_log", $factory->get(263, 0)); + self::register("stripped_acacia_wood", $factory->get(467, 12)); self::register("stripped_birch_log", $factory->get(261, 0)); + self::register("stripped_birch_wood", $factory->get(467, 10)); self::register("stripped_dark_oak_log", $factory->get(264, 0)); + self::register("stripped_dark_oak_wood", $factory->get(467, 13)); self::register("stripped_jungle_log", $factory->get(262, 0)); + self::register("stripped_jungle_wood", $factory->get(467, 11)); self::register("stripped_oak_log", $factory->get(265, 0)); + self::register("stripped_oak_wood", $factory->get(467, 8)); self::register("stripped_spruce_log", $factory->get(260, 0)); + self::register("stripped_spruce_wood", $factory->get(467, 9)); self::register("sugarcane", $factory->get(83, 0)); self::register("sunflower", $factory->get(175, 0)); self::register("tall_grass", $factory->get(31, 1)); diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index b421a96aba..70c3d82e31 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","438":"Powered Rail","439":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","446":"Powered Rail","447":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","454":"Detector Rail","455":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","462":"Detector Rail","463":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","696":"Smooth Stone Slab","697":"Sandstone Slab","698":"Fake Wooden Slab","699":"Cobblestone Slab","700":"Brick Slab","701":"Stone Brick Slab","702":"Quartz Slab","703":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","806":"Torch","807":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","865":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","870":"Chest","871":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","977":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","982":"Furnace","983":"Furnace","992":"Furnace","993":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","998":"Furnace","999":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1036":"Oak Door","1037":"Oak Door","1038":"Oak Door","1039":"Oak Door","1040":"Ladder","1041":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1046":"Ladder","1047":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1066":"Rail","1067":"Rail","1068":"Rail","1069":"Rail","1070":"Rail","1071":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1089":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1094":"Oak Wall Sign","1095":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1148":"Iron Door","1149":"Iron Door","1150":"Iron Door","1151":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1206":"Redstone Torch","1207":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1222":"Redstone Torch","1223":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1238":"Stone Button","1239":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1246":"Stone Button","1247":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1443":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1479":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Mushroom Stem","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"All Sided Mushroom Stem","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2022":"Activator Rail","2023":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2030":"Activator Rail","2031":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2044":"Cocoa Block","2045":"Cocoa Block","2046":"Cocoa Block","2047":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2081":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2086":"Ender Chest","2087":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2242":"Flower Pot","2243":"Flower Pot","2244":"Flower Pot","2245":"Flower Pot","2246":"Flower Pot","2247":"Flower Pot","2248":"Flower Pot","2249":"Flower Pot","2250":"Flower Pot","2251":"Flower Pot","2252":"Flower Pot","2253":"Flower Pot","2254":"Flower Pot","2255":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2294":"Oak Button","2295":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2302":"Oak Button","2303":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2310":"Mob Head","2311":"Mob Head","2312":"Mob Head","2313":"Mob Head","2314":"Mob Head","2315":"Mob Head","2316":"Mob Head","2317":"Mob Head","2318":"Mob Head","2319":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2332":"Anvil","2333":"Anvil","2334":"Anvil","2335":"Anvil","2336":"Trapped Chest","2337":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2342":"Trapped Chest","2343":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2401":"Redstone Comparator","2402":"Redstone Comparator","2403":"Redstone Comparator","2404":"Redstone Comparator","2405":"Redstone Comparator","2406":"Redstone Comparator","2407":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2465":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2470":"Hopper","2471":"Hopper","2472":"Hopper","2473":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2478":"Hopper","2479":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2493":"Chiseled Quartz Block","2494":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2520":"Oak Slab","2521":"Spruce Slab","2522":"Birch Slab","2523":"Jungle Slab","2524":"Acacia Slab","2525":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2732":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2833":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2838":"Wall Banner","2839":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2904":"Red Sandstone Slab","2905":"Purpur Slab","2906":"Prismarine Slab","2907":"Dark Prismarine Slab","2908":"Prismarine Bricks Slab","2909":"Mossy Cobblestone Slab","2910":"Smooth Sandstone Slab","2911":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3100":"Spruce Door","3101":"Spruce Door","3102":"Spruce Door","3103":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3116":"Birch Door","3117":"Birch Door","3118":"Birch Door","3119":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3132":"Jungle Door","3133":"Jungle Door","3134":"Jungle Door","3135":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3148":"Acacia Door","3149":"Acacia Door","3150":"Acacia Door","3151":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3164":"Dark Oak Door","3165":"Dark Oak Door","3166":"Dark Oak Door","3167":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3230":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3238":"Red Torch","3239":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3246":"Green Torch","3247":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3270":"Blue Torch","3271":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3278":"Purple Torch","3279":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3334":"End Rod","3335":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3468":"Bone Block","3504":"Purple Glazed Terracotta","3505":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3510":"Purple Glazed Terracotta","3511":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3521":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3526":"White Glazed Terracotta","3527":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3537":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3542":"Orange Glazed Terracotta","3543":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3553":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3558":"Magenta Glazed Terracotta","3559":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3569":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3574":"Light Blue Glazed Terracotta","3575":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3585":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3590":"Yellow Glazed Terracotta","3591":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3601":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3606":"Lime Glazed Terracotta","3607":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3617":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3622":"Pink Glazed Terracotta","3623":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3633":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3638":"Gray Glazed Terracotta","3639":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3649":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3654":"Light Gray Glazed Terracotta","3655":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3665":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3670":"Cyan Glazed Terracotta","3671":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3697":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3702":"Blue Glazed Terracotta","3703":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3713":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3718":"Brown Glazed Terracotta","3719":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3729":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3734":"Green Glazed Terracotta","3735":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3745":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3750":"Red Glazed Terracotta","3751":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3761":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3766":"Black Glazed Terracotta","3767":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3830":"Underwater Torch","3831":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3955":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4163":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4179":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4195":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4211":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4227":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4243":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6181":"Coral","6182":"Coral","6183":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6197":"Coral Block","6198":"Coral Block","6199":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6205":"Coral Block","6206":"Coral Block","6207":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6213":"Coral Fan","6214":"Coral Fan","6215":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6221":"Coral Fan","6222":"Coral Fan","6223":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6229":"Coral Fan","6230":"Coral Fan","6231":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6237":"Coral Fan","6238":"Coral Fan","6239":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6273":"Wall Coral Fan","6274":"Wall Coral Fan","6275":"Wall Coral Fan","6276":"Wall Coral Fan","6277":"Wall Coral Fan","6278":"Wall Coral Fan","6279":"Wall Coral Fan","6280":"Wall Coral Fan","6281":"Wall Coral Fan","6282":"Wall Coral Fan","6283":"Wall Coral Fan","6284":"Wall Coral Fan","6285":"Wall Coral Fan","6286":"Wall Coral Fan","6287":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6326":"Acacia Button","6327":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6334":"Acacia Button","6335":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6342":"Birch Button","6343":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6350":"Birch Button","6351":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6358":"Dark Oak Button","6359":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6366":"Dark Oak Button","6367":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6374":"Jungle Button","6375":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6382":"Jungle Button","6383":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6390":"Spruce Button","6391":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6398":"Spruce Button","6399":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6694":"Bamboo","6695":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6702":"Bamboo","6703":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6760":"End Stone Brick Slab","6761":"Smooth Red Sandstone Slab","6762":"Polished Andesite Slab","6763":"Andesite Slab","6764":"Diorite Slab","6765":"Polished Diorite Slab","6766":"Granite Slab","6767":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6776":"Mossy Stone Brick Slab","6777":"Smooth Quartz Slab","6778":"Stone Slab","6779":"Cut Sandstone Slab","6780":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6993":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","6998":"Spruce Wall Sign","6999":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7073":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7078":"Birch Wall Sign","7079":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7105":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7110":"Jungle Wall Sign","7111":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7137":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7142":"Acacia Wall Sign","7143":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7169":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7174":"Dark Oak Wall Sign","7175":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7334":"Barrel","7335":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7342":"Barrel","7343":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood"} \ No newline at end of file +{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","438":"Powered Rail","439":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","446":"Powered Rail","447":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","454":"Detector Rail","455":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","462":"Detector Rail","463":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","696":"Smooth Stone Slab","697":"Sandstone Slab","698":"Fake Wooden Slab","699":"Cobblestone Slab","700":"Brick Slab","701":"Stone Brick Slab","702":"Quartz Slab","703":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","806":"Torch","807":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","865":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","870":"Chest","871":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","977":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","982":"Furnace","983":"Furnace","992":"Furnace","993":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","998":"Furnace","999":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1036":"Oak Door","1037":"Oak Door","1038":"Oak Door","1039":"Oak Door","1040":"Ladder","1041":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1046":"Ladder","1047":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1066":"Rail","1067":"Rail","1068":"Rail","1069":"Rail","1070":"Rail","1071":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1089":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1094":"Oak Wall Sign","1095":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1148":"Iron Door","1149":"Iron Door","1150":"Iron Door","1151":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1206":"Redstone Torch","1207":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1222":"Redstone Torch","1223":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1238":"Stone Button","1239":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1246":"Stone Button","1247":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1443":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1479":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Mushroom Stem","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"All Sided Mushroom Stem","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2022":"Activator Rail","2023":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2030":"Activator Rail","2031":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2044":"Cocoa Block","2045":"Cocoa Block","2046":"Cocoa Block","2047":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2081":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2086":"Ender Chest","2087":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2242":"Flower Pot","2243":"Flower Pot","2244":"Flower Pot","2245":"Flower Pot","2246":"Flower Pot","2247":"Flower Pot","2248":"Flower Pot","2249":"Flower Pot","2250":"Flower Pot","2251":"Flower Pot","2252":"Flower Pot","2253":"Flower Pot","2254":"Flower Pot","2255":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2294":"Oak Button","2295":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2302":"Oak Button","2303":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2310":"Mob Head","2311":"Mob Head","2312":"Mob Head","2313":"Mob Head","2314":"Mob Head","2315":"Mob Head","2316":"Mob Head","2317":"Mob Head","2318":"Mob Head","2319":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2332":"Anvil","2333":"Anvil","2334":"Anvil","2335":"Anvil","2336":"Trapped Chest","2337":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2342":"Trapped Chest","2343":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2401":"Redstone Comparator","2402":"Redstone Comparator","2403":"Redstone Comparator","2404":"Redstone Comparator","2405":"Redstone Comparator","2406":"Redstone Comparator","2407":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2465":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2470":"Hopper","2471":"Hopper","2472":"Hopper","2473":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2478":"Hopper","2479":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2493":"Chiseled Quartz Block","2494":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2520":"Oak Slab","2521":"Spruce Slab","2522":"Birch Slab","2523":"Jungle Slab","2524":"Acacia Slab","2525":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2732":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2833":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2838":"Wall Banner","2839":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2904":"Red Sandstone Slab","2905":"Purpur Slab","2906":"Prismarine Slab","2907":"Dark Prismarine Slab","2908":"Prismarine Bricks Slab","2909":"Mossy Cobblestone Slab","2910":"Smooth Sandstone Slab","2911":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3100":"Spruce Door","3101":"Spruce Door","3102":"Spruce Door","3103":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3116":"Birch Door","3117":"Birch Door","3118":"Birch Door","3119":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3132":"Jungle Door","3133":"Jungle Door","3134":"Jungle Door","3135":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3148":"Acacia Door","3149":"Acacia Door","3150":"Acacia Door","3151":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3164":"Dark Oak Door","3165":"Dark Oak Door","3166":"Dark Oak Door","3167":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3230":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3238":"Red Torch","3239":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3246":"Green Torch","3247":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3270":"Blue Torch","3271":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3278":"Purple Torch","3279":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3334":"End Rod","3335":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3468":"Bone Block","3504":"Purple Glazed Terracotta","3505":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3510":"Purple Glazed Terracotta","3511":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3521":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3526":"White Glazed Terracotta","3527":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3537":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3542":"Orange Glazed Terracotta","3543":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3553":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3558":"Magenta Glazed Terracotta","3559":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3569":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3574":"Light Blue Glazed Terracotta","3575":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3585":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3590":"Yellow Glazed Terracotta","3591":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3601":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3606":"Lime Glazed Terracotta","3607":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3617":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3622":"Pink Glazed Terracotta","3623":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3633":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3638":"Gray Glazed Terracotta","3639":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3649":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3654":"Light Gray Glazed Terracotta","3655":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3665":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3670":"Cyan Glazed Terracotta","3671":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3697":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3702":"Blue Glazed Terracotta","3703":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3713":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3718":"Brown Glazed Terracotta","3719":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3729":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3734":"Green Glazed Terracotta","3735":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3745":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3750":"Red Glazed Terracotta","3751":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3761":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3766":"Black Glazed Terracotta","3767":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3830":"Underwater Torch","3831":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3955":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4163":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4179":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4195":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4211":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4227":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4243":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6181":"Coral","6182":"Coral","6183":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6197":"Coral Block","6198":"Coral Block","6199":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6205":"Coral Block","6206":"Coral Block","6207":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6213":"Coral Fan","6214":"Coral Fan","6215":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6221":"Coral Fan","6222":"Coral Fan","6223":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6229":"Coral Fan","6230":"Coral Fan","6231":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6237":"Coral Fan","6238":"Coral Fan","6239":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6273":"Wall Coral Fan","6274":"Wall Coral Fan","6275":"Wall Coral Fan","6276":"Wall Coral Fan","6277":"Wall Coral Fan","6278":"Wall Coral Fan","6279":"Wall Coral Fan","6280":"Wall Coral Fan","6281":"Wall Coral Fan","6282":"Wall Coral Fan","6283":"Wall Coral Fan","6284":"Wall Coral Fan","6285":"Wall Coral Fan","6286":"Wall Coral Fan","6287":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6326":"Acacia Button","6327":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6334":"Acacia Button","6335":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6342":"Birch Button","6343":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6350":"Birch Button","6351":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6358":"Dark Oak Button","6359":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6366":"Dark Oak Button","6367":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6374":"Jungle Button","6375":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6382":"Jungle Button","6383":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6390":"Spruce Button","6391":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6398":"Spruce Button","6399":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6694":"Bamboo","6695":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6702":"Bamboo","6703":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6760":"End Stone Brick Slab","6761":"Smooth Red Sandstone Slab","6762":"Polished Andesite Slab","6763":"Andesite Slab","6764":"Diorite Slab","6765":"Polished Diorite Slab","6766":"Granite Slab","6767":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6776":"Mossy Stone Brick Slab","6777":"Smooth Quartz Slab","6778":"Stone Slab","6779":"Cut Sandstone Slab","6780":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6993":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","6998":"Spruce Wall Sign","6999":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7073":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7078":"Birch Wall Sign","7079":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7105":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7110":"Jungle Wall Sign","7111":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7137":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7142":"Acacia Wall Sign","7143":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7169":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7174":"Dark Oak Wall Sign","7175":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7334":"Barrel","7335":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7342":"Barrel","7343":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood","7480":"Stripped Oak Wood","7481":"Stripped Spruce Wood","7482":"Stripped Birch Wood","7483":"Stripped Jungle Wood","7484":"Stripped Acacia Wood","7485":"Stripped Dark Oak Wood"} \ No newline at end of file From 285ad251684e1f1b316493947b1300e2a0e2e5bc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 22 May 2021 12:45:08 +0100 Subject: [PATCH 2504/3224] BlockFactory: use the vars we already have, instead of repeated method calls --- src/block/BlockFactory.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 64c6c16b5e..f220b0afcf 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -425,7 +425,7 @@ class BlockFactory{ $this->register(new Planks(new BID(Ids::PLANKS, $magicNumber), $name . " Planks", $planksBreakInfo)); $this->register(new Sapling(new BID(Ids::SAPLING, $magicNumber), $name . " Sapling", BlockBreakInfo::instant(), $treeType)); $this->register(new WoodenFence(new BID(Ids::FENCE, $magicNumber), $name . " Fence", $planksBreakInfo)); - $this->register(new WoodenSlab(new BIDFlattened(Ids::WOODEN_SLAB, [Ids::DOUBLE_WOODEN_SLAB], $treeType->getMagicNumber()), $treeType->getDisplayName(), $planksBreakInfo)); + $this->register(new WoodenSlab(new BIDFlattened(Ids::WOODEN_SLAB, [Ids::DOUBLE_WOODEN_SLAB], $magicNumber), $name, $planksBreakInfo)); //TODO: find a better way to deal with this split $this->register(new Leaves(new BID($magicNumber >= 4 ? Ids::LEAVES2 : Ids::LEAVES, $magicNumber & 0x03), $name . " Leaves", $leavesBreakInfo, $treeType)); @@ -436,17 +436,17 @@ class BlockFactory{ $this->remap($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, ($magicNumber & 0x03) | 0b1100, $wood); $this->register(new Wood(new BID(Ids::WOOD, $magicNumber | BlockLegacyMetadata::WOOD_FLAG_STRIPPED), "Stripped $name Wood", $logBreakInfo, $treeType, true)); - $this->register(new Log(BlockLegacyIdHelper::getStrippedLogIdentifier($treeType), "Stripped " . $treeType->getDisplayName() . " Log", $logBreakInfo, $treeType, true)); - $this->register(new FenceGate(BlockLegacyIdHelper::getWoodenFenceIdentifier($treeType), $treeType->getDisplayName() . " Fence Gate", $planksBreakInfo)); - $this->register(new WoodenStairs(BlockLegacyIdHelper::getWoodenStairsIdentifier($treeType), $treeType->getDisplayName() . " Stairs", $planksBreakInfo)); - $this->register(new WoodenDoor(BlockLegacyIdHelper::getWoodenDoorIdentifier($treeType), $treeType->getDisplayName() . " Door", $woodenDoorBreakInfo)); + $this->register(new Log(BlockLegacyIdHelper::getStrippedLogIdentifier($treeType), "Stripped " . $name . " Log", $logBreakInfo, $treeType, true)); + $this->register(new FenceGate(BlockLegacyIdHelper::getWoodenFenceIdentifier($treeType), $name . " Fence Gate", $planksBreakInfo)); + $this->register(new WoodenStairs(BlockLegacyIdHelper::getWoodenStairsIdentifier($treeType), $name . " Stairs", $planksBreakInfo)); + $this->register(new WoodenDoor(BlockLegacyIdHelper::getWoodenDoorIdentifier($treeType), $name . " Door", $woodenDoorBreakInfo)); - $this->register(new WoodenButton(BlockLegacyIdHelper::getWoodenButtonIdentifier($treeType), $treeType->getDisplayName() . " Button", $woodenButtonBreakInfo)); - $this->register(new WoodenPressurePlate(BlockLegacyIdHelper::getWoodenPressurePlateIdentifier($treeType), $treeType->getDisplayName() . " Pressure Plate", $woodenPressurePlateBreakInfo)); - $this->register(new WoodenTrapdoor(BlockLegacyIdHelper::getWoodenTrapdoorIdentifier($treeType), $treeType->getDisplayName() . " Trapdoor", $woodenDoorBreakInfo)); + $this->register(new WoodenButton(BlockLegacyIdHelper::getWoodenButtonIdentifier($treeType), $name . " Button", $woodenButtonBreakInfo)); + $this->register(new WoodenPressurePlate(BlockLegacyIdHelper::getWoodenPressurePlateIdentifier($treeType), $name . " Pressure Plate", $woodenPressurePlateBreakInfo)); + $this->register(new WoodenTrapdoor(BlockLegacyIdHelper::getWoodenTrapdoorIdentifier($treeType), $name . " Trapdoor", $woodenDoorBreakInfo)); - $this->register(new FloorSign(BlockLegacyIdHelper::getWoodenFloorSignIdentifier($treeType), $treeType->getDisplayName() . " Sign", $signBreakInfo)); - $this->register(new WallSign(BlockLegacyIdHelper::getWoodenWallSignIdentifier($treeType), $treeType->getDisplayName() . " Wall Sign", $signBreakInfo)); + $this->register(new FloorSign(BlockLegacyIdHelper::getWoodenFloorSignIdentifier($treeType), $name . " Sign", $signBreakInfo)); + $this->register(new WallSign(BlockLegacyIdHelper::getWoodenWallSignIdentifier($treeType), $name . " Wall Sign", $signBreakInfo)); } static $sandstoneTypes = [ From 73c229a236620a8ee115893e8f6c60cc69da4e50 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 22 May 2021 23:40:54 +0100 Subject: [PATCH 2505/3224] Block: fixed LSP violations in blocks using BlockIdentifierFlattened a property's type can't be changed by a subclass --- src/block/DaylightSensor.php | 7 ++++--- src/block/FloorCoralFan.php | 7 ++++--- src/block/Furnace.php | 7 ++++--- src/block/Liquid.php | 7 ++++--- src/block/RedstoneComparator.php | 7 ++++--- src/block/RedstoneLamp.php | 7 ++++--- src/block/RedstoneOre.php | 7 ++++--- src/block/RedstoneRepeater.php | 7 ++++--- src/block/RedstoneTorch.php | 7 ++++--- src/block/Slab.php | 7 ++++--- src/block/WallCoralFan.php | 15 ++++++++------- 11 files changed, 48 insertions(+), 37 deletions(-) diff --git a/src/block/DaylightSensor.php b/src/block/DaylightSensor.php index 68d5f6cabc..26dd582939 100644 --- a/src/block/DaylightSensor.php +++ b/src/block/DaylightSensor.php @@ -39,17 +39,18 @@ class DaylightSensor extends Transparent{ use AnalogRedstoneSignalEmitterTrait; /** @var BlockIdentifierFlattened */ - protected $idInfo; + protected $idInfoFlattened; /** @var bool */ protected $inverted = false; public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + $this->idInfoFlattened = $idInfo; parent::__construct($idInfo, $name, $breakInfo); } public function getId() : int{ - return $this->inverted ? $this->idInfo->getSecondId() : parent::getId(); + return $this->inverted ? $this->idInfoFlattened->getSecondId() : parent::getId(); } protected function writeStateToMeta() : int{ @@ -58,7 +59,7 @@ class DaylightSensor extends Transparent{ public function readStateFromData(int $id, int $stateMeta) : void{ $this->signalStrength = BlockDataSerializer::readBoundedInt("signalStrength", $stateMeta, 0, 15); - $this->inverted = $id === $this->idInfo->getSecondId(); + $this->inverted = $id === $this->idInfoFlattened->getSecondId(); } public function getStateBitmask() : int{ diff --git a/src/block/FloorCoralFan.php b/src/block/FloorCoralFan.php index 21ce87910b..1b69f0b6f2 100644 --- a/src/block/FloorCoralFan.php +++ b/src/block/FloorCoralFan.php @@ -37,16 +37,17 @@ use function rad2deg; final class FloorCoralFan extends BaseCoral{ /** @var BlockIdentifierFlattened */ - protected $idInfo; + protected $idInfoFlattened; private int $axis = Axis::X; public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + $this->idInfoFlattened = $idInfo; parent::__construct($idInfo, $name, $breakInfo); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->dead = $id === $this->idInfo->getSecondId(); + $this->dead = $id === $this->idInfoFlattened->getSecondId(); $this->axis = ($stateMeta >> 3) === BlockLegacyMetadata::CORAL_FAN_EAST_WEST ? Axis::X : Axis::Z; $coralType = CoralTypeIdMap::getInstance()->fromId($stateMeta & BlockLegacyMetadata::CORAL_FAN_TYPE_MASK); if($coralType === null){ @@ -56,7 +57,7 @@ final class FloorCoralFan extends BaseCoral{ } public function getId() : int{ - return $this->dead ? $this->idInfo->getSecondId() : parent::getId(); + return $this->dead ? $this->idInfoFlattened->getSecondId() : parent::getId(); } public function asItem() : Item{ diff --git a/src/block/Furnace.php b/src/block/Furnace.php index 6a01b994c1..6a78202827 100644 --- a/src/block/Furnace.php +++ b/src/block/Furnace.php @@ -37,22 +37,23 @@ class Furnace extends Opaque{ } /** @var BlockIdentifierFlattened */ - protected $idInfo; + protected $idInfoFlattened; /** @var bool */ protected $lit = false; //this is set based on the blockID public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + $this->idInfoFlattened = $idInfo; parent::__construct($idInfo, $name, $breakInfo); } public function getId() : int{ - return $this->lit ? $this->idInfo->getSecondId() : parent::getId(); + return $this->lit ? $this->idInfoFlattened->getSecondId() : parent::getId(); } public function readStateFromData(int $id, int $stateMeta) : void{ $this->readFacingStateFromData($id, $stateMeta); - $this->lit = $id === $this->idInfo->getSecondId(); + $this->lit = $id === $this->idInfoFlattened->getSecondId(); } public function getLightLevel() : int{ diff --git a/src/block/Liquid.php b/src/block/Liquid.php index 4c7f5230bb..77775a5fbd 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -40,7 +40,7 @@ use function min; abstract class Liquid extends Transparent{ /** @var BlockIdentifierFlattened */ - protected $idInfo; + protected $idInfoFlattened; /** @var int */ public $adjacentSources = 0; @@ -63,11 +63,12 @@ abstract class Liquid extends Transparent{ protected $still = false; public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + $this->idInfoFlattened = $idInfo; parent::__construct($idInfo, $name, $breakInfo); } public function getId() : int{ - return $this->still ? $this->idInfo->getSecondId() : parent::getId(); + return $this->still ? $this->idInfoFlattened->getSecondId() : parent::getId(); } protected function writeStateToMeta() : int{ @@ -77,7 +78,7 @@ abstract class Liquid extends Transparent{ public function readStateFromData(int $id, int $stateMeta) : void{ $this->decay = BlockDataSerializer::readBoundedInt("decay", $stateMeta & 0x07, 0, 7); $this->falling = ($stateMeta & BlockLegacyMetadata::LIQUID_FLAG_FALLING) !== 0; - $this->still = $id === $this->idInfo->getSecondId(); + $this->still = $id === $this->idInfoFlattened->getSecondId(); } public function getStateBitmask() : int{ diff --git a/src/block/RedstoneComparator.php b/src/block/RedstoneComparator.php index 96abcfde93..4ba4d938e2 100644 --- a/src/block/RedstoneComparator.php +++ b/src/block/RedstoneComparator.php @@ -42,23 +42,24 @@ class RedstoneComparator extends Flowable{ use PoweredByRedstoneTrait; /** @var BlockIdentifierFlattened */ - protected $idInfo; + protected $idInfoFlattened; /** @var bool */ protected $isSubtractMode = false; public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + $this->idInfoFlattened = $idInfo; parent::__construct($idInfo, $name, $breakInfo); } public function getId() : int{ - return $this->powered ? $this->idInfo->getSecondId() : parent::getId(); + return $this->powered ? $this->idInfoFlattened->getSecondId() : parent::getId(); } public function readStateFromData(int $id, int $stateMeta) : void{ $this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03); $this->isSubtractMode = ($stateMeta & BlockLegacyMetadata::REDSTONE_COMPARATOR_FLAG_SUBTRACT) !== 0; - $this->powered = ($id === $this->idInfo->getSecondId() or ($stateMeta & BlockLegacyMetadata::REDSTONE_COMPARATOR_FLAG_POWERED) !== 0); + $this->powered = ($id === $this->idInfoFlattened->getSecondId() or ($stateMeta & BlockLegacyMetadata::REDSTONE_COMPARATOR_FLAG_POWERED) !== 0); } public function writeStateToMeta() : int{ diff --git a/src/block/RedstoneLamp.php b/src/block/RedstoneLamp.php index f9694ee39a..7398c51dbd 100644 --- a/src/block/RedstoneLamp.php +++ b/src/block/RedstoneLamp.php @@ -29,18 +29,19 @@ class RedstoneLamp extends Opaque{ use PoweredByRedstoneTrait; /** @var BlockIdentifierFlattened */ - protected $idInfo; + protected $idInfoFlattened; public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + $this->idInfoFlattened = $idInfo; parent::__construct($idInfo, $name, $breakInfo); } public function getId() : int{ - return $this->powered ? $this->idInfo->getSecondId() : parent::getId(); + return $this->powered ? $this->idInfoFlattened->getSecondId() : parent::getId(); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->powered = $id === $this->idInfo->getSecondId(); + $this->powered = $id === $this->idInfoFlattened->getSecondId(); } public function getLightLevel() : int{ diff --git a/src/block/RedstoneOre.php b/src/block/RedstoneOre.php index ecbb215c82..9d32c4c6cb 100644 --- a/src/block/RedstoneOre.php +++ b/src/block/RedstoneOre.php @@ -31,21 +31,22 @@ use function mt_rand; class RedstoneOre extends Opaque{ /** @var BlockIdentifierFlattened */ - protected $idInfo; + protected $idInfoFlattened; /** @var bool */ protected $lit = false; public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + $this->idInfoFlattened = $idInfo; parent::__construct($idInfo, $name, $breakInfo); } public function getId() : int{ - return $this->lit ? $this->idInfo->getSecondId() : parent::getId(); + return $this->lit ? $this->idInfoFlattened->getSecondId() : parent::getId(); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->lit = $id === $this->idInfo->getSecondId(); + $this->lit = $id === $this->idInfoFlattened->getSecondId(); } public function isLit() : bool{ diff --git a/src/block/RedstoneRepeater.php b/src/block/RedstoneRepeater.php index 238a5dc428..7bd17e8577 100644 --- a/src/block/RedstoneRepeater.php +++ b/src/block/RedstoneRepeater.php @@ -38,23 +38,24 @@ class RedstoneRepeater extends Flowable{ use PoweredByRedstoneTrait; /** @var BlockIdentifierFlattened */ - protected $idInfo; + protected $idInfoFlattened; /** @var int */ protected $delay = 1; public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + $this->idInfoFlattened = $idInfo; parent::__construct($idInfo, $name, $breakInfo); } public function getId() : int{ - return $this->powered ? $this->idInfo->getSecondId() : parent::getId(); + return $this->powered ? $this->idInfoFlattened->getSecondId() : parent::getId(); } public function readStateFromData(int $id, int $stateMeta) : void{ $this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03); $this->delay = BlockDataSerializer::readBoundedInt("delay", ($stateMeta >> 2) + 1, 1, 4); - $this->powered = $id === $this->idInfo->getSecondId(); + $this->powered = $id === $this->idInfoFlattened->getSecondId(); } public function writeStateToMeta() : int{ diff --git a/src/block/RedstoneTorch.php b/src/block/RedstoneTorch.php index 1c5a9332c2..62badbc1aa 100644 --- a/src/block/RedstoneTorch.php +++ b/src/block/RedstoneTorch.php @@ -26,22 +26,23 @@ namespace pocketmine\block; class RedstoneTorch extends Torch{ /** @var BlockIdentifierFlattened */ - protected $idInfo; + protected $idInfoFlattened; /** @var bool */ protected $lit = true; public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + $this->idInfoFlattened = $idInfo; parent::__construct($idInfo, $name, $breakInfo); } public function getId() : int{ - return $this->lit ? parent::getId() : $this->idInfo->getSecondId(); + return $this->lit ? parent::getId() : $this->idInfoFlattened->getSecondId(); } public function readStateFromData(int $id, int $stateMeta) : void{ parent::readStateFromData($id, $stateMeta); - $this->lit = $id !== $this->idInfo->getSecondId(); + $this->lit = $id !== $this->idInfoFlattened->getSecondId(); } public function isLit() : bool{ diff --git a/src/block/Slab.php b/src/block/Slab.php index 275aa8bf8a..d1b37c3f94 100644 --- a/src/block/Slab.php +++ b/src/block/Slab.php @@ -33,18 +33,19 @@ use pocketmine\world\BlockTransaction; class Slab extends Transparent{ /** @var BlockIdentifierFlattened */ - protected $idInfo; + protected $idInfoFlattened; /** @var SlabType */ protected $slabType; public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + $this->idInfoFlattened = $idInfo; parent::__construct($idInfo, $name . " Slab", $breakInfo); $this->slabType = SlabType::BOTTOM(); } public function getId() : int{ - return $this->slabType->equals(SlabType::DOUBLE()) ? $this->idInfo->getSecondId() : parent::getId(); + return $this->slabType->equals(SlabType::DOUBLE()) ? $this->idInfoFlattened->getSecondId() : parent::getId(); } protected function writeStateToMeta() : int{ @@ -55,7 +56,7 @@ class Slab extends Transparent{ } public function readStateFromData(int $id, int $stateMeta) : void{ - if($id === $this->idInfo->getSecondId()){ + if($id === $this->idInfoFlattened->getSecondId()){ $this->slabType = SlabType::DOUBLE(); }else{ $this->slabType = ($stateMeta & BlockLegacyMetadata::SLAB_FLAG_UPPER) !== 0 ? SlabType::TOP() : SlabType::BOTTOM(); diff --git a/src/block/WallCoralFan.php b/src/block/WallCoralFan.php index 9e4fddf1f2..aee2cb8a0a 100644 --- a/src/block/WallCoralFan.php +++ b/src/block/WallCoralFan.php @@ -42,9 +42,10 @@ final class WallCoralFan extends BaseCoral{ use HorizontalFacingTrait; /** @var BlockIdentifierFlattened */ - protected $idInfo; + protected $idInfoFlattened; public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ + $this->idInfoFlattened = $idInfo; parent::__construct($idInfo, $name, $breakInfo); } @@ -54,13 +55,13 @@ final class WallCoralFan extends BaseCoral{ $coralTypeFlag = $stateMeta & BlockLegacyMetadata::CORAL_FAN_HANG_TYPE_MASK; switch($id){ - case $this->idInfo->getBlockId(): + case $this->idInfoFlattened->getBlockId(): $this->coralType = $coralTypeFlag === BlockLegacyMetadata::CORAL_FAN_HANG_TUBE ? CoralType::TUBE() : CoralType::BRAIN(); break; - case $this->idInfo->getAdditionalId(0): + case $this->idInfoFlattened->getAdditionalId(0): $this->coralType = $coralTypeFlag === BlockLegacyMetadata::CORAL_FAN_HANG2_BUBBLE ? CoralType::BUBBLE() : CoralType::FIRE(); break; - case $this->idInfo->getAdditionalId(1): + case $this->idInfoFlattened->getAdditionalId(1): if($coralTypeFlag !== BlockLegacyMetadata::CORAL_FAN_HANG3_HORN){ throw new InvalidBlockStateException("Invalid CORAL_FAN_HANG3 type"); } @@ -73,11 +74,11 @@ final class WallCoralFan extends BaseCoral{ public function getId() : int{ if($this->coralType->equals(CoralType::TUBE()) || $this->coralType->equals(CoralType::BRAIN())){ - return $this->idInfo->getBlockId(); + return $this->idInfoFlattened->getBlockId(); }elseif($this->coralType->equals(CoralType::BUBBLE()) || $this->coralType->equals(CoralType::FIRE())){ - return $this->idInfo->getAdditionalId(0); + return $this->idInfoFlattened->getAdditionalId(0); }elseif($this->coralType->equals(CoralType::HORN())){ - return $this->idInfo->getAdditionalId(1); + return $this->idInfoFlattened->getAdditionalId(1); } throw new AssumptionFailedError("All types of coral should be covered"); } From f68b9e79e1ebadf6b80641292a14208f6d2919a0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 22 May 2021 23:52:31 +0100 Subject: [PATCH 2506/3224] Use typed properties in block namespace --- src/block/Anvil.php | 3 +-- src/block/Bamboo.php | 9 +++------ src/block/BambooSapling.php | 3 +-- src/block/Barrel.php | 3 +-- src/block/BaseBanner.php | 6 +++--- src/block/BaseRail.php | 2 +- src/block/BaseSign.php | 7 ++----- src/block/Bed.php | 9 +++------ src/block/Bedrock.php | 3 +-- src/block/Block.php | 17 +++++------------ src/block/BlockBreakInfo.php | 12 ++++-------- src/block/BlockIdentifier.php | 16 +++++----------- src/block/BrewingStand.php | 2 +- src/block/Button.php | 3 +-- src/block/Cactus.php | 3 +-- src/block/Cake.php | 3 +-- src/block/CocoaBlock.php | 3 +-- src/block/CoralBlock.php | 7 ++----- src/block/Crops.php | 4 ++-- src/block/DaylightSensor.php | 6 ++---- src/block/Door.php | 10 +++------- src/block/DoublePlant.php | 3 +-- src/block/Element.php | 9 +++------ src/block/EndPortalFrame.php | 3 +-- src/block/Farmland.php | 3 +-- src/block/Fence.php | 2 +- src/block/FenceGate.php | 6 ++---- src/block/Fire.php | 3 +-- src/block/FloorCoralFan.php | 4 ++-- src/block/FlowerPot.php | 7 ++----- src/block/FrostedIce.php | 3 +-- src/block/Furnace.php | 6 ++---- src/block/Hopper.php | 3 +-- src/block/ItemFrame.php | 13 +++++-------- src/block/Jukebox.php | 4 ++-- src/block/Lantern.php | 3 +-- src/block/Leaves.php | 9 +++------ src/block/Lever.php | 9 +++------ src/block/Liquid.php | 21 ++++++++------------- src/block/NetherPortal.php | 4 ++-- src/block/NetherReactor.php | 3 +-- src/block/NetherWartPlant.php | 3 +-- src/block/Note.php | 3 +-- src/block/RedMushroomBlock.php | 2 +- src/block/RedstoneComparator.php | 6 ++---- src/block/RedstoneLamp.php | 3 +-- src/block/RedstoneOre.php | 7 +++---- src/block/RedstoneRepeater.php | 6 ++---- src/block/RedstoneTorch.php | 6 ++---- src/block/Sapling.php | 7 +++---- src/block/SeaPickle.php | 7 +++---- src/block/SimplePressurePlate.php | 3 +-- src/block/Skull.php | 10 +++------- src/block/Slab.php | 7 +++---- src/block/SnowLayer.php | 3 +-- src/block/Sponge.php | 3 +-- src/block/Stair.php | 7 ++----- src/block/Sugarcane.php | 3 +-- src/block/TNT.php | 3 +-- src/block/Thin.php | 2 +- src/block/Torch.php | 3 +-- src/block/Trapdoor.php | 6 ++---- src/block/Tripwire.php | 12 ++++-------- src/block/TripwireHook.php | 6 ++---- src/block/Vine.php | 2 +- src/block/Wall.php | 5 ++--- src/block/WallCoralFan.php | 3 +-- src/block/Wood.php | 3 +-- 68 files changed, 134 insertions(+), 246 deletions(-) diff --git a/src/block/Anvil.php b/src/block/Anvil.php index bc84f55d48..050ecc057b 100644 --- a/src/block/Anvil.php +++ b/src/block/Anvil.php @@ -39,8 +39,7 @@ class Anvil extends Transparent implements Fallable{ use FallableTrait; use HorizontalFacingTrait; - /** @var int */ - private $damage = 0; + private int $damage = 0; protected function writeStateToMeta() : int{ return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) | ($this->damage << 2); diff --git a/src/block/Bamboo.php b/src/block/Bamboo.php index c1848cf229..87ec7de2e5 100644 --- a/src/block/Bamboo.php +++ b/src/block/Bamboo.php @@ -48,12 +48,9 @@ class Bamboo extends Transparent{ public const SMALL_LEAVES = 1; public const LARGE_LEAVES = 2; - /** @var bool */ - protected $thick = false; //age in PC, but this is 0/1 - /** @var bool */ - protected $ready = false; - /** @var int */ - protected $leafSize = self::NO_LEAVES; + protected bool $thick = false; //age in PC, but this is 0/1 + protected bool $ready = false; + protected int $leafSize = self::NO_LEAVES; public function readStateFromData(int $id, int $stateMeta) : void{ $this->thick = ($stateMeta & BlockLegacyMetadata::BAMBOO_FLAG_THICK) !== 0; diff --git a/src/block/BambooSapling.php b/src/block/BambooSapling.php index 880e4349c7..5a35b0bb1a 100644 --- a/src/block/BambooSapling.php +++ b/src/block/BambooSapling.php @@ -32,8 +32,7 @@ use pocketmine\world\BlockTransaction; final class BambooSapling extends Flowable{ - /** @var bool */ - private $ready = false; + private bool $ready = false; public function readStateFromData(int $id, int $stateMeta) : void{ $this->ready = ($stateMeta & BlockLegacyMetadata::SAPLING_FLAG_READY) !== 0; diff --git a/src/block/Barrel.php b/src/block/Barrel.php index 27301cee91..40ee03d770 100644 --- a/src/block/Barrel.php +++ b/src/block/Barrel.php @@ -36,8 +36,7 @@ use function abs; class Barrel extends Opaque{ use AnyFacingTrait; - /** @var bool */ - protected $open = false; + protected bool $open = false; protected function writeStateToMeta() : int{ return BlockDataSerializer::writeFacing($this->facing) | ($this->open ? BlockLegacyMetadata::BARREL_FLAG_OPEN : 0); diff --git a/src/block/BaseBanner.php b/src/block/BaseBanner.php index e9bf340eca..2547b2ca34 100644 --- a/src/block/BaseBanner.php +++ b/src/block/BaseBanner.php @@ -40,14 +40,14 @@ use function assert; use function count; abstract class BaseBanner extends Transparent{ - /** @var DyeColor */ - protected $baseColor; + + protected DyeColor $baseColor; /** * @var BannerPatternLayer[] * @phpstan-var list */ - protected $patterns = []; + protected array $patterns = []; public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ parent::__construct($idInfo, $name, $breakInfo); diff --git a/src/block/BaseRail.php b/src/block/BaseRail.php index f78bc98c15..bafcfe2a41 100644 --- a/src/block/BaseRail.php +++ b/src/block/BaseRail.php @@ -72,7 +72,7 @@ abstract class BaseRail extends Flowable{ ]; /** @var int[] */ - protected $connections = []; + protected array $connections = []; protected function writeStateToMeta() : int{ if(count($this->connections) === 0){ diff --git a/src/block/BaseSign.php b/src/block/BaseSign.php index 21de8f6f70..8b8d72ae01 100644 --- a/src/block/BaseSign.php +++ b/src/block/BaseSign.php @@ -39,11 +39,8 @@ use function strlen; abstract class BaseSign extends Transparent{ //TODO: conditionally useless properties, find a way to fix - /** @var SignText */ - protected $text; - - /** @var int|null */ - protected $editorEntityRuntimeId = null; + protected SignText $text; + protected ?int $editorEntityRuntimeId = null; public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ parent::__construct($idInfo, $name, $breakInfo); diff --git a/src/block/Bed.php b/src/block/Bed.php index 6b581759ed..1a7482990f 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -43,12 +43,9 @@ use pocketmine\world\World; class Bed extends Transparent{ use HorizontalFacingTrait; - /** @var bool */ - protected $occupied = false; - /** @var bool */ - protected $head = false; - /** @var DyeColor */ - protected $color; + protected bool $occupied = false; + protected bool $head = false; + protected DyeColor $color; public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ parent::__construct($idInfo, $name, $breakInfo); diff --git a/src/block/Bedrock.php b/src/block/Bedrock.php index 7cc9624ec8..e794e39583 100644 --- a/src/block/Bedrock.php +++ b/src/block/Bedrock.php @@ -25,8 +25,7 @@ namespace pocketmine\block; class Bedrock extends Opaque{ - /** @var bool */ - private $burnsForever = false; + private bool $burnsForever = false; public function readStateFromData(int $id, int $stateMeta) : void{ $this->burnsForever = ($stateMeta & BlockLegacyMetadata::BEDROCK_FLAG_INFINIBURN) !== 0; diff --git a/src/block/Block.php b/src/block/Block.php index d54f6ef2b8..1dceaf22de 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -49,20 +49,13 @@ use const PHP_INT_MAX; class Block{ - /** @var BlockIdentifier */ - protected $idInfo; - - /** @var string */ - protected $fallbackName; - - /** @var BlockBreakInfo */ - protected $breakInfo; - - /** @var Position */ - protected $pos; + protected BlockIdentifier $idInfo; + protected string $fallbackName; + protected BlockBreakInfo $breakInfo; + protected Position $pos; /** @var AxisAlignedBB[]|null */ - protected $collisionBoxes = null; + protected ?array $collisionBoxes = null; /** * @param string $name English name of the block type (TODO: implement translations) diff --git a/src/block/BlockBreakInfo.php b/src/block/BlockBreakInfo.php index cff5a9034b..6d44f88202 100644 --- a/src/block/BlockBreakInfo.php +++ b/src/block/BlockBreakInfo.php @@ -28,14 +28,10 @@ use function get_class; class BlockBreakInfo{ - /** @var float */ - private $hardness; - /** @var float */ - private $blastResistance; - /** @var int */ - private $toolType; - /** @var int */ - private $toolHarvestLevel; + private float $hardness; + private float $blastResistance; + private int $toolType; + private int $toolHarvestLevel; /** * @param float|null $blastResistance default 5x hardness diff --git a/src/block/BlockIdentifier.php b/src/block/BlockIdentifier.php index 5b96066430..5ea45c90b0 100644 --- a/src/block/BlockIdentifier.php +++ b/src/block/BlockIdentifier.php @@ -27,17 +27,11 @@ use pocketmine\block\tile\Tile; class BlockIdentifier{ - /** @var int */ - private $blockId; - /** @var int */ - private $variant; - /** @var int|null */ - private $itemId; - /** - * @var string|null - * @phpstan-var class-string|null - */ - private $tileClass; + private int $blockId; + private int $variant; + private ?int $itemId; + /** @phpstan-var class-string|null */ + private ?string $tileClass; /** * @phpstan-param class-string|null $tileClass diff --git a/src/block/BrewingStand.php b/src/block/BrewingStand.php index f94f73c2a2..2afe267a50 100644 --- a/src/block/BrewingStand.php +++ b/src/block/BrewingStand.php @@ -36,7 +36,7 @@ class BrewingStand extends Transparent{ * @var BrewingStandSlot[] * @phpstan-var array */ - protected $slots = []; + protected array $slots = []; protected function writeStateToMeta() : int{ $flags = 0; diff --git a/src/block/Button.php b/src/block/Button.php index 0f50778ec8..0b9f88ed3c 100644 --- a/src/block/Button.php +++ b/src/block/Button.php @@ -36,8 +36,7 @@ use pocketmine\world\sound\RedstonePowerOnSound; abstract class Button extends Flowable{ use AnyFacingTrait; - /** @var bool */ - protected $pressed = false; + protected bool $pressed = false; protected function writeStateToMeta() : int{ return BlockDataSerializer::writeFacing($this->facing) | ($this->pressed ? BlockLegacyMetadata::BUTTON_FLAG_POWERED : 0); diff --git a/src/block/Cactus.php b/src/block/Cactus.php index 69ea4eb98e..48a0349142 100644 --- a/src/block/Cactus.php +++ b/src/block/Cactus.php @@ -37,8 +37,7 @@ use pocketmine\world\BlockTransaction; class Cactus extends Transparent{ - /** @var int */ - protected $age = 0; + protected int $age = 0; protected function writeStateToMeta() : int{ return $this->age; diff --git a/src/block/Cake.php b/src/block/Cake.php index 3926579494..6dcf251a94 100644 --- a/src/block/Cake.php +++ b/src/block/Cake.php @@ -36,8 +36,7 @@ use pocketmine\world\BlockTransaction; class Cake extends Transparent implements FoodSource{ - /** @var int */ - protected $bites = 0; + protected int $bites = 0; protected function writeStateToMeta() : int{ return $this->bites; diff --git a/src/block/CocoaBlock.php b/src/block/CocoaBlock.php index 0ccb579784..8c86749559 100644 --- a/src/block/CocoaBlock.php +++ b/src/block/CocoaBlock.php @@ -40,8 +40,7 @@ use function mt_rand; class CocoaBlock extends Transparent{ use HorizontalFacingTrait; - /** @var int */ - protected $age = 0; + protected int $age = 0; protected function writeStateToMeta() : int{ return BlockDataSerializer::writeLegacyHorizontalFacing(Facing::opposite($this->facing)) | ($this->age << 2); diff --git a/src/block/CoralBlock.php b/src/block/CoralBlock.php index 795621c23e..130b1ffd8e 100644 --- a/src/block/CoralBlock.php +++ b/src/block/CoralBlock.php @@ -31,11 +31,8 @@ use function mt_rand; final class CoralBlock extends Opaque{ - /** @var CoralType */ - private $coralType; - - /** @var bool */ - private $dead = false; + private CoralType $coralType; + private bool $dead = false; public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ $this->coralType = CoralType::TUBE(); diff --git a/src/block/Crops.php b/src/block/Crops.php index d931fa3713..2f2d3d21a0 100644 --- a/src/block/Crops.php +++ b/src/block/Crops.php @@ -34,8 +34,8 @@ use pocketmine\world\BlockTransaction; use function mt_rand; abstract class Crops extends Flowable{ - /** @var int */ - protected $age = 0; + + protected int $age = 0; protected function writeStateToMeta() : int{ return $this->age; diff --git a/src/block/DaylightSensor.php b/src/block/DaylightSensor.php index 26dd582939..fbcb92f5e4 100644 --- a/src/block/DaylightSensor.php +++ b/src/block/DaylightSensor.php @@ -38,11 +38,9 @@ use const M_PI; class DaylightSensor extends Transparent{ use AnalogRedstoneSignalEmitterTrait; - /** @var BlockIdentifierFlattened */ - protected $idInfoFlattened; + protected BlockIdentifierFlattened $idInfoFlattened; - /** @var bool */ - protected $inverted = false; + protected bool $inverted = false; public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ $this->idInfoFlattened = $idInfo; diff --git a/src/block/Door.php b/src/block/Door.php index 312c404a0a..7b421aeaf1 100644 --- a/src/block/Door.php +++ b/src/block/Door.php @@ -38,13 +38,9 @@ class Door extends Transparent{ use HorizontalFacingTrait; use PoweredByRedstoneTrait; - /** @var bool */ - protected $top = false; - /** @var bool */ - protected $hingeRight = false; - - /** @var bool */ - protected $open = false; + protected bool $top = false; + protected bool $hingeRight = false; + protected bool $open = false; protected function writeStateToMeta() : int{ if($this->top){ diff --git a/src/block/DoublePlant.php b/src/block/DoublePlant.php index aade018299..fb25379c5a 100644 --- a/src/block/DoublePlant.php +++ b/src/block/DoublePlant.php @@ -31,8 +31,7 @@ use pocketmine\world\BlockTransaction; class DoublePlant extends Flowable{ - /** @var bool */ - protected $top = false; + protected bool $top = false; protected function writeStateToMeta() : int{ return ($this->top ? BlockLegacyMetadata::DOUBLE_PLANT_FLAG_TOP : 0); diff --git a/src/block/Element.php b/src/block/Element.php index f12ab86725..f3f66a5871 100644 --- a/src/block/Element.php +++ b/src/block/Element.php @@ -25,12 +25,9 @@ namespace pocketmine\block; class Element extends Opaque{ - /** @var int */ - private $atomicWeight; - /** @var int */ - private $group; - /** @var string */ - private $symbol; + private int $atomicWeight; + private int $group; + private string $symbol; public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo, string $symbol, int $atomicWeight, int $group){ parent::__construct($idInfo, $name, $breakInfo); diff --git a/src/block/EndPortalFrame.php b/src/block/EndPortalFrame.php index b1ec84fa64..a80b2cf2cb 100644 --- a/src/block/EndPortalFrame.php +++ b/src/block/EndPortalFrame.php @@ -33,8 +33,7 @@ class EndPortalFrame extends Opaque{ use FacesOppositePlacingPlayerTrait; use HorizontalFacingTrait; - /** @var bool */ - protected $eye = false; + protected bool $eye = false; protected function writeStateToMeta() : int{ return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) | ($this->eye ? BlockLegacyMetadata::END_PORTAL_FRAME_FLAG_EYE : 0); diff --git a/src/block/Farmland.php b/src/block/Farmland.php index fd1aecf076..461c24493a 100644 --- a/src/block/Farmland.php +++ b/src/block/Farmland.php @@ -30,8 +30,7 @@ use pocketmine\math\Facing; class Farmland extends Transparent{ - /** @var int */ - protected $wetness = 0; //"moisture" blockstate property in PC + protected int $wetness = 0; //"moisture" blockstate property in PC protected function writeStateToMeta() : int{ return $this->wetness; diff --git a/src/block/Fence.php b/src/block/Fence.php index 1eeffc3a1b..0ee3cdaf1b 100644 --- a/src/block/Fence.php +++ b/src/block/Fence.php @@ -30,7 +30,7 @@ use function count; class Fence extends Transparent{ /** @var bool[] facing => dummy */ - protected $connections = []; + protected array $connections = []; public function getThickness() : float{ return 0.25; diff --git a/src/block/FenceGate.php b/src/block/FenceGate.php index 6e1b4defa2..f8240ee006 100644 --- a/src/block/FenceGate.php +++ b/src/block/FenceGate.php @@ -36,10 +36,8 @@ use pocketmine\world\sound\DoorSound; class FenceGate extends Transparent{ use HorizontalFacingTrait; - /** @var bool */ - protected $open = false; - /** @var bool */ - protected $inWall = false; + protected bool $open = false; + protected bool $inWall = false; protected function writeStateToMeta() : int{ return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) | diff --git a/src/block/Fire.php b/src/block/Fire.php index 14fc8cd6f1..e16e3adb28 100644 --- a/src/block/Fire.php +++ b/src/block/Fire.php @@ -37,8 +37,7 @@ use function mt_rand; class Fire extends Flowable{ - /** @var int */ - protected $age = 0; + protected int $age = 0; protected function writeStateToMeta() : int{ return $this->age; diff --git a/src/block/FloorCoralFan.php b/src/block/FloorCoralFan.php index 1b69f0b6f2..728b92aed5 100644 --- a/src/block/FloorCoralFan.php +++ b/src/block/FloorCoralFan.php @@ -36,8 +36,8 @@ use function atan2; use function rad2deg; final class FloorCoralFan extends BaseCoral{ - /** @var BlockIdentifierFlattened */ - protected $idInfoFlattened; + + protected BlockIdentifierFlattened $idInfoFlattened; private int $axis = Axis::X; diff --git a/src/block/FlowerPot.php b/src/block/FlowerPot.php index b5f7eedfff..91c1361e3b 100644 --- a/src/block/FlowerPot.php +++ b/src/block/FlowerPot.php @@ -36,12 +36,9 @@ class FlowerPot extends Flowable{ /** * TODO: get rid of this hack (it's currently needed to deal with blockfactory state handling) - * @var bool */ - protected $occupied = false; - - /** @var Block|null */ - protected $plant = null; + protected bool $occupied = false; + protected ?Block $plant = null; protected function writeStateToMeta() : int{ return $this->occupied ? BlockLegacyMetadata::FLOWER_POT_FLAG_OCCUPIED : 0; diff --git a/src/block/FrostedIce.php b/src/block/FrostedIce.php index 0099b71cf2..18857b8342 100644 --- a/src/block/FrostedIce.php +++ b/src/block/FrostedIce.php @@ -28,8 +28,7 @@ use function mt_rand; class FrostedIce extends Ice{ - /** @var int */ - protected $age = 0; + protected int $age = 0; public function readStateFromData(int $id, int $stateMeta) : void{ $this->age = BlockDataSerializer::readBoundedInt("age", $stateMeta, 0, 3); diff --git a/src/block/Furnace.php b/src/block/Furnace.php index 6a78202827..23285501e0 100644 --- a/src/block/Furnace.php +++ b/src/block/Furnace.php @@ -36,11 +36,9 @@ class Furnace extends Opaque{ readStateFromData as readFacingStateFromData; } - /** @var BlockIdentifierFlattened */ - protected $idInfoFlattened; + protected BlockIdentifierFlattened $idInfoFlattened; - /** @var bool */ - protected $lit = false; //this is set based on the blockID + protected bool $lit = false; //this is set based on the blockID public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ $this->idInfoFlattened = $idInfo; diff --git a/src/block/Hopper.php b/src/block/Hopper.php index f05d82a173..c05362f314 100644 --- a/src/block/Hopper.php +++ b/src/block/Hopper.php @@ -37,8 +37,7 @@ use pocketmine\world\BlockTransaction; class Hopper extends Transparent{ use PoweredByRedstoneTrait; - /** @var int */ - private $facing = Facing::DOWN; + private int $facing = Facing::DOWN; public function readStateFromData(int $id, int $stateMeta) : void{ $facing = BlockDataSerializer::readFacing($stateMeta & 0x07); diff --git a/src/block/ItemFrame.php b/src/block/ItemFrame.php index 6737519388..523d37c21b 100644 --- a/src/block/ItemFrame.php +++ b/src/block/ItemFrame.php @@ -38,14 +38,11 @@ class ItemFrame extends Flowable{ public const ROTATIONS = 8; - /** @var bool */ - protected $hasMap = false; //makes frame appear large if set - /** @var Item|null */ - protected $framedItem = null; - /** @var int */ - protected $itemRotation = 0; - /** @var float */ - protected $itemDropChance = 1.0; + protected bool $hasMap = false; //makes frame appear large if set + + protected ?Item $framedItem = null; + protected int $itemRotation = 0; + protected float $itemDropChance = 1.0; protected function writeStateToMeta() : int{ return BlockDataSerializer::write5MinusHorizontalFacing($this->facing) | ($this->hasMap ? BlockLegacyMetadata::ITEM_FRAME_FLAG_HAS_MAP : 0); diff --git a/src/block/Jukebox.php b/src/block/Jukebox.php index 6d192bbe28..66369817b3 100644 --- a/src/block/Jukebox.php +++ b/src/block/Jukebox.php @@ -32,8 +32,8 @@ use pocketmine\world\sound\RecordSound; use pocketmine\world\sound\RecordStopSound; class Jukebox extends Opaque{ - /** @var Record|null */ - private $record = null; + + private ?Record $record = null; public function getFuelTime() : int{ return 300; diff --git a/src/block/Lantern.php b/src/block/Lantern.php index aa0a4fe039..b6c91a1f4c 100644 --- a/src/block/Lantern.php +++ b/src/block/Lantern.php @@ -33,8 +33,7 @@ use pocketmine\world\BlockTransaction; class Lantern extends Transparent{ - /** @var bool */ - protected $hanging = false; + protected bool $hanging = false; public function readStateFromData(int $id, int $stateMeta) : void{ $this->hanging = ($stateMeta & BlockLegacyMetadata::LANTERN_FLAG_HANGING) !== 0; diff --git a/src/block/Leaves.php b/src/block/Leaves.php index 5578c6be65..9f14d8d4eb 100644 --- a/src/block/Leaves.php +++ b/src/block/Leaves.php @@ -37,13 +37,10 @@ use pocketmine\world\World; use function mt_rand; class Leaves extends Transparent{ - /** @var TreeType */ - protected $treeType; - /** @var bool */ - protected $noDecay = false; - /** @var bool */ - protected $checkDecay = false; + protected TreeType $treeType; + protected bool $noDecay = false; + protected bool $checkDecay = false; public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo, TreeType $treeType){ parent::__construct($idInfo, $name, $breakInfo); diff --git a/src/block/Lever.php b/src/block/Lever.php index 027ea6525f..c4d2abc9d4 100644 --- a/src/block/Lever.php +++ b/src/block/Lever.php @@ -38,12 +38,9 @@ class Lever extends Flowable{ protected const SIDE = 1; protected const TOP = 2; - /** @var int */ - protected $leverPos = self::BOTTOM; - /** @var int */ - protected $facing = Facing::NORTH; - /** @var bool */ - protected $powered = false; + protected int $leverPos = self::BOTTOM; + protected int $facing = Facing::NORTH; + protected bool $powered = false; protected function writeStateToMeta() : int{ if($this->leverPos === self::BOTTOM){ diff --git a/src/block/Liquid.php b/src/block/Liquid.php index 77775a5fbd..a04ac589ea 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -39,28 +39,23 @@ use function lcg_value; use function min; abstract class Liquid extends Transparent{ - /** @var BlockIdentifierFlattened */ - protected $idInfoFlattened; - /** @var int */ - public $adjacentSources = 0; + protected BlockIdentifierFlattened $idInfoFlattened; - /** @var Vector3|null */ - protected $flowVector = null; + public int $adjacentSources = 0; + + protected ?Vector3 $flowVector = null; /** @var int[] */ - private $flowCostVisited = []; + private array $flowCostVisited = []; private const CAN_FLOW_DOWN = 1; private const CAN_FLOW = 0; private const BLOCKED = -1; - /** @var bool */ - protected $falling = false; - /** @var int */ - protected $decay = 0; //PC "level" property - /** @var bool */ - protected $still = false; + protected bool $falling = false; + protected int $decay = 0; //PC "level" property + protected bool $still = false; public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ $this->idInfoFlattened = $idInfo; diff --git a/src/block/NetherPortal.php b/src/block/NetherPortal.php index d5cc01cd8a..b8c73d0a74 100644 --- a/src/block/NetherPortal.php +++ b/src/block/NetherPortal.php @@ -29,8 +29,8 @@ use pocketmine\math\Axis; use pocketmine\math\AxisAlignedBB; class NetherPortal extends Transparent{ - /** @var int */ - protected $axis = Axis::X; + + protected int $axis = Axis::X; public function readStateFromData(int $id, int $stateMeta) : void{ $this->axis = $stateMeta === BlockLegacyMetadata::NETHER_PORTAL_AXIS_Z ? Axis::Z : Axis::X; //mojang u dumb diff --git a/src/block/NetherReactor.php b/src/block/NetherReactor.php index f5c4272f61..96e5f0640f 100644 --- a/src/block/NetherReactor.php +++ b/src/block/NetherReactor.php @@ -29,8 +29,7 @@ use pocketmine\item\VanillaItems; class NetherReactor extends Opaque{ - /** @var int */ - protected $state = BlockLegacyMetadata::NETHER_REACTOR_INACTIVE; + protected int $state = BlockLegacyMetadata::NETHER_REACTOR_INACTIVE; protected function writeStateToMeta() : int{ return $this->state; diff --git a/src/block/NetherWartPlant.php b/src/block/NetherWartPlant.php index 028eba936f..ca727a8cce 100644 --- a/src/block/NetherWartPlant.php +++ b/src/block/NetherWartPlant.php @@ -34,8 +34,7 @@ use function mt_rand; class NetherWartPlant extends Flowable{ - /** @var int */ - protected $age = 0; + protected int $age = 0; protected function writeStateToMeta() : int{ return $this->age; diff --git a/src/block/Note.php b/src/block/Note.php index ee78207e1c..0cdd9fdaae 100644 --- a/src/block/Note.php +++ b/src/block/Note.php @@ -30,8 +30,7 @@ class Note extends Opaque{ public const MIN_PITCH = 0; public const MAX_PITCH = 24; - /** @var int */ - private $pitch = self::MIN_PITCH; + private int $pitch = self::MIN_PITCH; public function readStateFromWorld() : void{ parent::readStateFromWorld(); diff --git a/src/block/RedMushroomBlock.php b/src/block/RedMushroomBlock.php index cb9d418cc6..955514bcab 100644 --- a/src/block/RedMushroomBlock.php +++ b/src/block/RedMushroomBlock.php @@ -35,7 +35,7 @@ class RedMushroomBlock extends Opaque{ * the legacy crap for now. * TODO: change this once proper blockstates are implemented */ - protected $rotationData = 0; + protected int $rotationData = 0; protected function writeStateToMeta() : int{ return $this->rotationData; diff --git a/src/block/RedstoneComparator.php b/src/block/RedstoneComparator.php index 4ba4d938e2..b58dd1a697 100644 --- a/src/block/RedstoneComparator.php +++ b/src/block/RedstoneComparator.php @@ -41,11 +41,9 @@ class RedstoneComparator extends Flowable{ use AnalogRedstoneSignalEmitterTrait; use PoweredByRedstoneTrait; - /** @var BlockIdentifierFlattened */ - protected $idInfoFlattened; + protected BlockIdentifierFlattened $idInfoFlattened; - /** @var bool */ - protected $isSubtractMode = false; + protected bool $isSubtractMode = false; public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ $this->idInfoFlattened = $idInfo; diff --git a/src/block/RedstoneLamp.php b/src/block/RedstoneLamp.php index 7398c51dbd..b0f7bc9bc3 100644 --- a/src/block/RedstoneLamp.php +++ b/src/block/RedstoneLamp.php @@ -28,8 +28,7 @@ use pocketmine\block\utils\PoweredByRedstoneTrait; class RedstoneLamp extends Opaque{ use PoweredByRedstoneTrait; - /** @var BlockIdentifierFlattened */ - protected $idInfoFlattened; + protected BlockIdentifierFlattened $idInfoFlattened; public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ $this->idInfoFlattened = $idInfo; diff --git a/src/block/RedstoneOre.php b/src/block/RedstoneOre.php index 9d32c4c6cb..6078f8bfdd 100644 --- a/src/block/RedstoneOre.php +++ b/src/block/RedstoneOre.php @@ -30,11 +30,10 @@ use pocketmine\player\Player; use function mt_rand; class RedstoneOre extends Opaque{ - /** @var BlockIdentifierFlattened */ - protected $idInfoFlattened; - /** @var bool */ - protected $lit = false; + protected BlockIdentifierFlattened $idInfoFlattened; + + protected bool $lit = false; public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ $this->idInfoFlattened = $idInfo; diff --git a/src/block/RedstoneRepeater.php b/src/block/RedstoneRepeater.php index 7bd17e8577..2aa1ba1097 100644 --- a/src/block/RedstoneRepeater.php +++ b/src/block/RedstoneRepeater.php @@ -37,11 +37,9 @@ class RedstoneRepeater extends Flowable{ use HorizontalFacingTrait; use PoweredByRedstoneTrait; - /** @var BlockIdentifierFlattened */ - protected $idInfoFlattened; + protected BlockIdentifierFlattened $idInfoFlattened; - /** @var int */ - protected $delay = 1; + protected int $delay = 1; public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ $this->idInfoFlattened = $idInfo; diff --git a/src/block/RedstoneTorch.php b/src/block/RedstoneTorch.php index 62badbc1aa..43f6fbe642 100644 --- a/src/block/RedstoneTorch.php +++ b/src/block/RedstoneTorch.php @@ -25,11 +25,9 @@ namespace pocketmine\block; class RedstoneTorch extends Torch{ - /** @var BlockIdentifierFlattened */ - protected $idInfoFlattened; + protected BlockIdentifierFlattened $idInfoFlattened; - /** @var bool */ - protected $lit = true; + protected bool $lit = true; public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ $this->idInfoFlattened = $idInfo; diff --git a/src/block/Sapling.php b/src/block/Sapling.php index 64f1f5ad67..8605324a0f 100644 --- a/src/block/Sapling.php +++ b/src/block/Sapling.php @@ -36,10 +36,9 @@ use function mt_rand; class Sapling extends Flowable{ - /** @var bool */ - protected $ready = false; - /** @var TreeType */ - private $treeType; + protected bool $ready = false; + + private TreeType $treeType; public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo, TreeType $treeType){ parent::__construct($idInfo, $name, $breakInfo); diff --git a/src/block/SeaPickle.php b/src/block/SeaPickle.php index 22a2b4c217..9110dc22c4 100644 --- a/src/block/SeaPickle.php +++ b/src/block/SeaPickle.php @@ -30,10 +30,9 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class SeaPickle extends Transparent{ - /** @var int */ - protected $count = 1; - /** @var bool */ - protected $underwater = false; + + protected int $count = 1; + protected bool $underwater = false; public function readStateFromData(int $id, int $stateMeta) : void{ $this->count = ($stateMeta & 0x03) + 1; diff --git a/src/block/SimplePressurePlate.php b/src/block/SimplePressurePlate.php index 5635dcf36b..293106fd12 100644 --- a/src/block/SimplePressurePlate.php +++ b/src/block/SimplePressurePlate.php @@ -25,8 +25,7 @@ namespace pocketmine\block; abstract class SimplePressurePlate extends PressurePlate{ - /** @var bool */ - protected $pressed = false; + protected bool $pressed = false; protected function writeStateToMeta() : int{ return $this->pressed ? BlockLegacyMetadata::PRESSURE_PLATE_FLAG_POWERED : 0; diff --git a/src/block/Skull.php b/src/block/Skull.php index 625b0aa0ef..9c05649471 100644 --- a/src/block/Skull.php +++ b/src/block/Skull.php @@ -39,16 +39,12 @@ use function assert; use function floor; class Skull extends Flowable{ - /** @var SkullType */ - protected $skullType; - /** @var int */ - protected $facing = Facing::NORTH; + protected SkullType $skullType; + protected int $facing = Facing::NORTH; protected bool $noDrops = false; - - /** @var int */ - protected $rotation = 0; //TODO: split this into floor skull and wall skull handling + protected int $rotation = 0; //TODO: split this into floor skull and wall skull handling public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ $this->skullType = SkullType::SKELETON(); //TODO: this should be a parameter diff --git a/src/block/Slab.php b/src/block/Slab.php index d1b37c3f94..610c6ee8c0 100644 --- a/src/block/Slab.php +++ b/src/block/Slab.php @@ -32,11 +32,10 @@ use pocketmine\player\Player; use pocketmine\world\BlockTransaction; class Slab extends Transparent{ - /** @var BlockIdentifierFlattened */ - protected $idInfoFlattened; - /** @var SlabType */ - protected $slabType; + protected BlockIdentifierFlattened $idInfoFlattened; + + protected SlabType $slabType; public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ $this->idInfoFlattened = $idInfo; diff --git a/src/block/SnowLayer.php b/src/block/SnowLayer.php index a3bb8f3956..015f0b5b44 100644 --- a/src/block/SnowLayer.php +++ b/src/block/SnowLayer.php @@ -39,8 +39,7 @@ use function max; class SnowLayer extends Flowable implements Fallable{ use FallableTrait; - /** @var int */ - protected $layers = 1; + protected int $layers = 1; protected function writeStateToMeta() : int{ return $this->layers - 1; diff --git a/src/block/Sponge.php b/src/block/Sponge.php index ea53c0d0d4..63ca4a1336 100644 --- a/src/block/Sponge.php +++ b/src/block/Sponge.php @@ -25,8 +25,7 @@ namespace pocketmine\block; class Sponge extends Opaque{ - /** @var bool */ - protected $wet = false; + protected bool $wet = false; protected function writeStateToMeta() : int{ return $this->wet ? BlockLegacyMetadata::SPONGE_FLAG_WET : 0; diff --git a/src/block/Stair.php b/src/block/Stair.php index 9b477e5141..b4dd2c65a5 100644 --- a/src/block/Stair.php +++ b/src/block/Stair.php @@ -36,11 +36,8 @@ use pocketmine\world\BlockTransaction; class Stair extends Transparent{ use HorizontalFacingTrait; - /** @var bool */ - protected $upsideDown = false; - - /** @var StairShape */ - protected $shape; + protected bool $upsideDown = false; + protected StairShape $shape; public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ $this->shape = StairShape::STRAIGHT(); diff --git a/src/block/Sugarcane.php b/src/block/Sugarcane.php index 69e11b041a..15e6bad6d2 100644 --- a/src/block/Sugarcane.php +++ b/src/block/Sugarcane.php @@ -34,8 +34,7 @@ use pocketmine\world\BlockTransaction; class Sugarcane extends Flowable{ - /** @var int */ - protected $age = 0; + protected int $age = 0; protected function writeStateToMeta() : int{ return $this->age; diff --git a/src/block/TNT.php b/src/block/TNT.php index 1dc00e1a9f..6180ec6eac 100644 --- a/src/block/TNT.php +++ b/src/block/TNT.php @@ -41,8 +41,7 @@ use const M_PI; class TNT extends Opaque{ - /** @var bool */ - protected $unstable = false; //TODO: Usage unclear, seems to be a weird hack in vanilla + protected bool $unstable = false; //TODO: Usage unclear, seems to be a weird hack in vanilla protected bool $worksUnderwater = false; public function readStateFromData(int $id, int $stateMeta) : void{ diff --git a/src/block/Thin.php b/src/block/Thin.php index 060bf667c7..3f3dc86e73 100644 --- a/src/block/Thin.php +++ b/src/block/Thin.php @@ -30,7 +30,7 @@ use function count; class Thin extends Transparent{ /** @var bool[] facing => dummy */ - protected $connections = []; + protected array $connections = []; public function readStateFromWorld() : void{ parent::readStateFromWorld(); diff --git a/src/block/Torch.php b/src/block/Torch.php index 478e989fae..173920cae2 100644 --- a/src/block/Torch.php +++ b/src/block/Torch.php @@ -32,8 +32,7 @@ use pocketmine\world\BlockTransaction; class Torch extends Flowable{ - /** @var int */ - protected $facing = Facing::UP; + protected int $facing = Facing::UP; protected function writeStateToMeta() : int{ return $this->facing === Facing::UP ? 5 : 6 - BlockDataSerializer::writeHorizontalFacing($this->facing); diff --git a/src/block/Trapdoor.php b/src/block/Trapdoor.php index 7e82f725bc..490994b6ec 100644 --- a/src/block/Trapdoor.php +++ b/src/block/Trapdoor.php @@ -36,10 +36,8 @@ use pocketmine\world\sound\DoorSound; class Trapdoor extends Transparent{ use HorizontalFacingTrait; - /** @var bool */ - protected $open = false; - /** @var bool */ - protected $top = false; + protected bool $open = false; + protected bool $top = false; protected function writeStateToMeta() : int{ return BlockDataSerializer::write5MinusHorizontalFacing($this->facing) | ($this->top ? BlockLegacyMetadata::TRAPDOOR_FLAG_UPPER : 0) | ($this->open ? BlockLegacyMetadata::TRAPDOOR_FLAG_OPEN : 0); diff --git a/src/block/Tripwire.php b/src/block/Tripwire.php index bdb0ee8e94..ef42dbc673 100644 --- a/src/block/Tripwire.php +++ b/src/block/Tripwire.php @@ -25,14 +25,10 @@ namespace pocketmine\block; class Tripwire extends Flowable{ - /** @var bool */ - protected $triggered = false; - /** @var bool */ - protected $suspended = false; //unclear usage, makes hitbox bigger if set - /** @var bool */ - protected $connected = false; - /** @var bool */ - protected $disarmed = false; + protected bool $triggered = false; + protected bool $suspended = false; //unclear usage, makes hitbox bigger if set + protected bool $connected = false; + protected bool $disarmed = false; protected function writeStateToMeta() : int{ return ($this->triggered ? BlockLegacyMetadata::TRIPWIRE_FLAG_TRIGGERED : 0) | diff --git a/src/block/TripwireHook.php b/src/block/TripwireHook.php index dbdfebe7b5..a6f01fc9c6 100644 --- a/src/block/TripwireHook.php +++ b/src/block/TripwireHook.php @@ -35,10 +35,8 @@ use pocketmine\world\BlockTransaction; class TripwireHook extends Flowable{ use HorizontalFacingTrait; - /** @var bool */ - protected $connected = false; - /** @var bool */ - protected $powered = false; + protected bool $connected = false; + protected bool $powered = false; protected function writeStateToMeta() : int{ return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) | diff --git a/src/block/Vine.php b/src/block/Vine.php index c67353c5a3..84b42e7cbc 100644 --- a/src/block/Vine.php +++ b/src/block/Vine.php @@ -36,7 +36,7 @@ use function count; class Vine extends Flowable{ /** @var int[] */ - protected $faces = []; + protected array $faces = []; protected function writeStateToMeta() : int{ return diff --git a/src/block/Wall.php b/src/block/Wall.php index daa67813a8..5a1323d14c 100644 --- a/src/block/Wall.php +++ b/src/block/Wall.php @@ -29,9 +29,8 @@ use pocketmine\math\Facing; class Wall extends Transparent{ /** @var int[] facing => facing */ - protected $connections = []; - /** @var bool */ - protected $up = false; + protected array $connections = []; + protected bool $up = false; public function readStateFromWorld() : void{ parent::readStateFromWorld(); diff --git a/src/block/WallCoralFan.php b/src/block/WallCoralFan.php index aee2cb8a0a..a979931135 100644 --- a/src/block/WallCoralFan.php +++ b/src/block/WallCoralFan.php @@ -41,8 +41,7 @@ use pocketmine\world\BlockTransaction; final class WallCoralFan extends BaseCoral{ use HorizontalFacingTrait; - /** @var BlockIdentifierFlattened */ - protected $idInfoFlattened; + protected BlockIdentifierFlattened $idInfoFlattened; public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){ $this->idInfoFlattened = $idInfo; diff --git a/src/block/Wood.php b/src/block/Wood.php index 59aab1683a..f6d1c30fd9 100644 --- a/src/block/Wood.php +++ b/src/block/Wood.php @@ -30,8 +30,7 @@ use pocketmine\player\Player; class Wood extends Opaque{ - /** @var TreeType */ - private $treeType; + private TreeType $treeType; private bool $stripped; From 8171b18002bf88923ec58eb55dfa48b714e4988d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 29 May 2021 14:24:05 +0100 Subject: [PATCH 2507/3224] Separate ItemTypeDictionary implementation from initialization we're not going to want implementation details like how it's setup getting in the way when we separate protocol from the core. --- .../mcpe/convert/GlobalItemTypeDictionary.php | 65 +++++++++++++++++++ src/network/mcpe/convert/ItemTranslator.php | 3 +- src/network/mcpe/convert/TypeConverter.php | 2 +- .../mcpe/handler/PreSpawnPacketHandler.php | 4 +- .../serializer}/ItemTypeDictionary.php | 35 ++-------- .../protocol/serializer/PacketSerializer.php | 4 +- 6 files changed, 76 insertions(+), 37 deletions(-) create mode 100644 src/network/mcpe/convert/GlobalItemTypeDictionary.php rename src/network/mcpe/{convert => protocol/serializer}/ItemTypeDictionary.php (63%) diff --git a/src/network/mcpe/convert/GlobalItemTypeDictionary.php b/src/network/mcpe/convert/GlobalItemTypeDictionary.php new file mode 100644 index 0000000000..349ddc3bba --- /dev/null +++ b/src/network/mcpe/convert/GlobalItemTypeDictionary.php @@ -0,0 +1,65 @@ + $entry){ + if(!is_array($entry) || !is_string($name) || !isset($entry["component_based"], $entry["runtime_id"]) || !is_bool($entry["component_based"]) || !is_int($entry["runtime_id"])){ + throw new AssumptionFailedError("Invalid item list format"); + } + $params[] = new ItemTypeEntry($name, $entry["runtime_id"], $entry["component_based"]); + } + return new self(new ItemTypeDictionary($params)); + } + + private ItemTypeDictionary $dictionary; + + public function __construct(ItemTypeDictionary $dictionary){ + $this->dictionary = $dictionary; + } + + public function getDictionary() : ItemTypeDictionary{ return $this->dictionary; } +} diff --git a/src/network/mcpe/convert/ItemTranslator.php b/src/network/mcpe/convert/ItemTranslator.php index 530f4af4c2..f1d2a3ebd3 100644 --- a/src/network/mcpe/convert/ItemTranslator.php +++ b/src/network/mcpe/convert/ItemTranslator.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\convert; +use pocketmine\network\mcpe\protocol\serializer\ItemTypeDictionary; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\SingletonTrait; use function array_key_exists; @@ -108,7 +109,7 @@ final class ItemTranslator{ } } - return new self(ItemTypeDictionary::getInstance(), $simpleMappings, $complexMappings); + return new self(GlobalItemTypeDictionary::getInstance()->getDictionary(), $simpleMappings, $complexMappings); } /** diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index 5ac4c0b0df..a1adb20e69 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -63,7 +63,7 @@ class TypeConverter{ public function __construct(){ //TODO: inject stuff via constructor - $this->shieldRuntimeId = ItemTypeDictionary::getInstance()->fromStringId("minecraft:shield"); + $this->shieldRuntimeId = GlobalItemTypeDictionary::getInstance()->getDictionary()->fromStringId("minecraft:shield"); } /** diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index 4d1b991cf8..a52f86e738 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\handler; use pocketmine\network\mcpe\cache\CraftingDataCache; use pocketmine\network\mcpe\cache\StaticPacketCache; -use pocketmine\network\mcpe\convert\ItemTypeDictionary; +use pocketmine\network\mcpe\convert\GlobalItemTypeDictionary; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; @@ -87,7 +87,7 @@ class PreSpawnPacketHandler extends PacketHandler{ $pk->experiments = new Experiments([], false); $pk->levelId = ""; $pk->worldName = $this->server->getMotd(); - $pk->itemTable = ItemTypeDictionary::getInstance()->getEntries(); //TODO: check if this is actually needed + $pk->itemTable = GlobalItemTypeDictionary::getInstance()->getDictionary()->getEntries(); //TODO: check if this is actually needed $pk->playerMovementSettings = new PlayerMovementSettings(PlayerMovementType::LEGACY, 0, false); $this->session->sendDataPacket($pk); diff --git a/src/network/mcpe/convert/ItemTypeDictionary.php b/src/network/mcpe/protocol/serializer/ItemTypeDictionary.php similarity index 63% rename from src/network/mcpe/convert/ItemTypeDictionary.php rename to src/network/mcpe/protocol/serializer/ItemTypeDictionary.php index b23983dc47..bdb166589b 100644 --- a/src/network/mcpe/convert/ItemTypeDictionary.php +++ b/src/network/mcpe/protocol/serializer/ItemTypeDictionary.php @@ -21,55 +21,28 @@ declare(strict_types=1); -namespace pocketmine\network\mcpe\convert; +namespace pocketmine\network\mcpe\protocol\serializer; use pocketmine\network\mcpe\protocol\types\ItemTypeEntry; -use pocketmine\utils\AssumptionFailedError; -use pocketmine\utils\SingletonTrait; use function array_key_exists; -use function file_get_contents; -use function is_array; -use function is_bool; -use function is_int; -use function is_string; -use function json_decode; final class ItemTypeDictionary{ - use SingletonTrait; /** * @var ItemTypeEntry[] * @phpstan-var list */ - private $itemTypes; + private array $itemTypes; /** * @var string[] * @phpstan-var array */ - private $intToStringIdMap = []; + private array $intToStringIdMap = []; /** * @var int[] * @phpstan-var array */ - private $stringToIntMap = []; - - private static function make() : self{ - $data = file_get_contents(\pocketmine\RESOURCE_PATH . '/vanilla/required_item_list.json'); - if($data === false) throw new AssumptionFailedError("Missing required resource file"); - $table = json_decode($data, true); - if(!is_array($table)){ - throw new AssumptionFailedError("Invalid item list format"); - } - - $params = []; - foreach($table as $name => $entry){ - if(!is_array($entry) || !is_string($name) || !isset($entry["component_based"], $entry["runtime_id"]) || !is_bool($entry["component_based"]) || !is_int($entry["runtime_id"])){ - throw new AssumptionFailedError("Invalid item list format"); - } - $params[] = new ItemTypeEntry($name, $entry["runtime_id"], $entry["component_based"]); - } - return new self($params); - } + private array $stringToIntMap = []; /** * @param ItemTypeEntry[] $itemTypes diff --git a/src/network/mcpe/protocol/serializer/PacketSerializer.php b/src/network/mcpe/protocol/serializer/PacketSerializer.php index e569599c1b..29a70c0b39 100644 --- a/src/network/mcpe/protocol/serializer/PacketSerializer.php +++ b/src/network/mcpe/protocol/serializer/PacketSerializer.php @@ -30,7 +30,7 @@ use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; -use pocketmine\network\mcpe\convert\ItemTypeDictionary; +use pocketmine\network\mcpe\convert\GlobalItemTypeDictionary; use pocketmine\network\mcpe\protocol\PacketDecodeException; use pocketmine\network\mcpe\protocol\types\BoolGameRule; use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; @@ -73,7 +73,7 @@ class PacketSerializer extends BinaryStream{ public function __construct(string $buffer = "", int $offset = 0){ parent::__construct($buffer, $offset); - $this->shieldItemRuntimeId = ItemTypeDictionary::getInstance()->fromStringId("minecraft:shield"); + $this->shieldItemRuntimeId = GlobalItemTypeDictionary::getInstance()->getDictionary()->fromStringId("minecraft:shield"); } /** From 4bcc7e09cbb76f26a30e9bc523463890699fff29 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 29 May 2021 14:24:48 +0100 Subject: [PATCH 2508/3224] PacketSerializer: fix unnecessary FQN --- src/network/mcpe/protocol/serializer/PacketSerializer.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/mcpe/protocol/serializer/PacketSerializer.php b/src/network/mcpe/protocol/serializer/PacketSerializer.php index 29a70c0b39..c2b649060f 100644 --- a/src/network/mcpe/protocol/serializer/PacketSerializer.php +++ b/src/network/mcpe/protocol/serializer/PacketSerializer.php @@ -61,6 +61,7 @@ use pocketmine\network\mcpe\protocol\types\StructureEditorData; use pocketmine\network\mcpe\protocol\types\StructureSettings; use pocketmine\utils\BinaryDataException; use pocketmine\utils\BinaryStream; +use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; use function count; use function strlen; @@ -95,7 +96,7 @@ class PacketSerializer extends BinaryStream{ //This is two little-endian longs: bytes 7-0 followed by bytes 15-8 $p1 = strrev($this->get(8)); $p2 = strrev($this->get(8)); - return \Ramsey\Uuid\Uuid::fromBytes($p1 . $p2); + return Uuid::fromBytes($p1 . $p2); } public function putUUID(UuidInterface $uuid) : void{ From 0402e7e6977989608b4bdd0a843a571cb99a9284 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 29 May 2021 23:41:11 +0100 Subject: [PATCH 2509/3224] Separate CommandReader impl from CommandReaderThread --- src/Server.php | 15 ++- src/command/CommandReader.php | 125 +++--------------- src/command/CommandReaderThread.php | 82 ++++++++++++ tests/phpstan/configs/actual-problems.neon | 2 +- .../check-explicit-mixed-baseline.neon | 7 +- tests/phpstan/configs/l7-baseline.neon | 12 +- 6 files changed, 110 insertions(+), 133 deletions(-) create mode 100644 src/command/CommandReaderThread.php diff --git a/src/Server.php b/src/Server.php index f3f1e4e6ad..702739dc51 100644 --- a/src/Server.php +++ b/src/Server.php @@ -28,7 +28,7 @@ declare(strict_types=1); namespace pocketmine; use pocketmine\command\Command; -use pocketmine\command\CommandReader; +use pocketmine\command\CommandReaderThread; use pocketmine\command\CommandSender; use pocketmine\command\ConsoleCommandSender; use pocketmine\command\SimpleCommandMap; @@ -227,7 +227,7 @@ class Server{ /** @var MemoryManager */ private $memoryManager; - /** @var CommandReader */ + /** @var CommandReaderThread */ private $console; /** @var SimpleCommandMap */ @@ -1133,11 +1133,12 @@ class Server{ $this->subscribeToBroadcastChannel(self::BROADCAST_CHANNEL_USERS, $consoleSender); $consoleNotifier = new SleeperNotifier(); - $this->console = new CommandReader($consoleNotifier); - $this->tickSleeper->addNotifier($consoleNotifier, function() use ($consoleSender) : void{ + $commandBuffer = new \Threaded(); + $this->console = new CommandReaderThread($commandBuffer, $consoleNotifier); + $this->tickSleeper->addNotifier($consoleNotifier, function() use ($commandBuffer, $consoleSender) : void{ Timings::$serverCommand->startTiming(); - while(($line = $this->console->getLine()) !== null){ - $this->dispatchCommand($consoleSender, $line); + while(($line = $commandBuffer->shift()) !== null){ + $this->dispatchCommand($consoleSender, (string) $line); } Timings::$serverCommand->stopTiming(); }); @@ -1422,7 +1423,7 @@ class Server{ $this->configGroup->save(); } - if($this->console instanceof CommandReader){ + if($this->console instanceof CommandReaderThread){ $this->getLogger()->debug("Closing console"); $this->console->shutdown(); $this->console->notify(); diff --git a/src/command/CommandReader.php b/src/command/CommandReader.php index ac74145ecb..0aeefdf2b1 100644 --- a/src/command/CommandReader.php +++ b/src/command/CommandReader.php @@ -23,149 +23,58 @@ declare(strict_types=1); namespace pocketmine\command; -use pocketmine\snooze\SleeperNotifier; -use pocketmine\thread\Thread; -use pocketmine\thread\ThreadException; use function fclose; use function fgets; use function fopen; -use function fstat; use function is_resource; -use function microtime; -use function preg_replace; -use function readline; -use function stream_isatty; use function stream_select; use function trim; use function usleep; -class CommandReader extends Thread{ - - public const TYPE_READLINE = 0; - public const TYPE_STREAM = 1; - public const TYPE_PIPED = 2; - +final class CommandReader{ /** @var resource */ - private static $stdin; + private $stdin; - /** @var \Threaded */ - protected $buffer; - /** @var bool */ - private $shutdown = false; - /** @var int */ - private $type = self::TYPE_STREAM; - - /** @var SleeperNotifier|null */ - private $notifier; - - public function __construct(?SleeperNotifier $notifier = null){ - $this->buffer = new \Threaded; - $this->notifier = $notifier; - } - - public function shutdown() : void{ - $this->shutdown = true; - } - - public function quit() : void{ - $wait = microtime(true) + 0.5; - while(microtime(true) < $wait){ - if($this->isRunning()){ - usleep(100000); - }else{ - parent::quit(); - return; - } - } - - $message = "Thread blocked for unknown reason"; - if($this->type === self::TYPE_PIPED){ - $message = "STDIN is being piped from another location and the pipe is blocked, cannot stop safely"; - } - - throw new ThreadException($message); + public function __construct(){ + $this->initStdin(); } private function initStdin() : void{ - if(is_resource(self::$stdin)){ - fclose(self::$stdin); + if(is_resource($this->stdin)){ + fclose($this->stdin); } - self::$stdin = fopen("php://stdin", "r"); - if($this->isPipe(self::$stdin)){ - $this->type = self::TYPE_PIPED; - }else{ - $this->type = self::TYPE_STREAM; - } - } - - /** - * Checks if the specified stream is a FIFO pipe. - * - * @param resource $stream - */ - private function isPipe($stream) : bool{ - return is_resource($stream) and (!stream_isatty($stream) or ((fstat($stream)["mode"] & 0170000) === 0010000)); + $this->stdin = fopen("php://stdin", "r"); } /** * Reads a line from the console and adds it to the buffer. This method may block the thread. - * - * @return bool if the main execution should continue reading lines */ - private function readLine() : bool{ - if(!is_resource(self::$stdin)){ + public function readLine() : ?string{ + if(!is_resource($this->stdin)){ $this->initStdin(); } - $r = [self::$stdin]; + $r = [$this->stdin]; $w = $e = null; if(($count = stream_select($r, $w, $e, 0, 200000)) === 0){ //nothing changed in 200000 microseconds - return true; + return null; }elseif($count === false){ //stream error $this->initStdin(); } - if(($raw = fgets(self::$stdin)) === false){ //broken pipe or EOF + if(($raw = fgets($this->stdin)) === false){ //broken pipe or EOF $this->initStdin(); - $this->synchronized(function() : void{ - $this->wait(200000); - }); //prevent CPU waste if it's end of pipe - return true; //loop back round + usleep(200000); //prevent CPU waste if it's end of pipe + return null; //loop back round } $line = trim($raw); - if($line !== ""){ - $this->buffer[] = preg_replace("#\\x1b\\x5b([^\\x1b]*\\x7e|[\\x40-\\x50])#", "", $line); - if($this->notifier !== null){ - $this->notifier->wakeupSleeper(); - } - } - - return true; + return $line !== "" ? $line : null; } - /** - * Reads a line from console, if available. Returns null if not available - */ - public function getLine() : ?string{ - if($this->buffer->count() !== 0){ - return (string) $this->buffer->shift(); - } - - return null; - } - - protected function onRun() : void{ - $this->initStdin(); - - while(!$this->shutdown and $this->readLine()); - - fclose(self::$stdin); - } - - public function getThreadName() : string{ - return "Console"; + public function __destruct(){ + fclose($this->stdin); } } diff --git a/src/command/CommandReaderThread.php b/src/command/CommandReaderThread.php new file mode 100644 index 0000000000..5ae04a1c57 --- /dev/null +++ b/src/command/CommandReaderThread.php @@ -0,0 +1,82 @@ +buffer = $buffer; + $this->notifier = $notifier; + } + + public function shutdown() : void{ + $this->shutdown = true; + } + + public function quit() : void{ + $wait = microtime(true) + 0.5; + while(microtime(true) < $wait){ + if($this->isRunning()){ + usleep(100000); + }else{ + parent::quit(); + return; + } + } + + throw new ThreadException("CommandReader is stuck in a blocking STDIN read"); + } + + protected function onRun() : void{ + $buffer = $this->buffer; + $notifier = $this->notifier; + + $reader = new CommandReader(); + while(!$this->shutdown){ + $line = $reader->readLine(); + + if($line !== null){ + $buffer[] = preg_replace("#\\x1b\\x5b([^\\x1b]*\\x7e|[\\x40-\\x50])#", "", $line); + if($notifier !== null){ + $notifier->wakeupSleeper(); + } + } + } + } + + public function getThreadName() : string{ + return "Console"; + } +} diff --git a/tests/phpstan/configs/actual-problems.neon b/tests/phpstan/configs/actual-problems.neon index 21c05e8af9..49b2c5f07e 100644 --- a/tests/phpstan/configs/actual-problems.neon +++ b/tests/phpstan/configs/actual-problems.neon @@ -6,7 +6,7 @@ parameters: path: ../../../src/CrashDump.php - - message: "#^Instanceof between pocketmine\\\\command\\\\CommandReader and pocketmine\\\\command\\\\CommandReader will always evaluate to true\\.$#" + message: "#^Instanceof between pocketmine\\\\command\\\\CommandReaderThread and pocketmine\\\\command\\\\CommandReaderThread will always evaluate to true\\.$#" count: 1 path: ../../../src/Server.php diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index d746d6d604..a26af95067 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -37,7 +37,7 @@ parameters: - message: "#^Cannot cast mixed to string\\.$#" - count: 1 + count: 2 path: ../../../src/Server.php - @@ -80,11 +80,6 @@ parameters: count: 2 path: ../../../src/VersionInfo.php - - - message: "#^Cannot cast mixed to string\\.$#" - count: 1 - path: ../../../src/command/CommandReader.php - - message: "#^Part \\$host \\(mixed\\) of encapsed string cannot be cast to string\\.$#" count: 1 diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index 496df83119..f3d116666e 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -436,17 +436,7 @@ parameters: path: ../../../src/block/tile/TileFactory.php - - message: "#^Cannot access offset 'mode' on array\\(0 \\=\\> int, 1 \\=\\> int, 2 \\=\\> int, 3 \\=\\> int, 4 \\=\\> int, 5 \\=\\> int, 6 \\=\\> int, 7 \\=\\> int, \\.\\.\\.\\)\\|false\\.$#" - count: 1 - path: ../../../src/command/CommandReader.php - - - - message: "#^Parameter \\#1 \\$stream of method pocketmine\\\\command\\\\CommandReader\\:\\:isPipe\\(\\) expects resource, resource\\|false given\\.$#" - count: 1 - path: ../../../src/command/CommandReader.php - - - - message: "#^Static property pocketmine\\\\command\\\\CommandReader\\:\\:\\$stdin \\(resource\\) does not accept resource\\|false\\.$#" + message: "#^Property pocketmine\\\\command\\\\CommandReader\\:\\:\\$stdin \\(resource\\) does not accept resource\\|false\\.$#" count: 1 path: ../../../src/command/CommandReader.php From 7d99b0115ced7f1b735c4837c8342029db1b3f5b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 29 May 2021 23:51:46 +0100 Subject: [PATCH 2510/3224] Added a getName() override for RakLibServer --- src/network/mcpe/raklib/RakLibServer.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/network/mcpe/raklib/RakLibServer.php b/src/network/mcpe/raklib/RakLibServer.php index 05898e5675..e7f27c6ccb 100644 --- a/src/network/mcpe/raklib/RakLibServer.php +++ b/src/network/mcpe/raklib/RakLibServer.php @@ -171,4 +171,7 @@ class RakLibServer extends Thread{ } } + public function getThreadName() : string{ + return "RakLib"; + } } From 493977661fdc0c552660885257fa4ff771f04715 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 30 May 2021 20:46:39 +0100 Subject: [PATCH 2511/3224] Require pocketmine/binaryutils ^0.2.1 --- composer.json | 2 +- composer.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index ab9a0ff5df..7166c3e3bd 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "adhocore/json-comment": "^1.1", "mdanter/ecc": "^1.0", "netresearch/jsonmapper": "^4.0", - "pocketmine/binaryutils": "^0.2.0", + "pocketmine/binaryutils": "^0.2.1", "pocketmine/callback-validator": "^1.0.2", "pocketmine/classloader": "dev-master", "pocketmine/color": "^0.2.0", diff --git a/composer.lock b/composer.lock index 730468fae6..7940dfa2ef 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7e519325ae271d7d2c56a481a64b8d44", + "content-hash": "59dbdc116eef096a5499b4c2b7082fb1", "packages": [ { "name": "adhocore/json-comment", @@ -321,16 +321,16 @@ }, { "name": "pocketmine/binaryutils", - "version": "0.2.0", + "version": "0.2.1", "source": { "type": "git", "url": "https://github.com/pmmp/BinaryUtils.git", - "reference": "595c4ca4b8056777729c8cc5db9614c731eaf63b" + "reference": "8cd078e2426f8100331f2d73bef10f481dad6cde" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/595c4ca4b8056777729c8cc5db9614c731eaf63b", - "reference": "595c4ca4b8056777729c8cc5db9614c731eaf63b", + "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/8cd078e2426f8100331f2d73bef10f481dad6cde", + "reference": "8cd078e2426f8100331f2d73bef10f481dad6cde", "shasum": "" }, "require": { @@ -355,9 +355,9 @@ "description": "Classes and methods for conveniently handling binary data", "support": { "issues": "https://github.com/pmmp/BinaryUtils/issues", - "source": "https://github.com/pmmp/BinaryUtils/tree/0.2.0" + "source": "https://github.com/pmmp/BinaryUtils/tree/0.2.1" }, - "time": "2021-05-18T15:23:45+00:00" + "time": "2021-05-30T19:42:57+00:00" }, { "name": "pocketmine/callback-validator", From fadc96bb0e2b74269b3546ed14e05b18c78f7437 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 2 Jun 2021 21:34:19 +0100 Subject: [PATCH 2512/3224] Utils: include spl_object_id() in stack traces --- src/utils/Utils.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils/Utils.php b/src/utils/Utils.php index af4d222482..58c4fade67 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -64,6 +64,7 @@ use function preg_grep; use function preg_match; use function preg_match_all; use function preg_replace; +use function spl_object_id; use function str_pad; use function str_split; use function stripos; @@ -412,7 +413,7 @@ final class Utils{ $params = implode(", ", array_map(function($value) use($maxStringLength) : string{ if(is_object($value)){ - return "object " . self::getNiceClassName($value); + return "object " . self::getNiceClassName($value) . "#" . spl_object_id($value); } if(is_array($value)){ return "array[" . count($value) . "]"; From 9702b51bd19e3f386f68e51146d85713a207c1e4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 2 Jun 2021 21:36:47 +0100 Subject: [PATCH 2513/3224] Utils: improve how boolean arguments are displayed in stack traces --- src/utils/Utils.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/utils/Utils.php b/src/utils/Utils.php index 58c4fade67..26081a5ded 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -51,6 +51,7 @@ use function getenv; use function gettype; use function implode; use function is_array; +use function is_bool; use function is_object; use function is_string; use function mb_check_encoding; @@ -421,6 +422,9 @@ final class Utils{ if(is_string($value)){ return "string[" . strlen($value) . "] " . substr(Utils::printable($value), 0, $maxStringLength); } + if(is_bool($value)){ + return $value ? "true" : "false"; + } return gettype($value) . " " . Utils::printable((string) $value); }, $args)); } From 2fff3fa60cbf709057057fd22e447a6929b92e3b Mon Sep 17 00:00:00 2001 From: Dylan T Date: Wed, 9 Jun 2021 13:16:57 +0100 Subject: [PATCH 2514/3224] changelog: be more specific about the range of Bedrock worlds supported this was written 2 years ago, before 1.13 was released to disrupt everything all over again. [ci skip] --- changelogs/4.0-snapshot.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 19a40950f4..821269fb28 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -94,7 +94,7 @@ This major version features substantial changes throughout the core, including s - Progress of spawn terrain chunk generation is now logged during initial world creation. #### Functional -- Modern Minecraft Bedrock world formats are now supported. +- Minecraft Bedrock worlds up to 1.12.x are now supported. (1.13+ are still **not supported** due to yet another format change, which is large and requires a lot of work). - Automatic conversion of deprecated world formats is now implemented. - All formats except `leveldb` have been deprecated. The following world formats will be **automatically converted on load to a new format**: - `mcregion` From 38a32c6540a419370130982b699556bfa47590f4 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Wed, 9 Jun 2021 13:19:40 +0100 Subject: [PATCH 2515/3224] changelog: remove mentions of unsupported / corrupted world handling the fixes for these problems were backported to PM3 during the PHPStan integration. [ci skip] --- changelogs/4.0-snapshot.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 821269fb28..19dc5f6471 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -102,8 +102,6 @@ This major version features substantial changes throughout the core, including s - `pmanvil` - 256 build-height is now supported in all worlds (facilitated by automatic conversion). - Extended blocks are now supported (facilitated by automatic conversion). -- Unsupported world formats no longer causes a crash, but a graceful shutdown instead. -- World corruption no longer causes a crash, but a graceful shutdown instead. - Lighting is no longer stored or loaded from disk - instead, it's calculated on the fly as-needed. This fixes many long-standing bugs. #### Performance From 532d57eec72e8677a99f3a064737391c8aefd145 Mon Sep 17 00:00:00 2001 From: Jason Date: Wed, 9 Jun 2021 09:00:36 -0400 Subject: [PATCH 2516/3224] Arrow: Save and load critical state (#4241) Fixes #3596 --- src/entity/EntityFactory.php | 2 +- src/entity/projectile/Arrow.php | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index a7c9c1c0fb..d33dc442d1 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -77,7 +77,7 @@ final class EntityFactory{ //TODO: index them by version to allow proper multi-save compatibility $this->register(Arrow::class, function(World $world, CompoundTag $nbt) : Arrow{ - return new Arrow(EntityDataHelper::parseLocation($nbt, $world), null, false, $nbt); //TODO: missing critical flag + return new Arrow(EntityDataHelper::parseLocation($nbt, $world), null, $nbt->getByte(Arrow::TAG_CRIT, 0) === 1, $nbt); }, ['Arrow', 'minecraft:arrow'], EntityLegacyIds::ARROW); $this->register(Egg::class, function(World $world, CompoundTag $nbt) : Egg{ diff --git a/src/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php index d296b4092d..f0a1181fd8 100644 --- a/src/entity/projectile/Arrow.php +++ b/src/entity/projectile/Arrow.php @@ -50,6 +50,7 @@ class Arrow extends Projectile{ public const PICKUP_CREATIVE = 2; private const TAG_PICKUP = "pickup"; //TAG_Byte + public const TAG_CRIT = "crit"; //TAG_Byte protected $gravity = 0.05; protected $drag = 0.01; @@ -80,12 +81,14 @@ class Arrow extends Projectile{ parent::initEntity($nbt); $this->pickupMode = $nbt->getByte(self::TAG_PICKUP, self::PICKUP_ANY); + $this->critical = $nbt->getByte(self::TAG_CRIT, 0) === 1; $this->collideTicks = $nbt->getShort("life", $this->collideTicks); } public function saveNBT() : CompoundTag{ $nbt = parent::saveNBT(); $nbt->setByte(self::TAG_PICKUP, $this->pickupMode); + $nbt->setByte(self::TAG_CRIT, $this->critical ? 1 : 0); $nbt->setShort("life", $this->collideTicks); return $nbt; } From f245147c11917c47feafddc4aaf953a69e9347f1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 11 Jun 2021 18:27:43 +0100 Subject: [PATCH 2517/3224] AsyncPool: make collectTasks() return value more accurate during onCompletion() anything may happen, including scheduling new tasks, which the previous code did not account for. --- src/scheduler/AsyncPool.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/scheduler/AsyncPool.php b/src/scheduler/AsyncPool.php index bf5ecbbf75..d937a8c088 100644 --- a/src/scheduler/AsyncPool.php +++ b/src/scheduler/AsyncPool.php @@ -233,11 +233,17 @@ class AsyncPool{ * @return bool whether there are tasks left to be collected */ public function collectTasks() : bool{ - $more = false; foreach($this->taskQueues as $worker => $queue){ - $more = $this->collectTasksFromWorker($worker) || $more; + $this->collectTasksFromWorker($worker); } - return $more; + + //we check this in a second loop, because task collection could have caused new tasks to be added to the queues + foreach($this->taskQueues as $queue){ + if(!$queue->isEmpty()){ + return true; + } + } + return false; } public function collectTasksFromWorker(int $worker) : bool{ From 22b5e5db5e822ac94ed3978ea75bbadcfa8e7f4f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 11 Jun 2021 18:30:00 +0100 Subject: [PATCH 2518/3224] AsyncPool: Do not drop pending tasks on shutdown this creates an extra element of uncertainty for async pool usage. --- src/scheduler/AsyncPool.php | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/scheduler/AsyncPool.php b/src/scheduler/AsyncPool.php index d937a8c088..753e7e5a69 100644 --- a/src/scheduler/AsyncPool.php +++ b/src/scheduler/AsyncPool.php @@ -313,20 +313,8 @@ class AsyncPool{ * Cancels all pending tasks and shuts down all the workers in the pool. */ public function shutdown() : void{ - $this->collectTasks(); - - foreach($this->workers as $worker){ - /** @var AsyncTask $task */ - while(($task = $worker->unstack()) !== null){ - //NOOP: the below loop will deal with marking tasks as garbage - } - } - foreach($this->taskQueues as $queue){ - while(!$queue->isEmpty()){ - /** @var AsyncTask $task */ - $task = $queue->dequeue(); - $task->cancelRun(); - } + while($this->collectTasks()){ + //NOOP } foreach($this->workers as $worker){ From e4ed7bc4ea75a3142f000d532b8c4d4ef0a7985c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 11 Jun 2021 19:04:12 +0100 Subject: [PATCH 2519/3224] Fixed Mushroom Stem blocks never dropping anything --- src/block/MushroomStem.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/MushroomStem.php b/src/block/MushroomStem.php index 0544a38d80..5e61a5b1c8 100644 --- a/src/block/MushroomStem.php +++ b/src/block/MushroomStem.php @@ -27,7 +27,7 @@ use pocketmine\item\Item; final class MushroomStem extends Opaque{ - public function getDrops(Item $item) : array{ return []; } + public function getDropsForCompatibleTool(Item $item) : array{ return []; } public function isAffectedBySilkTouch() : bool{ return true; } } From 7dcc4891ca2d841aaa9bb757308a9f1a2940e147 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 11 Jun 2021 19:09:14 +0100 Subject: [PATCH 2520/3224] Block: added getDropsForIncompatibleTool() --- src/block/Block.php | 9 +++++++++ src/block/DeadBush.php | 12 ++++-------- src/block/DoubleTallGrass.php | 10 ++++------ src/block/TallGrass.php | 6 +----- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/block/Block.php b/src/block/Block.php index 1dceaf22de..0657c94b36 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -369,6 +369,15 @@ class Block{ return [$this->asItem()]; } + /** + * Returns the items dropped by this block when broken with an incorrect tool type (or tool with a too-low tier). + * + * @return Item[] + */ + public function getDropsForIncompatibleTool(Item $item) : array{ + return []; + } + /** * Returns an array of Items to be dropped when the block is broken using a compatible Silk Touch-enchanted tool. * diff --git a/src/block/DeadBush.php b/src/block/DeadBush.php index 3f6f4d8a76..7d7a933bc6 100644 --- a/src/block/DeadBush.php +++ b/src/block/DeadBush.php @@ -47,14 +47,10 @@ class DeadBush extends Flowable{ } } - public function getDrops(Item $item) : array{ - if(!$this->breakInfo->isToolCompatible($item)){ - return [ - VanillaItems::STICK()->setCount(mt_rand(0, 2)) - ]; - } - - return parent::getDrops($item); + public function getDropsForIncompatibleTool(Item $item) : array{ + return [ + VanillaItems::STICK()->setCount(mt_rand(0, 2)) + ]; } public function isAffectedBySilkTouch() : bool{ diff --git a/src/block/DoubleTallGrass.php b/src/block/DoubleTallGrass.php index 7c6769800c..6fee40e329 100644 --- a/src/block/DoubleTallGrass.php +++ b/src/block/DoubleTallGrass.php @@ -33,12 +33,10 @@ class DoubleTallGrass extends DoublePlant{ return true; } - public function getDrops(Item $item) : array{ - if($this->top and !$this->breakInfo->isToolCompatible($item) and mt_rand(0, 7) === 0){ - return [ - VanillaItems::WHEAT_SEEDS() - ]; + public function getDropsForIncompatibleTool(Item $item) : array{ + if($this->top and mt_rand(0, 7) === 0){ + return [VanillaItems::WHEAT_SEEDS()]; } - return parent::getDrops($item); + return []; } } diff --git a/src/block/TallGrass.php b/src/block/TallGrass.php index fd23ec7204..6140a855c8 100644 --- a/src/block/TallGrass.php +++ b/src/block/TallGrass.php @@ -52,11 +52,7 @@ class TallGrass extends Flowable{ } } - public function getDrops(Item $item) : array{ - if($this->breakInfo->isToolCompatible($item)){ - return parent::getDrops($item); - } - + public function getDropsForIncompatibleTool(Item $item) : array{ if(mt_rand(0, 15) === 0){ return [ VanillaItems::WHEAT_SEEDS() From 0ebafbd2247c831cdc3ee54a62260ff0c4a3e9de Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 12 Jun 2021 20:46:53 +0100 Subject: [PATCH 2521/3224] .... adding the most important part would probably help --- src/block/Block.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/Block.php b/src/block/Block.php index 0657c94b36..16056eb584 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -357,7 +357,7 @@ class Block{ return $this->getDropsForCompatibleTool($item); } - return []; + return $this->getDropsForIncompatibleTool($item); } /** From bfcf4a25d4796b7deca0c9898232d9c549470ec1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 12 Jun 2021 21:12:39 +0100 Subject: [PATCH 2522/3224] Automatic cleanup of permission subscriptions on PermissibleBase destructor calls this has gotten too complex ... --- src/command/ConsoleCommandSender.php | 5 - src/permission/PermissibleBase.php | 194 +--------------- src/permission/PermissibleDelegateTrait.php | 2 +- src/permission/PermissibleInternal.php | 233 ++++++++++++++++++++ src/player/Player.php | 2 - 5 files changed, 242 insertions(+), 194 deletions(-) create mode 100644 src/permission/PermissibleInternal.php diff --git a/src/command/ConsoleCommandSender.php b/src/command/ConsoleCommandSender.php index e94d8483e9..5649f9f4c9 100644 --- a/src/command/ConsoleCommandSender.php +++ b/src/command/ConsoleCommandSender.php @@ -87,9 +87,4 @@ class ConsoleCommandSender implements CommandSender{ } $this->lineHeight = $height; } - - public function __destruct(){ - //permission subscriptions need to be cleaned up explicitly - $this->perm->destroyCycles(); - } } diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index 87a6ca04c6..96e32a95f8 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -24,202 +24,24 @@ declare(strict_types=1); namespace pocketmine\permission; use pocketmine\plugin\Plugin; -use pocketmine\plugin\PluginException; -use pocketmine\timings\Timings; use pocketmine\utils\ObjectSet; -use function count; -use function spl_object_id; -class PermissibleBase implements Permissible{ - /** - * @var bool[] - * @phpstan-var array - */ - private $rootPermissions; +final class PermissibleBase implements Permissible{ + use PermissibleDelegateTrait; - /** @var PermissionAttachment[] */ - private $attachments = []; - - /** @var PermissionAttachmentInfo[] */ - private $permissions = []; - - /** - * @var ObjectSet|\Closure[] - * @phpstan-var ObjectSet<\Closure(array $changedPermissionsOldValues) : void> - */ - private $permissionRecalculationCallbacks; + private PermissibleInternal $permissibleBase; /** * @param bool[] $basePermissions * @phpstan-param array $basePermissions */ public function __construct(array $basePermissions){ - $this->permissionRecalculationCallbacks = new ObjectSet(); - - //TODO: we can't setBasePermission here directly due to bad architecture that causes recalculatePermissions to explode - //so, this hack has to be done here to prevent permission recalculations until it's fixed... - $this->rootPermissions = $basePermissions; - //TODO: permissions need to be recalculated here, or inherited permissions won't work + $this->permissibleBase = new PermissibleInternal($basePermissions); + $this->perm = $this->permissibleBase; } - public function setBasePermission($name, bool $grant) : void{ - if($name instanceof Permission){ - $name = $name->getName(); - } - $this->rootPermissions[$name] = $grant; - $this->recalculatePermissions(); - } - - public function unsetBasePermission($name) : void{ - unset($this->rootPermissions[$name instanceof Permission ? $name->getName() : $name]); - $this->recalculatePermissions(); - } - - /** - * @param Permission|string $name - */ - public function isPermissionSet($name) : bool{ - return isset($this->permissions[$name instanceof Permission ? $name->getName() : $name]); - } - - /** - * @param Permission|string $name - */ - public function hasPermission($name) : bool{ - if($name instanceof Permission){ - $name = $name->getName(); - } - - if($this->isPermissionSet($name)){ - return $this->permissions[$name]->getValue(); - } - - return false; - } - - /** - * //TODO: tick scheduled attachments - */ - public function addAttachment(Plugin $plugin, ?string $name = null, ?bool $value = null) : PermissionAttachment{ - if(!$plugin->isEnabled()){ - throw new PluginException("Plugin " . $plugin->getDescription()->getName() . " is disabled"); - } - - $result = new PermissionAttachment($plugin); - $this->attachments[spl_object_id($result)] = $result; - if($name !== null and $value !== null){ - $result->setPermission($name, $value); - } - - $result->subscribePermissible($this); - - $this->recalculatePermissions(); - - return $result; - } - - public function removeAttachment(PermissionAttachment $attachment) : void{ - if(isset($this->attachments[spl_object_id($attachment)])){ - unset($this->attachments[spl_object_id($attachment)]); - $attachment->unsubscribePermissible($this); - if(($ex = $attachment->getRemovalCallback()) !== null){ - $ex->attachmentRemoved($this, $attachment); - } - - $this->recalculatePermissions(); - - } - - } - - public function recalculatePermissions() : array{ - Timings::$permissibleCalculation->startTiming(); - - $permManager = PermissionManager::getInstance(); - $permManager->unsubscribeFromAllPermissions($this); - $oldPermissions = $this->permissions; - $this->permissions = []; - - foreach($this->rootPermissions as $name => $isGranted){ - $perm = $permManager->getPermission($name); - if($perm === null){ - throw new \InvalidStateException("Unregistered root permission $name"); - } - $this->permissions[$name] = new PermissionAttachmentInfo($name, null, $isGranted, null); - $permManager->subscribeToPermission($name, $this); - $this->calculateChildPermissions($perm->getChildren(), !$isGranted, null, $this->permissions[$name]); - } - - foreach($this->attachments as $attachment){ - $this->calculateChildPermissions($attachment->getPermissions(), false, $attachment, null); - } - - $diff = []; - Timings::$permissibleCalculationDiff->time(function() use ($oldPermissions, &$diff) : void{ - foreach($this->permissions as $permissionAttachmentInfo){ - $name = $permissionAttachmentInfo->getPermission(); - if(!isset($oldPermissions[$name])){ - $diff[$name] = false; - }elseif($oldPermissions[$name]->getValue() !== $permissionAttachmentInfo->getValue()){ - continue; - } - unset($oldPermissions[$name]); - } - //oldPermissions now only contains permissions that changed or are no longer set - foreach($oldPermissions as $permissionAttachmentInfo){ - $diff[$permissionAttachmentInfo->getPermission()] = $permissionAttachmentInfo->getValue(); - } - }); - - Timings::$permissibleCalculationCallback->time(function() use ($diff) : void{ - if(count($diff) > 0){ - foreach($this->permissionRecalculationCallbacks as $closure){ - $closure($diff); - } - } - }); - - Timings::$permissibleCalculation->stopTiming(); - return $diff; - } - - /** - * @param bool[] $children - */ - private function calculateChildPermissions(array $children, bool $invert, ?PermissionAttachment $attachment, ?PermissionAttachmentInfo $parent) : void{ - $permManager = PermissionManager::getInstance(); - foreach($children as $name => $v){ - $perm = $permManager->getPermission($name); - $value = ($v xor $invert); - $this->permissions[$name] = new PermissionAttachmentInfo($name, $attachment, $value, $parent); - $permManager->subscribeToPermission($name, $this); - - if($perm instanceof Permission){ - $this->calculateChildPermissions($perm->getChildren(), !$value, $attachment, $this->permissions[$name]); - } - } - } - - /** - * @return \Closure[]|ObjectSet - * @phpstan-return ObjectSet<\Closure(array $changedPermissionsOldValues) : void> - */ - public function getPermissionRecalculationCallbacks() : ObjectSet{ return $this->permissionRecalculationCallbacks; } - - /** - * @return PermissionAttachmentInfo[] - */ - public function getEffectivePermissions() : array{ - return $this->permissions; - } - - public function destroyCycles() : void{ - PermissionManager::getInstance()->unsubscribeFromAllPermissions($this); - $this->permissions = []; //PermissionAttachmentInfo doesn't reference Permissible anymore, but it references PermissionAttachment which does - foreach($this->attachments as $attachment){ - $attachment->unsubscribePermissible($this); - } - $this->attachments = []; - $this->permissionRecalculationCallbacks->clear(); + public function __destruct(){ + //permission subscriptions need to be cleaned up explicitly + $this->permissibleBase->destroyCycles(); } } diff --git a/src/permission/PermissibleDelegateTrait.php b/src/permission/PermissibleDelegateTrait.php index be3e8da91e..d9de362f23 100644 --- a/src/permission/PermissibleDelegateTrait.php +++ b/src/permission/PermissibleDelegateTrait.php @@ -28,7 +28,7 @@ use pocketmine\utils\ObjectSet; trait PermissibleDelegateTrait{ - /** @var PermissibleBase */ + /** @var Permissible */ private $perm; /** diff --git a/src/permission/PermissibleInternal.php b/src/permission/PermissibleInternal.php new file mode 100644 index 0000000000..2b0bce8dce --- /dev/null +++ b/src/permission/PermissibleInternal.php @@ -0,0 +1,233 @@ + + */ + private $rootPermissions; + + /** @var PermissionAttachment[] */ + private $attachments = []; + + /** @var PermissionAttachmentInfo[] */ + private $permissions = []; + + /** + * @var ObjectSet|\Closure[] + * @phpstan-var ObjectSet<\Closure(array $changedPermissionsOldValues) : void> + */ + private $permissionRecalculationCallbacks; + + /** + * @param bool[] $basePermissions + * @phpstan-param array $basePermissions + */ + public function __construct(array $basePermissions){ + $this->permissionRecalculationCallbacks = new ObjectSet(); + + //TODO: we can't setBasePermission here directly due to bad architecture that causes recalculatePermissions to explode + //so, this hack has to be done here to prevent permission recalculations until it's fixed... + $this->rootPermissions = $basePermissions; + //TODO: permissions need to be recalculated here, or inherited permissions won't work + } + + public function setBasePermission($name, bool $grant) : void{ + if($name instanceof Permission){ + $name = $name->getName(); + } + $this->rootPermissions[$name] = $grant; + $this->recalculatePermissions(); + } + + public function unsetBasePermission($name) : void{ + unset($this->rootPermissions[$name instanceof Permission ? $name->getName() : $name]); + $this->recalculatePermissions(); + } + + /** + * @param Permission|string $name + */ + public function isPermissionSet($name) : bool{ + return isset($this->permissions[$name instanceof Permission ? $name->getName() : $name]); + } + + /** + * @param Permission|string $name + */ + public function hasPermission($name) : bool{ + if($name instanceof Permission){ + $name = $name->getName(); + } + + if($this->isPermissionSet($name)){ + return $this->permissions[$name]->getValue(); + } + + return false; + } + + /** + * //TODO: tick scheduled attachments + */ + public function addAttachment(Plugin $plugin, ?string $name = null, ?bool $value = null) : PermissionAttachment{ + if(!$plugin->isEnabled()){ + throw new PluginException("Plugin " . $plugin->getDescription()->getName() . " is disabled"); + } + + $result = new PermissionAttachment($plugin); + $this->attachments[spl_object_id($result)] = $result; + if($name !== null and $value !== null){ + $result->setPermission($name, $value); + } + + $result->subscribePermissible($this); + + $this->recalculatePermissions(); + + return $result; + } + + public function removeAttachment(PermissionAttachment $attachment) : void{ + if(isset($this->attachments[spl_object_id($attachment)])){ + unset($this->attachments[spl_object_id($attachment)]); + $attachment->unsubscribePermissible($this); + if(($ex = $attachment->getRemovalCallback()) !== null){ + $ex->attachmentRemoved($this, $attachment); + } + + $this->recalculatePermissions(); + + } + + } + + public function recalculatePermissions() : array{ + Timings::$permissibleCalculation->startTiming(); + + $permManager = PermissionManager::getInstance(); + $permManager->unsubscribeFromAllPermissions($this); + $oldPermissions = $this->permissions; + $this->permissions = []; + + foreach($this->rootPermissions as $name => $isGranted){ + $perm = $permManager->getPermission($name); + if($perm === null){ + throw new \InvalidStateException("Unregistered root permission $name"); + } + $this->permissions[$name] = new PermissionAttachmentInfo($name, null, $isGranted, null); + $permManager->subscribeToPermission($name, $this); + $this->calculateChildPermissions($perm->getChildren(), !$isGranted, null, $this->permissions[$name]); + } + + foreach($this->attachments as $attachment){ + $this->calculateChildPermissions($attachment->getPermissions(), false, $attachment, null); + } + + $diff = []; + Timings::$permissibleCalculationDiff->time(function() use ($oldPermissions, &$diff) : void{ + foreach($this->permissions as $permissionAttachmentInfo){ + $name = $permissionAttachmentInfo->getPermission(); + if(!isset($oldPermissions[$name])){ + $diff[$name] = false; + }elseif($oldPermissions[$name]->getValue() !== $permissionAttachmentInfo->getValue()){ + continue; + } + unset($oldPermissions[$name]); + } + //oldPermissions now only contains permissions that changed or are no longer set + foreach($oldPermissions as $permissionAttachmentInfo){ + $diff[$permissionAttachmentInfo->getPermission()] = $permissionAttachmentInfo->getValue(); + } + }); + + Timings::$permissibleCalculationCallback->time(function() use ($diff) : void{ + if(count($diff) > 0){ + foreach($this->permissionRecalculationCallbacks as $closure){ + $closure($diff); + } + } + }); + + Timings::$permissibleCalculation->stopTiming(); + return $diff; + } + + /** + * @param bool[] $children + */ + private function calculateChildPermissions(array $children, bool $invert, ?PermissionAttachment $attachment, ?PermissionAttachmentInfo $parent) : void{ + $permManager = PermissionManager::getInstance(); + foreach($children as $name => $v){ + $perm = $permManager->getPermission($name); + $value = ($v xor $invert); + $this->permissions[$name] = new PermissionAttachmentInfo($name, $attachment, $value, $parent); + $permManager->subscribeToPermission($name, $this); + + if($perm instanceof Permission){ + $this->calculateChildPermissions($perm->getChildren(), !$value, $attachment, $this->permissions[$name]); + } + } + } + + /** + * @return \Closure[]|ObjectSet + * @phpstan-return ObjectSet<\Closure(array $changedPermissionsOldValues) : void> + */ + public function getPermissionRecalculationCallbacks() : ObjectSet{ return $this->permissionRecalculationCallbacks; } + + /** + * @return PermissionAttachmentInfo[] + */ + public function getEffectivePermissions() : array{ + return $this->permissions; + } + + public function destroyCycles() : void{ + PermissionManager::getInstance()->unsubscribeFromAllPermissions($this); + $this->permissions = []; //PermissionAttachmentInfo doesn't reference Permissible anymore, but it references PermissionAttachment which does + foreach($this->attachments as $attachment){ + $attachment->unsubscribePermissible($this); + } + $this->attachments = []; + $this->permissionRecalculationCallbacks->clear(); + } +} diff --git a/src/player/Player.php b/src/player/Player.php index ed8a706f48..9cf9ba72d1 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2005,8 +2005,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->removeCurrentWindow(); $this->removePermanentInventories(); - $this->perm->destroyCycles(); - $this->flagForDespawn(); } From 8e1d27a71914a29197ec98210fced04ed2d23bea Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 12 Jun 2021 21:28:19 +0100 Subject: [PATCH 2523/3224] Constrain types to PermissibleInternal on internal permission subscription methods --- src/permission/Permission.php | 2 +- src/permission/PermissionAttachment.php | 12 ++++++------ src/permission/PermissionManager.php | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/permission/Permission.php b/src/permission/Permission.php index df42876d3e..126f9aba87 100644 --- a/src/permission/Permission.php +++ b/src/permission/Permission.php @@ -78,7 +78,7 @@ class Permission{ } /** - * @return Permissible[] + * @return PermissibleInternal[] */ public function getPermissibles() : array{ return PermissionManager::getInstance()->getPermissionSubscriptions($this->name); diff --git a/src/permission/PermissionAttachment.php b/src/permission/PermissionAttachment.php index c66cc7fdfc..9c6d9d9adb 100644 --- a/src/permission/PermissionAttachment.php +++ b/src/permission/PermissionAttachment.php @@ -35,8 +35,8 @@ class PermissionAttachment{ private $permissions = []; /** - * @var Permissible[] - * @phpstan-var array + * @var PermissibleInternal[] + * @phpstan-var array */ private $subscribers = []; @@ -67,8 +67,8 @@ class PermissionAttachment{ } /** - * @return Permissible[] - * @phpstan-return array + * @return PermissibleInternal[] + * @phpstan-return array */ public function getSubscribers() : array{ return $this->subscribers; } @@ -148,14 +148,14 @@ class PermissionAttachment{ /** * @internal */ - public function subscribePermissible(Permissible $permissible) : void{ + public function subscribePermissible(PermissibleInternal $permissible) : void{ $this->subscribers[spl_object_id($permissible)] = $permissible; } /** * @internal */ - public function unsubscribePermissible(Permissible $permissible) : void{ + public function unsubscribePermissible(PermissibleInternal $permissible) : void{ unset($this->subscribers[spl_object_id($permissible)]); } } diff --git a/src/permission/PermissionManager.php b/src/permission/PermissionManager.php index a50db07e29..b8c859af35 100644 --- a/src/permission/PermissionManager.php +++ b/src/permission/PermissionManager.php @@ -40,7 +40,7 @@ class PermissionManager{ /** @var Permission[] */ protected $permissions = []; - /** @var Permissible[][] */ + /** @var PermissibleInternal[][] */ protected $permSubs = []; public function getPermission(string $name) : ?Permission{ @@ -68,14 +68,14 @@ class PermissionManager{ } } - public function subscribeToPermission(string $permission, Permissible $permissible) : void{ + public function subscribeToPermission(string $permission, PermissibleInternal $permissible) : void{ if(!isset($this->permSubs[$permission])){ $this->permSubs[$permission] = []; } $this->permSubs[$permission][spl_object_id($permissible)] = $permissible; } - public function unsubscribeFromPermission(string $permission, Permissible $permissible) : void{ + public function unsubscribeFromPermission(string $permission, PermissibleInternal $permissible) : void{ if(isset($this->permSubs[$permission])){ unset($this->permSubs[$permission][spl_object_id($permissible)]); if(count($this->permSubs[$permission]) === 0){ @@ -84,7 +84,7 @@ class PermissionManager{ } } - public function unsubscribeFromAllPermissions(Permissible $permissible) : void{ + public function unsubscribeFromAllPermissions(PermissibleInternal $permissible) : void{ foreach($this->permSubs as $permission => &$subs){ unset($subs[spl_object_id($permissible)]); if(count($subs) === 0){ @@ -94,7 +94,7 @@ class PermissionManager{ } /** - * @return Permissible[] + * @return PermissibleInternal[] */ public function getPermissionSubscriptions(string $permission) : array{ return $this->permSubs[$permission] ?? []; From b525f45bf8bfc0d10f566e6e48d2f79b725ad646 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 12 Jun 2021 21:51:08 +0100 Subject: [PATCH 2524/3224] Fixed CS --- src/permission/PermissibleBase.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/permission/PermissibleBase.php b/src/permission/PermissibleBase.php index 96e32a95f8..c2d92e9d50 100644 --- a/src/permission/PermissibleBase.php +++ b/src/permission/PermissibleBase.php @@ -23,9 +23,6 @@ declare(strict_types=1); namespace pocketmine\permission; -use pocketmine\plugin\Plugin; -use pocketmine\utils\ObjectSet; - final class PermissibleBase implements Permissible{ use PermissibleDelegateTrait; From 408e29da903aaef0a91cef221301473cf6a77fa6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 12 Jun 2021 21:55:59 +0100 Subject: [PATCH 2525/3224] Removed PermissionRemovedExecutor this interface is just about the most pointless code in all of PM or Bukkit. In over 4 million lines of code on Poggit, a Google search and a GitHub search, I didn't find a single usage of it that wasn't just bukkit internals code copy pasta, a spoon, a port of PM/Bukkit/whatever into a different language, or someone's generated javadoc. --- src/permission/PermissibleInternal.php | 3 -- src/permission/PermissionAttachment.php | 11 -------- src/permission/PermissionRemovedExecutor.php | 29 -------------------- 3 files changed, 43 deletions(-) delete mode 100644 src/permission/PermissionRemovedExecutor.php diff --git a/src/permission/PermissibleInternal.php b/src/permission/PermissibleInternal.php index 2b0bce8dce..4506142b30 100644 --- a/src/permission/PermissibleInternal.php +++ b/src/permission/PermissibleInternal.php @@ -130,9 +130,6 @@ class PermissibleInternal implements Permissible{ if(isset($this->attachments[spl_object_id($attachment)])){ unset($this->attachments[spl_object_id($attachment)]); $attachment->unsubscribePermissible($this); - if(($ex = $attachment->getRemovalCallback()) !== null){ - $ex->attachmentRemoved($this, $attachment); - } $this->recalculatePermissions(); diff --git a/src/permission/PermissionAttachment.php b/src/permission/PermissionAttachment.php index 9c6d9d9adb..1af03baa9f 100644 --- a/src/permission/PermissionAttachment.php +++ b/src/permission/PermissionAttachment.php @@ -28,9 +28,6 @@ use pocketmine\plugin\PluginException; use function spl_object_id; class PermissionAttachment{ - /** @var PermissionRemovedExecutor|null */ - private $removed = null; - /** @var bool[] */ private $permissions = []; @@ -58,14 +55,6 @@ class PermissionAttachment{ return $this->plugin; } - public function setRemovalCallback(PermissionRemovedExecutor $ex) : void{ - $this->removed = $ex; - } - - public function getRemovalCallback() : ?PermissionRemovedExecutor{ - return $this->removed; - } - /** * @return PermissibleInternal[] * @phpstan-return array diff --git a/src/permission/PermissionRemovedExecutor.php b/src/permission/PermissionRemovedExecutor.php deleted file mode 100644 index 4fbe96ff3f..0000000000 --- a/src/permission/PermissionRemovedExecutor.php +++ /dev/null @@ -1,29 +0,0 @@ - Date: Sun, 13 Jun 2021 09:37:09 -0400 Subject: [PATCH 2526/3224] Store ender chest viewer count on the tile, instead of relying on the inventory's viewer count (#4238) Fixes #4021 --- src/block/EnderChest.php | 1 + src/block/inventory/AnimatedBlockInventoryTrait.php | 8 ++++++-- src/block/inventory/EnderChestInventory.php | 13 +++++++++++++ src/block/tile/EnderChest.php | 13 +++++++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/block/EnderChest.php b/src/block/EnderChest.php index f633a12ca2..04d02195d8 100644 --- a/src/block/EnderChest.php +++ b/src/block/EnderChest.php @@ -53,6 +53,7 @@ class EnderChest extends Transparent{ if($player instanceof Player){ $enderChest = $this->pos->getWorld()->getTile($this->pos); if($enderChest instanceof TileEnderChest and $this->getSide(Facing::UP)->isTransparent()){ + $enderChest->setViewerCount($enderChest->getViewerCount() + 1); $player->setCurrentWindow(new EnderChestInventory($this->pos, $player->getEnderInventory())); } } diff --git a/src/block/inventory/AnimatedBlockInventoryTrait.php b/src/block/inventory/AnimatedBlockInventoryTrait.php index dd607b1373..e0bb9fee0f 100644 --- a/src/block/inventory/AnimatedBlockInventoryTrait.php +++ b/src/block/inventory/AnimatedBlockInventoryTrait.php @@ -30,6 +30,10 @@ use function count; trait AnimatedBlockInventoryTrait{ use BlockInventoryTrait; + public function getViewerCount() : int{ + return count($this->getViewers()); + } + /** * @return Player[] * @phpstan-return array @@ -43,7 +47,7 @@ trait AnimatedBlockInventoryTrait{ public function onOpen(Player $who) : void{ parent::onOpen($who); - if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){ + if($this->getHolder()->isValid() and $this->getViewerCount() === 1){ //TODO: this crap really shouldn't be managed by the inventory $this->animateBlock(true); $this->getHolder()->getWorld()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getOpenSound()); @@ -53,7 +57,7 @@ trait AnimatedBlockInventoryTrait{ abstract protected function animateBlock(bool $isOpen) : void; public function onClose(Player $who) : void{ - if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){ + if($this->getHolder()->isValid() and $this->getViewerCount() === 1){ //TODO: this crap really shouldn't be managed by the inventory $this->animateBlock(false); $this->getHolder()->getWorld()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getCloseSound()); diff --git a/src/block/inventory/EnderChestInventory.php b/src/block/inventory/EnderChestInventory.php index f0c706371a..4bf9bef833 100644 --- a/src/block/inventory/EnderChestInventory.php +++ b/src/block/inventory/EnderChestInventory.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block\inventory; +use pocketmine\block\tile\EnderChest; use pocketmine\inventory\BaseInventory; use pocketmine\inventory\CallbackInventoryListener; use pocketmine\inventory\Inventory; @@ -85,6 +86,14 @@ class EnderChestInventory extends BaseInventory implements BlockInventory{ $this->inventory->setContents($items); } + public function getViewerCount() : int{ + $enderChest = $this->getHolder()->getWorld()->getTile($this->getHolder()); + if(!$enderChest instanceof EnderChest){ + return 0; + } + return $enderChest->getViewerCount(); + } + protected function getOpenSound() : Sound{ return new EnderChestOpenSound(); } @@ -102,6 +111,10 @@ class EnderChestInventory extends BaseInventory implements BlockInventory{ public function onClose(Player $who) : void{ $this->animatedBlockInventoryTrait_onClose($who); + $enderChest = $this->getHolder()->getWorld()->getTile($this->getHolder()); + if($enderChest instanceof EnderChest){ + $enderChest->setViewerCount($enderChest->getViewerCount() - 1); + } if($who === $this->inventory->getHolder()){ $this->inventory->getListeners()->remove($this->inventoryListener); $this->inventoryListener = CallbackInventoryListener::onAnyChange(static function() : void{}); //break cyclic reference diff --git a/src/block/tile/EnderChest.php b/src/block/tile/EnderChest.php index 902bc79f8a..30bedd9368 100644 --- a/src/block/tile/EnderChest.php +++ b/src/block/tile/EnderChest.php @@ -27,6 +27,19 @@ use pocketmine\nbt\tag\CompoundTag; class EnderChest extends Spawnable{ + protected int $viewerCount = 0; + + public function getViewerCount() : int{ + return $this->viewerCount; + } + + public function setViewerCount(int $viewerCount) : void{ + if($viewerCount < 0){ + throw new \InvalidArgumentException('Viewer count cannot be negative'); + } + $this->viewerCount = $viewerCount; + } + public function readSaveData(CompoundTag $nbt) : void{ } From a676dba9f060c3422d133974b0fa904c74fd3722 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Jun 2021 14:47:35 +0100 Subject: [PATCH 2527/3224] Updated ClassLoader dependency --- composer.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.lock b/composer.lock index dda2954189..456474d166 100644 --- a/composer.lock +++ b/composer.lock @@ -415,12 +415,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/ClassLoader.git", - "reference": "ba70cbabc53d6a36c5d179776e99bc059f21b4a9" + "reference": "80226e0917be79ac3230606113e25134a31e6a85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/ba70cbabc53d6a36c5d179776e99bc059f21b4a9", - "reference": "ba70cbabc53d6a36c5d179776e99bc059f21b4a9", + "url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/80226e0917be79ac3230606113e25134a31e6a85", + "reference": "80226e0917be79ac3230606113e25134a31e6a85", "shasum": "" }, "require": { @@ -452,7 +452,7 @@ "issues": "https://github.com/pmmp/ClassLoader/issues", "source": "https://github.com/pmmp/ClassLoader/tree/master" }, - "time": "2021-04-21T22:05:17+00:00" + "time": "2021-05-29T23:09:32+00:00" }, { "name": "pocketmine/color", @@ -3533,5 +3533,5 @@ "platform-overrides": { "php": "7.4.0" }, - "plugin-api-version": "2.0.0" + "plugin-api-version": "2.1.0" } From d8b56a12193f47fd23ff606d8beaab57deb55192 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Jun 2021 14:48:24 +0100 Subject: [PATCH 2528/3224] Update transient composer junk that we don't care about, but have to update so that it doesn't slip in to some other commit --- composer.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/composer.lock b/composer.lock index 456474d166..dedb1f9090 100644 --- a/composer.lock +++ b/composer.lock @@ -1233,16 +1233,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.22.1", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "5232de97ee3b75b0360528dae24e73db49566ab1" + "reference": "2df51500adbaebdc4c38dea4c89a2e131c45c8a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1", - "reference": "5232de97ee3b75b0360528dae24e73db49566ab1", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/2df51500adbaebdc4c38dea4c89a2e131c45c8a1", + "reference": "2df51500adbaebdc4c38dea4c89a2e131c45c8a1", "shasum": "" }, "require": { @@ -1254,7 +1254,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1293,7 +1293,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.1" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.0" }, "funding": [ { @@ -1309,7 +1309,7 @@ "type": "tidelift" } ], - "time": "2021-01-22T09:19:47+00:00" + "time": "2021-05-27T09:27:20+00:00" } ], "packages-dev": [ @@ -2925,16 +2925,16 @@ }, { "name": "sebastian/global-state", - "version": "5.0.2", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "a90ccbddffa067b51f574dea6eb25d5680839455" + "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/a90ccbddffa067b51f574dea6eb25d5680839455", - "reference": "a90ccbddffa067b51f574dea6eb25d5680839455", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23bd5951f7ff26f12d4e3242864df3e08dec4e49", + "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49", "shasum": "" }, "require": { @@ -2977,7 +2977,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.2" + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.3" }, "funding": [ { @@ -2985,7 +2985,7 @@ "type": "github" } ], - "time": "2020-10-26T15:55:19+00:00" + "time": "2021-06-11T13:31:12+00:00" }, { "name": "sebastian/lines-of-code", From 4df536fee7d00b3718b88e9b7801097585a4eb65 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Jun 2021 15:22:12 +0100 Subject: [PATCH 2529/3224] Bump Snooze to 0.3.0 --- composer.json | 2 +- composer.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/composer.json b/composer.json index 7166c3e3bd..317d3197a7 100644 --- a/composer.json +++ b/composer.json @@ -45,7 +45,7 @@ "pocketmine/nbt": "^0.3.0", "pocketmine/raklib": "^0.13.1", "pocketmine/raklib-ipc": "^0.1.0", - "pocketmine/snooze": "^0.1.0", + "pocketmine/snooze": "^0.3.0", "pocketmine/spl": "dev-master", "ramsey/uuid": "^4.1", "respect/validation": "^2.0" diff --git a/composer.lock b/composer.lock index dedb1f9090..41cde8c7ab 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "59dbdc116eef096a5499b4c2b7082fb1", + "content-hash": "34888ad7b5a7e0f4976901788037b6c2", "packages": [ { "name": "adhocore/json-comment", @@ -784,25 +784,25 @@ }, { "name": "pocketmine/snooze", - "version": "0.1.5", + "version": "0.3.0", "source": { "type": "git", "url": "https://github.com/pmmp/Snooze.git", - "reference": "70b5e7937a06878dd321a3182ceb76d56298f2cd" + "reference": "fe5b1dbf0d6267da882d1f67924772bd93db833d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Snooze/zipball/70b5e7937a06878dd321a3182ceb76d56298f2cd", - "reference": "70b5e7937a06878dd321a3182ceb76d56298f2cd", + "url": "https://api.github.com/repos/pmmp/Snooze/zipball/fe5b1dbf0d6267da882d1f67924772bd93db833d", + "reference": "fe5b1dbf0d6267da882d1f67924772bd93db833d", "shasum": "" }, "require": { "ext-pthreads": ">=3.1.7dev", - "php-64bit": "^7.2 || ^8.0" + "php-64bit": "^7.3 || ^8.0" }, "require-dev": { "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "0.12.76", + "phpstan/phpstan": "0.12.88", "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", @@ -818,9 +818,9 @@ "description": "Thread notification management library for code using the pthreads extension", "support": { "issues": "https://github.com/pmmp/Snooze/issues", - "source": "https://github.com/pmmp/Snooze/tree/0.1.5" + "source": "https://github.com/pmmp/Snooze/tree/0.3.0" }, - "time": "2021-02-22T16:16:12+00:00" + "time": "2021-06-13T13:57:47+00:00" }, { "name": "pocketmine/spl", From 0df26774640c94e9f3f763b14c029929210592b5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Jun 2021 19:57:48 +0100 Subject: [PATCH 2530/3224] EncryptionContext: Allow passing encryption algo as a constructor parameter --- src/network/mcpe/NetworkSession.php | 2 +- src/network/mcpe/encryption/EncryptionContext.php | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 498fdf6402..0a61e0ed46 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -670,7 +670,7 @@ class NetworkSession{ } $this->sendDataPacket(ServerToClientHandshakePacket::create($handshakeJwt), true); //make sure this gets sent before encryption is enabled - $this->cipher = new EncryptionContext($encryptionKey); + $this->cipher = new EncryptionContext($encryptionKey, EncryptionContext::ENCRYPTION_SCHEME); $this->setHandler(new HandshakePacketHandler(function() : void{ $this->onServerLoginSuccess(); diff --git a/src/network/mcpe/encryption/EncryptionContext.php b/src/network/mcpe/encryption/EncryptionContext.php index 1b4df11bbf..270d40d439 100644 --- a/src/network/mcpe/encryption/EncryptionContext.php +++ b/src/network/mcpe/encryption/EncryptionContext.php @@ -32,7 +32,7 @@ use function strlen; use function substr; class EncryptionContext{ - private const ENCRYPTION_SCHEME = "AES-256-GCM"; + public const ENCRYPTION_SCHEME = "AES-256-GCM"; private const CHECKSUM_ALGO = "sha256"; /** @var bool */ @@ -43,22 +43,22 @@ class EncryptionContext{ /** @var Cipher */ private $decryptCipher; + /** @var int */ private $decryptCounter = 0; - /** @var Cipher */ private $encryptCipher; /** @var int */ private $encryptCounter = 0; - public function __construct(string $encryptionKey){ + public function __construct(string $encryptionKey, string $algorithm){ $this->key = $encryptionKey; - $this->decryptCipher = new Cipher(self::ENCRYPTION_SCHEME); + $this->decryptCipher = new Cipher($algorithm); $ivLength = $this->decryptCipher->getIVLength(); $this->decryptCipher->decryptInit($this->key, substr($this->key, 0, $ivLength)); - $this->encryptCipher = new Cipher(self::ENCRYPTION_SCHEME); + $this->encryptCipher = new Cipher($algorithm); $ivLength = $this->encryptCipher->getIVLength(); $this->encryptCipher->encryptInit($this->key, substr($this->key, 0, $ivLength)); } From 04a6e89d6fc1a8df76b66615fab9b2e97bb03ece Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Jun 2021 21:57:23 +0100 Subject: [PATCH 2531/3224] Change encryption to use CTR instead of GCM despite MCPE claiming to use GCM, it omits the auth tag, which defeats the whole point of using GCM. CTR can be used instead, with the final 4 bytes of the IV being 0002. --- src/network/mcpe/NetworkSession.php | 2 +- .../mcpe/encryption/EncryptionContext.php | 35 +++++++++++++++---- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 0a61e0ed46..8e3d0dfc00 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -670,7 +670,7 @@ class NetworkSession{ } $this->sendDataPacket(ServerToClientHandshakePacket::create($handshakeJwt), true); //make sure this gets sent before encryption is enabled - $this->cipher = new EncryptionContext($encryptionKey, EncryptionContext::ENCRYPTION_SCHEME); + $this->cipher = EncryptionContext::fakeGCM($encryptionKey); $this->setHandler(new HandshakePacketHandler(function() : void{ $this->onServerLoginSuccess(); diff --git a/src/network/mcpe/encryption/EncryptionContext.php b/src/network/mcpe/encryption/EncryptionContext.php index 270d40d439..18d4694689 100644 --- a/src/network/mcpe/encryption/EncryptionContext.php +++ b/src/network/mcpe/encryption/EncryptionContext.php @@ -32,7 +32,6 @@ use function strlen; use function substr; class EncryptionContext{ - public const ENCRYPTION_SCHEME = "AES-256-GCM"; private const CHECKSUM_ALGO = "sha256"; /** @var bool */ @@ -51,16 +50,40 @@ class EncryptionContext{ /** @var int */ private $encryptCounter = 0; - public function __construct(string $encryptionKey, string $algorithm){ + public function __construct(string $encryptionKey, string $algorithm, string $iv){ $this->key = $encryptionKey; $this->decryptCipher = new Cipher($algorithm); - $ivLength = $this->decryptCipher->getIVLength(); - $this->decryptCipher->decryptInit($this->key, substr($this->key, 0, $ivLength)); + $this->decryptCipher->decryptInit($this->key, $iv); $this->encryptCipher = new Cipher($algorithm); - $ivLength = $this->encryptCipher->getIVLength(); - $this->encryptCipher->encryptInit($this->key, substr($this->key, 0, $ivLength)); + $this->encryptCipher->encryptInit($this->key, $iv); + } + + /** + * Returns an EncryptionContext suitable for decrypting Minecraft packets from 1.16.200 and up. + * + * MCPE uses GCM, but without the auth tag, which defeats the whole purpose of using GCM. + * GCM is just a wrapper around CTR which adds the auth tag, so CTR can replace GCM for this case. + * However, since GCM passes only the first 12 bytes of the IV followed by 0002, we must do the same for + * compatibility with MCPE. + * In PM, we could skip this and just use GCM directly (since we use OpenSSL), but this way is more portable, and + * better for developers who come digging in the PM code looking for answers. + */ + public static function fakeGCM(string $encryptionKey) : self{ + return new EncryptionContext( + $encryptionKey, + "AES-256-CTR", + substr($encryptionKey, 0, 12) . "\x00\x00\x00\x02" + ); + } + + public static function cfb8(string $encryptionKey) : self{ + return new EncryptionContext( + $encryptionKey, + "AES-256-CFB8", + substr($encryptionKey, 0, 16) + ); } /** From e5dd5a57451e879408f814363c8c30e8d093d9b6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Jun 2021 22:24:12 +0100 Subject: [PATCH 2532/3224] NetworkSession: Fixed missing nullable declarations phpstan doesn't report these because .. reasons .. @ondrejmirtes this is causing bugs to go unfound :( I'm aware of the irony that I just silenced the bugs that were exposed by this commit .. that's an architectural problem for another day --- src/network/mcpe/NetworkSession.php | 8 ++++---- tests/phpstan/configs/l8-baseline.neon | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 8e3d0dfc00..4d2acdb30a 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -137,8 +137,8 @@ class NetworkSession{ private $ip; /** @var int */ private $port; - /** @var PlayerInfo */ - private $info; + /** @var PlayerInfo|null */ + private $info = null; /** @var int|null */ private $ping = null; @@ -158,8 +158,8 @@ class NetworkSession{ /** @var CompoundTag|null */ private $cachedOfflinePlayerData = null; - /** @var EncryptionContext */ - private $cipher; + /** @var EncryptionContext|null */ + private $cipher = null; /** @var Packet[] */ private $sendBuffer = []; diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 4dc8a7f587..c8742c2692 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -105,6 +105,16 @@ parameters: count: 1 path: ../../../src/network/mcpe/NetworkSession.php + - + message: "#^Cannot call method getUsername\\(\\) on pocketmine\\\\player\\\\PlayerInfo\\|null\\.$#" + count: 2 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Cannot call method getUuid\\(\\) on pocketmine\\\\player\\\\PlayerInfo\\|null\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + - message: "#^Cannot call method sendData\\(\\) on pocketmine\\\\player\\\\Player\\|null\\.$#" count: 1 @@ -170,6 +180,11 @@ parameters: count: 1 path: ../../../src/network/mcpe/NetworkSession.php + - + message: "#^Parameter \\#2 \\$playerInfo of method pocketmine\\\\Server\\:\\:createPlayer\\(\\) expects pocketmine\\\\player\\\\PlayerInfo, pocketmine\\\\player\\\\PlayerInfo\\|null given\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\LevelSoundEventPacket\\:\\:\\$position \\(pocketmine\\\\math\\\\Vector3\\) does not accept pocketmine\\\\math\\\\Vector3\\|null\\.$#" count: 1 From 3d0b21f30c3a20d7b1d4abcba3ed24c62521c919 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Jun 2021 22:27:23 +0100 Subject: [PATCH 2533/3224] Denoise NetworkSession with typed properties --- src/network/mcpe/NetworkSession.php | 72 ++++++++++------------------- 1 file changed, 25 insertions(+), 47 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 4d2acdb30a..cea24cb9c8 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -125,72 +125,50 @@ use function time; use function ucfirst; class NetworkSession{ - /** @var \PrefixedLogger */ - private $logger; - /** @var Server */ - private $server; - /** @var Player|null */ - private $player = null; - /** @var NetworkSessionManager */ - private $manager; - /** @var string */ - private $ip; - /** @var int */ - private $port; - /** @var PlayerInfo|null */ - private $info = null; - /** @var int|null */ - private $ping = null; + private \PrefixedLogger $logger; + private Server $server; + private ?Player $player = null; + private NetworkSessionManager $manager; + private string $ip; + private int $port; + private ?PlayerInfo $info = null; + private ?int $ping = null; - /** @var PacketHandler|null */ - private $handler = null; + private ?PacketHandler $handler = null; - /** @var bool */ - private $connected = true; - /** @var bool */ - private $disconnectGuard = false; - /** @var bool */ - private $loggedIn = false; - /** @var bool */ - private $authenticated = false; - /** @var int */ - private $connectTime; - /** @var CompoundTag|null */ - private $cachedOfflinePlayerData = null; + private bool $connected = true; + private bool $disconnectGuard = false; + private bool $loggedIn = false; + private bool $authenticated = false; + private int $connectTime; + private ?CompoundTag $cachedOfflinePlayerData = null; - /** @var EncryptionContext|null */ - private $cipher = null; + private ?EncryptionContext $cipher = null; /** @var Packet[] */ - private $sendBuffer = []; + private array $sendBuffer = []; /** * @var \SplQueue|CompressBatchPromise[] * @phpstan-var \SplQueue */ - private $compressedQueue; - /** @var Compressor */ - private $compressor; - /** @var bool */ - private $forceAsyncCompression = true; + private \SplQueue $compressedQueue; + private Compressor $compressor; + private bool $forceAsyncCompression = true; - /** @var PacketPool */ - private $packetPool; + private PacketPool $packetPool; - /** @var InventoryManager|null */ - private $invManager = null; + private ?InventoryManager $invManager = null; - /** @var PacketSender */ - private $sender; + private PacketSender $sender; - /** @var PacketBroadcaster */ - private $broadcaster; + private PacketBroadcaster $broadcaster; /** * @var \Closure[]|ObjectSet * @phpstan-var ObjectSet<\Closure() : void> */ - private $disposeHooks; + private ObjectSet $disposeHooks; public function __construct(Server $server, NetworkSessionManager $manager, PacketPool $packetPool, PacketSender $sender, PacketBroadcaster $broadcaster, Compressor $compressor, string $ip, int $port){ $this->server = $server; From 80bf948588135282128fc94b15ca416824683f6e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Jun 2021 22:41:36 +0100 Subject: [PATCH 2534/3224] Separate UPnPNetworkInterface from UPnP implementation --- src/Server.php | 4 +- src/network/upnp/UPnP.php | 53 +++------------- src/network/upnp/UPnPNetworkInterface.php | 75 +++++++++++++++++++++++ 3 files changed, 85 insertions(+), 47 deletions(-) create mode 100644 src/network/upnp/UPnPNetworkInterface.php diff --git a/src/Server.php b/src/Server.php index 702739dc51..213beeb12f 100644 --- a/src/Server.php +++ b/src/Server.php @@ -64,7 +64,7 @@ use pocketmine\network\Network; use pocketmine\network\query\DedicatedQueryNetworkInterface; use pocketmine\network\query\QueryHandler; use pocketmine\network\query\QueryInfo; -use pocketmine\network\upnp\UPnP; +use pocketmine\network\upnp\UPnPNetworkInterface; use pocketmine\permission\BanList; use pocketmine\permission\DefaultPermissions; use pocketmine\player\GameMode; @@ -1109,7 +1109,7 @@ class Server{ if((bool) $this->configGroup->getProperty("network.upnp-forwarding", false)){ try{ - $this->network->registerInterface(new UPnP($this->logger, Internet::getInternalIP(), $this->getPort())); + $this->network->registerInterface(new UPnPNetworkInterface($this->logger, Internet::getInternalIP(), $this->getPort())); }catch(\RuntimeException $e){ $this->logger->alert("UPnP portforward failed: " . $e->getMessage()); } diff --git a/src/network/upnp/UPnP.php b/src/network/upnp/UPnP.php index fb49dd8723..07399e0e4c 100644 --- a/src/network/upnp/UPnP.php +++ b/src/network/upnp/UPnP.php @@ -55,7 +55,6 @@ declare(strict_types=1); */ namespace pocketmine\network\upnp; -use pocketmine\network\NetworkInterface; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Internet; use function count; @@ -80,7 +79,7 @@ use const SOCKET_ETIMEDOUT; use const SOL_SOCKET; use const SOL_UDP; -class UPnP implements NetworkInterface{ +class UPnP{ private const MAX_DISCOVERY_ATTEMPTS = 3; private static function makePcreError() : \RuntimeException{ @@ -188,36 +187,13 @@ class UPnP implements NetworkInterface{ return $serviceURL; } - /** @var string */ - private $ip; - /** @var int */ - private $port; - - /** @var string|null */ - private $serviceURL = null; - /** @var \Logger */ - private $logger; - - public function __construct(\Logger $logger, string $ip, int $port){ - if(!Internet::$online){ - throw new \RuntimeException("Server is offline"); - } - - $this->ip = $ip; - $this->port = $port; - $this->logger = new \PrefixedLogger($logger, "UPnP Port Forwarder"); - } - - public function start() : void{ - $this->logger->info("Attempting to portforward..."); - $this->serviceURL = self::getServiceUrl(); - + public static function portForward(string $serviceURL, int $port) : void{ $body = '' . '' . - '' . $this->port . '' . + '' . $port . '' . 'UDP' . - '' . $this->port . '' . + '' . $port . '' . '' . Internet::getInternalIP() . '' . '1' . 'PocketMine-MP' . @@ -234,29 +210,16 @@ class UPnP implements NetworkInterface{ 'SOAPAction: "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"' ]; - if(Internet::postURL($this->serviceURL, $contents, 3, $headers, $err) === null){ + if(Internet::postURL($serviceURL, $contents, 3, $headers, $err) === null){ throw new \RuntimeException("Failed to portforward using UPnP: " . $err); } - - $this->logger->info("Forwarded $this->ip:$this->port to external port $this->port"); } - public function setName(string $name) : void{ - - } - - public function tick() : void{ - - } - - public function shutdown() : void{ - if($this->serviceURL === null){ - return; - } + public static function removePortForward(string $serviceURL, int $port) : void{ $body = '' . '' . - '' . $this->port . '' . + '' . $port . '' . 'UDP' . ''; @@ -270,6 +233,6 @@ class UPnP implements NetworkInterface{ 'SOAPAction: "urn:schemas-upnp-org:service:WANIPConnection:1#DeletePortMapping"' ]; - Internet::postURL($this->serviceURL, $contents, 3, $headers); + Internet::postURL($serviceURL, $contents, 3, $headers); } } diff --git a/src/network/upnp/UPnPNetworkInterface.php b/src/network/upnp/UPnPNetworkInterface.php new file mode 100644 index 0000000000..f4deafc39b --- /dev/null +++ b/src/network/upnp/UPnPNetworkInterface.php @@ -0,0 +1,75 @@ +ip = $ip; + $this->port = $port; + $this->logger = new \PrefixedLogger($logger, "UPnP Port Forwarder"); + } + + public function start() : void{ + $this->logger->info("Attempting to portforward..."); + $this->serviceURL = UPnP::getServiceUrl(); + + UPnP::portForward($this->serviceURL, $this->port); + + $this->logger->info("Forwarded $this->ip:$this->port to external port $this->port"); + } + + public function setName(string $name) : void{ + + } + + public function tick() : void{ + + } + + public function shutdown() : void{ + if($this->serviceURL === null){ + return; + } + + UPnP::removePortForward($this->serviceURL, $this->port); + } +} From ec7ea98ead298d758020854b6d57b9d0c7f39014 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Jun 2021 22:48:38 +0100 Subject: [PATCH 2535/3224] UPnP: expose more functionality --- src/network/upnp/UPnP.php | 12 ++++++------ src/network/upnp/UPnPNetworkInterface.php | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/network/upnp/UPnP.php b/src/network/upnp/UPnP.php index 07399e0e4c..8645fa99f7 100644 --- a/src/network/upnp/UPnP.php +++ b/src/network/upnp/UPnP.php @@ -187,14 +187,14 @@ class UPnP{ return $serviceURL; } - public static function portForward(string $serviceURL, int $port) : void{ + public static function portForward(string $serviceURL, string $internalIP, int $internalPort, int $externalPort) : void{ $body = '' . '' . - '' . $port . '' . + '' . $externalPort . '' . 'UDP' . - '' . $port . '' . - '' . Internet::getInternalIP() . '' . + '' . $internalPort . '' . + '' . $internalIP . '' . '1' . 'PocketMine-MP' . '0' . @@ -215,11 +215,11 @@ class UPnP{ } } - public static function removePortForward(string $serviceURL, int $port) : void{ + public static function removePortForward(string $serviceURL, int $externalPort) : void{ $body = '' . '' . - '' . $port . '' . + '' . $externalPort . '' . 'UDP' . ''; diff --git a/src/network/upnp/UPnPNetworkInterface.php b/src/network/upnp/UPnPNetworkInterface.php index f4deafc39b..ecb30e8766 100644 --- a/src/network/upnp/UPnPNetworkInterface.php +++ b/src/network/upnp/UPnPNetworkInterface.php @@ -52,7 +52,7 @@ final class UPnPNetworkInterface implements NetworkInterface{ $this->logger->info("Attempting to portforward..."); $this->serviceURL = UPnP::getServiceUrl(); - UPnP::portForward($this->serviceURL, $this->port); + UPnP::portForward($this->serviceURL, Internet::getInternalIP(), $this->port, $this->port); $this->logger->info("Forwarded $this->ip:$this->port to external port $this->port"); } From 2ee86f0edf625d3000658317678ecf8278f60970 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 13 Jun 2021 23:02:42 +0100 Subject: [PATCH 2536/3224] Improved UPnP exception handling --- src/Server.php | 6 +--- src/network/upnp/UPnP.php | 34 +++++++++++++---------- src/network/upnp/UPnPException.php | 28 +++++++++++++++++++ src/network/upnp/UPnPNetworkInterface.php | 9 ++++-- 4 files changed, 55 insertions(+), 22 deletions(-) create mode 100644 src/network/upnp/UPnPException.php diff --git a/src/Server.php b/src/Server.php index 213beeb12f..0ebbc6e07a 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1108,11 +1108,7 @@ class Server{ } if((bool) $this->configGroup->getProperty("network.upnp-forwarding", false)){ - try{ - $this->network->registerInterface(new UPnPNetworkInterface($this->logger, Internet::getInternalIP(), $this->getPort())); - }catch(\RuntimeException $e){ - $this->logger->alert("UPnP portforward failed: " . $e->getMessage()); - } + $this->network->registerInterface(new UPnPNetworkInterface($this->logger, Internet::getInternalIP(), $this->getPort())); } if((bool) $this->configGroup->getProperty("settings.send-usage", true)){ diff --git a/src/network/upnp/UPnP.php b/src/network/upnp/UPnP.php index 8645fa99f7..c2ed90f6e5 100644 --- a/src/network/upnp/UPnP.php +++ b/src/network/upnp/UPnP.php @@ -95,13 +95,16 @@ class UPnP{ throw new \RuntimeException("PCRE error: $message"); } + /** + * @throws UPnPException + */ public static function getServiceUrl() : string{ $socket = @socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); if($socket === false){ - throw new \RuntimeException("Socket error: " . trim(socket_strerror(socket_last_error()))); + throw new AssumptionFailedError("Socket error: " . trim(socket_strerror(socket_last_error()))); } if(!@socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, ["sec" => 3, "usec" => 0])){ - throw new \RuntimeException("Socket error: " . trim(socket_strerror(socket_last_error($socket)))); + throw new AssumptionFailedError("Socket error: " . trim(socket_strerror(socket_last_error($socket)))); } $contents = "M-SEARCH * HTTP/1.1\r\n" . @@ -113,17 +116,17 @@ class UPnP{ for($i = 0; $i < self::MAX_DISCOVERY_ATTEMPTS; ++$i){ $sendbyte = @socket_sendto($socket, $contents, strlen($contents), 0, "239.255.255.250", 1900); if($sendbyte === false){ - throw new \RuntimeException("Socket error: " . trim(socket_strerror(socket_last_error($socket)))); + throw new UPnPException("Socket error: " . trim(socket_strerror(socket_last_error($socket)))); } if($sendbyte !== strlen($contents)){ - throw new \RuntimeException("Socket error: Unable to send the entire contents."); + throw new UPnPException("Socket error: Unable to send the entire contents."); } while(true){ if(@socket_recvfrom($socket, $buffer, 1024, 0, $responseHost, $responsePort) === false){ if(socket_last_error($socket) === SOCKET_ETIMEDOUT){ continue 2; } - throw new \RuntimeException("Socket error: " . trim(socket_strerror(socket_last_error($socket)))); + throw new UPnPException("Socket error: " . trim(socket_strerror(socket_last_error($socket)))); } $pregResult = preg_match('/location\s*:\s*(.+)\n/i', $buffer, $matches); if($pregResult === false){ @@ -138,33 +141,33 @@ class UPnP{ } socket_close($socket); if($location === null){ - throw new \RuntimeException("Unable to find the router. Ensure that network discovery is enabled in Control Panel."); + throw new UPnPException("Unable to find the router. Ensure that network discovery is enabled in Control Panel."); } $url = parse_url($location); if($url === false){ - throw new \RuntimeException("Failed to parse the router's url: {$location}"); + throw new UPnPException("Failed to parse the router's url: {$location}"); } if(!isset($url['host'])){ - throw new \RuntimeException("Failed to recognize the host name from the router's url: {$location}"); + throw new UPnPException("Failed to recognize the host name from the router's url: {$location}"); } $urlHost = $url['host']; if(!isset($url['port'])){ - throw new \RuntimeException("Failed to recognize the port number from the router's url: {$location}"); + throw new UPnPException("Failed to recognize the port number from the router's url: {$location}"); } $urlPort = $url['port']; $response = Internet::getURL($location, 3, [], $err); if($response === null){ - throw new \RuntimeException("Unable to access XML: {$err}"); + throw new UPnPException("Unable to access XML: {$err}"); } if($response->getCode() !== 200){ - throw new \RuntimeException("Unable to access XML: {$response->getBody()}"); + throw new UPnPException("Unable to access XML: {$response->getBody()}"); } $defaultInternalError = libxml_use_internal_errors(true); try{ $root = new \SimpleXMLElement($response->getBody()); }catch(\Exception $e){ - throw new \RuntimeException("Broken XML."); + throw new UPnPException("Broken XML."); } libxml_use_internal_errors($defaultInternalError); $root->registerXPathNamespace("upnp", "urn:schemas-upnp-org:device-1-0"); @@ -180,13 +183,16 @@ class UPnP{ throw new AssumptionFailedError("xpath query should not error here"); } if(count($xpathResult) === 0){ - throw new \RuntimeException("Your router does not support portforwarding"); + throw new UPnPException("Your router does not support portforwarding"); } $controlURL = (string) $xpathResult[0]; $serviceURL = sprintf("%s:%d/%s", $urlHost, $urlPort, $controlURL); return $serviceURL; } + /** + * @throws UPnPException + */ public static function portForward(string $serviceURL, string $internalIP, int $internalPort, int $externalPort) : void{ $body = '' . @@ -211,7 +217,7 @@ class UPnP{ ]; if(Internet::postURL($serviceURL, $contents, 3, $headers, $err) === null){ - throw new \RuntimeException("Failed to portforward using UPnP: " . $err); + throw new UPnPException("Failed to portforward using UPnP: " . $err); } } diff --git a/src/network/upnp/UPnPException.php b/src/network/upnp/UPnPException.php new file mode 100644 index 0000000000..9152cec74f --- /dev/null +++ b/src/network/upnp/UPnPException.php @@ -0,0 +1,28 @@ +logger->info("Attempting to portforward..."); $this->serviceURL = UPnP::getServiceUrl(); - UPnP::portForward($this->serviceURL, Internet::getInternalIP(), $this->port, $this->port); - - $this->logger->info("Forwarded $this->ip:$this->port to external port $this->port"); + try{ + UPnP::portForward($this->serviceURL, Internet::getInternalIP(), $this->port, $this->port); + $this->logger->info("Forwarded $this->ip:$this->port to external port $this->port"); + }catch(UPnPException $e){ + $this->logger->error("UPnP portforward failed: " . $e->getMessage()); + } } public function setName(string $name) : void{ From c22f7935219aa09fb5fade9ecab4420dcca3d8cb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 15 Jun 2021 19:20:31 +0100 Subject: [PATCH 2537/3224] RakLibInterface: Log a message when a non-0xfe packet is received --- src/network/mcpe/raklib/RakLibInterface.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index c31b436940..5eb5d40dd7 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -44,6 +44,7 @@ use raklib\server\ipc\UserToRakLibThreadMessageSender; use raklib\server\ServerEventListener; use raklib\utils\InternetAddress; use function addcslashes; +use function base64_encode; use function bin2hex; use function implode; use function mt_rand; @@ -176,6 +177,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ public function onPacketReceive(int $sessionId, string $packet) : void{ if(isset($this->sessions[$sessionId])){ if($packet === "" or $packet[0] !== self::MCPE_RAKNET_PACKET_ID){ + $this->sessions[$sessionId]->getLogger()->debug("Non-FE packet received: " . base64_encode($packet)); return; } //get this now for blocking in case the player was closed before the exception was raised From 61c59be299e369878aae00976a970904d7ed8d6b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 16 Jun 2021 12:48:09 +0100 Subject: [PATCH 2538/3224] Replace hardcoded block metadata shifts and masks with constants we might want to make these bigger than 4 bits in the future. --- src/block/Block.php | 4 +++- src/block/BlockFactory.php | 14 ++++++------- .../mcpe/convert/RuntimeBlockMapping.php | 7 ++++--- src/world/format/Chunk.php | 5 +++-- src/world/format/io/leveldb/LevelDB.php | 21 ++++++++++--------- src/world/format/io/region/Anvil.php | 3 ++- src/world/format/io/region/McRegion.php | 3 ++- src/world/format/io/region/PMAnvil.php | 3 ++- .../block/regenerate_consistency_check.php | 6 +++--- 9 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/block/Block.php b/src/block/Block.php index 16056eb584..737bfd7c68 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -48,6 +48,8 @@ use function dechex; use const PHP_INT_MAX; class Block{ + public const INTERNAL_METADATA_BITS = 4; + public const INTERNAL_METADATA_MASK = ~(~0 << self::INTERNAL_METADATA_BITS); protected BlockIdentifier $idInfo; protected string $fallbackName; @@ -90,7 +92,7 @@ class Block{ * @internal */ public function getFullId() : int{ - return ($this->getId() << 4) | $this->getMeta(); + return ($this->getId() << self::INTERNAL_METADATA_BITS) | $this->getMeta(); } public function asItem() : Item{ diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index f220b0afcf..35bae199a2 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -895,7 +895,7 @@ class BlockFactory{ throw new \InvalidArgumentException("Block registration " . get_class($block) . " has states which conflict with other blocks"); } - $index = ($id << 4) | $m; + $index = ($id << Block::INTERNAL_METADATA_BITS) | $m; $v = clone $block; try{ @@ -915,7 +915,7 @@ class BlockFactory{ } public function remap(int $id, int $meta, Block $block) : void{ - $index = ($id << 4) | $meta; + $index = ($id << Block::INTERNAL_METADATA_BITS) | $meta; if($this->isRegistered($id, $meta)){ $existing = $this->fullList[$index]; if($existing !== null && $existing->getFullId() === $index){ @@ -924,7 +924,7 @@ class BlockFactory{ //if it's not a match, this was already remapped for some reason; remapping overwrites are OK } } - $this->fillStaticArrays(($id << 4) | $meta, $block); + $this->fillStaticArrays(($id << Block::INTERNAL_METADATA_BITS) | $meta, $block); } private function fillStaticArrays(int $index, Block $block) : void{ @@ -943,14 +943,14 @@ class BlockFactory{ * Deserializes a block from the provided legacy ID and legacy meta. */ public function get(int $id, int $meta) : Block{ - if($meta < 0 or $meta > 0xf){ + if($meta < 0 or $meta > (1 << Block::INTERNAL_METADATA_BITS)){ throw new \InvalidArgumentException("Block meta value $meta is out of bounds"); } /** @var Block|null $block */ $block = null; try{ - $index = ($id << 4) | $meta; + $index = ($id << Block::INTERNAL_METADATA_BITS) | $meta; if($this->fullList[$index] !== null){ $block = clone $this->fullList[$index]; } @@ -966,14 +966,14 @@ class BlockFactory{ } public function fromFullBlock(int $fullState) : Block{ - return $this->get($fullState >> 4, $fullState & 0xf); + return $this->get($fullState >> Block::INTERNAL_METADATA_BITS, $fullState & Block::INTERNAL_METADATA_MASK); } /** * Returns whether a specified block state is already registered in the block factory. */ public function isRegistered(int $id, int $meta = 0) : bool{ - $b = $this->fullList[($id << 4) | $meta]; + $b = $this->fullList[($id << Block::INTERNAL_METADATA_BITS) | $meta]; return $b !== null and !($b instanceof UnknownBlock); } diff --git a/src/network/mcpe/convert/RuntimeBlockMapping.php b/src/network/mcpe/convert/RuntimeBlockMapping.php index 00c18cbf74..91359f4519 100644 --- a/src/network/mcpe/convert/RuntimeBlockMapping.php +++ b/src/network/mcpe/convert/RuntimeBlockMapping.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\convert; +use pocketmine\block\Block; use pocketmine\block\BlockLegacyIds; use pocketmine\data\bedrock\LegacyBlockIdToStringIdMap; use pocketmine\nbt\tag\CompoundTag; @@ -110,7 +111,7 @@ final class RuntimeBlockMapping{ } public function toRuntimeId(int $internalStateId) : int{ - return $this->legacyToRuntimeMap[$internalStateId] ?? $this->legacyToRuntimeMap[BlockLegacyIds::INFO_UPDATE << 4]; + return $this->legacyToRuntimeMap[$internalStateId] ?? $this->legacyToRuntimeMap[BlockLegacyIds::INFO_UPDATE << Block::INTERNAL_METADATA_BITS]; } public function fromRuntimeId(int $runtimeId) : int{ @@ -118,8 +119,8 @@ final class RuntimeBlockMapping{ } private function registerMapping(int $staticRuntimeId, int $legacyId, int $legacyMeta) : void{ - $this->legacyToRuntimeMap[($legacyId << 4) | $legacyMeta] = $staticRuntimeId; - $this->runtimeToLegacyMap[$staticRuntimeId] = ($legacyId << 4) | $legacyMeta; + $this->legacyToRuntimeMap[($legacyId << Block::INTERNAL_METADATA_BITS) | $legacyMeta] = $staticRuntimeId; + $this->runtimeToLegacyMap[$staticRuntimeId] = ($legacyId << Block::INTERNAL_METADATA_BITS) | $legacyMeta; } /** diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index e666a675ed..a43cd4a8bf 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -26,6 +26,7 @@ declare(strict_types=1); namespace pocketmine\world\format; +use pocketmine\block\Block; use pocketmine\block\BlockLegacyIds; use pocketmine\block\tile\Tile; use pocketmine\data\bedrock\BiomeIds; @@ -86,7 +87,7 @@ class Chunk{ $this->subChunks = new \SplFixedArray(Chunk::MAX_SUBCHUNKS); foreach($this->subChunks as $y => $null){ - $this->subChunks[$y] = $subChunks[$y] ?? new SubChunk(BlockLegacyIds::AIR << 4, []); + $this->subChunks[$y] = $subChunks[$y] ?? new SubChunk(BlockLegacyIds::AIR << Block::INTERNAL_METADATA_BITS, []); } $val = ($this->subChunks->getSize() * 16); @@ -366,7 +367,7 @@ class Chunk{ throw new \InvalidArgumentException("Invalid subchunk Y coordinate $y"); } - $this->subChunks[$y] = $subChunk ?? new SubChunk(BlockLegacyIds::AIR << 4, []); + $this->subChunks[$y] = $subChunk ?? new SubChunk(BlockLegacyIds::AIR << Block::INTERNAL_METADATA_BITS, []); $this->setDirtyFlag(self::DIRTY_FLAG_TERRAIN, true); } diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 1adf76db94..53df6a190e 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\format\io\leveldb; +use pocketmine\block\Block; use pocketmine\block\BlockLegacyIds; use pocketmine\data\bedrock\LegacyBlockIdToStringIdMap; use pocketmine\nbt\LittleEndianNbtSerializer; @@ -176,7 +177,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ //we really need a proper state fixer, but this is a pressing issue. $data = 0; } - $palette[] = ($id << 4) | $data; + $palette[] = ($id << Block::INTERNAL_METADATA_BITS) | $data; } //TODO: exceptions @@ -219,9 +220,9 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $blockId = $value & 0xff; $blockData = ($value >> 8) & 0xf; if(!isset($extraDataLayers[$ySub])){ - $extraDataLayers[$ySub] = new PalettedBlockArray(BlockLegacyIds::AIR << 4); + $extraDataLayers[$ySub] = new PalettedBlockArray(BlockLegacyIds::AIR << Block::INTERNAL_METADATA_BITS); } - $extraDataLayers[$ySub]->set($x, $y, $z, ($blockId << 4) | $blockData); + $extraDataLayers[$ySub]->set($x, $y, $z, ($blockId << Block::INTERNAL_METADATA_BITS) | $blockData); } return $extraDataLayers; @@ -301,14 +302,14 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $storages[] = $convertedLegacyExtraData[$y]; } - $subChunks[$y] = new SubChunk(BlockLegacyIds::AIR << 4, $storages); + $subChunks[$y] = new SubChunk(BlockLegacyIds::AIR << Block::INTERNAL_METADATA_BITS, $storages); break; case 1: //paletted v1, has a single blockstorage $storages = [$this->deserializePaletted($binaryStream)]; if(isset($convertedLegacyExtraData[$y])){ $storages[] = $convertedLegacyExtraData[$y]; } - $subChunks[$y] = new SubChunk(BlockLegacyIds::AIR << 4, $storages); + $subChunks[$y] = new SubChunk(BlockLegacyIds::AIR << Block::INTERNAL_METADATA_BITS, $storages); break; case 8: //legacy extradata layers intentionally ignored because they aren't supposed to exist in v8 @@ -319,7 +320,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ for($k = 0; $k < $storageCount; ++$k){ $storages[] = $this->deserializePaletted($binaryStream); } - $subChunks[$y] = new SubChunk(BlockLegacyIds::AIR << 4, $storages); + $subChunks[$y] = new SubChunk(BlockLegacyIds::AIR << Block::INTERNAL_METADATA_BITS, $storages); } break; default: @@ -362,7 +363,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ if(isset($convertedLegacyExtraData[$yy])){ $storages[] = $convertedLegacyExtraData[$yy]; } - $subChunks[$yy] = new SubChunk(BlockLegacyIds::AIR << 4, $storages); + $subChunks[$yy] = new SubChunk(BlockLegacyIds::AIR << Block::INTERNAL_METADATA_BITS, $storages); } try{ @@ -446,9 +447,9 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $tags = []; foreach($palette as $p){ $tags[] = new TreeRoot(CompoundTag::create() - ->setString("name", $idMap->legacyToString($p >> 4) ?? "minecraft:info_update") - ->setInt("oldid", $p >> 4) //PM only (debugging), vanilla doesn't have this - ->setShort("val", $p & 0xf)); + ->setString("name", $idMap->legacyToString($p >> Block::INTERNAL_METADATA_BITS) ?? "minecraft:info_update") + ->setInt("oldid", $p >> Block::INTERNAL_METADATA_BITS) //PM only (debugging), vanilla doesn't have this + ->setShort("val", $p & Block::INTERNAL_METADATA_MASK)); } $subStream->put((new LittleEndianNbtSerializer())->writeMultiple($tags)); diff --git a/src/world/format/io/region/Anvil.php b/src/world/format/io/region/Anvil.php index 36fdcfda23..12e907d205 100644 --- a/src/world/format/io/region/Anvil.php +++ b/src/world/format/io/region/Anvil.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\format\io\region; +use pocketmine\block\Block; use pocketmine\block\BlockLegacyIds; use pocketmine\nbt\tag\CompoundTag; use pocketmine\world\format\io\SubChunkConverter; @@ -32,7 +33,7 @@ class Anvil extends RegionWorldProvider{ use LegacyAnvilChunkTrait; protected function deserializeSubChunk(CompoundTag $subChunk) : SubChunk{ - return new SubChunk(BlockLegacyIds::AIR << 4, [SubChunkConverter::convertSubChunkYZX( + return new SubChunk(BlockLegacyIds::AIR << Block::INTERNAL_METADATA_BITS, [SubChunkConverter::convertSubChunkYZX( self::readFixedSizeByteArray($subChunk, "Blocks", 4096), self::readFixedSizeByteArray($subChunk, "Data", 2048) )]); diff --git a/src/world/format/io/region/McRegion.php b/src/world/format/io/region/McRegion.php index 2b2b683849..9f9b3977e3 100644 --- a/src/world/format/io/region/McRegion.php +++ b/src/world/format/io/region/McRegion.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\format\io\region; +use pocketmine\block\Block; use pocketmine\block\BlockLegacyIds; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NbtDataException; @@ -63,7 +64,7 @@ class McRegion extends RegionWorldProvider{ $fullData = self::readFixedSizeByteArray($chunk, "Data", 16384); for($y = 0; $y < 8; ++$y){ - $subChunks[$y] = new SubChunk(BlockLegacyIds::AIR << 4, [SubChunkConverter::convertSubChunkFromLegacyColumn($fullIds, $fullData, $y)]); + $subChunks[$y] = new SubChunk(BlockLegacyIds::AIR << Block::INTERNAL_METADATA_BITS, [SubChunkConverter::convertSubChunkFromLegacyColumn($fullIds, $fullData, $y)]); } $makeBiomeArray = function(string $biomeIds) : BiomeArray{ diff --git a/src/world/format/io/region/PMAnvil.php b/src/world/format/io/region/PMAnvil.php index 58de81d121..299d597c94 100644 --- a/src/world/format/io/region/PMAnvil.php +++ b/src/world/format/io/region/PMAnvil.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\format\io\region; +use pocketmine\block\Block; use pocketmine\block\BlockLegacyIds; use pocketmine\nbt\tag\CompoundTag; use pocketmine\world\format\io\SubChunkConverter; @@ -36,7 +37,7 @@ class PMAnvil extends RegionWorldProvider{ use LegacyAnvilChunkTrait; protected function deserializeSubChunk(CompoundTag $subChunk) : SubChunk{ - return new SubChunk(BlockLegacyIds::AIR << 4, [SubChunkConverter::convertSubChunkXZY( + return new SubChunk(BlockLegacyIds::AIR << Block::INTERNAL_METADATA_BITS, [SubChunkConverter::convertSubChunkXZY( self::readFixedSizeByteArray($subChunk, "Blocks", 4096), self::readFixedSizeByteArray($subChunk, "Data", 2048) )]); diff --git a/tests/phpunit/block/regenerate_consistency_check.php b/tests/phpunit/block/regenerate_consistency_check.php index aac5194c9c..8160ff6cc5 100644 --- a/tests/phpunit/block/regenerate_consistency_check.php +++ b/tests/phpunit/block/regenerate_consistency_check.php @@ -36,14 +36,14 @@ $new = array_map( ); foreach($old as $k => $name){ if(!isset($new[$k])){ - echo "Removed state for $name (" . ($k >> 4) . ":" . ($k & 0xf) . ")\n"; + echo "Removed state for $name (" . ($k >> \pocketmine\block\Block::INTERNAL_METADATA_BITS) . ":" . ($k & \pocketmine\block\Block::INTERNAL_METADATA_MASK) . ")\n"; } } foreach($new as $k => $name){ if(!isset($old[$k])){ - echo "Added state for $name (" . ($k >> 4) . ":" . ($k & 0xf) . ")\n"; + echo "Added state for $name (" . ($k >> \pocketmine\block\Block::INTERNAL_METADATA_BITS) . ":" . ($k & \pocketmine\block\Block::INTERNAL_METADATA_MASK) . ")\n"; }elseif($old[$k] !== $name){ - echo "Name changed (" . ($k >> 4) . ":" . ($k & 0xf) . "): " . $old[$k] . " -> " . $name . "\n"; + echo "Name changed (" . ($k >> \pocketmine\block\Block::INTERNAL_METADATA_BITS) . ":" . ($k & \pocketmine\block\Block::INTERNAL_METADATA_MASK) . "): " . $old[$k] . " -> " . $name . "\n"; } } file_put_contents(__DIR__ . '/block_factory_consistency_check.json', json_encode( From ec6103d61e8154aab211c12c7b89286c29525819 Mon Sep 17 00:00:00 2001 From: Jason Date: Thu, 17 Jun 2021 10:37:02 -0400 Subject: [PATCH 2539/3224] Leaves can now be silk touched, closes #3714 (#4240) --- src/block/Leaves.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/block/Leaves.php b/src/block/Leaves.php index 9f14d8d4eb..42ce2b0122 100644 --- a/src/block/Leaves.php +++ b/src/block/Leaves.php @@ -136,9 +136,9 @@ class Leaves extends Transparent{ return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - public function getDrops(Item $item) : array{ + public function getDropsForCompatibleTool(Item $item) : array{ if(($item->getBlockToolType() & BlockToolType::SHEARS) !== 0){ - return $this->getDropsForCompatibleTool($item); + return parent::getDropsForCompatibleTool($item); } $drops = []; @@ -152,6 +152,10 @@ class Leaves extends Transparent{ return $drops; } + public function isAffectedBySilkTouch() : bool{ + return true; + } + public function getFlameEncouragement() : int{ return 30; } From 43f71d0d63039e9b245c83b6b880eebcae3af290 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 17 Jun 2021 20:45:47 +0100 Subject: [PATCH 2540/3224] FormatConverter: Copy worlds for backup if rename fails this can fail if the backups directory points to a different drive than the original worlds location. In this case, we have to copy and delete the files instead, which is much slower, but works. I REALLY advise against putting backups on a different mount point than worlds if you plan to convert large worlds. --- src/utils/Filesystem.php | 51 +++++++++++++++++++++++++ src/world/format/io/FormatConverter.php | 13 ++++++- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/utils/Filesystem.php b/src/utils/Filesystem.php index b899cb8f57..531becc78b 100644 --- a/src/utils/Filesystem.php +++ b/src/utils/Filesystem.php @@ -23,8 +23,11 @@ declare(strict_types=1); namespace pocketmine\utils; +use function copy; +use function dirname; use function fclose; use function fflush; +use function file_exists; use function flock; use function fopen; use function ftruncate; @@ -33,6 +36,7 @@ use function getmypid; use function is_dir; use function is_file; use function ltrim; +use function mkdir; use function preg_match; use function realpath; use function rmdir; @@ -88,6 +92,53 @@ final class Filesystem{ } } + /** + * Recursively copies a directory to a new location. The parent directories for the destination must exist. + */ + public static function recursiveCopy(string $origin, string $destination) : void{ + if(!is_dir($origin)){ + throw new \RuntimeException("$origin does not exist, or is not a directory"); + } + if(!is_dir($destination)){ + if(file_exists($destination)){ + throw new \RuntimeException("$destination already exists, and is not a directory"); + } + if(!is_dir(dirname($destination))){ + //if the parent dir doesn't exist, the user most likely made a mistake + throw new \RuntimeException("The parent directory of $destination does not exist, or is not a directory"); + } + if(!@mkdir($destination) && !is_dir($destination)){ + throw new \RuntimeException("Failed to create output directory $destination (permission denied?)"); + } + } + self::recursiveCopyInternal($origin, $destination); + } + + private static function recursiveCopyInternal(string $origin, string $destination) : void{ + if(is_dir($origin)){ + if(!is_dir($destination)){ + if(file_exists($destination)){ + throw new \RuntimeException("Path $destination does not exist, or is not a directory"); + } + mkdir($destination); //TODO: access permissions? + } + $objects = scandir($origin, SCANDIR_SORT_NONE); + if($objects === false) throw new AssumptionFailedError("scandir() shouldn't return false when is_dir() returns true"); + foreach($objects as $object){ + if($object === "." || $object === ".."){ + continue; + } + self::recursiveCopyInternal($origin . "/" . $object, $destination . "/" . $object); + } + }else{ + $dirName = dirname($destination); + if(!is_dir($dirName)){ //the destination folder should already exist + throw new AssumptionFailedError("The destination folder should have been created in the parent call"); + } + copy($origin, $destination); + } + } + public static function addCleanedPath(string $path, string $replacement) : void{ self::$cleanedPaths[$path] = $replacement; uksort(self::$cleanedPaths, function(string $str1, string $str2) : int{ diff --git a/src/world/format/io/FormatConverter.php b/src/world/format/io/FormatConverter.php index b8d113082e..2dfc5b624e 100644 --- a/src/world/format/io/FormatConverter.php +++ b/src/world/format/io/FormatConverter.php @@ -91,8 +91,17 @@ class FormatConverter{ $new->close(); $this->logger->info("Backing up pre-conversion world to " . $this->backupPath); - rename($path, $this->backupPath); - rename($new->getPath(), $path); + if(!@rename($path, $this->backupPath)){ + $this->logger->warning("Moving old world files for backup failed, attempting copy instead. This might take a long time."); + Filesystem::recursiveCopy($path, $this->backupPath); + Filesystem::recursiveUnlink($path); + } + if(!@rename($new->getPath(), $path)){ + //we don't expect this to happen because worlds/ should most likely be all on the same FS, but just in case... + $this->logger->debug("Relocation of new world files to location failed, attempting copy and delete instead"); + Filesystem::recursiveCopy($new->getPath(), $path); + Filesystem::recursiveUnlink($new->getPath()); + } $this->logger->info("Conversion completed"); /** From 71a4ea2a95a25f3d457a0b0850f16cdfc8b3c167 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 17 Jun 2021 20:59:40 +0100 Subject: [PATCH 2541/3224] FastChunkSerializer: remove useless variable initialization --- src/world/format/io/FastChunkSerializer.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index a0ea61188e..c60c1bf56c 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -113,7 +113,6 @@ final class FastChunkSerializer{ $terrainPopulated = (bool) ($flags & self::FLAG_POPULATED); $subChunks = []; - $biomeIds = null; $heightMap = null; $count = $stream->getByte(); From 15e5bdb2102200530197d86d7e63e361bdd4393c Mon Sep 17 00:00:00 2001 From: Jason Date: Thu, 17 Jun 2021 16:05:24 -0400 Subject: [PATCH 2542/3224] BaseInventory::addItem(item1,item2,item3) now has the same behaviour as multiple separate addItem() calls (#4237) fixes #1412 --- src/inventory/InventoryHelpersTrait.php | 60 ++++++++++--------- tests/phpunit/inventory/BaseInventoryTest.php | 38 ++++++++++++ 2 files changed, 69 insertions(+), 29 deletions(-) diff --git a/src/inventory/InventoryHelpersTrait.php b/src/inventory/InventoryHelpersTrait.php index 0ce6f22dd2..881a65d738 100644 --- a/src/inventory/InventoryHelpersTrait.php +++ b/src/inventory/InventoryHelpersTrait.php @@ -144,6 +144,20 @@ trait InventoryHelpersTrait{ } } + /** @var Item[] $returnSlots */ + $returnSlots = []; + + foreach($itemSlots as $item){ + $leftover = $this->internalAddItem($item); + if(!$leftover->isNull()){ + $returnSlots[] = $leftover; + } + } + + return $returnSlots; + } + + private function internalAddItem(Item $slot) : Item{ $emptySlots = []; for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ @@ -152,43 +166,31 @@ trait InventoryHelpersTrait{ $emptySlots[] = $i; } - foreach($itemSlots as $index => $slot){ - if($slot->equals($item) and $item->getCount() < $item->getMaxStackSize()){ - $amount = min($item->getMaxStackSize() - $item->getCount(), $slot->getCount(), $this->getMaxStackSize()); - if($amount > 0){ - $slot->setCount($slot->getCount() - $amount); - $item->setCount($item->getCount() + $amount); - $this->setItem($i, $item); - if($slot->getCount() <= 0){ - unset($itemSlots[$index]); - } + if($slot->equals($item) and $item->getCount() < $item->getMaxStackSize()){ + $amount = min($item->getMaxStackSize() - $item->getCount(), $slot->getCount(), $this->getMaxStackSize()); + if($amount > 0){ + $slot->setCount($slot->getCount() - $amount); + $item->setCount($item->getCount() + $amount); + $this->setItem($i, $item); + if($slot->getCount() <= 0){ + break; } } } + } - if(count($itemSlots) === 0){ + if(count($emptySlots) > 0){ + foreach($emptySlots as $slotIndex){ + $amount = min($slot->getMaxStackSize(), $slot->getCount(), $this->getMaxStackSize()); + $slot->setCount($slot->getCount() - $amount); + $item = clone $slot; + $item->setCount($amount); + $this->setItem($slotIndex, $item); break; } } - if(count($itemSlots) > 0 and count($emptySlots) > 0){ - foreach($emptySlots as $slotIndex){ - //This loop only gets the first item, then goes to the next empty slot - foreach($itemSlots as $index => $slot){ - $amount = min($slot->getMaxStackSize(), $slot->getCount(), $this->getMaxStackSize()); - $slot->setCount($slot->getCount() - $amount); - $item = clone $slot; - $item->setCount($amount); - $this->setItem($slotIndex, $item); - if($slot->getCount() <= 0){ - unset($itemSlots[$index]); - } - break; - } - } - } - - return $itemSlots; + return $slot; } public function removeItem(Item ...$slots) : array{ diff --git a/tests/phpunit/inventory/BaseInventoryTest.php b/tests/phpunit/inventory/BaseInventoryTest.php index 5f3d39b66f..89c65c8138 100644 --- a/tests/phpunit/inventory/BaseInventoryTest.php +++ b/tests/phpunit/inventory/BaseInventoryTest.php @@ -24,8 +24,10 @@ declare(strict_types=1); namespace pocketmine\inventory; use PHPUnit\Framework\TestCase; +use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\ItemIds; +use pocketmine\item\VanillaItems; class BaseInventoryTest extends TestCase{ @@ -47,4 +49,40 @@ class BaseInventoryTest extends TestCase{ self::assertFalse($inv->canAddItem($item1), "Item WITH userdata should not stack with item WITHOUT userdata"); self::assertNotEmpty($inv->addItem($item1)); } + + /** + * @return Item[] + */ + private function getTestItems() : array{ + return [ + VanillaItems::APPLE()->setCount(16), + VanillaItems::APPLE()->setCount(16), + VanillaItems::APPLE()->setCount(16), + VanillaItems::APPLE()->setCount(16) + ]; + } + + public function testAddMultipleItemsInOneCall() : void{ + $inventory = new class(1) extends SimpleInventory{ + + }; + $leftover = $inventory->addItem(...$this->getTestItems()); + self::assertCount(0, $leftover); + self::assertTrue($inventory->getItem(0)->equalsExact(VanillaItems::APPLE()->setCount(64))); + } + + public function testAddMultipleItemsInOneCallWithLeftover() : void{ + $inventory = new class(1) extends SimpleInventory{}; + $inventory->setItem(0, VanillaItems::APPLE()->setCount(20)); + $leftover = $inventory->addItem(...$this->getTestItems()); + self::assertCount(2, $leftover); //the leftovers are not currently stacked - if they were given separately, they'll be returned separately + self::assertTrue($inventory->getItem(0)->equalsExact(VanillaItems::APPLE()->setCount(64))); + + $leftoverCount = 0; + foreach($leftover as $item){ + self::assertTrue($item->equals(VanillaItems::APPLE())); + $leftoverCount += $item->getCount(); + } + self::assertSame(20, $leftoverCount); + } } From f1583f44df82d50d7f08aad58844a170e2679398 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 17 Jun 2021 22:21:35 +0100 Subject: [PATCH 2543/3224] LightArray: Avoid allocating 7 useless arrays for every node processed instead, use a const array of the offsets and add them to the coordinates, which avoids the allocations. In synthetic benchmarks, this method takes 40-50% less CPU time by eliding ZEND_INIT_ARRAY and ZEND_ADD_ARRAY opcodes. In practice, the benefit will likely be much smaller (perhaps even irrelevant). --- src/world/light/LightUpdate.php | 45 +++++++++++++-------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/src/world/light/LightUpdate.php b/src/world/light/LightUpdate.php index bc98e5b53a..2a531a89f3 100644 --- a/src/world/light/LightUpdate.php +++ b/src/world/light/LightUpdate.php @@ -31,6 +31,14 @@ use function max; //TODO: make light updates asynchronous abstract class LightUpdate{ + private const ADJACENTS = [ + [ 1, 0, 0], + [-1, 0, 0], + [ 0, 1, 0], + [ 0, -1, 0], + [ 0, 0, 1], + [ 0, 0, -1] + ]; /** * @var \SplFixedArray|int[] @@ -76,15 +84,8 @@ abstract class LightUpdate{ protected function getHighestAdjacentLight(int $x, int $y, int $z) : int{ $adjacent = 0; - foreach([ - [$x + 1, $y, $z], - [$x - 1, $y, $z], - [$x, $y + 1, $z], - [$x, $y - 1, $z], - [$x, $y, $z + 1], - [$x, $y, $z - 1] - ] as [$x1, $y1, $z1]){ - if(($adjacent = max($adjacent, $this->getEffectiveLight($x1, $y1, $z1))) === 15){ + foreach(self::ADJACENTS as [$ox, $oy, $oz]){ + if(($adjacent = max($adjacent, $this->getEffectiveLight($x + $ox, $y + $oy, $z + $oz))) === 15){ break; } } @@ -125,16 +126,11 @@ abstract class LightUpdate{ $touched++; [$x, $y, $z, $oldAdjacentLight] = $context->removalQueue->dequeue(); - $points = [ - [$x + 1, $y, $z], - [$x - 1, $y, $z], - [$x, $y + 1, $z], - [$x, $y - 1, $z], - [$x, $y, $z + 1], - [$x, $y, $z - 1] - ]; + foreach(self::ADJACENTS as [$ox, $oy, $oz]){ + $cx = $x + $ox; + $cy = $y + $oy; + $cz = $z + $oz; - foreach($points as [$cx, $cy, $cz]){ if($this->subChunkExplorer->moveTo($cx, $cy, $cz) !== SubChunkExplorerStatus::INVALID){ $this->computeRemoveLight($cx, $cy, $cz, $oldAdjacentLight, $context); }elseif($this->getEffectiveLight($cx, $cy, $cz) > 0 and !isset($context->spreadVisited[$index = World::blockHash($cx, $cy, $cz)])){ @@ -155,16 +151,11 @@ abstract class LightUpdate{ continue; } - $points = [ - [$x + 1, $y, $z], - [$x - 1, $y, $z], - [$x, $y + 1, $z], - [$x, $y - 1, $z], - [$x, $y, $z + 1], - [$x, $y, $z - 1] - ]; + foreach(self::ADJACENTS as [$ox, $oy, $oz]){ + $cx = $x + $ox; + $cy = $y + $oy; + $cz = $z + $oz; - foreach($points as [$cx, $cy, $cz]){ if($this->subChunkExplorer->moveTo($cx, $cy, $cz) !== SubChunkExplorerStatus::INVALID){ $this->computeSpreadLight($cx, $cy, $cz, $newAdjacentLight, $context); } From d96fc17339fe45f01ebc8fedcd7872de4158aa65 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 18 Jun 2021 19:07:38 +0100 Subject: [PATCH 2544/3224] World: Check placed block collision boxes after place() since we write these into a transaction instead of actually modifying the world directly, we can use the transaction to verify that the placement location is OK before setting the blocks. closes #4248 --- src/world/World.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index fbb351a79b..9abea832e4 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1795,9 +1795,17 @@ class World implements ChunkManager{ return false; } - foreach($hand->getCollisionBoxes() as $collisionBox){ - if(count($this->getCollidingEntities($collisionBox)) > 0){ - return false; //Entity in block + $tx = new BlockTransaction($this); + if(!$hand->place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ + return false; + } + + foreach($tx->getBlocks() as [$x, $y, $z, $block]){ + $block->position($this, $x, $y, $z); + foreach($block->getCollisionBoxes() as $collisionBox){ + if(count($entities = $this->getCollidingEntities($collisionBox)) > 0){ + return false; //Entity in block + } } } @@ -1829,8 +1837,7 @@ class World implements ChunkManager{ } } - $tx = new BlockTransaction($this); - if(!$hand->place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player) or !$tx->apply()){ + if(!$tx->apply()){ return false; } foreach($tx->getBlocks() as [$x, $y, $z, $_]){ From 745f455bd225971802b918848703ccaef235f139 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 18 Jun 2021 19:10:50 +0100 Subject: [PATCH 2545/3224] Door: change thickness to match MCPE since MCPE-19214 still hasn't been fixed after all these years, it's safe to say they won't fix it in the near future, and this causes placement glitches in PM. --- src/block/Door.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/block/Door.php b/src/block/Door.php index 7b421aeaf1..7fc3d2fd8b 100644 --- a/src/block/Door.php +++ b/src/block/Door.php @@ -115,7 +115,8 @@ class Door extends Transparent{ * @return AxisAlignedBB[] */ protected function recalculateCollisionBoxes() : array{ - return [AxisAlignedBB::one()->trim($this->open ? Facing::rotateY($this->facing, !$this->hingeRight) : $this->facing, 13 / 16)]; + //TODO: doors are 0.1825 blocks thick, instead of 0.1875 like JE (https://bugs.mojang.com/browse/MCPE-19214) + return [AxisAlignedBB::one()->trim($this->open ? Facing::rotateY($this->facing, !$this->hingeRight) : $this->facing, 327 / 400)]; } public function onNearbyBlockChange() : void{ From 11b483f2dc46d27ef66d91559495cae55c660309 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 19 Jun 2021 18:45:21 +0100 Subject: [PATCH 2546/3224] Inline EntityDataHelper::createBaseNBT() this is only used for saving entity data now, and its presence here is allowing plugin devs to keep abusing it. --- src/entity/Entity.php | 19 ++++++++++++++++++- src/entity/EntityDataHelper.php | 21 --------------------- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 4d4442c632..a020c56d65 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -40,6 +40,9 @@ use pocketmine\math\Facing; use pocketmine\math\Vector2; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\tag\DoubleTag; +use pocketmine\nbt\tag\FloatTag; +use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\protocol\AddActorPacket; use pocketmine\network\mcpe\protocol\MoveActorAbsolutePacket; @@ -459,7 +462,21 @@ abstract class Entity{ } public function saveNBT() : CompoundTag{ - $nbt = EntityDataHelper::createBaseNBT($this->location, $this->motion, $this->location->yaw, $this->location->pitch); + $nbt = CompoundTag::create() + ->setTag("Pos", new ListTag([ + new DoubleTag($this->location->x), + new DoubleTag($this->location->y), + new DoubleTag($this->location->z) + ])) + ->setTag("Motion", new ListTag([ + new DoubleTag($this->motion->x), + new DoubleTag($this->motion->y), + new DoubleTag($this->motion->z) + ])) + ->setTag("Rotation", new ListTag([ + new FloatTag($this->location->yaw), + new FloatTag($this->location->pitch) + ])); if(!($this instanceof Player)){ EntityFactory::getInstance()->injectSaveId(get_class($this), $nbt); diff --git a/src/entity/EntityDataHelper.php b/src/entity/EntityDataHelper.php index e4632aa076..f58fef743d 100644 --- a/src/entity/EntityDataHelper.php +++ b/src/entity/EntityDataHelper.php @@ -69,25 +69,4 @@ final class EntityDataHelper{ } return new Vector3($values[0]->getValue(), $values[1]->getValue(), $values[2]->getValue()); } - - /** - * Helper function which creates minimal NBT needed to spawn an entity. - */ - public static function createBaseNBT(Vector3 $pos, ?Vector3 $motion = null, float $yaw = 0.0, float $pitch = 0.0) : CompoundTag{ - return CompoundTag::create() - ->setTag("Pos", new ListTag([ - new DoubleTag($pos->x), - new DoubleTag($pos->y), - new DoubleTag($pos->z) - ])) - ->setTag("Motion", new ListTag([ - new DoubleTag($motion !== null ? $motion->x : 0.0), - new DoubleTag($motion !== null ? $motion->y : 0.0), - new DoubleTag($motion !== null ? $motion->z : 0.0) - ])) - ->setTag("Rotation", new ListTag([ - new FloatTag($yaw), - new FloatTag($pitch) - ])); - } } From 981b0285d1ae23557f8926c5b4abf7158bea06b9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 19 Jun 2021 19:14:02 +0100 Subject: [PATCH 2547/3224] Isolate config casting nastiness in one place this doesn't solve the underlying problem, but it does reduce the amount of noise made by PHPStan about it, as well as avoiding code litter. --- src/CrashDump.php | 6 +- src/MemoryManager.php | 28 ++++----- src/Server.php | 50 +++++++-------- src/ServerConfigGroup.php | 12 ++++ src/command/defaults/TimingsCommand.php | 2 +- src/network/mcpe/NetworkSession.php | 2 +- src/network/mcpe/raklib/RakLibInterface.php | 2 +- src/network/query/QueryInfo.php | 2 +- src/player/Player.php | 8 +-- src/stats/SendUsageTask.php | 2 +- src/updater/AutoUpdater.php | 6 +- src/world/World.php | 8 +-- .../check-explicit-mixed-baseline.neon | 61 +------------------ 13 files changed, 73 insertions(+), 116 deletions(-) diff --git a/src/CrashDump.php b/src/CrashDump.php index 1e22ba99a4..6758ba8845 100644 --- a/src/CrashDump.php +++ b/src/CrashDump.php @@ -191,7 +191,7 @@ class CrashDump{ private function extraData() : void{ global $argv; - if($this->server->getConfigGroup()->getProperty("auto-report.send-settings", true) !== false){ + if($this->server->getConfigGroup()->getPropertyBool("auto-report.send-settings", true)){ $this->data["parameters"] = (array) $argv; if(($serverDotProperties = @file_get_contents($this->server->getDataPath() . "server.properties")) !== false){ $this->data["server.properties"] = preg_replace("#^rcon\\.password=(.*)$#m", "rcon.password=******", $serverDotProperties); @@ -214,7 +214,7 @@ class CrashDump{ } $this->data["extensions"] = $extensions; - if($this->server->getConfigGroup()->getProperty("auto-report.send-phpinfo", true) !== false){ + if($this->server->getConfigGroup()->getPropertyBool("auto-report.send-phpinfo", true)){ ob_start(); phpinfo(); $this->data["phpinfo"] = ob_get_contents(); @@ -276,7 +276,7 @@ class CrashDump{ $this->addLine("Code:"); $this->data["code"] = []; - if($this->server->getConfigGroup()->getProperty("auto-report.send-code", true) !== false and file_exists($error["fullFile"])){ + if($this->server->getConfigGroup()->getPropertyBool("auto-report.send-code", true) and file_exists($error["fullFile"])){ $file = @file($error["fullFile"], FILE_IGNORE_NEW_LINES); if($file !== false){ for($l = max(0, $error["line"] - 10); $l < $error["line"] + 10 and isset($file[$l]); ++$l){ diff --git a/src/MemoryManager.php b/src/MemoryManager.php index 0097c88327..b54eed878d 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -123,7 +123,7 @@ class MemoryManager{ } private function init(ServerConfigGroup $config) : void{ - $this->memoryLimit = ((int) $config->getProperty("memory.main-limit", 0)) * 1024 * 1024; + $this->memoryLimit = $config->getPropertyInt("memory.main-limit", 0) * 1024 * 1024; $defaultMemory = 1024; @@ -149,7 +149,7 @@ class MemoryManager{ } } - $hardLimit = ((int) $config->getProperty("memory.main-hard-limit", $defaultMemory)); + $hardLimit = $config->getPropertyInt("memory.main-hard-limit", $defaultMemory); if($hardLimit <= 0){ ini_set("memory_limit", '-1'); @@ -157,22 +157,22 @@ class MemoryManager{ ini_set("memory_limit", $hardLimit . "M"); } - $this->globalMemoryLimit = ((int) $config->getProperty("memory.global-limit", 0)) * 1024 * 1024; - $this->checkRate = (int) $config->getProperty("memory.check-rate", 20); - $this->continuousTrigger = (bool) $config->getProperty("memory.continuous-trigger", true); - $this->continuousTriggerRate = (int) $config->getProperty("memory.continuous-trigger-rate", 30); + $this->globalMemoryLimit = $config->getPropertyInt("memory.global-limit", 0) * 1024 * 1024; + $this->checkRate = $config->getPropertyInt("memory.check-rate", 20); + $this->continuousTrigger = $config->getPropertyBool("memory.continuous-trigger", true); + $this->continuousTriggerRate = $config->getPropertyInt("memory.continuous-trigger-rate", 30); - $this->garbageCollectionPeriod = (int) $config->getProperty("memory.garbage-collection.period", 36000); - $this->garbageCollectionTrigger = (bool) $config->getProperty("memory.garbage-collection.low-memory-trigger", true); - $this->garbageCollectionAsync = (bool) $config->getProperty("memory.garbage-collection.collect-async-worker", true); + $this->garbageCollectionPeriod = $config->getPropertyInt("memory.garbage-collection.period", 36000); + $this->garbageCollectionTrigger = $config->getPropertyBool("memory.garbage-collection.low-memory-trigger", true); + $this->garbageCollectionAsync = $config->getPropertyBool("memory.garbage-collection.collect-async-worker", true); - $this->lowMemChunkRadiusOverride = (int) $config->getProperty("memory.max-chunks.chunk-radius", 4); - $this->lowMemChunkGC = (bool) $config->getProperty("memory.max-chunks.trigger-chunk-collect", true); + $this->lowMemChunkRadiusOverride = $config->getPropertyInt("memory.max-chunks.chunk-radius", 4); + $this->lowMemChunkGC = $config->getPropertyBool("memory.max-chunks.trigger-chunk-collect", true); - $this->lowMemDisableChunkCache = (bool) $config->getProperty("memory.world-caches.disable-chunk-cache", true); - $this->lowMemClearWorldCache = (bool) $config->getProperty("memory.world-caches.low-memory-trigger", true); + $this->lowMemDisableChunkCache = $config->getPropertyBool("memory.world-caches.disable-chunk-cache", true); + $this->lowMemClearWorldCache = $config->getPropertyBool("memory.world-caches.low-memory-trigger", true); - $this->dumpWorkers = (bool) $config->getProperty("memory.memory-dump.dump-async-worker", true); + $this->dumpWorkers = $config->getPropertyBool("memory.memory-dump.dump-async-worker", true); gc_enable(); } diff --git a/src/Server.php b/src/Server.php index 0ebbc6e07a..512354548f 100644 --- a/src/Server.php +++ b/src/Server.php @@ -496,7 +496,7 @@ class Server{ } public function shouldSavePlayerData() : bool{ - return (bool) $this->configGroup->getProperty("player.save-player-data", true); + return $this->configGroup->getPropertyBool("player.save-player-data", true); } /** @@ -858,13 +858,13 @@ class Server{ ]) ); - $debugLogLevel = (int) $this->configGroup->getProperty("debug.level", 1); + $debugLogLevel = $this->configGroup->getPropertyInt("debug.level", 1); if($this->logger instanceof MainLogger){ $this->logger->setLogDebug($debugLogLevel > 1); } - $this->forceLanguage = (bool) $this->configGroup->getProperty("settings.force-language", false); - $selectedLang = $this->configGroup->getConfigString("language", $this->configGroup->getProperty("settings.language", Language::FALLBACK_LANGUAGE)); + $this->forceLanguage = $this->configGroup->getPropertyBool("settings.force-language", false); + $selectedLang = $this->configGroup->getConfigString("language", $this->configGroup->getPropertyString("settings.language", Language::FALLBACK_LANGUAGE)); try{ $this->language = new Language($selectedLang); }catch(LanguageNotFoundException $e){ @@ -880,7 +880,7 @@ class Server{ $this->logger->info($this->getLanguage()->translateString("language.selected", [$this->getLanguage()->getName(), $this->getLanguage()->getLang()])); if(VersionInfo::IS_DEVELOPMENT_BUILD){ - if(!((bool) $this->configGroup->getProperty("settings.enable-dev-builds", false))){ + if(!$this->configGroup->getPropertyBool("settings.enable-dev-builds", false)){ $this->logger->emergency($this->language->translateString("pocketmine.server.devBuild.error1", [VersionInfo::NAME])); $this->logger->emergency($this->language->translateString("pocketmine.server.devBuild.error2")); $this->logger->emergency($this->language->translateString("pocketmine.server.devBuild.error3")); @@ -902,7 +902,7 @@ class Server{ $this->logger->info($this->getLanguage()->translateString("pocketmine.server.start", [TextFormat::AQUA . $this->getVersion() . TextFormat::RESET])); - if(($poolSize = $this->configGroup->getProperty("settings.async-workers", "auto")) === "auto"){ + if(($poolSize = $this->configGroup->getPropertyString("settings.async-workers", "auto")) === "auto"){ $poolSize = 2; $processors = Utils::getCoreCount() - 2; @@ -913,25 +913,25 @@ class Server{ $poolSize = max(1, (int) $poolSize); } - $this->asyncPool = new AsyncPool($poolSize, max(-1, (int) $this->configGroup->getProperty("memory.async-worker-hard-limit", 256)), $this->autoloader, $this->logger, $this->tickSleeper); + $this->asyncPool = new AsyncPool($poolSize, max(-1, $this->configGroup->getPropertyInt("memory.async-worker-hard-limit", 256)), $this->autoloader, $this->logger, $this->tickSleeper); $netCompressionThreshold = -1; - if($this->configGroup->getProperty("network.batch-threshold", 256) >= 0){ - $netCompressionThreshold = (int) $this->configGroup->getProperty("network.batch-threshold", 256); + if($this->configGroup->getPropertyInt("network.batch-threshold", 256) >= 0){ + $netCompressionThreshold = $this->configGroup->getPropertyInt("network.batch-threshold", 256); } - $netCompressionLevel = (int) $this->configGroup->getProperty("network.compression-level", 6); + $netCompressionLevel = $this->configGroup->getPropertyInt("network.compression-level", 6); if($netCompressionLevel < 1 or $netCompressionLevel > 9){ $this->logger->warning("Invalid network compression level $netCompressionLevel set, setting to default 6"); $netCompressionLevel = 6; } ZlibCompressor::setInstance(new ZlibCompressor($netCompressionLevel, $netCompressionThreshold, ZlibCompressor::DEFAULT_MAX_DECOMPRESSION_SIZE)); - $this->networkCompressionAsync = (bool) $this->configGroup->getProperty("network.async-compression", true); + $this->networkCompressionAsync = $this->configGroup->getPropertyBool("network.async-compression", true); - EncryptionContext::$ENABLED = (bool) $this->configGroup->getProperty("network.enable-encryption", true); + EncryptionContext::$ENABLED = $this->configGroup->getPropertyBool("network.enable-encryption", true); - $this->doTitleTick = ((bool) $this->configGroup->getProperty("console.title-tick", true)) && Terminal::hasFormattingCodes(); + $this->doTitleTick = $this->configGroup->getPropertyBool("console.title-tick", true) && Terminal::hasFormattingCodes(); $this->operators = new Config($this->dataPath . "ops.txt", Config::ENUM); $this->whitelist = new Config($this->dataPath . "white-list.txt", Config::ENUM); @@ -977,8 +977,8 @@ class Server{ $this->logger->info($this->getLanguage()->translateString("pocketmine.server.license", [$this->getName()])); Timings::init(); - TimingsHandler::setEnabled((bool) $this->configGroup->getProperty("settings.enable-profiling", false)); - $this->profilingTickRate = (float) $this->configGroup->getProperty("settings.profile-report-trigger", 20); + TimingsHandler::setEnabled($this->configGroup->getPropertyBool("settings.enable-profiling", false)); + $this->profilingTickRate = $this->configGroup->getPropertyInt("settings.profile-report-trigger", 20); DefaultPermissions::registerCorePermissions(); @@ -1000,13 +1000,13 @@ class Server{ $this->forceShutdown(); return; } - $this->pluginManager = new PluginManager($this, ((bool) $this->configGroup->getProperty("plugins.legacy-data-dir", true)) ? null : $this->getDataPath() . "plugin_data" . DIRECTORY_SEPARATOR, $pluginGraylist); + $this->pluginManager = new PluginManager($this, $this->configGroup->getPropertyBool("plugins.legacy-data-dir", true) ? null : $this->getDataPath() . "plugin_data" . DIRECTORY_SEPARATOR, $pluginGraylist); $this->pluginManager->registerInterface(new PharPluginLoader($this->autoloader)); $this->pluginManager->registerInterface(new ScriptPluginLoader()); $providerManager = new WorldProviderManager(); if( - ($format = $providerManager->getProviderByName($formatName = (string) $this->configGroup->getProperty("level-settings.default-format"))) !== null and + ($format = $providerManager->getProviderByName($formatName = $this->configGroup->getPropertyString("level-settings.default-format", ""))) !== null and is_a($format, WritableWorldProvider::class, true) ){ $providerManager->setDefault($format); @@ -1016,9 +1016,9 @@ class Server{ $this->worldManager = new WorldManager($this, $this->dataPath . "/worlds", $providerManager); $this->worldManager->setAutoSave($this->configGroup->getConfigBool("auto-save", $this->worldManager->getAutoSave())); - $this->worldManager->setAutoSaveInterval((int) $this->configGroup->getProperty("ticks-per.autosave", 6000)); + $this->worldManager->setAutoSaveInterval($this->configGroup->getPropertyInt("ticks-per.autosave", 6000)); - $this->updater = new AutoUpdater($this, $this->configGroup->getProperty("auto-updater.host", "update.pmmp.io")); + $this->updater = new AutoUpdater($this, $this->configGroup->getPropertyString("auto-updater.host", "update.pmmp.io")); $this->queryInfo = new QueryInfo($this); @@ -1107,11 +1107,11 @@ class Server{ $this->network->blockAddress($entry->getName(), -1); } - if((bool) $this->configGroup->getProperty("network.upnp-forwarding", false)){ + if($this->configGroup->getPropertyBool("network.upnp-forwarding", false)){ $this->network->registerInterface(new UPnPNetworkInterface($this->logger, Internet::getInternalIP(), $this->getPort())); } - if((bool) $this->configGroup->getProperty("settings.send-usage", true)){ + if($this->configGroup->getPropertyBool("settings.send-usage", true)){ $this->sendUsageTicker = 6000; $this->sendUsage(SendUsageTask::TYPE_OPEN); } @@ -1396,7 +1396,7 @@ class Server{ } if($this->network instanceof Network){ - $this->network->getSessionManager()->close($this->configGroup->getProperty("settings.shutdown-message", "Server closed")); + $this->network->getSessionManager()->close($this->configGroup->getPropertyString("settings.shutdown-message", "Server closed")); } if($this->worldManager instanceof WorldManager){ @@ -1501,7 +1501,7 @@ class Server{ $this->logger->emergency($this->getLanguage()->translateString("pocketmine.crash.submit", [$dump->getPath()])); - if($this->configGroup->getProperty("auto-report.enabled", true) !== false){ + if($this->configGroup->getPropertyBool("auto-report.enabled", true)){ $report = true; $stamp = $this->getDataPath() . "crashdumps/.last_crash"; @@ -1530,7 +1530,7 @@ class Server{ } if($report){ - $url = ((bool) $this->configGroup->getProperty("auto-report.use-https", true) ? "https" : "http") . "://" . $this->configGroup->getProperty("auto-report.host", "crash.pmmp.io") . "/submit/api"; + $url = ($this->configGroup->getPropertyBool("auto-report.use-https", true) ? "https" : "http") . "://" . $this->configGroup->getPropertyString("auto-report.host", "crash.pmmp.io") . "/submit/api"; $postUrlError = "Unknown error"; $reply = Internet::postURL($url, [ "report" => "yes", @@ -1616,7 +1616,7 @@ class Server{ } public function sendUsage(int $type = SendUsageTask::TYPE_STATUS) : void{ - if((bool) $this->configGroup->getProperty("anonymous-statistics.enabled", true)){ + if($this->configGroup->getPropertyBool("anonymous-statistics.enabled", true)){ $this->asyncPool->submitTask(new SendUsageTask($this, $type, $this->uniquePlayers)); } $this->uniquePlayers = []; diff --git a/src/ServerConfigGroup.php b/src/ServerConfigGroup.php index 88d2bc441d..1965e0d7fb 100644 --- a/src/ServerConfigGroup.php +++ b/src/ServerConfigGroup.php @@ -65,6 +65,18 @@ final class ServerConfigGroup{ return $this->propertyCache[$variable] ?? $defaultValue; } + public function getPropertyBool(string $variable, bool $defaultValue) : bool{ + return (bool) $this->getProperty($variable, $defaultValue); + } + + public function getPropertyInt(string $variable, int $defaultValue) : int{ + return (int) $this->getProperty($variable, $defaultValue); + } + + public function getPropertyString(string $variable, string $defaultValue) : string{ + return (string) $this->getProperty($variable, $defaultValue); + } + public function getConfigString(string $variable, string $defaultValue = "") : string{ $v = getopt("", ["$variable::"]); if(isset($v[$variable])){ diff --git a/src/command/defaults/TimingsCommand.php b/src/command/defaults/TimingsCommand.php index 3c3fbf6700..bcdd3ea102 100644 --- a/src/command/defaults/TimingsCommand.php +++ b/src/command/defaults/TimingsCommand.php @@ -131,7 +131,7 @@ class TimingsCommand extends VanillaCommand{ ]; fclose($fileTimings); - $host = $sender->getServer()->getConfigGroup()->getProperty("timings.host", "timings.pmmp.io"); + $host = $sender->getServer()->getConfigGroup()->getPropertyString("timings.host", "timings.pmmp.io"); $sender->getServer()->getAsyncPool()->submitTask(new BulkCurlTask( [new BulkCurlTaskOperation( diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index cea24cb9c8..9ba761abd3 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -595,7 +595,7 @@ class NetworkSession{ } $this->logger->debug("Xbox Live authenticated: " . ($this->authenticated ? "YES" : "NO")); - $checkXUID = (bool) $this->server->getConfigGroup()->getProperty("player.verify-xuid", true); + $checkXUID = $this->server->getConfigGroup()->getPropertyBool("player.verify-xuid", true); $myXUID = $this->info instanceof XboxLivePlayerInfo ? $this->info->getXuid() : ""; $kickForXUIDMismatch = function(string $xuid) use ($checkXUID, $myXUID) : bool{ if($checkXUID && $myXUID !== $xuid){ diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 5eb5d40dd7..9a5b38ceb2 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -103,7 +103,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ $threadToMainBuffer, new InternetAddress($this->server->getIp(), $this->server->getPort(), 4), $this->rakServerId, - (int) $this->server->getConfigGroup()->getProperty("network.max-mtu-size", 1492), + $this->server->getConfigGroup()->getPropertyInt("network.max-mtu-size", 1492), self::MCPE_RAKNET_PROTOCOL_VERSION, $this->sleeper ); diff --git a/src/network/query/QueryInfo.php b/src/network/query/QueryInfo.php index 47e95eedac..25d07f549d 100644 --- a/src/network/query/QueryInfo.php +++ b/src/network/query/QueryInfo.php @@ -77,7 +77,7 @@ final class QueryInfo{ public function __construct(Server $server){ $this->serverName = $server->getMotd(); - $this->listPlugins = (bool) $server->getConfigGroup()->getProperty("settings.query-plugins", true); + $this->listPlugins = $server->getConfigGroup()->getPropertyBool("settings.query-plugins", true); $this->plugins = $server->getPluginManager()->getPlugins(); $this->players = $server->getOnlinePlayers(); diff --git a/src/player/Player.php b/src/player/Player.php index 9cf9ba72d1..983c860100 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -281,8 +281,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $rootPermissions[DefaultPermissions::ROOT_OPERATOR] = true; } $this->perm = new PermissibleBase($rootPermissions); - $this->chunksPerTick = (int) $this->server->getConfigGroup()->getProperty("chunk-sending.per-tick", 4); - $this->spawnThreshold = (int) (($this->server->getConfigGroup()->getProperty("chunk-sending.spawn-radius", 4) ** 2) * M_PI); + $this->chunksPerTick = $this->server->getConfigGroup()->getPropertyInt("chunk-sending.per-tick", 4); + $this->spawnThreshold = (int) (($this->server->getConfigGroup()->getPropertyInt("chunk-sending.spawn-radius", 4) ** 2) * M_PI); $this->chunkSelector = new ChunkSelector(); $this->chunkLoader = new PlayerChunkLoader($spawnLocation); @@ -502,7 +502,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ public function setViewDistance(int $distance) : void{ $this->viewDistance = $this->server->getAllowedViewDistance($distance); - $this->spawnThreshold = (int) (min($this->viewDistance, $this->server->getConfigGroup()->getProperty("chunk-sending.spawn-radius", 4)) ** 2 * M_PI); + $this->spawnThreshold = (int) (min($this->viewDistance, $this->server->getConfigGroup()->getPropertyInt("chunk-sending.spawn-radius", 4)) ** 2 * M_PI); $this->nextChunkOrderRun = 0; @@ -806,7 +806,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->spawnToAll(); - if($this->server->getUpdater()->hasUpdate() and $this->hasPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE) and $this->server->getConfigGroup()->getProperty("auto-updater.on-update.warn-ops", true)){ + if($this->server->getUpdater()->hasUpdate() and $this->hasPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE) and $this->server->getConfigGroup()->getPropertyBool("auto-updater.on-update.warn-ops", true)){ $this->server->getUpdater()->showPlayerUpdate($this); } diff --git a/src/stats/SendUsageTask.php b/src/stats/SendUsageTask.php index c29eb60bc5..7516797326 100644 --- a/src/stats/SendUsageTask.php +++ b/src/stats/SendUsageTask.php @@ -60,7 +60,7 @@ class SendUsageTask extends AsyncTask{ * @phpstan-param array $playerList */ public function __construct(Server $server, int $type, array $playerList = []){ - $endpoint = "http://" . $server->getConfigGroup()->getProperty("anonymous-statistics.host", "stats.pocketmine.net") . "/"; + $endpoint = "http://" . $server->getConfigGroup()->getPropertyString("anonymous-statistics.host", "stats.pocketmine.net") . "/"; $data = []; $data["uniqueServerId"] = $server->getServerUniqueId()->toString(); diff --git a/src/updater/AutoUpdater.php b/src/updater/AutoUpdater.php index 9ca12b85e2..34ed5b7c10 100644 --- a/src/updater/AutoUpdater.php +++ b/src/updater/AutoUpdater.php @@ -55,7 +55,7 @@ class AutoUpdater{ $this->logger = new \PrefixedLogger($server->getLogger(), "Auto Updater"); $this->endpoint = "http://$endpoint/api/"; - if((bool) $server->getConfigGroup()->getProperty("auto-updater.enabled", true)){ + if($server->getConfigGroup()->getPropertyBool("auto-updater.enabled", true)){ $this->doCheck(); } } @@ -72,7 +72,7 @@ class AutoUpdater{ $this->checkUpdate(); if($this->hasUpdate()){ (new UpdateNotifyEvent($this))->call(); - if((bool) $this->server->getConfigGroup()->getProperty("auto-updater.on-update.warn-console", true)){ + if($this->server->getConfigGroup()->getPropertyBool("auto-updater.on-update.warn-console", true)){ $this->showConsoleUpdate(); } }else{ @@ -178,7 +178,7 @@ class AutoUpdater{ * Returns the channel used for update checking (stable, beta, dev) */ public function getChannel() : string{ - $channel = strtolower($this->server->getConfigGroup()->getProperty("auto-updater.preferred-channel", "stable")); + $channel = strtolower($this->server->getConfigGroup()->getPropertyString("auto-updater.preferred-channel", "stable")); if($channel !== "stable" and $channel !== "beta" and $channel !== "alpha" and $channel !== "development"){ $channel = "stable"; } diff --git a/src/world/World.php b/src/world/World.php index 9abea832e4..06acb48715 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -428,10 +428,10 @@ class World implements ChunkManager{ $this->time = $this->provider->getWorldData()->getTime(); $cfg = $this->server->getConfigGroup(); - $this->chunkTickRadius = min($this->server->getViewDistance(), max(1, (int) $cfg->getProperty("chunk-ticking.tick-radius", 4))); - $this->chunksPerTick = (int) $cfg->getProperty("chunk-ticking.per-tick", 40); - $this->tickedBlocksPerSubchunkPerTick = (int) $cfg->getProperty("chunk-ticking.blocks-per-subchunk-per-tick", self::DEFAULT_TICKED_BLOCKS_PER_SUBCHUNK_PER_TICK); - $this->maxConcurrentChunkPopulationTasks = (int) $cfg->getProperty("chunk-generation.population-queue-size", 2); + $this->chunkTickRadius = min($this->server->getViewDistance(), max(1, $cfg->getPropertyInt("chunk-ticking.tick-radius", 4))); + $this->chunksPerTick = $cfg->getPropertyInt("chunk-ticking.per-tick", 40); + $this->tickedBlocksPerSubchunkPerTick = $cfg->getPropertyInt("chunk-ticking.blocks-per-subchunk-per-tick", self::DEFAULT_TICKED_BLOCKS_PER_SUBCHUNK_PER_TICK); + $this->maxConcurrentChunkPopulationTasks = $cfg->getPropertyInt("chunk-generation.population-queue-size", 2); $dontTickBlocks = array_fill_keys($cfg->getProperty("chunk-ticking.disable-block-ticking", []), true); diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index 5f1245f45c..f439301715 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -15,29 +15,14 @@ parameters: count: 1 path: ../../../src/CrashDump.php - - - message: "#^Cannot cast mixed to int\\.$#" - count: 7 - path: ../../../src/MemoryManager.php - - message: "#^Cannot access offset 'type' on mixed\\.$#" count: 1 path: ../../../src/Server.php - - - message: "#^Cannot cast mixed to float\\.$#" - count: 1 - path: ../../../src/Server.php - - - - message: "#^Cannot cast mixed to int\\.$#" - count: 6 - path: ../../../src/Server.php - - message: "#^Cannot cast mixed to string\\.$#" - count: 2 + count: 1 path: ../../../src/Server.php - @@ -45,29 +30,14 @@ parameters: count: 1 path: ../../../src/Server.php - - - message: "#^Parameter \\#1 \\$reason of method pocketmine\\\\network\\\\NetworkSessionManager\\:\\:close\\(\\) expects string, mixed given\\.$#" - count: 1 - path: ../../../src/Server.php - - - - message: "#^Parameter \\#2 \\$defaultValue of method pocketmine\\\\ServerConfigGroup\\:\\:getConfigString\\(\\) expects string, mixed given\\.$#" - count: 1 - path: ../../../src/Server.php - - - - message: "#^Parameter \\#2 \\$endpoint of class pocketmine\\\\updater\\\\AutoUpdater constructor expects string, mixed given\\.$#" - count: 1 - path: ../../../src/Server.php - - message: "#^Cannot cast mixed to int\\.$#" - count: 1 + count: 2 path: ../../../src/ServerConfigGroup.php - message: "#^Cannot cast mixed to string\\.$#" - count: 1 + count: 2 path: ../../../src/ServerConfigGroup.php - @@ -80,11 +50,6 @@ parameters: count: 2 path: ../../../src/VersionInfo.php - - - message: "#^Part \\$host \\(mixed\\) of encapsed string cannot be cast to string\\.$#" - count: 1 - path: ../../../src/command/defaults/TimingsCommand.php - - message: "#^Cannot cast mixed to float\\.$#" count: 1 @@ -115,11 +80,6 @@ parameters: count: 1 path: ../../../src/network/mcpe/raklib/PthreadsChannelReader.php - - - message: "#^Cannot cast mixed to int\\.$#" - count: 1 - path: ../../../src/network/mcpe/raklib/RakLibInterface.php - - message: "#^Parameter \\#1 \\$value of static method pocketmine\\\\permission\\\\PermissionParser\\:\\:defaultFromString\\(\\) expects bool\\|string, mixed given\\.$#" count: 1 @@ -130,11 +90,6 @@ parameters: count: 1 path: ../../../src/permission/PermissionParser.php - - - message: "#^Cannot cast mixed to int\\.$#" - count: 1 - path: ../../../src/player/Player.php - - message: "#^Parameter \\#1 \\$description of method pocketmine\\\\command\\\\Command\\:\\:setDescription\\(\\) expects string, mixed given\\.$#" count: 1 @@ -240,11 +195,6 @@ parameters: count: 1 path: ../../../src/timings/TimingsHandler.php - - - message: "#^Parameter \\#1 \\$str of function strtolower expects string, mixed given\\.$#" - count: 1 - path: ../../../src/updater/AutoUpdater.php - - message: "#^Parameter \\#2 \\$start of function substr expects int, mixed given\\.$#" count: 1 @@ -285,11 +235,6 @@ parameters: count: 1 path: ../../../src/utils/Utils.php - - - message: "#^Cannot cast mixed to int\\.$#" - count: 4 - path: ../../../src/world/World.php - - message: "#^Parameter \\#1 \\$keys of function array_fill_keys expects array, mixed given\\.$#" count: 1 From fc70b625b362ac2af48f21b5d239cdfdc4d9cf07 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 19 Jun 2021 19:42:13 +0100 Subject: [PATCH 2548/3224] ExperienceOrb: Require providing XP value in constructor --- src/entity/EntityFactory.php | 10 +++++++++- src/entity/object/ExperienceOrb.php | 17 +++++++---------- src/world/World.php | 3 +-- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index d33dc442d1..4724e4ebc9 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -47,6 +47,7 @@ use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; +use pocketmine\nbt\tag\ShortTag; use pocketmine\nbt\tag\StringTag; use pocketmine\utils\SingletonTrait; use pocketmine\utils\Utils; @@ -93,7 +94,14 @@ final class EntityFactory{ }, ['ThrownExpBottle', 'minecraft:xp_bottle'], EntityLegacyIds::XP_BOTTLE); $this->register(ExperienceOrb::class, function(World $world, CompoundTag $nbt) : ExperienceOrb{ - return new ExperienceOrb(EntityDataHelper::parseLocation($nbt, $world), $nbt); + $value = 1; + if(($valuePcTag = $nbt->getTag(ExperienceOrb::TAG_VALUE_PC)) instanceof ShortTag){ //PC + $value = $valuePcTag->getValue(); + }elseif(($valuePeTag = $nbt->getTag(ExperienceOrb::TAG_VALUE_PE)) instanceof IntTag){ //PE save format + $value = $valuePeTag->getValue(); + } + + return new ExperienceOrb(EntityDataHelper::parseLocation($nbt, $world), $value, $nbt); }, ['XPOrb', 'minecraft:xp_orb'], EntityLegacyIds::XP_ORB); $this->register(FallingBlock::class, function(World $world, CompoundTag $nbt) : FallingBlock{ diff --git a/src/entity/object/ExperienceOrb.php b/src/entity/object/ExperienceOrb.php index c3f0b63827..8076dd9e7b 100644 --- a/src/entity/object/ExperienceOrb.php +++ b/src/entity/object/ExperienceOrb.php @@ -26,6 +26,7 @@ namespace pocketmine\entity\object; use pocketmine\entity\Entity; use pocketmine\entity\EntitySizeInfo; use pocketmine\entity\Human; +use pocketmine\entity\Location; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ShortTag; @@ -98,7 +99,12 @@ class ExperienceOrb extends Entity{ protected $targetPlayerRuntimeId = null; /** @var int */ - protected $xpValue = 1; + protected $xpValue; + + public function __construct(Location $location, int $xpValue, ?CompoundTag $nbt = null){ + $this->xpValue = $xpValue; + parent::__construct($location, $nbt); + } protected function getInitialSizeInfo() : EntitySizeInfo{ return new EntitySizeInfo(0.25, 0.25); } @@ -106,15 +112,6 @@ class ExperienceOrb extends Entity{ parent::initEntity($nbt); $this->age = $nbt->getShort("Age", 0); - - $value = 1; - if(($valuePcTag = $nbt->getTag(self::TAG_VALUE_PC)) instanceof ShortTag){ //PC - $value = $valuePcTag->getValue(); - }elseif(($valuePeTag = $nbt->getTag(self::TAG_VALUE_PE)) instanceof IntTag){ //PE save format - $value = $valuePeTag->getValue(); - } - - $this->setXpValue($value); } public function saveNBT() : CompoundTag{ diff --git a/src/world/World.php b/src/world/World.php index 06acb48715..acaf2866b6 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1616,9 +1616,8 @@ class World implements ChunkManager{ $orbs = []; foreach(ExperienceOrb::splitIntoOrbSizes($amount) as $split){ - $orb = new ExperienceOrb(Location::fromObject($pos, $this, lcg_value() * 360, 0)); + $orb = new ExperienceOrb(Location::fromObject($pos, $this, lcg_value() * 360, 0), $split); - $orb->setXpValue($split); $orb->setMotion(new Vector3((lcg_value() * 0.2 - 0.1) * 2, lcg_value() * 0.4, (lcg_value() * 0.2 - 0.1) * 2)); $orb->spawnToAll(); From 6fea09ded4d6297b651965be5090700bb08377ab Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 19 Jun 2021 19:47:44 +0100 Subject: [PATCH 2549/3224] SplashPotion: Require potionId in constructor --- src/entity/EntityFactory.php | 4 +++- src/entity/projectile/SplashPotion.php | 11 ++++++----- src/item/SplashPotion.php | 4 +--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index 4724e4ebc9..f40c7ce359 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -41,6 +41,7 @@ use pocketmine\entity\projectile\ExperienceBottle; use pocketmine\entity\projectile\Snowball; use pocketmine\entity\projectile\SplashPotion; use pocketmine\item\Item; +use pocketmine\item\Potion; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\nbt\NbtDataException; @@ -147,7 +148,8 @@ final class EntityFactory{ }, ['Snowball', 'minecraft:snowball'], EntityLegacyIds::SNOWBALL); $this->register(SplashPotion::class, function(World $world, CompoundTag $nbt) : SplashPotion{ - return new SplashPotion(EntityDataHelper::parseLocation($nbt, $world), null, $nbt); + $potionType = $nbt->getShort("PotionId", Potion::WATER); + return new SplashPotion(EntityDataHelper::parseLocation($nbt, $world), null, $potionType, $nbt); }, ['ThrownPotion', 'minecraft:potion', 'thrownpotion'], EntityLegacyIds::SPLASH_POTION); $this->register(Squid::class, function(World $world, CompoundTag $nbt) : Squid{ diff --git a/src/entity/projectile/SplashPotion.php b/src/entity/projectile/SplashPotion.php index 7fea391afc..8cde812823 100644 --- a/src/entity/projectile/SplashPotion.php +++ b/src/entity/projectile/SplashPotion.php @@ -28,7 +28,9 @@ use pocketmine\block\VanillaBlocks; use pocketmine\color\Color; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\InstantEffect; +use pocketmine\entity\Entity; use pocketmine\entity\Living; +use pocketmine\entity\Location; use pocketmine\event\entity\ProjectileHitBlockEvent; use pocketmine\event\entity\ProjectileHitEntityEvent; use pocketmine\event\entity\ProjectileHitEvent; @@ -54,12 +56,11 @@ class SplashPotion extends Throwable{ /** @var bool */ protected $linger = false; /** @var int */ - protected $potionId = Potion::WATER; + protected $potionId; - protected function initEntity(CompoundTag $nbt) : void{ - parent::initEntity($nbt); - - $this->setPotionId($nbt->getShort("PotionId", Potion::WATER)); + public function __construct(Location $location, ?Entity $shootingEntity, int $potionId, ?CompoundTag $nbt = null){ + $this->potionId = $potionId; + parent::__construct($location, $shootingEntity, $nbt); } public function saveNBT() : CompoundTag{ diff --git a/src/item/SplashPotion.php b/src/item/SplashPotion.php index 72d553e2f0..b1330875aa 100644 --- a/src/item/SplashPotion.php +++ b/src/item/SplashPotion.php @@ -43,9 +43,7 @@ class SplashPotion extends ProjectileItem{ } protected function createEntity(Location $location, Player $thrower) : Throwable{ - $projectile = new SplashPotionEntity($location, $thrower); - $projectile->setPotionId($this->potionId); - return $projectile; + return new SplashPotionEntity($location, $thrower, $this->potionId); } public function getThrowForce() : float{ From c07f3f5e12ec202d6450621d16557db03de88aff Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 19 Jun 2021 19:48:30 +0100 Subject: [PATCH 2550/3224] fix CS --- src/entity/object/ExperienceOrb.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/entity/object/ExperienceOrb.php b/src/entity/object/ExperienceOrb.php index 8076dd9e7b..8011a6a47a 100644 --- a/src/entity/object/ExperienceOrb.php +++ b/src/entity/object/ExperienceOrb.php @@ -28,8 +28,6 @@ use pocketmine\entity\EntitySizeInfo; use pocketmine\entity\Human; use pocketmine\entity\Location; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\IntTag; -use pocketmine\nbt\tag\ShortTag; use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; From 908fa5f901227855a87988c0f944a94b937af7a0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 19 Jun 2021 19:53:51 +0100 Subject: [PATCH 2551/3224] changelog: rewrite a whole lot of confusing bullshit EntityFactory doesn't exist at all on PM3, so mentioning changes in its behaviour here is only going to confuse people. --- changelogs/4.0-snapshot.md | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 19dc5f6471..6ecfa8c79d 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -395,18 +395,30 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Entity->initEntity()` now accepts a `CompoundTag` parameter. #### Entity creation -- Runtime entity creation no longer requires `EntityFactory` - just use `new YourEntity` instead. -- Entity constructors no longer require `CompoundTag`. You can now make your entity constructors have any signature you want. -- `EntityFactory` now requires a creation callback (usually a closure) with the signature `function(World, CompoundTag) : Entity` to construct entities loaded from disk. This is required to allow entity classes to have custom constructor signatures. This callback should do any necessary actions to transform NBT into constructor parameters. - - Example: `ItemEntity` now requires an `Item` in its constructor, so its creation callback decodes the `Item` from the NBT to be passed to the constructor. - - Example: `Painting` now requires a `PaintingMotive` in its constructor, so its creation callback decides which `PaintingMotive` to provide based on the NBT it receives. - - See `EntityFactory` for more examples. -- `EntityFactory`'s responsibility as runtime entity creator has been removed. It's now solely responsible for restoring entities saved on disk. -- Registering entities will now throw exceptions on error cases instead of returning `false`. +- `Entity::createEntity()` has been removed. It's no longer needed for creating new entities at runtime - just use `new YourEntity` instead. +- `Entity` subclass constructors can now have any signature, just like a normal class. +- Loading entities from NBT is now handled by `EntityFactory`. It works quite a bit differently than `Entity::createEntity()` did. Instead of registering `YourEntity::class` to a set of Minecraft save IDs, you now need to provide a callback which will construct an entity when given some NBT and a `World`. + - The creation callback is registered using `EntityFactory::register()`. + - The creation callback must have the signature `function(World, CompoundTag) : Entity`. + - This enables `Entity` subclasses to have any constructor parameters they like. + - It also allows requiring that certain data is always provided (for example, it doesn't make much sense to create a `FallingBlock` without specifying what type of block). + - Examples: + - `ItemEntity` now requires an `Item` in its constructor, so its creation callback decodes the `Item` from the NBT to be passed to the constructor. + - `Painting` now requires a `PaintingMotive` in its constructor, so its creation callback decides which `PaintingMotive` to provide based on the NBT it receives. + - See `EntityFactory` for more examples. +- `EntityFactory::register()` (previously `Entity::registerEntity()`) will now throw exceptions on error cases instead of returning `false`. - The following API methods have been moved: - `Entity::registerEntity()` -> `EntityFactory::register()` - - `Entity::createBaseNBT()` -> `EntityDataHelper::createBaseNBT()` +- The following classes have changed constructors: + - All projectile subclasses now require a `?Entity $thrower` parameter. + - `Arrow->__construct()` now requires a `bool $critical` parameter (in addition to the `$thrower` parameter). + - `ExperienceOrb->__construct()` now requires a `int $xpValue` parameter. + - `FallingBlock->__construct()` now requires a `Block $block` parameter. + - `ItemEntity->__construct()` now requires an `Item $item` parameter. + - `Painting->__construct()` now requires a `PaintingMotive $motive` parameter. + - `SplashPotion->__construct()` now requires a `int $potionId` parameter. - The following API methods have been removed: + - `Entity::createBaseNBT()`: `new YourEntity` and appropriate API methods should be used instead - `Entity->getSaveId()` - `Entity::getKnownEntityTypes()` - `Entity::createEntity()`: use `new YourEntity` instead (to be reviewed) From 5387456e44f0724b2603d8ece4bf201fb46674a4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 19 Jun 2021 21:39:23 +0100 Subject: [PATCH 2552/3224] Move potion types to enum --- src/data/bedrock/PotionTypeIdMap.php | 99 +++++++++++ src/data/bedrock/PotionTypeIds.php | 64 +++++++ src/entity/EntityFactory.php | 9 +- src/entity/projectile/SplashPotion.php | 25 +-- src/item/ItemFactory.php | 8 +- src/item/Potion.php | 235 +------------------------ src/item/PotionType.php | 202 +++++++++++++++++++++ src/item/SplashPotion.php | 9 +- 8 files changed, 398 insertions(+), 253 deletions(-) create mode 100644 src/data/bedrock/PotionTypeIdMap.php create mode 100644 src/data/bedrock/PotionTypeIds.php create mode 100644 src/item/PotionType.php diff --git a/src/data/bedrock/PotionTypeIdMap.php b/src/data/bedrock/PotionTypeIdMap.php new file mode 100644 index 0000000000..d665b0222e --- /dev/null +++ b/src/data/bedrock/PotionTypeIdMap.php @@ -0,0 +1,99 @@ + + */ + private array $idToEnum; + + /** + * @var int[] + * @phpstan-var array + */ + private array $enumToId; + + private function __construct(){ + $this->register(PotionTypeIds::WATER, PotionType::WATER()); + $this->register(PotionTypeIds::MUNDANE, PotionType::MUNDANE()); + $this->register(PotionTypeIds::LONG_MUNDANE, PotionType::LONG_MUNDANE()); + $this->register(PotionTypeIds::THICK, PotionType::THICK()); + $this->register(PotionTypeIds::AWKWARD, PotionType::AWKWARD()); + $this->register(PotionTypeIds::NIGHT_VISION, PotionType::NIGHT_VISION()); + $this->register(PotionTypeIds::LONG_NIGHT_VISION, PotionType::LONG_NIGHT_VISION()); + $this->register(PotionTypeIds::INVISIBILITY, PotionType::INVISIBILITY()); + $this->register(PotionTypeIds::LONG_INVISIBILITY, PotionType::LONG_INVISIBILITY()); + $this->register(PotionTypeIds::LEAPING, PotionType::LEAPING()); + $this->register(PotionTypeIds::LONG_LEAPING, PotionType::LONG_LEAPING()); + $this->register(PotionTypeIds::STRONG_LEAPING, PotionType::STRONG_LEAPING()); + $this->register(PotionTypeIds::FIRE_RESISTANCE, PotionType::FIRE_RESISTANCE()); + $this->register(PotionTypeIds::LONG_FIRE_RESISTANCE, PotionType::LONG_FIRE_RESISTANCE()); + $this->register(PotionTypeIds::SWIFTNESS, PotionType::SWIFTNESS()); + $this->register(PotionTypeIds::LONG_SWIFTNESS, PotionType::LONG_SWIFTNESS()); + $this->register(PotionTypeIds::STRONG_SWIFTNESS, PotionType::STRONG_SWIFTNESS()); + $this->register(PotionTypeIds::SLOWNESS, PotionType::SLOWNESS()); + $this->register(PotionTypeIds::LONG_SLOWNESS, PotionType::LONG_SLOWNESS()); + $this->register(PotionTypeIds::WATER_BREATHING, PotionType::WATER_BREATHING()); + $this->register(PotionTypeIds::LONG_WATER_BREATHING, PotionType::LONG_WATER_BREATHING()); + $this->register(PotionTypeIds::HEALING, PotionType::HEALING()); + $this->register(PotionTypeIds::STRONG_HEALING, PotionType::STRONG_HEALING()); + $this->register(PotionTypeIds::HARMING, PotionType::HARMING()); + $this->register(PotionTypeIds::STRONG_HARMING, PotionType::STRONG_HARMING()); + $this->register(PotionTypeIds::POISON, PotionType::POISON()); + $this->register(PotionTypeIds::LONG_POISON, PotionType::LONG_POISON()); + $this->register(PotionTypeIds::STRONG_POISON, PotionType::STRONG_POISON()); + $this->register(PotionTypeIds::REGENERATION, PotionType::REGENERATION()); + $this->register(PotionTypeIds::LONG_REGENERATION, PotionType::LONG_REGENERATION()); + $this->register(PotionTypeIds::STRONG_REGENERATION, PotionType::STRONG_REGENERATION()); + $this->register(PotionTypeIds::STRENGTH, PotionType::STRENGTH()); + $this->register(PotionTypeIds::LONG_STRENGTH, PotionType::LONG_STRENGTH()); + $this->register(PotionTypeIds::STRONG_STRENGTH, PotionType::STRONG_STRENGTH()); + $this->register(PotionTypeIds::WEAKNESS, PotionType::WEAKNESS()); + $this->register(PotionTypeIds::LONG_WEAKNESS, PotionType::LONG_WEAKNESS()); + $this->register(PotionTypeIds::WITHER, PotionType::WITHER()); + } + + private function register(int $id, PotionType $type) : void{ + $this->idToEnum[$id] = $type; + $this->enumToId[$type->id()] = $id; + } + + public function fromId(int $id) : ?PotionType{ + return $this->idToEnum[$id] ?? null; + } + + public function toId(PotionType $type) : int{ + if(!isset($this->enumToId[$type->id()])){ + throw new \InvalidArgumentException("Type does not have a mapped ID"); + } + return $this->enumToId[$type->id()]; + } +} diff --git a/src/data/bedrock/PotionTypeIds.php b/src/data/bedrock/PotionTypeIds.php new file mode 100644 index 0000000000..41167c2d6d --- /dev/null +++ b/src/data/bedrock/PotionTypeIds.php @@ -0,0 +1,64 @@ +register(SplashPotion::class, function(World $world, CompoundTag $nbt) : SplashPotion{ - $potionType = $nbt->getShort("PotionId", Potion::WATER); + $potionType = PotionTypeIdMap::getInstance()->fromId($nbt->getShort("PotionId", PotionTypeIds::WATER)); + if($potionType === null){ + $potionType = PotionType::WATER(); //TODO: this should be an error, but we haven't registered all the types yet + } return new SplashPotion(EntityDataHelper::parseLocation($nbt, $world), null, $potionType, $nbt); }, ['ThrownPotion', 'minecraft:potion', 'thrownpotion'], EntityLegacyIds::SPLASH_POTION); diff --git a/src/entity/projectile/SplashPotion.php b/src/entity/projectile/SplashPotion.php index 8cde812823..49bb264c05 100644 --- a/src/entity/projectile/SplashPotion.php +++ b/src/entity/projectile/SplashPotion.php @@ -26,6 +26,7 @@ namespace pocketmine\entity\projectile; use pocketmine\block\BlockLegacyIds; use pocketmine\block\VanillaBlocks; use pocketmine\color\Color; +use pocketmine\data\bedrock\PotionTypeIdMap; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\InstantEffect; use pocketmine\entity\Entity; @@ -35,6 +36,7 @@ use pocketmine\event\entity\ProjectileHitBlockEvent; use pocketmine\event\entity\ProjectileHitEntityEvent; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\item\Potion; +use pocketmine\item\PotionType; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; @@ -55,17 +57,16 @@ class SplashPotion extends Throwable{ /** @var bool */ protected $linger = false; - /** @var int */ - protected $potionId; + protected PotionType $potionType; - public function __construct(Location $location, ?Entity $shootingEntity, int $potionId, ?CompoundTag $nbt = null){ - $this->potionId = $potionId; + public function __construct(Location $location, ?Entity $shootingEntity, PotionType $potionType, ?CompoundTag $nbt = null){ + $this->potionType = $potionType; parent::__construct($location, $shootingEntity, $nbt); } public function saveNBT() : CompoundTag{ $nbt = parent::saveNBT(); - $nbt->setShort("PotionId", $this->getPotionId()); + $nbt->setShort("PotionId", PotionTypeIdMap::getInstance()->toId($this->getPotionType())); return $nbt; } @@ -128,7 +129,7 @@ class SplashPotion extends Throwable{ }else{ //TODO: lingering potions } - }elseif($event instanceof ProjectileHitBlockEvent and $this->getPotionId() === Potion::WATER){ + }elseif($event instanceof ProjectileHitBlockEvent and $this->getPotionType()->equals(PotionType::WATER())){ $blockIn = $event->getBlockHit()->getSide($event->getRayTraceResult()->getHitFace()); if($blockIn->getId() === BlockLegacyIds::FIRE){ @@ -145,12 +146,12 @@ class SplashPotion extends Throwable{ /** * Returns the meta value of the potion item that this splash potion corresponds to. This decides what effects will be applied to the entity when it collides with its target. */ - public function getPotionId() : int{ - return $this->potionId; + public function getPotionType() : PotionType{ + return $this->potionType; } - public function setPotionId(int $id) : void{ - $this->potionId = $id; //TODO: validation + public function setPotionType(PotionType $type) : void{ + $this->potionType = $type; $this->networkPropertiesDirty = true; } @@ -173,13 +174,13 @@ class SplashPotion extends Throwable{ * @return EffectInstance[] */ public function getPotionEffects() : array{ - return Potion::getPotionEffectsById($this->getPotionId()); + return $this->potionType->getEffects(); } protected function syncNetworkData(EntityMetadataCollection $properties) : void{ parent::syncNetworkData($properties); - $properties->setShort(EntityMetadataProperties::POTION_AUX_VALUE, $this->potionId); + $properties->setShort(EntityMetadataProperties::POTION_AUX_VALUE, PotionTypeIdMap::getInstance()->toId($this->potionType)); $properties->setGenericFlag(EntityMetadataFlags::LINGER, $this->linger); } } diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 8cfaec10f9..64707f13e9 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -33,6 +33,7 @@ use pocketmine\block\utils\TreeType; use pocketmine\block\VanillaBlocks; use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\data\bedrock\EntityLegacyIds; +use pocketmine\data\bedrock\PotionTypeIdMap; use pocketmine\entity\Entity; use pocketmine\entity\Location; use pocketmine\entity\Squid; @@ -278,9 +279,10 @@ class ItemFactory{ ))->setColor($color)); } - foreach(Potion::ALL as $type){ - $this->register(new Potion(new ItemIdentifier(ItemIds::POTION, $type), "Potion", $type)); - $this->register(new SplashPotion(new ItemIdentifier(ItemIds::SPLASH_POTION, $type), "Splash Potion", $type)); + foreach(PotionType::getAll() as $type){ + $typeId = PotionTypeIdMap::getInstance()->toId($type); + $this->register(new Potion(new ItemIdentifier(ItemIds::POTION, $typeId), "Potion", $type)); + $this->register(new SplashPotion(new ItemIdentifier(ItemIds::SPLASH_POTION, $typeId), "Splash Potion", $type)); } foreach(TreeType::getAll() as $type){ diff --git a/src/item/Potion.php b/src/item/Potion.php index 4d4dd1b34f..13fc8640a9 100644 --- a/src/item/Potion.php +++ b/src/item/Potion.php @@ -23,242 +23,15 @@ declare(strict_types=1); namespace pocketmine\item; -use pocketmine\entity\effect\EffectInstance; -use pocketmine\entity\effect\VanillaEffects; use pocketmine\entity\Living; class Potion extends Item implements ConsumableItem{ - public const WATER = 0; - public const MUNDANE = 1; - public const LONG_MUNDANE = 2; - public const THICK = 3; - public const AWKWARD = 4; - public const NIGHT_VISION = 5; - public const LONG_NIGHT_VISION = 6; - public const INVISIBILITY = 7; - public const LONG_INVISIBILITY = 8; - public const LEAPING = 9; - public const LONG_LEAPING = 10; - public const STRONG_LEAPING = 11; - public const FIRE_RESISTANCE = 12; - public const LONG_FIRE_RESISTANCE = 13; - public const SWIFTNESS = 14; - public const LONG_SWIFTNESS = 15; - public const STRONG_SWIFTNESS = 16; - public const SLOWNESS = 17; - public const LONG_SLOWNESS = 18; - public const WATER_BREATHING = 19; - public const LONG_WATER_BREATHING = 20; - public const HEALING = 21; - public const STRONG_HEALING = 22; - public const HARMING = 23; - public const STRONG_HARMING = 24; - public const POISON = 25; - public const LONG_POISON = 26; - public const STRONG_POISON = 27; - public const REGENERATION = 28; - public const LONG_REGENERATION = 29; - public const STRONG_REGENERATION = 30; - public const STRENGTH = 31; - public const LONG_STRENGTH = 32; - public const STRONG_STRENGTH = 33; - public const WEAKNESS = 34; - public const LONG_WEAKNESS = 35; - public const WITHER = 36; + private PotionType $potionType; - public const ALL = [ - self::WATER, - self::MUNDANE, - self::LONG_MUNDANE, - self::THICK, - self::AWKWARD, - self::NIGHT_VISION, - self::LONG_NIGHT_VISION, - self::INVISIBILITY, - self::LONG_INVISIBILITY, - self::LEAPING, - self::LONG_LEAPING, - self::STRONG_LEAPING, - self::FIRE_RESISTANCE, - self::LONG_FIRE_RESISTANCE, - self::SWIFTNESS, - self::LONG_SWIFTNESS, - self::STRONG_SWIFTNESS, - self::SLOWNESS, - self::LONG_SLOWNESS, - self::WATER_BREATHING, - self::LONG_WATER_BREATHING, - self::HEALING, - self::STRONG_HEALING, - self::HARMING, - self::STRONG_HARMING, - self::POISON, - self::LONG_POISON, - self::STRONG_POISON, - self::REGENERATION, - self::LONG_REGENERATION, - self::STRONG_REGENERATION, - self::STRENGTH, - self::LONG_STRENGTH, - self::STRONG_STRENGTH, - self::WEAKNESS, - self::LONG_WEAKNESS, - self::WITHER - ]; - - /** - * Returns a list of effects applied by potions with the specified ID. - * - * @return EffectInstance[] - */ - public static function getPotionEffectsById(int $id) : array{ - switch($id){ - case self::WATER: - case self::MUNDANE: - case self::LONG_MUNDANE: - case self::THICK: - case self::AWKWARD: - return []; - case self::NIGHT_VISION: - return [ - new EffectInstance(VanillaEffects::NIGHT_VISION(), 3600) - ]; - case self::LONG_NIGHT_VISION: - return [ - new EffectInstance(VanillaEffects::NIGHT_VISION(), 9600) - ]; - case self::INVISIBILITY: - return [ - new EffectInstance(VanillaEffects::INVISIBILITY(), 3600) - ]; - case self::LONG_INVISIBILITY: - return [ - new EffectInstance(VanillaEffects::INVISIBILITY(), 9600) - ]; - case self::LEAPING: - return [ - new EffectInstance(VanillaEffects::JUMP_BOOST(), 3600) - ]; - case self::LONG_LEAPING: - return [ - new EffectInstance(VanillaEffects::JUMP_BOOST(), 9600) - ]; - case self::STRONG_LEAPING: - return [ - new EffectInstance(VanillaEffects::JUMP_BOOST(), 1800, 1) - ]; - case self::FIRE_RESISTANCE: - return [ - new EffectInstance(VanillaEffects::FIRE_RESISTANCE(), 3600) - ]; - case self::LONG_FIRE_RESISTANCE: - return [ - new EffectInstance(VanillaEffects::FIRE_RESISTANCE(), 9600) - ]; - case self::SWIFTNESS: - return [ - new EffectInstance(VanillaEffects::SPEED(), 3600) - ]; - case self::LONG_SWIFTNESS: - return [ - new EffectInstance(VanillaEffects::SPEED(), 9600) - ]; - case self::STRONG_SWIFTNESS: - return [ - new EffectInstance(VanillaEffects::SPEED(), 1800, 1) - ]; - case self::SLOWNESS: - return [ - new EffectInstance(VanillaEffects::SLOWNESS(), 1800) - ]; - case self::LONG_SLOWNESS: - return [ - new EffectInstance(VanillaEffects::SLOWNESS(), 4800) - ]; - case self::WATER_BREATHING: - return [ - new EffectInstance(VanillaEffects::WATER_BREATHING(), 3600) - ]; - case self::LONG_WATER_BREATHING: - return [ - new EffectInstance(VanillaEffects::WATER_BREATHING(), 9600) - ]; - case self::HEALING: - return [ - new EffectInstance(VanillaEffects::INSTANT_HEALTH()) - ]; - case self::STRONG_HEALING: - return [ - new EffectInstance(VanillaEffects::INSTANT_HEALTH(), null, 1) - ]; - case self::HARMING: - return [ - new EffectInstance(VanillaEffects::INSTANT_DAMAGE()) - ]; - case self::STRONG_HARMING: - return [ - new EffectInstance(VanillaEffects::INSTANT_DAMAGE(), null, 1) - ]; - case self::POISON: - return [ - new EffectInstance(VanillaEffects::POISON(), 900) - ]; - case self::LONG_POISON: - return [ - new EffectInstance(VanillaEffects::POISON(), 2400) - ]; - case self::STRONG_POISON: - return [ - new EffectInstance(VanillaEffects::POISON(), 440, 1) - ]; - case self::REGENERATION: - return [ - new EffectInstance(VanillaEffects::REGENERATION(), 900) - ]; - case self::LONG_REGENERATION: - return [ - new EffectInstance(VanillaEffects::REGENERATION(), 2400) - ]; - case self::STRONG_REGENERATION: - return [ - new EffectInstance(VanillaEffects::REGENERATION(), 440, 1) - ]; - case self::STRENGTH: - return [ - new EffectInstance(VanillaEffects::STRENGTH(), 3600) - ]; - case self::LONG_STRENGTH: - return [ - new EffectInstance(VanillaEffects::STRENGTH(), 9600) - ]; - case self::STRONG_STRENGTH: - return [ - new EffectInstance(VanillaEffects::STRENGTH(), 1800, 1) - ]; - case self::WEAKNESS: - return [ - new EffectInstance(VanillaEffects::WEAKNESS(), 1800) - ]; - case self::LONG_WEAKNESS: - return [ - new EffectInstance(VanillaEffects::WEAKNESS(), 4800) - ]; - case self::WITHER: - return [ - new EffectInstance(VanillaEffects::WITHER(), 800, 1) - ]; - } - - return []; - } - - /** @var int */ - private $potionId; - - public function __construct(ItemIdentifier $identifier, string $name, int $potionId){ + public function __construct(ItemIdentifier $identifier, string $name, PotionType $potionType){ parent::__construct($identifier, $name); - $this->potionId = $potionId; + $this->potionType = $potionType; } public function getMaxStackSize() : int{ @@ -271,7 +44,7 @@ class Potion extends Item implements ConsumableItem{ public function getAdditionalEffects() : array{ //TODO: check CustomPotionEffects NBT - return self::getPotionEffectsById($this->potionId); + return $this->potionType->getEffects(); } public function getResidue() : Item{ diff --git a/src/item/PotionType.php b/src/item/PotionType.php new file mode 100644 index 0000000000..533d297240 --- /dev/null +++ b/src/item/PotionType.php @@ -0,0 +1,202 @@ + []), + new self("mundane", fn() => []), + new self("long_mundane", fn() => []), + new self("thick", fn() => []), + new self("awkward", fn() => []), + new self("night_vision", fn() => [ + new EffectInstance(VanillaEffects::NIGHT_VISION(), 3600) + ]), + new self("long_night_vision", fn() => [ + new EffectInstance(VanillaEffects::NIGHT_VISION(), 9600) + ]), + new self("invisibility", fn() => [ + new EffectInstance(VanillaEffects::INVISIBILITY(), 3600) + ]), + new self("long_invisibility", fn() => [ + new EffectInstance(VanillaEffects::INVISIBILITY(), 9600) + ]), + new self("leaping", fn() => [ + new EffectInstance(VanillaEffects::JUMP_BOOST(), 3600) + ]), + new self("long_leaping", fn() => [ + new EffectInstance(VanillaEffects::JUMP_BOOST(), 9600) + ]), + new self("strong_leaping", fn() => [ + new EffectInstance(VanillaEffects::JUMP_BOOST(), 1800, 1) + ]), + new self("fire_resistance", fn() => [ + new EffectInstance(VanillaEffects::FIRE_RESISTANCE(), 3600) + ]), + new self("long_fire_resistance", fn() => [ + new EffectInstance(VanillaEffects::FIRE_RESISTANCE(), 9600) + ]), + new self("swiftness", fn() => [ + new EffectInstance(VanillaEffects::SPEED(), 3600) + ]), + new self("long_swiftness", fn() => [ + new EffectInstance(VanillaEffects::SPEED(), 9600) + ]), + new self("strong_swiftness", fn() => [ + new EffectInstance(VanillaEffects::SPEED(), 1800, 1) + ]), + new self("slowness", fn() => [ + new EffectInstance(VanillaEffects::SLOWNESS(), 1800) + ]), + new self("long_slowness", fn() => [ + new EffectInstance(VanillaEffects::SLOWNESS(), 4800) + ]), + new self("water_breathing", fn() => [ + new EffectInstance(VanillaEffects::WATER_BREATHING(), 3600) + ]), + new self("long_water_breathing", fn() => [ + new EffectInstance(VanillaEffects::WATER_BREATHING(), 9600) + ]), + new self("healing", fn() => [ + new EffectInstance(VanillaEffects::INSTANT_HEALTH()) + ]), + new self("strong_healing", fn() => [ + new EffectInstance(VanillaEffects::INSTANT_HEALTH(), null, 1) + ]), + new self("harming", fn() => [ + new EffectInstance(VanillaEffects::INSTANT_DAMAGE()) + ]), + new self("strong_harming", fn() => [ + new EffectInstance(VanillaEffects::INSTANT_DAMAGE(), null, 1) + ]), + new self("poison", fn() => [ + new EffectInstance(VanillaEffects::POISON(), 900) + ]), + new self("long_poison", fn() => [ + new EffectInstance(VanillaEffects::POISON(), 2400) + ]), + new self("strong_poison", fn() => [ + new EffectInstance(VanillaEffects::POISON(), 440, 1) + ]), + new self("regeneration", fn() => [ + new EffectInstance(VanillaEffects::REGENERATION(), 900) + ]), + new self("long_regeneration", fn() => [ + new EffectInstance(VanillaEffects::REGENERATION(), 2400) + ]), + new self("strong_regeneration", fn() => [ + new EffectInstance(VanillaEffects::REGENERATION(), 440, 1) + ]), + new self("strength", fn() => [ + new EffectInstance(VanillaEffects::STRENGTH(), 3600) + ]), + new self("long_strength", fn() => [ + new EffectInstance(VanillaEffects::STRENGTH(), 9600) + ]), + new self("strong_strength", fn() => [ + new EffectInstance(VanillaEffects::STRENGTH(), 1800, 1) + ]), + new self("weakness", fn() => [ + new EffectInstance(VanillaEffects::WEAKNESS(), 1800) + ]), + new self("long_weakness", fn() => [ + new EffectInstance(VanillaEffects::WEAKNESS(), 4800) + ]), + new self("wither", fn() => [ + new EffectInstance(VanillaEffects::WITHER(), 800, 1) + ]) + ); + } + + /** @phpstan-var \Closure() : list */ + private \Closure $effectsGetter; + + /** + * @phpstan-param \Closure() : list $effectsGetter + */ + private function __construct(string $enumName, \Closure $effectsGetter){ + $this->Enum___construct($enumName); + $this->effectsGetter = $effectsGetter; + } + + /** + * @return EffectInstance[] + * @phpstan-return list + */ + public function getEffects() : array{ + return ($this->effectsGetter)(); + } +} diff --git a/src/item/SplashPotion.php b/src/item/SplashPotion.php index b1330875aa..1b338a96b1 100644 --- a/src/item/SplashPotion.php +++ b/src/item/SplashPotion.php @@ -30,12 +30,11 @@ use pocketmine\player\Player; class SplashPotion extends ProjectileItem{ - /** @var int */ - private $potionId; + private PotionType $potionType; - public function __construct(ItemIdentifier $identifier, string $name, int $potionId){ + public function __construct(ItemIdentifier $identifier, string $name, PotionType $potionType){ parent::__construct($identifier, $name); - $this->potionId = $potionId; + $this->potionType = $potionType; } public function getMaxStackSize() : int{ @@ -43,7 +42,7 @@ class SplashPotion extends ProjectileItem{ } protected function createEntity(Location $location, Player $thrower) : Throwable{ - return new SplashPotionEntity($location, $thrower, $this->potionId); + return new SplashPotionEntity($location, $thrower, $this->potionType); } public function getThrowForce() : float{ From 5d6146a01f45aa2c8b05e8b6b009751cefd511f9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 19 Jun 2021 21:53:08 +0100 Subject: [PATCH 2553/3224] Register missing potion types --- src/data/bedrock/PotionTypeIdMap.php | 5 +++++ src/data/bedrock/PotionTypeIds.php | 5 +++++ src/entity/EntityFactory.php | 2 +- src/item/PotionType.php | 20 ++++++++++++++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/data/bedrock/PotionTypeIdMap.php b/src/data/bedrock/PotionTypeIdMap.php index d665b0222e..4fcb9b693e 100644 --- a/src/data/bedrock/PotionTypeIdMap.php +++ b/src/data/bedrock/PotionTypeIdMap.php @@ -79,6 +79,11 @@ final class PotionTypeIdMap{ $this->register(PotionTypeIds::WEAKNESS, PotionType::WEAKNESS()); $this->register(PotionTypeIds::LONG_WEAKNESS, PotionType::LONG_WEAKNESS()); $this->register(PotionTypeIds::WITHER, PotionType::WITHER()); + $this->register(PotionTypeIds::TURTLE_MASTER, PotionType::TURTLE_MASTER()); + $this->register(PotionTypeIds::LONG_TURTLE_MASTER, PotionType::LONG_TURTLE_MASTER()); + $this->register(PotionTypeIds::STRONG_TURTLE_MASTER, PotionType::STRONG_TURTLE_MASTER()); + $this->register(PotionTypeIds::SLOW_FALLING, PotionType::SLOW_FALLING()); + $this->register(PotionTypeIds::LONG_SLOW_FALLING, PotionType::LONG_SLOW_FALLING()); } private function register(int $id, PotionType $type) : void{ diff --git a/src/data/bedrock/PotionTypeIds.php b/src/data/bedrock/PotionTypeIds.php index 41167c2d6d..ebe51de540 100644 --- a/src/data/bedrock/PotionTypeIds.php +++ b/src/data/bedrock/PotionTypeIds.php @@ -61,4 +61,9 @@ final class PotionTypeIds{ public const WEAKNESS = 34; public const LONG_WEAKNESS = 35; public const WITHER = 36; + public const TURTLE_MASTER = 37; + public const LONG_TURTLE_MASTER = 38; + public const STRONG_TURTLE_MASTER = 39; + public const SLOW_FALLING = 40; + public const LONG_SLOW_FALLING = 41; } diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index 47e19b9d3c..1967b3821d 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -152,7 +152,7 @@ final class EntityFactory{ $this->register(SplashPotion::class, function(World $world, CompoundTag $nbt) : SplashPotion{ $potionType = PotionTypeIdMap::getInstance()->fromId($nbt->getShort("PotionId", PotionTypeIds::WATER)); if($potionType === null){ - $potionType = PotionType::WATER(); //TODO: this should be an error, but we haven't registered all the types yet + throw new \UnexpectedValueException("No such potion type"); } return new SplashPotion(EntityDataHelper::parseLocation($nbt, $world), null, $potionType, $nbt); }, ['ThrownPotion', 'minecraft:potion', 'thrownpotion'], EntityLegacyIds::SPLASH_POTION); diff --git a/src/item/PotionType.php b/src/item/PotionType.php index 533d297240..83ee1b300a 100644 --- a/src/item/PotionType.php +++ b/src/item/PotionType.php @@ -46,8 +46,10 @@ use pocketmine\utils\EnumTrait; * @method static PotionType LONG_POISON() * @method static PotionType LONG_REGENERATION() * @method static PotionType LONG_SLOWNESS() + * @method static PotionType LONG_SLOW_FALLING() * @method static PotionType LONG_STRENGTH() * @method static PotionType LONG_SWIFTNESS() + * @method static PotionType LONG_TURTLE_MASTER() * @method static PotionType LONG_WATER_BREATHING() * @method static PotionType LONG_WEAKNESS() * @method static PotionType MUNDANE() @@ -55,6 +57,7 @@ use pocketmine\utils\EnumTrait; * @method static PotionType POISON() * @method static PotionType REGENERATION() * @method static PotionType SLOWNESS() + * @method static PotionType SLOW_FALLING() * @method static PotionType STRENGTH() * @method static PotionType STRONG_HARMING() * @method static PotionType STRONG_HEALING() @@ -63,8 +66,10 @@ use pocketmine\utils\EnumTrait; * @method static PotionType STRONG_REGENERATION() * @method static PotionType STRONG_STRENGTH() * @method static PotionType STRONG_SWIFTNESS() + * @method static PotionType STRONG_TURTLE_MASTER() * @method static PotionType SWIFTNESS() * @method static PotionType THICK() + * @method static PotionType TURTLE_MASTER() * @method static PotionType WATER() * @method static PotionType WATER_BREATHING() * @method static PotionType WEAKNESS() @@ -177,6 +182,21 @@ final class PotionType{ ]), new self("wither", fn() => [ new EffectInstance(VanillaEffects::WITHER(), 800, 1) + ]), + new self("turtle_master", fn() => [ + //TODO + ]), + new self("long_turtle_master", fn() => [ + //TODO + ]), + new self("strong_turtle_master", fn() => [ + //TODO + ]), + new self("slow_falling", fn() => [ + //TODO + ]), + new self("long_slow_falling", fn() => [ + //TODO ]) ); } From 60d80e173b4b3ba12bf4e78cb8a3056a1864e26b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 21 Jun 2021 20:03:32 +0100 Subject: [PATCH 2554/3224] Fixed player sounds not being broadcasted to the player itself fixes #4259 fixes #4270 --- src/player/Player.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/player/Player.php b/src/player/Player.php index 983c860100..f3b2814dfb 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -105,6 +105,7 @@ use pocketmine\world\Position; use pocketmine\world\sound\EntityAttackNoDamageSound; use pocketmine\world\sound\EntityAttackSound; use pocketmine\world\sound\FireExtinguishSound; +use pocketmine\world\sound\Sound; use pocketmine\world\World; use Ramsey\Uuid\UuidInterface; use function abs; @@ -2221,6 +2222,14 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ parent::broadcastAnimation($animation, $targets); } + public function broadcastSound(Sound $sound, ?array $targets = null) : void{ + if($this->spawned && $targets === null){ + $targets = $this->getViewers(); + $targets[] = $this; + } + parent::broadcastSound($sound, $targets); + } + /** * TODO: remove this */ From 85ee628a741209af88b72b429f715898c4de5c43 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 21 Jun 2021 20:08:43 +0100 Subject: [PATCH 2555/3224] Player: remove sendPosition() from public API plugins shouldn't be touching this for any reason now. --- src/player/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index f3b2814dfb..e0e8ffa914 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2233,7 +2233,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ /** * TODO: remove this */ - public function sendPosition(Vector3 $pos, ?float $yaw = null, ?float $pitch = null, int $mode = MovePlayerPacket::MODE_NORMAL) : void{ + protected function sendPosition(Vector3 $pos, ?float $yaw = null, ?float $pitch = null, int $mode = MovePlayerPacket::MODE_NORMAL) : void{ $this->getNetworkSession()->syncMovement($pos, $yaw, $pitch, $mode); $this->ySize = 0; From 2a6009f8bfe77ac87470e9d9cf5d2d55c9d46d82 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 21 Jun 2021 20:30:27 +0100 Subject: [PATCH 2556/3224] Check consistency of block remaps --- src/block/BlockFactory.php | 1 + tests/phpunit/block/BlockTest.php | 18 +++++++-- .../block_factory_consistency_check.json | 2 +- .../block/regenerate_consistency_check.php | 37 +++++++++++++++---- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 35bae199a2..22e6cc9dc4 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -56,6 +56,7 @@ use function array_fill; use function array_filter; use function get_class; use function min; +use function var_dump; /** * Manages deserializing block types from their legacy blockIDs and metadata. diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index 5150fbda22..2959211893 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -145,14 +145,26 @@ class BlockTest extends TestCase{ public function testConsistency() : void{ $list = json_decode(file_get_contents(__DIR__ . '/block_factory_consistency_check.json'), true); + $knownStates = $list["knownStates"]; + $remaps = $list["remaps"]; + $states = $this->blockFactory->getAllKnownStates(); foreach($states as $k => $state){ - self::assertArrayHasKey($k, $list, "New block state $k (" . $state->getName() . ") - consistency check may need regenerating"); - self::assertSame($list[$k], $state->getName()); + if($state->getFullId() !== $k){ + self::assertArrayHasKey($k, $remaps, "New remap of state $k (" . $state->getName() . ") - consistency check may need regenerating"); + self::assertSame($state->getFullId(), $remaps[$k], "Mismatched full IDs of remapped state $k"); + }else{ + self::assertArrayHasKey($k, $knownStates, "New block state $k (" . $state->getName() . ") - consistency check may need regenerating"); + self::assertSame($knownStates[$k], $state->getName()); + } } - foreach($list as $k => $name){ + foreach($knownStates as $k => $name){ self::assertArrayHasKey($k, $states, "Missing previously-known block state $k ($name)"); self::assertSame($name, $states[$k]->getName()); } + foreach($remaps as $origin => $destination){ + self::assertArrayHasKey($origin, $states, "Missing previously-remapped state $origin"); + self::assertSame($destination, $states[$origin]->getFullId()); + } } } diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 70c3d82e31..f47e13a024 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","284":"Oak Wood","285":"Spruce Wood","286":"Birch Wood","287":"Jungle Wood","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","438":"Powered Rail","439":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","446":"Powered Rail","447":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","454":"Detector Rail","455":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","462":"Detector Rail","463":"Detector Rail","480":"Cobweb","496":"Fern","497":"Tall Grass","498":"Fern","499":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","696":"Smooth Stone Slab","697":"Sandstone Slab","698":"Fake Wooden Slab","699":"Cobblestone Slab","700":"Brick Slab","701":"Stone Brick Slab","702":"Quartz Slab","703":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","800":"Torch","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","806":"Torch","807":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","864":"Chest","865":"Chest","866":"Chest","867":"Chest","868":"Chest","869":"Chest","870":"Chest","871":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","976":"Furnace","977":"Furnace","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","982":"Furnace","983":"Furnace","992":"Furnace","993":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","998":"Furnace","999":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1036":"Oak Door","1037":"Oak Door","1038":"Oak Door","1039":"Oak Door","1040":"Ladder","1041":"Ladder","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1046":"Ladder","1047":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1066":"Rail","1067":"Rail","1068":"Rail","1069":"Rail","1070":"Rail","1071":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1088":"Oak Wall Sign","1089":"Oak Wall Sign","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1094":"Oak Wall Sign","1095":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1148":"Iron Door","1149":"Iron Door","1150":"Iron Door","1151":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1200":"Redstone Torch","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1206":"Redstone Torch","1207":"Redstone Torch","1216":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1222":"Redstone Torch","1223":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1238":"Stone Button","1239":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1246":"Stone Button","1247":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1377":"Pumpkin","1378":"Pumpkin","1379":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1440":"Nether Portal","1441":"Nether Portal","1442":"Nether Portal","1443":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1479":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1595":"Brown Mushroom Block","1596":"Brown Mushroom Block","1597":"Brown Mushroom Block","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1610":"Mushroom Stem","1611":"Red Mushroom Block","1612":"Red Mushroom Block","1613":"Red Mushroom Block","1614":"Red Mushroom Block","1615":"All Sided Mushroom Stem","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2022":"Activator Rail","2023":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2030":"Activator Rail","2031":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2044":"Cocoa Block","2045":"Cocoa Block","2046":"Cocoa Block","2047":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2080":"Ender Chest","2081":"Ender Chest","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2086":"Ender Chest","2087":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2242":"Flower Pot","2243":"Flower Pot","2244":"Flower Pot","2245":"Flower Pot","2246":"Flower Pot","2247":"Flower Pot","2248":"Flower Pot","2249":"Flower Pot","2250":"Flower Pot","2251":"Flower Pot","2252":"Flower Pot","2253":"Flower Pot","2254":"Flower Pot","2255":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2294":"Oak Button","2295":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2302":"Oak Button","2303":"Oak Button","2304":"Mob Head","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2310":"Mob Head","2311":"Mob Head","2312":"Mob Head","2313":"Mob Head","2314":"Mob Head","2315":"Mob Head","2316":"Mob Head","2317":"Mob Head","2318":"Mob Head","2319":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2332":"Anvil","2333":"Anvil","2334":"Anvil","2335":"Anvil","2336":"Trapped Chest","2337":"Trapped Chest","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2342":"Trapped Chest","2343":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2392":"Redstone Comparator","2393":"Redstone Comparator","2394":"Redstone Comparator","2395":"Redstone Comparator","2396":"Redstone Comparator","2397":"Redstone Comparator","2398":"Redstone Comparator","2399":"Redstone Comparator","2400":"Redstone Comparator","2401":"Redstone Comparator","2402":"Redstone Comparator","2403":"Redstone Comparator","2404":"Redstone Comparator","2405":"Redstone Comparator","2406":"Redstone Comparator","2407":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2465":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2470":"Hopper","2471":"Hopper","2472":"Hopper","2473":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2478":"Hopper","2479":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2493":"Chiseled Quartz Block","2494":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2520":"Oak Slab","2521":"Spruce Slab","2522":"Birch Slab","2523":"Jungle Slab","2524":"Acacia Slab","2525":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2604":"Acacia Wood","2605":"Dark Oak Wood","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2732":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2832":"Wall Banner","2833":"Wall Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2838":"Wall Banner","2839":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2904":"Red Sandstone Slab","2905":"Purpur Slab","2906":"Prismarine Slab","2907":"Dark Prismarine Slab","2908":"Prismarine Bricks Slab","2909":"Mossy Cobblestone Slab","2910":"Smooth Sandstone Slab","2911":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3100":"Spruce Door","3101":"Spruce Door","3102":"Spruce Door","3103":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3116":"Birch Door","3117":"Birch Door","3118":"Birch Door","3119":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3132":"Jungle Door","3133":"Jungle Door","3134":"Jungle Door","3135":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3148":"Acacia Door","3149":"Acacia Door","3150":"Acacia Door","3151":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3164":"Dark Oak Door","3165":"Dark Oak Door","3166":"Dark Oak Door","3167":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3230":"Purpur Pillar","3232":"Red Torch","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3238":"Red Torch","3239":"Red Torch","3240":"Green Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3246":"Green Torch","3247":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3264":"Blue Torch","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3270":"Blue Torch","3271":"Blue Torch","3272":"Purple Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3278":"Purple Torch","3279":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3334":"End Rod","3335":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3468":"Bone Block","3504":"Purple Glazed Terracotta","3505":"Purple Glazed Terracotta","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3510":"Purple Glazed Terracotta","3511":"Purple Glazed Terracotta","3520":"White Glazed Terracotta","3521":"White Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3526":"White Glazed Terracotta","3527":"White Glazed Terracotta","3536":"Orange Glazed Terracotta","3537":"Orange Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3542":"Orange Glazed Terracotta","3543":"Orange Glazed Terracotta","3552":"Magenta Glazed Terracotta","3553":"Magenta Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3558":"Magenta Glazed Terracotta","3559":"Magenta Glazed Terracotta","3568":"Light Blue Glazed Terracotta","3569":"Light Blue Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3574":"Light Blue Glazed Terracotta","3575":"Light Blue Glazed Terracotta","3584":"Yellow Glazed Terracotta","3585":"Yellow Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3590":"Yellow Glazed Terracotta","3591":"Yellow Glazed Terracotta","3600":"Lime Glazed Terracotta","3601":"Lime Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3606":"Lime Glazed Terracotta","3607":"Lime Glazed Terracotta","3616":"Pink Glazed Terracotta","3617":"Pink Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3622":"Pink Glazed Terracotta","3623":"Pink Glazed Terracotta","3632":"Gray Glazed Terracotta","3633":"Gray Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3638":"Gray Glazed Terracotta","3639":"Gray Glazed Terracotta","3648":"Light Gray Glazed Terracotta","3649":"Light Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3654":"Light Gray Glazed Terracotta","3655":"Light Gray Glazed Terracotta","3664":"Cyan Glazed Terracotta","3665":"Cyan Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3670":"Cyan Glazed Terracotta","3671":"Cyan Glazed Terracotta","3696":"Blue Glazed Terracotta","3697":"Blue Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3702":"Blue Glazed Terracotta","3703":"Blue Glazed Terracotta","3712":"Brown Glazed Terracotta","3713":"Brown Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3718":"Brown Glazed Terracotta","3719":"Brown Glazed Terracotta","3728":"Green Glazed Terracotta","3729":"Green Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3734":"Green Glazed Terracotta","3735":"Green Glazed Terracotta","3744":"Red Glazed Terracotta","3745":"Red Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3750":"Red Glazed Terracotta","3751":"Red Glazed Terracotta","3760":"Black Glazed Terracotta","3761":"Black Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3766":"Black Glazed Terracotta","3767":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3824":"Underwater Torch","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3830":"Underwater Torch","3831":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3955":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4163":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4179":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4195":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4211":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4227":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4243":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6181":"Coral","6182":"Coral","6183":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6197":"Coral Block","6198":"Coral Block","6199":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6205":"Coral Block","6206":"Coral Block","6207":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6213":"Coral Fan","6214":"Coral Fan","6215":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6221":"Coral Fan","6222":"Coral Fan","6223":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6229":"Coral Fan","6230":"Coral Fan","6231":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6237":"Coral Fan","6238":"Coral Fan","6239":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6273":"Wall Coral Fan","6274":"Wall Coral Fan","6275":"Wall Coral Fan","6276":"Wall Coral Fan","6277":"Wall Coral Fan","6278":"Wall Coral Fan","6279":"Wall Coral Fan","6280":"Wall Coral Fan","6281":"Wall Coral Fan","6282":"Wall Coral Fan","6283":"Wall Coral Fan","6284":"Wall Coral Fan","6285":"Wall Coral Fan","6286":"Wall Coral Fan","6287":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6326":"Acacia Button","6327":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6334":"Acacia Button","6335":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6342":"Birch Button","6343":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6350":"Birch Button","6351":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6358":"Dark Oak Button","6359":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6366":"Dark Oak Button","6367":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6374":"Jungle Button","6375":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6382":"Jungle Button","6383":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6390":"Spruce Button","6391":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6398":"Spruce Button","6399":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6694":"Bamboo","6695":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6702":"Bamboo","6703":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6760":"End Stone Brick Slab","6761":"Smooth Red Sandstone Slab","6762":"Polished Andesite Slab","6763":"Andesite Slab","6764":"Diorite Slab","6765":"Polished Diorite Slab","6766":"Granite Slab","6767":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6776":"Mossy Stone Brick Slab","6777":"Smooth Quartz Slab","6778":"Stone Slab","6779":"Cut Sandstone Slab","6780":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6992":"Spruce Wall Sign","6993":"Spruce Wall Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","6998":"Spruce Wall Sign","6999":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7072":"Birch Wall Sign","7073":"Birch Wall Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7078":"Birch Wall Sign","7079":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7104":"Jungle Wall Sign","7105":"Jungle Wall Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7110":"Jungle Wall Sign","7111":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7136":"Acacia Wall Sign","7137":"Acacia Wall Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7142":"Acacia Wall Sign","7143":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7168":"Dark Oak Wall Sign","7169":"Dark Oak Wall Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7174":"Dark Oak Wall Sign","7175":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7334":"Barrel","7335":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7342":"Barrel","7343":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood","7480":"Stripped Oak Wood","7481":"Stripped Spruce Wood","7482":"Stripped Birch Wood","7483":"Stripped Jungle Wood","7484":"Stripped Acacia Wood","7485":"Stripped Dark Oak Wood"} \ No newline at end of file +{"knownStates":{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","497":"Tall Grass","498":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1614":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6274":"Wall Coral Fan","6276":"Wall Coral Fan","6278":"Wall Coral Fan","6280":"Wall Coral Fan","6282":"Wall Coral Fan","6284":"Wall Coral Fan","6286":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood","7480":"Stripped Oak Wood","7481":"Stripped Spruce Wood","7482":"Stripped Birch Wood","7483":"Stripped Jungle Wood","7484":"Stripped Acacia Wood","7485":"Stripped Dark Oak Wood"},"remaps":{"284":7472,"285":7473,"286":7474,"287":7475,"438":432,"439":432,"446":432,"447":432,"454":448,"455":448,"462":448,"463":448,"496":498,"499":498,"696":704,"697":705,"698":706,"699":707,"700":708,"701":709,"702":710,"703":711,"800":805,"806":805,"807":805,"864":866,"865":866,"870":866,"871":866,"976":978,"977":978,"982":978,"983":978,"992":978,"993":978,"998":978,"999":978,"1036":1027,"1037":1027,"1038":1027,"1039":1027,"1040":1042,"1041":1042,"1046":1042,"1047":1042,"1066":1056,"1067":1056,"1068":1056,"1069":1056,"1070":1056,"1071":1056,"1088":1090,"1089":1090,"1094":1090,"1095":1090,"1148":1139,"1149":1139,"1150":1139,"1151":1139,"1200":1221,"1206":1221,"1207":1221,"1216":1221,"1222":1221,"1223":1221,"1238":1232,"1239":1232,"1246":1232,"1247":1232,"1377":1376,"1378":1376,"1379":1376,"1440":1441,"1443":1441,"1479":1472,"1595":1598,"1596":1598,"1597":1598,"1610":1594,"1611":1614,"1612":1614,"1613":1614,"1615":1599,"2022":2016,"2023":2016,"2030":2016,"2031":2016,"2044":2032,"2045":2032,"2046":2032,"2047":2032,"2080":2082,"2081":2082,"2086":2082,"2087":2082,"2242":2240,"2243":2240,"2244":2240,"2245":2240,"2246":2240,"2247":2240,"2248":2240,"2249":2240,"2250":2240,"2251":2240,"2252":2240,"2253":2240,"2254":2240,"2255":2240,"2294":2288,"2295":2288,"2302":2288,"2303":2288,"2304":2306,"2310":2306,"2311":2306,"2312":2306,"2313":2306,"2314":2306,"2315":2306,"2316":2306,"2317":2306,"2318":2306,"2319":2306,"2332":2322,"2333":2322,"2334":2322,"2335":2322,"2336":2338,"2337":2338,"2342":2338,"2343":2338,"2392":2386,"2393":2386,"2394":2386,"2395":2386,"2396":2386,"2397":2386,"2398":2386,"2399":2386,"2400":2386,"2401":2386,"2402":2386,"2403":2386,"2404":2386,"2405":2386,"2406":2386,"2407":2386,"2465":2464,"2470":2464,"2471":2464,"2473":2464,"2478":2464,"2479":2464,"2493":2481,"2494":2482,"2520":2528,"2521":2529,"2522":2530,"2523":2531,"2524":2532,"2525":2533,"2604":7476,"2605":7477,"2732":2720,"2832":2834,"2833":2834,"2838":2834,"2839":2834,"2904":2912,"2905":2913,"2906":2914,"2907":2915,"2908":2916,"2909":2917,"2910":2918,"2911":2919,"3100":3091,"3101":3091,"3102":3091,"3103":3091,"3116":3107,"3117":3107,"3118":3107,"3119":3107,"3132":3123,"3133":3123,"3134":3123,"3135":3123,"3148":3139,"3149":3139,"3150":3139,"3151":3139,"3164":3155,"3165":3155,"3166":3155,"3167":3155,"3230":3218,"3232":3237,"3238":3237,"3239":3237,"3240":3245,"3246":3245,"3247":3245,"3264":3269,"3270":3269,"3271":3269,"3272":3277,"3278":3277,"3279":3277,"3334":3328,"3335":3328,"3468":3456,"3504":3506,"3505":3506,"3510":3506,"3511":3506,"3520":3522,"3521":3522,"3526":3522,"3527":3522,"3536":3538,"3537":3538,"3542":3538,"3543":3538,"3552":3554,"3553":3554,"3558":3554,"3559":3554,"3568":3570,"3569":3570,"3574":3570,"3575":3570,"3584":3586,"3585":3586,"3590":3586,"3591":3586,"3600":3602,"3601":3602,"3606":3602,"3607":3602,"3616":3618,"3617":3618,"3622":3618,"3623":3618,"3632":3634,"3633":3634,"3638":3634,"3639":3634,"3648":3650,"3649":3650,"3654":3650,"3655":3650,"3664":3666,"3665":3666,"3670":3666,"3671":3666,"3696":3698,"3697":3698,"3702":3698,"3703":3698,"3712":3714,"3713":3714,"3718":3714,"3719":3714,"3728":3730,"3729":3730,"3734":3730,"3735":3730,"3744":3746,"3745":3746,"3750":3746,"3751":3746,"3760":3762,"3761":3762,"3766":3762,"3767":3762,"3824":3829,"3830":3829,"3831":3829,"3955":3952,"4163":4160,"4179":4176,"4195":4192,"4211":4208,"4227":4224,"4243":4240,"6181":6176,"6182":6176,"6183":6176,"6197":6192,"6198":6192,"6199":6192,"6205":6192,"6206":6192,"6207":6192,"6213":6208,"6214":6208,"6215":6208,"6221":6208,"6222":6208,"6223":6208,"6229":6208,"6230":6208,"6231":6208,"6237":6208,"6238":6208,"6239":6208,"6273":6248,"6275":6248,"6277":6248,"6279":6248,"6281":6248,"6283":6248,"6285":6248,"6287":6248,"6326":6320,"6327":6320,"6334":6320,"6335":6320,"6342":6336,"6343":6336,"6350":6336,"6351":6336,"6358":6352,"6359":6352,"6366":6352,"6367":6352,"6374":6368,"6375":6368,"6382":6368,"6383":6368,"6390":6384,"6391":6384,"6398":6384,"6399":6384,"6694":6688,"6695":6688,"6702":6688,"6703":6688,"6760":6672,"6761":6673,"6762":6674,"6763":6675,"6764":6676,"6765":6677,"6766":6678,"6767":6679,"6776":6736,"6777":6737,"6778":6738,"6779":6739,"6780":6740,"6992":6994,"6993":6994,"6998":6994,"6999":6994,"7072":7074,"7073":7074,"7078":7074,"7079":7074,"7104":7106,"7105":7106,"7110":7106,"7111":7106,"7136":7138,"7137":7138,"7142":7138,"7143":7138,"7168":7170,"7169":7170,"7174":7170,"7175":7170,"7334":7328,"7335":7328,"7342":7328,"7343":7328}} \ No newline at end of file diff --git a/tests/phpunit/block/regenerate_consistency_check.php b/tests/phpunit/block/regenerate_consistency_check.php index 8160ff6cc5..6018307670 100644 --- a/tests/phpunit/block/regenerate_consistency_check.php +++ b/tests/phpunit/block/regenerate_consistency_check.php @@ -26,14 +26,19 @@ require dirname(__DIR__, 3) . '/vendor/autoload.php'; /* This script needs to be re-run after any intentional blockfactory change (adding or removing a block state). */ $factory = new \pocketmine\block\BlockFactory(); +$remaps = []; +$new = []; +foreach($factory->getAllKnownStates() as $index => $block){ + if($block->getFullId() !== $index){ + $remaps[$index] = $block->getFullId(); + }else{ + $new[$index] = $block->getName(); + } +} +$oldTable = json_decode(file_get_contents(__DIR__ . '/block_factory_consistency_check.json'), true); +$old = $oldTable["knownStates"]; +$oldRemaps = $oldTable["remaps"]; -$old = json_decode(file_get_contents(__DIR__ . '/block_factory_consistency_check.json'), true); -$new = array_map( - function(\pocketmine\block\Block $block) : string{ - return $block->getName(); - }, - $factory->getAllKnownStates() -); foreach($old as $k => $name){ if(!isset($new[$k])){ echo "Removed state for $name (" . ($k >> \pocketmine\block\Block::INTERNAL_METADATA_BITS) . ":" . ($k & \pocketmine\block\Block::INTERNAL_METADATA_MASK) . ")\n"; @@ -46,6 +51,22 @@ foreach($new as $k => $name){ echo "Name changed (" . ($k >> \pocketmine\block\Block::INTERNAL_METADATA_BITS) . ":" . ($k & \pocketmine\block\Block::INTERNAL_METADATA_MASK) . "): " . $old[$k] . " -> " . $name . "\n"; } } + +foreach($oldRemaps as $index => $mapped){ + if(!isset($remaps[$index])){ + echo "Removed remap of " . ($index >> 4) . ":" . ($index & 0xf) . "\n"; + } +} +foreach($remaps as $index => $mapped){ + if(!isset($oldRemaps[$index])){ + echo "New remap of " . ($index >> 4) . ":" . ($index & 0xf) . " (" . ($mapped >> 4) . ":" . ($mapped & 0xf) . ") (" . $new[$mapped] . ")\n"; + }elseif($oldRemaps[$index] !== $mapped){ + echo "Remap changed for " . ($index >> 4) . ":" . ($index & 0xf) . " (" . ($oldRemaps[$index] >> 4) . ":" . ($oldRemaps[$index] & 0xf) . " (" . $old[$oldRemaps[$index]] . ") -> " . ($mapped >> 4) . ":" . ($mapped & 0xf) . " (" . $new[$mapped] . "))\n"; + } +} file_put_contents(__DIR__ . '/block_factory_consistency_check.json', json_encode( - $new + [ + "knownStates" => $new, + "remaps" => $remaps + ], )); From 444d902990e00125afb6f1182d95cc0543b134c3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 21 Jun 2021 20:31:24 +0100 Subject: [PATCH 2557/3224] Fix CS --- src/block/BlockFactory.php | 1 - src/entity/EntityFactory.php | 1 - 2 files changed, 2 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 22e6cc9dc4..35bae199a2 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -56,7 +56,6 @@ use function array_fill; use function array_filter; use function get_class; use function min; -use function var_dump; /** * Manages deserializing block types from their legacy blockIDs and metadata. diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index 1967b3821d..809d323414 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -43,7 +43,6 @@ use pocketmine\entity\projectile\ExperienceBottle; use pocketmine\entity\projectile\Snowball; use pocketmine\entity\projectile\SplashPotion; use pocketmine\item\Item; -use pocketmine\item\PotionType; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\nbt\NbtDataException; From a6039ad7338c439531c58504b10e5edab2006254 Mon Sep 17 00:00:00 2001 From: aieuo <35859665+aieuo@users.noreply.github.com> Date: Sun, 27 Jun 2021 00:48:53 +0900 Subject: [PATCH 2558/3224] Fixed InventoryHelpersTrait::addItem() cannot add items with a count greater than maxstack (#4283) --- src/inventory/InventoryHelpersTrait.php | 4 +++- tests/phpunit/inventory/BaseInventoryTest.php | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/inventory/InventoryHelpersTrait.php b/src/inventory/InventoryHelpersTrait.php index 881a65d738..00bec34c70 100644 --- a/src/inventory/InventoryHelpersTrait.php +++ b/src/inventory/InventoryHelpersTrait.php @@ -186,7 +186,9 @@ trait InventoryHelpersTrait{ $item = clone $slot; $item->setCount($amount); $this->setItem($slotIndex, $item); - break; + if($slot->getCount() <= 0){ + break; + } } } diff --git a/tests/phpunit/inventory/BaseInventoryTest.php b/tests/phpunit/inventory/BaseInventoryTest.php index 89c65c8138..8fd7f43ea2 100644 --- a/tests/phpunit/inventory/BaseInventoryTest.php +++ b/tests/phpunit/inventory/BaseInventoryTest.php @@ -85,4 +85,19 @@ class BaseInventoryTest extends TestCase{ } self::assertSame(20, $leftoverCount); } + + public function testAddItemWithOversizedCount() : void{ + $inventory = new class(10) extends SimpleInventory{ + + }; + $leftover = $inventory->addItem(VanillaItems::APPLE()->setCount(100)); + self::assertCount(0, $leftover); + + $count = 0; + foreach($inventory->getContents() as $item){ + self::assertTrue($item->equals(VanillaItems::APPLE())); + $count += $item->getCount(); + } + self::assertSame(100, $count); + } } From 4a5bdefe8bf1256fefe6470503c9c8f909fb3ca1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Jun 2021 17:17:47 +0100 Subject: [PATCH 2559/3224] Player: Explicitly clear permission recalculation callbacks this is necessary to get rid of the broadcast permission callbacks, which retain references to the Player itself, forming a cycle which would prevent PermissibleBase->__destruct() from cleaning up. --- src/player/Player.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/player/Player.php b/src/player/Player.php index e0e8ffa914..d62362f436 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2006,6 +2006,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->removeCurrentWindow(); $this->removePermanentInventories(); + $this->perm->getPermissionRecalculationCallbacks()->clear(); + $this->flagForDespawn(); } From e43bca95bf58793e09f909f4785ce9eaa9b748cd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Jun 2021 17:40:43 +0100 Subject: [PATCH 2560/3224] Fixed build --- tests/phpunit/block/BlockTest.php | 4 ++++ tests/phpunit/block/regenerate_consistency_check.php | 3 +++ 2 files changed, 7 insertions(+) diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index 2959211893..1e7e470aef 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use PHPUnit\Framework\TestCase; use function file_get_contents; +use function is_array; use function json_decode; class BlockTest extends TestCase{ @@ -145,6 +146,9 @@ class BlockTest extends TestCase{ public function testConsistency() : void{ $list = json_decode(file_get_contents(__DIR__ . '/block_factory_consistency_check.json'), true); + if(!is_array($list)){ + throw new \pocketmine\utils\AssumptionFailedError("Old table should be array{knownStates: array, remaps: array}"); + } $knownStates = $list["knownStates"]; $remaps = $list["remaps"]; diff --git a/tests/phpunit/block/regenerate_consistency_check.php b/tests/phpunit/block/regenerate_consistency_check.php index 6018307670..c8dd68dc50 100644 --- a/tests/phpunit/block/regenerate_consistency_check.php +++ b/tests/phpunit/block/regenerate_consistency_check.php @@ -36,6 +36,9 @@ foreach($factory->getAllKnownStates() as $index => $block){ } } $oldTable = json_decode(file_get_contents(__DIR__ . '/block_factory_consistency_check.json'), true); +if(!is_array($oldTable)){ + throw new \pocketmine\utils\AssumptionFailedError("Old table should be array{knownStates: array, remaps: array}"); +} $old = $oldTable["knownStates"]; $oldRemaps = $oldTable["remaps"]; From 0910054c4185a2f601266ee1e23e286518d31383 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Jun 2021 17:44:42 +0100 Subject: [PATCH 2561/3224] NetworkSession: Fixed InventoryManager nullability disaster fixes #4277 fixes #4275 fixes #3139 --- src/block/tile/Furnace.php | 24 ++++++------ src/inventory/BaseInventory.php | 12 +++++- src/network/mcpe/NetworkSession.php | 8 ++-- src/network/mcpe/convert/TypeConverter.php | 5 ++- .../mcpe/handler/InGamePacketHandler.php | 37 ++++++++++--------- .../mcpe/handler/PreSpawnPacketHandler.php | 12 ++++-- src/player/Player.php | 9 +++-- tests/phpstan/configs/l8-baseline.neon | 15 +++++--- 8 files changed, 74 insertions(+), 48 deletions(-) diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index 5f31c8dfbf..756e23ff9a 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -34,7 +34,9 @@ use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\ContainerSetDataPacket; +use pocketmine\player\Player; use pocketmine\world\World; +use function array_map; use function max; class Furnace extends Spawnable implements Container, Nameable{ @@ -202,19 +204,19 @@ class Furnace extends Spawnable implements Container, Nameable{ $this->remainingFuelTime = $this->cookTime = $this->maxFuelTime = 0; } - if($prevCookTime !== $this->cookTime){ - foreach($this->inventory->getViewers() as $v){ - $v->getNetworkSession()->getInvManager()->syncData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_SMELT_PROGRESS, $this->cookTime); + $viewers = array_map(fn(Player $p) => $p->getNetworkSession()->getInvManager(), $this->inventory->getViewers()); + foreach($viewers as $v){ + if($v === null){ + continue; } - } - if($prevRemainingFuelTime !== $this->remainingFuelTime){ - foreach($this->inventory->getViewers() as $v){ - $v->getNetworkSession()->getInvManager()->syncData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_REMAINING_FUEL_TIME, $this->remainingFuelTime); + if($prevCookTime !== $this->cookTime){ + $v->syncData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_SMELT_PROGRESS, $this->cookTime); } - } - if($prevMaxFuelTime !== $this->maxFuelTime){ - foreach($this->inventory->getViewers() as $v){ - $v->getNetworkSession()->getInvManager()->syncData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_MAX_FUEL_TIME, $this->maxFuelTime); + if($prevRemainingFuelTime !== $this->remainingFuelTime){ + $v->syncData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_REMAINING_FUEL_TIME, $this->remainingFuelTime); + } + if($prevMaxFuelTime !== $this->maxFuelTime){ + $v->syncData($this->inventory, ContainerSetDataPacket::PROPERTY_FURNACE_MAX_FUEL_TIME, $this->maxFuelTime); } } diff --git a/src/inventory/BaseInventory.php b/src/inventory/BaseInventory.php index 03bbea73c0..425c6a8090 100644 --- a/src/inventory/BaseInventory.php +++ b/src/inventory/BaseInventory.php @@ -136,7 +136,11 @@ abstract class BaseInventory implements Inventory{ $listener->onSlotChange($this, $index, $before); } foreach($this->viewers as $viewer){ - $viewer->getNetworkSession()->getInvManager()->syncSlot($this, $index); + $invManager = $viewer->getNetworkSession()->getInvManager(); + if($invManager === null){ + continue; + } + $invManager->syncSlot($this, $index); } } @@ -150,7 +154,11 @@ abstract class BaseInventory implements Inventory{ } foreach($this->getViewers() as $viewer){ - $viewer->getNetworkSession()->getInvManager()->syncContents($this); + $invManager = $viewer->getNetworkSession()->getInvManager(); + if($invManager === null){ + continue; + } + $invManager->syncContents($this); } } diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 9ba761abd3..45926887a5 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -672,7 +672,7 @@ class NetworkSession{ } private function beginSpawnSequence() : void{ - $this->setHandler(new PreSpawnPacketHandler($this->server, $this->player, $this)); + $this->setHandler(new PreSpawnPacketHandler($this->server, $this->player, $this, $this->invManager)); $this->player->setImmobile(); //TODO: HACK: fix client-side falling pre-spawn $this->logger->debug("Waiting for chunk radius request"); @@ -691,7 +691,7 @@ class NetworkSession{ $this->player->setImmobile(false); //TODO: HACK: we set this during the spawn sequence to prevent the client sending junk movements $this->player->doFirstSpawn(); $this->forceAsyncCompression = false; - $this->setHandler(new InGamePacketHandler($this->player, $this)); + $this->setHandler(new InGamePacketHandler($this->player, $this, $this->invManager)); } public function onServerDeath() : void{ @@ -705,7 +705,7 @@ class NetworkSession{ $this->syncAdventureSettings($this->player); $this->invManager->syncAll(); - $this->setHandler(new InGamePacketHandler($this->player, $this)); + $this->setHandler(new InGamePacketHandler($this->player, $this, $this->invManager)); } public function syncMovement(Vector3 $pos, ?float $yaw = null, ?float $pitch = null, int $mode = MovePlayerPacket::MODE_NORMAL) : void{ @@ -937,7 +937,7 @@ class NetworkSession{ $this->sendDataPacket(SetDifficultyPacket::create($worldDifficulty)); } - public function getInvManager() : InventoryManager{ + public function getInvManager() : ?InventoryManager{ return $this->invManager; } diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index a1adb20e69..c523eac106 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -39,6 +39,7 @@ use pocketmine\item\ItemFactory; use pocketmine\item\ItemIds; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; +use pocketmine\network\mcpe\InventoryManager; use pocketmine\network\mcpe\protocol\types\GameMode as ProtocolGameMode; use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; @@ -240,7 +241,7 @@ class TypeConverter{ /** * @throws \UnexpectedValueException */ - public function createInventoryAction(NetworkInventoryAction $action, Player $player) : ?InventoryAction{ + public function createInventoryAction(NetworkInventoryAction $action, Player $player, InventoryManager $inventoryManager) : ?InventoryAction{ if($action->oldItem->getItemStack()->equals($action->newItem->getItemStack())){ //filter out useless noise in 1.13 return null; @@ -276,7 +277,7 @@ class TypeConverter{ } [$slot, $window] = $mapped; }else{ - $window = $player->getNetworkSession()->getInvManager()->getWindow($action->windowId); + $window = $inventoryManager->getWindow($action->windowId); $slot = $action->inventorySlot; } if($window !== null){ diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 376fa53617..21509067bb 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -143,9 +143,12 @@ class InGamePacketHandler extends PacketHandler{ */ protected $openHardcodedWindows = []; - public function __construct(Player $player, NetworkSession $session){ + private InventoryManager $inventoryManager; + + public function __construct(Player $player, NetworkSession $session, InventoryManager $inventoryManager){ $this->player = $player; $this->session = $session; + $this->inventoryManager = $inventoryManager; } public function handleText(TextPacket $packet) : bool{ @@ -224,7 +227,7 @@ class InGamePacketHandler extends PacketHandler{ $result = $this->handleNormalTransaction($packet->trData); }elseif($packet->trData instanceof MismatchTransactionData){ $this->session->getLogger()->debug("Mismatch transaction received"); - $this->session->getInvManager()->syncAll(); + $this->inventoryManager->syncAll(); $result = true; }elseif($packet->trData instanceof UseItemTransactionData){ $result = $this->handleUseItemTransaction($packet->trData); @@ -235,7 +238,7 @@ class InGamePacketHandler extends PacketHandler{ } if(!$result){ - $this->session->getInvManager()->syncAll(); + $this->inventoryManager->syncAll(); } return $result; } @@ -265,7 +268,7 @@ class InGamePacketHandler extends PacketHandler{ } try{ - $action = $converter->createInventoryAction($networkInventoryAction, $this->player); + $action = $converter->createInventoryAction($networkInventoryAction, $this->player, $this->inventoryManager); if($action !== null){ $actions[] = $action; } @@ -293,14 +296,14 @@ class InGamePacketHandler extends PacketHandler{ return true; } try{ - $this->session->getInvManager()->onTransactionStart($this->craftingTransaction); + $this->inventoryManager->onTransactionStart($this->craftingTransaction); $this->craftingTransaction->execute(); }catch(TransactionException $e){ $this->session->getLogger()->debug("Failed to execute crafting transaction: " . $e->getMessage()); //TODO: only sync slots that the client tried to change foreach($this->craftingTransaction->getInventories() as $inventory){ - $this->session->getInvManager()->syncContents($inventory); + $this->inventoryManager->syncContents($inventory); } /* * TODO: HACK! @@ -328,7 +331,7 @@ class InGamePacketHandler extends PacketHandler{ } $transaction = new InventoryTransaction($this->player, $actions); - $this->session->getInvManager()->onTransactionStart($transaction); + $this->inventoryManager->onTransactionStart($transaction); try{ $transaction->execute(); }catch(TransactionException $e){ @@ -337,7 +340,7 @@ class InGamePacketHandler extends PacketHandler{ $logger->debug("Actions: " . json_encode($data->getActions())); foreach($transaction->getInventories() as $inventory){ - $this->session->getInvManager()->syncContents($inventory); + $this->inventoryManager->syncContents($inventory); } return false; @@ -392,12 +395,12 @@ class InGamePacketHandler extends PacketHandler{ case UseItemTransactionData::ACTION_CLICK_AIR: if($this->player->isUsingItem()){ if(!$this->player->consumeHeldItem()){ - $this->session->getInvManager()->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); + $this->inventoryManager->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); } return true; } if(!$this->player->useHeldItem()){ - $this->session->getInvManager()->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); + $this->inventoryManager->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); } return true; } @@ -409,7 +412,7 @@ class InGamePacketHandler extends PacketHandler{ * Internal function used to execute rollbacks when an action fails on a block. */ private function onFailedBlockAction(Vector3 $blockPos, ?int $face) : void{ - $this->session->getInvManager()->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); + $this->inventoryManager->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); if($blockPos->distanceSquared($this->player->getLocation()) < 10000){ $blocks = $blockPos->sidesArray(); if($face !== null){ @@ -436,12 +439,12 @@ class InGamePacketHandler extends PacketHandler{ switch($data->getActionType()){ case UseItemOnEntityTransactionData::ACTION_INTERACT: if(!$this->player->interactEntity($target, $data->getClickPos())){ - $this->session->getInvManager()->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); + $this->inventoryManager->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); } return true; case UseItemOnEntityTransactionData::ACTION_ATTACK: if(!$this->player->attackEntity($target)){ - $this->session->getInvManager()->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); + $this->inventoryManager->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); } return true; } @@ -454,7 +457,7 @@ class InGamePacketHandler extends PacketHandler{ switch($data->getActionType()){ case ReleaseItemTransactionData::ACTION_RELEASE: if(!$this->player->releaseHeldItem()){ - $this->session->getInvManager()->syncContents($this->player->getInventory()); + $this->inventoryManager->syncContents($this->player->getInventory()); } return true; } @@ -467,9 +470,9 @@ class InGamePacketHandler extends PacketHandler{ return true; //this happens when we put an item into the offhand } if($packet->windowId === ContainerIds::INVENTORY){ - $this->session->getInvManager()->onClientSelectHotbarSlot($packet->hotbarSlot); + $this->inventoryManager->onClientSelectHotbarSlot($packet->hotbarSlot); if(!$this->player->selectHotbarSlot($packet->hotbarSlot)){ - $this->session->getInvManager()->syncSelectedHotbarSlot(); + $this->inventoryManager->syncSelectedHotbarSlot(); } return true; } @@ -603,7 +606,7 @@ class InGamePacketHandler extends PacketHandler{ if(array_key_exists($packet->windowId, $this->openHardcodedWindows)){ unset($this->openHardcodedWindows[$packet->windowId]); }else{ - $this->session->getInvManager()->onClientRemoveWindow($packet->windowId); + $this->inventoryManager->onClientRemoveWindow($packet->windowId); } $this->session->sendDataPacket(ContainerClosePacket::create($packet->windowId, false)); diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index a6f52af3eb..82996ac66a 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -27,6 +27,7 @@ use pocketmine\network\mcpe\cache\CraftingDataCache; use pocketmine\network\mcpe\cache\StaticPacketCache; use pocketmine\network\mcpe\convert\GlobalItemTypeDictionary; use pocketmine\network\mcpe\convert\TypeConverter; +use pocketmine\network\mcpe\InventoryManager; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; use pocketmine\network\mcpe\protocol\StartGamePacket; @@ -53,10 +54,13 @@ class PreSpawnPacketHandler extends PacketHandler{ /** @var NetworkSession */ private $session; - public function __construct(Server $server, Player $player, NetworkSession $session){ + private InventoryManager $inventoryManager; + + public function __construct(Server $server, Player $player, NetworkSession $session, InventoryManager $inventoryManager){ $this->player = $player; $this->server = $server; $this->session = $session; + $this->inventoryManager = $inventoryManager; } public function setUp() : void{ @@ -104,9 +108,9 @@ class PreSpawnPacketHandler extends PacketHandler{ } $this->player->sendData([$this->player]); - $this->session->getInvManager()->syncAll(); - $this->session->getInvManager()->syncCreative(); - $this->session->getInvManager()->syncSelectedHotbarSlot(); + $this->inventoryManager->syncAll(); + $this->inventoryManager->syncCreative(); + $this->inventoryManager->syncSelectedHotbarSlot(); $this->session->sendDataPacket(CraftingDataCache::getInstance()->getCache($this->server->getCraftingManager())); $this->session->syncPlayerList($this->server->getOnlinePlayers()); diff --git a/src/player/Player.php b/src/player/Player.php index d62362f436..4dedf51182 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2340,8 +2340,11 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ //TODO: client side race condition here makes the opening work incorrectly $this->removeCurrentWindow(); + if(($inventoryManager = $this->getNetworkSession()->getInvManager()) === null){ + throw new \InvalidArgumentException("Player cannot open inventories in this state"); + } $this->logger->debug("Opening inventory " . get_class($inventory) . "#" . spl_object_id($inventory)); - $this->getNetworkSession()->getInvManager()->onCurrentWindowChange($inventory); + $inventoryManager->onCurrentWindowChange($inventory); $inventory->onOpen($this); $this->currentWindow = $inventory; return true; @@ -2353,8 +2356,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->logger->debug("Closing inventory " . get_class($this->currentWindow) . "#" . spl_object_id($this->currentWindow)); $this->currentWindow->onClose($this); - if($this->isConnected()){ - $this->getNetworkSession()->getInvManager()->onCurrentWindowRemove(); + if(($inventoryManager = $this->getNetworkSession()->getInvManager()) !== null){ + $inventoryManager->onCurrentWindowRemove(); } $this->currentWindow = null; } diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index c8742c2692..9af2e2e80f 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -135,11 +135,6 @@ parameters: count: 1 path: ../../../src/network/mcpe/NetworkSession.php - - - message: "#^Method pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:getInvManager\\(\\) should return pocketmine\\\\network\\\\mcpe\\\\InventoryManager but returns pocketmine\\\\network\\\\mcpe\\\\InventoryManager\\|null\\.$#" - count: 1 - path: ../../../src/network/mcpe/NetworkSession.php - - message: "#^Parameter \\#1 \\$clientPub of class pocketmine\\\\network\\\\mcpe\\\\encryption\\\\PrepareEncryptionTask constructor expects Mdanter\\\\Ecc\\\\Crypto\\\\Key\\\\PublicKeyInterface, Mdanter\\\\Ecc\\\\Crypto\\\\Key\\\\PublicKeyInterface\\|null given\\.$#" count: 1 @@ -185,6 +180,16 @@ parameters: count: 1 path: ../../../src/network/mcpe/NetworkSession.php + - + message: "#^Parameter \\#3 \\$inventoryManager of class pocketmine\\\\network\\\\mcpe\\\\handler\\\\InGamePacketHandler constructor expects pocketmine\\\\network\\\\mcpe\\\\InventoryManager, pocketmine\\\\network\\\\mcpe\\\\InventoryManager\\|null given\\.$#" + count: 2 + path: ../../../src/network/mcpe/NetworkSession.php + + - + message: "#^Parameter \\#4 \\$inventoryManager of class pocketmine\\\\network\\\\mcpe\\\\handler\\\\PreSpawnPacketHandler constructor expects pocketmine\\\\network\\\\mcpe\\\\InventoryManager, pocketmine\\\\network\\\\mcpe\\\\InventoryManager\\|null given\\.$#" + count: 1 + path: ../../../src/network/mcpe/NetworkSession.php + - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\LevelSoundEventPacket\\:\\:\\$position \\(pocketmine\\\\math\\\\Vector3\\) does not accept pocketmine\\\\math\\\\Vector3\\|null\\.$#" count: 1 From bf7d69b69edf17c51f87f9fdaae0f4323f6faa8c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Jun 2021 19:14:51 +0100 Subject: [PATCH 2562/3224] Stop hardcoding permission names everywhere using strings for permission names is nearly as shitty, but this is at least cross-referencable and statically analysable. --- src/command/defaults/BanCommand.php | 3 +- src/command/defaults/BanIpCommand.php | 3 +- src/command/defaults/BanListCommand.php | 3 +- src/command/defaults/ClearCommand.php | 8 +- .../defaults/DefaultGamemodeCommand.php | 3 +- src/command/defaults/DeopCommand.php | 3 +- src/command/defaults/DifficultyCommand.php | 3 +- src/command/defaults/DumpMemoryCommand.php | 3 +- src/command/defaults/EffectCommand.php | 3 +- src/command/defaults/EnchantCommand.php | 3 +- src/command/defaults/GamemodeCommand.php | 3 +- .../defaults/GarbageCollectorCommand.php | 3 +- src/command/defaults/GiveCommand.php | 3 +- src/command/defaults/HelpCommand.php | 3 +- src/command/defaults/KickCommand.php | 3 +- src/command/defaults/KillCommand.php | 8 +- src/command/defaults/ListCommand.php | 3 +- src/command/defaults/MeCommand.php | 3 +- src/command/defaults/OpCommand.php | 3 +- src/command/defaults/PardonCommand.php | 3 +- src/command/defaults/PardonIpCommand.php | 3 +- src/command/defaults/ParticleCommand.php | 3 +- src/command/defaults/PluginsCommand.php | 3 +- src/command/defaults/SaveCommand.php | 3 +- src/command/defaults/SaveOffCommand.php | 3 +- src/command/defaults/SaveOnCommand.php | 3 +- src/command/defaults/SayCommand.php | 3 +- src/command/defaults/SeedCommand.php | 3 +- src/command/defaults/SetWorldSpawnCommand.php | 3 +- src/command/defaults/SpawnpointCommand.php | 3 +- src/command/defaults/StatusCommand.php | 3 +- src/command/defaults/StopCommand.php | 3 +- src/command/defaults/TeleportCommand.php | 3 +- src/command/defaults/TellCommand.php | 3 +- src/command/defaults/TimeCommand.php | 23 +++- src/command/defaults/TimingsCommand.php | 3 +- src/command/defaults/TitleCommand.php | 3 +- .../defaults/TransferServerCommand.php | 3 +- src/command/defaults/VersionCommand.php | 3 +- src/command/defaults/WhitelistCommand.php | 28 ++++- src/permission/DefaultPermissionNames.php | 83 +++++++++++++ src/permission/DefaultPermissions.php | 114 +++++++++--------- src/player/Player.php | 10 +- 43 files changed, 267 insertions(+), 115 deletions(-) create mode 100644 src/permission/DefaultPermissionNames.php diff --git a/src/command/defaults/BanCommand.php b/src/command/defaults/BanCommand.php index 6823ba19cb..98616f9ea9 100644 --- a/src/command/defaults/BanCommand.php +++ b/src/command/defaults/BanCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use function array_shift; use function count; @@ -40,7 +41,7 @@ class BanCommand extends VanillaCommand{ "%pocketmine.command.ban.player.description", "%commands.ban.usage" ); - $this->setPermission("pocketmine.command.ban.player"); + $this->setPermission(DefaultPermissionNames::COMMAND_BAN_PLAYER); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/BanIpCommand.php b/src/command/defaults/BanIpCommand.php index 4737ac6b74..f263d47459 100644 --- a/src/command/defaults/BanIpCommand.php +++ b/src/command/defaults/BanIpCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use function array_shift; use function count; @@ -41,7 +42,7 @@ class BanIpCommand extends VanillaCommand{ "%pocketmine.command.ban.ip.description", "%commands.banip.usage" ); - $this->setPermission("pocketmine.command.ban.ip"); + $this->setPermission(DefaultPermissionNames::COMMAND_BAN_IP); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/BanListCommand.php b/src/command/defaults/BanListCommand.php index 95c02f9a5c..ab33bf8aee 100644 --- a/src/command/defaults/BanListCommand.php +++ b/src/command/defaults/BanListCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; use pocketmine\permission\BanEntry; +use pocketmine\permission\DefaultPermissionNames; use function array_map; use function count; use function implode; @@ -42,7 +43,7 @@ class BanListCommand extends VanillaCommand{ "%pocketmine.command.banlist.description", "%commands.banlist.usage" ); - $this->setPermission("pocketmine.command.ban.list"); + $this->setPermission(DefaultPermissionNames::COMMAND_BAN_LIST); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/ClearCommand.php b/src/command/defaults/ClearCommand.php index c0342ab924..03c53c4e6e 100644 --- a/src/command/defaults/ClearCommand.php +++ b/src/command/defaults/ClearCommand.php @@ -29,10 +29,12 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\LegacyStringToItemParser; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function array_merge; use function count; +use function implode; class ClearCommand extends VanillaCommand{ @@ -42,7 +44,7 @@ class ClearCommand extends VanillaCommand{ "%pocketmine.command.clear.description", "%pocketmine.command.clear.usage" ); - $this->setPermission("pocketmine.command.clear.self;pocketmine.command.clear.other"); + $this->setPermission(implode(";", [DefaultPermissionNames::COMMAND_CLEAR_SELF, DefaultPermissionNames::COMMAND_CLEAR_OTHER])); } public function execute(CommandSender $sender, string $commandLabel, array $args){ @@ -61,12 +63,12 @@ class ClearCommand extends VanillaCommand{ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); return true; } - if($target !== $sender && !$sender->hasPermission("pocketmine.command.clear.other")){ + if($target !== $sender && !$sender->hasPermission(DefaultPermissionNames::COMMAND_CLEAR_OTHER)){ $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); return true; } }elseif($sender instanceof Player){ - if(!$sender->hasPermission("pocketmine.command.clear.self")){ + if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_CLEAR_SELF)){ $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); return true; } diff --git a/src/command/defaults/DefaultGamemodeCommand.php b/src/command/defaults/DefaultGamemodeCommand.php index 33f5b16866..308353aee5 100644 --- a/src/command/defaults/DefaultGamemodeCommand.php +++ b/src/command/defaults/DefaultGamemodeCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\GameMode; use function count; @@ -37,7 +38,7 @@ class DefaultGamemodeCommand extends VanillaCommand{ "%pocketmine.command.defaultgamemode.description", "%commands.defaultgamemode.usage" ); - $this->setPermission("pocketmine.command.defaultgamemode"); + $this->setPermission(DefaultPermissionNames::COMMAND_DEFAULTGAMEMODE); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/DeopCommand.php b/src/command/defaults/DeopCommand.php index 8448f27ac6..5a4a488cfa 100644 --- a/src/command/defaults/DeopCommand.php +++ b/src/command/defaults/DeopCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function array_shift; @@ -40,7 +41,7 @@ class DeopCommand extends VanillaCommand{ "%pocketmine.command.deop.description", "%commands.deop.usage" ); - $this->setPermission("pocketmine.command.op.take"); + $this->setPermission(DefaultPermissionNames::COMMAND_OP_TAKE); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/DifficultyCommand.php b/src/command/defaults/DifficultyCommand.php index 1f05070a33..56951b02e3 100644 --- a/src/command/defaults/DifficultyCommand.php +++ b/src/command/defaults/DifficultyCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\world\World; use function count; @@ -38,7 +39,7 @@ class DifficultyCommand extends VanillaCommand{ "%pocketmine.command.difficulty.description", "%commands.difficulty.usage" ); - $this->setPermission("pocketmine.command.difficulty"); + $this->setPermission(DefaultPermissionNames::COMMAND_DIFFICULTY); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/DumpMemoryCommand.php b/src/command/defaults/DumpMemoryCommand.php index f7a48f4def..34c1da9e69 100644 --- a/src/command/defaults/DumpMemoryCommand.php +++ b/src/command/defaults/DumpMemoryCommand.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; +use pocketmine\permission\DefaultPermissionNames; use function date; class DumpMemoryCommand extends VanillaCommand{ @@ -34,7 +35,7 @@ class DumpMemoryCommand extends VanillaCommand{ "Dumps the memory", "/$name [path]" ); - $this->setPermission("pocketmine.command.dumpmemory"); + $this->setPermission(DefaultPermissionNames::COMMAND_DUMPMEMORY); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/EffectCommand.php b/src/command/defaults/EffectCommand.php index df704ba728..d035aba7db 100644 --- a/src/command/defaults/EffectCommand.php +++ b/src/command/defaults/EffectCommand.php @@ -28,6 +28,7 @@ use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\VanillaEffects; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\Limits; use pocketmine\utils\TextFormat; use function count; @@ -41,7 +42,7 @@ class EffectCommand extends VanillaCommand{ "%pocketmine.command.effect.description", "%commands.effect.usage" ); - $this->setPermission("pocketmine.command.effect"); + $this->setPermission(DefaultPermissionNames::COMMAND_EFFECT); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/EnchantCommand.php b/src/command/defaults/EnchantCommand.php index 4c44165678..226c7729b9 100644 --- a/src/command/defaults/EnchantCommand.php +++ b/src/command/defaults/EnchantCommand.php @@ -28,6 +28,7 @@ use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\enchantment\EnchantmentInstance; use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\TextFormat; use function count; @@ -39,7 +40,7 @@ class EnchantCommand extends VanillaCommand{ "%pocketmine.command.enchant.description", "%commands.enchant.usage" ); - $this->setPermission("pocketmine.command.enchant"); + $this->setPermission(DefaultPermissionNames::COMMAND_ENCHANT); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/GamemodeCommand.php b/src/command/defaults/GamemodeCommand.php index c6cc022043..0633b914e6 100644 --- a/src/command/defaults/GamemodeCommand.php +++ b/src/command/defaults/GamemodeCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\GameMode; use pocketmine\player\Player; use pocketmine\utils\TextFormat; @@ -40,7 +41,7 @@ class GamemodeCommand extends VanillaCommand{ "%pocketmine.command.gamemode.description", "%commands.gamemode.usage" ); - $this->setPermission("pocketmine.command.gamemode"); + $this->setPermission(DefaultPermissionNames::COMMAND_GAMEMODE); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/GarbageCollectorCommand.php b/src/command/defaults/GarbageCollectorCommand.php index 1fc6b7f739..1614e9e901 100644 --- a/src/command/defaults/GarbageCollectorCommand.php +++ b/src/command/defaults/GarbageCollectorCommand.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\TextFormat; use function count; use function memory_get_usage; @@ -38,7 +39,7 @@ class GarbageCollectorCommand extends VanillaCommand{ "%pocketmine.command.gc.description", "%pocketmine.command.gc.usage" ); - $this->setPermission("pocketmine.command.gc"); + $this->setPermission(DefaultPermissionNames::COMMAND_GC); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/GiveCommand.php b/src/command/defaults/GiveCommand.php index 1812e6c0c9..3fd2085bdb 100644 --- a/src/command/defaults/GiveCommand.php +++ b/src/command/defaults/GiveCommand.php @@ -30,6 +30,7 @@ use pocketmine\item\LegacyStringToItemParser; use pocketmine\lang\TranslationContainer; use pocketmine\nbt\JsonNbtParser; use pocketmine\nbt\NbtDataException; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\TextFormat; use function array_slice; use function count; @@ -43,7 +44,7 @@ class GiveCommand extends VanillaCommand{ "%pocketmine.command.give.description", "%pocketmine.command.give.usage" ); - $this->setPermission("pocketmine.command.give"); + $this->setPermission(DefaultPermissionNames::COMMAND_GIVE); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/HelpCommand.php b/src/command/defaults/HelpCommand.php index 5e761d1807..ba7dda68e8 100644 --- a/src/command/defaults/HelpCommand.php +++ b/src/command/defaults/HelpCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\TextFormat; use function array_chunk; use function array_pop; @@ -48,7 +49,7 @@ class HelpCommand extends VanillaCommand{ "%commands.help.usage", ["?"] ); - $this->setPermission("pocketmine.command.help"); + $this->setPermission(DefaultPermissionNames::COMMAND_HELP); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/KickCommand.php b/src/command/defaults/KickCommand.php index f90592e4e9..67bbcf9d1c 100644 --- a/src/command/defaults/KickCommand.php +++ b/src/command/defaults/KickCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function array_shift; @@ -42,7 +43,7 @@ class KickCommand extends VanillaCommand{ "%pocketmine.command.kick.description", "%commands.kick.usage" ); - $this->setPermission("pocketmine.command.kick"); + $this->setPermission(DefaultPermissionNames::COMMAND_KICK); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/KillCommand.php b/src/command/defaults/KillCommand.php index f717719163..b399f05917 100644 --- a/src/command/defaults/KillCommand.php +++ b/src/command/defaults/KillCommand.php @@ -28,9 +28,11 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function count; +use function implode; class KillCommand extends VanillaCommand{ @@ -41,7 +43,7 @@ class KillCommand extends VanillaCommand{ "%pocketmine.command.kill.usage", ["suicide"] ); - $this->setPermission("pocketmine.command.kill.self;pocketmine.command.kill.other"); + $this->setPermission(implode(";", [DefaultPermissionNames::COMMAND_KILL_SELF, DefaultPermissionNames::COMMAND_KILL_OTHER])); } public function execute(CommandSender $sender, string $commandLabel, array $args){ @@ -54,7 +56,7 @@ class KillCommand extends VanillaCommand{ } if(count($args) === 1){ - if(!$sender->hasPermission("pocketmine.command.kill.other")){ + if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_KILL_OTHER)){ $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); return true; @@ -73,7 +75,7 @@ class KillCommand extends VanillaCommand{ } if($sender instanceof Player){ - if(!$sender->hasPermission("pocketmine.command.kill.self")){ + if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_KILL_SELF)){ $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); return true; diff --git a/src/command/defaults/ListCommand.php b/src/command/defaults/ListCommand.php index 3e703566a6..70cbd90734 100644 --- a/src/command/defaults/ListCommand.php +++ b/src/command/defaults/ListCommand.php @@ -25,6 +25,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use function array_filter; use function array_map; @@ -41,7 +42,7 @@ class ListCommand extends VanillaCommand{ "%pocketmine.command.list.description", "%command.players.usage" ); - $this->setPermission("pocketmine.command.list"); + $this->setPermission(DefaultPermissionNames::COMMAND_LIST); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/MeCommand.php b/src/command/defaults/MeCommand.php index 8b6d9a7fb7..1f643ac215 100644 --- a/src/command/defaults/MeCommand.php +++ b/src/command/defaults/MeCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function count; @@ -39,7 +40,7 @@ class MeCommand extends VanillaCommand{ "%pocketmine.command.me.description", "%commands.me.usage" ); - $this->setPermission("pocketmine.command.me"); + $this->setPermission(DefaultPermissionNames::COMMAND_ME); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/OpCommand.php b/src/command/defaults/OpCommand.php index 0b4537d2cc..a2aef219b6 100644 --- a/src/command/defaults/OpCommand.php +++ b/src/command/defaults/OpCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function array_shift; @@ -40,7 +41,7 @@ class OpCommand extends VanillaCommand{ "%pocketmine.command.op.description", "%commands.op.usage" ); - $this->setPermission("pocketmine.command.op.give"); + $this->setPermission(DefaultPermissionNames::COMMAND_OP_GIVE); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/PardonCommand.php b/src/command/defaults/PardonCommand.php index f46c0b4858..c9b04e7962 100644 --- a/src/command/defaults/PardonCommand.php +++ b/src/command/defaults/PardonCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use function count; class PardonCommand extends VanillaCommand{ @@ -38,7 +39,7 @@ class PardonCommand extends VanillaCommand{ "%commands.unban.usage", ["unban"] ); - $this->setPermission("pocketmine.command.unban.player"); + $this->setPermission(DefaultPermissionNames::COMMAND_UNBAN_PLAYER); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/PardonIpCommand.php b/src/command/defaults/PardonIpCommand.php index 0133f046db..df515d5ce7 100644 --- a/src/command/defaults/PardonIpCommand.php +++ b/src/command/defaults/PardonIpCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use function count; use function preg_match; @@ -39,7 +40,7 @@ class PardonIpCommand extends VanillaCommand{ "%commands.unbanip.usage", ["unban-ip"] ); - $this->setPermission("pocketmine.command.unban.ip"); + $this->setPermission(DefaultPermissionNames::COMMAND_UNBAN_IP); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/ParticleCommand.php b/src/command/defaults/ParticleCommand.php index 1420f5d3c4..560b3e426d 100644 --- a/src/command/defaults/ParticleCommand.php +++ b/src/command/defaults/ParticleCommand.php @@ -31,6 +31,7 @@ use pocketmine\item\ItemFactory; use pocketmine\item\VanillaItems; use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\Random; use pocketmine\utils\TextFormat; @@ -80,7 +81,7 @@ class ParticleCommand extends VanillaCommand{ "%pocketmine.command.particle.description", "%pocketmine.command.particle.usage" ); - $this->setPermission("pocketmine.command.particle"); + $this->setPermission(DefaultPermissionNames::COMMAND_PARTICLE); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/PluginsCommand.php b/src/command/defaults/PluginsCommand.php index 993ea0bbe4..ac3c9cd8ac 100644 --- a/src/command/defaults/PluginsCommand.php +++ b/src/command/defaults/PluginsCommand.php @@ -25,6 +25,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\plugin\Plugin; use pocketmine\utils\TextFormat; use function array_map; @@ -42,7 +43,7 @@ class PluginsCommand extends VanillaCommand{ "%pocketmine.command.plugins.usage", ["pl"] ); - $this->setPermission("pocketmine.command.plugins"); + $this->setPermission(DefaultPermissionNames::COMMAND_PLUGINS); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/SaveCommand.php b/src/command/defaults/SaveCommand.php index 1949baa307..e701d3801e 100644 --- a/src/command/defaults/SaveCommand.php +++ b/src/command/defaults/SaveCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use function microtime; use function round; @@ -37,7 +38,7 @@ class SaveCommand extends VanillaCommand{ "%pocketmine.command.save.description", "%commands.save.usage" ); - $this->setPermission("pocketmine.command.save.perform"); + $this->setPermission(DefaultPermissionNames::COMMAND_SAVE_PERFORM); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/SaveOffCommand.php b/src/command/defaults/SaveOffCommand.php index 82687867af..9c08e24600 100644 --- a/src/command/defaults/SaveOffCommand.php +++ b/src/command/defaults/SaveOffCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; class SaveOffCommand extends VanillaCommand{ @@ -35,7 +36,7 @@ class SaveOffCommand extends VanillaCommand{ "%pocketmine.command.saveoff.description", "%commands.save-off.usage" ); - $this->setPermission("pocketmine.command.save.disable"); + $this->setPermission(DefaultPermissionNames::COMMAND_SAVE_DISABLE); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/SaveOnCommand.php b/src/command/defaults/SaveOnCommand.php index 3df4808bd6..08a342de8d 100644 --- a/src/command/defaults/SaveOnCommand.php +++ b/src/command/defaults/SaveOnCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; class SaveOnCommand extends VanillaCommand{ @@ -35,7 +36,7 @@ class SaveOnCommand extends VanillaCommand{ "%pocketmine.command.saveon.description", "%commands.save-on.usage" ); - $this->setPermission("pocketmine.command.save.enable"); + $this->setPermission(DefaultPermissionNames::COMMAND_SAVE_ENABLE); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/SayCommand.php b/src/command/defaults/SayCommand.php index 709d68facf..64adf3d90a 100644 --- a/src/command/defaults/SayCommand.php +++ b/src/command/defaults/SayCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\CommandSender; use pocketmine\command\ConsoleCommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function count; @@ -40,7 +41,7 @@ class SayCommand extends VanillaCommand{ "%pocketmine.command.say.description", "%commands.say.usage" ); - $this->setPermission("pocketmine.command.say"); + $this->setPermission(DefaultPermissionNames::COMMAND_SAY); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/SeedCommand.php b/src/command/defaults/SeedCommand.php index 29017edb51..d3015436aa 100644 --- a/src/command/defaults/SeedCommand.php +++ b/src/command/defaults/SeedCommand.php @@ -25,6 +25,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; class SeedCommand extends VanillaCommand{ @@ -35,7 +36,7 @@ class SeedCommand extends VanillaCommand{ "%pocketmine.command.seed.description", "%commands.seed.usage" ); - $this->setPermission("pocketmine.command.seed"); + $this->setPermission(DefaultPermissionNames::COMMAND_SEED); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/SetWorldSpawnCommand.php b/src/command/defaults/SetWorldSpawnCommand.php index 45534184ac..6ff10470d1 100644 --- a/src/command/defaults/SetWorldSpawnCommand.php +++ b/src/command/defaults/SetWorldSpawnCommand.php @@ -28,6 +28,7 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function count; @@ -41,7 +42,7 @@ class SetWorldSpawnCommand extends VanillaCommand{ "%pocketmine.command.setworldspawn.description", "%commands.setworldspawn.usage" ); - $this->setPermission("pocketmine.command.setworldspawn"); + $this->setPermission(DefaultPermissionNames::COMMAND_SETWORLDSPAWN); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/SpawnpointCommand.php b/src/command/defaults/SpawnpointCommand.php index 3c5cf4f0c8..fcf86869d1 100644 --- a/src/command/defaults/SpawnpointCommand.php +++ b/src/command/defaults/SpawnpointCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; use pocketmine\world\Position; @@ -42,7 +43,7 @@ class SpawnpointCommand extends VanillaCommand{ "%pocketmine.command.spawnpoint.description", "%commands.spawnpoint.usage" ); - $this->setPermission("pocketmine.command.spawnpoint"); + $this->setPermission(DefaultPermissionNames::COMMAND_SPAWNPOINT); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/StatusCommand.php b/src/command/defaults/StatusCommand.php index cbf53c0ee5..a64dc6dc90 100644 --- a/src/command/defaults/StatusCommand.php +++ b/src/command/defaults/StatusCommand.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\Process; use pocketmine\utils\TextFormat; use function count; @@ -40,7 +41,7 @@ class StatusCommand extends VanillaCommand{ "%pocketmine.command.status.description", "%pocketmine.command.status.usage" ); - $this->setPermission("pocketmine.command.status"); + $this->setPermission(DefaultPermissionNames::COMMAND_STATUS); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/StopCommand.php b/src/command/defaults/StopCommand.php index cc5e2f1bf9..1b943d0d78 100644 --- a/src/command/defaults/StopCommand.php +++ b/src/command/defaults/StopCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; class StopCommand extends VanillaCommand{ @@ -35,7 +36,7 @@ class StopCommand extends VanillaCommand{ "%pocketmine.command.stop.description", "%commands.stop.usage" ); - $this->setPermission("pocketmine.command.stop"); + $this->setPermission(DefaultPermissionNames::COMMAND_STOP); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/TeleportCommand.php b/src/command/defaults/TeleportCommand.php index 5dd3d9b144..77a6642711 100644 --- a/src/command/defaults/TeleportCommand.php +++ b/src/command/defaults/TeleportCommand.php @@ -28,6 +28,7 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\entity\Location; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\TextFormat; @@ -44,7 +45,7 @@ class TeleportCommand extends VanillaCommand{ "%commands.tp.usage", ["teleport"] ); - $this->setPermission("pocketmine.command.teleport"); + $this->setPermission(DefaultPermissionNames::COMMAND_TELEPORT); } private function findPlayer(CommandSender $sender, string $playerName) : ?Player{ diff --git a/src/command/defaults/TellCommand.php b/src/command/defaults/TellCommand.php index 27f9d811c6..f4e9c90f0a 100644 --- a/src/command/defaults/TellCommand.php +++ b/src/command/defaults/TellCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function array_shift; @@ -42,7 +43,7 @@ class TellCommand extends VanillaCommand{ "%commands.message.usage", ["w", "msg"] ); - $this->setPermission("pocketmine.command.tell"); + $this->setPermission(DefaultPermissionNames::COMMAND_TELL); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/TimeCommand.php b/src/command/defaults/TimeCommand.php index f98fdee5e6..23e1e1556b 100644 --- a/src/command/defaults/TimeCommand.php +++ b/src/command/defaults/TimeCommand.php @@ -27,10 +27,12 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; use pocketmine\world\World; use function count; +use function implode; class TimeCommand extends VanillaCommand{ @@ -40,16 +42,25 @@ class TimeCommand extends VanillaCommand{ "%pocketmine.command.time.description", "%pocketmine.command.time.usage" ); - $this->setPermission("pocketmine.command.time.add;pocketmine.command.time.set;pocketmine.command.time.start;pocketmine.command.time.stop"); + $this->setPermission(implode(";", [ + DefaultPermissionNames::COMMAND_TIME_ADD, + DefaultPermissionNames::COMMAND_TIME_SET, + DefaultPermissionNames::COMMAND_TIME_START, + DefaultPermissionNames::COMMAND_TIME_STOP, + DefaultPermissionNames::COMMAND_TIME_QUERY + ])); } public function execute(CommandSender $sender, string $commandLabel, array $args){ + if(!$this->testPermission($sender)){ + return true; + } if(count($args) < 1){ throw new InvalidCommandSyntaxException(); } if($args[0] === "start"){ - if(!$sender->hasPermission("pocketmine.command.time.start")){ + if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_TIME_START)){ $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); return true; @@ -60,7 +71,7 @@ class TimeCommand extends VanillaCommand{ Command::broadcastCommandMessage($sender, "Restarted the time"); return true; }elseif($args[0] === "stop"){ - if(!$sender->hasPermission("pocketmine.command.time.stop")){ + if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_TIME_STOP)){ $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); return true; @@ -71,7 +82,7 @@ class TimeCommand extends VanillaCommand{ Command::broadcastCommandMessage($sender, "Stopped the time"); return true; }elseif($args[0] === "query"){ - if(!$sender->hasPermission("pocketmine.command.time.query")){ + if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_TIME_QUERY)){ $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); return true; @@ -90,7 +101,7 @@ class TimeCommand extends VanillaCommand{ } if($args[0] === "set"){ - if(!$sender->hasPermission("pocketmine.command.time.set")){ + if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_TIME_SET)){ $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); return true; @@ -125,7 +136,7 @@ class TimeCommand extends VanillaCommand{ } Command::broadcastCommandMessage($sender, new TranslationContainer("commands.time.set", [$value])); }elseif($args[0] === "add"){ - if(!$sender->hasPermission("pocketmine.command.time.add")){ + if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_TIME_ADD)){ $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); return true; diff --git a/src/command/defaults/TimingsCommand.php b/src/command/defaults/TimingsCommand.php index bcdd3ea102..e4dbc72a06 100644 --- a/src/command/defaults/TimingsCommand.php +++ b/src/command/defaults/TimingsCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\scheduler\BulkCurlTask; use pocketmine\scheduler\BulkCurlTaskOperation; @@ -60,7 +61,7 @@ class TimingsCommand extends VanillaCommand{ "%pocketmine.command.timings.description", "%pocketmine.command.timings.usage" ); - $this->setPermission("pocketmine.command.timings"); + $this->setPermission(DefaultPermissionNames::COMMAND_TIMINGS); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/TitleCommand.php b/src/command/defaults/TitleCommand.php index f03123fdbb..ec846763b1 100644 --- a/src/command/defaults/TitleCommand.php +++ b/src/command/defaults/TitleCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use function array_slice; use function count; use function implode; @@ -38,7 +39,7 @@ class TitleCommand extends VanillaCommand{ "%pocketmine.command.title.description", "%commands.title.usage" ); - $this->setPermission("pocketmine.command.title"); + $this->setPermission(DefaultPermissionNames::COMMAND_TITLE); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/TransferServerCommand.php b/src/command/defaults/TransferServerCommand.php index 295ce3f453..1e783f9f99 100644 --- a/src/command/defaults/TransferServerCommand.php +++ b/src/command/defaults/TransferServerCommand.php @@ -25,6 +25,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use function count; @@ -36,7 +37,7 @@ class TransferServerCommand extends VanillaCommand{ "%pocketmine.command.transferserver.description", "%pocketmine.command.transferserver.usage" ); - $this->setPermission("pocketmine.command.transferserver"); + $this->setPermission(DefaultPermissionNames::COMMAND_TRANSFERSERVER); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/VersionCommand.php b/src/command/defaults/VersionCommand.php index e132671bd1..884e4c77fb 100644 --- a/src/command/defaults/VersionCommand.php +++ b/src/command/defaults/VersionCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\lang\TranslationContainer; use pocketmine\network\mcpe\protocol\ProtocolInfo; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\plugin\Plugin; use pocketmine\utils\TextFormat; use function count; @@ -42,7 +43,7 @@ class VersionCommand extends VanillaCommand{ "%pocketmine.command.version.usage", ["ver", "about"] ); - $this->setPermission("pocketmine.command.version"); + $this->setPermission(DefaultPermissionNames::COMMAND_VERSION); } public function execute(CommandSender $sender, string $commandLabel, array $args){ diff --git a/src/command/defaults/WhitelistCommand.php b/src/command/defaults/WhitelistCommand.php index 1a9547c37a..e0fd3ae10a 100644 --- a/src/command/defaults/WhitelistCommand.php +++ b/src/command/defaults/WhitelistCommand.php @@ -27,7 +27,9 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\TranslationContainer; +use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; +use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\TextFormat; use function count; use function implode; @@ -43,7 +45,14 @@ class WhitelistCommand extends VanillaCommand{ "%pocketmine.command.whitelist.description", "%commands.whitelist.usage" ); - $this->setPermission("pocketmine.command.whitelist.reload;pocketmine.command.whitelist.enable;pocketmine.command.whitelist.disable;pocketmine.command.whitelist.list;pocketmine.command.whitelist.add;pocketmine.command.whitelist.remove"); + $this->setPermission(implode(";", [ + DefaultPermissionNames::COMMAND_WHITELIST_RELOAD, + DefaultPermissionNames::COMMAND_WHITELIST_ENABLE, + DefaultPermissionNames::COMMAND_WHITELIST_DISABLE, + DefaultPermissionNames::COMMAND_WHITELIST_LIST, + DefaultPermissionNames::COMMAND_WHITELIST_ADD, + DefaultPermissionNames::COMMAND_WHITELIST_REMOVE + ])); } public function execute(CommandSender $sender, string $commandLabel, array $args){ @@ -115,11 +124,18 @@ class WhitelistCommand extends VanillaCommand{ } private function badPerm(CommandSender $sender, string $subcommand) : bool{ - static $map = [ - "on" => "enable", - "off" => "disable" - ]; - if(!$sender->hasPermission("pocketmine.command.whitelist." . ($map[$subcommand] ?? $subcommand))){ + $permission = [ + "reload" => DefaultPermissionNames::COMMAND_WHITELIST_RELOAD, + "on" => DefaultPermissionNames::COMMAND_WHITELIST_ENABLE, + "off" => DefaultPermissionNames::COMMAND_WHITELIST_DISABLE, + "list" => DefaultPermissionNames::COMMAND_WHITELIST_LIST, + "add" => DefaultPermissionNames::COMMAND_WHITELIST_ADD, + "remove" => DefaultPermissionNames::COMMAND_WHITELIST_REMOVE + ][$subcommand] ?? null; + if($permission === null){ + throw new AssumptionFailedError("Unknown subcommand $subcommand"); + } + if(!$sender->hasPermission($permission)){ $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); return true; diff --git a/src/permission/DefaultPermissionNames.php b/src/permission/DefaultPermissionNames.php new file mode 100644 index 0000000000..d90b72f54d --- /dev/null +++ b/src/permission/DefaultPermissionNames.php @@ -0,0 +1,83 @@ +hasPermission($channel)){ + foreach([ + DefaultPermissionNames::BROADCAST_ADMIN => Server::BROADCAST_CHANNEL_ADMINISTRATIVE, + DefaultPermissionNames::BROADCAST_USER => Server::BROADCAST_CHANNEL_USERS + ] as $permission => $channel){ + if($this->hasPermission($permission)){ $this->server->subscribeToBroadcastChannel($channel, $this); }else{ $this->server->unsubscribeFromBroadcastChannel($channel, $this); @@ -807,7 +811,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->spawnToAll(); - if($this->server->getUpdater()->hasUpdate() and $this->hasPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE) and $this->server->getConfigGroup()->getPropertyBool("auto-updater.on-update.warn-ops", true)){ + if($this->server->getUpdater()->hasUpdate() and $this->hasPermission(DefaultPermissionNames::BROADCAST_ADMIN) and $this->server->getConfigGroup()->getPropertyBool("auto-updater.on-update.warn-ops", true)){ $this->server->getUpdater()->showPlayerUpdate($this); } From a70bd115f12f2bc78990f07b458db6e815a1adba Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Jun 2021 19:24:42 +0100 Subject: [PATCH 2563/3224] Moved console-specific stuff to its own namespace this stuff has different functionality than everything else in the command namespace (specifically console handling), so it doesn't belong in here. I know that this will probably break some plugins, but I don't care, because plugins shouldn't have been abusing ConsoleCommandSender in the first place. --- src/Server.php | 4 ++-- src/command/Command.php | 1 + src/command/defaults/SayCommand.php | 2 +- src/{command => console}/CommandReader.php | 2 +- src/{command => console}/CommandReaderThread.php | 2 +- src/{command => console}/ConsoleCommandSender.php | 3 ++- tests/phpstan/configs/actual-problems.neon | 2 +- tests/phpstan/configs/l7-baseline.neon | 4 ++-- tests/phpstan/configs/phpstan-bugs.neon | 2 +- 9 files changed, 12 insertions(+), 10 deletions(-) rename src/{command => console}/CommandReader.php (98%) rename src/{command => console}/CommandReaderThread.php (98%) rename src/{command => console}/ConsoleCommandSender.php (97%) diff --git a/src/Server.php b/src/Server.php index 512354548f..7b3496dd2f 100644 --- a/src/Server.php +++ b/src/Server.php @@ -28,10 +28,10 @@ declare(strict_types=1); namespace pocketmine; use pocketmine\command\Command; -use pocketmine\command\CommandReaderThread; use pocketmine\command\CommandSender; -use pocketmine\command\ConsoleCommandSender; use pocketmine\command\SimpleCommandMap; +use pocketmine\console\CommandReaderThread; +use pocketmine\console\ConsoleCommandSender; use pocketmine\crafting\CraftingManager; use pocketmine\crafting\CraftingManagerFromDataHelper; use pocketmine\entity\EntityDataHelper; diff --git a/src/command/Command.php b/src/command/Command.php index 740571e638..d779721018 100644 --- a/src/command/Command.php +++ b/src/command/Command.php @@ -27,6 +27,7 @@ declare(strict_types=1); namespace pocketmine\command; use pocketmine\command\utils\CommandException; +use pocketmine\console\ConsoleCommandSender; use pocketmine\lang\TranslationContainer; use pocketmine\permission\PermissionManager; use pocketmine\Server; diff --git a/src/command/defaults/SayCommand.php b/src/command/defaults/SayCommand.php index 64adf3d90a..ac3faa8e57 100644 --- a/src/command/defaults/SayCommand.php +++ b/src/command/defaults/SayCommand.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; -use pocketmine\command\ConsoleCommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\console\ConsoleCommandSender; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; diff --git a/src/command/CommandReader.php b/src/console/CommandReader.php similarity index 98% rename from src/command/CommandReader.php rename to src/console/CommandReader.php index 0aeefdf2b1..ce10c587df 100644 --- a/src/command/CommandReader.php +++ b/src/console/CommandReader.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\command; +namespace pocketmine\console; use function fclose; use function fgets; diff --git a/src/command/CommandReaderThread.php b/src/console/CommandReaderThread.php similarity index 98% rename from src/command/CommandReaderThread.php rename to src/console/CommandReaderThread.php index 5ae04a1c57..4bcd993057 100644 --- a/src/command/CommandReaderThread.php +++ b/src/console/CommandReaderThread.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\command; +namespace pocketmine\console; use pocketmine\snooze\SleeperNotifier; use pocketmine\thread\Thread; diff --git a/src/command/ConsoleCommandSender.php b/src/console/ConsoleCommandSender.php similarity index 97% rename from src/command/ConsoleCommandSender.php rename to src/console/ConsoleCommandSender.php index 5649f9f4c9..eba16586ae 100644 --- a/src/command/ConsoleCommandSender.php +++ b/src/console/ConsoleCommandSender.php @@ -21,8 +21,9 @@ declare(strict_types=1); -namespace pocketmine\command; +namespace pocketmine\console; +use pocketmine\command\CommandSender; use pocketmine\lang\Language; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissions; diff --git a/tests/phpstan/configs/actual-problems.neon b/tests/phpstan/configs/actual-problems.neon index 49b2c5f07e..e01519bffd 100644 --- a/tests/phpstan/configs/actual-problems.neon +++ b/tests/phpstan/configs/actual-problems.neon @@ -6,7 +6,7 @@ parameters: path: ../../../src/CrashDump.php - - message: "#^Instanceof between pocketmine\\\\command\\\\CommandReaderThread and pocketmine\\\\command\\\\CommandReaderThread will always evaluate to true\\.$#" + message: "#^Instanceof between pocketmine\\\\console\\\\CommandReaderThread and pocketmine\\\\console\\\\CommandReaderThread will always evaluate to true\\.$#" count: 1 path: ../../../src/Server.php diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index f3d116666e..cec2e9a225 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -436,9 +436,9 @@ parameters: path: ../../../src/block/tile/TileFactory.php - - message: "#^Property pocketmine\\\\command\\\\CommandReader\\:\\:\\$stdin \\(resource\\) does not accept resource\\|false\\.$#" + message: "#^Property pocketmine\\\\console\\\\CommandReader\\:\\:\\$stdin \\(resource\\) does not accept resource\\|false\\.$#" count: 1 - path: ../../../src/command/CommandReader.php + path: ../../../src/console/CommandReader.php - message: "#^Only booleans are allowed in an if condition, int\\|false given\\.$#" diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index d4a7743530..215140dba7 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -3,7 +3,7 @@ parameters: - message: "#^Call to function is_resource\\(\\) with resource will always evaluate to true\\.$#" count: 2 - path: ../../../src/command/CommandReader.php + path: ../../../src/console/CommandReader.php - message: "#^Method pocketmine\\\\crafting\\\\CraftingManager\\:\\:getDestructorCallbacks\\(\\) should return pocketmine\\\\utils\\\\ObjectSet\\ but returns pocketmine\\\\utils\\\\ObjectSet\\\\|pocketmine\\\\utils\\\\ObjectSet\\\\.$#" From e14bad4ea6a90a21f72bae810e7a3b19b7611c1e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Jun 2021 19:29:58 +0100 Subject: [PATCH 2564/3224] Rename CommandReader and friends to ConsoleReader --- src/Server.php | 8 ++++---- src/console/{CommandReader.php => ConsoleReader.php} | 2 +- .../{CommandReaderThread.php => ConsoleReaderThread.php} | 4 ++-- tests/phpstan/configs/actual-problems.neon | 2 +- tests/phpstan/configs/l7-baseline.neon | 4 ++-- tests/phpstan/configs/phpstan-bugs.neon | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) rename src/console/{CommandReader.php => ConsoleReader.php} (98%) rename src/console/{CommandReaderThread.php => ConsoleReaderThread.php} (96%) diff --git a/src/Server.php b/src/Server.php index 7b3496dd2f..cb6958c925 100644 --- a/src/Server.php +++ b/src/Server.php @@ -30,7 +30,7 @@ namespace pocketmine; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\SimpleCommandMap; -use pocketmine\console\CommandReaderThread; +use pocketmine\console\ConsoleReaderThread; use pocketmine\console\ConsoleCommandSender; use pocketmine\crafting\CraftingManager; use pocketmine\crafting\CraftingManagerFromDataHelper; @@ -227,7 +227,7 @@ class Server{ /** @var MemoryManager */ private $memoryManager; - /** @var CommandReaderThread */ + /** @var ConsoleReaderThread */ private $console; /** @var SimpleCommandMap */ @@ -1130,7 +1130,7 @@ class Server{ $consoleNotifier = new SleeperNotifier(); $commandBuffer = new \Threaded(); - $this->console = new CommandReaderThread($commandBuffer, $consoleNotifier); + $this->console = new ConsoleReaderThread($commandBuffer, $consoleNotifier); $this->tickSleeper->addNotifier($consoleNotifier, function() use ($commandBuffer, $consoleSender) : void{ Timings::$serverCommand->startTiming(); while(($line = $commandBuffer->shift()) !== null){ @@ -1419,7 +1419,7 @@ class Server{ $this->configGroup->save(); } - if($this->console instanceof CommandReaderThread){ + if($this->console instanceof ConsoleReaderThread){ $this->getLogger()->debug("Closing console"); $this->console->shutdown(); $this->console->notify(); diff --git a/src/console/CommandReader.php b/src/console/ConsoleReader.php similarity index 98% rename from src/console/CommandReader.php rename to src/console/ConsoleReader.php index ce10c587df..9da61cb6dd 100644 --- a/src/console/CommandReader.php +++ b/src/console/ConsoleReader.php @@ -31,7 +31,7 @@ use function stream_select; use function trim; use function usleep; -final class CommandReader{ +final class ConsoleReader{ /** @var resource */ private $stdin; diff --git a/src/console/CommandReaderThread.php b/src/console/ConsoleReaderThread.php similarity index 96% rename from src/console/CommandReaderThread.php rename to src/console/ConsoleReaderThread.php index 4bcd993057..accc6a8398 100644 --- a/src/console/CommandReaderThread.php +++ b/src/console/ConsoleReaderThread.php @@ -30,7 +30,7 @@ use function microtime; use function preg_replace; use function usleep; -final class CommandReaderThread extends Thread{ +final class ConsoleReaderThread extends Thread{ private \Threaded $buffer; private ?SleeperNotifier $notifier; @@ -63,7 +63,7 @@ final class CommandReaderThread extends Thread{ $buffer = $this->buffer; $notifier = $this->notifier; - $reader = new CommandReader(); + $reader = new ConsoleReader(); while(!$this->shutdown){ $line = $reader->readLine(); diff --git a/tests/phpstan/configs/actual-problems.neon b/tests/phpstan/configs/actual-problems.neon index e01519bffd..06987c93c3 100644 --- a/tests/phpstan/configs/actual-problems.neon +++ b/tests/phpstan/configs/actual-problems.neon @@ -6,7 +6,7 @@ parameters: path: ../../../src/CrashDump.php - - message: "#^Instanceof between pocketmine\\\\console\\\\CommandReaderThread and pocketmine\\\\console\\\\CommandReaderThread will always evaluate to true\\.$#" + message: "#^Instanceof between pocketmine\\\\console\\\\ConsoleReaderThread and pocketmine\\\\console\\\\ConsoleReaderThread will always evaluate to true\\.$#" count: 1 path: ../../../src/Server.php diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index cec2e9a225..a9eb810285 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -436,9 +436,9 @@ parameters: path: ../../../src/block/tile/TileFactory.php - - message: "#^Property pocketmine\\\\console\\\\CommandReader\\:\\:\\$stdin \\(resource\\) does not accept resource\\|false\\.$#" + message: "#^Property pocketmine\\\\console\\\\ConsoleReader\\:\\:\\$stdin \\(resource\\) does not accept resource\\|false\\.$#" count: 1 - path: ../../../src/console/CommandReader.php + path: ../../../src/console/ConsoleReader.php - message: "#^Only booleans are allowed in an if condition, int\\|false given\\.$#" diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 215140dba7..7d22109867 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -3,7 +3,7 @@ parameters: - message: "#^Call to function is_resource\\(\\) with resource will always evaluate to true\\.$#" count: 2 - path: ../../../src/console/CommandReader.php + path: ../../../src/console/ConsoleReader.php - message: "#^Method pocketmine\\\\crafting\\\\CraftingManager\\:\\:getDestructorCallbacks\\(\\) should return pocketmine\\\\utils\\\\ObjectSet\\ but returns pocketmine\\\\utils\\\\ObjectSet\\\\|pocketmine\\\\utils\\\\ObjectSet\\\\.$#" From 8cd7cc7c009e4ca342265d7551be91f686839ac2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Jun 2021 19:32:05 +0100 Subject: [PATCH 2565/3224] pacify php-cs-fixer --- src/Server.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Server.php b/src/Server.php index cb6958c925..8aa06aaacf 100644 --- a/src/Server.php +++ b/src/Server.php @@ -30,8 +30,8 @@ namespace pocketmine; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\SimpleCommandMap; -use pocketmine\console\ConsoleReaderThread; use pocketmine\console\ConsoleCommandSender; +use pocketmine\console\ConsoleReaderThread; use pocketmine\crafting\CraftingManager; use pocketmine\crafting\CraftingManagerFromDataHelper; use pocketmine\entity\EntityDataHelper; From 9b30c2fedaf2381cd36ec1084512ca40c51dde1a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Jun 2021 20:56:04 +0100 Subject: [PATCH 2566/3224] Extract a DelegateInventory from EnderChestInventory --- src/block/inventory/EnderChestInventory.php | 42 +---------- src/inventory/DelegateInventory.php | 78 +++++++++++++++++++++ 2 files changed, 81 insertions(+), 39 deletions(-) create mode 100644 src/inventory/DelegateInventory.php diff --git a/src/block/inventory/EnderChestInventory.php b/src/block/inventory/EnderChestInventory.php index 4bf9bef833..6887219c69 100644 --- a/src/block/inventory/EnderChestInventory.php +++ b/src/block/inventory/EnderChestInventory.php @@ -24,12 +24,9 @@ declare(strict_types=1); namespace pocketmine\block\inventory; use pocketmine\block\tile\EnderChest; -use pocketmine\inventory\BaseInventory; -use pocketmine\inventory\CallbackInventoryListener; +use pocketmine\inventory\DelegateInventory; use pocketmine\inventory\Inventory; -use pocketmine\inventory\InventoryListener; use pocketmine\inventory\PlayerEnderInventory; -use pocketmine\item\Item; use pocketmine\network\mcpe\protocol\BlockEventPacket; use pocketmine\player\Player; use pocketmine\world\Position; @@ -40,52 +37,23 @@ use pocketmine\world\sound\Sound; /** * EnderChestInventory is not a real inventory; it's just a gateway to the player's ender inventory. */ -class EnderChestInventory extends BaseInventory implements BlockInventory{ +class EnderChestInventory extends DelegateInventory implements BlockInventory{ use AnimatedBlockInventoryTrait { onClose as animatedBlockInventoryTrait_onClose; } private PlayerEnderInventory $inventory; - private InventoryListener $inventoryListener; public function __construct(Position $holder, PlayerEnderInventory $inventory){ - parent::__construct(); + parent::__construct($inventory); $this->holder = $holder; $this->inventory = $inventory; - $this->inventory->getListeners()->add($this->inventoryListener = new CallbackInventoryListener( - function(Inventory $unused, int $slot, Item $oldItem) : void{ - $this->onSlotChange($slot, $oldItem); - }, - function(Inventory $unused, array $oldContents) : void{ - $this->onContentChange($oldContents); - } - )); } public function getEnderInventory() : PlayerEnderInventory{ return $this->inventory; } - public function getSize() : int{ - return $this->inventory->getSize(); - } - - public function getItem(int $index) : Item{ - return $this->inventory->getItem($index); - } - - protected function internalSetItem(int $index, Item $item) : void{ - $this->inventory->setItem($index, $item); - } - - public function getContents(bool $includeEmpty = false) : array{ - return $this->inventory->getContents($includeEmpty); - } - - protected function internalSetContents(array $items) : void{ - $this->inventory->setContents($items); - } - public function getViewerCount() : int{ $enderChest = $this->getHolder()->getWorld()->getTile($this->getHolder()); if(!$enderChest instanceof EnderChest){ @@ -115,9 +83,5 @@ class EnderChestInventory extends BaseInventory implements BlockInventory{ if($enderChest instanceof EnderChest){ $enderChest->setViewerCount($enderChest->getViewerCount() - 1); } - if($who === $this->inventory->getHolder()){ - $this->inventory->getListeners()->remove($this->inventoryListener); - $this->inventoryListener = CallbackInventoryListener::onAnyChange(static function() : void{}); //break cyclic reference - } } } diff --git a/src/inventory/DelegateInventory.php b/src/inventory/DelegateInventory.php new file mode 100644 index 0000000000..484df6d24e --- /dev/null +++ b/src/inventory/DelegateInventory.php @@ -0,0 +1,78 @@ +backingInventory = $backingInventory; + $this->backingInventory->getListeners()->add($this->inventoryListener = new CallbackInventoryListener( + function(Inventory $unused, int $slot, Item $oldItem) : void{ + $this->onSlotChange($slot, $oldItem); + }, + function(Inventory $unused, array $oldContents) : void{ + $this->onContentChange($oldContents); + } + )); + } + + public function getSize() : int{ + return $this->backingInventory->getSize(); + } + + public function getItem(int $index) : Item{ + return $this->backingInventory->getItem($index); + } + + protected function internalSetItem(int $index, Item $item) : void{ + $this->backingInventory->setItem($index, $item); + } + + public function getContents(bool $includeEmpty = false) : array{ + return $this->backingInventory->getContents($includeEmpty); + } + + protected function internalSetContents(array $items) : void{ + $this->backingInventory->setContents($items); + } + + public function onClose(Player $who) : void{ + parent::onClose($who); + if(count($this->getViewers()) === 0 && count($this->getListeners()->toArray()) === 1){ + $this->backingInventory->getListeners()->remove($this->inventoryListener); + $this->inventoryListener = CallbackInventoryListener::onAnyChange(static function() : void{}); //break cyclic reference + } + } +} From b8ebf8936ed67d15b78b7c1bbd5dbf44e156b570 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Jun 2021 21:21:23 +0100 Subject: [PATCH 2567/3224] InventoryManager: fix container open callbacks not working this was reported to me on socials by multiple different people, but nobody reported an issue so I almost forgot. >.< --- src/network/mcpe/InventoryManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index e162687b63..814f6be86f 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -145,8 +145,8 @@ class InventoryManager{ $this->session->sendDataPacket($pk); } $this->syncContents($inventory); + return; } - return; } throw new \UnsupportedOperationException("Unsupported inventory type"); } From 02fab77e553a7b91e58868214bff3f551166f222 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Jun 2021 21:54:18 +0100 Subject: [PATCH 2568/3224] World: change 'closed' to 'unloaded' this makes more sense overall from a reader's perspective. and also provide a rug-jerk for any idiots using World->close() when they aren't supposed to? .... --- src/world/Position.php | 6 +++--- src/world/World.php | 16 ++++++++-------- src/world/WorldManager.php | 4 ++-- src/world/generator/PopulationTask.php | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/world/Position.php b/src/world/Position.php index 0f83b6fd05..82df931e0d 100644 --- a/src/world/Position.php +++ b/src/world/Position.php @@ -39,7 +39,7 @@ class Position extends Vector3{ */ public function __construct($x, $y, $z, ?World $world){ parent::__construct($x, $y, $z); - if($world !== null and $world->isClosed()){ + if($world !== null and !$world->isLoaded()){ throw new \InvalidArgumentException("Specified world has been unloaded and cannot be used"); } @@ -66,7 +66,7 @@ class Position extends Vector3{ * @throws AssumptionFailedError */ public function getWorld() : World{ - if($this->world === null || $this->world->isClosed()){ + if($this->world === null || !$this->world->isLoaded()){ throw new AssumptionFailedError("Position world is null or has been unloaded"); } @@ -77,7 +77,7 @@ class Position extends Vector3{ * Checks if this object has a valid reference to a loaded world */ public function isValid() : bool{ - if($this->world !== null and $this->world->isClosed()){ + if($this->world !== null and !$this->world->isLoaded()){ $this->world = null; return false; diff --git a/src/world/World.php b/src/world/World.php index acaf2866b6..7c7a4c2717 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -285,7 +285,7 @@ class World implements ChunkManager{ private $generator; /** @var bool */ - private $closed = false; + private $unloaded = false; /** * @var \Closure[] * @phpstan-var array @@ -493,15 +493,15 @@ class World implements ChunkManager{ return $this->worldId; } - public function isClosed() : bool{ - return $this->closed; + public function isLoaded() : bool{ + return !$this->unloaded; } /** * @internal */ - public function close() : void{ - if($this->closed){ + public function onUnload() : void{ + if($this->unloaded){ throw new \InvalidStateException("Tried to close a world which is already closed"); } @@ -523,7 +523,7 @@ class World implements ChunkManager{ $this->provider = null; $this->blockCache = []; - $this->closed = true; + $this->unloaded = true; } /** @phpstan-param \Closure() : void $callback */ @@ -747,7 +747,7 @@ class World implements ChunkManager{ * @internal */ public function doTick(int $currentTick) : void{ - if($this->closed){ + if($this->unloaded){ throw new \InvalidStateException("Attempted to tick a world which has been closed"); } @@ -1046,7 +1046,7 @@ class World implements ChunkManager{ * @phpstan-var array $skyLight * @phpstan-var array $heightMap */ - if($this->closed || ($chunk = $this->getChunk($chunkX, $chunkZ)) === null || $chunk->isLightPopulated() === true){ + if($this->unloaded || ($chunk = $this->getChunk($chunkX, $chunkZ)) === null || $chunk->isLightPopulated() === true){ return; } //TODO: calculated light information might not be valid if the terrain changed during light calculation diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 573a95ab8a..9bca16ad22 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -168,7 +168,7 @@ class WorldManager{ } unset($this->worlds[$world->getId()]); - $world->close(); + $world->onUnload(); return true; } @@ -321,7 +321,7 @@ class WorldManager{ */ public function findEntity(int $entityId) : ?Entity{ foreach($this->worlds as $world){ - assert(!$world->isClosed()); + assert($world->isLoaded()); if(($entity = $world->getEntity($entityId)) instanceof Entity){ return $entity; } diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 13c0126d2c..5291a957ab 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -136,7 +136,7 @@ class PopulationTask extends AsyncTask{ public function onCompletion() : void{ /** @var World $world */ $world = $this->fetchLocal(self::TLS_KEY_WORLD); - if(!$world->isClosed()){ + if($world->isLoaded()){ $chunk = $this->chunk !== null ? FastChunkSerializer::deserialize($this->chunk) : null; for($i = 0; $i < 9; ++$i){ From ede4d58394275cd7d92d732e7d9c2aefc6927512 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 26 Jun 2021 22:15:22 +0100 Subject: [PATCH 2569/3224] Automatic permission calculation on PermissibleBase construction thanks to the PermissibleInternal/PermissibleBase architectural change, there's no longer any concern regarding cyclic refs. --- src/Server.php | 1 - src/permission/PermissibleInternal.php | 4 +--- src/player/Player.php | 2 -- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Server.php b/src/Server.php index 8aa06aaacf..37feb68abd 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1124,7 +1124,6 @@ class Server{ //TODO: move console parts to a separate component $consoleSender = new ConsoleCommandSender($this, $this->language); - $consoleSender->recalculatePermissions(); $this->subscribeToBroadcastChannel(self::BROADCAST_CHANNEL_ADMINISTRATIVE, $consoleSender); $this->subscribeToBroadcastChannel(self::BROADCAST_CHANNEL_USERS, $consoleSender); diff --git a/src/permission/PermissibleInternal.php b/src/permission/PermissibleInternal.php index 4506142b30..c9484085ee 100644 --- a/src/permission/PermissibleInternal.php +++ b/src/permission/PermissibleInternal.php @@ -64,10 +64,8 @@ class PermissibleInternal implements Permissible{ public function __construct(array $basePermissions){ $this->permissionRecalculationCallbacks = new ObjectSet(); - //TODO: we can't setBasePermission here directly due to bad architecture that causes recalculatePermissions to explode - //so, this hack has to be done here to prevent permission recalculations until it's fixed... $this->rootPermissions = $basePermissions; - //TODO: permissions need to be recalculated here, or inherited permissions won't work + $this->recalculatePermissions(); } public function setBasePermission($name, bool $grant) : void{ diff --git a/src/player/Player.php b/src/player/Player.php index 2eccd1ceac..8e18a1119d 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -305,8 +305,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return; } - $this->perm->recalculatePermissions(); - $this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logIn", [ TextFormat::AQUA . $this->username . TextFormat::WHITE, $session->getIp(), From db28358316bbd46c60cb7f024d72480919222547 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 27 Jun 2021 17:50:39 +0100 Subject: [PATCH 2570/3224] Player: Assume that usedChunks was cleared by the previous loop --- src/player/Player.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index 8e18a1119d..8ede644770 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -98,6 +98,7 @@ use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissibleDelegateTrait; use pocketmine\Server; use pocketmine\timings\Timings; +use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\TextFormat; use pocketmine\world\ChunkListener; use pocketmine\world\ChunkListenerNoOpTrait; @@ -2002,7 +2003,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->unloadChunk($chunkX, $chunkZ); } } - $this->usedChunks = []; + if(count($this->usedChunks) !== 0){ + throw new AssumptionFailedError("Previous loop should have cleared this array"); + } $this->loadQueue = []; $this->removeCurrentWindow(); From 5cdf0b169fa74cc14d873e6cbfd5d26e3e07ad71 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 27 Jun 2021 20:05:01 +0100 Subject: [PATCH 2571/3224] PluginManager: Separate listener method filtering to its own method this makes registerEvents() easier to read. --- src/plugin/PluginManager.php | 117 ++++++++++++++++++++--------------- 1 file changed, 68 insertions(+), 49 deletions(-) diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 7f2073faa1..4b7c1b960d 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -437,6 +437,47 @@ class PluginManager{ $this->fileAssociations = []; } + /** + * Returns whether the given ReflectionMethod could be used as an event handler. Used to filter methods on Listeners + * when registering. + * + * Note: This DOES NOT validate the listener annotations; if this method returns false, the method will be ignored + * completely. Invalid annotations on candidate listener methods should result in an error, so those aren't checked + * here. + * + * @phpstan-return class-string|null + */ + private function getEventsHandledBy(\ReflectionMethod $method) : ?string{ + if($method->isStatic() or !$method->getDeclaringClass()->implementsInterface(Listener::class)){ + return null; + } + $tags = Utils::parseDocComment((string) $method->getDocComment()); + if(isset($tags[ListenerMethodTags::NOT_HANDLER])){ + return null; + } + + $parameters = $method->getParameters(); + if(count($parameters) !== 1){ + return null; + } + + $paramType = $parameters[0]->getType(); + //isBuiltin() returns false for builtin classes .................. + if(!$paramType instanceof \ReflectionNamedType || $paramType->isBuiltin()){ + return null; + } + + /** @phpstan-var class-string $paramClass */ + $paramClass = $paramType->getName(); + $eventClass = new \ReflectionClass($paramClass); + if(!$eventClass->isSubclassOf(Event::class)){ + return null; + } + + /** @var \ReflectionClass $eventClass */ + return $eventClass->getName(); + } + /** * Registers all the events in the given Listener class * @@ -449,56 +490,34 @@ class PluginManager{ $reflection = new \ReflectionClass(get_class($listener)); foreach($reflection->getMethods(\ReflectionMethod::IS_PUBLIC) as $method){ - if(!$method->isStatic() and $method->getDeclaringClass()->implementsInterface(Listener::class)){ - $tags = Utils::parseDocComment((string) $method->getDocComment()); - if(isset($tags[ListenerMethodTags::NOT_HANDLER])){ - continue; - } - - $parameters = $method->getParameters(); - if(count($parameters) !== 1){ - continue; - } - - $paramType = $parameters[0]->getType(); - //isBuiltin() returns false for builtin classes .................. - if($paramType instanceof \ReflectionNamedType && !$paramType->isBuiltin()){ - /** @phpstan-var class-string $paramClass */ - $paramClass = $paramType->getName(); - $eventClass = new \ReflectionClass($paramClass); - if(!$eventClass->isSubclassOf(Event::class)){ - continue; - } - }else{ - continue; - } - - $handlerClosure = $method->getClosure($listener); - if($handlerClosure === null) throw new AssumptionFailedError("This should never happen"); - - try{ - $priority = isset($tags[ListenerMethodTags::PRIORITY]) ? EventPriority::fromString($tags[ListenerMethodTags::PRIORITY]) : EventPriority::NORMAL; - }catch(\InvalidArgumentException $e){ - throw new PluginException("Event handler " . Utils::getNiceClosureName($handlerClosure) . "() declares invalid/unknown priority \"" . $tags[ListenerMethodTags::PRIORITY] . "\""); - } - - $handleCancelled = false; - if(isset($tags[ListenerMethodTags::HANDLE_CANCELLED])){ - switch(strtolower($tags[ListenerMethodTags::HANDLE_CANCELLED])){ - case "true": - case "": - $handleCancelled = true; - break; - case "false": - break; - default: - throw new PluginException("Event handler " . Utils::getNiceClosureName($handlerClosure) . "() declares invalid @" . ListenerMethodTags::HANDLE_CANCELLED . " value \"" . $tags[ListenerMethodTags::HANDLE_CANCELLED] . "\""); - } - } - - /** @phpstan-var \ReflectionClass $eventClass */ - $this->registerEvent($eventClass->getName(), $handlerClosure, $priority, $plugin, $handleCancelled); + $tags = Utils::parseDocComment((string) $method->getDocComment()); + if(isset($tags[ListenerMethodTags::NOT_HANDLER]) || ($eventClass = $this->getEventsHandledBy($method)) === null){ + continue; } + $handlerClosure = $method->getClosure($listener); + if($handlerClosure === null) throw new AssumptionFailedError("This should never happen"); + + try{ + $priority = isset($tags[ListenerMethodTags::PRIORITY]) ? EventPriority::fromString($tags[ListenerMethodTags::PRIORITY]) : EventPriority::NORMAL; + }catch(\InvalidArgumentException $e){ + throw new PluginException("Event handler " . Utils::getNiceClosureName($handlerClosure) . "() declares invalid/unknown priority \"" . $tags[ListenerMethodTags::PRIORITY] . "\""); + } + + $handleCancelled = false; + if(isset($tags[ListenerMethodTags::HANDLE_CANCELLED])){ + switch(strtolower($tags[ListenerMethodTags::HANDLE_CANCELLED])){ + case "true": + case "": + $handleCancelled = true; + break; + case "false": + break; + default: + throw new PluginException("Event handler " . Utils::getNiceClosureName($handlerClosure) . "() declares invalid @" . ListenerMethodTags::HANDLE_CANCELLED . " value \"" . $tags[ListenerMethodTags::HANDLE_CANCELLED] . "\""); + } + } + + $this->registerEvent($eventClass, $handlerClosure, $priority, $plugin, $handleCancelled); } } From 902ea515f7f83a4785197c0bfe5b813acb684f7d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 27 Jun 2021 20:32:35 +0100 Subject: [PATCH 2572/3224] Separate ID handling from GameMode the aliases of 0,1,2,3 remain for user-interface level compatibility. --- src/Server.php | 3 +- .../defaults/DefaultGamemodeCommand.php | 3 +- src/data/java/GameModeIdMap.php | 67 +++++++++++++++++++ src/network/query/QueryInfo.php | 3 +- src/player/GameMode.php | 30 ++------- src/player/Player.php | 5 +- src/wizard/SetupWizard.php | 3 +- 7 files changed, 83 insertions(+), 31 deletions(-) create mode 100644 src/data/java/GameModeIdMap.php diff --git a/src/Server.php b/src/Server.php index 37feb68abd..aef04a98ed 100644 --- a/src/Server.php +++ b/src/Server.php @@ -34,6 +34,7 @@ use pocketmine\console\ConsoleCommandSender; use pocketmine\console\ConsoleReaderThread; use pocketmine\crafting\CraftingManager; use pocketmine\crafting\CraftingManagerFromDataHelper; +use pocketmine\data\java\GameModeIdMap; use pocketmine\entity\EntityDataHelper; use pocketmine\entity\Location; use pocketmine\event\HandlerListManager; @@ -372,7 +373,7 @@ class Server{ } public function getGamemode() : GameMode{ - return GameMode::fromMagicNumber($this->configGroup->getConfigInt("gamemode", 0) & 0b11); + return GameModeIdMap::getInstance()->fromId($this->configGroup->getConfigInt("gamemode", 0)) ?? GameMode::SURVIVAL(); } public function getForceGamemode() : bool{ diff --git a/src/command/defaults/DefaultGamemodeCommand.php b/src/command/defaults/DefaultGamemodeCommand.php index 308353aee5..8a72fab706 100644 --- a/src/command/defaults/DefaultGamemodeCommand.php +++ b/src/command/defaults/DefaultGamemodeCommand.php @@ -25,6 +25,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\data\java\GameModeIdMap; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\GameMode; @@ -57,7 +58,7 @@ class DefaultGamemodeCommand extends VanillaCommand{ return true; } - $sender->getServer()->getConfigGroup()->setConfigInt("gamemode", $gameMode->getMagicNumber()); + $sender->getServer()->getConfigGroup()->setConfigInt("gamemode", GameModeIdMap::getInstance()->toId($gameMode)); $sender->sendMessage(new TranslationContainer("commands.defaultgamemode.success", [$gameMode->getTranslationKey()])); return true; } diff --git a/src/data/java/GameModeIdMap.php b/src/data/java/GameModeIdMap.php new file mode 100644 index 0000000000..5990a72864 --- /dev/null +++ b/src/data/java/GameModeIdMap.php @@ -0,0 +1,67 @@ + + */ + private array $idToEnum = []; + + /** + * @var int[] + * @phpstan-var array + */ + private array $enumToId = []; + + public function __construct(){ + $this->register(0, GameMode::SURVIVAL()); + $this->register(1, GameMode::CREATIVE()); + $this->register(2, GameMode::ADVENTURE()); + $this->register(3, GameMode::SPECTATOR()); + } + + private function register(int $id, GameMode $type) : void{ + $this->idToEnum[$id] = $type; + $this->enumToId[$type->id()] = $id; + } + + public function fromId(int $id) : ?GameMode{ + return $this->idToEnum[$id] ?? null; + } + + public function toId(GameMode $type) : int{ + if(!array_key_exists($type->id(), $this->enumToId)){ + throw new \InvalidArgumentException("Game mode does not have a mapped ID"); //this should never happen + } + return $this->enumToId[$type->id()]; + } +} diff --git a/src/network/query/QueryInfo.php b/src/network/query/QueryInfo.php index 25d07f549d..b6cb199cae 100644 --- a/src/network/query/QueryInfo.php +++ b/src/network/query/QueryInfo.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\query; +use pocketmine\player\GameMode; use pocketmine\player\Player; use pocketmine\plugin\Plugin; use pocketmine\Server; @@ -81,7 +82,7 @@ final class QueryInfo{ $this->plugins = $server->getPluginManager()->getPlugins(); $this->players = $server->getOnlinePlayers(); - $this->gametype = ($server->getGamemode()->getMagicNumber() & 0x01) === 0 ? "SMP" : "CMP"; + $this->gametype = ($server->getGamemode()->equals(GameMode::SURVIVAL()) || $server->getGamemode()->equals(GameMode::ADVENTURE())) ? "SMP" : "CMP"; $this->version = $server->getVersion(); $this->server_engine = $server->getName() . " " . $server->getPocketMineVersion(); $world = $server->getWorldManager()->getDefaultWorld(); diff --git a/src/player/GameMode.php b/src/player/GameMode.php index d8e2d28bfe..3d5c0c7dce 100644 --- a/src/player/GameMode.php +++ b/src/player/GameMode.php @@ -44,21 +44,18 @@ final class GameMode{ /** @var self[] */ protected static $aliasMap = []; - /** @var self[] */ - protected static $magicNumberMap = []; protected static function setup() : void{ self::registerAll( - new self("survival", 0, "Survival", "gameMode.survival", ["s", "0"]), - new self("creative", 1, "Creative", "gameMode.creative", ["c", "1"]), - new self("adventure", 2, "Adventure", "gameMode.adventure", ["a", "2"]), - new self("spectator", 3, "Spectator", "gameMode.spectator", ["v", "view", "3"]) + new self("survival", "Survival", "gameMode.survival", ["s", "0"]), + new self("creative", "Creative", "gameMode.creative", ["c", "1"]), + new self("adventure", "Adventure", "gameMode.adventure", ["a", "2"]), + new self("spectator", "Spectator", "gameMode.spectator", ["v", "view", "3"]) ); } protected static function register(self $member) : void{ self::Enum_register($member); - self::$magicNumberMap[$member->getMagicNumber()] = $member; foreach($member->getAliases() as $alias){ self::$aliasMap[$alias] = $member; } @@ -69,18 +66,6 @@ final class GameMode{ return self::$aliasMap[$str] ?? self::Enum_fromString($str); } - /** - * @return GameMode - * @throws \InvalidArgumentException - */ - public static function fromMagicNumber(int $n) : self{ - self::checkInit(); - if(!isset(self::$magicNumberMap[$n])){ - throw new \InvalidArgumentException("No " . self::class . " enum member matches magic number $n"); - } - return self::$magicNumberMap[$n]; - } - /** @var int */ private $magicNumber; /** @var string */ @@ -93,18 +78,13 @@ final class GameMode{ /** * @param string[] $aliases */ - private function __construct(string $enumName, int $magicNumber, string $englishName, string $translationKey, array $aliases = []){ + private function __construct(string $enumName, string $englishName, string $translationKey, array $aliases = []){ $this->Enum___construct($enumName); - $this->magicNumber = $magicNumber; $this->englishName = $englishName; $this->translationKey = $translationKey; $this->aliases = $aliases; } - public function getMagicNumber() : int{ - return $this->magicNumber; - } - public function getEnglishName() : string{ return $this->englishName; } diff --git a/src/player/Player.php b/src/player/Player.php index 8ede644770..2c4227a172 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -29,6 +29,7 @@ use pocketmine\block\UnknownBlock; use pocketmine\block\VanillaBlocks; use pocketmine\command\CommandSender; use pocketmine\crafting\CraftingGrid; +use pocketmine\data\java\GameModeIdMap; use pocketmine\entity\animation\Animation; use pocketmine\entity\animation\ArmSwingAnimation; use pocketmine\entity\animation\CriticalHitAnimation; @@ -332,7 +333,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->lastPlayed = $nbt->getLong("lastPlayed", $now); if(!$this->server->getForceGamemode() and ($gameModeTag = $nbt->getTag("playerGameType")) instanceof IntTag){ - $this->internalSetGameMode(GameMode::fromMagicNumber($gameModeTag->getValue() & 0x03)); //TODO: bad hack here to avoid crashes on corrupted data + $this->internalSetGameMode(GameModeIdMap::getInstance()->fromId($gameModeTag->getValue()) ?? GameMode::SURVIVAL()); //TODO: bad hack here to avoid crashes on corrupted data }else{ $this->internalSetGameMode($this->server->getGamemode()); } @@ -2069,7 +2070,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $nbt->setInt("SpawnZ", $spawn->getFloorZ()); } - $nbt->setInt("playerGameType", $this->gamemode->getMagicNumber()); + $nbt->setInt("playerGameType", GameModeIdMap::getInstance()->toId($this->gamemode)); $nbt->setLong("firstPlayed", $this->firstPlayed); $nbt->setLong("lastPlayed", (int) floor(microtime(true) * 1000)); diff --git a/src/wizard/SetupWizard.php b/src/wizard/SetupWizard.php index c6040aa469..5491422c62 100644 --- a/src/wizard/SetupWizard.php +++ b/src/wizard/SetupWizard.php @@ -27,6 +27,7 @@ declare(strict_types=1); */ namespace pocketmine\wizard; +use pocketmine\data\java\GameModeIdMap; use pocketmine\lang\Language; use pocketmine\lang\LanguageNotFoundException; use pocketmine\player\GameMode; @@ -158,7 +159,7 @@ LICENSE; $this->message($this->lang->get("gamemode_info")); do{ - $gamemode = (int) $this->getInput($this->lang->get("default_gamemode"), (string) GameMode::SURVIVAL()->getMagicNumber()); + $gamemode = (int) $this->getInput($this->lang->get("default_gamemode"), (string) GameModeIdMap::getInstance()->toId(GameMode::SURVIVAL())); }while($gamemode < 0 or $gamemode > 3); $config->set("gamemode", $gamemode); From 3dd33cd35e135c0252d3dfa727d2990ce3493846 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 27 Jun 2021 20:52:56 +0100 Subject: [PATCH 2573/3224] Get rid of EnumTrait::fromString() it's better to just implement this for stuff where there's explicitly designated aliases, otherwise we could end up with unexpected BC breaks (e.g. hardcoding POSTWORLD in plugin.yml would suddenly break if the core enum was changed, even though it remained valid). --- src/player/GameMode.php | 18 ++++++----- src/plugin/PluginEnableOrder.php | 53 ++++++++++++++++++++++++++++++-- src/utils/EnumTrait.php | 13 -------- 3 files changed, 61 insertions(+), 23 deletions(-) diff --git a/src/player/GameMode.php b/src/player/GameMode.php index 3d5c0c7dce..3508d3d67e 100644 --- a/src/player/GameMode.php +++ b/src/player/GameMode.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\player; use pocketmine\utils\EnumTrait; +use function mb_strtolower; /** * This doc-block is generated automatically, do not modify it manually. @@ -39,7 +40,6 @@ final class GameMode{ use EnumTrait { __construct as Enum___construct; register as Enum_register; - fromString as Enum_fromString; } /** @var self[] */ @@ -47,23 +47,27 @@ final class GameMode{ protected static function setup() : void{ self::registerAll( - new self("survival", "Survival", "gameMode.survival", ["s", "0"]), - new self("creative", "Creative", "gameMode.creative", ["c", "1"]), - new self("adventure", "Adventure", "gameMode.adventure", ["a", "2"]), - new self("spectator", "Spectator", "gameMode.spectator", ["v", "view", "3"]) + new self("survival", "Survival", "gameMode.survival", ["survival", "s", "0"]), + new self("creative", "Creative", "gameMode.creative", ["creative", "c", "1"]), + new self("adventure", "Adventure", "gameMode.adventure", ["adventure", "a", "2"]), + new self("spectator", "Spectator", "gameMode.spectator", ["spectator", "v", "view", "3"]) ); } protected static function register(self $member) : void{ self::Enum_register($member); foreach($member->getAliases() as $alias){ - self::$aliasMap[$alias] = $member; + self::$aliasMap[mb_strtolower($alias)] = $member; } } public static function fromString(string $str) : self{ self::checkInit(); - return self::$aliasMap[$str] ?? self::Enum_fromString($str); + $result = self::$aliasMap[mb_strtolower($str)] ?? null; + if($result === null){ + throw new \InvalidArgumentException("Invalid gamemode alias $str"); + } + return $result; } /** @var int */ diff --git a/src/plugin/PluginEnableOrder.php b/src/plugin/PluginEnableOrder.php index ae800decb6..9aee306dd7 100644 --- a/src/plugin/PluginEnableOrder.php +++ b/src/plugin/PluginEnableOrder.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\plugin; use pocketmine\utils\EnumTrait; +use function mb_strtolower; /** * This doc-block is generated automatically, do not modify it manually. @@ -34,12 +35,58 @@ use pocketmine\utils\EnumTrait; * @method static PluginEnableOrder STARTUP() */ final class PluginEnableOrder{ - use EnumTrait; + use EnumTrait { + __construct as Enum___construct; + register as Enum_register; + } protected static function setup() : void{ self::registerAll( - new self("startup"), - new self("postworld") + new self("startup", ["startup"]), + new self("postworld", ["postworld"]) ); } + + /** + * @var self[] + * @phpstan-var array + */ + private static array $aliasMap = []; + + protected static function register(self $member) : void{ + self::Enum_register($member); + foreach($member->getAliases() as $alias){ + self::$aliasMap[mb_strtolower($alias)] = $member; + } + } + + public static function fromString(string $name) : self{ + self::checkInit(); + $result = self::$aliasMap[mb_strtolower($name)] ?? null; + if($result === null){ + throw new \InvalidArgumentException("No such alias $name"); + } + return $result; + } + + /** + * @var string[] + * @phpstan-var list + */ + private array $aliases; + + /** + * @param string[] $aliases + * @phpstan-param list $aliases + */ + private function __construct(string $enumName, array $aliases){ + $this->Enum___construct($enumName); + $this->aliases = $aliases; + } + + /** + * @return string[] + * @phpstan-return list + */ + public function getAliases() : array{ return $this->aliases; } } diff --git a/src/utils/EnumTrait.php b/src/utils/EnumTrait.php index 163c0b0b26..e464442fe7 100644 --- a/src/utils/EnumTrait.php +++ b/src/utils/EnumTrait.php @@ -56,19 +56,6 @@ trait EnumTrait{ return $result; } - /** - * Returns the enum member matching the given name. - * This is overridden to change the return typehint. - * - * @throws \InvalidArgumentException if no member matches. - */ - public static function fromString(string $name) : self{ - //phpstan doesn't support generic traits yet :( - /** @var self $result */ - $result = self::_registryFromString($name); - return $result; - } - /** @var int|null */ private static $nextId = null; From 6fb8ac211ef01bf4bdeb9852cd5ddfc8db7f9693 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 27 Jun 2021 20:56:51 +0100 Subject: [PATCH 2574/3224] Make GameMode::fromString() and PluginEnableOrder::fromString() return null, instead of throwing exceptions since these are always used for handling userdata, it doesn't make sense for them to throw exceptions. --- src/command/defaults/DefaultGamemodeCommand.php | 5 ++--- src/command/defaults/GamemodeCommand.php | 5 ++--- src/player/GameMode.php | 8 ++------ src/plugin/PluginDescription.php | 6 +++--- src/plugin/PluginEnableOrder.php | 8 ++------ 5 files changed, 11 insertions(+), 21 deletions(-) diff --git a/src/command/defaults/DefaultGamemodeCommand.php b/src/command/defaults/DefaultGamemodeCommand.php index 8a72fab706..7fc9651711 100644 --- a/src/command/defaults/DefaultGamemodeCommand.php +++ b/src/command/defaults/DefaultGamemodeCommand.php @@ -51,9 +51,8 @@ class DefaultGamemodeCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - try{ - $gameMode = GameMode::fromString($args[0]); - }catch(\InvalidArgumentException $e){ + $gameMode = GameMode::fromString($args[0]); + if($gameMode === null){ $sender->sendMessage("Unknown game mode"); return true; } diff --git a/src/command/defaults/GamemodeCommand.php b/src/command/defaults/GamemodeCommand.php index 0633b914e6..8e71fe23bf 100644 --- a/src/command/defaults/GamemodeCommand.php +++ b/src/command/defaults/GamemodeCommand.php @@ -53,9 +53,8 @@ class GamemodeCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - try{ - $gameMode = GameMode::fromString($args[0]); - }catch(\InvalidArgumentException $e){ + $gameMode = GameMode::fromString($args[0]); + if($gameMode === null){ $sender->sendMessage("Unknown game mode"); return true; } diff --git a/src/player/GameMode.php b/src/player/GameMode.php index 3508d3d67e..a41963008a 100644 --- a/src/player/GameMode.php +++ b/src/player/GameMode.php @@ -61,13 +61,9 @@ final class GameMode{ } } - public static function fromString(string $str) : self{ + public static function fromString(string $str) : ?self{ self::checkInit(); - $result = self::$aliasMap[mb_strtolower($str)] ?? null; - if($result === null){ - throw new \InvalidArgumentException("Invalid gamemode alias $str"); - } - return $result; + return self::$aliasMap[mb_strtolower($str)] ?? null; } /** @var int */ diff --git a/src/plugin/PluginDescription.php b/src/plugin/PluginDescription.php index 02a81da480..9ae463093d 100644 --- a/src/plugin/PluginDescription.php +++ b/src/plugin/PluginDescription.php @@ -151,11 +151,11 @@ class PluginDescription{ $this->prefix = (string) ($plugin["prefix"] ?? $this->prefix); if(isset($plugin["load"])){ - try{ - $this->order = PluginEnableOrder::fromString($plugin["load"]); - }catch(\InvalidArgumentException $e){ + $order = PluginEnableOrder::fromString($plugin["load"]); + if($order === null){ throw new PluginException("Invalid Plugin \"load\""); } + $this->order = $order; }else{ $this->order = PluginEnableOrder::POSTWORLD(); } diff --git a/src/plugin/PluginEnableOrder.php b/src/plugin/PluginEnableOrder.php index 9aee306dd7..5b44830324 100644 --- a/src/plugin/PluginEnableOrder.php +++ b/src/plugin/PluginEnableOrder.php @@ -60,13 +60,9 @@ final class PluginEnableOrder{ } } - public static function fromString(string $name) : self{ + public static function fromString(string $name) : ?self{ self::checkInit(); - $result = self::$aliasMap[mb_strtolower($name)] ?? null; - if($result === null){ - throw new \InvalidArgumentException("No such alias $name"); - } - return $result; + return self::$aliasMap[mb_strtolower($name)] ?? null; } /** From f68caa878a87bf4acc86c3eaab648899bcfb5c4e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 29 Jun 2021 16:53:26 +0100 Subject: [PATCH 2575/3224] Potion: added getType() --- src/item/Potion.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/item/Potion.php b/src/item/Potion.php index 13fc8640a9..5b2bbc17ef 100644 --- a/src/item/Potion.php +++ b/src/item/Potion.php @@ -34,6 +34,8 @@ class Potion extends Item implements ConsumableItem{ $this->potionType = $potionType; } + public function getType() : PotionType{ return $this->potionType; } + public function getMaxStackSize() : int{ return 1; } From 07d97bbdeb891a019f11272b0a10a23f135180de Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 29 Jun 2021 18:19:27 +0100 Subject: [PATCH 2576/3224] PotionType: Added display names --- src/item/PotionType.php | 91 ++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/src/item/PotionType.php b/src/item/PotionType.php index 83ee1b300a..023b3f9366 100644 --- a/src/item/PotionType.php +++ b/src/item/PotionType.php @@ -80,122 +80,124 @@ final class PotionType{ __construct as Enum___construct; } + private string $displayName; + protected static function setup() : void{ self::registerAll( - new self("water", fn() => []), - new self("mundane", fn() => []), - new self("long_mundane", fn() => []), - new self("thick", fn() => []), - new self("awkward", fn() => []), - new self("night_vision", fn() => [ + new self("water", "Water", fn() => []), + new self("mundane", "Mundane", fn() => []), + new self("long_mundane", "Long Mundane", fn() => []), + new self("thick", "Thick", fn() => []), + new self("awkward", "Awkward", fn() => []), + new self("night_vision", "Night Vision", fn() => [ new EffectInstance(VanillaEffects::NIGHT_VISION(), 3600) ]), - new self("long_night_vision", fn() => [ + new self("long_night_vision", "Long Night Vision", fn() => [ new EffectInstance(VanillaEffects::NIGHT_VISION(), 9600) ]), - new self("invisibility", fn() => [ + new self("invisibility", "Invisibility", fn() => [ new EffectInstance(VanillaEffects::INVISIBILITY(), 3600) ]), - new self("long_invisibility", fn() => [ + new self("long_invisibility", "Long Invisibility", fn() => [ new EffectInstance(VanillaEffects::INVISIBILITY(), 9600) ]), - new self("leaping", fn() => [ + new self("leaping", "Leaping", fn() => [ new EffectInstance(VanillaEffects::JUMP_BOOST(), 3600) ]), - new self("long_leaping", fn() => [ + new self("long_leaping", "Long Leaping", fn() => [ new EffectInstance(VanillaEffects::JUMP_BOOST(), 9600) ]), - new self("strong_leaping", fn() => [ + new self("strong_leaping", "Strong Leaping", fn() => [ new EffectInstance(VanillaEffects::JUMP_BOOST(), 1800, 1) ]), - new self("fire_resistance", fn() => [ + new self("fire_resistance", "Fire Resistance", fn() => [ new EffectInstance(VanillaEffects::FIRE_RESISTANCE(), 3600) ]), - new self("long_fire_resistance", fn() => [ + new self("long_fire_resistance", "Long Fire Resistance", fn() => [ new EffectInstance(VanillaEffects::FIRE_RESISTANCE(), 9600) ]), - new self("swiftness", fn() => [ + new self("swiftness", "Swiftness", fn() => [ new EffectInstance(VanillaEffects::SPEED(), 3600) ]), - new self("long_swiftness", fn() => [ + new self("long_swiftness", "Long Swiftness", fn() => [ new EffectInstance(VanillaEffects::SPEED(), 9600) ]), - new self("strong_swiftness", fn() => [ + new self("strong_swiftness", "Strong Swiftness", fn() => [ new EffectInstance(VanillaEffects::SPEED(), 1800, 1) ]), - new self("slowness", fn() => [ + new self("slowness", "Slowness", fn() => [ new EffectInstance(VanillaEffects::SLOWNESS(), 1800) ]), - new self("long_slowness", fn() => [ + new self("long_slowness", "Long Slowness", fn() => [ new EffectInstance(VanillaEffects::SLOWNESS(), 4800) ]), - new self("water_breathing", fn() => [ + new self("water_breathing", "Water Breathing", fn() => [ new EffectInstance(VanillaEffects::WATER_BREATHING(), 3600) ]), - new self("long_water_breathing", fn() => [ + new self("long_water_breathing", "Long Water Breathing", fn() => [ new EffectInstance(VanillaEffects::WATER_BREATHING(), 9600) ]), - new self("healing", fn() => [ + new self("healing", "Healing", fn() => [ new EffectInstance(VanillaEffects::INSTANT_HEALTH()) ]), - new self("strong_healing", fn() => [ + new self("strong_healing", "Strong Healing", fn() => [ new EffectInstance(VanillaEffects::INSTANT_HEALTH(), null, 1) ]), - new self("harming", fn() => [ + new self("harming", "Harming", fn() => [ new EffectInstance(VanillaEffects::INSTANT_DAMAGE()) ]), - new self("strong_harming", fn() => [ + new self("strong_harming", "Strong Harming", fn() => [ new EffectInstance(VanillaEffects::INSTANT_DAMAGE(), null, 1) ]), - new self("poison", fn() => [ + new self("poison", "Poison", fn() => [ new EffectInstance(VanillaEffects::POISON(), 900) ]), - new self("long_poison", fn() => [ + new self("long_poison", "Long Poison", fn() => [ new EffectInstance(VanillaEffects::POISON(), 2400) ]), - new self("strong_poison", fn() => [ + new self("strong_poison", "Strong Poison", fn() => [ new EffectInstance(VanillaEffects::POISON(), 440, 1) ]), - new self("regeneration", fn() => [ + new self("regeneration", "Regeneration", fn() => [ new EffectInstance(VanillaEffects::REGENERATION(), 900) ]), - new self("long_regeneration", fn() => [ + new self("long_regeneration", "Long Regeneration", fn() => [ new EffectInstance(VanillaEffects::REGENERATION(), 2400) ]), - new self("strong_regeneration", fn() => [ + new self("strong_regeneration", "Strong Regeneration", fn() => [ new EffectInstance(VanillaEffects::REGENERATION(), 440, 1) ]), - new self("strength", fn() => [ + new self("strength", "Strength", fn() => [ new EffectInstance(VanillaEffects::STRENGTH(), 3600) ]), - new self("long_strength", fn() => [ + new self("long_strength", "Long Strength", fn() => [ new EffectInstance(VanillaEffects::STRENGTH(), 9600) ]), - new self("strong_strength", fn() => [ + new self("strong_strength", "Strong Strength", fn() => [ new EffectInstance(VanillaEffects::STRENGTH(), 1800, 1) ]), - new self("weakness", fn() => [ + new self("weakness", "Weakness", fn() => [ new EffectInstance(VanillaEffects::WEAKNESS(), 1800) ]), - new self("long_weakness", fn() => [ + new self("long_weakness", "Long Weakness", fn() => [ new EffectInstance(VanillaEffects::WEAKNESS(), 4800) ]), - new self("wither", fn() => [ + new self("wither", "Wither", fn() => [ new EffectInstance(VanillaEffects::WITHER(), 800, 1) ]), - new self("turtle_master", fn() => [ + new self("turtle_master", "Turtle Master", fn() => [ //TODO ]), - new self("long_turtle_master", fn() => [ + new self("long_turtle_master", "Long Turtle Master", fn() => [ //TODO ]), - new self("strong_turtle_master", fn() => [ + new self("strong_turtle_master", "Strong Turtle Master", fn() => [ //TODO ]), - new self("slow_falling", fn() => [ + new self("slow_falling", "Slow Falling", fn() => [ //TODO ]), - new self("long_slow_falling", fn() => [ + new self("long_slow_falling", "Long Slow Falling", fn() => [ //TODO ]) ); @@ -207,11 +209,14 @@ final class PotionType{ /** * @phpstan-param \Closure() : list $effectsGetter */ - private function __construct(string $enumName, \Closure $effectsGetter){ + private function __construct(string $enumName, string $displayName, \Closure $effectsGetter){ $this->Enum___construct($enumName); + $this->displayName = $displayName; $this->effectsGetter = $effectsGetter; } + public function getDisplayName() : string{ return $this->displayName; } + /** * @return EffectInstance[] * @phpstan-return list From 0ec869823b893cbffc31ff8a228ef33851faabdb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 29 Jun 2021 18:21:41 +0100 Subject: [PATCH 2577/3224] Added potion display names to Potion and SplashPotion --- src/item/ItemFactory.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 64707f13e9..19f8b5c1af 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -281,8 +281,8 @@ class ItemFactory{ foreach(PotionType::getAll() as $type){ $typeId = PotionTypeIdMap::getInstance()->toId($type); - $this->register(new Potion(new ItemIdentifier(ItemIds::POTION, $typeId), "Potion", $type)); - $this->register(new SplashPotion(new ItemIdentifier(ItemIds::SPLASH_POTION, $typeId), "Splash Potion", $type)); + $this->register(new Potion(new ItemIdentifier(ItemIds::POTION, $typeId), $type->getDisplayName() . " Potion", $type)); + $this->register(new SplashPotion(new ItemIdentifier(ItemIds::SPLASH_POTION, $typeId), $type->getDisplayName() . " Splash Potion", $type)); } foreach(TreeType::getAll() as $type){ From 7029f85c1c3c9f5dcd5cd3dcb7efa637d8c6458d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 29 Jun 2021 18:23:24 +0100 Subject: [PATCH 2578/3224] Regenerated VanillaItems --- src/item/VanillaItems.php | 184 +++++++++++++++++++++++++++++++++++--- 1 file changed, 174 insertions(+), 10 deletions(-) diff --git a/src/item/VanillaItems.php b/src/item/VanillaItems.php index 886751907e..ec6b30f584 100644 --- a/src/item/VanillaItems.php +++ b/src/item/VanillaItems.php @@ -34,6 +34,8 @@ use function assert; * @method static Boat ACACIA_BOAT() * @method static Apple APPLE() * @method static Arrow ARROW() + * @method static Potion AWKWARD_POTION() + * @method static SplashPotion AWKWARD_SPLASH_POTION() * @method static BakedPotato BAKED_POTATO() * @method static Beetroot BEETROOT() * @method static BeetrootSeeds BEETROOT_SEEDS() @@ -56,7 +58,6 @@ use function assert; * @method static Bed BROWN_BED() * @method static Dye BROWN_DYE() * @method static Bucket BUCKET() - * @method static ItemBlock CAKE() * @method static Carrot CARROT() * @method static Armor CHAINMAIL_BOOTS() * @method static Armor CHAINMAIL_CHESTPLATE() @@ -139,6 +140,8 @@ use function assert; * @method static ExperienceBottle EXPERIENCE_BOTTLE() * @method static Item FEATHER() * @method static Item FERMENTED_SPIDER_EYE() + * @method static Potion FIRE_RESISTANCE_POTION() + * @method static SplashPotion FIRE_RESISTANCE_SPLASH_POTION() * @method static FishingRod FISHING_ROD() * @method static Item FLINT() * @method static FlintSteel FLINT_AND_STEEL() @@ -164,8 +167,14 @@ use function assert; * @method static Bed GREEN_BED() * @method static Dye GREEN_DYE() * @method static Item GUNPOWDER() + * @method static Potion HARMING_POTION() + * @method static SplashPotion HARMING_SPLASH_POTION() + * @method static Potion HEALING_POTION() + * @method static SplashPotion HEALING_SPLASH_POTION() * @method static Item HEART_OF_THE_SEA() * @method static Item INK_SAC() + * @method static Potion INVISIBILITY_POTION() + * @method static SplashPotion INVISIBILITY_SPLASH_POTION() * @method static Axe IRON_AXE() * @method static Armor IRON_BOOTS() * @method static Armor IRON_CHESTPLATE() @@ -180,6 +189,8 @@ use function assert; * @method static Boat JUNGLE_BOAT() * @method static Item LAPIS_LAZULI() * @method static LiquidBucket LAVA_BUCKET() + * @method static Potion LEAPING_POTION() + * @method static SplashPotion LEAPING_SPLASH_POTION() * @method static Item LEATHER() * @method static Armor LEATHER_BOOTS() * @method static Armor LEATHER_CAP() @@ -191,6 +202,34 @@ use function assert; * @method static Dye LIGHT_GRAY_DYE() * @method static Bed LIME_BED() * @method static Dye LIME_DYE() + * @method static Potion LONG_FIRE_RESISTANCE_POTION() + * @method static SplashPotion LONG_FIRE_RESISTANCE_SPLASH_POTION() + * @method static Potion LONG_INVISIBILITY_POTION() + * @method static SplashPotion LONG_INVISIBILITY_SPLASH_POTION() + * @method static Potion LONG_LEAPING_POTION() + * @method static SplashPotion LONG_LEAPING_SPLASH_POTION() + * @method static Potion LONG_MUNDANE_POTION() + * @method static SplashPotion LONG_MUNDANE_SPLASH_POTION() + * @method static Potion LONG_NIGHT_VISION_POTION() + * @method static SplashPotion LONG_NIGHT_VISION_SPLASH_POTION() + * @method static Potion LONG_POISON_POTION() + * @method static SplashPotion LONG_POISON_SPLASH_POTION() + * @method static Potion LONG_REGENERATION_POTION() + * @method static SplashPotion LONG_REGENERATION_SPLASH_POTION() + * @method static Potion LONG_SLOWNESS_POTION() + * @method static SplashPotion LONG_SLOWNESS_SPLASH_POTION() + * @method static Potion LONG_SLOW_FALLING_POTION() + * @method static SplashPotion LONG_SLOW_FALLING_SPLASH_POTION() + * @method static Potion LONG_STRENGTH_POTION() + * @method static SplashPotion LONG_STRENGTH_SPLASH_POTION() + * @method static Potion LONG_SWIFTNESS_POTION() + * @method static SplashPotion LONG_SWIFTNESS_SPLASH_POTION() + * @method static Potion LONG_TURTLE_MASTER_POTION() + * @method static SplashPotion LONG_TURTLE_MASTER_SPLASH_POTION() + * @method static Potion LONG_WATER_BREATHING_POTION() + * @method static SplashPotion LONG_WATER_BREATHING_SPLASH_POTION() + * @method static Potion LONG_WEAKNESS_POTION() + * @method static SplashPotion LONG_WEAKNESS_SPLASH_POTION() * @method static Bed MAGENTA_BED() * @method static Dye MAGENTA_DYE() * @method static Item MAGMA_CREAM() @@ -198,12 +237,15 @@ use function assert; * @method static MelonSeeds MELON_SEEDS() * @method static MilkBucket MILK_BUCKET() * @method static Minecart MINECART() + * @method static Potion MUNDANE_POTION() + * @method static SplashPotion MUNDANE_SPLASH_POTION() * @method static MushroomStew MUSHROOM_STEW() * @method static Item NAUTILUS_SHELL() * @method static Item NETHER_BRICK() * @method static Item NETHER_QUARTZ() * @method static Item NETHER_STAR() - * @method static ItemBlock NETHER_WART() + * @method static Potion NIGHT_VISION_POTION() + * @method static SplashPotion NIGHT_VISION_SPLASH_POTION() * @method static Boat OAK_BOAT() * @method static Bed ORANGE_BED() * @method static Dye ORANGE_DYE() @@ -213,9 +255,10 @@ use function assert; * @method static Dye PINK_DYE() * @method static Skull PLAYER_HEAD() * @method static PoisonousPotato POISONOUS_POTATO() + * @method static Potion POISON_POTION() + * @method static SplashPotion POISON_SPLASH_POTION() * @method static Item POPPED_CHORUS_FRUIT() * @method static Potato POTATO() - * @method static Potion POTION() * @method static Item PRISMARINE_CRYSTALS() * @method static Item PRISMARINE_SHARD() * @method static Pufferfish PUFFERFISH() @@ -248,16 +291,22 @@ use function assert; * @method static Redstone REDSTONE_DUST() * @method static Bed RED_BED() * @method static Dye RED_DYE() + * @method static Potion REGENERATION_POTION() + * @method static SplashPotion REGENERATION_SPLASH_POTION() * @method static RottenFlesh ROTTEN_FLESH() * @method static Item SCUTE() * @method static Shears SHEARS() * @method static Item SHULKER_SHELL() * @method static Skull SKELETON_SKULL() * @method static Item SLIMEBALL() + * @method static Potion SLOWNESS_POTION() + * @method static SplashPotion SLOWNESS_SPLASH_POTION() + * @method static Potion SLOW_FALLING_POTION() + * @method static SplashPotion SLOW_FALLING_SPLASH_POTION() * @method static Snowball SNOWBALL() * @method static SpiderEye SPIDER_EYE() - * @method static SplashPotion SPLASH_POTION() * @method static Boat SPRUCE_BOAT() + * @method static SpawnEgg SQUID_SPAWN_EGG() * @method static Steak STEAK() * @method static Stick STICK() * @method static Axe STONE_AXE() @@ -265,16 +314,48 @@ use function assert; * @method static Pickaxe STONE_PICKAXE() * @method static Shovel STONE_SHOVEL() * @method static Sword STONE_SWORD() + * @method static Potion STRENGTH_POTION() + * @method static SplashPotion STRENGTH_SPLASH_POTION() * @method static StringItem STRING() + * @method static Potion STRONG_HARMING_POTION() + * @method static SplashPotion STRONG_HARMING_SPLASH_POTION() + * @method static Potion STRONG_HEALING_POTION() + * @method static SplashPotion STRONG_HEALING_SPLASH_POTION() + * @method static Potion STRONG_LEAPING_POTION() + * @method static SplashPotion STRONG_LEAPING_SPLASH_POTION() + * @method static Potion STRONG_POISON_POTION() + * @method static SplashPotion STRONG_POISON_SPLASH_POTION() + * @method static Potion STRONG_REGENERATION_POTION() + * @method static SplashPotion STRONG_REGENERATION_SPLASH_POTION() + * @method static Potion STRONG_STRENGTH_POTION() + * @method static SplashPotion STRONG_STRENGTH_SPLASH_POTION() + * @method static Potion STRONG_SWIFTNESS_POTION() + * @method static SplashPotion STRONG_SWIFTNESS_SPLASH_POTION() + * @method static Potion STRONG_TURTLE_MASTER_POTION() + * @method static SplashPotion STRONG_TURTLE_MASTER_SPLASH_POTION() * @method static Item SUGAR() - * @method static ItemBlock SUGARCANE() + * @method static Potion SWIFTNESS_POTION() + * @method static SplashPotion SWIFTNESS_SPLASH_POTION() + * @method static Potion THICK_POTION() + * @method static SplashPotion THICK_SPLASH_POTION() * @method static Totem TOTEM() + * @method static Potion TURTLE_MASTER_POTION() + * @method static SplashPotion TURTLE_MASTER_SPLASH_POTION() + * @method static SpawnEgg VILLAGER_SPAWN_EGG() + * @method static Potion WATER_BREATHING_POTION() + * @method static SplashPotion WATER_BREATHING_SPLASH_POTION() * @method static LiquidBucket WATER_BUCKET() + * @method static Potion WATER_POTION() + * @method static SplashPotion WATER_SPLASH_POTION() + * @method static Potion WEAKNESS_POTION() + * @method static SplashPotion WEAKNESS_SPLASH_POTION() * @method static Item WHEAT() * @method static WheatSeeds WHEAT_SEEDS() * @method static Bed WHITE_BED() * @method static Dye WHITE_DYE() + * @method static Potion WITHER_POTION() * @method static Skull WITHER_SKELETON_SKULL() + * @method static SplashPotion WITHER_SPLASH_POTION() * @method static Axe WOODEN_AXE() * @method static Hoe WOODEN_HOE() * @method static Pickaxe WOODEN_PICKAXE() @@ -285,6 +366,7 @@ use function assert; * @method static Bed YELLOW_BED() * @method static Dye YELLOW_DYE() * @method static Skull ZOMBIE_HEAD() + * @method static SpawnEgg ZOMBIE_SPAWN_EGG() */ final class VanillaItems{ use CloningRegistryTrait; @@ -318,6 +400,8 @@ final class VanillaItems{ self::register("acacia_boat", $factory->get(333, 4)); self::register("apple", $factory->get(260)); self::register("arrow", $factory->get(262)); + self::register("awkward_potion", $factory->get(373, 4)); + self::register("awkward_splash_potion", $factory->get(438, 4)); self::register("baked_potato", $factory->get(393)); self::register("beetroot", $factory->get(457)); self::register("beetroot_seeds", $factory->get(458)); @@ -340,7 +424,6 @@ final class VanillaItems{ self::register("brown_bed", $factory->get(355, 12)); self::register("brown_dye", $factory->get(351, 17)); self::register("bucket", $factory->get(325)); - self::register("cake", $factory->get(354)); self::register("carrot", $factory->get(391)); self::register("chainmail_boots", $factory->get(305)); self::register("chainmail_chestplate", $factory->get(303)); @@ -423,6 +506,8 @@ final class VanillaItems{ self::register("experience_bottle", $factory->get(384)); self::register("feather", $factory->get(288)); self::register("fermented_spider_eye", $factory->get(376)); + self::register("fire_resistance_potion", $factory->get(373, 12)); + self::register("fire_resistance_splash_potion", $factory->get(438, 12)); self::register("fishing_rod", $factory->get(346)); self::register("flint", $factory->get(318)); self::register("flint_and_steel", $factory->get(259)); @@ -448,8 +533,14 @@ final class VanillaItems{ self::register("green_bed", $factory->get(355, 13)); self::register("green_dye", $factory->get(351, 2)); self::register("gunpowder", $factory->get(289)); + self::register("harming_potion", $factory->get(373, 23)); + self::register("harming_splash_potion", $factory->get(438, 23)); + self::register("healing_potion", $factory->get(373, 21)); + self::register("healing_splash_potion", $factory->get(438, 21)); self::register("heart_of_the_sea", $factory->get(467)); self::register("ink_sac", $factory->get(351)); + self::register("invisibility_potion", $factory->get(373, 7)); + self::register("invisibility_splash_potion", $factory->get(438, 7)); self::register("iron_axe", $factory->get(258)); self::register("iron_boots", $factory->get(309)); self::register("iron_chestplate", $factory->get(307)); @@ -464,6 +555,8 @@ final class VanillaItems{ self::register("jungle_boat", $factory->get(333, 3)); self::register("lapis_lazuli", $factory->get(351, 4)); self::register("lava_bucket", $factory->get(325, 10)); + self::register("leaping_potion", $factory->get(373, 9)); + self::register("leaping_splash_potion", $factory->get(438, 9)); self::register("leather", $factory->get(334)); self::register("leather_boots", $factory->get(301)); self::register("leather_cap", $factory->get(298)); @@ -475,6 +568,34 @@ final class VanillaItems{ self::register("light_gray_dye", $factory->get(351, 7)); self::register("lime_bed", $factory->get(355, 5)); self::register("lime_dye", $factory->get(351, 10)); + self::register("long_fire_resistance_potion", $factory->get(373, 13)); + self::register("long_fire_resistance_splash_potion", $factory->get(438, 13)); + self::register("long_invisibility_potion", $factory->get(373, 8)); + self::register("long_invisibility_splash_potion", $factory->get(438, 8)); + self::register("long_leaping_potion", $factory->get(373, 10)); + self::register("long_leaping_splash_potion", $factory->get(438, 10)); + self::register("long_mundane_potion", $factory->get(373, 2)); + self::register("long_mundane_splash_potion", $factory->get(438, 2)); + self::register("long_night_vision_potion", $factory->get(373, 6)); + self::register("long_night_vision_splash_potion", $factory->get(438, 6)); + self::register("long_poison_potion", $factory->get(373, 26)); + self::register("long_poison_splash_potion", $factory->get(438, 26)); + self::register("long_regeneration_potion", $factory->get(373, 29)); + self::register("long_regeneration_splash_potion", $factory->get(438, 29)); + self::register("long_slow_falling_potion", $factory->get(373, 41)); + self::register("long_slow_falling_splash_potion", $factory->get(438, 41)); + self::register("long_slowness_potion", $factory->get(373, 18)); + self::register("long_slowness_splash_potion", $factory->get(438, 18)); + self::register("long_strength_potion", $factory->get(373, 32)); + self::register("long_strength_splash_potion", $factory->get(438, 32)); + self::register("long_swiftness_potion", $factory->get(373, 15)); + self::register("long_swiftness_splash_potion", $factory->get(438, 15)); + self::register("long_turtle_master_potion", $factory->get(373, 38)); + self::register("long_turtle_master_splash_potion", $factory->get(438, 38)); + self::register("long_water_breathing_potion", $factory->get(373, 20)); + self::register("long_water_breathing_splash_potion", $factory->get(438, 20)); + self::register("long_weakness_potion", $factory->get(373, 35)); + self::register("long_weakness_splash_potion", $factory->get(438, 35)); self::register("magenta_bed", $factory->get(355, 2)); self::register("magenta_dye", $factory->get(351, 13)); self::register("magma_cream", $factory->get(378)); @@ -482,12 +603,15 @@ final class VanillaItems{ self::register("melon_seeds", $factory->get(362)); self::register("milk_bucket", $factory->get(325, 1)); self::register("minecart", $factory->get(328)); + self::register("mundane_potion", $factory->get(373, 1)); + self::register("mundane_splash_potion", $factory->get(438, 1)); self::register("mushroom_stew", $factory->get(282)); self::register("nautilus_shell", $factory->get(465)); self::register("nether_brick", $factory->get(405)); self::register("nether_quartz", $factory->get(406)); self::register("nether_star", $factory->get(399)); - self::register("nether_wart", $factory->get(372)); + self::register("night_vision_potion", $factory->get(373, 5)); + self::register("night_vision_splash_potion", $factory->get(438, 5)); self::register("oak_boat", $factory->get(333)); self::register("orange_bed", $factory->get(355, 1)); self::register("orange_dye", $factory->get(351, 14)); @@ -496,10 +620,11 @@ final class VanillaItems{ self::register("pink_bed", $factory->get(355, 6)); self::register("pink_dye", $factory->get(351, 9)); self::register("player_head", $factory->get(397, 3)); + self::register("poison_potion", $factory->get(373, 25)); + self::register("poison_splash_potion", $factory->get(438, 25)); self::register("poisonous_potato", $factory->get(394)); self::register("popped_chorus_fruit", $factory->get(433)); self::register("potato", $factory->get(392)); - self::register("potion", $factory->get(373)); self::register("prismarine_crystals", $factory->get(422)); self::register("prismarine_shard", $factory->get(409)); self::register("pufferfish", $factory->get(462)); @@ -532,16 +657,22 @@ final class VanillaItems{ self::register("red_bed", $factory->get(355, 14)); self::register("red_dye", $factory->get(351, 1)); self::register("redstone_dust", $factory->get(331)); + self::register("regeneration_potion", $factory->get(373, 28)); + self::register("regeneration_splash_potion", $factory->get(438, 28)); self::register("rotten_flesh", $factory->get(367)); self::register("scute", $factory->get(468)); self::register("shears", $factory->get(359)); self::register("shulker_shell", $factory->get(445)); self::register("skeleton_skull", $factory->get(397)); self::register("slimeball", $factory->get(341)); + self::register("slow_falling_potion", $factory->get(373, 40)); + self::register("slow_falling_splash_potion", $factory->get(438, 40)); + self::register("slowness_potion", $factory->get(373, 17)); + self::register("slowness_splash_potion", $factory->get(438, 17)); self::register("snowball", $factory->get(332)); self::register("spider_eye", $factory->get(375)); - self::register("splash_potion", $factory->get(438)); self::register("spruce_boat", $factory->get(333, 1)); + self::register("squid_spawn_egg", $factory->get(383, 17)); self::register("steak", $factory->get(364)); self::register("stick", $factory->get(280)); self::register("stone_axe", $factory->get(275)); @@ -549,16 +680,48 @@ final class VanillaItems{ self::register("stone_pickaxe", $factory->get(274)); self::register("stone_shovel", $factory->get(273)); self::register("stone_sword", $factory->get(272)); + self::register("strength_potion", $factory->get(373, 31)); + self::register("strength_splash_potion", $factory->get(438, 31)); self::register("string", $factory->get(287)); + self::register("strong_harming_potion", $factory->get(373, 24)); + self::register("strong_harming_splash_potion", $factory->get(438, 24)); + self::register("strong_healing_potion", $factory->get(373, 22)); + self::register("strong_healing_splash_potion", $factory->get(438, 22)); + self::register("strong_leaping_potion", $factory->get(373, 11)); + self::register("strong_leaping_splash_potion", $factory->get(438, 11)); + self::register("strong_poison_potion", $factory->get(373, 27)); + self::register("strong_poison_splash_potion", $factory->get(438, 27)); + self::register("strong_regeneration_potion", $factory->get(373, 30)); + self::register("strong_regeneration_splash_potion", $factory->get(438, 30)); + self::register("strong_strength_potion", $factory->get(373, 33)); + self::register("strong_strength_splash_potion", $factory->get(438, 33)); + self::register("strong_swiftness_potion", $factory->get(373, 16)); + self::register("strong_swiftness_splash_potion", $factory->get(438, 16)); + self::register("strong_turtle_master_potion", $factory->get(373, 39)); + self::register("strong_turtle_master_splash_potion", $factory->get(438, 39)); self::register("sugar", $factory->get(353)); - self::register("sugarcane", $factory->get(338)); + self::register("swiftness_potion", $factory->get(373, 14)); + self::register("swiftness_splash_potion", $factory->get(438, 14)); + self::register("thick_potion", $factory->get(373, 3)); + self::register("thick_splash_potion", $factory->get(438, 3)); self::register("totem", $factory->get(450)); + self::register("turtle_master_potion", $factory->get(373, 37)); + self::register("turtle_master_splash_potion", $factory->get(438, 37)); + self::register("villager_spawn_egg", $factory->get(383, 15)); + self::register("water_breathing_potion", $factory->get(373, 19)); + self::register("water_breathing_splash_potion", $factory->get(438, 19)); self::register("water_bucket", $factory->get(325, 8)); + self::register("water_potion", $factory->get(373)); + self::register("water_splash_potion", $factory->get(438)); + self::register("weakness_potion", $factory->get(373, 34)); + self::register("weakness_splash_potion", $factory->get(438, 34)); self::register("wheat", $factory->get(296)); self::register("wheat_seeds", $factory->get(295)); self::register("white_bed", $factory->get(355)); self::register("white_dye", $factory->get(351, 19)); + self::register("wither_potion", $factory->get(373, 36)); self::register("wither_skeleton_skull", $factory->get(397, 1)); + self::register("wither_splash_potion", $factory->get(438, 36)); self::register("wooden_axe", $factory->get(271)); self::register("wooden_hoe", $factory->get(290)); self::register("wooden_pickaxe", $factory->get(270)); @@ -569,5 +732,6 @@ final class VanillaItems{ self::register("yellow_bed", $factory->get(355, 4)); self::register("yellow_dye", $factory->get(351, 11)); self::register("zombie_head", $factory->get(397, 2)); + self::register("zombie_spawn_egg", $factory->get(383, 32)); } } From 35ad199b118a5555401dfc57820ca273b465398a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 29 Jun 2021 19:24:28 +0100 Subject: [PATCH 2579/3224] changelog: mention Potion API changes [ci skip] --- changelogs/4.0-snapshot.md | 42 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 6ecfa8c79d..cd6603ba45 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -599,7 +599,47 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Item->setCompoundTag()` - `Item->getCompoundTag()` - `Item->hasCompoundTag()` + - `Potion::getPotionEffectsById()` - `ProjectileItem->getProjectileEntityType()` +- The following constants have been removed: + - `Potion::ALL` - use `PotionType::getAll()` instead + - `Potion::WATER` + - `Potion::MUNDANE` + - `Potion::LONG_MUNDANE` + - `Potion::THICK` + - `Potion::AWKWARD` + - `Potion::NIGHT_VISION` + - `Potion::LONG_NIGHT_VISION` + - `Potion::INVISIBILITY` + - `Potion::LONG_INVISIBILITY` + - `Potion::LEAPING` + - `Potion::LONG_LEAPING` + - `Potion::STRONG_LEAPING` + - `Potion::FIRE_RESISTANCE` + - `Potion::LONG_FIRE_RESISTANCE` + - `Potion::SWIFTNESS` + - `Potion::LONG_SWIFTNESS` + - `Potion::STRONG_SWIFTNESS` + - `Potion::SLOWNESS` + - `Potion::LONG_SLOWNESS` + - `Potion::WATER_BREATHING` + - `Potion::LONG_WATER_BREATHING` + - `Potion::HEALING` + - `Potion::STRONG_HEALING` + - `Potion::HARMING` + - `Potion::STRONG_HARMING` + - `Potion::POISON` + - `Potion::LONG_POISON` + - `Potion::STRONG_POISON` + - `Potion::REGENERATION` + - `Potion::LONG_REGENERATION` + - `Potion::STRONG_REGENERATION` + - `Potion::STRENGTH` + - `Potion::LONG_STRENGTH` + - `Potion::STRONG_STRENGTH` + - `Potion::WEAKNESS` + - `Potion::LONG_WEAKNESS` + - `Potion::WITHER` - The following methods have been renamed: - `Item->getDamage()` -> `Item->getMeta()` - The following methods have been moved to `pocketmine\inventory\CreativeInventory`: @@ -615,10 +655,12 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Fertilizer` - `LiquidBucket` - `MilkBucket` + - `PotionType`: enum class containing information about vanilla potion types - `WritableBookBase` - `WritableBookPage` - The following API methods have been added: - `Armor->getArmorSlot()` + - `Potion->getType()`: returns a `PotionType` enum object containing information such as the applied effects - `ProjectileItem->getProjectileEntityClass()`: returns the class of projectile to be created when thrown - The following classes have been removed: - `ChainBoots` From aee7b03c1da92f9eb5baa4751ecb18501041d749 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 29 Jun 2021 19:26:02 +0100 Subject: [PATCH 2580/3224] changelog: fix outdated mention of ProjectileItem::getProjectileEntityClass() [ci skip] --- changelogs/4.0-snapshot.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index cd6603ba45..035a3716ee 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -661,7 +661,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - The following API methods have been added: - `Armor->getArmorSlot()` - `Potion->getType()`: returns a `PotionType` enum object containing information such as the applied effects - - `ProjectileItem->getProjectileEntityClass()`: returns the class of projectile to be created when thrown + - `ProjectileItem->createEntity()`: returns a new instance of the projectile entity that will be thrown - The following classes have been removed: - `ChainBoots` - `ChainChestplate` From 32d7b1e6afd1127c0c64ba6b04f036b6a69035cb Mon Sep 17 00:00:00 2001 From: Dylan T Date: Tue, 29 Jun 2021 19:40:43 +0100 Subject: [PATCH 2581/3224] Start using webmozart/pathutil for joining paths (#4287) --- composer.json | 3 +- composer.lock | 168 ++++++++++++------ src/CrashDump.php | 13 +- src/MemoryManager.php | 15 +- src/PocketMine.php | 7 +- src/Server.php | 67 +++---- src/command/defaults/DumpMemoryCommand.php | 3 +- src/command/defaults/TimingsCommand.php | 7 +- .../bedrock/LegacyBlockIdToStringIdMap.php | 3 +- .../bedrock/LegacyEntityIdToStringIdMap.php | 3 +- .../bedrock/LegacyItemIdToStringIdMap.php | 3 +- src/inventory/CreativeInventory.php | 4 +- src/item/LegacyStringToItemParser.php | 3 +- src/lang/Language.php | 7 +- src/network/mcpe/cache/StaticPacketCache.php | 5 +- .../mcpe/convert/GlobalItemTypeDictionary.php | 3 +- src/network/mcpe/convert/ItemTranslator.php | 5 +- .../mcpe/convert/RuntimeBlockMapping.php | 5 +- src/plugin/PluginBase.php | 5 +- src/plugin/PluginManager.php | 6 +- src/resourcepacks/ResourcePackManager.php | 12 +- src/scheduler/DumpWorkerMemoryTask.php | 4 +- src/utils/Config.php | 6 +- src/utils/Filesystem.php | 10 +- src/wizard/SetupWizard.php | 11 +- src/world/WorldManager.php | 6 +- src/world/format/io/FormatConverter.php | 3 +- src/world/format/io/leveldb/LevelDB.php | 13 +- .../format/io/region/RegionWorldProvider.php | 12 +- .../io/region/WritableRegionWorldProvider.php | 6 +- .../format/io/region/RegionLoaderTest.php | 6 +- 31 files changed, 252 insertions(+), 172 deletions(-) diff --git a/composer.json b/composer.json index 253f161443..096c42360d 100644 --- a/composer.json +++ b/composer.json @@ -48,7 +48,8 @@ "pocketmine/snooze": "^0.3.0", "pocketmine/spl": "dev-master", "ramsey/uuid": "^4.1", - "respect/validation": "^2.0" + "respect/validation": "^2.0", + "webmozart/path-util": "^2.3" }, "require-dev": { "phpstan/phpstan": "0.12.90", diff --git a/composer.lock b/composer.lock index cfa81060e8..400311eba3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1ec8a08d7688ec903c9b67945feab26e", + "content-hash": "3e3b505ec39bbf9e449e0466f154d5aa", "packages": [ { "name": "adhocore/json-comment", @@ -1310,6 +1310,114 @@ } ], "time": "2021-05-27T09:27:20+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.10.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.10.0" + }, + "time": "2021-03-09T10:59:23+00:00" + }, + { + "name": "webmozart/path-util", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/path-util.git", + "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "webmozart/assert": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\PathUtil\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.", + "support": { + "issues": "https://github.com/webmozart/path-util/issues", + "source": "https://github.com/webmozart/path-util/tree/2.3.0" + }, + "time": "2015-12-17T08:42:14+00:00" } ], "packages-dev": [ @@ -3435,64 +3543,6 @@ } ], "time": "2020-07-12T23:59:07+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.10.0", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.10.0" - }, - "time": "2021-03-09T10:59:23+00:00" } ], "aliases": [], diff --git a/src/CrashDump.php b/src/CrashDump.php index 6758ba8845..e6f72de5f7 100644 --- a/src/CrashDump.php +++ b/src/CrashDump.php @@ -31,6 +31,7 @@ use pocketmine\plugin\PluginManager; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Filesystem; use pocketmine\utils\Utils; +use Webmozart\PathUtil\Path; use function base64_encode; use function date; use function error_get_last; @@ -103,10 +104,12 @@ class CrashDump{ public function __construct(Server $server){ $this->time = microtime(true); $this->server = $server; - if(!is_dir($this->server->getDataPath() . "crashdumps")){ - mkdir($this->server->getDataPath() . "crashdumps"); + + $crashPath = Path::join($this->server->getDataPath(), "crashdumps"); + if(!is_dir($crashPath)){ + mkdir($crashPath); } - $this->path = $this->server->getDataPath() . "crashdumps/" . date("D_M_j-H.i.s-T_Y", (int) $this->time) . ".log"; + $this->path = Path::join($crashPath, date("D_M_j-H.i.s-T_Y", (int) $this->time) . ".log"); $fp = @fopen($this->path, "wb"); if(!is_resource($fp)){ throw new \RuntimeException("Could not create Crash Dump"); @@ -193,12 +196,12 @@ class CrashDump{ if($this->server->getConfigGroup()->getPropertyBool("auto-report.send-settings", true)){ $this->data["parameters"] = (array) $argv; - if(($serverDotProperties = @file_get_contents($this->server->getDataPath() . "server.properties")) !== false){ + if(($serverDotProperties = @file_get_contents(Path::join($this->server->getDataPath(), "server.properties"))) !== false){ $this->data["server.properties"] = preg_replace("#^rcon\\.password=(.*)$#m", "rcon.password=******", $serverDotProperties); }else{ $this->data["server.properties"] = $serverDotProperties; } - if(($pocketmineDotYml = @file_get_contents($this->server->getDataPath() . "pocketmine.yml")) !== false){ + if(($pocketmineDotYml = @file_get_contents(Path::join($this->server->getDataPath(), "pocketmine.yml"))) !== false){ $this->data["pocketmine.yml"] = $pocketmineDotYml; }else{ $this->data["pocketmine.yml"] = ""; diff --git a/src/MemoryManager.php b/src/MemoryManager.php index b54eed878d..0a84e6b07a 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -30,6 +30,7 @@ use pocketmine\timings\Timings; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Process; use pocketmine\utils\Utils; +use Webmozart\PathUtil\Path; use function arsort; use function count; use function fclose; @@ -316,7 +317,7 @@ class MemoryManager{ mkdir($outputFolder, 0777, true); } - $obData = fopen($outputFolder . "/objects.js", "wb+"); + $obData = fopen(Path::join($outputFolder, "objects.js"), "wb+"); $data = []; @@ -367,7 +368,7 @@ class MemoryManager{ } } - file_put_contents($outputFolder . "/staticProperties.js", json_encode($staticProperties, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); + file_put_contents(Path::join($outputFolder, "staticProperties.js"), json_encode($staticProperties, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); $logger->info("Wrote $staticCount static properties"); if(isset($GLOBALS)){ //This might be null if we're on a different thread @@ -395,7 +396,7 @@ class MemoryManager{ $globalVariables[$varName] = self::continueDump($value, $objects, $refCounts, 0, $maxNesting, $maxStringSize); } - file_put_contents($outputFolder . "/globalVariables.js", json_encode($globalVariables, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); + file_put_contents(Path::join($outputFolder, "globalVariables.js"), json_encode($globalVariables, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); $logger->info("Wrote $globalCount global variables"); } @@ -411,7 +412,7 @@ class MemoryManager{ $functionStaticVarsCount += count($vars); } } - file_put_contents($outputFolder . '/functionStaticVars.js', json_encode($functionStaticVars, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); + file_put_contents(Path::join($outputFolder, 'functionStaticVars.js'), json_encode($functionStaticVars, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); $logger->info("Wrote $functionStaticVarsCount function static variables"); $data = self::continueDump($startingObject, $objects, $refCounts, 0, $maxNesting, $maxStringSize); @@ -483,11 +484,11 @@ class MemoryManager{ fclose($obData); - file_put_contents($outputFolder . "/serverEntry.js", json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); - file_put_contents($outputFolder . "/referenceCounts.js", json_encode($refCounts, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); + file_put_contents(Path::join($outputFolder, "serverEntry.js"), json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); + file_put_contents(Path::join($outputFolder, "referenceCounts.js"), json_encode($refCounts, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); arsort($instanceCounts, SORT_NUMERIC); - file_put_contents($outputFolder . "/instanceCounts.js", json_encode($instanceCounts, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); + file_put_contents(Path::join($outputFolder, "instanceCounts.js"), json_encode($instanceCounts, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); $logger->info("Finished!"); diff --git a/src/PocketMine.php b/src/PocketMine.php index b154a8f123..0fce540eff 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -33,6 +33,7 @@ namespace pocketmine { use pocketmine\utils\Terminal; use pocketmine\utils\Timezone; use pocketmine\wizard\SetupWizard; + use Webmozart\PathUtil\Path; use function extension_loaded; use function phpversion; use function preg_match; @@ -234,7 +235,7 @@ namespace pocketmine { mkdir($dataPath, 0777, true); } - $lockFilePath = $dataPath . '/server.lock'; + $lockFilePath = Path::join($dataPath, 'server.lock'); if(($pid = Filesystem::createLockFile($lockFilePath)) !== null){ critical_error("Another " . VersionInfo::NAME . " instance (PID $pid) is already using this folder (" . realpath($dataPath) . ")."); critical_error("Please stop the other server first before running a new one."); @@ -252,14 +253,14 @@ namespace pocketmine { Terminal::init(); } - $logger = new MainLogger($dataPath . "server.log", Terminal::hasFormattingCodes(), "Server", new \DateTimeZone(Timezone::get())); + $logger = new MainLogger(Path::join($dataPath, "server.log"), Terminal::hasFormattingCodes(), "Server", new \DateTimeZone(Timezone::get())); \GlobalLogger::set($logger); emit_performance_warnings($logger); $exitCode = 0; do{ - if(!file_exists($dataPath . "server.properties") and !isset($opts["no-wizard"])){ + if(!file_exists(Path::join($dataPath, "server.properties")) and !isset($opts["no-wizard"])){ $installer = new SetupWizard($dataPath); if(!$installer->run()){ $exitCode = -1; diff --git a/src/Server.php b/src/Server.php index aef04a98ed..5b355f8b40 100644 --- a/src/Server.php +++ b/src/Server.php @@ -105,6 +105,7 @@ use pocketmine\world\World; use pocketmine\world\WorldCreationOptions; use pocketmine\world\WorldManager; use Ramsey\Uuid\UuidInterface; +use Webmozart\PathUtil\Path; use function array_shift; use function array_sum; use function base64_encode; @@ -515,7 +516,7 @@ class Server{ } private function getPlayerDataPath(string $username) : string{ - return $this->getDataPath() . '/players/' . strtolower($username) . '.dat'; + return Path::join($this->getDataPath(), 'players', strtolower($username) . '.dat'); } /** @@ -811,33 +812,33 @@ class Server{ $this->logger = $logger; try{ - if(!file_exists($dataPath . "worlds/")){ - mkdir($dataPath . "worlds/", 0777); - } - - if(!file_exists($dataPath . "players/")){ - mkdir($dataPath . "players/", 0777); - } - - if(!file_exists($pluginPath)){ - mkdir($pluginPath, 0777); + foreach([ + $dataPath, + $pluginPath, + Path::join($dataPath, "worlds"), + Path::join($dataPath, "players") + ] as $neededPath){ + if(!file_exists($neededPath)){ + mkdir($neededPath, 0777); + } } $this->dataPath = realpath($dataPath) . DIRECTORY_SEPARATOR; $this->pluginPath = realpath($pluginPath) . DIRECTORY_SEPARATOR; $this->logger->info("Loading server configuration"); - if(!file_exists($this->dataPath . "pocketmine.yml")){ - $content = file_get_contents(\pocketmine\RESOURCE_PATH . "pocketmine.yml"); + $pocketmineYmlPath = Path::join($this->dataPath, "pocketmine.yml"); + if(!file_exists($pocketmineYmlPath)){ + $content = file_get_contents(Path::join(\pocketmine\RESOURCE_PATH, "pocketmine.yml")); if(VersionInfo::IS_DEVELOPMENT_BUILD){ $content = str_replace("preferred-channel: stable", "preferred-channel: beta", $content); } - @file_put_contents($this->dataPath . "pocketmine.yml", $content); + @file_put_contents($pocketmineYmlPath, $content); } $this->configGroup = new ServerConfigGroup( - new Config($this->dataPath . "pocketmine.yml", Config::YAML, []), - new Config($this->dataPath . "server.properties", Config::PROPERTIES, [ + new Config($pocketmineYmlPath, Config::YAML, []), + new Config(Path::join($this->dataPath, "server.properties"), Config::PROPERTIES, [ "motd" => VersionInfo::NAME . " Server", "server-port" => 19132, "white-list" => false, @@ -934,16 +935,20 @@ class Server{ $this->doTitleTick = $this->configGroup->getPropertyBool("console.title-tick", true) && Terminal::hasFormattingCodes(); - $this->operators = new Config($this->dataPath . "ops.txt", Config::ENUM); - $this->whitelist = new Config($this->dataPath . "white-list.txt", Config::ENUM); - if(file_exists($this->dataPath . "banned.txt") and !file_exists($this->dataPath . "banned-players.txt")){ - @rename($this->dataPath . "banned.txt", $this->dataPath . "banned-players.txt"); + $this->operators = new Config(Path::join($this->dataPath, "ops.txt"), Config::ENUM); + $this->whitelist = new Config(Path::join($this->dataPath, "white-list.txt"), Config::ENUM); + + $bannedTxt = Path::join($this->dataPath, "banned.txt"); + $bannedPlayersTxt = Path::join($this->dataPath, "banned-players.txt"); + if(file_exists($bannedTxt) and !file_exists($bannedPlayersTxt)){ + @rename($bannedTxt, $bannedPlayersTxt); } - @touch($this->dataPath . "banned-players.txt"); - $this->banByName = new BanList($this->dataPath . "banned-players.txt"); + @touch($bannedPlayersTxt); + $this->banByName = new BanList($bannedPlayersTxt); $this->banByName->load(); - @touch($this->dataPath . "banned-ips.txt"); - $this->banByIP = new BanList($this->dataPath . "banned-ips.txt"); + $bannedIpsTxt = Path::join($this->dataPath, "banned-ips.txt"); + @touch($bannedIpsTxt); + $this->banByIP = new BanList($bannedIpsTxt); $this->banByIP->load(); $this->maxPlayers = $this->configGroup->getConfigInt("max-players", 20); @@ -985,14 +990,14 @@ class Server{ $this->commandMap = new SimpleCommandMap($this); - $this->craftingManager = CraftingManagerFromDataHelper::make(\pocketmine\RESOURCE_PATH . '/vanilla/recipes.json'); + $this->craftingManager = CraftingManagerFromDataHelper::make(Path::join(\pocketmine\RESOURCE_PATH, "vanilla", "recipes.json")); - $this->resourceManager = new ResourcePackManager($this->getDataPath() . "resource_packs" . DIRECTORY_SEPARATOR, $this->logger); + $this->resourceManager = new ResourcePackManager(Path::join($this->getDataPath(), "resource_packs"), $this->logger); $pluginGraylist = null; - $graylistFile = $this->dataPath . "plugin_list.yml"; + $graylistFile = Path::join($this->dataPath, "plugin_list.yml"); if(!file_exists($graylistFile)){ - copy(\pocketmine\RESOURCE_PATH . 'plugin_list.yml', $graylistFile); + copy(Path::join(\pocketmine\RESOURCE_PATH, 'plugin_list.yml'), $graylistFile); } try{ $pluginGraylist = PluginGraylist::fromArray(yaml_parse(file_get_contents($graylistFile))); @@ -1001,7 +1006,7 @@ class Server{ $this->forceShutdown(); return; } - $this->pluginManager = new PluginManager($this, $this->configGroup->getPropertyBool("plugins.legacy-data-dir", true) ? null : $this->getDataPath() . "plugin_data" . DIRECTORY_SEPARATOR, $pluginGraylist); + $this->pluginManager = new PluginManager($this, $this->configGroup->getPropertyBool("plugins.legacy-data-dir", true) ? null : Path::join($this->getDataPath(), "plugin_data"), $pluginGraylist); $this->pluginManager->registerInterface(new PharPluginLoader($this->autoloader)); $this->pluginManager->registerInterface(new ScriptPluginLoader()); @@ -1015,7 +1020,7 @@ class Server{ $this->logger->warning($this->language->translateString("pocketmine.level.badDefaultFormat", [$formatName])); } - $this->worldManager = new WorldManager($this, $this->dataPath . "/worlds", $providerManager); + $this->worldManager = new WorldManager($this, Path::join($this->dataPath, "worlds"), $providerManager); $this->worldManager->setAutoSave($this->configGroup->getConfigBool("auto-save", $this->worldManager->getAutoSave())); $this->worldManager->setAutoSaveInterval($this->configGroup->getPropertyInt("ticks-per.autosave", 6000)); @@ -1504,7 +1509,7 @@ class Server{ if($this->configGroup->getPropertyBool("auto-report.enabled", true)){ $report = true; - $stamp = $this->getDataPath() . "crashdumps/.last_crash"; + $stamp = Path::join($this->getDataPath(), "crashdumps", ".last_crash"); $crashInterval = 120; //2 minutes if(file_exists($stamp) and !($report = (filemtime($stamp) + $crashInterval < time()))){ $this->logger->debug("Not sending crashdump due to last crash less than $crashInterval seconds ago"); diff --git a/src/command/defaults/DumpMemoryCommand.php b/src/command/defaults/DumpMemoryCommand.php index 34c1da9e69..0f57103046 100644 --- a/src/command/defaults/DumpMemoryCommand.php +++ b/src/command/defaults/DumpMemoryCommand.php @@ -25,6 +25,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\permission\DefaultPermissionNames; +use Webmozart\PathUtil\Path; use function date; class DumpMemoryCommand extends VanillaCommand{ @@ -43,7 +44,7 @@ class DumpMemoryCommand extends VanillaCommand{ return true; } - $sender->getServer()->getMemoryManager()->dumpServerMemory($args[0] ?? ($sender->getServer()->getDataPath() . "/memory_dumps/" . date("D_M_j-H.i.s-T_Y")), 48, 80); + $sender->getServer()->getMemoryManager()->dumpServerMemory($args[0] ?? (Path::join($sender->getServer()->getDataPath(), "memory_dumps" . date("D_M_j-H.i.s-T_Y"))), 48, 80); return true; } } diff --git a/src/command/defaults/TimingsCommand.php b/src/command/defaults/TimingsCommand.php index e4dbc72a06..21018d50a6 100644 --- a/src/command/defaults/TimingsCommand.php +++ b/src/command/defaults/TimingsCommand.php @@ -34,6 +34,7 @@ use pocketmine\scheduler\BulkCurlTaskOperation; use pocketmine\timings\TimingsHandler; use pocketmine\utils\InternetException; use pocketmine\utils\InternetRequestResult; +use Webmozart\PathUtil\Path; use function count; use function fclose; use function file_exists; @@ -107,14 +108,14 @@ class TimingsCommand extends VanillaCommand{ $fileTimings = fopen("php://temp", "r+b"); }else{ $index = 0; - $timingFolder = $sender->getServer()->getDataPath() . "timings/"; + $timingFolder = Path::join($sender->getServer()->getDataPath(), "timings"); if(!file_exists($timingFolder)){ mkdir($timingFolder, 0777); } - $timings = $timingFolder . "timings.txt"; + $timings = Path::join($timingFolder, "timings.txt"); while(file_exists($timings)){ - $timings = $timingFolder . "timings" . (++$index) . ".txt"; + $timings = Path::join($timingFolder, "timings" . (++$index) . ".txt"); } $fileTimings = fopen($timings, "a+b"); diff --git a/src/data/bedrock/LegacyBlockIdToStringIdMap.php b/src/data/bedrock/LegacyBlockIdToStringIdMap.php index e46fefb9dd..c9e0212b08 100644 --- a/src/data/bedrock/LegacyBlockIdToStringIdMap.php +++ b/src/data/bedrock/LegacyBlockIdToStringIdMap.php @@ -24,11 +24,12 @@ declare(strict_types=1); namespace pocketmine\data\bedrock; use pocketmine\utils\SingletonTrait; +use Webmozart\PathUtil\Path; final class LegacyBlockIdToStringIdMap extends LegacyToStringBidirectionalIdMap{ use SingletonTrait; public function __construct(){ - parent::__construct(\pocketmine\RESOURCE_PATH . 'vanilla/block_id_map.json'); + parent::__construct(Path::join(\pocketmine\RESOURCE_PATH, 'vanilla', 'block_id_map.json')); } } diff --git a/src/data/bedrock/LegacyEntityIdToStringIdMap.php b/src/data/bedrock/LegacyEntityIdToStringIdMap.php index b12cc8bced..fa37bfbd91 100644 --- a/src/data/bedrock/LegacyEntityIdToStringIdMap.php +++ b/src/data/bedrock/LegacyEntityIdToStringIdMap.php @@ -24,11 +24,12 @@ declare(strict_types=1); namespace pocketmine\data\bedrock; use pocketmine\utils\SingletonTrait; +use Webmozart\PathUtil\Path; final class LegacyEntityIdToStringIdMap extends LegacyToStringBidirectionalIdMap{ use SingletonTrait; public function __construct(){ - parent::__construct(\pocketmine\RESOURCE_PATH . '/vanilla/entity_id_map.json'); + parent::__construct(Path::join(\pocketmine\RESOURCE_PATH, 'vanilla', 'entity_id_map.json')); } } diff --git a/src/data/bedrock/LegacyItemIdToStringIdMap.php b/src/data/bedrock/LegacyItemIdToStringIdMap.php index 93219a549e..083f2024b4 100644 --- a/src/data/bedrock/LegacyItemIdToStringIdMap.php +++ b/src/data/bedrock/LegacyItemIdToStringIdMap.php @@ -24,11 +24,12 @@ declare(strict_types=1); namespace pocketmine\data\bedrock; use pocketmine\utils\SingletonTrait; +use Webmozart\PathUtil\Path; final class LegacyItemIdToStringIdMap extends LegacyToStringBidirectionalIdMap{ use SingletonTrait; public function __construct(){ - parent::__construct(\pocketmine\RESOURCE_PATH . 'vanilla/item_id_map.json'); + parent::__construct(Path::join(\pocketmine\RESOURCE_PATH, 'vanilla', 'item_id_map.json')); } } diff --git a/src/inventory/CreativeInventory.php b/src/inventory/CreativeInventory.php index a2666d1bed..99ad5f60ed 100644 --- a/src/inventory/CreativeInventory.php +++ b/src/inventory/CreativeInventory.php @@ -26,9 +26,9 @@ namespace pocketmine\inventory; use pocketmine\item\Durable; use pocketmine\item\Item; use pocketmine\utils\SingletonTrait; +use Webmozart\PathUtil\Path; use function file_get_contents; use function json_decode; -use const DIRECTORY_SEPARATOR; final class CreativeInventory{ use SingletonTrait; @@ -37,7 +37,7 @@ final class CreativeInventory{ private $creative = []; private function __construct(){ - $creativeItems = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla" . DIRECTORY_SEPARATOR . "creativeitems.json"), true); + $creativeItems = json_decode(file_get_contents(Path::join(\pocketmine\RESOURCE_PATH, "vanilla", "creativeitems.json")), true); foreach($creativeItems as $data){ $item = Item::jsonDeserialize($data); diff --git a/src/item/LegacyStringToItemParser.php b/src/item/LegacyStringToItemParser.php index 6eaa62ff92..ca7559e640 100644 --- a/src/item/LegacyStringToItemParser.php +++ b/src/item/LegacyStringToItemParser.php @@ -25,6 +25,7 @@ namespace pocketmine\item; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\SingletonTrait; +use Webmozart\PathUtil\Path; use function explode; use function file_get_contents; use function is_array; @@ -51,7 +52,7 @@ final class LegacyStringToItemParser{ private static function make() : self{ $result = new self(ItemFactory::getInstance()); - $mappingsRaw = @file_get_contents(\pocketmine\RESOURCE_PATH . '/item_from_string_bc_map.json'); + $mappingsRaw = @file_get_contents(Path::join(\pocketmine\RESOURCE_PATH, 'item_from_string_bc_map.json')); if($mappingsRaw === false) throw new AssumptionFailedError("Missing required resource file"); $mappings = json_decode($mappingsRaw, true); diff --git a/src/lang/Language.php b/src/lang/Language.php index efac90e002..29cb311a7b 100644 --- a/src/lang/Language.php +++ b/src/lang/Language.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\lang; +use Webmozart\PathUtil\Path; use function array_filter; use function array_map; use function explode; @@ -51,7 +52,7 @@ class Language{ */ public static function getLanguageList(string $path = "") : array{ if($path === ""){ - $path = \pocketmine\RESOURCE_PATH . "locale/"; + $path = Path::join(\pocketmine\RESOURCE_PATH, "locale"); } if(is_dir($path)){ @@ -100,7 +101,7 @@ class Language{ $this->langName = strtolower($lang); if($path === null){ - $path = \pocketmine\RESOURCE_PATH . "locale/"; + $path = Path::join(\pocketmine\RESOURCE_PATH, "locale"); } $this->lang = self::loadLang($path, $this->langName); @@ -120,7 +121,7 @@ class Language{ * @phpstan-return array */ protected static function loadLang(string $path, string $languageCode) : array{ - $file = $path . $languageCode . ".ini"; + $file = Path::join($path, $languageCode . ".ini"); if(file_exists($file)){ return array_map('\stripcslashes', parse_ini_file($file, false, INI_SCANNER_RAW)); } diff --git a/src/network/mcpe/cache/StaticPacketCache.php b/src/network/mcpe/cache/StaticPacketCache.php index 51bc879e08..901fe875cc 100644 --- a/src/network/mcpe/cache/StaticPacketCache.php +++ b/src/network/mcpe/cache/StaticPacketCache.php @@ -28,6 +28,7 @@ use pocketmine\network\mcpe\protocol\BiomeDefinitionListPacket; use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; use pocketmine\network\mcpe\protocol\types\CacheableNbt; use pocketmine\utils\SingletonTrait; +use Webmozart\PathUtil\Path; use function file_get_contents; class StaticPacketCache{ @@ -49,8 +50,8 @@ class StaticPacketCache{ private static function make() : self{ return new self( - BiomeDefinitionListPacket::create(self::loadCompoundFromFile(\pocketmine\RESOURCE_PATH . '/vanilla/biome_definitions.nbt')), - AvailableActorIdentifiersPacket::create(self::loadCompoundFromFile(\pocketmine\RESOURCE_PATH . '/vanilla/entity_identifiers.nbt')) + BiomeDefinitionListPacket::create(self::loadCompoundFromFile(Path::join(\pocketmine\RESOURCE_PATH, 'vanilla', 'biome_definitions.nbt'))), + AvailableActorIdentifiersPacket::create(self::loadCompoundFromFile(Path::join(\pocketmine\RESOURCE_PATH, 'vanilla', 'entity_identifiers.nbt'))) ); } diff --git a/src/network/mcpe/convert/GlobalItemTypeDictionary.php b/src/network/mcpe/convert/GlobalItemTypeDictionary.php index 349ddc3bba..c1537fa7cd 100644 --- a/src/network/mcpe/convert/GlobalItemTypeDictionary.php +++ b/src/network/mcpe/convert/GlobalItemTypeDictionary.php @@ -27,6 +27,7 @@ use pocketmine\network\mcpe\protocol\serializer\ItemTypeDictionary; use pocketmine\network\mcpe\protocol\types\ItemTypeEntry; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\SingletonTrait; +use Webmozart\PathUtil\Path; use function file_get_contents; use function is_array; use function is_bool; @@ -38,7 +39,7 @@ final class GlobalItemTypeDictionary{ use SingletonTrait; private static function make() : self{ - $data = file_get_contents(\pocketmine\RESOURCE_PATH . '/vanilla/required_item_list.json'); + $data = file_get_contents(Path::join(\pocketmine\RESOURCE_PATH, 'vanilla', 'required_item_list.json')); if($data === false) throw new AssumptionFailedError("Missing required resource file"); $table = json_decode($data, true); if(!is_array($table)){ diff --git a/src/network/mcpe/convert/ItemTranslator.php b/src/network/mcpe/convert/ItemTranslator.php index 30a53ebd1d..d1a7c3a580 100644 --- a/src/network/mcpe/convert/ItemTranslator.php +++ b/src/network/mcpe/convert/ItemTranslator.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\convert; use pocketmine\network\mcpe\protocol\serializer\ItemTypeDictionary; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\SingletonTrait; +use Webmozart\PathUtil\Path; use function array_key_exists; use function file_get_contents; use function is_array; @@ -64,14 +65,14 @@ final class ItemTranslator{ private $complexNetToCoreMapping = []; private static function make() : self{ - $data = file_get_contents(\pocketmine\RESOURCE_PATH . '/vanilla/r16_to_current_item_map.json'); + $data = file_get_contents(Path::join(\pocketmine\RESOURCE_PATH, 'vanilla', 'r16_to_current_item_map.json')); if($data === false) throw new AssumptionFailedError("Missing required resource file"); $json = json_decode($data, true); if(!is_array($json) or !isset($json["simple"], $json["complex"]) || !is_array($json["simple"]) || !is_array($json["complex"])){ throw new AssumptionFailedError("Invalid item table format"); } - $legacyStringToIntMapRaw = file_get_contents(\pocketmine\RESOURCE_PATH . '/vanilla/item_id_map.json'); + $legacyStringToIntMapRaw = file_get_contents(Path::join(\pocketmine\RESOURCE_PATH, 'vanilla', 'item_id_map.json')); if($legacyStringToIntMapRaw === false){ throw new AssumptionFailedError("Missing required resource file"); } diff --git a/src/network/mcpe/convert/RuntimeBlockMapping.php b/src/network/mcpe/convert/RuntimeBlockMapping.php index 91359f4519..95dbcb8fb1 100644 --- a/src/network/mcpe/convert/RuntimeBlockMapping.php +++ b/src/network/mcpe/convert/RuntimeBlockMapping.php @@ -31,6 +31,7 @@ use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\SingletonTrait; +use Webmozart\PathUtil\Path; use function file_get_contents; /** @@ -47,7 +48,7 @@ final class RuntimeBlockMapping{ private $bedrockKnownStates; private function __construct(){ - $canonicalBlockStatesFile = file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla/canonical_block_states.nbt"); + $canonicalBlockStatesFile = file_get_contents(Path::join(\pocketmine\RESOURCE_PATH, "vanilla", "canonical_block_states.nbt")); if($canonicalBlockStatesFile === false){ throw new AssumptionFailedError("Missing required resource file"); } @@ -65,7 +66,7 @@ final class RuntimeBlockMapping{ $legacyIdMap = LegacyBlockIdToStringIdMap::getInstance(); /** @var R12ToCurrentBlockMapEntry[] $legacyStateMap */ $legacyStateMap = []; - $legacyStateMapReader = new PacketSerializer(file_get_contents(\pocketmine\RESOURCE_PATH . "vanilla/r12_to_current_block_map.bin")); + $legacyStateMapReader = new PacketSerializer(file_get_contents(Path::join(\pocketmine\RESOURCE_PATH, "vanilla", "r12_to_current_block_map.bin"))); $nbtReader = new NetworkNbtSerializer(); while(!$legacyStateMapReader->feof()){ $id = $legacyStateMapReader->getString(); diff --git a/src/plugin/PluginBase.php b/src/plugin/PluginBase.php index 02d2325343..eae2aeec3e 100644 --- a/src/plugin/PluginBase.php +++ b/src/plugin/PluginBase.php @@ -31,6 +31,7 @@ use pocketmine\scheduler\TaskScheduler; use pocketmine\Server; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Config; +use Webmozart\PathUtil\Path; use function count; use function dirname; use function fclose; @@ -86,7 +87,7 @@ abstract class PluginBase implements Plugin, CommandExecutor{ $this->dataFolder = rtrim($dataFolder, "/" . DIRECTORY_SEPARATOR) . "/"; //TODO: this is accessed externally via reflection, not unused $this->file = rtrim($file, "/" . DIRECTORY_SEPARATOR) . "/"; - $this->configFile = $this->dataFolder . "config.yml"; + $this->configFile = Path::join($this->dataFolder, "config.yml"); $prefix = $this->getDescription()->getPrefix(); $this->logger = new PluginLogger($server->getLogger(), $prefix !== "" ? $prefix : $this->getName()); @@ -261,7 +262,7 @@ abstract class PluginBase implements Plugin, CommandExecutor{ return false; } - $out = $this->dataFolder . $filename; + $out = Path::join($this->dataFolder, $filename); if(!file_exists(dirname($out))){ mkdir(dirname($out), 0755, true); } diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 4b7c1b960d..f42669b1df 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -39,6 +39,7 @@ use pocketmine\Server; use pocketmine\timings\TimingsHandler; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Utils; +use Webmozart\PathUtil\Path; use function array_intersect; use function array_merge; use function class_exists; @@ -59,7 +60,6 @@ use function shuffle; use function stripos; use function strpos; use function strtolower; -use const DIRECTORY_SEPARATOR; /** * Manages all the plugins @@ -121,9 +121,9 @@ class PluginManager{ private function getDataDirectory(string $pluginPath, string $pluginName) : string{ if($this->pluginDataDirectory !== null){ - return $this->pluginDataDirectory . $pluginName; + return Path::join($this->pluginDataDirectory, $pluginName); } - return dirname($pluginPath) . DIRECTORY_SEPARATOR . $pluginName; + return Path::join(dirname($pluginPath), $pluginName); } /** diff --git a/src/resourcepacks/ResourcePackManager.php b/src/resourcepacks/ResourcePackManager.php index 1b6af4549b..08b9a90ae7 100644 --- a/src/resourcepacks/ResourcePackManager.php +++ b/src/resourcepacks/ResourcePackManager.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\resourcepacks; use pocketmine\utils\Config; +use Webmozart\PathUtil\Path; use function array_keys; use function copy; use function count; @@ -63,11 +64,12 @@ class ResourcePackManager{ throw new \InvalidArgumentException("Resource packs path $path exists and is not a directory"); } - if(!file_exists($this->path . "resource_packs.yml")){ - copy(\pocketmine\RESOURCE_PATH . "resource_packs.yml", $this->path . "resource_packs.yml"); + $resourcePacksYml = Path::join($this->path, "resource_packs.yml"); + if(!file_exists($resourcePacksYml)){ + copy(Path::join(\pocketmine\RESOURCE_PATH, "resource_packs.yml"), $resourcePacksYml); } - $resourcePacksConfig = new Config($this->path . "resource_packs.yml", Config::YAML, []); + $resourcePacksConfig = new Config($resourcePacksYml, Config::YAML, []); $this->serverForceResources = (bool) $resourcePacksConfig->get("force_resources", false); @@ -84,7 +86,7 @@ class ResourcePackManager{ continue; } try{ - $packPath = $this->path . DIRECTORY_SEPARATOR . $pack; + $packPath = Path::join($this->path, $pack); if(!file_exists($packPath)){ throw new ResourcePackException("File or directory not found"); } @@ -120,7 +122,7 @@ class ResourcePackManager{ * Returns the directory which resource packs are loaded from. */ public function getPath() : string{ - return $this->path; + return $this->path . DIRECTORY_SEPARATOR; } /** diff --git a/src/scheduler/DumpWorkerMemoryTask.php b/src/scheduler/DumpWorkerMemoryTask.php index 213721fae3..01ff114632 100644 --- a/src/scheduler/DumpWorkerMemoryTask.php +++ b/src/scheduler/DumpWorkerMemoryTask.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\scheduler; use pocketmine\MemoryManager; -use const DIRECTORY_SEPARATOR; +use Webmozart\PathUtil\Path; /** * Task used to dump memory from AsyncWorkers @@ -46,7 +46,7 @@ class DumpWorkerMemoryTask extends AsyncTask{ public function onRun() : void{ MemoryManager::dumpMemory( $this->worker, - $this->outputFolder . DIRECTORY_SEPARATOR . "AsyncWorker#" . $this->worker->getAsyncWorkerId(), + Path::join($this->outputFolder, "AsyncWorker#" . $this->worker->getAsyncWorkerId()), $this->maxNesting, $this->maxStringSize, new \PrefixedLogger($this->worker->getLogger(), "Memory Dump") diff --git a/src/utils/Config.php b/src/utils/Config.php index dfd41bda97..0a42deac37 100644 --- a/src/utils/Config.php +++ b/src/utils/Config.php @@ -23,11 +23,10 @@ declare(strict_types=1); namespace pocketmine\utils; +use Webmozart\PathUtil\Path; use function array_change_key_case; use function array_keys; -use function array_pop; use function array_shift; -use function basename; use function count; use function date; use function explode; @@ -152,8 +151,7 @@ class Config{ $this->type = $type; if($this->type === Config::DETECT){ - $extension = explode(".", basename($this->file)); - $extension = strtolower(trim(array_pop($extension))); + $extension = strtolower(Path::getExtension($this->file)); if(isset(Config::$formats[$extension])){ $this->type = Config::$formats[$extension]; }else{ diff --git a/src/utils/Filesystem.php b/src/utils/Filesystem.php index 531becc78b..9a89976e6c 100644 --- a/src/utils/Filesystem.php +++ b/src/utils/Filesystem.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\utils; +use Webmozart\PathUtil\Path; use function copy; use function dirname; use function fclose; @@ -79,10 +80,11 @@ final class Filesystem{ if($objects === false) throw new AssumptionFailedError("scandir() shouldn't return false when is_dir() returns true"); foreach($objects as $object){ if($object !== "." and $object !== ".."){ - if(is_dir($dir . "/" . $object)){ - self::recursiveUnlink($dir . "/" . $object); + $fullObject = Path::join($dir, $object); + if(is_dir($fullObject)){ + self::recursiveUnlink($fullObject); }else{ - unlink($dir . "/" . $object); + unlink($fullObject); } } } @@ -128,7 +130,7 @@ final class Filesystem{ if($object === "." || $object === ".."){ continue; } - self::recursiveCopyInternal($origin . "/" . $object, $destination . "/" . $object); + self::recursiveCopyInternal(Path::join($origin, $object), Path::join($destination, $object)); } }else{ $dirName = dirname($destination); diff --git a/src/wizard/SetupWizard.php b/src/wizard/SetupWizard.php index 5491422c62..31d71e5515 100644 --- a/src/wizard/SetupWizard.php +++ b/src/wizard/SetupWizard.php @@ -35,6 +35,7 @@ use pocketmine\utils\Config; use pocketmine\utils\Internet; use pocketmine\utils\InternetException; use pocketmine\VersionInfo; +use Webmozart\PathUtil\Path; use function fgets; use function sleep; use function strtolower; @@ -88,7 +89,7 @@ class SetupWizard{ } //this has to happen here to prevent user avoiding agreeing to license - $config = new Config($this->dataPath . "/server.properties", Config::PROPERTIES); + $config = new Config(Path::join($this->dataPath, "server.properties"), Config::PROPERTIES); $config->set("language", $lang); $config->save(); @@ -138,7 +139,7 @@ LICENSE; } private function generateBaseConfig() : void{ - $config = new Config($this->dataPath . "/server.properties", Config::PROPERTIES); + $config = new Config(Path::join($this->dataPath, "server.properties"), Config::PROPERTIES); $config->set("motd", ($name = $this->getInput($this->lang->get("name_your_server"), self::DEFAULT_NAME))); $config->set("server-name", $name); @@ -175,14 +176,14 @@ LICENSE; if($op === ""){ $this->error($this->lang->get("op_warning")); }else{ - $ops = new Config($this->dataPath . "/ops.txt", Config::ENUM); + $ops = new Config(Path::join($this->dataPath, "ops.txt"), Config::ENUM); $ops->set($op, true); $ops->save(); } $this->message($this->lang->get("whitelist_info")); - $config = new Config($this->dataPath . "/server.properties", Config::PROPERTIES); + $config = new Config(Path::join($this->dataPath, "server.properties"), Config::PROPERTIES); if(strtolower($this->getInput($this->lang->get("whitelist_enable"), "n", "y/N")) === "y"){ $this->error($this->lang->get("whitelist_warning")); $config->set("white-list", true); @@ -193,7 +194,7 @@ LICENSE; } private function networkFunctions() : void{ - $config = new Config($this->dataPath . "/server.properties", Config::PROPERTIES); + $config = new Config(Path::join($this->dataPath, "server.properties"), Config::PROPERTIES); $this->error($this->lang->get("query_warning1")); $this->error($this->lang->get("query_warning2")); if(strtolower($this->getInput($this->lang->get("query_disable"), "n", "y/N")) === "y"){ diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 9bca16ad22..4fb3df5b29 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -37,6 +37,7 @@ use pocketmine\world\format\io\WorldProvider; use pocketmine\world\format\io\WorldProviderManager; use pocketmine\world\format\io\WritableWorldProvider; use pocketmine\world\generator\GeneratorManager; +use Webmozart\PathUtil\Path; use function array_keys; use function array_shift; use function assert; @@ -49,7 +50,6 @@ use function microtime; use function round; use function sprintf; use function trim; -use const DIRECTORY_SEPARATOR; class WorldManager{ /** @var string */ @@ -228,7 +228,7 @@ class WorldManager{ } $this->server->getLogger()->notice("Upgrading world \"$name\" to new format. This may take a while."); - $converter = new FormatConverter($provider, $this->providerManager->getDefault(), $this->server->getDataPath() . "backups" . DIRECTORY_SEPARATOR . "worlds", $this->server->getLogger()); + $converter = new FormatConverter($provider, $this->providerManager->getDefault(), Path::join($this->server->getDataPath(), "backups", "worlds"), $this->server->getLogger()); $provider = $converter->execute(); $this->server->getLogger()->notice("Upgraded world \"$name\" to new format successfully. Backed up pre-conversion world at " . $converter->getBackupPath()); @@ -300,7 +300,7 @@ class WorldManager{ } private function getWorldPath(string $name) : string{ - return $this->dataPath . "/" . $name . "/"; + return Path::join($this->dataPath, $name) . "/"; //TODO: check if we still need the trailing dirsep (I'm a little scared to remove it) } public function isWorldGenerated(string $name) : bool{ diff --git a/src/world/format/io/FormatConverter.php b/src/world/format/io/FormatConverter.php index 2dfc5b624e..053e26c372 100644 --- a/src/world/format/io/FormatConverter.php +++ b/src/world/format/io/FormatConverter.php @@ -27,6 +27,7 @@ use pocketmine\utils\Filesystem; use pocketmine\utils\Utils; use pocketmine\world\generator\GeneratorManager; use pocketmine\world\WorldCreationOptions; +use Webmozart\PathUtil\Path; use function basename; use function crc32; use function file_exists; @@ -71,7 +72,7 @@ class FormatConverter{ } $nextSuffix = ""; do{ - $this->backupPath = $backupPath . DIRECTORY_SEPARATOR . basename($this->oldProvider->getPath()) . $nextSuffix; + $this->backupPath = Path::join($backupPath, basename($this->oldProvider->getPath()) . $nextSuffix); $nextSuffix = "_" . crc32(random_bytes(4)); }while(file_exists($this->backupPath)); } diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 53df6a190e..aaffee8fb4 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -47,6 +47,7 @@ use pocketmine\world\format\io\WritableWorldProvider; use pocketmine\world\format\PalettedBlockArray; use pocketmine\world\format\SubChunk; use pocketmine\world\WorldCreationOptions; +use Webmozart\PathUtil\Path; use function array_map; use function array_values; use function chr; @@ -62,7 +63,6 @@ use function strlen; use function substr; use function trim; use function unpack; -use const DIRECTORY_SEPARATOR; use const LEVELDB_ZLIB_RAW_COMPRESSION; class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ @@ -110,7 +110,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ * @throws \LevelDBException */ private static function createDB(string $path) : \LevelDB{ - return new \LevelDB($path . "/db", [ + return new \LevelDB(Path::join($path, "db"), [ "compression" => LEVELDB_ZLIB_RAW_COMPRESSION, "block_size" => 64 * 1024 //64KB, big enough for most chunks ]); @@ -129,7 +129,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ } protected function loadLevelData() : WorldData{ - return new BedrockWorldData($this->getPath() . DIRECTORY_SEPARATOR . "level.dat"); + return new BedrockWorldData(Path::join($this->getPath(), "level.dat")); } public function getWorldMinY() : int{ @@ -141,14 +141,15 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ } public static function isValid(string $path) : bool{ - return file_exists($path . "/level.dat") and is_dir($path . "/db/"); + return file_exists(Path::join($path, "level.dat")) and is_dir(Path::join($path, "db")); } public static function generate(string $path, string $name, WorldCreationOptions $options) : void{ self::checkForLevelDBExtension(); - if(!file_exists($path . "/db")){ - mkdir($path . "/db", 0777, true); + $dbPath = Path::join($path, "db"); + if(!file_exists($dbPath)){ + mkdir($dbPath, 0777, true); } BedrockWorldData::generate($path, $name, $options); diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index 212691b282..3765a33eb5 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -32,6 +32,7 @@ use pocketmine\world\format\io\BaseWorldProvider; use pocketmine\world\format\io\data\JavaWorldData; use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\WorldData; +use Webmozart\PathUtil\Path; use function assert; use function file_exists; use function is_dir; @@ -43,7 +44,6 @@ use function strlen; use function strrpos; use function substr; use function time; -use const DIRECTORY_SEPARATOR; use const SCANDIR_SORT_NONE; abstract class RegionWorldProvider extends BaseWorldProvider{ @@ -59,8 +59,8 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ abstract protected static function getPcWorldFormatVersion() : int; public static function isValid(string $path) : bool{ - if(file_exists($path . "/level.dat") and is_dir($path . "/region/")){ - foreach(scandir($path . "/region/", SCANDIR_SORT_NONE) as $file){ + if(file_exists(Path::join($path, "level.dat")) and is_dir($regionPath = Path::join($path, "region"))){ + foreach(scandir($regionPath, SCANDIR_SORT_NONE) as $file){ $extPos = strrpos($file, "."); if($extPos !== false && substr($file, $extPos + 1) === static::getRegionFileExtension()){ //we don't care if other region types exist, we only care if this format is possible @@ -76,7 +76,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ protected $regions = []; protected function loadLevelData() : WorldData{ - return new JavaWorldData($this->getPath() . DIRECTORY_SEPARATOR . "level.dat"); + return new JavaWorldData(Path::join($this->getPath(), "level.dat")); } public function doGarbageCollection() : void{ @@ -106,7 +106,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ * Returns the path to a specific region file based on its X/Z coordinates */ protected function pathToRegion(int $regionX, int $regionZ) : string{ - return $this->path . "/region/r.$regionX.$regionZ." . static::getRegionFileExtension(); + return Path::join($this->path, "region", "r.$regionX.$regionZ." . static::getRegionFileExtension()); } protected function loadRegion(int $regionX, int $regionZ) : RegionLoader{ @@ -205,7 +205,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ private function createRegionIterator() : \RegexIterator{ return new \RegexIterator( new \FilesystemIterator( - $this->path . '/region/', + Path::join($this->path, 'region'), \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS ), '/\/r\.(-?\d+)\.(-?\d+)\.' . static::getRegionFileExtension() . '$/', diff --git a/src/world/format/io/region/WritableRegionWorldProvider.php b/src/world/format/io/region/WritableRegionWorldProvider.php index 156caa3e61..ed1b9eba77 100644 --- a/src/world/format/io/region/WritableRegionWorldProvider.php +++ b/src/world/format/io/region/WritableRegionWorldProvider.php @@ -27,6 +27,7 @@ use pocketmine\world\format\Chunk; use pocketmine\world\format\io\data\JavaWorldData; use pocketmine\world\format\io\WritableWorldProvider; use pocketmine\world\WorldCreationOptions; +use Webmozart\PathUtil\Path; use function file_exists; use function mkdir; @@ -42,8 +43,9 @@ abstract class WritableRegionWorldProvider extends RegionWorldProvider implement mkdir($path, 0777, true); } - if(!file_exists($path . "/region")){ - mkdir($path . "/region", 0777); + $regionPath = Path::join($path, "region"); + if(!file_exists($regionPath)){ + mkdir($regionPath, 0777); } JavaWorldData::generate($path, $name, $options, static::getPcWorldFormatVersion()); diff --git a/tests/phpunit/world/format/io/region/RegionLoaderTest.php b/tests/phpunit/world/format/io/region/RegionLoaderTest.php index 0de5babc1a..7bb72b5d6d 100644 --- a/tests/phpunit/world/format/io/region/RegionLoaderTest.php +++ b/tests/phpunit/world/format/io/region/RegionLoaderTest.php @@ -25,6 +25,7 @@ namespace pocketmine\world\format\io\region; use PHPUnit\Framework\TestCase; use pocketmine\world\format\ChunkException; +use Webmozart\PathUtil\Path; use function bin2hex; use function clearstatcache; use function file_exists; @@ -32,7 +33,6 @@ use function random_bytes; use function str_repeat; use function sys_get_temp_dir; use function unlink; -use const DIRECTORY_SEPARATOR; class RegionLoaderTest extends TestCase{ @@ -42,7 +42,7 @@ class RegionLoaderTest extends TestCase{ private $region; public function setUp() : void{ - $this->regionPath = sys_get_temp_dir() . '/test.testregion'; + $this->regionPath = Path::join(sys_get_temp_dir(), 'test.testregion'); if(file_exists($this->regionPath)){ unlink($this->regionPath); } @@ -140,7 +140,7 @@ class RegionLoaderTest extends TestCase{ clearstatcache(); do{ - $randfile = sys_get_temp_dir() . DIRECTORY_SEPARATOR . bin2hex(random_bytes(6)) . ".mca"; + $randfile = Path::join(sys_get_temp_dir(), bin2hex(random_bytes(6)) . ".mca"); }while(file_exists($randfile)); $this->expectException(\RuntimeException::class); RegionLoader::loadExisting($randfile); From 7ba573db7758f3a0229c2453fb631aac5a642d1e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 29 Jun 2021 19:52:52 +0100 Subject: [PATCH 2582/3224] Added API method Item::canStackWith() --- changelogs/4.0-snapshot.md | 1 + src/crafting/CraftingManager.php | 2 +- src/inventory/InventoryHelpersTrait.php | 4 ++-- src/inventory/transaction/CraftingTransaction.php | 2 +- src/inventory/transaction/InventoryTransaction.php | 2 +- src/item/Item.php | 7 +++++++ 6 files changed, 13 insertions(+), 5 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 035a3716ee..29d3bb32a7 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -660,6 +660,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `WritableBookPage` - The following API methods have been added: - `Armor->getArmorSlot()` + - `Item->canStackWith()`: returns whether the two items could be contained in the same inventory slot, ignoring count and stack size limits - `Potion->getType()`: returns a `PotionType` enum object containing information such as the applied effects - `ProjectileItem->createEntity()`: returns a new instance of the projectile entity that will be thrown - The following classes have been removed: diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index 50e1cc89a6..c05dfc5e4d 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -82,7 +82,7 @@ class CraftingManager{ foreach($items as $i => $item){ foreach($result as $otherItem){ - if($item->equals($otherItem)){ + if($item->canStackWith($otherItem)){ $otherItem->setCount($otherItem->getCount() + $item->getCount()); continue 2; } diff --git a/src/inventory/InventoryHelpersTrait.php b/src/inventory/InventoryHelpersTrait.php index 00bec34c70..1d6de457bc 100644 --- a/src/inventory/InventoryHelpersTrait.php +++ b/src/inventory/InventoryHelpersTrait.php @@ -118,7 +118,7 @@ trait InventoryHelpersTrait{ $count = $item->getCount(); for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ $slot = $this->getItem($i); - if($item->equals($slot)){ + if($item->canStackWith($slot)){ if(($diff = min($slot->getMaxStackSize(), $item->getMaxStackSize()) - $slot->getCount()) > 0){ $count -= $diff; } @@ -166,7 +166,7 @@ trait InventoryHelpersTrait{ $emptySlots[] = $i; } - if($slot->equals($item) and $item->getCount() < $item->getMaxStackSize()){ + if($slot->canStackWith($item) and $item->getCount() < $item->getMaxStackSize()){ $amount = min($item->getMaxStackSize() - $item->getCount(), $slot->getCount(), $this->getMaxStackSize()); if($amount > 0){ $slot->setCount($slot->getCount() - $amount); diff --git a/src/inventory/transaction/CraftingTransaction.php b/src/inventory/transaction/CraftingTransaction.php index d361b287c9..0d13ccbed4 100644 --- a/src/inventory/transaction/CraftingTransaction.php +++ b/src/inventory/transaction/CraftingTransaction.php @@ -84,7 +84,7 @@ class CraftingTransaction extends InventoryTransaction{ $recipeItem = array_pop($recipeItems); $needCount = $recipeItem->getCount(); foreach($recipeItems as $i => $otherRecipeItem){ - if($otherRecipeItem->equals($recipeItem)){ //make sure they have the same wildcards set + if($otherRecipeItem->canStackWith($recipeItem)){ //make sure they have the same wildcards set $needCount += $otherRecipeItem->getCount(); unset($recipeItems[$i]); } diff --git a/src/inventory/transaction/InventoryTransaction.php b/src/inventory/transaction/InventoryTransaction.php index 9b089126b2..d79b07cd1c 100644 --- a/src/inventory/transaction/InventoryTransaction.php +++ b/src/inventory/transaction/InventoryTransaction.php @@ -158,7 +158,7 @@ class InventoryTransaction{ foreach($needItems as $i => $needItem){ foreach($haveItems as $j => $haveItem){ - if($needItem->equals($haveItem)){ + if($needItem->canStackWith($haveItem)){ $amount = min($needItem->getCount(), $haveItem->getCount()); $needItem->setCount($needItem->getCount() - $amount); $haveItem->setCount($haveItem->getCount() - $amount); diff --git a/src/item/Item.php b/src/item/Item.php index afa34d8c82..bef3adb868 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -566,6 +566,13 @@ class Item implements \JsonSerializable{ (!$checkCompound or $this->getNamedTag()->equals($item->getNamedTag())); } + /** + * Returns whether this item could stack with the given item (ignoring stack size and count). + */ + final public function canStackWith(Item $other) : bool{ + return $this->equals($other, true, true); + } + /** * Returns whether the specified item stack has the same ID, damage, NBT and count as this item stack. */ From 1170c8fe1302a7429c1db8e530df2740cd6ef3b1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 29 Jun 2021 19:55:43 +0100 Subject: [PATCH 2583/3224] EnumTrait: override __clone, __sleep, __wakeup to prevent duplication --- src/utils/EnumTrait.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/utils/EnumTrait.php b/src/utils/EnumTrait.php index e464442fe7..689c718287 100644 --- a/src/utils/EnumTrait.php +++ b/src/utils/EnumTrait.php @@ -97,4 +97,16 @@ trait EnumTrait{ public function equals(self $other) : bool{ return $this->enumName === $other->enumName; } + + public function __clone(){ + throw new \LogicException("Enum members cannot be cloned"); + } + + public function __sleep(){ + throw new \LogicException("Enum members cannot be serialized"); + } + + public function __wakeup(){ + throw new \LogicException("Enum members cannot be unserialized"); + } } From 83332024dfa5b4dbba7a68ff782ccd551a8f4f2b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 29 Jun 2021 20:07:39 +0100 Subject: [PATCH 2584/3224] TranslationContainer: remove __toString() it doesn't make any sense to use TranslationContainer in this way. --- src/lang/TranslationContainer.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/lang/TranslationContainer.php b/src/lang/TranslationContainer.php index a16095d323..3e2905f6f9 100644 --- a/src/lang/TranslationContainer.php +++ b/src/lang/TranslationContainer.php @@ -58,8 +58,4 @@ final class TranslationContainer{ public function getParameter(int $i) : ?string{ return $this->params[$i] ?? null; } - - public function __toString() : string{ - return $this->getText(); - } } From f02817bcd332b1823824639039655ad358381c1d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 29 Jun 2021 20:14:11 +0100 Subject: [PATCH 2585/3224] Player: fixed toString() on TranslationContainer exposed by previous commit this code looks smelly... --- src/player/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index 2c4227a172..281405a56c 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -803,7 +803,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ ]) ); $ev->call(); - if(strlen(trim((string) $ev->getJoinMessage())) > 0){ + if($ev->getJoinMessage() !== ""){ $this->server->broadcastMessage($ev->getJoinMessage()); } From 94e16f416de31b79c93bdc2c6cf84b22d25ba63f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 29 Jun 2021 22:46:04 +0100 Subject: [PATCH 2586/3224] Added KnownTranslationKeys (generated) and start using it --- build/generate-known-translation-keys.php | 93 +++++ phpstan.neon.dist | 1 + src/Server.php | 61 +-- src/block/Bed.php | 7 +- src/command/Command.php | 7 +- src/command/SimpleCommandMap.php | 9 +- src/command/defaults/BanCommand.php | 7 +- src/command/defaults/BanIpCommand.php | 11 +- src/command/defaults/BanListCommand.php | 9 +- src/command/defaults/ClearCommand.php | 21 +- .../defaults/DefaultGamemodeCommand.php | 7 +- src/command/defaults/DeopCommand.php | 7 +- src/command/defaults/DifficultyCommand.php | 7 +- src/command/defaults/EffectCommand.php | 19 +- src/command/defaults/EnchantCommand.php | 13 +- src/command/defaults/GamemodeCommand.php | 13 +- .../defaults/GarbageCollectorCommand.php | 5 +- src/command/defaults/GiveCommand.php | 5 +- src/command/defaults/HelpCommand.php | 7 +- src/command/defaults/KickCommand.php | 11 +- src/command/defaults/KillCommand.php | 15 +- src/command/defaults/ListCommand.php | 7 +- src/command/defaults/MeCommand.php | 7 +- src/command/defaults/OpCommand.php | 7 +- src/command/defaults/PardonCommand.php | 7 +- src/command/defaults/PardonIpCommand.php | 9 +- src/command/defaults/ParticleCommand.php | 9 +- src/command/defaults/PluginsCommand.php | 7 +- src/command/defaults/SaveCommand.php | 9 +- src/command/defaults/SaveOffCommand.php | 7 +- src/command/defaults/SaveOnCommand.php | 7 +- src/command/defaults/SayCommand.php | 7 +- src/command/defaults/SeedCommand.php | 7 +- src/command/defaults/SetWorldSpawnCommand.php | 7 +- src/command/defaults/SpawnpointCommand.php | 11 +- src/command/defaults/StatusCommand.php | 5 +- src/command/defaults/StopCommand.php | 7 +- src/command/defaults/TeleportCommand.php | 9 +- src/command/defaults/TellCommand.php | 15 +- src/command/defaults/TimeCommand.php | 21 +- src/command/defaults/TimingsCommand.php | 21 +- src/command/defaults/TitleCommand.php | 9 +- .../defaults/TransferServerCommand.php | 5 +- src/command/defaults/VersionCommand.php | 9 +- src/command/defaults/WhitelistCommand.php | 23 +- src/lang/KnownTranslationKeys.php | 369 ++++++++++++++++++ src/lang/Language.php | 2 +- src/network/mcpe/NetworkSession.php | 3 +- src/network/mcpe/auth/ProcessLoginTask.php | 11 +- .../mcpe/handler/LoginPacketHandler.php | 3 +- src/network/query/QueryHandler.php | 3 +- src/player/Player.php | 3 +- src/plugin/PluginBase.php | 5 +- src/plugin/PluginManager.php | 41 +- src/wizard/SetupWizard.php | 61 +-- src/world/World.php | 3 +- src/world/WorldManager.php | 17 +- 57 files changed, 802 insertions(+), 286 deletions(-) create mode 100644 build/generate-known-translation-keys.php create mode 100644 src/lang/KnownTranslationKeys.php diff --git a/build/generate-known-translation-keys.php b/build/generate-known-translation-keys.php new file mode 100644 index 0000000000..2018db3ffe --- /dev/null +++ b/build/generate-known-translation-keys.php @@ -0,0 +1,93 @@ + $v){ + $perms[] = $k; +} + +sort($perms, SORT_STRING); +foreach($perms as $perm){ + echo "\tpublic const "; + echo constantify($perm); + echo " = \"" . $perm . "\";\n"; +} + +echo "}\n"; + +file_put_contents(dirname(__DIR__) . '/src/lang/KnownTranslationKeys.php', ob_get_clean()); + +echo "Done.\n"; diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 06f5907b98..4e1631d93e 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -31,6 +31,7 @@ parameters: - src/PocketMine.php - build/make-release.php - build/server-phar.php + - build/generate-known-translation-keys.php paths: - src - tests/phpstan/rules diff --git a/src/Server.php b/src/Server.php index 5b355f8b40..8d2e83c187 100644 --- a/src/Server.php +++ b/src/Server.php @@ -43,6 +43,7 @@ use pocketmine\event\player\PlayerDataSaveEvent; use pocketmine\event\server\CommandEvent; use pocketmine\event\server\DataPacketSendEvent; use pocketmine\event\server\QueryRegenerateEvent; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\Language; use pocketmine\lang\LanguageNotFoundException; use pocketmine\lang\TranslationContainer; @@ -529,7 +530,7 @@ class Server{ private function handleCorruptedPlayerData(string $name) : void{ $path = $this->getPlayerDataPath($name); rename($path, $path . '.bak'); - $this->logger->error($this->getLanguage()->translateString("pocketmine.data.playerCorrupted", [$name])); + $this->logger->error($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_DATA_PLAYERCORRUPTED, [$name])); } public function getOfflinePlayerData(string $name) : ?CompoundTag{ @@ -575,7 +576,7 @@ class Server{ try{ file_put_contents($this->getPlayerDataPath($name), zlib_encode($nbt->write(new TreeRoot($ev->getSaveData())), ZLIB_ENCODING_GZIP)); }catch(\ErrorException $e){ - $this->logger->critical($this->getLanguage()->translateString("pocketmine.data.saveError", [$name, $e->getMessage()])); + $this->logger->critical($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_DATA_SAVEERROR, [$name, $e->getMessage()])); $this->logger->logException($e); } }); @@ -879,30 +880,30 @@ class Server{ } } - $this->logger->info($this->getLanguage()->translateString("language.selected", [$this->getLanguage()->getName(), $this->getLanguage()->getLang()])); + $this->logger->info($this->getLanguage()->translateString(KnownTranslationKeys::LANGUAGE_SELECTED, [$this->getLanguage()->getName(), $this->getLanguage()->getLang()])); if(VersionInfo::IS_DEVELOPMENT_BUILD){ if(!$this->configGroup->getPropertyBool("settings.enable-dev-builds", false)){ - $this->logger->emergency($this->language->translateString("pocketmine.server.devBuild.error1", [VersionInfo::NAME])); - $this->logger->emergency($this->language->translateString("pocketmine.server.devBuild.error2")); - $this->logger->emergency($this->language->translateString("pocketmine.server.devBuild.error3")); - $this->logger->emergency($this->language->translateString("pocketmine.server.devBuild.error4", ["settings.enable-dev-builds"])); - $this->logger->emergency($this->language->translateString("pocketmine.server.devBuild.error5", ["https://github.com/pmmp/PocketMine-MP/releases"])); + $this->logger->emergency($this->language->translateString(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR1, [VersionInfo::NAME])); + $this->logger->emergency($this->language->translateString(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR2)); + $this->logger->emergency($this->language->translateString(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR3)); + $this->logger->emergency($this->language->translateString(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR4, ["settings.enable-dev-builds"])); + $this->logger->emergency($this->language->translateString(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR5, ["https://github.com/pmmp/PocketMine-MP/releases"])); $this->forceShutdown(); return; } $this->logger->warning(str_repeat("-", 40)); - $this->logger->warning($this->language->translateString("pocketmine.server.devBuild.warning1", [VersionInfo::NAME])); - $this->logger->warning($this->language->translateString("pocketmine.server.devBuild.warning2")); - $this->logger->warning($this->language->translateString("pocketmine.server.devBuild.warning3")); + $this->logger->warning($this->language->translateString(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_WARNING1, [VersionInfo::NAME])); + $this->logger->warning($this->language->translateString(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_WARNING2)); + $this->logger->warning($this->language->translateString(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_WARNING3)); $this->logger->warning(str_repeat("-", 40)); } $this->memoryManager = new MemoryManager($this); - $this->logger->info($this->getLanguage()->translateString("pocketmine.server.start", [TextFormat::AQUA . $this->getVersion() . TextFormat::RESET])); + $this->logger->info($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_START, [TextFormat::AQUA . $this->getVersion() . TextFormat::RESET])); if(($poolSize = $this->configGroup->getPropertyString("settings.async-workers", "auto")) === "auto"){ $poolSize = 2; @@ -955,11 +956,11 @@ class Server{ $this->onlineMode = $this->configGroup->getConfigBool("xbox-auth", true); if($this->onlineMode){ - $this->logger->info($this->getLanguage()->translateString("pocketmine.server.auth.enabled")); + $this->logger->info($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_AUTH_ENABLED)); }else{ - $this->logger->warning($this->getLanguage()->translateString("pocketmine.server.auth.disabled")); - $this->logger->warning($this->getLanguage()->translateString("pocketmine.server.authWarning")); - $this->logger->warning($this->getLanguage()->translateString("pocketmine.server.authProperty.disabled")); + $this->logger->warning($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_AUTH_DISABLED)); + $this->logger->warning($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_AUTHWARNING)); + $this->logger->warning($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_AUTHPROPERTY_DISABLED)); } if($this->configGroup->getConfigBool("hardcore", false) and $this->getDifficulty() < World::DIFFICULTY_HARD){ @@ -976,11 +977,11 @@ class Server{ $this->network = new Network($this->logger); $this->network->setName($this->getMotd()); - $this->logger->info($this->getLanguage()->translateString("pocketmine.server.info", [ + $this->logger->info($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_INFO, [ $this->getName(), (VersionInfo::IS_DEVELOPMENT_BUILD ? TextFormat::YELLOW : "") . $this->getPocketMineVersion() . TextFormat::RESET ])); - $this->logger->info($this->getLanguage()->translateString("pocketmine.server.license", [$this->getName()])); + $this->logger->info($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_LICENSE, [$this->getName()])); Timings::init(); TimingsHandler::setEnabled($this->configGroup->getPropertyBool("settings.enable-profiling", false)); @@ -1017,7 +1018,7 @@ class Server{ ){ $providerManager->setDefault($format); }elseif($formatName !== ""){ - $this->logger->warning($this->language->translateString("pocketmine.level.badDefaultFormat", [$formatName])); + $this->logger->warning($this->language->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_BADDEFAULTFORMAT, [$formatName])); } $this->worldManager = new WorldManager($this, Path::join($this->dataPath, "worlds"), $providerManager); @@ -1087,7 +1088,7 @@ class Server{ $world = $this->worldManager->getWorldByName($default); if($world === null){ - $this->getLogger()->emergency($this->getLanguage()->translateString("pocketmine.level.defaultError")); + $this->getLogger()->emergency($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_DEFAULTERROR)); $this->forceShutdown(); return; @@ -1103,7 +1104,7 @@ class Server{ //if it's not registered we need to make sure Query still works $this->network->registerInterface(new DedicatedQueryNetworkInterface($this->getIp(), $this->getPort(), new \PrefixedLogger($this->logger, "Dedicated Query Interface"))); } - $this->logger->info($this->getLanguage()->translateString("pocketmine.server.networkStart", [$this->getIp(), $this->getPort()])); + $this->logger->info($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_NETWORKSTART, [$this->getIp(), $this->getPort()])); if($useQuery){ $this->network->registerRawPacketHandler(new QueryHandler($this)); @@ -1124,9 +1125,9 @@ class Server{ $this->configGroup->save(); - $this->logger->info($this->getLanguage()->translateString("pocketmine.server.defaultGameMode", [$this->getGamemode()->getTranslationKey()])); - $this->logger->info($this->getLanguage()->translateString("pocketmine.server.donate", [TextFormat::AQUA . "https://patreon.com/pocketminemp" . TextFormat::RESET])); - $this->logger->info($this->getLanguage()->translateString("pocketmine.server.startFinished", [round(microtime(true) - $this->startTime, 3)])); + $this->logger->info($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_DEFAULTGAMEMODE, [$this->getGamemode()->getTranslationKey()])); + $this->logger->info($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_DONATE, [TextFormat::AQUA . "https://patreon.com/pocketminemp" . TextFormat::RESET])); + $this->logger->info($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_STARTFINISHED, [round(microtime(true) - $this->startTime, 3)])); //TODO: move console parts to a separate component $consoleSender = new ConsoleCommandSender($this, $this->language); @@ -1365,7 +1366,7 @@ class Server{ return true; } - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.notFound")); + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_NOTFOUND)); return false; } @@ -1501,10 +1502,10 @@ class Server{ ini_set("error_reporting", '0'); ini_set("memory_limit", '-1'); //Fix error dump not dumped on memory problems try{ - $this->logger->emergency($this->getLanguage()->translateString("pocketmine.crash.create")); + $this->logger->emergency($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_CRASH_CREATE)); $dump = new CrashDump($this); - $this->logger->emergency($this->getLanguage()->translateString("pocketmine.crash.submit", [$dump->getPath()])); + $this->logger->emergency($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_CRASH_SUBMIT, [$dump->getPath()])); if($this->configGroup->getPropertyBool("auto-report.enabled", true)){ $report = true; @@ -1548,7 +1549,7 @@ class Server{ if(isset($data->crashId) and isset($data->crashUrl)){ $reportId = $data->crashId; $reportUrl = $data->crashUrl; - $this->logger->emergency($this->getLanguage()->translateString("pocketmine.crash.archive", [$reportUrl, $reportId])); + $this->logger->emergency($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_CRASH_ARCHIVE, [$reportUrl, $reportId])); }elseif(isset($data->error)){ $this->logger->emergency("Automatic crash report submission failed: $data->error"); } @@ -1560,7 +1561,7 @@ class Server{ }catch(\Throwable $e){ $this->logger->logException($e); try{ - $this->logger->critical($this->getLanguage()->translateString("pocketmine.crash.error", [$e->getMessage()])); + $this->logger->critical($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_CRASH_ERROR, [$e->getMessage()])); }catch(\Throwable $e){} } @@ -1729,7 +1730,7 @@ class Server{ } if($this->getTicksPerSecondAverage() < 12){ - $this->logger->warning($this->getLanguage()->translateString("pocketmine.server.tickOverload")); + $this->logger->warning($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_TICKOVERLOAD)); } } diff --git a/src/block/Bed.php b/src/block/Bed.php index 1a7482990f..c8c40a831e 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -31,6 +31,7 @@ use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\item\Bed as ItemBed; use pocketmine\item\Item; use pocketmine\item\ItemFactory; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; @@ -135,7 +136,7 @@ class Bed extends Transparent{ return true; }elseif($playerPos->distanceSquared($this->pos) > 4 and $playerPos->distanceSquared($other->pos) > 4){ - $player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.tooFar")); + $player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%" . KnownTranslationKeys::TILE_BED_TOOFAR)); return true; } @@ -144,7 +145,7 @@ class Bed extends Transparent{ $isNight = ($time >= World::TIME_NIGHT and $time < World::TIME_SUNRISE); if(!$isNight){ - $player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.noSleep")); + $player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%" . KnownTranslationKeys::TILE_BED_NOSLEEP)); return true; } @@ -152,7 +153,7 @@ class Bed extends Transparent{ $b = ($this->isHeadPart() ? $this : $other); if($b->isOccupied()){ - $player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.occupied")); + $player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%" . KnownTranslationKeys::TILE_BED_OCCUPIED)); return true; } diff --git a/src/command/Command.php b/src/command/Command.php index d779721018..341883fddf 100644 --- a/src/command/Command.php +++ b/src/command/Command.php @@ -28,6 +28,7 @@ namespace pocketmine\command; use pocketmine\command\utils\CommandException; use pocketmine\console\ConsoleCommandSender; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\PermissionManager; use pocketmine\Server; @@ -116,7 +117,7 @@ abstract class Command{ } if($this->permissionMessage === null){ - $target->sendMessage($target->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + $target->sendMessage($target->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); }elseif($this->permissionMessage !== ""){ $target->sendMessage(str_replace("", $this->permission, $this->permissionMessage)); } @@ -239,8 +240,8 @@ abstract class Command{ $result = new TranslationContainer($formatted, $message->getParameters()); $colored = new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . $formatted, $message->getParameters()); }else{ - $result = new TranslationContainer("chat.type.admin", [$source->getName(), $message]); - $colored = new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . "%chat.type.admin", [$source->getName(), $message]); + $result = new TranslationContainer(KnownTranslationKeys::CHAT_TYPE_ADMIN, [$source->getName(), $message]); + $colored = new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . "%" . KnownTranslationKeys::CHAT_TYPE_ADMIN, [$source->getName(), $message]); } if($sendToSource and !($source instanceof ConsoleCommandSender)){ diff --git a/src/command/SimpleCommandMap.php b/src/command/SimpleCommandMap.php index 8d124d748e..2feb20a5b8 100644 --- a/src/command/SimpleCommandMap.php +++ b/src/command/SimpleCommandMap.php @@ -65,6 +65,7 @@ use pocketmine\command\defaults\VanillaCommand; use pocketmine\command\defaults\VersionCommand; use pocketmine\command\defaults\WhitelistCommand; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\Server; use function array_shift; use function count; @@ -245,7 +246,7 @@ class SimpleCommandMap implements CommandMap{ try{ $target->execute($sender, $sentCommandLabel, $args); }catch(InvalidCommandSyntaxException $e){ - $sender->sendMessage($sender->getLanguage()->translateString("commands.generic.usage", [$target->getUsage()])); + $sender->sendMessage($sender->getLanguage()->translateString(KnownTranslationKeys::COMMANDS_GENERIC_USAGE, [$target->getUsage()])); }finally{ $target->timings->stopTiming(); } @@ -277,7 +278,7 @@ class SimpleCommandMap implements CommandMap{ foreach($values as $alias => $commandStrings){ if(strpos($alias, ":") !== false){ - $this->server->getLogger()->warning($this->server->getLanguage()->translateString("pocketmine.command.alias.illegal", [$alias])); + $this->server->getLogger()->warning($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_COMMAND_ALIAS_ILLEGAL, [$alias])); continue; } @@ -300,12 +301,12 @@ class SimpleCommandMap implements CommandMap{ } if(count($recursive) > 0){ - $this->server->getLogger()->warning($this->server->getLanguage()->translateString("pocketmine.command.alias.recursive", [$alias, implode(", ", $recursive)])); + $this->server->getLogger()->warning($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_COMMAND_ALIAS_RECURSIVE, [$alias, implode(", ", $recursive)])); continue; } if(count($bad) > 0){ - $this->server->getLogger()->warning($this->server->getLanguage()->translateString("pocketmine.command.alias.notFound", [$alias, implode(", ", $bad)])); + $this->server->getLogger()->warning($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_COMMAND_ALIAS_NOTFOUND, [$alias, implode(", ", $bad)])); continue; } diff --git a/src/command/defaults/BanCommand.php b/src/command/defaults/BanCommand.php index 98616f9ea9..14f3416205 100644 --- a/src/command/defaults/BanCommand.php +++ b/src/command/defaults/BanCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -38,8 +39,8 @@ class BanCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.ban.player.description", - "%commands.ban.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_BAN_PLAYER_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_BAN_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_BAN_PLAYER); } @@ -62,7 +63,7 @@ class BanCommand extends VanillaCommand{ $player->kick($reason !== "" ? "Banned by admin. Reason: " . $reason : "Banned by admin."); } - Command::broadcastCommandMessage($sender, new TranslationContainer("%commands.ban.success", [$player !== null ? $player->getName() : $name])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_BAN_SUCCESS, [$player !== null ? $player->getName() : $name])); return true; } diff --git a/src/command/defaults/BanIpCommand.php b/src/command/defaults/BanIpCommand.php index f263d47459..89d10e7f4a 100644 --- a/src/command/defaults/BanIpCommand.php +++ b/src/command/defaults/BanIpCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -39,8 +40,8 @@ class BanIpCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.ban.ip.description", - "%commands.banip.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_BAN_IP_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_BANIP_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_BAN_IP); } @@ -60,15 +61,15 @@ class BanIpCommand extends VanillaCommand{ if(preg_match("/^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$/", $value)){ $this->processIPBan($value, $sender, $reason); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.banip.success", [$value])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_BANIP_SUCCESS, [$value])); }else{ if(($player = $sender->getServer()->getPlayerByPrefix($value)) instanceof Player){ $ip = $player->getNetworkSession()->getIp(); $this->processIPBan($ip, $sender, $reason); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.banip.success.players", [$ip, $player->getName()])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_BANIP_SUCCESS_PLAYERS, [$ip, $player->getName()])); }else{ - $sender->sendMessage(new TranslationContainer("commands.banip.invalid")); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_BANIP_INVALID)); return false; } diff --git a/src/command/defaults/BanListCommand.php b/src/command/defaults/BanListCommand.php index ab33bf8aee..366a479aef 100644 --- a/src/command/defaults/BanListCommand.php +++ b/src/command/defaults/BanListCommand.php @@ -25,6 +25,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\BanEntry; use pocketmine\permission\DefaultPermissionNames; @@ -40,8 +41,8 @@ class BanListCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.banlist.description", - "%commands.banlist.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_BANLIST_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_BANLIST_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_BAN_LIST); } @@ -72,9 +73,9 @@ class BanListCommand extends VanillaCommand{ $message = implode(", ", $list); if($args[0] === "ips"){ - $sender->sendMessage(new TranslationContainer("commands.banlist.ips", [count($list)])); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_BANLIST_IPS, [count($list)])); }else{ - $sender->sendMessage(new TranslationContainer("commands.banlist.players", [count($list)])); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_BANLIST_PLAYERS, [count($list)])); } $sender->sendMessage($message); diff --git a/src/command/defaults/ClearCommand.php b/src/command/defaults/ClearCommand.php index 03c53c4e6e..eded7e8faf 100644 --- a/src/command/defaults/ClearCommand.php +++ b/src/command/defaults/ClearCommand.php @@ -28,6 +28,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\LegacyStringToItemParser; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -41,8 +42,8 @@ class ClearCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.clear.description", - "%pocketmine.command.clear.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_CLEAR_DESCRIPTION, + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_CLEAR_USAGE ); $this->setPermission(implode(";", [DefaultPermissionNames::COMMAND_CLEAR_SELF, DefaultPermissionNames::COMMAND_CLEAR_OTHER])); } @@ -60,16 +61,16 @@ class ClearCommand extends VanillaCommand{ if(isset($args[0])){ $target = $sender->getServer()->getPlayerByPrefix($args[0]); if($target === null){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); return true; } if($target !== $sender && !$sender->hasPermission(DefaultPermissionNames::COMMAND_CLEAR_OTHER)){ - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); return true; } }elseif($sender instanceof Player){ if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_CLEAR_SELF)){ - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); return true; } @@ -89,7 +90,7 @@ class ClearCommand extends VanillaCommand{ } }catch(InvalidArgumentException $e){ //vanilla checks this at argument parsing layer, can't come up with a better alternative - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.give.item.notFound", [$args[1]])); + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GIVE_ITEM_NOTFOUND, [$args[1]])); return true; } } @@ -103,9 +104,9 @@ class ClearCommand extends VanillaCommand{ } if($count > 0){ - $sender->sendMessage(new TranslationContainer("%commands.clear.testing", [$target->getName(), $count])); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_CLEAR_TESTING, [$target->getName(), $count])); }else{ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.clear.failure.no.items", [$target->getName()])); + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_CLEAR_FAILURE_NO_ITEMS, [$target->getName()])); } return true; @@ -165,9 +166,9 @@ class ClearCommand extends VanillaCommand{ } if($cleared > 0){ - Command::broadcastCommandMessage($sender, new TranslationContainer("%commands.clear.success", [$target->getName(), $cleared])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_CLEAR_SUCCESS, [$target->getName(), $cleared])); }else{ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.clear.failure.no.items", [$target->getName()])); + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_CLEAR_FAILURE_NO_ITEMS, [$target->getName()])); } return true; diff --git a/src/command/defaults/DefaultGamemodeCommand.php b/src/command/defaults/DefaultGamemodeCommand.php index 7fc9651711..88648edd0d 100644 --- a/src/command/defaults/DefaultGamemodeCommand.php +++ b/src/command/defaults/DefaultGamemodeCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\data\java\GameModeIdMap; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\GameMode; @@ -36,8 +37,8 @@ class DefaultGamemodeCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.defaultgamemode.description", - "%commands.defaultgamemode.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_DEFAULTGAMEMODE_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_DEFAULTGAMEMODE_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_DEFAULTGAMEMODE); } @@ -58,7 +59,7 @@ class DefaultGamemodeCommand extends VanillaCommand{ } $sender->getServer()->getConfigGroup()->setConfigInt("gamemode", GameModeIdMap::getInstance()->toId($gameMode)); - $sender->sendMessage(new TranslationContainer("commands.defaultgamemode.success", [$gameMode->getTranslationKey()])); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_DEFAULTGAMEMODE_SUCCESS, [$gameMode->getTranslationKey()])); return true; } } diff --git a/src/command/defaults/DeopCommand.php b/src/command/defaults/DeopCommand.php index 5a4a488cfa..6df6520cd2 100644 --- a/src/command/defaults/DeopCommand.php +++ b/src/command/defaults/DeopCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -38,8 +39,8 @@ class DeopCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.deop.description", - "%commands.deop.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_DEOP_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_DEOP_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_OP_TAKE); } @@ -62,7 +63,7 @@ class DeopCommand extends VanillaCommand{ if(($player = $sender->getServer()->getPlayerExact($name)) !== null){ $player->sendMessage(TextFormat::GRAY . "You are no longer op!"); } - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.deop.success", [$name])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_DEOP_SUCCESS, [$name])); return true; } diff --git a/src/command/defaults/DifficultyCommand.php b/src/command/defaults/DifficultyCommand.php index 56951b02e3..bd2011359a 100644 --- a/src/command/defaults/DifficultyCommand.php +++ b/src/command/defaults/DifficultyCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\world\World; @@ -36,8 +37,8 @@ class DifficultyCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.difficulty.description", - "%commands.difficulty.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_DIFFICULTY_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_DIFFICULTY_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_DIFFICULTY); } @@ -65,7 +66,7 @@ class DifficultyCommand extends VanillaCommand{ $world->setDifficulty($difficulty); } - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.difficulty.success", [$difficulty])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_DIFFICULTY_SUCCESS, [$difficulty])); }else{ throw new InvalidCommandSyntaxException(); } diff --git a/src/command/defaults/EffectCommand.php b/src/command/defaults/EffectCommand.php index d035aba7db..db37acbe8f 100644 --- a/src/command/defaults/EffectCommand.php +++ b/src/command/defaults/EffectCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\VanillaEffects; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\Limits; @@ -39,8 +40,8 @@ class EffectCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.effect.description", - "%commands.effect.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_EFFECT_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_EFFECT_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_EFFECT); } @@ -57,7 +58,7 @@ class EffectCommand extends VanillaCommand{ $player = $sender->getServer()->getPlayerByPrefix($args[0]); if($player === null){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); return true; } $effectManager = $player->getEffects(); @@ -65,14 +66,14 @@ class EffectCommand extends VanillaCommand{ if(strtolower($args[1]) === "clear"){ $effectManager->clear(); - $sender->sendMessage(new TranslationContainer("commands.effect.success.removed.all", [$player->getDisplayName()])); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_SUCCESS_REMOVED_ALL, [$player->getDisplayName()])); return true; } try{ $effect = VanillaEffects::fromString($args[1]); }catch(\InvalidArgumentException $e){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.effect.notFound", [$args[1]])); + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_EFFECT_NOTFOUND, [$args[1]])); return true; } @@ -105,19 +106,19 @@ class EffectCommand extends VanillaCommand{ if($duration === 0){ if(!$effectManager->has($effect)){ if(count($effectManager->all()) === 0){ - $sender->sendMessage(new TranslationContainer("commands.effect.failure.notActive.all", [$player->getDisplayName()])); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_FAILURE_NOTACTIVE_ALL, [$player->getDisplayName()])); }else{ - $sender->sendMessage(new TranslationContainer("commands.effect.failure.notActive", [$effect->getName(), $player->getDisplayName()])); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_FAILURE_NOTACTIVE, [$effect->getName(), $player->getDisplayName()])); } return true; } $effectManager->remove($effect); - $sender->sendMessage(new TranslationContainer("commands.effect.success.removed", [$effect->getName(), $player->getDisplayName()])); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_SUCCESS_REMOVED, [$effect->getName(), $player->getDisplayName()])); }else{ $instance = new EffectInstance($effect, $duration, $amplification, $visible); $effectManager->add($instance); - self::broadcastCommandMessage($sender, new TranslationContainer("%commands.effect.success", [$effect->getName(), $instance->getAmplifier(), $player->getDisplayName(), $instance->getDuration() / 20])); + self::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_SUCCESS, [$effect->getName(), $instance->getAmplifier(), $player->getDisplayName(), $instance->getDuration() / 20])); } return true; diff --git a/src/command/defaults/EnchantCommand.php b/src/command/defaults/EnchantCommand.php index 226c7729b9..a05b48d7f2 100644 --- a/src/command/defaults/EnchantCommand.php +++ b/src/command/defaults/EnchantCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\enchantment\EnchantmentInstance; use pocketmine\item\enchantment\VanillaEnchantments; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\TextFormat; @@ -37,8 +38,8 @@ class EnchantCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.enchant.description", - "%commands.enchant.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_ENCHANT_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_ENCHANT_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_ENCHANT); } @@ -55,21 +56,21 @@ class EnchantCommand extends VanillaCommand{ $player = $sender->getServer()->getPlayerByPrefix($args[0]); if($player === null){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); return true; } $item = $player->getInventory()->getItemInHand(); if($item->isNull()){ - $sender->sendMessage(new TranslationContainer("commands.enchant.noItem")); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_ENCHANT_NOITEM)); return true; } try{ $enchantment = VanillaEnchantments::fromString($args[1]); }catch(\InvalidArgumentException $e){ - $sender->sendMessage(new TranslationContainer("commands.enchant.notFound", [$args[1]])); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_ENCHANT_NOTFOUND, [$args[1]])); return true; } @@ -84,7 +85,7 @@ class EnchantCommand extends VanillaCommand{ $item->addEnchantment(new EnchantmentInstance($enchantment, $level)); $player->getInventory()->setItemInHand($item); - self::broadcastCommandMessage($sender, new TranslationContainer("%commands.enchant.success", [$player->getName()])); + self::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_ENCHANT_SUCCESS, [$player->getName()])); return true; } } diff --git a/src/command/defaults/GamemodeCommand.php b/src/command/defaults/GamemodeCommand.php index 8e71fe23bf..3b99fe22bb 100644 --- a/src/command/defaults/GamemodeCommand.php +++ b/src/command/defaults/GamemodeCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\GameMode; @@ -38,8 +39,8 @@ class GamemodeCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.gamemode.description", - "%commands.gamemode.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_GAMEMODE_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_GAMEMODE_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_GAMEMODE); } @@ -62,7 +63,7 @@ class GamemodeCommand extends VanillaCommand{ if(isset($args[1])){ $target = $sender->getServer()->getPlayerByPrefix($args[1]); if($target === null){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); return true; } @@ -77,10 +78,10 @@ class GamemodeCommand extends VanillaCommand{ $sender->sendMessage("Game mode change for " . $target->getName() . " failed!"); }else{ if($target === $sender){ - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.gamemode.success.self", [$gameMode->getTranslationKey()])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_GAMEMODE_SUCCESS_SELF, [$gameMode->getTranslationKey()])); }else{ - $target->sendMessage(new TranslationContainer("gameMode.changed", [$gameMode->getTranslationKey()])); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.gamemode.success.other", [$gameMode->getTranslationKey(), $target->getName()])); + $target->sendMessage(new TranslationContainer(KnownTranslationKeys::GAMEMODE_CHANGED, [$gameMode->getTranslationKey()])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_GAMEMODE_SUCCESS_OTHER, [$gameMode->getTranslationKey(), $target->getName()])); } } diff --git a/src/command/defaults/GarbageCollectorCommand.php b/src/command/defaults/GarbageCollectorCommand.php index 1614e9e901..8e11fb515b 100644 --- a/src/command/defaults/GarbageCollectorCommand.php +++ b/src/command/defaults/GarbageCollectorCommand.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\TextFormat; use function count; @@ -36,8 +37,8 @@ class GarbageCollectorCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.gc.description", - "%pocketmine.command.gc.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_GC_DESCRIPTION, + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_GC_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_GC); } diff --git a/src/command/defaults/GiveCommand.php b/src/command/defaults/GiveCommand.php index 3fd2085bdb..aa23475f91 100644 --- a/src/command/defaults/GiveCommand.php +++ b/src/command/defaults/GiveCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\LegacyStringToItemParser; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\nbt\JsonNbtParser; use pocketmine\nbt\NbtDataException; @@ -41,8 +42,8 @@ class GiveCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.give.description", - "%pocketmine.command.give.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_GIVE_DESCRIPTION, + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_GIVE_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_GIVE); } diff --git a/src/command/defaults/HelpCommand.php b/src/command/defaults/HelpCommand.php index ba7dda68e8..09c29c3c85 100644 --- a/src/command/defaults/HelpCommand.php +++ b/src/command/defaults/HelpCommand.php @@ -25,6 +25,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\TextFormat; @@ -45,8 +46,8 @@ class HelpCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.help.description", - "%commands.help.usage", + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_HELP_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_HELP_USAGE, ["?"] ); $this->setPermission(DefaultPermissionNames::COMMAND_HELP); @@ -87,7 +88,7 @@ class HelpCommand extends VanillaCommand{ if($pageNumber < 1){ $pageNumber = 1; } - $sender->sendMessage(new TranslationContainer("commands.help.header", [$pageNumber, count($commands)])); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_HELP_HEADER, [$pageNumber, count($commands)])); if(isset($commands[$pageNumber - 1])){ foreach($commands[$pageNumber - 1] as $command){ $sender->sendMessage(TextFormat::DARK_GREEN . "/" . $command->getName() . ": " . TextFormat::WHITE . $command->getDescription()); diff --git a/src/command/defaults/KickCommand.php b/src/command/defaults/KickCommand.php index 67bbcf9d1c..f30761fea7 100644 --- a/src/command/defaults/KickCommand.php +++ b/src/command/defaults/KickCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -40,8 +41,8 @@ class KickCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.kick.description", - "%commands.kick.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_KICK_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_KICK_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_KICK); } @@ -61,12 +62,12 @@ class KickCommand extends VanillaCommand{ if(($player = $sender->getServer()->getPlayerByPrefix($name)) instanceof Player){ $player->kick("Kicked by admin." . ($reason !== "" ? "Reason: " . $reason : "")); if($reason !== ""){ - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.kick.success.reason", [$player->getName(), $reason])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_KICK_SUCCESS_REASON, [$player->getName(), $reason])); }else{ - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.kick.success", [$player->getName()])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_KICK_SUCCESS, [$player->getName()])); } }else{ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); } return true; diff --git a/src/command/defaults/KillCommand.php b/src/command/defaults/KillCommand.php index b399f05917..d30ae3917e 100644 --- a/src/command/defaults/KillCommand.php +++ b/src/command/defaults/KillCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\event\entity\EntityDamageEvent; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -39,8 +40,8 @@ class KillCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.kill.description", - "%pocketmine.command.kill.usage", + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_KILL_DESCRIPTION, + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_KILL_USAGE, ["suicide"] ); $this->setPermission(implode(";", [DefaultPermissionNames::COMMAND_KILL_SELF, DefaultPermissionNames::COMMAND_KILL_OTHER])); @@ -57,7 +58,7 @@ class KillCommand extends VanillaCommand{ if(count($args) === 1){ if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_KILL_OTHER)){ - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); return true; } @@ -66,9 +67,9 @@ class KillCommand extends VanillaCommand{ if($player instanceof Player){ $player->attack(new EntityDamageEvent($player, EntityDamageEvent::CAUSE_SUICIDE, 1000)); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.kill.successful", [$player->getName()])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_KILL_SUCCESSFUL, [$player->getName()])); }else{ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); } return true; @@ -76,13 +77,13 @@ class KillCommand extends VanillaCommand{ if($sender instanceof Player){ if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_KILL_SELF)){ - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); return true; } $sender->attack(new EntityDamageEvent($sender, EntityDamageEvent::CAUSE_SUICIDE, 1000)); - $sender->sendMessage(new TranslationContainer("commands.kill.successful", [$sender->getName()])); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_KILL_SUCCESSFUL, [$sender->getName()])); }else{ throw new InvalidCommandSyntaxException(); } diff --git a/src/command/defaults/ListCommand.php b/src/command/defaults/ListCommand.php index 70cbd90734..282a889ce8 100644 --- a/src/command/defaults/ListCommand.php +++ b/src/command/defaults/ListCommand.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -39,8 +40,8 @@ class ListCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.list.description", - "%command.players.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_LIST_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_PLAYERS_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_LIST); } @@ -57,7 +58,7 @@ class ListCommand extends VanillaCommand{ })); sort($playerNames, SORT_STRING); - $sender->sendMessage(new TranslationContainer("commands.players.list", [count($playerNames), $sender->getServer()->getMaxPlayers()])); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_PLAYERS_LIST, [count($playerNames), $sender->getServer()->getMaxPlayers()])); $sender->sendMessage(implode(", ", $playerNames)); return true; diff --git a/src/command/defaults/MeCommand.php b/src/command/defaults/MeCommand.php index 1f643ac215..868571579d 100644 --- a/src/command/defaults/MeCommand.php +++ b/src/command/defaults/MeCommand.php @@ -25,6 +25,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -37,8 +38,8 @@ class MeCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.me.description", - "%commands.me.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_ME_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_ME_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_ME); } @@ -52,7 +53,7 @@ class MeCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $sender->getServer()->broadcastMessage(new TranslationContainer("chat.type.emote", [$sender instanceof Player ? $sender->getDisplayName() : $sender->getName(), TextFormat::WHITE . implode(" ", $args)])); + $sender->getServer()->broadcastMessage(new TranslationContainer(KnownTranslationKeys::CHAT_TYPE_EMOTE, [$sender instanceof Player ? $sender->getDisplayName() : $sender->getName(), TextFormat::WHITE . implode(" ", $args)])); return true; } diff --git a/src/command/defaults/OpCommand.php b/src/command/defaults/OpCommand.php index a2aef219b6..8d8c55f1a9 100644 --- a/src/command/defaults/OpCommand.php +++ b/src/command/defaults/OpCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -38,8 +39,8 @@ class OpCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.op.description", - "%commands.op.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_OP_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_OP_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_OP_GIVE); } @@ -62,7 +63,7 @@ class OpCommand extends VanillaCommand{ if(($player = $sender->getServer()->getPlayerExact($name)) !== null){ $player->sendMessage(TextFormat::GRAY . "You are now op!"); } - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.op.success", [$name])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_OP_SUCCESS, [$name])); return true; } } diff --git a/src/command/defaults/PardonCommand.php b/src/command/defaults/PardonCommand.php index c9b04e7962..eaadf87052 100644 --- a/src/command/defaults/PardonCommand.php +++ b/src/command/defaults/PardonCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use function count; @@ -35,8 +36,8 @@ class PardonCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.unban.player.description", - "%commands.unban.usage", + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_UNBAN_PLAYER_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_UNBAN_USAGE, ["unban"] ); $this->setPermission(DefaultPermissionNames::COMMAND_UNBAN_PLAYER); @@ -53,7 +54,7 @@ class PardonCommand extends VanillaCommand{ $sender->getServer()->getNameBans()->remove($args[0]); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.unban.success", [$args[0]])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_UNBAN_SUCCESS, [$args[0]])); return true; } diff --git a/src/command/defaults/PardonIpCommand.php b/src/command/defaults/PardonIpCommand.php index df515d5ce7..f728b27616 100644 --- a/src/command/defaults/PardonIpCommand.php +++ b/src/command/defaults/PardonIpCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use function count; @@ -36,8 +37,8 @@ class PardonIpCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.unban.ip.description", - "%commands.unbanip.usage", + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_UNBAN_IP_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_UNBANIP_USAGE, ["unban-ip"] ); $this->setPermission(DefaultPermissionNames::COMMAND_UNBAN_IP); @@ -55,9 +56,9 @@ class PardonIpCommand extends VanillaCommand{ if(preg_match("/^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$/", $args[0])){ $sender->getServer()->getIPBans()->remove($args[0]); $sender->getServer()->getNetwork()->unblockAddress($args[0]); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.unbanip.success", [$args[0]])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_UNBANIP_SUCCESS, [$args[0]])); }else{ - $sender->sendMessage(new TranslationContainer("commands.unbanip.invalid")); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_UNBANIP_INVALID)); } return true; diff --git a/src/command/defaults/ParticleCommand.php b/src/command/defaults/ParticleCommand.php index 560b3e426d..569bd71958 100644 --- a/src/command/defaults/ParticleCommand.php +++ b/src/command/defaults/ParticleCommand.php @@ -29,6 +29,7 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\ItemFactory; use pocketmine\item\VanillaItems; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; use pocketmine\permission\DefaultPermissionNames; @@ -78,8 +79,8 @@ class ParticleCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.particle.description", - "%pocketmine.command.particle.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_PARTICLE_DESCRIPTION, + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_PARTICLE_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_PARTICLE); } @@ -119,11 +120,11 @@ class ParticleCommand extends VanillaCommand{ $particle = $this->getParticle($name, $data); if($particle === null){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.particle.notFound", [$name])); + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_PARTICLE_NOTFOUND, [$name])); return true; } - $sender->sendMessage(new TranslationContainer("commands.particle.success", [$name, $count])); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_PARTICLE_SUCCESS, [$name, $count])); $random = new Random((int) (microtime(true) * 1000) + mt_rand()); diff --git a/src/command/defaults/PluginsCommand.php b/src/command/defaults/PluginsCommand.php index ac3c9cd8ac..791c341720 100644 --- a/src/command/defaults/PluginsCommand.php +++ b/src/command/defaults/PluginsCommand.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\plugin\Plugin; @@ -39,8 +40,8 @@ class PluginsCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.plugins.description", - "%pocketmine.command.plugins.usage", + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_DESCRIPTION, + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_USAGE, ["pl"] ); $this->setPermission(DefaultPermissionNames::COMMAND_PLUGINS); @@ -56,7 +57,7 @@ class PluginsCommand extends VanillaCommand{ }, $sender->getServer()->getPluginManager()->getPlugins()); sort($list, SORT_STRING); - $sender->sendMessage(new TranslationContainer("pocketmine.command.plugins.success", [count($list), implode(TextFormat::WHITE . ", ", $list)])); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_SUCCESS, [count($list), implode(TextFormat::WHITE . ", ", $list)])); return true; } } diff --git a/src/command/defaults/SaveCommand.php b/src/command/defaults/SaveCommand.php index e701d3801e..12b8b54d60 100644 --- a/src/command/defaults/SaveCommand.php +++ b/src/command/defaults/SaveCommand.php @@ -25,6 +25,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use function microtime; @@ -35,8 +36,8 @@ class SaveCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.save.description", - "%commands.save.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_SAVE_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_SAVE_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_SAVE_PERFORM); } @@ -46,7 +47,7 @@ class SaveCommand extends VanillaCommand{ return true; } - Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.save.start")); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::POCKETMINE_SAVE_START)); $start = microtime(true); foreach($sender->getServer()->getOnlinePlayers() as $player){ @@ -57,7 +58,7 @@ class SaveCommand extends VanillaCommand{ $world->save(true); } - Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.save.success", [round(microtime(true) - $start, 3)])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::POCKETMINE_SAVE_SUCCESS, [round(microtime(true) - $start, 3)])); return true; } diff --git a/src/command/defaults/SaveOffCommand.php b/src/command/defaults/SaveOffCommand.php index 9c08e24600..b64fec44eb 100644 --- a/src/command/defaults/SaveOffCommand.php +++ b/src/command/defaults/SaveOffCommand.php @@ -25,6 +25,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; @@ -33,8 +34,8 @@ class SaveOffCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.saveoff.description", - "%commands.save-off.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_SAVEOFF_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_SAVE_OFF_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_SAVE_DISABLE); } @@ -46,7 +47,7 @@ class SaveOffCommand extends VanillaCommand{ $sender->getServer()->getWorldManager()->setAutoSave(false); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.save.disabled")); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_SAVE_DISABLED)); return true; } diff --git a/src/command/defaults/SaveOnCommand.php b/src/command/defaults/SaveOnCommand.php index 08a342de8d..d19e3a3cc9 100644 --- a/src/command/defaults/SaveOnCommand.php +++ b/src/command/defaults/SaveOnCommand.php @@ -25,6 +25,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; @@ -33,8 +34,8 @@ class SaveOnCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.saveon.description", - "%commands.save-on.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_SAVEON_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_SAVE_ON_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_SAVE_ENABLE); } @@ -46,7 +47,7 @@ class SaveOnCommand extends VanillaCommand{ $sender->getServer()->getWorldManager()->setAutoSave(true); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.save.enabled")); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_SAVE_ENABLED)); return true; } diff --git a/src/command/defaults/SayCommand.php b/src/command/defaults/SayCommand.php index ac3faa8e57..d337b6bc87 100644 --- a/src/command/defaults/SayCommand.php +++ b/src/command/defaults/SayCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\console\ConsoleCommandSender; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -38,8 +39,8 @@ class SayCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.say.description", - "%commands.say.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_SAY_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_SAY_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_SAY); } @@ -53,7 +54,7 @@ class SayCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $sender->getServer()->broadcastMessage(new TranslationContainer(TextFormat::LIGHT_PURPLE . "%chat.type.announcement", [$sender instanceof Player ? $sender->getDisplayName() : ($sender instanceof ConsoleCommandSender ? "Server" : $sender->getName()), TextFormat::LIGHT_PURPLE . implode(" ", $args)])); + $sender->getServer()->broadcastMessage(new TranslationContainer(TextFormat::LIGHT_PURPLE . "%" . KnownTranslationKeys::CHAT_TYPE_ANNOUNCEMENT, [$sender instanceof Player ? $sender->getDisplayName() : ($sender instanceof ConsoleCommandSender ? "Server" : $sender->getName()), TextFormat::LIGHT_PURPLE . implode(" ", $args)])); return true; } } diff --git a/src/command/defaults/SeedCommand.php b/src/command/defaults/SeedCommand.php index d3015436aa..078f5f2d5b 100644 --- a/src/command/defaults/SeedCommand.php +++ b/src/command/defaults/SeedCommand.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -33,8 +34,8 @@ class SeedCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.seed.description", - "%commands.seed.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_SEED_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_SEED_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_SEED); } @@ -49,7 +50,7 @@ class SeedCommand extends VanillaCommand{ }else{ $seed = $sender->getServer()->getWorldManager()->getDefaultWorld()->getSeed(); } - $sender->sendMessage(new TranslationContainer("commands.seed.success", [$seed])); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_SEED_SUCCESS, [$seed])); return true; } diff --git a/src/command/defaults/SetWorldSpawnCommand.php b/src/command/defaults/SetWorldSpawnCommand.php index 6ff10470d1..055795dbb7 100644 --- a/src/command/defaults/SetWorldSpawnCommand.php +++ b/src/command/defaults/SetWorldSpawnCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; use pocketmine\permission\DefaultPermissionNames; @@ -39,8 +40,8 @@ class SetWorldSpawnCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.setworldspawn.description", - "%commands.setworldspawn.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_SETWORLDSPAWN_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_SETWORLDSPAWN_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_SETWORLDSPAWN); } @@ -69,7 +70,7 @@ class SetWorldSpawnCommand extends VanillaCommand{ $world->setSpawnLocation($pos); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.setworldspawn.success", [round($pos->x, 2), round($pos->y, 2), round($pos->z, 2)])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_SETWORLDSPAWN_SUCCESS, [round($pos->x, 2), round($pos->y, 2), round($pos->z, 2)])); return true; } diff --git a/src/command/defaults/SpawnpointCommand.php b/src/command/defaults/SpawnpointCommand.php index fcf86869d1..bf5c91ec95 100644 --- a/src/command/defaults/SpawnpointCommand.php +++ b/src/command/defaults/SpawnpointCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -40,8 +41,8 @@ class SpawnpointCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.spawnpoint.description", - "%commands.spawnpoint.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_SPAWNPOINT_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_SPAWNPOINT_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_SPAWNPOINT); } @@ -64,7 +65,7 @@ class SpawnpointCommand extends VanillaCommand{ }else{ $target = $sender->getServer()->getPlayerByPrefix($args[0]); if($target === null){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); return true; } @@ -78,7 +79,7 @@ class SpawnpointCommand extends VanillaCommand{ $z = $this->getRelativeDouble($pos->z, $sender, $args[3]); $target->setSpawn(new Position($x, $y, $z, $world)); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.spawnpoint.success", [$target->getName(), round($x, 2), round($y, 2), round($z, 2)])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_SPAWNPOINT_SUCCESS, [$target->getName(), round($x, 2), round($y, 2), round($z, 2)])); return true; }elseif(count($args) <= 1){ @@ -87,7 +88,7 @@ class SpawnpointCommand extends VanillaCommand{ $pos = Position::fromObject($cpos->floor(), $cpos->getWorld()); $target->setSpawn($pos); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.spawnpoint.success", [$target->getName(), round($pos->x, 2), round($pos->y, 2), round($pos->z, 2)])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_SPAWNPOINT_SUCCESS, [$target->getName(), round($pos->x, 2), round($pos->y, 2), round($pos->z, 2)])); return true; }else{ $sender->sendMessage(TextFormat::RED . "Please provide a player!"); diff --git a/src/command/defaults/StatusCommand.php b/src/command/defaults/StatusCommand.php index a64dc6dc90..6f5e0133be 100644 --- a/src/command/defaults/StatusCommand.php +++ b/src/command/defaults/StatusCommand.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\Process; use pocketmine\utils\TextFormat; @@ -38,8 +39,8 @@ class StatusCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.status.description", - "%pocketmine.command.status.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_STATUS_DESCRIPTION, + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_STATUS_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_STATUS); } diff --git a/src/command/defaults/StopCommand.php b/src/command/defaults/StopCommand.php index 1b943d0d78..fe89c3af2d 100644 --- a/src/command/defaults/StopCommand.php +++ b/src/command/defaults/StopCommand.php @@ -25,6 +25,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; @@ -33,8 +34,8 @@ class StopCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.stop.description", - "%commands.stop.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_STOP_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_STOP_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_STOP); } @@ -44,7 +45,7 @@ class StopCommand extends VanillaCommand{ return true; } - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.stop.start")); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_STOP_START)); $sender->getServer()->shutdown(); diff --git a/src/command/defaults/TeleportCommand.php b/src/command/defaults/TeleportCommand.php index 77a6642711..4f9998b3d7 100644 --- a/src/command/defaults/TeleportCommand.php +++ b/src/command/defaults/TeleportCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\entity\Location; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -41,8 +42,8 @@ class TeleportCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.tp.description", - "%commands.tp.usage", + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_TP_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_TP_USAGE, ["teleport"] ); $this->setPermission(DefaultPermissionNames::COMMAND_TELEPORT); @@ -96,7 +97,7 @@ class TeleportCommand extends VanillaCommand{ } $subject->teleport($targetPlayer->getLocation()); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.tp.success", [$subject->getName(), $targetPlayer->getName()])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_TP_SUCCESS, [$subject->getName(), $targetPlayer->getName()])); return true; case 3: @@ -116,7 +117,7 @@ class TeleportCommand extends VanillaCommand{ $targetLocation = new Location($x, $y, $z, $yaw, $pitch, $base->getWorld()); $subject->teleport($targetLocation); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.tp.success.coordinates", [ + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_TP_SUCCESS_COORDINATES, [ $subject->getName(), round($targetLocation->x, 2), round($targetLocation->y, 2), diff --git a/src/command/defaults/TellCommand.php b/src/command/defaults/TellCommand.php index f4e9c90f0a..589df12f3a 100644 --- a/src/command/defaults/TellCommand.php +++ b/src/command/defaults/TellCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -39,8 +40,8 @@ class TellCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.tell.description", - "%commands.message.usage", + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_TELL_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_MESSAGE_USAGE, ["w", "msg"] ); $this->setPermission(DefaultPermissionNames::COMMAND_TELL); @@ -58,18 +59,18 @@ class TellCommand extends VanillaCommand{ $player = $sender->getServer()->getPlayerByPrefix(array_shift($args)); if($player === $sender){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.message.sameTarget")); + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_MESSAGE_SAMETARGET)); return true; } if($player instanceof Player){ $message = implode(" ", $args); - $sender->sendMessage(new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . "%commands.message.display.outgoing", [$player->getDisplayName(), $message])); + $sender->sendMessage(new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . "%" . KnownTranslationKeys::COMMANDS_MESSAGE_DISPLAY_OUTGOING, [$player->getDisplayName(), $message])); $name = $sender instanceof Player ? $sender->getDisplayName() : $sender->getName(); - $player->sendMessage(new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . "%commands.message.display.incoming", [$name, $message])); - Command::broadcastCommandMessage($sender, new TranslationContainer("%commands.message.display.outgoing", [$player->getDisplayName(), $message]), false); + $player->sendMessage(new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . "%" . KnownTranslationKeys::COMMANDS_MESSAGE_DISPLAY_INCOMING, [$name, $message])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_MESSAGE_DISPLAY_OUTGOING, [$player->getDisplayName(), $message]), false); }else{ - $sender->sendMessage(new TranslationContainer("commands.generic.player.notFound")); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); } return true; diff --git a/src/command/defaults/TimeCommand.php b/src/command/defaults/TimeCommand.php index 23e1e1556b..7d8ad4e301 100644 --- a/src/command/defaults/TimeCommand.php +++ b/src/command/defaults/TimeCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -39,8 +40,8 @@ class TimeCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.time.description", - "%pocketmine.command.time.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_TIME_DESCRIPTION, + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_TIME_USAGE ); $this->setPermission(implode(";", [ DefaultPermissionNames::COMMAND_TIME_ADD, @@ -61,7 +62,7 @@ class TimeCommand extends VanillaCommand{ if($args[0] === "start"){ if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_TIME_START)){ - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); return true; } @@ -72,7 +73,7 @@ class TimeCommand extends VanillaCommand{ return true; }elseif($args[0] === "stop"){ if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_TIME_STOP)){ - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); return true; } @@ -83,7 +84,7 @@ class TimeCommand extends VanillaCommand{ return true; }elseif($args[0] === "query"){ if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_TIME_QUERY)){ - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); return true; } @@ -92,7 +93,7 @@ class TimeCommand extends VanillaCommand{ }else{ $world = $sender->getServer()->getWorldManager()->getDefaultWorld(); } - $sender->sendMessage($sender->getLanguage()->translateString("commands.time.query", [$world->getTime()])); + $sender->sendMessage($sender->getLanguage()->translateString(KnownTranslationKeys::COMMANDS_TIME_QUERY, [$world->getTime()])); return true; } @@ -102,7 +103,7 @@ class TimeCommand extends VanillaCommand{ if($args[0] === "set"){ if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_TIME_SET)){ - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); return true; } @@ -134,10 +135,10 @@ class TimeCommand extends VanillaCommand{ foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){ $world->setTime($value); } - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.time.set", [$value])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_TIME_SET, [$value])); }elseif($args[0] === "add"){ if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_TIME_ADD)){ - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); return true; } @@ -146,7 +147,7 @@ class TimeCommand extends VanillaCommand{ foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){ $world->setTime($world->getTime() + $value); } - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.time.added", [$value])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_TIME_ADDED, [$value])); }else{ throw new InvalidCommandSyntaxException(); } diff --git a/src/command/defaults/TimingsCommand.php b/src/command/defaults/TimingsCommand.php index 21018d50a6..de501ad993 100644 --- a/src/command/defaults/TimingsCommand.php +++ b/src/command/defaults/TimingsCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -59,8 +60,8 @@ class TimingsCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.timings.description", - "%pocketmine.command.timings.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_DESCRIPTION, + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_TIMINGS); } @@ -78,21 +79,21 @@ class TimingsCommand extends VanillaCommand{ if($mode === "on"){ if(TimingsHandler::isEnabled()){ - $sender->sendMessage(new TranslationContainer("pocketmine.command.timings.alreadyEnabled")); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_ALREADYENABLED)); return true; } TimingsHandler::setEnabled(); - Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.command.timings.enable")); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_ENABLE)); return true; }elseif($mode === "off"){ TimingsHandler::setEnabled(false); - Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.command.timings.disable")); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_DISABLE)); return true; } if(!TimingsHandler::isEnabled()){ - $sender->sendMessage(new TranslationContainer("pocketmine.command.timings.timingsDisabled")); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSDISABLED)); return true; } @@ -101,7 +102,7 @@ class TimingsCommand extends VanillaCommand{ if($mode === "reset"){ TimingsHandler::reload(); - Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.command.timings.reset")); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_RESET)); }elseif($mode === "merged" or $mode === "report" or $paste){ $timings = ""; if($paste){ @@ -163,16 +164,16 @@ class TimingsCommand extends VanillaCommand{ } $response = json_decode($result->getBody(), true); if(is_array($response) && isset($response["id"])){ - Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.command.timings.timingsRead", + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSREAD, ["https://" . $host . "/?id=" . $response["id"]])); }else{ - Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.command.timings.pasteError")); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_PASTEERROR)); } } )); }else{ fclose($fileTimings); - Command::broadcastCommandMessage($sender, new TranslationContainer("pocketmine.command.timings.timingsWrite", [$timings])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSWRITE, [$timings])); } }else{ throw new InvalidCommandSyntaxException(); diff --git a/src/command/defaults/TitleCommand.php b/src/command/defaults/TitleCommand.php index ec846763b1..86a5723c3e 100644 --- a/src/command/defaults/TitleCommand.php +++ b/src/command/defaults/TitleCommand.php @@ -25,6 +25,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use function array_slice; @@ -36,8 +37,8 @@ class TitleCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.title.description", - "%commands.title.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_TITLE_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_TITLE_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_TITLE); } @@ -53,7 +54,7 @@ class TitleCommand extends VanillaCommand{ $player = $sender->getServer()->getPlayerByPrefix($args[0]); if($player === null){ - $sender->sendMessage(new TranslationContainer("commands.generic.player.notFound")); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); return true; } @@ -96,7 +97,7 @@ class TitleCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $sender->sendMessage(new TranslationContainer("commands.title.success")); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_TITLE_SUCCESS)); return true; } diff --git a/src/command/defaults/TransferServerCommand.php b/src/command/defaults/TransferServerCommand.php index 1e783f9f99..0a64ccfcf3 100644 --- a/src/command/defaults/TransferServerCommand.php +++ b/src/command/defaults/TransferServerCommand.php @@ -25,6 +25,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use function count; @@ -34,8 +35,8 @@ class TransferServerCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.transferserver.description", - "%pocketmine.command.transferserver.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_TRANSFERSERVER_DESCRIPTION, + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_TRANSFERSERVER_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_TRANSFERSERVER); } diff --git a/src/command/defaults/VersionCommand.php b/src/command/defaults/VersionCommand.php index 884e4c77fb..b099ed8e41 100644 --- a/src/command/defaults/VersionCommand.php +++ b/src/command/defaults/VersionCommand.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\permission\DefaultPermissionNames; @@ -39,8 +40,8 @@ class VersionCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.version.description", - "%pocketmine.command.version.usage", + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_DESCRIPTION, + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_USAGE, ["ver", "about"] ); $this->setPermission(DefaultPermissionNames::COMMAND_VERSION); @@ -52,7 +53,7 @@ class VersionCommand extends VanillaCommand{ } if(count($args) === 0){ - $sender->sendMessage(new TranslationContainer("pocketmine.server.info.extended", [ + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_INFO_EXTENDED, [ $sender->getServer()->getName(), $sender->getServer()->getPocketMineVersion(), $sender->getServer()->getVersion(), @@ -78,7 +79,7 @@ class VersionCommand extends VanillaCommand{ } if(!$found){ - $sender->sendMessage(new TranslationContainer("pocketmine.command.version.noSuchPlugin")); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_NOSUCHPLUGIN)); } } diff --git a/src/command/defaults/WhitelistCommand.php b/src/command/defaults/WhitelistCommand.php index e0fd3ae10a..0fddb59b3a 100644 --- a/src/command/defaults/WhitelistCommand.php +++ b/src/command/defaults/WhitelistCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -42,8 +43,8 @@ class WhitelistCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%pocketmine.command.whitelist.description", - "%commands.whitelist.usage" + "%" . KnownTranslationKeys::POCKETMINE_COMMAND_WHITELIST_DESCRIPTION, + "%" . KnownTranslationKeys::COMMANDS_WHITELIST_USAGE ); $this->setPermission(implode(";", [ DefaultPermissionNames::COMMAND_WHITELIST_RELOAD, @@ -67,17 +68,17 @@ class WhitelistCommand extends VanillaCommand{ switch(strtolower($args[0])){ case "reload": $sender->getServer()->getWhitelisted()->reload(); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.whitelist.reloaded")); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_RELOADED)); return true; case "on": $sender->getServer()->getConfigGroup()->setConfigBool("white-list", true); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.whitelist.enabled")); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_ENABLED)); return true; case "off": $sender->getServer()->getConfigGroup()->setConfigBool("white-list", false); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.whitelist.disabled")); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_DISABLED)); return true; case "list": @@ -86,17 +87,17 @@ class WhitelistCommand extends VanillaCommand{ $result = implode(", ", $entries); $count = count($entries); - $sender->sendMessage(new TranslationContainer("commands.whitelist.list", [$count, $count])); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_LIST, [$count, $count])); $sender->sendMessage($result); return true; case "add": - $sender->sendMessage(new TranslationContainer("commands.generic.usage", ["%commands.whitelist.add.usage"])); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_USAGE, ["%" . KnownTranslationKeys::COMMANDS_WHITELIST_ADD_USAGE])); return true; case "remove": - $sender->sendMessage(new TranslationContainer("commands.generic.usage", ["%commands.whitelist.remove.usage"])); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_USAGE, ["%" . KnownTranslationKeys::COMMANDS_WHITELIST_REMOVE_USAGE])); return true; } }elseif(count($args) === 2){ @@ -109,12 +110,12 @@ class WhitelistCommand extends VanillaCommand{ switch(strtolower($args[0])){ case "add": $sender->getServer()->addWhitelist($args[1]); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.whitelist.add.success", [$args[1]])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_ADD_SUCCESS, [$args[1]])); return true; case "remove": $sender->getServer()->removeWhitelist($args[1]); - Command::broadcastCommandMessage($sender, new TranslationContainer("commands.whitelist.remove.success", [$args[1]])); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_REMOVE_SUCCESS, [$args[1]])); return true; } @@ -136,7 +137,7 @@ class WhitelistCommand extends VanillaCommand{ throw new AssumptionFailedError("Unknown subcommand $subcommand"); } if(!$sender->hasPermission($permission)){ - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%commands.generic.permission")); + $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); return true; } diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php new file mode 100644 index 0000000000..6d5112688e --- /dev/null +++ b/src/lang/KnownTranslationKeys.php @@ -0,0 +1,369 @@ +get("language.name"); + return $this->get(KnownTranslationKeys::LANGUAGE_NAME); } public function getLang() : string{ diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 45926887a5..eab54915b1 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -34,6 +34,7 @@ use pocketmine\event\player\PlayerDuplicateLoginEvent; use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\event\server\DataPacketSendEvent; use pocketmine\form\Form; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\StringTag; @@ -576,7 +577,7 @@ class NetworkSession{ } if($error !== null){ - $this->disconnect($this->server->getLanguage()->translateString("pocketmine.disconnect.invalidSession", [$error])); + $this->disconnect($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION, [$error])); return; } diff --git a/src/network/mcpe/auth/ProcessLoginTask.php b/src/network/mcpe/auth/ProcessLoginTask.php index fa81052352..103a394053 100644 --- a/src/network/mcpe/auth/ProcessLoginTask.php +++ b/src/network/mcpe/auth/ProcessLoginTask.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\auth; use FG\ASN1\Exception\ParserException; use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\network\mcpe\JwtException; use pocketmine\network\mcpe\JwtUtils; use pocketmine\network\mcpe\protocol\types\login\JwtChainLinkBody; @@ -133,14 +134,14 @@ class ProcessLoginTask extends AsyncTask{ if($currentPublicKey === null){ if(!$first){ - throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.missingKey"); + throw new VerifyLoginException("%" . KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_MISSINGKEY); } //First link, check that it is self-signed $currentPublicKey = $headers->x5u; }elseif($headers->x5u !== $currentPublicKey){ //Fast path: if the header key doesn't match what we expected, the signature isn't going to validate anyway - throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.badSignature"); + throw new VerifyLoginException("%" . KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_BADSIGNATURE); } $derPublicKeySerializer = new DerPublicKeySerializer(); @@ -156,7 +157,7 @@ class ProcessLoginTask extends AsyncTask{ try{ if(!JwtUtils::verify($jwt, $signingKey)){ - throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.badSignature"); + throw new VerifyLoginException("%" . KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_BADSIGNATURE); } }catch(JwtException $e){ throw new VerifyLoginException($e->getMessage(), 0, $e); @@ -180,11 +181,11 @@ class ProcessLoginTask extends AsyncTask{ $time = time(); if(isset($claims->nbf) and $claims->nbf > $time + self::CLOCK_DRIFT_MAX){ - throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.tooEarly"); + throw new VerifyLoginException("%" . KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_TOOEARLY); } if(isset($claims->exp) and $claims->exp < $time - self::CLOCK_DRIFT_MAX){ - throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.tooLate"); + throw new VerifyLoginException("%" . KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_TOOLATE); } $currentPublicKey = $claims->identityPublicKey ?? null; //if there are further links, the next link should be signed with this diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index 222a67407f..27911a3fa9 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\handler; use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; use pocketmine\entity\InvalidSkinException; use pocketmine\event\player\PlayerPreLoginEvent; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\network\mcpe\auth\ProcessLoginTask; use pocketmine\network\mcpe\convert\SkinAdapterSingleton; use pocketmine\network\mcpe\JwtException; @@ -87,7 +88,7 @@ class LoginPacketHandler extends PacketHandler{ //This pocketmine disconnect message will only be seen by the console (PlayStatusPacket causes the messages to be shown for the client) $this->session->disconnect( - $this->server->getLanguage()->translateString("pocketmine.disconnect.incompatibleProtocol", [$packet->protocol]), + $this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_DISCONNECT_INCOMPATIBLEPROTOCOL, [$packet->protocol]), false ); diff --git a/src/network/query/QueryHandler.php b/src/network/query/QueryHandler.php index b88e47b739..101b47174b 100644 --- a/src/network/query/QueryHandler.php +++ b/src/network/query/QueryHandler.php @@ -27,6 +27,7 @@ declare(strict_types=1); */ namespace pocketmine\network\query; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\RawPacketHandler; use pocketmine\Server; @@ -70,7 +71,7 @@ class QueryHandler implements RawPacketHandler{ $this->regenerateToken(); $this->lastToken = $this->token; - $this->logger->info($this->server->getLanguage()->translateString("pocketmine.server.query.running", [$addr, $port])); + $this->logger->info($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_QUERY_RUNNING, [$addr, $port])); } public function getPattern() : string{ diff --git a/src/player/Player.php b/src/player/Player.php index 281405a56c..3e626fed32 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -80,6 +80,7 @@ use pocketmine\item\enchantment\MeleeWeaponEnchantment; use pocketmine\item\Item; use pocketmine\item\ItemUseResult; use pocketmine\item\Releasable; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\Language; use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; @@ -307,7 +308,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return; } - $this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logIn", [ + $this->server->getLogger()->info($this->getServer()->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLAYER_LOGIN, [ TextFormat::AQUA . $this->username . TextFormat::WHITE, $session->getIp(), $session->getPort(), diff --git a/src/plugin/PluginBase.php b/src/plugin/PluginBase.php index eae2aeec3e..e2beaeb0f2 100644 --- a/src/plugin/PluginBase.php +++ b/src/plugin/PluginBase.php @@ -27,6 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandExecutor; use pocketmine\command\CommandSender; use pocketmine\command\PluginCommand; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\scheduler\TaskScheduler; use pocketmine\Server; use pocketmine\utils\AssumptionFailedError; @@ -167,7 +168,7 @@ abstract class PluginBase implements Plugin, CommandExecutor{ foreach($this->getDescription()->getCommands() as $key => $data){ if(strpos($key, ":") !== false){ - $this->logger->error($this->server->getLanguage()->translateString("pocketmine.plugin.commandError", [$key, $this->getDescription()->getFullName()])); + $this->logger->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_COMMANDERROR, [$key, $this->getDescription()->getFullName()])); continue; } if(is_array($data)){ //TODO: error out if it isn't @@ -184,7 +185,7 @@ abstract class PluginBase implements Plugin, CommandExecutor{ $aliasList = []; foreach($data["aliases"] as $alias){ if(strpos($alias, ":") !== false){ - $this->logger->error($this->server->getLanguage()->translateString("pocketmine.plugin.aliasError", [$alias, $this->getDescription()->getFullName()])); + $this->logger->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_ALIASERROR, [$alias, $this->getDescription()->getFullName()])); continue; } $aliasList[] = $alias; diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index f42669b1df..08a01259b0 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -31,6 +31,7 @@ use pocketmine\event\ListenerMethodTags; use pocketmine\event\plugin\PluginDisableEvent; use pocketmine\event\plugin\PluginEnableEvent; use pocketmine\event\RegisteredListener; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\permission\DefaultPermissions; use pocketmine\permission\PermissionManager; @@ -134,7 +135,7 @@ class PluginManager{ if($loader->canLoadPlugin($path)){ $description = $loader->getPluginDescription($path); if($description instanceof PluginDescription){ - $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.plugin.load", [$description->getFullName()])); + $this->server->getLogger()->info($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_LOAD, [$description->getFullName()])); try{ $description->checkRequiredExtensions(); }catch(PluginException $ex){ @@ -245,7 +246,7 @@ class PluginManager{ try{ $description = $loader->getPluginDescription($file); }catch(\RuntimeException $e){ //TODO: more specific exception handling - $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.fileError", [$file, $directory, $e->getMessage()])); + $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_FILEERROR, [$file, $directory, $e->getMessage()])); $this->server->getLogger()->logException($e); continue; } @@ -255,38 +256,38 @@ class PluginManager{ $name = $description->getName(); if(stripos($name, "pocketmine") !== false or stripos($name, "minecraft") !== false or stripos($name, "mojang") !== false){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.loadError", [$name, "%pocketmine.plugin.restrictedName"])); + $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_LOADERROR, [$name, "%" . KnownTranslationKeys::POCKETMINE_PLUGIN_RESTRICTEDNAME])); continue; } if(strpos($name, " ") !== false){ - $this->server->getLogger()->warning($this->server->getLanguage()->translateString("pocketmine.plugin.spacesDiscouraged", [$name])); + $this->server->getLogger()->warning($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_SPACESDISCOURAGED, [$name])); } if(isset($plugins[$name]) or $this->getPlugin($name) instanceof Plugin){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.duplicateError", [$name])); + $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_DUPLICATEERROR, [$name])); continue; } if(!ApiVersion::isCompatible($this->server->getApiVersion(), $description->getCompatibleApis())){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.loadError", [ + $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_LOADERROR, [ $name, - $this->server->getLanguage()->translateString("%pocketmine.plugin.incompatibleAPI", [implode(", ", $description->getCompatibleApis())]) + $this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEAPI, [implode(", ", $description->getCompatibleApis())]) ])); continue; } $ambiguousVersions = ApiVersion::checkAmbiguousVersions($description->getCompatibleApis()); if(count($ambiguousVersions) > 0){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.loadError", [ + $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_LOADERROR, [ $name, - $this->server->getLanguage()->translateString("pocketmine.plugin.ambiguousMinAPI", [implode(", ", $ambiguousVersions)]) + $this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_AMBIGUOUSMINAPI, [implode(", ", $ambiguousVersions)]) ])); continue; } if(count($description->getCompatibleOperatingSystems()) > 0 and !in_array(Utils::getOS(), $description->getCompatibleOperatingSystems(), true)) { - $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.loadError", [ + $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_LOADERROR, [ $name, - $this->server->getLanguage()->translateString("%pocketmine.plugin.incompatibleOS", [implode(", ", $description->getCompatibleOperatingSystems())]) + $this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEOS, [implode(", ", $description->getCompatibleOperatingSystems())]) ])); continue; } @@ -294,16 +295,16 @@ class PluginManager{ if(count($pluginMcpeProtocols = $description->getCompatibleMcpeProtocols()) > 0){ $serverMcpeProtocols = [ProtocolInfo::CURRENT_PROTOCOL]; if(count(array_intersect($pluginMcpeProtocols, $serverMcpeProtocols)) === 0){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.plugin.loadError", [ + $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_LOADERROR, [ $name, - $this->server->getLanguage()->translateString("%pocketmine.plugin.incompatibleProtocol", [implode(", ", $pluginMcpeProtocols)]) + $this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_DISCONNECT_INCOMPATIBLEPROTOCOL, [implode(", ", $pluginMcpeProtocols)]) ])); continue; } } if($this->graylist !== null and !$this->graylist->isAllowed($name)){ - $this->server->getLogger()->notice($this->server->getLanguage()->translateString("pocketmine.plugin.loadError", [ + $this->server->getLogger()->notice($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_LOADERROR, [ $name, "Disallowed by graylist" ])); @@ -332,9 +333,9 @@ class PluginManager{ if(isset($loadedPlugins[$dependency]) or $this->getPlugin($dependency) instanceof Plugin){ unset($dependencies[$name][$key]); }elseif(!isset($plugins[$dependency])){ - $this->server->getLogger()->critical($this->server->getLanguage()->translateString("pocketmine.plugin.loadError", [ + $this->server->getLogger()->critical($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_LOADERROR, [ $name, - $this->server->getLanguage()->translateString("%pocketmine.plugin.unknownDependency", [$dependency]) + $this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_UNKNOWNDEPENDENCY, [$dependency]) ])); unset($plugins[$name]); continue 2; @@ -371,7 +372,7 @@ class PluginManager{ if(($plugin = $this->loadPlugin($file, $loaders)) instanceof Plugin){ $loadedPlugins[$name] = $plugin; }else{ - $this->server->getLogger()->critical($this->server->getLanguage()->translateString("pocketmine.plugin.genericLoadError", [$name])); + $this->server->getLogger()->critical($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_GENERICLOADERROR, [$name])); } } } @@ -379,7 +380,7 @@ class PluginManager{ if($loadedThisLoop === 0){ //No plugins loaded :( foreach($plugins as $name => $file){ - $this->server->getLogger()->critical($this->server->getLanguage()->translateString("pocketmine.plugin.loadError", [$name, "%pocketmine.plugin.circularDependency"])); + $this->server->getLogger()->critical($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_LOADERROR, [$name, "%" . KnownTranslationKeys::POCKETMINE_PLUGIN_CIRCULARDEPENDENCY])); } $plugins = []; } @@ -394,7 +395,7 @@ class PluginManager{ public function enablePlugin(Plugin $plugin) : void{ if(!$plugin->isEnabled()){ - $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.plugin.enable", [$plugin->getDescription()->getFullName()])); + $this->server->getLogger()->info($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_ENABLE, [$plugin->getDescription()->getFullName()])); $plugin->getScheduler()->setEnabled(true); $plugin->onEnableStateChange(true); @@ -413,7 +414,7 @@ class PluginManager{ public function disablePlugin(Plugin $plugin) : void{ if($plugin->isEnabled()){ - $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.plugin.disable", [$plugin->getDescription()->getFullName()])); + $this->server->getLogger()->info($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_DISABLE, [$plugin->getDescription()->getFullName()])); (new PluginDisableEvent($plugin))->call(); unset($this->enabledPlugins[$plugin->getDescription()->getName()]); diff --git a/src/wizard/SetupWizard.php b/src/wizard/SetupWizard.php index 31d71e5515..62d7d391ec 100644 --- a/src/wizard/SetupWizard.php +++ b/src/wizard/SetupWizard.php @@ -28,6 +28,7 @@ declare(strict_types=1); namespace pocketmine\wizard; use pocketmine\data\java\GameModeIdMap; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\Language; use pocketmine\lang\LanguageNotFoundException; use pocketmine\player\GameMode; @@ -82,7 +83,7 @@ class SetupWizard{ $this->lang = new Language($lang); - $this->message($this->lang->get("language_has_been_selected")); + $this->message($this->lang->get(KnownTranslationKeys::LANGUAGE_HAS_BEEN_SELECTED)); if(!$this->showLicense()){ return false; @@ -93,7 +94,7 @@ class SetupWizard{ $config->set("language", $lang); $config->save(); - if(strtolower($this->getInput($this->lang->get("skip_installer"), "n", "y/N")) === "y"){ + if(strtolower($this->getInput($this->lang->get(KnownTranslationKeys::SKIP_INSTALLER), "n", "y/N")) === "y"){ $this->printIpDetails(); return true; } @@ -112,7 +113,7 @@ class SetupWizard{ } private function showLicense() : bool{ - $this->message($this->lang->translateString("welcome_to_pocketmine", [VersionInfo::NAME])); + $this->message($this->lang->translateString(KnownTranslationKeys::WELCOME_TO_POCKETMINE, [VersionInfo::NAME])); echo <<writeLine(); - if(strtolower($this->getInput($this->lang->get("accept_license"), "n", "y/N")) !== "y"){ - $this->error($this->lang->translateString("you_have_to_accept_the_license", [VersionInfo::NAME])); + if(strtolower($this->getInput($this->lang->get(KnownTranslationKeys::ACCEPT_LICENSE), "n", "y/N")) !== "y"){ + $this->error($this->lang->translateString(KnownTranslationKeys::YOU_HAVE_TO_ACCEPT_THE_LICENSE, [VersionInfo::NAME])); sleep(5); return false; @@ -133,23 +134,23 @@ LICENSE; } private function welcome() : void{ - $this->message($this->lang->get("setting_up_server_now")); - $this->message($this->lang->get("default_values_info")); - $this->message($this->lang->get("server_properties")); + $this->message($this->lang->get(KnownTranslationKeys::SETTING_UP_SERVER_NOW)); + $this->message($this->lang->get(KnownTranslationKeys::DEFAULT_VALUES_INFO)); + $this->message($this->lang->get(KnownTranslationKeys::SERVER_PROPERTIES)); } private function generateBaseConfig() : void{ $config = new Config(Path::join($this->dataPath, "server.properties"), Config::PROPERTIES); - $config->set("motd", ($name = $this->getInput($this->lang->get("name_your_server"), self::DEFAULT_NAME))); + $config->set("motd", ($name = $this->getInput($this->lang->get(KnownTranslationKeys::NAME_YOUR_SERVER), self::DEFAULT_NAME))); $config->set("server-name", $name); - $this->message($this->lang->get("port_warning")); + $this->message($this->lang->get(KnownTranslationKeys::PORT_WARNING)); do{ - $port = (int) $this->getInput($this->lang->get("server_port"), (string) self::DEFAULT_PORT); + $port = (int) $this->getInput($this->lang->get(KnownTranslationKeys::SERVER_PORT), (string) self::DEFAULT_PORT); if($port <= 0 or $port > 65535){ - $this->error($this->lang->get("invalid_port")); + $this->error($this->lang->get(KnownTranslationKeys::INVALID_PORT)); continue; } @@ -157,35 +158,35 @@ LICENSE; }while(true); $config->set("server-port", $port); - $this->message($this->lang->get("gamemode_info")); + $this->message($this->lang->get(KnownTranslationKeys::GAMEMODE_INFO)); do{ - $gamemode = (int) $this->getInput($this->lang->get("default_gamemode"), (string) GameModeIdMap::getInstance()->toId(GameMode::SURVIVAL())); + $gamemode = (int) $this->getInput($this->lang->get(KnownTranslationKeys::DEFAULT_GAMEMODE), (string) GameModeIdMap::getInstance()->toId(GameMode::SURVIVAL())); }while($gamemode < 0 or $gamemode > 3); $config->set("gamemode", $gamemode); - $config->set("max-players", (int) $this->getInput($this->lang->get("max_players"), (string) self::DEFAULT_PLAYERS)); + $config->set("max-players", (int) $this->getInput($this->lang->get(KnownTranslationKeys::MAX_PLAYERS), (string) self::DEFAULT_PLAYERS)); $config->save(); } private function generateUserFiles() : void{ - $this->message($this->lang->get("op_info")); + $this->message($this->lang->get(KnownTranslationKeys::OP_INFO)); - $op = strtolower($this->getInput($this->lang->get("op_who"), "")); + $op = strtolower($this->getInput($this->lang->get(KnownTranslationKeys::OP_WHO), "")); if($op === ""){ - $this->error($this->lang->get("op_warning")); + $this->error($this->lang->get(KnownTranslationKeys::OP_WARNING)); }else{ $ops = new Config(Path::join($this->dataPath, "ops.txt"), Config::ENUM); $ops->set($op, true); $ops->save(); } - $this->message($this->lang->get("whitelist_info")); + $this->message($this->lang->get(KnownTranslationKeys::WHITELIST_INFO)); $config = new Config(Path::join($this->dataPath, "server.properties"), Config::PROPERTIES); - if(strtolower($this->getInput($this->lang->get("whitelist_enable"), "n", "y/N")) === "y"){ - $this->error($this->lang->get("whitelist_warning")); + if(strtolower($this->getInput($this->lang->get(KnownTranslationKeys::WHITELIST_ENABLE), "n", "y/N")) === "y"){ + $this->error($this->lang->get(KnownTranslationKeys::WHITELIST_WARNING)); $config->set("white-list", true); }else{ $config->set("white-list", false); @@ -195,9 +196,9 @@ LICENSE; private function networkFunctions() : void{ $config = new Config(Path::join($this->dataPath, "server.properties"), Config::PROPERTIES); - $this->error($this->lang->get("query_warning1")); - $this->error($this->lang->get("query_warning2")); - if(strtolower($this->getInput($this->lang->get("query_disable"), "n", "y/N")) === "y"){ + $this->error($this->lang->get(KnownTranslationKeys::QUERY_WARNING1)); + $this->error($this->lang->get(KnownTranslationKeys::QUERY_WARNING2)); + if(strtolower($this->getInput($this->lang->get(KnownTranslationKeys::QUERY_DISABLE), "n", "y/N")) === "y"){ $config->set("enable-query", false); }else{ $config->set("enable-query", true); @@ -207,7 +208,7 @@ LICENSE; } private function printIpDetails() : void{ - $this->message($this->lang->get("ip_get")); + $this->message($this->lang->get(KnownTranslationKeys::IP_GET)); $externalIP = Internet::getIP(); if($externalIP === false){ @@ -219,15 +220,15 @@ LICENSE; $internalIP = "unknown (" . $e->getMessage() . ")"; } - $this->error($this->lang->translateString("ip_warning", ["EXTERNAL_IP" => $externalIP, "INTERNAL_IP" => $internalIP])); - $this->error($this->lang->get("ip_confirm")); + $this->error($this->lang->translateString(KnownTranslationKeys::IP_WARNING, ["EXTERNAL_IP" => $externalIP, "INTERNAL_IP" => $internalIP])); + $this->error($this->lang->get(KnownTranslationKeys::IP_CONFIRM)); $this->readLine(); } private function endWizard() : void{ - $this->message($this->lang->get("you_have_finished")); - $this->message($this->lang->get("pocketmine_plugins")); - $this->message($this->lang->translateString("pocketmine_will_start", [VersionInfo::NAME])); + $this->message($this->lang->get(KnownTranslationKeys::YOU_HAVE_FINISHED)); + $this->message($this->lang->get(KnownTranslationKeys::POCKETMINE_PLUGINS)); + $this->message($this->lang->translateString(KnownTranslationKeys::POCKETMINE_WILL_START, [VersionInfo::NAME])); $this->writeLine(); $this->writeLine(); diff --git a/src/world/World.php b/src/world/World.php index 7c7a4c2717..4bdcb7e40c 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -54,6 +54,7 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\ItemUseResult; use pocketmine\item\LegacyStringToItemParser; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; use pocketmine\nbt\NbtDataException; @@ -400,7 +401,7 @@ class World implements ChunkManager{ $this->minY = $this->provider->getWorldMinY(); $this->maxY = $this->provider->getWorldMaxY(); - $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.level.preparing", [$this->displayName])); + $this->server->getLogger()->info($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_PREPARING, [$this->displayName])); $this->generator = GeneratorManager::getInstance()->getGenerator($this->provider->getWorldData()->getGenerator(), true); //TODO: validate generator options $this->chunkPopulationRequestQueue = new \SplQueue(); diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 4fb3df5b29..99e07b566f 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -27,6 +27,7 @@ use pocketmine\entity\Entity; use pocketmine\event\world\WorldInitEvent; use pocketmine\event\world\WorldLoadEvent; use pocketmine\event\world\WorldUnloadEvent; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\player\ChunkSelector; use pocketmine\Server; use pocketmine\timings\Timings; @@ -149,7 +150,7 @@ class WorldManager{ return false; } - $this->server->getLogger()->info($this->server->getLanguage()->translateString("pocketmine.level.unloading", [$world->getDisplayName()])); + $this->server->getLogger()->info($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_UNLOADING, [$world->getDisplayName()])); try{ $safeSpawn = $this->defaultWorld !== null ? $this->defaultWorld->getSafeSpawn() : null; }catch(WorldException $e){ @@ -193,11 +194,11 @@ class WorldManager{ $providers = $this->providerManager->getMatchingProviders($path); if(count($providers) !== 1){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.level.loadError", [ + $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_LOADERROR, [ $name, count($providers) === 0 ? - $this->server->getLanguage()->translateString("pocketmine.level.unknownFormat") : - $this->server->getLanguage()->translateString("pocketmine.level.ambiguousFormat", [implode(", ", array_keys($providers))]) + $this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_UNKNOWNFORMAT) : + $this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_AMBIGUOUSFORMAT, [implode(", ", array_keys($providers))]) ])); return false; } @@ -210,16 +211,16 @@ class WorldManager{ */ $provider = new $providerClass($path); }catch(CorruptedWorldException $e){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.level.loadError", [$name, "Corruption detected: " . $e->getMessage()])); + $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_LOADERROR, [$name, "Corruption detected: " . $e->getMessage()])); return false; }catch(UnsupportedWorldFormatException $e){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.level.loadError", [$name, "Unsupported format: " . $e->getMessage()])); + $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_LOADERROR, [$name, "Unsupported format: " . $e->getMessage()])); return false; } try{ GeneratorManager::getInstance()->getGenerator($provider->getWorldData()->getGenerator(), true); }catch(\InvalidArgumentException $e){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString("pocketmine.level.loadError", [$name, "Unknown generator \"" . $provider->getWorldData()->getGenerator() . "\""])); + $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_LOADERROR, [$name, "Unknown generator \"" . $provider->getWorldData()->getGenerator() . "\""])); return false; } if(!($provider instanceof WritableWorldProvider)){ @@ -271,7 +272,7 @@ class WorldManager{ (new WorldLoadEvent($world))->call(); if($backgroundGeneration){ - $this->server->getLogger()->notice($this->server->getLanguage()->translateString("pocketmine.level.backgroundGeneration", [$name])); + $this->server->getLogger()->notice($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_BACKGROUNDGENERATION, [$name])); $spawnLocation = $world->getSpawnLocation(); $centerX = $spawnLocation->getFloorX() >> 4; From 316e2654ccf22ff51a13a7a0c8a18c116e36c3da Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 29 Jun 2021 22:50:08 +0100 Subject: [PATCH 2587/3224] Fixed CS --- build/generate-known-translation-keys.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/generate-known-translation-keys.php b/build/generate-known-translation-keys.php index 2018db3ffe..60f901eb3f 100644 --- a/build/generate-known-translation-keys.php +++ b/build/generate-known-translation-keys.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\build\generate_known_translation_keys; use Webmozart\PathUtil\Path; +use function dirname; require dirname(__DIR__) . '/vendor/autoload.php'; @@ -66,7 +67,6 @@ final class KnownTranslationKeys{ HEADER; - $perms = []; $lang = parse_ini_file(Path::join(\pocketmine\RESOURCE_PATH, "locale", "eng.ini"), false, INI_SCANNER_RAW); From 2312511be6e75e02412e45054f11661baf8eead0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 29 Jun 2021 23:54:52 +0100 Subject: [PATCH 2588/3224] Living: remove unnecessary double CompoundTag::getTag() call --- src/entity/Living.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entity/Living.php b/src/entity/Living.php index e11b2e5a1e..c21f6720ae 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -142,7 +142,7 @@ abstract class Living extends Entity{ $health = $healFTag->getValue(); }elseif(($healthTag = $nbt->getTag("Health")) instanceof ShortTag){ $health = $healthTag->getValue(); //Older versions of PocketMine-MP incorrectly saved this as a short instead of a float - }elseif(($healthTag = $nbt->getTag("Health")) instanceof FloatTag){ + }elseif($healthTag instanceof FloatTag){ $health = $healthTag->getValue(); } From 76a74b3931357c19c751212665a1ac8b7d492768 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 30 Jun 2021 13:13:53 +0100 Subject: [PATCH 2589/3224] Revert "Item: skip a step when decoding PC itemstacks" This reverts commit 9b52af62b6f469771f2355a964b35ecffa5117d9. We shouldn't assume that a string maps directly to a legacy ID, because we might want string aliases (e.g. dark_oak_boat) which refer to items that have a specific meta value in the MCPE system. Overall, I want to get rid of the reliance on IDs here and register all this stuff using closure callbacks on VanillaItems, so getting rid of this assumption also serves that goal. --- src/item/Item.php | 9 +++++---- src/item/LegacyStringToItemParser.php | 5 ----- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/item/Item.php b/src/item/Item.php index bef3adb868..103638c156 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -678,12 +678,13 @@ class Item implements \JsonSerializable{ if($idTag instanceof ShortTag){ $item = ItemFactory::getInstance()->get($idTag->getValue(), $meta, $count); }elseif($idTag instanceof StringTag){ //PC item save format - //TODO: this isn't a very good mapping source, we need a dedicated mapping for PC - $id = LegacyStringToItemParser::getInstance()->parseId($idTag->getValue()); - if($id === null){ + try{ + $item = LegacyStringToItemParser::getInstance()->parse($idTag->getValue() . ":$meta"); + }catch(\InvalidArgumentException $e){ + //TODO: improve error handling return ItemFactory::air(); } - $item = ItemFactory::getInstance()->get($id, $meta, $count); + $item->setCount($count); }else{ throw new \InvalidArgumentException("Item CompoundTag ID must be an instance of StringTag or ShortTag, " . get_class($idTag) . " given"); } diff --git a/src/item/LegacyStringToItemParser.php b/src/item/LegacyStringToItemParser.php index ca7559e640..d4d345b578 100644 --- a/src/item/LegacyStringToItemParser.php +++ b/src/item/LegacyStringToItemParser.php @@ -33,7 +33,6 @@ use function is_int; use function is_numeric; use function is_string; use function json_decode; -use function mb_strtolower; use function str_replace; use function strtolower; use function trim; @@ -80,10 +79,6 @@ final class LegacyStringToItemParser{ $this->map[$alias] = $id; } - public function parseId(string $input) : ?int{ - return $this->map[mb_strtolower($this->reprocess($input))] ?? null; - } - /** * Tries to parse the specified string into Item types. * From f3bd48e6cb69dc025b7013241dd478a6f3141bff Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 30 Jun 2021 14:02:55 +0100 Subject: [PATCH 2590/3224] Updated some more hardcoded translation key usages missed by 94e16f416de31b79c93bdc2c6cf84b22d25ba63f --- src/command/defaults/GiveCommand.php | 8 ++--- src/command/defaults/VanillaCommand.php | 5 ++-- src/event/player/PlayerDeathEvent.php | 39 +++++++++++++------------ src/player/Player.php | 4 +-- 4 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/command/defaults/GiveCommand.php b/src/command/defaults/GiveCommand.php index aa23475f91..9637937e31 100644 --- a/src/command/defaults/GiveCommand.php +++ b/src/command/defaults/GiveCommand.php @@ -59,14 +59,14 @@ class GiveCommand extends VanillaCommand{ $player = $sender->getServer()->getPlayerByPrefix($args[0]); if($player === null){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); return true; } try{ $item = LegacyStringToItemParser::getInstance()->parse($args[1]); }catch(\InvalidArgumentException $e){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.give.item.notFound", [$args[1]])); + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GIVE_ITEM_NOTFOUND, [$args[1]])); return true; } @@ -81,7 +81,7 @@ class GiveCommand extends VanillaCommand{ try{ $tags = JsonNbtParser::parseJson($data); }catch(NbtDataException $e){ - $sender->sendMessage(new TranslationContainer("commands.give.tagError", [$e->getMessage()])); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_GIVE_TAGERROR, [$e->getMessage()])); return true; } @@ -91,7 +91,7 @@ class GiveCommand extends VanillaCommand{ //TODO: overflow $player->getInventory()->addItem(clone $item); - Command::broadcastCommandMessage($sender, new TranslationContainer("%commands.give.success", [ + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_GIVE_SUCCESS, [ $item->getName() . " (" . $item->getId() . ":" . $item->getMeta() . ")", (string) $item->getCount(), $player->getName() diff --git a/src/command/defaults/VanillaCommand.php b/src/command/defaults/VanillaCommand.php index c4b821e6da..b12ccf2786 100644 --- a/src/command/defaults/VanillaCommand.php +++ b/src/command/defaults/VanillaCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\utils\TextFormat; use function is_numeric; @@ -82,11 +83,11 @@ abstract class VanillaCommand extends Command{ $v = (int) $input; if($v > $max){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.num.tooBig", [$input, (string) $max])); + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_NUM_TOOBIG, [$input, (string) $max])); return null; } if($v < $min){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.num.tooSmall", [$input, (string) $min])); + $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_NUM_TOOSMALL, [$input, (string) $min])); return null; } diff --git a/src/event/player/PlayerDeathEvent.php b/src/event/player/PlayerDeathEvent.php index acfa86a7e3..c33f3ee0de 100644 --- a/src/event/player/PlayerDeathEvent.php +++ b/src/event/player/PlayerDeathEvent.php @@ -30,6 +30,7 @@ use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDeathEvent; use pocketmine\item\Item; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\player\Player; @@ -88,7 +89,7 @@ class PlayerDeathEvent extends EntityDeathEvent{ * Returns the vanilla death message for the given death cause. */ public static function deriveMessage(string $name, ?EntityDamageEvent $deathCause) : TranslationContainer{ - $message = "death.attack.generic"; + $message = KnownTranslationKeys::DEATH_ATTACK_GENERIC; $params = [$name]; switch($deathCause === null ? EntityDamageEvent::CAUSE_CUSTOM : $deathCause->getCause()){ @@ -96,11 +97,11 @@ class PlayerDeathEvent extends EntityDeathEvent{ if($deathCause instanceof EntityDamageByEntityEvent){ $e = $deathCause->getDamager(); if($e instanceof Player){ - $message = "death.attack.player"; + $message = KnownTranslationKeys::DEATH_ATTACK_PLAYER; $params[] = $e->getDisplayName(); break; }elseif($e instanceof Living){ - $message = "death.attack.mob"; + $message = KnownTranslationKeys::DEATH_ATTACK_MOB; $params[] = $e->getNameTag() !== "" ? $e->getNameTag() : $e->getName(); break; }else{ @@ -112,10 +113,10 @@ class PlayerDeathEvent extends EntityDeathEvent{ if($deathCause instanceof EntityDamageByEntityEvent){ $e = $deathCause->getDamager(); if($e instanceof Player){ - $message = "death.attack.arrow"; + $message = KnownTranslationKeys::DEATH_ATTACK_ARROW; $params[] = $e->getDisplayName(); }elseif($e instanceof Living){ - $message = "death.attack.arrow"; + $message = KnownTranslationKeys::DEATH_ATTACK_ARROW; $params[] = $e->getNameTag() !== "" ? $e->getNameTag() : $e->getName(); break; }else{ @@ -124,45 +125,45 @@ class PlayerDeathEvent extends EntityDeathEvent{ } break; case EntityDamageEvent::CAUSE_SUICIDE: - $message = "death.attack.generic"; + $message = KnownTranslationKeys::DEATH_ATTACK_GENERIC; break; case EntityDamageEvent::CAUSE_VOID: - $message = "death.attack.outOfWorld"; + $message = KnownTranslationKeys::DEATH_ATTACK_OUTOFWORLD; break; case EntityDamageEvent::CAUSE_FALL: if($deathCause instanceof EntityDamageEvent){ if($deathCause->getFinalDamage() > 2){ - $message = "death.fell.accident.generic"; + $message = KnownTranslationKeys::DEATH_FELL_ACCIDENT_GENERIC; break; } } - $message = "death.attack.fall"; + $message = KnownTranslationKeys::DEATH_ATTACK_FALL; break; case EntityDamageEvent::CAUSE_SUFFOCATION: - $message = "death.attack.inWall"; + $message = KnownTranslationKeys::DEATH_ATTACK_INWALL; break; case EntityDamageEvent::CAUSE_LAVA: - $message = "death.attack.lava"; + $message = KnownTranslationKeys::DEATH_ATTACK_LAVA; break; case EntityDamageEvent::CAUSE_FIRE: - $message = "death.attack.onFire"; + $message = KnownTranslationKeys::DEATH_ATTACK_ONFIRE; break; case EntityDamageEvent::CAUSE_FIRE_TICK: - $message = "death.attack.inFire"; + $message = KnownTranslationKeys::DEATH_ATTACK_INFIRE; break; case EntityDamageEvent::CAUSE_DROWNING: - $message = "death.attack.drown"; + $message = KnownTranslationKeys::DEATH_ATTACK_DROWN; break; case EntityDamageEvent::CAUSE_CONTACT: if($deathCause instanceof EntityDamageByBlockEvent){ if($deathCause->getDamager()->getId() === BlockLegacyIds::CACTUS){ - $message = "death.attack.cactus"; + $message = KnownTranslationKeys::DEATH_ATTACK_CACTUS; } } break; @@ -172,20 +173,20 @@ class PlayerDeathEvent extends EntityDeathEvent{ if($deathCause instanceof EntityDamageByEntityEvent){ $e = $deathCause->getDamager(); if($e instanceof Player){ - $message = "death.attack.explosion.player"; + $message = KnownTranslationKeys::DEATH_ATTACK_EXPLOSION_PLAYER; $params[] = $e->getDisplayName(); }elseif($e instanceof Living){ - $message = "death.attack.explosion.player"; + $message = KnownTranslationKeys::DEATH_ATTACK_EXPLOSION_PLAYER; $params[] = $e->getNameTag() !== "" ? $e->getNameTag() : $e->getName(); break; } }else{ - $message = "death.attack.explosion"; + $message = KnownTranslationKeys::DEATH_ATTACK_EXPLOSION; } break; case EntityDamageEvent::CAUSE_MAGIC: - $message = "death.attack.magic"; + $message = KnownTranslationKeys::DEATH_ATTACK_MAGIC; break; case EntityDamageEvent::CAUSE_CUSTOM: diff --git a/src/player/Player.php b/src/player/Player.php index 3e626fed32..ddc418a784 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -355,7 +355,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ */ public function getLeaveMessage(){ if($this->spawned){ - return new TranslationContainer(TextFormat::YELLOW . "%multiplayer.player.left", [ + return new TranslationContainer(TextFormat::YELLOW . "%" . KnownTranslationKeys::MULTIPLAYER_PLAYER_LEFT, [ $this->getDisplayName() ]); } @@ -799,7 +799,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ }); $ev = new PlayerJoinEvent($this, - new TranslationContainer(TextFormat::YELLOW . "%multiplayer.player.joined", [ + new TranslationContainer(TextFormat::YELLOW . "%" . KnownTranslationKeys::MULTIPLAYER_PLAYER_JOINED, [ $this->getDisplayName() ]) ); From a888ab025707b1e011141834b4c888e56f7e46ae Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 30 Jun 2021 14:07:58 +0100 Subject: [PATCH 2591/3224] GiveCommand: remove useless clone addItem() clones this anyway. --- src/command/defaults/GiveCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command/defaults/GiveCommand.php b/src/command/defaults/GiveCommand.php index 9637937e31..df740c2ace 100644 --- a/src/command/defaults/GiveCommand.php +++ b/src/command/defaults/GiveCommand.php @@ -89,7 +89,7 @@ class GiveCommand extends VanillaCommand{ } //TODO: overflow - $player->getInventory()->addItem(clone $item); + $player->getInventory()->addItem($item); Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_GIVE_SUCCESS, [ $item->getName() . " (" . $item->getId() . ":" . $item->getMeta() . ")", From 9e79d48aebab626a05f6124a3407a8bd5a4eeed2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 30 Jun 2021 15:59:39 +0100 Subject: [PATCH 2592/3224] BaseBanner: use ColoredTrait --- src/block/BaseBanner.php | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/block/BaseBanner.php b/src/block/BaseBanner.php index 2547b2ca34..c66458350a 100644 --- a/src/block/BaseBanner.php +++ b/src/block/BaseBanner.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\block\tile\Banner as TileBanner; use pocketmine\block\utils\BannerPatternLayer; +use pocketmine\block\utils\ColoredTrait; use pocketmine\block\utils\DyeColor; use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\item\Banner as ItemBanner; @@ -40,8 +41,7 @@ use function assert; use function count; abstract class BaseBanner extends Transparent{ - - protected DyeColor $baseColor; + use ColoredTrait; /** * @var BannerPatternLayer[] @@ -50,15 +50,15 @@ abstract class BaseBanner extends Transparent{ protected array $patterns = []; public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ + $this->color = DyeColor::BLACK(); parent::__construct($idInfo, $name, $breakInfo); - $this->baseColor = DyeColor::BLACK(); } public function readStateFromWorld() : void{ parent::readStateFromWorld(); $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileBanner){ - $this->baseColor = $tile->getBaseColor(); + $this->color = $tile->getBaseColor(); $this->setPatterns($tile->getPatterns()); } } @@ -67,7 +67,7 @@ abstract class BaseBanner extends Transparent{ parent::writeStateToWorld(); $tile = $this->pos->getWorld()->getTile($this->pos); assert($tile instanceof TileBanner); - $tile->setBaseColor($this->baseColor); + $tile->setBaseColor($this->color); $tile->setPatterns($this->patterns); } @@ -75,13 +75,6 @@ abstract class BaseBanner extends Transparent{ return false; } - /** - * TODO: interface method? this is only the BASE colour... - */ - public function getColor() : DyeColor{ - return $this->baseColor; - } - /** * @return BannerPatternLayer[] * @phpstan-return list @@ -114,7 +107,7 @@ abstract class BaseBanner extends Transparent{ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof ItemBanner){ - $this->baseColor = $item->getColor(); + $this->color = $item->getColor(); $this->setPatterns($item->getPatterns()); } @@ -130,7 +123,7 @@ abstract class BaseBanner extends Transparent{ } public function asItem() : Item{ - return ItemFactory::getInstance()->get(ItemIds::BANNER, DyeColorIdMap::getInstance()->toInvertedId($this->baseColor)); + return ItemFactory::getInstance()->get(ItemIds::BANNER, DyeColorIdMap::getInstance()->toInvertedId($this->color)); } public function getDropsForCompatibleTool(Item $item) : array{ From 2b4a1ffdfbf149da78c7f62ea4495cff49c9b87c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 30 Jun 2021 16:05:57 +0100 Subject: [PATCH 2593/3224] Bed: use ColoredTrait --- src/block/Bed.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/block/Bed.php b/src/block/Bed.php index c8c40a831e..19c60667c9 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -25,6 +25,7 @@ namespace pocketmine\block; use pocketmine\block\tile\Bed as TileBed; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\ColoredTrait; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\data\bedrock\DyeColorIdMap; @@ -42,15 +43,15 @@ use pocketmine\world\BlockTransaction; use pocketmine\world\World; class Bed extends Transparent{ + use ColoredTrait; use HorizontalFacingTrait; protected bool $occupied = false; protected bool $head = false; - protected DyeColor $color; public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ - parent::__construct($idInfo, $name, $breakInfo); $this->color = DyeColor::RED(); + parent::__construct($idInfo, $name, $breakInfo); } protected function writeStateToMeta() : int{ From 12905d8c27c145863279437750ed4773a8debe18 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 30 Jun 2021 17:03:20 +0100 Subject: [PATCH 2594/3224] BlockFactory: remove some TODOs --- src/block/BlockFactory.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 35bae199a2..2b607636f4 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -561,7 +561,6 @@ class BlockFactory{ //TODO: minecraft:lectern //TODO: minecraft:lit_blast_furnace //TODO: minecraft:lit_smoker - //TODO: minecraft:loom //TODO: minecraft:movingBlock //TODO: minecraft:observer //TODO: minecraft:piston @@ -575,12 +574,6 @@ class BlockFactory{ //TODO: minecraft:smoker //TODO: minecraft:sticky_piston //TODO: minecraft:stonecutter_block - //TODO: minecraft:stripped_acacia_log - //TODO: minecraft:stripped_birch_log - //TODO: minecraft:stripped_dark_oak_log - //TODO: minecraft:stripped_jungle_log - //TODO: minecraft:stripped_oak_log - //TODO: minecraft:stripped_spruce_log //TODO: minecraft:structure_block //TODO: minecraft:sweet_berry_bush //TODO: minecraft:turtle_egg From c05f6db8d994daa19b948b83e1ca1db63fb24829 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 30 Jun 2021 17:27:14 +0100 Subject: [PATCH 2595/3224] Bed and Skull items now return a correct block, with appropriate type information I wanted to do the same for banners, but unfortunately banners are a tad more complicated. --- src/block/Bed.php | 4 ---- src/block/Skull.php | 4 ---- src/item/Bed.php | 2 +- src/item/Skull.php | 4 +++- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/block/Bed.php b/src/block/Bed.php index 19c60667c9..3979b8a099 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -29,7 +29,6 @@ use pocketmine\block\utils\ColoredTrait; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\data\bedrock\DyeColorIdMap; -use pocketmine\item\Bed as ItemBed; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\lang\KnownTranslationKeys; @@ -174,9 +173,6 @@ class Bed extends Transparent{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($item instanceof ItemBed){ //TODO: the item should do this - $this->color = $item->getColor(); - } $down = $this->getSide(Facing::DOWN); if(!$down->isTransparent()){ $this->facing = $player !== null ? $player->getHorizontalFacing() : Facing::NORTH; diff --git a/src/block/Skull.php b/src/block/Skull.php index 9c05649471..ae6abe8d57 100644 --- a/src/block/Skull.php +++ b/src/block/Skull.php @@ -29,7 +29,6 @@ use pocketmine\block\utils\SkullType; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\ItemIds; -use pocketmine\item\Skull as ItemSkull; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -137,9 +136,6 @@ class Skull extends Flowable{ } $this->facing = $face; - if($item instanceof ItemSkull){ - $this->skullType = $item->getSkullType(); //TODO: the item should handle this, but this hack is currently needed because of tile mess - } if($player !== null and $face === Facing::UP){ $this->rotation = ((int) floor(($player->getLocation()->getYaw() * 16 / 360) + 0.5)) & 0xf; } diff --git a/src/item/Bed.php b/src/item/Bed.php index 887ff6130a..c1251ac634 100644 --- a/src/item/Bed.php +++ b/src/item/Bed.php @@ -42,7 +42,7 @@ class Bed extends Item{ } public function getBlock(?int $clickedFace = null) : Block{ - return VanillaBlocks::BED(); + return VanillaBlocks::BED()->setColor($this->color); } public function getMaxStackSize() : int{ diff --git a/src/item/Skull.php b/src/item/Skull.php index 77f4b5f9ac..6e4a982038 100644 --- a/src/item/Skull.php +++ b/src/item/Skull.php @@ -38,7 +38,9 @@ class Skull extends Item{ } public function getBlock(?int $clickedFace = null) : Block{ - return VanillaBlocks::MOB_HEAD(); + //TODO: we ought to be able to represent this as a regular ItemBlock + //but that's not currently possible because the skulltype isn't part of the internal block runtimeID + return VanillaBlocks::MOB_HEAD()->setSkullType($this->skullType); } public function getSkullType() : SkullType{ From 91d54ff0ad1bb10f9caf197eaaf4e6e7bca6186b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 30 Jun 2021 19:16:25 +0100 Subject: [PATCH 2596/3224] Removed unnecessary and/or obsolete GC hacks the intent of these hacks was to break cyclic references to avoid having objects lingering in memory. However, all of the stuff that's being removed in this commit no longer has any effect anyway, due to the fact that these things don't circularly reference each other anymore. Notably, Tile inventories now keep Position instead of a Tile ref. --- src/block/tile/Barrel.php | 1 - src/block/tile/BrewingStand.php | 1 - src/block/tile/Chest.php | 2 -- src/block/tile/Furnace.php | 1 - src/block/tile/Hopper.php | 1 - src/block/tile/Tile.php | 1 - src/entity/Entity.php | 1 - src/world/World.php | 1 - tests/phpstan/configs/gc-hacks.neon | 40 ----------------------------- 9 files changed, 49 deletions(-) diff --git a/src/block/tile/Barrel.php b/src/block/tile/Barrel.php index ae8d6dfa8b..5b71f00f09 100644 --- a/src/block/tile/Barrel.php +++ b/src/block/tile/Barrel.php @@ -53,7 +53,6 @@ class Barrel extends Spawnable implements Container, Nameable{ public function close() : void{ if(!$this->closed){ $this->inventory->removeAllViewers(); - $this->inventory = null; parent::close(); } } diff --git a/src/block/tile/BrewingStand.php b/src/block/tile/BrewingStand.php index f10c47f79d..bccc10a279 100644 --- a/src/block/tile/BrewingStand.php +++ b/src/block/tile/BrewingStand.php @@ -90,7 +90,6 @@ class BrewingStand extends Spawnable implements Container, Nameable{ public function close() : void{ if(!$this->closed){ $this->inventory->removeAllViewers(); - $this->inventory = null; parent::close(); } diff --git a/src/block/tile/Chest.php b/src/block/tile/Chest.php index 40ba79cd58..f7c9b765ca 100644 --- a/src/block/tile/Chest.php +++ b/src/block/tile/Chest.php @@ -108,8 +108,6 @@ class Chest extends Spawnable implements Container, Nameable{ $this->doubleInventory = null; } - $this->inventory = null; - parent::close(); } } diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index 756e23ff9a..83f7ff1d87 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -98,7 +98,6 @@ class Furnace extends Spawnable implements Container, Nameable{ public function close() : void{ if(!$this->closed){ $this->inventory->removeAllViewers(); - $this->inventory = null; parent::close(); } diff --git a/src/block/tile/Hopper.php b/src/block/tile/Hopper.php index 6a0988dcf3..fe1501c157 100644 --- a/src/block/tile/Hopper.php +++ b/src/block/tile/Hopper.php @@ -63,7 +63,6 @@ class Hopper extends Spawnable implements Container, Nameable{ public function close() : void{ if(!$this->closed){ $this->inventory->removeAllViewers(); - $this->inventory = null; parent::close(); } diff --git a/src/block/tile/Tile.php b/src/block/tile/Tile.php index 59406a74ae..368c2f28b2 100644 --- a/src/block/tile/Tile.php +++ b/src/block/tile/Tile.php @@ -134,7 +134,6 @@ abstract class Tile{ if($this->pos->isValid()){ $this->pos->getWorld()->removeTile($this); } - $this->pos = null; } } } diff --git a/src/entity/Entity.php b/src/entity/Entity.php index a020c56d65..d123fd4464 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1587,7 +1587,6 @@ abstract class Entity{ * It is expected that the object is unusable after this is called. */ protected function destroyCycles() : void{ - $this->location = null; $this->lastDamageCause = null; } diff --git a/src/world/World.php b/src/world/World.php index 4bdcb7e40c..0f613fe036 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -521,7 +521,6 @@ class World implements ChunkManager{ $this->unregisterGenerator(); $this->provider->close(); - $this->provider = null; $this->blockCache = []; $this->unloaded = true; diff --git a/tests/phpstan/configs/gc-hacks.neon b/tests/phpstan/configs/gc-hacks.neon index adf69ad5db..4e854c21b2 100644 --- a/tests/phpstan/configs/gc-hacks.neon +++ b/tests/phpstan/configs/gc-hacks.neon @@ -1,40 +1,5 @@ parameters: ignoreErrors: - - - message: "#^Property pocketmine\\\\block\\\\tile\\\\Barrel\\:\\:\\$inventory \\(pocketmine\\\\block\\\\inventory\\\\BarrelInventory\\) does not accept null\\.$#" - count: 1 - path: ../../../src/block/tile/Barrel.php - - - - message: "#^Property pocketmine\\\\block\\\\tile\\\\BrewingStand\\:\\:\\$inventory \\(pocketmine\\\\block\\\\inventory\\\\BrewingStandInventory\\) does not accept null\\.$#" - count: 1 - path: ../../../src/block/tile/BrewingStand.php - - - - message: "#^Property pocketmine\\\\block\\\\tile\\\\Chest\\:\\:\\$inventory \\(pocketmine\\\\block\\\\inventory\\\\ChestInventory\\) does not accept null\\.$#" - count: 1 - path: ../../../src/block/tile/Chest.php - - - - message: "#^Property pocketmine\\\\block\\\\tile\\\\Furnace\\:\\:\\$inventory \\(pocketmine\\\\block\\\\inventory\\\\FurnaceInventory\\) does not accept null\\.$#" - count: 1 - path: ../../../src/block/tile/Furnace.php - - - - message: "#^Property pocketmine\\\\block\\\\tile\\\\Hopper\\:\\:\\$inventory \\(pocketmine\\\\block\\\\inventory\\\\HopperInventory\\) does not accept null\\.$#" - count: 1 - path: ../../../src/block/tile/Hopper.php - - - - message: "#^Property pocketmine\\\\block\\\\tile\\\\Tile\\:\\:\\$pos \\(pocketmine\\\\world\\\\Position\\) does not accept null\\.$#" - count: 1 - path: ../../../src/block/tile/Tile.php - - - - message: "#^Property pocketmine\\\\entity\\\\Entity\\:\\:\\$location \\(pocketmine\\\\entity\\\\Location\\) does not accept null\\.$#" - count: 1 - path: ../../../src/entity/Entity.php - - message: "#^Property pocketmine\\\\entity\\\\Human\\:\\:\\$enderInventory \\(pocketmine\\\\inventory\\\\PlayerEnderInventory\\) does not accept null\\.$#" count: 1 @@ -80,8 +45,3 @@ parameters: count: 1 path: ../../../src/player/Player.php - - - message: "#^Property pocketmine\\\\world\\\\World\\:\\:\\$provider \\(pocketmine\\\\world\\\\format\\\\io\\\\WritableWorldProvider\\) does not accept null\\.$#" - count: 1 - path: ../../../src/world/World.php - From 7a35fdb1bb55ee520483a4ce48d8edc283499164 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 30 Jun 2021 19:28:16 +0100 Subject: [PATCH 2597/3224] Allow Blocks to specify their max stack size --- src/block/BaseBanner.php | 4 ++++ src/block/BaseSign.php | 4 ++++ src/block/Block.php | 7 +++++++ src/item/Banner.php | 4 ---- src/item/ItemBlock.php | 4 ++++ src/item/ItemBlockWallOrFloor.php | 4 ++++ src/item/ItemFactory.php | 12 ++++++------ src/item/Sign.php | 31 ------------------------------- 8 files changed, 29 insertions(+), 41 deletions(-) delete mode 100644 src/item/Sign.php diff --git a/src/block/BaseBanner.php b/src/block/BaseBanner.php index c66458350a..9fa9a7550e 100644 --- a/src/block/BaseBanner.php +++ b/src/block/BaseBanner.php @@ -75,6 +75,10 @@ abstract class BaseBanner extends Transparent{ return false; } + public function getMaxStackSize() : int{ + return 16; + } + /** * @return BannerPatternLayer[] * @phpstan-return list diff --git a/src/block/BaseSign.php b/src/block/BaseSign.php index 8b8d72ae01..c2eedd1d06 100644 --- a/src/block/BaseSign.php +++ b/src/block/BaseSign.php @@ -68,6 +68,10 @@ abstract class BaseSign extends Transparent{ return false; } + public function getMaxStackSize() : int{ + return 16; + } + /** * @return AxisAlignedBB[] */ diff --git a/src/block/Block.php b/src/block/Block.php index 737bfd7c68..ad10e710df 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -439,6 +439,13 @@ class Block{ return 0; } + /** + * Returns the maximum number of this block that can fit into a single item stack. + */ + public function getMaxStackSize() : int{ + return 64; + } + /** * Returns the chance that the block will catch fire from nearby fire sources. Higher values lead to faster catching * fire. diff --git a/src/item/Banner.php b/src/item/Banner.php index 506af76203..18d0f1081c 100644 --- a/src/item/Banner.php +++ b/src/item/Banner.php @@ -66,10 +66,6 @@ class Banner extends ItemBlockWallOrFloor{ return DyeColorIdMap::getInstance()->toInvertedId($this->color); } - public function getMaxStackSize() : int{ - return 16; - } - /** * @return BannerPatternLayer[] * @phpstan-return list diff --git a/src/item/ItemBlock.php b/src/item/ItemBlock.php index 4e3941429d..0836d86e1c 100644 --- a/src/item/ItemBlock.php +++ b/src/item/ItemBlock.php @@ -45,4 +45,8 @@ class ItemBlock extends Item{ public function getFuelTime() : int{ return $this->getBlock()->getFuelTime(); } + + public function getMaxStackSize() : int{ + return $this->getBlock()->getMaxStackSize(); + } } diff --git a/src/item/ItemBlockWallOrFloor.php b/src/item/ItemBlockWallOrFloor.php index fa157c61a2..92a6afcf53 100644 --- a/src/item/ItemBlockWallOrFloor.php +++ b/src/item/ItemBlockWallOrFloor.php @@ -51,4 +51,8 @@ class ItemBlockWallOrFloor extends Item{ public function getFuelTime() : int{ return $this->getBlock()->getFuelTime(); } + + public function getMaxStackSize() : int{ + return $this->getBlock()->getMaxStackSize(); + } } diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 19f8b5c1af..1727b66484 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -240,12 +240,12 @@ class ItemFactory{ $this->register(new Redstone(new ItemIdentifier(ItemIds::REDSTONE, 0), "Redstone")); $this->register(new RottenFlesh(new ItemIdentifier(ItemIds::ROTTEN_FLESH, 0), "Rotten Flesh")); $this->register(new Shears(new ItemIdentifier(ItemIds::SHEARS, 0), "Shears")); - $this->register(new Sign(new ItemIdentifier(ItemIds::SIGN, 0), VanillaBlocks::OAK_SIGN(), VanillaBlocks::OAK_WALL_SIGN())); - $this->register(new Sign(new ItemIdentifier(ItemIds::SPRUCE_SIGN, 0), VanillaBlocks::SPRUCE_SIGN(), VanillaBlocks::SPRUCE_WALL_SIGN())); - $this->register(new Sign(new ItemIdentifier(ItemIds::BIRCH_SIGN, 0), VanillaBlocks::BIRCH_SIGN(), VanillaBlocks::BIRCH_WALL_SIGN())); - $this->register(new Sign(new ItemIdentifier(ItemIds::JUNGLE_SIGN, 0), VanillaBlocks::JUNGLE_SIGN(), VanillaBlocks::JUNGLE_WALL_SIGN())); - $this->register(new Sign(new ItemIdentifier(ItemIds::ACACIA_SIGN, 0), VanillaBlocks::ACACIA_SIGN(), VanillaBlocks::ACACIA_WALL_SIGN())); - $this->register(new Sign(new ItemIdentifier(ItemIds::DARKOAK_SIGN, 0), VanillaBlocks::DARK_OAK_SIGN(), VanillaBlocks::DARK_OAK_WALL_SIGN())); + $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::SIGN, 0), VanillaBlocks::OAK_SIGN(), VanillaBlocks::OAK_WALL_SIGN())); + $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::SPRUCE_SIGN, 0), VanillaBlocks::SPRUCE_SIGN(), VanillaBlocks::SPRUCE_WALL_SIGN())); + $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::BIRCH_SIGN, 0), VanillaBlocks::BIRCH_SIGN(), VanillaBlocks::BIRCH_WALL_SIGN())); + $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::JUNGLE_SIGN, 0), VanillaBlocks::JUNGLE_SIGN(), VanillaBlocks::JUNGLE_WALL_SIGN())); + $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::ACACIA_SIGN, 0), VanillaBlocks::ACACIA_SIGN(), VanillaBlocks::ACACIA_WALL_SIGN())); + $this->register(new ItemBlockWallOrFloor(new ItemIdentifier(ItemIds::DARKOAK_SIGN, 0), VanillaBlocks::DARK_OAK_SIGN(), VanillaBlocks::DARK_OAK_WALL_SIGN())); $this->register(new Snowball(new ItemIdentifier(ItemIds::SNOWBALL, 0), "Snowball")); $this->register(new SpiderEye(new ItemIdentifier(ItemIds::SPIDER_EYE, 0), "Spider Eye")); $this->register(new Steak(new ItemIdentifier(ItemIds::STEAK, 0), "Steak")); diff --git a/src/item/Sign.php b/src/item/Sign.php deleted file mode 100644 index f95240e371..0000000000 --- a/src/item/Sign.php +++ /dev/null @@ -1,31 +0,0 @@ - Date: Wed, 30 Jun 2021 19:47:11 +0100 Subject: [PATCH 2598/3224] BlockBreakInfo: Expose hardness multipliers as constants --- src/block/BlockBreakInfo.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/block/BlockBreakInfo.php b/src/block/BlockBreakInfo.php index 6d44f88202..0290b02ab2 100644 --- a/src/block/BlockBreakInfo.php +++ b/src/block/BlockBreakInfo.php @@ -27,6 +27,16 @@ use pocketmine\item\Item; use function get_class; class BlockBreakInfo{ + /** + * If the tool is the correct type and high enough harvest level (tool tier), base break time is hardness multiplied + * by this value. + */ + public const COMPATIBLE_TOOL_MULTIPLIER = 1.5; + /** + * If the tool is an incorrect type or too low harvest level (tool tier), base break time is hardness multiplied by + * this value. + */ + public const INCOMPATIBLE_TOOL_MULTIPLIER = 5.0; private float $hardness; private float $blastResistance; @@ -121,9 +131,9 @@ class BlockBreakInfo{ public function getBreakTime(Item $item) : float{ $base = $this->hardness; if($this->isToolCompatible($item)){ - $base *= 1.5; + $base *= self::COMPATIBLE_TOOL_MULTIPLIER; }else{ - $base *= 5; + $base *= self::INCOMPATIBLE_TOOL_MULTIPLIER; } $efficiency = $item->getMiningEfficiency(($this->toolType & $item->getBlockToolType()) !== 0); From b7ea10b9052ceea0d849effdb9e9dbba6f7109f2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 5 Jul 2021 19:20:59 +0100 Subject: [PATCH 2599/3224] MainLogger: do not assume that exception codes are always integers PDOException most notably breaks this rule. closes #4294 --- src/CrashDump.php | 1 + src/utils/MainLogger.php | 11 +++++++---- .../configs/check-explicit-mixed-baseline.neon | 5 ----- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/CrashDump.php b/src/CrashDump.php index e6f72de5f7..5536116087 100644 --- a/src/CrashDump.php +++ b/src/CrashDump.php @@ -44,6 +44,7 @@ use function fwrite; use function get_loaded_extensions; use function implode; use function is_dir; +use function is_int; use function is_resource; use function json_encode; use function json_last_error_msg; diff --git a/src/utils/MainLogger.php b/src/utils/MainLogger.php index f2c1ae1605..ebce6012ed 100644 --- a/src/utils/MainLogger.php +++ b/src/utils/MainLogger.php @@ -28,6 +28,7 @@ use pocketmine\errorhandler\ErrorTypeToStringMap; use pocketmine\thread\Thread; use pocketmine\thread\Worker; use function get_class; +use function is_int; use function preg_replace; use function sprintf; use function trim; @@ -159,10 +160,12 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ $errstr = preg_replace('/\s+/', ' ', trim($e->getMessage())); $errno = $e->getCode(); - try{ - $errno = ErrorTypeToStringMap::get($errno); - }catch(\InvalidArgumentException $ex){ - //pass + if(is_int($errno)){ + try{ + $errno = ErrorTypeToStringMap::get($errno); + }catch(\InvalidArgumentException $ex){ + //pass + } } $errfile = Filesystem::cleanPath($e->getFile()); diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index f439301715..c5c875fb52 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -205,11 +205,6 @@ parameters: count: 1 path: ../../../src/utils/Internet.php - - - message: "#^Parameter \\#1 \\$errorType of static method pocketmine\\\\errorhandler\\\\ErrorTypeToStringMap\\:\\:get\\(\\) expects int, mixed given\\.$#" - count: 1 - path: ../../../src/utils/MainLogger.php - - message: "#^Part \\$errno \\(mixed\\) of encapsed string cannot be cast to string\\.$#" count: 1 From 5130a3233317306ec47cb37cd860b5640230b86a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 5 Jul 2021 20:00:24 +0100 Subject: [PATCH 2600/3224] GameMode: removed dead property (leftover from 902ea515f7f83a4785197c0bfe5b813acb684f7d) --- src/player/GameMode.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/player/GameMode.php b/src/player/GameMode.php index a41963008a..97eb21d955 100644 --- a/src/player/GameMode.php +++ b/src/player/GameMode.php @@ -66,8 +66,6 @@ final class GameMode{ return self::$aliasMap[mb_strtolower($str)] ?? null; } - /** @var int */ - private $magicNumber; /** @var string */ private $englishName; /** @var string */ From 605e26d584ae5d47f18031f6cd3b6d8084ff6880 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 5 Jul 2021 20:03:11 +0100 Subject: [PATCH 2601/3224] remove unused import --- src/CrashDump.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/CrashDump.php b/src/CrashDump.php index 5536116087..e6f72de5f7 100644 --- a/src/CrashDump.php +++ b/src/CrashDump.php @@ -44,7 +44,6 @@ use function fwrite; use function get_loaded_extensions; use function implode; use function is_dir; -use function is_int; use function is_resource; use function json_encode; use function json_last_error_msg; From 4e731f61afe6a565bf5ad051f145861b357b0f17 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 8 Jul 2021 20:34:14 +0100 Subject: [PATCH 2602/3224] BlockFactory: Remap double slab IDs with 0x8 bit set to their base DOUBLE state, instead of BOTTOM this was causing problems with slabs in converted Java worlds, where the 0x8 bit means 'smooth', instead of 'double'. In MCPE it has no effect. Since Slab doesn't retain the high/low flag for DOUBLE type slabs, this caused BlockFactory to assume that those states were invalid, and remapped them to their base state instead. The following changes resulted in the consistency check: Remap changed for 43:8 (44:0 (Smooth Stone Slab) -> 43:0 (Smooth Stone Slab)) Remap changed for 43:9 (44:1 (Sandstone Slab) -> 43:1 (Sandstone Slab)) Remap changed for 43:10 (44:2 (Fake Wooden Slab) -> 43:2 (Fake Wooden Slab)) Remap changed for 43:11 (44:3 (Cobblestone Slab) -> 43:3 (Cobblestone Slab)) Remap changed for 43:12 (44:4 (Brick Slab) -> 43:4 (Brick Slab)) Remap changed for 43:13 (44:5 (Stone Brick Slab) -> 43:5 (Stone Brick Slab)) Remap changed for 43:14 (44:6 (Quartz Slab) -> 43:6 (Quartz Slab)) Remap changed for 43:15 (44:7 (Nether Brick Slab) -> 43:7 (Nether Brick Slab)) Remap changed for 157:8 (158:0 (Oak Slab) -> 157:0 (Oak Slab)) Remap changed for 157:9 (158:1 (Spruce Slab) -> 157:1 (Spruce Slab)) Remap changed for 157:10 (158:2 (Birch Slab) -> 157:2 (Birch Slab)) Remap changed for 157:11 (158:3 (Jungle Slab) -> 157:3 (Jungle Slab)) Remap changed for 157:12 (158:4 (Acacia Slab) -> 157:4 (Acacia Slab)) Remap changed for 157:13 (158:5 (Dark Oak Slab) -> 157:5 (Dark Oak Slab)) Remap changed for 181:8 (182:0 (Red Sandstone Slab) -> 181:0 (Red Sandstone Slab)) Remap changed for 181:9 (182:1 (Purpur Slab) -> 181:1 (Purpur Slab)) Remap changed for 181:10 (182:2 (Prismarine Slab) -> 181:2 (Prismarine Slab)) Remap changed for 181:11 (182:3 (Dark Prismarine Slab) -> 181:3 (Dark Prismarine Slab)) Remap changed for 181:12 (182:4 (Prismarine Bricks Slab) -> 181:4 (Prismarine Bricks Slab)) Remap changed for 181:13 (182:5 (Mossy Cobblestone Slab) -> 181:5 (Mossy Cobblestone Slab)) Remap changed for 181:14 (182:6 (Smooth Sandstone Slab) -> 181:6 (Smooth Sandstone Slab)) Remap changed for 181:15 (182:7 (Red Nether Brick Slab) -> 181:7 (Red Nether Brick Slab)) Remap changed for 422:8 (417:0 (End Stone Brick Slab) -> 422:0 (End Stone Brick Slab)) Remap changed for 422:9 (417:1 (Smooth Red Sandstone Slab) -> 422:1 (Smooth Red Sandstone Slab)) Remap changed for 422:10 (417:2 (Polished Andesite Slab) -> 422:2 (Polished Andesite Slab)) Remap changed for 422:11 (417:3 (Andesite Slab) -> 422:3 (Andesite Slab)) Remap changed for 422:12 (417:4 (Diorite Slab) -> 422:4 (Diorite Slab)) Remap changed for 422:13 (417:5 (Polished Diorite Slab) -> 422:5 (Polished Diorite Slab)) Remap changed for 422:14 (417:6 (Granite Slab) -> 422:6 (Granite Slab)) Remap changed for 422:15 (417:7 (Polished Granite Slab) -> 422:7 (Polished Granite Slab)) Remap changed for 423:8 (421:0 (Mossy Stone Brick Slab) -> 423:0 (Mossy Stone Brick Slab)) Remap changed for 423:9 (421:1 (Smooth Quartz Slab) -> 423:1 (Smooth Quartz Slab)) Remap changed for 423:10 (421:2 (Stone Slab) -> 423:2 (Stone Slab)) Remap changed for 423:11 (421:3 (Cut Sandstone Slab) -> 423:3 (Cut Sandstone Slab)) Remap changed for 423:12 (421:4 (Cut Red Sandstone Slab) -> 423:4 (Cut Red Sandstone Slab)) --- src/block/BlockFactory.php | 69 +++++++++++-------- .../block_factory_consistency_check.json | 2 +- 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 2b607636f4..be3cbc8eea 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -47,6 +47,7 @@ use pocketmine\block\tile\Note as TileNote; use pocketmine\block\tile\Skull as TileSkull; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\InvalidBlockStateException; +use pocketmine\block\utils\SlabType; use pocketmine\block\utils\TreeType; use pocketmine\item\Item; use pocketmine\item\ItemIds; @@ -356,35 +357,35 @@ class BlockFactory{ //TODO: in the future this won't be the same for all the types $stoneSlabBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_BRICK), "Brick", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_COBBLESTONE), "Cobblestone", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_FAKE_WOODEN), "Fake Wooden", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_NETHER_BRICK), "Nether Brick", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_QUARTZ), "Quartz", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_SANDSTONE), "Sandstone", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_SMOOTH_STONE), "Smooth Stone", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_STONE_BRICK), "Stone Brick", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_DARK_PRISMARINE), "Dark Prismarine", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_MOSSY_COBBLESTONE), "Mossy Cobblestone", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_PRISMARINE), "Prismarine", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_PRISMARINE_BRICKS), "Prismarine Bricks", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_PURPUR), "Purpur", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_RED_NETHER_BRICK), "Red Nether Brick", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_RED_SANDSTONE), "Red Sandstone", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_SMOOTH_SANDSTONE), "Smooth Sandstone", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_ANDESITE), "Andesite", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_DIORITE), "Diorite", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_END_STONE_BRICK), "End Stone Brick", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_GRANITE), "Granite", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_POLISHED_ANDESITE), "Polished Andesite", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_POLISHED_DIORITE), "Polished Diorite", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_POLISHED_GRANITE), "Polished Granite", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_SMOOTH_RED_SANDSTONE), "Smooth Red Sandstone", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_CUT_RED_SANDSTONE), "Cut Red Sandstone", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_CUT_SANDSTONE), "Cut Sandstone", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_MOSSY_STONE_BRICK), "Mossy Stone Brick", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_SMOOTH_QUARTZ), "Smooth Quartz", $stoneSlabBreakInfo)); - $this->register(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_STONE), "Stone", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_BRICK), "Brick", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_COBBLESTONE), "Cobblestone", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_FAKE_WOODEN), "Fake Wooden", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_NETHER_BRICK), "Nether Brick", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_QUARTZ), "Quartz", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_SANDSTONE), "Sandstone", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_SMOOTH_STONE), "Smooth Stone", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(1, Meta::STONE_SLAB_STONE_BRICK), "Stone Brick", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_DARK_PRISMARINE), "Dark Prismarine", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_MOSSY_COBBLESTONE), "Mossy Cobblestone", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_PRISMARINE), "Prismarine", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_PRISMARINE_BRICKS), "Prismarine Bricks", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_PURPUR), "Purpur", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_RED_NETHER_BRICK), "Red Nether Brick", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_RED_SANDSTONE), "Red Sandstone", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(2, Meta::STONE_SLAB2_SMOOTH_SANDSTONE), "Smooth Sandstone", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_ANDESITE), "Andesite", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_DIORITE), "Diorite", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_END_STONE_BRICK), "End Stone Brick", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_GRANITE), "Granite", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_POLISHED_ANDESITE), "Polished Andesite", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_POLISHED_DIORITE), "Polished Diorite", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_POLISHED_GRANITE), "Polished Granite", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(3, Meta::STONE_SLAB3_SMOOTH_RED_SANDSTONE), "Smooth Red Sandstone", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_CUT_RED_SANDSTONE), "Cut Red Sandstone", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_CUT_SANDSTONE), "Cut Sandstone", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_MOSSY_STONE_BRICK), "Mossy Stone Brick", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_SMOOTH_QUARTZ), "Smooth Quartz", $stoneSlabBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_STONE), "Stone", $stoneSlabBreakInfo)); $this->register(new Opaque(new BID(Ids::STONECUTTER, 0), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); $this->register(new Sugarcane(new BID(Ids::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane", BlockBreakInfo::instant())); $this->register(new TNT(new BID(Ids::TNT, 0), "TNT", BlockBreakInfo::instant())); @@ -425,7 +426,7 @@ class BlockFactory{ $this->register(new Planks(new BID(Ids::PLANKS, $magicNumber), $name . " Planks", $planksBreakInfo)); $this->register(new Sapling(new BID(Ids::SAPLING, $magicNumber), $name . " Sapling", BlockBreakInfo::instant(), $treeType)); $this->register(new WoodenFence(new BID(Ids::FENCE, $magicNumber), $name . " Fence", $planksBreakInfo)); - $this->register(new WoodenSlab(new BIDFlattened(Ids::WOODEN_SLAB, [Ids::DOUBLE_WOODEN_SLAB], $magicNumber), $name, $planksBreakInfo)); + $this->registerSlabWithDoubleHighBitsRemapping(new WoodenSlab(new BIDFlattened(Ids::WOODEN_SLAB, [Ids::DOUBLE_WOODEN_SLAB], $magicNumber), $name, $planksBreakInfo)); //TODO: find a better way to deal with this split $this->register(new Leaves(new BID($magicNumber >= 4 ? Ids::LEAVES2 : Ids::LEAVES, $magicNumber & 0x03), $name . " Leaves", $leavesBreakInfo, $treeType)); @@ -854,6 +855,14 @@ class BlockFactory{ $this->register(new Element(new BID(Ids::ELEMENT_118, 0), "Oganesson", $instaBreak, "og", 118, 7)); } + private function registerSlabWithDoubleHighBitsRemapping(Slab $block) : void{ + $this->register($block); + $identifierFlattened = $block->getIdInfo(); + if($identifierFlattened instanceof BlockIdentifierFlattened){ + $this->remap($identifierFlattened->getSecondId(), $identifierFlattened->getVariant() | 0x8, $block->setSlabType(SlabType::DOUBLE())); + } + } + /** * Maps a block type to its corresponding ID. This is necessary to ensure that the block is correctly loaded when * reading from disk storage. diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index f47e13a024..1b6273747d 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"knownStates":{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","497":"Tall Grass","498":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1614":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6274":"Wall Coral Fan","6276":"Wall Coral Fan","6278":"Wall Coral Fan","6280":"Wall Coral Fan","6282":"Wall Coral Fan","6284":"Wall Coral Fan","6286":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood","7480":"Stripped Oak Wood","7481":"Stripped Spruce Wood","7482":"Stripped Birch Wood","7483":"Stripped Jungle Wood","7484":"Stripped Acacia Wood","7485":"Stripped Dark Oak Wood"},"remaps":{"284":7472,"285":7473,"286":7474,"287":7475,"438":432,"439":432,"446":432,"447":432,"454":448,"455":448,"462":448,"463":448,"496":498,"499":498,"696":704,"697":705,"698":706,"699":707,"700":708,"701":709,"702":710,"703":711,"800":805,"806":805,"807":805,"864":866,"865":866,"870":866,"871":866,"976":978,"977":978,"982":978,"983":978,"992":978,"993":978,"998":978,"999":978,"1036":1027,"1037":1027,"1038":1027,"1039":1027,"1040":1042,"1041":1042,"1046":1042,"1047":1042,"1066":1056,"1067":1056,"1068":1056,"1069":1056,"1070":1056,"1071":1056,"1088":1090,"1089":1090,"1094":1090,"1095":1090,"1148":1139,"1149":1139,"1150":1139,"1151":1139,"1200":1221,"1206":1221,"1207":1221,"1216":1221,"1222":1221,"1223":1221,"1238":1232,"1239":1232,"1246":1232,"1247":1232,"1377":1376,"1378":1376,"1379":1376,"1440":1441,"1443":1441,"1479":1472,"1595":1598,"1596":1598,"1597":1598,"1610":1594,"1611":1614,"1612":1614,"1613":1614,"1615":1599,"2022":2016,"2023":2016,"2030":2016,"2031":2016,"2044":2032,"2045":2032,"2046":2032,"2047":2032,"2080":2082,"2081":2082,"2086":2082,"2087":2082,"2242":2240,"2243":2240,"2244":2240,"2245":2240,"2246":2240,"2247":2240,"2248":2240,"2249":2240,"2250":2240,"2251":2240,"2252":2240,"2253":2240,"2254":2240,"2255":2240,"2294":2288,"2295":2288,"2302":2288,"2303":2288,"2304":2306,"2310":2306,"2311":2306,"2312":2306,"2313":2306,"2314":2306,"2315":2306,"2316":2306,"2317":2306,"2318":2306,"2319":2306,"2332":2322,"2333":2322,"2334":2322,"2335":2322,"2336":2338,"2337":2338,"2342":2338,"2343":2338,"2392":2386,"2393":2386,"2394":2386,"2395":2386,"2396":2386,"2397":2386,"2398":2386,"2399":2386,"2400":2386,"2401":2386,"2402":2386,"2403":2386,"2404":2386,"2405":2386,"2406":2386,"2407":2386,"2465":2464,"2470":2464,"2471":2464,"2473":2464,"2478":2464,"2479":2464,"2493":2481,"2494":2482,"2520":2528,"2521":2529,"2522":2530,"2523":2531,"2524":2532,"2525":2533,"2604":7476,"2605":7477,"2732":2720,"2832":2834,"2833":2834,"2838":2834,"2839":2834,"2904":2912,"2905":2913,"2906":2914,"2907":2915,"2908":2916,"2909":2917,"2910":2918,"2911":2919,"3100":3091,"3101":3091,"3102":3091,"3103":3091,"3116":3107,"3117":3107,"3118":3107,"3119":3107,"3132":3123,"3133":3123,"3134":3123,"3135":3123,"3148":3139,"3149":3139,"3150":3139,"3151":3139,"3164":3155,"3165":3155,"3166":3155,"3167":3155,"3230":3218,"3232":3237,"3238":3237,"3239":3237,"3240":3245,"3246":3245,"3247":3245,"3264":3269,"3270":3269,"3271":3269,"3272":3277,"3278":3277,"3279":3277,"3334":3328,"3335":3328,"3468":3456,"3504":3506,"3505":3506,"3510":3506,"3511":3506,"3520":3522,"3521":3522,"3526":3522,"3527":3522,"3536":3538,"3537":3538,"3542":3538,"3543":3538,"3552":3554,"3553":3554,"3558":3554,"3559":3554,"3568":3570,"3569":3570,"3574":3570,"3575":3570,"3584":3586,"3585":3586,"3590":3586,"3591":3586,"3600":3602,"3601":3602,"3606":3602,"3607":3602,"3616":3618,"3617":3618,"3622":3618,"3623":3618,"3632":3634,"3633":3634,"3638":3634,"3639":3634,"3648":3650,"3649":3650,"3654":3650,"3655":3650,"3664":3666,"3665":3666,"3670":3666,"3671":3666,"3696":3698,"3697":3698,"3702":3698,"3703":3698,"3712":3714,"3713":3714,"3718":3714,"3719":3714,"3728":3730,"3729":3730,"3734":3730,"3735":3730,"3744":3746,"3745":3746,"3750":3746,"3751":3746,"3760":3762,"3761":3762,"3766":3762,"3767":3762,"3824":3829,"3830":3829,"3831":3829,"3955":3952,"4163":4160,"4179":4176,"4195":4192,"4211":4208,"4227":4224,"4243":4240,"6181":6176,"6182":6176,"6183":6176,"6197":6192,"6198":6192,"6199":6192,"6205":6192,"6206":6192,"6207":6192,"6213":6208,"6214":6208,"6215":6208,"6221":6208,"6222":6208,"6223":6208,"6229":6208,"6230":6208,"6231":6208,"6237":6208,"6238":6208,"6239":6208,"6273":6248,"6275":6248,"6277":6248,"6279":6248,"6281":6248,"6283":6248,"6285":6248,"6287":6248,"6326":6320,"6327":6320,"6334":6320,"6335":6320,"6342":6336,"6343":6336,"6350":6336,"6351":6336,"6358":6352,"6359":6352,"6366":6352,"6367":6352,"6374":6368,"6375":6368,"6382":6368,"6383":6368,"6390":6384,"6391":6384,"6398":6384,"6399":6384,"6694":6688,"6695":6688,"6702":6688,"6703":6688,"6760":6672,"6761":6673,"6762":6674,"6763":6675,"6764":6676,"6765":6677,"6766":6678,"6767":6679,"6776":6736,"6777":6737,"6778":6738,"6779":6739,"6780":6740,"6992":6994,"6993":6994,"6998":6994,"6999":6994,"7072":7074,"7073":7074,"7078":7074,"7079":7074,"7104":7106,"7105":7106,"7110":7106,"7111":7106,"7136":7138,"7137":7138,"7142":7138,"7143":7138,"7168":7170,"7169":7170,"7174":7170,"7175":7170,"7334":7328,"7335":7328,"7342":7328,"7343":7328}} \ No newline at end of file +{"knownStates":{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","497":"Tall Grass","498":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1614":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6274":"Wall Coral Fan","6276":"Wall Coral Fan","6278":"Wall Coral Fan","6280":"Wall Coral Fan","6282":"Wall Coral Fan","6284":"Wall Coral Fan","6286":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood","7480":"Stripped Oak Wood","7481":"Stripped Spruce Wood","7482":"Stripped Birch Wood","7483":"Stripped Jungle Wood","7484":"Stripped Acacia Wood","7485":"Stripped Dark Oak Wood"},"remaps":{"284":7472,"285":7473,"286":7474,"287":7475,"438":432,"439":432,"446":432,"447":432,"454":448,"455":448,"462":448,"463":448,"496":498,"499":498,"696":688,"697":689,"698":690,"699":691,"700":692,"701":693,"702":694,"703":695,"800":805,"806":805,"807":805,"864":866,"865":866,"870":866,"871":866,"976":978,"977":978,"982":978,"983":978,"992":978,"993":978,"998":978,"999":978,"1036":1027,"1037":1027,"1038":1027,"1039":1027,"1040":1042,"1041":1042,"1046":1042,"1047":1042,"1066":1056,"1067":1056,"1068":1056,"1069":1056,"1070":1056,"1071":1056,"1088":1090,"1089":1090,"1094":1090,"1095":1090,"1148":1139,"1149":1139,"1150":1139,"1151":1139,"1200":1221,"1206":1221,"1207":1221,"1216":1221,"1222":1221,"1223":1221,"1238":1232,"1239":1232,"1246":1232,"1247":1232,"1377":1376,"1378":1376,"1379":1376,"1440":1441,"1443":1441,"1479":1472,"1595":1598,"1596":1598,"1597":1598,"1610":1594,"1611":1614,"1612":1614,"1613":1614,"1615":1599,"2022":2016,"2023":2016,"2030":2016,"2031":2016,"2044":2032,"2045":2032,"2046":2032,"2047":2032,"2080":2082,"2081":2082,"2086":2082,"2087":2082,"2242":2240,"2243":2240,"2244":2240,"2245":2240,"2246":2240,"2247":2240,"2248":2240,"2249":2240,"2250":2240,"2251":2240,"2252":2240,"2253":2240,"2254":2240,"2255":2240,"2294":2288,"2295":2288,"2302":2288,"2303":2288,"2304":2306,"2310":2306,"2311":2306,"2312":2306,"2313":2306,"2314":2306,"2315":2306,"2316":2306,"2317":2306,"2318":2306,"2319":2306,"2332":2322,"2333":2322,"2334":2322,"2335":2322,"2336":2338,"2337":2338,"2342":2338,"2343":2338,"2392":2386,"2393":2386,"2394":2386,"2395":2386,"2396":2386,"2397":2386,"2398":2386,"2399":2386,"2400":2386,"2401":2386,"2402":2386,"2403":2386,"2404":2386,"2405":2386,"2406":2386,"2407":2386,"2465":2464,"2470":2464,"2471":2464,"2473":2464,"2478":2464,"2479":2464,"2493":2481,"2494":2482,"2520":2512,"2521":2513,"2522":2514,"2523":2515,"2524":2516,"2525":2517,"2604":7476,"2605":7477,"2732":2720,"2832":2834,"2833":2834,"2838":2834,"2839":2834,"2904":2896,"2905":2897,"2906":2898,"2907":2899,"2908":2900,"2909":2901,"2910":2902,"2911":2903,"3100":3091,"3101":3091,"3102":3091,"3103":3091,"3116":3107,"3117":3107,"3118":3107,"3119":3107,"3132":3123,"3133":3123,"3134":3123,"3135":3123,"3148":3139,"3149":3139,"3150":3139,"3151":3139,"3164":3155,"3165":3155,"3166":3155,"3167":3155,"3230":3218,"3232":3237,"3238":3237,"3239":3237,"3240":3245,"3246":3245,"3247":3245,"3264":3269,"3270":3269,"3271":3269,"3272":3277,"3278":3277,"3279":3277,"3334":3328,"3335":3328,"3468":3456,"3504":3506,"3505":3506,"3510":3506,"3511":3506,"3520":3522,"3521":3522,"3526":3522,"3527":3522,"3536":3538,"3537":3538,"3542":3538,"3543":3538,"3552":3554,"3553":3554,"3558":3554,"3559":3554,"3568":3570,"3569":3570,"3574":3570,"3575":3570,"3584":3586,"3585":3586,"3590":3586,"3591":3586,"3600":3602,"3601":3602,"3606":3602,"3607":3602,"3616":3618,"3617":3618,"3622":3618,"3623":3618,"3632":3634,"3633":3634,"3638":3634,"3639":3634,"3648":3650,"3649":3650,"3654":3650,"3655":3650,"3664":3666,"3665":3666,"3670":3666,"3671":3666,"3696":3698,"3697":3698,"3702":3698,"3703":3698,"3712":3714,"3713":3714,"3718":3714,"3719":3714,"3728":3730,"3729":3730,"3734":3730,"3735":3730,"3744":3746,"3745":3746,"3750":3746,"3751":3746,"3760":3762,"3761":3762,"3766":3762,"3767":3762,"3824":3829,"3830":3829,"3831":3829,"3955":3952,"4163":4160,"4179":4176,"4195":4192,"4211":4208,"4227":4224,"4243":4240,"6181":6176,"6182":6176,"6183":6176,"6197":6192,"6198":6192,"6199":6192,"6205":6192,"6206":6192,"6207":6192,"6213":6208,"6214":6208,"6215":6208,"6221":6208,"6222":6208,"6223":6208,"6229":6208,"6230":6208,"6231":6208,"6237":6208,"6238":6208,"6239":6208,"6273":6248,"6275":6248,"6277":6248,"6279":6248,"6281":6248,"6283":6248,"6285":6248,"6287":6248,"6326":6320,"6327":6320,"6334":6320,"6335":6320,"6342":6336,"6343":6336,"6350":6336,"6351":6336,"6358":6352,"6359":6352,"6366":6352,"6367":6352,"6374":6368,"6375":6368,"6382":6368,"6383":6368,"6390":6384,"6391":6384,"6398":6384,"6399":6384,"6694":6688,"6695":6688,"6702":6688,"6703":6688,"6760":6752,"6761":6753,"6762":6754,"6763":6755,"6764":6756,"6765":6757,"6766":6758,"6767":6759,"6776":6768,"6777":6769,"6778":6770,"6779":6771,"6780":6772,"6992":6994,"6993":6994,"6998":6994,"6999":6994,"7072":7074,"7073":7074,"7078":7074,"7079":7074,"7104":7106,"7105":7106,"7110":7106,"7111":7106,"7136":7138,"7137":7138,"7142":7138,"7143":7138,"7168":7170,"7169":7170,"7174":7170,"7175":7170,"7334":7328,"7335":7328,"7342":7328,"7343":7328}} \ No newline at end of file From 9d1b2c839d41702ccab788182c3f24a451156092 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 9 Jul 2021 19:39:15 +0100 Subject: [PATCH 2603/3224] this managed to get lost in the merge --- src/network/mcpe/handler/InGamePacketHandler.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 21509067bb..9958658b62 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -351,6 +351,8 @@ class InGamePacketHandler extends PacketHandler{ } private function handleUseItemTransaction(UseItemTransactionData $data) : bool{ + $this->player->selectHotbarSlot($data->getHotbarSlot()); + switch($data->getActionType()){ case UseItemTransactionData::ACTION_CLICK_BLOCK: //TODO: start hack for client spam bug @@ -435,6 +437,8 @@ class InGamePacketHandler extends PacketHandler{ return false; } + $this->player->selectHotbarSlot($data->getHotbarSlot()); + //TODO: use transactiondata for rollbacks here switch($data->getActionType()){ case UseItemOnEntityTransactionData::ACTION_INTERACT: @@ -453,6 +457,8 @@ class InGamePacketHandler extends PacketHandler{ } private function handleReleaseItemTransaction(ReleaseItemTransactionData $data) : bool{ + $this->player->selectHotbarSlot($data->getHotbarSlot()); + //TODO: use transactiondata for rollbacks here (resending entire inventory is very wasteful) switch($data->getActionType()){ case ReleaseItemTransactionData::ACTION_RELEASE: From 3997e612b19eaaab4be143360e63afb070bbdce0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 9 Jul 2021 19:44:25 +0100 Subject: [PATCH 2604/3224] silence phpstan bug phpstan/phpstan#5271 --- tests/phpstan/configs/phpstan-bugs.neon | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 7d22109867..48a613645c 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -1,5 +1,10 @@ parameters: ignoreErrors: + - + message: "#^Instanceof between pocketmine\\\\block\\\\utils\\\\BannerPatternLayer and pocketmine\\\\block\\\\utils\\\\BannerPatternLayer will always evaluate to true\\.$#" + count: 1 + path: ../../../src/block/BaseBanner.php + - message: "#^Call to function is_resource\\(\\) with resource will always evaluate to true\\.$#" count: 2 From fc090e238dc13ef9d6de5c20593b32aceb5ba1f2 Mon Sep 17 00:00:00 2001 From: Aericio <16523741+Aericio@users.noreply.github.com> Date: Sat, 10 Jul 2021 08:48:38 -1000 Subject: [PATCH 2605/3224] Add Shulker Boxes (#3678) this implementation is working, although incomplete: - The shulker close sound should not be played until the end of the shulker closing animation, which takes approximately 1 second. - An open shulker box has a different collision box than a closed one - it should be +0.5 in whichever direction the shulker is facing. (During the animation, the bounding box also dynamically changes size - you can see this in vanilla by shooting an arrow into the top of an open shulkerbox facing UP, and then closing it - the arrow will fall and collide with the lid multiple times. However, resolving both of these issues requires significant internal changes which are beyond the scope of this PR. --- src/block/BlockFactory.php | 6 +- src/block/DyedShulkerBox.php | 36 ++++++ src/block/ShulkerBox.php | 95 ++++++++++++++ src/block/VanillaBlocks.php | 4 + src/block/inventory/ShulkerBoxInventory.php | 64 ++++++++++ src/block/tile/ShulkerBox.php | 120 ++++++++++++++++++ src/block/tile/TileFactory.php | 2 +- src/world/sound/ShulkerCloseSound.php | 34 +++++ src/world/sound/ShulkerOpenSound.php | 34 +++++ .../block_factory_consistency_check.json | 2 +- 10 files changed, 393 insertions(+), 4 deletions(-) create mode 100644 src/block/DyedShulkerBox.php create mode 100644 src/block/ShulkerBox.php create mode 100644 src/block/inventory/ShulkerBoxInventory.php create mode 100644 src/block/tile/ShulkerBox.php create mode 100644 src/world/sound/ShulkerCloseSound.php create mode 100644 src/world/sound/ShulkerOpenSound.php diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index be3cbc8eea..69f11dbb1a 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -44,6 +44,7 @@ use pocketmine\block\tile\ItemFrame as TileItemFrame; use pocketmine\block\tile\Jukebox as TileJukebox; use pocketmine\block\tile\MonsterSpawner as TileMonsterSpawner; use pocketmine\block\tile\Note as TileNote; +use pocketmine\block\tile\ShulkerBox as TileShulkerBox; use pocketmine\block\tile\Skull as TileSkull; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\InvalidBlockStateException; @@ -316,6 +317,8 @@ class BlockFactory{ $this->register(new SnowLayer(new BID(Ids::SNOW_LAYER, 0), "Snow Layer", new BlockBreakInfo(0.1, BlockToolType::SHOVEL, ToolTier::WOOD()->getHarvestLevel()))); $this->register(new SoulSand(new BID(Ids::SOUL_SAND, 0), "Soul Sand", new BlockBreakInfo(0.5, BlockToolType::SHOVEL))); $this->register(new Sponge(new BID(Ids::SPONGE, 0), "Sponge", new BlockBreakInfo(0.6, BlockToolType::HOE))); + $shulkerBoxBreakInfo = new BlockBreakInfo(2, BlockToolType::PICKAXE); + $this->register(new ShulkerBox(new BID(Ids::UNDYED_SHULKER_BOX, 0, null, TileShulkerBox::class), "Shulker Box", $shulkerBoxBreakInfo)); $stoneBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); $this->register($stone = new class(new BID(Ids::STONE, Meta::STONE_NORMAL), "Stone", $stoneBreakInfo) extends Opaque{ @@ -473,6 +476,7 @@ class BlockFactory{ }; $this->register(new GlazedTerracotta(BlockLegacyIdHelper::getGlazedTerracottaIdentifier($color), $coloredName("Glazed Terracotta"), $glazedTerracottaBreakInfo)); } + $this->register(new DyedShulkerBox(new BID(Ids::SHULKER_BOX, 0, null, TileShulkerBox::class), "Dyed Shulker Box", $shulkerBoxBreakInfo)); $this->register(new StainedGlass(new BID(Ids::STAINED_GLASS, 0), "Stained Glass", $glassBreakInfo)); $this->register(new StainedGlassPane(new BID(Ids::STAINED_GLASS_PANE, 0), "Stained Glass Pane", $glassBreakInfo)); $this->register(new StainedHardenedClay(new BID(Ids::STAINED_CLAY, 0), "Stained Clay", $hardenedClayBreakInfo)); @@ -569,7 +573,6 @@ class BlockFactory{ //TODO: minecraft:repeating_command_block //TODO: minecraft:scaffolding //TODO: minecraft:seagrass - //TODO: minecraft:shulker_box //TODO: minecraft:slime //TODO: minecraft:smithing_table //TODO: minecraft:smoker @@ -578,7 +581,6 @@ class BlockFactory{ //TODO: minecraft:structure_block //TODO: minecraft:sweet_berry_bush //TODO: minecraft:turtle_egg - //TODO: minecraft:undyed_shulker_box //endregion //region --- auto-generated TODOs for bedrock-1.13.0 --- diff --git a/src/block/DyedShulkerBox.php b/src/block/DyedShulkerBox.php new file mode 100644 index 0000000000..7c50cacd0a --- /dev/null +++ b/src/block/DyedShulkerBox.php @@ -0,0 +1,36 @@ +color = DyeColor::WHITE(); + parent::__construct($idInfo, $name, $breakInfo); + } +} diff --git a/src/block/ShulkerBox.php b/src/block/ShulkerBox.php new file mode 100644 index 0000000000..5ad7f21fbf --- /dev/null +++ b/src/block/ShulkerBox.php @@ -0,0 +1,95 @@ +pos->getWorld()->getTile($this->pos); + if($shulker instanceof TileShulkerBox){ + $shulker->setFacing($this->facing); + } + } + + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); + $shulker = $this->pos->getWorld()->getTile($this->pos); + if($shulker instanceof TileShulkerBox){ + $this->facing = $shulker->getFacing(); + } + } + + public function getMaxStackSize() : int{ + return 1; + } + + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + $this->facing = $face; + + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + + public function asItem() : Item{ + $item = parent::asItem(); + $shulker = $this->pos->getWorld()->getTile($this->pos); + if($shulker instanceof TileShulkerBox){ + $shulkerNBT = $shulker->getCleanedNBT(); + if($shulkerNBT !== null){ + $item->setNamedTag($shulkerNBT); + } + if($shulker->hasName()){ + $item->setCustomName($shulker->getName()); + } + } + return $item; + } + + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($player instanceof Player){ + + $shulker = $this->pos->getWorld()->getTile($this->pos); + if($shulker instanceof TileShulkerBox){ + if( + $this->getSide($this->facing)->getId() !== BlockLegacyIds::AIR or + !$shulker->canOpenWith($item->getCustomName()) + ){ + return true; + } + + $player->setCurrentWindow($shulker->getInventory()); + } + } + + return true; + } +} diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index eb8cf97312..1da1d079f1 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -161,6 +161,7 @@ use function assert; * @method static DoubleTallGrass DOUBLE_TALLGRASS() * @method static DragonEgg DRAGON_EGG() * @method static DriedKelp DRIED_KELP() + * @method static DyedShulkerBox DYED_SHULKER_BOX() * @method static Element ELEMENT_ACTINIUM() * @method static Element ELEMENT_ALUMINUM() * @method static Element ELEMENT_AMERICIUM() @@ -484,6 +485,7 @@ use function assert; * @method static Wall SANDSTONE_WALL() * @method static SeaLantern SEA_LANTERN() * @method static SeaPickle SEA_PICKLE() + * @method static ShulkerBox SHULKER_BOX() * @method static Opaque SMOOTH_QUARTZ() * @method static Slab SMOOTH_QUARTZ_SLAB() * @method static Stair SMOOTH_QUARTZ_STAIRS() @@ -720,6 +722,7 @@ final class VanillaBlocks{ self::register("double_tallgrass", $factory->get(175, 2)); self::register("dragon_egg", $factory->get(122, 0)); self::register("dried_kelp", $factory->get(394, 0)); + self::register("dyed_shulker_box", $factory->get(218, 0)); self::register("element_actinium", $factory->get(355, 0)); self::register("element_aluminum", $factory->get(279, 0)); self::register("element_americium", $factory->get(361, 0)); @@ -1043,6 +1046,7 @@ final class VanillaBlocks{ self::register("sandstone_wall", $factory->get(139, 5)); self::register("sea_lantern", $factory->get(169, 0)); self::register("sea_pickle", $factory->get(411, 0)); + self::register("shulker_box", $factory->get(205, 0)); self::register("smooth_quartz", $factory->get(155, 3)); self::register("smooth_quartz_slab", $factory->get(421, 1)); self::register("smooth_quartz_stairs", $factory->get(440, 0)); diff --git a/src/block/inventory/ShulkerBoxInventory.php b/src/block/inventory/ShulkerBoxInventory.php new file mode 100644 index 0000000000..7c5a00e6df --- /dev/null +++ b/src/block/inventory/ShulkerBoxInventory.php @@ -0,0 +1,64 @@ +holder = $holder; + parent::__construct(27); + } + + protected function getOpenSound() : Sound{ + return new ShulkerOpenSound(); + } + + protected function getCloseSound() : Sound{ + return new ShulkerCloseSound(); + } + + public function canAddItem(Item $item) : bool{ + if($item->getId() === BlockLegacyIds::UNDYED_SHULKER_BOX || $item->getId() === BlockLegacyIds::SHULKER_BOX){ + return false; + } + return parent::canAddItem($item); + } + + protected function animateBlock(bool $isOpen) : void{ + $holder = $this->getHolder(); + + //event ID is always 1 for a chest + $holder->getWorld()->broadcastPacketToViewers($holder, BlockEventPacket::create(1, $isOpen ? 1 : 0, $holder->asVector3())); + } +} diff --git a/src/block/tile/ShulkerBox.php b/src/block/tile/ShulkerBox.php new file mode 100644 index 0000000000..a2e3bbb363 --- /dev/null +++ b/src/block/tile/ShulkerBox.php @@ -0,0 +1,120 @@ +inventory = new ShulkerBoxInventory($this->pos); + } + + public function readSaveData(CompoundTag $nbt) : void{ + $this->loadName($nbt); + $this->loadItems($nbt); + $this->facing = $nbt->getByte(self::TAG_FACING, $this->facing); + } + + protected function writeSaveData(CompoundTag $nbt) : void{ + $this->saveName($nbt); + $this->saveItems($nbt); + $nbt->setByte(self::TAG_FACING, $this->facing); + } + + public function copyDataFromItem(Item $item) : void{ + $this->readSaveData($item->getNamedTag()); + if($item->hasCustomName()){ + $this->setName($item->getCustomName()); + } + } + + public function close() : void{ + if(!$this->closed){ + $this->inventory->removeAllViewers(); + parent::close(); + } + } + + protected function onBlockDestroyedHook() : void{ + //NOOP override of ContainerTrait - shulker boxes retain their contents when destroyed + } + + public function getCleanedNBT() : ?CompoundTag{ + $nbt = parent::getCleanedNBT(); + if($nbt !== null){ + $nbt->removeTag(self::TAG_FACING); + } + return $nbt; + } + + public function getFacing() : int{ + return $this->facing; + } + + public function setFacing(int $facing) : void{ + $this->facing = $facing; + } + + /** + * @return ShulkerBoxInventory + */ + public function getInventory(){ + return $this->inventory; + } + + /** + * @return ShulkerBoxInventory + */ + public function getRealInventory(){ + return $this->inventory; + } + + public function getDefaultName() : string{ + return "Shulker Box"; + } + + protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ + $nbt->setByte(self::TAG_FACING, $this->facing); + $this->addNameSpawnData($nbt); + } +} diff --git a/src/block/tile/TileFactory.php b/src/block/tile/TileFactory.php index 10d144648f..0e37366d74 100644 --- a/src/block/tile/TileFactory.php +++ b/src/block/tile/TileFactory.php @@ -66,6 +66,7 @@ final class TileFactory{ $this->register(Jukebox::class, ["Jukebox", "RecordPlayer", "minecraft:jukebox"]); $this->register(MonsterSpawner::class, ["MobSpawner", "minecraft:mob_spawner"]); $this->register(Note::class, ["Music", "minecraft:noteblock"]); + $this->register(ShulkerBox::class, ["ShulkerBox", "minecraft:shulker_box"]); $this->register(Sign::class, ["Sign", "minecraft:sign"]); $this->register(Skull::class, ["Skull", "minecraft:skull"]); @@ -86,7 +87,6 @@ final class TileFactory{ //TODO: MovingBlock //TODO: NetherReactor //TODO: PistonArm - //TODO: ShulkerBox //TODO: Smoker //TODO: StructureBlock } diff --git a/src/world/sound/ShulkerCloseSound.php b/src/world/sound/ShulkerCloseSound.php new file mode 100644 index 0000000000..fc8bbd9306 --- /dev/null +++ b/src/world/sound/ShulkerCloseSound.php @@ -0,0 +1,34 @@ + Date: Sat, 10 Jul 2021 19:59:59 +0100 Subject: [PATCH 2606/3224] Shulker open/close sounds != shulker box open/close sounds --- src/block/inventory/ShulkerBoxInventory.php | 8 ++++---- .../{ShulkerCloseSound.php => ShulkerBoxCloseSound.php} | 2 +- .../{ShulkerOpenSound.php => ShulkerBoxOpenSound.php} | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) rename src/world/sound/{ShulkerCloseSound.php => ShulkerBoxCloseSound.php} (95%) rename src/world/sound/{ShulkerOpenSound.php => ShulkerBoxOpenSound.php} (95%) diff --git a/src/block/inventory/ShulkerBoxInventory.php b/src/block/inventory/ShulkerBoxInventory.php index 7c5a00e6df..3e4edcdd7e 100644 --- a/src/block/inventory/ShulkerBoxInventory.php +++ b/src/block/inventory/ShulkerBoxInventory.php @@ -28,8 +28,8 @@ use pocketmine\inventory\SimpleInventory; use pocketmine\item\Item; use pocketmine\network\mcpe\protocol\BlockEventPacket; use pocketmine\world\Position; -use pocketmine\world\sound\ShulkerCloseSound; -use pocketmine\world\sound\ShulkerOpenSound; +use pocketmine\world\sound\ShulkerBoxCloseSound; +use pocketmine\world\sound\ShulkerBoxOpenSound; use pocketmine\world\sound\Sound; class ShulkerBoxInventory extends SimpleInventory implements BlockInventory{ @@ -41,11 +41,11 @@ class ShulkerBoxInventory extends SimpleInventory implements BlockInventory{ } protected function getOpenSound() : Sound{ - return new ShulkerOpenSound(); + return new ShulkerBoxOpenSound(); } protected function getCloseSound() : Sound{ - return new ShulkerCloseSound(); + return new ShulkerBoxCloseSound(); } public function canAddItem(Item $item) : bool{ diff --git a/src/world/sound/ShulkerCloseSound.php b/src/world/sound/ShulkerBoxCloseSound.php similarity index 95% rename from src/world/sound/ShulkerCloseSound.php rename to src/world/sound/ShulkerBoxCloseSound.php index fc8bbd9306..cb170aab65 100644 --- a/src/world/sound/ShulkerCloseSound.php +++ b/src/world/sound/ShulkerBoxCloseSound.php @@ -26,7 +26,7 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; -class ShulkerCloseSound implements Sound{ +class ShulkerBoxCloseSound implements Sound{ public function encode(?Vector3 $pos) : array{ return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_SHULKERBOX_CLOSED, $pos)]; diff --git a/src/world/sound/ShulkerOpenSound.php b/src/world/sound/ShulkerBoxOpenSound.php similarity index 95% rename from src/world/sound/ShulkerOpenSound.php rename to src/world/sound/ShulkerBoxOpenSound.php index 7da764eb97..fd75b2f82f 100644 --- a/src/world/sound/ShulkerOpenSound.php +++ b/src/world/sound/ShulkerBoxOpenSound.php @@ -26,7 +26,7 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; -class ShulkerOpenSound implements Sound{ +class ShulkerBoxOpenSound implements Sound{ public function encode(?Vector3 $pos) : array{ return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_SHULKERBOX_OPEN, $pos)]; From 654fc9a2a6dfd1e48a4100dcd06c2ca373520c94 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 10 Jul 2021 20:13:44 +0100 Subject: [PATCH 2607/3224] LegacyStringToItemParser: Throw more specific exceptions --- src/command/defaults/ClearCommand.php | 4 +-- src/command/defaults/GiveCommand.php | 3 +- src/item/Item.php | 2 +- src/item/LegacyStringToItemParser.php | 6 ++-- .../LegacyStringToItemParserException.php | 28 +++++++++++++++++++ src/world/generator/Flat.php | 3 +- 6 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 src/item/LegacyStringToItemParserException.php diff --git a/src/command/defaults/ClearCommand.php b/src/command/defaults/ClearCommand.php index eded7e8faf..96055d86fc 100644 --- a/src/command/defaults/ClearCommand.php +++ b/src/command/defaults/ClearCommand.php @@ -23,11 +23,11 @@ declare(strict_types=1); namespace pocketmine\command\defaults; -use InvalidArgumentException; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\LegacyStringToItemParser; +use pocketmine\item\LegacyStringToItemParserException; use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; @@ -88,7 +88,7 @@ class ClearCommand extends VanillaCommand{ if(isset($args[2])){ $item->setCount($maxCount = $this->getInteger($sender, $args[2], 0)); } - }catch(InvalidArgumentException $e){ + }catch(LegacyStringToItemParserException $e){ //vanilla checks this at argument parsing layer, can't come up with a better alternative $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GIVE_ITEM_NOTFOUND, [$args[1]])); return true; diff --git a/src/command/defaults/GiveCommand.php b/src/command/defaults/GiveCommand.php index df740c2ace..f28e6fee00 100644 --- a/src/command/defaults/GiveCommand.php +++ b/src/command/defaults/GiveCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\LegacyStringToItemParser; +use pocketmine\item\LegacyStringToItemParserException; use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\nbt\JsonNbtParser; @@ -65,7 +66,7 @@ class GiveCommand extends VanillaCommand{ try{ $item = LegacyStringToItemParser::getInstance()->parse($args[1]); - }catch(\InvalidArgumentException $e){ + }catch(LegacyStringToItemParserException $e){ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GIVE_ITEM_NOTFOUND, [$args[1]])); return true; } diff --git a/src/item/Item.php b/src/item/Item.php index 103638c156..b28bf90661 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -680,7 +680,7 @@ class Item implements \JsonSerializable{ }elseif($idTag instanceof StringTag){ //PC item save format try{ $item = LegacyStringToItemParser::getInstance()->parse($idTag->getValue() . ":$meta"); - }catch(\InvalidArgumentException $e){ + }catch(LegacyStringToItemParserException $e){ //TODO: improve error handling return ItemFactory::air(); } diff --git a/src/item/LegacyStringToItemParser.php b/src/item/LegacyStringToItemParser.php index d4d345b578..2d872d93d1 100644 --- a/src/item/LegacyStringToItemParser.php +++ b/src/item/LegacyStringToItemParser.php @@ -87,7 +87,7 @@ final class LegacyStringToItemParser{ * - `minecraft:string` * - `351:4 (lapis lazuli ID:meta)` * - * @throws \InvalidArgumentException if the given string cannot be parsed as an item identifier + * @throws LegacyStringToItemParserException if the given string cannot be parsed as an item identifier */ public function parse(string $input) : Item{ $key = $this->reprocess($input); @@ -98,7 +98,7 @@ final class LegacyStringToItemParser{ }elseif(is_numeric($b[1])){ $meta = (int) $b[1]; }else{ - throw new \InvalidArgumentException("Unable to parse \"" . $b[1] . "\" from \"" . $input . "\" as a valid meta value"); + throw new LegacyStringToItemParserException("Unable to parse \"" . $b[1] . "\" from \"" . $input . "\" as a valid meta value"); } if(is_numeric($b[0])){ @@ -106,7 +106,7 @@ final class LegacyStringToItemParser{ }elseif(isset($this->map[strtolower($b[0])])){ $item = $this->itemFactory->get($this->map[strtolower($b[0])], $meta); }else{ - throw new \InvalidArgumentException("Unable to resolve \"" . $input . "\" to a valid item"); + throw new LegacyStringToItemParserException("Unable to resolve \"" . $input . "\" to a valid item"); } return $item; diff --git a/src/item/LegacyStringToItemParserException.php b/src/item/LegacyStringToItemParserException.php new file mode 100644 index 0000000000..8b6e7212da --- /dev/null +++ b/src/item/LegacyStringToItemParserException.php @@ -0,0 +1,28 @@ +parse($matches[2])->getBlock(); - }catch(\InvalidArgumentException $e){ + }catch(LegacyStringToItemParserException $e){ throw new InvalidGeneratorOptionsException("Invalid preset layer \"$line\": " . $e->getMessage(), 0, $e); } for($cY = $y, $y += $cnt; $cY < $y; ++$cY){ From 676bacbee18d5eafeddf7b89ed7b70a2ce911f70 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 13 Jul 2021 16:53:17 +0100 Subject: [PATCH 2608/3224] Improve the flexibility of WorldProvider registration WorldProviders now have the following requirements removed: - __construct() is no longer required to have a specific signature - static isValid() no longer needs to be implemented (you will still need it for registering, but it can be declared anywhere now) - static generate() no longer needs to be implemented This paves the way for more interesting types of world providers that use something other than local disk to store chunks (e.g. a mysql database). WorldProviderManager no longer accepts class-string. Instead, WorldProviderManagerEntry is required, with 2 or 3 callbacks: - ReadOnlyWorldProviderManager must provide a callback for isValid, and a callback for fromPath - WritableWorldProviderManagerEntry must provide the same, and also a generate() callback In practice, this requires zero changes to the WorldProviders themselves, since a WorldProviderManagerEntry can be created like this: `new WritableWorldProviderManagerEntry(\Closure::fromCallable([LevelDB::class, 'isValid']), fn(string ) => new LevelDB(), \Closure::fromCallable([LevelDB::class, 'generate']))` This provides identical functionality to before for the provider itself; only registration is changed. --- src/Server.php | 5 +- src/world/WorldManager.php | 15 ++--- src/world/format/io/FormatConverter.php | 22 ++----- .../io/ReadOnlyWorldProviderManagerEntry.php | 15 ++++- src/world/format/io/WorldProvider.php | 15 ----- src/world/format/io/WorldProviderManager.php | 65 +++++++------------ .../format/io/WorldProviderManagerEntry.php | 53 +++++++++++++++ src/world/format/io/WritableWorldProvider.php | 6 -- .../io/WritableWorldProviderManagerEntry.php | 58 +++++++++++++++++ .../format/io/InterfaceWorldProvider.php | 28 -------- .../format/io/LevelProviderManagerTest.php | 60 ----------------- 11 files changed, 158 insertions(+), 184 deletions(-) rename tests/phpunit/world/format/io/AbstractWorldProvider.php => src/world/format/io/ReadOnlyWorldProviderManagerEntry.php (61%) create mode 100644 src/world/format/io/WorldProviderManagerEntry.php create mode 100644 src/world/format/io/WritableWorldProviderManagerEntry.php delete mode 100644 tests/phpunit/world/format/io/InterfaceWorldProvider.php delete mode 100644 tests/phpunit/world/format/io/LevelProviderManagerTest.php diff --git a/src/Server.php b/src/Server.php index 8d2e83c187..2b34f1cb7d 100644 --- a/src/Server.php +++ b/src/Server.php @@ -99,7 +99,7 @@ use pocketmine\utils\Terminal; use pocketmine\utils\TextFormat; use pocketmine\utils\Utils; use pocketmine\world\format\io\WorldProviderManager; -use pocketmine\world\format\io\WritableWorldProvider; +use pocketmine\world\format\io\WritableWorldProviderManagerEntry; use pocketmine\world\generator\Generator; use pocketmine\world\generator\GeneratorManager; use pocketmine\world\World; @@ -121,7 +121,6 @@ use function filemtime; use function get_class; use function implode; use function ini_set; -use function is_a; use function is_array; use function is_string; use function json_decode; @@ -1014,7 +1013,7 @@ class Server{ $providerManager = new WorldProviderManager(); if( ($format = $providerManager->getProviderByName($formatName = $this->configGroup->getPropertyString("level-settings.default-format", ""))) !== null and - is_a($format, WritableWorldProvider::class, true) + $format instanceof WritableWorldProviderManagerEntry ){ $providerManager->setDefault($format); }elseif($formatName !== ""){ diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 99e07b566f..0c3a166b83 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -34,7 +34,6 @@ use pocketmine\timings\Timings; use pocketmine\world\format\io\exception\CorruptedWorldException; use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; use pocketmine\world\format\io\FormatConverter; -use pocketmine\world\format\io\WorldProvider; use pocketmine\world\format\io\WorldProviderManager; use pocketmine\world\format\io\WritableWorldProvider; use pocketmine\world\generator\GeneratorManager; @@ -205,11 +204,7 @@ class WorldManager{ $providerClass = array_shift($providers); try{ - /** - * @var WorldProvider $provider - * @see WorldProvider::__construct() - */ - $provider = new $providerClass($path); + $provider = $providerClass->fromPath($path); }catch(CorruptedWorldException $e){ $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_LOADERROR, [$name, "Corruption detected: " . $e->getMessage()])); return false; @@ -255,14 +250,12 @@ class WorldManager{ return false; } - $providerClass = $this->providerManager->getDefault(); + $providerEntry = $this->providerManager->getDefault(); $path = $this->getWorldPath($name); - /** @var WritableWorldProvider $providerClass */ - $providerClass::generate($path, $name, $options); + $providerEntry->generate($path, $name, $options); - /** @see WritableWorldProvider::__construct() */ - $world = new World($this->server, $name, new $providerClass($path), $this->server->getAsyncPool()); + $world = new World($this->server, $name, $providerEntry->fromPath($path), $this->server->getAsyncPool()); $this->worlds[$world->getId()] = $world; $world->setAutoSave($this->autoSave); diff --git a/src/world/format/io/FormatConverter.php b/src/world/format/io/FormatConverter.php index 053e26c372..24ca24db34 100644 --- a/src/world/format/io/FormatConverter.php +++ b/src/world/format/io/FormatConverter.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\world\format\io; use pocketmine\utils\Filesystem; -use pocketmine\utils\Utils; use pocketmine\world\generator\GeneratorManager; use pocketmine\world\WorldCreationOptions; use Webmozart\PathUtil\Path; @@ -44,7 +43,7 @@ class FormatConverter{ /** @var WorldProvider */ private $oldProvider; - /** @var WritableWorldProvider|string */ + /** @var WritableWorldProviderManagerEntry */ private $newProvider; /** @var string */ @@ -56,13 +55,8 @@ class FormatConverter{ /** @var int */ private $chunksPerProgressUpdate; - /** - * @phpstan-template TNewProvider of WritableWorldProvider - * @phpstan-param class-string $newProvider - */ - public function __construct(WorldProvider $oldProvider, string $newProvider, string $backupPath, \Logger $logger, int $chunksPerProgressUpdate = 256){ + public function __construct(WorldProvider $oldProvider, WritableWorldProviderManagerEntry $newProvider, string $backupPath, \Logger $logger, int $chunksPerProgressUpdate = 256){ $this->oldProvider = $oldProvider; - Utils::testValidInstance($newProvider, WritableWorldProvider::class); $this->newProvider = $newProvider; $this->logger = new \PrefixedLogger($logger, "World Converter: " . $this->oldProvider->getWorldData()->getName()); $this->chunksPerProgressUpdate = $chunksPerProgressUpdate; @@ -105,10 +99,7 @@ class FormatConverter{ } $this->logger->info("Conversion completed"); - /** - * @see WritableWorldProvider::__construct() - */ - return new $this->newProvider($path); + return $this->newProvider->fromPath($path); } private function generateNew() : WritableWorldProvider{ @@ -120,7 +111,7 @@ class FormatConverter{ $this->logger->info("Found previous conversion attempt, deleting..."); Filesystem::recursiveUnlink($convertedOutput); } - $this->newProvider::generate($convertedOutput, $data->getName(), WorldCreationOptions::create() + $this->newProvider->generate($convertedOutput, $data->getName(), WorldCreationOptions::create() ->setGeneratorClass(GeneratorManager::getInstance()->getGenerator($data->getGenerator())) ->setGeneratorOptions($data->getGeneratorOptions()) ->setSeed($data->getSeed()) @@ -128,10 +119,7 @@ class FormatConverter{ ->setDifficulty($data->getDifficulty()) ); - /** - * @see WritableWorldProvider::__construct() - */ - return new $this->newProvider($convertedOutput); + return $this->newProvider->fromPath($convertedOutput); } private function populateLevelData(WorldData $data) : void{ diff --git a/tests/phpunit/world/format/io/AbstractWorldProvider.php b/src/world/format/io/ReadOnlyWorldProviderManagerEntry.php similarity index 61% rename from tests/phpunit/world/format/io/AbstractWorldProvider.php rename to src/world/format/io/ReadOnlyWorldProviderManagerEntry.php index 29e78451ee..beb4098821 100644 --- a/tests/phpunit/world/format/io/AbstractWorldProvider.php +++ b/src/world/format/io/ReadOnlyWorldProviderManagerEntry.php @@ -23,6 +23,19 @@ declare(strict_types=1); namespace pocketmine\world\format\io; -abstract class AbstractWorldProvider implements WorldProvider{ +/** + * @phpstan-type FromPath \Closure(string $path) : WorldProvider + */ +class ReadOnlyWorldProviderManagerEntry extends WorldProviderManagerEntry{ + /** @phpstan-var FromPath */ + private \Closure $fromPath; + + /** @phpstan-param FromPath $fromPath */ + public function __construct(\Closure $isValid, \Closure $fromPath){ + parent::__construct($isValid); + $this->fromPath = $fromPath; + } + + public function fromPath(string $path) : WorldProvider{ return ($this->fromPath)($path); } } diff --git a/src/world/format/io/WorldProvider.php b/src/world/format/io/WorldProvider.php index 77f0fa1998..5089d8e5ba 100644 --- a/src/world/format/io/WorldProvider.php +++ b/src/world/format/io/WorldProvider.php @@ -25,17 +25,8 @@ namespace pocketmine\world\format\io; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\exception\CorruptedChunkException; -use pocketmine\world\format\io\exception\CorruptedWorldException; -use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; interface WorldProvider{ - - /** - * @throws CorruptedWorldException - * @throws UnsupportedWorldFormatException - */ - public function __construct(string $path); - /** * Returns the lowest buildable Y coordinate of this world */ @@ -48,12 +39,6 @@ interface WorldProvider{ public function getPath() : string; - /** - * Tells if the path is a valid world. - * This must tell if the current format supports opening the files in the directory - */ - public static function isValid(string $path) : bool; - /** * Loads a chunk (usually from disk storage) and returns it. If the chunk does not exist, null is returned. * diff --git a/src/world/format/io/WorldProviderManager.php b/src/world/format/io/WorldProviderManager.php index ba611eba1d..001f92913b 100644 --- a/src/world/format/io/WorldProviderManager.php +++ b/src/world/format/io/WorldProviderManager.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\world\format\io; -use pocketmine\utils\Utils; use pocketmine\world\format\io\leveldb\LevelDB; use pocketmine\world\format\io\region\Anvil; use pocketmine\world\format\io\region\McRegion; @@ -33,80 +32,62 @@ use function trim; final class WorldProviderManager{ /** - * @var string[] - * @phpstan-var array> + * @var WorldProviderManagerEntry[] + * @phpstan-var array */ protected $providers = []; - /** - * @var string - * @phpstan-var class-string - */ - private $default = LevelDB::class; + private WritableWorldProviderManagerEntry $default; public function __construct(){ - $this->addProvider(Anvil::class, "anvil"); - $this->addProvider(McRegion::class, "mcregion"); - $this->addProvider(PMAnvil::class, "pmanvil"); - $this->addProvider(LevelDB::class, "leveldb"); + $leveldb = new WritableWorldProviderManagerEntry(\Closure::fromCallable([LevelDB::class, 'isValid']), fn(string $path) => new LevelDB($path), \Closure::fromCallable([LevelDB::class, 'generate'])); + $this->default = $leveldb; + $this->addProvider($leveldb, "leveldb"); + + $this->addProvider(new ReadOnlyWorldProviderManagerEntry(\Closure::fromCallable([Anvil::class, 'isValid']), fn(string $path) => new Anvil($path)), "anvil"); + $this->addProvider(new ReadOnlyWorldProviderManagerEntry(\Closure::fromCallable([McRegion::class, 'isValid']), fn(string $path) => new McRegion($path)), "mcregion"); + $this->addProvider(new ReadOnlyWorldProviderManagerEntry(\Closure::fromCallable([PMAnvil::class, 'isValid']), fn(string $path) => new PMAnvil($path)), "pmanvil"); } /** * Returns the default format used to generate new worlds. - * - * @phpstan-return class-string */ - public function getDefault() : string{ + public function getDefault() : WritableWorldProviderManagerEntry{ return $this->default; } - /** - * Sets the default format. - * - * @param string $class Class implementing WritableWorldProvider - * @phpstan-param class-string $class - * - * @throws \InvalidArgumentException - */ - public function setDefault(string $class) : void{ - Utils::testValidInstance($class, WritableWorldProvider::class); - + public function setDefault(WritableWorldProviderManagerEntry $class) : void{ $this->default = $class; } - /** - * @phpstan-param class-string $class - */ - public function addProvider(string $class, string $name, bool $overwrite = false) : void{ - Utils::testValidInstance($class, WorldProvider::class); - + public function addProvider(WorldProviderManagerEntry $providerEntry, string $name, bool $overwrite = false) : void{ $name = strtolower($name); if(!$overwrite and isset($this->providers[$name])){ throw new \InvalidArgumentException("Alias \"$name\" is already assigned"); } - $this->providers[$name] = $class; + $this->providers[$name] = $providerEntry; } /** * Returns a WorldProvider class for this path, or null * - * @return string[] - * @phpstan-return array> + * @return WorldProviderManagerEntry[] + * @phpstan-return array */ public function getMatchingProviders(string $path) : array{ $result = []; - foreach($this->providers as $alias => $provider){ - if($provider::isValid($path)){ - $result[$alias] = $provider; + foreach($this->providers as $alias => $providerEntry){ + if($providerEntry->isValid($path)){ + $result[$alias] = $providerEntry; } } return $result; } /** - * @return string[] - * @phpstan-return array> + * @return WorldProviderManagerEntry[] + * @phpstan-return array */ public function getAvailableProviders() : array{ return $this->providers; @@ -114,10 +95,8 @@ final class WorldProviderManager{ /** * Returns a WorldProvider by name, or null if not found - * - * @phpstan-return class-string|null */ - public function getProviderByName(string $name) : ?string{ + public function getProviderByName(string $name) : ?WorldProviderManagerEntry{ return $this->providers[trim(strtolower($name))] ?? null; } } diff --git a/src/world/format/io/WorldProviderManagerEntry.php b/src/world/format/io/WorldProviderManagerEntry.php new file mode 100644 index 0000000000..5c35ac09ec --- /dev/null +++ b/src/world/format/io/WorldProviderManagerEntry.php @@ -0,0 +1,53 @@ +isValid = $isValid; + } + + /** + * Tells if the path is a valid world. + * This must tell if the current format supports opening the files in the directory + */ + public function isValid(string $path) : bool{ return ($this->isValid)($path); } + + /** + * @throws CorruptedWorldException + * @throws UnsupportedWorldFormatException + */ + abstract public function fromPath(string $path) : WorldProvider; +} diff --git a/src/world/format/io/WritableWorldProvider.php b/src/world/format/io/WritableWorldProvider.php index 3f1652417c..61fe03f0b0 100644 --- a/src/world/format/io/WritableWorldProvider.php +++ b/src/world/format/io/WritableWorldProvider.php @@ -24,14 +24,8 @@ declare(strict_types=1); namespace pocketmine\world\format\io; use pocketmine\world\format\Chunk; -use pocketmine\world\WorldCreationOptions; interface WritableWorldProvider extends WorldProvider{ - /** - * Generate the needed files in the path given - */ - public static function generate(string $path, string $name, WorldCreationOptions $options) : void; - /** * Saves a chunk (usually to disk). */ diff --git a/src/world/format/io/WritableWorldProviderManagerEntry.php b/src/world/format/io/WritableWorldProviderManagerEntry.php new file mode 100644 index 0000000000..296e4ca42b --- /dev/null +++ b/src/world/format/io/WritableWorldProviderManagerEntry.php @@ -0,0 +1,58 @@ +fromPath = $fromPath; + $this->generate = $generate; + } + + public function fromPath(string $path) : WritableWorldProvider{ + return ($this->fromPath)($path); + } + + /** + * Generates world manifest files and any other things needed to initialize a new world on disk + */ + public function generate(string $path, string $name, WorldCreationOptions $options) : void{ + ($this->generate)($path, $name, $options); + } +} diff --git a/tests/phpunit/world/format/io/InterfaceWorldProvider.php b/tests/phpunit/world/format/io/InterfaceWorldProvider.php deleted file mode 100644 index baaa3337d1..0000000000 --- a/tests/phpunit/world/format/io/InterfaceWorldProvider.php +++ /dev/null @@ -1,28 +0,0 @@ -providerManager = new WorldProviderManager(); - } - - public function testAddNonClassProvider() : void{ - $this->expectException(\InvalidArgumentException::class); - - $this->providerManager->addProvider("lol", "nope"); - } - - public function testAddAbstractClassProvider() : void{ - $this->expectException(\InvalidArgumentException::class); - - $this->providerManager->addProvider(AbstractWorldProvider::class, "abstract"); - } - - public function testAddInterfaceProvider() : void{ - $this->expectException(\InvalidArgumentException::class); - - $this->providerManager->addProvider(InterfaceWorldProvider::class, "interface"); - } - - public function testAddWrongClassProvider() : void{ - $this->expectException(\InvalidArgumentException::class); - - $this->providerManager->addProvider(LevelProviderManagerTest::class, "bad_class"); - } -} From 28ede7273ffd84956c1cdf6d4db6afc7d7837040 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 13 Jul 2021 18:16:25 +0100 Subject: [PATCH 2609/3224] Fixed CS --- src/network/mcpe/protocol/ResourcePacksInfoPacket.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php index 20093d5d7a..7f1b5dd000 100644 --- a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php +++ b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php @@ -45,7 +45,6 @@ class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ public $resourcePackEntries = []; /** - * @param bool $forceServerPacks * @param ResourcePackInfoEntry[] $resourcePacks * @param BehaviorPackInfoEntry[] $behaviorPacks * From 1ad38d499c05de802376a701ff0211f483b3cd60 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 14 Jul 2021 14:26:32 +0100 Subject: [PATCH 2610/3224] Deglobalize ItemTypeDictionary usage, at least for the protocol while this is a bit hacky outside of the protocol namespace, it makes it much easier to use the protocol library for alternative purposes, such as for a client or MITM proxy. It also removes all but one remaining core dependency of the protocol library, making it very close to being able to be separated from the server core entirely. --- src/network/mcpe/ChunkRequestTask.php | 7 +++- src/network/mcpe/NetworkSession.php | 12 ++++-- .../mcpe/StandardPacketBroadcaster.php | 5 ++- .../mcpe/convert/RuntimeBlockMapping.php | 5 ++- .../mcpe/protocol/serializer/PacketBatch.php | 10 ++--- .../protocol/serializer/PacketSerializer.php | 30 ++++++++------ .../serializer/PacketSerializerContext.php | 39 +++++++++++++++++++ .../mcpe/serializer/ChunkSerializer.php | 5 ++- tests/phpstan/configs/l7-baseline.neon | 2 +- .../network/mcpe/protocol/DataPacketTest.php | 8 +++- .../network/mcpe/protocol/LoginPacketTest.php | 9 +++-- .../protocol/serializer/PacketBatchTest.php | 12 ++++-- 12 files changed, 108 insertions(+), 36 deletions(-) create mode 100644 src/network/mcpe/protocol/serializer/PacketSerializerContext.php diff --git a/src/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php index d90e0cd32d..7395da7280 100644 --- a/src/network/mcpe/ChunkRequestTask.php +++ b/src/network/mcpe/ChunkRequestTask.php @@ -25,9 +25,11 @@ namespace pocketmine\network\mcpe; use pocketmine\network\mcpe\compression\CompressBatchPromise; use pocketmine\network\mcpe\compression\Compressor; +use pocketmine\network\mcpe\convert\GlobalItemTypeDictionary; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\LevelChunkPacket; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\network\mcpe\serializer\ChunkSerializer; use pocketmine\scheduler\AsyncTask; use pocketmine\world\format\Chunk; @@ -68,8 +70,9 @@ class ChunkRequestTask extends AsyncTask{ public function onRun() : void{ $chunk = FastChunkSerializer::deserialize($this->chunk); $subCount = ChunkSerializer::getSubChunkCount($chunk); - $payload = ChunkSerializer::serialize($chunk, RuntimeBlockMapping::getInstance(), $this->tiles); - $this->setResult($this->compressor->compress(PacketBatch::fromPackets(LevelChunkPacket::withoutCache($this->chunkX, $this->chunkZ, $subCount, $payload))->getBuffer())); + $encoderContext = new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary()); + $payload = ChunkSerializer::serialize($chunk, RuntimeBlockMapping::getInstance(), $encoderContext, $this->tiles); + $this->setResult($this->compressor->compress(PacketBatch::fromPackets($encoderContext, LevelChunkPacket::withoutCache($this->chunkX, $this->chunkZ, $subCount, $payload))->getBuffer())); } public function onError() : void{ diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index eab54915b1..258e21ee9d 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -42,6 +42,7 @@ use pocketmine\network\mcpe\cache\ChunkCache; use pocketmine\network\mcpe\compression\CompressBatchPromise; use pocketmine\network\mcpe\compression\Compressor; use pocketmine\network\mcpe\compression\DecompressionException; +use pocketmine\network\mcpe\convert\GlobalItemTypeDictionary; use pocketmine\network\mcpe\convert\SkinAdapterSingleton; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\encryption\DecryptionException; @@ -74,6 +75,7 @@ use pocketmine\network\mcpe\protocol\PlayStatusPacket; use pocketmine\network\mcpe\protocol\RemoveActorPacket; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\network\mcpe\protocol\ServerboundPacket; use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket; use pocketmine\network\mcpe\protocol\SetActorDataPacket; @@ -158,6 +160,7 @@ class NetworkSession{ private bool $forceAsyncCompression = true; private PacketPool $packetPool; + private PacketSerializerContext $packetSerializerContext; private ?InventoryManager $invManager = null; @@ -185,6 +188,9 @@ class NetworkSession{ $this->compressor = $compressor; $this->packetPool = $packetPool; + //TODO: allow this to be injected + $this->packetSerializerContext = new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary()); + $this->disposeHooks = new ObjectSet(); $this->connectTime = time(); @@ -335,7 +341,7 @@ class NetworkSession{ } try{ - foreach($stream->getPackets($this->packetPool, 500) as [$packet, $buffer]){ + foreach($stream->getPackets($this->packetPool, $this->packetSerializerContext, 500) as [$packet, $buffer]){ try{ $this->handleDataPacket($packet, $buffer); }catch(PacketHandlingException $e){ @@ -361,7 +367,7 @@ class NetworkSession{ $timings->startTiming(); try{ - $stream = new PacketSerializer($buffer); + $stream = PacketSerializer::decoder($buffer, 0, $this->packetSerializerContext); try{ $packet->decode($stream); }catch(PacketDecodeException $e){ @@ -430,7 +436,7 @@ class NetworkSession{ }elseif($this->forceAsyncCompression){ $syncMode = false; } - $promise = $this->server->prepareBatch(PacketBatch::fromPackets(...$this->sendBuffer), $this->compressor, $syncMode); + $promise = $this->server->prepareBatch(PacketBatch::fromPackets($this->packetSerializerContext, ...$this->sendBuffer), $this->compressor, $syncMode); $this->sendBuffer = []; $this->queueCompressedNoBufferFlush($promise, $immediate); } diff --git a/src/network/mcpe/StandardPacketBroadcaster.php b/src/network/mcpe/StandardPacketBroadcaster.php index 3638f04cb4..1442a5bbf6 100644 --- a/src/network/mcpe/StandardPacketBroadcaster.php +++ b/src/network/mcpe/StandardPacketBroadcaster.php @@ -24,7 +24,9 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; use pocketmine\network\mcpe\compression\Compressor; +use pocketmine\network\mcpe\convert\GlobalItemTypeDictionary; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\Server; use function spl_object_id; @@ -38,7 +40,8 @@ final class StandardPacketBroadcaster implements PacketBroadcaster{ } public function broadcastPackets(array $recipients, array $packets) : void{ - $stream = PacketBatch::fromPackets(...$packets); + //TODO: we should be using session-specific serializer contexts for this + $stream = PacketBatch::fromPackets(new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary()), ...$packets); /** @var Compressor[] $compressors */ $compressors = []; diff --git a/src/network/mcpe/convert/RuntimeBlockMapping.php b/src/network/mcpe/convert/RuntimeBlockMapping.php index 95dbcb8fb1..1185a02dde 100644 --- a/src/network/mcpe/convert/RuntimeBlockMapping.php +++ b/src/network/mcpe/convert/RuntimeBlockMapping.php @@ -29,6 +29,7 @@ use pocketmine\data\bedrock\LegacyBlockIdToStringIdMap; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\SingletonTrait; use Webmozart\PathUtil\Path; @@ -52,7 +53,7 @@ final class RuntimeBlockMapping{ if($canonicalBlockStatesFile === false){ throw new AssumptionFailedError("Missing required resource file"); } - $stream = new PacketSerializer($canonicalBlockStatesFile); + $stream = PacketSerializer::decoder($canonicalBlockStatesFile, 0, new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary())); $list = []; while(!$stream->feof()){ $list[] = $stream->getNbtCompoundRoot(); @@ -66,7 +67,7 @@ final class RuntimeBlockMapping{ $legacyIdMap = LegacyBlockIdToStringIdMap::getInstance(); /** @var R12ToCurrentBlockMapEntry[] $legacyStateMap */ $legacyStateMap = []; - $legacyStateMapReader = new PacketSerializer(file_get_contents(Path::join(\pocketmine\RESOURCE_PATH, "vanilla", "r12_to_current_block_map.bin"))); + $legacyStateMapReader = PacketSerializer::decoder(file_get_contents(Path::join(\pocketmine\RESOURCE_PATH, "vanilla", "r12_to_current_block_map.bin")), 0, new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary())); $nbtReader = new NetworkNbtSerializer(); while(!$legacyStateMapReader->feof()){ $id = $legacyStateMapReader->getString(); diff --git a/src/network/mcpe/protocol/serializer/PacketBatch.php b/src/network/mcpe/protocol/serializer/PacketBatch.php index 86b0a94d64..a1af98c35a 100644 --- a/src/network/mcpe/protocol/serializer/PacketBatch.php +++ b/src/network/mcpe/protocol/serializer/PacketBatch.php @@ -42,8 +42,8 @@ class PacketBatch{ * @phpstan-return \Generator * @throws PacketDecodeException */ - public function getPackets(PacketPool $packetPool, int $max) : \Generator{ - $serializer = new PacketSerializer($this->buffer); + public function getPackets(PacketPool $packetPool, PacketSerializerContext $decoderContext, int $max) : \Generator{ + $serializer = PacketSerializer::decoder($this->buffer, 0, $decoderContext); for($c = 0; $c < $max and !$serializer->feof(); ++$c){ try{ $buffer = $serializer->getString(); @@ -64,10 +64,10 @@ class PacketBatch{ * * @return PacketBatch */ - public static function fromPackets(Packet ...$packets) : self{ - $serializer = new PacketSerializer(); + public static function fromPackets(PacketSerializerContext $context, Packet ...$packets) : self{ + $serializer = PacketSerializer::encoder($context); foreach($packets as $packet){ - $subSerializer = new PacketSerializer(); + $subSerializer = PacketSerializer::encoder($context); $packet->encode($subSerializer); $serializer->putString($subSerializer->getBuffer()); } diff --git a/src/network/mcpe/protocol/serializer/PacketSerializer.php b/src/network/mcpe/protocol/serializer/PacketSerializer.php index 1f2ad22786..9df467f1c6 100644 --- a/src/network/mcpe/protocol/serializer/PacketSerializer.php +++ b/src/network/mcpe/protocol/serializer/PacketSerializer.php @@ -30,7 +30,6 @@ use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\TreeRoot; -use pocketmine\network\mcpe\convert\GlobalItemTypeDictionary; use pocketmine\network\mcpe\protocol\PacketDecodeException; use pocketmine\network\mcpe\protocol\types\BoolGameRule; use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; @@ -71,10 +70,20 @@ use function substr; class PacketSerializer extends BinaryStream{ private int $shieldItemRuntimeId; + private PacketSerializerContext $context; - public function __construct(string $buffer = "", int $offset = 0){ + protected function __construct(PacketSerializerContext $context, string $buffer = "", int $offset = 0){ parent::__construct($buffer, $offset); - $this->shieldItemRuntimeId = GlobalItemTypeDictionary::getInstance()->getDictionary()->fromStringId("minecraft:shield"); + $this->context = $context; + $this->shieldItemRuntimeId = $context->getItemDictionary()->fromStringId("minecraft:shield"); + } + + public static function encoder(PacketSerializerContext $context) : self{ + return new self($context); + } + + public static function decoder(string $buffer, int $offset, PacketSerializerContext $context) : self{ + return new self($context, $buffer, $offset); } /** @@ -248,9 +257,8 @@ class PacketSerializer extends BinaryStream{ $readExtraCrapInTheMiddle($this); $blockRuntimeId = $this->getVarInt(); - $extraData = new PacketSerializer($this->getString()); - $shieldItemRuntimeId = $this->shieldItemRuntimeId; - return (static function() use ($extraData, $id, $meta, $count, $blockRuntimeId, $shieldItemRuntimeId) : ItemStack{ + $extraData = self::decoder($this->getString(), 0, $this->context); + return (static function() use ($extraData, $id, $meta, $count, $blockRuntimeId) : ItemStack{ $nbtLen = $extraData->getLShort(); /** @var CompoundTag|null $compound */ @@ -283,7 +291,7 @@ class PacketSerializer extends BinaryStream{ } $shieldBlockingTick = null; - if($id === $shieldItemRuntimeId){ + if($id === $extraData->shieldItemRuntimeId){ $shieldBlockingTick = $extraData->getLLong(); } @@ -312,9 +320,9 @@ class PacketSerializer extends BinaryStream{ $writeExtraCrapInTheMiddle($this); $this->putVarInt($item->getBlockRuntimeId()); - $shieldItemRuntimeId = $this->shieldItemRuntimeId; - $this->putString((static function() use ($item, $shieldItemRuntimeId) : string{ - $extraData = new PacketSerializer(); + $context = $this->context; + $this->putString((static function() use ($item, $context) : string{ + $extraData = PacketSerializer::encoder($context); $nbt = $item->getNbt(); if($nbt !== null){ @@ -337,7 +345,7 @@ class PacketSerializer extends BinaryStream{ } $blockingTick = $item->getShieldBlockingTick(); - if($item->getId() === $shieldItemRuntimeId){ + if($item->getId() === $extraData->shieldItemRuntimeId){ $extraData->putLLong($blockingTick ?? 0); } return $extraData->getBuffer(); diff --git a/src/network/mcpe/protocol/serializer/PacketSerializerContext.php b/src/network/mcpe/protocol/serializer/PacketSerializerContext.php new file mode 100644 index 0000000000..887adbc909 --- /dev/null +++ b/src/network/mcpe/protocol/serializer/PacketSerializerContext.php @@ -0,0 +1,39 @@ +itemDictionary = $itemDictionary; + } + + public function getItemDictionary() : ItemTypeDictionary{ return $this->itemDictionary; } +} diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index abf0e1b25c..6408cd7801 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\serializer; use pocketmine\block\tile\Spawnable; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\utils\Binary; use pocketmine\utils\BinaryStream; use pocketmine\world\format\Chunk; @@ -52,8 +53,8 @@ final class ChunkSerializer{ return 0; } - public static function serialize(Chunk $chunk, RuntimeBlockMapping $blockMapper, ?string $tiles = null) : string{ - $stream = new PacketSerializer(); + public static function serialize(Chunk $chunk, RuntimeBlockMapping $blockMapper, PacketSerializerContext $encoderContext, ?string $tiles = null) : string{ + $stream = PacketSerializer::encoder($encoderContext); $subChunkCount = self::getSubChunkCount($chunk); for($y = 0; $y < $subChunkCount; ++$y){ $layers = $chunk->getSubChunk($y)->getBlockLayers(); diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index a9eb810285..ff9421a412 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -591,7 +591,7 @@ parameters: path: ../../../src/network/mcpe/auth/ProcessLoginTask.php - - message: "#^Parameter \\#1 \\$buffer of class pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer constructor expects string, string\\|false given\\.$#" + message: "#^Parameter \\#1 \\$buffer of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:decoder\\(\\) expects string, string\\|false given\\.$#" count: 1 path: ../../../src/network/mcpe/convert/RuntimeBlockMapping.php diff --git a/tests/phpunit/network/mcpe/protocol/DataPacketTest.php b/tests/phpunit/network/mcpe/protocol/DataPacketTest.php index 94bdcb83df..880be1e8f9 100644 --- a/tests/phpunit/network/mcpe/protocol/DataPacketTest.php +++ b/tests/phpunit/network/mcpe/protocol/DataPacketTest.php @@ -24,7 +24,9 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; use PHPUnit\Framework\TestCase; +use pocketmine\network\mcpe\convert\GlobalItemTypeDictionary; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; class DataPacketTest extends TestCase{ @@ -32,11 +34,13 @@ class DataPacketTest extends TestCase{ $pk = new TestPacket(); $pk->senderSubId = 3; $pk->recipientSubId = 2; - $serializer = new PacketSerializer(); + + $context = new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary()); + $serializer = PacketSerializer::encoder($context); $pk->encode($serializer); $pk2 = new TestPacket(); - $pk2->decode(new PacketSerializer($serializer->getBuffer())); + $pk2->decode(PacketSerializer::decoder($serializer->getBuffer(), 0, $context)); self::assertSame($pk2->senderSubId, 3); self::assertSame($pk2->recipientSubId, 2); } diff --git a/tests/phpunit/network/mcpe/protocol/LoginPacketTest.php b/tests/phpunit/network/mcpe/protocol/LoginPacketTest.php index 7ddf34dbeb..cdd20f8400 100644 --- a/tests/phpunit/network/mcpe/protocol/LoginPacketTest.php +++ b/tests/phpunit/network/mcpe/protocol/LoginPacketTest.php @@ -24,18 +24,21 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\protocol; use PHPUnit\Framework\TestCase; +use pocketmine\network\mcpe\convert\GlobalItemTypeDictionary; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use function strlen; class LoginPacketTest extends TestCase{ public function testInvalidChainDataJsonHandling() : void{ - $stream = new PacketSerializer(); + $context = new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary()); + $stream = PacketSerializer::encoder($context); $stream->putUnsignedVarInt(ProtocolInfo::LOGIN_PACKET); $payload = '{"chain":[]'; //intentionally malformed $stream->putInt(ProtocolInfo::CURRENT_PROTOCOL); - $stream2 = new PacketSerializer(); + $stream2 = PacketSerializer::encoder($context); $stream2->putLInt(strlen($payload)); $stream2->put($payload); $stream->putString($stream2->getBuffer()); @@ -43,6 +46,6 @@ class LoginPacketTest extends TestCase{ $pk = PacketPool::getInstance()->getPacket($stream->getBuffer()); $this->expectException(PacketDecodeException::class); - $pk->decode(new PacketSerializer($stream->getBuffer())); //bang + $pk->decode(PacketSerializer::decoder($stream->getBuffer(), 0, $context)); //bang } } diff --git a/tests/phpunit/network/mcpe/protocol/serializer/PacketBatchTest.php b/tests/phpunit/network/mcpe/protocol/serializer/PacketBatchTest.php index 28d01dc8c3..da90c0c0a7 100644 --- a/tests/phpunit/network/mcpe/protocol/serializer/PacketBatchTest.php +++ b/tests/phpunit/network/mcpe/protocol/serializer/PacketBatchTest.php @@ -24,9 +24,11 @@ declare(strict_types=1); namespace pocketmine\mcpe\protocol\serializer; use PHPUnit\Framework\TestCase; +use pocketmine\network\mcpe\convert\GlobalItemTypeDictionary; use pocketmine\network\mcpe\protocol\PacketDecodeException; use pocketmine\network\mcpe\protocol\PacketPool; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; +use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\network\mcpe\protocol\TestPacket; use function array_fill; @@ -34,21 +36,23 @@ class PacketBatchTest extends TestCase{ public function testDecodeTooBig() : void{ $limit = 10; - $write = PacketBatch::fromPackets(...array_fill(0, $limit + 1, new TestPacket())); + $decoderContext = new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary()); + $write = PacketBatch::fromPackets($decoderContext, ...array_fill(0, $limit + 1, new TestPacket())); $read = new PacketBatch($write->getBuffer()); $this->expectException(PacketDecodeException::class); $readCount = 0; - foreach($read->getPackets(PacketPool::getInstance(), $limit) as $packet){ + foreach($read->getPackets(PacketPool::getInstance(), $decoderContext, $limit) as $packet){ $readCount++; } } public function testDecodeAtLimit() : void{ $limit = 10; - $write = PacketBatch::fromPackets(...array_fill(0, $limit, new TestPacket())); + $decoderContext = new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary()); + $write = PacketBatch::fromPackets($decoderContext, ...array_fill(0, $limit, new TestPacket())); $read = new PacketBatch($write->getBuffer()); $readCount = 0; - foreach($read->getPackets(PacketPool::getInstance(), $limit) as $packet){ + foreach($read->getPackets(PacketPool::getInstance(), $decoderContext, $limit) as $packet){ $readCount++; } self::assertSame($limit, $readCount); From c474aa42e5879c7a3eeb39785c7cf4f386d88c9d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 14 Jul 2021 14:50:59 +0100 Subject: [PATCH 2611/3224] ClientDataToSkinDataHelper: Remove SingletonTrait SingletonTrait is pointless here for multiple reasons: 1) the class is final 2) this is protocol-specific translation of types, no loss of data or alternative mutation of it needs to occur Using SingletonTrait is an obstacle to separating the protocol library from the core code, so it has to go. --- src/network/mcpe/handler/LoginPacketHandler.php | 2 +- .../mcpe/protocol/types/login/ClientDataToSkinDataHelper.php | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index 27911a3fa9..989bac9f64 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -105,7 +105,7 @@ class LoginPacketHandler extends PacketHandler{ $clientData = $this->parseClientData($packet->clientDataJwt); try{ - $skin = SkinAdapterSingleton::get()->fromSkinData(ClientDataToSkinDataHelper::getInstance()->fromClientData($clientData)); + $skin = SkinAdapterSingleton::get()->fromSkinData(ClientDataToSkinDataHelper::fromClientData($clientData)); }catch(\InvalidArgumentException | InvalidSkinException $e){ $this->session->getLogger()->debug("Invalid skin: " . $e->getMessage()); $this->session->disconnect("disconnectionScreen.invalidSkin"); diff --git a/src/network/mcpe/protocol/types/login/ClientDataToSkinDataHelper.php b/src/network/mcpe/protocol/types/login/ClientDataToSkinDataHelper.php index 037a799420..2a30562b66 100644 --- a/src/network/mcpe/protocol/types/login/ClientDataToSkinDataHelper.php +++ b/src/network/mcpe/protocol/types/login/ClientDataToSkinDataHelper.php @@ -28,12 +28,10 @@ use pocketmine\network\mcpe\protocol\types\skin\PersonaSkinPiece; use pocketmine\network\mcpe\protocol\types\skin\SkinAnimation; use pocketmine\network\mcpe\protocol\types\skin\SkinData; use pocketmine\network\mcpe\protocol\types\skin\SkinImage; -use pocketmine\utils\SingletonTrait; use function array_map; use function base64_decode; final class ClientDataToSkinDataHelper{ - use SingletonTrait; /** * @throws \InvalidArgumentException @@ -49,7 +47,7 @@ final class ClientDataToSkinDataHelper{ /** * @throws \InvalidArgumentException */ - public function fromClientData(ClientData $clientData) : SkinData{ + public static function fromClientData(ClientData $clientData) : SkinData{ /** @var SkinAnimation[] $animations */ $animations = []; foreach($clientData->AnimatedImageData as $k => $animation){ From 9f11be25cb7d8ac32018fdcb7042b6cc6fdf45bb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 14 Jul 2021 15:21:33 +0100 Subject: [PATCH 2612/3224] LevelSoundEventPacket: fixed bad null assignment in ::create() --- src/network/mcpe/protocol/LevelSoundEventPacket.php | 2 +- tests/phpstan/configs/l8-baseline.neon | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/network/mcpe/protocol/LevelSoundEventPacket.php b/src/network/mcpe/protocol/LevelSoundEventPacket.php index 45052d6e08..58476cae81 100644 --- a/src/network/mcpe/protocol/LevelSoundEventPacket.php +++ b/src/network/mcpe/protocol/LevelSoundEventPacket.php @@ -364,7 +364,7 @@ class LevelSoundEventPacket extends DataPacket implements ClientboundPacket, Ser $result = new self; $result->sound = $sound; $result->extraData = $extraData; - $result->position = $pos; + $result->position = $pos ?? new Vector3(0, 0, 0); $result->disableRelativeVolume = $pos === null; $result->entityType = $entityType; $result->isBabyMob = $isBabyMob; diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 9af2e2e80f..98057695cb 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -190,11 +190,6 @@ parameters: count: 1 path: ../../../src/network/mcpe/NetworkSession.php - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\protocol\\\\LevelSoundEventPacket\\:\\:\\$position \\(pocketmine\\\\math\\\\Vector3\\) does not accept pocketmine\\\\math\\\\Vector3\\|null\\.$#" - count: 1 - path: ../../../src/network/mcpe/protocol/LevelSoundEventPacket.php - - message: "#^Parameter \\#1 \\$eid of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:putEntityUniqueId\\(\\) expects int, int\\|null given\\.$#" count: 1 From b86d68279366debc42a6f0870f9da2ce1d52804f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 14 Jul 2021 20:14:33 +0100 Subject: [PATCH 2613/3224] Update to released version of pocketmine/math --- composer.json | 2 +- composer.lock | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/composer.json b/composer.json index 48b207fbdb..37ac6a7b0e 100644 --- a/composer.json +++ b/composer.json @@ -41,7 +41,7 @@ "pocketmine/errorhandler": "^0.3.0", "pocketmine/log": "^0.3.0", "pocketmine/log-pthreads": "^0.2.0", - "pocketmine/math": "dev-master", + "pocketmine/math": "^0.3.0", "pocketmine/nbt": "^0.3.0", "pocketmine/raklib": "^0.13.1", "pocketmine/raklib-ipc": "^0.1.0", diff --git a/composer.lock b/composer.lock index 5bdbc6d8f0..4810dab992 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "28939b75a6c33177454a6d027bf4d7cb", + "content-hash": "5456f8b834ba877a4c04d1cf5a933d63", "packages": [ { "name": "adhocore/json-comment", @@ -617,26 +617,26 @@ }, { "name": "pocketmine/math", - "version": "dev-master", + "version": "0.3.0", "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "4595b5ee90627e817317839519a7d482c809effb" + "reference": "83ec067b12c066fc61d9fb129daf7e61ef3b1d63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/4595b5ee90627e817317839519a7d482c809effb", - "reference": "4595b5ee90627e817317839519a7d482c809effb", + "url": "https://api.github.com/repos/pmmp/Math/zipball/83ec067b12c066fc61d9fb129daf7e61ef3b1d63", + "reference": "83ec067b12c066fc61d9fb129daf7e61ef3b1d63", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", + "php": "^7.4 || ^8.0", "php-64bit": "*" }, "require-dev": { "irstea/phpunit-shim": "^8.5 || ^9.5", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "0.12.80", + "phpstan/phpstan": "0.12.90", "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", @@ -652,9 +652,9 @@ "description": "PHP library containing math related code used in PocketMine-MP", "support": { "issues": "https://github.com/pmmp/Math/issues", - "source": "https://github.com/pmmp/Math/tree/master" + "source": "https://github.com/pmmp/Math/tree/0.3.0" }, - "time": "2021-05-10T10:44:46+00:00" + "time": "2021-07-14T18:39:31+00:00" }, { "name": "pocketmine/nbt", @@ -3548,7 +3548,6 @@ "minimum-stability": "stable", "stability-flags": { "pocketmine/classloader": 20, - "pocketmine/math": 20, "pocketmine/spl": 20 }, "prefer-stable": false, From a2e2196a9089b1206ca0e7a5b9978943cc162100 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 14 Jul 2021 20:32:15 +0100 Subject: [PATCH 2614/3224] Start using pocketmine/bedrock-protocol library --- composer.json | 1 + composer.lock | 51 +- .../mcpe/protocol/ActorEventPacket.php | 124 --- .../mcpe/protocol/ActorPickRequestPacket.php | 51 -- src/network/mcpe/protocol/AddActorPacket.php | 119 --- .../mcpe/protocol/AddBehaviorTreePacket.php | 47 -- src/network/mcpe/protocol/AddEntityPacket.php | 57 -- .../mcpe/protocol/AddItemActorPacket.php | 77 -- .../mcpe/protocol/AddPaintingPacket.php | 64 -- src/network/mcpe/protocol/AddPlayerPacket.php | 156 ---- .../mcpe/protocol/AddVolumeEntityPacket.php | 65 -- .../mcpe/protocol/AdventureSettingsPacket.php | 123 --- .../mcpe/protocol/AnimateEntityPacket.php | 108 --- src/network/mcpe/protocol/AnimatePacket.php | 80 -- .../mcpe/protocol/AnvilDamagePacket.php | 78 -- .../AutomationClientConnectPacket.php | 47 -- .../AvailableActorIdentifiersPacket.php | 60 -- .../mcpe/protocol/AvailableCommandsPacket.php | 487 ----------- .../protocol/BiomeDefinitionListPacket.php | 60 -- .../mcpe/protocol/BlockActorDataPacket.php | 69 -- .../mcpe/protocol/BlockEventPacket.php | 70 -- .../mcpe/protocol/BlockPickRequestPacket.php | 59 -- src/network/mcpe/protocol/BookEditPacket.php | 119 --- src/network/mcpe/protocol/BossEventPacket.php | 184 ---- src/network/mcpe/protocol/CameraPacket.php | 51 -- .../mcpe/protocol/CameraShakePacket.php | 82 -- .../mcpe/protocol/ChangeDimensionPacket.php | 56 -- .../protocol/ChunkRadiusUpdatedPacket.php | 53 -- .../protocol/ClientCacheBlobStatusPacket.php | 93 -- .../ClientCacheMissResponsePacket.php | 76 -- .../mcpe/protocol/ClientCacheStatusPacket.php | 57 -- .../ClientToServerHandshakePacket.php | 48 -- .../ClientboundDebugRendererPacket.php | 137 --- .../protocol/ClientboundMapItemDataPacket.php | 208 ----- .../mcpe/protocol/ClientboundPacket.php | 28 - .../mcpe/protocol/CodeBuilderPacket.php | 66 -- .../protocol/CommandBlockUpdatePacket.php | 111 --- .../mcpe/protocol/CommandOutputPacket.php | 111 --- .../mcpe/protocol/CommandRequestPacket.php | 56 -- .../protocol/CompletedUsingItemPacket.php | 68 -- .../mcpe/protocol/ContainerClosePacket.php | 58 -- .../mcpe/protocol/ContainerOpenPacket.php | 85 -- .../mcpe/protocol/ContainerSetDataPacket.php | 73 -- .../CorrectPlayerMovePredictionPacket.php | 77 -- .../mcpe/protocol/CraftingDataPacket.php | 131 --- .../mcpe/protocol/CraftingEventPacket.php | 82 -- .../mcpe/protocol/CreativeContentPacket.php | 67 -- src/network/mcpe/protocol/DataPacket.php | 129 --- src/network/mcpe/protocol/DebugInfoPacket.php | 65 -- .../mcpe/protocol/DisconnectPacket.php | 72 -- .../mcpe/protocol/EducationSettingsPacket.php | 100 --- src/network/mcpe/protocol/EmoteListPacket.php | 74 -- src/network/mcpe/protocol/EmotePacket.php | 80 -- src/network/mcpe/protocol/EventPacket.php | 85 -- .../mcpe/protocol/FilterTextPacket.php | 62 -- .../mcpe/protocol/GameRulesChangedPacket.php | 51 -- .../mcpe/protocol/GuiDataPickItemPacket.php | 55 -- src/network/mcpe/protocol/HurtArmorPacket.php | 51 -- src/network/mcpe/protocol/InteractPacket.php | 76 -- .../mcpe/protocol/InventoryContentPacket.php | 71 -- .../mcpe/protocol/InventorySlotPacket.php | 65 -- .../protocol/InventoryTransactionPacket.php | 108 --- .../mcpe/protocol/ItemComponentPacket.php | 79 -- .../mcpe/protocol/ItemFrameDropItemPacket.php | 52 -- .../mcpe/protocol/ItemStackRequestPacket.php | 67 -- .../mcpe/protocol/ItemStackResponsePacket.php | 67 -- src/network/mcpe/protocol/LabTablePacket.php | 65 -- .../mcpe/protocol/LecternUpdatePacket.php | 63 -- .../mcpe/protocol/LevelChunkPacket.php | 133 --- .../mcpe/protocol/LevelEventGenericPacket.php | 74 -- .../mcpe/protocol/LevelEventPacket.php | 151 ---- .../mcpe/protocol/LevelSoundEventPacket.php | 408 --------- .../mcpe/protocol/LevelSoundEventPacketV1.php | 71 -- .../mcpe/protocol/LevelSoundEventPacketV2.php | 71 -- src/network/mcpe/protocol/LoginPacket.php | 101 --- .../protocol/MapCreateLockedCopyPacket.php | 51 -- .../mcpe/protocol/MapInfoRequestPacket.php | 47 -- .../mcpe/protocol/MobArmorEquipmentPacket.php | 78 -- src/network/mcpe/protocol/MobEffectPacket.php | 90 -- .../mcpe/protocol/MobEquipmentPacket.php | 74 -- .../mcpe/protocol/ModalFormRequestPacket.php | 58 -- .../mcpe/protocol/ModalFormResponsePacket.php | 51 -- .../protocol/MotionPredictionHintsPacket.php | 70 -- .../mcpe/protocol/MoveActorAbsolutePacket.php | 83 -- .../mcpe/protocol/MoveActorDeltaPacket.php | 118 --- .../mcpe/protocol/MovePlayerPacket.php | 97 --- .../protocol/MultiplayerSettingsPacket.php | 61 -- .../NetworkChunkPublisherUpdatePacket.php | 64 -- .../mcpe/protocol/NetworkSettingsPacket.php | 60 -- .../protocol/NetworkStackLatencyPacket.php | 65 -- .../mcpe/protocol/NpcDialoguePacket.php | 87 -- .../mcpe/protocol/NpcRequestPacket.php | 70 -- .../OnScreenTextureAnimationPacket.php | 47 -- src/network/mcpe/protocol/Packet.php | 57 -- .../mcpe/protocol/PacketDecodeException.php | 31 - .../mcpe/protocol/PacketHandlerInterface.php | 357 -------- src/network/mcpe/protocol/PacketPool.php | 227 ----- .../protocol/PacketViolationWarningPacket.php | 84 -- .../mcpe/protocol/PhotoTransferPacket.php | 55 -- src/network/mcpe/protocol/PlaySoundPacket.php | 66 -- .../mcpe/protocol/PlayStatusPacket.php | 66 -- .../mcpe/protocol/PlayerActionPacket.php | 92 -- .../mcpe/protocol/PlayerArmorDamagePacket.php | 108 --- .../mcpe/protocol/PlayerAuthInputPacket.php | 179 ---- .../protocol/PlayerEnchantOptionsPacket.php | 69 -- src/network/mcpe/protocol/PlayerFogPacket.php | 73 -- .../mcpe/protocol/PlayerHotbarPacket.php | 64 -- .../mcpe/protocol/PlayerInputPacket.php | 59 -- .../mcpe/protocol/PlayerListPacket.php | 120 --- .../mcpe/protocol/PlayerSkinPacket.php | 70 -- .../PositionTrackingDBClientRequestPacket.php | 64 -- ...ositionTrackingDBServerBroadcastPacket.php | 81 -- src/network/mcpe/protocol/ProtocolInfo.php | 220 ----- .../mcpe/protocol/PurchaseReceiptPacket.php | 54 -- .../mcpe/protocol/RemoveActorPacket.php | 53 -- .../mcpe/protocol/RemoveEntityPacket.php | 57 -- .../mcpe/protocol/RemoveObjectivePacket.php | 47 -- .../protocol/RemoveVolumeEntityPacket.php | 55 -- .../protocol/RequestChunkRadiusPacket.php | 47 -- .../protocol/ResourcePackChunkDataPacket.php | 68 -- .../ResourcePackChunkRequestPacket.php | 51 -- .../ResourcePackClientResponsePacket.php | 64 -- .../protocol/ResourcePackDataInfoPacket.php | 82 -- .../mcpe/protocol/ResourcePackStackPacket.php | 101 --- .../mcpe/protocol/ResourcePacksInfoPacket.php | 95 --- src/network/mcpe/protocol/RespawnPacket.php | 68 -- src/network/mcpe/protocol/RiderJumpPacket.php | 47 -- .../mcpe/protocol/ScriptCustomEventPacket.php | 51 -- .../protocol/ServerSettingsRequestPacket.php | 44 - .../protocol/ServerSettingsResponsePacket.php | 51 -- .../ServerToClientHandshakePacket.php | 60 -- .../mcpe/protocol/ServerboundPacket.php | 28 - .../mcpe/protocol/SetActorDataPacket.php | 73 -- .../mcpe/protocol/SetActorLinkPacket.php | 48 -- .../mcpe/protocol/SetActorMotionPacket.php | 59 -- .../protocol/SetCommandsEnabledPacket.php | 53 -- .../protocol/SetDefaultGameTypePacket.php | 53 -- .../mcpe/protocol/SetDifficultyPacket.php | 53 -- .../protocol/SetDisplayObjectivePacket.php | 70 -- src/network/mcpe/protocol/SetHealthPacket.php | 47 -- .../mcpe/protocol/SetLastHurtByPacket.php | 47 -- .../SetLocalPlayerAsInitializedPacket.php | 47 -- .../mcpe/protocol/SetPlayerGameTypePacket.php | 53 -- src/network/mcpe/protocol/SetScorePacket.php | 95 --- .../protocol/SetScoreboardIdentityPacket.php | 70 -- .../mcpe/protocol/SetSpawnPositionPacket.php | 88 -- src/network/mcpe/protocol/SetTimePacket.php | 53 -- src/network/mcpe/protocol/SetTitlePacket.php | 119 --- .../mcpe/protocol/SettingsCommandPacket.php | 66 -- .../mcpe/protocol/ShowCreditsPacket.php | 54 -- .../mcpe/protocol/ShowProfilePacket.php | 47 -- .../mcpe/protocol/ShowStoreOfferPacket.php | 51 -- .../mcpe/protocol/SimpleEventPacket.php | 51 -- .../mcpe/protocol/SimulationTypePacket.php | 58 -- .../protocol/SpawnExperienceOrbPacket.php | 52 -- .../protocol/SpawnParticleEffectPacket.php | 61 -- src/network/mcpe/protocol/StartGamePacket.php | 348 -------- src/network/mcpe/protocol/StopSoundPacket.php | 51 -- .../protocol/StructureBlockUpdatePacket.php | 60 -- .../StructureTemplateDataRequestPacket.php | 67 -- .../StructureTemplateDataResponsePacket.php | 60 -- .../mcpe/protocol/SubClientLoginPacket.php | 47 -- .../mcpe/protocol/SyncActorPropertyPacket.php | 58 -- .../mcpe/protocol/TakeItemActorPacket.php | 58 -- src/network/mcpe/protocol/TextPacket.php | 186 ---- src/network/mcpe/protocol/TickSyncPacket.php | 73 -- src/network/mcpe/protocol/TransferPacket.php | 58 -- src/network/mcpe/protocol/UnknownPacket.php | 66 -- .../mcpe/protocol/UpdateAttributesPacket.php | 70 -- .../mcpe/protocol/UpdateBlockPacket.php | 78 -- .../mcpe/protocol/UpdateBlockSyncedPacket.php | 57 -- .../mcpe/protocol/UpdateEquipPacket.php | 67 -- .../protocol/UpdatePlayerGameTypePacket.php | 67 -- .../mcpe/protocol/UpdateSoftEnumPacket.php | 65 -- .../mcpe/protocol/UpdateTradePacket.php | 90 -- .../serializer/ItemTypeDictionary.php | 79 -- .../serializer/NetworkNbtSerializer.php | 101 --- .../mcpe/protocol/serializer/PacketBatch.php | 80 -- .../protocol/serializer/PacketSerializer.php | 795 ------------------ .../serializer/PacketSerializerContext.php | 39 - .../mcpe/protocol/types/BlockPaletteEntry.php | 43 - .../mcpe/protocol/types/BoolGameRule.php | 53 -- .../mcpe/protocol/types/CacheableNbt.php | 60 -- .../mcpe/protocol/types/ChunkCacheBlob.php | 47 -- src/network/mcpe/protocol/types/DeviceOS.php | 44 - .../mcpe/protocol/types/DimensionIds.php | 36 - .../protocol/types/EducationEditionOffer.php | 35 - src/network/mcpe/protocol/types/Enchant.php | 53 -- .../mcpe/protocol/types/EnchantOption.php | 126 --- .../mcpe/protocol/types/Experiments.php | 72 -- .../mcpe/protocol/types/FloatGameRule.php | 52 -- src/network/mcpe/protocol/types/GameMode.php | 38 - src/network/mcpe/protocol/types/GameRule.php | 41 - .../mcpe/protocol/types/GameRuleType.php | 35 - .../mcpe/protocol/types/GeneratorType.php | 37 - src/network/mcpe/protocol/types/InputMode.php | 36 - .../mcpe/protocol/types/IntGameRule.php | 53 -- .../types/ItemComponentPacketEntry.php | 43 - .../mcpe/protocol/types/ItemTypeEntry.php | 46 - .../mcpe/protocol/types/MapDecoration.php | 74 -- .../mcpe/protocol/types/MapTrackedObject.php | 43 - .../types/MultiplayerGameVisibility.php | 37 - .../mcpe/protocol/types/ParticleIds.php | 113 --- src/network/mcpe/protocol/types/PlayMode.php | 45 - .../protocol/types/PlayerAuthInputFlags.php | 75 -- .../mcpe/protocol/types/PlayerListEntry.php | 71 -- .../protocol/types/PlayerMovementSettings.php | 61 -- .../protocol/types/PlayerMovementType.php | 31 - .../mcpe/protocol/types/PlayerPermissions.php | 37 - .../mcpe/protocol/types/ScorePacketEntry.php | 45 - .../types/ScoreboardIdentityPacketEntry.php | 32 - .../mcpe/protocol/types/SpawnSettings.php | 73 -- .../protocol/types/StructureEditorData.php | 48 -- .../mcpe/protocol/types/StructureSettings.php | 59 -- src/network/mcpe/protocol/types/UIProfile.php | 34 - .../protocol/types/command/CommandData.php | 83 -- .../protocol/types/command/CommandEnum.php | 55 -- .../types/command/CommandEnumConstraint.php | 65 -- .../types/command/CommandOriginData.php | 52 -- .../types/command/CommandOutputMessage.php | 34 - .../types/command/CommandParameter.php | 69 -- .../mcpe/protocol/types/entity/Attribute.php | 65 -- .../types/entity/BlockPosMetadataProperty.php | 59 -- .../types/entity/ByteMetadataProperty.php | 50 -- .../entity/CompoundTagMetadataProperty.php | 62 -- .../mcpe/protocol/types/entity/EntityIds.php | 148 ---- .../mcpe/protocol/types/entity/EntityLink.php | 50 -- .../types/entity/EntityMetadataCollection.php | 152 ---- .../types/entity/EntityMetadataFlags.php | 126 --- .../types/entity/EntityMetadataProperties.php | 150 ---- .../types/entity/EntityMetadataTypes.php | 41 - .../types/entity/FloatMetadataProperty.php | 56 -- .../types/entity/IntMetadataProperty.php | 50 -- .../entity/IntegerishMetadataProperty.php | 62 -- .../types/entity/LongMetadataProperty.php | 52 -- .../types/entity/MetadataProperty.php | 35 - .../types/entity/PlayerMetadataFlags.php | 34 - .../types/entity/ShortMetadataProperty.php | 50 -- .../types/entity/StringMetadataProperty.php | 51 -- .../types/entity/Vec3MetadataProperty.php | 56 -- .../protocol/types/inventory/ContainerIds.php | 43 - .../types/inventory/CreativeContentEntry.php | 54 -- .../InventoryTransactionChangedSlotsHack.php | 65 -- .../protocol/types/inventory/ItemStack.php | 142 ---- .../types/inventory/ItemStackWrapper.php | 67 -- .../inventory/MismatchTransactionData.php | 50 -- .../inventory/NetworkInventoryAction.php | 138 --- .../types/inventory/NormalTransactionData.php | 53 -- .../inventory/ReleaseItemTransactionData.php | 90 -- .../types/inventory/TransactionData.php | 71 -- .../types/inventory/UIInventorySlotOffset.php | 105 --- .../UseItemOnEntityTransactionData.php | 108 --- .../inventory/UseItemTransactionData.php | 128 --- .../protocol/types/inventory/WindowTypes.php | 70 -- .../BeaconPaymentStackRequestAction.php | 59 -- .../CraftRecipeAutoStackRequestAction.php | 34 - .../CraftRecipeOptionalStackRequestAction.php | 59 -- .../CraftRecipeStackRequestAction.php | 33 - .../CraftRecipeStackRequestActionTrait.php | 47 -- ...CraftingConsumeInputStackRequestAction.php | 33 - ...gMarkSecondaryResultStackRequestAction.php | 53 -- .../CreativeCreateStackRequestAction.php | 52 -- ...aftingNonImplementedStackRequestAction.php | 45 - ...catedCraftingResultsStackRequestAction.php | 74 -- .../DestroyStackRequestAction.php | 34 - .../DisappearStackRequestActionTrait.php | 53 -- .../stackrequest/DropStackRequestAction.php | 66 -- .../stackrequest/ItemStackRequest.php | 110 --- .../stackrequest/ItemStackRequestAction.php | 33 - .../ItemStackRequestActionType.php | 48 -- .../stackrequest/ItemStackRequestSlotInfo.php | 61 -- .../LabTableCombineStackRequestAction.php | 43 - .../MineBlockStackRequestAction.php | 63 -- .../stackrequest/PlaceStackRequestAction.php | 33 - .../stackrequest/SwapStackRequestAction.php | 59 -- .../TakeOrPlaceStackRequestActionTrait.php | 61 -- .../stackrequest/TakeStackRequestAction.php | 33 - .../stackresponse/ItemStackResponse.php | 77 -- .../ItemStackResponseContainerInfo.php | 65 -- .../ItemStackResponseSlotInfo.php | 82 -- .../types/login/AuthenticationData.php | 41 - .../mcpe/protocol/types/login/ClientData.php | 149 ---- .../types/login/ClientDataAnimationFrame.php | 48 -- .../login/ClientDataPersonaPieceTintColor.php | 38 - .../login/ClientDataPersonaSkinPiece.php | 44 - .../login/ClientDataToSkinDataHelper.php | 89 -- .../protocol/types/login/JwtBodyRfc7519.php | 39 - .../mcpe/protocol/types/login/JwtChain.php | 36 - .../protocol/types/login/JwtChainLinkBody.php | 32 - .../mcpe/protocol/types/login/JwtHeader.php | 31 - .../protocol/types/recipe/FurnaceRecipe.php | 85 -- .../protocol/types/recipe/MultiRecipe.php | 73 -- .../recipe/PotionContainerChangeRecipe.php | 51 -- .../types/recipe/PotionTypeRecipe.php | 72 -- .../types/recipe/RecipeIngredient.php | 52 -- .../types/recipe/RecipeWithTypeId.php | 41 - .../protocol/types/recipe/ShapedRecipe.php | 160 ---- .../protocol/types/recipe/ShapelessRecipe.php | 132 --- .../resourcepacks/BehaviorPackInfoEntry.php | 103 --- .../resourcepacks/ResourcePackInfoEntry.php | 110 --- .../resourcepacks/ResourcePackStackEntry.php | 67 -- .../types/resourcepacks/ResourcePackType.php | 41 - .../types/skin/PersonaPieceTintColor.php | 55 -- .../protocol/types/skin/PersonaSkinPiece.php | 77 -- .../protocol/types/skin/SkinAnimation.php | 73 -- .../mcpe/protocol/types/skin/SkinData.php | 182 ---- .../mcpe/protocol/types/skin/SkinImage.php | 73 -- 307 files changed, 51 insertions(+), 23572 deletions(-) delete mode 100644 src/network/mcpe/protocol/ActorEventPacket.php delete mode 100644 src/network/mcpe/protocol/ActorPickRequestPacket.php delete mode 100644 src/network/mcpe/protocol/AddActorPacket.php delete mode 100644 src/network/mcpe/protocol/AddBehaviorTreePacket.php delete mode 100644 src/network/mcpe/protocol/AddEntityPacket.php delete mode 100644 src/network/mcpe/protocol/AddItemActorPacket.php delete mode 100644 src/network/mcpe/protocol/AddPaintingPacket.php delete mode 100644 src/network/mcpe/protocol/AddPlayerPacket.php delete mode 100644 src/network/mcpe/protocol/AddVolumeEntityPacket.php delete mode 100644 src/network/mcpe/protocol/AdventureSettingsPacket.php delete mode 100644 src/network/mcpe/protocol/AnimateEntityPacket.php delete mode 100644 src/network/mcpe/protocol/AnimatePacket.php delete mode 100644 src/network/mcpe/protocol/AnvilDamagePacket.php delete mode 100644 src/network/mcpe/protocol/AutomationClientConnectPacket.php delete mode 100644 src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php delete mode 100644 src/network/mcpe/protocol/AvailableCommandsPacket.php delete mode 100644 src/network/mcpe/protocol/BiomeDefinitionListPacket.php delete mode 100644 src/network/mcpe/protocol/BlockActorDataPacket.php delete mode 100644 src/network/mcpe/protocol/BlockEventPacket.php delete mode 100644 src/network/mcpe/protocol/BlockPickRequestPacket.php delete mode 100644 src/network/mcpe/protocol/BookEditPacket.php delete mode 100644 src/network/mcpe/protocol/BossEventPacket.php delete mode 100644 src/network/mcpe/protocol/CameraPacket.php delete mode 100644 src/network/mcpe/protocol/CameraShakePacket.php delete mode 100644 src/network/mcpe/protocol/ChangeDimensionPacket.php delete mode 100644 src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php delete mode 100644 src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php delete mode 100644 src/network/mcpe/protocol/ClientCacheMissResponsePacket.php delete mode 100644 src/network/mcpe/protocol/ClientCacheStatusPacket.php delete mode 100644 src/network/mcpe/protocol/ClientToServerHandshakePacket.php delete mode 100644 src/network/mcpe/protocol/ClientboundDebugRendererPacket.php delete mode 100644 src/network/mcpe/protocol/ClientboundMapItemDataPacket.php delete mode 100644 src/network/mcpe/protocol/ClientboundPacket.php delete mode 100644 src/network/mcpe/protocol/CodeBuilderPacket.php delete mode 100644 src/network/mcpe/protocol/CommandBlockUpdatePacket.php delete mode 100644 src/network/mcpe/protocol/CommandOutputPacket.php delete mode 100644 src/network/mcpe/protocol/CommandRequestPacket.php delete mode 100644 src/network/mcpe/protocol/CompletedUsingItemPacket.php delete mode 100644 src/network/mcpe/protocol/ContainerClosePacket.php delete mode 100644 src/network/mcpe/protocol/ContainerOpenPacket.php delete mode 100644 src/network/mcpe/protocol/ContainerSetDataPacket.php delete mode 100644 src/network/mcpe/protocol/CorrectPlayerMovePredictionPacket.php delete mode 100644 src/network/mcpe/protocol/CraftingDataPacket.php delete mode 100644 src/network/mcpe/protocol/CraftingEventPacket.php delete mode 100644 src/network/mcpe/protocol/CreativeContentPacket.php delete mode 100644 src/network/mcpe/protocol/DataPacket.php delete mode 100644 src/network/mcpe/protocol/DebugInfoPacket.php delete mode 100644 src/network/mcpe/protocol/DisconnectPacket.php delete mode 100644 src/network/mcpe/protocol/EducationSettingsPacket.php delete mode 100644 src/network/mcpe/protocol/EmoteListPacket.php delete mode 100644 src/network/mcpe/protocol/EmotePacket.php delete mode 100644 src/network/mcpe/protocol/EventPacket.php delete mode 100644 src/network/mcpe/protocol/FilterTextPacket.php delete mode 100644 src/network/mcpe/protocol/GameRulesChangedPacket.php delete mode 100644 src/network/mcpe/protocol/GuiDataPickItemPacket.php delete mode 100644 src/network/mcpe/protocol/HurtArmorPacket.php delete mode 100644 src/network/mcpe/protocol/InteractPacket.php delete mode 100644 src/network/mcpe/protocol/InventoryContentPacket.php delete mode 100644 src/network/mcpe/protocol/InventorySlotPacket.php delete mode 100644 src/network/mcpe/protocol/InventoryTransactionPacket.php delete mode 100644 src/network/mcpe/protocol/ItemComponentPacket.php delete mode 100644 src/network/mcpe/protocol/ItemFrameDropItemPacket.php delete mode 100644 src/network/mcpe/protocol/ItemStackRequestPacket.php delete mode 100644 src/network/mcpe/protocol/ItemStackResponsePacket.php delete mode 100644 src/network/mcpe/protocol/LabTablePacket.php delete mode 100644 src/network/mcpe/protocol/LecternUpdatePacket.php delete mode 100644 src/network/mcpe/protocol/LevelChunkPacket.php delete mode 100644 src/network/mcpe/protocol/LevelEventGenericPacket.php delete mode 100644 src/network/mcpe/protocol/LevelEventPacket.php delete mode 100644 src/network/mcpe/protocol/LevelSoundEventPacket.php delete mode 100644 src/network/mcpe/protocol/LevelSoundEventPacketV1.php delete mode 100644 src/network/mcpe/protocol/LevelSoundEventPacketV2.php delete mode 100644 src/network/mcpe/protocol/LoginPacket.php delete mode 100644 src/network/mcpe/protocol/MapCreateLockedCopyPacket.php delete mode 100644 src/network/mcpe/protocol/MapInfoRequestPacket.php delete mode 100644 src/network/mcpe/protocol/MobArmorEquipmentPacket.php delete mode 100644 src/network/mcpe/protocol/MobEffectPacket.php delete mode 100644 src/network/mcpe/protocol/MobEquipmentPacket.php delete mode 100644 src/network/mcpe/protocol/ModalFormRequestPacket.php delete mode 100644 src/network/mcpe/protocol/ModalFormResponsePacket.php delete mode 100644 src/network/mcpe/protocol/MotionPredictionHintsPacket.php delete mode 100644 src/network/mcpe/protocol/MoveActorAbsolutePacket.php delete mode 100644 src/network/mcpe/protocol/MoveActorDeltaPacket.php delete mode 100644 src/network/mcpe/protocol/MovePlayerPacket.php delete mode 100644 src/network/mcpe/protocol/MultiplayerSettingsPacket.php delete mode 100644 src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php delete mode 100644 src/network/mcpe/protocol/NetworkSettingsPacket.php delete mode 100644 src/network/mcpe/protocol/NetworkStackLatencyPacket.php delete mode 100644 src/network/mcpe/protocol/NpcDialoguePacket.php delete mode 100644 src/network/mcpe/protocol/NpcRequestPacket.php delete mode 100644 src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php delete mode 100644 src/network/mcpe/protocol/Packet.php delete mode 100644 src/network/mcpe/protocol/PacketDecodeException.php delete mode 100644 src/network/mcpe/protocol/PacketHandlerInterface.php delete mode 100644 src/network/mcpe/protocol/PacketPool.php delete mode 100644 src/network/mcpe/protocol/PacketViolationWarningPacket.php delete mode 100644 src/network/mcpe/protocol/PhotoTransferPacket.php delete mode 100644 src/network/mcpe/protocol/PlaySoundPacket.php delete mode 100644 src/network/mcpe/protocol/PlayStatusPacket.php delete mode 100644 src/network/mcpe/protocol/PlayerActionPacket.php delete mode 100644 src/network/mcpe/protocol/PlayerArmorDamagePacket.php delete mode 100644 src/network/mcpe/protocol/PlayerAuthInputPacket.php delete mode 100644 src/network/mcpe/protocol/PlayerEnchantOptionsPacket.php delete mode 100644 src/network/mcpe/protocol/PlayerFogPacket.php delete mode 100644 src/network/mcpe/protocol/PlayerHotbarPacket.php delete mode 100644 src/network/mcpe/protocol/PlayerInputPacket.php delete mode 100644 src/network/mcpe/protocol/PlayerListPacket.php delete mode 100644 src/network/mcpe/protocol/PlayerSkinPacket.php delete mode 100644 src/network/mcpe/protocol/PositionTrackingDBClientRequestPacket.php delete mode 100644 src/network/mcpe/protocol/PositionTrackingDBServerBroadcastPacket.php delete mode 100644 src/network/mcpe/protocol/ProtocolInfo.php delete mode 100644 src/network/mcpe/protocol/PurchaseReceiptPacket.php delete mode 100644 src/network/mcpe/protocol/RemoveActorPacket.php delete mode 100644 src/network/mcpe/protocol/RemoveEntityPacket.php delete mode 100644 src/network/mcpe/protocol/RemoveObjectivePacket.php delete mode 100644 src/network/mcpe/protocol/RemoveVolumeEntityPacket.php delete mode 100644 src/network/mcpe/protocol/RequestChunkRadiusPacket.php delete mode 100644 src/network/mcpe/protocol/ResourcePackChunkDataPacket.php delete mode 100644 src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php delete mode 100644 src/network/mcpe/protocol/ResourcePackClientResponsePacket.php delete mode 100644 src/network/mcpe/protocol/ResourcePackDataInfoPacket.php delete mode 100644 src/network/mcpe/protocol/ResourcePackStackPacket.php delete mode 100644 src/network/mcpe/protocol/ResourcePacksInfoPacket.php delete mode 100644 src/network/mcpe/protocol/RespawnPacket.php delete mode 100644 src/network/mcpe/protocol/RiderJumpPacket.php delete mode 100644 src/network/mcpe/protocol/ScriptCustomEventPacket.php delete mode 100644 src/network/mcpe/protocol/ServerSettingsRequestPacket.php delete mode 100644 src/network/mcpe/protocol/ServerSettingsResponsePacket.php delete mode 100644 src/network/mcpe/protocol/ServerToClientHandshakePacket.php delete mode 100644 src/network/mcpe/protocol/ServerboundPacket.php delete mode 100644 src/network/mcpe/protocol/SetActorDataPacket.php delete mode 100644 src/network/mcpe/protocol/SetActorLinkPacket.php delete mode 100644 src/network/mcpe/protocol/SetActorMotionPacket.php delete mode 100644 src/network/mcpe/protocol/SetCommandsEnabledPacket.php delete mode 100644 src/network/mcpe/protocol/SetDefaultGameTypePacket.php delete mode 100644 src/network/mcpe/protocol/SetDifficultyPacket.php delete mode 100644 src/network/mcpe/protocol/SetDisplayObjectivePacket.php delete mode 100644 src/network/mcpe/protocol/SetHealthPacket.php delete mode 100644 src/network/mcpe/protocol/SetLastHurtByPacket.php delete mode 100644 src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php delete mode 100644 src/network/mcpe/protocol/SetPlayerGameTypePacket.php delete mode 100644 src/network/mcpe/protocol/SetScorePacket.php delete mode 100644 src/network/mcpe/protocol/SetScoreboardIdentityPacket.php delete mode 100644 src/network/mcpe/protocol/SetSpawnPositionPacket.php delete mode 100644 src/network/mcpe/protocol/SetTimePacket.php delete mode 100644 src/network/mcpe/protocol/SetTitlePacket.php delete mode 100644 src/network/mcpe/protocol/SettingsCommandPacket.php delete mode 100644 src/network/mcpe/protocol/ShowCreditsPacket.php delete mode 100644 src/network/mcpe/protocol/ShowProfilePacket.php delete mode 100644 src/network/mcpe/protocol/ShowStoreOfferPacket.php delete mode 100644 src/network/mcpe/protocol/SimpleEventPacket.php delete mode 100644 src/network/mcpe/protocol/SimulationTypePacket.php delete mode 100644 src/network/mcpe/protocol/SpawnExperienceOrbPacket.php delete mode 100644 src/network/mcpe/protocol/SpawnParticleEffectPacket.php delete mode 100644 src/network/mcpe/protocol/StartGamePacket.php delete mode 100644 src/network/mcpe/protocol/StopSoundPacket.php delete mode 100644 src/network/mcpe/protocol/StructureBlockUpdatePacket.php delete mode 100644 src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php delete mode 100644 src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php delete mode 100644 src/network/mcpe/protocol/SubClientLoginPacket.php delete mode 100644 src/network/mcpe/protocol/SyncActorPropertyPacket.php delete mode 100644 src/network/mcpe/protocol/TakeItemActorPacket.php delete mode 100644 src/network/mcpe/protocol/TextPacket.php delete mode 100644 src/network/mcpe/protocol/TickSyncPacket.php delete mode 100644 src/network/mcpe/protocol/TransferPacket.php delete mode 100644 src/network/mcpe/protocol/UnknownPacket.php delete mode 100644 src/network/mcpe/protocol/UpdateAttributesPacket.php delete mode 100644 src/network/mcpe/protocol/UpdateBlockPacket.php delete mode 100644 src/network/mcpe/protocol/UpdateBlockSyncedPacket.php delete mode 100644 src/network/mcpe/protocol/UpdateEquipPacket.php delete mode 100644 src/network/mcpe/protocol/UpdatePlayerGameTypePacket.php delete mode 100644 src/network/mcpe/protocol/UpdateSoftEnumPacket.php delete mode 100644 src/network/mcpe/protocol/UpdateTradePacket.php delete mode 100644 src/network/mcpe/protocol/serializer/ItemTypeDictionary.php delete mode 100644 src/network/mcpe/protocol/serializer/NetworkNbtSerializer.php delete mode 100644 src/network/mcpe/protocol/serializer/PacketBatch.php delete mode 100644 src/network/mcpe/protocol/serializer/PacketSerializer.php delete mode 100644 src/network/mcpe/protocol/serializer/PacketSerializerContext.php delete mode 100644 src/network/mcpe/protocol/types/BlockPaletteEntry.php delete mode 100644 src/network/mcpe/protocol/types/BoolGameRule.php delete mode 100644 src/network/mcpe/protocol/types/CacheableNbt.php delete mode 100644 src/network/mcpe/protocol/types/ChunkCacheBlob.php delete mode 100644 src/network/mcpe/protocol/types/DeviceOS.php delete mode 100644 src/network/mcpe/protocol/types/DimensionIds.php delete mode 100644 src/network/mcpe/protocol/types/EducationEditionOffer.php delete mode 100644 src/network/mcpe/protocol/types/Enchant.php delete mode 100644 src/network/mcpe/protocol/types/EnchantOption.php delete mode 100644 src/network/mcpe/protocol/types/Experiments.php delete mode 100644 src/network/mcpe/protocol/types/FloatGameRule.php delete mode 100644 src/network/mcpe/protocol/types/GameMode.php delete mode 100644 src/network/mcpe/protocol/types/GameRule.php delete mode 100644 src/network/mcpe/protocol/types/GameRuleType.php delete mode 100644 src/network/mcpe/protocol/types/GeneratorType.php delete mode 100644 src/network/mcpe/protocol/types/InputMode.php delete mode 100644 src/network/mcpe/protocol/types/IntGameRule.php delete mode 100644 src/network/mcpe/protocol/types/ItemComponentPacketEntry.php delete mode 100644 src/network/mcpe/protocol/types/ItemTypeEntry.php delete mode 100644 src/network/mcpe/protocol/types/MapDecoration.php delete mode 100644 src/network/mcpe/protocol/types/MapTrackedObject.php delete mode 100644 src/network/mcpe/protocol/types/MultiplayerGameVisibility.php delete mode 100644 src/network/mcpe/protocol/types/ParticleIds.php delete mode 100644 src/network/mcpe/protocol/types/PlayMode.php delete mode 100644 src/network/mcpe/protocol/types/PlayerAuthInputFlags.php delete mode 100644 src/network/mcpe/protocol/types/PlayerListEntry.php delete mode 100644 src/network/mcpe/protocol/types/PlayerMovementSettings.php delete mode 100644 src/network/mcpe/protocol/types/PlayerMovementType.php delete mode 100644 src/network/mcpe/protocol/types/PlayerPermissions.php delete mode 100644 src/network/mcpe/protocol/types/ScorePacketEntry.php delete mode 100644 src/network/mcpe/protocol/types/ScoreboardIdentityPacketEntry.php delete mode 100644 src/network/mcpe/protocol/types/SpawnSettings.php delete mode 100644 src/network/mcpe/protocol/types/StructureEditorData.php delete mode 100644 src/network/mcpe/protocol/types/StructureSettings.php delete mode 100644 src/network/mcpe/protocol/types/UIProfile.php delete mode 100644 src/network/mcpe/protocol/types/command/CommandData.php delete mode 100644 src/network/mcpe/protocol/types/command/CommandEnum.php delete mode 100644 src/network/mcpe/protocol/types/command/CommandEnumConstraint.php delete mode 100644 src/network/mcpe/protocol/types/command/CommandOriginData.php delete mode 100644 src/network/mcpe/protocol/types/command/CommandOutputMessage.php delete mode 100644 src/network/mcpe/protocol/types/command/CommandParameter.php delete mode 100644 src/network/mcpe/protocol/types/entity/Attribute.php delete mode 100644 src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php delete mode 100644 src/network/mcpe/protocol/types/entity/ByteMetadataProperty.php delete mode 100644 src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php delete mode 100644 src/network/mcpe/protocol/types/entity/EntityIds.php delete mode 100644 src/network/mcpe/protocol/types/entity/EntityLink.php delete mode 100644 src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php delete mode 100644 src/network/mcpe/protocol/types/entity/EntityMetadataFlags.php delete mode 100644 src/network/mcpe/protocol/types/entity/EntityMetadataProperties.php delete mode 100644 src/network/mcpe/protocol/types/entity/EntityMetadataTypes.php delete mode 100644 src/network/mcpe/protocol/types/entity/FloatMetadataProperty.php delete mode 100644 src/network/mcpe/protocol/types/entity/IntMetadataProperty.php delete mode 100644 src/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php delete mode 100644 src/network/mcpe/protocol/types/entity/LongMetadataProperty.php delete mode 100644 src/network/mcpe/protocol/types/entity/MetadataProperty.php delete mode 100644 src/network/mcpe/protocol/types/entity/PlayerMetadataFlags.php delete mode 100644 src/network/mcpe/protocol/types/entity/ShortMetadataProperty.php delete mode 100644 src/network/mcpe/protocol/types/entity/StringMetadataProperty.php delete mode 100644 src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php delete mode 100644 src/network/mcpe/protocol/types/inventory/ContainerIds.php delete mode 100644 src/network/mcpe/protocol/types/inventory/CreativeContentEntry.php delete mode 100644 src/network/mcpe/protocol/types/inventory/InventoryTransactionChangedSlotsHack.php delete mode 100644 src/network/mcpe/protocol/types/inventory/ItemStack.php delete mode 100644 src/network/mcpe/protocol/types/inventory/ItemStackWrapper.php delete mode 100644 src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php delete mode 100644 src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php delete mode 100644 src/network/mcpe/protocol/types/inventory/NormalTransactionData.php delete mode 100644 src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php delete mode 100644 src/network/mcpe/protocol/types/inventory/TransactionData.php delete mode 100644 src/network/mcpe/protocol/types/inventory/UIInventorySlotOffset.php delete mode 100644 src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php delete mode 100644 src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php delete mode 100644 src/network/mcpe/protocol/types/inventory/WindowTypes.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/BeaconPaymentStackRequestAction.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/CraftRecipeAutoStackRequestAction.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/CraftRecipeOptionalStackRequestAction.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/CraftRecipeStackRequestAction.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/CraftRecipeStackRequestActionTrait.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/CraftingConsumeInputStackRequestAction.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/CraftingMarkSecondaryResultStackRequestAction.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/CreativeCreateStackRequestAction.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/DeprecatedCraftingNonImplementedStackRequestAction.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/DeprecatedCraftingResultsStackRequestAction.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/DestroyStackRequestAction.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/DisappearStackRequestActionTrait.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/DropStackRequestAction.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/ItemStackRequest.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/ItemStackRequestAction.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/ItemStackRequestActionType.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/ItemStackRequestSlotInfo.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/LabTableCombineStackRequestAction.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/MineBlockStackRequestAction.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/PlaceStackRequestAction.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/SwapStackRequestAction.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/TakeOrPlaceStackRequestActionTrait.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackrequest/TakeStackRequestAction.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackresponse/ItemStackResponse.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackresponse/ItemStackResponseContainerInfo.php delete mode 100644 src/network/mcpe/protocol/types/inventory/stackresponse/ItemStackResponseSlotInfo.php delete mode 100644 src/network/mcpe/protocol/types/login/AuthenticationData.php delete mode 100644 src/network/mcpe/protocol/types/login/ClientData.php delete mode 100644 src/network/mcpe/protocol/types/login/ClientDataAnimationFrame.php delete mode 100644 src/network/mcpe/protocol/types/login/ClientDataPersonaPieceTintColor.php delete mode 100644 src/network/mcpe/protocol/types/login/ClientDataPersonaSkinPiece.php delete mode 100644 src/network/mcpe/protocol/types/login/ClientDataToSkinDataHelper.php delete mode 100644 src/network/mcpe/protocol/types/login/JwtBodyRfc7519.php delete mode 100644 src/network/mcpe/protocol/types/login/JwtChain.php delete mode 100644 src/network/mcpe/protocol/types/login/JwtChainLinkBody.php delete mode 100644 src/network/mcpe/protocol/types/login/JwtHeader.php delete mode 100644 src/network/mcpe/protocol/types/recipe/FurnaceRecipe.php delete mode 100644 src/network/mcpe/protocol/types/recipe/MultiRecipe.php delete mode 100644 src/network/mcpe/protocol/types/recipe/PotionContainerChangeRecipe.php delete mode 100644 src/network/mcpe/protocol/types/recipe/PotionTypeRecipe.php delete mode 100644 src/network/mcpe/protocol/types/recipe/RecipeIngredient.php delete mode 100644 src/network/mcpe/protocol/types/recipe/RecipeWithTypeId.php delete mode 100644 src/network/mcpe/protocol/types/recipe/ShapedRecipe.php delete mode 100644 src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php delete mode 100644 src/network/mcpe/protocol/types/resourcepacks/BehaviorPackInfoEntry.php delete mode 100644 src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php delete mode 100644 src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php delete mode 100644 src/network/mcpe/protocol/types/resourcepacks/ResourcePackType.php delete mode 100644 src/network/mcpe/protocol/types/skin/PersonaPieceTintColor.php delete mode 100644 src/network/mcpe/protocol/types/skin/PersonaSkinPiece.php delete mode 100644 src/network/mcpe/protocol/types/skin/SkinAnimation.php delete mode 100644 src/network/mcpe/protocol/types/skin/SkinData.php delete mode 100644 src/network/mcpe/protocol/types/skin/SkinImage.php diff --git a/composer.json b/composer.json index 37ac6a7b0e..1f4d6cac1a 100644 --- a/composer.json +++ b/composer.json @@ -34,6 +34,7 @@ "adhocore/json-comment": "^1.1", "mdanter/ecc": "^1.0", "netresearch/jsonmapper": "^4.0", + "pocketmine/bedrock-protocol": "dev-master#88ae308a03e8e61ccfdddd42623efabe9e772b42", "pocketmine/binaryutils": "^0.2.1", "pocketmine/callback-validator": "^1.0.2", "pocketmine/classloader": "dev-master", diff --git a/composer.lock b/composer.lock index 4810dab992..56ce589d9a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5456f8b834ba877a4c04d1cf5a933d63", + "content-hash": "4748ce46dd62b80f9a89791d7601b57f", "packages": [ { "name": "adhocore/json-comment", @@ -319,6 +319,54 @@ }, "time": "2020-12-01T19:48:11+00:00" }, + { + "name": "pocketmine/bedrock-protocol", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/pmmp/BedrockProtocol.git", + "reference": "88ae308a03e8e61ccfdddd42623efabe9e772b42" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/88ae308a03e8e61ccfdddd42623efabe9e772b42", + "reference": "88ae308a03e8e61ccfdddd42623efabe9e772b42", + "shasum": "" + }, + "require": { + "ext-json": "*", + "netresearch/jsonmapper": "^4.0", + "php": "^7.4 || ^8.0", + "pocketmine/binaryutils": "^0.2.0", + "pocketmine/color": "^0.2.0", + "pocketmine/math": "^0.3.0", + "pocketmine/nbt": "^0.3.0", + "ramsey/uuid": "^4.1" + }, + "require-dev": { + "phpstan/phpstan": "0.12.92", + "phpstan/phpstan-phpunit": "^0.12.21", + "phpstan/phpstan-strict-rules": "^0.12.10", + "phpunit/phpunit": "^9.5" + }, + "default-branch": true, + "type": "library", + "autoload": { + "psr-4": { + "pocketmine\\network\\mcpe\\protocol\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0" + ], + "description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP", + "support": { + "issues": "https://github.com/pmmp/BedrockProtocol/issues", + "source": "https://github.com/pmmp/BedrockProtocol/tree/master" + }, + "time": "2021-07-14T19:29:34+00:00" + }, { "name": "pocketmine/binaryutils", "version": "0.2.1", @@ -3547,6 +3595,7 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { + "pocketmine/bedrock-protocol": 20, "pocketmine/classloader": 20, "pocketmine/spl": 20 }, diff --git a/src/network/mcpe/protocol/ActorEventPacket.php b/src/network/mcpe/protocol/ActorEventPacket.php deleted file mode 100644 index a6cc893ab9..0000000000 --- a/src/network/mcpe/protocol/ActorEventPacket.php +++ /dev/null @@ -1,124 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ActorEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::ACTOR_EVENT_PACKET; - - public const JUMP = 1; - public const HURT_ANIMATION = 2; - public const DEATH_ANIMATION = 3; - public const ARM_SWING = 4; - public const STOP_ATTACK = 5; - public const TAME_FAIL = 6; - public const TAME_SUCCESS = 7; - public const SHAKE_WET = 8; - public const USE_ITEM = 9; - public const EAT_GRASS_ANIMATION = 10; - public const FISH_HOOK_BUBBLE = 11; - public const FISH_HOOK_POSITION = 12; - public const FISH_HOOK_HOOK = 13; - public const FISH_HOOK_TEASE = 14; - public const SQUID_INK_CLOUD = 15; - public const ZOMBIE_VILLAGER_CURE = 16; - - public const RESPAWN = 18; - public const IRON_GOLEM_OFFER_FLOWER = 19; - public const IRON_GOLEM_WITHDRAW_FLOWER = 20; - public const LOVE_PARTICLES = 21; //breeding - public const VILLAGER_ANGRY = 22; - public const VILLAGER_HAPPY = 23; - public const WITCH_SPELL_PARTICLES = 24; - public const FIREWORK_PARTICLES = 25; - public const IN_LOVE_PARTICLES = 26; - public const SILVERFISH_SPAWN_ANIMATION = 27; - public const GUARDIAN_ATTACK = 28; - public const WITCH_DRINK_POTION = 29; - public const WITCH_THROW_POTION = 30; - public const MINECART_TNT_PRIME_FUSE = 31; - public const CREEPER_PRIME_FUSE = 32; - public const AIR_SUPPLY_EXPIRED = 33; - public const PLAYER_ADD_XP_LEVELS = 34; - public const ELDER_GUARDIAN_CURSE = 35; - public const AGENT_ARM_SWING = 36; - public const ENDER_DRAGON_DEATH = 37; - public const DUST_PARTICLES = 38; //not sure what this is - public const ARROW_SHAKE = 39; - - public const EATING_ITEM = 57; - - public const BABY_ANIMAL_FEED = 60; //green particles, like bonemeal on crops - public const DEATH_SMOKE_CLOUD = 61; - public const COMPLETE_TRADE = 62; - public const REMOVE_LEASH = 63; //data 1 = cut leash - - public const CONSUME_TOTEM = 65; - public const PLAYER_CHECK_TREASURE_HUNTER_ACHIEVEMENT = 66; //mojang... - public const ENTITY_SPAWN = 67; //used for MinecraftEventing stuff, not needed - public const DRAGON_PUKE = 68; //they call this puke particles - public const ITEM_ENTITY_MERGE = 69; - public const START_SWIM = 70; - public const BALLOON_POP = 71; - public const TREASURE_HUNT = 72; - public const AGENT_SUMMON = 73; - public const CHARGED_CROSSBOW = 74; - public const FALL = 75; - - //TODO: add more events - - /** @var int */ - public $entityRuntimeId; - /** @var int */ - public $event; - /** @var int */ - public $data = 0; - - public static function create(int $entityRuntimeId, int $eventId, int $eventData) : self{ - $result = new self; - $result->entityRuntimeId = $entityRuntimeId; - $result->event = $eventId; - $result->data = $eventData; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityRuntimeId = $in->getEntityRuntimeId(); - $this->event = $in->getByte(); - $this->data = $in->getVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityRuntimeId($this->entityRuntimeId); - $out->putByte($this->event); - $out->putVarInt($this->data); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleActorEvent($this); - } -} diff --git a/src/network/mcpe/protocol/ActorPickRequestPacket.php b/src/network/mcpe/protocol/ActorPickRequestPacket.php deleted file mode 100644 index bf04e560a8..0000000000 --- a/src/network/mcpe/protocol/ActorPickRequestPacket.php +++ /dev/null @@ -1,51 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ActorPickRequestPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::ACTOR_PICK_REQUEST_PACKET; - - /** @var int */ - public $entityUniqueId; - /** @var int */ - public $hotbarSlot; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityUniqueId = $in->getLLong(); - $this->hotbarSlot = $in->getByte(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putLLong($this->entityUniqueId); - $out->putByte($this->hotbarSlot); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleActorPickRequest($this); - } -} diff --git a/src/network/mcpe/protocol/AddActorPacket.php b/src/network/mcpe/protocol/AddActorPacket.php deleted file mode 100644 index 356797ade3..0000000000 --- a/src/network/mcpe/protocol/AddActorPacket.php +++ /dev/null @@ -1,119 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\entity\Attribute; -use pocketmine\network\mcpe\protocol\types\entity\EntityLink; -use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; -use function count; - -class AddActorPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::ADD_ACTOR_PACKET; - - /** @var int|null */ - public $entityUniqueId = null; //TODO - /** @var int */ - public $entityRuntimeId; - /** @var string */ - public $type; - /** @var Vector3 */ - public $position; - /** @var Vector3|null */ - public $motion; - /** @var float */ - public $pitch = 0.0; - /** @var float */ - public $yaw = 0.0; - /** @var float */ - public $headYaw = 0.0; - - /** @var Attribute[] */ - public $attributes = []; - /** - * @var MetadataProperty[] - * @phpstan-var array - */ - public $metadata = []; - /** @var EntityLink[] */ - public $links = []; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityUniqueId = $in->getEntityUniqueId(); - $this->entityRuntimeId = $in->getEntityRuntimeId(); - $this->type = $in->getString(); - $this->position = $in->getVector3(); - $this->motion = $in->getVector3(); - $this->pitch = $in->getLFloat(); - $this->yaw = $in->getLFloat(); - $this->headYaw = $in->getLFloat(); - - $attrCount = $in->getUnsignedVarInt(); - for($i = 0; $i < $attrCount; ++$i){ - $id = $in->getString(); - $min = $in->getLFloat(); - $current = $in->getLFloat(); - $max = $in->getLFloat(); - $this->attributes[] = new Attribute($id, $min, $max, $current, $current); - } - - $this->metadata = $in->getEntityMetadata(); - $linkCount = $in->getUnsignedVarInt(); - for($i = 0; $i < $linkCount; ++$i){ - $this->links[] = $in->getEntityLink(); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); - $out->putEntityRuntimeId($this->entityRuntimeId); - $out->putString($this->type); - $out->putVector3($this->position); - $out->putVector3Nullable($this->motion); - $out->putLFloat($this->pitch); - $out->putLFloat($this->yaw); - $out->putLFloat($this->headYaw); - - $out->putUnsignedVarInt(count($this->attributes)); - foreach($this->attributes as $attribute){ - $out->putString($attribute->getId()); - $out->putLFloat($attribute->getMin()); - $out->putLFloat($attribute->getCurrent()); - $out->putLFloat($attribute->getMax()); - } - - $out->putEntityMetadata($this->metadata); - $out->putUnsignedVarInt(count($this->links)); - foreach($this->links as $link){ - $out->putEntityLink($link); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleAddActor($this); - } -} diff --git a/src/network/mcpe/protocol/AddBehaviorTreePacket.php b/src/network/mcpe/protocol/AddBehaviorTreePacket.php deleted file mode 100644 index 30052c748c..0000000000 --- a/src/network/mcpe/protocol/AddBehaviorTreePacket.php +++ /dev/null @@ -1,47 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class AddBehaviorTreePacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::ADD_BEHAVIOR_TREE_PACKET; - - /** @var string */ - public $behaviorTreeJson; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->behaviorTreeJson = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->behaviorTreeJson); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleAddBehaviorTree($this); - } -} diff --git a/src/network/mcpe/protocol/AddEntityPacket.php b/src/network/mcpe/protocol/AddEntityPacket.php deleted file mode 100644 index a8c33d1300..0000000000 --- a/src/network/mcpe/protocol/AddEntityPacket.php +++ /dev/null @@ -1,57 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class AddEntityPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::ADD_ENTITY_PACKET; - - /** @var int */ - private $entityNetId; - - public static function create(int $entityNetId) : self{ - $result = new self; - $result->entityNetId = $entityNetId; - return $result; - } - - public function getEntityNetId() : int{ - return $this->entityNetId; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityNetId = $in->getUnsignedVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt($this->entityNetId); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleAddEntity($this); - } -} diff --git a/src/network/mcpe/protocol/AddItemActorPacket.php b/src/network/mcpe/protocol/AddItemActorPacket.php deleted file mode 100644 index bf6f445dd1..0000000000 --- a/src/network/mcpe/protocol/AddItemActorPacket.php +++ /dev/null @@ -1,77 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; -use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper; - -class AddItemActorPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::ADD_ITEM_ACTOR_PACKET; - - /** @var int|null */ - public $entityUniqueId = null; //TODO - /** @var int */ - public $entityRuntimeId; - /** @var ItemStackWrapper */ - public $item; - /** @var Vector3 */ - public $position; - /** @var Vector3|null */ - public $motion; - /** - * @var MetadataProperty[] - * @phpstan-var array - */ - public $metadata = []; - /** @var bool */ - public $isFromFishing = false; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityUniqueId = $in->getEntityUniqueId(); - $this->entityRuntimeId = $in->getEntityRuntimeId(); - $this->item = ItemStackWrapper::read($in); - $this->position = $in->getVector3(); - $this->motion = $in->getVector3(); - $this->metadata = $in->getEntityMetadata(); - $this->isFromFishing = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); - $out->putEntityRuntimeId($this->entityRuntimeId); - $this->item->write($out); - $out->putVector3($this->position); - $out->putVector3Nullable($this->motion); - $out->putEntityMetadata($this->metadata); - $out->putBool($this->isFromFishing); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleAddItemActor($this); - } -} diff --git a/src/network/mcpe/protocol/AddPaintingPacket.php b/src/network/mcpe/protocol/AddPaintingPacket.php deleted file mode 100644 index 0f8a38ed73..0000000000 --- a/src/network/mcpe/protocol/AddPaintingPacket.php +++ /dev/null @@ -1,64 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class AddPaintingPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::ADD_PAINTING_PACKET; - - /** @var int|null */ - public $entityUniqueId = null; - /** @var int */ - public $entityRuntimeId; - /** @var Vector3 */ - public $position; - /** @var int */ - public $direction; - /** @var string */ - public $title; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityUniqueId = $in->getEntityUniqueId(); - $this->entityRuntimeId = $in->getEntityRuntimeId(); - $this->position = $in->getVector3(); - $this->direction = $in->getVarInt(); - $this->title = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); - $out->putEntityRuntimeId($this->entityRuntimeId); - $out->putVector3($this->position); - $out->putVarInt($this->direction); - $out->putString($this->title); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleAddPainting($this); - } -} diff --git a/src/network/mcpe/protocol/AddPlayerPacket.php b/src/network/mcpe/protocol/AddPlayerPacket.php deleted file mode 100644 index c3d45cd779..0000000000 --- a/src/network/mcpe/protocol/AddPlayerPacket.php +++ /dev/null @@ -1,156 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\DeviceOS; -use pocketmine\network\mcpe\protocol\types\entity\EntityLink; -use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; -use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper; -use Ramsey\Uuid\UuidInterface; -use function count; - -class AddPlayerPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::ADD_PLAYER_PACKET; - - /** @var UuidInterface */ - public $uuid; - /** @var string */ - public $username; - /** @var int|null */ - public $entityUniqueId = null; //TODO - /** @var int */ - public $entityRuntimeId; - /** @var string */ - public $platformChatId = ""; - /** @var Vector3 */ - public $position; - /** @var Vector3|null */ - public $motion; - /** @var float */ - public $pitch = 0.0; - /** @var float */ - public $yaw = 0.0; - /** @var float|null */ - public $headYaw = null; //TODO - /** @var ItemStackWrapper */ - public $item; - /** - * @var MetadataProperty[] - * @phpstan-var array - */ - public $metadata = []; - - //TODO: adventure settings stuff - /** @var int */ - public $uvarint1 = 0; - /** @var int */ - public $uvarint2 = 0; - /** @var int */ - public $uvarint3 = 0; - /** @var int */ - public $uvarint4 = 0; - /** @var int */ - public $uvarint5 = 0; - - /** @var int */ - public $long1 = 0; - - /** @var EntityLink[] */ - public $links = []; - - /** @var string */ - public $deviceId = ""; //TODO: fill player's device ID (???) - /** @var int */ - public $buildPlatform = DeviceOS::UNKNOWN; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->uuid = $in->getUUID(); - $this->username = $in->getString(); - $this->entityUniqueId = $in->getEntityUniqueId(); - $this->entityRuntimeId = $in->getEntityRuntimeId(); - $this->platformChatId = $in->getString(); - $this->position = $in->getVector3(); - $this->motion = $in->getVector3(); - $this->pitch = $in->getLFloat(); - $this->yaw = $in->getLFloat(); - $this->headYaw = $in->getLFloat(); - $this->item = ItemStackWrapper::read($in); - $this->metadata = $in->getEntityMetadata(); - - $this->uvarint1 = $in->getUnsignedVarInt(); - $this->uvarint2 = $in->getUnsignedVarInt(); - $this->uvarint3 = $in->getUnsignedVarInt(); - $this->uvarint4 = $in->getUnsignedVarInt(); - $this->uvarint5 = $in->getUnsignedVarInt(); - - $this->long1 = $in->getLLong(); - - $linkCount = $in->getUnsignedVarInt(); - for($i = 0; $i < $linkCount; ++$i){ - $this->links[$i] = $in->getEntityLink(); - } - - $this->deviceId = $in->getString(); - $this->buildPlatform = $in->getLInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUUID($this->uuid); - $out->putString($this->username); - $out->putEntityUniqueId($this->entityUniqueId ?? $this->entityRuntimeId); - $out->putEntityRuntimeId($this->entityRuntimeId); - $out->putString($this->platformChatId); - $out->putVector3($this->position); - $out->putVector3Nullable($this->motion); - $out->putLFloat($this->pitch); - $out->putLFloat($this->yaw); - $out->putLFloat($this->headYaw ?? $this->yaw); - $this->item->write($out); - $out->putEntityMetadata($this->metadata); - - $out->putUnsignedVarInt($this->uvarint1); - $out->putUnsignedVarInt($this->uvarint2); - $out->putUnsignedVarInt($this->uvarint3); - $out->putUnsignedVarInt($this->uvarint4); - $out->putUnsignedVarInt($this->uvarint5); - - $out->putLLong($this->long1); - - $out->putUnsignedVarInt(count($this->links)); - foreach($this->links as $link){ - $out->putEntityLink($link); - } - - $out->putString($this->deviceId); - $out->putLInt($this->buildPlatform); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleAddPlayer($this); - } -} diff --git a/src/network/mcpe/protocol/AddVolumeEntityPacket.php b/src/network/mcpe/protocol/AddVolumeEntityPacket.php deleted file mode 100644 index 612fe90422..0000000000 --- a/src/network/mcpe/protocol/AddVolumeEntityPacket.php +++ /dev/null @@ -1,65 +0,0 @@ - - -use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\TreeRoot; -use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class AddVolumeEntityPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::ADD_VOLUME_ENTITY_PACKET; - - /** @var int */ - private $entityNetId; - /** @var CompoundTag */ - private $data; - - public static function create(int $entityNetId, CompoundTag $data) : self{ - $result = new self; - $result->entityNetId = $entityNetId; - $result->data = $data; - return $result; - } - - public function getEntityNetId() : int{ return $this->entityNetId; } - - public function getData() : CompoundTag{ return $this->data; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityNetId = $in->getUnsignedVarInt(); - $this->data = $in->getNbtCompoundRoot(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt($this->entityNetId); - $out->put((new NetworkNbtSerializer())->write(new TreeRoot($this->data))); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleAddVolumeEntity($this); - } -} diff --git a/src/network/mcpe/protocol/AdventureSettingsPacket.php b/src/network/mcpe/protocol/AdventureSettingsPacket.php deleted file mode 100644 index 4d69ba9b96..0000000000 --- a/src/network/mcpe/protocol/AdventureSettingsPacket.php +++ /dev/null @@ -1,123 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\PlayerPermissions; - -class AdventureSettingsPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::ADVENTURE_SETTINGS_PACKET; - - public const PERMISSION_NORMAL = 0; - public const PERMISSION_OPERATOR = 1; - public const PERMISSION_HOST = 2; - public const PERMISSION_AUTOMATION = 3; - public const PERMISSION_ADMIN = 4; - - /** - * This constant is used to identify flags that should be set on the second field. In a sensible world, these - * flags would all be set on the same packet field, but as of MCPE 1.2, the new abilities flags have for some - * reason been assigned a separate field. - */ - public const BITFLAG_SECOND_SET = 1 << 16; - - public const WORLD_IMMUTABLE = 0x01; - public const NO_PVP = 0x02; - - public const AUTO_JUMP = 0x20; - public const ALLOW_FLIGHT = 0x40; - public const NO_CLIP = 0x80; - public const WORLD_BUILDER = 0x100; - public const FLYING = 0x200; - public const MUTED = 0x400; - - public const MINE = 0x01 | self::BITFLAG_SECOND_SET; - public const DOORS_AND_SWITCHES = 0x02 | self::BITFLAG_SECOND_SET; - public const OPEN_CONTAINERS = 0x04 | self::BITFLAG_SECOND_SET; - public const ATTACK_PLAYERS = 0x08 | self::BITFLAG_SECOND_SET; - public const ATTACK_MOBS = 0x10 | self::BITFLAG_SECOND_SET; - public const OPERATOR = 0x20 | self::BITFLAG_SECOND_SET; - public const TELEPORT = 0x80 | self::BITFLAG_SECOND_SET; - public const BUILD = 0x100 | self::BITFLAG_SECOND_SET; - public const DEFAULT = 0x200 | self::BITFLAG_SECOND_SET; - - /** @var int */ - public $flags = 0; - /** @var int */ - public $commandPermission = self::PERMISSION_NORMAL; - /** @var int */ - public $flags2 = -1; - /** @var int */ - public $playerPermission = PlayerPermissions::MEMBER; - /** @var int */ - public $customFlags = 0; //... - /** @var int */ - public $entityUniqueId; //This is a little-endian long, NOT a var-long. (WTF Mojang) - - protected function decodePayload(PacketSerializer $in) : void{ - $this->flags = $in->getUnsignedVarInt(); - $this->commandPermission = $in->getUnsignedVarInt(); - $this->flags2 = $in->getUnsignedVarInt(); - $this->playerPermission = $in->getUnsignedVarInt(); - $this->customFlags = $in->getUnsignedVarInt(); - $this->entityUniqueId = $in->getLLong(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt($this->flags); - $out->putUnsignedVarInt($this->commandPermission); - $out->putUnsignedVarInt($this->flags2); - $out->putUnsignedVarInt($this->playerPermission); - $out->putUnsignedVarInt($this->customFlags); - $out->putLLong($this->entityUniqueId); - } - - public function getFlag(int $flag) : bool{ - if(($flag & self::BITFLAG_SECOND_SET) !== 0){ - return ($this->flags2 & $flag) !== 0; - } - - return ($this->flags & $flag) !== 0; - } - - public function setFlag(int $flag, bool $value) : void{ - if(($flag & self::BITFLAG_SECOND_SET) !== 0){ - $flagSet =& $this->flags2; - }else{ - $flagSet =& $this->flags; - } - - if($value){ - $flagSet |= $flag; - }else{ - $flagSet &= ~$flag; - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleAdventureSettings($this); - } -} diff --git a/src/network/mcpe/protocol/AnimateEntityPacket.php b/src/network/mcpe/protocol/AnimateEntityPacket.php deleted file mode 100644 index c8202bb750..0000000000 --- a/src/network/mcpe/protocol/AnimateEntityPacket.php +++ /dev/null @@ -1,108 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use function count; - -class AnimateEntityPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::ANIMATE_ENTITY_PACKET; - - /** @var string */ - private $animation; - /** @var string */ - private $nextState; - /** @var string */ - private $stopExpression; - /** @var string */ - private $controller; - /** @var float */ - private $blendOutTime; - /** - * @var int[] - * @phpstan-var list - */ - private $actorRuntimeIds; - - /** - * @param int[] $actorRuntimeIds - * @phpstan-param list $actorRuntimeIds - */ - public static function create(string $animation, string $nextState, string $stopExpression, string $controller, float $blendOutTime, array $actorRuntimeIds) : self{ - $result = new self; - $result->animation = $animation; - $result->nextState = $nextState; - $result->stopExpression = $stopExpression; - $result->controller = $controller; - $result->blendOutTime = $blendOutTime; - $result->actorRuntimeIds = $actorRuntimeIds; - return $result; - } - - public function getAnimation() : string{ return $this->animation; } - - public function getNextState() : string{ return $this->nextState; } - - public function getStopExpression() : string{ return $this->stopExpression; } - - public function getController() : string{ return $this->controller; } - - public function getBlendOutTime() : float{ return $this->blendOutTime; } - - /** - * @return int[] - * @phpstan-return list - */ - public function getActorRuntimeIds() : array{ return $this->actorRuntimeIds; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->animation = $in->getString(); - $this->nextState = $in->getString(); - $this->stopExpression = $in->getString(); - $this->controller = $in->getString(); - $this->blendOutTime = $in->getLFloat(); - $this->actorRuntimeIds = []; - for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ - $this->actorRuntimeIds[] = $in->getEntityRuntimeId(); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->animation); - $out->putString($this->nextState); - $out->putString($this->stopExpression); - $out->putString($this->controller); - $out->putLFloat($this->blendOutTime); - $out->putUnsignedVarInt(count($this->actorRuntimeIds)); - foreach($this->actorRuntimeIds as $id){ - $out->putEntityRuntimeId($id); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleAnimateEntity($this); - } -} diff --git a/src/network/mcpe/protocol/AnimatePacket.php b/src/network/mcpe/protocol/AnimatePacket.php deleted file mode 100644 index 95aea04795..0000000000 --- a/src/network/mcpe/protocol/AnimatePacket.php +++ /dev/null @@ -1,80 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class AnimatePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::ANIMATE_PACKET; - - public const ACTION_SWING_ARM = 1; - - public const ACTION_STOP_SLEEP = 3; - public const ACTION_CRITICAL_HIT = 4; - public const ACTION_MAGICAL_CRITICAL_HIT = 5; - public const ACTION_ROW_RIGHT = 128; - public const ACTION_ROW_LEFT = 129; - - /** @var int */ - public $action; - /** @var int */ - public $entityRuntimeId; - /** @var float */ - public $float = 0.0; //TODO (Boat rowing time?) - - public static function create(int $entityRuntimeId, int $actionId) : self{ - $result = new self; - $result->entityRuntimeId = $entityRuntimeId; - $result->action = $actionId; - return $result; - } - - public static function boatHack(int $entityRuntimeId, int $actionId, float $data) : self{ - $result = self::create($entityRuntimeId, $actionId); - $result->float = $data; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->action = $in->getVarInt(); - $this->entityRuntimeId = $in->getEntityRuntimeId(); - if(($this->action & 0x80) !== 0){ - $this->float = $in->getLFloat(); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVarInt($this->action); - $out->putEntityRuntimeId($this->entityRuntimeId); - if(($this->action & 0x80) !== 0){ - $out->putLFloat($this->float); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleAnimate($this); - } -} diff --git a/src/network/mcpe/protocol/AnvilDamagePacket.php b/src/network/mcpe/protocol/AnvilDamagePacket.php deleted file mode 100644 index 7f6616ddec..0000000000 --- a/src/network/mcpe/protocol/AnvilDamagePacket.php +++ /dev/null @@ -1,78 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class AnvilDamagePacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::ANVIL_DAMAGE_PACKET; - - /** @var int */ - private $x; - /** @var int */ - private $y; - /** @var int */ - private $z; - /** @var int */ - private $damageAmount; - - public static function create(int $x, int $y, int $z, int $damageAmount) : self{ - $result = new self; - [$result->x, $result->y, $result->z] = [$x, $y, $z]; - $result->damageAmount = $damageAmount; - return $result; - } - - public function getDamageAmount() : int{ - return $this->damageAmount; - } - - public function getX() : int{ - return $this->x; - } - - public function getY() : int{ - return $this->y; - } - - public function getZ() : int{ - return $this->z; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->damageAmount = $in->getByte(); - $in->getBlockPosition($this->x, $this->y, $this->z); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->damageAmount); - $out->putBlockPosition($this->x, $this->y, $this->z); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleAnvilDamage($this); - } -} diff --git a/src/network/mcpe/protocol/AutomationClientConnectPacket.php b/src/network/mcpe/protocol/AutomationClientConnectPacket.php deleted file mode 100644 index e9ae268c02..0000000000 --- a/src/network/mcpe/protocol/AutomationClientConnectPacket.php +++ /dev/null @@ -1,47 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class AutomationClientConnectPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::AUTOMATION_CLIENT_CONNECT_PACKET; - - /** @var string */ - public $serverUri; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->serverUri = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->serverUri); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleAutomationClientConnect($this); - } -} diff --git a/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php b/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php deleted file mode 100644 index 93f0bab998..0000000000 --- a/src/network/mcpe/protocol/AvailableActorIdentifiersPacket.php +++ /dev/null @@ -1,60 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\CacheableNbt; - -class AvailableActorIdentifiersPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::AVAILABLE_ACTOR_IDENTIFIERS_PACKET; - - /** - * @var CacheableNbt - * @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag> - */ - public $identifiers; - - /** - * @phpstan-param CacheableNbt<\pocketmine\nbt\tag\CompoundTag> $nbt - */ - public static function create(CacheableNbt $nbt) : self{ - $result = new self; - $result->identifiers = $nbt; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->identifiers = new CacheableNbt($in->getNbtCompoundRoot()); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->put($this->identifiers->getEncodedNbt()); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleAvailableActorIdentifiers($this); - } -} diff --git a/src/network/mcpe/protocol/AvailableCommandsPacket.php b/src/network/mcpe/protocol/AvailableCommandsPacket.php deleted file mode 100644 index 4ad40a69ff..0000000000 --- a/src/network/mcpe/protocol/AvailableCommandsPacket.php +++ /dev/null @@ -1,487 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\command\CommandData; -use pocketmine\network\mcpe\protocol\types\command\CommandEnum; -use pocketmine\network\mcpe\protocol\types\command\CommandEnumConstraint; -use pocketmine\network\mcpe\protocol\types\command\CommandParameter; -use pocketmine\utils\BinaryDataException; -use function array_search; -use function count; -use function dechex; - -class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::AVAILABLE_COMMANDS_PACKET; - - /** - * This flag is set on all types EXCEPT the POSTFIX type. Not completely sure what this is for, but it is required - * for the argtype to work correctly. VALID seems as good a name as any. - */ - public const ARG_FLAG_VALID = 0x100000; - - /** - * Basic parameter types. These must be combined with the ARG_FLAG_VALID constant. - * ARG_FLAG_VALID | (type const) - */ - public const ARG_TYPE_INT = 0x01; - public const ARG_TYPE_FLOAT = 0x03; - public const ARG_TYPE_VALUE = 0x04; - public const ARG_TYPE_WILDCARD_INT = 0x05; - public const ARG_TYPE_OPERATOR = 0x06; - public const ARG_TYPE_TARGET = 0x07; - public const ARG_TYPE_WILDCARD_TARGET = 0x08; - - public const ARG_TYPE_FILEPATH = 0x10; - - public const ARG_TYPE_STRING = 0x20; - - public const ARG_TYPE_POSITION = 0x28; - - public const ARG_TYPE_MESSAGE = 0x2c; - - public const ARG_TYPE_RAWTEXT = 0x2e; - - public const ARG_TYPE_JSON = 0x32; - - public const ARG_TYPE_COMMAND = 0x3f; - - /** - * Enums are a little different: they are composed as follows: - * ARG_FLAG_ENUM | ARG_FLAG_VALID | (enum index) - */ - public const ARG_FLAG_ENUM = 0x200000; - - /** This is used for /xp L. It can only be applied to integer parameters. */ - public const ARG_FLAG_POSTFIX = 0x1000000; - - public const HARDCODED_ENUM_NAMES = [ - "CommandName" => true - ]; - - /** - * @var CommandData[] - * List of command data, including name, description, alias indexes and parameters. - */ - public $commandData = []; - - /** - * @var CommandEnum[] - * List of enums which aren't directly referenced by any vanilla command. - * This is used for the `CommandName` enum, which is a magic enum used by the `command` argument type. - */ - public $hardcodedEnums = []; - - /** - * @var CommandEnum[] - * List of dynamic command enums, also referred to as "soft" enums. These can by dynamically updated mid-game - * without resending this packet. - */ - public $softEnums = []; - - /** - * @var CommandEnumConstraint[] - * List of constraints for enum members. Used to constrain gamerules that can bechanged in nocheats mode and more. - */ - public $enumConstraints = []; - - protected function decodePayload(PacketSerializer $in) : void{ - /** @var string[] $enumValues */ - $enumValues = []; - for($i = 0, $enumValuesCount = $in->getUnsignedVarInt(); $i < $enumValuesCount; ++$i){ - $enumValues[] = $in->getString(); - } - - /** @var string[] $postfixes */ - $postfixes = []; - for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ - $postfixes[] = $in->getString(); - } - - /** @var CommandEnum[] $enums */ - $enums = []; - for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ - $enums[] = $enum = $this->getEnum($enumValues, $in); - if(isset(self::HARDCODED_ENUM_NAMES[$enum->getName()])){ - $this->hardcodedEnums[] = $enum; - } - } - - for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ - $this->commandData[] = $this->getCommandData($enums, $postfixes, $in); - } - - for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ - $this->softEnums[] = $this->getSoftEnum($in); - } - - for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ - $this->enumConstraints[] = $this->getEnumConstraint($enums, $enumValues, $in); - } - } - - /** - * @param string[] $enumValueList - * - * @throws PacketDecodeException - * @throws BinaryDataException - */ - protected function getEnum(array $enumValueList, PacketSerializer $in) : CommandEnum{ - $enumName = $in->getString(); - $enumValues = []; - - $listSize = count($enumValueList); - - for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ - $index = $this->getEnumValueIndex($listSize, $in); - if(!isset($enumValueList[$index])){ - throw new PacketDecodeException("Invalid enum value index $index"); - } - //Get the enum value from the initial pile of mess - $enumValues[] = $enumValueList[$index]; - } - - return new CommandEnum($enumName, $enumValues); - } - - /** - * @throws BinaryDataException - */ - protected function getSoftEnum(PacketSerializer $in) : CommandEnum{ - $enumName = $in->getString(); - $enumValues = []; - - for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ - //Get the enum value from the initial pile of mess - $enumValues[] = $in->getString(); - } - - return new CommandEnum($enumName, $enumValues); - } - - /** - * @param int[] $enumValueMap - */ - protected function putEnum(CommandEnum $enum, array $enumValueMap, PacketSerializer $out) : void{ - $out->putString($enum->getName()); - - $values = $enum->getValues(); - $out->putUnsignedVarInt(count($values)); - $listSize = count($enumValueMap); - foreach($values as $value){ - $index = $enumValueMap[$value] ?? -1; - if($index === -1){ - throw new \InvalidStateException("Enum value '$value' not found"); - } - $this->putEnumValueIndex($index, $listSize, $out); - } - } - - protected function putSoftEnum(CommandEnum $enum, PacketSerializer $out) : void{ - $out->putString($enum->getName()); - - $values = $enum->getValues(); - $out->putUnsignedVarInt(count($values)); - foreach($values as $value){ - $out->putString($value); - } - } - - /** - * @throws BinaryDataException - */ - protected function getEnumValueIndex(int $valueCount, PacketSerializer $in) : int{ - if($valueCount < 256){ - return $in->getByte(); - }elseif($valueCount < 65536){ - return $in->getLShort(); - }else{ - return $in->getLInt(); - } - } - - protected function putEnumValueIndex(int $index, int $valueCount, PacketSerializer $out) : void{ - if($valueCount < 256){ - $out->putByte($index); - }elseif($valueCount < 65536){ - $out->putLShort($index); - }else{ - $out->putLInt($index); - } - } - - /** - * @param CommandEnum[] $enums - * @param string[] $enumValues - * - * @throws PacketDecodeException - * @throws BinaryDataException - */ - protected function getEnumConstraint(array $enums, array $enumValues, PacketSerializer $in) : CommandEnumConstraint{ - //wtf, what was wrong with an offset inside the enum? :( - $valueIndex = $in->getLInt(); - if(!isset($enumValues[$valueIndex])){ - throw new PacketDecodeException("Enum constraint refers to unknown enum value index $valueIndex"); - } - $enumIndex = $in->getLInt(); - if(!isset($enums[$enumIndex])){ - throw new PacketDecodeException("Enum constraint refers to unknown enum index $enumIndex"); - } - $enum = $enums[$enumIndex]; - $valueOffset = array_search($enumValues[$valueIndex], $enum->getValues(), true); - if($valueOffset === false){ - throw new PacketDecodeException("Value \"" . $enumValues[$valueIndex] . "\" does not belong to enum \"" . $enum->getName() . "\""); - } - - $constraintIds = []; - for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ - $constraintIds[] = $in->getByte(); - } - - return new CommandEnumConstraint($enum, $valueOffset, $constraintIds); - } - - /** - * @param int[] $enumIndexes string enum name -> int index - * @param int[] $enumValueIndexes string value -> int index - */ - protected function putEnumConstraint(CommandEnumConstraint $constraint, array $enumIndexes, array $enumValueIndexes, PacketSerializer $out) : void{ - $out->putLInt($enumValueIndexes[$constraint->getAffectedValue()]); - $out->putLInt($enumIndexes[$constraint->getEnum()->getName()]); - $out->putUnsignedVarInt(count($constraint->getConstraints())); - foreach($constraint->getConstraints() as $v){ - $out->putByte($v); - } - } - - /** - * @param CommandEnum[] $enums - * @param string[] $postfixes - * - * @throws PacketDecodeException - * @throws BinaryDataException - */ - protected function getCommandData(array $enums, array $postfixes, PacketSerializer $in) : CommandData{ - $name = $in->getString(); - $description = $in->getString(); - $flags = $in->getLShort(); - $permission = $in->getByte(); - $aliases = $enums[$in->getLInt()] ?? null; - $overloads = []; - - for($overloadIndex = 0, $overloadCount = $in->getUnsignedVarInt(); $overloadIndex < $overloadCount; ++$overloadIndex){ - $overloads[$overloadIndex] = []; - for($paramIndex = 0, $paramCount = $in->getUnsignedVarInt(); $paramIndex < $paramCount; ++$paramIndex){ - $parameter = new CommandParameter(); - $parameter->paramName = $in->getString(); - $parameter->paramType = $in->getLInt(); - $parameter->isOptional = $in->getBool(); - $parameter->flags = $in->getByte(); - - if(($parameter->paramType & self::ARG_FLAG_ENUM) !== 0){ - $index = ($parameter->paramType & 0xffff); - $parameter->enum = $enums[$index] ?? null; - if($parameter->enum === null){ - throw new PacketDecodeException("deserializing $name parameter $parameter->paramName: expected enum at $index, but got none"); - } - }elseif(($parameter->paramType & self::ARG_FLAG_POSTFIX) !== 0){ - $index = ($parameter->paramType & 0xffff); - $parameter->postfix = $postfixes[$index] ?? null; - if($parameter->postfix === null){ - throw new PacketDecodeException("deserializing $name parameter $parameter->paramName: expected postfix at $index, but got none"); - } - }elseif(($parameter->paramType & self::ARG_FLAG_VALID) === 0){ - throw new PacketDecodeException("deserializing $name parameter $parameter->paramName: Invalid parameter type 0x" . dechex($parameter->paramType)); - } - - $overloads[$overloadIndex][$paramIndex] = $parameter; - } - } - - return new CommandData($name, $description, $flags, $permission, $aliases, $overloads); - } - - /** - * @param int[] $enumIndexes string enum name -> int index - * @param int[] $postfixIndexes - */ - protected function putCommandData(CommandData $data, array $enumIndexes, array $postfixIndexes, PacketSerializer $out) : void{ - $out->putString($data->name); - $out->putString($data->description); - $out->putLShort($data->flags); - $out->putByte($data->permission); - - if($data->aliases !== null){ - $out->putLInt($enumIndexes[$data->aliases->getName()] ?? -1); - }else{ - $out->putLInt(-1); - } - - $out->putUnsignedVarInt(count($data->overloads)); - foreach($data->overloads as $overload){ - /** @var CommandParameter[] $overload */ - $out->putUnsignedVarInt(count($overload)); - foreach($overload as $parameter){ - $out->putString($parameter->paramName); - - if($parameter->enum !== null){ - $type = self::ARG_FLAG_ENUM | self::ARG_FLAG_VALID | ($enumIndexes[$parameter->enum->getName()] ?? -1); - }elseif($parameter->postfix !== null){ - $key = $postfixIndexes[$parameter->postfix] ?? -1; - if($key === -1){ - throw new \InvalidStateException("Postfix '$parameter->postfix' not in postfixes array"); - } - $type = self::ARG_FLAG_POSTFIX | $key; - }else{ - $type = $parameter->paramType; - } - - $out->putLInt($type); - $out->putBool($parameter->isOptional); - $out->putByte($parameter->flags); - } - } - } - - /** - * @param string[] $postfixes - * @phpstan-param array $postfixes - */ - private function argTypeToString(int $argtype, array $postfixes) : string{ - if(($argtype & self::ARG_FLAG_VALID) !== 0){ - if(($argtype & self::ARG_FLAG_ENUM) !== 0){ - return "stringenum (" . ($argtype & 0xffff) . ")"; - } - - switch($argtype & 0xffff){ - case self::ARG_TYPE_INT: - return "int"; - case self::ARG_TYPE_FLOAT: - return "float"; - case self::ARG_TYPE_VALUE: - return "mixed"; - case self::ARG_TYPE_TARGET: - return "target"; - case self::ARG_TYPE_STRING: - return "string"; - case self::ARG_TYPE_POSITION: - return "xyz"; - case self::ARG_TYPE_MESSAGE: - return "message"; - case self::ARG_TYPE_RAWTEXT: - return "text"; - case self::ARG_TYPE_JSON: - return "json"; - case self::ARG_TYPE_COMMAND: - return "command"; - } - }elseif(($argtype & self::ARG_FLAG_POSTFIX) !== 0){ - $postfix = $postfixes[$argtype & 0xffff]; - - return "int (postfix $postfix)"; - }else{ - throw new \UnexpectedValueException("Unknown arg type 0x" . dechex($argtype)); - } - - return "unknown ($argtype)"; - } - - protected function encodePayload(PacketSerializer $out) : void{ - /** @var int[] $enumValueIndexes */ - $enumValueIndexes = []; - /** @var int[] $postfixIndexes */ - $postfixIndexes = []; - /** @var int[] $enumIndexes */ - $enumIndexes = []; - /** @var CommandEnum[] $enums */ - $enums = []; - - $addEnumFn = static function(CommandEnum $enum) use (&$enums, &$enumIndexes, &$enumValueIndexes) : void{ - if(!isset($enumIndexes[$enum->getName()])){ - $enums[$enumIndexes[$enum->getName()] = count($enumIndexes)] = $enum; - } - foreach($enum->getValues() as $str){ - $enumValueIndexes[$str] = $enumValueIndexes[$str] ?? count($enumValueIndexes); //latest index - } - }; - foreach($this->hardcodedEnums as $enum){ - $addEnumFn($enum); - } - foreach($this->commandData as $commandData){ - if($commandData->aliases !== null){ - $addEnumFn($commandData->aliases); - } - /** @var CommandParameter[] $overload */ - foreach($commandData->overloads as $overload){ - /** @var CommandParameter $parameter */ - foreach($overload as $parameter){ - if($parameter->enum !== null){ - $addEnumFn($parameter->enum); - } - - if($parameter->postfix !== null){ - $postfixIndexes[$parameter->postfix] = $postfixIndexes[$parameter->postfix] ?? count($postfixIndexes); - } - } - } - } - - $out->putUnsignedVarInt(count($enumValueIndexes)); - foreach($enumValueIndexes as $enumValue => $index){ - $out->putString((string) $enumValue); //stupid PHP key casting D: - } - - $out->putUnsignedVarInt(count($postfixIndexes)); - foreach($postfixIndexes as $postfix => $index){ - $out->putString((string) $postfix); //stupid PHP key casting D: - } - - $out->putUnsignedVarInt(count($enums)); - foreach($enums as $enum){ - $this->putEnum($enum, $enumValueIndexes, $out); - } - - $out->putUnsignedVarInt(count($this->commandData)); - foreach($this->commandData as $data){ - $this->putCommandData($data, $enumIndexes, $postfixIndexes, $out); - } - - $out->putUnsignedVarInt(count($this->softEnums)); - foreach($this->softEnums as $enum){ - $this->putSoftEnum($enum, $out); - } - - $out->putUnsignedVarInt(count($this->enumConstraints)); - foreach($this->enumConstraints as $constraint){ - $this->putEnumConstraint($constraint, $enumIndexes, $enumValueIndexes, $out); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleAvailableCommands($this); - } -} diff --git a/src/network/mcpe/protocol/BiomeDefinitionListPacket.php b/src/network/mcpe/protocol/BiomeDefinitionListPacket.php deleted file mode 100644 index 6ef0456329..0000000000 --- a/src/network/mcpe/protocol/BiomeDefinitionListPacket.php +++ /dev/null @@ -1,60 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\CacheableNbt; - -class BiomeDefinitionListPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::BIOME_DEFINITION_LIST_PACKET; - - /** - * @var CacheableNbt - * @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag> - */ - public $defs; - - /** - * @phpstan-param CacheableNbt<\pocketmine\nbt\tag\CompoundTag> $nbt - */ - public static function create(CacheableNbt $nbt) : self{ - $result = new self; - $result->defs = $nbt; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->defs = new CacheableNbt($in->getNbtCompoundRoot()); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->put($this->defs->getEncodedNbt()); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleBiomeDefinitionList($this); - } -} diff --git a/src/network/mcpe/protocol/BlockActorDataPacket.php b/src/network/mcpe/protocol/BlockActorDataPacket.php deleted file mode 100644 index 7f111aa5d7..0000000000 --- a/src/network/mcpe/protocol/BlockActorDataPacket.php +++ /dev/null @@ -1,69 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\CacheableNbt; - -class BlockActorDataPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::BLOCK_ACTOR_DATA_PACKET; - - /** @var int */ - public $x; - /** @var int */ - public $y; - /** @var int */ - public $z; - /** - * @var CacheableNbt - * @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag> - */ - public $namedtag; - - /** - * @phpstan-param CacheableNbt<\pocketmine\nbt\tag\CompoundTag> $nbt - */ - public static function create(int $x, int $y, int $z, CacheableNbt $nbt) : self{ - $result = new self; - [$result->x, $result->y, $result->z] = [$x, $y, $z]; - $result->namedtag = $nbt; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $in->getBlockPosition($this->x, $this->y, $this->z); - $this->namedtag = new CacheableNbt($in->getNbtCompoundRoot()); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putBlockPosition($this->x, $this->y, $this->z); - $out->put($this->namedtag->getEncodedNbt()); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleBlockActorData($this); - } -} diff --git a/src/network/mcpe/protocol/BlockEventPacket.php b/src/network/mcpe/protocol/BlockEventPacket.php deleted file mode 100644 index bc706c29ed..0000000000 --- a/src/network/mcpe/protocol/BlockEventPacket.php +++ /dev/null @@ -1,70 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class BlockEventPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::BLOCK_EVENT_PACKET; - - /** @var int */ - public $x; - /** @var int */ - public $y; - /** @var int */ - public $z; - /** @var int */ - public $eventType; - /** @var int */ - public $eventData; - - public static function create(int $eventId, int $eventData, Vector3 $pos) : self{ - $pk = new self; - $pk->eventType = $eventId; - $pk->eventData = $eventData; - $pk->x = $pos->getFloorX(); - $pk->y = $pos->getFloorY(); - $pk->z = $pos->getFloorZ(); - return $pk; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $in->getBlockPosition($this->x, $this->y, $this->z); - $this->eventType = $in->getVarInt(); - $this->eventData = $in->getVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putBlockPosition($this->x, $this->y, $this->z); - $out->putVarInt($this->eventType); - $out->putVarInt($this->eventData); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleBlockEvent($this); - } -} diff --git a/src/network/mcpe/protocol/BlockPickRequestPacket.php b/src/network/mcpe/protocol/BlockPickRequestPacket.php deleted file mode 100644 index 51a62955ee..0000000000 --- a/src/network/mcpe/protocol/BlockPickRequestPacket.php +++ /dev/null @@ -1,59 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class BlockPickRequestPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::BLOCK_PICK_REQUEST_PACKET; - - /** @var int */ - public $blockX; - /** @var int */ - public $blockY; - /** @var int */ - public $blockZ; - /** @var bool */ - public $addUserData = false; - /** @var int */ - public $hotbarSlot; - - protected function decodePayload(PacketSerializer $in) : void{ - $in->getSignedBlockPosition($this->blockX, $this->blockY, $this->blockZ); - $this->addUserData = $in->getBool(); - $this->hotbarSlot = $in->getByte(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putSignedBlockPosition($this->blockX, $this->blockY, $this->blockZ); - $out->putBool($this->addUserData); - $out->putByte($this->hotbarSlot); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleBlockPickRequest($this); - } -} diff --git a/src/network/mcpe/protocol/BookEditPacket.php b/src/network/mcpe/protocol/BookEditPacket.php deleted file mode 100644 index f080ad62a7..0000000000 --- a/src/network/mcpe/protocol/BookEditPacket.php +++ /dev/null @@ -1,119 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class BookEditPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::BOOK_EDIT_PACKET; - - public const TYPE_REPLACE_PAGE = 0; - public const TYPE_ADD_PAGE = 1; - public const TYPE_DELETE_PAGE = 2; - public const TYPE_SWAP_PAGES = 3; - public const TYPE_SIGN_BOOK = 4; - - /** @var int */ - public $type; - /** @var int */ - public $inventorySlot; - /** @var int */ - public $pageNumber; - /** @var int */ - public $secondaryPageNumber; - - /** @var string */ - public $text; - /** @var string */ - public $photoName; - - /** @var string */ - public $title; - /** @var string */ - public $author; - /** @var string */ - public $xuid; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->type = $in->getByte(); - $this->inventorySlot = $in->getByte(); - - switch($this->type){ - case self::TYPE_REPLACE_PAGE: - case self::TYPE_ADD_PAGE: - $this->pageNumber = $in->getByte(); - $this->text = $in->getString(); - $this->photoName = $in->getString(); - break; - case self::TYPE_DELETE_PAGE: - $this->pageNumber = $in->getByte(); - break; - case self::TYPE_SWAP_PAGES: - $this->pageNumber = $in->getByte(); - $this->secondaryPageNumber = $in->getByte(); - break; - case self::TYPE_SIGN_BOOK: - $this->title = $in->getString(); - $this->author = $in->getString(); - $this->xuid = $in->getString(); - break; - default: - throw new PacketDecodeException("Unknown book edit type $this->type!"); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->type); - $out->putByte($this->inventorySlot); - - switch($this->type){ - case self::TYPE_REPLACE_PAGE: - case self::TYPE_ADD_PAGE: - $out->putByte($this->pageNumber); - $out->putString($this->text); - $out->putString($this->photoName); - break; - case self::TYPE_DELETE_PAGE: - $out->putByte($this->pageNumber); - break; - case self::TYPE_SWAP_PAGES: - $out->putByte($this->pageNumber); - $out->putByte($this->secondaryPageNumber); - break; - case self::TYPE_SIGN_BOOK: - $out->putString($this->title); - $out->putString($this->author); - $out->putString($this->xuid); - break; - default: - throw new \InvalidArgumentException("Unknown book edit type $this->type!"); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleBookEdit($this); - } -} diff --git a/src/network/mcpe/protocol/BossEventPacket.php b/src/network/mcpe/protocol/BossEventPacket.php deleted file mode 100644 index 46b7f078bd..0000000000 --- a/src/network/mcpe/protocol/BossEventPacket.php +++ /dev/null @@ -1,184 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class BossEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::BOSS_EVENT_PACKET; - - /* S2C: Shows the boss-bar to the player. */ - public const TYPE_SHOW = 0; - /* C2S: Registers a player to a boss fight. */ - public const TYPE_REGISTER_PLAYER = 1; - /* S2C: Removes the boss-bar from the client. */ - public const TYPE_HIDE = 2; - /* C2S: Unregisters a player from a boss fight. */ - public const TYPE_UNREGISTER_PLAYER = 3; - /* S2C: Sets the bar percentage. */ - public const TYPE_HEALTH_PERCENT = 4; - /* S2C: Sets title of the bar. */ - public const TYPE_TITLE = 5; - /* S2C: Not sure on this. Includes color and overlay fields, plus an unknown short. TODO: check this */ - public const TYPE_UNKNOWN_6 = 6; - /* S2C: Not implemented :( Intended to alter bar appearance, but these currently produce no effect on client-side whatsoever. */ - public const TYPE_TEXTURE = 7; - - /** @var int */ - public $bossEid; - /** @var int */ - public $eventType; - - /** @var int (long) */ - public $playerEid; - /** @var float */ - public $healthPercent; - /** @var string */ - public $title; - /** @var int */ - public $unknownShort; - /** @var int */ - public $color; - /** @var int */ - public $overlay; - - private static function base(int $bossEntityUniqueId, int $eventId) : self{ - $result = new self; - $result->bossEid = $bossEntityUniqueId; - $result->eventType = $eventId; - return $result; - } - - public static function show(int $bossEntityUniqueId, string $title, float $healthPercent, int $unknownShort = 0) : self{ - $result = self::base($bossEntityUniqueId, self::TYPE_SHOW); - $result->title = $title; - $result->healthPercent = $healthPercent; - $result->unknownShort = $unknownShort; - $result->color = 0; //hardcoded due to being useless - $result->overlay = 0; - return $result; - } - - public static function hide(int $bossEntityUniqueId) : self{ - return self::base($bossEntityUniqueId, self::TYPE_HIDE); - } - - public static function registerPlayer(int $bossEntityUniqueId, int $playerEntityUniqueId) : self{ - $result = self::base($bossEntityUniqueId, self::TYPE_REGISTER_PLAYER); - $result->playerEid = $playerEntityUniqueId; - return $result; - } - - public static function unregisterPlayer(int $bossEntityUniqueId, int $playerEntityUniqueId) : self{ - $result = self::base($bossEntityUniqueId, self::TYPE_UNREGISTER_PLAYER); - $result->playerEid = $playerEntityUniqueId; - return $result; - } - - public static function healthPercent(int $bossEntityUniqueId, float $healthPercent) : self{ - $result = self::base($bossEntityUniqueId, self::TYPE_HEALTH_PERCENT); - $result->healthPercent = $healthPercent; - return $result; - } - - public static function title(int $bossEntityUniqueId, string $title) : self{ - $result = self::base($bossEntityUniqueId, self::TYPE_TITLE); - $result->title = $title; - return $result; - } - - public static function unknown6(int $bossEntityUniqueId, int $unknownShort) : self{ - $result = self::base($bossEntityUniqueId, self::TYPE_UNKNOWN_6); - $result->unknownShort = $unknownShort; - $result->color = 0; //hardcoded due to being useless - $result->overlay = 0; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->bossEid = $in->getEntityUniqueId(); - $this->eventType = $in->getUnsignedVarInt(); - switch($this->eventType){ - case self::TYPE_REGISTER_PLAYER: - case self::TYPE_UNREGISTER_PLAYER: - $this->playerEid = $in->getEntityUniqueId(); - break; - /** @noinspection PhpMissingBreakStatementInspection */ - case self::TYPE_SHOW: - $this->title = $in->getString(); - $this->healthPercent = $in->getLFloat(); - /** @noinspection PhpMissingBreakStatementInspection */ - case self::TYPE_UNKNOWN_6: - $this->unknownShort = $in->getLShort(); - case self::TYPE_TEXTURE: - $this->color = $in->getUnsignedVarInt(); - $this->overlay = $in->getUnsignedVarInt(); - break; - case self::TYPE_HEALTH_PERCENT: - $this->healthPercent = $in->getLFloat(); - break; - case self::TYPE_TITLE: - $this->title = $in->getString(); - break; - default: - break; - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityUniqueId($this->bossEid); - $out->putUnsignedVarInt($this->eventType); - switch($this->eventType){ - case self::TYPE_REGISTER_PLAYER: - case self::TYPE_UNREGISTER_PLAYER: - $out->putEntityUniqueId($this->playerEid); - break; - /** @noinspection PhpMissingBreakStatementInspection */ - case self::TYPE_SHOW: - $out->putString($this->title); - $out->putLFloat($this->healthPercent); - /** @noinspection PhpMissingBreakStatementInspection */ - case self::TYPE_UNKNOWN_6: - $out->putLShort($this->unknownShort); - case self::TYPE_TEXTURE: - $out->putUnsignedVarInt($this->color); - $out->putUnsignedVarInt($this->overlay); - break; - case self::TYPE_HEALTH_PERCENT: - $out->putLFloat($this->healthPercent); - break; - case self::TYPE_TITLE: - $out->putString($this->title); - break; - default: - break; - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleBossEvent($this); - } -} diff --git a/src/network/mcpe/protocol/CameraPacket.php b/src/network/mcpe/protocol/CameraPacket.php deleted file mode 100644 index fac61d86cc..0000000000 --- a/src/network/mcpe/protocol/CameraPacket.php +++ /dev/null @@ -1,51 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class CameraPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::CAMERA_PACKET; - - /** @var int */ - public $cameraUniqueId; - /** @var int */ - public $playerUniqueId; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->cameraUniqueId = $in->getEntityUniqueId(); - $this->playerUniqueId = $in->getEntityUniqueId(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityUniqueId($this->cameraUniqueId); - $out->putEntityUniqueId($this->playerUniqueId); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleCamera($this); - } -} diff --git a/src/network/mcpe/protocol/CameraShakePacket.php b/src/network/mcpe/protocol/CameraShakePacket.php deleted file mode 100644 index 03c1fe67a3..0000000000 --- a/src/network/mcpe/protocol/CameraShakePacket.php +++ /dev/null @@ -1,82 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class CameraShakePacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::CAMERA_SHAKE_PACKET; - - public const TYPE_POSITIONAL = 0; - public const TYPE_ROTATIONAL = 1; - - public const ACTION_ADD = 0; - public const ACTION_STOP = 1; - - /** @var float */ - private $intensity; - /** @var float */ - private $duration; - /** @var int */ - private $shakeType; - /** @var int */ - private $shakeAction; - - public static function create(float $intensity, float $duration, int $shakeType, int $shakeAction) : self{ - $result = new self; - $result->intensity = $intensity; - $result->duration = $duration; - $result->shakeType = $shakeType; - $result->shakeAction = $shakeAction; - return $result; - } - - public function getIntensity() : float{ return $this->intensity; } - - public function getDuration() : float{ return $this->duration; } - - public function getShakeType() : int{ return $this->shakeType; } - - public function getShakeAction() : int{ return $this->shakeAction; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->intensity = $in->getLFloat(); - $this->duration = $in->getLFloat(); - $this->shakeType = $in->getByte(); - $this->shakeAction = $in->getByte(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putLFloat($this->intensity); - $out->putLFloat($this->duration); - $out->putByte($this->shakeType); - $out->putByte($this->shakeAction); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleCameraShake($this); - } -} diff --git a/src/network/mcpe/protocol/ChangeDimensionPacket.php b/src/network/mcpe/protocol/ChangeDimensionPacket.php deleted file mode 100644 index 7e654b56e2..0000000000 --- a/src/network/mcpe/protocol/ChangeDimensionPacket.php +++ /dev/null @@ -1,56 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ChangeDimensionPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::CHANGE_DIMENSION_PACKET; - - /** @var int */ - public $dimension; - /** @var Vector3 */ - public $position; - /** @var bool */ - public $respawn = false; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->dimension = $in->getVarInt(); - $this->position = $in->getVector3(); - $this->respawn = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVarInt($this->dimension); - $out->putVector3($this->position); - $out->putBool($this->respawn); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleChangeDimension($this); - } -} diff --git a/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php b/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php deleted file mode 100644 index 25a06caf7c..0000000000 --- a/src/network/mcpe/protocol/ChunkRadiusUpdatedPacket.php +++ /dev/null @@ -1,53 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ChunkRadiusUpdatedPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::CHUNK_RADIUS_UPDATED_PACKET; - - /** @var int */ - public $radius; - - public static function create(int $radius) : self{ - $result = new self; - $result->radius = $radius; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->radius = $in->getVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVarInt($this->radius); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleChunkRadiusUpdated($this); - } -} diff --git a/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php b/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php deleted file mode 100644 index 6470bfc7e7..0000000000 --- a/src/network/mcpe/protocol/ClientCacheBlobStatusPacket.php +++ /dev/null @@ -1,93 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use function count; - -class ClientCacheBlobStatusPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::CLIENT_CACHE_BLOB_STATUS_PACKET; - - /** @var int[] xxHash64 subchunk data hashes */ - private $hitHashes = []; - /** @var int[] xxHash64 subchunk data hashes */ - private $missHashes = []; - - /** - * @param int[] $hitHashes - * @param int[] $missHashes - */ - public static function create(array $hitHashes, array $missHashes) : self{ - //type checks - (static function(int ...$hashes) : void{})(...$hitHashes); - (static function(int ...$hashes) : void{})(...$missHashes); - - $result = new self; - $result->hitHashes = $hitHashes; - $result->missHashes = $missHashes; - return $result; - } - - /** - * @return int[] - */ - public function getHitHashes() : array{ - return $this->hitHashes; - } - - /** - * @return int[] - */ - public function getMissHashes() : array{ - return $this->missHashes; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $missCount = $in->getUnsignedVarInt(); - $hitCount = $in->getUnsignedVarInt(); - for($i = 0; $i < $missCount; ++$i){ - $this->missHashes[] = $in->getLLong(); - } - for($i = 0; $i < $hitCount; ++$i){ - $this->hitHashes[] = $in->getLLong(); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt(count($this->missHashes)); - $out->putUnsignedVarInt(count($this->hitHashes)); - foreach($this->missHashes as $hash){ - $out->putLLong($hash); - } - foreach($this->hitHashes as $hash){ - $out->putLLong($hash); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleClientCacheBlobStatus($this); - } -} diff --git a/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php b/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php deleted file mode 100644 index afa4441fa6..0000000000 --- a/src/network/mcpe/protocol/ClientCacheMissResponsePacket.php +++ /dev/null @@ -1,76 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\ChunkCacheBlob; -use function count; - -class ClientCacheMissResponsePacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::CLIENT_CACHE_MISS_RESPONSE_PACKET; - - /** @var ChunkCacheBlob[] */ - private $blobs = []; - - /** - * @param ChunkCacheBlob[] $blobs - */ - public static function create(array $blobs) : self{ - //type check - (static function(ChunkCacheBlob ...$blobs) : void{})(...$blobs); - - $result = new self; - $result->blobs = $blobs; - return $result; - } - - /** - * @return ChunkCacheBlob[] - */ - public function getBlobs() : array{ - return $this->blobs; - } - - protected function decodePayload(PacketSerializer $in) : void{ - for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ - $hash = $in->getLLong(); - $payload = $in->getString(); - $this->blobs[] = new ChunkCacheBlob($hash, $payload); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt(count($this->blobs)); - foreach($this->blobs as $blob){ - $out->putLLong($blob->getHash()); - $out->putString($blob->getPayload()); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleClientCacheMissResponse($this); - } -} diff --git a/src/network/mcpe/protocol/ClientCacheStatusPacket.php b/src/network/mcpe/protocol/ClientCacheStatusPacket.php deleted file mode 100644 index 15f493cdc1..0000000000 --- a/src/network/mcpe/protocol/ClientCacheStatusPacket.php +++ /dev/null @@ -1,57 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ClientCacheStatusPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::CLIENT_CACHE_STATUS_PACKET; - - /** @var bool */ - private $enabled; - - public static function create(bool $enabled) : self{ - $result = new self; - $result->enabled = $enabled; - return $result; - } - - public function isEnabled() : bool{ - return $this->enabled; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->enabled = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putBool($this->enabled); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleClientCacheStatus($this); - } -} diff --git a/src/network/mcpe/protocol/ClientToServerHandshakePacket.php b/src/network/mcpe/protocol/ClientToServerHandshakePacket.php deleted file mode 100644 index 7457d27eed..0000000000 --- a/src/network/mcpe/protocol/ClientToServerHandshakePacket.php +++ /dev/null @@ -1,48 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ClientToServerHandshakePacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::CLIENT_TO_SERVER_HANDSHAKE_PACKET; - - public function canBeSentBeforeLogin() : bool{ - return true; - } - - protected function decodePayload(PacketSerializer $in) : void{ - //No payload - } - - protected function encodePayload(PacketSerializer $out) : void{ - //No payload - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleClientToServerHandshake($this); - } -} diff --git a/src/network/mcpe/protocol/ClientboundDebugRendererPacket.php b/src/network/mcpe/protocol/ClientboundDebugRendererPacket.php deleted file mode 100644 index 35a182ce9d..0000000000 --- a/src/network/mcpe/protocol/ClientboundDebugRendererPacket.php +++ /dev/null @@ -1,137 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ClientboundDebugRendererPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::CLIENTBOUND_DEBUG_RENDERER_PACKET; - - public const TYPE_CLEAR = 1; - public const TYPE_ADD_CUBE = 2; - - /** @var int */ - private $type; - - //TODO: if more types are added, we'll probably want to make a separate data type and interfaces - /** @var string */ - private $text; - /** @var Vector3 */ - private $position; - /** @var float */ - private $red; - /** @var float */ - private $green; - /** @var float */ - private $blue; - /** @var float */ - private $alpha; - /** @var int */ - private $durationMillis; - - private static function base(int $type) : self{ - $result = new self; - $result->type = $type; - return $result; - } - - public static function clear() : self{ return self::base(self::TYPE_CLEAR); } - - public static function addCube(string $text, Vector3 $position, float $red, float $green, float $blue, float $alpha, int $durationMillis) : self{ - $result = self::base(self::TYPE_ADD_CUBE); - $result->text = $text; - $result->position = $position; - $result->red = $red; - $result->green = $green; - $result->blue = $blue; - $result->alpha = $alpha; - $result->durationMillis = $durationMillis; - return $result; - } - - public function getType() : int{ return $this->type; } - - public function getText() : string{ return $this->text; } - - public function getPosition() : Vector3{ return $this->position; } - - public function getRed() : float{ return $this->red; } - - public function getGreen() : float{ return $this->green; } - - public function getBlue() : float{ return $this->blue; } - - public function getAlpha() : float{ return $this->alpha; } - - public function getDurationMillis() : int{ return $this->durationMillis; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->type = $in->getLInt(); - - switch($this->type){ - case self::TYPE_CLEAR: - //NOOP - break; - case self::TYPE_ADD_CUBE: - $this->text = $in->getString(); - $this->position = $in->getVector3(); - $this->red = $in->getLFloat(); - $this->green = $in->getLFloat(); - $this->blue = $in->getLFloat(); - $this->alpha = $in->getLFloat(); - $this->durationMillis = $in->getLLong(); - break; - default: - throw new \UnexpectedValueException("Unknown type " . $this->type); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putLInt($this->type); - - switch($this->type){ - case self::TYPE_CLEAR: - //NOOP - break; - case self::TYPE_ADD_CUBE: - $out->putString($this->text); - $out->putVector3($this->position); - $out->putLFloat($this->red); - $out->putLFloat($this->green); - $out->putLFloat($this->blue); - $out->putLFloat($this->alpha); - $out->putLLong($this->durationMillis); - break; - default: - throw new \InvalidArgumentException("Unknown type " . $this->type); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleClientboundDebugRenderer($this); - } -} diff --git a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php b/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php deleted file mode 100644 index d92077cf1b..0000000000 --- a/src/network/mcpe/protocol/ClientboundMapItemDataPacket.php +++ /dev/null @@ -1,208 +0,0 @@ - - -use pocketmine\color\Color; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\DimensionIds; -use pocketmine\network\mcpe\protocol\types\MapDecoration; -use pocketmine\network\mcpe\protocol\types\MapTrackedObject; -use function count; -#ifndef COMPILE -use pocketmine\utils\Binary; -#endif - -class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::CLIENTBOUND_MAP_ITEM_DATA_PACKET; - - public const BITFLAG_TEXTURE_UPDATE = 0x02; - public const BITFLAG_DECORATION_UPDATE = 0x04; - - /** @var int */ - public $mapId; - /** @var int */ - public $type; - /** @var int */ - public $dimensionId = DimensionIds::OVERWORLD; - /** @var bool */ - public $isLocked = false; - - /** @var int[] */ - public $eids = []; - /** @var int */ - public $scale; - - /** @var MapTrackedObject[] */ - public $trackedEntities = []; - /** @var MapDecoration[] */ - public $decorations = []; - - /** @var int */ - public $width; - /** @var int */ - public $height; - /** @var int */ - public $xOffset = 0; - /** @var int */ - public $yOffset = 0; - /** @var Color[][] */ - public $colors = []; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->mapId = $in->getEntityUniqueId(); - $this->type = $in->getUnsignedVarInt(); - $this->dimensionId = $in->getByte(); - $this->isLocked = $in->getBool(); - - if(($this->type & 0x08) !== 0){ - $count = $in->getUnsignedVarInt(); - for($i = 0; $i < $count; ++$i){ - $this->eids[] = $in->getEntityUniqueId(); - } - } - - if(($this->type & (0x08 | self::BITFLAG_DECORATION_UPDATE | self::BITFLAG_TEXTURE_UPDATE)) !== 0){ //Decoration bitflag or colour bitflag - $this->scale = $in->getByte(); - } - - if(($this->type & self::BITFLAG_DECORATION_UPDATE) !== 0){ - for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ - $object = new MapTrackedObject(); - $object->type = $in->getLInt(); - if($object->type === MapTrackedObject::TYPE_BLOCK){ - $in->getBlockPosition($object->x, $object->y, $object->z); - }elseif($object->type === MapTrackedObject::TYPE_ENTITY){ - $object->entityUniqueId = $in->getEntityUniqueId(); - }else{ - throw new PacketDecodeException("Unknown map object type $object->type"); - } - $this->trackedEntities[] = $object; - } - - for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ - $icon = $in->getByte(); - $rotation = $in->getByte(); - $xOffset = $in->getByte(); - $yOffset = $in->getByte(); - $label = $in->getString(); - $color = Color::fromRGBA(Binary::flipIntEndianness($in->getUnsignedVarInt())); - $this->decorations[] = new MapDecoration($icon, $rotation, $xOffset, $yOffset, $label, $color); - } - } - - if(($this->type & self::BITFLAG_TEXTURE_UPDATE) !== 0){ - $this->width = $in->getVarInt(); - $this->height = $in->getVarInt(); - $this->xOffset = $in->getVarInt(); - $this->yOffset = $in->getVarInt(); - - $count = $in->getUnsignedVarInt(); - if($count !== $this->width * $this->height){ - throw new PacketDecodeException("Expected colour count of " . ($this->height * $this->width) . " (height $this->height * width $this->width), got $count"); - } - - for($y = 0; $y < $this->height; ++$y){ - for($x = 0; $x < $this->width; ++$x){ - $this->colors[$y][$x] = Color::fromRGBA(Binary::flipIntEndianness($in->getUnsignedVarInt())); - } - } - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityUniqueId($this->mapId); - - $type = 0; - if(($eidsCount = count($this->eids)) > 0){ - $type |= 0x08; - } - if(($decorationCount = count($this->decorations)) > 0){ - $type |= self::BITFLAG_DECORATION_UPDATE; - } - if(count($this->colors) > 0){ - $type |= self::BITFLAG_TEXTURE_UPDATE; - } - - $out->putUnsignedVarInt($type); - $out->putByte($this->dimensionId); - $out->putBool($this->isLocked); - - if(($type & 0x08) !== 0){ //TODO: find out what these are for - $out->putUnsignedVarInt($eidsCount); - foreach($this->eids as $eid){ - $out->putEntityUniqueId($eid); - } - } - - if(($type & (0x08 | self::BITFLAG_TEXTURE_UPDATE | self::BITFLAG_DECORATION_UPDATE)) !== 0){ - $out->putByte($this->scale); - } - - if(($type & self::BITFLAG_DECORATION_UPDATE) !== 0){ - $out->putUnsignedVarInt(count($this->trackedEntities)); - foreach($this->trackedEntities as $object){ - $out->putLInt($object->type); - if($object->type === MapTrackedObject::TYPE_BLOCK){ - $out->putBlockPosition($object->x, $object->y, $object->z); - }elseif($object->type === MapTrackedObject::TYPE_ENTITY){ - $out->putEntityUniqueId($object->entityUniqueId); - }else{ - throw new \InvalidArgumentException("Unknown map object type $object->type"); - } - } - - $out->putUnsignedVarInt($decorationCount); - foreach($this->decorations as $decoration){ - $out->putByte($decoration->getIcon()); - $out->putByte($decoration->getRotation()); - $out->putByte($decoration->getXOffset()); - $out->putByte($decoration->getYOffset()); - $out->putString($decoration->getLabel()); - $out->putUnsignedVarInt(Binary::flipIntEndianness($decoration->getColor()->toRGBA())); - } - } - - if(($type & self::BITFLAG_TEXTURE_UPDATE) !== 0){ - $out->putVarInt($this->width); - $out->putVarInt($this->height); - $out->putVarInt($this->xOffset); - $out->putVarInt($this->yOffset); - - $out->putUnsignedVarInt($this->width * $this->height); //list count, but we handle it as a 2D array... thanks for the confusion mojang - - for($y = 0; $y < $this->height; ++$y){ - for($x = 0; $x < $this->width; ++$x){ - //if mojang had any sense this would just be a regular LE int - $out->putUnsignedVarInt(Binary::flipIntEndianness($this->colors[$y][$x]->toRGBA())); - } - } - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleClientboundMapItemData($this); - } -} diff --git a/src/network/mcpe/protocol/ClientboundPacket.php b/src/network/mcpe/protocol/ClientboundPacket.php deleted file mode 100644 index edd22bf0e9..0000000000 --- a/src/network/mcpe/protocol/ClientboundPacket.php +++ /dev/null @@ -1,28 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class CodeBuilderPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::CODE_BUILDER_PACKET; - - /** @var string */ - private $url; - /** @var bool */ - private $openCodeBuilder; - - public static function create(string $url, bool $openCodeBuilder) : self{ - $result = new self; - $result->url = $url; - $result->openCodeBuilder = $openCodeBuilder; - return $result; - } - - public function getUrl() : string{ - return $this->url; - } - - public function openCodeBuilder() : bool{ - return $this->openCodeBuilder; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->url = $in->getString(); - $this->openCodeBuilder = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->url); - $out->putBool($this->openCodeBuilder); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleCodeBuilder($this); - } -} diff --git a/src/network/mcpe/protocol/CommandBlockUpdatePacket.php b/src/network/mcpe/protocol/CommandBlockUpdatePacket.php deleted file mode 100644 index 2fadff4ec2..0000000000 --- a/src/network/mcpe/protocol/CommandBlockUpdatePacket.php +++ /dev/null @@ -1,111 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class CommandBlockUpdatePacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::COMMAND_BLOCK_UPDATE_PACKET; - - /** @var bool */ - public $isBlock; - - /** @var int */ - public $x; - /** @var int */ - public $y; - /** @var int */ - public $z; - /** @var int */ - public $commandBlockMode; - /** @var bool */ - public $isRedstoneMode; - /** @var bool */ - public $isConditional; - - /** @var int */ - public $minecartEid; - - /** @var string */ - public $command; - /** @var string */ - public $lastOutput; - /** @var string */ - public $name; - /** @var bool */ - public $shouldTrackOutput; - /** @var int */ - public $tickDelay; - /** @var bool */ - public $executeOnFirstTick; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->isBlock = $in->getBool(); - - if($this->isBlock){ - $in->getBlockPosition($this->x, $this->y, $this->z); - $this->commandBlockMode = $in->getUnsignedVarInt(); - $this->isRedstoneMode = $in->getBool(); - $this->isConditional = $in->getBool(); - }else{ - //Minecart with command block - $this->minecartEid = $in->getEntityRuntimeId(); - } - - $this->command = $in->getString(); - $this->lastOutput = $in->getString(); - $this->name = $in->getString(); - - $this->shouldTrackOutput = $in->getBool(); - $this->tickDelay = $in->getLInt(); - $this->executeOnFirstTick = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putBool($this->isBlock); - - if($this->isBlock){ - $out->putBlockPosition($this->x, $this->y, $this->z); - $out->putUnsignedVarInt($this->commandBlockMode); - $out->putBool($this->isRedstoneMode); - $out->putBool($this->isConditional); - }else{ - $out->putEntityRuntimeId($this->minecartEid); - } - - $out->putString($this->command); - $out->putString($this->lastOutput); - $out->putString($this->name); - - $out->putBool($this->shouldTrackOutput); - $out->putLInt($this->tickDelay); - $out->putBool($this->executeOnFirstTick); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleCommandBlockUpdate($this); - } -} diff --git a/src/network/mcpe/protocol/CommandOutputPacket.php b/src/network/mcpe/protocol/CommandOutputPacket.php deleted file mode 100644 index 6dc70acc8c..0000000000 --- a/src/network/mcpe/protocol/CommandOutputPacket.php +++ /dev/null @@ -1,111 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; -use pocketmine\network\mcpe\protocol\types\command\CommandOutputMessage; -use pocketmine\utils\BinaryDataException; -use function count; - -class CommandOutputPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::COMMAND_OUTPUT_PACKET; - - public const TYPE_LAST = 1; - public const TYPE_SILENT = 2; - public const TYPE_ALL = 3; - public const TYPE_DATA_SET = 4; - - /** @var CommandOriginData */ - public $originData; - /** @var int */ - public $outputType; - /** @var int */ - public $successCount; - /** @var CommandOutputMessage[] */ - public $messages = []; - /** @var string */ - public $unknownString; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->originData = $in->getCommandOriginData(); - $this->outputType = $in->getByte(); - $this->successCount = $in->getUnsignedVarInt(); - - for($i = 0, $size = $in->getUnsignedVarInt(); $i < $size; ++$i){ - $this->messages[] = $this->getCommandMessage($in); - } - - if($this->outputType === self::TYPE_DATA_SET){ - $this->unknownString = $in->getString(); - } - } - - /** - * @throws BinaryDataException - */ - protected function getCommandMessage(PacketSerializer $in) : CommandOutputMessage{ - $message = new CommandOutputMessage(); - - $message->isInternal = $in->getBool(); - $message->messageId = $in->getString(); - - for($i = 0, $size = $in->getUnsignedVarInt(); $i < $size; ++$i){ - $message->parameters[] = $in->getString(); - } - - return $message; - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putCommandOriginData($this->originData); - $out->putByte($this->outputType); - $out->putUnsignedVarInt($this->successCount); - - $out->putUnsignedVarInt(count($this->messages)); - foreach($this->messages as $message){ - $this->putCommandMessage($message, $out); - } - - if($this->outputType === self::TYPE_DATA_SET){ - $out->putString($this->unknownString); - } - } - - protected function putCommandMessage(CommandOutputMessage $message, PacketSerializer $out) : void{ - $out->putBool($message->isInternal); - $out->putString($message->messageId); - - $out->putUnsignedVarInt(count($message->parameters)); - foreach($message->parameters as $parameter){ - $out->putString($parameter); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleCommandOutput($this); - } -} diff --git a/src/network/mcpe/protocol/CommandRequestPacket.php b/src/network/mcpe/protocol/CommandRequestPacket.php deleted file mode 100644 index ecc8f336d7..0000000000 --- a/src/network/mcpe/protocol/CommandRequestPacket.php +++ /dev/null @@ -1,56 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; - -class CommandRequestPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::COMMAND_REQUEST_PACKET; - - /** @var string */ - public $command; - /** @var CommandOriginData */ - public $originData; - /** @var bool */ - public $isInternal; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->command = $in->getString(); - $this->originData = $in->getCommandOriginData(); - $this->isInternal = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->command); - $out->putCommandOriginData($this->originData); - $out->putBool($this->isInternal); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleCommandRequest($this); - } -} diff --git a/src/network/mcpe/protocol/CompletedUsingItemPacket.php b/src/network/mcpe/protocol/CompletedUsingItemPacket.php deleted file mode 100644 index f8fe5357b6..0000000000 --- a/src/network/mcpe/protocol/CompletedUsingItemPacket.php +++ /dev/null @@ -1,68 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class CompletedUsingItemPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::COMPLETED_USING_ITEM_PACKET; - - public const ACTION_UNKNOWN = -1; - public const ACTION_EQUIP_ARMOR = 0; - public const ACTION_EAT = 1; - public const ACTION_ATTACK = 2; - public const ACTION_CONSUME = 3; - public const ACTION_THROW = 4; - public const ACTION_SHOOT = 5; - public const ACTION_PLACE = 6; - public const ACTION_FILL_BOTTLE = 7; - public const ACTION_FILL_BUCKET = 8; - public const ACTION_POUR_BUCKET = 9; - public const ACTION_USE_TOOL = 10; - public const ACTION_INTERACT = 11; - public const ACTION_RETRIEVED = 12; - public const ACTION_DYED = 13; - public const ACTION_TRADED = 14; - - /** @var int */ - public $itemId; - /** @var int */ - public $action; - - public function decodePayload(PacketSerializer $in) : void{ - $this->itemId = $in->getShort(); - $this->action = $in->getLInt(); - } - - public function encodePayload(PacketSerializer $out) : void{ - $out->putShort($this->itemId); - $out->putLInt($this->action); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleCompletedUsingItem($this); - } -} diff --git a/src/network/mcpe/protocol/ContainerClosePacket.php b/src/network/mcpe/protocol/ContainerClosePacket.php deleted file mode 100644 index c8f5f21116..0000000000 --- a/src/network/mcpe/protocol/ContainerClosePacket.php +++ /dev/null @@ -1,58 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ContainerClosePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::CONTAINER_CLOSE_PACKET; - - /** @var int */ - public $windowId; - /** @var bool */ - public $server = false; - - public static function create(int $windowId, bool $server) : self{ - $result = new self; - $result->windowId = $windowId; - $result->server = $server; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->windowId = $in->getByte(); - $this->server = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->windowId); - $out->putBool($this->server); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleContainerClose($this); - } -} diff --git a/src/network/mcpe/protocol/ContainerOpenPacket.php b/src/network/mcpe/protocol/ContainerOpenPacket.php deleted file mode 100644 index 54f5890557..0000000000 --- a/src/network/mcpe/protocol/ContainerOpenPacket.php +++ /dev/null @@ -1,85 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ContainerOpenPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::CONTAINER_OPEN_PACKET; - - /** @var int */ - public $windowId; - /** @var int */ - public $type; - /** @var int */ - public $x; - /** @var int */ - public $y; - /** @var int */ - public $z; - /** @var int */ - public $entityUniqueId = -1; - - public static function blockInv(int $windowId, int $windowType, int $x, int $y, int $z) : self{ - $result = new self; - $result->windowId = $windowId; - $result->type = $windowType; - [$result->x, $result->y, $result->z] = [$x, $y, $z]; - return $result; - } - - public static function blockInvVec3(int $windowId, int $windowType, Vector3 $vector3) : self{ - return self::blockInv($windowId, $windowType, $vector3->getFloorX(), $vector3->getFloorY(), $vector3->getFloorZ()); - } - - public static function entityInv(int $windowId, int $windowType, int $entityUniqueId) : self{ - $result = new self; - $result->windowId = $windowId; - $result->type = $windowType; - $result->entityUniqueId = $entityUniqueId; - $result->x = $result->y = $result->z = 0; //these have to be set even if they aren't used - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->windowId = $in->getByte(); - $this->type = $in->getByte(); - $in->getBlockPosition($this->x, $this->y, $this->z); - $this->entityUniqueId = $in->getEntityUniqueId(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->windowId); - $out->putByte($this->type); - $out->putBlockPosition($this->x, $this->y, $this->z); - $out->putEntityUniqueId($this->entityUniqueId); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleContainerOpen($this); - } -} diff --git a/src/network/mcpe/protocol/ContainerSetDataPacket.php b/src/network/mcpe/protocol/ContainerSetDataPacket.php deleted file mode 100644 index 9778ef25ef..0000000000 --- a/src/network/mcpe/protocol/ContainerSetDataPacket.php +++ /dev/null @@ -1,73 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ContainerSetDataPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::CONTAINER_SET_DATA_PACKET; - - public const PROPERTY_FURNACE_SMELT_PROGRESS = 0; - public const PROPERTY_FURNACE_REMAINING_FUEL_TIME = 1; - public const PROPERTY_FURNACE_MAX_FUEL_TIME = 2; - public const PROPERTY_FURNACE_STORED_XP = 3; - public const PROPERTY_FURNACE_FUEL_AUX = 4; - - public const PROPERTY_BREWING_STAND_BREW_TIME = 0; - public const PROPERTY_BREWING_STAND_FUEL_AMOUNT = 1; - public const PROPERTY_BREWING_STAND_FUEL_TOTAL = 2; - - /** @var int */ - public $windowId; - /** @var int */ - public $property; - /** @var int */ - public $value; - - public static function create(int $windowId, int $propertyId, int $value) : self{ - $result = new self; - $result->property = $propertyId; - $result->value = $value; - $result->windowId = $windowId; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->windowId = $in->getByte(); - $this->property = $in->getVarInt(); - $this->value = $in->getVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->windowId); - $out->putVarInt($this->property); - $out->putVarInt($this->value); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleContainerSetData($this); - } -} diff --git a/src/network/mcpe/protocol/CorrectPlayerMovePredictionPacket.php b/src/network/mcpe/protocol/CorrectPlayerMovePredictionPacket.php deleted file mode 100644 index 3e7d49bba7..0000000000 --- a/src/network/mcpe/protocol/CorrectPlayerMovePredictionPacket.php +++ /dev/null @@ -1,77 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class CorrectPlayerMovePredictionPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::CORRECT_PLAYER_MOVE_PREDICTION_PACKET; - - /** @var Vector3 */ - private $position; - /** @var Vector3 */ - private $delta; - /** @var bool */ - private $onGround; - /** @var int */ - private $tick; - - public static function create(Vector3 $position, Vector3 $delta, bool $onGround, int $tick) : self{ - $result = new self; - $result->position = $position; - $result->delta = $delta; - $result->onGround = $onGround; - $result->tick = $tick; - return $result; - } - - public function getPosition() : Vector3{ return $this->position; } - - public function getDelta() : Vector3{ return $this->delta; } - - public function isOnGround() : bool{ return $this->onGround; } - - public function getTick() : int{ return $this->tick; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->position = $in->getVector3(); - $this->delta = $in->getVector3(); - $this->onGround = $in->getBool(); - $this->tick = $in->getUnsignedVarLong(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVector3($this->position); - $out->putVector3($this->delta); - $out->putBool($this->onGround); - $out->putUnsignedVarLong($this->tick); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleCorrectPlayerMovePrediction($this); - } -} diff --git a/src/network/mcpe/protocol/CraftingDataPacket.php b/src/network/mcpe/protocol/CraftingDataPacket.php deleted file mode 100644 index 692c1b352d..0000000000 --- a/src/network/mcpe/protocol/CraftingDataPacket.php +++ /dev/null @@ -1,131 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\recipe\FurnaceRecipe; -use pocketmine\network\mcpe\protocol\types\recipe\MultiRecipe; -use pocketmine\network\mcpe\protocol\types\recipe\PotionContainerChangeRecipe; -use pocketmine\network\mcpe\protocol\types\recipe\PotionTypeRecipe; -use pocketmine\network\mcpe\protocol\types\recipe\RecipeWithTypeId; -use pocketmine\network\mcpe\protocol\types\recipe\ShapedRecipe; -use pocketmine\network\mcpe\protocol\types\recipe\ShapelessRecipe; -use function count; - -class CraftingDataPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::CRAFTING_DATA_PACKET; - - public const ENTRY_SHAPELESS = 0; - public const ENTRY_SHAPED = 1; - public const ENTRY_FURNACE = 2; - public const ENTRY_FURNACE_DATA = 3; - public const ENTRY_MULTI = 4; - public const ENTRY_SHULKER_BOX = 5; - public const ENTRY_SHAPELESS_CHEMISTRY = 6; - public const ENTRY_SHAPED_CHEMISTRY = 7; - - /** @var RecipeWithTypeId[] */ - public $entries = []; - /** @var PotionTypeRecipe[] */ - public $potionTypeRecipes = []; - /** @var PotionContainerChangeRecipe[] */ - public $potionContainerRecipes = []; - /** @var bool */ - public $cleanRecipes = false; - - protected function decodePayload(PacketSerializer $in) : void{ - $recipeCount = $in->getUnsignedVarInt(); - for($i = 0; $i < $recipeCount; ++$i){ - $recipeType = $in->getVarInt(); - - switch($recipeType){ - case self::ENTRY_SHAPELESS: - case self::ENTRY_SHULKER_BOX: - case self::ENTRY_SHAPELESS_CHEMISTRY: - $this->entries[] = ShapelessRecipe::decode($recipeType, $in); - break; - case self::ENTRY_SHAPED: - case self::ENTRY_SHAPED_CHEMISTRY: - $this->entries[] = ShapedRecipe::decode($recipeType, $in); - break; - case self::ENTRY_FURNACE: - case self::ENTRY_FURNACE_DATA: - $this->entries[] = FurnaceRecipe::decode($recipeType, $in); - break; - case self::ENTRY_MULTI: - $this->entries[] = MultiRecipe::decode($recipeType, $in); - break; - default: - throw new PacketDecodeException("Unhandled recipe type $recipeType!"); //do not continue attempting to decode - } - } - for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ - $inputId = $in->getVarInt(); - $inputMeta = $in->getVarInt(); - $ingredientId = $in->getVarInt(); - $ingredientMeta = $in->getVarInt(); - $outputId = $in->getVarInt(); - $outputMeta = $in->getVarInt(); - $this->potionTypeRecipes[] = new PotionTypeRecipe($inputId, $inputMeta, $ingredientId, $ingredientMeta, $outputId, $outputMeta); - } - for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ - $input = $in->getVarInt(); - $ingredient = $in->getVarInt(); - $output = $in->getVarInt(); - $this->potionContainerRecipes[] = new PotionContainerChangeRecipe($input, $ingredient, $output); - } - $this->cleanRecipes = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt(count($this->entries)); - foreach($this->entries as $d){ - $out->putVarInt($d->getTypeId()); - $d->encode($out); - } - $out->putUnsignedVarInt(count($this->potionTypeRecipes)); - foreach($this->potionTypeRecipes as $recipe){ - $out->putVarInt($recipe->getInputItemId()); - $out->putVarInt($recipe->getInputItemMeta()); - $out->putVarInt($recipe->getIngredientItemId()); - $out->putVarInt($recipe->getIngredientItemMeta()); - $out->putVarInt($recipe->getOutputItemId()); - $out->putVarInt($recipe->getOutputItemMeta()); - } - $out->putUnsignedVarInt(count($this->potionContainerRecipes)); - foreach($this->potionContainerRecipes as $recipe){ - $out->putVarInt($recipe->getInputItemId()); - $out->putVarInt($recipe->getIngredientItemId()); - $out->putVarInt($recipe->getOutputItemId()); - } - - $out->putBool($this->cleanRecipes); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleCraftingData($this); - } -} diff --git a/src/network/mcpe/protocol/CraftingEventPacket.php b/src/network/mcpe/protocol/CraftingEventPacket.php deleted file mode 100644 index e35186a55a..0000000000 --- a/src/network/mcpe/protocol/CraftingEventPacket.php +++ /dev/null @@ -1,82 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper; -use Ramsey\Uuid\UuidInterface; -use function count; - -class CraftingEventPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::CRAFTING_EVENT_PACKET; - - /** @var int */ - public $windowId; - /** @var int */ - public $type; - /** @var UuidInterface */ - public $id; - /** @var ItemStackWrapper[] */ - public $input = []; - /** @var ItemStackWrapper[] */ - public $output = []; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->windowId = $in->getByte(); - $this->type = $in->getVarInt(); - $this->id = $in->getUUID(); - - $size = $in->getUnsignedVarInt(); - for($i = 0; $i < $size and $i < 128; ++$i){ - $this->input[] = ItemStackWrapper::read($in); - } - - $size = $in->getUnsignedVarInt(); - for($i = 0; $i < $size and $i < 128; ++$i){ - $this->output[] = ItemStackWrapper::read($in); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->windowId); - $out->putVarInt($this->type); - $out->putUUID($this->id); - - $out->putUnsignedVarInt(count($this->input)); - foreach($this->input as $item){ - $item->write($out); - } - - $out->putUnsignedVarInt(count($this->output)); - foreach($this->output as $item){ - $item->write($out); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleCraftingEvent($this); - } -} diff --git a/src/network/mcpe/protocol/CreativeContentPacket.php b/src/network/mcpe/protocol/CreativeContentPacket.php deleted file mode 100644 index 2c7f0d522b..0000000000 --- a/src/network/mcpe/protocol/CreativeContentPacket.php +++ /dev/null @@ -1,67 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\inventory\CreativeContentEntry; -use function count; - -class CreativeContentPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::CREATIVE_CONTENT_PACKET; - - /** @var CreativeContentEntry[] */ - private $entries; - - /** - * @param CreativeContentEntry[] $entries - */ - public static function create(array $entries) : self{ - $result = new self; - $result->entries = $entries; - return $result; - } - - /** @return CreativeContentEntry[] */ - public function getEntries() : array{ return $this->entries; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entries = []; - for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ - $this->entries[] = CreativeContentEntry::read($in); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt(count($this->entries)); - foreach($this->entries as $entry){ - $entry->write($out); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleCreativeContent($this); - } -} diff --git a/src/network/mcpe/protocol/DataPacket.php b/src/network/mcpe/protocol/DataPacket.php deleted file mode 100644 index 128d96b2a9..0000000000 --- a/src/network/mcpe/protocol/DataPacket.php +++ /dev/null @@ -1,129 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\utils\BinaryDataException; -use function get_class; - -abstract class DataPacket implements Packet{ - - public const NETWORK_ID = 0; - - public const PID_MASK = 0x3ff; //10 bits - - private const SUBCLIENT_ID_MASK = 0x03; //2 bits - private const SENDER_SUBCLIENT_ID_SHIFT = 10; - private const RECIPIENT_SUBCLIENT_ID_SHIFT = 12; - - /** @var int */ - public $senderSubId = 0; - /** @var int */ - public $recipientSubId = 0; - - public function pid() : int{ - return $this::NETWORK_ID; - } - - public function getName() : string{ - return (new \ReflectionClass($this))->getShortName(); - } - - public function canBeSentBeforeLogin() : bool{ - return false; - } - - /** - * @throws PacketDecodeException - */ - final public function decode(PacketSerializer $in) : void{ - try{ - $this->decodeHeader($in); - $this->decodePayload($in); - }catch(BinaryDataException | PacketDecodeException $e){ - throw PacketDecodeException::wrap($e, $this->getName()); - } - } - - /** - * @throws BinaryDataException - * @throws \UnexpectedValueException - */ - protected function decodeHeader(PacketSerializer $in) : void{ - $header = $in->getUnsignedVarInt(); - $pid = $header & self::PID_MASK; - if($pid !== static::NETWORK_ID){ - //TODO: this means a logical error in the code, but how to prevent it from happening? - throw new \UnexpectedValueException("Expected " . static::NETWORK_ID . " for packet ID, got $pid"); - } - $this->senderSubId = ($header >> self::SENDER_SUBCLIENT_ID_SHIFT) & self::SUBCLIENT_ID_MASK; - $this->recipientSubId = ($header >> self::RECIPIENT_SUBCLIENT_ID_SHIFT) & self::SUBCLIENT_ID_MASK; - - } - - /** - * Decodes the packet body, without the packet ID or other generic header fields. - * - * @throws PacketDecodeException - * @throws BinaryDataException - */ - abstract protected function decodePayload(PacketSerializer $in) : void; - - final public function encode(PacketSerializer $out) : void{ - $this->encodeHeader($out); - $this->encodePayload($out); - } - - protected function encodeHeader(PacketSerializer $out) : void{ - $out->putUnsignedVarInt( - static::NETWORK_ID | - ($this->senderSubId << self::SENDER_SUBCLIENT_ID_SHIFT) | - ($this->recipientSubId << self::RECIPIENT_SUBCLIENT_ID_SHIFT) - ); - } - - /** - * Encodes the packet body, without the packet ID or other generic header fields. - */ - abstract protected function encodePayload(PacketSerializer $out) : void; - - /** - * @param string $name - * - * @return mixed - */ - public function __get($name){ - throw new \Error("Undefined property: " . get_class($this) . "::\$" . $name); - } - - /** - * @param string $name - * @param mixed $value - */ - public function __set($name, $value) : void{ - throw new \Error("Undefined property: " . get_class($this) . "::\$" . $name); - } -} diff --git a/src/network/mcpe/protocol/DebugInfoPacket.php b/src/network/mcpe/protocol/DebugInfoPacket.php deleted file mode 100644 index c6cadb4634..0000000000 --- a/src/network/mcpe/protocol/DebugInfoPacket.php +++ /dev/null @@ -1,65 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class DebugInfoPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::DEBUG_INFO_PACKET; - - /** @var int */ - private $entityUniqueId; - /** @var string */ - private $data; - - public static function create(int $entityUniqueId, string $data) : self{ - $result = new self; - $result->entityUniqueId = $entityUniqueId; - $result->data = $data; - return $result; - } - - /** - * TODO: we can't call this getEntityRuntimeId() because of base class collision (crap architecture, thanks Shoghi) - */ - public function getEntityUniqueIdField() : int{ return $this->entityUniqueId; } - - public function getData() : string{ return $this->data; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityUniqueId = $in->getEntityUniqueId(); - $this->data = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityUniqueId($this->entityUniqueId); - $out->putString($this->data); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleDebugInfo($this); - } -} diff --git a/src/network/mcpe/protocol/DisconnectPacket.php b/src/network/mcpe/protocol/DisconnectPacket.php deleted file mode 100644 index 31bd9e509b..0000000000 --- a/src/network/mcpe/protocol/DisconnectPacket.php +++ /dev/null @@ -1,72 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class DisconnectPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::DISCONNECT_PACKET; - - /** @var bool */ - public $hideDisconnectionScreen = false; - /** @var string */ - public $message = ""; - - public static function silent() : self{ - $result = new self; - $result->hideDisconnectionScreen = true; - return $result; - } - - public static function message(string $message) : self{ - $result = new self; - $result->hideDisconnectionScreen = false; - $result->message = $message; - return $result; - } - - public function canBeSentBeforeLogin() : bool{ - return true; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->hideDisconnectionScreen = $in->getBool(); - if(!$this->hideDisconnectionScreen){ - $this->message = $in->getString(); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putBool($this->hideDisconnectionScreen); - if(!$this->hideDisconnectionScreen){ - $out->putString($this->message); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleDisconnect($this); - } -} diff --git a/src/network/mcpe/protocol/EducationSettingsPacket.php b/src/network/mcpe/protocol/EducationSettingsPacket.php deleted file mode 100644 index f8f6b6bb97..0000000000 --- a/src/network/mcpe/protocol/EducationSettingsPacket.php +++ /dev/null @@ -1,100 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class EducationSettingsPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::EDUCATION_SETTINGS_PACKET; - - /** @var string */ - private $codeBuilderDefaultUri; - /** @var string */ - private $codeBuilderTitle; - /** @var bool */ - private $canResizeCodeBuilder; - /** @var string|null */ - private $codeBuilderOverrideUri; - /** @var bool */ - private $hasQuiz; - - public static function create(string $codeBuilderDefaultUri, string $codeBuilderTitle, bool $canResizeCodeBuilder, ?string $codeBuilderOverrideUri, bool $hasQuiz) : self{ - $result = new self; - $result->codeBuilderDefaultUri = $codeBuilderDefaultUri; - $result->codeBuilderTitle = $codeBuilderTitle; - $result->canResizeCodeBuilder = $canResizeCodeBuilder; - $result->codeBuilderOverrideUri = $codeBuilderOverrideUri; - $result->hasQuiz = $hasQuiz; - return $result; - } - - public function getCodeBuilderDefaultUri() : string{ - return $this->codeBuilderDefaultUri; - } - - public function getCodeBuilderTitle() : string{ - return $this->codeBuilderTitle; - } - - public function canResizeCodeBuilder() : bool{ - return $this->canResizeCodeBuilder; - } - - public function getCodeBuilderOverrideUri() : ?string{ - return $this->codeBuilderOverrideUri; - } - - public function getHasQuiz() : bool{ - return $this->hasQuiz; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->codeBuilderDefaultUri = $in->getString(); - $this->codeBuilderTitle = $in->getString(); - $this->canResizeCodeBuilder = $in->getBool(); - if($in->getBool()){ - $this->codeBuilderOverrideUri = $in->getString(); - }else{ - $this->codeBuilderOverrideUri = null; - } - $this->hasQuiz = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->codeBuilderDefaultUri); - $out->putString($this->codeBuilderTitle); - $out->putBool($this->canResizeCodeBuilder); - $out->putBool($this->codeBuilderOverrideUri !== null); - if($this->codeBuilderOverrideUri !== null){ - $out->putString($this->codeBuilderOverrideUri); - } - $out->putBool($this->hasQuiz); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleEducationSettings($this); - } -} diff --git a/src/network/mcpe/protocol/EmoteListPacket.php b/src/network/mcpe/protocol/EmoteListPacket.php deleted file mode 100644 index f6872eac27..0000000000 --- a/src/network/mcpe/protocol/EmoteListPacket.php +++ /dev/null @@ -1,74 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use Ramsey\Uuid\UuidInterface; -use function count; - -class EmoteListPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::EMOTE_LIST_PACKET; - - /** @var int */ - private $playerEntityRuntimeId; - /** @var UuidInterface[] */ - private $emoteIds; - - /** - * @param UuidInterface[] $emoteIds - */ - public static function create(int $playerEntityRuntimeId, array $emoteIds) : self{ - $result = new self; - $result->playerEntityRuntimeId = $playerEntityRuntimeId; - $result->emoteIds = $emoteIds; - return $result; - } - - public function getPlayerEntityRuntimeId() : int{ return $this->playerEntityRuntimeId; } - - /** @return UuidInterface[] */ - public function getEmoteIds() : array{ return $this->emoteIds; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->playerEntityRuntimeId = $in->getEntityRuntimeId(); - $this->emoteIds = []; - for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ - $this->emoteIds[] = $in->getUUID(); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityRuntimeId($this->playerEntityRuntimeId); - $out->putUnsignedVarInt(count($this->emoteIds)); - foreach($this->emoteIds as $emoteId){ - $out->putUUID($emoteId); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleEmoteList($this); - } -} diff --git a/src/network/mcpe/protocol/EmotePacket.php b/src/network/mcpe/protocol/EmotePacket.php deleted file mode 100644 index b32e6662d8..0000000000 --- a/src/network/mcpe/protocol/EmotePacket.php +++ /dev/null @@ -1,80 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class EmotePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::EMOTE_PACKET; - - public const FLAG_SERVER = 1 << 0; - - /** @var int */ - private $entityRuntimeId; - /** @var string */ - private $emoteId; - /** @var int */ - private $flags; - - public static function create(int $entityRuntimeId, string $emoteId, int $flags) : self{ - $result = new self; - $result->entityRuntimeId = $entityRuntimeId; - $result->emoteId = $emoteId; - $result->flags = $flags; - return $result; - } - - /** - * TODO: we can't call this getEntityRuntimeId() because of base class collision (crap architecture, thanks Shoghi) - */ - public function getEntityRuntimeIdField() : int{ - return $this->entityRuntimeId; - } - - public function getEmoteId() : string{ - return $this->emoteId; - } - - public function getFlags() : int{ - return $this->flags; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityRuntimeId = $in->getEntityRuntimeId(); - $this->emoteId = $in->getString(); - $this->flags = $in->getByte(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityRuntimeId($this->entityRuntimeId); - $out->putString($this->emoteId); - $out->putByte($this->flags); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleEmote($this); - } -} diff --git a/src/network/mcpe/protocol/EventPacket.php b/src/network/mcpe/protocol/EventPacket.php deleted file mode 100644 index 581b02fc74..0000000000 --- a/src/network/mcpe/protocol/EventPacket.php +++ /dev/null @@ -1,85 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class EventPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::EVENT_PACKET; - - public const TYPE_ACHIEVEMENT_AWARDED = 0; - public const TYPE_ENTITY_INTERACT = 1; - public const TYPE_PORTAL_BUILT = 2; - public const TYPE_PORTAL_USED = 3; - public const TYPE_MOB_KILLED = 4; - public const TYPE_CAULDRON_USED = 5; - public const TYPE_PLAYER_DEATH = 6; - public const TYPE_BOSS_KILLED = 7; - public const TYPE_AGENT_COMMAND = 8; - public const TYPE_AGENT_CREATED = 9; - public const TYPE_PATTERN_REMOVED = 10; //??? - public const TYPE_COMMANED_EXECUTED = 11; - public const TYPE_FISH_BUCKETED = 12; - public const TYPE_MOB_BORN = 13; - public const TYPE_PET_DIED = 14; - public const TYPE_CAULDRON_BLOCK_USED = 15; - public const TYPE_COMPOSTER_BLOCK_USED = 16; - public const TYPE_BELL_BLOCK_USED = 17; - public const TYPE_ACTOR_DEFINITION = 18; - public const TYPE_RAID_UPDATE = 19; - public const TYPE_PLAYER_MOVEMENT_ANOMALY = 20; //anti cheat - public const TYPE_PLAYER_MOVEMENT_CORRECTED = 21; - public const TYPE_HONEY_HARVESTED = 22; - public const TYPE_TARGET_BLOCK_HIT = 23; - public const TYPE_PIGLIN_BARTER = 24; - - /** @var int */ - public $playerRuntimeId; - /** @var int */ - public $eventData; - /** @var int */ - public $type; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->playerRuntimeId = $in->getEntityRuntimeId(); - $this->eventData = $in->getVarInt(); - $this->type = $in->getByte(); - - //TODO: nice confusing mess - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityRuntimeId($this->playerRuntimeId); - $out->putVarInt($this->eventData); - $out->putByte($this->type); - - //TODO: also nice confusing mess - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleEvent($this); - } -} diff --git a/src/network/mcpe/protocol/FilterTextPacket.php b/src/network/mcpe/protocol/FilterTextPacket.php deleted file mode 100644 index 3d19c47a7e..0000000000 --- a/src/network/mcpe/protocol/FilterTextPacket.php +++ /dev/null @@ -1,62 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class FilterTextPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::FILTER_TEXT_PACKET; - - /** @var string */ - private $text; - /** @var bool */ - private $fromServer; - - public static function create(string $text, bool $server) : self{ - $result = new self; - $result->text = $text; - $result->fromServer = $server; - return $result; - } - - public function getText() : string{ return $this->text; } - - public function isFromServer() : bool{ return $this->fromServer; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->text = $in->getString(); - $this->fromServer = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->text); - $out->putBool($this->fromServer); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleFilterText($this); - } -} diff --git a/src/network/mcpe/protocol/GameRulesChangedPacket.php b/src/network/mcpe/protocol/GameRulesChangedPacket.php deleted file mode 100644 index 35aa036ba8..0000000000 --- a/src/network/mcpe/protocol/GameRulesChangedPacket.php +++ /dev/null @@ -1,51 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\GameRule; - -class GameRulesChangedPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::GAME_RULES_CHANGED_PACKET; - - /** - * @var GameRule[] - * @phpstan-var array - */ - public $gameRules = []; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->gameRules = $in->getGameRules(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putGameRules($this->gameRules); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleGameRulesChanged($this); - } -} diff --git a/src/network/mcpe/protocol/GuiDataPickItemPacket.php b/src/network/mcpe/protocol/GuiDataPickItemPacket.php deleted file mode 100644 index 808cd882a5..0000000000 --- a/src/network/mcpe/protocol/GuiDataPickItemPacket.php +++ /dev/null @@ -1,55 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class GuiDataPickItemPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::GUI_DATA_PICK_ITEM_PACKET; - - /** @var string */ - public $itemDescription; - /** @var string */ - public $itemEffects; - /** @var int */ - public $hotbarSlot; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->itemDescription = $in->getString(); - $this->itemEffects = $in->getString(); - $this->hotbarSlot = $in->getLInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->itemDescription); - $out->putString($this->itemEffects); - $out->putLInt($this->hotbarSlot); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleGuiDataPickItem($this); - } -} diff --git a/src/network/mcpe/protocol/HurtArmorPacket.php b/src/network/mcpe/protocol/HurtArmorPacket.php deleted file mode 100644 index 661fbb105c..0000000000 --- a/src/network/mcpe/protocol/HurtArmorPacket.php +++ /dev/null @@ -1,51 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class HurtArmorPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::HURT_ARMOR_PACKET; - - /** @var int */ - public $cause; - /** @var int */ - public $health; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->cause = $in->getVarInt(); - $this->health = $in->getVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVarInt($this->cause); - $out->putVarInt($this->health); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleHurtArmor($this); - } -} diff --git a/src/network/mcpe/protocol/InteractPacket.php b/src/network/mcpe/protocol/InteractPacket.php deleted file mode 100644 index 829d39a81c..0000000000 --- a/src/network/mcpe/protocol/InteractPacket.php +++ /dev/null @@ -1,76 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class InteractPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::INTERACT_PACKET; - - public const ACTION_LEAVE_VEHICLE = 3; - public const ACTION_MOUSEOVER = 4; - public const ACTION_OPEN_NPC = 5; - public const ACTION_OPEN_INVENTORY = 6; - - /** @var int */ - public $action; - /** @var int */ - public $target; - - /** @var float */ - public $x; - /** @var float */ - public $y; - /** @var float */ - public $z; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->action = $in->getByte(); - $this->target = $in->getEntityRuntimeId(); - - if($this->action === self::ACTION_MOUSEOVER){ - //TODO: should this be a vector3? - $this->x = $in->getLFloat(); - $this->y = $in->getLFloat(); - $this->z = $in->getLFloat(); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->action); - $out->putEntityRuntimeId($this->target); - - if($this->action === self::ACTION_MOUSEOVER){ - $out->putLFloat($this->x); - $out->putLFloat($this->y); - $out->putLFloat($this->z); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleInteract($this); - } -} diff --git a/src/network/mcpe/protocol/InventoryContentPacket.php b/src/network/mcpe/protocol/InventoryContentPacket.php deleted file mode 100644 index 435f8ac15d..0000000000 --- a/src/network/mcpe/protocol/InventoryContentPacket.php +++ /dev/null @@ -1,71 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper; -use function count; - -class InventoryContentPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::INVENTORY_CONTENT_PACKET; - - /** @var int */ - public $windowId; - /** @var ItemStackWrapper[] */ - public $items = []; - - /** - * @param ItemStackWrapper[] $items - * - * @return InventoryContentPacket - */ - public static function create(int $windowId, array $items) : self{ - $result = new self; - $result->windowId = $windowId; - $result->items = $items; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->windowId = $in->getUnsignedVarInt(); - $count = $in->getUnsignedVarInt(); - for($i = 0; $i < $count; ++$i){ - $this->items[] = ItemStackWrapper::read($in); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt($this->windowId); - $out->putUnsignedVarInt(count($this->items)); - foreach($this->items as $item){ - $item->write($out); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleInventoryContent($this); - } -} diff --git a/src/network/mcpe/protocol/InventorySlotPacket.php b/src/network/mcpe/protocol/InventorySlotPacket.php deleted file mode 100644 index 59708dd792..0000000000 --- a/src/network/mcpe/protocol/InventorySlotPacket.php +++ /dev/null @@ -1,65 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper; - -class InventorySlotPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::INVENTORY_SLOT_PACKET; - - /** @var int */ - public $windowId; - /** @var int */ - public $inventorySlot; - /** @var ItemStackWrapper */ - public $item; - - public static function create(int $windowId, int $slot, ItemStackWrapper $item) : self{ - $result = new self; - $result->inventorySlot = $slot; - $result->item = $item; - $result->windowId = $windowId; - - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->windowId = $in->getUnsignedVarInt(); - $this->inventorySlot = $in->getUnsignedVarInt(); - $this->item = ItemStackWrapper::read($in); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt($this->windowId); - $out->putUnsignedVarInt($this->inventorySlot); - $this->item->write($out); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleInventorySlot($this); - } -} diff --git a/src/network/mcpe/protocol/InventoryTransactionPacket.php b/src/network/mcpe/protocol/InventoryTransactionPacket.php deleted file mode 100644 index a5af13c40c..0000000000 --- a/src/network/mcpe/protocol/InventoryTransactionPacket.php +++ /dev/null @@ -1,108 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\inventory\InventoryTransactionChangedSlotsHack; -use pocketmine\network\mcpe\protocol\types\inventory\MismatchTransactionData; -use pocketmine\network\mcpe\protocol\types\inventory\NormalTransactionData; -use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData; -use pocketmine\network\mcpe\protocol\types\inventory\TransactionData; -use pocketmine\network\mcpe\protocol\types\inventory\UseItemOnEntityTransactionData; -use pocketmine\network\mcpe\protocol\types\inventory\UseItemTransactionData; -use function count; - -/** - * This packet effectively crams multiple packets into one. - */ -class InventoryTransactionPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::INVENTORY_TRANSACTION_PACKET; - - public const TYPE_NORMAL = 0; - public const TYPE_MISMATCH = 1; - public const TYPE_USE_ITEM = 2; - public const TYPE_USE_ITEM_ON_ENTITY = 3; - public const TYPE_RELEASE_ITEM = 4; - - /** @var int */ - public $requestId; - /** @var InventoryTransactionChangedSlotsHack[] */ - public $requestChangedSlots; - /** @var TransactionData */ - public $trData; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->requestId = $in->readGenericTypeNetworkId(); - $this->requestChangedSlots = []; - if($this->requestId !== 0){ - for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ - $this->requestChangedSlots[] = InventoryTransactionChangedSlotsHack::read($in); - } - } - - $transactionType = $in->getUnsignedVarInt(); - - switch($transactionType){ - case self::TYPE_NORMAL: - $this->trData = new NormalTransactionData(); - break; - case self::TYPE_MISMATCH: - $this->trData = new MismatchTransactionData(); - break; - case self::TYPE_USE_ITEM: - $this->trData = new UseItemTransactionData(); - break; - case self::TYPE_USE_ITEM_ON_ENTITY: - $this->trData = new UseItemOnEntityTransactionData(); - break; - case self::TYPE_RELEASE_ITEM: - $this->trData = new ReleaseItemTransactionData(); - break; - default: - throw new PacketDecodeException("Unknown transaction type $transactionType"); - } - - $this->trData->decode($in); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->writeGenericTypeNetworkId($this->requestId); - if($this->requestId !== 0){ - $out->putUnsignedVarInt(count($this->requestChangedSlots)); - foreach($this->requestChangedSlots as $changedSlots){ - $changedSlots->write($out); - } - } - - $out->putUnsignedVarInt($this->trData->getTypeId()); - - $this->trData->encode($out); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleInventoryTransaction($this); - } -} diff --git a/src/network/mcpe/protocol/ItemComponentPacket.php b/src/network/mcpe/protocol/ItemComponentPacket.php deleted file mode 100644 index 5a716966cd..0000000000 --- a/src/network/mcpe/protocol/ItemComponentPacket.php +++ /dev/null @@ -1,79 +0,0 @@ - - -use pocketmine\nbt\TreeRoot; -use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\ItemComponentPacketEntry; -use function count; - -class ItemComponentPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::ITEM_COMPONENT_PACKET; - - /** - * @var ItemComponentPacketEntry[] - * @phpstan-var list - */ - private $entries; - - /** - * @param ItemComponentPacketEntry[] $entries - * @phpstan-param list $entries - */ - public static function create(array $entries) : self{ - $result = new self; - $result->entries = $entries; - return $result; - } - - /** - * @return ItemComponentPacketEntry[] - * @phpstan-return list - */ - public function getEntries() : array{ return $this->entries; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entries = []; - for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ - $name = $in->getString(); - $nbt = $in->getNbtCompoundRoot(); - $this->entries[] = new ItemComponentPacketEntry($name, $nbt); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt(count($this->entries)); - foreach($this->entries as $entry){ - $out->putString($entry->getName()); - $out->put((new NetworkNbtSerializer())->write(new TreeRoot($entry->getComponentNbt()))); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleItemComponent($this); - } -} diff --git a/src/network/mcpe/protocol/ItemFrameDropItemPacket.php b/src/network/mcpe/protocol/ItemFrameDropItemPacket.php deleted file mode 100644 index f09998e67d..0000000000 --- a/src/network/mcpe/protocol/ItemFrameDropItemPacket.php +++ /dev/null @@ -1,52 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ItemFrameDropItemPacket extends DataPacket implements ServerboundPacket{ - - public const NETWORK_ID = ProtocolInfo::ITEM_FRAME_DROP_ITEM_PACKET; - - /** @var int */ - public $x; - /** @var int */ - public $y; - /** @var int */ - public $z; - - protected function decodePayload(PacketSerializer $in) : void{ - $in->getBlockPosition($this->x, $this->y, $this->z); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putBlockPosition($this->x, $this->y, $this->z); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleItemFrameDropItem($this); - } -} diff --git a/src/network/mcpe/protocol/ItemStackRequestPacket.php b/src/network/mcpe/protocol/ItemStackRequestPacket.php deleted file mode 100644 index 8a9a6e541f..0000000000 --- a/src/network/mcpe/protocol/ItemStackRequestPacket.php +++ /dev/null @@ -1,67 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\inventory\stackrequest\ItemStackRequest; -use function count; - -class ItemStackRequestPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::ITEM_STACK_REQUEST_PACKET; - - /** @var ItemStackRequest[] */ - private $requests; - - /** - * @param ItemStackRequest[] $requests - */ - public static function create(array $requests) : self{ - $result = new self; - $result->requests = $requests; - return $result; - } - - /** @return ItemStackRequest[] */ - public function getRequests() : array{ return $this->requests; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->requests = []; - for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ - $this->requests[] = ItemStackRequest::read($in); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt(count($this->requests)); - foreach($this->requests as $request){ - $request->write($out); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleItemStackRequest($this); - } -} diff --git a/src/network/mcpe/protocol/ItemStackResponsePacket.php b/src/network/mcpe/protocol/ItemStackResponsePacket.php deleted file mode 100644 index 07a54517d1..0000000000 --- a/src/network/mcpe/protocol/ItemStackResponsePacket.php +++ /dev/null @@ -1,67 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\inventory\stackresponse\ItemStackResponse; -use function count; - -class ItemStackResponsePacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::ITEM_STACK_RESPONSE_PACKET; - - /** @var ItemStackResponse[] */ - private $responses; - - /** - * @param ItemStackResponse[] $responses - */ - public static function create(array $responses) : self{ - $result = new self; - $result->responses = $responses; - return $result; - } - - /** @return ItemStackResponse[] */ - public function getResponses() : array{ return $this->responses; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->responses = []; - for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ - $this->responses[] = ItemStackResponse::read($in); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt(count($this->responses)); - foreach($this->responses as $response){ - $response->write($out); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleItemStackResponse($this); - } -} diff --git a/src/network/mcpe/protocol/LabTablePacket.php b/src/network/mcpe/protocol/LabTablePacket.php deleted file mode 100644 index 375572c3c4..0000000000 --- a/src/network/mcpe/protocol/LabTablePacket.php +++ /dev/null @@ -1,65 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class LabTablePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::LAB_TABLE_PACKET; - - public const TYPE_START_COMBINE = 0; - public const TYPE_START_REACTION = 1; - public const TYPE_RESET = 2; - - /** @var int */ - public $type; - - /** @var int */ - public $x; - /** @var int */ - public $y; - /** @var int */ - public $z; - - /** @var int */ - public $reactionType; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->type = $in->getByte(); - $in->getSignedBlockPosition($this->x, $this->y, $this->z); - $this->reactionType = $in->getByte(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->type); - $out->putSignedBlockPosition($this->x, $this->y, $this->z); - $out->putByte($this->reactionType); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleLabTable($this); - } -} diff --git a/src/network/mcpe/protocol/LecternUpdatePacket.php b/src/network/mcpe/protocol/LecternUpdatePacket.php deleted file mode 100644 index 9ce58e55e7..0000000000 --- a/src/network/mcpe/protocol/LecternUpdatePacket.php +++ /dev/null @@ -1,63 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class LecternUpdatePacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::LECTERN_UPDATE_PACKET; - - /** @var int */ - public $page; - /** @var int */ - public $totalPages; - /** @var int */ - public $x; - /** @var int */ - public $y; - /** @var int */ - public $z; - /** @var bool */ - public $dropBook; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->page = $in->getByte(); - $this->totalPages = $in->getByte(); - $in->getBlockPosition($this->x, $this->y, $this->z); - $this->dropBook = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->page); - $out->putByte($this->totalPages); - $out->putBlockPosition($this->x, $this->y, $this->z); - $out->putBool($this->dropBook); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleLecternUpdate($this); - } -} diff --git a/src/network/mcpe/protocol/LevelChunkPacket.php b/src/network/mcpe/protocol/LevelChunkPacket.php deleted file mode 100644 index bbbe2dd987..0000000000 --- a/src/network/mcpe/protocol/LevelChunkPacket.php +++ /dev/null @@ -1,133 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use function count; - -class LevelChunkPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::LEVEL_CHUNK_PACKET; - - /** @var int */ - private $chunkX; - /** @var int */ - private $chunkZ; - /** @var int */ - private $subChunkCount; - /** @var bool */ - private $cacheEnabled; - /** @var int[] */ - private $usedBlobHashes = []; - /** @var string */ - private $extraPayload; - - public static function withoutCache(int $chunkX, int $chunkZ, int $subChunkCount, string $payload) : self{ - $result = new self; - $result->chunkX = $chunkX; - $result->chunkZ = $chunkZ; - $result->subChunkCount = $subChunkCount; - $result->extraPayload = $payload; - - $result->cacheEnabled = false; - - return $result; - } - - /** - * @param int[] $usedBlobHashes - */ - public static function withCache(int $chunkX, int $chunkZ, int $subChunkCount, array $usedBlobHashes, string $extraPayload) : self{ - (static function(int ...$hashes) : void{})(...$usedBlobHashes); - $result = new self; - $result->chunkX = $chunkX; - $result->chunkZ = $chunkZ; - $result->subChunkCount = $subChunkCount; - $result->extraPayload = $extraPayload; - - $result->cacheEnabled = true; - $result->usedBlobHashes = $usedBlobHashes; - - return $result; - } - - public function getChunkX() : int{ - return $this->chunkX; - } - - public function getChunkZ() : int{ - return $this->chunkZ; - } - - public function getSubChunkCount() : int{ - return $this->subChunkCount; - } - - public function isCacheEnabled() : bool{ - return $this->cacheEnabled; - } - - /** - * @return int[] - */ - public function getUsedBlobHashes() : array{ - return $this->usedBlobHashes; - } - - public function getExtraPayload() : string{ - return $this->extraPayload; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->chunkX = $in->getVarInt(); - $this->chunkZ = $in->getVarInt(); - $this->subChunkCount = $in->getUnsignedVarInt(); - $this->cacheEnabled = $in->getBool(); - if($this->cacheEnabled){ - for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ - $this->usedBlobHashes[] = $in->getLLong(); - } - } - $this->extraPayload = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVarInt($this->chunkX); - $out->putVarInt($this->chunkZ); - $out->putUnsignedVarInt($this->subChunkCount); - $out->putBool($this->cacheEnabled); - if($this->cacheEnabled){ - $out->putUnsignedVarInt(count($this->usedBlobHashes)); - foreach($this->usedBlobHashes as $hash){ - $out->putLLong($hash); - } - } - $out->putString($this->extraPayload); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleLevelChunk($this); - } -} diff --git a/src/network/mcpe/protocol/LevelEventGenericPacket.php b/src/network/mcpe/protocol/LevelEventGenericPacket.php deleted file mode 100644 index d538c66581..0000000000 --- a/src/network/mcpe/protocol/LevelEventGenericPacket.php +++ /dev/null @@ -1,74 +0,0 @@ - - -use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\CacheableNbt; - -class LevelEventGenericPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::LEVEL_EVENT_GENERIC_PACKET; - - /** @var int */ - private $eventId; - /** - * @var CacheableNbt - * @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag> - */ - private $eventData; - - public static function create(int $eventId, CompoundTag $data) : self{ - $result = new self; - $result->eventId = $eventId; - $result->eventData = new CacheableNbt($data); - return $result; - } - - public function getEventId() : int{ - return $this->eventId; - } - - /** - * @phpstan-return CacheableNbt<\pocketmine\nbt\tag\CompoundTag> - */ - public function getEventData() : CacheableNbt{ - return $this->eventData; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->eventId = $in->getVarInt(); - $this->eventData = new CacheableNbt($in->getNbtCompoundRoot()); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVarInt($this->eventId); - $out->put($this->eventData->getEncodedNbt()); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleLevelEventGeneric($this); - } -} diff --git a/src/network/mcpe/protocol/LevelEventPacket.php b/src/network/mcpe/protocol/LevelEventPacket.php deleted file mode 100644 index 6e560f91b7..0000000000 --- a/src/network/mcpe/protocol/LevelEventPacket.php +++ /dev/null @@ -1,151 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class LevelEventPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::LEVEL_EVENT_PACKET; - - public const EVENT_SOUND_CLICK = 1000; - public const EVENT_SOUND_CLICK_FAIL = 1001; - public const EVENT_SOUND_SHOOT = 1002; - public const EVENT_SOUND_DOOR = 1003; - public const EVENT_SOUND_FIZZ = 1004; - public const EVENT_SOUND_IGNITE = 1005; - - public const EVENT_SOUND_GHAST = 1007; - public const EVENT_SOUND_GHAST_SHOOT = 1008; - public const EVENT_SOUND_BLAZE_SHOOT = 1009; - public const EVENT_SOUND_DOOR_BUMP = 1010; - - public const EVENT_SOUND_DOOR_CRASH = 1012; - - public const EVENT_SOUND_ENDERMAN_TELEPORT = 1018; - - public const EVENT_SOUND_ANVIL_BREAK = 1020; - public const EVENT_SOUND_ANVIL_USE = 1021; - public const EVENT_SOUND_ANVIL_FALL = 1022; - - public const EVENT_SOUND_POP = 1030; - - public const EVENT_SOUND_PORTAL = 1032; - - public const EVENT_SOUND_ITEMFRAME_ADD_ITEM = 1040; - public const EVENT_SOUND_ITEMFRAME_REMOVE = 1041; - public const EVENT_SOUND_ITEMFRAME_PLACE = 1042; - public const EVENT_SOUND_ITEMFRAME_REMOVE_ITEM = 1043; - public const EVENT_SOUND_ITEMFRAME_ROTATE_ITEM = 1044; - - public const EVENT_SOUND_CAMERA = 1050; - public const EVENT_SOUND_ORB = 1051; - public const EVENT_SOUND_TOTEM = 1052; - - public const EVENT_SOUND_ARMOR_STAND_BREAK = 1060; - public const EVENT_SOUND_ARMOR_STAND_HIT = 1061; - public const EVENT_SOUND_ARMOR_STAND_FALL = 1062; - public const EVENT_SOUND_ARMOR_STAND_PLACE = 1063; - - //TODO: check 2000-2017 - public const EVENT_PARTICLE_SHOOT = 2000; - public const EVENT_PARTICLE_DESTROY = 2001; - public const EVENT_PARTICLE_SPLASH = 2002; - public const EVENT_PARTICLE_EYE_DESPAWN = 2003; - public const EVENT_PARTICLE_SPAWN = 2004; - - public const EVENT_GUARDIAN_CURSE = 2006; - - public const EVENT_PARTICLE_BLOCK_FORCE_FIELD = 2008; - public const EVENT_PARTICLE_PROJECTILE_HIT = 2009; - public const EVENT_PARTICLE_DRAGON_EGG_TELEPORT = 2010; - - public const EVENT_PARTICLE_ENDERMAN_TELEPORT = 2013; - public const EVENT_PARTICLE_PUNCH_BLOCK = 2014; - - public const EVENT_START_RAIN = 3001; - public const EVENT_START_THUNDER = 3002; - public const EVENT_STOP_RAIN = 3003; - public const EVENT_STOP_THUNDER = 3004; - public const EVENT_PAUSE_GAME = 3005; //data: 1 to pause, 0 to resume - public const EVENT_PAUSE_GAME_NO_SCREEN = 3006; //data: 1 to pause, 0 to resume - same effect as normal pause but without screen - public const EVENT_SET_GAME_SPEED = 3007; //x coordinate of pos = scale factor (default 1.0) - - public const EVENT_REDSTONE_TRIGGER = 3500; - public const EVENT_CAULDRON_EXPLODE = 3501; - public const EVENT_CAULDRON_DYE_ARMOR = 3502; - public const EVENT_CAULDRON_CLEAN_ARMOR = 3503; - public const EVENT_CAULDRON_FILL_POTION = 3504; - public const EVENT_CAULDRON_TAKE_POTION = 3505; - public const EVENT_CAULDRON_FILL_WATER = 3506; - public const EVENT_CAULDRON_TAKE_WATER = 3507; - public const EVENT_CAULDRON_ADD_DYE = 3508; - public const EVENT_CAULDRON_CLEAN_BANNER = 3509; - - public const EVENT_BLOCK_START_BREAK = 3600; - public const EVENT_BLOCK_STOP_BREAK = 3601; - - public const EVENT_SET_DATA = 4000; - - public const EVENT_PLAYERS_SLEEPING = 9800; - - public const EVENT_ADD_PARTICLE_MASK = 0x4000; - - /** @var int */ - public $evid; - /** @var Vector3|null */ - public $position; - /** @var int */ - public $data; - - public static function create(int $evid, int $data, ?Vector3 $pos) : self{ - $pk = new self; - $pk->evid = $evid; - $pk->data = $data; - $pk->position = $pos !== null ? $pos->asVector3() : null; - return $pk; - } - - public static function standardParticle(int $particleId, int $data, Vector3 $pos) : self{ - return self::create(self::EVENT_ADD_PARTICLE_MASK | $particleId, $data, $pos); - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->evid = $in->getVarInt(); - $this->position = $in->getVector3(); - $this->data = $in->getVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVarInt($this->evid); - $out->putVector3Nullable($this->position); - $out->putVarInt($this->data); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleLevelEvent($this); - } -} diff --git a/src/network/mcpe/protocol/LevelSoundEventPacket.php b/src/network/mcpe/protocol/LevelSoundEventPacket.php deleted file mode 100644 index 58476cae81..0000000000 --- a/src/network/mcpe/protocol/LevelSoundEventPacket.php +++ /dev/null @@ -1,408 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class LevelSoundEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::LEVEL_SOUND_EVENT_PACKET; - - public const SOUND_ITEM_USE_ON = 0; - public const SOUND_HIT = 1; - public const SOUND_STEP = 2; - public const SOUND_FLY = 3; - public const SOUND_JUMP = 4; - public const SOUND_BREAK = 5; - public const SOUND_PLACE = 6; - public const SOUND_HEAVY_STEP = 7; - public const SOUND_GALLOP = 8; - public const SOUND_FALL = 9; - public const SOUND_AMBIENT = 10; - public const SOUND_AMBIENT_BABY = 11; - public const SOUND_AMBIENT_IN_WATER = 12; - public const SOUND_BREATHE = 13; - public const SOUND_DEATH = 14; - public const SOUND_DEATH_IN_WATER = 15; - public const SOUND_DEATH_TO_ZOMBIE = 16; - public const SOUND_HURT = 17; - public const SOUND_HURT_IN_WATER = 18; - public const SOUND_MAD = 19; - public const SOUND_BOOST = 20; - public const SOUND_BOW = 21; - public const SOUND_SQUISH_BIG = 22; - public const SOUND_SQUISH_SMALL = 23; - public const SOUND_FALL_BIG = 24; - public const SOUND_FALL_SMALL = 25; - public const SOUND_SPLASH = 26; - public const SOUND_FIZZ = 27; - public const SOUND_FLAP = 28; - public const SOUND_SWIM = 29; - public const SOUND_DRINK = 30; - public const SOUND_EAT = 31; - public const SOUND_TAKEOFF = 32; - public const SOUND_SHAKE = 33; - public const SOUND_PLOP = 34; - public const SOUND_LAND = 35; - public const SOUND_SADDLE = 36; - public const SOUND_ARMOR = 37; - public const SOUND_MOB_ARMOR_STAND_PLACE = 38; - public const SOUND_ADD_CHEST = 39; - public const SOUND_THROW = 40; - public const SOUND_ATTACK = 41; - public const SOUND_ATTACK_NODAMAGE = 42; - public const SOUND_ATTACK_STRONG = 43; - public const SOUND_WARN = 44; - public const SOUND_SHEAR = 45; - public const SOUND_MILK = 46; - public const SOUND_THUNDER = 47; - public const SOUND_EXPLODE = 48; - public const SOUND_FIRE = 49; - public const SOUND_IGNITE = 50; - public const SOUND_FUSE = 51; - public const SOUND_STARE = 52; - public const SOUND_SPAWN = 53; - public const SOUND_SHOOT = 54; - public const SOUND_BREAK_BLOCK = 55; - public const SOUND_LAUNCH = 56; - public const SOUND_BLAST = 57; - public const SOUND_LARGE_BLAST = 58; - public const SOUND_TWINKLE = 59; - public const SOUND_REMEDY = 60; - public const SOUND_UNFECT = 61; - public const SOUND_LEVELUP = 62; - public const SOUND_BOW_HIT = 63; - public const SOUND_BULLET_HIT = 64; - public const SOUND_EXTINGUISH_FIRE = 65; - public const SOUND_ITEM_FIZZ = 66; - public const SOUND_CHEST_OPEN = 67; - public const SOUND_CHEST_CLOSED = 68; - public const SOUND_SHULKERBOX_OPEN = 69; - public const SOUND_SHULKERBOX_CLOSED = 70; - public const SOUND_ENDERCHEST_OPEN = 71; - public const SOUND_ENDERCHEST_CLOSED = 72; - public const SOUND_POWER_ON = 73; - public const SOUND_POWER_OFF = 74; - public const SOUND_ATTACH = 75; - public const SOUND_DETACH = 76; - public const SOUND_DENY = 77; - public const SOUND_TRIPOD = 78; - public const SOUND_POP = 79; - public const SOUND_DROP_SLOT = 80; - public const SOUND_NOTE = 81; - public const SOUND_THORNS = 82; - public const SOUND_PISTON_IN = 83; - public const SOUND_PISTON_OUT = 84; - public const SOUND_PORTAL = 85; - public const SOUND_WATER = 86; - public const SOUND_LAVA_POP = 87; - public const SOUND_LAVA = 88; - public const SOUND_BURP = 89; - public const SOUND_BUCKET_FILL_WATER = 90; - public const SOUND_BUCKET_FILL_LAVA = 91; - public const SOUND_BUCKET_EMPTY_WATER = 92; - public const SOUND_BUCKET_EMPTY_LAVA = 93; - public const SOUND_ARMOR_EQUIP_CHAIN = 94; - public const SOUND_ARMOR_EQUIP_DIAMOND = 95; - public const SOUND_ARMOR_EQUIP_GENERIC = 96; - public const SOUND_ARMOR_EQUIP_GOLD = 97; - public const SOUND_ARMOR_EQUIP_IRON = 98; - public const SOUND_ARMOR_EQUIP_LEATHER = 99; - public const SOUND_ARMOR_EQUIP_ELYTRA = 100; - public const SOUND_RECORD_13 = 101; - public const SOUND_RECORD_CAT = 102; - public const SOUND_RECORD_BLOCKS = 103; - public const SOUND_RECORD_CHIRP = 104; - public const SOUND_RECORD_FAR = 105; - public const SOUND_RECORD_MALL = 106; - public const SOUND_RECORD_MELLOHI = 107; - public const SOUND_RECORD_STAL = 108; - public const SOUND_RECORD_STRAD = 109; - public const SOUND_RECORD_WARD = 110; - public const SOUND_RECORD_11 = 111; - public const SOUND_RECORD_WAIT = 112; - public const SOUND_STOP_RECORD = 113; //Not really a sound - public const SOUND_FLOP = 114; - public const SOUND_ELDERGUARDIAN_CURSE = 115; - public const SOUND_MOB_WARNING = 116; - public const SOUND_MOB_WARNING_BABY = 117; - public const SOUND_TELEPORT = 118; - public const SOUND_SHULKER_OPEN = 119; - public const SOUND_SHULKER_CLOSE = 120; - public const SOUND_HAGGLE = 121; - public const SOUND_HAGGLE_YES = 122; - public const SOUND_HAGGLE_NO = 123; - public const SOUND_HAGGLE_IDLE = 124; - public const SOUND_CHORUSGROW = 125; - public const SOUND_CHORUSDEATH = 126; - public const SOUND_GLASS = 127; - public const SOUND_POTION_BREWED = 128; - public const SOUND_CAST_SPELL = 129; - public const SOUND_PREPARE_ATTACK = 130; - public const SOUND_PREPARE_SUMMON = 131; - public const SOUND_PREPARE_WOLOLO = 132; - public const SOUND_FANG = 133; - public const SOUND_CHARGE = 134; - public const SOUND_CAMERA_TAKE_PICTURE = 135; - public const SOUND_LEASHKNOT_PLACE = 136; - public const SOUND_LEASHKNOT_BREAK = 137; - public const SOUND_GROWL = 138; - public const SOUND_WHINE = 139; - public const SOUND_PANT = 140; - public const SOUND_PURR = 141; - public const SOUND_PURREOW = 142; - public const SOUND_DEATH_MIN_VOLUME = 143; - public const SOUND_DEATH_MID_VOLUME = 144; - public const SOUND_IMITATE_BLAZE = 145; - public const SOUND_IMITATE_CAVE_SPIDER = 146; - public const SOUND_IMITATE_CREEPER = 147; - public const SOUND_IMITATE_ELDER_GUARDIAN = 148; - public const SOUND_IMITATE_ENDER_DRAGON = 149; - public const SOUND_IMITATE_ENDERMAN = 150; - - public const SOUND_IMITATE_EVOCATION_ILLAGER = 152; - public const SOUND_IMITATE_GHAST = 153; - public const SOUND_IMITATE_HUSK = 154; - public const SOUND_IMITATE_ILLUSION_ILLAGER = 155; - public const SOUND_IMITATE_MAGMA_CUBE = 156; - public const SOUND_IMITATE_POLAR_BEAR = 157; - public const SOUND_IMITATE_SHULKER = 158; - public const SOUND_IMITATE_SILVERFISH = 159; - public const SOUND_IMITATE_SKELETON = 160; - public const SOUND_IMITATE_SLIME = 161; - public const SOUND_IMITATE_SPIDER = 162; - public const SOUND_IMITATE_STRAY = 163; - public const SOUND_IMITATE_VEX = 164; - public const SOUND_IMITATE_VINDICATION_ILLAGER = 165; - public const SOUND_IMITATE_WITCH = 166; - public const SOUND_IMITATE_WITHER = 167; - public const SOUND_IMITATE_WITHER_SKELETON = 168; - public const SOUND_IMITATE_WOLF = 169; - public const SOUND_IMITATE_ZOMBIE = 170; - public const SOUND_IMITATE_ZOMBIE_PIGMAN = 171; - public const SOUND_IMITATE_ZOMBIE_VILLAGER = 172; - public const SOUND_BLOCK_END_PORTAL_FRAME_FILL = 173; - public const SOUND_BLOCK_END_PORTAL_SPAWN = 174; - public const SOUND_RANDOM_ANVIL_USE = 175; - public const SOUND_BOTTLE_DRAGONBREATH = 176; - public const SOUND_PORTAL_TRAVEL = 177; - public const SOUND_ITEM_TRIDENT_HIT = 178; - public const SOUND_ITEM_TRIDENT_RETURN = 179; - public const SOUND_ITEM_TRIDENT_RIPTIDE_1 = 180; - public const SOUND_ITEM_TRIDENT_RIPTIDE_2 = 181; - public const SOUND_ITEM_TRIDENT_RIPTIDE_3 = 182; - public const SOUND_ITEM_TRIDENT_THROW = 183; - public const SOUND_ITEM_TRIDENT_THUNDER = 184; - public const SOUND_ITEM_TRIDENT_HIT_GROUND = 185; - public const SOUND_DEFAULT = 186; - public const SOUND_BLOCK_FLETCHING_TABLE_USE = 187; - public const SOUND_ELEMCONSTRUCT_OPEN = 188; - public const SOUND_ICEBOMB_HIT = 189; - public const SOUND_BALLOONPOP = 190; - public const SOUND_LT_REACTION_ICEBOMB = 191; - public const SOUND_LT_REACTION_BLEACH = 192; - public const SOUND_LT_REACTION_EPASTE = 193; - public const SOUND_LT_REACTION_EPASTE2 = 194; - - public const SOUND_LT_REACTION_FERTILIZER = 199; - public const SOUND_LT_REACTION_FIREBALL = 200; - public const SOUND_LT_REACTION_MGSALT = 201; - public const SOUND_LT_REACTION_MISCFIRE = 202; - public const SOUND_LT_REACTION_FIRE = 203; - public const SOUND_LT_REACTION_MISCEXPLOSION = 204; - public const SOUND_LT_REACTION_MISCMYSTICAL = 205; - public const SOUND_LT_REACTION_MISCMYSTICAL2 = 206; - public const SOUND_LT_REACTION_PRODUCT = 207; - public const SOUND_SPARKLER_USE = 208; - public const SOUND_GLOWSTICK_USE = 209; - public const SOUND_SPARKLER_ACTIVE = 210; - public const SOUND_CONVERT_TO_DROWNED = 211; - public const SOUND_BUCKET_FILL_FISH = 212; - public const SOUND_BUCKET_EMPTY_FISH = 213; - public const SOUND_BUBBLE_UP = 214; - public const SOUND_BUBBLE_DOWN = 215; - public const SOUND_BUBBLE_POP = 216; - public const SOUND_BUBBLE_UPINSIDE = 217; - public const SOUND_BUBBLE_DOWNINSIDE = 218; - public const SOUND_HURT_BABY = 219; - public const SOUND_DEATH_BABY = 220; - public const SOUND_STEP_BABY = 221; - - public const SOUND_BORN = 223; - public const SOUND_BLOCK_TURTLE_EGG_BREAK = 224; - public const SOUND_BLOCK_TURTLE_EGG_CRACK = 225; - public const SOUND_BLOCK_TURTLE_EGG_HATCH = 226; - public const SOUND_LAY_EGG = 227; - public const SOUND_BLOCK_TURTLE_EGG_ATTACK = 228; - public const SOUND_BEACON_ACTIVATE = 229; - public const SOUND_BEACON_AMBIENT = 230; - public const SOUND_BEACON_DEACTIVATE = 231; - public const SOUND_BEACON_POWER = 232; - public const SOUND_CONDUIT_ACTIVATE = 233; - public const SOUND_CONDUIT_AMBIENT = 234; - public const SOUND_CONDUIT_ATTACK = 235; - public const SOUND_CONDUIT_DEACTIVATE = 236; - public const SOUND_CONDUIT_SHORT = 237; - public const SOUND_SWOOP = 238; - public const SOUND_BLOCK_BAMBOO_SAPLING_PLACE = 239; - public const SOUND_PRESNEEZE = 240; - public const SOUND_SNEEZE = 241; - public const SOUND_AMBIENT_TAME = 242; - public const SOUND_SCARED = 243; - public const SOUND_BLOCK_SCAFFOLDING_CLIMB = 244; - public const SOUND_CROSSBOW_LOADING_START = 245; - public const SOUND_CROSSBOW_LOADING_MIDDLE = 246; - public const SOUND_CROSSBOW_LOADING_END = 247; - public const SOUND_CROSSBOW_SHOOT = 248; - public const SOUND_CROSSBOW_QUICK_CHARGE_START = 249; - public const SOUND_CROSSBOW_QUICK_CHARGE_MIDDLE = 250; - public const SOUND_CROSSBOW_QUICK_CHARGE_END = 251; - public const SOUND_AMBIENT_AGGRESSIVE = 252; - public const SOUND_AMBIENT_WORRIED = 253; - public const SOUND_CANT_BREED = 254; - public const SOUND_ITEM_SHIELD_BLOCK = 255; - public const SOUND_ITEM_BOOK_PUT = 256; - public const SOUND_BLOCK_GRINDSTONE_USE = 257; - public const SOUND_BLOCK_BELL_HIT = 258; - public const SOUND_BLOCK_CAMPFIRE_CRACKLE = 259; - public const SOUND_ROAR = 260; - public const SOUND_STUN = 261; - public const SOUND_BLOCK_SWEET_BERRY_BUSH_HURT = 262; - public const SOUND_BLOCK_SWEET_BERRY_BUSH_PICK = 263; - public const SOUND_BLOCK_CARTOGRAPHY_TABLE_USE = 264; - public const SOUND_BLOCK_STONECUTTER_USE = 265; - public const SOUND_BLOCK_COMPOSTER_EMPTY = 266; - public const SOUND_BLOCK_COMPOSTER_FILL = 267; - public const SOUND_BLOCK_COMPOSTER_FILL_SUCCESS = 268; - public const SOUND_BLOCK_COMPOSTER_READY = 269; - public const SOUND_BLOCK_BARREL_OPEN = 270; - public const SOUND_BLOCK_BARREL_CLOSE = 271; - public const SOUND_RAID_HORN = 272; - public const SOUND_BLOCK_LOOM_USE = 273; - public const SOUND_AMBIENT_IN_RAID = 274; - public const SOUND_UI_CARTOGRAPHY_TABLE_TAKE_RESULT = 275; - public const SOUND_UI_STONECUTTER_TAKE_RESULT = 276; - public const SOUND_UI_LOOM_TAKE_RESULT = 277; - public const SOUND_BLOCK_SMOKER_SMOKE = 278; - public const SOUND_BLOCK_BLASTFURNACE_FIRE_CRACKLE = 279; - public const SOUND_BLOCK_SMITHING_TABLE_USE = 280; - public const SOUND_SCREECH = 281; - public const SOUND_SLEEP = 282; - public const SOUND_BLOCK_FURNACE_LIT = 283; - public const SOUND_CONVERT_MOOSHROOM = 284; - public const SOUND_MILK_SUSPICIOUSLY = 285; - public const SOUND_CELEBRATE = 286; - public const SOUND_JUMP_PREVENT = 287; - public const SOUND_AMBIENT_POLLINATE = 288; - public const SOUND_BLOCK_BEEHIVE_DRIP = 289; - public const SOUND_BLOCK_BEEHIVE_ENTER = 290; - public const SOUND_BLOCK_BEEHIVE_EXIT = 291; - public const SOUND_BLOCK_BEEHIVE_WORK = 292; - public const SOUND_BLOCK_BEEHIVE_SHEAR = 293; - public const SOUND_DRINK_HONEY = 294; - public const SOUND_AMBIENT_CAVE = 295; - public const SOUND_RETREAT = 296; - public const SOUND_CONVERTED_TO_ZOMBIFIED = 297; - public const SOUND_ADMIRE = 298; - public const SOUND_STEP_LAVA = 299; - public const SOUND_TEMPT = 300; - public const SOUND_PANIC = 301; - public const SOUND_ANGRY = 302; - public const SOUND_AMBIENT_WARPED_FOREST_MOOD = 303; - public const SOUND_AMBIENT_SOULSAND_VALLEY_MOOD = 304; - public const SOUND_AMBIENT_NETHER_WASTES_MOOD = 305; - public const SOUND_RESPAWN_ANCHOR_BASALT_DELTAS_MOOD = 306; - public const SOUND_AMBIENT_CRIMSON_FOREST_MOOD = 307; - public const SOUND_RESPAWN_ANCHOR_CHARGE = 308; - public const SOUND_RESPAWN_ANCHOR_DEPLETE = 309; - public const SOUND_RESPAWN_ANCHOR_SET_SPAWN = 310; - public const SOUND_RESPAWN_ANCHOR_AMBIENT = 311; - public const SOUND_PARTICLE_SOUL_ESCAPE_QUIET = 312; - public const SOUND_PARTICLE_SOUL_ESCAPE_LOUD = 313; - public const SOUND_RECORD_PIGSTEP = 314; - public const SOUND_LODESTONE_COMPASS_LINK_COMPASS_TO_LODESTONE = 315; - public const SOUND_SMITHING_TABLE_USE = 316; - public const SOUND_ARMOR_EQUIP_NETHERITE = 317; - public const SOUND_AMBIENT_WARPED_FOREST_LOOP = 318; - public const SOUND_AMBIENT_SOULSAND_VALLEY_LOOP = 319; - public const SOUND_AMBIENT_NETHER_WASTES_LOOP = 320; - public const SOUND_AMBIENT_BASALT_DELTAS_LOOP = 321; - public const SOUND_AMBIENT_CRIMSON_FOREST_LOOP = 322; - public const SOUND_AMBIENT_WARPED_FOREST_ADDITIONS = 323; - public const SOUND_AMBIENT_SOULSAND_VALLEY_ADDITIONS = 324; - public const SOUND_AMBIENT_NETHER_WASTES_ADDITIONS = 325; - public const SOUND_AMBIENT_BASALT_DELTAS_ADDITIONS = 326; - public const SOUND_AMBIENT_CRIMSON_FOREST_ADDITIONS = 327; - public const SOUND_BUCKET_FILL_POWDER_SNOW = 328; - public const SOUND_BUCKET_EMPTY_POWDER_SNOW = 329; - public const SOUND_UNDEFINED = 330; - - public static function create(int $sound, ?Vector3 $pos, int $extraData = -1, string $entityType = ":", bool $isBabyMob = false) : self{ - $result = new self; - $result->sound = $sound; - $result->extraData = $extraData; - $result->position = $pos ?? new Vector3(0, 0, 0); - $result->disableRelativeVolume = $pos === null; - $result->entityType = $entityType; - $result->isBabyMob = $isBabyMob; - return $result; - } - - /** @var int */ - public $sound; - /** @var Vector3 */ - public $position; - /** @var int */ - public $extraData = -1; - /** @var string */ - public $entityType = ":"; //??? - /** @var bool */ - public $isBabyMob = false; //... - /** @var bool */ - public $disableRelativeVolume = false; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->sound = $in->getUnsignedVarInt(); - $this->position = $in->getVector3(); - $this->extraData = $in->getVarInt(); - $this->entityType = $in->getString(); - $this->isBabyMob = $in->getBool(); - $this->disableRelativeVolume = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt($this->sound); - $out->putVector3($this->position); - $out->putVarInt($this->extraData); - $out->putString($this->entityType); - $out->putBool($this->isBabyMob); - $out->putBool($this->disableRelativeVolume); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleLevelSoundEvent($this); - } -} diff --git a/src/network/mcpe/protocol/LevelSoundEventPacketV1.php b/src/network/mcpe/protocol/LevelSoundEventPacketV1.php deleted file mode 100644 index 213db6f716..0000000000 --- a/src/network/mcpe/protocol/LevelSoundEventPacketV1.php +++ /dev/null @@ -1,71 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -/** - * Useless leftover from a 1.8 refactor, does nothing - */ -class LevelSoundEventPacketV1 extends DataPacket{ - public const NETWORK_ID = ProtocolInfo::LEVEL_SOUND_EVENT_PACKET_V1; - - /** @var int */ - public $sound; - /** @var Vector3 */ - public $position; - /** @var int */ - public $extraData = 0; - /** @var int */ - public $entityType = 1; - /** @var bool */ - public $isBabyMob = false; //... - /** @var bool */ - public $disableRelativeVolume = false; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->sound = $in->getByte(); - $this->position = $in->getVector3(); - $this->extraData = $in->getVarInt(); - $this->entityType = $in->getVarInt(); - $this->isBabyMob = $in->getBool(); - $this->disableRelativeVolume = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->sound); - $out->putVector3($this->position); - $out->putVarInt($this->extraData); - $out->putVarInt($this->entityType); - $out->putBool($this->isBabyMob); - $out->putBool($this->disableRelativeVolume); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleLevelSoundEventPacketV1($this); - } -} diff --git a/src/network/mcpe/protocol/LevelSoundEventPacketV2.php b/src/network/mcpe/protocol/LevelSoundEventPacketV2.php deleted file mode 100644 index 934004602c..0000000000 --- a/src/network/mcpe/protocol/LevelSoundEventPacketV2.php +++ /dev/null @@ -1,71 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -/** - * Useless leftover from a 1.9 refactor, does nothing - */ -class LevelSoundEventPacketV2 extends DataPacket{ - public const NETWORK_ID = ProtocolInfo::LEVEL_SOUND_EVENT_PACKET_V2; - - /** @var int */ - public $sound; - /** @var Vector3 */ - public $position; - /** @var int */ - public $extraData = -1; - /** @var string */ - public $entityType = ":"; //??? - /** @var bool */ - public $isBabyMob = false; //... - /** @var bool */ - public $disableRelativeVolume = false; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->sound = $in->getByte(); - $this->position = $in->getVector3(); - $this->extraData = $in->getVarInt(); - $this->entityType = $in->getString(); - $this->isBabyMob = $in->getBool(); - $this->disableRelativeVolume = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->sound); - $out->putVector3($this->position); - $out->putVarInt($this->extraData); - $out->putString($this->entityType); - $out->putBool($this->isBabyMob); - $out->putBool($this->disableRelativeVolume); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleLevelSoundEventPacketV2($this); - } -} diff --git a/src/network/mcpe/protocol/LoginPacket.php b/src/network/mcpe/protocol/LoginPacket.php deleted file mode 100644 index 615afa1384..0000000000 --- a/src/network/mcpe/protocol/LoginPacket.php +++ /dev/null @@ -1,101 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\login\JwtChain; -use pocketmine\utils\BinaryStream; -use function is_object; -use function json_decode; -use function json_encode; -use function json_last_error_msg; -use function strlen; - -class LoginPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::LOGIN_PACKET; - - /** @var int */ - public $protocol; - - /** @var JwtChain */ - public $chainDataJwt; - /** @var string */ - public $clientDataJwt; - - public function canBeSentBeforeLogin() : bool{ - return true; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->protocol = $in->getInt(); - $this->decodeConnectionRequest($in->getString()); - } - - protected function decodeConnectionRequest(string $binary) : void{ - $connRequestReader = new BinaryStream($binary); - - $chainDataJson = json_decode($connRequestReader->get($connRequestReader->getLInt())); - if(!is_object($chainDataJson)){ - throw new PacketDecodeException("Failed decoding chain data JSON: " . json_last_error_msg()); - } - $mapper = new \JsonMapper; - $mapper->bExceptionOnMissingData = true; - $mapper->bExceptionOnUndefinedProperty = true; - try{ - $chainData = $mapper->map($chainDataJson, new JwtChain); - }catch(\JsonMapper_Exception $e){ - throw PacketDecodeException::wrap($e); - } - - $this->chainDataJwt = $chainData; - $this->clientDataJwt = $connRequestReader->get($connRequestReader->getLInt()); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putInt($this->protocol); - $out->putString($this->encodeConnectionRequest()); - } - - protected function encodeConnectionRequest() : string{ - $connRequestWriter = new BinaryStream(); - - $chainDataJson = json_encode($this->chainDataJwt); - if($chainDataJson === false){ - throw new \InvalidStateException("Failed to encode chain data JSON: " . json_last_error_msg()); - } - $connRequestWriter->putLInt(strlen($chainDataJson)); - $connRequestWriter->put($chainDataJson); - - $connRequestWriter->putLInt(strlen($this->clientDataJwt)); - $connRequestWriter->put($this->clientDataJwt); - - return $connRequestWriter->getBuffer(); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleLogin($this); - } -} diff --git a/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php b/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php deleted file mode 100644 index 2c74b60e1a..0000000000 --- a/src/network/mcpe/protocol/MapCreateLockedCopyPacket.php +++ /dev/null @@ -1,51 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class MapCreateLockedCopyPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::MAP_CREATE_LOCKED_COPY_PACKET; - - /** @var int */ - public $originalMapId; - /** @var int */ - public $newMapId; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->originalMapId = $in->getEntityUniqueId(); - $this->newMapId = $in->getEntityUniqueId(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityUniqueId($this->originalMapId); - $out->putEntityUniqueId($this->newMapId); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleMapCreateLockedCopy($this); - } -} diff --git a/src/network/mcpe/protocol/MapInfoRequestPacket.php b/src/network/mcpe/protocol/MapInfoRequestPacket.php deleted file mode 100644 index 7d8ac82f05..0000000000 --- a/src/network/mcpe/protocol/MapInfoRequestPacket.php +++ /dev/null @@ -1,47 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class MapInfoRequestPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::MAP_INFO_REQUEST_PACKET; - - /** @var int */ - public $mapId; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->mapId = $in->getEntityUniqueId(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityUniqueId($this->mapId); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleMapInfoRequest($this); - } -} diff --git a/src/network/mcpe/protocol/MobArmorEquipmentPacket.php b/src/network/mcpe/protocol/MobArmorEquipmentPacket.php deleted file mode 100644 index 813101d6b2..0000000000 --- a/src/network/mcpe/protocol/MobArmorEquipmentPacket.php +++ /dev/null @@ -1,78 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper; - -class MobArmorEquipmentPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::MOB_ARMOR_EQUIPMENT_PACKET; - - /** @var int */ - public $entityRuntimeId; - - //this intentionally doesn't use an array because we don't want any implicit dependencies on internal order - - /** @var ItemStackWrapper */ - public $head; - /** @var ItemStackWrapper */ - public $chest; - /** @var ItemStackWrapper */ - public $legs; - /** @var ItemStackWrapper */ - public $feet; - - public static function create(int $entityRuntimeId, ItemStackWrapper $head, ItemStackWrapper $chest, ItemStackWrapper $legs, ItemStackWrapper $feet) : self{ - $result = new self; - $result->entityRuntimeId = $entityRuntimeId; - $result->head = $head; - $result->chest = $chest; - $result->legs = $legs; - $result->feet = $feet; - - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityRuntimeId = $in->getEntityRuntimeId(); - $this->head = ItemStackWrapper::read($in); - $this->chest = ItemStackWrapper::read($in); - $this->legs = ItemStackWrapper::read($in); - $this->feet = ItemStackWrapper::read($in); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityRuntimeId($this->entityRuntimeId); - $this->head->write($out); - $this->chest->write($out); - $this->legs->write($out); - $this->feet->write($out); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleMobArmorEquipment($this); - } -} diff --git a/src/network/mcpe/protocol/MobEffectPacket.php b/src/network/mcpe/protocol/MobEffectPacket.php deleted file mode 100644 index 7265c22535..0000000000 --- a/src/network/mcpe/protocol/MobEffectPacket.php +++ /dev/null @@ -1,90 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class MobEffectPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::MOB_EFFECT_PACKET; - - public const EVENT_ADD = 1; - public const EVENT_MODIFY = 2; - public const EVENT_REMOVE = 3; - - /** @var int */ - public $entityRuntimeId; - /** @var int */ - public $eventId; - /** @var int */ - public $effectId; - /** @var int */ - public $amplifier = 0; - /** @var bool */ - public $particles = true; - /** @var int */ - public $duration = 0; - - public static function add(int $entityRuntimeId, bool $replace, int $effectId, int $amplifier, bool $particles, int $duration) : self{ - $result = new self; - $result->eventId = $replace ? self::EVENT_MODIFY : self::EVENT_ADD; - $result->entityRuntimeId = $entityRuntimeId; - $result->effectId = $effectId; - $result->amplifier = $amplifier; - $result->particles = $particles; - $result->duration = $duration; - return $result; - } - - public static function remove(int $entityRuntimeId, int $effectId) : self{ - $pk = new self; - $pk->eventId = self::EVENT_REMOVE; - $pk->entityRuntimeId = $entityRuntimeId; - $pk->effectId = $effectId; - return $pk; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityRuntimeId = $in->getEntityRuntimeId(); - $this->eventId = $in->getByte(); - $this->effectId = $in->getVarInt(); - $this->amplifier = $in->getVarInt(); - $this->particles = $in->getBool(); - $this->duration = $in->getVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityRuntimeId($this->entityRuntimeId); - $out->putByte($this->eventId); - $out->putVarInt($this->effectId); - $out->putVarInt($this->amplifier); - $out->putBool($this->particles); - $out->putVarInt($this->duration); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleMobEffect($this); - } -} diff --git a/src/network/mcpe/protocol/MobEquipmentPacket.php b/src/network/mcpe/protocol/MobEquipmentPacket.php deleted file mode 100644 index 2f36f1cb54..0000000000 --- a/src/network/mcpe/protocol/MobEquipmentPacket.php +++ /dev/null @@ -1,74 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper; - -class MobEquipmentPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::MOB_EQUIPMENT_PACKET; - - /** @var int */ - public $entityRuntimeId; - /** @var ItemStackWrapper */ - public $item; - /** @var int */ - public $inventorySlot; - /** @var int */ - public $hotbarSlot; - /** @var int */ - public $windowId = 0; - - public static function create(int $entityRuntimeId, ItemStackWrapper $item, int $inventorySlot, int $windowId) : self{ - $result = new self; - $result->entityRuntimeId = $entityRuntimeId; - $result->item = $item; - $result->inventorySlot = $inventorySlot; - $result->hotbarSlot = $inventorySlot; - $result->windowId = $windowId; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityRuntimeId = $in->getEntityRuntimeId(); - $this->item = ItemStackWrapper::read($in); - $this->inventorySlot = $in->getByte(); - $this->hotbarSlot = $in->getByte(); - $this->windowId = $in->getByte(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityRuntimeId($this->entityRuntimeId); - $this->item->write($out); - $out->putByte($this->inventorySlot); - $out->putByte($this->hotbarSlot); - $out->putByte($this->windowId); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleMobEquipment($this); - } -} diff --git a/src/network/mcpe/protocol/ModalFormRequestPacket.php b/src/network/mcpe/protocol/ModalFormRequestPacket.php deleted file mode 100644 index 0d00021e3a..0000000000 --- a/src/network/mcpe/protocol/ModalFormRequestPacket.php +++ /dev/null @@ -1,58 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ModalFormRequestPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::MODAL_FORM_REQUEST_PACKET; - - /** @var int */ - public $formId; - /** @var string */ - public $formData; //json - - public static function create(int $formId, string $formData) : self{ - $result = new self; - $result->formId = $formId; - $result->formData = $formData; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->formId = $in->getUnsignedVarInt(); - $this->formData = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt($this->formId); - $out->putString($this->formData); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleModalFormRequest($this); - } -} diff --git a/src/network/mcpe/protocol/ModalFormResponsePacket.php b/src/network/mcpe/protocol/ModalFormResponsePacket.php deleted file mode 100644 index 1d7d552a5d..0000000000 --- a/src/network/mcpe/protocol/ModalFormResponsePacket.php +++ /dev/null @@ -1,51 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ModalFormResponsePacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::MODAL_FORM_RESPONSE_PACKET; - - /** @var int */ - public $formId; - /** @var string */ - public $formData; //json - - protected function decodePayload(PacketSerializer $in) : void{ - $this->formId = $in->getUnsignedVarInt(); - $this->formData = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt($this->formId); - $out->putString($this->formData); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleModalFormResponse($this); - } -} diff --git a/src/network/mcpe/protocol/MotionPredictionHintsPacket.php b/src/network/mcpe/protocol/MotionPredictionHintsPacket.php deleted file mode 100644 index 8afe9b9f31..0000000000 --- a/src/network/mcpe/protocol/MotionPredictionHintsPacket.php +++ /dev/null @@ -1,70 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class MotionPredictionHintsPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::MOTION_PREDICTION_HINTS_PACKET; - - /** @var int */ - private $entityRuntimeId; - /** @var Vector3 */ - private $motion; - /** @var bool */ - private $onGround; - - public static function create(int $entityRuntimeId, Vector3 $motion, bool $onGround) : self{ - $result = new self; - $result->entityRuntimeId = $entityRuntimeId; - $result->motion = $motion; - $result->onGround = $onGround; - return $result; - } - - public function getEntityRuntimeId() : int{ return $this->entityRuntimeId; } - - public function getMotion() : Vector3{ return $this->motion; } - - public function isOnGround() : bool{ return $this->onGround; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityRuntimeId = $in->getEntityRuntimeId(); - $this->motion = $in->getVector3(); - $this->onGround = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityRuntimeId($this->entityRuntimeId); - $out->putVector3($this->motion); - $out->putBool($this->onGround); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleMotionPredictionHints($this); - } -} diff --git a/src/network/mcpe/protocol/MoveActorAbsolutePacket.php b/src/network/mcpe/protocol/MoveActorAbsolutePacket.php deleted file mode 100644 index a987cc51fd..0000000000 --- a/src/network/mcpe/protocol/MoveActorAbsolutePacket.php +++ /dev/null @@ -1,83 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class MoveActorAbsolutePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::MOVE_ACTOR_ABSOLUTE_PACKET; - - public const FLAG_GROUND = 0x01; - public const FLAG_TELEPORT = 0x02; - public const FLAG_FORCE_MOVE_LOCAL_ENTITY = 0x04; - - /** @var int */ - public $entityRuntimeId; - /** @var int */ - public $flags = 0; - /** @var Vector3 */ - public $position; - /** @var float */ - public $xRot; - /** @var float */ - public $yRot; - /** @var float */ - public $zRot; - - public static function create(int $entityRuntimeId, Vector3 $pos, float $xRot, float $yRot, float $zRot, int $flags = 0) : self{ - $result = new self; - $result->entityRuntimeId = $entityRuntimeId; - $result->position = $pos->asVector3(); - $result->xRot = $xRot; - $result->yRot = $yRot; - $result->zRot = $zRot; - $result->flags = $flags; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityRuntimeId = $in->getEntityRuntimeId(); - $this->flags = $in->getByte(); - $this->position = $in->getVector3(); - $this->xRot = $in->getByteRotation(); - $this->yRot = $in->getByteRotation(); - $this->zRot = $in->getByteRotation(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityRuntimeId($this->entityRuntimeId); - $out->putByte($this->flags); - $out->putVector3($this->position); - $out->putByteRotation($this->xRot); - $out->putByteRotation($this->yRot); - $out->putByteRotation($this->zRot); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleMoveActorAbsolute($this); - } -} diff --git a/src/network/mcpe/protocol/MoveActorDeltaPacket.php b/src/network/mcpe/protocol/MoveActorDeltaPacket.php deleted file mode 100644 index 30ac900e58..0000000000 --- a/src/network/mcpe/protocol/MoveActorDeltaPacket.php +++ /dev/null @@ -1,118 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\utils\BinaryDataException; - -class MoveActorDeltaPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::MOVE_ACTOR_DELTA_PACKET; - - public const FLAG_HAS_X = 0x01; - public const FLAG_HAS_Y = 0x02; - public const FLAG_HAS_Z = 0x04; - public const FLAG_HAS_ROT_X = 0x08; - public const FLAG_HAS_ROT_Y = 0x10; - public const FLAG_HAS_ROT_Z = 0x20; - public const FLAG_GROUND = 0x40; - public const FLAG_TELEPORT = 0x80; - public const FLAG_FORCE_MOVE_LOCAL_ENTITY = 0x100; - - /** @var int */ - public $entityRuntimeId; - /** @var int */ - public $flags; - /** @var float */ - public $xPos = 0; - /** @var float */ - public $yPos = 0; - /** @var float */ - public $zPos = 0; - /** @var float */ - public $xRot = 0.0; - /** @var float */ - public $yRot = 0.0; - /** @var float */ - public $zRot = 0.0; - - /** - * @throws BinaryDataException - */ - private function maybeReadCoord(int $flag, PacketSerializer $in) : float{ - if(($this->flags & $flag) !== 0){ - return $in->getLFloat(); - } - return 0; - } - - /** - * @throws BinaryDataException - */ - private function maybeReadRotation(int $flag, PacketSerializer $in) : float{ - if(($this->flags & $flag) !== 0){ - return $in->getByteRotation(); - } - return 0.0; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityRuntimeId = $in->getEntityRuntimeId(); - $this->flags = $in->getLShort(); - $this->xPos = $this->maybeReadCoord(self::FLAG_HAS_X, $in); - $this->yPos = $this->maybeReadCoord(self::FLAG_HAS_Y, $in); - $this->zPos = $this->maybeReadCoord(self::FLAG_HAS_Z, $in); - $this->xRot = $this->maybeReadRotation(self::FLAG_HAS_ROT_X, $in); - $this->yRot = $this->maybeReadRotation(self::FLAG_HAS_ROT_Y, $in); - $this->zRot = $this->maybeReadRotation(self::FLAG_HAS_ROT_Z, $in); - } - - private function maybeWriteCoord(int $flag, float $val, PacketSerializer $out) : void{ - if(($this->flags & $flag) !== 0){ - $out->putLFloat($val); - } - } - - private function maybeWriteRotation(int $flag, float $val, PacketSerializer $out) : void{ - if(($this->flags & $flag) !== 0){ - $out->putByteRotation($val); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityRuntimeId($this->entityRuntimeId); - $out->putLShort($this->flags); - $this->maybeWriteCoord(self::FLAG_HAS_X, $this->xPos, $out); - $this->maybeWriteCoord(self::FLAG_HAS_Y, $this->yPos, $out); - $this->maybeWriteCoord(self::FLAG_HAS_Z, $this->zPos, $out); - $this->maybeWriteRotation(self::FLAG_HAS_ROT_X, $this->xRot, $out); - $this->maybeWriteRotation(self::FLAG_HAS_ROT_Y, $this->yRot, $out); - $this->maybeWriteRotation(self::FLAG_HAS_ROT_Z, $this->zRot, $out); - } - - public function handle(PacketHandlerInterface $session) : bool{ - return $session->handleMoveActorDelta($this); - } -} diff --git a/src/network/mcpe/protocol/MovePlayerPacket.php b/src/network/mcpe/protocol/MovePlayerPacket.php deleted file mode 100644 index c092f67127..0000000000 --- a/src/network/mcpe/protocol/MovePlayerPacket.php +++ /dev/null @@ -1,97 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class MovePlayerPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::MOVE_PLAYER_PACKET; - - public const MODE_NORMAL = 0; - public const MODE_RESET = 1; - public const MODE_TELEPORT = 2; - public const MODE_PITCH = 3; //facepalm Mojang - - /** @var int */ - public $entityRuntimeId; - /** @var Vector3 */ - public $position; - /** @var float */ - public $pitch; - /** @var float */ - public $yaw; - /** @var float */ - public $headYaw; - /** @var int */ - public $mode = self::MODE_NORMAL; - /** @var bool */ - public $onGround = false; //TODO - /** @var int */ - public $ridingEid = 0; - /** @var int */ - public $teleportCause = 0; - /** @var int */ - public $teleportItem = 0; - /** @var int */ - public $tick = 0; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityRuntimeId = $in->getEntityRuntimeId(); - $this->position = $in->getVector3(); - $this->pitch = $in->getLFloat(); - $this->yaw = $in->getLFloat(); - $this->headYaw = $in->getLFloat(); - $this->mode = $in->getByte(); - $this->onGround = $in->getBool(); - $this->ridingEid = $in->getEntityRuntimeId(); - if($this->mode === MovePlayerPacket::MODE_TELEPORT){ - $this->teleportCause = $in->getLInt(); - $this->teleportItem = $in->getLInt(); - } - $this->tick = $in->getUnsignedVarLong(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityRuntimeId($this->entityRuntimeId); - $out->putVector3($this->position); - $out->putLFloat($this->pitch); - $out->putLFloat($this->yaw); - $out->putLFloat($this->headYaw); //TODO - $out->putByte($this->mode); - $out->putBool($this->onGround); - $out->putEntityRuntimeId($this->ridingEid); - if($this->mode === MovePlayerPacket::MODE_TELEPORT){ - $out->putLInt($this->teleportCause); - $out->putLInt($this->teleportItem); - } - $out->putUnsignedVarLong($this->tick); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleMovePlayer($this); - } -} diff --git a/src/network/mcpe/protocol/MultiplayerSettingsPacket.php b/src/network/mcpe/protocol/MultiplayerSettingsPacket.php deleted file mode 100644 index 0c635b5179..0000000000 --- a/src/network/mcpe/protocol/MultiplayerSettingsPacket.php +++ /dev/null @@ -1,61 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class MultiplayerSettingsPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::MULTIPLAYER_SETTINGS_PACKET; - - public const ACTION_ENABLE_MULTIPLAYER = 0; - public const ACTION_DISABLE_MULTIPLAYER = 1; - public const ACTION_REFRESH_JOIN_CODE = 2; - - /** @var int */ - private $action; - - public static function create(int $action) : self{ - $result = new self; - $result->action = $action; - return $result; - } - - public function getAction() : int{ - return $this->action; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->action = $in->getVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVarInt($this->action); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleMultiplayerSettings($this); - } -} diff --git a/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php b/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php deleted file mode 100644 index 32aeb02740..0000000000 --- a/src/network/mcpe/protocol/NetworkChunkPublisherUpdatePacket.php +++ /dev/null @@ -1,64 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class NetworkChunkPublisherUpdatePacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::NETWORK_CHUNK_PUBLISHER_UPDATE_PACKET; - - /** @var int */ - public $x; - /** @var int */ - public $y; - /** @var int */ - public $z; - /** @var int */ - public $radius; - - public static function create(int $x, int $y, int $z, int $blockRadius) : self{ - $result = new self; - $result->x = $x; - $result->y = $y; - $result->z = $z; - $result->radius = $blockRadius; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $in->getSignedBlockPosition($this->x, $this->y, $this->z); - $this->radius = $in->getUnsignedVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putSignedBlockPosition($this->x, $this->y, $this->z); - $out->putUnsignedVarInt($this->radius); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleNetworkChunkPublisherUpdate($this); - } -} diff --git a/src/network/mcpe/protocol/NetworkSettingsPacket.php b/src/network/mcpe/protocol/NetworkSettingsPacket.php deleted file mode 100644 index 77477d1299..0000000000 --- a/src/network/mcpe/protocol/NetworkSettingsPacket.php +++ /dev/null @@ -1,60 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class NetworkSettingsPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::NETWORK_SETTINGS_PACKET; - - public const COMPRESS_NOTHING = 0; - public const COMPRESS_EVERYTHING = 1; - - /** @var int */ - private $compressionThreshold; - - public static function create(int $compressionThreshold) : self{ - $result = new self; - $result->compressionThreshold = $compressionThreshold; - return $result; - } - - public function getCompressionThreshold() : int{ - return $this->compressionThreshold; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->compressionThreshold = $in->getLShort(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putLShort($this->compressionThreshold); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleNetworkSettings($this); - } -} diff --git a/src/network/mcpe/protocol/NetworkStackLatencyPacket.php b/src/network/mcpe/protocol/NetworkStackLatencyPacket.php deleted file mode 100644 index 11211fea47..0000000000 --- a/src/network/mcpe/protocol/NetworkStackLatencyPacket.php +++ /dev/null @@ -1,65 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class NetworkStackLatencyPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::NETWORK_STACK_LATENCY_PACKET; - - /** @var int */ - public $timestamp; - /** @var bool */ - public $needResponse; - - public static function request(int $timestampNs) : self{ - $result = new self; - $result->timestamp = $timestampNs; - $result->needResponse = true; - return $result; - } - - public static function response(int $timestampNs) : self{ - $result = new self; - $result->timestamp = $timestampNs; - $result->needResponse = false; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->timestamp = $in->getLLong(); - $this->needResponse = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putLLong($this->timestamp); - $out->putBool($this->needResponse); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleNetworkStackLatency($this); - } -} diff --git a/src/network/mcpe/protocol/NpcDialoguePacket.php b/src/network/mcpe/protocol/NpcDialoguePacket.php deleted file mode 100644 index 87beb49154..0000000000 --- a/src/network/mcpe/protocol/NpcDialoguePacket.php +++ /dev/null @@ -1,87 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class NpcDialoguePacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::NPC_DIALOGUE_PACKET; - - public const ACTION_OPEN = 0; - public const ACTION_CLOSE = 1; - - private int $npcActorUniqueId; - private int $actionType; - private string $dialogue; - private string $sceneName; - private string $npcName; - private string $actionJson; - - public static function create(int $npcActorUniqueId, int $actionType, string $dialogue, string $sceneName, string $npcName, string $actionJson) : self{ - $result = new self; - $result->npcActorUniqueId = $npcActorUniqueId; - $result->actionType = $actionType; - $result->dialogue = $dialogue; - $result->sceneName = $sceneName; - $result->npcName = $npcName; - $result->actionJson = $actionJson; - return $result; - } - - public function getNpcActorUniqueId() : int{ return $this->npcActorUniqueId; } - - public function getActionType() : int{ return $this->actionType; } - - public function getDialogue() : string{ return $this->dialogue; } - - public function getSceneName() : string{ return $this->sceneName; } - - public function getNpcName() : string{ return $this->npcName; } - - public function getActionJson() : string{ return $this->actionJson; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->npcActorUniqueId = $in->getEntityUniqueId(); - $this->actionType = $in->getVarInt(); - $this->dialogue = $in->getString(); - $this->sceneName = $in->getString(); - $this->npcName = $in->getString(); - $this->actionJson = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityUniqueId($this->npcActorUniqueId); - $out->putVarInt($this->actionType); - $out->putString($this->dialogue); - $out->putString($this->sceneName); - $out->putString($this->npcName); - $out->putString($this->actionJson); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleNpcDialogue($this); - } -} diff --git a/src/network/mcpe/protocol/NpcRequestPacket.php b/src/network/mcpe/protocol/NpcRequestPacket.php deleted file mode 100644 index 674bfb8427..0000000000 --- a/src/network/mcpe/protocol/NpcRequestPacket.php +++ /dev/null @@ -1,70 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class NpcRequestPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::NPC_REQUEST_PACKET; - - public const REQUEST_SET_ACTIONS = 0; - public const REQUEST_EXECUTE_ACTION = 1; - public const REQUEST_EXECUTE_CLOSING_COMMANDS = 2; - public const REQUEST_SET_NAME = 3; - public const REQUEST_SET_SKIN = 4; - public const REQUEST_SET_INTERACTION_TEXT = 5; - public const REQUEST_EXECUTE_OPENING_COMMANDS = 6; - - /** @var int */ - public $entityRuntimeId; - /** @var int */ - public $requestType; - /** @var string */ - public $commandString; - /** @var int */ - public $actionType; - public string $sceneName; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityRuntimeId = $in->getEntityRuntimeId(); - $this->requestType = $in->getByte(); - $this->commandString = $in->getString(); - $this->actionType = $in->getByte(); - $this->sceneName = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityRuntimeId($this->entityRuntimeId); - $out->putByte($this->requestType); - $out->putString($this->commandString); - $out->putByte($this->actionType); - $out->putString($this->sceneName); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleNpcRequest($this); - } -} diff --git a/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php b/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php deleted file mode 100644 index 80d66b37a9..0000000000 --- a/src/network/mcpe/protocol/OnScreenTextureAnimationPacket.php +++ /dev/null @@ -1,47 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class OnScreenTextureAnimationPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::ON_SCREEN_TEXTURE_ANIMATION_PACKET; - - /** @var int */ - public $effectId; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->effectId = $in->getLInt(); //unsigned - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putLInt($this->effectId); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleOnScreenTextureAnimation($this); - } -} diff --git a/src/network/mcpe/protocol/Packet.php b/src/network/mcpe/protocol/Packet.php deleted file mode 100644 index f089901ca3..0000000000 --- a/src/network/mcpe/protocol/Packet.php +++ /dev/null @@ -1,57 +0,0 @@ -getMessage(), 0, $previous); - } -} \ No newline at end of file diff --git a/src/network/mcpe/protocol/PacketHandlerInterface.php b/src/network/mcpe/protocol/PacketHandlerInterface.php deleted file mode 100644 index 1dc610952a..0000000000 --- a/src/network/mcpe/protocol/PacketHandlerInterface.php +++ /dev/null @@ -1,357 +0,0 @@ - */ - protected $pool; - - public function __construct(){ - $this->pool = new \SplFixedArray(256); - - $this->registerPacket(new LoginPacket()); - $this->registerPacket(new PlayStatusPacket()); - $this->registerPacket(new ServerToClientHandshakePacket()); - $this->registerPacket(new ClientToServerHandshakePacket()); - $this->registerPacket(new DisconnectPacket()); - $this->registerPacket(new ResourcePacksInfoPacket()); - $this->registerPacket(new ResourcePackStackPacket()); - $this->registerPacket(new ResourcePackClientResponsePacket()); - $this->registerPacket(new TextPacket()); - $this->registerPacket(new SetTimePacket()); - $this->registerPacket(new StartGamePacket()); - $this->registerPacket(new AddPlayerPacket()); - $this->registerPacket(new AddActorPacket()); - $this->registerPacket(new RemoveActorPacket()); - $this->registerPacket(new AddItemActorPacket()); - $this->registerPacket(new TakeItemActorPacket()); - $this->registerPacket(new MoveActorAbsolutePacket()); - $this->registerPacket(new MovePlayerPacket()); - $this->registerPacket(new RiderJumpPacket()); - $this->registerPacket(new UpdateBlockPacket()); - $this->registerPacket(new AddPaintingPacket()); - $this->registerPacket(new TickSyncPacket()); - $this->registerPacket(new LevelSoundEventPacketV1()); - $this->registerPacket(new LevelEventPacket()); - $this->registerPacket(new BlockEventPacket()); - $this->registerPacket(new ActorEventPacket()); - $this->registerPacket(new MobEffectPacket()); - $this->registerPacket(new UpdateAttributesPacket()); - $this->registerPacket(new InventoryTransactionPacket()); - $this->registerPacket(new MobEquipmentPacket()); - $this->registerPacket(new MobArmorEquipmentPacket()); - $this->registerPacket(new InteractPacket()); - $this->registerPacket(new BlockPickRequestPacket()); - $this->registerPacket(new ActorPickRequestPacket()); - $this->registerPacket(new PlayerActionPacket()); - $this->registerPacket(new HurtArmorPacket()); - $this->registerPacket(new SetActorDataPacket()); - $this->registerPacket(new SetActorMotionPacket()); - $this->registerPacket(new SetActorLinkPacket()); - $this->registerPacket(new SetHealthPacket()); - $this->registerPacket(new SetSpawnPositionPacket()); - $this->registerPacket(new AnimatePacket()); - $this->registerPacket(new RespawnPacket()); - $this->registerPacket(new ContainerOpenPacket()); - $this->registerPacket(new ContainerClosePacket()); - $this->registerPacket(new PlayerHotbarPacket()); - $this->registerPacket(new InventoryContentPacket()); - $this->registerPacket(new InventorySlotPacket()); - $this->registerPacket(new ContainerSetDataPacket()); - $this->registerPacket(new CraftingDataPacket()); - $this->registerPacket(new CraftingEventPacket()); - $this->registerPacket(new GuiDataPickItemPacket()); - $this->registerPacket(new AdventureSettingsPacket()); - $this->registerPacket(new BlockActorDataPacket()); - $this->registerPacket(new PlayerInputPacket()); - $this->registerPacket(new LevelChunkPacket()); - $this->registerPacket(new SetCommandsEnabledPacket()); - $this->registerPacket(new SetDifficultyPacket()); - $this->registerPacket(new ChangeDimensionPacket()); - $this->registerPacket(new SetPlayerGameTypePacket()); - $this->registerPacket(new PlayerListPacket()); - $this->registerPacket(new SimpleEventPacket()); - $this->registerPacket(new EventPacket()); - $this->registerPacket(new SpawnExperienceOrbPacket()); - $this->registerPacket(new ClientboundMapItemDataPacket()); - $this->registerPacket(new MapInfoRequestPacket()); - $this->registerPacket(new RequestChunkRadiusPacket()); - $this->registerPacket(new ChunkRadiusUpdatedPacket()); - $this->registerPacket(new ItemFrameDropItemPacket()); - $this->registerPacket(new GameRulesChangedPacket()); - $this->registerPacket(new CameraPacket()); - $this->registerPacket(new BossEventPacket()); - $this->registerPacket(new ShowCreditsPacket()); - $this->registerPacket(new AvailableCommandsPacket()); - $this->registerPacket(new CommandRequestPacket()); - $this->registerPacket(new CommandBlockUpdatePacket()); - $this->registerPacket(new CommandOutputPacket()); - $this->registerPacket(new UpdateTradePacket()); - $this->registerPacket(new UpdateEquipPacket()); - $this->registerPacket(new ResourcePackDataInfoPacket()); - $this->registerPacket(new ResourcePackChunkDataPacket()); - $this->registerPacket(new ResourcePackChunkRequestPacket()); - $this->registerPacket(new TransferPacket()); - $this->registerPacket(new PlaySoundPacket()); - $this->registerPacket(new StopSoundPacket()); - $this->registerPacket(new SetTitlePacket()); - $this->registerPacket(new AddBehaviorTreePacket()); - $this->registerPacket(new StructureBlockUpdatePacket()); - $this->registerPacket(new ShowStoreOfferPacket()); - $this->registerPacket(new PurchaseReceiptPacket()); - $this->registerPacket(new PlayerSkinPacket()); - $this->registerPacket(new SubClientLoginPacket()); - $this->registerPacket(new AutomationClientConnectPacket()); - $this->registerPacket(new SetLastHurtByPacket()); - $this->registerPacket(new BookEditPacket()); - $this->registerPacket(new NpcRequestPacket()); - $this->registerPacket(new PhotoTransferPacket()); - $this->registerPacket(new ModalFormRequestPacket()); - $this->registerPacket(new ModalFormResponsePacket()); - $this->registerPacket(new ServerSettingsRequestPacket()); - $this->registerPacket(new ServerSettingsResponsePacket()); - $this->registerPacket(new ShowProfilePacket()); - $this->registerPacket(new SetDefaultGameTypePacket()); - $this->registerPacket(new RemoveObjectivePacket()); - $this->registerPacket(new SetDisplayObjectivePacket()); - $this->registerPacket(new SetScorePacket()); - $this->registerPacket(new LabTablePacket()); - $this->registerPacket(new UpdateBlockSyncedPacket()); - $this->registerPacket(new MoveActorDeltaPacket()); - $this->registerPacket(new SetScoreboardIdentityPacket()); - $this->registerPacket(new SetLocalPlayerAsInitializedPacket()); - $this->registerPacket(new UpdateSoftEnumPacket()); - $this->registerPacket(new NetworkStackLatencyPacket()); - $this->registerPacket(new ScriptCustomEventPacket()); - $this->registerPacket(new SpawnParticleEffectPacket()); - $this->registerPacket(new AvailableActorIdentifiersPacket()); - $this->registerPacket(new LevelSoundEventPacketV2()); - $this->registerPacket(new NetworkChunkPublisherUpdatePacket()); - $this->registerPacket(new BiomeDefinitionListPacket()); - $this->registerPacket(new LevelSoundEventPacket()); - $this->registerPacket(new LevelEventGenericPacket()); - $this->registerPacket(new LecternUpdatePacket()); - $this->registerPacket(new AddEntityPacket()); - $this->registerPacket(new RemoveEntityPacket()); - $this->registerPacket(new ClientCacheStatusPacket()); - $this->registerPacket(new OnScreenTextureAnimationPacket()); - $this->registerPacket(new MapCreateLockedCopyPacket()); - $this->registerPacket(new StructureTemplateDataRequestPacket()); - $this->registerPacket(new StructureTemplateDataResponsePacket()); - $this->registerPacket(new ClientCacheBlobStatusPacket()); - $this->registerPacket(new ClientCacheMissResponsePacket()); - $this->registerPacket(new EducationSettingsPacket()); - $this->registerPacket(new EmotePacket()); - $this->registerPacket(new MultiplayerSettingsPacket()); - $this->registerPacket(new SettingsCommandPacket()); - $this->registerPacket(new AnvilDamagePacket()); - $this->registerPacket(new CompletedUsingItemPacket()); - $this->registerPacket(new NetworkSettingsPacket()); - $this->registerPacket(new PlayerAuthInputPacket()); - $this->registerPacket(new CreativeContentPacket()); - $this->registerPacket(new PlayerEnchantOptionsPacket()); - $this->registerPacket(new ItemStackRequestPacket()); - $this->registerPacket(new ItemStackResponsePacket()); - $this->registerPacket(new PlayerArmorDamagePacket()); - $this->registerPacket(new CodeBuilderPacket()); - $this->registerPacket(new UpdatePlayerGameTypePacket()); - $this->registerPacket(new EmoteListPacket()); - $this->registerPacket(new PositionTrackingDBServerBroadcastPacket()); - $this->registerPacket(new PositionTrackingDBClientRequestPacket()); - $this->registerPacket(new DebugInfoPacket()); - $this->registerPacket(new PacketViolationWarningPacket()); - $this->registerPacket(new MotionPredictionHintsPacket()); - $this->registerPacket(new AnimateEntityPacket()); - $this->registerPacket(new CameraShakePacket()); - $this->registerPacket(new PlayerFogPacket()); - $this->registerPacket(new CorrectPlayerMovePredictionPacket()); - $this->registerPacket(new ItemComponentPacket()); - $this->registerPacket(new FilterTextPacket()); - $this->registerPacket(new ClientboundDebugRendererPacket()); - $this->registerPacket(new SyncActorPropertyPacket()); - $this->registerPacket(new AddVolumeEntityPacket()); - $this->registerPacket(new RemoveVolumeEntityPacket()); - $this->registerPacket(new SimulationTypePacket()); - $this->registerPacket(new NpcDialoguePacket()); - } - - public function registerPacket(Packet $packet) : void{ - $this->pool[$packet->pid()] = clone $packet; - } - - public function getPacketById(int $pid) : Packet{ - return isset($this->pool[$pid]) ? clone $this->pool[$pid] : new UnknownPacket(); - } - - /** - * @throws BinaryDataException - */ - public function getPacket(string $buffer) : Packet{ - $offset = 0; - return $this->getPacketById(Binary::readUnsignedVarInt($buffer, $offset) & DataPacket::PID_MASK); - } -} diff --git a/src/network/mcpe/protocol/PacketViolationWarningPacket.php b/src/network/mcpe/protocol/PacketViolationWarningPacket.php deleted file mode 100644 index c100647cee..0000000000 --- a/src/network/mcpe/protocol/PacketViolationWarningPacket.php +++ /dev/null @@ -1,84 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class PacketViolationWarningPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::PACKET_VIOLATION_WARNING_PACKET; - - public const TYPE_MALFORMED = 0; - - public const SEVERITY_WARNING = 0; - public const SEVERITY_FINAL_WARNING = 1; - public const SEVERITY_TERMINATING_CONNECTION = 2; - - /** @var int */ - private $type; - /** @var int */ - private $severity; - /** @var int */ - private $packetId; - /** @var string */ - private $message; - - public static function create(int $type, int $severity, int $packetId, string $message) : self{ - $result = new self; - - $result->type = $type; - $result->severity = $severity; - $result->packetId = $packetId; - $result->message = $message; - - return $result; - } - - public function getType() : int{ return $this->type; } - - public function getSeverity() : int{ return $this->severity; } - - public function getPacketId() : int{ return $this->packetId; } - - public function getMessage() : string{ return $this->message; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->type = $in->getVarInt(); - $this->severity = $in->getVarInt(); - $this->packetId = $in->getVarInt(); - $this->message = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVarInt($this->type); - $out->putVarInt($this->severity); - $out->putVarInt($this->packetId); - $out->putString($this->message); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handlePacketViolationWarning($this); - } -} diff --git a/src/network/mcpe/protocol/PhotoTransferPacket.php b/src/network/mcpe/protocol/PhotoTransferPacket.php deleted file mode 100644 index ccaf0eb510..0000000000 --- a/src/network/mcpe/protocol/PhotoTransferPacket.php +++ /dev/null @@ -1,55 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class PhotoTransferPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::PHOTO_TRANSFER_PACKET; - - /** @var string */ - public $photoName; - /** @var string */ - public $photoData; - /** @var string */ - public $bookId; //photos are stored in a sibling directory to the games folder (screenshots/(some UUID)/bookID/example.png) - - protected function decodePayload(PacketSerializer $in) : void{ - $this->photoName = $in->getString(); - $this->photoData = $in->getString(); - $this->bookId = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->photoName); - $out->putString($this->photoData); - $out->putString($this->bookId); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handlePhotoTransfer($this); - } -} diff --git a/src/network/mcpe/protocol/PlaySoundPacket.php b/src/network/mcpe/protocol/PlaySoundPacket.php deleted file mode 100644 index 7384145fae..0000000000 --- a/src/network/mcpe/protocol/PlaySoundPacket.php +++ /dev/null @@ -1,66 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class PlaySoundPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::PLAY_SOUND_PACKET; - - /** @var string */ - public $soundName; - /** @var float */ - public $x; - /** @var float */ - public $y; - /** @var float */ - public $z; - /** @var float */ - public $volume; - /** @var float */ - public $pitch; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->soundName = $in->getString(); - $in->getBlockPosition($this->x, $this->y, $this->z); - $this->x /= 8; - $this->y /= 8; - $this->z /= 8; - $this->volume = $in->getLFloat(); - $this->pitch = $in->getLFloat(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->soundName); - $out->putBlockPosition((int) ($this->x * 8), (int) ($this->y * 8), (int) ($this->z * 8)); - $out->putLFloat($this->volume); - $out->putLFloat($this->pitch); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handlePlaySound($this); - } -} diff --git a/src/network/mcpe/protocol/PlayStatusPacket.php b/src/network/mcpe/protocol/PlayStatusPacket.php deleted file mode 100644 index 98aec071cf..0000000000 --- a/src/network/mcpe/protocol/PlayStatusPacket.php +++ /dev/null @@ -1,66 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class PlayStatusPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::PLAY_STATUS_PACKET; - - public const LOGIN_SUCCESS = 0; - public const LOGIN_FAILED_CLIENT = 1; - public const LOGIN_FAILED_SERVER = 2; - public const PLAYER_SPAWN = 3; - public const LOGIN_FAILED_INVALID_TENANT = 4; - public const LOGIN_FAILED_VANILLA_EDU = 5; - public const LOGIN_FAILED_EDU_VANILLA = 6; - public const LOGIN_FAILED_SERVER_FULL = 7; - - /** @var int */ - public $status; - - public static function create(int $status) : self{ - $result = new self; - $result->status = $status; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->status = $in->getInt(); - } - - public function canBeSentBeforeLogin() : bool{ - return true; - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putInt($this->status); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handlePlayStatus($this); - } -} diff --git a/src/network/mcpe/protocol/PlayerActionPacket.php b/src/network/mcpe/protocol/PlayerActionPacket.php deleted file mode 100644 index 4ceef5dfe0..0000000000 --- a/src/network/mcpe/protocol/PlayerActionPacket.php +++ /dev/null @@ -1,92 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class PlayerActionPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::PLAYER_ACTION_PACKET; - - public const ACTION_START_BREAK = 0; - public const ACTION_ABORT_BREAK = 1; - public const ACTION_STOP_BREAK = 2; - public const ACTION_GET_UPDATED_BLOCK = 3; - public const ACTION_DROP_ITEM = 4; - public const ACTION_START_SLEEPING = 5; - public const ACTION_STOP_SLEEPING = 6; - public const ACTION_RESPAWN = 7; - public const ACTION_JUMP = 8; - public const ACTION_START_SPRINT = 9; - public const ACTION_STOP_SPRINT = 10; - public const ACTION_START_SNEAK = 11; - public const ACTION_STOP_SNEAK = 12; - public const ACTION_CREATIVE_PLAYER_DESTROY_BLOCK = 13; - public const ACTION_DIMENSION_CHANGE_ACK = 14; //sent when spawning in a different dimension to tell the server we spawned - public const ACTION_START_GLIDE = 15; - public const ACTION_STOP_GLIDE = 16; - public const ACTION_BUILD_DENIED = 17; - public const ACTION_CRACK_BREAK = 18; - public const ACTION_CHANGE_SKIN = 19; - public const ACTION_SET_ENCHANTMENT_SEED = 20; //no longer used - public const ACTION_START_SWIMMING = 21; - public const ACTION_STOP_SWIMMING = 22; - public const ACTION_START_SPIN_ATTACK = 23; - public const ACTION_STOP_SPIN_ATTACK = 24; - public const ACTION_INTERACT_BLOCK = 25; - public const ACTION_PREDICT_DESTROY_BLOCK = 26; - public const ACTION_CONTINUE_DESTROY_BLOCK = 27; - - /** @var int */ - public $entityRuntimeId; - /** @var int */ - public $action; - /** @var int */ - public $x; - /** @var int */ - public $y; - /** @var int */ - public $z; - /** @var int */ - public $face; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityRuntimeId = $in->getEntityRuntimeId(); - $this->action = $in->getVarInt(); - $in->getBlockPosition($this->x, $this->y, $this->z); - $this->face = $in->getVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityRuntimeId($this->entityRuntimeId); - $out->putVarInt($this->action); - $out->putBlockPosition($this->x, $this->y, $this->z); - $out->putVarInt($this->face); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handlePlayerAction($this); - } -} diff --git a/src/network/mcpe/protocol/PlayerArmorDamagePacket.php b/src/network/mcpe/protocol/PlayerArmorDamagePacket.php deleted file mode 100644 index 748084c615..0000000000 --- a/src/network/mcpe/protocol/PlayerArmorDamagePacket.php +++ /dev/null @@ -1,108 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class PlayerArmorDamagePacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::PLAYER_ARMOR_DAMAGE_PACKET; - - private const FLAG_HEAD = 0; - private const FLAG_CHEST = 1; - private const FLAG_LEGS = 2; - private const FLAG_FEET = 3; - - /** @var int|null */ - private $headSlotDamage; - /** @var int|null */ - private $chestSlotDamage; - /** @var int|null */ - private $legsSlotDamage; - /** @var int|null */ - private $feetSlotDamage; - - public static function create(?int $headSlotDamage, ?int $chestSlotDamage, ?int $legsSlotDamage, ?int $feetSlotDamage) : self{ - $result = new self; - $result->headSlotDamage = $headSlotDamage; - $result->chestSlotDamage = $chestSlotDamage; - $result->legsSlotDamage = $legsSlotDamage; - $result->feetSlotDamage = $feetSlotDamage; - - return $result; - } - - public function getHeadSlotDamage() : ?int{ return $this->headSlotDamage; } - - public function getChestSlotDamage() : ?int{ return $this->chestSlotDamage; } - - public function getLegsSlotDamage() : ?int{ return $this->legsSlotDamage; } - - public function getFeetSlotDamage() : ?int{ return $this->feetSlotDamage; } - - private function maybeReadDamage(int $flags, int $flag, PacketSerializer $in) : ?int{ - if(($flags & (1 << $flag)) !== 0){ - return $in->getVarInt(); - } - return null; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $flags = $in->getByte(); - - $this->headSlotDamage = $this->maybeReadDamage($flags, self::FLAG_HEAD, $in); - $this->chestSlotDamage = $this->maybeReadDamage($flags, self::FLAG_CHEST, $in); - $this->legsSlotDamage = $this->maybeReadDamage($flags, self::FLAG_LEGS, $in); - $this->feetSlotDamage = $this->maybeReadDamage($flags, self::FLAG_FEET, $in); - } - - private function composeFlag(?int $field, int $flag) : int{ - return $field !== null ? (1 << $flag) : 0; - } - - private function maybeWriteDamage(?int $field, PacketSerializer $out) : void{ - if($field !== null){ - $out->putVarInt($field); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte( - $this->composeFlag($this->headSlotDamage, self::FLAG_HEAD) | - $this->composeFlag($this->chestSlotDamage, self::FLAG_CHEST) | - $this->composeFlag($this->legsSlotDamage, self::FLAG_LEGS) | - $this->composeFlag($this->feetSlotDamage, self::FLAG_FEET) - ); - - $this->maybeWriteDamage($this->headSlotDamage, $out); - $this->maybeWriteDamage($this->chestSlotDamage, $out); - $this->maybeWriteDamage($this->legsSlotDamage, $out); - $this->maybeWriteDamage($this->feetSlotDamage, $out); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handlePlayerArmorDamage($this); - } -} diff --git a/src/network/mcpe/protocol/PlayerAuthInputPacket.php b/src/network/mcpe/protocol/PlayerAuthInputPacket.php deleted file mode 100644 index 77fa3f5f9b..0000000000 --- a/src/network/mcpe/protocol/PlayerAuthInputPacket.php +++ /dev/null @@ -1,179 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\InputMode; -use pocketmine\network\mcpe\protocol\types\PlayerAuthInputFlags; -use pocketmine\network\mcpe\protocol\types\PlayMode; -use function assert; - -class PlayerAuthInputPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::PLAYER_AUTH_INPUT_PACKET; - - /** @var Vector3 */ - private $position; - /** @var float */ - private $pitch; - /** @var float */ - private $yaw; - /** @var float */ - private $headYaw; - /** @var float */ - private $moveVecX; - /** @var float */ - private $moveVecZ; - /** @var int */ - private $inputFlags; - /** @var int */ - private $inputMode; - /** @var int */ - private $playMode; - /** @var Vector3|null */ - private $vrGazeDirection = null; - /** @var int */ - private $tick; - /** @var Vector3 */ - private $delta; - - /** - * @param int $inputFlags @see InputFlags - * @param int $inputMode @see InputMode - * @param int $playMode @see PlayMode - * @param Vector3|null $vrGazeDirection only used when PlayMode::VR - */ - public static function create(Vector3 $position, float $pitch, float $yaw, float $headYaw, float $moveVecX, float $moveVecZ, int $inputFlags, int $inputMode, int $playMode, ?Vector3 $vrGazeDirection, int $tick, Vector3 $delta) : self{ - if($playMode === PlayMode::VR and $vrGazeDirection === null){ - //yuck, can we get a properly written packet just once? ... - throw new \InvalidArgumentException("Gaze direction must be provided for VR play mode"); - } - $result = new self; - $result->position = $position->asVector3(); - $result->pitch = $pitch; - $result->yaw = $yaw; - $result->headYaw = $headYaw; - $result->moveVecX = $moveVecX; - $result->moveVecZ = $moveVecZ; - $result->inputFlags = $inputFlags; - $result->inputMode = $inputMode; - $result->playMode = $playMode; - if($vrGazeDirection !== null){ - $result->vrGazeDirection = $vrGazeDirection->asVector3(); - } - $result->tick = $tick; - $result->delta = $delta; - return $result; - } - - public function getPosition() : Vector3{ - return $this->position; - } - - public function getPitch() : float{ - return $this->pitch; - } - - public function getYaw() : float{ - return $this->yaw; - } - - public function getHeadYaw() : float{ - return $this->headYaw; - } - - public function getMoveVecX() : float{ - return $this->moveVecX; - } - - public function getMoveVecZ() : float{ - return $this->moveVecZ; - } - - /** - * @see PlayerAuthInputFlags - */ - public function getInputFlags() : int{ - return $this->inputFlags; - } - - /** - * @see InputMode - */ - public function getInputMode() : int{ - return $this->inputMode; - } - - /** - * @see PlayMode - */ - public function getPlayMode() : int{ - return $this->playMode; - } - - public function getVrGazeDirection() : ?Vector3{ - return $this->vrGazeDirection; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->pitch = $in->getLFloat(); - $this->yaw = $in->getLFloat(); - $this->position = $in->getVector3(); - $this->moveVecX = $in->getLFloat(); - $this->moveVecZ = $in->getLFloat(); - $this->headYaw = $in->getLFloat(); - $this->inputFlags = $in->getUnsignedVarLong(); - $this->inputMode = $in->getUnsignedVarInt(); - $this->playMode = $in->getUnsignedVarInt(); - if($this->playMode === PlayMode::VR){ - $this->vrGazeDirection = $in->getVector3(); - } - $this->tick = $in->getUnsignedVarLong(); - $this->delta = $in->getVector3(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putLFloat($this->pitch); - $out->putLFloat($this->yaw); - $out->putVector3($this->position); - $out->putLFloat($this->moveVecX); - $out->putLFloat($this->moveVecZ); - $out->putLFloat($this->headYaw); - $out->putUnsignedVarLong($this->inputFlags); - $out->putUnsignedVarInt($this->inputMode); - $out->putUnsignedVarInt($this->playMode); - if($this->playMode === PlayMode::VR){ - assert($this->vrGazeDirection !== null); - $out->putVector3($this->vrGazeDirection); - } - $out->putUnsignedVarLong($this->tick); - $out->putVector3($this->delta); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handlePlayerAuthInput($this); - } -} diff --git a/src/network/mcpe/protocol/PlayerEnchantOptionsPacket.php b/src/network/mcpe/protocol/PlayerEnchantOptionsPacket.php deleted file mode 100644 index d7efbd7c4e..0000000000 --- a/src/network/mcpe/protocol/PlayerEnchantOptionsPacket.php +++ /dev/null @@ -1,69 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\EnchantOption; -use function count; - -class PlayerEnchantOptionsPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::PLAYER_ENCHANT_OPTIONS_PACKET; - - /** @var EnchantOption[] */ - private $options; - - /** - * @param EnchantOption[] $options - */ - public static function create(array $options) : self{ - $result = new self; - $result->options = $options; - return $result; - } - - /** - * @return EnchantOption[] - */ - public function getOptions() : array{ return $this->options; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->options = []; - for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ - $this->options[] = EnchantOption::read($in); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt(count($this->options)); - foreach($this->options as $option){ - $option->write($out); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handlePlayerEnchantOptions($this); - } -} diff --git a/src/network/mcpe/protocol/PlayerFogPacket.php b/src/network/mcpe/protocol/PlayerFogPacket.php deleted file mode 100644 index c97c77285c..0000000000 --- a/src/network/mcpe/protocol/PlayerFogPacket.php +++ /dev/null @@ -1,73 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use function count; - -class PlayerFogPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::PLAYER_FOG_PACKET; - - /** - * @var string[] - * @phpstan-var list - */ - private $fogLayers; - - /** - * @param string[] $fogLayers - * @phpstan-param list $fogLayers - */ - public static function create(array $fogLayers) : self{ - $result = new self; - $result->fogLayers = $fogLayers; - return $result; - } - - /** - * @return string[] - * @phpstan-return list - */ - public function getFogLayers() : array{ return $this->fogLayers; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->fogLayers = []; - for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ - $this->fogLayers[] = $in->getString(); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt(count($this->fogLayers)); - foreach($this->fogLayers as $fogLayer){ - $out->putString($fogLayer); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handlePlayerFog($this); - } -} diff --git a/src/network/mcpe/protocol/PlayerHotbarPacket.php b/src/network/mcpe/protocol/PlayerHotbarPacket.php deleted file mode 100644 index b6dc141a7f..0000000000 --- a/src/network/mcpe/protocol/PlayerHotbarPacket.php +++ /dev/null @@ -1,64 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; - -class PlayerHotbarPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::PLAYER_HOTBAR_PACKET; - - /** @var int */ - public $selectedHotbarSlot; - /** @var int */ - public $windowId = ContainerIds::INVENTORY; - /** @var bool */ - public $selectHotbarSlot = true; - - public static function create(int $slot, int $windowId, bool $selectSlot = true) : self{ - $result = new self; - $result->selectedHotbarSlot = $slot; - $result->windowId = $windowId; - $result->selectHotbarSlot = $selectSlot; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->selectedHotbarSlot = $in->getUnsignedVarInt(); - $this->windowId = $in->getByte(); - $this->selectHotbarSlot = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt($this->selectedHotbarSlot); - $out->putByte($this->windowId); - $out->putBool($this->selectHotbarSlot); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handlePlayerHotbar($this); - } -} diff --git a/src/network/mcpe/protocol/PlayerInputPacket.php b/src/network/mcpe/protocol/PlayerInputPacket.php deleted file mode 100644 index 5069a66fde..0000000000 --- a/src/network/mcpe/protocol/PlayerInputPacket.php +++ /dev/null @@ -1,59 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class PlayerInputPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::PLAYER_INPUT_PACKET; - - /** @var float */ - public $motionX; - /** @var float */ - public $motionY; - /** @var bool */ - public $jumping; - /** @var bool */ - public $sneaking; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->motionX = $in->getLFloat(); - $this->motionY = $in->getLFloat(); - $this->jumping = $in->getBool(); - $this->sneaking = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putLFloat($this->motionX); - $out->putLFloat($this->motionY); - $out->putBool($this->jumping); - $out->putBool($this->sneaking); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handlePlayerInput($this); - } -} diff --git a/src/network/mcpe/protocol/PlayerListPacket.php b/src/network/mcpe/protocol/PlayerListPacket.php deleted file mode 100644 index 54ac6462f8..0000000000 --- a/src/network/mcpe/protocol/PlayerListPacket.php +++ /dev/null @@ -1,120 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\PlayerListEntry; -use function count; - -class PlayerListPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::PLAYER_LIST_PACKET; - - public const TYPE_ADD = 0; - public const TYPE_REMOVE = 1; - - /** @var PlayerListEntry[] */ - public $entries = []; - /** @var int */ - public $type; - - /** - * @param PlayerListEntry[] $entries - */ - public static function add(array $entries) : self{ - $result = new self; - $result->type = self::TYPE_ADD; - $result->entries = $entries; - return $result; - } - - /** - * @param PlayerListEntry[] $entries - */ - public static function remove(array $entries) : self{ - $result = new self; - $result->type = self::TYPE_REMOVE; - $result->entries = $entries; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->type = $in->getByte(); - $count = $in->getUnsignedVarInt(); - for($i = 0; $i < $count; ++$i){ - $entry = new PlayerListEntry(); - - if($this->type === self::TYPE_ADD){ - $entry->uuid = $in->getUUID(); - $entry->entityUniqueId = $in->getEntityUniqueId(); - $entry->username = $in->getString(); - $entry->xboxUserId = $in->getString(); - $entry->platformChatId = $in->getString(); - $entry->buildPlatform = $in->getLInt(); - $entry->skinData = $in->getSkin(); - $entry->isTeacher = $in->getBool(); - $entry->isHost = $in->getBool(); - }else{ - $entry->uuid = $in->getUUID(); - } - - $this->entries[$i] = $entry; - } - if($this->type === self::TYPE_ADD){ - for($i = 0; $i < $count; ++$i){ - $this->entries[$i]->skinData->setVerified($in->getBool()); - } - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->type); - $out->putUnsignedVarInt(count($this->entries)); - foreach($this->entries as $entry){ - if($this->type === self::TYPE_ADD){ - $out->putUUID($entry->uuid); - $out->putEntityUniqueId($entry->entityUniqueId); - $out->putString($entry->username); - $out->putString($entry->xboxUserId); - $out->putString($entry->platformChatId); - $out->putLInt($entry->buildPlatform); - $out->putSkin($entry->skinData); - $out->putBool($entry->isTeacher); - $out->putBool($entry->isHost); - }else{ - $out->putUUID($entry->uuid); - } - } - if($this->type === self::TYPE_ADD){ - foreach($this->entries as $entry){ - $out->putBool($entry->skinData->isVerified()); - } - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handlePlayerList($this); - } -} diff --git a/src/network/mcpe/protocol/PlayerSkinPacket.php b/src/network/mcpe/protocol/PlayerSkinPacket.php deleted file mode 100644 index 3b688e46a0..0000000000 --- a/src/network/mcpe/protocol/PlayerSkinPacket.php +++ /dev/null @@ -1,70 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\skin\SkinData; -use Ramsey\Uuid\UuidInterface; - -class PlayerSkinPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::PLAYER_SKIN_PACKET; - - /** @var UuidInterface */ - public $uuid; - /** @var string */ - public $oldSkinName = ""; - /** @var string */ - public $newSkinName = ""; - /** @var SkinData */ - public $skin; - - public static function create(UuidInterface $uuid, SkinData $skinData) : self{ - $result = new self; - $result->uuid = $uuid; - $result->skin = $skinData; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->uuid = $in->getUUID(); - $this->skin = $in->getSkin(); - $this->newSkinName = $in->getString(); - $this->oldSkinName = $in->getString(); - $this->skin->setVerified($in->getBool()); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUUID($this->uuid); - $out->putSkin($this->skin); - $out->putString($this->newSkinName); - $out->putString($this->oldSkinName); - $out->putBool($this->skin->isVerified()); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handlePlayerSkin($this); - } -} diff --git a/src/network/mcpe/protocol/PositionTrackingDBClientRequestPacket.php b/src/network/mcpe/protocol/PositionTrackingDBClientRequestPacket.php deleted file mode 100644 index f5a6a13f7f..0000000000 --- a/src/network/mcpe/protocol/PositionTrackingDBClientRequestPacket.php +++ /dev/null @@ -1,64 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class PositionTrackingDBClientRequestPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::POSITION_TRACKING_D_B_CLIENT_REQUEST_PACKET; - - public const ACTION_QUERY = 0; - - /** @var int */ - private $action; - /** @var int */ - private $trackingId; - - public static function create(int $action, int $trackingId) : self{ - $result = new self; - $result->action = $action; - $result->trackingId = $trackingId; - return $result; - } - - public function getAction() : int{ return $this->action; } - - public function getTrackingId() : int{ return $this->trackingId; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->action = $in->getByte(); - $this->trackingId = $in->getVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->action); - $out->putVarInt($this->trackingId); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handlePositionTrackingDBClientRequest($this); - } -} diff --git a/src/network/mcpe/protocol/PositionTrackingDBServerBroadcastPacket.php b/src/network/mcpe/protocol/PositionTrackingDBServerBroadcastPacket.php deleted file mode 100644 index 7045643bcb..0000000000 --- a/src/network/mcpe/protocol/PositionTrackingDBServerBroadcastPacket.php +++ /dev/null @@ -1,81 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\CacheableNbt; - -class PositionTrackingDBServerBroadcastPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::POSITION_TRACKING_D_B_SERVER_BROADCAST_PACKET; - - public const ACTION_UPDATE = 0; - public const ACTION_DESTROY = 1; - public const ACTION_NOT_FOUND = 2; - - /** @var int */ - private $action; - /** @var int */ - private $trackingId; - /** - * @var CacheableNbt - * @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag> - */ - private $nbt; - - /** - * @phpstan-param CacheableNbt<\pocketmine\nbt\tag\CompoundTag> $nbt - */ - public static function create(int $action, int $trackingId, CacheableNbt $nbt) : self{ - $result = new self; - $result->action = $action; - $result->trackingId = $trackingId; - $result->nbt = $nbt; - return $result; - } - - public function getAction() : int{ return $this->action; } - - public function getTrackingId() : int{ return $this->trackingId; } - - /** @phpstan-return CacheableNbt<\pocketmine\nbt\tag\CompoundTag> */ - public function getNbt() : CacheableNbt{ return $this->nbt; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->action = $in->getByte(); - $this->trackingId = $in->getVarInt(); - $this->nbt = new CacheableNbt($in->getNbtCompoundRoot()); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->action); - $out->putVarInt($this->trackingId); - $out->put($this->nbt->getEncodedNbt()); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handlePositionTrackingDBServerBroadcast($this); - } -} diff --git a/src/network/mcpe/protocol/ProtocolInfo.php b/src/network/mcpe/protocol/ProtocolInfo.php deleted file mode 100644 index 9d5b94b2e9..0000000000 --- a/src/network/mcpe/protocol/ProtocolInfo.php +++ /dev/null @@ -1,220 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use function count; - -class PurchaseReceiptPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::PURCHASE_RECEIPT_PACKET; - - /** @var string[] */ - public $entries = []; - - protected function decodePayload(PacketSerializer $in) : void{ - $count = $in->getUnsignedVarInt(); - for($i = 0; $i < $count; ++$i){ - $this->entries[] = $in->getString(); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt(count($this->entries)); - foreach($this->entries as $entry){ - $out->putString($entry); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handlePurchaseReceipt($this); - } -} diff --git a/src/network/mcpe/protocol/RemoveActorPacket.php b/src/network/mcpe/protocol/RemoveActorPacket.php deleted file mode 100644 index 8fdc2a766d..0000000000 --- a/src/network/mcpe/protocol/RemoveActorPacket.php +++ /dev/null @@ -1,53 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class RemoveActorPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::REMOVE_ACTOR_PACKET; - - /** @var int */ - public $entityUniqueId; - - public static function create(int $entityUniqueId) : self{ - $result = new self; - $result->entityUniqueId = $entityUniqueId; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityUniqueId = $in->getEntityUniqueId(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityUniqueId($this->entityUniqueId); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleRemoveActor($this); - } -} diff --git a/src/network/mcpe/protocol/RemoveEntityPacket.php b/src/network/mcpe/protocol/RemoveEntityPacket.php deleted file mode 100644 index 6c9981d211..0000000000 --- a/src/network/mcpe/protocol/RemoveEntityPacket.php +++ /dev/null @@ -1,57 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class RemoveEntityPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::REMOVE_ENTITY_PACKET; - - /** @var int */ - private $entityNetId; - - public static function create(int $entityNetId) : self{ - $result = new self; - $result->entityNetId = $entityNetId; - return $result; - } - - public function getEntityNetId() : int{ - return $this->entityNetId; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityNetId = $in->getUnsignedVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt($this->entityNetId); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleRemoveEntity($this); - } -} diff --git a/src/network/mcpe/protocol/RemoveObjectivePacket.php b/src/network/mcpe/protocol/RemoveObjectivePacket.php deleted file mode 100644 index 7b4bf22e82..0000000000 --- a/src/network/mcpe/protocol/RemoveObjectivePacket.php +++ /dev/null @@ -1,47 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class RemoveObjectivePacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::REMOVE_OBJECTIVE_PACKET; - - /** @var string */ - public $objectiveName; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->objectiveName = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->objectiveName); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleRemoveObjective($this); - } -} diff --git a/src/network/mcpe/protocol/RemoveVolumeEntityPacket.php b/src/network/mcpe/protocol/RemoveVolumeEntityPacket.php deleted file mode 100644 index 3f5c069f43..0000000000 --- a/src/network/mcpe/protocol/RemoveVolumeEntityPacket.php +++ /dev/null @@ -1,55 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class RemoveVolumeEntityPacket extends DataPacket{ - public const NETWORK_ID = ProtocolInfo::REMOVE_VOLUME_ENTITY_PACKET; - - /** @var int */ - private $entityNetId; - - public static function create(int $entityNetId) : self{ - $result = new self; - $result->entityNetId = $entityNetId; - return $result; - } - - public function getEntityNetId() : int{ return $this->entityNetId; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityNetId = $in->getUnsignedVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt($this->entityNetId); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleRemoveVolumeEntity($this); - } -} diff --git a/src/network/mcpe/protocol/RequestChunkRadiusPacket.php b/src/network/mcpe/protocol/RequestChunkRadiusPacket.php deleted file mode 100644 index 76cdd84709..0000000000 --- a/src/network/mcpe/protocol/RequestChunkRadiusPacket.php +++ /dev/null @@ -1,47 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class RequestChunkRadiusPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::REQUEST_CHUNK_RADIUS_PACKET; - - /** @var int */ - public $radius; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->radius = $in->getVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVarInt($this->radius); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleRequestChunkRadius($this); - } -} diff --git a/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php b/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php deleted file mode 100644 index a26db209e6..0000000000 --- a/src/network/mcpe/protocol/ResourcePackChunkDataPacket.php +++ /dev/null @@ -1,68 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ResourcePackChunkDataPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_CHUNK_DATA_PACKET; - - /** @var string */ - public $packId; - /** @var int */ - public $chunkIndex; - /** @var int */ - public $progress; - /** @var string */ - public $data; - - public static function create(string $packId, int $chunkIndex, int $chunkOffset, string $data) : self{ - $result = new self; - $result->packId = $packId; - $result->chunkIndex = $chunkIndex; - $result->progress = $chunkOffset; - $result->data = $data; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->packId = $in->getString(); - $this->chunkIndex = $in->getLInt(); - $this->progress = $in->getLLong(); - $this->data = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->packId); - $out->putLInt($this->chunkIndex); - $out->putLLong($this->progress); - $out->putString($this->data); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleResourcePackChunkData($this); - } -} diff --git a/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php b/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php deleted file mode 100644 index 30ea02cd84..0000000000 --- a/src/network/mcpe/protocol/ResourcePackChunkRequestPacket.php +++ /dev/null @@ -1,51 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ResourcePackChunkRequestPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_CHUNK_REQUEST_PACKET; - - /** @var string */ - public $packId; - /** @var int */ - public $chunkIndex; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->packId = $in->getString(); - $this->chunkIndex = $in->getLInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->packId); - $out->putLInt($this->chunkIndex); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleResourcePackChunkRequest($this); - } -} diff --git a/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php b/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php deleted file mode 100644 index e0ed823cbe..0000000000 --- a/src/network/mcpe/protocol/ResourcePackClientResponsePacket.php +++ /dev/null @@ -1,64 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use function count; - -class ResourcePackClientResponsePacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_CLIENT_RESPONSE_PACKET; - - public const STATUS_REFUSED = 1; - public const STATUS_SEND_PACKS = 2; - public const STATUS_HAVE_ALL_PACKS = 3; - public const STATUS_COMPLETED = 4; - - /** @var int */ - public $status; - /** @var string[] */ - public $packIds = []; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->status = $in->getByte(); - $entryCount = $in->getLShort(); - $this->packIds = []; - while($entryCount-- > 0){ - $this->packIds[] = $in->getString(); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->status); - $out->putLShort(count($this->packIds)); - foreach($this->packIds as $id){ - $out->putString($id); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleResourcePackClientResponse($this); - } -} diff --git a/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php b/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php deleted file mode 100644 index a7ed482534..0000000000 --- a/src/network/mcpe/protocol/ResourcePackDataInfoPacket.php +++ /dev/null @@ -1,82 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackType; - -class ResourcePackDataInfoPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_DATA_INFO_PACKET; - - /** @var string */ - public $packId; - /** @var int */ - public $maxChunkSize; - /** @var int */ - public $chunkCount; - /** @var int */ - public $compressedPackSize; - /** @var string */ - public $sha256; - /** @var bool */ - public $isPremium = false; - /** @var int */ - public $packType = ResourcePackType::RESOURCES; //TODO: check the values for this - - public static function create(string $packId, int $maxChunkSize, int $chunkCount, int $compressedPackSize, string $sha256sum) : self{ - $result = new self; - $result->packId = $packId; - $result->maxChunkSize = $maxChunkSize; - $result->chunkCount = $chunkCount; - $result->compressedPackSize = $compressedPackSize; - $result->sha256 = $sha256sum; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->packId = $in->getString(); - $this->maxChunkSize = $in->getLInt(); - $this->chunkCount = $in->getLInt(); - $this->compressedPackSize = $in->getLLong(); - $this->sha256 = $in->getString(); - $this->isPremium = $in->getBool(); - $this->packType = $in->getByte(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->packId); - $out->putLInt($this->maxChunkSize); - $out->putLInt($this->chunkCount); - $out->putLLong($this->compressedPackSize); - $out->putString($this->sha256); - $out->putBool($this->isPremium); - $out->putByte($this->packType); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleResourcePackDataInfo($this); - } -} diff --git a/src/network/mcpe/protocol/ResourcePackStackPacket.php b/src/network/mcpe/protocol/ResourcePackStackPacket.php deleted file mode 100644 index 2da8ef97d3..0000000000 --- a/src/network/mcpe/protocol/ResourcePackStackPacket.php +++ /dev/null @@ -1,101 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\Experiments; -use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackStackEntry; -use function count; - -class ResourcePackStackPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::RESOURCE_PACK_STACK_PACKET; - - /** @var bool */ - public $mustAccept = false; - - /** @var ResourcePackStackEntry[] */ - public $behaviorPackStack = []; - /** @var ResourcePackStackEntry[] */ - public $resourcePackStack = []; - - /** @var string */ - public $baseGameVersion = ProtocolInfo::MINECRAFT_VERSION_NETWORK; - - /** @var Experiments */ - public $experiments; - - /** - * @param ResourcePackStackEntry[] $resourcePacks - * @param ResourcePackStackEntry[] $behaviorPacks - * - * @return ResourcePackStackPacket - */ - public static function create(array $resourcePacks, array $behaviorPacks, bool $mustAccept, Experiments $experiments) : self{ - $result = new self; - $result->mustAccept = $mustAccept; - $result->resourcePackStack = $resourcePacks; - $result->behaviorPackStack = $behaviorPacks; - $result->experiments = $experiments; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->mustAccept = $in->getBool(); - $behaviorPackCount = $in->getUnsignedVarInt(); - while($behaviorPackCount-- > 0){ - $this->behaviorPackStack[] = ResourcePackStackEntry::read($in); - } - - $resourcePackCount = $in->getUnsignedVarInt(); - while($resourcePackCount-- > 0){ - $this->resourcePackStack[] = ResourcePackStackEntry::read($in); - } - - $this->baseGameVersion = $in->getString(); - $this->experiments = Experiments::read($in); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putBool($this->mustAccept); - - $out->putUnsignedVarInt(count($this->behaviorPackStack)); - foreach($this->behaviorPackStack as $entry){ - $entry->write($out); - } - - $out->putUnsignedVarInt(count($this->resourcePackStack)); - foreach($this->resourcePackStack as $entry){ - $entry->write($out); - } - - $out->putString($this->baseGameVersion); - $this->experiments->write($out); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleResourcePackStack($this); - } -} diff --git a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php b/src/network/mcpe/protocol/ResourcePacksInfoPacket.php deleted file mode 100644 index 7f1b5dd000..0000000000 --- a/src/network/mcpe/protocol/ResourcePacksInfoPacket.php +++ /dev/null @@ -1,95 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\resourcepacks\BehaviorPackInfoEntry; -use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackInfoEntry; -use function count; - -class ResourcePacksInfoPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::RESOURCE_PACKS_INFO_PACKET; - - /** @var bool */ - public $mustAccept = false; //if true, forces client to choose between accepting packs or being disconnected - /** @var bool */ - public $hasScripts = false; //if true, causes disconnect for any platform that doesn't support scripts yet - - public bool $forceServerPacks = false; - /** @var BehaviorPackInfoEntry[] */ - public $behaviorPackEntries = []; - /** @var ResourcePackInfoEntry[] */ - public $resourcePackEntries = []; - - /** - * @param ResourcePackInfoEntry[] $resourcePacks - * @param BehaviorPackInfoEntry[] $behaviorPacks - * - * @return ResourcePacksInfoPacket - */ - public static function create(array $resourcePacks, array $behaviorPacks, bool $mustAccept, bool $hasScripts, bool $forceServerPacks) : self{ - $result = new self; - $result->mustAccept = $mustAccept; - $result->hasScripts = $hasScripts; - $result->resourcePackEntries = $resourcePacks; - $result->behaviorPackEntries = $behaviorPacks; - $result->forceServerPacks = $forceServerPacks; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->mustAccept = $in->getBool(); - $this->hasScripts = $in->getBool(); - $this->forceServerPacks = $in->getBool(); - $behaviorPackCount = $in->getLShort(); - while($behaviorPackCount-- > 0){ - $this->behaviorPackEntries[] = BehaviorPackInfoEntry::read($in); - } - - $resourcePackCount = $in->getLShort(); - while($resourcePackCount-- > 0){ - $this->resourcePackEntries[] = ResourcePackInfoEntry::read($in); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putBool($this->mustAccept); - $out->putBool($this->hasScripts); - $out->putBool($this->forceServerPacks); - $out->putLShort(count($this->behaviorPackEntries)); - foreach($this->behaviorPackEntries as $entry){ - $entry->write($out); - } - $out->putLShort(count($this->resourcePackEntries)); - foreach($this->resourcePackEntries as $entry){ - $entry->write($out); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleResourcePacksInfo($this); - } -} diff --git a/src/network/mcpe/protocol/RespawnPacket.php b/src/network/mcpe/protocol/RespawnPacket.php deleted file mode 100644 index 4bf6945173..0000000000 --- a/src/network/mcpe/protocol/RespawnPacket.php +++ /dev/null @@ -1,68 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class RespawnPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::RESPAWN_PACKET; - - public const SEARCHING_FOR_SPAWN = 0; - public const READY_TO_SPAWN = 1; - public const CLIENT_READY_TO_SPAWN = 2; - - /** @var Vector3 */ - public $position; - /** @var int */ - public $respawnState = self::SEARCHING_FOR_SPAWN; - /** @var int */ - public $entityRuntimeId; - - public static function create(Vector3 $position, int $respawnStatus, int $entityRuntimeId) : self{ - $result = new self; - $result->position = $position->asVector3(); - $result->respawnState = $respawnStatus; - $result->entityRuntimeId = $entityRuntimeId; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->position = $in->getVector3(); - $this->respawnState = $in->getByte(); - $this->entityRuntimeId = $in->getEntityRuntimeId(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVector3($this->position); - $out->putByte($this->respawnState); - $out->putEntityRuntimeId($this->entityRuntimeId); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleRespawn($this); - } -} diff --git a/src/network/mcpe/protocol/RiderJumpPacket.php b/src/network/mcpe/protocol/RiderJumpPacket.php deleted file mode 100644 index d7186968b7..0000000000 --- a/src/network/mcpe/protocol/RiderJumpPacket.php +++ /dev/null @@ -1,47 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class RiderJumpPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::RIDER_JUMP_PACKET; - - /** @var int */ - public $jumpStrength; //percentage - - protected function decodePayload(PacketSerializer $in) : void{ - $this->jumpStrength = $in->getVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVarInt($this->jumpStrength); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleRiderJump($this); - } -} diff --git a/src/network/mcpe/protocol/ScriptCustomEventPacket.php b/src/network/mcpe/protocol/ScriptCustomEventPacket.php deleted file mode 100644 index 17be40ff91..0000000000 --- a/src/network/mcpe/protocol/ScriptCustomEventPacket.php +++ /dev/null @@ -1,51 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ScriptCustomEventPacket extends DataPacket{ //TODO: this doesn't have handlers in either client or server in the game as of 1.8 - public const NETWORK_ID = ProtocolInfo::SCRIPT_CUSTOM_EVENT_PACKET; - - /** @var string */ - public $eventName; - /** @var string json data */ - public $eventData; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->eventName = $in->getString(); - $this->eventData = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->eventName); - $out->putString($this->eventData); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleScriptCustomEvent($this); - } -} diff --git a/src/network/mcpe/protocol/ServerSettingsRequestPacket.php b/src/network/mcpe/protocol/ServerSettingsRequestPacket.php deleted file mode 100644 index 9d1e60b35e..0000000000 --- a/src/network/mcpe/protocol/ServerSettingsRequestPacket.php +++ /dev/null @@ -1,44 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ServerSettingsRequestPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::SERVER_SETTINGS_REQUEST_PACKET; - - protected function decodePayload(PacketSerializer $in) : void{ - //No payload - } - - protected function encodePayload(PacketSerializer $out) : void{ - //No payload - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleServerSettingsRequest($this); - } -} diff --git a/src/network/mcpe/protocol/ServerSettingsResponsePacket.php b/src/network/mcpe/protocol/ServerSettingsResponsePacket.php deleted file mode 100644 index b1fd1a2708..0000000000 --- a/src/network/mcpe/protocol/ServerSettingsResponsePacket.php +++ /dev/null @@ -1,51 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ServerSettingsResponsePacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::SERVER_SETTINGS_RESPONSE_PACKET; - - /** @var int */ - public $formId; - /** @var string */ - public $formData; //json - - protected function decodePayload(PacketSerializer $in) : void{ - $this->formId = $in->getUnsignedVarInt(); - $this->formData = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt($this->formId); - $out->putString($this->formData); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleServerSettingsResponse($this); - } -} diff --git a/src/network/mcpe/protocol/ServerToClientHandshakePacket.php b/src/network/mcpe/protocol/ServerToClientHandshakePacket.php deleted file mode 100644 index 19f15ade2d..0000000000 --- a/src/network/mcpe/protocol/ServerToClientHandshakePacket.php +++ /dev/null @@ -1,60 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ServerToClientHandshakePacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::SERVER_TO_CLIENT_HANDSHAKE_PACKET; - - /** - * @var string - * Server pubkey and token is contained in the JWT. - */ - public $jwt; - - public static function create(string $jwt) : self{ - $result = new self; - $result->jwt = $jwt; - return $result; - } - - public function canBeSentBeforeLogin() : bool{ - return true; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->jwt = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->jwt); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleServerToClientHandshake($this); - } -} diff --git a/src/network/mcpe/protocol/ServerboundPacket.php b/src/network/mcpe/protocol/ServerboundPacket.php deleted file mode 100644 index 26c0833503..0000000000 --- a/src/network/mcpe/protocol/ServerboundPacket.php +++ /dev/null @@ -1,28 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; - -class SetActorDataPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ //TODO: check why this is serverbound - public const NETWORK_ID = ProtocolInfo::SET_ACTOR_DATA_PACKET; - - /** @var int */ - public $entityRuntimeId; - /** - * @var MetadataProperty[] - * @phpstan-var array - */ - public $metadata; - - /** @var int */ - public $tick = 0; - - /** - * @param MetadataProperty[] $metadata - * @phpstan-param array $metadata - */ - public static function create(int $entityRuntimeId, array $metadata, int $tick) : self{ - - $result = new self; - $result->entityRuntimeId = $entityRuntimeId; - $result->metadata = $metadata; - $result->tick = $tick; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityRuntimeId = $in->getEntityRuntimeId(); - $this->metadata = $in->getEntityMetadata(); - $this->tick = $in->getUnsignedVarLong(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityRuntimeId($this->entityRuntimeId); - $out->putEntityMetadata($this->metadata); - $out->putUnsignedVarLong($this->tick); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSetActorData($this); - } -} diff --git a/src/network/mcpe/protocol/SetActorLinkPacket.php b/src/network/mcpe/protocol/SetActorLinkPacket.php deleted file mode 100644 index f8ca170b81..0000000000 --- a/src/network/mcpe/protocol/SetActorLinkPacket.php +++ /dev/null @@ -1,48 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\entity\EntityLink; - -class SetActorLinkPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::SET_ACTOR_LINK_PACKET; - - /** @var EntityLink */ - public $link; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->link = $in->getEntityLink(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityLink($this->link); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSetActorLink($this); - } -} diff --git a/src/network/mcpe/protocol/SetActorMotionPacket.php b/src/network/mcpe/protocol/SetActorMotionPacket.php deleted file mode 100644 index d848c5ca0f..0000000000 --- a/src/network/mcpe/protocol/SetActorMotionPacket.php +++ /dev/null @@ -1,59 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class SetActorMotionPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::SET_ACTOR_MOTION_PACKET; - - /** @var int */ - public $entityRuntimeId; - /** @var Vector3 */ - public $motion; - - public static function create(int $entityRuntimeId, Vector3 $motion) : self{ - $result = new self; - $result->entityRuntimeId = $entityRuntimeId; - $result->motion = $motion->asVector3(); - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityRuntimeId = $in->getEntityRuntimeId(); - $this->motion = $in->getVector3(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityRuntimeId($this->entityRuntimeId); - $out->putVector3($this->motion); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSetActorMotion($this); - } -} diff --git a/src/network/mcpe/protocol/SetCommandsEnabledPacket.php b/src/network/mcpe/protocol/SetCommandsEnabledPacket.php deleted file mode 100644 index ad5269907b..0000000000 --- a/src/network/mcpe/protocol/SetCommandsEnabledPacket.php +++ /dev/null @@ -1,53 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class SetCommandsEnabledPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::SET_COMMANDS_ENABLED_PACKET; - - /** @var bool */ - public $enabled; - - public static function create(bool $enabled) : self{ - $result = new self; - $result->enabled = $enabled; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->enabled = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putBool($this->enabled); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSetCommandsEnabled($this); - } -} diff --git a/src/network/mcpe/protocol/SetDefaultGameTypePacket.php b/src/network/mcpe/protocol/SetDefaultGameTypePacket.php deleted file mode 100644 index 63cd53f653..0000000000 --- a/src/network/mcpe/protocol/SetDefaultGameTypePacket.php +++ /dev/null @@ -1,53 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class SetDefaultGameTypePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::SET_DEFAULT_GAME_TYPE_PACKET; - - /** @var int */ - public $gamemode; - - public static function create(int $gameMode) : self{ - $result = new self; - $result->gamemode = $gameMode; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->gamemode = $in->getVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt($this->gamemode); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSetDefaultGameType($this); - } -} diff --git a/src/network/mcpe/protocol/SetDifficultyPacket.php b/src/network/mcpe/protocol/SetDifficultyPacket.php deleted file mode 100644 index e430c53d64..0000000000 --- a/src/network/mcpe/protocol/SetDifficultyPacket.php +++ /dev/null @@ -1,53 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class SetDifficultyPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::SET_DIFFICULTY_PACKET; - - /** @var int */ - public $difficulty; - - public static function create(int $difficulty) : self{ - $result = new self; - $result->difficulty = $difficulty; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->difficulty = $in->getUnsignedVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putUnsignedVarInt($this->difficulty); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSetDifficulty($this); - } -} diff --git a/src/network/mcpe/protocol/SetDisplayObjectivePacket.php b/src/network/mcpe/protocol/SetDisplayObjectivePacket.php deleted file mode 100644 index 9154bfa952..0000000000 --- a/src/network/mcpe/protocol/SetDisplayObjectivePacket.php +++ /dev/null @@ -1,70 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class SetDisplayObjectivePacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::SET_DISPLAY_OBJECTIVE_PACKET; - - public const DISPLAY_SLOT_LIST = "list"; - public const DISPLAY_SLOT_SIDEBAR = "sidebar"; - public const DISPLAY_SLOT_BELOW_NAME = "belowname"; - - public const SORT_ORDER_ASCENDING = 0; - public const SORT_ORDER_DESCENDING = 1; - - /** @var string */ - public $displaySlot; - /** @var string */ - public $objectiveName; - /** @var string */ - public $displayName; - /** @var string */ - public $criteriaName; - /** @var int */ - public $sortOrder; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->displaySlot = $in->getString(); - $this->objectiveName = $in->getString(); - $this->displayName = $in->getString(); - $this->criteriaName = $in->getString(); - $this->sortOrder = $in->getVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->displaySlot); - $out->putString($this->objectiveName); - $out->putString($this->displayName); - $out->putString($this->criteriaName); - $out->putVarInt($this->sortOrder); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSetDisplayObjective($this); - } -} diff --git a/src/network/mcpe/protocol/SetHealthPacket.php b/src/network/mcpe/protocol/SetHealthPacket.php deleted file mode 100644 index 87e08b9baa..0000000000 --- a/src/network/mcpe/protocol/SetHealthPacket.php +++ /dev/null @@ -1,47 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class SetHealthPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::SET_HEALTH_PACKET; - - /** @var int */ - public $health; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->health = $in->getVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVarInt($this->health); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSetHealth($this); - } -} diff --git a/src/network/mcpe/protocol/SetLastHurtByPacket.php b/src/network/mcpe/protocol/SetLastHurtByPacket.php deleted file mode 100644 index 6a3fd71119..0000000000 --- a/src/network/mcpe/protocol/SetLastHurtByPacket.php +++ /dev/null @@ -1,47 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class SetLastHurtByPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::SET_LAST_HURT_BY_PACKET; - - /** @var int */ - public $entityTypeId; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityTypeId = $in->getVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVarInt($this->entityTypeId); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSetLastHurtBy($this); - } -} diff --git a/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php b/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php deleted file mode 100644 index 5f9eda5663..0000000000 --- a/src/network/mcpe/protocol/SetLocalPlayerAsInitializedPacket.php +++ /dev/null @@ -1,47 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class SetLocalPlayerAsInitializedPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::SET_LOCAL_PLAYER_AS_INITIALIZED_PACKET; - - /** @var int */ - public $entityRuntimeId; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityRuntimeId = $in->getEntityRuntimeId(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityRuntimeId($this->entityRuntimeId); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSetLocalPlayerAsInitialized($this); - } -} diff --git a/src/network/mcpe/protocol/SetPlayerGameTypePacket.php b/src/network/mcpe/protocol/SetPlayerGameTypePacket.php deleted file mode 100644 index eb337f2a71..0000000000 --- a/src/network/mcpe/protocol/SetPlayerGameTypePacket.php +++ /dev/null @@ -1,53 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class SetPlayerGameTypePacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::SET_PLAYER_GAME_TYPE_PACKET; - - /** @var int */ - public $gamemode; - - public static function create(int $gamemode) : self{ - $pk = new self; - $pk->gamemode = $gamemode; - return $pk; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->gamemode = $in->getVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVarInt($this->gamemode); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSetPlayerGameType($this); - } -} diff --git a/src/network/mcpe/protocol/SetScorePacket.php b/src/network/mcpe/protocol/SetScorePacket.php deleted file mode 100644 index 2d135c938b..0000000000 --- a/src/network/mcpe/protocol/SetScorePacket.php +++ /dev/null @@ -1,95 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\ScorePacketEntry; -use function count; - -class SetScorePacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::SET_SCORE_PACKET; - - public const TYPE_CHANGE = 0; - public const TYPE_REMOVE = 1; - - /** @var int */ - public $type; - /** @var ScorePacketEntry[] */ - public $entries = []; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->type = $in->getByte(); - for($i = 0, $i2 = $in->getUnsignedVarInt(); $i < $i2; ++$i){ - $entry = new ScorePacketEntry(); - $entry->scoreboardId = $in->getVarLong(); - $entry->objectiveName = $in->getString(); - $entry->score = $in->getLInt(); - if($this->type !== self::TYPE_REMOVE){ - $entry->type = $in->getByte(); - switch($entry->type){ - case ScorePacketEntry::TYPE_PLAYER: - case ScorePacketEntry::TYPE_ENTITY: - $entry->entityUniqueId = $in->getEntityUniqueId(); - break; - case ScorePacketEntry::TYPE_FAKE_PLAYER: - $entry->customName = $in->getString(); - break; - default: - throw new PacketDecodeException("Unknown entry type $entry->type"); - } - } - $this->entries[] = $entry; - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->type); - $out->putUnsignedVarInt(count($this->entries)); - foreach($this->entries as $entry){ - $out->putVarLong($entry->scoreboardId); - $out->putString($entry->objectiveName); - $out->putLInt($entry->score); - if($this->type !== self::TYPE_REMOVE){ - $out->putByte($entry->type); - switch($entry->type){ - case ScorePacketEntry::TYPE_PLAYER: - case ScorePacketEntry::TYPE_ENTITY: - $out->putEntityUniqueId($entry->entityUniqueId); - break; - case ScorePacketEntry::TYPE_FAKE_PLAYER: - $out->putString($entry->customName); - break; - default: - throw new \InvalidArgumentException("Unknown entry type $entry->type"); - } - } - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSetScore($this); - } -} diff --git a/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php b/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php deleted file mode 100644 index d48a7e9bec..0000000000 --- a/src/network/mcpe/protocol/SetScoreboardIdentityPacket.php +++ /dev/null @@ -1,70 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\ScoreboardIdentityPacketEntry; -use function count; - -class SetScoreboardIdentityPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::SET_SCOREBOARD_IDENTITY_PACKET; - - public const TYPE_REGISTER_IDENTITY = 0; - public const TYPE_CLEAR_IDENTITY = 1; - - /** @var int */ - public $type; - /** @var ScoreboardIdentityPacketEntry[] */ - public $entries = []; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->type = $in->getByte(); - for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ - $entry = new ScoreboardIdentityPacketEntry(); - $entry->scoreboardId = $in->getVarLong(); - if($this->type === self::TYPE_REGISTER_IDENTITY){ - $entry->entityUniqueId = $in->getEntityUniqueId(); - } - - $this->entries[] = $entry; - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->type); - $out->putUnsignedVarInt(count($this->entries)); - foreach($this->entries as $entry){ - $out->putVarLong($entry->scoreboardId); - if($this->type === self::TYPE_REGISTER_IDENTITY){ - $out->putEntityUniqueId($entry->entityUniqueId); - } - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSetScoreboardIdentity($this); - } -} diff --git a/src/network/mcpe/protocol/SetSpawnPositionPacket.php b/src/network/mcpe/protocol/SetSpawnPositionPacket.php deleted file mode 100644 index a1cffc88fb..0000000000 --- a/src/network/mcpe/protocol/SetSpawnPositionPacket.php +++ /dev/null @@ -1,88 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class SetSpawnPositionPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::SET_SPAWN_POSITION_PACKET; - - public const TYPE_PLAYER_SPAWN = 0; - public const TYPE_WORLD_SPAWN = 1; - - /** @var int */ - public $spawnType; - /** @var int */ - public $x; - /** @var int */ - public $y; - /** @var int */ - public $z; - /** @var int */ - public $dimension; - /** @var int */ - public $x2; - /** @var int */ - public $y2; - /** @var int */ - public $z2; - - public static function playerSpawn(int $x, int $y, int $z, int $dimension, int $x2, int $y2, int $z2) : self{ - $result = new self; - $result->spawnType = self::TYPE_PLAYER_SPAWN; - [$result->x, $result->y, $result->z] = [$x, $y, $z]; - [$result->x2, $result->y2, $result->z2] = [$x2, $y2, $z2]; - $result->dimension = $dimension; - return $result; - } - - public static function worldSpawn(int $x, int $y, int $z, int $dimension) : self{ - $result = new self; - $result->spawnType = self::TYPE_WORLD_SPAWN; - [$result->x, $result->y, $result->z] = [$x, $y, $z]; - [$result->x2, $result->y2, $result->z2] = [$x, $y, $z]; - $result->dimension = $dimension; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->spawnType = $in->getVarInt(); - $in->getBlockPosition($this->x, $this->y, $this->z); - $this->dimension = $in->getVarInt(); - $in->getBlockPosition($this->x2, $this->y2, $this->z2); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVarInt($this->spawnType); - $out->putBlockPosition($this->x, $this->y, $this->z); - $out->putVarInt($this->dimension); - $out->putBlockPosition($this->x2, $this->y2, $this->z2); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSetSpawnPosition($this); - } -} diff --git a/src/network/mcpe/protocol/SetTimePacket.php b/src/network/mcpe/protocol/SetTimePacket.php deleted file mode 100644 index a8e38e03e1..0000000000 --- a/src/network/mcpe/protocol/SetTimePacket.php +++ /dev/null @@ -1,53 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class SetTimePacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::SET_TIME_PACKET; - - /** @var int */ - public $time; - - public static function create(int $time) : self{ - $result = new self; - $result->time = $time & 0xffffffff; //avoid overflowing the field, since the packet uses an int32 - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->time = $in->getVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVarInt($this->time); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSetTime($this); - } -} diff --git a/src/network/mcpe/protocol/SetTitlePacket.php b/src/network/mcpe/protocol/SetTitlePacket.php deleted file mode 100644 index da5e6ced93..0000000000 --- a/src/network/mcpe/protocol/SetTitlePacket.php +++ /dev/null @@ -1,119 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class SetTitlePacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::SET_TITLE_PACKET; - - public const TYPE_CLEAR_TITLE = 0; - public const TYPE_RESET_TITLE = 1; - public const TYPE_SET_TITLE = 2; - public const TYPE_SET_SUBTITLE = 3; - public const TYPE_SET_ACTIONBAR_MESSAGE = 4; - public const TYPE_SET_ANIMATION_TIMES = 5; - public const TYPE_SET_TITLE_JSON = 6; - public const TYPE_SET_SUBTITLE_JSON = 7; - public const TYPE_SET_ACTIONBAR_MESSAGE_JSON = 8; - - /** @var int */ - public $type; - /** @var string */ - public $text = ""; - /** @var int */ - public $fadeInTime = 0; - /** @var int */ - public $stayTime = 0; - /** @var int */ - public $fadeOutTime = 0; - public string $xuid = ""; - public string $platformOnlineId = ""; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->type = $in->getVarInt(); - $this->text = $in->getString(); - $this->fadeInTime = $in->getVarInt(); - $this->stayTime = $in->getVarInt(); - $this->fadeOutTime = $in->getVarInt(); - $this->xuid = $in->getString(); - $this->platformOnlineId = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVarInt($this->type); - $out->putString($this->text); - $out->putVarInt($this->fadeInTime); - $out->putVarInt($this->stayTime); - $out->putVarInt($this->fadeOutTime); - $out->putString($this->xuid); - $out->putString($this->platformOnlineId); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSetTitle($this); - } - - private static function type(int $type) : self{ - $result = new self; - $result->type = $type; - return $result; - } - - private static function text(int $type, string $text) : self{ - $result = self::type($type); - $result->text = $text; - return $result; - } - - public static function title(string $text) : self{ - return self::text(self::TYPE_SET_TITLE, $text); - } - - public static function subtitle(string $text) : self{ - return self::text(self::TYPE_SET_SUBTITLE, $text); - } - - public static function actionBarMessage(string $text) : self{ - return self::text(self::TYPE_SET_ACTIONBAR_MESSAGE, $text); - } - - public static function clearTitle() : self{ - return self::type(self::TYPE_CLEAR_TITLE); - } - - public static function resetTitleOptions() : self{ - return self::type(self::TYPE_RESET_TITLE); - } - - public static function setAnimationTimes(int $fadeIn, int $stay, int $fadeOut) : self{ - $result = self::type(self::TYPE_SET_ANIMATION_TIMES); - $result->fadeInTime = $fadeIn; - $result->stayTime = $stay; - $result->fadeOutTime = $fadeOut; - return $result; - } -} diff --git a/src/network/mcpe/protocol/SettingsCommandPacket.php b/src/network/mcpe/protocol/SettingsCommandPacket.php deleted file mode 100644 index 3bf2d10c6a..0000000000 --- a/src/network/mcpe/protocol/SettingsCommandPacket.php +++ /dev/null @@ -1,66 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class SettingsCommandPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::SETTINGS_COMMAND_PACKET; - - /** @var string */ - private $command; - /** @var bool */ - private $suppressOutput; - - public static function create(string $command, bool $suppressOutput) : self{ - $result = new self; - $result->command = $command; - $result->suppressOutput = $suppressOutput; - return $result; - } - - public function getCommand() : string{ - return $this->command; - } - - public function getSuppressOutput() : bool{ - return $this->suppressOutput; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->command = $in->getString(); - $this->suppressOutput = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->command); - $out->putBool($this->suppressOutput); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSettingsCommand($this); - } -} diff --git a/src/network/mcpe/protocol/ShowCreditsPacket.php b/src/network/mcpe/protocol/ShowCreditsPacket.php deleted file mode 100644 index 22b56ed297..0000000000 --- a/src/network/mcpe/protocol/ShowCreditsPacket.php +++ /dev/null @@ -1,54 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ShowCreditsPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::SHOW_CREDITS_PACKET; - - public const STATUS_START_CREDITS = 0; - public const STATUS_END_CREDITS = 1; - - /** @var int */ - public $playerEid; - /** @var int */ - public $status; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->playerEid = $in->getEntityRuntimeId(); - $this->status = $in->getVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityRuntimeId($this->playerEid); - $out->putVarInt($this->status); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleShowCredits($this); - } -} diff --git a/src/network/mcpe/protocol/ShowProfilePacket.php b/src/network/mcpe/protocol/ShowProfilePacket.php deleted file mode 100644 index 0d3ae01658..0000000000 --- a/src/network/mcpe/protocol/ShowProfilePacket.php +++ /dev/null @@ -1,47 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ShowProfilePacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::SHOW_PROFILE_PACKET; - - /** @var string */ - public $xuid; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->xuid = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->xuid); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleShowProfile($this); - } -} diff --git a/src/network/mcpe/protocol/ShowStoreOfferPacket.php b/src/network/mcpe/protocol/ShowStoreOfferPacket.php deleted file mode 100644 index 5636f3c175..0000000000 --- a/src/network/mcpe/protocol/ShowStoreOfferPacket.php +++ /dev/null @@ -1,51 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class ShowStoreOfferPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::SHOW_STORE_OFFER_PACKET; - - /** @var string */ - public $offerId; - /** @var bool */ - public $showAll; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->offerId = $in->getString(); - $this->showAll = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->offerId); - $out->putBool($this->showAll); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleShowStoreOffer($this); - } -} diff --git a/src/network/mcpe/protocol/SimpleEventPacket.php b/src/network/mcpe/protocol/SimpleEventPacket.php deleted file mode 100644 index 0ae0bfdebf..0000000000 --- a/src/network/mcpe/protocol/SimpleEventPacket.php +++ /dev/null @@ -1,51 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class SimpleEventPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::SIMPLE_EVENT_PACKET; - - public const TYPE_ENABLE_COMMANDS = 1; - public const TYPE_DISABLE_COMMANDS = 2; - public const TYPE_UNLOCK_WORLD_TEMPLATE_SETTINGS = 3; - - /** @var int */ - public $eventType; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->eventType = $in->getLShort(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putLShort($this->eventType); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSimpleEvent($this); - } -} diff --git a/src/network/mcpe/protocol/SimulationTypePacket.php b/src/network/mcpe/protocol/SimulationTypePacket.php deleted file mode 100644 index 28f662b63b..0000000000 --- a/src/network/mcpe/protocol/SimulationTypePacket.php +++ /dev/null @@ -1,58 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class SimulationTypePacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::SIMULATION_TYPE_PACKET; - - public const GAME = 0; - public const EDITOR = 1; - public const TEST = 2; - - private int $type; - - public static function create(int $type) : self{ - $result = new self; - $result->type = $type; - return $result; - } - - public function getType() : int{ return $this->type; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->type = $in->getByte(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->type); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSimulationType($this); - } -} diff --git a/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php b/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php deleted file mode 100644 index 6f1ee186d0..0000000000 --- a/src/network/mcpe/protocol/SpawnExperienceOrbPacket.php +++ /dev/null @@ -1,52 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class SpawnExperienceOrbPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::SPAWN_EXPERIENCE_ORB_PACKET; - - /** @var Vector3 */ - public $position; - /** @var int */ - public $amount; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->position = $in->getVector3(); - $this->amount = $in->getVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVector3($this->position); - $out->putVarInt($this->amount); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSpawnExperienceOrb($this); - } -} diff --git a/src/network/mcpe/protocol/SpawnParticleEffectPacket.php b/src/network/mcpe/protocol/SpawnParticleEffectPacket.php deleted file mode 100644 index 2485608d33..0000000000 --- a/src/network/mcpe/protocol/SpawnParticleEffectPacket.php +++ /dev/null @@ -1,61 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\DimensionIds; - -class SpawnParticleEffectPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::SPAWN_PARTICLE_EFFECT_PACKET; - - /** @var int */ - public $dimensionId = DimensionIds::OVERWORLD; //wtf mojang - /** @var int */ - public $entityUniqueId = -1; //default none - /** @var Vector3 */ - public $position; - /** @var string */ - public $particleName; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->dimensionId = $in->getByte(); - $this->entityUniqueId = $in->getEntityUniqueId(); - $this->position = $in->getVector3(); - $this->particleName = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->dimensionId); - $out->putEntityUniqueId($this->entityUniqueId); - $out->putVector3($this->position); - $out->putString($this->particleName); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSpawnParticleEffect($this); - } -} diff --git a/src/network/mcpe/protocol/StartGamePacket.php b/src/network/mcpe/protocol/StartGamePacket.php deleted file mode 100644 index 2a7ee064f4..0000000000 --- a/src/network/mcpe/protocol/StartGamePacket.php +++ /dev/null @@ -1,348 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\nbt\TreeRoot; -use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\BlockPaletteEntry; -use pocketmine\network\mcpe\protocol\types\EducationEditionOffer; -use pocketmine\network\mcpe\protocol\types\Experiments; -use pocketmine\network\mcpe\protocol\types\GameRule; -use pocketmine\network\mcpe\protocol\types\GeneratorType; -use pocketmine\network\mcpe\protocol\types\ItemTypeEntry; -use pocketmine\network\mcpe\protocol\types\MultiplayerGameVisibility; -use pocketmine\network\mcpe\protocol\types\PlayerMovementSettings; -use pocketmine\network\mcpe\protocol\types\PlayerPermissions; -use pocketmine\network\mcpe\protocol\types\SpawnSettings; -use function count; - -class StartGamePacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::START_GAME_PACKET; - - /** @var int */ - public $entityUniqueId; - /** @var int */ - public $entityRuntimeId; - /** @var int */ - public $playerGamemode; - - /** @var Vector3 */ - public $playerPosition; - - /** @var float */ - public $pitch; - /** @var float */ - public $yaw; - - /** @var int */ - public $seed; - /** @var SpawnSettings */ - public $spawnSettings; - /** @var int */ - public $generator = GeneratorType::OVERWORLD; - /** @var int */ - public $worldGamemode; - /** @var int */ - public $difficulty; - /** @var int */ - public $spawnX; - /** @var int */ - public $spawnY; - /** @var int */ - public $spawnZ; - /** @var bool */ - public $hasAchievementsDisabled = true; - /** @var int */ - public $time = -1; - /** @var int */ - public $eduEditionOffer = EducationEditionOffer::NONE; - /** @var bool */ - public $hasEduFeaturesEnabled = false; - /** @var string */ - public $eduProductUUID = ""; - /** @var float */ - public $rainLevel; - /** @var float */ - public $lightningLevel; - /** @var bool */ - public $hasConfirmedPlatformLockedContent = false; - /** @var bool */ - public $isMultiplayerGame = true; - /** @var bool */ - public $hasLANBroadcast = true; - /** @var int */ - public $xboxLiveBroadcastMode = MultiplayerGameVisibility::PUBLIC; - /** @var int */ - public $platformBroadcastMode = MultiplayerGameVisibility::PUBLIC; - /** @var bool */ - public $commandsEnabled; - /** @var bool */ - public $isTexturePacksRequired = true; - /** - * @var GameRule[] - * @phpstan-var array - */ - public $gameRules = []; - /** @var Experiments */ - public $experiments; - /** @var bool */ - public $hasBonusChestEnabled = false; - /** @var bool */ - public $hasStartWithMapEnabled = false; - /** @var int */ - public $defaultPlayerPermission = PlayerPermissions::MEMBER; //TODO - - /** @var int */ - public $serverChunkTickRadius = 4; //TODO (leave as default for now) - - /** @var bool */ - public $hasLockedBehaviorPack = false; - /** @var bool */ - public $hasLockedResourcePack = false; - /** @var bool */ - public $isFromLockedWorldTemplate = false; - /** @var bool */ - public $useMsaGamertagsOnly = false; - /** @var bool */ - public $isFromWorldTemplate = false; - /** @var bool */ - public $isWorldTemplateOptionLocked = false; - /** @var bool */ - public $onlySpawnV1Villagers = false; - /** @var string */ - public $vanillaVersion = ProtocolInfo::MINECRAFT_VERSION_NETWORK; - /** @var int */ - public $limitedWorldWidth = 0; - /** @var int */ - public $limitedWorldLength = 0; - /** @var bool */ - public $isNewNether = true; - /** @var bool|null */ - public $experimentalGameplayOverride = null; - - /** @var string */ - public $levelId = ""; //base64 string, usually the same as world folder name in vanilla - /** @var string */ - public $worldName; - /** @var string */ - public $premiumWorldTemplateId = ""; - /** @var bool */ - public $isTrial = false; - /** @var PlayerMovementSettings */ - public $playerMovementSettings; - /** @var int */ - public $currentTick = 0; //only used if isTrial is true - /** @var int */ - public $enchantmentSeed = 0; - /** @var string */ - public $multiplayerCorrelationId = ""; //TODO: this should be filled with a UUID of some sort - /** @var bool */ - public $enableNewInventorySystem = false; //TODO - /** @var string */ - public $serverSoftwareVersion; - - /** - * @var BlockPaletteEntry[] - * @phpstan-var list - */ - public $blockPalette = []; - /** - * @var ItemTypeEntry[] - * @phpstan-var list - */ - public $itemTable; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityUniqueId = $in->getEntityUniqueId(); - $this->entityRuntimeId = $in->getEntityRuntimeId(); - $this->playerGamemode = $in->getVarInt(); - - $this->playerPosition = $in->getVector3(); - - $this->pitch = $in->getLFloat(); - $this->yaw = $in->getLFloat(); - - //Level settings - $this->seed = $in->getVarInt(); - $this->spawnSettings = SpawnSettings::read($in); - $this->generator = $in->getVarInt(); - $this->worldGamemode = $in->getVarInt(); - $this->difficulty = $in->getVarInt(); - $in->getBlockPosition($this->spawnX, $this->spawnY, $this->spawnZ); - $this->hasAchievementsDisabled = $in->getBool(); - $this->time = $in->getVarInt(); - $this->eduEditionOffer = $in->getVarInt(); - $this->hasEduFeaturesEnabled = $in->getBool(); - $this->eduProductUUID = $in->getString(); - $this->rainLevel = $in->getLFloat(); - $this->lightningLevel = $in->getLFloat(); - $this->hasConfirmedPlatformLockedContent = $in->getBool(); - $this->isMultiplayerGame = $in->getBool(); - $this->hasLANBroadcast = $in->getBool(); - $this->xboxLiveBroadcastMode = $in->getVarInt(); - $this->platformBroadcastMode = $in->getVarInt(); - $this->commandsEnabled = $in->getBool(); - $this->isTexturePacksRequired = $in->getBool(); - $this->gameRules = $in->getGameRules(); - $this->experiments = Experiments::read($in); - $this->hasBonusChestEnabled = $in->getBool(); - $this->hasStartWithMapEnabled = $in->getBool(); - $this->defaultPlayerPermission = $in->getVarInt(); - $this->serverChunkTickRadius = $in->getLInt(); - $this->hasLockedBehaviorPack = $in->getBool(); - $this->hasLockedResourcePack = $in->getBool(); - $this->isFromLockedWorldTemplate = $in->getBool(); - $this->useMsaGamertagsOnly = $in->getBool(); - $this->isFromWorldTemplate = $in->getBool(); - $this->isWorldTemplateOptionLocked = $in->getBool(); - $this->onlySpawnV1Villagers = $in->getBool(); - $this->vanillaVersion = $in->getString(); - $this->limitedWorldWidth = $in->getLInt(); - $this->limitedWorldLength = $in->getLInt(); - $this->isNewNether = $in->getBool(); - if($in->getBool()){ - $this->experimentalGameplayOverride = $in->getBool(); - }else{ - $this->experimentalGameplayOverride = null; - } - - $this->levelId = $in->getString(); - $this->worldName = $in->getString(); - $this->premiumWorldTemplateId = $in->getString(); - $this->isTrial = $in->getBool(); - $this->playerMovementSettings = PlayerMovementSettings::read($in); - $this->currentTick = $in->getLLong(); - - $this->enchantmentSeed = $in->getVarInt(); - - $this->blockPalette = []; - for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ - $blockName = $in->getString(); - $state = $in->getNbtCompoundRoot(); - $this->blockPalette[] = new BlockPaletteEntry($blockName, $state); - } - - $this->itemTable = []; - for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ - $stringId = $in->getString(); - $numericId = $in->getSignedLShort(); - $isComponentBased = $in->getBool(); - - $this->itemTable[] = new ItemTypeEntry($stringId, $numericId, $isComponentBased); - } - - $this->multiplayerCorrelationId = $in->getString(); - $this->enableNewInventorySystem = $in->getBool(); - $this->serverSoftwareVersion = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityUniqueId($this->entityUniqueId); - $out->putEntityRuntimeId($this->entityRuntimeId); - $out->putVarInt($this->playerGamemode); - - $out->putVector3($this->playerPosition); - - $out->putLFloat($this->pitch); - $out->putLFloat($this->yaw); - - //Level settings - $out->putVarInt($this->seed); - $this->spawnSettings->write($out); - $out->putVarInt($this->generator); - $out->putVarInt($this->worldGamemode); - $out->putVarInt($this->difficulty); - $out->putBlockPosition($this->spawnX, $this->spawnY, $this->spawnZ); - $out->putBool($this->hasAchievementsDisabled); - $out->putVarInt($this->time); - $out->putVarInt($this->eduEditionOffer); - $out->putBool($this->hasEduFeaturesEnabled); - $out->putString($this->eduProductUUID); - $out->putLFloat($this->rainLevel); - $out->putLFloat($this->lightningLevel); - $out->putBool($this->hasConfirmedPlatformLockedContent); - $out->putBool($this->isMultiplayerGame); - $out->putBool($this->hasLANBroadcast); - $out->putVarInt($this->xboxLiveBroadcastMode); - $out->putVarInt($this->platformBroadcastMode); - $out->putBool($this->commandsEnabled); - $out->putBool($this->isTexturePacksRequired); - $out->putGameRules($this->gameRules); - $this->experiments->write($out); - $out->putBool($this->hasBonusChestEnabled); - $out->putBool($this->hasStartWithMapEnabled); - $out->putVarInt($this->defaultPlayerPermission); - $out->putLInt($this->serverChunkTickRadius); - $out->putBool($this->hasLockedBehaviorPack); - $out->putBool($this->hasLockedResourcePack); - $out->putBool($this->isFromLockedWorldTemplate); - $out->putBool($this->useMsaGamertagsOnly); - $out->putBool($this->isFromWorldTemplate); - $out->putBool($this->isWorldTemplateOptionLocked); - $out->putBool($this->onlySpawnV1Villagers); - $out->putString($this->vanillaVersion); - $out->putLInt($this->limitedWorldWidth); - $out->putLInt($this->limitedWorldLength); - $out->putBool($this->isNewNether); - $out->putBool($this->experimentalGameplayOverride !== null); - if($this->experimentalGameplayOverride !== null){ - $out->putBool($this->experimentalGameplayOverride); - } - - $out->putString($this->levelId); - $out->putString($this->worldName); - $out->putString($this->premiumWorldTemplateId); - $out->putBool($this->isTrial); - $this->playerMovementSettings->write($out); - $out->putLLong($this->currentTick); - - $out->putVarInt($this->enchantmentSeed); - - $out->putUnsignedVarInt(count($this->blockPalette)); - $nbtWriter = new NetworkNbtSerializer(); - foreach($this->blockPalette as $entry){ - $out->putString($entry->getName()); - $out->put($nbtWriter->write(new TreeRoot($entry->getStates()))); - } - - $out->putUnsignedVarInt(count($this->itemTable)); - foreach($this->itemTable as $entry){ - $out->putString($entry->getStringId()); - $out->putLShort($entry->getNumericId()); - $out->putBool($entry->isComponentBased()); - } - - $out->putString($this->multiplayerCorrelationId); - $out->putBool($this->enableNewInventorySystem); - $out->putString($this->serverSoftwareVersion); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleStartGame($this); - } -} diff --git a/src/network/mcpe/protocol/StopSoundPacket.php b/src/network/mcpe/protocol/StopSoundPacket.php deleted file mode 100644 index 50f747500e..0000000000 --- a/src/network/mcpe/protocol/StopSoundPacket.php +++ /dev/null @@ -1,51 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class StopSoundPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::STOP_SOUND_PACKET; - - /** @var string */ - public $soundName; - /** @var bool */ - public $stopAll; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->soundName = $in->getString(); - $this->stopAll = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->soundName); - $out->putBool($this->stopAll); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleStopSound($this); - } -} diff --git a/src/network/mcpe/protocol/StructureBlockUpdatePacket.php b/src/network/mcpe/protocol/StructureBlockUpdatePacket.php deleted file mode 100644 index 4ec92a45c1..0000000000 --- a/src/network/mcpe/protocol/StructureBlockUpdatePacket.php +++ /dev/null @@ -1,60 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\StructureEditorData; - -class StructureBlockUpdatePacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::STRUCTURE_BLOCK_UPDATE_PACKET; - - /** @var int */ - public $x; - /** @var int */ - public $y; - /** @var int */ - public $z; - /** @var StructureEditorData */ - public $structureEditorData; - /** @var bool */ - public $isPowered; - - protected function decodePayload(PacketSerializer $in) : void{ - $in->getBlockPosition($this->x, $this->y, $this->z); - $this->structureEditorData = $in->getStructureEditorData(); - $this->isPowered = $in->getBool(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putBlockPosition($this->x, $this->y, $this->z); - $out->putStructureEditorData($this->structureEditorData); - $out->putBool($this->isPowered); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleStructureBlockUpdate($this); - } -} diff --git a/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php b/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php deleted file mode 100644 index 376e300b3a..0000000000 --- a/src/network/mcpe/protocol/StructureTemplateDataRequestPacket.php +++ /dev/null @@ -1,67 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\StructureSettings; - -class StructureTemplateDataRequestPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::STRUCTURE_TEMPLATE_DATA_REQUEST_PACKET; - - public const TYPE_ALWAYS_LOAD = 1; - public const TYPE_CREATE_AND_LOAD = 2; - - /** @var string */ - public $structureTemplateName; - /** @var int */ - public $structureBlockX; - /** @var int */ - public $structureBlockY; - /** @var int */ - public $structureBlockZ; - /** @var StructureSettings */ - public $structureSettings; - /** @var int */ - public $structureTemplateResponseType; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->structureTemplateName = $in->getString(); - $in->getBlockPosition($this->structureBlockX, $this->structureBlockY, $this->structureBlockZ); - $this->structureSettings = $in->getStructureSettings(); - $this->structureTemplateResponseType = $in->getByte(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->structureTemplateName); - $out->putBlockPosition($this->structureBlockX, $this->structureBlockY, $this->structureBlockZ); - $out->putStructureSettings($this->structureSettings); - $out->putByte($this->structureTemplateResponseType); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleStructureTemplateDataRequest($this); - } -} diff --git a/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php b/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php deleted file mode 100644 index ad3e080511..0000000000 --- a/src/network/mcpe/protocol/StructureTemplateDataResponsePacket.php +++ /dev/null @@ -1,60 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\CacheableNbt; - -class StructureTemplateDataResponsePacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::STRUCTURE_TEMPLATE_DATA_RESPONSE_PACKET; - - /** @var string */ - public $structureTemplateName; - /** - * @var CacheableNbt|null - * @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag> - */ - public $namedtag; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->structureTemplateName = $in->getString(); - if($in->getBool()){ - $this->namedtag = new CacheableNbt($in->getNbtCompoundRoot()); - } - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->structureTemplateName); - $out->putBool($this->namedtag !== null); - if($this->namedtag !== null){ - $out->put($this->namedtag->getEncodedNbt()); - } - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleStructureTemplateDataResponse($this); - } -} diff --git a/src/network/mcpe/protocol/SubClientLoginPacket.php b/src/network/mcpe/protocol/SubClientLoginPacket.php deleted file mode 100644 index f2685891bf..0000000000 --- a/src/network/mcpe/protocol/SubClientLoginPacket.php +++ /dev/null @@ -1,47 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class SubClientLoginPacket extends DataPacket implements ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::SUB_CLIENT_LOGIN_PACKET; - - /** @var string */ - public $connectionRequestData; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->connectionRequestData = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->connectionRequestData); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSubClientLogin($this); - } -} diff --git a/src/network/mcpe/protocol/SyncActorPropertyPacket.php b/src/network/mcpe/protocol/SyncActorPropertyPacket.php deleted file mode 100644 index de547f4e94..0000000000 --- a/src/network/mcpe/protocol/SyncActorPropertyPacket.php +++ /dev/null @@ -1,58 +0,0 @@ - - -use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\TreeRoot; -use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class SyncActorPropertyPacket extends DataPacket{ - public const NETWORK_ID = ProtocolInfo::SYNC_ACTOR_PROPERTY_PACKET; - - /** @var CompoundTag */ - private $data; - - public static function create(CompoundTag $data) : self{ - $result = new self; - $result->data = $data; - return $result; - } - - public function getData() : CompoundTag{ return $this->data; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->data = $in->getNbtCompoundRoot(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->put((new NetworkNbtSerializer())->write(new TreeRoot($this->data))); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleSyncActorProperty($this); - } -} diff --git a/src/network/mcpe/protocol/TakeItemActorPacket.php b/src/network/mcpe/protocol/TakeItemActorPacket.php deleted file mode 100644 index 74331a615c..0000000000 --- a/src/network/mcpe/protocol/TakeItemActorPacket.php +++ /dev/null @@ -1,58 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class TakeItemActorPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::TAKE_ITEM_ACTOR_PACKET; - - /** @var int */ - public $target; - /** @var int */ - public $eid; - - public static function create(int $takerEntityRuntimeId, int $itemEntityRuntimeId) : self{ - $result = new self; - $result->target = $itemEntityRuntimeId; - $result->eid = $takerEntityRuntimeId; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->target = $in->getEntityRuntimeId(); - $this->eid = $in->getEntityRuntimeId(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityRuntimeId($this->target); - $out->putEntityRuntimeId($this->eid); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleTakeItemActor($this); - } -} diff --git a/src/network/mcpe/protocol/TextPacket.php b/src/network/mcpe/protocol/TextPacket.php deleted file mode 100644 index 1928e40ca2..0000000000 --- a/src/network/mcpe/protocol/TextPacket.php +++ /dev/null @@ -1,186 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use function count; - -class TextPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::TEXT_PACKET; - - public const TYPE_RAW = 0; - public const TYPE_CHAT = 1; - public const TYPE_TRANSLATION = 2; - public const TYPE_POPUP = 3; - public const TYPE_JUKEBOX_POPUP = 4; - public const TYPE_TIP = 5; - public const TYPE_SYSTEM = 6; - public const TYPE_WHISPER = 7; - public const TYPE_ANNOUNCEMENT = 8; - public const TYPE_JSON_WHISPER = 9; - public const TYPE_JSON = 10; - - /** @var int */ - public $type; - /** @var bool */ - public $needsTranslation = false; - /** @var string */ - public $sourceName; - /** @var string */ - public $message; - /** @var string[] */ - public $parameters = []; - /** @var string */ - public $xboxUserId = ""; - /** @var string */ - public $platformChatId = ""; - - private static function messageOnly(int $type, string $message) : self{ - $result = new self; - $result->type = $type; - $result->message = $message; - return $result; - } - - /** - * @param string[] $parameters - */ - private static function baseTranslation(int $type, string $key, array $parameters) : self{ - $result = new self; - $result->type = $type; - $result->needsTranslation = true; - $result->message = $key; - $result->parameters = $parameters; - return $result; - } - - public static function raw(string $message) : self{ - return self::messageOnly(self::TYPE_RAW, $message); - } - - /** - * @param string[] $parameters - * - * @return TextPacket - */ - public static function translation(string $key, array $parameters = []) : self{ - return self::baseTranslation(self::TYPE_TRANSLATION, $key, $parameters); - } - - public static function popup(string $message) : self{ - return self::messageOnly(self::TYPE_POPUP, $message); - } - - /** - * @param string[] $parameters - * - * @return TextPacket - */ - public static function translatedPopup(string $key, array $parameters = []) : self{ - return self::baseTranslation(self::TYPE_POPUP, $key, $parameters); - } - - /** - * @param string[] $parameters - * - * @return TextPacket - */ - public static function jukeboxPopup(string $key, array $parameters = []) : self{ - return self::baseTranslation(self::TYPE_JUKEBOX_POPUP, $key, $parameters); - } - - public static function tip(string $message) : self{ - return self::messageOnly(self::TYPE_TIP, $message); - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->type = $in->getByte(); - $this->needsTranslation = $in->getBool(); - switch($this->type){ - case self::TYPE_CHAT: - case self::TYPE_WHISPER: - /** @noinspection PhpMissingBreakStatementInspection */ - case self::TYPE_ANNOUNCEMENT: - $this->sourceName = $in->getString(); - case self::TYPE_RAW: - case self::TYPE_TIP: - case self::TYPE_SYSTEM: - case self::TYPE_JSON_WHISPER: - case self::TYPE_JSON: - $this->message = $in->getString(); - break; - - case self::TYPE_TRANSLATION: - case self::TYPE_POPUP: - case self::TYPE_JUKEBOX_POPUP: - $this->message = $in->getString(); - $count = $in->getUnsignedVarInt(); - for($i = 0; $i < $count; ++$i){ - $this->parameters[] = $in->getString(); - } - break; - } - - $this->xboxUserId = $in->getString(); - $this->platformChatId = $in->getString(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->type); - $out->putBool($this->needsTranslation); - switch($this->type){ - case self::TYPE_CHAT: - case self::TYPE_WHISPER: - /** @noinspection PhpMissingBreakStatementInspection */ - case self::TYPE_ANNOUNCEMENT: - $out->putString($this->sourceName); - case self::TYPE_RAW: - case self::TYPE_TIP: - case self::TYPE_SYSTEM: - case self::TYPE_JSON_WHISPER: - case self::TYPE_JSON: - $out->putString($this->message); - break; - - case self::TYPE_TRANSLATION: - case self::TYPE_POPUP: - case self::TYPE_JUKEBOX_POPUP: - $out->putString($this->message); - $out->putUnsignedVarInt(count($this->parameters)); - foreach($this->parameters as $p){ - $out->putString($p); - } - break; - } - - $out->putString($this->xboxUserId); - $out->putString($this->platformChatId); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleText($this); - } -} diff --git a/src/network/mcpe/protocol/TickSyncPacket.php b/src/network/mcpe/protocol/TickSyncPacket.php deleted file mode 100644 index 134ca40aff..0000000000 --- a/src/network/mcpe/protocol/TickSyncPacket.php +++ /dev/null @@ -1,73 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class TickSyncPacket extends DataPacket implements ClientboundPacket, ServerboundPacket{ - public const NETWORK_ID = ProtocolInfo::TICK_SYNC_PACKET; - - /** @var int */ - private $clientSendTime; - /** @var int */ - private $serverReceiveTime; - - public static function request(int $clientTime) : self{ - $result = new self; - $result->clientSendTime = $clientTime; - $result->serverReceiveTime = 0; //useless - return $result; - } - - public static function response(int $clientSendTime, int $serverReceiveTime) : self{ - $result = new self; - $result->clientSendTime = $clientSendTime; - $result->serverReceiveTime = $serverReceiveTime; - return $result; - } - - public function getClientSendTime() : int{ - return $this->clientSendTime; - } - - public function getServerReceiveTime() : int{ - return $this->serverReceiveTime; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->clientSendTime = $in->getLLong(); - $this->serverReceiveTime = $in->getLLong(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putLLong($this->clientSendTime); - $out->putLLong($this->serverReceiveTime); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleTickSync($this); - } -} diff --git a/src/network/mcpe/protocol/TransferPacket.php b/src/network/mcpe/protocol/TransferPacket.php deleted file mode 100644 index 8b25ef64eb..0000000000 --- a/src/network/mcpe/protocol/TransferPacket.php +++ /dev/null @@ -1,58 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class TransferPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::TRANSFER_PACKET; - - /** @var string */ - public $address; - /** @var int */ - public $port = 19132; - - public static function create(string $address, int $port) : self{ - $result = new self; - $result->address = $address; - $result->port = $port; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->address = $in->getString(); - $this->port = $in->getLShort(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->address); - $out->putLShort($this->port); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleTransfer($this); - } -} diff --git a/src/network/mcpe/protocol/UnknownPacket.php b/src/network/mcpe/protocol/UnknownPacket.php deleted file mode 100644 index feecedea20..0000000000 --- a/src/network/mcpe/protocol/UnknownPacket.php +++ /dev/null @@ -1,66 +0,0 @@ -payload ?? "") > 0){ - return ord($this->payload[0]); - } - return self::NETWORK_ID; - } - - public function getName() : string{ - return "unknown packet"; - } - - protected function decodeHeader(PacketSerializer $in) : void{ - - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->payload = $in->getRemaining(); - } - - protected function encodeHeader(PacketSerializer $out) : void{ - - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->put($this->payload); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return false; - } -} diff --git a/src/network/mcpe/protocol/UpdateAttributesPacket.php b/src/network/mcpe/protocol/UpdateAttributesPacket.php deleted file mode 100644 index 2867f772a6..0000000000 --- a/src/network/mcpe/protocol/UpdateAttributesPacket.php +++ /dev/null @@ -1,70 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\entity\Attribute; -use function array_values; - -class UpdateAttributesPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::UPDATE_ATTRIBUTES_PACKET; - - /** @var int */ - public $entityRuntimeId; - /** @var Attribute[] */ - public $entries = []; - /** @var int */ - public $tick = 0; - - /** - * @param Attribute[] $attributes - * - * @return UpdateAttributesPacket - */ - public static function create(int $entityRuntimeId, array $attributes, int $tick) : self{ - $result = new self; - $result->entityRuntimeId = $entityRuntimeId; - $result->entries = $attributes; - $result->tick = $tick; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->entityRuntimeId = $in->getEntityRuntimeId(); - $this->entries = $in->getAttributeList(); - $this->tick = $in->getUnsignedVarLong(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putEntityRuntimeId($this->entityRuntimeId); - $out->putAttributeList(...array_values($this->entries)); - $out->putUnsignedVarLong($this->tick); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleUpdateAttributes($this); - } -} diff --git a/src/network/mcpe/protocol/UpdateBlockPacket.php b/src/network/mcpe/protocol/UpdateBlockPacket.php deleted file mode 100644 index a4ea6faffa..0000000000 --- a/src/network/mcpe/protocol/UpdateBlockPacket.php +++ /dev/null @@ -1,78 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class UpdateBlockPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::UPDATE_BLOCK_PACKET; - - public const DATA_LAYER_NORMAL = 0; - public const DATA_LAYER_LIQUID = 1; - - /** @var int */ - public $x; - /** @var int */ - public $z; - /** @var int */ - public $y; - /** @var int */ - public $blockRuntimeId; - /** - * @var int - * Flags are used by MCPE internally for block setting, but only flag 2 (network flag) is relevant for network. - * This field is pointless really. - */ - public $flags = 0x02; - /** @var int */ - public $dataLayerId = self::DATA_LAYER_NORMAL; - - public static function create(int $x, int $y, int $z, int $blockRuntimeId, int $dataLayerId = self::DATA_LAYER_NORMAL) : self{ - $result = new self; - [$result->x, $result->y, $result->z] = [$x, $y, $z]; - $result->blockRuntimeId = $blockRuntimeId; - $result->dataLayerId = $dataLayerId; - return $result; - } - - protected function decodePayload(PacketSerializer $in) : void{ - $in->getBlockPosition($this->x, $this->y, $this->z); - $this->blockRuntimeId = $in->getUnsignedVarInt(); - $this->flags = $in->getUnsignedVarInt(); - $this->dataLayerId = $in->getUnsignedVarInt(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putBlockPosition($this->x, $this->y, $this->z); - $out->putUnsignedVarInt($this->blockRuntimeId); - $out->putUnsignedVarInt($this->flags); - $out->putUnsignedVarInt($this->dataLayerId); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleUpdateBlock($this); - } -} diff --git a/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php b/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php deleted file mode 100644 index 373365b917..0000000000 --- a/src/network/mcpe/protocol/UpdateBlockSyncedPacket.php +++ /dev/null @@ -1,57 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; - -class UpdateBlockSyncedPacket extends UpdateBlockPacket{ - public const NETWORK_ID = ProtocolInfo::UPDATE_BLOCK_SYNCED_PACKET; - - public const TYPE_NONE = 0; - public const TYPE_CREATE = 1; - public const TYPE_DESTROY = 2; - - /** @var int */ - public $entityUniqueId; - /** @var int */ - public $updateType; - - protected function decodePayload(PacketSerializer $in) : void{ - parent::decodePayload($in); - $this->entityUniqueId = $in->getUnsignedVarLong(); - $this->updateType = $in->getUnsignedVarLong(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - parent::encodePayload($out); - $out->putUnsignedVarLong($this->entityUniqueId); - $out->putUnsignedVarLong($this->updateType); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleUpdateBlockSynced($this); - } -} diff --git a/src/network/mcpe/protocol/UpdateEquipPacket.php b/src/network/mcpe/protocol/UpdateEquipPacket.php deleted file mode 100644 index 45051919c6..0000000000 --- a/src/network/mcpe/protocol/UpdateEquipPacket.php +++ /dev/null @@ -1,67 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\CacheableNbt; - -class UpdateEquipPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::UPDATE_EQUIP_PACKET; - - /** @var int */ - public $windowId; - /** @var int */ - public $windowType; - /** @var int */ - public $windowSlotCount; //useless, seems to be part of a standard container header - /** @var int */ - public $entityUniqueId; - /** - * @var CacheableNbt - * @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag> - */ - public $namedtag; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->windowId = $in->getByte(); - $this->windowType = $in->getByte(); - $this->windowSlotCount = $in->getVarInt(); - $this->entityUniqueId = $in->getEntityUniqueId(); - $this->namedtag = new CacheableNbt($in->getNbtCompoundRoot()); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->windowId); - $out->putByte($this->windowType); - $out->putVarInt($this->windowSlotCount); - $out->putEntityUniqueId($this->entityUniqueId); - $out->put($this->namedtag->getEncodedNbt()); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleUpdateEquip($this); - } -} diff --git a/src/network/mcpe/protocol/UpdatePlayerGameTypePacket.php b/src/network/mcpe/protocol/UpdatePlayerGameTypePacket.php deleted file mode 100644 index a190de79fc..0000000000 --- a/src/network/mcpe/protocol/UpdatePlayerGameTypePacket.php +++ /dev/null @@ -1,67 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\GameMode; - -class UpdatePlayerGameTypePacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::UPDATE_PLAYER_GAME_TYPE_PACKET; - - /** - * @var int - * @see GameMode - */ - private $gameMode; - - /** @var int */ - private $playerEntityUniqueId; - - public static function create(int $gameMode, int $playerEntityUniqueId) : self{ - $result = new self; - $result->gameMode = $gameMode; - $result->playerEntityUniqueId = $playerEntityUniqueId; - return $result; - } - - public function getGameMode() : int{ return $this->gameMode; } - - public function getPlayerEntityUniqueId() : int{ return $this->playerEntityUniqueId; } - - protected function decodePayload(PacketSerializer $in) : void{ - $this->gameMode = $in->getVarInt(); - $this->playerEntityUniqueId = $in->getEntityUniqueId(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putVarInt($this->gameMode); - $out->putEntityUniqueId($this->playerEntityUniqueId); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleUpdatePlayerGameType($this); - } -} diff --git a/src/network/mcpe/protocol/UpdateSoftEnumPacket.php b/src/network/mcpe/protocol/UpdateSoftEnumPacket.php deleted file mode 100644 index 7ec0e4d745..0000000000 --- a/src/network/mcpe/protocol/UpdateSoftEnumPacket.php +++ /dev/null @@ -1,65 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use function count; - -class UpdateSoftEnumPacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::UPDATE_SOFT_ENUM_PACKET; - - public const TYPE_ADD = 0; - public const TYPE_REMOVE = 1; - public const TYPE_SET = 2; - - /** @var string */ - public $enumName; - /** @var string[] */ - public $values = []; - /** @var int */ - public $type; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->enumName = $in->getString(); - for($i = 0, $count = $in->getUnsignedVarInt(); $i < $count; ++$i){ - $this->values[] = $in->getString(); - } - $this->type = $in->getByte(); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putString($this->enumName); - $out->putUnsignedVarInt(count($this->values)); - foreach($this->values as $v){ - $out->putString($v); - } - $out->putByte($this->type); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleUpdateSoftEnum($this); - } -} diff --git a/src/network/mcpe/protocol/UpdateTradePacket.php b/src/network/mcpe/protocol/UpdateTradePacket.php deleted file mode 100644 index ef70485b0c..0000000000 --- a/src/network/mcpe/protocol/UpdateTradePacket.php +++ /dev/null @@ -1,90 +0,0 @@ - - -use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; -use pocketmine\network\mcpe\protocol\types\CacheableNbt; -use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes; - -class UpdateTradePacket extends DataPacket implements ClientboundPacket{ - public const NETWORK_ID = ProtocolInfo::UPDATE_TRADE_PACKET; - - //TODO: find fields - - /** @var int */ - public $windowId; - /** @var int */ - public $windowType = WindowTypes::TRADING; //Mojang hardcoded this -_- - /** @var int */ - public $windowSlotCount = 0; //useless, seems to be part of a standard container header - /** @var int */ - public $tradeTier; - /** @var int */ - public $traderEid; - /** @var int */ - public $playerEid; - /** @var string */ - public $displayName; - /** @var bool */ - public $isV2Trading; - /** @var bool */ - public $isWilling; - /** - * @var CacheableNbt - * @phpstan-var CacheableNbt<\pocketmine\nbt\tag\CompoundTag> - */ - public $offers; - - protected function decodePayload(PacketSerializer $in) : void{ - $this->windowId = $in->getByte(); - $this->windowType = $in->getByte(); - $this->windowSlotCount = $in->getVarInt(); - $this->tradeTier = $in->getVarInt(); - $this->traderEid = $in->getEntityUniqueId(); - $this->playerEid = $in->getEntityUniqueId(); - $this->displayName = $in->getString(); - $this->isV2Trading = $in->getBool(); - $this->isWilling = $in->getBool(); - $this->offers = new CacheableNbt($in->getNbtCompoundRoot()); - } - - protected function encodePayload(PacketSerializer $out) : void{ - $out->putByte($this->windowId); - $out->putByte($this->windowType); - $out->putVarInt($this->windowSlotCount); - $out->putVarInt($this->tradeTier); - $out->putEntityUniqueId($this->traderEid); - $out->putEntityUniqueId($this->playerEid); - $out->putString($this->displayName); - $out->putBool($this->isV2Trading); - $out->putBool($this->isWilling); - $out->put($this->offers->getEncodedNbt()); - } - - public function handle(PacketHandlerInterface $handler) : bool{ - return $handler->handleUpdateTrade($this); - } -} diff --git a/src/network/mcpe/protocol/serializer/ItemTypeDictionary.php b/src/network/mcpe/protocol/serializer/ItemTypeDictionary.php deleted file mode 100644 index bdb166589b..0000000000 --- a/src/network/mcpe/protocol/serializer/ItemTypeDictionary.php +++ /dev/null @@ -1,79 +0,0 @@ - - */ - private array $itemTypes; - /** - * @var string[] - * @phpstan-var array - */ - private array $intToStringIdMap = []; - /** - * @var int[] - * @phpstan-var array - */ - private array $stringToIntMap = []; - - /** - * @param ItemTypeEntry[] $itemTypes - */ - public function __construct(array $itemTypes){ - $this->itemTypes = $itemTypes; - foreach($this->itemTypes as $type){ - $this->stringToIntMap[$type->getStringId()] = $type->getNumericId(); - $this->intToStringIdMap[$type->getNumericId()] = $type->getStringId(); - } - } - - /** - * @return ItemTypeEntry[] - * @phpstan-return list - */ - public function getEntries() : array{ - return $this->itemTypes; - } - - public function fromStringId(string $stringId) : int{ - if(!array_key_exists($stringId, $this->stringToIntMap)){ - throw new \InvalidArgumentException("Unmapped string ID \"$stringId\""); - } - return $this->stringToIntMap[$stringId]; - } - - public function fromIntId(int $intId) : string{ - if(!array_key_exists($intId, $this->intToStringIdMap)){ - throw new \InvalidArgumentException("Unmapped int ID $intId"); - } - return $this->intToStringIdMap[$intId]; - } -} diff --git a/src/network/mcpe/protocol/serializer/NetworkNbtSerializer.php b/src/network/mcpe/protocol/serializer/NetworkNbtSerializer.php deleted file mode 100644 index e3949444fc..0000000000 --- a/src/network/mcpe/protocol/serializer/NetworkNbtSerializer.php +++ /dev/null @@ -1,101 +0,0 @@ -buffer->getLShort(); - } - - public function readSignedShort() : int{ - return $this->buffer->getSignedLShort(); - } - - public function writeShort(int $v) : void{ - $this->buffer->putLShort($v); - } - - public function readInt() : int{ - return $this->buffer->getVarInt(); - } - - public function writeInt(int $v) : void{ - $this->buffer->putVarInt($v); - } - - public function readLong() : int{ - return $this->buffer->getVarLong(); - } - - public function writeLong(int $v) : void{ - $this->buffer->putVarLong($v); - } - - public function readString() : string{ - return $this->buffer->get(self::checkReadStringLength($this->buffer->getUnsignedVarInt())); - } - - public function writeString(string $v) : void{ - $this->buffer->putUnsignedVarInt(self::checkWriteStringLength(strlen($v))); - $this->buffer->put($v); - } - - public function readFloat() : float{ - return $this->buffer->getLFloat(); - } - - public function writeFloat(float $v) : void{ - $this->buffer->putLFloat($v); - } - - public function readDouble() : float{ - return $this->buffer->getLDouble(); - } - - public function writeDouble(float $v) : void{ - $this->buffer->putLDouble($v); - } - - public function readIntArray() : array{ - $len = $this->readInt(); //varint - $ret = []; - for($i = 0; $i < $len; ++$i){ - $ret[] = $this->readInt(); //varint - } - - return $ret; - } - - public function writeIntArray(array $array) : void{ - $this->writeInt(count($array)); //varint - foreach($array as $v){ - $this->writeInt($v); //varint - } - } -} diff --git a/src/network/mcpe/protocol/serializer/PacketBatch.php b/src/network/mcpe/protocol/serializer/PacketBatch.php deleted file mode 100644 index a1af98c35a..0000000000 --- a/src/network/mcpe/protocol/serializer/PacketBatch.php +++ /dev/null @@ -1,80 +0,0 @@ -buffer = $buffer; - } - - /** - * @return \Generator|Packet[] - * @phpstan-return \Generator - * @throws PacketDecodeException - */ - public function getPackets(PacketPool $packetPool, PacketSerializerContext $decoderContext, int $max) : \Generator{ - $serializer = PacketSerializer::decoder($this->buffer, 0, $decoderContext); - for($c = 0; $c < $max and !$serializer->feof(); ++$c){ - try{ - $buffer = $serializer->getString(); - yield $c => [$packetPool->getPacket($buffer), $buffer]; - }catch(BinaryDataException $e){ - throw new PacketDecodeException("Error decoding packet $c of batch: " . $e->getMessage(), 0, $e); - } - } - if(!$serializer->feof()){ - throw new PacketDecodeException("Reached limit of $max packets in a single batch"); - } - } - - /** - * Constructs a packet batch from the given list of packets. - * - * @param Packet ...$packets - * - * @return PacketBatch - */ - public static function fromPackets(PacketSerializerContext $context, Packet ...$packets) : self{ - $serializer = PacketSerializer::encoder($context); - foreach($packets as $packet){ - $subSerializer = PacketSerializer::encoder($context); - $packet->encode($subSerializer); - $serializer->putString($subSerializer->getBuffer()); - } - return new self($serializer->getBuffer()); - } - - public function getBuffer() : string{ - return $this->buffer; - } -} diff --git a/src/network/mcpe/protocol/serializer/PacketSerializer.php b/src/network/mcpe/protocol/serializer/PacketSerializer.php deleted file mode 100644 index 9df467f1c6..0000000000 --- a/src/network/mcpe/protocol/serializer/PacketSerializer.php +++ /dev/null @@ -1,795 +0,0 @@ - - -use pocketmine\math\Vector3; -use pocketmine\nbt\LittleEndianNbtSerializer; -use pocketmine\nbt\NbtDataException; -use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\TreeRoot; -use pocketmine\network\mcpe\protocol\PacketDecodeException; -use pocketmine\network\mcpe\protocol\types\BoolGameRule; -use pocketmine\network\mcpe\protocol\types\command\CommandOriginData; -use pocketmine\network\mcpe\protocol\types\entity\Attribute; -use pocketmine\network\mcpe\protocol\types\entity\BlockPosMetadataProperty; -use pocketmine\network\mcpe\protocol\types\entity\ByteMetadataProperty; -use pocketmine\network\mcpe\protocol\types\entity\CompoundTagMetadataProperty; -use pocketmine\network\mcpe\protocol\types\entity\EntityLink; -use pocketmine\network\mcpe\protocol\types\entity\FloatMetadataProperty; -use pocketmine\network\mcpe\protocol\types\entity\IntMetadataProperty; -use pocketmine\network\mcpe\protocol\types\entity\LongMetadataProperty; -use pocketmine\network\mcpe\protocol\types\entity\MetadataProperty; -use pocketmine\network\mcpe\protocol\types\entity\ShortMetadataProperty; -use pocketmine\network\mcpe\protocol\types\entity\StringMetadataProperty; -use pocketmine\network\mcpe\protocol\types\entity\Vec3MetadataProperty; -use pocketmine\network\mcpe\protocol\types\FloatGameRule; -use pocketmine\network\mcpe\protocol\types\GameRule; -use pocketmine\network\mcpe\protocol\types\GameRuleType; -use pocketmine\network\mcpe\protocol\types\IntGameRule; -use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; -use pocketmine\network\mcpe\protocol\types\recipe\RecipeIngredient; -use pocketmine\network\mcpe\protocol\types\skin\PersonaPieceTintColor; -use pocketmine\network\mcpe\protocol\types\skin\PersonaSkinPiece; -use pocketmine\network\mcpe\protocol\types\skin\SkinAnimation; -use pocketmine\network\mcpe\protocol\types\skin\SkinData; -use pocketmine\network\mcpe\protocol\types\skin\SkinImage; -use pocketmine\network\mcpe\protocol\types\StructureEditorData; -use pocketmine\network\mcpe\protocol\types\StructureSettings; -use pocketmine\utils\BinaryDataException; -use pocketmine\utils\BinaryStream; -use Ramsey\Uuid\Uuid; -use Ramsey\Uuid\UuidInterface; -use function count; -use function strlen; -use function strrev; -use function substr; - -class PacketSerializer extends BinaryStream{ - - private int $shieldItemRuntimeId; - private PacketSerializerContext $context; - - protected function __construct(PacketSerializerContext $context, string $buffer = "", int $offset = 0){ - parent::__construct($buffer, $offset); - $this->context = $context; - $this->shieldItemRuntimeId = $context->getItemDictionary()->fromStringId("minecraft:shield"); - } - - public static function encoder(PacketSerializerContext $context) : self{ - return new self($context); - } - - public static function decoder(string $buffer, int $offset, PacketSerializerContext $context) : self{ - return new self($context, $buffer, $offset); - } - - /** - * @throws BinaryDataException - */ - public function getString() : string{ - return $this->get($this->getUnsignedVarInt()); - } - - public function putString(string $v) : void{ - $this->putUnsignedVarInt(strlen($v)); - $this->put($v); - } - - /** - * @throws BinaryDataException - */ - public function getUUID() : UuidInterface{ - //This is two little-endian longs: bytes 7-0 followed by bytes 15-8 - $p1 = strrev($this->get(8)); - $p2 = strrev($this->get(8)); - return Uuid::fromBytes($p1 . $p2); - } - - public function putUUID(UuidInterface $uuid) : void{ - $bytes = $uuid->getBytes(); - $this->put(strrev(substr($bytes, 0, 8))); - $this->put(strrev(substr($bytes, 8, 8))); - } - - public function getSkin() : SkinData{ - $skinId = $this->getString(); - $skinPlayFabId = $this->getString(); - $skinResourcePatch = $this->getString(); - $skinData = $this->getSkinImage(); - $animationCount = $this->getLInt(); - $animations = []; - for($i = 0; $i < $animationCount; ++$i){ - $skinImage = $this->getSkinImage(); - $animationType = $this->getLInt(); - $animationFrames = $this->getLFloat(); - $expressionType = $this->getLInt(); - $animations[] = new SkinAnimation($skinImage, $animationType, $animationFrames, $expressionType); - } - $capeData = $this->getSkinImage(); - $geometryData = $this->getString(); - $animationData = $this->getString(); - $premium = $this->getBool(); - $persona = $this->getBool(); - $capeOnClassic = $this->getBool(); - $capeId = $this->getString(); - $fullSkinId = $this->getString(); - $armSize = $this->getString(); - $skinColor = $this->getString(); - $personaPieceCount = $this->getLInt(); - $personaPieces = []; - for($i = 0; $i < $personaPieceCount; ++$i){ - $pieceId = $this->getString(); - $pieceType = $this->getString(); - $packId = $this->getString(); - $isDefaultPiece = $this->getBool(); - $productId = $this->getString(); - $personaPieces[] = new PersonaSkinPiece($pieceId, $pieceType, $packId, $isDefaultPiece, $productId); - } - $pieceTintColorCount = $this->getLInt(); - $pieceTintColors = []; - for($i = 0; $i < $pieceTintColorCount; ++$i){ - $pieceType = $this->getString(); - $colorCount = $this->getLInt(); - $colors = []; - for($j = 0; $j < $colorCount; ++$j){ - $colors[] = $this->getString(); - } - $pieceTintColors[] = new PersonaPieceTintColor( - $pieceType, - $colors - ); - } - - return new SkinData($skinId, $skinPlayFabId, $skinResourcePatch, $skinData, $animations, $capeData, $geometryData, $animationData, $premium, $persona, $capeOnClassic, $capeId, $fullSkinId, $armSize, $skinColor, $personaPieces, $pieceTintColors); - } - - public function putSkin(SkinData $skin) : void{ - $this->putString($skin->getSkinId()); - $this->putString($skin->getPlayFabId()); - $this->putString($skin->getResourcePatch()); - $this->putSkinImage($skin->getSkinImage()); - $this->putLInt(count($skin->getAnimations())); - foreach($skin->getAnimations() as $animation){ - $this->putSkinImage($animation->getImage()); - $this->putLInt($animation->getType()); - $this->putLFloat($animation->getFrames()); - $this->putLInt($animation->getExpressionType()); - } - $this->putSkinImage($skin->getCapeImage()); - $this->putString($skin->getGeometryData()); - $this->putString($skin->getAnimationData()); - $this->putBool($skin->isPremium()); - $this->putBool($skin->isPersona()); - $this->putBool($skin->isPersonaCapeOnClassic()); - $this->putString($skin->getCapeId()); - $this->putString($skin->getFullSkinId()); - $this->putString($skin->getArmSize()); - $this->putString($skin->getSkinColor()); - $this->putLInt(count($skin->getPersonaPieces())); - foreach($skin->getPersonaPieces() as $piece){ - $this->putString($piece->getPieceId()); - $this->putString($piece->getPieceType()); - $this->putString($piece->getPackId()); - $this->putBool($piece->isDefaultPiece()); - $this->putString($piece->getProductId()); - } - $this->putLInt(count($skin->getPieceTintColors())); - foreach($skin->getPieceTintColors() as $tint){ - $this->putString($tint->getPieceType()); - $this->putLInt(count($tint->getColors())); - foreach($tint->getColors() as $color){ - $this->putString($color); - } - } - } - - private function getSkinImage() : SkinImage{ - $width = $this->getLInt(); - $height = $this->getLInt(); - $data = $this->getString(); - try{ - return new SkinImage($height, $width, $data); - }catch(\InvalidArgumentException $e){ - throw new PacketDecodeException($e->getMessage(), 0, $e); - } - } - - private function putSkinImage(SkinImage $image) : void{ - $this->putLInt($image->getWidth()); - $this->putLInt($image->getHeight()); - $this->putString($image->getData()); - } - - /** - * @throws PacketDecodeException - * @throws BinaryDataException - */ - public function getItemStackWithoutStackId() : ItemStack{ - return $this->getItemStack(function() : void{ - //NOOP - }); - } - - public function putItemStackWithoutStackId(ItemStack $item) : void{ - $this->putItemStack($item, function() : void{ - //NOOP - }); - } - - /** - * @phpstan-param \Closure(PacketSerializer) : void $readExtraCrapInTheMiddle - * - * @throws PacketDecodeException - * @throws BinaryDataException - */ - public function getItemStack(\Closure $readExtraCrapInTheMiddle) : ItemStack{ - $id = $this->getVarInt(); - if($id === 0){ - return ItemStack::null(); - } - - $count = $this->getLShort(); - $meta = $this->getUnsignedVarInt(); - - $readExtraCrapInTheMiddle($this); - - $blockRuntimeId = $this->getVarInt(); - $extraData = self::decoder($this->getString(), 0, $this->context); - return (static function() use ($extraData, $id, $meta, $count, $blockRuntimeId) : ItemStack{ - $nbtLen = $extraData->getLShort(); - - /** @var CompoundTag|null $compound */ - $compound = null; - if($nbtLen === 0xffff){ - $nbtDataVersion = $extraData->getByte(); - if($nbtDataVersion !== 1){ - throw new PacketDecodeException("Unexpected NBT data version $nbtDataVersion"); - } - $offset = $extraData->getOffset(); - try{ - $compound = (new LittleEndianNbtSerializer())->read($extraData->getBuffer(), $offset, 512)->mustGetCompoundTag(); - }catch(NbtDataException $e){ - throw PacketDecodeException::wrap($e, "Failed decoding NBT root"); - }finally{ - $extraData->setOffset($offset); - } - }elseif($nbtLen !== 0){ - throw new PacketDecodeException("Unexpected fake NBT length $nbtLen"); - } - - $canPlaceOn = []; - for($i = 0, $canPlaceOnCount = $extraData->getLInt(); $i < $canPlaceOnCount; ++$i){ - $canPlaceOn[] = $extraData->get($extraData->getLShort()); - } - - $canDestroy = []; - for($i = 0, $canDestroyCount = $extraData->getLInt(); $i < $canDestroyCount; ++$i){ - $canDestroy[] = $extraData->get($extraData->getLShort()); - } - - $shieldBlockingTick = null; - if($id === $extraData->shieldItemRuntimeId){ - $shieldBlockingTick = $extraData->getLLong(); - } - - if(!$extraData->feof()){ - throw new PacketDecodeException("Unexpected trailing extradata for network item $id"); - } - - return new ItemStack($id, $meta, $count, $blockRuntimeId, $compound, $canPlaceOn, $canDestroy, $shieldBlockingTick); - })(); - } - - /** - * @phpstan-param \Closure(PacketSerializer) : void $writeExtraCrapInTheMiddle - */ - public function putItemStack(ItemStack $item, \Closure $writeExtraCrapInTheMiddle) : void{ - if($item->getId() === 0){ - $this->putVarInt(0); - - return; - } - - $this->putVarInt($item->getId()); - $this->putLShort($item->getCount()); - $this->putUnsignedVarInt($item->getMeta()); - - $writeExtraCrapInTheMiddle($this); - - $this->putVarInt($item->getBlockRuntimeId()); - $context = $this->context; - $this->putString((static function() use ($item, $context) : string{ - $extraData = PacketSerializer::encoder($context); - - $nbt = $item->getNbt(); - if($nbt !== null){ - $extraData->putLShort(0xffff); - $extraData->putByte(1); //TODO: NBT data version (?) - $extraData->put((new LittleEndianNbtSerializer())->write(new TreeRoot($nbt))); - }else{ - $extraData->putLShort(0); - } - - $extraData->putLInt(count($item->getCanPlaceOn())); - foreach($item->getCanPlaceOn() as $entry){ - $extraData->putLShort(strlen($entry)); - $extraData->put($entry); - } - $extraData->putLInt(count($item->getCanDestroy())); - foreach($item->getCanDestroy() as $entry){ - $extraData->putLShort(strlen($entry)); - $extraData->put($entry); - } - - $blockingTick = $item->getShieldBlockingTick(); - if($item->getId() === $extraData->shieldItemRuntimeId){ - $extraData->putLLong($blockingTick ?? 0); - } - return $extraData->getBuffer(); - })()); - } - - public function getRecipeIngredient() : RecipeIngredient{ - $id = $this->getVarInt(); - if($id === 0){ - return new RecipeIngredient(0, 0, 0); - } - $meta = $this->getVarInt(); - $count = $this->getVarInt(); - - return new RecipeIngredient($id, $meta, $count); - } - - public function putRecipeIngredient(RecipeIngredient $ingredient) : void{ - if($ingredient->getId() === 0){ - $this->putVarInt(0); - }else{ - $this->putVarInt($ingredient->getId()); - $this->putVarInt($ingredient->getMeta()); - $this->putVarInt($ingredient->getCount()); - } - } - - /** - * Decodes entity metadata from the stream. - * - * @return MetadataProperty[] - * @phpstan-return array - * - * @throws PacketDecodeException - * @throws BinaryDataException - */ - public function getEntityMetadata() : array{ - $count = $this->getUnsignedVarInt(); - $data = []; - for($i = 0; $i < $count; ++$i){ - $key = $this->getUnsignedVarInt(); - $type = $this->getUnsignedVarInt(); - - $data[$key] = $this->readMetadataProperty($type); - } - - return $data; - } - - private function readMetadataProperty(int $type) : MetadataProperty{ - switch($type){ - case ByteMetadataProperty::id(): - return ByteMetadataProperty::read($this); - case ShortMetadataProperty::id(): - return ShortMetadataProperty::read($this); - case IntMetadataProperty::id(): - return IntMetadataProperty::read($this); - case FloatMetadataProperty::id(): - return FloatMetadataProperty::read($this); - case StringMetadataProperty::id(): - return StringMetadataProperty::read($this); - case CompoundTagMetadataProperty::id(): - return CompoundTagMetadataProperty::read($this); - case BlockPosMetadataProperty::id(): - return BlockPosMetadataProperty::read($this); - case LongMetadataProperty::id(): - return LongMetadataProperty::read($this); - case Vec3MetadataProperty::id(): - return Vec3MetadataProperty::read($this); - default: - throw new PacketDecodeException("Unknown entity metadata type " . $type); - } - } - - /** - * Writes entity metadata to the packet buffer. - * - * @param MetadataProperty[] $metadata - * - * @phpstan-param array $metadata - */ - public function putEntityMetadata(array $metadata) : void{ - $this->putUnsignedVarInt(count($metadata)); - foreach($metadata as $key => $d){ - $this->putUnsignedVarInt($key); - $this->putUnsignedVarInt($d::id()); - $d->write($this); - } - } - - /** - * Reads a list of Attributes from the stream. - * @return Attribute[] - * - * @throws BinaryDataException - */ - public function getAttributeList() : array{ - $list = []; - $count = $this->getUnsignedVarInt(); - - for($i = 0; $i < $count; ++$i){ - $min = $this->getLFloat(); - $max = $this->getLFloat(); - $current = $this->getLFloat(); - $default = $this->getLFloat(); - $id = $this->getString(); - - $list[] = new Attribute($id, $min, $max, $current, $default); - } - - return $list; - } - - /** - * Writes a list of Attributes to the packet buffer using the standard format. - * - * @param Attribute ...$attributes - */ - public function putAttributeList(Attribute ...$attributes) : void{ - $this->putUnsignedVarInt(count($attributes)); - foreach($attributes as $attribute){ - $this->putLFloat($attribute->getMin()); - $this->putLFloat($attribute->getMax()); - $this->putLFloat($attribute->getCurrent()); - $this->putLFloat($attribute->getDefault()); - $this->putString($attribute->getId()); - } - } - - /** - * Reads and returns an EntityUniqueID - * - * @throws BinaryDataException - */ - final public function getEntityUniqueId() : int{ - return $this->getVarLong(); - } - - /** - * Writes an EntityUniqueID - */ - public function putEntityUniqueId(int $eid) : void{ - $this->putVarLong($eid); - } - - /** - * Reads and returns an EntityRuntimeID - * - * @throws BinaryDataException - */ - final public function getEntityRuntimeId() : int{ - return $this->getUnsignedVarLong(); - } - - /** - * Writes an EntityRuntimeID - */ - public function putEntityRuntimeId(int $eid) : void{ - $this->putUnsignedVarLong($eid); - } - - /** - * Reads an block position with unsigned Y coordinate. - * - * @param int $x reference parameter - * @param int $y reference parameter - * @param int $z reference parameter - * - * @throws BinaryDataException - */ - public function getBlockPosition(&$x, &$y, &$z) : void{ - $x = $this->getVarInt(); - $y = $this->getUnsignedVarInt(); - $z = $this->getVarInt(); - } - - /** - * Writes a block position with unsigned Y coordinate. - */ - public function putBlockPosition(int $x, int $y, int $z) : void{ - $this->putVarInt($x); - $this->putUnsignedVarInt($y); - $this->putVarInt($z); - } - - /** - * Reads a block position with a signed Y coordinate. - * - * @param int $x reference parameter - * @param int $y reference parameter - * @param int $z reference parameter - * - * @throws BinaryDataException - */ - public function getSignedBlockPosition(&$x, &$y, &$z) : void{ - $x = $this->getVarInt(); - $y = $this->getVarInt(); - $z = $this->getVarInt(); - } - - /** - * Writes a block position with a signed Y coordinate. - */ - public function putSignedBlockPosition(int $x, int $y, int $z) : void{ - $this->putVarInt($x); - $this->putVarInt($y); - $this->putVarInt($z); - } - - /** - * Reads a floating-point Vector3 object with coordinates rounded to 4 decimal places. - * - * @throws BinaryDataException - */ - public function getVector3() : Vector3{ - $x = $this->getLFloat(); - $y = $this->getLFloat(); - $z = $this->getLFloat(); - return new Vector3($x, $y, $z); - } - - /** - * Writes a floating-point Vector3 object, or 3x zero if null is given. - * - * Note: ONLY use this where it is reasonable to allow not specifying the vector. - * For all other purposes, use the non-nullable version. - * - * @see PacketSerializer::putVector3() - */ - public function putVector3Nullable(?Vector3 $vector) : void{ - if($vector !== null){ - $this->putVector3($vector); - }else{ - $this->putLFloat(0.0); - $this->putLFloat(0.0); - $this->putLFloat(0.0); - } - } - - /** - * Writes a floating-point Vector3 object - */ - public function putVector3(Vector3 $vector) : void{ - $this->putLFloat($vector->x); - $this->putLFloat($vector->y); - $this->putLFloat($vector->z); - } - - /** - * @throws BinaryDataException - */ - public function getByteRotation() : float{ - return ($this->getByte() * (360 / 256)); - } - - public function putByteRotation(float $rotation) : void{ - $this->putByte((int) ($rotation / (360 / 256))); - } - - private function readGameRule(int $type, bool $isPlayerModifiable) : GameRule{ - switch($type){ - case GameRuleType::BOOL: return BoolGameRule::decode($this, $isPlayerModifiable); - case GameRuleType::INT: return IntGameRule::decode($this, $isPlayerModifiable); - case GameRuleType::FLOAT: return FloatGameRule::decode($this, $isPlayerModifiable); - default: - throw new PacketDecodeException("Unknown gamerule type $type"); - } - } - - /** - * Reads gamerules - * - * @return GameRule[] game rule name => value - * @phpstan-return array - * - * @throws PacketDecodeException - * @throws BinaryDataException - */ - public function getGameRules() : array{ - $count = $this->getUnsignedVarInt(); - $rules = []; - for($i = 0; $i < $count; ++$i){ - $name = $this->getString(); - $isPlayerModifiable = $this->getBool(); - $type = $this->getUnsignedVarInt(); - $rules[$name] = $this->readGameRule($type, $isPlayerModifiable); - } - - return $rules; - } - - /** - * Writes a gamerule array - * - * @param GameRule[] $rules - * @phpstan-param array $rules - */ - public function putGameRules(array $rules) : void{ - $this->putUnsignedVarInt(count($rules)); - foreach($rules as $name => $rule){ - $this->putString($name); - $this->putBool($rule->isPlayerModifiable()); - $this->putUnsignedVarInt($rule->getType()); - $rule->encode($this); - } - } - - /** - * @throws BinaryDataException - */ - public function getEntityLink() : EntityLink{ - $fromEntityUniqueId = $this->getEntityUniqueId(); - $toEntityUniqueId = $this->getEntityUniqueId(); - $type = $this->getByte(); - $immediate = $this->getBool(); - $causedByRider = $this->getBool(); - return new EntityLink($fromEntityUniqueId, $toEntityUniqueId, $type, $immediate, $causedByRider); - } - - public function putEntityLink(EntityLink $link) : void{ - $this->putEntityUniqueId($link->fromEntityUniqueId); - $this->putEntityUniqueId($link->toEntityUniqueId); - $this->putByte($link->type); - $this->putBool($link->immediate); - $this->putBool($link->causedByRider); - } - - /** - * @throws BinaryDataException - */ - public function getCommandOriginData() : CommandOriginData{ - $result = new CommandOriginData(); - - $result->type = $this->getUnsignedVarInt(); - $result->uuid = $this->getUUID(); - $result->requestId = $this->getString(); - - if($result->type === CommandOriginData::ORIGIN_DEV_CONSOLE or $result->type === CommandOriginData::ORIGIN_TEST){ - $result->playerEntityUniqueId = $this->getVarLong(); - } - - return $result; - } - - public function putCommandOriginData(CommandOriginData $data) : void{ - $this->putUnsignedVarInt($data->type); - $this->putUUID($data->uuid); - $this->putString($data->requestId); - - if($data->type === CommandOriginData::ORIGIN_DEV_CONSOLE or $data->type === CommandOriginData::ORIGIN_TEST){ - $this->putVarLong($data->playerEntityUniqueId); - } - } - - public function getStructureSettings() : StructureSettings{ - $result = new StructureSettings(); - - $result->paletteName = $this->getString(); - - $result->ignoreEntities = $this->getBool(); - $result->ignoreBlocks = $this->getBool(); - - $this->getBlockPosition($result->structureSizeX, $result->structureSizeY, $result->structureSizeZ); - $this->getBlockPosition($result->structureOffsetX, $result->structureOffsetY, $result->structureOffsetZ); - - $result->lastTouchedByPlayerID = $this->getEntityUniqueId(); - $result->rotation = $this->getByte(); - $result->mirror = $this->getByte(); - $result->integrityValue = $this->getFloat(); - $result->integritySeed = $this->getInt(); - $result->pivot = $this->getVector3(); - - return $result; - } - - public function putStructureSettings(StructureSettings $structureSettings) : void{ - $this->putString($structureSettings->paletteName); - - $this->putBool($structureSettings->ignoreEntities); - $this->putBool($structureSettings->ignoreBlocks); - - $this->putBlockPosition($structureSettings->structureSizeX, $structureSettings->structureSizeY, $structureSettings->structureSizeZ); - $this->putBlockPosition($structureSettings->structureOffsetX, $structureSettings->structureOffsetY, $structureSettings->structureOffsetZ); - - $this->putEntityUniqueId($structureSettings->lastTouchedByPlayerID); - $this->putByte($structureSettings->rotation); - $this->putByte($structureSettings->mirror); - $this->putFloat($structureSettings->integrityValue); - $this->putInt($structureSettings->integritySeed); - $this->putVector3($structureSettings->pivot); - } - - public function getStructureEditorData() : StructureEditorData{ - $result = new StructureEditorData(); - - $result->structureName = $this->getString(); - $result->structureDataField = $this->getString(); - - $result->includePlayers = $this->getBool(); - $result->showBoundingBox = $this->getBool(); - - $result->structureBlockType = $this->getVarInt(); - $result->structureSettings = $this->getStructureSettings(); - $result->structureRedstoneSaveMove = $this->getVarInt(); - - return $result; - } - - public function putStructureEditorData(StructureEditorData $structureEditorData) : void{ - $this->putString($structureEditorData->structureName); - $this->putString($structureEditorData->structureDataField); - - $this->putBool($structureEditorData->includePlayers); - $this->putBool($structureEditorData->showBoundingBox); - - $this->putVarInt($structureEditorData->structureBlockType); - $this->putStructureSettings($structureEditorData->structureSettings); - $this->putVarInt($structureEditorData->structureRedstoneSaveMove); - } - - public function getNbtRoot() : TreeRoot{ - $offset = $this->getOffset(); - try{ - return (new NetworkNbtSerializer())->read($this->getBuffer(), $offset, 512); - }catch(NbtDataException $e){ - throw PacketDecodeException::wrap($e, "Failed decoding NBT root"); - }finally{ - $this->setOffset($offset); - } - } - - public function getNbtCompoundRoot() : CompoundTag{ - try{ - return $this->getNbtRoot()->mustGetCompoundTag(); - }catch(NbtDataException $e){ - throw PacketDecodeException::wrap($e, "Expected TAG_Compound NBT root"); - } - } - - public function readGenericTypeNetworkId() : int{ - return $this->getVarInt(); - } - - public function writeGenericTypeNetworkId(int $id) : void{ - $this->putVarInt($id); - } -} diff --git a/src/network/mcpe/protocol/serializer/PacketSerializerContext.php b/src/network/mcpe/protocol/serializer/PacketSerializerContext.php deleted file mode 100644 index 887adbc909..0000000000 --- a/src/network/mcpe/protocol/serializer/PacketSerializerContext.php +++ /dev/null @@ -1,39 +0,0 @@ -itemDictionary = $itemDictionary; - } - - public function getItemDictionary() : ItemTypeDictionary{ return $this->itemDictionary; } -} diff --git a/src/network/mcpe/protocol/types/BlockPaletteEntry.php b/src/network/mcpe/protocol/types/BlockPaletteEntry.php deleted file mode 100644 index 27c5fb29e0..0000000000 --- a/src/network/mcpe/protocol/types/BlockPaletteEntry.php +++ /dev/null @@ -1,43 +0,0 @@ -name = $name; - $this->states = $states; - } - - public function getName() : string{ return $this->name; } - - public function getStates() : CompoundTag{ return $this->states; } -} diff --git a/src/network/mcpe/protocol/types/BoolGameRule.php b/src/network/mcpe/protocol/types/BoolGameRule.php deleted file mode 100644 index c26b2c9160..0000000000 --- a/src/network/mcpe/protocol/types/BoolGameRule.php +++ /dev/null @@ -1,53 +0,0 @@ -value = $value; - } - - public function getType() : int{ - return GameRuleType::BOOL; - } - - public function getValue() : bool{ - return $this->value; - } - - public function encode(PacketSerializer $out) : void{ - $out->putBool($this->value); - } - - public static function decode(PacketSerializer $in, bool $isPlayerModifiable) : self{ - return new self($in->getBool(), $isPlayerModifiable); - } -} diff --git a/src/network/mcpe/protocol/types/CacheableNbt.php b/src/network/mcpe/protocol/types/CacheableNbt.php deleted file mode 100644 index 073c40c1d4..0000000000 --- a/src/network/mcpe/protocol/types/CacheableNbt.php +++ /dev/null @@ -1,60 +0,0 @@ -root = $nbtRoot; - } - - /** - * @phpstan-return TTagType - */ - public function getRoot() : Tag{ - return $this->root; - } - - public function getEncodedNbt() : string{ - return $this->encodedNbt ?? ($this->encodedNbt = (new NetworkNbtSerializer())->write(new TreeRoot($this->root))); - } -} diff --git a/src/network/mcpe/protocol/types/ChunkCacheBlob.php b/src/network/mcpe/protocol/types/ChunkCacheBlob.php deleted file mode 100644 index a20137620e..0000000000 --- a/src/network/mcpe/protocol/types/ChunkCacheBlob.php +++ /dev/null @@ -1,47 +0,0 @@ -hash = $hash; - $this->payload = $payload; - } - - public function getHash() : int{ - return $this->hash; - } - - public function getPayload() : string{ - return $this->payload; - } -} diff --git a/src/network/mcpe/protocol/types/DeviceOS.php b/src/network/mcpe/protocol/types/DeviceOS.php deleted file mode 100644 index 97a6fe5eb1..0000000000 --- a/src/network/mcpe/protocol/types/DeviceOS.php +++ /dev/null @@ -1,44 +0,0 @@ -id = $id; - $this->level = $level; - } - - public function getId() : int{ return $this->id; } - - public function getLevel() : int{ return $this->level; } - - public static function read(PacketSerializer $in) : self{ - $id = $in->getByte(); - $level = $in->getByte(); - return new self($id, $level); - } - - public function write(PacketSerializer $out) : void{ - $out->putByte($this->id); - $out->putByte($this->level); - } -} diff --git a/src/network/mcpe/protocol/types/EnchantOption.php b/src/network/mcpe/protocol/types/EnchantOption.php deleted file mode 100644 index f3aa8b7f07..0000000000 --- a/src/network/mcpe/protocol/types/EnchantOption.php +++ /dev/null @@ -1,126 +0,0 @@ -cost = $cost; - $this->slotFlags = $slotFlags; - $this->equipActivatedEnchantments = $equipActivatedEnchantments; - $this->heldActivatedEnchantments = $heldActivatedEnchantments; - $this->selfActivatedEnchantments = $selfActivatedEnchantments; - $this->name = $name; - $this->optionId = $optionId; - } - - public function getCost() : int{ return $this->cost; } - - public function getSlotFlags() : int{ return $this->slotFlags; } - - /** @return Enchant[] */ - public function getEquipActivatedEnchantments() : array{ return $this->equipActivatedEnchantments; } - - /** @return Enchant[] */ - public function getHeldActivatedEnchantments() : array{ return $this->heldActivatedEnchantments; } - - /** @return Enchant[] */ - public function getSelfActivatedEnchantments() : array{ return $this->selfActivatedEnchantments; } - - public function getName() : string{ return $this->name; } - - public function getOptionId() : int{ return $this->optionId; } - - /** - * @return Enchant[] - */ - private static function readEnchantList(PacketSerializer $in) : array{ - $result = []; - for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ - $result[] = Enchant::read($in); - } - return $result; - } - - /** - * @param Enchant[] $list - */ - private static function writeEnchantList(PacketSerializer $out, array $list) : void{ - $out->putUnsignedVarInt(count($list)); - foreach($list as $item){ - $item->write($out); - } - } - - public static function read(PacketSerializer $in) : self{ - $cost = $in->getUnsignedVarInt(); - - $slotFlags = $in->getLInt(); - $equipActivatedEnchants = self::readEnchantList($in); - $heldActivatedEnchants = self::readEnchantList($in); - $selfActivatedEnchants = self::readEnchantList($in); - - $name = $in->getString(); - $optionId = $in->readGenericTypeNetworkId(); - - return new self($cost, $slotFlags, $equipActivatedEnchants, $heldActivatedEnchants, $selfActivatedEnchants, $name, $optionId); - } - - public function write(PacketSerializer $out) : void{ - $out->putUnsignedVarInt($this->cost); - - $out->putLInt($this->slotFlags); - self::writeEnchantList($out, $this->equipActivatedEnchantments); - self::writeEnchantList($out, $this->heldActivatedEnchantments); - self::writeEnchantList($out, $this->selfActivatedEnchantments); - - $out->putString($this->name); - $out->writeGenericTypeNetworkId($this->optionId); - } -} diff --git a/src/network/mcpe/protocol/types/Experiments.php b/src/network/mcpe/protocol/types/Experiments.php deleted file mode 100644 index 550e597103..0000000000 --- a/src/network/mcpe/protocol/types/Experiments.php +++ /dev/null @@ -1,72 +0,0 @@ - - */ - private $experiments; - /** @var bool */ - private $hasPreviouslyUsedExperiments; - - /** - * @param bool[] $experiments - * @phpstan-param array $experiments - */ - public function __construct(array $experiments, bool $hasPreviouslyUsedExperiments){ - $this->experiments = $experiments; - $this->hasPreviouslyUsedExperiments = $hasPreviouslyUsedExperiments; - } - - /** @return bool[] */ - public function getExperiments() : array{ return $this->experiments; } - - public function hasPreviouslyUsedExperiments() : bool{ return $this->hasPreviouslyUsedExperiments; } - - public static function read(PacketSerializer $in) : self{ - $experiments = []; - for($i = 0, $len = $in->getLInt(); $i < $len; ++$i){ - $experimentName = $in->getString(); - $enabled = $in->getBool(); - $experiments[$experimentName] = $enabled; - } - $hasPreviouslyUsedExperiments = $in->getBool(); - return new self($experiments, $hasPreviouslyUsedExperiments); - } - - public function write(PacketSerializer $out) : void{ - $out->putLInt(count($this->experiments)); - foreach($this->experiments as $experimentName => $enabled){ - $out->putString($experimentName); - $out->putBool($enabled); - } - $out->putBool($this->hasPreviouslyUsedExperiments); - } -} diff --git a/src/network/mcpe/protocol/types/FloatGameRule.php b/src/network/mcpe/protocol/types/FloatGameRule.php deleted file mode 100644 index caab87c3a7..0000000000 --- a/src/network/mcpe/protocol/types/FloatGameRule.php +++ /dev/null @@ -1,52 +0,0 @@ -value = $value; - } - - public function getType() : int{ - return GameRuleType::FLOAT; - } - - public function getValue() : float{ - return $this->value; - } - - public function encode(PacketSerializer $out) : void{ - $out->putLFloat($this->value); - } - - public static function decode(PacketSerializer $in, bool $isPlayerModifiable) : self{ - return new self($in->getLFloat(), $isPlayerModifiable); - } -} diff --git a/src/network/mcpe/protocol/types/GameMode.php b/src/network/mcpe/protocol/types/GameMode.php deleted file mode 100644 index 616c92259a..0000000000 --- a/src/network/mcpe/protocol/types/GameMode.php +++ /dev/null @@ -1,38 +0,0 @@ -playerModifiable = $isPlayerModifiable; - } - - public function isPlayerModifiable() : bool{ return $this->playerModifiable; } - - abstract public function getType() : int; - - abstract public function encode(PacketSerializer $out) : void; -} diff --git a/src/network/mcpe/protocol/types/GameRuleType.php b/src/network/mcpe/protocol/types/GameRuleType.php deleted file mode 100644 index 66a6b47619..0000000000 --- a/src/network/mcpe/protocol/types/GameRuleType.php +++ /dev/null @@ -1,35 +0,0 @@ -value = $value; - } - - public function getType() : int{ - return GameRuleType::INT; - } - - public function getValue() : int{ - return $this->value; - } - - public function encode(PacketSerializer $out) : void{ - $out->putUnsignedVarInt($this->value); - } - - public static function decode(PacketSerializer $in, bool $isPlayerModifiable) : self{ - return new self($in->getUnsignedVarInt(), $isPlayerModifiable); - } -} diff --git a/src/network/mcpe/protocol/types/ItemComponentPacketEntry.php b/src/network/mcpe/protocol/types/ItemComponentPacketEntry.php deleted file mode 100644 index dbe1207016..0000000000 --- a/src/network/mcpe/protocol/types/ItemComponentPacketEntry.php +++ /dev/null @@ -1,43 +0,0 @@ -name = $name; - $this->componentNbt = $componentNbt; - } - - public function getName() : string{ return $this->name; } - - public function getComponentNbt() : CompoundTag{ return $this->componentNbt; } -} diff --git a/src/network/mcpe/protocol/types/ItemTypeEntry.php b/src/network/mcpe/protocol/types/ItemTypeEntry.php deleted file mode 100644 index 79d063bc60..0000000000 --- a/src/network/mcpe/protocol/types/ItemTypeEntry.php +++ /dev/null @@ -1,46 +0,0 @@ -stringId = $stringId; - $this->numericId = $numericId; - $this->componentBased = $componentBased; - } - - public function getStringId() : string{ return $this->stringId; } - - public function getNumericId() : int{ return $this->numericId; } - - public function isComponentBased() : bool{ return $this->componentBased; } -} diff --git a/src/network/mcpe/protocol/types/MapDecoration.php b/src/network/mcpe/protocol/types/MapDecoration.php deleted file mode 100644 index 7cf2dbde25..0000000000 --- a/src/network/mcpe/protocol/types/MapDecoration.php +++ /dev/null @@ -1,74 +0,0 @@ -icon = $icon; - $this->rotation = $rotation; - $this->xOffset = $xOffset; - $this->yOffset = $yOffset; - $this->label = $label; - $this->color = $color; - } - - public function getIcon() : int{ - return $this->icon; - } - - public function getRotation() : int{ - return $this->rotation; - } - - public function getXOffset() : int{ - return $this->xOffset; - } - - public function getYOffset() : int{ - return $this->yOffset; - } - - public function getLabel() : string{ - return $this->label; - } - - public function getColor() : Color{ - return $this->color; - } -} diff --git a/src/network/mcpe/protocol/types/MapTrackedObject.php b/src/network/mcpe/protocol/types/MapTrackedObject.php deleted file mode 100644 index 7c9f109541..0000000000 --- a/src/network/mcpe/protocol/types/MapTrackedObject.php +++ /dev/null @@ -1,43 +0,0 @@ -uuid = $uuid; - - return $entry; - } - - public static function createAdditionEntry(UuidInterface $uuid, int $entityUniqueId, string $username, SkinData $skinData, string $xboxUserId = "", string $platformChatId = "", int $buildPlatform = -1, bool $isTeacher = false, bool $isHost = false) : PlayerListEntry{ - $entry = new PlayerListEntry(); - $entry->uuid = $uuid; - $entry->entityUniqueId = $entityUniqueId; - $entry->username = $username; - $entry->skinData = $skinData; - $entry->xboxUserId = $xboxUserId; - $entry->platformChatId = $platformChatId; - $entry->buildPlatform = $buildPlatform; - $entry->isTeacher = $isTeacher; - $entry->isHost = $isHost; - - return $entry; - } -} diff --git a/src/network/mcpe/protocol/types/PlayerMovementSettings.php b/src/network/mcpe/protocol/types/PlayerMovementSettings.php deleted file mode 100644 index dc735523dd..0000000000 --- a/src/network/mcpe/protocol/types/PlayerMovementSettings.php +++ /dev/null @@ -1,61 +0,0 @@ -movementType = $movementType; - $this->rewindHistorySize = $rewindHistorySize; - //do not ask me what the F this is doing here - $this->serverAuthoritativeBlockBreaking = $serverAuthoritativeBlockBreaking; - } - - public function getMovementType() : int{ return $this->movementType; } - - public function getRewindHistorySize() : int{ return $this->rewindHistorySize; } - - public function isServerAuthoritativeBlockBreaking() : bool{ return $this->serverAuthoritativeBlockBreaking; } - - public static function read(PacketSerializer $in) : self{ - $movementType = $in->getVarInt(); - $rewindHistorySize = $in->getVarInt(); - $serverAuthBlockBreaking = $in->getBool(); - return new self($movementType, $rewindHistorySize, $serverAuthBlockBreaking); - } - - public function write(PacketSerializer $out) : void{ - $out->putVarInt($this->movementType); - $out->putVarInt($this->rewindHistorySize); - $out->putBool($this->serverAuthoritativeBlockBreaking); - } -} diff --git a/src/network/mcpe/protocol/types/PlayerMovementType.php b/src/network/mcpe/protocol/types/PlayerMovementType.php deleted file mode 100644 index 0521742ba1..0000000000 --- a/src/network/mcpe/protocol/types/PlayerMovementType.php +++ /dev/null @@ -1,31 +0,0 @@ -biomeType = $biomeType; - $this->biomeName = $biomeName; - $this->dimension = $dimension; - } - - public function getBiomeType() : int{ - return $this->biomeType; - } - - public function getBiomeName() : string{ - return $this->biomeName; - } - - /** - * @see DimensionIds - */ - public function getDimension() : int{ - return $this->dimension; - } - - public static function read(PacketSerializer $in) : self{ - $biomeType = $in->getLShort(); - $biomeName = $in->getString(); - $dimension = $in->getVarInt(); - - return new self($biomeType, $biomeName, $dimension); - } - - public function write(PacketSerializer $out) : void{ - $out->putLShort($this->biomeType); - $out->putString($this->biomeName); - $out->putVarInt($this->dimension); - } -} diff --git a/src/network/mcpe/protocol/types/StructureEditorData.php b/src/network/mcpe/protocol/types/StructureEditorData.php deleted file mode 100644 index 9e7f042631..0000000000 --- a/src/network/mcpe/protocol/types/StructureEditorData.php +++ /dev/null @@ -1,48 +0,0 @@ -name = $name; - $this->description = $description; - $this->flags = $flags; - $this->permission = $permission; - $this->aliases = $aliases; - $this->overloads = $overloads; - } - - public function getName() : string{ - return $this->name; - } - - public function getDescription() : string{ - return $this->description; - } - - public function getFlags() : int{ - return $this->flags; - } - - public function getPermission() : int{ - return $this->permission; - } - - public function getAliases() : ?CommandEnum{ - return $this->aliases; - } - - /** - * @return CommandParameter[][] - */ - public function getOverloads() : array{ - return $this->overloads; - } -} diff --git a/src/network/mcpe/protocol/types/command/CommandEnum.php b/src/network/mcpe/protocol/types/command/CommandEnum.php deleted file mode 100644 index e7594e8bb7..0000000000 --- a/src/network/mcpe/protocol/types/command/CommandEnum.php +++ /dev/null @@ -1,55 +0,0 @@ - - */ - private $enumValues = []; - - /** - * @param string[] $enumValues - * @phpstan-param list $enumValues - */ - public function __construct(string $enumName, array $enumValues){ - $this->enumName = $enumName; - $this->enumValues = $enumValues; - } - - public function getName() : string{ - return $this->enumName; - } - - /** - * @return string[] - * @phpstan-return list - */ - public function getValues() : array{ - return $this->enumValues; - } -} diff --git a/src/network/mcpe/protocol/types/command/CommandEnumConstraint.php b/src/network/mcpe/protocol/types/command/CommandEnumConstraint.php deleted file mode 100644 index 923b6edbb7..0000000000 --- a/src/network/mcpe/protocol/types/command/CommandEnumConstraint.php +++ /dev/null @@ -1,65 +0,0 @@ -getValues()[$valueOffset])){ - throw new \InvalidArgumentException("Invalid enum value offset $valueOffset"); - } - $this->enum = $enum; - $this->valueOffset = $valueOffset; - $this->constraints = $constraints; - } - - public function getEnum() : CommandEnum{ - return $this->enum; - } - - public function getValueOffset() : int{ - return $this->valueOffset; - } - - public function getAffectedValue() : string{ - return $this->enum->getValues()[$this->valueOffset]; - } - - /** - * @return int[] - */ - public function getConstraints() : array{ - return $this->constraints; - } -} diff --git a/src/network/mcpe/protocol/types/command/CommandOriginData.php b/src/network/mcpe/protocol/types/command/CommandOriginData.php deleted file mode 100644 index 576a80112e..0000000000 --- a/src/network/mcpe/protocol/types/command/CommandOriginData.php +++ /dev/null @@ -1,52 +0,0 @@ -paramName = $name; - $result->paramType = $type; - $result->flags = $flags; - $result->isOptional = $optional; - return $result; - } - - public static function standard(string $name, int $type, int $flags = 0, bool $optional = false) : self{ - return self::baseline($name, AvailableCommandsPacket::ARG_FLAG_VALID | $type, $flags, $optional); - } - - public static function postfixed(string $name, string $postfix, int $flags = 0, bool $optional = false) : self{ - $result = self::baseline($name, AvailableCommandsPacket::ARG_FLAG_POSTFIX, $flags, $optional); - $result->postfix = $postfix; - return $result; - } - - public static function enum(string $name, CommandEnum $enum, int $flags, bool $optional = false) : self{ - $result = self::baseline($name, AvailableCommandsPacket::ARG_FLAG_ENUM | AvailableCommandsPacket::ARG_FLAG_VALID, $flags, $optional); - $result->enum = $enum; - return $result; - } -} diff --git a/src/network/mcpe/protocol/types/entity/Attribute.php b/src/network/mcpe/protocol/types/entity/Attribute.php deleted file mode 100644 index 84deb8c600..0000000000 --- a/src/network/mcpe/protocol/types/entity/Attribute.php +++ /dev/null @@ -1,65 +0,0 @@ -id = $id; - $this->min = $min; - $this->max = $max; - $this->current = $current; - $this->default = $default; - } - - public function getId() : string{ - return $this->id; - } - - public function getMin() : float{ - return $this->min; - } - - public function getMax() : float{ - return $this->max; - } - - public function getCurrent() : float{ - return $this->current; - } - - public function getDefault() : float{ - return $this->default; - } -} diff --git a/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php b/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php deleted file mode 100644 index 0770f0bd5e..0000000000 --- a/src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php +++ /dev/null @@ -1,59 +0,0 @@ -value = $value->floor(); - } - - public function getValue() : Vector3{ - return $this->value; - } - - public static function id() : int{ - return EntityMetadataTypes::POS; - } - - public static function read(PacketSerializer $in) : self{ - $x = $y = $z = 0; - $in->getSignedBlockPosition($x, $y, $z); - return new self(new Vector3($x, $y, $z)); - } - - public function write(PacketSerializer $out) : void{ - $out->putSignedBlockPosition($this->value->x, $this->value->y, $this->value->z); - } - - public function equals(MetadataProperty $other) : bool{ - return $other instanceof self and $other->value->equals($this->value); - } -} diff --git a/src/network/mcpe/protocol/types/entity/ByteMetadataProperty.php b/src/network/mcpe/protocol/types/entity/ByteMetadataProperty.php deleted file mode 100644 index b4ee55377d..0000000000 --- a/src/network/mcpe/protocol/types/entity/ByteMetadataProperty.php +++ /dev/null @@ -1,50 +0,0 @@ -getByte()); - } - - public function write(PacketSerializer $out) : void{ - $out->putByte($this->value); - } -} diff --git a/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php b/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php deleted file mode 100644 index 970c7ff635..0000000000 --- a/src/network/mcpe/protocol/types/entity/CompoundTagMetadataProperty.php +++ /dev/null @@ -1,62 +0,0 @@ -value = clone $value; - } - - public function getValue() : CompoundTag{ - return clone $this->value; - } - - public static function id() : int{ - return EntityMetadataTypes::COMPOUND_TAG; - } - - public function equals(MetadataProperty $other) : bool{ - return $other instanceof self and $other->value->equals($this->value); - } - - /** - * @throws PacketDecodeException - */ - public static function read(PacketSerializer $in) : self{ - return new self($in->getNbtCompoundRoot()); - } - - public function write(PacketSerializer $out) : void{ - $out->put((new NetworkNbtSerializer())->write(new TreeRoot($this->value))); - } -} diff --git a/src/network/mcpe/protocol/types/entity/EntityIds.php b/src/network/mcpe/protocol/types/entity/EntityIds.php deleted file mode 100644 index 4d60a66533..0000000000 --- a/src/network/mcpe/protocol/types/entity/EntityIds.php +++ /dev/null @@ -1,148 +0,0 @@ -fromEntityUniqueId = $fromEntityUniqueId; - $this->toEntityUniqueId = $toEntityUniqueId; - $this->type = $type; - $this->immediate = $immediate; - $this->causedByRider = $causedByRider; - } -} diff --git a/src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php b/src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php deleted file mode 100644 index 5d66c41632..0000000000 --- a/src/network/mcpe/protocol/types/entity/EntityMetadataCollection.php +++ /dev/null @@ -1,152 +0,0 @@ - - */ - private $properties = []; - /** - * @var MetadataProperty[] - * @phpstan-var array - */ - private $dirtyProperties = []; - - public function __construct(){ - - } - - public function setByte(int $key, int $value, bool $force = false) : void{ - - $this->set($key, new ByteMetadataProperty($value), $force); - } - - public function setShort(int $key, int $value, bool $force = false) : void{ - $this->set($key, new ShortMetadataProperty($value), $force); - } - - public function setInt(int $key, int $value, bool $force = false) : void{ - $this->set($key, new IntMetadataProperty($value), $force); - } - - public function setFloat(int $key, float $value, bool $force = false) : void{ - $this->set($key, new FloatMetadataProperty($value), $force); - } - - public function setString(int $key, string $value, bool $force = false) : void{ - $this->set($key, new StringMetadataProperty($value), $force); - } - - public function setCompoundTag(int $key, CompoundTag $value, bool $force = false) : void{ - $this->set($key, new CompoundTagMetadataProperty($value), $force); - } - - public function setBlockPos(int $key, ?Vector3 $value, bool $force = false) : void{ - $this->set($key, new BlockPosMetadataProperty($value ?? new Vector3(0, 0, 0)), $force); - } - - public function setLong(int $key, int $value, bool $force = false) : void{ - $this->set($key, new LongMetadataProperty($value), $force); - } - - public function setVector3(int $key, ?Vector3 $value, bool $force = false) : void{ - $this->set($key, new Vec3MetadataProperty($value ?? new Vector3(0, 0, 0)), $force); - } - - public function set(int $key, MetadataProperty $value, bool $force = false) : void{ - if(!$force and isset($this->properties[$key]) and !($this->properties[$key] instanceof $value)){ - throw new \InvalidArgumentException("Can't overwrite property with mismatching types (have " . get_class($this->properties[$key]) . ")"); - } - if(!isset($this->properties[$key]) or !$this->properties[$key]->equals($value)){ - $this->properties[$key] = $this->dirtyProperties[$key] = $value; - } - } - - public function setGenericFlag(int $flagId, bool $value) : void{ - $propertyId = $flagId >= 64 ? EntityMetadataProperties::FLAGS2 : EntityMetadataProperties::FLAGS; - $realFlagId = $flagId % 64; - $flagSetProp = $this->properties[$propertyId] ?? null; - if($flagSetProp === null){ - $flagSet = 0; - }elseif($flagSetProp instanceof LongMetadataProperty){ - $flagSet = $flagSetProp->getValue(); - }else{ - throw new \InvalidArgumentException("Wrong type found for flags, want long, but have " . get_class($flagSetProp)); - } - - if((($flagSet >> $realFlagId) & 1) !== ($value ? 1 : 0)){ - $flagSet ^= (1 << $realFlagId); - $this->setLong($propertyId, $flagSet); - } - } - - public function setPlayerFlag(int $flagId, bool $value) : void{ - $flagSetProp = $this->properties[EntityMetadataProperties::PLAYER_FLAGS] ?? null; - if($flagSetProp === null){ - $flagSet = 0; - }elseif($flagSetProp instanceof ByteMetadataProperty){ - $flagSet = $flagSetProp->getValue(); - }else{ - throw new \InvalidArgumentException("Wrong type found for flags, want byte, but have " . get_class($flagSetProp)); - } - if((($flagSet >> $flagId) & 1) !== ($value ? 1 : 0)){ - $flagSet ^= (1 << $flagId); - $this->setByte(EntityMetadataProperties::PLAYER_FLAGS, $flagSet); - } - } - - /** - * Returns all properties. - * - * @return MetadataProperty[] - * @phpstan-return array - */ - public function getAll() : array{ - return $this->properties; - } - - /** - * Returns properties that have changed and need to be broadcasted. - * - * @return MetadataProperty[] - * @phpstan-return array - */ - public function getDirty() : array{ - return $this->dirtyProperties; - } - - /** - * Clears records of dirty properties. - */ - public function clearDirtyProperties() : void{ - $this->dirtyProperties = []; - } -} diff --git a/src/network/mcpe/protocol/types/entity/EntityMetadataFlags.php b/src/network/mcpe/protocol/types/entity/EntityMetadataFlags.php deleted file mode 100644 index 5a27fdcd68..0000000000 --- a/src/network/mcpe/protocol/types/entity/EntityMetadataFlags.php +++ /dev/null @@ -1,126 +0,0 @@ -value = $value; - } - - public function getValue() : float{ - return $this->value; - } - - public static function id() : int{ - return EntityMetadataTypes::FLOAT; - } - - public function equals(MetadataProperty $other) : bool{ - return $other instanceof self and $other->value === $this->value; - } - - public static function read(PacketSerializer $in) : self{ - return new self($in->getLFloat()); - } - - public function write(PacketSerializer $out) : void{ - $out->putLFloat($this->value); - } -} diff --git a/src/network/mcpe/protocol/types/entity/IntMetadataProperty.php b/src/network/mcpe/protocol/types/entity/IntMetadataProperty.php deleted file mode 100644 index ea17316782..0000000000 --- a/src/network/mcpe/protocol/types/entity/IntMetadataProperty.php +++ /dev/null @@ -1,50 +0,0 @@ -getVarInt()); - } - - public function write(PacketSerializer $out) : void{ - $out->putVarInt($this->value); - } -} diff --git a/src/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php b/src/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php deleted file mode 100644 index 62be6a0d0b..0000000000 --- a/src/network/mcpe/protocol/types/entity/IntegerishMetadataProperty.php +++ /dev/null @@ -1,62 +0,0 @@ -min() or $value > $this->max()){ - throw new \InvalidArgumentException("Value is out of range " . $this->min() . " - " . $this->max()); - } - $this->value = $value; - } - - abstract protected function min() : int; - - abstract protected function max() : int; - - public function getValue() : int{ - return $this->value; - } - - public function equals(MetadataProperty $other) : bool{ - return $other instanceof self and $other->value === $this->value; - } - - /** - * @param bool[] $flags - * @phpstan-param array $flags - */ - public static function buildFromFlags(array $flags) : self{ - $value = 0; - foreach($flags as $flag => $v){ - if($v){ - $value |= 1 << $flag; - } - } - return new self($value); - } -} diff --git a/src/network/mcpe/protocol/types/entity/LongMetadataProperty.php b/src/network/mcpe/protocol/types/entity/LongMetadataProperty.php deleted file mode 100644 index 895dbe7066..0000000000 --- a/src/network/mcpe/protocol/types/entity/LongMetadataProperty.php +++ /dev/null @@ -1,52 +0,0 @@ -getVarLong()); - } - - public function write(PacketSerializer $out) : void{ - $out->putVarLong($this->value); - } -} diff --git a/src/network/mcpe/protocol/types/entity/MetadataProperty.php b/src/network/mcpe/protocol/types/entity/MetadataProperty.php deleted file mode 100644 index 63673d9320..0000000000 --- a/src/network/mcpe/protocol/types/entity/MetadataProperty.php +++ /dev/null @@ -1,35 +0,0 @@ -getSignedLShort()); - } - - public function write(PacketSerializer $out) : void{ - $out->putLShort($this->value); - } -} diff --git a/src/network/mcpe/protocol/types/entity/StringMetadataProperty.php b/src/network/mcpe/protocol/types/entity/StringMetadataProperty.php deleted file mode 100644 index 5396d34b16..0000000000 --- a/src/network/mcpe/protocol/types/entity/StringMetadataProperty.php +++ /dev/null @@ -1,51 +0,0 @@ -value = $value; - } - - public static function id() : int{ - return EntityMetadataTypes::STRING; - } - - public static function read(PacketSerializer $in) : self{ - return new self($in->getString()); - } - - public function write(PacketSerializer $out) : void{ - $out->putString($this->value); - } - - public function equals(MetadataProperty $other) : bool{ - return $other instanceof self and $other->value === $this->value; - } -} diff --git a/src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php b/src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php deleted file mode 100644 index 44b81e6105..0000000000 --- a/src/network/mcpe/protocol/types/entity/Vec3MetadataProperty.php +++ /dev/null @@ -1,56 +0,0 @@ -value = $value->asVector3(); - } - - public function getValue() : Vector3{ - return clone $this->value; - } - - public static function id() : int{ - return EntityMetadataTypes::VECTOR3F; - } - - public static function read(PacketSerializer $in) : self{ - return new self($in->getVector3()); - } - - public function write(PacketSerializer $out) : void{ - $out->putVector3($this->value); - } - - public function equals(MetadataProperty $other) : bool{ - return $other instanceof self and $other->value->equals($this->value); - } -} diff --git a/src/network/mcpe/protocol/types/inventory/ContainerIds.php b/src/network/mcpe/protocol/types/inventory/ContainerIds.php deleted file mode 100644 index 2a4501dc2d..0000000000 --- a/src/network/mcpe/protocol/types/inventory/ContainerIds.php +++ /dev/null @@ -1,43 +0,0 @@ -entryId = $entryId; - $this->item = $item; - } - - public function getEntryId() : int{ return $this->entryId; } - - public function getItem() : ItemStack{ return $this->item; } - - public static function read(PacketSerializer $in) : self{ - $entryId = $in->readGenericTypeNetworkId(); - $item = $in->getItemStackWithoutStackId(); - return new self($entryId, $item); - } - - public function write(PacketSerializer $out) : void{ - $out->writeGenericTypeNetworkId($this->entryId); - $out->putItemStackWithoutStackId($this->item); - } -} diff --git a/src/network/mcpe/protocol/types/inventory/InventoryTransactionChangedSlotsHack.php b/src/network/mcpe/protocol/types/inventory/InventoryTransactionChangedSlotsHack.php deleted file mode 100644 index 4566665019..0000000000 --- a/src/network/mcpe/protocol/types/inventory/InventoryTransactionChangedSlotsHack.php +++ /dev/null @@ -1,65 +0,0 @@ -containerId = $containerId; - $this->changedSlotIndexes = $changedSlotIndexes; - } - - public function getContainerId() : int{ return $this->containerId; } - - /** @return int[] */ - public function getChangedSlotIndexes() : array{ return $this->changedSlotIndexes; } - - public static function read(PacketSerializer $in) : self{ - $containerId = $in->getByte(); - $changedSlots = []; - for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ - $changedSlots[] = $in->getByte(); - } - return new self($containerId, $changedSlots); - } - - public function write(PacketSerializer $out) : void{ - $out->putByte($this->containerId); - $out->putUnsignedVarInt(count($this->changedSlotIndexes)); - foreach($this->changedSlotIndexes as $index){ - $out->putByte($index); - } - } -} diff --git a/src/network/mcpe/protocol/types/inventory/ItemStack.php b/src/network/mcpe/protocol/types/inventory/ItemStack.php deleted file mode 100644 index 2250c33ad3..0000000000 --- a/src/network/mcpe/protocol/types/inventory/ItemStack.php +++ /dev/null @@ -1,142 +0,0 @@ -id = $id; - $this->meta = $meta; - $this->count = $count; - $this->blockRuntimeId = $blockRuntimeId; - $this->canPlaceOn = $canPlaceOn; - $this->canDestroy = $canDestroy; - $this->nbt = $nbt; - $this->shieldBlockingTick = $shieldBlockingTick; - } - - public static function null() : self{ - return new self(0, 0, 0, 0, null, [], [], null); - } - - public function getId() : int{ - return $this->id; - } - - public function getMeta() : int{ - return $this->meta; - } - - public function getCount() : int{ - return $this->count; - } - - public function getBlockRuntimeId() : int{ return $this->blockRuntimeId; } - - /** - * @return string[] - */ - public function getCanPlaceOn() : array{ - return $this->canPlaceOn; - } - - /** - * @return string[] - */ - public function getCanDestroy() : array{ - return $this->canDestroy; - } - - public function getNbt() : ?CompoundTag{ - return $this->nbt; - } - - public function getShieldBlockingTick() : ?int{ - return $this->shieldBlockingTick; - } - - public function equals(ItemStack $itemStack) : bool{ - return - $this->id === $itemStack->id && - $this->meta === $itemStack->meta && - $this->count === $itemStack->count && - $this->blockRuntimeId === $itemStack->blockRuntimeId && - $this->canPlaceOn === $itemStack->canPlaceOn && - $this->canDestroy === $itemStack->canDestroy && - $this->shieldBlockingTick === $itemStack->shieldBlockingTick && ( - $this->nbt === $itemStack->nbt || //this covers null === null and fast object identity - ($this->nbt !== null && $itemStack->nbt !== null && $this->nbt->equals($itemStack->nbt)) - ); - } - - /** @return mixed[] */ - public function jsonSerialize() : array{ - $result = [ - "id" => $this->id, - "meta" => $this->meta, - "count" => $this->count, - "blockRuntimeId" => $this->blockRuntimeId, - ]; - if(count($this->canPlaceOn) > 0){ - $result["canPlaceOn"] = $this->canPlaceOn; - } - if(count($this->canDestroy) > 0){ - $result["canDestroy"] = $this->canDestroy; - } - if($this->shieldBlockingTick !== null){ - $result["shieldBlockingTick"] = $this->shieldBlockingTick; - } - if($this->nbt !== null){ - $result["nbt"] = base64_encode((new NetworkNbtSerializer())->write(new TreeRoot($this->nbt))); - } - return $result; - } -} diff --git a/src/network/mcpe/protocol/types/inventory/ItemStackWrapper.php b/src/network/mcpe/protocol/types/inventory/ItemStackWrapper.php deleted file mode 100644 index 1ed56454d8..0000000000 --- a/src/network/mcpe/protocol/types/inventory/ItemStackWrapper.php +++ /dev/null @@ -1,67 +0,0 @@ -stackId = $stackId; - $this->itemStack = $itemStack; - } - - public static function legacy(ItemStack $itemStack) : self{ - return new self($itemStack->getId() === 0 ? 0 : 1, $itemStack); - } - - public function getStackId() : int{ return $this->stackId; } - - public function getItemStack() : ItemStack{ return $this->itemStack; } - - public static function read(PacketSerializer $in) : self{ - $stackId = 0; - $stack = $in->getItemStack(function(PacketSerializer $in) use (&$stackId) : void{ - $hasNetId = $in->getBool(); - if($hasNetId){ - $stackId = $in->readGenericTypeNetworkId(); - } - }); - return new self($stackId, $stack); - } - - public function write(PacketSerializer $out) : void{ - $out->putItemStack($this->itemStack, function(PacketSerializer $out) : void{ - $out->putBool($this->stackId !== 0); - if($this->stackId !== 0){ - $out->writeGenericTypeNetworkId($this->stackId); - } - }); - } -} diff --git a/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php b/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php deleted file mode 100644 index 66e0c0ff78..0000000000 --- a/src/network/mcpe/protocol/types/inventory/MismatchTransactionData.php +++ /dev/null @@ -1,50 +0,0 @@ -actions) > 0){ - throw new PacketDecodeException("Mismatch transaction type should not have any actions associated with it, but got " . count($this->actions)); - } - } - - protected function encodeData(PacketSerializer $stream) : void{ - - } - - public static function new() : self{ - return new self; //no arguments - } -} diff --git a/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php b/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php deleted file mode 100644 index f966be26dc..0000000000 --- a/src/network/mcpe/protocol/types/inventory/NetworkInventoryAction.php +++ /dev/null @@ -1,138 +0,0 @@ -sourceType = $packet->getUnsignedVarInt(); - - switch($this->sourceType){ - case self::SOURCE_CONTAINER: - $this->windowId = $packet->getVarInt(); - break; - case self::SOURCE_WORLD: - $this->sourceFlags = $packet->getUnsignedVarInt(); - break; - case self::SOURCE_CREATIVE: - break; - case self::SOURCE_TODO: - $this->windowId = $packet->getVarInt(); - break; - default: - throw new PacketDecodeException("Unknown inventory action source type $this->sourceType"); - } - - $this->inventorySlot = $packet->getUnsignedVarInt(); - $this->oldItem = ItemStackWrapper::read($packet); - $this->newItem = ItemStackWrapper::read($packet); - - return $this; - } - - /** - * @throws \InvalidArgumentException - */ - public function write(PacketSerializer $packet) : void{ - $packet->putUnsignedVarInt($this->sourceType); - - switch($this->sourceType){ - case self::SOURCE_CONTAINER: - $packet->putVarInt($this->windowId); - break; - case self::SOURCE_WORLD: - $packet->putUnsignedVarInt($this->sourceFlags); - break; - case self::SOURCE_CREATIVE: - break; - case self::SOURCE_TODO: - $packet->putVarInt($this->windowId); - break; - default: - throw new \InvalidArgumentException("Unknown inventory action source type $this->sourceType"); - } - - $packet->putUnsignedVarInt($this->inventorySlot); - $this->oldItem->write($packet); - $this->newItem->write($packet); - } -} diff --git a/src/network/mcpe/protocol/types/inventory/NormalTransactionData.php b/src/network/mcpe/protocol/types/inventory/NormalTransactionData.php deleted file mode 100644 index 37c2e565dd..0000000000 --- a/src/network/mcpe/protocol/types/inventory/NormalTransactionData.php +++ /dev/null @@ -1,53 +0,0 @@ -actions = $actions; - return $result; - } -} diff --git a/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php b/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php deleted file mode 100644 index 5db088e415..0000000000 --- a/src/network/mcpe/protocol/types/inventory/ReleaseItemTransactionData.php +++ /dev/null @@ -1,90 +0,0 @@ -actionType; - } - - public function getHotbarSlot() : int{ - return $this->hotbarSlot; - } - - public function getItemInHand() : ItemStackWrapper{ - return $this->itemInHand; - } - - public function getHeadPos() : Vector3{ - return $this->headPos; - } - - public function getTypeId() : int{ - return InventoryTransactionPacket::TYPE_RELEASE_ITEM; - } - - protected function decodeData(PacketSerializer $stream) : void{ - $this->actionType = $stream->getUnsignedVarInt(); - $this->hotbarSlot = $stream->getVarInt(); - $this->itemInHand = ItemStackWrapper::read($stream); - $this->headPos = $stream->getVector3(); - } - - protected function encodeData(PacketSerializer $stream) : void{ - $stream->putUnsignedVarInt($this->actionType); - $stream->putVarInt($this->hotbarSlot); - $this->itemInHand->write($stream); - $stream->putVector3($this->headPos); - } - - /** - * @param NetworkInventoryAction[] $actions - */ - public static function new(array $actions, int $actionType, int $hotbarSlot, ItemStackWrapper $itemInHand, Vector3 $headPos) : self{ - $result = new self; - $result->actions = $actions; - $result->actionType = $actionType; - $result->hotbarSlot = $hotbarSlot; - $result->itemInHand = $itemInHand; - $result->headPos = $headPos; - - return $result; - } -} diff --git a/src/network/mcpe/protocol/types/inventory/TransactionData.php b/src/network/mcpe/protocol/types/inventory/TransactionData.php deleted file mode 100644 index ea10fce258..0000000000 --- a/src/network/mcpe/protocol/types/inventory/TransactionData.php +++ /dev/null @@ -1,71 +0,0 @@ -actions; - } - - abstract public function getTypeId() : int; - - /** - * @throws BinaryDataException - * @throws PacketDecodeException - */ - final public function decode(PacketSerializer $stream) : void{ - $actionCount = $stream->getUnsignedVarInt(); - for($i = 0; $i < $actionCount; ++$i){ - $this->actions[] = (new NetworkInventoryAction())->read($stream); - } - $this->decodeData($stream); - } - - /** - * @throws BinaryDataException - * @throws PacketDecodeException - */ - abstract protected function decodeData(PacketSerializer $stream) : void; - - final public function encode(PacketSerializer $stream) : void{ - $stream->putUnsignedVarInt(count($this->actions)); - foreach($this->actions as $action){ - $action->write($stream); - } - $this->encodeData($stream); - } - - abstract protected function encodeData(PacketSerializer $stream) : void; -} diff --git a/src/network/mcpe/protocol/types/inventory/UIInventorySlotOffset.php b/src/network/mcpe/protocol/types/inventory/UIInventorySlotOffset.php deleted file mode 100644 index 12e2c60eb7..0000000000 --- a/src/network/mcpe/protocol/types/inventory/UIInventorySlotOffset.php +++ /dev/null @@ -1,105 +0,0 @@ - 0, - 2 => 1, - ]; - public const STONE_CUTTER_INPUT = 3; - public const TRADE2_INGREDIENT = [ - 4 => 0, - 5 => 1, - ]; - public const TRADE_INGREDIENT = [ - 6 => 0, - 7 => 1, - ]; - public const MATERIAL_REDUCER_INPUT = 8; - public const LOOM = [ - 9 => 0, - 10 => 1, - 11 => 2, - ]; - public const CARTOGRAPHY_TABLE = [ - 12 => 0, - 13 => 1, - ]; - public const ENCHANTING_TABLE = [ - 14 => 0, - 15 => 1, - ]; - public const GRINDSTONE = [ - 16 => 0, - 17 => 1, - ]; - public const COMPOUND_CREATOR_INPUT = [ - 18 => 0, - 19 => 1, - 20 => 2, - 21 => 3, - 22 => 4, - 23 => 5, - 24 => 6, - 25 => 7, - 26 => 8, - ]; - public const BEACON_PAYMENT = 27; - public const CRAFTING2X2_INPUT = [ - 28 => 0, - 29 => 1, - 30 => 2, - 31 => 3, - ]; - public const CRAFTING3X3_INPUT = [ - 32 => 0, - 33 => 1, - 34 => 2, - 35 => 3, - 36 => 4, - 37 => 5, - 38 => 6, - 39 => 7, - 40 => 8, - ]; - public const MATERIAL_REDUCER_OUTPUT = [ - 41 => 0, - 42 => 1, - 43 => 2, - 44 => 3, - 45 => 4, - 46 => 5, - 47 => 6, - 48 => 7, - 49 => 8, - ]; - public const CREATED_ITEM_OUTPUT = 50; -} diff --git a/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php b/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php deleted file mode 100644 index 857df5e605..0000000000 --- a/src/network/mcpe/protocol/types/inventory/UseItemOnEntityTransactionData.php +++ /dev/null @@ -1,108 +0,0 @@ -entityRuntimeId; - } - - public function getActionType() : int{ - return $this->actionType; - } - - public function getHotbarSlot() : int{ - return $this->hotbarSlot; - } - - public function getItemInHand() : ItemStackWrapper{ - return $this->itemInHand; - } - - public function getPlayerPos() : Vector3{ - return $this->playerPos; - } - - public function getClickPos() : Vector3{ - return $this->clickPos; - } - - public function getTypeId() : int{ - return InventoryTransactionPacket::TYPE_USE_ITEM_ON_ENTITY; - } - - protected function decodeData(PacketSerializer $stream) : void{ - $this->entityRuntimeId = $stream->getEntityRuntimeId(); - $this->actionType = $stream->getUnsignedVarInt(); - $this->hotbarSlot = $stream->getVarInt(); - $this->itemInHand = ItemStackWrapper::read($stream); - $this->playerPos = $stream->getVector3(); - $this->clickPos = $stream->getVector3(); - } - - protected function encodeData(PacketSerializer $stream) : void{ - $stream->putEntityRuntimeId($this->entityRuntimeId); - $stream->putUnsignedVarInt($this->actionType); - $stream->putVarInt($this->hotbarSlot); - $this->itemInHand->write($stream); - $stream->putVector3($this->playerPos); - $stream->putVector3($this->clickPos); - } - - /** - * @param NetworkInventoryAction[] $actions - */ - public static function new(array $actions, int $entityRuntimeId, int $actionType, int $hotbarSlot, ItemStackWrapper $itemInHand, Vector3 $playerPos, Vector3 $clickPos) : self{ - $result = new self; - $result->actions = $actions; - $result->entityRuntimeId = $entityRuntimeId; - $result->actionType = $actionType; - $result->hotbarSlot = $hotbarSlot; - $result->itemInHand = $itemInHand; - $result->playerPos = $playerPos; - $result->clickPos = $clickPos; - return $result; - } -} diff --git a/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php b/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php deleted file mode 100644 index 0a425e9d6f..0000000000 --- a/src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php +++ /dev/null @@ -1,128 +0,0 @@ -actionType; - } - - public function getBlockPos() : Vector3{ - return $this->blockPos; - } - - public function getFace() : int{ - return $this->face; - } - - public function getHotbarSlot() : int{ - return $this->hotbarSlot; - } - - public function getItemInHand() : ItemStackWrapper{ - return $this->itemInHand; - } - - public function getPlayerPos() : Vector3{ - return $this->playerPos; - } - - public function getClickPos() : Vector3{ - return $this->clickPos; - } - - public function getBlockRuntimeId() : int{ - return $this->blockRuntimeId; - } - - public function getTypeId() : int{ - return InventoryTransactionPacket::TYPE_USE_ITEM; - } - - protected function decodeData(PacketSerializer $stream) : void{ - $this->actionType = $stream->getUnsignedVarInt(); - $x = $y = $z = 0; - $stream->getBlockPosition($x, $y, $z); - $this->blockPos = new Vector3($x, $y, $z); - $this->face = $stream->getVarInt(); - $this->hotbarSlot = $stream->getVarInt(); - $this->itemInHand = ItemStackWrapper::read($stream); - $this->playerPos = $stream->getVector3(); - $this->clickPos = $stream->getVector3(); - $this->blockRuntimeId = $stream->getUnsignedVarInt(); - } - - protected function encodeData(PacketSerializer $stream) : void{ - $stream->putUnsignedVarInt($this->actionType); - $stream->putBlockPosition($this->blockPos->x, $this->blockPos->y, $this->blockPos->z); - $stream->putVarInt($this->face); - $stream->putVarInt($this->hotbarSlot); - $this->itemInHand->write($stream); - $stream->putVector3($this->playerPos); - $stream->putVector3($this->clickPos); - $stream->putUnsignedVarInt($this->blockRuntimeId); - } - - /** - * @param NetworkInventoryAction[] $actions - */ - public static function new(array $actions, int $actionType, Vector3 $blockPos, int $face, int $hotbarSlot, ItemStackWrapper $itemInHand, Vector3 $playerPos, Vector3 $clickPos, int $blockRuntimeId) : self{ - $result = new self; - $result->actions = $actions; - $result->actionType = $actionType; - $result->blockPos = $blockPos; - $result->face = $face; - $result->hotbarSlot = $hotbarSlot; - $result->itemInHand = $itemInHand; - $result->playerPos = $playerPos; - $result->clickPos = $clickPos; - $result->blockRuntimeId = $blockRuntimeId; - return $result; - } -} diff --git a/src/network/mcpe/protocol/types/inventory/WindowTypes.php b/src/network/mcpe/protocol/types/inventory/WindowTypes.php deleted file mode 100644 index c20f806015..0000000000 --- a/src/network/mcpe/protocol/types/inventory/WindowTypes.php +++ /dev/null @@ -1,70 +0,0 @@ -primaryEffectId = $primaryEffectId; - $this->secondaryEffectId = $secondaryEffectId; - } - - public function getPrimaryEffectId() : int{ return $this->primaryEffectId; } - - public function getSecondaryEffectId() : int{ return $this->secondaryEffectId; } - - public static function getTypeId() : int{ return ItemStackRequestActionType::BEACON_PAYMENT; } - - public static function read(PacketSerializer $in) : self{ - $primary = $in->getVarInt(); - $secondary = $in->getVarInt(); - return new self($primary, $secondary); - } - - public function write(PacketSerializer $out) : void{ - $out->putVarInt($this->primaryEffectId); - $out->putVarInt($this->secondaryEffectId); - } -} diff --git a/src/network/mcpe/protocol/types/inventory/stackrequest/CraftRecipeAutoStackRequestAction.php b/src/network/mcpe/protocol/types/inventory/stackrequest/CraftRecipeAutoStackRequestAction.php deleted file mode 100644 index d5f10ee1f1..0000000000 --- a/src/network/mcpe/protocol/types/inventory/stackrequest/CraftRecipeAutoStackRequestAction.php +++ /dev/null @@ -1,34 +0,0 @@ -recipeId = $type; - $this->filterStringIndex = $filterStringIndex; - } - - public function getRecipeId() : int{ return $this->recipeId; } - - public function getFilterStringIndex() : int{ return $this->filterStringIndex; } - - public static function getTypeId() : int{ return ItemStackRequestActionType::CRAFTING_RECIPE_OPTIONAL; } - - public static function read(PacketSerializer $in) : self{ - $recipeId = $in->readGenericTypeNetworkId(); - $filterStringIndex = $in->getLInt(); - return new self($recipeId, $filterStringIndex); - } - - public function write(PacketSerializer $out) : void{ - $out->writeGenericTypeNetworkId($this->recipeId); - $out->putLInt($this->filterStringIndex); - } -} diff --git a/src/network/mcpe/protocol/types/inventory/stackrequest/CraftRecipeStackRequestAction.php b/src/network/mcpe/protocol/types/inventory/stackrequest/CraftRecipeStackRequestAction.php deleted file mode 100644 index 6341aecc59..0000000000 --- a/src/network/mcpe/protocol/types/inventory/stackrequest/CraftRecipeStackRequestAction.php +++ /dev/null @@ -1,33 +0,0 @@ -recipeId = $recipeId; - } - - public function getRecipeId() : int{ return $this->recipeId; } - - public static function read(PacketSerializer $in) : self{ - $recipeId = $in->readGenericTypeNetworkId(); - return new self($recipeId); - } - - public function write(PacketSerializer $out) : void{ - $out->writeGenericTypeNetworkId($this->recipeId); - } -} diff --git a/src/network/mcpe/protocol/types/inventory/stackrequest/CraftingConsumeInputStackRequestAction.php b/src/network/mcpe/protocol/types/inventory/stackrequest/CraftingConsumeInputStackRequestAction.php deleted file mode 100644 index 26f85f7a79..0000000000 --- a/src/network/mcpe/protocol/types/inventory/stackrequest/CraftingConsumeInputStackRequestAction.php +++ /dev/null @@ -1,33 +0,0 @@ -craftingGridSlot = $craftingGridSlot; - } - - public function getCraftingGridSlot() : int{ return $this->craftingGridSlot; } - - public static function getTypeId() : int{ return ItemStackRequestActionType::CRAFTING_MARK_SECONDARY_RESULT_SLOT; } - - public static function read(PacketSerializer $in) : self{ - $slot = $in->getByte(); - return new self($slot); - } - - public function write(PacketSerializer $out) : void{ - $out->putByte($this->craftingGridSlot); - } -} diff --git a/src/network/mcpe/protocol/types/inventory/stackrequest/CreativeCreateStackRequestAction.php b/src/network/mcpe/protocol/types/inventory/stackrequest/CreativeCreateStackRequestAction.php deleted file mode 100644 index e84975afa7..0000000000 --- a/src/network/mcpe/protocol/types/inventory/stackrequest/CreativeCreateStackRequestAction.php +++ /dev/null @@ -1,52 +0,0 @@ -creativeItemId = $creativeItemId; - } - - public function getCreativeItemId() : int{ return $this->creativeItemId; } - - public static function getTypeId() : int{ return ItemStackRequestActionType::CREATIVE_CREATE; } - - public static function read(PacketSerializer $in) : self{ - $creativeItemId = $in->readGenericTypeNetworkId(); - return new self($creativeItemId); - } - - public function write(PacketSerializer $out) : void{ - $out->writeGenericTypeNetworkId($this->creativeItemId); - } -} diff --git a/src/network/mcpe/protocol/types/inventory/stackrequest/DeprecatedCraftingNonImplementedStackRequestAction.php b/src/network/mcpe/protocol/types/inventory/stackrequest/DeprecatedCraftingNonImplementedStackRequestAction.php deleted file mode 100644 index 5ec79617ac..0000000000 --- a/src/network/mcpe/protocol/types/inventory/stackrequest/DeprecatedCraftingNonImplementedStackRequestAction.php +++ /dev/null @@ -1,45 +0,0 @@ -results = $results; - $this->iterations = $iterations; - } - - /** @return ItemStack[] */ - public function getResults() : array{ return $this->results; } - - public function getIterations() : int{ return $this->iterations; } - - public static function getTypeId() : int{ - return ItemStackRequestActionType::CRAFTING_RESULTS_DEPRECATED_ASK_TY_LAING; - } - - public static function read(PacketSerializer $in) : self{ - $results = []; - for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ - $results[] = $in->getItemStackWithoutStackId(); - } - $iterations = $in->getByte(); - return new self($results, $iterations); - } - - public function write(PacketSerializer $out) : void{ - $out->putUnsignedVarInt(count($this->results)); - foreach($this->results as $result){ - $out->putItemStackWithoutStackId($result); - } - $out->putByte($this->iterations); - } -} diff --git a/src/network/mcpe/protocol/types/inventory/stackrequest/DestroyStackRequestAction.php b/src/network/mcpe/protocol/types/inventory/stackrequest/DestroyStackRequestAction.php deleted file mode 100644 index 36f55e9a49..0000000000 --- a/src/network/mcpe/protocol/types/inventory/stackrequest/DestroyStackRequestAction.php +++ /dev/null @@ -1,34 +0,0 @@ -count = $count; - $this->source = $source; - } - - final public function getCount() : int{ return $this->count; } - - final public function getSource() : ItemStackRequestSlotInfo{ return $this->source; } - - public static function read(PacketSerializer $in) : self{ - $count = $in->getByte(); - $source = ItemStackRequestSlotInfo::read($in); - return new self($count, $source); - } - - public function write(PacketSerializer $out) : void{ - $out->putByte($this->count); - $this->source->write($out); - } -} diff --git a/src/network/mcpe/protocol/types/inventory/stackrequest/DropStackRequestAction.php b/src/network/mcpe/protocol/types/inventory/stackrequest/DropStackRequestAction.php deleted file mode 100644 index 6a48578055..0000000000 --- a/src/network/mcpe/protocol/types/inventory/stackrequest/DropStackRequestAction.php +++ /dev/null @@ -1,66 +0,0 @@ -count = $count; - $this->source = $source; - $this->randomly = $randomly; - } - - public function getCount() : int{ return $this->count; } - - public function getSource() : ItemStackRequestSlotInfo{ return $this->source; } - - public function isRandomly() : bool{ return $this->randomly; } - - public static function getTypeId() : int{ return ItemStackRequestActionType::DROP; } - - public static function read(PacketSerializer $in) : self{ - $count = $in->getByte(); - $source = ItemStackRequestSlotInfo::read($in); - $random = $in->getBool(); - return new self($count, $source, $random); - } - - public function write(PacketSerializer $out) : void{ - $out->putByte($this->count); - $this->source->write($out); - $out->putBool($this->randomly); - } -} diff --git a/src/network/mcpe/protocol/types/inventory/stackrequest/ItemStackRequest.php b/src/network/mcpe/protocol/types/inventory/stackrequest/ItemStackRequest.php deleted file mode 100644 index 82ac464f11..0000000000 --- a/src/network/mcpe/protocol/types/inventory/stackrequest/ItemStackRequest.php +++ /dev/null @@ -1,110 +0,0 @@ - - */ - private $filterStrings; - - /** - * @param ItemStackRequestAction[] $actions - * @param string[] $filterStrings - * @phpstan-param list $filterStrings - */ - public function __construct(int $requestId, array $actions, array $filterStrings){ - $this->requestId = $requestId; - $this->actions = $actions; - $this->filterStrings = $filterStrings; - } - - public function getRequestId() : int{ return $this->requestId; } - - /** @return ItemStackRequestAction[] */ - public function getActions() : array{ return $this->actions; } - - /** - * @return string[] - * @phpstan-return list - */ - public function getFilterStrings() : array{ return $this->filterStrings; } - private static function readAction(PacketSerializer $in, int $typeId) : ItemStackRequestAction{ - switch($typeId){ - case TakeStackRequestAction::getTypeId(): return TakeStackRequestAction::read($in); - case PlaceStackRequestAction::getTypeId(): return PlaceStackRequestAction::read($in); - case SwapStackRequestAction::getTypeId(): return SwapStackRequestAction::read($in); - case DropStackRequestAction::getTypeId(): return DropStackRequestAction::read($in); - case DestroyStackRequestAction::getTypeId(): return DestroyStackRequestAction::read($in); - case CraftingConsumeInputStackRequestAction::getTypeId(): return CraftingConsumeInputStackRequestAction::read($in); - case CraftingMarkSecondaryResultStackRequestAction::getTypeId(): return CraftingMarkSecondaryResultStackRequestAction::read($in); - case LabTableCombineStackRequestAction::getTypeId(): return LabTableCombineStackRequestAction::read($in); - case BeaconPaymentStackRequestAction::getTypeId(): return BeaconPaymentStackRequestAction::read($in); - case MineBlockStackRequestAction::getTypeId(): return MineBlockStackRequestAction::read($in); - case CraftRecipeStackRequestAction::getTypeId(): return CraftRecipeStackRequestAction::read($in); - case CraftRecipeAutoStackRequestAction::getTypeId(): return CraftRecipeAutoStackRequestAction::read($in); - case CreativeCreateStackRequestAction::getTypeId(): return CreativeCreateStackRequestAction::read($in); - case CraftRecipeOptionalStackRequestAction::getTypeId(): return CraftRecipeOptionalStackRequestAction::read($in); - case DeprecatedCraftingNonImplementedStackRequestAction::getTypeId(): return DeprecatedCraftingNonImplementedStackRequestAction::read($in); - case DeprecatedCraftingResultsStackRequestAction::getTypeId(): return DeprecatedCraftingResultsStackRequestAction::read($in); - } - throw new \UnexpectedValueException("Unhandled item stack request action type $typeId"); - } - - public static function read(PacketSerializer $in) : self{ - $requestId = $in->readGenericTypeNetworkId(); - $actions = []; - for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ - $typeId = $in->getByte(); - $actions[] = self::readAction($in, $typeId); - } - $filterStrings = []; - for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ - $filterStrings[] = $in->getString(); - } - return new self($requestId, $actions, $filterStrings); - } - - public function write(PacketSerializer $out) : void{ - $out->writeGenericTypeNetworkId($this->requestId); - $out->putUnsignedVarInt(count($this->actions)); - foreach($this->actions as $action){ - $out->putByte($action::getTypeId()); - $action->write($out); - } - $out->putUnsignedVarInt(count($this->filterStrings)); - foreach($this->filterStrings as $string){ - $out->putString($string); - } - } -} diff --git a/src/network/mcpe/protocol/types/inventory/stackrequest/ItemStackRequestAction.php b/src/network/mcpe/protocol/types/inventory/stackrequest/ItemStackRequestAction.php deleted file mode 100644 index bd56a07970..0000000000 --- a/src/network/mcpe/protocol/types/inventory/stackrequest/ItemStackRequestAction.php +++ /dev/null @@ -1,33 +0,0 @@ -containerId = $containerId; - $this->slotId = $slotId; - $this->stackId = $stackId; - } - - public function getContainerId() : int{ return $this->containerId; } - - public function getSlotId() : int{ return $this->slotId; } - - public function getStackId() : int{ return $this->stackId; } - - public static function read(PacketSerializer $in) : self{ - $containerId = $in->getByte(); - $slotId = $in->getByte(); - $stackId = $in->readGenericTypeNetworkId(); - return new self($containerId, $slotId, $stackId); - } - - public function write(PacketSerializer $out) : void{ - $out->putByte($this->containerId); - $out->putByte($this->slotId); - $out->writeGenericTypeNetworkId($this->stackId); - } -} diff --git a/src/network/mcpe/protocol/types/inventory/stackrequest/LabTableCombineStackRequestAction.php b/src/network/mcpe/protocol/types/inventory/stackrequest/LabTableCombineStackRequestAction.php deleted file mode 100644 index 8ea896a824..0000000000 --- a/src/network/mcpe/protocol/types/inventory/stackrequest/LabTableCombineStackRequestAction.php +++ /dev/null @@ -1,43 +0,0 @@ -unknown1 = $unknown1; - $this->predictedDurability = $predictedDurability; - $this->stackId = $stackId; - } - - public function getUnknown1() : int{ return $this->unknown1; } - - public function getPredictedDurability() : int{ return $this->predictedDurability; } - - public function getStackId() : int{ return $this->stackId; } - - public static function getTypeId() : int{ return ItemStackRequestActionType::MINE_BLOCK; } - - public static function read(PacketSerializer $in) : self{ - $unknown1 = $in->getVarInt(); - $predictedDurability = $in->getVarInt(); - $stackId = $in->readGenericTypeNetworkId(); - return new self($unknown1, $predictedDurability, $stackId); - } - - public function write(PacketSerializer $out) : void{ - $out->putVarInt($this->unknown1); - $out->putVarInt($this->predictedDurability); - $out->writeGenericTypeNetworkId($this->stackId); - } -} diff --git a/src/network/mcpe/protocol/types/inventory/stackrequest/PlaceStackRequestAction.php b/src/network/mcpe/protocol/types/inventory/stackrequest/PlaceStackRequestAction.php deleted file mode 100644 index 2fa453e1b8..0000000000 --- a/src/network/mcpe/protocol/types/inventory/stackrequest/PlaceStackRequestAction.php +++ /dev/null @@ -1,33 +0,0 @@ -slot1 = $slot1; - $this->slot2 = $slot2; - } - - public function getSlot1() : ItemStackRequestSlotInfo{ return $this->slot1; } - - public function getSlot2() : ItemStackRequestSlotInfo{ return $this->slot2; } - - public static function getTypeId() : int{ return ItemStackRequestActionType::SWAP; } - - public static function read(PacketSerializer $in) : self{ - $slot1 = ItemStackRequestSlotInfo::read($in); - $slot2 = ItemStackRequestSlotInfo::read($in); - return new self($slot1, $slot2); - } - - public function write(PacketSerializer $out) : void{ - $this->slot1->write($out); - $this->slot2->write($out); - } -} diff --git a/src/network/mcpe/protocol/types/inventory/stackrequest/TakeOrPlaceStackRequestActionTrait.php b/src/network/mcpe/protocol/types/inventory/stackrequest/TakeOrPlaceStackRequestActionTrait.php deleted file mode 100644 index 2866c641de..0000000000 --- a/src/network/mcpe/protocol/types/inventory/stackrequest/TakeOrPlaceStackRequestActionTrait.php +++ /dev/null @@ -1,61 +0,0 @@ -count = $count; - $this->source = $source; - $this->destination = $destination; - } - - final public function getCount() : int{ return $this->count; } - - final public function getSource() : ItemStackRequestSlotInfo{ return $this->source; } - - final public function getDestination() : ItemStackRequestSlotInfo{ return $this->destination; } - - public static function read(PacketSerializer $in) : self{ - $count = $in->getByte(); - $src = ItemStackRequestSlotInfo::read($in); - $dst = ItemStackRequestSlotInfo::read($in); - return new self($count, $src, $dst); - } - - public function write(PacketSerializer $out) : void{ - $out->putByte($this->count); - $this->source->write($out); - $this->destination->write($out); - } -} diff --git a/src/network/mcpe/protocol/types/inventory/stackrequest/TakeStackRequestAction.php b/src/network/mcpe/protocol/types/inventory/stackrequest/TakeStackRequestAction.php deleted file mode 100644 index f2946def27..0000000000 --- a/src/network/mcpe/protocol/types/inventory/stackrequest/TakeStackRequestAction.php +++ /dev/null @@ -1,33 +0,0 @@ -result = $result; - $this->requestId = $requestId; - $this->containerInfos = $containerInfos; - } - - public function getResult() : int{ return $this->result; } - - public function getRequestId() : int{ return $this->requestId; } - - /** @return ItemStackResponseContainerInfo[] */ - public function getContainerInfos() : array{ return $this->containerInfos; } - - public static function read(PacketSerializer $in) : self{ - $result = $in->getByte(); - $requestId = $in->readGenericTypeNetworkId(); - $containerInfos = []; - for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ - $containerInfos[] = ItemStackResponseContainerInfo::read($in); - } - return new self($result, $requestId, $containerInfos); - } - - public function write(PacketSerializer $out) : void{ - $out->putByte($this->result); - $out->writeGenericTypeNetworkId($this->requestId); - $out->putUnsignedVarInt(count($this->containerInfos)); - foreach($this->containerInfos as $containerInfo){ - $containerInfo->write($out); - } - } -} diff --git a/src/network/mcpe/protocol/types/inventory/stackresponse/ItemStackResponseContainerInfo.php b/src/network/mcpe/protocol/types/inventory/stackresponse/ItemStackResponseContainerInfo.php deleted file mode 100644 index 3678c84d89..0000000000 --- a/src/network/mcpe/protocol/types/inventory/stackresponse/ItemStackResponseContainerInfo.php +++ /dev/null @@ -1,65 +0,0 @@ -containerId = $containerId; - $this->slots = $slots; - } - - public function getContainerId() : int{ return $this->containerId; } - - /** @return ItemStackResponseSlotInfo[] */ - public function getSlots() : array{ return $this->slots; } - - public static function read(PacketSerializer $in) : self{ - $containerId = $in->getByte(); - $slots = []; - for($i = 0, $len = $in->getUnsignedVarInt(); $i < $len; ++$i){ - $slots[] = ItemStackResponseSlotInfo::read($in); - } - return new self($containerId, $slots); - } - - public function write(PacketSerializer $out) : void{ - $out->putByte($this->containerId); - $out->putUnsignedVarInt(count($this->slots)); - foreach($this->slots as $slot){ - $slot->write($out); - } - } -} diff --git a/src/network/mcpe/protocol/types/inventory/stackresponse/ItemStackResponseSlotInfo.php b/src/network/mcpe/protocol/types/inventory/stackresponse/ItemStackResponseSlotInfo.php deleted file mode 100644 index 05ae10b4cc..0000000000 --- a/src/network/mcpe/protocol/types/inventory/stackresponse/ItemStackResponseSlotInfo.php +++ /dev/null @@ -1,82 +0,0 @@ -slot = $slot; - $this->hotbarSlot = $hotbarSlot; - $this->count = $count; - $this->itemStackId = $itemStackId; - $this->customName = $customName; - $this->durabilityCorrection = $durabilityCorrection; - } - - public function getSlot() : int{ return $this->slot; } - - public function getHotbarSlot() : int{ return $this->hotbarSlot; } - - public function getCount() : int{ return $this->count; } - - public function getItemStackId() : int{ return $this->itemStackId; } - - public function getCustomName() : string{ return $this->customName; } - - public function getDurabilityCorrection() : int{ return $this->durabilityCorrection; } - - public static function read(PacketSerializer $in) : self{ - $slot = $in->getByte(); - $hotbarSlot = $in->getByte(); - $count = $in->getByte(); - $itemStackId = $in->readGenericTypeNetworkId(); - $customName = $in->getString(); - $durabilityCorrection = $in->getVarInt(); - return new self($slot, $hotbarSlot, $count, $itemStackId, $customName, $durabilityCorrection); - } - - public function write(PacketSerializer $out) : void{ - $out->putByte($this->slot); - $out->putByte($this->hotbarSlot); - $out->putByte($this->count); - $out->writeGenericTypeNetworkId($this->itemStackId); - $out->putString($this->customName); - $out->putVarInt($this->durabilityCorrection); - } -} diff --git a/src/network/mcpe/protocol/types/login/AuthenticationData.php b/src/network/mcpe/protocol/types/login/AuthenticationData.php deleted file mode 100644 index 535d8ca43d..0000000000 --- a/src/network/mcpe/protocol/types/login/AuthenticationData.php +++ /dev/null @@ -1,41 +0,0 @@ -AnimatedImageData as $k => $animation){ - $animations[] = new SkinAnimation( - new SkinImage( - $animation->ImageHeight, - $animation->ImageWidth, - self::safeB64Decode($animation->Image, "AnimatedImageData.$k.Image") - ), - $animation->Type, - $animation->Frames, - $animation->AnimationExpression - ); - } - return new SkinData( - $clientData->SkinId, - $clientData->PlayFabId, - self::safeB64Decode($clientData->SkinResourcePatch, "SkinResourcePatch"), - new SkinImage($clientData->SkinImageHeight, $clientData->SkinImageWidth, self::safeB64Decode($clientData->SkinData, "SkinData")), - $animations, - new SkinImage($clientData->CapeImageHeight, $clientData->CapeImageWidth, self::safeB64Decode($clientData->CapeData, "CapeData")), - self::safeB64Decode($clientData->SkinGeometryData, "SkinGeometryData"), - self::safeB64Decode($clientData->SkinAnimationData, "SkinAnimationData"), - $clientData->PremiumSkin, - $clientData->PersonaSkin, - $clientData->CapeOnClassicSkin, - $clientData->CapeId, - null, - $clientData->ArmSize, - $clientData->SkinColor, - array_map(function(ClientDataPersonaSkinPiece $piece) : PersonaSkinPiece{ - return new PersonaSkinPiece($piece->PieceId, $piece->PieceType, $piece->PackId, $piece->IsDefault, $piece->ProductId); - }, $clientData->PersonaPieces), - array_map(function(ClientDataPersonaPieceTintColor $tint) : PersonaPieceTintColor{ - return new PersonaPieceTintColor($tint->PieceType, $tint->Colors); - }, $clientData->PieceTintColors) - ); - } -} \ No newline at end of file diff --git a/src/network/mcpe/protocol/types/login/JwtBodyRfc7519.php b/src/network/mcpe/protocol/types/login/JwtBodyRfc7519.php deleted file mode 100644 index b048e2d9fa..0000000000 --- a/src/network/mcpe/protocol/types/login/JwtBodyRfc7519.php +++ /dev/null @@ -1,39 +0,0 @@ -inputId = $inputId; - $this->inputMeta = $inputMeta; - $this->result = $result; - $this->blockName = $blockName; - } - - public function getInputId() : int{ - return $this->inputId; - } - - public function getInputMeta() : ?int{ - return $this->inputMeta; - } - - public function getResult() : ItemStack{ - return $this->result; - } - - public function getBlockName() : string{ - return $this->blockName; - } - - public static function decode(int $typeId, PacketSerializer $in) : self{ - $inputId = $in->getVarInt(); - $inputData = null; - if($typeId === CraftingDataPacket::ENTRY_FURNACE_DATA){ - $inputData = $in->getVarInt(); - } - $output = $in->getItemStackWithoutStackId(); - $block = $in->getString(); - - return new self($typeId, $inputId, $inputData, $output, $block); - } - - public function encode(PacketSerializer $out) : void{ - $out->putVarInt($this->inputId); - if($this->getTypeId() === CraftingDataPacket::ENTRY_FURNACE_DATA){ - $out->putVarInt($this->inputMeta); - } - $out->putItemStackWithoutStackId($this->result); - $out->putString($this->blockName); - } -} diff --git a/src/network/mcpe/protocol/types/recipe/MultiRecipe.php b/src/network/mcpe/protocol/types/recipe/MultiRecipe.php deleted file mode 100644 index 52b5276ebc..0000000000 --- a/src/network/mcpe/protocol/types/recipe/MultiRecipe.php +++ /dev/null @@ -1,73 +0,0 @@ -recipeId = $recipeId; - $this->recipeNetId = $recipeNetId; - } - - public function getRecipeId() : UuidInterface{ - return $this->recipeId; - } - - public function getRecipeNetId() : int{ - return $this->recipeNetId; - } - - public static function decode(int $typeId, PacketSerializer $in) : self{ - $uuid = $in->getUUID(); - $recipeNetId = $in->readGenericTypeNetworkId(); - return new self($typeId, $uuid, $recipeNetId); - } - - public function encode(PacketSerializer $out) : void{ - $out->putUUID($this->recipeId); - $out->writeGenericTypeNetworkId($this->recipeNetId); - } -} diff --git a/src/network/mcpe/protocol/types/recipe/PotionContainerChangeRecipe.php b/src/network/mcpe/protocol/types/recipe/PotionContainerChangeRecipe.php deleted file mode 100644 index eb0bb65320..0000000000 --- a/src/network/mcpe/protocol/types/recipe/PotionContainerChangeRecipe.php +++ /dev/null @@ -1,51 +0,0 @@ -inputItemId = $inputItemId; - $this->ingredientItemId = $ingredientItemId; - $this->outputItemId = $outputItemId; - } - - public function getInputItemId() : int{ - return $this->inputItemId; - } - - public function getIngredientItemId() : int{ - return $this->ingredientItemId; - } - - public function getOutputItemId() : int{ - return $this->outputItemId; - } -} diff --git a/src/network/mcpe/protocol/types/recipe/PotionTypeRecipe.php b/src/network/mcpe/protocol/types/recipe/PotionTypeRecipe.php deleted file mode 100644 index 31628ac4c9..0000000000 --- a/src/network/mcpe/protocol/types/recipe/PotionTypeRecipe.php +++ /dev/null @@ -1,72 +0,0 @@ -inputItemId = $inputItemId; - $this->inputItemMeta = $inputItemMeta; - $this->ingredientItemId = $ingredientItemId; - $this->ingredientItemMeta = $ingredientItemMeta; - $this->outputItemId = $outputItemId; - $this->outputItemMeta = $outputItemMeta; - } - - public function getInputItemId() : int{ - return $this->inputItemId; - } - - public function getInputItemMeta() : int{ - return $this->inputItemMeta; - } - - public function getIngredientItemId() : int{ - return $this->ingredientItemId; - } - - public function getIngredientItemMeta() : int{ - return $this->ingredientItemMeta; - } - - public function getOutputItemId() : int{ - return $this->outputItemId; - } - - public function getOutputItemMeta() : int{ - return $this->outputItemMeta; - } -} diff --git a/src/network/mcpe/protocol/types/recipe/RecipeIngredient.php b/src/network/mcpe/protocol/types/recipe/RecipeIngredient.php deleted file mode 100644 index 1349e26343..0000000000 --- a/src/network/mcpe/protocol/types/recipe/RecipeIngredient.php +++ /dev/null @@ -1,52 +0,0 @@ -id = $id; - $this->meta = $meta; - $this->count = $count; - } - - public function getId() : int{ - return $this->id; - } - - public function getMeta() : int{ - return $this->meta; - } - - public function getCount() : int{ - return $this->count; - } -} diff --git a/src/network/mcpe/protocol/types/recipe/RecipeWithTypeId.php b/src/network/mcpe/protocol/types/recipe/RecipeWithTypeId.php deleted file mode 100644 index 9171f52bc6..0000000000 --- a/src/network/mcpe/protocol/types/recipe/RecipeWithTypeId.php +++ /dev/null @@ -1,41 +0,0 @@ -typeId = $typeId; - } - - final public function getTypeId() : int{ - return $this->typeId; - } - - abstract public function encode(PacketSerializer $out) : void; -} diff --git a/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php b/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php deleted file mode 100644 index 55f10bdc50..0000000000 --- a/src/network/mcpe/protocol/types/recipe/ShapedRecipe.php +++ /dev/null @@ -1,160 +0,0 @@ - 3){ - throw new \InvalidArgumentException("Expected 1, 2 or 3 input rows"); - } - $columns = null; - foreach($input as $rowNumber => $row){ - if($columns === null){ - $columns = count($row); - }elseif(count($row) !== $columns){ - throw new \InvalidArgumentException("Expected each row to be $columns columns, but have " . count($row) . " in row $rowNumber"); - } - } - $this->recipeId = $recipeId; - $this->input = $input; - $this->output = $output; - $this->blockName = $blockType; - $this->priority = $priority; - $this->uuid = $uuid; - $this->recipeNetId = $recipeNetId; - } - - public function getRecipeId() : string{ - return $this->recipeId; - } - - public function getWidth() : int{ - return count($this->input[0]); - } - - public function getHeight() : int{ - return count($this->input); - } - - /** - * @return RecipeIngredient[][] - */ - public function getInput() : array{ - return $this->input; - } - - /** - * @return ItemStack[] - */ - public function getOutput() : array{ - return $this->output; - } - - public function getUuid() : UuidInterface{ - return $this->uuid; - } - - public function getBlockName() : string{ - return $this->blockName; - } - - public function getPriority() : int{ - return $this->priority; - } - - public function getRecipeNetId() : int{ - return $this->recipeNetId; - } - - public static function decode(int $recipeType, PacketSerializer $in) : self{ - $recipeId = $in->getString(); - $width = $in->getVarInt(); - $height = $in->getVarInt(); - $input = []; - for($row = 0; $row < $height; ++$row){ - for($column = 0; $column < $width; ++$column){ - $input[$row][$column] = $in->getRecipeIngredient(); - } - } - - $output = []; - for($k = 0, $resultCount = $in->getUnsignedVarInt(); $k < $resultCount; ++$k){ - $output[] = $in->getItemStackWithoutStackId(); - } - $uuid = $in->getUUID(); - $block = $in->getString(); - $priority = $in->getVarInt(); - $recipeNetId = $in->readGenericTypeNetworkId(); - - return new self($recipeType, $recipeId, $input, $output, $uuid, $block, $priority, $recipeNetId); - } - - public function encode(PacketSerializer $out) : void{ - $out->putString($this->recipeId); - $out->putVarInt($this->getWidth()); - $out->putVarInt($this->getHeight()); - foreach($this->input as $row){ - foreach($row as $ingredient){ - $out->putRecipeIngredient($ingredient); - } - } - - $out->putUnsignedVarInt(count($this->output)); - foreach($this->output as $item){ - $out->putItemStackWithoutStackId($item); - } - - $out->putUUID($this->uuid); - $out->putString($this->blockName); - $out->putVarInt($this->priority); - $out->writeGenericTypeNetworkId($this->recipeNetId); - } -} diff --git a/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php b/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php deleted file mode 100644 index c97dd40bda..0000000000 --- a/src/network/mcpe/protocol/types/recipe/ShapelessRecipe.php +++ /dev/null @@ -1,132 +0,0 @@ -recipeId = $recipeId; - $this->inputs = $inputs; - $this->outputs = $outputs; - $this->uuid = $uuid; - $this->blockName = $blockName; - $this->priority = $priority; - $this->recipeNetId = $recipeNetId; - } - - public function getRecipeId() : string{ - return $this->recipeId; - } - - /** - * @return RecipeIngredient[] - */ - public function getInputs() : array{ - return $this->inputs; - } - - /** - * @return ItemStack[] - */ - public function getOutputs() : array{ - return $this->outputs; - } - - public function getUuid() : UuidInterface{ - return $this->uuid; - } - - public function getBlockName() : string{ - return $this->blockName; - } - - public function getPriority() : int{ - return $this->priority; - } - - public function getRecipeNetId() : int{ - return $this->recipeNetId; - } - - public static function decode(int $recipeType, PacketSerializer $in) : self{ - $recipeId = $in->getString(); - $input = []; - for($j = 0, $ingredientCount = $in->getUnsignedVarInt(); $j < $ingredientCount; ++$j){ - $input[] = $in->getRecipeIngredient(); - } - $output = []; - for($k = 0, $resultCount = $in->getUnsignedVarInt(); $k < $resultCount; ++$k){ - $output[] = $in->getItemStackWithoutStackId(); - } - $uuid = $in->getUUID(); - $block = $in->getString(); - $priority = $in->getVarInt(); - $recipeNetId = $in->readGenericTypeNetworkId(); - - return new self($recipeType, $recipeId, $input, $output, $uuid, $block, $priority, $recipeNetId); - } - - public function encode(PacketSerializer $out) : void{ - $out->putString($this->recipeId); - $out->putUnsignedVarInt(count($this->inputs)); - foreach($this->inputs as $item){ - $out->putRecipeIngredient($item); - } - - $out->putUnsignedVarInt(count($this->outputs)); - foreach($this->outputs as $item){ - $out->putItemStackWithoutStackId($item); - } - - $out->putUUID($this->uuid); - $out->putString($this->blockName); - $out->putVarInt($this->priority); - $out->writeGenericTypeNetworkId($this->recipeNetId); - } -} diff --git a/src/network/mcpe/protocol/types/resourcepacks/BehaviorPackInfoEntry.php b/src/network/mcpe/protocol/types/resourcepacks/BehaviorPackInfoEntry.php deleted file mode 100644 index df08580454..0000000000 --- a/src/network/mcpe/protocol/types/resourcepacks/BehaviorPackInfoEntry.php +++ /dev/null @@ -1,103 +0,0 @@ -packId = $packId; - $this->version = $version; - $this->sizeBytes = $sizeBytes; - $this->encryptionKey = $encryptionKey; - $this->subPackName = $subPackName; - $this->contentId = $contentId; - $this->hasScripts = $hasScripts; - } - - public function getPackId() : string{ - return $this->packId; - } - - public function getVersion() : string{ - return $this->version; - } - - public function getSizeBytes() : int{ - return $this->sizeBytes; - } - - public function getEncryptionKey() : string{ - return $this->encryptionKey; - } - - public function getSubPackName() : string{ - return $this->subPackName; - } - - public function getContentId() : string{ - return $this->contentId; - } - - public function hasScripts() : bool{ - return $this->hasScripts; - } - - public function write(PacketSerializer $out) : void{ - $out->putString($this->packId); - $out->putString($this->version); - $out->putLLong($this->sizeBytes); - $out->putString($this->encryptionKey); - $out->putString($this->subPackName); - $out->putString($this->contentId); - $out->putBool($this->hasScripts); - } - - public static function read(PacketSerializer $in) : self{ - $uuid = $in->getString(); - $version = $in->getString(); - $sizeBytes = $in->getLLong(); - $encryptionKey = $in->getString(); - $subPackName = $in->getString(); - $contentId = $in->getString(); - $hasScripts = $in->getBool(); - return new self($uuid, $version, $sizeBytes, $encryptionKey, $subPackName, $contentId, $hasScripts); - } -} diff --git a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php deleted file mode 100644 index 9be7072ba1..0000000000 --- a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackInfoEntry.php +++ /dev/null @@ -1,110 +0,0 @@ -packId = $packId; - $this->version = $version; - $this->sizeBytes = $sizeBytes; - $this->encryptionKey = $encryptionKey; - $this->subPackName = $subPackName; - $this->contentId = $contentId; - $this->hasScripts = $hasScripts; - $this->isRtxCapable = $isRtxCapable; - } - - public function getPackId() : string{ - return $this->packId; - } - - public function getVersion() : string{ - return $this->version; - } - - public function getSizeBytes() : int{ - return $this->sizeBytes; - } - - public function getEncryptionKey() : string{ - return $this->encryptionKey; - } - - public function getSubPackName() : string{ - return $this->subPackName; - } - - public function getContentId() : string{ - return $this->contentId; - } - - public function hasScripts() : bool{ - return $this->hasScripts; - } - - public function isRtxCapable() : bool{ return $this->isRtxCapable; } - - public function write(PacketSerializer $out) : void{ - $out->putString($this->packId); - $out->putString($this->version); - $out->putLLong($this->sizeBytes); - $out->putString($this->encryptionKey); - $out->putString($this->subPackName); - $out->putString($this->contentId); - $out->putBool($this->hasScripts); - $out->putBool($this->isRtxCapable); - } - - public static function read(PacketSerializer $in) : self{ - $uuid = $in->getString(); - $version = $in->getString(); - $sizeBytes = $in->getLLong(); - $encryptionKey = $in->getString(); - $subPackName = $in->getString(); - $contentId = $in->getString(); - $hasScripts = $in->getBool(); - $rtxCapable = $in->getBool(); - return new self($uuid, $version, $sizeBytes, $encryptionKey, $subPackName, $contentId, $hasScripts, $rtxCapable); - } -} diff --git a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php deleted file mode 100644 index 1151d37d56..0000000000 --- a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackStackEntry.php +++ /dev/null @@ -1,67 +0,0 @@ -packId = $packId; - $this->version = $version; - $this->subPackName = $subPackName; - } - - public function getPackId() : string{ - return $this->packId; - } - - public function getVersion() : string{ - return $this->version; - } - - public function getSubPackName() : string{ - return $this->subPackName; - } - - public function write(PacketSerializer $out) : void{ - $out->putString($this->packId); - $out->putString($this->version); - $out->putString($this->subPackName); - } - - public static function read(PacketSerializer $in) : self{ - $packId = $in->getString(); - $version = $in->getString(); - $subPackName = $in->getString(); - return new self($packId, $version, $subPackName); - } -} diff --git a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackType.php b/src/network/mcpe/protocol/types/resourcepacks/ResourcePackType.php deleted file mode 100644 index 94ab159fa8..0000000000 --- a/src/network/mcpe/protocol/types/resourcepacks/ResourcePackType.php +++ /dev/null @@ -1,41 +0,0 @@ -pieceType = $pieceType; - $this->colors = $colors; - } - - public function getPieceType() : string{ - return $this->pieceType; - } - - /** - * @return string[] - */ - public function getColors() : array{ - return $this->colors; - } -} diff --git a/src/network/mcpe/protocol/types/skin/PersonaSkinPiece.php b/src/network/mcpe/protocol/types/skin/PersonaSkinPiece.php deleted file mode 100644 index e198da964d..0000000000 --- a/src/network/mcpe/protocol/types/skin/PersonaSkinPiece.php +++ /dev/null @@ -1,77 +0,0 @@ -pieceId = $pieceId; - $this->pieceType = $pieceType; - $this->packId = $packId; - $this->isDefaultPiece = $isDefaultPiece; - $this->productId = $productId; - } - - public function getPieceId() : string{ - return $this->pieceId; - } - - public function getPieceType() : string{ - return $this->pieceType; - } - - public function getPackId() : string{ - return $this->packId; - } - - public function isDefaultPiece() : bool{ - return $this->isDefaultPiece; - } - - public function getProductId() : string{ - return $this->productId; - } -} diff --git a/src/network/mcpe/protocol/types/skin/SkinAnimation.php b/src/network/mcpe/protocol/types/skin/SkinAnimation.php deleted file mode 100644 index a7dc17679e..0000000000 --- a/src/network/mcpe/protocol/types/skin/SkinAnimation.php +++ /dev/null @@ -1,73 +0,0 @@ -image = $image; - $this->type = $type; - $this->frames = $frames; - $this->expressionType = $expressionType; - } - - /** - * Image of the animation. - */ - public function getImage() : SkinImage{ - return $this->image; - } - - /** - * The type of animation you are applying. - */ - public function getType() : int{ - return $this->type; - } - - /** - * The total amount of frames in an animation. - */ - public function getFrames() : float{ - return $this->frames; - } - - public function getExpressionType() : int{ return $this->expressionType; } -} diff --git a/src/network/mcpe/protocol/types/skin/SkinData.php b/src/network/mcpe/protocol/types/skin/SkinData.php deleted file mode 100644 index ccc958e891..0000000000 --- a/src/network/mcpe/protocol/types/skin/SkinData.php +++ /dev/null @@ -1,182 +0,0 @@ -skinId = $skinId; - $this->playFabId = $playFabId; - $this->resourcePatch = $resourcePatch; - $this->skinImage = $skinImage; - $this->animations = $animations; - $this->capeImage = $capeImage ?? new SkinImage(0, 0, ""); - $this->geometryData = $geometryData; - $this->animationData = $animationData; - $this->premium = $premium; - $this->persona = $persona; - $this->personaCapeOnClassic = $personaCapeOnClassic; - $this->capeId = $capeId; - //this has to be unique or the client will do stupid things - $this->fullSkinId = $fullSkinId ?? Uuid::uuid4()->toString(); - $this->armSize = $armSize; - $this->skinColor = $skinColor; - $this->personaPieces = $personaPieces; - $this->pieceTintColors = $pieceTintColors; - $this->isVerified = $isVerified; - } - - public function getSkinId() : string{ - return $this->skinId; - } - - public function getPlayFabId() : string{ return $this->playFabId; } - - public function getResourcePatch() : string{ - return $this->resourcePatch; - } - - public function getSkinImage() : SkinImage{ - return $this->skinImage; - } - - /** - * @return SkinAnimation[] - */ - public function getAnimations() : array{ - return $this->animations; - } - - public function getCapeImage() : SkinImage{ - return $this->capeImage; - } - - public function getGeometryData() : string{ - return $this->geometryData; - } - - public function getAnimationData() : string{ - return $this->animationData; - } - - public function isPersona() : bool{ - return $this->persona; - } - - public function isPremium() : bool{ - return $this->premium; - } - - public function isPersonaCapeOnClassic() : bool{ - return $this->personaCapeOnClassic; - } - - public function getCapeId() : string{ - return $this->capeId; - } - - public function getFullSkinId() : string{ - return $this->fullSkinId; - } - - public function getArmSize() : string{ - return $this->armSize; - } - - public function getSkinColor() : string{ - return $this->skinColor; - } - - /** - * @return PersonaSkinPiece[] - */ - public function getPersonaPieces() : array{ - return $this->personaPieces; - } - - /** - * @return PersonaPieceTintColor[] - */ - public function getPieceTintColors() : array{ - return $this->pieceTintColors; - } - - public function isVerified() : bool{ - return $this->isVerified; - } - - /** - * @internal - */ - public function setVerified(bool $verified) : void{ - $this->isVerified = $verified; - } -} diff --git a/src/network/mcpe/protocol/types/skin/SkinImage.php b/src/network/mcpe/protocol/types/skin/SkinImage.php deleted file mode 100644 index fa797cd7fe..0000000000 --- a/src/network/mcpe/protocol/types/skin/SkinImage.php +++ /dev/null @@ -1,73 +0,0 @@ -height = $height; - $this->width = $width; - $this->data = $data; - } - - public static function fromLegacy(string $data) : SkinImage{ - switch(strlen($data)){ - case 64 * 32 * 4: - return new self(32, 64, $data); - case 64 * 64 * 4: - return new self(64, 64, $data); - case 128 * 128 * 4: - return new self(128, 128, $data); - } - - throw new \InvalidArgumentException("Unknown size"); - } - - public function getHeight() : int{ - return $this->height; - } - - public function getWidth() : int{ - return $this->width; - } - - public function getData() : string{ - return $this->data; - } -} From 53d7ed2b5cc73c9ebcdfc42799e3aec72221d9a5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 14 Jul 2021 20:39:32 +0100 Subject: [PATCH 2615/3224] these tests are now done by pocketmine/bedrock-protocol --- .../network/mcpe/protocol/DataPacketTest.php | 47 --------------- .../network/mcpe/protocol/LoginPacketTest.php | 51 ---------------- .../mcpe/protocol/ProtocolInfoTest.php | 37 ------------ .../network/mcpe/protocol/TestPacket.php | 42 ------------- .../protocol/serializer/PacketBatchTest.php | 60 ------------------- 5 files changed, 237 deletions(-) delete mode 100644 tests/phpunit/network/mcpe/protocol/DataPacketTest.php delete mode 100644 tests/phpunit/network/mcpe/protocol/LoginPacketTest.php delete mode 100644 tests/phpunit/network/mcpe/protocol/ProtocolInfoTest.php delete mode 100644 tests/phpunit/network/mcpe/protocol/TestPacket.php delete mode 100644 tests/phpunit/network/mcpe/protocol/serializer/PacketBatchTest.php diff --git a/tests/phpunit/network/mcpe/protocol/DataPacketTest.php b/tests/phpunit/network/mcpe/protocol/DataPacketTest.php deleted file mode 100644 index 880be1e8f9..0000000000 --- a/tests/phpunit/network/mcpe/protocol/DataPacketTest.php +++ /dev/null @@ -1,47 +0,0 @@ -senderSubId = 3; - $pk->recipientSubId = 2; - - $context = new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary()); - $serializer = PacketSerializer::encoder($context); - $pk->encode($serializer); - - $pk2 = new TestPacket(); - $pk2->decode(PacketSerializer::decoder($serializer->getBuffer(), 0, $context)); - self::assertSame($pk2->senderSubId, 3); - self::assertSame($pk2->recipientSubId, 2); - } -} diff --git a/tests/phpunit/network/mcpe/protocol/LoginPacketTest.php b/tests/phpunit/network/mcpe/protocol/LoginPacketTest.php deleted file mode 100644 index cdd20f8400..0000000000 --- a/tests/phpunit/network/mcpe/protocol/LoginPacketTest.php +++ /dev/null @@ -1,51 +0,0 @@ -getDictionary()); - $stream = PacketSerializer::encoder($context); - $stream->putUnsignedVarInt(ProtocolInfo::LOGIN_PACKET); - $payload = '{"chain":[]'; //intentionally malformed - $stream->putInt(ProtocolInfo::CURRENT_PROTOCOL); - - $stream2 = PacketSerializer::encoder($context); - $stream2->putLInt(strlen($payload)); - $stream2->put($payload); - $stream->putString($stream2->getBuffer()); - - $pk = PacketPool::getInstance()->getPacket($stream->getBuffer()); - - $this->expectException(PacketDecodeException::class); - $pk->decode(PacketSerializer::decoder($stream->getBuffer(), 0, $context)); //bang - } -} diff --git a/tests/phpunit/network/mcpe/protocol/ProtocolInfoTest.php b/tests/phpunit/network/mcpe/protocol/ProtocolInfoTest.php deleted file mode 100644 index e83a919834..0000000000 --- a/tests/phpunit/network/mcpe/protocol/ProtocolInfoTest.php +++ /dev/null @@ -1,37 +0,0 @@ -getDictionary()); - $write = PacketBatch::fromPackets($decoderContext, ...array_fill(0, $limit + 1, new TestPacket())); - $read = new PacketBatch($write->getBuffer()); - $this->expectException(PacketDecodeException::class); - $readCount = 0; - foreach($read->getPackets(PacketPool::getInstance(), $decoderContext, $limit) as $packet){ - $readCount++; - } - } - - public function testDecodeAtLimit() : void{ - $limit = 10; - $decoderContext = new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary()); - $write = PacketBatch::fromPackets($decoderContext, ...array_fill(0, $limit, new TestPacket())); - $read = new PacketBatch($write->getBuffer()); - $readCount = 0; - foreach($read->getPackets(PacketPool::getInstance(), $decoderContext, $limit) as $packet){ - $readCount++; - } - self::assertSame($limit, $readCount); - } -} From ac8b13ee362941bfc8f328ac5ff8323242c78c1a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 14 Jul 2021 20:47:07 +0100 Subject: [PATCH 2616/3224] actions: don't preprocess anything except dependency src --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 77b4d6ad62..d4ad6b106a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -245,7 +245,7 @@ jobs: cp -r "$VENDOR_PM" "$VENDOR_PM_BACKUP" for f in $(ls $VENDOR_PM/pocketmine); do echo "Processing directory \"$f\"..." - php "$PM_PREPROCESSOR_PATH/PreProcessor.php" --path="$VENDOR_PM/pocketmine/$f" --multisize || (echo "Preprocessor exited with code $?" && exit 1) + php "$PM_PREPROCESSOR_PATH/PreProcessor.php" --path="$VENDOR_PM/pocketmine/$f/src" --multisize || (echo "Preprocessor exited with code $?" && exit 1) echo "Checking for changes in \"$f\"..." DIFF=$(git diff --no-index "$VENDOR_PM_BACKUP/pocketmine/$f" "$VENDOR_PM/pocketmine/$f" || true) if [ "$DIFF" != "" ]; then From 5fbc7681b04fe702fcbd43940b9d325e5c216707 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 15 Jul 2021 19:00:40 +0100 Subject: [PATCH 2617/3224] Allow registering multiple ClassLoaders for a thread --- src/scheduler/AsyncPool.php | 2 +- src/thread/CommonThreadPartsTrait.php | 56 ++++++++++++++++++--------- src/thread/Thread.php | 4 +- src/thread/Worker.php | 4 +- 4 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/scheduler/AsyncPool.php b/src/scheduler/AsyncPool.php index 753e7e5a69..707a6e3f33 100644 --- a/src/scheduler/AsyncPool.php +++ b/src/scheduler/AsyncPool.php @@ -147,7 +147,7 @@ class AsyncPool{ $this->eventLoop->addNotifier($notifier, function() use ($worker) : void{ $this->collectTasksFromWorker($worker); }); - $this->workers[$worker]->setClassLoader($this->classLoader); + $this->workers[$worker]->setClassLoaders([$this->classLoader]); $this->workers[$worker]->start(self::WORKER_START_OPTIONS); $this->taskQueues[$worker] = new \SplQueue(); diff --git a/src/thread/CommonThreadPartsTrait.php b/src/thread/CommonThreadPartsTrait.php index 7ce63983a9..3f609d8330 100644 --- a/src/thread/CommonThreadPartsTrait.php +++ b/src/thread/CommonThreadPartsTrait.php @@ -28,46 +28,66 @@ use pocketmine\Server; use function error_reporting; trait CommonThreadPartsTrait{ - /** @var \ClassLoader|null */ - protected $classLoader; + /** @var \Threaded|\ClassLoader[]|null */ + private ?\Threaded $classLoaders = null; /** @var string|null */ protected $composerAutoloaderPath; /** @var bool */ protected $isKilled = false; - public function getClassLoader() : ?\ClassLoader{ - return $this->classLoader; - } - - public function setClassLoader(?\ClassLoader $loader = null) : void{ - $this->composerAutoloaderPath = \pocketmine\COMPOSER_AUTOLOADER_PATH; - - if($loader === null){ - $loader = Server::getInstance()->getLoader(); - } - $this->classLoader = $loader; + /** + * @return \ClassLoader[] + */ + public function getClassLoaders() : ?array{ + return $this->classLoaders !== null ? (array) $this->classLoaders : null; } /** - * Registers the class loader for this thread. + * @param \ClassLoader[] $autoloaders + */ + public function setClassLoaders(?array $autoloaders = null) : void{ + $this->composerAutoloaderPath = \pocketmine\COMPOSER_AUTOLOADER_PATH; + + if($autoloaders === null){ + $autoloaders = [Server::getInstance()->getLoader()]; + } + + if($this->classLoaders === null){ + $this->classLoaders = new \Threaded(); + }else{ + foreach($this->classLoaders as $k => $autoloader){ + unset($this->classLoaders[$k]); + } + } + foreach($autoloaders as $autoloader){ + $this->classLoaders[] = $autoloader; + } + } + + /** + * Registers the class loaders for this thread. * * WARNING: This method MUST be called from any descendent threads' run() method to make autoloading usable. * If you do not do this, you will not be able to use new classes that were not loaded when the thread was started * (unless you are using a custom autoloader). */ - public function registerClassLoader() : void{ + public function registerClassLoaders() : void{ if($this->composerAutoloaderPath !== null){ require $this->composerAutoloaderPath; } - if($this->classLoader !== null){ - $this->classLoader->register(false); + $autoloaders = $this->classLoaders; + if($autoloaders !== null){ + foreach($autoloaders as $autoloader){ + /** @var \ClassLoader $autoloader */ + $autoloader->register(false); + } } } final public function run() : void{ error_reporting(-1); - $this->registerClassLoader(); + $this->registerClassLoaders(); //set this after the autoloader is registered ErrorToExceptionHandler::set(); $this->onRun(); diff --git a/src/thread/Thread.php b/src/thread/Thread.php index 22f2e09861..66c88b1068 100644 --- a/src/thread/Thread.php +++ b/src/thread/Thread.php @@ -35,8 +35,8 @@ abstract class Thread extends \Thread{ //this is intentionally not traitified ThreadManager::getInstance()->add($this); - if($this->getClassLoader() === null){ - $this->setClassLoader(); + if($this->getClassLoaders() === null){ + $this->setClassLoaders(); } return parent::start($options); } diff --git a/src/thread/Worker.php b/src/thread/Worker.php index 8af3659b05..cb31b16238 100644 --- a/src/thread/Worker.php +++ b/src/thread/Worker.php @@ -35,8 +35,8 @@ abstract class Worker extends \Worker{ //this is intentionally not traitified ThreadManager::getInstance()->add($this); - if($this->getClassLoader() === null){ - $this->setClassLoader(); + if($this->getClassLoaders() === null){ + $this->setClassLoaders(); } return parent::start($options); } From e5327a0f3e5c842c9759c61137384532d3be0d0b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 17 Jul 2021 18:29:14 +0100 Subject: [PATCH 2618/3224] ChunkSerializer: Extract serializeSubChunk() from main serialize() routine this will be used in the future for cache-based chunk sends. --- src/network/mcpe/ChunkRequestTask.php | 2 +- .../mcpe/serializer/ChunkSerializer.php | 43 +++++++++++-------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php index 7395da7280..ec7b0adf7b 100644 --- a/src/network/mcpe/ChunkRequestTask.php +++ b/src/network/mcpe/ChunkRequestTask.php @@ -71,7 +71,7 @@ class ChunkRequestTask extends AsyncTask{ $chunk = FastChunkSerializer::deserialize($this->chunk); $subCount = ChunkSerializer::getSubChunkCount($chunk); $encoderContext = new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary()); - $payload = ChunkSerializer::serialize($chunk, RuntimeBlockMapping::getInstance(), $encoderContext, $this->tiles); + $payload = ChunkSerializer::serializeFullChunk($chunk, RuntimeBlockMapping::getInstance(), $encoderContext, $this->tiles); $this->setResult($this->compressor->compress(PacketBatch::fromPackets($encoderContext, LevelChunkPacket::withoutCache($this->chunkX, $this->chunkZ, $subCount, $payload))->getBuffer())); } diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index 6408cd7801..d9ada1181b 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -30,6 +30,7 @@ use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\utils\Binary; use pocketmine\utils\BinaryStream; use pocketmine\world\format\Chunk; +use pocketmine\world\format\SubChunk; use function count; final class ChunkSerializer{ @@ -53,28 +54,11 @@ final class ChunkSerializer{ return 0; } - public static function serialize(Chunk $chunk, RuntimeBlockMapping $blockMapper, PacketSerializerContext $encoderContext, ?string $tiles = null) : string{ + public static function serializeFullChunk(Chunk $chunk, RuntimeBlockMapping $blockMapper, PacketSerializerContext $encoderContext, ?string $tiles = null) : string{ $stream = PacketSerializer::encoder($encoderContext); $subChunkCount = self::getSubChunkCount($chunk); for($y = 0; $y < $subChunkCount; ++$y){ - $layers = $chunk->getSubChunk($y)->getBlockLayers(); - $stream->putByte(8); //version - - $stream->putByte(count($layers)); - - foreach($layers as $blocks){ - $stream->putByte(($blocks->getBitsPerBlock() << 1) | 1); //last 1-bit means "network format", but seems pointless - $stream->put($blocks->getWordArray()); - $palette = $blocks->getPalette(); - - //these LSHIFT by 1 uvarints are optimizations: the client expects zigzag varints here - //but since we know they are always unsigned, we can avoid the extra fcall overhead of - //zigzag and just shift directly. - $stream->putUnsignedVarInt(count($palette) << 1); //yes, this is intentionally zigzag - foreach($palette as $p){ - $stream->put(Binary::writeUnsignedVarInt($blockMapper->toRuntimeId($p) << 1)); - } - } + self::serializeSubChunk($chunk->getSubChunk($y), $blockMapper, $stream); } $stream->put($chunk->getBiomeIdArray()); $stream->putByte(0); //border block array count @@ -88,6 +72,27 @@ final class ChunkSerializer{ return $stream->getBuffer(); } + public static function serializeSubChunk(SubChunk $subChunk, RuntimeBlockMapping $blockMapper, PacketSerializer $stream) : void{ + $layers = $subChunk->getBlockLayers(); + $stream->putByte(8); //version + + $stream->putByte(count($layers)); + + foreach($layers as $blocks){ + $stream->putByte(($blocks->getBitsPerBlock() << 1) | 1); //last 1-bit means "network format", but seems pointless + $stream->put($blocks->getWordArray()); + $palette = $blocks->getPalette(); + + //these LSHIFT by 1 uvarints are optimizations: the client expects zigzag varints here + //but since we know they are always unsigned, we can avoid the extra fcall overhead of + //zigzag and just shift directly. + $stream->putUnsignedVarInt(count($palette) << 1); //yes, this is intentionally zigzag + foreach($palette as $p){ + $stream->put(Binary::writeUnsignedVarInt($blockMapper->toRuntimeId($p) << 1)); + } + } + } + public static function serializeTiles(Chunk $chunk) : string{ $stream = new BinaryStream(); foreach($chunk->getTiles() as $tile){ From 17d0767db503e2b34a46bc35ea3b4c1c0da7ce33 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 17 Jul 2021 18:45:04 +0100 Subject: [PATCH 2619/3224] ChunkSerializer: implement support for persistent network chunk format --- .../mcpe/serializer/ChunkSerializer.php | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index d9ada1181b..8f621e0c82 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -24,7 +24,9 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\serializer; use pocketmine\block\tile\Spawnable; +use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; +use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; use pocketmine\network\mcpe\protocol\serializer\PacketSerializer; use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\utils\Binary; @@ -58,7 +60,7 @@ final class ChunkSerializer{ $stream = PacketSerializer::encoder($encoderContext); $subChunkCount = self::getSubChunkCount($chunk); for($y = 0; $y < $subChunkCount; ++$y){ - self::serializeSubChunk($chunk->getSubChunk($y), $blockMapper, $stream); + self::serializeSubChunk($chunk->getSubChunk($y), $blockMapper, $stream, false); } $stream->put($chunk->getBiomeIdArray()); $stream->putByte(0); //border block array count @@ -72,14 +74,14 @@ final class ChunkSerializer{ return $stream->getBuffer(); } - public static function serializeSubChunk(SubChunk $subChunk, RuntimeBlockMapping $blockMapper, PacketSerializer $stream) : void{ + public static function serializeSubChunk(SubChunk $subChunk, RuntimeBlockMapping $blockMapper, PacketSerializer $stream, bool $persistentBlockStates) : void{ $layers = $subChunk->getBlockLayers(); $stream->putByte(8); //version $stream->putByte(count($layers)); foreach($layers as $blocks){ - $stream->putByte(($blocks->getBitsPerBlock() << 1) | 1); //last 1-bit means "network format", but seems pointless + $stream->putByte(($blocks->getBitsPerBlock() << 1) | ($persistentBlockStates ? 0 : 1)); $stream->put($blocks->getWordArray()); $palette = $blocks->getPalette(); @@ -87,8 +89,15 @@ final class ChunkSerializer{ //but since we know they are always unsigned, we can avoid the extra fcall overhead of //zigzag and just shift directly. $stream->putUnsignedVarInt(count($palette) << 1); //yes, this is intentionally zigzag - foreach($palette as $p){ - $stream->put(Binary::writeUnsignedVarInt($blockMapper->toRuntimeId($p) << 1)); + if($persistentBlockStates){ + $nbtSerializer = new NetworkNbtSerializer(); + foreach($palette as $p){ + $stream->put($nbtSerializer->write(new TreeRoot($blockMapper->getBedrockKnownStates()[$blockMapper->toRuntimeId($p)]))); + } + }else{ + foreach($palette as $p){ + $stream->put(Binary::writeUnsignedVarInt($blockMapper->toRuntimeId($p) << 1)); + } } } } From 19e81b0cd355bdf5863ebc049e8881985a576f00 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 17 Jul 2021 19:06:49 +0100 Subject: [PATCH 2620/3224] BlockFactory: Be aware of potential size changes to metadata bits during testing I found the need to use more bits (for example, bells have 32 states in 1.12). --- src/block/BlockFactory.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 69f11dbb1a..6da50285e7 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -94,12 +94,12 @@ class BlockFactory{ public $blastResistance; public function __construct(){ - $this->fullList = new \SplFixedArray(16384); + $this->fullList = new \SplFixedArray(1024 << Block::INTERNAL_METADATA_BITS); - $this->light = \SplFixedArray::fromArray(array_fill(0, 16384, 0)); - $this->lightFilter = \SplFixedArray::fromArray(array_fill(0, 16384, 1)); - $this->blocksDirectSkyLight = \SplFixedArray::fromArray(array_fill(0, 16384, false)); - $this->blastResistance = \SplFixedArray::fromArray(array_fill(0, 16384, 0.0)); + $this->light = \SplFixedArray::fromArray(array_fill(0, 1024 << Block::INTERNAL_METADATA_BITS, 0)); + $this->lightFilter = \SplFixedArray::fromArray(array_fill(0, 1024 << Block::INTERNAL_METADATA_BITS, 1)); + $this->blocksDirectSkyLight = \SplFixedArray::fromArray(array_fill(0, 1024 << Block::INTERNAL_METADATA_BITS, false)); + $this->blastResistance = \SplFixedArray::fromArray(array_fill(0, 1024 << Block::INTERNAL_METADATA_BITS, 0.0)); $railBreakInfo = new BlockBreakInfo(0.7); $this->register(new ActivatorRail(new BID(Ids::ACTIVATOR_RAIL, 0), "Activator Rail", $railBreakInfo)); From d35e818ea06810aaffa2006555a5dd15ea34df1e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 17 Jul 2021 19:11:28 +0100 Subject: [PATCH 2621/3224] BlockLegacyMetadata: added constants for bell attachment types --- src/block/BlockLegacyMetadata.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/block/BlockLegacyMetadata.php b/src/block/BlockLegacyMetadata.php index 2b4fb17d28..c9faa5ce73 100644 --- a/src/block/BlockLegacyMetadata.php +++ b/src/block/BlockLegacyMetadata.php @@ -49,6 +49,11 @@ final class BlockLegacyMetadata{ public const BEDROCK_FLAG_INFINIBURN = 0x01; + public const BELL_ATTACHMENT_FLOOR = 0; + public const BELL_ATTACHMENT_CEILING = 1; + public const BELL_ATTACHMENT_ONE_WALL = 2; + public const BELL_ATTACHMENT_TWO_WALLS = 3; + public const BREWING_STAND_FLAG_EAST = 0x01; public const BREWING_STAND_FLAG_SOUTHWEST = 0x02; public const BREWING_STAND_FLAG_NORTHWEST = 0x04; From c5abae9eaabd0da2e6860308151d0e2646d73b2b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 17 Jul 2021 22:59:45 +0100 Subject: [PATCH 2622/3224] Fixed merge error in bbf3f4c476bb203f399b7631a7d69013980bbae8 the corresponding code on PM3 was originally removed here: https://github.com/pmmp/PocketMine-MP/commit/485f573955fdfda52395e15fc497066d6ef77040#diff-cf181dff0292664e4aa13c8a1731dc62131489fa404f4ac1357493d320264cceL2263 --- src/network/mcpe/handler/InGamePacketHandler.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 9958658b62..47e0debeb0 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -180,7 +180,6 @@ class InGamePacketHandler extends PacketHandler{ $newPos = $packet->position->subtract(0, 1.62, 0); if($this->forceMoveSync and $newPos->distanceSquared($curPos) > 1){ //Tolerate up to 1 block to avoid problems with client-sided physics when spawning in blocks - $this->session->syncMovement($curPos, null, null, MovePlayerPacket::MODE_RESET); $this->session->getLogger()->debug("Got outdated pre-teleport movement, received " . $newPos . ", expected " . $curPos); //Still getting movements from before teleport, ignore them return false; From 5874ce582ab0440dcff7e300708f126e084e4aff Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Jul 2021 17:00:56 +0100 Subject: [PATCH 2623/3224] Implemented bells --- src/block/Bell.php | 162 ++++++++++++++++++ src/block/BlockFactory.php | 3 +- src/block/VanillaBlocks.php | 2 + src/block/tile/Bell.php | 86 ++++++++++ src/block/tile/TileFactory.php | 2 +- src/block/utils/BellAttachmentType.php | 49 ++++++ src/world/sound/BellRingSound.php | 34 ++++ .../block_factory_consistency_check.json | 2 +- 8 files changed, 337 insertions(+), 3 deletions(-) create mode 100644 src/block/Bell.php create mode 100644 src/block/tile/Bell.php create mode 100644 src/block/utils/BellAttachmentType.php create mode 100644 src/world/sound/BellRingSound.php diff --git a/src/block/Bell.php b/src/block/Bell.php new file mode 100644 index 0000000000..954e55c1c4 --- /dev/null +++ b/src/block/Bell.php @@ -0,0 +1,162 @@ +attachmentType = BellAttachmentType::FLOOR(); + parent::__construct($idInfo, $name, $breakInfo); + } + + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->setFacing(BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03)); + + $attachmentType = [ + BlockLegacyMetadata::BELL_ATTACHMENT_FLOOR => BellAttachmentType::FLOOR(), + BlockLegacyMetadata::BELL_ATTACHMENT_CEILING => BellAttachmentType::CEILING(), + BlockLegacyMetadata::BELL_ATTACHMENT_ONE_WALL => BellAttachmentType::ONE_WALL(), + BlockLegacyMetadata::BELL_ATTACHMENT_TWO_WALLS => BellAttachmentType::TWO_WALLS() + ][($stateMeta >> 2) & 0b11] ?? null; + if($attachmentType === null){ + throw new InvalidBlockStateException("No such attachment type"); + } + $this->setAttachmentType($attachmentType); + } + + public function writeStateToMeta() : int{ + $attachmentTypeMeta = [ + BellAttachmentType::FLOOR()->id() => BlockLegacyMetadata::BELL_ATTACHMENT_FLOOR, + BellAttachmentType::CEILING()->id() => BlockLegacyMetadata::BELL_ATTACHMENT_CEILING, + BellAttachmentType::ONE_WALL()->id() => BlockLegacyMetadata::BELL_ATTACHMENT_ONE_WALL, + BellAttachmentType::TWO_WALLS()->id() => BlockLegacyMetadata::BELL_ATTACHMENT_TWO_WALLS + ][$this->getAttachmentType()->id()] ?? null; + if($attachmentTypeMeta === null){ + throw new AssumptionFailedError("Mapping should cover all cases"); + } + return BlockDataSerializer::writeLegacyHorizontalFacing($this->getFacing()) | ($attachmentTypeMeta << 2); + } + + public function getStateBitmask() : int{ + return 0b1111; + } + + public function getAttachmentType() : BellAttachmentType{ return $this->attachmentType; } + + /** @return $this */ + public function setAttachmentType(BellAttachmentType $attachmentType) : self{ + $this->attachmentType = $attachmentType; + return $this; + } + + private function canBeSupportedBy(Block $block) : bool{ + //TODO: this isn't the actual logic, but it's the closest approximation we can support for now + return $block->isSolid(); + } + + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($face === Facing::UP){ + if(!$this->canBeSupportedBy($tx->fetchBlock($this->pos->down()))){ + return false; + } + if($player !== null){ + $this->setFacing(Facing::opposite($player->getHorizontalFacing())); + } + $this->setAttachmentType(BellAttachmentType::FLOOR()); + }elseif($face === Facing::DOWN){ + if(!$this->canBeSupportedBy($tx->fetchBlock($this->pos->up()))){ + return false; + } + $this->setAttachmentType(BellAttachmentType::CEILING()); + }else{ + $this->setFacing($face); + if($this->canBeSupportedBy($tx->fetchBlock($this->pos->getSide(Facing::opposite($face))))){ + $this->setAttachmentType(BellAttachmentType::ONE_WALL()); + }else{ + return false; + } + if($this->canBeSupportedBy($tx->fetchBlock($this->pos->getSide($face)))){ + $this->setAttachmentType(BellAttachmentType::TWO_WALLS()); + } + } + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + + public function onNearbyBlockChange() : void{ + if( + ($this->attachmentType->equals(BellAttachmentType::CEILING()) && !$this->canBeSupportedBy($this->getSide(Facing::UP))) || + ($this->attachmentType->equals(BellAttachmentType::FLOOR()) && !$this->canBeSupportedBy($this->getSide(Facing::DOWN))) || + ($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) && !$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing)))) || + ($this->attachmentType->equals(BellAttachmentType::TWO_WALLS()) && (!$this->canBeSupportedBy($this->getSide($this->facing)) || !$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing))))) + ){ + $this->pos->getWorld()->useBreakOn($this->pos); + } + } + + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($player !== null){ + $faceHit = Facing::opposite($player->getHorizontalFacing()); + if($this->attachmentType->equals(BellAttachmentType::CEILING())){ + $this->ring($faceHit); + } + if($this->attachmentType->equals(BellAttachmentType::FLOOR()) && Facing::axis($faceHit) === Facing::axis($this->facing)){ + $this->ring($faceHit); + } + if( + ($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) || $this->attachmentType->equals(BellAttachmentType::TWO_WALLS())) && + ($faceHit === Facing::rotateY($this->facing, false) || $faceHit === Facing::rotateY($this->facing, true)) + ){ + $this->ring($faceHit); + } + } + + return true; + } + + public function ring(int $faceHit) : void{ + $this->pos->getWorld()->addSound($this->pos, new BellRingSound()); + $tile = $this->pos->getWorld()->getTile($this->pos); + if($tile instanceof TileBell){ + $this->pos->getWorld()->broadcastPacketToViewers($this->pos, $tile->createFakeUpdatePacket($faceHit)); + } + } +} diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 6da50285e7..35ee2b0084 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -31,6 +31,7 @@ use pocketmine\block\tile\Banner as TileBanner; use pocketmine\block\tile\Barrel as TileBarrel; use pocketmine\block\tile\Beacon as TileBeacon; use pocketmine\block\tile\Bed as TileBed; +use pocketmine\block\tile\Bell as TileBell; use pocketmine\block\tile\BrewingStand as TileBrewingStand; use pocketmine\block\tile\Chest as TileChest; use pocketmine\block\tile\Comparator as TileComparator; @@ -118,6 +119,7 @@ class BlockFactory{ $this->register(new Bedrock(new BID(Ids::BEDROCK, 0), "Bedrock", BlockBreakInfo::indestructible())); $this->register(new Beetroot(new BID(Ids::BEETROOT_BLOCK, 0), "Beetroot Block", BlockBreakInfo::instant())); + $this->register(new Bell(new BID(Ids::BELL, 0, null, TileBell::class), "Bell", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); $this->register(new BlueIce(new BID(Ids::BLUE_ICE, 0), "Blue Ice", new BlockBreakInfo(2.8, BlockToolType::PICKAXE))); $this->register(new BoneBlock(new BID(Ids::BONE_BLOCK, 0), "Bone Block", new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); $this->register(new Bookshelf(new BID(Ids::BOOKSHELF, 0), "Bookshelf", new BlockBreakInfo(1.5, BlockToolType::AXE))); @@ -542,7 +544,6 @@ class BlockFactory{ )); //region --- auto-generated TODOs for bedrock-1.11.0 --- - //TODO: minecraft:bell //TODO: minecraft:blast_furnace //TODO: minecraft:bubble_column //TODO: minecraft:campfire diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 1da1d079f1..003ffafbcd 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -65,6 +65,7 @@ use function assert; * @method static Bed BED() * @method static Bedrock BEDROCK() * @method static Beetroot BEETROOTS() + * @method static Bell BELL() * @method static WoodenButton BIRCH_BUTTON() * @method static WoodenDoor BIRCH_DOOR() * @method static WoodenFence BIRCH_FENCE() @@ -626,6 +627,7 @@ final class VanillaBlocks{ self::register("bed", $factory->get(26, 0)); self::register("bedrock", $factory->get(7, 0)); self::register("beetroots", $factory->get(244, 0)); + self::register("bell", $factory->get(461, 0)); self::register("birch_button", $factory->get(396, 0)); self::register("birch_door", $factory->get(194, 0)); self::register("birch_fence", $factory->get(85, 2)); diff --git a/src/block/tile/Bell.php b/src/block/tile/Bell.php new file mode 100644 index 0000000000..248c260ca6 --- /dev/null +++ b/src/block/tile/Bell.php @@ -0,0 +1,86 @@ +ringing; } + + public function setRinging(bool $ringing) : void{ $this->ringing = $ringing; } + + public function getFacing() : int{ return $this->facing; } + + public function setFacing(int $facing) : void{ $this->facing = $facing; } + + public function getTicks() : int{ return $this->ticks; } + + public function setTicks(int $ticks) : void{ $this->ticks = $ticks; } + + protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ + $nbt->setByte(self::TAG_RINGING, $this->ringing ? 1 : 0); + $nbt->setInt(self::TAG_DIRECTION, $this->facing); + $nbt->setInt(self::TAG_TICKS, $this->ticks); + } + + public function readSaveData(CompoundTag $nbt) : void{ + $this->ringing = $nbt->getByte(self::TAG_RINGING, 0) !== 0; + $this->facing = $nbt->getInt(self::TAG_DIRECTION, Facing::NORTH); + $this->ticks = $nbt->getInt(self::TAG_TICKS, 0); + } + + protected function writeSaveData(CompoundTag $nbt) : void{ + $nbt->setByte(self::TAG_RINGING, $this->ringing ? 1 : 0); + $nbt->setInt(self::TAG_DIRECTION, $this->facing); + $nbt->setInt(self::TAG_TICKS, $this->ticks); + } + + /** + * TODO: HACK! + * Creates a BlockActorDataPacket that triggers the ringing animation on a bell block. + * + * Bedrock team overcomplicated making bells ring when they implemented this; this would have been better and much + * simpler as a BlockEventPacket. It's simpler to implement bells with this hack than to follow Mojang's complicated + * mess. + */ + public function createFakeUpdatePacket(int $bellHitFace) : BlockActorDataPacket{ + $nbt = $this->getSpawnCompound(); + $nbt->setByte(self::TAG_RINGING, 1); + $nbt->setInt(self::TAG_DIRECTION, BlockDataSerializer::writeLegacyHorizontalFacing($bellHitFace)); + $nbt->setInt(self::TAG_TICKS, 0); + return BlockActorDataPacket::create($this->pos->getFloorX(), $this->pos->getFloorY(), $this->pos->getFloorZ(), new CacheableNbt($nbt)); + } +} diff --git a/src/block/tile/TileFactory.php b/src/block/tile/TileFactory.php index 0e37366d74..7e36a70575 100644 --- a/src/block/tile/TileFactory.php +++ b/src/block/tile/TileFactory.php @@ -53,6 +53,7 @@ final class TileFactory{ $this->register(Banner::class, ["Banner", "minecraft:banner"]); $this->register(Beacon::class, ["Beacon", "minecraft:beacon"]); $this->register(Bed::class, ["Bed", "minecraft:bed"]); + $this->register(Bell::class, ["Bell", "minecraft:bell"]); $this->register(BrewingStand::class, ["BrewingStand", "minecraft:brewing_stand"]); $this->register(Chest::class, ["Chest", "minecraft:chest"]); $this->register(Comparator::class, ["Comparator", "minecraft:comparator"]); @@ -70,7 +71,6 @@ final class TileFactory{ $this->register(Sign::class, ["Sign", "minecraft:sign"]); $this->register(Skull::class, ["Skull", "minecraft:skull"]); - //TODO: Bell //TODO: BlastFurnace //TODO: Campfire //TODO: Cauldron diff --git a/src/block/utils/BellAttachmentType.php b/src/block/utils/BellAttachmentType.php new file mode 100644 index 0000000000..f07b047c92 --- /dev/null +++ b/src/block/utils/BellAttachmentType.php @@ -0,0 +1,49 @@ + Date: Mon, 19 Jul 2021 17:39:35 +0100 Subject: [PATCH 2624/3224] Removed FlowerPot update_bit hack --- src/block/BlockFactory.php | 7 ++++++- src/block/FlowerPot.php | 16 ++++------------ .../block/block_factory_consistency_check.json | 2 +- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 35ee2b0084..26404d962f 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -193,7 +193,12 @@ class BlockFactory{ $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_POPPY), "Poppy", BlockBreakInfo::instant())); $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_RED_TULIP), "Red Tulip", BlockBreakInfo::instant())); $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_WHITE_TULIP), "White Tulip", BlockBreakInfo::instant())); - $this->register(new FlowerPot(new BID(Ids::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, TileFlowerPot::class), "Flower Pot", BlockBreakInfo::instant())); + + $flowerPot = new FlowerPot(new BID(Ids::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, TileFlowerPot::class), "Flower Pot", BlockBreakInfo::instant()); + $this->register($flowerPot); + for($meta = 1; $meta < 16; ++$meta){ + $this->remap(Ids::FLOWER_POT_BLOCK, $meta, $flowerPot); + } $this->register(new FrostedIce(new BID(Ids::FROSTED_ICE, 0), "Frosted Ice", new BlockBreakInfo(2.5, BlockToolType::PICKAXE))); $this->register(new Furnace(new BIDFlattened(Ids::FURNACE, [Ids::LIT_FURNACE], 0, null, TileFurnace::class), "Furnace", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); diff --git a/src/block/FlowerPot.php b/src/block/FlowerPot.php index 91c1361e3b..d3a8ba5412 100644 --- a/src/block/FlowerPot.php +++ b/src/block/FlowerPot.php @@ -34,22 +34,15 @@ use function assert; class FlowerPot extends Flowable{ - /** - * TODO: get rid of this hack (it's currently needed to deal with blockfactory state handling) - */ - protected bool $occupied = false; protected ?Block $plant = null; protected function writeStateToMeta() : int{ - return $this->occupied ? BlockLegacyMetadata::FLOWER_POT_FLAG_OCCUPIED : 0; - } - - public function readStateFromData(int $id, int $stateMeta) : void{ - $this->occupied = ($stateMeta & BlockLegacyMetadata::FLOWER_POT_FLAG_OCCUPIED) !== 0; + //TODO: HACK! this is just to make the client actually render the plant - we purposely don't read the flag back + return $this->plant !== null ? BlockLegacyMetadata::FLOWER_POT_FLAG_OCCUPIED : 0; } public function getStateBitmask() : int{ - return 0b1111; //vanilla uses various values, we only care about 1 and 0 for PE + return 0b1; } public function readStateFromWorld() : void{ @@ -58,7 +51,7 @@ class FlowerPot extends Flowable{ if($tile instanceof TileFlowerPot){ $this->setPlant($tile->getPlant()); }else{ - $this->occupied = false; + $this->setPlant(null); } } @@ -81,7 +74,6 @@ class FlowerPot extends Flowable{ }else{ $this->plant = clone $plant; } - $this->occupied = $this->plant !== null; return $this; } diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 6fd0979edc..f27ef0e790 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"knownStates":{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","497":"Tall Grass","498":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1614":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2241":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3280":"Shulker Box","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3488":"Dyed Shulker Box","3489":"Dyed Shulker Box","3490":"Dyed Shulker Box","3491":"Dyed Shulker Box","3492":"Dyed Shulker Box","3493":"Dyed Shulker Box","3494":"Dyed Shulker Box","3495":"Dyed Shulker Box","3496":"Dyed Shulker Box","3497":"Dyed Shulker Box","3498":"Dyed Shulker Box","3499":"Dyed Shulker Box","3500":"Dyed Shulker Box","3501":"Dyed Shulker Box","3502":"Dyed Shulker Box","3503":"Dyed Shulker Box","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6274":"Wall Coral Fan","6276":"Wall Coral Fan","6278":"Wall Coral Fan","6280":"Wall Coral Fan","6282":"Wall Coral Fan","6284":"Wall Coral Fan","6286":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7376":"Bell","7377":"Bell","7378":"Bell","7379":"Bell","7380":"Bell","7381":"Bell","7382":"Bell","7383":"Bell","7384":"Bell","7385":"Bell","7386":"Bell","7387":"Bell","7388":"Bell","7389":"Bell","7390":"Bell","7391":"Bell","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood","7480":"Stripped Oak Wood","7481":"Stripped Spruce Wood","7482":"Stripped Birch Wood","7483":"Stripped Jungle Wood","7484":"Stripped Acacia Wood","7485":"Stripped Dark Oak Wood"},"remaps":{"284":7472,"285":7473,"286":7474,"287":7475,"438":432,"439":432,"446":432,"447":432,"454":448,"455":448,"462":448,"463":448,"496":498,"499":498,"696":688,"697":689,"698":690,"699":691,"700":692,"701":693,"702":694,"703":695,"800":805,"806":805,"807":805,"864":866,"865":866,"870":866,"871":866,"976":978,"977":978,"982":978,"983":978,"992":978,"993":978,"998":978,"999":978,"1036":1027,"1037":1027,"1038":1027,"1039":1027,"1040":1042,"1041":1042,"1046":1042,"1047":1042,"1066":1056,"1067":1056,"1068":1056,"1069":1056,"1070":1056,"1071":1056,"1088":1090,"1089":1090,"1094":1090,"1095":1090,"1148":1139,"1149":1139,"1150":1139,"1151":1139,"1200":1221,"1206":1221,"1207":1221,"1216":1221,"1222":1221,"1223":1221,"1238":1232,"1239":1232,"1246":1232,"1247":1232,"1377":1376,"1378":1376,"1379":1376,"1440":1441,"1443":1441,"1479":1472,"1595":1598,"1596":1598,"1597":1598,"1610":1594,"1611":1614,"1612":1614,"1613":1614,"1615":1599,"2022":2016,"2023":2016,"2030":2016,"2031":2016,"2044":2032,"2045":2032,"2046":2032,"2047":2032,"2080":2082,"2081":2082,"2086":2082,"2087":2082,"2242":2240,"2243":2240,"2244":2240,"2245":2240,"2246":2240,"2247":2240,"2248":2240,"2249":2240,"2250":2240,"2251":2240,"2252":2240,"2253":2240,"2254":2240,"2255":2240,"2294":2288,"2295":2288,"2302":2288,"2303":2288,"2304":2306,"2310":2306,"2311":2306,"2312":2306,"2313":2306,"2314":2306,"2315":2306,"2316":2306,"2317":2306,"2318":2306,"2319":2306,"2332":2322,"2333":2322,"2334":2322,"2335":2322,"2336":2338,"2337":2338,"2342":2338,"2343":2338,"2392":2386,"2393":2386,"2394":2386,"2395":2386,"2396":2386,"2397":2386,"2398":2386,"2399":2386,"2400":2386,"2401":2386,"2402":2386,"2403":2386,"2404":2386,"2405":2386,"2406":2386,"2407":2386,"2465":2464,"2470":2464,"2471":2464,"2473":2464,"2478":2464,"2479":2464,"2493":2481,"2494":2482,"2520":2512,"2521":2513,"2522":2514,"2523":2515,"2524":2516,"2525":2517,"2604":7476,"2605":7477,"2732":2720,"2832":2834,"2833":2834,"2838":2834,"2839":2834,"2904":2896,"2905":2897,"2906":2898,"2907":2899,"2908":2900,"2909":2901,"2910":2902,"2911":2903,"3100":3091,"3101":3091,"3102":3091,"3103":3091,"3116":3107,"3117":3107,"3118":3107,"3119":3107,"3132":3123,"3133":3123,"3134":3123,"3135":3123,"3148":3139,"3149":3139,"3150":3139,"3151":3139,"3164":3155,"3165":3155,"3166":3155,"3167":3155,"3230":3218,"3232":3237,"3238":3237,"3239":3237,"3240":3245,"3246":3245,"3247":3245,"3264":3269,"3270":3269,"3271":3269,"3272":3277,"3278":3277,"3279":3277,"3334":3328,"3335":3328,"3468":3456,"3504":3506,"3505":3506,"3510":3506,"3511":3506,"3520":3522,"3521":3522,"3526":3522,"3527":3522,"3536":3538,"3537":3538,"3542":3538,"3543":3538,"3552":3554,"3553":3554,"3558":3554,"3559":3554,"3568":3570,"3569":3570,"3574":3570,"3575":3570,"3584":3586,"3585":3586,"3590":3586,"3591":3586,"3600":3602,"3601":3602,"3606":3602,"3607":3602,"3616":3618,"3617":3618,"3622":3618,"3623":3618,"3632":3634,"3633":3634,"3638":3634,"3639":3634,"3648":3650,"3649":3650,"3654":3650,"3655":3650,"3664":3666,"3665":3666,"3670":3666,"3671":3666,"3696":3698,"3697":3698,"3702":3698,"3703":3698,"3712":3714,"3713":3714,"3718":3714,"3719":3714,"3728":3730,"3729":3730,"3734":3730,"3735":3730,"3744":3746,"3745":3746,"3750":3746,"3751":3746,"3760":3762,"3761":3762,"3766":3762,"3767":3762,"3824":3829,"3830":3829,"3831":3829,"3955":3952,"4163":4160,"4179":4176,"4195":4192,"4211":4208,"4227":4224,"4243":4240,"6181":6176,"6182":6176,"6183":6176,"6197":6192,"6198":6192,"6199":6192,"6205":6192,"6206":6192,"6207":6192,"6213":6208,"6214":6208,"6215":6208,"6221":6208,"6222":6208,"6223":6208,"6229":6208,"6230":6208,"6231":6208,"6237":6208,"6238":6208,"6239":6208,"6273":6248,"6275":6248,"6277":6248,"6279":6248,"6281":6248,"6283":6248,"6285":6248,"6287":6248,"6326":6320,"6327":6320,"6334":6320,"6335":6320,"6342":6336,"6343":6336,"6350":6336,"6351":6336,"6358":6352,"6359":6352,"6366":6352,"6367":6352,"6374":6368,"6375":6368,"6382":6368,"6383":6368,"6390":6384,"6391":6384,"6398":6384,"6399":6384,"6694":6688,"6695":6688,"6702":6688,"6703":6688,"6760":6752,"6761":6753,"6762":6754,"6763":6755,"6764":6756,"6765":6757,"6766":6758,"6767":6759,"6776":6768,"6777":6769,"6778":6770,"6779":6771,"6780":6772,"6992":6994,"6993":6994,"6998":6994,"6999":6994,"7072":7074,"7073":7074,"7078":7074,"7079":7074,"7104":7106,"7105":7106,"7110":7106,"7111":7106,"7136":7138,"7137":7138,"7142":7138,"7143":7138,"7168":7170,"7169":7170,"7174":7170,"7175":7170,"7334":7328,"7335":7328,"7342":7328,"7343":7328}} \ No newline at end of file +{"knownStates":{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","497":"Tall Grass","498":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1614":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3280":"Shulker Box","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3488":"Dyed Shulker Box","3489":"Dyed Shulker Box","3490":"Dyed Shulker Box","3491":"Dyed Shulker Box","3492":"Dyed Shulker Box","3493":"Dyed Shulker Box","3494":"Dyed Shulker Box","3495":"Dyed Shulker Box","3496":"Dyed Shulker Box","3497":"Dyed Shulker Box","3498":"Dyed Shulker Box","3499":"Dyed Shulker Box","3500":"Dyed Shulker Box","3501":"Dyed Shulker Box","3502":"Dyed Shulker Box","3503":"Dyed Shulker Box","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6274":"Wall Coral Fan","6276":"Wall Coral Fan","6278":"Wall Coral Fan","6280":"Wall Coral Fan","6282":"Wall Coral Fan","6284":"Wall Coral Fan","6286":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7376":"Bell","7377":"Bell","7378":"Bell","7379":"Bell","7380":"Bell","7381":"Bell","7382":"Bell","7383":"Bell","7384":"Bell","7385":"Bell","7386":"Bell","7387":"Bell","7388":"Bell","7389":"Bell","7390":"Bell","7391":"Bell","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood","7480":"Stripped Oak Wood","7481":"Stripped Spruce Wood","7482":"Stripped Birch Wood","7483":"Stripped Jungle Wood","7484":"Stripped Acacia Wood","7485":"Stripped Dark Oak Wood"},"remaps":{"284":7472,"285":7473,"286":7474,"287":7475,"438":432,"439":432,"446":432,"447":432,"454":448,"455":448,"462":448,"463":448,"496":498,"499":498,"696":688,"697":689,"698":690,"699":691,"700":692,"701":693,"702":694,"703":695,"800":805,"806":805,"807":805,"864":866,"865":866,"870":866,"871":866,"976":978,"977":978,"982":978,"983":978,"992":978,"993":978,"998":978,"999":978,"1036":1027,"1037":1027,"1038":1027,"1039":1027,"1040":1042,"1041":1042,"1046":1042,"1047":1042,"1066":1056,"1067":1056,"1068":1056,"1069":1056,"1070":1056,"1071":1056,"1088":1090,"1089":1090,"1094":1090,"1095":1090,"1148":1139,"1149":1139,"1150":1139,"1151":1139,"1200":1221,"1206":1221,"1207":1221,"1216":1221,"1222":1221,"1223":1221,"1238":1232,"1239":1232,"1246":1232,"1247":1232,"1377":1376,"1378":1376,"1379":1376,"1440":1441,"1443":1441,"1479":1472,"1595":1598,"1596":1598,"1597":1598,"1610":1594,"1611":1614,"1612":1614,"1613":1614,"1615":1599,"2022":2016,"2023":2016,"2030":2016,"2031":2016,"2044":2032,"2045":2032,"2046":2032,"2047":2032,"2080":2082,"2081":2082,"2086":2082,"2087":2082,"2241":2240,"2242":2240,"2243":2240,"2244":2240,"2245":2240,"2246":2240,"2247":2240,"2248":2240,"2249":2240,"2250":2240,"2251":2240,"2252":2240,"2253":2240,"2254":2240,"2255":2240,"2294":2288,"2295":2288,"2302":2288,"2303":2288,"2304":2306,"2310":2306,"2311":2306,"2312":2306,"2313":2306,"2314":2306,"2315":2306,"2316":2306,"2317":2306,"2318":2306,"2319":2306,"2332":2322,"2333":2322,"2334":2322,"2335":2322,"2336":2338,"2337":2338,"2342":2338,"2343":2338,"2392":2386,"2393":2386,"2394":2386,"2395":2386,"2396":2386,"2397":2386,"2398":2386,"2399":2386,"2400":2386,"2401":2386,"2402":2386,"2403":2386,"2404":2386,"2405":2386,"2406":2386,"2407":2386,"2465":2464,"2470":2464,"2471":2464,"2473":2464,"2478":2464,"2479":2464,"2493":2481,"2494":2482,"2520":2512,"2521":2513,"2522":2514,"2523":2515,"2524":2516,"2525":2517,"2604":7476,"2605":7477,"2732":2720,"2832":2834,"2833":2834,"2838":2834,"2839":2834,"2904":2896,"2905":2897,"2906":2898,"2907":2899,"2908":2900,"2909":2901,"2910":2902,"2911":2903,"3100":3091,"3101":3091,"3102":3091,"3103":3091,"3116":3107,"3117":3107,"3118":3107,"3119":3107,"3132":3123,"3133":3123,"3134":3123,"3135":3123,"3148":3139,"3149":3139,"3150":3139,"3151":3139,"3164":3155,"3165":3155,"3166":3155,"3167":3155,"3230":3218,"3232":3237,"3238":3237,"3239":3237,"3240":3245,"3246":3245,"3247":3245,"3264":3269,"3270":3269,"3271":3269,"3272":3277,"3278":3277,"3279":3277,"3334":3328,"3335":3328,"3468":3456,"3504":3506,"3505":3506,"3510":3506,"3511":3506,"3520":3522,"3521":3522,"3526":3522,"3527":3522,"3536":3538,"3537":3538,"3542":3538,"3543":3538,"3552":3554,"3553":3554,"3558":3554,"3559":3554,"3568":3570,"3569":3570,"3574":3570,"3575":3570,"3584":3586,"3585":3586,"3590":3586,"3591":3586,"3600":3602,"3601":3602,"3606":3602,"3607":3602,"3616":3618,"3617":3618,"3622":3618,"3623":3618,"3632":3634,"3633":3634,"3638":3634,"3639":3634,"3648":3650,"3649":3650,"3654":3650,"3655":3650,"3664":3666,"3665":3666,"3670":3666,"3671":3666,"3696":3698,"3697":3698,"3702":3698,"3703":3698,"3712":3714,"3713":3714,"3718":3714,"3719":3714,"3728":3730,"3729":3730,"3734":3730,"3735":3730,"3744":3746,"3745":3746,"3750":3746,"3751":3746,"3760":3762,"3761":3762,"3766":3762,"3767":3762,"3824":3829,"3830":3829,"3831":3829,"3955":3952,"4163":4160,"4179":4176,"4195":4192,"4211":4208,"4227":4224,"4243":4240,"6181":6176,"6182":6176,"6183":6176,"6197":6192,"6198":6192,"6199":6192,"6205":6192,"6206":6192,"6207":6192,"6213":6208,"6214":6208,"6215":6208,"6221":6208,"6222":6208,"6223":6208,"6229":6208,"6230":6208,"6231":6208,"6237":6208,"6238":6208,"6239":6208,"6273":6248,"6275":6248,"6277":6248,"6279":6248,"6281":6248,"6283":6248,"6285":6248,"6287":6248,"6326":6320,"6327":6320,"6334":6320,"6335":6320,"6342":6336,"6343":6336,"6350":6336,"6351":6336,"6358":6352,"6359":6352,"6366":6352,"6367":6352,"6374":6368,"6375":6368,"6382":6368,"6383":6368,"6390":6384,"6391":6384,"6398":6384,"6399":6384,"6694":6688,"6695":6688,"6702":6688,"6703":6688,"6760":6752,"6761":6753,"6762":6754,"6763":6755,"6764":6756,"6765":6757,"6766":6758,"6767":6759,"6776":6768,"6777":6769,"6778":6770,"6779":6771,"6780":6772,"6992":6994,"6993":6994,"6998":6994,"6999":6994,"7072":7074,"7073":7074,"7078":7074,"7079":7074,"7104":7106,"7105":7106,"7110":7106,"7111":7106,"7136":7138,"7137":7138,"7142":7138,"7143":7138,"7168":7170,"7169":7170,"7174":7170,"7175":7170,"7334":7328,"7335":7328,"7342":7328,"7343":7328}} \ No newline at end of file From dcbc0bc2a6076e1ee419c8685cff10a5f7a7f576 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Jul 2021 17:58:24 +0100 Subject: [PATCH 2625/3224] BrownMushroomBlock: remove useless function --- src/block/BrownMushroomBlock.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/block/BrownMushroomBlock.php b/src/block/BrownMushroomBlock.php index 47f2ff07dc..09b183491b 100644 --- a/src/block/BrownMushroomBlock.php +++ b/src/block/BrownMushroomBlock.php @@ -33,8 +33,4 @@ class BrownMushroomBlock extends RedMushroomBlock{ VanillaBlocks::BROWN_MUSHROOM()->asItem()->setCount(mt_rand(0, 2)) ]; } - - public function isAffectedBySilkTouch() : bool{ - return true; - } } From f64ef50ce3c97bf0b6b4463eee387b502c0fc354 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 19 Jul 2021 18:08:13 +0100 Subject: [PATCH 2626/3224] ShulkerBox: fixed incorrect block-picking behaviour --- src/block/ShulkerBox.php | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/block/ShulkerBox.php b/src/block/ShulkerBox.php index 5ad7f21fbf..13b3977536 100644 --- a/src/block/ShulkerBox.php +++ b/src/block/ShulkerBox.php @@ -59,19 +59,30 @@ class ShulkerBox extends Opaque{ return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - public function asItem() : Item{ - $item = parent::asItem(); - $shulker = $this->pos->getWorld()->getTile($this->pos); - if($shulker instanceof TileShulkerBox){ - $shulkerNBT = $shulker->getCleanedNBT(); - if($shulkerNBT !== null){ - $item->setNamedTag($shulkerNBT); - } - if($shulker->hasName()){ - $item->setCustomName($shulker->getName()); - } + private function addDataFromTile(TileShulkerBox $tile, Item $item) : void{ + $shulkerNBT = $tile->getCleanedNBT(); + if($shulkerNBT !== null){ + $item->setNamedTag($shulkerNBT); } - return $item; + if($tile->hasName()){ + $item->setCustomName($tile->getName()); + } + } + + public function getDropsForCompatibleTool(Item $item) : array{ + $drop = $this->asItem(); + if(($tile = $this->pos->getWorld()->getTile($this->pos)) instanceof TileShulkerBox){ + $this->addDataFromTile($tile, $drop); + } + return [$drop]; + } + + public function getPickedItem(bool $addUserData = false) : Item{ + $result = parent::getPickedItem($addUserData); + if($addUserData && ($tile = $this->pos->getWorld()->getTile($this->pos)) instanceof TileShulkerBox){ + $this->addDataFromTile($tile, $result); + } + return $result; } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ From 309bed414f03afb71c245a70a801940dabdd43a6 Mon Sep 17 00:00:00 2001 From: Angel <24781244+aimjel@users.noreply.github.com> Date: Mon, 19 Jul 2021 15:01:33 -0400 Subject: [PATCH 2627/3224] Implemented sweet berries (#4164) this doesn't implement the server-side logic for the "stickiness" (slowdown) because we don't have the system needed for it yet. It also doesn't have parity with vanilla on the damage. --- src/block/BlockFactory.php | 2 +- src/block/SweetBerryBush.php | 161 ++++++++++++++++++ src/block/VanillaBlocks.php | 2 + src/item/ItemFactory.php | 2 +- src/item/SweetBerries.php | 42 +++++ src/item/VanillaItems.php | 2 + .../block_factory_consistency_check.json | 2 +- 7 files changed, 210 insertions(+), 3 deletions(-) create mode 100644 src/block/SweetBerryBush.php create mode 100644 src/item/SweetBerries.php diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 26404d962f..48ff3faee7 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -585,7 +585,7 @@ class BlockFactory{ //TODO: minecraft:sticky_piston //TODO: minecraft:stonecutter_block //TODO: minecraft:structure_block - //TODO: minecraft:sweet_berry_bush + $this->register(new SweetBerryBush(new BID(Ids::SWEET_BERRY_BUSH, 0, ItemIds::SWEET_BERRIES), "Sweet Berry Bush", BlockBreakInfo::instant())); //TODO: minecraft:turtle_egg //endregion diff --git a/src/block/SweetBerryBush.php b/src/block/SweetBerryBush.php new file mode 100644 index 0000000000..418c5ee77f --- /dev/null +++ b/src/block/SweetBerryBush.php @@ -0,0 +1,161 @@ +age; + } + + public function readStateFromData(int $id, int $stateMeta) : void{ + $this->age = BlockDataSerializer::readBoundedInt("stage", $stateMeta, self::STAGE_SAPLING, self::STAGE_MATURE); + } + + public function getStateBitmask() : int{ + return 0b111; + } + + public function getAge() : int{ return $this->age; } + + /** @return $this */ + public function setAge(int $age) : self{ + if($age < self::STAGE_SAPLING || $age > self::STAGE_MATURE){ + throw new \InvalidArgumentException("Age must be in range 0-3"); + } + $this->age = $age; + return $this; + } + + public function getBerryDropAmount() : int{ + if($this->age === self::STAGE_MATURE){ + return mt_rand(2, 3); + }elseif($this->age >= self::STAGE_BUSH_SOME_BERRIES){ + return mt_rand(1, 2); + } + return 0; + } + + protected function canBeSupportedBy(Block $block) : bool{ + $id = $block->getId(); + return $id === BlockLegacyIds::GRASS || $id === BlockLegacyIds::DIRT || $id === BlockLegacyIds::PODZOL; + } + + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if(!$this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN))){ + return false; + } + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); + } + + public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($this->age < self::STAGE_MATURE && $item instanceof Fertilizer){ + $block = clone $this; + $block->age++; + + $ev = new BlockGrowEvent($this, $block); + $ev->call(); + + if(!$ev->isCancelled()){ + $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); + } + + $item->pop(); + }elseif(($dropAmount = $this->getBerryDropAmount()) > 0){ + $this->pos->getWorld()->setBlock($this->pos, $this->setAge(self::STAGE_BUSH_NO_BERRIES)); + $this->pos->getWorld()->dropItem($this->pos, $this->asItem()->setCount($dropAmount)); + } + + return true; + } + + public function asItem() : Item{ + return VanillaItems::SWEET_BERRIES(); + } + + public function getDropsForCompatibleTool(Item $item) : array{ + if(($dropAmount = $this->getBerryDropAmount()) > 0){ + return [ + $this->asItem()->setCount($dropAmount) + ]; + } + + return []; + } + + public function onNearbyBlockChange() : void{ + if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){ + $this->pos->getWorld()->useBreakOn($this->pos); + } + } + + public function ticksRandomly() : bool{ + return true; + } + + public function onRandomTick() : void{ + if($this->age < self::STAGE_MATURE and mt_rand(0, 2) === 1){ + $block = clone $this; + ++$block->age; + $ev = new BlockGrowEvent($this, $block); + $ev->call(); + if(!$ev->isCancelled()){ + $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); + } + } + } + + public function hasEntityCollision() : bool{ + return true; + } + + public function onEntityInside(Entity $entity) : bool{ + //TODO: in MCPE, this only triggers if moving while inside the bush block - we don't have the system to deal + //with that reliably right now + if($this->age >= self::STAGE_BUSH_NO_BERRIES && $entity instanceof Living){ + $entity->attack(new EntityDamageByBlockEvent($this, $entity, EntityDamageByBlockEvent::CAUSE_CONTACT, 1)); + } + return true; + } +} diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 003ffafbcd..2484634a60 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -545,6 +545,7 @@ use function assert; * @method static Wood STRIPPED_SPRUCE_WOOD() * @method static Sugarcane SUGARCANE() * @method static DoublePlant SUNFLOWER() + * @method static SweetBerryBush SWEET_BERRY_BUSH() * @method static TallGrass TALL_GRASS() * @method static TNT TNT() * @method static Torch TORCH() @@ -1107,6 +1108,7 @@ final class VanillaBlocks{ self::register("stripped_spruce_wood", $factory->get(467, 9)); self::register("sugarcane", $factory->get(83, 0)); self::register("sunflower", $factory->get(175, 0)); + self::register("sweet_berry_bush", $factory->get(462, 0)); self::register("tall_grass", $factory->get(31, 1)); self::register("tnt", $factory->get(46, 0)); self::register("torch", $factory->get(50, 5)); diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 1727b66484..2c99611322 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -326,7 +326,7 @@ class ItemFactory{ //TODO: minecraft:shield //TODO: minecraft:sparkler //TODO: minecraft:spawn_egg - //TODO: minecraft:sweet_berries + $this->register(new SweetBerries(new ItemIdentifier(ItemIds::SWEET_BERRIES, 0), "Sweet Berries")); //TODO: minecraft:tnt_minecart //TODO: minecraft:trident //TODO: minecraft:turtle_helmet diff --git a/src/item/SweetBerries.php b/src/item/SweetBerries.php new file mode 100644 index 0000000000..6e2d1ee4ef --- /dev/null +++ b/src/item/SweetBerries.php @@ -0,0 +1,42 @@ +get(373, 39)); self::register("strong_turtle_master_splash_potion", $factory->get(438, 39)); self::register("sugar", $factory->get(353)); + self::register("sweet_berries", $factory->get(477)); self::register("swiftness_potion", $factory->get(373, 14)); self::register("swiftness_splash_potion", $factory->get(438, 14)); self::register("thick_potion", $factory->get(373, 3)); diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index f27ef0e790..46ea7ad974 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"knownStates":{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","497":"Tall Grass","498":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1614":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3280":"Shulker Box","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3488":"Dyed Shulker Box","3489":"Dyed Shulker Box","3490":"Dyed Shulker Box","3491":"Dyed Shulker Box","3492":"Dyed Shulker Box","3493":"Dyed Shulker Box","3494":"Dyed Shulker Box","3495":"Dyed Shulker Box","3496":"Dyed Shulker Box","3497":"Dyed Shulker Box","3498":"Dyed Shulker Box","3499":"Dyed Shulker Box","3500":"Dyed Shulker Box","3501":"Dyed Shulker Box","3502":"Dyed Shulker Box","3503":"Dyed Shulker Box","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6274":"Wall Coral Fan","6276":"Wall Coral Fan","6278":"Wall Coral Fan","6280":"Wall Coral Fan","6282":"Wall Coral Fan","6284":"Wall Coral Fan","6286":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7376":"Bell","7377":"Bell","7378":"Bell","7379":"Bell","7380":"Bell","7381":"Bell","7382":"Bell","7383":"Bell","7384":"Bell","7385":"Bell","7386":"Bell","7387":"Bell","7388":"Bell","7389":"Bell","7390":"Bell","7391":"Bell","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood","7480":"Stripped Oak Wood","7481":"Stripped Spruce Wood","7482":"Stripped Birch Wood","7483":"Stripped Jungle Wood","7484":"Stripped Acacia Wood","7485":"Stripped Dark Oak Wood"},"remaps":{"284":7472,"285":7473,"286":7474,"287":7475,"438":432,"439":432,"446":432,"447":432,"454":448,"455":448,"462":448,"463":448,"496":498,"499":498,"696":688,"697":689,"698":690,"699":691,"700":692,"701":693,"702":694,"703":695,"800":805,"806":805,"807":805,"864":866,"865":866,"870":866,"871":866,"976":978,"977":978,"982":978,"983":978,"992":978,"993":978,"998":978,"999":978,"1036":1027,"1037":1027,"1038":1027,"1039":1027,"1040":1042,"1041":1042,"1046":1042,"1047":1042,"1066":1056,"1067":1056,"1068":1056,"1069":1056,"1070":1056,"1071":1056,"1088":1090,"1089":1090,"1094":1090,"1095":1090,"1148":1139,"1149":1139,"1150":1139,"1151":1139,"1200":1221,"1206":1221,"1207":1221,"1216":1221,"1222":1221,"1223":1221,"1238":1232,"1239":1232,"1246":1232,"1247":1232,"1377":1376,"1378":1376,"1379":1376,"1440":1441,"1443":1441,"1479":1472,"1595":1598,"1596":1598,"1597":1598,"1610":1594,"1611":1614,"1612":1614,"1613":1614,"1615":1599,"2022":2016,"2023":2016,"2030":2016,"2031":2016,"2044":2032,"2045":2032,"2046":2032,"2047":2032,"2080":2082,"2081":2082,"2086":2082,"2087":2082,"2241":2240,"2242":2240,"2243":2240,"2244":2240,"2245":2240,"2246":2240,"2247":2240,"2248":2240,"2249":2240,"2250":2240,"2251":2240,"2252":2240,"2253":2240,"2254":2240,"2255":2240,"2294":2288,"2295":2288,"2302":2288,"2303":2288,"2304":2306,"2310":2306,"2311":2306,"2312":2306,"2313":2306,"2314":2306,"2315":2306,"2316":2306,"2317":2306,"2318":2306,"2319":2306,"2332":2322,"2333":2322,"2334":2322,"2335":2322,"2336":2338,"2337":2338,"2342":2338,"2343":2338,"2392":2386,"2393":2386,"2394":2386,"2395":2386,"2396":2386,"2397":2386,"2398":2386,"2399":2386,"2400":2386,"2401":2386,"2402":2386,"2403":2386,"2404":2386,"2405":2386,"2406":2386,"2407":2386,"2465":2464,"2470":2464,"2471":2464,"2473":2464,"2478":2464,"2479":2464,"2493":2481,"2494":2482,"2520":2512,"2521":2513,"2522":2514,"2523":2515,"2524":2516,"2525":2517,"2604":7476,"2605":7477,"2732":2720,"2832":2834,"2833":2834,"2838":2834,"2839":2834,"2904":2896,"2905":2897,"2906":2898,"2907":2899,"2908":2900,"2909":2901,"2910":2902,"2911":2903,"3100":3091,"3101":3091,"3102":3091,"3103":3091,"3116":3107,"3117":3107,"3118":3107,"3119":3107,"3132":3123,"3133":3123,"3134":3123,"3135":3123,"3148":3139,"3149":3139,"3150":3139,"3151":3139,"3164":3155,"3165":3155,"3166":3155,"3167":3155,"3230":3218,"3232":3237,"3238":3237,"3239":3237,"3240":3245,"3246":3245,"3247":3245,"3264":3269,"3270":3269,"3271":3269,"3272":3277,"3278":3277,"3279":3277,"3334":3328,"3335":3328,"3468":3456,"3504":3506,"3505":3506,"3510":3506,"3511":3506,"3520":3522,"3521":3522,"3526":3522,"3527":3522,"3536":3538,"3537":3538,"3542":3538,"3543":3538,"3552":3554,"3553":3554,"3558":3554,"3559":3554,"3568":3570,"3569":3570,"3574":3570,"3575":3570,"3584":3586,"3585":3586,"3590":3586,"3591":3586,"3600":3602,"3601":3602,"3606":3602,"3607":3602,"3616":3618,"3617":3618,"3622":3618,"3623":3618,"3632":3634,"3633":3634,"3638":3634,"3639":3634,"3648":3650,"3649":3650,"3654":3650,"3655":3650,"3664":3666,"3665":3666,"3670":3666,"3671":3666,"3696":3698,"3697":3698,"3702":3698,"3703":3698,"3712":3714,"3713":3714,"3718":3714,"3719":3714,"3728":3730,"3729":3730,"3734":3730,"3735":3730,"3744":3746,"3745":3746,"3750":3746,"3751":3746,"3760":3762,"3761":3762,"3766":3762,"3767":3762,"3824":3829,"3830":3829,"3831":3829,"3955":3952,"4163":4160,"4179":4176,"4195":4192,"4211":4208,"4227":4224,"4243":4240,"6181":6176,"6182":6176,"6183":6176,"6197":6192,"6198":6192,"6199":6192,"6205":6192,"6206":6192,"6207":6192,"6213":6208,"6214":6208,"6215":6208,"6221":6208,"6222":6208,"6223":6208,"6229":6208,"6230":6208,"6231":6208,"6237":6208,"6238":6208,"6239":6208,"6273":6248,"6275":6248,"6277":6248,"6279":6248,"6281":6248,"6283":6248,"6285":6248,"6287":6248,"6326":6320,"6327":6320,"6334":6320,"6335":6320,"6342":6336,"6343":6336,"6350":6336,"6351":6336,"6358":6352,"6359":6352,"6366":6352,"6367":6352,"6374":6368,"6375":6368,"6382":6368,"6383":6368,"6390":6384,"6391":6384,"6398":6384,"6399":6384,"6694":6688,"6695":6688,"6702":6688,"6703":6688,"6760":6752,"6761":6753,"6762":6754,"6763":6755,"6764":6756,"6765":6757,"6766":6758,"6767":6759,"6776":6768,"6777":6769,"6778":6770,"6779":6771,"6780":6772,"6992":6994,"6993":6994,"6998":6994,"6999":6994,"7072":7074,"7073":7074,"7078":7074,"7079":7074,"7104":7106,"7105":7106,"7110":7106,"7111":7106,"7136":7138,"7137":7138,"7142":7138,"7143":7138,"7168":7170,"7169":7170,"7174":7170,"7175":7170,"7334":7328,"7335":7328,"7342":7328,"7343":7328}} \ No newline at end of file +{"knownStates":{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","497":"Tall Grass","498":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1614":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3280":"Shulker Box","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3488":"Dyed Shulker Box","3489":"Dyed Shulker Box","3490":"Dyed Shulker Box","3491":"Dyed Shulker Box","3492":"Dyed Shulker Box","3493":"Dyed Shulker Box","3494":"Dyed Shulker Box","3495":"Dyed Shulker Box","3496":"Dyed Shulker Box","3497":"Dyed Shulker Box","3498":"Dyed Shulker Box","3499":"Dyed Shulker Box","3500":"Dyed Shulker Box","3501":"Dyed Shulker Box","3502":"Dyed Shulker Box","3503":"Dyed Shulker Box","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6274":"Wall Coral Fan","6276":"Wall Coral Fan","6278":"Wall Coral Fan","6280":"Wall Coral Fan","6282":"Wall Coral Fan","6284":"Wall Coral Fan","6286":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7376":"Bell","7377":"Bell","7378":"Bell","7379":"Bell","7380":"Bell","7381":"Bell","7382":"Bell","7383":"Bell","7384":"Bell","7385":"Bell","7386":"Bell","7387":"Bell","7388":"Bell","7389":"Bell","7390":"Bell","7391":"Bell","7392":"Sweet Berry Bush","7393":"Sweet Berry Bush","7394":"Sweet Berry Bush","7395":"Sweet Berry Bush","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood","7480":"Stripped Oak Wood","7481":"Stripped Spruce Wood","7482":"Stripped Birch Wood","7483":"Stripped Jungle Wood","7484":"Stripped Acacia Wood","7485":"Stripped Dark Oak Wood"},"remaps":{"284":7472,"285":7473,"286":7474,"287":7475,"438":432,"439":432,"446":432,"447":432,"454":448,"455":448,"462":448,"463":448,"496":498,"499":498,"696":688,"697":689,"698":690,"699":691,"700":692,"701":693,"702":694,"703":695,"800":805,"806":805,"807":805,"864":866,"865":866,"870":866,"871":866,"976":978,"977":978,"982":978,"983":978,"992":978,"993":978,"998":978,"999":978,"1036":1027,"1037":1027,"1038":1027,"1039":1027,"1040":1042,"1041":1042,"1046":1042,"1047":1042,"1066":1056,"1067":1056,"1068":1056,"1069":1056,"1070":1056,"1071":1056,"1088":1090,"1089":1090,"1094":1090,"1095":1090,"1148":1139,"1149":1139,"1150":1139,"1151":1139,"1200":1221,"1206":1221,"1207":1221,"1216":1221,"1222":1221,"1223":1221,"1238":1232,"1239":1232,"1246":1232,"1247":1232,"1377":1376,"1378":1376,"1379":1376,"1440":1441,"1443":1441,"1479":1472,"1595":1598,"1596":1598,"1597":1598,"1610":1594,"1611":1614,"1612":1614,"1613":1614,"1615":1599,"2022":2016,"2023":2016,"2030":2016,"2031":2016,"2044":2032,"2045":2032,"2046":2032,"2047":2032,"2080":2082,"2081":2082,"2086":2082,"2087":2082,"2241":2240,"2242":2240,"2243":2240,"2244":2240,"2245":2240,"2246":2240,"2247":2240,"2248":2240,"2249":2240,"2250":2240,"2251":2240,"2252":2240,"2253":2240,"2254":2240,"2255":2240,"2294":2288,"2295":2288,"2302":2288,"2303":2288,"2304":2306,"2310":2306,"2311":2306,"2312":2306,"2313":2306,"2314":2306,"2315":2306,"2316":2306,"2317":2306,"2318":2306,"2319":2306,"2332":2322,"2333":2322,"2334":2322,"2335":2322,"2336":2338,"2337":2338,"2342":2338,"2343":2338,"2392":2386,"2393":2386,"2394":2386,"2395":2386,"2396":2386,"2397":2386,"2398":2386,"2399":2386,"2400":2386,"2401":2386,"2402":2386,"2403":2386,"2404":2386,"2405":2386,"2406":2386,"2407":2386,"2465":2464,"2470":2464,"2471":2464,"2473":2464,"2478":2464,"2479":2464,"2493":2481,"2494":2482,"2520":2512,"2521":2513,"2522":2514,"2523":2515,"2524":2516,"2525":2517,"2604":7476,"2605":7477,"2732":2720,"2832":2834,"2833":2834,"2838":2834,"2839":2834,"2904":2896,"2905":2897,"2906":2898,"2907":2899,"2908":2900,"2909":2901,"2910":2902,"2911":2903,"3100":3091,"3101":3091,"3102":3091,"3103":3091,"3116":3107,"3117":3107,"3118":3107,"3119":3107,"3132":3123,"3133":3123,"3134":3123,"3135":3123,"3148":3139,"3149":3139,"3150":3139,"3151":3139,"3164":3155,"3165":3155,"3166":3155,"3167":3155,"3230":3218,"3232":3237,"3238":3237,"3239":3237,"3240":3245,"3246":3245,"3247":3245,"3264":3269,"3270":3269,"3271":3269,"3272":3277,"3278":3277,"3279":3277,"3334":3328,"3335":3328,"3468":3456,"3504":3506,"3505":3506,"3510":3506,"3511":3506,"3520":3522,"3521":3522,"3526":3522,"3527":3522,"3536":3538,"3537":3538,"3542":3538,"3543":3538,"3552":3554,"3553":3554,"3558":3554,"3559":3554,"3568":3570,"3569":3570,"3574":3570,"3575":3570,"3584":3586,"3585":3586,"3590":3586,"3591":3586,"3600":3602,"3601":3602,"3606":3602,"3607":3602,"3616":3618,"3617":3618,"3622":3618,"3623":3618,"3632":3634,"3633":3634,"3638":3634,"3639":3634,"3648":3650,"3649":3650,"3654":3650,"3655":3650,"3664":3666,"3665":3666,"3670":3666,"3671":3666,"3696":3698,"3697":3698,"3702":3698,"3703":3698,"3712":3714,"3713":3714,"3718":3714,"3719":3714,"3728":3730,"3729":3730,"3734":3730,"3735":3730,"3744":3746,"3745":3746,"3750":3746,"3751":3746,"3760":3762,"3761":3762,"3766":3762,"3767":3762,"3824":3829,"3830":3829,"3831":3829,"3955":3952,"4163":4160,"4179":4176,"4195":4192,"4211":4208,"4227":4224,"4243":4240,"6181":6176,"6182":6176,"6183":6176,"6197":6192,"6198":6192,"6199":6192,"6205":6192,"6206":6192,"6207":6192,"6213":6208,"6214":6208,"6215":6208,"6221":6208,"6222":6208,"6223":6208,"6229":6208,"6230":6208,"6231":6208,"6237":6208,"6238":6208,"6239":6208,"6273":6248,"6275":6248,"6277":6248,"6279":6248,"6281":6248,"6283":6248,"6285":6248,"6287":6248,"6326":6320,"6327":6320,"6334":6320,"6335":6320,"6342":6336,"6343":6336,"6350":6336,"6351":6336,"6358":6352,"6359":6352,"6366":6352,"6367":6352,"6374":6368,"6375":6368,"6382":6368,"6383":6368,"6390":6384,"6391":6384,"6398":6384,"6399":6384,"6694":6688,"6695":6688,"6702":6688,"6703":6688,"6760":6752,"6761":6753,"6762":6754,"6763":6755,"6764":6756,"6765":6757,"6766":6758,"6767":6759,"6776":6768,"6777":6769,"6778":6770,"6779":6771,"6780":6772,"6992":6994,"6993":6994,"6998":6994,"6999":6994,"7072":7074,"7073":7074,"7078":7074,"7079":7074,"7104":7106,"7105":7106,"7110":7106,"7111":7106,"7136":7138,"7137":7138,"7142":7138,"7143":7138,"7168":7170,"7169":7170,"7174":7170,"7175":7170,"7334":7328,"7335":7328,"7342":7328,"7343":7328,"7396":7392,"7397":7392,"7398":7392,"7399":7392}} \ No newline at end of file From 3466fbe3e33c0b764efd4a6c66866bd0655f6f54 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 21 Jul 2021 19:25:01 +0100 Subject: [PATCH 2628/3224] MemoryManager: remove unused variable declaration it's overwritten further down anyway. --- src/MemoryManager.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/MemoryManager.php b/src/MemoryManager.php index 0a84e6b07a..657daca80b 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -319,8 +319,6 @@ class MemoryManager{ $obData = fopen(Path::join($outputFolder, "objects.js"), "wb+"); - $data = []; - $objects = []; $refCounts = []; From e803ca0e06299974f9010e1a610dc19c559f10ac Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 22 Jul 2021 14:27:20 +0100 Subject: [PATCH 2629/3224] Living: Limit vertical knockback to 0.4 by default this will break non-standard use cases with large forces, but they only have to stick a 'null' at the end of the parameter list. Since this function should be primarily used for vanilla knockback, it makes more sense to keep the default as vanilla, but allow people to change it if they want to. closes #4106 (this is close to #4106 anyway, but small enough that it was easier to recreate it than pull and modify it) closes #2707 --- src/entity/Living.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/entity/Living.php b/src/entity/Living.php index c21f6720ae..afa3096d99 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -507,7 +507,7 @@ abstract class Living extends Entity{ $this->broadcastAnimation(new HurtAnimation($this)); } - public function knockBack(float $x, float $z, float $base = 0.4) : void{ + public function knockBack(float $x, float $z, float $base = 0.4, ?float $verticalLimit = 0.4) : void{ $f = sqrt($x * $x + $z * $z); if($f <= 0){ return; @@ -522,8 +522,9 @@ abstract class Living extends Entity{ $motionY += $base; $motionZ += $z * $f * $base; - if($motionY > $base){ - $motionY = $base; + $verticalLimit ??= $base; + if($motionY > $verticalLimit){ + $motionY = $verticalLimit; } $this->setMotion(new Vector3($motionX, $motionY, $motionZ)); From 77138c5c069c93f27d0ee77420d0937d22fcbca2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 22 Jul 2021 15:46:08 +0100 Subject: [PATCH 2630/3224] Living: changed bad parameter name --- src/entity/Living.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/entity/Living.php b/src/entity/Living.php index afa3096d99..8c78b7a00c 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -507,7 +507,7 @@ abstract class Living extends Entity{ $this->broadcastAnimation(new HurtAnimation($this)); } - public function knockBack(float $x, float $z, float $base = 0.4, ?float $verticalLimit = 0.4) : void{ + public function knockBack(float $x, float $z, float $force = 0.4, ?float $verticalLimit = 0.4) : void{ $f = sqrt($x * $x + $z * $z); if($f <= 0){ return; @@ -518,11 +518,11 @@ abstract class Living extends Entity{ $motionX = $this->motion->x / 2; $motionY = $this->motion->y / 2; $motionZ = $this->motion->z / 2; - $motionX += $x * $f * $base; - $motionY += $base; - $motionZ += $z * $f * $base; + $motionX += $x * $f * $force; + $motionY += $force; + $motionZ += $z * $f * $force; - $verticalLimit ??= $base; + $verticalLimit ??= $force; if($motionY > $verticalLimit){ $motionY = $verticalLimit; } From 2476f40cc68eebc389597ca787a55f053544bc9d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 22 Jul 2021 16:45:42 +0100 Subject: [PATCH 2631/3224] Rail: store shape instead of connections shape is what we'll eventually expose on the API. --- src/block/BaseRail.php | 28 +++++++++---------- src/block/DetectorRail.php | 9 ++++-- src/block/Rail.php | 12 +++++--- .../utils/RailPoweredByRedstoneTrait.php | 9 ++++-- 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/block/BaseRail.php b/src/block/BaseRail.php index bafcfe2a41..aeb62b3842 100644 --- a/src/block/BaseRail.php +++ b/src/block/BaseRail.php @@ -71,24 +71,22 @@ abstract class BaseRail extends Flowable{ ] ]; - /** @var int[] */ - protected array $connections = []; + protected int $railShape = BlockLegacyMetadata::RAIL_STRAIGHT_NORTH_SOUTH; protected function writeStateToMeta() : int{ - if(count($this->connections) === 0){ - return BlockLegacyMetadata::RAIL_STRAIGHT_NORTH_SOUTH; - } - return $this->getMetaForState($this->connections); + return $this->railShape; } public function readStateFromData(int $id, int $stateMeta) : void{ - $connections = $this->getConnectionsFromMeta($stateMeta); - if($connections === null){ + $railShape = $this->readRailShapeFromMeta($stateMeta); + if($railShape === null){ throw new InvalidBlockStateException("Invalid rail type meta $stateMeta"); } - $this->connections = $connections; + $this->railShape = $railShape; } + abstract protected function readRailShapeFromMeta(int $stateMeta) : ?int; + public function getStateBitmask() : int{ return 0b1111; } @@ -129,7 +127,7 @@ abstract class BaseRail extends Flowable{ * * @throws \InvalidArgumentException if no state matches the given connections */ - protected function getMetaForState(array $connections) : int{ + protected function getShapeForConnections(array $connections) : int{ return self::searchState($connections, self::CONNECTIONS); } @@ -138,7 +136,7 @@ abstract class BaseRail extends Flowable{ * * @return int[] */ - abstract protected function getConnectionsFromMeta(int $meta) : ?array; + abstract protected function getCurrentShapeConnections() : array; /** * Returns all the directions this rail is already connected in. @@ -150,7 +148,7 @@ abstract class BaseRail extends Flowable{ $connections = []; /** @var int $connection */ - foreach($this->connections as $connection){ + foreach($this->getCurrentShapeConnections() as $connection){ $other = $this->getSide($connection & ~self::FLAG_ASCEND); $otherConnection = Facing::opposite($connection & ~self::FLAG_ASCEND); @@ -164,7 +162,7 @@ abstract class BaseRail extends Flowable{ if( $other instanceof BaseRail and - in_array($otherConnection, $other->connections, true) + in_array($otherConnection, $other->getCurrentShapeConnections(), true) ){ $connections[] = $connection; } @@ -278,14 +276,14 @@ abstract class BaseRail extends Flowable{ throw new \InvalidArgumentException("Expected exactly 2 connections, got " . count($connections)); } - $this->connections = $connections; + $this->railShape = $this->getShapeForConnections($connections); } public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ $this->pos->getWorld()->useBreakOn($this->pos); }else{ - foreach($this->connections as $connection){ + foreach($this->getCurrentShapeConnections() as $connection){ if(($connection & self::FLAG_ASCEND) !== 0 and $this->getSide($connection & ~self::FLAG_ASCEND)->isTransparent()){ $this->pos->getWorld()->useBreakOn($this->pos); break; diff --git a/src/block/DetectorRail.php b/src/block/DetectorRail.php index 2ddc4a271a..572cb63cd8 100644 --- a/src/block/DetectorRail.php +++ b/src/block/DetectorRail.php @@ -34,6 +34,11 @@ class DetectorRail extends BaseRail{ return $this; } + protected function readRailShapeFromMeta(int $stateMeta) : ?int{ + $stateMeta &= ~BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED; + return isset(self::CONNECTIONS[$stateMeta]) ? $stateMeta : null; + } + protected function writeStateToMeta() : int{ return parent::writeStateToMeta() | ($this->activated ? BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED : 0); } @@ -43,8 +48,8 @@ class DetectorRail extends BaseRail{ $this->activated = ($stateMeta & BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED) !== 0; } - protected function getConnectionsFromMeta(int $meta) : ?array{ - return self::CONNECTIONS[$meta & ~BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED] ?? null; + protected function getCurrentShapeConnections() : array{ + return self::CONNECTIONS[$this->railShape]; } //TODO diff --git a/src/block/Rail.php b/src/block/Rail.php index c906470ca1..82968dcdf7 100644 --- a/src/block/Rail.php +++ b/src/block/Rail.php @@ -48,16 +48,20 @@ class Rail extends BaseRail{ ] ]; - protected function getMetaForState(array $connections) : int{ + protected function readRailShapeFromMeta(int $stateMeta) : ?int{ + return isset(self::CURVE_CONNECTIONS[$stateMeta]) || isset(self::CONNECTIONS[$stateMeta]) ? $stateMeta : null; + } + + protected function getShapeForConnections(array $connections) : int{ try{ return self::searchState($connections, self::CURVE_CONNECTIONS); }catch(\InvalidArgumentException $e){ - return parent::getMetaForState($connections); + return parent::getShapeForConnections($connections); } } - protected function getConnectionsFromMeta(int $meta) : ?array{ - return self::CURVE_CONNECTIONS[$meta] ?? self::CONNECTIONS[$meta] ?? null; + protected function getCurrentShapeConnections() : array{ + return self::CURVE_CONNECTIONS[$this->railShape] ?? self::CONNECTIONS[$this->railShape]; } protected function getPossibleConnectionDirectionsOneConstraint(int $constraint) : array{ diff --git a/src/block/utils/RailPoweredByRedstoneTrait.php b/src/block/utils/RailPoweredByRedstoneTrait.php index 0314c4bec7..9845eb5b74 100644 --- a/src/block/utils/RailPoweredByRedstoneTrait.php +++ b/src/block/utils/RailPoweredByRedstoneTrait.php @@ -28,6 +28,11 @@ use pocketmine\block\BlockLegacyMetadata; trait RailPoweredByRedstoneTrait{ use PoweredByRedstoneTrait; + protected function readRailShapeFromMeta(int $stateMeta) : ?int{ + $stateMeta &= ~BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED; + return isset(self::CONNECTIONS[$stateMeta]) ? $stateMeta : null; + } + protected function writeStateToMeta() : int{ return parent::writeStateToMeta() | ($this->powered ? BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED : 0); } @@ -37,7 +42,7 @@ trait RailPoweredByRedstoneTrait{ $this->powered = ($stateMeta & BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED) !== 0; } - protected function getConnectionsFromMeta(int $meta) : ?array{ - return self::CONNECTIONS[$meta & ~BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED] ?? null; + protected function getCurrentShapeConnections() : array{ + return self::CONNECTIONS[$this->railShape]; } } From e97234d42064f9a6323414b33521f1b0922dca6c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 22 Jul 2021 17:35:10 +0100 Subject: [PATCH 2632/3224] Refactor Rail handling to allow LSP-complaint shape handling the reason there hasn't been any API until now is because of how inconvenient it was to expose a LSP-compliant API _and_ use the same base class for handling all the connection logic. This commit fixes that problem by abstracting shape handling away from BaseRail entirely, so that now it deals exclusively with connections. Deciding the shape of rail to use is now the job of the subclasses. --- src/block/ActivatorRail.php | 2 +- src/block/BaseRail.php | 108 ++++-------------- src/block/DetectorRail.php | 17 +-- src/block/PoweredRail.php | 2 +- src/block/Rail.php | 53 ++++----- src/block/StraightOnlyRail.php | 64 +++++++++++ src/block/utils/RailConnectionInfo.php | 82 +++++++++++++ .../utils/RailPoweredByRedstoneTrait.php | 20 ++-- 8 files changed, 210 insertions(+), 138 deletions(-) create mode 100644 src/block/StraightOnlyRail.php create mode 100644 src/block/utils/RailConnectionInfo.php diff --git a/src/block/ActivatorRail.php b/src/block/ActivatorRail.php index 84538db7b6..d842be041d 100644 --- a/src/block/ActivatorRail.php +++ b/src/block/ActivatorRail.php @@ -25,7 +25,7 @@ namespace pocketmine\block; use pocketmine\block\utils\RailPoweredByRedstoneTrait; -class ActivatorRail extends BaseRail{ +class ActivatorRail extends StraightOnlyRail{ use RailPoweredByRedstoneTrait; //TODO diff --git a/src/block/BaseRail.php b/src/block/BaseRail.php index aeb62b3842..52ff91dfa6 100644 --- a/src/block/BaseRail.php +++ b/src/block/BaseRail.php @@ -23,74 +23,20 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\InvalidBlockStateException; +use pocketmine\block\utils\RailConnectionInfo; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\world\BlockTransaction; -use function array_map; use function array_reverse; use function array_search; use function array_shift; use function count; -use function implode; use function in_array; abstract class BaseRail extends Flowable{ - protected const FLAG_ASCEND = 1 << 24; //used to indicate direction-up - - protected const CONNECTIONS = [ - //straights - BlockLegacyMetadata::RAIL_STRAIGHT_NORTH_SOUTH => [ - Facing::NORTH, - Facing::SOUTH - ], - BlockLegacyMetadata::RAIL_STRAIGHT_EAST_WEST => [ - Facing::EAST, - Facing::WEST - ], - - //ascending - BlockLegacyMetadata::RAIL_ASCENDING_EAST => [ - Facing::WEST, - Facing::EAST | self::FLAG_ASCEND - ], - BlockLegacyMetadata::RAIL_ASCENDING_WEST => [ - Facing::EAST, - Facing::WEST | self::FLAG_ASCEND - ], - BlockLegacyMetadata::RAIL_ASCENDING_NORTH => [ - Facing::SOUTH, - Facing::NORTH | self::FLAG_ASCEND - ], - BlockLegacyMetadata::RAIL_ASCENDING_SOUTH => [ - Facing::NORTH, - Facing::SOUTH | self::FLAG_ASCEND - ] - ]; - - protected int $railShape = BlockLegacyMetadata::RAIL_STRAIGHT_NORTH_SOUTH; - - protected function writeStateToMeta() : int{ - return $this->railShape; - } - - public function readStateFromData(int $id, int $stateMeta) : void{ - $railShape = $this->readRailShapeFromMeta($stateMeta); - if($railShape === null){ - throw new InvalidBlockStateException("Invalid rail type meta $stateMeta"); - } - $this->railShape = $railShape; - } - - abstract protected function readRailShapeFromMeta(int $stateMeta) : ?int; - - public function getStateBitmask() : int{ - return 0b1111; - } - public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$blockReplace->getSide(Facing::DOWN)->isTransparent()){ return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); @@ -108,28 +54,22 @@ abstract class BaseRail extends Flowable{ * @param int[][] $lookup * @phpstan-param array> $lookup */ - protected static function searchState(array $connections, array $lookup) : int{ - $meta = array_search($connections, $lookup, true); - if($meta === false){ - $meta = array_search(array_reverse($connections), $lookup, true); + protected static function searchState(array $connections, array $lookup) : ?int{ + $shape = array_search($connections, $lookup, true); + if($shape === false){ + $shape = array_search(array_reverse($connections), $lookup, true); } - if($meta === false){ - throw new \InvalidArgumentException("No meta value matches connections " . implode(", ", array_map('\dechex', $connections))); - } - - return $meta; + return $shape === false ? null : $shape; } /** - * Returns a meta value for the rail with the given connections. + * Sets the rail shape according to the given connections, if a shape matches. * * @param int[] $connections * - * @throws \InvalidArgumentException if no state matches the given connections + * @throws \InvalidArgumentException if no shape matches the given connections */ - protected function getShapeForConnections(array $connections) : int{ - return self::searchState($connections, self::CONNECTIONS); - } + abstract protected function setShapeFromConnections(array $connections) : void; /** * Returns the connection directions of this rail (depending on the current block state) @@ -149,15 +89,15 @@ abstract class BaseRail extends Flowable{ /** @var int $connection */ foreach($this->getCurrentShapeConnections() as $connection){ - $other = $this->getSide($connection & ~self::FLAG_ASCEND); - $otherConnection = Facing::opposite($connection & ~self::FLAG_ASCEND); + $other = $this->getSide($connection & ~RailConnectionInfo::FLAG_ASCEND); + $otherConnection = Facing::opposite($connection & ~RailConnectionInfo::FLAG_ASCEND); - if(($connection & self::FLAG_ASCEND) !== 0){ + if(($connection & RailConnectionInfo::FLAG_ASCEND) !== 0){ $other = $other->getSide(Facing::UP); }elseif(!($other instanceof BaseRail)){ //check for rail sloping up to meet this one $other = $other->getSide(Facing::DOWN); - $otherConnection |= self::FLAG_ASCEND; + $otherConnection |= RailConnectionInfo::FLAG_ASCEND; } if( @@ -188,7 +128,7 @@ abstract class BaseRail extends Flowable{ Facing::EAST => true ]; foreach($possible as $p => $_){ - $possible[$p | self::FLAG_ASCEND] = true; + $possible[$p | RailConnectionInfo::FLAG_ASCEND] = true; } return $possible; @@ -206,13 +146,13 @@ abstract class BaseRail extends Flowable{ * @phpstan-return array */ protected function getPossibleConnectionDirectionsOneConstraint(int $constraint) : array{ - $opposite = Facing::opposite($constraint & ~self::FLAG_ASCEND); + $opposite = Facing::opposite($constraint & ~RailConnectionInfo::FLAG_ASCEND); $possible = [$opposite => true]; - if(($constraint & self::FLAG_ASCEND) === 0){ + if(($constraint & RailConnectionInfo::FLAG_ASCEND) === 0){ //We can slope the other way if this connection isn't already a slope - $possible[$opposite | self::FLAG_ASCEND] = true; + $possible[$opposite | RailConnectionInfo::FLAG_ASCEND] = true; } return $possible; @@ -227,16 +167,16 @@ abstract class BaseRail extends Flowable{ $continue = false; foreach($possible as $thisSide => $_){ - $otherSide = Facing::opposite($thisSide & ~self::FLAG_ASCEND); + $otherSide = Facing::opposite($thisSide & ~RailConnectionInfo::FLAG_ASCEND); - $other = $this->getSide($thisSide & ~self::FLAG_ASCEND); + $other = $this->getSide($thisSide & ~RailConnectionInfo::FLAG_ASCEND); - if(($thisSide & self::FLAG_ASCEND) !== 0){ + if(($thisSide & RailConnectionInfo::FLAG_ASCEND) !== 0){ $other = $other->getSide(Facing::UP); }elseif(!($other instanceof BaseRail)){ //check if other rails can slope up to meet this one $other = $other->getSide(Facing::DOWN); - $otherSide |= self::FLAG_ASCEND; + $otherSide |= RailConnectionInfo::FLAG_ASCEND; } if(!($other instanceof BaseRail) or count($otherConnections = $other->getConnectedDirections()) >= 2){ @@ -271,12 +211,12 @@ abstract class BaseRail extends Flowable{ */ private function setConnections(array $connections) : void{ if(count($connections) === 1){ - $connections[] = Facing::opposite($connections[0] & ~self::FLAG_ASCEND); + $connections[] = Facing::opposite($connections[0] & ~RailConnectionInfo::FLAG_ASCEND); }elseif(count($connections) !== 2){ throw new \InvalidArgumentException("Expected exactly 2 connections, got " . count($connections)); } - $this->railShape = $this->getShapeForConnections($connections); + $this->setShapeFromConnections($connections); } public function onNearbyBlockChange() : void{ @@ -284,7 +224,7 @@ abstract class BaseRail extends Flowable{ $this->pos->getWorld()->useBreakOn($this->pos); }else{ foreach($this->getCurrentShapeConnections() as $connection){ - if(($connection & self::FLAG_ASCEND) !== 0 and $this->getSide($connection & ~self::FLAG_ASCEND)->isTransparent()){ + if(($connection & RailConnectionInfo::FLAG_ASCEND) !== 0 and $this->getSide($connection & ~RailConnectionInfo::FLAG_ASCEND)->isTransparent()){ $this->pos->getWorld()->useBreakOn($this->pos); break; } diff --git a/src/block/DetectorRail.php b/src/block/DetectorRail.php index 572cb63cd8..935fd0a04d 100644 --- a/src/block/DetectorRail.php +++ b/src/block/DetectorRail.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -class DetectorRail extends BaseRail{ +class DetectorRail extends StraightOnlyRail{ protected bool $activated = false; public function isActivated() : bool{ return $this->activated; } @@ -34,22 +34,17 @@ class DetectorRail extends BaseRail{ return $this; } - protected function readRailShapeFromMeta(int $stateMeta) : ?int{ - $stateMeta &= ~BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED; - return isset(self::CONNECTIONS[$stateMeta]) ? $stateMeta : null; + public function readStateFromData(int $id, int $stateMeta) : void{ + parent::readStateFromData($id, $stateMeta & ~BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED); + $this->activated = ($stateMeta & BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED) !== 0; } protected function writeStateToMeta() : int{ return parent::writeStateToMeta() | ($this->activated ? BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED : 0); } - public function readStateFromData(int $id, int $stateMeta) : void{ - parent::readStateFromData($id, $stateMeta); - $this->activated = ($stateMeta & BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED) !== 0; - } - - protected function getCurrentShapeConnections() : array{ - return self::CONNECTIONS[$this->railShape]; + public function getStateBitmask() : int{ + return 0b1111; } //TODO diff --git a/src/block/PoweredRail.php b/src/block/PoweredRail.php index 320227619d..0c754d57f9 100644 --- a/src/block/PoweredRail.php +++ b/src/block/PoweredRail.php @@ -25,6 +25,6 @@ namespace pocketmine\block; use pocketmine\block\utils\RailPoweredByRedstoneTrait; -class PoweredRail extends BaseRail{ +class PoweredRail extends StraightOnlyRail{ use RailPoweredByRedstoneTrait; } diff --git a/src/block/Rail.php b/src/block/Rail.php index 82968dcdf7..0d0415f8bd 100644 --- a/src/block/Rail.php +++ b/src/block/Rail.php @@ -23,51 +23,46 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\InvalidBlockStateException; +use pocketmine\block\utils\RailConnectionInfo; use pocketmine\math\Facing; class Rail extends BaseRail{ - /* extended meta values for regular rails, to allow curving */ + private int $railShape = BlockLegacyMetadata::RAIL_STRAIGHT_NORTH_SOUTH; - private const CURVE_CONNECTIONS = [ - BlockLegacyMetadata::RAIL_CURVE_SOUTHEAST => [ - Facing::SOUTH, - Facing::EAST - ], - BlockLegacyMetadata::RAIL_CURVE_SOUTHWEST => [ - Facing::SOUTH, - Facing::WEST - ], - BlockLegacyMetadata::RAIL_CURVE_NORTHWEST => [ - Facing::NORTH, - Facing::WEST - ], - BlockLegacyMetadata::RAIL_CURVE_NORTHEAST => [ - Facing::NORTH, - Facing::EAST - ] - ]; - - protected function readRailShapeFromMeta(int $stateMeta) : ?int{ - return isset(self::CURVE_CONNECTIONS[$stateMeta]) || isset(self::CONNECTIONS[$stateMeta]) ? $stateMeta : null; + public function readStateFromData(int $id, int $stateMeta) : void{ + if(!isset(RailConnectionInfo::CONNECTIONS[$stateMeta]) && !isset(RailConnectionInfo::CURVE_CONNECTIONS[$stateMeta])){ + throw new InvalidBlockStateException("No rail shape matches metadata $stateMeta"); + } + $this->railShape = $stateMeta; } - protected function getShapeForConnections(array $connections) : int{ - try{ - return self::searchState($connections, self::CURVE_CONNECTIONS); - }catch(\InvalidArgumentException $e){ - return parent::getShapeForConnections($connections); + protected function writeStateToMeta() : int{ + //TODO: railShape won't be plain metadata in future + return $this->railShape; + } + + public function getStateBitmask() : int{ + return 0b1111; + } + + protected function setShapeFromConnections(array $connections) : void{ + $railShape = self::searchState($connections, RailConnectionInfo::CONNECTIONS) ?? self::searchState($connections, RailConnectionInfo::CURVE_CONNECTIONS); + if($railShape === null){ + throw new \InvalidArgumentException("No rail shape matches these connections"); } + $this->railShape = $railShape; } protected function getCurrentShapeConnections() : array{ - return self::CURVE_CONNECTIONS[$this->railShape] ?? self::CONNECTIONS[$this->railShape]; + return RailConnectionInfo::CURVE_CONNECTIONS[$this->railShape] ?? RailConnectionInfo::CONNECTIONS[$this->railShape]; } protected function getPossibleConnectionDirectionsOneConstraint(int $constraint) : array{ $possible = parent::getPossibleConnectionDirectionsOneConstraint($constraint); - if(($constraint & self::FLAG_ASCEND) === 0){ + if(($constraint & RailConnectionInfo::FLAG_ASCEND) === 0){ foreach([ Facing::NORTH, Facing::SOUTH, diff --git a/src/block/StraightOnlyRail.php b/src/block/StraightOnlyRail.php new file mode 100644 index 0000000000..4b393bb926 --- /dev/null +++ b/src/block/StraightOnlyRail.php @@ -0,0 +1,64 @@ +railShape = $railShape; + } + + protected function writeStateToMeta() : int{ + //TODO: railShape won't be plain metadata in the future + return $this->railShape; + } + + public function getStateBitmask() : int{ + return 0b111; + } + + protected function setShapeFromConnections(array $connections) : void{ + $railShape = self::searchState($connections, RailConnectionInfo::CONNECTIONS); + if($railShape === null){ + throw new \InvalidArgumentException("No rail shape matches these connections"); + } + $this->railShape = $railShape; + } + + protected function getCurrentShapeConnections() : array{ + return RailConnectionInfo::CONNECTIONS[$this->railShape]; + } +} diff --git a/src/block/utils/RailConnectionInfo.php b/src/block/utils/RailConnectionInfo.php new file mode 100644 index 0000000000..324ee3cfb5 --- /dev/null +++ b/src/block/utils/RailConnectionInfo.php @@ -0,0 +1,82 @@ + [ + Facing::NORTH, + Facing::SOUTH + ], + BlockLegacyMetadata::RAIL_STRAIGHT_EAST_WEST => [ + Facing::EAST, + Facing::WEST + ], + + //ascending + BlockLegacyMetadata::RAIL_ASCENDING_EAST => [ + Facing::WEST, + Facing::EAST | self::FLAG_ASCEND + ], + BlockLegacyMetadata::RAIL_ASCENDING_WEST => [ + Facing::EAST, + Facing::WEST | self::FLAG_ASCEND + ], + BlockLegacyMetadata::RAIL_ASCENDING_NORTH => [ + Facing::SOUTH, + Facing::NORTH | self::FLAG_ASCEND + ], + BlockLegacyMetadata::RAIL_ASCENDING_SOUTH => [ + Facing::NORTH, + Facing::SOUTH | self::FLAG_ASCEND + ] + ]; + + /* extended meta values for regular rails, to allow curving */ + public const CURVE_CONNECTIONS = [ + BlockLegacyMetadata::RAIL_CURVE_SOUTHEAST => [ + Facing::SOUTH, + Facing::EAST + ], + BlockLegacyMetadata::RAIL_CURVE_SOUTHWEST => [ + Facing::SOUTH, + Facing::WEST + ], + BlockLegacyMetadata::RAIL_CURVE_NORTHWEST => [ + Facing::NORTH, + Facing::WEST + ], + BlockLegacyMetadata::RAIL_CURVE_NORTHEAST => [ + Facing::NORTH, + Facing::EAST + ] + ]; +} diff --git a/src/block/utils/RailPoweredByRedstoneTrait.php b/src/block/utils/RailPoweredByRedstoneTrait.php index 9845eb5b74..f0549429fa 100644 --- a/src/block/utils/RailPoweredByRedstoneTrait.php +++ b/src/block/utils/RailPoweredByRedstoneTrait.php @@ -28,21 +28,17 @@ use pocketmine\block\BlockLegacyMetadata; trait RailPoweredByRedstoneTrait{ use PoweredByRedstoneTrait; - protected function readRailShapeFromMeta(int $stateMeta) : ?int{ - $stateMeta &= ~BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED; - return isset(self::CONNECTIONS[$stateMeta]) ? $stateMeta : null; - } - - protected function writeStateToMeta() : int{ - return parent::writeStateToMeta() | ($this->powered ? BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED : 0); - } - public function readStateFromData(int $id, int $stateMeta) : void{ - parent::readStateFromData($id, $stateMeta); + parent::readStateFromData($id, $stateMeta & ~BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED); $this->powered = ($stateMeta & BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED) !== 0; } - protected function getCurrentShapeConnections() : array{ - return self::CONNECTIONS[$this->railShape]; + protected function writeStateToMeta() : int{ + //TODO: railShape won't be plain metadata in the future + return parent::writeStateToMeta() | ($this->powered ? BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED : 0); + } + + public function getStateBitmask() : int{ + return 0b1111; } } From 5c609cc1c1b93dbb48359e3dc127d862a511454a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 22 Jul 2021 18:37:30 +0100 Subject: [PATCH 2633/3224] Added getShape() and setShape() APIs to StraightOnlyRail and Rail --- src/block/Rail.php | 13 +++++++++++++ src/block/StraightOnlyRail.php | 14 ++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/block/Rail.php b/src/block/Rail.php index 0d0415f8bd..9270b5faed 100644 --- a/src/block/Rail.php +++ b/src/block/Rail.php @@ -26,6 +26,8 @@ namespace pocketmine\block; use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\block\utils\RailConnectionInfo; use pocketmine\math\Facing; +use function array_keys; +use function implode; class Rail extends BaseRail{ @@ -77,4 +79,15 @@ class Rail extends BaseRail{ return $possible; } + + public function getShape() : int{ return $this->railShape; } + + /** @return $this */ + public function setShape(int $shape) : self{ + if(!isset(RailConnectionInfo::CONNECTIONS[$shape]) && !isset(RailConnectionInfo::CURVE_CONNECTIONS[$shape])){ + throw new \InvalidArgumentException("Invalid shape, must be one of " . implode(", ", [...array_keys(RailConnectionInfo::CONNECTIONS), ...array_keys(RailConnectionInfo::CURVE_CONNECTIONS)])); + } + $this->railShape = $shape; + return $this; + } } diff --git a/src/block/StraightOnlyRail.php b/src/block/StraightOnlyRail.php index 4b393bb926..a4d6203680 100644 --- a/src/block/StraightOnlyRail.php +++ b/src/block/StraightOnlyRail.php @@ -25,6 +25,8 @@ namespace pocketmine\block; use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\block\utils\RailConnectionInfo; +use function array_keys; +use function implode; /** * Simple non-curvable rail. @@ -61,4 +63,16 @@ class StraightOnlyRail extends BaseRail{ protected function getCurrentShapeConnections() : array{ return RailConnectionInfo::CONNECTIONS[$this->railShape]; } + + public function getShape() : int{ return $this->railShape; } + + /** @return $this */ + public function setShape(int $shape) : self{ + if(!isset(RailConnectionInfo::CONNECTIONS[$shape])){ + throw new \InvalidArgumentException("Invalid rail shape, must be one of " . implode(", ", array_keys(RailConnectionInfo::CONNECTIONS))); + } + $this->railShape = $shape; + return $this; + + } } From 832a156fc7df7c34bbc123fde963bdd522a098f2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 22 Jul 2021 18:52:58 +0100 Subject: [PATCH 2634/3224] RakLib: split PthreadsChannelWriter into two implementations this gains a very small performance improvement by avoiding unnecessary !== null checks on every packet written in either direction. It's insignificant for sure, but I just found this code in an old stash, so what the heck. --- .../mcpe/raklib/PthreadsChannelWriter.php | 8 +--- src/network/mcpe/raklib/RakLibServer.php | 2 +- .../SnoozeAwarePthreadsChannelWriter.php | 42 +++++++++++++++++++ 3 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 src/network/mcpe/raklib/SnoozeAwarePthreadsChannelWriter.php diff --git a/src/network/mcpe/raklib/PthreadsChannelWriter.php b/src/network/mcpe/raklib/PthreadsChannelWriter.php index 580d774bb8..8372dbf592 100644 --- a/src/network/mcpe/raklib/PthreadsChannelWriter.php +++ b/src/network/mcpe/raklib/PthreadsChannelWriter.php @@ -23,18 +23,12 @@ use raklib\server\ipc\InterThreadChannelWriter; final class PthreadsChannelWriter implements InterThreadChannelWriter{ /** @var \Threaded */ private $buffer; - /** @var SleeperNotifier|null */ - private $notifier; - public function __construct(\Threaded $buffer, ?SleeperNotifier $notifier = null){ + public function __construct(\Threaded $buffer){ $this->buffer = $buffer; - $this->notifier = $notifier; } public function write(string $str) : void{ $this->buffer[] = $str; - if($this->notifier !== null){ - $this->notifier->wakeupSleeper(); - } } } diff --git a/src/network/mcpe/raklib/RakLibServer.php b/src/network/mcpe/raklib/RakLibServer.php index e7f27c6ccb..7591475ee9 100644 --- a/src/network/mcpe/raklib/RakLibServer.php +++ b/src/network/mcpe/raklib/RakLibServer.php @@ -153,7 +153,7 @@ class RakLibServer extends Thread{ $this->maxMtuSize, new SimpleProtocolAcceptor($this->protocolVersion), new UserToRakLibThreadMessageReceiver(new PthreadsChannelReader($this->mainToThreadBuffer)), - new RakLibToUserThreadMessageSender(new PthreadsChannelWriter($this->threadToMainBuffer, $this->mainThreadNotifier)), + new RakLibToUserThreadMessageSender(new SnoozeAwarePthreadsChannelWriter($this->threadToMainBuffer, $this->mainThreadNotifier)), new ExceptionTraceCleaner($this->mainPath) ); $this->synchronized(function() : void{ diff --git a/src/network/mcpe/raklib/SnoozeAwarePthreadsChannelWriter.php b/src/network/mcpe/raklib/SnoozeAwarePthreadsChannelWriter.php new file mode 100644 index 0000000000..2600c85e37 --- /dev/null +++ b/src/network/mcpe/raklib/SnoozeAwarePthreadsChannelWriter.php @@ -0,0 +1,42 @@ +buffer = $buffer; + $this->notifier = $notifier; + } + + public function write(string $str) : void{ + $this->buffer[] = $str; + $this->notifier->wakeupSleeper(); + } +} From 41d9bf8a2e039e220b4e428fa3fecce2b1320464 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 22 Jul 2021 19:08:21 +0100 Subject: [PATCH 2635/3224] PthreadsChannelWriter: remove unused import --- src/network/mcpe/raklib/PthreadsChannelWriter.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/network/mcpe/raklib/PthreadsChannelWriter.php b/src/network/mcpe/raklib/PthreadsChannelWriter.php index 8372dbf592..a51c08c4de 100644 --- a/src/network/mcpe/raklib/PthreadsChannelWriter.php +++ b/src/network/mcpe/raklib/PthreadsChannelWriter.php @@ -17,7 +17,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\raklib; -use pocketmine\snooze\SleeperNotifier; use raklib\server\ipc\InterThreadChannelWriter; final class PthreadsChannelWriter implements InterThreadChannelWriter{ From 83016a97bd7249fe1e5aae18e34a95178d921fb5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 22 Jul 2021 19:13:26 +0100 Subject: [PATCH 2636/3224] Added getMushroomBlockType() / setMushroomBlockType() APIs to Red/BrownMushroomBlock --- src/block/RedMushroomBlock.php | 33 ++++++--- src/block/utils/MushroomBlockType.php | 63 ++++++++++++++++++ src/data/bedrock/MushroomBlockTypeIdMap.php | 74 +++++++++++++++++++++ 3 files changed, 160 insertions(+), 10 deletions(-) create mode 100644 src/block/utils/MushroomBlockType.php create mode 100644 src/data/bedrock/MushroomBlockTypeIdMap.php diff --git a/src/block/RedMushroomBlock.php b/src/block/RedMushroomBlock.php index 955514bcab..a41b031f5e 100644 --- a/src/block/RedMushroomBlock.php +++ b/src/block/RedMushroomBlock.php @@ -23,32 +23,45 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\InvalidBlockStateException; +use pocketmine\block\utils\MushroomBlockType; +use pocketmine\data\bedrock\MushroomBlockTypeIdMap; use pocketmine\item\Item; use function mt_rand; class RedMushroomBlock extends Opaque{ - /** - * @var int - * In PC they have blockstate properties for each of the sides (pores/not pores). Unfortunately, we can't support - * that because we can't serialize 2^6 combinations into a 4-bit metadata value, so this has to stick with storing - * the legacy crap for now. - * TODO: change this once proper blockstates are implemented - */ - protected int $rotationData = 0; + protected MushroomBlockType $mushroomBlockType; + + public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ + $this->mushroomBlockType = MushroomBlockType::PORES(); + parent::__construct($idInfo, $name, $breakInfo); + } protected function writeStateToMeta() : int{ - return $this->rotationData; + return MushroomBlockTypeIdMap::getInstance()->toId($this->mushroomBlockType); } public function readStateFromData(int $id, int $stateMeta) : void{ - $this->rotationData = $stateMeta; + $type = MushroomBlockTypeIdMap::getInstance()->fromId($stateMeta); + if($type === null){ + throw new InvalidBlockStateException("No such mushroom variant $stateMeta"); + } + $this->mushroomBlockType = $type; } public function getStateBitmask() : int{ return 0b1111; } + public function getMushroomBlockType() : MushroomBlockType{ return $this->mushroomBlockType; } + + /** @return $this */ + public function setMushroomBlockType(MushroomBlockType $mushroomBlockType) : self{ + $this->mushroomBlockType = $mushroomBlockType; + return $this; + } + public function getDropsForCompatibleTool(Item $item) : array{ return [ VanillaBlocks::RED_MUSHROOM()->asItem()->setCount(mt_rand(0, 2)) diff --git a/src/block/utils/MushroomBlockType.php b/src/block/utils/MushroomBlockType.php new file mode 100644 index 0000000000..413c273702 --- /dev/null +++ b/src/block/utils/MushroomBlockType.php @@ -0,0 +1,63 @@ + + */ + private array $idToEnum = []; + /** + * @var int[] + * @phpstan-var array + */ + private array $enumToId = []; + + public function __construct(){ + $this->register(LegacyMeta::MUSHROOM_BLOCK_ALL_PORES, MushroomBlockType::PORES()); + $this->register(LegacyMeta::MUSHROOM_BLOCK_CAP_NORTHWEST_CORNER, MushroomBlockType::CAP_NORTHWEST()); + $this->register(LegacyMeta::MUSHROOM_BLOCK_CAP_NORTH_SIDE, MushroomBlockType::CAP_NORTH()); + $this->register(LegacyMeta::MUSHROOM_BLOCK_CAP_NORTHEAST_CORNER, MushroomBlockType::CAP_NORTHEAST()); + $this->register(LegacyMeta::MUSHROOM_BLOCK_CAP_WEST_SIDE, MushroomBlockType::CAP_WEST()); + $this->register(LegacyMeta::MUSHROOM_BLOCK_CAP_TOP_ONLY, MushroomBlockType::CAP_MIDDLE()); + $this->register(LegacyMeta::MUSHROOM_BLOCK_CAP_EAST_SIDE, MushroomBlockType::CAP_EAST()); + $this->register(LegacyMeta::MUSHROOM_BLOCK_CAP_SOUTHWEST_CORNER, MushroomBlockType::CAP_SOUTHWEST()); + $this->register(LegacyMeta::MUSHROOM_BLOCK_CAP_SOUTH_SIDE, MushroomBlockType::CAP_SOUTH()); + $this->register(LegacyMeta::MUSHROOM_BLOCK_CAP_SOUTHEAST_CORNER, MushroomBlockType::CAP_SOUTHEAST()); + $this->register(LegacyMeta::MUSHROOM_BLOCK_ALL_CAP, MushroomBlockType::ALL_CAP()); + } + + public function register(int $id, MushroomBlockType $type) : void{ + $this->idToEnum[$id] = $type; + $this->enumToId[$type->id()] = $id; + } + + public function fromId(int $id) : ?MushroomBlockType{ + return $this->idToEnum[$id] ?? null; + } + + public function toId(MushroomBlockType $type) : int{ + if(!array_key_exists($type->id(), $this->enumToId)){ + throw new \InvalidArgumentException("Mushroom block type does not have a mapped ID"); //this should never happen + } + return $this->enumToId[$type->id()]; + } +} From 0eb4231b5174e57371ad40e91abd26c2977dd810 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Thu, 22 Jul 2021 23:04:00 +0100 Subject: [PATCH 2637/3224] Use OpenSSL for ECDH during client login, drop mdanter/ecc (#4328) This brings a significant performance improvement to login sequence handling, reducing CPU cost of `PrepareEncryptionTask` by over 90% and `ProcessLoginTask` by over 60%. It also allows us to shed a dependency. --- composer.json | 2 +- composer.lock | 78 +------------ phpstan.neon.dist | 1 + src/network/mcpe/JwtUtils.php | 104 ++++++++++++++---- src/network/mcpe/NetworkSession.php | 5 +- src/network/mcpe/auth/ProcessLoginTask.php | 53 ++++----- .../mcpe/encryption/EncryptionUtils.php | 27 +++-- .../mcpe/encryption/PrepareEncryptionTask.php | 37 +++++-- .../mcpe/handler/LoginPacketHandler.php | 9 +- tests/phpstan/configs/l8-baseline.neon | 2 +- tests/phpstan/stubs/phpasn1.stub | 22 ++++ 11 files changed, 186 insertions(+), 154 deletions(-) create mode 100644 tests/phpstan/stubs/phpasn1.stub diff --git a/composer.json b/composer.json index b6659c8c1b..6548e7df54 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "ext-zlib": ">=1.2.11", "composer-runtime-api": "^2.0", "adhocore/json-comment": "^1.1", - "mdanter/ecc": "^1.0", + "fgrosse/phpasn1": "^2.3", "netresearch/jsonmapper": "^4.0", "pocketmine/bedrock-protocol": "dev-master#88ae308a03e8e61ccfdddd42623efabe9e772b42", "pocketmine/binaryutils": "^0.2.1", diff --git a/composer.lock b/composer.lock index 622e8f1ce6..e339513298 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7c8ebad0871e3c90e8894476e3c5b925", + "content-hash": "49005f17832ef5949b4a2ac04cd1ee93", "packages": [ { "name": "adhocore/json-comment", @@ -192,82 +192,6 @@ }, "time": "2021-04-24T19:01:55+00:00" }, - { - "name": "mdanter/ecc", - "version": "v1.0.0", - "source": { - "type": "git", - "url": "https://github.com/phpecc/phpecc.git", - "reference": "34e2eec096bf3dcda814e8f66dd91ae87a2db7cd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpecc/phpecc/zipball/34e2eec096bf3dcda814e8f66dd91ae87a2db7cd", - "reference": "34e2eec096bf3dcda814e8f66dd91ae87a2db7cd", - "shasum": "" - }, - "require": { - "ext-gmp": "*", - "fgrosse/phpasn1": "^2.0", - "php": "^7.0||^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0||^8.0||^9.0", - "squizlabs/php_codesniffer": "^2.0", - "symfony/yaml": "^2.6|^3.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Mdanter\\Ecc\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matyas Danter", - "homepage": "http://matejdanter.com/", - "role": "Author" - }, - { - "name": "Thibaud Fabre", - "email": "thibaud@aztech.io", - "homepage": "http://aztech.io", - "role": "Maintainer" - }, - { - "name": "Thomas Kerin", - "email": "afk11@users.noreply.github.com", - "role": "Maintainer" - } - ], - "description": "PHP Elliptic Curve Cryptography library", - "homepage": "https://github.com/phpecc/phpecc", - "keywords": [ - "Diffie", - "ECDSA", - "Hellman", - "curve", - "ecdh", - "elliptic", - "nistp192", - "nistp224", - "nistp256", - "nistp384", - "nistp521", - "phpecc", - "secp256k1", - "secp256r1" - ], - "support": { - "issues": "https://github.com/phpecc/phpecc/issues", - "source": "https://github.com/phpecc/phpecc/tree/v1.0.0" - }, - "time": "2021-01-16T19:42:14+00:00" - }, { "name": "netresearch/jsonmapper", "version": "v4.0.0", diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 4e1631d93e..cd3c5b18b3 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -46,6 +46,7 @@ parameters: - tests/phpstan/stubs/JsonMapper.stub - tests/phpstan/stubs/pthreads.stub - tests/phpstan/stubs/leveldb.stub + - tests/phpstan/stubs/phpasn1.stub reportUnmatchedIgnoredErrors: false #no other way to silence platform-specific non-warnings staticReflectionClassNamePatterns: - "#^COM$#" diff --git a/src/network/mcpe/JwtUtils.php b/src/network/mcpe/JwtUtils.php index 1b11623621..f2fb273c0d 100644 --- a/src/network/mcpe/JwtUtils.php +++ b/src/network/mcpe/JwtUtils.php @@ -23,36 +23,39 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; -use Mdanter\Ecc\Crypto\Key\PrivateKeyInterface; -use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; -use Mdanter\Ecc\Crypto\Signature\Signature; -use Mdanter\Ecc\Serializer\PrivateKey\DerPrivateKeySerializer; -use Mdanter\Ecc\Serializer\PrivateKey\PemPrivateKeySerializer; -use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; -use Mdanter\Ecc\Serializer\PublicKey\PemPublicKeySerializer; -use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer; +use FG\ASN1\Exception\ParserException; +use FG\ASN1\Universal\Integer; +use FG\ASN1\Universal\Sequence; use pocketmine\utils\AssumptionFailedError; use function base64_decode; use function base64_encode; -use function bin2hex; use function count; use function explode; +use function gmp_export; +use function gmp_import; use function gmp_init; use function gmp_strval; -use function hex2bin; use function is_array; use function json_decode; use function json_encode; use function json_last_error_msg; use function openssl_error_string; +use function openssl_pkey_get_details; +use function openssl_pkey_get_public; use function openssl_sign; use function openssl_verify; +use function preg_match; use function rtrim; +use function sprintf; use function str_pad; use function str_repeat; +use function str_replace; use function str_split; use function strlen; use function strtr; +use const GMP_BIG_ENDIAN; +use const GMP_MSW_FIRST; +use const JSON_THROW_ON_ERROR; use const OPENSSL_ALGO_SHA384; use const STR_PAD_LEFT; @@ -94,9 +97,11 @@ final class JwtUtils{ } /** + * @param resource $signingKey + * * @throws JwtException */ - public static function verify(string $jwt, PublicKeyInterface $signingKey) : bool{ + public static function verify(string $jwt, $signingKey) : bool{ [$header, $body, $signature] = self::split($jwt); $plainSignature = self::b64UrlDecode($signature); @@ -105,12 +110,17 @@ final class JwtUtils{ } [$rString, $sString] = str_split($plainSignature, 48); - $sig = new Signature(gmp_init(bin2hex($rString), 16), gmp_init(bin2hex($sString), 16)); + $convert = fn(string $str) => gmp_strval(gmp_import($str, 1, GMP_BIG_ENDIAN | GMP_MSW_FIRST), 10); + + $sequence = new Sequence( + new Integer($convert($rString)), + new Integer($convert($sString)) + ); $v = openssl_verify( $header . '.' . $body, - (new DerSignatureSerializer())->serialize($sig), - (new PemPublicKeySerializer(new DerPublicKeySerializer()))->serialize($signingKey), + $sequence->getBinary(), + $signingKey, OPENSSL_ALGO_SHA384 ); switch($v){ @@ -122,24 +132,43 @@ final class JwtUtils{ } /** + * @param resource $signingKey + * * @phpstan-param array $header * @phpstan-param array $claims */ - public static function create(array $header, array $claims, PrivateKeyInterface $signingKey) : string{ - $jwtBody = JwtUtils::b64UrlEncode(json_encode($header)) . "." . JwtUtils::b64UrlEncode(json_encode($claims)); + public static function create(array $header, array $claims, $signingKey) : string{ + $jwtBody = JwtUtils::b64UrlEncode(json_encode($header, JSON_THROW_ON_ERROR)) . "." . JwtUtils::b64UrlEncode(json_encode($claims, JSON_THROW_ON_ERROR)); openssl_sign( $jwtBody, - $sig, - (new PemPrivateKeySerializer(new DerPrivateKeySerializer()))->serialize($signingKey), + $rawDerSig, + $signingKey, OPENSSL_ALGO_SHA384 ); - $decodedSig = (new DerSignatureSerializer())->parse($sig); - $jwtSig = JwtUtils::b64UrlEncode( - hex2bin(str_pad(gmp_strval($decodedSig->getR(), 16), 96, "0", STR_PAD_LEFT)) . - hex2bin(str_pad(gmp_strval($decodedSig->getS(), 16), 96, "0", STR_PAD_LEFT)) + try{ + $asnObject = Sequence::fromBinary($rawDerSig); + }catch(ParserException $e){ + throw new AssumptionFailedError("Failed to parse OpenSSL signature: " . $e->getMessage(), 0, $e); + } + if(count($asnObject) !== 2){ + throw new AssumptionFailedError("OpenSSL produced invalid signature, expected exactly 2 parts"); + } + [$r, $s] = [$asnObject[0], $asnObject[1]]; + if(!($r instanceof Integer) || !($s instanceof Integer)){ + throw new AssumptionFailedError("OpenSSL produced invalid signature, expected 2 INTEGER parts"); + } + $rString = $r->getContent(); + $sString = $s->getContent(); + + $toBinary = fn($str) => str_pad( + gmp_export(gmp_init($str, 10), 1, GMP_BIG_ENDIAN | GMP_MSW_FIRST), + 48, + "\x00", + STR_PAD_LEFT ); + $jwtSig = JwtUtils::b64UrlEncode($toBinary($rString) . $toBinary($sString)); return "$jwtBody.$jwtSig"; } @@ -158,4 +187,35 @@ final class JwtUtils{ } return $decoded; } + + /** + * @param resource $opensslKey + */ + public static function emitDerPublicKey($opensslKey) : string{ + $details = openssl_pkey_get_details($opensslKey); + if($details === false){ + throw new AssumptionFailedError("Failed to get details from OpenSSL key resource"); + } + + /** @var string $pemKey */ + $pemKey = $details['key']; + if(preg_match("@^-----BEGIN[A-Z\d ]+PUBLIC KEY-----\n([A-Za-z\d+/\n]+)\n-----END[A-Z\d ]+PUBLIC KEY-----\n$@", $pemKey, $matches) === 1){ + $derKey = base64_decode(str_replace("\n", "", $matches[1]), true); + if($derKey !== false){ + return $derKey; + } + } + throw new AssumptionFailedError("OpenSSL resource contains invalid public key"); + } + + /** + * @return resource + */ + public static function parseDerPublicKey(string $derKey){ + $signingKeyOpenSSL = openssl_pkey_get_public(sprintf("-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----\n", base64_encode($derKey))); + if($signingKeyOpenSSL === false){ + throw new JwtException("OpenSSL failed to parse key: " . openssl_error_string()); + } + return $signingKeyOpenSSL; + } } diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 258e21ee9d..650d72d6c6 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; -use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; use pocketmine\data\bedrock\EffectIdMap; use pocketmine\entity\Attribute; use pocketmine\entity\effect\EffectInstance; @@ -203,7 +202,7 @@ class NetworkSession{ $this->logger->info("Player: " . TextFormat::AQUA . $info->getUsername() . TextFormat::RESET); $this->logger->setPrefix($this->getLogPrefix()); }, - function(bool $isAuthenticated, bool $authRequired, ?string $error, ?PublicKeyInterface $clientPubKey) : void{ + function(bool $isAuthenticated, bool $authRequired, ?string $error, ?string $clientPubKey) : void{ $this->setAuthenticationStatus($isAuthenticated, $authRequired, $error, $clientPubKey); } )); @@ -570,7 +569,7 @@ class NetworkSession{ }, $reason); } - private function setAuthenticationStatus(bool $authenticated, bool $authRequired, ?string $error, ?PublicKeyInterface $clientPubKey) : void{ + private function setAuthenticationStatus(bool $authenticated, bool $authRequired, ?string $error, ?string $clientPubKey) : void{ if(!$this->connected){ return; } diff --git a/src/network/mcpe/auth/ProcessLoginTask.php b/src/network/mcpe/auth/ProcessLoginTask.php index 103a394053..b02f9e2158 100644 --- a/src/network/mcpe/auth/ProcessLoginTask.php +++ b/src/network/mcpe/auth/ProcessLoginTask.php @@ -23,9 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\auth; -use FG\ASN1\Exception\ParserException; -use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; -use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; use pocketmine\lang\KnownTranslationKeys; use pocketmine\network\mcpe\JwtException; use pocketmine\network\mcpe\JwtUtils; @@ -35,6 +32,8 @@ use pocketmine\scheduler\AsyncTask; use function base64_decode; use function igbinary_serialize; use function igbinary_unserialize; +use function openssl_error_string; +use function openssl_free_key; use function time; class ProcessLoginTask extends AsyncTask{ @@ -65,12 +64,12 @@ class ProcessLoginTask extends AsyncTask{ /** @var bool */ private $authRequired; - /** @var PublicKeyInterface|null */ + /** @var string|null */ private $clientPublicKey = null; /** * @param string[] $chainJwts - * @phpstan-param \Closure(bool $isAuthenticated, bool $authRequired, ?string $error, ?PublicKeyInterface $clientPublicKey) : void $onCompletion + * @phpstan-param \Closure(bool $isAuthenticated, bool $authRequired, ?string $error, ?string $clientPublicKey) : void $onCompletion */ public function __construct(array $chainJwts, string $clientDataJwt, bool $authRequired, \Closure $onCompletion){ $this->storeLocal(self::TLS_KEY_ON_COMPLETION, $onCompletion); @@ -88,7 +87,7 @@ class ProcessLoginTask extends AsyncTask{ } } - private function validateChain() : PublicKeyInterface{ + private function validateChain() : string{ /** @var string[] $chain */ $chain = igbinary_unserialize($this->chain); @@ -107,7 +106,7 @@ class ProcessLoginTask extends AsyncTask{ $this->validateToken($this->clientDataJwt, $currentKey); - return (new DerPublicKeySerializer())->parse(base64_decode($clientKey, true)); + return $clientKey; } /** @@ -132,38 +131,36 @@ class ProcessLoginTask extends AsyncTask{ throw new VerifyLoginException("Invalid JWT header: " . $e->getMessage(), 0, $e); } + $headerDerKey = base64_decode($headers->x5u, true); + if($headerDerKey === false){ + throw new VerifyLoginException("Invalid JWT public key: base64 decoding error decoding x5u"); + } + if($currentPublicKey === null){ if(!$first){ throw new VerifyLoginException("%" . KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_MISSINGKEY); } - - //First link, check that it is self-signed - $currentPublicKey = $headers->x5u; - }elseif($headers->x5u !== $currentPublicKey){ + }elseif($headerDerKey !== $currentPublicKey){ //Fast path: if the header key doesn't match what we expected, the signature isn't going to validate anyway throw new VerifyLoginException("%" . KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_BADSIGNATURE); } - $derPublicKeySerializer = new DerPublicKeySerializer(); - $rawPublicKey = base64_decode($currentPublicKey, true); - if($rawPublicKey === false){ - throw new VerifyLoginException("Failed to decode base64'd public key"); + try{ + $signingKeyOpenSSL = JwtUtils::parseDerPublicKey($headerDerKey); + }catch(JwtException $e){ + throw new VerifyLoginException("Invalid JWT public key: " . openssl_error_string()); } try{ - $signingKey = $derPublicKeySerializer->parse($rawPublicKey); - }catch(\RuntimeException | ParserException $e){ - throw new VerifyLoginException("Failed to parse DER public key: " . $e->getMessage(), 0, $e); - } - - try{ - if(!JwtUtils::verify($jwt, $signingKey)){ + if(!JwtUtils::verify($jwt, $signingKeyOpenSSL)){ throw new VerifyLoginException("%" . KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_BADSIGNATURE); } }catch(JwtException $e){ throw new VerifyLoginException($e->getMessage(), 0, $e); } - if($currentPublicKey === self::MOJANG_ROOT_PUBLIC_KEY){ + openssl_free_key($signingKeyOpenSSL); + + if($headers->x5u === self::MOJANG_ROOT_PUBLIC_KEY){ $this->authenticated = true; //we're signed into xbox live } @@ -188,13 +185,19 @@ class ProcessLoginTask extends AsyncTask{ throw new VerifyLoginException("%" . KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_TOOLATE); } - $currentPublicKey = $claims->identityPublicKey ?? null; //if there are further links, the next link should be signed with this + if(isset($claims->identityPublicKey)){ + $identityPublicKey = base64_decode($claims->identityPublicKey, true); + if($identityPublicKey === false){ + throw new VerifyLoginException("Invalid identityPublicKey: base64 error decoding"); + } + $currentPublicKey = $identityPublicKey; //if there are further links, the next link should be signed with this + } } public function onCompletion() : void{ /** * @var \Closure $callback - * @phpstan-var \Closure(bool, bool, ?string, ?PublicKeyInterface) : void $callback + * @phpstan-var \Closure(bool, bool, ?string, ?string) : void $callback */ $callback = $this->fetchLocal(self::TLS_KEY_ON_COMPLETION); $callback($this->authenticated, $this->authRequired, $this->error, $this->clientPublicKey); diff --git a/src/network/mcpe/encryption/EncryptionUtils.php b/src/network/mcpe/encryption/EncryptionUtils.php index c34e4a38f3..45682a3000 100644 --- a/src/network/mcpe/encryption/EncryptionUtils.php +++ b/src/network/mcpe/encryption/EncryptionUtils.php @@ -23,14 +23,15 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\encryption; -use Mdanter\Ecc\Crypto\Key\PrivateKeyInterface; -use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; -use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; use pocketmine\network\mcpe\JwtUtils; use function base64_encode; +use function bin2hex; +use function gmp_init; use function gmp_strval; use function hex2bin; use function openssl_digest; +use function openssl_error_string; +use function openssl_pkey_derive; use function str_pad; final class EncryptionUtils{ @@ -39,18 +40,30 @@ final class EncryptionUtils{ //NOOP } - public static function generateSharedSecret(PrivateKeyInterface $localPriv, PublicKeyInterface $remotePub) : \GMP{ - return $localPriv->createExchange($remotePub)->calculateSharedKey(); + /** + * @param resource $localPriv + * @param resource $remotePub + */ + public static function generateSharedSecret($localPriv, $remotePub) : \GMP{ + $hexSecret = openssl_pkey_derive($remotePub, $localPriv, 48); + if($hexSecret === false){ + throw new \InvalidArgumentException("Failed to derive shared secret: " . openssl_error_string()); + } + return gmp_init(bin2hex($hexSecret), 16); } public static function generateKey(\GMP $secret, string $salt) : string{ return openssl_digest($salt . hex2bin(str_pad(gmp_strval($secret, 16), 96, "0", STR_PAD_LEFT)), 'sha256', true); } - public static function generateServerHandshakeJwt(PrivateKeyInterface $serverPriv, string $salt) : string{ + /** + * @param resource $serverPriv + */ + public static function generateServerHandshakeJwt($serverPriv, string $salt) : string{ + $derPublicKey = JwtUtils::emitDerPublicKey($serverPriv); return JwtUtils::create( [ - "x5u" => base64_encode((new DerPublicKeySerializer())->serialize($serverPriv->getPublicKey())), + "x5u" => base64_encode($derPublicKey), "alg" => "ES384" ], [ diff --git a/src/network/mcpe/encryption/PrepareEncryptionTask.php b/src/network/mcpe/encryption/PrepareEncryptionTask.php index 883947e043..e5cfaf92de 100644 --- a/src/network/mcpe/encryption/PrepareEncryptionTask.php +++ b/src/network/mcpe/encryption/PrepareEncryptionTask.php @@ -23,50 +23,65 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\encryption; -use Mdanter\Ecc\Crypto\Key\PrivateKeyInterface; -use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; -use Mdanter\Ecc\EccFactory; +use pocketmine\network\mcpe\JwtUtils; use pocketmine\scheduler\AsyncTask; use pocketmine\utils\AssumptionFailedError; +use function igbinary_serialize; +use function igbinary_unserialize; +use function openssl_error_string; +use function openssl_free_key; +use function openssl_pkey_get_details; +use function openssl_pkey_new; use function random_bytes; class PrepareEncryptionTask extends AsyncTask{ private const TLS_KEY_ON_COMPLETION = "completion"; - /** @var PrivateKeyInterface|null */ + /** @var resource|null */ private static $SERVER_PRIVATE_KEY = null; - /** @var PrivateKeyInterface */ + /** @var string */ private $serverPrivateKey; /** @var string|null */ private $aesKey = null; /** @var string|null */ private $handshakeJwt = null; - /** @var PublicKeyInterface */ + /** @var string */ private $clientPub; /** * @phpstan-param \Closure(string $encryptionKey, string $handshakeJwt) : void $onCompletion */ - public function __construct(PublicKeyInterface $clientPub, \Closure $onCompletion){ + public function __construct(string $clientPub, \Closure $onCompletion){ if(self::$SERVER_PRIVATE_KEY === null){ - self::$SERVER_PRIVATE_KEY = EccFactory::getNistCurves()->generator384()->createPrivateKey(); + $serverPrivateKey = openssl_pkey_new(["ec" => ["curve_name" => "secp384r1"]]); + if($serverPrivateKey === false){ + throw new \RuntimeException("openssl_pkey_new() failed: " . openssl_error_string()); + } + self::$SERVER_PRIVATE_KEY = $serverPrivateKey; } - $this->serverPrivateKey = self::$SERVER_PRIVATE_KEY; + $this->serverPrivateKey = igbinary_serialize(openssl_pkey_get_details(self::$SERVER_PRIVATE_KEY)); $this->clientPub = $clientPub; $this->storeLocal(self::TLS_KEY_ON_COMPLETION, $onCompletion); } public function onRun() : void{ - $serverPriv = $this->serverPrivateKey; - $sharedSecret = EncryptionUtils::generateSharedSecret($serverPriv, $this->clientPub); + /** @var mixed[] $serverPrivDetails */ + $serverPrivDetails = igbinary_unserialize($this->serverPrivateKey); + $serverPriv = openssl_pkey_new($serverPrivDetails); + if($serverPriv === false) throw new AssumptionFailedError("Failed to restore server signing key from details"); + $clientPub = JwtUtils::parseDerPublicKey($this->clientPub); + $sharedSecret = EncryptionUtils::generateSharedSecret($serverPriv, $clientPub); $salt = random_bytes(16); $this->aesKey = EncryptionUtils::generateKey($sharedSecret, $salt); $this->handshakeJwt = EncryptionUtils::generateServerHandshakeJwt($serverPriv, $salt); + + openssl_free_key($serverPriv); + openssl_free_key($clientPub); } public function onCompletion() : void{ diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index 989bac9f64..926e207403 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; -use Mdanter\Ecc\Crypto\Key\PublicKeyInterface; use pocketmine\entity\InvalidSkinException; use pocketmine\event\player\PlayerPreLoginEvent; use pocketmine\lang\KnownTranslationKeys; @@ -63,13 +62,13 @@ class LoginPacketHandler extends PacketHandler{ private $playerInfoConsumer; /** * @var \Closure - * @phpstan-var \Closure(bool, bool, ?string, ?PublicKeyInterface) : void + * @phpstan-var \Closure(bool, bool, ?string, ?string) : void */ private $authCallback; /** * @phpstan-param \Closure(PlayerInfo) : void $playerInfoConsumer - * @phpstan-param \Closure(bool $isAuthenticated, bool $authRequired, ?string $error, ?PublicKeyInterface $clientPubKey) : void $authCallback + * @phpstan-param \Closure(bool $isAuthenticated, bool $authRequired, ?string $error, ?string $clientPubKey) : void $authCallback */ public function __construct(Server $server, NetworkSession $session, \Closure $playerInfoConsumer, \Closure $authCallback){ $this->session = $session; @@ -78,10 +77,6 @@ class LoginPacketHandler extends PacketHandler{ $this->authCallback = $authCallback; } - private static function dummy() : void{ - echo PublicKeyInterface::class; //this prevents the import getting removed by tools that don't understand phpstan - } - public function handleLogin(LoginPacket $packet) : bool{ if(!$this->isCompatibleProtocol($packet->protocol)){ $this->session->sendDataPacket(PlayStatusPacket::create($packet->protocol < ProtocolInfo::CURRENT_PROTOCOL ? PlayStatusPacket::LOGIN_FAILED_CLIENT : PlayStatusPacket::LOGIN_FAILED_SERVER), true); diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 98057695cb..6e5d7a4fe6 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -136,7 +136,7 @@ parameters: path: ../../../src/network/mcpe/NetworkSession.php - - message: "#^Parameter \\#1 \\$clientPub of class pocketmine\\\\network\\\\mcpe\\\\encryption\\\\PrepareEncryptionTask constructor expects Mdanter\\\\Ecc\\\\Crypto\\\\Key\\\\PublicKeyInterface, Mdanter\\\\Ecc\\\\Crypto\\\\Key\\\\PublicKeyInterface\\|null given\\.$#" + message: "#^Parameter \\#1 \\$clientPub of class pocketmine\\\\network\\\\mcpe\\\\encryption\\\\PrepareEncryptionTask constructor expects string, string\\|null given\\.$#" count: 1 path: ../../../src/network/mcpe/NetworkSession.php diff --git a/tests/phpstan/stubs/phpasn1.stub b/tests/phpstan/stubs/phpasn1.stub new file mode 100644 index 0000000000..b459289efb --- /dev/null +++ b/tests/phpstan/stubs/phpasn1.stub @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FG\ASN1\Universal; + +class Integer +{ + /** + * @param int|string $value + */ + public function __construct($value){} + + /** @return int|string */ + public function getContent(){} +} From f89e10e684a4244c5bcb1868e2a744186937f488 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 23 Jul 2021 16:30:22 +0100 Subject: [PATCH 2638/3224] Silence openssl_free_key() deprecation warnings on 8.0 we don't give a shit and these calls are currently needed for 7.4. --- src/network/mcpe/auth/ProcessLoginTask.php | 2 +- src/network/mcpe/encryption/PrepareEncryptionTask.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network/mcpe/auth/ProcessLoginTask.php b/src/network/mcpe/auth/ProcessLoginTask.php index b02f9e2158..0674ba0339 100644 --- a/src/network/mcpe/auth/ProcessLoginTask.php +++ b/src/network/mcpe/auth/ProcessLoginTask.php @@ -158,7 +158,7 @@ class ProcessLoginTask extends AsyncTask{ throw new VerifyLoginException($e->getMessage(), 0, $e); } - openssl_free_key($signingKeyOpenSSL); + @openssl_free_key($signingKeyOpenSSL); if($headers->x5u === self::MOJANG_ROOT_PUBLIC_KEY){ $this->authenticated = true; //we're signed into xbox live diff --git a/src/network/mcpe/encryption/PrepareEncryptionTask.php b/src/network/mcpe/encryption/PrepareEncryptionTask.php index e5cfaf92de..036ab42861 100644 --- a/src/network/mcpe/encryption/PrepareEncryptionTask.php +++ b/src/network/mcpe/encryption/PrepareEncryptionTask.php @@ -80,8 +80,8 @@ class PrepareEncryptionTask extends AsyncTask{ $this->aesKey = EncryptionUtils::generateKey($sharedSecret, $salt); $this->handshakeJwt = EncryptionUtils::generateServerHandshakeJwt($serverPriv, $salt); - openssl_free_key($serverPriv); - openssl_free_key($clientPub); + @openssl_free_key($serverPriv); + @openssl_free_key($clientPub); } public function onCompletion() : void{ From 772935cd7e84caee0597d9f4ccc384df9bdba0dc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 23 Jul 2021 22:35:09 +0100 Subject: [PATCH 2639/3224] Updated biome ID constants --- src/data/bedrock/BiomeIds.php | 80 ++++++++++++++++++++++++--- src/world/biome/BiomeRegistry.php | 6 +- src/world/generator/normal/Normal.php | 6 +- 3 files changed, 79 insertions(+), 13 deletions(-) diff --git a/src/data/bedrock/BiomeIds.php b/src/data/bedrock/BiomeIds.php index 9513a0dd31..ffb0af8d74 100644 --- a/src/data/bedrock/BiomeIds.php +++ b/src/data/bedrock/BiomeIds.php @@ -32,17 +32,83 @@ final class BiomeIds{ public const OCEAN = 0; public const PLAINS = 1; public const DESERT = 2; - public const MOUNTAINS = 3; + public const EXTREME_HILLS = 3; public const FOREST = 4; public const TAIGA = 5; - public const SWAMP = 6; + public const SWAMPLAND = 6; public const RIVER = 7; - public const HELL = 8; - + public const THE_END = 9; + public const LEGACY_FROZEN_OCEAN = 10; + public const FROZEN_RIVER = 11; public const ICE_PLAINS = 12; - - public const SMALL_MOUNTAINS = 20; - + public const ICE_MOUNTAINS = 13; + public const MUSHROOM_ISLAND = 14; + public const MUSHROOM_ISLAND_SHORE = 15; + public const BEACH = 16; + public const DESERT_HILLS = 17; + public const FOREST_HILLS = 18; + public const TAIGA_HILLS = 19; + public const EXTREME_HILLS_EDGE = 20; + public const JUNGLE = 21; + public const JUNGLE_HILLS = 22; + public const JUNGLE_EDGE = 23; + public const DEEP_OCEAN = 24; + public const STONE_BEACH = 25; + public const COLD_BEACH = 26; public const BIRCH_FOREST = 27; + public const BIRCH_FOREST_HILLS = 28; + public const ROOFED_FOREST = 29; + public const COLD_TAIGA = 30; + public const COLD_TAIGA_HILLS = 31; + public const MEGA_TAIGA = 32; + public const MEGA_TAIGA_HILLS = 33; + public const EXTREME_HILLS_PLUS_TREES = 34; + public const SAVANNA = 35; + public const SAVANNA_PLATEAU = 36; + public const MESA = 37; + public const MESA_PLATEAU_STONE = 38; + public const MESA_PLATEAU = 39; + public const WARM_OCEAN = 40; + public const DEEP_WARM_OCEAN = 41; + public const LUKEWARM_OCEAN = 42; + public const DEEP_LUKEWARM_OCEAN = 43; + public const COLD_OCEAN = 44; + public const DEEP_COLD_OCEAN = 45; + public const FROZEN_OCEAN = 46; + public const DEEP_FROZEN_OCEAN = 47; + public const BAMBOO_JUNGLE = 48; + public const BAMBOO_JUNGLE_HILLS = 49; + + public const SUNFLOWER_PLAINS = 129; + public const DESERT_MUTATED = 130; + public const EXTREME_HILLS_MUTATED = 131; + public const FLOWER_FOREST = 132; + public const TAIGA_MUTATED = 133; + public const SWAMPLAND_MUTATED = 134; + + public const ICE_PLAINS_SPIKES = 140; + + public const JUNGLE_MUTATED = 149; + + public const JUNGLE_EDGE_MUTATED = 151; + + public const BIRCH_FOREST_MUTATED = 155; + public const BIRCH_FOREST_HILLS_MUTATED = 156; + public const ROOFED_FOREST_MUTATED = 157; + public const COLD_TAIGA_MUTATED = 158; + + public const REDWOOD_TAIGA_MUTATED = 160; + public const REDWOOD_TAIGA_HILLS_MUTATED = 161; + public const EXTREME_HILLS_PLUS_TREES_MUTATED = 162; + public const SAVANNA_MUTATED = 163; + public const SAVANNA_PLATEAU_MUTATED = 164; + public const MESA_BRYCE = 165; + public const MESA_PLATEAU_STONE_MUTATED = 166; + public const MESA_PLATEAU_MUTATED = 167; + + public const SOULSAND_VALLEY = 178; + public const CRIMSON_FOREST = 179; + public const WARPED_FOREST = 180; + public const BASALT_DELTAS = 181; } diff --git a/src/world/biome/BiomeRegistry.php b/src/world/biome/BiomeRegistry.php index 803d1b1c3e..9e7f3077b8 100644 --- a/src/world/biome/BiomeRegistry.php +++ b/src/world/biome/BiomeRegistry.php @@ -42,17 +42,17 @@ final class BiomeRegistry{ $this->register(BiomeIds::OCEAN, new OceanBiome()); $this->register(BiomeIds::PLAINS, new PlainBiome()); $this->register(BiomeIds::DESERT, new DesertBiome()); - $this->register(BiomeIds::MOUNTAINS, new MountainsBiome()); + $this->register(BiomeIds::EXTREME_HILLS, new MountainsBiome()); $this->register(BiomeIds::FOREST, new ForestBiome()); $this->register(BiomeIds::TAIGA, new TaigaBiome()); - $this->register(BiomeIds::SWAMP, new SwampBiome()); + $this->register(BiomeIds::SWAMPLAND, new SwampBiome()); $this->register(BiomeIds::RIVER, new RiverBiome()); $this->register(BiomeIds::HELL, new HellBiome()); $this->register(BiomeIds::ICE_PLAINS, new IcePlainsBiome()); - $this->register(BiomeIds::SMALL_MOUNTAINS, new SmallMountainsBiome()); + $this->register(BiomeIds::EXTREME_HILLS_EDGE, new SmallMountainsBiome()); $this->register(BiomeIds::BIRCH_FOREST, new ForestBiome(TreeType::BIRCH())); } diff --git a/src/world/generator/normal/Normal.php b/src/world/generator/normal/Normal.php index be7de07652..9ee0426820 100644 --- a/src/world/generator/normal/Normal.php +++ b/src/world/generator/normal/Normal.php @@ -76,7 +76,7 @@ class Normal extends Generator{ }elseif($temperature < 0.85){ return BiomeIds::RIVER; }else{ - return BiomeIds::SWAMP; + return BiomeIds::SWAMPLAND; } }elseif($rainfall < 0.60){ if($temperature < 0.25){ @@ -96,9 +96,9 @@ class Normal extends Generator{ } }else{ if($temperature < 0.20){ - return BiomeIds::MOUNTAINS; + return BiomeIds::EXTREME_HILLS; }elseif($temperature < 0.40){ - return BiomeIds::SMALL_MOUNTAINS; + return BiomeIds::EXTREME_HILLS_EDGE; }else{ return BiomeIds::RIVER; } From 1246d1b7ef944b62d77ccf24df4182fe544b61f8 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Sat, 24 Jul 2021 22:10:50 +0100 Subject: [PATCH 2640/3224] Use a subprocess for reading lines from STDIN (#4332) this FINALLY provides us with a way to deal with Windows without needing to forcibly terminate the entire server on shutdown. --- src/console/ConsoleReaderChildProcess.php | 49 +++++++++++++ src/console/ConsoleReaderThread.php | 89 +++++++++++++++++------ tests/phpstan/configs/phpstan-bugs.neon | 5 ++ 3 files changed, 121 insertions(+), 22 deletions(-) create mode 100644 src/console/ConsoleReaderChildProcess.php diff --git a/src/console/ConsoleReaderChildProcess.php b/src/console/ConsoleReaderChildProcess.php new file mode 100644 index 0000000000..ea827ecc8f --- /dev/null +++ b/src/console/ConsoleReaderChildProcess.php @@ -0,0 +1,49 @@ +readLine(); + if($line !== null){ + fwrite($socket, $line . "\n"); + } +} diff --git a/src/console/ConsoleReaderThread.php b/src/console/ConsoleReaderThread.php index accc6a8398..2fc139b3e4 100644 --- a/src/console/ConsoleReaderThread.php +++ b/src/console/ConsoleReaderThread.php @@ -25,10 +25,21 @@ namespace pocketmine\console; use pocketmine\snooze\SleeperNotifier; use pocketmine\thread\Thread; -use pocketmine\thread\ThreadException; -use function microtime; +use pocketmine\utils\AssumptionFailedError; +use Webmozart\PathUtil\Path; +use function fgets; +use function fopen; use function preg_replace; -use function usleep; +use function proc_open; +use function proc_terminate; +use function sprintf; +use function stream_select; +use function stream_socket_accept; +use function stream_socket_get_name; +use function stream_socket_server; +use function stream_socket_shutdown; +use const PHP_BINARY; +use const STREAM_SHUT_RDWR; final class ConsoleReaderThread extends Thread{ private \Threaded $buffer; @@ -45,35 +56,69 @@ final class ConsoleReaderThread extends Thread{ $this->shutdown = true; } - public function quit() : void{ - $wait = microtime(true) + 0.5; - while(microtime(true) < $wait){ - if($this->isRunning()){ - usleep(100000); - }else{ - parent::quit(); - return; - } - } - - throw new ThreadException("CommandReader is stuck in a blocking STDIN read"); - } - protected function onRun() : void{ $buffer = $this->buffer; $notifier = $this->notifier; - $reader = new ConsoleReader(); - while(!$this->shutdown){ - $line = $reader->readLine(); + /* + * This pile of shit exists because PHP on Windows is broken, and can't handle stream_select() on stdin or pipes + * properly - stdin native triggers stream_select() when a key is pressed, causing it to get stuck in fgets() + * waiting for a line that might never come (and Windows doesn't support character-based reading either), and + * pipes just constantly trigger stream_select() instead of only when data is returned, rendering it useless. + * + * This results in whichever process reads stdin getting stuck on shutdown, which previously forced us to kill + * the entire server process to make it go away. + * + * To get around this problem, we delegate the responsibility of reading stdin to a subprocess, which we can + * then brutally murder when the server shuts down, without killing the entire server process. + * Thankfully, stream_select() actually works properly on sockets, so we can use them for inter-process + * communication. + */ - if($line !== null){ - $buffer[] = preg_replace("#\\x1b\\x5b([^\\x1b]*\\x7e|[\\x40-\\x50])#", "", $line); + $server = stream_socket_server("tcp://127.0.0.1:0"); + if($server === false){ + throw new \RuntimeException("Failed to open console reader socket server"); + } + $address = stream_socket_get_name($server, false); + if($address === false) throw new AssumptionFailedError("stream_socket_get_name() shouldn't return false here"); + + $sub = proc_open( + [PHP_BINARY, '-r', sprintf('require "%s";', Path::join(__DIR__, 'ConsoleReaderChildProcess.php')), $address], + [ + 2 => fopen("php://stderr", "w"), + ], + $pipes + ); + if($sub === false){ + throw new AssumptionFailedError("Something has gone horribly wrong"); + } + $client = stream_socket_accept($server); + if($client === false){ + throw new AssumptionFailedError("stream_socket_accept() returned false"); + } + stream_socket_shutdown($server, STREAM_SHUT_RDWR); + while(!$this->shutdown){ + $r = [$client]; + $w = null; + $e = null; + if(stream_select($r, $w, $e, 0, 200000) === 1){ + $command = fgets($client); + if($command === false){ + throw new AssumptionFailedError("Something has gone horribly wrong"); + } + + $buffer[] = preg_replace("#\\x1b\\x5b([^\\x1b]*\\x7e|[\\x40-\\x50])#", "", $command); if($notifier !== null){ $notifier->wakeupSleeper(); } } } + + //we have no way to signal to the subprocess to shut down gracefully; besides, Windows sucks, and the subprocess + //gets stuck in a blocking fgets() read because stream_select() is a hunk of junk (hence the separate process in + //the first place). + proc_terminate($sub); + stream_socket_shutdown($client, STREAM_SHUT_RDWR); } public function getThreadName() : string{ diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 48a613645c..b484b3e8b5 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -10,6 +10,11 @@ parameters: count: 2 path: ../../../src/console/ConsoleReader.php + - + message: "#^Parameter \\#1 \\$command of function proc_open expects string, array\\ given\\.$#" + count: 1 + path: ../../../src/console/ConsoleReaderThread.php + - message: "#^Method pocketmine\\\\crafting\\\\CraftingManager\\:\\:getDestructorCallbacks\\(\\) should return pocketmine\\\\utils\\\\ObjectSet\\ but returns pocketmine\\\\utils\\\\ObjectSet\\\\|pocketmine\\\\utils\\\\ObjectSet\\\\.$#" count: 1 From 1afda04620606e49cd4a8eeb04d08ff3908f2da4 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Sun, 25 Jul 2021 12:27:25 +0100 Subject: [PATCH 2641/3224] PrimedTNT: fixed fuse not getting updated client-side, closes #4333 --- src/entity/object/PrimedTNT.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/entity/object/PrimedTNT.php b/src/entity/object/PrimedTNT.php index 184a30285a..f3ed921b89 100644 --- a/src/entity/object/PrimedTNT.php +++ b/src/entity/object/PrimedTNT.php @@ -104,6 +104,7 @@ class PrimedTNT extends Entity implements Explosive{ if(!$this->isFlaggedForDespawn()){ $this->fuse -= $tickDiff; + $this->networkPropertiesDirty = true; if($this->fuse <= 0){ $this->flagForDespawn(); From c7bb77e24a2d5832637bb2c162c5939ed838a198 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Mon, 26 Jul 2021 15:07:39 +0100 Subject: [PATCH 2642/3224] ConsoleReaderChildProcess: die voluntarily if connection to server process is closed this happens if the parent process is killed via SIGINT, because its stdin will be closed, interrupting a blocking read. This might also happen if the user pressed CTRL+D, so we don't die unless end of socket stream was also detected. closes #4335 --- src/console/ConsoleReaderChildProcess.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/console/ConsoleReaderChildProcess.php b/src/console/ConsoleReaderChildProcess.php index ea827ecc8f..bf9bf0213b 100644 --- a/src/console/ConsoleReaderChildProcess.php +++ b/src/console/ConsoleReaderChildProcess.php @@ -41,7 +41,7 @@ if($socket === false){ throw new \RuntimeException("Failed to connect to server process"); } $consoleReader = new ConsoleReader(); -while(true){ +while(!feof($socket)){ $line = $consoleReader->readLine(); if($line !== null){ fwrite($socket, $line . "\n"); From c2c9132812fa962a6ce6748237cdb3a026f2db8d Mon Sep 17 00:00:00 2001 From: Dylan T Date: Mon, 26 Jul 2021 15:17:24 +0100 Subject: [PATCH 2643/3224] ConsoleReaderThread: say what actually happened when we fail to read commands --- src/console/ConsoleReaderThread.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/console/ConsoleReaderThread.php b/src/console/ConsoleReaderThread.php index 2fc139b3e4..b2456e1fa7 100644 --- a/src/console/ConsoleReaderThread.php +++ b/src/console/ConsoleReaderThread.php @@ -104,7 +104,7 @@ final class ConsoleReaderThread extends Thread{ if(stream_select($r, $w, $e, 0, 200000) === 1){ $command = fgets($client); if($command === false){ - throw new AssumptionFailedError("Something has gone horribly wrong"); + throw new \RuntimeException("Broken connection to child process (probably killed)"); } $buffer[] = preg_replace("#\\x1b\\x5b([^\\x1b]*\\x7e|[\\x40-\\x50])#", "", $command); From f9863acadc1e3e70581a13a96295dc61ac17cea5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 26 Jul 2021 15:38:38 +0100 Subject: [PATCH 2644/3224] Restart console reader subprocess if it dies this can happen for a bunch of different reasons, which are all indistinguishable. This also fixes pmmp/PcntlSignalHandler#3. --- src/console/ConsoleReaderThread.php | 39 ++++++++++++++++++----------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/console/ConsoleReaderThread.php b/src/console/ConsoleReaderThread.php index b2456e1fa7..afd1eedf0c 100644 --- a/src/console/ConsoleReaderThread.php +++ b/src/console/ConsoleReaderThread.php @@ -60,21 +60,26 @@ final class ConsoleReaderThread extends Thread{ $buffer = $this->buffer; $notifier = $this->notifier; - /* - * This pile of shit exists because PHP on Windows is broken, and can't handle stream_select() on stdin or pipes - * properly - stdin native triggers stream_select() when a key is pressed, causing it to get stuck in fgets() - * waiting for a line that might never come (and Windows doesn't support character-based reading either), and - * pipes just constantly trigger stream_select() instead of only when data is returned, rendering it useless. - * - * This results in whichever process reads stdin getting stuck on shutdown, which previously forced us to kill - * the entire server process to make it go away. - * - * To get around this problem, we delegate the responsibility of reading stdin to a subprocess, which we can - * then brutally murder when the server shuts down, without killing the entire server process. - * Thankfully, stream_select() actually works properly on sockets, so we can use them for inter-process - * communication. - */ + while(!$this->shutdown){ + $this->runSubprocess($buffer, $notifier); + } + } + /** + * This pile of shit exists because PHP on Windows is broken, and can't handle stream_select() on stdin or pipes + * properly - stdin native triggers stream_select() when a key is pressed, causing it to get stuck in fgets() + * waiting for a line that might never come (and Windows doesn't support character-based reading either), and + * pipes just constantly trigger stream_select() instead of only when data is returned, rendering it useless. + * + * This results in whichever process reads stdin getting stuck on shutdown, which previously forced us to kill + * the entire server process to make it go away. + * + * To get around this problem, we delegate the responsibility of reading stdin to a subprocess, which we can + * then brutally murder when the server shuts down, without killing the entire server process. + * Thankfully, stream_select() actually works properly on sockets, so we can use them for inter-process + * communication. + */ + private function runSubprocess(\Threaded $buffer, ?SleeperNotifier $notifier) : void{ $server = stream_socket_server("tcp://127.0.0.1:0"); if($server === false){ throw new \RuntimeException("Failed to open console reader socket server"); @@ -104,7 +109,11 @@ final class ConsoleReaderThread extends Thread{ if(stream_select($r, $w, $e, 0, 200000) === 1){ $command = fgets($client); if($command === false){ - throw new \RuntimeException("Broken connection to child process (probably killed)"); + //subprocess died for some reason; this could be someone killed it manually from outside (e.g. + //mistyped PID) or it might be a ctrl+c signal to this process that the child is handling + //differently (different signal handlers). + //since we have no way to know the difference, we just kill the sub and start a new one. + break; } $buffer[] = preg_replace("#\\x1b\\x5b([^\\x1b]*\\x7e|[\\x40-\\x50])#", "", $command); From 2b5667a56bb0448ed04149268f4cb942353cf8d7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 26 Jul 2021 20:29:39 +0100 Subject: [PATCH 2645/3224] Move PHP minimum to 8.0 --- .github/workflows/main.yml | 17 ++--- composer.json | 4 +- composer.lock | 35 +++++----- phpstan.neon.dist | 4 -- phpstan.php7.neon | 10 --- src/PocketMine.php | 2 +- src/network/mcpe/JwtUtils.php | 22 ++---- .../mcpe/encryption/EncryptionUtils.php | 14 +--- .../mcpe/encryption/PrepareEncryptionTask.php | 6 +- .../query/DedicatedQueryNetworkInterface.php | 6 +- src/utils/Internet.php | 2 +- src/utils/Timezone.php | 3 - src/utils/Utils.php | 4 +- tests/phpstan/configs/php7.neon | 67 ------------------- tests/phpstan/configs/php74-compat.neon | 12 ---- 15 files changed, 37 insertions(+), 171 deletions(-) delete mode 100644 phpstan.php7.neon delete mode 100644 tests/phpstan/configs/php7.neon delete mode 100644 tests/phpstan/configs/php74-compat.neon diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 35851d6f24..0bbf26852b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: image: [ubuntu-20.04] - php: [7.4.20, 8.0.7] + php: [8.0.7] steps: - uses: actions/checkout@v2 #needed for build.sh @@ -36,13 +36,8 @@ jobs: strategy: fail-fast: false matrix: - include: - - php: 8.0.7 - config: phpstan.neon.dist - image: ubuntu-20.04 - - php: 7.4.20 - config: phpstan.php7.neon - image: ubuntu-20.04 + image: [ubuntu-20.04] + php: [8.0.7] steps: - uses: actions/checkout@v2 @@ -92,7 +87,7 @@ jobs: fail-fast: false matrix: image: [ubuntu-20.04] - php: [7.4.20, 8.0.7] + php: [8.0.7] steps: - uses: actions/checkout@v2 @@ -144,7 +139,7 @@ jobs: fail-fast: false matrix: image: [ubuntu-20.04] - php: [7.4.20, 8.0.7] + php: [8.0.7] steps: - uses: actions/checkout@v2 @@ -196,7 +191,7 @@ jobs: fail-fast: false matrix: image: [ubuntu-20.04] - php: [7.4.20, 8.0.7] + php: [8.0.7] steps: - uses: actions/checkout@v2 diff --git a/composer.json b/composer.json index 6548e7df54..09e3b5bd6c 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,7 @@ "homepage": "https://pmmp.io", "license": "LGPL-3.0", "require": { - "php": "^7.4 || ^8.0", + "php": "^8.0", "php-64bit": "*", "ext-chunkutils2": "^0.2.0", "ext-crypto": "^0.3.1", @@ -74,7 +74,7 @@ }, "config": { "platform": { - "php": "7.4.0" + "php": "8.0.0" }, "sort-packages": true }, diff --git a/composer.lock b/composer.lock index eaada0c98c..1b52df1962 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "49005f17832ef5949b4a2ac04cd1ee93", + "content-hash": "a6269c62c36da26e5e628322bdcdbb51", "packages": [ { "name": "adhocore/json-comment", @@ -268,7 +268,7 @@ "ramsey/uuid": "^4.1" }, "require-dev": { - "phpstan/phpstan": "0.12.92", + "phpstan/phpstan": "0.12.93", "phpstan/phpstan-phpunit": "^0.12.21", "phpstan/phpstan-strict-rules": "^0.12.10", "phpunit/phpunit": "^9.5" @@ -289,7 +289,7 @@ "issues": "https://github.com/pmmp/BedrockProtocol/issues", "source": "https://github.com/pmmp/BedrockProtocol/tree/master" }, - "time": "2021-07-14T19:29:34+00:00" + "time": "2021-07-23T22:10:41+00:00" }, { "name": "pocketmine/binaryutils", @@ -1522,16 +1522,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.11.0", + "version": "v4.12.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "fe14cf3672a149364fb66dfe11bf6549af899f94" + "reference": "6608f01670c3cc5079e18c1dab1104e002579143" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/fe14cf3672a149364fb66dfe11bf6549af899f94", - "reference": "fe14cf3672a149364fb66dfe11bf6549af899f94", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6608f01670c3cc5079e18c1dab1104e002579143", + "reference": "6608f01670c3cc5079e18c1dab1104e002579143", "shasum": "" }, "require": { @@ -1572,22 +1572,22 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.11.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.12.0" }, - "time": "2021-07-03T13:36:55+00:00" + "time": "2021-07-21T10:44:31+00:00" }, { "name": "phar-io/manifest", - "version": "2.0.1", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133" + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", - "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", "shasum": "" }, "require": { @@ -1632,9 +1632,9 @@ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/master" + "source": "https://github.com/phar-io/manifest/tree/2.0.3" }, - "time": "2020-06-27T14:33:11+00:00" + "time": "2021-07-20T11:28:43+00:00" }, { "name": "phar-io/version", @@ -3354,6 +3354,7 @@ "type": "github" } ], + "abandoned": true, "time": "2020-09-28T06:45:17+00:00" }, { @@ -3526,7 +3527,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^7.4 || ^8.0", + "php": "^8.0", "php-64bit": "*", "ext-chunkutils2": "^0.2.0", "ext-crypto": "^0.3.1", @@ -3555,7 +3556,7 @@ }, "platform-dev": [], "platform-overrides": { - "php": "7.4.0" + "php": "8.0.0" }, "plugin-api-version": "2.1.0" } diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 7e347bceef..cd3c5b18b3 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -5,7 +5,6 @@ includes: - tests/phpstan/configs/impossible-generics.neon - tests/phpstan/configs/l7-baseline.neon - tests/phpstan/configs/l8-baseline.neon - - tests/phpstan/configs/php74-compat.neon - tests/phpstan/configs/php-bugs.neon - tests/phpstan/configs/phpstan-bugs.neon - tests/phpstan/configs/phpunit-wiring-tests.neon @@ -57,6 +56,3 @@ parameters: #we'll just fill it with 10 - it's very unlikely to encounter a callable with 10 parameters anyway. anyCallable: 'callable(mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed) : mixed' anyClosure: '\Closure(mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed) : mixed' - PhpSocket: '\Socket' - PhpCurlHandle: '\CurlHandle' - PhpOpenSSLAsymmetricKey: '\OpenSSLAsymmetricKey' diff --git a/phpstan.php7.neon b/phpstan.php7.neon deleted file mode 100644 index 2c6ef7729f..0000000000 --- a/phpstan.php7.neon +++ /dev/null @@ -1,10 +0,0 @@ -includes: - - phpstan.neon.dist - - tests/phpstan/configs/php7.neon - -parameters: - phpVersion: 70400 - typeAliases: - PhpSocket: resource - PhpCurlHandle: resource - PhpOpenSSLAsymmetricKey: resource diff --git a/src/PocketMine.php b/src/PocketMine.php index 06f148132b..c96cd8060d 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -43,7 +43,7 @@ namespace pocketmine { require_once __DIR__ . '/VersionInfo.php'; - const MIN_PHP_VERSION = "7.4.0"; + const MIN_PHP_VERSION = "8.0.0"; /** * @param string $message diff --git a/src/network/mcpe/JwtUtils.php b/src/network/mcpe/JwtUtils.php index 49ed2211ae..06d5cdfee9 100644 --- a/src/network/mcpe/JwtUtils.php +++ b/src/network/mcpe/JwtUtils.php @@ -97,12 +97,9 @@ final class JwtUtils{ } /** - * @param \OpenSSLAsymmetricKey|resource $signingKey - * @phpstan-param PhpOpenSSLAsymmetricKey $signingKey - * * @throws JwtException */ - public static function verify(string $jwt, $signingKey) : bool{ + public static function verify(string $jwt, \OpenSSLAsymmetricKey $signingKey) : bool{ [$header, $body, $signature] = self::split($jwt); $plainSignature = self::b64UrlDecode($signature); @@ -133,13 +130,10 @@ final class JwtUtils{ } /** - * @param \OpenSSLAsymmetricKey|resource $signingKey - * @phpstan-param PhpOpenSSLAsymmetricKey $signingKey - * * @phpstan-param array $header * @phpstan-param array $claims */ - public static function create(array $header, array $claims, $signingKey) : string{ + public static function create(array $header, array $claims, \OpenSSLAsymmetricKey $signingKey) : string{ $jwtBody = JwtUtils::b64UrlEncode(json_encode($header, JSON_THROW_ON_ERROR)) . "." . JwtUtils::b64UrlEncode(json_encode($claims, JSON_THROW_ON_ERROR)); openssl_sign( @@ -190,11 +184,7 @@ final class JwtUtils{ return $decoded; } - /** - * @param \OpenSSLAsymmetricKey|resource $opensslKey - * @phpstan-param PhpOpenSSLAsymmetricKey $opensslKey - */ - public static function emitDerPublicKey($opensslKey) : string{ + public static function emitDerPublicKey(\OpenSSLAsymmetricKey $opensslKey) : string{ $details = openssl_pkey_get_details($opensslKey); if($details === false){ throw new AssumptionFailedError("Failed to get details from OpenSSL key resource"); @@ -211,11 +201,7 @@ final class JwtUtils{ throw new AssumptionFailedError("OpenSSL resource contains invalid public key"); } - /** - * @return \OpenSSLAsymmetricKey|resource - * @phpstan-return PhpOpenSSLAsymmetricKey - */ - public static function parseDerPublicKey(string $derKey){ + public static function parseDerPublicKey(string $derKey) : \OpenSSLAsymmetricKey{ $signingKeyOpenSSL = openssl_pkey_get_public(sprintf("-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----\n", base64_encode($derKey))); if($signingKeyOpenSSL === false){ throw new JwtException("OpenSSL failed to parse key: " . openssl_error_string()); diff --git a/src/network/mcpe/encryption/EncryptionUtils.php b/src/network/mcpe/encryption/EncryptionUtils.php index a8e5662218..0ad2ebfee2 100644 --- a/src/network/mcpe/encryption/EncryptionUtils.php +++ b/src/network/mcpe/encryption/EncryptionUtils.php @@ -40,13 +40,7 @@ final class EncryptionUtils{ //NOOP } - /** - * @param \OpenSSLAsymmetricKey|resource $localPriv - * @param \OpenSSLAsymmetricKey|resource $remotePub - * @phpstan-param PhpOpenSSLAsymmetricKey $localPriv - * @phpstan-param PhpOpenSSLAsymmetricKey $remotePub - */ - public static function generateSharedSecret($localPriv, $remotePub) : \GMP{ + public static function generateSharedSecret(\OpenSSLAsymmetricKey $localPriv, \OpenSSLAsymmetricKey $remotePub) : \GMP{ $hexSecret = openssl_pkey_derive($remotePub, $localPriv, 48); if($hexSecret === false){ throw new \InvalidArgumentException("Failed to derive shared secret: " . openssl_error_string()); @@ -58,11 +52,7 @@ final class EncryptionUtils{ return openssl_digest($salt . hex2bin(str_pad(gmp_strval($secret, 16), 96, "0", STR_PAD_LEFT)), 'sha256', true); } - /** - * @param \OpenSSLAsymmetricKey|resource $serverPriv - * @phpstan-param PhpOpenSSLAsymmetricKey $serverPriv - */ - public static function generateServerHandshakeJwt($serverPriv, string $salt) : string{ + public static function generateServerHandshakeJwt(\OpenSSLAsymmetricKey $serverPriv, string $salt) : string{ $derPublicKey = JwtUtils::emitDerPublicKey($serverPriv); return JwtUtils::create( [ diff --git a/src/network/mcpe/encryption/PrepareEncryptionTask.php b/src/network/mcpe/encryption/PrepareEncryptionTask.php index b18a16d731..75b3b1f1cf 100644 --- a/src/network/mcpe/encryption/PrepareEncryptionTask.php +++ b/src/network/mcpe/encryption/PrepareEncryptionTask.php @@ -38,11 +38,7 @@ class PrepareEncryptionTask extends AsyncTask{ private const TLS_KEY_ON_COMPLETION = "completion"; - /** - * @var \OpenSSLAsymmetricKey|resource|null - * @phpstan-var PhpOpenSSLAsymmetricKey|null - */ - private static $SERVER_PRIVATE_KEY = null; + private static ?\OpenSSLAsymmetricKey $SERVER_PRIVATE_KEY = null; /** @var string */ private $serverPrivateKey; diff --git a/src/network/query/DedicatedQueryNetworkInterface.php b/src/network/query/DedicatedQueryNetworkInterface.php index 184b4f54a9..d742c9e53d 100644 --- a/src/network/query/DedicatedQueryNetworkInterface.php +++ b/src/network/query/DedicatedQueryNetworkInterface.php @@ -63,11 +63,7 @@ final class DedicatedQueryNetworkInterface implements AdvancedNetworkInterface{ private $port; /** @var \Logger */ private $logger; - /** - * @var \Socket|resource - * @phpstan-var PhpSocket - */ - private $socket; + private \Socket $socket; /** @var Network */ private $network; /** diff --git a/src/utils/Internet.php b/src/utils/Internet.php index 639f3f912f..d7f602cb6e 100644 --- a/src/utils/Internet.php +++ b/src/utils/Internet.php @@ -185,7 +185,7 @@ class Internet{ * @param \Closure|null $onSuccess function to be called if there is no error. Accepts a resource argument as the cURL handle. * @phpstan-param array $extraOpts * @phpstan-param list $extraHeaders - * @phpstan-param (\Closure(PhpCurlHandle) : void)|null $onSuccess + * @phpstan-param (\Closure(\CurlHandle) : void)|null $onSuccess * * @throws InternetException if a cURL error occurs */ diff --git a/src/utils/Timezone.php b/src/utils/Timezone.php index 673671ec53..1cd6677154 100644 --- a/src/utils/Timezone.php +++ b/src/utils/Timezone.php @@ -193,9 +193,6 @@ abstract class Timezone{ } $parsed = date_parse($offset); - if($parsed === false){ - return false; - } $offset = $parsed['hour'] * 3600 + $parsed['minute'] * 60 + $parsed['second']; //After date_parse is done, put the sign back diff --git a/src/utils/Utils.php b/src/utils/Utils.php index 26081a5ded..32c40d92f3 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -470,9 +470,7 @@ final class Utils{ } preg_match_all('/(*ANYCRLF)^[\t ]*(?:\* )?@([a-zA-Z]+)(?:[\t ]+(.+?))?[\t ]*$/m', $rawDocComment, $matches); - $result = array_combine($matches[1], $matches[2]); - if($result === false) throw new AssumptionFailedError("array_combine() doesn't return false with two equal-sized arrays"); - return $result; + return array_combine($matches[1], $matches[2]); } /** diff --git a/tests/phpstan/configs/php7.neon b/tests/phpstan/configs/php7.neon deleted file mode 100644 index b263cb1cab..0000000000 --- a/tests/phpstan/configs/php7.neon +++ /dev/null @@ -1,67 +0,0 @@ -parameters: - ignoreErrors: - - - message: "#^Parameter \\#1 \\$fp of function fclose expects resource, resource\\|false given\\.$#" - count: 1 - path: ../../../src/MemoryManager.php - - - - message: "#^Parameter \\#1 \\$fp of function fwrite expects resource, resource\\|false given\\.$#" - count: 1 - path: ../../../src/MemoryManager.php - - - - message: "#^Parameter \\#1 \\$str of function strtolower expects string, mixed given\\.$#" - count: 1 - path: ../../../src/ServerConfigGroup.php - - - - message: "#^Parameter \\#1 \\$fp of function fclose expects resource, resource\\|false given\\.$#" - count: 2 - path: ../../../src/command/defaults/TimingsCommand.php - - - - message: "#^Parameter \\#1 \\$fp of function fseek expects resource, resource\\|false given\\.$#" - count: 1 - path: ../../../src/command/defaults/TimingsCommand.php - - - - message: "#^Parameter \\#1 \\$fp of function fwrite expects resource, resource\\|false given\\.$#" - count: 1 - path: ../../../src/command/defaults/TimingsCommand.php - - - - message: "#^Parameter \\#1 \\$source of function stream_get_contents expects resource, resource\\|false given\\.$#" - count: 1 - path: ../../../src/command/defaults/TimingsCommand.php - - - - message: "#^Parameter \\#1 \\$argument of class ReflectionClass constructor expects class\\-string\\\\|T of object, string given\\.$#" - count: 1 - path: ../../../src/event/HandlerListManager.php - - - - message: "#^Parameter \\#2 \\$input1 of function array_map expects array, array\\|false given\\.$#" - count: 1 - path: ../../../src/lang/Language.php - - - - message: "#^Parameter \\#2 \\$start of function substr expects int, mixed given\\.$#" - count: 1 - path: ../../../src/utils/Internet.php - - - - message: "#^Parameter \\#3 \\$length of function substr expects int, mixed given\\.$#" - count: 1 - path: ../../../src/utils/Internet.php - - - - message: "#^Parameter \\#1 \\$timezone_identifier of function date_default_timezone_set expects string, string\\|false given\\.$#" - count: 1 - path: ../../../src/utils/Timezone.php - - - - message: "#^Parameter \\#2 \\$input1 of function array_map expects array, mixed given\\.$#" - count: 1 - path: ../../../src/utils/Utils.php - diff --git a/tests/phpstan/configs/php74-compat.neon b/tests/phpstan/configs/php74-compat.neon deleted file mode 100644 index 0ca093a67e..0000000000 --- a/tests/phpstan/configs/php74-compat.neon +++ /dev/null @@ -1,12 +0,0 @@ -parameters: - ignoreErrors: - - - message: "#^Strict comparison using \\=\\=\\= between array\\ and false will always evaluate to false\\.$#" - count: 1 - path: ../../../src/utils/Timezone.php - - - - message: "#^Strict comparison using \\=\\=\\= between array and false will always evaluate to false\\.$#" - count: 1 - path: ../../../src/utils/Utils.php - From 3319fad86313096547c2dcd689dcba834b600915 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 26 Jul 2021 20:33:44 +0100 Subject: [PATCH 2646/3224] Fix build error --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0bbf26852b..27f54c08cb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -77,7 +77,7 @@ jobs: run: php composer.phar install --prefer-dist --no-interaction - name: Run PHPStan - run: ./vendor/bin/phpstan analyze --no-progress --memory-limit=2G -c ${{ matrix.config }} + run: ./vendor/bin/phpstan analyze --no-progress --memory-limit=2G phpunit: name: PHPUnit tests From 22c3736d636a0dfe181318f87b270710418d1b12 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 30 Jul 2021 23:30:28 +0100 Subject: [PATCH 2647/3224] LightUpdate: micro optimisations opcache isn't smart enough for this removes 6 unnecessary opcodes from computeSpreadLight() and 3 from computeRemoveLight(). Tested with opcache.opt_debug_level=0x20000. --- src/world/light/LightUpdate.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/world/light/LightUpdate.php b/src/world/light/LightUpdate.php index 2a531a89f3..ed430354a3 100644 --- a/src/world/light/LightUpdate.php +++ b/src/world/light/LightUpdate.php @@ -167,10 +167,13 @@ abstract class LightUpdate{ protected function computeRemoveLight(int $x, int $y, int $z, int $oldAdjacentLevel, LightPropagationContext $context) : void{ $lightArray = $this->getCurrentLightArray(); - $current = $lightArray->get($x & 0xf, $y & 0xf, $z & 0xf); + $lx = $x & 0xf; + $ly = $y & 0xf; + $lz = $z & 0xf; + $current = $lightArray->get($lx, $ly, $lz); if($current !== 0 and $current < $oldAdjacentLevel){ - $lightArray->set($x & 0xf, $y & 0xf, $z & 0xf, 0); + $lightArray->set($lx, $ly, $lz, 0); if(!isset($context->removalVisited[$index = World::blockHash($x, $y, $z)])){ $context->removalVisited[$index] = true; @@ -188,11 +191,14 @@ abstract class LightUpdate{ protected function computeSpreadLight(int $x, int $y, int $z, int $newAdjacentLevel, LightPropagationContext $context) : void{ $lightArray = $this->getCurrentLightArray(); - $current = $lightArray->get($x & 0xf, $y & 0xf, $z & 0xf); - $potentialLight = $newAdjacentLevel - $this->lightFilters[$this->subChunkExplorer->currentSubChunk->getFullBlock($x & 0x0f, $y & 0x0f, $z & 0x0f)]; + $lx = $x & 0xf; + $ly = $y & 0xf; + $lz = $z & 0xf; + $current = $lightArray->get($lx, $ly, $lz); + $potentialLight = $newAdjacentLevel - $this->lightFilters[$this->subChunkExplorer->currentSubChunk->getFullBlock($lx, $ly, $lz)]; if($current < $potentialLight){ - $lightArray->set($x & 0xf, $y & 0xf, $z & 0xf, $potentialLight); + $lightArray->set($lx, $ly, $lz, $potentialLight); if(!isset($context->spreadVisited[$index = World::blockHash($x, $y, $z)]) and $potentialLight > 1){ $context->spreadVisited[$index] = true; From 1bbf7393855587d4e46943afc7ae3b313dc74105 Mon Sep 17 00:00:00 2001 From: Sensei Tarzan <32621158+SenseiTarzan@users.noreply.github.com> Date: Sat, 31 Jul 2021 17:54:31 +0200 Subject: [PATCH 2648/3224] the function stringToLegacy gives already null useless to put a default null (#4338) --- src/network/mcpe/convert/RuntimeBlockMapping.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/convert/RuntimeBlockMapping.php b/src/network/mcpe/convert/RuntimeBlockMapping.php index 1185a02dde..45affea444 100644 --- a/src/network/mcpe/convert/RuntimeBlockMapping.php +++ b/src/network/mcpe/convert/RuntimeBlockMapping.php @@ -87,7 +87,7 @@ final class RuntimeBlockMapping{ $idToStatesMap[$state->getString("name")][] = $k; } foreach($legacyStateMap as $pair){ - $id = $legacyIdMap->stringToLegacy($pair->getId()) ?? null; + $id = $legacyIdMap->stringToLegacy($pair->getId()); if($id === null){ throw new \RuntimeException("No legacy ID matches " . $pair->getId()); } From eb23d27004967c7e08ecdedb3747ce3aab662451 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Sat, 31 Jul 2021 18:11:34 +0100 Subject: [PATCH 2649/3224] composer: accept ext-leveldb ^0.3.0 --- composer.json | 2 +- composer.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 09e3b5bd6c..fc719ec41d 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "ext-hash": "*", "ext-igbinary": "^3.0.1", "ext-json": "*", - "ext-leveldb": "^0.2.1", + "ext-leveldb": "^0.2.1 || ^0.3.0", "ext-mbstring": "*", "ext-morton": "^0.1.0", "ext-openssl": "*", diff --git a/composer.lock b/composer.lock index 1b52df1962..cbc17e9309 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a6269c62c36da26e5e628322bdcdbb51", + "content-hash": "6aa42d767f14ce036f410d0001fd3845", "packages": [ { "name": "adhocore/json-comment", @@ -3538,7 +3538,7 @@ "ext-hash": "*", "ext-igbinary": "^3.0.1", "ext-json": "*", - "ext-leveldb": "^0.2.1", + "ext-leveldb": "^0.2.1 || ^0.3.0", "ext-mbstring": "*", "ext-morton": "^0.1.0", "ext-openssl": "*", From 01b48a21d9fb8e3d4821af7c1fd5b9c0cd26ff0b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 2 Aug 2021 14:31:30 +0100 Subject: [PATCH 2650/3224] Simplify NetworkSession ticking we need to tick sessions every tick anyway, because other stuff is happening (e.g. sync attributes/entity metadata, batch buffer flush). --- src/network/NetworkSessionManager.php | 21 ++++++--------------- src/network/mcpe/NetworkSession.php | 8 ++------ 2 files changed, 8 insertions(+), 21 deletions(-) diff --git a/src/network/NetworkSessionManager.php b/src/network/NetworkSessionManager.php index 3a38f5f4ab..509d3df90b 100644 --- a/src/network/NetworkSessionManager.php +++ b/src/network/NetworkSessionManager.php @@ -31,15 +31,13 @@ class NetworkSessionManager{ /** @var NetworkSession[] */ private $sessions = []; - /** @var NetworkSession[] */ - private $updateSessions = []; /** * Adds a network session to the manager. This should only be called on session creation. */ public function add(NetworkSession $session) : void{ $idx = spl_object_id($session); - $this->sessions[$idx] = $this->updateSessions[$idx] = $session; + $this->sessions[$idx] = $session; } /** @@ -48,14 +46,7 @@ class NetworkSessionManager{ */ public function remove(NetworkSession $session) : void{ $idx = spl_object_id($session); - unset($this->sessions[$idx], $this->updateSessions[$idx]); - } - - /** - * Requests an update to be scheduled on the given network session at the next tick. - */ - public function scheduleUpdate(NetworkSession $session) : void{ - $this->updateSessions[spl_object_id($session)] = $session; + unset($this->sessions[$idx]); } /** @@ -72,9 +63,10 @@ class NetworkSessionManager{ * Updates all sessions which need it. */ public function tick() : void{ - foreach($this->updateSessions as $k => $session){ - if(!$session->tick()){ - unset($this->updateSessions[$k]); + foreach($this->sessions as $k => $session){ + $session->tick(); + if(!$session->isConnected()){ + unset($this->sessions[$k]); } } } @@ -87,6 +79,5 @@ class NetworkSessionManager{ $session->disconnect($reason); } $this->sessions = []; - $this->updateSessions = []; } } diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index ca3179265b..06bd45eacb 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -421,7 +421,6 @@ class NetworkSession{ $timings->startTiming(); try{ $this->sendBuffer[] = $packet; - $this->manager->scheduleUpdate($this); //schedule flush at end of tick }finally{ $timings->stopTiming(); } @@ -1021,14 +1020,13 @@ class NetworkSession{ $this->sendDataPacket(SetTitlePacket::setAnimationTimes($fadeIn, $stay, $fadeOut)); } - public function tick() : bool{ + public function tick() : void{ if($this->info === null){ if(time() >= $this->connectTime + 10){ $this->disconnect("Login timeout"); - return false; } - return true; //keep ticking until timeout + return; } if($this->player !== null){ @@ -1044,7 +1042,5 @@ class NetworkSession{ } $this->flushSendBuffer(); - - return true; } } From bdac98beafea8dc1c227c8ee9751907fa4dae851 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 2 Aug 2021 19:17:24 +0100 Subject: [PATCH 2651/3224] Block: get rid of getNonPersistentStateBitmask(), add writeStateToItemMeta() this is more flexible and less confusing. --- src/block/Anvil.php | 4 ++-- src/block/BaseBanner.php | 6 ++---- src/block/Bed.php | 5 ++--- src/block/Block.php | 10 +++++----- src/block/Coral.php | 8 ++++---- src/block/CoralBlock.php | 8 ++++---- src/block/Dirt.php | 8 ++++---- src/block/FloorCoralFan.php | 10 +++++----- src/block/Skull.php | 6 ++---- src/block/Sponge.php | 8 ++++---- src/block/TNT.php | 6 ++++-- src/block/WallCoralFan.php | 10 +++++----- src/block/utils/ColorInMetadataTrait.php | 14 +++++++------- 13 files changed, 50 insertions(+), 53 deletions(-) diff --git a/src/block/Anvil.php b/src/block/Anvil.php index 050ecc057b..946c78c27e 100644 --- a/src/block/Anvil.php +++ b/src/block/Anvil.php @@ -54,8 +54,8 @@ class Anvil extends Transparent implements Fallable{ return 0b1111; } - public function getNonPersistentStateBitmask() : int{ - return 0b11; + protected function writeStateToItemMeta() : int{ + return $this->damage << 2; } public function getDamage() : int{ return $this->damage; } diff --git a/src/block/BaseBanner.php b/src/block/BaseBanner.php index 9fa9a7550e..36a637864e 100644 --- a/src/block/BaseBanner.php +++ b/src/block/BaseBanner.php @@ -30,8 +30,6 @@ use pocketmine\block\utils\DyeColor; use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\item\Banner as ItemBanner; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; -use pocketmine\item\ItemIds; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -126,8 +124,8 @@ abstract class BaseBanner extends Transparent{ } } - public function asItem() : Item{ - return ItemFactory::getInstance()->get(ItemIds::BANNER, DyeColorIdMap::getInstance()->toInvertedId($this->color)); + protected function writeStateToItemMeta() : int{ + return DyeColorIdMap::getInstance()->toInvertedId($this->color); } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/block/Bed.php b/src/block/Bed.php index 3979b8a099..c03ae71ddc 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -30,7 +30,6 @@ use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\math\AxisAlignedBB; @@ -197,8 +196,8 @@ class Bed extends Transparent{ return []; } - public function asItem() : Item{ - return ItemFactory::getInstance()->get($this->idInfo->getItemId(), DyeColorIdMap::getInstance()->toId($this->color)); + protected function writeStateToItemMeta() : int{ + return DyeColorIdMap::getInstance()->toId($this->color); } public function getAffectedBlocks() : array{ diff --git a/src/block/Block.php b/src/block/Block.php index ad10e710df..762063dcc6 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -98,7 +98,7 @@ class Block{ public function asItem() : Item{ return ItemFactory::getInstance()->get( $this->idInfo->getItemId(), - $this->idInfo->getVariant() | ($this->writeStateToMeta() & ~$this->getNonPersistentStateBitmask()) + $this->idInfo->getVariant() | $this->writeStateToItemMeta() ); } @@ -108,6 +108,10 @@ class Block{ return $this->idInfo->getVariant() | $stateMeta; } + protected function writeStateToItemMeta() : int{ + return 0; + } + /** * Returns a bitmask used to extract state bits from block metadata. */ @@ -115,10 +119,6 @@ class Block{ return 0; } - public function getNonPersistentStateBitmask() : int{ - return $this->getStateBitmask(); - } - protected function writeStateToMeta() : int{ return 0; } diff --git a/src/block/Coral.php b/src/block/Coral.php index 7c9185c1dc..b6ccb0cadd 100644 --- a/src/block/Coral.php +++ b/src/block/Coral.php @@ -44,12 +44,12 @@ final class Coral extends BaseCoral{ return CoralTypeIdMap::getInstance()->toId($this->coralType); } - public function getStateBitmask() : int{ - return 0b0111; + protected function writeStateToItemMeta() : int{ + return $this->writeStateToMeta(); } - public function getNonPersistentStateBitmask() : int{ - return 0b0000; + public function getStateBitmask() : int{ + return 0b0111; } public function readStateFromWorld() : void{ diff --git a/src/block/CoralBlock.php b/src/block/CoralBlock.php index 130b1ffd8e..c0bcad32f6 100644 --- a/src/block/CoralBlock.php +++ b/src/block/CoralBlock.php @@ -52,12 +52,12 @@ final class CoralBlock extends Opaque{ return ($this->dead ? BlockLegacyMetadata::CORAL_BLOCK_FLAG_DEAD : 0) | CoralTypeIdMap::getInstance()->toId($this->coralType); } - public function getStateBitmask() : int{ - return 0b1111; + protected function writeStateToItemMeta() : int{ + return $this->writeStateToMeta(); } - public function getNonPersistentStateBitmask() : int{ - return 0; + public function getStateBitmask() : int{ + return 0b1111; } public function getCoralType() : CoralType{ return $this->coralType; } diff --git a/src/block/Dirt.php b/src/block/Dirt.php index b357c95bf2..6c624d886e 100644 --- a/src/block/Dirt.php +++ b/src/block/Dirt.php @@ -41,12 +41,12 @@ class Dirt extends Opaque{ return $this->coarse ? BlockLegacyMetadata::DIRT_FLAG_COARSE : 0; } - public function getStateBitmask() : int{ - return 0b1; + protected function writeStateToItemMeta() : int{ + return $this->writeStateToMeta(); } - public function getNonPersistentStateBitmask() : int{ - return 0; + public function getStateBitmask() : int{ + return 0b1; } public function isCoarse() : bool{ return $this->coarse; } diff --git a/src/block/FloorCoralFan.php b/src/block/FloorCoralFan.php index 728b92aed5..c4a5cc0a00 100644 --- a/src/block/FloorCoralFan.php +++ b/src/block/FloorCoralFan.php @@ -64,7 +64,7 @@ final class FloorCoralFan extends BaseCoral{ //TODO: HACK! workaround dead flag being lost when broken / blockpicked (original impl only uses first ID) return ItemFactory::getInstance()->get( $this->dead ? ItemIds::CORAL_FAN_DEAD : ItemIds::CORAL_FAN, - CoralTypeIdMap::getInstance()->toId($this->coralType) + $this->writeStateToItemMeta() ); } @@ -73,12 +73,12 @@ final class FloorCoralFan extends BaseCoral{ CoralTypeIdMap::getInstance()->toId($this->coralType); } - public function getStateBitmask() : int{ - return 0b1111; + protected function writeStateToItemMeta() : int{ + return CoralTypeIdMap::getInstance()->toId($this->coralType); } - public function getNonPersistentStateBitmask() : int{ - return 0b1000; + public function getStateBitmask() : int{ + return 0b1111; } public function getAxis() : int{ return $this->axis; } diff --git a/src/block/Skull.php b/src/block/Skull.php index ae6abe8d57..20fcd760bc 100644 --- a/src/block/Skull.php +++ b/src/block/Skull.php @@ -27,8 +27,6 @@ use pocketmine\block\tile\Skull as TileSkull; use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\SkullType; use pocketmine\item\Item; -use pocketmine\item\ItemFactory; -use pocketmine\item\ItemIds; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -142,7 +140,7 @@ class Skull extends Flowable{ return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } - public function asItem() : Item{ - return ItemFactory::getInstance()->get(ItemIds::SKULL, $this->skullType->getMagicNumber()); + protected function writeStateToItemMeta() : int{ + return $this->skullType->getMagicNumber(); } } diff --git a/src/block/Sponge.php b/src/block/Sponge.php index 63ca4a1336..5ccf766abc 100644 --- a/src/block/Sponge.php +++ b/src/block/Sponge.php @@ -35,12 +35,12 @@ class Sponge extends Opaque{ $this->wet = ($stateMeta & BlockLegacyMetadata::SPONGE_FLAG_WET) !== 0; } - public function getStateBitmask() : int{ - return 0b1; + protected function writeStateToItemMeta() : int{ + return $this->writeStateToMeta(); } - public function getNonPersistentStateBitmask() : int{ - return 0; + public function getStateBitmask() : int{ + return 0b1; } public function isWet() : bool{ return $this->wet; } diff --git a/src/block/TNT.php b/src/block/TNT.php index 6180ec6eac..6cae9ca554 100644 --- a/src/block/TNT.php +++ b/src/block/TNT.php @@ -53,12 +53,14 @@ class TNT extends Opaque{ return ($this->unstable ? BlockLegacyMetadata::TNT_FLAG_UNSTABLE : 0) | ($this->worksUnderwater ? BlockLegacyMetadata::TNT_FLAG_UNDERWATER : 0); } + protected function writeStateToItemMeta() : int{ + return $this->worksUnderwater ? BlockLegacyMetadata::TNT_FLAG_UNDERWATER : 0; + } + public function getStateBitmask() : int{ return 0b11; } - public function getNonPersistentStateBitmask() : int{ return 0b1; } - public function isUnstable() : bool{ return $this->unstable; } /** @return $this */ diff --git a/src/block/WallCoralFan.php b/src/block/WallCoralFan.php index a979931135..fb93f3eef7 100644 --- a/src/block/WallCoralFan.php +++ b/src/block/WallCoralFan.php @@ -96,18 +96,18 @@ final class WallCoralFan extends BaseCoral{ return (BlockDataSerializer::writeCoralFacing($this->facing) << 2) | ($this->dead ? BlockLegacyMetadata::CORAL_FAN_HANG_FLAG_DEAD : 0) | $coralTypeFlag; } - public function getStateBitmask() : int{ - return 0b1111; + protected function writeStateToItemMeta() : int{ + return CoralTypeIdMap::getInstance()->toId($this->coralType); } - public function getNonPersistentStateBitmask() : int{ - return 0b1110; + public function getStateBitmask() : int{ + return 0b1111; } public function asItem() : Item{ return ItemFactory::getInstance()->get( $this->dead ? ItemIds::CORAL_FAN_DEAD : ItemIds::CORAL_FAN, - CoralTypeIdMap::getInstance()->toId($this->coralType) + $this->writeStateToItemMeta() ); } diff --git a/src/block/utils/ColorInMetadataTrait.php b/src/block/utils/ColorInMetadataTrait.php index 95b7292863..1130ae27c0 100644 --- a/src/block/utils/ColorInMetadataTrait.php +++ b/src/block/utils/ColorInMetadataTrait.php @@ -47,17 +47,17 @@ trait ColorInMetadataTrait{ return DyeColorIdMap::getInstance()->toId($this->color); } + /** + * @see Block::writeStateToItemMeta() + */ + protected function writeStateToItemMeta() : int{ + return DyeColorIdMap::getInstance()->toId($this->color); + } + /** * @see Block::getStateBitmask() */ public function getStateBitmask() : int{ return 0b1111; } - - /** - * @see Block::getNonPersistentStateBitmask() - */ - public function getNonPersistentStateBitmask() : int{ - return 0; - } } From 8221475ce2d4ba5f427a7701019e85f5e376a199 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 2 Aug 2021 19:20:19 +0100 Subject: [PATCH 2652/3224] BlockDataSerializer: fix wrong exception type being thrown --- src/block/utils/BlockDataSerializer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/utils/BlockDataSerializer.php b/src/block/utils/BlockDataSerializer.php index e0b7f1b3bf..0c0c8005b7 100644 --- a/src/block/utils/BlockDataSerializer.php +++ b/src/block/utils/BlockDataSerializer.php @@ -131,7 +131,7 @@ final class BlockDataSerializer{ 3 => Facing::SOUTH ][$value] ?? null; if($result === null){ - throw new \InvalidArgumentException("Invalid coral facing $value"); + throw new InvalidBlockStateException("Invalid coral facing $value"); } return $result; } From dcd203370b8fb185764f4bef6917659b2c9d8bf7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Aug 2021 15:02:32 +0100 Subject: [PATCH 2653/3224] Player: make use of typed properties readability significantly benefits from use of typed properties here. --- src/player/Player.php | 124 +++++++++++++++--------------------------- 1 file changed, 44 insertions(+), 80 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 1771161409..42d3111096 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -157,113 +157,77 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return $lname !== "rcon" and $lname !== "console" and $len >= 1 and $len <= 16 and preg_match("/[^A-Za-z0-9_ ]/", $name) === 0; } - /** @var NetworkSession|null */ - protected $networkSession; + protected ?NetworkSession $networkSession; - /** @var bool */ - public $spawned = false; + public bool $spawned = false; - /** @var string */ - protected $username; - /** @var string */ - protected $displayName; - /** @var string */ - protected $xuid = ""; - /** @var bool */ - protected $authenticated; - /** @var PlayerInfo */ - protected $playerInfo; + protected string $username; + protected string $displayName; + protected string $xuid = ""; + protected bool $authenticated; + protected PlayerInfo $playerInfo; - /** @var Inventory|null */ - protected $currentWindow = null; + protected ?Inventory $currentWindow = null; /** @var Inventory[] */ - protected $permanentWindows = []; - /** @var PlayerCursorInventory */ - protected $cursorInventory; - /** @var CraftingGrid */ - protected $craftingGrid; + protected array $permanentWindows = []; + protected PlayerCursorInventory $cursorInventory; + protected CraftingGrid $craftingGrid; - /** @var int */ - protected $messageCounter = 2; + protected int $messageCounter = 2; - /** @var int */ - protected $firstPlayed; - /** @var int */ - protected $lastPlayed; - /** @var GameMode */ - protected $gamemode; + protected int $firstPlayed; + protected int $lastPlayed; + protected GameMode $gamemode; /** * @var UsedChunkStatus[] chunkHash => status * @phpstan-var array */ - protected $usedChunks = []; + protected array $usedChunks = []; /** @var bool[] chunkHash => dummy */ - protected $loadQueue = []; - /** @var int */ - protected $nextChunkOrderRun = 5; + protected array $loadQueue = []; + protected int $nextChunkOrderRun = 5; - /** @var int */ - protected $viewDistance = -1; - /** @var int */ - protected $spawnThreshold; - /** @var int */ - protected $spawnChunkLoadCount = 0; - /** @var int */ - protected $chunksPerTick; - /** @var ChunkSelector */ - protected $chunkSelector; - /** @var PlayerChunkLoader */ - protected $chunkLoader; + protected int $viewDistance = -1; + protected int $spawnThreshold; + protected int $spawnChunkLoadCount = 0; + protected int $chunksPerTick; + protected ChunkSelector $chunkSelector; + protected PlayerChunkLoader $chunkLoader; /** @var bool[] map: raw UUID (string) => bool */ - protected $hiddenPlayers = []; + protected array $hiddenPlayers = []; - /** @var float */ - protected $moveRateLimit = 10 * self::MOVES_PER_TICK; - /** @var float|null */ - protected $lastMovementProcess = null; + protected float $moveRateLimit = 10 * self::MOVES_PER_TICK; + protected ?float $lastMovementProcess = null; - /** @var int */ - protected $inAirTicks = 0; - /** @var float */ - protected $stepHeight = 0.6; + protected int $inAirTicks = 0; + protected float $stepHeight = 0.6; - /** @var Vector3|null */ - protected $sleeping = null; - /** @var Position|null */ - private $spawnPosition = null; + protected ?Vector3 $sleeping = null; + private ?Position $spawnPosition = null; private bool $respawnLocked = false; //TODO: Abilities - /** @var bool */ - protected $autoJump = true; - /** @var bool */ - protected $allowFlight = false; - /** @var bool */ - protected $flying = false; + protected bool $autoJump = true; + protected bool $allowFlight = false; + protected bool $flying = false; - /** @var int|null */ - protected $lineHeight = null; - /** @var string */ - protected $locale = "en_US"; + protected ?int $lineHeight = null; + protected string $locale = "en_US"; - /** @var int */ - protected $startAction = -1; + protected int $startAction = -1; /** @var int[] ID => ticks map */ - protected $usedItemsCooldown = []; + protected array $usedItemsCooldown = []; - /** @var int */ - protected $formIdCounter = 0; + protected int $formIdCounter = 0; /** @var Form[] */ - protected $forms = []; + protected array $forms = []; - /** @var \Logger */ - protected $logger; + protected \Logger $logger; - /** @var SurvivalBlockBreakHandler|null */ - protected $blockBreakHandler = null; + protected ?SurvivalBlockBreakHandler $blockBreakHandler = null; public function __construct(Server $server, NetworkSession $session, PlayerInfo $playerInfo, bool $authenticated, Location $spawnLocation, ?CompoundTag $namedtag){ $username = TextFormat::clean($playerInfo->getUsername()); @@ -2019,8 +1983,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ protected function destroyCycles() : void{ $this->networkSession = null; - $this->cursorInventory = null; - $this->craftingGrid = null; + unset($this->cursorInventory); + unset($this->craftingGrid); $this->spawnPosition = null; $this->blockBreakHandler = null; parent::destroyCycles(); From 565cf84e1bb42fd11315cd93876bc21e038a47ae Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Aug 2021 15:13:28 +0100 Subject: [PATCH 2654/3224] MemoryManager: use typed properties --- src/MemoryManager.php | 60 +++++++++++++++---------------------------- 1 file changed, 20 insertions(+), 40 deletions(-) diff --git a/src/MemoryManager.php b/src/MemoryManager.php index 657daca80b..09f0c889c7 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -68,53 +68,33 @@ use const SORT_NUMERIC; class MemoryManager{ - /** @var Server */ - private $server; + private Server $server; - /** @var int */ - private $memoryLimit; - /** @var int */ - private $globalMemoryLimit; - /** @var int */ - private $checkRate; - /** @var int */ - private $checkTicker = 0; - /** @var bool */ - private $lowMemory = false; + private int $memoryLimit; + private int $globalMemoryLimit; + private int $checkRate; + private int $checkTicker = 0; + private bool $lowMemory = false; - /** @var bool */ - private $continuousTrigger = true; - /** @var int */ - private $continuousTriggerRate; - /** @var int */ - private $continuousTriggerCount = 0; - /** @var int */ - private $continuousTriggerTicker = 0; + private bool $continuousTrigger = true; + private int $continuousTriggerRate; + private int $continuousTriggerCount = 0; + private int $continuousTriggerTicker = 0; - /** @var int */ - private $garbageCollectionPeriod; - /** @var int */ - private $garbageCollectionTicker = 0; - /** @var bool */ - private $garbageCollectionTrigger; - /** @var bool */ - private $garbageCollectionAsync; + private int $garbageCollectionPeriod; + private int $garbageCollectionTicker = 0; + private bool $garbageCollectionTrigger; + private bool $garbageCollectionAsync; - /** @var int */ - private $lowMemChunkRadiusOverride; - /** @var bool */ - private $lowMemChunkGC; + private int $lowMemChunkRadiusOverride; + private bool $lowMemChunkGC; - /** @var bool */ - private $lowMemDisableChunkCache; - /** @var bool */ - private $lowMemClearWorldCache; + private bool $lowMemDisableChunkCache; + private bool $lowMemClearWorldCache; - /** @var bool */ - private $dumpWorkers = true; + private bool $dumpWorkers = true; - /** @var \Logger */ - private $logger; + private \Logger $logger; public function __construct(Server $server){ $this->server = $server; From c567ed4b7ab5cd27f63de43e9eacca0d7abcf292 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Aug 2021 15:32:21 +0100 Subject: [PATCH 2655/3224] fix build error --- src/player/Player.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index 42d3111096..1e6aa550a2 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -202,7 +202,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ protected ?float $lastMovementProcess = null; protected int $inAirTicks = 0; - protected float $stepHeight = 0.6; + /** @var float */ + protected $stepHeight = 0.6; protected ?Vector3 $sleeping = null; private ?Position $spawnPosition = null; From 16965fa742e536314295c70286126d6067ceea1a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Aug 2021 18:48:18 +0100 Subject: [PATCH 2656/3224] ConsoleReaderThread: override default socket timeout for accept otherwise, people can break the console reader by setting the default timeout to zero or some other small value. --- src/console/ConsoleReaderThread.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/console/ConsoleReaderThread.php b/src/console/ConsoleReaderThread.php index afd1eedf0c..6d56c0f416 100644 --- a/src/console/ConsoleReaderThread.php +++ b/src/console/ConsoleReaderThread.php @@ -97,7 +97,7 @@ final class ConsoleReaderThread extends Thread{ if($sub === false){ throw new AssumptionFailedError("Something has gone horribly wrong"); } - $client = stream_socket_accept($server); + $client = stream_socket_accept($server, 15); if($client === false){ throw new AssumptionFailedError("stream_socket_accept() returned false"); } From 50b4ec0d2035a77ba207f626ee737eb2abf6228d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 3 Aug 2021 18:50:36 +0100 Subject: [PATCH 2657/3224] Override timeout for the subprocess also --- src/console/ConsoleReaderChildProcess.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/console/ConsoleReaderChildProcess.php b/src/console/ConsoleReaderChildProcess.php index bf9bf0213b..5bb05a818b 100644 --- a/src/console/ConsoleReaderChildProcess.php +++ b/src/console/ConsoleReaderChildProcess.php @@ -36,9 +36,11 @@ if(count($argv) !== 2){ } @cli_set_process_title('PocketMine-MP Console Reader'); -$socket = stream_socket_client($argv[1]); +$errCode = null; +$errMessage = null; +$socket = stream_socket_client($argv[1], $errCode, $errMessage, 15.0); if($socket === false){ - throw new \RuntimeException("Failed to connect to server process"); + throw new \RuntimeException("Failed to connect to server process ($errCode): $errMessage"); } $consoleReader = new ConsoleReader(); while(!feof($socket)){ From 71c6f69fd3957def0c85e4af532e8910951a8d31 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Aug 2021 20:29:07 +0100 Subject: [PATCH 2658/3224] Command: standardise permission checking if subcommands had different permissions, the permissionMessage would not be used. --- src/command/Command.php | 15 ++++++++------- src/command/defaults/ClearCommand.php | 6 ++---- src/command/defaults/KillCommand.php | 8 ++------ src/command/defaults/TimeCommand.php | 21 +++++---------------- src/command/defaults/WhitelistCommand.php | 9 +-------- 5 files changed, 18 insertions(+), 41 deletions(-) diff --git a/src/command/Command.php b/src/command/Command.php index 341883fddf..fa792fdb13 100644 --- a/src/command/Command.php +++ b/src/command/Command.php @@ -111,27 +111,28 @@ abstract class Command{ $this->permission = $permission; } - public function testPermission(CommandSender $target) : bool{ - if($this->testPermissionSilent($target)){ + public function testPermission(CommandSender $target, ?string $permission = null) : bool{ + if($this->testPermissionSilent($target, $permission)){ return true; } if($this->permissionMessage === null){ $target->sendMessage($target->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); }elseif($this->permissionMessage !== ""){ - $target->sendMessage(str_replace("", $this->permission, $this->permissionMessage)); + $target->sendMessage(str_replace("", $permission ?? $this->permission, $this->permissionMessage)); } return false; } - public function testPermissionSilent(CommandSender $target) : bool{ - if($this->permission === null or $this->permission === ""){ + public function testPermissionSilent(CommandSender $target, ?string $permission = null) : bool{ + $permission ??= $this->permission; + if($permission === null or $permission === ""){ return true; } - foreach(explode(";", $this->permission) as $permission){ - if($target->hasPermission($permission)){ + foreach(explode(";", $permission) as $p){ + if($target->hasPermission($p)){ return true; } } diff --git a/src/command/defaults/ClearCommand.php b/src/command/defaults/ClearCommand.php index 96055d86fc..bfa5623f76 100644 --- a/src/command/defaults/ClearCommand.php +++ b/src/command/defaults/ClearCommand.php @@ -64,13 +64,11 @@ class ClearCommand extends VanillaCommand{ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); return true; } - if($target !== $sender && !$sender->hasPermission(DefaultPermissionNames::COMMAND_CLEAR_OTHER)){ - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); + if($target !== $sender && !$this->testPermission($sender, DefaultPermissionNames::COMMAND_CLEAR_OTHER)){ return true; } }elseif($sender instanceof Player){ - if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_CLEAR_SELF)){ - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); + if(!$this->testPermission($sender, DefaultPermissionNames::COMMAND_CLEAR_SELF)){ return true; } diff --git a/src/command/defaults/KillCommand.php b/src/command/defaults/KillCommand.php index d30ae3917e..65b2386e68 100644 --- a/src/command/defaults/KillCommand.php +++ b/src/command/defaults/KillCommand.php @@ -57,9 +57,7 @@ class KillCommand extends VanillaCommand{ } if(count($args) === 1){ - if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_KILL_OTHER)){ - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); - + if(!$this->testPermission($sender, DefaultPermissionNames::COMMAND_KILL_OTHER)){ return true; } @@ -76,9 +74,7 @@ class KillCommand extends VanillaCommand{ } if($sender instanceof Player){ - if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_KILL_SELF)){ - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); - + if(!$this->testPermission($sender, DefaultPermissionNames::COMMAND_KILL_SELF)){ return true; } diff --git a/src/command/defaults/TimeCommand.php b/src/command/defaults/TimeCommand.php index 7d8ad4e301..8a1bf2b9e1 100644 --- a/src/command/defaults/TimeCommand.php +++ b/src/command/defaults/TimeCommand.php @@ -30,7 +30,6 @@ use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; -use pocketmine\utils\TextFormat; use pocketmine\world\World; use function count; use function implode; @@ -61,9 +60,7 @@ class TimeCommand extends VanillaCommand{ } if($args[0] === "start"){ - if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_TIME_START)){ - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); - + if(!$this->testPermission($sender, DefaultPermissionNames::COMMAND_TIME_START)){ return true; } foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){ @@ -72,9 +69,7 @@ class TimeCommand extends VanillaCommand{ Command::broadcastCommandMessage($sender, "Restarted the time"); return true; }elseif($args[0] === "stop"){ - if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_TIME_STOP)){ - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); - + if(!$this->testPermission($sender, DefaultPermissionNames::COMMAND_TIME_STOP)){ return true; } foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){ @@ -83,9 +78,7 @@ class TimeCommand extends VanillaCommand{ Command::broadcastCommandMessage($sender, "Stopped the time"); return true; }elseif($args[0] === "query"){ - if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_TIME_QUERY)){ - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); - + if(!$this->testPermission($sender, DefaultPermissionNames::COMMAND_TIME_QUERY)){ return true; } if($sender instanceof Player){ @@ -102,9 +95,7 @@ class TimeCommand extends VanillaCommand{ } if($args[0] === "set"){ - if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_TIME_SET)){ - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); - + if(!$this->testPermission($sender, DefaultPermissionNames::COMMAND_TIME_SET)){ return true; } @@ -137,9 +128,7 @@ class TimeCommand extends VanillaCommand{ } Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_TIME_SET, [$value])); }elseif($args[0] === "add"){ - if(!$sender->hasPermission(DefaultPermissionNames::COMMAND_TIME_ADD)){ - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); - + if(!$this->testPermission($sender, DefaultPermissionNames::COMMAND_TIME_ADD)){ return true; } diff --git a/src/command/defaults/WhitelistCommand.php b/src/command/defaults/WhitelistCommand.php index 0fddb59b3a..d6f51185aa 100644 --- a/src/command/defaults/WhitelistCommand.php +++ b/src/command/defaults/WhitelistCommand.php @@ -31,7 +31,6 @@ use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\AssumptionFailedError; -use pocketmine\utils\TextFormat; use function count; use function implode; use function sort; @@ -136,12 +135,6 @@ class WhitelistCommand extends VanillaCommand{ if($permission === null){ throw new AssumptionFailedError("Unknown subcommand $subcommand"); } - if(!$sender->hasPermission($permission)){ - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); - - return true; - } - - return false; + return !$this->testPermission($sender, $permission); } } From bb79797b68fb150a0fae0cb3577e594a5bfc8a53 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Aug 2021 20:34:54 +0100 Subject: [PATCH 2659/3224] WhitelistCommand: fixed permission checking closes #4349 --- src/command/defaults/WhitelistCommand.php | 66 ++++++++++------------- 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/src/command/defaults/WhitelistCommand.php b/src/command/defaults/WhitelistCommand.php index d6f51185aa..8144459b7f 100644 --- a/src/command/defaults/WhitelistCommand.php +++ b/src/command/defaults/WhitelistCommand.php @@ -30,7 +30,6 @@ use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; -use pocketmine\utils\AssumptionFailedError; use function count; use function implode; use function sort; @@ -61,33 +60,38 @@ class WhitelistCommand extends VanillaCommand{ } if(count($args) === 1){ - if($this->badPerm($sender, strtolower($args[0]))){ - return false; - } switch(strtolower($args[0])){ case "reload": - $sender->getServer()->getWhitelisted()->reload(); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_RELOADED)); + if($this->testPermission($sender, DefaultPermissionNames::COMMAND_WHITELIST_RELOAD)){ + $sender->getServer()->getWhitelisted()->reload(); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_RELOADED)); + } return true; case "on": - $sender->getServer()->getConfigGroup()->setConfigBool("white-list", true); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_ENABLED)); + if($this->testPermission($sender, DefaultPermissionNames::COMMAND_WHITELIST_ENABLE)){ + $sender->getServer()->getConfigGroup()->setConfigBool("white-list", true); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_ENABLED)); + } return true; case "off": - $sender->getServer()->getConfigGroup()->setConfigBool("white-list", false); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_DISABLED)); + if($this->testPermission($sender, DefaultPermissionNames::COMMAND_WHITELIST_DISABLE)){ + $sender->getServer()->getConfigGroup()->setConfigBool("white-list", false); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_DISABLED)); + } return true; case "list": - $entries = $sender->getServer()->getWhitelisted()->getAll(true); - sort($entries, SORT_STRING); - $result = implode(", ", $entries); - $count = count($entries); + if($this->testPermission($sender, DefaultPermissionNames::COMMAND_WHITELIST_LIST)){ + $entries = $sender->getServer()->getWhitelisted()->getAll(true); + sort($entries, SORT_STRING); + $result = implode(", ", $entries); + $count = count($entries); - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_LIST, [$count, $count])); - $sender->sendMessage($result); + $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_LIST, [$count, $count])); + $sender->sendMessage($result); + } return true; @@ -100,21 +104,22 @@ class WhitelistCommand extends VanillaCommand{ return true; } }elseif(count($args) === 2){ - if($this->badPerm($sender, strtolower($args[0]))){ - return false; - } if(!Player::isValidUserName($args[1])){ throw new InvalidCommandSyntaxException(); } switch(strtolower($args[0])){ case "add": - $sender->getServer()->addWhitelist($args[1]); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_ADD_SUCCESS, [$args[1]])); + if($this->testPermission($sender, DefaultPermissionNames::COMMAND_WHITELIST_ADD)){ + $sender->getServer()->addWhitelist($args[1]); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_ADD_SUCCESS, [$args[1]])); + } return true; case "remove": - $sender->getServer()->removeWhitelist($args[1]); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_REMOVE_SUCCESS, [$args[1]])); + if($this->testPermission($sender, DefaultPermissionNames::COMMAND_WHITELIST_REMOVE)){ + $sender->getServer()->removeWhitelist($args[1]); + Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_REMOVE_SUCCESS, [$args[1]])); + } return true; } @@ -122,19 +127,4 @@ class WhitelistCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - - private function badPerm(CommandSender $sender, string $subcommand) : bool{ - $permission = [ - "reload" => DefaultPermissionNames::COMMAND_WHITELIST_RELOAD, - "on" => DefaultPermissionNames::COMMAND_WHITELIST_ENABLE, - "off" => DefaultPermissionNames::COMMAND_WHITELIST_DISABLE, - "list" => DefaultPermissionNames::COMMAND_WHITELIST_LIST, - "add" => DefaultPermissionNames::COMMAND_WHITELIST_ADD, - "remove" => DefaultPermissionNames::COMMAND_WHITELIST_REMOVE - ][$subcommand] ?? null; - if($permission === null){ - throw new AssumptionFailedError("Unknown subcommand $subcommand"); - } - return !$this->testPermission($sender, $permission); - } } From 00984c1b9f1d9345e1e5db7801cffd8b5c1acbf6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Aug 2021 20:57:20 +0100 Subject: [PATCH 2660/3224] BaseInventory: Move contents of InventoryHelpersTrait back inline I moved these to a trait in anticipation of having multiple full Inventory implementations. That's no longer necessary because of the abstraction of SimpleInventory. --- src/inventory/BaseInventory.php | 204 ++++++++++++++++++- src/inventory/InventoryHelpersTrait.php | 248 ------------------------ 2 files changed, 202 insertions(+), 250 deletions(-) delete mode 100644 src/inventory/InventoryHelpersTrait.php diff --git a/src/inventory/BaseInventory.php b/src/inventory/BaseInventory.php index 425c6a8090..4d79d7d94c 100644 --- a/src/inventory/BaseInventory.php +++ b/src/inventory/BaseInventory.php @@ -29,14 +29,14 @@ use pocketmine\player\Player; use pocketmine\utils\ObjectSet; use function array_slice; use function count; +use function max; +use function min; use function spl_object_id; /** * This class provides everything needed to implement an inventory, minus the underlying storage system. */ abstract class BaseInventory implements Inventory{ - use InventoryHelpersTrait; - /** @var int */ protected $maxStackSize = Inventory::MAX_STACK; /** @var Player[] */ @@ -100,6 +100,206 @@ abstract class BaseInventory implements Inventory{ $this->onSlotChange($index, $oldItem); } + public function contains(Item $item) : bool{ + $count = max(1, $item->getCount()); + $checkDamage = !$item->hasAnyDamageValue(); + $checkTags = $item->hasNamedTag(); + foreach($this->getContents() as $i){ + if($item->equals($i, $checkDamage, $checkTags)){ + $count -= $i->getCount(); + if($count <= 0){ + return true; + } + } + } + + return false; + } + + public function all(Item $item) : array{ + $slots = []; + $checkDamage = !$item->hasAnyDamageValue(); + $checkTags = $item->hasNamedTag(); + foreach($this->getContents() as $index => $i){ + if($item->equals($i, $checkDamage, $checkTags)){ + $slots[$index] = $i; + } + } + + return $slots; + } + + public function remove(Item $item) : void{ + $checkDamage = !$item->hasAnyDamageValue(); + $checkTags = $item->hasNamedTag(); + + foreach($this->getContents() as $index => $i){ + if($item->equals($i, $checkDamage, $checkTags)){ + $this->clear($index); + } + } + } + + public function first(Item $item, bool $exact = false) : int{ + $count = $exact ? $item->getCount() : max(1, $item->getCount()); + $checkDamage = $exact || !$item->hasAnyDamageValue(); + $checkTags = $exact || $item->hasNamedTag(); + + foreach($this->getContents() as $index => $i){ + if($item->equals($i, $checkDamage, $checkTags) and ($i->getCount() === $count or (!$exact and $i->getCount() > $count))){ + return $index; + } + } + + return -1; + } + + public function firstEmpty() : int{ + foreach($this->getContents(true) as $i => $slot){ + if($slot->isNull()){ + return $i; + } + } + + return -1; + } + + public function isSlotEmpty(int $index) : bool{ + return $this->getItem($index)->isNull(); + } + + public function canAddItem(Item $item) : bool{ + $count = $item->getCount(); + for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ + $slot = $this->getItem($i); + if($item->canStackWith($slot)){ + if(($diff = min($slot->getMaxStackSize(), $item->getMaxStackSize()) - $slot->getCount()) > 0){ + $count -= $diff; + } + }elseif($slot->isNull()){ + $count -= min($this->getMaxStackSize(), $item->getMaxStackSize()); + } + + if($count <= 0){ + return true; + } + } + + return false; + } + + public function addItem(Item ...$slots) : array{ + /** @var Item[] $itemSlots */ + /** @var Item[] $slots */ + $itemSlots = []; + foreach($slots as $slot){ + if(!$slot->isNull()){ + $itemSlots[] = clone $slot; + } + } + + /** @var Item[] $returnSlots */ + $returnSlots = []; + + foreach($itemSlots as $item){ + $leftover = $this->internalAddItem($item); + if(!$leftover->isNull()){ + $returnSlots[] = $leftover; + } + } + + return $returnSlots; + } + + private function internalAddItem(Item $slot) : Item{ + $emptySlots = []; + + for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ + $item = $this->getItem($i); + if($item->isNull()){ + $emptySlots[] = $i; + } + + if($slot->canStackWith($item) and $item->getCount() < $item->getMaxStackSize()){ + $amount = min($item->getMaxStackSize() - $item->getCount(), $slot->getCount(), $this->getMaxStackSize()); + if($amount > 0){ + $slot->setCount($slot->getCount() - $amount); + $item->setCount($item->getCount() + $amount); + $this->setItem($i, $item); + if($slot->getCount() <= 0){ + break; + } + } + } + } + + if(count($emptySlots) > 0){ + foreach($emptySlots as $slotIndex){ + $amount = min($slot->getMaxStackSize(), $slot->getCount(), $this->getMaxStackSize()); + $slot->setCount($slot->getCount() - $amount); + $item = clone $slot; + $item->setCount($amount); + $this->setItem($slotIndex, $item); + if($slot->getCount() <= 0){ + break; + } + } + } + + return $slot; + } + + public function removeItem(Item ...$slots) : array{ + /** @var Item[] $itemSlots */ + /** @var Item[] $slots */ + $itemSlots = []; + foreach($slots as $slot){ + if(!$slot->isNull()){ + $itemSlots[] = clone $slot; + } + } + + for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ + $item = $this->getItem($i); + if($item->isNull()){ + continue; + } + + foreach($itemSlots as $index => $slot){ + if($slot->equals($item, !$slot->hasAnyDamageValue(), $slot->hasNamedTag())){ + $amount = min($item->getCount(), $slot->getCount()); + $slot->setCount($slot->getCount() - $amount); + $item->setCount($item->getCount() - $amount); + $this->setItem($i, $item); + if($slot->getCount() <= 0){ + unset($itemSlots[$index]); + } + } + } + + if(count($itemSlots) === 0){ + break; + } + } + + return $itemSlots; + } + + public function clear(int $index) : void{ + $this->setItem($index, ItemFactory::air()); + } + + public function clearAll() : void{ + $this->setContents([]); + } + + public function swap(int $slot1, int $slot2) : void{ + $i1 = $this->getItem($slot1); + $i2 = $this->getItem($slot2); + $this->setItem($slot1, $i2); + $this->setItem($slot2, $i1); + } + /** * @return Player[] */ diff --git a/src/inventory/InventoryHelpersTrait.php b/src/inventory/InventoryHelpersTrait.php deleted file mode 100644 index 1d6de457bc..0000000000 --- a/src/inventory/InventoryHelpersTrait.php +++ /dev/null @@ -1,248 +0,0 @@ -getCount()); - $checkDamage = !$item->hasAnyDamageValue(); - $checkTags = $item->hasNamedTag(); - foreach($this->getContents() as $i){ - if($item->equals($i, $checkDamage, $checkTags)){ - $count -= $i->getCount(); - if($count <= 0){ - return true; - } - } - } - - return false; - } - - public function all(Item $item) : array{ - $slots = []; - $checkDamage = !$item->hasAnyDamageValue(); - $checkTags = $item->hasNamedTag(); - foreach($this->getContents() as $index => $i){ - if($item->equals($i, $checkDamage, $checkTags)){ - $slots[$index] = $i; - } - } - - return $slots; - } - - public function remove(Item $item) : void{ - $checkDamage = !$item->hasAnyDamageValue(); - $checkTags = $item->hasNamedTag(); - - foreach($this->getContents() as $index => $i){ - if($item->equals($i, $checkDamage, $checkTags)){ - $this->clear($index); - } - } - } - - public function first(Item $item, bool $exact = false) : int{ - $count = $exact ? $item->getCount() : max(1, $item->getCount()); - $checkDamage = $exact || !$item->hasAnyDamageValue(); - $checkTags = $exact || $item->hasNamedTag(); - - foreach($this->getContents() as $index => $i){ - if($item->equals($i, $checkDamage, $checkTags) and ($i->getCount() === $count or (!$exact and $i->getCount() > $count))){ - return $index; - } - } - - return -1; - } - - public function firstEmpty() : int{ - foreach($this->getContents(true) as $i => $slot){ - if($slot->isNull()){ - return $i; - } - } - - return -1; - } - - public function isSlotEmpty(int $index) : bool{ - return $this->getItem($index)->isNull(); - } - - public function canAddItem(Item $item) : bool{ - $count = $item->getCount(); - for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ - $slot = $this->getItem($i); - if($item->canStackWith($slot)){ - if(($diff = min($slot->getMaxStackSize(), $item->getMaxStackSize()) - $slot->getCount()) > 0){ - $count -= $diff; - } - }elseif($slot->isNull()){ - $count -= min($this->getMaxStackSize(), $item->getMaxStackSize()); - } - - if($count <= 0){ - return true; - } - } - - return false; - } - - public function addItem(Item ...$slots) : array{ - /** @var Item[] $itemSlots */ - /** @var Item[] $slots */ - $itemSlots = []; - foreach($slots as $slot){ - if(!$slot->isNull()){ - $itemSlots[] = clone $slot; - } - } - - /** @var Item[] $returnSlots */ - $returnSlots = []; - - foreach($itemSlots as $item){ - $leftover = $this->internalAddItem($item); - if(!$leftover->isNull()){ - $returnSlots[] = $leftover; - } - } - - return $returnSlots; - } - - private function internalAddItem(Item $slot) : Item{ - $emptySlots = []; - - for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ - $item = $this->getItem($i); - if($item->isNull()){ - $emptySlots[] = $i; - } - - if($slot->canStackWith($item) and $item->getCount() < $item->getMaxStackSize()){ - $amount = min($item->getMaxStackSize() - $item->getCount(), $slot->getCount(), $this->getMaxStackSize()); - if($amount > 0){ - $slot->setCount($slot->getCount() - $amount); - $item->setCount($item->getCount() + $amount); - $this->setItem($i, $item); - if($slot->getCount() <= 0){ - break; - } - } - } - } - - if(count($emptySlots) > 0){ - foreach($emptySlots as $slotIndex){ - $amount = min($slot->getMaxStackSize(), $slot->getCount(), $this->getMaxStackSize()); - $slot->setCount($slot->getCount() - $amount); - $item = clone $slot; - $item->setCount($amount); - $this->setItem($slotIndex, $item); - if($slot->getCount() <= 0){ - break; - } - } - } - - return $slot; - } - - public function removeItem(Item ...$slots) : array{ - /** @var Item[] $itemSlots */ - /** @var Item[] $slots */ - $itemSlots = []; - foreach($slots as $slot){ - if(!$slot->isNull()){ - $itemSlots[] = clone $slot; - } - } - - for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ - $item = $this->getItem($i); - if($item->isNull()){ - continue; - } - - foreach($itemSlots as $index => $slot){ - if($slot->equals($item, !$slot->hasAnyDamageValue(), $slot->hasNamedTag())){ - $amount = min($item->getCount(), $slot->getCount()); - $slot->setCount($slot->getCount() - $amount); - $item->setCount($item->getCount() - $amount); - $this->setItem($i, $item); - if($slot->getCount() <= 0){ - unset($itemSlots[$index]); - } - } - } - - if(count($itemSlots) === 0){ - break; - } - } - - return $itemSlots; - } - - public function clear(int $index) : void{ - $this->setItem($index, ItemFactory::air()); - } - - public function clearAll() : void{ - $this->setContents([]); - } - - public function swap(int $slot1, int $slot2) : void{ - $i1 = $this->getItem($slot1); - $i2 = $this->getItem($slot2); - $this->setItem($slot1, $i2); - $this->setItem($slot2, $i1); - } -} From 61b7faae0806d5b21cd682261d7dc9e15722360c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Aug 2021 21:01:01 +0100 Subject: [PATCH 2661/3224] Simplify BaseInventoryTest --- tests/phpunit/inventory/BaseInventoryTest.php | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/tests/phpunit/inventory/BaseInventoryTest.php b/tests/phpunit/inventory/BaseInventoryTest.php index 8fd7f43ea2..a0ae029ea1 100644 --- a/tests/phpunit/inventory/BaseInventoryTest.php +++ b/tests/phpunit/inventory/BaseInventoryTest.php @@ -32,9 +32,7 @@ use pocketmine\item\VanillaItems; class BaseInventoryTest extends TestCase{ public function testAddItemDifferentUserData() : void{ - $inv = new class(1) extends SimpleInventory{ - - }; + $inv = new SimpleInventory(1); $item1 = ItemFactory::getInstance()->get(ItemIds::ARROW, 0, 1); $item2 = ItemFactory::getInstance()->get(ItemIds::ARROW, 0, 1)->setCustomName("TEST"); @@ -63,16 +61,14 @@ class BaseInventoryTest extends TestCase{ } public function testAddMultipleItemsInOneCall() : void{ - $inventory = new class(1) extends SimpleInventory{ - - }; + $inventory = new SimpleInventory(1); $leftover = $inventory->addItem(...$this->getTestItems()); self::assertCount(0, $leftover); self::assertTrue($inventory->getItem(0)->equalsExact(VanillaItems::APPLE()->setCount(64))); } public function testAddMultipleItemsInOneCallWithLeftover() : void{ - $inventory = new class(1) extends SimpleInventory{}; + $inventory = new SimpleInventory(1); $inventory->setItem(0, VanillaItems::APPLE()->setCount(20)); $leftover = $inventory->addItem(...$this->getTestItems()); self::assertCount(2, $leftover); //the leftovers are not currently stacked - if they were given separately, they'll be returned separately @@ -87,9 +83,7 @@ class BaseInventoryTest extends TestCase{ } public function testAddItemWithOversizedCount() : void{ - $inventory = new class(10) extends SimpleInventory{ - - }; + $inventory = new SimpleInventory(10); $leftover = $inventory->addItem(VanillaItems::APPLE()->setCount(100)); self::assertCount(0, $leftover); From b31dce2119477b9ab7337615f3f0505ef642b3ab Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Aug 2021 21:17:44 +0100 Subject: [PATCH 2662/3224] Player: fixed type of loadQueue field --- src/player/Player.php | 5 ++++- tests/phpstan/configs/l7-baseline.neon | 5 ----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 1e6aa550a2..a8c0ad2911 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -184,7 +184,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ * @phpstan-var array */ protected array $usedChunks = []; - /** @var bool[] chunkHash => dummy */ + /** + * @var true[] chunkHash => dummy + * @phpstan-var array + */ protected array $loadQueue = []; protected int $nextChunkOrderRun = 5; diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index 4f5cbd83c6..b5781fdfe4 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -625,11 +625,6 @@ parameters: count: 1 path: ../../../src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php - - - message: "#^Array \\(array\\\\) does not accept key \\(int\\|string\\)\\.$#" - count: 3 - path: ../../../src/player/Player.php - - message: "#^Method pocketmine\\\\resourcepacks\\\\ZippedResourcePack\\:\\:getPackChunk\\(\\) should return string but returns string\\|false\\.$#" count: 1 From b72d81be5eafaa76f7d676c01fd4b06e45014289 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 4 Aug 2021 21:24:13 +0100 Subject: [PATCH 2663/3224] Cleanup PHPStan baselines --- phpstan.neon.dist | 1 - tests/phpstan/configs/gc-hacks.neon | 10 ---- tests/phpstan/configs/l7-baseline.neon | 50 ++----------------- tests/phpstan/configs/l8-baseline.neon | 25 ---------- tests/phpstan/configs/php-bugs.neon | 10 ---- tests/phpstan/configs/phpstan-bugs.neon | 5 -- .../phpstan/configs/phpunit-wiring-tests.neon | 7 --- 7 files changed, 5 insertions(+), 103 deletions(-) delete mode 100644 tests/phpstan/configs/phpunit-wiring-tests.neon diff --git a/phpstan.neon.dist b/phpstan.neon.dist index cd3c5b18b3..8c45f81584 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -7,7 +7,6 @@ includes: - tests/phpstan/configs/l8-baseline.neon - tests/phpstan/configs/php-bugs.neon - tests/phpstan/configs/phpstan-bugs.neon - - tests/phpstan/configs/phpunit-wiring-tests.neon - tests/phpstan/configs/pthreads-bugs.neon - tests/phpstan/configs/runtime-type-checks.neon - vendor/phpstan/phpstan-phpunit/extension.neon diff --git a/tests/phpstan/configs/gc-hacks.neon b/tests/phpstan/configs/gc-hacks.neon index 4e854c21b2..37ac037f18 100644 --- a/tests/phpstan/configs/gc-hacks.neon +++ b/tests/phpstan/configs/gc-hacks.neon @@ -35,13 +35,3 @@ parameters: count: 1 path: ../../../src/entity/Living.php - - - message: "#^Property pocketmine\\\\player\\\\Player\\:\\:\\$craftingGrid \\(pocketmine\\\\crafting\\\\CraftingGrid\\) does not accept null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - - - message: "#^Property pocketmine\\\\player\\\\Player\\:\\:\\$cursorInventory \\(pocketmine\\\\inventory\\\\PlayerCursorInventory\\) does not accept null\\.$#" - count: 1 - path: ../../../src/player/Player.php - diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index b5781fdfe4..f7e9f17e77 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -430,11 +430,6 @@ parameters: count: 1 path: ../../../src/block/tile/TileFactory.php - - - message: "#^Property pocketmine\\\\console\\\\ConsoleReader\\:\\:\\$stdin \\(resource\\) does not accept resource\\|false\\.$#" - count: 1 - path: ../../../src/console/ConsoleReader.php - - message: "#^Only booleans are allowed in an if condition, int\\|false given\\.$#" count: 1 @@ -465,6 +460,11 @@ parameters: count: 1 path: ../../../src/command/defaults/TimingsCommand.php + - + message: "#^Property pocketmine\\\\console\\\\ConsoleReader\\:\\:\\$stdin \\(resource\\) does not accept resource\\|false\\.$#" + count: 1 + path: ../../../src/console/ConsoleReader.php + - message: "#^Method pocketmine\\\\crafting\\\\CraftingManager\\:\\:hashOutputs\\(\\) should return string but returns string\\|false\\.$#" count: 1 @@ -575,16 +575,6 @@ parameters: count: 1 path: ../../../src/lang/Language.php - - - message: "#^Parameter \\#1 \\$str of static method pocketmine\\\\network\\\\mcpe\\\\JwtUtils\\:\\:b64UrlEncode\\(\\) expects string, string\\|false given\\.$#" - count: 2 - path: ../../../src/network/mcpe/JwtUtils.php - - - - message: "#^Parameter \\#1 \\$string of method Mdanter\\\\Ecc\\\\Serializer\\\\PublicKey\\\\DerPublicKeySerializer\\:\\:parse\\(\\) expects string, string\\|false given\\.$#" - count: 1 - path: ../../../src/network/mcpe/auth/ProcessLoginTask.php - - message: "#^Parameter \\#1 \\$buffer of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:decoder\\(\\) expects string, string\\|false given\\.$#" count: 1 @@ -595,36 +585,6 @@ parameters: count: 1 path: ../../../src/network/mcpe/encryption/EncryptionUtils.php - - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:putSignedBlockPosition\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php - - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:putSignedBlockPosition\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php - - - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:putSignedBlockPosition\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/network/mcpe/protocol/types/entity/BlockPosMetadataProperty.php - - - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:putBlockPosition\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php - - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:putBlockPosition\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php - - - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:putBlockPosition\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/network/mcpe/protocol/types/inventory/UseItemTransactionData.php - - message: "#^Method pocketmine\\\\resourcepacks\\\\ZippedResourcePack\\:\\:getPackChunk\\(\\) should return string but returns string\\|false\\.$#" count: 1 diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 6e5d7a4fe6..a21403ea7c 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -190,31 +190,6 @@ parameters: count: 1 path: ../../../src/network/mcpe/NetworkSession.php - - - message: "#^Parameter \\#1 \\$eid of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:putEntityUniqueId\\(\\) expects int, int\\|null given\\.$#" - count: 1 - path: ../../../src/network/mcpe/protocol/SetScorePacket.php - - - - message: "#^Parameter \\#1 \\$v of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:putString\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: ../../../src/network/mcpe/protocol/SetScorePacket.php - - - - message: "#^Parameter \\#1 \\$eid of method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\serializer\\\\PacketSerializer\\:\\:putEntityUniqueId\\(\\) expects int, int\\|null given\\.$#" - count: 1 - path: ../../../src/network/mcpe/protocol/SetScoreboardIdentityPacket.php - - - - message: "#^Parameter \\#1 \\$v of method pocketmine\\\\utils\\\\BinaryStream\\:\\:putVarInt\\(\\) expects int, int\\|null given\\.$#" - count: 1 - path: ../../../src/network/mcpe/protocol/types/recipe/FurnaceRecipe.php - - - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\raklib\\\\RakLibServer\\:\\:\\$mainThreadNotifier \\(pocketmine\\\\snooze\\\\SleeperNotifier\\) does not accept pocketmine\\\\snooze\\\\SleeperNotifier\\|null\\.$#" - count: 1 - path: ../../../src/network/mcpe/raklib/RakLibServer.php - - message: "#^Method pocketmine\\\\permission\\\\DefaultPermissions\\:\\:registerPermission\\(\\) should return pocketmine\\\\permission\\\\Permission but returns pocketmine\\\\permission\\\\Permission\\|null\\.$#" count: 1 diff --git a/tests/phpstan/configs/php-bugs.neon b/tests/phpstan/configs/php-bugs.neon index b0d65acb60..f4754087b4 100644 --- a/tests/phpstan/configs/php-bugs.neon +++ b/tests/phpstan/configs/php-bugs.neon @@ -1,15 +1,5 @@ parameters: ignoreErrors: - - - message: "#^Method ReflectionMethod\\:\\:getClosure\\(\\) invoked with 0 parameters, 1 required\\.$#" - count: 2 - path: ../../phpunit/event/HandlerListManagerTest.php - - - - message: "#^Method ReflectionMethod\\:\\:getClosure\\(\\) invoked with 0 parameters, 1 required\\.$#" - count: 1 - path: ../../phpunit/network/mcpe/handler/StupidJsonDecodeTest.php - - message: "#^Property pocketmine\\\\network\\\\mcpe\\\\handler\\\\StupidJsonDecodeTest\\:\\:\\$stupidJsonDecodeFunc \\(Closure\\(string, bool\\)\\: mixed\\) does not accept Closure\\|null\\.$#" count: 1 diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 3e0dab33b1..a4bff81f06 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -10,11 +10,6 @@ parameters: count: 2 path: ../../../src/console/ConsoleReader.php - - - message: "#^Parameter \\#1 \\$command of function proc_open expects string, array\\ given\\.$#" - count: 1 - path: ../../../src/console/ConsoleReaderThread.php - - message: "#^Method pocketmine\\\\crafting\\\\CraftingManager\\:\\:getDestructorCallbacks\\(\\) should return pocketmine\\\\utils\\\\ObjectSet\\ but returns pocketmine\\\\utils\\\\ObjectSet\\\\|pocketmine\\\\utils\\\\ObjectSet\\\\.$#" count: 1 diff --git a/tests/phpstan/configs/phpunit-wiring-tests.neon b/tests/phpstan/configs/phpunit-wiring-tests.neon deleted file mode 100644 index 40cbef80d2..0000000000 --- a/tests/phpstan/configs/phpunit-wiring-tests.neon +++ /dev/null @@ -1,7 +0,0 @@ -parameters: - ignoreErrors: - - - message: "#^Parameter \\#1 \\$class of method pocketmine\\\\world\\\\format\\\\io\\\\WorldProviderManager\\:\\:addProvider\\(\\) expects class\\-string\\, string given\\.$#" - count: 2 - path: ../../phpunit/world/format/io/LevelProviderManagerTest.php - From 041d3141900541decdff0a9b88ccfd871d3d34a9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 5 Aug 2021 20:11:58 +0100 Subject: [PATCH 2664/3224] HandlerListManager: apply class-string type for getListFor() parameter --- src/event/HandlerListManager.php | 3 +++ tests/phpstan/configs/impossible-generics.neon | 10 ---------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/event/HandlerListManager.php b/src/event/HandlerListManager.php index 942b794670..3bed7631c1 100644 --- a/src/event/HandlerListManager.php +++ b/src/event/HandlerListManager.php @@ -84,6 +84,9 @@ class HandlerListManager{ * * Calling this method also lazily initializes the $classMap inheritance tree of handler lists. * + * @phpstan-template TEvent of Event + * @phpstan-param class-string $event + * * @throws \ReflectionException * @throws \InvalidArgumentException */ diff --git a/tests/phpstan/configs/impossible-generics.neon b/tests/phpstan/configs/impossible-generics.neon index 93ca7da792..0281bcd7f7 100644 --- a/tests/phpstan/configs/impossible-generics.neon +++ b/tests/phpstan/configs/impossible-generics.neon @@ -1,15 +1,5 @@ parameters: ignoreErrors: - - - message: "#^Parameter \\#1 \\$class of static method pocketmine\\\\event\\\\HandlerListManager\\:\\:isValidClass\\(\\) expects ReflectionClass\\, ReflectionClass\\ given\\.$#" - count: 1 - path: ../../../src/event/HandlerListManager.php - - - - message: "#^Parameter \\#1 \\$class of static method pocketmine\\\\event\\\\HandlerListManager\\:\\:resolveNearestHandleableParent\\(\\) expects ReflectionClass\\, ReflectionClass\\ given\\.$#" - count: 1 - path: ../../../src/event/HandlerListManager.php - - message: "#^Method pocketmine\\\\event\\\\RegisteredListener\\:\\:__construct\\(\\) has parameter \\$handler with no signature specified for Closure\\.$#" count: 1 From 91cb374220307d6da8c7a93d1041fe593a14ad04 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 8 Aug 2021 16:01:30 +0100 Subject: [PATCH 2665/3224] LevelDB: fixed isPopulated state getting lost after chunk unload/reload --- src/world/format/io/leveldb/LevelDB.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index aaffee8fb4..c479df90fd 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -412,7 +412,13 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ //TODO: tile ticks, biome states (?) - $chunk->setPopulated(); + $finalisationChr = $this->db->get($index . self::TAG_STATE_FINALISATION); + if($finalisationChr !== false){ + $finalisation = ord($finalisationChr); + $chunk->setPopulated($finalisation === self::FINALISATION_DONE); + }else{ //older versions didn't have this tag + $chunk->setPopulated(); + } if($hasBeenUpgraded){ $chunk->setDirty(); //trigger rewriting chunk to disk if it was converted from an older format } @@ -466,7 +472,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ } //TODO: use this properly - $write->put($index . self::TAG_STATE_FINALISATION, chr(self::FINALISATION_DONE)); + $write->put($index . self::TAG_STATE_FINALISATION, chr($chunk->isPopulated() ? self::FINALISATION_DONE : self::FINALISATION_NEEDS_POPULATION)); $this->writeTags($chunk->getNBTtiles(), $index . self::TAG_BLOCK_ENTITY, $write); $this->writeTags($chunk->getNBTentities(), $index . self::TAG_ENTITY, $write); From 4c10dcaa53466f682e12b7270b53ad94ae30bb6c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 8 Aug 2021 16:19:08 +0100 Subject: [PATCH 2666/3224] ConsoleReaderThread: fixed UTF-8 paths getting corrupted on the way to the subprocess in some cases I was never able to reproduce this, but it appears that Windows breaks the character encoding of command parameters (and also unicode environment variables, even though UNICODE_ENVIRONMENT should be set in php-src) when the file path contains Unicode characters (such as Cyrillic). We workaround this problem using base64, which is an abysmally shitty hack, but not worse than using a subprocess for ConsoleReader in the first place. PHP fucking sucks, and so does Windows. closes #4353 --- src/console/ConsoleReaderThread.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/console/ConsoleReaderThread.php b/src/console/ConsoleReaderThread.php index 6d56c0f416..148149f469 100644 --- a/src/console/ConsoleReaderThread.php +++ b/src/console/ConsoleReaderThread.php @@ -27,12 +27,12 @@ use pocketmine\snooze\SleeperNotifier; use pocketmine\thread\Thread; use pocketmine\utils\AssumptionFailedError; use Webmozart\PathUtil\Path; +use function base64_encode; use function fgets; use function fopen; use function preg_replace; use function proc_open; use function proc_terminate; -use function sprintf; use function stream_select; use function stream_socket_accept; use function stream_socket_get_name; @@ -87,12 +87,18 @@ final class ConsoleReaderThread extends Thread{ $address = stream_socket_get_name($server, false); if($address === false) throw new AssumptionFailedError("stream_socket_get_name() shouldn't return false here"); + $subEnv = $_ENV; + //Windows sucks, and likes to corrupt UTF-8 file paths when they travel to the subprocess, so we base64 encode + //the path to avoid the problem. This is an abysmally shitty hack, but here we are :( + $subEnv["PMConsoleReaderChildProcessFile"] = base64_encode(Path::join(__DIR__, 'ConsoleReaderChildProcess.php')); $sub = proc_open( - [PHP_BINARY, '-r', sprintf('require "%s";', Path::join(__DIR__, 'ConsoleReaderChildProcess.php')), $address], + [PHP_BINARY, '-r', 'require base64_decode($_ENV["PMConsoleReaderChildProcessFile"], true);', $address], [ 2 => fopen("php://stderr", "w"), ], - $pipes + $pipes, + null, + $subEnv ); if($sub === false){ throw new AssumptionFailedError("Something has gone horribly wrong"); From de61417bb68193fbaa738103e723d171e4c1d7c3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 8 Aug 2021 18:53:13 +0100 Subject: [PATCH 2667/3224] Simplify console subprocess require hack --- src/console/ConsoleReaderThread.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/console/ConsoleReaderThread.php b/src/console/ConsoleReaderThread.php index 148149f469..08caec7964 100644 --- a/src/console/ConsoleReaderThread.php +++ b/src/console/ConsoleReaderThread.php @@ -33,6 +33,7 @@ use function fopen; use function preg_replace; use function proc_open; use function proc_terminate; +use function sprintf; use function stream_select; use function stream_socket_accept; use function stream_socket_get_name; @@ -87,18 +88,14 @@ final class ConsoleReaderThread extends Thread{ $address = stream_socket_get_name($server, false); if($address === false) throw new AssumptionFailedError("stream_socket_get_name() shouldn't return false here"); - $subEnv = $_ENV; //Windows sucks, and likes to corrupt UTF-8 file paths when they travel to the subprocess, so we base64 encode //the path to avoid the problem. This is an abysmally shitty hack, but here we are :( - $subEnv["PMConsoleReaderChildProcessFile"] = base64_encode(Path::join(__DIR__, 'ConsoleReaderChildProcess.php')); $sub = proc_open( - [PHP_BINARY, '-r', 'require base64_decode($_ENV["PMConsoleReaderChildProcessFile"], true);', $address], + [PHP_BINARY, '-r', sprintf('require base64_decode("%s", true);', base64_encode(Path::join(__DIR__, 'ConsoleReaderChildProcess.php'))), $address], [ 2 => fopen("php://stderr", "w"), ], - $pipes, - null, - $subEnv + $pipes ); if($sub === false){ throw new AssumptionFailedError("Something has gone horribly wrong"); From d39080c45aef572261cc66d9b5219afa03aeacd5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 10 Aug 2021 14:26:47 +0100 Subject: [PATCH 2668/3224] TranslationContainer: Add support for named translation parameters this also fixes use cases like: [1] = something; [0] = match(...) It made no sense whatsoever to discard the keys anyway. Language::translateString() already supported named parameters since forever anyway. --- src/lang/TranslationContainer.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/lang/TranslationContainer.php b/src/lang/TranslationContainer.php index 3e2905f6f9..bcafb38c02 100644 --- a/src/lang/TranslationContainer.php +++ b/src/lang/TranslationContainer.php @@ -36,11 +36,8 @@ final class TranslationContainer{ public function __construct(string $text, array $params = []){ $this->text = $text; - $i = 0; - foreach($params as $str){ - $this->params[$i] = (string) $str; - - ++$i; + foreach($params as $k => $str){ + $this->params[$k] = (string) $str; } } @@ -55,7 +52,7 @@ final class TranslationContainer{ return $this->params; } - public function getParameter(int $i) : ?string{ + public function getParameter(int|string $i) : ?string{ return $this->params[$i] ?? null; } } From 2293bd948dc2c20198170d94a9bd212477b79611 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 10 Aug 2021 14:50:40 +0100 Subject: [PATCH 2669/3224] Added KnownTranslationFactory and use it in as many places as possible this makes translation usage much more statically analysable. The only places this isn't used are: - places that prefix translations with colours (those are still a problem) - places where server/client translations don't match (e.g. gameMode.changed accepts different parameters in vanilla than in PM) --- build/generate-known-translation-apis.php | 178 ++ build/generate-known-translation-keys.php | 93 - phpstan.neon.dist | 2 +- src/Server.php | 62 +- src/command/Command.php | 3 +- src/command/SimpleCommandMap.php | 10 +- src/command/defaults/BanCommand.php | 4 +- src/command/defaults/BanIpCommand.php | 8 +- src/command/defaults/BanListCommand.php | 6 +- src/command/defaults/ClearCommand.php | 5 +- .../defaults/DefaultGamemodeCommand.php | 4 +- src/command/defaults/DeopCommand.php | 4 +- src/command/defaults/DifficultyCommand.php | 4 +- src/command/defaults/EffectCommand.php | 11 +- src/command/defaults/EnchantCommand.php | 5 +- src/command/defaults/GamemodeCommand.php | 5 +- src/command/defaults/GiveCommand.php | 7 +- src/command/defaults/HelpCommand.php | 4 +- src/command/defaults/KickCommand.php | 5 +- src/command/defaults/KillCommand.php | 5 +- src/command/defaults/ListCommand.php | 4 +- src/command/defaults/MeCommand.php | 4 +- src/command/defaults/OpCommand.php | 4 +- src/command/defaults/PardonCommand.php | 4 +- src/command/defaults/PardonIpCommand.php | 6 +- src/command/defaults/ParticleCommand.php | 3 +- src/command/defaults/PluginsCommand.php | 4 +- src/command/defaults/SaveCommand.php | 6 +- src/command/defaults/SaveOffCommand.php | 4 +- src/command/defaults/SaveOnCommand.php | 4 +- src/command/defaults/SeedCommand.php | 4 +- src/command/defaults/SetWorldSpawnCommand.php | 4 +- src/command/defaults/SpawnpointCommand.php | 5 +- src/command/defaults/StopCommand.php | 4 +- src/command/defaults/TeleportCommand.php | 14 +- src/command/defaults/TellCommand.php | 5 +- src/command/defaults/TimeCommand.php | 8 +- src/command/defaults/TimingsCommand.php | 20 +- src/command/defaults/TitleCommand.php | 6 +- src/command/defaults/VersionCommand.php | 10 +- src/command/defaults/WhitelistCommand.php | 20 +- src/event/player/PlayerDeathEvent.php | 73 +- src/lang/KnownTranslationFactory.php | 1744 +++++++++++++++++ src/network/mcpe/NetworkSession.php | 4 +- .../mcpe/handler/LoginPacketHandler.php | 4 +- src/network/query/QueryHandler.php | 4 +- src/player/Player.php | 15 +- src/plugin/PluginBase.php | 6 +- src/plugin/PluginManager.php | 53 +- src/wizard/SetupWizard.php | 62 +- src/world/World.php | 4 +- src/world/WorldManager.php | 20 +- 52 files changed, 2185 insertions(+), 372 deletions(-) create mode 100644 build/generate-known-translation-apis.php delete mode 100644 build/generate-known-translation-keys.php create mode 100644 src/lang/KnownTranslationFactory.php diff --git a/build/generate-known-translation-apis.php b/build/generate-known-translation-apis.php new file mode 100644 index 0000000000..fd24072c05 --- /dev/null +++ b/build/generate-known-translation-apis.php @@ -0,0 +1,178 @@ + $languageDefinitions + */ +function generate_known_translation_keys(array $languageDefinitions) : void{ + ob_start(); + + echo SHARED_HEADER; + echo <<<'HEADER' +/** + * This class contains constants for all the translations known to PocketMine-MP as per the used version of pmmp/Language. + * This class is generated automatically, do NOT modify it by hand. + */ +final class KnownTranslationKeys{ + +HEADER; + + ksort($languageDefinitions, SORT_STRING); + foreach($languageDefinitions as $k => $_){ + echo "\tpublic const "; + echo constantify($k); + echo " = \"" . $k . "\";\n"; + } + + echo "}\n"; + + file_put_contents(dirname(__DIR__) . '/src/lang/KnownTranslationKeys.php', ob_get_clean()); + + echo "Done generating KnownTranslationKeys.\n"; +} + +/** + * @param string[] $languageDefinitions + * @phpstan-param array $languageDefinitions + */ +function generate_known_translation_factory(array $languageDefinitions) : void{ + ob_start(); + + echo SHARED_HEADER; + echo <<<'HEADER' +/** + * This class contains factory methods for all the translations known to PocketMine-MP as per the used version of + * pmmp/Language. + * This class is generated automatically, do NOT modify it by hand. + */ +final class KnownTranslationFactory{ + +HEADER; + ksort($languageDefinitions, SORT_STRING); + + $parameterRegex = '/{%(.+?)}/'; + foreach($languageDefinitions as $key => $value){ + $parameters = []; + if(preg_match_all($parameterRegex, $value, $matches) > 0){ + foreach($matches[1] as $parameterName){ + if(is_numeric($parameterName)){ + $parameters[$parameterName] = "param$parameterName"; + }else{ + $parameters[$parameterName] = $parameterName; + } + } + } + echo "\tpublic static function " . + functionify($key) . + "(" . implode(", ", array_map(fn(string $paramName) => "string \$$paramName", $parameters)) . ") : TranslationContainer{\n"; + echo "\t\treturn new TranslationContainer(KnownTranslationKeys::" . constantify($key) . ", ["; + foreach($parameters as $parameterKey => $parameterName){ + echo "\n\t\t\t"; + if(!is_numeric($parameterKey)){ + echo "\"$parameterKey\""; + }else{ + echo $parameterKey; + } + echo " => \$$parameterName,"; + } + if(count($parameters) !== 0){ + echo "\n\t\t"; + } + echo "]);\n\t}\n\n"; + } + + echo "}\n"; + + file_put_contents(dirname(__DIR__) . '/src/lang/KnownTranslationFactory.php', ob_get_clean()); + + echo "Done generating KnownTranslationFactory.\n"; +} + + +$lang = parse_ini_file(Path::join(\pocketmine\RESOURCE_PATH, "locale", "eng.ini"), false, INI_SCANNER_RAW); +if($lang === false){ + fwrite(STDERR, "Missing language files!\n"); + exit(1); +} + +generate_known_translation_keys($lang); +generate_known_translation_factory($lang); diff --git a/build/generate-known-translation-keys.php b/build/generate-known-translation-keys.php deleted file mode 100644 index 60f901eb3f..0000000000 --- a/build/generate-known-translation-keys.php +++ /dev/null @@ -1,93 +0,0 @@ - $v){ - $perms[] = $k; -} - -sort($perms, SORT_STRING); -foreach($perms as $perm){ - echo "\tpublic const "; - echo constantify($perm); - echo " = \"" . $perm . "\";\n"; -} - -echo "}\n"; - -file_put_contents(dirname(__DIR__) . '/src/lang/KnownTranslationKeys.php', ob_get_clean()); - -echo "Done.\n"; diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 8c45f81584..c3b6a99fdd 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -30,7 +30,7 @@ parameters: - src/PocketMine.php - build/make-release.php - build/server-phar.php - - build/generate-known-translation-keys.php + - build/generate-known-translation-apis.php paths: - src - tests/phpstan/rules diff --git a/src/Server.php b/src/Server.php index 2b34f1cb7d..bce3d1a68e 100644 --- a/src/Server.php +++ b/src/Server.php @@ -43,6 +43,7 @@ use pocketmine\event\player\PlayerDataSaveEvent; use pocketmine\event\server\CommandEvent; use pocketmine\event\server\DataPacketSendEvent; use pocketmine\event\server\QueryRegenerateEvent; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\Language; use pocketmine\lang\LanguageNotFoundException; @@ -143,6 +144,7 @@ use function stripos; use function strlen; use function strrpos; use function strtolower; +use function strval; use function time; use function touch; use function trim; @@ -529,7 +531,7 @@ class Server{ private function handleCorruptedPlayerData(string $name) : void{ $path = $this->getPlayerDataPath($name); rename($path, $path . '.bak'); - $this->logger->error($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_DATA_PLAYERCORRUPTED, [$name])); + $this->logger->error($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_data_playerCorrupted($name))); } public function getOfflinePlayerData(string $name) : ?CompoundTag{ @@ -575,7 +577,7 @@ class Server{ try{ file_put_contents($this->getPlayerDataPath($name), zlib_encode($nbt->write(new TreeRoot($ev->getSaveData())), ZLIB_ENCODING_GZIP)); }catch(\ErrorException $e){ - $this->logger->critical($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_DATA_SAVEERROR, [$name, $e->getMessage()])); + $this->logger->critical($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_data_saveError($name, $e->getMessage()))); $this->logger->logException($e); } }); @@ -879,30 +881,30 @@ class Server{ } } - $this->logger->info($this->getLanguage()->translateString(KnownTranslationKeys::LANGUAGE_SELECTED, [$this->getLanguage()->getName(), $this->getLanguage()->getLang()])); + $this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::language_selected($this->getLanguage()->getName(), $this->getLanguage()->getLang()))); if(VersionInfo::IS_DEVELOPMENT_BUILD){ if(!$this->configGroup->getPropertyBool("settings.enable-dev-builds", false)){ - $this->logger->emergency($this->language->translateString(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR1, [VersionInfo::NAME])); - $this->logger->emergency($this->language->translateString(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR2)); - $this->logger->emergency($this->language->translateString(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR3)); - $this->logger->emergency($this->language->translateString(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR4, ["settings.enable-dev-builds"])); - $this->logger->emergency($this->language->translateString(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR5, ["https://github.com/pmmp/PocketMine-MP/releases"])); + $this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_server_devBuild_error1(VersionInfo::NAME))); + $this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_server_devBuild_error2())); + $this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_server_devBuild_error3())); + $this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_server_devBuild_error4("settings.enable-dev-builds"))); + $this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_server_devBuild_error5("https://github.com/pmmp/PocketMine-MP/releases"))); $this->forceShutdown(); return; } $this->logger->warning(str_repeat("-", 40)); - $this->logger->warning($this->language->translateString(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_WARNING1, [VersionInfo::NAME])); - $this->logger->warning($this->language->translateString(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_WARNING2)); - $this->logger->warning($this->language->translateString(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_WARNING3)); + $this->logger->warning($this->language->translate(KnownTranslationFactory::pocketmine_server_devBuild_warning1(VersionInfo::NAME))); + $this->logger->warning($this->language->translate(KnownTranslationFactory::pocketmine_server_devBuild_warning2())); + $this->logger->warning($this->language->translate(KnownTranslationFactory::pocketmine_server_devBuild_warning3())); $this->logger->warning(str_repeat("-", 40)); } $this->memoryManager = new MemoryManager($this); - $this->logger->info($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_START, [TextFormat::AQUA . $this->getVersion() . TextFormat::RESET])); + $this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_start(TextFormat::AQUA . $this->getVersion() . TextFormat::RESET))); if(($poolSize = $this->configGroup->getPropertyString("settings.async-workers", "auto")) === "auto"){ $poolSize = 2; @@ -955,11 +957,11 @@ class Server{ $this->onlineMode = $this->configGroup->getConfigBool("xbox-auth", true); if($this->onlineMode){ - $this->logger->info($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_AUTH_ENABLED)); + $this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_auth_enabled())); }else{ - $this->logger->warning($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_AUTH_DISABLED)); - $this->logger->warning($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_AUTHWARNING)); - $this->logger->warning($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_AUTHPROPERTY_DISABLED)); + $this->logger->warning($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_auth_disabled())); + $this->logger->warning($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_authWarning())); + $this->logger->warning($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_authProperty_disabled())); } if($this->configGroup->getConfigBool("hardcore", false) and $this->getDifficulty() < World::DIFFICULTY_HARD){ @@ -976,11 +978,11 @@ class Server{ $this->network = new Network($this->logger); $this->network->setName($this->getMotd()); - $this->logger->info($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_INFO, [ + $this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_info( $this->getName(), (VersionInfo::IS_DEVELOPMENT_BUILD ? TextFormat::YELLOW : "") . $this->getPocketMineVersion() . TextFormat::RESET - ])); - $this->logger->info($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_LICENSE, [$this->getName()])); + ))); + $this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_license($this->getName()))); Timings::init(); TimingsHandler::setEnabled($this->configGroup->getPropertyBool("settings.enable-profiling", false)); @@ -1017,7 +1019,7 @@ class Server{ ){ $providerManager->setDefault($format); }elseif($formatName !== ""){ - $this->logger->warning($this->language->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_BADDEFAULTFORMAT, [$formatName])); + $this->logger->warning($this->language->translate(KnownTranslationFactory::pocketmine_level_badDefaultFormat($formatName))); } $this->worldManager = new WorldManager($this, Path::join($this->dataPath, "worlds"), $providerManager); @@ -1087,7 +1089,7 @@ class Server{ $world = $this->worldManager->getWorldByName($default); if($world === null){ - $this->getLogger()->emergency($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_DEFAULTERROR)); + $this->getLogger()->emergency($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_defaultError())); $this->forceShutdown(); return; @@ -1103,7 +1105,7 @@ class Server{ //if it's not registered we need to make sure Query still works $this->network->registerInterface(new DedicatedQueryNetworkInterface($this->getIp(), $this->getPort(), new \PrefixedLogger($this->logger, "Dedicated Query Interface"))); } - $this->logger->info($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_NETWORKSTART, [$this->getIp(), $this->getPort()])); + $this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_networkStart($this->getIp(), (string) $this->getPort()))); if($useQuery){ $this->network->registerRawPacketHandler(new QueryHandler($this)); @@ -1124,9 +1126,9 @@ class Server{ $this->configGroup->save(); - $this->logger->info($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_DEFAULTGAMEMODE, [$this->getGamemode()->getTranslationKey()])); - $this->logger->info($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_DONATE, [TextFormat::AQUA . "https://patreon.com/pocketminemp" . TextFormat::RESET])); - $this->logger->info($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_STARTFINISHED, [round(microtime(true) - $this->startTime, 3)])); + $this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_defaultGameMode($this->getGamemode()->getTranslationKey()))); + $this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_donate(TextFormat::AQUA . "https://patreon.com/pocketminemp" . TextFormat::RESET))); + $this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_startFinished(strval(round(microtime(true) - $this->startTime, 3))))); //TODO: move console parts to a separate component $consoleSender = new ConsoleCommandSender($this, $this->language); @@ -1501,10 +1503,10 @@ class Server{ ini_set("error_reporting", '0'); ini_set("memory_limit", '-1'); //Fix error dump not dumped on memory problems try{ - $this->logger->emergency($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_CRASH_CREATE)); + $this->logger->emergency($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_crash_create())); $dump = new CrashDump($this); - $this->logger->emergency($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_CRASH_SUBMIT, [$dump->getPath()])); + $this->logger->emergency($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_crash_submit($dump->getPath()))); if($this->configGroup->getPropertyBool("auto-report.enabled", true)){ $report = true; @@ -1548,7 +1550,7 @@ class Server{ if(isset($data->crashId) and isset($data->crashUrl)){ $reportId = $data->crashId; $reportUrl = $data->crashUrl; - $this->logger->emergency($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_CRASH_ARCHIVE, [$reportUrl, $reportId])); + $this->logger->emergency($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_crash_archive($reportUrl, (string) $reportId))); }elseif(isset($data->error)){ $this->logger->emergency("Automatic crash report submission failed: $data->error"); } @@ -1560,7 +1562,7 @@ class Server{ }catch(\Throwable $e){ $this->logger->logException($e); try{ - $this->logger->critical($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_CRASH_ERROR, [$e->getMessage()])); + $this->logger->critical($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_crash_error($e->getMessage()))); }catch(\Throwable $e){} } @@ -1729,7 +1731,7 @@ class Server{ } if($this->getTicksPerSecondAverage() < 12){ - $this->logger->warning($this->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_TICKOVERLOAD)); + $this->logger->warning($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_tickOverload())); } } diff --git a/src/command/Command.php b/src/command/Command.php index fa792fdb13..9ba5fd16c9 100644 --- a/src/command/Command.php +++ b/src/command/Command.php @@ -28,6 +28,7 @@ namespace pocketmine\command; use pocketmine\command\utils\CommandException; use pocketmine\console\ConsoleCommandSender; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\PermissionManager; @@ -241,7 +242,7 @@ abstract class Command{ $result = new TranslationContainer($formatted, $message->getParameters()); $colored = new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . $formatted, $message->getParameters()); }else{ - $result = new TranslationContainer(KnownTranslationKeys::CHAT_TYPE_ADMIN, [$source->getName(), $message]); + $result = KnownTranslationFactory::chat_type_admin($source->getName(), $message); $colored = new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . "%" . KnownTranslationKeys::CHAT_TYPE_ADMIN, [$source->getName(), $message]); } diff --git a/src/command/SimpleCommandMap.php b/src/command/SimpleCommandMap.php index 2feb20a5b8..90d54be63c 100644 --- a/src/command/SimpleCommandMap.php +++ b/src/command/SimpleCommandMap.php @@ -65,7 +65,7 @@ use pocketmine\command\defaults\VanillaCommand; use pocketmine\command\defaults\VersionCommand; use pocketmine\command\defaults\WhitelistCommand; use pocketmine\command\utils\InvalidCommandSyntaxException; -use pocketmine\lang\KnownTranslationKeys; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\Server; use function array_shift; use function count; @@ -246,7 +246,7 @@ class SimpleCommandMap implements CommandMap{ try{ $target->execute($sender, $sentCommandLabel, $args); }catch(InvalidCommandSyntaxException $e){ - $sender->sendMessage($sender->getLanguage()->translateString(KnownTranslationKeys::COMMANDS_GENERIC_USAGE, [$target->getUsage()])); + $sender->sendMessage($sender->getLanguage()->translate(KnownTranslationFactory::commands_generic_usage($target->getUsage()))); }finally{ $target->timings->stopTiming(); } @@ -278,7 +278,7 @@ class SimpleCommandMap implements CommandMap{ foreach($values as $alias => $commandStrings){ if(strpos($alias, ":") !== false){ - $this->server->getLogger()->warning($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_COMMAND_ALIAS_ILLEGAL, [$alias])); + $this->server->getLogger()->warning($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_command_alias_illegal($alias))); continue; } @@ -301,12 +301,12 @@ class SimpleCommandMap implements CommandMap{ } if(count($recursive) > 0){ - $this->server->getLogger()->warning($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_COMMAND_ALIAS_RECURSIVE, [$alias, implode(", ", $recursive)])); + $this->server->getLogger()->warning($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_command_alias_recursive($alias, implode(", ", $recursive)))); continue; } if(count($bad) > 0){ - $this->server->getLogger()->warning($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_COMMAND_ALIAS_NOTFOUND, [$alias, implode(", ", $bad)])); + $this->server->getLogger()->warning($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_command_alias_notFound($alias, implode(", ", $bad)))); continue; } diff --git a/src/command/defaults/BanCommand.php b/src/command/defaults/BanCommand.php index 14f3416205..d571a9aa04 100644 --- a/src/command/defaults/BanCommand.php +++ b/src/command/defaults/BanCommand.php @@ -26,8 +26,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use function array_shift; @@ -63,7 +63,7 @@ class BanCommand extends VanillaCommand{ $player->kick($reason !== "" ? "Banned by admin. Reason: " . $reason : "Banned by admin."); } - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_BAN_SUCCESS, [$player !== null ? $player->getName() : $name])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_ban_success($player !== null ? $player->getName() : $name)); return true; } diff --git a/src/command/defaults/BanIpCommand.php b/src/command/defaults/BanIpCommand.php index 89d10e7f4a..3356e5ece1 100644 --- a/src/command/defaults/BanIpCommand.php +++ b/src/command/defaults/BanIpCommand.php @@ -26,8 +26,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use function array_shift; @@ -61,15 +61,15 @@ class BanIpCommand extends VanillaCommand{ if(preg_match("/^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$/", $value)){ $this->processIPBan($value, $sender, $reason); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_BANIP_SUCCESS, [$value])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_banip_success($value)); }else{ if(($player = $sender->getServer()->getPlayerByPrefix($value)) instanceof Player){ $ip = $player->getNetworkSession()->getIp(); $this->processIPBan($ip, $sender, $reason); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_BANIP_SUCCESS_PLAYERS, [$ip, $player->getName()])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_banip_success_players($ip, $player->getName())); }else{ - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_BANIP_INVALID)); + $sender->sendMessage(KnownTranslationFactory::commands_banip_invalid()); return false; } diff --git a/src/command/defaults/BanListCommand.php b/src/command/defaults/BanListCommand.php index 366a479aef..86d140cb10 100644 --- a/src/command/defaults/BanListCommand.php +++ b/src/command/defaults/BanListCommand.php @@ -25,8 +25,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\BanEntry; use pocketmine\permission\DefaultPermissionNames; use function array_map; @@ -73,9 +73,9 @@ class BanListCommand extends VanillaCommand{ $message = implode(", ", $list); if($args[0] === "ips"){ - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_BANLIST_IPS, [count($list)])); + $sender->sendMessage(KnownTranslationFactory::commands_banlist_ips((string) count($list))); }else{ - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_BANLIST_PLAYERS, [count($list)])); + $sender->sendMessage(KnownTranslationFactory::commands_banlist_players((string) count($list))); } $sender->sendMessage($message); diff --git a/src/command/defaults/ClearCommand.php b/src/command/defaults/ClearCommand.php index bfa5623f76..6951ef2cfc 100644 --- a/src/command/defaults/ClearCommand.php +++ b/src/command/defaults/ClearCommand.php @@ -28,6 +28,7 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\LegacyStringToItemParser; use pocketmine\item\LegacyStringToItemParserException; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; @@ -102,7 +103,7 @@ class ClearCommand extends VanillaCommand{ } if($count > 0){ - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_CLEAR_TESTING, [$target->getName(), $count])); + $sender->sendMessage(KnownTranslationFactory::commands_clear_testing($target->getName(), (string) $count)); }else{ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_CLEAR_FAILURE_NO_ITEMS, [$target->getName()])); } @@ -164,7 +165,7 @@ class ClearCommand extends VanillaCommand{ } if($cleared > 0){ - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_CLEAR_SUCCESS, [$target->getName(), $cleared])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_clear_success($target->getName(), (string) $cleared)); }else{ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_CLEAR_FAILURE_NO_ITEMS, [$target->getName()])); } diff --git a/src/command/defaults/DefaultGamemodeCommand.php b/src/command/defaults/DefaultGamemodeCommand.php index 88648edd0d..f799777f22 100644 --- a/src/command/defaults/DefaultGamemodeCommand.php +++ b/src/command/defaults/DefaultGamemodeCommand.php @@ -26,8 +26,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\data\java\GameModeIdMap; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\GameMode; use function count; @@ -59,7 +59,7 @@ class DefaultGamemodeCommand extends VanillaCommand{ } $sender->getServer()->getConfigGroup()->setConfigInt("gamemode", GameModeIdMap::getInstance()->toId($gameMode)); - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_DEFAULTGAMEMODE_SUCCESS, [$gameMode->getTranslationKey()])); + $sender->sendMessage(KnownTranslationFactory::commands_defaultgamemode_success($gameMode->getTranslationKey())); return true; } } diff --git a/src/command/defaults/DeopCommand.php b/src/command/defaults/DeopCommand.php index 6df6520cd2..900aa0381a 100644 --- a/src/command/defaults/DeopCommand.php +++ b/src/command/defaults/DeopCommand.php @@ -26,8 +26,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; @@ -63,7 +63,7 @@ class DeopCommand extends VanillaCommand{ if(($player = $sender->getServer()->getPlayerExact($name)) !== null){ $player->sendMessage(TextFormat::GRAY . "You are no longer op!"); } - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_DEOP_SUCCESS, [$name])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_deop_success($name)); return true; } diff --git a/src/command/defaults/DifficultyCommand.php b/src/command/defaults/DifficultyCommand.php index bd2011359a..ce5b42ce73 100644 --- a/src/command/defaults/DifficultyCommand.php +++ b/src/command/defaults/DifficultyCommand.php @@ -26,8 +26,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\world\World; use function count; @@ -66,7 +66,7 @@ class DifficultyCommand extends VanillaCommand{ $world->setDifficulty($difficulty); } - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_DIFFICULTY_SUCCESS, [$difficulty])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_difficulty_success((string) $difficulty)); }else{ throw new InvalidCommandSyntaxException(); } diff --git a/src/command/defaults/EffectCommand.php b/src/command/defaults/EffectCommand.php index db37acbe8f..0e6df678dd 100644 --- a/src/command/defaults/EffectCommand.php +++ b/src/command/defaults/EffectCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\VanillaEffects; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; @@ -66,7 +67,7 @@ class EffectCommand extends VanillaCommand{ if(strtolower($args[1]) === "clear"){ $effectManager->clear(); - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_SUCCESS_REMOVED_ALL, [$player->getDisplayName()])); + $sender->sendMessage(KnownTranslationFactory::commands_effect_success_removed_all($player->getDisplayName())); return true; } @@ -106,19 +107,19 @@ class EffectCommand extends VanillaCommand{ if($duration === 0){ if(!$effectManager->has($effect)){ if(count($effectManager->all()) === 0){ - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_FAILURE_NOTACTIVE_ALL, [$player->getDisplayName()])); + $sender->sendMessage(KnownTranslationFactory::commands_effect_failure_notActive_all($player->getDisplayName())); }else{ - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_FAILURE_NOTACTIVE, [$effect->getName(), $player->getDisplayName()])); + $sender->sendMessage(KnownTranslationFactory::commands_effect_failure_notActive($effect->getName(), $player->getDisplayName())); } return true; } $effectManager->remove($effect); - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_SUCCESS_REMOVED, [$effect->getName(), $player->getDisplayName()])); + $sender->sendMessage(KnownTranslationFactory::commands_effect_success_removed($effect->getName(), $player->getDisplayName())); }else{ $instance = new EffectInstance($effect, $duration, $amplification, $visible); $effectManager->add($instance); - self::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_SUCCESS, [$effect->getName(), $instance->getAmplifier(), $player->getDisplayName(), $instance->getDuration() / 20])); + self::broadcastCommandMessage($sender, KnownTranslationFactory::commands_effect_success($effect->getName(), (string) $instance->getAmplifier(), $player->getDisplayName(), (string) ($instance->getDuration() / 20))); } return true; diff --git a/src/command/defaults/EnchantCommand.php b/src/command/defaults/EnchantCommand.php index a05b48d7f2..d34e6a884c 100644 --- a/src/command/defaults/EnchantCommand.php +++ b/src/command/defaults/EnchantCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\enchantment\EnchantmentInstance; use pocketmine\item\enchantment\VanillaEnchantments; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; @@ -63,14 +64,14 @@ class EnchantCommand extends VanillaCommand{ $item = $player->getInventory()->getItemInHand(); if($item->isNull()){ - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_ENCHANT_NOITEM)); + $sender->sendMessage(KnownTranslationFactory::commands_enchant_noItem()); return true; } try{ $enchantment = VanillaEnchantments::fromString($args[1]); }catch(\InvalidArgumentException $e){ - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_ENCHANT_NOTFOUND, [$args[1]])); + $sender->sendMessage(KnownTranslationFactory::commands_enchant_notFound($args[1])); return true; } diff --git a/src/command/defaults/GamemodeCommand.php b/src/command/defaults/GamemodeCommand.php index 3b99fe22bb..41fc5262f9 100644 --- a/src/command/defaults/GamemodeCommand.php +++ b/src/command/defaults/GamemodeCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; @@ -78,10 +79,10 @@ class GamemodeCommand extends VanillaCommand{ $sender->sendMessage("Game mode change for " . $target->getName() . " failed!"); }else{ if($target === $sender){ - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_GAMEMODE_SUCCESS_SELF, [$gameMode->getTranslationKey()])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_gamemode_success_self($gameMode->getTranslationKey())); }else{ $target->sendMessage(new TranslationContainer(KnownTranslationKeys::GAMEMODE_CHANGED, [$gameMode->getTranslationKey()])); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_GAMEMODE_SUCCESS_OTHER, [$gameMode->getTranslationKey(), $target->getName()])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_gamemode_success_other($gameMode->getTranslationKey(), $target->getName())); } } diff --git a/src/command/defaults/GiveCommand.php b/src/command/defaults/GiveCommand.php index f28e6fee00..63cb328600 100644 --- a/src/command/defaults/GiveCommand.php +++ b/src/command/defaults/GiveCommand.php @@ -28,6 +28,7 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\LegacyStringToItemParser; use pocketmine\item\LegacyStringToItemParserException; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\nbt\JsonNbtParser; @@ -82,7 +83,7 @@ class GiveCommand extends VanillaCommand{ try{ $tags = JsonNbtParser::parseJson($data); }catch(NbtDataException $e){ - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_GIVE_TAGERROR, [$e->getMessage()])); + $sender->sendMessage(KnownTranslationFactory::commands_give_tagError($e->getMessage())); return true; } @@ -92,11 +93,11 @@ class GiveCommand extends VanillaCommand{ //TODO: overflow $player->getInventory()->addItem($item); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_GIVE_SUCCESS, [ + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_give_success( $item->getName() . " (" . $item->getId() . ":" . $item->getMeta() . ")", (string) $item->getCount(), $player->getName() - ])); + )); return true; } } diff --git a/src/command/defaults/HelpCommand.php b/src/command/defaults/HelpCommand.php index 09c29c3c85..4ace7931c1 100644 --- a/src/command/defaults/HelpCommand.php +++ b/src/command/defaults/HelpCommand.php @@ -25,8 +25,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\TextFormat; use function array_chunk; @@ -88,7 +88,7 @@ class HelpCommand extends VanillaCommand{ if($pageNumber < 1){ $pageNumber = 1; } - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_HELP_HEADER, [$pageNumber, count($commands)])); + $sender->sendMessage(KnownTranslationFactory::commands_help_header((string) $pageNumber, (string) count($commands))); if(isset($commands[$pageNumber - 1])){ foreach($commands[$pageNumber - 1] as $command){ $sender->sendMessage(TextFormat::DARK_GREEN . "/" . $command->getName() . ": " . TextFormat::WHITE . $command->getDescription()); diff --git a/src/command/defaults/KickCommand.php b/src/command/defaults/KickCommand.php index f30761fea7..3fbd00a0e9 100644 --- a/src/command/defaults/KickCommand.php +++ b/src/command/defaults/KickCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; @@ -62,9 +63,9 @@ class KickCommand extends VanillaCommand{ if(($player = $sender->getServer()->getPlayerByPrefix($name)) instanceof Player){ $player->kick("Kicked by admin." . ($reason !== "" ? "Reason: " . $reason : "")); if($reason !== ""){ - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_KICK_SUCCESS_REASON, [$player->getName(), $reason])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_kick_success_reason($player->getName(), $reason)); }else{ - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_KICK_SUCCESS, [$player->getName()])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_kick_success($player->getName())); } }else{ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); diff --git a/src/command/defaults/KillCommand.php b/src/command/defaults/KillCommand.php index 65b2386e68..f8655738aa 100644 --- a/src/command/defaults/KillCommand.php +++ b/src/command/defaults/KillCommand.php @@ -27,6 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\event\entity\EntityDamageEvent; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; @@ -65,7 +66,7 @@ class KillCommand extends VanillaCommand{ if($player instanceof Player){ $player->attack(new EntityDamageEvent($player, EntityDamageEvent::CAUSE_SUICIDE, 1000)); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_KILL_SUCCESSFUL, [$player->getName()])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_kill_successful($player->getName())); }else{ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); } @@ -79,7 +80,7 @@ class KillCommand extends VanillaCommand{ } $sender->attack(new EntityDamageEvent($sender, EntityDamageEvent::CAUSE_SUICIDE, 1000)); - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_KILL_SUCCESSFUL, [$sender->getName()])); + $sender->sendMessage(KnownTranslationFactory::commands_kill_successful($sender->getName())); }else{ throw new InvalidCommandSyntaxException(); } diff --git a/src/command/defaults/ListCommand.php b/src/command/defaults/ListCommand.php index 282a889ce8..db8e66c8e4 100644 --- a/src/command/defaults/ListCommand.php +++ b/src/command/defaults/ListCommand.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use function array_filter; @@ -58,7 +58,7 @@ class ListCommand extends VanillaCommand{ })); sort($playerNames, SORT_STRING); - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_PLAYERS_LIST, [count($playerNames), $sender->getServer()->getMaxPlayers()])); + $sender->sendMessage(KnownTranslationFactory::commands_players_list((string) count($playerNames), (string) $sender->getServer()->getMaxPlayers())); $sender->sendMessage(implode(", ", $playerNames)); return true; diff --git a/src/command/defaults/MeCommand.php b/src/command/defaults/MeCommand.php index 868571579d..f0df8bf336 100644 --- a/src/command/defaults/MeCommand.php +++ b/src/command/defaults/MeCommand.php @@ -25,8 +25,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; @@ -53,7 +53,7 @@ class MeCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $sender->getServer()->broadcastMessage(new TranslationContainer(KnownTranslationKeys::CHAT_TYPE_EMOTE, [$sender instanceof Player ? $sender->getDisplayName() : $sender->getName(), TextFormat::WHITE . implode(" ", $args)])); + $sender->getServer()->broadcastMessage(KnownTranslationFactory::chat_type_emote($sender instanceof Player ? $sender->getDisplayName() : $sender->getName(), TextFormat::WHITE . implode(" ", $args))); return true; } diff --git a/src/command/defaults/OpCommand.php b/src/command/defaults/OpCommand.php index 8d8c55f1a9..721dda447e 100644 --- a/src/command/defaults/OpCommand.php +++ b/src/command/defaults/OpCommand.php @@ -26,8 +26,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; @@ -63,7 +63,7 @@ class OpCommand extends VanillaCommand{ if(($player = $sender->getServer()->getPlayerExact($name)) !== null){ $player->sendMessage(TextFormat::GRAY . "You are now op!"); } - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_OP_SUCCESS, [$name])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_op_success($name)); return true; } } diff --git a/src/command/defaults/PardonCommand.php b/src/command/defaults/PardonCommand.php index eaadf87052..f35839b00b 100644 --- a/src/command/defaults/PardonCommand.php +++ b/src/command/defaults/PardonCommand.php @@ -26,8 +26,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use function count; @@ -54,7 +54,7 @@ class PardonCommand extends VanillaCommand{ $sender->getServer()->getNameBans()->remove($args[0]); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_UNBAN_SUCCESS, [$args[0]])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_unban_success($args[0])); return true; } diff --git a/src/command/defaults/PardonIpCommand.php b/src/command/defaults/PardonIpCommand.php index f728b27616..191dc036cb 100644 --- a/src/command/defaults/PardonIpCommand.php +++ b/src/command/defaults/PardonIpCommand.php @@ -26,8 +26,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use function count; use function preg_match; @@ -56,9 +56,9 @@ class PardonIpCommand extends VanillaCommand{ if(preg_match("/^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$/", $args[0])){ $sender->getServer()->getIPBans()->remove($args[0]); $sender->getServer()->getNetwork()->unblockAddress($args[0]); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_UNBANIP_SUCCESS, [$args[0]])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_unbanip_success($args[0])); }else{ - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_UNBANIP_INVALID)); + $sender->sendMessage(KnownTranslationFactory::commands_unbanip_invalid()); } return true; diff --git a/src/command/defaults/ParticleCommand.php b/src/command/defaults/ParticleCommand.php index 569bd71958..a7ee0d8c42 100644 --- a/src/command/defaults/ParticleCommand.php +++ b/src/command/defaults/ParticleCommand.php @@ -29,6 +29,7 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\ItemFactory; use pocketmine\item\VanillaItems; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; @@ -124,7 +125,7 @@ class ParticleCommand extends VanillaCommand{ return true; } - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_PARTICLE_SUCCESS, [$name, $count])); + $sender->sendMessage(KnownTranslationFactory::commands_particle_success($name, (string) $count)); $random = new Random((int) (microtime(true) * 1000) + mt_rand()); diff --git a/src/command/defaults/PluginsCommand.php b/src/command/defaults/PluginsCommand.php index 791c341720..3666c45435 100644 --- a/src/command/defaults/PluginsCommand.php +++ b/src/command/defaults/PluginsCommand.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\plugin\Plugin; use pocketmine\utils\TextFormat; @@ -57,7 +57,7 @@ class PluginsCommand extends VanillaCommand{ }, $sender->getServer()->getPluginManager()->getPlugins()); sort($list, SORT_STRING); - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_SUCCESS, [count($list), implode(TextFormat::WHITE . ", ", $list)])); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_plugins_success((string) count($list), implode(TextFormat::WHITE . ", ", $list))); return true; } } diff --git a/src/command/defaults/SaveCommand.php b/src/command/defaults/SaveCommand.php index 12b8b54d60..fe07c53a8e 100644 --- a/src/command/defaults/SaveCommand.php +++ b/src/command/defaults/SaveCommand.php @@ -25,8 +25,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use function microtime; use function round; @@ -47,7 +47,7 @@ class SaveCommand extends VanillaCommand{ return true; } - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::POCKETMINE_SAVE_START)); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_save_start()); $start = microtime(true); foreach($sender->getServer()->getOnlinePlayers() as $player){ @@ -58,7 +58,7 @@ class SaveCommand extends VanillaCommand{ $world->save(true); } - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::POCKETMINE_SAVE_SUCCESS, [round(microtime(true) - $start, 3)])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_save_success((string) round(microtime(true) - $start, 3))); return true; } diff --git a/src/command/defaults/SaveOffCommand.php b/src/command/defaults/SaveOffCommand.php index b64fec44eb..6d85082496 100644 --- a/src/command/defaults/SaveOffCommand.php +++ b/src/command/defaults/SaveOffCommand.php @@ -25,8 +25,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; class SaveOffCommand extends VanillaCommand{ @@ -47,7 +47,7 @@ class SaveOffCommand extends VanillaCommand{ $sender->getServer()->getWorldManager()->setAutoSave(false); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_SAVE_DISABLED)); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_save_disabled()); return true; } diff --git a/src/command/defaults/SaveOnCommand.php b/src/command/defaults/SaveOnCommand.php index d19e3a3cc9..b0d5ebf05c 100644 --- a/src/command/defaults/SaveOnCommand.php +++ b/src/command/defaults/SaveOnCommand.php @@ -25,8 +25,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; class SaveOnCommand extends VanillaCommand{ @@ -47,7 +47,7 @@ class SaveOnCommand extends VanillaCommand{ $sender->getServer()->getWorldManager()->setAutoSave(true); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_SAVE_ENABLED)); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_save_enabled()); return true; } diff --git a/src/command/defaults/SeedCommand.php b/src/command/defaults/SeedCommand.php index 078f5f2d5b..d154ff8916 100644 --- a/src/command/defaults/SeedCommand.php +++ b/src/command/defaults/SeedCommand.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -50,7 +50,7 @@ class SeedCommand extends VanillaCommand{ }else{ $seed = $sender->getServer()->getWorldManager()->getDefaultWorld()->getSeed(); } - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_SEED_SUCCESS, [$seed])); + $sender->sendMessage(KnownTranslationFactory::commands_seed_success((string) $seed)); return true; } diff --git a/src/command/defaults/SetWorldSpawnCommand.php b/src/command/defaults/SetWorldSpawnCommand.php index 055795dbb7..2c6f145b14 100644 --- a/src/command/defaults/SetWorldSpawnCommand.php +++ b/src/command/defaults/SetWorldSpawnCommand.php @@ -26,8 +26,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -70,7 +70,7 @@ class SetWorldSpawnCommand extends VanillaCommand{ $world->setSpawnLocation($pos); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_SETWORLDSPAWN_SUCCESS, [round($pos->x, 2), round($pos->y, 2), round($pos->z, 2)])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_setworldspawn_success((string) round($pos->x, 2), (string) round($pos->y, 2), (string) round($pos->z, 2))); return true; } diff --git a/src/command/defaults/SpawnpointCommand.php b/src/command/defaults/SpawnpointCommand.php index bf5c91ec95..23cf0b82e3 100644 --- a/src/command/defaults/SpawnpointCommand.php +++ b/src/command/defaults/SpawnpointCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; @@ -79,7 +80,7 @@ class SpawnpointCommand extends VanillaCommand{ $z = $this->getRelativeDouble($pos->z, $sender, $args[3]); $target->setSpawn(new Position($x, $y, $z, $world)); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_SPAWNPOINT_SUCCESS, [$target->getName(), round($x, 2), round($y, 2), round($z, 2)])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_spawnpoint_success($target->getName(), (string) round($x, 2), (string) round($y, 2), (string) round($z, 2))); return true; }elseif(count($args) <= 1){ @@ -88,7 +89,7 @@ class SpawnpointCommand extends VanillaCommand{ $pos = Position::fromObject($cpos->floor(), $cpos->getWorld()); $target->setSpawn($pos); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_SPAWNPOINT_SUCCESS, [$target->getName(), round($pos->x, 2), round($pos->y, 2), round($pos->z, 2)])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_spawnpoint_success($target->getName(), (string) round($pos->x, 2), (string) round($pos->y, 2), (string) round($pos->z, 2))); return true; }else{ $sender->sendMessage(TextFormat::RED . "Please provide a player!"); diff --git a/src/command/defaults/StopCommand.php b/src/command/defaults/StopCommand.php index fe89c3af2d..edf2eb7e3c 100644 --- a/src/command/defaults/StopCommand.php +++ b/src/command/defaults/StopCommand.php @@ -25,8 +25,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; class StopCommand extends VanillaCommand{ @@ -45,7 +45,7 @@ class StopCommand extends VanillaCommand{ return true; } - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_STOP_START)); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_stop_start()); $sender->getServer()->shutdown(); diff --git a/src/command/defaults/TeleportCommand.php b/src/command/defaults/TeleportCommand.php index 4f9998b3d7..945036ebf9 100644 --- a/src/command/defaults/TeleportCommand.php +++ b/src/command/defaults/TeleportCommand.php @@ -27,8 +27,8 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\entity\Location; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\AssumptionFailedError; @@ -97,7 +97,7 @@ class TeleportCommand extends VanillaCommand{ } $subject->teleport($targetPlayer->getLocation()); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_TP_SUCCESS, [$subject->getName(), $targetPlayer->getName()])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_tp_success($subject->getName(), $targetPlayer->getName())); return true; case 3: @@ -117,12 +117,12 @@ class TeleportCommand extends VanillaCommand{ $targetLocation = new Location($x, $y, $z, $yaw, $pitch, $base->getWorld()); $subject->teleport($targetLocation); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_TP_SUCCESS_COORDINATES, [ + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_tp_success_coordinates( $subject->getName(), - round($targetLocation->x, 2), - round($targetLocation->y, 2), - round($targetLocation->z, 2) - ])); + (string) round($targetLocation->x, 2), + (string) round($targetLocation->y, 2), + (string) round($targetLocation->z, 2) + )); return true; default: throw new AssumptionFailedError("This branch should be unreachable (for now)"); diff --git a/src/command/defaults/TellCommand.php b/src/command/defaults/TellCommand.php index 589df12f3a..9b9ba5f8d4 100644 --- a/src/command/defaults/TellCommand.php +++ b/src/command/defaults/TellCommand.php @@ -26,6 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; @@ -68,9 +69,9 @@ class TellCommand extends VanillaCommand{ $sender->sendMessage(new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . "%" . KnownTranslationKeys::COMMANDS_MESSAGE_DISPLAY_OUTGOING, [$player->getDisplayName(), $message])); $name = $sender instanceof Player ? $sender->getDisplayName() : $sender->getName(); $player->sendMessage(new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . "%" . KnownTranslationKeys::COMMANDS_MESSAGE_DISPLAY_INCOMING, [$name, $message])); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_MESSAGE_DISPLAY_OUTGOING, [$player->getDisplayName(), $message]), false); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_message_display_outgoing($player->getDisplayName(), $message), false); }else{ - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); + $sender->sendMessage(KnownTranslationFactory::commands_generic_player_notFound()); } return true; diff --git a/src/command/defaults/TimeCommand.php b/src/command/defaults/TimeCommand.php index 8a1bf2b9e1..5978b7ec2c 100644 --- a/src/command/defaults/TimeCommand.php +++ b/src/command/defaults/TimeCommand.php @@ -26,8 +26,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\world\World; @@ -86,7 +86,7 @@ class TimeCommand extends VanillaCommand{ }else{ $world = $sender->getServer()->getWorldManager()->getDefaultWorld(); } - $sender->sendMessage($sender->getLanguage()->translateString(KnownTranslationKeys::COMMANDS_TIME_QUERY, [$world->getTime()])); + $sender->sendMessage($sender->getLanguage()->translate(KnownTranslationFactory::commands_time_query((string) $world->getTime()))); return true; } @@ -126,7 +126,7 @@ class TimeCommand extends VanillaCommand{ foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){ $world->setTime($value); } - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_TIME_SET, [$value])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_time_set((string) $value)); }elseif($args[0] === "add"){ if(!$this->testPermission($sender, DefaultPermissionNames::COMMAND_TIME_ADD)){ return true; @@ -136,7 +136,7 @@ class TimeCommand extends VanillaCommand{ foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){ $world->setTime($world->getTime() + $value); } - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_TIME_ADDED, [$value])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_time_added((string) $value)); }else{ throw new InvalidCommandSyntaxException(); } diff --git a/src/command/defaults/TimingsCommand.php b/src/command/defaults/TimingsCommand.php index de501ad993..68350b56a0 100644 --- a/src/command/defaults/TimingsCommand.php +++ b/src/command/defaults/TimingsCommand.php @@ -26,8 +26,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\scheduler\BulkCurlTask; @@ -79,21 +79,21 @@ class TimingsCommand extends VanillaCommand{ if($mode === "on"){ if(TimingsHandler::isEnabled()){ - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_ALREADYENABLED)); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_timings_alreadyEnabled()); return true; } TimingsHandler::setEnabled(); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_ENABLE)); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_enable()); return true; }elseif($mode === "off"){ TimingsHandler::setEnabled(false); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_DISABLE)); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_disable()); return true; } if(!TimingsHandler::isEnabled()){ - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSDISABLED)); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_timings_timingsDisabled()); return true; } @@ -102,7 +102,7 @@ class TimingsCommand extends VanillaCommand{ if($mode === "reset"){ TimingsHandler::reload(); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_RESET)); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_reset()); }elseif($mode === "merged" or $mode === "report" or $paste){ $timings = ""; if($paste){ @@ -164,16 +164,16 @@ class TimingsCommand extends VanillaCommand{ } $response = json_decode($result->getBody(), true); if(is_array($response) && isset($response["id"])){ - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSREAD, - ["https://" . $host . "/?id=" . $response["id"]])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_timingsRead( + "https://" . $host . "/?id=" . $response["id"])); }else{ - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_PASTEERROR)); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_pasteError()); } } )); }else{ fclose($fileTimings); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSWRITE, [$timings])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::pocketmine_command_timings_timingsWrite($timings)); } }else{ throw new InvalidCommandSyntaxException(); diff --git a/src/command/defaults/TitleCommand.php b/src/command/defaults/TitleCommand.php index 86a5723c3e..62b80e4223 100644 --- a/src/command/defaults/TitleCommand.php +++ b/src/command/defaults/TitleCommand.php @@ -25,8 +25,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use function array_slice; use function count; @@ -54,7 +54,7 @@ class TitleCommand extends VanillaCommand{ $player = $sender->getServer()->getPlayerByPrefix($args[0]); if($player === null){ - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); + $sender->sendMessage(KnownTranslationFactory::commands_generic_player_notFound()); return true; } @@ -97,7 +97,7 @@ class TitleCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_TITLE_SUCCESS)); + $sender->sendMessage(KnownTranslationFactory::commands_title_success()); return true; } diff --git a/src/command/defaults/VersionCommand.php b/src/command/defaults/VersionCommand.php index b099ed8e41..9b86160715 100644 --- a/src/command/defaults/VersionCommand.php +++ b/src/command/defaults/VersionCommand.php @@ -24,8 +24,8 @@ declare(strict_types=1); namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\permission\DefaultPermissionNames; use pocketmine\plugin\Plugin; @@ -53,12 +53,12 @@ class VersionCommand extends VanillaCommand{ } if(count($args) === 0){ - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_INFO_EXTENDED, [ + $sender->sendMessage(KnownTranslationFactory::pocketmine_server_info_extended( $sender->getServer()->getName(), $sender->getServer()->getPocketMineVersion(), $sender->getServer()->getVersion(), - ProtocolInfo::CURRENT_PROTOCOL - ])); + (string) ProtocolInfo::CURRENT_PROTOCOL + )); }else{ $pluginName = implode(" ", $args); $exactPlugin = $sender->getServer()->getPluginManager()->getPlugin($pluginName); @@ -79,7 +79,7 @@ class VersionCommand extends VanillaCommand{ } if(!$found){ - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_NOSUCHPLUGIN)); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_noSuchPlugin()); } } diff --git a/src/command/defaults/WhitelistCommand.php b/src/command/defaults/WhitelistCommand.php index 8144459b7f..afbcb3e381 100644 --- a/src/command/defaults/WhitelistCommand.php +++ b/src/command/defaults/WhitelistCommand.php @@ -26,8 +26,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use function count; @@ -64,21 +64,21 @@ class WhitelistCommand extends VanillaCommand{ case "reload": if($this->testPermission($sender, DefaultPermissionNames::COMMAND_WHITELIST_RELOAD)){ $sender->getServer()->getWhitelisted()->reload(); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_RELOADED)); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_whitelist_reloaded()); } return true; case "on": if($this->testPermission($sender, DefaultPermissionNames::COMMAND_WHITELIST_ENABLE)){ $sender->getServer()->getConfigGroup()->setConfigBool("white-list", true); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_ENABLED)); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_whitelist_enabled()); } return true; case "off": if($this->testPermission($sender, DefaultPermissionNames::COMMAND_WHITELIST_DISABLE)){ $sender->getServer()->getConfigGroup()->setConfigBool("white-list", false); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_DISABLED)); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_whitelist_disabled()); } return true; @@ -87,20 +87,20 @@ class WhitelistCommand extends VanillaCommand{ $entries = $sender->getServer()->getWhitelisted()->getAll(true); sort($entries, SORT_STRING); $result = implode(", ", $entries); - $count = count($entries); + $count = (string) count($entries); - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_LIST, [$count, $count])); + $sender->sendMessage(KnownTranslationFactory::commands_whitelist_list($count, $count)); $sender->sendMessage($result); } return true; case "add": - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_USAGE, ["%" . KnownTranslationKeys::COMMANDS_WHITELIST_ADD_USAGE])); + $sender->sendMessage(KnownTranslationFactory::commands_generic_usage("%" . KnownTranslationKeys::COMMANDS_WHITELIST_ADD_USAGE)); return true; case "remove": - $sender->sendMessage(new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_USAGE, ["%" . KnownTranslationKeys::COMMANDS_WHITELIST_REMOVE_USAGE])); + $sender->sendMessage(KnownTranslationFactory::commands_generic_usage("%" . KnownTranslationKeys::COMMANDS_WHITELIST_REMOVE_USAGE)); return true; } }elseif(count($args) === 2){ @@ -111,14 +111,14 @@ class WhitelistCommand extends VanillaCommand{ case "add": if($this->testPermission($sender, DefaultPermissionNames::COMMAND_WHITELIST_ADD)){ $sender->getServer()->addWhitelist($args[1]); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_ADD_SUCCESS, [$args[1]])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_whitelist_add_success($args[1])); } return true; case "remove": if($this->testPermission($sender, DefaultPermissionNames::COMMAND_WHITELIST_REMOVE)){ $sender->getServer()->removeWhitelist($args[1]); - Command::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_REMOVE_SUCCESS, [$args[1]])); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_whitelist_remove_success($args[1])); } return true; diff --git a/src/event/player/PlayerDeathEvent.php b/src/event/player/PlayerDeathEvent.php index c33f3ee0de..0886a36520 100644 --- a/src/event/player/PlayerDeathEvent.php +++ b/src/event/player/PlayerDeathEvent.php @@ -30,7 +30,7 @@ use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDeathEvent; use pocketmine\item\Item; -use pocketmine\lang\KnownTranslationKeys; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\TranslationContainer; use pocketmine\player\Player; @@ -89,23 +89,14 @@ class PlayerDeathEvent extends EntityDeathEvent{ * Returns the vanilla death message for the given death cause. */ public static function deriveMessage(string $name, ?EntityDamageEvent $deathCause) : TranslationContainer{ - $message = KnownTranslationKeys::DEATH_ATTACK_GENERIC; - $params = [$name]; - switch($deathCause === null ? EntityDamageEvent::CAUSE_CUSTOM : $deathCause->getCause()){ case EntityDamageEvent::CAUSE_ENTITY_ATTACK: if($deathCause instanceof EntityDamageByEntityEvent){ $e = $deathCause->getDamager(); if($e instanceof Player){ - $message = KnownTranslationKeys::DEATH_ATTACK_PLAYER; - $params[] = $e->getDisplayName(); - break; + return KnownTranslationFactory::death_attack_player($name, $e->getDisplayName()); }elseif($e instanceof Living){ - $message = KnownTranslationKeys::DEATH_ATTACK_MOB; - $params[] = $e->getNameTag() !== "" ? $e->getNameTag() : $e->getName(); - break; - }else{ - $params[] = "Unknown"; + return KnownTranslationFactory::death_attack_mob($name, $e->getNameTag() !== "" ? $e->getNameTag() : $e->getName()); } } break; @@ -113,57 +104,41 @@ class PlayerDeathEvent extends EntityDeathEvent{ if($deathCause instanceof EntityDamageByEntityEvent){ $e = $deathCause->getDamager(); if($e instanceof Player){ - $message = KnownTranslationKeys::DEATH_ATTACK_ARROW; - $params[] = $e->getDisplayName(); + return KnownTranslationFactory::death_attack_arrow($name, $e->getDisplayName()); }elseif($e instanceof Living){ - $message = KnownTranslationKeys::DEATH_ATTACK_ARROW; - $params[] = $e->getNameTag() !== "" ? $e->getNameTag() : $e->getName(); - break; - }else{ - $params[] = "Unknown"; + return KnownTranslationFactory::death_attack_arrow($name, $e->getNameTag() !== "" ? $e->getNameTag() : $e->getName()); } } break; case EntityDamageEvent::CAUSE_SUICIDE: - $message = KnownTranslationKeys::DEATH_ATTACK_GENERIC; - break; + return KnownTranslationFactory::death_attack_generic($name); case EntityDamageEvent::CAUSE_VOID: - $message = KnownTranslationKeys::DEATH_ATTACK_OUTOFWORLD; - break; + return KnownTranslationFactory::death_attack_outOfWorld($name); case EntityDamageEvent::CAUSE_FALL: - if($deathCause instanceof EntityDamageEvent){ - if($deathCause->getFinalDamage() > 2){ - $message = KnownTranslationKeys::DEATH_FELL_ACCIDENT_GENERIC; - break; - } + if($deathCause instanceof EntityDamageEvent && $deathCause->getFinalDamage() > 2){ + return KnownTranslationFactory::death_fell_accident_generic($name); } - $message = KnownTranslationKeys::DEATH_ATTACK_FALL; - break; + return KnownTranslationFactory::death_attack_fall($name); case EntityDamageEvent::CAUSE_SUFFOCATION: - $message = KnownTranslationKeys::DEATH_ATTACK_INWALL; - break; + return KnownTranslationFactory::death_attack_inWall($name); case EntityDamageEvent::CAUSE_LAVA: - $message = KnownTranslationKeys::DEATH_ATTACK_LAVA; - break; + return KnownTranslationFactory::death_attack_lava($name); case EntityDamageEvent::CAUSE_FIRE: - $message = KnownTranslationKeys::DEATH_ATTACK_ONFIRE; - break; + return KnownTranslationFactory::death_attack_onFire($name); case EntityDamageEvent::CAUSE_FIRE_TICK: - $message = KnownTranslationKeys::DEATH_ATTACK_INFIRE; - break; + return KnownTranslationFactory::death_attack_inFire($name); case EntityDamageEvent::CAUSE_DROWNING: - $message = KnownTranslationKeys::DEATH_ATTACK_DROWN; - break; + return KnownTranslationFactory::death_attack_drown($name); case EntityDamageEvent::CAUSE_CONTACT: if($deathCause instanceof EntityDamageByBlockEvent){ if($deathCause->getDamager()->getId() === BlockLegacyIds::CACTUS){ - $message = KnownTranslationKeys::DEATH_ATTACK_CACTUS; + return KnownTranslationFactory::death_attack_cactus($name); } } break; @@ -173,21 +148,15 @@ class PlayerDeathEvent extends EntityDeathEvent{ if($deathCause instanceof EntityDamageByEntityEvent){ $e = $deathCause->getDamager(); if($e instanceof Player){ - $message = KnownTranslationKeys::DEATH_ATTACK_EXPLOSION_PLAYER; - $params[] = $e->getDisplayName(); + return KnownTranslationFactory::death_attack_explosion_player($name, $e->getDisplayName()); }elseif($e instanceof Living){ - $message = KnownTranslationKeys::DEATH_ATTACK_EXPLOSION_PLAYER; - $params[] = $e->getNameTag() !== "" ? $e->getNameTag() : $e->getName(); - break; + return KnownTranslationFactory::death_attack_explosion_player($name, $e->getNameTag() !== "" ? $e->getNameTag() : $e->getName()); } - }else{ - $message = KnownTranslationKeys::DEATH_ATTACK_EXPLOSION; } - break; + return KnownTranslationFactory::death_attack_explosion($name); case EntityDamageEvent::CAUSE_MAGIC: - $message = KnownTranslationKeys::DEATH_ATTACK_MAGIC; - break; + return KnownTranslationFactory::death_attack_magic($name); case EntityDamageEvent::CAUSE_CUSTOM: break; @@ -196,6 +165,6 @@ class PlayerDeathEvent extends EntityDeathEvent{ break; } - return new TranslationContainer($message, $params); + return KnownTranslationFactory::death_attack_generic($name); } } diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php new file mode 100644 index 0000000000..77f2ca2017 --- /dev/null +++ b/src/lang/KnownTranslationFactory.php @@ -0,0 +1,1744 @@ + $param0, + 1 => $param1, + ]); + } + + public static function chat_type_admin(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::CHAT_TYPE_ADMIN, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function chat_type_announcement(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::CHAT_TYPE_ANNOUNCEMENT, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function chat_type_emote(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::CHAT_TYPE_EMOTE, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function chat_type_text(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::CHAT_TYPE_TEXT, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function commands_ban_success(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_BAN_SUCCESS, [ + 0 => $param0, + ]); + } + + public static function commands_ban_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_BAN_USAGE, []); + } + + public static function commands_banip_invalid() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANIP_INVALID, []); + } + + public static function commands_banip_success(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANIP_SUCCESS, [ + 0 => $param0, + ]); + } + + public static function commands_banip_success_players(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANIP_SUCCESS_PLAYERS, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function commands_banip_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANIP_USAGE, []); + } + + public static function commands_banlist_ips(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANLIST_IPS, [ + 0 => $param0, + ]); + } + + public static function commands_banlist_players(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANLIST_PLAYERS, [ + 0 => $param0, + ]); + } + + public static function commands_banlist_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANLIST_USAGE, []); + } + + public static function commands_clear_failure_no_items(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_CLEAR_FAILURE_NO_ITEMS, [ + 0 => $param0, + ]); + } + + public static function commands_clear_success(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_CLEAR_SUCCESS, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function commands_clear_testing(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_CLEAR_TESTING, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function commands_defaultgamemode_success(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_DEFAULTGAMEMODE_SUCCESS, [ + 0 => $param0, + ]); + } + + public static function commands_defaultgamemode_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_DEFAULTGAMEMODE_USAGE, []); + } + + public static function commands_deop_success(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_DEOP_SUCCESS, [ + 0 => $param0, + ]); + } + + public static function commands_deop_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_DEOP_USAGE, []); + } + + public static function commands_difficulty_success(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_DIFFICULTY_SUCCESS, [ + 0 => $param0, + ]); + } + + public static function commands_difficulty_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_DIFFICULTY_USAGE, []); + } + + public static function commands_effect_failure_notActive(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_FAILURE_NOTACTIVE, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function commands_effect_failure_notActive_all(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_FAILURE_NOTACTIVE_ALL, [ + 0 => $param0, + ]); + } + + public static function commands_effect_notFound(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_NOTFOUND, [ + 0 => $param0, + ]); + } + + public static function commands_effect_success(string $param0, string $param1, string $param2, string $param3) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_SUCCESS, [ + 0 => $param0, + 1 => $param1, + 2 => $param2, + 3 => $param3, + ]); + } + + public static function commands_effect_success_removed(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_SUCCESS_REMOVED, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function commands_effect_success_removed_all(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_SUCCESS_REMOVED_ALL, [ + 0 => $param0, + ]); + } + + public static function commands_effect_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_USAGE, []); + } + + public static function commands_enchant_noItem() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_ENCHANT_NOITEM, []); + } + + public static function commands_enchant_notFound(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_ENCHANT_NOTFOUND, [ + 0 => $param0, + ]); + } + + public static function commands_enchant_success() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_ENCHANT_SUCCESS, []); + } + + public static function commands_enchant_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_ENCHANT_USAGE, []); + } + + public static function commands_gamemode_success_other(string $param1, string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_GAMEMODE_SUCCESS_OTHER, [ + 1 => $param1, + 0 => $param0, + ]); + } + + public static function commands_gamemode_success_self(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_GAMEMODE_SUCCESS_SELF, [ + 0 => $param0, + ]); + } + + public static function commands_gamemode_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_GAMEMODE_USAGE, []); + } + + public static function commands_generic_notFound() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_NOTFOUND, []); + } + + public static function commands_generic_num_tooBig(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_NUM_TOOBIG, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function commands_generic_num_tooSmall(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_NUM_TOOSMALL, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function commands_generic_permission() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION, []); + } + + public static function commands_generic_player_notFound() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND, []); + } + + public static function commands_generic_usage(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_USAGE, [ + 0 => $param0, + ]); + } + + public static function commands_give_item_notFound(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_GIVE_ITEM_NOTFOUND, [ + 0 => $param0, + ]); + } + + public static function commands_give_success(string $param0, string $param1, string $param2) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_GIVE_SUCCESS, [ + 0 => $param0, + 1 => $param1, + 2 => $param2, + ]); + } + + public static function commands_give_tagError(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_GIVE_TAGERROR, [ + 0 => $param0, + ]); + } + + public static function commands_help_header(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_HELP_HEADER, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function commands_help_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_HELP_USAGE, []); + } + + public static function commands_kick_success(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_KICK_SUCCESS, [ + 0 => $param0, + ]); + } + + public static function commands_kick_success_reason(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_KICK_SUCCESS_REASON, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function commands_kick_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_KICK_USAGE, []); + } + + public static function commands_kill_successful(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_KILL_SUCCESSFUL, [ + 0 => $param0, + ]); + } + + public static function commands_me_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_ME_USAGE, []); + } + + public static function commands_message_display_incoming(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_MESSAGE_DISPLAY_INCOMING, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function commands_message_display_outgoing(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_MESSAGE_DISPLAY_OUTGOING, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function commands_message_sameTarget() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_MESSAGE_SAMETARGET, []); + } + + public static function commands_message_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_MESSAGE_USAGE, []); + } + + public static function commands_op_success(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_OP_SUCCESS, [ + 0 => $param0, + ]); + } + + public static function commands_op_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_OP_USAGE, []); + } + + public static function commands_particle_notFound(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_PARTICLE_NOTFOUND, [ + 0 => $param0, + ]); + } + + public static function commands_particle_success(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_PARTICLE_SUCCESS, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function commands_players_list(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_PLAYERS_LIST, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function commands_players_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_PLAYERS_USAGE, []); + } + + public static function commands_save_off_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_SAVE_OFF_USAGE, []); + } + + public static function commands_save_on_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_SAVE_ON_USAGE, []); + } + + public static function commands_save_disabled() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_SAVE_DISABLED, []); + } + + public static function commands_save_enabled() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_SAVE_ENABLED, []); + } + + public static function commands_save_start() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_SAVE_START, []); + } + + public static function commands_save_success() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_SAVE_SUCCESS, []); + } + + public static function commands_save_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_SAVE_USAGE, []); + } + + public static function commands_say_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_SAY_USAGE, []); + } + + public static function commands_seed_success(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_SEED_SUCCESS, [ + 0 => $param0, + ]); + } + + public static function commands_seed_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_SEED_USAGE, []); + } + + public static function commands_setworldspawn_success(string $param0, string $param1, string $param2) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_SETWORLDSPAWN_SUCCESS, [ + 0 => $param0, + 1 => $param1, + 2 => $param2, + ]); + } + + public static function commands_setworldspawn_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_SETWORLDSPAWN_USAGE, []); + } + + public static function commands_spawnpoint_success(string $param0, string $param1, string $param2, string $param3) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_SPAWNPOINT_SUCCESS, [ + 0 => $param0, + 1 => $param1, + 2 => $param2, + 3 => $param3, + ]); + } + + public static function commands_spawnpoint_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_SPAWNPOINT_USAGE, []); + } + + public static function commands_stop_start() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_STOP_START, []); + } + + public static function commands_stop_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_STOP_USAGE, []); + } + + public static function commands_time_added(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_TIME_ADDED, [ + 0 => $param0, + ]); + } + + public static function commands_time_query(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_TIME_QUERY, [ + 0 => $param0, + ]); + } + + public static function commands_time_set(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_TIME_SET, [ + 0 => $param0, + ]); + } + + public static function commands_title_success() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_TITLE_SUCCESS, []); + } + + public static function commands_title_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_TITLE_USAGE, []); + } + + public static function commands_tp_success(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_TP_SUCCESS, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function commands_tp_success_coordinates(string $param0, string $param1, string $param2, string $param3) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_TP_SUCCESS_COORDINATES, [ + 0 => $param0, + 1 => $param1, + 2 => $param2, + 3 => $param3, + ]); + } + + public static function commands_tp_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_TP_USAGE, []); + } + + public static function commands_unban_success(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_UNBAN_SUCCESS, [ + 0 => $param0, + ]); + } + + public static function commands_unban_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_UNBAN_USAGE, []); + } + + public static function commands_unbanip_invalid() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_UNBANIP_INVALID, []); + } + + public static function commands_unbanip_success(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_UNBANIP_SUCCESS, [ + 0 => $param0, + ]); + } + + public static function commands_unbanip_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_UNBANIP_USAGE, []); + } + + public static function commands_whitelist_add_success(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_ADD_SUCCESS, [ + 0 => $param0, + ]); + } + + public static function commands_whitelist_add_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_ADD_USAGE, []); + } + + public static function commands_whitelist_disabled() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_DISABLED, []); + } + + public static function commands_whitelist_enabled() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_ENABLED, []); + } + + public static function commands_whitelist_list(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_LIST, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function commands_whitelist_reloaded() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_RELOADED, []); + } + + public static function commands_whitelist_remove_success(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_REMOVE_SUCCESS, [ + 0 => $param0, + ]); + } + + public static function commands_whitelist_remove_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_REMOVE_USAGE, []); + } + + public static function commands_whitelist_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_USAGE, []); + } + + public static function death_attack_arrow(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_ARROW, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function death_attack_arrow_item(string $param0, string $param1, string $param2) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_ARROW_ITEM, [ + 0 => $param0, + 1 => $param1, + 2 => $param2, + ]); + } + + public static function death_attack_cactus(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_CACTUS, [ + 0 => $param0, + ]); + } + + public static function death_attack_drown(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_DROWN, [ + 0 => $param0, + ]); + } + + public static function death_attack_explosion(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_EXPLOSION, [ + 0 => $param0, + ]); + } + + public static function death_attack_explosion_player(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_EXPLOSION_PLAYER, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function death_attack_fall(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_FALL, [ + 0 => $param0, + ]); + } + + public static function death_attack_generic(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_GENERIC, [ + 0 => $param0, + ]); + } + + public static function death_attack_inFire(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_INFIRE, [ + 0 => $param0, + ]); + } + + public static function death_attack_inWall(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_INWALL, [ + 0 => $param0, + ]); + } + + public static function death_attack_lava(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_LAVA, [ + 0 => $param0, + ]); + } + + public static function death_attack_magic(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_MAGIC, [ + 0 => $param0, + ]); + } + + public static function death_attack_mob(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_MOB, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function death_attack_onFire(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_ONFIRE, [ + 0 => $param0, + ]); + } + + public static function death_attack_outOfWorld(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_OUTOFWORLD, [ + 0 => $param0, + ]); + } + + public static function death_attack_player(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_PLAYER, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function death_attack_player_item(string $param0, string $param1, string $param2) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_PLAYER_ITEM, [ + 0 => $param0, + 1 => $param1, + 2 => $param2, + ]); + } + + public static function death_attack_wither(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_WITHER, [ + 0 => $param0, + ]); + } + + public static function death_fell_accident_generic(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEATH_FELL_ACCIDENT_GENERIC, [ + 0 => $param0, + ]); + } + + public static function default_gamemode() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEFAULT_GAMEMODE, []); + } + + public static function default_values_info() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DEFAULT_VALUES_INFO, []); + } + + public static function disconnectionScreen_invalidName() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DISCONNECTIONSCREEN_INVALIDNAME, []); + } + + public static function disconnectionScreen_invalidSkin() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DISCONNECTIONSCREEN_INVALIDSKIN, []); + } + + public static function disconnectionScreen_noReason() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DISCONNECTIONSCREEN_NOREASON, []); + } + + public static function disconnectionScreen_notAuthenticated() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DISCONNECTIONSCREEN_NOTAUTHENTICATED, []); + } + + public static function disconnectionScreen_outdatedClient() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DISCONNECTIONSCREEN_OUTDATEDCLIENT, []); + } + + public static function disconnectionScreen_outdatedServer() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DISCONNECTIONSCREEN_OUTDATEDSERVER, []); + } + + public static function disconnectionScreen_resourcePack() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DISCONNECTIONSCREEN_RESOURCEPACK, []); + } + + public static function disconnectionScreen_serverFull() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::DISCONNECTIONSCREEN_SERVERFULL, []); + } + + public static function gameMode_adventure() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::GAMEMODE_ADVENTURE, []); + } + + public static function gameMode_changed() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::GAMEMODE_CHANGED, []); + } + + public static function gameMode_creative() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::GAMEMODE_CREATIVE, []); + } + + public static function gameMode_spectator() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::GAMEMODE_SPECTATOR, []); + } + + public static function gameMode_survival() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::GAMEMODE_SURVIVAL, []); + } + + public static function gamemode_info() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::GAMEMODE_INFO, []); + } + + public static function invalid_port() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::INVALID_PORT, []); + } + + public static function ip_confirm() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::IP_CONFIRM, []); + } + + public static function ip_get() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::IP_GET, []); + } + + public static function ip_warning(string $EXTERNAL_IP, string $INTERNAL_IP) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::IP_WARNING, [ + "EXTERNAL_IP" => $EXTERNAL_IP, + "INTERNAL_IP" => $INTERNAL_IP, + ]); + } + + public static function kick_admin() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::KICK_ADMIN, []); + } + + public static function kick_admin_reason(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::KICK_ADMIN_REASON, [ + 0 => $param0, + ]); + } + + public static function kick_reason_cheat(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::KICK_REASON_CHEAT, [ + 0 => $param0, + ]); + } + + public static function language_name() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::LANGUAGE_NAME, []); + } + + public static function language_selected(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::LANGUAGE_SELECTED, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function language_has_been_selected() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::LANGUAGE_HAS_BEEN_SELECTED, []); + } + + public static function max_players() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::MAX_PLAYERS, []); + } + + public static function multiplayer_player_joined(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::MULTIPLAYER_PLAYER_JOINED, [ + 0 => $param0, + ]); + } + + public static function multiplayer_player_left(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::MULTIPLAYER_PLAYER_LEFT, [ + 0 => $param0, + ]); + } + + public static function name_your_server() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::NAME_YOUR_SERVER, []); + } + + public static function op_info() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::OP_INFO, []); + } + + public static function op_warning() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::OP_WARNING, []); + } + + public static function op_who() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::OP_WHO, []); + } + + public static function pocketmine_command_alias_illegal(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_ALIAS_ILLEGAL, [ + 0 => $param0, + ]); + } + + public static function pocketmine_command_alias_notFound(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_ALIAS_NOTFOUND, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function pocketmine_command_alias_recursive(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_ALIAS_RECURSIVE, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function pocketmine_command_ban_ip_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_BAN_IP_DESCRIPTION, []); + } + + public static function pocketmine_command_ban_player_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_BAN_PLAYER_DESCRIPTION, []); + } + + public static function pocketmine_command_banlist_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_BANLIST_DESCRIPTION, []); + } + + public static function pocketmine_command_clear_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_CLEAR_DESCRIPTION, []); + } + + public static function pocketmine_command_clear_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_CLEAR_USAGE, []); + } + + public static function pocketmine_command_defaultgamemode_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_DEFAULTGAMEMODE_DESCRIPTION, []); + } + + public static function pocketmine_command_deop_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_DEOP_DESCRIPTION, []); + } + + public static function pocketmine_command_difficulty_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_DIFFICULTY_DESCRIPTION, []); + } + + public static function pocketmine_command_effect_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_EFFECT_DESCRIPTION, []); + } + + public static function pocketmine_command_enchant_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_ENCHANT_DESCRIPTION, []); + } + + public static function pocketmine_command_exception(string $param0, string $param1, string $param2) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_EXCEPTION, [ + 0 => $param0, + 1 => $param1, + 2 => $param2, + ]); + } + + public static function pocketmine_command_gamemode_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_GAMEMODE_DESCRIPTION, []); + } + + public static function pocketmine_command_gc_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_GC_DESCRIPTION, []); + } + + public static function pocketmine_command_gc_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_GC_USAGE, []); + } + + public static function pocketmine_command_give_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_GIVE_DESCRIPTION, []); + } + + public static function pocketmine_command_give_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_GIVE_USAGE, []); + } + + public static function pocketmine_command_help_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_HELP_DESCRIPTION, []); + } + + public static function pocketmine_command_kick_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_KICK_DESCRIPTION, []); + } + + public static function pocketmine_command_kill_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_KILL_DESCRIPTION, []); + } + + public static function pocketmine_command_kill_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_KILL_USAGE, []); + } + + public static function pocketmine_command_list_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_LIST_DESCRIPTION, []); + } + + public static function pocketmine_command_me_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_ME_DESCRIPTION, []); + } + + public static function pocketmine_command_op_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_OP_DESCRIPTION, []); + } + + public static function pocketmine_command_particle_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_PARTICLE_DESCRIPTION, []); + } + + public static function pocketmine_command_particle_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_PARTICLE_USAGE, []); + } + + public static function pocketmine_command_plugins_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_DESCRIPTION, []); + } + + public static function pocketmine_command_plugins_success(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_SUCCESS, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function pocketmine_command_plugins_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_USAGE, []); + } + + public static function pocketmine_command_save_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_SAVE_DESCRIPTION, []); + } + + public static function pocketmine_command_saveoff_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_SAVEOFF_DESCRIPTION, []); + } + + public static function pocketmine_command_saveon_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_SAVEON_DESCRIPTION, []); + } + + public static function pocketmine_command_say_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_SAY_DESCRIPTION, []); + } + + public static function pocketmine_command_seed_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_SEED_DESCRIPTION, []); + } + + public static function pocketmine_command_setworldspawn_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_SETWORLDSPAWN_DESCRIPTION, []); + } + + public static function pocketmine_command_spawnpoint_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_SPAWNPOINT_DESCRIPTION, []); + } + + public static function pocketmine_command_status_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_STATUS_DESCRIPTION, []); + } + + public static function pocketmine_command_status_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_STATUS_USAGE, []); + } + + public static function pocketmine_command_stop_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_STOP_DESCRIPTION, []); + } + + public static function pocketmine_command_tell_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TELL_DESCRIPTION, []); + } + + public static function pocketmine_command_time_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIME_DESCRIPTION, []); + } + + public static function pocketmine_command_time_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIME_USAGE, []); + } + + public static function pocketmine_command_timings_alreadyEnabled() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_ALREADYENABLED, []); + } + + public static function pocketmine_command_timings_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_DESCRIPTION, []); + } + + public static function pocketmine_command_timings_disable() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_DISABLE, []); + } + + public static function pocketmine_command_timings_enable() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_ENABLE, []); + } + + public static function pocketmine_command_timings_pasteError() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_PASTEERROR, []); + } + + public static function pocketmine_command_timings_reset() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_RESET, []); + } + + public static function pocketmine_command_timings_timingsDisabled() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSDISABLED, []); + } + + public static function pocketmine_command_timings_timingsRead(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSREAD, [ + 0 => $param0, + ]); + } + + public static function pocketmine_command_timings_timingsUpload(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSUPLOAD, [ + 0 => $param0, + ]); + } + + public static function pocketmine_command_timings_timingsWrite(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSWRITE, [ + 0 => $param0, + ]); + } + + public static function pocketmine_command_timings_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_USAGE, []); + } + + public static function pocketmine_command_title_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TITLE_DESCRIPTION, []); + } + + public static function pocketmine_command_tp_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TP_DESCRIPTION, []); + } + + public static function pocketmine_command_transferserver_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TRANSFERSERVER_DESCRIPTION, []); + } + + public static function pocketmine_command_transferserver_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TRANSFERSERVER_USAGE, []); + } + + public static function pocketmine_command_unban_ip_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_UNBAN_IP_DESCRIPTION, []); + } + + public static function pocketmine_command_unban_player_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_UNBAN_PLAYER_DESCRIPTION, []); + } + + public static function pocketmine_command_version_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_DESCRIPTION, []); + } + + public static function pocketmine_command_version_noSuchPlugin() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_NOSUCHPLUGIN, []); + } + + public static function pocketmine_command_version_usage() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_USAGE, []); + } + + public static function pocketmine_command_whitelist_description() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_WHITELIST_DESCRIPTION, []); + } + + public static function pocketmine_crash_archive(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_CRASH_ARCHIVE, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function pocketmine_crash_create() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_CRASH_CREATE, []); + } + + public static function pocketmine_crash_error(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_CRASH_ERROR, [ + 0 => $param0, + ]); + } + + public static function pocketmine_crash_submit(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_CRASH_SUBMIT, [ + 0 => $param0, + ]); + } + + public static function pocketmine_data_playerCorrupted(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DATA_PLAYERCORRUPTED, [ + 0 => $param0, + ]); + } + + public static function pocketmine_data_playerNotFound(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DATA_PLAYERNOTFOUND, [ + 0 => $param0, + ]); + } + + public static function pocketmine_data_playerOld(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DATA_PLAYEROLD, [ + 0 => $param0, + ]); + } + + public static function pocketmine_data_saveError(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DATA_SAVEERROR, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function pocketmine_debug_enable() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DEBUG_ENABLE, []); + } + + public static function pocketmine_disconnect_incompatibleProtocol(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DISCONNECT_INCOMPATIBLEPROTOCOL, [ + 0 => $param0, + ]); + } + + public static function pocketmine_disconnect_invalidSession(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION, [ + 0 => $param0, + ]); + } + + public static function pocketmine_disconnect_invalidSession_badSignature() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_BADSIGNATURE, []); + } + + public static function pocketmine_disconnect_invalidSession_missingKey() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_MISSINGKEY, []); + } + + public static function pocketmine_disconnect_invalidSession_tooEarly() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_TOOEARLY, []); + } + + public static function pocketmine_disconnect_invalidSession_tooLate() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_TOOLATE, []); + } + + public static function pocketmine_level_ambiguousFormat(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_AMBIGUOUSFORMAT, [ + 0 => $param0, + ]); + } + + public static function pocketmine_level_backgroundGeneration(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_BACKGROUNDGENERATION, [ + 0 => $param0, + ]); + } + + public static function pocketmine_level_badDefaultFormat(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_BADDEFAULTFORMAT, [ + 0 => $param0, + ]); + } + + public static function pocketmine_level_defaultError() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_DEFAULTERROR, []); + } + + public static function pocketmine_level_generationError(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_GENERATIONERROR, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function pocketmine_level_loadError(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_LOADERROR, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function pocketmine_level_notFound(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_NOTFOUND, [ + 0 => $param0, + ]); + } + + public static function pocketmine_level_preparing(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_PREPARING, [ + 0 => $param0, + ]); + } + + public static function pocketmine_level_unknownFormat() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_UNKNOWNFORMAT, []); + } + + public static function pocketmine_level_unloading(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_UNLOADING, [ + 0 => $param0, + ]); + } + + public static function pocketmine_player_invalidEntity(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLAYER_INVALIDENTITY, [ + 0 => $param0, + ]); + } + + public static function pocketmine_player_invalidMove(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLAYER_INVALIDMOVE, [ + 0 => $param0, + ]); + } + + public static function pocketmine_player_logIn(string $param0, string $param1, string $param2, string $param3, string $param4, string $param5, string $param6, string $param7) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLAYER_LOGIN, [ + 0 => $param0, + 1 => $param1, + 2 => $param2, + 3 => $param3, + 4 => $param4, + 5 => $param5, + 6 => $param6, + 7 => $param7, + ]); + } + + public static function pocketmine_player_logOut(string $param0, string $param1, string $param2, string $param3) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLAYER_LOGOUT, [ + 0 => $param0, + 1 => $param1, + 2 => $param2, + 3 => $param3, + ]); + } + + public static function pocketmine_plugin_aliasError(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_ALIASERROR, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function pocketmine_plugin_ambiguousMinAPI(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_AMBIGUOUSMINAPI, [ + 0 => $param0, + ]); + } + + public static function pocketmine_plugin_circularDependency() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_CIRCULARDEPENDENCY, []); + } + + public static function pocketmine_plugin_commandError(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_COMMANDERROR, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function pocketmine_plugin_deprecatedEvent(string $param0, string $param1, string $param2) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_DEPRECATEDEVENT, [ + 0 => $param0, + 1 => $param1, + 2 => $param2, + ]); + } + + public static function pocketmine_plugin_disable(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_DISABLE, [ + 0 => $param0, + ]); + } + + public static function pocketmine_plugin_duplicateError(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_DUPLICATEERROR, [ + 0 => $param0, + ]); + } + + public static function pocketmine_plugin_enable(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_ENABLE, [ + 0 => $param0, + ]); + } + + public static function pocketmine_plugin_fileError(string $param0, string $param1, string $param2) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_FILEERROR, [ + 0 => $param0, + 1 => $param1, + 2 => $param2, + ]); + } + + public static function pocketmine_plugin_genericLoadError(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_GENERICLOADERROR, [ + 0 => $param0, + ]); + } + + public static function pocketmine_plugin_incompatibleAPI(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEAPI, [ + 0 => $param0, + ]); + } + + public static function pocketmine_plugin_incompatibleOS(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEOS, [ + 0 => $param0, + ]); + } + + public static function pocketmine_plugin_incompatiblePhpVersion(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEPHPVERSION, [ + 0 => $param0, + ]); + } + + public static function pocketmine_plugin_incompatibleProtocol(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEPROTOCOL, [ + 0 => $param0, + ]); + } + + public static function pocketmine_plugin_load(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_LOAD, [ + 0 => $param0, + ]); + } + + public static function pocketmine_plugin_loadError(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_LOADERROR, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function pocketmine_plugin_restrictedName() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_RESTRICTEDNAME, []); + } + + public static function pocketmine_plugin_spacesDiscouraged(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_SPACESDISCOURAGED, [ + 0 => $param0, + ]); + } + + public static function pocketmine_plugin_unknownDependency(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_UNKNOWNDEPENDENCY, [ + 0 => $param0, + ]); + } + + public static function pocketmine_save_start() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SAVE_START, []); + } + + public static function pocketmine_save_success(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SAVE_SUCCESS, [ + 0 => $param0, + ]); + } + + public static function pocketmine_server_auth_disabled() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_AUTH_DISABLED, []); + } + + public static function pocketmine_server_auth_enabled() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_AUTH_ENABLED, []); + } + + public static function pocketmine_server_authProperty_disabled() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_AUTHPROPERTY_DISABLED, []); + } + + public static function pocketmine_server_authProperty_enabled() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_AUTHPROPERTY_ENABLED, []); + } + + public static function pocketmine_server_authWarning() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_AUTHWARNING, []); + } + + public static function pocketmine_server_defaultGameMode(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEFAULTGAMEMODE, [ + 0 => $param0, + ]); + } + + public static function pocketmine_server_devBuild_error1(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR1, [ + 0 => $param0, + ]); + } + + public static function pocketmine_server_devBuild_error2() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR2, []); + } + + public static function pocketmine_server_devBuild_error3() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR3, []); + } + + public static function pocketmine_server_devBuild_error4(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR4, [ + 0 => $param0, + ]); + } + + public static function pocketmine_server_devBuild_error5(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR5, [ + 0 => $param0, + ]); + } + + public static function pocketmine_server_devBuild_warning1(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_WARNING1, [ + 0 => $param0, + ]); + } + + public static function pocketmine_server_devBuild_warning2() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_WARNING2, []); + } + + public static function pocketmine_server_devBuild_warning3() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_WARNING3, []); + } + + public static function pocketmine_server_donate(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DONATE, [ + 0 => $param0, + ]); + } + + public static function pocketmine_server_info(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_INFO, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function pocketmine_server_info_extended(string $param0, string $param1, string $param2, string $param3) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_INFO_EXTENDED, [ + 0 => $param0, + 1 => $param1, + 2 => $param2, + 3 => $param3, + ]); + } + + public static function pocketmine_server_license(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_LICENSE, [ + 0 => $param0, + ]); + } + + public static function pocketmine_server_networkStart(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_NETWORKSTART, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function pocketmine_server_query_running(string $param0, string $param1) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_QUERY_RUNNING, [ + 0 => $param0, + 1 => $param1, + ]); + } + + public static function pocketmine_server_start(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_START, [ + 0 => $param0, + ]); + } + + public static function pocketmine_server_startFinished(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_STARTFINISHED, [ + 0 => $param0, + ]); + } + + public static function pocketmine_server_tickOverload() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_TICKOVERLOAD, []); + } + + public static function pocketmine_plugins() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGINS, []); + } + + public static function pocketmine_will_start(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_WILL_START, [ + 0 => $param0, + ]); + } + + public static function port_warning() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::PORT_WARNING, []); + } + + public static function potion_absorption() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_ABSORPTION, []); + } + + public static function potion_blindness() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_BLINDNESS, []); + } + + public static function potion_conduitPower() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_CONDUITPOWER, []); + } + + public static function potion_confusion() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_CONFUSION, []); + } + + public static function potion_damageBoost() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_DAMAGEBOOST, []); + } + + public static function potion_digSlowDown() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_DIGSLOWDOWN, []); + } + + public static function potion_digSpeed() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_DIGSPEED, []); + } + + public static function potion_fireResistance() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_FIRERESISTANCE, []); + } + + public static function potion_harm() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_HARM, []); + } + + public static function potion_heal() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_HEAL, []); + } + + public static function potion_healthBoost() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_HEALTHBOOST, []); + } + + public static function potion_hunger() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_HUNGER, []); + } + + public static function potion_invisibility() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_INVISIBILITY, []); + } + + public static function potion_jump() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_JUMP, []); + } + + public static function potion_levitation() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_LEVITATION, []); + } + + public static function potion_moveSlowdown() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_MOVESLOWDOWN, []); + } + + public static function potion_moveSpeed() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_MOVESPEED, []); + } + + public static function potion_nightVision() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_NIGHTVISION, []); + } + + public static function potion_poison() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_POISON, []); + } + + public static function potion_regeneration() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_REGENERATION, []); + } + + public static function potion_resistance() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_RESISTANCE, []); + } + + public static function potion_saturation() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_SATURATION, []); + } + + public static function potion_waterBreathing() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_WATERBREATHING, []); + } + + public static function potion_weakness() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_WEAKNESS, []); + } + + public static function potion_wither() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POTION_WITHER, []); + } + + public static function query_disable() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::QUERY_DISABLE, []); + } + + public static function query_warning1() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::QUERY_WARNING1, []); + } + + public static function query_warning2() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::QUERY_WARNING2, []); + } + + public static function server_port() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::SERVER_PORT, []); + } + + public static function server_properties() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::SERVER_PROPERTIES, []); + } + + public static function setting_up_server_now() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::SETTING_UP_SERVER_NOW, []); + } + + public static function skip_installer() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::SKIP_INSTALLER, []); + } + + public static function tile_bed_noSleep() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::TILE_BED_NOSLEEP, []); + } + + public static function tile_bed_occupied() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::TILE_BED_OCCUPIED, []); + } + + public static function tile_bed_tooFar() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::TILE_BED_TOOFAR, []); + } + + public static function welcome_to_pocketmine(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::WELCOME_TO_POCKETMINE, [ + 0 => $param0, + ]); + } + + public static function whitelist_enable() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::WHITELIST_ENABLE, []); + } + + public static function whitelist_info() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::WHITELIST_INFO, []); + } + + public static function whitelist_warning() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::WHITELIST_WARNING, []); + } + + public static function you_have_finished() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::YOU_HAVE_FINISHED, []); + } + + public static function you_have_to_accept_the_license(string $param0) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::YOU_HAVE_TO_ACCEPT_THE_LICENSE, [ + 0 => $param0, + ]); + } + +} diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 06bd45eacb..946fbd92f5 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -33,7 +33,7 @@ use pocketmine\event\player\PlayerDuplicateLoginEvent; use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\event\server\DataPacketSendEvent; use pocketmine\form\Form; -use pocketmine\lang\KnownTranslationKeys; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\StringTag; @@ -581,7 +581,7 @@ class NetworkSession{ } if($error !== null){ - $this->disconnect($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION, [$error])); + $this->disconnect($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_disconnect_invalidSession($error))); return; } diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index 926e207403..25532f1721 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\handler; use pocketmine\entity\InvalidSkinException; use pocketmine\event\player\PlayerPreLoginEvent; -use pocketmine\lang\KnownTranslationKeys; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\network\mcpe\auth\ProcessLoginTask; use pocketmine\network\mcpe\convert\SkinAdapterSingleton; use pocketmine\network\mcpe\JwtException; @@ -83,7 +83,7 @@ class LoginPacketHandler extends PacketHandler{ //This pocketmine disconnect message will only be seen by the console (PlayStatusPacket causes the messages to be shown for the client) $this->session->disconnect( - $this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_DISCONNECT_INCOMPATIBLEPROTOCOL, [$packet->protocol]), + $this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_disconnect_incompatibleProtocol((string) $packet->protocol)), false ); diff --git a/src/network/query/QueryHandler.php b/src/network/query/QueryHandler.php index 101b47174b..1ec8a22773 100644 --- a/src/network/query/QueryHandler.php +++ b/src/network/query/QueryHandler.php @@ -27,7 +27,7 @@ declare(strict_types=1); */ namespace pocketmine\network\query; -use pocketmine\lang\KnownTranslationKeys; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\RawPacketHandler; use pocketmine\Server; @@ -71,7 +71,7 @@ class QueryHandler implements RawPacketHandler{ $this->regenerateToken(); $this->lastToken = $this->token; - $this->logger->info($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_SERVER_QUERY_RUNNING, [$addr, $port])); + $this->logger->info($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_query_running($addr, (string) $port))); } public function getPattern() : string{ diff --git a/src/player/Player.php b/src/player/Player.php index a8c0ad2911..d27726295f 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -80,6 +80,7 @@ use pocketmine\item\enchantment\MeleeWeaponEnchantment; use pocketmine\item\Item; use pocketmine\item\ItemUseResult; use pocketmine\item\Releasable; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\Language; use pocketmine\lang\TranslationContainer; @@ -276,16 +277,16 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return; } - $this->server->getLogger()->info($this->getServer()->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLAYER_LOGIN, [ + $this->server->getLogger()->info($this->getServer()->getLanguage()->translate(KnownTranslationFactory::pocketmine_player_logIn( TextFormat::AQUA . $this->username . TextFormat::WHITE, $session->getIp(), - $session->getPort(), - $this->id, + (string) $session->getPort(), + (string) $this->id, $this->getWorld()->getDisplayName(), - round($this->location->x, 4), - round($this->location->y, 4), - round($this->location->z, 4) - ])); + (string) round($this->location->x, 4), + (string) round($this->location->y, 4), + (string) round($this->location->z, 4) + ))); $this->server->addOnlinePlayer($this); } diff --git a/src/plugin/PluginBase.php b/src/plugin/PluginBase.php index e2beaeb0f2..ac7b0036f1 100644 --- a/src/plugin/PluginBase.php +++ b/src/plugin/PluginBase.php @@ -27,7 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandExecutor; use pocketmine\command\CommandSender; use pocketmine\command\PluginCommand; -use pocketmine\lang\KnownTranslationKeys; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\scheduler\TaskScheduler; use pocketmine\Server; use pocketmine\utils\AssumptionFailedError; @@ -168,7 +168,7 @@ abstract class PluginBase implements Plugin, CommandExecutor{ foreach($this->getDescription()->getCommands() as $key => $data){ if(strpos($key, ":") !== false){ - $this->logger->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_COMMANDERROR, [$key, $this->getDescription()->getFullName()])); + $this->logger->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_commandError($key, $this->getDescription()->getFullName()))); continue; } if(is_array($data)){ //TODO: error out if it isn't @@ -185,7 +185,7 @@ abstract class PluginBase implements Plugin, CommandExecutor{ $aliasList = []; foreach($data["aliases"] as $alias){ if(strpos($alias, ":") !== false){ - $this->logger->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_ALIASERROR, [$alias, $this->getDescription()->getFullName()])); + $this->logger->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_aliasError($alias, $this->getDescription()->getFullName()))); continue; } $aliasList[] = $alias; diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 08a01259b0..695a38ab78 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -31,6 +31,7 @@ use pocketmine\event\ListenerMethodTags; use pocketmine\event\plugin\PluginDisableEvent; use pocketmine\event\plugin\PluginEnableEvent; use pocketmine\event\RegisteredListener; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\permission\DefaultPermissions; @@ -135,7 +136,7 @@ class PluginManager{ if($loader->canLoadPlugin($path)){ $description = $loader->getPluginDescription($path); if($description instanceof PluginDescription){ - $this->server->getLogger()->info($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_LOAD, [$description->getFullName()])); + $this->server->getLogger()->info($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_load($description->getFullName()))); try{ $description->checkRequiredExtensions(); }catch(PluginException $ex){ @@ -246,7 +247,7 @@ class PluginManager{ try{ $description = $loader->getPluginDescription($file); }catch(\RuntimeException $e){ //TODO: more specific exception handling - $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_FILEERROR, [$file, $directory, $e->getMessage()])); + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_fileError($file, $directory, $e->getMessage()))); $this->server->getLogger()->logException($e); continue; } @@ -256,58 +257,58 @@ class PluginManager{ $name = $description->getName(); if(stripos($name, "pocketmine") !== false or stripos($name, "minecraft") !== false or stripos($name, "mojang") !== false){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_LOADERROR, [$name, "%" . KnownTranslationKeys::POCKETMINE_PLUGIN_RESTRICTEDNAME])); + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError($name, "%" . KnownTranslationKeys::POCKETMINE_PLUGIN_RESTRICTEDNAME))); continue; } if(strpos($name, " ") !== false){ - $this->server->getLogger()->warning($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_SPACESDISCOURAGED, [$name])); + $this->server->getLogger()->warning($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_spacesDiscouraged($name))); } if(isset($plugins[$name]) or $this->getPlugin($name) instanceof Plugin){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_DUPLICATEERROR, [$name])); + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_duplicateError($name))); continue; } if(!ApiVersion::isCompatible($this->server->getApiVersion(), $description->getCompatibleApis())){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_LOADERROR, [ + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( $name, - $this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEAPI, [implode(", ", $description->getCompatibleApis())]) - ])); + $this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_incompatibleAPI(implode(", ", $description->getCompatibleApis()))) + ))); continue; } $ambiguousVersions = ApiVersion::checkAmbiguousVersions($description->getCompatibleApis()); if(count($ambiguousVersions) > 0){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_LOADERROR, [ + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( $name, - $this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_AMBIGUOUSMINAPI, [implode(", ", $ambiguousVersions)]) - ])); + $this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_ambiguousMinAPI(implode(", ", $ambiguousVersions))) + ))); continue; } if(count($description->getCompatibleOperatingSystems()) > 0 and !in_array(Utils::getOS(), $description->getCompatibleOperatingSystems(), true)) { - $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_LOADERROR, [ + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( $name, - $this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEOS, [implode(", ", $description->getCompatibleOperatingSystems())]) - ])); + $this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_incompatibleOS(implode(", ", $description->getCompatibleOperatingSystems()))) + ))); continue; } if(count($pluginMcpeProtocols = $description->getCompatibleMcpeProtocols()) > 0){ $serverMcpeProtocols = [ProtocolInfo::CURRENT_PROTOCOL]; if(count(array_intersect($pluginMcpeProtocols, $serverMcpeProtocols)) === 0){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_LOADERROR, [ + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( $name, - $this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_DISCONNECT_INCOMPATIBLEPROTOCOL, [implode(", ", $pluginMcpeProtocols)]) - ])); + $this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_incompatibleProtocol(implode(", ", $pluginMcpeProtocols))) + ))); continue; } } if($this->graylist !== null and !$this->graylist->isAllowed($name)){ - $this->server->getLogger()->notice($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_LOADERROR, [ + $this->server->getLogger()->notice($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( $name, "Disallowed by graylist" - ])); + ))); continue; } $plugins[$name] = $file; @@ -333,10 +334,10 @@ class PluginManager{ if(isset($loadedPlugins[$dependency]) or $this->getPlugin($dependency) instanceof Plugin){ unset($dependencies[$name][$key]); }elseif(!isset($plugins[$dependency])){ - $this->server->getLogger()->critical($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_LOADERROR, [ + $this->server->getLogger()->critical($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( $name, - $this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_UNKNOWNDEPENDENCY, [$dependency]) - ])); + $this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_unknownDependency($dependency)) + ))); unset($plugins[$name]); continue 2; } @@ -372,7 +373,7 @@ class PluginManager{ if(($plugin = $this->loadPlugin($file, $loaders)) instanceof Plugin){ $loadedPlugins[$name] = $plugin; }else{ - $this->server->getLogger()->critical($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_GENERICLOADERROR, [$name])); + $this->server->getLogger()->critical($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_genericLoadError($name))); } } } @@ -380,7 +381,7 @@ class PluginManager{ if($loadedThisLoop === 0){ //No plugins loaded :( foreach($plugins as $name => $file){ - $this->server->getLogger()->critical($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_LOADERROR, [$name, "%" . KnownTranslationKeys::POCKETMINE_PLUGIN_CIRCULARDEPENDENCY])); + $this->server->getLogger()->critical($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError($name, "%" . KnownTranslationKeys::POCKETMINE_PLUGIN_CIRCULARDEPENDENCY))); } $plugins = []; } @@ -395,7 +396,7 @@ class PluginManager{ public function enablePlugin(Plugin $plugin) : void{ if(!$plugin->isEnabled()){ - $this->server->getLogger()->info($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_ENABLE, [$plugin->getDescription()->getFullName()])); + $this->server->getLogger()->info($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_enable($plugin->getDescription()->getFullName()))); $plugin->getScheduler()->setEnabled(true); $plugin->onEnableStateChange(true); @@ -414,7 +415,7 @@ class PluginManager{ public function disablePlugin(Plugin $plugin) : void{ if($plugin->isEnabled()){ - $this->server->getLogger()->info($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_PLUGIN_DISABLE, [$plugin->getDescription()->getFullName()])); + $this->server->getLogger()->info($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_disable($plugin->getDescription()->getFullName()))); (new PluginDisableEvent($plugin))->call(); unset($this->enabledPlugins[$plugin->getDescription()->getName()]); diff --git a/src/wizard/SetupWizard.php b/src/wizard/SetupWizard.php index 62d7d391ec..bb1b8de264 100644 --- a/src/wizard/SetupWizard.php +++ b/src/wizard/SetupWizard.php @@ -28,7 +28,7 @@ declare(strict_types=1); namespace pocketmine\wizard; use pocketmine\data\java\GameModeIdMap; -use pocketmine\lang\KnownTranslationKeys; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\Language; use pocketmine\lang\LanguageNotFoundException; use pocketmine\player\GameMode; @@ -83,7 +83,7 @@ class SetupWizard{ $this->lang = new Language($lang); - $this->message($this->lang->get(KnownTranslationKeys::LANGUAGE_HAS_BEEN_SELECTED)); + $this->message($this->lang->translate(KnownTranslationFactory::language_has_been_selected())); if(!$this->showLicense()){ return false; @@ -94,7 +94,7 @@ class SetupWizard{ $config->set("language", $lang); $config->save(); - if(strtolower($this->getInput($this->lang->get(KnownTranslationKeys::SKIP_INSTALLER), "n", "y/N")) === "y"){ + if(strtolower($this->getInput($this->lang->translate(KnownTranslationFactory::skip_installer()), "n", "y/N")) === "y"){ $this->printIpDetails(); return true; } @@ -113,7 +113,7 @@ class SetupWizard{ } private function showLicense() : bool{ - $this->message($this->lang->translateString(KnownTranslationKeys::WELCOME_TO_POCKETMINE, [VersionInfo::NAME])); + $this->message($this->lang->translate(KnownTranslationFactory::welcome_to_pocketmine(VersionInfo::NAME))); echo <<writeLine(); - if(strtolower($this->getInput($this->lang->get(KnownTranslationKeys::ACCEPT_LICENSE), "n", "y/N")) !== "y"){ - $this->error($this->lang->translateString(KnownTranslationKeys::YOU_HAVE_TO_ACCEPT_THE_LICENSE, [VersionInfo::NAME])); + if(strtolower($this->getInput($this->lang->translate(KnownTranslationFactory::accept_license()), "n", "y/N")) !== "y"){ + $this->error($this->lang->translate(KnownTranslationFactory::you_have_to_accept_the_license(VersionInfo::NAME))); sleep(5); return false; @@ -134,23 +134,23 @@ LICENSE; } private function welcome() : void{ - $this->message($this->lang->get(KnownTranslationKeys::SETTING_UP_SERVER_NOW)); - $this->message($this->lang->get(KnownTranslationKeys::DEFAULT_VALUES_INFO)); - $this->message($this->lang->get(KnownTranslationKeys::SERVER_PROPERTIES)); + $this->message($this->lang->translate(KnownTranslationFactory::setting_up_server_now())); + $this->message($this->lang->translate(KnownTranslationFactory::default_values_info())); + $this->message($this->lang->translate(KnownTranslationFactory::server_properties())); } private function generateBaseConfig() : void{ $config = new Config(Path::join($this->dataPath, "server.properties"), Config::PROPERTIES); - $config->set("motd", ($name = $this->getInput($this->lang->get(KnownTranslationKeys::NAME_YOUR_SERVER), self::DEFAULT_NAME))); + $config->set("motd", ($name = $this->getInput($this->lang->translate(KnownTranslationFactory::name_your_server()), self::DEFAULT_NAME))); $config->set("server-name", $name); - $this->message($this->lang->get(KnownTranslationKeys::PORT_WARNING)); + $this->message($this->lang->translate(KnownTranslationFactory::port_warning())); do{ - $port = (int) $this->getInput($this->lang->get(KnownTranslationKeys::SERVER_PORT), (string) self::DEFAULT_PORT); + $port = (int) $this->getInput($this->lang->translate(KnownTranslationFactory::server_port()), (string) self::DEFAULT_PORT); if($port <= 0 or $port > 65535){ - $this->error($this->lang->get(KnownTranslationKeys::INVALID_PORT)); + $this->error($this->lang->translate(KnownTranslationFactory::invalid_port())); continue; } @@ -158,35 +158,35 @@ LICENSE; }while(true); $config->set("server-port", $port); - $this->message($this->lang->get(KnownTranslationKeys::GAMEMODE_INFO)); + $this->message($this->lang->translate(KnownTranslationFactory::gamemode_info())); do{ - $gamemode = (int) $this->getInput($this->lang->get(KnownTranslationKeys::DEFAULT_GAMEMODE), (string) GameModeIdMap::getInstance()->toId(GameMode::SURVIVAL())); + $gamemode = (int) $this->getInput($this->lang->translate(KnownTranslationFactory::default_gamemode()), (string) GameModeIdMap::getInstance()->toId(GameMode::SURVIVAL())); }while($gamemode < 0 or $gamemode > 3); $config->set("gamemode", $gamemode); - $config->set("max-players", (int) $this->getInput($this->lang->get(KnownTranslationKeys::MAX_PLAYERS), (string) self::DEFAULT_PLAYERS)); + $config->set("max-players", (int) $this->getInput($this->lang->translate(KnownTranslationFactory::max_players()), (string) self::DEFAULT_PLAYERS)); $config->save(); } private function generateUserFiles() : void{ - $this->message($this->lang->get(KnownTranslationKeys::OP_INFO)); + $this->message($this->lang->translate(KnownTranslationFactory::op_info())); - $op = strtolower($this->getInput($this->lang->get(KnownTranslationKeys::OP_WHO), "")); + $op = strtolower($this->getInput($this->lang->translate(KnownTranslationFactory::op_who()), "")); if($op === ""){ - $this->error($this->lang->get(KnownTranslationKeys::OP_WARNING)); + $this->error($this->lang->translate(KnownTranslationFactory::op_warning())); }else{ $ops = new Config(Path::join($this->dataPath, "ops.txt"), Config::ENUM); $ops->set($op, true); $ops->save(); } - $this->message($this->lang->get(KnownTranslationKeys::WHITELIST_INFO)); + $this->message($this->lang->translate(KnownTranslationFactory::whitelist_info())); $config = new Config(Path::join($this->dataPath, "server.properties"), Config::PROPERTIES); - if(strtolower($this->getInput($this->lang->get(KnownTranslationKeys::WHITELIST_ENABLE), "n", "y/N")) === "y"){ - $this->error($this->lang->get(KnownTranslationKeys::WHITELIST_WARNING)); + if(strtolower($this->getInput($this->lang->translate(KnownTranslationFactory::whitelist_enable()), "n", "y/N")) === "y"){ + $this->error($this->lang->translate(KnownTranslationFactory::whitelist_warning())); $config->set("white-list", true); }else{ $config->set("white-list", false); @@ -196,9 +196,9 @@ LICENSE; private function networkFunctions() : void{ $config = new Config(Path::join($this->dataPath, "server.properties"), Config::PROPERTIES); - $this->error($this->lang->get(KnownTranslationKeys::QUERY_WARNING1)); - $this->error($this->lang->get(KnownTranslationKeys::QUERY_WARNING2)); - if(strtolower($this->getInput($this->lang->get(KnownTranslationKeys::QUERY_DISABLE), "n", "y/N")) === "y"){ + $this->error($this->lang->translate(KnownTranslationFactory::query_warning1())); + $this->error($this->lang->translate(KnownTranslationFactory::query_warning2())); + if(strtolower($this->getInput($this->lang->translate(KnownTranslationFactory::query_disable()), "n", "y/N")) === "y"){ $config->set("enable-query", false); }else{ $config->set("enable-query", true); @@ -208,7 +208,7 @@ LICENSE; } private function printIpDetails() : void{ - $this->message($this->lang->get(KnownTranslationKeys::IP_GET)); + $this->message($this->lang->translate(KnownTranslationFactory::ip_get())); $externalIP = Internet::getIP(); if($externalIP === false){ @@ -220,15 +220,15 @@ LICENSE; $internalIP = "unknown (" . $e->getMessage() . ")"; } - $this->error($this->lang->translateString(KnownTranslationKeys::IP_WARNING, ["EXTERNAL_IP" => $externalIP, "INTERNAL_IP" => $internalIP])); - $this->error($this->lang->get(KnownTranslationKeys::IP_CONFIRM)); + $this->error($this->lang->translate(KnownTranslationFactory::ip_warning($externalIP, $internalIP))); + $this->error($this->lang->translate(KnownTranslationFactory::ip_confirm())); $this->readLine(); } private function endWizard() : void{ - $this->message($this->lang->get(KnownTranslationKeys::YOU_HAVE_FINISHED)); - $this->message($this->lang->get(KnownTranslationKeys::POCKETMINE_PLUGINS)); - $this->message($this->lang->translateString(KnownTranslationKeys::POCKETMINE_WILL_START, [VersionInfo::NAME])); + $this->message($this->lang->translate(KnownTranslationFactory::you_have_finished())); + $this->message($this->lang->translate(KnownTranslationFactory::pocketmine_plugins())); + $this->message($this->lang->translate(KnownTranslationFactory::pocketmine_will_start(VersionInfo::NAME))); $this->writeLine(); $this->writeLine(); diff --git a/src/world/World.php b/src/world/World.php index 0f613fe036..14e16c72d4 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -54,7 +54,7 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\ItemUseResult; use pocketmine\item\LegacyStringToItemParser; -use pocketmine\lang\KnownTranslationKeys; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; use pocketmine\nbt\NbtDataException; @@ -401,7 +401,7 @@ class World implements ChunkManager{ $this->minY = $this->provider->getWorldMinY(); $this->maxY = $this->provider->getWorldMaxY(); - $this->server->getLogger()->info($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_PREPARING, [$this->displayName])); + $this->server->getLogger()->info($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_preparing($this->displayName))); $this->generator = GeneratorManager::getInstance()->getGenerator($this->provider->getWorldData()->getGenerator(), true); //TODO: validate generator options $this->chunkPopulationRequestQueue = new \SplQueue(); diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 0c3a166b83..45a57e3f70 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -27,7 +27,7 @@ use pocketmine\entity\Entity; use pocketmine\event\world\WorldInitEvent; use pocketmine\event\world\WorldLoadEvent; use pocketmine\event\world\WorldUnloadEvent; -use pocketmine\lang\KnownTranslationKeys; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\player\ChunkSelector; use pocketmine\Server; use pocketmine\timings\Timings; @@ -149,7 +149,7 @@ class WorldManager{ return false; } - $this->server->getLogger()->info($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_UNLOADING, [$world->getDisplayName()])); + $this->server->getLogger()->info($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_unloading($world->getDisplayName()))); try{ $safeSpawn = $this->defaultWorld !== null ? $this->defaultWorld->getSafeSpawn() : null; }catch(WorldException $e){ @@ -193,12 +193,12 @@ class WorldManager{ $providers = $this->providerManager->getMatchingProviders($path); if(count($providers) !== 1){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_LOADERROR, [ + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_loadError( $name, count($providers) === 0 ? - $this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_UNKNOWNFORMAT) : - $this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_AMBIGUOUSFORMAT, [implode(", ", array_keys($providers))]) - ])); + $this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_unknownFormat()) : + $this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_ambiguousFormat(implode(", ", array_keys($providers))) + )))); return false; } $providerClass = array_shift($providers); @@ -206,16 +206,16 @@ class WorldManager{ try{ $provider = $providerClass->fromPath($path); }catch(CorruptedWorldException $e){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_LOADERROR, [$name, "Corruption detected: " . $e->getMessage()])); + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_loadError($name, "Corruption detected: " . $e->getMessage()))); return false; }catch(UnsupportedWorldFormatException $e){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_LOADERROR, [$name, "Unsupported format: " . $e->getMessage()])); + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_loadError($name, "Unsupported format: " . $e->getMessage()))); return false; } try{ GeneratorManager::getInstance()->getGenerator($provider->getWorldData()->getGenerator(), true); }catch(\InvalidArgumentException $e){ - $this->server->getLogger()->error($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_LOADERROR, [$name, "Unknown generator \"" . $provider->getWorldData()->getGenerator() . "\""])); + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_loadError($name, "Unknown generator \"" . $provider->getWorldData()->getGenerator() . "\""))); return false; } if(!($provider instanceof WritableWorldProvider)){ @@ -265,7 +265,7 @@ class WorldManager{ (new WorldLoadEvent($world))->call(); if($backgroundGeneration){ - $this->server->getLogger()->notice($this->server->getLanguage()->translateString(KnownTranslationKeys::POCKETMINE_LEVEL_BACKGROUNDGENERATION, [$name])); + $this->server->getLogger()->notice($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_backgroundGeneration($name))); $spawnLocation = $world->getSpawnLocation(); $centerX = $spawnLocation->getFloorX() >> 4; From 27a2d060833639ccadc0bd150809b4711db51d02 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 10 Aug 2021 14:53:03 +0100 Subject: [PATCH 2670/3224] Fix CS --- build/generate-known-translation-apis.php | 3 +-- src/lang/KnownTranslationFactory.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/build/generate-known-translation-apis.php b/build/generate-known-translation-apis.php index fd24072c05..4c61a16052 100644 --- a/build/generate-known-translation-apis.php +++ b/build/generate-known-translation-apis.php @@ -120,7 +120,7 @@ function generate_known_translation_factory(array $languageDefinitions) : void{ echo SHARED_HEADER; echo <<<'HEADER' /** - * This class contains factory methods for all the translations known to PocketMine-MP as per the used version of + * This class contains factory methods for all the translations known to PocketMine-MP as per the used version of * pmmp/Language. * This class is generated automatically, do NOT modify it by hand. */ @@ -167,7 +167,6 @@ HEADER; echo "Done generating KnownTranslationFactory.\n"; } - $lang = parse_ini_file(Path::join(\pocketmine\RESOURCE_PATH, "locale", "eng.ini"), false, INI_SCANNER_RAW); if($lang === false){ fwrite(STDERR, "Missing language files!\n"); diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index 77f2ca2017..78c301a3e2 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\lang; /** - * This class contains factory methods for all the translations known to PocketMine-MP as per the used version of + * This class contains factory methods for all the translations known to PocketMine-MP as per the used version of * pmmp/Language. * This class is generated automatically, do NOT modify it by hand. */ From b4c0ddd15522e302e1ba3cf0b21fb0529fac8f12 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 10 Aug 2021 15:17:26 +0100 Subject: [PATCH 2671/3224] Use native union types for TranslationContainer|string --- src/Server.php | 3 +-- src/command/Command.php | 5 +---- src/command/CommandSender.php | 5 +---- src/console/ConsoleCommandSender.php | 5 +---- src/event/player/PlayerDeathEvent.php | 12 +++--------- src/event/player/PlayerJoinEvent.php | 17 +++-------------- src/event/player/PlayerKickEvent.php | 17 +++-------------- src/event/player/PlayerQuitEvent.php | 15 +++------------ src/player/Player.php | 17 +++++------------ 9 files changed, 21 insertions(+), 75 deletions(-) diff --git a/src/Server.php b/src/Server.php index bce3d1a68e..ad23df82b8 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1194,10 +1194,9 @@ class Server{ } /** - * @param TranslationContainer|string $message * @param CommandSender[]|null $recipients */ - public function broadcastMessage($message, ?array $recipients = null) : int{ + public function broadcastMessage(TranslationContainer|string $message, ?array $recipients = null) : int{ $recipients = $recipients ?? $this->getBroadcastChannelSubscribers(self::BROADCAST_CHANNEL_USERS); foreach($recipients as $recipient){ diff --git a/src/command/Command.php b/src/command/Command.php index 9ba5fd16c9..c7ce225c82 100644 --- a/src/command/Command.php +++ b/src/command/Command.php @@ -231,10 +231,7 @@ abstract class Command{ $this->usageMessage = $usage; } - /** - * @param TranslationContainer|string $message - */ - public static function broadcastCommandMessage(CommandSender $source, $message, bool $sendToSource = true) : void{ + public static function broadcastCommandMessage(CommandSender $source, TranslationContainer|string $message, bool $sendToSource = true) : void{ $users = $source->getServer()->getBroadcastChannelSubscribers(Server::BROADCAST_CHANNEL_ADMINISTRATIVE); if($message instanceof TranslationContainer){ $formatted = "[" . $source->getName() . ": " . ($source->getLanguage()->get($message->getText()) !== $message->getText() ? "%" : "") . $message->getText() . "]"; diff --git a/src/command/CommandSender.php b/src/command/CommandSender.php index 3c19565fed..0776a614ff 100644 --- a/src/command/CommandSender.php +++ b/src/command/CommandSender.php @@ -32,10 +32,7 @@ interface CommandSender extends Permissible{ public function getLanguage() : Language; - /** - * @param TranslationContainer|string $message - */ - public function sendMessage($message) : void; + public function sendMessage(TranslationContainer|string $message) : void; public function getServer() : Server; diff --git a/src/console/ConsoleCommandSender.php b/src/console/ConsoleCommandSender.php index eba16586ae..219ecb2afd 100644 --- a/src/console/ConsoleCommandSender.php +++ b/src/console/ConsoleCommandSender.php @@ -58,10 +58,7 @@ class ConsoleCommandSender implements CommandSender{ return $this->language; } - /** - * @param TranslationContainer|string $message - */ - public function sendMessage($message) : void{ + public function sendMessage(TranslationContainer|string $message) : void{ $server = $this->getServer(); if($message instanceof TranslationContainer){ $message = $this->getLanguage()->translate($message); diff --git a/src/event/player/PlayerDeathEvent.php b/src/event/player/PlayerDeathEvent.php index 0886a36520..b3d55dc13c 100644 --- a/src/event/player/PlayerDeathEvent.php +++ b/src/event/player/PlayerDeathEvent.php @@ -47,7 +47,7 @@ class PlayerDeathEvent extends EntityDeathEvent{ * @param Item[] $drops * @param string|TranslationContainer|null $deathMessage Null will cause the default vanilla message to be used */ - public function __construct(Player $entity, array $drops, int $xp, $deathMessage){ + public function __construct(Player $entity, array $drops, int $xp, TranslationContainer|string|null $deathMessage){ parent::__construct($entity, $drops, $xp); $this->deathMessage = $deathMessage ?? self::deriveMessage($entity->getDisplayName(), $entity->getLastDamageCause()); } @@ -63,17 +63,11 @@ class PlayerDeathEvent extends EntityDeathEvent{ return $this->entity; } - /** - * @return TranslationContainer|string - */ - public function getDeathMessage(){ + public function getDeathMessage() : TranslationContainer|string{ return $this->deathMessage; } - /** - * @param TranslationContainer|string $deathMessage - */ - public function setDeathMessage($deathMessage) : void{ + public function setDeathMessage(TranslationContainer|string $deathMessage) : void{ $this->deathMessage = $deathMessage; } diff --git a/src/event/player/PlayerJoinEvent.php b/src/event/player/PlayerJoinEvent.php index 30a46065bf..56900874b6 100644 --- a/src/event/player/PlayerJoinEvent.php +++ b/src/event/player/PlayerJoinEvent.php @@ -37,27 +37,16 @@ class PlayerJoinEvent extends PlayerEvent{ /** @var string|TranslationContainer */ protected $joinMessage; - /** - * PlayerJoinEvent constructor. - * - * @param TranslationContainer|string $joinMessage - */ - public function __construct(Player $player, $joinMessage){ + public function __construct(Player $player, TranslationContainer|string $joinMessage){ $this->player = $player; $this->joinMessage = $joinMessage; } - /** - * @param string|TranslationContainer $joinMessage - */ - public function setJoinMessage($joinMessage) : void{ + public function setJoinMessage(TranslationContainer|string $joinMessage) : void{ $this->joinMessage = $joinMessage; } - /** - * @return string|TranslationContainer - */ - public function getJoinMessage(){ + public function getJoinMessage() : TranslationContainer|string{ return $this->joinMessage; } } diff --git a/src/event/player/PlayerKickEvent.php b/src/event/player/PlayerKickEvent.php index a31e9e1da6..4119d18b81 100644 --- a/src/event/player/PlayerKickEvent.php +++ b/src/event/player/PlayerKickEvent.php @@ -40,12 +40,7 @@ class PlayerKickEvent extends PlayerEvent implements Cancellable{ /** @var string */ protected $reason; - /** - * PlayerKickEvent constructor. - * - * @param TranslationContainer|string $quitMessage - */ - public function __construct(Player $player, string $reason, $quitMessage){ + public function __construct(Player $player, string $reason, TranslationContainer|string $quitMessage){ $this->player = $player; $this->quitMessage = $quitMessage; $this->reason = $reason; @@ -59,17 +54,11 @@ class PlayerKickEvent extends PlayerEvent implements Cancellable{ return $this->reason; } - /** - * @param TranslationContainer|string $quitMessage - */ - public function setQuitMessage($quitMessage) : void{ + public function setQuitMessage(TranslationContainer|string $quitMessage) : void{ $this->quitMessage = $quitMessage; } - /** - * @return TranslationContainer|string - */ - public function getQuitMessage(){ + public function getQuitMessage() : TranslationContainer|string{ return $this->quitMessage; } } diff --git a/src/event/player/PlayerQuitEvent.php b/src/event/player/PlayerQuitEvent.php index 4fe6bf71f8..84beece22c 100644 --- a/src/event/player/PlayerQuitEvent.php +++ b/src/event/player/PlayerQuitEvent.php @@ -36,26 +36,17 @@ class PlayerQuitEvent extends PlayerEvent{ /** @var string */ protected $quitReason; - /** - * @param TranslationContainer|string $quitMessage - */ - public function __construct(Player $player, $quitMessage, string $quitReason){ + public function __construct(Player $player, TranslationContainer|string $quitMessage, string $quitReason){ $this->player = $player; $this->quitMessage = $quitMessage; $this->quitReason = $quitReason; } - /** - * @param TranslationContainer|string $quitMessage - */ - public function setQuitMessage($quitMessage) : void{ + public function setQuitMessage(TranslationContainer|string $quitMessage) : void{ $this->quitMessage = $quitMessage; } - /** - * @return TranslationContainer|string - */ - public function getQuitMessage(){ + public function getQuitMessage() : TranslationContainer|string{ return $this->quitMessage; } diff --git a/src/player/Player.php b/src/player/Player.php index d27726295f..e333996907 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -319,10 +319,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } } - /** - * @return TranslationContainer|string - */ - public function getLeaveMessage(){ + public function getLeaveMessage() : TranslationContainer|string{ if($this->spawned){ return new TranslationContainer(TextFormat::YELLOW . "%" . KnownTranslationKeys::MULTIPLAYER_PLAYER_LEFT, [ $this->getDisplayName() @@ -1782,10 +1779,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ /** * Sends a direct chat message to a player - * - * @param TranslationContainer|string $message */ - public function sendMessage($message) : void{ + public function sendMessage(TranslationContainer|string $message) : void{ if($message instanceof TranslationContainer){ $this->sendTranslation($message->getText(), $message->getParameters()); return; @@ -1883,10 +1878,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ /** * Kicks a player from the server - * - * @param TranslationContainer|string|null $quitMessage */ - public function kick(string $reason = "", $quitMessage = null) : bool{ + public function kick(string $reason = "", TranslationContainer|string|null $quitMessage = null) : bool{ $ev = new PlayerKickEvent($this, $reason, $quitMessage ?? $this->getLeaveMessage()); $ev->call(); if(!$ev->isCancelled()){ @@ -1914,7 +1907,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ * @param string $reason Shown to the player, usually this will appear on their disconnect screen. * @param TranslationContainer|string|null $quitMessage Message to broadcast to online players (null will use default) */ - public function disconnect(string $reason, $quitMessage = null) : void{ + public function disconnect(string $reason, TranslationContainer|string|null $quitMessage = null) : void{ if(!$this->isConnected()){ return; } @@ -1930,7 +1923,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ * @param string $reason Shown to the player, usually this will appear on their disconnect screen. * @param TranslationContainer|string|null $quitMessage Message to broadcast to online players (null will use default) */ - public function onPostDisconnect(string $reason, $quitMessage) : void{ + public function onPostDisconnect(string $reason, TranslationContainer|string|null $quitMessage) : void{ if($this->isConnected()){ throw new \InvalidStateException("Player is still connected"); } From 2ad5de379f3c6a2f4be5686dbe546045fa6023a6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 10 Aug 2021 15:28:11 +0100 Subject: [PATCH 2672/3224] HandlerListManager::unregisterAll() accepts RegisteredListener since all this function is doing is passing the object on to the HandlerList, it should accept RegisteredListener, like HandlerList::unregister(). --- src/event/HandlerListManager.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/event/HandlerListManager.php b/src/event/HandlerListManager.php index 3bed7631c1..0859b1e5ec 100644 --- a/src/event/HandlerListManager.php +++ b/src/event/HandlerListManager.php @@ -42,10 +42,10 @@ class HandlerListManager{ * Unregisters all the listeners * If a Plugin or Listener is passed, all the listeners with that object will be removed * - * @param Plugin|Listener|null $object + * @param Plugin|Listener|RegisteredListener|null $object */ public function unregisterAll($object = null) : void{ - if($object instanceof Listener or $object instanceof Plugin){ + if($object instanceof Listener or $object instanceof Plugin or $object instanceof RegisteredListener){ foreach($this->allLists as $h){ $h->unregister($object); } From 2cdd6e634fb10a753855a7f59e4a0941516a13de Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 10 Aug 2021 19:32:28 +0100 Subject: [PATCH 2673/3224] New /version format --- resources/locale | 2 +- src/command/defaults/VersionCommand.php | 44 ++++++++++++++++-- src/lang/KnownTranslationFactory.php | 62 +++++++++++++++++++++++++ src/lang/KnownTranslationKeys.php | 10 ++++ 4 files changed, 113 insertions(+), 5 deletions(-) diff --git a/resources/locale b/resources/locale index ca7fecaf24..6f74d9449a 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit ca7fecaf24d8a8f9b947b69f1a8772475e03c379 +Subproject commit 6f74d9449a00f806fd78140743004d6077b1577b diff --git a/src/command/defaults/VersionCommand.php b/src/command/defaults/VersionCommand.php index 9b86160715..8bebadefb7 100644 --- a/src/command/defaults/VersionCommand.php +++ b/src/command/defaults/VersionCommand.php @@ -30,10 +30,16 @@ use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\permission\DefaultPermissionNames; use pocketmine\plugin\Plugin; use pocketmine\utils\TextFormat; +use pocketmine\utils\Utils; +use pocketmine\VersionInfo; use function count; +use function function_exists; use function implode; +use function opcache_get_status; +use function sprintf; use function stripos; use function strtolower; +use const PHP_VERSION; class VersionCommand extends VanillaCommand{ @@ -53,12 +59,42 @@ class VersionCommand extends VanillaCommand{ } if(count($args) === 0){ - $sender->sendMessage(KnownTranslationFactory::pocketmine_server_info_extended( - $sender->getServer()->getName(), - $sender->getServer()->getPocketMineVersion(), - $sender->getServer()->getVersion(), + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_serverSoftwareName( + TextFormat::GREEN, + VersionInfo::NAME + )); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_serverSoftwareVersion( + TextFormat::GREEN, + VersionInfo::getVersionObj()->getFullVersion(), + VersionInfo::getGitHash() + )); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_minecraftVersion( + TextFormat::GREEN, + ProtocolInfo::MINECRAFT_VERSION_NETWORK, (string) ProtocolInfo::CURRENT_PROTOCOL )); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_phpVersion(TextFormat::GREEN, PHP_VERSION)); + + $jitColor = TextFormat::GREEN; + if( + function_exists('opcache_get_status') && + ($opcacheStatus = opcache_get_status(false)) !== false && + isset($opcacheStatus["jit"]["on"]) + ){ + $jit = $opcacheStatus["jit"]; + if($jit["on"] === true){ + $jitStatus = KnownTranslationFactory::pocketmine_command_version_phpJitEnabled( + sprintf("CRTO: %s%s%s%s", $jit["opt_flags"] >> 2, $jit["opt_flags"] & 0x03, $jit["kind"], $jit["opt_level"]) + ); + $jitColor = TextFormat::YELLOW; + }else{ + $jitStatus = KnownTranslationFactory::pocketmine_command_version_phpJitDisabled(); + } + }else{ + $jitStatus = KnownTranslationFactory::pocketmine_command_version_phpJitNotSupported(); + } + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_phpJitStatus($jitColor, $sender->getLanguage()->translate($jitStatus))); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_operatingSystem(TextFormat::GREEN, Utils::getOS())); }else{ $pluginName = implode(" ", $args); $exactPlugin = $sender->getServer()->getPluginManager()->getPlugin($pluginName); diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index 78c301a3e2..27fa603925 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -1124,10 +1124,72 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_DESCRIPTION, []); } + public static function pocketmine_command_version_header() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_HEADER, []); + } + + public static function pocketmine_command_version_minecraftVersion(string $color, string $minecraftVersion, string $minecraftProtocolVersion) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_MINECRAFTVERSION, [ + "color" => $color, + "minecraftVersion" => $minecraftVersion, + "minecraftProtocolVersion" => $minecraftProtocolVersion, + ]); + } + public static function pocketmine_command_version_noSuchPlugin() : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_NOSUCHPLUGIN, []); } + public static function pocketmine_command_version_operatingSystem(string $color, string $operatingSystemName) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_OPERATINGSYSTEM, [ + "color" => $color, + "operatingSystemName" => $operatingSystemName, + ]); + } + + public static function pocketmine_command_version_phpJitDisabled() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPJITDISABLED, []); + } + + public static function pocketmine_command_version_phpJitEnabled(string $extraJitInfo) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPJITENABLED, [ + "extraJitInfo" => $extraJitInfo, + ]); + } + + public static function pocketmine_command_version_phpJitNotSupported() : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPJITNOTSUPPORTED, []); + } + + public static function pocketmine_command_version_phpJitStatus(string $color, string $jitStatus) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPJITSTATUS, [ + "color" => $color, + "jitStatus" => $jitStatus, + ]); + } + + public static function pocketmine_command_version_phpVersion(string $color, string $phpVersion) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPVERSION, [ + "color" => $color, + "phpVersion" => $phpVersion, + ]); + } + + public static function pocketmine_command_version_serverSoftwareName(string $color, string $serverSoftwareName) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_SERVERSOFTWARENAME, [ + "color" => $color, + "serverSoftwareName" => $serverSoftwareName, + ]); + } + + public static function pocketmine_command_version_serverSoftwareVersion(string $color, string $serverSoftwareVersion, string $serverGitHash) : TranslationContainer{ + return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_SERVERSOFTWAREVERSION, [ + "color" => $color, + "serverSoftwareVersion" => $serverSoftwareVersion, + "serverGitHash" => $serverGitHash, + ]); + } + public static function pocketmine_command_version_usage() : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_USAGE, []); } diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index 6d5112688e..3f5185e1cf 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -246,7 +246,17 @@ final class KnownTranslationKeys{ public const POCKETMINE_COMMAND_UNBAN_IP_DESCRIPTION = "pocketmine.command.unban.ip.description"; public const POCKETMINE_COMMAND_UNBAN_PLAYER_DESCRIPTION = "pocketmine.command.unban.player.description"; public const POCKETMINE_COMMAND_VERSION_DESCRIPTION = "pocketmine.command.version.description"; + public const POCKETMINE_COMMAND_VERSION_HEADER = "pocketmine.command.version.header"; + public const POCKETMINE_COMMAND_VERSION_MINECRAFTVERSION = "pocketmine.command.version.minecraftVersion"; public const POCKETMINE_COMMAND_VERSION_NOSUCHPLUGIN = "pocketmine.command.version.noSuchPlugin"; + public const POCKETMINE_COMMAND_VERSION_OPERATINGSYSTEM = "pocketmine.command.version.operatingSystem"; + public const POCKETMINE_COMMAND_VERSION_PHPJITDISABLED = "pocketmine.command.version.phpJitDisabled"; + public const POCKETMINE_COMMAND_VERSION_PHPJITENABLED = "pocketmine.command.version.phpJitEnabled"; + public const POCKETMINE_COMMAND_VERSION_PHPJITNOTSUPPORTED = "pocketmine.command.version.phpJitNotSupported"; + public const POCKETMINE_COMMAND_VERSION_PHPJITSTATUS = "pocketmine.command.version.phpJitStatus"; + public const POCKETMINE_COMMAND_VERSION_PHPVERSION = "pocketmine.command.version.phpVersion"; + public const POCKETMINE_COMMAND_VERSION_SERVERSOFTWARENAME = "pocketmine.command.version.serverSoftwareName"; + public const POCKETMINE_COMMAND_VERSION_SERVERSOFTWAREVERSION = "pocketmine.command.version.serverSoftwareVersion"; public const POCKETMINE_COMMAND_VERSION_USAGE = "pocketmine.command.version.usage"; public const POCKETMINE_COMMAND_WHITELIST_DESCRIPTION = "pocketmine.command.whitelist.description"; public const POCKETMINE_CRASH_ARCHIVE = "pocketmine.crash.archive"; From cf77b33c3bb21658847e103ed81844d67295189a Mon Sep 17 00:00:00 2001 From: Rush2929 <76860328+Rush2929@users.noreply.github.com> Date: Wed, 11 Aug 2021 03:36:57 +0900 Subject: [PATCH 2674/3224] Bows can now use offhand arrows (#4356) --- src/item/Bow.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/item/Bow.php b/src/item/Bow.php index c86438b3b6..fd6364e846 100644 --- a/src/item/Bow.php +++ b/src/item/Bow.php @@ -46,7 +46,13 @@ class Bow extends Tool implements Releasable{ public function onReleaseUsing(Player $player) : ItemUseResult{ $arrow = VanillaItems::ARROW(); - if($player->hasFiniteResources() and !$player->getInventory()->contains($arrow)){ + $inventory = match(true){ + $player->getOffHandInventory()->contains($arrow) => $player->getOffHandInventory(), + $player->getInventory()->contains($arrow) => $player->getInventory(), + default => null + }; + + if($player->hasFiniteResources() and $inventory === null){ return ItemUseResult::FAIL(); } @@ -110,7 +116,7 @@ class Bow extends Tool implements Releasable{ if($player->hasFiniteResources()){ if(!$infinity){ //TODO: tipped arrows are still consumed when Infinity is applied - $player->getInventory()->removeItem($arrow); + $inventory?->removeItem($arrow); } $this->applyDamage(1); } From f42c9bb6d685a24bb4a095bd2693370302f6e232 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 10 Aug 2021 19:48:30 +0100 Subject: [PATCH 2675/3224] Removed unused translation --- resources/locale | 2 +- src/lang/KnownTranslationFactory.php | 4 ---- src/lang/KnownTranslationKeys.php | 1 - 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/resources/locale b/resources/locale index 6f74d9449a..26ea57220b 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 6f74d9449a00f806fd78140743004d6077b1577b +Subproject commit 26ea57220b388647c12bed051116b154aa8b88fe diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index 27fa603925..9c5037377d 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -1124,10 +1124,6 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_DESCRIPTION, []); } - public static function pocketmine_command_version_header() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_HEADER, []); - } - public static function pocketmine_command_version_minecraftVersion(string $color, string $minecraftVersion, string $minecraftProtocolVersion) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_MINECRAFTVERSION, [ "color" => $color, diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index 3f5185e1cf..128049118b 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -246,7 +246,6 @@ final class KnownTranslationKeys{ public const POCKETMINE_COMMAND_UNBAN_IP_DESCRIPTION = "pocketmine.command.unban.ip.description"; public const POCKETMINE_COMMAND_UNBAN_PLAYER_DESCRIPTION = "pocketmine.command.unban.player.description"; public const POCKETMINE_COMMAND_VERSION_DESCRIPTION = "pocketmine.command.version.description"; - public const POCKETMINE_COMMAND_VERSION_HEADER = "pocketmine.command.version.header"; public const POCKETMINE_COMMAND_VERSION_MINECRAFTVERSION = "pocketmine.command.version.minecraftVersion"; public const POCKETMINE_COMMAND_VERSION_NOSUCHPLUGIN = "pocketmine.command.version.noSuchPlugin"; public const POCKETMINE_COMMAND_VERSION_OPERATINGSYSTEM = "pocketmine.command.version.operatingSystem"; From eb24e040f3489ab96ef61e4b364e8b3abaed85f8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Aug 2021 13:13:33 +0100 Subject: [PATCH 2676/3224] TextFormat: add COLORS and FORMATS constants --- src/utils/TextFormat.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/utils/TextFormat.php b/src/utils/TextFormat.php index c848795821..5594024a0b 100644 --- a/src/utils/TextFormat.php +++ b/src/utils/TextFormat.php @@ -67,11 +67,39 @@ abstract class TextFormat{ public const YELLOW = TextFormat::ESCAPE . "e"; public const WHITE = TextFormat::ESCAPE . "f"; + public const COLORS = [ + self::BLACK => self::BLACK, + self::DARK_BLUE => self::DARK_BLUE, + self::DARK_GREEN => self::DARK_GREEN, + self::DARK_AQUA => self::DARK_AQUA, + self::DARK_RED => self::DARK_RED, + self::DARK_PURPLE => self::DARK_PURPLE, + self::GOLD => self::GOLD, + self::GRAY => self::GRAY, + self::DARK_GRAY => self::DARK_GRAY, + self::BLUE => self::BLUE, + self::GREEN => self::GREEN, + self::AQUA => self::AQUA, + self::RED => self::RED, + self::LIGHT_PURPLE => self::LIGHT_PURPLE, + self::YELLOW => self::YELLOW, + self::WHITE => self::WHITE, + ]; + public const OBFUSCATED = TextFormat::ESCAPE . "k"; public const BOLD = TextFormat::ESCAPE . "l"; public const STRIKETHROUGH = TextFormat::ESCAPE . "m"; public const UNDERLINE = TextFormat::ESCAPE . "n"; public const ITALIC = TextFormat::ESCAPE . "o"; + + public const FORMATS = [ + self::OBFUSCATED => self::OBFUSCATED, + self::BOLD => self::BOLD, + self::STRIKETHROUGH => self::STRIKETHROUGH, + self::UNDERLINE => self::UNDERLINE, + self::ITALIC => self::ITALIC, + ]; + public const RESET = TextFormat::ESCAPE . "r"; private static function makePcreError() : \InvalidArgumentException{ From 4d683c63d8a7ced240a2f7a440c9df1f6cb20356 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Aug 2021 13:43:58 +0100 Subject: [PATCH 2677/3224] TextFormat: remove toJSON() this is not used in the PM core, and is only used by 1 plugin in the whole public ecosystem: BigBrother. It makes more sense to make BigBrother maintainers shoulder the responsibility of maintaining this code, since they are the only ones that need it - besides, if this changed in any MCJE update in the last 5y, nobody has updated it, and nobody has maintained it either due to not having a fucking clue what the thing is for (the documentation is basically nonexistent). --- src/utils/TextFormat.php | 192 ----------------------------- src/utils/TextFormatJsonObject.php | 60 --------- 2 files changed, 252 deletions(-) delete mode 100644 src/utils/TextFormatJsonObject.php diff --git a/src/utils/TextFormat.php b/src/utils/TextFormat.php index 5594024a0b..cd25a21812 100644 --- a/src/utils/TextFormat.php +++ b/src/utils/TextFormat.php @@ -24,8 +24,6 @@ declare(strict_types=1); namespace pocketmine\utils; use function is_array; -use function json_encode; -use function json_last_error_msg; use function mb_scrub; use function preg_last_error; use function preg_quote; @@ -33,7 +31,6 @@ use function preg_replace; use function preg_split; use function str_repeat; use function str_replace; -use const JSON_UNESCAPED_SLASHES; use const PREG_BACKTRACK_LIMIT_ERROR; use const PREG_BAD_UTF8_ERROR; use const PREG_BAD_UTF8_OFFSET_ERROR; @@ -160,195 +157,6 @@ abstract class TextFormat{ return self::preg_replace('/' . preg_quote($placeholder, "/") . '([0-9a-fk-or])/u', TextFormat::ESCAPE . '$1', $string); } - /** - * Returns an JSON-formatted string with colors/markup - * - * @param string|string[] $string - */ - public static function toJSON($string) : string{ - if(!is_array($string)){ - $string = self::tokenize($string); - } - $newString = new TextFormatJsonObject(); - $pointer = $newString; - $color = "white"; - $bold = false; - $italic = false; - $underlined = false; - $strikethrough = false; - $obfuscated = false; - $index = 0; - - foreach($string as $token){ - if($pointer->text !== null){ - if($newString->extra === null){ - $newString->extra = []; - } - $newString->extra[$index] = $pointer = new TextFormatJsonObject(); - if($color !== "white"){ - $pointer->color = $color; - } - if($bold){ - $pointer->bold = true; - } - if($italic){ - $pointer->italic = true; - } - if($underlined){ - $pointer->underlined = true; - } - if($strikethrough){ - $pointer->strikethrough = true; - } - if($obfuscated){ - $pointer->obfuscated = true; - } - ++$index; - } - switch($token){ - case TextFormat::BOLD: - if(!$bold){ - $pointer->bold = true; - $bold = true; - } - break; - case TextFormat::OBFUSCATED: - if(!$obfuscated){ - $pointer->obfuscated = true; - $obfuscated = true; - } - break; - case TextFormat::ITALIC: - if(!$italic){ - $pointer->italic = true; - $italic = true; - } - break; - case TextFormat::UNDERLINE: - if(!$underlined){ - $pointer->underlined = true; - $underlined = true; - } - break; - case TextFormat::STRIKETHROUGH: - if(!$strikethrough){ - $pointer->strikethrough = true; - $strikethrough = true; - } - break; - case TextFormat::RESET: - if($color !== "white"){ - $pointer->color = "white"; - $color = "white"; - } - if($bold){ - $pointer->bold = false; - $bold = false; - } - if($italic){ - $pointer->italic = false; - $italic = false; - } - if($underlined){ - $pointer->underlined = false; - $underlined = false; - } - if($strikethrough){ - $pointer->strikethrough = false; - $strikethrough = false; - } - if($obfuscated){ - $pointer->obfuscated = false; - $obfuscated = false; - } - break; - - //Colors - case TextFormat::BLACK: - $pointer->color = "black"; - $color = "black"; - break; - case TextFormat::DARK_BLUE: - $pointer->color = "dark_blue"; - $color = "dark_blue"; - break; - case TextFormat::DARK_GREEN: - $pointer->color = "dark_green"; - $color = "dark_green"; - break; - case TextFormat::DARK_AQUA: - $pointer->color = "dark_aqua"; - $color = "dark_aqua"; - break; - case TextFormat::DARK_RED: - $pointer->color = "dark_red"; - $color = "dark_red"; - break; - case TextFormat::DARK_PURPLE: - $pointer->color = "dark_purple"; - $color = "dark_purple"; - break; - case TextFormat::GOLD: - $pointer->color = "gold"; - $color = "gold"; - break; - case TextFormat::GRAY: - $pointer->color = "gray"; - $color = "gray"; - break; - case TextFormat::DARK_GRAY: - $pointer->color = "dark_gray"; - $color = "dark_gray"; - break; - case TextFormat::BLUE: - $pointer->color = "blue"; - $color = "blue"; - break; - case TextFormat::GREEN: - $pointer->color = "green"; - $color = "green"; - break; - case TextFormat::AQUA: - $pointer->color = "aqua"; - $color = "aqua"; - break; - case TextFormat::RED: - $pointer->color = "red"; - $color = "red"; - break; - case TextFormat::LIGHT_PURPLE: - $pointer->color = "light_purple"; - $color = "light_purple"; - break; - case TextFormat::YELLOW: - $pointer->color = "yellow"; - $color = "yellow"; - break; - case TextFormat::WHITE: - $pointer->color = "white"; - $color = "white"; - break; - default: - $pointer->text = $token; - break; - } - } - - if($newString->extra !== null){ - foreach($newString->extra as $k => $d){ - if($d->text === null){ - unset($newString->extra[$k]); - } - } - } - - $result = json_encode($newString, JSON_UNESCAPED_SLASHES); - if($result === false){ - throw new \InvalidArgumentException("Failed to encode result JSON: " . json_last_error_msg()); - } - return $result; - } - /** * Returns an HTML-formatted string with colors/markup * diff --git a/src/utils/TextFormatJsonObject.php b/src/utils/TextFormatJsonObject.php deleted file mode 100644 index f6ebf02aa6..0000000000 --- a/src/utils/TextFormatJsonObject.php +++ /dev/null @@ -1,60 +0,0 @@ -|null - */ - public $extra = null; - - public function jsonSerialize(){ - $result = (array) $this; - foreach($result as $k => $v){ - if($v === null){ - unset($result[$k]); - } - } - return $result; - } -} From 2782af7e22b2c25b79cca15587233b6eadd854ab Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Aug 2021 19:41:16 +0100 Subject: [PATCH 2678/3224] Terminal: use typed properties --- src/utils/Terminal.php | 66 ++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 44 deletions(-) diff --git a/src/utils/Terminal.php b/src/utils/Terminal.php index d85b1154f7..eb99f1fb39 100644 --- a/src/utils/Terminal.php +++ b/src/utils/Terminal.php @@ -33,52 +33,30 @@ use function stream_isatty; use const PHP_EOL; abstract class Terminal{ - /** @var string */ - public static $FORMAT_BOLD = ""; - /** @var string */ - public static $FORMAT_OBFUSCATED = ""; - /** @var string */ - public static $FORMAT_ITALIC = ""; - /** @var string */ - public static $FORMAT_UNDERLINE = ""; - /** @var string */ - public static $FORMAT_STRIKETHROUGH = ""; + public static string $FORMAT_BOLD = ""; + public static string $FORMAT_OBFUSCATED = ""; + public static string $FORMAT_ITALIC = ""; + public static string $FORMAT_UNDERLINE = ""; + public static string $FORMAT_STRIKETHROUGH = ""; - /** @var string */ - public static $FORMAT_RESET = ""; + public static string $FORMAT_RESET = ""; - /** @var string */ - public static $COLOR_BLACK = ""; - /** @var string */ - public static $COLOR_DARK_BLUE = ""; - /** @var string */ - public static $COLOR_DARK_GREEN = ""; - /** @var string */ - public static $COLOR_DARK_AQUA = ""; - /** @var string */ - public static $COLOR_DARK_RED = ""; - /** @var string */ - public static $COLOR_PURPLE = ""; - /** @var string */ - public static $COLOR_GOLD = ""; - /** @var string */ - public static $COLOR_GRAY = ""; - /** @var string */ - public static $COLOR_DARK_GRAY = ""; - /** @var string */ - public static $COLOR_BLUE = ""; - /** @var string */ - public static $COLOR_GREEN = ""; - /** @var string */ - public static $COLOR_AQUA = ""; - /** @var string */ - public static $COLOR_RED = ""; - /** @var string */ - public static $COLOR_LIGHT_PURPLE = ""; - /** @var string */ - public static $COLOR_YELLOW = ""; - /** @var string */ - public static $COLOR_WHITE = ""; + public static string $COLOR_BLACK = ""; + public static string $COLOR_DARK_BLUE = ""; + public static string $COLOR_DARK_GREEN = ""; + public static string $COLOR_DARK_AQUA = ""; + public static string $COLOR_DARK_RED = ""; + public static string $COLOR_PURPLE = ""; + public static string $COLOR_GOLD = ""; + public static string $COLOR_GRAY = ""; + public static string $COLOR_DARK_GRAY = ""; + public static string $COLOR_BLUE = ""; + public static string $COLOR_GREEN = ""; + public static string $COLOR_AQUA = ""; + public static string $COLOR_RED = ""; + public static string $COLOR_LIGHT_PURPLE = ""; + public static string $COLOR_YELLOW = ""; + public static string $COLOR_WHITE = ""; /** @var bool|null */ private static $formattingCodes = null; From 6a2a4cca4d552f19193668c96c6649cee336161b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Aug 2021 20:13:44 +0100 Subject: [PATCH 2679/3224] Terminal: use match instead of switch in toANSI() phpstan seems to have some trouble with large match statements (phpstan/phpstan#5454) --- src/utils/Terminal.php | 98 +++++++------------------ tests/phpstan/configs/phpstan-bugs.neon | 65 ++++++++++++++++ 2 files changed, 90 insertions(+), 73 deletions(-) diff --git a/src/utils/Terminal.php b/src/utils/Terminal.php index eb99f1fb39..f76aef6e41 100644 --- a/src/utils/Terminal.php +++ b/src/utils/Terminal.php @@ -187,79 +187,31 @@ abstract class Terminal{ $newString = ""; foreach($string as $token){ - switch($token){ - case TextFormat::BOLD: - $newString .= Terminal::$FORMAT_BOLD; - break; - case TextFormat::OBFUSCATED: - $newString .= Terminal::$FORMAT_OBFUSCATED; - break; - case TextFormat::ITALIC: - $newString .= Terminal::$FORMAT_ITALIC; - break; - case TextFormat::UNDERLINE: - $newString .= Terminal::$FORMAT_UNDERLINE; - break; - case TextFormat::STRIKETHROUGH: - $newString .= Terminal::$FORMAT_STRIKETHROUGH; - break; - case TextFormat::RESET: - $newString .= Terminal::$FORMAT_RESET; - break; - - //Colors - case TextFormat::BLACK: - $newString .= Terminal::$COLOR_BLACK; - break; - case TextFormat::DARK_BLUE: - $newString .= Terminal::$COLOR_DARK_BLUE; - break; - case TextFormat::DARK_GREEN: - $newString .= Terminal::$COLOR_DARK_GREEN; - break; - case TextFormat::DARK_AQUA: - $newString .= Terminal::$COLOR_DARK_AQUA; - break; - case TextFormat::DARK_RED: - $newString .= Terminal::$COLOR_DARK_RED; - break; - case TextFormat::DARK_PURPLE: - $newString .= Terminal::$COLOR_PURPLE; - break; - case TextFormat::GOLD: - $newString .= Terminal::$COLOR_GOLD; - break; - case TextFormat::GRAY: - $newString .= Terminal::$COLOR_GRAY; - break; - case TextFormat::DARK_GRAY: - $newString .= Terminal::$COLOR_DARK_GRAY; - break; - case TextFormat::BLUE: - $newString .= Terminal::$COLOR_BLUE; - break; - case TextFormat::GREEN: - $newString .= Terminal::$COLOR_GREEN; - break; - case TextFormat::AQUA: - $newString .= Terminal::$COLOR_AQUA; - break; - case TextFormat::RED: - $newString .= Terminal::$COLOR_RED; - break; - case TextFormat::LIGHT_PURPLE: - $newString .= Terminal::$COLOR_LIGHT_PURPLE; - break; - case TextFormat::YELLOW: - $newString .= Terminal::$COLOR_YELLOW; - break; - case TextFormat::WHITE: - $newString .= Terminal::$COLOR_WHITE; - break; - default: - $newString .= $token; - break; - } + $newString .= match($token){ + TextFormat::BOLD => Terminal::$FORMAT_BOLD, + TextFormat::OBFUSCATED => Terminal::$FORMAT_OBFUSCATED, + TextFormat::ITALIC => Terminal::$FORMAT_ITALIC, + TextFormat::UNDERLINE => Terminal::$FORMAT_UNDERLINE, + TextFormat::STRIKETHROUGH => Terminal::$FORMAT_STRIKETHROUGH, + TextFormat::RESET => Terminal::$FORMAT_RESET, + TextFormat::BLACK => Terminal::$COLOR_BLACK, + TextFormat::DARK_BLUE => Terminal::$COLOR_DARK_BLUE, + TextFormat::DARK_GREEN => Terminal::$COLOR_DARK_GREEN, + TextFormat::DARK_AQUA => Terminal::$COLOR_DARK_AQUA, + TextFormat::DARK_RED => Terminal::$COLOR_DARK_RED, + TextFormat::DARK_PURPLE => Terminal::$COLOR_PURPLE, + TextFormat::GOLD => Terminal::$COLOR_GOLD, + TextFormat::GRAY => Terminal::$COLOR_GRAY, + TextFormat::DARK_GRAY => Terminal::$COLOR_DARK_GRAY, + TextFormat::BLUE => Terminal::$COLOR_BLUE, + TextFormat::GREEN => Terminal::$COLOR_GREEN, + TextFormat::AQUA => Terminal::$COLOR_AQUA, + TextFormat::RED => Terminal::$COLOR_RED, + TextFormat::LIGHT_PURPLE => Terminal::$COLOR_LIGHT_PURPLE, + TextFormat::YELLOW => Terminal::$COLOR_YELLOW, + TextFormat::WHITE => Terminal::$COLOR_WHITE, + default => $token, + }; } return $newString; diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index a4bff81f06..efc2e88e48 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -40,6 +40,71 @@ parameters: count: 1 path: ../../../src/utils/Promise.php + - + message: "#^Match arm comparison between string and '§3' is always false\\.$#" + count: 1 + path: ../../../src/utils/Terminal.php + + - + message: "#^Match arm comparison between string and '§4' is always false\\.$#" + count: 1 + path: ../../../src/utils/Terminal.php + + - + message: "#^Match arm comparison between string and '§5' is always false\\.$#" + count: 1 + path: ../../../src/utils/Terminal.php + + - + message: "#^Match arm comparison between string and '§6' is always false\\.$#" + count: 1 + path: ../../../src/utils/Terminal.php + + - + message: "#^Match arm comparison between string and '§7' is always false\\.$#" + count: 1 + path: ../../../src/utils/Terminal.php + + - + message: "#^Match arm comparison between string and '§8' is always false\\.$#" + count: 1 + path: ../../../src/utils/Terminal.php + + - + message: "#^Match arm comparison between string and '§9' is always false\\.$#" + count: 1 + path: ../../../src/utils/Terminal.php + + - + message: "#^Match arm comparison between string and '§a' is always false\\.$#" + count: 1 + path: ../../../src/utils/Terminal.php + + - + message: "#^Match arm comparison between string and '§b' is always false\\.$#" + count: 1 + path: ../../../src/utils/Terminal.php + + - + message: "#^Match arm comparison between string and '§c' is always false\\.$#" + count: 1 + path: ../../../src/utils/Terminal.php + + - + message: "#^Match arm comparison between string and '§d' is always false\\.$#" + count: 1 + path: ../../../src/utils/Terminal.php + + - + message: "#^Match arm comparison between string and '§e' is always false\\.$#" + count: 1 + path: ../../../src/utils/Terminal.php + + - + message: "#^Match arm comparison between string and '§f' is always false\\.$#" + count: 1 + path: ../../../src/utils/Terminal.php + - message: "#^Parameter \\#1 \\$ of closure expects TMemberType, TMemberType given\\.$#" count: 1 From 662d1a35ffb28fc6ae68eb067fa4511aebc6e7d5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Aug 2021 20:29:21 +0100 Subject: [PATCH 2680/3224] generate-registry-annotations: skip files that don't contain classes --- build/generate-registry-annotations.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/generate-registry-annotations.php b/build/generate-registry-annotations.php index fe9b444b62..2eece2caed 100644 --- a/build/generate-registry-annotations.php +++ b/build/generate-registry-annotations.php @@ -49,7 +49,7 @@ foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($argv[1], throw new \RuntimeException("Failed to get contents of $file"); } - if(preg_match("/^namespace (.+);$/m", $contents, $matches) !== 1){ + if(preg_match("/^namespace (.+);$/m", $contents, $matches) !== 1 || preg_match('/^((final|abstract)\s+)?class /m', $contents) !== 1){ continue; } $shortClassName = basename($file, ".php"); From d18b5cb3060fc9899a33fe3ea06e9484f4ab4491 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Aug 2021 20:30:21 +0100 Subject: [PATCH 2681/3224] composer.json: added update-registry-annotations command --- composer.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/composer.json b/composer.json index fc719ec41d..b7a035714b 100644 --- a/composer.json +++ b/composer.json @@ -83,6 +83,9 @@ "make-server": [ "@composer install --no-dev --classmap-authoritative", "@php -dphar.readonly=0 build/server-phar.php" + ], + "update-registry-annotations": [ + "@php build/generate-registry-annotations.php src" ] } } From fd41a0f510ea5425c71b13e236fe63e1b7c22515 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Aug 2021 20:35:25 +0100 Subject: [PATCH 2682/3224] Remove colors from VersionCommand these will have to stay gone for now, until we have some way to terminate formatting codes without breaking logger output. (we need &p!! #4364) --- resources/locale | 2 +- src/command/defaults/VersionCommand.php | 11 +++-------- src/lang/KnownTranslationFactory.php | 18 ++++++------------ 3 files changed, 10 insertions(+), 21 deletions(-) diff --git a/resources/locale b/resources/locale index 26ea57220b..b41efc9044 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 26ea57220b388647c12bed051116b154aa8b88fe +Subproject commit b41efc9044e1f6ab2d5c44ced3203ea18cba0165 diff --git a/src/command/defaults/VersionCommand.php b/src/command/defaults/VersionCommand.php index 8bebadefb7..82fe5e0db6 100644 --- a/src/command/defaults/VersionCommand.php +++ b/src/command/defaults/VersionCommand.php @@ -60,22 +60,18 @@ class VersionCommand extends VanillaCommand{ if(count($args) === 0){ $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_serverSoftwareName( - TextFormat::GREEN, VersionInfo::NAME )); $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_serverSoftwareVersion( - TextFormat::GREEN, VersionInfo::getVersionObj()->getFullVersion(), VersionInfo::getGitHash() )); $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_minecraftVersion( - TextFormat::GREEN, ProtocolInfo::MINECRAFT_VERSION_NETWORK, (string) ProtocolInfo::CURRENT_PROTOCOL )); - $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_phpVersion(TextFormat::GREEN, PHP_VERSION)); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_phpVersion(PHP_VERSION)); - $jitColor = TextFormat::GREEN; if( function_exists('opcache_get_status') && ($opcacheStatus = opcache_get_status(false)) !== false && @@ -86,15 +82,14 @@ class VersionCommand extends VanillaCommand{ $jitStatus = KnownTranslationFactory::pocketmine_command_version_phpJitEnabled( sprintf("CRTO: %s%s%s%s", $jit["opt_flags"] >> 2, $jit["opt_flags"] & 0x03, $jit["kind"], $jit["opt_level"]) ); - $jitColor = TextFormat::YELLOW; }else{ $jitStatus = KnownTranslationFactory::pocketmine_command_version_phpJitDisabled(); } }else{ $jitStatus = KnownTranslationFactory::pocketmine_command_version_phpJitNotSupported(); } - $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_phpJitStatus($jitColor, $sender->getLanguage()->translate($jitStatus))); - $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_operatingSystem(TextFormat::GREEN, Utils::getOS())); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_phpJitStatus($sender->getLanguage()->translate($jitStatus))); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_operatingSystem(Utils::getOS())); }else{ $pluginName = implode(" ", $args); $exactPlugin = $sender->getServer()->getPluginManager()->getPlugin($pluginName); diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index 9c5037377d..7156de7cb2 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -1124,9 +1124,8 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_DESCRIPTION, []); } - public static function pocketmine_command_version_minecraftVersion(string $color, string $minecraftVersion, string $minecraftProtocolVersion) : TranslationContainer{ + public static function pocketmine_command_version_minecraftVersion(string $minecraftVersion, string $minecraftProtocolVersion) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_MINECRAFTVERSION, [ - "color" => $color, "minecraftVersion" => $minecraftVersion, "minecraftProtocolVersion" => $minecraftProtocolVersion, ]); @@ -1136,9 +1135,8 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_NOSUCHPLUGIN, []); } - public static function pocketmine_command_version_operatingSystem(string $color, string $operatingSystemName) : TranslationContainer{ + public static function pocketmine_command_version_operatingSystem(string $operatingSystemName) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_OPERATINGSYSTEM, [ - "color" => $color, "operatingSystemName" => $operatingSystemName, ]); } @@ -1157,30 +1155,26 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPJITNOTSUPPORTED, []); } - public static function pocketmine_command_version_phpJitStatus(string $color, string $jitStatus) : TranslationContainer{ + public static function pocketmine_command_version_phpJitStatus(string $jitStatus) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPJITSTATUS, [ - "color" => $color, "jitStatus" => $jitStatus, ]); } - public static function pocketmine_command_version_phpVersion(string $color, string $phpVersion) : TranslationContainer{ + public static function pocketmine_command_version_phpVersion(string $phpVersion) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPVERSION, [ - "color" => $color, "phpVersion" => $phpVersion, ]); } - public static function pocketmine_command_version_serverSoftwareName(string $color, string $serverSoftwareName) : TranslationContainer{ + public static function pocketmine_command_version_serverSoftwareName(string $serverSoftwareName) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_SERVERSOFTWARENAME, [ - "color" => $color, "serverSoftwareName" => $serverSoftwareName, ]); } - public static function pocketmine_command_version_serverSoftwareVersion(string $color, string $serverSoftwareVersion, string $serverGitHash) : TranslationContainer{ + public static function pocketmine_command_version_serverSoftwareVersion(string $serverSoftwareVersion, string $serverGitHash) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_SERVERSOFTWAREVERSION, [ - "color" => $color, "serverSoftwareVersion" => $serverSoftwareVersion, "serverGitHash" => $serverGitHash, ]); From ce70dc48c0d7003e19d4f1205ef89e541944c76a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Aug 2021 20:37:03 +0100 Subject: [PATCH 2683/3224] composer.json: added update-translation-apis custom command --- composer.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/composer.json b/composer.json index b7a035714b..bac50cf100 100644 --- a/composer.json +++ b/composer.json @@ -86,6 +86,9 @@ ], "update-registry-annotations": [ "@php build/generate-registry-annotations.php src" + ], + "update-translation-apis": [ + "@php build/generate-known-translation-apis.php" ] } } From 483c16cc418f5eed975667e42f77675413b9fef2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Aug 2021 20:42:23 +0100 Subject: [PATCH 2684/3224] Updated to ramsey/uuid 4.2.1 --- composer.lock | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/composer.lock b/composer.lock index cbc17e9309..c24246d388 100644 --- a/composer.lock +++ b/composer.lock @@ -910,16 +910,16 @@ }, { "name": "ramsey/uuid", - "version": "4.1.1", + "version": "4.2.1", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "cd4032040a750077205918c86049aa0f43d22947" + "reference": "fe665a03df4f056aa65af552a96e1976df8c8dae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/cd4032040a750077205918c86049aa0f43d22947", - "reference": "cd4032040a750077205918c86049aa0f43d22947", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/fe665a03df4f056aa65af552a96e1976df8c8dae", + "reference": "fe665a03df4f056aa65af552a96e1976df8c8dae", "shasum": "" }, "require": { @@ -933,26 +933,26 @@ "rhumsaa/uuid": "self.version" }, "require-dev": { - "codeception/aspect-mock": "^3", - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7.0", + "captainhook/captainhook": "^5.10", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "doctrine/annotations": "^1.8", - "goaop/framework": "^2", + "ergebnis/composer-normalize": "^2.15", "mockery/mockery": "^1.3", "moontoast/math": "^1.1", "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.2", "php-mock/php-mock-mockery": "^1.3", - "php-mock/php-mock-phpunit": "^2.5", "php-parallel-lint/php-parallel-lint": "^1.1", - "phpbench/phpbench": "^0.17.1", + "phpbench/phpbench": "^1.0", "phpstan/extension-installer": "^1.0", "phpstan/phpstan": "^0.12", "phpstan/phpstan-mockery": "^0.12", "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^8.5", - "psy/psysh": "^0.10.0", - "slevomat/coding-standard": "^6.0", + "phpunit/phpunit": "^8.5 || ^9", + "slevomat/coding-standard": "^7.0", "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "3.9.4" + "vimeo/psalm": "^4.9" }, "suggest": { "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", @@ -965,7 +965,10 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.x-dev" + "dev-main": "4.x-dev" + }, + "captainhook": { + "force-install": true } }, "autoload": { @@ -981,7 +984,6 @@ "MIT" ], "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", - "homepage": "https://github.com/ramsey/uuid", "keywords": [ "guid", "identifier", @@ -989,16 +991,19 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "rss": "https://github.com/ramsey/uuid/releases.atom", - "source": "https://github.com/ramsey/uuid" + "source": "https://github.com/ramsey/uuid/tree/4.2.1" }, "funding": [ { "url": "https://github.com/ramsey", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", + "type": "tidelift" } ], - "time": "2020-08-18T17:17:46+00:00" + "time": "2021-08-11T01:06:55+00:00" }, { "name": "respect/stringifier", From 27e0ecf7ee6ba4710d8fd38dbe5de8d77aa21f97 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Thu, 12 Aug 2021 23:27:05 +0100 Subject: [PATCH 2685/3224] Implemented Blast Furnace and Smoker (#4362) --- src/block/BlockFactory.php | 12 ++-- src/block/VanillaBlocks.php | 4 ++ src/block/inventory/FurnaceInventory.php | 8 ++- src/block/tile/BlastFurnace.php | 32 +++++++++++ src/block/tile/Furnace.php | 15 +++-- src/block/tile/NormalFurnace.php | 32 +++++++++++ src/block/tile/Smoker.php | 32 +++++++++++ src/block/tile/TileFactory.php | 6 +- src/crafting/CraftingManager.php | 27 +++++---- .../CraftingManagerFromDataHelper.php | 11 +++- src/crafting/FurnaceType.php | 55 +++++++++++++++++++ src/network/mcpe/InventoryManager.php | 10 +++- src/network/mcpe/cache/CraftingDataCache.php | 28 +++++++--- .../block_factory_consistency_check.json | 2 +- 14 files changed, 235 insertions(+), 39 deletions(-) create mode 100644 src/block/tile/BlastFurnace.php create mode 100644 src/block/tile/NormalFurnace.php create mode 100644 src/block/tile/Smoker.php create mode 100644 src/crafting/FurnaceType.php diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 48ff3faee7..98249adf8a 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -32,6 +32,7 @@ use pocketmine\block\tile\Barrel as TileBarrel; use pocketmine\block\tile\Beacon as TileBeacon; use pocketmine\block\tile\Bed as TileBed; use pocketmine\block\tile\Bell as TileBell; +use pocketmine\block\tile\BlastFurnace as TileBlastFurnace; use pocketmine\block\tile\BrewingStand as TileBrewingStand; use pocketmine\block\tile\Chest as TileChest; use pocketmine\block\tile\Comparator as TileComparator; @@ -39,14 +40,15 @@ use pocketmine\block\tile\DaylightSensor as TileDaylightSensor; use pocketmine\block\tile\EnchantTable as TileEnchantingTable; use pocketmine\block\tile\EnderChest as TileEnderChest; use pocketmine\block\tile\FlowerPot as TileFlowerPot; -use pocketmine\block\tile\Furnace as TileFurnace; use pocketmine\block\tile\Hopper as TileHopper; use pocketmine\block\tile\ItemFrame as TileItemFrame; use pocketmine\block\tile\Jukebox as TileJukebox; use pocketmine\block\tile\MonsterSpawner as TileMonsterSpawner; +use pocketmine\block\tile\NormalFurnace as TileNormalFurnace; use pocketmine\block\tile\Note as TileNote; use pocketmine\block\tile\ShulkerBox as TileShulkerBox; use pocketmine\block\tile\Skull as TileSkull; +use pocketmine\block\tile\Smoker as TileSmoker; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\InvalidBlockStateException; use pocketmine\block\utils\SlabType; @@ -200,7 +202,9 @@ class BlockFactory{ $this->remap(Ids::FLOWER_POT_BLOCK, $meta, $flowerPot); } $this->register(new FrostedIce(new BID(Ids::FROSTED_ICE, 0), "Frosted Ice", new BlockBreakInfo(2.5, BlockToolType::PICKAXE))); - $this->register(new Furnace(new BIDFlattened(Ids::FURNACE, [Ids::LIT_FURNACE], 0, null, TileFurnace::class), "Furnace", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->register(new Furnace(new BIDFlattened(Ids::FURNACE, [Ids::LIT_FURNACE], 0, null, TileNormalFurnace::class), "Furnace", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->register(new Furnace(new BIDFlattened(Ids::BLAST_FURNACE, [Ids::LIT_BLAST_FURNACE], 0, null, TileBlastFurnace::class), "Blast Furnace", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->register(new Furnace(new BIDFlattened(Ids::SMOKER, [Ids::LIT_SMOKER], 0, null, TileSmoker::class), "Smoker", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); $glassBreakInfo = new BlockBreakInfo(0.3); $this->register(new Glass(new BID(Ids::GLASS, 0), "Glass", $glassBreakInfo)); @@ -549,7 +553,6 @@ class BlockFactory{ )); //region --- auto-generated TODOs for bedrock-1.11.0 --- - //TODO: minecraft:blast_furnace //TODO: minecraft:bubble_column //TODO: minecraft:campfire //TODO: minecraft:cartography_table @@ -570,8 +573,6 @@ class BlockFactory{ //TODO: minecraft:kelp //TODO: minecraft:lava_cauldron //TODO: minecraft:lectern - //TODO: minecraft:lit_blast_furnace - //TODO: minecraft:lit_smoker //TODO: minecraft:movingBlock //TODO: minecraft:observer //TODO: minecraft:piston @@ -581,7 +582,6 @@ class BlockFactory{ //TODO: minecraft:seagrass //TODO: minecraft:slime //TODO: minecraft:smithing_table - //TODO: minecraft:smoker //TODO: minecraft:sticky_piston //TODO: minecraft:stonecutter_block //TODO: minecraft:structure_block diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 2484634a60..6d752b67fd 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -82,6 +82,7 @@ use function assert; * @method static WallSign BIRCH_WALL_SIGN() * @method static Wood BIRCH_WOOD() * @method static GlazedTerracotta BLACK_GLAZED_TERRACOTTA() + * @method static Furnace BLAST_FURNACE() * @method static GlazedTerracotta BLUE_GLAZED_TERRACOTTA() * @method static BlueIce BLUE_ICE() * @method static Flower BLUE_ORCHID() @@ -487,6 +488,7 @@ use function assert; * @method static SeaLantern SEA_LANTERN() * @method static SeaPickle SEA_PICKLE() * @method static ShulkerBox SHULKER_BOX() + * @method static Furnace SMOKER() * @method static Opaque SMOOTH_QUARTZ() * @method static Slab SMOOTH_QUARTZ_SLAB() * @method static Stair SMOOTH_QUARTZ_STAIRS() @@ -645,6 +647,7 @@ final class VanillaBlocks{ self::register("birch_wall_sign", $factory->get(442, 2)); self::register("birch_wood", $factory->get(467, 2)); self::register("black_glazed_terracotta", $factory->get(235, 2)); + self::register("blast_furnace", $factory->get(451, 2)); self::register("blue_glazed_terracotta", $factory->get(231, 2)); self::register("blue_ice", $factory->get(266, 0)); self::register("blue_orchid", $factory->get(38, 1)); @@ -1050,6 +1053,7 @@ final class VanillaBlocks{ self::register("sea_lantern", $factory->get(169, 0)); self::register("sea_pickle", $factory->get(411, 0)); self::register("shulker_box", $factory->get(205, 0)); + self::register("smoker", $factory->get(453, 2)); self::register("smooth_quartz", $factory->get(155, 3)); self::register("smooth_quartz_slab", $factory->get(421, 1)); self::register("smooth_quartz_stairs", $factory->get(440, 0)); diff --git a/src/block/inventory/FurnaceInventory.php b/src/block/inventory/FurnaceInventory.php index eb2f522047..bece0b61c7 100644 --- a/src/block/inventory/FurnaceInventory.php +++ b/src/block/inventory/FurnaceInventory.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block\inventory; +use pocketmine\crafting\FurnaceType; use pocketmine\inventory\SimpleInventory; use pocketmine\item\Item; use pocketmine\world\Position; @@ -30,11 +31,16 @@ use pocketmine\world\Position; class FurnaceInventory extends SimpleInventory implements BlockInventory{ use BlockInventoryTrait; - public function __construct(Position $holder){ + private FurnaceType $furnaceType; + + public function __construct(Position $holder, FurnaceType $furnaceType){ $this->holder = $holder; + $this->furnaceType = $furnaceType; parent::__construct(3); } + public function getFurnaceType() : FurnaceType{ return $this->furnaceType; } + public function getResult() : Item{ return $this->getItem(2); } diff --git a/src/block/tile/BlastFurnace.php b/src/block/tile/BlastFurnace.php new file mode 100644 index 0000000000..ded48d7106 --- /dev/null +++ b/src/block/tile/BlastFurnace.php @@ -0,0 +1,32 @@ +inventory = new FurnaceInventory($this->pos); + $this->inventory = new FurnaceInventory($this->pos, $this->getFurnaceType()); $this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange( static function(Inventory $unused) use ($world, $pos) : void{ $world->scheduleDelayedBlockUpdate($pos, 1); @@ -148,6 +149,8 @@ class Furnace extends Spawnable implements Container, Nameable{ } } + abstract public function getFurnaceType() : FurnaceType; + public function onUpdate() : bool{ //TODO: move this to Block if($this->closed){ @@ -165,7 +168,9 @@ class Furnace extends Spawnable implements Container, Nameable{ $fuel = $this->inventory->getFuel(); $raw = $this->inventory->getSmelting(); $product = $this->inventory->getResult(); - $smelt = $this->pos->getWorld()->getServer()->getCraftingManager()->getFurnaceRecipeManager()->match($raw); + + $furnaceType = $this->getFurnaceType(); + $smelt = $this->pos->getWorld()->getServer()->getCraftingManager()->getFurnaceRecipeManager($furnaceType)->match($raw); $canSmelt = ($smelt instanceof FurnaceRecipe and $raw->getCount() > 0 and (($smelt->getResult()->equals($product) and $product->getCount() < $product->getMaxStackSize()) or $product->isNull())); if($this->remainingFuelTime <= 0 and $canSmelt and $fuel->getFuelTime() > 0 and $fuel->getCount() > 0){ @@ -178,7 +183,7 @@ class Furnace extends Spawnable implements Container, Nameable{ if($smelt instanceof FurnaceRecipe and $canSmelt){ ++$this->cookTime; - if($this->cookTime >= 200){ //10 seconds + if($this->cookTime >= $furnaceType->getCookDurationTicks()){ $product = $smelt->getResult()->setCount($product->getCount() + 1); $ev = new FurnaceSmeltEvent($this, $raw, $product); @@ -190,7 +195,7 @@ class Furnace extends Spawnable implements Container, Nameable{ $this->inventory->setSmelting($raw); } - $this->cookTime -= 200; + $this->cookTime -= $furnaceType->getCookDurationTicks(); } }elseif($this->remainingFuelTime <= 0){ $this->remainingFuelTime = $this->cookTime = $this->maxFuelTime = 0; diff --git a/src/block/tile/NormalFurnace.php b/src/block/tile/NormalFurnace.php new file mode 100644 index 0000000000..c5c17e5e5f --- /dev/null +++ b/src/block/tile/NormalFurnace.php @@ -0,0 +1,32 @@ +register(Beacon::class, ["Beacon", "minecraft:beacon"]); $this->register(Bed::class, ["Bed", "minecraft:bed"]); $this->register(Bell::class, ["Bell", "minecraft:bell"]); + $this->register(BlastFurnace::class, ["BlastFurnace", "minecraft:blast_furnace"]); $this->register(BrewingStand::class, ["BrewingStand", "minecraft:brewing_stand"]); $this->register(Chest::class, ["Chest", "minecraft:chest"]); $this->register(Comparator::class, ["Comparator", "minecraft:comparator"]); @@ -61,7 +62,7 @@ final class TileFactory{ $this->register(EnchantTable::class, ["EnchantTable", "minecraft:enchanting_table"]); $this->register(EnderChest::class, ["EnderChest", "minecraft:ender_chest"]); $this->register(FlowerPot::class, ["FlowerPot", "minecraft:flower_pot"]); - $this->register(Furnace::class, ["Furnace", "minecraft:furnace"]); + $this->register(NormalFurnace::class, ["Furnace", "minecraft:furnace"]); $this->register(Hopper::class, ["Hopper", "minecraft:hopper"]); $this->register(ItemFrame::class, ["ItemFrame"]); //this is an entity in PC $this->register(Jukebox::class, ["Jukebox", "RecordPlayer", "minecraft:jukebox"]); @@ -69,9 +70,9 @@ final class TileFactory{ $this->register(Note::class, ["Music", "minecraft:noteblock"]); $this->register(ShulkerBox::class, ["ShulkerBox", "minecraft:shulker_box"]); $this->register(Sign::class, ["Sign", "minecraft:sign"]); + $this->register(Smoker::class, ["Smoker", "minecraft:smoker"]); $this->register(Skull::class, ["Skull", "minecraft:skull"]); - //TODO: BlastFurnace //TODO: Campfire //TODO: Cauldron //TODO: ChalkboardBlock @@ -87,7 +88,6 @@ final class TileFactory{ //TODO: MovingBlock //TODO: NetherReactor //TODO: PistonArm - //TODO: Smoker //TODO: StructureBlock } diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index c05dfc5e4d..578db78d7c 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -37,8 +37,11 @@ class CraftingManager{ /** @var ShapelessRecipe[][] */ protected $shapelessRecipes = []; - /** @var FurnaceRecipeManager */ - protected $furnaceRecipeManager; + /** + * @var FurnaceRecipeManager[] + * @phpstan-var array + */ + protected $furnaceRecipeManagers; /** * @var ObjectSet @@ -48,14 +51,18 @@ class CraftingManager{ public function __construct(){ $this->recipeRegisteredCallbacks = new ObjectSet(); - $this->furnaceRecipeManager = new FurnaceRecipeManager(); + foreach(FurnaceType::getAll() as $furnaceType){ + $this->furnaceRecipeManagers[$furnaceType->id()] = new FurnaceRecipeManager(); + } $recipeRegisteredCallbacks = $this->recipeRegisteredCallbacks; - $this->furnaceRecipeManager->getRecipeRegisteredCallbacks()->add(static function(FurnaceRecipe $recipe) use ($recipeRegisteredCallbacks) : void{ - foreach($recipeRegisteredCallbacks as $callback){ - $callback(); - } - }); + foreach($this->furnaceRecipeManagers as $furnaceRecipeManager){ + $furnaceRecipeManager->getRecipeRegisteredCallbacks()->add(static function(FurnaceRecipe $recipe) use ($recipeRegisteredCallbacks) : void{ + foreach($recipeRegisteredCallbacks as $callback){ + $callback(); + } + }); + } } /** @phpstan-return ObjectSet<\Closure() : void> */ @@ -123,8 +130,8 @@ class CraftingManager{ return $this->shapedRecipes; } - public function getFurnaceRecipeManager() : FurnaceRecipeManager{ - return $this->furnaceRecipeManager; + public function getFurnaceRecipeManager(FurnaceType $furnaceType) : FurnaceRecipeManager{ + return $this->furnaceRecipeManagers[$furnaceType->id()]; } public function registerShapedRecipe(ShapedRecipe $recipe) : void{ diff --git a/src/crafting/CraftingManagerFromDataHelper.php b/src/crafting/CraftingManagerFromDataHelper.php index 5cc41e9997..6660bb6024 100644 --- a/src/crafting/CraftingManagerFromDataHelper.php +++ b/src/crafting/CraftingManagerFromDataHelper.php @@ -61,10 +61,17 @@ final class CraftingManagerFromDataHelper{ )); } foreach($recipes["smelting"] as $recipe){ - if($recipe["block"] !== "furnace"){ //TODO: filter others out for now to avoid breaking economics + $furnaceType = match ($recipe["block"]){ + "furnace" => FurnaceType::FURNACE(), + "blast_furnace" => FurnaceType::BLAST_FURNACE(), + "smoker" => FurnaceType::SMOKER(), + //TODO: campfire + default => null + }; + if($furnaceType === null){ continue; } - $result->getFurnaceRecipeManager()->register(new FurnaceRecipe( + $result->getFurnaceRecipeManager($furnaceType)->register(new FurnaceRecipe( Item::jsonDeserialize($recipe["output"]), Item::jsonDeserialize($recipe["input"])) ); diff --git a/src/crafting/FurnaceType.php b/src/crafting/FurnaceType.php new file mode 100644 index 0000000000..d68702f10a --- /dev/null +++ b/src/crafting/FurnaceType.php @@ -0,0 +1,55 @@ +Enum___construct($enumName); + } + + public function getCookDurationTicks() : int{ return $this->cookDurationTicks; } +} diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index 814f6be86f..4cc8d1e466 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -30,6 +30,7 @@ use pocketmine\block\inventory\EnchantInventory; use pocketmine\block\inventory\FurnaceInventory; use pocketmine\block\inventory\HopperInventory; use pocketmine\block\inventory\LoomInventory; +use pocketmine\crafting\FurnaceType; use pocketmine\inventory\CreativeInventory; use pocketmine\inventory\Inventory; use pocketmine\inventory\transaction\action\SlotChangeAction; @@ -49,6 +50,7 @@ use pocketmine\network\mcpe\protocol\types\inventory\CreativeContentEntry; use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper; use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes; use pocketmine\player\Player; +use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\ObjectSet; use function array_map; use function array_search; @@ -166,8 +168,12 @@ class InventoryManager{ case $inv instanceof LoomInventory: return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::LOOM, $inv->getHolder())]; case $inv instanceof FurnaceInventory: - //TODO: specialized furnace types - return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::FURNACE, $inv->getHolder())]; + return match($inv->getFurnaceType()->id()){ + FurnaceType::FURNACE()->id() => [ContainerOpenPacket::blockInvVec3($id, WindowTypes::FURNACE, $inv->getHolder())], + FurnaceType::BLAST_FURNACE()->id() => [ContainerOpenPacket::blockInvVec3($id, WindowTypes::BLAST_FURNACE, $inv->getHolder())], + FurnaceType::SMOKER()->id() => [ContainerOpenPacket::blockInvVec3($id, WindowTypes::SMOKER, $inv->getHolder())], + default => throw new AssumptionFailedError("Unreachable") + }; case $inv instanceof EnchantInventory: return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::ENCHANTMENT, $inv->getHolder())]; case $inv instanceof BrewingStandInventory: diff --git a/src/network/mcpe/cache/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php index 275e1ac20e..22dfde37bf 100644 --- a/src/network/mcpe/cache/CraftingDataCache.php +++ b/src/network/mcpe/cache/CraftingDataCache.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\cache; use pocketmine\crafting\CraftingManager; +use pocketmine\crafting\FurnaceType; use pocketmine\item\Item; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\CraftingDataPacket; @@ -33,6 +34,7 @@ use pocketmine\network\mcpe\protocol\types\recipe\RecipeIngredient; use pocketmine\network\mcpe\protocol\types\recipe\ShapedRecipe as ProtocolShapedRecipe; use pocketmine\network\mcpe\protocol\types\recipe\ShapelessRecipe as ProtocolShapelessRecipe; use pocketmine\timings\Timings; +use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Binary; use pocketmine\utils\SingletonTrait; use Ramsey\Uuid\Uuid; @@ -115,15 +117,23 @@ final class CraftingDataCache{ } } - foreach($manager->getFurnaceRecipeManager()->getAll() as $recipe){ - $input = $converter->coreItemStackToNet($recipe->getInput()); - $pk->entries[] = new ProtocolFurnaceRecipe( - CraftingDataPacket::ENTRY_FURNACE_DATA, - $input->getId(), - $input->getMeta(), - $converter->coreItemStackToNet($recipe->getResult()), - "furnace" - ); + foreach(FurnaceType::getAll() as $furnaceType){ + $typeTag = match($furnaceType->id()){ + FurnaceType::FURNACE()->id() => "furnace", + FurnaceType::BLAST_FURNACE()->id() => "blast_furnace", + FurnaceType::SMOKER()->id() => "smoker", + default => throw new AssumptionFailedError("Unreachable"), + }; + foreach($manager->getFurnaceRecipeManager($furnaceType)->getAll() as $recipe){ + $input = $converter->coreItemStackToNet($recipe->getInput()); + $pk->entries[] = new ProtocolFurnaceRecipe( + CraftingDataPacket::ENTRY_FURNACE_DATA, + $input->getId(), + $input->getMeta(), + $converter->coreItemStackToNet($recipe->getResult()), + $typeTag + ); + } } Timings::$craftingDataCacheRebuild->stopTiming(); diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 46ea7ad974..fec39fedf7 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"knownStates":{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","497":"Tall Grass","498":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1614":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3280":"Shulker Box","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3488":"Dyed Shulker Box","3489":"Dyed Shulker Box","3490":"Dyed Shulker Box","3491":"Dyed Shulker Box","3492":"Dyed Shulker Box","3493":"Dyed Shulker Box","3494":"Dyed Shulker Box","3495":"Dyed Shulker Box","3496":"Dyed Shulker Box","3497":"Dyed Shulker Box","3498":"Dyed Shulker Box","3499":"Dyed Shulker Box","3500":"Dyed Shulker Box","3501":"Dyed Shulker Box","3502":"Dyed Shulker Box","3503":"Dyed Shulker Box","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6274":"Wall Coral Fan","6276":"Wall Coral Fan","6278":"Wall Coral Fan","6280":"Wall Coral Fan","6282":"Wall Coral Fan","6284":"Wall Coral Fan","6286":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7376":"Bell","7377":"Bell","7378":"Bell","7379":"Bell","7380":"Bell","7381":"Bell","7382":"Bell","7383":"Bell","7384":"Bell","7385":"Bell","7386":"Bell","7387":"Bell","7388":"Bell","7389":"Bell","7390":"Bell","7391":"Bell","7392":"Sweet Berry Bush","7393":"Sweet Berry Bush","7394":"Sweet Berry Bush","7395":"Sweet Berry Bush","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood","7480":"Stripped Oak Wood","7481":"Stripped Spruce Wood","7482":"Stripped Birch Wood","7483":"Stripped Jungle Wood","7484":"Stripped Acacia Wood","7485":"Stripped Dark Oak Wood"},"remaps":{"284":7472,"285":7473,"286":7474,"287":7475,"438":432,"439":432,"446":432,"447":432,"454":448,"455":448,"462":448,"463":448,"496":498,"499":498,"696":688,"697":689,"698":690,"699":691,"700":692,"701":693,"702":694,"703":695,"800":805,"806":805,"807":805,"864":866,"865":866,"870":866,"871":866,"976":978,"977":978,"982":978,"983":978,"992":978,"993":978,"998":978,"999":978,"1036":1027,"1037":1027,"1038":1027,"1039":1027,"1040":1042,"1041":1042,"1046":1042,"1047":1042,"1066":1056,"1067":1056,"1068":1056,"1069":1056,"1070":1056,"1071":1056,"1088":1090,"1089":1090,"1094":1090,"1095":1090,"1148":1139,"1149":1139,"1150":1139,"1151":1139,"1200":1221,"1206":1221,"1207":1221,"1216":1221,"1222":1221,"1223":1221,"1238":1232,"1239":1232,"1246":1232,"1247":1232,"1377":1376,"1378":1376,"1379":1376,"1440":1441,"1443":1441,"1479":1472,"1595":1598,"1596":1598,"1597":1598,"1610":1594,"1611":1614,"1612":1614,"1613":1614,"1615":1599,"2022":2016,"2023":2016,"2030":2016,"2031":2016,"2044":2032,"2045":2032,"2046":2032,"2047":2032,"2080":2082,"2081":2082,"2086":2082,"2087":2082,"2241":2240,"2242":2240,"2243":2240,"2244":2240,"2245":2240,"2246":2240,"2247":2240,"2248":2240,"2249":2240,"2250":2240,"2251":2240,"2252":2240,"2253":2240,"2254":2240,"2255":2240,"2294":2288,"2295":2288,"2302":2288,"2303":2288,"2304":2306,"2310":2306,"2311":2306,"2312":2306,"2313":2306,"2314":2306,"2315":2306,"2316":2306,"2317":2306,"2318":2306,"2319":2306,"2332":2322,"2333":2322,"2334":2322,"2335":2322,"2336":2338,"2337":2338,"2342":2338,"2343":2338,"2392":2386,"2393":2386,"2394":2386,"2395":2386,"2396":2386,"2397":2386,"2398":2386,"2399":2386,"2400":2386,"2401":2386,"2402":2386,"2403":2386,"2404":2386,"2405":2386,"2406":2386,"2407":2386,"2465":2464,"2470":2464,"2471":2464,"2473":2464,"2478":2464,"2479":2464,"2493":2481,"2494":2482,"2520":2512,"2521":2513,"2522":2514,"2523":2515,"2524":2516,"2525":2517,"2604":7476,"2605":7477,"2732":2720,"2832":2834,"2833":2834,"2838":2834,"2839":2834,"2904":2896,"2905":2897,"2906":2898,"2907":2899,"2908":2900,"2909":2901,"2910":2902,"2911":2903,"3100":3091,"3101":3091,"3102":3091,"3103":3091,"3116":3107,"3117":3107,"3118":3107,"3119":3107,"3132":3123,"3133":3123,"3134":3123,"3135":3123,"3148":3139,"3149":3139,"3150":3139,"3151":3139,"3164":3155,"3165":3155,"3166":3155,"3167":3155,"3230":3218,"3232":3237,"3238":3237,"3239":3237,"3240":3245,"3246":3245,"3247":3245,"3264":3269,"3270":3269,"3271":3269,"3272":3277,"3278":3277,"3279":3277,"3334":3328,"3335":3328,"3468":3456,"3504":3506,"3505":3506,"3510":3506,"3511":3506,"3520":3522,"3521":3522,"3526":3522,"3527":3522,"3536":3538,"3537":3538,"3542":3538,"3543":3538,"3552":3554,"3553":3554,"3558":3554,"3559":3554,"3568":3570,"3569":3570,"3574":3570,"3575":3570,"3584":3586,"3585":3586,"3590":3586,"3591":3586,"3600":3602,"3601":3602,"3606":3602,"3607":3602,"3616":3618,"3617":3618,"3622":3618,"3623":3618,"3632":3634,"3633":3634,"3638":3634,"3639":3634,"3648":3650,"3649":3650,"3654":3650,"3655":3650,"3664":3666,"3665":3666,"3670":3666,"3671":3666,"3696":3698,"3697":3698,"3702":3698,"3703":3698,"3712":3714,"3713":3714,"3718":3714,"3719":3714,"3728":3730,"3729":3730,"3734":3730,"3735":3730,"3744":3746,"3745":3746,"3750":3746,"3751":3746,"3760":3762,"3761":3762,"3766":3762,"3767":3762,"3824":3829,"3830":3829,"3831":3829,"3955":3952,"4163":4160,"4179":4176,"4195":4192,"4211":4208,"4227":4224,"4243":4240,"6181":6176,"6182":6176,"6183":6176,"6197":6192,"6198":6192,"6199":6192,"6205":6192,"6206":6192,"6207":6192,"6213":6208,"6214":6208,"6215":6208,"6221":6208,"6222":6208,"6223":6208,"6229":6208,"6230":6208,"6231":6208,"6237":6208,"6238":6208,"6239":6208,"6273":6248,"6275":6248,"6277":6248,"6279":6248,"6281":6248,"6283":6248,"6285":6248,"6287":6248,"6326":6320,"6327":6320,"6334":6320,"6335":6320,"6342":6336,"6343":6336,"6350":6336,"6351":6336,"6358":6352,"6359":6352,"6366":6352,"6367":6352,"6374":6368,"6375":6368,"6382":6368,"6383":6368,"6390":6384,"6391":6384,"6398":6384,"6399":6384,"6694":6688,"6695":6688,"6702":6688,"6703":6688,"6760":6752,"6761":6753,"6762":6754,"6763":6755,"6764":6756,"6765":6757,"6766":6758,"6767":6759,"6776":6768,"6777":6769,"6778":6770,"6779":6771,"6780":6772,"6992":6994,"6993":6994,"6998":6994,"6999":6994,"7072":7074,"7073":7074,"7078":7074,"7079":7074,"7104":7106,"7105":7106,"7110":7106,"7111":7106,"7136":7138,"7137":7138,"7142":7138,"7143":7138,"7168":7170,"7169":7170,"7174":7170,"7175":7170,"7334":7328,"7335":7328,"7342":7328,"7343":7328,"7396":7392,"7397":7392,"7398":7392,"7399":7392}} \ No newline at end of file +{"knownStates":{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","497":"Tall Grass","498":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1614":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3280":"Shulker Box","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3488":"Dyed Shulker Box","3489":"Dyed Shulker Box","3490":"Dyed Shulker Box","3491":"Dyed Shulker Box","3492":"Dyed Shulker Box","3493":"Dyed Shulker Box","3494":"Dyed Shulker Box","3495":"Dyed Shulker Box","3496":"Dyed Shulker Box","3497":"Dyed Shulker Box","3498":"Dyed Shulker Box","3499":"Dyed Shulker Box","3500":"Dyed Shulker Box","3501":"Dyed Shulker Box","3502":"Dyed Shulker Box","3503":"Dyed Shulker Box","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6274":"Wall Coral Fan","6276":"Wall Coral Fan","6278":"Wall Coral Fan","6280":"Wall Coral Fan","6282":"Wall Coral Fan","6284":"Wall Coral Fan","6286":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7218":"Blast Furnace","7219":"Blast Furnace","7220":"Blast Furnace","7221":"Blast Furnace","7250":"Smoker","7251":"Smoker","7252":"Smoker","7253":"Smoker","7266":"Smoker","7267":"Smoker","7268":"Smoker","7269":"Smoker","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7376":"Bell","7377":"Bell","7378":"Bell","7379":"Bell","7380":"Bell","7381":"Bell","7382":"Bell","7383":"Bell","7384":"Bell","7385":"Bell","7386":"Bell","7387":"Bell","7388":"Bell","7389":"Bell","7390":"Bell","7391":"Bell","7392":"Sweet Berry Bush","7393":"Sweet Berry Bush","7394":"Sweet Berry Bush","7395":"Sweet Berry Bush","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood","7480":"Stripped Oak Wood","7481":"Stripped Spruce Wood","7482":"Stripped Birch Wood","7483":"Stripped Jungle Wood","7484":"Stripped Acacia Wood","7485":"Stripped Dark Oak Wood","7506":"Blast Furnace","7507":"Blast Furnace","7508":"Blast Furnace","7509":"Blast Furnace"},"remaps":{"284":7472,"285":7473,"286":7474,"287":7475,"438":432,"439":432,"446":432,"447":432,"454":448,"455":448,"462":448,"463":448,"496":498,"499":498,"696":688,"697":689,"698":690,"699":691,"700":692,"701":693,"702":694,"703":695,"800":805,"806":805,"807":805,"864":866,"865":866,"870":866,"871":866,"976":978,"977":978,"982":978,"983":978,"992":978,"993":978,"998":978,"999":978,"1036":1027,"1037":1027,"1038":1027,"1039":1027,"1040":1042,"1041":1042,"1046":1042,"1047":1042,"1066":1056,"1067":1056,"1068":1056,"1069":1056,"1070":1056,"1071":1056,"1088":1090,"1089":1090,"1094":1090,"1095":1090,"1148":1139,"1149":1139,"1150":1139,"1151":1139,"1200":1221,"1206":1221,"1207":1221,"1216":1221,"1222":1221,"1223":1221,"1238":1232,"1239":1232,"1246":1232,"1247":1232,"1377":1376,"1378":1376,"1379":1376,"1440":1441,"1443":1441,"1479":1472,"1595":1598,"1596":1598,"1597":1598,"1610":1594,"1611":1614,"1612":1614,"1613":1614,"1615":1599,"2022":2016,"2023":2016,"2030":2016,"2031":2016,"2044":2032,"2045":2032,"2046":2032,"2047":2032,"2080":2082,"2081":2082,"2086":2082,"2087":2082,"2241":2240,"2242":2240,"2243":2240,"2244":2240,"2245":2240,"2246":2240,"2247":2240,"2248":2240,"2249":2240,"2250":2240,"2251":2240,"2252":2240,"2253":2240,"2254":2240,"2255":2240,"2294":2288,"2295":2288,"2302":2288,"2303":2288,"2304":2306,"2310":2306,"2311":2306,"2312":2306,"2313":2306,"2314":2306,"2315":2306,"2316":2306,"2317":2306,"2318":2306,"2319":2306,"2332":2322,"2333":2322,"2334":2322,"2335":2322,"2336":2338,"2337":2338,"2342":2338,"2343":2338,"2392":2386,"2393":2386,"2394":2386,"2395":2386,"2396":2386,"2397":2386,"2398":2386,"2399":2386,"2400":2386,"2401":2386,"2402":2386,"2403":2386,"2404":2386,"2405":2386,"2406":2386,"2407":2386,"2465":2464,"2470":2464,"2471":2464,"2473":2464,"2478":2464,"2479":2464,"2493":2481,"2494":2482,"2520":2512,"2521":2513,"2522":2514,"2523":2515,"2524":2516,"2525":2517,"2604":7476,"2605":7477,"2732":2720,"2832":2834,"2833":2834,"2838":2834,"2839":2834,"2904":2896,"2905":2897,"2906":2898,"2907":2899,"2908":2900,"2909":2901,"2910":2902,"2911":2903,"3100":3091,"3101":3091,"3102":3091,"3103":3091,"3116":3107,"3117":3107,"3118":3107,"3119":3107,"3132":3123,"3133":3123,"3134":3123,"3135":3123,"3148":3139,"3149":3139,"3150":3139,"3151":3139,"3164":3155,"3165":3155,"3166":3155,"3167":3155,"3230":3218,"3232":3237,"3238":3237,"3239":3237,"3240":3245,"3246":3245,"3247":3245,"3264":3269,"3270":3269,"3271":3269,"3272":3277,"3278":3277,"3279":3277,"3334":3328,"3335":3328,"3468":3456,"3504":3506,"3505":3506,"3510":3506,"3511":3506,"3520":3522,"3521":3522,"3526":3522,"3527":3522,"3536":3538,"3537":3538,"3542":3538,"3543":3538,"3552":3554,"3553":3554,"3558":3554,"3559":3554,"3568":3570,"3569":3570,"3574":3570,"3575":3570,"3584":3586,"3585":3586,"3590":3586,"3591":3586,"3600":3602,"3601":3602,"3606":3602,"3607":3602,"3616":3618,"3617":3618,"3622":3618,"3623":3618,"3632":3634,"3633":3634,"3638":3634,"3639":3634,"3648":3650,"3649":3650,"3654":3650,"3655":3650,"3664":3666,"3665":3666,"3670":3666,"3671":3666,"3696":3698,"3697":3698,"3702":3698,"3703":3698,"3712":3714,"3713":3714,"3718":3714,"3719":3714,"3728":3730,"3729":3730,"3734":3730,"3735":3730,"3744":3746,"3745":3746,"3750":3746,"3751":3746,"3760":3762,"3761":3762,"3766":3762,"3767":3762,"3824":3829,"3830":3829,"3831":3829,"3955":3952,"4163":4160,"4179":4176,"4195":4192,"4211":4208,"4227":4224,"4243":4240,"6181":6176,"6182":6176,"6183":6176,"6197":6192,"6198":6192,"6199":6192,"6205":6192,"6206":6192,"6207":6192,"6213":6208,"6214":6208,"6215":6208,"6221":6208,"6222":6208,"6223":6208,"6229":6208,"6230":6208,"6231":6208,"6237":6208,"6238":6208,"6239":6208,"6273":6248,"6275":6248,"6277":6248,"6279":6248,"6281":6248,"6283":6248,"6285":6248,"6287":6248,"6326":6320,"6327":6320,"6334":6320,"6335":6320,"6342":6336,"6343":6336,"6350":6336,"6351":6336,"6358":6352,"6359":6352,"6366":6352,"6367":6352,"6374":6368,"6375":6368,"6382":6368,"6383":6368,"6390":6384,"6391":6384,"6398":6384,"6399":6384,"6694":6688,"6695":6688,"6702":6688,"6703":6688,"6760":6752,"6761":6753,"6762":6754,"6763":6755,"6764":6756,"6765":6757,"6766":6758,"6767":6759,"6776":6768,"6777":6769,"6778":6770,"6779":6771,"6780":6772,"6992":6994,"6993":6994,"6998":6994,"6999":6994,"7072":7074,"7073":7074,"7078":7074,"7079":7074,"7104":7106,"7105":7106,"7110":7106,"7111":7106,"7136":7138,"7137":7138,"7142":7138,"7143":7138,"7168":7170,"7169":7170,"7174":7170,"7175":7170,"7216":7218,"7217":7218,"7222":7218,"7223":7218,"7248":7250,"7249":7250,"7254":7250,"7255":7250,"7264":7250,"7265":7250,"7270":7250,"7271":7250,"7334":7328,"7335":7328,"7342":7328,"7343":7328,"7396":7392,"7397":7392,"7398":7392,"7399":7392,"7504":7218,"7505":7218,"7510":7218,"7511":7218}} \ No newline at end of file From 58bc9332cdcd5565d086191e5e38313de9c0a7ff Mon Sep 17 00:00:00 2001 From: Rush2929 <76860328+Rush2929@users.noreply.github.com> Date: Fri, 13 Aug 2021 07:27:53 +0900 Subject: [PATCH 2686/3224] Workaround for offhand sync (#4359) fixes #4231 --- src/network/mcpe/InventoryManager.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index 4cc8d1e466..67931b7d0a 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -215,7 +215,17 @@ class InventoryManager{ $currentItem = $inventory->getItem($slot); $clientSideItem = $this->initiatedSlotChanges[$windowId][$slot] ?? null; if($clientSideItem === null or !$clientSideItem->equalsExact($currentItem)){ - $this->session->sendDataPacket(InventorySlotPacket::create($windowId, $slot, ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($currentItem)))); + $itemStackWrapper = ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($currentItem)); + if($windowId === ContainerIds::OFFHAND){ + //TODO: HACK! + //The client may sometimes ignore the InventorySlotPacket for the offhand slot. + //This can cause a lot of problems (totems, arrows, and more...). + //The workaround is to send an InventoryContentPacket instead + //BDS (Bedrock Dedicated Server) also seems to work this way. + $this->session->sendDataPacket(InventoryContentPacket::create($windowId, [$itemStackWrapper])); + }else{ + $this->session->sendDataPacket(InventorySlotPacket::create($windowId, $slot, $itemStackWrapper)); + } } unset($this->initiatedSlotChanges[$windowId][$slot]); } From d30371be116b425817f6a18be09f7f1b64761609 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Aug 2021 23:31:37 +0100 Subject: [PATCH 2687/3224] Command: Assume that TranslationContainer->getText() returns a valid translation key there's no reason for it not to be. --- src/command/Command.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command/Command.php b/src/command/Command.php index c7ce225c82..7972638af7 100644 --- a/src/command/Command.php +++ b/src/command/Command.php @@ -234,7 +234,7 @@ abstract class Command{ public static function broadcastCommandMessage(CommandSender $source, TranslationContainer|string $message, bool $sendToSource = true) : void{ $users = $source->getServer()->getBroadcastChannelSubscribers(Server::BROADCAST_CHANNEL_ADMINISTRATIVE); if($message instanceof TranslationContainer){ - $formatted = "[" . $source->getName() . ": " . ($source->getLanguage()->get($message->getText()) !== $message->getText() ? "%" : "") . $message->getText() . "]"; + $formatted = "[" . $source->getName() . ": %" . $message->getText() . "]"; $result = new TranslationContainer($formatted, $message->getParameters()); $colored = new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . $formatted, $message->getParameters()); From a59ac522ee3525cee1822dac2b85541a2c337aad Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Aug 2021 23:35:45 +0100 Subject: [PATCH 2688/3224] Terminal: do not assume that an array given to toANSI() is actually a tokenized string this is a far stretch, since the documentation doesn't mention that the string needs to be tokenized. Anyone passing an array in here is most likely doing so by mistake. --- src/utils/Terminal.php | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/utils/Terminal.php b/src/utils/Terminal.php index f76aef6e41..041e475c3d 100644 --- a/src/utils/Terminal.php +++ b/src/utils/Terminal.php @@ -27,7 +27,6 @@ use function fclose; use function fopen; use function function_exists; use function getenv; -use function is_array; use function sapi_windows_vt100_support; use function stream_isatty; use const PHP_EOL; @@ -177,16 +176,10 @@ abstract class Terminal{ /** * Returns a string with colorized ANSI Escape codes for the current terminal * Note that this is platform-dependent and might produce different results depending on the terminal type and/or OS. - * - * @param string|string[] $string */ - public static function toANSI($string) : string{ - if(!is_array($string)){ - $string = TextFormat::tokenize($string); - } - + public static function toANSI(string $string) : string{ $newString = ""; - foreach($string as $token){ + foreach(TextFormat::tokenize($string) as $token){ $newString .= match($token){ TextFormat::BOLD => Terminal::$FORMAT_BOLD, TextFormat::OBFUSCATED => Terminal::$FORMAT_OBFUSCATED, From 34309bc81055a2efea11fa4c1538dd074d96e009 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Aug 2021 23:37:00 +0100 Subject: [PATCH 2689/3224] TextFormat: do not assume that an array given to toHTML() is actually a tokenized string this is a far stretch, since the documentation doesn't mention that the string needs to be tokenized. Anyone passing an array in here is most likely doing so by mistake. --- src/utils/TextFormat.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/utils/TextFormat.php b/src/utils/TextFormat.php index cd25a21812..40c37b91ce 100644 --- a/src/utils/TextFormat.php +++ b/src/utils/TextFormat.php @@ -159,16 +159,11 @@ abstract class TextFormat{ /** * Returns an HTML-formatted string with colors/markup - * - * @param string|string[] $string */ - public static function toHTML($string) : string{ - if(!is_array($string)){ - $string = self::tokenize($string); - } + public static function toHTML(string $string) : string{ $newString = ""; $tokens = 0; - foreach($string as $token){ + foreach(self::tokenize($string) as $token){ switch($token){ case TextFormat::BOLD: $newString .= ""; From e907c70160aa756da55744224936d3f29dc6b5e1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Aug 2021 23:37:24 +0100 Subject: [PATCH 2690/3224] ... --- src/utils/TextFormat.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utils/TextFormat.php b/src/utils/TextFormat.php index 40c37b91ce..66189078c2 100644 --- a/src/utils/TextFormat.php +++ b/src/utils/TextFormat.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\utils; -use function is_array; use function mb_scrub; use function preg_last_error; use function preg_quote; From 0e0bbdfb7065695ce2e32721517aa9ad414f7532 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Aug 2021 23:52:39 +0100 Subject: [PATCH 2691/3224] Use typed properties in Server --- src/Server.php | 143 ++++++++++++++++++------------------------------- 1 file changed, 51 insertions(+), 92 deletions(-) diff --git a/src/Server.php b/src/Server.php index ad23df82b8..cdc075d7f7 100644 --- a/src/Server.php +++ b/src/Server.php @@ -164,134 +164,93 @@ class Server{ public const BROADCAST_CHANNEL_ADMINISTRATIVE = "pocketmine.broadcast.admin"; public const BROADCAST_CHANNEL_USERS = "pocketmine.broadcast.user"; - /** @var Server|null */ - private static $instance = null; + private static ?Server $instance = null; - /** @var SleeperHandler */ - private $tickSleeper; + private SleeperHandler $tickSleeper; - /** @var BanList */ - private $banByName; + private BanList $banByName; - /** @var BanList */ - private $banByIP; + private BanList $banByIP; - /** @var Config */ - private $operators; + private Config $operators; - /** @var Config */ - private $whitelist; + private Config $whitelist; - /** @var bool */ - private $isRunning = true; + private bool $isRunning = true; - /** @var bool */ - private $hasStopped = false; + private bool $hasStopped = false; - /** @var PluginManager */ - private $pluginManager; + private PluginManager $pluginManager; - /** @var float */ - private $profilingTickRate = 20; + private float $profilingTickRate = 20; - /** @var AutoUpdater */ - private $updater; + private AutoUpdater $updater; - /** @var AsyncPool */ - private $asyncPool; + private AsyncPool $asyncPool; - /** - * Counts the ticks since the server start - * - * @var int - */ - private $tickCounter = 0; - /** @var float */ - private $nextTick = 0; + /** Counts the ticks since the server start */ + private int $tickCounter = 0; + private float $nextTick = 0; /** @var float[] */ - private $tickAverage = [20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20]; + private array $tickAverage = [20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20]; /** @var float[] */ - private $useAverage = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - /** @var float */ - private $currentTPS = 20; - /** @var float */ - private $currentUse = 0; - /** @var float */ - private $startTime; + private array $useAverage = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + private float $currentTPS = 20; + private float $currentUse = 0; + private float $startTime; - /** @var bool */ - private $doTitleTick = true; + private bool $doTitleTick = true; - /** @var int */ - private $sendUsageTicker = 0; + private int $sendUsageTicker = 0; - /** @var \AttachableThreadedLogger */ - private $logger; + private \AttachableThreadedLogger $logger; - /** @var MemoryManager */ - private $memoryManager; + private MemoryManager $memoryManager; - /** @var ConsoleReaderThread */ - private $console; + private ConsoleReaderThread $console; - /** @var SimpleCommandMap */ - private $commandMap; + private SimpleCommandMap $commandMap; - /** @var CraftingManager */ - private $craftingManager; + private CraftingManager $craftingManager; - /** @var ResourcePackManager */ - private $resourceManager; + private ResourcePackManager $resourceManager; - /** @var WorldManager */ - private $worldManager; + private WorldManager $worldManager; - /** @var int */ - private $maxPlayers; + private int $maxPlayers; - /** @var bool */ - private $onlineMode = true; + private bool $onlineMode = true; - /** @var Network */ - private $network; - /** @var bool */ - private $networkCompressionAsync = true; + private Network $network; + private bool $networkCompressionAsync = true; - /** @var Language */ - private $language; - /** @var bool */ - private $forceLanguage = false; + private Language $language; + private bool $forceLanguage = false; - /** @var UuidInterface */ - private $serverID; + private UuidInterface $serverID; - /** @var \DynamicClassLoader */ - private $autoloader; - /** @var string */ - private $dataPath; - /** @var string */ - private $pluginPath; + private \DynamicClassLoader $autoloader; + private string $dataPath; + private string $pluginPath; /** * @var string[] * @phpstan-var array */ - private $uniquePlayers = []; + private array $uniquePlayers = []; - /** @var QueryInfo */ - private $queryInfo; + private QueryInfo $queryInfo; - /** @var ServerConfigGroup */ - private $configGroup; + private ServerConfigGroup $configGroup; /** @var Player[] */ - private $playerList = []; + private array $playerList = []; /** * @var CommandSender[][] * @phpstan-var array> */ - private $broadcastSubscribers = []; + private array $broadcastSubscribers = []; public function getName() : string{ return VersionInfo::NAME; @@ -1396,16 +1355,16 @@ class Server{ $this->shutdown(); - if($this->pluginManager instanceof PluginManager){ + if(isset($this->pluginManager)){ $this->getLogger()->debug("Disabling all plugins"); $this->pluginManager->disablePlugins(); } - if($this->network instanceof Network){ + if(isset($this->network)){ $this->network->getSessionManager()->close($this->configGroup->getPropertyString("settings.shutdown-message", "Server closed")); } - if($this->worldManager instanceof WorldManager){ + if(isset($this->worldManager)){ $this->getLogger()->debug("Unloading all worlds"); foreach($this->worldManager->getWorlds() as $world){ $this->worldManager->unloadWorld($world, true); @@ -1415,23 +1374,23 @@ class Server{ $this->getLogger()->debug("Removing event handlers"); HandlerListManager::global()->unregisterAll(); - if($this->asyncPool instanceof AsyncPool){ + if(isset($this->asyncPool)){ $this->getLogger()->debug("Shutting down async task worker pool"); $this->asyncPool->shutdown(); } - if($this->configGroup !== null){ + if(isset($this->configGroup)){ $this->getLogger()->debug("Saving properties"); $this->configGroup->save(); } - if($this->console instanceof ConsoleReaderThread){ + if(isset($this->console)){ $this->getLogger()->debug("Closing console"); $this->console->shutdown(); $this->console->notify(); } - if($this->network instanceof Network){ + if(isset($this->network)){ $this->getLogger()->debug("Stopping network interfaces"); foreach($this->network->getInterfaces() as $interface){ $this->getLogger()->debug("Stopping network interface " . get_class($interface)); From 2ca7fc72546b525f68e3a2e0b12fa188c4debf1b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 12 Aug 2021 23:56:43 +0100 Subject: [PATCH 2692/3224] Server: add native return types to getters that were skipped first time --- src/Server.php | 75 ++++++++++---------------------------------------- 1 file changed, 15 insertions(+), 60 deletions(-) diff --git a/src/Server.php b/src/Server.php index cdc075d7f7..07fdfa70a2 100644 --- a/src/Server.php +++ b/src/Server.php @@ -327,10 +327,7 @@ class Server{ return $str !== "" ? $str : "0.0.0.0"; } - /** - * @return UuidInterface - */ - public function getServerUniqueId(){ + public function getServerUniqueId() : UuidInterface{ return $this->serverID; } @@ -361,38 +358,23 @@ class Server{ return $this->configGroup->getConfigString("motd", VersionInfo::NAME . " Server"); } - /** - * @return \DynamicClassLoader - */ - public function getLoader(){ + public function getLoader() : \DynamicClassLoader{ return $this->autoloader; } - /** - * @return \AttachableThreadedLogger - */ - public function getLogger(){ + public function getLogger() : \AttachableThreadedLogger{ return $this->logger; } - /** - * @return AutoUpdater - */ - public function getUpdater(){ + public function getUpdater() : AutoUpdater{ return $this->updater; } - /** - * @return PluginManager - */ - public function getPluginManager(){ + public function getPluginManager() : PluginManager{ return $this->pluginManager; } - /** - * @return CraftingManager - */ - public function getCraftingManager(){ + public function getCraftingManager() : CraftingManager{ return $this->craftingManager; } @@ -444,10 +426,7 @@ class Server{ return $this->startTime; } - /** - * @return SimpleCommandMap - */ - public function getCommandMap(){ + public function getCommandMap() : SimpleCommandMap{ return $this->commandMap; } @@ -668,17 +647,11 @@ class Server{ } } - /** - * @return BanList - */ - public function getNameBans(){ + public function getNameBans() : BanList{ return $this->banByName; } - /** - * @return BanList - */ - public function getIPBans(){ + public function getIPBans() : BanList{ return $this->banByIP; } @@ -718,17 +691,11 @@ class Server{ return $this->operators->exists($name, true); } - /** - * @return Config - */ - public function getWhitelisted(){ + public function getWhitelisted() : Config{ return $this->whitelist; } - /** - * @return Config - */ - public function getOps(){ + public function getOps() : Config{ return $this->operators; } @@ -1405,10 +1372,7 @@ class Server{ } - /** - * @return QueryInfo - */ - public function getQueryInformation(){ + public function getQueryInformation() : QueryInfo{ return $this->queryInfo; } @@ -1587,10 +1551,7 @@ class Server{ $this->uniquePlayers = []; } - /** - * @return Language - */ - public function getLanguage(){ + public function getLanguage() : Language{ return $this->language; } @@ -1598,17 +1559,11 @@ class Server{ return $this->forceLanguage; } - /** - * @return Network - */ - public function getNetwork(){ + public function getNetwork() : Network{ return $this->network; } - /** - * @return MemoryManager - */ - public function getMemoryManager(){ + public function getMemoryManager() : MemoryManager{ return $this->memoryManager; } From 78c2dcaee5241da42cf6d3a9df155ca4449f0652 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 13 Aug 2021 14:00:17 +0100 Subject: [PATCH 2693/3224] Terminal: fixed crash on platforms which don't support tput fully in 8-bit colour mode, it seems that ITALIC is not supported. This only showed its face now because of typed properties. closes #4365 closes #4366 --- src/utils/Terminal.php | 65 +++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/src/utils/Terminal.php b/src/utils/Terminal.php index 041e475c3d..39baea9491 100644 --- a/src/utils/Terminal.php +++ b/src/utils/Terminal.php @@ -27,7 +27,9 @@ use function fclose; use function fopen; use function function_exists; use function getenv; +use function is_string; use function sapi_windows_vt100_support; +use function shell_exec; use function stream_isatty; use const PHP_EOL; @@ -109,41 +111,44 @@ abstract class Terminal{ } protected static function getEscapeCodes() : void{ - self::$FORMAT_BOLD = `tput bold`; - self::$FORMAT_OBFUSCATED = `tput smacs`; - self::$FORMAT_ITALIC = `tput sitm`; - self::$FORMAT_UNDERLINE = `tput smul`; + $tput = fn(string $args) => is_string($result = shell_exec("tput $args")) ? $result : ""; + $setaf = fn(int $code) => $tput("setaf $code"); + + self::$FORMAT_BOLD = $tput("bold"); + self::$FORMAT_OBFUSCATED = $tput("smacs"); + self::$FORMAT_ITALIC = $tput("sitm"); + self::$FORMAT_UNDERLINE = $tput("smul"); self::$FORMAT_STRIKETHROUGH = "\x1b[9m"; //`tput `; - self::$FORMAT_RESET = `tput sgr0`; + self::$FORMAT_RESET = $tput("sgr0"); - $colors = (int) `tput colors`; + $colors = (int) $tput("colors"); if($colors > 8){ - self::$COLOR_BLACK = $colors >= 256 ? `tput setaf 16` : `tput setaf 0`; - self::$COLOR_DARK_BLUE = $colors >= 256 ? `tput setaf 19` : `tput setaf 4`; - self::$COLOR_DARK_GREEN = $colors >= 256 ? `tput setaf 34` : `tput setaf 2`; - self::$COLOR_DARK_AQUA = $colors >= 256 ? `tput setaf 37` : `tput setaf 6`; - self::$COLOR_DARK_RED = $colors >= 256 ? `tput setaf 124` : `tput setaf 1`; - self::$COLOR_PURPLE = $colors >= 256 ? `tput setaf 127` : `tput setaf 5`; - self::$COLOR_GOLD = $colors >= 256 ? `tput setaf 214` : `tput setaf 3`; - self::$COLOR_GRAY = $colors >= 256 ? `tput setaf 145` : `tput setaf 7`; - self::$COLOR_DARK_GRAY = $colors >= 256 ? `tput setaf 59` : `tput setaf 8`; - self::$COLOR_BLUE = $colors >= 256 ? `tput setaf 63` : `tput setaf 12`; - self::$COLOR_GREEN = $colors >= 256 ? `tput setaf 83` : `tput setaf 10`; - self::$COLOR_AQUA = $colors >= 256 ? `tput setaf 87` : `tput setaf 14`; - self::$COLOR_RED = $colors >= 256 ? `tput setaf 203` : `tput setaf 9`; - self::$COLOR_LIGHT_PURPLE = $colors >= 256 ? `tput setaf 207` : `tput setaf 13`; - self::$COLOR_YELLOW = $colors >= 256 ? `tput setaf 227` : `tput setaf 11`; - self::$COLOR_WHITE = $colors >= 256 ? `tput setaf 231` : `tput setaf 15`; + self::$COLOR_BLACK = $colors >= 256 ? $setaf(16) : $setaf(0); + self::$COLOR_DARK_BLUE = $colors >= 256 ? $setaf(19) : $setaf(4); + self::$COLOR_DARK_GREEN = $colors >= 256 ? $setaf(34) : $setaf(2); + self::$COLOR_DARK_AQUA = $colors >= 256 ? $setaf(37) : $setaf(6); + self::$COLOR_DARK_RED = $colors >= 256 ? $setaf(124) : $setaf(1); + self::$COLOR_PURPLE = $colors >= 256 ? $setaf(127) : $setaf(5); + self::$COLOR_GOLD = $colors >= 256 ? $setaf(214) : $setaf(3); + self::$COLOR_GRAY = $colors >= 256 ? $setaf(145) : $setaf(7); + self::$COLOR_DARK_GRAY = $colors >= 256 ? $setaf(59) : $setaf(8); + self::$COLOR_BLUE = $colors >= 256 ? $setaf(63) : $setaf(12); + self::$COLOR_GREEN = $colors >= 256 ? $setaf(83) : $setaf(10); + self::$COLOR_AQUA = $colors >= 256 ? $setaf(87) : $setaf(14); + self::$COLOR_RED = $colors >= 256 ? $setaf(203) : $setaf(9); + self::$COLOR_LIGHT_PURPLE = $colors >= 256 ? $setaf(207) : $setaf(13); + self::$COLOR_YELLOW = $colors >= 256 ? $setaf(227) : $setaf(11); + self::$COLOR_WHITE = $colors >= 256 ? $setaf(231) : $setaf(15); }else{ - self::$COLOR_BLACK = self::$COLOR_DARK_GRAY = `tput setaf 0`; - self::$COLOR_RED = self::$COLOR_DARK_RED = `tput setaf 1`; - self::$COLOR_GREEN = self::$COLOR_DARK_GREEN = `tput setaf 2`; - self::$COLOR_YELLOW = self::$COLOR_GOLD = `tput setaf 3`; - self::$COLOR_BLUE = self::$COLOR_DARK_BLUE = `tput setaf 4`; - self::$COLOR_LIGHT_PURPLE = self::$COLOR_PURPLE = `tput setaf 5`; - self::$COLOR_AQUA = self::$COLOR_DARK_AQUA = `tput setaf 6`; - self::$COLOR_GRAY = self::$COLOR_WHITE = `tput setaf 7`; + self::$COLOR_BLACK = self::$COLOR_DARK_GRAY = $setaf(0); + self::$COLOR_RED = self::$COLOR_DARK_RED = $setaf(1); + self::$COLOR_GREEN = self::$COLOR_DARK_GREEN = $setaf(2); + self::$COLOR_YELLOW = self::$COLOR_GOLD = $setaf(3); + self::$COLOR_BLUE = self::$COLOR_DARK_BLUE = $setaf(4); + self::$COLOR_LIGHT_PURPLE = self::$COLOR_PURPLE = $setaf(5); + self::$COLOR_AQUA = self::$COLOR_DARK_AQUA = $setaf(6); + self::$COLOR_GRAY = self::$COLOR_WHITE = $setaf(7); } } From ecdfd9ea2614c079483235d54bec1ab0acebeda6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 13 Aug 2021 14:04:13 +0100 Subject: [PATCH 2694/3224] Terminal: reduce code duplication in getFallbackEscapeCodes() --- src/utils/Terminal.php | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/utils/Terminal.php b/src/utils/Terminal.php index 39baea9491..4280f94d88 100644 --- a/src/utils/Terminal.php +++ b/src/utils/Terminal.php @@ -92,22 +92,24 @@ abstract class Terminal{ self::$FORMAT_RESET = "\x1b[m"; - self::$COLOR_BLACK = "\x1b[38;5;16m"; - self::$COLOR_DARK_BLUE = "\x1b[38;5;19m"; - self::$COLOR_DARK_GREEN = "\x1b[38;5;34m"; - self::$COLOR_DARK_AQUA = "\x1b[38;5;37m"; - self::$COLOR_DARK_RED = "\x1b[38;5;124m"; - self::$COLOR_PURPLE = "\x1b[38;5;127m"; - self::$COLOR_GOLD = "\x1b[38;5;214m"; - self::$COLOR_GRAY = "\x1b[38;5;145m"; - self::$COLOR_DARK_GRAY = "\x1b[38;5;59m"; - self::$COLOR_BLUE = "\x1b[38;5;63m"; - self::$COLOR_GREEN = "\x1b[38;5;83m"; - self::$COLOR_AQUA = "\x1b[38;5;87m"; - self::$COLOR_RED = "\x1b[38;5;203m"; - self::$COLOR_LIGHT_PURPLE = "\x1b[38;5;207m"; - self::$COLOR_YELLOW = "\x1b[38;5;227m"; - self::$COLOR_WHITE = "\x1b[38;5;231m"; + $color = fn(int $code) => "\x1b[38;5;${code}m"; + + self::$COLOR_BLACK = $color(16); + self::$COLOR_DARK_BLUE = $color(19); + self::$COLOR_DARK_GREEN = $color(34); + self::$COLOR_DARK_AQUA = $color(37); + self::$COLOR_DARK_RED = $color(124); + self::$COLOR_PURPLE = $color(127); + self::$COLOR_GOLD = $color(214); + self::$COLOR_GRAY = $color(145); + self::$COLOR_DARK_GRAY = $color(59); + self::$COLOR_BLUE = $color(63); + self::$COLOR_GREEN = $color(83); + self::$COLOR_AQUA = $color(87); + self::$COLOR_RED = $color(203); + self::$COLOR_LIGHT_PURPLE = $color(207); + self::$COLOR_YELLOW = $color(227); + self::$COLOR_WHITE = $color(231); } protected static function getEscapeCodes() : void{ From 13d4131d0d6147b54e88b632518753968bda8f8d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 14 Aug 2021 13:27:21 +0100 Subject: [PATCH 2695/3224] Remove player update warnings a player ingame is not going to have access to the terminal to update PM, and if they do, they can see the warning on the console themselves anyway. --- resources/pocketmine.yml | 1 - src/player/Player.php | 4 ---- src/updater/AutoUpdater.php | 10 ---------- 3 files changed, 15 deletions(-) diff --git a/resources/pocketmine.yml b/resources/pocketmine.yml index f27a6d01c4..3cb7ce4303 100644 --- a/resources/pocketmine.yml +++ b/resources/pocketmine.yml @@ -155,7 +155,6 @@ auto-updater: enabled: true on-update: warn-console: true - warn-ops: true #Can be development, alpha, beta or stable. preferred-channel: stable #If using a development version, it will suggest changing the channel diff --git a/src/player/Player.php b/src/player/Player.php index e333996907..e4bc20180a 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -770,10 +770,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->spawnToAll(); - if($this->server->getUpdater()->hasUpdate() and $this->hasPermission(DefaultPermissionNames::BROADCAST_ADMIN) and $this->server->getConfigGroup()->getPropertyBool("auto-updater.on-update.warn-ops", true)){ - $this->server->getUpdater()->showPlayerUpdate($this); - } - if($this->getHealth() <= 0){ $this->logger->debug("Quit while dead, forcing respawn"); $this->respawn(); diff --git a/src/updater/AutoUpdater.php b/src/updater/AutoUpdater.php index 34ed5b7c10..b20db07671 100644 --- a/src/updater/AutoUpdater.php +++ b/src/updater/AutoUpdater.php @@ -24,9 +24,7 @@ declare(strict_types=1); namespace pocketmine\updater; use pocketmine\event\server\UpdateNotifyEvent; -use pocketmine\player\Player; use pocketmine\Server; -use pocketmine\utils\TextFormat; use pocketmine\utils\VersionString; use pocketmine\VersionInfo; use function date; @@ -105,14 +103,6 @@ class AutoUpdater{ $this->printConsoleMessage($messages, \LogLevel::WARNING); } - /** - * Shows a warning to a player to tell them there is an update available - */ - public function showPlayerUpdate(Player $player) : void{ - $player->sendMessage(TextFormat::DARK_PURPLE . "The version of " . $this->server->getName() . " that this server is running is out of date. Please consider updating to the latest version."); - $player->sendMessage(TextFormat::DARK_PURPLE . "Check the console for more details."); - } - protected function showChannelSuggestionStable() : void{ $this->printConsoleMessage([ "It appears you're running a Stable build, when you've specified that you prefer to run " . ucfirst($this->getChannel()) . " builds.", From 804d02b08603829b49be6e438e2e8fa211df2b9a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 14 Aug 2021 16:08:22 +0100 Subject: [PATCH 2696/3224] TranslationContainer: added prefix(), postfix() and format() --- src/Server.php | 3 +-- src/block/Bed.php | 9 ++++----- src/command/Command.php | 10 +++------- src/command/defaults/ClearCommand.php | 9 ++++----- src/command/defaults/EffectCommand.php | 5 ++--- src/command/defaults/EnchantCommand.php | 2 +- src/command/defaults/GamemodeCommand.php | 2 +- src/command/defaults/GiveCommand.php | 5 ++--- src/command/defaults/KickCommand.php | 3 +-- src/command/defaults/KillCommand.php | 3 +-- src/command/defaults/ParticleCommand.php | 3 +-- src/command/defaults/SayCommand.php | 7 +++++-- src/command/defaults/SpawnpointCommand.php | 3 +-- src/command/defaults/TellCommand.php | 7 +++---- src/command/defaults/TitleCommand.php | 3 ++- src/lang/TranslationContainer.php | 12 ++++++++++++ src/player/Player.php | 9 ++------- 17 files changed, 46 insertions(+), 49 deletions(-) diff --git a/src/Server.php b/src/Server.php index 07fdfa70a2..f5aebbbb9b 100644 --- a/src/Server.php +++ b/src/Server.php @@ -44,7 +44,6 @@ use pocketmine\event\server\CommandEvent; use pocketmine\event\server\DataPacketSendEvent; use pocketmine\event\server\QueryRegenerateEvent; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\Language; use pocketmine\lang\LanguageNotFoundException; use pocketmine\lang\TranslationContainer; @@ -1292,7 +1291,7 @@ class Server{ return true; } - $sender->sendMessage($sender->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_NOTFOUND)); + $sender->sendMessage(KnownTranslationFactory::commands_generic_notFound()->prefix(TextFormat::RED)); return false; } diff --git a/src/block/Bed.php b/src/block/Bed.php index c03ae71ddc..dd63c4a0d5 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -30,8 +30,7 @@ use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\item\Item; -use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; @@ -135,7 +134,7 @@ class Bed extends Transparent{ return true; }elseif($playerPos->distanceSquared($this->pos) > 4 and $playerPos->distanceSquared($other->pos) > 4){ - $player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%" . KnownTranslationKeys::TILE_BED_TOOFAR)); + $player->sendMessage(KnownTranslationFactory::tile_bed_tooFar()->prefix(TextFormat::GRAY)); return true; } @@ -144,7 +143,7 @@ class Bed extends Transparent{ $isNight = ($time >= World::TIME_NIGHT and $time < World::TIME_SUNRISE); if(!$isNight){ - $player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%" . KnownTranslationKeys::TILE_BED_NOSLEEP)); + $player->sendMessage(KnownTranslationFactory::tile_bed_tooFar()->prefix(TextFormat::GRAY)); return true; } @@ -152,7 +151,7 @@ class Bed extends Transparent{ $b = ($this->isHeadPart() ? $this : $other); if($b->isOccupied()){ - $player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%" . KnownTranslationKeys::TILE_BED_OCCUPIED)); + $player->sendMessage(KnownTranslationFactory::tile_bed_occupied()->prefix(TextFormat::GRAY)); return true; } diff --git a/src/command/Command.php b/src/command/Command.php index 7972638af7..d723992cad 100644 --- a/src/command/Command.php +++ b/src/command/Command.php @@ -29,7 +29,6 @@ namespace pocketmine\command; use pocketmine\command\utils\CommandException; use pocketmine\console\ConsoleCommandSender; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\TranslationContainer; use pocketmine\permission\PermissionManager; use pocketmine\Server; @@ -118,7 +117,7 @@ abstract class Command{ } if($this->permissionMessage === null){ - $target->sendMessage($target->getLanguage()->translateString(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION)); + $target->sendMessage(KnownTranslationFactory::commands_generic_permission()->prefix(TextFormat::RED)); }elseif($this->permissionMessage !== ""){ $target->sendMessage(str_replace("", $permission ?? $this->permission, $this->permissionMessage)); } @@ -234,14 +233,11 @@ abstract class Command{ public static function broadcastCommandMessage(CommandSender $source, TranslationContainer|string $message, bool $sendToSource = true) : void{ $users = $source->getServer()->getBroadcastChannelSubscribers(Server::BROADCAST_CHANNEL_ADMINISTRATIVE); if($message instanceof TranslationContainer){ - $formatted = "[" . $source->getName() . ": %" . $message->getText() . "]"; - - $result = new TranslationContainer($formatted, $message->getParameters()); - $colored = new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . $formatted, $message->getParameters()); + $result = $message->format("[" . $source->getName() . ": ", "]"); }else{ $result = KnownTranslationFactory::chat_type_admin($source->getName(), $message); - $colored = new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . "%" . KnownTranslationKeys::CHAT_TYPE_ADMIN, [$source->getName(), $message]); } + $colored = $result->prefix(TextFormat::GRAY . TextFormat::ITALIC); if($sendToSource and !($source instanceof ConsoleCommandSender)){ $source->sendMessage($message); diff --git a/src/command/defaults/ClearCommand.php b/src/command/defaults/ClearCommand.php index 6951ef2cfc..08f160caa2 100644 --- a/src/command/defaults/ClearCommand.php +++ b/src/command/defaults/ClearCommand.php @@ -30,7 +30,6 @@ use pocketmine\item\LegacyStringToItemParser; use pocketmine\item\LegacyStringToItemParserException; use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; @@ -62,7 +61,7 @@ class ClearCommand extends VanillaCommand{ if(isset($args[0])){ $target = $sender->getServer()->getPlayerByPrefix($args[0]); if($target === null){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); + $sender->sendMessage(KnownTranslationFactory::commands_generic_player_notFound()->prefix(TextFormat::RED)); return true; } if($target !== $sender && !$this->testPermission($sender, DefaultPermissionNames::COMMAND_CLEAR_OTHER)){ @@ -89,7 +88,7 @@ class ClearCommand extends VanillaCommand{ } }catch(LegacyStringToItemParserException $e){ //vanilla checks this at argument parsing layer, can't come up with a better alternative - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GIVE_ITEM_NOTFOUND, [$args[1]])); + $sender->sendMessage(KnownTranslationFactory::commands_give_item_notFound($args[1])->prefix(TextFormat::RED)); return true; } } @@ -105,7 +104,7 @@ class ClearCommand extends VanillaCommand{ if($count > 0){ $sender->sendMessage(KnownTranslationFactory::commands_clear_testing($target->getName(), (string) $count)); }else{ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_CLEAR_FAILURE_NO_ITEMS, [$target->getName()])); + $sender->sendMessage(KnownTranslationFactory::commands_clear_failure_no_items($target->getName())->prefix(TextFormat::RED)); } return true; @@ -167,7 +166,7 @@ class ClearCommand extends VanillaCommand{ if($cleared > 0){ Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_clear_success($target->getName(), (string) $cleared)); }else{ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_CLEAR_FAILURE_NO_ITEMS, [$target->getName()])); + $sender->sendMessage(KnownTranslationFactory::commands_clear_failure_no_items($target->getName())->prefix(TextFormat::RED)); } return true; diff --git a/src/command/defaults/EffectCommand.php b/src/command/defaults/EffectCommand.php index 0e6df678dd..5923010036 100644 --- a/src/command/defaults/EffectCommand.php +++ b/src/command/defaults/EffectCommand.php @@ -29,7 +29,6 @@ use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\VanillaEffects; use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\Limits; use pocketmine\utils\TextFormat; @@ -59,7 +58,7 @@ class EffectCommand extends VanillaCommand{ $player = $sender->getServer()->getPlayerByPrefix($args[0]); if($player === null){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); + $sender->sendMessage(KnownTranslationFactory::commands_generic_player_notFound()->prefix(TextFormat::RED)); return true; } $effectManager = $player->getEffects(); @@ -74,7 +73,7 @@ class EffectCommand extends VanillaCommand{ try{ $effect = VanillaEffects::fromString($args[1]); }catch(\InvalidArgumentException $e){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_EFFECT_NOTFOUND, [$args[1]])); + $sender->sendMessage(KnownTranslationFactory::commands_effect_notFound($args[1])->prefix(TextFormat::RED)); return true; } diff --git a/src/command/defaults/EnchantCommand.php b/src/command/defaults/EnchantCommand.php index d34e6a884c..08135bca56 100644 --- a/src/command/defaults/EnchantCommand.php +++ b/src/command/defaults/EnchantCommand.php @@ -57,7 +57,7 @@ class EnchantCommand extends VanillaCommand{ $player = $sender->getServer()->getPlayerByPrefix($args[0]); if($player === null){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); + $sender->sendMessage(KnownTranslationFactory::commands_generic_player_notFound()->prefix(TextFormat::RED)); return true; } diff --git a/src/command/defaults/GamemodeCommand.php b/src/command/defaults/GamemodeCommand.php index 41fc5262f9..be26935eca 100644 --- a/src/command/defaults/GamemodeCommand.php +++ b/src/command/defaults/GamemodeCommand.php @@ -64,7 +64,7 @@ class GamemodeCommand extends VanillaCommand{ if(isset($args[1])){ $target = $sender->getServer()->getPlayerByPrefix($args[1]); if($target === null){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); + $sender->sendMessage(KnownTranslationFactory::commands_generic_player_notFound()->prefix(TextFormat::RED)); return true; } diff --git a/src/command/defaults/GiveCommand.php b/src/command/defaults/GiveCommand.php index 63cb328600..975d63d888 100644 --- a/src/command/defaults/GiveCommand.php +++ b/src/command/defaults/GiveCommand.php @@ -30,7 +30,6 @@ use pocketmine\item\LegacyStringToItemParser; use pocketmine\item\LegacyStringToItemParserException; use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\nbt\JsonNbtParser; use pocketmine\nbt\NbtDataException; use pocketmine\permission\DefaultPermissionNames; @@ -61,14 +60,14 @@ class GiveCommand extends VanillaCommand{ $player = $sender->getServer()->getPlayerByPrefix($args[0]); if($player === null){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); + $sender->sendMessage(KnownTranslationFactory::commands_generic_player_notFound()->prefix(TextFormat::RED)); return true; } try{ $item = LegacyStringToItemParser::getInstance()->parse($args[1]); }catch(LegacyStringToItemParserException $e){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GIVE_ITEM_NOTFOUND, [$args[1]])); + $sender->sendMessage(KnownTranslationFactory::commands_give_item_notFound($args[1])->prefix(TextFormat::RED)); return true; } diff --git a/src/command/defaults/KickCommand.php b/src/command/defaults/KickCommand.php index 3fbd00a0e9..d654be2da4 100644 --- a/src/command/defaults/KickCommand.php +++ b/src/command/defaults/KickCommand.php @@ -28,7 +28,6 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; @@ -68,7 +67,7 @@ class KickCommand extends VanillaCommand{ Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_kick_success($player->getName())); } }else{ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); + $sender->sendMessage(KnownTranslationFactory::commands_generic_player_notFound()->prefix(TextFormat::RED)); } return true; diff --git a/src/command/defaults/KillCommand.php b/src/command/defaults/KillCommand.php index f8655738aa..2e1bb0b9f2 100644 --- a/src/command/defaults/KillCommand.php +++ b/src/command/defaults/KillCommand.php @@ -29,7 +29,6 @@ use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; @@ -68,7 +67,7 @@ class KillCommand extends VanillaCommand{ $player->attack(new EntityDamageEvent($player, EntityDamageEvent::CAUSE_SUICIDE, 1000)); Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_kill_successful($player->getName())); }else{ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); + $sender->sendMessage(KnownTranslationFactory::commands_generic_player_notFound()->prefix(TextFormat::RED)); } return true; diff --git a/src/command/defaults/ParticleCommand.php b/src/command/defaults/ParticleCommand.php index a7ee0d8c42..7bb6e098b6 100644 --- a/src/command/defaults/ParticleCommand.php +++ b/src/command/defaults/ParticleCommand.php @@ -31,7 +31,6 @@ use pocketmine\item\ItemFactory; use pocketmine\item\VanillaItems; use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -121,7 +120,7 @@ class ParticleCommand extends VanillaCommand{ $particle = $this->getParticle($name, $data); if($particle === null){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_PARTICLE_NOTFOUND, [$name])); + $sender->sendMessage(KnownTranslationFactory::commands_particle_notFound($name)->prefix(TextFormat::RED)); return true; } diff --git a/src/command/defaults/SayCommand.php b/src/command/defaults/SayCommand.php index d337b6bc87..62d9fd2142 100644 --- a/src/command/defaults/SayCommand.php +++ b/src/command/defaults/SayCommand.php @@ -26,8 +26,8 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\console\ConsoleCommandSender; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; @@ -54,7 +54,10 @@ class SayCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - $sender->getServer()->broadcastMessage(new TranslationContainer(TextFormat::LIGHT_PURPLE . "%" . KnownTranslationKeys::CHAT_TYPE_ANNOUNCEMENT, [$sender instanceof Player ? $sender->getDisplayName() : ($sender instanceof ConsoleCommandSender ? "Server" : $sender->getName()), TextFormat::LIGHT_PURPLE . implode(" ", $args)])); + $sender->getServer()->broadcastMessage(KnownTranslationFactory::chat_type_announcement( + $sender instanceof Player ? $sender->getDisplayName() : ($sender instanceof ConsoleCommandSender ? "Server" : $sender->getName()), + implode(" ", $args) + )->prefix(TextFormat::LIGHT_PURPLE)); return true; } } diff --git a/src/command/defaults/SpawnpointCommand.php b/src/command/defaults/SpawnpointCommand.php index 23cf0b82e3..031c64ae4a 100644 --- a/src/command/defaults/SpawnpointCommand.php +++ b/src/command/defaults/SpawnpointCommand.php @@ -28,7 +28,6 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; @@ -66,7 +65,7 @@ class SpawnpointCommand extends VanillaCommand{ }else{ $target = $sender->getServer()->getPlayerByPrefix($args[0]); if($target === null){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND)); + $sender->sendMessage(KnownTranslationFactory::commands_generic_player_notFound()->prefix(TextFormat::RED)); return true; } diff --git a/src/command/defaults/TellCommand.php b/src/command/defaults/TellCommand.php index 9b9ba5f8d4..693fae68b6 100644 --- a/src/command/defaults/TellCommand.php +++ b/src/command/defaults/TellCommand.php @@ -28,7 +28,6 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; @@ -60,15 +59,15 @@ class TellCommand extends VanillaCommand{ $player = $sender->getServer()->getPlayerByPrefix(array_shift($args)); if($player === $sender){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_MESSAGE_SAMETARGET)); + $sender->sendMessage(KnownTranslationFactory::commands_message_sameTarget()->prefix(TextFormat::RED)); return true; } if($player instanceof Player){ $message = implode(" ", $args); - $sender->sendMessage(new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . "%" . KnownTranslationKeys::COMMANDS_MESSAGE_DISPLAY_OUTGOING, [$player->getDisplayName(), $message])); + $sender->sendMessage(KnownTranslationFactory::commands_message_display_outgoing($player->getDisplayName(), $message)->prefix(TextFormat::GRAY . TextFormat::ITALIC)); $name = $sender instanceof Player ? $sender->getDisplayName() : $sender->getName(); - $player->sendMessage(new TranslationContainer(TextFormat::GRAY . TextFormat::ITALIC . "%" . KnownTranslationKeys::COMMANDS_MESSAGE_DISPLAY_INCOMING, [$name, $message])); + $player->sendMessage(KnownTranslationFactory::commands_message_display_incoming($name, $message)->prefix(TextFormat::GRAY . TextFormat::ITALIC)); Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_message_display_outgoing($player->getDisplayName(), $message), false); }else{ $sender->sendMessage(KnownTranslationFactory::commands_generic_player_notFound()); diff --git a/src/command/defaults/TitleCommand.php b/src/command/defaults/TitleCommand.php index 62b80e4223..6a96293aea 100644 --- a/src/command/defaults/TitleCommand.php +++ b/src/command/defaults/TitleCommand.php @@ -28,6 +28,7 @@ use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; +use pocketmine\utils\TextFormat; use function array_slice; use function count; use function implode; @@ -54,7 +55,7 @@ class TitleCommand extends VanillaCommand{ $player = $sender->getServer()->getPlayerByPrefix($args[0]); if($player === null){ - $sender->sendMessage(KnownTranslationFactory::commands_generic_player_notFound()); + $sender->sendMessage(KnownTranslationFactory::commands_generic_player_notFound()->prefix(TextFormat::RED)); return true; } diff --git a/src/lang/TranslationContainer.php b/src/lang/TranslationContainer.php index bcafb38c02..4780535b42 100644 --- a/src/lang/TranslationContainer.php +++ b/src/lang/TranslationContainer.php @@ -55,4 +55,16 @@ final class TranslationContainer{ public function getParameter(int|string $i) : ?string{ return $this->params[$i] ?? null; } + + public function format(string $before, string $after) : self{ + return new self("$before%$this->text$after", $this->params); + } + + public function prefix(string $prefix) : self{ + return new self("$prefix%$this->text", $this->params); + } + + public function postfix(string $postfix) : self{ + return new self("%$this->text" . $postfix); + } } diff --git a/src/player/Player.php b/src/player/Player.php index e4bc20180a..be5fec6c34 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -81,7 +81,6 @@ use pocketmine\item\Item; use pocketmine\item\ItemUseResult; use pocketmine\item\Releasable; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\Language; use pocketmine\lang\TranslationContainer; use pocketmine\math\Vector3; @@ -321,9 +320,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ public function getLeaveMessage() : TranslationContainer|string{ if($this->spawned){ - return new TranslationContainer(TextFormat::YELLOW . "%" . KnownTranslationKeys::MULTIPLAYER_PLAYER_LEFT, [ - $this->getDisplayName() - ]); + return KnownTranslationFactory::multiplayer_player_left($this->getDisplayName())->prefix(TextFormat::YELLOW); } return ""; @@ -757,9 +754,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ }); $ev = new PlayerJoinEvent($this, - new TranslationContainer(TextFormat::YELLOW . "%" . KnownTranslationKeys::MULTIPLAYER_PLAYER_JOINED, [ - $this->getDisplayName() - ]) + KnownTranslationFactory::multiplayer_player_joined($this->getDisplayName())->prefix(TextFormat::YELLOW) ); $ev->call(); if($ev->getJoinMessage() !== ""){ From 8b9d7d63900c6a28ffa3b0d86266a33c9f7b21b7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 14 Aug 2021 20:57:13 +0100 Subject: [PATCH 2697/3224] Support for nested TranslationContainers --- build/generate-known-translation-apis.php | 2 +- src/command/defaults/VersionCommand.php | 2 +- src/lang/KnownTranslationFactory.php | 298 +++++++++++----------- src/lang/Language.php | 8 +- src/lang/TranslationContainer.php | 16 +- src/player/Player.php | 5 +- src/plugin/PluginManager.php | 14 +- src/world/WorldManager.php | 6 +- 8 files changed, 180 insertions(+), 171 deletions(-) diff --git a/build/generate-known-translation-apis.php b/build/generate-known-translation-apis.php index 4c61a16052..bb0679b01c 100644 --- a/build/generate-known-translation-apis.php +++ b/build/generate-known-translation-apis.php @@ -143,7 +143,7 @@ HEADER; } echo "\tpublic static function " . functionify($key) . - "(" . implode(", ", array_map(fn(string $paramName) => "string \$$paramName", $parameters)) . ") : TranslationContainer{\n"; + "(" . implode(", ", array_map(fn(string $paramName) => "TranslationContainer|string \$$paramName", $parameters)) . ") : TranslationContainer{\n"; echo "\t\treturn new TranslationContainer(KnownTranslationKeys::" . constantify($key) . ", ["; foreach($parameters as $parameterKey => $parameterName){ echo "\n\t\t\t"; diff --git a/src/command/defaults/VersionCommand.php b/src/command/defaults/VersionCommand.php index 82fe5e0db6..ff69f76273 100644 --- a/src/command/defaults/VersionCommand.php +++ b/src/command/defaults/VersionCommand.php @@ -88,7 +88,7 @@ class VersionCommand extends VanillaCommand{ }else{ $jitStatus = KnownTranslationFactory::pocketmine_command_version_phpJitNotSupported(); } - $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_phpJitStatus($sender->getLanguage()->translate($jitStatus))); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_phpJitStatus($jitStatus)); $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_operatingSystem(Utils::getOS())); }else{ $pluginName = implode(" ", $args); diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index 7156de7cb2..c512519e99 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -41,42 +41,42 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::ACCEPT_LICENSE, []); } - public static function chat_type_achievement(string $param0, string $param1) : TranslationContainer{ + public static function chat_type_achievement(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::CHAT_TYPE_ACHIEVEMENT, [ 0 => $param0, 1 => $param1, ]); } - public static function chat_type_admin(string $param0, string $param1) : TranslationContainer{ + public static function chat_type_admin(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::CHAT_TYPE_ADMIN, [ 0 => $param0, 1 => $param1, ]); } - public static function chat_type_announcement(string $param0, string $param1) : TranslationContainer{ + public static function chat_type_announcement(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::CHAT_TYPE_ANNOUNCEMENT, [ 0 => $param0, 1 => $param1, ]); } - public static function chat_type_emote(string $param0, string $param1) : TranslationContainer{ + public static function chat_type_emote(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::CHAT_TYPE_EMOTE, [ 0 => $param0, 1 => $param1, ]); } - public static function chat_type_text(string $param0, string $param1) : TranslationContainer{ + public static function chat_type_text(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::CHAT_TYPE_TEXT, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_ban_success(string $param0) : TranslationContainer{ + public static function commands_ban_success(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_BAN_SUCCESS, [ 0 => $param0, ]); @@ -90,13 +90,13 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANIP_INVALID, []); } - public static function commands_banip_success(string $param0) : TranslationContainer{ + public static function commands_banip_success(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANIP_SUCCESS, [ 0 => $param0, ]); } - public static function commands_banip_success_players(string $param0, string $param1) : TranslationContainer{ + public static function commands_banip_success_players(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANIP_SUCCESS_PLAYERS, [ 0 => $param0, 1 => $param1, @@ -107,13 +107,13 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANIP_USAGE, []); } - public static function commands_banlist_ips(string $param0) : TranslationContainer{ + public static function commands_banlist_ips(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANLIST_IPS, [ 0 => $param0, ]); } - public static function commands_banlist_players(string $param0) : TranslationContainer{ + public static function commands_banlist_players(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANLIST_PLAYERS, [ 0 => $param0, ]); @@ -123,27 +123,27 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANLIST_USAGE, []); } - public static function commands_clear_failure_no_items(string $param0) : TranslationContainer{ + public static function commands_clear_failure_no_items(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_CLEAR_FAILURE_NO_ITEMS, [ 0 => $param0, ]); } - public static function commands_clear_success(string $param0, string $param1) : TranslationContainer{ + public static function commands_clear_success(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_CLEAR_SUCCESS, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_clear_testing(string $param0, string $param1) : TranslationContainer{ + public static function commands_clear_testing(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_CLEAR_TESTING, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_defaultgamemode_success(string $param0) : TranslationContainer{ + public static function commands_defaultgamemode_success(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_DEFAULTGAMEMODE_SUCCESS, [ 0 => $param0, ]); @@ -153,7 +153,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_DEFAULTGAMEMODE_USAGE, []); } - public static function commands_deop_success(string $param0) : TranslationContainer{ + public static function commands_deop_success(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_DEOP_SUCCESS, [ 0 => $param0, ]); @@ -163,7 +163,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_DEOP_USAGE, []); } - public static function commands_difficulty_success(string $param0) : TranslationContainer{ + public static function commands_difficulty_success(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_DIFFICULTY_SUCCESS, [ 0 => $param0, ]); @@ -173,26 +173,26 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_DIFFICULTY_USAGE, []); } - public static function commands_effect_failure_notActive(string $param0, string $param1) : TranslationContainer{ + public static function commands_effect_failure_notActive(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_FAILURE_NOTACTIVE, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_effect_failure_notActive_all(string $param0) : TranslationContainer{ + public static function commands_effect_failure_notActive_all(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_FAILURE_NOTACTIVE_ALL, [ 0 => $param0, ]); } - public static function commands_effect_notFound(string $param0) : TranslationContainer{ + public static function commands_effect_notFound(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_NOTFOUND, [ 0 => $param0, ]); } - public static function commands_effect_success(string $param0, string $param1, string $param2, string $param3) : TranslationContainer{ + public static function commands_effect_success(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2, TranslationContainer|string $param3) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_SUCCESS, [ 0 => $param0, 1 => $param1, @@ -201,14 +201,14 @@ final class KnownTranslationFactory{ ]); } - public static function commands_effect_success_removed(string $param0, string $param1) : TranslationContainer{ + public static function commands_effect_success_removed(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_SUCCESS_REMOVED, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_effect_success_removed_all(string $param0) : TranslationContainer{ + public static function commands_effect_success_removed_all(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_SUCCESS_REMOVED_ALL, [ 0 => $param0, ]); @@ -222,7 +222,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_ENCHANT_NOITEM, []); } - public static function commands_enchant_notFound(string $param0) : TranslationContainer{ + public static function commands_enchant_notFound(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_ENCHANT_NOTFOUND, [ 0 => $param0, ]); @@ -236,14 +236,14 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_ENCHANT_USAGE, []); } - public static function commands_gamemode_success_other(string $param1, string $param0) : TranslationContainer{ + public static function commands_gamemode_success_other(TranslationContainer|string $param1, TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_GAMEMODE_SUCCESS_OTHER, [ 1 => $param1, 0 => $param0, ]); } - public static function commands_gamemode_success_self(string $param0) : TranslationContainer{ + public static function commands_gamemode_success_self(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_GAMEMODE_SUCCESS_SELF, [ 0 => $param0, ]); @@ -257,14 +257,14 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_NOTFOUND, []); } - public static function commands_generic_num_tooBig(string $param0, string $param1) : TranslationContainer{ + public static function commands_generic_num_tooBig(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_NUM_TOOBIG, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_generic_num_tooSmall(string $param0, string $param1) : TranslationContainer{ + public static function commands_generic_num_tooSmall(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_NUM_TOOSMALL, [ 0 => $param0, 1 => $param1, @@ -279,19 +279,19 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND, []); } - public static function commands_generic_usage(string $param0) : TranslationContainer{ + public static function commands_generic_usage(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_USAGE, [ 0 => $param0, ]); } - public static function commands_give_item_notFound(string $param0) : TranslationContainer{ + public static function commands_give_item_notFound(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_GIVE_ITEM_NOTFOUND, [ 0 => $param0, ]); } - public static function commands_give_success(string $param0, string $param1, string $param2) : TranslationContainer{ + public static function commands_give_success(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_GIVE_SUCCESS, [ 0 => $param0, 1 => $param1, @@ -299,13 +299,13 @@ final class KnownTranslationFactory{ ]); } - public static function commands_give_tagError(string $param0) : TranslationContainer{ + public static function commands_give_tagError(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_GIVE_TAGERROR, [ 0 => $param0, ]); } - public static function commands_help_header(string $param0, string $param1) : TranslationContainer{ + public static function commands_help_header(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_HELP_HEADER, [ 0 => $param0, 1 => $param1, @@ -316,13 +316,13 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_HELP_USAGE, []); } - public static function commands_kick_success(string $param0) : TranslationContainer{ + public static function commands_kick_success(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_KICK_SUCCESS, [ 0 => $param0, ]); } - public static function commands_kick_success_reason(string $param0, string $param1) : TranslationContainer{ + public static function commands_kick_success_reason(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_KICK_SUCCESS_REASON, [ 0 => $param0, 1 => $param1, @@ -333,7 +333,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_KICK_USAGE, []); } - public static function commands_kill_successful(string $param0) : TranslationContainer{ + public static function commands_kill_successful(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_KILL_SUCCESSFUL, [ 0 => $param0, ]); @@ -343,14 +343,14 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_ME_USAGE, []); } - public static function commands_message_display_incoming(string $param0, string $param1) : TranslationContainer{ + public static function commands_message_display_incoming(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_MESSAGE_DISPLAY_INCOMING, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_message_display_outgoing(string $param0, string $param1) : TranslationContainer{ + public static function commands_message_display_outgoing(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_MESSAGE_DISPLAY_OUTGOING, [ 0 => $param0, 1 => $param1, @@ -365,7 +365,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_MESSAGE_USAGE, []); } - public static function commands_op_success(string $param0) : TranslationContainer{ + public static function commands_op_success(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_OP_SUCCESS, [ 0 => $param0, ]); @@ -375,20 +375,20 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_OP_USAGE, []); } - public static function commands_particle_notFound(string $param0) : TranslationContainer{ + public static function commands_particle_notFound(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_PARTICLE_NOTFOUND, [ 0 => $param0, ]); } - public static function commands_particle_success(string $param0, string $param1) : TranslationContainer{ + public static function commands_particle_success(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_PARTICLE_SUCCESS, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_players_list(string $param0, string $param1) : TranslationContainer{ + public static function commands_players_list(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_PLAYERS_LIST, [ 0 => $param0, 1 => $param1, @@ -431,7 +431,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_SAY_USAGE, []); } - public static function commands_seed_success(string $param0) : TranslationContainer{ + public static function commands_seed_success(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_SEED_SUCCESS, [ 0 => $param0, ]); @@ -441,7 +441,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_SEED_USAGE, []); } - public static function commands_setworldspawn_success(string $param0, string $param1, string $param2) : TranslationContainer{ + public static function commands_setworldspawn_success(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_SETWORLDSPAWN_SUCCESS, [ 0 => $param0, 1 => $param1, @@ -453,7 +453,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_SETWORLDSPAWN_USAGE, []); } - public static function commands_spawnpoint_success(string $param0, string $param1, string $param2, string $param3) : TranslationContainer{ + public static function commands_spawnpoint_success(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2, TranslationContainer|string $param3) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_SPAWNPOINT_SUCCESS, [ 0 => $param0, 1 => $param1, @@ -474,19 +474,19 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_STOP_USAGE, []); } - public static function commands_time_added(string $param0) : TranslationContainer{ + public static function commands_time_added(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_TIME_ADDED, [ 0 => $param0, ]); } - public static function commands_time_query(string $param0) : TranslationContainer{ + public static function commands_time_query(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_TIME_QUERY, [ 0 => $param0, ]); } - public static function commands_time_set(string $param0) : TranslationContainer{ + public static function commands_time_set(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_TIME_SET, [ 0 => $param0, ]); @@ -500,14 +500,14 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_TITLE_USAGE, []); } - public static function commands_tp_success(string $param0, string $param1) : TranslationContainer{ + public static function commands_tp_success(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_TP_SUCCESS, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_tp_success_coordinates(string $param0, string $param1, string $param2, string $param3) : TranslationContainer{ + public static function commands_tp_success_coordinates(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2, TranslationContainer|string $param3) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_TP_SUCCESS_COORDINATES, [ 0 => $param0, 1 => $param1, @@ -520,7 +520,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_TP_USAGE, []); } - public static function commands_unban_success(string $param0) : TranslationContainer{ + public static function commands_unban_success(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_UNBAN_SUCCESS, [ 0 => $param0, ]); @@ -534,7 +534,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_UNBANIP_INVALID, []); } - public static function commands_unbanip_success(string $param0) : TranslationContainer{ + public static function commands_unbanip_success(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_UNBANIP_SUCCESS, [ 0 => $param0, ]); @@ -544,7 +544,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_UNBANIP_USAGE, []); } - public static function commands_whitelist_add_success(string $param0) : TranslationContainer{ + public static function commands_whitelist_add_success(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_ADD_SUCCESS, [ 0 => $param0, ]); @@ -562,7 +562,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_ENABLED, []); } - public static function commands_whitelist_list(string $param0, string $param1) : TranslationContainer{ + public static function commands_whitelist_list(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_LIST, [ 0 => $param0, 1 => $param1, @@ -573,7 +573,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_RELOADED, []); } - public static function commands_whitelist_remove_success(string $param0) : TranslationContainer{ + public static function commands_whitelist_remove_success(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_REMOVE_SUCCESS, [ 0 => $param0, ]); @@ -587,14 +587,14 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_USAGE, []); } - public static function death_attack_arrow(string $param0, string $param1) : TranslationContainer{ + public static function death_attack_arrow(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_ARROW, [ 0 => $param0, 1 => $param1, ]); } - public static function death_attack_arrow_item(string $param0, string $param1, string $param2) : TranslationContainer{ + public static function death_attack_arrow_item(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_ARROW_ITEM, [ 0 => $param0, 1 => $param1, @@ -602,94 +602,94 @@ final class KnownTranslationFactory{ ]); } - public static function death_attack_cactus(string $param0) : TranslationContainer{ + public static function death_attack_cactus(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_CACTUS, [ 0 => $param0, ]); } - public static function death_attack_drown(string $param0) : TranslationContainer{ + public static function death_attack_drown(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_DROWN, [ 0 => $param0, ]); } - public static function death_attack_explosion(string $param0) : TranslationContainer{ + public static function death_attack_explosion(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_EXPLOSION, [ 0 => $param0, ]); } - public static function death_attack_explosion_player(string $param0, string $param1) : TranslationContainer{ + public static function death_attack_explosion_player(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_EXPLOSION_PLAYER, [ 0 => $param0, 1 => $param1, ]); } - public static function death_attack_fall(string $param0) : TranslationContainer{ + public static function death_attack_fall(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_FALL, [ 0 => $param0, ]); } - public static function death_attack_generic(string $param0) : TranslationContainer{ + public static function death_attack_generic(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_GENERIC, [ 0 => $param0, ]); } - public static function death_attack_inFire(string $param0) : TranslationContainer{ + public static function death_attack_inFire(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_INFIRE, [ 0 => $param0, ]); } - public static function death_attack_inWall(string $param0) : TranslationContainer{ + public static function death_attack_inWall(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_INWALL, [ 0 => $param0, ]); } - public static function death_attack_lava(string $param0) : TranslationContainer{ + public static function death_attack_lava(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_LAVA, [ 0 => $param0, ]); } - public static function death_attack_magic(string $param0) : TranslationContainer{ + public static function death_attack_magic(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_MAGIC, [ 0 => $param0, ]); } - public static function death_attack_mob(string $param0, string $param1) : TranslationContainer{ + public static function death_attack_mob(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_MOB, [ 0 => $param0, 1 => $param1, ]); } - public static function death_attack_onFire(string $param0) : TranslationContainer{ + public static function death_attack_onFire(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_ONFIRE, [ 0 => $param0, ]); } - public static function death_attack_outOfWorld(string $param0) : TranslationContainer{ + public static function death_attack_outOfWorld(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_OUTOFWORLD, [ 0 => $param0, ]); } - public static function death_attack_player(string $param0, string $param1) : TranslationContainer{ + public static function death_attack_player(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_PLAYER, [ 0 => $param0, 1 => $param1, ]); } - public static function death_attack_player_item(string $param0, string $param1, string $param2) : TranslationContainer{ + public static function death_attack_player_item(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_PLAYER_ITEM, [ 0 => $param0, 1 => $param1, @@ -697,13 +697,13 @@ final class KnownTranslationFactory{ ]); } - public static function death_attack_wither(string $param0) : TranslationContainer{ + public static function death_attack_wither(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_WITHER, [ 0 => $param0, ]); } - public static function death_fell_accident_generic(string $param0) : TranslationContainer{ + public static function death_fell_accident_generic(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::DEATH_FELL_ACCIDENT_GENERIC, [ 0 => $param0, ]); @@ -785,7 +785,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::IP_GET, []); } - public static function ip_warning(string $EXTERNAL_IP, string $INTERNAL_IP) : TranslationContainer{ + public static function ip_warning(TranslationContainer|string $EXTERNAL_IP, TranslationContainer|string $INTERNAL_IP) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::IP_WARNING, [ "EXTERNAL_IP" => $EXTERNAL_IP, "INTERNAL_IP" => $INTERNAL_IP, @@ -796,13 +796,13 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::KICK_ADMIN, []); } - public static function kick_admin_reason(string $param0) : TranslationContainer{ + public static function kick_admin_reason(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::KICK_ADMIN_REASON, [ 0 => $param0, ]); } - public static function kick_reason_cheat(string $param0) : TranslationContainer{ + public static function kick_reason_cheat(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::KICK_REASON_CHEAT, [ 0 => $param0, ]); @@ -812,7 +812,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::LANGUAGE_NAME, []); } - public static function language_selected(string $param0, string $param1) : TranslationContainer{ + public static function language_selected(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::LANGUAGE_SELECTED, [ 0 => $param0, 1 => $param1, @@ -827,13 +827,13 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::MAX_PLAYERS, []); } - public static function multiplayer_player_joined(string $param0) : TranslationContainer{ + public static function multiplayer_player_joined(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::MULTIPLAYER_PLAYER_JOINED, [ 0 => $param0, ]); } - public static function multiplayer_player_left(string $param0) : TranslationContainer{ + public static function multiplayer_player_left(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::MULTIPLAYER_PLAYER_LEFT, [ 0 => $param0, ]); @@ -855,20 +855,20 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::OP_WHO, []); } - public static function pocketmine_command_alias_illegal(string $param0) : TranslationContainer{ + public static function pocketmine_command_alias_illegal(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_ALIAS_ILLEGAL, [ 0 => $param0, ]); } - public static function pocketmine_command_alias_notFound(string $param0, string $param1) : TranslationContainer{ + public static function pocketmine_command_alias_notFound(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_ALIAS_NOTFOUND, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_command_alias_recursive(string $param0, string $param1) : TranslationContainer{ + public static function pocketmine_command_alias_recursive(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_ALIAS_RECURSIVE, [ 0 => $param0, 1 => $param1, @@ -915,7 +915,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_ENCHANT_DESCRIPTION, []); } - public static function pocketmine_command_exception(string $param0, string $param1, string $param2) : TranslationContainer{ + public static function pocketmine_command_exception(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_EXCEPTION, [ 0 => $param0, 1 => $param1, @@ -983,7 +983,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_DESCRIPTION, []); } - public static function pocketmine_command_plugins_success(string $param0, string $param1) : TranslationContainer{ + public static function pocketmine_command_plugins_success(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_SUCCESS, [ 0 => $param0, 1 => $param1, @@ -1074,19 +1074,19 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSDISABLED, []); } - public static function pocketmine_command_timings_timingsRead(string $param0) : TranslationContainer{ + public static function pocketmine_command_timings_timingsRead(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSREAD, [ 0 => $param0, ]); } - public static function pocketmine_command_timings_timingsUpload(string $param0) : TranslationContainer{ + public static function pocketmine_command_timings_timingsUpload(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSUPLOAD, [ 0 => $param0, ]); } - public static function pocketmine_command_timings_timingsWrite(string $param0) : TranslationContainer{ + public static function pocketmine_command_timings_timingsWrite(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSWRITE, [ 0 => $param0, ]); @@ -1124,7 +1124,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_DESCRIPTION, []); } - public static function pocketmine_command_version_minecraftVersion(string $minecraftVersion, string $minecraftProtocolVersion) : TranslationContainer{ + public static function pocketmine_command_version_minecraftVersion(TranslationContainer|string $minecraftVersion, TranslationContainer|string $minecraftProtocolVersion) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_MINECRAFTVERSION, [ "minecraftVersion" => $minecraftVersion, "minecraftProtocolVersion" => $minecraftProtocolVersion, @@ -1135,7 +1135,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_NOSUCHPLUGIN, []); } - public static function pocketmine_command_version_operatingSystem(string $operatingSystemName) : TranslationContainer{ + public static function pocketmine_command_version_operatingSystem(TranslationContainer|string $operatingSystemName) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_OPERATINGSYSTEM, [ "operatingSystemName" => $operatingSystemName, ]); @@ -1145,7 +1145,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPJITDISABLED, []); } - public static function pocketmine_command_version_phpJitEnabled(string $extraJitInfo) : TranslationContainer{ + public static function pocketmine_command_version_phpJitEnabled(TranslationContainer|string $extraJitInfo) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPJITENABLED, [ "extraJitInfo" => $extraJitInfo, ]); @@ -1155,25 +1155,25 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPJITNOTSUPPORTED, []); } - public static function pocketmine_command_version_phpJitStatus(string $jitStatus) : TranslationContainer{ + public static function pocketmine_command_version_phpJitStatus(TranslationContainer|string $jitStatus) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPJITSTATUS, [ "jitStatus" => $jitStatus, ]); } - public static function pocketmine_command_version_phpVersion(string $phpVersion) : TranslationContainer{ + public static function pocketmine_command_version_phpVersion(TranslationContainer|string $phpVersion) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPVERSION, [ "phpVersion" => $phpVersion, ]); } - public static function pocketmine_command_version_serverSoftwareName(string $serverSoftwareName) : TranslationContainer{ + public static function pocketmine_command_version_serverSoftwareName(TranslationContainer|string $serverSoftwareName) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_SERVERSOFTWARENAME, [ "serverSoftwareName" => $serverSoftwareName, ]); } - public static function pocketmine_command_version_serverSoftwareVersion(string $serverSoftwareVersion, string $serverGitHash) : TranslationContainer{ + public static function pocketmine_command_version_serverSoftwareVersion(TranslationContainer|string $serverSoftwareVersion, TranslationContainer|string $serverGitHash) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_SERVERSOFTWAREVERSION, [ "serverSoftwareVersion" => $serverSoftwareVersion, "serverGitHash" => $serverGitHash, @@ -1188,7 +1188,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_WHITELIST_DESCRIPTION, []); } - public static function pocketmine_crash_archive(string $param0, string $param1) : TranslationContainer{ + public static function pocketmine_crash_archive(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_CRASH_ARCHIVE, [ 0 => $param0, 1 => $param1, @@ -1199,37 +1199,37 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_CRASH_CREATE, []); } - public static function pocketmine_crash_error(string $param0) : TranslationContainer{ + public static function pocketmine_crash_error(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_CRASH_ERROR, [ 0 => $param0, ]); } - public static function pocketmine_crash_submit(string $param0) : TranslationContainer{ + public static function pocketmine_crash_submit(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_CRASH_SUBMIT, [ 0 => $param0, ]); } - public static function pocketmine_data_playerCorrupted(string $param0) : TranslationContainer{ + public static function pocketmine_data_playerCorrupted(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DATA_PLAYERCORRUPTED, [ 0 => $param0, ]); } - public static function pocketmine_data_playerNotFound(string $param0) : TranslationContainer{ + public static function pocketmine_data_playerNotFound(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DATA_PLAYERNOTFOUND, [ 0 => $param0, ]); } - public static function pocketmine_data_playerOld(string $param0) : TranslationContainer{ + public static function pocketmine_data_playerOld(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DATA_PLAYEROLD, [ 0 => $param0, ]); } - public static function pocketmine_data_saveError(string $param0, string $param1) : TranslationContainer{ + public static function pocketmine_data_saveError(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DATA_SAVEERROR, [ 0 => $param0, 1 => $param1, @@ -1240,13 +1240,13 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DEBUG_ENABLE, []); } - public static function pocketmine_disconnect_incompatibleProtocol(string $param0) : TranslationContainer{ + public static function pocketmine_disconnect_incompatibleProtocol(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DISCONNECT_INCOMPATIBLEPROTOCOL, [ 0 => $param0, ]); } - public static function pocketmine_disconnect_invalidSession(string $param0) : TranslationContainer{ + public static function pocketmine_disconnect_invalidSession(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION, [ 0 => $param0, ]); @@ -1268,19 +1268,19 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_TOOLATE, []); } - public static function pocketmine_level_ambiguousFormat(string $param0) : TranslationContainer{ + public static function pocketmine_level_ambiguousFormat(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_AMBIGUOUSFORMAT, [ 0 => $param0, ]); } - public static function pocketmine_level_backgroundGeneration(string $param0) : TranslationContainer{ + public static function pocketmine_level_backgroundGeneration(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_BACKGROUNDGENERATION, [ 0 => $param0, ]); } - public static function pocketmine_level_badDefaultFormat(string $param0) : TranslationContainer{ + public static function pocketmine_level_badDefaultFormat(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_BADDEFAULTFORMAT, [ 0 => $param0, ]); @@ -1290,27 +1290,27 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_DEFAULTERROR, []); } - public static function pocketmine_level_generationError(string $param0, string $param1) : TranslationContainer{ + public static function pocketmine_level_generationError(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_GENERATIONERROR, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_level_loadError(string $param0, string $param1) : TranslationContainer{ + public static function pocketmine_level_loadError(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_LOADERROR, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_level_notFound(string $param0) : TranslationContainer{ + public static function pocketmine_level_notFound(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_NOTFOUND, [ 0 => $param0, ]); } - public static function pocketmine_level_preparing(string $param0) : TranslationContainer{ + public static function pocketmine_level_preparing(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_PREPARING, [ 0 => $param0, ]); @@ -1320,25 +1320,25 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_UNKNOWNFORMAT, []); } - public static function pocketmine_level_unloading(string $param0) : TranslationContainer{ + public static function pocketmine_level_unloading(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_UNLOADING, [ 0 => $param0, ]); } - public static function pocketmine_player_invalidEntity(string $param0) : TranslationContainer{ + public static function pocketmine_player_invalidEntity(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLAYER_INVALIDENTITY, [ 0 => $param0, ]); } - public static function pocketmine_player_invalidMove(string $param0) : TranslationContainer{ + public static function pocketmine_player_invalidMove(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLAYER_INVALIDMOVE, [ 0 => $param0, ]); } - public static function pocketmine_player_logIn(string $param0, string $param1, string $param2, string $param3, string $param4, string $param5, string $param6, string $param7) : TranslationContainer{ + public static function pocketmine_player_logIn(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2, TranslationContainer|string $param3, TranslationContainer|string $param4, TranslationContainer|string $param5, TranslationContainer|string $param6, TranslationContainer|string $param7) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLAYER_LOGIN, [ 0 => $param0, 1 => $param1, @@ -1351,7 +1351,7 @@ final class KnownTranslationFactory{ ]); } - public static function pocketmine_player_logOut(string $param0, string $param1, string $param2, string $param3) : TranslationContainer{ + public static function pocketmine_player_logOut(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2, TranslationContainer|string $param3) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLAYER_LOGOUT, [ 0 => $param0, 1 => $param1, @@ -1360,14 +1360,14 @@ final class KnownTranslationFactory{ ]); } - public static function pocketmine_plugin_aliasError(string $param0, string $param1) : TranslationContainer{ + public static function pocketmine_plugin_aliasError(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_ALIASERROR, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_plugin_ambiguousMinAPI(string $param0) : TranslationContainer{ + public static function pocketmine_plugin_ambiguousMinAPI(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_AMBIGUOUSMINAPI, [ 0 => $param0, ]); @@ -1377,14 +1377,14 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_CIRCULARDEPENDENCY, []); } - public static function pocketmine_plugin_commandError(string $param0, string $param1) : TranslationContainer{ + public static function pocketmine_plugin_commandError(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_COMMANDERROR, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_plugin_deprecatedEvent(string $param0, string $param1, string $param2) : TranslationContainer{ + public static function pocketmine_plugin_deprecatedEvent(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_DEPRECATEDEVENT, [ 0 => $param0, 1 => $param1, @@ -1392,25 +1392,25 @@ final class KnownTranslationFactory{ ]); } - public static function pocketmine_plugin_disable(string $param0) : TranslationContainer{ + public static function pocketmine_plugin_disable(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_DISABLE, [ 0 => $param0, ]); } - public static function pocketmine_plugin_duplicateError(string $param0) : TranslationContainer{ + public static function pocketmine_plugin_duplicateError(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_DUPLICATEERROR, [ 0 => $param0, ]); } - public static function pocketmine_plugin_enable(string $param0) : TranslationContainer{ + public static function pocketmine_plugin_enable(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_ENABLE, [ 0 => $param0, ]); } - public static function pocketmine_plugin_fileError(string $param0, string $param1, string $param2) : TranslationContainer{ + public static function pocketmine_plugin_fileError(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_FILEERROR, [ 0 => $param0, 1 => $param1, @@ -1418,43 +1418,43 @@ final class KnownTranslationFactory{ ]); } - public static function pocketmine_plugin_genericLoadError(string $param0) : TranslationContainer{ + public static function pocketmine_plugin_genericLoadError(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_GENERICLOADERROR, [ 0 => $param0, ]); } - public static function pocketmine_plugin_incompatibleAPI(string $param0) : TranslationContainer{ + public static function pocketmine_plugin_incompatibleAPI(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEAPI, [ 0 => $param0, ]); } - public static function pocketmine_plugin_incompatibleOS(string $param0) : TranslationContainer{ + public static function pocketmine_plugin_incompatibleOS(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEOS, [ 0 => $param0, ]); } - public static function pocketmine_plugin_incompatiblePhpVersion(string $param0) : TranslationContainer{ + public static function pocketmine_plugin_incompatiblePhpVersion(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEPHPVERSION, [ 0 => $param0, ]); } - public static function pocketmine_plugin_incompatibleProtocol(string $param0) : TranslationContainer{ + public static function pocketmine_plugin_incompatibleProtocol(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEPROTOCOL, [ 0 => $param0, ]); } - public static function pocketmine_plugin_load(string $param0) : TranslationContainer{ + public static function pocketmine_plugin_load(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_LOAD, [ 0 => $param0, ]); } - public static function pocketmine_plugin_loadError(string $param0, string $param1) : TranslationContainer{ + public static function pocketmine_plugin_loadError(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_LOADERROR, [ 0 => $param0, 1 => $param1, @@ -1465,13 +1465,13 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_RESTRICTEDNAME, []); } - public static function pocketmine_plugin_spacesDiscouraged(string $param0) : TranslationContainer{ + public static function pocketmine_plugin_spacesDiscouraged(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_SPACESDISCOURAGED, [ 0 => $param0, ]); } - public static function pocketmine_plugin_unknownDependency(string $param0) : TranslationContainer{ + public static function pocketmine_plugin_unknownDependency(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_UNKNOWNDEPENDENCY, [ 0 => $param0, ]); @@ -1481,7 +1481,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SAVE_START, []); } - public static function pocketmine_save_success(string $param0) : TranslationContainer{ + public static function pocketmine_save_success(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SAVE_SUCCESS, [ 0 => $param0, ]); @@ -1507,13 +1507,13 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_AUTHWARNING, []); } - public static function pocketmine_server_defaultGameMode(string $param0) : TranslationContainer{ + public static function pocketmine_server_defaultGameMode(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEFAULTGAMEMODE, [ 0 => $param0, ]); } - public static function pocketmine_server_devBuild_error1(string $param0) : TranslationContainer{ + public static function pocketmine_server_devBuild_error1(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR1, [ 0 => $param0, ]); @@ -1527,19 +1527,19 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR3, []); } - public static function pocketmine_server_devBuild_error4(string $param0) : TranslationContainer{ + public static function pocketmine_server_devBuild_error4(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR4, [ 0 => $param0, ]); } - public static function pocketmine_server_devBuild_error5(string $param0) : TranslationContainer{ + public static function pocketmine_server_devBuild_error5(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR5, [ 0 => $param0, ]); } - public static function pocketmine_server_devBuild_warning1(string $param0) : TranslationContainer{ + public static function pocketmine_server_devBuild_warning1(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_WARNING1, [ 0 => $param0, ]); @@ -1553,20 +1553,20 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_WARNING3, []); } - public static function pocketmine_server_donate(string $param0) : TranslationContainer{ + public static function pocketmine_server_donate(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DONATE, [ 0 => $param0, ]); } - public static function pocketmine_server_info(string $param0, string $param1) : TranslationContainer{ + public static function pocketmine_server_info(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_INFO, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_server_info_extended(string $param0, string $param1, string $param2, string $param3) : TranslationContainer{ + public static function pocketmine_server_info_extended(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2, TranslationContainer|string $param3) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_INFO_EXTENDED, [ 0 => $param0, 1 => $param1, @@ -1575,33 +1575,33 @@ final class KnownTranslationFactory{ ]); } - public static function pocketmine_server_license(string $param0) : TranslationContainer{ + public static function pocketmine_server_license(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_LICENSE, [ 0 => $param0, ]); } - public static function pocketmine_server_networkStart(string $param0, string $param1) : TranslationContainer{ + public static function pocketmine_server_networkStart(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_NETWORKSTART, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_server_query_running(string $param0, string $param1) : TranslationContainer{ + public static function pocketmine_server_query_running(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_QUERY_RUNNING, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_server_start(string $param0) : TranslationContainer{ + public static function pocketmine_server_start(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_START, [ 0 => $param0, ]); } - public static function pocketmine_server_startFinished(string $param0) : TranslationContainer{ + public static function pocketmine_server_startFinished(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_STARTFINISHED, [ 0 => $param0, ]); @@ -1615,7 +1615,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGINS, []); } - public static function pocketmine_will_start(string $param0) : TranslationContainer{ + public static function pocketmine_will_start(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::POCKETMINE_WILL_START, [ 0 => $param0, ]); @@ -1765,7 +1765,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::TILE_BED_TOOFAR, []); } - public static function welcome_to_pocketmine(string $param0) : TranslationContainer{ + public static function welcome_to_pocketmine(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::WELCOME_TO_POCKETMINE, [ 0 => $param0, ]); @@ -1787,7 +1787,7 @@ final class KnownTranslationFactory{ return new TranslationContainer(KnownTranslationKeys::YOU_HAVE_FINISHED, []); } - public static function you_have_to_accept_the_license(string $param0) : TranslationContainer{ + public static function you_have_to_accept_the_license(TranslationContainer|string $param0) : TranslationContainer{ return new TranslationContainer(KnownTranslationKeys::YOU_HAVE_TO_ACCEPT_THE_LICENSE, [ 0 => $param0, ]); diff --git a/src/lang/Language.php b/src/lang/Language.php index 56f349bfa4..ec95b19058 100644 --- a/src/lang/Language.php +++ b/src/lang/Language.php @@ -130,14 +130,15 @@ class Language{ } /** - * @param (float|int|string)[] $params + * @param (float|int|string|TranslationContainer)[] $params */ public function translateString(string $str, array $params = [], ?string $onlyPrefix = null) : string{ $baseText = $this->get($str); $baseText = $this->parseTranslation(($onlyPrefix === null or strpos($str, $onlyPrefix) === 0) ? $baseText : $str, $onlyPrefix); foreach($params as $i => $p){ - $baseText = str_replace("{%$i}", $this->parseTranslation((string) $p), $baseText); + $replacement = $p instanceof TranslationContainer ? $this->translate($p) : $this->parseTranslation((string) $p); + $baseText = str_replace("{%$i}", $replacement, $baseText); } return $baseText; @@ -148,7 +149,8 @@ class Language{ $baseText = $this->parseTranslation($baseText ?? $c->getText()); foreach($c->getParameters() as $i => $p){ - $baseText = str_replace("{%$i}", $this->parseTranslation($p), $baseText); + $replacement = $p instanceof TranslationContainer ? $this->translate($p) : $this->parseTranslation($p); + $baseText = str_replace("{%$i}", $replacement, $baseText); } return $baseText; diff --git a/src/lang/TranslationContainer.php b/src/lang/TranslationContainer.php index 4780535b42..1b51f11ef3 100644 --- a/src/lang/TranslationContainer.php +++ b/src/lang/TranslationContainer.php @@ -27,17 +27,21 @@ final class TranslationContainer{ /** @var string $text */ protected $text; - /** @var string[] $params */ + /** @var string[]|TranslationContainer[] $params */ protected $params = []; /** - * @param (float|int|string)[] $params + * @param (float|int|string|TranslationContainer)[] $params */ public function __construct(string $text, array $params = []){ $this->text = $text; - foreach($params as $k => $str){ - $this->params[$k] = (string) $str; + foreach($params as $k => $param){ + if(!($param instanceof TranslationContainer)){ + $this->params[$k] = (string) $param; + }else{ + $this->params[$k] = $param; + } } } @@ -46,13 +50,13 @@ final class TranslationContainer{ } /** - * @return string[] + * @return string[]|TranslationContainer[] */ public function getParameters() : array{ return $this->params; } - public function getParameter(int|string $i) : ?string{ + public function getParameter(int|string $i) : TranslationContainer|string|null{ return $this->params[$i] ?? null; } diff --git a/src/player/Player.php b/src/player/Player.php index be5fec6c34..8f423c5297 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -113,6 +113,7 @@ use pocketmine\world\sound\Sound; use pocketmine\world\World; use Ramsey\Uuid\UuidInterface; use function abs; +use function array_map; use function assert; use function count; use function explode; @@ -1781,9 +1782,11 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } /** - * @param string[] $parameters + * @param string[]|TranslationContainer[] $parameters */ public function sendTranslation(string $message, array $parameters = []) : void{ + //we can't send nested translations to the client, so make sure they are always pre-translated by the server + $parameters = array_map(fn(string|TranslationContainer $p) => $p instanceof TranslationContainer ? $this->getLanguage()->translate($p) : $p, $parameters); if(!$this->server->isLanguageForced()){ foreach($parameters as $i => $p){ $parameters[$i] = $this->getLanguage()->translateString($p, [], "pocketmine."); diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 695a38ab78..425b28e344 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -257,7 +257,7 @@ class PluginManager{ $name = $description->getName(); if(stripos($name, "pocketmine") !== false or stripos($name, "minecraft") !== false or stripos($name, "mojang") !== false){ - $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError($name, "%" . KnownTranslationKeys::POCKETMINE_PLUGIN_RESTRICTEDNAME))); + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError($name, KnownTranslationFactory::pocketmine_plugin_restrictedName()))); continue; } if(strpos($name, " ") !== false){ @@ -272,7 +272,7 @@ class PluginManager{ if(!ApiVersion::isCompatible($this->server->getApiVersion(), $description->getCompatibleApis())){ $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( $name, - $this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_incompatibleAPI(implode(", ", $description->getCompatibleApis()))) + KnownTranslationFactory::pocketmine_plugin_incompatibleAPI(implode(", ", $description->getCompatibleApis())) ))); continue; } @@ -280,7 +280,7 @@ class PluginManager{ if(count($ambiguousVersions) > 0){ $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( $name, - $this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_ambiguousMinAPI(implode(", ", $ambiguousVersions))) + KnownTranslationFactory::pocketmine_plugin_ambiguousMinAPI(implode(", ", $ambiguousVersions)) ))); continue; } @@ -288,7 +288,7 @@ class PluginManager{ if(count($description->getCompatibleOperatingSystems()) > 0 and !in_array(Utils::getOS(), $description->getCompatibleOperatingSystems(), true)) { $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( $name, - $this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_incompatibleOS(implode(", ", $description->getCompatibleOperatingSystems()))) + KnownTranslationFactory::pocketmine_plugin_incompatibleOS(implode(", ", $description->getCompatibleOperatingSystems())) ))); continue; } @@ -298,7 +298,7 @@ class PluginManager{ if(count(array_intersect($pluginMcpeProtocols, $serverMcpeProtocols)) === 0){ $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( $name, - $this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_incompatibleProtocol(implode(", ", $pluginMcpeProtocols))) + KnownTranslationFactory::pocketmine_plugin_incompatibleProtocol(implode(", ", $pluginMcpeProtocols)) ))); continue; } @@ -336,7 +336,7 @@ class PluginManager{ }elseif(!isset($plugins[$dependency])){ $this->server->getLogger()->critical($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( $name, - $this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_unknownDependency($dependency)) + KnownTranslationFactory::pocketmine_plugin_unknownDependency($dependency) ))); unset($plugins[$name]); continue 2; @@ -381,7 +381,7 @@ class PluginManager{ if($loadedThisLoop === 0){ //No plugins loaded :( foreach($plugins as $name => $file){ - $this->server->getLogger()->critical($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError($name, "%" . KnownTranslationKeys::POCKETMINE_PLUGIN_CIRCULARDEPENDENCY))); + $this->server->getLogger()->critical($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError($name, KnownTranslationFactory::pocketmine_plugin_circularDependency()))); } $plugins = []; } diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 45a57e3f70..652f4684ad 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -196,9 +196,9 @@ class WorldManager{ $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_loadError( $name, count($providers) === 0 ? - $this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_unknownFormat()) : - $this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_ambiguousFormat(implode(", ", array_keys($providers))) - )))); + KnownTranslationFactory::pocketmine_level_unknownFormat() : + KnownTranslationFactory::pocketmine_level_ambiguousFormat(implode(", ", array_keys($providers))) + ))); return false; } $providerClass = array_shift($providers); From 4748b0db37c55a7fba7ae263fd16ce8c1aecdba0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 14 Aug 2021 21:28:38 +0100 Subject: [PATCH 2698/3224] PluginManager: remove unused import --- src/plugin/PluginManager.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 425b28e344..c646a4dffb 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -32,7 +32,6 @@ use pocketmine\event\plugin\PluginDisableEvent; use pocketmine\event\plugin\PluginEnableEvent; use pocketmine\event\RegisteredListener; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\permission\DefaultPermissions; use pocketmine\permission\PermissionManager; From db90b40bdd4be4472249c7c26bf35e3c453c3ded Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 15 Aug 2021 16:00:16 +0100 Subject: [PATCH 2699/3224] Command: remove unnecessary branching in broadcastCommandMessage() this problem is handled automatically now that nested translations are supported. --- src/command/Command.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/command/Command.php b/src/command/Command.php index d723992cad..0c6b3cb335 100644 --- a/src/command/Command.php +++ b/src/command/Command.php @@ -232,11 +232,7 @@ abstract class Command{ public static function broadcastCommandMessage(CommandSender $source, TranslationContainer|string $message, bool $sendToSource = true) : void{ $users = $source->getServer()->getBroadcastChannelSubscribers(Server::BROADCAST_CHANNEL_ADMINISTRATIVE); - if($message instanceof TranslationContainer){ - $result = $message->format("[" . $source->getName() . ": ", "]"); - }else{ - $result = KnownTranslationFactory::chat_type_admin($source->getName(), $message); - } + $result = KnownTranslationFactory::chat_type_admin($source->getName(), $message); $colored = $result->prefix(TextFormat::GRAY . TextFormat::ITALIC); if($sendToSource and !($source instanceof ConsoleCommandSender)){ From 177eecf9eef8ecd0f96600659b034ed94e085688 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 15 Aug 2021 16:04:27 +0100 Subject: [PATCH 2700/3224] [ci skip] changelog: mention recent translation changes --- changelogs/4.0-snapshot.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 29d3bb32a7..8fa02fb84b 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -713,6 +713,10 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - The following classes have been renamed: - `BaseLang` -> `Language` - `LanguageNotFoundException` has been added. This is thrown when trying to construct a `Language` which doesn't exist in the server files. +- `TranslationContainer` no longer discards keys for translation parameters. Previously, only the insertion order was considered. +- `TranslationContainer` now supports string keys for translation parameters. +- `TranslationContainer` now supports providing other `TranslationContainers` as translation parameters. +- `Language->translateString()` now supports providing `TranslationContainers` as translation parameters. ### Network From 5bdcc0339f3645899a108abf899fbeb74fbce61c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 15 Aug 2021 16:13:07 +0100 Subject: [PATCH 2701/3224] build/generate-known-translation-apis: make the ref to TranslationContainer statically analysable this ensures that it will follow refactors automatically with no additional changes. --- build/generate-known-translation-apis.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/build/generate-known-translation-apis.php b/build/generate-known-translation-apis.php index bb0679b01c..ad05db0b37 100644 --- a/build/generate-known-translation-apis.php +++ b/build/generate-known-translation-apis.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\build\generate_known_translation_apis; +use pocketmine\lang\TranslationContainer; use Webmozart\PathUtil\Path; use function array_map; use function count; @@ -130,6 +131,8 @@ HEADER; ksort($languageDefinitions, SORT_STRING); $parameterRegex = '/{%(.+?)}/'; + + $translationContainerClass = (new \ReflectionClass(TranslationContainer::class))->getShortName(); foreach($languageDefinitions as $key => $value){ $parameters = []; if(preg_match_all($parameterRegex, $value, $matches) > 0){ @@ -143,8 +146,8 @@ HEADER; } echo "\tpublic static function " . functionify($key) . - "(" . implode(", ", array_map(fn(string $paramName) => "TranslationContainer|string \$$paramName", $parameters)) . ") : TranslationContainer{\n"; - echo "\t\treturn new TranslationContainer(KnownTranslationKeys::" . constantify($key) . ", ["; + "(" . implode(", ", array_map(fn(string $paramName) => "$translationContainerClass|string \$$paramName", $parameters)) . ") : $translationContainerClass{\n"; + echo "\t\treturn new $translationContainerClass(KnownTranslationKeys::" . constantify($key) . ", ["; foreach($parameters as $parameterKey => $parameterName){ echo "\n\t\t\t"; if(!is_numeric($parameterKey)){ From 789a669395a0d4d9e2ca59b3244e41f3ff05b5b3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 15 Aug 2021 16:17:46 +0100 Subject: [PATCH 2702/3224] Rename TranslationContainer -> Translatable --- build/generate-known-translation-apis.php | 4 +- src/Server.php | 4 +- src/command/Command.php | 4 +- src/command/CommandSender.php | 4 +- src/command/defaults/EnchantCommand.php | 4 +- src/command/defaults/GamemodeCommand.php | 4 +- src/command/defaults/VanillaCommand.php | 6 +- src/console/ConsoleCommandSender.php | 6 +- src/event/player/PlayerDeathEvent.php | 16 +- src/event/player/PlayerJoinEvent.php | 10 +- src/event/player/PlayerKickEvent.php | 10 +- src/event/player/PlayerQuitEvent.php | 10 +- src/lang/KnownTranslationFactory.php | 1388 ++++++++--------- src/lang/Language.php | 8 +- ...nslationContainer.php => Translatable.php} | 12 +- src/player/Player.php | 24 +- 16 files changed, 757 insertions(+), 757 deletions(-) rename src/lang/{TranslationContainer.php => Translatable.php} (83%) diff --git a/build/generate-known-translation-apis.php b/build/generate-known-translation-apis.php index ad05db0b37..2772b3f4a4 100644 --- a/build/generate-known-translation-apis.php +++ b/build/generate-known-translation-apis.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\build\generate_known_translation_apis; -use pocketmine\lang\TranslationContainer; +use pocketmine\lang\Translatable; use Webmozart\PathUtil\Path; use function array_map; use function count; @@ -132,7 +132,7 @@ HEADER; $parameterRegex = '/{%(.+?)}/'; - $translationContainerClass = (new \ReflectionClass(TranslationContainer::class))->getShortName(); + $translationContainerClass = (new \ReflectionClass(Translatable::class))->getShortName(); foreach($languageDefinitions as $key => $value){ $parameters = []; if(preg_match_all($parameterRegex, $value, $matches) > 0){ diff --git a/src/Server.php b/src/Server.php index f5aebbbb9b..888b34f1f7 100644 --- a/src/Server.php +++ b/src/Server.php @@ -46,7 +46,7 @@ use pocketmine\event\server\QueryRegenerateEvent; use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\Language; use pocketmine\lang\LanguageNotFoundException; -use pocketmine\lang\TranslationContainer; +use pocketmine\lang\Translatable; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\CompoundTag; @@ -1121,7 +1121,7 @@ class Server{ /** * @param CommandSender[]|null $recipients */ - public function broadcastMessage(TranslationContainer|string $message, ?array $recipients = null) : int{ + public function broadcastMessage(Translatable|string $message, ?array $recipients = null) : int{ $recipients = $recipients ?? $this->getBroadcastChannelSubscribers(self::BROADCAST_CHANNEL_USERS); foreach($recipients as $recipient){ diff --git a/src/command/Command.php b/src/command/Command.php index 0c6b3cb335..fbd9797848 100644 --- a/src/command/Command.php +++ b/src/command/Command.php @@ -29,7 +29,7 @@ namespace pocketmine\command; use pocketmine\command\utils\CommandException; use pocketmine\console\ConsoleCommandSender; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\TranslationContainer; +use pocketmine\lang\Translatable; use pocketmine\permission\PermissionManager; use pocketmine\Server; use pocketmine\timings\Timings; @@ -230,7 +230,7 @@ abstract class Command{ $this->usageMessage = $usage; } - public static function broadcastCommandMessage(CommandSender $source, TranslationContainer|string $message, bool $sendToSource = true) : void{ + public static function broadcastCommandMessage(CommandSender $source, Translatable|string $message, bool $sendToSource = true) : void{ $users = $source->getServer()->getBroadcastChannelSubscribers(Server::BROADCAST_CHANNEL_ADMINISTRATIVE); $result = KnownTranslationFactory::chat_type_admin($source->getName(), $message); $colored = $result->prefix(TextFormat::GRAY . TextFormat::ITALIC); diff --git a/src/command/CommandSender.php b/src/command/CommandSender.php index 0776a614ff..50734758c6 100644 --- a/src/command/CommandSender.php +++ b/src/command/CommandSender.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\command; use pocketmine\lang\Language; -use pocketmine\lang\TranslationContainer; +use pocketmine\lang\Translatable; use pocketmine\permission\Permissible; use pocketmine\Server; @@ -32,7 +32,7 @@ interface CommandSender extends Permissible{ public function getLanguage() : Language; - public function sendMessage(TranslationContainer|string $message) : void; + public function sendMessage(Translatable|string $message) : void; public function getServer() : Server; diff --git a/src/command/defaults/EnchantCommand.php b/src/command/defaults/EnchantCommand.php index 08135bca56..592c7c57f2 100644 --- a/src/command/defaults/EnchantCommand.php +++ b/src/command/defaults/EnchantCommand.php @@ -29,7 +29,7 @@ use pocketmine\item\enchantment\EnchantmentInstance; use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; +use pocketmine\lang\Translatable; use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\TextFormat; use function count; @@ -86,7 +86,7 @@ class EnchantCommand extends VanillaCommand{ $item->addEnchantment(new EnchantmentInstance($enchantment, $level)); $player->getInventory()->setItemInHand($item); - self::broadcastCommandMessage($sender, new TranslationContainer(KnownTranslationKeys::COMMANDS_ENCHANT_SUCCESS, [$player->getName()])); + self::broadcastCommandMessage($sender, new Translatable(KnownTranslationKeys::COMMANDS_ENCHANT_SUCCESS, [$player->getName()])); return true; } } diff --git a/src/command/defaults/GamemodeCommand.php b/src/command/defaults/GamemodeCommand.php index be26935eca..a632458697 100644 --- a/src/command/defaults/GamemodeCommand.php +++ b/src/command/defaults/GamemodeCommand.php @@ -28,7 +28,7 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; +use pocketmine\lang\Translatable; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\GameMode; use pocketmine\player\Player; @@ -81,7 +81,7 @@ class GamemodeCommand extends VanillaCommand{ if($target === $sender){ Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_gamemode_success_self($gameMode->getTranslationKey())); }else{ - $target->sendMessage(new TranslationContainer(KnownTranslationKeys::GAMEMODE_CHANGED, [$gameMode->getTranslationKey()])); + $target->sendMessage(new Translatable(KnownTranslationKeys::GAMEMODE_CHANGED, [$gameMode->getTranslationKey()])); Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_gamemode_success_other($gameMode->getTranslationKey(), $target->getName())); } } diff --git a/src/command/defaults/VanillaCommand.php b/src/command/defaults/VanillaCommand.php index b12ccf2786..7aa1c757dc 100644 --- a/src/command/defaults/VanillaCommand.php +++ b/src/command/defaults/VanillaCommand.php @@ -27,7 +27,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\TranslationContainer; +use pocketmine\lang\Translatable; use pocketmine\utils\TextFormat; use function is_numeric; use function substr; @@ -83,11 +83,11 @@ abstract class VanillaCommand extends Command{ $v = (int) $input; if($v > $max){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_NUM_TOOBIG, [$input, (string) $max])); + $sender->sendMessage(new Translatable(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_NUM_TOOBIG, [$input, (string) $max])); return null; } if($v < $min){ - $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_NUM_TOOSMALL, [$input, (string) $min])); + $sender->sendMessage(new Translatable(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_NUM_TOOSMALL, [$input, (string) $min])); return null; } diff --git a/src/console/ConsoleCommandSender.php b/src/console/ConsoleCommandSender.php index 219ecb2afd..3d2feb762b 100644 --- a/src/console/ConsoleCommandSender.php +++ b/src/console/ConsoleCommandSender.php @@ -25,7 +25,7 @@ namespace pocketmine\console; use pocketmine\command\CommandSender; use pocketmine\lang\Language; -use pocketmine\lang\TranslationContainer; +use pocketmine\lang\Translatable; use pocketmine\permission\DefaultPermissions; use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissibleDelegateTrait; @@ -58,9 +58,9 @@ class ConsoleCommandSender implements CommandSender{ return $this->language; } - public function sendMessage(TranslationContainer|string $message) : void{ + public function sendMessage(Translatable|string $message) : void{ $server = $this->getServer(); - if($message instanceof TranslationContainer){ + if($message instanceof Translatable){ $message = $this->getLanguage()->translate($message); }else{ $message = $this->getLanguage()->translateString($message); diff --git a/src/event/player/PlayerDeathEvent.php b/src/event/player/PlayerDeathEvent.php index b3d55dc13c..8b018c1a1f 100644 --- a/src/event/player/PlayerDeathEvent.php +++ b/src/event/player/PlayerDeathEvent.php @@ -31,23 +31,23 @@ use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDeathEvent; use pocketmine\item\Item; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\TranslationContainer; +use pocketmine\lang\Translatable; use pocketmine\player\Player; class PlayerDeathEvent extends EntityDeathEvent{ /** @var Player */ protected $entity; - /** @var TranslationContainer|string */ + /** @var Translatable|string */ private $deathMessage; /** @var bool */ private $keepInventory = false; /** - * @param Item[] $drops - * @param string|TranslationContainer|null $deathMessage Null will cause the default vanilla message to be used + * @param Item[] $drops + * @param string|Translatable|null $deathMessage Null will cause the default vanilla message to be used */ - public function __construct(Player $entity, array $drops, int $xp, TranslationContainer|string|null $deathMessage){ + public function __construct(Player $entity, array $drops, int $xp, Translatable|string|null $deathMessage){ parent::__construct($entity, $drops, $xp); $this->deathMessage = $deathMessage ?? self::deriveMessage($entity->getDisplayName(), $entity->getLastDamageCause()); } @@ -63,11 +63,11 @@ class PlayerDeathEvent extends EntityDeathEvent{ return $this->entity; } - public function getDeathMessage() : TranslationContainer|string{ + public function getDeathMessage() : Translatable|string{ return $this->deathMessage; } - public function setDeathMessage(TranslationContainer|string $deathMessage) : void{ + public function setDeathMessage(Translatable|string $deathMessage) : void{ $this->deathMessage = $deathMessage; } @@ -82,7 +82,7 @@ class PlayerDeathEvent extends EntityDeathEvent{ /** * Returns the vanilla death message for the given death cause. */ - public static function deriveMessage(string $name, ?EntityDamageEvent $deathCause) : TranslationContainer{ + public static function deriveMessage(string $name, ?EntityDamageEvent $deathCause) : Translatable{ switch($deathCause === null ? EntityDamageEvent::CAUSE_CUSTOM : $deathCause->getCause()){ case EntityDamageEvent::CAUSE_ENTITY_ATTACK: if($deathCause instanceof EntityDamageByEntityEvent){ diff --git a/src/event/player/PlayerJoinEvent.php b/src/event/player/PlayerJoinEvent.php index 56900874b6..e46e3fd7d5 100644 --- a/src/event/player/PlayerJoinEvent.php +++ b/src/event/player/PlayerJoinEvent.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\event\player; -use pocketmine\lang\TranslationContainer; +use pocketmine\lang\Translatable; use pocketmine\player\Player; /** @@ -34,19 +34,19 @@ use pocketmine\player\Player; * @see PlayerLoginEvent */ class PlayerJoinEvent extends PlayerEvent{ - /** @var string|TranslationContainer */ + /** @var string|Translatable */ protected $joinMessage; - public function __construct(Player $player, TranslationContainer|string $joinMessage){ + public function __construct(Player $player, Translatable|string $joinMessage){ $this->player = $player; $this->joinMessage = $joinMessage; } - public function setJoinMessage(TranslationContainer|string $joinMessage) : void{ + public function setJoinMessage(Translatable|string $joinMessage) : void{ $this->joinMessage = $joinMessage; } - public function getJoinMessage() : TranslationContainer|string{ + public function getJoinMessage() : Translatable|string{ return $this->joinMessage; } } diff --git a/src/event/player/PlayerKickEvent.php b/src/event/player/PlayerKickEvent.php index 4119d18b81..7c91399d01 100644 --- a/src/event/player/PlayerKickEvent.php +++ b/src/event/player/PlayerKickEvent.php @@ -25,7 +25,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; -use pocketmine\lang\TranslationContainer; +use pocketmine\lang\Translatable; use pocketmine\player\Player; /** @@ -34,13 +34,13 @@ use pocketmine\player\Player; class PlayerKickEvent extends PlayerEvent implements Cancellable{ use CancellableTrait; - /** @var TranslationContainer|string */ + /** @var Translatable|string */ protected $quitMessage; /** @var string */ protected $reason; - public function __construct(Player $player, string $reason, TranslationContainer|string $quitMessage){ + public function __construct(Player $player, string $reason, Translatable|string $quitMessage){ $this->player = $player; $this->quitMessage = $quitMessage; $this->reason = $reason; @@ -54,11 +54,11 @@ class PlayerKickEvent extends PlayerEvent implements Cancellable{ return $this->reason; } - public function setQuitMessage(TranslationContainer|string $quitMessage) : void{ + public function setQuitMessage(Translatable|string $quitMessage) : void{ $this->quitMessage = $quitMessage; } - public function getQuitMessage() : TranslationContainer|string{ + public function getQuitMessage() : Translatable|string{ return $this->quitMessage; } } diff --git a/src/event/player/PlayerQuitEvent.php b/src/event/player/PlayerQuitEvent.php index 84beece22c..9791cd8938 100644 --- a/src/event/player/PlayerQuitEvent.php +++ b/src/event/player/PlayerQuitEvent.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\event\player; -use pocketmine\lang\TranslationContainer; +use pocketmine\lang\Translatable; use pocketmine\player\Player; /** @@ -31,22 +31,22 @@ use pocketmine\player\Player; */ class PlayerQuitEvent extends PlayerEvent{ - /** @var TranslationContainer|string */ + /** @var Translatable|string */ protected $quitMessage; /** @var string */ protected $quitReason; - public function __construct(Player $player, TranslationContainer|string $quitMessage, string $quitReason){ + public function __construct(Player $player, Translatable|string $quitMessage, string $quitReason){ $this->player = $player; $this->quitMessage = $quitMessage; $this->quitReason = $quitReason; } - public function setQuitMessage(TranslationContainer|string $quitMessage) : void{ + public function setQuitMessage(Translatable|string $quitMessage) : void{ $this->quitMessage = $quitMessage; } - public function getQuitMessage() : TranslationContainer|string{ + public function getQuitMessage() : Translatable|string{ return $this->quitMessage; } diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index c512519e99..d61ce8ff33 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -29,171 +29,171 @@ namespace pocketmine\lang; * This class is generated automatically, do NOT modify it by hand. */ final class KnownTranslationFactory{ - public static function ability_flight() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::ABILITY_FLIGHT, []); + public static function ability_flight() : Translatable{ + return new Translatable(KnownTranslationKeys::ABILITY_FLIGHT, []); } - public static function ability_noclip() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::ABILITY_NOCLIP, []); + public static function ability_noclip() : Translatable{ + return new Translatable(KnownTranslationKeys::ABILITY_NOCLIP, []); } - public static function accept_license() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::ACCEPT_LICENSE, []); + public static function accept_license() : Translatable{ + return new Translatable(KnownTranslationKeys::ACCEPT_LICENSE, []); } - public static function chat_type_achievement(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::CHAT_TYPE_ACHIEVEMENT, [ + public static function chat_type_achievement(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::CHAT_TYPE_ACHIEVEMENT, [ 0 => $param0, 1 => $param1, ]); } - public static function chat_type_admin(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::CHAT_TYPE_ADMIN, [ + public static function chat_type_admin(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::CHAT_TYPE_ADMIN, [ 0 => $param0, 1 => $param1, ]); } - public static function chat_type_announcement(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::CHAT_TYPE_ANNOUNCEMENT, [ + public static function chat_type_announcement(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::CHAT_TYPE_ANNOUNCEMENT, [ 0 => $param0, 1 => $param1, ]); } - public static function chat_type_emote(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::CHAT_TYPE_EMOTE, [ + public static function chat_type_emote(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::CHAT_TYPE_EMOTE, [ 0 => $param0, 1 => $param1, ]); } - public static function chat_type_text(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::CHAT_TYPE_TEXT, [ + public static function chat_type_text(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::CHAT_TYPE_TEXT, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_ban_success(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_BAN_SUCCESS, [ + public static function commands_ban_success(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_BAN_SUCCESS, [ 0 => $param0, ]); } - public static function commands_ban_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_BAN_USAGE, []); + public static function commands_ban_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_BAN_USAGE, []); } - public static function commands_banip_invalid() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANIP_INVALID, []); + public static function commands_banip_invalid() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_BANIP_INVALID, []); } - public static function commands_banip_success(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANIP_SUCCESS, [ + public static function commands_banip_success(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_BANIP_SUCCESS, [ 0 => $param0, ]); } - public static function commands_banip_success_players(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANIP_SUCCESS_PLAYERS, [ + public static function commands_banip_success_players(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_BANIP_SUCCESS_PLAYERS, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_banip_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANIP_USAGE, []); + public static function commands_banip_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_BANIP_USAGE, []); } - public static function commands_banlist_ips(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANLIST_IPS, [ + public static function commands_banlist_ips(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_BANLIST_IPS, [ 0 => $param0, ]); } - public static function commands_banlist_players(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANLIST_PLAYERS, [ + public static function commands_banlist_players(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_BANLIST_PLAYERS, [ 0 => $param0, ]); } - public static function commands_banlist_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_BANLIST_USAGE, []); + public static function commands_banlist_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_BANLIST_USAGE, []); } - public static function commands_clear_failure_no_items(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_CLEAR_FAILURE_NO_ITEMS, [ + public static function commands_clear_failure_no_items(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_CLEAR_FAILURE_NO_ITEMS, [ 0 => $param0, ]); } - public static function commands_clear_success(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_CLEAR_SUCCESS, [ + public static function commands_clear_success(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_CLEAR_SUCCESS, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_clear_testing(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_CLEAR_TESTING, [ + public static function commands_clear_testing(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_CLEAR_TESTING, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_defaultgamemode_success(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_DEFAULTGAMEMODE_SUCCESS, [ + public static function commands_defaultgamemode_success(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_DEFAULTGAMEMODE_SUCCESS, [ 0 => $param0, ]); } - public static function commands_defaultgamemode_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_DEFAULTGAMEMODE_USAGE, []); + public static function commands_defaultgamemode_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_DEFAULTGAMEMODE_USAGE, []); } - public static function commands_deop_success(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_DEOP_SUCCESS, [ + public static function commands_deop_success(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_DEOP_SUCCESS, [ 0 => $param0, ]); } - public static function commands_deop_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_DEOP_USAGE, []); + public static function commands_deop_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_DEOP_USAGE, []); } - public static function commands_difficulty_success(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_DIFFICULTY_SUCCESS, [ + public static function commands_difficulty_success(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_DIFFICULTY_SUCCESS, [ 0 => $param0, ]); } - public static function commands_difficulty_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_DIFFICULTY_USAGE, []); + public static function commands_difficulty_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_DIFFICULTY_USAGE, []); } - public static function commands_effect_failure_notActive(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_FAILURE_NOTACTIVE, [ + public static function commands_effect_failure_notActive(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_EFFECT_FAILURE_NOTACTIVE, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_effect_failure_notActive_all(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_FAILURE_NOTACTIVE_ALL, [ + public static function commands_effect_failure_notActive_all(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_EFFECT_FAILURE_NOTACTIVE_ALL, [ 0 => $param0, ]); } - public static function commands_effect_notFound(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_NOTFOUND, [ + public static function commands_effect_notFound(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_EFFECT_NOTFOUND, [ 0 => $param0, ]); } - public static function commands_effect_success(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2, TranslationContainer|string $param3) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_SUCCESS, [ + public static function commands_effect_success(Translatable|string $param0, Translatable|string $param1, Translatable|string $param2, Translatable|string $param3) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_EFFECT_SUCCESS, [ 0 => $param0, 1 => $param1, 2 => $param2, @@ -201,260 +201,260 @@ final class KnownTranslationFactory{ ]); } - public static function commands_effect_success_removed(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_SUCCESS_REMOVED, [ + public static function commands_effect_success_removed(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_EFFECT_SUCCESS_REMOVED, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_effect_success_removed_all(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_SUCCESS_REMOVED_ALL, [ + public static function commands_effect_success_removed_all(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_EFFECT_SUCCESS_REMOVED_ALL, [ 0 => $param0, ]); } - public static function commands_effect_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_EFFECT_USAGE, []); + public static function commands_effect_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_EFFECT_USAGE, []); } - public static function commands_enchant_noItem() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_ENCHANT_NOITEM, []); + public static function commands_enchant_noItem() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_ENCHANT_NOITEM, []); } - public static function commands_enchant_notFound(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_ENCHANT_NOTFOUND, [ + public static function commands_enchant_notFound(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_ENCHANT_NOTFOUND, [ 0 => $param0, ]); } - public static function commands_enchant_success() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_ENCHANT_SUCCESS, []); + public static function commands_enchant_success() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_ENCHANT_SUCCESS, []); } - public static function commands_enchant_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_ENCHANT_USAGE, []); + public static function commands_enchant_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_ENCHANT_USAGE, []); } - public static function commands_gamemode_success_other(TranslationContainer|string $param1, TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_GAMEMODE_SUCCESS_OTHER, [ + public static function commands_gamemode_success_other(Translatable|string $param1, Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_GAMEMODE_SUCCESS_OTHER, [ 1 => $param1, 0 => $param0, ]); } - public static function commands_gamemode_success_self(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_GAMEMODE_SUCCESS_SELF, [ + public static function commands_gamemode_success_self(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_GAMEMODE_SUCCESS_SELF, [ 0 => $param0, ]); } - public static function commands_gamemode_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_GAMEMODE_USAGE, []); + public static function commands_gamemode_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_GAMEMODE_USAGE, []); } - public static function commands_generic_notFound() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_NOTFOUND, []); + public static function commands_generic_notFound() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_GENERIC_NOTFOUND, []); } - public static function commands_generic_num_tooBig(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_NUM_TOOBIG, [ + public static function commands_generic_num_tooBig(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_GENERIC_NUM_TOOBIG, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_generic_num_tooSmall(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_NUM_TOOSMALL, [ + public static function commands_generic_num_tooSmall(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_GENERIC_NUM_TOOSMALL, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_generic_permission() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION, []); + public static function commands_generic_permission() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_GENERIC_PERMISSION, []); } - public static function commands_generic_player_notFound() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND, []); + public static function commands_generic_player_notFound() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_GENERIC_PLAYER_NOTFOUND, []); } - public static function commands_generic_usage(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_GENERIC_USAGE, [ + public static function commands_generic_usage(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_GENERIC_USAGE, [ 0 => $param0, ]); } - public static function commands_give_item_notFound(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_GIVE_ITEM_NOTFOUND, [ + public static function commands_give_item_notFound(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_GIVE_ITEM_NOTFOUND, [ 0 => $param0, ]); } - public static function commands_give_success(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_GIVE_SUCCESS, [ + public static function commands_give_success(Translatable|string $param0, Translatable|string $param1, Translatable|string $param2) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_GIVE_SUCCESS, [ 0 => $param0, 1 => $param1, 2 => $param2, ]); } - public static function commands_give_tagError(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_GIVE_TAGERROR, [ + public static function commands_give_tagError(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_GIVE_TAGERROR, [ 0 => $param0, ]); } - public static function commands_help_header(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_HELP_HEADER, [ + public static function commands_help_header(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_HELP_HEADER, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_help_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_HELP_USAGE, []); + public static function commands_help_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_HELP_USAGE, []); } - public static function commands_kick_success(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_KICK_SUCCESS, [ + public static function commands_kick_success(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_KICK_SUCCESS, [ 0 => $param0, ]); } - public static function commands_kick_success_reason(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_KICK_SUCCESS_REASON, [ + public static function commands_kick_success_reason(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_KICK_SUCCESS_REASON, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_kick_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_KICK_USAGE, []); + public static function commands_kick_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_KICK_USAGE, []); } - public static function commands_kill_successful(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_KILL_SUCCESSFUL, [ + public static function commands_kill_successful(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_KILL_SUCCESSFUL, [ 0 => $param0, ]); } - public static function commands_me_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_ME_USAGE, []); + public static function commands_me_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_ME_USAGE, []); } - public static function commands_message_display_incoming(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_MESSAGE_DISPLAY_INCOMING, [ + public static function commands_message_display_incoming(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_MESSAGE_DISPLAY_INCOMING, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_message_display_outgoing(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_MESSAGE_DISPLAY_OUTGOING, [ + public static function commands_message_display_outgoing(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_MESSAGE_DISPLAY_OUTGOING, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_message_sameTarget() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_MESSAGE_SAMETARGET, []); + public static function commands_message_sameTarget() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_MESSAGE_SAMETARGET, []); } - public static function commands_message_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_MESSAGE_USAGE, []); + public static function commands_message_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_MESSAGE_USAGE, []); } - public static function commands_op_success(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_OP_SUCCESS, [ + public static function commands_op_success(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_OP_SUCCESS, [ 0 => $param0, ]); } - public static function commands_op_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_OP_USAGE, []); + public static function commands_op_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_OP_USAGE, []); } - public static function commands_particle_notFound(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_PARTICLE_NOTFOUND, [ + public static function commands_particle_notFound(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_PARTICLE_NOTFOUND, [ 0 => $param0, ]); } - public static function commands_particle_success(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_PARTICLE_SUCCESS, [ + public static function commands_particle_success(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_PARTICLE_SUCCESS, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_players_list(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_PLAYERS_LIST, [ + public static function commands_players_list(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_PLAYERS_LIST, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_players_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_PLAYERS_USAGE, []); + public static function commands_players_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_PLAYERS_USAGE, []); } - public static function commands_save_off_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_SAVE_OFF_USAGE, []); + public static function commands_save_off_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_SAVE_OFF_USAGE, []); } - public static function commands_save_on_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_SAVE_ON_USAGE, []); + public static function commands_save_on_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_SAVE_ON_USAGE, []); } - public static function commands_save_disabled() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_SAVE_DISABLED, []); + public static function commands_save_disabled() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_SAVE_DISABLED, []); } - public static function commands_save_enabled() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_SAVE_ENABLED, []); + public static function commands_save_enabled() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_SAVE_ENABLED, []); } - public static function commands_save_start() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_SAVE_START, []); + public static function commands_save_start() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_SAVE_START, []); } - public static function commands_save_success() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_SAVE_SUCCESS, []); + public static function commands_save_success() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_SAVE_SUCCESS, []); } - public static function commands_save_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_SAVE_USAGE, []); + public static function commands_save_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_SAVE_USAGE, []); } - public static function commands_say_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_SAY_USAGE, []); + public static function commands_say_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_SAY_USAGE, []); } - public static function commands_seed_success(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_SEED_SUCCESS, [ + public static function commands_seed_success(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_SEED_SUCCESS, [ 0 => $param0, ]); } - public static function commands_seed_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_SEED_USAGE, []); + public static function commands_seed_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_SEED_USAGE, []); } - public static function commands_setworldspawn_success(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_SETWORLDSPAWN_SUCCESS, [ + public static function commands_setworldspawn_success(Translatable|string $param0, Translatable|string $param1, Translatable|string $param2) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_SETWORLDSPAWN_SUCCESS, [ 0 => $param0, 1 => $param1, 2 => $param2, ]); } - public static function commands_setworldspawn_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_SETWORLDSPAWN_USAGE, []); + public static function commands_setworldspawn_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_SETWORLDSPAWN_USAGE, []); } - public static function commands_spawnpoint_success(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2, TranslationContainer|string $param3) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_SPAWNPOINT_SUCCESS, [ + public static function commands_spawnpoint_success(Translatable|string $param0, Translatable|string $param1, Translatable|string $param2, Translatable|string $param3) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_SPAWNPOINT_SUCCESS, [ 0 => $param0, 1 => $param1, 2 => $param2, @@ -462,53 +462,53 @@ final class KnownTranslationFactory{ ]); } - public static function commands_spawnpoint_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_SPAWNPOINT_USAGE, []); + public static function commands_spawnpoint_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_SPAWNPOINT_USAGE, []); } - public static function commands_stop_start() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_STOP_START, []); + public static function commands_stop_start() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_STOP_START, []); } - public static function commands_stop_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_STOP_USAGE, []); + public static function commands_stop_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_STOP_USAGE, []); } - public static function commands_time_added(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_TIME_ADDED, [ + public static function commands_time_added(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_TIME_ADDED, [ 0 => $param0, ]); } - public static function commands_time_query(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_TIME_QUERY, [ + public static function commands_time_query(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_TIME_QUERY, [ 0 => $param0, ]); } - public static function commands_time_set(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_TIME_SET, [ + public static function commands_time_set(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_TIME_SET, [ 0 => $param0, ]); } - public static function commands_title_success() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_TITLE_SUCCESS, []); + public static function commands_title_success() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_TITLE_SUCCESS, []); } - public static function commands_title_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_TITLE_USAGE, []); + public static function commands_title_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_TITLE_USAGE, []); } - public static function commands_tp_success(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_TP_SUCCESS, [ + public static function commands_tp_success(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_TP_SUCCESS, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_tp_success_coordinates(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2, TranslationContainer|string $param3) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_TP_SUCCESS_COORDINATES, [ + public static function commands_tp_success_coordinates(Translatable|string $param0, Translatable|string $param1, Translatable|string $param2, Translatable|string $param3) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_TP_SUCCESS_COORDINATES, [ 0 => $param0, 1 => $param1, 2 => $param2, @@ -516,830 +516,830 @@ final class KnownTranslationFactory{ ]); } - public static function commands_tp_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_TP_USAGE, []); + public static function commands_tp_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_TP_USAGE, []); } - public static function commands_unban_success(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_UNBAN_SUCCESS, [ + public static function commands_unban_success(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_UNBAN_SUCCESS, [ 0 => $param0, ]); } - public static function commands_unban_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_UNBAN_USAGE, []); + public static function commands_unban_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_UNBAN_USAGE, []); } - public static function commands_unbanip_invalid() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_UNBANIP_INVALID, []); + public static function commands_unbanip_invalid() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_UNBANIP_INVALID, []); } - public static function commands_unbanip_success(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_UNBANIP_SUCCESS, [ + public static function commands_unbanip_success(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_UNBANIP_SUCCESS, [ 0 => $param0, ]); } - public static function commands_unbanip_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_UNBANIP_USAGE, []); + public static function commands_unbanip_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_UNBANIP_USAGE, []); } - public static function commands_whitelist_add_success(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_ADD_SUCCESS, [ + public static function commands_whitelist_add_success(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_WHITELIST_ADD_SUCCESS, [ 0 => $param0, ]); } - public static function commands_whitelist_add_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_ADD_USAGE, []); + public static function commands_whitelist_add_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_WHITELIST_ADD_USAGE, []); } - public static function commands_whitelist_disabled() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_DISABLED, []); + public static function commands_whitelist_disabled() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_WHITELIST_DISABLED, []); } - public static function commands_whitelist_enabled() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_ENABLED, []); + public static function commands_whitelist_enabled() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_WHITELIST_ENABLED, []); } - public static function commands_whitelist_list(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_LIST, [ + public static function commands_whitelist_list(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_WHITELIST_LIST, [ 0 => $param0, 1 => $param1, ]); } - public static function commands_whitelist_reloaded() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_RELOADED, []); + public static function commands_whitelist_reloaded() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_WHITELIST_RELOADED, []); } - public static function commands_whitelist_remove_success(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_REMOVE_SUCCESS, [ + public static function commands_whitelist_remove_success(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_WHITELIST_REMOVE_SUCCESS, [ 0 => $param0, ]); } - public static function commands_whitelist_remove_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_REMOVE_USAGE, []); + public static function commands_whitelist_remove_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_WHITELIST_REMOVE_USAGE, []); } - public static function commands_whitelist_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::COMMANDS_WHITELIST_USAGE, []); + public static function commands_whitelist_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_WHITELIST_USAGE, []); } - public static function death_attack_arrow(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_ARROW, [ + public static function death_attack_arrow(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_ATTACK_ARROW, [ 0 => $param0, 1 => $param1, ]); } - public static function death_attack_arrow_item(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_ARROW_ITEM, [ + public static function death_attack_arrow_item(Translatable|string $param0, Translatable|string $param1, Translatable|string $param2) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_ATTACK_ARROW_ITEM, [ 0 => $param0, 1 => $param1, 2 => $param2, ]); } - public static function death_attack_cactus(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_CACTUS, [ + public static function death_attack_cactus(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_ATTACK_CACTUS, [ 0 => $param0, ]); } - public static function death_attack_drown(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_DROWN, [ + public static function death_attack_drown(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_ATTACK_DROWN, [ 0 => $param0, ]); } - public static function death_attack_explosion(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_EXPLOSION, [ + public static function death_attack_explosion(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_ATTACK_EXPLOSION, [ 0 => $param0, ]); } - public static function death_attack_explosion_player(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_EXPLOSION_PLAYER, [ + public static function death_attack_explosion_player(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_ATTACK_EXPLOSION_PLAYER, [ 0 => $param0, 1 => $param1, ]); } - public static function death_attack_fall(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_FALL, [ + public static function death_attack_fall(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_ATTACK_FALL, [ 0 => $param0, ]); } - public static function death_attack_generic(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_GENERIC, [ + public static function death_attack_generic(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_ATTACK_GENERIC, [ 0 => $param0, ]); } - public static function death_attack_inFire(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_INFIRE, [ + public static function death_attack_inFire(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_ATTACK_INFIRE, [ 0 => $param0, ]); } - public static function death_attack_inWall(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_INWALL, [ + public static function death_attack_inWall(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_ATTACK_INWALL, [ 0 => $param0, ]); } - public static function death_attack_lava(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_LAVA, [ + public static function death_attack_lava(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_ATTACK_LAVA, [ 0 => $param0, ]); } - public static function death_attack_magic(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_MAGIC, [ + public static function death_attack_magic(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_ATTACK_MAGIC, [ 0 => $param0, ]); } - public static function death_attack_mob(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_MOB, [ + public static function death_attack_mob(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_ATTACK_MOB, [ 0 => $param0, 1 => $param1, ]); } - public static function death_attack_onFire(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_ONFIRE, [ + public static function death_attack_onFire(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_ATTACK_ONFIRE, [ 0 => $param0, ]); } - public static function death_attack_outOfWorld(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_OUTOFWORLD, [ + public static function death_attack_outOfWorld(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_ATTACK_OUTOFWORLD, [ 0 => $param0, ]); } - public static function death_attack_player(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_PLAYER, [ + public static function death_attack_player(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_ATTACK_PLAYER, [ 0 => $param0, 1 => $param1, ]); } - public static function death_attack_player_item(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_PLAYER_ITEM, [ + public static function death_attack_player_item(Translatable|string $param0, Translatable|string $param1, Translatable|string $param2) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_ATTACK_PLAYER_ITEM, [ 0 => $param0, 1 => $param1, 2 => $param2, ]); } - public static function death_attack_wither(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEATH_ATTACK_WITHER, [ + public static function death_attack_wither(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_ATTACK_WITHER, [ 0 => $param0, ]); } - public static function death_fell_accident_generic(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEATH_FELL_ACCIDENT_GENERIC, [ + public static function death_fell_accident_generic(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_FELL_ACCIDENT_GENERIC, [ 0 => $param0, ]); } - public static function default_gamemode() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEFAULT_GAMEMODE, []); + public static function default_gamemode() : Translatable{ + return new Translatable(KnownTranslationKeys::DEFAULT_GAMEMODE, []); } - public static function default_values_info() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DEFAULT_VALUES_INFO, []); + public static function default_values_info() : Translatable{ + return new Translatable(KnownTranslationKeys::DEFAULT_VALUES_INFO, []); } - public static function disconnectionScreen_invalidName() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DISCONNECTIONSCREEN_INVALIDNAME, []); + public static function disconnectionScreen_invalidName() : Translatable{ + return new Translatable(KnownTranslationKeys::DISCONNECTIONSCREEN_INVALIDNAME, []); } - public static function disconnectionScreen_invalidSkin() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DISCONNECTIONSCREEN_INVALIDSKIN, []); + public static function disconnectionScreen_invalidSkin() : Translatable{ + return new Translatable(KnownTranslationKeys::DISCONNECTIONSCREEN_INVALIDSKIN, []); } - public static function disconnectionScreen_noReason() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DISCONNECTIONSCREEN_NOREASON, []); + public static function disconnectionScreen_noReason() : Translatable{ + return new Translatable(KnownTranslationKeys::DISCONNECTIONSCREEN_NOREASON, []); } - public static function disconnectionScreen_notAuthenticated() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DISCONNECTIONSCREEN_NOTAUTHENTICATED, []); + public static function disconnectionScreen_notAuthenticated() : Translatable{ + return new Translatable(KnownTranslationKeys::DISCONNECTIONSCREEN_NOTAUTHENTICATED, []); } - public static function disconnectionScreen_outdatedClient() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DISCONNECTIONSCREEN_OUTDATEDCLIENT, []); + public static function disconnectionScreen_outdatedClient() : Translatable{ + return new Translatable(KnownTranslationKeys::DISCONNECTIONSCREEN_OUTDATEDCLIENT, []); } - public static function disconnectionScreen_outdatedServer() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DISCONNECTIONSCREEN_OUTDATEDSERVER, []); + public static function disconnectionScreen_outdatedServer() : Translatable{ + return new Translatable(KnownTranslationKeys::DISCONNECTIONSCREEN_OUTDATEDSERVER, []); } - public static function disconnectionScreen_resourcePack() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DISCONNECTIONSCREEN_RESOURCEPACK, []); + public static function disconnectionScreen_resourcePack() : Translatable{ + return new Translatable(KnownTranslationKeys::DISCONNECTIONSCREEN_RESOURCEPACK, []); } - public static function disconnectionScreen_serverFull() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::DISCONNECTIONSCREEN_SERVERFULL, []); + public static function disconnectionScreen_serverFull() : Translatable{ + return new Translatable(KnownTranslationKeys::DISCONNECTIONSCREEN_SERVERFULL, []); } - public static function gameMode_adventure() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::GAMEMODE_ADVENTURE, []); + public static function gameMode_adventure() : Translatable{ + return new Translatable(KnownTranslationKeys::GAMEMODE_ADVENTURE, []); } - public static function gameMode_changed() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::GAMEMODE_CHANGED, []); + public static function gameMode_changed() : Translatable{ + return new Translatable(KnownTranslationKeys::GAMEMODE_CHANGED, []); } - public static function gameMode_creative() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::GAMEMODE_CREATIVE, []); + public static function gameMode_creative() : Translatable{ + return new Translatable(KnownTranslationKeys::GAMEMODE_CREATIVE, []); } - public static function gameMode_spectator() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::GAMEMODE_SPECTATOR, []); + public static function gameMode_spectator() : Translatable{ + return new Translatable(KnownTranslationKeys::GAMEMODE_SPECTATOR, []); } - public static function gameMode_survival() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::GAMEMODE_SURVIVAL, []); + public static function gameMode_survival() : Translatable{ + return new Translatable(KnownTranslationKeys::GAMEMODE_SURVIVAL, []); } - public static function gamemode_info() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::GAMEMODE_INFO, []); + public static function gamemode_info() : Translatable{ + return new Translatable(KnownTranslationKeys::GAMEMODE_INFO, []); } - public static function invalid_port() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::INVALID_PORT, []); + public static function invalid_port() : Translatable{ + return new Translatable(KnownTranslationKeys::INVALID_PORT, []); } - public static function ip_confirm() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::IP_CONFIRM, []); + public static function ip_confirm() : Translatable{ + return new Translatable(KnownTranslationKeys::IP_CONFIRM, []); } - public static function ip_get() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::IP_GET, []); + public static function ip_get() : Translatable{ + return new Translatable(KnownTranslationKeys::IP_GET, []); } - public static function ip_warning(TranslationContainer|string $EXTERNAL_IP, TranslationContainer|string $INTERNAL_IP) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::IP_WARNING, [ + public static function ip_warning(Translatable|string $EXTERNAL_IP, Translatable|string $INTERNAL_IP) : Translatable{ + return new Translatable(KnownTranslationKeys::IP_WARNING, [ "EXTERNAL_IP" => $EXTERNAL_IP, "INTERNAL_IP" => $INTERNAL_IP, ]); } - public static function kick_admin() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::KICK_ADMIN, []); + public static function kick_admin() : Translatable{ + return new Translatable(KnownTranslationKeys::KICK_ADMIN, []); } - public static function kick_admin_reason(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::KICK_ADMIN_REASON, [ + public static function kick_admin_reason(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::KICK_ADMIN_REASON, [ 0 => $param0, ]); } - public static function kick_reason_cheat(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::KICK_REASON_CHEAT, [ + public static function kick_reason_cheat(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::KICK_REASON_CHEAT, [ 0 => $param0, ]); } - public static function language_name() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::LANGUAGE_NAME, []); + public static function language_name() : Translatable{ + return new Translatable(KnownTranslationKeys::LANGUAGE_NAME, []); } - public static function language_selected(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::LANGUAGE_SELECTED, [ + public static function language_selected(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::LANGUAGE_SELECTED, [ 0 => $param0, 1 => $param1, ]); } - public static function language_has_been_selected() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::LANGUAGE_HAS_BEEN_SELECTED, []); + public static function language_has_been_selected() : Translatable{ + return new Translatable(KnownTranslationKeys::LANGUAGE_HAS_BEEN_SELECTED, []); } - public static function max_players() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::MAX_PLAYERS, []); + public static function max_players() : Translatable{ + return new Translatable(KnownTranslationKeys::MAX_PLAYERS, []); } - public static function multiplayer_player_joined(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::MULTIPLAYER_PLAYER_JOINED, [ + public static function multiplayer_player_joined(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::MULTIPLAYER_PLAYER_JOINED, [ 0 => $param0, ]); } - public static function multiplayer_player_left(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::MULTIPLAYER_PLAYER_LEFT, [ + public static function multiplayer_player_left(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::MULTIPLAYER_PLAYER_LEFT, [ 0 => $param0, ]); } - public static function name_your_server() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::NAME_YOUR_SERVER, []); + public static function name_your_server() : Translatable{ + return new Translatable(KnownTranslationKeys::NAME_YOUR_SERVER, []); } - public static function op_info() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::OP_INFO, []); + public static function op_info() : Translatable{ + return new Translatable(KnownTranslationKeys::OP_INFO, []); } - public static function op_warning() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::OP_WARNING, []); + public static function op_warning() : Translatable{ + return new Translatable(KnownTranslationKeys::OP_WARNING, []); } - public static function op_who() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::OP_WHO, []); + public static function op_who() : Translatable{ + return new Translatable(KnownTranslationKeys::OP_WHO, []); } - public static function pocketmine_command_alias_illegal(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_ALIAS_ILLEGAL, [ + public static function pocketmine_command_alias_illegal(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_ALIAS_ILLEGAL, [ 0 => $param0, ]); } - public static function pocketmine_command_alias_notFound(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_ALIAS_NOTFOUND, [ + public static function pocketmine_command_alias_notFound(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_ALIAS_NOTFOUND, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_command_alias_recursive(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_ALIAS_RECURSIVE, [ + public static function pocketmine_command_alias_recursive(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_ALIAS_RECURSIVE, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_command_ban_ip_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_BAN_IP_DESCRIPTION, []); + public static function pocketmine_command_ban_ip_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_BAN_IP_DESCRIPTION, []); } - public static function pocketmine_command_ban_player_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_BAN_PLAYER_DESCRIPTION, []); + public static function pocketmine_command_ban_player_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_BAN_PLAYER_DESCRIPTION, []); } - public static function pocketmine_command_banlist_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_BANLIST_DESCRIPTION, []); + public static function pocketmine_command_banlist_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_BANLIST_DESCRIPTION, []); } - public static function pocketmine_command_clear_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_CLEAR_DESCRIPTION, []); + public static function pocketmine_command_clear_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_CLEAR_DESCRIPTION, []); } - public static function pocketmine_command_clear_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_CLEAR_USAGE, []); + public static function pocketmine_command_clear_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_CLEAR_USAGE, []); } - public static function pocketmine_command_defaultgamemode_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_DEFAULTGAMEMODE_DESCRIPTION, []); + public static function pocketmine_command_defaultgamemode_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_DEFAULTGAMEMODE_DESCRIPTION, []); } - public static function pocketmine_command_deop_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_DEOP_DESCRIPTION, []); + public static function pocketmine_command_deop_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_DEOP_DESCRIPTION, []); } - public static function pocketmine_command_difficulty_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_DIFFICULTY_DESCRIPTION, []); + public static function pocketmine_command_difficulty_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_DIFFICULTY_DESCRIPTION, []); } - public static function pocketmine_command_effect_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_EFFECT_DESCRIPTION, []); + public static function pocketmine_command_effect_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_EFFECT_DESCRIPTION, []); } - public static function pocketmine_command_enchant_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_ENCHANT_DESCRIPTION, []); + public static function pocketmine_command_enchant_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_ENCHANT_DESCRIPTION, []); } - public static function pocketmine_command_exception(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_EXCEPTION, [ + public static function pocketmine_command_exception(Translatable|string $param0, Translatable|string $param1, Translatable|string $param2) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_EXCEPTION, [ 0 => $param0, 1 => $param1, 2 => $param2, ]); } - public static function pocketmine_command_gamemode_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_GAMEMODE_DESCRIPTION, []); + public static function pocketmine_command_gamemode_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_GAMEMODE_DESCRIPTION, []); } - public static function pocketmine_command_gc_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_GC_DESCRIPTION, []); + public static function pocketmine_command_gc_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_GC_DESCRIPTION, []); } - public static function pocketmine_command_gc_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_GC_USAGE, []); + public static function pocketmine_command_gc_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_GC_USAGE, []); } - public static function pocketmine_command_give_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_GIVE_DESCRIPTION, []); + public static function pocketmine_command_give_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_GIVE_DESCRIPTION, []); } - public static function pocketmine_command_give_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_GIVE_USAGE, []); + public static function pocketmine_command_give_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_GIVE_USAGE, []); } - public static function pocketmine_command_help_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_HELP_DESCRIPTION, []); + public static function pocketmine_command_help_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_HELP_DESCRIPTION, []); } - public static function pocketmine_command_kick_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_KICK_DESCRIPTION, []); + public static function pocketmine_command_kick_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_KICK_DESCRIPTION, []); } - public static function pocketmine_command_kill_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_KILL_DESCRIPTION, []); + public static function pocketmine_command_kill_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_KILL_DESCRIPTION, []); } - public static function pocketmine_command_kill_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_KILL_USAGE, []); + public static function pocketmine_command_kill_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_KILL_USAGE, []); } - public static function pocketmine_command_list_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_LIST_DESCRIPTION, []); + public static function pocketmine_command_list_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_LIST_DESCRIPTION, []); } - public static function pocketmine_command_me_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_ME_DESCRIPTION, []); + public static function pocketmine_command_me_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_ME_DESCRIPTION, []); } - public static function pocketmine_command_op_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_OP_DESCRIPTION, []); + public static function pocketmine_command_op_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_OP_DESCRIPTION, []); } - public static function pocketmine_command_particle_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_PARTICLE_DESCRIPTION, []); + public static function pocketmine_command_particle_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_PARTICLE_DESCRIPTION, []); } - public static function pocketmine_command_particle_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_PARTICLE_USAGE, []); + public static function pocketmine_command_particle_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_PARTICLE_USAGE, []); } - public static function pocketmine_command_plugins_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_DESCRIPTION, []); + public static function pocketmine_command_plugins_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_DESCRIPTION, []); } - public static function pocketmine_command_plugins_success(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_SUCCESS, [ + public static function pocketmine_command_plugins_success(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_SUCCESS, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_command_plugins_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_USAGE, []); + public static function pocketmine_command_plugins_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_USAGE, []); } - public static function pocketmine_command_save_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_SAVE_DESCRIPTION, []); + public static function pocketmine_command_save_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_SAVE_DESCRIPTION, []); } - public static function pocketmine_command_saveoff_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_SAVEOFF_DESCRIPTION, []); + public static function pocketmine_command_saveoff_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_SAVEOFF_DESCRIPTION, []); } - public static function pocketmine_command_saveon_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_SAVEON_DESCRIPTION, []); + public static function pocketmine_command_saveon_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_SAVEON_DESCRIPTION, []); } - public static function pocketmine_command_say_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_SAY_DESCRIPTION, []); + public static function pocketmine_command_say_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_SAY_DESCRIPTION, []); } - public static function pocketmine_command_seed_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_SEED_DESCRIPTION, []); + public static function pocketmine_command_seed_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_SEED_DESCRIPTION, []); } - public static function pocketmine_command_setworldspawn_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_SETWORLDSPAWN_DESCRIPTION, []); + public static function pocketmine_command_setworldspawn_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_SETWORLDSPAWN_DESCRIPTION, []); } - public static function pocketmine_command_spawnpoint_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_SPAWNPOINT_DESCRIPTION, []); + public static function pocketmine_command_spawnpoint_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_SPAWNPOINT_DESCRIPTION, []); } - public static function pocketmine_command_status_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_STATUS_DESCRIPTION, []); + public static function pocketmine_command_status_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_STATUS_DESCRIPTION, []); } - public static function pocketmine_command_status_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_STATUS_USAGE, []); + public static function pocketmine_command_status_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_STATUS_USAGE, []); } - public static function pocketmine_command_stop_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_STOP_DESCRIPTION, []); + public static function pocketmine_command_stop_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_STOP_DESCRIPTION, []); } - public static function pocketmine_command_tell_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TELL_DESCRIPTION, []); + public static function pocketmine_command_tell_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_TELL_DESCRIPTION, []); } - public static function pocketmine_command_time_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIME_DESCRIPTION, []); + public static function pocketmine_command_time_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_TIME_DESCRIPTION, []); } - public static function pocketmine_command_time_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIME_USAGE, []); + public static function pocketmine_command_time_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_TIME_USAGE, []); } - public static function pocketmine_command_timings_alreadyEnabled() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_ALREADYENABLED, []); + public static function pocketmine_command_timings_alreadyEnabled() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_ALREADYENABLED, []); } - public static function pocketmine_command_timings_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_DESCRIPTION, []); + public static function pocketmine_command_timings_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_DESCRIPTION, []); } - public static function pocketmine_command_timings_disable() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_DISABLE, []); + public static function pocketmine_command_timings_disable() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_DISABLE, []); } - public static function pocketmine_command_timings_enable() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_ENABLE, []); + public static function pocketmine_command_timings_enable() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_ENABLE, []); } - public static function pocketmine_command_timings_pasteError() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_PASTEERROR, []); + public static function pocketmine_command_timings_pasteError() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_PASTEERROR, []); } - public static function pocketmine_command_timings_reset() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_RESET, []); + public static function pocketmine_command_timings_reset() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_RESET, []); } - public static function pocketmine_command_timings_timingsDisabled() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSDISABLED, []); + public static function pocketmine_command_timings_timingsDisabled() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSDISABLED, []); } - public static function pocketmine_command_timings_timingsRead(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSREAD, [ + public static function pocketmine_command_timings_timingsRead(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSREAD, [ 0 => $param0, ]); } - public static function pocketmine_command_timings_timingsUpload(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSUPLOAD, [ + public static function pocketmine_command_timings_timingsUpload(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSUPLOAD, [ 0 => $param0, ]); } - public static function pocketmine_command_timings_timingsWrite(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSWRITE, [ + public static function pocketmine_command_timings_timingsWrite(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_TIMINGSWRITE, [ 0 => $param0, ]); } - public static function pocketmine_command_timings_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_USAGE, []); + public static function pocketmine_command_timings_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_USAGE, []); } - public static function pocketmine_command_title_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TITLE_DESCRIPTION, []); + public static function pocketmine_command_title_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_TITLE_DESCRIPTION, []); } - public static function pocketmine_command_tp_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TP_DESCRIPTION, []); + public static function pocketmine_command_tp_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_TP_DESCRIPTION, []); } - public static function pocketmine_command_transferserver_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TRANSFERSERVER_DESCRIPTION, []); + public static function pocketmine_command_transferserver_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_TRANSFERSERVER_DESCRIPTION, []); } - public static function pocketmine_command_transferserver_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_TRANSFERSERVER_USAGE, []); + public static function pocketmine_command_transferserver_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_TRANSFERSERVER_USAGE, []); } - public static function pocketmine_command_unban_ip_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_UNBAN_IP_DESCRIPTION, []); + public static function pocketmine_command_unban_ip_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_UNBAN_IP_DESCRIPTION, []); } - public static function pocketmine_command_unban_player_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_UNBAN_PLAYER_DESCRIPTION, []); + public static function pocketmine_command_unban_player_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_UNBAN_PLAYER_DESCRIPTION, []); } - public static function pocketmine_command_version_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_DESCRIPTION, []); + public static function pocketmine_command_version_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_DESCRIPTION, []); } - public static function pocketmine_command_version_minecraftVersion(TranslationContainer|string $minecraftVersion, TranslationContainer|string $minecraftProtocolVersion) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_MINECRAFTVERSION, [ + public static function pocketmine_command_version_minecraftVersion(Translatable|string $minecraftVersion, Translatable|string $minecraftProtocolVersion) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_MINECRAFTVERSION, [ "minecraftVersion" => $minecraftVersion, "minecraftProtocolVersion" => $minecraftProtocolVersion, ]); } - public static function pocketmine_command_version_noSuchPlugin() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_NOSUCHPLUGIN, []); + public static function pocketmine_command_version_noSuchPlugin() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_NOSUCHPLUGIN, []); } - public static function pocketmine_command_version_operatingSystem(TranslationContainer|string $operatingSystemName) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_OPERATINGSYSTEM, [ + public static function pocketmine_command_version_operatingSystem(Translatable|string $operatingSystemName) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_OPERATINGSYSTEM, [ "operatingSystemName" => $operatingSystemName, ]); } - public static function pocketmine_command_version_phpJitDisabled() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPJITDISABLED, []); + public static function pocketmine_command_version_phpJitDisabled() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPJITDISABLED, []); } - public static function pocketmine_command_version_phpJitEnabled(TranslationContainer|string $extraJitInfo) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPJITENABLED, [ + public static function pocketmine_command_version_phpJitEnabled(Translatable|string $extraJitInfo) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPJITENABLED, [ "extraJitInfo" => $extraJitInfo, ]); } - public static function pocketmine_command_version_phpJitNotSupported() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPJITNOTSUPPORTED, []); + public static function pocketmine_command_version_phpJitNotSupported() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPJITNOTSUPPORTED, []); } - public static function pocketmine_command_version_phpJitStatus(TranslationContainer|string $jitStatus) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPJITSTATUS, [ + public static function pocketmine_command_version_phpJitStatus(Translatable|string $jitStatus) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPJITSTATUS, [ "jitStatus" => $jitStatus, ]); } - public static function pocketmine_command_version_phpVersion(TranslationContainer|string $phpVersion) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPVERSION, [ + public static function pocketmine_command_version_phpVersion(Translatable|string $phpVersion) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_PHPVERSION, [ "phpVersion" => $phpVersion, ]); } - public static function pocketmine_command_version_serverSoftwareName(TranslationContainer|string $serverSoftwareName) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_SERVERSOFTWARENAME, [ + public static function pocketmine_command_version_serverSoftwareName(Translatable|string $serverSoftwareName) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_SERVERSOFTWARENAME, [ "serverSoftwareName" => $serverSoftwareName, ]); } - public static function pocketmine_command_version_serverSoftwareVersion(TranslationContainer|string $serverSoftwareVersion, TranslationContainer|string $serverGitHash) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_SERVERSOFTWAREVERSION, [ + public static function pocketmine_command_version_serverSoftwareVersion(Translatable|string $serverSoftwareVersion, Translatable|string $serverGitHash) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_SERVERSOFTWAREVERSION, [ "serverSoftwareVersion" => $serverSoftwareVersion, "serverGitHash" => $serverGitHash, ]); } - public static function pocketmine_command_version_usage() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_USAGE, []); + public static function pocketmine_command_version_usage() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_USAGE, []); } - public static function pocketmine_command_whitelist_description() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_COMMAND_WHITELIST_DESCRIPTION, []); + public static function pocketmine_command_whitelist_description() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_WHITELIST_DESCRIPTION, []); } - public static function pocketmine_crash_archive(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_CRASH_ARCHIVE, [ + public static function pocketmine_crash_archive(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_CRASH_ARCHIVE, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_crash_create() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_CRASH_CREATE, []); + public static function pocketmine_crash_create() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_CRASH_CREATE, []); } - public static function pocketmine_crash_error(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_CRASH_ERROR, [ + public static function pocketmine_crash_error(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_CRASH_ERROR, [ 0 => $param0, ]); } - public static function pocketmine_crash_submit(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_CRASH_SUBMIT, [ + public static function pocketmine_crash_submit(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_CRASH_SUBMIT, [ 0 => $param0, ]); } - public static function pocketmine_data_playerCorrupted(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DATA_PLAYERCORRUPTED, [ + public static function pocketmine_data_playerCorrupted(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DATA_PLAYERCORRUPTED, [ 0 => $param0, ]); } - public static function pocketmine_data_playerNotFound(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DATA_PLAYERNOTFOUND, [ + public static function pocketmine_data_playerNotFound(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DATA_PLAYERNOTFOUND, [ 0 => $param0, ]); } - public static function pocketmine_data_playerOld(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DATA_PLAYEROLD, [ + public static function pocketmine_data_playerOld(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DATA_PLAYEROLD, [ 0 => $param0, ]); } - public static function pocketmine_data_saveError(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DATA_SAVEERROR, [ + public static function pocketmine_data_saveError(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DATA_SAVEERROR, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_debug_enable() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DEBUG_ENABLE, []); + public static function pocketmine_debug_enable() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DEBUG_ENABLE, []); } - public static function pocketmine_disconnect_incompatibleProtocol(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DISCONNECT_INCOMPATIBLEPROTOCOL, [ + public static function pocketmine_disconnect_incompatibleProtocol(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_INCOMPATIBLEPROTOCOL, [ 0 => $param0, ]); } - public static function pocketmine_disconnect_invalidSession(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION, [ + public static function pocketmine_disconnect_invalidSession(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION, [ 0 => $param0, ]); } - public static function pocketmine_disconnect_invalidSession_badSignature() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_BADSIGNATURE, []); + public static function pocketmine_disconnect_invalidSession_badSignature() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_BADSIGNATURE, []); } - public static function pocketmine_disconnect_invalidSession_missingKey() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_MISSINGKEY, []); + public static function pocketmine_disconnect_invalidSession_missingKey() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_MISSINGKEY, []); } - public static function pocketmine_disconnect_invalidSession_tooEarly() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_TOOEARLY, []); + public static function pocketmine_disconnect_invalidSession_tooEarly() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_TOOEARLY, []); } - public static function pocketmine_disconnect_invalidSession_tooLate() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_TOOLATE, []); + public static function pocketmine_disconnect_invalidSession_tooLate() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_TOOLATE, []); } - public static function pocketmine_level_ambiguousFormat(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_AMBIGUOUSFORMAT, [ + public static function pocketmine_level_ambiguousFormat(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_AMBIGUOUSFORMAT, [ 0 => $param0, ]); } - public static function pocketmine_level_backgroundGeneration(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_BACKGROUNDGENERATION, [ + public static function pocketmine_level_backgroundGeneration(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_BACKGROUNDGENERATION, [ 0 => $param0, ]); } - public static function pocketmine_level_badDefaultFormat(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_BADDEFAULTFORMAT, [ + public static function pocketmine_level_badDefaultFormat(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_BADDEFAULTFORMAT, [ 0 => $param0, ]); } - public static function pocketmine_level_defaultError() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_DEFAULTERROR, []); + public static function pocketmine_level_defaultError() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_DEFAULTERROR, []); } - public static function pocketmine_level_generationError(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_GENERATIONERROR, [ + public static function pocketmine_level_generationError(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_GENERATIONERROR, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_level_loadError(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_LOADERROR, [ + public static function pocketmine_level_loadError(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_LOADERROR, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_level_notFound(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_NOTFOUND, [ + public static function pocketmine_level_notFound(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_NOTFOUND, [ 0 => $param0, ]); } - public static function pocketmine_level_preparing(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_PREPARING, [ + public static function pocketmine_level_preparing(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_PREPARING, [ 0 => $param0, ]); } - public static function pocketmine_level_unknownFormat() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_UNKNOWNFORMAT, []); + public static function pocketmine_level_unknownFormat() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_UNKNOWNFORMAT, []); } - public static function pocketmine_level_unloading(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_LEVEL_UNLOADING, [ + public static function pocketmine_level_unloading(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_UNLOADING, [ 0 => $param0, ]); } - public static function pocketmine_player_invalidEntity(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLAYER_INVALIDENTITY, [ + public static function pocketmine_player_invalidEntity(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLAYER_INVALIDENTITY, [ 0 => $param0, ]); } - public static function pocketmine_player_invalidMove(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLAYER_INVALIDMOVE, [ + public static function pocketmine_player_invalidMove(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLAYER_INVALIDMOVE, [ 0 => $param0, ]); } - public static function pocketmine_player_logIn(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2, TranslationContainer|string $param3, TranslationContainer|string $param4, TranslationContainer|string $param5, TranslationContainer|string $param6, TranslationContainer|string $param7) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLAYER_LOGIN, [ + public static function pocketmine_player_logIn(Translatable|string $param0, Translatable|string $param1, Translatable|string $param2, Translatable|string $param3, Translatable|string $param4, Translatable|string $param5, Translatable|string $param6, Translatable|string $param7) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLAYER_LOGIN, [ 0 => $param0, 1 => $param1, 2 => $param2, @@ -1351,8 +1351,8 @@ final class KnownTranslationFactory{ ]); } - public static function pocketmine_player_logOut(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2, TranslationContainer|string $param3) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLAYER_LOGOUT, [ + public static function pocketmine_player_logOut(Translatable|string $param0, Translatable|string $param1, Translatable|string $param2, Translatable|string $param3) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLAYER_LOGOUT, [ 0 => $param0, 1 => $param1, 2 => $param2, @@ -1360,214 +1360,214 @@ final class KnownTranslationFactory{ ]); } - public static function pocketmine_plugin_aliasError(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_ALIASERROR, [ + public static function pocketmine_plugin_aliasError(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_ALIASERROR, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_plugin_ambiguousMinAPI(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_AMBIGUOUSMINAPI, [ + public static function pocketmine_plugin_ambiguousMinAPI(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_AMBIGUOUSMINAPI, [ 0 => $param0, ]); } - public static function pocketmine_plugin_circularDependency() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_CIRCULARDEPENDENCY, []); + public static function pocketmine_plugin_circularDependency() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_CIRCULARDEPENDENCY, []); } - public static function pocketmine_plugin_commandError(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_COMMANDERROR, [ + public static function pocketmine_plugin_commandError(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_COMMANDERROR, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_plugin_deprecatedEvent(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_DEPRECATEDEVENT, [ + public static function pocketmine_plugin_deprecatedEvent(Translatable|string $param0, Translatable|string $param1, Translatable|string $param2) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_DEPRECATEDEVENT, [ 0 => $param0, 1 => $param1, 2 => $param2, ]); } - public static function pocketmine_plugin_disable(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_DISABLE, [ + public static function pocketmine_plugin_disable(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_DISABLE, [ 0 => $param0, ]); } - public static function pocketmine_plugin_duplicateError(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_DUPLICATEERROR, [ + public static function pocketmine_plugin_duplicateError(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_DUPLICATEERROR, [ 0 => $param0, ]); } - public static function pocketmine_plugin_enable(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_ENABLE, [ + public static function pocketmine_plugin_enable(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_ENABLE, [ 0 => $param0, ]); } - public static function pocketmine_plugin_fileError(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_FILEERROR, [ + public static function pocketmine_plugin_fileError(Translatable|string $param0, Translatable|string $param1, Translatable|string $param2) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_FILEERROR, [ 0 => $param0, 1 => $param1, 2 => $param2, ]); } - public static function pocketmine_plugin_genericLoadError(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_GENERICLOADERROR, [ + public static function pocketmine_plugin_genericLoadError(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_GENERICLOADERROR, [ 0 => $param0, ]); } - public static function pocketmine_plugin_incompatibleAPI(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEAPI, [ + public static function pocketmine_plugin_incompatibleAPI(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEAPI, [ 0 => $param0, ]); } - public static function pocketmine_plugin_incompatibleOS(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEOS, [ + public static function pocketmine_plugin_incompatibleOS(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEOS, [ 0 => $param0, ]); } - public static function pocketmine_plugin_incompatiblePhpVersion(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEPHPVERSION, [ + public static function pocketmine_plugin_incompatiblePhpVersion(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEPHPVERSION, [ 0 => $param0, ]); } - public static function pocketmine_plugin_incompatibleProtocol(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEPROTOCOL, [ + public static function pocketmine_plugin_incompatibleProtocol(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEPROTOCOL, [ 0 => $param0, ]); } - public static function pocketmine_plugin_load(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_LOAD, [ + public static function pocketmine_plugin_load(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_LOAD, [ 0 => $param0, ]); } - public static function pocketmine_plugin_loadError(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_LOADERROR, [ + public static function pocketmine_plugin_loadError(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_LOADERROR, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_plugin_restrictedName() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_RESTRICTEDNAME, []); + public static function pocketmine_plugin_restrictedName() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_RESTRICTEDNAME, []); } - public static function pocketmine_plugin_spacesDiscouraged(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_SPACESDISCOURAGED, [ + public static function pocketmine_plugin_spacesDiscouraged(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_SPACESDISCOURAGED, [ 0 => $param0, ]); } - public static function pocketmine_plugin_unknownDependency(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGIN_UNKNOWNDEPENDENCY, [ + public static function pocketmine_plugin_unknownDependency(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_UNKNOWNDEPENDENCY, [ 0 => $param0, ]); } - public static function pocketmine_save_start() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SAVE_START, []); + public static function pocketmine_save_start() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SAVE_START, []); } - public static function pocketmine_save_success(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SAVE_SUCCESS, [ + public static function pocketmine_save_success(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SAVE_SUCCESS, [ 0 => $param0, ]); } - public static function pocketmine_server_auth_disabled() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_AUTH_DISABLED, []); + public static function pocketmine_server_auth_disabled() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_AUTH_DISABLED, []); } - public static function pocketmine_server_auth_enabled() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_AUTH_ENABLED, []); + public static function pocketmine_server_auth_enabled() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_AUTH_ENABLED, []); } - public static function pocketmine_server_authProperty_disabled() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_AUTHPROPERTY_DISABLED, []); + public static function pocketmine_server_authProperty_disabled() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_AUTHPROPERTY_DISABLED, []); } - public static function pocketmine_server_authProperty_enabled() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_AUTHPROPERTY_ENABLED, []); + public static function pocketmine_server_authProperty_enabled() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_AUTHPROPERTY_ENABLED, []); } - public static function pocketmine_server_authWarning() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_AUTHWARNING, []); + public static function pocketmine_server_authWarning() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_AUTHWARNING, []); } - public static function pocketmine_server_defaultGameMode(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEFAULTGAMEMODE, [ + public static function pocketmine_server_defaultGameMode(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_DEFAULTGAMEMODE, [ 0 => $param0, ]); } - public static function pocketmine_server_devBuild_error1(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR1, [ + public static function pocketmine_server_devBuild_error1(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR1, [ 0 => $param0, ]); } - public static function pocketmine_server_devBuild_error2() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR2, []); + public static function pocketmine_server_devBuild_error2() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR2, []); } - public static function pocketmine_server_devBuild_error3() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR3, []); + public static function pocketmine_server_devBuild_error3() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR3, []); } - public static function pocketmine_server_devBuild_error4(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR4, [ + public static function pocketmine_server_devBuild_error4(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR4, [ 0 => $param0, ]); } - public static function pocketmine_server_devBuild_error5(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR5, [ + public static function pocketmine_server_devBuild_error5(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_ERROR5, [ 0 => $param0, ]); } - public static function pocketmine_server_devBuild_warning1(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_WARNING1, [ + public static function pocketmine_server_devBuild_warning1(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_WARNING1, [ 0 => $param0, ]); } - public static function pocketmine_server_devBuild_warning2() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_WARNING2, []); + public static function pocketmine_server_devBuild_warning2() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_WARNING2, []); } - public static function pocketmine_server_devBuild_warning3() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_WARNING3, []); + public static function pocketmine_server_devBuild_warning3() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_DEVBUILD_WARNING3, []); } - public static function pocketmine_server_donate(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_DONATE, [ + public static function pocketmine_server_donate(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_DONATE, [ 0 => $param0, ]); } - public static function pocketmine_server_info(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_INFO, [ + public static function pocketmine_server_info(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_INFO, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_server_info_extended(TranslationContainer|string $param0, TranslationContainer|string $param1, TranslationContainer|string $param2, TranslationContainer|string $param3) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_INFO_EXTENDED, [ + public static function pocketmine_server_info_extended(Translatable|string $param0, Translatable|string $param1, Translatable|string $param2, Translatable|string $param3) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_INFO_EXTENDED, [ 0 => $param0, 1 => $param1, 2 => $param2, @@ -1575,220 +1575,220 @@ final class KnownTranslationFactory{ ]); } - public static function pocketmine_server_license(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_LICENSE, [ + public static function pocketmine_server_license(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_LICENSE, [ 0 => $param0, ]); } - public static function pocketmine_server_networkStart(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_NETWORKSTART, [ + public static function pocketmine_server_networkStart(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_NETWORKSTART, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_server_query_running(TranslationContainer|string $param0, TranslationContainer|string $param1) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_QUERY_RUNNING, [ + public static function pocketmine_server_query_running(Translatable|string $param0, Translatable|string $param1) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_QUERY_RUNNING, [ 0 => $param0, 1 => $param1, ]); } - public static function pocketmine_server_start(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_START, [ + public static function pocketmine_server_start(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_START, [ 0 => $param0, ]); } - public static function pocketmine_server_startFinished(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_STARTFINISHED, [ + public static function pocketmine_server_startFinished(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_STARTFINISHED, [ 0 => $param0, ]); } - public static function pocketmine_server_tickOverload() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_SERVER_TICKOVERLOAD, []); + public static function pocketmine_server_tickOverload() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_TICKOVERLOAD, []); } - public static function pocketmine_plugins() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_PLUGINS, []); + public static function pocketmine_plugins() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGINS, []); } - public static function pocketmine_will_start(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POCKETMINE_WILL_START, [ + public static function pocketmine_will_start(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_WILL_START, [ 0 => $param0, ]); } - public static function port_warning() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::PORT_WARNING, []); + public static function port_warning() : Translatable{ + return new Translatable(KnownTranslationKeys::PORT_WARNING, []); } - public static function potion_absorption() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_ABSORPTION, []); + public static function potion_absorption() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_ABSORPTION, []); } - public static function potion_blindness() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_BLINDNESS, []); + public static function potion_blindness() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_BLINDNESS, []); } - public static function potion_conduitPower() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_CONDUITPOWER, []); + public static function potion_conduitPower() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_CONDUITPOWER, []); } - public static function potion_confusion() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_CONFUSION, []); + public static function potion_confusion() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_CONFUSION, []); } - public static function potion_damageBoost() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_DAMAGEBOOST, []); + public static function potion_damageBoost() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_DAMAGEBOOST, []); } - public static function potion_digSlowDown() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_DIGSLOWDOWN, []); + public static function potion_digSlowDown() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_DIGSLOWDOWN, []); } - public static function potion_digSpeed() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_DIGSPEED, []); + public static function potion_digSpeed() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_DIGSPEED, []); } - public static function potion_fireResistance() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_FIRERESISTANCE, []); + public static function potion_fireResistance() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_FIRERESISTANCE, []); } - public static function potion_harm() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_HARM, []); + public static function potion_harm() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_HARM, []); } - public static function potion_heal() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_HEAL, []); + public static function potion_heal() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_HEAL, []); } - public static function potion_healthBoost() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_HEALTHBOOST, []); + public static function potion_healthBoost() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_HEALTHBOOST, []); } - public static function potion_hunger() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_HUNGER, []); + public static function potion_hunger() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_HUNGER, []); } - public static function potion_invisibility() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_INVISIBILITY, []); + public static function potion_invisibility() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_INVISIBILITY, []); } - public static function potion_jump() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_JUMP, []); + public static function potion_jump() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_JUMP, []); } - public static function potion_levitation() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_LEVITATION, []); + public static function potion_levitation() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_LEVITATION, []); } - public static function potion_moveSlowdown() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_MOVESLOWDOWN, []); + public static function potion_moveSlowdown() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_MOVESLOWDOWN, []); } - public static function potion_moveSpeed() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_MOVESPEED, []); + public static function potion_moveSpeed() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_MOVESPEED, []); } - public static function potion_nightVision() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_NIGHTVISION, []); + public static function potion_nightVision() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_NIGHTVISION, []); } - public static function potion_poison() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_POISON, []); + public static function potion_poison() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_POISON, []); } - public static function potion_regeneration() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_REGENERATION, []); + public static function potion_regeneration() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_REGENERATION, []); } - public static function potion_resistance() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_RESISTANCE, []); + public static function potion_resistance() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_RESISTANCE, []); } - public static function potion_saturation() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_SATURATION, []); + public static function potion_saturation() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_SATURATION, []); } - public static function potion_waterBreathing() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_WATERBREATHING, []); + public static function potion_waterBreathing() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_WATERBREATHING, []); } - public static function potion_weakness() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_WEAKNESS, []); + public static function potion_weakness() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_WEAKNESS, []); } - public static function potion_wither() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::POTION_WITHER, []); + public static function potion_wither() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_WITHER, []); } - public static function query_disable() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::QUERY_DISABLE, []); + public static function query_disable() : Translatable{ + return new Translatable(KnownTranslationKeys::QUERY_DISABLE, []); } - public static function query_warning1() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::QUERY_WARNING1, []); + public static function query_warning1() : Translatable{ + return new Translatable(KnownTranslationKeys::QUERY_WARNING1, []); } - public static function query_warning2() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::QUERY_WARNING2, []); + public static function query_warning2() : Translatable{ + return new Translatable(KnownTranslationKeys::QUERY_WARNING2, []); } - public static function server_port() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::SERVER_PORT, []); + public static function server_port() : Translatable{ + return new Translatable(KnownTranslationKeys::SERVER_PORT, []); } - public static function server_properties() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::SERVER_PROPERTIES, []); + public static function server_properties() : Translatable{ + return new Translatable(KnownTranslationKeys::SERVER_PROPERTIES, []); } - public static function setting_up_server_now() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::SETTING_UP_SERVER_NOW, []); + public static function setting_up_server_now() : Translatable{ + return new Translatable(KnownTranslationKeys::SETTING_UP_SERVER_NOW, []); } - public static function skip_installer() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::SKIP_INSTALLER, []); + public static function skip_installer() : Translatable{ + return new Translatable(KnownTranslationKeys::SKIP_INSTALLER, []); } - public static function tile_bed_noSleep() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::TILE_BED_NOSLEEP, []); + public static function tile_bed_noSleep() : Translatable{ + return new Translatable(KnownTranslationKeys::TILE_BED_NOSLEEP, []); } - public static function tile_bed_occupied() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::TILE_BED_OCCUPIED, []); + public static function tile_bed_occupied() : Translatable{ + return new Translatable(KnownTranslationKeys::TILE_BED_OCCUPIED, []); } - public static function tile_bed_tooFar() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::TILE_BED_TOOFAR, []); + public static function tile_bed_tooFar() : Translatable{ + return new Translatable(KnownTranslationKeys::TILE_BED_TOOFAR, []); } - public static function welcome_to_pocketmine(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::WELCOME_TO_POCKETMINE, [ + public static function welcome_to_pocketmine(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::WELCOME_TO_POCKETMINE, [ 0 => $param0, ]); } - public static function whitelist_enable() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::WHITELIST_ENABLE, []); + public static function whitelist_enable() : Translatable{ + return new Translatable(KnownTranslationKeys::WHITELIST_ENABLE, []); } - public static function whitelist_info() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::WHITELIST_INFO, []); + public static function whitelist_info() : Translatable{ + return new Translatable(KnownTranslationKeys::WHITELIST_INFO, []); } - public static function whitelist_warning() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::WHITELIST_WARNING, []); + public static function whitelist_warning() : Translatable{ + return new Translatable(KnownTranslationKeys::WHITELIST_WARNING, []); } - public static function you_have_finished() : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::YOU_HAVE_FINISHED, []); + public static function you_have_finished() : Translatable{ + return new Translatable(KnownTranslationKeys::YOU_HAVE_FINISHED, []); } - public static function you_have_to_accept_the_license(TranslationContainer|string $param0) : TranslationContainer{ - return new TranslationContainer(KnownTranslationKeys::YOU_HAVE_TO_ACCEPT_THE_LICENSE, [ + public static function you_have_to_accept_the_license(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::YOU_HAVE_TO_ACCEPT_THE_LICENSE, [ 0 => $param0, ]); } diff --git a/src/lang/Language.php b/src/lang/Language.php index ec95b19058..72e1a073be 100644 --- a/src/lang/Language.php +++ b/src/lang/Language.php @@ -130,26 +130,26 @@ class Language{ } /** - * @param (float|int|string|TranslationContainer)[] $params + * @param (float|int|string|Translatable)[] $params */ public function translateString(string $str, array $params = [], ?string $onlyPrefix = null) : string{ $baseText = $this->get($str); $baseText = $this->parseTranslation(($onlyPrefix === null or strpos($str, $onlyPrefix) === 0) ? $baseText : $str, $onlyPrefix); foreach($params as $i => $p){ - $replacement = $p instanceof TranslationContainer ? $this->translate($p) : $this->parseTranslation((string) $p); + $replacement = $p instanceof Translatable ? $this->translate($p) : $this->parseTranslation((string) $p); $baseText = str_replace("{%$i}", $replacement, $baseText); } return $baseText; } - public function translate(TranslationContainer $c) : string{ + public function translate(Translatable $c) : string{ $baseText = $this->internalGet($c->getText()); $baseText = $this->parseTranslation($baseText ?? $c->getText()); foreach($c->getParameters() as $i => $p){ - $replacement = $p instanceof TranslationContainer ? $this->translate($p) : $this->parseTranslation($p); + $replacement = $p instanceof Translatable ? $this->translate($p) : $this->parseTranslation($p); $baseText = str_replace("{%$i}", $replacement, $baseText); } diff --git a/src/lang/TranslationContainer.php b/src/lang/Translatable.php similarity index 83% rename from src/lang/TranslationContainer.php rename to src/lang/Translatable.php index 1b51f11ef3..43905a1b1c 100644 --- a/src/lang/TranslationContainer.php +++ b/src/lang/Translatable.php @@ -23,21 +23,21 @@ declare(strict_types=1); namespace pocketmine\lang; -final class TranslationContainer{ +final class Translatable{ /** @var string $text */ protected $text; - /** @var string[]|TranslationContainer[] $params */ + /** @var string[]|Translatable[] $params */ protected $params = []; /** - * @param (float|int|string|TranslationContainer)[] $params + * @param (float|int|string|Translatable)[] $params */ public function __construct(string $text, array $params = []){ $this->text = $text; foreach($params as $k => $param){ - if(!($param instanceof TranslationContainer)){ + if(!($param instanceof Translatable)){ $this->params[$k] = (string) $param; }else{ $this->params[$k] = $param; @@ -50,13 +50,13 @@ final class TranslationContainer{ } /** - * @return string[]|TranslationContainer[] + * @return string[]|Translatable[] */ public function getParameters() : array{ return $this->params; } - public function getParameter(int|string $i) : TranslationContainer|string|null{ + public function getParameter(int|string $i) : Translatable|string|null{ return $this->params[$i] ?? null; } diff --git a/src/player/Player.php b/src/player/Player.php index 8f423c5297..174d833a31 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -82,7 +82,7 @@ use pocketmine\item\ItemUseResult; use pocketmine\item\Releasable; use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\Language; -use pocketmine\lang\TranslationContainer; +use pocketmine\lang\Translatable; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; @@ -319,7 +319,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } } - public function getLeaveMessage() : TranslationContainer|string{ + public function getLeaveMessage() : Translatable|string{ if($this->spawned){ return KnownTranslationFactory::multiplayer_player_left($this->getDisplayName())->prefix(TextFormat::YELLOW); } @@ -1772,8 +1772,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ /** * Sends a direct chat message to a player */ - public function sendMessage(TranslationContainer|string $message) : void{ - if($message instanceof TranslationContainer){ + public function sendMessage(Translatable|string $message) : void{ + if($message instanceof Translatable){ $this->sendTranslation($message->getText(), $message->getParameters()); return; } @@ -1782,11 +1782,11 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } /** - * @param string[]|TranslationContainer[] $parameters + * @param string[]|Translatable[] $parameters */ public function sendTranslation(string $message, array $parameters = []) : void{ //we can't send nested translations to the client, so make sure they are always pre-translated by the server - $parameters = array_map(fn(string|TranslationContainer $p) => $p instanceof TranslationContainer ? $this->getLanguage()->translate($p) : $p, $parameters); + $parameters = array_map(fn(string|Translatable $p) => $p instanceof Translatable ? $this->getLanguage()->translate($p) : $p, $parameters); if(!$this->server->isLanguageForced()){ foreach($parameters as $i => $p){ $parameters[$i] = $this->getLanguage()->translateString($p, [], "pocketmine."); @@ -1873,7 +1873,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ /** * Kicks a player from the server */ - public function kick(string $reason = "", TranslationContainer|string|null $quitMessage = null) : bool{ + public function kick(string $reason = "", Translatable|string|null $quitMessage = null) : bool{ $ev = new PlayerKickEvent($this, $reason, $quitMessage ?? $this->getLeaveMessage()); $ev->call(); if(!$ev->isCancelled()){ @@ -1898,10 +1898,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ * * Note for internals developers: Do not call this from network sessions. It will cause a feedback loop. * - * @param string $reason Shown to the player, usually this will appear on their disconnect screen. - * @param TranslationContainer|string|null $quitMessage Message to broadcast to online players (null will use default) + * @param string $reason Shown to the player, usually this will appear on their disconnect screen. + * @param Translatable|string|null $quitMessage Message to broadcast to online players (null will use default) */ - public function disconnect(string $reason, TranslationContainer|string|null $quitMessage = null) : void{ + public function disconnect(string $reason, Translatable|string|null $quitMessage = null) : void{ if(!$this->isConnected()){ return; } @@ -1915,9 +1915,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ * This method executes post-disconnect actions and cleanups. * * @param string $reason Shown to the player, usually this will appear on their disconnect screen. - * @param TranslationContainer|string|null $quitMessage Message to broadcast to online players (null will use default) + * @param Translatable|string|null $quitMessage Message to broadcast to online players (null will use default) */ - public function onPostDisconnect(string $reason, TranslationContainer|string|null $quitMessage) : void{ + public function onPostDisconnect(string $reason, Translatable|string|null $quitMessage) : void{ if($this->isConnected()){ throw new \InvalidStateException("Player is still connected"); } From 715fbc9ee5ff3e710071fe34a6de2b1528dfb7b7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 15 Aug 2021 16:35:51 +0100 Subject: [PATCH 2703/3224] fix last remaining non-usages of KnownTranslationFactory --- resources/locale | 2 +- src/command/defaults/EnchantCommand.php | 3 +-- src/command/defaults/GamemodeCommand.php | 3 +-- src/command/defaults/VanillaCommand.php | 7 +++---- src/lang/KnownTranslationFactory.php | 12 ++++++++---- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/resources/locale b/resources/locale index b41efc9044..f07494a024 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit b41efc9044e1f6ab2d5c44ced3203ea18cba0165 +Subproject commit f07494a0245dc52fa6cbcc4d0e45703d1fc22ee8 diff --git a/src/command/defaults/EnchantCommand.php b/src/command/defaults/EnchantCommand.php index 592c7c57f2..205cb8b7a7 100644 --- a/src/command/defaults/EnchantCommand.php +++ b/src/command/defaults/EnchantCommand.php @@ -29,7 +29,6 @@ use pocketmine\item\enchantment\EnchantmentInstance; use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\Translatable; use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\TextFormat; use function count; @@ -86,7 +85,7 @@ class EnchantCommand extends VanillaCommand{ $item->addEnchantment(new EnchantmentInstance($enchantment, $level)); $player->getInventory()->setItemInHand($item); - self::broadcastCommandMessage($sender, new Translatable(KnownTranslationKeys::COMMANDS_ENCHANT_SUCCESS, [$player->getName()])); + self::broadcastCommandMessage($sender, KnownTranslationFactory::commands_enchant_success($player->getName())); return true; } } diff --git a/src/command/defaults/GamemodeCommand.php b/src/command/defaults/GamemodeCommand.php index a632458697..a5210c4382 100644 --- a/src/command/defaults/GamemodeCommand.php +++ b/src/command/defaults/GamemodeCommand.php @@ -28,7 +28,6 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\Translatable; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\GameMode; use pocketmine\player\Player; @@ -81,7 +80,7 @@ class GamemodeCommand extends VanillaCommand{ if($target === $sender){ Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_gamemode_success_self($gameMode->getTranslationKey())); }else{ - $target->sendMessage(new Translatable(KnownTranslationKeys::GAMEMODE_CHANGED, [$gameMode->getTranslationKey()])); + $target->sendMessage(KnownTranslationFactory::gameMode_changed($gameMode->getTranslationKey())); Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_gamemode_success_other($gameMode->getTranslationKey(), $target->getName())); } } diff --git a/src/command/defaults/VanillaCommand.php b/src/command/defaults/VanillaCommand.php index 7aa1c757dc..e4a32ee9c8 100644 --- a/src/command/defaults/VanillaCommand.php +++ b/src/command/defaults/VanillaCommand.php @@ -26,8 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; -use pocketmine\lang\KnownTranslationKeys; -use pocketmine\lang\Translatable; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\utils\TextFormat; use function is_numeric; use function substr; @@ -83,11 +82,11 @@ abstract class VanillaCommand extends Command{ $v = (int) $input; if($v > $max){ - $sender->sendMessage(new Translatable(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_NUM_TOOBIG, [$input, (string) $max])); + $sender->sendMessage(KnownTranslationFactory::commands_generic_num_tooBig($input, (string) $max)->prefix(TextFormat::RED)); return null; } if($v < $min){ - $sender->sendMessage(new Translatable(TextFormat::RED . "%" . KnownTranslationKeys::COMMANDS_GENERIC_NUM_TOOSMALL, [$input, (string) $min])); + $sender->sendMessage(KnownTranslationFactory::commands_generic_num_tooSmall($input, (string) $min)->prefix(TextFormat::RED)); return null; } diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index d61ce8ff33..5d9536487b 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -228,8 +228,10 @@ final class KnownTranslationFactory{ ]); } - public static function commands_enchant_success() : Translatable{ - return new Translatable(KnownTranslationKeys::COMMANDS_ENCHANT_SUCCESS, []); + public static function commands_enchant_success(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_ENCHANT_SUCCESS, [ + 0 => $param0, + ]); } public static function commands_enchant_usage() : Translatable{ @@ -753,8 +755,10 @@ final class KnownTranslationFactory{ return new Translatable(KnownTranslationKeys::GAMEMODE_ADVENTURE, []); } - public static function gameMode_changed() : Translatable{ - return new Translatable(KnownTranslationKeys::GAMEMODE_CHANGED, []); + public static function gameMode_changed(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::GAMEMODE_CHANGED, [ + 0 => $param0, + ]); } public static function gameMode_creative() : Translatable{ From 752d1179a1d44252ee0ce216f2b78ee284a39fb7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 15 Aug 2021 19:05:05 +0100 Subject: [PATCH 2704/3224] Do not rely on random translation keys prefixed with % getting translated --- src/command/SimpleCommandMap.php | 2 +- src/command/defaults/HelpCommand.php | 7 ++++--- src/command/defaults/WhitelistCommand.php | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/command/SimpleCommandMap.php b/src/command/SimpleCommandMap.php index 90d54be63c..4412ee8cbf 100644 --- a/src/command/SimpleCommandMap.php +++ b/src/command/SimpleCommandMap.php @@ -246,7 +246,7 @@ class SimpleCommandMap implements CommandMap{ try{ $target->execute($sender, $sentCommandLabel, $args); }catch(InvalidCommandSyntaxException $e){ - $sender->sendMessage($sender->getLanguage()->translate(KnownTranslationFactory::commands_generic_usage($target->getUsage()))); + $sender->sendMessage($sender->getLanguage()->translate(KnownTranslationFactory::commands_generic_usage($sender->getLanguage()->translateString($target->getUsage())))); }finally{ $target->timings->stopTiming(); } diff --git a/src/command/defaults/HelpCommand.php b/src/command/defaults/HelpCommand.php index 4ace7931c1..27f9c767e7 100644 --- a/src/command/defaults/HelpCommand.php +++ b/src/command/defaults/HelpCommand.php @@ -89,9 +89,10 @@ class HelpCommand extends VanillaCommand{ $pageNumber = 1; } $sender->sendMessage(KnownTranslationFactory::commands_help_header((string) $pageNumber, (string) count($commands))); + $lang = $sender->getLanguage(); if(isset($commands[$pageNumber - 1])){ foreach($commands[$pageNumber - 1] as $command){ - $sender->sendMessage(TextFormat::DARK_GREEN . "/" . $command->getName() . ": " . TextFormat::WHITE . $command->getDescription()); + $sender->sendMessage(TextFormat::DARK_GREEN . "/" . $command->getName() . ": " . TextFormat::WHITE . $lang->translateString($command->getDescription())); } } @@ -100,8 +101,8 @@ class HelpCommand extends VanillaCommand{ if(($cmd = $sender->getServer()->getCommandMap()->getCommand(strtolower($commandName))) instanceof Command){ if($cmd->testPermissionSilent($sender)){ $message = TextFormat::YELLOW . "--------- " . TextFormat::WHITE . " Help: /" . $cmd->getName() . TextFormat::YELLOW . " ---------\n"; - $message .= TextFormat::GOLD . "Description: " . TextFormat::WHITE . $cmd->getDescription() . "\n"; - $message .= TextFormat::GOLD . "Usage: " . TextFormat::WHITE . implode("\n" . TextFormat::WHITE, explode("\n", $cmd->getUsage())) . "\n"; + $message .= TextFormat::GOLD . "Description: " . TextFormat::WHITE . $sender->getLanguage()->translateString($cmd->getDescription()) . "\n"; + $message .= TextFormat::GOLD . "Usage: " . TextFormat::WHITE . implode("\n" . TextFormat::WHITE, explode("\n", $sender->getLanguage()->translateString($cmd->getUsage()))) . "\n"; $sender->sendMessage($message); return true; diff --git a/src/command/defaults/WhitelistCommand.php b/src/command/defaults/WhitelistCommand.php index afbcb3e381..abe67064f8 100644 --- a/src/command/defaults/WhitelistCommand.php +++ b/src/command/defaults/WhitelistCommand.php @@ -96,11 +96,11 @@ class WhitelistCommand extends VanillaCommand{ return true; case "add": - $sender->sendMessage(KnownTranslationFactory::commands_generic_usage("%" . KnownTranslationKeys::COMMANDS_WHITELIST_ADD_USAGE)); + $sender->sendMessage(KnownTranslationFactory::commands_generic_usage(KnownTranslationFactory::commands_whitelist_add_usage())); return true; case "remove": - $sender->sendMessage(KnownTranslationFactory::commands_generic_usage("%" . KnownTranslationKeys::COMMANDS_WHITELIST_REMOVE_USAGE)); + $sender->sendMessage(KnownTranslationFactory::commands_generic_usage(KnownTranslationFactory::commands_whitelist_remove_usage())); return true; } }elseif(count($args) === 2){ From 60ac76a3bc9fb1b737c3b04d319c232a10ffe6cd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 15 Aug 2021 19:22:40 +0100 Subject: [PATCH 2705/3224] Remove more usages of hardcoded translation keys --- src/Server.php | 2 +- src/block/Jukebox.php | 2 +- src/block/utils/RecordType.php | 35 ++++++------- .../defaults/DefaultGamemodeCommand.php | 2 +- src/command/defaults/GamemodeCommand.php | 6 +-- src/lang/KnownTranslationFactory.php | 52 +++++++++++++++++++ src/lang/KnownTranslationKeys.php | 13 +++++ src/player/GameMode.php | 19 +++---- 8 files changed, 95 insertions(+), 36 deletions(-) diff --git a/src/Server.php b/src/Server.php index 888b34f1f7..6f243532a6 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1051,7 +1051,7 @@ class Server{ $this->configGroup->save(); - $this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_defaultGameMode($this->getGamemode()->getTranslationKey()))); + $this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_defaultGameMode($this->getGamemode()->getTranslatableName()))); $this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_donate(TextFormat::AQUA . "https://patreon.com/pocketminemp" . TextFormat::RESET))); $this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_startFinished(strval(round(microtime(true) - $this->startTime, 3))))); diff --git a/src/block/Jukebox.php b/src/block/Jukebox.php index 66369817b3..37a0e53b5d 100644 --- a/src/block/Jukebox.php +++ b/src/block/Jukebox.php @@ -44,7 +44,7 @@ class Jukebox extends Opaque{ if($this->record !== null){ $this->ejectRecord(); }elseif($item instanceof Record){ - $player->sendJukeboxPopup("record.nowPlaying", ["%" . $item->getRecordType()->getTranslationKey()]); + $player->sendJukeboxPopup("record.nowPlaying", [$player->getLanguage()->translate($item->getRecordType()->getTranslatableName())]); $this->insertRecord($item->pop()); } } diff --git a/src/block/utils/RecordType.php b/src/block/utils/RecordType.php index 57def3b4c9..8b72d0a786 100644 --- a/src/block/utils/RecordType.php +++ b/src/block/utils/RecordType.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\block\utils; +use pocketmine\lang\KnownTranslationFactory; +use pocketmine\lang\Translatable; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\utils\EnumTrait; @@ -51,18 +53,18 @@ final class RecordType{ protected static function setup() : void{ self::registerAll( - new RecordType("disk_13", "C418 - 13", LevelSoundEventPacket::SOUND_RECORD_13, "item.record_13.desc"), - new RecordType("disk_cat", "C418 - cat", LevelSoundEventPacket::SOUND_RECORD_CAT, "item.record_cat.desc"), - new RecordType("disk_blocks", "C418 - blocks", LevelSoundEventPacket::SOUND_RECORD_BLOCKS, "item.record_blocks.desc"), - new RecordType("disk_chirp", "C418 - chirp", LevelSoundEventPacket::SOUND_RECORD_CHIRP, "item.record_chirp.desc"), - new RecordType("disk_far", "C418 - far", LevelSoundEventPacket::SOUND_RECORD_FAR, "item.record_far.desc"), - new RecordType("disk_mall", "C418 - mall", LevelSoundEventPacket::SOUND_RECORD_MALL, "item.record_mall.desc"), - new RecordType("disk_mellohi", "C418 - mellohi", LevelSoundEventPacket::SOUND_RECORD_MELLOHI, "item.record_mellohi.desc"), - new RecordType("disk_stal", "C418 - stal", LevelSoundEventPacket::SOUND_RECORD_STAL, "item.record_stal.desc"), - new RecordType("disk_strad", "C418 - strad", LevelSoundEventPacket::SOUND_RECORD_STRAD, "item.record_strad.desc"), - new RecordType("disk_ward", "C418 - ward", LevelSoundEventPacket::SOUND_RECORD_WARD, "item.record_ward.desc"), - new RecordType("disk_11", "C418 - 11", LevelSoundEventPacket::SOUND_RECORD_11, "item.record_11.desc"), - new RecordType("disk_wait", "C418 - wait", LevelSoundEventPacket::SOUND_RECORD_WAIT, "item.record_wait.desc") + new RecordType("disk_13", "C418 - 13", LevelSoundEventPacket::SOUND_RECORD_13, KnownTranslationFactory::item_record_13_desc()), + new RecordType("disk_cat", "C418 - cat", LevelSoundEventPacket::SOUND_RECORD_CAT, KnownTranslationFactory::item_record_cat_desc()), + new RecordType("disk_blocks", "C418 - blocks", LevelSoundEventPacket::SOUND_RECORD_BLOCKS, KnownTranslationFactory::item_record_blocks_desc()), + new RecordType("disk_chirp", "C418 - chirp", LevelSoundEventPacket::SOUND_RECORD_CHIRP, KnownTranslationFactory::item_record_chirp_desc()), + new RecordType("disk_far", "C418 - far", LevelSoundEventPacket::SOUND_RECORD_FAR, KnownTranslationFactory::item_record_far_desc()), + new RecordType("disk_mall", "C418 - mall", LevelSoundEventPacket::SOUND_RECORD_MALL, KnownTranslationFactory::item_record_mall_desc()), + new RecordType("disk_mellohi", "C418 - mellohi", LevelSoundEventPacket::SOUND_RECORD_MELLOHI, KnownTranslationFactory::item_record_mellohi_desc()), + new RecordType("disk_stal", "C418 - stal", LevelSoundEventPacket::SOUND_RECORD_STAL, KnownTranslationFactory::item_record_stal_desc()), + new RecordType("disk_strad", "C418 - strad", LevelSoundEventPacket::SOUND_RECORD_STRAD, KnownTranslationFactory::item_record_strad_desc()), + new RecordType("disk_ward", "C418 - ward", LevelSoundEventPacket::SOUND_RECORD_WARD, KnownTranslationFactory::item_record_ward_desc()), + new RecordType("disk_11", "C418 - 11", LevelSoundEventPacket::SOUND_RECORD_11, KnownTranslationFactory::item_record_11_desc()), + new RecordType("disk_wait", "C418 - wait", LevelSoundEventPacket::SOUND_RECORD_WAIT, KnownTranslationFactory::item_record_wait_desc()) //TODO: Lena Raine - Pigstep ); } @@ -71,14 +73,11 @@ final class RecordType{ private $soundName; /** @var int */ private $soundId; - /** @var string */ - private $translationKey; - private function __construct(string $enumName, string $soundName, int $soundId, string $translationKey){ + private function __construct(string $enumName, string $soundName, int $soundId, private Translatable $translatableName){ $this->Enum___construct($enumName); $this->soundName = $soundName; $this->soundId = $soundId; - $this->translationKey = $translationKey; } public function getSoundName() : string{ @@ -89,7 +88,5 @@ final class RecordType{ return $this->soundId; } - public function getTranslationKey() : string{ - return $this->translationKey; - } + public function getTranslatableName() : Translatable{ return $this->translatableName; } } diff --git a/src/command/defaults/DefaultGamemodeCommand.php b/src/command/defaults/DefaultGamemodeCommand.php index f799777f22..bbfa5eb357 100644 --- a/src/command/defaults/DefaultGamemodeCommand.php +++ b/src/command/defaults/DefaultGamemodeCommand.php @@ -59,7 +59,7 @@ class DefaultGamemodeCommand extends VanillaCommand{ } $sender->getServer()->getConfigGroup()->setConfigInt("gamemode", GameModeIdMap::getInstance()->toId($gameMode)); - $sender->sendMessage(KnownTranslationFactory::commands_defaultgamemode_success($gameMode->getTranslationKey())); + $sender->sendMessage(KnownTranslationFactory::commands_defaultgamemode_success($gameMode->getTranslatableName())); return true; } } diff --git a/src/command/defaults/GamemodeCommand.php b/src/command/defaults/GamemodeCommand.php index a5210c4382..e8a51bec62 100644 --- a/src/command/defaults/GamemodeCommand.php +++ b/src/command/defaults/GamemodeCommand.php @@ -78,10 +78,10 @@ class GamemodeCommand extends VanillaCommand{ $sender->sendMessage("Game mode change for " . $target->getName() . " failed!"); }else{ if($target === $sender){ - Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_gamemode_success_self($gameMode->getTranslationKey())); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_gamemode_success_self($gameMode->getTranslatableName())); }else{ - $target->sendMessage(KnownTranslationFactory::gameMode_changed($gameMode->getTranslationKey())); - Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_gamemode_success_other($gameMode->getTranslationKey(), $target->getName())); + $target->sendMessage(KnownTranslationFactory::gameMode_changed($gameMode->getTranslatableName())); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_gamemode_success_other($gameMode->getTranslatableName(), $target->getName())); } } diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index 5d9536487b..650d19d83f 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -796,6 +796,58 @@ final class KnownTranslationFactory{ ]); } + public static function item_record_11_desc() : Translatable{ + return new Translatable(KnownTranslationKeys::ITEM_RECORD_11_DESC, []); + } + + public static function item_record_13_desc() : Translatable{ + return new Translatable(KnownTranslationKeys::ITEM_RECORD_13_DESC, []); + } + + public static function item_record_blocks_desc() : Translatable{ + return new Translatable(KnownTranslationKeys::ITEM_RECORD_BLOCKS_DESC, []); + } + + public static function item_record_cat_desc() : Translatable{ + return new Translatable(KnownTranslationKeys::ITEM_RECORD_CAT_DESC, []); + } + + public static function item_record_chirp_desc() : Translatable{ + return new Translatable(KnownTranslationKeys::ITEM_RECORD_CHIRP_DESC, []); + } + + public static function item_record_far_desc() : Translatable{ + return new Translatable(KnownTranslationKeys::ITEM_RECORD_FAR_DESC, []); + } + + public static function item_record_mall_desc() : Translatable{ + return new Translatable(KnownTranslationKeys::ITEM_RECORD_MALL_DESC, []); + } + + public static function item_record_mellohi_desc() : Translatable{ + return new Translatable(KnownTranslationKeys::ITEM_RECORD_MELLOHI_DESC, []); + } + + public static function item_record_pigstep_desc() : Translatable{ + return new Translatable(KnownTranslationKeys::ITEM_RECORD_PIGSTEP_DESC, []); + } + + public static function item_record_stal_desc() : Translatable{ + return new Translatable(KnownTranslationKeys::ITEM_RECORD_STAL_DESC, []); + } + + public static function item_record_strad_desc() : Translatable{ + return new Translatable(KnownTranslationKeys::ITEM_RECORD_STRAD_DESC, []); + } + + public static function item_record_wait_desc() : Translatable{ + return new Translatable(KnownTranslationKeys::ITEM_RECORD_WAIT_DESC, []); + } + + public static function item_record_ward_desc() : Translatable{ + return new Translatable(KnownTranslationKeys::ITEM_RECORD_WARD_DESC, []); + } + public static function kick_admin() : Translatable{ return new Translatable(KnownTranslationKeys::KICK_ADMIN, []); } diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index 128049118b..12aaa7d57e 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -171,6 +171,19 @@ final class KnownTranslationKeys{ public const IP_CONFIRM = "ip_confirm"; public const IP_GET = "ip_get"; public const IP_WARNING = "ip_warning"; + public const ITEM_RECORD_11_DESC = "item.record_11.desc"; + public const ITEM_RECORD_13_DESC = "item.record_13.desc"; + public const ITEM_RECORD_BLOCKS_DESC = "item.record_blocks.desc"; + public const ITEM_RECORD_CAT_DESC = "item.record_cat.desc"; + public const ITEM_RECORD_CHIRP_DESC = "item.record_chirp.desc"; + public const ITEM_RECORD_FAR_DESC = "item.record_far.desc"; + public const ITEM_RECORD_MALL_DESC = "item.record_mall.desc"; + public const ITEM_RECORD_MELLOHI_DESC = "item.record_mellohi.desc"; + public const ITEM_RECORD_PIGSTEP_DESC = "item.record_pigstep.desc"; + public const ITEM_RECORD_STAL_DESC = "item.record_stal.desc"; + public const ITEM_RECORD_STRAD_DESC = "item.record_strad.desc"; + public const ITEM_RECORD_WAIT_DESC = "item.record_wait.desc"; + public const ITEM_RECORD_WARD_DESC = "item.record_ward.desc"; public const KICK_ADMIN = "kick.admin"; public const KICK_ADMIN_REASON = "kick.admin.reason"; public const KICK_REASON_CHEAT = "kick.reason.cheat"; diff --git a/src/player/GameMode.php b/src/player/GameMode.php index 97eb21d955..e3bcd9e1b7 100644 --- a/src/player/GameMode.php +++ b/src/player/GameMode.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\player; +use pocketmine\lang\KnownTranslationFactory; +use pocketmine\lang\Translatable; use pocketmine\utils\EnumTrait; use function mb_strtolower; @@ -47,10 +49,10 @@ final class GameMode{ protected static function setup() : void{ self::registerAll( - new self("survival", "Survival", "gameMode.survival", ["survival", "s", "0"]), - new self("creative", "Creative", "gameMode.creative", ["creative", "c", "1"]), - new self("adventure", "Adventure", "gameMode.adventure", ["adventure", "a", "2"]), - new self("spectator", "Spectator", "gameMode.spectator", ["spectator", "v", "view", "3"]) + new self("survival", "Survival", KnownTranslationFactory::gameMode_survival(), ["survival", "s", "0"]), + new self("creative", "Creative", KnownTranslationFactory::gameMode_creative(), ["creative", "c", "1"]), + new self("adventure", "Adventure", KnownTranslationFactory::gameMode_adventure(), ["adventure", "a", "2"]), + new self("spectator", "Spectator", KnownTranslationFactory::gameMode_spectator(), ["spectator", "v", "view", "3"]) ); } @@ -68,18 +70,15 @@ final class GameMode{ /** @var string */ private $englishName; - /** @var string */ - private $translationKey; /** @var string[] */ private $aliases; /** * @param string[] $aliases */ - private function __construct(string $enumName, string $englishName, string $translationKey, array $aliases = []){ + private function __construct(string $enumName, string $englishName, private Translatable $translatableName, array $aliases = []){ $this->Enum___construct($enumName); $this->englishName = $englishName; - $this->translationKey = $translationKey; $this->aliases = $aliases; } @@ -87,9 +86,7 @@ final class GameMode{ return $this->englishName; } - public function getTranslationKey() : string{ - return "%" . $this->translationKey; - } + public function getTranslatableName() : Translatable{ return $this->translatableName; } /** * @return string[] From dfc82f68209a06a1014d2ee3c789cfbf7025db3e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 15 Aug 2021 19:32:33 +0100 Subject: [PATCH 2706/3224] VanillaCommand: fix bogus mixed typehints --- src/command/defaults/VanillaCommand.php | 10 ++-------- .../phpstan/configs/check-explicit-mixed-baseline.neon | 10 ---------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/command/defaults/VanillaCommand.php b/src/command/defaults/VanillaCommand.php index e4a32ee9c8..7133597d8f 100644 --- a/src/command/defaults/VanillaCommand.php +++ b/src/command/defaults/VanillaCommand.php @@ -35,10 +35,7 @@ abstract class VanillaCommand extends Command{ public const MAX_COORD = 30000000; public const MIN_COORD = -30000000; - /** - * @param mixed $value - */ - protected function getInteger(CommandSender $sender, $value, int $min = self::MIN_COORD, int $max = self::MAX_COORD) : int{ + protected function getInteger(CommandSender $sender, string $value, int $min = self::MIN_COORD, int $max = self::MAX_COORD) : int{ $i = (int) $value; if($i < $min){ @@ -60,10 +57,7 @@ abstract class VanillaCommand extends Command{ return $this->getDouble($sender, $input, $min, $max); } - /** - * @param mixed $value - */ - protected function getDouble(CommandSender $sender, $value, float $min = self::MIN_COORD, float $max = self::MAX_COORD) : float{ + protected function getDouble(CommandSender $sender, string $value, float $min = self::MIN_COORD, float $max = self::MAX_COORD) : float{ $i = (double) $value; if($i < $min){ diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index 71c18550f1..9d12ae3ada 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -50,16 +50,6 @@ parameters: count: 2 path: ../../../src/VersionInfo.php - - - message: "#^Cannot cast mixed to float\\.$#" - count: 1 - path: ../../../src/command/defaults/VanillaCommand.php - - - - message: "#^Cannot cast mixed to int\\.$#" - count: 1 - path: ../../../src/command/defaults/VanillaCommand.php - - message: "#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#" count: 1 From 1aa541aefe87c0c07a2d40e96a4e6c9a03bd351f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 15 Aug 2021 19:38:55 +0100 Subject: [PATCH 2707/3224] Utils: remove useless commented code --- src/utils/Utils.php | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/utils/Utils.php b/src/utils/Utils.php index 32c40d92f3..774874f628 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -347,18 +347,6 @@ final class Utils{ return preg_replace('#([^\x20-\x7E])#', '.', $str); } - /* - public static function angle3D($pos1, $pos2){ - $X = $pos1["x"] - $pos2["x"]; - $Z = $pos1["z"] - $pos2["z"]; - $dXZ = sqrt(pow($X, 2) + pow($Z, 2)); - $Y = $pos1["y"] - $pos2["y"]; - $hAngle = rad2deg(atan2($Z, $X) - M_PI_2); - $vAngle = rad2deg(-atan2($Y, $dXZ)); - - return array("yaw" => $hAngle, "pitch" => $vAngle); - }*/ - public static function javaStringHash(string $string) : int{ $hash = 0; for($i = 0, $len = strlen($string); $i < $len; $i++){ From 39cdf23bd5fc7e620378fd6c70c08bb46b0ad6fd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 15 Aug 2021 20:00:58 +0100 Subject: [PATCH 2708/3224] Language: Attempt to treat parameters as translation keys, even if they don't have %prefixes %prefixes should only be necessary for embedded translations where the key isn't at the start of the string. Longer term we should just drop raw string translation entirely and just translate Translatables exclusively, but this is a stepping stone. --- src/lang/Language.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lang/Language.php b/src/lang/Language.php index 72e1a073be..ea8171dfd5 100644 --- a/src/lang/Language.php +++ b/src/lang/Language.php @@ -137,7 +137,7 @@ class Language{ $baseText = $this->parseTranslation(($onlyPrefix === null or strpos($str, $onlyPrefix) === 0) ? $baseText : $str, $onlyPrefix); foreach($params as $i => $p){ - $replacement = $p instanceof Translatable ? $this->translate($p) : $this->parseTranslation((string) $p); + $replacement = $p instanceof Translatable ? $this->translate($p) : $this->internalGet((string) $p) ?? $this->parseTranslation((string) $p); $baseText = str_replace("{%$i}", $replacement, $baseText); } @@ -149,7 +149,7 @@ class Language{ $baseText = $this->parseTranslation($baseText ?? $c->getText()); foreach($c->getParameters() as $i => $p){ - $replacement = $p instanceof Translatable ? $this->translate($p) : $this->parseTranslation($p); + $replacement = $p instanceof Translatable ? $this->translate($p) : $this->internalGet($p) ?? $this->parseTranslation($p); $baseText = str_replace("{%$i}", $replacement, $baseText); } From 039c59856da48666e9830fe00b67749fc23e7aa7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 15 Aug 2021 20:03:38 +0100 Subject: [PATCH 2709/3224] Remove % translation prefixes dotted around all over the place --- src/command/defaults/BanCommand.php | 4 ++-- src/command/defaults/BanIpCommand.php | 4 ++-- src/command/defaults/BanListCommand.php | 4 ++-- src/command/defaults/ClearCommand.php | 4 ++-- src/command/defaults/DefaultGamemodeCommand.php | 4 ++-- src/command/defaults/DeopCommand.php | 4 ++-- src/command/defaults/DifficultyCommand.php | 4 ++-- src/command/defaults/EffectCommand.php | 4 ++-- src/command/defaults/EnchantCommand.php | 4 ++-- src/command/defaults/GamemodeCommand.php | 4 ++-- src/command/defaults/GarbageCollectorCommand.php | 4 ++-- src/command/defaults/GiveCommand.php | 4 ++-- src/command/defaults/HelpCommand.php | 4 ++-- src/command/defaults/KickCommand.php | 4 ++-- src/command/defaults/KillCommand.php | 4 ++-- src/command/defaults/ListCommand.php | 4 ++-- src/command/defaults/MeCommand.php | 4 ++-- src/command/defaults/OpCommand.php | 4 ++-- src/command/defaults/PardonCommand.php | 4 ++-- src/command/defaults/PardonIpCommand.php | 4 ++-- src/command/defaults/ParticleCommand.php | 4 ++-- src/command/defaults/PluginsCommand.php | 4 ++-- src/command/defaults/SaveCommand.php | 4 ++-- src/command/defaults/SaveOffCommand.php | 4 ++-- src/command/defaults/SaveOnCommand.php | 4 ++-- src/command/defaults/SayCommand.php | 4 ++-- src/command/defaults/SeedCommand.php | 4 ++-- src/command/defaults/SetWorldSpawnCommand.php | 4 ++-- src/command/defaults/SpawnpointCommand.php | 4 ++-- src/command/defaults/StatusCommand.php | 4 ++-- src/command/defaults/StopCommand.php | 4 ++-- src/command/defaults/TeleportCommand.php | 4 ++-- src/command/defaults/TellCommand.php | 4 ++-- src/command/defaults/TimeCommand.php | 4 ++-- src/command/defaults/TimingsCommand.php | 4 ++-- src/command/defaults/TitleCommand.php | 4 ++-- src/command/defaults/TransferServerCommand.php | 4 ++-- src/command/defaults/VersionCommand.php | 4 ++-- src/command/defaults/WhitelistCommand.php | 4 ++-- src/network/mcpe/auth/ProcessLoginTask.php | 10 +++++----- 40 files changed, 83 insertions(+), 83 deletions(-) diff --git a/src/command/defaults/BanCommand.php b/src/command/defaults/BanCommand.php index d571a9aa04..3e264abf83 100644 --- a/src/command/defaults/BanCommand.php +++ b/src/command/defaults/BanCommand.php @@ -39,8 +39,8 @@ class BanCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_BAN_PLAYER_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_BAN_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_BAN_PLAYER_DESCRIPTION, + KnownTranslationKeys::COMMANDS_BAN_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_BAN_PLAYER); } diff --git a/src/command/defaults/BanIpCommand.php b/src/command/defaults/BanIpCommand.php index 3356e5ece1..13305b7844 100644 --- a/src/command/defaults/BanIpCommand.php +++ b/src/command/defaults/BanIpCommand.php @@ -40,8 +40,8 @@ class BanIpCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_BAN_IP_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_BANIP_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_BAN_IP_DESCRIPTION, + KnownTranslationKeys::COMMANDS_BANIP_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_BAN_IP); } diff --git a/src/command/defaults/BanListCommand.php b/src/command/defaults/BanListCommand.php index 86d140cb10..3cf92076ce 100644 --- a/src/command/defaults/BanListCommand.php +++ b/src/command/defaults/BanListCommand.php @@ -41,8 +41,8 @@ class BanListCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_BANLIST_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_BANLIST_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_BANLIST_DESCRIPTION, + KnownTranslationKeys::COMMANDS_BANLIST_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_BAN_LIST); } diff --git a/src/command/defaults/ClearCommand.php b/src/command/defaults/ClearCommand.php index 08f160caa2..b2dbcc97b2 100644 --- a/src/command/defaults/ClearCommand.php +++ b/src/command/defaults/ClearCommand.php @@ -42,8 +42,8 @@ class ClearCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_CLEAR_DESCRIPTION, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_CLEAR_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_CLEAR_DESCRIPTION, + KnownTranslationKeys::POCKETMINE_COMMAND_CLEAR_USAGE ); $this->setPermission(implode(";", [DefaultPermissionNames::COMMAND_CLEAR_SELF, DefaultPermissionNames::COMMAND_CLEAR_OTHER])); } diff --git a/src/command/defaults/DefaultGamemodeCommand.php b/src/command/defaults/DefaultGamemodeCommand.php index bbfa5eb357..501ef98fab 100644 --- a/src/command/defaults/DefaultGamemodeCommand.php +++ b/src/command/defaults/DefaultGamemodeCommand.php @@ -37,8 +37,8 @@ class DefaultGamemodeCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_DEFAULTGAMEMODE_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_DEFAULTGAMEMODE_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_DEFAULTGAMEMODE_DESCRIPTION, + KnownTranslationKeys::COMMANDS_DEFAULTGAMEMODE_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_DEFAULTGAMEMODE); } diff --git a/src/command/defaults/DeopCommand.php b/src/command/defaults/DeopCommand.php index 900aa0381a..615eb9b498 100644 --- a/src/command/defaults/DeopCommand.php +++ b/src/command/defaults/DeopCommand.php @@ -39,8 +39,8 @@ class DeopCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_DEOP_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_DEOP_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_DEOP_DESCRIPTION, + KnownTranslationKeys::COMMANDS_DEOP_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_OP_TAKE); } diff --git a/src/command/defaults/DifficultyCommand.php b/src/command/defaults/DifficultyCommand.php index ce5b42ce73..c61fc2516e 100644 --- a/src/command/defaults/DifficultyCommand.php +++ b/src/command/defaults/DifficultyCommand.php @@ -37,8 +37,8 @@ class DifficultyCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_DIFFICULTY_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_DIFFICULTY_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_DIFFICULTY_DESCRIPTION, + KnownTranslationKeys::COMMANDS_DIFFICULTY_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_DIFFICULTY); } diff --git a/src/command/defaults/EffectCommand.php b/src/command/defaults/EffectCommand.php index 5923010036..ac5828d656 100644 --- a/src/command/defaults/EffectCommand.php +++ b/src/command/defaults/EffectCommand.php @@ -40,8 +40,8 @@ class EffectCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_EFFECT_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_EFFECT_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_EFFECT_DESCRIPTION, + KnownTranslationKeys::COMMANDS_EFFECT_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_EFFECT); } diff --git a/src/command/defaults/EnchantCommand.php b/src/command/defaults/EnchantCommand.php index 205cb8b7a7..10d2c3f167 100644 --- a/src/command/defaults/EnchantCommand.php +++ b/src/command/defaults/EnchantCommand.php @@ -38,8 +38,8 @@ class EnchantCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_ENCHANT_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_ENCHANT_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_ENCHANT_DESCRIPTION, + KnownTranslationKeys::COMMANDS_ENCHANT_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_ENCHANT); } diff --git a/src/command/defaults/GamemodeCommand.php b/src/command/defaults/GamemodeCommand.php index e8a51bec62..90c6627aeb 100644 --- a/src/command/defaults/GamemodeCommand.php +++ b/src/command/defaults/GamemodeCommand.php @@ -39,8 +39,8 @@ class GamemodeCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_GAMEMODE_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_GAMEMODE_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_GAMEMODE_DESCRIPTION, + KnownTranslationKeys::COMMANDS_GAMEMODE_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_GAMEMODE); } diff --git a/src/command/defaults/GarbageCollectorCommand.php b/src/command/defaults/GarbageCollectorCommand.php index 8e11fb515b..e9ce55f317 100644 --- a/src/command/defaults/GarbageCollectorCommand.php +++ b/src/command/defaults/GarbageCollectorCommand.php @@ -37,8 +37,8 @@ class GarbageCollectorCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_GC_DESCRIPTION, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_GC_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_GC_DESCRIPTION, + KnownTranslationKeys::POCKETMINE_COMMAND_GC_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_GC); } diff --git a/src/command/defaults/GiveCommand.php b/src/command/defaults/GiveCommand.php index 975d63d888..6d3df6ab1b 100644 --- a/src/command/defaults/GiveCommand.php +++ b/src/command/defaults/GiveCommand.php @@ -43,8 +43,8 @@ class GiveCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_GIVE_DESCRIPTION, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_GIVE_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_GIVE_DESCRIPTION, + KnownTranslationKeys::POCKETMINE_COMMAND_GIVE_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_GIVE); } diff --git a/src/command/defaults/HelpCommand.php b/src/command/defaults/HelpCommand.php index 27f9c767e7..be1beab252 100644 --- a/src/command/defaults/HelpCommand.php +++ b/src/command/defaults/HelpCommand.php @@ -46,8 +46,8 @@ class HelpCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_HELP_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_HELP_USAGE, + KnownTranslationKeys::POCKETMINE_COMMAND_HELP_DESCRIPTION, + KnownTranslationKeys::COMMANDS_HELP_USAGE, ["?"] ); $this->setPermission(DefaultPermissionNames::COMMAND_HELP); diff --git a/src/command/defaults/KickCommand.php b/src/command/defaults/KickCommand.php index d654be2da4..50a37f6a80 100644 --- a/src/command/defaults/KickCommand.php +++ b/src/command/defaults/KickCommand.php @@ -41,8 +41,8 @@ class KickCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_KICK_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_KICK_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_KICK_DESCRIPTION, + KnownTranslationKeys::COMMANDS_KICK_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_KICK); } diff --git a/src/command/defaults/KillCommand.php b/src/command/defaults/KillCommand.php index 2e1bb0b9f2..ff96a387f0 100644 --- a/src/command/defaults/KillCommand.php +++ b/src/command/defaults/KillCommand.php @@ -40,8 +40,8 @@ class KillCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_KILL_DESCRIPTION, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_KILL_USAGE, + KnownTranslationKeys::POCKETMINE_COMMAND_KILL_DESCRIPTION, + KnownTranslationKeys::POCKETMINE_COMMAND_KILL_USAGE, ["suicide"] ); $this->setPermission(implode(";", [DefaultPermissionNames::COMMAND_KILL_SELF, DefaultPermissionNames::COMMAND_KILL_OTHER])); diff --git a/src/command/defaults/ListCommand.php b/src/command/defaults/ListCommand.php index db8e66c8e4..556ff24f88 100644 --- a/src/command/defaults/ListCommand.php +++ b/src/command/defaults/ListCommand.php @@ -40,8 +40,8 @@ class ListCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_LIST_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_PLAYERS_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_LIST_DESCRIPTION, + KnownTranslationKeys::COMMANDS_PLAYERS_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_LIST); } diff --git a/src/command/defaults/MeCommand.php b/src/command/defaults/MeCommand.php index f0df8bf336..d1d8329491 100644 --- a/src/command/defaults/MeCommand.php +++ b/src/command/defaults/MeCommand.php @@ -38,8 +38,8 @@ class MeCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_ME_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_ME_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_ME_DESCRIPTION, + KnownTranslationKeys::COMMANDS_ME_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_ME); } diff --git a/src/command/defaults/OpCommand.php b/src/command/defaults/OpCommand.php index 721dda447e..3e172b3daf 100644 --- a/src/command/defaults/OpCommand.php +++ b/src/command/defaults/OpCommand.php @@ -39,8 +39,8 @@ class OpCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_OP_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_OP_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_OP_DESCRIPTION, + KnownTranslationKeys::COMMANDS_OP_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_OP_GIVE); } diff --git a/src/command/defaults/PardonCommand.php b/src/command/defaults/PardonCommand.php index f35839b00b..27b40069f0 100644 --- a/src/command/defaults/PardonCommand.php +++ b/src/command/defaults/PardonCommand.php @@ -36,8 +36,8 @@ class PardonCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_UNBAN_PLAYER_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_UNBAN_USAGE, + KnownTranslationKeys::POCKETMINE_COMMAND_UNBAN_PLAYER_DESCRIPTION, + KnownTranslationKeys::COMMANDS_UNBAN_USAGE, ["unban"] ); $this->setPermission(DefaultPermissionNames::COMMAND_UNBAN_PLAYER); diff --git a/src/command/defaults/PardonIpCommand.php b/src/command/defaults/PardonIpCommand.php index 191dc036cb..9b2278706b 100644 --- a/src/command/defaults/PardonIpCommand.php +++ b/src/command/defaults/PardonIpCommand.php @@ -37,8 +37,8 @@ class PardonIpCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_UNBAN_IP_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_UNBANIP_USAGE, + KnownTranslationKeys::POCKETMINE_COMMAND_UNBAN_IP_DESCRIPTION, + KnownTranslationKeys::COMMANDS_UNBANIP_USAGE, ["unban-ip"] ); $this->setPermission(DefaultPermissionNames::COMMAND_UNBAN_IP); diff --git a/src/command/defaults/ParticleCommand.php b/src/command/defaults/ParticleCommand.php index 7bb6e098b6..00e052bb7f 100644 --- a/src/command/defaults/ParticleCommand.php +++ b/src/command/defaults/ParticleCommand.php @@ -79,8 +79,8 @@ class ParticleCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_PARTICLE_DESCRIPTION, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_PARTICLE_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_PARTICLE_DESCRIPTION, + KnownTranslationKeys::POCKETMINE_COMMAND_PARTICLE_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_PARTICLE); } diff --git a/src/command/defaults/PluginsCommand.php b/src/command/defaults/PluginsCommand.php index 3666c45435..c0339f52d3 100644 --- a/src/command/defaults/PluginsCommand.php +++ b/src/command/defaults/PluginsCommand.php @@ -40,8 +40,8 @@ class PluginsCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_DESCRIPTION, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_USAGE, + KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_DESCRIPTION, + KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_USAGE, ["pl"] ); $this->setPermission(DefaultPermissionNames::COMMAND_PLUGINS); diff --git a/src/command/defaults/SaveCommand.php b/src/command/defaults/SaveCommand.php index fe07c53a8e..71a3c33f87 100644 --- a/src/command/defaults/SaveCommand.php +++ b/src/command/defaults/SaveCommand.php @@ -36,8 +36,8 @@ class SaveCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_SAVE_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_SAVE_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_SAVE_DESCRIPTION, + KnownTranslationKeys::COMMANDS_SAVE_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_SAVE_PERFORM); } diff --git a/src/command/defaults/SaveOffCommand.php b/src/command/defaults/SaveOffCommand.php index 6d85082496..6d8f8a7e9b 100644 --- a/src/command/defaults/SaveOffCommand.php +++ b/src/command/defaults/SaveOffCommand.php @@ -34,8 +34,8 @@ class SaveOffCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_SAVEOFF_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_SAVE_OFF_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_SAVEOFF_DESCRIPTION, + KnownTranslationKeys::COMMANDS_SAVE_OFF_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_SAVE_DISABLE); } diff --git a/src/command/defaults/SaveOnCommand.php b/src/command/defaults/SaveOnCommand.php index b0d5ebf05c..f57fa55936 100644 --- a/src/command/defaults/SaveOnCommand.php +++ b/src/command/defaults/SaveOnCommand.php @@ -34,8 +34,8 @@ class SaveOnCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_SAVEON_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_SAVE_ON_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_SAVEON_DESCRIPTION, + KnownTranslationKeys::COMMANDS_SAVE_ON_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_SAVE_ENABLE); } diff --git a/src/command/defaults/SayCommand.php b/src/command/defaults/SayCommand.php index 62d9fd2142..a4fd0e0669 100644 --- a/src/command/defaults/SayCommand.php +++ b/src/command/defaults/SayCommand.php @@ -39,8 +39,8 @@ class SayCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_SAY_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_SAY_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_SAY_DESCRIPTION, + KnownTranslationKeys::COMMANDS_SAY_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_SAY); } diff --git a/src/command/defaults/SeedCommand.php b/src/command/defaults/SeedCommand.php index d154ff8916..53f19a19a3 100644 --- a/src/command/defaults/SeedCommand.php +++ b/src/command/defaults/SeedCommand.php @@ -34,8 +34,8 @@ class SeedCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_SEED_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_SEED_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_SEED_DESCRIPTION, + KnownTranslationKeys::COMMANDS_SEED_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_SEED); } diff --git a/src/command/defaults/SetWorldSpawnCommand.php b/src/command/defaults/SetWorldSpawnCommand.php index 2c6f145b14..9b67fa0765 100644 --- a/src/command/defaults/SetWorldSpawnCommand.php +++ b/src/command/defaults/SetWorldSpawnCommand.php @@ -40,8 +40,8 @@ class SetWorldSpawnCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_SETWORLDSPAWN_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_SETWORLDSPAWN_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_SETWORLDSPAWN_DESCRIPTION, + KnownTranslationKeys::COMMANDS_SETWORLDSPAWN_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_SETWORLDSPAWN); } diff --git a/src/command/defaults/SpawnpointCommand.php b/src/command/defaults/SpawnpointCommand.php index 031c64ae4a..6bfea948a0 100644 --- a/src/command/defaults/SpawnpointCommand.php +++ b/src/command/defaults/SpawnpointCommand.php @@ -41,8 +41,8 @@ class SpawnpointCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_SPAWNPOINT_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_SPAWNPOINT_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_SPAWNPOINT_DESCRIPTION, + KnownTranslationKeys::COMMANDS_SPAWNPOINT_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_SPAWNPOINT); } diff --git a/src/command/defaults/StatusCommand.php b/src/command/defaults/StatusCommand.php index 6f5e0133be..7086934237 100644 --- a/src/command/defaults/StatusCommand.php +++ b/src/command/defaults/StatusCommand.php @@ -39,8 +39,8 @@ class StatusCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_STATUS_DESCRIPTION, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_STATUS_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_STATUS_DESCRIPTION, + KnownTranslationKeys::POCKETMINE_COMMAND_STATUS_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_STATUS); } diff --git a/src/command/defaults/StopCommand.php b/src/command/defaults/StopCommand.php index edf2eb7e3c..23a624dd5a 100644 --- a/src/command/defaults/StopCommand.php +++ b/src/command/defaults/StopCommand.php @@ -34,8 +34,8 @@ class StopCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_STOP_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_STOP_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_STOP_DESCRIPTION, + KnownTranslationKeys::COMMANDS_STOP_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_STOP); } diff --git a/src/command/defaults/TeleportCommand.php b/src/command/defaults/TeleportCommand.php index 945036ebf9..17979fec61 100644 --- a/src/command/defaults/TeleportCommand.php +++ b/src/command/defaults/TeleportCommand.php @@ -42,8 +42,8 @@ class TeleportCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_TP_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_TP_USAGE, + KnownTranslationKeys::POCKETMINE_COMMAND_TP_DESCRIPTION, + KnownTranslationKeys::COMMANDS_TP_USAGE, ["teleport"] ); $this->setPermission(DefaultPermissionNames::COMMAND_TELEPORT); diff --git a/src/command/defaults/TellCommand.php b/src/command/defaults/TellCommand.php index 693fae68b6..c7feb644ca 100644 --- a/src/command/defaults/TellCommand.php +++ b/src/command/defaults/TellCommand.php @@ -40,8 +40,8 @@ class TellCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_TELL_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_MESSAGE_USAGE, + KnownTranslationKeys::POCKETMINE_COMMAND_TELL_DESCRIPTION, + KnownTranslationKeys::COMMANDS_MESSAGE_USAGE, ["w", "msg"] ); $this->setPermission(DefaultPermissionNames::COMMAND_TELL); diff --git a/src/command/defaults/TimeCommand.php b/src/command/defaults/TimeCommand.php index 5978b7ec2c..b3b1f397df 100644 --- a/src/command/defaults/TimeCommand.php +++ b/src/command/defaults/TimeCommand.php @@ -39,8 +39,8 @@ class TimeCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_TIME_DESCRIPTION, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_TIME_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_TIME_DESCRIPTION, + KnownTranslationKeys::POCKETMINE_COMMAND_TIME_USAGE ); $this->setPermission(implode(";", [ DefaultPermissionNames::COMMAND_TIME_ADD, diff --git a/src/command/defaults/TimingsCommand.php b/src/command/defaults/TimingsCommand.php index 68350b56a0..cff3f4dd0b 100644 --- a/src/command/defaults/TimingsCommand.php +++ b/src/command/defaults/TimingsCommand.php @@ -60,8 +60,8 @@ class TimingsCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_DESCRIPTION, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_DESCRIPTION, + KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_TIMINGS); } diff --git a/src/command/defaults/TitleCommand.php b/src/command/defaults/TitleCommand.php index 6a96293aea..084949cd37 100644 --- a/src/command/defaults/TitleCommand.php +++ b/src/command/defaults/TitleCommand.php @@ -38,8 +38,8 @@ class TitleCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_TITLE_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_TITLE_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_TITLE_DESCRIPTION, + KnownTranslationKeys::COMMANDS_TITLE_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_TITLE); } diff --git a/src/command/defaults/TransferServerCommand.php b/src/command/defaults/TransferServerCommand.php index 0a64ccfcf3..0190e48ee2 100644 --- a/src/command/defaults/TransferServerCommand.php +++ b/src/command/defaults/TransferServerCommand.php @@ -35,8 +35,8 @@ class TransferServerCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_TRANSFERSERVER_DESCRIPTION, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_TRANSFERSERVER_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_TRANSFERSERVER_DESCRIPTION, + KnownTranslationKeys::POCKETMINE_COMMAND_TRANSFERSERVER_USAGE ); $this->setPermission(DefaultPermissionNames::COMMAND_TRANSFERSERVER); } diff --git a/src/command/defaults/VersionCommand.php b/src/command/defaults/VersionCommand.php index ff69f76273..daecc625f0 100644 --- a/src/command/defaults/VersionCommand.php +++ b/src/command/defaults/VersionCommand.php @@ -46,8 +46,8 @@ class VersionCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_DESCRIPTION, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_USAGE, + KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_DESCRIPTION, + KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_USAGE, ["ver", "about"] ); $this->setPermission(DefaultPermissionNames::COMMAND_VERSION); diff --git a/src/command/defaults/WhitelistCommand.php b/src/command/defaults/WhitelistCommand.php index abe67064f8..458d819e00 100644 --- a/src/command/defaults/WhitelistCommand.php +++ b/src/command/defaults/WhitelistCommand.php @@ -41,8 +41,8 @@ class WhitelistCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - "%" . KnownTranslationKeys::POCKETMINE_COMMAND_WHITELIST_DESCRIPTION, - "%" . KnownTranslationKeys::COMMANDS_WHITELIST_USAGE + KnownTranslationKeys::POCKETMINE_COMMAND_WHITELIST_DESCRIPTION, + KnownTranslationKeys::COMMANDS_WHITELIST_USAGE ); $this->setPermission(implode(";", [ DefaultPermissionNames::COMMAND_WHITELIST_RELOAD, diff --git a/src/network/mcpe/auth/ProcessLoginTask.php b/src/network/mcpe/auth/ProcessLoginTask.php index 0674ba0339..c0e537c646 100644 --- a/src/network/mcpe/auth/ProcessLoginTask.php +++ b/src/network/mcpe/auth/ProcessLoginTask.php @@ -138,11 +138,11 @@ class ProcessLoginTask extends AsyncTask{ if($currentPublicKey === null){ if(!$first){ - throw new VerifyLoginException("%" . KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_MISSINGKEY); + throw new VerifyLoginException(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_MISSINGKEY); } }elseif($headerDerKey !== $currentPublicKey){ //Fast path: if the header key doesn't match what we expected, the signature isn't going to validate anyway - throw new VerifyLoginException("%" . KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_BADSIGNATURE); + throw new VerifyLoginException(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_BADSIGNATURE); } try{ @@ -152,7 +152,7 @@ class ProcessLoginTask extends AsyncTask{ } try{ if(!JwtUtils::verify($jwt, $signingKeyOpenSSL)){ - throw new VerifyLoginException("%" . KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_BADSIGNATURE); + throw new VerifyLoginException(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_BADSIGNATURE); } }catch(JwtException $e){ throw new VerifyLoginException($e->getMessage(), 0, $e); @@ -178,11 +178,11 @@ class ProcessLoginTask extends AsyncTask{ $time = time(); if(isset($claims->nbf) and $claims->nbf > $time + self::CLOCK_DRIFT_MAX){ - throw new VerifyLoginException("%" . KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_TOOEARLY); + throw new VerifyLoginException(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_TOOEARLY); } if(isset($claims->exp) and $claims->exp < $time - self::CLOCK_DRIFT_MAX){ - throw new VerifyLoginException("%" . KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_TOOLATE); + throw new VerifyLoginException(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_TOOLATE); } if(isset($claims->identityPublicKey)){ From a81680c5c613f52a1ae4d99c30514c8433a2d7cc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 15 Aug 2021 20:12:55 +0100 Subject: [PATCH 2710/3224] missed a few more hardcoded translation keys --- src/network/mcpe/NetworkSession.php | 3 ++- src/network/mcpe/handler/LoginPacketHandler.php | 7 ++++--- src/network/mcpe/handler/ResourcePacksPacketHandler.php | 3 ++- src/player/Player.php | 3 ++- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 946fbd92f5..a8c68f8e82 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -34,6 +34,7 @@ use pocketmine\event\server\DataPacketReceiveEvent; use pocketmine\event\server\DataPacketSendEvent; use pocketmine\form\Form; use pocketmine\lang\KnownTranslationFactory; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\StringTag; @@ -590,7 +591,7 @@ class NetworkSession{ if(!$this->authenticated){ if($authRequired){ - $this->disconnect("disconnectionScreen.notAuthenticated"); + $this->disconnect(KnownTranslationKeys::DISCONNECTIONSCREEN_NOTAUTHENTICATED); return; } if($this->info instanceof XboxLivePlayerInfo){ diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index 25532f1721..3ff77e2c43 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\handler; use pocketmine\entity\InvalidSkinException; use pocketmine\event\player\PlayerPreLoginEvent; use pocketmine\lang\KnownTranslationFactory; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\network\mcpe\auth\ProcessLoginTask; use pocketmine\network\mcpe\convert\SkinAdapterSingleton; use pocketmine\network\mcpe\JwtException; @@ -93,7 +94,7 @@ class LoginPacketHandler extends PacketHandler{ $extraData = $this->fetchAuthData($packet->chainDataJwt); if(!Player::isValidUserName($extraData->displayName)){ - $this->session->disconnect("disconnectionScreen.invalidName"); + $this->session->disconnect(KnownTranslationKeys::DISCONNECTIONSCREEN_INVALIDNAME); return true; } @@ -103,7 +104,7 @@ class LoginPacketHandler extends PacketHandler{ $skin = SkinAdapterSingleton::get()->fromSkinData(ClientDataToSkinDataHelper::fromClientData($clientData)); }catch(\InvalidArgumentException | InvalidSkinException $e){ $this->session->getLogger()->debug("Invalid skin: " . $e->getMessage()); - $this->session->disconnect("disconnectionScreen.invalidSkin"); + $this->session->disconnect(KnownTranslationKeys::DISCONNECTIONSCREEN_INVALIDSKIN); return true; } @@ -139,7 +140,7 @@ class LoginPacketHandler extends PacketHandler{ $this->server->requiresAuthentication() ); if($this->server->getNetwork()->getConnectionCount() > $this->server->getMaxPlayers()){ - $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_SERVER_FULL, "disconnectionScreen.serverFull"); + $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_SERVER_FULL, KnownTranslationKeys::DISCONNECTIONSCREEN_SERVERFULL); } if(!$this->server->isWhitelisted($playerInfo->getUsername())){ $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_SERVER_WHITELISTED, "Server is whitelisted"); diff --git a/src/network/mcpe/handler/ResourcePacksPacketHandler.php b/src/network/mcpe/handler/ResourcePacksPacketHandler.php index 23676b436e..5b6d1d7a58 100644 --- a/src/network/mcpe/handler/ResourcePacksPacketHandler.php +++ b/src/network/mcpe/handler/ResourcePacksPacketHandler.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\ResourcePackChunkDataPacket; use pocketmine\network\mcpe\protocol\ResourcePackChunkRequestPacket; @@ -83,7 +84,7 @@ class ResourcePacksPacketHandler extends PacketHandler{ private function disconnectWithError(string $error) : void{ $this->session->getLogger()->error("Error downloading resource packs: " . $error); - $this->session->disconnect("disconnectionScreen.resourcePack"); + $this->session->disconnect(KnownTranslationKeys::DISCONNECTIONSCREEN_RESOURCEPACK); } public function handleResourcePackClientResponse(ResourcePackClientResponsePacket $packet) : bool{ diff --git a/src/player/Player.php b/src/player/Player.php index 174d833a31..7ecb53b4f0 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -81,6 +81,7 @@ use pocketmine\item\Item; use pocketmine\item\ItemUseResult; use pocketmine\item\Releasable; use pocketmine\lang\KnownTranslationFactory; +use pocketmine\lang\KnownTranslationKeys; use pocketmine\lang\Language; use pocketmine\lang\Translatable; use pocketmine\math\Vector3; @@ -1879,7 +1880,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ if(!$ev->isCancelled()){ $reason = $ev->getReason(); if($reason === ""){ - $reason = "disconnectionScreen.noReason"; + $reason = KnownTranslationKeys::DISCONNECTIONSCREEN_NOREASON; } $this->disconnect($reason, $ev->getQuitMessage()); From 5da90b9530c4100cd7c3971675faea74f27b5438 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 15 Aug 2021 20:44:27 +0100 Subject: [PATCH 2711/3224] Stop auto-translating strings when not asked fixes #4371 --- src/console/ConsoleCommandSender.php | 2 -- src/lang/Language.php | 4 ++-- src/network/mcpe/NetworkSession.php | 2 +- src/player/Player.php | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/console/ConsoleCommandSender.php b/src/console/ConsoleCommandSender.php index 3d2feb762b..45ae2f5ab3 100644 --- a/src/console/ConsoleCommandSender.php +++ b/src/console/ConsoleCommandSender.php @@ -62,8 +62,6 @@ class ConsoleCommandSender implements CommandSender{ $server = $this->getServer(); if($message instanceof Translatable){ $message = $this->getLanguage()->translate($message); - }else{ - $message = $this->getLanguage()->translateString($message); } foreach(explode("\n", trim($message)) as $line){ diff --git a/src/lang/Language.php b/src/lang/Language.php index ea8171dfd5..f3e9667049 100644 --- a/src/lang/Language.php +++ b/src/lang/Language.php @@ -137,7 +137,7 @@ class Language{ $baseText = $this->parseTranslation(($onlyPrefix === null or strpos($str, $onlyPrefix) === 0) ? $baseText : $str, $onlyPrefix); foreach($params as $i => $p){ - $replacement = $p instanceof Translatable ? $this->translate($p) : $this->internalGet((string) $p) ?? $this->parseTranslation((string) $p); + $replacement = $p instanceof Translatable ? $this->translate($p) : (string) $p; $baseText = str_replace("{%$i}", $replacement, $baseText); } @@ -149,7 +149,7 @@ class Language{ $baseText = $this->parseTranslation($baseText ?? $c->getText()); foreach($c->getParameters() as $i => $p){ - $replacement = $p instanceof Translatable ? $this->translate($p) : $this->internalGet($p) ?? $this->parseTranslation($p); + $replacement = $p instanceof Translatable ? $this->translate($p) : $p; $baseText = str_replace("{%$i}", $replacement, $baseText); } diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index a8c68f8e82..4683c2c728 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -582,7 +582,7 @@ class NetworkSession{ } if($error !== null){ - $this->disconnect($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_disconnect_invalidSession($error))); + $this->disconnect($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_disconnect_invalidSession($this->server->getLanguage()->translateString($error)))); return; } diff --git a/src/player/Player.php b/src/player/Player.php index 7ecb53b4f0..9b102396a1 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1779,7 +1779,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return; } - $this->getNetworkSession()->onRawChatMessage($this->getLanguage()->translateString($message)); + $this->getNetworkSession()->onRawChatMessage($message); } /** From a012e7ccc017ec8a1768b6976ac9685318551613 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 16 Aug 2021 16:37:36 +0100 Subject: [PATCH 2712/3224] VersionInfo: make static methods more constant-like if we could have class constants declared at runtime, these would be constant. --- build/make-release.php | 2 +- src/CrashDump.php | 6 +++--- src/PocketMine.php | 2 +- src/Server.php | 4 ++-- src/VersionInfo.php | 4 ++-- src/command/defaults/VersionCommand.php | 4 ++-- src/network/mcpe/handler/PreSpawnPacketHandler.php | 2 +- src/stats/SendUsageTask.php | 2 +- src/updater/AutoUpdater.php | 2 +- src/utils/Internet.php | 2 +- 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/build/make-release.php b/build/make-release.php index ff669f3934..aa31f8097f 100644 --- a/build/make-release.php +++ b/build/make-release.php @@ -60,7 +60,7 @@ function main(array $argv) : void{ if(isset($argv[1])){ $currentVer = new VersionString($argv[1]); }else{ - $currentVer = VersionInfo::getVersionObj(); + $currentVer = VersionInfo::VERSION(); } $nextVer = new VersionString(sprintf( "%u.%u.%u", diff --git a/src/CrashDump.php b/src/CrashDump.php index e6f72de5f7..983ecd4a89 100644 --- a/src/CrashDump.php +++ b/src/CrashDump.php @@ -328,7 +328,7 @@ class CrashDump{ } private function generalData() : void{ - $version = VersionInfo::getVersionObj(); + $version = VersionInfo::VERSION(); $composerLibraries = []; foreach(InstalledVersions::getInstalledPackages() as $package){ $composerLibraries[$package] = sprintf( @@ -344,7 +344,7 @@ class CrashDump{ $this->data["general"]["build"] = VersionInfo::BUILD_NUMBER; $this->data["general"]["is_dev"] = VersionInfo::IS_DEVELOPMENT_BUILD; $this->data["general"]["protocol"] = ProtocolInfo::CURRENT_PROTOCOL; - $this->data["general"]["git"] = VersionInfo::getGitHash(); + $this->data["general"]["git"] = VersionInfo::GIT_HASH(); $this->data["general"]["uname"] = php_uname("a"); $this->data["general"]["php"] = phpversion(); $this->data["general"]["zend"] = zend_version(); @@ -352,7 +352,7 @@ class CrashDump{ $this->data["general"]["os"] = Utils::getOS(); $this->data["general"]["composer_libraries"] = $composerLibraries; $this->addLine($this->server->getName() . " version: " . $version->getFullVersion(true) . " [Protocol " . ProtocolInfo::CURRENT_PROTOCOL . "]"); - $this->addLine("Git commit: " . VersionInfo::getGitHash()); + $this->addLine("Git commit: " . VersionInfo::GIT_HASH()); $this->addLine("uname -a: " . php_uname("a")); $this->addLine("PHP Version: " . phpversion()); $this->addLine("Zend version: " . zend_version()); diff --git a/src/PocketMine.php b/src/PocketMine.php index c96cd8060d..f345cacf95 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -229,7 +229,7 @@ JIT_WARNING $composerGitHash = InstalledVersions::getReference('pocketmine/pocketmine-mp'); if($composerGitHash !== null){ //we can't verify dependency versions if we were installed without using git - $currentGitHash = explode("-", VersionInfo::getGitHash())[0]; + $currentGitHash = explode("-", VersionInfo::GIT_HASH())[0]; if($currentGitHash !== $composerGitHash){ critical_error("Composer dependencies and/or autoloader are out of sync."); critical_error("- Current revision is $currentGitHash"); diff --git a/src/Server.php b/src/Server.php index 6f243532a6..d290ebdaa3 100644 --- a/src/Server.php +++ b/src/Server.php @@ -260,7 +260,7 @@ class Server{ } public function getPocketMineVersion() : string{ - return VersionInfo::getVersionObj()->getFullVersion(true); + return VersionInfo::VERSION()->getFullVersion(true); } public function getVersion() : string{ @@ -1452,7 +1452,7 @@ class Server{ $report = false; } - if(strrpos(VersionInfo::getGitHash(), "-dirty") !== false or VersionInfo::getGitHash() === str_repeat("00", 20)){ + if(strrpos(VersionInfo::GIT_HASH(), "-dirty") !== false or VersionInfo::GIT_HASH() === str_repeat("00", 20)){ $this->logger->debug("Not sending crashdump due to locally modified"); $report = false; //Don't send crashdumps for locally modified builds } diff --git a/src/VersionInfo.php b/src/VersionInfo.php index e4daaf30f1..3b74e3708e 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -40,7 +40,7 @@ final class VersionInfo{ /** @var string|null */ private static $gitHash = null; - public static function getGitHash() : string{ + public static function GIT_HASH() : string{ if(self::$gitHash === null){ $gitHash = str_repeat("00", 20); @@ -63,7 +63,7 @@ final class VersionInfo{ /** @var VersionString|null */ private static $fullVersion = null; - public static function getVersionObj() : VersionString{ + public static function VERSION() : VersionString{ if(self::$fullVersion === null){ self::$fullVersion = new VersionString(self::BASE_VERSION, self::IS_DEVELOPMENT_BUILD, self::BUILD_NUMBER); } diff --git a/src/command/defaults/VersionCommand.php b/src/command/defaults/VersionCommand.php index daecc625f0..17e4c858ca 100644 --- a/src/command/defaults/VersionCommand.php +++ b/src/command/defaults/VersionCommand.php @@ -63,8 +63,8 @@ class VersionCommand extends VanillaCommand{ VersionInfo::NAME )); $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_serverSoftwareVersion( - VersionInfo::getVersionObj()->getFullVersion(), - VersionInfo::getGitHash() + VersionInfo::VERSION()->getFullVersion(), + VersionInfo::GIT_HASH() )); $sender->sendMessage(KnownTranslationFactory::pocketmine_command_version_minecraftVersion( ProtocolInfo::MINECRAFT_VERSION_NETWORK, diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index 82996ac66a..59d204d68f 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -95,7 +95,7 @@ class PreSpawnPacketHandler extends PacketHandler{ $pk->worldName = $this->server->getMotd(); $pk->itemTable = GlobalItemTypeDictionary::getInstance()->getDictionary()->getEntries(); //TODO: check if this is actually needed $pk->playerMovementSettings = new PlayerMovementSettings(PlayerMovementType::LEGACY, 0, false); - $pk->serverSoftwareVersion = sprintf("%s %s", VersionInfo::NAME, VersionInfo::getVersionObj()->getFullVersion(true)); + $pk->serverSoftwareVersion = sprintf("%s %s", VersionInfo::NAME, VersionInfo::VERSION()->getFullVersion(true)); $this->session->sendDataPacket($pk); $this->session->sendDataPacket(StaticPacketCache::getInstance()->getAvailableActorIdentifiers()); diff --git a/src/stats/SendUsageTask.php b/src/stats/SendUsageTask.php index 7516797326..d108ca94a7 100644 --- a/src/stats/SendUsageTask.php +++ b/src/stats/SendUsageTask.php @@ -71,7 +71,7 @@ class SendUsageTask extends AsyncTask{ case self::TYPE_OPEN: $data["event"] = "open"; - $version = VersionInfo::getVersionObj(); + $version = VersionInfo::VERSION(); $data["server"] = [ "port" => $server->getPort(), diff --git a/src/updater/AutoUpdater.php b/src/updater/AutoUpdater.php index b20db07671..61b2aa7a3c 100644 --- a/src/updater/AutoUpdater.php +++ b/src/updater/AutoUpdater.php @@ -150,7 +150,7 @@ class AutoUpdater{ if($this->updateInfo === null){ return; } - $currentVersion = VersionInfo::getVersionObj(); + $currentVersion = VersionInfo::VERSION(); try{ $newVersion = new VersionString($this->updateInfo->base_version, $this->updateInfo->is_dev, $this->updateInfo->build); }catch(\InvalidArgumentException $e){ diff --git a/src/utils/Internet.php b/src/utils/Internet.php index d7f602cb6e..36dc96fc24 100644 --- a/src/utils/Internet.php +++ b/src/utils/Internet.php @@ -209,7 +209,7 @@ class Internet{ CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT_MS => (int) ($timeout * 1000), CURLOPT_TIMEOUT_MS => (int) ($timeout * 1000), - CURLOPT_HTTPHEADER => array_merge(["User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0 " . VersionInfo::NAME . "/" . VersionInfo::getVersionObj()->getFullVersion(true)], $extraHeaders), + CURLOPT_HTTPHEADER => array_merge(["User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0 " . VersionInfo::NAME . "/" . VersionInfo::VERSION()->getFullVersion(true)], $extraHeaders), CURLOPT_HEADER => true ]); try{ From b3298d7c77520e39d83da9d6b69f1438407b586c Mon Sep 17 00:00:00 2001 From: marshall Date: Tue, 17 Aug 2021 02:06:30 +0800 Subject: [PATCH 2713/3224] Fix Skull->asItem() (#4375) --- src/block/BlockFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 98249adf8a..b4a82575be 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -322,7 +322,7 @@ class BlockFactory{ $this->register(new Sand(new BID(Ids::SAND, 1), "Red Sand", $sandBreakInfo)); $this->register(new SeaLantern(new BID(Ids::SEALANTERN, 0), "Sea Lantern", new BlockBreakInfo(0.3))); $this->register(new SeaPickle(new BID(Ids::SEA_PICKLE, 0), "Sea Pickle", BlockBreakInfo::instant())); - $this->register(new Skull(new BID(Ids::MOB_HEAD_BLOCK, 0, null, TileSkull::class), "Mob Head", new BlockBreakInfo(1.0))); + $this->register(new Skull(new BID(Ids::MOB_HEAD_BLOCK, 0, ItemIds::SKULL, TileSkull::class), "Mob Head", new BlockBreakInfo(1.0))); $this->register(new Snow(new BID(Ids::SNOW, 0), "Snow Block", new BlockBreakInfo(0.2, BlockToolType::SHOVEL, ToolTier::WOOD()->getHarvestLevel()))); $this->register(new SnowLayer(new BID(Ids::SNOW_LAYER, 0), "Snow Layer", new BlockBreakInfo(0.1, BlockToolType::SHOVEL, ToolTier::WOOD()->getHarvestLevel()))); From 83805a340690edf39e00f1d6218213f188186a9d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 17 Aug 2021 20:44:33 +0100 Subject: [PATCH 2714/3224] Entity: use match in checkObstruction() --- src/entity/Entity.php | 48 ++++++++++++------------------------------- 1 file changed, 13 insertions(+), 35 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index d123fd4464..040fa06c38 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -868,43 +868,21 @@ abstract class Entity{ $direction = Facing::SOUTH; } + if($direction === -1){ + return false; + } + $force = lcg_value() * 0.2 + 0.1; - if($direction === Facing::WEST){ - $this->motion = $this->motion->withComponents(-$force, null, null); - - return true; - } - - if($direction === Facing::EAST){ - $this->motion = $this->motion->withComponents($force, null, null); - - return true; - } - - if($direction === Facing::DOWN){ - $this->motion = $this->motion->withComponents(null, -$force, null); - - return true; - } - - if($direction === Facing::UP){ - $this->motion = $this->motion->withComponents(null, $force, null); - - return true; - } - - if($direction === Facing::NORTH){ - $this->motion = $this->motion->withComponents(null, null, -$force); - - return true; - } - - if($direction === Facing::SOUTH){ - $this->motion = $this->motion->withComponents(null, null, $force); - - return true; - } + $this->motion = match($direction){ + Facing::WEST => $this->motion->withComponents(-$force, null, null), + Facing::EAST => $this->motion->withComponents($force, null, null), + Facing::DOWN => $this->motion->withComponents(null, -$force, null), + Facing::UP => $this->motion->withComponents(null, $force, null), + Facing::NORTH => $this->motion->withComponents(null, null, -$force), + Facing::SOUTH => $this->motion->withComponents(null, null, $force), + }; + return true; } return false; From a5b85e095abfc8db5032f5bb798bab953dbff893 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 19 Aug 2021 15:40:43 +0100 Subject: [PATCH 2715/3224] Fixed some missing function imports these weren't getting corrected since php-cs-fixer 3.0 due to a change in the default configuration for native_function_invocation. Since the builds are randomly choosing to use php-cs-fixer 2.19 at the moment, the consistency is a problem. --- build/generate-known-translation-apis.php | 2 ++ src/console/ConsoleReaderChildProcess.php | 1 + 2 files changed, 3 insertions(+) diff --git a/build/generate-known-translation-apis.php b/build/generate-known-translation-apis.php index 2772b3f4a4..04dbe37a6e 100644 --- a/build/generate-known-translation-apis.php +++ b/build/generate-known-translation-apis.php @@ -32,9 +32,11 @@ use function file_put_contents; use function fwrite; use function implode; use function is_numeric; +use function ksort; use function ob_get_clean; use function ob_start; use function parse_ini_file; +use function preg_match_all; use function str_replace; use function strtoupper; use const INI_SCANNER_RAW; diff --git a/src/console/ConsoleReaderChildProcess.php b/src/console/ConsoleReaderChildProcess.php index 5bb05a818b..3879ecdff8 100644 --- a/src/console/ConsoleReaderChildProcess.php +++ b/src/console/ConsoleReaderChildProcess.php @@ -26,6 +26,7 @@ namespace pocketmine\console; use function cli_set_process_title; use function count; use function dirname; +use function feof; use function fwrite; use function stream_socket_client; From bf8b5905e4a02c6267d06ec26d3b1db26f96c680 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 19 Aug 2021 15:56:40 +0100 Subject: [PATCH 2716/3224] Player: Play ItemBreakSounds when items break due to usage closes #4381 --- src/player/Player.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/player/Player.php b/src/player/Player.php index e5c5046c5a..41b57be804 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -75,6 +75,7 @@ use pocketmine\form\FormValidationException; use pocketmine\inventory\Inventory; use pocketmine\inventory\PlayerCursorInventory; use pocketmine\item\ConsumableItem; +use pocketmine\item\Durable; use pocketmine\item\enchantment\EnchantmentInstance; use pocketmine\item\enchantment\MeleeWeaponEnchantment; use pocketmine\item\Item; @@ -110,6 +111,7 @@ use pocketmine\world\Position; use pocketmine\world\sound\EntityAttackNoDamageSound; use pocketmine\world\sound\EntityAttackSound; use pocketmine\world\sound\FireExtinguishSound; +use pocketmine\world\sound\ItemBreakSound; use pocketmine\world\sound\Sound; use pocketmine\world\World; use Ramsey\Uuid\UuidInterface; @@ -1380,6 +1382,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->resetItemCooldown($item); if($this->hasFiniteResources() and !$item->equalsExact($oldItem) and $oldItem->equalsExact($this->inventory->getItemInHand())){ + if($item instanceof Durable && $item->isBroken()){ + $this->broadcastSound(new ItemBreakSound()); + } $this->inventory->setItemInHand($item); } @@ -1441,6 +1446,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ if($result->equals(ItemUseResult::SUCCESS())){ $this->resetItemCooldown($item); if(!$item->equalsExact($oldItem) and $oldItem->equalsExact($this->inventory->getItemInHand())){ + if($item instanceof Durable && $item->isBroken()){ + $this->broadcastSound(new ItemBreakSound()); + } $this->inventory->setItemInHand($item); } return true; @@ -1558,6 +1566,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $oldItem = clone $item; if($this->getWorld()->useBreakOn($pos, $item, $this, true)){ if($this->hasFiniteResources() and !$item->equalsExact($oldItem) and $oldItem->equalsExact($this->inventory->getItemInHand())){ + if($item instanceof Durable && $item->isBroken()){ + $this->broadcastSound(new ItemBreakSound()); + } $this->inventory->setItemInHand($item); } $this->hungerManager->exhaust(0.025, PlayerExhaustEvent::CAUSE_MINING); @@ -1582,6 +1593,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $oldItem = clone $item; if($this->getWorld()->useItemOn($pos, $item, $face, $clickOffset, $this, true)){ if($this->hasFiniteResources() and !$item->equalsExact($oldItem) and $oldItem->equalsExact($this->inventory->getItemInHand())){ + if($item instanceof Durable && $item->isBroken()){ + $this->broadcastSound(new ItemBreakSound()); + } $this->inventory->setItemInHand($item); } return true; @@ -1654,6 +1668,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ //reactive damage like thorns might cause us to be killed by attacking another mob, which //would mean we'd already have dropped the inventory by the time we reached here if($heldItem->onAttackEntity($entity) and $this->hasFiniteResources() and $oldItem->equalsExact($this->inventory->getItemInHand())){ //always fire the hook, even if we are survival + if($heldItem instanceof Durable && $heldItem->isBroken()){ + $this->broadcastSound(new ItemBreakSound()); + } $this->inventory->setItemInHand($heldItem); } From 7ba34927c98c3726ca941a7199896f5c78ab6a56 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 19 Aug 2021 15:57:53 +0100 Subject: [PATCH 2717/3224] Update UpdateInfo JSON model to be compatible with new updater API --- src/updater/UpdateInfo.php | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/updater/UpdateInfo.php b/src/updater/UpdateInfo.php index 2b0d1eb4c9..2da98819c2 100644 --- a/src/updater/UpdateInfo.php +++ b/src/updater/UpdateInfo.php @@ -28,11 +28,6 @@ namespace pocketmine\updater; * @link https://update.pmmp.io/api */ final class UpdateInfo{ - /** - * @var string - * @required - */ - public $job; /** * @var string * @required @@ -43,21 +38,13 @@ final class UpdateInfo{ * @required */ public $base_version; - /** - * @var int - * @required - */ - public $build_number; /** * @var bool * @required */ public $is_dev; - /** - * @var string - * @required - */ - public $branch; + /** @required */ + public string $channel; /** * @var string * @required @@ -68,11 +55,6 @@ final class UpdateInfo{ * @required */ public $mcpe_version; - /** - * @var string - * @required - */ - public $phar_name; /** * @var int * @required @@ -93,4 +75,6 @@ final class UpdateInfo{ * @required */ public $download_url; + /** @required */ + public string $source_url; } From 5478b7cb63d4266edec40f5484a6ad7470932fda Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 19 Aug 2021 16:07:11 +0100 Subject: [PATCH 2718/3224] UpdateInfo: use typed properties --- src/updater/UpdateInfo.php | 63 +++++++++++--------------------------- 1 file changed, 18 insertions(+), 45 deletions(-) diff --git a/src/updater/UpdateInfo.php b/src/updater/UpdateInfo.php index 2da98819c2..ebbc393d0b 100644 --- a/src/updater/UpdateInfo.php +++ b/src/updater/UpdateInfo.php @@ -28,53 +28,26 @@ namespace pocketmine\updater; * @link https://update.pmmp.io/api */ final class UpdateInfo{ - /** - * @var string - * @required - */ - public $php_version; - /** - * @var string - * @required - */ - public $base_version; - /** - * @var bool - * @required - */ - public $is_dev; + /** @required */ + public string $php_version; + /** @required */ + public string $base_version; + /** @required */ + public bool $is_dev; /** @required */ public string $channel; - /** - * @var string - * @required - */ - public $git_commit; - /** - * @var string - * @required - */ - public $mcpe_version; - /** - * @var int - * @required - */ - public $build; - /** - * @var int - * @required - */ - public $date; - /** - * @var string - * @required - */ - public $details_url; - /** - * @var string - * @required - */ - public $download_url; + /** @required */ + public string $git_commit; + /** @required */ + public string $mcpe_version; + /** @required */ + public int $build; + /** @required */ + public int $date; + /** @required */ + public string $details_url; + /** @required */ + public string $download_url; /** @required */ public string $source_url; } From 17c7e25346db697400633f0ff92cd64e961b7497 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 19 Aug 2021 16:12:04 +0100 Subject: [PATCH 2719/3224] resourcepacks: use typed properties in JSON models --- src/resourcepacks/json/Manifest.php | 19 +++++----------- src/resourcepacks/json/ManifestHeader.php | 22 +++++++------------ src/resourcepacks/json/ManifestMetadata.php | 10 ++++----- .../json/ManifestModuleEntry.php | 21 +++++------------- 4 files changed, 25 insertions(+), 47 deletions(-) diff --git a/src/resourcepacks/json/Manifest.php b/src/resourcepacks/json/Manifest.php index 94521c1f59..31c68973eb 100644 --- a/src/resourcepacks/json/Manifest.php +++ b/src/resourcepacks/json/Manifest.php @@ -27,24 +27,17 @@ namespace pocketmine\resourcepacks\json; * Model for JsonMapper to represent resource pack manifest.json contents. */ final class Manifest{ - /** - * @var int - * @required - */ - public $format_version; + /** @required */ + public int $format_version; - /** - * @var ManifestHeader - * @required - */ - public $header; + /** @required */ + public ManifestHeader $header; /** * @var ManifestModuleEntry[] * @required */ - public $modules; + public array $modules; - /** @var ManifestMetadata|null */ - public $metadata = null; + public ?ManifestMetadata $metadata = null; } diff --git a/src/resourcepacks/json/ManifestHeader.php b/src/resourcepacks/json/ManifestHeader.php index 92f5aa7bce..60568a4db9 100644 --- a/src/resourcepacks/json/ManifestHeader.php +++ b/src/resourcepacks/json/ManifestHeader.php @@ -24,31 +24,25 @@ declare(strict_types=1); namespace pocketmine\resourcepacks\json; final class ManifestHeader{ - /** @var string */ - public $description; - /** - * @var string - * @required - */ - public $name; + public string $description; - /** - * @var string - * @required - */ - public $uuid; + /** @required */ + public string $name; + + /** @required */ + public string $uuid; /** * @var int[] * @phpstan-var array{int, int, int} * @required */ - public $version; + public array $version; /** * @var int[] * @phpstan-var array{int, int, int} */ - public $min_engine_version; + public array $min_engine_version; } diff --git a/src/resourcepacks/json/ManifestMetadata.php b/src/resourcepacks/json/ManifestMetadata.php index 5eb0c99960..d44c42167c 100644 --- a/src/resourcepacks/json/ManifestMetadata.php +++ b/src/resourcepacks/json/ManifestMetadata.php @@ -25,9 +25,9 @@ namespace pocketmine\resourcepacks\json; final class ManifestMetadata{ /** @var string[]|null */ - public $authors = null; - /** @var string|null */ - public $license = null; - /** @var string|null */ - public $url = null; + public ?array $authors = null; + + public ?string $license = null; + + public ?string $url = null; } diff --git a/src/resourcepacks/json/ManifestModuleEntry.php b/src/resourcepacks/json/ManifestModuleEntry.php index 26bb129c59..a97623b05a 100644 --- a/src/resourcepacks/json/ManifestModuleEntry.php +++ b/src/resourcepacks/json/ManifestModuleEntry.php @@ -25,27 +25,18 @@ namespace pocketmine\resourcepacks\json; final class ManifestModuleEntry{ - /** - * @var string - */ - public $description; + public string $description; - /** - * @var string - * @required - */ - public $type; + /** @required */ + public string $type; - /** - * @var string - * @required - */ - public $uuid; + /** @required */ + public string $uuid; /** * @var int[] * @phpstan-var array{int, int, int} * @required */ - public $version; + public array $version; } From d488c25a1aba68b9e75545016af7179fa980860b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 20 Aug 2021 19:54:08 +0100 Subject: [PATCH 2720/3224] Rename AutoUpdater -> UpdateChecker --- src/Server.php | 8 ++++---- src/event/server/UpdateNotifyEvent.php | 8 ++++---- src/updater/UpdateCheckTask.php | 4 ++-- src/updater/{AutoUpdater.php => UpdateChecker.php} | 6 +++--- tests/phpstan/configs/l8-baseline.neon | 8 ++++---- 5 files changed, 17 insertions(+), 17 deletions(-) rename src/updater/{AutoUpdater.php => UpdateChecker.php} (97%) diff --git a/src/Server.php b/src/Server.php index d290ebdaa3..e2e1c17481 100644 --- a/src/Server.php +++ b/src/Server.php @@ -87,7 +87,7 @@ use pocketmine\snooze\SleeperNotifier; use pocketmine\stats\SendUsageTask; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; -use pocketmine\updater\AutoUpdater; +use pocketmine\updater\UpdateChecker; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Config; use pocketmine\utils\Filesystem; @@ -183,7 +183,7 @@ class Server{ private float $profilingTickRate = 20; - private AutoUpdater $updater; + private UpdateChecker $updater; private AsyncPool $asyncPool; @@ -365,7 +365,7 @@ class Server{ return $this->logger; } - public function getUpdater() : AutoUpdater{ + public function getUpdater() : UpdateChecker{ return $this->updater; } @@ -951,7 +951,7 @@ class Server{ $this->worldManager->setAutoSave($this->configGroup->getConfigBool("auto-save", $this->worldManager->getAutoSave())); $this->worldManager->setAutoSaveInterval($this->configGroup->getPropertyInt("ticks-per.autosave", 6000)); - $this->updater = new AutoUpdater($this, $this->configGroup->getPropertyString("auto-updater.host", "update.pmmp.io")); + $this->updater = new UpdateChecker($this, $this->configGroup->getPropertyString("auto-updater.host", "update.pmmp.io")); $this->queryInfo = new QueryInfo($this); diff --git a/src/event/server/UpdateNotifyEvent.php b/src/event/server/UpdateNotifyEvent.php index c52b8a637d..843b2c60e8 100644 --- a/src/event/server/UpdateNotifyEvent.php +++ b/src/event/server/UpdateNotifyEvent.php @@ -23,21 +23,21 @@ declare(strict_types=1); namespace pocketmine\event\server; -use pocketmine\updater\AutoUpdater; +use pocketmine\updater\UpdateChecker; /** * Called when the AutoUpdater receives notification of an available PocketMine-MP update. * Plugins may use this event to perform actions when an update notification is received. */ class UpdateNotifyEvent extends ServerEvent{ - /** @var AutoUpdater */ + /** @var UpdateChecker */ private $updater; - public function __construct(AutoUpdater $updater){ + public function __construct(UpdateChecker $updater){ $this->updater = $updater; } - public function getUpdater() : AutoUpdater{ + public function getUpdater() : UpdateChecker{ return $this->updater; } } diff --git a/src/updater/UpdateCheckTask.php b/src/updater/UpdateCheckTask.php index 67b5a49e71..6b571b2fed 100644 --- a/src/updater/UpdateCheckTask.php +++ b/src/updater/UpdateCheckTask.php @@ -39,7 +39,7 @@ class UpdateCheckTask extends AsyncTask{ /** @var string */ private $error = "Unknown error"; - public function __construct(AutoUpdater $updater, string $endpoint, string $channel){ + public function __construct(UpdateChecker $updater, string $endpoint, string $channel){ $this->storeLocal(self::TLS_KEY_UPDATER, $updater); $this->endpoint = $endpoint; $this->channel = $channel; @@ -74,7 +74,7 @@ class UpdateCheckTask extends AsyncTask{ } public function onCompletion() : void{ - /** @var AutoUpdater $updater */ + /** @var UpdateChecker $updater */ $updater = $this->fetchLocal(self::TLS_KEY_UPDATER); if($this->hasResult()){ /** @var UpdateInfo $response */ diff --git a/src/updater/AutoUpdater.php b/src/updater/UpdateChecker.php similarity index 97% rename from src/updater/AutoUpdater.php rename to src/updater/UpdateChecker.php index 61b2aa7a3c..f479a95a58 100644 --- a/src/updater/AutoUpdater.php +++ b/src/updater/UpdateChecker.php @@ -34,7 +34,7 @@ use function strlen; use function strtolower; use function ucfirst; -class AutoUpdater{ +class UpdateChecker{ /** @var Server */ protected $server; @@ -50,7 +50,7 @@ class AutoUpdater{ public function __construct(Server $server, string $endpoint){ $this->server = $server; - $this->logger = new \PrefixedLogger($server->getLogger(), "Auto Updater"); + $this->logger = new \PrefixedLogger($server->getLogger(), "Update Checker"); $this->endpoint = "http://$endpoint/api/"; if($server->getConfigGroup()->getPropertyBool("auto-updater.enabled", true)){ @@ -121,7 +121,7 @@ class AutoUpdater{ * @param string[] $lines */ protected function printConsoleMessage(array $lines, string $logLevel = \LogLevel::INFO) : void{ - $title = $this->server->getName() . ' Auto Updater'; + $title = $this->server->getName() . ' Update Checker'; $this->logger->log($logLevel, sprintf('----- %s -----', $title)); foreach($lines as $line){ $this->logger->log($logLevel, $line); diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 9445fac52c..e72b8cf11b 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -248,22 +248,22 @@ parameters: - message: "#^Cannot access property \\$date on pocketmine\\\\updater\\\\UpdateInfo\\|null\\.$#" count: 1 - path: ../../../src/updater/AutoUpdater.php + path: ../../../src/updater/UpdateChecker.php - message: "#^Cannot access property \\$details_url on pocketmine\\\\updater\\\\UpdateInfo\\|null\\.$#" count: 1 - path: ../../../src/updater/AutoUpdater.php + path: ../../../src/updater/UpdateChecker.php - message: "#^Cannot access property \\$download_url on pocketmine\\\\updater\\\\UpdateInfo\\|null\\.$#" count: 1 - path: ../../../src/updater/AutoUpdater.php + path: ../../../src/updater/UpdateChecker.php - message: "#^Cannot call method getFullVersion\\(\\) on pocketmine\\\\utils\\\\VersionString\\|null\\.$#" count: 1 - path: ../../../src/updater/AutoUpdater.php + path: ../../../src/updater/UpdateChecker.php - message: "#^Method pocketmine\\\\utils\\\\Config\\:\\:fixYAMLIndexes\\(\\) should return string but returns string\\|null\\.$#" From 950dadab0c6f2c6dc0783b8807b7af4a178b657d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 20 Aug 2021 19:56:55 +0100 Subject: [PATCH 2721/3224] UpdateChecker: be less noisy we already have a log prefix, so there's no need for this spam as well. --- src/updater/UpdateChecker.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/updater/UpdateChecker.php b/src/updater/UpdateChecker.php index f479a95a58..83ffce9404 100644 --- a/src/updater/UpdateChecker.php +++ b/src/updater/UpdateChecker.php @@ -28,9 +28,6 @@ use pocketmine\Server; use pocketmine\utils\VersionString; use pocketmine\VersionInfo; use function date; -use function sprintf; -use function str_repeat; -use function strlen; use function strtolower; use function ucfirst; @@ -121,12 +118,9 @@ class UpdateChecker{ * @param string[] $lines */ protected function printConsoleMessage(array $lines, string $logLevel = \LogLevel::INFO) : void{ - $title = $this->server->getName() . ' Update Checker'; - $this->logger->log($logLevel, sprintf('----- %s -----', $title)); foreach($lines as $line){ $this->logger->log($logLevel, $line); } - $this->logger->log($logLevel, sprintf('----- %s -----', str_repeat('-', strlen($title)))); } /** From e113981750878a54ef24637c9c0e45d696edaaa1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 20 Aug 2021 19:59:55 +0100 Subject: [PATCH 2722/3224] UpdateChecker: be less wordy --- src/updater/UpdateChecker.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/updater/UpdateChecker.php b/src/updater/UpdateChecker.php index 83ffce9404..5f8332586a 100644 --- a/src/updater/UpdateChecker.php +++ b/src/updater/UpdateChecker.php @@ -102,15 +102,15 @@ class UpdateChecker{ protected function showChannelSuggestionStable() : void{ $this->printConsoleMessage([ - "It appears you're running a Stable build, when you've specified that you prefer to run " . ucfirst($this->getChannel()) . " builds.", - "If you would like to be kept informed about new Stable builds only, it is recommended that you change 'preferred-channel' in your pocketmine.yml to 'stable'." + "You're running a Stable build, but you're receiving update notifications for " . ucfirst($this->getChannel()) . " builds.", + "To get notified about new Stable builds only, change 'preferred-channel' in your pocketmine.yml to 'stable'." ]); } protected function showChannelSuggestionBeta() : void{ $this->printConsoleMessage([ - "It appears you're running a Beta build, when you've specified that you prefer to run Stable builds.", - "If you would like to be kept informed about new Beta or Development builds, it is recommended that you change 'preferred-channel' in your pocketmine.yml to 'beta' or 'development'." + "You're running a Beta build, but you're receiving update notifications for Stable builds.", + "To get notified about new Beta or Development builds, change 'preferred-channel' in your pocketmine.yml to 'beta' or 'development'." ]); } From e43d39c0bcc0c146efc5707bc37b1fd0b8c2e572 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 20 Aug 2021 20:06:09 +0100 Subject: [PATCH 2723/3224] UpdateChecker: improve type handling --- src/updater/UpdateChecker.php | 22 ++++++++++------------ tests/phpstan/configs/l8-baseline.neon | 20 -------------------- 2 files changed, 10 insertions(+), 32 deletions(-) diff --git a/src/updater/UpdateChecker.php b/src/updater/UpdateChecker.php index 5f8332586a..ede2343c79 100644 --- a/src/updater/UpdateChecker.php +++ b/src/updater/UpdateChecker.php @@ -39,8 +39,6 @@ class UpdateChecker{ protected $endpoint; /** @var UpdateInfo|null */ protected $updateInfo = null; - /** @var VersionString|null */ - protected $newVersion; /** @var \Logger */ private $logger; @@ -63,8 +61,7 @@ class UpdateChecker{ * Callback used at the end of the update checking task */ public function checkUpdateCallback(UpdateInfo $updateInfo) : void{ - $this->updateInfo = $updateInfo; - $this->checkUpdate(); + $this->checkUpdate($updateInfo); if($this->hasUpdate()){ (new UpdateNotifyEvent($this))->call(); if($this->server->getConfigGroup()->getPropertyBool("auto-updater.on-update.warn-console", true)){ @@ -83,15 +80,19 @@ class UpdateChecker{ * Returns whether there is an update available. */ public function hasUpdate() : bool{ - return $this->newVersion !== null; + return $this->updateInfo !== null; } /** * Posts a warning to the console to tell the user there is an update available */ public function showConsoleUpdate() : void{ + if($this->updateInfo === null){ + return; + } + $newVersion = new VersionString($this->updateInfo->base_version, $this->updateInfo->is_dev, $this->updateInfo->build); $messages = [ - "Your version of " . $this->server->getName() . " is out of date. Version " . $this->newVersion->getFullVersion(true) . " was released on " . date("D M j h:i:s Y", $this->updateInfo->date) + "Your version of " . $this->server->getName() . " is out of date. Version " . $newVersion->getFullVersion(true) . " was released on " . date("D M j h:i:s Y", $this->updateInfo->date) ]; $messages[] = "Details: " . $this->updateInfo->details_url; @@ -140,13 +141,10 @@ class UpdateChecker{ /** * Checks the update information against the current server version to decide if there's an update */ - protected function checkUpdate() : void{ - if($this->updateInfo === null){ - return; - } + protected function checkUpdate(UpdateInfo $updateInfo) : void{ $currentVersion = VersionInfo::VERSION(); try{ - $newVersion = new VersionString($this->updateInfo->base_version, $this->updateInfo->is_dev, $this->updateInfo->build); + $newVersion = new VersionString($updateInfo->base_version, $updateInfo->is_dev, $updateInfo->build); }catch(\InvalidArgumentException $e){ //Invalid version returned from API, assume there's no update $this->logger->debug("Assuming no update because \"" . $e->getMessage() . "\""); @@ -154,7 +152,7 @@ class UpdateChecker{ } if($currentVersion->compare($newVersion) > 0 and ($currentVersion->getFullVersion() !== $newVersion->getFullVersion() or $currentVersion->getBuild() > 0)){ - $this->newVersion = $newVersion; + $this->updateInfo = $updateInfo; } } diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index e72b8cf11b..a87cd0dc25 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -245,26 +245,6 @@ parameters: count: 1 path: ../../../src/scheduler/DumpWorkerMemoryTask.php - - - message: "#^Cannot access property \\$date on pocketmine\\\\updater\\\\UpdateInfo\\|null\\.$#" - count: 1 - path: ../../../src/updater/UpdateChecker.php - - - - message: "#^Cannot access property \\$details_url on pocketmine\\\\updater\\\\UpdateInfo\\|null\\.$#" - count: 1 - path: ../../../src/updater/UpdateChecker.php - - - - message: "#^Cannot access property \\$download_url on pocketmine\\\\updater\\\\UpdateInfo\\|null\\.$#" - count: 1 - path: ../../../src/updater/UpdateChecker.php - - - - message: "#^Cannot call method getFullVersion\\(\\) on pocketmine\\\\utils\\\\VersionString\\|null\\.$#" - count: 1 - path: ../../../src/updater/UpdateChecker.php - - message: "#^Method pocketmine\\\\utils\\\\Config\\:\\:fixYAMLIndexes\\(\\) should return string but returns string\\|null\\.$#" count: 1 From 34a740582042c513bb8ba9880601075172e174ee Mon Sep 17 00:00:00 2001 From: alvin0319 Date: Sat, 21 Aug 2021 06:51:36 +0900 Subject: [PATCH 2724/3224] Player: fixed player can fly after respawn (#4388) --- src/player/Player.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/player/Player.php b/src/player/Player.php index 41b57be804..76cdc8db37 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2124,6 +2124,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->setSprinting(false); $this->setSneaking(false); + $this->setFlying(false); $this->extinguish(); $this->setAirSupplyTicks($this->getMaxAirSupplyTicks()); From eb9188c30958c8efa4ad8acf1126712a4013d4ca Mon Sep 17 00:00:00 2001 From: Rush2929 <76860328+Rush2929@users.noreply.github.com> Date: Sat, 21 Aug 2021 06:59:35 +0900 Subject: [PATCH 2725/3224] Replace InventoryPickup*Event with EntityItemPickupEvent (#4384) The rationale here is that inventories don't actually pick items up - their holders do. It's especially misleading to say that an inventory is picking up an item in creative mode when the picked-up item can't actually be added to the target inventory in the first place. This change allows a range of new functionality, such as: - Allowing survival players to pick items up even when their inventories are full, similarly to creative players - Changing the destination inventory of collected items (e.g. items could be redirected to the offhand or ender chest inventory, while still allowing other plugins to understand what's happening) As an added bonus, this obsoletes one more use case for Inventory->getHolder(), bringing us one step closer to removing the cyclic reference nightmare from inventories. The choice of naming (EntityItemPickup, instead of EntityPickupItem) is to be consistent with other events, where the word order is SubjectObjectActionEvent. --- src/entity/object/ItemEntity.php | 15 ++-- src/entity/projectile/Arrow.php | 14 ++-- src/event/entity/EntityItemPickupEvent.php | 80 +++++++++++++++++++ .../inventory/InventoryPickupArrowEvent.php | 45 ----------- .../inventory/InventoryPickupItemEvent.php | 45 ----------- 5 files changed, 97 insertions(+), 102 deletions(-) create mode 100644 src/event/entity/EntityItemPickupEvent.php delete mode 100644 src/event/inventory/InventoryPickupArrowEvent.php delete mode 100644 src/event/inventory/InventoryPickupItemEvent.php diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index 4d5f80f763..bd06c647a2 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -26,9 +26,9 @@ namespace pocketmine\entity\object; use pocketmine\entity\Entity; use pocketmine\entity\EntitySizeInfo; use pocketmine\entity\Location; +use pocketmine\event\entity\EntityItemPickupEvent; use pocketmine\event\entity\ItemDespawnEvent; use pocketmine\event\entity\ItemSpawnEvent; -use pocketmine\event\inventory\InventoryPickupItemEvent; use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; @@ -227,12 +227,15 @@ class ItemEntity extends Entity{ $item = $this->getItem(); $playerInventory = $player->getInventory(); - - if($player->hasFiniteResources() and !$playerInventory->canAddItem($item)){ - return; + if(!$playerInventory->canAddItem($item)){ + $playerInventory = null; + } + + $ev = new EntityItemPickupEvent($player, $this, $item, $playerInventory); + if($player->hasFiniteResources() and $playerInventory === null){ + $ev->cancel(); } - $ev = new InventoryPickupItemEvent($playerInventory, $this); $ev->call(); if($ev->isCancelled()){ return; @@ -242,7 +245,7 @@ class ItemEntity extends Entity{ $viewer->getNetworkSession()->onPlayerPickUpItem($player, $this); } - $playerInventory->addItem(clone $item); + $ev->getInventory()?->addItem($ev->getItem()); $this->flagForDespawn(); } } diff --git a/src/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php index f0a1181fd8..8ae2b57e22 100644 --- a/src/entity/projectile/Arrow.php +++ b/src/entity/projectile/Arrow.php @@ -28,8 +28,8 @@ use pocketmine\entity\animation\ArrowShakeAnimation; use pocketmine\entity\Entity; use pocketmine\entity\EntitySizeInfo; use pocketmine\entity\Location; +use pocketmine\event\entity\EntityItemPickupEvent; use pocketmine\event\entity\ProjectileHitEvent; -use pocketmine\event\inventory\InventoryPickupArrowEvent; use pocketmine\item\VanillaItems; use pocketmine\math\RayTraceResult; use pocketmine\nbt\tag\CompoundTag; @@ -174,13 +174,15 @@ class Arrow extends Projectile{ } $item = VanillaItems::ARROW(); - $playerInventory = $player->getInventory(); - if($player->hasFiniteResources() and !$playerInventory->canAddItem($item)){ - return; + if(!$playerInventory->canAddItem($item)){ + $playerInventory = null; } - $ev = new InventoryPickupArrowEvent($playerInventory, $this); + $ev = new EntityItemPickupEvent($player, $this, $item, $playerInventory); + if($player->hasFiniteResources() and $playerInventory === null){ + $ev->cancel(); + } if($this->pickupMode === self::PICKUP_NONE or ($this->pickupMode === self::PICKUP_CREATIVE and !$player->isCreative())){ $ev->cancel(); } @@ -194,7 +196,7 @@ class Arrow extends Projectile{ $viewer->getNetworkSession()->onPlayerPickUpItem($player, $this); } - $playerInventory->addItem(clone $item); + $ev->getInventory()?->addItem($ev->getItem()); $this->flagForDespawn(); } diff --git a/src/event/entity/EntityItemPickupEvent.php b/src/event/entity/EntityItemPickupEvent.php new file mode 100644 index 0000000000..2e00f8570e --- /dev/null +++ b/src/event/entity/EntityItemPickupEvent.php @@ -0,0 +1,80 @@ + + */ +class EntityItemPickupEvent extends EntityEvent implements Cancellable{ + use CancellableTrait; + + public function __construct( + Entity $collector, + private Entity $origin, + private Item $item, + private ?Inventory $inventory + ){ + $this->entity = $collector; + } + + public function getOrigin() : Entity{ + return $this->origin; + } + + /** + * Items to be received + */ + public function getItem() : Item{ + return clone $this->item; + } + + /** + * Change the items to receive. + */ + public function setItem(Item $item) : void{ + $this->item = clone $item; + } + + /** + * Inventory to which received items will be added. + */ + public function getInventory() : ?Inventory{ + return $this->inventory; + } + + /** + * Change the inventory to which received items are added. + */ + public function setInventory(?Inventory $inventory) : void{ + $this->inventory = $inventory; + } + +} diff --git a/src/event/inventory/InventoryPickupArrowEvent.php b/src/event/inventory/InventoryPickupArrowEvent.php deleted file mode 100644 index 1c4d2772d5..0000000000 --- a/src/event/inventory/InventoryPickupArrowEvent.php +++ /dev/null @@ -1,45 +0,0 @@ -arrow = $arrow; - parent::__construct($inventory); - } - - public function getArrow() : Arrow{ - return $this->arrow; - } -} diff --git a/src/event/inventory/InventoryPickupItemEvent.php b/src/event/inventory/InventoryPickupItemEvent.php deleted file mode 100644 index 71a81c57c4..0000000000 --- a/src/event/inventory/InventoryPickupItemEvent.php +++ /dev/null @@ -1,45 +0,0 @@ -itemEntity = $itemEntity; - parent::__construct($inventory); - } - - public function getItemEntity() : ItemEntity{ - return $this->itemEntity; - } -} From f5a4baf3cfad21ecdfa541215f1797eac3411faf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 20 Aug 2021 20:16:59 +0100 Subject: [PATCH 2726/3224] AsyncTask: regroup some methods into more sensible places how the fuck is anyone supposed to find anything?? --- src/scheduler/AsyncTask.php | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/scheduler/AsyncTask.php b/src/scheduler/AsyncTask.php index b58f1fddb9..8440eb3e91 100644 --- a/src/scheduler/AsyncTask.php +++ b/src/scheduler/AsyncTask.php @@ -104,6 +104,10 @@ abstract class AsyncTask extends \Threaded{ return $this->finished or $this->isCrashed(); } + public function hasResult() : bool{ + return $this->result !== null; + } + /** * @return mixed */ @@ -115,18 +119,6 @@ abstract class AsyncTask extends \Threaded{ return $this->result; } - public function cancelRun() : void{ - $this->cancelRun = true; - } - - public function hasCancelledRun() : bool{ - return $this->cancelRun; - } - - public function hasResult() : bool{ - return $this->result !== null; - } - /** * @param mixed $result */ @@ -134,6 +126,13 @@ abstract class AsyncTask extends \Threaded{ $this->result = ($this->serialized = !is_scalar($result)) ? igbinary_serialize($result) : $result; } + public function cancelRun() : void{ + $this->cancelRun = true; + } + public function hasCancelledRun() : bool{ + return $this->cancelRun; + } + public function setSubmitted() : void{ $this->submitted = true; } From 14577daae37155f602d3f0e0bc53dbea154bb8a4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 20 Aug 2021 23:52:34 +0100 Subject: [PATCH 2727/3224] fixed build --- src/network/BandwidthStatsTracker.php | 1 + src/network/BidirectionalBandwidthStatsTracker.php | 1 + 2 files changed, 2 insertions(+) diff --git a/src/network/BandwidthStatsTracker.php b/src/network/BandwidthStatsTracker.php index 0f0358dd19..5d0b6e6c1c 100644 --- a/src/network/BandwidthStatsTracker.php +++ b/src/network/BandwidthStatsTracker.php @@ -39,6 +39,7 @@ final class BandwidthStatsTracker{ /** @var int */ private $totalBytes = 0; + /** @phpstan-param positive-int $historySize */ public function __construct(int $historySize){ $this->history = array_fill(0, $historySize, 0); } diff --git a/src/network/BidirectionalBandwidthStatsTracker.php b/src/network/BidirectionalBandwidthStatsTracker.php index a4cf3f6a49..f9ed1a5645 100644 --- a/src/network/BidirectionalBandwidthStatsTracker.php +++ b/src/network/BidirectionalBandwidthStatsTracker.php @@ -31,6 +31,7 @@ final class BidirectionalBandwidthStatsTracker{ /** @var BandwidthStatsTracker */ private $receive; + /** @phpstan-param positive-int $historySize */ public function __construct(int $historySize){ $this->send = new BandwidthStatsTracker($historySize); $this->receive = new BandwidthStatsTracker($historySize); From 4023a024ceff8285074224825dbc5a58a0e5b5d6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Aug 2021 00:15:38 +0100 Subject: [PATCH 2728/3224] [ci skip] update changelog --- changelogs/4.0-snapshot.md | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 8fa02fb84b..4c9c0b1621 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -499,10 +499,15 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `PlayerItemUseEvent`: player activating their held item, for example to throw it. - `BlockTeleportEvent`: block teleporting, for example dragon egg when attacked. - `PlayerDisplayNameChangeEvent` + - `EntityItemPickupEvent`: player (or other entity) picks up a dropped item (or arrow). Replaces `InventoryPickupItemEvent` and `InventoryPickupArrowEvent`. + - Unlike its predecessors, this event supports changing the destination inventory. + - If the destination inventory is `null`, the item will be destroyed. This is usually seen for creative players with full inventories. - The following events have been removed: - `EntityArmorChangeEvent` - `EntityInventoryChangeEvent` - `EntityLevelChangeEvent` - `EntityTeleportEvent` with world checks should be used instead. + - `InventoryPickupItemEvent` - use `EntityItemPickupEvent` instead + - `InventoryPickupArrowEvent` - use `EntityItemPickupEvent` instead - `NetworkInterfaceCrashEvent` - `PlayerCheatEvent` - `PlayerIllegalMoveEvent` @@ -712,12 +717,25 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` ### Lang - The following classes have been renamed: - `BaseLang` -> `Language` + - `TranslationContainer` -> `Translatable` +- The following classes have been removed: + - `TextContainer` +- The following API methods have been added: + - `Translatable->format()`: allows adding formatting (such as color codes) to a translation + - `Translatable->prefix()`: allows prefixing formatting + - `Translatable->postfix()`: allows postfixing formatting +- The following API methods have changed signatures: + - `Translatable->__construct()` now accepts `array` for parameters, instead of just `list`. + - `Translatable->getParameter()` now accepts `int|string` for the index instead of just `int`. + - `Translatable->getParameter()` now returns `Translatable|string` instead of just `string`. + - `Translatable->getParameters()` now returns `array`. - `LanguageNotFoundException` has been added. This is thrown when trying to construct a `Language` which doesn't exist in the server files. -- `TranslationContainer` no longer discards keys for translation parameters. Previously, only the insertion order was considered. -- `TranslationContainer` now supports string keys for translation parameters. -- `TranslationContainer` now supports providing other `TranslationContainers` as translation parameters. -- `Language->translateString()` now supports providing `TranslationContainers` as translation parameters. - +- `Translatable` no longer discards keys for translation parameters. Previously, only the insertion order was considered. +- `Translatable` now supports string keys for translation parameters. +- `Translatable` now supports providing other `Translatable`s as translation parameters. +- `Language->translateString()` now supports providing `Translatable`s as translation parameters. +- `Language->translateString()` no longer automatically attempts to translate string parameters. If you want them to be translated, translate them explicitly. This fixes bugs where player chat messages containing translation keys would be unexpectedly translated. +- `Language->translate()` no longer attempts to translate string parameters of `Translatable` (same rationale as previous point). ### Network - The following fields have been removed: @@ -1138,6 +1156,9 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Terminal::write()`: emits a Minecraft-formatted text line without newline - `Terminal::writeLine()`: emits a Minecraft-formatted text line with newline - `Utils::recursiveUnlink()`: recursively deletes a directory and its contents +- The following API class constants have been added: + - `TextFormat::COLORS`: lists all known color codes + - `TextFormat::FORMATS`: lists all known formatting codes (e.g. italic, bold). (`RESET` is not included because it _removes_ formats, rather than adding them.) - The following deprecated API redirects have been removed: - `Utils::execute()`: moved to `Process` - `Utils::getIP()`: moved to `Internet` @@ -1155,6 +1176,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - The following API methods have signature changes: - `Internet::simpleCurl()` now requires a `Closure` for its `onSuccess` parameter instead of `callable`. - The following API methods have been removed: + - `TextFormat::toJSON()` - `Utils::getCallableIdentifier()` ## Gameplay @@ -1164,6 +1186,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - bamboo sapling - barrel - barrier + - blast furnace - blue ice - carved pumpkin - coral block @@ -1176,6 +1199,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - note block - red, green, blue and purple torches (from Minecraft: Education Edition) - sea pickle + - smoker - underwater torches (from Minecraft: Education Edition) - additional wood variants of the following: - buttons From 686bf398d5d83e3bb089e72c79ba2cdb69ad3db8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Aug 2021 15:41:00 +0100 Subject: [PATCH 2729/3224] BlockFactory: simplify get() code --- src/block/BlockFactory.php | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index b4a82575be..7f5d156ffa 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -957,18 +957,13 @@ class BlockFactory{ throw new \InvalidArgumentException("Block meta value $meta is out of bounds"); } - /** @var Block|null $block */ - $block = null; - try{ - $index = ($id << Block::INTERNAL_METADATA_BITS) | $meta; - if($this->fullList[$index] !== null){ - $block = clone $this->fullList[$index]; - } - }catch(\RuntimeException $e){ + $index = ($id << Block::INTERNAL_METADATA_BITS) | $meta; + if($index < 0 || $index >= $this->fullList->getSize()){ throw new \InvalidArgumentException("Block ID $id is out of bounds"); } - - if($block === null){ + if($this->fullList[$index] !== null){ + $block = clone $this->fullList[$index]; + }else{ $block = new UnknownBlock(new BID($id, $meta), BlockBreakInfo::instant()); } From 5f3c9e6f19cf4b0a35e0d7deb188a6a7e79097ba Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Aug 2021 15:43:30 +0100 Subject: [PATCH 2730/3224] Timezone: fix some implicit boolean type conversions --- src/utils/Timezone.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/Timezone.php b/src/utils/Timezone.php index 1cd6677154..c5d3f01b9b 100644 --- a/src/utils/Timezone.php +++ b/src/utils/Timezone.php @@ -76,7 +76,7 @@ abstract class Timezone{ } } - if(($timezone = self::detectSystemTimezone()) and date_default_timezone_set($timezone)){ + if(($timezone = self::detectSystemTimezone()) !== false and date_default_timezone_set($timezone)){ //Success! Timezone has already been set and validated in the if statement. //This here is just for redundancy just in case some program wants to read timezone data from the ini. ini_set("date.timezone", $timezone); @@ -84,7 +84,7 @@ abstract class Timezone{ } if(($response = Internet::getURL("http://ip-api.com/json")) !== null //If system timezone detection fails or timezone is an invalid value. - and $ip_geolocation_data = json_decode($response->getBody(), true) + and is_array($ip_geolocation_data = json_decode($response->getBody(), true)) and $ip_geolocation_data['status'] !== 'fail' and date_default_timezone_set($ip_geolocation_data['timezone']) ){ From 7d9f8ff4eddcf2f1b7c6f1ed8a37fe01659ab6d9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Aug 2021 15:46:19 +0100 Subject: [PATCH 2731/3224] World: do not use static:: for private property access --- src/world/World.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index 14e16c72d4..43bf9b4c8c 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -389,7 +389,7 @@ class World implements ChunkManager{ * Init the default world data */ public function __construct(Server $server, string $name, WritableWorldProvider $provider, AsyncPool $workerPool){ - $this->worldId = static::$worldIdCounter++; + $this->worldId = self::$worldIdCounter++; $this->server = $server; $this->provider = $provider; From 4d73c938862e12dfd83cbfed0e1f8ef61716258b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Aug 2021 15:54:11 +0100 Subject: [PATCH 2732/3224] fix CS --- src/utils/Timezone.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils/Timezone.php b/src/utils/Timezone.php index c5d3f01b9b..9f16da98f3 100644 --- a/src/utils/Timezone.php +++ b/src/utils/Timezone.php @@ -31,6 +31,7 @@ use function file_get_contents; use function implode; use function ini_get; use function ini_set; +use function is_array; use function is_string; use function json_decode; use function parse_ini_file; From cd9af7f9f64078fe21e62c05959c70a043e47646 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 21 Aug 2021 15:57:57 +0100 Subject: [PATCH 2733/3224] Utils: be explicit about class existence checking in testValidInstance() --- src/utils/Utils.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/utils/Utils.php b/src/utils/Utils.php index 774874f628..72192e6eec 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -36,6 +36,7 @@ use function array_reverse; use function array_values; use function bin2hex; use function chunk_split; +use function class_exists; use function count; use function debug_zval_dump; use function dechex; @@ -466,17 +467,14 @@ final class Utils{ * @phpstan-param class-string $baseName */ public static function testValidInstance(string $className, string $baseName) : void{ - try{ - $base = new \ReflectionClass($baseName); - }catch(\ReflectionException $e){ + if(!class_exists($baseName)){ throw new \InvalidArgumentException("Base class $baseName does not exist"); } - - try{ - $class = new \ReflectionClass($className); - }catch(\ReflectionException $e){ + if(!class_exists($className)){ throw new \InvalidArgumentException("Class $className does not exist"); } + $base = new \ReflectionClass($baseName); + $class = new \ReflectionClass($className); if(!$class->isSubclassOf($baseName)){ throw new \InvalidArgumentException("Class $className does not " . ($base->isInterface() ? "implement" : "extend") . " " . $baseName); From 1ce9474fce1d9259973a84146a328bbbbfb3da44 Mon Sep 17 00:00:00 2001 From: Rush2929 <76860328+Rush2929@users.noreply.github.com> Date: Mon, 23 Aug 2021 04:36:12 +0900 Subject: [PATCH 2734/3224] Picked up items can now be added to offhand slots. (#4360) --- src/entity/object/ItemEntity.php | 9 +++++---- src/entity/projectile/Arrow.php | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index bd06c647a2..5ca0b93c5f 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -226,10 +226,11 @@ class ItemEntity extends Entity{ } $item = $this->getItem(); - $playerInventory = $player->getInventory(); - if(!$playerInventory->canAddItem($item)){ - $playerInventory = null; - } + $playerInventory = match(true){ + $player->getOffHandInventory()->getItem(0)->canStackWith($item) => $player->getOffHandInventory(), + $player->getInventory()->canAddItem($item) => $player->getInventory(), + default => null + }; $ev = new EntityItemPickupEvent($player, $this, $item, $playerInventory); if($player->hasFiniteResources() and $playerInventory === null){ diff --git a/src/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php index 8ae2b57e22..eafaadb96d 100644 --- a/src/entity/projectile/Arrow.php +++ b/src/entity/projectile/Arrow.php @@ -174,10 +174,11 @@ class Arrow extends Projectile{ } $item = VanillaItems::ARROW(); - $playerInventory = $player->getInventory(); - if(!$playerInventory->canAddItem($item)){ - $playerInventory = null; - } + $playerInventory = match(true){ + $player->getOffHandInventory()->getItem(0)->canStackWith($item) => $player->getOffHandInventory(), + $player->getInventory()->canAddItem($item) => $player->getInventory(), + default => null + }; $ev = new EntityItemPickupEvent($player, $this, $item, $playerInventory); if($player->hasFiniteResources() and $playerInventory === null){ From 270ee5c0853c54220a697a8d640d77f8c86af1b9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 22 Aug 2021 23:02:36 +0100 Subject: [PATCH 2735/3224] Simplify registry method generation --- build/generate-registry-annotations.php | 47 +++++++++- src/block/VanillaBlocks.php | 3 +- src/block/utils/BannerPatternType.php | 3 +- src/block/utils/BellAttachmentType.php | 3 +- src/block/utils/BrewingStandSlot.php | 3 +- src/block/utils/CoralType.php | 3 +- src/block/utils/DyeColor.php | 3 +- src/block/utils/MushroomBlockType.php | 3 +- src/block/utils/RecordType.php | 3 +- src/block/utils/SkullType.php | 3 +- src/block/utils/SlabType.php | 3 +- src/block/utils/StairShape.php | 3 +- src/block/utils/TreeType.php | 3 +- src/crafting/FurnaceType.php | 3 +- src/entity/effect/VanillaEffects.php | 3 +- src/item/ItemUseResult.php | 3 +- src/item/PotionType.php | 3 +- src/item/ToolTier.php | 3 +- src/item/VanillaItems.php | 3 +- src/item/enchantment/VanillaEnchantments.php | 3 +- src/player/GameMode.php | 3 +- src/player/UsedChunkStatus.php | 3 +- src/plugin/PluginEnableOrder.php | 3 +- src/utils/RegistryUtils.php | 92 -------------------- src/world/sound/NoteInstrument.php | 3 +- 25 files changed, 90 insertions(+), 118 deletions(-) delete mode 100644 src/utils/RegistryUtils.php diff --git a/build/generate-registry-annotations.php b/build/generate-registry-annotations.php index 2eece2caed..b92fd67c85 100644 --- a/build/generate-registry-annotations.php +++ b/build/generate-registry-annotations.php @@ -23,21 +23,62 @@ declare(strict_types=1); namespace pocketmine\build\update_registry_annotations; -use pocketmine\utils\RegistryUtils; use function basename; use function class_exists; use function count; use function dirname; use function file_get_contents; use function file_put_contents; +use function implode; +use function ksort; use function preg_match; +use function sprintf; use function str_replace; use function substr; +use const SORT_STRING; if(count($argv) !== 2){ die("Provide a path to process"); } +/** + * @param object[] $members + */ +function generateMethodAnnotations(string $namespaceName, array $members) : string{ + $selfName = basename(__FILE__); + $lines = ["/**"]; + $lines[] = " * This doc-block is generated automatically, do not modify it manually."; + $lines[] = " * This must be regenerated whenever registry members are added, removed or changed."; + $lines[] = " * @see build/$selfName"; + $lines[] = " * @generate-registry-docblock"; + $lines[] = " *"; + + static $lineTmpl = " * @method static %2\$s %s()"; + $memberLines = []; + foreach($members as $name => $member){ + $reflect = new \ReflectionClass($member); + while($reflect !== false and $reflect->isAnonymous()){ + $reflect = $reflect->getParentClass(); + } + if($reflect === false){ + $typehint = "object"; + }elseif($reflect->getNamespaceName() === $namespaceName){ + $typehint = $reflect->getShortName(); + }else{ + $typehint = '\\' . $reflect->getName(); + } + $accessor = mb_strtoupper($name); + $memberLines[$accessor] = sprintf($lineTmpl, $accessor, $typehint); + } + ksort($memberLines, SORT_STRING); + + foreach($memberLines as $line){ + $lines[] = $line; + } + $lines[] = " */"; + return implode("\n", $lines); +} + require dirname(__DIR__) . '/vendor/autoload.php'; foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($argv[1], \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::CURRENT_AS_PATHNAME)) as $file){ @@ -59,12 +100,12 @@ foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($argv[1], } $reflect = new \ReflectionClass($className); $docComment = $reflect->getDocComment(); - if($docComment === false || (preg_match("/^\s*\*\s*\@see .+::_generateMethodAnnotations\(\)$/m", $docComment) !== 1 && preg_match("/^\s*\*\s*@generate-registry-docblock$/m", $docComment) !== 1)){ + if($docComment === false || preg_match("/^\s*\*\s*@generate-registry-docblock$/m", $docComment) !== 1){ continue; } echo "Found registry in $file\n"; - $replacement = RegistryUtils::_generateMethodAnnotations($matches[1], $className::getAll()); + $replacement = generateMethodAnnotations($matches[1], $className::getAll()); $newContents = str_replace($docComment, $replacement, $contents); if($newContents !== $contents){ diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 6d752b67fd..7cfd702d07 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -29,7 +29,8 @@ use function assert; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static WoodenButton ACACIA_BUTTON() * @method static WoodenDoor ACACIA_DOOR() diff --git a/src/block/utils/BannerPatternType.php b/src/block/utils/BannerPatternType.php index 51d85f6e43..5ede3d92b3 100644 --- a/src/block/utils/BannerPatternType.php +++ b/src/block/utils/BannerPatternType.php @@ -28,7 +28,8 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static BannerPatternType BORDER() * @method static BannerPatternType BRICKS() diff --git a/src/block/utils/BellAttachmentType.php b/src/block/utils/BellAttachmentType.php index f07b047c92..dc80e0c195 100644 --- a/src/block/utils/BellAttachmentType.php +++ b/src/block/utils/BellAttachmentType.php @@ -28,7 +28,8 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static BellAttachmentType CEILING() * @method static BellAttachmentType FLOOR() diff --git a/src/block/utils/BrewingStandSlot.php b/src/block/utils/BrewingStandSlot.php index 7d257e9add..c5b14af1bb 100644 --- a/src/block/utils/BrewingStandSlot.php +++ b/src/block/utils/BrewingStandSlot.php @@ -28,7 +28,8 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static BrewingStandSlot EAST() * @method static BrewingStandSlot NORTHWEST() diff --git a/src/block/utils/CoralType.php b/src/block/utils/CoralType.php index fb61a95e58..07d94d7ea8 100644 --- a/src/block/utils/CoralType.php +++ b/src/block/utils/CoralType.php @@ -28,7 +28,8 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static CoralType BRAIN() * @method static CoralType BUBBLE() diff --git a/src/block/utils/DyeColor.php b/src/block/utils/DyeColor.php index 0bd40c8c3c..91fe73fbfc 100644 --- a/src/block/utils/DyeColor.php +++ b/src/block/utils/DyeColor.php @@ -29,7 +29,8 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static DyeColor BLACK() * @method static DyeColor BLUE() diff --git a/src/block/utils/MushroomBlockType.php b/src/block/utils/MushroomBlockType.php index 413c273702..33b04831d1 100644 --- a/src/block/utils/MushroomBlockType.php +++ b/src/block/utils/MushroomBlockType.php @@ -28,7 +28,8 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static MushroomBlockType ALL_CAP() * @method static MushroomBlockType CAP_EAST() diff --git a/src/block/utils/RecordType.php b/src/block/utils/RecordType.php index 8b72d0a786..093663d0ba 100644 --- a/src/block/utils/RecordType.php +++ b/src/block/utils/RecordType.php @@ -31,7 +31,8 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static RecordType DISK_11() * @method static RecordType DISK_13() diff --git a/src/block/utils/SkullType.php b/src/block/utils/SkullType.php index 72bd94d6c2..2bbb566ddf 100644 --- a/src/block/utils/SkullType.php +++ b/src/block/utils/SkullType.php @@ -28,7 +28,8 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static SkullType CREEPER() * @method static SkullType DRAGON() diff --git a/src/block/utils/SlabType.php b/src/block/utils/SlabType.php index 806fdf5a45..26648481f3 100644 --- a/src/block/utils/SlabType.php +++ b/src/block/utils/SlabType.php @@ -28,7 +28,8 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static SlabType BOTTOM() * @method static SlabType DOUBLE() diff --git a/src/block/utils/StairShape.php b/src/block/utils/StairShape.php index 5f963728ec..dadd7d15ef 100644 --- a/src/block/utils/StairShape.php +++ b/src/block/utils/StairShape.php @@ -28,7 +28,8 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static StairShape INNER_LEFT() * @method static StairShape INNER_RIGHT() diff --git a/src/block/utils/TreeType.php b/src/block/utils/TreeType.php index 6896784d51..7667d144de 100644 --- a/src/block/utils/TreeType.php +++ b/src/block/utils/TreeType.php @@ -28,7 +28,8 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static TreeType ACACIA() * @method static TreeType BIRCH() diff --git a/src/crafting/FurnaceType.php b/src/crafting/FurnaceType.php index d68702f10a..889150c453 100644 --- a/src/crafting/FurnaceType.php +++ b/src/crafting/FurnaceType.php @@ -28,7 +28,8 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static FurnaceType BLAST_FURNACE() * @method static FurnaceType FURNACE() diff --git a/src/entity/effect/VanillaEffects.php b/src/entity/effect/VanillaEffects.php index bef5f7aa93..db5d28fffd 100644 --- a/src/entity/effect/VanillaEffects.php +++ b/src/entity/effect/VanillaEffects.php @@ -30,7 +30,8 @@ use function assert; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static AbsorptionEffect ABSORPTION() * @method static Effect BLINDNESS() diff --git a/src/item/ItemUseResult.php b/src/item/ItemUseResult.php index 57eff8e2df..8b5079289a 100644 --- a/src/item/ItemUseResult.php +++ b/src/item/ItemUseResult.php @@ -28,7 +28,8 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static ItemUseResult FAIL() * @method static ItemUseResult NONE() diff --git a/src/item/PotionType.php b/src/item/PotionType.php index 023b3f9366..952aa7e713 100644 --- a/src/item/PotionType.php +++ b/src/item/PotionType.php @@ -30,7 +30,8 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static PotionType AWKWARD() * @method static PotionType FIRE_RESISTANCE() diff --git a/src/item/ToolTier.php b/src/item/ToolTier.php index 85e363c3e7..a0984c6add 100644 --- a/src/item/ToolTier.php +++ b/src/item/ToolTier.php @@ -28,7 +28,8 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static ToolTier DIAMOND() * @method static ToolTier GOLD() diff --git a/src/item/VanillaItems.php b/src/item/VanillaItems.php index 6aadc4c486..f9ab3ade77 100644 --- a/src/item/VanillaItems.php +++ b/src/item/VanillaItems.php @@ -29,7 +29,8 @@ use function assert; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static Boat ACACIA_BOAT() * @method static Apple APPLE() diff --git a/src/item/enchantment/VanillaEnchantments.php b/src/item/enchantment/VanillaEnchantments.php index f961f22834..8ff97770a4 100644 --- a/src/item/enchantment/VanillaEnchantments.php +++ b/src/item/enchantment/VanillaEnchantments.php @@ -29,7 +29,8 @@ use pocketmine\utils\RegistryTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static ProtectionEnchantment BLAST_PROTECTION() * @method static Enchantment EFFICIENCY() diff --git a/src/player/GameMode.php b/src/player/GameMode.php index e3bcd9e1b7..a604f720ee 100644 --- a/src/player/GameMode.php +++ b/src/player/GameMode.php @@ -31,7 +31,8 @@ use function mb_strtolower; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static GameMode ADVENTURE() * @method static GameMode CREATIVE() diff --git a/src/player/UsedChunkStatus.php b/src/player/UsedChunkStatus.php index ff8c03089e..bbdb9a0616 100644 --- a/src/player/UsedChunkStatus.php +++ b/src/player/UsedChunkStatus.php @@ -28,7 +28,8 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static UsedChunkStatus NEEDED() * @method static UsedChunkStatus REQUESTED() diff --git a/src/plugin/PluginEnableOrder.php b/src/plugin/PluginEnableOrder.php index 5b44830324..16851cc724 100644 --- a/src/plugin/PluginEnableOrder.php +++ b/src/plugin/PluginEnableOrder.php @@ -29,7 +29,8 @@ use function mb_strtolower; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static PluginEnableOrder POSTWORLD() * @method static PluginEnableOrder STARTUP() diff --git a/src/utils/RegistryUtils.php b/src/utils/RegistryUtils.php deleted file mode 100644 index 7b76a14f7a..0000000000 --- a/src/utils/RegistryUtils.php +++ /dev/null @@ -1,92 +0,0 @@ - $member){ - $lines[] = sprintf($fnTmpl, mb_strtoupper($name), '\\' . get_class($member)); - } - return "//region auto-generated code\n" . implode("\n", $lines) . "\n\n//endregion\n"; - } - - /** - * Generates a block of @ method annotations for accessors for this registry's known members. - * - * @param object[] $members - */ - public static function _generateMethodAnnotations(string $namespaceName, array $members) : string{ - $selfName = __METHOD__; - $lines = ["/**"]; - $lines[] = " * This doc-block is generated automatically, do not modify it manually."; - $lines[] = " * This must be regenerated whenever registry members are added, removed or changed."; - $lines[] = " * @see \\$selfName()"; - $lines[] = " *"; - - static $lineTmpl = " * @method static %2\$s %s()"; - $memberLines = []; - foreach($members as $name => $member){ - $reflect = new \ReflectionClass($member); - while($reflect !== false and $reflect->isAnonymous()){ - $reflect = $reflect->getParentClass(); - } - if($reflect === false){ - $typehint = "object"; - }elseif($reflect->getNamespaceName() === $namespaceName){ - $typehint = $reflect->getShortName(); - }else{ - $typehint = '\\' . $reflect->getName(); - } - $accessor = mb_strtoupper($name); - $memberLines[$accessor] = sprintf($lineTmpl, $accessor, $typehint); - } - ksort($memberLines, SORT_STRING); - - foreach($memberLines as $line){ - $lines[] = $line; - } - $lines[] = " */"; - return implode("\n", $lines); - } -} diff --git a/src/world/sound/NoteInstrument.php b/src/world/sound/NoteInstrument.php index bec080d071..b22bc21492 100644 --- a/src/world/sound/NoteInstrument.php +++ b/src/world/sound/NoteInstrument.php @@ -28,7 +28,8 @@ use pocketmine\utils\EnumTrait; /** * This doc-block is generated automatically, do not modify it manually. * This must be regenerated whenever registry members are added, removed or changed. - * @see \pocketmine\utils\RegistryUtils::_generateMethodAnnotations() + * @see build/generate-registry-annotations.php + * @generate-registry-docblock * * @method static NoteInstrument BASS_DRUM() * @method static NoteInstrument CLICKS_AND_STICKS() From 044b2f54ac7802a953cbfb893e2124ecaa6cc71d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 22 Aug 2021 23:13:25 +0100 Subject: [PATCH 2736/3224] Fixed build --- build/generate-registry-annotations.php | 1 + 1 file changed, 1 insertion(+) diff --git a/build/generate-registry-annotations.php b/build/generate-registry-annotations.php index b92fd67c85..f7dce3c508 100644 --- a/build/generate-registry-annotations.php +++ b/build/generate-registry-annotations.php @@ -31,6 +31,7 @@ use function file_get_contents; use function file_put_contents; use function implode; use function ksort; +use function mb_strtoupper; use function preg_match; use function sprintf; use function str_replace; From 22316976faef5cfd0764d5c722d9cc8a6aa496e1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 23 Aug 2021 00:38:53 +0100 Subject: [PATCH 2737/3224] Introduce next-generation StringToItemParser this isn't specced up with some of the finer features of LegacyStringToItemParser such as metadata parsing, but those are still a work in progress (and probably limited to specific items like durable stuff). The goal is to unbind these aliases from legacy internal IDs, while also providing a nice flexible way for plugins to add their own items and aliases to the existing system. This system allows mapping a string to any item at all, irrespective of state, internal IDs, or any of that nonsense. This means it's finally possible to have stuff like lapis_lazuli and bone_meal aliases in commands. --- src/command/defaults/ClearCommand.php | 3 +- src/command/defaults/GiveCommand.php | 3 +- src/item/StringToItemParser.php | 885 ++++++++++++++++++++++++++ 3 files changed, 889 insertions(+), 2 deletions(-) create mode 100644 src/item/StringToItemParser.php diff --git a/src/command/defaults/ClearCommand.php b/src/command/defaults/ClearCommand.php index b2dbcc97b2..265549a9a8 100644 --- a/src/command/defaults/ClearCommand.php +++ b/src/command/defaults/ClearCommand.php @@ -28,6 +28,7 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\LegacyStringToItemParser; use pocketmine\item\LegacyStringToItemParserException; +use pocketmine\item\StringToItemParser; use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; @@ -81,7 +82,7 @@ class ClearCommand extends VanillaCommand{ $maxCount = -1; if(isset($args[1])){ try{ - $item = LegacyStringToItemParser::getInstance()->parse($args[1]); + $item = StringToItemParser::getInstance()->parse($args[1]) ?? LegacyStringToItemParser::getInstance()->parse($args[1]); if(isset($args[2])){ $item->setCount($maxCount = $this->getInteger($sender, $args[2], 0)); diff --git a/src/command/defaults/GiveCommand.php b/src/command/defaults/GiveCommand.php index 6d3df6ab1b..7a5de25707 100644 --- a/src/command/defaults/GiveCommand.php +++ b/src/command/defaults/GiveCommand.php @@ -28,6 +28,7 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\LegacyStringToItemParser; use pocketmine\item\LegacyStringToItemParserException; +use pocketmine\item\StringToItemParser; use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; use pocketmine\nbt\JsonNbtParser; @@ -65,7 +66,7 @@ class GiveCommand extends VanillaCommand{ } try{ - $item = LegacyStringToItemParser::getInstance()->parse($args[1]); + $item = StringToItemParser::getInstance()->parse($args[1]) ?? LegacyStringToItemParser::getInstance()->parse($args[1]); }catch(LegacyStringToItemParserException $e){ $sender->sendMessage(KnownTranslationFactory::commands_give_item_notFound($args[1])->prefix(TextFormat::RED)); return true; diff --git a/src/item/StringToItemParser.php b/src/item/StringToItemParser.php new file mode 100644 index 0000000000..3d9f504c2b --- /dev/null +++ b/src/item/StringToItemParser.php @@ -0,0 +1,885 @@ + + */ + private array $callbackMap = []; + + private static function make() : self{ + $result = new self; + + $result->registerBlock("acacia_button", fn() => VanillaBlocks::ACACIA_BUTTON()); + $result->registerBlock("acacia_door", fn() => VanillaBlocks::ACACIA_DOOR()); + $result->registerBlock("acacia_door_block", fn() => VanillaBlocks::ACACIA_DOOR()); + $result->registerBlock("acacia_fence_gate", fn() => VanillaBlocks::ACACIA_FENCE_GATE()); + $result->registerBlock("acacia_pressure_plate", fn() => VanillaBlocks::ACACIA_PRESSURE_PLATE()); + $result->registerBlock("acacia_sign", fn() => VanillaBlocks::ACACIA_SIGN()); + $result->registerBlock("acacia_stairs", fn() => VanillaBlocks::ACACIA_STAIRS()); + $result->registerBlock("acacia_standing_sign", fn() => VanillaBlocks::ACACIA_SIGN()); + $result->registerBlock("acacia_trapdoor", fn() => VanillaBlocks::ACACIA_TRAPDOOR()); + $result->registerBlock("acacia_wall_sign", fn() => VanillaBlocks::ACACIA_WALL_SIGN()); + $result->registerBlock("acacia_wood_stairs", fn() => VanillaBlocks::ACACIA_STAIRS()); + $result->registerBlock("acacia_wooden_stairs", fn() => VanillaBlocks::ACACIA_STAIRS()); + $result->registerBlock("activator_rail", fn() => VanillaBlocks::ACTIVATOR_RAIL()); + $result->registerBlock("active_redstone_lamp", fn() => VanillaBlocks::REDSTONE_LAMP()->setPowered(true)); + $result->registerBlock("air", fn() => VanillaBlocks::AIR()); + $result->registerBlock("andesite_stairs", fn() => VanillaBlocks::ANDESITE_STAIRS()); + $result->registerBlock("anvil", fn() => VanillaBlocks::ANVIL()); + $result->registerBlock("ateupd_block", fn() => VanillaBlocks::INFO_UPDATE2()); + $result->registerBlock("bamboo", fn() => VanillaBlocks::BAMBOO_SAPLING()); + $result->registerBlock("bamboo_sapling", fn() => VanillaBlocks::BAMBOO_SAPLING()); + $result->registerBlock("banner", fn() => VanillaBlocks::BANNER()); + $result->registerBlock("barrel", fn() => VanillaBlocks::BARREL()); + $result->registerBlock("barrier", fn() => VanillaBlocks::BARRIER()); + $result->registerBlock("beacon", fn() => VanillaBlocks::BEACON()); + $result->registerBlock("bed_block", fn() => VanillaBlocks::BED()); + $result->registerBlock("bedrock", fn() => VanillaBlocks::BEDROCK()); + $result->registerBlock("beetroot_block", fn() => VanillaBlocks::BEETROOTS()); + $result->registerBlock("bell", fn() => VanillaBlocks::BELL()); + $result->registerBlock("birch_button", fn() => VanillaBlocks::BIRCH_BUTTON()); + $result->registerBlock("birch_door", fn() => VanillaBlocks::BIRCH_DOOR()); + $result->registerBlock("birch_door_block", fn() => VanillaBlocks::BIRCH_DOOR()); + $result->registerBlock("birch_fence_gate", fn() => VanillaBlocks::BIRCH_FENCE_GATE()); + $result->registerBlock("birch_pressure_plate", fn() => VanillaBlocks::BIRCH_PRESSURE_PLATE()); + $result->registerBlock("birch_sign", fn() => VanillaBlocks::BIRCH_SIGN()); + $result->registerBlock("birch_stairs", fn() => VanillaBlocks::BIRCH_STAIRS()); + $result->registerBlock("birch_standing_sign", fn() => VanillaBlocks::BIRCH_SIGN()); + $result->registerBlock("birch_trapdoor", fn() => VanillaBlocks::BIRCH_TRAPDOOR()); + $result->registerBlock("birch_wall_sign", fn() => VanillaBlocks::BIRCH_WALL_SIGN()); + $result->registerBlock("birch_wood_stairs", fn() => VanillaBlocks::BIRCH_STAIRS()); + $result->registerBlock("birch_wooden_stairs", fn() => VanillaBlocks::BIRCH_STAIRS()); + $result->registerBlock("black_glazed_terracotta", fn() => VanillaBlocks::BLACK_GLAZED_TERRACOTTA()); + $result->registerBlock("blast_furnace", fn() => VanillaBlocks::BLAST_FURNACE()); + $result->registerBlock("blue_glazed_terracotta", fn() => VanillaBlocks::BLUE_GLAZED_TERRACOTTA()); + $result->registerBlock("blue_ice", fn() => VanillaBlocks::BLUE_ICE()); + $result->registerBlock("bone_block", fn() => VanillaBlocks::BONE_BLOCK()); + $result->registerBlock("bookshelf", fn() => VanillaBlocks::BOOKSHELF()); + $result->registerBlock("brewing_stand", fn() => VanillaBlocks::BREWING_STAND()); + $result->registerBlock("brewing_stand_block", fn() => VanillaBlocks::BREWING_STAND()); + $result->registerBlock("brick_block", fn() => VanillaBlocks::BRICKS()); + $result->registerBlock("brick_stairs", fn() => VanillaBlocks::BRICK_STAIRS()); + $result->registerBlock("bricks", fn() => VanillaBlocks::BRICKS()); + $result->registerBlock("bricks_block", fn() => VanillaBlocks::BRICKS()); + $result->registerBlock("brown_glazed_terracotta", fn() => VanillaBlocks::BROWN_GLAZED_TERRACOTTA()); + $result->registerBlock("brown_mushroom", fn() => VanillaBlocks::BROWN_MUSHROOM()); + $result->registerBlock("brown_mushroom_block", fn() => VanillaBlocks::BROWN_MUSHROOM_BLOCK()); + $result->registerBlock("burning_furnace", fn() => VanillaBlocks::FURNACE()); + $result->registerBlock("bush", fn() => VanillaBlocks::DEAD_BUSH()); + $result->registerBlock("cactus", fn() => VanillaBlocks::CACTUS()); + $result->registerBlock("cake", fn() => VanillaBlocks::CAKE()); + $result->registerBlock("cake_block", fn() => VanillaBlocks::CAKE()); + $result->registerBlock("carpet", fn() => VanillaBlocks::CARPET()); + $result->registerBlock("carrot_block", fn() => VanillaBlocks::CARROTS()); + $result->registerBlock("carrots", fn() => VanillaBlocks::CARROTS()); + $result->registerBlock("carved_pumpkin", fn() => VanillaBlocks::CARVED_PUMPKIN()); + $result->registerBlock("chemical_heat", fn() => VanillaBlocks::CHEMICAL_HEAT()); + $result->registerBlock("chemistry_table", fn() => VanillaBlocks::COMPOUND_CREATOR()); + $result->registerBlock("chest", fn() => VanillaBlocks::CHEST()); + $result->registerBlock("clay_block", fn() => VanillaBlocks::CLAY()); + $result->registerBlock("coal_block", fn() => VanillaBlocks::COAL()); + $result->registerBlock("coal_ore", fn() => VanillaBlocks::COAL_ORE()); + $result->registerBlock("cobble", fn() => VanillaBlocks::COBBLESTONE()); + $result->registerBlock("cobble_stairs", fn() => VanillaBlocks::COBBLESTONE_STAIRS()); + $result->registerBlock("cobble_wall", fn() => VanillaBlocks::COBBLESTONE_WALL()); + $result->registerBlock("cobblestone", fn() => VanillaBlocks::COBBLESTONE()); + $result->registerBlock("cobblestone_stairs", fn() => VanillaBlocks::COBBLESTONE_STAIRS()); + $result->registerBlock("cobblestone_wall", fn() => VanillaBlocks::COBBLESTONE_WALL()); + $result->registerBlock("cobweb", fn() => VanillaBlocks::COBWEB()); + $result->registerBlock("cocoa", fn() => VanillaBlocks::COCOA_POD()); + $result->registerBlock("cocoa_block", fn() => VanillaBlocks::COCOA_POD()); + $result->registerBlock("cocoa_pods", fn() => VanillaBlocks::COCOA_POD()); + $result->registerBlock("colored_torch_bp", fn() => VanillaBlocks::BLUE_TORCH()); + $result->registerBlock("colored_torch_rg", fn() => VanillaBlocks::RED_TORCH()); + $result->registerBlock("comparator", fn() => VanillaBlocks::REDSTONE_COMPARATOR()); + $result->registerBlock("comparator_block", fn() => VanillaBlocks::REDSTONE_COMPARATOR()); + $result->registerBlock("concrete", fn() => VanillaBlocks::CONCRETE()); + $result->registerBlock("concrete_powder", fn() => VanillaBlocks::CONCRETE_POWDER()); + $result->registerBlock("concretepowder", fn() => VanillaBlocks::CONCRETE_POWDER()); + $result->registerBlock("coral", fn() => VanillaBlocks::CORAL()); + $result->registerBlock("coral_block", fn() => VanillaBlocks::CORAL_BLOCK()); + $result->registerBlock("coral_fan", fn() => VanillaBlocks::CORAL_FAN()); + $result->registerBlock("coral_fan_dead", fn() => VanillaBlocks::CORAL_FAN()->setCoralType(CoralType::TUBE())->setDead(true)); + $result->registerBlock("coral_fan_hang", fn() => VanillaBlocks::WALL_CORAL_FAN()); + $result->registerBlock("coral_fan_hang2", fn() => VanillaBlocks::WALL_CORAL_FAN()->setCoralType(CoralType::BUBBLE())); + $result->registerBlock("coral_fan_hang3", fn() => VanillaBlocks::WALL_CORAL_FAN()->setCoralType(CoralType::HORN())); + $result->registerBlock("crafting_table", fn() => VanillaBlocks::CRAFTING_TABLE()); + $result->registerBlock("cyan_glazed_terracotta", fn() => VanillaBlocks::CYAN_GLAZED_TERRACOTTA()); + $result->registerBlock("dandelion", fn() => VanillaBlocks::DANDELION()); + $result->registerBlock("dark_oak_button", fn() => VanillaBlocks::DARK_OAK_BUTTON()); + $result->registerBlock("dark_oak_door", fn() => VanillaBlocks::DARK_OAK_DOOR()); + $result->registerBlock("dark_oak_door_block", fn() => VanillaBlocks::DARK_OAK_DOOR()); + $result->registerBlock("dark_oak_fence_gate", fn() => VanillaBlocks::DARK_OAK_FENCE_GATE()); + $result->registerBlock("dark_oak_pressure_plate", fn() => VanillaBlocks::DARK_OAK_PRESSURE_PLATE()); + $result->registerBlock("dark_oak_stairs", fn() => VanillaBlocks::DARK_OAK_STAIRS()); + $result->registerBlock("dark_oak_trapdoor", fn() => VanillaBlocks::DARK_OAK_TRAPDOOR()); + $result->registerBlock("dark_oak_wood_stairs", fn() => VanillaBlocks::DARK_OAK_STAIRS()); + $result->registerBlock("dark_oak_wooden_stairs", fn() => VanillaBlocks::DARK_OAK_STAIRS()); + $result->registerBlock("dark_prismarine_stairs", fn() => VanillaBlocks::DARK_PRISMARINE_STAIRS()); + $result->registerBlock("darkoak_sign", fn() => VanillaBlocks::DARK_OAK_SIGN()); + $result->registerBlock("darkoak_standing_sign", fn() => VanillaBlocks::DARK_OAK_SIGN()); + $result->registerBlock("darkoak_wall_sign", fn() => VanillaBlocks::DARK_OAK_WALL_SIGN()); + $result->registerBlock("daylight_detector", fn() => VanillaBlocks::DAYLIGHT_SENSOR()); + $result->registerBlock("daylight_detector_inverted", fn() => VanillaBlocks::DAYLIGHT_SENSOR()->setInverted(true)); + $result->registerBlock("daylight_sensor", fn() => VanillaBlocks::DAYLIGHT_SENSOR()); + $result->registerBlock("daylight_sensor_inverted", fn() => VanillaBlocks::DAYLIGHT_SENSOR()->setInverted(true)); + $result->registerBlock("dead_bush", fn() => VanillaBlocks::DEAD_BUSH()); + $result->registerBlock("deadbush", fn() => VanillaBlocks::DEAD_BUSH()); + $result->registerBlock("detector_rail", fn() => VanillaBlocks::DETECTOR_RAIL()); + $result->registerBlock("diamond_block", fn() => VanillaBlocks::DIAMOND()); + $result->registerBlock("diamond_ore", fn() => VanillaBlocks::DIAMOND_ORE()); + $result->registerBlock("diorite_stairs", fn() => VanillaBlocks::DIORITE_STAIRS()); + $result->registerBlock("dirt", fn() => VanillaBlocks::DIRT()); + $result->registerBlock("door_block", fn() => VanillaBlocks::OAK_DOOR()); + $result->registerBlock("double_plant", fn() => VanillaBlocks::SUNFLOWER()); + $result->registerBlock("double_red_sandstone_slab", fn() => VanillaBlocks::RED_SANDSTONE_SLAB()->setSlabType(SlabType::DOUBLE())); + $result->registerBlock("double_slab", fn() => VanillaBlocks::STONE_SLAB()->setSlabType(SlabType::DOUBLE())); + $result->registerBlock("double_slabs", fn() => VanillaBlocks::STONE_SLAB()->setSlabType(SlabType::DOUBLE())); + $result->registerBlock("double_stone_slab", fn() => VanillaBlocks::STONE_SLAB()->setSlabType(SlabType::DOUBLE())); + $result->registerBlock("double_stone_slab2", fn() => VanillaBlocks::RED_SANDSTONE_SLAB()->setSlabType(SlabType::DOUBLE())); + $result->registerBlock("double_stone_slab3", fn() => VanillaBlocks::END_STONE_BRICK_SLAB()->setSlabType(SlabType::DOUBLE())); + $result->registerBlock("double_stone_slab4", fn() => VanillaBlocks::MOSSY_STONE_BRICK_SLAB()->setSlabType(SlabType::DOUBLE())); + $result->registerBlock("double_wood_slab", fn() => VanillaBlocks::OAK_SLAB()->setSlabType(SlabType::DOUBLE())); + $result->registerBlock("double_wood_slabs", fn() => VanillaBlocks::OAK_SLAB()->setSlabType(SlabType::DOUBLE())); + $result->registerBlock("double_wooden_slab", fn() => VanillaBlocks::OAK_SLAB()->setSlabType(SlabType::DOUBLE())); + $result->registerBlock("double_wooden_slabs", fn() => VanillaBlocks::OAK_SLAB()->setSlabType(SlabType::DOUBLE())); + $result->registerBlock("dragon_egg", fn() => VanillaBlocks::DRAGON_EGG()); + $result->registerBlock("dried_kelp_block", fn() => VanillaBlocks::DRIED_KELP()); + $result->registerBlock("element_0", fn() => VanillaBlocks::ELEMENT_ZERO()); + $result->registerBlock("element_1", fn() => VanillaBlocks::ELEMENT_HYDROGEN()); + $result->registerBlock("element_10", fn() => VanillaBlocks::ELEMENT_NEON()); + $result->registerBlock("element_100", fn() => VanillaBlocks::ELEMENT_FERMIUM()); + $result->registerBlock("element_101", fn() => VanillaBlocks::ELEMENT_MENDELEVIUM()); + $result->registerBlock("element_102", fn() => VanillaBlocks::ELEMENT_NOBELIUM()); + $result->registerBlock("element_103", fn() => VanillaBlocks::ELEMENT_LAWRENCIUM()); + $result->registerBlock("element_104", fn() => VanillaBlocks::ELEMENT_RUTHERFORDIUM()); + $result->registerBlock("element_105", fn() => VanillaBlocks::ELEMENT_DUBNIUM()); + $result->registerBlock("element_106", fn() => VanillaBlocks::ELEMENT_SEABORGIUM()); + $result->registerBlock("element_107", fn() => VanillaBlocks::ELEMENT_BOHRIUM()); + $result->registerBlock("element_108", fn() => VanillaBlocks::ELEMENT_HASSIUM()); + $result->registerBlock("element_109", fn() => VanillaBlocks::ELEMENT_MEITNERIUM()); + $result->registerBlock("element_11", fn() => VanillaBlocks::ELEMENT_SODIUM()); + $result->registerBlock("element_110", fn() => VanillaBlocks::ELEMENT_DARMSTADTIUM()); + $result->registerBlock("element_111", fn() => VanillaBlocks::ELEMENT_ROENTGENIUM()); + $result->registerBlock("element_112", fn() => VanillaBlocks::ELEMENT_COPERNICIUM()); + $result->registerBlock("element_113", fn() => VanillaBlocks::ELEMENT_NIHONIUM()); + $result->registerBlock("element_114", fn() => VanillaBlocks::ELEMENT_FLEROVIUM()); + $result->registerBlock("element_115", fn() => VanillaBlocks::ELEMENT_MOSCOVIUM()); + $result->registerBlock("element_116", fn() => VanillaBlocks::ELEMENT_LIVERMORIUM()); + $result->registerBlock("element_117", fn() => VanillaBlocks::ELEMENT_TENNESSINE()); + $result->registerBlock("element_118", fn() => VanillaBlocks::ELEMENT_OGANESSON()); + $result->registerBlock("element_12", fn() => VanillaBlocks::ELEMENT_MAGNESIUM()); + $result->registerBlock("element_13", fn() => VanillaBlocks::ELEMENT_ALUMINUM()); + $result->registerBlock("element_14", fn() => VanillaBlocks::ELEMENT_SILICON()); + $result->registerBlock("element_15", fn() => VanillaBlocks::ELEMENT_PHOSPHORUS()); + $result->registerBlock("element_16", fn() => VanillaBlocks::ELEMENT_SULFUR()); + $result->registerBlock("element_17", fn() => VanillaBlocks::ELEMENT_CHLORINE()); + $result->registerBlock("element_18", fn() => VanillaBlocks::ELEMENT_ARGON()); + $result->registerBlock("element_19", fn() => VanillaBlocks::ELEMENT_POTASSIUM()); + $result->registerBlock("element_2", fn() => VanillaBlocks::ELEMENT_HELIUM()); + $result->registerBlock("element_20", fn() => VanillaBlocks::ELEMENT_CALCIUM()); + $result->registerBlock("element_21", fn() => VanillaBlocks::ELEMENT_SCANDIUM()); + $result->registerBlock("element_22", fn() => VanillaBlocks::ELEMENT_TITANIUM()); + $result->registerBlock("element_23", fn() => VanillaBlocks::ELEMENT_VANADIUM()); + $result->registerBlock("element_24", fn() => VanillaBlocks::ELEMENT_CHROMIUM()); + $result->registerBlock("element_25", fn() => VanillaBlocks::ELEMENT_MANGANESE()); + $result->registerBlock("element_26", fn() => VanillaBlocks::ELEMENT_IRON()); + $result->registerBlock("element_27", fn() => VanillaBlocks::ELEMENT_COBALT()); + $result->registerBlock("element_28", fn() => VanillaBlocks::ELEMENT_NICKEL()); + $result->registerBlock("element_29", fn() => VanillaBlocks::ELEMENT_COPPER()); + $result->registerBlock("element_3", fn() => VanillaBlocks::ELEMENT_LITHIUM()); + $result->registerBlock("element_30", fn() => VanillaBlocks::ELEMENT_ZINC()); + $result->registerBlock("element_31", fn() => VanillaBlocks::ELEMENT_GALLIUM()); + $result->registerBlock("element_32", fn() => VanillaBlocks::ELEMENT_GERMANIUM()); + $result->registerBlock("element_33", fn() => VanillaBlocks::ELEMENT_ARSENIC()); + $result->registerBlock("element_34", fn() => VanillaBlocks::ELEMENT_SELENIUM()); + $result->registerBlock("element_35", fn() => VanillaBlocks::ELEMENT_BROMINE()); + $result->registerBlock("element_36", fn() => VanillaBlocks::ELEMENT_KRYPTON()); + $result->registerBlock("element_37", fn() => VanillaBlocks::ELEMENT_RUBIDIUM()); + $result->registerBlock("element_38", fn() => VanillaBlocks::ELEMENT_STRONTIUM()); + $result->registerBlock("element_39", fn() => VanillaBlocks::ELEMENT_YTTRIUM()); + $result->registerBlock("element_4", fn() => VanillaBlocks::ELEMENT_BERYLLIUM()); + $result->registerBlock("element_40", fn() => VanillaBlocks::ELEMENT_ZIRCONIUM()); + $result->registerBlock("element_41", fn() => VanillaBlocks::ELEMENT_NIOBIUM()); + $result->registerBlock("element_42", fn() => VanillaBlocks::ELEMENT_MOLYBDENUM()); + $result->registerBlock("element_43", fn() => VanillaBlocks::ELEMENT_TECHNETIUM()); + $result->registerBlock("element_44", fn() => VanillaBlocks::ELEMENT_RUTHENIUM()); + $result->registerBlock("element_45", fn() => VanillaBlocks::ELEMENT_RHODIUM()); + $result->registerBlock("element_46", fn() => VanillaBlocks::ELEMENT_PALLADIUM()); + $result->registerBlock("element_47", fn() => VanillaBlocks::ELEMENT_SILVER()); + $result->registerBlock("element_48", fn() => VanillaBlocks::ELEMENT_CADMIUM()); + $result->registerBlock("element_49", fn() => VanillaBlocks::ELEMENT_INDIUM()); + $result->registerBlock("element_5", fn() => VanillaBlocks::ELEMENT_BORON()); + $result->registerBlock("element_50", fn() => VanillaBlocks::ELEMENT_TIN()); + $result->registerBlock("element_51", fn() => VanillaBlocks::ELEMENT_ANTIMONY()); + $result->registerBlock("element_52", fn() => VanillaBlocks::ELEMENT_TELLURIUM()); + $result->registerBlock("element_53", fn() => VanillaBlocks::ELEMENT_IODINE()); + $result->registerBlock("element_54", fn() => VanillaBlocks::ELEMENT_XENON()); + $result->registerBlock("element_55", fn() => VanillaBlocks::ELEMENT_CESIUM()); + $result->registerBlock("element_56", fn() => VanillaBlocks::ELEMENT_BARIUM()); + $result->registerBlock("element_57", fn() => VanillaBlocks::ELEMENT_LANTHANUM()); + $result->registerBlock("element_58", fn() => VanillaBlocks::ELEMENT_CERIUM()); + $result->registerBlock("element_59", fn() => VanillaBlocks::ELEMENT_PRASEODYMIUM()); + $result->registerBlock("element_6", fn() => VanillaBlocks::ELEMENT_CARBON()); + $result->registerBlock("element_60", fn() => VanillaBlocks::ELEMENT_NEODYMIUM()); + $result->registerBlock("element_61", fn() => VanillaBlocks::ELEMENT_PROMETHIUM()); + $result->registerBlock("element_62", fn() => VanillaBlocks::ELEMENT_SAMARIUM()); + $result->registerBlock("element_63", fn() => VanillaBlocks::ELEMENT_EUROPIUM()); + $result->registerBlock("element_64", fn() => VanillaBlocks::ELEMENT_GADOLINIUM()); + $result->registerBlock("element_65", fn() => VanillaBlocks::ELEMENT_TERBIUM()); + $result->registerBlock("element_66", fn() => VanillaBlocks::ELEMENT_DYSPROSIUM()); + $result->registerBlock("element_67", fn() => VanillaBlocks::ELEMENT_HOLMIUM()); + $result->registerBlock("element_68", fn() => VanillaBlocks::ELEMENT_ERBIUM()); + $result->registerBlock("element_69", fn() => VanillaBlocks::ELEMENT_THULIUM()); + $result->registerBlock("element_7", fn() => VanillaBlocks::ELEMENT_NITROGEN()); + $result->registerBlock("element_70", fn() => VanillaBlocks::ELEMENT_YTTERBIUM()); + $result->registerBlock("element_71", fn() => VanillaBlocks::ELEMENT_LUTETIUM()); + $result->registerBlock("element_72", fn() => VanillaBlocks::ELEMENT_HAFNIUM()); + $result->registerBlock("element_73", fn() => VanillaBlocks::ELEMENT_TANTALUM()); + $result->registerBlock("element_74", fn() => VanillaBlocks::ELEMENT_TUNGSTEN()); + $result->registerBlock("element_75", fn() => VanillaBlocks::ELEMENT_RHENIUM()); + $result->registerBlock("element_76", fn() => VanillaBlocks::ELEMENT_OSMIUM()); + $result->registerBlock("element_77", fn() => VanillaBlocks::ELEMENT_IRIDIUM()); + $result->registerBlock("element_78", fn() => VanillaBlocks::ELEMENT_PLATINUM()); + $result->registerBlock("element_79", fn() => VanillaBlocks::ELEMENT_GOLD()); + $result->registerBlock("element_8", fn() => VanillaBlocks::ELEMENT_OXYGEN()); + $result->registerBlock("element_80", fn() => VanillaBlocks::ELEMENT_MERCURY()); + $result->registerBlock("element_81", fn() => VanillaBlocks::ELEMENT_THALLIUM()); + $result->registerBlock("element_82", fn() => VanillaBlocks::ELEMENT_LEAD()); + $result->registerBlock("element_83", fn() => VanillaBlocks::ELEMENT_BISMUTH()); + $result->registerBlock("element_84", fn() => VanillaBlocks::ELEMENT_POLONIUM()); + $result->registerBlock("element_85", fn() => VanillaBlocks::ELEMENT_ASTATINE()); + $result->registerBlock("element_86", fn() => VanillaBlocks::ELEMENT_RADON()); + $result->registerBlock("element_87", fn() => VanillaBlocks::ELEMENT_FRANCIUM()); + $result->registerBlock("element_88", fn() => VanillaBlocks::ELEMENT_RADIUM()); + $result->registerBlock("element_89", fn() => VanillaBlocks::ELEMENT_ACTINIUM()); + $result->registerBlock("element_9", fn() => VanillaBlocks::ELEMENT_FLUORINE()); + $result->registerBlock("element_90", fn() => VanillaBlocks::ELEMENT_THORIUM()); + $result->registerBlock("element_91", fn() => VanillaBlocks::ELEMENT_PROTACTINIUM()); + $result->registerBlock("element_92", fn() => VanillaBlocks::ELEMENT_URANIUM()); + $result->registerBlock("element_93", fn() => VanillaBlocks::ELEMENT_NEPTUNIUM()); + $result->registerBlock("element_94", fn() => VanillaBlocks::ELEMENT_PLUTONIUM()); + $result->registerBlock("element_95", fn() => VanillaBlocks::ELEMENT_AMERICIUM()); + $result->registerBlock("element_96", fn() => VanillaBlocks::ELEMENT_CURIUM()); + $result->registerBlock("element_97", fn() => VanillaBlocks::ELEMENT_BERKELIUM()); + $result->registerBlock("element_98", fn() => VanillaBlocks::ELEMENT_CALIFORNIUM()); + $result->registerBlock("element_99", fn() => VanillaBlocks::ELEMENT_EINSTEINIUM()); + $result->registerBlock("emerald_block", fn() => VanillaBlocks::EMERALD()); + $result->registerBlock("emerald_ore", fn() => VanillaBlocks::EMERALD_ORE()); + $result->registerBlock("enchant_table", fn() => VanillaBlocks::ENCHANTING_TABLE()); + $result->registerBlock("enchanting_table", fn() => VanillaBlocks::ENCHANTING_TABLE()); + $result->registerBlock("enchantment_table", fn() => VanillaBlocks::ENCHANTING_TABLE()); + $result->registerBlock("end_brick_stairs", fn() => VanillaBlocks::END_STONE_BRICK_STAIRS()); + $result->registerBlock("end_bricks", fn() => VanillaBlocks::END_STONE_BRICKS()); + $result->registerBlock("end_portal_frame", fn() => VanillaBlocks::END_PORTAL_FRAME()); + $result->registerBlock("end_rod", fn() => VanillaBlocks::END_ROD()); + $result->registerBlock("end_stone", fn() => VanillaBlocks::END_STONE()); + $result->registerBlock("ender_chest", fn() => VanillaBlocks::ENDER_CHEST()); + $result->registerBlock("farmland", fn() => VanillaBlocks::FARMLAND()); + $result->registerBlock("fence", fn() => VanillaBlocks::OAK_FENCE()); + $result->registerBlock("fence_gate", fn() => VanillaBlocks::OAK_FENCE_GATE()); + $result->registerBlock("fence_gate_acacia", fn() => VanillaBlocks::ACACIA_FENCE_GATE()); + $result->registerBlock("fence_gate_birch", fn() => VanillaBlocks::BIRCH_FENCE_GATE()); + $result->registerBlock("fence_gate_dark_oak", fn() => VanillaBlocks::DARK_OAK_FENCE_GATE()); + $result->registerBlock("fence_gate_jungle", fn() => VanillaBlocks::JUNGLE_FENCE_GATE()); + $result->registerBlock("fence_gate_spruce", fn() => VanillaBlocks::SPRUCE_FENCE_GATE()); + $result->registerBlock("fire", fn() => VanillaBlocks::FIRE()); + $result->registerBlock("flower_pot", fn() => VanillaBlocks::FLOWER_POT()); + $result->registerBlock("flower_pot_block", fn() => VanillaBlocks::FLOWER_POT()); + $result->registerBlock("flowing_lava", fn() => VanillaBlocks::LAVA()); + $result->registerBlock("flowing_water", fn() => VanillaBlocks::WATER()); + $result->registerBlock("frame", fn() => VanillaBlocks::ITEM_FRAME()); + $result->registerBlock("frame_block", fn() => VanillaBlocks::ITEM_FRAME()); + $result->registerBlock("frosted_ice", fn() => VanillaBlocks::FROSTED_ICE()); + $result->registerBlock("furnace", fn() => VanillaBlocks::FURNACE()); + $result->registerBlock("glass", fn() => VanillaBlocks::GLASS()); + $result->registerBlock("glass_pane", fn() => VanillaBlocks::GLASS_PANE()); + $result->registerBlock("glass_panel", fn() => VanillaBlocks::GLASS_PANE()); + $result->registerBlock("glowing_obsidian", fn() => VanillaBlocks::GLOWING_OBSIDIAN()); + $result->registerBlock("glowing_redstone_ore", fn() => VanillaBlocks::REDSTONE_ORE()->setLit(true)); + $result->registerBlock("glowingobsidian", fn() => VanillaBlocks::GLOWING_OBSIDIAN()); + $result->registerBlock("glowstone", fn() => VanillaBlocks::GLOWSTONE()); + $result->registerBlock("glowstone_block", fn() => VanillaBlocks::GLOWSTONE()); + $result->registerBlock("gold_block", fn() => VanillaBlocks::GOLD()); + $result->registerBlock("gold_ore", fn() => VanillaBlocks::GOLD_ORE()); + $result->registerBlock("gold_pressure_plate", fn() => VanillaBlocks::WEIGHTED_PRESSURE_PLATE_LIGHT()); + $result->registerBlock("golden_rail", fn() => VanillaBlocks::POWERED_RAIL()); + $result->registerBlock("granite_stairs", fn() => VanillaBlocks::GRANITE_STAIRS()); + $result->registerBlock("grass", fn() => VanillaBlocks::GRASS()); + $result->registerBlock("grass_path", fn() => VanillaBlocks::GRASS_PATH()); + $result->registerBlock("gravel", fn() => VanillaBlocks::GRAVEL()); + $result->registerBlock("gray_glazed_terracotta", fn() => VanillaBlocks::GRAY_GLAZED_TERRACOTTA()); + $result->registerBlock("green_glazed_terracotta", fn() => VanillaBlocks::GREEN_GLAZED_TERRACOTTA()); + $result->registerBlock("hard_glass", fn() => VanillaBlocks::HARDENED_GLASS()); + $result->registerBlock("hard_glass_pane", fn() => VanillaBlocks::HARDENED_GLASS_PANE()); + $result->registerBlock("hard_stained_glass", fn() => VanillaBlocks::STAINED_HARDENED_GLASS()); + $result->registerBlock("hard_stained_glass_pane", fn() => VanillaBlocks::STAINED_HARDENED_GLASS_PANE()); + $result->registerBlock("hardened_clay", fn() => VanillaBlocks::HARDENED_CLAY()); + $result->registerBlock("hay_bale", fn() => VanillaBlocks::HAY_BALE()); + $result->registerBlock("hay_block", fn() => VanillaBlocks::HAY_BALE()); + $result->registerBlock("heavy_weighted_pressure_plate", fn() => VanillaBlocks::WEIGHTED_PRESSURE_PLATE_HEAVY()); + $result->registerBlock("hopper", fn() => VanillaBlocks::HOPPER()); + $result->registerBlock("hopper_block", fn() => VanillaBlocks::HOPPER()); + $result->registerBlock("ice", fn() => VanillaBlocks::ICE()); + $result->registerBlock("inactive_redstone_lamp", fn() => VanillaBlocks::REDSTONE_LAMP()); + $result->registerBlock("info_reserved6", fn() => VanillaBlocks::RESERVED6()); + $result->registerBlock("info_update", fn() => VanillaBlocks::INFO_UPDATE()); + $result->registerBlock("info_update2", fn() => VanillaBlocks::INFO_UPDATE2()); + $result->registerBlock("inverted_daylight_sensor", fn() => VanillaBlocks::DAYLIGHT_SENSOR()->setInverted(true)); + $result->registerBlock("invisible_bedrock", fn() => VanillaBlocks::INVISIBLE_BEDROCK()); + $result->registerBlock("invisiblebedrock", fn() => VanillaBlocks::INVISIBLE_BEDROCK()); + $result->registerBlock("iron_bar", fn() => VanillaBlocks::IRON_BARS()); + $result->registerBlock("iron_bars", fn() => VanillaBlocks::IRON_BARS()); + $result->registerBlock("iron_block", fn() => VanillaBlocks::IRON()); + $result->registerBlock("iron_door", fn() => VanillaBlocks::IRON_DOOR()); + $result->registerBlock("iron_door_block", fn() => VanillaBlocks::IRON_DOOR()); + $result->registerBlock("iron_ore", fn() => VanillaBlocks::IRON_ORE()); + $result->registerBlock("iron_pressure_plate", fn() => VanillaBlocks::WEIGHTED_PRESSURE_PLATE_HEAVY()); + $result->registerBlock("iron_trapdoor", fn() => VanillaBlocks::IRON_TRAPDOOR()); + $result->registerBlock("item_frame", fn() => VanillaBlocks::ITEM_FRAME()); + $result->registerBlock("item_frame_block", fn() => VanillaBlocks::ITEM_FRAME()); + $result->registerBlock("jack_o_lantern", fn() => VanillaBlocks::LIT_PUMPKIN()); + $result->registerBlock("jukebox", fn() => VanillaBlocks::JUKEBOX()); + $result->registerBlock("jungle_button", fn() => VanillaBlocks::JUNGLE_BUTTON()); + $result->registerBlock("jungle_door", fn() => VanillaBlocks::JUNGLE_DOOR()); + $result->registerBlock("jungle_door_block", fn() => VanillaBlocks::JUNGLE_DOOR()); + $result->registerBlock("jungle_fence_gate", fn() => VanillaBlocks::JUNGLE_FENCE_GATE()); + $result->registerBlock("jungle_pressure_plate", fn() => VanillaBlocks::JUNGLE_PRESSURE_PLATE()); + $result->registerBlock("jungle_sign", fn() => VanillaBlocks::JUNGLE_SIGN()); + $result->registerBlock("jungle_stairs", fn() => VanillaBlocks::JUNGLE_STAIRS()); + $result->registerBlock("jungle_standing_sign", fn() => VanillaBlocks::JUNGLE_SIGN()); + $result->registerBlock("jungle_trapdoor", fn() => VanillaBlocks::JUNGLE_TRAPDOOR()); + $result->registerBlock("jungle_wall_sign", fn() => VanillaBlocks::JUNGLE_WALL_SIGN()); + $result->registerBlock("ladder", fn() => VanillaBlocks::LADDER()); + $result->registerBlock("lantern", fn() => VanillaBlocks::LANTERN()); + $result->registerBlock("lapis_block", fn() => VanillaBlocks::LAPIS_LAZULI()); + $result->registerBlock("lapis_ore", fn() => VanillaBlocks::LAPIS_LAZULI_ORE()); + $result->registerBlock("lava", fn() => VanillaBlocks::LAVA()); + $result->registerBlock("leave", fn() => VanillaBlocks::OAK_LEAVES()); + $result->registerBlock("leave2", fn() => VanillaBlocks::ACACIA_LEAVES()); + $result->registerBlock("leaves", fn() => VanillaBlocks::OAK_LEAVES()); + $result->registerBlock("leaves2", fn() => VanillaBlocks::ACACIA_LEAVES()); + $result->registerBlock("lever", fn() => VanillaBlocks::LEVER()); + $result->registerBlock("light_blue_glazed_terracotta", fn() => VanillaBlocks::LIGHT_BLUE_GLAZED_TERRACOTTA()); + $result->registerBlock("light_weighted_pressure_plate", fn() => VanillaBlocks::WEIGHTED_PRESSURE_PLATE_LIGHT()); + $result->registerBlock("lily_pad", fn() => VanillaBlocks::LILY_PAD()); + $result->registerBlock("lime_glazed_terracotta", fn() => VanillaBlocks::LIME_GLAZED_TERRACOTTA()); + $result->registerBlock("lit_blast_furnace", fn() => VanillaBlocks::BLAST_FURNACE()); + $result->registerBlock("lit_furnace", fn() => VanillaBlocks::FURNACE()); + $result->registerBlock("lit_pumpkin", fn() => VanillaBlocks::LIT_PUMPKIN()); + $result->registerBlock("lit_redstone_lamp", fn() => VanillaBlocks::REDSTONE_LAMP()->setPowered(true)); + $result->registerBlock("lit_redstone_ore", fn() => VanillaBlocks::REDSTONE_ORE()->setLit(true)); + $result->registerBlock("lit_redstone_torch", fn() => VanillaBlocks::REDSTONE_TORCH()); + $result->registerBlock("lit_smoker", fn() => VanillaBlocks::SMOKER()); + $result->registerBlock("log", fn() => VanillaBlocks::OAK_LOG()); + $result->registerBlock("log2", fn() => VanillaBlocks::ACACIA_LOG()); + $result->registerBlock("loom", fn() => VanillaBlocks::LOOM()); + $result->registerBlock("magenta_glazed_terracotta", fn() => VanillaBlocks::MAGENTA_GLAZED_TERRACOTTA()); + $result->registerBlock("magma", fn() => VanillaBlocks::MAGMA()); + $result->registerBlock("melon_block", fn() => VanillaBlocks::MELON()); + $result->registerBlock("melon_stem", fn() => VanillaBlocks::MELON_STEM()); + $result->registerBlock("mob_head_block", fn() => VanillaBlocks::MOB_HEAD()); + $result->registerBlock("mob_spawner", fn() => VanillaBlocks::MONSTER_SPAWNER()); + $result->registerBlock("monster_egg", fn() => VanillaBlocks::INFESTED_STONE()); + $result->registerBlock("monster_egg_block", fn() => VanillaBlocks::INFESTED_STONE()); + $result->registerBlock("monster_spawner", fn() => VanillaBlocks::MONSTER_SPAWNER()); + $result->registerBlock("moss_stone", fn() => VanillaBlocks::MOSSY_COBBLESTONE()); + $result->registerBlock("mossy_cobblestone", fn() => VanillaBlocks::MOSSY_COBBLESTONE()); + $result->registerBlock("mossy_cobblestone_stairs", fn() => VanillaBlocks::MOSSY_COBBLESTONE_STAIRS()); + $result->registerBlock("mossy_stone", fn() => VanillaBlocks::MOSSY_COBBLESTONE()); + $result->registerBlock("mossy_stone_brick_stairs", fn() => VanillaBlocks::MOSSY_STONE_BRICK_STAIRS()); + $result->registerBlock("mycelium", fn() => VanillaBlocks::MYCELIUM()); + $result->registerBlock("nether_brick_block", fn() => VanillaBlocks::NETHER_BRICKS()); + $result->registerBlock("nether_brick_fence", fn() => VanillaBlocks::NETHER_BRICK_FENCE()); + $result->registerBlock("nether_brick_stairs", fn() => VanillaBlocks::NETHER_BRICK_STAIRS()); + $result->registerBlock("nether_bricks", fn() => VanillaBlocks::NETHER_BRICKS()); + $result->registerBlock("nether_bricks_stairs", fn() => VanillaBlocks::NETHER_BRICK_STAIRS()); + $result->registerBlock("nether_quartz_ore", fn() => VanillaBlocks::NETHER_QUARTZ_ORE()); + $result->registerBlock("nether_reactor", fn() => VanillaBlocks::NETHER_REACTOR_CORE()); + $result->registerBlock("nether_wart", fn() => VanillaBlocks::NETHER_WART()); + $result->registerBlock("nether_wart_block", fn() => VanillaBlocks::NETHER_WART_BLOCK()); + $result->registerBlock("nether_wart_plant", fn() => VanillaBlocks::NETHER_WART()); + $result->registerBlock("netherrack", fn() => VanillaBlocks::NETHERRACK()); + $result->registerBlock("netherreactor", fn() => VanillaBlocks::NETHER_REACTOR_CORE()); + $result->registerBlock("normal_stone_stairs", fn() => VanillaBlocks::STONE_STAIRS()); + $result->registerBlock("note_block", fn() => VanillaBlocks::NOTE_BLOCK()); + $result->registerBlock("noteblock", fn() => VanillaBlocks::NOTE_BLOCK()); + $result->registerBlock("oak_door", fn() => VanillaBlocks::OAK_DOOR()); + $result->registerBlock("oak_door_block", fn() => VanillaBlocks::OAK_DOOR()); + $result->registerBlock("oak_fence_gate", fn() => VanillaBlocks::OAK_FENCE_GATE()); + $result->registerBlock("oak_stairs", fn() => VanillaBlocks::OAK_STAIRS()); + $result->registerBlock("oak_wood_stairs", fn() => VanillaBlocks::OAK_STAIRS()); + $result->registerBlock("oak_wooden_stairs", fn() => VanillaBlocks::OAK_STAIRS()); + $result->registerBlock("obsidian", fn() => VanillaBlocks::OBSIDIAN()); + $result->registerBlock("orange_glazed_terracotta", fn() => VanillaBlocks::ORANGE_GLAZED_TERRACOTTA()); + $result->registerBlock("packed_ice", fn() => VanillaBlocks::PACKED_ICE()); + $result->registerBlock("pink_glazed_terracotta", fn() => VanillaBlocks::PINK_GLAZED_TERRACOTTA()); + $result->registerBlock("plank", fn() => VanillaBlocks::OAK_PLANKS()); + $result->registerBlock("planks", fn() => VanillaBlocks::OAK_PLANKS()); + $result->registerBlock("podzol", fn() => VanillaBlocks::PODZOL()); + $result->registerBlock("polished_andesite_stairs", fn() => VanillaBlocks::POLISHED_ANDESITE_STAIRS()); + $result->registerBlock("polished_diorite_stairs", fn() => VanillaBlocks::POLISHED_DIORITE_STAIRS()); + $result->registerBlock("polished_granite_stairs", fn() => VanillaBlocks::POLISHED_GRANITE_STAIRS()); + $result->registerBlock("poppy", fn() => VanillaBlocks::POPPY()); + $result->registerBlock("portal", fn() => VanillaBlocks::NETHER_PORTAL()); + $result->registerBlock("portal_block", fn() => VanillaBlocks::NETHER_PORTAL()); + $result->registerBlock("potato_block", fn() => VanillaBlocks::POTATOES()); + $result->registerBlock("potatoes", fn() => VanillaBlocks::POTATOES()); + $result->registerBlock("powered_comparator", fn() => VanillaBlocks::REDSTONE_COMPARATOR()); + $result->registerBlock("powered_comparator_block", fn() => VanillaBlocks::REDSTONE_COMPARATOR()); + $result->registerBlock("powered_rail", fn() => VanillaBlocks::POWERED_RAIL()); + $result->registerBlock("powered_repeater", fn() => VanillaBlocks::REDSTONE_REPEATER()->setPowered(true)); + $result->registerBlock("powered_repeater_block", fn() => VanillaBlocks::REDSTONE_REPEATER()->setPowered(true)); + $result->registerBlock("prismarine", fn() => VanillaBlocks::PRISMARINE()); + $result->registerBlock("prismarine_bricks_stairs", fn() => VanillaBlocks::PRISMARINE_BRICKS_STAIRS()); + $result->registerBlock("prismarine_stairs", fn() => VanillaBlocks::PRISMARINE_STAIRS()); + $result->registerBlock("pumpkin", fn() => VanillaBlocks::PUMPKIN()); + $result->registerBlock("pumpkin_stem", fn() => VanillaBlocks::PUMPKIN_STEM()); + $result->registerBlock("purple_glazed_terracotta", fn() => VanillaBlocks::PURPLE_GLAZED_TERRACOTTA()); + $result->registerBlock("purpur_block", fn() => VanillaBlocks::PURPUR()); + $result->registerBlock("purpur_stairs", fn() => VanillaBlocks::PURPUR_STAIRS()); + $result->registerBlock("quartz_block", fn() => VanillaBlocks::QUARTZ()); + $result->registerBlock("quartz_ore", fn() => VanillaBlocks::NETHER_QUARTZ_ORE()); + $result->registerBlock("quartz_stairs", fn() => VanillaBlocks::QUARTZ_STAIRS()); + $result->registerBlock("rail", fn() => VanillaBlocks::RAIL()); + $result->registerBlock("red_flower", fn() => VanillaBlocks::POPPY()); + $result->registerBlock("red_glazed_terracotta", fn() => VanillaBlocks::RED_GLAZED_TERRACOTTA()); + $result->registerBlock("red_mushroom", fn() => VanillaBlocks::RED_MUSHROOM()); + $result->registerBlock("red_mushroom_block", fn() => VanillaBlocks::RED_MUSHROOM_BLOCK()); + $result->registerBlock("red_nether_brick", fn() => VanillaBlocks::RED_NETHER_BRICKS()); + $result->registerBlock("red_nether_brick_stairs", fn() => VanillaBlocks::RED_NETHER_BRICK_STAIRS()); + $result->registerBlock("red_sandstone", fn() => VanillaBlocks::RED_SANDSTONE()); + $result->registerBlock("red_sandstone_slab", fn() => VanillaBlocks::RED_SANDSTONE_SLAB()); + $result->registerBlock("red_sandstone_stairs", fn() => VanillaBlocks::RED_SANDSTONE_STAIRS()); + $result->registerBlock("redstone_block", fn() => VanillaBlocks::REDSTONE()); + $result->registerBlock("redstone_lamp", fn() => VanillaBlocks::REDSTONE_LAMP()); + $result->registerBlock("redstone_ore", fn() => VanillaBlocks::REDSTONE_ORE()); + $result->registerBlock("redstone_torch", fn() => VanillaBlocks::REDSTONE_TORCH()); + $result->registerBlock("redstone_wire", fn() => VanillaBlocks::REDSTONE_WIRE()); + $result->registerBlock("reeds", fn() => VanillaBlocks::SUGARCANE()); + $result->registerBlock("reeds_block", fn() => VanillaBlocks::SUGARCANE()); + $result->registerBlock("repeater", fn() => VanillaBlocks::REDSTONE_REPEATER()); + $result->registerBlock("repeater_block", fn() => VanillaBlocks::REDSTONE_REPEATER()); + $result->registerBlock("reserved6", fn() => VanillaBlocks::RESERVED6()); + $result->registerBlock("rose", fn() => VanillaBlocks::POPPY()); + $result->registerBlock("sand", fn() => VanillaBlocks::SAND()); + $result->registerBlock("sandstone", fn() => VanillaBlocks::SANDSTONE()); + $result->registerBlock("sandstone_stairs", fn() => VanillaBlocks::SANDSTONE_STAIRS()); + $result->registerBlock("sapling", fn() => VanillaBlocks::OAK_SAPLING()); + $result->registerBlock("sea_lantern", fn() => VanillaBlocks::SEA_LANTERN()); + $result->registerBlock("sea_pickle", fn() => VanillaBlocks::SEA_PICKLE()); + $result->registerBlock("sealantern", fn() => VanillaBlocks::SEA_LANTERN()); + $result->registerBlock("shulker_box", fn() => VanillaBlocks::DYED_SHULKER_BOX()); + $result->registerBlock("sign", fn() => VanillaBlocks::OAK_SIGN()); + $result->registerBlock("sign_post", fn() => VanillaBlocks::OAK_SIGN()); + $result->registerBlock("silver_glazed_terracotta", fn() => VanillaBlocks::LIGHT_GRAY_GLAZED_TERRACOTTA()); + $result->registerBlock("skull_block", fn() => VanillaBlocks::MOB_HEAD()); + $result->registerBlock("slab", fn() => VanillaBlocks::SMOOTH_STONE_SLAB()); + $result->registerBlock("slabs", fn() => VanillaBlocks::SMOOTH_STONE_SLAB()); + $result->registerBlock("smoker", fn() => VanillaBlocks::SMOKER()); + $result->registerBlock("smooth_quartz_stairs", fn() => VanillaBlocks::SMOOTH_QUARTZ_STAIRS()); + $result->registerBlock("smooth_red_sandstone_stairs", fn() => VanillaBlocks::SMOOTH_RED_SANDSTONE_STAIRS()); + $result->registerBlock("smooth_sandstone_stairs", fn() => VanillaBlocks::SMOOTH_SANDSTONE_STAIRS()); + $result->registerBlock("smooth_stone", fn() => VanillaBlocks::SMOOTH_STONE()); + $result->registerBlock("snow", fn() => VanillaBlocks::SNOW()); + $result->registerBlock("snow_block", fn() => VanillaBlocks::SNOW()); + $result->registerBlock("snow_layer", fn() => VanillaBlocks::SNOW_LAYER()); + $result->registerBlock("soul_sand", fn() => VanillaBlocks::SOUL_SAND()); + $result->registerBlock("sponge", fn() => VanillaBlocks::SPONGE()); + $result->registerBlock("spruce_button", fn() => VanillaBlocks::SPRUCE_BUTTON()); + $result->registerBlock("spruce_door", fn() => VanillaBlocks::SPRUCE_DOOR()); + $result->registerBlock("spruce_door_block", fn() => VanillaBlocks::SPRUCE_DOOR()); + $result->registerBlock("spruce_fence_gate", fn() => VanillaBlocks::SPRUCE_FENCE_GATE()); + $result->registerBlock("spruce_pressure_plate", fn() => VanillaBlocks::SPRUCE_PRESSURE_PLATE()); + $result->registerBlock("spruce_sign", fn() => VanillaBlocks::SPRUCE_SIGN()); + $result->registerBlock("spruce_stairs", fn() => VanillaBlocks::SPRUCE_STAIRS()); + $result->registerBlock("spruce_standing_sign", fn() => VanillaBlocks::SPRUCE_SIGN()); + $result->registerBlock("spruce_trapdoor", fn() => VanillaBlocks::SPRUCE_TRAPDOOR()); + $result->registerBlock("spruce_wall_sign", fn() => VanillaBlocks::SPRUCE_WALL_SIGN()); + $result->registerBlock("spruce_wood_stairs", fn() => VanillaBlocks::SPRUCE_STAIRS()); + $result->registerBlock("spruce_wooden_stairs", fn() => VanillaBlocks::SPRUCE_STAIRS()); + $result->registerBlock("stained_clay", fn() => VanillaBlocks::STAINED_CLAY()); + $result->registerBlock("stained_glass", fn() => VanillaBlocks::STAINED_GLASS()); + $result->registerBlock("stained_glass_pane", fn() => VanillaBlocks::STAINED_GLASS_PANE()); + $result->registerBlock("stained_hardened_clay", fn() => VanillaBlocks::STAINED_CLAY()); + $result->registerBlock("standing_banner", fn() => VanillaBlocks::BANNER()); + $result->registerBlock("standing_sign", fn() => VanillaBlocks::OAK_SIGN()); + $result->registerBlock("still_lava", fn() => VanillaBlocks::LAVA()->setStill(true)); + $result->registerBlock("still_water", fn() => VanillaBlocks::WATER()->setStill(true)); + $result->registerBlock("stone", fn() => VanillaBlocks::STONE()); + $result->registerBlock("stone_brick", fn() => VanillaBlocks::STONE_BRICKS()); + $result->registerBlock("stone_brick_stairs", fn() => VanillaBlocks::STONE_BRICK_STAIRS()); + $result->registerBlock("stone_bricks", fn() => VanillaBlocks::STONE_BRICKS()); + $result->registerBlock("stone_button", fn() => VanillaBlocks::STONE_BUTTON()); + $result->registerBlock("stone_pressure_plate", fn() => VanillaBlocks::STONE_PRESSURE_PLATE()); + $result->registerBlock("stone_slab", fn() => VanillaBlocks::SMOOTH_STONE_SLAB()); + $result->registerBlock("stone_slab2", fn() => VanillaBlocks::RED_SANDSTONE_SLAB()); + $result->registerBlock("stone_slab3", fn() => VanillaBlocks::END_STONE_BRICK_SLAB()); + $result->registerBlock("stone_slab4", fn() => VanillaBlocks::MOSSY_STONE_BRICK_SLAB()); + $result->registerBlock("stone_stairs", fn() => VanillaBlocks::COBBLESTONE_STAIRS()); + $result->registerBlock("stone_wall", fn() => VanillaBlocks::COBBLESTONE_WALL()); + $result->registerBlock("stonebrick", fn() => VanillaBlocks::STONE_BRICKS()); + $result->registerBlock("stonecutter", fn() => VanillaBlocks::LEGACY_STONECUTTER()); + $result->registerBlock("stripped_acacia_log", fn() => VanillaBlocks::STRIPPED_ACACIA_LOG()); + $result->registerBlock("stripped_birch_log", fn() => VanillaBlocks::STRIPPED_BIRCH_LOG()); + $result->registerBlock("stripped_dark_oak_log", fn() => VanillaBlocks::STRIPPED_DARK_OAK_LOG()); + $result->registerBlock("stripped_jungle_log", fn() => VanillaBlocks::STRIPPED_JUNGLE_LOG()); + $result->registerBlock("stripped_oak_log", fn() => VanillaBlocks::STRIPPED_OAK_LOG()); + $result->registerBlock("stripped_spruce_log", fn() => VanillaBlocks::STRIPPED_SPRUCE_LOG()); + $result->registerBlock("sugar_cane", fn() => VanillaBlocks::SUGARCANE()); + $result->registerBlock("sugar_canes", fn() => VanillaBlocks::SUGARCANE()); + $result->registerBlock("sugarcane", fn() => VanillaBlocks::SUGARCANE()); + $result->registerBlock("sugarcane_block", fn() => VanillaBlocks::SUGARCANE()); + $result->registerBlock("sweet_berry_bush", fn() => VanillaBlocks::SWEET_BERRY_BUSH()); + $result->registerBlock("tall_grass", fn() => VanillaBlocks::FERN()); + $result->registerBlock("tallgrass", fn() => VanillaBlocks::FERN()); + $result->registerBlock("terracotta", fn() => VanillaBlocks::STAINED_CLAY()); + $result->registerBlock("tnt", fn() => VanillaBlocks::TNT()); + $result->registerBlock("torch", fn() => VanillaBlocks::TORCH()); + $result->registerBlock("trapdoor", fn() => VanillaBlocks::OAK_TRAPDOOR()); + $result->registerBlock("trapped_chest", fn() => VanillaBlocks::TRAPPED_CHEST()); + $result->registerBlock("trip_wire", fn() => VanillaBlocks::TRIPWIRE()); + $result->registerBlock("tripwire", fn() => VanillaBlocks::TRIPWIRE()); + $result->registerBlock("tripwire_hook", fn() => VanillaBlocks::TRIPWIRE_HOOK()); + $result->registerBlock("trunk", fn() => VanillaBlocks::OAK_PLANKS()); + $result->registerBlock("trunk2", fn() => VanillaBlocks::ACACIA_LOG()); + $result->registerBlock("underwater_torch", fn() => VanillaBlocks::UNDERWATER_TORCH()); + $result->registerBlock("undyed_shulker_box", fn() => VanillaBlocks::SHULKER_BOX()); + $result->registerBlock("unlit_redstone_torch", fn() => VanillaBlocks::REDSTONE_TORCH()); + $result->registerBlock("unpowered_comparator", fn() => VanillaBlocks::REDSTONE_COMPARATOR()); + $result->registerBlock("unpowered_comparator_block", fn() => VanillaBlocks::REDSTONE_COMPARATOR()); + $result->registerBlock("unpowered_repeater", fn() => VanillaBlocks::REDSTONE_REPEATER()); + $result->registerBlock("unpowered_repeater_block", fn() => VanillaBlocks::REDSTONE_REPEATER()); + $result->registerBlock("update_block", fn() => VanillaBlocks::INFO_UPDATE()); + $result->registerBlock("vine", fn() => VanillaBlocks::VINES()); + $result->registerBlock("vines", fn() => VanillaBlocks::VINES()); + $result->registerBlock("wall_banner", fn() => VanillaBlocks::WALL_BANNER()); + $result->registerBlock("wall_sign", fn() => VanillaBlocks::OAK_WALL_SIGN()); + $result->registerBlock("water", fn() => VanillaBlocks::WATER()); + $result->registerBlock("water_lily", fn() => VanillaBlocks::LILY_PAD()); + $result->registerBlock("waterlily", fn() => VanillaBlocks::LILY_PAD()); + $result->registerBlock("web", fn() => VanillaBlocks::COBWEB()); + $result->registerBlock("weighted_pressure_plate_heavy", fn() => VanillaBlocks::WEIGHTED_PRESSURE_PLATE_HEAVY()); + $result->registerBlock("weighted_pressure_plate_light", fn() => VanillaBlocks::WEIGHTED_PRESSURE_PLATE_LIGHT()); + $result->registerBlock("wheat_block", fn() => VanillaBlocks::WHEAT()); + $result->registerBlock("white_glazed_terracotta", fn() => VanillaBlocks::WHITE_GLAZED_TERRACOTTA()); + $result->registerBlock("wood", fn() => VanillaBlocks::OAK_LOG()); + $result->registerBlock("wood2", fn() => VanillaBlocks::ACACIA_LOG()); + $result->registerBlock("wood_door_block", fn() => VanillaBlocks::OAK_DOOR()); + $result->registerBlock("wood_slab", fn() => VanillaBlocks::OAK_SLAB()); + $result->registerBlock("wood_slabs", fn() => VanillaBlocks::OAK_SLAB()); + $result->registerBlock("wood_stairs", fn() => VanillaBlocks::OAK_STAIRS()); + $result->registerBlock("wooden_button", fn() => VanillaBlocks::OAK_BUTTON()); + $result->registerBlock("wooden_door", fn() => VanillaBlocks::OAK_DOOR()); + $result->registerBlock("wooden_door_block", fn() => VanillaBlocks::OAK_DOOR()); + $result->registerBlock("wooden_plank", fn() => VanillaBlocks::OAK_PLANKS()); + $result->registerBlock("wooden_planks", fn() => VanillaBlocks::OAK_PLANKS()); + $result->registerBlock("wooden_pressure_plate", fn() => VanillaBlocks::OAK_PRESSURE_PLATE()); + $result->registerBlock("wooden_slab", fn() => VanillaBlocks::OAK_SLAB()); + $result->registerBlock("wooden_slabs", fn() => VanillaBlocks::OAK_SLAB()); + $result->registerBlock("wooden_stairs", fn() => VanillaBlocks::OAK_STAIRS()); + $result->registerBlock("wooden_trapdoor", fn() => VanillaBlocks::OAK_TRAPDOOR()); + $result->registerBlock("wool", fn() => VanillaBlocks::WOOL()); + $result->registerBlock("workbench", fn() => VanillaBlocks::CRAFTING_TABLE()); + $result->registerBlock("yellow_flower", fn() => VanillaBlocks::DANDELION()); + $result->registerBlock("yellow_glazed_terracotta", fn() => VanillaBlocks::YELLOW_GLAZED_TERRACOTTA()); + + $result->register("apple", fn() => VanillaItems::APPLE()); + $result->register("apple_enchanted", fn() => VanillaItems::ENCHANTED_GOLDEN_APPLE()); + $result->register("appleenchanted", fn() => VanillaItems::ENCHANTED_GOLDEN_APPLE()); + $result->register("arrow", fn() => VanillaItems::ARROW()); + $result->register("baked_potato", fn() => VanillaItems::BAKED_POTATO()); + $result->register("baked_potatoes", fn() => VanillaItems::BAKED_POTATO()); + $result->register("bed", fn() => VanillaItems::WHITE_BED()); + $result->register("beef", fn() => VanillaItems::RAW_BEEF()); + $result->register("beetroot", fn() => VanillaItems::BEETROOT()); + $result->register("beetroot_seed", fn() => VanillaItems::BEETROOT_SEEDS()); + $result->register("beetroot_seeds", fn() => VanillaItems::BEETROOT_SEEDS()); + $result->register("beetroot_soup", fn() => VanillaItems::BEETROOT_SOUP()); + $result->register("blaze_powder", fn() => VanillaItems::BLAZE_POWDER()); + $result->register("blaze_rod", fn() => VanillaItems::BLAZE_ROD()); + $result->register("bleach", fn() => VanillaItems::BLEACH()); + $result->register("boat", fn() => VanillaItems::OAK_BOAT()); + $result->register("bone", fn() => VanillaItems::BONE()); + $result->register("book", fn() => VanillaItems::BOOK()); + $result->register("bottle_o_enchanting", fn() => VanillaItems::EXPERIENCE_BOTTLE()); + $result->register("bow", fn() => VanillaItems::BOW()); + $result->register("bowl", fn() => VanillaItems::BOWL()); + $result->register("bread", fn() => VanillaItems::BREAD()); + $result->register("brick", fn() => VanillaItems::BRICK()); + $result->register("bucket", fn() => VanillaItems::BUCKET()); + $result->register("carrot", fn() => VanillaItems::CARROT()); + $result->register("chain_boots", fn() => VanillaItems::CHAINMAIL_BOOTS()); + $result->register("chain_chestplate", fn() => VanillaItems::CHAINMAIL_CHESTPLATE()); + $result->register("chain_helmet", fn() => VanillaItems::CHAINMAIL_HELMET()); + $result->register("chain_leggings", fn() => VanillaItems::CHAINMAIL_LEGGINGS()); + $result->register("chainmail_boots", fn() => VanillaItems::CHAINMAIL_BOOTS()); + $result->register("chainmail_chestplate", fn() => VanillaItems::CHAINMAIL_CHESTPLATE()); + $result->register("chainmail_helmet", fn() => VanillaItems::CHAINMAIL_HELMET()); + $result->register("chainmail_leggings", fn() => VanillaItems::CHAINMAIL_LEGGINGS()); + $result->register("chicken", fn() => VanillaItems::RAW_CHICKEN()); + $result->register("chorus_fruit", fn() => VanillaItems::CHORUS_FRUIT()); + $result->register("chorus_fruit_popped", fn() => VanillaItems::POPPED_CHORUS_FRUIT()); + $result->register("clay", fn() => VanillaItems::CLAY()); + $result->register("clay_ball", fn() => VanillaItems::CLAY()); + $result->register("clock", fn() => VanillaItems::CLOCK()); + $result->register("clown_fish", fn() => VanillaItems::CLOWNFISH()); + $result->register("clownfish", fn() => VanillaItems::CLOWNFISH()); + $result->register("coal", fn() => VanillaItems::COAL()); + $result->register("compass", fn() => VanillaItems::COMPASS()); + $result->register("compound", fn() => VanillaItems::CHEMICAL_SALT()); + $result->register("cooked_beef", fn() => VanillaItems::STEAK()); + $result->register("cooked_chicken", fn() => VanillaItems::COOKED_CHICKEN()); + $result->register("cooked_fish", fn() => VanillaItems::COOKED_FISH()); + $result->register("cooked_mutton", fn() => VanillaItems::COOKED_MUTTON()); + $result->register("cooked_porkchop", fn() => VanillaItems::COOKED_PORKCHOP()); + $result->register("cooked_rabbit", fn() => VanillaItems::COOKED_RABBIT()); + $result->register("cooked_salmon", fn() => VanillaItems::COOKED_SALMON()); + $result->register("cookie", fn() => VanillaItems::COOKIE()); + $result->register("diamond", fn() => VanillaItems::DIAMOND()); + $result->register("diamond_axe", fn() => VanillaItems::DIAMOND_AXE()); + $result->register("diamond_boots", fn() => VanillaItems::DIAMOND_BOOTS()); + $result->register("diamond_chestplate", fn() => VanillaItems::DIAMOND_CHESTPLATE()); + $result->register("diamond_helmet", fn() => VanillaItems::DIAMOND_HELMET()); + $result->register("diamond_hoe", fn() => VanillaItems::DIAMOND_HOE()); + $result->register("diamond_leggings", fn() => VanillaItems::DIAMOND_LEGGINGS()); + $result->register("diamond_pickaxe", fn() => VanillaItems::DIAMOND_PICKAXE()); + $result->register("diamond_shovel", fn() => VanillaItems::DIAMOND_SHOVEL()); + $result->register("diamond_sword", fn() => VanillaItems::DIAMOND_SWORD()); + $result->register("dragon_breath", fn() => VanillaItems::DRAGON_BREATH()); + $result->register("dried_kelp", fn() => VanillaItems::DRIED_KELP()); + $result->register("dye", fn() => VanillaItems::INK_SAC()); + $result->register("egg", fn() => VanillaItems::EGG()); + $result->register("emerald", fn() => VanillaItems::EMERALD()); + $result->register("enchanted_golden_apple", fn() => VanillaItems::ENCHANTED_GOLDEN_APPLE()); + $result->register("enchanting_bottle", fn() => VanillaItems::EXPERIENCE_BOTTLE()); + $result->register("ender_pearl", fn() => VanillaItems::ENDER_PEARL()); + $result->register("experience_bottle", fn() => VanillaItems::EXPERIENCE_BOTTLE()); + $result->register("feather", fn() => VanillaItems::FEATHER()); + $result->register("fermented_spider_eye", fn() => VanillaItems::FERMENTED_SPIDER_EYE()); + $result->register("fish", fn() => VanillaItems::RAW_FISH()); + $result->register("fishing_rod", fn() => VanillaItems::FISHING_ROD()); + $result->register("flint", fn() => VanillaItems::FLINT()); + $result->register("flint_and_steel", fn() => VanillaItems::FLINT_AND_STEEL()); + $result->register("flint_steel", fn() => VanillaItems::FLINT_AND_STEEL()); + $result->register("ghast_tear", fn() => VanillaItems::GHAST_TEAR()); + $result->register("glass_bottle", fn() => VanillaItems::GLASS_BOTTLE()); + $result->register("glistering_melon", fn() => VanillaItems::GLISTERING_MELON()); + $result->register("glowstone_dust", fn() => VanillaItems::GLOWSTONE_DUST()); + $result->register("gold_axe", fn() => VanillaItems::GOLDEN_AXE()); + $result->register("gold_boots", fn() => VanillaItems::GOLDEN_BOOTS()); + $result->register("gold_chestplate", fn() => VanillaItems::GOLDEN_CHESTPLATE()); + $result->register("gold_helmet", fn() => VanillaItems::GOLDEN_HELMET()); + $result->register("gold_hoe", fn() => VanillaItems::GOLDEN_HOE()); + $result->register("gold_ingot", fn() => VanillaItems::GOLD_INGOT()); + $result->register("gold_leggings", fn() => VanillaItems::GOLDEN_LEGGINGS()); + $result->register("gold_nugget", fn() => VanillaItems::GOLD_NUGGET()); + $result->register("gold_pickaxe", fn() => VanillaItems::GOLDEN_PICKAXE()); + $result->register("gold_shovel", fn() => VanillaItems::GOLDEN_SHOVEL()); + $result->register("gold_sword", fn() => VanillaItems::GOLDEN_SWORD()); + $result->register("golden_apple", fn() => VanillaItems::GOLDEN_APPLE()); + $result->register("golden_axe", fn() => VanillaItems::GOLDEN_AXE()); + $result->register("golden_boots", fn() => VanillaItems::GOLDEN_BOOTS()); + $result->register("golden_carrot", fn() => VanillaItems::GOLDEN_CARROT()); + $result->register("golden_chestplate", fn() => VanillaItems::GOLDEN_CHESTPLATE()); + $result->register("golden_helmet", fn() => VanillaItems::GOLDEN_HELMET()); + $result->register("golden_hoe", fn() => VanillaItems::GOLDEN_HOE()); + $result->register("golden_leggings", fn() => VanillaItems::GOLDEN_LEGGINGS()); + $result->register("golden_nugget", fn() => VanillaItems::GOLD_NUGGET()); + $result->register("golden_pickaxe", fn() => VanillaItems::GOLDEN_PICKAXE()); + $result->register("golden_shovel", fn() => VanillaItems::GOLDEN_SHOVEL()); + $result->register("golden_sword", fn() => VanillaItems::GOLDEN_SWORD()); + $result->register("gunpowder", fn() => VanillaItems::GUNPOWDER()); + $result->register("heart_of_the_sea", fn() => VanillaItems::HEART_OF_THE_SEA()); + $result->register("iron_axe", fn() => VanillaItems::IRON_AXE()); + $result->register("iron_boots", fn() => VanillaItems::IRON_BOOTS()); + $result->register("iron_chestplate", fn() => VanillaItems::IRON_CHESTPLATE()); + $result->register("iron_helmet", fn() => VanillaItems::IRON_HELMET()); + $result->register("iron_hoe", fn() => VanillaItems::IRON_HOE()); + $result->register("iron_ingot", fn() => VanillaItems::IRON_INGOT()); + $result->register("iron_leggings", fn() => VanillaItems::IRON_LEGGINGS()); + $result->register("iron_nugget", fn() => VanillaItems::IRON_NUGGET()); + $result->register("iron_pickaxe", fn() => VanillaItems::IRON_PICKAXE()); + $result->register("iron_shovel", fn() => VanillaItems::IRON_SHOVEL()); + $result->register("iron_sword", fn() => VanillaItems::IRON_SWORD()); + $result->register("leather", fn() => VanillaItems::LEATHER()); + $result->register("leather_boots", fn() => VanillaItems::LEATHER_BOOTS()); + $result->register("leather_cap", fn() => VanillaItems::LEATHER_CAP()); + $result->register("leather_chestplate", fn() => VanillaItems::LEATHER_TUNIC()); + $result->register("leather_helmet", fn() => VanillaItems::LEATHER_CAP()); + $result->register("leather_leggings", fn() => VanillaItems::LEATHER_PANTS()); + $result->register("leather_pants", fn() => VanillaItems::LEATHER_PANTS()); + $result->register("leather_tunic", fn() => VanillaItems::LEATHER_TUNIC()); + $result->register("magma_cream", fn() => VanillaItems::MAGMA_CREAM()); + $result->register("melon", fn() => VanillaItems::MELON()); + $result->register("melon_seeds", fn() => VanillaItems::MELON_SEEDS()); + $result->register("melon_slice", fn() => VanillaItems::MELON()); + $result->register("minecart", fn() => VanillaItems::MINECART()); + $result->register("mob_head", fn() => VanillaItems::SKELETON_SKULL()); + $result->register("mushroom_stew", fn() => VanillaItems::MUSHROOM_STEW()); + $result->register("mutton", fn() => VanillaItems::RAW_MUTTON()); + $result->register("mutton_cooked", fn() => VanillaItems::COOKED_MUTTON()); + $result->register("mutton_raw", fn() => VanillaItems::RAW_MUTTON()); + $result->register("muttoncooked", fn() => VanillaItems::COOKED_MUTTON()); + $result->register("muttonraw", fn() => VanillaItems::RAW_MUTTON()); + $result->register("nautilus_shell", fn() => VanillaItems::NAUTILUS_SHELL()); + $result->register("nether_brick", fn() => VanillaItems::NETHER_BRICK()); + $result->register("nether_quartz", fn() => VanillaItems::NETHER_QUARTZ()); + $result->register("nether_star", fn() => VanillaItems::NETHER_STAR()); + $result->register("netherbrick", fn() => VanillaItems::NETHER_BRICK()); + $result->register("netherstar", fn() => VanillaItems::NETHER_STAR()); + $result->register("painting", fn() => VanillaItems::PAINTING()); + $result->register("paper", fn() => VanillaItems::PAPER()); + $result->register("poisonous_potato", fn() => VanillaItems::POISONOUS_POTATO()); + $result->register("porkchop", fn() => VanillaItems::RAW_PORKCHOP()); + $result->register("potato", fn() => VanillaItems::POTATO()); + $result->register("potion", fn() => VanillaItems::WATER_POTION()); + $result->register("prismarine_crystals", fn() => VanillaItems::PRISMARINE_CRYSTALS()); + $result->register("prismarine_shard", fn() => VanillaItems::PRISMARINE_SHARD()); + $result->register("puffer_fish", fn() => VanillaItems::PUFFERFISH()); + $result->register("pufferfish", fn() => VanillaItems::PUFFERFISH()); + $result->register("pumpkin_pie", fn() => VanillaItems::PUMPKIN_PIE()); + $result->register("pumpkin_seeds", fn() => VanillaItems::PUMPKIN_SEEDS()); + $result->register("quartz", fn() => VanillaItems::NETHER_QUARTZ()); + $result->register("rabbit", fn() => VanillaItems::RAW_RABBIT()); + $result->register("rabbit_foot", fn() => VanillaItems::RABBIT_FOOT()); + $result->register("rabbit_hide", fn() => VanillaItems::RABBIT_HIDE()); + $result->register("rabbit_stew", fn() => VanillaItems::RABBIT_STEW()); + $result->register("raw_beef", fn() => VanillaItems::RAW_BEEF()); + $result->register("raw_chicken", fn() => VanillaItems::RAW_CHICKEN()); + $result->register("raw_fish", fn() => VanillaItems::RAW_FISH()); + $result->register("raw_mutton", fn() => VanillaItems::RAW_MUTTON()); + $result->register("raw_porkchop", fn() => VanillaItems::RAW_PORKCHOP()); + $result->register("raw_rabbit", fn() => VanillaItems::RAW_RABBIT()); + $result->register("raw_salmon", fn() => VanillaItems::RAW_SALMON()); + $result->register("record_11", fn() => VanillaItems::RECORD_11()); + $result->register("record_13", fn() => VanillaItems::RECORD_13()); + $result->register("record_blocks", fn() => VanillaItems::RECORD_BLOCKS()); + $result->register("record_cat", fn() => VanillaItems::RECORD_CAT()); + $result->register("record_chirp", fn() => VanillaItems::RECORD_CHIRP()); + $result->register("record_far", fn() => VanillaItems::RECORD_FAR()); + $result->register("record_mall", fn() => VanillaItems::RECORD_MALL()); + $result->register("record_mellohi", fn() => VanillaItems::RECORD_MELLOHI()); + $result->register("record_stal", fn() => VanillaItems::RECORD_STAL()); + $result->register("record_strad", fn() => VanillaItems::RECORD_STRAD()); + $result->register("record_wait", fn() => VanillaItems::RECORD_WAIT()); + $result->register("record_ward", fn() => VanillaItems::RECORD_WARD()); + $result->register("redstone", fn() => VanillaItems::REDSTONE_DUST()); + $result->register("redstone_dust", fn() => VanillaItems::REDSTONE_DUST()); + $result->register("rotten_flesh", fn() => VanillaItems::ROTTEN_FLESH()); + $result->register("salmon", fn() => VanillaItems::RAW_SALMON()); + $result->register("seeds", fn() => VanillaItems::WHEAT_SEEDS()); + $result->register("shears", fn() => VanillaItems::SHEARS()); + $result->register("shulker_shell", fn() => VanillaItems::SHULKER_SHELL()); + $result->register("skull", fn() => VanillaItems::SKELETON_SKULL()); + $result->register("slime_ball", fn() => VanillaItems::SLIMEBALL()); + $result->register("slimeball", fn() => VanillaItems::SLIMEBALL()); + $result->register("snowball", fn() => VanillaItems::SNOWBALL()); + $result->register("speckled_melon", fn() => VanillaItems::GLISTERING_MELON()); + $result->register("spider_eye", fn() => VanillaItems::SPIDER_EYE()); + $result->register("splash_potion", fn() => VanillaItems::WATER_SPLASH_POTION()); + $result->register("steak", fn() => VanillaItems::STEAK()); + $result->register("stick", fn() => VanillaItems::STICK()); + $result->register("sticks", fn() => VanillaItems::STICK()); + $result->register("stone_axe", fn() => VanillaItems::STONE_AXE()); + $result->register("stone_hoe", fn() => VanillaItems::STONE_HOE()); + $result->register("stone_pickaxe", fn() => VanillaItems::STONE_PICKAXE()); + $result->register("stone_shovel", fn() => VanillaItems::STONE_SHOVEL()); + $result->register("stone_sword", fn() => VanillaItems::STONE_SWORD()); + $result->register("string", fn() => VanillaItems::STRING()); + $result->register("sugar", fn() => VanillaItems::SUGAR()); + $result->register("sweet_berries", fn() => VanillaItems::SWEET_BERRIES()); + $result->register("totem", fn() => VanillaItems::TOTEM()); + $result->register("turtle_shell_piece", fn() => VanillaItems::SCUTE()); + $result->register("wheat", fn() => VanillaItems::WHEAT()); + $result->register("wheat_seeds", fn() => VanillaItems::WHEAT_SEEDS()); + $result->register("wooden_axe", fn() => VanillaItems::WOODEN_AXE()); + $result->register("wooden_hoe", fn() => VanillaItems::WOODEN_HOE()); + $result->register("wooden_pickaxe", fn() => VanillaItems::WOODEN_PICKAXE()); + $result->register("wooden_shovel", fn() => VanillaItems::WOODEN_SHOVEL()); + $result->register("wooden_sword", fn() => VanillaItems::WOODEN_SWORD()); + $result->register("writable_book", fn() => VanillaItems::WRITABLE_BOOK()); + $result->register("written_book", fn() => VanillaItems::WRITTEN_BOOK()); + + return $result; + } + + /** @phpstan-param \Closure(string $input) : Item $callback */ + public function register(string $alias, \Closure $callback) : void{ + $key = $this->reprocess($alias); + if(isset($this->callbackMap[$key])){ + throw new \InvalidArgumentException("Alias \"$key\" is already registered"); + } + $this->callbackMap[$key] = $callback; + } + + /** @phpstan-param \Closure(string $input) : Block $callback */ + public function registerBlock(string $alias, \Closure $callback) : void{ + $this->register($alias, fn(string $input) => $callback($input)->asItem()); + } + + /** @phpstan-param \Closure(string $input) : Item $callback */ + public function override(string $alias, \Closure $callback) : void{ + $this->callbackMap[$this->reprocess($alias)] = $callback; + } + + /** Tries to parse the specified string into an item. */ + public function parse(string $input) : ?Item{ + $key = $this->reprocess($input); + if(isset($this->callbackMap[$key])){ + return ($this->callbackMap[$key])($input); + } + + return null; + } + + protected function reprocess(string $input) : string{ + return strtolower(str_replace([" ", "minecraft:"], ["_", ""], trim($input))); + } + + /** @return string[] */ + public function getKnownAliases() : array{ + return array_keys($this->callbackMap); + } +} From 7fd712c1ff5e33c2df8e888f8b3986947f3f4eb4 Mon Sep 17 00:00:00 2001 From: SalmonDE Date: Mon, 23 Aug 2021 15:01:32 +0200 Subject: [PATCH 2738/3224] Refactor Block & Tile: getPos() to getPosition() (#4395) this also changes the name of the class property 'pos' to 'position' as well as Block->getPosOffset() to Block->getPositionOffset() --- src/block/Anvil.php | 2 +- src/block/Bamboo.php | 34 +++++----- src/block/BambooSapling.php | 24 +++---- src/block/Barrel.php | 8 +-- src/block/BaseBanner.php | 6 +- src/block/BaseCoral.php | 6 +- src/block/BaseRail.php | 8 +-- src/block/BaseSign.php | 8 +-- src/block/Bed.php | 14 ++-- src/block/Bell.php | 16 ++--- src/block/Block.php | 46 +++++++------- src/block/BrewingStand.php | 2 +- src/block/Button.php | 10 +-- src/block/Cactus.php | 14 ++-- src/block/Cake.php | 4 +- src/block/Carpet.php | 2 +- src/block/Chest.php | 6 +- src/block/CocoaBlock.php | 6 +- src/block/ConcretePowder.php | 2 +- src/block/Coral.php | 12 ++-- src/block/CoralBlock.php | 8 +-- src/block/Crops.php | 6 +- src/block/DaylightSensor.php | 10 +-- src/block/DeadBush.php | 2 +- src/block/Dirt.php | 2 +- src/block/Door.php | 10 +-- src/block/DoublePlant.php | 4 +- src/block/DragonEgg.php | 16 ++--- src/block/EnchantingTable.php | 2 +- src/block/EnderChest.php | 4 +- src/block/Farmland.php | 14 ++-- src/block/FenceGate.php | 6 +- src/block/Fire.php | 12 ++-- src/block/FloorCoralFan.php | 10 +-- src/block/Flower.php | 2 +- src/block/FlowerPot.php | 8 +-- src/block/FrostedIce.php | 16 ++--- src/block/Furnace.php | 6 +- src/block/Grass.php | 26 ++++---- src/block/GrassPath.php | 2 +- src/block/Hopper.php | 2 +- src/block/Ice.php | 6 +- src/block/ItemFrame.php | 12 ++-- src/block/Jukebox.php | 12 ++-- src/block/Ladder.php | 4 +- src/block/Lantern.php | 8 +-- src/block/Leaves.php | 10 +-- src/block/Lever.php | 8 +-- src/block/Liquid.php | 88 +++++++++++++------------- src/block/Loom.php | 2 +- src/block/Mycelium.php | 10 +-- src/block/NetherWartPlant.php | 4 +- src/block/Note.php | 4 +- src/block/RedMushroom.php | 2 +- src/block/RedstoneComparator.php | 8 +-- src/block/RedstoneOre.php | 6 +- src/block/RedstoneRepeater.php | 4 +- src/block/Sapling.php | 10 +-- src/block/ShulkerBox.php | 10 +-- src/block/Skull.php | 4 +- src/block/SnowLayer.php | 4 +- src/block/Stem.php | 4 +- src/block/Sugarcane.php | 12 ++-- src/block/SweetBerryBush.php | 10 +-- src/block/TNT.php | 4 +- src/block/TallGrass.php | 2 +- src/block/Torch.php | 2 +- src/block/Trapdoor.php | 4 +- src/block/Vine.php | 4 +- src/block/WallCoralFan.php | 6 +- src/block/WaterLily.php | 2 +- src/block/tile/Barrel.php | 2 +- src/block/tile/Bell.php | 2 +- src/block/tile/BrewingStand.php | 2 +- src/block/tile/Chest.php | 22 +++---- src/block/tile/ContainerTrait.php | 4 +- src/block/tile/Furnace.php | 8 +-- src/block/tile/Hopper.php | 2 +- src/block/tile/ShulkerBox.php | 2 +- src/block/tile/Spawnable.php | 6 +- src/block/tile/Tile.php | 20 +++--- src/block/utils/FallableTrait.php | 4 +- src/entity/projectile/Projectile.php | 4 +- src/entity/projectile/SplashPotion.php | 4 +- src/item/Bucket.php | 4 +- src/item/FlintSteel.php | 4 +- src/item/LiquidBucket.php | 4 +- src/item/PaintingItem.php | 6 +- src/item/SpawnEgg.php | 2 +- src/player/Player.php | 4 +- src/world/Explosion.php | 6 +- src/world/World.php | 24 +++---- src/world/format/Chunk.php | 4 +- 93 files changed, 402 insertions(+), 402 deletions(-) diff --git a/src/block/Anvil.php b/src/block/Anvil.php index 946c78c27e..48fade268d 100644 --- a/src/block/Anvil.php +++ b/src/block/Anvil.php @@ -78,7 +78,7 @@ class Anvil extends Transparent implements Fallable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $player->setCurrentWindow(new AnvilInventory($this->pos)); + $player->setCurrentWindow(new AnvilInventory($this->position)); } return true; diff --git a/src/block/Bamboo.php b/src/block/Bamboo.php index 87ec7de2e5..7e1e7f1da4 100644 --- a/src/block/Bamboo.php +++ b/src/block/Bamboo.php @@ -114,8 +114,8 @@ class Bamboo extends Transparent{ return 12 + (self::getOffsetSeed($x, 0, $z) % 5); } - public function getPosOffset() : ?Vector3{ - $seed = self::getOffsetSeed($this->pos->getFloorX(), 0, $this->pos->getFloorZ()); + public function getPositionOffset() : ?Vector3{ + $seed = self::getOffsetSeed($this->position->getFloorX(), 0, $this->position->getFloorZ()); $retX = (($seed % 12) + 1) / 16; $retZ = ((($seed >> 8) % 12) + 1) / 16; return new Vector3($retX, 0, $retZ); @@ -133,9 +133,9 @@ class Bamboo extends Transparent{ } private function seekToTop() : Bamboo{ - $world = $this->pos->getWorld(); + $world = $this->position->getWorld(); $top = $this; - while(($next = $world->getBlock($top->pos->up())) instanceof Bamboo && $next->isSameType($this)){ + while(($next = $world->getBlock($top->position->up())) instanceof Bamboo && $next->isSameType($this)){ $top = $next; } return $top; @@ -144,7 +144,7 @@ class Bamboo extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof Fertilizer){ $top = $this->seekToTop(); - if($top->grow(self::getMaxHeight($top->pos->getFloorX(), $top->pos->getFloorZ()), mt_rand(1, 2))){ + if($top->grow(self::getMaxHeight($top->position->getFloorX(), $top->position->getFloorZ()), mt_rand(1, 2))){ $item->pop(); return true; } @@ -158,20 +158,20 @@ class Bamboo extends Transparent{ } public function onNearbyBlockChange() : void{ - $below = $this->pos->getWorld()->getBlock($this->pos->down()); + $below = $this->position->getWorld()->getBlock($this->position->down()); if(!$this->canBeSupportedBy($below) and !$below->isSameType($this)){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } private function grow(int $maxHeight, int $growAmount) : bool{ - $world = $this->pos->getWorld(); - if(!$world->getBlock($this->pos->up())->canBeReplaced()){ + $world = $this->position->getWorld(); + if(!$world->getBlock($this->position->up())->canBeReplaced()){ return false; } $height = 1; - while($world->getBlock($this->pos->subtract(0, $height, 0))->isSameType($this)){ + while($world->getBlock($this->position->subtract(0, $height, 0))->isSameType($this)){ if(++$height >= $maxHeight){ return false; } @@ -206,9 +206,9 @@ class Bamboo extends Transparent{ } } - $tx = new BlockTransaction($this->pos->getWorld()); + $tx = new BlockTransaction($this->position->getWorld()); foreach($newBlocks as $idx => $newBlock){ - $tx->addBlock($this->pos->subtract(0, $idx - $growAmount, 0), $newBlock); + $tx->addBlock($this->position->subtract(0, $idx - $growAmount, 0), $newBlock); } return $tx->apply(); } @@ -218,15 +218,15 @@ class Bamboo extends Transparent{ } public function onRandomTick() : void{ - $world = $this->pos->getWorld(); + $world = $this->position->getWorld(); if($this->ready){ $this->ready = false; - if($world->getFullLight($this->pos) < 9 || !$this->grow(self::getMaxHeight($this->pos->getFloorX(), $this->pos->getFloorZ()), 1)){ - $world->setBlock($this->pos, $this); + if($world->getFullLight($this->position) < 9 || !$this->grow(self::getMaxHeight($this->position->getFloorX(), $this->position->getFloorZ()), 1)){ + $world->setBlock($this->position, $this); } - }elseif($world->getBlock($this->pos->up())->canBeReplaced()){ + }elseif($world->getBlock($this->position->up())->canBeReplaced()){ $this->ready = true; - $world->setBlock($this->pos, $this); + $world->setBlock($this->position, $this); } } } diff --git a/src/block/BambooSapling.php b/src/block/BambooSapling.php index 5a35b0bb1a..e01094912a 100644 --- a/src/block/BambooSapling.php +++ b/src/block/BambooSapling.php @@ -64,7 +64,7 @@ final class BambooSapling extends Flowable{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canBeSupportedBy($blockReplace->pos->getWorld()->getBlock($blockReplace->pos->down()))){ + if(!$this->canBeSupportedBy($blockReplace->position->getWorld()->getBlock($blockReplace->position->down()))){ return false; } return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); @@ -81,21 +81,21 @@ final class BambooSapling extends Flowable{ } public function onNearbyBlockChange() : void{ - if(!$this->canBeSupportedBy($this->pos->getWorld()->getBlock($this->pos->down()))){ - $this->pos->getWorld()->useBreakOn($this->pos); + if(!$this->canBeSupportedBy($this->position->getWorld()->getBlock($this->position->down()))){ + $this->position->getWorld()->useBreakOn($this->position); } } private function grow() : bool{ - $world = $this->pos->getWorld(); - if(!$world->getBlock($this->pos->up())->canBeReplaced()){ + $world = $this->position->getWorld(); + if(!$world->getBlock($this->position->up())->canBeReplaced()){ return false; } $tx = new BlockTransaction($world); $bamboo = VanillaBlocks::BAMBOO(); - $tx->addBlock($this->pos, $bamboo) - ->addBlock($this->pos->up(), (clone $bamboo)->setLeafSize(Bamboo::SMALL_LEAVES)); + $tx->addBlock($this->position, $bamboo) + ->addBlock($this->position->up(), (clone $bamboo)->setLeafSize(Bamboo::SMALL_LEAVES)); return $tx->apply(); } @@ -104,15 +104,15 @@ final class BambooSapling extends Flowable{ } public function onRandomTick() : void{ - $world = $this->pos->getWorld(); + $world = $this->position->getWorld(); if($this->ready){ $this->ready = false; - if($world->getFullLight($this->pos) < 9 || !$this->grow()){ - $world->setBlock($this->pos, $this); + if($world->getFullLight($this->position) < 9 || !$this->grow()){ + $world->setBlock($this->position, $this); } - }elseif($world->getBlock($this->pos->up())->canBeReplaced()){ + }elseif($world->getBlock($this->position->up())->canBeReplaced()){ $this->ready = true; - $world->setBlock($this->pos, $this); + $world->setBlock($this->position, $this); } } diff --git a/src/block/Barrel.php b/src/block/Barrel.php index 40ee03d770..a9d992abf5 100644 --- a/src/block/Barrel.php +++ b/src/block/Barrel.php @@ -63,12 +63,12 @@ class Barrel extends Opaque{ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ - if(abs($player->getPosition()->getX() - $this->pos->getX()) < 2 && abs($player->getPosition()->getZ() - $this->pos->getZ()) < 2){ + if(abs($player->getPosition()->getX() - $this->position->getX()) < 2 && abs($player->getPosition()->getZ() - $this->position->getZ()) < 2){ $y = $player->getEyePos()->getY(); - if($y - $this->pos->getY() > 2){ + if($y - $this->position->getY() > 2){ $this->facing = Facing::UP; - }elseif($this->pos->getY() - $y > 0){ + }elseif($this->position->getY() - $y > 0){ $this->facing = Facing::DOWN; }else{ $this->facing = Facing::opposite($player->getHorizontalFacing()); @@ -83,7 +83,7 @@ class Barrel extends Opaque{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $barrel = $this->pos->getWorld()->getTile($this->pos); + $barrel = $this->position->getWorld()->getTile($this->position); if($barrel instanceof TileBarrel){ if(!$barrel->canOpenWith($item->getCustomName())){ return true; diff --git a/src/block/BaseBanner.php b/src/block/BaseBanner.php index 36a637864e..0f7d55ae59 100644 --- a/src/block/BaseBanner.php +++ b/src/block/BaseBanner.php @@ -54,7 +54,7 @@ abstract class BaseBanner extends Transparent{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->pos->getWorld()->getTile($this->pos); + $tile = $this->position->getWorld()->getTile($this->position); if($tile instanceof TileBanner){ $this->color = $tile->getBaseColor(); $this->setPatterns($tile->getPatterns()); @@ -63,7 +63,7 @@ abstract class BaseBanner extends Transparent{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->pos->getWorld()->getTile($this->pos); + $tile = $this->position->getWorld()->getTile($this->position); assert($tile instanceof TileBanner); $tile->setBaseColor($this->color); $tile->setPatterns($this->patterns); @@ -120,7 +120,7 @@ abstract class BaseBanner extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide($this->getSupportingFace())->getId() === BlockLegacyIds::AIR){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } diff --git a/src/block/BaseCoral.php b/src/block/BaseCoral.php index 99af72324c..f3b37988a8 100644 --- a/src/block/BaseCoral.php +++ b/src/block/BaseCoral.php @@ -54,10 +54,10 @@ abstract class BaseCoral extends Transparent{ public function onNearbyBlockChange() : void{ if(!$this->dead){ - $world = $this->pos->getWorld(); + $world = $this->position->getWorld(); $hasWater = false; - foreach($this->pos->sides() as $vector3){ + foreach($this->position->sides() as $vector3){ if($world->getBlock($vector3) instanceof Water){ $hasWater = true; break; @@ -66,7 +66,7 @@ abstract class BaseCoral extends Transparent{ //TODO: check water inside the block itself (not supported on the API yet) if(!$hasWater){ - $world->setBlock($this->pos, $this->setDead(true)); + $world->setBlock($this->position, $this->setDead(true)); } } } diff --git a/src/block/BaseRail.php b/src/block/BaseRail.php index 52ff91dfa6..bf117cd7cc 100644 --- a/src/block/BaseRail.php +++ b/src/block/BaseRail.php @@ -189,7 +189,7 @@ abstract class BaseRail extends Flowable{ if(isset($otherPossible[$otherSide])){ $otherConnections[] = $otherSide; $other->setConnections($otherConnections); - $this->pos->getWorld()->setBlock($other->pos, $other); + $this->position->getWorld()->setBlock($other->position, $other); $changed = true; $thisConnections[] = $thisSide; @@ -202,7 +202,7 @@ abstract class BaseRail extends Flowable{ if($changed){ $this->setConnections($thisConnections); - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); } } @@ -221,11 +221,11 @@ abstract class BaseRail extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); }else{ foreach($this->getCurrentShapeConnections() as $connection){ if(($connection & RailConnectionInfo::FLAG_ASCEND) !== 0 and $this->getSide($connection & ~RailConnectionInfo::FLAG_ASCEND)->isTransparent()){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); break; } } diff --git a/src/block/BaseSign.php b/src/block/BaseSign.php index c2eedd1d06..586eee6a13 100644 --- a/src/block/BaseSign.php +++ b/src/block/BaseSign.php @@ -49,7 +49,7 @@ abstract class BaseSign extends Transparent{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->pos->getWorld()->getTile($this->pos); + $tile = $this->position->getWorld()->getTile($this->position); if($tile instanceof TileSign){ $this->text = $tile->getText(); $this->editorEntityRuntimeId = $tile->getEditorEntityRuntimeId(); @@ -58,7 +58,7 @@ abstract class BaseSign extends Transparent{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->pos->getWorld()->getTile($this->pos); + $tile = $this->position->getWorld()->getTile($this->position); assert($tile instanceof TileSign); $tile->setText($this->text); $tile->setEditorEntityRuntimeId($this->editorEntityRuntimeId); @@ -83,7 +83,7 @@ abstract class BaseSign extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide($this->getSupportingFace())->getId() === BlockLegacyIds::AIR){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } @@ -130,7 +130,7 @@ abstract class BaseSign extends Transparent{ $ev->call(); if(!$ev->isCancelled()){ $this->setText($ev->getNewText()); - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); return true; } diff --git a/src/block/Bed.php b/src/block/Bed.php index dd63c4a0d5..a9d4873976 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -70,7 +70,7 @@ class Bed extends Transparent{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); //read extra state information from the tile - this is an ugly hack - $tile = $this->pos->getWorld()->getTile($this->pos); + $tile = $this->position->getWorld()->getTile($this->position); if($tile instanceof TileBed){ $this->color = $tile->getColor(); } @@ -79,7 +79,7 @@ class Bed extends Transparent{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); //extra block properties storage hack - $tile = $this->pos->getWorld()->getTile($this->pos); + $tile = $this->position->getWorld()->getTile($this->position); if($tile instanceof TileBed){ $tile->setColor($this->color); } @@ -133,12 +133,12 @@ class Bed extends Transparent{ $player->sendMessage(TextFormat::GRAY . "This bed is incomplete"); return true; - }elseif($playerPos->distanceSquared($this->pos) > 4 and $playerPos->distanceSquared($other->pos) > 4){ + }elseif($playerPos->distanceSquared($this->position) > 4 and $playerPos->distanceSquared($other->position) > 4){ $player->sendMessage(KnownTranslationFactory::tile_bed_tooFar()->prefix(TextFormat::GRAY)); return true; } - $time = $this->pos->getWorld()->getTimeOfDay(); + $time = $this->position->getWorld()->getTimeOfDay(); $isNight = ($time >= World::TIME_NIGHT and $time < World::TIME_SUNRISE); @@ -156,7 +156,7 @@ class Bed extends Transparent{ return true; } - $player->sleepOn($b->pos); + $player->sleepOn($b->position); } return true; @@ -166,7 +166,7 @@ class Bed extends Transparent{ public function onNearbyBlockChange() : void{ if(($other = $this->getOtherHalf()) !== null and $other->occupied !== $this->occupied){ $this->occupied = $other->occupied; - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); } } @@ -179,7 +179,7 @@ class Bed extends Transparent{ if($next->canBeReplaced() and !$next->getSide(Facing::DOWN)->isTransparent()){ $nextState = clone $this; $nextState->head = true; - $tx->addBlock($blockReplace->pos, $this)->addBlock($next->pos, $nextState); + $tx->addBlock($blockReplace->position, $this)->addBlock($next->position, $nextState); return true; } } diff --git a/src/block/Bell.php b/src/block/Bell.php index 954e55c1c4..1cffd606bc 100644 --- a/src/block/Bell.php +++ b/src/block/Bell.php @@ -95,7 +95,7 @@ final class Bell extends Transparent{ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP){ - if(!$this->canBeSupportedBy($tx->fetchBlock($this->pos->down()))){ + if(!$this->canBeSupportedBy($tx->fetchBlock($this->position->down()))){ return false; } if($player !== null){ @@ -103,18 +103,18 @@ final class Bell extends Transparent{ } $this->setAttachmentType(BellAttachmentType::FLOOR()); }elseif($face === Facing::DOWN){ - if(!$this->canBeSupportedBy($tx->fetchBlock($this->pos->up()))){ + if(!$this->canBeSupportedBy($tx->fetchBlock($this->position->up()))){ return false; } $this->setAttachmentType(BellAttachmentType::CEILING()); }else{ $this->setFacing($face); - if($this->canBeSupportedBy($tx->fetchBlock($this->pos->getSide(Facing::opposite($face))))){ + if($this->canBeSupportedBy($tx->fetchBlock($this->position->getSide(Facing::opposite($face))))){ $this->setAttachmentType(BellAttachmentType::ONE_WALL()); }else{ return false; } - if($this->canBeSupportedBy($tx->fetchBlock($this->pos->getSide($face)))){ + if($this->canBeSupportedBy($tx->fetchBlock($this->position->getSide($face)))){ $this->setAttachmentType(BellAttachmentType::TWO_WALLS()); } } @@ -128,7 +128,7 @@ final class Bell extends Transparent{ ($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) && !$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing)))) || ($this->attachmentType->equals(BellAttachmentType::TWO_WALLS()) && (!$this->canBeSupportedBy($this->getSide($this->facing)) || !$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing))))) ){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } @@ -153,10 +153,10 @@ final class Bell extends Transparent{ } public function ring(int $faceHit) : void{ - $this->pos->getWorld()->addSound($this->pos, new BellRingSound()); - $tile = $this->pos->getWorld()->getTile($this->pos); + $this->position->getWorld()->addSound($this->position, new BellRingSound()); + $tile = $this->position->getWorld()->getTile($this->position); if($tile instanceof TileBell){ - $this->pos->getWorld()->broadcastPacketToViewers($this->pos, $tile->createFakeUpdatePacket($faceHit)); + $this->position->getWorld()->broadcastPacketToViewers($this->position, $tile->createFakeUpdatePacket($faceHit)); } } } diff --git a/src/block/Block.php b/src/block/Block.php index 762063dcc6..247f9e3dc8 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -54,7 +54,7 @@ class Block{ protected BlockIdentifier $idInfo; protected string $fallbackName; protected BlockBreakInfo $breakInfo; - protected Position $pos; + protected Position $position; /** @var AxisAlignedBB[]|null */ protected ?array $collisionBoxes = null; @@ -69,11 +69,11 @@ class Block{ $this->idInfo = $idInfo; $this->fallbackName = $name; $this->breakInfo = $breakInfo; - $this->pos = new Position(0, 0, 0, null); + $this->position = new Position(0, 0, 0, null); } public function __clone(){ - $this->pos = clone $this->pos; + $this->position = clone $this->position; } public function getIdInfo() : BlockIdentifier{ @@ -142,10 +142,10 @@ class Block{ } public function writeStateToWorld() : void{ - $this->pos->getWorld()->getOrLoadChunkAtPosition($this->pos)->setFullBlock($this->pos->x & 0xf, $this->pos->y, $this->pos->z & 0xf, $this->getFullId()); + $this->position->getWorld()->getOrLoadChunkAtPosition($this->position)->setFullBlock($this->position->x & 0xf, $this->position->y, $this->position->z & 0xf, $this->getFullId()); $tileType = $this->idInfo->getTileClass(); - $oldTile = $this->pos->getWorld()->getTile($this->pos); + $oldTile = $this->position->getWorld()->getTile($this->position); if($oldTile !== null){ if($tileType === null or !($oldTile instanceof $tileType)){ $oldTile->close(); @@ -159,8 +159,8 @@ class Block{ * @var Tile $tile * @see Tile::__construct() */ - $tile = new $tileType($this->pos->getWorld(), $this->pos->asVector3()); - $this->pos->getWorld()->addTile($tile); + $tile = new $tileType($this->position->getWorld(), $this->position->asVector3()); + $this->position->getWorld()->addTile($tile); } } @@ -200,7 +200,7 @@ class Block{ * Places the Block, using block space and block target, and side. Returns if the block has been placed. */ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - $tx->addBlock($blockReplace->pos, $this); + $tx->addBlock($blockReplace->position, $this); return true; } @@ -219,10 +219,10 @@ class Block{ * Do the actions needed so the block is broken with the Item */ public function onBreak(Item $item, ?Player $player = null) : bool{ - if(($t = $this->pos->getWorld()->getTile($this->pos)) !== null){ + if(($t = $this->position->getWorld()->getTile($this->position)) !== null){ $t->onBlockDestroyed(); } - $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); + $this->position->getWorld()->setBlock($this->position, VanillaBlocks::AIR()); return true; } @@ -334,15 +334,15 @@ class Block{ return null; } - final public function getPos() : Position{ - return $this->pos; + final public function getPosition() : Position{ + return $this->position; } /** * @internal */ final public function position(World $world, int $x, int $y, int $z) : void{ - $this->pos = new Position($x, $y, $z, $world); + $this->position = new Position($x, $y, $z, $world); } /** @@ -420,7 +420,7 @@ class Block{ public function getPickedItem(bool $addUserData = false) : Item{ $item = $this->asItem(); if($addUserData){ - $tile = $this->pos->getWorld()->getTile($this->pos); + $tile = $this->position->getWorld()->getTile($this->position); if($tile instanceof Tile){ $nbt = $tile->getCleanedNBT(); if($nbt instanceof CompoundTag){ @@ -488,8 +488,8 @@ class Block{ * @return Block */ public function getSide(int $side, int $step = 1){ - if($this->pos->isValid()){ - return $this->pos->getWorld()->getBlock($this->pos->getSide($side, $step)); + if($this->position->isValid()){ + return $this->position->getWorld()->getBlock($this->position->getSide($side, $step)); } throw new \InvalidStateException("Block does not have a valid world"); @@ -502,8 +502,8 @@ class Block{ * @phpstan-return \Generator */ public function getHorizontalSides() : \Generator{ - $world = $this->pos->getWorld(); - foreach($this->pos->sidesAroundAxis(Axis::Y) as $vector3){ + $world = $this->position->getWorld(); + foreach($this->position->sidesAroundAxis(Axis::Y) as $vector3){ yield $world->getBlock($vector3); } } @@ -515,8 +515,8 @@ class Block{ * @phpstan-return \Generator */ public function getAllSides() : \Generator{ - $world = $this->pos->getWorld(); - foreach($this->pos->sides() as $vector3){ + $world = $this->position->getWorld(); + foreach($this->position->sides() as $vector3){ yield $world->getBlock($vector3); } } @@ -568,8 +568,8 @@ class Block{ final public function getCollisionBoxes() : array{ if($this->collisionBoxes === null){ $this->collisionBoxes = $this->recalculateCollisionBoxes(); - $extraOffset = $this->getPosOffset(); - $offset = $extraOffset !== null ? $this->pos->addVector($extraOffset) : $this->pos; + $extraOffset = $this->getPositionOffset(); + $offset = $extraOffset !== null ? $this->position->addVector($extraOffset) : $this->position; foreach($this->collisionBoxes as $bb){ $bb->offset($offset->x, $offset->y, $offset->z); } @@ -582,7 +582,7 @@ class Block{ * Returns an additional fractional vector to shift the block's effective position by based on the current position. * Used to randomize position of things like bamboo canes and tall grass. */ - public function getPosOffset() : ?Vector3{ + public function getPositionOffset() : ?Vector3{ return null; } diff --git a/src/block/BrewingStand.php b/src/block/BrewingStand.php index 2afe267a50..8d631453f5 100644 --- a/src/block/BrewingStand.php +++ b/src/block/BrewingStand.php @@ -99,7 +99,7 @@ class BrewingStand extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $stand = $this->pos->getWorld()->getTile($this->pos); + $stand = $this->position->getWorld()->getTile($this->position); if($stand instanceof TileBrewingStand and $stand->canOpenWith($item->getCustomName())){ $player->setCurrentWindow($stand->getInventory()); } diff --git a/src/block/Button.php b/src/block/Button.php index 0b9f88ed3c..9168bbd169 100644 --- a/src/block/Button.php +++ b/src/block/Button.php @@ -71,9 +71,9 @@ abstract class Button extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$this->pressed){ $this->pressed = true; - $this->pos->getWorld()->setBlock($this->pos, $this); - $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, $this->getActivationTime()); - $this->pos->getWorld()->addSound($this->pos->add(0.5, 0.5, 0.5), new RedstonePowerOnSound()); + $this->position->getWorld()->setBlock($this->position, $this); + $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, $this->getActivationTime()); + $this->position->getWorld()->addSound($this->position->add(0.5, 0.5, 0.5), new RedstonePowerOnSound()); } return true; @@ -82,8 +82,8 @@ abstract class Button extends Flowable{ public function onScheduledUpdate() : void{ if($this->pressed){ $this->pressed = false; - $this->pos->getWorld()->setBlock($this->pos, $this); - $this->pos->getWorld()->addSound($this->pos->add(0.5, 0.5, 0.5), new RedstonePowerOffSound()); + $this->position->getWorld()->setBlock($this->position, $this); + $this->position->getWorld()->addSound($this->position->add(0.5, 0.5, 0.5), new RedstonePowerOffSound()); } } } diff --git a/src/block/Cactus.php b/src/block/Cactus.php index 48a0349142..56ee7017fe 100644 --- a/src/block/Cactus.php +++ b/src/block/Cactus.php @@ -83,12 +83,12 @@ class Cactus extends Transparent{ public function onNearbyBlockChange() : void{ $down = $this->getSide(Facing::DOWN); if($down->getId() !== BlockLegacyIds::SAND and !$down->isSameType($this)){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); }else{ foreach(Facing::HORIZONTAL as $side){ $b = $this->getSide($side); if($b->isSolid()){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); break; } } @@ -103,26 +103,26 @@ class Cactus extends Transparent{ if(!$this->getSide(Facing::DOWN)->isSameType($this)){ if($this->age === 15){ for($y = 1; $y < 3; ++$y){ - if(!$this->pos->getWorld()->isInWorld($this->pos->x, $this->pos->y + $y, $this->pos->z)){ + if(!$this->position->getWorld()->isInWorld($this->position->x, $this->position->y + $y, $this->position->z)){ break; } - $b = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z); + $b = $this->position->getWorld()->getBlockAt($this->position->x, $this->position->y + $y, $this->position->z); if($b->getId() === BlockLegacyIds::AIR){ $ev = new BlockGrowEvent($b, VanillaBlocks::CACTUS()); $ev->call(); if($ev->isCancelled()){ break; } - $this->pos->getWorld()->setBlock($b->pos, $ev->getNewState()); + $this->position->getWorld()->setBlock($b->position, $ev->getNewState()); }else{ break; } } $this->age = 0; - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); }else{ ++$this->age; - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); } } } diff --git a/src/block/Cake.php b/src/block/Cake.php index 6dcf251a94..75030c659d 100644 --- a/src/block/Cake.php +++ b/src/block/Cake.php @@ -84,7 +84,7 @@ class Cake extends Transparent implements FoodSource{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ //Replace with common break method - $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); + $this->position->getWorld()->setBlock($this->position, VanillaBlocks::AIR()); } } @@ -133,6 +133,6 @@ class Cake extends Transparent implements FoodSource{ } public function onConsume(Living $consumer) : void{ - $this->pos->getWorld()->setBlock($this->pos, $this->getResidue()); + $this->position->getWorld()->setBlock($this->position, $this->getResidue()); } } diff --git a/src/block/Carpet.php b/src/block/Carpet.php index 8878b7b81f..54a1b4abe2 100644 --- a/src/block/Carpet.php +++ b/src/block/Carpet.php @@ -62,7 +62,7 @@ class Carpet extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } diff --git a/src/block/Chest.php b/src/block/Chest.php index 46c5eb5440..c89b3dde7c 100644 --- a/src/block/Chest.php +++ b/src/block/Chest.php @@ -45,7 +45,7 @@ class Chest extends Transparent{ } public function onPostPlace() : void{ - $tile = $this->pos->getWorld()->getTile($this->pos); + $tile = $this->position->getWorld()->getTile($this->position); if($tile instanceof TileChest){ foreach([ Facing::rotateY($this->facing, true), @@ -53,7 +53,7 @@ class Chest extends Transparent{ ] as $side){ $c = $this->getSide($side); if($c instanceof Chest and $c->isSameType($this) and $c->facing === $this->facing){ - $pair = $this->pos->getWorld()->getTile($c->pos); + $pair = $this->position->getWorld()->getTile($c->position); if($pair instanceof TileChest and !$pair->isPaired()){ $pair->pairWith($tile); $tile->pairWith($pair); @@ -67,7 +67,7 @@ class Chest extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $chest = $this->pos->getWorld()->getTile($this->pos); + $chest = $this->position->getWorld()->getTile($this->position); if($chest instanceof TileChest){ if( !$this->getSide(Facing::UP)->isTransparent() or diff --git a/src/block/CocoaBlock.php b/src/block/CocoaBlock.php index 8c86749559..82b5141729 100644 --- a/src/block/CocoaBlock.php +++ b/src/block/CocoaBlock.php @@ -96,7 +96,7 @@ class CocoaBlock extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($this->age < 2 and $item instanceof Fertilizer){ $this->age++; - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); $item->pop(); @@ -108,7 +108,7 @@ class CocoaBlock extends Transparent{ public function onNearbyBlockChange() : void{ if(!$this->canAttachTo($this->getSide(Facing::opposite($this->facing)))){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } @@ -119,7 +119,7 @@ class CocoaBlock extends Transparent{ public function onRandomTick() : void{ if($this->age < 2 and mt_rand(1, 5) === 1){ $this->age++; - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); } } diff --git a/src/block/ConcretePowder.php b/src/block/ConcretePowder.php index d65d682d23..b3c4c51ea8 100644 --- a/src/block/ConcretePowder.php +++ b/src/block/ConcretePowder.php @@ -42,7 +42,7 @@ class ConcretePowder extends Opaque implements Fallable{ public function onNearbyBlockChange() : void{ if(($block = $this->checkAdjacentWater()) !== null){ - $this->pos->getWorld()->setBlock($this->pos, $block); + $this->position->getWorld()->setBlock($this->position, $block); }else{ $this->startFalling(); } diff --git a/src/block/Coral.php b/src/block/Coral.php index b6ccb0cadd..7a991492d0 100644 --- a/src/block/Coral.php +++ b/src/block/Coral.php @@ -54,9 +54,9 @@ final class Coral extends BaseCoral{ public function readStateFromWorld() : void{ //TODO: this hack ensures correct state of coral plants, because they don't retain their dead flag in metadata - $world = $this->pos->getWorld(); + $world = $this->position->getWorld(); $this->dead = true; - foreach($this->pos->sides() as $vector3){ + foreach($this->position->sides() as $vector3){ if($world->getBlock($vector3) instanceof Water){ $this->dead = false; break; @@ -65,16 +65,16 @@ final class Coral extends BaseCoral{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$tx->fetchBlock($blockReplace->getPos()->down())->isSolid()){ + if(!$tx->fetchBlock($blockReplace->getPosition()->down())->isSolid()){ return false; } return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onNearbyBlockChange() : void{ - $world = $this->pos->getWorld(); - if(!$world->getBlock($this->pos->down())->isSolid()){ - $world->useBreakOn($this->pos); + $world = $this->position->getWorld(); + if(!$world->getBlock($this->position->down())->isSolid()){ + $world->useBreakOn($this->position); }else{ parent::onNearbyBlockChange(); } diff --git a/src/block/CoralBlock.php b/src/block/CoralBlock.php index c0bcad32f6..5399e58044 100644 --- a/src/block/CoralBlock.php +++ b/src/block/CoralBlock.php @@ -78,23 +78,23 @@ final class CoralBlock extends Opaque{ public function onNearbyBlockChange() : void{ if(!$this->dead){ - $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(40, 200)); + $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, mt_rand(40, 200)); } } public function onScheduledUpdate() : void{ if(!$this->dead){ - $world = $this->pos->getWorld(); + $world = $this->position->getWorld(); $hasWater = false; - foreach($this->pos->sides() as $vector3){ + foreach($this->position->sides() as $vector3){ if($world->getBlock($vector3) instanceof Water){ $hasWater = true; break; } } if(!$hasWater){ - $world->setBlock($this->pos, $this->setDead(true)); + $world->setBlock($this->position, $this->setDead(true)); } } } diff --git a/src/block/Crops.php b/src/block/Crops.php index 2f2d3d21a0..47cb338977 100644 --- a/src/block/Crops.php +++ b/src/block/Crops.php @@ -79,7 +79,7 @@ abstract class Crops extends Flowable{ $ev = new BlockGrowEvent($this, $block); $ev->call(); if(!$ev->isCancelled()){ - $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); + $this->position->getWorld()->setBlock($this->position, $ev->getNewState()); } $item->pop(); @@ -92,7 +92,7 @@ abstract class Crops extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::FARMLAND){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } @@ -107,7 +107,7 @@ abstract class Crops extends Flowable{ $ev = new BlockGrowEvent($this, $block); $ev->call(); if(!$ev->isCancelled()){ - $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); + $this->position->getWorld()->setBlock($this->position, $ev->getNewState()); } } } diff --git a/src/block/DaylightSensor.php b/src/block/DaylightSensor.php index fbcb92f5e4..17103ed473 100644 --- a/src/block/DaylightSensor.php +++ b/src/block/DaylightSensor.php @@ -90,7 +90,7 @@ class DaylightSensor extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->inverted = !$this->inverted; $this->signalStrength = $this->recalculateSignalStrength(); - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); return true; } @@ -98,18 +98,18 @@ class DaylightSensor extends Transparent{ $signalStrength = $this->recalculateSignalStrength(); if($this->signalStrength !== $signalStrength){ $this->signalStrength = $signalStrength; - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); } - $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 20); + $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, 20); } private function recalculateSignalStrength() : int{ - $lightLevel = $this->pos->getWorld()->getRealBlockSkyLightAt($this->pos->x, $this->pos->y, $this->pos->z); + $lightLevel = $this->position->getWorld()->getRealBlockSkyLightAt($this->position->x, $this->position->y, $this->position->z); if($this->inverted){ return 15 - $lightLevel; } - $sunAngle = $this->pos->getWorld()->getSunAnglePercentage(); + $sunAngle = $this->position->getWorld()->getSunAnglePercentage(); return max(0, (int) round($lightLevel * cos(($sunAngle + ((($sunAngle < 0.5 ? 0 : 1) - $sunAngle) / 5)) * 2 * M_PI))); } diff --git a/src/block/DeadBush.php b/src/block/DeadBush.php index 7d7a933bc6..7b5262b49c 100644 --- a/src/block/DeadBush.php +++ b/src/block/DeadBush.php @@ -43,7 +43,7 @@ class DeadBush extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } diff --git a/src/block/Dirt.php b/src/block/Dirt.php index 6c624d886e..29df9f5457 100644 --- a/src/block/Dirt.php +++ b/src/block/Dirt.php @@ -60,7 +60,7 @@ class Dirt extends Opaque{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP and $item instanceof Hoe){ $item->applyDamage(1); - $this->pos->getWorld()->setBlock($this->pos, $this->coarse ? VanillaBlocks::DIRT() : VanillaBlocks::FARMLAND()); + $this->position->getWorld()->setBlock($this->position, $this->coarse ? VanillaBlocks::DIRT() : VanillaBlocks::FARMLAND()); return true; } diff --git a/src/block/Door.php b/src/block/Door.php index 7fc3d2fd8b..74a9f1b783 100644 --- a/src/block/Door.php +++ b/src/block/Door.php @@ -121,7 +121,7 @@ class Door extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ //Replace with common break method - $this->pos->getWorld()->useBreakOn($this->pos); //this will delete both halves if they exist + $this->position->getWorld()->useBreakOn($this->position); //this will delete both halves if they exist } } @@ -147,7 +147,7 @@ class Door extends Transparent{ $topHalf = clone $this; $topHalf->top = true; - $tx->addBlock($blockReplace->pos, $this)->addBlock($blockUp->pos, $topHalf); + $tx->addBlock($blockReplace->position, $this)->addBlock($blockUp->position, $topHalf); return true; } @@ -160,11 +160,11 @@ class Door extends Transparent{ $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); if($other instanceof Door and $other->isSameType($this)){ $other->open = $this->open; - $this->pos->getWorld()->setBlock($other->pos, $other); + $this->position->getWorld()->setBlock($other->position, $other); } - $this->pos->getWorld()->setBlock($this->pos, $this); - $this->pos->getWorld()->addSound($this->pos, new DoorSound()); + $this->position->getWorld()->setBlock($this->position, $this); + $this->position->getWorld()->addSound($this->position, new DoorSound()); return true; } diff --git a/src/block/DoublePlant.php b/src/block/DoublePlant.php index fb25379c5a..00d3618326 100644 --- a/src/block/DoublePlant.php +++ b/src/block/DoublePlant.php @@ -58,7 +58,7 @@ class DoublePlant extends Flowable{ if(($id === BlockLegacyIds::GRASS or $id === BlockLegacyIds::DIRT) and $blockReplace->getSide(Facing::UP)->canBeReplaced()){ $top = clone $this; $top->top = true; - $tx->addBlock($blockReplace->pos, $this)->addBlock($blockReplace->pos->getSide(Facing::UP), $top); + $tx->addBlock($blockReplace->position, $this)->addBlock($blockReplace->position->getSide(Facing::UP), $top); return true; } @@ -80,7 +80,7 @@ class DoublePlant extends Flowable{ public function onNearbyBlockChange() : void{ if(!$this->isValidHalfPlant() or (!$this->top and $this->getSide(Facing::DOWN)->isTransparent())){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } diff --git a/src/block/DragonEgg.php b/src/block/DragonEgg.php index 8f02a740a8..a2ef58cd47 100644 --- a/src/block/DragonEgg.php +++ b/src/block/DragonEgg.php @@ -62,22 +62,22 @@ class DragonEgg extends Transparent implements Fallable{ public function teleport() : void{ for($tries = 0; $tries < 16; ++$tries){ - $block = $this->pos->getWorld()->getBlockAt( - $this->pos->x + mt_rand(-16, 16), - max(World::Y_MIN, min(World::Y_MAX - 1, $this->pos->y + mt_rand(-8, 8))), - $this->pos->z + mt_rand(-16, 16) + $block = $this->position->getWorld()->getBlockAt( + $this->position->x + mt_rand(-16, 16), + max(World::Y_MIN, min(World::Y_MAX - 1, $this->position->y + mt_rand(-8, 8))), + $this->position->z + mt_rand(-16, 16) ); if($block instanceof Air){ - $ev = new BlockTeleportEvent($this, $block->pos); + $ev = new BlockTeleportEvent($this, $block->position); $ev->call(); if($ev->isCancelled()){ break; } $blockPos = $ev->getTo(); - $this->pos->getWorld()->addParticle($this->pos, new DragonEggTeleportParticle($this->pos->x - $blockPos->x, $this->pos->y - $blockPos->y, $this->pos->z - $blockPos->z)); - $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); - $this->pos->getWorld()->setBlock($blockPos, $this); + $this->position->getWorld()->addParticle($this->position, new DragonEggTeleportParticle($this->position->x - $blockPos->x, $this->position->y - $blockPos->y, $this->position->z - $blockPos->z)); + $this->position->getWorld()->setBlock($this->position, VanillaBlocks::AIR()); + $this->position->getWorld()->setBlock($blockPos, $this); break; } } diff --git a/src/block/EnchantingTable.php b/src/block/EnchantingTable.php index 9a402a827e..b011002cdf 100644 --- a/src/block/EnchantingTable.php +++ b/src/block/EnchantingTable.php @@ -43,7 +43,7 @@ class EnchantingTable extends Transparent{ if($player instanceof Player){ //TODO lock - $player->setCurrentWindow(new EnchantInventory($this->pos)); + $player->setCurrentWindow(new EnchantInventory($this->position)); } return true; diff --git a/src/block/EnderChest.php b/src/block/EnderChest.php index 04d02195d8..e376320086 100644 --- a/src/block/EnderChest.php +++ b/src/block/EnderChest.php @@ -51,10 +51,10 @@ class EnderChest extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $enderChest = $this->pos->getWorld()->getTile($this->pos); + $enderChest = $this->position->getWorld()->getTile($this->position); if($enderChest instanceof TileEnderChest and $this->getSide(Facing::UP)->isTransparent()){ $enderChest->setViewerCount($enderChest->getViewerCount() + 1); - $player->setCurrentWindow(new EnderChestInventory($this->pos, $player->getEnderInventory())); + $player->setCurrentWindow(new EnderChestInventory($this->position, $player->getEnderInventory())); } } diff --git a/src/block/Farmland.php b/src/block/Farmland.php index 461c24493a..058567929f 100644 --- a/src/block/Farmland.php +++ b/src/block/Farmland.php @@ -64,7 +64,7 @@ class Farmland extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::UP)->isSolid()){ - $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::DIRT()); + $this->position->getWorld()->setBlock($this->position, VanillaBlocks::DIRT()); } } @@ -76,24 +76,24 @@ class Farmland extends Transparent{ if(!$this->canHydrate()){ if($this->wetness > 0){ $this->wetness--; - $this->pos->getWorld()->setBlock($this->pos, $this, false); + $this->position->getWorld()->setBlock($this->position, $this, false); }else{ - $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::DIRT()); + $this->position->getWorld()->setBlock($this->position, VanillaBlocks::DIRT()); } }elseif($this->wetness < 7){ $this->wetness = 7; - $this->pos->getWorld()->setBlock($this->pos, $this, false); + $this->position->getWorld()->setBlock($this->position, $this, false); } } protected function canHydrate() : bool{ //TODO: check rain - $start = $this->pos->add(-4, 0, -4); - $end = $this->pos->add(4, 1, 4); + $start = $this->position->add(-4, 0, -4); + $end = $this->position->add(4, 1, 4); for($y = $start->y; $y <= $end->y; ++$y){ for($z = $start->z; $z <= $end->z; ++$z){ for($x = $start->x; $x <= $end->x; ++$x){ - if($this->pos->getWorld()->getBlockAt($x, $y, $z) instanceof Water){ + if($this->position->getWorld()->getBlockAt($x, $y, $z) instanceof Water){ return true; } } diff --git a/src/block/FenceGate.php b/src/block/FenceGate.php index f8240ee006..32d79eba32 100644 --- a/src/block/FenceGate.php +++ b/src/block/FenceGate.php @@ -99,7 +99,7 @@ class FenceGate extends Transparent{ $inWall = $this->checkInWall(); if($inWall !== $this->inWall){ $this->inWall = $inWall; - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); } } @@ -112,8 +112,8 @@ class FenceGate extends Transparent{ } } - $this->pos->getWorld()->setBlock($this->pos, $this); - $this->pos->getWorld()->addSound($this->pos, new DoorSound()); + $this->position->getWorld()->setBlock($this->position, $this); + $this->position->getWorld()->addSound($this->position, new DoorSound()); return true; } diff --git a/src/block/Fire.php b/src/block/Fire.php index e16e3adb28..82c08bfe03 100644 --- a/src/block/Fire.php +++ b/src/block/Fire.php @@ -95,9 +95,9 @@ class Fire extends Flowable{ public function onNearbyBlockChange() : void{ if(!$this->getSide(Facing::DOWN)->isSolid() and !$this->hasAdjacentFlammableBlocks()){ - $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); + $this->position->getWorld()->setBlock($this->position, VanillaBlocks::AIR()); }else{ - $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(30, 40)); + $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, mt_rand(30, 40)); } } @@ -131,10 +131,10 @@ class Fire extends Flowable{ } if($result !== null){ - $this->pos->getWorld()->setBlock($this->pos, $result); + $this->position->getWorld()->setBlock($this->position, $result); } - $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(30, 40)); + $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, mt_rand(30, 40)); if($canSpread){ //TODO: raise upper bound for chance in humid biomes @@ -175,9 +175,9 @@ class Fire extends Flowable{ if(mt_rand(0, $this->age + 9) < 5){ //TODO: check rain $fire = clone $this; $fire->age = min(15, $fire->age + (mt_rand(0, 4) >> 2)); - $this->pos->getWorld()->setBlock($block->pos, $fire); + $this->position->getWorld()->setBlock($block->position, $fire); }else{ - $this->pos->getWorld()->setBlock($block->pos, VanillaBlocks::AIR()); + $this->position->getWorld()->setBlock($block->position, VanillaBlocks::AIR()); } } } diff --git a/src/block/FloorCoralFan.php b/src/block/FloorCoralFan.php index c4a5cc0a00..262925c063 100644 --- a/src/block/FloorCoralFan.php +++ b/src/block/FloorCoralFan.php @@ -93,12 +93,12 @@ final class FloorCoralFan extends BaseCoral{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$tx->fetchBlock($blockReplace->getPos()->down())->isSolid()){ + if(!$tx->fetchBlock($blockReplace->getPosition()->down())->isSolid()){ return false; } if($player !== null){ $playerBlockPos = $player->getPosition()->floor(); - $directionVector = $blockReplace->getPos()->subtractVector($playerBlockPos)->normalize(); + $directionVector = $blockReplace->getPosition()->subtractVector($playerBlockPos)->normalize(); $angle = rad2deg(atan2($directionVector->getZ(), $directionVector->getX())); if($angle <= 45 || 315 <= $angle || (135 <= $angle && $angle <= 225)){ @@ -111,9 +111,9 @@ final class FloorCoralFan extends BaseCoral{ } public function onNearbyBlockChange() : void{ - $world = $this->pos->getWorld(); - if(!$world->getBlock($this->pos->down())->isSolid()){ - $world->useBreakOn($this->pos); + $world = $this->position->getWorld(); + if(!$world->getBlock($this->position->down())->isSolid()){ + $world->useBreakOn($this->position); }else{ parent::onNearbyBlockChange(); } diff --git a/src/block/Flower.php b/src/block/Flower.php index 7ccef8f771..a7e10dfab7 100644 --- a/src/block/Flower.php +++ b/src/block/Flower.php @@ -42,7 +42,7 @@ class Flower extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } diff --git a/src/block/FlowerPot.php b/src/block/FlowerPot.php index d3a8ba5412..79e8e80b1b 100644 --- a/src/block/FlowerPot.php +++ b/src/block/FlowerPot.php @@ -47,7 +47,7 @@ class FlowerPot extends Flowable{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->pos->getWorld()->getTile($this->pos); + $tile = $this->position->getWorld()->getTile($this->position); if($tile instanceof TileFlowerPot){ $this->setPlant($tile->getPlant()); }else{ @@ -58,7 +58,7 @@ class FlowerPot extends Flowable{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->pos->getWorld()->getTile($this->pos); + $tile = $this->position->getWorld()->getTile($this->position); assert($tile instanceof TileFlowerPot); $tile->setPlant($this->plant); } @@ -109,7 +109,7 @@ class FlowerPot extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } @@ -121,7 +121,7 @@ class FlowerPot extends Flowable{ $this->setPlant($plant); $item->pop(); - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); return true; } diff --git a/src/block/FrostedIce.php b/src/block/FrostedIce.php index 18857b8342..269832d493 100644 --- a/src/block/FrostedIce.php +++ b/src/block/FrostedIce.php @@ -55,15 +55,15 @@ class FrostedIce extends Ice{ public function onNearbyBlockChange() : void{ if(!$this->checkAdjacentBlocks(2)){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); }else{ - $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(20, 40)); + $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, mt_rand(20, 40)); } } public function onRandomTick() : void{ if((!$this->checkAdjacentBlocks(4) or mt_rand(0, 2) === 0) and - $this->pos->getWorld()->getHighestAdjacentFullLightAt($this->pos->x, $this->pos->y, $this->pos->z) >= 12 - $this->age){ + $this->position->getWorld()->getHighestAdjacentFullLightAt($this->position->x, $this->position->y, $this->position->z) >= 12 - $this->age){ if($this->tryMelt()){ foreach($this->getAllSides() as $block){ if($block instanceof FrostedIce){ @@ -72,7 +72,7 @@ class FrostedIce extends Ice{ } } }else{ - $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(20, 40)); + $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, mt_rand(20, 40)); } } @@ -88,7 +88,7 @@ class FrostedIce extends Ice{ continue; } if( - $this->pos->getWorld()->getBlockAt($this->pos->x + $x, $this->pos->y, $this->pos->z + $z) instanceof FrostedIce and + $this->position->getWorld()->getBlockAt($this->position->x + $x, $this->position->y, $this->position->z + $z) instanceof FrostedIce and ++$found >= $requirement ){ return true; @@ -105,13 +105,13 @@ class FrostedIce extends Ice{ */ private function tryMelt() : bool{ if($this->age >= 3){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); return true; } $this->age++; - $this->pos->getWorld()->setBlock($this->pos, $this); - $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(20, 40)); + $this->position->getWorld()->setBlock($this->position, $this); + $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, mt_rand(20, 40)); return false; } } diff --git a/src/block/Furnace.php b/src/block/Furnace.php index 23285501e0..c49ffa35b6 100644 --- a/src/block/Furnace.php +++ b/src/block/Furnace.php @@ -72,7 +72,7 @@ class Furnace extends Opaque{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $furnace = $this->pos->getWorld()->getTile($this->pos); + $furnace = $this->position->getWorld()->getTile($this->position); if($furnace instanceof TileFurnace and $furnace->canOpenWith($item->getCustomName())){ $player->setCurrentWindow($furnace->getInventory()); } @@ -82,9 +82,9 @@ class Furnace extends Opaque{ } public function onScheduledUpdate() : void{ - $furnace = $this->pos->getWorld()->getTile($this->pos); + $furnace = $this->position->getWorld()->getTile($this->position); if($furnace instanceof TileFurnace and $furnace->onUpdate()){ - $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 1); //TODO: check this + $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, 1); //TODO: check this } } } diff --git a/src/block/Grass.php b/src/block/Grass.php index e95c967eff..e6a1288508 100644 --- a/src/block/Grass.php +++ b/src/block/Grass.php @@ -52,27 +52,27 @@ class Grass extends Opaque{ } public function onRandomTick() : void{ - $lightAbove = $this->pos->getWorld()->getFullLightAt($this->pos->x, $this->pos->y + 1, $this->pos->z); - if($lightAbove < 4 and $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z)->getLightFilter() >= 2){ + $lightAbove = $this->position->getWorld()->getFullLightAt($this->position->x, $this->position->y + 1, $this->position->z); + if($lightAbove < 4 and $this->position->getWorld()->getBlockAt($this->position->x, $this->position->y + 1, $this->position->z)->getLightFilter() >= 2){ //grass dies $ev = new BlockSpreadEvent($this, $this, VanillaBlocks::DIRT()); $ev->call(); if(!$ev->isCancelled()){ - $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState(), false); + $this->position->getWorld()->setBlock($this->position, $ev->getNewState(), false); } }elseif($lightAbove >= 9){ //try grass spread for($i = 0; $i < 4; ++$i){ - $x = mt_rand($this->pos->x - 1, $this->pos->x + 1); - $y = mt_rand($this->pos->y - 3, $this->pos->y + 1); - $z = mt_rand($this->pos->z - 1, $this->pos->z + 1); + $x = mt_rand($this->position->x - 1, $this->position->x + 1); + $y = mt_rand($this->position->y - 3, $this->position->y + 1); + $z = mt_rand($this->position->z - 1, $this->position->z + 1); - $b = $this->pos->getWorld()->getBlockAt($x, $y, $z); + $b = $this->position->getWorld()->getBlockAt($x, $y, $z); if( !($b instanceof Dirt) or $b->isCoarse() or - $this->pos->getWorld()->getFullLightAt($x, $y + 1, $z) < 4 or - $this->pos->getWorld()->getBlockAt($x, $y + 1, $z)->getLightFilter() >= 2 + $this->position->getWorld()->getFullLightAt($x, $y + 1, $z) < 4 or + $this->position->getWorld()->getBlockAt($x, $y + 1, $z)->getLightFilter() >= 2 ){ continue; } @@ -80,7 +80,7 @@ class Grass extends Opaque{ $ev = new BlockSpreadEvent($b, $this, VanillaBlocks::GRASS()); $ev->call(); if(!$ev->isCancelled()){ - $this->pos->getWorld()->setBlock($b->pos, $ev->getNewState(), false); + $this->position->getWorld()->setBlock($b->position, $ev->getNewState(), false); } } } @@ -92,17 +92,17 @@ class Grass extends Opaque{ } if($item instanceof Fertilizer){ $item->pop(); - TallGrassObject::growGrass($this->pos->getWorld(), $this->pos, new Random(mt_rand()), 8, 2); + TallGrassObject::growGrass($this->position->getWorld(), $this->position, new Random(mt_rand()), 8, 2); return true; }elseif($item instanceof Hoe){ $item->applyDamage(1); - $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::FARMLAND()); + $this->position->getWorld()->setBlock($this->position, VanillaBlocks::FARMLAND()); return true; }elseif($item instanceof Shovel and $this->getSide(Facing::UP)->getId() === BlockLegacyIds::AIR){ $item->applyDamage(1); - $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::GRASS_PATH()); + $this->position->getWorld()->setBlock($this->position, VanillaBlocks::GRASS_PATH()); return true; } diff --git a/src/block/GrassPath.php b/src/block/GrassPath.php index b3b8f1f4c8..4a46fe6899 100644 --- a/src/block/GrassPath.php +++ b/src/block/GrassPath.php @@ -38,7 +38,7 @@ class GrassPath extends Transparent{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::UP)->isSolid()){ - $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::DIRT()); + $this->position->getWorld()->setBlock($this->position, VanillaBlocks::DIRT()); } } diff --git a/src/block/Hopper.php b/src/block/Hopper.php index c05362f314..ec8f69014e 100644 --- a/src/block/Hopper.php +++ b/src/block/Hopper.php @@ -86,7 +86,7 @@ class Hopper extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ - $tile = $this->pos->getWorld()->getTile($this->pos); + $tile = $this->position->getWorld()->getTile($this->position); if($tile instanceof TileHopper){ //TODO: find a way to have inventories open on click without this boilerplate in every block $player->setCurrentWindow($tile->getInventory()); } diff --git a/src/block/Ice.php b/src/block/Ice.php index 3c39f97bdf..c1156fffae 100644 --- a/src/block/Ice.php +++ b/src/block/Ice.php @@ -39,7 +39,7 @@ class Ice extends Transparent{ public function onBreak(Item $item, ?Player $player = null) : bool{ if(($player === null or $player->isSurvival()) and !$item->hasEnchantment(VanillaEnchantments::SILK_TOUCH())){ - $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::WATER()); + $this->position->getWorld()->setBlock($this->position, VanillaBlocks::WATER()); return true; } return parent::onBreak($item, $player); @@ -50,8 +50,8 @@ class Ice extends Transparent{ } public function onRandomTick() : void{ - if($this->pos->getWorld()->getHighestAdjacentBlockLight($this->pos->x, $this->pos->y, $this->pos->z) >= 12){ - $this->pos->getWorld()->useBreakOn($this->pos); + if($this->position->getWorld()->getHighestAdjacentBlockLight($this->position->x, $this->position->y, $this->position->z) >= 12){ + $this->position->getWorld()->useBreakOn($this->position); } } diff --git a/src/block/ItemFrame.php b/src/block/ItemFrame.php index 523d37c21b..aff9f65669 100644 --- a/src/block/ItemFrame.php +++ b/src/block/ItemFrame.php @@ -55,7 +55,7 @@ class ItemFrame extends Flowable{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->pos->getWorld()->getTile($this->pos); + $tile = $this->position->getWorld()->getTile($this->position); if($tile instanceof TileItemFrame){ $this->framedItem = $tile->getItem(); if($this->framedItem->isNull()){ @@ -68,7 +68,7 @@ class ItemFrame extends Flowable{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->pos->getWorld()->getTile($this->pos); + $tile = $this->position->getWorld()->getTile($this->position); if($tile instanceof TileItemFrame){ $tile->setItem($this->framedItem); $tile->setItemRotation($this->itemRotation); @@ -137,7 +137,7 @@ class ItemFrame extends Flowable{ return true; } - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); return true; } @@ -147,16 +147,16 @@ class ItemFrame extends Flowable{ return false; } if(lcg_value() <= $this->itemDropChance){ - $this->pos->getWorld()->dropItem($this->pos->add(0.5, 0.5, 0.5), clone $this->framedItem); + $this->position->getWorld()->dropItem($this->position->add(0.5, 0.5, 0.5), clone $this->framedItem); } $this->setFramedItem(null); - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); return true; } public function onNearbyBlockChange() : void{ if(!$this->getSide(Facing::opposite($this->facing))->isSolid()){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } diff --git a/src/block/Jukebox.php b/src/block/Jukebox.php index 37a0e53b5d..be8fa7f4c4 100644 --- a/src/block/Jukebox.php +++ b/src/block/Jukebox.php @@ -49,7 +49,7 @@ class Jukebox extends Opaque{ } } - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); return true; } @@ -60,7 +60,7 @@ class Jukebox extends Opaque{ public function ejectRecord() : void{ if($this->record !== null){ - $this->getPos()->getWorld()->dropItem($this->getPos()->add(0.5, 1, 0.5), $this->record); + $this->getPosition()->getWorld()->dropItem($this->getPosition()->add(0.5, 1, 0.5), $this->record); $this->record = null; $this->stopSound(); } @@ -75,12 +75,12 @@ class Jukebox extends Opaque{ public function startSound() : void{ if($this->record !== null){ - $this->getPos()->getWorld()->addSound($this->getPos(), new RecordSound($this->record->getRecordType())); + $this->getPosition()->getWorld()->addSound($this->getPosition(), new RecordSound($this->record->getRecordType())); } } public function stopSound() : void{ - $this->getPos()->getWorld()->addSound($this->getPos(), new RecordStopSound()); + $this->getPosition()->getWorld()->addSound($this->getPosition(), new RecordStopSound()); } public function onBreak(Item $item, ?Player $player = null) : bool{ @@ -98,7 +98,7 @@ class Jukebox extends Opaque{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $jukebox = $this->pos->getWorld()->getTile($this->pos); + $jukebox = $this->position->getWorld()->getTile($this->position); if($jukebox instanceof JukeboxTile){ $this->record = $jukebox->getRecord(); } @@ -106,7 +106,7 @@ class Jukebox extends Opaque{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $jukebox = $this->pos->getWorld()->getTile($this->pos); + $jukebox = $this->position->getWorld()->getTile($this->position); if($jukebox instanceof JukeboxTile){ $jukebox->setRecord($this->record); } diff --git a/src/block/Ladder.php b/src/block/Ladder.php index 978d29d654..f76a28b6fb 100644 --- a/src/block/Ladder.php +++ b/src/block/Ladder.php @@ -50,7 +50,7 @@ class Ladder extends Transparent{ } public function onEntityInside(Entity $entity) : bool{ - if($entity instanceof Living && $entity->getPosition()->floor()->distanceSquared($this->pos) < 1){ //entity coordinates must be inside block + if($entity instanceof Living && $entity->getPosition()->floor()->distanceSquared($this->position) < 1){ //entity coordinates must be inside block $entity->resetFallDistance(); $entity->onGround = true; } @@ -75,7 +75,7 @@ class Ladder extends Transparent{ public function onNearbyBlockChange() : void{ if(!$this->getSide(Facing::opposite($this->facing))->isSolid()){ //Replace with common break method - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } } diff --git a/src/block/Lantern.php b/src/block/Lantern.php index b6c91a1f4c..4bd2f59188 100644 --- a/src/block/Lantern.php +++ b/src/block/Lantern.php @@ -77,17 +77,17 @@ class Lantern extends Transparent{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canAttachTo($this->pos->getWorld()->getBlock($blockReplace->getPos()->up())) and !$this->canAttachTo($this->pos->getWorld()->getBlock($blockReplace->getPos()->down()))){ + if(!$this->canAttachTo($this->position->getWorld()->getBlock($blockReplace->getPosition()->up())) and !$this->canAttachTo($this->position->getWorld()->getBlock($blockReplace->getPosition()->down()))){ return false; } - $this->hanging = ($face === Facing::DOWN or !$this->canAttachTo($this->pos->getWorld()->getBlock($blockReplace->getPos()->down()))); + $this->hanging = ($face === Facing::DOWN or !$this->canAttachTo($this->position->getWorld()->getBlock($blockReplace->getPosition()->down()))); return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onNearbyBlockChange() : void{ - if(!$this->canAttachTo($this->pos->getWorld()->getBlock($this->hanging ? $this->pos->up() : $this->pos->down()))){ - $this->pos->getWorld()->useBreakOn($this->pos); + if(!$this->canAttachTo($this->position->getWorld()->getBlock($this->hanging ? $this->position->up() : $this->position->down()))){ + $this->position->getWorld()->useBreakOn($this->position); } } } diff --git a/src/block/Leaves.php b/src/block/Leaves.php index 42ce2b0122..03c99936e8 100644 --- a/src/block/Leaves.php +++ b/src/block/Leaves.php @@ -91,7 +91,7 @@ class Leaves extends Transparent{ } $visited[$index] = true; - $block = $this->pos->getWorld()->getBlock($pos); + $block = $this->position->getWorld()->getBlock($pos); if($block instanceof Wood){ //type doesn't matter return true; } @@ -110,7 +110,7 @@ class Leaves extends Transparent{ public function onNearbyBlockChange() : void{ if(!$this->noDecay and !$this->checkDecay){ $this->checkDecay = true; - $this->pos->getWorld()->setBlock($this->pos, $this, false); + $this->position->getWorld()->setBlock($this->position, $this, false); } } @@ -122,11 +122,11 @@ class Leaves extends Transparent{ if(!$this->noDecay and $this->checkDecay){ $ev = new LeavesDecayEvent($this); $ev->call(); - if($ev->isCancelled() or $this->findLog($this->pos)){ + if($ev->isCancelled() or $this->findLog($this->position)){ $this->checkDecay = false; - $this->pos->getWorld()->setBlock($this->pos, $this, false); + $this->position->getWorld()->setBlock($this->position, $this, false); }else{ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } } diff --git a/src/block/Lever.php b/src/block/Lever.php index c4d2abc9d4..e32920f70e 100644 --- a/src/block/Lever.php +++ b/src/block/Lever.php @@ -101,15 +101,15 @@ class Lever extends Flowable{ } if(!$this->getSide($face)->isSolid()){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->powered = !$this->powered; - $this->pos->getWorld()->setBlock($this->pos, $this); - $this->pos->getWorld()->addSound( - $this->pos->add(0.5, 0.5, 0.5), + $this->position->getWorld()->setBlock($this->position, $this); + $this->position->getWorld()->addSound( + $this->position->add(0.5, 0.5, 0.5), $this->powered ? new RedstonePowerOnSound() : new RedstonePowerOffSound() ); return true; diff --git a/src/block/Liquid.php b/src/block/Liquid.php index a04ac589ea..999218372f 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -184,13 +184,13 @@ abstract class Liquid extends Transparent{ $decay = $this->getEffectiveFlowDecay($this); - $world = $this->pos->getWorld(); + $world = $this->position->getWorld(); for($j = 0; $j < 4; ++$j){ - $x = $this->pos->x; - $y = $this->pos->y; - $z = $this->pos->z; + $x = $this->position->x; + $y = $this->position->y; + $z = $this->position->z; if($j === 0){ --$x; @@ -214,17 +214,17 @@ abstract class Liquid extends Transparent{ if($blockDecay >= 0){ $realDecay = $blockDecay - ($decay - 8); - $vX += ($x - $this->pos->x) * $realDecay; - $vY += ($y - $this->pos->y) * $realDecay; - $vZ += ($z - $this->pos->z) * $realDecay; + $vX += ($x - $this->position->x) * $realDecay; + $vY += ($y - $this->position->y) * $realDecay; + $vZ += ($z - $this->position->z) * $realDecay; } continue; }else{ $realDecay = $blockDecay - $decay; - $vX += ($x - $this->pos->x) * $realDecay; - $vY += ($y - $this->pos->y) * $realDecay; - $vZ += ($z - $this->pos->z) * $realDecay; + $vX += ($x - $this->position->x) * $realDecay; + $vY += ($y - $this->position->y) * $realDecay; + $vZ += ($z - $this->position->z) * $realDecay; } } @@ -232,14 +232,14 @@ abstract class Liquid extends Transparent{ if($this->falling){ if( - !$this->canFlowInto($world->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1)) or - !$this->canFlowInto($world->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z + 1)) or - !$this->canFlowInto($world->getBlockAt($this->pos->x - 1, $this->pos->y, $this->pos->z)) or - !$this->canFlowInto($world->getBlockAt($this->pos->x + 1, $this->pos->y, $this->pos->z)) or - !$this->canFlowInto($world->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z - 1)) or - !$this->canFlowInto($world->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z + 1)) or - !$this->canFlowInto($world->getBlockAt($this->pos->x - 1, $this->pos->y + 1, $this->pos->z)) or - !$this->canFlowInto($world->getBlockAt($this->pos->x + 1, $this->pos->y + 1, $this->pos->z)) + !$this->canFlowInto($world->getBlockAt($this->position->x, $this->position->y, $this->position->z - 1)) or + !$this->canFlowInto($world->getBlockAt($this->position->x, $this->position->y, $this->position->z + 1)) or + !$this->canFlowInto($world->getBlockAt($this->position->x - 1, $this->position->y, $this->position->z)) or + !$this->canFlowInto($world->getBlockAt($this->position->x + 1, $this->position->y, $this->position->z)) or + !$this->canFlowInto($world->getBlockAt($this->position->x, $this->position->y + 1, $this->position->z - 1)) or + !$this->canFlowInto($world->getBlockAt($this->position->x, $this->position->y + 1, $this->position->z + 1)) or + !$this->canFlowInto($world->getBlockAt($this->position->x - 1, $this->position->y + 1, $this->position->z)) or + !$this->canFlowInto($world->getBlockAt($this->position->x + 1, $this->position->y + 1, $this->position->z)) ){ $vector = $vector->normalize()->add(0, -6, 0); } @@ -266,7 +266,7 @@ abstract class Liquid extends Transparent{ public function onNearbyBlockChange() : void{ if(!$this->checkForHarden()){ - $this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, $this->tickRate()); + $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, $this->tickRate()); } } @@ -276,10 +276,10 @@ abstract class Liquid extends Transparent{ if(!$this->isSource()){ $smallestFlowDecay = -100; $this->adjacentSources = 0; - $smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1), $smallestFlowDecay); - $smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z + 1), $smallestFlowDecay); - $smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorld()->getBlockAt($this->pos->x - 1, $this->pos->y, $this->pos->z), $smallestFlowDecay); - $smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorld()->getBlockAt($this->pos->x + 1, $this->pos->y, $this->pos->z), $smallestFlowDecay); + $smallestFlowDecay = $this->getSmallestFlowDecay($this->position->getWorld()->getBlockAt($this->position->x, $this->position->y, $this->position->z - 1), $smallestFlowDecay); + $smallestFlowDecay = $this->getSmallestFlowDecay($this->position->getWorld()->getBlockAt($this->position->x, $this->position->y, $this->position->z + 1), $smallestFlowDecay); + $smallestFlowDecay = $this->getSmallestFlowDecay($this->position->getWorld()->getBlockAt($this->position->x - 1, $this->position->y, $this->position->z), $smallestFlowDecay); + $smallestFlowDecay = $this->getSmallestFlowDecay($this->position->getWorld()->getBlockAt($this->position->x + 1, $this->position->y, $this->position->z), $smallestFlowDecay); $newDecay = $smallestFlowDecay + $multiplier; $falling = false; @@ -288,12 +288,12 @@ abstract class Liquid extends Transparent{ $newDecay = -1; } - if($this->getEffectiveFlowDecay($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z)) >= 0){ + if($this->getEffectiveFlowDecay($this->position->getWorld()->getBlockAt($this->position->x, $this->position->y + 1, $this->position->z)) >= 0){ $falling = true; } if($this->adjacentSources >= 2 and $this instanceof Water){ - $bottomBlock = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y - 1, $this->pos->z); + $bottomBlock = $this->position->getWorld()->getBlockAt($this->position->x, $this->position->y - 1, $this->position->z); if($bottomBlock->isSolid() or ($bottomBlock instanceof Water and $bottomBlock->isSource())){ $newDecay = 0; $falling = false; @@ -302,17 +302,17 @@ abstract class Liquid extends Transparent{ if($falling !== $this->falling or (!$falling and $newDecay !== $this->decay)){ if(!$falling and $newDecay < 0){ - $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); + $this->position->getWorld()->setBlock($this->position, VanillaBlocks::AIR()); return; } $this->falling = $falling; $this->decay = $falling ? 0 : $newDecay; - $this->pos->getWorld()->setBlock($this->pos, $this); //local block update will cause an update to be scheduled + $this->position->getWorld()->setBlock($this->position, $this); //local block update will cause an update to be scheduled } } - $bottomBlock = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y - 1, $this->pos->z); + $bottomBlock = $this->position->getWorld()->getBlockAt($this->position->x, $this->position->y - 1, $this->position->z); $this->flowIntoBlock($bottomBlock, 0, true); @@ -327,19 +327,19 @@ abstract class Liquid extends Transparent{ $flags = $this->getOptimalFlowDirections(); if($flags[0]){ - $this->flowIntoBlock($this->pos->getWorld()->getBlockAt($this->pos->x - 1, $this->pos->y, $this->pos->z), $adjacentDecay, false); + $this->flowIntoBlock($this->position->getWorld()->getBlockAt($this->position->x - 1, $this->position->y, $this->position->z), $adjacentDecay, false); } if($flags[1]){ - $this->flowIntoBlock($this->pos->getWorld()->getBlockAt($this->pos->x + 1, $this->pos->y, $this->pos->z), $adjacentDecay, false); + $this->flowIntoBlock($this->position->getWorld()->getBlockAt($this->position->x + 1, $this->position->y, $this->position->z), $adjacentDecay, false); } if($flags[2]){ - $this->flowIntoBlock($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1), $adjacentDecay, false); + $this->flowIntoBlock($this->position->getWorld()->getBlockAt($this->position->x, $this->position->y, $this->position->z - 1), $adjacentDecay, false); } if($flags[3]){ - $this->flowIntoBlock($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z + 1), $adjacentDecay, false); + $this->flowIntoBlock($this->position->getWorld()->getBlockAt($this->position->x, $this->position->y, $this->position->z + 1), $adjacentDecay, false); } } } @@ -357,10 +357,10 @@ abstract class Liquid extends Transparent{ $ev->call(); if(!$ev->isCancelled()){ if($block->getId() > 0){ - $this->pos->getWorld()->useBreakOn($block->pos); + $this->position->getWorld()->useBreakOn($block->position); } - $this->pos->getWorld()->setBlock($block->pos, $ev->getNewState()); + $this->position->getWorld()->setBlock($block->position, $ev->getNewState()); } } } @@ -388,10 +388,10 @@ abstract class Liquid extends Transparent{ } if(!isset($this->flowCostVisited[$hash = World::blockHash($x, $y, $z)])){ - $blockSide = $this->pos->getWorld()->getBlockAt($x, $y, $z); + $blockSide = $this->position->getWorld()->getBlockAt($x, $y, $z); if(!$this->canFlowInto($blockSide)){ $this->flowCostVisited[$hash] = self::BLOCKED; - }elseif($this->pos->getWorld()->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ + }elseif($this->position->getWorld()->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ $this->flowCostVisited[$hash] = self::CAN_FLOW_DOWN; }else{ $this->flowCostVisited[$hash] = self::CAN_FLOW; @@ -427,9 +427,9 @@ abstract class Liquid extends Transparent{ $flowCost = array_fill(0, 4, 1000); $maxCost = intdiv(4, $this->getFlowDecayPerBlock()); for($j = 0; $j < 4; ++$j){ - $x = $this->pos->x; - $y = $this->pos->y; - $z = $this->pos->z; + $x = $this->position->x; + $y = $this->position->y; + $z = $this->position->z; if($j === 0){ --$x; @@ -440,12 +440,12 @@ abstract class Liquid extends Transparent{ }elseif($j === 3){ ++$z; } - $block = $this->pos->getWorld()->getBlockAt($x, $y, $z); + $block = $this->position->getWorld()->getBlockAt($x, $y, $z); if(!$this->canFlowInto($block)){ $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::BLOCKED; continue; - }elseif($this->pos->getWorld()->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ + }elseif($this->position->getWorld()->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::CAN_FLOW_DOWN; $flowCost[$j] = $maxCost = 0; }elseif($maxCost > 0){ @@ -493,13 +493,13 @@ abstract class Liquid extends Transparent{ $ev = new BlockFormEvent($this, $result); $ev->call(); if(!$ev->isCancelled()){ - $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); - $this->pos->getWorld()->addSound($this->pos->add(0.5, 0.5, 0.5), new FizzSound(2.6 + (lcg_value() - lcg_value()) * 0.8)); + $this->position->getWorld()->setBlock($this->position, $ev->getNewState()); + $this->position->getWorld()->addSound($this->position->add(0.5, 0.5, 0.5), new FizzSound(2.6 + (lcg_value() - lcg_value()) * 0.8)); } return true; } protected function canFlowInto(Block $block) : bool{ - return $this->pos->getWorld()->isInWorld($block->pos->x, $block->pos->y, $block->pos->z) and $block->canBeFlowedInto() and !($block instanceof Liquid and $block->isSource()); //TODO: I think this should only be liquids of the same type + return $this->position->getWorld()->isInWorld($block->position->x, $block->position->y, $block->position->z) and $block->canBeFlowedInto() and !($block instanceof Liquid and $block->isSource()); //TODO: I think this should only be liquids of the same type } } diff --git a/src/block/Loom.php b/src/block/Loom.php index d4efcf1030..976eea46c5 100644 --- a/src/block/Loom.php +++ b/src/block/Loom.php @@ -49,7 +49,7 @@ final class Loom extends Opaque{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ - $player->setCurrentWindow(new LoomInventory($this->pos)); + $player->setCurrentWindow(new LoomInventory($this->position)); return true; } return false; diff --git a/src/block/Mycelium.php b/src/block/Mycelium.php index 940cb00dc2..4d456ea980 100644 --- a/src/block/Mycelium.php +++ b/src/block/Mycelium.php @@ -46,16 +46,16 @@ class Mycelium extends Opaque{ public function onRandomTick() : void{ //TODO: light levels - $x = mt_rand($this->pos->x - 1, $this->pos->x + 1); - $y = mt_rand($this->pos->y - 2, $this->pos->y + 2); - $z = mt_rand($this->pos->z - 1, $this->pos->z + 1); - $block = $this->pos->getWorld()->getBlockAt($x, $y, $z); + $x = mt_rand($this->position->x - 1, $this->position->x + 1); + $y = mt_rand($this->position->y - 2, $this->position->y + 2); + $z = mt_rand($this->position->z - 1, $this->position->z + 1); + $block = $this->position->getWorld()->getBlockAt($x, $y, $z); if($block->getId() === BlockLegacyIds::DIRT){ if($block->getSide(Facing::UP) instanceof Transparent){ $ev = new BlockSpreadEvent($block, $this, VanillaBlocks::MYCELIUM()); $ev->call(); if(!$ev->isCancelled()){ - $this->pos->getWorld()->setBlock($block->pos, $ev->getNewState()); + $this->position->getWorld()->setBlock($block->position, $ev->getNewState()); } } } diff --git a/src/block/NetherWartPlant.php b/src/block/NetherWartPlant.php index ca727a8cce..5809c8a4ee 100644 --- a/src/block/NetherWartPlant.php +++ b/src/block/NetherWartPlant.php @@ -70,7 +70,7 @@ class NetherWartPlant extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::SOUL_SAND){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } @@ -85,7 +85,7 @@ class NetherWartPlant extends Flowable{ $ev = new BlockGrowEvent($this, $block); $ev->call(); if(!$ev->isCancelled()){ - $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); + $this->position->getWorld()->setBlock($this->position, $ev->getNewState()); } } } diff --git a/src/block/Note.php b/src/block/Note.php index 0cdd9fdaae..d8ff224028 100644 --- a/src/block/Note.php +++ b/src/block/Note.php @@ -34,7 +34,7 @@ class Note extends Opaque{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->pos->getWorld()->getTile($this->pos); + $tile = $this->position->getWorld()->getTile($this->position); if($tile instanceof TileNote){ $this->pitch = $tile->getPitch(); }else{ @@ -44,7 +44,7 @@ class Note extends Opaque{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->pos->getWorld()->getTile($this->pos); + $tile = $this->position->getWorld()->getTile($this->position); assert($tile instanceof TileNote); $tile->setPitch($this->pitch); } diff --git a/src/block/RedMushroom.php b/src/block/RedMushroom.php index 3ca1a0bdb5..567c36589e 100644 --- a/src/block/RedMushroom.php +++ b/src/block/RedMushroom.php @@ -37,7 +37,7 @@ class RedMushroom extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } diff --git a/src/block/RedstoneComparator.php b/src/block/RedstoneComparator.php index b58dd1a697..7646769533 100644 --- a/src/block/RedstoneComparator.php +++ b/src/block/RedstoneComparator.php @@ -72,7 +72,7 @@ class RedstoneComparator extends Flowable{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->pos->getWorld()->getTile($this->pos); + $tile = $this->position->getWorld()->getTile($this->position); if($tile instanceof Comparator){ $this->signalStrength = $tile->getSignalStrength(); } @@ -80,7 +80,7 @@ class RedstoneComparator extends Flowable{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $tile = $this->pos->getWorld()->getTile($this->pos); + $tile = $this->position->getWorld()->getTile($this->position); assert($tile instanceof Comparator); $tile->setSignalStrength($this->signalStrength); } @@ -115,13 +115,13 @@ class RedstoneComparator extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->isSubtractMode = !$this->isSubtractMode; - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); return true; } public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } diff --git a/src/block/RedstoneOre.php b/src/block/RedstoneOre.php index 6078f8bfdd..f402eacf88 100644 --- a/src/block/RedstoneOre.php +++ b/src/block/RedstoneOre.php @@ -67,7 +67,7 @@ class RedstoneOre extends Opaque{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if(!$this->lit){ $this->lit = true; - $this->pos->getWorld()->setBlock($this->pos, $this); //no return here - this shouldn't prevent block placement + $this->position->getWorld()->setBlock($this->position, $this); //no return here - this shouldn't prevent block placement } return false; } @@ -75,7 +75,7 @@ class RedstoneOre extends Opaque{ public function onNearbyBlockChange() : void{ if(!$this->lit){ $this->lit = true; - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); } } @@ -86,7 +86,7 @@ class RedstoneOre extends Opaque{ public function onRandomTick() : void{ if($this->lit){ $this->lit = false; - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); } } diff --git a/src/block/RedstoneRepeater.php b/src/block/RedstoneRepeater.php index 2aa1ba1097..b0fb793fdf 100644 --- a/src/block/RedstoneRepeater.php +++ b/src/block/RedstoneRepeater.php @@ -98,13 +98,13 @@ class RedstoneRepeater extends Flowable{ if(++$this->delay > 4){ $this->delay = 1; } - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); return true; } public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } diff --git a/src/block/Sapling.php b/src/block/Sapling.php index 8605324a0f..586f956f38 100644 --- a/src/block/Sapling.php +++ b/src/block/Sapling.php @@ -76,7 +76,7 @@ class Sapling extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof Fertilizer){ - Tree::growTree($this->pos->getWorld(), $this->pos->x, $this->pos->y, $this->pos->z, new Random(mt_rand()), $this->treeType); + Tree::growTree($this->position->getWorld(), $this->position->x, $this->position->y, $this->position->z, new Random(mt_rand()), $this->treeType); $item->pop(); @@ -88,7 +88,7 @@ class Sapling extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } @@ -97,12 +97,12 @@ class Sapling extends Flowable{ } public function onRandomTick() : void{ - if($this->pos->getWorld()->getFullLightAt($this->pos->x, $this->pos->y, $this->pos->z) >= 8 and mt_rand(1, 7) === 1){ + if($this->position->getWorld()->getFullLightAt($this->position->x, $this->position->y, $this->position->z) >= 8 and mt_rand(1, 7) === 1){ if($this->ready){ - Tree::growTree($this->pos->getWorld(), $this->pos->x, $this->pos->y, $this->pos->z, new Random(mt_rand()), $this->treeType); + Tree::growTree($this->position->getWorld(), $this->position->x, $this->position->y, $this->position->z, new Random(mt_rand()), $this->treeType); }else{ $this->ready = true; - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); } } } diff --git a/src/block/ShulkerBox.php b/src/block/ShulkerBox.php index 13b3977536..a81e5009d9 100644 --- a/src/block/ShulkerBox.php +++ b/src/block/ShulkerBox.php @@ -35,7 +35,7 @@ class ShulkerBox extends Opaque{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); - $shulker = $this->pos->getWorld()->getTile($this->pos); + $shulker = $this->position->getWorld()->getTile($this->position); if($shulker instanceof TileShulkerBox){ $shulker->setFacing($this->facing); } @@ -43,7 +43,7 @@ class ShulkerBox extends Opaque{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $shulker = $this->pos->getWorld()->getTile($this->pos); + $shulker = $this->position->getWorld()->getTile($this->position); if($shulker instanceof TileShulkerBox){ $this->facing = $shulker->getFacing(); } @@ -71,7 +71,7 @@ class ShulkerBox extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ $drop = $this->asItem(); - if(($tile = $this->pos->getWorld()->getTile($this->pos)) instanceof TileShulkerBox){ + if(($tile = $this->position->getWorld()->getTile($this->position)) instanceof TileShulkerBox){ $this->addDataFromTile($tile, $drop); } return [$drop]; @@ -79,7 +79,7 @@ class ShulkerBox extends Opaque{ public function getPickedItem(bool $addUserData = false) : Item{ $result = parent::getPickedItem($addUserData); - if($addUserData && ($tile = $this->pos->getWorld()->getTile($this->pos)) instanceof TileShulkerBox){ + if($addUserData && ($tile = $this->position->getWorld()->getTile($this->position)) instanceof TileShulkerBox){ $this->addDataFromTile($tile, $result); } return $result; @@ -88,7 +88,7 @@ class ShulkerBox extends Opaque{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $shulker = $this->pos->getWorld()->getTile($this->pos); + $shulker = $this->position->getWorld()->getTile($this->position); if($shulker instanceof TileShulkerBox){ if( $this->getSide($this->facing)->getId() !== BlockLegacyIds::AIR or diff --git a/src/block/Skull.php b/src/block/Skull.php index 20fcd760bc..6ee2e77f43 100644 --- a/src/block/Skull.php +++ b/src/block/Skull.php @@ -64,7 +64,7 @@ class Skull extends Flowable{ public function readStateFromWorld() : void{ parent::readStateFromWorld(); - $tile = $this->pos->getWorld()->getTile($this->pos); + $tile = $this->position->getWorld()->getTile($this->position); if($tile instanceof TileSkull){ $this->skullType = $tile->getSkullType(); $this->rotation = $tile->getRotation(); @@ -74,7 +74,7 @@ class Skull extends Flowable{ public function writeStateToWorld() : void{ parent::writeStateToWorld(); //extra block properties storage hack - $tile = $this->pos->getWorld()->getTile($this->pos); + $tile = $this->position->getWorld()->getTile($this->position); assert($tile instanceof TileSkull); $tile->setRotation($this->rotation); $tile->setSkullType($this->skullType); diff --git a/src/block/SnowLayer.php b/src/block/SnowLayer.php index 015f0b5b44..c901e9d0c5 100644 --- a/src/block/SnowLayer.php +++ b/src/block/SnowLayer.php @@ -99,8 +99,8 @@ class SnowLayer extends Flowable implements Fallable{ } public function onRandomTick() : void{ - if($this->pos->getWorld()->getBlockLightAt($this->pos->x, $this->pos->y, $this->pos->z) >= 12){ - $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR(), false); + if($this->position->getWorld()->getBlockLightAt($this->position->x, $this->position->y, $this->position->z) >= 12){ + $this->position->getWorld()->setBlock($this->position, VanillaBlocks::AIR(), false); } } diff --git a/src/block/Stem.php b/src/block/Stem.php index a70adfc452..5904736f71 100644 --- a/src/block/Stem.php +++ b/src/block/Stem.php @@ -41,7 +41,7 @@ abstract class Stem extends Crops{ $ev = new BlockGrowEvent($this, $block); $ev->call(); if(!$ev->isCancelled()){ - $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); + $this->position->getWorld()->setBlock($this->position, $ev->getNewState()); } }else{ $grow = $this->getPlant(); @@ -57,7 +57,7 @@ abstract class Stem extends Crops{ $ev = new BlockGrowEvent($side, $grow); $ev->call(); if(!$ev->isCancelled()){ - $this->pos->getWorld()->setBlock($side->pos, $ev->getNewState()); + $this->position->getWorld()->setBlock($side->position, $ev->getNewState()); } } } diff --git a/src/block/Sugarcane.php b/src/block/Sugarcane.php index 15e6bad6d2..eadf9c1ff0 100644 --- a/src/block/Sugarcane.php +++ b/src/block/Sugarcane.php @@ -50,23 +50,23 @@ class Sugarcane extends Flowable{ private function grow() : void{ for($y = 1; $y < 3; ++$y){ - if(!$this->pos->getWorld()->isInWorld($this->pos->x, $this->pos->y + $y, $this->pos->z)){ + if(!$this->position->getWorld()->isInWorld($this->position->x, $this->position->y + $y, $this->position->z)){ break; } - $b = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z); + $b = $this->position->getWorld()->getBlockAt($this->position->x, $this->position->y + $y, $this->position->z); if($b->getId() === BlockLegacyIds::AIR){ $ev = new BlockGrowEvent($b, VanillaBlocks::SUGARCANE()); $ev->call(); if($ev->isCancelled()){ break; } - $this->pos->getWorld()->setBlock($b->pos, $ev->getNewState()); + $this->position->getWorld()->setBlock($b->position, $ev->getNewState()); }else{ break; } } $this->age = 0; - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); } public function getAge() : int{ return $this->age; } @@ -97,7 +97,7 @@ class Sugarcane extends Flowable{ public function onNearbyBlockChange() : void{ $down = $this->getSide(Facing::DOWN); if($down->isTransparent() and !$down->isSameType($this)){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } @@ -111,7 +111,7 @@ class Sugarcane extends Flowable{ $this->grow(); }else{ ++$this->age; - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); } } } diff --git a/src/block/SweetBerryBush.php b/src/block/SweetBerryBush.php index 418c5ee77f..efb35845e1 100644 --- a/src/block/SweetBerryBush.php +++ b/src/block/SweetBerryBush.php @@ -98,13 +98,13 @@ class SweetBerryBush extends Flowable{ $ev->call(); if(!$ev->isCancelled()){ - $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); + $this->position->getWorld()->setBlock($this->position, $ev->getNewState()); } $item->pop(); }elseif(($dropAmount = $this->getBerryDropAmount()) > 0){ - $this->pos->getWorld()->setBlock($this->pos, $this->setAge(self::STAGE_BUSH_NO_BERRIES)); - $this->pos->getWorld()->dropItem($this->pos, $this->asItem()->setCount($dropAmount)); + $this->position->getWorld()->setBlock($this->position, $this->setAge(self::STAGE_BUSH_NO_BERRIES)); + $this->position->getWorld()->dropItem($this->position, $this->asItem()->setCount($dropAmount)); } return true; @@ -126,7 +126,7 @@ class SweetBerryBush extends Flowable{ public function onNearbyBlockChange() : void{ if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } @@ -141,7 +141,7 @@ class SweetBerryBush extends Flowable{ $ev = new BlockGrowEvent($this, $block); $ev->call(); if(!$ev->isCancelled()){ - $this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); + $this->position->getWorld()->setBlock($this->position, $ev->getNewState()); } } } diff --git a/src/block/TNT.php b/src/block/TNT.php index 6cae9ca554..27383e9962 100644 --- a/src/block/TNT.php +++ b/src/block/TNT.php @@ -110,11 +110,11 @@ class TNT extends Opaque{ } public function ignite(int $fuse = 80) : void{ - $this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); + $this->position->getWorld()->setBlock($this->position, VanillaBlocks::AIR()); $mot = (new Random())->nextSignedFloat() * M_PI * 2; - $tnt = new PrimedTNT(Location::fromObject($this->pos->add(0.5, 0, 0.5), $this->pos->getWorld())); + $tnt = new PrimedTNT(Location::fromObject($this->position->add(0.5, 0, 0.5), $this->position->getWorld())); $tnt->setFuse($fuse); $tnt->setWorksUnderwater($this->worksUnderwater); $tnt->setMotion(new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02)); diff --git a/src/block/TallGrass.php b/src/block/TallGrass.php index 6140a855c8..7f5daf731f 100644 --- a/src/block/TallGrass.php +++ b/src/block/TallGrass.php @@ -48,7 +48,7 @@ class TallGrass extends Flowable{ public function onNearbyBlockChange() : void{ if($this->getSide(Facing::DOWN)->isTransparent()){ //Replace with common break method - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } diff --git a/src/block/Torch.php b/src/block/Torch.php index 173920cae2..292bfbb180 100644 --- a/src/block/Torch.php +++ b/src/block/Torch.php @@ -67,7 +67,7 @@ class Torch extends Flowable{ $face = Facing::opposite($this->facing); if($this->getSide($face)->isTransparent() and !($face === Facing::DOWN and ($below->getId() === BlockLegacyIds::FENCE or $below->getId() === BlockLegacyIds::COBBLESTONE_WALL))){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } diff --git a/src/block/Trapdoor.php b/src/block/Trapdoor.php index 490994b6ec..6f9d7b34c1 100644 --- a/src/block/Trapdoor.php +++ b/src/block/Trapdoor.php @@ -91,8 +91,8 @@ class Trapdoor extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $this->open = !$this->open; - $this->pos->getWorld()->setBlock($this->pos, $this); - $this->pos->getWorld()->addSound($this->pos, new DoorSound()); + $this->position->getWorld()->setBlock($this->position, $this); + $this->position->getWorld()->addSound($this->position, new DoorSound()); return true; } } diff --git a/src/block/Vine.php b/src/block/Vine.php index 84b42e7cbc..b9331bc40d 100644 --- a/src/block/Vine.php +++ b/src/block/Vine.php @@ -142,9 +142,9 @@ class Vine extends Flowable{ if($changed){ if(count($this->faces) === 0){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); }else{ - $this->pos->getWorld()->setBlock($this->pos, $this); + $this->position->getWorld()->setBlock($this->position, $this); } } } diff --git a/src/block/WallCoralFan.php b/src/block/WallCoralFan.php index fb93f3eef7..f9462f5823 100644 --- a/src/block/WallCoralFan.php +++ b/src/block/WallCoralFan.php @@ -121,9 +121,9 @@ final class WallCoralFan extends BaseCoral{ } public function onNearbyBlockChange() : void{ - $world = $this->pos->getWorld(); - if(!$world->getBlock($this->pos->getSide(Facing::opposite($this->facing)))->isSolid()){ - $world->useBreakOn($this->pos); + $world = $this->position->getWorld(); + if(!$world->getBlock($this->position->getSide(Facing::opposite($this->facing)))->isSolid()){ + $world->useBreakOn($this->position); }else{ parent::onNearbyBlockChange(); } diff --git a/src/block/WaterLily.php b/src/block/WaterLily.php index 6b7f583e82..9cb5396b81 100644 --- a/src/block/WaterLily.php +++ b/src/block/WaterLily.php @@ -52,7 +52,7 @@ class WaterLily extends Flowable{ public function onNearbyBlockChange() : void{ if(!($this->getSide(Facing::DOWN) instanceof Water)){ - $this->pos->getWorld()->useBreakOn($this->pos); + $this->position->getWorld()->useBreakOn($this->position); } } } diff --git a/src/block/tile/Barrel.php b/src/block/tile/Barrel.php index 5b71f00f09..68491cd089 100644 --- a/src/block/tile/Barrel.php +++ b/src/block/tile/Barrel.php @@ -37,7 +37,7 @@ class Barrel extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); - $this->inventory = new BarrelInventory($this->pos); + $this->inventory = new BarrelInventory($this->position); } public function readSaveData(CompoundTag $nbt) : void{ diff --git a/src/block/tile/Bell.php b/src/block/tile/Bell.php index 248c260ca6..b7e5eadde2 100644 --- a/src/block/tile/Bell.php +++ b/src/block/tile/Bell.php @@ -81,6 +81,6 @@ final class Bell extends Spawnable{ $nbt->setByte(self::TAG_RINGING, 1); $nbt->setInt(self::TAG_DIRECTION, BlockDataSerializer::writeLegacyHorizontalFacing($bellHitFace)); $nbt->setInt(self::TAG_TICKS, 0); - return BlockActorDataPacket::create($this->pos->getFloorX(), $this->pos->getFloorY(), $this->pos->getFloorZ(), new CacheableNbt($nbt)); + return BlockActorDataPacket::create($this->position->getFloorX(), $this->position->getFloorY(), $this->position->getFloorZ(), new CacheableNbt($nbt)); } } diff --git a/src/block/tile/BrewingStand.php b/src/block/tile/BrewingStand.php index bccc10a279..450a521255 100644 --- a/src/block/tile/BrewingStand.php +++ b/src/block/tile/BrewingStand.php @@ -53,7 +53,7 @@ class BrewingStand extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); - $this->inventory = new BrewingStandInventory($this->pos); + $this->inventory = new BrewingStandInventory($this->position); $this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange(static function(Inventory $unused) use ($world, $pos) : void{ $world->scheduleDelayedBlockUpdate($pos, 1); })); diff --git a/src/block/tile/Chest.php b/src/block/tile/Chest.php index f7c9b765ca..52a12763ea 100644 --- a/src/block/tile/Chest.php +++ b/src/block/tile/Chest.php @@ -55,7 +55,7 @@ class Chest extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); - $this->inventory = new ChestInventory($this->pos); + $this->inventory = new ChestInventory($this->position); } public function readSaveData(CompoundTag $nbt) : void{ @@ -63,8 +63,8 @@ class Chest extends Spawnable implements Container, Nameable{ $pairX = $pairXTag->getValue(); $pairZ = $pairZTag->getValue(); if( - ($this->pos->x === $pairX and abs($this->pos->z - $pairZ) === 1) or - ($this->pos->z === $pairZ and abs($this->pos->x - $pairX) === 1) + ($this->position->x === $pairX and abs($this->position->z - $pairZ) === 1) or + ($this->position->z === $pairZ and abs($this->position->x - $pairX) === 1) ){ $this->pairX = $pairX; $this->pairZ = $pairZ; @@ -99,7 +99,7 @@ class Chest extends Spawnable implements Container, Nameable{ $this->inventory->removeAllViewers(); if($this->doubleInventory !== null){ - if($this->isPaired() and $this->pos->getWorld()->isChunkLoaded($this->pairX >> 4, $this->pairZ >> 4)){ + if($this->isPaired() and $this->position->getWorld()->isChunkLoaded($this->pairX >> 4, $this->pairZ >> 4)){ $this->doubleInventory->removeAllViewers(); if(($pair = $this->getPair()) !== null){ $pair->doubleInventory = null; @@ -135,7 +135,7 @@ class Chest extends Spawnable implements Container, Nameable{ } protected function checkPairing() : void{ - if($this->isPaired() and !$this->pos->getWorld()->isInLoadedTerrain(new Vector3($this->pairX, $this->pos->y, $this->pairZ))){ + if($this->isPaired() and !$this->position->getWorld()->isInLoadedTerrain(new Vector3($this->pairX, $this->position->y, $this->pairZ))){ //paired to a tile in an unloaded chunk $this->doubleInventory = null; @@ -148,7 +148,7 @@ class Chest extends Spawnable implements Container, Nameable{ if($pair->doubleInventory !== null){ $this->doubleInventory = $pair->doubleInventory; }else{ - if(($pair->getPos()->x + ($pair->getPos()->z << 15)) > ($this->pos->x + ($this->pos->z << 15))){ //Order them correctly + if(($pair->getPosition()->x + ($pair->getPosition()->z << 15)) > ($this->position->x + ($this->position->z << 15))){ //Order them correctly $this->doubleInventory = $pair->doubleInventory = new DoubleChestInventory($pair->inventory, $this->inventory); }else{ $this->doubleInventory = $pair->doubleInventory = new DoubleChestInventory($this->inventory, $pair->inventory); @@ -171,7 +171,7 @@ class Chest extends Spawnable implements Container, Nameable{ public function getPair() : ?Chest{ if($this->isPaired()){ - $tile = $this->pos->getWorld()->getTileAt($this->pairX, $this->pos->y, $this->pairZ); + $tile = $this->position->getWorld()->getTileAt($this->pairX, $this->position->y, $this->pairZ); if($tile instanceof Chest){ return $tile; } @@ -195,11 +195,11 @@ class Chest extends Spawnable implements Container, Nameable{ } private function createPair(Chest $tile) : void{ - $this->pairX = $tile->getPos()->x; - $this->pairZ = $tile->getPos()->z; + $this->pairX = $tile->getPosition()->x; + $this->pairZ = $tile->getPosition()->z; - $tile->pairX = $this->getPos()->x; - $tile->pairZ = $this->getPos()->z; + $tile->pairX = $this->getPosition()->x; + $tile->pairZ = $this->getPosition()->z; } public function unpair() : bool{ diff --git a/src/block/tile/ContainerTrait.php b/src/block/tile/ContainerTrait.php index b01aa59445..ae8cc8ea77 100644 --- a/src/block/tile/ContainerTrait.php +++ b/src/block/tile/ContainerTrait.php @@ -84,14 +84,14 @@ trait ContainerTrait{ /** * @see Position::asPosition() */ - abstract protected function getPos() : Position; + abstract protected function getPosition() : Position; /** * @see Tile::onBlockDestroyedHook() */ protected function onBlockDestroyedHook() : void{ $inv = $this->getRealInventory(); - $pos = $this->getPos(); + $pos = $this->getPosition(); foreach($inv->getContents() as $k => $item){ $pos->getWorld()->dropItem($pos->add(0.5, 0.5, 0.5), $item); diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index 42d460c941..6f2533e868 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -59,7 +59,7 @@ abstract class Furnace extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); - $this->inventory = new FurnaceInventory($this->pos, $this->getFurnaceType()); + $this->inventory = new FurnaceInventory($this->position, $this->getFurnaceType()); $this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange( static function(Inventory $unused) use ($world, $pos) : void{ $world->scheduleDelayedBlockUpdate($pos, 1); @@ -137,7 +137,7 @@ abstract class Furnace extends Spawnable implements Container, Nameable{ $block = $this->getBlock(); if($block instanceof BlockFurnace and !$block->isLit()){ $block->setLit(true); - $this->pos->getWorld()->setBlock($block->getPos(), $block); + $this->position->getWorld()->setBlock($block->getPosition(), $block); } } @@ -145,7 +145,7 @@ abstract class Furnace extends Spawnable implements Container, Nameable{ $block = $this->getBlock(); if($block instanceof BlockFurnace and $block->isLit()){ $block->setLit(false); - $this->pos->getWorld()->setBlock($block->getPos(), $block); + $this->position->getWorld()->setBlock($block->getPosition(), $block); } } @@ -170,7 +170,7 @@ abstract class Furnace extends Spawnable implements Container, Nameable{ $product = $this->inventory->getResult(); $furnaceType = $this->getFurnaceType(); - $smelt = $this->pos->getWorld()->getServer()->getCraftingManager()->getFurnaceRecipeManager($furnaceType)->match($raw); + $smelt = $this->position->getWorld()->getServer()->getCraftingManager()->getFurnaceRecipeManager($furnaceType)->match($raw); $canSmelt = ($smelt instanceof FurnaceRecipe and $raw->getCount() > 0 and (($smelt->getResult()->equals($product) and $product->getCount() < $product->getMaxStackSize()) or $product->isNull())); if($this->remainingFuelTime <= 0 and $canSmelt and $fuel->getFuelTime() > 0 and $fuel->getCount() > 0){ diff --git a/src/block/tile/Hopper.php b/src/block/tile/Hopper.php index fe1501c157..9ebb429ef2 100644 --- a/src/block/tile/Hopper.php +++ b/src/block/tile/Hopper.php @@ -43,7 +43,7 @@ class Hopper extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); - $this->inventory = new HopperInventory($this->pos); + $this->inventory = new HopperInventory($this->position); } public function readSaveData(CompoundTag $nbt) : void{ diff --git a/src/block/tile/ShulkerBox.php b/src/block/tile/ShulkerBox.php index a2e3bbb363..fb740c5663 100644 --- a/src/block/tile/ShulkerBox.php +++ b/src/block/tile/ShulkerBox.php @@ -46,7 +46,7 @@ class ShulkerBox extends Spawnable implements Container, Nameable{ public function __construct(World $world, Vector3 $pos){ parent::__construct($world, $pos); - $this->inventory = new ShulkerBoxInventory($this->pos); + $this->inventory = new ShulkerBoxInventory($this->position); } public function readSaveData(CompoundTag $nbt) : void{ diff --git a/src/block/tile/Spawnable.php b/src/block/tile/Spawnable.php index c81b71138d..5b62f1980f 100644 --- a/src/block/tile/Spawnable.php +++ b/src/block/tile/Spawnable.php @@ -67,9 +67,9 @@ abstract class Spawnable extends Tile{ final public function getSpawnCompound() : CompoundTag{ $nbt = CompoundTag::create() ->setString(self::TAG_ID, TileFactory::getInstance()->getSaveId(get_class($this))) //TODO: disassociate network ID from save ID - ->setInt(self::TAG_X, $this->pos->x) - ->setInt(self::TAG_Y, $this->pos->y) - ->setInt(self::TAG_Z, $this->pos->z); + ->setInt(self::TAG_X, $this->position->x) + ->setInt(self::TAG_Y, $this->position->y) + ->setInt(self::TAG_Z, $this->position->z); $this->addAdditionalSpawnData($nbt); return $nbt; } diff --git a/src/block/tile/Tile.php b/src/block/tile/Tile.php index 368c2f28b2..00ff1bed64 100644 --- a/src/block/tile/Tile.php +++ b/src/block/tile/Tile.php @@ -46,14 +46,14 @@ abstract class Tile{ public const TAG_Z = "z"; /** @var Position */ - protected $pos; + protected $position; /** @var bool */ public $closed = false; /** @var TimingsHandler */ protected $timings; public function __construct(World $world, Vector3 $pos){ - $this->pos = Position::fromObject($pos, $world); + $this->position = Position::fromObject($pos, $world); $this->timings = Timings::getTileEntityTimings($this); } @@ -72,9 +72,9 @@ abstract class Tile{ public function saveNBT() : CompoundTag{ $nbt = CompoundTag::create() ->setString(self::TAG_ID, TileFactory::getInstance()->getSaveId(get_class($this))) - ->setInt(self::TAG_X, $this->pos->getFloorX()) - ->setInt(self::TAG_Y, $this->pos->getFloorY()) - ->setInt(self::TAG_Z, $this->pos->getFloorZ()); + ->setInt(self::TAG_X, $this->position->getFloorX()) + ->setInt(self::TAG_Y, $this->position->getFloorY()) + ->setInt(self::TAG_Z, $this->position->getFloorZ()); $this->writeSaveData($nbt); return $nbt; @@ -97,11 +97,11 @@ abstract class Tile{ } public function getBlock() : Block{ - return $this->pos->getWorld()->getBlock($this->pos); + return $this->position->getWorld()->getBlock($this->position); } - public function getPos() : Position{ - return $this->pos; + public function getPosition() : Position{ + return $this->position; } public function isClosed() : bool{ @@ -131,8 +131,8 @@ abstract class Tile{ if(!$this->closed){ $this->closed = true; - if($this->pos->isValid()){ - $this->pos->getWorld()->removeTile($this); + if($this->position->isValid()){ + $this->position->getWorld()->removeTile($this); } } } diff --git a/src/block/utils/FallableTrait.php b/src/block/utils/FallableTrait.php index c0d2760573..33f71a8902 100644 --- a/src/block/utils/FallableTrait.php +++ b/src/block/utils/FallableTrait.php @@ -41,14 +41,14 @@ use pocketmine\world\Position; */ trait FallableTrait{ - abstract protected function getPos() : Position; + abstract protected function getPosition() : Position; abstract protected function getId() : int; abstract protected function getMeta() : int; public function onNearbyBlockChange() : void{ - $pos = $this->getPos(); + $pos = $this->getPosition(); $down = $pos->getWorld()->getBlock($pos->getSide(Facing::DOWN)); if($down->getId() === BlockLegacyIds::AIR or $down instanceof Liquid or $down instanceof Fire){ $pos->getWorld()->setBlock($pos, VanillaBlocks::AIR()); diff --git a/src/entity/projectile/Projectile.php b/src/entity/projectile/Projectile.php index 944728452f..6d28b2eaaa 100644 --- a/src/entity/projectile/Projectile.php +++ b/src/entity/projectile/Projectile.php @@ -141,7 +141,7 @@ abstract class Projectile extends Entity{ $nbt->setDouble("damage", $this->damage); if($this->blockHit !== null){ - $pos = $this->blockHit->getPos(); + $pos = $this->blockHit->getPosition(); $nbt->setInt("tileX", $pos->x); $nbt->setInt("tileY", $pos->y); $nbt->setInt("tileZ", $pos->z); @@ -159,7 +159,7 @@ abstract class Projectile extends Entity{ } public function onNearbyBlockChange() : void{ - if($this->blockHit !== null and $this->getWorld()->isInLoadedTerrain($this->blockHit->getPos()) and !$this->blockHit->isSameState($this->getWorld()->getBlock($this->blockHit->getPos()))){ + if($this->blockHit !== null and $this->getWorld()->isInLoadedTerrain($this->blockHit->getPosition()) and !$this->blockHit->isSameState($this->getWorld()->getBlock($this->blockHit->getPosition()))){ $this->blockHit = null; } diff --git a/src/entity/projectile/SplashPotion.php b/src/entity/projectile/SplashPotion.php index 49bb264c05..a7ecfa47a3 100644 --- a/src/entity/projectile/SplashPotion.php +++ b/src/entity/projectile/SplashPotion.php @@ -133,11 +133,11 @@ class SplashPotion extends Throwable{ $blockIn = $event->getBlockHit()->getSide($event->getRayTraceResult()->getHitFace()); if($blockIn->getId() === BlockLegacyIds::FIRE){ - $this->getWorld()->setBlock($blockIn->getPos(), VanillaBlocks::AIR()); + $this->getWorld()->setBlock($blockIn->getPosition(), VanillaBlocks::AIR()); } foreach($blockIn->getHorizontalSides() as $horizontalSide){ if($horizontalSide->getId() === BlockLegacyIds::FIRE){ - $this->getWorld()->setBlock($horizontalSide->getPos(), VanillaBlocks::AIR()); + $this->getWorld()->setBlock($horizontalSide->getPosition(), VanillaBlocks::AIR()); } } } diff --git a/src/item/Bucket.php b/src/item/Bucket.php index 2cf0ac55ff..b7fd2a19f3 100644 --- a/src/item/Bucket.php +++ b/src/item/Bucket.php @@ -46,8 +46,8 @@ class Bucket extends Item{ $ev = new PlayerBucketFillEvent($player, $blockReplace, $face, $this, $resultItem); $ev->call(); if(!$ev->isCancelled()){ - $player->getWorld()->setBlock($blockClicked->getPos(), VanillaBlocks::AIR()); - $player->getWorld()->addSound($blockClicked->getPos()->add(0.5, 0.5, 0.5), $blockClicked->getBucketFillSound()); + $player->getWorld()->setBlock($blockClicked->getPosition(), VanillaBlocks::AIR()); + $player->getWorld()->addSound($blockClicked->getPosition()->add(0.5, 0.5, 0.5), $blockClicked->getBucketFillSound()); if($player->hasFiniteResources()){ if($stack->getCount() === 0){ $player->getInventory()->setItemInHand($ev->getItem()); diff --git a/src/item/FlintSteel.php b/src/item/FlintSteel.php index d5088e6415..ee387f4e68 100644 --- a/src/item/FlintSteel.php +++ b/src/item/FlintSteel.php @@ -35,8 +35,8 @@ class FlintSteel extends Tool{ public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ if($blockReplace->getId() === BlockLegacyIds::AIR){ $world = $player->getWorld(); - $world->setBlock($blockReplace->getPos(), VanillaBlocks::FIRE()); - $world->addSound($blockReplace->getPos()->add(0.5, 0.5, 0.5), new FlintSteelSound()); + $world->setBlock($blockReplace->getPosition(), VanillaBlocks::FIRE()); + $world->addSound($blockReplace->getPosition()->add(0.5, 0.5, 0.5), new FlintSteelSound()); $this->applyDamage(1); diff --git a/src/item/LiquidBucket.php b/src/item/LiquidBucket.php index 5291e6e9cb..710e37ba1a 100644 --- a/src/item/LiquidBucket.php +++ b/src/item/LiquidBucket.php @@ -67,8 +67,8 @@ class LiquidBucket extends Item{ $ev = new PlayerBucketEmptyEvent($player, $blockReplace, $face, $this, VanillaItems::BUCKET()); $ev->call(); if(!$ev->isCancelled()){ - $player->getWorld()->setBlock($blockReplace->getPos(), $resultBlock->getFlowingForm()); - $player->getWorld()->addSound($blockReplace->getPos()->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound()); + $player->getWorld()->setBlock($blockReplace->getPosition(), $resultBlock->getFlowingForm()); + $player->getWorld()->addSound($blockReplace->getPosition()->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound()); if($player->hasFiniteResources()){ $player->getInventory()->setItemInHand($ev->getItem()); diff --git a/src/item/PaintingItem.php b/src/item/PaintingItem.php index d640e061ef..061f837ca8 100644 --- a/src/item/PaintingItem.php +++ b/src/item/PaintingItem.php @@ -51,7 +51,7 @@ class PaintingItem extends Item{ continue; } - if(Painting::canFit($player->getWorld(), $blockReplace->getPos(), $face, true, $motive)){ + if(Painting::canFit($player->getWorld(), $blockReplace->getPosition(), $face, true, $motive)){ if($currentTotalDimension > $totalDimension){ $totalDimension = $currentTotalDimension; /* @@ -73,8 +73,8 @@ class PaintingItem extends Item{ /** @var PaintingMotive $motive */ $motive = $motives[array_rand($motives)]; - $replacePos = $blockReplace->getPos(); - $clickedPos = $blockClicked->getPos(); + $replacePos = $blockReplace->getPosition(); + $clickedPos = $blockClicked->getPosition(); $entity = new Painting(Location::fromObject($replacePos, $replacePos->getWorld()), $clickedPos, $face, $motive); $this->pop(); diff --git a/src/item/SpawnEgg.php b/src/item/SpawnEgg.php index e41e3997d0..e905c5f2b8 100644 --- a/src/item/SpawnEgg.php +++ b/src/item/SpawnEgg.php @@ -35,7 +35,7 @@ abstract class SpawnEgg extends Item{ abstract protected function createEntity(World $world, Vector3 $pos, float $yaw, float $pitch) : Entity; public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{ - $entity = $this->createEntity($player->getWorld(), $blockReplace->getPos()->add(0.5, 0, 0.5), lcg_value() * 360, 0); + $entity = $this->createEntity($player->getWorld(), $blockReplace->getPosition()->add(0.5, 0, 0.5), lcg_value() * 360, 0); if($this->hasCustomName()){ $entity->setNameTag($this->getCustomName()); diff --git a/src/player/Player.php b/src/player/Player.php index 76cdc8db37..a76d1b52ab 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1526,8 +1526,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $block = $target->getSide($face); if($block->getId() === BlockLegacyIds::FIRE){ - $this->getWorld()->setBlock($block->getPos(), VanillaBlocks::AIR()); - $this->getWorld()->addSound($block->getPos()->add(0.5, 0.5, 0.5), new FireExtinguishSound()); + $this->getWorld()->setBlock($block->getPosition(), VanillaBlocks::AIR()); + $this->getWorld()->addSound($block->getPosition()->add(0.5, 0.5, 0.5), new FireExtinguishSound()); return true; } diff --git a/src/world/Explosion.php b/src/world/Explosion.php index db27b472e0..3689ec5479 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -138,7 +138,7 @@ class Explosion{ $_block = $blockFactory->fromFullBlock($state); $_block->position($this->world, $vBlockX, $vBlockY, $vBlockZ); foreach($_block->getAffectedBlocks() as $_affectedBlock){ - $_affectedBlockPos = $_affectedBlock->getPos(); + $_affectedBlockPos = $_affectedBlock->getPosition(); $this->affectedBlocks[World::blockHash($_affectedBlockPos->x, $_affectedBlockPos->y, $_affectedBlockPos->z)] = $_affectedBlock; } } @@ -214,7 +214,7 @@ class Explosion{ $airBlock = VanillaBlocks::AIR(); foreach($this->affectedBlocks as $block){ - $pos = $block->getPos(); + $pos = $block->getPosition(); if($block instanceof TNT){ $block->ignite(mt_rand(10, 30)); }else{ @@ -232,7 +232,7 @@ class Explosion{ } foreach($this->affectedBlocks as $block){ - $pos = $block->getPos(); + $pos = $block->getPosition(); foreach(Facing::ALL as $side){ $sideBlock = $pos->getSide($side); if(!$this->world->isInWorld($sideBlock->x, $sideBlock->y, $sideBlock->z)){ diff --git a/src/world/World.php b/src/world/World.php index 43bf9b4c8c..5914e9d994 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1563,7 +1563,7 @@ class World implements ChunkManager{ $block->position($this, $x, $y, $z); $block->writeStateToWorld(); - $pos = $block->getPos(); + $pos = $block->getPosition(); $chunkHash = World::chunkHash($x >> 4, $z >> 4); $relativeBlockHash = World::chunkBlockHash($x, $y, $z); @@ -1718,12 +1718,12 @@ class World implements ChunkManager{ private function destroyBlockInternal(Block $target, Item $item, ?Player $player = null, bool $createParticles = false) : void{ if($createParticles){ - $this->addParticle($target->getPos()->add(0.5, 0.5, 0.5), new BlockBreakParticle($target)); + $this->addParticle($target->getPosition()->add(0.5, 0.5, 0.5), new BlockBreakParticle($target)); } $target->onBreak($item, $player); - $tile = $this->getTile($target->getPos()); + $tile = $this->getTile($target->getPosition()); if($tile !== null){ $tile->onBlockDestroyed(); } @@ -1743,12 +1743,12 @@ class World implements ChunkManager{ $clickVector = new Vector3(0.0, 0.0, 0.0); } - if(!$this->isInWorld($blockReplace->getPos()->x, $blockReplace->getPos()->y, $blockReplace->getPos()->z)){ + if(!$this->isInWorld($blockReplace->getPosition()->x, $blockReplace->getPosition()->y, $blockReplace->getPosition()->z)){ //TODO: build height limit messages for custom world heights and mcregion cap return false; } - $chunkX = $blockReplace->getPos()->getFloorX() >> 4; - $chunkZ = $blockReplace->getPos()->getFloorZ() >> 4; + $chunkX = $blockReplace->getPosition()->getFloorX() >> 4; + $chunkZ = $blockReplace->getPosition()->getFloorZ() >> 4; if(!$this->isChunkLoaded($chunkX, $chunkZ) || !$this->isChunkGenerated($chunkX, $chunkZ) || $this->isChunkLocked($chunkX, $chunkZ)){ return false; } @@ -1782,14 +1782,14 @@ class World implements ChunkManager{ if($item->canBePlaced()){ $hand = $item->getBlock($face); - $hand->position($this, $blockReplace->getPos()->x, $blockReplace->getPos()->y, $blockReplace->getPos()->z); + $hand->position($this, $blockReplace->getPosition()->x, $blockReplace->getPosition()->y, $blockReplace->getPosition()->z); }else{ return false; } if($hand->canBePlacedAt($blockClicked, $clickVector, $face, true)){ $blockReplace = $blockClicked; - $hand->position($this, $blockReplace->getPos()->x, $blockReplace->getPos()->y, $blockReplace->getPos()->z); + $hand->position($this, $blockReplace->getPosition()->x, $blockReplace->getPosition()->y, $blockReplace->getPosition()->z); }elseif(!$hand->canBePlacedAt($blockReplace, $clickVector, $face, false)){ return false; } @@ -1850,7 +1850,7 @@ class World implements ChunkManager{ } if($playSound){ - $this->addSound($hand->getPos(), new BlockPlaceSound($hand)); + $this->addSound($hand->getPosition(), new BlockPlaceSound($hand)); } $item->pop(); @@ -2367,7 +2367,7 @@ class World implements ChunkManager{ if($tile->isClosed()){ throw new \InvalidArgumentException("Attempted to add a garbage closed Tile to world"); } - $pos = $tile->getPos(); + $pos = $tile->getPosition(); if(!$pos->isValid() || $pos->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Tile world"); } @@ -2390,7 +2390,7 @@ class World implements ChunkManager{ * @throws \InvalidArgumentException */ public function removeTile(Tile $tile) : void{ - $pos = $tile->getPos(); + $pos = $tile->getPosition(); if(!$pos->isValid() || $pos->getWorld() !== $this){ throw new \InvalidArgumentException("Invalid Tile world"); } @@ -2507,7 +2507,7 @@ class World implements ChunkManager{ } if($tile === null){ $this->getLogger()->warning("Chunk $chunkX $chunkZ: Deleted unknown tile entity type " . $nbt->getString("id", "")); - }elseif(!$this->isChunkLoaded($tile->getPos()->getFloorX() >> 4, $tile->getPos()->getFloorZ() >> 4)){ + }elseif(!$this->isChunkLoaded($tile->getPosition()->getFloorX() >> 4, $tile->getPosition()->getFloorZ() >> 4)){ $this->logger->error("Chunk $chunkX $chunkZ: Found tile saved on wrong chunk - unable to fix due to correct chunk not loaded"); }else{ $this->addTile($tile); diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index a43cd4a8bf..e51eeec05f 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -228,7 +228,7 @@ class Chunk{ throw new \InvalidArgumentException("Attempted to add a garbage closed Tile to a chunk"); } - $pos = $tile->getPos(); + $pos = $tile->getPosition(); if(isset($this->tiles[$index = Chunk::blockHash($pos->x, $pos->y, $pos->z)]) and $this->tiles[$index] !== $tile){ throw new \InvalidArgumentException("Another tile is already at this location"); } @@ -237,7 +237,7 @@ class Chunk{ } public function removeTile(Tile $tile) : void{ - $pos = $tile->getPos(); + $pos = $tile->getPosition(); unset($this->tiles[Chunk::blockHash($pos->x, $pos->y, $pos->z)]); $this->dirtyFlags |= self::DIRTY_FLAG_TILES; } From 78b0275a6c4dd2f11b951fe54ea9b11e61fcc339 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 23 Aug 2021 14:24:39 +0100 Subject: [PATCH 2739/3224] StringToItemParser: added a bunch of nice new aliases this should especially make potions less cancerous to /give. --- src/item/StringToItemParser.php | 188 ++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) diff --git a/src/item/StringToItemParser.php b/src/item/StringToItemParser.php index 3d9f504c2b..e2b7258dac 100644 --- a/src/item/StringToItemParser.php +++ b/src/item/StringToItemParser.php @@ -25,6 +25,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\block\utils\CoralType; +use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\SlabType; use pocketmine\block\VanillaBlocks; use pocketmine\utils\SingletonTrait; @@ -50,6 +51,30 @@ final class StringToItemParser{ private static function make() : self{ $result = new self; + foreach(DyeColor::getAll() as $color){ + $prefix = fn(string $name) => $color->name() . "_" . $name; + //wall and floor banner are the same item + $result->registerBlock($prefix("banner"), fn() => VanillaBlocks::BANNER()->setColor($color)); + $result->registerBlock($prefix("bed"), fn() => VanillaBlocks::BED()->setColor($color)); + $result->registerBlock($prefix("carpet"), fn() => VanillaBlocks::CARPET()->setColor($color)); + $result->registerBlock($prefix("concrete"), fn() => VanillaBlocks::CONCRETE()->setColor($color)); + $result->registerBlock($prefix("concrete_powder"), fn() => VanillaBlocks::CONCRETE()->setColor($color)); + $result->registerBlock($prefix("stained_clay"), fn() => VanillaBlocks::STAINED_CLAY()->setColor($color)); + $result->registerBlock($prefix("stained_glass"), fn() => VanillaBlocks::STAINED_GLASS()->setColor($color)); + $result->registerBlock($prefix("stained_glass_pane"), fn() => VanillaBlocks::STAINED_GLASS_PANE()->setColor($color)); + $result->registerBlock($prefix("stained_hardened_glass"), fn() => VanillaBlocks::STAINED_HARDENED_GLASS()->setColor($color)); + $result->registerBlock($prefix("stained_hardened_glass_pane"), fn() => VanillaBlocks::STAINED_HARDENED_GLASS_PANE()->setColor($color)); + $result->registerBlock($prefix("wool"), fn() => VanillaBlocks::WOOL()->setColor($color)); + $result->registerBlock($prefix("shulker_box"), fn() => VanillaBlocks::DYED_SHULKER_BOX()->setColor($color)); + } + foreach(CoralType::getAll() as $coralType){ + $prefix = fn(string $name) => $coralType->name() . "_" . $name; + $result->registerBlock($prefix("coral"), fn() => VanillaBlocks::CORAL()->setCoralType($coralType)); + $result->registerBlock($prefix("coral_block"), fn() => VanillaBlocks::CORAL_BLOCK()->setCoralType($coralType)); + //wall and floor coral fans are the same item + $result->registerBlock($prefix("coral_fan"), fn() => VanillaBlocks::CORAL_FAN()->setCoralType($coralType)); + } + $result->registerBlock("acacia_button", fn() => VanillaBlocks::ACACIA_BUTTON()); $result->registerBlock("acacia_door", fn() => VanillaBlocks::ACACIA_DOOR()); $result->registerBlock("acacia_door_block", fn() => VanillaBlocks::ACACIA_DOOR()); @@ -625,10 +650,13 @@ final class StringToItemParser{ $result->registerBlock("yellow_flower", fn() => VanillaBlocks::DANDELION()); $result->registerBlock("yellow_glazed_terracotta", fn() => VanillaBlocks::YELLOW_GLAZED_TERRACOTTA()); + $result->register("acacia_boat", fn() => VanillaItems::ACACIA_BOAT()); $result->register("apple", fn() => VanillaItems::APPLE()); $result->register("apple_enchanted", fn() => VanillaItems::ENCHANTED_GOLDEN_APPLE()); $result->register("appleenchanted", fn() => VanillaItems::ENCHANTED_GOLDEN_APPLE()); $result->register("arrow", fn() => VanillaItems::ARROW()); + $result->register("awkward_potion", fn() => VanillaItems::AWKWARD_POTION()); + $result->register("awkward_splash_potion", fn() => VanillaItems::AWKWARD_SPLASH_POTION()); $result->register("baked_potato", fn() => VanillaItems::BAKED_POTATO()); $result->register("baked_potatoes", fn() => VanillaItems::BAKED_POTATO()); $result->register("bed", fn() => VanillaItems::WHITE_BED()); @@ -637,17 +665,22 @@ final class StringToItemParser{ $result->register("beetroot_seed", fn() => VanillaItems::BEETROOT_SEEDS()); $result->register("beetroot_seeds", fn() => VanillaItems::BEETROOT_SEEDS()); $result->register("beetroot_soup", fn() => VanillaItems::BEETROOT_SOUP()); + $result->register("birch_boat", fn() => VanillaItems::BIRCH_BOAT()); + $result->register("black_dye", fn() => VanillaItems::BLACK_DYE()); $result->register("blaze_powder", fn() => VanillaItems::BLAZE_POWDER()); $result->register("blaze_rod", fn() => VanillaItems::BLAZE_ROD()); $result->register("bleach", fn() => VanillaItems::BLEACH()); + $result->register("blue_dye", fn() => VanillaItems::BLUE_DYE()); $result->register("boat", fn() => VanillaItems::OAK_BOAT()); $result->register("bone", fn() => VanillaItems::BONE()); + $result->register("bone_meal", fn() => VanillaItems::BONE_MEAL()); $result->register("book", fn() => VanillaItems::BOOK()); $result->register("bottle_o_enchanting", fn() => VanillaItems::EXPERIENCE_BOTTLE()); $result->register("bow", fn() => VanillaItems::BOW()); $result->register("bowl", fn() => VanillaItems::BOWL()); $result->register("bread", fn() => VanillaItems::BREAD()); $result->register("brick", fn() => VanillaItems::BRICK()); + $result->register("brown_dye", fn() => VanillaItems::BROWN_DYE()); $result->register("bucket", fn() => VanillaItems::BUCKET()); $result->register("carrot", fn() => VanillaItems::CARROT()); $result->register("chain_boots", fn() => VanillaItems::CHAINMAIL_BOOTS()); @@ -658,6 +691,45 @@ final class StringToItemParser{ $result->register("chainmail_chestplate", fn() => VanillaItems::CHAINMAIL_CHESTPLATE()); $result->register("chainmail_helmet", fn() => VanillaItems::CHAINMAIL_HELMET()); $result->register("chainmail_leggings", fn() => VanillaItems::CHAINMAIL_LEGGINGS()); + $result->register("charcoal", fn() => VanillaItems::CHARCOAL()); + $result->register("chemical_aluminium_oxide", fn() => VanillaItems::CHEMICAL_ALUMINIUM_OXIDE()); + $result->register("chemical_ammonia", fn() => VanillaItems::CHEMICAL_AMMONIA()); + $result->register("chemical_barium_sulphate", fn() => VanillaItems::CHEMICAL_BARIUM_SULPHATE()); + $result->register("chemical_benzene", fn() => VanillaItems::CHEMICAL_BENZENE()); + $result->register("chemical_boron_trioxide", fn() => VanillaItems::CHEMICAL_BORON_TRIOXIDE()); + $result->register("chemical_calcium_bromide", fn() => VanillaItems::CHEMICAL_CALCIUM_BROMIDE()); + $result->register("chemical_calcium_chloride", fn() => VanillaItems::CHEMICAL_CALCIUM_CHLORIDE()); + $result->register("chemical_cerium_chloride", fn() => VanillaItems::CHEMICAL_CERIUM_CHLORIDE()); + $result->register("chemical_charcoal", fn() => VanillaItems::CHEMICAL_CHARCOAL()); + $result->register("chemical_crude_oil", fn() => VanillaItems::CHEMICAL_CRUDE_OIL()); + $result->register("chemical_glue", fn() => VanillaItems::CHEMICAL_GLUE()); + $result->register("chemical_hydrogen_peroxide", fn() => VanillaItems::CHEMICAL_HYDROGEN_PEROXIDE()); + $result->register("chemical_hypochlorite", fn() => VanillaItems::CHEMICAL_HYPOCHLORITE()); + $result->register("chemical_ink", fn() => VanillaItems::CHEMICAL_INK()); + $result->register("chemical_iron_sulphide", fn() => VanillaItems::CHEMICAL_IRON_SULPHIDE()); + $result->register("chemical_latex", fn() => VanillaItems::CHEMICAL_LATEX()); + $result->register("chemical_lithium_hydride", fn() => VanillaItems::CHEMICAL_LITHIUM_HYDRIDE()); + $result->register("chemical_luminol", fn() => VanillaItems::CHEMICAL_LUMINOL()); + $result->register("chemical_magnesium_nitrate", fn() => VanillaItems::CHEMICAL_MAGNESIUM_NITRATE()); + $result->register("chemical_magnesium_oxide", fn() => VanillaItems::CHEMICAL_MAGNESIUM_OXIDE()); + $result->register("chemical_magnesium_salts", fn() => VanillaItems::CHEMICAL_MAGNESIUM_SALTS()); + $result->register("chemical_mercuric_chloride", fn() => VanillaItems::CHEMICAL_MERCURIC_CHLORIDE()); + $result->register("chemical_polyethylene", fn() => VanillaItems::CHEMICAL_POLYETHYLENE()); + $result->register("chemical_potassium_chloride", fn() => VanillaItems::CHEMICAL_POTASSIUM_CHLORIDE()); + $result->register("chemical_potassium_iodide", fn() => VanillaItems::CHEMICAL_POTASSIUM_IODIDE()); + $result->register("chemical_rubbish", fn() => VanillaItems::CHEMICAL_RUBBISH()); + $result->register("chemical_salt", fn() => VanillaItems::CHEMICAL_SALT()); + $result->register("chemical_soap", fn() => VanillaItems::CHEMICAL_SOAP()); + $result->register("chemical_sodium_acetate", fn() => VanillaItems::CHEMICAL_SODIUM_ACETATE()); + $result->register("chemical_sodium_fluoride", fn() => VanillaItems::CHEMICAL_SODIUM_FLUORIDE()); + $result->register("chemical_sodium_hydride", fn() => VanillaItems::CHEMICAL_SODIUM_HYDRIDE()); + $result->register("chemical_sodium_hydroxide", fn() => VanillaItems::CHEMICAL_SODIUM_HYDROXIDE()); + $result->register("chemical_sodium_hypochlorite", fn() => VanillaItems::CHEMICAL_SODIUM_HYPOCHLORITE()); + $result->register("chemical_sodium_oxide", fn() => VanillaItems::CHEMICAL_SODIUM_OXIDE()); + $result->register("chemical_sugar", fn() => VanillaItems::CHEMICAL_SUGAR()); + $result->register("chemical_sulphate", fn() => VanillaItems::CHEMICAL_SULPHATE()); + $result->register("chemical_tungsten_chloride", fn() => VanillaItems::CHEMICAL_TUNGSTEN_CHLORIDE()); + $result->register("chemical_water", fn() => VanillaItems::CHEMICAL_WATER()); $result->register("chicken", fn() => VanillaItems::RAW_CHICKEN()); $result->register("chorus_fruit", fn() => VanillaItems::CHORUS_FRUIT()); $result->register("chorus_fruit_popped", fn() => VanillaItems::POPPED_CHORUS_FRUIT()); @@ -667,6 +739,7 @@ final class StringToItemParser{ $result->register("clown_fish", fn() => VanillaItems::CLOWNFISH()); $result->register("clownfish", fn() => VanillaItems::CLOWNFISH()); $result->register("coal", fn() => VanillaItems::COAL()); + $result->register("cocoa_beans", fn() => VanillaItems::COCOA_BEANS()); $result->register("compass", fn() => VanillaItems::COMPASS()); $result->register("compound", fn() => VanillaItems::CHEMICAL_SALT()); $result->register("cooked_beef", fn() => VanillaItems::STEAK()); @@ -677,6 +750,9 @@ final class StringToItemParser{ $result->register("cooked_rabbit", fn() => VanillaItems::COOKED_RABBIT()); $result->register("cooked_salmon", fn() => VanillaItems::COOKED_SALMON()); $result->register("cookie", fn() => VanillaItems::COOKIE()); + $result->register("creeper_head", fn() => VanillaItems::CREEPER_HEAD()); + $result->register("cyan_dye", fn() => VanillaItems::CYAN_DYE()); + $result->register("dark_oak_boat", fn() => VanillaItems::DARK_OAK_BOAT()); $result->register("diamond", fn() => VanillaItems::DIAMOND()); $result->register("diamond_axe", fn() => VanillaItems::DIAMOND_AXE()); $result->register("diamond_boots", fn() => VanillaItems::DIAMOND_BOOTS()); @@ -688,6 +764,7 @@ final class StringToItemParser{ $result->register("diamond_shovel", fn() => VanillaItems::DIAMOND_SHOVEL()); $result->register("diamond_sword", fn() => VanillaItems::DIAMOND_SWORD()); $result->register("dragon_breath", fn() => VanillaItems::DRAGON_BREATH()); + $result->register("dragon_head", fn() => VanillaItems::DRAGON_HEAD()); $result->register("dried_kelp", fn() => VanillaItems::DRIED_KELP()); $result->register("dye", fn() => VanillaItems::INK_SAC()); $result->register("egg", fn() => VanillaItems::EGG()); @@ -698,6 +775,8 @@ final class StringToItemParser{ $result->register("experience_bottle", fn() => VanillaItems::EXPERIENCE_BOTTLE()); $result->register("feather", fn() => VanillaItems::FEATHER()); $result->register("fermented_spider_eye", fn() => VanillaItems::FERMENTED_SPIDER_EYE()); + $result->register("fire_resistance_potion", fn() => VanillaItems::FIRE_RESISTANCE_POTION()); + $result->register("fire_resistance_splash_potion", fn() => VanillaItems::FIRE_RESISTANCE_SPLASH_POTION()); $result->register("fish", fn() => VanillaItems::RAW_FISH()); $result->register("fishing_rod", fn() => VanillaItems::FISHING_ROD()); $result->register("flint", fn() => VanillaItems::FLINT()); @@ -730,8 +809,17 @@ final class StringToItemParser{ $result->register("golden_pickaxe", fn() => VanillaItems::GOLDEN_PICKAXE()); $result->register("golden_shovel", fn() => VanillaItems::GOLDEN_SHOVEL()); $result->register("golden_sword", fn() => VanillaItems::GOLDEN_SWORD()); + $result->register("gray_dye", fn() => VanillaItems::GRAY_DYE()); + $result->register("green_dye", fn() => VanillaItems::GREEN_DYE()); $result->register("gunpowder", fn() => VanillaItems::GUNPOWDER()); + $result->register("harming_potion", fn() => VanillaItems::HARMING_POTION()); + $result->register("harming_splash_potion", fn() => VanillaItems::HARMING_SPLASH_POTION()); + $result->register("healing_potion", fn() => VanillaItems::HEALING_POTION()); + $result->register("healing_splash_potion", fn() => VanillaItems::HEALING_SPLASH_POTION()); $result->register("heart_of_the_sea", fn() => VanillaItems::HEART_OF_THE_SEA()); + $result->register("ink_sac", fn() => VanillaItems::INK_SAC()); + $result->register("invisibility_potion", fn() => VanillaItems::INVISIBILITY_POTION()); + $result->register("invisibility_splash_potion", fn() => VanillaItems::INVISIBILITY_SPLASH_POTION()); $result->register("iron_axe", fn() => VanillaItems::IRON_AXE()); $result->register("iron_boots", fn() => VanillaItems::IRON_BOOTS()); $result->register("iron_chestplate", fn() => VanillaItems::IRON_CHESTPLATE()); @@ -743,6 +831,11 @@ final class StringToItemParser{ $result->register("iron_pickaxe", fn() => VanillaItems::IRON_PICKAXE()); $result->register("iron_shovel", fn() => VanillaItems::IRON_SHOVEL()); $result->register("iron_sword", fn() => VanillaItems::IRON_SWORD()); + $result->register("jungle_boat", fn() => VanillaItems::JUNGLE_BOAT()); + $result->register("lapis_lazuli", fn() => VanillaItems::LAPIS_LAZULI()); + $result->register("lava_bucket", fn() => VanillaItems::LAVA_BUCKET()); + $result->register("leaping_potion", fn() => VanillaItems::LEAPING_POTION()); + $result->register("leaping_splash_potion", fn() => VanillaItems::LEAPING_SPLASH_POTION()); $result->register("leather", fn() => VanillaItems::LEATHER()); $result->register("leather_boots", fn() => VanillaItems::LEATHER_BOOTS()); $result->register("leather_cap", fn() => VanillaItems::LEATHER_CAP()); @@ -751,12 +844,47 @@ final class StringToItemParser{ $result->register("leather_leggings", fn() => VanillaItems::LEATHER_PANTS()); $result->register("leather_pants", fn() => VanillaItems::LEATHER_PANTS()); $result->register("leather_tunic", fn() => VanillaItems::LEATHER_TUNIC()); + $result->register("light_blue_dye", fn() => VanillaItems::LIGHT_BLUE_DYE()); + $result->register("light_gray_dye", fn() => VanillaItems::LIGHT_GRAY_DYE()); + $result->register("lime_dye", fn() => VanillaItems::LIME_DYE()); + $result->register("long_fire_resistance_potion", fn() => VanillaItems::LONG_FIRE_RESISTANCE_POTION()); + $result->register("long_fire_resistance_splash_potion", fn() => VanillaItems::LONG_FIRE_RESISTANCE_SPLASH_POTION()); + $result->register("long_invisibility_potion", fn() => VanillaItems::LONG_INVISIBILITY_POTION()); + $result->register("long_invisibility_splash_potion", fn() => VanillaItems::LONG_INVISIBILITY_SPLASH_POTION()); + $result->register("long_leaping_potion", fn() => VanillaItems::LONG_LEAPING_POTION()); + $result->register("long_leaping_splash_potion", fn() => VanillaItems::LONG_LEAPING_SPLASH_POTION()); + $result->register("long_mundane_potion", fn() => VanillaItems::LONG_MUNDANE_POTION()); + $result->register("long_mundane_splash_potion", fn() => VanillaItems::LONG_MUNDANE_SPLASH_POTION()); + $result->register("long_night_vision_potion", fn() => VanillaItems::LONG_NIGHT_VISION_POTION()); + $result->register("long_night_vision_splash_potion", fn() => VanillaItems::LONG_NIGHT_VISION_SPLASH_POTION()); + $result->register("long_poison_potion", fn() => VanillaItems::LONG_POISON_POTION()); + $result->register("long_poison_splash_potion", fn() => VanillaItems::LONG_POISON_SPLASH_POTION()); + $result->register("long_regeneration_potion", fn() => VanillaItems::LONG_REGENERATION_POTION()); + $result->register("long_regeneration_splash_potion", fn() => VanillaItems::LONG_REGENERATION_SPLASH_POTION()); + $result->register("long_slow_falling_potion", fn() => VanillaItems::LONG_SLOW_FALLING_POTION()); + $result->register("long_slow_falling_splash_potion", fn() => VanillaItems::LONG_SLOW_FALLING_SPLASH_POTION()); + $result->register("long_slowness_potion", fn() => VanillaItems::LONG_SLOWNESS_POTION()); + $result->register("long_slowness_splash_potion", fn() => VanillaItems::LONG_SLOWNESS_SPLASH_POTION()); + $result->register("long_strength_potion", fn() => VanillaItems::LONG_STRENGTH_POTION()); + $result->register("long_strength_splash_potion", fn() => VanillaItems::LONG_STRENGTH_SPLASH_POTION()); + $result->register("long_swiftness_potion", fn() => VanillaItems::LONG_SWIFTNESS_POTION()); + $result->register("long_swiftness_splash_potion", fn() => VanillaItems::LONG_SWIFTNESS_SPLASH_POTION()); + $result->register("long_turtle_master_potion", fn() => VanillaItems::LONG_TURTLE_MASTER_POTION()); + $result->register("long_turtle_master_splash_potion", fn() => VanillaItems::LONG_TURTLE_MASTER_SPLASH_POTION()); + $result->register("long_water_breathing_potion", fn() => VanillaItems::LONG_WATER_BREATHING_POTION()); + $result->register("long_water_breathing_splash_potion", fn() => VanillaItems::LONG_WATER_BREATHING_SPLASH_POTION()); + $result->register("long_weakness_potion", fn() => VanillaItems::LONG_WEAKNESS_POTION()); + $result->register("long_weakness_splash_potion", fn() => VanillaItems::LONG_WEAKNESS_SPLASH_POTION()); + $result->register("magenta_dye", fn() => VanillaItems::MAGENTA_DYE()); $result->register("magma_cream", fn() => VanillaItems::MAGMA_CREAM()); $result->register("melon", fn() => VanillaItems::MELON()); $result->register("melon_seeds", fn() => VanillaItems::MELON_SEEDS()); $result->register("melon_slice", fn() => VanillaItems::MELON()); + $result->register("milk_bucket", fn() => VanillaItems::MILK_BUCKET()); $result->register("minecart", fn() => VanillaItems::MINECART()); $result->register("mob_head", fn() => VanillaItems::SKELETON_SKULL()); + $result->register("mundane_potion", fn() => VanillaItems::MUNDANE_POTION()); + $result->register("mundane_splash_potion", fn() => VanillaItems::MUNDANE_SPLASH_POTION()); $result->register("mushroom_stew", fn() => VanillaItems::MUSHROOM_STEW()); $result->register("mutton", fn() => VanillaItems::RAW_MUTTON()); $result->register("mutton_cooked", fn() => VanillaItems::COOKED_MUTTON()); @@ -769,9 +897,18 @@ final class StringToItemParser{ $result->register("nether_star", fn() => VanillaItems::NETHER_STAR()); $result->register("netherbrick", fn() => VanillaItems::NETHER_BRICK()); $result->register("netherstar", fn() => VanillaItems::NETHER_STAR()); + $result->register("night_vision_potion", fn() => VanillaItems::NIGHT_VISION_POTION()); + $result->register("night_vision_splash_potion", fn() => VanillaItems::NIGHT_VISION_SPLASH_POTION()); + $result->register("oak_boat", fn() => VanillaItems::OAK_BOAT()); + $result->register("orange_dye", fn() => VanillaItems::ORANGE_DYE()); $result->register("painting", fn() => VanillaItems::PAINTING()); $result->register("paper", fn() => VanillaItems::PAPER()); + $result->register("pink_dye", fn() => VanillaItems::PINK_DYE()); + $result->register("player_head", fn() => VanillaItems::PLAYER_HEAD()); + $result->register("poison_potion", fn() => VanillaItems::POISON_POTION()); + $result->register("poison_splash_potion", fn() => VanillaItems::POISON_SPLASH_POTION()); $result->register("poisonous_potato", fn() => VanillaItems::POISONOUS_POTATO()); + $result->register("popped_chorus_fruit", fn() => VanillaItems::POPPED_CHORUS_FRUIT()); $result->register("porkchop", fn() => VanillaItems::RAW_PORKCHOP()); $result->register("potato", fn() => VanillaItems::POTATO()); $result->register("potion", fn() => VanillaItems::WATER_POTION()); @@ -781,6 +918,7 @@ final class StringToItemParser{ $result->register("pufferfish", fn() => VanillaItems::PUFFERFISH()); $result->register("pumpkin_pie", fn() => VanillaItems::PUMPKIN_PIE()); $result->register("pumpkin_seeds", fn() => VanillaItems::PUMPKIN_SEEDS()); + $result->register("purple_dye", fn() => VanillaItems::PURPLE_DYE()); $result->register("quartz", fn() => VanillaItems::NETHER_QUARTZ()); $result->register("rabbit", fn() => VanillaItems::RAW_RABBIT()); $result->register("rabbit_foot", fn() => VanillaItems::RABBIT_FOOT()); @@ -805,20 +943,31 @@ final class StringToItemParser{ $result->register("record_strad", fn() => VanillaItems::RECORD_STRAD()); $result->register("record_wait", fn() => VanillaItems::RECORD_WAIT()); $result->register("record_ward", fn() => VanillaItems::RECORD_WARD()); + $result->register("red_dye", fn() => VanillaItems::RED_DYE()); $result->register("redstone", fn() => VanillaItems::REDSTONE_DUST()); $result->register("redstone_dust", fn() => VanillaItems::REDSTONE_DUST()); + $result->register("regeneration_potion", fn() => VanillaItems::REGENERATION_POTION()); + $result->register("regeneration_splash_potion", fn() => VanillaItems::REGENERATION_SPLASH_POTION()); $result->register("rotten_flesh", fn() => VanillaItems::ROTTEN_FLESH()); $result->register("salmon", fn() => VanillaItems::RAW_SALMON()); + $result->register("scute", fn() => VanillaItems::SCUTE()); $result->register("seeds", fn() => VanillaItems::WHEAT_SEEDS()); $result->register("shears", fn() => VanillaItems::SHEARS()); $result->register("shulker_shell", fn() => VanillaItems::SHULKER_SHELL()); + $result->register("skeleton_skull", fn() => VanillaItems::SKELETON_SKULL()); $result->register("skull", fn() => VanillaItems::SKELETON_SKULL()); $result->register("slime_ball", fn() => VanillaItems::SLIMEBALL()); $result->register("slimeball", fn() => VanillaItems::SLIMEBALL()); + $result->register("slow_falling_potion", fn() => VanillaItems::SLOW_FALLING_POTION()); + $result->register("slow_falling_splash_potion", fn() => VanillaItems::SLOW_FALLING_SPLASH_POTION()); + $result->register("slowness_potion", fn() => VanillaItems::SLOWNESS_POTION()); + $result->register("slowness_splash_potion", fn() => VanillaItems::SLOWNESS_SPLASH_POTION()); $result->register("snowball", fn() => VanillaItems::SNOWBALL()); $result->register("speckled_melon", fn() => VanillaItems::GLISTERING_MELON()); $result->register("spider_eye", fn() => VanillaItems::SPIDER_EYE()); $result->register("splash_potion", fn() => VanillaItems::WATER_SPLASH_POTION()); + $result->register("spruce_boat", fn() => VanillaItems::SPRUCE_BOAT()); + $result->register("squid_spawn_egg", fn() => VanillaItems::SQUID_SPAWN_EGG()); $result->register("steak", fn() => VanillaItems::STEAK()); $result->register("stick", fn() => VanillaItems::STICK()); $result->register("sticks", fn() => VanillaItems::STICK()); @@ -827,13 +976,49 @@ final class StringToItemParser{ $result->register("stone_pickaxe", fn() => VanillaItems::STONE_PICKAXE()); $result->register("stone_shovel", fn() => VanillaItems::STONE_SHOVEL()); $result->register("stone_sword", fn() => VanillaItems::STONE_SWORD()); + $result->register("strength_potion", fn() => VanillaItems::STRENGTH_POTION()); + $result->register("strength_splash_potion", fn() => VanillaItems::STRENGTH_SPLASH_POTION()); $result->register("string", fn() => VanillaItems::STRING()); + $result->register("strong_harming_potion", fn() => VanillaItems::STRONG_HARMING_POTION()); + $result->register("strong_harming_splash_potion", fn() => VanillaItems::STRONG_HARMING_SPLASH_POTION()); + $result->register("strong_healing_potion", fn() => VanillaItems::STRONG_HEALING_POTION()); + $result->register("strong_healing_splash_potion", fn() => VanillaItems::STRONG_HEALING_SPLASH_POTION()); + $result->register("strong_leaping_potion", fn() => VanillaItems::STRONG_LEAPING_POTION()); + $result->register("strong_leaping_splash_potion", fn() => VanillaItems::STRONG_LEAPING_SPLASH_POTION()); + $result->register("strong_poison_potion", fn() => VanillaItems::STRONG_POISON_POTION()); + $result->register("strong_poison_splash_potion", fn() => VanillaItems::STRONG_POISON_SPLASH_POTION()); + $result->register("strong_regeneration_potion", fn() => VanillaItems::STRONG_REGENERATION_POTION()); + $result->register("strong_regeneration_splash_potion", fn() => VanillaItems::STRONG_REGENERATION_SPLASH_POTION()); + $result->register("strong_strength_potion", fn() => VanillaItems::STRONG_STRENGTH_POTION()); + $result->register("strong_strength_splash_potion", fn() => VanillaItems::STRONG_STRENGTH_SPLASH_POTION()); + $result->register("strong_swiftness_potion", fn() => VanillaItems::STRONG_SWIFTNESS_POTION()); + $result->register("strong_swiftness_splash_potion", fn() => VanillaItems::STRONG_SWIFTNESS_SPLASH_POTION()); + $result->register("strong_turtle_master_potion", fn() => VanillaItems::STRONG_TURTLE_MASTER_POTION()); + $result->register("strong_turtle_master_splash_potion", fn() => VanillaItems::STRONG_TURTLE_MASTER_SPLASH_POTION()); $result->register("sugar", fn() => VanillaItems::SUGAR()); $result->register("sweet_berries", fn() => VanillaItems::SWEET_BERRIES()); + $result->register("swiftness_potion", fn() => VanillaItems::SWIFTNESS_POTION()); + $result->register("swiftness_splash_potion", fn() => VanillaItems::SWIFTNESS_SPLASH_POTION()); + $result->register("thick_potion", fn() => VanillaItems::THICK_POTION()); + $result->register("thick_splash_potion", fn() => VanillaItems::THICK_SPLASH_POTION()); $result->register("totem", fn() => VanillaItems::TOTEM()); + $result->register("turtle_master_potion", fn() => VanillaItems::TURTLE_MASTER_POTION()); + $result->register("turtle_master_splash_potion", fn() => VanillaItems::TURTLE_MASTER_SPLASH_POTION()); $result->register("turtle_shell_piece", fn() => VanillaItems::SCUTE()); + $result->register("villager_spawn_egg", fn() => VanillaItems::VILLAGER_SPAWN_EGG()); + $result->register("water_breathing_potion", fn() => VanillaItems::WATER_BREATHING_POTION()); + $result->register("water_breathing_splash_potion", fn() => VanillaItems::WATER_BREATHING_SPLASH_POTION()); + $result->register("water_bucket", fn() => VanillaItems::WATER_BUCKET()); + $result->register("water_potion", fn() => VanillaItems::WATER_POTION()); + $result->register("water_splash_potion", fn() => VanillaItems::WATER_SPLASH_POTION()); + $result->register("weakness_potion", fn() => VanillaItems::WEAKNESS_POTION()); + $result->register("weakness_splash_potion", fn() => VanillaItems::WEAKNESS_SPLASH_POTION()); $result->register("wheat", fn() => VanillaItems::WHEAT()); $result->register("wheat_seeds", fn() => VanillaItems::WHEAT_SEEDS()); + $result->register("white_dye", fn() => VanillaItems::WHITE_DYE()); + $result->register("wither_potion", fn() => VanillaItems::WITHER_POTION()); + $result->register("wither_skeleton_skull", fn() => VanillaItems::WITHER_SKELETON_SKULL()); + $result->register("wither_splash_potion", fn() => VanillaItems::WITHER_SPLASH_POTION()); $result->register("wooden_axe", fn() => VanillaItems::WOODEN_AXE()); $result->register("wooden_hoe", fn() => VanillaItems::WOODEN_HOE()); $result->register("wooden_pickaxe", fn() => VanillaItems::WOODEN_PICKAXE()); @@ -841,6 +1026,9 @@ final class StringToItemParser{ $result->register("wooden_sword", fn() => VanillaItems::WOODEN_SWORD()); $result->register("writable_book", fn() => VanillaItems::WRITABLE_BOOK()); $result->register("written_book", fn() => VanillaItems::WRITTEN_BOOK()); + $result->register("yellow_dye", fn() => VanillaItems::YELLOW_DYE()); + $result->register("zombie_head", fn() => VanillaItems::ZOMBIE_HEAD()); + $result->register("zombie_spawn_egg", fn() => VanillaItems::ZOMBIE_SPAWN_EGG()); return $result; } From 2d025bf02f7e64877b8cf8563c75dd52dedb4052 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 23 Aug 2021 14:49:30 +0100 Subject: [PATCH 2740/3224] Populate StringToItemParser with some names from VanillaBlocks this makes just about everything easily accessible via commands. There are some stuff that shouldn't be here due to not being actual items (e.g. door blocks, bed blocks, wall coral fans) but since there were legacy aliases for all those things already, I figured what the heck - it's more effort to exclude them, so whatever. --- src/item/StringToItemParser.php | 291 ++++++++++++++++++++++++++++++++ 1 file changed, 291 insertions(+) diff --git a/src/item/StringToItemParser.php b/src/item/StringToItemParser.php index e2b7258dac..700ada9bf8 100644 --- a/src/item/StringToItemParser.php +++ b/src/item/StringToItemParser.php @@ -78,21 +78,34 @@ final class StringToItemParser{ $result->registerBlock("acacia_button", fn() => VanillaBlocks::ACACIA_BUTTON()); $result->registerBlock("acacia_door", fn() => VanillaBlocks::ACACIA_DOOR()); $result->registerBlock("acacia_door_block", fn() => VanillaBlocks::ACACIA_DOOR()); + $result->registerBlock("acacia_fence", fn() => VanillaBlocks::ACACIA_FENCE()); $result->registerBlock("acacia_fence_gate", fn() => VanillaBlocks::ACACIA_FENCE_GATE()); + $result->registerBlock("acacia_leaves", fn() => VanillaBlocks::ACACIA_LEAVES()); + $result->registerBlock("acacia_log", fn() => VanillaBlocks::ACACIA_LOG()); + $result->registerBlock("acacia_planks", fn() => VanillaBlocks::ACACIA_PLANKS()); $result->registerBlock("acacia_pressure_plate", fn() => VanillaBlocks::ACACIA_PRESSURE_PLATE()); + $result->registerBlock("acacia_sapling", fn() => VanillaBlocks::ACACIA_SAPLING()); $result->registerBlock("acacia_sign", fn() => VanillaBlocks::ACACIA_SIGN()); + $result->registerBlock("acacia_slab", fn() => VanillaBlocks::ACACIA_SLAB()); $result->registerBlock("acacia_stairs", fn() => VanillaBlocks::ACACIA_STAIRS()); $result->registerBlock("acacia_standing_sign", fn() => VanillaBlocks::ACACIA_SIGN()); $result->registerBlock("acacia_trapdoor", fn() => VanillaBlocks::ACACIA_TRAPDOOR()); $result->registerBlock("acacia_wall_sign", fn() => VanillaBlocks::ACACIA_WALL_SIGN()); + $result->registerBlock("acacia_wood", fn() => VanillaBlocks::ACACIA_WOOD()); $result->registerBlock("acacia_wood_stairs", fn() => VanillaBlocks::ACACIA_STAIRS()); $result->registerBlock("acacia_wooden_stairs", fn() => VanillaBlocks::ACACIA_STAIRS()); $result->registerBlock("activator_rail", fn() => VanillaBlocks::ACTIVATOR_RAIL()); $result->registerBlock("active_redstone_lamp", fn() => VanillaBlocks::REDSTONE_LAMP()->setPowered(true)); $result->registerBlock("air", fn() => VanillaBlocks::AIR()); + $result->registerBlock("all_sided_mushroom_stem", fn() => VanillaBlocks::ALL_SIDED_MUSHROOM_STEM()); + $result->registerBlock("allium", fn() => VanillaBlocks::ALLIUM()); + $result->registerBlock("andesite", fn() => VanillaBlocks::ANDESITE()); + $result->registerBlock("andesite_slab", fn() => VanillaBlocks::ANDESITE_SLAB()); $result->registerBlock("andesite_stairs", fn() => VanillaBlocks::ANDESITE_STAIRS()); + $result->registerBlock("andesite_wall", fn() => VanillaBlocks::ANDESITE_WALL()); $result->registerBlock("anvil", fn() => VanillaBlocks::ANVIL()); $result->registerBlock("ateupd_block", fn() => VanillaBlocks::INFO_UPDATE2()); + $result->registerBlock("azure_bluet", fn() => VanillaBlocks::AZURE_BLUET()); $result->registerBlock("bamboo", fn() => VanillaBlocks::BAMBOO_SAPLING()); $result->registerBlock("bamboo_sapling", fn() => VanillaBlocks::BAMBOO_SAPLING()); $result->registerBlock("banner", fn() => VanillaBlocks::BANNER()); @@ -102,29 +115,41 @@ final class StringToItemParser{ $result->registerBlock("bed_block", fn() => VanillaBlocks::BED()); $result->registerBlock("bedrock", fn() => VanillaBlocks::BEDROCK()); $result->registerBlock("beetroot_block", fn() => VanillaBlocks::BEETROOTS()); + $result->registerBlock("beetroots", fn() => VanillaBlocks::BEETROOTS()); $result->registerBlock("bell", fn() => VanillaBlocks::BELL()); $result->registerBlock("birch_button", fn() => VanillaBlocks::BIRCH_BUTTON()); $result->registerBlock("birch_door", fn() => VanillaBlocks::BIRCH_DOOR()); $result->registerBlock("birch_door_block", fn() => VanillaBlocks::BIRCH_DOOR()); + $result->registerBlock("birch_fence", fn() => VanillaBlocks::BIRCH_FENCE()); $result->registerBlock("birch_fence_gate", fn() => VanillaBlocks::BIRCH_FENCE_GATE()); + $result->registerBlock("birch_leaves", fn() => VanillaBlocks::BIRCH_LEAVES()); + $result->registerBlock("birch_log", fn() => VanillaBlocks::BIRCH_LOG()); + $result->registerBlock("birch_planks", fn() => VanillaBlocks::BIRCH_PLANKS()); $result->registerBlock("birch_pressure_plate", fn() => VanillaBlocks::BIRCH_PRESSURE_PLATE()); + $result->registerBlock("birch_sapling", fn() => VanillaBlocks::BIRCH_SAPLING()); $result->registerBlock("birch_sign", fn() => VanillaBlocks::BIRCH_SIGN()); + $result->registerBlock("birch_slab", fn() => VanillaBlocks::BIRCH_SLAB()); $result->registerBlock("birch_stairs", fn() => VanillaBlocks::BIRCH_STAIRS()); $result->registerBlock("birch_standing_sign", fn() => VanillaBlocks::BIRCH_SIGN()); $result->registerBlock("birch_trapdoor", fn() => VanillaBlocks::BIRCH_TRAPDOOR()); $result->registerBlock("birch_wall_sign", fn() => VanillaBlocks::BIRCH_WALL_SIGN()); + $result->registerBlock("birch_wood", fn() => VanillaBlocks::BIRCH_WOOD()); $result->registerBlock("birch_wood_stairs", fn() => VanillaBlocks::BIRCH_STAIRS()); $result->registerBlock("birch_wooden_stairs", fn() => VanillaBlocks::BIRCH_STAIRS()); $result->registerBlock("black_glazed_terracotta", fn() => VanillaBlocks::BLACK_GLAZED_TERRACOTTA()); $result->registerBlock("blast_furnace", fn() => VanillaBlocks::BLAST_FURNACE()); $result->registerBlock("blue_glazed_terracotta", fn() => VanillaBlocks::BLUE_GLAZED_TERRACOTTA()); $result->registerBlock("blue_ice", fn() => VanillaBlocks::BLUE_ICE()); + $result->registerBlock("blue_orchid", fn() => VanillaBlocks::BLUE_ORCHID()); + $result->registerBlock("blue_torch", fn() => VanillaBlocks::BLUE_TORCH()); $result->registerBlock("bone_block", fn() => VanillaBlocks::BONE_BLOCK()); $result->registerBlock("bookshelf", fn() => VanillaBlocks::BOOKSHELF()); $result->registerBlock("brewing_stand", fn() => VanillaBlocks::BREWING_STAND()); $result->registerBlock("brewing_stand_block", fn() => VanillaBlocks::BREWING_STAND()); $result->registerBlock("brick_block", fn() => VanillaBlocks::BRICKS()); + $result->registerBlock("brick_slab", fn() => VanillaBlocks::BRICK_SLAB()); $result->registerBlock("brick_stairs", fn() => VanillaBlocks::BRICK_STAIRS()); + $result->registerBlock("brick_wall", fn() => VanillaBlocks::BRICK_WALL()); $result->registerBlock("bricks", fn() => VanillaBlocks::BRICKS()); $result->registerBlock("bricks_block", fn() => VanillaBlocks::BRICKS()); $result->registerBlock("brown_glazed_terracotta", fn() => VanillaBlocks::BROWN_GLAZED_TERRACOTTA()); @@ -142,6 +167,10 @@ final class StringToItemParser{ $result->registerBlock("chemical_heat", fn() => VanillaBlocks::CHEMICAL_HEAT()); $result->registerBlock("chemistry_table", fn() => VanillaBlocks::COMPOUND_CREATOR()); $result->registerBlock("chest", fn() => VanillaBlocks::CHEST()); + $result->registerBlock("chiseled_quartz", fn() => VanillaBlocks::CHISELED_QUARTZ()); + $result->registerBlock("chiseled_red_sandstone", fn() => VanillaBlocks::CHISELED_RED_SANDSTONE()); + $result->registerBlock("chiseled_sandstone", fn() => VanillaBlocks::CHISELED_SANDSTONE()); + $result->registerBlock("chiseled_stone_bricks", fn() => VanillaBlocks::CHISELED_STONE_BRICKS()); $result->registerBlock("clay_block", fn() => VanillaBlocks::CLAY()); $result->registerBlock("coal_block", fn() => VanillaBlocks::COAL()); $result->registerBlock("coal_ore", fn() => VanillaBlocks::COAL_ORE()); @@ -149,16 +178,19 @@ final class StringToItemParser{ $result->registerBlock("cobble_stairs", fn() => VanillaBlocks::COBBLESTONE_STAIRS()); $result->registerBlock("cobble_wall", fn() => VanillaBlocks::COBBLESTONE_WALL()); $result->registerBlock("cobblestone", fn() => VanillaBlocks::COBBLESTONE()); + $result->registerBlock("cobblestone_slab", fn() => VanillaBlocks::COBBLESTONE_SLAB()); $result->registerBlock("cobblestone_stairs", fn() => VanillaBlocks::COBBLESTONE_STAIRS()); $result->registerBlock("cobblestone_wall", fn() => VanillaBlocks::COBBLESTONE_WALL()); $result->registerBlock("cobweb", fn() => VanillaBlocks::COBWEB()); $result->registerBlock("cocoa", fn() => VanillaBlocks::COCOA_POD()); $result->registerBlock("cocoa_block", fn() => VanillaBlocks::COCOA_POD()); + $result->registerBlock("cocoa_pod", fn() => VanillaBlocks::COCOA_POD()); $result->registerBlock("cocoa_pods", fn() => VanillaBlocks::COCOA_POD()); $result->registerBlock("colored_torch_bp", fn() => VanillaBlocks::BLUE_TORCH()); $result->registerBlock("colored_torch_rg", fn() => VanillaBlocks::RED_TORCH()); $result->registerBlock("comparator", fn() => VanillaBlocks::REDSTONE_COMPARATOR()); $result->registerBlock("comparator_block", fn() => VanillaBlocks::REDSTONE_COMPARATOR()); + $result->registerBlock("compound_creator", fn() => VanillaBlocks::COMPOUND_CREATOR()); $result->registerBlock("concrete", fn() => VanillaBlocks::CONCRETE()); $result->registerBlock("concrete_powder", fn() => VanillaBlocks::CONCRETE_POWDER()); $result->registerBlock("concretepowder", fn() => VanillaBlocks::CONCRETE_POWDER()); @@ -169,18 +201,35 @@ final class StringToItemParser{ $result->registerBlock("coral_fan_hang", fn() => VanillaBlocks::WALL_CORAL_FAN()); $result->registerBlock("coral_fan_hang2", fn() => VanillaBlocks::WALL_CORAL_FAN()->setCoralType(CoralType::BUBBLE())); $result->registerBlock("coral_fan_hang3", fn() => VanillaBlocks::WALL_CORAL_FAN()->setCoralType(CoralType::HORN())); + $result->registerBlock("cornflower", fn() => VanillaBlocks::CORNFLOWER()); + $result->registerBlock("cracked_stone_bricks", fn() => VanillaBlocks::CRACKED_STONE_BRICKS()); $result->registerBlock("crafting_table", fn() => VanillaBlocks::CRAFTING_TABLE()); + $result->registerBlock("cut_red_sandstone", fn() => VanillaBlocks::CUT_RED_SANDSTONE()); + $result->registerBlock("cut_red_sandstone_slab", fn() => VanillaBlocks::CUT_RED_SANDSTONE_SLAB()); + $result->registerBlock("cut_sandstone", fn() => VanillaBlocks::CUT_SANDSTONE()); + $result->registerBlock("cut_sandstone_slab", fn() => VanillaBlocks::CUT_SANDSTONE_SLAB()); $result->registerBlock("cyan_glazed_terracotta", fn() => VanillaBlocks::CYAN_GLAZED_TERRACOTTA()); $result->registerBlock("dandelion", fn() => VanillaBlocks::DANDELION()); $result->registerBlock("dark_oak_button", fn() => VanillaBlocks::DARK_OAK_BUTTON()); $result->registerBlock("dark_oak_door", fn() => VanillaBlocks::DARK_OAK_DOOR()); $result->registerBlock("dark_oak_door_block", fn() => VanillaBlocks::DARK_OAK_DOOR()); + $result->registerBlock("dark_oak_fence", fn() => VanillaBlocks::DARK_OAK_FENCE()); $result->registerBlock("dark_oak_fence_gate", fn() => VanillaBlocks::DARK_OAK_FENCE_GATE()); + $result->registerBlock("dark_oak_leaves", fn() => VanillaBlocks::DARK_OAK_LEAVES()); + $result->registerBlock("dark_oak_log", fn() => VanillaBlocks::DARK_OAK_LOG()); + $result->registerBlock("dark_oak_planks", fn() => VanillaBlocks::DARK_OAK_PLANKS()); $result->registerBlock("dark_oak_pressure_plate", fn() => VanillaBlocks::DARK_OAK_PRESSURE_PLATE()); + $result->registerBlock("dark_oak_sapling", fn() => VanillaBlocks::DARK_OAK_SAPLING()); + $result->registerBlock("dark_oak_sign", fn() => VanillaBlocks::DARK_OAK_SIGN()); + $result->registerBlock("dark_oak_slab", fn() => VanillaBlocks::DARK_OAK_SLAB()); $result->registerBlock("dark_oak_stairs", fn() => VanillaBlocks::DARK_OAK_STAIRS()); $result->registerBlock("dark_oak_trapdoor", fn() => VanillaBlocks::DARK_OAK_TRAPDOOR()); + $result->registerBlock("dark_oak_wall_sign", fn() => VanillaBlocks::DARK_OAK_WALL_SIGN()); + $result->registerBlock("dark_oak_wood", fn() => VanillaBlocks::DARK_OAK_WOOD()); $result->registerBlock("dark_oak_wood_stairs", fn() => VanillaBlocks::DARK_OAK_STAIRS()); $result->registerBlock("dark_oak_wooden_stairs", fn() => VanillaBlocks::DARK_OAK_STAIRS()); + $result->registerBlock("dark_prismarine", fn() => VanillaBlocks::DARK_PRISMARINE()); + $result->registerBlock("dark_prismarine_slab", fn() => VanillaBlocks::DARK_PRISMARINE_SLAB()); $result->registerBlock("dark_prismarine_stairs", fn() => VanillaBlocks::DARK_PRISMARINE_STAIRS()); $result->registerBlock("darkoak_sign", fn() => VanillaBlocks::DARK_OAK_SIGN()); $result->registerBlock("darkoak_standing_sign", fn() => VanillaBlocks::DARK_OAK_SIGN()); @@ -194,7 +243,10 @@ final class StringToItemParser{ $result->registerBlock("detector_rail", fn() => VanillaBlocks::DETECTOR_RAIL()); $result->registerBlock("diamond_block", fn() => VanillaBlocks::DIAMOND()); $result->registerBlock("diamond_ore", fn() => VanillaBlocks::DIAMOND_ORE()); + $result->registerBlock("diorite", fn() => VanillaBlocks::DIORITE()); + $result->registerBlock("diorite_slab", fn() => VanillaBlocks::DIORITE_SLAB()); $result->registerBlock("diorite_stairs", fn() => VanillaBlocks::DIORITE_STAIRS()); + $result->registerBlock("diorite_wall", fn() => VanillaBlocks::DIORITE_WALL()); $result->registerBlock("dirt", fn() => VanillaBlocks::DIRT()); $result->registerBlock("door_block", fn() => VanillaBlocks::OAK_DOOR()); $result->registerBlock("double_plant", fn() => VanillaBlocks::SUNFLOWER()); @@ -205,12 +257,14 @@ final class StringToItemParser{ $result->registerBlock("double_stone_slab2", fn() => VanillaBlocks::RED_SANDSTONE_SLAB()->setSlabType(SlabType::DOUBLE())); $result->registerBlock("double_stone_slab3", fn() => VanillaBlocks::END_STONE_BRICK_SLAB()->setSlabType(SlabType::DOUBLE())); $result->registerBlock("double_stone_slab4", fn() => VanillaBlocks::MOSSY_STONE_BRICK_SLAB()->setSlabType(SlabType::DOUBLE())); + $result->registerBlock("double_tallgrass", fn() => VanillaBlocks::DOUBLE_TALLGRASS()); $result->registerBlock("double_wood_slab", fn() => VanillaBlocks::OAK_SLAB()->setSlabType(SlabType::DOUBLE())); $result->registerBlock("double_wood_slabs", fn() => VanillaBlocks::OAK_SLAB()->setSlabType(SlabType::DOUBLE())); $result->registerBlock("double_wooden_slab", fn() => VanillaBlocks::OAK_SLAB()->setSlabType(SlabType::DOUBLE())); $result->registerBlock("double_wooden_slabs", fn() => VanillaBlocks::OAK_SLAB()->setSlabType(SlabType::DOUBLE())); $result->registerBlock("dragon_egg", fn() => VanillaBlocks::DRAGON_EGG()); $result->registerBlock("dried_kelp_block", fn() => VanillaBlocks::DRIED_KELP()); + $result->registerBlock("dyed_shulker_box", fn() => VanillaBlocks::DYED_SHULKER_BOX()); $result->registerBlock("element_0", fn() => VanillaBlocks::ELEMENT_ZERO()); $result->registerBlock("element_1", fn() => VanillaBlocks::ELEMENT_HYDROGEN()); $result->registerBlock("element_10", fn() => VanillaBlocks::ELEMENT_NEON()); @@ -330,6 +384,126 @@ final class StringToItemParser{ $result->registerBlock("element_97", fn() => VanillaBlocks::ELEMENT_BERKELIUM()); $result->registerBlock("element_98", fn() => VanillaBlocks::ELEMENT_CALIFORNIUM()); $result->registerBlock("element_99", fn() => VanillaBlocks::ELEMENT_EINSTEINIUM()); + $result->registerBlock("element_actinium", fn() => VanillaBlocks::ELEMENT_ACTINIUM()); + $result->registerBlock("element_aluminum", fn() => VanillaBlocks::ELEMENT_ALUMINUM()); + $result->registerBlock("element_americium", fn() => VanillaBlocks::ELEMENT_AMERICIUM()); + $result->registerBlock("element_antimony", fn() => VanillaBlocks::ELEMENT_ANTIMONY()); + $result->registerBlock("element_argon", fn() => VanillaBlocks::ELEMENT_ARGON()); + $result->registerBlock("element_arsenic", fn() => VanillaBlocks::ELEMENT_ARSENIC()); + $result->registerBlock("element_astatine", fn() => VanillaBlocks::ELEMENT_ASTATINE()); + $result->registerBlock("element_barium", fn() => VanillaBlocks::ELEMENT_BARIUM()); + $result->registerBlock("element_berkelium", fn() => VanillaBlocks::ELEMENT_BERKELIUM()); + $result->registerBlock("element_beryllium", fn() => VanillaBlocks::ELEMENT_BERYLLIUM()); + $result->registerBlock("element_bismuth", fn() => VanillaBlocks::ELEMENT_BISMUTH()); + $result->registerBlock("element_bohrium", fn() => VanillaBlocks::ELEMENT_BOHRIUM()); + $result->registerBlock("element_boron", fn() => VanillaBlocks::ELEMENT_BORON()); + $result->registerBlock("element_bromine", fn() => VanillaBlocks::ELEMENT_BROMINE()); + $result->registerBlock("element_cadmium", fn() => VanillaBlocks::ELEMENT_CADMIUM()); + $result->registerBlock("element_calcium", fn() => VanillaBlocks::ELEMENT_CALCIUM()); + $result->registerBlock("element_californium", fn() => VanillaBlocks::ELEMENT_CALIFORNIUM()); + $result->registerBlock("element_carbon", fn() => VanillaBlocks::ELEMENT_CARBON()); + $result->registerBlock("element_cerium", fn() => VanillaBlocks::ELEMENT_CERIUM()); + $result->registerBlock("element_cesium", fn() => VanillaBlocks::ELEMENT_CESIUM()); + $result->registerBlock("element_chlorine", fn() => VanillaBlocks::ELEMENT_CHLORINE()); + $result->registerBlock("element_chromium", fn() => VanillaBlocks::ELEMENT_CHROMIUM()); + $result->registerBlock("element_cobalt", fn() => VanillaBlocks::ELEMENT_COBALT()); + $result->registerBlock("element_constructor", fn() => VanillaBlocks::ELEMENT_CONSTRUCTOR()); + $result->registerBlock("element_copernicium", fn() => VanillaBlocks::ELEMENT_COPERNICIUM()); + $result->registerBlock("element_copper", fn() => VanillaBlocks::ELEMENT_COPPER()); + $result->registerBlock("element_curium", fn() => VanillaBlocks::ELEMENT_CURIUM()); + $result->registerBlock("element_darmstadtium", fn() => VanillaBlocks::ELEMENT_DARMSTADTIUM()); + $result->registerBlock("element_dubnium", fn() => VanillaBlocks::ELEMENT_DUBNIUM()); + $result->registerBlock("element_dysprosium", fn() => VanillaBlocks::ELEMENT_DYSPROSIUM()); + $result->registerBlock("element_einsteinium", fn() => VanillaBlocks::ELEMENT_EINSTEINIUM()); + $result->registerBlock("element_erbium", fn() => VanillaBlocks::ELEMENT_ERBIUM()); + $result->registerBlock("element_europium", fn() => VanillaBlocks::ELEMENT_EUROPIUM()); + $result->registerBlock("element_fermium", fn() => VanillaBlocks::ELEMENT_FERMIUM()); + $result->registerBlock("element_flerovium", fn() => VanillaBlocks::ELEMENT_FLEROVIUM()); + $result->registerBlock("element_fluorine", fn() => VanillaBlocks::ELEMENT_FLUORINE()); + $result->registerBlock("element_francium", fn() => VanillaBlocks::ELEMENT_FRANCIUM()); + $result->registerBlock("element_gadolinium", fn() => VanillaBlocks::ELEMENT_GADOLINIUM()); + $result->registerBlock("element_gallium", fn() => VanillaBlocks::ELEMENT_GALLIUM()); + $result->registerBlock("element_germanium", fn() => VanillaBlocks::ELEMENT_GERMANIUM()); + $result->registerBlock("element_gold", fn() => VanillaBlocks::ELEMENT_GOLD()); + $result->registerBlock("element_hafnium", fn() => VanillaBlocks::ELEMENT_HAFNIUM()); + $result->registerBlock("element_hassium", fn() => VanillaBlocks::ELEMENT_HASSIUM()); + $result->registerBlock("element_helium", fn() => VanillaBlocks::ELEMENT_HELIUM()); + $result->registerBlock("element_holmium", fn() => VanillaBlocks::ELEMENT_HOLMIUM()); + $result->registerBlock("element_hydrogen", fn() => VanillaBlocks::ELEMENT_HYDROGEN()); + $result->registerBlock("element_indium", fn() => VanillaBlocks::ELEMENT_INDIUM()); + $result->registerBlock("element_iodine", fn() => VanillaBlocks::ELEMENT_IODINE()); + $result->registerBlock("element_iridium", fn() => VanillaBlocks::ELEMENT_IRIDIUM()); + $result->registerBlock("element_iron", fn() => VanillaBlocks::ELEMENT_IRON()); + $result->registerBlock("element_krypton", fn() => VanillaBlocks::ELEMENT_KRYPTON()); + $result->registerBlock("element_lanthanum", fn() => VanillaBlocks::ELEMENT_LANTHANUM()); + $result->registerBlock("element_lawrencium", fn() => VanillaBlocks::ELEMENT_LAWRENCIUM()); + $result->registerBlock("element_lead", fn() => VanillaBlocks::ELEMENT_LEAD()); + $result->registerBlock("element_lithium", fn() => VanillaBlocks::ELEMENT_LITHIUM()); + $result->registerBlock("element_livermorium", fn() => VanillaBlocks::ELEMENT_LIVERMORIUM()); + $result->registerBlock("element_lutetium", fn() => VanillaBlocks::ELEMENT_LUTETIUM()); + $result->registerBlock("element_magnesium", fn() => VanillaBlocks::ELEMENT_MAGNESIUM()); + $result->registerBlock("element_manganese", fn() => VanillaBlocks::ELEMENT_MANGANESE()); + $result->registerBlock("element_meitnerium", fn() => VanillaBlocks::ELEMENT_MEITNERIUM()); + $result->registerBlock("element_mendelevium", fn() => VanillaBlocks::ELEMENT_MENDELEVIUM()); + $result->registerBlock("element_mercury", fn() => VanillaBlocks::ELEMENT_MERCURY()); + $result->registerBlock("element_molybdenum", fn() => VanillaBlocks::ELEMENT_MOLYBDENUM()); + $result->registerBlock("element_moscovium", fn() => VanillaBlocks::ELEMENT_MOSCOVIUM()); + $result->registerBlock("element_neodymium", fn() => VanillaBlocks::ELEMENT_NEODYMIUM()); + $result->registerBlock("element_neon", fn() => VanillaBlocks::ELEMENT_NEON()); + $result->registerBlock("element_neptunium", fn() => VanillaBlocks::ELEMENT_NEPTUNIUM()); + $result->registerBlock("element_nickel", fn() => VanillaBlocks::ELEMENT_NICKEL()); + $result->registerBlock("element_nihonium", fn() => VanillaBlocks::ELEMENT_NIHONIUM()); + $result->registerBlock("element_niobium", fn() => VanillaBlocks::ELEMENT_NIOBIUM()); + $result->registerBlock("element_nitrogen", fn() => VanillaBlocks::ELEMENT_NITROGEN()); + $result->registerBlock("element_nobelium", fn() => VanillaBlocks::ELEMENT_NOBELIUM()); + $result->registerBlock("element_oganesson", fn() => VanillaBlocks::ELEMENT_OGANESSON()); + $result->registerBlock("element_osmium", fn() => VanillaBlocks::ELEMENT_OSMIUM()); + $result->registerBlock("element_oxygen", fn() => VanillaBlocks::ELEMENT_OXYGEN()); + $result->registerBlock("element_palladium", fn() => VanillaBlocks::ELEMENT_PALLADIUM()); + $result->registerBlock("element_phosphorus", fn() => VanillaBlocks::ELEMENT_PHOSPHORUS()); + $result->registerBlock("element_platinum", fn() => VanillaBlocks::ELEMENT_PLATINUM()); + $result->registerBlock("element_plutonium", fn() => VanillaBlocks::ELEMENT_PLUTONIUM()); + $result->registerBlock("element_polonium", fn() => VanillaBlocks::ELEMENT_POLONIUM()); + $result->registerBlock("element_potassium", fn() => VanillaBlocks::ELEMENT_POTASSIUM()); + $result->registerBlock("element_praseodymium", fn() => VanillaBlocks::ELEMENT_PRASEODYMIUM()); + $result->registerBlock("element_promethium", fn() => VanillaBlocks::ELEMENT_PROMETHIUM()); + $result->registerBlock("element_protactinium", fn() => VanillaBlocks::ELEMENT_PROTACTINIUM()); + $result->registerBlock("element_radium", fn() => VanillaBlocks::ELEMENT_RADIUM()); + $result->registerBlock("element_radon", fn() => VanillaBlocks::ELEMENT_RADON()); + $result->registerBlock("element_rhenium", fn() => VanillaBlocks::ELEMENT_RHENIUM()); + $result->registerBlock("element_rhodium", fn() => VanillaBlocks::ELEMENT_RHODIUM()); + $result->registerBlock("element_roentgenium", fn() => VanillaBlocks::ELEMENT_ROENTGENIUM()); + $result->registerBlock("element_rubidium", fn() => VanillaBlocks::ELEMENT_RUBIDIUM()); + $result->registerBlock("element_ruthenium", fn() => VanillaBlocks::ELEMENT_RUTHENIUM()); + $result->registerBlock("element_rutherfordium", fn() => VanillaBlocks::ELEMENT_RUTHERFORDIUM()); + $result->registerBlock("element_samarium", fn() => VanillaBlocks::ELEMENT_SAMARIUM()); + $result->registerBlock("element_scandium", fn() => VanillaBlocks::ELEMENT_SCANDIUM()); + $result->registerBlock("element_seaborgium", fn() => VanillaBlocks::ELEMENT_SEABORGIUM()); + $result->registerBlock("element_selenium", fn() => VanillaBlocks::ELEMENT_SELENIUM()); + $result->registerBlock("element_silicon", fn() => VanillaBlocks::ELEMENT_SILICON()); + $result->registerBlock("element_silver", fn() => VanillaBlocks::ELEMENT_SILVER()); + $result->registerBlock("element_sodium", fn() => VanillaBlocks::ELEMENT_SODIUM()); + $result->registerBlock("element_strontium", fn() => VanillaBlocks::ELEMENT_STRONTIUM()); + $result->registerBlock("element_sulfur", fn() => VanillaBlocks::ELEMENT_SULFUR()); + $result->registerBlock("element_tantalum", fn() => VanillaBlocks::ELEMENT_TANTALUM()); + $result->registerBlock("element_technetium", fn() => VanillaBlocks::ELEMENT_TECHNETIUM()); + $result->registerBlock("element_tellurium", fn() => VanillaBlocks::ELEMENT_TELLURIUM()); + $result->registerBlock("element_tennessine", fn() => VanillaBlocks::ELEMENT_TENNESSINE()); + $result->registerBlock("element_terbium", fn() => VanillaBlocks::ELEMENT_TERBIUM()); + $result->registerBlock("element_thallium", fn() => VanillaBlocks::ELEMENT_THALLIUM()); + $result->registerBlock("element_thorium", fn() => VanillaBlocks::ELEMENT_THORIUM()); + $result->registerBlock("element_thulium", fn() => VanillaBlocks::ELEMENT_THULIUM()); + $result->registerBlock("element_tin", fn() => VanillaBlocks::ELEMENT_TIN()); + $result->registerBlock("element_titanium", fn() => VanillaBlocks::ELEMENT_TITANIUM()); + $result->registerBlock("element_tungsten", fn() => VanillaBlocks::ELEMENT_TUNGSTEN()); + $result->registerBlock("element_uranium", fn() => VanillaBlocks::ELEMENT_URANIUM()); + $result->registerBlock("element_vanadium", fn() => VanillaBlocks::ELEMENT_VANADIUM()); + $result->registerBlock("element_xenon", fn() => VanillaBlocks::ELEMENT_XENON()); + $result->registerBlock("element_ytterbium", fn() => VanillaBlocks::ELEMENT_YTTERBIUM()); + $result->registerBlock("element_yttrium", fn() => VanillaBlocks::ELEMENT_YTTRIUM()); + $result->registerBlock("element_zero", fn() => VanillaBlocks::ELEMENT_ZERO()); + $result->registerBlock("element_zinc", fn() => VanillaBlocks::ELEMENT_ZINC()); + $result->registerBlock("element_zirconium", fn() => VanillaBlocks::ELEMENT_ZIRCONIUM()); $result->registerBlock("emerald_block", fn() => VanillaBlocks::EMERALD()); $result->registerBlock("emerald_ore", fn() => VanillaBlocks::EMERALD_ORE()); $result->registerBlock("enchant_table", fn() => VanillaBlocks::ENCHANTING_TABLE()); @@ -340,7 +514,12 @@ final class StringToItemParser{ $result->registerBlock("end_portal_frame", fn() => VanillaBlocks::END_PORTAL_FRAME()); $result->registerBlock("end_rod", fn() => VanillaBlocks::END_ROD()); $result->registerBlock("end_stone", fn() => VanillaBlocks::END_STONE()); + $result->registerBlock("end_stone_brick_slab", fn() => VanillaBlocks::END_STONE_BRICK_SLAB()); + $result->registerBlock("end_stone_brick_stairs", fn() => VanillaBlocks::END_STONE_BRICK_STAIRS()); + $result->registerBlock("end_stone_brick_wall", fn() => VanillaBlocks::END_STONE_BRICK_WALL()); + $result->registerBlock("end_stone_bricks", fn() => VanillaBlocks::END_STONE_BRICKS()); $result->registerBlock("ender_chest", fn() => VanillaBlocks::ENDER_CHEST()); + $result->registerBlock("fake_wooden_slab", fn() => VanillaBlocks::FAKE_WOODEN_SLAB()); $result->registerBlock("farmland", fn() => VanillaBlocks::FARMLAND()); $result->registerBlock("fence", fn() => VanillaBlocks::OAK_FENCE()); $result->registerBlock("fence_gate", fn() => VanillaBlocks::OAK_FENCE_GATE()); @@ -349,6 +528,7 @@ final class StringToItemParser{ $result->registerBlock("fence_gate_dark_oak", fn() => VanillaBlocks::DARK_OAK_FENCE_GATE()); $result->registerBlock("fence_gate_jungle", fn() => VanillaBlocks::JUNGLE_FENCE_GATE()); $result->registerBlock("fence_gate_spruce", fn() => VanillaBlocks::SPRUCE_FENCE_GATE()); + $result->registerBlock("fern", fn() => VanillaBlocks::FERN()); $result->registerBlock("fire", fn() => VanillaBlocks::FIRE()); $result->registerBlock("flower_pot", fn() => VanillaBlocks::FLOWER_POT()); $result->registerBlock("flower_pot_block", fn() => VanillaBlocks::FLOWER_POT()); @@ -366,21 +546,28 @@ final class StringToItemParser{ $result->registerBlock("glowingobsidian", fn() => VanillaBlocks::GLOWING_OBSIDIAN()); $result->registerBlock("glowstone", fn() => VanillaBlocks::GLOWSTONE()); $result->registerBlock("glowstone_block", fn() => VanillaBlocks::GLOWSTONE()); + $result->registerBlock("gold", fn() => VanillaBlocks::GOLD()); $result->registerBlock("gold_block", fn() => VanillaBlocks::GOLD()); $result->registerBlock("gold_ore", fn() => VanillaBlocks::GOLD_ORE()); $result->registerBlock("gold_pressure_plate", fn() => VanillaBlocks::WEIGHTED_PRESSURE_PLATE_LIGHT()); $result->registerBlock("golden_rail", fn() => VanillaBlocks::POWERED_RAIL()); + $result->registerBlock("granite", fn() => VanillaBlocks::GRANITE()); + $result->registerBlock("granite_slab", fn() => VanillaBlocks::GRANITE_SLAB()); $result->registerBlock("granite_stairs", fn() => VanillaBlocks::GRANITE_STAIRS()); + $result->registerBlock("granite_wall", fn() => VanillaBlocks::GRANITE_WALL()); $result->registerBlock("grass", fn() => VanillaBlocks::GRASS()); $result->registerBlock("grass_path", fn() => VanillaBlocks::GRASS_PATH()); $result->registerBlock("gravel", fn() => VanillaBlocks::GRAVEL()); $result->registerBlock("gray_glazed_terracotta", fn() => VanillaBlocks::GRAY_GLAZED_TERRACOTTA()); $result->registerBlock("green_glazed_terracotta", fn() => VanillaBlocks::GREEN_GLAZED_TERRACOTTA()); + $result->registerBlock("green_torch", fn() => VanillaBlocks::GREEN_TORCH()); $result->registerBlock("hard_glass", fn() => VanillaBlocks::HARDENED_GLASS()); $result->registerBlock("hard_glass_pane", fn() => VanillaBlocks::HARDENED_GLASS_PANE()); $result->registerBlock("hard_stained_glass", fn() => VanillaBlocks::STAINED_HARDENED_GLASS()); $result->registerBlock("hard_stained_glass_pane", fn() => VanillaBlocks::STAINED_HARDENED_GLASS_PANE()); $result->registerBlock("hardened_clay", fn() => VanillaBlocks::HARDENED_CLAY()); + $result->registerBlock("hardened_glass", fn() => VanillaBlocks::HARDENED_GLASS()); + $result->registerBlock("hardened_glass_pane", fn() => VanillaBlocks::HARDENED_GLASS_PANE()); $result->registerBlock("hay_bale", fn() => VanillaBlocks::HAY_BALE()); $result->registerBlock("hay_block", fn() => VanillaBlocks::HAY_BALE()); $result->registerBlock("heavy_weighted_pressure_plate", fn() => VanillaBlocks::WEIGHTED_PRESSURE_PLATE_HEAVY()); @@ -388,12 +575,19 @@ final class StringToItemParser{ $result->registerBlock("hopper_block", fn() => VanillaBlocks::HOPPER()); $result->registerBlock("ice", fn() => VanillaBlocks::ICE()); $result->registerBlock("inactive_redstone_lamp", fn() => VanillaBlocks::REDSTONE_LAMP()); + $result->registerBlock("infested_chiseled_stone_brick", fn() => VanillaBlocks::INFESTED_CHISELED_STONE_BRICK()); + $result->registerBlock("infested_cobblestone", fn() => VanillaBlocks::INFESTED_COBBLESTONE()); + $result->registerBlock("infested_cracked_stone_brick", fn() => VanillaBlocks::INFESTED_CRACKED_STONE_BRICK()); + $result->registerBlock("infested_mossy_stone_brick", fn() => VanillaBlocks::INFESTED_MOSSY_STONE_BRICK()); + $result->registerBlock("infested_stone", fn() => VanillaBlocks::INFESTED_STONE()); + $result->registerBlock("infested_stone_brick", fn() => VanillaBlocks::INFESTED_STONE_BRICK()); $result->registerBlock("info_reserved6", fn() => VanillaBlocks::RESERVED6()); $result->registerBlock("info_update", fn() => VanillaBlocks::INFO_UPDATE()); $result->registerBlock("info_update2", fn() => VanillaBlocks::INFO_UPDATE2()); $result->registerBlock("inverted_daylight_sensor", fn() => VanillaBlocks::DAYLIGHT_SENSOR()->setInverted(true)); $result->registerBlock("invisible_bedrock", fn() => VanillaBlocks::INVISIBLE_BEDROCK()); $result->registerBlock("invisiblebedrock", fn() => VanillaBlocks::INVISIBLE_BEDROCK()); + $result->registerBlock("iron", fn() => VanillaBlocks::IRON()); $result->registerBlock("iron_bar", fn() => VanillaBlocks::IRON_BARS()); $result->registerBlock("iron_bars", fn() => VanillaBlocks::IRON_BARS()); $result->registerBlock("iron_block", fn() => VanillaBlocks::IRON()); @@ -409,25 +603,40 @@ final class StringToItemParser{ $result->registerBlock("jungle_button", fn() => VanillaBlocks::JUNGLE_BUTTON()); $result->registerBlock("jungle_door", fn() => VanillaBlocks::JUNGLE_DOOR()); $result->registerBlock("jungle_door_block", fn() => VanillaBlocks::JUNGLE_DOOR()); + $result->registerBlock("jungle_fence", fn() => VanillaBlocks::JUNGLE_FENCE()); $result->registerBlock("jungle_fence_gate", fn() => VanillaBlocks::JUNGLE_FENCE_GATE()); + $result->registerBlock("jungle_leaves", fn() => VanillaBlocks::JUNGLE_LEAVES()); + $result->registerBlock("jungle_log", fn() => VanillaBlocks::JUNGLE_LOG()); + $result->registerBlock("jungle_planks", fn() => VanillaBlocks::JUNGLE_PLANKS()); $result->registerBlock("jungle_pressure_plate", fn() => VanillaBlocks::JUNGLE_PRESSURE_PLATE()); + $result->registerBlock("jungle_sapling", fn() => VanillaBlocks::JUNGLE_SAPLING()); $result->registerBlock("jungle_sign", fn() => VanillaBlocks::JUNGLE_SIGN()); + $result->registerBlock("jungle_slab", fn() => VanillaBlocks::JUNGLE_SLAB()); $result->registerBlock("jungle_stairs", fn() => VanillaBlocks::JUNGLE_STAIRS()); $result->registerBlock("jungle_standing_sign", fn() => VanillaBlocks::JUNGLE_SIGN()); $result->registerBlock("jungle_trapdoor", fn() => VanillaBlocks::JUNGLE_TRAPDOOR()); $result->registerBlock("jungle_wall_sign", fn() => VanillaBlocks::JUNGLE_WALL_SIGN()); + $result->registerBlock("jungle_wood", fn() => VanillaBlocks::JUNGLE_WOOD()); + $result->registerBlock("lab_table", fn() => VanillaBlocks::LAB_TABLE()); $result->registerBlock("ladder", fn() => VanillaBlocks::LADDER()); $result->registerBlock("lantern", fn() => VanillaBlocks::LANTERN()); $result->registerBlock("lapis_block", fn() => VanillaBlocks::LAPIS_LAZULI()); + $result->registerBlock("lapis_lazuli_block", fn() => VanillaBlocks::LAPIS_LAZULI()); + $result->registerBlock("lapis_lazuli_ore", fn() => VanillaBlocks::LAPIS_LAZULI_ORE()); $result->registerBlock("lapis_ore", fn() => VanillaBlocks::LAPIS_LAZULI_ORE()); + $result->registerBlock("large_fern", fn() => VanillaBlocks::LARGE_FERN()); $result->registerBlock("lava", fn() => VanillaBlocks::LAVA()); $result->registerBlock("leave", fn() => VanillaBlocks::OAK_LEAVES()); $result->registerBlock("leave2", fn() => VanillaBlocks::ACACIA_LEAVES()); $result->registerBlock("leaves", fn() => VanillaBlocks::OAK_LEAVES()); $result->registerBlock("leaves2", fn() => VanillaBlocks::ACACIA_LEAVES()); + $result->registerBlock("legacy_stonecutter", fn() => VanillaBlocks::LEGACY_STONECUTTER()); $result->registerBlock("lever", fn() => VanillaBlocks::LEVER()); $result->registerBlock("light_blue_glazed_terracotta", fn() => VanillaBlocks::LIGHT_BLUE_GLAZED_TERRACOTTA()); + $result->registerBlock("light_gray_glazed_terracotta", fn() => VanillaBlocks::LIGHT_GRAY_GLAZED_TERRACOTTA()); $result->registerBlock("light_weighted_pressure_plate", fn() => VanillaBlocks::WEIGHTED_PRESSURE_PLATE_LIGHT()); + $result->registerBlock("lilac", fn() => VanillaBlocks::LILAC()); + $result->registerBlock("lily_of_the_valley", fn() => VanillaBlocks::LILY_OF_THE_VALLEY()); $result->registerBlock("lily_pad", fn() => VanillaBlocks::LILY_PAD()); $result->registerBlock("lime_glazed_terracotta", fn() => VanillaBlocks::LIME_GLAZED_TERRACOTTA()); $result->registerBlock("lit_blast_furnace", fn() => VanillaBlocks::BLAST_FURNACE()); @@ -442,6 +651,7 @@ final class StringToItemParser{ $result->registerBlock("loom", fn() => VanillaBlocks::LOOM()); $result->registerBlock("magenta_glazed_terracotta", fn() => VanillaBlocks::MAGENTA_GLAZED_TERRACOTTA()); $result->registerBlock("magma", fn() => VanillaBlocks::MAGMA()); + $result->registerBlock("material_reducer", fn() => VanillaBlocks::MATERIAL_REDUCER()); $result->registerBlock("melon_block", fn() => VanillaBlocks::MELON()); $result->registerBlock("melon_stem", fn() => VanillaBlocks::MELON_STEM()); $result->registerBlock("mob_head_block", fn() => VanillaBlocks::MOB_HEAD()); @@ -451,17 +661,27 @@ final class StringToItemParser{ $result->registerBlock("monster_spawner", fn() => VanillaBlocks::MONSTER_SPAWNER()); $result->registerBlock("moss_stone", fn() => VanillaBlocks::MOSSY_COBBLESTONE()); $result->registerBlock("mossy_cobblestone", fn() => VanillaBlocks::MOSSY_COBBLESTONE()); + $result->registerBlock("mossy_cobblestone_slab", fn() => VanillaBlocks::MOSSY_COBBLESTONE_SLAB()); $result->registerBlock("mossy_cobblestone_stairs", fn() => VanillaBlocks::MOSSY_COBBLESTONE_STAIRS()); + $result->registerBlock("mossy_cobblestone_wall", fn() => VanillaBlocks::MOSSY_COBBLESTONE_WALL()); $result->registerBlock("mossy_stone", fn() => VanillaBlocks::MOSSY_COBBLESTONE()); + $result->registerBlock("mossy_stone_brick_slab", fn() => VanillaBlocks::MOSSY_STONE_BRICK_SLAB()); $result->registerBlock("mossy_stone_brick_stairs", fn() => VanillaBlocks::MOSSY_STONE_BRICK_STAIRS()); + $result->registerBlock("mossy_stone_brick_wall", fn() => VanillaBlocks::MOSSY_STONE_BRICK_WALL()); + $result->registerBlock("mossy_stone_bricks", fn() => VanillaBlocks::MOSSY_STONE_BRICKS()); + $result->registerBlock("mushroom_stem", fn() => VanillaBlocks::MUSHROOM_STEM()); $result->registerBlock("mycelium", fn() => VanillaBlocks::MYCELIUM()); $result->registerBlock("nether_brick_block", fn() => VanillaBlocks::NETHER_BRICKS()); $result->registerBlock("nether_brick_fence", fn() => VanillaBlocks::NETHER_BRICK_FENCE()); + $result->registerBlock("nether_brick_slab", fn() => VanillaBlocks::NETHER_BRICK_SLAB()); $result->registerBlock("nether_brick_stairs", fn() => VanillaBlocks::NETHER_BRICK_STAIRS()); + $result->registerBlock("nether_brick_wall", fn() => VanillaBlocks::NETHER_BRICK_WALL()); $result->registerBlock("nether_bricks", fn() => VanillaBlocks::NETHER_BRICKS()); $result->registerBlock("nether_bricks_stairs", fn() => VanillaBlocks::NETHER_BRICK_STAIRS()); + $result->registerBlock("nether_portal", fn() => VanillaBlocks::NETHER_PORTAL()); $result->registerBlock("nether_quartz_ore", fn() => VanillaBlocks::NETHER_QUARTZ_ORE()); $result->registerBlock("nether_reactor", fn() => VanillaBlocks::NETHER_REACTOR_CORE()); + $result->registerBlock("nether_reactor_core", fn() => VanillaBlocks::NETHER_REACTOR_CORE()); $result->registerBlock("nether_wart", fn() => VanillaBlocks::NETHER_WART()); $result->registerBlock("nether_wart_block", fn() => VanillaBlocks::NETHER_WART_BLOCK()); $result->registerBlock("nether_wart_plant", fn() => VanillaBlocks::NETHER_WART()); @@ -470,21 +690,43 @@ final class StringToItemParser{ $result->registerBlock("normal_stone_stairs", fn() => VanillaBlocks::STONE_STAIRS()); $result->registerBlock("note_block", fn() => VanillaBlocks::NOTE_BLOCK()); $result->registerBlock("noteblock", fn() => VanillaBlocks::NOTE_BLOCK()); + $result->registerBlock("oak_button", fn() => VanillaBlocks::OAK_BUTTON()); $result->registerBlock("oak_door", fn() => VanillaBlocks::OAK_DOOR()); $result->registerBlock("oak_door_block", fn() => VanillaBlocks::OAK_DOOR()); + $result->registerBlock("oak_fence", fn() => VanillaBlocks::OAK_FENCE()); $result->registerBlock("oak_fence_gate", fn() => VanillaBlocks::OAK_FENCE_GATE()); + $result->registerBlock("oak_leaves", fn() => VanillaBlocks::OAK_LEAVES()); + $result->registerBlock("oak_log", fn() => VanillaBlocks::OAK_LOG()); + $result->registerBlock("oak_planks", fn() => VanillaBlocks::OAK_PLANKS()); + $result->registerBlock("oak_pressure_plate", fn() => VanillaBlocks::OAK_PRESSURE_PLATE()); + $result->registerBlock("oak_sapling", fn() => VanillaBlocks::OAK_SAPLING()); + $result->registerBlock("oak_sign", fn() => VanillaBlocks::OAK_SIGN()); + $result->registerBlock("oak_slab", fn() => VanillaBlocks::OAK_SLAB()); $result->registerBlock("oak_stairs", fn() => VanillaBlocks::OAK_STAIRS()); + $result->registerBlock("oak_trapdoor", fn() => VanillaBlocks::OAK_TRAPDOOR()); + $result->registerBlock("oak_wall_sign", fn() => VanillaBlocks::OAK_WALL_SIGN()); + $result->registerBlock("oak_wood", fn() => VanillaBlocks::OAK_WOOD()); $result->registerBlock("oak_wood_stairs", fn() => VanillaBlocks::OAK_STAIRS()); $result->registerBlock("oak_wooden_stairs", fn() => VanillaBlocks::OAK_STAIRS()); $result->registerBlock("obsidian", fn() => VanillaBlocks::OBSIDIAN()); $result->registerBlock("orange_glazed_terracotta", fn() => VanillaBlocks::ORANGE_GLAZED_TERRACOTTA()); + $result->registerBlock("orange_tulip", fn() => VanillaBlocks::ORANGE_TULIP()); + $result->registerBlock("oxeye_daisy", fn() => VanillaBlocks::OXEYE_DAISY()); $result->registerBlock("packed_ice", fn() => VanillaBlocks::PACKED_ICE()); + $result->registerBlock("peony", fn() => VanillaBlocks::PEONY()); $result->registerBlock("pink_glazed_terracotta", fn() => VanillaBlocks::PINK_GLAZED_TERRACOTTA()); + $result->registerBlock("pink_tulip", fn() => VanillaBlocks::PINK_TULIP()); $result->registerBlock("plank", fn() => VanillaBlocks::OAK_PLANKS()); $result->registerBlock("planks", fn() => VanillaBlocks::OAK_PLANKS()); $result->registerBlock("podzol", fn() => VanillaBlocks::PODZOL()); + $result->registerBlock("polished_andesite", fn() => VanillaBlocks::POLISHED_ANDESITE()); + $result->registerBlock("polished_andesite_slab", fn() => VanillaBlocks::POLISHED_ANDESITE_SLAB()); $result->registerBlock("polished_andesite_stairs", fn() => VanillaBlocks::POLISHED_ANDESITE_STAIRS()); + $result->registerBlock("polished_diorite", fn() => VanillaBlocks::POLISHED_DIORITE()); + $result->registerBlock("polished_diorite_slab", fn() => VanillaBlocks::POLISHED_DIORITE_SLAB()); $result->registerBlock("polished_diorite_stairs", fn() => VanillaBlocks::POLISHED_DIORITE_STAIRS()); + $result->registerBlock("polished_granite", fn() => VanillaBlocks::POLISHED_GRANITE()); + $result->registerBlock("polished_granite_slab", fn() => VanillaBlocks::POLISHED_GRANITE_SLAB()); $result->registerBlock("polished_granite_stairs", fn() => VanillaBlocks::POLISHED_GRANITE_STAIRS()); $result->registerBlock("poppy", fn() => VanillaBlocks::POPPY()); $result->registerBlock("portal", fn() => VanillaBlocks::NETHER_PORTAL()); @@ -497,15 +739,25 @@ final class StringToItemParser{ $result->registerBlock("powered_repeater", fn() => VanillaBlocks::REDSTONE_REPEATER()->setPowered(true)); $result->registerBlock("powered_repeater_block", fn() => VanillaBlocks::REDSTONE_REPEATER()->setPowered(true)); $result->registerBlock("prismarine", fn() => VanillaBlocks::PRISMARINE()); + $result->registerBlock("prismarine_bricks", fn() => VanillaBlocks::PRISMARINE_BRICKS()); + $result->registerBlock("prismarine_bricks_slab", fn() => VanillaBlocks::PRISMARINE_BRICKS_SLAB()); $result->registerBlock("prismarine_bricks_stairs", fn() => VanillaBlocks::PRISMARINE_BRICKS_STAIRS()); + $result->registerBlock("prismarine_slab", fn() => VanillaBlocks::PRISMARINE_SLAB()); $result->registerBlock("prismarine_stairs", fn() => VanillaBlocks::PRISMARINE_STAIRS()); + $result->registerBlock("prismarine_wall", fn() => VanillaBlocks::PRISMARINE_WALL()); $result->registerBlock("pumpkin", fn() => VanillaBlocks::PUMPKIN()); $result->registerBlock("pumpkin_stem", fn() => VanillaBlocks::PUMPKIN_STEM()); $result->registerBlock("purple_glazed_terracotta", fn() => VanillaBlocks::PURPLE_GLAZED_TERRACOTTA()); + $result->registerBlock("purple_torch", fn() => VanillaBlocks::PURPLE_TORCH()); + $result->registerBlock("purpur", fn() => VanillaBlocks::PURPUR()); $result->registerBlock("purpur_block", fn() => VanillaBlocks::PURPUR()); + $result->registerBlock("purpur_pillar", fn() => VanillaBlocks::PURPUR_PILLAR()); + $result->registerBlock("purpur_slab", fn() => VanillaBlocks::PURPUR_SLAB()); $result->registerBlock("purpur_stairs", fn() => VanillaBlocks::PURPUR_STAIRS()); $result->registerBlock("quartz_block", fn() => VanillaBlocks::QUARTZ()); $result->registerBlock("quartz_ore", fn() => VanillaBlocks::NETHER_QUARTZ_ORE()); + $result->registerBlock("quartz_pillar", fn() => VanillaBlocks::QUARTZ_PILLAR()); + $result->registerBlock("quartz_slab", fn() => VanillaBlocks::QUARTZ_SLAB()); $result->registerBlock("quartz_stairs", fn() => VanillaBlocks::QUARTZ_STAIRS()); $result->registerBlock("rail", fn() => VanillaBlocks::RAIL()); $result->registerBlock("red_flower", fn() => VanillaBlocks::POPPY()); @@ -513,13 +765,22 @@ final class StringToItemParser{ $result->registerBlock("red_mushroom", fn() => VanillaBlocks::RED_MUSHROOM()); $result->registerBlock("red_mushroom_block", fn() => VanillaBlocks::RED_MUSHROOM_BLOCK()); $result->registerBlock("red_nether_brick", fn() => VanillaBlocks::RED_NETHER_BRICKS()); + $result->registerBlock("red_nether_brick_slab", fn() => VanillaBlocks::RED_NETHER_BRICK_SLAB()); $result->registerBlock("red_nether_brick_stairs", fn() => VanillaBlocks::RED_NETHER_BRICK_STAIRS()); + $result->registerBlock("red_nether_brick_wall", fn() => VanillaBlocks::RED_NETHER_BRICK_WALL()); + $result->registerBlock("red_nether_bricks", fn() => VanillaBlocks::RED_NETHER_BRICKS()); + $result->registerBlock("red_sand", fn() => VanillaBlocks::RED_SAND()); $result->registerBlock("red_sandstone", fn() => VanillaBlocks::RED_SANDSTONE()); $result->registerBlock("red_sandstone_slab", fn() => VanillaBlocks::RED_SANDSTONE_SLAB()); $result->registerBlock("red_sandstone_stairs", fn() => VanillaBlocks::RED_SANDSTONE_STAIRS()); + $result->registerBlock("red_sandstone_wall", fn() => VanillaBlocks::RED_SANDSTONE_WALL()); + $result->registerBlock("red_torch", fn() => VanillaBlocks::RED_TORCH()); + $result->registerBlock("red_tulip", fn() => VanillaBlocks::RED_TULIP()); $result->registerBlock("redstone_block", fn() => VanillaBlocks::REDSTONE()); + $result->registerBlock("redstone_comparator", fn() => VanillaBlocks::REDSTONE_COMPARATOR()); $result->registerBlock("redstone_lamp", fn() => VanillaBlocks::REDSTONE_LAMP()); $result->registerBlock("redstone_ore", fn() => VanillaBlocks::REDSTONE_ORE()); + $result->registerBlock("redstone_repeater", fn() => VanillaBlocks::REDSTONE_REPEATER()); $result->registerBlock("redstone_torch", fn() => VanillaBlocks::REDSTONE_TORCH()); $result->registerBlock("redstone_wire", fn() => VanillaBlocks::REDSTONE_WIRE()); $result->registerBlock("reeds", fn() => VanillaBlocks::SUGARCANE()); @@ -528,9 +789,12 @@ final class StringToItemParser{ $result->registerBlock("repeater_block", fn() => VanillaBlocks::REDSTONE_REPEATER()); $result->registerBlock("reserved6", fn() => VanillaBlocks::RESERVED6()); $result->registerBlock("rose", fn() => VanillaBlocks::POPPY()); + $result->registerBlock("rose_bush", fn() => VanillaBlocks::ROSE_BUSH()); $result->registerBlock("sand", fn() => VanillaBlocks::SAND()); $result->registerBlock("sandstone", fn() => VanillaBlocks::SANDSTONE()); + $result->registerBlock("sandstone_slab", fn() => VanillaBlocks::SANDSTONE_SLAB()); $result->registerBlock("sandstone_stairs", fn() => VanillaBlocks::SANDSTONE_STAIRS()); + $result->registerBlock("sandstone_wall", fn() => VanillaBlocks::SANDSTONE_WALL()); $result->registerBlock("sapling", fn() => VanillaBlocks::OAK_SAPLING()); $result->registerBlock("sea_lantern", fn() => VanillaBlocks::SEA_LANTERN()); $result->registerBlock("sea_pickle", fn() => VanillaBlocks::SEA_PICKLE()); @@ -543,10 +807,17 @@ final class StringToItemParser{ $result->registerBlock("slab", fn() => VanillaBlocks::SMOOTH_STONE_SLAB()); $result->registerBlock("slabs", fn() => VanillaBlocks::SMOOTH_STONE_SLAB()); $result->registerBlock("smoker", fn() => VanillaBlocks::SMOKER()); + $result->registerBlock("smooth_quartz", fn() => VanillaBlocks::SMOOTH_QUARTZ()); + $result->registerBlock("smooth_quartz_slab", fn() => VanillaBlocks::SMOOTH_QUARTZ_SLAB()); $result->registerBlock("smooth_quartz_stairs", fn() => VanillaBlocks::SMOOTH_QUARTZ_STAIRS()); + $result->registerBlock("smooth_red_sandstone", fn() => VanillaBlocks::SMOOTH_RED_SANDSTONE()); + $result->registerBlock("smooth_red_sandstone_slab", fn() => VanillaBlocks::SMOOTH_RED_SANDSTONE_SLAB()); $result->registerBlock("smooth_red_sandstone_stairs", fn() => VanillaBlocks::SMOOTH_RED_SANDSTONE_STAIRS()); + $result->registerBlock("smooth_sandstone", fn() => VanillaBlocks::SMOOTH_SANDSTONE()); + $result->registerBlock("smooth_sandstone_slab", fn() => VanillaBlocks::SMOOTH_SANDSTONE_SLAB()); $result->registerBlock("smooth_sandstone_stairs", fn() => VanillaBlocks::SMOOTH_SANDSTONE_STAIRS()); $result->registerBlock("smooth_stone", fn() => VanillaBlocks::SMOOTH_STONE()); + $result->registerBlock("smooth_stone_slab", fn() => VanillaBlocks::SMOOTH_STONE_SLAB()); $result->registerBlock("snow", fn() => VanillaBlocks::SNOW()); $result->registerBlock("snow_block", fn() => VanillaBlocks::SNOW()); $result->registerBlock("snow_layer", fn() => VanillaBlocks::SNOW_LAYER()); @@ -555,26 +826,37 @@ final class StringToItemParser{ $result->registerBlock("spruce_button", fn() => VanillaBlocks::SPRUCE_BUTTON()); $result->registerBlock("spruce_door", fn() => VanillaBlocks::SPRUCE_DOOR()); $result->registerBlock("spruce_door_block", fn() => VanillaBlocks::SPRUCE_DOOR()); + $result->registerBlock("spruce_fence", fn() => VanillaBlocks::SPRUCE_FENCE()); $result->registerBlock("spruce_fence_gate", fn() => VanillaBlocks::SPRUCE_FENCE_GATE()); + $result->registerBlock("spruce_leaves", fn() => VanillaBlocks::SPRUCE_LEAVES()); + $result->registerBlock("spruce_log", fn() => VanillaBlocks::SPRUCE_LOG()); + $result->registerBlock("spruce_planks", fn() => VanillaBlocks::SPRUCE_PLANKS()); $result->registerBlock("spruce_pressure_plate", fn() => VanillaBlocks::SPRUCE_PRESSURE_PLATE()); + $result->registerBlock("spruce_sapling", fn() => VanillaBlocks::SPRUCE_SAPLING()); $result->registerBlock("spruce_sign", fn() => VanillaBlocks::SPRUCE_SIGN()); + $result->registerBlock("spruce_slab", fn() => VanillaBlocks::SPRUCE_SLAB()); $result->registerBlock("spruce_stairs", fn() => VanillaBlocks::SPRUCE_STAIRS()); $result->registerBlock("spruce_standing_sign", fn() => VanillaBlocks::SPRUCE_SIGN()); $result->registerBlock("spruce_trapdoor", fn() => VanillaBlocks::SPRUCE_TRAPDOOR()); $result->registerBlock("spruce_wall_sign", fn() => VanillaBlocks::SPRUCE_WALL_SIGN()); + $result->registerBlock("spruce_wood", fn() => VanillaBlocks::SPRUCE_WOOD()); $result->registerBlock("spruce_wood_stairs", fn() => VanillaBlocks::SPRUCE_STAIRS()); $result->registerBlock("spruce_wooden_stairs", fn() => VanillaBlocks::SPRUCE_STAIRS()); $result->registerBlock("stained_clay", fn() => VanillaBlocks::STAINED_CLAY()); $result->registerBlock("stained_glass", fn() => VanillaBlocks::STAINED_GLASS()); $result->registerBlock("stained_glass_pane", fn() => VanillaBlocks::STAINED_GLASS_PANE()); $result->registerBlock("stained_hardened_clay", fn() => VanillaBlocks::STAINED_CLAY()); + $result->registerBlock("stained_hardened_glass", fn() => VanillaBlocks::STAINED_HARDENED_GLASS()); + $result->registerBlock("stained_hardened_glass_pane", fn() => VanillaBlocks::STAINED_HARDENED_GLASS_PANE()); $result->registerBlock("standing_banner", fn() => VanillaBlocks::BANNER()); $result->registerBlock("standing_sign", fn() => VanillaBlocks::OAK_SIGN()); $result->registerBlock("still_lava", fn() => VanillaBlocks::LAVA()->setStill(true)); $result->registerBlock("still_water", fn() => VanillaBlocks::WATER()->setStill(true)); $result->registerBlock("stone", fn() => VanillaBlocks::STONE()); $result->registerBlock("stone_brick", fn() => VanillaBlocks::STONE_BRICKS()); + $result->registerBlock("stone_brick_slab", fn() => VanillaBlocks::STONE_BRICK_SLAB()); $result->registerBlock("stone_brick_stairs", fn() => VanillaBlocks::STONE_BRICK_STAIRS()); + $result->registerBlock("stone_brick_wall", fn() => VanillaBlocks::STONE_BRICK_WALL()); $result->registerBlock("stone_bricks", fn() => VanillaBlocks::STONE_BRICKS()); $result->registerBlock("stone_button", fn() => VanillaBlocks::STONE_BUTTON()); $result->registerBlock("stone_pressure_plate", fn() => VanillaBlocks::STONE_PRESSURE_PLATE()); @@ -587,15 +869,22 @@ final class StringToItemParser{ $result->registerBlock("stonebrick", fn() => VanillaBlocks::STONE_BRICKS()); $result->registerBlock("stonecutter", fn() => VanillaBlocks::LEGACY_STONECUTTER()); $result->registerBlock("stripped_acacia_log", fn() => VanillaBlocks::STRIPPED_ACACIA_LOG()); + $result->registerBlock("stripped_acacia_wood", fn() => VanillaBlocks::STRIPPED_ACACIA_WOOD()); $result->registerBlock("stripped_birch_log", fn() => VanillaBlocks::STRIPPED_BIRCH_LOG()); + $result->registerBlock("stripped_birch_wood", fn() => VanillaBlocks::STRIPPED_BIRCH_WOOD()); $result->registerBlock("stripped_dark_oak_log", fn() => VanillaBlocks::STRIPPED_DARK_OAK_LOG()); + $result->registerBlock("stripped_dark_oak_wood", fn() => VanillaBlocks::STRIPPED_DARK_OAK_WOOD()); $result->registerBlock("stripped_jungle_log", fn() => VanillaBlocks::STRIPPED_JUNGLE_LOG()); + $result->registerBlock("stripped_jungle_wood", fn() => VanillaBlocks::STRIPPED_JUNGLE_WOOD()); $result->registerBlock("stripped_oak_log", fn() => VanillaBlocks::STRIPPED_OAK_LOG()); + $result->registerBlock("stripped_oak_wood", fn() => VanillaBlocks::STRIPPED_OAK_WOOD()); $result->registerBlock("stripped_spruce_log", fn() => VanillaBlocks::STRIPPED_SPRUCE_LOG()); + $result->registerBlock("stripped_spruce_wood", fn() => VanillaBlocks::STRIPPED_SPRUCE_WOOD()); $result->registerBlock("sugar_cane", fn() => VanillaBlocks::SUGARCANE()); $result->registerBlock("sugar_canes", fn() => VanillaBlocks::SUGARCANE()); $result->registerBlock("sugarcane", fn() => VanillaBlocks::SUGARCANE()); $result->registerBlock("sugarcane_block", fn() => VanillaBlocks::SUGARCANE()); + $result->registerBlock("sunflower", fn() => VanillaBlocks::SUNFLOWER()); $result->registerBlock("sweet_berry_bush", fn() => VanillaBlocks::SWEET_BERRY_BUSH()); $result->registerBlock("tall_grass", fn() => VanillaBlocks::FERN()); $result->registerBlock("tallgrass", fn() => VanillaBlocks::FERN()); @@ -620,6 +909,7 @@ final class StringToItemParser{ $result->registerBlock("vine", fn() => VanillaBlocks::VINES()); $result->registerBlock("vines", fn() => VanillaBlocks::VINES()); $result->registerBlock("wall_banner", fn() => VanillaBlocks::WALL_BANNER()); + $result->registerBlock("wall_coral_fan", fn() => VanillaBlocks::WALL_CORAL_FAN()); $result->registerBlock("wall_sign", fn() => VanillaBlocks::OAK_WALL_SIGN()); $result->registerBlock("water", fn() => VanillaBlocks::WATER()); $result->registerBlock("water_lily", fn() => VanillaBlocks::LILY_PAD()); @@ -629,6 +919,7 @@ final class StringToItemParser{ $result->registerBlock("weighted_pressure_plate_light", fn() => VanillaBlocks::WEIGHTED_PRESSURE_PLATE_LIGHT()); $result->registerBlock("wheat_block", fn() => VanillaBlocks::WHEAT()); $result->registerBlock("white_glazed_terracotta", fn() => VanillaBlocks::WHITE_GLAZED_TERRACOTTA()); + $result->registerBlock("white_tulip", fn() => VanillaBlocks::WHITE_TULIP()); $result->registerBlock("wood", fn() => VanillaBlocks::OAK_LOG()); $result->registerBlock("wood2", fn() => VanillaBlocks::ACACIA_LOG()); $result->registerBlock("wood_door_block", fn() => VanillaBlocks::OAK_DOOR()); From 224d71f272932e685b088a4aaf6c852e4e87f3ab Mon Sep 17 00:00:00 2001 From: Colin Date: Mon, 23 Aug 2021 22:23:35 +0200 Subject: [PATCH 2741/3224] World: renamed getChunks() to getLoadedChunks() (#4393) --- src/command/defaults/GarbageCollectorCommand.php | 4 ++-- src/command/defaults/StatusCommand.php | 2 +- src/world/World.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/command/defaults/GarbageCollectorCommand.php b/src/command/defaults/GarbageCollectorCommand.php index e9ce55f317..47d1dba819 100644 --- a/src/command/defaults/GarbageCollectorCommand.php +++ b/src/command/defaults/GarbageCollectorCommand.php @@ -54,10 +54,10 @@ class GarbageCollectorCommand extends VanillaCommand{ $memory = memory_get_usage(); foreach($sender->getServer()->getWorldManager()->getWorlds() as $world){ - $diff = [count($world->getChunks()), count($world->getEntities())]; + $diff = [count($world->getLoadedChunks()), count($world->getEntities())]; $world->doChunkGarbageCollection(); $world->unloadChunks(true); - $chunksCollected += $diff[0] - count($world->getChunks()); + $chunksCollected += $diff[0] - count($world->getLoadedChunks()); $entitiesCollected += $diff[1] - count($world->getEntities()); $world->clearCache(true); } diff --git a/src/command/defaults/StatusCommand.php b/src/command/defaults/StatusCommand.php index 7086934237..d3bbc7b3aa 100644 --- a/src/command/defaults/StatusCommand.php +++ b/src/command/defaults/StatusCommand.php @@ -113,7 +113,7 @@ class StatusCommand extends VanillaCommand{ $worldName = $world->getFolderName() !== $world->getDisplayName() ? " (" . $world->getDisplayName() . ")" : ""; $timeColor = $world->getTickRateTime() > 40 ? TextFormat::RED : TextFormat::YELLOW; $sender->sendMessage(TextFormat::GOLD . "World \"{$world->getFolderName()}\"$worldName: " . - TextFormat::RED . number_format(count($world->getChunks())) . TextFormat::GREEN . " chunks, " . + TextFormat::RED . number_format(count($world->getLoadedChunks())) . TextFormat::GREEN . " chunks, " . TextFormat::RED . number_format(count($world->getEntities())) . TextFormat::GREEN . " entities. " . "Time $timeColor" . round($world->getTickRateTime(), 2) . "ms" ); diff --git a/src/world/World.php b/src/world/World.php index 5914e9d994..d70524243e 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2035,7 +2035,7 @@ class World implements ChunkManager{ /** * @return Chunk[] */ - public function getChunks() : array{ + public function getLoadedChunks() : array{ return $this->chunks; } From 6e68e99ec036d57d4707f5a8330aa4168a216c51 Mon Sep 17 00:00:00 2001 From: marshall Date: Tue, 24 Aug 2021 18:56:10 +0800 Subject: [PATCH 2742/3224] Added PlayerEntityInteractEvent (#4374) --- src/entity/Entity.php | 7 +++ .../player/PlayerEntityInteractEvent.php | 56 +++++++++++++++++++ src/player/Player.php | 13 ++++- 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 src/event/player/PlayerEntityInteractEvent.php diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 040fa06c38..51b9d4bfb6 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1058,6 +1058,13 @@ abstract class Entity{ } + /** + * Called when interacted or tapped by a Player. Returns whether something happened as a result of the interaction. + */ + public function onInteract(Player $player, Vector3 $clickPos) : bool{ + return false; + } + public function isUnderwater() : bool{ $block = $this->getWorld()->getBlockAt((int) floor($this->location->x), $blockY = (int) floor($y = ($this->location->y + $this->getEyeHeight())), (int) floor($this->location->z)); diff --git a/src/event/player/PlayerEntityInteractEvent.php b/src/event/player/PlayerEntityInteractEvent.php new file mode 100644 index 0000000000..262d5dbc16 --- /dev/null +++ b/src/event/player/PlayerEntityInteractEvent.php @@ -0,0 +1,56 @@ +player = $player; + } + + public function getEntity() : Entity{ + return $this->entity; + } + + /** + * Returns the absolute coordinates of the click. This is usually on the surface of the entity's hitbox. + */ + public function getClickPosition() : Vector3{ + return $this->clickPos; + } +} diff --git a/src/player/Player.php b/src/player/Player.php index a76d1b52ab..608ee63c93 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -53,6 +53,7 @@ use pocketmine\event\player\PlayerChatEvent; use pocketmine\event\player\PlayerCommandPreprocessEvent; use pocketmine\event\player\PlayerDeathEvent; use pocketmine\event\player\PlayerDisplayNameChangeEvent; +use pocketmine\event\player\PlayerEntityInteractEvent; use pocketmine\event\player\PlayerExhaustEvent; use pocketmine\event\player\PlayerGameModeChangeEvent; use pocketmine\event\player\PlayerInteractEvent; @@ -1684,7 +1685,17 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ * Interacts with the given entity using the currently-held item. */ public function interactEntity(Entity $entity, Vector3 $clickPos) : bool{ - //TODO + $ev = new PlayerEntityInteractEvent($this, $entity, $clickPos); + + if(!$this->canInteract($entity->getLocation(), 8)){ + $ev->cancel(); + } + + $ev->call(); + + if(!$ev->isCancelled()){ + return $entity->onInteract($this, $clickPos); + } return false; } From 4189fbdaefd5f73485b64c0cc9509d8ad0479f5f Mon Sep 17 00:00:00 2001 From: Colin Date: Wed, 25 Aug 2021 15:05:30 +0200 Subject: [PATCH 2743/3224] Added StructureGrowEvent (#4354) This event is currently fired for tree and bamboo growth. Its intended use is for any plant growth that affects multiple blocks at once. TODO: We could explore using this for cacti and sugarcane? --- src/block/Bamboo.php | 8 +++++++ src/block/BambooSapling.php | 8 +++++++ src/block/Sapling.php | 4 ++-- src/event/block/StructureGrowEvent.php | 29 +++++++++++++++++++++++ src/world/generator/object/BirchTree.php | 4 ++-- src/world/generator/object/OakTree.php | 4 ++-- src/world/generator/object/SpruceTree.php | 4 ++-- src/world/generator/object/Tree.php | 16 ++++++++++--- 8 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 src/event/block/StructureGrowEvent.php diff --git a/src/block/Bamboo.php b/src/block/Bamboo.php index 7e1e7f1da4..fc5182cfb9 100644 --- a/src/block/Bamboo.php +++ b/src/block/Bamboo.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\event\block\StructureGrowEvent; use pocketmine\item\Bamboo as ItemBamboo; use pocketmine\item\Fertilizer; use pocketmine\item\Item; @@ -210,6 +211,13 @@ class Bamboo extends Transparent{ foreach($newBlocks as $idx => $newBlock){ $tx->addBlock($this->position->subtract(0, $idx - $growAmount, 0), $newBlock); } + + $ev = new StructureGrowEvent($this, $tx); + $ev->call(); + if($ev->isCancelled()){ + return false; + } + return $tx->apply(); } diff --git a/src/block/BambooSapling.php b/src/block/BambooSapling.php index e01094912a..b617236ed2 100644 --- a/src/block/BambooSapling.php +++ b/src/block/BambooSapling.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\event\block\StructureGrowEvent; use pocketmine\item\Bamboo as ItemBamboo; use pocketmine\item\Fertilizer; use pocketmine\item\Item; @@ -96,6 +97,13 @@ final class BambooSapling extends Flowable{ $bamboo = VanillaBlocks::BAMBOO(); $tx->addBlock($this->position, $bamboo) ->addBlock($this->position->up(), (clone $bamboo)->setLeafSize(Bamboo::SMALL_LEAVES)); + + $ev = new StructureGrowEvent($this, $tx); + $ev->call(); + if($ev->isCancelled()){ + return false; + } + return $tx->apply(); } diff --git a/src/block/Sapling.php b/src/block/Sapling.php index 586f956f38..c084a82968 100644 --- a/src/block/Sapling.php +++ b/src/block/Sapling.php @@ -76,7 +76,7 @@ class Sapling extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof Fertilizer){ - Tree::growTree($this->position->getWorld(), $this->position->x, $this->position->y, $this->position->z, new Random(mt_rand()), $this->treeType); + Tree::growTree($this->position->getWorld(), $this->position->x, $this->position->y, $this->position->z, new Random(mt_rand()), $this->treeType, true); $item->pop(); @@ -99,7 +99,7 @@ class Sapling extends Flowable{ public function onRandomTick() : void{ if($this->position->getWorld()->getFullLightAt($this->position->x, $this->position->y, $this->position->z) >= 8 and mt_rand(1, 7) === 1){ if($this->ready){ - Tree::growTree($this->position->getWorld(), $this->position->x, $this->position->y, $this->position->z, new Random(mt_rand()), $this->treeType); + Tree::growTree($this->position->getWorld(), $this->position->x, $this->position->y, $this->position->z, new Random(mt_rand()), $this->treeType, true); }else{ $this->ready = true; $this->position->getWorld()->setBlock($this->position, $this); diff --git a/src/event/block/StructureGrowEvent.php b/src/event/block/StructureGrowEvent.php new file mode 100644 index 0000000000..88fd54ae88 --- /dev/null +++ b/src/event/block/StructureGrowEvent.php @@ -0,0 +1,29 @@ +transaction = $transaction; + } + + public function getTransaction() : BlockTransaction{ + return $this->transaction; + } +} \ No newline at end of file diff --git a/src/world/generator/object/BirchTree.php b/src/world/generator/object/BirchTree.php index c3fdc8de11..b320d58905 100644 --- a/src/world/generator/object/BirchTree.php +++ b/src/world/generator/object/BirchTree.php @@ -36,11 +36,11 @@ class BirchTree extends Tree{ $this->superBirch = $superBirch; } - public function placeObject(ChunkManager $world, int $x, int $y, int $z, Random $random) : void{ + public function placeObject(ChunkManager $world, int $x, int $y, int $z, Random $random, bool $callEvent = false) : void{ $this->treeHeight = $random->nextBoundedInt(3) + 5; if($this->superBirch){ $this->treeHeight += 5; } - parent::placeObject($world, $x, $y, $z, $random); + parent::placeObject($world, $x, $y, $z, $random, $callEvent); } } diff --git a/src/world/generator/object/OakTree.php b/src/world/generator/object/OakTree.php index e66b7a0e2b..14bbcaf7de 100644 --- a/src/world/generator/object/OakTree.php +++ b/src/world/generator/object/OakTree.php @@ -33,8 +33,8 @@ class OakTree extends Tree{ parent::__construct(VanillaBlocks::OAK_LOG(), VanillaBlocks::OAK_LEAVES()); } - public function placeObject(ChunkManager $world, int $x, int $y, int $z, Random $random) : void{ + public function placeObject(ChunkManager $world, int $x, int $y, int $z, Random $random, bool $callEvent = false) : void{ $this->treeHeight = $random->nextBoundedInt(3) + 4; - parent::placeObject($world, $x, $y, $z, $random); + parent::placeObject($world, $x, $y, $z, $random, $callEvent); } } diff --git a/src/world/generator/object/SpruceTree.php b/src/world/generator/object/SpruceTree.php index 679b5fcc01..7686c6cd24 100644 --- a/src/world/generator/object/SpruceTree.php +++ b/src/world/generator/object/SpruceTree.php @@ -39,9 +39,9 @@ class SpruceTree extends Tree{ return $this->treeHeight - $random->nextBoundedInt(3); } - public function placeObject(ChunkManager $world, int $x, int $y, int $z, Random $random) : void{ + public function placeObject(ChunkManager $world, int $x, int $y, int $z, Random $random, bool $callEvent = false) : void{ $this->treeHeight = $random->nextBoundedInt(4) + 6; - parent::placeObject($world, $x, $y, $z, $random); + parent::placeObject($world, $x, $y, $z, $random, $callEvent); } protected function placeCanopy(int $x, int $y, int $z, Random $random, BlockTransaction $transaction) : void{ diff --git a/src/world/generator/object/Tree.php b/src/world/generator/object/Tree.php index c15ffb5610..61aa1ae743 100644 --- a/src/world/generator/object/Tree.php +++ b/src/world/generator/object/Tree.php @@ -28,6 +28,7 @@ use pocketmine\block\Leaves; use pocketmine\block\Sapling; use pocketmine\block\utils\TreeType; use pocketmine\block\VanillaBlocks; +use pocketmine\event\block\StructureGrowEvent; use pocketmine\utils\Random; use pocketmine\world\BlockTransaction; use pocketmine\world\ChunkManager; @@ -51,10 +52,11 @@ abstract class Tree{ /** * @param TreeType|null $type default oak + * @param bool $callEvent set this parameter to true to allow the calling of the BlockSproutEvent when the tree grows * * @throws \InvalidArgumentException */ - public static function growTree(ChunkManager $world, int $x, int $y, int $z, Random $random, ?TreeType $type = null) : void{ + public static function growTree(ChunkManager $world, int $x, int $y, int $z, Random $random, ?TreeType $type = null, bool $callEvent = false) : void{ /** @var null|Tree $tree */ $tree = null; $type = $type ?? TreeType::OAK(); @@ -78,7 +80,7 @@ abstract class Tree{ } if($tree !== null and $tree->canPlaceObject($world, $x, $y, $z, $random)){ - $tree->placeObject($world, $x, $y, $z, $random); + $tree->placeObject($world, $x, $y, $z, $random, $callEvent); } } @@ -100,11 +102,19 @@ abstract class Tree{ return true; } - public function placeObject(ChunkManager $world, int $x, int $y, int $z, Random $random) : void{ + public function placeObject(ChunkManager $world, int $x, int $y, int $z, Random $random, bool $callEvent = false) : void{ $transaction = new BlockTransaction($world); $this->placeTrunk($x, $y, $z, $random, $this->generateChunkHeight($random), $transaction); $this->placeCanopy($x, $y, $z, $random, $transaction); + if($callEvent){ + $ev = new StructureGrowEvent($world->getBlockAt($x, $y, $z), $transaction); + $ev->call(); + if($ev->isCancelled()){ + return; + } + } + $transaction->apply(); //TODO: handle return value on failure } From 47120022c22143b20ca25f1004b3dcc445781b1f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 26 Aug 2021 13:29:31 +0100 Subject: [PATCH 2744/3224] Localize messages for /op and /deop --- resources/locale | 2 +- src/command/defaults/DeopCommand.php | 2 +- src/command/defaults/OpCommand.php | 2 +- src/lang/KnownTranslationFactory.php | 8 ++++++++ src/lang/KnownTranslationKeys.php | 2 ++ 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/resources/locale b/resources/locale index f07494a024..1332ae273a 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit f07494a0245dc52fa6cbcc4d0e45703d1fc22ee8 +Subproject commit 1332ae273aefc6faf1c62fb62244050e75c4f5e1 diff --git a/src/command/defaults/DeopCommand.php b/src/command/defaults/DeopCommand.php index 615eb9b498..7d94c56330 100644 --- a/src/command/defaults/DeopCommand.php +++ b/src/command/defaults/DeopCommand.php @@ -61,7 +61,7 @@ class DeopCommand extends VanillaCommand{ $sender->getServer()->removeOp($name); if(($player = $sender->getServer()->getPlayerExact($name)) !== null){ - $player->sendMessage(TextFormat::GRAY . "You are no longer op!"); + $player->sendMessage(KnownTranslationFactory::commands_deop_message()->prefix(TextFormat::GRAY)); } Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_deop_success($name)); diff --git a/src/command/defaults/OpCommand.php b/src/command/defaults/OpCommand.php index 3e172b3daf..88348c7acd 100644 --- a/src/command/defaults/OpCommand.php +++ b/src/command/defaults/OpCommand.php @@ -61,7 +61,7 @@ class OpCommand extends VanillaCommand{ $sender->getServer()->addOp($name); if(($player = $sender->getServer()->getPlayerExact($name)) !== null){ - $player->sendMessage(TextFormat::GRAY . "You are now op!"); + $player->sendMessage(KnownTranslationFactory::commands_op_message()->prefix(TextFormat::GRAY)); } Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_op_success($name)); return true; diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index 650d19d83f..29615de91d 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -153,6 +153,10 @@ final class KnownTranslationFactory{ return new Translatable(KnownTranslationKeys::COMMANDS_DEFAULTGAMEMODE_USAGE, []); } + public static function commands_deop_message() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_DEOP_MESSAGE, []); + } + public static function commands_deop_success(Translatable|string $param0) : Translatable{ return new Translatable(KnownTranslationKeys::COMMANDS_DEOP_SUCCESS, [ 0 => $param0, @@ -367,6 +371,10 @@ final class KnownTranslationFactory{ return new Translatable(KnownTranslationKeys::COMMANDS_MESSAGE_USAGE, []); } + public static function commands_op_message() : Translatable{ + return new Translatable(KnownTranslationKeys::COMMANDS_OP_MESSAGE, []); + } + public static function commands_op_success(Translatable|string $param0) : Translatable{ return new Translatable(KnownTranslationKeys::COMMANDS_OP_SUCCESS, [ 0 => $param0, diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index 12aaa7d57e..a5eea3c502 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -50,6 +50,7 @@ final class KnownTranslationKeys{ public const COMMANDS_CLEAR_TESTING = "commands.clear.testing"; public const COMMANDS_DEFAULTGAMEMODE_SUCCESS = "commands.defaultgamemode.success"; public const COMMANDS_DEFAULTGAMEMODE_USAGE = "commands.defaultgamemode.usage"; + public const COMMANDS_DEOP_MESSAGE = "commands.deop.message"; public const COMMANDS_DEOP_SUCCESS = "commands.deop.success"; public const COMMANDS_DEOP_USAGE = "commands.deop.usage"; public const COMMANDS_DIFFICULTY_SUCCESS = "commands.difficulty.success"; @@ -88,6 +89,7 @@ final class KnownTranslationKeys{ public const COMMANDS_MESSAGE_DISPLAY_OUTGOING = "commands.message.display.outgoing"; public const COMMANDS_MESSAGE_SAMETARGET = "commands.message.sameTarget"; public const COMMANDS_MESSAGE_USAGE = "commands.message.usage"; + public const COMMANDS_OP_MESSAGE = "commands.op.message"; public const COMMANDS_OP_SUCCESS = "commands.op.success"; public const COMMANDS_OP_USAGE = "commands.op.usage"; public const COMMANDS_PARTICLE_NOTFOUND = "commands.particle.notFound"; From 239534995fdbefac4d75ab8e1cd9a492b38b7f40 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 26 Aug 2021 13:32:50 +0100 Subject: [PATCH 2745/3224] Update preprocessor submodule to pmmp/PreProcessor@8a3163aad6bb8683a11d78fb907d2f43b0b0fc0a --- build/preprocessor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/preprocessor b/build/preprocessor index 6e223fa9a0..8a3163aad6 160000 --- a/build/preprocessor +++ b/build/preprocessor @@ -1 +1 @@ -Subproject commit 6e223fa9a05b4816c496479fb30a949844513a41 +Subproject commit 8a3163aad6bb8683a11d78fb907d2f43b0b0fc0a From e140614a6378faf64950f770c32331c8fe8afeee Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 26 Aug 2021 15:06:43 +0100 Subject: [PATCH 2746/3224] Localize /gc --- resources/locale | 2 +- .../defaults/GarbageCollectorCommand.php | 11 ++++---- src/lang/KnownTranslationFactory.php | 28 +++++++++++++++++++ src/lang/KnownTranslationKeys.php | 5 ++++ 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/resources/locale b/resources/locale index 1332ae273a..558e260fc5 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 1332ae273aefc6faf1c62fb62244050e75c4f5e1 +Subproject commit 558e260fc5bfee5f0de8ce701be93eeac184f454 diff --git a/src/command/defaults/GarbageCollectorCommand.php b/src/command/defaults/GarbageCollectorCommand.php index 47d1dba819..1614739cd1 100644 --- a/src/command/defaults/GarbageCollectorCommand.php +++ b/src/command/defaults/GarbageCollectorCommand.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\TextFormat; @@ -64,12 +65,12 @@ class GarbageCollectorCommand extends VanillaCommand{ $cyclesCollected = $sender->getServer()->getMemoryManager()->triggerGarbageCollector(); - $sender->sendMessage(TextFormat::GREEN . "---- " . TextFormat::WHITE . "Garbage collection result" . TextFormat::GREEN . " ----"); - $sender->sendMessage(TextFormat::GOLD . "Chunks: " . TextFormat::RED . number_format($chunksCollected)); - $sender->sendMessage(TextFormat::GOLD . "Entities: " . TextFormat::RED . number_format($entitiesCollected)); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_gc_header()->format(TextFormat::GREEN . "---- " . TextFormat::WHITE, TextFormat::GREEN . " ----" . TextFormat::WHITE)); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_gc_chunks(TextFormat::RED . number_format($chunksCollected))->prefix(TextFormat::GOLD)); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_gc_entities(TextFormat::RED . number_format($entitiesCollected))->prefix(TextFormat::GOLD)); - $sender->sendMessage(TextFormat::GOLD . "Cycles: " . TextFormat::RED . number_format($cyclesCollected)); - $sender->sendMessage(TextFormat::GOLD . "Memory freed: " . TextFormat::RED . number_format(round((($memory - memory_get_usage()) / 1024) / 1024, 2), 2) . " MB"); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_gc_cycles(TextFormat::RED . number_format($cyclesCollected))->prefix(TextFormat::GOLD)); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_gc_memoryFreed(TextFormat::RED . number_format(round((($memory - memory_get_usage()) / 1024) / 1024, 2), 2) . " MB")->prefix(TextFormat::GOLD)); return true; } } diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index 29615de91d..e390b01a4e 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -991,10 +991,38 @@ final class KnownTranslationFactory{ return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_GAMEMODE_DESCRIPTION, []); } + public static function pocketmine_command_gc_chunks(Translatable|string $chunksCollected) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_GC_CHUNKS, [ + "chunksCollected" => $chunksCollected, + ]); + } + + public static function pocketmine_command_gc_cycles(Translatable|string $cyclesCollected) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_GC_CYCLES, [ + "cyclesCollected" => $cyclesCollected, + ]); + } + public static function pocketmine_command_gc_description() : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_GC_DESCRIPTION, []); } + public static function pocketmine_command_gc_entities(Translatable|string $entitiesCollected) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_GC_ENTITIES, [ + "entitiesCollected" => $entitiesCollected, + ]); + } + + public static function pocketmine_command_gc_header() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_GC_HEADER, []); + } + + public static function pocketmine_command_gc_memoryFreed(Translatable|string $memoryFreed) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_GC_MEMORYFREED, [ + "memoryFreed" => $memoryFreed, + ]); + } + public static function pocketmine_command_gc_usage() : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_GC_USAGE, []); } diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index a5eea3c502..1c1de33c31 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -214,7 +214,12 @@ final class KnownTranslationKeys{ public const POCKETMINE_COMMAND_ENCHANT_DESCRIPTION = "pocketmine.command.enchant.description"; public const POCKETMINE_COMMAND_EXCEPTION = "pocketmine.command.exception"; public const POCKETMINE_COMMAND_GAMEMODE_DESCRIPTION = "pocketmine.command.gamemode.description"; + public const POCKETMINE_COMMAND_GC_CHUNKS = "pocketmine.command.gc.chunks"; + public const POCKETMINE_COMMAND_GC_CYCLES = "pocketmine.command.gc.cycles"; public const POCKETMINE_COMMAND_GC_DESCRIPTION = "pocketmine.command.gc.description"; + public const POCKETMINE_COMMAND_GC_ENTITIES = "pocketmine.command.gc.entities"; + public const POCKETMINE_COMMAND_GC_HEADER = "pocketmine.command.gc.header"; + public const POCKETMINE_COMMAND_GC_MEMORYFREED = "pocketmine.command.gc.memoryFreed"; public const POCKETMINE_COMMAND_GC_USAGE = "pocketmine.command.gc.usage"; public const POCKETMINE_COMMAND_GIVE_DESCRIPTION = "pocketmine.command.give.description"; public const POCKETMINE_COMMAND_GIVE_USAGE = "pocketmine.command.give.usage"; From 7919a1a1c59bed871f7f32dbc5ff7a13f30fdf13 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 26 Aug 2021 15:24:35 +0100 Subject: [PATCH 2747/3224] Drop support for commands with spaces in the names the use case for this is basically zero, since the community prefers implementing their own subcommand systems instead (which are much more flexible). In addition, allowing spaces in command names makes it extra complicated to display helpful information to the user, such as the command that was actually accepted by the command map (which would be useful for identifying accidental invisible characters / control characters when sending commands). --- src/command/SimpleCommandMap.php | 35 +++++++------------------------- 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/src/command/SimpleCommandMap.php b/src/command/SimpleCommandMap.php index 4412ee8cbf..d54e422b3e 100644 --- a/src/command/SimpleCommandMap.php +++ b/src/command/SimpleCommandMap.php @@ -200,29 +200,6 @@ class SimpleCommandMap implements CommandMap{ return true; } - /** - * Returns a command to match the specified command line, or null if no matching command was found. - * This method is intended to provide capability for handling commands with spaces in their name. - * The referenced parameters will be modified accordingly depending on the resulting matched command. - * - * @param string $commandName reference parameter - * @param string[] $args reference parameter - */ - public function matchCommand(string &$commandName, array &$args) : ?Command{ - $count = min(count($args), 255); - - for($i = 0; $i < $count; ++$i){ - $commandName .= array_shift($args); - if(($command = $this->getCommand($commandName)) instanceof Command){ - return $command; - } - - $commandName .= " "; - } - - return null; - } - public function dispatch(CommandSender $sender, string $commandLine) : bool{ $args = []; preg_match_all('/"((?:\\\\.|[^\\\\"])*)"|(\S+)/u', $commandLine, $matches); @@ -234,9 +211,11 @@ class SimpleCommandMap implements CommandMap{ } } } - $sentCommandLabel = ""; - $target = $this->matchCommand($sentCommandLabel, $args); - + $sentCommandLabel = array_shift($args); + if($sentCommandLabel === null){ + return false; + } + $target = $this->getCommand($sentCommandLabel); if($target === null){ return false; } @@ -288,8 +267,8 @@ class SimpleCommandMap implements CommandMap{ foreach($commandStrings as $commandString){ $args = explode(" ", $commandString); - $commandName = ""; - $command = $this->matchCommand($commandName, $args); + $commandName = array_shift($args); + $command = $this->getCommand($commandName); if($command === null){ $bad[] = $commandString; From d9b9aed2cc31f89fa26306c6b779890487325b9c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 26 Aug 2021 15:31:28 +0100 Subject: [PATCH 2748/3224] Fixed CS --- src/command/SimpleCommandMap.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/command/SimpleCommandMap.php b/src/command/SimpleCommandMap.php index d54e422b3e..aab3a9e8ed 100644 --- a/src/command/SimpleCommandMap.php +++ b/src/command/SimpleCommandMap.php @@ -71,7 +71,6 @@ use function array_shift; use function count; use function explode; use function implode; -use function min; use function preg_match_all; use function strcasecmp; use function stripslashes; From ee16a00c5796b0dac361837ba6e05ad8c71cf006 Mon Sep 17 00:00:00 2001 From: marshall Date: Fri, 27 Aug 2021 20:14:56 +0800 Subject: [PATCH 2749/3224] World: do not attempt placement of itemblock if stack size is zero (#4410) This doesn't make any sense, and also caused a crash. --- src/world/World.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index d70524243e..ae8902e230 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1780,12 +1780,11 @@ class World implements ChunkManager{ return true; } - if($item->canBePlaced()){ - $hand = $item->getBlock($face); - $hand->position($this, $blockReplace->getPosition()->x, $blockReplace->getPosition()->y, $blockReplace->getPosition()->z); - }else{ + if($item->isNull() or !$item->canBePlaced()){ return false; } + $hand = $item->getBlock($face); + $hand->position($this, $blockReplace->getPosition()->x, $blockReplace->getPosition()->y, $blockReplace->getPosition()->z); if($hand->canBePlacedAt($blockClicked, $clickVector, $face, true)){ $blockReplace = $blockClicked; From 8f89c04c51056149c0e9cc61d767799d7f5dbab8 Mon Sep 17 00:00:00 2001 From: Colin Date: Fri, 27 Aug 2021 21:11:05 +0200 Subject: [PATCH 2750/3224] Refactor Tree classes (#4407) --- src/block/Sapling.php | 24 +++++++++++-- src/world/generator/object/BirchTree.php | 5 +-- src/world/generator/object/OakTree.php | 5 +-- src/world/generator/object/SpruceTree.php | 4 +-- src/world/generator/object/Tree.php | 43 +++++++++-------------- src/world/generator/populator/Tree.php | 4 ++- 6 files changed, 49 insertions(+), 36 deletions(-) diff --git a/src/block/Sapling.php b/src/block/Sapling.php index c084a82968..57b16408b0 100644 --- a/src/block/Sapling.php +++ b/src/block/Sapling.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\TreeType; +use pocketmine\event\block\StructureGrowEvent; use pocketmine\item\Fertilizer; use pocketmine\item\Item; use pocketmine\math\Facing; @@ -76,7 +77,7 @@ class Sapling extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof Fertilizer){ - Tree::growTree($this->position->getWorld(), $this->position->x, $this->position->y, $this->position->z, new Random(mt_rand()), $this->treeType, true); + $this->grow(); $item->pop(); @@ -97,9 +98,9 @@ class Sapling extends Flowable{ } public function onRandomTick() : void{ - if($this->position->getWorld()->getFullLightAt($this->position->x, $this->position->y, $this->position->z) >= 8 and mt_rand(1, 7) === 1){ + if($this->position->getWorld()->getFullLightAt($this->position->getFloorX(), $this->position->getFloorY(), $this->position->getFloorZ()) >= 8 and mt_rand(1, 7) === 1){ if($this->ready){ - Tree::growTree($this->position->getWorld(), $this->position->x, $this->position->y, $this->position->z, new Random(mt_rand()), $this->treeType, true); + $this->grow(); }else{ $this->ready = true; $this->position->getWorld()->setBlock($this->position, $this); @@ -107,6 +108,23 @@ class Sapling extends Flowable{ } } + private function grow() : void{ + $random = new Random(mt_rand()); + $tree = Tree::get($random, $this->treeType); + $transaction = $tree?->getBlockTransaction($this->position->getWorld(), $this->position->getFloorX(), $this->position->getFloorY(), $this->position->getFloorZ(), $random); + if($transaction === null){ + return; + } + + $ev = new StructureGrowEvent($this, $transaction); + $ev->call(); + if($ev->isCancelled()){ + return; + } + + $transaction->apply(); + } + public function getFuelTime() : int{ return 100; } diff --git a/src/world/generator/object/BirchTree.php b/src/world/generator/object/BirchTree.php index b320d58905..5bd0b98ffe 100644 --- a/src/world/generator/object/BirchTree.php +++ b/src/world/generator/object/BirchTree.php @@ -25,6 +25,7 @@ namespace pocketmine\world\generator\object; use pocketmine\block\VanillaBlocks; use pocketmine\utils\Random; +use pocketmine\world\BlockTransaction; use pocketmine\world\ChunkManager; class BirchTree extends Tree{ @@ -36,11 +37,11 @@ class BirchTree extends Tree{ $this->superBirch = $superBirch; } - public function placeObject(ChunkManager $world, int $x, int $y, int $z, Random $random, bool $callEvent = false) : void{ + public function getBlockTransaction(ChunkManager $world, int $x, int $y, int $z, Random $random) : ?BlockTransaction{ $this->treeHeight = $random->nextBoundedInt(3) + 5; if($this->superBirch){ $this->treeHeight += 5; } - parent::placeObject($world, $x, $y, $z, $random, $callEvent); + return parent::getBlockTransaction($world, $x, $y, $z, $random); } } diff --git a/src/world/generator/object/OakTree.php b/src/world/generator/object/OakTree.php index 14bbcaf7de..d273d2ae5b 100644 --- a/src/world/generator/object/OakTree.php +++ b/src/world/generator/object/OakTree.php @@ -25,6 +25,7 @@ namespace pocketmine\world\generator\object; use pocketmine\block\VanillaBlocks; use pocketmine\utils\Random; +use pocketmine\world\BlockTransaction; use pocketmine\world\ChunkManager; class OakTree extends Tree{ @@ -33,8 +34,8 @@ class OakTree extends Tree{ parent::__construct(VanillaBlocks::OAK_LOG(), VanillaBlocks::OAK_LEAVES()); } - public function placeObject(ChunkManager $world, int $x, int $y, int $z, Random $random, bool $callEvent = false) : void{ + public function getBlockTransaction(ChunkManager $world, int $x, int $y, int $z, Random $random) : ?BlockTransaction{ $this->treeHeight = $random->nextBoundedInt(3) + 4; - parent::placeObject($world, $x, $y, $z, $random, $callEvent); + return parent::getBlockTransaction($world, $x, $y, $z, $random); } } diff --git a/src/world/generator/object/SpruceTree.php b/src/world/generator/object/SpruceTree.php index 7686c6cd24..62a4e44129 100644 --- a/src/world/generator/object/SpruceTree.php +++ b/src/world/generator/object/SpruceTree.php @@ -39,9 +39,9 @@ class SpruceTree extends Tree{ return $this->treeHeight - $random->nextBoundedInt(3); } - public function placeObject(ChunkManager $world, int $x, int $y, int $z, Random $random, bool $callEvent = false) : void{ + public function getBlockTransaction(ChunkManager $world, int $x, int $y, int $z, Random $random) : ?BlockTransaction{ $this->treeHeight = $random->nextBoundedInt(4) + 6; - parent::placeObject($world, $x, $y, $z, $random, $callEvent); + return parent::getBlockTransaction($world, $x, $y, $z, $random); } protected function placeCanopy(int $x, int $y, int $z, Random $random, BlockTransaction $transaction) : void{ diff --git a/src/world/generator/object/Tree.php b/src/world/generator/object/Tree.php index 61aa1ae743..8d7244dfc4 100644 --- a/src/world/generator/object/Tree.php +++ b/src/world/generator/object/Tree.php @@ -28,7 +28,6 @@ use pocketmine\block\Leaves; use pocketmine\block\Sapling; use pocketmine\block\utils\TreeType; use pocketmine\block\VanillaBlocks; -use pocketmine\event\block\StructureGrowEvent; use pocketmine\utils\Random; use pocketmine\world\BlockTransaction; use pocketmine\world\ChunkManager; @@ -52,36 +51,28 @@ abstract class Tree{ /** * @param TreeType|null $type default oak - * @param bool $callEvent set this parameter to true to allow the calling of the BlockSproutEvent when the tree grows - * - * @throws \InvalidArgumentException */ - public static function growTree(ChunkManager $world, int $x, int $y, int $z, Random $random, ?TreeType $type = null, bool $callEvent = false) : void{ - /** @var null|Tree $tree */ - $tree = null; + public static function get(Random $random, ?TreeType $type = null) : ?self { $type = $type ?? TreeType::OAK(); if($type->equals(TreeType::SPRUCE())){ - $tree = new SpruceTree(); + return new SpruceTree(); }elseif($type->equals(TreeType::BIRCH())){ if($random->nextBoundedInt(39) === 0){ - $tree = new BirchTree(true); + return new BirchTree(true); }else{ - $tree = new BirchTree(); + return new BirchTree(); } }elseif($type->equals(TreeType::JUNGLE())){ - $tree = new JungleTree(); + return new JungleTree(); }elseif($type->equals(TreeType::OAK())){ //default - $tree = new OakTree(); + return new OakTree(); /*if($random->nextRange(0, 9) === 0){ $tree = new BigTree(); }else{*/ //} } - - if($tree !== null and $tree->canPlaceObject($world, $x, $y, $z, $random)){ - $tree->placeObject($world, $x, $y, $z, $random, $callEvent); - } + return null; } public function canPlaceObject(ChunkManager $world, int $x, int $y, int $z, Random $random) : bool{ @@ -102,20 +93,20 @@ abstract class Tree{ return true; } - public function placeObject(ChunkManager $world, int $x, int $y, int $z, Random $random, bool $callEvent = false) : void{ + /** + * Returns the BlockTransaction containing all the blocks the tree would change upon growing at the given coordinates + * or null if the tree can't be grown + */ + public function getBlockTransaction(ChunkManager $world, int $x, int $y, int $z, Random $random) : ?BlockTransaction{ + if(!$this->canPlaceObject($world, $x, $y, $z, $random)){ + return null; + } + $transaction = new BlockTransaction($world); $this->placeTrunk($x, $y, $z, $random, $this->generateChunkHeight($random), $transaction); $this->placeCanopy($x, $y, $z, $random, $transaction); - if($callEvent){ - $ev = new StructureGrowEvent($world->getBlockAt($x, $y, $z), $transaction); - $ev->call(); - if($ev->isCancelled()){ - return; - } - } - - $transaction->apply(); //TODO: handle return value on failure + return $transaction; } protected function generateChunkHeight(Random $random) : int{ diff --git a/src/world/generator/populator/Tree.php b/src/world/generator/populator/Tree.php index 2e1df68d65..f1de8c114f 100644 --- a/src/world/generator/populator/Tree.php +++ b/src/world/generator/populator/Tree.php @@ -62,7 +62,9 @@ class Tree extends Populator{ if($y === -1){ continue; } - ObjectTree::growTree($world, $x, $y, $z, $random, $this->type); + $tree = ObjectTree::get($random, $this->type); + $transaction = $tree?->getBlockTransaction($world, $x, $y, $z, $random); + $transaction?->apply(); } } From 4778c1483a5671b3823da4494784901fa6c62c69 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Aug 2021 20:14:31 +0100 Subject: [PATCH 2751/3224] Tree: fixed formatting error --- src/world/generator/object/Tree.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/generator/object/Tree.php b/src/world/generator/object/Tree.php index 8d7244dfc4..8363935419 100644 --- a/src/world/generator/object/Tree.php +++ b/src/world/generator/object/Tree.php @@ -52,7 +52,7 @@ abstract class Tree{ /** * @param TreeType|null $type default oak */ - public static function get(Random $random, ?TreeType $type = null) : ?self { + public static function get(Random $random, ?TreeType $type = null) : ?self{ $type = $type ?? TreeType::OAK(); if($type->equals(TreeType::SPRUCE())){ return new SpruceTree(); From beba0ffe1578e0632e98b2c38f3c446f2ee0266c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Aug 2021 20:25:21 +0100 Subject: [PATCH 2752/3224] Remove circular dependency between Tree and its children --- src/world/generator/object/Tree.php | 27 ----------- src/world/generator/object/TreeFactory.php | 56 ++++++++++++++++++++++ src/world/generator/populator/Tree.php | 4 +- 3 files changed, 58 insertions(+), 29 deletions(-) create mode 100644 src/world/generator/object/TreeFactory.php diff --git a/src/world/generator/object/Tree.php b/src/world/generator/object/Tree.php index 8363935419..b37f56a3d8 100644 --- a/src/world/generator/object/Tree.php +++ b/src/world/generator/object/Tree.php @@ -26,7 +26,6 @@ namespace pocketmine\world\generator\object; use pocketmine\block\Block; use pocketmine\block\Leaves; use pocketmine\block\Sapling; -use pocketmine\block\utils\TreeType; use pocketmine\block\VanillaBlocks; use pocketmine\utils\Random; use pocketmine\world\BlockTransaction; @@ -49,32 +48,6 @@ abstract class Tree{ $this->treeHeight = $treeHeight; } - /** - * @param TreeType|null $type default oak - */ - public static function get(Random $random, ?TreeType $type = null) : ?self{ - $type = $type ?? TreeType::OAK(); - if($type->equals(TreeType::SPRUCE())){ - return new SpruceTree(); - }elseif($type->equals(TreeType::BIRCH())){ - if($random->nextBoundedInt(39) === 0){ - return new BirchTree(true); - }else{ - return new BirchTree(); - } - }elseif($type->equals(TreeType::JUNGLE())){ - return new JungleTree(); - }elseif($type->equals(TreeType::OAK())){ //default - return new OakTree(); - /*if($random->nextRange(0, 9) === 0){ - $tree = new BigTree(); - }else{*/ - - //} - } - return null; - } - public function canPlaceObject(ChunkManager $world, int $x, int $y, int $z, Random $random) : bool{ $radiusToCheck = 0; for($yy = 0; $yy < $this->treeHeight + 3; ++$yy){ diff --git a/src/world/generator/object/TreeFactory.php b/src/world/generator/object/TreeFactory.php new file mode 100644 index 0000000000..6921817386 --- /dev/null +++ b/src/world/generator/object/TreeFactory.php @@ -0,0 +1,56 @@ +equals(TreeType::SPRUCE())){ + return new SpruceTree(); + }elseif($type->equals(TreeType::BIRCH())){ + if($random->nextBoundedInt(39) === 0){ + return new BirchTree(true); + }else{ + return new BirchTree(); + } + }elseif($type->equals(TreeType::JUNGLE())){ + return new JungleTree(); + }elseif($type->equals(TreeType::OAK())){ //default + return new OakTree(); + /*if($random->nextRange(0, 9) === 0){ + $tree = new BigTree(); + }else{*/ + + //} + } + return null; + } +} diff --git a/src/world/generator/populator/Tree.php b/src/world/generator/populator/Tree.php index f1de8c114f..26063d99fc 100644 --- a/src/world/generator/populator/Tree.php +++ b/src/world/generator/populator/Tree.php @@ -27,7 +27,7 @@ use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\TreeType; use pocketmine\utils\Random; use pocketmine\world\ChunkManager; -use pocketmine\world\generator\object\Tree as ObjectTree; +use pocketmine\world\generator\object\TreeFactory; class Tree extends Populator{ /** @var int */ @@ -62,7 +62,7 @@ class Tree extends Populator{ if($y === -1){ continue; } - $tree = ObjectTree::get($random, $this->type); + $tree = TreeFactory::get($random, $this->type); $transaction = $tree?->getBlockTransaction($world, $x, $y, $z, $random); $transaction?->apply(); } From 6c1fec8a29bf1b2fe9be08262fca4e7adfdbaa58 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Aug 2021 20:32:07 +0100 Subject: [PATCH 2753/3224] Tree: renamed generateChunkHeight to generateTrunkHeight I guess it must have been late at night when I originally wrote this code. --- src/world/generator/object/SpruceTree.php | 2 +- src/world/generator/object/Tree.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/world/generator/object/SpruceTree.php b/src/world/generator/object/SpruceTree.php index 62a4e44129..3439b03d4d 100644 --- a/src/world/generator/object/SpruceTree.php +++ b/src/world/generator/object/SpruceTree.php @@ -35,7 +35,7 @@ class SpruceTree extends Tree{ parent::__construct(VanillaBlocks::SPRUCE_LOG(), VanillaBlocks::SPRUCE_LEAVES(), 10); } - protected function generateChunkHeight(Random $random) : int{ + protected function generateTrunkHeight(Random $random) : int{ return $this->treeHeight - $random->nextBoundedInt(3); } diff --git a/src/world/generator/object/Tree.php b/src/world/generator/object/Tree.php index b37f56a3d8..90eef6c3ab 100644 --- a/src/world/generator/object/Tree.php +++ b/src/world/generator/object/Tree.php @@ -76,13 +76,13 @@ abstract class Tree{ } $transaction = new BlockTransaction($world); - $this->placeTrunk($x, $y, $z, $random, $this->generateChunkHeight($random), $transaction); + $this->placeTrunk($x, $y, $z, $random, $this->generateTrunkHeight($random), $transaction); $this->placeCanopy($x, $y, $z, $random, $transaction); return $transaction; } - protected function generateChunkHeight(Random $random) : int{ + protected function generateTrunkHeight(Random $random) : int{ return $this->treeHeight - 1; } From c7f78bec15d607e04b0c52a8fb71964ef0b515d9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Aug 2021 20:33:17 +0100 Subject: [PATCH 2754/3224] Added missing change to complete beba0ffe1578e0632e98b2c38f3c446f2ee0266c --- src/block/Sapling.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/block/Sapling.php b/src/block/Sapling.php index 57b16408b0..cb9d36b021 100644 --- a/src/block/Sapling.php +++ b/src/block/Sapling.php @@ -32,7 +32,7 @@ use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\utils\Random; use pocketmine\world\BlockTransaction; -use pocketmine\world\generator\object\Tree; +use pocketmine\world\generator\object\TreeFactory; use function mt_rand; class Sapling extends Flowable{ @@ -110,7 +110,7 @@ class Sapling extends Flowable{ private function grow() : void{ $random = new Random(mt_rand()); - $tree = Tree::get($random, $this->treeType); + $tree = TreeFactory::get($random, $this->treeType); $transaction = $tree?->getBlockTransaction($this->position->getWorld(), $this->position->getFloorX(), $this->position->getFloorY(), $this->position->getFloorZ(), $random); if($transaction === null){ return; From 938e430b0fed7bb539e66426ed74c16f9350f512 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Aug 2021 20:41:54 +0100 Subject: [PATCH 2755/3224] Convert Populator into an interface --- src/world/generator/populator/GroundCover.php | 2 +- src/world/generator/populator/Ore.php | 2 +- src/world/generator/populator/Populator.php | 5 +++-- src/world/generator/populator/TallGrass.php | 2 +- src/world/generator/populator/Tree.php | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/world/generator/populator/GroundCover.php b/src/world/generator/populator/GroundCover.php index 718f2cd39d..ed4c652047 100644 --- a/src/world/generator/populator/GroundCover.php +++ b/src/world/generator/populator/GroundCover.php @@ -32,7 +32,7 @@ use pocketmine\world\ChunkManager; use function count; use function min; -class GroundCover extends Populator{ +class GroundCover implements Populator{ public function populate(ChunkManager $world, int $chunkX, int $chunkZ, Random $random) : void{ $chunk = $world->getChunk($chunkX, $chunkZ); diff --git a/src/world/generator/populator/Ore.php b/src/world/generator/populator/Ore.php index 8590852d8c..4c3261a763 100644 --- a/src/world/generator/populator/Ore.php +++ b/src/world/generator/populator/Ore.php @@ -28,7 +28,7 @@ use pocketmine\world\ChunkManager; use pocketmine\world\generator\object\Ore as ObjectOre; use pocketmine\world\generator\object\OreType; -class Ore extends Populator{ +class Ore implements Populator{ /** @var OreType[] */ private $oreTypes = []; diff --git a/src/world/generator/populator/Populator.php b/src/world/generator/populator/Populator.php index f0d0f7b8da..87e734ec0c 100644 --- a/src/world/generator/populator/Populator.php +++ b/src/world/generator/populator/Populator.php @@ -24,12 +24,13 @@ declare(strict_types=1); /** * All the Object populator classes */ + namespace pocketmine\world\generator\populator; use pocketmine\utils\Random; use pocketmine\world\ChunkManager; -abstract class Populator{ +interface Populator{ - abstract public function populate(ChunkManager $world, int $chunkX, int $chunkZ, Random $random) : void; + public function populate(ChunkManager $world, int $chunkX, int $chunkZ, Random $random) : void; } diff --git a/src/world/generator/populator/TallGrass.php b/src/world/generator/populator/TallGrass.php index 2c2667f8ca..a448fba96d 100644 --- a/src/world/generator/populator/TallGrass.php +++ b/src/world/generator/populator/TallGrass.php @@ -28,7 +28,7 @@ use pocketmine\block\VanillaBlocks; use pocketmine\utils\Random; use pocketmine\world\ChunkManager; -class TallGrass extends Populator{ +class TallGrass implements Populator{ /** @var int */ private $randomAmount = 1; /** @var int */ diff --git a/src/world/generator/populator/Tree.php b/src/world/generator/populator/Tree.php index 26063d99fc..005fabb842 100644 --- a/src/world/generator/populator/Tree.php +++ b/src/world/generator/populator/Tree.php @@ -29,7 +29,7 @@ use pocketmine\utils\Random; use pocketmine\world\ChunkManager; use pocketmine\world\generator\object\TreeFactory; -class Tree extends Populator{ +class Tree implements Populator{ /** @var int */ private $randomAmount = 1; /** @var int */ From 43d90d621de4d8e97093e08f943cb4a5a4915347 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Aug 2021 20:55:19 +0100 Subject: [PATCH 2756/3224] [ci skip] update changelog --- changelogs/4.0-snapshot.md | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 4c9c0b1621..a7fa98f36d 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -61,10 +61,6 @@ This major version features substantial changes throughout the core, including s ## Core ### General - A new "plugin greylist" feature has been introduced, which allows whitelisting or blacklisting plugins from loading. -- The `/reload` command has been removed. -- The `/effect` command no longer supports numeric IDs - it's now required to use names. -- The `/enchant` command no longer supports numeric IDs - it's now required to use names. -- Added `/clear` command with functionality equivalent to that of vanilla Minecraft. - Remote console (RCON) has been removed. The [RconServer](https://github.com/pmmp/RconServer) plugin is provided as a substitute. - Spawn protection has been removed. The [BasicSpawnProtection](https://github.com/pmmp/BasicSpawnProtection) plugin is provided as a substitute. - CTRL+C signal handling has been removed. The [PcntlSignalHandler](https://github.com/pmmp/PcntlSignalHandler) plugin is provided as a substitute. @@ -80,6 +76,17 @@ This major version features substantial changes throughout the core, including s - Spawning inside blocks (or above the ground) when respawning with a custom spawn position set - Player spawn positions sticking to the old location when world spawn position changed - this was because the world spawn at time of player creation was used as the player's custom spawn, so the bug will persist for older player data, but will work as expected for new players. +### Commands +- The `/reload` command has been removed. +- The `/effect` command no longer supports numeric IDs - it's now required to use names. +- The `/enchant` command no longer supports numeric IDs - it's now required to use names. +- Added `/clear` command with functionality equivalent to that of vanilla Minecraft. +- The following commands' outputs are now localized according to the chosen language settings: + - `/gc` + - `/status` + - `/op` + - `/deop` + ### Configuration - World presets can now be provided as a `preset` key in `pocketmine.yml`, instead of putting them in the `generator` key. - The following new options have been added to `pocketmine.yml`: @@ -199,7 +206,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` ### Block - A new `VanillaBlocks` class has been added, which contains static methods for creating any currently-known block type. This should be preferred instead of use of `BlockFactory::get()` where constants were used. -- Blocks now contain their positions instead of extending `Position`. `Block->getPos()` has been added. +- Blocks now contain their positions instead of extending `Position`. `Block->getPosition()` has been added. - Blocks with IDs >= 256 are now supported. - Block state and variant metadata have been separated. - Variant is considered an extension of ID and is immutable. @@ -288,6 +295,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - The following API methods have signature changes: - `Command->setPermission()` argument is now mandatory (but still nullable). - `CommandSender->setScreenLineHeight()` argument is now mandatory (but still nullable). +- Commands with spaces in the name are no longer supported. ### Entity #### General @@ -496,6 +504,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `PlayerInteractEvent::RIGHT_CLICK_AIR` - `PlayerInteractEvent::PHYSICAL` - The following events have been added: + - `PlayerEntityInteractEvent`: player right-clicking (or long-clicking on mobile) on an entity. - `PlayerItemUseEvent`: player activating their held item, for example to throw it. - `BlockTeleportEvent`: block teleporting, for example dragon egg when attacked. - `PlayerDisplayNameChangeEvent` @@ -1079,6 +1088,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Chunk->setSubChunk()` no longer accepts `SubChunkInterface`, and the `$allowEmpty` parameter has been removed. - `WorldManager->generateWorld()` (previously `Server->generateWorld()`) now accepts `WorldCreationOptions` instead of `int $seed, class-string $generator, mixed[] $options`. - The following API methods have been renamed / moved: + - `Level->getChunks()` -> `World->getLoadedChunks()` - `Level->getCollisionCubes()` -> `World->getCollisionBoxes()` - `World->getName()` -> `World->getDisplayName()` - `World->populateChunk()` has been split into `World->requestChunkPopulation()` and `World->orderChunkPopulation()`. From 3fe6ce7d1fb5abab3079746a2b75a9a9c4eddd41 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 27 Aug 2021 21:02:52 +0100 Subject: [PATCH 2757/3224] [ci skip] changelog: mention StructureGrowEvent --- changelogs/4.0-snapshot.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index a7fa98f36d..724e58e3b3 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -511,6 +511,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `EntityItemPickupEvent`: player (or other entity) picks up a dropped item (or arrow). Replaces `InventoryPickupItemEvent` and `InventoryPickupArrowEvent`. - Unlike its predecessors, this event supports changing the destination inventory. - If the destination inventory is `null`, the item will be destroyed. This is usually seen for creative players with full inventories. + - `StructureGrowEvent`: called when trees or bamboo grow (or any other multi-block plant structure). - The following events have been removed: - `EntityArmorChangeEvent` - `EntityInventoryChangeEvent` From 2139171a5525a89061cbadfa30f3f3f1243973b4 Mon Sep 17 00:00:00 2001 From: Colin Date: Sun, 29 Aug 2021 01:40:09 +0200 Subject: [PATCH 2758/3224] added BlockItemPickupEvent class (#4402) --- src/event/block/BlockItemPickupEvent.php | 60 ++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/event/block/BlockItemPickupEvent.php diff --git a/src/event/block/BlockItemPickupEvent.php b/src/event/block/BlockItemPickupEvent.php new file mode 100644 index 0000000000..2428405386 --- /dev/null +++ b/src/event/block/BlockItemPickupEvent.php @@ -0,0 +1,60 @@ +origin; + } + + /** + * Items to be received + */ + public function getItem() : Item{ + return clone $this->item; + } + + /** + * Change the items to receive. + */ + public function setItem(Item $item) : void{ + $this->item = clone $item; + } + + /** + * Inventory to which received items will be added. + */ + public function getInventory() : ?Inventory{ + return $this->inventory; + } + + /** + * Change the inventory to which received items are added. + */ + public function setInventory(?Inventory $inventory) : void{ + $this->inventory = $inventory; + } +} \ No newline at end of file From c2558573e208749135456744d42dd3b197e927dc Mon Sep 17 00:00:00 2001 From: Rush2929 <76860328+Rush2929@users.noreply.github.com> Date: Sun, 29 Aug 2021 20:45:23 +0900 Subject: [PATCH 2759/3224] Fix offhand pickup (#4412) --- src/entity/object/ItemEntity.php | 2 +- src/entity/projectile/Arrow.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index 5ca0b93c5f..7de765e65c 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -227,7 +227,7 @@ class ItemEntity extends Entity{ $item = $this->getItem(); $playerInventory = match(true){ - $player->getOffHandInventory()->getItem(0)->canStackWith($item) => $player->getOffHandInventory(), + $player->getOffHandInventory()->getItem(0)->canStackWith($item) and $player->getOffHandInventory()->canAddItem($item) => $player->getOffHandInventory(), $player->getInventory()->canAddItem($item) => $player->getInventory(), default => null }; diff --git a/src/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php index eafaadb96d..5fbef6486d 100644 --- a/src/entity/projectile/Arrow.php +++ b/src/entity/projectile/Arrow.php @@ -175,7 +175,7 @@ class Arrow extends Projectile{ $item = VanillaItems::ARROW(); $playerInventory = match(true){ - $player->getOffHandInventory()->getItem(0)->canStackWith($item) => $player->getOffHandInventory(), + $player->getOffHandInventory()->getItem(0)->canStackWith($item) and $player->getOffHandInventory()->canAddItem($item) => $player->getOffHandInventory(), $player->getInventory()->canAddItem($item) => $player->getInventory(), default => null }; From dee2062b1b7333837af9b1bbeab64c29e690680d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 29 Aug 2021 15:41:10 +0100 Subject: [PATCH 2760/3224] CraftingManager: Reduce footprint of recipe keys this was using json before, which is horribly inefficient. This saved about 200 KB of memory on initial startup (which isn't much, but for more complex recipes, it might have been significantly worse. --- src/crafting/CraftingManager.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/crafting/CraftingManager.php b/src/crafting/CraftingManager.php index 578db78d7c..32b6b77179 100644 --- a/src/crafting/CraftingManager.php +++ b/src/crafting/CraftingManager.php @@ -24,9 +24,11 @@ declare(strict_types=1); namespace pocketmine\crafting; use pocketmine\item\Item; +use pocketmine\nbt\LittleEndianNbtSerializer; +use pocketmine\nbt\TreeRoot; +use pocketmine\utils\BinaryStream; use pocketmine\utils\DestructorCallbackTrait; use pocketmine\utils\ObjectSet; -use function json_encode; use function usort; class CraftingManager{ @@ -108,12 +110,16 @@ class CraftingManager{ private static function hashOutputs(array $outputs) : string{ $outputs = self::pack($outputs); usort($outputs, [self::class, "sort"]); + $result = new BinaryStream(); foreach($outputs as $o){ - //this reduces accuracy of hash, but it's necessary to deal with recipe book shift-clicking stupidity - $o->setCount(1); + //count is not written because the outputs might be from multiple repetitions of a single recipe + //this reduces the accuracy of the hash, but it won't matter in most cases. + $result->putVarInt($o->getId()); + $result->putVarInt($o->getMeta()); + $result->put((new LittleEndianNbtSerializer())->write(new TreeRoot($o->getNamedTag()))); } - return json_encode($outputs); + return $result->getBuffer(); } /** From 8847aa2d7f2109674e5ce3524bfd907042230ae9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 29 Aug 2021 16:13:19 +0100 Subject: [PATCH 2761/3224] LegacyStringToItemParser: mark as deprecated, and point people towards StringToItemParser, which is much nicer --- src/item/LegacyStringToItemParser.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/item/LegacyStringToItemParser.php b/src/item/LegacyStringToItemParser.php index 2d872d93d1..9edb37c19e 100644 --- a/src/item/LegacyStringToItemParser.php +++ b/src/item/LegacyStringToItemParser.php @@ -38,9 +38,14 @@ use function strtolower; use function trim; /** - * This class fills in as a substitute for all the stuff that used to make ItemFactory::fromString() - * work. Since legacy item IDs are on their way out, we can't keep using their constants as stringy - * IDs (especially not considering the unnoticed BC-break potential posed by such a stupid idea). + * @deprecated + * @see StringToItemParser + * + * This class replaces the functionality that used to be provided by ItemFactory::fromString(), but in a more dynamic + * way. + * Avoid using this wherever possible. Unless you need to parse item strings containing meta (e.g. "dye:4", "351:4") or + * item IDs (e.g. "351"), you should prefer the newer StringToItemParser, which is much more user-friendly, more + * flexible, and also supports registering custom aliases for any item in any state. */ final class LegacyStringToItemParser{ use SingletonTrait; From 510b75ef38dbc89c9df11f5a3efbe434465cde94 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 29 Aug 2021 16:23:56 +0100 Subject: [PATCH 2762/3224] Use tagged version of BedrockProtocol --- composer.json | 2 +- composer.lock | 18 ++++++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/composer.json b/composer.json index 9991318570..090e9e2184 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "adhocore/json-comment": "^1.1", "fgrosse/phpasn1": "^2.3", "netresearch/jsonmapper": "^4.0", - "pocketmine/bedrock-protocol": "dev-master#88ae308a03e8e61ccfdddd42623efabe9e772b42", + "pocketmine/bedrock-protocol": "1.0.0+bedrock1.17.10", "pocketmine/binaryutils": "^0.2.1", "pocketmine/callback-validator": "^1.0.2", "pocketmine/classloader": "dev-master", diff --git a/composer.lock b/composer.lock index 69ac419f97..3e33cab316 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "db2d0f1b7626686a7d1d368052ff9a0a", + "content-hash": "2165259c189ef225a417898ac118f0d3", "packages": [ { "name": "adhocore/json-comment", @@ -245,16 +245,16 @@ }, { "name": "pocketmine/bedrock-protocol", - "version": "dev-master", + "version": "1.0.0+bedrock1.17.10", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "88ae308a03e8e61ccfdddd42623efabe9e772b42" + "reference": "2e3bba545dae1774681883fc12a3ee84e553df67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/88ae308a03e8e61ccfdddd42623efabe9e772b42", - "reference": "88ae308a03e8e61ccfdddd42623efabe9e772b42", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/2e3bba545dae1774681883fc12a3ee84e553df67", + "reference": "2e3bba545dae1774681883fc12a3ee84e553df67", "shasum": "" }, "require": { @@ -268,12 +268,11 @@ "ramsey/uuid": "^4.1" }, "require-dev": { - "phpstan/phpstan": "0.12.93", + "phpstan/phpstan": "0.12.96", "phpstan/phpstan-phpunit": "^0.12.21", "phpstan/phpstan-strict-rules": "^0.12.10", "phpunit/phpunit": "^9.5" }, - "default-branch": true, "type": "library", "autoload": { "psr-4": { @@ -287,9 +286,9 @@ "description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP", "support": { "issues": "https://github.com/pmmp/BedrockProtocol/issues", - "source": "https://github.com/pmmp/BedrockProtocol/tree/master" + "source": "https://github.com/pmmp/BedrockProtocol/tree/1.0.0+bedrock1.17.10" }, - "time": "2021-07-23T22:10:41+00:00" + "time": "2021-08-23T14:30:22+00:00" }, { "name": "pocketmine/binaryutils", @@ -3524,7 +3523,6 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "pocketmine/bedrock-protocol": 20, "pocketmine/classloader": 20, "pocketmine/spl": 20 }, From b4e23a57d261e9bf254af2c3a8dc1831894ee8bf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 29 Aug 2021 16:26:18 +0100 Subject: [PATCH 2763/3224] CraftingDataCache: Replace hardcoded recipe block names with constants from BedrockProtocol --- src/network/mcpe/cache/CraftingDataCache.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/network/mcpe/cache/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php index 22dfde37bf..a87629a262 100644 --- a/src/network/mcpe/cache/CraftingDataCache.php +++ b/src/network/mcpe/cache/CraftingDataCache.php @@ -29,7 +29,9 @@ use pocketmine\item\Item; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\CraftingDataPacket; use pocketmine\network\mcpe\protocol\types\inventory\ItemStack; +use pocketmine\network\mcpe\protocol\types\recipe\CraftingRecipeBlockName; use pocketmine\network\mcpe\protocol\types\recipe\FurnaceRecipe as ProtocolFurnaceRecipe; +use pocketmine\network\mcpe\protocol\types\recipe\FurnaceRecipeBlockName; use pocketmine\network\mcpe\protocol\types\recipe\RecipeIngredient; use pocketmine\network\mcpe\protocol\types\recipe\ShapedRecipe as ProtocolShapedRecipe; use pocketmine\network\mcpe\protocol\types\recipe\ShapelessRecipe as ProtocolShapelessRecipe; @@ -87,7 +89,7 @@ final class CraftingDataCache{ return $converter->coreItemStackToNet($item); }, $recipe->getResults()), $nullUUID, - "crafting_table", + CraftingRecipeBlockName::CRAFTING_TABLE, 50, $counter ); @@ -110,7 +112,7 @@ final class CraftingDataCache{ return $converter->coreItemStackToNet($item); }, $recipe->getResults()), $nullUUID, - "crafting_table", + CraftingRecipeBlockName::CRAFTING_TABLE, 50, $counter ); @@ -119,9 +121,9 @@ final class CraftingDataCache{ foreach(FurnaceType::getAll() as $furnaceType){ $typeTag = match($furnaceType->id()){ - FurnaceType::FURNACE()->id() => "furnace", - FurnaceType::BLAST_FURNACE()->id() => "blast_furnace", - FurnaceType::SMOKER()->id() => "smoker", + FurnaceType::FURNACE()->id() => FurnaceRecipeBlockName::FURNACE, + FurnaceType::BLAST_FURNACE()->id() => FurnaceRecipeBlockName::BLAST_FURNACE, + FurnaceType::SMOKER()->id() => FurnaceRecipeBlockName::SMOKER, default => throw new AssumptionFailedError("Unreachable"), }; foreach($manager->getFurnaceRecipeManager($furnaceType)->getAll() as $recipe){ From 533b0d07245d3e6554fd767a206d02ea70c83b5b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 29 Aug 2021 21:04:59 +0100 Subject: [PATCH 2764/3224] Updated convert-world CLI tool --- tools/convert-world.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tools/convert-world.php b/tools/convert-world.php index 3884b19939..1aa9e3d618 100644 --- a/tools/convert-world.php +++ b/tools/convert-world.php @@ -22,16 +22,14 @@ declare(strict_types=1); use pocketmine\world\format\io\FormatConverter; -use pocketmine\world\format\io\WorldProvider; use pocketmine\world\format\io\WorldProviderManager; -use pocketmine\world\format\io\WritableWorldProvider; +use pocketmine\world\format\io\WorldProviderManagerEntry; +use pocketmine\world\format\io\WritableWorldProviderManagerEntry; require_once dirname(__DIR__) . '/vendor/autoload.php'; $providerManager = new WorldProviderManager(); -$writableFormats = array_filter($providerManager->getAvailableProviders(), function(string $class){ - return is_a($class, WritableWorldProvider::class, true); -}); +$writableFormats = array_filter($providerManager->getAvailableProviders(), fn(WorldProviderManagerEntry $class) => $class instanceof WritableWorldProviderManagerEntry); $requiredOpts = [ "world" => "path to the input world for conversion", "backup" => "path to back up the original files", @@ -68,8 +66,7 @@ if(count($oldProviderClasses) > 1){ die("Ambiguous input world format: matched " . count($oldProviderClasses) . " (" . implode(array_keys($oldProviderClasses)) . ")"); } $oldProviderClass = array_shift($oldProviderClasses); -/** @var WorldProvider $oldProvider */ -$oldProvider = new $oldProviderClass($inputPath); +$oldProvider = $oldProviderClass->fromPath($inputPath); $converter = new FormatConverter($oldProvider, $writableFormats[$args["format"]], realpath($backupPath), GlobalLogger::get()); $converter->execute(); From 994a2c9eb9ceb77653327f53de5ec2f53608dacb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 29 Aug 2021 23:11:18 +0100 Subject: [PATCH 2765/3224] Clean up entity/tile data loading from world providers --- src/world/World.php | 38 +++++++++------ src/world/format/Chunk.php | 30 +----------- src/world/format/io/ChunkData.php | 48 +++++++++++++++++++ src/world/format/io/FastChunkSerializer.php | 2 +- src/world/format/io/FormatConverter.php | 2 +- src/world/format/io/WorldProvider.php | 7 ++- src/world/format/io/WritableWorldProvider.php | 4 +- src/world/format/io/leveldb/LevelDB.php | 14 +++--- .../io/region/LegacyAnvilChunkTrait.php | 11 +++-- src/world/format/io/region/McRegion.php | 12 ++--- .../format/io/region/RegionWorldProvider.php | 6 +-- .../io/region/WritableRegionWorldProvider.php | 8 ++-- 12 files changed, 106 insertions(+), 76 deletions(-) create mode 100644 src/world/format/io/ChunkData.php diff --git a/src/world/World.php b/src/world/World.php index ae8902e230..eaa4a94b66 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -75,6 +75,7 @@ use pocketmine\utils\ReversePriorityQueue; use pocketmine\world\biome\Biome; use pocketmine\world\biome\BiomeRegistry; use pocketmine\world\format\Chunk; +use pocketmine\world\format\io\ChunkData; use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\WritableWorldProvider; use pocketmine\world\format\LightArray; @@ -1127,7 +1128,11 @@ class World implements ChunkManager{ foreach($this->chunks as $chunkHash => $chunk){ if($chunk->isDirty()){ self::getXZ($chunkHash, $chunkX, $chunkZ); - $this->provider->saveChunk($chunkX, $chunkZ, $chunk); + $this->provider->saveChunk($chunkX, $chunkZ, new ChunkData( + $chunk, + array_map(fn(Entity $e) => $e->saveNBT(), $chunk->getSavableEntities()), + array_map(fn(Tile $t) => $t->saveNBT(), $chunk->getTiles()), + )); $chunk->clearDirtyFlags(); } } @@ -2443,31 +2448,31 @@ class World implements ChunkManager{ return null; } - $this->chunks[$chunkHash] = $chunk; + $this->chunks[$chunkHash] = $chunk->getChunk(); unset($this->blockCache[$chunkHash]); $this->initChunk($x, $z, $chunk); - (new ChunkLoadEvent($this, $x, $z, $chunk, false))->call(); + (new ChunkLoadEvent($this, $x, $z, $this->chunks[$chunkHash], false))->call(); if(!$this->isChunkInUse($x, $z)){ $this->logger->debug("Newly loaded chunk $x $z has no loaders registered, will be unloaded at next available opportunity"); $this->unloadChunkRequest($x, $z); } foreach($this->getChunkListeners($x, $z) as $listener){ - $listener->onChunkLoaded($x, $z, $chunk); + $listener->onChunkLoaded($x, $z, $this->chunks[$chunkHash]); } $this->timings->syncChunkLoad->stopTiming(); - return $chunk; + return $this->chunks[$chunkHash]; } - private function initChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ - if($chunk->NBTentities !== null){ + private function initChunk(int $chunkX, int $chunkZ, ChunkData $chunkData) : void{ + if(count($chunkData->getEntityNBT()) !== 0){ $this->timings->syncChunkLoadEntities->startTiming(); $entityFactory = EntityFactory::getInstance(); - foreach($chunk->NBTentities as $k => $nbt){ + foreach($chunkData->getEntityNBT() as $k => $nbt){ try{ $entity = $entityFactory->createFromData($this, $nbt); }catch(NbtDataException $e){ @@ -2489,14 +2494,14 @@ class World implements ChunkManager{ //here, because entities currently add themselves to the world } - $chunk->setDirtyFlag(Chunk::DIRTY_FLAG_ENTITIES, true); - $chunk->NBTentities = null; + $this->getChunk($chunkX, $chunkZ)?->setDirtyFlag(Chunk::DIRTY_FLAG_ENTITIES, true); $this->timings->syncChunkLoadEntities->stopTiming(); } - if($chunk->NBTtiles !== null){ + + if(count($chunkData->getTileNBT()) !== 0){ $this->timings->syncChunkLoadTileEntities->startTiming(); $tileFactory = TileFactory::getInstance(); - foreach($chunk->NBTtiles as $k => $nbt){ + foreach($chunkData->getTileNBT() as $k => $nbt){ try{ $tile = $tileFactory->createFromData($this, $nbt); }catch(NbtDataException $e){ @@ -2513,8 +2518,7 @@ class World implements ChunkManager{ } } - $chunk->setDirtyFlag(Chunk::DIRTY_FLAG_TILES, true); - $chunk->NBTtiles = null; + $this->getChunk($chunkX, $chunkZ)?->setDirtyFlag(Chunk::DIRTY_FLAG_TILES, true); $this->timings->syncChunkLoadTileEntities->stopTiming(); } } @@ -2564,7 +2568,11 @@ class World implements ChunkManager{ if($trySave and $this->getAutoSave() and $chunk->isDirty()){ $this->timings->syncChunkSave->startTiming(); try{ - $this->provider->saveChunk($x, $z, $chunk); + $this->provider->saveChunk($x, $z, new ChunkData( + $chunk, + array_map(fn(Entity $e) => $e->saveNBT(), $chunk->getSavableEntities()), + array_map(fn(Tile $t) => $t->saveNBT(), $chunk->getTiles()), + )); }finally{ $this->timings->syncChunkSave->stopTiming(); } diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index e51eeec05f..551b37cb7d 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -31,7 +31,6 @@ use pocketmine\block\BlockLegacyIds; use pocketmine\block\tile\Tile; use pocketmine\data\bedrock\BiomeIds; use pocketmine\entity\Entity; -use pocketmine\nbt\tag\CompoundTag; use pocketmine\player\Player; use function array_fill; use function array_filter; @@ -72,18 +71,10 @@ class Chunk{ /** @var BiomeArray */ protected $biomeIds; - /** @var CompoundTag[]|null */ - public $NBTtiles; - - /** @var CompoundTag[]|null */ - public $NBTentities; - /** - * @param SubChunk[] $subChunks - * @param CompoundTag[] $entities - * @param CompoundTag[] $tiles + * @param SubChunk[] $subChunks */ - public function __construct(array $subChunks = [], ?array $entities = null, ?array $tiles = null, ?BiomeArray $biomeIds = null, ?HeightArray $heightMap = null){ + public function __construct(array $subChunks = [], ?BiomeArray $biomeIds = null, ?HeightArray $heightMap = null){ $this->subChunks = new \SplFixedArray(Chunk::MAX_SUBCHUNKS); foreach($this->subChunks as $y => $null){ @@ -93,9 +84,6 @@ class Chunk{ $val = ($this->subChunks->getSize() * 16); $this->heightMap = $heightMap ?? new HeightArray(array_fill(0, 256, $val)); $this->biomeIds = $biomeIds ?? BiomeArray::fill(BiomeIds::OCEAN); - - $this->NBTtiles = $tiles; - $this->NBTentities = $entities; } /** @@ -292,20 +280,6 @@ class Chunk{ } } - /** - * @return CompoundTag[] - */ - public function getNBTtiles() : array{ - return $this->NBTtiles ?? array_map(function(Tile $tile) : CompoundTag{ return $tile->saveNBT(); }, $this->tiles); - } - - /** - * @return CompoundTag[] - */ - public function getNBTentities() : array{ - return $this->NBTentities ?? array_map(function(Entity $entity) : CompoundTag{ return $entity->saveNBT(); }, $this->getSavableEntities()); - } - public function getBiomeIdArray() : string{ return $this->biomeIds->getData(); } diff --git a/src/world/format/io/ChunkData.php b/src/world/format/io/ChunkData.php new file mode 100644 index 0000000000..93ce350958 --- /dev/null +++ b/src/world/format/io/ChunkData.php @@ -0,0 +1,48 @@ +chunk; } + + /** @return CompoundTag[] */ + public function getEntityNBT() : array{ return $this->entityNBT; } + + /** @return CompoundTag[] */ + public function getTileNBT() : array{ return $this->tileNBT; } +} diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index c60c1bf56c..8dcdb10e77 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -143,7 +143,7 @@ final class FastChunkSerializer{ $heightMap = new HeightArray(array_values($unpackedHeightMap)); } - $chunk = new Chunk($subChunks, null, null, $biomeIds, $heightMap); + $chunk = new Chunk($subChunks, $biomeIds, $heightMap); $chunk->setPopulated($terrainPopulated); $chunk->setLightPopulated($lightPopulated); $chunk->clearDirtyFlags(); diff --git a/src/world/format/io/FormatConverter.php b/src/world/format/io/FormatConverter.php index 24ca24db34..1ad50ccc86 100644 --- a/src/world/format/io/FormatConverter.php +++ b/src/world/format/io/FormatConverter.php @@ -149,7 +149,7 @@ class FormatConverter{ $thisRound = $start; foreach($this->oldProvider->getAllChunks(true, $this->logger) as $coords => $chunk){ [$chunkX, $chunkZ] = $coords; - $chunk->setDirty(); + $chunk->getChunk()->setDirty(); $new->saveChunk($chunkX, $chunkZ, $chunk); $counter++; if(($counter % $this->chunksPerProgressUpdate) === 0){ diff --git a/src/world/format/io/WorldProvider.php b/src/world/format/io/WorldProvider.php index 5089d8e5ba..577bfe876b 100644 --- a/src/world/format/io/WorldProvider.php +++ b/src/world/format/io/WorldProvider.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\world\format\io; -use pocketmine\world\format\Chunk; use pocketmine\world\format\io\exception\CorruptedChunkException; interface WorldProvider{ @@ -44,7 +43,7 @@ interface WorldProvider{ * * @throws CorruptedChunkException */ - public function loadChunk(int $chunkX, int $chunkZ) : ?Chunk; + public function loadChunk(int $chunkX, int $chunkZ) : ?ChunkData; /** * Performs garbage collection in the world provider, such as cleaning up regions in Region-based worlds. @@ -64,8 +63,8 @@ interface WorldProvider{ /** * Returns a generator which yields all the chunks in this world. * - * @return \Generator|Chunk[] - * @phpstan-return \Generator + * @return \Generator|ChunkData[] + * @phpstan-return \Generator * @throws CorruptedChunkException */ public function getAllChunks(bool $skipCorrupted = false, ?\Logger $logger = null) : \Generator; diff --git a/src/world/format/io/WritableWorldProvider.php b/src/world/format/io/WritableWorldProvider.php index 61fe03f0b0..eda481e3a3 100644 --- a/src/world/format/io/WritableWorldProvider.php +++ b/src/world/format/io/WritableWorldProvider.php @@ -23,11 +23,9 @@ declare(strict_types=1); namespace pocketmine\world\format\io; -use pocketmine\world\format\Chunk; - interface WritableWorldProvider extends WorldProvider{ /** * Saves a chunk (usually to disk). */ - public function saveChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void; + public function saveChunk(int $chunkX, int $chunkZ, ChunkData $chunkData) : void; } diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index c479df90fd..5064141de8 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -36,6 +36,7 @@ use pocketmine\utils\BinaryStream; use pocketmine\world\format\BiomeArray; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\BaseWorldProvider; +use pocketmine\world\format\io\ChunkData; use pocketmine\world\format\io\ChunkUtils; use pocketmine\world\format\io\data\BedrockWorldData; use pocketmine\world\format\io\exception\CorruptedChunkException; @@ -232,7 +233,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ /** * @throws CorruptedChunkException */ - public function loadChunk(int $chunkX, int $chunkZ) : ?Chunk{ + public function loadChunk(int $chunkX, int $chunkZ) : ?ChunkData{ $index = LevelDB::chunkIndex($chunkX, $chunkZ); $chunkVersionRaw = $this->db->get($index . self::TAG_VERSION); @@ -405,8 +406,6 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $chunk = new Chunk( $subChunks, - $entities, - $tiles, $biomeArray ); @@ -423,16 +422,17 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $chunk->setDirty(); //trigger rewriting chunk to disk if it was converted from an older format } - return $chunk; + return new ChunkData($chunk, $entities, $tiles); } - public function saveChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ + public function saveChunk(int $chunkX, int $chunkZ, ChunkData $chunkData) : void{ $idMap = LegacyBlockIdToStringIdMap::getInstance(); $index = LevelDB::chunkIndex($chunkX, $chunkZ); $write = new \LevelDBWriteBatch(); $write->put($index . self::TAG_VERSION, chr(self::CURRENT_LEVEL_CHUNK_VERSION)); + $chunk = $chunkData->getChunk(); if($chunk->getDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN)){ $subChunks = $chunk->getSubChunks(); foreach($subChunks as $y => $subChunk){ @@ -474,8 +474,8 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ //TODO: use this properly $write->put($index . self::TAG_STATE_FINALISATION, chr($chunk->isPopulated() ? self::FINALISATION_DONE : self::FINALISATION_NEEDS_POPULATION)); - $this->writeTags($chunk->getNBTtiles(), $index . self::TAG_BLOCK_ENTITY, $write); - $this->writeTags($chunk->getNBTentities(), $index . self::TAG_ENTITY, $write); + $this->writeTags($chunkData->getTileNBT(), $index . self::TAG_BLOCK_ENTITY, $write); + $this->writeTags($chunkData->getEntityNBT(), $index . self::TAG_ENTITY, $write); $write->delete($index . self::TAG_DATA_2D_LEGACY); $write->delete($index . self::TAG_LEGACY_TERRAIN); diff --git a/src/world/format/io/region/LegacyAnvilChunkTrait.php b/src/world/format/io/region/LegacyAnvilChunkTrait.php index c507c86387..831f02b18a 100644 --- a/src/world/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/world/format/io/region/LegacyAnvilChunkTrait.php @@ -31,6 +31,7 @@ use pocketmine\nbt\tag\IntArrayTag; use pocketmine\nbt\tag\ListTag; use pocketmine\world\format\BiomeArray; use pocketmine\world\format\Chunk; +use pocketmine\world\format\io\ChunkData; use pocketmine\world\format\io\ChunkUtils; use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\SubChunk; @@ -49,7 +50,7 @@ trait LegacyAnvilChunkTrait{ /** * @throws CorruptedChunkException */ - protected function deserializeChunk(string $data) : Chunk{ + protected function deserializeChunk(string $data) : ChunkData{ $decompressed = @zlib_decode($data); if($decompressed === false){ throw new CorruptedChunkException("Failed to decompress chunk NBT"); @@ -89,12 +90,14 @@ trait LegacyAnvilChunkTrait{ $result = new Chunk( $subChunks, - ($entitiesTag = $chunk->getTag("Entities")) instanceof ListTag ? self::getCompoundList("Entities", $entitiesTag) : [], - ($tilesTag = $chunk->getTag("TileEntities")) instanceof ListTag ? self::getCompoundList("TileEntities", $tilesTag) : [], $biomeArray ); $result->setPopulated($chunk->getByte("TerrainPopulated", 0) !== 0); - return $result; + return new ChunkData( + $result, + ($entitiesTag = $chunk->getTag("Entities")) instanceof ListTag ? self::getCompoundList("Entities", $entitiesTag) : [], + ($tilesTag = $chunk->getTag("TileEntities")) instanceof ListTag ? self::getCompoundList("TileEntities", $tilesTag) : [], + ); } abstract protected function deserializeSubChunk(CompoundTag $subChunk) : SubChunk; diff --git a/src/world/format/io/region/McRegion.php b/src/world/format/io/region/McRegion.php index 9f9b3977e3..aab62a3db3 100644 --- a/src/world/format/io/region/McRegion.php +++ b/src/world/format/io/region/McRegion.php @@ -33,6 +33,7 @@ use pocketmine\nbt\tag\IntArrayTag; use pocketmine\nbt\tag\ListTag; use pocketmine\world\format\BiomeArray; use pocketmine\world\format\Chunk; +use pocketmine\world\format\io\ChunkData; use pocketmine\world\format\io\ChunkUtils; use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\SubChunkConverter; @@ -43,7 +44,7 @@ class McRegion extends RegionWorldProvider{ /** * @throws CorruptedChunkException */ - protected function deserializeChunk(string $data) : Chunk{ + protected function deserializeChunk(string $data) : ChunkData{ $decompressed = @zlib_decode($data); if($decompressed === false){ throw new CorruptedChunkException("Failed to decompress chunk NBT"); @@ -81,14 +82,13 @@ class McRegion extends RegionWorldProvider{ $biomeIds = $makeBiomeArray($biomesTag->getValue()); } - $result = new Chunk( - $subChunks, + $result = new Chunk($subChunks, $biomeIds); + $result->setPopulated($chunk->getByte("TerrainPopulated", 0) !== 0); + return new ChunkData( + $result, ($entitiesTag = $chunk->getTag("Entities")) instanceof ListTag ? self::getCompoundList("Entities", $entitiesTag) : [], ($tilesTag = $chunk->getTag("TileEntities")) instanceof ListTag ? self::getCompoundList("TileEntities", $tilesTag) : [], - $biomeIds ); - $result->setPopulated($chunk->getByte("TerrainPopulated", 0) !== 0); - return $result; } protected static function getRegionFileExtension() : string{ diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index 3765a33eb5..3ac9132f67 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -27,8 +27,8 @@ use pocketmine\nbt\NBT; use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; -use pocketmine\world\format\Chunk; use pocketmine\world\format\io\BaseWorldProvider; +use pocketmine\world\format\io\ChunkData; use pocketmine\world\format\io\data\JavaWorldData; use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\WorldData; @@ -146,7 +146,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ /** * @throws CorruptedChunkException */ - abstract protected function deserializeChunk(string $data) : Chunk; + abstract protected function deserializeChunk(string $data) : ChunkData; /** * @return CompoundTag[] @@ -185,7 +185,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ /** * @throws CorruptedChunkException */ - public function loadChunk(int $chunkX, int $chunkZ) : ?Chunk{ + public function loadChunk(int $chunkX, int $chunkZ) : ?ChunkData{ $regionX = $regionZ = null; self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ); assert(is_int($regionX) and is_int($regionZ)); diff --git a/src/world/format/io/region/WritableRegionWorldProvider.php b/src/world/format/io/region/WritableRegionWorldProvider.php index ed1b9eba77..ae4c5ee06e 100644 --- a/src/world/format/io/region/WritableRegionWorldProvider.php +++ b/src/world/format/io/region/WritableRegionWorldProvider.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\format\io\region; -use pocketmine\world\format\Chunk; +use pocketmine\world\format\io\ChunkData; use pocketmine\world\format\io\data\JavaWorldData; use pocketmine\world\format\io\WritableWorldProvider; use pocketmine\world\WorldCreationOptions; @@ -51,10 +51,10 @@ abstract class WritableRegionWorldProvider extends RegionWorldProvider implement JavaWorldData::generate($path, $name, $options, static::getPcWorldFormatVersion()); } - abstract protected function serializeChunk(Chunk $chunk) : string; + abstract protected function serializeChunk(ChunkData $chunk) : string; - public function saveChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ + public function saveChunk(int $chunkX, int $chunkZ, ChunkData $chunkData) : void{ self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ); - $this->loadRegion($regionX, $regionZ)->writeChunk($chunkX & 0x1f, $chunkZ & 0x1f, $this->serializeChunk($chunk)); + $this->loadRegion($regionX, $regionZ)->writeChunk($chunkX & 0x1f, $chunkZ & 0x1f, $this->serializeChunk($chunkData)); } } From ee8b854f30527cb379787e2b43cc80fbf8ad68a7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 29 Aug 2021 23:31:24 +0100 Subject: [PATCH 2766/3224] Add tools/ to PHPStan analysis --- phpstan.neon.dist | 2 ++ tools/compact-regions.php | 6 +++++- tools/convert-world.php | 14 ++++++++------ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 9618642aab..85b9b2fc81 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -27,6 +27,7 @@ parameters: - tests/phpstan/bootstrap.php scanDirectories: - tests/plugins/TesterPlugin + - tools scanFiles: - src/PocketMine.php - build/make-release.php @@ -39,6 +40,7 @@ parameters: - build/server-phar.php - tests/phpunit - tests/plugins/TesterPlugin + - tools dynamicConstantNames: - pocketmine\VersionInfo::IS_DEVELOPMENT_BUILD - pocketmine\DEBUG diff --git a/tools/compact-regions.php b/tools/compact-regions.php index 54e6fbe94a..153bd62b9f 100644 --- a/tools/compact-regions.php +++ b/tools/compact-regions.php @@ -59,7 +59,11 @@ const SUPPORTED_EXTENSIONS = [ * @phpstan-param array $files */ function find_regions_recursive(string $dir, array &$files) : void{ - foreach(scandir($dir, SCANDIR_SORT_NONE) as $file){ + $dirFiles = scandir($dir, SCANDIR_SORT_NONE); + if($dirFiles === false){ + return; + } + foreach($dirFiles as $file){ if($file === "." or $file === ".."){ continue; } diff --git a/tools/convert-world.php b/tools/convert-world.php index 1aa9e3d618..c70f23a697 100644 --- a/tools/convert-world.php +++ b/tools/convert-world.php @@ -39,11 +39,13 @@ $usageMessage = "Options:\n"; foreach($requiredOpts as $_opt => $_desc){ $usageMessage .= "\t--$_opt : $_desc\n"; } -$args = getopt("", array_map(function(string $str){ return "$str:"; }, array_keys($requiredOpts))); +$plainArgs = getopt("", array_map(function(string $str){ return "$str:"; }, array_keys($requiredOpts))); +$args = []; foreach($requiredOpts as $opt => $desc){ - if(!isset($args[$opt])){ + if(!isset($plainArgs[$opt]) || !is_string($plainArgs[$opt])){ die($usageMessage); } + $args[$opt] = $plainArgs[$opt]; } if(!array_key_exists($args["format"], $writableFormats)){ die($usageMessage); @@ -53,9 +55,9 @@ $inputPath = realpath($args["world"]); if($inputPath === false){ die("Cannot find input world at location: " . $args["world"]); } -$backupPath = $args["backup"]; -if((!@mkdir($backupPath, 0777, true) and !is_dir($backupPath)) or !is_writable($backupPath)){ - die("Backup file path " . $backupPath . " is not writable (permission error or doesn't exist), aborting"); +$backupPath = realpath($args["backup"]); +if($backupPath === false || (!@mkdir($backupPath, 0777, true) and !is_dir($backupPath)) or !is_writable($backupPath)){ + die("Backup file path " . $args["backup"] . " is not writable (permission error or doesn't exist), aborting"); } $oldProviderClasses = $providerManager->getMatchingProviders($inputPath); @@ -68,5 +70,5 @@ if(count($oldProviderClasses) > 1){ $oldProviderClass = array_shift($oldProviderClasses); $oldProvider = $oldProviderClass->fromPath($inputPath); -$converter = new FormatConverter($oldProvider, $writableFormats[$args["format"]], realpath($backupPath), GlobalLogger::get()); +$converter = new FormatConverter($oldProvider, $writableFormats[$args["format"]], $backupPath, GlobalLogger::get()); $converter->execute(); From 7def3db7810bacc71152acdaa114d6b55d4ea716 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 29 Aug 2021 23:32:08 +0100 Subject: [PATCH 2767/3224] Fixed generate-known-translation-apis script not getting PHPStan'd --- phpstan.neon.dist | 1 + 1 file changed, 1 insertion(+) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 85b9b2fc81..af85e84a94 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -36,6 +36,7 @@ parameters: paths: - src - tests/phpstan/rules + - build/generate-known-translation-apis.php - build/make-release.php - build/server-phar.php - tests/phpunit From 4b06e19d2898988b7487e2385e20f7b461504ea7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 29 Aug 2021 23:33:07 +0100 Subject: [PATCH 2768/3224] Cover tools/ in php-cs-fixer --- .php-cs-fixer.php | 1 + tools/compact-regions.php | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index 373c8fc80e..925c1cbcae 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -4,6 +4,7 @@ $finder = PhpCsFixer\Finder::create() ->in(__DIR__ . '/src') ->in(__DIR__ . '/build') ->in(__DIR__ . '/tests') + ->in(__DIR__ . '/tools') ->notPath('plugins/DevTools') ->notPath('preprocessor') ->notContains('#ifndef COMPILE') //preprocessor will break if these are changed diff --git a/tools/compact-regions.php b/tools/compact-regions.php index 153bd62b9f..62f1d35f46 100644 --- a/tools/compact-regions.php +++ b/tools/compact-regions.php @@ -43,8 +43,6 @@ use function rename; use function round; use function scandir; use function unlink; -use function zlib_decode; -use function zlib_encode; require dirname(__DIR__) . '/vendor/autoload.php'; From 0289b45202bac7274cba3c0ff1b713157b66329b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 30 Aug 2021 00:09:36 +0100 Subject: [PATCH 2769/3224] Chunk: Drop dirty flags for tiles and entities instead, just ungate this and allow the provider to decide what to do. Any chunk that contains entities or tiles is already always considered dirty, so the only thing the flags are good for is flagging chunks that previously had tiles and/or entities but no longer do. In those cases, it's just removing keys from LevelDB anyway, so it's already very cheap. Avoiding these redundant deletions is not worth the extra complexity and fragility of relying on flags to track this stuff. --- src/world/World.php | 22 ++++------ src/world/format/Chunk.php | 47 ++++++++------------- src/world/format/io/FastChunkSerializer.php | 2 +- src/world/format/io/FormatConverter.php | 2 +- src/world/format/io/leveldb/LevelDB.php | 6 +-- src/world/generator/PopulationTask.php | 10 ++--- 6 files changed, 37 insertions(+), 52 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index eaa4a94b66..43d15bbbc2 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1126,15 +1126,13 @@ class World implements ChunkManager{ $this->timings->syncChunkSave->startTiming(); try{ foreach($this->chunks as $chunkHash => $chunk){ - if($chunk->isDirty()){ - self::getXZ($chunkHash, $chunkX, $chunkZ); - $this->provider->saveChunk($chunkX, $chunkZ, new ChunkData( - $chunk, - array_map(fn(Entity $e) => $e->saveNBT(), $chunk->getSavableEntities()), - array_map(fn(Tile $t) => $t->saveNBT(), $chunk->getTiles()), - )); - $chunk->clearDirtyFlags(); - } + self::getXZ($chunkHash, $chunkX, $chunkZ); + $this->provider->saveChunk($chunkX, $chunkZ, new ChunkData( + $chunk, + array_map(fn(Entity $e) => $e->saveNBT(), $chunk->getSavableEntities()), + array_map(fn(Tile $t) => $t->saveNBT(), $chunk->getTiles()), + )); + $chunk->clearTerrainDirtyFlags(); } }finally{ $this->timings->syncChunkSave->stopTiming(); @@ -2186,7 +2184,7 @@ class World implements ChunkManager{ unset($this->blockCache[$chunkHash]); unset($this->changedBlocks[$chunkHash]); - $chunk->setDirty(); + $chunk->setTerrainDirty(); if(!$this->isChunkInUse($chunkX, $chunkZ)){ $this->unloadChunkRequest($chunkX, $chunkZ); @@ -2494,7 +2492,6 @@ class World implements ChunkManager{ //here, because entities currently add themselves to the world } - $this->getChunk($chunkX, $chunkZ)?->setDirtyFlag(Chunk::DIRTY_FLAG_ENTITIES, true); $this->timings->syncChunkLoadEntities->stopTiming(); } @@ -2518,7 +2515,6 @@ class World implements ChunkManager{ } } - $this->getChunk($chunkX, $chunkZ)?->setDirtyFlag(Chunk::DIRTY_FLAG_TILES, true); $this->timings->syncChunkLoadTileEntities->stopTiming(); } } @@ -2565,7 +2561,7 @@ class World implements ChunkManager{ return false; } - if($trySave and $this->getAutoSave() and $chunk->isDirty()){ + if($trySave and $this->getAutoSave()){ $this->timings->syncChunkSave->startTiming(); try{ $this->provider->saveChunk($x, $z, new ChunkData( diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 551b37cb7d..839f7854b8 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -35,18 +35,15 @@ use pocketmine\player\Player; use function array_fill; use function array_filter; use function array_map; -use function count; class Chunk{ public const DIRTY_FLAG_TERRAIN = 1 << 0; - public const DIRTY_FLAG_ENTITIES = 1 << 1; - public const DIRTY_FLAG_TILES = 1 << 2; public const DIRTY_FLAG_BIOMES = 1 << 3; public const MAX_SUBCHUNKS = 16; /** @var int */ - private $dirtyFlags = 0; + private $terrainDirtyFlags = 0; /** @var bool|null */ protected $lightPopulated = false; @@ -111,7 +108,7 @@ class Chunk{ */ public function setFullBlock(int $x, int $y, int $z, int $block) : void{ $this->getSubChunk($y >> 4)->setFullBlock($x, $y & 0xf, $z, $block); - $this->dirtyFlags |= self::DIRTY_FLAG_TERRAIN; + $this->terrainDirtyFlags |= self::DIRTY_FLAG_TERRAIN; } /** @@ -174,7 +171,7 @@ class Chunk{ */ public function setBiomeId(int $x, int $z, int $biomeId) : void{ $this->biomeIds->set($x, $z, $biomeId); - $this->dirtyFlags |= self::DIRTY_FLAG_BIOMES; + $this->terrainDirtyFlags |= self::DIRTY_FLAG_BIOMES; } public function isLightPopulated() : ?bool{ @@ -191,7 +188,7 @@ class Chunk{ public function setPopulated(bool $value = true) : void{ $this->terrainPopulated = $value; - $this->dirtyFlags |= self::DIRTY_FLAG_TERRAIN; + $this->terrainDirtyFlags |= self::DIRTY_FLAG_TERRAIN; } public function addEntity(Entity $entity) : void{ @@ -199,16 +196,10 @@ class Chunk{ throw new \InvalidArgumentException("Attempted to add a garbage closed Entity to a chunk"); } $this->entities[$entity->getId()] = $entity; - if(!($entity instanceof Player)){ - $this->dirtyFlags |= self::DIRTY_FLAG_ENTITIES; - } } public function removeEntity(Entity $entity) : void{ unset($this->entities[$entity->getId()]); - if(!($entity instanceof Player)){ - $this->dirtyFlags |= self::DIRTY_FLAG_ENTITIES; - } } public function addTile(Tile $tile) : void{ @@ -221,13 +212,11 @@ class Chunk{ throw new \InvalidArgumentException("Another tile is already at this location"); } $this->tiles[$index] = $tile; - $this->dirtyFlags |= self::DIRTY_FLAG_TILES; } public function removeTile(Tile $tile) : void{ $pos = $tile->getPosition(); unset($this->tiles[Chunk::blockHash($pos->x, $pos->y, $pos->z)]); - $this->dirtyFlags |= self::DIRTY_FLAG_TILES; } /** @@ -298,32 +287,32 @@ class Chunk{ $this->heightMap = new HeightArray($values); } - public function isDirty() : bool{ - return $this->dirtyFlags !== 0 or count($this->tiles) > 0 or count($this->getSavableEntities()) > 0; + public function isTerrainDirty() : bool{ + return $this->terrainDirtyFlags !== 0; } - public function getDirtyFlag(int $flag) : bool{ - return ($this->dirtyFlags & $flag) !== 0; + public function getTerrainDirtyFlag(int $flag) : bool{ + return ($this->terrainDirtyFlags & $flag) !== 0; } - public function getDirtyFlags() : int{ - return $this->dirtyFlags; + public function getTerrainDirtyFlags() : int{ + return $this->terrainDirtyFlags; } - public function setDirtyFlag(int $flag, bool $value) : void{ + public function setTerrainDirtyFlag(int $flag, bool $value) : void{ if($value){ - $this->dirtyFlags |= $flag; + $this->terrainDirtyFlags |= $flag; }else{ - $this->dirtyFlags &= ~$flag; + $this->terrainDirtyFlags &= ~$flag; } } - public function setDirty() : void{ - $this->dirtyFlags = ~0; + public function setTerrainDirty() : void{ + $this->terrainDirtyFlags = ~0; } - public function clearDirtyFlags() : void{ - $this->dirtyFlags = 0; + public function clearTerrainDirtyFlags() : void{ + $this->terrainDirtyFlags = 0; } public function getSubChunk(int $y) : SubChunk{ @@ -342,7 +331,7 @@ class Chunk{ } $this->subChunks[$y] = $subChunk ?? new SubChunk(BlockLegacyIds::AIR << Block::INTERNAL_METADATA_BITS, []); - $this->setDirtyFlag(self::DIRTY_FLAG_TERRAIN, true); + $this->setTerrainDirtyFlag(self::DIRTY_FLAG_TERRAIN, true); } /** diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index 8dcdb10e77..ca6d4ea50f 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -146,7 +146,7 @@ final class FastChunkSerializer{ $chunk = new Chunk($subChunks, $biomeIds, $heightMap); $chunk->setPopulated($terrainPopulated); $chunk->setLightPopulated($lightPopulated); - $chunk->clearDirtyFlags(); + $chunk->clearTerrainDirtyFlags(); return $chunk; } diff --git a/src/world/format/io/FormatConverter.php b/src/world/format/io/FormatConverter.php index 1ad50ccc86..5ee6ea3a8f 100644 --- a/src/world/format/io/FormatConverter.php +++ b/src/world/format/io/FormatConverter.php @@ -149,7 +149,7 @@ class FormatConverter{ $thisRound = $start; foreach($this->oldProvider->getAllChunks(true, $this->logger) as $coords => $chunk){ [$chunkX, $chunkZ] = $coords; - $chunk->getChunk()->setDirty(); + $chunk->getChunk()->setTerrainDirty(); $new->saveChunk($chunkX, $chunkZ, $chunk); $counter++; if(($counter % $this->chunksPerProgressUpdate) === 0){ diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 5064141de8..92beecc2ad 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -419,7 +419,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $chunk->setPopulated(); } if($hasBeenUpgraded){ - $chunk->setDirty(); //trigger rewriting chunk to disk if it was converted from an older format + $chunk->setTerrainDirty(); //trigger rewriting chunk to disk if it was converted from an older format } return new ChunkData($chunk, $entities, $tiles); @@ -433,7 +433,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $write->put($index . self::TAG_VERSION, chr(self::CURRENT_LEVEL_CHUNK_VERSION)); $chunk = $chunkData->getChunk(); - if($chunk->getDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN)){ + if($chunk->getTerrainDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN)){ $subChunks = $chunk->getSubChunks(); foreach($subChunks as $y => $subChunk){ $key = $index . self::TAG_SUBCHUNK_PREFIX . chr($y); @@ -467,7 +467,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ } } - if($chunk->getDirtyFlag(Chunk::DIRTY_FLAG_BIOMES)){ + if($chunk->getTerrainDirtyFlag(Chunk::DIRTY_FLAG_BIOMES)){ $write->put($index . self::TAG_DATA_2D, str_repeat("\x00", 512) . $chunk->getBiomeIdArray()); } diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 5291a957ab..12d921d45f 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -106,8 +106,8 @@ class PopulationTask extends AsyncTask{ if($chunk === null){ $generator->generateChunk($manager, $this->chunkX, $this->chunkZ); $chunk = $manager->getChunk($this->chunkX, $this->chunkZ); - $chunk->setDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN, true); - $chunk->setDirtyFlag(Chunk::DIRTY_FLAG_BIOMES, true); + $chunk->setTerrainDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN, true); + $chunk->setTerrainDirtyFlag(Chunk::DIRTY_FLAG_BIOMES, true); } foreach($chunks as $i => $c){ @@ -117,8 +117,8 @@ class PopulationTask extends AsyncTask{ if($c === null){ $generator->generateChunk($manager, $cX, $cZ); $chunks[$i] = $manager->getChunk($cX, $cZ); - $chunks[$i]->setDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN, true); - $chunks[$i]->setDirtyFlag(Chunk::DIRTY_FLAG_BIOMES, true); + $chunks[$i]->setTerrainDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN, true); + $chunks[$i]->setTerrainDirtyFlag(Chunk::DIRTY_FLAG_BIOMES, true); } } @@ -129,7 +129,7 @@ class PopulationTask extends AsyncTask{ $this->chunk = FastChunkSerializer::serializeWithoutLight($chunk); foreach($chunks as $i => $c){ - $this->{"chunk$i"} = $c->isDirty() ? FastChunkSerializer::serializeWithoutLight($c) : null; + $this->{"chunk$i"} = $c->isTerrainDirty() ? FastChunkSerializer::serializeWithoutLight($c) : null; } } From e0d6357eb7bdeae086816f6269a66e5b133cdecd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 30 Aug 2021 00:18:34 +0100 Subject: [PATCH 2770/3224] OreType: use promoted constructo properties --- src/world/generator/object/OreType.php | 29 +++++++------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/src/world/generator/object/OreType.php b/src/world/generator/object/OreType.php index e9ea680c71..96c46b8d7b 100644 --- a/src/world/generator/object/OreType.php +++ b/src/world/generator/object/OreType.php @@ -26,25 +26,12 @@ namespace pocketmine\world\generator\object; use pocketmine\block\Block; class OreType{ - /** @var Block */ - public $material; - /** @var Block */ - public $replaces; - /** @var int */ - public $clusterCount; - /** @var int */ - public $clusterSize; - /** @var int */ - public $maxHeight; - /** @var int */ - public $minHeight; - - public function __construct(Block $material, Block $replaces, int $clusterCount, int $clusterSize, int $minHeight, int $maxHeight){ - $this->material = $material; - $this->replaces = $replaces; - $this->clusterCount = $clusterCount; - $this->clusterSize = $clusterSize; - $this->maxHeight = $maxHeight; - $this->minHeight = $minHeight; - } + public function __construct( + public Block $material, + public Block $replaces, + public int $clusterCount, + public int $clusterSize, + public int $minHeight, + public int $maxHeight + ){} } From 2fe03757d503a8f05783cfe3e5b895ed9a7bed9a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 30 Aug 2021 00:26:54 +0100 Subject: [PATCH 2771/3224] PopulationTask: fixed PHPStan errors --- src/world/generator/PopulationTask.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 12d921d45f..87222664ec 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -106,21 +106,30 @@ class PopulationTask extends AsyncTask{ if($chunk === null){ $generator->generateChunk($manager, $this->chunkX, $this->chunkZ); $chunk = $manager->getChunk($this->chunkX, $this->chunkZ); + if($chunk === null){ + throw new AssumptionFailedError("We just set this chunk, so it must exist"); + } $chunk->setTerrainDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN, true); $chunk->setTerrainDirtyFlag(Chunk::DIRTY_FLAG_BIOMES, true); } + $resultChunks = []; //this is just to keep phpstan's type inference happy foreach($chunks as $i => $c){ $cX = (-1 + $i % 3) + $this->chunkX; $cZ = (-1 + intdiv($i, 3)) + $this->chunkZ; $manager->setChunk($cX, $cZ, $c ?? new Chunk()); if($c === null){ $generator->generateChunk($manager, $cX, $cZ); - $chunks[$i] = $manager->getChunk($cX, $cZ); - $chunks[$i]->setTerrainDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN, true); - $chunks[$i]->setTerrainDirtyFlag(Chunk::DIRTY_FLAG_BIOMES, true); + $c = $manager->getChunk($cX, $cZ); + if($c === null){ + throw new AssumptionFailedError("We just set this chunk, so it must exist"); + } + $c->setTerrainDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN, true); + $c->setTerrainDirtyFlag(Chunk::DIRTY_FLAG_BIOMES, true); } + $resultChunks[$i] = $c; } + $chunks = $resultChunks; $generator->populateChunk($manager, $this->chunkX, $this->chunkZ); $chunk = $manager->getChunk($this->chunkX, $this->chunkZ); From 963f4a9cf326d6fdb067effeefe54bbb3d9108d6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 3 Sep 2021 12:16:07 +0100 Subject: [PATCH 2772/3224] Added constant slot IDs for Furnace, Enchanting, Anvil and Brewing Stand inventories --- src/block/inventory/BrewingStandInventory.php | 6 ++++++ src/block/inventory/EnchantInventory.php | 3 +++ src/block/inventory/FurnaceInventory.php | 16 ++++++++++------ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/block/inventory/BrewingStandInventory.php b/src/block/inventory/BrewingStandInventory.php index d171b59053..0faf4b672f 100644 --- a/src/block/inventory/BrewingStandInventory.php +++ b/src/block/inventory/BrewingStandInventory.php @@ -29,6 +29,12 @@ use pocketmine\world\Position; class BrewingStandInventory extends SimpleInventory implements BlockInventory{ use BlockInventoryTrait; + public const SLOT_INGREDIENT = 0; + public const SLOT_BOTTLE_LEFT = 1; + public const SLOT_BOTTLE_MIDDLE = 2; + public const SLOT_BOTTLE_RIGHT = 3; + public const SLOT_FUEL = 4; + public function __construct(Position $holder, int $size = 5){ $this->holder = $holder; parent::__construct($size); diff --git a/src/block/inventory/EnchantInventory.php b/src/block/inventory/EnchantInventory.php index 9bd72da27b..aafc90caf0 100644 --- a/src/block/inventory/EnchantInventory.php +++ b/src/block/inventory/EnchantInventory.php @@ -30,6 +30,9 @@ use pocketmine\world\Position; class EnchantInventory extends SimpleInventory implements BlockInventory{ use BlockInventoryTrait; + public const SLOT_INPUT = 0; + public const SLOT_LAPIS = 1; + public function __construct(Position $holder){ $this->holder = $holder; parent::__construct(2); diff --git a/src/block/inventory/FurnaceInventory.php b/src/block/inventory/FurnaceInventory.php index bece0b61c7..5f3a685eab 100644 --- a/src/block/inventory/FurnaceInventory.php +++ b/src/block/inventory/FurnaceInventory.php @@ -31,6 +31,10 @@ use pocketmine\world\Position; class FurnaceInventory extends SimpleInventory implements BlockInventory{ use BlockInventoryTrait; + public const SLOT_INPUT = 0; + public const SLOT_FUEL = 1; + public const SLOT_RESULT = 2; + private FurnaceType $furnaceType; public function __construct(Position $holder, FurnaceType $furnaceType){ @@ -42,26 +46,26 @@ class FurnaceInventory extends SimpleInventory implements BlockInventory{ public function getFurnaceType() : FurnaceType{ return $this->furnaceType; } public function getResult() : Item{ - return $this->getItem(2); + return $this->getItem(self::SLOT_RESULT); } public function getFuel() : Item{ - return $this->getItem(1); + return $this->getItem(self::SLOT_FUEL); } public function getSmelting() : Item{ - return $this->getItem(0); + return $this->getItem(self::SLOT_INPUT); } public function setResult(Item $item) : void{ - $this->setItem(2, $item); + $this->setItem(self::SLOT_RESULT, $item); } public function setFuel(Item $item) : void{ - $this->setItem(1, $item); + $this->setItem(self::SLOT_FUEL, $item); } public function setSmelting(Item $item) : void{ - $this->setItem(0, $item); + $this->setItem(self::SLOT_INPUT, $item); } } From 2e153624adec62e8bfb6784ac1488c5c2039671e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 3 Sep 2021 12:44:41 +0100 Subject: [PATCH 2773/3224] Anvil: actually add slot constants, this time --- src/block/inventory/AnvilInventory.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/block/inventory/AnvilInventory.php b/src/block/inventory/AnvilInventory.php index 18a455863e..2e875d3ffd 100644 --- a/src/block/inventory/AnvilInventory.php +++ b/src/block/inventory/AnvilInventory.php @@ -30,6 +30,9 @@ use pocketmine\world\Position; class AnvilInventory extends SimpleInventory implements BlockInventory{ use BlockInventoryTrait; + public const SLOT_INPUT = 0; + public const SLOT_MATERIAL = 1; + public function __construct(Position $holder){ $this->holder = $holder; parent::__construct(2); From 078347b44a6ae61f58941d45645383759850a6f9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 3 Sep 2021 20:26:58 +0100 Subject: [PATCH 2774/3224] MemoryManager: fixed a PHPStan error --- src/MemoryManager.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/MemoryManager.php b/src/MemoryManager.php index 09f0c889c7..dbcd800927 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -47,6 +47,7 @@ use function get_declared_classes; use function get_defined_functions; use function ini_get; use function ini_set; +use function intdiv; use function is_array; use function is_object; use function is_resource; @@ -115,7 +116,7 @@ class MemoryManager{ }else{ switch(mb_strtoupper($matches[2])){ case "K": - $defaultMemory = $m / 1024; + $defaultMemory = intdiv($m, 1024); break; case "M": $defaultMemory = $m; From 8e58beef7f210df12e0acbd6b274655ff6b35fa1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 3 Sep 2021 20:32:13 +0100 Subject: [PATCH 2775/3224] Effect: use promoted properties --- src/entity/effect/Effect.php | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/src/entity/effect/Effect.php b/src/entity/effect/Effect.php index 277b16972d..c6d1c6e43f 100644 --- a/src/entity/effect/Effect.php +++ b/src/entity/effect/Effect.php @@ -29,31 +29,20 @@ use pocketmine\entity\Living; class Effect{ - /** @var int */ - protected $internalRuntimeId; - /** @var string */ - protected $name; - /** @var Color */ - protected $color; - /** @var bool */ - protected $bad; - /** @var bool */ - protected $hasBubbles; - /** * @param int $internalRuntimeId Internal runtime ID, unique to this effect type. Used for comparisons. * @param string $name Translation key used for effect name * @param Color $color Color of bubbles given by this effect - * @param bool $isBad Whether the effect is harmful + * @param bool $bad Whether the effect is harmful * @param bool $hasBubbles Whether the effect has potion bubbles. Some do not (e.g. Instant Damage has its own particles instead of bubbles) */ - public function __construct(int $internalRuntimeId, string $name, Color $color, bool $isBad = false, bool $hasBubbles = true){ - $this->internalRuntimeId = $internalRuntimeId; - $this->name = $name; - $this->color = $color; - $this->bad = $isBad; - $this->hasBubbles = $hasBubbles; - } + public function __construct( + protected int $internalRuntimeId, + protected string $name, + protected Color $color, + protected bool $bad = false, + protected bool $hasBubbles = true + ){} /** * Returns a unique identifier for this effect type From 665f2473e1f3d693a6012f6d0420bf8c0551c696 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 3 Sep 2021 20:39:02 +0100 Subject: [PATCH 2776/3224] Effect: stop using hardcoded translation keys for names --- src/entity/effect/Effect.php | 15 ++++---- src/entity/effect/PoisonEffect.php | 3 +- src/entity/effect/VanillaEffects.php | 53 ++++++++++++++-------------- 3 files changed, 37 insertions(+), 34 deletions(-) diff --git a/src/entity/effect/Effect.php b/src/entity/effect/Effect.php index c6d1c6e43f..02ac6dc135 100644 --- a/src/entity/effect/Effect.php +++ b/src/entity/effect/Effect.php @@ -26,19 +26,20 @@ namespace pocketmine\entity\effect; use pocketmine\color\Color; use pocketmine\entity\Entity; use pocketmine\entity\Living; +use pocketmine\lang\Translatable; class Effect{ /** - * @param int $internalRuntimeId Internal runtime ID, unique to this effect type. Used for comparisons. - * @param string $name Translation key used for effect name - * @param Color $color Color of bubbles given by this effect - * @param bool $bad Whether the effect is harmful - * @param bool $hasBubbles Whether the effect has potion bubbles. Some do not (e.g. Instant Damage has its own particles instead of bubbles) + * @param int $internalRuntimeId Internal runtime ID, unique to this effect type. Used for comparisons. + * @param Translatable|string $name Translation key used for effect name + * @param Color $color Color of bubbles given by this effect + * @param bool $bad Whether the effect is harmful + * @param bool $hasBubbles Whether the effect has potion bubbles. Some do not (e.g. Instant Damage has its own particles instead of bubbles) */ public function __construct( protected int $internalRuntimeId, - protected string $name, + protected Translatable|string $name, protected Color $color, protected bool $bad = false, protected bool $hasBubbles = true @@ -55,7 +56,7 @@ class Effect{ /** * Returns the translation key used to translate this effect's name. */ - public function getName() : string{ + public function getName() : Translatable|string{ return $this->name; } diff --git a/src/entity/effect/PoisonEffect.php b/src/entity/effect/PoisonEffect.php index e55da697ce..61442159ed 100644 --- a/src/entity/effect/PoisonEffect.php +++ b/src/entity/effect/PoisonEffect.php @@ -27,13 +27,14 @@ use pocketmine\color\Color; use pocketmine\entity\Entity; use pocketmine\entity\Living; use pocketmine\event\entity\EntityDamageEvent; +use pocketmine\lang\Translatable; class PoisonEffect extends Effect{ /** @var bool */ private $fatal; - public function __construct(int $internalRuntimeId, string $name, Color $color, bool $isBad = false, bool $hasBubbles = true, bool $fatal = false){ + public function __construct(int $internalRuntimeId, Translatable $name, Color $color, bool $isBad = false, bool $hasBubbles = true, bool $fatal = false){ parent::__construct($internalRuntimeId, $name, $color, $isBad, $hasBubbles); $this->fatal = $fatal; } diff --git a/src/entity/effect/VanillaEffects.php b/src/entity/effect/VanillaEffects.php index db5d28fffd..4145b5f9d9 100644 --- a/src/entity/effect/VanillaEffects.php +++ b/src/entity/effect/VanillaEffects.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\entity\effect; use pocketmine\color\Color; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\utils\RegistryTrait; use function assert; @@ -64,35 +65,35 @@ final class VanillaEffects{ use RegistryTrait; protected static function setup() : void{ - self::register("absorption", new AbsorptionEffect(22, "%potion.absorption", new Color(0x25, 0x52, 0xa5))); + self::register("absorption", new AbsorptionEffect(22, KnownTranslationFactory::potion_absorption(), new Color(0x25, 0x52, 0xa5))); //TODO: bad_omen - self::register("blindness", new Effect(15, "%potion.blindness", new Color(0x1f, 0x1f, 0x23), true)); - self::register("conduit_power", new Effect(26, "%potion.conduitPower", new Color(0x1d, 0xc2, 0xd1))); - self::register("fatal_poison", new PoisonEffect(25, "%potion.poison", new Color(0x4e, 0x93, 0x31), true, true, true)); - self::register("fire_resistance", new Effect(12, "%potion.fireResistance", new Color(0xe4, 0x9a, 0x3a))); - self::register("haste", new Effect(3, "%potion.digSpeed", new Color(0xd9, 0xc0, 0x43))); - self::register("health_boost", new HealthBoostEffect(21, "%potion.healthBoost", new Color(0xf8, 0x7d, 0x23))); - self::register("hunger", new HungerEffect(17, "%potion.hunger", new Color(0x58, 0x76, 0x53), true)); - self::register("instant_damage", new InstantDamageEffect(7, "%potion.harm", new Color(0x43, 0x0a, 0x09), true, false)); - self::register("instant_health", new InstantHealthEffect(6, "%potion.heal", new Color(0xf8, 0x24, 0x23), false, false)); - self::register("invisibility", new InvisibilityEffect(14, "%potion.invisibility", new Color(0x7f, 0x83, 0x92))); - self::register("jump_boost", new Effect(8, "%potion.jump", new Color(0x22, 0xff, 0x4c))); - self::register("levitation", new LevitationEffect(24, "%potion.levitation", new Color(0xce, 0xff, 0xff))); - self::register("mining_fatigue", new Effect(4, "%potion.digSlowDown", new Color(0x4a, 0x42, 0x17), true)); - self::register("nausea", new Effect(9, "%potion.confusion", new Color(0x55, 0x1d, 0x4a), true)); - self::register("night_vision", new Effect(16, "%potion.nightVision", new Color(0x1f, 0x1f, 0xa1))); - self::register("poison", new PoisonEffect(19, "%potion.poison", new Color(0x4e, 0x93, 0x31), true)); - self::register("regeneration", new RegenerationEffect(10, "%potion.regeneration", new Color(0xcd, 0x5c, 0xab))); - self::register("resistance", new Effect(11, "%potion.resistance", new Color(0x99, 0x45, 0x3a))); - self::register("saturation", new SaturationEffect(23, "%potion.saturation", new Color(0xf8, 0x24, 0x23), false)); + self::register("blindness", new Effect(15, KnownTranslationFactory::potion_blindness(), new Color(0x1f, 0x1f, 0x23), true)); + self::register("conduit_power", new Effect(26, KnownTranslationFactory::potion_conduitPower(), new Color(0x1d, 0xc2, 0xd1))); + self::register("fatal_poison", new PoisonEffect(25, KnownTranslationFactory::potion_poison(), new Color(0x4e, 0x93, 0x31), true, true, true)); + self::register("fire_resistance", new Effect(12, KnownTranslationFactory::potion_fireResistance(), new Color(0xe4, 0x9a, 0x3a))); + self::register("haste", new Effect(3, KnownTranslationFactory::potion_digSpeed(), new Color(0xd9, 0xc0, 0x43))); + self::register("health_boost", new HealthBoostEffect(21, KnownTranslationFactory::potion_healthBoost(), new Color(0xf8, 0x7d, 0x23))); + self::register("hunger", new HungerEffect(17, KnownTranslationFactory::potion_hunger(), new Color(0x58, 0x76, 0x53), true)); + self::register("instant_damage", new InstantDamageEffect(7, KnownTranslationFactory::potion_harm(), new Color(0x43, 0x0a, 0x09), true, false)); + self::register("instant_health", new InstantHealthEffect(6, KnownTranslationFactory::potion_heal(), new Color(0xf8, 0x24, 0x23), false, false)); + self::register("invisibility", new InvisibilityEffect(14, KnownTranslationFactory::potion_invisibility(), new Color(0x7f, 0x83, 0x92))); + self::register("jump_boost", new Effect(8, KnownTranslationFactory::potion_jump(), new Color(0x22, 0xff, 0x4c))); + self::register("levitation", new LevitationEffect(24, KnownTranslationFactory::potion_levitation(), new Color(0xce, 0xff, 0xff))); + self::register("mining_fatigue", new Effect(4, KnownTranslationFactory::potion_digSlowDown(), new Color(0x4a, 0x42, 0x17), true)); + self::register("nausea", new Effect(9, KnownTranslationFactory::potion_confusion(), new Color(0x55, 0x1d, 0x4a), true)); + self::register("night_vision", new Effect(16, KnownTranslationFactory::potion_nightVision(), new Color(0x1f, 0x1f, 0xa1))); + self::register("poison", new PoisonEffect(19, KnownTranslationFactory::potion_poison(), new Color(0x4e, 0x93, 0x31), true)); + self::register("regeneration", new RegenerationEffect(10, KnownTranslationFactory::potion_regeneration(), new Color(0xcd, 0x5c, 0xab))); + self::register("resistance", new Effect(11, KnownTranslationFactory::potion_resistance(), new Color(0x99, 0x45, 0x3a))); + self::register("saturation", new SaturationEffect(23, KnownTranslationFactory::potion_saturation(), new Color(0xf8, 0x24, 0x23), false)); //TODO: slow_falling - self::register("slowness", new SlownessEffect(2, "%potion.moveSlowdown", new Color(0x5a, 0x6c, 0x81), true)); - self::register("speed", new SpeedEffect(1, "%potion.moveSpeed", new Color(0x7c, 0xaf, 0xc6))); - self::register("strength", new Effect(5, "%potion.damageBoost", new Color(0x93, 0x24, 0x23))); + self::register("slowness", new SlownessEffect(2, KnownTranslationFactory::potion_moveSlowdown(), new Color(0x5a, 0x6c, 0x81), true)); + self::register("speed", new SpeedEffect(1, KnownTranslationFactory::potion_moveSpeed(), new Color(0x7c, 0xaf, 0xc6))); + self::register("strength", new Effect(5, KnownTranslationFactory::potion_damageBoost(), new Color(0x93, 0x24, 0x23))); //TODO: village_hero - self::register("water_breathing", new Effect(13, "%potion.waterBreathing", new Color(0x2e, 0x52, 0x99))); - self::register("weakness", new Effect(18, "%potion.weakness", new Color(0x48, 0x4d, 0x48), true)); - self::register("wither", new WitherEffect(20, "%potion.wither", new Color(0x35, 0x2a, 0x27), true)); + self::register("water_breathing", new Effect(13, KnownTranslationFactory::potion_waterBreathing(), new Color(0x2e, 0x52, 0x99))); + self::register("weakness", new Effect(18, KnownTranslationFactory::potion_weakness(), new Color(0x48, 0x4d, 0x48), true)); + self::register("wither", new WitherEffect(20, KnownTranslationFactory::potion_wither(), new Color(0x35, 0x2a, 0x27), true)); } protected static function register(string $name, Effect $member) : void{ From fbbaef440100c4c79eafc055df91a8e686616811 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 3 Sep 2021 20:41:43 +0100 Subject: [PATCH 2777/3224] Enchantment: use promoted properties --- src/item/enchantment/Enchantment.php | 29 ++++++++-------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/src/item/enchantment/Enchantment.php b/src/item/enchantment/Enchantment.php index c4081af967..9c80914a8a 100644 --- a/src/item/enchantment/Enchantment.php +++ b/src/item/enchantment/Enchantment.php @@ -30,27 +30,14 @@ use function constant; */ class Enchantment{ - /** @var int */ - private $internalRuntimeId; - /** @var string */ - private $name; - /** @var int */ - private $rarity; - /** @var int */ - private $primaryItemFlags; - /** @var int */ - private $secondaryItemFlags; - /** @var int */ - private $maxLevel; - - public function __construct(int $internalRuntimeId, string $name, int $rarity, int $primaryItemFlags, int $secondaryItemFlags, int $maxLevel){ - $this->internalRuntimeId = $internalRuntimeId; - $this->name = $name; - $this->rarity = $rarity; - $this->primaryItemFlags = $primaryItemFlags; - $this->secondaryItemFlags = $secondaryItemFlags; - $this->maxLevel = $maxLevel; - } + public function __construct( + private int $internalRuntimeId, + private string $name, + private int $rarity, + private int $primaryItemFlags, + private int $secondaryItemFlags, + private int $maxLevel + ){} /** * Returns the internal runtime ID of this enchantment. From aa5a9f6d12910299378dc492dc36ee652d7d4efc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 3 Sep 2021 20:52:05 +0100 Subject: [PATCH 2778/3224] Enchantment: use Translatable instead of hardcoded translation keys --- resources/locale | 2 +- src/item/enchantment/Enchantment.php | 5 +- .../enchantment/ProtectionEnchantment.php | 3 +- src/item/enchantment/VanillaEnchantments.php | 39 ++--- src/lang/KnownTranslationFactory.php | 148 ++++++++++++++++++ src/lang/KnownTranslationKeys.php | 37 +++++ tests/phpunit/item/ItemTest.php | 2 +- 7 files changed, 212 insertions(+), 24 deletions(-) diff --git a/resources/locale b/resources/locale index 558e260fc5..95b9c82f25 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 558e260fc5bfee5f0de8ce701be93eeac184f454 +Subproject commit 95b9c82f25f2d216683769c326c06c88706ce3cc diff --git a/src/item/enchantment/Enchantment.php b/src/item/enchantment/Enchantment.php index 9c80914a8a..a44a25b484 100644 --- a/src/item/enchantment/Enchantment.php +++ b/src/item/enchantment/Enchantment.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\item\enchantment; +use pocketmine\lang\Translatable; use function constant; /** @@ -32,7 +33,7 @@ class Enchantment{ public function __construct( private int $internalRuntimeId, - private string $name, + private Translatable|string $name, private int $rarity, private int $primaryItemFlags, private int $secondaryItemFlags, @@ -50,7 +51,7 @@ class Enchantment{ /** * Returns a translation key for this enchantment's name. */ - public function getName() : string{ + public function getName() : Translatable|string{ return $this->name; } diff --git a/src/item/enchantment/ProtectionEnchantment.php b/src/item/enchantment/ProtectionEnchantment.php index 141678b07c..debf620292 100644 --- a/src/item/enchantment/ProtectionEnchantment.php +++ b/src/item/enchantment/ProtectionEnchantment.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\item\enchantment; use pocketmine\event\entity\EntityDamageEvent; +use pocketmine\lang\Translatable; use function array_flip; use function floor; @@ -38,7 +39,7 @@ class ProtectionEnchantment extends Enchantment{ * * @param int[]|null $applicableDamageTypes EntityDamageEvent::CAUSE_* constants which this enchantment type applies to, or null if it applies to all types of damage. */ - public function __construct(int $internalRuntimeId, string $name, int $rarity, int $primaryItemFlags, int $secondaryItemFlags, int $maxLevel, float $typeModifier, ?array $applicableDamageTypes){ + public function __construct(int $internalRuntimeId, Translatable|string $name, int $rarity, int $primaryItemFlags, int $secondaryItemFlags, int $maxLevel, float $typeModifier, ?array $applicableDamageTypes){ parent::__construct($internalRuntimeId, $name, $rarity, $primaryItemFlags, $secondaryItemFlags, $maxLevel); $this->typeModifier = $typeModifier; diff --git a/src/item/enchantment/VanillaEnchantments.php b/src/item/enchantment/VanillaEnchantments.php index 8ff97770a4..bef5c250c3 100644 --- a/src/item/enchantment/VanillaEnchantments.php +++ b/src/item/enchantment/VanillaEnchantments.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\item\enchantment; use pocketmine\event\entity\EntityDamageEvent; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\utils\RegistryTrait; /** @@ -64,44 +65,44 @@ final class VanillaEnchantments{ } protected static function setup() : void{ - self::register("PROTECTION", new ProtectionEnchantment(self::newRtId(), "%enchantment.protect.all", Rarity::COMMON, ItemFlags::ARMOR, ItemFlags::NONE, 4, 0.75, null)); - self::register("FIRE_PROTECTION", new ProtectionEnchantment(self::newRtId(), "%enchantment.protect.fire", Rarity::UNCOMMON, ItemFlags::ARMOR, ItemFlags::NONE, 4, 1.25, [ + self::register("PROTECTION", new ProtectionEnchantment(self::newRtId(), KnownTranslationFactory::enchantment_protect_all(), Rarity::COMMON, ItemFlags::ARMOR, ItemFlags::NONE, 4, 0.75, null)); + self::register("FIRE_PROTECTION", new ProtectionEnchantment(self::newRtId(), KnownTranslationFactory::enchantment_protect_fire(), Rarity::UNCOMMON, ItemFlags::ARMOR, ItemFlags::NONE, 4, 1.25, [ EntityDamageEvent::CAUSE_FIRE, EntityDamageEvent::CAUSE_FIRE_TICK, EntityDamageEvent::CAUSE_LAVA //TODO: check fireballs ])); - self::register("FEATHER_FALLING", new ProtectionEnchantment(self::newRtId(), "%enchantment.protect.fall", Rarity::UNCOMMON, ItemFlags::FEET, ItemFlags::NONE, 4, 2.5, [ + self::register("FEATHER_FALLING", new ProtectionEnchantment(self::newRtId(), KnownTranslationFactory::enchantment_protect_fall(), Rarity::UNCOMMON, ItemFlags::FEET, ItemFlags::NONE, 4, 2.5, [ EntityDamageEvent::CAUSE_FALL ])); - self::register("BLAST_PROTECTION", new ProtectionEnchantment(self::newRtId(), "%enchantment.protect.explosion", Rarity::RARE, ItemFlags::ARMOR, ItemFlags::NONE, 4, 1.5, [ + self::register("BLAST_PROTECTION", new ProtectionEnchantment(self::newRtId(), KnownTranslationFactory::enchantment_protect_explosion(), Rarity::RARE, ItemFlags::ARMOR, ItemFlags::NONE, 4, 1.5, [ EntityDamageEvent::CAUSE_BLOCK_EXPLOSION, EntityDamageEvent::CAUSE_ENTITY_EXPLOSION ])); - self::register("PROJECTILE_PROTECTION", new ProtectionEnchantment(self::newRtId(), "%enchantment.protect.projectile", Rarity::UNCOMMON, ItemFlags::ARMOR, ItemFlags::NONE, 4, 1.5, [ + self::register("PROJECTILE_PROTECTION", new ProtectionEnchantment(self::newRtId(), KnownTranslationFactory::enchantment_protect_projectile(), Rarity::UNCOMMON, ItemFlags::ARMOR, ItemFlags::NONE, 4, 1.5, [ EntityDamageEvent::CAUSE_PROJECTILE ])); - self::register("THORNS", new Enchantment(self::newRtId(), "%enchantment.thorns", Rarity::MYTHIC, ItemFlags::TORSO, ItemFlags::HEAD | ItemFlags::LEGS | ItemFlags::FEET, 3)); - self::register("RESPIRATION", new Enchantment(self::newRtId(), "%enchantment.oxygen", Rarity::RARE, ItemFlags::HEAD, ItemFlags::NONE, 3)); + self::register("THORNS", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_thorns(), Rarity::MYTHIC, ItemFlags::TORSO, ItemFlags::HEAD | ItemFlags::LEGS | ItemFlags::FEET, 3)); + self::register("RESPIRATION", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_oxygen(), Rarity::RARE, ItemFlags::HEAD, ItemFlags::NONE, 3)); - self::register("SHARPNESS", new SharpnessEnchantment(self::newRtId(), "%enchantment.damage.all", Rarity::COMMON, ItemFlags::SWORD, ItemFlags::AXE, 5)); + self::register("SHARPNESS", new SharpnessEnchantment(self::newRtId(), KnownTranslationFactory::enchantment_damage_all(), Rarity::COMMON, ItemFlags::SWORD, ItemFlags::AXE, 5)); //TODO: smite, bane of arthropods (these don't make sense now because their applicable mobs don't exist yet) - self::register("KNOCKBACK", new KnockbackEnchantment(self::newRtId(), "%enchantment.knockback", Rarity::UNCOMMON, ItemFlags::SWORD, ItemFlags::NONE, 2)); - self::register("FIRE_ASPECT", new FireAspectEnchantment(self::newRtId(), "%enchantment.fire", Rarity::RARE, ItemFlags::SWORD, ItemFlags::NONE, 2)); + self::register("KNOCKBACK", new KnockbackEnchantment(self::newRtId(), KnownTranslationFactory::enchantment_knockback(), Rarity::UNCOMMON, ItemFlags::SWORD, ItemFlags::NONE, 2)); + self::register("FIRE_ASPECT", new FireAspectEnchantment(self::newRtId(), KnownTranslationFactory::enchantment_fire(), Rarity::RARE, ItemFlags::SWORD, ItemFlags::NONE, 2)); - self::register("EFFICIENCY", new Enchantment(self::newRtId(), "%enchantment.digging", Rarity::COMMON, ItemFlags::DIG, ItemFlags::SHEARS, 5)); - self::register("SILK_TOUCH", new Enchantment(self::newRtId(), "%enchantment.untouching", Rarity::MYTHIC, ItemFlags::DIG, ItemFlags::SHEARS, 1)); - self::register("UNBREAKING", new Enchantment(self::newRtId(), "%enchantment.durability", Rarity::UNCOMMON, ItemFlags::DIG | ItemFlags::ARMOR | ItemFlags::FISHING_ROD | ItemFlags::BOW, ItemFlags::TOOL | ItemFlags::CARROT_STICK | ItemFlags::ELYTRA, 3)); + self::register("EFFICIENCY", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_digging(), Rarity::COMMON, ItemFlags::DIG, ItemFlags::SHEARS, 5)); + self::register("SILK_TOUCH", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_untouching(), Rarity::MYTHIC, ItemFlags::DIG, ItemFlags::SHEARS, 1)); + self::register("UNBREAKING", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_durability(), Rarity::UNCOMMON, ItemFlags::DIG | ItemFlags::ARMOR | ItemFlags::FISHING_ROD | ItemFlags::BOW, ItemFlags::TOOL | ItemFlags::CARROT_STICK | ItemFlags::ELYTRA, 3)); - self::register("POWER", new Enchantment(self::newRtId(), "%enchantment.arrowDamage", Rarity::COMMON, ItemFlags::BOW, ItemFlags::NONE, 5)); - self::register("PUNCH", new Enchantment(self::newRtId(), "%enchantment.arrowKnockback", Rarity::RARE, ItemFlags::BOW, ItemFlags::NONE, 2)); - self::register("FLAME", new Enchantment(self::newRtId(), "%enchantment.arrowFire", Rarity::RARE, ItemFlags::BOW, ItemFlags::NONE, 1)); - self::register("INFINITY", new Enchantment(self::newRtId(), "%enchantment.arrowInfinite", Rarity::MYTHIC, ItemFlags::BOW, ItemFlags::NONE, 1)); + self::register("POWER", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_arrowDamage(), Rarity::COMMON, ItemFlags::BOW, ItemFlags::NONE, 5)); + self::register("PUNCH", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_arrowKnockback(), Rarity::RARE, ItemFlags::BOW, ItemFlags::NONE, 2)); + self::register("FLAME", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_arrowFire(), Rarity::RARE, ItemFlags::BOW, ItemFlags::NONE, 1)); + self::register("INFINITY", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_arrowInfinite(), Rarity::MYTHIC, ItemFlags::BOW, ItemFlags::NONE, 1)); - self::register("MENDING", new Enchantment(self::newRtId(), "%enchantment.mending", Rarity::RARE, ItemFlags::NONE, ItemFlags::ALL, 1)); + self::register("MENDING", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_mending(), Rarity::RARE, ItemFlags::NONE, ItemFlags::ALL, 1)); - self::register("VANISHING", new Enchantment(self::newRtId(), "%enchantment.curse.vanishing", Rarity::MYTHIC, ItemFlags::NONE, ItemFlags::ALL, 1)); + self::register("VANISHING", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_curse_vanishing(), Rarity::MYTHIC, ItemFlags::NONE, ItemFlags::ALL, 1)); } protected static function register(string $name, Enchantment $member) : void{ diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index e390b01a4e..96eac592cc 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -759,6 +759,154 @@ final class KnownTranslationFactory{ return new Translatable(KnownTranslationKeys::DISCONNECTIONSCREEN_SERVERFULL, []); } + public static function enchantment_arrowDamage() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_ARROWDAMAGE, []); + } + + public static function enchantment_arrowFire() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_ARROWFIRE, []); + } + + public static function enchantment_arrowInfinite() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_ARROWINFINITE, []); + } + + public static function enchantment_arrowKnockback() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_ARROWKNOCKBACK, []); + } + + public static function enchantment_crossbowMultishot() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_CROSSBOWMULTISHOT, []); + } + + public static function enchantment_crossbowPiercing() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_CROSSBOWPIERCING, []); + } + + public static function enchantment_crossbowQuickCharge() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_CROSSBOWQUICKCHARGE, []); + } + + public static function enchantment_curse_binding() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_CURSE_BINDING, []); + } + + public static function enchantment_curse_vanishing() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_CURSE_VANISHING, []); + } + + public static function enchantment_damage_all() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_DAMAGE_ALL, []); + } + + public static function enchantment_damage_arthropods() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_DAMAGE_ARTHROPODS, []); + } + + public static function enchantment_damage_undead() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_DAMAGE_UNDEAD, []); + } + + public static function enchantment_digging() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_DIGGING, []); + } + + public static function enchantment_durability() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_DURABILITY, []); + } + + public static function enchantment_fire() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_FIRE, []); + } + + public static function enchantment_fishingSpeed() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_FISHINGSPEED, []); + } + + public static function enchantment_frostwalker() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_FROSTWALKER, []); + } + + public static function enchantment_knockback() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_KNOCKBACK, []); + } + + public static function enchantment_lootBonus() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_LOOTBONUS, []); + } + + public static function enchantment_lootBonusDigger() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_LOOTBONUSDIGGER, []); + } + + public static function enchantment_lootBonusFishing() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_LOOTBONUSFISHING, []); + } + + public static function enchantment_mending() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_MENDING, []); + } + + public static function enchantment_oxygen() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_OXYGEN, []); + } + + public static function enchantment_protect_all() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_PROTECT_ALL, []); + } + + public static function enchantment_protect_explosion() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_PROTECT_EXPLOSION, []); + } + + public static function enchantment_protect_fall() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_PROTECT_FALL, []); + } + + public static function enchantment_protect_fire() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_PROTECT_FIRE, []); + } + + public static function enchantment_protect_projectile() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_PROTECT_PROJECTILE, []); + } + + public static function enchantment_soul_speed() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_SOUL_SPEED, []); + } + + public static function enchantment_thorns() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_THORNS, []); + } + + public static function enchantment_tridentChanneling() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_TRIDENTCHANNELING, []); + } + + public static function enchantment_tridentImpaling() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_TRIDENTIMPALING, []); + } + + public static function enchantment_tridentLoyalty() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_TRIDENTLOYALTY, []); + } + + public static function enchantment_tridentRiptide() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_TRIDENTRIPTIDE, []); + } + + public static function enchantment_untouching() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_UNTOUCHING, []); + } + + public static function enchantment_waterWalker() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_WATERWALKER, []); + } + + public static function enchantment_waterWorker() : Translatable{ + return new Translatable(KnownTranslationKeys::ENCHANTMENT_WATERWORKER, []); + } + public static function gameMode_adventure() : Translatable{ return new Translatable(KnownTranslationKeys::GAMEMODE_ADVENTURE, []); } diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index 1c1de33c31..3e9b90eb2a 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -163,6 +163,43 @@ final class KnownTranslationKeys{ public const DISCONNECTIONSCREEN_OUTDATEDSERVER = "disconnectionScreen.outdatedServer"; public const DISCONNECTIONSCREEN_RESOURCEPACK = "disconnectionScreen.resourcePack"; public const DISCONNECTIONSCREEN_SERVERFULL = "disconnectionScreen.serverFull"; + public const ENCHANTMENT_ARROWDAMAGE = "enchantment.arrowDamage"; + public const ENCHANTMENT_ARROWFIRE = "enchantment.arrowFire"; + public const ENCHANTMENT_ARROWINFINITE = "enchantment.arrowInfinite"; + public const ENCHANTMENT_ARROWKNOCKBACK = "enchantment.arrowKnockback"; + public const ENCHANTMENT_CROSSBOWMULTISHOT = "enchantment.crossbowMultishot"; + public const ENCHANTMENT_CROSSBOWPIERCING = "enchantment.crossbowPiercing"; + public const ENCHANTMENT_CROSSBOWQUICKCHARGE = "enchantment.crossbowQuickCharge"; + public const ENCHANTMENT_CURSE_BINDING = "enchantment.curse.binding"; + public const ENCHANTMENT_CURSE_VANISHING = "enchantment.curse.vanishing"; + public const ENCHANTMENT_DAMAGE_ALL = "enchantment.damage.all"; + public const ENCHANTMENT_DAMAGE_ARTHROPODS = "enchantment.damage.arthropods"; + public const ENCHANTMENT_DAMAGE_UNDEAD = "enchantment.damage.undead"; + public const ENCHANTMENT_DIGGING = "enchantment.digging"; + public const ENCHANTMENT_DURABILITY = "enchantment.durability"; + public const ENCHANTMENT_FIRE = "enchantment.fire"; + public const ENCHANTMENT_FISHINGSPEED = "enchantment.fishingSpeed"; + public const ENCHANTMENT_FROSTWALKER = "enchantment.frostwalker"; + public const ENCHANTMENT_KNOCKBACK = "enchantment.knockback"; + public const ENCHANTMENT_LOOTBONUS = "enchantment.lootBonus"; + public const ENCHANTMENT_LOOTBONUSDIGGER = "enchantment.lootBonusDigger"; + public const ENCHANTMENT_LOOTBONUSFISHING = "enchantment.lootBonusFishing"; + public const ENCHANTMENT_MENDING = "enchantment.mending"; + public const ENCHANTMENT_OXYGEN = "enchantment.oxygen"; + public const ENCHANTMENT_PROTECT_ALL = "enchantment.protect.all"; + public const ENCHANTMENT_PROTECT_EXPLOSION = "enchantment.protect.explosion"; + public const ENCHANTMENT_PROTECT_FALL = "enchantment.protect.fall"; + public const ENCHANTMENT_PROTECT_FIRE = "enchantment.protect.fire"; + public const ENCHANTMENT_PROTECT_PROJECTILE = "enchantment.protect.projectile"; + public const ENCHANTMENT_SOUL_SPEED = "enchantment.soul_speed"; + public const ENCHANTMENT_THORNS = "enchantment.thorns"; + public const ENCHANTMENT_TRIDENTCHANNELING = "enchantment.tridentChanneling"; + public const ENCHANTMENT_TRIDENTIMPALING = "enchantment.tridentImpaling"; + public const ENCHANTMENT_TRIDENTLOYALTY = "enchantment.tridentLoyalty"; + public const ENCHANTMENT_TRIDENTRIPTIDE = "enchantment.tridentRiptide"; + public const ENCHANTMENT_UNTOUCHING = "enchantment.untouching"; + public const ENCHANTMENT_WATERWALKER = "enchantment.waterWalker"; + public const ENCHANTMENT_WATERWORKER = "enchantment.waterWorker"; public const GAMEMODE_ADVENTURE = "gameMode.adventure"; public const GAMEMODE_CHANGED = "gameMode.changed"; public const GAMEMODE_CREATIVE = "gameMode.creative"; diff --git a/tests/phpunit/item/ItemTest.php b/tests/phpunit/item/ItemTest.php index 7c34d04ffc..846b23f5fb 100644 --- a/tests/phpunit/item/ItemTest.php +++ b/tests/phpunit/item/ItemTest.php @@ -103,7 +103,7 @@ class ItemTest extends TestCase{ continue 2; } } - self::fail("Unknown extra enchantment found: " . $enchantment->getType()->getName() . " x" . $enchantment->getLevel()); + self::fail("Unknown extra enchantment found"); } self::assertEmpty($enchantments, "Expected all enchantments to be present"); } From b026ada489dda4db7eb7e2708bf6ddccf9e88c1a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 3 Sep 2021 21:07:10 +0100 Subject: [PATCH 2779/3224] Standardize serialize denying --- src/Server.php | 12 +++--------- src/utils/EnumTrait.php | 9 +-------- src/utils/NotSerializable.php | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 17 deletions(-) create mode 100644 src/utils/NotSerializable.php diff --git a/src/Server.php b/src/Server.php index e2e1c17481..5029769b11 100644 --- a/src/Server.php +++ b/src/Server.php @@ -93,6 +93,7 @@ use pocketmine\utils\Config; use pocketmine\utils\Filesystem; use pocketmine\utils\Internet; use pocketmine\utils\MainLogger; +use pocketmine\utils\NotSerializable; use pocketmine\utils\Process; use pocketmine\utils\Promise; use pocketmine\utils\Terminal; @@ -160,6 +161,8 @@ use const ZLIB_ENCODING_GZIP; * The class that manages everything */ class Server{ + use NotSerializable; + public const BROADCAST_CHANNEL_ADMINISTRATIVE = "pocketmine.broadcast.admin"; public const BROADCAST_CHANNEL_USERS = "pocketmine.broadcast.user"; @@ -1667,13 +1670,4 @@ class Server{ $this->nextTick += 0.05; } } - - /** - * Called when something attempts to serialize the server instance. - * - * @throws \BadMethodCallException because Server instances cannot be serialized - */ - public function __sleep(){ - throw new \BadMethodCallException("Cannot serialize Server instance"); - } } diff --git a/src/utils/EnumTrait.php b/src/utils/EnumTrait.php index 689c718287..581a7fd18d 100644 --- a/src/utils/EnumTrait.php +++ b/src/utils/EnumTrait.php @@ -27,6 +27,7 @@ use function preg_match; trait EnumTrait{ use RegistryTrait; + use NotSerializable; /** * Registers the given object as an enum member. @@ -101,12 +102,4 @@ trait EnumTrait{ public function __clone(){ throw new \LogicException("Enum members cannot be cloned"); } - - public function __sleep(){ - throw new \LogicException("Enum members cannot be serialized"); - } - - public function __wakeup(){ - throw new \LogicException("Enum members cannot be unserialized"); - } } diff --git a/src/utils/NotSerializable.php b/src/utils/NotSerializable.php new file mode 100644 index 0000000000..6a391d85c8 --- /dev/null +++ b/src/utils/NotSerializable.php @@ -0,0 +1,35 @@ + Date: Fri, 3 Sep 2021 21:07:39 +0100 Subject: [PATCH 2780/3224] Standardize clone denying --- src/utils/EnumTrait.php | 5 +---- src/utils/NotCloneable.php | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 src/utils/NotCloneable.php diff --git a/src/utils/EnumTrait.php b/src/utils/EnumTrait.php index 581a7fd18d..40057b9ea4 100644 --- a/src/utils/EnumTrait.php +++ b/src/utils/EnumTrait.php @@ -27,6 +27,7 @@ use function preg_match; trait EnumTrait{ use RegistryTrait; + use NotCloneable; use NotSerializable; /** @@ -98,8 +99,4 @@ trait EnumTrait{ public function equals(self $other) : bool{ return $this->enumName === $other->enumName; } - - public function __clone(){ - throw new \LogicException("Enum members cannot be cloned"); - } } diff --git a/src/utils/NotCloneable.php b/src/utils/NotCloneable.php new file mode 100644 index 0000000000..23eb04754d --- /dev/null +++ b/src/utils/NotCloneable.php @@ -0,0 +1,31 @@ + Date: Fri, 3 Sep 2021 21:08:29 +0100 Subject: [PATCH 2781/3224] Server is not cloneable --- src/Server.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Server.php b/src/Server.php index 5029769b11..b5402bdf46 100644 --- a/src/Server.php +++ b/src/Server.php @@ -93,6 +93,7 @@ use pocketmine\utils\Config; use pocketmine\utils\Filesystem; use pocketmine\utils\Internet; use pocketmine\utils\MainLogger; +use pocketmine\utils\NotCloneable; use pocketmine\utils\NotSerializable; use pocketmine\utils\Process; use pocketmine\utils\Promise; @@ -161,6 +162,7 @@ use const ZLIB_ENCODING_GZIP; * The class that manages everything */ class Server{ + use NotCloneable; use NotSerializable; public const BROADCAST_CHANNEL_ADMINISTRATIVE = "pocketmine.broadcast.admin"; From ed1e7322dd05f9e5a4bc6a842757327c33e1329c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 3 Sep 2021 21:16:37 +0100 Subject: [PATCH 2782/3224] be quiet phpstan --- src/utils/NotSerializable.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/utils/NotSerializable.php b/src/utils/NotSerializable.php index 6a391d85c8..ccf204e22e 100644 --- a/src/utils/NotSerializable.php +++ b/src/utils/NotSerializable.php @@ -25,11 +25,13 @@ namespace pocketmine\utils; trait NotSerializable{ - final public function __serialize(){ + /** @return mixed[] */ + final public function __serialize() : array{ throw new \LogicException("Serialization of " . static::class . " objects is not allowed"); } - final public function __unserialize(array $data){ + /** @param mixed[] $data */ + final public function __unserialize(array $data) : void{ throw new \LogicException("Unserialization of " . static::class . " objects is not allowed"); } } From c062282954cfd511780830fc662ee8f63191b322 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 3 Sep 2021 21:20:43 +0100 Subject: [PATCH 2783/3224] Drop enchantment runtime IDs --- src/data/bedrock/EnchantmentIdMap.php | 7 +-- src/item/ItemEnchantmentHandlingTrait.php | 9 ++-- src/item/enchantment/Enchantment.php | 14 ++---- src/item/enchantment/EnchantmentInstance.php | 8 ---- .../enchantment/ProtectionEnchantment.php | 4 +- src/item/enchantment/VanillaEnchantments.php | 46 ++++++++----------- 6 files changed, 34 insertions(+), 54 deletions(-) diff --git a/src/data/bedrock/EnchantmentIdMap.php b/src/data/bedrock/EnchantmentIdMap.php index 9c9a783f2d..94985680a3 100644 --- a/src/data/bedrock/EnchantmentIdMap.php +++ b/src/data/bedrock/EnchantmentIdMap.php @@ -27,6 +27,7 @@ use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\utils\SingletonTrait; use function array_key_exists; +use function spl_object_id; /** * Handles translation of internal enchantment types to and from Minecraft: Bedrock IDs. @@ -76,7 +77,7 @@ final class EnchantmentIdMap{ public function register(int $mcpeId, Enchantment $enchantment) : void{ $this->idToEnch[$mcpeId] = $enchantment; - $this->enchToId[$enchantment->getRuntimeId()] = $mcpeId; + $this->enchToId[spl_object_id($enchantment)] = $mcpeId; } public function fromId(int $id) : ?Enchantment{ @@ -85,10 +86,10 @@ final class EnchantmentIdMap{ } public function toId(Enchantment $enchantment) : int{ - if(!array_key_exists($enchantment->getRuntimeId(), $this->enchToId)){ + if(!array_key_exists(spl_object_id($enchantment), $this->enchToId)){ //this should never happen, so we treat it as an exceptional condition throw new \InvalidArgumentException("Enchantment does not have a mapped ID"); } - return $this->enchToId[$enchantment->getRuntimeId()]; + return $this->enchToId[spl_object_id($enchantment)]; } } diff --git a/src/item/ItemEnchantmentHandlingTrait.php b/src/item/ItemEnchantmentHandlingTrait.php index 8d44f0a07d..927509a415 100644 --- a/src/item/ItemEnchantmentHandlingTrait.php +++ b/src/item/ItemEnchantmentHandlingTrait.php @@ -26,6 +26,7 @@ namespace pocketmine\item; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\EnchantmentInstance; use function count; +use function spl_object_id; /** * This trait encapsulates all enchantment handling needed for itemstacks. @@ -40,12 +41,12 @@ trait ItemEnchantmentHandlingTrait{ } public function hasEnchantment(Enchantment $enchantment, int $level = -1) : bool{ - $id = $enchantment->getRuntimeId(); + $id = spl_object_id($enchantment); return isset($this->enchantments[$id]) and ($level === -1 or $this->enchantments[$id]->getLevel() === $level); } public function getEnchantment(Enchantment $enchantment) : ?EnchantmentInstance{ - return $this->enchantments[$enchantment->getRuntimeId()] ?? null; + return $this->enchantments[spl_object_id($enchantment)] ?? null; } /** @@ -54,7 +55,7 @@ trait ItemEnchantmentHandlingTrait{ public function removeEnchantment(Enchantment $enchantment, int $level = -1) : self{ $instance = $this->getEnchantment($enchantment); if($instance !== null and ($level === -1 or $instance->getLevel() === $level)){ - unset($this->enchantments[$enchantment->getRuntimeId()]); + unset($this->enchantments[spl_object_id($enchantment)]); } return $this; @@ -72,7 +73,7 @@ trait ItemEnchantmentHandlingTrait{ * @return $this */ public function addEnchantment(EnchantmentInstance $enchantment) : self{ - $this->enchantments[$enchantment->getRuntimeId()] = $enchantment; + $this->enchantments[spl_object_id($enchantment->getType())] = $enchantment; return $this; } diff --git a/src/item/enchantment/Enchantment.php b/src/item/enchantment/Enchantment.php index a44a25b484..7185a7af27 100644 --- a/src/item/enchantment/Enchantment.php +++ b/src/item/enchantment/Enchantment.php @@ -24,15 +24,17 @@ declare(strict_types=1); namespace pocketmine\item\enchantment; use pocketmine\lang\Translatable; -use function constant; +use pocketmine\utils\NotCloneable; +use pocketmine\utils\NotSerializable; /** * Manages enchantment type data. */ class Enchantment{ + use NotCloneable; + use NotSerializable; public function __construct( - private int $internalRuntimeId, private Translatable|string $name, private int $rarity, private int $primaryItemFlags, @@ -40,14 +42,6 @@ class Enchantment{ private int $maxLevel ){} - /** - * Returns the internal runtime ID of this enchantment. - * WARNING: DO NOT STORE THIS IDENTIFIER - IT MAY CHANGE AFTER RESTART - */ - public function getRuntimeId() : int{ - return $this->internalRuntimeId; - } - /** * Returns a translation key for this enchantment's name. */ diff --git a/src/item/enchantment/EnchantmentInstance.php b/src/item/enchantment/EnchantmentInstance.php index 443c33913f..f46d2c75b8 100644 --- a/src/item/enchantment/EnchantmentInstance.php +++ b/src/item/enchantment/EnchantmentInstance.php @@ -52,14 +52,6 @@ final class EnchantmentInstance{ return $this->enchantment; } - /** - * Returns the runtime type identifier of this enchantment instance. - * WARNING: DO NOT STORE THIS IDENTIFIER - IT MAY CHANGE AFTER SERVER RESTART - */ - public function getRuntimeId() : int{ - return $this->enchantment->getRuntimeId(); - } - /** * Returns the level of the enchantment. */ diff --git a/src/item/enchantment/ProtectionEnchantment.php b/src/item/enchantment/ProtectionEnchantment.php index debf620292..30312ce341 100644 --- a/src/item/enchantment/ProtectionEnchantment.php +++ b/src/item/enchantment/ProtectionEnchantment.php @@ -39,8 +39,8 @@ class ProtectionEnchantment extends Enchantment{ * * @param int[]|null $applicableDamageTypes EntityDamageEvent::CAUSE_* constants which this enchantment type applies to, or null if it applies to all types of damage. */ - public function __construct(int $internalRuntimeId, Translatable|string $name, int $rarity, int $primaryItemFlags, int $secondaryItemFlags, int $maxLevel, float $typeModifier, ?array $applicableDamageTypes){ - parent::__construct($internalRuntimeId, $name, $rarity, $primaryItemFlags, $secondaryItemFlags, $maxLevel); + public function __construct(Translatable|string $name, int $rarity, int $primaryItemFlags, int $secondaryItemFlags, int $maxLevel, float $typeModifier, ?array $applicableDamageTypes){ + parent::__construct($name, $rarity, $primaryItemFlags, $secondaryItemFlags, $maxLevel); $this->typeModifier = $typeModifier; if($applicableDamageTypes !== null){ diff --git a/src/item/enchantment/VanillaEnchantments.php b/src/item/enchantment/VanillaEnchantments.php index bef5c250c3..37425bca13 100644 --- a/src/item/enchantment/VanillaEnchantments.php +++ b/src/item/enchantment/VanillaEnchantments.php @@ -56,53 +56,45 @@ use pocketmine\utils\RegistryTrait; final class VanillaEnchantments{ use RegistryTrait; - /** @var int */ - private static $nextRtId = 0; - - private static function newRtId() : int{ - //TODO: this functionality should probably be generalized - return self::$nextRtId++; - } - protected static function setup() : void{ - self::register("PROTECTION", new ProtectionEnchantment(self::newRtId(), KnownTranslationFactory::enchantment_protect_all(), Rarity::COMMON, ItemFlags::ARMOR, ItemFlags::NONE, 4, 0.75, null)); - self::register("FIRE_PROTECTION", new ProtectionEnchantment(self::newRtId(), KnownTranslationFactory::enchantment_protect_fire(), Rarity::UNCOMMON, ItemFlags::ARMOR, ItemFlags::NONE, 4, 1.25, [ + self::register("PROTECTION", new ProtectionEnchantment(KnownTranslationFactory::enchantment_protect_all(), Rarity::COMMON, ItemFlags::ARMOR, ItemFlags::NONE, 4, 0.75, null)); + self::register("FIRE_PROTECTION", new ProtectionEnchantment(KnownTranslationFactory::enchantment_protect_fire(), Rarity::UNCOMMON, ItemFlags::ARMOR, ItemFlags::NONE, 4, 1.25, [ EntityDamageEvent::CAUSE_FIRE, EntityDamageEvent::CAUSE_FIRE_TICK, EntityDamageEvent::CAUSE_LAVA //TODO: check fireballs ])); - self::register("FEATHER_FALLING", new ProtectionEnchantment(self::newRtId(), KnownTranslationFactory::enchantment_protect_fall(), Rarity::UNCOMMON, ItemFlags::FEET, ItemFlags::NONE, 4, 2.5, [ + self::register("FEATHER_FALLING", new ProtectionEnchantment(KnownTranslationFactory::enchantment_protect_fall(), Rarity::UNCOMMON, ItemFlags::FEET, ItemFlags::NONE, 4, 2.5, [ EntityDamageEvent::CAUSE_FALL ])); - self::register("BLAST_PROTECTION", new ProtectionEnchantment(self::newRtId(), KnownTranslationFactory::enchantment_protect_explosion(), Rarity::RARE, ItemFlags::ARMOR, ItemFlags::NONE, 4, 1.5, [ + self::register("BLAST_PROTECTION", new ProtectionEnchantment(KnownTranslationFactory::enchantment_protect_explosion(), Rarity::RARE, ItemFlags::ARMOR, ItemFlags::NONE, 4, 1.5, [ EntityDamageEvent::CAUSE_BLOCK_EXPLOSION, EntityDamageEvent::CAUSE_ENTITY_EXPLOSION ])); - self::register("PROJECTILE_PROTECTION", new ProtectionEnchantment(self::newRtId(), KnownTranslationFactory::enchantment_protect_projectile(), Rarity::UNCOMMON, ItemFlags::ARMOR, ItemFlags::NONE, 4, 1.5, [ + self::register("PROJECTILE_PROTECTION", new ProtectionEnchantment(KnownTranslationFactory::enchantment_protect_projectile(), Rarity::UNCOMMON, ItemFlags::ARMOR, ItemFlags::NONE, 4, 1.5, [ EntityDamageEvent::CAUSE_PROJECTILE ])); - self::register("THORNS", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_thorns(), Rarity::MYTHIC, ItemFlags::TORSO, ItemFlags::HEAD | ItemFlags::LEGS | ItemFlags::FEET, 3)); - self::register("RESPIRATION", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_oxygen(), Rarity::RARE, ItemFlags::HEAD, ItemFlags::NONE, 3)); + self::register("THORNS", new Enchantment(KnownTranslationFactory::enchantment_thorns(), Rarity::MYTHIC, ItemFlags::TORSO, ItemFlags::HEAD | ItemFlags::LEGS | ItemFlags::FEET, 3)); + self::register("RESPIRATION", new Enchantment(KnownTranslationFactory::enchantment_oxygen(), Rarity::RARE, ItemFlags::HEAD, ItemFlags::NONE, 3)); - self::register("SHARPNESS", new SharpnessEnchantment(self::newRtId(), KnownTranslationFactory::enchantment_damage_all(), Rarity::COMMON, ItemFlags::SWORD, ItemFlags::AXE, 5)); + self::register("SHARPNESS", new SharpnessEnchantment(KnownTranslationFactory::enchantment_damage_all(), Rarity::COMMON, ItemFlags::SWORD, ItemFlags::AXE, 5)); //TODO: smite, bane of arthropods (these don't make sense now because their applicable mobs don't exist yet) - self::register("KNOCKBACK", new KnockbackEnchantment(self::newRtId(), KnownTranslationFactory::enchantment_knockback(), Rarity::UNCOMMON, ItemFlags::SWORD, ItemFlags::NONE, 2)); - self::register("FIRE_ASPECT", new FireAspectEnchantment(self::newRtId(), KnownTranslationFactory::enchantment_fire(), Rarity::RARE, ItemFlags::SWORD, ItemFlags::NONE, 2)); + self::register("KNOCKBACK", new KnockbackEnchantment(KnownTranslationFactory::enchantment_knockback(), Rarity::UNCOMMON, ItemFlags::SWORD, ItemFlags::NONE, 2)); + self::register("FIRE_ASPECT", new FireAspectEnchantment(KnownTranslationFactory::enchantment_fire(), Rarity::RARE, ItemFlags::SWORD, ItemFlags::NONE, 2)); - self::register("EFFICIENCY", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_digging(), Rarity::COMMON, ItemFlags::DIG, ItemFlags::SHEARS, 5)); - self::register("SILK_TOUCH", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_untouching(), Rarity::MYTHIC, ItemFlags::DIG, ItemFlags::SHEARS, 1)); - self::register("UNBREAKING", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_durability(), Rarity::UNCOMMON, ItemFlags::DIG | ItemFlags::ARMOR | ItemFlags::FISHING_ROD | ItemFlags::BOW, ItemFlags::TOOL | ItemFlags::CARROT_STICK | ItemFlags::ELYTRA, 3)); + self::register("EFFICIENCY", new Enchantment(KnownTranslationFactory::enchantment_digging(), Rarity::COMMON, ItemFlags::DIG, ItemFlags::SHEARS, 5)); + self::register("SILK_TOUCH", new Enchantment(KnownTranslationFactory::enchantment_untouching(), Rarity::MYTHIC, ItemFlags::DIG, ItemFlags::SHEARS, 1)); + self::register("UNBREAKING", new Enchantment(KnownTranslationFactory::enchantment_durability(), Rarity::UNCOMMON, ItemFlags::DIG | ItemFlags::ARMOR | ItemFlags::FISHING_ROD | ItemFlags::BOW, ItemFlags::TOOL | ItemFlags::CARROT_STICK | ItemFlags::ELYTRA, 3)); - self::register("POWER", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_arrowDamage(), Rarity::COMMON, ItemFlags::BOW, ItemFlags::NONE, 5)); - self::register("PUNCH", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_arrowKnockback(), Rarity::RARE, ItemFlags::BOW, ItemFlags::NONE, 2)); - self::register("FLAME", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_arrowFire(), Rarity::RARE, ItemFlags::BOW, ItemFlags::NONE, 1)); - self::register("INFINITY", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_arrowInfinite(), Rarity::MYTHIC, ItemFlags::BOW, ItemFlags::NONE, 1)); + self::register("POWER", new Enchantment(KnownTranslationFactory::enchantment_arrowDamage(), Rarity::COMMON, ItemFlags::BOW, ItemFlags::NONE, 5)); + self::register("PUNCH", new Enchantment(KnownTranslationFactory::enchantment_arrowKnockback(), Rarity::RARE, ItemFlags::BOW, ItemFlags::NONE, 2)); + self::register("FLAME", new Enchantment(KnownTranslationFactory::enchantment_arrowFire(), Rarity::RARE, ItemFlags::BOW, ItemFlags::NONE, 1)); + self::register("INFINITY", new Enchantment(KnownTranslationFactory::enchantment_arrowInfinite(), Rarity::MYTHIC, ItemFlags::BOW, ItemFlags::NONE, 1)); - self::register("MENDING", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_mending(), Rarity::RARE, ItemFlags::NONE, ItemFlags::ALL, 1)); + self::register("MENDING", new Enchantment(KnownTranslationFactory::enchantment_mending(), Rarity::RARE, ItemFlags::NONE, ItemFlags::ALL, 1)); - self::register("VANISHING", new Enchantment(self::newRtId(), KnownTranslationFactory::enchantment_curse_vanishing(), Rarity::MYTHIC, ItemFlags::NONE, ItemFlags::ALL, 1)); + self::register("VANISHING", new Enchantment(KnownTranslationFactory::enchantment_curse_vanishing(), Rarity::MYTHIC, ItemFlags::NONE, ItemFlags::ALL, 1)); } protected static function register(string $name, Enchantment $member) : void{ From 0404298c740d667e20a35856d2b302fccf4c1fd4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 3 Sep 2021 21:25:06 +0100 Subject: [PATCH 2784/3224] Effect: get rid of runtimeIDs --- src/data/bedrock/EffectIdMap.php | 7 ++-- src/entity/effect/Effect.php | 14 +++----- src/entity/effect/EffectManager.php | 9 ++--- src/entity/effect/PoisonEffect.php | 4 +-- src/entity/effect/VanillaEffects.php | 52 ++++++++++++++-------------- 5 files changed, 41 insertions(+), 45 deletions(-) diff --git a/src/data/bedrock/EffectIdMap.php b/src/data/bedrock/EffectIdMap.php index b9ccf24715..f5257fe0de 100644 --- a/src/data/bedrock/EffectIdMap.php +++ b/src/data/bedrock/EffectIdMap.php @@ -27,6 +27,7 @@ use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\VanillaEffects; use pocketmine\utils\SingletonTrait; use function array_key_exists; +use function spl_object_id; final class EffectIdMap{ use SingletonTrait; @@ -79,7 +80,7 @@ final class EffectIdMap{ public function register(int $mcpeId, Effect $effect) : void{ $this->idToEffect[$mcpeId] = $effect; - $this->effectToId[$effect->getRuntimeId()] = $mcpeId; + $this->effectToId[spl_object_id($effect)] = $mcpeId; } public function fromId(int $id) : ?Effect{ @@ -88,10 +89,10 @@ final class EffectIdMap{ } public function toId(Effect $effect) : int{ - if(!array_key_exists($effect->getRuntimeId(), $this->effectToId)){ + if(!array_key_exists(spl_object_id($effect), $this->effectToId)){ //this should never happen, so we treat it as an exceptional condition throw new \InvalidArgumentException("Effect does not have a mapped ID"); } - return $this->effectToId[$effect->getRuntimeId()]; + return $this->effectToId[spl_object_id($effect)]; } } diff --git a/src/entity/effect/Effect.php b/src/entity/effect/Effect.php index 02ac6dc135..b5c385c6f8 100644 --- a/src/entity/effect/Effect.php +++ b/src/entity/effect/Effect.php @@ -27,32 +27,26 @@ use pocketmine\color\Color; use pocketmine\entity\Entity; use pocketmine\entity\Living; use pocketmine\lang\Translatable; +use pocketmine\utils\NotCloneable; +use pocketmine\utils\NotSerializable; class Effect{ + use NotCloneable; + use NotSerializable; /** - * @param int $internalRuntimeId Internal runtime ID, unique to this effect type. Used for comparisons. * @param Translatable|string $name Translation key used for effect name * @param Color $color Color of bubbles given by this effect * @param bool $bad Whether the effect is harmful * @param bool $hasBubbles Whether the effect has potion bubbles. Some do not (e.g. Instant Damage has its own particles instead of bubbles) */ public function __construct( - protected int $internalRuntimeId, protected Translatable|string $name, protected Color $color, protected bool $bad = false, protected bool $hasBubbles = true ){} - /** - * Returns a unique identifier for this effect type - * WARNING: DO NOT STORE THIS - IT MAY CHANGE BETWEEN RESTARTS - */ - public function getRuntimeId() : int{ - return $this->internalRuntimeId; - } - /** * Returns the translation key used to translate this effect's name. */ diff --git a/src/entity/effect/EffectManager.php b/src/entity/effect/EffectManager.php index d9933d16dd..17bdb89471 100644 --- a/src/entity/effect/EffectManager.php +++ b/src/entity/effect/EffectManager.php @@ -30,6 +30,7 @@ use pocketmine\event\entity\EntityEffectRemoveEvent; use pocketmine\utils\ObjectSet; use function abs; use function count; +use function spl_object_id; class EffectManager{ @@ -83,7 +84,7 @@ class EffectManager{ * Removes the effect with the specified ID from the mob. */ public function remove(Effect $effectType) : void{ - $index = $effectType->getRuntimeId(); + $index = spl_object_id($effectType); if(isset($this->effects[$index])){ $effect = $this->effects[$index]; $hasExpired = $effect->hasExpired(); @@ -113,14 +114,14 @@ class EffectManager{ * effect. */ public function get(Effect $effect) : ?EffectInstance{ - return $this->effects[$effect->getRuntimeId()] ?? null; + return $this->effects[spl_object_id($effect)] ?? null; } /** * Returns whether the specified effect is active on the mob. */ public function has(Effect $effect) : bool{ - return isset($this->effects[$effect->getRuntimeId()]); + return isset($this->effects[spl_object_id($effect)]); } /** @@ -134,7 +135,7 @@ class EffectManager{ $oldEffect = null; $cancelled = false; - $index = $effect->getType()->getRuntimeId(); + $index = spl_object_id($effect->getType()); if(isset($this->effects[$index])){ $oldEffect = $this->effects[$index]; if( diff --git a/src/entity/effect/PoisonEffect.php b/src/entity/effect/PoisonEffect.php index 61442159ed..02bab6b8cd 100644 --- a/src/entity/effect/PoisonEffect.php +++ b/src/entity/effect/PoisonEffect.php @@ -34,8 +34,8 @@ class PoisonEffect extends Effect{ /** @var bool */ private $fatal; - public function __construct(int $internalRuntimeId, Translatable $name, Color $color, bool $isBad = false, bool $hasBubbles = true, bool $fatal = false){ - parent::__construct($internalRuntimeId, $name, $color, $isBad, $hasBubbles); + public function __construct(Translatable $name, Color $color, bool $isBad = false, bool $hasBubbles = true, bool $fatal = false){ + parent::__construct($name, $color, $isBad, $hasBubbles); $this->fatal = $fatal; } diff --git a/src/entity/effect/VanillaEffects.php b/src/entity/effect/VanillaEffects.php index 4145b5f9d9..a447613d40 100644 --- a/src/entity/effect/VanillaEffects.php +++ b/src/entity/effect/VanillaEffects.php @@ -65,35 +65,35 @@ final class VanillaEffects{ use RegistryTrait; protected static function setup() : void{ - self::register("absorption", new AbsorptionEffect(22, KnownTranslationFactory::potion_absorption(), new Color(0x25, 0x52, 0xa5))); + self::register("absorption", new AbsorptionEffect(KnownTranslationFactory::potion_absorption(), new Color(0x25, 0x52, 0xa5))); //TODO: bad_omen - self::register("blindness", new Effect(15, KnownTranslationFactory::potion_blindness(), new Color(0x1f, 0x1f, 0x23), true)); - self::register("conduit_power", new Effect(26, KnownTranslationFactory::potion_conduitPower(), new Color(0x1d, 0xc2, 0xd1))); - self::register("fatal_poison", new PoisonEffect(25, KnownTranslationFactory::potion_poison(), new Color(0x4e, 0x93, 0x31), true, true, true)); - self::register("fire_resistance", new Effect(12, KnownTranslationFactory::potion_fireResistance(), new Color(0xe4, 0x9a, 0x3a))); - self::register("haste", new Effect(3, KnownTranslationFactory::potion_digSpeed(), new Color(0xd9, 0xc0, 0x43))); - self::register("health_boost", new HealthBoostEffect(21, KnownTranslationFactory::potion_healthBoost(), new Color(0xf8, 0x7d, 0x23))); - self::register("hunger", new HungerEffect(17, KnownTranslationFactory::potion_hunger(), new Color(0x58, 0x76, 0x53), true)); - self::register("instant_damage", new InstantDamageEffect(7, KnownTranslationFactory::potion_harm(), new Color(0x43, 0x0a, 0x09), true, false)); - self::register("instant_health", new InstantHealthEffect(6, KnownTranslationFactory::potion_heal(), new Color(0xf8, 0x24, 0x23), false, false)); - self::register("invisibility", new InvisibilityEffect(14, KnownTranslationFactory::potion_invisibility(), new Color(0x7f, 0x83, 0x92))); - self::register("jump_boost", new Effect(8, KnownTranslationFactory::potion_jump(), new Color(0x22, 0xff, 0x4c))); - self::register("levitation", new LevitationEffect(24, KnownTranslationFactory::potion_levitation(), new Color(0xce, 0xff, 0xff))); - self::register("mining_fatigue", new Effect(4, KnownTranslationFactory::potion_digSlowDown(), new Color(0x4a, 0x42, 0x17), true)); - self::register("nausea", new Effect(9, KnownTranslationFactory::potion_confusion(), new Color(0x55, 0x1d, 0x4a), true)); - self::register("night_vision", new Effect(16, KnownTranslationFactory::potion_nightVision(), new Color(0x1f, 0x1f, 0xa1))); - self::register("poison", new PoisonEffect(19, KnownTranslationFactory::potion_poison(), new Color(0x4e, 0x93, 0x31), true)); - self::register("regeneration", new RegenerationEffect(10, KnownTranslationFactory::potion_regeneration(), new Color(0xcd, 0x5c, 0xab))); - self::register("resistance", new Effect(11, KnownTranslationFactory::potion_resistance(), new Color(0x99, 0x45, 0x3a))); - self::register("saturation", new SaturationEffect(23, KnownTranslationFactory::potion_saturation(), new Color(0xf8, 0x24, 0x23), false)); + self::register("blindness", new Effect(KnownTranslationFactory::potion_blindness(), new Color(0x1f, 0x1f, 0x23), true)); + self::register("conduit_power", new Effect(KnownTranslationFactory::potion_conduitPower(), new Color(0x1d, 0xc2, 0xd1))); + self::register("fatal_poison", new PoisonEffect(KnownTranslationFactory::potion_poison(), new Color(0x4e, 0x93, 0x31), true, true, true)); + self::register("fire_resistance", new Effect(KnownTranslationFactory::potion_fireResistance(), new Color(0xe4, 0x9a, 0x3a))); + self::register("haste", new Effect(KnownTranslationFactory::potion_digSpeed(), new Color(0xd9, 0xc0, 0x43))); + self::register("health_boost", new HealthBoostEffect(KnownTranslationFactory::potion_healthBoost(), new Color(0xf8, 0x7d, 0x23))); + self::register("hunger", new HungerEffect(KnownTranslationFactory::potion_hunger(), new Color(0x58, 0x76, 0x53), true)); + self::register("instant_damage", new InstantDamageEffect(KnownTranslationFactory::potion_harm(), new Color(0x43, 0x0a, 0x09), true, false)); + self::register("instant_health", new InstantHealthEffect(KnownTranslationFactory::potion_heal(), new Color(0xf8, 0x24, 0x23), false, false)); + self::register("invisibility", new InvisibilityEffect(KnownTranslationFactory::potion_invisibility(), new Color(0x7f, 0x83, 0x92))); + self::register("jump_boost", new Effect(KnownTranslationFactory::potion_jump(), new Color(0x22, 0xff, 0x4c))); + self::register("levitation", new LevitationEffect(KnownTranslationFactory::potion_levitation(), new Color(0xce, 0xff, 0xff))); + self::register("mining_fatigue", new Effect(KnownTranslationFactory::potion_digSlowDown(), new Color(0x4a, 0x42, 0x17), true)); + self::register("nausea", new Effect(KnownTranslationFactory::potion_confusion(), new Color(0x55, 0x1d, 0x4a), true)); + self::register("night_vision", new Effect(KnownTranslationFactory::potion_nightVision(), new Color(0x1f, 0x1f, 0xa1))); + self::register("poison", new PoisonEffect(KnownTranslationFactory::potion_poison(), new Color(0x4e, 0x93, 0x31), true)); + self::register("regeneration", new RegenerationEffect(KnownTranslationFactory::potion_regeneration(), new Color(0xcd, 0x5c, 0xab))); + self::register("resistance", new Effect(KnownTranslationFactory::potion_resistance(), new Color(0x99, 0x45, 0x3a))); + self::register("saturation", new SaturationEffect(KnownTranslationFactory::potion_saturation(), new Color(0xf8, 0x24, 0x23), false)); //TODO: slow_falling - self::register("slowness", new SlownessEffect(2, KnownTranslationFactory::potion_moveSlowdown(), new Color(0x5a, 0x6c, 0x81), true)); - self::register("speed", new SpeedEffect(1, KnownTranslationFactory::potion_moveSpeed(), new Color(0x7c, 0xaf, 0xc6))); - self::register("strength", new Effect(5, KnownTranslationFactory::potion_damageBoost(), new Color(0x93, 0x24, 0x23))); + self::register("slowness", new SlownessEffect(KnownTranslationFactory::potion_moveSlowdown(), new Color(0x5a, 0x6c, 0x81), true)); + self::register("speed", new SpeedEffect(KnownTranslationFactory::potion_moveSpeed(), new Color(0x7c, 0xaf, 0xc6))); + self::register("strength", new Effect(KnownTranslationFactory::potion_damageBoost(), new Color(0x93, 0x24, 0x23))); //TODO: village_hero - self::register("water_breathing", new Effect(13, KnownTranslationFactory::potion_waterBreathing(), new Color(0x2e, 0x52, 0x99))); - self::register("weakness", new Effect(18, KnownTranslationFactory::potion_weakness(), new Color(0x48, 0x4d, 0x48), true)); - self::register("wither", new WitherEffect(20, KnownTranslationFactory::potion_wither(), new Color(0x35, 0x2a, 0x27), true)); + self::register("water_breathing", new Effect(KnownTranslationFactory::potion_waterBreathing(), new Color(0x2e, 0x52, 0x99))); + self::register("weakness", new Effect(KnownTranslationFactory::potion_weakness(), new Color(0x48, 0x4d, 0x48), true)); + self::register("wither", new WitherEffect(KnownTranslationFactory::potion_wither(), new Color(0x35, 0x2a, 0x27), true)); } protected static function register(string $name, Effect $member) : void{ From 7d5b9295cbfdb7b8daa79d9385e4622328d1a2f6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 3 Sep 2021 21:33:55 +0100 Subject: [PATCH 2785/3224] PoisonEffect should accept Translatable|string, like its parent this doesn't really break anything, but someone will likely whine about consistency if it's not fixed now. --- src/entity/effect/PoisonEffect.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entity/effect/PoisonEffect.php b/src/entity/effect/PoisonEffect.php index 02bab6b8cd..99dffb3afd 100644 --- a/src/entity/effect/PoisonEffect.php +++ b/src/entity/effect/PoisonEffect.php @@ -34,7 +34,7 @@ class PoisonEffect extends Effect{ /** @var bool */ private $fatal; - public function __construct(Translatable $name, Color $color, bool $isBad = false, bool $hasBubbles = true, bool $fatal = false){ + public function __construct(Translatable|string $name, Color $color, bool $isBad = false, bool $hasBubbles = true, bool $fatal = false){ parent::__construct($name, $color, $isBad, $hasBubbles); $this->fatal = $fatal; } From 7e82cafdeb14c989280106d1ad27b586d9ca3318 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Sep 2021 13:27:48 +0100 Subject: [PATCH 2786/3224] Entity: remove a bunch of commented code that no one cares about --- src/entity/Entity.php | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 51b9d4bfb6..e7b387b4cb 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1096,46 +1096,8 @@ abstract class Entity{ }else{ $this->ySize *= self::STEP_CLIP_MULTIPLIER; - /* - if($this->isColliding){ //With cobweb? - $this->isColliding = false; - $dx *= 0.25; - $dy *= 0.05; - $dz *= 0.25; - $this->motionX = 0; - $this->motionY = 0; - $this->motionZ = 0; - } - */ - $moveBB = clone $this->boundingBox; - /*$sneakFlag = $this->onGround and $this instanceof Player; - - if($sneakFlag){ - for($mov = 0.05; $dx != 0.0 and count($this->world->getCollisionCubes($this, $this->boundingBox->getOffsetBoundingBox($dx, -1, 0))) === 0; $movX = $dx){ - if($dx < $mov and $dx >= -$mov){ - $dx = 0; - }elseif($dx > 0){ - $dx -= $mov; - }else{ - $dx += $mov; - } - } - - for(; $dz != 0.0 and count($this->world->getCollisionCubes($this, $this->boundingBox->getOffsetBoundingBox(0, -1, $dz))) === 0; $movZ = $dz){ - if($dz < $mov and $dz >= -$mov){ - $dz = 0; - }elseif($dz > 0){ - $dz -= $mov; - }else{ - $dz += $mov; - } - } - - //TODO: big messy loop - }*/ - assert(abs($dx) <= 20 and abs($dy) <= 20 and abs($dz) <= 20, "Movement distance is excessive: dx=$dx, dy=$dy, dz=$dz"); $list = $this->getWorld()->getCollisionBoxes($this, $moveBB->addCoord($dx, $dy, $dz), false); From 6ecad153eae695f9409de838fe78e95020e6379d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Sep 2021 13:34:43 +0100 Subject: [PATCH 2787/3224] Entity: remove fallDistance parameter from fall() --- src/entity/Entity.php | 4 ++-- src/entity/Living.php | 4 ++-- src/player/Player.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index e7b387b4cb..be78dece8c 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1025,7 +1025,7 @@ abstract class Entity{ protected function updateFallState(float $distanceThisTick, bool $onGround) : void{ if($onGround){ if($this->fallDistance > 0){ - $this->fall($this->fallDistance); + $this->fall(); $this->resetFallDistance(); } }elseif($distanceThisTick < $this->fallDistance){ @@ -1042,7 +1042,7 @@ abstract class Entity{ /** * Called when a falling entity hits the ground. */ - public function fall(float $fallDistance) : void{ + public function fall() : void{ } diff --git a/src/entity/Living.php b/src/entity/Living.php index 8c78b7a00c..20d9c5ee12 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -305,8 +305,8 @@ abstract class Living extends Entity{ } } - public function fall(float $fallDistance) : void{ - $damage = ceil($fallDistance - 3 - (($jumpBoost = $this->effectManager->get(VanillaEffects::JUMP_BOOST())) !== null ? $jumpBoost->getEffectLevel() : 0)); + public function fall() : void{ + $damage = ceil($this->fallDistance - 3 - (($jumpBoost = $this->effectManager->get(VanillaEffects::JUMP_BOOST())) !== null ? $jumpBoost->getEffectLevel() : 0)); if($damage > 0){ $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FALL, $damage); $this->attack($ev); diff --git a/src/player/Player.php b/src/player/Player.php index 608ee63c93..3fc2ac198f 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1200,9 +1200,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->sendPosition($from, $from->yaw, $from->pitch, MovePlayerPacket::MODE_RESET); } - public function fall(float $fallDistance) : void{ + public function fall() : void{ if(!$this->flying){ - parent::fall($fallDistance); + parent::fall(); } } From 8be1f34736b93fb4697eb6d93ccc07ec66b6212e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Sep 2021 13:36:40 +0100 Subject: [PATCH 2788/3224] Entity: Rename fall() to onHitGround(), and make it protected this had no business being exposed to public API in the first place. --- src/entity/Entity.php | 4 ++-- src/entity/Living.php | 2 +- src/player/Player.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index be78dece8c..d4837d60ef 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1025,7 +1025,7 @@ abstract class Entity{ protected function updateFallState(float $distanceThisTick, bool $onGround) : void{ if($onGround){ if($this->fallDistance > 0){ - $this->fall(); + $this->onHitGround(); $this->resetFallDistance(); } }elseif($distanceThisTick < $this->fallDistance){ @@ -1042,7 +1042,7 @@ abstract class Entity{ /** * Called when a falling entity hits the ground. */ - public function fall() : void{ + protected function onHitGround() : void{ } diff --git a/src/entity/Living.php b/src/entity/Living.php index 20d9c5ee12..2c1d3d2477 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -305,7 +305,7 @@ abstract class Living extends Entity{ } } - public function fall() : void{ + protected function onHitGround() : void{ $damage = ceil($this->fallDistance - 3 - (($jumpBoost = $this->effectManager->get(VanillaEffects::JUMP_BOOST())) !== null ? $jumpBoost->getEffectLevel() : 0)); if($damage > 0){ $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FALL, $damage); diff --git a/src/player/Player.php b/src/player/Player.php index 3fc2ac198f..123b2974a8 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1200,9 +1200,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->sendPosition($from, $from->yaw, $from->pitch, MovePlayerPacket::MODE_RESET); } - public function fall() : void{ + protected function onHitGround() : void{ if(!$this->flying){ - parent::fall(); + parent::onHitGround(); } } From 73cc841d0b95fed7a9a0fa3bb62c6710027a75be Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Sep 2021 14:00:27 +0100 Subject: [PATCH 2789/3224] Entity: rename checkBlockCollisions() to checkBlockIntersections() --- src/entity/Entity.php | 6 +++--- src/entity/projectile/Projectile.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index d4837d60ef..8c930a834e 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -632,7 +632,7 @@ abstract class Entity{ $hasUpdate = false; - $this->checkBlockCollision(); + $this->checkBlockIntersections(); if($this->location->y <= -16 and $this->isAlive()){ $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_VOID, 10); @@ -1181,7 +1181,7 @@ abstract class Entity{ ); $this->getWorld()->onEntityMoved($this); - $this->checkBlockCollision(); + $this->checkBlockIntersections(); $this->checkGroundState($movX, $movY, $movZ, $dx, $dy, $dz); $this->updateFallState($dy, $this->onGround); @@ -1243,7 +1243,7 @@ abstract class Entity{ return true; } - protected function checkBlockCollision() : void{ + protected function checkBlockIntersections() : void{ $vectors = []; foreach($this->getBlocksAroundWithEntityInsideActions() as $block){ diff --git a/src/entity/projectile/Projectile.php b/src/entity/projectile/Projectile.php index 6d28b2eaaa..9201b60600 100644 --- a/src/entity/projectile/Projectile.php +++ b/src/entity/projectile/Projectile.php @@ -262,7 +262,7 @@ abstract class Projectile extends Entity{ } $this->getWorld()->onEntityMoved($this); - $this->checkBlockCollision(); + $this->checkBlockIntersections(); Timings::$entityMove->stopTiming(); } From d329bfb25d854bb8dc3832469dee5dd1d8936bf9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Sep 2021 14:06:53 +0100 Subject: [PATCH 2790/3224] Entity: rename movX/movY/movZ to wantedX/wantedY/wantedZ this makes the code much easier to understand. --- src/entity/Entity.php | 30 +++++++++++++++--------------- src/player/Player.php | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 8c930a834e..b983babeff 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1087,9 +1087,9 @@ abstract class Entity{ Timings::$entityMove->startTiming(); - $movX = $dx; - $movY = $dy; - $movZ = $dz; + $wantedX = $dx; + $wantedY = $dy; + $wantedZ = $dz; if($this->keepMovement){ $this->boundingBox->offset($dx, $dy, $dz); @@ -1108,7 +1108,7 @@ abstract class Entity{ $moveBB->offset(0, $dy, 0); - $fallingFlag = ($this->onGround or ($dy != $movY and $movY < 0)); + $fallingFlag = ($this->onGround or ($dy != $wantedY and $wantedY < 0)); foreach($list as $bb){ $dx = $bb->calculateXOffset($moveBB, $dx); @@ -1122,13 +1122,13 @@ abstract class Entity{ $moveBB->offset(0, 0, $dz); - if($this->stepHeight > 0 and $fallingFlag and ($movX != $dx or $movZ != $dz)){ + if($this->stepHeight > 0 and $fallingFlag and ($wantedX != $dx or $wantedZ != $dz)){ $cx = $dx; $cy = $dy; $cz = $dz; - $dx = $movX; + $dx = $wantedX; $dy = $this->stepHeight; - $dz = $movZ; + $dz = $wantedZ; $stepBB = clone $this->boundingBox; @@ -1182,13 +1182,13 @@ abstract class Entity{ $this->getWorld()->onEntityMoved($this); $this->checkBlockIntersections(); - $this->checkGroundState($movX, $movY, $movZ, $dx, $dy, $dz); + $this->checkGroundState($wantedX, $wantedY, $wantedZ, $dx, $dy, $dz); $this->updateFallState($dy, $this->onGround); $this->motion = $this->motion->withComponents( - $movX != $dx ? 0 : null, - $movY != $dy ? 0 : null, - $movZ != $dz ? 0 : null + $wantedX != $dx ? 0 : null, + $wantedY != $dy ? 0 : null, + $wantedZ != $dz ? 0 : null ); //TODO: vehicle collision events (first we need to spawn them!) @@ -1196,11 +1196,11 @@ abstract class Entity{ Timings::$entityMove->stopTiming(); } - protected function checkGroundState(float $movX, float $movY, float $movZ, float $dx, float $dy, float $dz) : void{ - $this->isCollidedVertically = $movY != $dy; - $this->isCollidedHorizontally = ($movX != $dx or $movZ != $dz); + protected function checkGroundState(float $wantedX, float $wantedY, float $wantedZ, float $dx, float $dy, float $dz) : void{ + $this->isCollidedVertically = $wantedY != $dy; + $this->isCollidedHorizontally = ($wantedX != $dx or $wantedZ != $dz); $this->isCollided = ($this->isCollidedHorizontally or $this->isCollidedVertically); - $this->onGround = ($movY != $dy and $movY < 0); + $this->onGround = ($wantedY != $dy and $wantedY < 0); } /** diff --git a/src/player/Player.php b/src/player/Player.php index 123b2974a8..6ec3a36ff2 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1058,7 +1058,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return 0; } - protected function checkGroundState(float $movX, float $movY, float $movZ, float $dx, float $dy, float $dz) : void{ + protected function checkGroundState(float $wantedX, float $wantedY, float $wantedZ, float $dx, float $dy, float $dz) : void{ if($this->isSpectator()){ $this->onGround = false; }else{ From 17dfd2cc52b213d051051b94933907f5eb01c456 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Sep 2021 14:10:54 +0100 Subject: [PATCH 2791/3224] Living: Trigger fall sounds on the nearest collidable block below we can't have landed on it unless it actually has a collision box - otherwise, we only landed _in_ it. This assumes, of course, that no blocks have bounding boxes >= 2 blocks tall, which currently none do. --- src/entity/Living.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entity/Living.php b/src/entity/Living.php index 2c1d3d2477..4e7401307c 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -318,7 +318,7 @@ abstract class Living extends Entity{ }else{ $fallBlockPos = $this->location->floor(); $fallBlock = $this->getWorld()->getBlock($fallBlockPos); - if($fallBlock->getId() === BlockLegacyIds::AIR){ + if(count($fallBlock->getCollisionBoxes()) === 0){ $fallBlockPos = $fallBlockPos->subtract(0, 1, 0); $fallBlock = $this->getWorld()->getBlock($fallBlockPos); } From 6b7e67179460b9ae434ad9451ffb6853d1634b31 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Sep 2021 14:12:04 +0100 Subject: [PATCH 2792/3224] Living: use Vector3->down() instead of subtract(). --- src/entity/Living.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entity/Living.php b/src/entity/Living.php index 4e7401307c..1bfb7a3351 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -319,7 +319,7 @@ abstract class Living extends Entity{ $fallBlockPos = $this->location->floor(); $fallBlock = $this->getWorld()->getBlock($fallBlockPos); if(count($fallBlock->getCollisionBoxes()) === 0){ - $fallBlockPos = $fallBlockPos->subtract(0, 1, 0); + $fallBlockPos = $fallBlockPos->down(); $fallBlock = $this->getWorld()->getBlock($fallBlockPos); } if($fallBlock->getId() !== BlockLegacyIds::AIR){ From d4d00a9b80218b2f3b312eb8b150dec9e8ca0123 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Sep 2021 14:36:58 +0100 Subject: [PATCH 2793/3224] Living: added calculateFallDamage() to clean up the way that fall damage is handled for flying players; also, onHitGround() isn't only doing fall damage things these days. --- src/entity/Living.php | 6 +++++- src/player/Player.php | 6 ++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/entity/Living.php b/src/entity/Living.php index 1bfb7a3351..a1c2f9ab3f 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -305,8 +305,12 @@ abstract class Living extends Entity{ } } + protected function calculateFallDamage(float $fallDistance) : float{ + return ceil($fallDistance - 3 - (($jumpBoost = $this->effectManager->get(VanillaEffects::JUMP_BOOST())) !== null ? $jumpBoost->getEffectLevel() : 0)); + } + protected function onHitGround() : void{ - $damage = ceil($this->fallDistance - 3 - (($jumpBoost = $this->effectManager->get(VanillaEffects::JUMP_BOOST())) !== null ? $jumpBoost->getEffectLevel() : 0)); + $damage = $this->calculateFallDamage($this->fallDistance); if($damage > 0){ $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FALL, $damage); $this->attack($ev); diff --git a/src/player/Player.php b/src/player/Player.php index 6ec3a36ff2..55e32943a4 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1200,10 +1200,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->sendPosition($from, $from->yaw, $from->pitch, MovePlayerPacket::MODE_RESET); } - protected function onHitGround() : void{ - if(!$this->flying){ - parent::onHitGround(); - } + protected function calculateFallDamage(float $fallDistance) : float{ + return $this->flying ? 0 : parent::calculateFallDamage($fallDistance); } public function jump() : void{ From 19513c65f0630152eae03d0855554e20a9778161 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Sep 2021 15:13:22 +0100 Subject: [PATCH 2794/3224] World: avoid code duplication between getCollidingEntities() and getNearbyEntities() these two methods are very misleadingly named, but they do almost exactly the same thing - the only difference is that getCollidingEntities() does a couple of additional checks. --- src/world/World.php | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 43d15bbbc2..16d871be2d 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1882,22 +1882,9 @@ class World implements ChunkManager{ $nearby = []; if($entity === null or $entity->canCollide){ - $minX = ((int) floor($bb->minX - 2)) >> 4; - $maxX = ((int) floor($bb->maxX + 2)) >> 4; - $minZ = ((int) floor($bb->minZ - 2)) >> 4; - $maxZ = ((int) floor($bb->maxZ + 2)) >> 4; - - for($x = $minX; $x <= $maxX; ++$x){ - for($z = $minZ; $z <= $maxZ; ++$z){ - if(!$this->isChunkLoaded($x, $z)){ - continue; - } - foreach($this->getChunk($x, $z)->getEntities() as $ent){ - /** @var Entity|null $entity */ - if($ent->canBeCollidedWith() and ($entity === null or ($ent !== $entity and $entity->canCollideWith($ent))) and $ent->boundingBox->intersectsWith($bb)){ - $nearby[] = $ent; - } - } + foreach($this->getNearbyEntities($bb, $entity) as $ent){ + if($ent->canBeCollidedWith() and ($entity === null or $entity->canCollideWith($ent))){ + $nearby[] = $ent; } } } From 2fc33d3bff95a070bb754d555f4daac46c5c1e31 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Sep 2021 15:15:48 +0100 Subject: [PATCH 2795/3224] World: remove unused variable --- src/world/World.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index 16d871be2d..3edd783efa 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1804,7 +1804,7 @@ class World implements ChunkManager{ foreach($tx->getBlocks() as [$x, $y, $z, $block]){ $block->position($this, $x, $y, $z); foreach($block->getCollisionBoxes() as $collisionBox){ - if(count($entities = $this->getCollidingEntities($collisionBox)) > 0){ + if(count($this->getCollidingEntities($collisionBox)) > 0){ return false; //Entity in block } } From e1b7bf31bbbf8a0c679bdf238cf7594881d0842b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Sep 2021 15:22:12 +0100 Subject: [PATCH 2796/3224] World: make the second parameter for getCollidingEntities() mandatory and non-nullable the only reason to use getCollidingEntities() instead of getNearbyEntities() is if you have an entity that may or may not be collidable depending on certain conditions. Really, I don't think this logic belongs in World at all, but for now it has to stay, because some other stuff depends on it. --- src/world/World.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 3edd783efa..f4304b08e8 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1804,7 +1804,7 @@ class World implements ChunkManager{ foreach($tx->getBlocks() as [$x, $y, $z, $block]){ $block->position($this, $x, $y, $z); foreach($block->getCollisionBoxes() as $collisionBox){ - if(count($this->getCollidingEntities($collisionBox)) > 0){ + if(count($this->getNearbyEntities($collisionBox)) > 0){ return false; //Entity in block } } @@ -1878,12 +1878,12 @@ class World implements ChunkManager{ * * @return Entity[] */ - public function getCollidingEntities(AxisAlignedBB $bb, ?Entity $entity = null) : array{ + public function getCollidingEntities(AxisAlignedBB $bb, Entity $entity) : array{ $nearby = []; - if($entity === null or $entity->canCollide){ + if($entity->canCollide){ foreach($this->getNearbyEntities($bb, $entity) as $ent){ - if($ent->canBeCollidedWith() and ($entity === null or $entity->canCollideWith($ent))){ + if($ent->canBeCollidedWith() and $entity->canCollideWith($ent)){ $nearby[] = $ent; } } From 92f3a7d206c87b55d8e47361ec9ae3d40ece707d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Sep 2021 15:29:55 +0100 Subject: [PATCH 2797/3224] make-release: allow specifying the nextVer as well as currentVer --- build/make-release.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/build/make-release.php b/build/make-release.php index 59bbb99581..9ecfe50c9b 100644 --- a/build/make-release.php +++ b/build/make-release.php @@ -66,7 +66,7 @@ function replaceVersion(string $versionInfoPath, string $newVersion, bool $isDev */ function main(array $argv) : void{ if(count($argv) < 2){ - fwrite(STDERR, "Arguments: [release version]\n"); + fwrite(STDERR, "Arguments: [release version] [next version]\n"); exit(1); } if(isset($argv[2])){ @@ -74,12 +74,16 @@ function main(array $argv) : void{ }else{ $currentVer = VersionInfo::VERSION(); } - $nextVer = new VersionString(sprintf( - "%u.%u.%u", - $currentVer->getMajor(), - $currentVer->getMinor(), - $currentVer->getPatch() + 1 - )); + if(isset($argv[3])){ + $nextVer = new VersionString($argv[3]); + }else{ + $nextVer = new VersionString(sprintf( + "%u.%u.%u", + $currentVer->getMajor(), + $currentVer->getMinor(), + $currentVer->getPatch() + 1 + )); + } echo "please add appropriate notes to the changelog and press enter..."; fgets(STDIN); From ded778f422a67748adab60ea7456dcdbc0851eb2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Sep 2021 20:11:49 +0100 Subject: [PATCH 2798/3224] Implemented bed bouncing --- src/block/Bed.php | 6 ++++++ src/block/Block.php | 8 ++++++++ src/entity/Entity.php | 14 ++++++++------ src/entity/Living.php | 23 ++++++++++++----------- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/block/Bed.php b/src/block/Bed.php index a9d4873976..913728f1ea 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -29,6 +29,7 @@ use pocketmine\block\utils\ColoredTrait; use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\data\bedrock\DyeColorIdMap; +use pocketmine\entity\Entity; use pocketmine\item\Item; use pocketmine\lang\KnownTranslationFactory; use pocketmine\math\AxisAlignedBB; @@ -170,6 +171,11 @@ class Bed extends Transparent{ } } + public function onEntityLand(Entity $entity) : ?float{ + $entity->fallDistance *= 0.5; + return $entity->getMotion()->y * -3 / 4; // 2/3 in Java, according to the wiki + } + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if(!$down->isTransparent()){ diff --git a/src/block/Block.php b/src/block/Block.php index 247f9e3dc8..2bbdfc1c77 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -562,6 +562,14 @@ class Block{ return true; } + /** + * Called when an entity lands on this block (usually due to falling). + * @return float|null The new vertical velocity of the entity, or null if unchanged. + */ + public function onEntityLand(Entity $entity) : ?float{ + return null; + } + /** * @return AxisAlignedBB[] */ diff --git a/src/entity/Entity.php b/src/entity/Entity.php index b983babeff..c8db00efed 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1022,11 +1022,12 @@ abstract class Entity{ $this->fallDistance = 0.0; } - protected function updateFallState(float $distanceThisTick, bool $onGround) : void{ + protected function updateFallState(float $distanceThisTick, bool $onGround) : ?float{ if($onGround){ if($this->fallDistance > 0){ - $this->onHitGround(); + $newVerticalVelocity = $this->onHitGround(); $this->resetFallDistance(); + return $newVerticalVelocity; } }elseif($distanceThisTick < $this->fallDistance){ //we've fallen some distance (distanceThisTick is negative) @@ -1037,13 +1038,14 @@ abstract class Entity{ //reset it so it will be measured starting from the new, higher position $this->fallDistance = 0; } + return null; } /** * Called when a falling entity hits the ground. */ - protected function onHitGround() : void{ - + protected function onHitGround() : ?float{ + return null; } public function getEyeHeight() : float{ @@ -1183,11 +1185,11 @@ abstract class Entity{ $this->getWorld()->onEntityMoved($this); $this->checkBlockIntersections(); $this->checkGroundState($wantedX, $wantedY, $wantedZ, $dx, $dy, $dz); - $this->updateFallState($dy, $this->onGround); + $postFallVerticalVelocity = $this->updateFallState($dy, $this->onGround); $this->motion = $this->motion->withComponents( $wantedX != $dx ? 0 : null, - $wantedY != $dy ? 0 : null, + $postFallVerticalVelocity ?? ($wantedY != $dy ? 0 : null), $wantedZ != $dz ? 0 : null ); diff --git a/src/entity/Living.php b/src/entity/Living.php index a1c2f9ab3f..d95dfaba14 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -309,7 +309,15 @@ abstract class Living extends Entity{ return ceil($fallDistance - 3 - (($jumpBoost = $this->effectManager->get(VanillaEffects::JUMP_BOOST())) !== null ? $jumpBoost->getEffectLevel() : 0)); } - protected function onHitGround() : void{ + protected function onHitGround() : ?float{ + $fallBlockPos = $this->location->floor(); + $fallBlock = $this->getWorld()->getBlock($fallBlockPos); + if(count($fallBlock->getCollisionBoxes()) === 0){ + $fallBlockPos = $fallBlockPos->down(); + $fallBlock = $this->getWorld()->getBlock($fallBlockPos); + } + $newVerticalVelocity = $fallBlock->onEntityLand($this); + $damage = $this->calculateFallDamage($this->fallDistance); if($damage > 0){ $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FALL, $damage); @@ -319,17 +327,10 @@ abstract class Living extends Entity{ new EntityLongFallSound($this) : new EntityShortFallSound($this) ); - }else{ - $fallBlockPos = $this->location->floor(); - $fallBlock = $this->getWorld()->getBlock($fallBlockPos); - if(count($fallBlock->getCollisionBoxes()) === 0){ - $fallBlockPos = $fallBlockPos->down(); - $fallBlock = $this->getWorld()->getBlock($fallBlockPos); - } - if($fallBlock->getId() !== BlockLegacyIds::AIR){ - $this->broadcastSound(new EntityLandSound($this, $fallBlock)); - } + }elseif($fallBlock->getId() !== BlockLegacyIds::AIR){ + $this->broadcastSound(new EntityLandSound($this, $fallBlock)); } + return $newVerticalVelocity; } /** From 8e2486b96a502d44f564be5444e5b0fb37f8fcf8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Sep 2021 20:14:17 +0100 Subject: [PATCH 2799/3224] Bed: bounce doesn't apply if the entity was sneaking --- src/block/Bed.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/block/Bed.php b/src/block/Bed.php index 913728f1ea..fe419547af 100644 --- a/src/block/Bed.php +++ b/src/block/Bed.php @@ -30,6 +30,7 @@ use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\data\bedrock\DyeColorIdMap; use pocketmine\entity\Entity; +use pocketmine\entity\Living; use pocketmine\item\Item; use pocketmine\lang\KnownTranslationFactory; use pocketmine\math\AxisAlignedBB; @@ -172,6 +173,9 @@ class Bed extends Transparent{ } public function onEntityLand(Entity $entity) : ?float{ + if($entity instanceof Living && $entity->isSneaking()){ + return null; + } $entity->fallDistance *= 0.5; return $entity->getMotion()->y * -3 / 4; // 2/3 in Java, according to the wiki } From df3b112877e97674ba64b1cbe8cf3ff817901214 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Sep 2021 20:46:59 +0100 Subject: [PATCH 2800/3224] Implemented slime blocks --- src/block/BlockFactory.php | 3 +- src/block/Slime.php | 44 +++++++++++++++++++ src/block/VanillaBlocks.php | 2 + .../block_factory_consistency_check.json | 2 +- 4 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 src/block/Slime.php diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 7f5d156ffa..94414da460 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -323,7 +323,7 @@ class BlockFactory{ $this->register(new SeaLantern(new BID(Ids::SEALANTERN, 0), "Sea Lantern", new BlockBreakInfo(0.3))); $this->register(new SeaPickle(new BID(Ids::SEA_PICKLE, 0), "Sea Pickle", BlockBreakInfo::instant())); $this->register(new Skull(new BID(Ids::MOB_HEAD_BLOCK, 0, ItemIds::SKULL, TileSkull::class), "Mob Head", new BlockBreakInfo(1.0))); - + $this->register(new Slime(new BID(Ids::SLIME, 0), "Slime Block", BlockBreakInfo::instant())); $this->register(new Snow(new BID(Ids::SNOW, 0), "Snow Block", new BlockBreakInfo(0.2, BlockToolType::SHOVEL, ToolTier::WOOD()->getHarvestLevel()))); $this->register(new SnowLayer(new BID(Ids::SNOW_LAYER, 0), "Snow Layer", new BlockBreakInfo(0.1, BlockToolType::SHOVEL, ToolTier::WOOD()->getHarvestLevel()))); $this->register(new SoulSand(new BID(Ids::SOUL_SAND, 0), "Soul Sand", new BlockBreakInfo(0.5, BlockToolType::SHOVEL))); @@ -580,7 +580,6 @@ class BlockFactory{ //TODO: minecraft:repeating_command_block //TODO: minecraft:scaffolding //TODO: minecraft:seagrass - //TODO: minecraft:slime //TODO: minecraft:smithing_table //TODO: minecraft:sticky_piston //TODO: minecraft:stonecutter_block diff --git a/src/block/Slime.php b/src/block/Slime.php new file mode 100644 index 0000000000..2212219322 --- /dev/null +++ b/src/block/Slime.php @@ -0,0 +1,44 @@ +isSneaking()){ + return null; + } + $entity->resetFallDistance(); + return -$entity->getMotion()->y; + } + + //TODO: slime blocks should slow entities walking on them to about 0.4x original speed +} diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 7cfd702d07..a1b39b0231 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -489,6 +489,7 @@ use function assert; * @method static SeaLantern SEA_LANTERN() * @method static SeaPickle SEA_PICKLE() * @method static ShulkerBox SHULKER_BOX() + * @method static Slime SLIME() * @method static Furnace SMOKER() * @method static Opaque SMOOTH_QUARTZ() * @method static Slab SMOOTH_QUARTZ_SLAB() @@ -1054,6 +1055,7 @@ final class VanillaBlocks{ self::register("sea_lantern", $factory->get(169, 0)); self::register("sea_pickle", $factory->get(411, 0)); self::register("shulker_box", $factory->get(205, 0)); + self::register("slime", $factory->get(165, 0)); self::register("smoker", $factory->get(453, 2)); self::register("smooth_quartz", $factory->get(155, 3)); self::register("smooth_quartz_slab", $factory->get(421, 1)); diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index fec39fedf7..28308e4a4a 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"knownStates":{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","497":"Tall Grass","498":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1614":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3280":"Shulker Box","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3488":"Dyed Shulker Box","3489":"Dyed Shulker Box","3490":"Dyed Shulker Box","3491":"Dyed Shulker Box","3492":"Dyed Shulker Box","3493":"Dyed Shulker Box","3494":"Dyed Shulker Box","3495":"Dyed Shulker Box","3496":"Dyed Shulker Box","3497":"Dyed Shulker Box","3498":"Dyed Shulker Box","3499":"Dyed Shulker Box","3500":"Dyed Shulker Box","3501":"Dyed Shulker Box","3502":"Dyed Shulker Box","3503":"Dyed Shulker Box","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6274":"Wall Coral Fan","6276":"Wall Coral Fan","6278":"Wall Coral Fan","6280":"Wall Coral Fan","6282":"Wall Coral Fan","6284":"Wall Coral Fan","6286":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7218":"Blast Furnace","7219":"Blast Furnace","7220":"Blast Furnace","7221":"Blast Furnace","7250":"Smoker","7251":"Smoker","7252":"Smoker","7253":"Smoker","7266":"Smoker","7267":"Smoker","7268":"Smoker","7269":"Smoker","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7376":"Bell","7377":"Bell","7378":"Bell","7379":"Bell","7380":"Bell","7381":"Bell","7382":"Bell","7383":"Bell","7384":"Bell","7385":"Bell","7386":"Bell","7387":"Bell","7388":"Bell","7389":"Bell","7390":"Bell","7391":"Bell","7392":"Sweet Berry Bush","7393":"Sweet Berry Bush","7394":"Sweet Berry Bush","7395":"Sweet Berry Bush","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood","7480":"Stripped Oak Wood","7481":"Stripped Spruce Wood","7482":"Stripped Birch Wood","7483":"Stripped Jungle Wood","7484":"Stripped Acacia Wood","7485":"Stripped Dark Oak Wood","7506":"Blast Furnace","7507":"Blast Furnace","7508":"Blast Furnace","7509":"Blast Furnace"},"remaps":{"284":7472,"285":7473,"286":7474,"287":7475,"438":432,"439":432,"446":432,"447":432,"454":448,"455":448,"462":448,"463":448,"496":498,"499":498,"696":688,"697":689,"698":690,"699":691,"700":692,"701":693,"702":694,"703":695,"800":805,"806":805,"807":805,"864":866,"865":866,"870":866,"871":866,"976":978,"977":978,"982":978,"983":978,"992":978,"993":978,"998":978,"999":978,"1036":1027,"1037":1027,"1038":1027,"1039":1027,"1040":1042,"1041":1042,"1046":1042,"1047":1042,"1066":1056,"1067":1056,"1068":1056,"1069":1056,"1070":1056,"1071":1056,"1088":1090,"1089":1090,"1094":1090,"1095":1090,"1148":1139,"1149":1139,"1150":1139,"1151":1139,"1200":1221,"1206":1221,"1207":1221,"1216":1221,"1222":1221,"1223":1221,"1238":1232,"1239":1232,"1246":1232,"1247":1232,"1377":1376,"1378":1376,"1379":1376,"1440":1441,"1443":1441,"1479":1472,"1595":1598,"1596":1598,"1597":1598,"1610":1594,"1611":1614,"1612":1614,"1613":1614,"1615":1599,"2022":2016,"2023":2016,"2030":2016,"2031":2016,"2044":2032,"2045":2032,"2046":2032,"2047":2032,"2080":2082,"2081":2082,"2086":2082,"2087":2082,"2241":2240,"2242":2240,"2243":2240,"2244":2240,"2245":2240,"2246":2240,"2247":2240,"2248":2240,"2249":2240,"2250":2240,"2251":2240,"2252":2240,"2253":2240,"2254":2240,"2255":2240,"2294":2288,"2295":2288,"2302":2288,"2303":2288,"2304":2306,"2310":2306,"2311":2306,"2312":2306,"2313":2306,"2314":2306,"2315":2306,"2316":2306,"2317":2306,"2318":2306,"2319":2306,"2332":2322,"2333":2322,"2334":2322,"2335":2322,"2336":2338,"2337":2338,"2342":2338,"2343":2338,"2392":2386,"2393":2386,"2394":2386,"2395":2386,"2396":2386,"2397":2386,"2398":2386,"2399":2386,"2400":2386,"2401":2386,"2402":2386,"2403":2386,"2404":2386,"2405":2386,"2406":2386,"2407":2386,"2465":2464,"2470":2464,"2471":2464,"2473":2464,"2478":2464,"2479":2464,"2493":2481,"2494":2482,"2520":2512,"2521":2513,"2522":2514,"2523":2515,"2524":2516,"2525":2517,"2604":7476,"2605":7477,"2732":2720,"2832":2834,"2833":2834,"2838":2834,"2839":2834,"2904":2896,"2905":2897,"2906":2898,"2907":2899,"2908":2900,"2909":2901,"2910":2902,"2911":2903,"3100":3091,"3101":3091,"3102":3091,"3103":3091,"3116":3107,"3117":3107,"3118":3107,"3119":3107,"3132":3123,"3133":3123,"3134":3123,"3135":3123,"3148":3139,"3149":3139,"3150":3139,"3151":3139,"3164":3155,"3165":3155,"3166":3155,"3167":3155,"3230":3218,"3232":3237,"3238":3237,"3239":3237,"3240":3245,"3246":3245,"3247":3245,"3264":3269,"3270":3269,"3271":3269,"3272":3277,"3278":3277,"3279":3277,"3334":3328,"3335":3328,"3468":3456,"3504":3506,"3505":3506,"3510":3506,"3511":3506,"3520":3522,"3521":3522,"3526":3522,"3527":3522,"3536":3538,"3537":3538,"3542":3538,"3543":3538,"3552":3554,"3553":3554,"3558":3554,"3559":3554,"3568":3570,"3569":3570,"3574":3570,"3575":3570,"3584":3586,"3585":3586,"3590":3586,"3591":3586,"3600":3602,"3601":3602,"3606":3602,"3607":3602,"3616":3618,"3617":3618,"3622":3618,"3623":3618,"3632":3634,"3633":3634,"3638":3634,"3639":3634,"3648":3650,"3649":3650,"3654":3650,"3655":3650,"3664":3666,"3665":3666,"3670":3666,"3671":3666,"3696":3698,"3697":3698,"3702":3698,"3703":3698,"3712":3714,"3713":3714,"3718":3714,"3719":3714,"3728":3730,"3729":3730,"3734":3730,"3735":3730,"3744":3746,"3745":3746,"3750":3746,"3751":3746,"3760":3762,"3761":3762,"3766":3762,"3767":3762,"3824":3829,"3830":3829,"3831":3829,"3955":3952,"4163":4160,"4179":4176,"4195":4192,"4211":4208,"4227":4224,"4243":4240,"6181":6176,"6182":6176,"6183":6176,"6197":6192,"6198":6192,"6199":6192,"6205":6192,"6206":6192,"6207":6192,"6213":6208,"6214":6208,"6215":6208,"6221":6208,"6222":6208,"6223":6208,"6229":6208,"6230":6208,"6231":6208,"6237":6208,"6238":6208,"6239":6208,"6273":6248,"6275":6248,"6277":6248,"6279":6248,"6281":6248,"6283":6248,"6285":6248,"6287":6248,"6326":6320,"6327":6320,"6334":6320,"6335":6320,"6342":6336,"6343":6336,"6350":6336,"6351":6336,"6358":6352,"6359":6352,"6366":6352,"6367":6352,"6374":6368,"6375":6368,"6382":6368,"6383":6368,"6390":6384,"6391":6384,"6398":6384,"6399":6384,"6694":6688,"6695":6688,"6702":6688,"6703":6688,"6760":6752,"6761":6753,"6762":6754,"6763":6755,"6764":6756,"6765":6757,"6766":6758,"6767":6759,"6776":6768,"6777":6769,"6778":6770,"6779":6771,"6780":6772,"6992":6994,"6993":6994,"6998":6994,"6999":6994,"7072":7074,"7073":7074,"7078":7074,"7079":7074,"7104":7106,"7105":7106,"7110":7106,"7111":7106,"7136":7138,"7137":7138,"7142":7138,"7143":7138,"7168":7170,"7169":7170,"7174":7170,"7175":7170,"7216":7218,"7217":7218,"7222":7218,"7223":7218,"7248":7250,"7249":7250,"7254":7250,"7255":7250,"7264":7250,"7265":7250,"7270":7250,"7271":7250,"7334":7328,"7335":7328,"7342":7328,"7343":7328,"7396":7392,"7397":7392,"7398":7392,"7399":7392,"7504":7218,"7505":7218,"7510":7218,"7511":7218}} \ No newline at end of file +{"knownStates":{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","497":"Tall Grass","498":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1614":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2640":"Slime Block","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3280":"Shulker Box","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3488":"Dyed Shulker Box","3489":"Dyed Shulker Box","3490":"Dyed Shulker Box","3491":"Dyed Shulker Box","3492":"Dyed Shulker Box","3493":"Dyed Shulker Box","3494":"Dyed Shulker Box","3495":"Dyed Shulker Box","3496":"Dyed Shulker Box","3497":"Dyed Shulker Box","3498":"Dyed Shulker Box","3499":"Dyed Shulker Box","3500":"Dyed Shulker Box","3501":"Dyed Shulker Box","3502":"Dyed Shulker Box","3503":"Dyed Shulker Box","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6274":"Wall Coral Fan","6276":"Wall Coral Fan","6278":"Wall Coral Fan","6280":"Wall Coral Fan","6282":"Wall Coral Fan","6284":"Wall Coral Fan","6286":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7218":"Blast Furnace","7219":"Blast Furnace","7220":"Blast Furnace","7221":"Blast Furnace","7250":"Smoker","7251":"Smoker","7252":"Smoker","7253":"Smoker","7266":"Smoker","7267":"Smoker","7268":"Smoker","7269":"Smoker","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7376":"Bell","7377":"Bell","7378":"Bell","7379":"Bell","7380":"Bell","7381":"Bell","7382":"Bell","7383":"Bell","7384":"Bell","7385":"Bell","7386":"Bell","7387":"Bell","7388":"Bell","7389":"Bell","7390":"Bell","7391":"Bell","7392":"Sweet Berry Bush","7393":"Sweet Berry Bush","7394":"Sweet Berry Bush","7395":"Sweet Berry Bush","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood","7480":"Stripped Oak Wood","7481":"Stripped Spruce Wood","7482":"Stripped Birch Wood","7483":"Stripped Jungle Wood","7484":"Stripped Acacia Wood","7485":"Stripped Dark Oak Wood","7506":"Blast Furnace","7507":"Blast Furnace","7508":"Blast Furnace","7509":"Blast Furnace"},"remaps":{"284":7472,"285":7473,"286":7474,"287":7475,"438":432,"439":432,"446":432,"447":432,"454":448,"455":448,"462":448,"463":448,"496":498,"499":498,"696":688,"697":689,"698":690,"699":691,"700":692,"701":693,"702":694,"703":695,"800":805,"806":805,"807":805,"864":866,"865":866,"870":866,"871":866,"976":978,"977":978,"982":978,"983":978,"992":978,"993":978,"998":978,"999":978,"1036":1027,"1037":1027,"1038":1027,"1039":1027,"1040":1042,"1041":1042,"1046":1042,"1047":1042,"1066":1056,"1067":1056,"1068":1056,"1069":1056,"1070":1056,"1071":1056,"1088":1090,"1089":1090,"1094":1090,"1095":1090,"1148":1139,"1149":1139,"1150":1139,"1151":1139,"1200":1221,"1206":1221,"1207":1221,"1216":1221,"1222":1221,"1223":1221,"1238":1232,"1239":1232,"1246":1232,"1247":1232,"1377":1376,"1378":1376,"1379":1376,"1440":1441,"1443":1441,"1479":1472,"1595":1598,"1596":1598,"1597":1598,"1610":1594,"1611":1614,"1612":1614,"1613":1614,"1615":1599,"2022":2016,"2023":2016,"2030":2016,"2031":2016,"2044":2032,"2045":2032,"2046":2032,"2047":2032,"2080":2082,"2081":2082,"2086":2082,"2087":2082,"2241":2240,"2242":2240,"2243":2240,"2244":2240,"2245":2240,"2246":2240,"2247":2240,"2248":2240,"2249":2240,"2250":2240,"2251":2240,"2252":2240,"2253":2240,"2254":2240,"2255":2240,"2294":2288,"2295":2288,"2302":2288,"2303":2288,"2304":2306,"2310":2306,"2311":2306,"2312":2306,"2313":2306,"2314":2306,"2315":2306,"2316":2306,"2317":2306,"2318":2306,"2319":2306,"2332":2322,"2333":2322,"2334":2322,"2335":2322,"2336":2338,"2337":2338,"2342":2338,"2343":2338,"2392":2386,"2393":2386,"2394":2386,"2395":2386,"2396":2386,"2397":2386,"2398":2386,"2399":2386,"2400":2386,"2401":2386,"2402":2386,"2403":2386,"2404":2386,"2405":2386,"2406":2386,"2407":2386,"2465":2464,"2470":2464,"2471":2464,"2473":2464,"2478":2464,"2479":2464,"2493":2481,"2494":2482,"2520":2512,"2521":2513,"2522":2514,"2523":2515,"2524":2516,"2525":2517,"2604":7476,"2605":7477,"2732":2720,"2832":2834,"2833":2834,"2838":2834,"2839":2834,"2904":2896,"2905":2897,"2906":2898,"2907":2899,"2908":2900,"2909":2901,"2910":2902,"2911":2903,"3100":3091,"3101":3091,"3102":3091,"3103":3091,"3116":3107,"3117":3107,"3118":3107,"3119":3107,"3132":3123,"3133":3123,"3134":3123,"3135":3123,"3148":3139,"3149":3139,"3150":3139,"3151":3139,"3164":3155,"3165":3155,"3166":3155,"3167":3155,"3230":3218,"3232":3237,"3238":3237,"3239":3237,"3240":3245,"3246":3245,"3247":3245,"3264":3269,"3270":3269,"3271":3269,"3272":3277,"3278":3277,"3279":3277,"3334":3328,"3335":3328,"3468":3456,"3504":3506,"3505":3506,"3510":3506,"3511":3506,"3520":3522,"3521":3522,"3526":3522,"3527":3522,"3536":3538,"3537":3538,"3542":3538,"3543":3538,"3552":3554,"3553":3554,"3558":3554,"3559":3554,"3568":3570,"3569":3570,"3574":3570,"3575":3570,"3584":3586,"3585":3586,"3590":3586,"3591":3586,"3600":3602,"3601":3602,"3606":3602,"3607":3602,"3616":3618,"3617":3618,"3622":3618,"3623":3618,"3632":3634,"3633":3634,"3638":3634,"3639":3634,"3648":3650,"3649":3650,"3654":3650,"3655":3650,"3664":3666,"3665":3666,"3670":3666,"3671":3666,"3696":3698,"3697":3698,"3702":3698,"3703":3698,"3712":3714,"3713":3714,"3718":3714,"3719":3714,"3728":3730,"3729":3730,"3734":3730,"3735":3730,"3744":3746,"3745":3746,"3750":3746,"3751":3746,"3760":3762,"3761":3762,"3766":3762,"3767":3762,"3824":3829,"3830":3829,"3831":3829,"3955":3952,"4163":4160,"4179":4176,"4195":4192,"4211":4208,"4227":4224,"4243":4240,"6181":6176,"6182":6176,"6183":6176,"6197":6192,"6198":6192,"6199":6192,"6205":6192,"6206":6192,"6207":6192,"6213":6208,"6214":6208,"6215":6208,"6221":6208,"6222":6208,"6223":6208,"6229":6208,"6230":6208,"6231":6208,"6237":6208,"6238":6208,"6239":6208,"6273":6248,"6275":6248,"6277":6248,"6279":6248,"6281":6248,"6283":6248,"6285":6248,"6287":6248,"6326":6320,"6327":6320,"6334":6320,"6335":6320,"6342":6336,"6343":6336,"6350":6336,"6351":6336,"6358":6352,"6359":6352,"6366":6352,"6367":6352,"6374":6368,"6375":6368,"6382":6368,"6383":6368,"6390":6384,"6391":6384,"6398":6384,"6399":6384,"6694":6688,"6695":6688,"6702":6688,"6703":6688,"6760":6752,"6761":6753,"6762":6754,"6763":6755,"6764":6756,"6765":6757,"6766":6758,"6767":6759,"6776":6768,"6777":6769,"6778":6770,"6779":6771,"6780":6772,"6992":6994,"6993":6994,"6998":6994,"6999":6994,"7072":7074,"7073":7074,"7078":7074,"7079":7074,"7104":7106,"7105":7106,"7110":7106,"7111":7106,"7136":7138,"7137":7138,"7142":7138,"7143":7138,"7168":7170,"7169":7170,"7174":7170,"7175":7170,"7216":7218,"7217":7218,"7222":7218,"7223":7218,"7248":7250,"7249":7250,"7254":7250,"7255":7250,"7264":7250,"7265":7250,"7270":7250,"7271":7250,"7334":7328,"7335":7328,"7342":7328,"7343":7328,"7396":7392,"7397":7392,"7398":7392,"7399":7392,"7504":7218,"7505":7218,"7510":7218,"7511":7218}} \ No newline at end of file From 956780c6a6ae5a23124a5086bb2aa7b67cf694c9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 5 Sep 2021 23:59:04 +0100 Subject: [PATCH 2801/3224] Entity: add getters and setters for fallDistance --- src/entity/Entity.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index c8db00efed..9ee67a9b1a 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1018,6 +1018,12 @@ abstract class Entity{ ); } + public function getFallDistance() : float{ return $this->fallDistance; } + + public function setFallDistance(float $fallDistance) : void{ + $this->fallDistance = $fallDistance; + } + public function resetFallDistance() : void{ $this->fallDistance = 0.0; } From 931c3ed77d2ee10f418723855da8c0af2f3a810e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 6 Sep 2021 12:53:37 +0100 Subject: [PATCH 2802/3224] Entity: fixed current movement not being accounted for in fall height this caused incorrect damage when falling from heights, as well as a bug in #4434. --- src/entity/Entity.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 9ee67a9b1a..918bb6d1c8 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1029,13 +1029,7 @@ abstract class Entity{ } protected function updateFallState(float $distanceThisTick, bool $onGround) : ?float{ - if($onGround){ - if($this->fallDistance > 0){ - $newVerticalVelocity = $this->onHitGround(); - $this->resetFallDistance(); - return $newVerticalVelocity; - } - }elseif($distanceThisTick < $this->fallDistance){ + if($distanceThisTick < $this->fallDistance){ //we've fallen some distance (distanceThisTick is negative) //or we ascended back towards where fall distance was measured from initially (distanceThisTick is positive but less than existing fallDistance) $this->fallDistance -= $distanceThisTick; @@ -1044,6 +1038,11 @@ abstract class Entity{ //reset it so it will be measured starting from the new, higher position $this->fallDistance = 0; } + if($onGround && $this->fallDistance > 0){ + $newVerticalVelocity = $this->onHitGround(); + $this->resetFallDistance(); + return $newVerticalVelocity; + } return null; } From 710345d4b02eed27e54633a3fedce2b0e5bbd18a Mon Sep 17 00:00:00 2001 From: Cosmic <83475653+Cosmic5173@users.noreply.github.com> Date: Mon, 6 Sep 2021 07:55:52 -0400 Subject: [PATCH 2803/3224] Implemented Farmland turns to dirt when jumped on. (#4434) --- src/block/Farmland.php | 15 ++++++ .../entity/EntityTrampleFarmlandEvent.php | 48 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 src/event/entity/EntityTrampleFarmlandEvent.php diff --git a/src/block/Farmland.php b/src/block/Farmland.php index 058567929f..81f6a43e0c 100644 --- a/src/block/Farmland.php +++ b/src/block/Farmland.php @@ -24,9 +24,13 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\entity\Entity; +use pocketmine\entity\Living; +use pocketmine\event\entity\EntityTrampleFarmlandEvent; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; +use function lcg_value; class Farmland extends Transparent{ @@ -86,6 +90,17 @@ class Farmland extends Transparent{ } } + public function onEntityLand(Entity $entity) : ?float{ + if($entity instanceof Living && lcg_value() < $entity->getFallDistance() - 0.5){ + $ev = new EntityTrampleFarmlandEvent($entity, $this); + $ev->call(); + if(!$ev->isCancelled()){ + $this->getPosition()->getWorld()->setBlock($this->getPosition(), VanillaBlocks::DIRT()); + } + } + return null; + } + protected function canHydrate() : bool{ //TODO: check rain $start = $this->position->add(-4, 0, -4); diff --git a/src/event/entity/EntityTrampleFarmlandEvent.php b/src/event/entity/EntityTrampleFarmlandEvent.php new file mode 100644 index 0000000000..feea85bfe6 --- /dev/null +++ b/src/event/entity/EntityTrampleFarmlandEvent.php @@ -0,0 +1,48 @@ + + */ +class EntityTrampleFarmlandEvent extends EntityEvent implements Cancellable{ + use CancellableTrait; + + /** @var Block */ + private $block; + + public function __construct(Living $entity, Block $block){ + $this->entity = $entity; + $this->block = $block; + } + + public function getBlock() : Block{ + return $this->block; + } +} From 580b53eb9b638e632ae41a7a1be12f6d25f5c423 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Sep 2021 12:05:13 +0100 Subject: [PATCH 2804/3224] update changelog [ci skip] --- changelogs/4.0-snapshot.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 724e58e3b3..522e5cf80d 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -210,7 +210,8 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - Blocks with IDs >= 256 are now supported. - Block state and variant metadata have been separated. - Variant is considered an extension of ID and is immutable. - - `Block->setDamage()` has been removed. `Block->readStateFromData()` is now used for state deserialization. + - `Block->setDamage()` has been removed. + - All blocks now have getters and setters for their appropriate block properties, such as facing, lit/unlit, colour (in some cases), and many more. These should be used instead of metadata. - Tile entities are now created and deleted automatically when `World->setBlock()` is used with a block that requires a tile entity. - Some tile entities' API has been exposed on their corresponding `Block` classes, with the tile entity classes being deprecated. - The `pocketmine\tile` namespace has been relocated to `pocketmine\block\tile`. @@ -230,6 +231,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Block->isFullCube()` - The following hooks have been added: - `Block->onAttack()`: called when a player in survival left-clicks the block to try to start breaking it + - `Block->onEntityLand()`: called when an entity lands on this block after falling (from any distance) - `Block->onPostPlace()`: called directly after placement in the world, handles things like rail connections and chest pairing - The following API methods have been renamed: - `Block->getDamage()` -> `Block->getMeta()` @@ -306,8 +308,11 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Entity->width`: moved to `EntitySizeInfo`; use `Entity->size` instead - `Entity->eyeHeight`: moved to `EntitySizeInfo`; use `Entity->size` instead - The following API methods have been added: + - `Entity->getFallDistance()` + - `Entity->setFallDistance()` - `ItemEntity->getDespawnDelay()` - `ItemEntity->setDespawnDelay()` + - `Living->calculateFallDamage()`: this is `protected`, and may be overridden by subclasses to provide custom damage logic - `Human->getHungerManager()` - `Human->getXpManager()` - The following methods have signature changes: @@ -320,6 +325,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `HungerManager`: contains hunger-management functionality extracted from `Human` - `ExperienceManager`: contains XP-management functionality extracted from `Human` - The following API methods have been moved / renamed: + - `Entity->fall()` -> `Entity->onHitGround()` (and visibility changed to `protected` from `public`) - `Living->removeAllEffects()` -> `EffectManager->clear()` - `Living->removeEffect()` -> `EffectManager->remove()` - `Living->addEffect()` -> `EffectManager->add()` @@ -511,6 +517,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `EntityItemPickupEvent`: player (or other entity) picks up a dropped item (or arrow). Replaces `InventoryPickupItemEvent` and `InventoryPickupArrowEvent`. - Unlike its predecessors, this event supports changing the destination inventory. - If the destination inventory is `null`, the item will be destroyed. This is usually seen for creative players with full inventories. + - `EntityTrampleFarmlandEvent`: mob (or player) jumping on farmland causing it to turn to dirt - `StructureGrowEvent`: called when trees or bamboo grow (or any other multi-block plant structure). - The following events have been removed: - `EntityArmorChangeEvent` @@ -589,6 +596,9 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` ### Item #### General - A new `VanillaItems` class has been added, which contains static methods for creating any currently-known item type. This should be preferred instead of use of `ItemFactory::get()` where constants were used. +- `StringToItemParser` has been added, which allows mapping any string to any item, irrespective of IDs. These mappings are used by `/give` and `/clear`, and are made with custom plugin aliases in mind. + - Yes, this means you can finally add your own custom aliases to `/give` without ugly hacks! +- `LegacyStringToItemParser` has been added, which is a slightly more dynamic (but still inadvisable) replacement for `ItemFactory::fromString()`. - `Item->count` is no longer public. - The hierarchy of writable books has been changed: `WritableBook` and `WrittenBook` now extend `WritableBookBase`. - The following API methods have signature changes: @@ -1005,6 +1015,8 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - The following API methods have been added: - `World->registerChunkListener()` - `World->unregisterChunkListener()` + - `World->getBlockAt()` (accepts int x/y/z instead of Vector3, faster for some use cases) + - `World->setBlockAt()` (accepts int x/y/z instead of Vector3, faster for some use cases) - `Chunk->isDirty()` (replacement for `Chunk->hasChanged()`) - `Chunk->getDirtyFlag()` (more granular component-based chunk dirty-flagging, used to avoid saving unmodified parts of the chunk) - `Chunk->setDirty()` @@ -1210,6 +1222,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - note block - red, green, blue and purple torches (from Minecraft: Education Edition) - sea pickle + - slime - smoker - underwater torches (from Minecraft: Education Edition) - additional wood variants of the following: @@ -1228,9 +1241,14 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - red nether brick - red sandstone (and variants) - stone-like slabs of many variants +- Non-player entities now bounce when falling on beds. +- Players and mobs now receive reduced fall damage when falling on beds. ### Items - Implemented the following items: - records - compounds (from Minecraft: Education Edition) - black, brown, blue and white dyes + +### Inventory +- Implemented offhand inventory. From 9a745ffc09059a9dd27ca0002a4182648c32e950 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Sep 2021 12:06:36 +0100 Subject: [PATCH 2805/3224] Do not enforce suffix checks for API versions --- src/plugin/ApiVersion.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugin/ApiVersion.php b/src/plugin/ApiVersion.php index 2cf11a7226..5a2bb035b5 100644 --- a/src/plugin/ApiVersion.php +++ b/src/plugin/ApiVersion.php @@ -45,7 +45,7 @@ final class ApiVersion{ //Format: majorVersion.minorVersion.patch (3.0.0) // or: majorVersion.minorVersion.patch-devBuild (3.0.0-alpha1) if($version->getBaseVersion() !== $myVersion->getBaseVersion()){ - if($version->getMajor() !== $myVersion->getMajor() or $version->getSuffix() !== $myVersion->getSuffix()){ + if($version->getMajor() !== $myVersion->getMajor()){ continue; } From da0482d330311d147a1ca1cfd98369ef737d16a7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Sep 2021 12:24:16 +0100 Subject: [PATCH 2806/3224] Solidify version comparison --- src/utils/VersionString.php | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/utils/VersionString.php b/src/utils/VersionString.php index 59a4deddad..1dd666c9f1 100644 --- a/src/utils/VersionString.php +++ b/src/utils/VersionString.php @@ -117,18 +117,16 @@ class VersionString{ if($diff){ return $tNumber - $number; } - if($number > $tNumber){ - return -1; //Target is older - }elseif($number < $tNumber){ - return 1; //Target is newer - }elseif($target->isDev() and !$this->isDev()){ - return -1; //Dev builds of the same version are always considered older than a release - }elseif($target->getBuild() > $this->getBuild()){ - return 1; - }elseif($target->getBuild() < $this->getBuild()){ - return -1; - }else{ - return 0; //Same version + + if(($result = $tNumber <=> $number) !== 0){ + return $result; } + if($target->isDev() !== $this->isDev()){ + return $this->isDev() ? 1 : -1; //Dev builds of the same version are always considered older than a release + } + if(($target->getSuffix() === "") !== ($this->suffix === "")){ + return $this->suffix !== "" ? 1 : -1; //alpha/beta/whatever releases are always considered older than a non-suffixed version + } + return $target->getBuild() <=> $this->getBuild(); } } From dd4abe7f7a28cb9a7d082f33c9927daa41a658d5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Sep 2021 12:27:24 +0100 Subject: [PATCH 2807/3224] Updated test --- tests/phpunit/plugin/ApiVersionTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/plugin/ApiVersionTest.php b/tests/phpunit/plugin/ApiVersionTest.php index 4d348ee0db..bd7c890326 100644 --- a/tests/phpunit/plugin/ApiVersionTest.php +++ b/tests/phpunit/plugin/ApiVersionTest.php @@ -41,8 +41,8 @@ class ApiVersionTest extends TestCase{ yield ["4.0.0", "3.0.0", false]; yield ["3.0.0", "3.0.1", false]; //bug fix patch required yield ["3.0.1", "3.0.0", true]; - yield ["3.0.0-ALPHA1", "3.0.0-ALPHA2", false]; - yield ["3.0.0-ALPHA2", "3.0.0-ALPHA1", false]; + yield ["3.0.0-ALPHA1", "3.0.0-ALPHA2", true]; + yield ["3.0.0-ALPHA2", "3.0.0-ALPHA1", true]; //at the time these weren't actually compatible, but these are just test samples. yield ["3.0.0-ALPHA1", "3.0.0-ALPHA1", true]; yield ["3.0.0-ALPHA1", "4.0.0-ALPHA1", false]; } From 06a0e37b94c9f048c1e54b6efe564483c3342635 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Sep 2021 12:47:41 +0100 Subject: [PATCH 2808/3224] Fixed build info generation for PM4 --- build/generate-build-info-json.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build/generate-build-info-json.php b/build/generate-build-info-json.php index 57828c3722..6428ce239c 100644 --- a/build/generate-build-info-json.php +++ b/build/generate-build-info-json.php @@ -30,10 +30,10 @@ if(count($argv) !== 4){ echo json_encode([ "php_version" => sprintf("%d.%d", PHP_MAJOR_VERSION, PHP_MINOR_VERSION), - "base_version" => \pocketmine\BASE_VERSION, - "build" => \pocketmine\BUILD_NUMBER, - "is_dev" => \pocketmine\IS_DEVELOPMENT_BUILD, - "channel" => \pocketmine\BUILD_CHANNEL, + "base_version" => \pocketmine\VersionInfo::BASE_VERSION, + "build" => \pocketmine\VersionInfo::BUILD_NUMBER, + "is_dev" => \pocketmine\VersionInfo::IS_DEVELOPMENT_BUILD, + "channel" => \pocketmine\VersionInfo::BUILD_CHANNEL, "git_commit" => $argv[1], "mcpe_version" => \pocketmine\network\mcpe\protocol\ProtocolInfo::MINECRAFT_VERSION_NETWORK, "date" => time(), //TODO: maybe we should embed this in VersionInfo? From 7276e9610c088fc3bd4e3dfd75591061958a0ca6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Sep 2021 12:49:39 +0100 Subject: [PATCH 2809/3224] fixing draft-release for PM4 --- .github/workflows/draft-release.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml index 4015c96c27..60f7857ef9 100644 --- a/.github/workflows/draft-release.yml +++ b/.github/workflows/draft-release.yml @@ -39,10 +39,10 @@ jobs: run: | BUILD_NUMBER=2000+$GITHUB_RUN_NUMBER #to stay above jenkins echo "Build number: $BUILD_NUMBER" - sed -i "s/const BUILD_NUMBER = 0/const BUILD_NUMBER = ${BUILD_NUMBER}/" src/pocketmine/VersionInfo.php + sed -i "s/const BUILD_NUMBER = 0/const BUILD_NUMBER = ${BUILD_NUMBER}/" src/VersionInfo.php - name: Minify BedrockData JSON files - run: php src/pocketmine/resources/vanilla/.minify_json.php + run: php resources/vanilla/.minify_json.php - name: Run preprocessor run: | @@ -73,10 +73,10 @@ jobs: - name: Get PocketMine-MP release version id: get-pm-version run: | - echo ::set-output name=PM_VERSION::$(php -r 'require "vendor/autoload.php"; echo \pocketmine\BASE_VERSION;') + echo ::set-output name=PM_VERSION::$(php -r 'require "vendor/autoload.php"; echo \pocketmine\VersionInfo::BASE_VERSION;') echo ::set-output name=MCPE_VERSION::$(php -r 'require "vendor/autoload.php"; echo \pocketmine\network\mcpe\protocol\ProtocolInfo::MINECRAFT_VERSION_NETWORK;') - echo ::set-output name=PM_VERSION_SHORT::$(php -r 'require "vendor/autoload.php"; $v = explode(".", \pocketmine\BASE_VERSION); array_pop($v); echo implode(".", $v);') - echo ::set-output name=PM_VERSION_MD::$(php -r 'require "vendor/autoload.php"; echo str_replace(".", "", \pocketmine\BASE_VERSION);') + echo ::set-output name=PM_VERSION_SHORT::$(php -r 'require "vendor/autoload.php"; $v = explode(".", \pocketmine\VersionInfo::BASE_VERSION); array_pop($v); echo implode(".", $v);') + echo ::set-output name=PM_VERSION_MD::$(php -r 'require "vendor/autoload.php"; echo str_replace(".", "", \pocketmine\VersionInfo::BASE_VERSION);') - name: Generate build info run: php build/generate-build-info-json.php ${{ github.sha }} ${{ steps.get-pm-version.outputs.PM_VERSION }} ${{ github.repository }} > build_info.json From 57e2b1613944ed8680b8e2763b3c619b4cafd335 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Sep 2021 14:04:52 +0100 Subject: [PATCH 2810/3224] Dropped PreProcessor --- .github/workflows/draft-release.yml | 31 ----------- .github/workflows/main.yml | 81 ----------------------------- .gitmodules | 3 -- .php-cs-fixer.php | 2 - BUILDING.md | 4 -- build/preprocessor | 1 - changelogs/4.0-snapshot.md | 1 + phpstan.neon.dist | 3 -- 8 files changed, 1 insertion(+), 125 deletions(-) delete mode 160000 build/preprocessor diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml index 60f7857ef9..6c3d25996e 100644 --- a/.github/workflows/draft-release.yml +++ b/.github/workflows/draft-release.yml @@ -44,29 +44,6 @@ jobs: - name: Minify BedrockData JSON files run: php resources/vanilla/.minify_json.php - - name: Run preprocessor - run: | - PM_PREPROCESSOR_PATH="$GITHUB_WORKSPACE/build/preprocessor" - php "$PM_PREPROCESSOR_PATH/PreProcessor.php" --path=src --multisize || (echo "Preprocessor exited with code $?" && exit 1) - #dump the diff of preprocessor replacements to a patch in case it has bugs - git diff > preprocessor_diff.patch - VENDOR_PM="$GITHUB_WORKSPACE/vendor" - VENDOR_PM_BACKUP="$GITHUB_WORKSPACE/vendor-before-preprocess" - cp -r "$VENDOR_PM" "$VENDOR_PM_BACKUP" - for f in $(ls $VENDOR_PM/pocketmine); do - echo "Processing directory \"$f\"..." - php "$PM_PREPROCESSOR_PATH/PreProcessor.php" --path="$VENDOR_PM/pocketmine/$f" --multisize || (echo "Preprocessor exited with code $?" && exit 1) - echo "Checking for changes in \"$f\"..." - DIFF=$(git diff --no-index "$VENDOR_PM_BACKUP/pocketmine/$f" "$VENDOR_PM/pocketmine/$f" || true) - if [ "$DIFF" != "" ]; then - PATCH="$GITHUB_WORKSPACE/preprocessor_diff_$f.patch" - echo "$DIFF" > "$PATCH" - echo "Generated patch file \"$PATCH\"" - else - echo "No diff generated for \"$f\" (preprocessor made no changes)" - fi - done - - name: Build PocketMine-MP.phar run: php -dphar.readonly=0 build/server-phar.php --git ${{ github.sha }} @@ -103,11 +80,3 @@ jobs: **For Minecraft: Bedrock Edition ${{ steps.get-pm-version.outputs.MCPE_VERSION }}** Please see the [changelogs](/changelogs/${{ steps.get-pm-version.outputs.PM_VERSION_SHORT }}.md#${{ steps.get-pm-version.outputs.PM_VERSION_MD }}) for details. - - - name: Upload preprocessor diffs - uses: actions/upload-artifact@v2 - if: always() - with: - name: preprocessor_diffs - path: ${{ github.workspace }}/preprocessor_diff*.patch - diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9ef9bf38c2..2176401d39 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -183,87 +183,6 @@ jobs: - name: Run integration tests run: ./tests/travis.sh -t4 - preprocessor: - name: Preprocessor tests - needs: build-php - runs-on: ${{ matrix.image }} - strategy: - fail-fast: false - matrix: - image: [ubuntu-20.04] - php: [8.0.9] - - steps: - - uses: actions/checkout@v2 - with: - submodules: true - - - name: Restore PHP build cache - id: php-build-cache - uses: actions/cache@v2 - with: - path: "./bin" - key: "php-build-generic-${{ matrix.php }}-${{ matrix.image }}-${{ hashFiles('./tests/gh-actions/build.sh') }}" - - - name: Kill build on PHP build cache miss (should never happen) - if: steps.php-build-cache.outputs.cache-hit != 'true' - run: exit 1 - - - name: Install cached PHP's dependencies - if: steps.php-build-cache.outputs.cache-hit == 'true' - run: ./tests/gh-actions/install-dependencies.sh - - - name: Prefix PHP to PATH - run: echo "$(pwd)/bin/php7/bin" >> $GITHUB_PATH - - - name: Install Composer - run: curl -sS https://getcomposer.org/installer | php - - - name: Restore Composer package cache - uses: actions/cache@v2 - with: - path: | - ~/.cache/composer/files - ~/.cache/composer/vcs - key: "composer-v2-cache-${{ matrix.php }}-${{ hashFiles('./composer.lock') }}" - restore-keys: | - composer-v2-cache- - - - name: Install Composer dependencies - run: php composer.phar install --no-dev --prefer-dist --no-interaction - - - name: Run preprocessor - run: | - PM_PREPROCESSOR_PATH="$GITHUB_WORKSPACE/build/preprocessor" - php "$PM_PREPROCESSOR_PATH/PreProcessor.php" --path=src --multisize || (echo "Preprocessor exited with code $?" && exit 1) - - #dump the diff of preprocessor replacements to a patch in case it has bugs - git diff > preprocessor_diff.patch - - VENDOR_PM="$GITHUB_WORKSPACE/vendor" - VENDOR_PM_BACKUP="$GITHUB_WORKSPACE/vendor-before-preprocess" - cp -r "$VENDOR_PM" "$VENDOR_PM_BACKUP" - for f in $(ls $VENDOR_PM/pocketmine); do - echo "Processing directory \"$f\"..." - php "$PM_PREPROCESSOR_PATH/PreProcessor.php" --path="$VENDOR_PM/pocketmine/$f/src" --multisize || (echo "Preprocessor exited with code $?" && exit 1) - echo "Checking for changes in \"$f\"..." - DIFF=$(git diff --no-index "$VENDOR_PM_BACKUP/pocketmine/$f" "$VENDOR_PM/pocketmine/$f" || true) - if [ "$DIFF" != "" ]; then - PATCH="$GITHUB_WORKSPACE/preprocessor_diff_$f.patch" - echo "$DIFF" > "$PATCH" - echo "Generated patch file \"$PATCH\"" - else - echo "No diff generated for \"$f\" (preprocessor made no changes)" - fi - done - - - name: Upload preprocessor diffs - uses: actions/upload-artifact@v2 - if: always() - with: - name: preprocessor_diffs_${{ matrix.php }}_${{ matrix.image }} - path: ${{ github.workspace }}/preprocessor_diff*.patch - codestyle: name: Code Style checks runs-on: ubuntu-20.04 diff --git a/.gitmodules b/.gitmodules index 84120f0650..ec6560fd14 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "resources/locale"] path = resources/locale url = https://github.com/pmmp/Language.git -[submodule "tests/preprocessor"] - path = build/preprocessor - url = https://github.com/pmmp/preprocessor.git [submodule "tests/plugins/DevTools"] path = tests/plugins/DevTools url = https://github.com/pmmp/DevTools.git diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index 925c1cbcae..659d767483 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -6,8 +6,6 @@ $finder = PhpCsFixer\Finder::create() ->in(__DIR__ . '/tests') ->in(__DIR__ . '/tools') ->notPath('plugins/DevTools') - ->notPath('preprocessor') - ->notContains('#ifndef COMPILE') //preprocessor will break if these are changed ->notName('PocketMine.php'); return (new PhpCsFixer\Config) diff --git a/BUILDING.md b/BUILDING.md index 4a2b132b05..6860967bc4 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -24,10 +24,6 @@ If you use a custom binary, you'll need to replace `composer` usages in this gui ## Optimizing for release builds 1. Add the flags `--no-dev --classmap-authoritative` to your `composer install` command. This will reduce build size and improve autoloading speed. -2. Preprocess the source code by running `build/preprocessor/PreProcessor.php`. Usage instructions are provided in `build/preprocessor/README.md`. - -### Note -Preprocessor requires that the `cpp` (c preprocessor) is available in your PATH. ## Building `PocketMine-MP.phar` Run `composer make-server` using your preferred PHP binary. It'll drop a `PocketMine-MP.phar` into the current working directory. diff --git a/build/preprocessor b/build/preprocessor deleted file mode 160000 index 8a3163aad6..0000000000 --- a/build/preprocessor +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8a3163aad6bb8683a11d78fb907d2f43b0b0fc0a diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 522e5cf80d..01b5b5feb1 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -75,6 +75,7 @@ This major version features substantial changes throughout the core, including s - Spawning underneath bedrock on first server join on very slow machines (or when the machine was under very high load) - Spawning inside blocks (or above the ground) when respawning with a custom spawn position set - Player spawn positions sticking to the old location when world spawn position changed - this was because the world spawn at time of player creation was used as the player's custom spawn, so the bug will persist for older player data, but will work as expected for new players. +- PreProcessor is removed from builds due to high maintenance cost and low benefit. Its usage is now discouraged. ### Commands - The `/reload` command has been removed. diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 5fc9bed4e3..762eaefc91 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -38,9 +38,6 @@ parameters: - tests/phpunit - tests/plugins/TesterPlugin - tools - excludePaths: - analyseAndScan: - - build/preprocessor dynamicConstantNames: - pocketmine\VersionInfo::IS_DEVELOPMENT_BUILD - pocketmine\DEBUG From 210b9c7b75fe3183600e85f9f4a24ef125fcb1cf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Sep 2021 14:19:29 +0100 Subject: [PATCH 2811/3224] Release 4.0.0-BETA1 --- changelogs/{4.0-snapshot.md => 4.0.md} | 12 +++++++++++- src/VersionInfo.php | 6 +++--- 2 files changed, 14 insertions(+), 4 deletions(-) rename changelogs/{4.0-snapshot.md => 4.0.md} (99%) diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0.md similarity index 99% rename from changelogs/4.0-snapshot.md rename to changelogs/4.0.md index 01b5b5feb1..2b3833f7a2 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0.md @@ -1,7 +1,17 @@ -# 4.0.0-SNAPSHOT-1907XX (2019-07-XX) +# 4.0.0-BETA1 +Released 7th September 2021. This major version features substantial changes throughout the core, including significant API changes, new world format support, performance improvements and a network revamp. +Please note that this is a BETA release and is not finalized. While no significant changes are expected between now and release, the API might still be changed. + +Please also note that this changelog is provided on a best-effort basis, and it's possible some changes might not have been mentioned here. +If you find any omissions, please submit pull requests to add them. + +## WARNING +This is NOT a stable release. PMMP accepts no responsibility or liability for any damages incurred by using this build. +It should be used for TESTING purposes only. + ## Contents * [Core](#core) + [General](#general) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index d6bfa93cfc..b61191507c 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -29,10 +29,10 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "4.0.0"; - public const IS_DEVELOPMENT_BUILD = true; + public const BASE_VERSION = "4.0.0-BETA1"; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_NUMBER = 0; - public const BUILD_CHANNEL = ""; + public const BUILD_CHANNEL = "beta"; private function __construct(){ //NOOP From ac55b21fb4dcfe4ef5ed88994a9b28384de06bfa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Sep 2021 14:19:29 +0100 Subject: [PATCH 2812/3224] 4.0.0-BETA2 is next --- src/VersionInfo.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index b61191507c..c9fdad2dd2 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -29,10 +29,10 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "4.0.0-BETA1"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "4.0.0-BETA2"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_NUMBER = 0; - public const BUILD_CHANNEL = "beta"; + public const BUILD_CHANNEL = ""; private function __construct(){ //NOOP From 72fb49b35616b6ecf6c9f012ebfac966fbec73dc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Sep 2021 20:18:53 +0100 Subject: [PATCH 2813/3224] World: add notifyNeighbourBlockUpdate() to allow triggering neighbour block updates on blocks manually this can be useful if blocks were modified asynchronously. --- src/world/World.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index f4304b08e8..1675aef96d 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1164,6 +1164,17 @@ class World implements ChunkManager{ } } + /** + * Notify the blocks at and around the position that the block at the position may have changed. + * This will cause onNeighbourBlockUpdate() to be called for these blocks. + */ + public function notifyNeighbourBlockUpdate(Vector3 $pos) : void{ + $this->tryAddToNeighbourUpdateQueue($pos); + foreach($pos->sides() as $side){ + $this->tryAddToNeighbourUpdateQueue($side); + } + } + /** * @return Block[] */ From 0f703488213691a2531fb967e80d05704c6658be Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Sep 2021 20:31:13 +0100 Subject: [PATCH 2814/3224] Remove noise --- src/Server.php | 3 +-- src/command/defaults/StatusCommand.php | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Server.php b/src/Server.php index b5402bdf46..e4faf67e15 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1573,10 +1573,9 @@ class Server{ private function titleTick() : void{ Timings::$titleTick->startTiming(); - $d = Process::getRealMemoryUsage(); $u = Process::getAdvancedMemoryUsage(); - $usage = sprintf("%g/%g/%g/%g MB @ %d threads", round(($u[0] / 1024) / 1024, 2), round(($d[0] / 1024) / 1024, 2), round(($u[1] / 1024) / 1024, 2), round(($u[2] / 1024) / 1024, 2), Process::getThreadCount()); + $usage = sprintf("%g/%g/%g MB @ %d threads", round(($u[0] / 1024) / 1024, 2), round(($u[1] / 1024) / 1024, 2), round(($u[2] / 1024) / 1024, 2), Process::getThreadCount()); $online = count($this->playerList); $connecting = $this->network->getConnectionCount() - $online; diff --git a/src/command/defaults/StatusCommand.php b/src/command/defaults/StatusCommand.php index d3bbc7b3aa..7a4a98558d 100644 --- a/src/command/defaults/StatusCommand.php +++ b/src/command/defaults/StatusCommand.php @@ -50,7 +50,6 @@ class StatusCommand extends VanillaCommand{ return true; } - $rUsage = Process::getRealMemoryUsage(); $mUsage = Process::getAdvancedMemoryUsage(); $server = $sender->getServer(); @@ -102,7 +101,6 @@ class StatusCommand extends VanillaCommand{ $sender->sendMessage(TextFormat::GOLD . "Main thread memory: " . TextFormat::RED . number_format(round(($mUsage[0] / 1024) / 1024, 2), 2) . " MB."); $sender->sendMessage(TextFormat::GOLD . "Total memory: " . TextFormat::RED . number_format(round(($mUsage[1] / 1024) / 1024, 2), 2) . " MB."); $sender->sendMessage(TextFormat::GOLD . "Total virtual memory: " . TextFormat::RED . number_format(round(($mUsage[2] / 1024) / 1024, 2), 2) . " MB."); - $sender->sendMessage(TextFormat::GOLD . "Heap memory: " . TextFormat::RED . number_format(round(($rUsage[0] / 1024) / 1024, 2), 2) . " MB."); $globalLimit = $server->getMemoryManager()->getGlobalMemoryLimit(); if($globalLimit > 0){ From c605b5459108c64649c2debf45dc3cf75c76dc22 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Sep 2021 22:52:00 +0100 Subject: [PATCH 2815/3224] Accept dev versions of chunkutils2 --- src/PocketMine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index 6644acef0c..4d6d3cd4ac 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -133,7 +133,7 @@ namespace pocketmine { $wantedVersionMin = "$wantedVersionLock.0"; if($chunkutils2_version !== false && ( version_compare($chunkutils2_version, $wantedVersionMin) < 0 || - preg_match("/^" . preg_quote($wantedVersionLock, "/") . "\.\d+$/", $chunkutils2_version) === 0 //lock in at ^0.2, optionally at a patch release + preg_match("/^" . preg_quote($wantedVersionLock, "/") . "\.\d+(?:-dev)?$/", $chunkutils2_version) === 0 //lock in at ^0.2, optionally at a patch release )){ $messages[] = "chunkutils2 ^$wantedVersionMin is required, while you have $chunkutils2_version."; } From 11d2e1ef08c82a5abad2f1f9a0891f4723f05b9e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Sep 2021 22:53:50 +0100 Subject: [PATCH 2816/3224] Require ext-chunkutils ^0.3.0 --- composer.json | 2 +- composer.lock | 4 ++-- src/PocketMine.php | 2 +- src/network/mcpe/serializer/ChunkSerializer.php | 15 +++++++++++++-- src/world/format/io/leveldb/LevelDB.php | 11 +++++++++-- 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index ea49fcd3f9..c548e63310 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ "require": { "php": "^8.0", "php-64bit": "*", - "ext-chunkutils2": "^0.2.0", + "ext-chunkutils2": "^0.3.0", "ext-crypto": "^0.3.1", "ext-ctype": "*", "ext-curl": "*", diff --git a/composer.lock b/composer.lock index 62ccacf9dd..70eadad960 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "009abb4d28399a27dc9d059bfd849aee", + "content-hash": "ad6be987e3e2228abcb23e169f139d29", "packages": [ { "name": "adhocore/json-comment", @@ -3532,7 +3532,7 @@ "platform": { "php": "^8.0", "php-64bit": "*", - "ext-chunkutils2": "^0.2.0", + "ext-chunkutils2": "^0.3.0", "ext-crypto": "^0.3.1", "ext-ctype": "*", "ext-curl": "*", diff --git a/src/PocketMine.php b/src/PocketMine.php index 4d6d3cd4ac..afac6fd8d6 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -129,7 +129,7 @@ namespace pocketmine { } $chunkutils2_version = phpversion("chunkutils2"); - $wantedVersionLock = "0.2"; + $wantedVersionLock = "0.3"; $wantedVersionMin = "$wantedVersionLock.0"; if($chunkutils2_version !== false && ( version_compare($chunkutils2_version, $wantedVersionMin) < 0 || diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index 8f621e0c82..9565598868 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -32,8 +32,10 @@ use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\utils\Binary; use pocketmine\utils\BinaryStream; use pocketmine\world\format\Chunk; +use pocketmine\world\format\PalettedBlockArray; use pocketmine\world\format\SubChunk; use function count; +use function str_repeat; final class ChunkSerializer{ @@ -81,8 +83,17 @@ final class ChunkSerializer{ $stream->putByte(count($layers)); foreach($layers as $blocks){ - $stream->putByte(($blocks->getBitsPerBlock() << 1) | ($persistentBlockStates ? 0 : 1)); - $stream->put($blocks->getWordArray()); + if($blocks->getBitsPerBlock() === 0){ + //TODO: we use these in memory, but the game doesn't support them yet + //polyfill them with 1-bpb instead + $bitsPerBlock = 1; + $words = str_repeat("\x00", PalettedBlockArray::getExpectedWordArraySize(1)); + }else{ + $bitsPerBlock = $blocks->getBitsPerBlock(); + $words = $blocks->getWordArray(); + } + $stream->putByte(($bitsPerBlock << 1) | ($persistentBlockStates ? 0 : 1)); + $stream->put($words); $palette = $blocks->getPalette(); //these LSHIFT by 1 uvarints are optimizations: the client expects zigzag varints here diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 92beecc2ad..d849822b5e 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -446,8 +446,15 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $layers = $subChunk->getBlockLayers(); $subStream->putByte(count($layers)); foreach($layers as $blocks){ - $subStream->putByte($blocks->getBitsPerBlock() << 1); - $subStream->put($blocks->getWordArray()); + if($blocks->getBitsPerBlock() !== 0){ + $subStream->putByte($blocks->getBitsPerBlock() << 1); + $subStream->put($blocks->getWordArray()); + }else{ + //TODO: we use these in-memory, but they aren't supported on disk by the game yet + //polyfill them with a zero'd 1-bpb instead + $subStream->putByte(1 << 1); + $subStream->put(str_repeat("\x00", PalettedBlockArray::getExpectedWordArraySize(1))); + } $palette = $blocks->getPalette(); $subStream->putLInt(count($palette)); From bc6e73e81d0c781343f5ad89ec42d6b6a11b29d3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Sep 2021 22:54:54 +0100 Subject: [PATCH 2817/3224] SubChunk: fixed light array GC since native LightArray introduction since this went native, there was no support for copy-on-write, so this was only lazy-inited, but never cleaned if the array remained empty. --- src/world/format/SubChunk.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/world/format/SubChunk.php b/src/world/format/SubChunk.php index 676c643b81..b9baf52cbe 100644 --- a/src/world/format/SubChunk.php +++ b/src/world/format/SubChunk.php @@ -145,11 +145,11 @@ class SubChunk{ } $this->blockLayers = array_values($this->blockLayers); - if($this->skyLight !== null){ - $this->skyLight->collectGarbage(); + if($this->skyLight !== null && $this->skyLight->isUniform(0)){ + $this->skyLight = null; } - if($this->blockLight !== null){ - $this->blockLight->collectGarbage(); + if($this->blockLight !== null && $this->blockLight->isUniform(0)){ + $this->blockLight = null; } } From 627c70c4df2f90833f11488608de0bc612df077b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Sep 2021 22:55:50 +0100 Subject: [PATCH 2818/3224] actions: use chunkutils2 0.3.1 --- tests/gh-actions/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/gh-actions/build.sh b/tests/gh-actions/build.sh index cef21d7e63..23b3641bff 100755 --- a/tests/gh-actions/build.sh +++ b/tests/gh-actions/build.sh @@ -53,7 +53,7 @@ PHP_BUILD_INSTALL_EXTENSION="\ pthreads=@a6afc0434f91c1e9541444aef6ac7a1f16c595be \ yaml=2.2.1 \ leveldb=@60763a09bf5c7a10376d16e25b078b99a35c5c37 \ -chunkutils2=@0.2.0 \ +chunkutils2=@0.3.1 \ morton=@0.1.2 \ igbinary=3.2.1 \ " PHP_BUILD_ZTS_ENABLE=on PHP_BUILD_CONFIGURE_OPTS='--with-gmp' ./bin/php-build "$VERSION" "$INSTALL_DIR" || exit 1 From b8a15b647c186649c7802f941b5a0a796ff31c70 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Sep 2021 22:35:02 +0000 Subject: [PATCH 2819/3224] Updated build/php submodule to pmmp/php-build-scripts@ad9cd1fdb47742038365ec8ec7e2ed61ba58a068 --- build/php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/php b/build/php index 48c96fdf77..ad9cd1fdb4 160000 --- a/build/php +++ b/build/php @@ -1 +1 @@ -Subproject commit 48c96fdf778debec0198a16045315f7242d9bc13 +Subproject commit ad9cd1fdb47742038365ec8ec7e2ed61ba58a068 From 7c943880b24d939514f48b91a3fac91fd103e628 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 7 Sep 2021 23:51:58 +0100 Subject: [PATCH 2820/3224] Do not show update notifications to users running from git sources --- src/updater/UpdateChecker.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/updater/UpdateChecker.php b/src/updater/UpdateChecker.php index ede2343c79..f7459a1ce8 100644 --- a/src/updater/UpdateChecker.php +++ b/src/updater/UpdateChecker.php @@ -151,7 +151,7 @@ class UpdateChecker{ return; } - if($currentVersion->compare($newVersion) > 0 and ($currentVersion->getFullVersion() !== $newVersion->getFullVersion() or $currentVersion->getBuild() > 0)){ + if($currentVersion->getBuild() > 0 && $currentVersion->compare($newVersion) > 0){ $this->updateInfo = $updateInfo; } } From dca5a9d8ea13117d9eef350500e28ec77187b4a3 Mon Sep 17 00:00:00 2001 From: Jack Honour Date: Wed, 8 Sep 2021 17:00:12 +0100 Subject: [PATCH 2821/3224] Remove PHP Version from notice. (#4442) --- start.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/start.sh b/start.sh index fe4d95a8e6..087b53db8c 100755 --- a/start.sh +++ b/start.sh @@ -26,7 +26,7 @@ if [ "$PHP_BINARY" == "" ]; then elif [[ ! -z $(type php) ]]; then PHP_BINARY=$(type -p php) else - echo "Couldn't find a working PHP 7 binary, please use the installer." + echo "Couldn't find a working PHP binary, please use the installer." exit 1 fi fi From b9b1ba95261f90e61657a0220ca8a59fa0dad9d7 Mon Sep 17 00:00:00 2001 From: marshall Date: Thu, 9 Sep 2021 04:54:32 +0800 Subject: [PATCH 2822/3224] Include eye height in Living->lookAt() calculation (#4440) --- src/entity/Living.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entity/Living.php b/src/entity/Living.php index d95dfaba14..401bd051d3 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -772,7 +772,7 @@ abstract class Living extends Entity{ */ public function lookAt(Vector3 $target) : void{ $horizontal = sqrt(($target->x - $this->location->x) ** 2 + ($target->z - $this->location->z) ** 2); - $vertical = $target->y - $this->location->y; + $vertical = $target->y - ($this->location->y + $this->getEyeHeight()); $this->location->pitch = -atan2($vertical, $horizontal) / M_PI * 180; //negative is up, positive is down $xDist = $target->x - $this->location->x; From ba2bfe0e1149d98abff6028474bb68adf7f016cb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 8 Sep 2021 22:10:50 +0100 Subject: [PATCH 2823/3224] World: depopulate neighbourBlockUpdateQueueIndex sooner this fixes 2 problems: 1) Blocks which set themselves to something else during onNearbyBlockChange() would not receive any block update 2) A memory leak when blocks in unloaded chunks were scheduled for an update. I'm a little uneasy about this change, because there must have been some reason why I put this at the end of the block and not at the start, but whatever it is, I can't reason about it, and there's reasons not to put it at the end too. --- src/world/World.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index 1675aef96d..a13a0a73d3 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -804,6 +804,7 @@ class World implements ChunkManager{ //Normal updates while($this->neighbourBlockUpdateQueue->count() > 0){ $index = $this->neighbourBlockUpdateQueue->dequeue(); + unset($this->neighbourBlockUpdateQueueIndex[$index]); World::getBlockXYZ($index, $x, $y, $z); if(!$this->isChunkLoaded($x >> 4, $z >> 4)){ continue; @@ -820,7 +821,6 @@ class World implements ChunkManager{ } $block->onNearbyBlockChange(); } - unset($this->neighbourBlockUpdateQueueIndex[$index]); } $this->timings->scheduledBlockUpdates->stopTiming(); From 34f01a3ce3c02f41cfebfc81d34b755cfed62811 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 Sep 2021 01:17:41 +0100 Subject: [PATCH 2824/3224] World: Track entities separately from chunks this allows entities to exist outside of generated chunks, with one caveat: they won't be saved in such cases. Obviously, for player entities, this doesn't matter. fixes #3947 --- src/player/Player.php | 11 +-- src/world/World.php | 108 ++++++++++++++----------- src/world/format/Chunk.php | 40 --------- tests/phpstan/configs/l8-baseline.neon | 10 --- 4 files changed, 67 insertions(+), 102 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 55e32943a4..65c8798dd9 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -630,12 +630,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $world = $world ?? $this->getWorld(); $index = World::chunkHash($x, $z); if(isset($this->usedChunks[$index])){ - $chunk = $world->getChunk($x, $z); - if($chunk !== null){ //this might be a chunk that hasn't been generated yet - foreach($chunk->getEntities() as $entity){ - if($entity !== $this){ - $entity->despawnFrom($this); - } + foreach($world->getChunkEntities($x, $z) as $entity){ + if($entity !== $this){ + $entity->despawnFrom($this); } } $this->getNetworkSession()->stopUsingChunk($x, $z); @@ -656,7 +653,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } protected function spawnEntitiesOnChunk(int $chunkX, int $chunkZ) : void{ - foreach($this->getWorld()->getChunk($chunkX, $chunkZ)->getEntities() as $entity){ + foreach($this->getWorld()->getChunkEntities($chunkX, $chunkZ) as $entity){ if($entity !== $this and !$entity->isFlaggedForDespawn()){ $entity->spawnTo($this); } diff --git a/src/world/World.php b/src/world/World.php index a13a0a73d3..d63481f2a7 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -93,6 +93,7 @@ use pocketmine\world\sound\Sound; use pocketmine\world\utils\SubChunkExplorer; use function abs; use function array_fill_keys; +use function array_filter; use function array_key_exists; use function array_map; use function array_merge; @@ -158,6 +159,12 @@ class World implements ChunkManager{ */ private $entityLastKnownPositions = []; + /** + * @var Entity[][] + * @phpstan-var array> + */ + private array $entitiesByChunk = []; + /** @var Entity[] */ public $updateEntities = []; /** @var Block[][] */ @@ -516,6 +523,15 @@ class World implements ChunkManager{ self::getXZ($chunkHash, $chunkX, $chunkZ); $this->unloadChunk($chunkX, $chunkZ, false); } + foreach($this->entitiesByChunk as $chunkHash => $entities){ + self::getXZ($chunkHash, $chunkX, $chunkZ); + if(count($entities) !== 0){ + $this->logger->warning(count($entities) . " entities found in ungenerated chunk $chunkX $chunkZ, they won't be saved!"); + } + foreach($entities as $entity){ + $entity->close(); + } + } $this->save(); @@ -1070,7 +1086,7 @@ class World implements ChunkManager{ if($chunk === null){ throw new \InvalidArgumentException("Chunk is not loaded"); } - foreach($chunk->getEntities() as $entity){ + foreach($this->getChunkEntities($chunkX, $chunkZ) as $entity){ $entity->onRandomUpdate(); } @@ -1129,7 +1145,7 @@ class World implements ChunkManager{ self::getXZ($chunkHash, $chunkX, $chunkZ); $this->provider->saveChunk($chunkX, $chunkZ, new ChunkData( $chunk, - array_map(fn(Entity $e) => $e->saveNBT(), $chunk->getSavableEntities()), + array_map(fn(Entity $e) => $e->saveNBT(), array_filter($this->getChunkEntities($chunkX, $chunkZ), fn(Entity $e) => $e->canSaveWithChunk())), array_map(fn(Tile $t) => $t->saveNBT(), $chunk->getTiles()), )); $chunk->clearTerrainDirtyFlags(); @@ -1921,7 +1937,7 @@ class World implements ChunkManager{ if(!$this->isChunkLoaded($x, $z)){ continue; } - foreach($this->getChunk($x, $z)->getEntities() as $ent){ + foreach($this->getChunkEntities($x, $z) as $ent){ if($ent !== $entity and $ent->boundingBox->intersectsWith($bb)){ $nearby[] = $ent; } @@ -1964,7 +1980,7 @@ class World implements ChunkManager{ if(!$this->isChunkLoaded($x, $z)){ continue; } - foreach($this->getChunk($x, $z)->getEntities() as $entity){ + foreach($this->getChunkEntities($x, $z) as $entity){ if(!($entity instanceof $entityType) or $entity->isFlaggedForDespawn() or (!$includeDead and !$entity->isAlive())){ continue; } @@ -2043,6 +2059,13 @@ class World implements ChunkManager{ return $this->chunks[World::chunkHash($chunkX, $chunkZ)] ?? null; } + /** + * @return Entity[] + */ + public function getChunkEntities(int $chunkX, int $chunkZ) : array{ + return $this->entitiesByChunk[World::chunkHash($chunkX, $chunkZ)] ?? []; + } + /** * Returns the chunk containing the given Vector3 position. */ @@ -2154,11 +2177,8 @@ class World implements ChunkManager{ $oldChunk = $this->loadChunk($chunkX, $chunkZ); if($oldChunk !== null and $oldChunk !== $chunk){ if($deleteEntitiesAndTiles){ - foreach($oldChunk->getEntities() as $entity){ - if($entity instanceof Player){ - $chunk->addEntity($entity); - $oldChunk->removeEntity($entity); - }else{ + foreach($this->getChunkEntities($chunkX, $chunkZ) as $entity){ + if(!($entity instanceof Player)){ $entity->close(); } } @@ -2166,11 +2186,6 @@ class World implements ChunkManager{ $tile->close(); } }else{ - foreach($oldChunk->getEntities() as $entity){ - $chunk->addEntity($entity); - $oldChunk->removeEntity($entity); - } - foreach($oldChunk->getTiles() as $tile){ $chunk->addTile($tile); $oldChunk->removeTile($tile); @@ -2272,7 +2287,7 @@ class World implements ChunkManager{ if($chunk === null){ throw new \InvalidArgumentException("Cannot add an Entity in an ungenerated chunk"); } - $chunk->addEntity($entity); + $this->entitiesByChunk[World::chunkHash($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4)][$entity->getId()] = $entity; $this->entityLastKnownPositions[$entity->getId()] = $pos; if($entity instanceof Player){ @@ -2294,9 +2309,12 @@ class World implements ChunkManager{ throw new \InvalidArgumentException("Entity is not tracked by this world (possibly already removed?)"); } $pos = $this->entityLastKnownPositions[$entity->getId()]; - $chunk = $this->getChunk($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4); - if($chunk !== null){ //we don't care if the chunk already went out of scope - $chunk->removeEntity($entity); + $chunkHash = World::chunkHash($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4); + if(isset($this->entitiesByChunk[$chunkHash][$entity->getId()])){ + unset($this->entitiesByChunk[$chunkHash][$entity->getId()]); + if(count($this->entitiesByChunk[$chunkHash]) === 0){ + unset($this->entitiesByChunk[$chunkHash]); + } } unset($this->entityLastKnownPositions[$entity->getId()]); @@ -2326,35 +2344,28 @@ class World implements ChunkManager{ $newChunkZ = $newPosition->getFloorZ() >> 4; if($oldChunkX !== $newChunkX || $oldChunkZ !== $newChunkZ){ - $oldChunk = $this->getChunk($oldChunkX, $oldChunkZ); - if($oldChunk !== null){ - $oldChunk->removeEntity($entity); + $oldChunkHash = World::chunkHash($oldChunkX, $oldChunkZ); + if(isset($this->entitiesByChunk[$oldChunkHash][$entity->getId()])){ + unset($this->entitiesByChunk[$oldChunkHash][$entity->getId()]); + if(count($this->entitiesByChunk[$oldChunkHash]) === 0){ + unset($this->entitiesByChunk[$oldChunkHash]); + } } - $newChunk = $this->loadChunk($newChunkX, $newChunkZ); - if($newChunk === null){ - //TODO: this is a non-ideal solution for a hard problem - //when this happens the entity won't be tracked by any chunk, so we can't have it hanging around in memory - //we also can't allow this to cause chunk generation, nor can we just create an empty ungenerated chunk - //for it, because an empty chunk won't get saved, so the entity will vanish anyway. Therefore, this is - //the cleanest way to make sure this doesn't result in leaks. - $this->logger->debug("Entity " . $entity->getId() . " is in ungenerated terrain, flagging for despawn"); - $entity->flagForDespawn(); - $entity->despawnFromAll(); - }else{ - $newViewers = $this->getViewersForPosition($newPosition); - foreach($entity->getViewers() as $player){ - if(!isset($newViewers[spl_object_id($player)])){ - $entity->despawnFrom($player); - }else{ - unset($newViewers[spl_object_id($player)]); - } - } - foreach($newViewers as $player){ - $entity->spawnTo($player); - } - $newChunk->addEntity($entity); + $newViewers = $this->getViewersForPosition($newPosition); + foreach($entity->getViewers() as $player){ + if(!isset($newViewers[spl_object_id($player)])){ + $entity->despawnFrom($player); + }else{ + unset($newViewers[spl_object_id($player)]); + } } + foreach($newViewers as $player){ + $entity->spawnTo($player); + } + + $newChunkHash = World::chunkHash($newChunkX, $newChunkZ); + $this->entitiesByChunk[$newChunkHash][$entity->getId()] = $entity; } $this->entityLastKnownPositions[$entity->getId()] = $newPosition->asVector3(); } @@ -2564,7 +2575,7 @@ class World implements ChunkManager{ try{ $this->provider->saveChunk($x, $z, new ChunkData( $chunk, - array_map(fn(Entity $e) => $e->saveNBT(), $chunk->getSavableEntities()), + array_map(fn(Entity $e) => $e->saveNBT(), array_filter($this->getChunkEntities($x, $z), fn(Entity $e) => $e->canSaveWithChunk())), array_map(fn(Tile $t) => $t->saveNBT(), $chunk->getTiles()), )); }finally{ @@ -2576,6 +2587,13 @@ class World implements ChunkManager{ $listener->onChunkUnloaded($x, $z, $chunk); } + foreach($this->getChunkEntities($x, $z) as $entity){ + if($entity instanceof Player){ + continue; + } + $entity->close(); + } + $chunk->onUnload(); } diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 839f7854b8..56894c503e 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -30,10 +30,7 @@ use pocketmine\block\Block; use pocketmine\block\BlockLegacyIds; use pocketmine\block\tile\Tile; use pocketmine\data\bedrock\BiomeIds; -use pocketmine\entity\Entity; -use pocketmine\player\Player; use function array_fill; -use function array_filter; use function array_map; class Chunk{ @@ -59,9 +56,6 @@ class Chunk{ /** @var Tile[] */ protected $tiles = []; - /** @var Entity[] */ - protected $entities = []; - /** @var HeightArray */ protected $heightMap; @@ -191,17 +185,6 @@ class Chunk{ $this->terrainDirtyFlags |= self::DIRTY_FLAG_TERRAIN; } - public function addEntity(Entity $entity) : void{ - if($entity->isClosed()){ - throw new \InvalidArgumentException("Attempted to add a garbage closed Entity to a chunk"); - } - $this->entities[$entity->getId()] = $entity; - } - - public function removeEntity(Entity $entity) : void{ - unset($this->entities[$entity->getId()]); - } - public function addTile(Tile $tile) : void{ if($tile->isClosed()){ throw new \InvalidArgumentException("Attempted to add a garbage closed Tile to a chunk"); @@ -219,22 +202,6 @@ class Chunk{ unset($this->tiles[Chunk::blockHash($pos->x, $pos->y, $pos->z)]); } - /** - * Returns an array of entities currently using this chunk. - * - * @return Entity[] - */ - public function getEntities() : array{ - return $this->entities; - } - - /** - * @return Entity[] - */ - public function getSavableEntities() : array{ - return array_filter($this->entities, function(Entity $entity) : bool{ return $entity->canSaveWithChunk(); }); - } - /** * @return Tile[] */ @@ -257,13 +224,6 @@ class Chunk{ * Called when the chunk is unloaded, closing entities and tiles. */ public function onUnload() : void{ - foreach($this->getEntities() as $entity){ - if($entity instanceof Player){ - continue; - } - $entity->close(); - } - foreach($this->getTiles() as $tile){ $tile->close(); } diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index a87cd0dc25..33e53ac737 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -195,11 +195,6 @@ parameters: count: 1 path: ../../../src/permission/DefaultPermissions.php - - - message: "#^Cannot call method getEntities\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/player/Player.php - - message: "#^Cannot call method getSpawnLocation\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" count: 1 @@ -265,11 +260,6 @@ parameters: count: 1 path: ../../../src/world/Explosion.php - - - message: "#^Cannot call method getEntities\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 3 - path: ../../../src/world/World.php - - message: "#^Parameter \\#3 \\$chunk of method pocketmine\\\\player\\\\Player\\:\\:onChunkChanged\\(\\) expects pocketmine\\\\world\\\\format\\\\Chunk, pocketmine\\\\world\\\\format\\\\Chunk\\|null given\\.$#" count: 1 From 6f8261f26a099af71244d05e7c57bda41e111ea6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 Sep 2021 01:32:39 +0100 Subject: [PATCH 2825/3224] Added changelog so far for beta2 --- changelogs/4.0.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index 2b3833f7a2..8916a6f286 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1263,3 +1263,29 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` ### Inventory - Implemented offhand inventory. + +# 4.0.0-BETA2 + + +## General +- ext-chunkutils 0.3.x is now required. +- Reduced memory usage of light storage after garbage collection. +- Reduced memory usage of uniform subchunks which only contain 1 type of block. +- The title bar no longer displays heap memory usage numbers (nobody seemed to know that was what it was, anyway). +- `/status` no longer displays heap memory usage numbers. +- `start.sh` no longer specifically mentions PHP 7 when erroring because of a missing PHP binary. + +## Fixes +- Fixed players getting disconnected when using `/tp` to ungenerated chunks (or when teleported by players). +- Fixed a potential memory leak in block updating when chunks are unloaded. +- Fixed `Living->lookAt()` not taking eye height into account. + +## API changes +- The following API methods have been added: + - `World->getChunkEntities()` + - `World->notifyNeighbourBlockUpdate()` +- The following API methods have been removed: + - `Chunk->getEntities()` + - `Chunk->getSavableEntities()` + - `Chunk->addEntity()` + - `Chunk->removeEntity()` From e0e19c67effff579c2cc21bc9b4b465bc7e36212 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 Sep 2021 15:55:37 +0100 Subject: [PATCH 2826/3224] World: do not warn about leaked Player entities during world unload this raises false-positives during shutdown if players were online. The fact that the player entity leans on the World to clean up after it is slightly problematic, but I'm not sure what else to do about it for now. --- src/world/World.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index d63481f2a7..a1af7fcdd7 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -525,12 +525,17 @@ class World implements ChunkManager{ } foreach($this->entitiesByChunk as $chunkHash => $entities){ self::getXZ($chunkHash, $chunkX, $chunkZ); - if(count($entities) !== 0){ - $this->logger->warning(count($entities) . " entities found in ungenerated chunk $chunkX $chunkZ, they won't be saved!"); - } + + $leakedEntities = 0; foreach($entities as $entity){ + if(!$entity->isFlaggedForDespawn()){ + $leakedEntities++; + } $entity->close(); } + if($leakedEntities !== 0){ + $this->logger->warning("$leakedEntities leaked entities found in ungenerated chunk $chunkX $chunkZ during unload, they won't be saved!"); + } } $this->save(); From 5d4f14b3888f461799bec236148c209b029c0137 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 Sep 2021 17:10:04 +0100 Subject: [PATCH 2827/3224] Added TransactionBuilderInventory for server-side inventory transaction generation --- .../TransactionBuilderInventory.php | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 src/inventory/transaction/TransactionBuilderInventory.php diff --git a/src/inventory/transaction/TransactionBuilderInventory.php b/src/inventory/transaction/TransactionBuilderInventory.php new file mode 100644 index 0000000000..8888b4a452 --- /dev/null +++ b/src/inventory/transaction/TransactionBuilderInventory.php @@ -0,0 +1,106 @@ + + */ + private \SplFixedArray $changedSlots; + + public function __construct( + private Inventory $actualInventory + ){ + parent::__construct(); + $this->changedSlots = new \SplFixedArray($this->actualInventory->getSize()); + } + + protected function internalSetContents(array $items) : void{ + for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ + if(!isset($items[$i])){ + $this->clear($i); + }else{ + $this->setItem($i, $items[$i]); + } + } + } + + protected function internalSetItem(int $index, Item $item) : void{ + if(!$item->equalsExact($this->actualInventory->getItem($index))){ + $this->changedSlots[$index] = $item->isNull() ? ItemFactory::air() : clone $item; + } + } + + public function getSize() : int{ + return $this->actualInventory->getSize(); + } + + public function getItem(int $index) : Item{ + return $this->changedSlots[$index] !== null ? clone $this->changedSlots[$index] : $this->actualInventory->getItem($index); + } + + public function getContents(bool $includeEmpty = false) : array{ + $contents = $this->actualInventory->getContents($includeEmpty); + foreach($this->changedSlots as $index => $item){ + if($item !== null){ + if($includeEmpty || !$item->isNull()){ + $contents[$index] = clone $item; + }else{ + unset($contents[$index]); + } + } + } + return $contents; + } + + /** + * @return SlotChangeAction[] + */ + public function generateActions() : array{ + $result = []; + foreach($this->changedSlots as $index => $newItem){ + if($newItem !== null){ + $oldItem = $this->actualInventory->getItem($index); + if(!$newItem->equalsExact($oldItem)){ + $result[] = new SlotChangeAction($this->actualInventory, $index, $oldItem, $newItem); + } + } + } + return $result; + } +} From 082f0f2d5732a1d005bbf6ec70004970cc06d8f8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 9 Sep 2021 17:11:59 +0100 Subject: [PATCH 2828/3224] Player: Generate an InventoryTransaction (with event) for crafting grid/cursor evacuation this fixes the crack in the armour that allows creative players to drop items even when all drops are being cancelled by plugins. closes #3284 --- src/player/Player.php | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 65c8798dd9..7c77bd5a3f 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -75,6 +75,11 @@ use pocketmine\form\Form; use pocketmine\form\FormValidationException; use pocketmine\inventory\Inventory; use pocketmine\inventory\PlayerCursorInventory; +use pocketmine\inventory\transaction\action\DropItemAction; +use pocketmine\inventory\transaction\InventoryTransaction; +use pocketmine\inventory\transaction\TransactionBuilderInventory; +use pocketmine\inventory\transaction\TransactionCancelledException; +use pocketmine\inventory\transaction\TransactionValidationException; use pocketmine\item\ConsumableItem; use pocketmine\item\Durable; use pocketmine\item\enchantment\EnchantmentInstance; @@ -2282,15 +2287,40 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ public function doCloseInventory() : void{ /** @var Inventory[] $inventories */ $inventories = [$this->craftingGrid, $this->cursorInventory]; + + $transaction = new InventoryTransaction($this); + $mainInventoryTransactionBuilder = new TransactionBuilderInventory($this->inventory); foreach($inventories as $inventory){ $contents = $inventory->getContents(); + if(count($contents) > 0){ - $drops = $this->inventory->addItem(...$contents); + $drops = $mainInventoryTransactionBuilder->addItem(...$contents); foreach($drops as $drop){ - $this->dropItem($drop); + $transaction->addAction(new DropItemAction($drop)); } - $inventory->clearAll(); + $clearedInventoryTransactionBuilder = new TransactionBuilderInventory($inventory); + $clearedInventoryTransactionBuilder->clearAll(); + foreach($clearedInventoryTransactionBuilder->generateActions() as $action){ + $transaction->addAction($action); + } + } + } + foreach($mainInventoryTransactionBuilder->generateActions() as $action){ + $transaction->addAction($action); + } + + if(count($transaction->getActions()) !== 0){ + try{ + $transaction->execute(); + $this->logger->debug("Successfully evacuated items from temporary inventories"); + }catch(TransactionCancelledException){ + $this->logger->debug("Plugin cancelled transaction evacuating items from temporary inventories; items will be destroyed"); + foreach($inventories as $inventory){ + $inventory->clearAll(); + } + }catch(TransactionValidationException $e){ + throw new AssumptionFailedError("This server-generated transaction should never be invalid", 0, $e); } } From 334bf1277d6897cbc237b7be5f7c5f6ad7d8e8f1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 10 Sep 2021 00:31:28 +0100 Subject: [PATCH 2829/3224] BlockTransaction: Return failure if no blocks were changed fixes #2813 --- src/world/BlockTransaction.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/world/BlockTransaction.php b/src/world/BlockTransaction.php index f30d761f3d..80bf8445fb 100644 --- a/src/world/BlockTransaction.php +++ b/src/world/BlockTransaction.php @@ -95,10 +95,15 @@ class BlockTransaction{ } } } + $changedBlocks = 0; foreach($this->getBlocks() as [$x, $y, $z, $block]){ - $this->world->setBlockAt($x, $y, $z, $block); + $oldBlock = $this->world->getBlockAt($x, $y, $z); + if(!$oldBlock->isSameState($block)){ + $this->world->setBlockAt($x, $y, $z, $block); + $changedBlocks++; + } } - return true; + return $changedBlocks !== 0; } /** From 1cc57afd25e9ff2cd28f4608dafbe455bc217519 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 10 Sep 2021 13:48:01 +0100 Subject: [PATCH 2830/3224] Stop the ConsoleReaderThread explicitly, instead of letting ThreadManager do it this hack dates back to the days when the console reader would get stuck on shutdown on some platforms. --- src/Server.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Server.php b/src/Server.php index e4faf67e15..6e2d654128 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1358,7 +1358,7 @@ class Server{ if(isset($this->console)){ $this->getLogger()->debug("Closing console"); $this->console->shutdown(); - $this->console->notify(); + $this->console->quit(); } if(isset($this->network)){ From 32588d79c8b42fec3cee25feb0b180cf49375f62 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 10 Sep 2021 13:54:42 +0100 Subject: [PATCH 2831/3224] ConsoleReaderThread: remove useless code --- src/Server.php | 1 - src/console/ConsoleReaderThread.php | 10 ++-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/Server.php b/src/Server.php index 6e2d654128..c515f32dc7 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1357,7 +1357,6 @@ class Server{ if(isset($this->console)){ $this->getLogger()->debug("Closing console"); - $this->console->shutdown(); $this->console->quit(); } diff --git a/src/console/ConsoleReaderThread.php b/src/console/ConsoleReaderThread.php index 08caec7964..f1cca9bb33 100644 --- a/src/console/ConsoleReaderThread.php +++ b/src/console/ConsoleReaderThread.php @@ -46,22 +46,16 @@ final class ConsoleReaderThread extends Thread{ private \Threaded $buffer; private ?SleeperNotifier $notifier; - public bool $shutdown = false; - public function __construct(\Threaded $buffer, ?SleeperNotifier $notifier = null){ $this->buffer = $buffer; $this->notifier = $notifier; } - public function shutdown() : void{ - $this->shutdown = true; - } - protected function onRun() : void{ $buffer = $this->buffer; $notifier = $this->notifier; - while(!$this->shutdown){ + while(!$this->isKilled){ $this->runSubprocess($buffer, $notifier); } } @@ -105,7 +99,7 @@ final class ConsoleReaderThread extends Thread{ throw new AssumptionFailedError("stream_socket_accept() returned false"); } stream_socket_shutdown($server, STREAM_SHUT_RDWR); - while(!$this->shutdown){ + while(!$this->isKilled){ $r = [$client]; $w = null; $e = null; From f5c9c02e09f54b53ed4c495c8a0000b54930ccef Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 10 Sep 2021 15:57:45 +0100 Subject: [PATCH 2832/3224] Improve documentation of Thread and Worker --- src/thread/Thread.php | 9 ++++++++- src/thread/Worker.php | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/thread/Thread.php b/src/thread/Thread.php index 66c88b1068..8448289a6a 100644 --- a/src/thread/Thread.php +++ b/src/thread/Thread.php @@ -23,10 +23,17 @@ declare(strict_types=1); namespace pocketmine\thread; +use pocketmine\scheduler\AsyncTask; use const PTHREADS_INHERIT_NONE; /** - * This class must be extended by all custom threading classes + * Specialized Thread class aimed at PocketMine-MP-related usages. It handles setting up autoloading and error handling. + * + * Note: You probably don't need a thread unless you're doing something in it that's expected to last a long time (or + * indefinitely). + * For CPU-demanding tasks that take a short amount of time, consider using AsyncTasks instead to make better use of the + * CPU. + * @see AsyncTask */ abstract class Thread extends \Thread{ use CommonThreadPartsTrait; diff --git a/src/thread/Worker.php b/src/thread/Worker.php index cb31b16238..e710787ccd 100644 --- a/src/thread/Worker.php +++ b/src/thread/Worker.php @@ -26,7 +26,14 @@ namespace pocketmine\thread; use const PTHREADS_INHERIT_NONE; /** - * This class must be extended by all custom threading classes + * Specialized Worker class for PocketMine-MP-related use cases. It handles setting up autoloading and error handling. + * + * Workers are a special type of thread which execute tasks passed to them during their lifetime. Since creating a new + * thread has a high resource cost, workers can be kept around and reused for lots of short-lived tasks. + * + * As a plugin developer, you'll rarely (if ever) actually need to use this class directly. + * If you want to run tasks on other CPU cores, check out AsyncTask first. + * @see AsyncTask */ abstract class Worker extends \Worker{ use CommonThreadPartsTrait; From cf762d345d9bdaf877a40a94396382c255d3bc94 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 10 Sep 2021 15:58:38 +0100 Subject: [PATCH 2833/3224] Player: Log debug messages when canInteract() prevents block interaction --- src/player/Player.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index 7c77bd5a3f..c3976b0e2c 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1575,6 +1575,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->hungerManager->exhaust(0.025, PlayerExhaustEvent::CAUSE_MINING); return true; } + }else{ + $this->logger->debug("Cancelled block break at $pos due to not currently being interactable"); } return false; @@ -1601,6 +1603,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } return true; } + }else{ + $this->logger->debug("Cancelled interaction of block at $pos due to not currently being interactable"); } return false; @@ -1625,7 +1629,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $oldItem = clone $heldItem; $ev = new EntityDamageByEntityEvent($this, $entity, EntityDamageEvent::CAUSE_ENTITY_ATTACK, $heldItem->getAttackPoints()); - if($this->isSpectator() or !$this->canInteract($entity->getLocation(), 8) or ($entity instanceof Player and !$this->server->getConfigGroup()->getConfigBool("pvp"))){ + if(!$this->canInteract($entity->getLocation(), 8)){ + $this->logger->debug("Cancelled attack of entity " . $entity->getId() . " due to not currently being interactable"); + $ev->cancel(); + }elseif($this->isSpectator() or ($entity instanceof Player and !$this->server->getConfigGroup()->getConfigBool("pvp"))){ $ev->cancel(); } @@ -1688,6 +1695,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $ev = new PlayerEntityInteractEvent($this, $entity, $clickPos); if(!$this->canInteract($entity->getLocation(), 8)){ + $this->logger->debug("Cancelled interaction with entity " . $entity->getId() . " due to not currently being interactable"); $ev->cancel(); } From 9d5a86fe5306ea8be3e9a24273b73b19c604f032 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 10 Sep 2021 16:06:08 +0100 Subject: [PATCH 2834/3224] Revert "World: make the second parameter for getCollidingEntities() mandatory and non-nullable" This reverts commit e1b7bf31bbbf8a0c679bdf238cf7594881d0842b. fixes #4447 --- src/world/World.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index a1af7fcdd7..0ae25d1836 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1836,7 +1836,7 @@ class World implements ChunkManager{ foreach($tx->getBlocks() as [$x, $y, $z, $block]){ $block->position($this, $x, $y, $z); foreach($block->getCollisionBoxes() as $collisionBox){ - if(count($this->getNearbyEntities($collisionBox)) > 0){ + if(count($this->getCollidingEntities($collisionBox)) > 0){ return false; //Entity in block } } @@ -1910,12 +1910,12 @@ class World implements ChunkManager{ * * @return Entity[] */ - public function getCollidingEntities(AxisAlignedBB $bb, Entity $entity) : array{ + public function getCollidingEntities(AxisAlignedBB $bb, ?Entity $entity = null) : array{ $nearby = []; - if($entity->canCollide){ + if($entity === null or $entity->canCollide){ foreach($this->getNearbyEntities($bb, $entity) as $ent){ - if($ent->canBeCollidedWith() and $entity->canCollideWith($ent)){ + if($ent->canBeCollidedWith() and ($entity === null or $entity->canCollideWith($ent))){ $nearby[] = $ent; } } From 4111d92b989686f59b589cdaf038ab7aff0defe0 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Fri, 10 Sep 2021 16:13:25 +0100 Subject: [PATCH 2835/3224] Stop hardcoding chunk dimensions everywhere (#4443) --- src/Server.php | 3 +- src/block/Block.php | 3 +- src/block/tile/Chest.php | 3 +- src/entity/Entity.php | 3 +- src/network/mcpe/cache/ChunkCache.php | 2 +- src/player/Player.php | 14 +-- src/world/Explosion.php | 3 +- src/world/SimpleChunkManager.php | 8 +- src/world/World.php | 115 +++++++++--------- src/world/WorldManager.php | 5 +- src/world/format/Chunk.php | 16 ++- src/world/format/SubChunk.php | 6 +- src/world/format/io/leveldb/LevelDB.php | 4 +- src/world/generator/Flat.php | 15 +-- src/world/generator/hell/Nether.php | 7 +- src/world/generator/normal/Normal.php | 11 +- src/world/generator/populator/GroundCover.php | 5 +- src/world/generator/populator/Ore.php | 5 +- src/world/generator/populator/TallGrass.php | 5 +- src/world/generator/populator/Tree.php | 5 +- src/world/light/BlockLightUpdate.php | 10 +- src/world/light/LightUpdate.php | 19 +-- src/world/light/SkyLightUpdate.php | 31 ++--- src/world/utils/SubChunkExplorer.php | 8 +- 24 files changed, 166 insertions(+), 140 deletions(-) diff --git a/src/Server.php b/src/Server.php index c515f32dc7..f76235d57f 100644 --- a/src/Server.php +++ b/src/Server.php @@ -100,6 +100,7 @@ use pocketmine\utils\Promise; use pocketmine\utils\Terminal; use pocketmine\utils\TextFormat; use pocketmine\utils\Utils; +use pocketmine\world\format\Chunk; use pocketmine\world\format\io\WorldProviderManager; use pocketmine\world\format\io\WritableWorldProviderManagerEntry; use pocketmine\world\generator\Generator; @@ -546,7 +547,7 @@ class Server{ $spawn = $world->getSpawnLocation(); } $playerPromise = new Promise(); - $world->requestChunkPopulation($spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4, null)->onCompletion( + $world->requestChunkPopulation($spawn->getFloorX() >> Chunk::COORD_BIT_SIZE, $spawn->getFloorZ() >> Chunk::COORD_BIT_SIZE, null)->onCompletion( function() use ($playerPromise, $class, $session, $playerInfo, $authenticated, $world, $playerPos, $spawn, $offlinePlayerData) : void{ if(!$session->isConnected()){ $playerPromise->reject(); diff --git a/src/block/Block.php b/src/block/Block.php index 2bbdfc1c77..7006db1ca3 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -40,6 +40,7 @@ use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\player\Player; use pocketmine\world\BlockTransaction; +use pocketmine\world\format\Chunk; use pocketmine\world\Position; use pocketmine\world\World; use function assert; @@ -142,7 +143,7 @@ class Block{ } public function writeStateToWorld() : void{ - $this->position->getWorld()->getOrLoadChunkAtPosition($this->position)->setFullBlock($this->position->x & 0xf, $this->position->y, $this->position->z & 0xf, $this->getFullId()); + $this->position->getWorld()->getOrLoadChunkAtPosition($this->position)->setFullBlock($this->position->x & Chunk::COORD_MASK, $this->position->y, $this->position->z & Chunk::COORD_MASK, $this->getFullId()); $tileType = $this->idInfo->getTileClass(); $oldTile = $this->position->getWorld()->getTile($this->position); diff --git a/src/block/tile/Chest.php b/src/block/tile/Chest.php index 52a12763ea..67534f123e 100644 --- a/src/block/tile/Chest.php +++ b/src/block/tile/Chest.php @@ -28,6 +28,7 @@ use pocketmine\block\inventory\DoubleChestInventory; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; +use pocketmine\world\format\Chunk; use pocketmine\world\World; use function abs; @@ -99,7 +100,7 @@ class Chest extends Spawnable implements Container, Nameable{ $this->inventory->removeAllViewers(); if($this->doubleInventory !== null){ - if($this->isPaired() and $this->position->getWorld()->isChunkLoaded($this->pairX >> 4, $this->pairZ >> 4)){ + if($this->isPaired() and $this->position->getWorld()->isChunkLoaded($this->pairX >> Chunk::COORD_BIT_SIZE, $this->pairZ >> Chunk::COORD_BIT_SIZE)){ $this->doubleInventory->removeAllViewers(); if(($pair = $this->getPair()) !== null){ $pair->doubleInventory = null; diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 918bb6d1c8..b1680fdb21 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -56,6 +56,7 @@ use pocketmine\player\Player; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; +use pocketmine\world\format\Chunk; use pocketmine\world\Position; use pocketmine\world\sound\Sound; use pocketmine\world\World; @@ -1436,7 +1437,7 @@ abstract class Entity{ //TODO: this will cause some visible lag during chunk resends; if the player uses a spawn egg in a chunk, the //created entity won't be visible until after the resend arrives. However, this is better than possibly crashing //the player by sending them entities too early. - if(!isset($this->hasSpawned[$id]) and $player->hasReceivedChunk($this->location->getFloorX() >> 4, $this->location->getFloorZ() >> 4)){ + if(!isset($this->hasSpawned[$id]) and $player->hasReceivedChunk($this->location->getFloorX() >> Chunk::COORD_BIT_SIZE, $this->location->getFloorZ() >> Chunk::COORD_BIT_SIZE)){ $this->hasSpawned[$id] = $player; $this->sendSpawnPacket($player); diff --git a/src/network/mcpe/cache/ChunkCache.php b/src/network/mcpe/cache/ChunkCache.php index 0729a1f8c2..269451f497 100644 --- a/src/network/mcpe/cache/ChunkCache.php +++ b/src/network/mcpe/cache/ChunkCache.php @@ -193,7 +193,7 @@ class ChunkCache implements ChunkListener{ public function onBlockChanged(Vector3 $block) : void{ //FIXME: requesters will still receive this chunk after it's been dropped, but we can't mark this for a simple //sync here because it can spam the worker pool - $this->destroy($block->getFloorX() >> 4, $block->getFloorZ() >> 4); + $this->destroy($block->getFloorX() >> Chunk::COORD_BIT_SIZE, $block->getFloorZ() >> Chunk::COORD_BIT_SIZE); } /** diff --git a/src/player/Player.php b/src/player/Player.php index c3976b0e2c..b892c5a9c8 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -272,9 +272,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $world = $spawnLocation->getWorld(); //load the spawn chunk so we can see the terrain - $world->registerChunkLoader($this->chunkLoader, $spawnLocation->getFloorX() >> 4, $spawnLocation->getFloorZ() >> 4, true); - $world->registerChunkListener($this, $spawnLocation->getFloorX() >> 4, $spawnLocation->getFloorZ() >> 4); - $this->usedChunks[World::chunkHash($spawnLocation->getFloorX() >> 4, $spawnLocation->getFloorZ() >> 4)] = UsedChunkStatus::NEEDED(); + $world->registerChunkLoader($this->chunkLoader, $spawnLocation->getFloorX() >> Chunk::COORD_BIT_SIZE, $spawnLocation->getFloorZ() >> Chunk::COORD_BIT_SIZE, true); + $world->registerChunkListener($this, $spawnLocation->getFloorX() >> Chunk::COORD_BIT_SIZE, $spawnLocation->getFloorZ() >> Chunk::COORD_BIT_SIZE); + $this->usedChunks[World::chunkHash($spawnLocation->getFloorX() >> Chunk::COORD_BIT_SIZE, $spawnLocation->getFloorZ() >> Chunk::COORD_BIT_SIZE)] = UsedChunkStatus::NEEDED(); parent::__construct($spawnLocation, $this->playerInfo->getSkin(), $namedtag); @@ -794,8 +794,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ foreach($this->chunkSelector->selectChunks( $this->server->getAllowedViewDistance($this->viewDistance), - $this->location->getFloorX() >> 4, - $this->location->getFloorZ() >> 4 + $this->location->getFloorX() >> Chunk::COORD_BIT_SIZE, + $this->location->getFloorZ() >> Chunk::COORD_BIT_SIZE ) as $hash){ if(!isset($this->usedChunks[$hash]) or $this->usedChunks[$hash]->equals(UsedChunkStatus::NEEDED())){ $newOrder[$hash] = true; @@ -1126,7 +1126,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->logger->debug("Moved too fast, reverting movement"); $this->logger->debug("Old position: " . $this->location->asVector3() . ", new position: " . $newPos); $revert = true; - }elseif(!$this->getWorld()->isInLoadedTerrain($newPos) or !$this->getWorld()->isChunkGenerated($newPos->getFloorX() >> 4, $newPos->getFloorZ() >> 4)){ + }elseif(!$this->getWorld()->isInLoadedTerrain($newPos) or !$this->getWorld()->isChunkGenerated($newPos->getFloorX() >> Chunk::COORD_BIT_SIZE, $newPos->getFloorZ() >> Chunk::COORD_BIT_SIZE)){ $revert = true; $this->nextChunkOrderRun = 0; } @@ -2128,7 +2128,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->logger->debug("Waiting for spawn terrain generation for respawn"); $spawn = $this->getSpawn(); - $spawn->getWorld()->orderChunkPopulation($spawn->getFloorX() >> 4, $spawn->getFloorZ() >> 4, null)->onCompletion( + $spawn->getWorld()->orderChunkPopulation($spawn->getFloorX() >> Chunk::COORD_BIT_SIZE, $spawn->getFloorZ() >> Chunk::COORD_BIT_SIZE, null)->onCompletion( function() use ($spawn) : void{ if(!$this->isConnected()){ return; diff --git a/src/world/Explosion.php b/src/world/Explosion.php index 3689ec5479..722b08e90d 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -37,6 +37,7 @@ use pocketmine\item\ItemFactory; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Facing; use pocketmine\math\Vector3; +use pocketmine\world\format\SubChunk; use pocketmine\world\particle\HugeExplodeSeedParticle; use pocketmine\world\sound\ExplodeSound; use pocketmine\world\utils\SubChunkExplorer; @@ -128,7 +129,7 @@ class Explosion{ continue; } - $state = $this->subChunkExplorer->currentSubChunk->getFullBlock($vBlockX & 0x0f, $vBlockY & 0x0f, $vBlockZ & 0x0f); + $state = $this->subChunkExplorer->currentSubChunk->getFullBlock($vBlockX & SubChunk::COORD_MASK, $vBlockY & SubChunk::COORD_MASK, $vBlockZ & SubChunk::COORD_MASK); $blastResistance = $blockFactory->blastResistance[$state]; if($blastResistance >= 0){ diff --git a/src/world/SimpleChunkManager.php b/src/world/SimpleChunkManager.php index d78e533383..105412bb50 100644 --- a/src/world/SimpleChunkManager.php +++ b/src/world/SimpleChunkManager.php @@ -45,15 +45,15 @@ class SimpleChunkManager implements ChunkManager{ } public function getBlockAt(int $x, int $y, int $z) : Block{ - if($this->isInWorld($x, $y, $z) && ($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ - return BlockFactory::getInstance()->fromFullBlock($chunk->getFullBlock($x & 0xf, $y, $z & 0xf)); + if($this->isInWorld($x, $y, $z) && ($chunk = $this->getChunk($x >> Chunk::COORD_BIT_SIZE, $z >> Chunk::COORD_BIT_SIZE)) !== null){ + return BlockFactory::getInstance()->fromFullBlock($chunk->getFullBlock($x & Chunk::COORD_MASK, $y, $z & Chunk::COORD_MASK)); } return VanillaBlocks::AIR(); } public function setBlockAt(int $x, int $y, int $z, Block $block) : void{ - if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null){ - $chunk->setFullBlock($x & 0xf, $y, $z & 0xf, $block->getFullId()); + if(($chunk = $this->getChunk($x >> Chunk::COORD_BIT_SIZE, $z >> Chunk::COORD_BIT_SIZE)) !== null){ + $chunk->setFullBlock($x & Chunk::COORD_MASK, $y, $z & Chunk::COORD_MASK, $block->getFullId()); }else{ throw new \InvalidArgumentException("Cannot set block at coordinates x=$x,y=$y,z=$z, terrain is not loaded or out of bounds"); } diff --git a/src/world/World.php b/src/world/World.php index 0ae25d1836..50109a1b36 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -79,6 +79,7 @@ use pocketmine\world\format\io\ChunkData; use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\WritableWorldProvider; use pocketmine\world\format\LightArray; +use pocketmine\world\format\SubChunk; use pocketmine\world\generator\GeneratorManager; use pocketmine\world\generator\GeneratorRegisterTask; use pocketmine\world\generator\GeneratorUnregisterTask; @@ -625,14 +626,14 @@ class World implements ChunkManager{ * @return Player[] */ public function getViewersForPosition(Vector3 $pos) : array{ - return $this->getChunkPlayers($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4); + return $this->getChunkPlayers($pos->getFloorX() >> Chunk::COORD_BIT_SIZE, $pos->getFloorZ() >> Chunk::COORD_BIT_SIZE); } /** * Broadcasts a packet to every player who has the target position within their view distance. */ public function broadcastPacketToViewers(Vector3 $pos, ClientboundPacket $packet) : void{ - $this->broadcastPacketToPlayersUsingChunk($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4, $packet); + $this->broadcastPacketToPlayersUsingChunk($pos->getFloorX() >> Chunk::COORD_BIT_SIZE, $pos->getFloorZ() >> Chunk::COORD_BIT_SIZE, $packet); } private function broadcastPacketToPlayersUsingChunk(int $chunkX, int $chunkZ, ClientboundPacket $packet) : void{ @@ -827,7 +828,7 @@ class World implements ChunkManager{ $index = $this->neighbourBlockUpdateQueue->dequeue(); unset($this->neighbourBlockUpdateQueueIndex[$index]); World::getBlockXYZ($index, $x, $y, $z); - if(!$this->isChunkLoaded($x >> 4, $z >> 4)){ + if(!$this->isChunkLoaded($x >> Chunk::COORD_BIT_SIZE, $z >> Chunk::COORD_BIT_SIZE)){ continue; } @@ -1008,8 +1009,8 @@ class World implements ChunkManager{ $randRange = (int) ($randRange > $this->chunkTickRadius ? $this->chunkTickRadius : $randRange); foreach($this->tickingLoaders as $loader){ - $chunkX = (int) floor($loader->getX()) >> 4; - $chunkZ = (int) floor($loader->getZ()) >> 4; + $chunkX = (int) floor($loader->getX()) >> Chunk::COORD_BIT_SIZE; + $chunkZ = (int) floor($loader->getZ()) >> Chunk::COORD_BIT_SIZE; for($chunk = 0; $chunk < $chunksPerLoader; ++$chunk){ $dx = mt_rand(-$randRange, $randRange); @@ -1103,17 +1104,17 @@ class World implements ChunkManager{ //60 bits will be used by 5 blocks (12 bits each) $k = mt_rand(0, (1 << 60) - 1); } - $x = $k & 0x0f; - $y = ($k >> 4) & 0x0f; - $z = ($k >> 8) & 0x0f; - $k >>= 12; + $x = $k & SubChunk::COORD_MASK; + $y = ($k >> SubChunk::COORD_BIT_SIZE) & SubChunk::COORD_MASK; + $z = ($k >> (SubChunk::COORD_BIT_SIZE * 2)) & SubChunk::COORD_MASK; + $k >>= (SubChunk::COORD_BIT_SIZE * 3); $state = $subChunk->getFullBlock($x, $y, $z); if(isset($this->randomTickBlocks[$state])){ /** @var Block $block */ $block = BlockFactory::getInstance()->fromFullBlock($state); - $block->position($this, $chunkX * 16 + $x, ($Y << 4) + $y, $chunkZ * 16 + $z); + $block->position($this, $chunkX * Chunk::EDGE_LENGTH + $x, ($Y << SubChunk::COORD_BIT_SIZE) + $y, $chunkZ * Chunk::EDGE_LENGTH + $z); $block->onRandomTick(); } } @@ -1369,8 +1370,8 @@ class World implements ChunkManager{ if(!$this->isInWorld($x, $y, $z)){ return $y >= self::Y_MAX ? 15 : 0; } - if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null && $chunk->isLightPopulated() === true){ - return $chunk->getSubChunk($y >> 4)->getBlockSkyLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); + if(($chunk = $this->getChunk($x >> Chunk::COORD_BIT_SIZE, $z >> Chunk::COORD_BIT_SIZE)) !== null && $chunk->isLightPopulated() === true){ + return $chunk->getSubChunk($y >> Chunk::COORD_BIT_SIZE)->getBlockSkyLightArray()->get($x & SubChunk::COORD_MASK, $y & SubChunk::COORD_MASK, $z & SubChunk::COORD_MASK); } return 0; //TODO: this should probably throw instead (light not calculated yet) } @@ -1394,14 +1395,14 @@ class World implements ChunkManager{ if(!$this->isInWorld($x, $y, $z)){ return 0; } - if(($chunk = $this->getChunk($x >> 4, $z >> 4)) !== null && $chunk->isLightPopulated() === true){ - return $chunk->getSubChunk($y >> 4)->getBlockLightArray()->get($x & 0x0f, $y & 0xf, $z & 0x0f); + if(($chunk = $this->getChunk($x >> Chunk::COORD_BIT_SIZE, $z >> Chunk::COORD_BIT_SIZE)) !== null && $chunk->isLightPopulated() === true){ + return $chunk->getSubChunk($y >> Chunk::COORD_BIT_SIZE)->getBlockLightArray()->get($x & SubChunk::COORD_MASK, $y & SubChunk::COORD_MASK, $z & SubChunk::COORD_MASK); } return 0; //TODO: this should probably throw instead (light not calculated yet) } public function updateAllLight(int $x, int $y, int $z) : void{ - if(($chunk = $this->getChunk($x >> 4, $z >> 4)) === null || $chunk->isLightPopulated() !== true){ + if(($chunk = $this->getChunk($x >> Chunk::COORD_BIT_SIZE, $z >> Chunk::COORD_BIT_SIZE)) === null || $chunk->isLightPopulated() !== true){ $this->logger->debug("Skipped runtime light update of x=$x,y=$y,z=$z because the target area has not received base light calculation"); return; } @@ -1437,7 +1438,7 @@ class World implements ChunkManager{ ] as [$x1, $y1, $z1]){ if( !$this->isInWorld($x1, $y1, $z1) || - ($chunk = $this->getChunk($x1 >> 4, $z1 >> 4)) === null || + ($chunk = $this->getChunk($x1 >> Chunk::COORD_BIT_SIZE, $z1 >> Chunk::COORD_BIT_SIZE)) === null || $chunk->isLightPopulated() !== true ){ continue; @@ -1518,7 +1519,7 @@ class World implements ChunkManager{ */ public function getBlockAt(int $x, int $y, int $z, bool $cached = true, bool $addToCache = true) : Block{ $relativeBlockHash = null; - $chunkHash = World::chunkHash($x >> 4, $z >> 4); + $chunkHash = World::chunkHash($x >> Chunk::COORD_BIT_SIZE, $z >> Chunk::COORD_BIT_SIZE); if($this->isInWorld($x, $y, $z)){ $relativeBlockHash = World::chunkBlockHash($x, $y, $z); @@ -1529,7 +1530,7 @@ class World implements ChunkManager{ $chunk = $this->chunks[$chunkHash] ?? null; if($chunk !== null){ - $block = BlockFactory::getInstance()->fromFullBlock($chunk->getFullBlock($x & 0x0f, $y, $z & 0x0f)); + $block = BlockFactory::getInstance()->fromFullBlock($chunk->getFullBlock($x & Chunk::COORD_MASK, $y, $z & Chunk::COORD_MASK)); }else{ $addToCache = false; $block = VanillaBlocks::AIR(); @@ -1581,8 +1582,8 @@ class World implements ChunkManager{ if(!$this->isInWorld($x, $y, $z)){ throw new \InvalidArgumentException("Pos x=$x,y=$y,z=$z is outside of the world bounds"); } - $chunkX = $x >> 4; - $chunkZ = $z >> 4; + $chunkX = $x >> Chunk::COORD_BIT_SIZE; + $chunkZ = $z >> Chunk::COORD_BIT_SIZE; if($this->isChunkLocked($chunkX, $chunkZ)){ throw new WorldException("Terrain is locked for generation/population"); } @@ -1600,7 +1601,7 @@ class World implements ChunkManager{ $block->writeStateToWorld(); $pos = $block->getPosition(); - $chunkHash = World::chunkHash($x >> 4, $z >> 4); + $chunkHash = World::chunkHash($x >> Chunk::COORD_BIT_SIZE, $z >> Chunk::COORD_BIT_SIZE); $relativeBlockHash = World::chunkBlockHash($x, $y, $z); unset($this->blockCache[$chunkHash][$relativeBlockHash]); @@ -1610,7 +1611,7 @@ class World implements ChunkManager{ } $this->changedBlocks[$chunkHash][$relativeBlockHash] = $pos; - foreach($this->getChunkListeners($x >> 4, $z >> 4) as $listener){ + foreach($this->getChunkListeners($x >> Chunk::COORD_BIT_SIZE, $z >> Chunk::COORD_BIT_SIZE) as $listener){ $listener->onBlockChanged($pos); } @@ -1671,8 +1672,8 @@ class World implements ChunkManager{ public function useBreakOn(Vector3 $vector, Item &$item = null, ?Player $player = null, bool $createParticles = false) : bool{ $vector = $vector->floor(); - $chunkX = $vector->getFloorX() >> 4; - $chunkZ = $vector->getFloorZ() >> 4; + $chunkX = $vector->getFloorX() >> Chunk::COORD_BIT_SIZE; + $chunkZ = $vector->getFloorZ() >> Chunk::COORD_BIT_SIZE; if(!$this->isChunkLoaded($chunkX, $chunkZ) || !$this->isChunkGenerated($chunkX, $chunkZ) || $this->isChunkLocked($chunkX, $chunkZ)){ return false; } @@ -1782,8 +1783,8 @@ class World implements ChunkManager{ //TODO: build height limit messages for custom world heights and mcregion cap return false; } - $chunkX = $blockReplace->getPosition()->getFloorX() >> 4; - $chunkZ = $blockReplace->getPosition()->getFloorZ() >> 4; + $chunkX = $blockReplace->getPosition()->getFloorX() >> Chunk::COORD_BIT_SIZE; + $chunkZ = $blockReplace->getPosition()->getFloorZ() >> Chunk::COORD_BIT_SIZE; if(!$this->isChunkLoaded($chunkX, $chunkZ) || !$this->isChunkGenerated($chunkX, $chunkZ) || $this->isChunkLocked($chunkX, $chunkZ)){ return false; } @@ -1932,10 +1933,10 @@ class World implements ChunkManager{ public function getNearbyEntities(AxisAlignedBB $bb, ?Entity $entity = null) : array{ $nearby = []; - $minX = ((int) floor($bb->minX - 2)) >> 4; - $maxX = ((int) floor($bb->maxX + 2)) >> 4; - $minZ = ((int) floor($bb->minZ - 2)) >> 4; - $maxZ = ((int) floor($bb->maxZ + 2)) >> 4; + $minX = ((int) floor($bb->minX - 2)) >> Chunk::COORD_BIT_SIZE; + $maxX = ((int) floor($bb->maxX + 2)) >> Chunk::COORD_BIT_SIZE; + $minZ = ((int) floor($bb->minZ - 2)) >> Chunk::COORD_BIT_SIZE; + $maxZ = ((int) floor($bb->maxZ + 2)) >> Chunk::COORD_BIT_SIZE; for($x = $minX; $x <= $maxX; ++$x){ for($z = $minZ; $z <= $maxZ; ++$z){ @@ -1967,10 +1968,10 @@ class World implements ChunkManager{ public function getNearestEntity(Vector3 $pos, float $maxDistance, string $entityType = Entity::class, bool $includeDead = false) : ?Entity{ assert(is_a($entityType, Entity::class, true)); - $minX = ((int) floor($pos->x - $maxDistance)) >> 4; - $maxX = ((int) floor($pos->x + $maxDistance)) >> 4; - $minZ = ((int) floor($pos->z - $maxDistance)) >> 4; - $maxZ = ((int) floor($pos->z + $maxDistance)) >> 4; + $minX = ((int) floor($pos->x - $maxDistance)) >> Chunk::COORD_BIT_SIZE; + $maxX = ((int) floor($pos->x + $maxDistance)) >> Chunk::COORD_BIT_SIZE; + $minZ = ((int) floor($pos->z - $maxDistance)) >> Chunk::COORD_BIT_SIZE; + $maxZ = ((int) floor($pos->z + $maxDistance)) >> Chunk::COORD_BIT_SIZE; $currentTargetDistSq = $maxDistance ** 2; @@ -2024,12 +2025,12 @@ class World implements ChunkManager{ * Returns the tile at the specified x,y,z coordinates, or null if it does not exist. */ public function getTileAt(int $x, int $y, int $z) : ?Tile{ - return ($chunk = $this->loadChunk($x >> 4, $z >> 4)) !== null ? $chunk->getTile($x & 0x0f, $y, $z & 0x0f) : null; + return ($chunk = $this->loadChunk($x >> Chunk::COORD_BIT_SIZE, $z >> Chunk::COORD_BIT_SIZE)) !== null ? $chunk->getTile($x & Chunk::COORD_MASK, $y, $z & Chunk::COORD_MASK) : null; } public function getBiomeId(int $x, int $z) : int{ - if(($chunk = $this->loadChunk($x >> 4, $z >> 4)) !== null){ - return $chunk->getBiomeId($x & 0x0f, $z & 0x0f); + if(($chunk = $this->loadChunk($x >> Chunk::COORD_BIT_SIZE, $z >> Chunk::COORD_BIT_SIZE)) !== null){ + return $chunk->getBiomeId($x & Chunk::COORD_MASK, $z & Chunk::COORD_MASK); } return BiomeIds::OCEAN; //TODO: this should probably throw instead (terrain not generated yet) } @@ -2039,14 +2040,14 @@ class World implements ChunkManager{ } public function setBiomeId(int $x, int $z, int $biomeId) : void{ - $chunkX = $x >> 4; - $chunkZ = $z >> 4; + $chunkX = $x >> Chunk::COORD_BIT_SIZE; + $chunkZ = $z >> Chunk::COORD_BIT_SIZE; if($this->isChunkLocked($chunkX, $chunkZ)){ //the changes would be overwritten when the generation finishes throw new WorldException("Chunk is currently locked for async generation/population"); } if(($chunk = $this->loadChunk($chunkX, $chunkZ)) !== null){ - $chunk->setBiomeId($x & 0x0f, $z & 0x0f, $biomeId); + $chunk->setBiomeId($x & Chunk::COORD_MASK, $z & Chunk::COORD_MASK, $biomeId); }else{ //if we allowed this, the modifications would be lost when the chunk is created throw new WorldException("Cannot set biome in a non-generated chunk"); @@ -2075,7 +2076,7 @@ class World implements ChunkManager{ * Returns the chunk containing the given Vector3 position. */ public function getOrLoadChunkAtPosition(Vector3 $pos) : ?Chunk{ - return $this->loadChunk($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4); + return $this->loadChunk($pos->getFloorX() >> Chunk::COORD_BIT_SIZE, $pos->getFloorZ() >> Chunk::COORD_BIT_SIZE); } /** @@ -2228,8 +2229,8 @@ class World implements ChunkManager{ * @throws WorldException if the terrain is not generated */ public function getHighestBlockAt(int $x, int $z) : ?int{ - if(($chunk = $this->loadChunk($x >> 4, $z >> 4)) !== null){ - return $chunk->getHighestBlockAt($x & 0x0f, $z & 0x0f); + if(($chunk = $this->loadChunk($x >> Chunk::COORD_BIT_SIZE, $z >> Chunk::COORD_BIT_SIZE)) !== null){ + return $chunk->getHighestBlockAt($x & Chunk::COORD_MASK, $z & Chunk::COORD_MASK); } throw new WorldException("Cannot get highest block in an ungenerated chunk"); } @@ -2238,7 +2239,7 @@ class World implements ChunkManager{ * Returns whether the given position is in a loaded area of terrain. */ public function isInLoadedTerrain(Vector3 $pos) : bool{ - return $this->isChunkLoaded($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4); + return $this->isChunkLoaded($pos->getFloorX() >> Chunk::COORD_BIT_SIZE, $pos->getFloorZ() >> Chunk::COORD_BIT_SIZE); } public function isChunkLoaded(int $x, int $z) : bool{ @@ -2292,7 +2293,7 @@ class World implements ChunkManager{ if($chunk === null){ throw new \InvalidArgumentException("Cannot add an Entity in an ungenerated chunk"); } - $this->entitiesByChunk[World::chunkHash($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4)][$entity->getId()] = $entity; + $this->entitiesByChunk[World::chunkHash($pos->getFloorX() >> Chunk::COORD_BIT_SIZE, $pos->getFloorZ() >> Chunk::COORD_BIT_SIZE)][$entity->getId()] = $entity; $this->entityLastKnownPositions[$entity->getId()] = $pos; if($entity instanceof Player){ @@ -2314,7 +2315,7 @@ class World implements ChunkManager{ throw new \InvalidArgumentException("Entity is not tracked by this world (possibly already removed?)"); } $pos = $this->entityLastKnownPositions[$entity->getId()]; - $chunkHash = World::chunkHash($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4); + $chunkHash = World::chunkHash($pos->getFloorX() >> Chunk::COORD_BIT_SIZE, $pos->getFloorZ() >> Chunk::COORD_BIT_SIZE); if(isset($this->entitiesByChunk[$chunkHash][$entity->getId()])){ unset($this->entitiesByChunk[$chunkHash][$entity->getId()]); if(count($this->entitiesByChunk[$chunkHash]) === 0){ @@ -2343,10 +2344,10 @@ class World implements ChunkManager{ $oldPosition = $this->entityLastKnownPositions[$entity->getId()]; $newPosition = $entity->getPosition(); - $oldChunkX = $oldPosition->getFloorX() >> 4; - $oldChunkZ = $oldPosition->getFloorZ() >> 4; - $newChunkX = $newPosition->getFloorX() >> 4; - $newChunkZ = $newPosition->getFloorZ() >> 4; + $oldChunkX = $oldPosition->getFloorX() >> Chunk::COORD_BIT_SIZE; + $oldChunkZ = $oldPosition->getFloorZ() >> Chunk::COORD_BIT_SIZE; + $newChunkX = $newPosition->getFloorX() >> Chunk::COORD_BIT_SIZE; + $newChunkZ = $newPosition->getFloorZ() >> Chunk::COORD_BIT_SIZE; if($oldChunkX !== $newChunkX || $oldChunkZ !== $newChunkZ){ $oldChunkHash = World::chunkHash($oldChunkX, $oldChunkZ); @@ -2388,8 +2389,8 @@ class World implements ChunkManager{ throw new \InvalidArgumentException("Invalid Tile world"); } - $chunkX = $pos->getFloorX() >> 4; - $chunkZ = $pos->getFloorZ() >> 4; + $chunkX = $pos->getFloorX() >> Chunk::COORD_BIT_SIZE; + $chunkZ = $pos->getFloorZ() >> Chunk::COORD_BIT_SIZE; if(isset($this->chunks[$hash = World::chunkHash($chunkX, $chunkZ)])){ $this->chunks[$hash]->addTile($tile); @@ -2411,8 +2412,8 @@ class World implements ChunkManager{ throw new \InvalidArgumentException("Invalid Tile world"); } - $chunkX = $pos->getFloorX() >> 4; - $chunkZ = $pos->getFloorZ() >> 4; + $chunkX = $pos->getFloorX() >> Chunk::COORD_BIT_SIZE; + $chunkZ = $pos->getFloorZ() >> Chunk::COORD_BIT_SIZE; if(isset($this->chunks[$hash = World::chunkHash($chunkX, $chunkZ)])){ $this->chunks[$hash]->removeTile($tile); @@ -2522,7 +2523,7 @@ class World implements ChunkManager{ } if($tile === null){ $this->getLogger()->warning("Chunk $chunkX $chunkZ: Deleted unknown tile entity type " . $nbt->getString("id", "")); - }elseif(!$this->isChunkLoaded($tile->getPosition()->getFloorX() >> 4, $tile->getPosition()->getFloorZ() >> 4)){ + }elseif(!$this->isChunkLoaded($tile->getPosition()->getFloorX() >> Chunk::COORD_BIT_SIZE, $tile->getPosition()->getFloorZ() >> Chunk::COORD_BIT_SIZE)){ $this->logger->error("Chunk $chunkX $chunkZ: Found tile saved on wrong chunk - unable to fix due to correct chunk not loaded"); }else{ $this->addTile($tile); @@ -2621,8 +2622,8 @@ class World implements ChunkManager{ */ public function isSpawnChunk(int $X, int $Z) : bool{ $spawn = $this->getSpawnLocation(); - $spawnX = $spawn->x >> 4; - $spawnZ = $spawn->z >> 4; + $spawnX = $spawn->x >> Chunk::COORD_BIT_SIZE; + $spawnZ = $spawn->z >> Chunk::COORD_BIT_SIZE; return abs($X - $spawnX) <= 1 and abs($Z - $spawnZ) <= 1; } diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 652f4684ad..452e5a1251 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -31,6 +31,7 @@ use pocketmine\lang\KnownTranslationFactory; use pocketmine\player\ChunkSelector; use pocketmine\Server; use pocketmine\timings\Timings; +use pocketmine\world\format\Chunk; use pocketmine\world\format\io\exception\CorruptedWorldException; use pocketmine\world\format\io\exception\UnsupportedWorldFormatException; use pocketmine\world\format\io\FormatConverter; @@ -268,8 +269,8 @@ class WorldManager{ $this->server->getLogger()->notice($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_backgroundGeneration($name))); $spawnLocation = $world->getSpawnLocation(); - $centerX = $spawnLocation->getFloorX() >> 4; - $centerZ = $spawnLocation->getFloorZ() >> 4; + $centerX = $spawnLocation->getFloorX() >> Chunk::COORD_BIT_SIZE; + $centerZ = $spawnLocation->getFloorZ() >> Chunk::COORD_BIT_SIZE; $selected = iterator_to_array((new ChunkSelector())->selectChunks(8, $centerX, $centerZ)); $done = 0; diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 56894c503e..3691b4dbd4 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -39,6 +39,10 @@ class Chunk{ public const MAX_SUBCHUNKS = 16; + public const EDGE_LENGTH = SubChunk::EDGE_LENGTH; + public const COORD_BIT_SIZE = SubChunk::COORD_BIT_SIZE; + public const COORD_MASK = SubChunk::COORD_MASK; + /** @var int */ private $terrainDirtyFlags = 0; @@ -72,7 +76,7 @@ class Chunk{ $this->subChunks[$y] = $subChunks[$y] ?? new SubChunk(BlockLegacyIds::AIR << Block::INTERNAL_METADATA_BITS, []); } - $val = ($this->subChunks->getSize() * 16); + $val = ($this->subChunks->getSize() * SubChunk::EDGE_LENGTH); $this->heightMap = $heightMap ?? new HeightArray(array_fill(0, 256, $val)); $this->biomeIds = $biomeIds ?? BiomeArray::fill(BiomeIds::OCEAN); } @@ -94,14 +98,14 @@ class Chunk{ * @return int bitmap, (id << 4) | meta */ public function getFullBlock(int $x, int $y, int $z) : int{ - return $this->getSubChunk($y >> 4)->getFullBlock($x, $y & 0x0f, $z); + return $this->getSubChunk($y >> SubChunk::COORD_BIT_SIZE)->getFullBlock($x, $y & SubChunk::COORD_MASK, $z); } /** * Sets the blockstate at the given coordinate by internal ID. */ public function setFullBlock(int $x, int $y, int $z, int $block) : void{ - $this->getSubChunk($y >> 4)->setFullBlock($x, $y & 0xf, $z, $block); + $this->getSubChunk($y >> SubChunk::COORD_BIT_SIZE)->setFullBlock($x, $y & SubChunk::COORD_MASK, $z, $block); $this->terrainDirtyFlags |= self::DIRTY_FLAG_TERRAIN; } @@ -117,7 +121,7 @@ class Chunk{ for($y = $this->subChunks->count() - 1; $y >= 0; --$y){ $height = $this->getSubChunk($y)->getHighestBlockAt($x, $z); if($height !== null){ - return $height | ($y << 4); + return $height | ($y << SubChunk::COORD_BIT_SIZE); } } @@ -328,6 +332,8 @@ class Chunk{ * @param int $z 0-15 */ public static function blockHash(int $x, int $y, int $z) : int{ - return ($y << 8) | (($z & 0x0f) << 4) | ($x & 0x0f); + return ($y << (2 * SubChunk::COORD_BIT_SIZE)) | + (($z & SubChunk::COORD_MASK) << SubChunk::COORD_BIT_SIZE) | + ($x & SubChunk::COORD_MASK); } } diff --git a/src/world/format/SubChunk.php b/src/world/format/SubChunk.php index b9baf52cbe..ea20b917f5 100644 --- a/src/world/format/SubChunk.php +++ b/src/world/format/SubChunk.php @@ -28,6 +28,10 @@ use function array_values; use function count; class SubChunk{ + public const COORD_BIT_SIZE = 4; + public const COORD_MASK = ~(~0 << self::COORD_BIT_SIZE); + public const EDGE_LENGTH = 1 << self::COORD_BIT_SIZE; + /** @var int */ private $emptyBlockId; /** @var PalettedBlockArray[] */ @@ -100,7 +104,7 @@ class SubChunk{ if(count($this->blockLayers) === 0){ return null; } - for($y = 15; $y >= 0; --$y){ + for($y = self::EDGE_LENGTH - 1; $y >= 0; --$y){ if($this->blockLayers[0]->get($x, $y, $z) !== $this->emptyBlockId){ return $y; } diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index d849822b5e..f6aeafba31 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -216,8 +216,8 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ self::deserializeExtraDataKey($chunkVersion, $key, $x, $fullY, $z); - $ySub = ($fullY >> 4) & 0xf; - $y = $key & 0xf; + $ySub = ($fullY >> SubChunk::COORD_BIT_SIZE); + $y = $key & SubChunk::COORD_MASK; $blockId = $value & 0xff; $blockData = ($value >> 8) & 0xf; diff --git a/src/world/generator/Flat.php b/src/world/generator/Flat.php index ac160fbbfc..1aba3ae130 100644 --- a/src/world/generator/Flat.php +++ b/src/world/generator/Flat.php @@ -28,6 +28,7 @@ use pocketmine\item\LegacyStringToItemParser; use pocketmine\item\LegacyStringToItemParserException; use pocketmine\world\ChunkManager; use pocketmine\world\format\Chunk; +use pocketmine\world\format\SubChunk; use pocketmine\world\generator\object\OreType; use pocketmine\world\generator\populator\Ore; use pocketmine\world\generator\populator\Populator; @@ -141,20 +142,20 @@ class Flat extends Generator{ protected function generateBaseChunk() : void{ $this->chunk = new Chunk(); - for($Z = 0; $Z < 16; ++$Z){ - for($X = 0; $X < 16; ++$X){ + for($Z = 0; $Z < Chunk::EDGE_LENGTH; ++$Z){ + for($X = 0; $X < Chunk::EDGE_LENGTH; ++$X){ $this->chunk->setBiomeId($X, $Z, $this->biome); } } $count = count($this->structure); - for($sy = 0; $sy < $count; $sy += 16){ - $subchunk = $this->chunk->getSubChunk($sy >> 4); - for($y = 0; $y < 16 and isset($this->structure[$y | $sy]); ++$y){ + for($sy = 0; $sy < $count; $sy += SubChunk::EDGE_LENGTH){ + $subchunk = $this->chunk->getSubChunk($sy >> SubChunk::COORD_BIT_SIZE); + for($y = 0; $y < SubChunk::EDGE_LENGTH and isset($this->structure[$y | $sy]); ++$y){ $id = $this->structure[$y | $sy]; - for($Z = 0; $Z < 16; ++$Z){ - for($X = 0; $X < 16; ++$X){ + for($Z = 0; $Z < SubChunk::EDGE_LENGTH; ++$Z){ + for($X = 0; $X < SubChunk::EDGE_LENGTH; ++$X){ $subchunk->setFullBlock($X, $y, $Z, $id); } } diff --git a/src/world/generator/hell/Nether.php b/src/world/generator/hell/Nether.php index 3038f4ffbc..8657e25808 100644 --- a/src/world/generator/hell/Nether.php +++ b/src/world/generator/hell/Nether.php @@ -27,6 +27,7 @@ use pocketmine\block\VanillaBlocks; use pocketmine\data\bedrock\BiomeIds; use pocketmine\world\biome\BiomeRegistry; use pocketmine\world\ChunkManager; +use pocketmine\world\format\Chunk; use pocketmine\world\generator\Generator; use pocketmine\world\generator\InvalidGeneratorOptionsException; use pocketmine\world\generator\noise\Simplex; @@ -72,7 +73,7 @@ class Nether extends Generator{ public function generateChunk(ChunkManager $world, int $chunkX, int $chunkZ) : void{ $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed); - $noise = $this->noiseBase->getFastNoise3D(16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16); + $noise = $this->noiseBase->getFastNoise3D(Chunk::EDGE_LENGTH, 128, Chunk::EDGE_LENGTH, 4, 8, 4, $chunkX * Chunk::EDGE_LENGTH, 0, $chunkZ * Chunk::EDGE_LENGTH); $chunk = $world->getChunk($chunkX, $chunkZ); @@ -80,8 +81,8 @@ class Nether extends Generator{ $netherrack = VanillaBlocks::NETHERRACK()->getFullId(); $stillLava = VanillaBlocks::LAVA()->getFullId(); - for($x = 0; $x < 16; ++$x){ - for($z = 0; $z < 16; ++$z){ + for($x = 0; $x < Chunk::EDGE_LENGTH; ++$x){ + for($z = 0; $z < Chunk::EDGE_LENGTH; ++$z){ $chunk->setBiomeId($x, $z, BiomeIds::HELL); for($y = 0; $y < 128; ++$y){ diff --git a/src/world/generator/normal/Normal.php b/src/world/generator/normal/Normal.php index 9ee0426820..f8a006663c 100644 --- a/src/world/generator/normal/Normal.php +++ b/src/world/generator/normal/Normal.php @@ -28,6 +28,7 @@ use pocketmine\data\bedrock\BiomeIds; use pocketmine\world\biome\Biome; use pocketmine\world\biome\BiomeRegistry; use pocketmine\world\ChunkManager; +use pocketmine\world\format\Chunk; use pocketmine\world\generator\biome\BiomeSelector; use pocketmine\world\generator\Gaussian; use pocketmine\world\generator\Generator; @@ -144,7 +145,7 @@ class Normal extends Generator{ public function generateChunk(ChunkManager $world, int $chunkX, int $chunkZ) : void{ $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->seed); - $noise = $this->noiseBase->getFastNoise3D(16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16); + $noise = $this->noiseBase->getFastNoise3D(Chunk::EDGE_LENGTH, 128, Chunk::EDGE_LENGTH, 4, 8, 4, $chunkX * Chunk::EDGE_LENGTH, 0, $chunkZ * Chunk::EDGE_LENGTH); $chunk = $world->getChunk($chunkX, $chunkZ); @@ -154,11 +155,11 @@ class Normal extends Generator{ $stillWater = VanillaBlocks::WATER()->getFullId(); $stone = VanillaBlocks::STONE()->getFullId(); - $baseX = $chunkX * 16; - $baseZ = $chunkZ * 16; - for($x = 0; $x < 16; ++$x){ + $baseX = $chunkX * Chunk::EDGE_LENGTH; + $baseZ = $chunkZ * Chunk::EDGE_LENGTH; + for($x = 0; $x < Chunk::EDGE_LENGTH; ++$x){ $absoluteX = $baseX + $x; - for($z = 0; $z < 16; ++$z){ + for($z = 0; $z < Chunk::EDGE_LENGTH; ++$z){ $absoluteZ = $baseZ + $z; $minSum = 0; $maxSum = 0; diff --git a/src/world/generator/populator/GroundCover.php b/src/world/generator/populator/GroundCover.php index ed4c652047..da5a336a3e 100644 --- a/src/world/generator/populator/GroundCover.php +++ b/src/world/generator/populator/GroundCover.php @@ -29,6 +29,7 @@ use pocketmine\block\Liquid; use pocketmine\utils\Random; use pocketmine\world\biome\BiomeRegistry; use pocketmine\world\ChunkManager; +use pocketmine\world\format\Chunk; use function count; use function min; @@ -38,8 +39,8 @@ class GroundCover implements Populator{ $chunk = $world->getChunk($chunkX, $chunkZ); $factory = BlockFactory::getInstance(); $biomeRegistry = BiomeRegistry::getInstance(); - for($x = 0; $x < 16; ++$x){ - for($z = 0; $z < 16; ++$z){ + for($x = 0; $x < Chunk::EDGE_LENGTH; ++$x){ + for($z = 0; $z < Chunk::EDGE_LENGTH; ++$z){ $biome = $biomeRegistry->getBiome($chunk->getBiomeId($x, $z)); $cover = $biome->getGroundCover(); if(count($cover) > 0){ diff --git a/src/world/generator/populator/Ore.php b/src/world/generator/populator/Ore.php index 4c3261a763..7a0d6aff9c 100644 --- a/src/world/generator/populator/Ore.php +++ b/src/world/generator/populator/Ore.php @@ -25,6 +25,7 @@ namespace pocketmine\world\generator\populator; use pocketmine\utils\Random; use pocketmine\world\ChunkManager; +use pocketmine\world\format\Chunk; use pocketmine\world\generator\object\Ore as ObjectOre; use pocketmine\world\generator\object\OreType; @@ -36,9 +37,9 @@ class Ore implements Populator{ foreach($this->oreTypes as $type){ $ore = new ObjectOre($random, $type); for($i = 0; $i < $ore->type->clusterCount; ++$i){ - $x = $random->nextRange($chunkX << 4, ($chunkX << 4) + 15); + $x = $random->nextRange($chunkX << Chunk::COORD_BIT_SIZE, ($chunkX << Chunk::COORD_BIT_SIZE) + Chunk::EDGE_LENGTH - 1); $y = $random->nextRange($ore->type->minHeight, $ore->type->maxHeight); - $z = $random->nextRange($chunkZ << 4, ($chunkZ << 4) + 15); + $z = $random->nextRange($chunkZ << Chunk::COORD_BIT_SIZE, ($chunkZ << Chunk::COORD_BIT_SIZE) + Chunk::EDGE_LENGTH - 1); if($ore->canPlaceObject($world, $x, $y, $z)){ $ore->placeObject($world, $x, $y, $z); } diff --git a/src/world/generator/populator/TallGrass.php b/src/world/generator/populator/TallGrass.php index a448fba96d..6783e6537a 100644 --- a/src/world/generator/populator/TallGrass.php +++ b/src/world/generator/populator/TallGrass.php @@ -27,6 +27,7 @@ use pocketmine\block\BlockLegacyIds; use pocketmine\block\VanillaBlocks; use pocketmine\utils\Random; use pocketmine\world\ChunkManager; +use pocketmine\world\format\Chunk; class TallGrass implements Populator{ /** @var int */ @@ -47,8 +48,8 @@ class TallGrass implements Populator{ $block = VanillaBlocks::TALL_GRASS(); for($i = 0; $i < $amount; ++$i){ - $x = $random->nextRange($chunkX * 16, $chunkX * 16 + 15); - $z = $random->nextRange($chunkZ * 16, $chunkZ * 16 + 15); + $x = $random->nextRange($chunkX * Chunk::EDGE_LENGTH, $chunkX * Chunk::EDGE_LENGTH + (Chunk::EDGE_LENGTH - 1)); + $z = $random->nextRange($chunkZ * Chunk::EDGE_LENGTH, $chunkZ * Chunk::EDGE_LENGTH + (Chunk::EDGE_LENGTH - 1)); $y = $this->getHighestWorkableBlock($world, $x, $z); if($y !== -1 and $this->canTallGrassStay($world, $x, $y, $z)){ diff --git a/src/world/generator/populator/Tree.php b/src/world/generator/populator/Tree.php index 005fabb842..45eb64835c 100644 --- a/src/world/generator/populator/Tree.php +++ b/src/world/generator/populator/Tree.php @@ -27,6 +27,7 @@ use pocketmine\block\BlockLegacyIds; use pocketmine\block\utils\TreeType; use pocketmine\utils\Random; use pocketmine\world\ChunkManager; +use pocketmine\world\format\Chunk; use pocketmine\world\generator\object\TreeFactory; class Tree implements Populator{ @@ -56,8 +57,8 @@ class Tree implements Populator{ public function populate(ChunkManager $world, int $chunkX, int $chunkZ, Random $random) : void{ $amount = $random->nextRange(0, $this->randomAmount) + $this->baseAmount; for($i = 0; $i < $amount; ++$i){ - $x = $random->nextRange($chunkX << 4, ($chunkX << 4) + 15); - $z = $random->nextRange($chunkZ << 4, ($chunkZ << 4) + 15); + $x = $random->nextRange($chunkX << Chunk::COORD_BIT_SIZE, ($chunkX << Chunk::COORD_BIT_SIZE) + Chunk::EDGE_LENGTH); + $z = $random->nextRange($chunkZ << Chunk::COORD_BIT_SIZE, ($chunkZ << Chunk::COORD_BIT_SIZE) + Chunk::EDGE_LENGTH); $y = $this->getHighestWorkableBlock($world, $x, $z); if($y === -1){ continue; diff --git a/src/world/light/BlockLightUpdate.php b/src/world/light/BlockLightUpdate.php index ed1bf5d272..5036400d8f 100644 --- a/src/world/light/BlockLightUpdate.php +++ b/src/world/light/BlockLightUpdate.php @@ -54,7 +54,7 @@ class BlockLightUpdate extends LightUpdate{ public function recalculateNode(int $x, int $y, int $z) : void{ if($this->subChunkExplorer->moveTo($x, $y, $z) !== SubChunkExplorerStatus::INVALID){ - $block = $this->subChunkExplorer->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf); + $block = $this->subChunkExplorer->currentSubChunk->getFullBlock($x & SubChunk::COORD_MASK, $y & SubChunk::COORD_MASK, $z & SubChunk::COORD_MASK); $this->setAndUpdateLight($x, $y, $z, max($this->lightEmitters[$block], $this->getHighestAdjacentLight($x, $y, $z) - $this->lightFilters[$block])); } } @@ -72,7 +72,7 @@ class BlockLightUpdate extends LightUpdate{ foreach($subChunk->getBlockLayers() as $layer){ foreach($layer->getPalette() as $state){ if($this->lightEmitters[$state] > 0){ - $lightSources += $this->scanForLightEmittingBlocks($subChunk, $chunkX << 4, $subChunkY << 4, $chunkZ << 4); + $lightSources += $this->scanForLightEmittingBlocks($subChunk, $chunkX << SubChunk::COORD_BIT_SIZE, $subChunkY << SubChunk::COORD_BIT_SIZE, $chunkZ << SubChunk::COORD_BIT_SIZE); break 2; } } @@ -84,9 +84,9 @@ class BlockLightUpdate extends LightUpdate{ private function scanForLightEmittingBlocks(SubChunk $subChunk, int $baseX, int $baseY, int $baseZ) : int{ $lightSources = 0; - for($x = 0; $x < 16; ++$x){ - for($z = 0; $z < 16; ++$z){ - for($y = 0; $y < 16; ++$y){ + for($x = 0; $x < SubChunk::EDGE_LENGTH; ++$x){ + for($z = 0; $z < SubChunk::EDGE_LENGTH; ++$z){ + for($y = 0; $y < SubChunk::EDGE_LENGTH; ++$y){ $light = $this->lightEmitters[$subChunk->getFullBlock($x, $y, $z)]; if($light > 0){ $this->setAndUpdateLight( diff --git a/src/world/light/LightUpdate.php b/src/world/light/LightUpdate.php index ed430354a3..a8b196a520 100644 --- a/src/world/light/LightUpdate.php +++ b/src/world/light/LightUpdate.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\world\light; use pocketmine\world\format\LightArray; +use pocketmine\world\format\SubChunk; use pocketmine\world\utils\SubChunkExplorer; use pocketmine\world\utils\SubChunkExplorerStatus; use pocketmine\world\World; @@ -77,7 +78,7 @@ abstract class LightUpdate{ protected function getEffectiveLight(int $x, int $y, int $z) : int{ if($this->subChunkExplorer->moveTo($x, $y, $z) !== SubChunkExplorerStatus::INVALID){ - return $this->getCurrentLightArray()->get($x & 0xf, $y & 0xf, $z & 0xf); + return $this->getCurrentLightArray()->get($x & SubChunk::COORD_MASK, $y & SubChunk::COORD_MASK, $z & SubChunk::COORD_MASK); } return 0; } @@ -101,10 +102,10 @@ abstract class LightUpdate{ foreach($this->updateNodes as $blockHash => [$x, $y, $z, $newLevel]){ if($this->subChunkExplorer->moveTo($x, $y, $z) !== SubChunkExplorerStatus::INVALID){ $lightArray = $this->getCurrentLightArray(); - $oldLevel = $lightArray->get($x & 0xf, $y & 0xf, $z & 0xf); + $oldLevel = $lightArray->get($x & SubChunk::COORD_MASK, $y & SubChunk::COORD_MASK, $z & SubChunk::COORD_MASK); if($oldLevel !== $newLevel){ - $lightArray->set($x & 0xf, $y & 0xf, $z & 0xf, $newLevel); + $lightArray->set($x & SubChunk::COORD_MASK, $y & SubChunk::COORD_MASK, $z & SubChunk::COORD_MASK, $newLevel); if($oldLevel < $newLevel){ //light increased $context->spreadVisited[$blockHash] = true; $context->spreadQueue->enqueue([$x, $y, $z]); @@ -167,9 +168,9 @@ abstract class LightUpdate{ protected function computeRemoveLight(int $x, int $y, int $z, int $oldAdjacentLevel, LightPropagationContext $context) : void{ $lightArray = $this->getCurrentLightArray(); - $lx = $x & 0xf; - $ly = $y & 0xf; - $lz = $z & 0xf; + $lx = $x & SubChunk::COORD_MASK; + $ly = $y & SubChunk::COORD_MASK; + $lz = $z & SubChunk::COORD_MASK; $current = $lightArray->get($lx, $ly, $lz); if($current !== 0 and $current < $oldAdjacentLevel){ @@ -191,9 +192,9 @@ abstract class LightUpdate{ protected function computeSpreadLight(int $x, int $y, int $z, int $newAdjacentLevel, LightPropagationContext $context) : void{ $lightArray = $this->getCurrentLightArray(); - $lx = $x & 0xf; - $ly = $y & 0xf; - $lz = $z & 0xf; + $lx = $x & SubChunk::COORD_MASK; + $ly = $y & SubChunk::COORD_MASK; + $lz = $z & SubChunk::COORD_MASK; $current = $lightArray->get($lx, $ly, $lz); $potentialLight = $newAdjacentLevel - $this->lightFilters[$this->subChunkExplorer->currentSubChunk->getFullBlock($lx, $ly, $lz)]; diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index e86cf95bb9..e9507c153e 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -26,6 +26,7 @@ namespace pocketmine\world\light; use pocketmine\world\format\Chunk; use pocketmine\world\format\HeightArray; use pocketmine\world\format\LightArray; +use pocketmine\world\format\SubChunk; use pocketmine\world\utils\SubChunkExplorer; use pocketmine\world\utils\SubChunkExplorerStatus; use pocketmine\world\World; @@ -68,17 +69,17 @@ class SkyLightUpdate extends LightUpdate{ } $chunk = $this->subChunkExplorer->currentChunk; - $oldHeightMap = $chunk->getHeightMap($x & 0xf, $z & 0xf); - $source = $this->subChunkExplorer->currentSubChunk->getFullBlock($x & 0xf, $y & 0xf, $z & 0xf); + $oldHeightMap = $chunk->getHeightMap($x & Chunk::COORD_MASK, $z & Chunk::COORD_MASK); + $source = $this->subChunkExplorer->currentSubChunk->getFullBlock($x & SubChunk::COORD_MASK, $y & SubChunk::COORD_MASK, $z & SubChunk::COORD_MASK); $yPlusOne = $y + 1; if($yPlusOne === $oldHeightMap){ //Block changed directly beneath the heightmap. Check if a block was removed or changed to a different light-filter. - $newHeightMap = self::recalculateHeightMapColumn($chunk, $x & 0x0f, $z & 0x0f, $this->directSkyLightBlockers); - $chunk->setHeightMap($x & 0xf, $z & 0xf, $newHeightMap); + $newHeightMap = self::recalculateHeightMapColumn($chunk, $x & Chunk::COORD_MASK, $z & Chunk::COORD_MASK, $this->directSkyLightBlockers); + $chunk->setHeightMap($x & Chunk::COORD_MASK, $z & Chunk::COORD_MASK, $newHeightMap); }elseif($yPlusOne > $oldHeightMap){ //Block changed above the heightmap. if($this->directSkyLightBlockers[$source]){ - $chunk->setHeightMap($x & 0xf, $z & 0xf, $yPlusOne); + $chunk->setHeightMap($x & Chunk::COORD_MASK, $z & Chunk::COORD_MASK, $yPlusOne); $newHeightMap = $yPlusOne; }else{ //Block changed which has no effect on direct sky light, for example placing or removing glass. return; @@ -112,7 +113,7 @@ class SkyLightUpdate extends LightUpdate{ //setAndUpdateLight() won't bother propagating from nodes that are already what we want to change them to, so we //have to avoid filling full light for any subchunk that contains a heightmap Y coordinate $highestHeightMapPlusOne = max($chunk->getHeightMapArray()) + 1; - $lowestClearSubChunk = ($highestHeightMapPlusOne >> 4) + (($highestHeightMapPlusOne & 0xf) !== 0 ? 1 : 0); + $lowestClearSubChunk = ($highestHeightMapPlusOne >> SubChunk::COORD_BIT_SIZE) + (($highestHeightMapPlusOne & SubChunk::COORD_MASK) !== 0 ? 1 : 0); $chunkHeight = $chunk->getSubChunks()->count(); for($y = 0; $y < $lowestClearSubChunk && $y < $chunkHeight; $y++){ $chunk->getSubChunk($y)->setBlockSkyLightArray(LightArray::fill(0)); @@ -123,10 +124,10 @@ class SkyLightUpdate extends LightUpdate{ $lightSources = 0; - $baseX = $chunkX << 4; - $baseZ = $chunkZ << 4; - for($x = 0; $x < 16; ++$x){ - for($z = 0; $z < 16; ++$z){ + $baseX = $chunkX << Chunk::COORD_BIT_SIZE; + $baseZ = $chunkZ << Chunk::COORD_BIT_SIZE; + for($x = 0; $x < Chunk::EDGE_LENGTH; ++$x){ + for($z = 0; $z < Chunk::EDGE_LENGTH; ++$z){ $currentHeight = $chunk->getHeightMap($x, $z); $maxAdjacentHeight = 0; if($x !== 0){ @@ -154,9 +155,9 @@ class SkyLightUpdate extends LightUpdate{ $this->setAndUpdateLight($x + $baseX, $y, $z + $baseZ, 15); $lightSources++; } - for($y = $nodeColumnEnd + 1, $yMax = $lowestClearSubChunk * 16; $y < $yMax; $y++){ + for($y = $nodeColumnEnd + 1, $yMax = $lowestClearSubChunk * SubChunk::EDGE_LENGTH; $y < $yMax; $y++){ if($this->subChunkExplorer->moveTo($x + $baseX, $y, $z + $baseZ) !== SubChunkExplorerStatus::INVALID){ - $this->getCurrentLightArray()->set($x, $y & 0xf, $z, 15); + $this->getCurrentLightArray()->set($x, $y & SubChunk::COORD_MASK, $z, 15); } } } @@ -183,13 +184,13 @@ class SkyLightUpdate extends LightUpdate{ return $result; } - for($z = 0; $z < 16; ++$z){ - for($x = 0; $x < 16; ++$x){ + for($z = 0; $z < Chunk::EDGE_LENGTH; ++$z){ + for($x = 0; $x < Chunk::EDGE_LENGTH; ++$x){ $y = null; for($subChunkY = $maxSubChunkY; $subChunkY >= 0; $subChunkY--){ $subHighestBlockY = $chunk->getSubChunk($subChunkY)->getHighestBlockAt($x, $z); if($subHighestBlockY !== null){ - $y = ($subChunkY * 16) + $subHighestBlockY; + $y = ($subChunkY * SubChunk::EDGE_LENGTH) + $subHighestBlockY; break; } } diff --git a/src/world/utils/SubChunkExplorer.php b/src/world/utils/SubChunkExplorer.php index 05685b6cfd..9d7faeb969 100644 --- a/src/world/utils/SubChunkExplorer.php +++ b/src/world/utils/SubChunkExplorer.php @@ -51,8 +51,8 @@ class SubChunkExplorer{ * @phpstan-return SubChunkExplorerStatus::* */ public function moveTo(int $x, int $y, int $z) : int{ - $newChunkX = $x >> 4; - $newChunkZ = $z >> 4; + $newChunkX = $x >> SubChunk::COORD_BIT_SIZE; + $newChunkZ = $z >> SubChunk::COORD_BIT_SIZE; if($this->currentChunk === null or $this->currentX !== $newChunkX or $this->currentZ !== $newChunkZ){ $this->currentX = $newChunkX; $this->currentZ = $newChunkZ; @@ -64,7 +64,7 @@ class SubChunkExplorer{ } } - $newChunkY = $y >> 4; + $newChunkY = $y >> SubChunk::COORD_BIT_SIZE; if($this->currentSubChunk === null or $this->currentY !== $newChunkY){ $this->currentY = $newChunkY; @@ -85,7 +85,7 @@ class SubChunkExplorer{ */ public function moveToChunk(int $chunkX, int $chunkY, int $chunkZ) : int{ //this is a cold path, so we don't care much if it's a bit slower (extra fcall overhead) - return $this->moveTo($chunkX << 4, $chunkY << 4, $chunkZ << 4); + return $this->moveTo($chunkX << SubChunk::COORD_BIT_SIZE, $chunkY << SubChunk::COORD_BIT_SIZE, $chunkZ << SubChunk::COORD_BIT_SIZE); } /** From 7701e1ff988af54eee167bc3e2281762b6c017d7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 10 Sep 2021 16:52:27 +0100 Subject: [PATCH 2836/3224] InGamePacketHandler: fix regression in movement handling since 82c8fa696a2e8609d8ae086c52f96abe7c7705b6 fixes #4291 fixes #4398 --- src/network/mcpe/handler/InGamePacketHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 47e0debeb0..c36510d022 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -177,7 +177,7 @@ class InGamePacketHandler extends PacketHandler{ $this->player->setRotation($yaw, $pitch); $curPos = $this->player->getLocation(); - $newPos = $packet->position->subtract(0, 1.62, 0); + $newPos = $packet->position->round(4)->subtract(0, 1.62, 0); if($this->forceMoveSync and $newPos->distanceSquared($curPos) > 1){ //Tolerate up to 1 block to avoid problems with client-sided physics when spawning in blocks $this->session->getLogger()->debug("Got outdated pre-teleport movement, received " . $newPos . ", expected " . $curPos); From c995c2de37499c41cb21ad9dc28473f8a7b32b7b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 10 Sep 2021 17:04:35 +0100 Subject: [PATCH 2837/3224] updated changelog [ci skip] --- changelogs/4.0.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index 8916a6f286..b45913e7ee 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1274,11 +1274,14 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - The title bar no longer displays heap memory usage numbers (nobody seemed to know that was what it was, anyway). - `/status` no longer displays heap memory usage numbers. - `start.sh` no longer specifically mentions PHP 7 when erroring because of a missing PHP binary. +- Debug messages are now logged when reach distance checks prevent players from doing something. ## Fixes - Fixed players getting disconnected when using `/tp` to ungenerated chunks (or when teleported by players). - Fixed a potential memory leak in block updating when chunks are unloaded. - Fixed `Living->lookAt()` not taking eye height into account. +- Fixed grass replacing itself when placing grass (and consuming inventory items). +- Fixed players taking fall damage when falling next to a wall. ## API changes - The following API methods have been added: @@ -1289,3 +1292,12 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Chunk->getSavableEntities()` - `Chunk->addEntity()` - `Chunk->removeEntity()` +- The following classes have been added: + - `pocketmine\inventory\transaction\TransactionBuilderInventory`: facilitates building `InventoryTransaction`s using standard `Inventory` API methods +- The following class constants have been added: + - `Chunk::EDGE_LENGTH` + - `Chunk::COORD_BIT_SIZE` + - `Chunk::COORD_MASK` + - `SubChunk::EDGE_LENGTH` + - `SubChunk::COORD_BIT_SIZE` + - `SubChunk::COORD_MASK` From 26e3280fea976b4ce634e07685122e1843d99ca0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 10 Sep 2021 17:18:31 +0100 Subject: [PATCH 2838/3224] Release 4.0.0-BETA2 --- changelogs/4.0.md | 2 +- src/VersionInfo.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index b45913e7ee..bbf2937da4 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1265,7 +1265,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - Implemented offhand inventory. # 4.0.0-BETA2 - +Released 10th September 2021. ## General - ext-chunkutils 0.3.x is now required. diff --git a/src/VersionInfo.php b/src/VersionInfo.php index c9fdad2dd2..1f9262e26d 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -30,9 +30,9 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; public const BASE_VERSION = "4.0.0-BETA2"; - public const IS_DEVELOPMENT_BUILD = true; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_NUMBER = 0; - public const BUILD_CHANNEL = ""; + public const BUILD_CHANNEL = "beta"; private function __construct(){ //NOOP From b65e3c69b110102e1741e3108b911221454680e4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 10 Sep 2021 17:18:32 +0100 Subject: [PATCH 2839/3224] 4.0.0-BETA3 is next --- src/VersionInfo.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 1f9262e26d..f049a991ec 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -29,10 +29,10 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "4.0.0-BETA2"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "4.0.0-BETA3"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_NUMBER = 0; - public const BUILD_CHANNEL = "beta"; + public const BUILD_CHANNEL = ""; private function __construct(){ //NOOP From 3b7580688c575b8585bb4f95b23b9691f0a7aca1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 11 Sep 2021 16:46:40 +0100 Subject: [PATCH 2840/3224] Stop auto-translating string descriptions/usages for commands Require usage of Translatable for translations. --- src/command/Command.php | 14 +++++++------- src/command/SimpleCommandMap.php | 2 +- src/command/defaults/BanCommand.php | 5 ++--- src/command/defaults/BanIpCommand.php | 5 ++--- src/command/defaults/BanListCommand.php | 5 ++--- src/command/defaults/ClearCommand.php | 5 ++--- .../defaults/DefaultGamemodeCommand.php | 5 ++--- src/command/defaults/DeopCommand.php | 5 ++--- src/command/defaults/DifficultyCommand.php | 5 ++--- src/command/defaults/EffectCommand.php | 5 ++--- src/command/defaults/EnchantCommand.php | 5 ++--- src/command/defaults/GamemodeCommand.php | 5 ++--- .../defaults/GarbageCollectorCommand.php | 5 ++--- src/command/defaults/GiveCommand.php | 5 ++--- src/command/defaults/HelpCommand.php | 19 +++++++++++++------ src/command/defaults/KickCommand.php | 5 ++--- src/command/defaults/KillCommand.php | 5 ++--- src/command/defaults/ListCommand.php | 5 ++--- src/command/defaults/MeCommand.php | 5 ++--- src/command/defaults/OpCommand.php | 5 ++--- src/command/defaults/PardonCommand.php | 5 ++--- src/command/defaults/PardonIpCommand.php | 5 ++--- src/command/defaults/ParticleCommand.php | 5 ++--- src/command/defaults/PluginsCommand.php | 5 ++--- src/command/defaults/SaveCommand.php | 5 ++--- src/command/defaults/SaveOffCommand.php | 5 ++--- src/command/defaults/SaveOnCommand.php | 5 ++--- src/command/defaults/SayCommand.php | 5 ++--- src/command/defaults/SeedCommand.php | 5 ++--- src/command/defaults/SetWorldSpawnCommand.php | 5 ++--- src/command/defaults/SpawnpointCommand.php | 5 ++--- src/command/defaults/StatusCommand.php | 6 +++--- src/command/defaults/StopCommand.php | 5 ++--- src/command/defaults/TeleportCommand.php | 5 ++--- src/command/defaults/TellCommand.php | 5 ++--- src/command/defaults/TimeCommand.php | 5 ++--- src/command/defaults/TimingsCommand.php | 5 ++--- src/command/defaults/TitleCommand.php | 5 ++--- .../defaults/TransferServerCommand.php | 6 +++--- src/command/defaults/VersionCommand.php | 5 ++--- src/command/defaults/WhitelistCommand.php | 5 ++--- src/network/mcpe/NetworkSession.php | 4 +++- .../check-explicit-mixed-baseline.neon | 4 ++-- 43 files changed, 104 insertions(+), 131 deletions(-) diff --git a/src/command/Command.php b/src/command/Command.php index fbd9797848..ff08620f1f 100644 --- a/src/command/Command.php +++ b/src/command/Command.php @@ -58,10 +58,10 @@ abstract class Command{ /** @var CommandMap|null */ private $commandMap = null; - /** @var string */ + /** @var Translatable|string */ protected $description = ""; - /** @var string */ + /** @var Translatable|string */ protected $usageMessage; /** @var string|null */ @@ -76,7 +76,7 @@ abstract class Command{ /** * @param string[] $aliases */ - public function __construct(string $name, string $description = "", ?string $usageMessage = null, array $aliases = []){ + public function __construct(string $name, Translatable|string $description = "", Translatable|string|null $usageMessage = null, array $aliases = []){ $this->name = $name; $this->setLabel($name); $this->setDescription($description); @@ -200,11 +200,11 @@ abstract class Command{ return $this->permissionMessage; } - public function getDescription() : string{ + public function getDescription() : Translatable|string{ return $this->description; } - public function getUsage() : string{ + public function getUsage() : Translatable|string{ return $this->usageMessage; } @@ -218,7 +218,7 @@ abstract class Command{ } } - public function setDescription(string $description) : void{ + public function setDescription(Translatable|string $description) : void{ $this->description = $description; } @@ -226,7 +226,7 @@ abstract class Command{ $this->permissionMessage = $permissionMessage; } - public function setUsage(string $usage) : void{ + public function setUsage(Translatable|string $usage) : void{ $this->usageMessage = $usage; } diff --git a/src/command/SimpleCommandMap.php b/src/command/SimpleCommandMap.php index aab3a9e8ed..638e107400 100644 --- a/src/command/SimpleCommandMap.php +++ b/src/command/SimpleCommandMap.php @@ -224,7 +224,7 @@ class SimpleCommandMap implements CommandMap{ try{ $target->execute($sender, $sentCommandLabel, $args); }catch(InvalidCommandSyntaxException $e){ - $sender->sendMessage($sender->getLanguage()->translate(KnownTranslationFactory::commands_generic_usage($sender->getLanguage()->translateString($target->getUsage())))); + $sender->sendMessage($sender->getLanguage()->translate(KnownTranslationFactory::commands_generic_usage($target->getUsage()))); }finally{ $target->timings->stopTiming(); } diff --git a/src/command/defaults/BanCommand.php b/src/command/defaults/BanCommand.php index 3e264abf83..4b734303d1 100644 --- a/src/command/defaults/BanCommand.php +++ b/src/command/defaults/BanCommand.php @@ -27,7 +27,6 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use function array_shift; @@ -39,8 +38,8 @@ class BanCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_BAN_PLAYER_DESCRIPTION, - KnownTranslationKeys::COMMANDS_BAN_USAGE + KnownTranslationFactory::pocketmine_command_ban_player_description(), + KnownTranslationFactory::commands_ban_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_BAN_PLAYER); } diff --git a/src/command/defaults/BanIpCommand.php b/src/command/defaults/BanIpCommand.php index 13305b7844..fca99eff64 100644 --- a/src/command/defaults/BanIpCommand.php +++ b/src/command/defaults/BanIpCommand.php @@ -27,7 +27,6 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use function array_shift; @@ -40,8 +39,8 @@ class BanIpCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_BAN_IP_DESCRIPTION, - KnownTranslationKeys::COMMANDS_BANIP_USAGE + KnownTranslationFactory::pocketmine_command_ban_ip_description(), + KnownTranslationFactory::commands_banip_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_BAN_IP); } diff --git a/src/command/defaults/BanListCommand.php b/src/command/defaults/BanListCommand.php index 3cf92076ce..f3bd20baa8 100644 --- a/src/command/defaults/BanListCommand.php +++ b/src/command/defaults/BanListCommand.php @@ -26,7 +26,6 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\BanEntry; use pocketmine\permission\DefaultPermissionNames; use function array_map; @@ -41,8 +40,8 @@ class BanListCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_BANLIST_DESCRIPTION, - KnownTranslationKeys::COMMANDS_BANLIST_USAGE + KnownTranslationFactory::pocketmine_command_banlist_description(), + KnownTranslationFactory::commands_banlist_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_BAN_LIST); } diff --git a/src/command/defaults/ClearCommand.php b/src/command/defaults/ClearCommand.php index 265549a9a8..59bee1e5b8 100644 --- a/src/command/defaults/ClearCommand.php +++ b/src/command/defaults/ClearCommand.php @@ -30,7 +30,6 @@ use pocketmine\item\LegacyStringToItemParser; use pocketmine\item\LegacyStringToItemParserException; use pocketmine\item\StringToItemParser; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; @@ -43,8 +42,8 @@ class ClearCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_CLEAR_DESCRIPTION, - KnownTranslationKeys::POCKETMINE_COMMAND_CLEAR_USAGE + KnownTranslationFactory::pocketmine_command_clear_description(), + KnownTranslationFactory::pocketmine_command_clear_usage() ); $this->setPermission(implode(";", [DefaultPermissionNames::COMMAND_CLEAR_SELF, DefaultPermissionNames::COMMAND_CLEAR_OTHER])); } diff --git a/src/command/defaults/DefaultGamemodeCommand.php b/src/command/defaults/DefaultGamemodeCommand.php index 501ef98fab..f7752319e2 100644 --- a/src/command/defaults/DefaultGamemodeCommand.php +++ b/src/command/defaults/DefaultGamemodeCommand.php @@ -27,7 +27,6 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\data\java\GameModeIdMap; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\GameMode; use function count; @@ -37,8 +36,8 @@ class DefaultGamemodeCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_DEFAULTGAMEMODE_DESCRIPTION, - KnownTranslationKeys::COMMANDS_DEFAULTGAMEMODE_USAGE + KnownTranslationFactory::pocketmine_command_defaultgamemode_description(), + KnownTranslationFactory::commands_defaultgamemode_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_DEFAULTGAMEMODE); } diff --git a/src/command/defaults/DeopCommand.php b/src/command/defaults/DeopCommand.php index 7d94c56330..9dbd0757c5 100644 --- a/src/command/defaults/DeopCommand.php +++ b/src/command/defaults/DeopCommand.php @@ -27,7 +27,6 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; @@ -39,8 +38,8 @@ class DeopCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_DEOP_DESCRIPTION, - KnownTranslationKeys::COMMANDS_DEOP_USAGE + KnownTranslationFactory::pocketmine_command_deop_description(), + KnownTranslationFactory::commands_deop_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_OP_TAKE); } diff --git a/src/command/defaults/DifficultyCommand.php b/src/command/defaults/DifficultyCommand.php index c61fc2516e..7ccde43f09 100644 --- a/src/command/defaults/DifficultyCommand.php +++ b/src/command/defaults/DifficultyCommand.php @@ -27,7 +27,6 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\world\World; use function count; @@ -37,8 +36,8 @@ class DifficultyCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_DIFFICULTY_DESCRIPTION, - KnownTranslationKeys::COMMANDS_DIFFICULTY_USAGE + KnownTranslationFactory::pocketmine_command_difficulty_description(), + KnownTranslationFactory::commands_difficulty_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_DIFFICULTY); } diff --git a/src/command/defaults/EffectCommand.php b/src/command/defaults/EffectCommand.php index ac5828d656..84fa8585e5 100644 --- a/src/command/defaults/EffectCommand.php +++ b/src/command/defaults/EffectCommand.php @@ -28,7 +28,6 @@ use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\VanillaEffects; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\Limits; use pocketmine\utils\TextFormat; @@ -40,8 +39,8 @@ class EffectCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_EFFECT_DESCRIPTION, - KnownTranslationKeys::COMMANDS_EFFECT_USAGE + KnownTranslationFactory::pocketmine_command_effect_description(), + KnownTranslationFactory::commands_effect_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_EFFECT); } diff --git a/src/command/defaults/EnchantCommand.php b/src/command/defaults/EnchantCommand.php index 10d2c3f167..08e959a4fb 100644 --- a/src/command/defaults/EnchantCommand.php +++ b/src/command/defaults/EnchantCommand.php @@ -28,7 +28,6 @@ use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\enchantment\EnchantmentInstance; use pocketmine\item\enchantment\VanillaEnchantments; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\TextFormat; use function count; @@ -38,8 +37,8 @@ class EnchantCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_ENCHANT_DESCRIPTION, - KnownTranslationKeys::COMMANDS_ENCHANT_USAGE + KnownTranslationFactory::pocketmine_command_enchant_description(), + KnownTranslationFactory::commands_enchant_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_ENCHANT); } diff --git a/src/command/defaults/GamemodeCommand.php b/src/command/defaults/GamemodeCommand.php index 90c6627aeb..e011508756 100644 --- a/src/command/defaults/GamemodeCommand.php +++ b/src/command/defaults/GamemodeCommand.php @@ -27,7 +27,6 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\GameMode; use pocketmine\player\Player; @@ -39,8 +38,8 @@ class GamemodeCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_GAMEMODE_DESCRIPTION, - KnownTranslationKeys::COMMANDS_GAMEMODE_USAGE + KnownTranslationFactory::pocketmine_command_gamemode_description(), + KnownTranslationFactory::commands_gamemode_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_GAMEMODE); } diff --git a/src/command/defaults/GarbageCollectorCommand.php b/src/command/defaults/GarbageCollectorCommand.php index 1614739cd1..2a2ccf49cd 100644 --- a/src/command/defaults/GarbageCollectorCommand.php +++ b/src/command/defaults/GarbageCollectorCommand.php @@ -25,7 +25,6 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\TextFormat; use function count; @@ -38,8 +37,8 @@ class GarbageCollectorCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_GC_DESCRIPTION, - KnownTranslationKeys::POCKETMINE_COMMAND_GC_USAGE + KnownTranslationFactory::pocketmine_command_gc_description(), + KnownTranslationFactory::pocketmine_command_gc_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_GC); } diff --git a/src/command/defaults/GiveCommand.php b/src/command/defaults/GiveCommand.php index 7a5de25707..34814f207c 100644 --- a/src/command/defaults/GiveCommand.php +++ b/src/command/defaults/GiveCommand.php @@ -30,7 +30,6 @@ use pocketmine\item\LegacyStringToItemParser; use pocketmine\item\LegacyStringToItemParserException; use pocketmine\item\StringToItemParser; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\nbt\JsonNbtParser; use pocketmine\nbt\NbtDataException; use pocketmine\permission\DefaultPermissionNames; @@ -44,8 +43,8 @@ class GiveCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_GIVE_DESCRIPTION, - KnownTranslationKeys::POCKETMINE_COMMAND_GIVE_USAGE + KnownTranslationFactory::pocketmine_command_give_description(), + KnownTranslationFactory::pocketmine_command_give_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_GIVE); } diff --git a/src/command/defaults/HelpCommand.php b/src/command/defaults/HelpCommand.php index be1beab252..77bc98d0e7 100644 --- a/src/command/defaults/HelpCommand.php +++ b/src/command/defaults/HelpCommand.php @@ -26,7 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; +use pocketmine\lang\Translatable; use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\TextFormat; use function array_chunk; @@ -46,8 +46,8 @@ class HelpCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_HELP_DESCRIPTION, - KnownTranslationKeys::COMMANDS_HELP_USAGE, + KnownTranslationFactory::pocketmine_command_help_description(), + KnownTranslationFactory::commands_help_usage(), ["?"] ); $this->setPermission(DefaultPermissionNames::COMMAND_HELP); @@ -92,7 +92,9 @@ class HelpCommand extends VanillaCommand{ $lang = $sender->getLanguage(); if(isset($commands[$pageNumber - 1])){ foreach($commands[$pageNumber - 1] as $command){ - $sender->sendMessage(TextFormat::DARK_GREEN . "/" . $command->getName() . ": " . TextFormat::WHITE . $lang->translateString($command->getDescription())); + $description = $command->getDescription(); + $descriptionString = $description instanceof Translatable ? $lang->translate($description) : $description; + $sender->sendMessage(TextFormat::DARK_GREEN . "/" . $command->getName() . ": " . TextFormat::WHITE . $descriptionString); } } @@ -100,9 +102,14 @@ class HelpCommand extends VanillaCommand{ }else{ if(($cmd = $sender->getServer()->getCommandMap()->getCommand(strtolower($commandName))) instanceof Command){ if($cmd->testPermissionSilent($sender)){ + $lang = $sender->getLanguage(); + $description = $cmd->getDescription(); + $descriptionString = $description instanceof Translatable ? $lang->translate($description) : $description; $message = TextFormat::YELLOW . "--------- " . TextFormat::WHITE . " Help: /" . $cmd->getName() . TextFormat::YELLOW . " ---------\n"; - $message .= TextFormat::GOLD . "Description: " . TextFormat::WHITE . $sender->getLanguage()->translateString($cmd->getDescription()) . "\n"; - $message .= TextFormat::GOLD . "Usage: " . TextFormat::WHITE . implode("\n" . TextFormat::WHITE, explode("\n", $sender->getLanguage()->translateString($cmd->getUsage()))) . "\n"; + $message .= TextFormat::GOLD . "Description: " . TextFormat::WHITE . $descriptionString . "\n"; + $usage = $cmd->getUsage(); + $usageString = $usage instanceof Translatable ? $lang->translate($usage) : $usage; + $message .= TextFormat::GOLD . "Usage: " . TextFormat::WHITE . implode("\n" . TextFormat::WHITE, explode("\n", $usageString)) . "\n"; $sender->sendMessage($message); return true; diff --git a/src/command/defaults/KickCommand.php b/src/command/defaults/KickCommand.php index 50a37f6a80..a341ca64b0 100644 --- a/src/command/defaults/KickCommand.php +++ b/src/command/defaults/KickCommand.php @@ -27,7 +27,6 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; @@ -41,8 +40,8 @@ class KickCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_KICK_DESCRIPTION, - KnownTranslationKeys::COMMANDS_KICK_USAGE + KnownTranslationFactory::pocketmine_command_kick_description(), + KnownTranslationFactory::commands_kick_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_KICK); } diff --git a/src/command/defaults/KillCommand.php b/src/command/defaults/KillCommand.php index ff96a387f0..f425060e3c 100644 --- a/src/command/defaults/KillCommand.php +++ b/src/command/defaults/KillCommand.php @@ -28,7 +28,6 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; @@ -40,8 +39,8 @@ class KillCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_KILL_DESCRIPTION, - KnownTranslationKeys::POCKETMINE_COMMAND_KILL_USAGE, + KnownTranslationFactory::pocketmine_command_kill_description(), + KnownTranslationFactory::pocketmine_command_kill_usage(), ["suicide"] ); $this->setPermission(implode(";", [DefaultPermissionNames::COMMAND_KILL_SELF, DefaultPermissionNames::COMMAND_KILL_OTHER])); diff --git a/src/command/defaults/ListCommand.php b/src/command/defaults/ListCommand.php index 556ff24f88..5de2e6697a 100644 --- a/src/command/defaults/ListCommand.php +++ b/src/command/defaults/ListCommand.php @@ -25,7 +25,6 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use function array_filter; @@ -40,8 +39,8 @@ class ListCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_LIST_DESCRIPTION, - KnownTranslationKeys::COMMANDS_PLAYERS_USAGE + KnownTranslationFactory::pocketmine_command_list_description(), + KnownTranslationFactory::commands_players_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_LIST); } diff --git a/src/command/defaults/MeCommand.php b/src/command/defaults/MeCommand.php index d1d8329491..904b39fe40 100644 --- a/src/command/defaults/MeCommand.php +++ b/src/command/defaults/MeCommand.php @@ -26,7 +26,6 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; @@ -38,8 +37,8 @@ class MeCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_ME_DESCRIPTION, - KnownTranslationKeys::COMMANDS_ME_USAGE + KnownTranslationFactory::pocketmine_command_me_description(), + KnownTranslationFactory::commands_me_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_ME); } diff --git a/src/command/defaults/OpCommand.php b/src/command/defaults/OpCommand.php index 88348c7acd..4067eb3e74 100644 --- a/src/command/defaults/OpCommand.php +++ b/src/command/defaults/OpCommand.php @@ -27,7 +27,6 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; @@ -39,8 +38,8 @@ class OpCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_OP_DESCRIPTION, - KnownTranslationKeys::COMMANDS_OP_USAGE + KnownTranslationFactory::pocketmine_command_op_description(), + KnownTranslationFactory::commands_op_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_OP_GIVE); } diff --git a/src/command/defaults/PardonCommand.php b/src/command/defaults/PardonCommand.php index 27b40069f0..842cbe3aec 100644 --- a/src/command/defaults/PardonCommand.php +++ b/src/command/defaults/PardonCommand.php @@ -27,7 +27,6 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use function count; @@ -36,8 +35,8 @@ class PardonCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_UNBAN_PLAYER_DESCRIPTION, - KnownTranslationKeys::COMMANDS_UNBAN_USAGE, + KnownTranslationFactory::pocketmine_command_unban_player_description(), + KnownTranslationFactory::commands_unban_usage(), ["unban"] ); $this->setPermission(DefaultPermissionNames::COMMAND_UNBAN_PLAYER); diff --git a/src/command/defaults/PardonIpCommand.php b/src/command/defaults/PardonIpCommand.php index 9b2278706b..395ba1d931 100644 --- a/src/command/defaults/PardonIpCommand.php +++ b/src/command/defaults/PardonIpCommand.php @@ -27,7 +27,6 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use function count; use function preg_match; @@ -37,8 +36,8 @@ class PardonIpCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_UNBAN_IP_DESCRIPTION, - KnownTranslationKeys::COMMANDS_UNBANIP_USAGE, + KnownTranslationFactory::pocketmine_command_unban_ip_description(), + KnownTranslationFactory::commands_unbanip_usage(), ["unban-ip"] ); $this->setPermission(DefaultPermissionNames::COMMAND_UNBAN_IP); diff --git a/src/command/defaults/ParticleCommand.php b/src/command/defaults/ParticleCommand.php index 00e052bb7f..ee7af129a0 100644 --- a/src/command/defaults/ParticleCommand.php +++ b/src/command/defaults/ParticleCommand.php @@ -30,7 +30,6 @@ use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\ItemFactory; use pocketmine\item\VanillaItems; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\math\Vector3; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -79,8 +78,8 @@ class ParticleCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_PARTICLE_DESCRIPTION, - KnownTranslationKeys::POCKETMINE_COMMAND_PARTICLE_USAGE + KnownTranslationFactory::pocketmine_command_particle_description(), + KnownTranslationFactory::pocketmine_command_particle_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_PARTICLE); } diff --git a/src/command/defaults/PluginsCommand.php b/src/command/defaults/PluginsCommand.php index c0339f52d3..3ae8d19a21 100644 --- a/src/command/defaults/PluginsCommand.php +++ b/src/command/defaults/PluginsCommand.php @@ -25,7 +25,6 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\plugin\Plugin; use pocketmine\utils\TextFormat; @@ -40,8 +39,8 @@ class PluginsCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_DESCRIPTION, - KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_USAGE, + KnownTranslationFactory::pocketmine_command_plugins_description(), + KnownTranslationFactory::pocketmine_command_plugins_usage(), ["pl"] ); $this->setPermission(DefaultPermissionNames::COMMAND_PLUGINS); diff --git a/src/command/defaults/SaveCommand.php b/src/command/defaults/SaveCommand.php index 71a3c33f87..9fe3cf197a 100644 --- a/src/command/defaults/SaveCommand.php +++ b/src/command/defaults/SaveCommand.php @@ -26,7 +26,6 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use function microtime; use function round; @@ -36,8 +35,8 @@ class SaveCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_SAVE_DESCRIPTION, - KnownTranslationKeys::COMMANDS_SAVE_USAGE + KnownTranslationFactory::pocketmine_command_save_description(), + KnownTranslationFactory::commands_save_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_SAVE_PERFORM); } diff --git a/src/command/defaults/SaveOffCommand.php b/src/command/defaults/SaveOffCommand.php index 6d8f8a7e9b..5dd39f6f3c 100644 --- a/src/command/defaults/SaveOffCommand.php +++ b/src/command/defaults/SaveOffCommand.php @@ -26,7 +26,6 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; class SaveOffCommand extends VanillaCommand{ @@ -34,8 +33,8 @@ class SaveOffCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_SAVEOFF_DESCRIPTION, - KnownTranslationKeys::COMMANDS_SAVE_OFF_USAGE + KnownTranslationFactory::pocketmine_command_saveoff_description(), + KnownTranslationFactory::commands_save_off_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_SAVE_DISABLE); } diff --git a/src/command/defaults/SaveOnCommand.php b/src/command/defaults/SaveOnCommand.php index f57fa55936..1bbdd5a0be 100644 --- a/src/command/defaults/SaveOnCommand.php +++ b/src/command/defaults/SaveOnCommand.php @@ -26,7 +26,6 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; class SaveOnCommand extends VanillaCommand{ @@ -34,8 +33,8 @@ class SaveOnCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_SAVEON_DESCRIPTION, - KnownTranslationKeys::COMMANDS_SAVE_ON_USAGE + KnownTranslationFactory::pocketmine_command_saveon_description(), + KnownTranslationFactory::commands_save_on_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_SAVE_ENABLE); } diff --git a/src/command/defaults/SayCommand.php b/src/command/defaults/SayCommand.php index a4fd0e0669..29513280eb 100644 --- a/src/command/defaults/SayCommand.php +++ b/src/command/defaults/SayCommand.php @@ -27,7 +27,6 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\console\ConsoleCommandSender; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; @@ -39,8 +38,8 @@ class SayCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_SAY_DESCRIPTION, - KnownTranslationKeys::COMMANDS_SAY_USAGE + KnownTranslationFactory::pocketmine_command_say_description(), + KnownTranslationFactory::commands_say_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_SAY); } diff --git a/src/command/defaults/SeedCommand.php b/src/command/defaults/SeedCommand.php index 53f19a19a3..364c9d0033 100644 --- a/src/command/defaults/SeedCommand.php +++ b/src/command/defaults/SeedCommand.php @@ -25,7 +25,6 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -34,8 +33,8 @@ class SeedCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_SEED_DESCRIPTION, - KnownTranslationKeys::COMMANDS_SEED_USAGE + KnownTranslationFactory::pocketmine_command_seed_description(), + KnownTranslationFactory::commands_seed_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_SEED); } diff --git a/src/command/defaults/SetWorldSpawnCommand.php b/src/command/defaults/SetWorldSpawnCommand.php index 9b67fa0765..9bd37db988 100644 --- a/src/command/defaults/SetWorldSpawnCommand.php +++ b/src/command/defaults/SetWorldSpawnCommand.php @@ -27,7 +27,6 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\math\Vector3; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; @@ -40,8 +39,8 @@ class SetWorldSpawnCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_SETWORLDSPAWN_DESCRIPTION, - KnownTranslationKeys::COMMANDS_SETWORLDSPAWN_USAGE + KnownTranslationFactory::pocketmine_command_setworldspawn_description(), + KnownTranslationFactory::commands_setworldspawn_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_SETWORLDSPAWN); } diff --git a/src/command/defaults/SpawnpointCommand.php b/src/command/defaults/SpawnpointCommand.php index 6bfea948a0..a99d4a49ef 100644 --- a/src/command/defaults/SpawnpointCommand.php +++ b/src/command/defaults/SpawnpointCommand.php @@ -27,7 +27,6 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; @@ -41,8 +40,8 @@ class SpawnpointCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_SPAWNPOINT_DESCRIPTION, - KnownTranslationKeys::COMMANDS_SPAWNPOINT_USAGE + KnownTranslationFactory::pocketmine_command_spawnpoint_description(), + KnownTranslationFactory::commands_spawnpoint_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_SPAWNPOINT); } diff --git a/src/command/defaults/StatusCommand.php b/src/command/defaults/StatusCommand.php index 7a4a98558d..7ccbbb3137 100644 --- a/src/command/defaults/StatusCommand.php +++ b/src/command/defaults/StatusCommand.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; -use pocketmine\lang\KnownTranslationKeys; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\Process; use pocketmine\utils\TextFormat; @@ -39,8 +39,8 @@ class StatusCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_STATUS_DESCRIPTION, - KnownTranslationKeys::POCKETMINE_COMMAND_STATUS_USAGE + KnownTranslationFactory::pocketmine_command_status_description(), + KnownTranslationFactory::pocketmine_command_status_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_STATUS); } diff --git a/src/command/defaults/StopCommand.php b/src/command/defaults/StopCommand.php index 23a624dd5a..3292cd7c65 100644 --- a/src/command/defaults/StopCommand.php +++ b/src/command/defaults/StopCommand.php @@ -26,7 +26,6 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; class StopCommand extends VanillaCommand{ @@ -34,8 +33,8 @@ class StopCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_STOP_DESCRIPTION, - KnownTranslationKeys::COMMANDS_STOP_USAGE + KnownTranslationFactory::pocketmine_command_stop_description(), + KnownTranslationFactory::commands_stop_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_STOP); } diff --git a/src/command/defaults/TeleportCommand.php b/src/command/defaults/TeleportCommand.php index 17979fec61..1ece20f308 100644 --- a/src/command/defaults/TeleportCommand.php +++ b/src/command/defaults/TeleportCommand.php @@ -28,7 +28,6 @@ use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\entity\Location; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\AssumptionFailedError; @@ -42,8 +41,8 @@ class TeleportCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_TP_DESCRIPTION, - KnownTranslationKeys::COMMANDS_TP_USAGE, + KnownTranslationFactory::pocketmine_command_tp_description(), + KnownTranslationFactory::commands_tp_usage(), ["teleport"] ); $this->setPermission(DefaultPermissionNames::COMMAND_TELEPORT); diff --git a/src/command/defaults/TellCommand.php b/src/command/defaults/TellCommand.php index c7feb644ca..4e294af5bf 100644 --- a/src/command/defaults/TellCommand.php +++ b/src/command/defaults/TellCommand.php @@ -27,7 +27,6 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; @@ -40,8 +39,8 @@ class TellCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_TELL_DESCRIPTION, - KnownTranslationKeys::COMMANDS_MESSAGE_USAGE, + KnownTranslationFactory::pocketmine_command_tell_description(), + KnownTranslationFactory::commands_message_usage(), ["w", "msg"] ); $this->setPermission(DefaultPermissionNames::COMMAND_TELL); diff --git a/src/command/defaults/TimeCommand.php b/src/command/defaults/TimeCommand.php index b3b1f397df..fcdd89dee4 100644 --- a/src/command/defaults/TimeCommand.php +++ b/src/command/defaults/TimeCommand.php @@ -27,7 +27,6 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\world\World; @@ -39,8 +38,8 @@ class TimeCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_TIME_DESCRIPTION, - KnownTranslationKeys::POCKETMINE_COMMAND_TIME_USAGE + KnownTranslationFactory::pocketmine_command_time_description(), + KnownTranslationFactory::pocketmine_command_time_usage() ); $this->setPermission(implode(";", [ DefaultPermissionNames::COMMAND_TIME_ADD, diff --git a/src/command/defaults/TimingsCommand.php b/src/command/defaults/TimingsCommand.php index cff3f4dd0b..26839b3123 100644 --- a/src/command/defaults/TimingsCommand.php +++ b/src/command/defaults/TimingsCommand.php @@ -27,7 +27,6 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\scheduler\BulkCurlTask; @@ -60,8 +59,8 @@ class TimingsCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_DESCRIPTION, - KnownTranslationKeys::POCKETMINE_COMMAND_TIMINGS_USAGE + KnownTranslationFactory::pocketmine_command_timings_description(), + KnownTranslationFactory::pocketmine_command_timings_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_TIMINGS); } diff --git a/src/command/defaults/TitleCommand.php b/src/command/defaults/TitleCommand.php index 084949cd37..76e6f3b6e2 100644 --- a/src/command/defaults/TitleCommand.php +++ b/src/command/defaults/TitleCommand.php @@ -26,7 +26,6 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\TextFormat; use function array_slice; @@ -38,8 +37,8 @@ class TitleCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_TITLE_DESCRIPTION, - KnownTranslationKeys::COMMANDS_TITLE_USAGE + KnownTranslationFactory::pocketmine_command_title_description(), + KnownTranslationFactory::commands_title_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_TITLE); } diff --git a/src/command/defaults/TransferServerCommand.php b/src/command/defaults/TransferServerCommand.php index 0190e48ee2..4159a5b256 100644 --- a/src/command/defaults/TransferServerCommand.php +++ b/src/command/defaults/TransferServerCommand.php @@ -25,7 +25,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; -use pocketmine\lang\KnownTranslationKeys; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use function count; @@ -35,8 +35,8 @@ class TransferServerCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_TRANSFERSERVER_DESCRIPTION, - KnownTranslationKeys::POCKETMINE_COMMAND_TRANSFERSERVER_USAGE + KnownTranslationFactory::pocketmine_command_transferserver_description(), + KnownTranslationFactory::pocketmine_command_transferserver_usage() ); $this->setPermission(DefaultPermissionNames::COMMAND_TRANSFERSERVER); } diff --git a/src/command/defaults/VersionCommand.php b/src/command/defaults/VersionCommand.php index 17e4c858ca..c5a09b98f4 100644 --- a/src/command/defaults/VersionCommand.php +++ b/src/command/defaults/VersionCommand.php @@ -25,7 +25,6 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\permission\DefaultPermissionNames; use pocketmine\plugin\Plugin; @@ -46,8 +45,8 @@ class VersionCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_DESCRIPTION, - KnownTranslationKeys::POCKETMINE_COMMAND_VERSION_USAGE, + KnownTranslationFactory::pocketmine_command_version_description(), + KnownTranslationFactory::pocketmine_command_version_usage(), ["ver", "about"] ); $this->setPermission(DefaultPermissionNames::COMMAND_VERSION); diff --git a/src/command/defaults/WhitelistCommand.php b/src/command/defaults/WhitelistCommand.php index 458d819e00..2fdf5a1fa0 100644 --- a/src/command/defaults/WhitelistCommand.php +++ b/src/command/defaults/WhitelistCommand.php @@ -27,7 +27,6 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\KnownTranslationKeys; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use function count; @@ -41,8 +40,8 @@ class WhitelistCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationKeys::POCKETMINE_COMMAND_WHITELIST_DESCRIPTION, - KnownTranslationKeys::COMMANDS_WHITELIST_USAGE + KnownTranslationFactory::pocketmine_command_whitelist_description(), + KnownTranslationFactory::commands_whitelist_usage() ); $this->setPermission(implode(";", [ DefaultPermissionNames::COMMAND_WHITELIST_RELOAD, diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 4683c2c728..45d6daaa66 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -35,6 +35,7 @@ use pocketmine\event\server\DataPacketSendEvent; use pocketmine\form\Form; use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\KnownTranslationKeys; +use pocketmine\lang\Translatable; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\StringTag; @@ -832,9 +833,10 @@ class NetworkSession{ $aliasObj = new CommandEnum(ucfirst($command->getName()) . "Aliases", array_values($aliases)); } + $description = $command->getDescription(); $data = new CommandData( $lname, //TODO: commands containing uppercase letters in the name crash 1.9.0 client - $this->player->getLanguage()->translateString($command->getDescription()), + $description instanceof Translatable ? $this->player->getLanguage()->translate($description) : $description, 0, 0, $aliasObj, diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index 9d12ae3ada..e01b6b7491 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -81,7 +81,7 @@ parameters: path: ../../../src/permission/PermissionParser.php - - message: "#^Parameter \\#1 \\$description of method pocketmine\\\\command\\\\Command\\:\\:setDescription\\(\\) expects string, mixed given\\.$#" + message: "#^Parameter \\#1 \\$description of method pocketmine\\\\command\\\\Command\\:\\:setDescription\\(\\) expects pocketmine\\\\lang\\\\Translatable\\|string, mixed given\\.$#" count: 1 path: ../../../src/plugin/PluginBase.php @@ -91,7 +91,7 @@ parameters: path: ../../../src/plugin/PluginBase.php - - message: "#^Parameter \\#1 \\$usage of method pocketmine\\\\command\\\\Command\\:\\:setUsage\\(\\) expects string, mixed given\\.$#" + message: "#^Parameter \\#1 \\$usage of method pocketmine\\\\command\\\\Command\\:\\:setUsage\\(\\) expects pocketmine\\\\lang\\\\Translatable\\|string, mixed given\\.$#" count: 1 path: ../../../src/plugin/PluginBase.php From 273aa8ab4258dd86b4abba7edf64da91ce8adbf6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 11 Sep 2021 17:06:26 +0100 Subject: [PATCH 2841/3224] Drop useless usage translation strings for commands with no parameters --- resources/locale | 2 +- .../defaults/GarbageCollectorCommand.php | 3 +- src/command/defaults/ListCommand.php | 3 +- src/command/defaults/PluginsCommand.php | 2 +- src/command/defaults/SaveCommand.php | 3 +- src/command/defaults/SaveOffCommand.php | 3 +- src/command/defaults/SaveOnCommand.php | 3 +- src/command/defaults/SeedCommand.php | 3 +- src/command/defaults/StatusCommand.php | 3 +- src/command/defaults/StopCommand.php | 3 +- src/lang/KnownTranslationFactory.php | 36 ------------------- src/lang/KnownTranslationKeys.php | 9 ----- 12 files changed, 10 insertions(+), 63 deletions(-) diff --git a/resources/locale b/resources/locale index 95b9c82f25..4a322da43e 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 95b9c82f25f2d216683769c326c06c88706ce3cc +Subproject commit 4a322da43eb9beef727bd36be3d6b641b8316591 diff --git a/src/command/defaults/GarbageCollectorCommand.php b/src/command/defaults/GarbageCollectorCommand.php index 2a2ccf49cd..1081ac52e9 100644 --- a/src/command/defaults/GarbageCollectorCommand.php +++ b/src/command/defaults/GarbageCollectorCommand.php @@ -37,8 +37,7 @@ class GarbageCollectorCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationFactory::pocketmine_command_gc_description(), - KnownTranslationFactory::pocketmine_command_gc_usage() + KnownTranslationFactory::pocketmine_command_gc_description() ); $this->setPermission(DefaultPermissionNames::COMMAND_GC); } diff --git a/src/command/defaults/ListCommand.php b/src/command/defaults/ListCommand.php index 5de2e6697a..a19130e3f0 100644 --- a/src/command/defaults/ListCommand.php +++ b/src/command/defaults/ListCommand.php @@ -39,8 +39,7 @@ class ListCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationFactory::pocketmine_command_list_description(), - KnownTranslationFactory::commands_players_usage() + KnownTranslationFactory::pocketmine_command_list_description() ); $this->setPermission(DefaultPermissionNames::COMMAND_LIST); } diff --git a/src/command/defaults/PluginsCommand.php b/src/command/defaults/PluginsCommand.php index 3ae8d19a21..2b4ef9ad63 100644 --- a/src/command/defaults/PluginsCommand.php +++ b/src/command/defaults/PluginsCommand.php @@ -40,7 +40,7 @@ class PluginsCommand extends VanillaCommand{ parent::__construct( $name, KnownTranslationFactory::pocketmine_command_plugins_description(), - KnownTranslationFactory::pocketmine_command_plugins_usage(), + null, ["pl"] ); $this->setPermission(DefaultPermissionNames::COMMAND_PLUGINS); diff --git a/src/command/defaults/SaveCommand.php b/src/command/defaults/SaveCommand.php index 9fe3cf197a..ae31cb18a5 100644 --- a/src/command/defaults/SaveCommand.php +++ b/src/command/defaults/SaveCommand.php @@ -35,8 +35,7 @@ class SaveCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationFactory::pocketmine_command_save_description(), - KnownTranslationFactory::commands_save_usage() + KnownTranslationFactory::pocketmine_command_save_description() ); $this->setPermission(DefaultPermissionNames::COMMAND_SAVE_PERFORM); } diff --git a/src/command/defaults/SaveOffCommand.php b/src/command/defaults/SaveOffCommand.php index 5dd39f6f3c..223d81e64c 100644 --- a/src/command/defaults/SaveOffCommand.php +++ b/src/command/defaults/SaveOffCommand.php @@ -33,8 +33,7 @@ class SaveOffCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationFactory::pocketmine_command_saveoff_description(), - KnownTranslationFactory::commands_save_off_usage() + KnownTranslationFactory::pocketmine_command_saveoff_description() ); $this->setPermission(DefaultPermissionNames::COMMAND_SAVE_DISABLE); } diff --git a/src/command/defaults/SaveOnCommand.php b/src/command/defaults/SaveOnCommand.php index 1bbdd5a0be..0999181a98 100644 --- a/src/command/defaults/SaveOnCommand.php +++ b/src/command/defaults/SaveOnCommand.php @@ -33,8 +33,7 @@ class SaveOnCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationFactory::pocketmine_command_saveon_description(), - KnownTranslationFactory::commands_save_on_usage() + KnownTranslationFactory::pocketmine_command_saveon_description() ); $this->setPermission(DefaultPermissionNames::COMMAND_SAVE_ENABLE); } diff --git a/src/command/defaults/SeedCommand.php b/src/command/defaults/SeedCommand.php index 364c9d0033..50e1061457 100644 --- a/src/command/defaults/SeedCommand.php +++ b/src/command/defaults/SeedCommand.php @@ -33,8 +33,7 @@ class SeedCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationFactory::pocketmine_command_seed_description(), - KnownTranslationFactory::commands_seed_usage() + KnownTranslationFactory::pocketmine_command_seed_description() ); $this->setPermission(DefaultPermissionNames::COMMAND_SEED); } diff --git a/src/command/defaults/StatusCommand.php b/src/command/defaults/StatusCommand.php index 7ccbbb3137..05dfc7abf3 100644 --- a/src/command/defaults/StatusCommand.php +++ b/src/command/defaults/StatusCommand.php @@ -39,8 +39,7 @@ class StatusCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationFactory::pocketmine_command_status_description(), - KnownTranslationFactory::pocketmine_command_status_usage() + KnownTranslationFactory::pocketmine_command_status_description() ); $this->setPermission(DefaultPermissionNames::COMMAND_STATUS); } diff --git a/src/command/defaults/StopCommand.php b/src/command/defaults/StopCommand.php index 3292cd7c65..2562087141 100644 --- a/src/command/defaults/StopCommand.php +++ b/src/command/defaults/StopCommand.php @@ -33,8 +33,7 @@ class StopCommand extends VanillaCommand{ public function __construct(string $name){ parent::__construct( $name, - KnownTranslationFactory::pocketmine_command_stop_description(), - KnownTranslationFactory::commands_stop_usage() + KnownTranslationFactory::pocketmine_command_stop_description() ); $this->setPermission(DefaultPermissionNames::COMMAND_STOP); } diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index 96eac592cc..62577ee162 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -405,18 +405,6 @@ final class KnownTranslationFactory{ ]); } - public static function commands_players_usage() : Translatable{ - return new Translatable(KnownTranslationKeys::COMMANDS_PLAYERS_USAGE, []); - } - - public static function commands_save_off_usage() : Translatable{ - return new Translatable(KnownTranslationKeys::COMMANDS_SAVE_OFF_USAGE, []); - } - - public static function commands_save_on_usage() : Translatable{ - return new Translatable(KnownTranslationKeys::COMMANDS_SAVE_ON_USAGE, []); - } - public static function commands_save_disabled() : Translatable{ return new Translatable(KnownTranslationKeys::COMMANDS_SAVE_DISABLED, []); } @@ -433,10 +421,6 @@ final class KnownTranslationFactory{ return new Translatable(KnownTranslationKeys::COMMANDS_SAVE_SUCCESS, []); } - public static function commands_save_usage() : Translatable{ - return new Translatable(KnownTranslationKeys::COMMANDS_SAVE_USAGE, []); - } - public static function commands_say_usage() : Translatable{ return new Translatable(KnownTranslationKeys::COMMANDS_SAY_USAGE, []); } @@ -447,10 +431,6 @@ final class KnownTranslationFactory{ ]); } - public static function commands_seed_usage() : Translatable{ - return new Translatable(KnownTranslationKeys::COMMANDS_SEED_USAGE, []); - } - public static function commands_setworldspawn_success(Translatable|string $param0, Translatable|string $param1, Translatable|string $param2) : Translatable{ return new Translatable(KnownTranslationKeys::COMMANDS_SETWORLDSPAWN_SUCCESS, [ 0 => $param0, @@ -480,10 +460,6 @@ final class KnownTranslationFactory{ return new Translatable(KnownTranslationKeys::COMMANDS_STOP_START, []); } - public static function commands_stop_usage() : Translatable{ - return new Translatable(KnownTranslationKeys::COMMANDS_STOP_USAGE, []); - } - public static function commands_time_added(Translatable|string $param0) : Translatable{ return new Translatable(KnownTranslationKeys::COMMANDS_TIME_ADDED, [ 0 => $param0, @@ -1171,10 +1147,6 @@ final class KnownTranslationFactory{ ]); } - public static function pocketmine_command_gc_usage() : Translatable{ - return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_GC_USAGE, []); - } - public static function pocketmine_command_give_description() : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_GIVE_DESCRIPTION, []); } @@ -1230,10 +1202,6 @@ final class KnownTranslationFactory{ ]); } - public static function pocketmine_command_plugins_usage() : Translatable{ - return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_PLUGINS_USAGE, []); - } - public static function pocketmine_command_save_description() : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_SAVE_DESCRIPTION, []); } @@ -1266,10 +1234,6 @@ final class KnownTranslationFactory{ return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_STATUS_DESCRIPTION, []); } - public static function pocketmine_command_status_usage() : Translatable{ - return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_STATUS_USAGE, []); - } - public static function pocketmine_command_stop_description() : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_STOP_DESCRIPTION, []); } diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index 3e9b90eb2a..5c3d5bfa36 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -95,23 +95,17 @@ final class KnownTranslationKeys{ public const COMMANDS_PARTICLE_NOTFOUND = "commands.particle.notFound"; public const COMMANDS_PARTICLE_SUCCESS = "commands.particle.success"; public const COMMANDS_PLAYERS_LIST = "commands.players.list"; - public const COMMANDS_PLAYERS_USAGE = "commands.players.usage"; - public const COMMANDS_SAVE_OFF_USAGE = "commands.save-off.usage"; - public const COMMANDS_SAVE_ON_USAGE = "commands.save-on.usage"; public const COMMANDS_SAVE_DISABLED = "commands.save.disabled"; public const COMMANDS_SAVE_ENABLED = "commands.save.enabled"; public const COMMANDS_SAVE_START = "commands.save.start"; public const COMMANDS_SAVE_SUCCESS = "commands.save.success"; - public const COMMANDS_SAVE_USAGE = "commands.save.usage"; public const COMMANDS_SAY_USAGE = "commands.say.usage"; public const COMMANDS_SEED_SUCCESS = "commands.seed.success"; - public const COMMANDS_SEED_USAGE = "commands.seed.usage"; public const COMMANDS_SETWORLDSPAWN_SUCCESS = "commands.setworldspawn.success"; public const COMMANDS_SETWORLDSPAWN_USAGE = "commands.setworldspawn.usage"; public const COMMANDS_SPAWNPOINT_SUCCESS = "commands.spawnpoint.success"; public const COMMANDS_SPAWNPOINT_USAGE = "commands.spawnpoint.usage"; public const COMMANDS_STOP_START = "commands.stop.start"; - public const COMMANDS_STOP_USAGE = "commands.stop.usage"; public const COMMANDS_TIME_ADDED = "commands.time.added"; public const COMMANDS_TIME_QUERY = "commands.time.query"; public const COMMANDS_TIME_SET = "commands.time.set"; @@ -257,7 +251,6 @@ final class KnownTranslationKeys{ public const POCKETMINE_COMMAND_GC_ENTITIES = "pocketmine.command.gc.entities"; public const POCKETMINE_COMMAND_GC_HEADER = "pocketmine.command.gc.header"; public const POCKETMINE_COMMAND_GC_MEMORYFREED = "pocketmine.command.gc.memoryFreed"; - public const POCKETMINE_COMMAND_GC_USAGE = "pocketmine.command.gc.usage"; public const POCKETMINE_COMMAND_GIVE_DESCRIPTION = "pocketmine.command.give.description"; public const POCKETMINE_COMMAND_GIVE_USAGE = "pocketmine.command.give.usage"; public const POCKETMINE_COMMAND_HELP_DESCRIPTION = "pocketmine.command.help.description"; @@ -271,7 +264,6 @@ final class KnownTranslationKeys{ public const POCKETMINE_COMMAND_PARTICLE_USAGE = "pocketmine.command.particle.usage"; public const POCKETMINE_COMMAND_PLUGINS_DESCRIPTION = "pocketmine.command.plugins.description"; public const POCKETMINE_COMMAND_PLUGINS_SUCCESS = "pocketmine.command.plugins.success"; - public const POCKETMINE_COMMAND_PLUGINS_USAGE = "pocketmine.command.plugins.usage"; public const POCKETMINE_COMMAND_SAVE_DESCRIPTION = "pocketmine.command.save.description"; public const POCKETMINE_COMMAND_SAVEOFF_DESCRIPTION = "pocketmine.command.saveoff.description"; public const POCKETMINE_COMMAND_SAVEON_DESCRIPTION = "pocketmine.command.saveon.description"; @@ -280,7 +272,6 @@ final class KnownTranslationKeys{ public const POCKETMINE_COMMAND_SETWORLDSPAWN_DESCRIPTION = "pocketmine.command.setworldspawn.description"; public const POCKETMINE_COMMAND_SPAWNPOINT_DESCRIPTION = "pocketmine.command.spawnpoint.description"; public const POCKETMINE_COMMAND_STATUS_DESCRIPTION = "pocketmine.command.status.description"; - public const POCKETMINE_COMMAND_STATUS_USAGE = "pocketmine.command.status.usage"; public const POCKETMINE_COMMAND_STOP_DESCRIPTION = "pocketmine.command.stop.description"; public const POCKETMINE_COMMAND_TELL_DESCRIPTION = "pocketmine.command.tell.description"; public const POCKETMINE_COMMAND_TIME_DESCRIPTION = "pocketmine.command.time.description"; From 33a7c05425c53ec154b55e9b8ecd84fcc2e9a9aa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 11 Sep 2021 23:12:43 +0100 Subject: [PATCH 2842/3224] Updated PHPStan baselines --- tests/phpstan/configs/actual-problems.neon | 25 ------------- .../check-explicit-mixed-baseline.neon | 10 ------ tests/phpstan/configs/l7-baseline.neon | 35 ------------------- tests/phpstan/configs/l8-baseline.neon | 17 +-------- 4 files changed, 1 insertion(+), 86 deletions(-) diff --git a/tests/phpstan/configs/actual-problems.neon b/tests/phpstan/configs/actual-problems.neon index 06987c93c3..312971fa64 100644 --- a/tests/phpstan/configs/actual-problems.neon +++ b/tests/phpstan/configs/actual-problems.neon @@ -5,31 +5,6 @@ parameters: count: 1 path: ../../../src/CrashDump.php - - - message: "#^Instanceof between pocketmine\\\\console\\\\ConsoleReaderThread and pocketmine\\\\console\\\\ConsoleReaderThread will always evaluate to true\\.$#" - count: 1 - path: ../../../src/Server.php - - - - message: "#^Instanceof between pocketmine\\\\network\\\\Network and pocketmine\\\\network\\\\Network will always evaluate to true\\.$#" - count: 2 - path: ../../../src/Server.php - - - - message: "#^Instanceof between pocketmine\\\\plugin\\\\PluginManager and pocketmine\\\\plugin\\\\PluginManager will always evaluate to true\\.$#" - count: 1 - path: ../../../src/Server.php - - - - message: "#^Instanceof between pocketmine\\\\scheduler\\\\AsyncPool and pocketmine\\\\scheduler\\\\AsyncPool will always evaluate to true\\.$#" - count: 1 - path: ../../../src/Server.php - - - - message: "#^Instanceof between pocketmine\\\\world\\\\WorldManager and pocketmine\\\\world\\\\WorldManager will always evaluate to true\\.$#" - count: 1 - path: ../../../src/Server.php - - message: "#^Property pocketmine\\\\event\\\\entity\\\\EntityShootBowEvent\\:\\:\\$projectile \\(pocketmine\\\\entity\\\\projectile\\\\Projectile\\) does not accept pocketmine\\\\entity\\\\Entity\\.$#" count: 1 diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index e01b6b7491..56654cf262 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -200,16 +200,6 @@ parameters: count: 1 path: ../../../src/utils/MainLogger.php - - - message: "#^Cannot access offset 'status' on mixed\\.$#" - count: 1 - path: ../../../src/utils/Timezone.php - - - - message: "#^Cannot access offset 'timezone' on mixed\\.$#" - count: 2 - path: ../../../src/utils/Timezone.php - - message: "#^Parameter \\#1 \\$path of static method pocketmine\\\\utils\\\\Filesystem\\:\\:cleanPath\\(\\) expects string, mixed given\\.$#" count: 1 diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index 443b0f812a..4f82f4aff4 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -330,36 +330,6 @@ parameters: count: 3 path: ../../../src/block/Mycelium.php - - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/block/Sapling.php - - - - message: "#^Parameter \\#2 \\$x of static method pocketmine\\\\world\\\\generator\\\\object\\\\Tree\\:\\:growTree\\(\\) expects int, float\\|int given\\.$#" - count: 2 - path: ../../../src/block/Sapling.php - - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/block/Sapling.php - - - - message: "#^Parameter \\#3 \\$y of static method pocketmine\\\\world\\\\generator\\\\object\\\\Tree\\:\\:growTree\\(\\) expects int, float\\|int given\\.$#" - count: 2 - path: ../../../src/block/Sapling.php - - - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getFullLightAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/block/Sapling.php - - - - message: "#^Parameter \\#4 \\$z of static method pocketmine\\\\world\\\\generator\\\\object\\\\Tree\\:\\:growTree\\(\\) expects int, float\\|int given\\.$#" - count: 2 - path: ../../../src/block/Sapling.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getBlockLightAt\\(\\) expects int, float\\|int given\\.$#" count: 1 @@ -465,11 +435,6 @@ parameters: count: 1 path: ../../../src/console/ConsoleReader.php - - - message: "#^Method pocketmine\\\\crafting\\\\CraftingManager\\:\\:hashOutputs\\(\\) should return string but returns string\\|false\\.$#" - count: 1 - path: ../../../src/crafting/CraftingManager.php - - message: "#^Parameter \\#1 \\$json of function json_decode expects string, string\\|false given\\.$#" count: 1 diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 33e53ac737..cb21fad4ea 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -5,11 +5,6 @@ parameters: count: 2 path: ../../../build/make-release.php - - - message: "#^Parameter \\#1 \\$constraint of method pocketmine\\\\block\\\\BaseRail\\:\\:getPossibleConnectionDirectionsOneConstraint\\(\\) expects int, int\\|null given\\.$#" - count: 1 - path: ../../../src/block/BaseRail.php - - message: "#^Cannot call method setFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" count: 1 @@ -280,16 +275,6 @@ parameters: count: 1 path: ../../../src/world/format/HeightArray.php - - - message: "#^Cannot call method isDirty\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/world/generator/PopulationTask.php - - - - message: "#^Cannot call method setDirtyFlag\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 4 - path: ../../../src/world/generator/PopulationTask.php - - message: "#^Cannot call method setPopulated\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" count: 1 @@ -297,7 +282,7 @@ parameters: - message: "#^Parameter \\#1 \\$chunk of static method pocketmine\\\\world\\\\format\\\\io\\\\FastChunkSerializer\\:\\:serializeWithoutLight\\(\\) expects pocketmine\\\\world\\\\format\\\\Chunk, pocketmine\\\\world\\\\format\\\\Chunk\\|null given\\.$#" - count: 2 + count: 1 path: ../../../src/world/generator/PopulationTask.php - From f0fa561c2f49d006482aab2bbff9d313664f5ebb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 12 Sep 2021 15:16:55 +0100 Subject: [PATCH 2843/3224] World: use arrow functions in useBreakOn() --- src/world/World.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 50109a1b36..0f989e9ce7 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1687,12 +1687,12 @@ class World implements ChunkManager{ $drops = []; if($player === null or $player->hasFiniteResources()){ - $drops = array_merge(...array_map(function(Block $block) use ($item) : array{ return $block->getDrops($item); }, $affectedBlocks)); + $drops = array_merge(...array_map(fn(Block $block) => $block->getDrops($item), $affectedBlocks)); } $xpDrop = 0; if($player !== null and $player->hasFiniteResources()){ - $xpDrop = array_sum(array_map(function(Block $block) use ($item) : int{ return $block->getXpDropForTool($item); }, $affectedBlocks)); + $xpDrop = array_sum(array_map(fn(Block $block) => $block->getXpDropForTool($item), $affectedBlocks)); } if($player !== null){ From 5ddd94b7e842016b771f5c9ca6ccb9d48e89fbe5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 12 Sep 2021 15:21:09 +0100 Subject: [PATCH 2844/3224] Remove redundant World->isChunkGenerated() calls isChunkGenerated() merely checks if the chunk can be loaded from disk, if it's not in the runtime cache already. This is pointless in all of these cases, because the check is prefaced by an isChunkLoaded() check, which already limits the possibility anyway. If the chunk is not generated, it'll also be considered not loaded. --- src/player/Player.php | 2 +- src/world/World.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index b892c5a9c8..9a45635428 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1126,7 +1126,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->logger->debug("Moved too fast, reverting movement"); $this->logger->debug("Old position: " . $this->location->asVector3() . ", new position: " . $newPos); $revert = true; - }elseif(!$this->getWorld()->isInLoadedTerrain($newPos) or !$this->getWorld()->isChunkGenerated($newPos->getFloorX() >> Chunk::COORD_BIT_SIZE, $newPos->getFloorZ() >> Chunk::COORD_BIT_SIZE)){ + }elseif(!$this->getWorld()->isInLoadedTerrain($newPos)){ $revert = true; $this->nextChunkOrderRun = 0; } diff --git a/src/world/World.php b/src/world/World.php index 0f989e9ce7..05ff4dcd8c 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1674,7 +1674,7 @@ class World implements ChunkManager{ $chunkX = $vector->getFloorX() >> Chunk::COORD_BIT_SIZE; $chunkZ = $vector->getFloorZ() >> Chunk::COORD_BIT_SIZE; - if(!$this->isChunkLoaded($chunkX, $chunkZ) || !$this->isChunkGenerated($chunkX, $chunkZ) || $this->isChunkLocked($chunkX, $chunkZ)){ + if(!$this->isChunkLoaded($chunkX, $chunkZ) || $this->isChunkLocked($chunkX, $chunkZ)){ return false; } @@ -1785,7 +1785,7 @@ class World implements ChunkManager{ } $chunkX = $blockReplace->getPosition()->getFloorX() >> Chunk::COORD_BIT_SIZE; $chunkZ = $blockReplace->getPosition()->getFloorZ() >> Chunk::COORD_BIT_SIZE; - if(!$this->isChunkLoaded($chunkX, $chunkZ) || !$this->isChunkGenerated($chunkX, $chunkZ) || $this->isChunkLocked($chunkX, $chunkZ)){ + if(!$this->isChunkLoaded($chunkX, $chunkZ) || $this->isChunkLocked($chunkX, $chunkZ)){ return false; } From ace8841d5d71835db723e7b917af0a515a414987 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 12 Sep 2021 15:45:02 +0100 Subject: [PATCH 2845/3224] Explosion: allow the normal blockupdate mechanism to deal with explosions in PM4, all blockupdates are buffered, so the old 7x performance penalty that used to be incurred by doing this is no longer a problem. Also, this actually reduces the overhead of explosions themselves by moving the onNearbyBlockChange() burden off explodeB() and into the main world ticking function. --- src/world/Explosion.php | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/src/world/Explosion.php b/src/world/Explosion.php index 722b08e90d..86d9eeb800 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -28,14 +28,12 @@ use pocketmine\block\BlockFactory; use pocketmine\block\TNT; use pocketmine\block\VanillaBlocks; use pocketmine\entity\Entity; -use pocketmine\event\block\BlockUpdateEvent; use pocketmine\event\entity\EntityDamageByBlockEvent; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityExplodeEvent; use pocketmine\item\ItemFactory; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\world\format\SubChunk; use pocketmine\world\particle\HugeExplodeSeedParticle; @@ -227,29 +225,7 @@ class Explosion{ if(($t = $this->world->getTileAt($pos->x, $pos->y, $pos->z)) !== null){ $t->onBlockDestroyed(); //needed to create drops for inventories } - $this->world->setBlockAt($pos->x, $pos->y, $pos->z, $airBlock, false); //TODO: should updating really be disabled here? - $this->world->updateAllLight($pos->x, $pos->y, $pos->z); - } - } - - foreach($this->affectedBlocks as $block){ - $pos = $block->getPosition(); - foreach(Facing::ALL as $side){ - $sideBlock = $pos->getSide($side); - if(!$this->world->isInWorld($sideBlock->x, $sideBlock->y, $sideBlock->z)){ - continue; - } - if(!isset($this->affectedBlocks[$index = World::blockHash($sideBlock->x, $sideBlock->y, $sideBlock->z)]) and !isset($updateBlocks[$index])){ - $ev = new BlockUpdateEvent($this->world->getBlockAt($sideBlock->x, $sideBlock->y, $sideBlock->z)); - $ev->call(); - if(!$ev->isCancelled()){ - foreach($this->world->getNearbyEntities(AxisAlignedBB::one()->offset($sideBlock->x, $sideBlock->y, $sideBlock->z)->expand(1, 1, 1)) as $entity){ - $entity->onNearbyBlockChange(); - } - $ev->getBlock()->onNearbyBlockChange(); - } - $updateBlocks[$index] = true; - } + $this->world->setBlockAt($pos->x, $pos->y, $pos->z, $airBlock); } } From 84170ad3e1c1e9fec1cd71fee2dbb7accfb6e1ee Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 12 Sep 2021 15:49:33 +0100 Subject: [PATCH 2846/3224] Furnace: fixed deactivation after being reloaded from disk (regression from PM3) closes #4430 --- src/block/tile/Furnace.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/block/tile/Furnace.php b/src/block/tile/Furnace.php index 6f2533e868..b527317d6d 100644 --- a/src/block/tile/Furnace.php +++ b/src/block/tile/Furnace.php @@ -82,6 +82,10 @@ abstract class Furnace extends Spawnable implements Container, Nameable{ $this->loadName($nbt); $this->loadItems($nbt); + + if($this->remainingFuelTime > 0){ + $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, 1); + } } protected function writeSaveData(CompoundTag $nbt) : void{ From a1c82da2f242bbc5bf286f189b26009a17fea689 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 12 Sep 2021 16:03:52 +0100 Subject: [PATCH 2847/3224] Liquid: remove useless continue --- src/block/Liquid.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/block/Liquid.php b/src/block/Liquid.php index 999218372f..74f88255b9 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -444,7 +444,6 @@ abstract class Liquid extends Transparent{ if(!$this->canFlowInto($block)){ $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::BLOCKED; - continue; }elseif($this->position->getWorld()->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::CAN_FLOW_DOWN; $flowCost[$j] = $maxCost = 0; From 59f3622f69e10738fc72571d430cc46aff38a377 Mon Sep 17 00:00:00 2001 From: Mini S <60860894+minijaham@users.noreply.github.com> Date: Thu, 16 Sep 2021 01:18:53 +0900 Subject: [PATCH 2848/3224] changelog: mention PluginLoadOrder changes (#4458) [ci skip] --- changelogs/4.0.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index bbf2937da4..59f2151dbe 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -897,6 +897,9 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `PluginManager->registerEvent()` now has a simpler signature: `registerEvent(string $event, \Closure $handler, int $priority, Plugin $plugin, bool $handleCancelled = false)`. The provided closure must accept the specified event class as its only parameter. See [Event API changes](#event) for more details. - The following classes have been removed: - `PluginLogger` +- The following constants have been removed: + - `PluginLoadOrder::STARTUP` - use `PluginEnableOrder::STARTUP()` + - `PluginLoadOrder::POSTWORLD` - use `PluginEnableOrder::POSTWORLD()` - The following interface requirements have been removed: - `Plugin->onEnable()`: this is now internalized inside `PluginBase` - `Plugin->onDisable()`: same as above From 9490b78640c477bc3d1a7ccfd3a7d6f65345edfc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 15 Sep 2021 22:27:33 +0100 Subject: [PATCH 2849/3224] Move packet handler default implementations to BedrockProtocol in many cases this will now require zero changes to PM at all to be compatible with a new protocol version. --- composer.json | 2 +- composer.lock | 14 +- src/network/mcpe/handler/PacketHandler.php | 822 +-------------------- 3 files changed, 10 insertions(+), 828 deletions(-) diff --git a/composer.json b/composer.json index c548e63310..ae2cf4a1d3 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "adhocore/json-comment": "^1.1", "fgrosse/phpasn1": "^2.3", "netresearch/jsonmapper": "^4.0", - "pocketmine/bedrock-protocol": "1.0.0+bedrock1.17.10", + "pocketmine/bedrock-protocol": "1.1.0+bedrock1.17.10", "pocketmine/binaryutils": "^0.2.1", "pocketmine/callback-validator": "^1.0.2", "pocketmine/classloader": "dev-master", diff --git a/composer.lock b/composer.lock index 70eadad960..7fa6959166 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ad6be987e3e2228abcb23e169f139d29", + "content-hash": "b0ec4c919d9322989980754f328c5e36", "packages": [ { "name": "adhocore/json-comment", @@ -245,16 +245,16 @@ }, { "name": "pocketmine/bedrock-protocol", - "version": "1.0.0+bedrock1.17.10", + "version": "1.1.0+bedrock1.17.10", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "2e3bba545dae1774681883fc12a3ee84e553df67" + "reference": "9250ef96eba59c78c6aec91f154c63aebae118c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/2e3bba545dae1774681883fc12a3ee84e553df67", - "reference": "2e3bba545dae1774681883fc12a3ee84e553df67", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/9250ef96eba59c78c6aec91f154c63aebae118c5", + "reference": "9250ef96eba59c78c6aec91f154c63aebae118c5", "shasum": "" }, "require": { @@ -286,9 +286,9 @@ "description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP", "support": { "issues": "https://github.com/pmmp/BedrockProtocol/issues", - "source": "https://github.com/pmmp/BedrockProtocol/tree/1.0.0+bedrock1.17.10" + "source": "https://github.com/pmmp/BedrockProtocol/tree/1.1.0+bedrock1.17.10" }, - "time": "2021-08-23T14:30:22+00:00" + "time": "2021-09-15T21:19:15+00:00" }, { "name": "pocketmine/binaryutils", diff --git a/src/network/mcpe/handler/PacketHandler.php b/src/network/mcpe/handler/PacketHandler.php index 156762467d..501a87df64 100644 --- a/src/network/mcpe/handler/PacketHandler.php +++ b/src/network/mcpe/handler/PacketHandler.php @@ -23,171 +23,8 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; -use pocketmine\network\mcpe\protocol\ActorEventPacket; -use pocketmine\network\mcpe\protocol\ActorPickRequestPacket; -use pocketmine\network\mcpe\protocol\AddActorPacket; -use pocketmine\network\mcpe\protocol\AddBehaviorTreePacket; -use pocketmine\network\mcpe\protocol\AddEntityPacket; -use pocketmine\network\mcpe\protocol\AddItemActorPacket; -use pocketmine\network\mcpe\protocol\AddPaintingPacket; -use pocketmine\network\mcpe\protocol\AddPlayerPacket; -use pocketmine\network\mcpe\protocol\AddVolumeEntityPacket; -use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; -use pocketmine\network\mcpe\protocol\AnimateEntityPacket; -use pocketmine\network\mcpe\protocol\AnimatePacket; -use pocketmine\network\mcpe\protocol\AnvilDamagePacket; -use pocketmine\network\mcpe\protocol\AutomationClientConnectPacket; -use pocketmine\network\mcpe\protocol\AvailableActorIdentifiersPacket; -use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; -use pocketmine\network\mcpe\protocol\BiomeDefinitionListPacket; -use pocketmine\network\mcpe\protocol\BlockActorDataPacket; -use pocketmine\network\mcpe\protocol\BlockEventPacket; -use pocketmine\network\mcpe\protocol\BlockPickRequestPacket; -use pocketmine\network\mcpe\protocol\BookEditPacket; -use pocketmine\network\mcpe\protocol\BossEventPacket; -use pocketmine\network\mcpe\protocol\CameraPacket; -use pocketmine\network\mcpe\protocol\CameraShakePacket; -use pocketmine\network\mcpe\protocol\ChangeDimensionPacket; -use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; -use pocketmine\network\mcpe\protocol\ClientboundDebugRendererPacket; -use pocketmine\network\mcpe\protocol\ClientboundMapItemDataPacket; -use pocketmine\network\mcpe\protocol\ClientCacheBlobStatusPacket; -use pocketmine\network\mcpe\protocol\ClientCacheMissResponsePacket; -use pocketmine\network\mcpe\protocol\ClientCacheStatusPacket; -use pocketmine\network\mcpe\protocol\ClientToServerHandshakePacket; -use pocketmine\network\mcpe\protocol\CodeBuilderPacket; -use pocketmine\network\mcpe\protocol\CommandBlockUpdatePacket; -use pocketmine\network\mcpe\protocol\CommandOutputPacket; -use pocketmine\network\mcpe\protocol\CommandRequestPacket; -use pocketmine\network\mcpe\protocol\CompletedUsingItemPacket; -use pocketmine\network\mcpe\protocol\ContainerClosePacket; -use pocketmine\network\mcpe\protocol\ContainerOpenPacket; -use pocketmine\network\mcpe\protocol\ContainerSetDataPacket; -use pocketmine\network\mcpe\protocol\CorrectPlayerMovePredictionPacket; -use pocketmine\network\mcpe\protocol\CraftingDataPacket; -use pocketmine\network\mcpe\protocol\CraftingEventPacket; -use pocketmine\network\mcpe\protocol\CreativeContentPacket; -use pocketmine\network\mcpe\protocol\DebugInfoPacket; -use pocketmine\network\mcpe\protocol\DisconnectPacket; -use pocketmine\network\mcpe\protocol\EducationSettingsPacket; -use pocketmine\network\mcpe\protocol\EmoteListPacket; -use pocketmine\network\mcpe\protocol\EmotePacket; -use pocketmine\network\mcpe\protocol\EventPacket; -use pocketmine\network\mcpe\protocol\FilterTextPacket; -use pocketmine\network\mcpe\protocol\GameRulesChangedPacket; -use pocketmine\network\mcpe\protocol\GuiDataPickItemPacket; -use pocketmine\network\mcpe\protocol\HurtArmorPacket; -use pocketmine\network\mcpe\protocol\InteractPacket; -use pocketmine\network\mcpe\protocol\InventoryContentPacket; -use pocketmine\network\mcpe\protocol\InventorySlotPacket; -use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; -use pocketmine\network\mcpe\protocol\ItemComponentPacket; -use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket; -use pocketmine\network\mcpe\protocol\ItemStackRequestPacket; -use pocketmine\network\mcpe\protocol\ItemStackResponsePacket; -use pocketmine\network\mcpe\protocol\LabTablePacket; -use pocketmine\network\mcpe\protocol\LecternUpdatePacket; -use pocketmine\network\mcpe\protocol\LevelChunkPacket; -use pocketmine\network\mcpe\protocol\LevelEventGenericPacket; -use pocketmine\network\mcpe\protocol\LevelEventPacket; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacketV1; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacketV2; -use pocketmine\network\mcpe\protocol\LoginPacket; -use pocketmine\network\mcpe\protocol\MapCreateLockedCopyPacket; -use pocketmine\network\mcpe\protocol\MapInfoRequestPacket; -use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket; -use pocketmine\network\mcpe\protocol\MobEffectPacket; -use pocketmine\network\mcpe\protocol\MobEquipmentPacket; -use pocketmine\network\mcpe\protocol\ModalFormRequestPacket; -use pocketmine\network\mcpe\protocol\ModalFormResponsePacket; -use pocketmine\network\mcpe\protocol\MotionPredictionHintsPacket; -use pocketmine\network\mcpe\protocol\MoveActorAbsolutePacket; -use pocketmine\network\mcpe\protocol\MoveActorDeltaPacket; -use pocketmine\network\mcpe\protocol\MovePlayerPacket; -use pocketmine\network\mcpe\protocol\MultiplayerSettingsPacket; -use pocketmine\network\mcpe\protocol\NetworkChunkPublisherUpdatePacket; -use pocketmine\network\mcpe\protocol\NetworkSettingsPacket; -use pocketmine\network\mcpe\protocol\NetworkStackLatencyPacket; -use pocketmine\network\mcpe\protocol\NpcDialoguePacket; -use pocketmine\network\mcpe\protocol\NpcRequestPacket; -use pocketmine\network\mcpe\protocol\OnScreenTextureAnimationPacket; +use pocketmine\network\mcpe\protocol\PacketHandlerDefaultImplTrait; use pocketmine\network\mcpe\protocol\PacketHandlerInterface; -use pocketmine\network\mcpe\protocol\PacketViolationWarningPacket; -use pocketmine\network\mcpe\protocol\PhotoTransferPacket; -use pocketmine\network\mcpe\protocol\PlayerActionPacket; -use pocketmine\network\mcpe\protocol\PlayerArmorDamagePacket; -use pocketmine\network\mcpe\protocol\PlayerAuthInputPacket; -use pocketmine\network\mcpe\protocol\PlayerEnchantOptionsPacket; -use pocketmine\network\mcpe\protocol\PlayerFogPacket; -use pocketmine\network\mcpe\protocol\PlayerHotbarPacket; -use pocketmine\network\mcpe\protocol\PlayerInputPacket; -use pocketmine\network\mcpe\protocol\PlayerListPacket; -use pocketmine\network\mcpe\protocol\PlayerSkinPacket; -use pocketmine\network\mcpe\protocol\PlaySoundPacket; -use pocketmine\network\mcpe\protocol\PlayStatusPacket; -use pocketmine\network\mcpe\protocol\PositionTrackingDBClientRequestPacket; -use pocketmine\network\mcpe\protocol\PositionTrackingDBServerBroadcastPacket; -use pocketmine\network\mcpe\protocol\PurchaseReceiptPacket; -use pocketmine\network\mcpe\protocol\RemoveActorPacket; -use pocketmine\network\mcpe\protocol\RemoveEntityPacket; -use pocketmine\network\mcpe\protocol\RemoveObjectivePacket; -use pocketmine\network\mcpe\protocol\RemoveVolumeEntityPacket; -use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; -use pocketmine\network\mcpe\protocol\ResourcePackChunkDataPacket; -use pocketmine\network\mcpe\protocol\ResourcePackChunkRequestPacket; -use pocketmine\network\mcpe\protocol\ResourcePackClientResponsePacket; -use pocketmine\network\mcpe\protocol\ResourcePackDataInfoPacket; -use pocketmine\network\mcpe\protocol\ResourcePacksInfoPacket; -use pocketmine\network\mcpe\protocol\ResourcePackStackPacket; -use pocketmine\network\mcpe\protocol\RespawnPacket; -use pocketmine\network\mcpe\protocol\RiderJumpPacket; -use pocketmine\network\mcpe\protocol\ScriptCustomEventPacket; -use pocketmine\network\mcpe\protocol\ServerSettingsRequestPacket; -use pocketmine\network\mcpe\protocol\ServerSettingsResponsePacket; -use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket; -use pocketmine\network\mcpe\protocol\SetActorDataPacket; -use pocketmine\network\mcpe\protocol\SetActorLinkPacket; -use pocketmine\network\mcpe\protocol\SetActorMotionPacket; -use pocketmine\network\mcpe\protocol\SetCommandsEnabledPacket; -use pocketmine\network\mcpe\protocol\SetDefaultGameTypePacket; -use pocketmine\network\mcpe\protocol\SetDifficultyPacket; -use pocketmine\network\mcpe\protocol\SetDisplayObjectivePacket; -use pocketmine\network\mcpe\protocol\SetHealthPacket; -use pocketmine\network\mcpe\protocol\SetLastHurtByPacket; -use pocketmine\network\mcpe\protocol\SetLocalPlayerAsInitializedPacket; -use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket; -use pocketmine\network\mcpe\protocol\SetScoreboardIdentityPacket; -use pocketmine\network\mcpe\protocol\SetScorePacket; -use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket; -use pocketmine\network\mcpe\protocol\SetTimePacket; -use pocketmine\network\mcpe\protocol\SettingsCommandPacket; -use pocketmine\network\mcpe\protocol\SetTitlePacket; -use pocketmine\network\mcpe\protocol\ShowCreditsPacket; -use pocketmine\network\mcpe\protocol\ShowProfilePacket; -use pocketmine\network\mcpe\protocol\ShowStoreOfferPacket; -use pocketmine\network\mcpe\protocol\SimpleEventPacket; -use pocketmine\network\mcpe\protocol\SimulationTypePacket; -use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket; -use pocketmine\network\mcpe\protocol\SpawnParticleEffectPacket; -use pocketmine\network\mcpe\protocol\StartGamePacket; -use pocketmine\network\mcpe\protocol\StopSoundPacket; -use pocketmine\network\mcpe\protocol\StructureBlockUpdatePacket; -use pocketmine\network\mcpe\protocol\StructureTemplateDataRequestPacket; -use pocketmine\network\mcpe\protocol\StructureTemplateDataResponsePacket; -use pocketmine\network\mcpe\protocol\SubClientLoginPacket; -use pocketmine\network\mcpe\protocol\SyncActorPropertyPacket; -use pocketmine\network\mcpe\protocol\TakeItemActorPacket; -use pocketmine\network\mcpe\protocol\TextPacket; -use pocketmine\network\mcpe\protocol\TickSyncPacket; -use pocketmine\network\mcpe\protocol\TransferPacket; -use pocketmine\network\mcpe\protocol\UpdateAttributesPacket; -use pocketmine\network\mcpe\protocol\UpdateBlockPacket; -use pocketmine\network\mcpe\protocol\UpdateBlockSyncedPacket; -use pocketmine\network\mcpe\protocol\UpdateEquipPacket; -use pocketmine\network\mcpe\protocol\UpdatePlayerGameTypePacket; -use pocketmine\network\mcpe\protocol\UpdateSoftEnumPacket; -use pocketmine\network\mcpe\protocol\UpdateTradePacket; /** * Handlers are attached to sessions to handle packets received from their associated clients. A handler @@ -196,664 +33,9 @@ use pocketmine\network\mcpe\protocol\UpdateTradePacket; * This class is an automatically generated stub. Do not edit it manually. */ abstract class PacketHandler implements PacketHandlerInterface{ + use PacketHandlerDefaultImplTrait; public function setUp() : void{ } - - public function handleLogin(LoginPacket $packet) : bool{ - return false; - } - - public function handlePlayStatus(PlayStatusPacket $packet) : bool{ - return false; - } - - public function handleServerToClientHandshake(ServerToClientHandshakePacket $packet) : bool{ - return false; - } - - public function handleClientToServerHandshake(ClientToServerHandshakePacket $packet) : bool{ - return false; - } - - public function handleDisconnect(DisconnectPacket $packet) : bool{ - return false; - } - - public function handleResourcePacksInfo(ResourcePacksInfoPacket $packet) : bool{ - return false; - } - - public function handleResourcePackStack(ResourcePackStackPacket $packet) : bool{ - return false; - } - - public function handleResourcePackClientResponse(ResourcePackClientResponsePacket $packet) : bool{ - return false; - } - - public function handleText(TextPacket $packet) : bool{ - return false; - } - - public function handleSetTime(SetTimePacket $packet) : bool{ - return false; - } - - public function handleStartGame(StartGamePacket $packet) : bool{ - return false; - } - - public function handleAddPlayer(AddPlayerPacket $packet) : bool{ - return false; - } - - public function handleAddActor(AddActorPacket $packet) : bool{ - return false; - } - - public function handleRemoveActor(RemoveActorPacket $packet) : bool{ - return false; - } - - public function handleAddItemActor(AddItemActorPacket $packet) : bool{ - return false; - } - - public function handleTakeItemActor(TakeItemActorPacket $packet) : bool{ - return false; - } - - public function handleMoveActorAbsolute(MoveActorAbsolutePacket $packet) : bool{ - return false; - } - - public function handleMovePlayer(MovePlayerPacket $packet) : bool{ - return false; - } - - public function handleRiderJump(RiderJumpPacket $packet) : bool{ - return false; - } - - public function handleUpdateBlock(UpdateBlockPacket $packet) : bool{ - return false; - } - - public function handleAddPainting(AddPaintingPacket $packet) : bool{ - return false; - } - - public function handleTickSync(TickSyncPacket $packet) : bool{ - return false; - } - - public function handleLevelSoundEventPacketV1(LevelSoundEventPacketV1 $packet) : bool{ - return false; - } - - public function handleLevelEvent(LevelEventPacket $packet) : bool{ - return false; - } - - public function handleBlockEvent(BlockEventPacket $packet) : bool{ - return false; - } - - public function handleActorEvent(ActorEventPacket $packet) : bool{ - return false; - } - - public function handleMobEffect(MobEffectPacket $packet) : bool{ - return false; - } - - public function handleUpdateAttributes(UpdateAttributesPacket $packet) : bool{ - return false; - } - - public function handleInventoryTransaction(InventoryTransactionPacket $packet) : bool{ - return false; - } - - public function handleMobEquipment(MobEquipmentPacket $packet) : bool{ - return false; - } - - public function handleMobArmorEquipment(MobArmorEquipmentPacket $packet) : bool{ - return false; - } - - public function handleInteract(InteractPacket $packet) : bool{ - return false; - } - - public function handleBlockPickRequest(BlockPickRequestPacket $packet) : bool{ - return false; - } - - public function handleActorPickRequest(ActorPickRequestPacket $packet) : bool{ - return false; - } - - public function handlePlayerAction(PlayerActionPacket $packet) : bool{ - return false; - } - - public function handleHurtArmor(HurtArmorPacket $packet) : bool{ - return false; - } - - public function handleSetActorData(SetActorDataPacket $packet) : bool{ - return false; - } - - public function handleSetActorMotion(SetActorMotionPacket $packet) : bool{ - return false; - } - - public function handleSetActorLink(SetActorLinkPacket $packet) : bool{ - return false; - } - - public function handleSetHealth(SetHealthPacket $packet) : bool{ - return false; - } - - public function handleSetSpawnPosition(SetSpawnPositionPacket $packet) : bool{ - return false; - } - - public function handleAnimate(AnimatePacket $packet) : bool{ - return false; - } - - public function handleRespawn(RespawnPacket $packet) : bool{ - return false; - } - - public function handleContainerOpen(ContainerOpenPacket $packet) : bool{ - return false; - } - - public function handleContainerClose(ContainerClosePacket $packet) : bool{ - return false; - } - - public function handlePlayerHotbar(PlayerHotbarPacket $packet) : bool{ - return false; - } - - public function handleInventoryContent(InventoryContentPacket $packet) : bool{ - return false; - } - - public function handleInventorySlot(InventorySlotPacket $packet) : bool{ - return false; - } - - public function handleContainerSetData(ContainerSetDataPacket $packet) : bool{ - return false; - } - - public function handleCraftingData(CraftingDataPacket $packet) : bool{ - return false; - } - - public function handleCraftingEvent(CraftingEventPacket $packet) : bool{ - return false; - } - - public function handleGuiDataPickItem(GuiDataPickItemPacket $packet) : bool{ - return false; - } - - public function handleAdventureSettings(AdventureSettingsPacket $packet) : bool{ - return false; - } - - public function handleBlockActorData(BlockActorDataPacket $packet) : bool{ - return false; - } - - public function handlePlayerInput(PlayerInputPacket $packet) : bool{ - return false; - } - - public function handleLevelChunk(LevelChunkPacket $packet) : bool{ - return false; - } - - public function handleSetCommandsEnabled(SetCommandsEnabledPacket $packet) : bool{ - return false; - } - - public function handleSetDifficulty(SetDifficultyPacket $packet) : bool{ - return false; - } - - public function handleChangeDimension(ChangeDimensionPacket $packet) : bool{ - return false; - } - - public function handleSetPlayerGameType(SetPlayerGameTypePacket $packet) : bool{ - return false; - } - - public function handlePlayerList(PlayerListPacket $packet) : bool{ - return false; - } - - public function handleSimpleEvent(SimpleEventPacket $packet) : bool{ - return false; - } - - public function handleEvent(EventPacket $packet) : bool{ - return false; - } - - public function handleSpawnExperienceOrb(SpawnExperienceOrbPacket $packet) : bool{ - return false; - } - - public function handleClientboundMapItemData(ClientboundMapItemDataPacket $packet) : bool{ - return false; - } - - public function handleMapInfoRequest(MapInfoRequestPacket $packet) : bool{ - return false; - } - - public function handleRequestChunkRadius(RequestChunkRadiusPacket $packet) : bool{ - return false; - } - - public function handleChunkRadiusUpdated(ChunkRadiusUpdatedPacket $packet) : bool{ - return false; - } - - public function handleItemFrameDropItem(ItemFrameDropItemPacket $packet) : bool{ - return false; - } - - public function handleGameRulesChanged(GameRulesChangedPacket $packet) : bool{ - return false; - } - - public function handleCamera(CameraPacket $packet) : bool{ - return false; - } - - public function handleBossEvent(BossEventPacket $packet) : bool{ - return false; - } - - public function handleShowCredits(ShowCreditsPacket $packet) : bool{ - return false; - } - - public function handleAvailableCommands(AvailableCommandsPacket $packet) : bool{ - return false; - } - - public function handleCommandRequest(CommandRequestPacket $packet) : bool{ - return false; - } - - public function handleCommandBlockUpdate(CommandBlockUpdatePacket $packet) : bool{ - return false; - } - - public function handleCommandOutput(CommandOutputPacket $packet) : bool{ - return false; - } - - public function handleUpdateTrade(UpdateTradePacket $packet) : bool{ - return false; - } - - public function handleUpdateEquip(UpdateEquipPacket $packet) : bool{ - return false; - } - - public function handleResourcePackDataInfo(ResourcePackDataInfoPacket $packet) : bool{ - return false; - } - - public function handleResourcePackChunkData(ResourcePackChunkDataPacket $packet) : bool{ - return false; - } - - public function handleResourcePackChunkRequest(ResourcePackChunkRequestPacket $packet) : bool{ - return false; - } - - public function handleTransfer(TransferPacket $packet) : bool{ - return false; - } - - public function handlePlaySound(PlaySoundPacket $packet) : bool{ - return false; - } - - public function handleStopSound(StopSoundPacket $packet) : bool{ - return false; - } - - public function handleSetTitle(SetTitlePacket $packet) : bool{ - return false; - } - - public function handleAddBehaviorTree(AddBehaviorTreePacket $packet) : bool{ - return false; - } - - public function handleStructureBlockUpdate(StructureBlockUpdatePacket $packet) : bool{ - return false; - } - - public function handleShowStoreOffer(ShowStoreOfferPacket $packet) : bool{ - return false; - } - - public function handlePurchaseReceipt(PurchaseReceiptPacket $packet) : bool{ - return false; - } - - public function handlePlayerSkin(PlayerSkinPacket $packet) : bool{ - return false; - } - - public function handleSubClientLogin(SubClientLoginPacket $packet) : bool{ - return false; - } - - public function handleAutomationClientConnect(AutomationClientConnectPacket $packet) : bool{ - return false; - } - - public function handleSetLastHurtBy(SetLastHurtByPacket $packet) : bool{ - return false; - } - - public function handleBookEdit(BookEditPacket $packet) : bool{ - return false; - } - - public function handleNpcRequest(NpcRequestPacket $packet) : bool{ - return false; - } - - public function handlePhotoTransfer(PhotoTransferPacket $packet) : bool{ - return false; - } - - public function handleModalFormRequest(ModalFormRequestPacket $packet) : bool{ - return false; - } - - public function handleModalFormResponse(ModalFormResponsePacket $packet) : bool{ - return false; - } - - public function handleServerSettingsRequest(ServerSettingsRequestPacket $packet) : bool{ - return false; - } - - public function handleServerSettingsResponse(ServerSettingsResponsePacket $packet) : bool{ - return false; - } - - public function handleShowProfile(ShowProfilePacket $packet) : bool{ - return false; - } - - public function handleSetDefaultGameType(SetDefaultGameTypePacket $packet) : bool{ - return false; - } - - public function handleRemoveObjective(RemoveObjectivePacket $packet) : bool{ - return false; - } - - public function handleSetDisplayObjective(SetDisplayObjectivePacket $packet) : bool{ - return false; - } - - public function handleSetScore(SetScorePacket $packet) : bool{ - return false; - } - - public function handleLabTable(LabTablePacket $packet) : bool{ - return false; - } - - public function handleUpdateBlockSynced(UpdateBlockSyncedPacket $packet) : bool{ - return false; - } - - public function handleMoveActorDelta(MoveActorDeltaPacket $packet) : bool{ - return false; - } - - public function handleSetScoreboardIdentity(SetScoreboardIdentityPacket $packet) : bool{ - return false; - } - - public function handleSetLocalPlayerAsInitialized(SetLocalPlayerAsInitializedPacket $packet) : bool{ - return false; - } - - public function handleUpdateSoftEnum(UpdateSoftEnumPacket $packet) : bool{ - return false; - } - - public function handleNetworkStackLatency(NetworkStackLatencyPacket $packet) : bool{ - return false; - } - - public function handleScriptCustomEvent(ScriptCustomEventPacket $packet) : bool{ - return false; - } - - public function handleSpawnParticleEffect(SpawnParticleEffectPacket $packet) : bool{ - return false; - } - - public function handleAvailableActorIdentifiers(AvailableActorIdentifiersPacket $packet) : bool{ - return false; - } - - public function handleLevelSoundEventPacketV2(LevelSoundEventPacketV2 $packet) : bool{ - return false; - } - - public function handleNetworkChunkPublisherUpdate(NetworkChunkPublisherUpdatePacket $packet) : bool{ - return false; - } - - public function handleBiomeDefinitionList(BiomeDefinitionListPacket $packet) : bool{ - return false; - } - - public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{ - return false; - } - - public function handleLevelEventGeneric(LevelEventGenericPacket $packet) : bool{ - return false; - } - - public function handleLecternUpdate(LecternUpdatePacket $packet) : bool{ - return false; - } - - public function handleAddEntity(AddEntityPacket $packet) : bool{ - return false; - } - - public function handleRemoveEntity(RemoveEntityPacket $packet) : bool{ - return false; - } - - public function handleClientCacheStatus(ClientCacheStatusPacket $packet) : bool{ - return false; - } - - public function handleOnScreenTextureAnimation(OnScreenTextureAnimationPacket $packet) : bool{ - return false; - } - - public function handleMapCreateLockedCopy(MapCreateLockedCopyPacket $packet) : bool{ - return false; - } - - public function handleStructureTemplateDataRequest(StructureTemplateDataRequestPacket $packet) : bool{ - return false; - } - - public function handleStructureTemplateDataResponse(StructureTemplateDataResponsePacket $packet) : bool{ - return false; - } - - public function handleClientCacheBlobStatus(ClientCacheBlobStatusPacket $packet) : bool{ - return false; - } - - public function handleClientCacheMissResponse(ClientCacheMissResponsePacket $packet) : bool{ - return false; - } - - public function handleEducationSettings(EducationSettingsPacket $packet) : bool{ - return false; - } - - public function handleEmote(EmotePacket $packet) : bool{ - return false; - } - - public function handleMultiplayerSettings(MultiplayerSettingsPacket $packet) : bool{ - return false; - } - - public function handleSettingsCommand(SettingsCommandPacket $packet) : bool{ - return false; - } - - public function handleAnvilDamage(AnvilDamagePacket $packet) : bool{ - return false; - } - - public function handleCompletedUsingItem(CompletedUsingItemPacket $packet) : bool{ - return false; - } - - public function handleNetworkSettings(NetworkSettingsPacket $packet) : bool{ - return false; - } - - public function handlePlayerAuthInput(PlayerAuthInputPacket $packet) : bool{ - return false; - } - - public function handleCreativeContent(CreativeContentPacket $packet) : bool{ - return false; - } - - public function handlePlayerEnchantOptions(PlayerEnchantOptionsPacket $packet) : bool{ - return false; - } - - public function handleItemStackRequest(ItemStackRequestPacket $packet) : bool{ - return false; - } - - public function handleItemStackResponse(ItemStackResponsePacket $packet) : bool{ - return false; - } - - public function handlePlayerArmorDamage(PlayerArmorDamagePacket $packet) : bool{ - return false; - } - - public function handleCodeBuilder(CodeBuilderPacket $packet) : bool{ - return false; - } - - public function handleUpdatePlayerGameType(UpdatePlayerGameTypePacket $packet) : bool{ - return false; - } - - public function handleEmoteList(EmoteListPacket $packet) : bool{ - return false; - } - - public function handlePositionTrackingDBServerBroadcast(PositionTrackingDBServerBroadcastPacket $packet) : bool{ - return false; - } - - public function handlePositionTrackingDBClientRequest(PositionTrackingDBClientRequestPacket $packet) : bool{ - return false; - } - - public function handleDebugInfo(DebugInfoPacket $packet) : bool{ - return false; - } - - public function handlePacketViolationWarning(PacketViolationWarningPacket $packet) : bool{ - return false; - } - - public function handleMotionPredictionHints(MotionPredictionHintsPacket $packet) : bool{ - return false; - } - - public function handleAnimateEntity(AnimateEntityPacket $packet) : bool{ - return false; - } - - public function handleCameraShake(CameraShakePacket $packet) : bool{ - return false; - } - - public function handlePlayerFog(PlayerFogPacket $packet) : bool{ - return false; - } - - public function handleCorrectPlayerMovePrediction(CorrectPlayerMovePredictionPacket $packet) : bool{ - return false; - } - - public function handleItemComponent(ItemComponentPacket $packet) : bool{ - return false; - } - - public function handleFilterText(FilterTextPacket $packet) : bool{ - return false; - } - - public function handleClientboundDebugRenderer(ClientboundDebugRendererPacket $packet) : bool{ - return false; - } - - public function handleSyncActorProperty(SyncActorPropertyPacket $packet) : bool{ - return false; - } - - public function handleAddVolumeEntity(AddVolumeEntityPacket $packet) : bool{ - return false; - } - - public function handleRemoveVolumeEntity(RemoveVolumeEntityPacket $packet) : bool{ - return false; - } - - public function handleSimulationType(SimulationTypePacket $packet) : bool{ - return false; - } - - public function handleNpcDialogue(NpcDialoguePacket $packet) : bool{ - return false; - } } From 6cf181b5798e510cbbd75ac221b507e74524918a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 16 Sep 2021 14:44:56 +0100 Subject: [PATCH 2850/3224] LevelDB: Use arrow functions for better readability --- src/world/format/io/leveldb/LevelDB.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index f6aeafba31..6713818ac7 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -388,7 +388,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $entities = []; if(($entityData = $this->db->get($index . self::TAG_ENTITY)) !== false and $entityData !== ""){ try{ - $entities = array_map(function(TreeRoot $root) : CompoundTag{ return $root->mustGetCompoundTag(); }, $nbt->readMultiple($entityData)); + $entities = array_map(fn(TreeRoot $root) => $root->mustGetCompoundTag(), $nbt->readMultiple($entityData)); }catch(NbtDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } @@ -398,7 +398,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $tiles = []; if(($tileData = $this->db->get($index . self::TAG_BLOCK_ENTITY)) !== false and $tileData !== ""){ try{ - $tiles = array_map(function(TreeRoot $root) : CompoundTag{ return $root->mustGetCompoundTag(); }, $nbt->readMultiple($tileData)); + $tiles = array_map(fn(TreeRoot $root) => $root->mustGetCompoundTag(), $nbt->readMultiple($tileData)); }catch(NbtDataException $e){ throw new CorruptedChunkException($e->getMessage(), 0, $e); } @@ -496,7 +496,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ private function writeTags(array $targets, string $index, \LevelDBWriteBatch $write) : void{ if(count($targets) > 0){ $nbt = new LittleEndianNbtSerializer(); - $write->put($index, $nbt->writeMultiple(array_map(function(CompoundTag $tag) : TreeRoot{ return new TreeRoot($tag); }, $targets))); + $write->put($index, $nbt->writeMultiple(array_map(fn(CompoundTag $tag) => new TreeRoot($tag), $targets))); }else{ $write->delete($index); } From 05e2bef5ce7f08db75452b00ef9595e05765727a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 16 Sep 2021 14:53:19 +0100 Subject: [PATCH 2851/3224] ItemFactory: fix crash when checking if blockitem IDs are registered --- src/item/ItemFactory.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 2c99611322..5fb7438a10 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -432,6 +432,10 @@ class ItemFactory{ $this->list[self::getListOffset($identifier->getId(), $identifier->getMeta())] = clone $item; } + private static function itemToBlockId(int $id) : int{ + return $id < 0 ? 255 - $id : $id; + } + /** * @deprecated This method should ONLY be used for deserializing data, e.g. from a config or database. For all other * purposes, use VanillaItems. @@ -456,7 +460,7 @@ class ItemFactory{ } }elseif($id < 256){ //intentionally includes negatives, for extended block IDs //TODO: do not assume that item IDs and block IDs are the same or related - $item = new ItemBlock(new ItemIdentifier($id, $meta), BlockFactory::getInstance()->get($id < 0 ? 255 - $id : $id, $meta & 0xf)); + $item = new ItemBlock(new ItemIdentifier($id, $meta), BlockFactory::getInstance()->get(self::itemToBlockId($id), $meta & 0xf)); } } @@ -481,7 +485,7 @@ class ItemFactory{ */ public function isRegistered(int $id, int $variant = 0) : bool{ if($id < 256){ - return BlockFactory::getInstance()->isRegistered($id); + return BlockFactory::getInstance()->isRegistered(self::itemToBlockId($id)); } return isset($this->list[self::getListOffset($id, $variant)]); From 43b2e1a0e8210302d1de6251653c6875dda55085 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 16 Sep 2021 15:28:20 +0100 Subject: [PATCH 2852/3224] tools/convert-world: improve error messages and exit codes die with a string exits with zero? wtf? --- tools/convert-world.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tools/convert-world.php b/tools/convert-world.php index c70f23a697..7d83d5fd85 100644 --- a/tools/convert-world.php +++ b/tools/convert-world.php @@ -43,29 +43,35 @@ $plainArgs = getopt("", array_map(function(string $str){ return "$str:"; }, arra $args = []; foreach($requiredOpts as $opt => $desc){ if(!isset($plainArgs[$opt]) || !is_string($plainArgs[$opt])){ - die($usageMessage); + fwrite(STDERR, $usageMessage); + exit(1); } $args[$opt] = $plainArgs[$opt]; } if(!array_key_exists($args["format"], $writableFormats)){ - die($usageMessage); + fwrite(STDERR, $usageMessage); + exit(1); } $inputPath = realpath($args["world"]); if($inputPath === false){ - die("Cannot find input world at location: " . $args["world"]); + fwrite(STDERR, "Cannot find input world at location: " . $args["world"] . PHP_EOL); + exit(1); } $backupPath = realpath($args["backup"]); if($backupPath === false || (!@mkdir($backupPath, 0777, true) and !is_dir($backupPath)) or !is_writable($backupPath)){ - die("Backup file path " . $args["backup"] . " is not writable (permission error or doesn't exist), aborting"); + fwrite(STDERR, "Backup file path " . $args["backup"] . " is not writable (permission error or doesn't exist), aborting" . PHP_EOL); + exit(1); } $oldProviderClasses = $providerManager->getMatchingProviders($inputPath); if(count($oldProviderClasses) === 0){ - die("Unknown input world format"); + fwrite(STDERR, "Unknown input world format" . PHP_EOL); + exit(1); } if(count($oldProviderClasses) > 1){ - die("Ambiguous input world format: matched " . count($oldProviderClasses) . " (" . implode(array_keys($oldProviderClasses)) . ")"); + fwrite(STDERR, "Ambiguous input world format: matched " . count($oldProviderClasses) . " (" . implode(array_keys($oldProviderClasses)) . ")" . PHP_EOL); + exit(1); } $oldProviderClass = array_shift($oldProviderClasses); $oldProvider = $oldProviderClass->fromPath($inputPath); From 87dc763d924c4221f599fad4bcd35e9cadbc72a7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 17 Sep 2021 16:46:27 +0100 Subject: [PATCH 2853/3224] actions: test that generated code is consistent --- .github/workflows/main.yml | 61 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2176401d39..db51b50701 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -183,6 +183,67 @@ jobs: - name: Run integration tests run: ./tests/travis.sh -t4 + codegen: + name: Generated Code consistency checks + needs: build-php + runs-on: ${{ matrix.image }} + strategy: + fail-fast: false + matrix: + image: [ubuntu-20.04] + php: [8.0.9] + + steps: + - uses: actions/checkout@v2 + with: + submodules: true + + - name: Restore PHP build cache + id: php-build-cache + uses: actions/cache@v2 + with: + path: "./bin" + key: "php-build-generic-${{ matrix.php }}-${{ matrix.image }}-${{ hashFiles('./tests/gh-actions/build.sh') }}" + + - name: Kill build on PHP build cache miss (should never happen) + if: steps.php-build-cache.outputs.cache-hit != 'true' + run: exit 1 + + - name: Install cached PHP's dependencies + if: steps.php-build-cache.outputs.cache-hit == 'true' + run: ./tests/gh-actions/install-dependencies.sh + + - name: Prefix PHP to PATH + run: echo "$(pwd)/bin/php7/bin" >> $GITHUB_PATH + + - name: Install Composer + run: curl -sS https://getcomposer.org/installer | php + + - name: Restore Composer package cache + uses: actions/cache@v2 + with: + path: | + ~/.cache/composer/files + ~/.cache/composer/vcs + key: "composer-v2-cache-${{ matrix.php }}-${{ hashFiles('./composer.lock') }}" + restore-keys: | + composer-v2-cache- + + - name: Install Composer dependencies + run: php composer.phar install --no-dev --prefer-dist --no-interaction + + - name: Regenerate registry annotations + run: php build/generate-registry-annotations.php src + + - name: Regenerate KnownTranslation APIs + run: php build/generate-known-translation-apis.php + + - name: Run git diff + run: git diff + + - name: Fail job if changes were made + run: git diff --quiet + codestyle: name: Code Style checks runs-on: ubuntu-20.04 From 3836a57ba6c5b4ae03c36f771333f026d530f0cf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 17 Sep 2021 22:17:36 +0100 Subject: [PATCH 2854/3224] Player: add getPlayerInfo(), closes #4450 --- src/player/Player.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/player/Player.php b/src/player/Player.php index 9a45635428..14a6b205a9 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -340,6 +340,12 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return $this->authenticated; } + /** + * Returns an object containing information about the player, such as their username, skin, and misc extra + * client-specific data. + */ + public function getPlayerInfo() : PlayerInfo{ return $this->playerInfo; } + /** * If the player is logged into Xbox Live, returns their Xbox user ID (XUID) as a string. Returns an empty string if * the player is not logged into Xbox Live. From 1b5071e0745bd129840514ad40ec7a3cbaeb8899 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 Sep 2021 15:28:45 +0100 Subject: [PATCH 2855/3224] Liquid: make some code slightly less cancerous to read --- src/block/Liquid.php | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/block/Liquid.php b/src/block/Liquid.php index 74f88255b9..e873d59b99 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -273,13 +273,15 @@ abstract class Liquid extends Transparent{ public function onScheduledUpdate() : void{ $multiplier = $this->getFlowDecayPerBlock(); + $world = $this->position->getWorld(); + if(!$this->isSource()){ $smallestFlowDecay = -100; $this->adjacentSources = 0; - $smallestFlowDecay = $this->getSmallestFlowDecay($this->position->getWorld()->getBlockAt($this->position->x, $this->position->y, $this->position->z - 1), $smallestFlowDecay); - $smallestFlowDecay = $this->getSmallestFlowDecay($this->position->getWorld()->getBlockAt($this->position->x, $this->position->y, $this->position->z + 1), $smallestFlowDecay); - $smallestFlowDecay = $this->getSmallestFlowDecay($this->position->getWorld()->getBlockAt($this->position->x - 1, $this->position->y, $this->position->z), $smallestFlowDecay); - $smallestFlowDecay = $this->getSmallestFlowDecay($this->position->getWorld()->getBlockAt($this->position->x + 1, $this->position->y, $this->position->z), $smallestFlowDecay); + $smallestFlowDecay = $this->getSmallestFlowDecay($world->getBlockAt($this->position->x, $this->position->y, $this->position->z - 1), $smallestFlowDecay); + $smallestFlowDecay = $this->getSmallestFlowDecay($world->getBlockAt($this->position->x, $this->position->y, $this->position->z + 1), $smallestFlowDecay); + $smallestFlowDecay = $this->getSmallestFlowDecay($world->getBlockAt($this->position->x - 1, $this->position->y, $this->position->z), $smallestFlowDecay); + $smallestFlowDecay = $this->getSmallestFlowDecay($world->getBlockAt($this->position->x + 1, $this->position->y, $this->position->z), $smallestFlowDecay); $newDecay = $smallestFlowDecay + $multiplier; $falling = false; @@ -288,12 +290,12 @@ abstract class Liquid extends Transparent{ $newDecay = -1; } - if($this->getEffectiveFlowDecay($this->position->getWorld()->getBlockAt($this->position->x, $this->position->y + 1, $this->position->z)) >= 0){ + if($this->getEffectiveFlowDecay($world->getBlockAt($this->position->x, $this->position->y + 1, $this->position->z)) >= 0){ $falling = true; } if($this->adjacentSources >= 2 and $this instanceof Water){ - $bottomBlock = $this->position->getWorld()->getBlockAt($this->position->x, $this->position->y - 1, $this->position->z); + $bottomBlock = $world->getBlockAt($this->position->x, $this->position->y - 1, $this->position->z); if($bottomBlock->isSolid() or ($bottomBlock instanceof Water and $bottomBlock->isSource())){ $newDecay = 0; $falling = false; @@ -302,17 +304,17 @@ abstract class Liquid extends Transparent{ if($falling !== $this->falling or (!$falling and $newDecay !== $this->decay)){ if(!$falling and $newDecay < 0){ - $this->position->getWorld()->setBlock($this->position, VanillaBlocks::AIR()); + $world->setBlock($this->position, VanillaBlocks::AIR()); return; } $this->falling = $falling; $this->decay = $falling ? 0 : $newDecay; - $this->position->getWorld()->setBlock($this->position, $this); //local block update will cause an update to be scheduled + $world->setBlock($this->position, $this); //local block update will cause an update to be scheduled } } - $bottomBlock = $this->position->getWorld()->getBlockAt($this->position->x, $this->position->y - 1, $this->position->z); + $bottomBlock = $world->getBlockAt($this->position->x, $this->position->y - 1, $this->position->z); $this->flowIntoBlock($bottomBlock, 0, true); @@ -327,19 +329,19 @@ abstract class Liquid extends Transparent{ $flags = $this->getOptimalFlowDirections(); if($flags[0]){ - $this->flowIntoBlock($this->position->getWorld()->getBlockAt($this->position->x - 1, $this->position->y, $this->position->z), $adjacentDecay, false); + $this->flowIntoBlock($world->getBlockAt($this->position->x - 1, $this->position->y, $this->position->z), $adjacentDecay, false); } if($flags[1]){ - $this->flowIntoBlock($this->position->getWorld()->getBlockAt($this->position->x + 1, $this->position->y, $this->position->z), $adjacentDecay, false); + $this->flowIntoBlock($world->getBlockAt($this->position->x + 1, $this->position->y, $this->position->z), $adjacentDecay, false); } if($flags[2]){ - $this->flowIntoBlock($this->position->getWorld()->getBlockAt($this->position->x, $this->position->y, $this->position->z - 1), $adjacentDecay, false); + $this->flowIntoBlock($world->getBlockAt($this->position->x, $this->position->y, $this->position->z - 1), $adjacentDecay, false); } if($flags[3]){ - $this->flowIntoBlock($this->position->getWorld()->getBlockAt($this->position->x, $this->position->y, $this->position->z + 1), $adjacentDecay, false); + $this->flowIntoBlock($world->getBlockAt($this->position->x, $this->position->y, $this->position->z + 1), $adjacentDecay, false); } } } @@ -368,6 +370,7 @@ abstract class Liquid extends Transparent{ private function calculateFlowCost(int $blockX, int $blockY, int $blockZ, int $accumulatedCost, int $maxCost, int $originOpposite, int $lastOpposite) : int{ $cost = 1000; + $world = $this->position->getWorld(); for($j = 0; $j < 4; ++$j){ if($j === $originOpposite or $j === $lastOpposite){ continue; @@ -388,10 +391,10 @@ abstract class Liquid extends Transparent{ } if(!isset($this->flowCostVisited[$hash = World::blockHash($x, $y, $z)])){ - $blockSide = $this->position->getWorld()->getBlockAt($x, $y, $z); + $blockSide = $world->getBlockAt($x, $y, $z); if(!$this->canFlowInto($blockSide)){ $this->flowCostVisited[$hash] = self::BLOCKED; - }elseif($this->position->getWorld()->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ + }elseif($world->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ $this->flowCostVisited[$hash] = self::CAN_FLOW_DOWN; }else{ $this->flowCostVisited[$hash] = self::CAN_FLOW; @@ -424,6 +427,7 @@ abstract class Liquid extends Transparent{ * @return bool[] */ private function getOptimalFlowDirections() : array{ + $world = $this->position->getWorld(); $flowCost = array_fill(0, 4, 1000); $maxCost = intdiv(4, $this->getFlowDecayPerBlock()); for($j = 0; $j < 4; ++$j){ @@ -440,11 +444,11 @@ abstract class Liquid extends Transparent{ }elseif($j === 3){ ++$z; } - $block = $this->position->getWorld()->getBlockAt($x, $y, $z); + $block = $world->getBlockAt($x, $y, $z); if(!$this->canFlowInto($block)){ $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::BLOCKED; - }elseif($this->position->getWorld()->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ + }elseif($world->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::CAN_FLOW_DOWN; $flowCost[$j] = $maxCost = 0; }elseif($maxCost > 0){ From b0471007199dea330932047e1a70341db962e496 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 Sep 2021 15:52:16 +0100 Subject: [PATCH 2856/3224] Liquid: improve minimum cost calculation handling --- src/block/Liquid.php | 52 ++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/src/block/Liquid.php b/src/block/Liquid.php index e873d59b99..bf8327a376 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -29,6 +29,7 @@ use pocketmine\event\block\BlockFormEvent; use pocketmine\event\block\BlockSpreadEvent; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\world\sound\FizzSound; use pocketmine\world\sound\Sound; @@ -326,22 +327,8 @@ abstract class Liquid extends Transparent{ } if($adjacentDecay < 8){ - $flags = $this->getOptimalFlowDirections(); - - if($flags[0]){ - $this->flowIntoBlock($world->getBlockAt($this->position->x - 1, $this->position->y, $this->position->z), $adjacentDecay, false); - } - - if($flags[1]){ - $this->flowIntoBlock($world->getBlockAt($this->position->x + 1, $this->position->y, $this->position->z), $adjacentDecay, false); - } - - if($flags[2]){ - $this->flowIntoBlock($world->getBlockAt($this->position->x, $this->position->y, $this->position->z - 1), $adjacentDecay, false); - } - - if($flags[3]){ - $this->flowIntoBlock($world->getBlockAt($this->position->x, $this->position->y, $this->position->z + 1), $adjacentDecay, false); + foreach($this->getOptimalFlowDirections() as $facing){ + $this->flowIntoBlock($world->getBlock($this->position->getSide($facing)), $adjacentDecay, false); } } } @@ -371,7 +358,7 @@ abstract class Liquid extends Transparent{ $cost = 1000; $world = $this->position->getWorld(); - for($j = 0; $j < 4; ++$j){ + foreach(Facing::HORIZONTAL as $j){ if($j === $originOpposite or $j === $lastOpposite){ continue; } @@ -380,13 +367,13 @@ abstract class Liquid extends Transparent{ $y = $blockY; $z = $blockZ; - if($j === 0){ + if($j === Facing::WEST){ --$x; - }elseif($j === 1){ + }elseif($j === Facing::EAST){ ++$x; - }elseif($j === 2){ + }elseif($j === Facing::NORTH){ --$z; - }elseif($j === 3){ + }elseif($j === Facing::SOUTH){ ++$z; } @@ -413,7 +400,7 @@ abstract class Liquid extends Transparent{ continue; } - $realCost = $this->calculateFlowCost($x, $y, $z, $accumulatedCost + 1, $maxCost, $originOpposite, $j ^ 0x01); + $realCost = $this->calculateFlowCost($x, $y, $z, $accumulatedCost + 1, $maxCost, $originOpposite, Facing::opposite($j)); if($realCost < $cost){ $cost = $realCost; @@ -424,24 +411,24 @@ abstract class Liquid extends Transparent{ } /** - * @return bool[] + * @return int[] */ private function getOptimalFlowDirections() : array{ $world = $this->position->getWorld(); $flowCost = array_fill(0, 4, 1000); $maxCost = intdiv(4, $this->getFlowDecayPerBlock()); - for($j = 0; $j < 4; ++$j){ + foreach(Facing::HORIZONTAL as $j){ $x = $this->position->x; $y = $this->position->y; $z = $this->position->z; - if($j === 0){ + if($j === Facing::WEST){ --$x; - }elseif($j === 1){ + }elseif($j === Facing::EAST){ ++$x; - }elseif($j === 2){ + }elseif($j === Facing::NORTH){ --$z; - }elseif($j === 3){ + }elseif($j === Facing::SOUTH){ ++$z; } $block = $world->getBlockAt($x, $y, $z); @@ -453,7 +440,8 @@ abstract class Liquid extends Transparent{ $flowCost[$j] = $maxCost = 0; }elseif($maxCost > 0){ $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::CAN_FLOW; - $flowCost[$j] = $this->calculateFlowCost($x, $y, $z, 1, $maxCost, $j ^ 0x01, $j ^ 0x01); + $opposite = Facing::opposite($j); + $flowCost[$j] = $this->calculateFlowCost($x, $y, $z, 1, $maxCost, $opposite, $opposite); $maxCost = min($maxCost, $flowCost[$j]); } } @@ -464,8 +452,10 @@ abstract class Liquid extends Transparent{ $isOptimalFlowDirection = []; - for($i = 0; $i < 4; ++$i){ - $isOptimalFlowDirection[$i] = ($flowCost[$i] === $minCost); + foreach($flowCost as $facing => $cost){ + if($cost === $minCost){ + $isOptimalFlowDirection[] = $facing; + } } return $isOptimalFlowDirection; From 34e1b244fa95a08e19b28759417103004dd6eb4a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 Sep 2021 15:53:54 +0100 Subject: [PATCH 2857/3224] Liquid: split canFlowInto() over multiple lines the original version is very hard to read. --- src/block/Liquid.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/block/Liquid.php b/src/block/Liquid.php index bf8327a376..542b2dc48b 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -493,6 +493,9 @@ abstract class Liquid extends Transparent{ } protected function canFlowInto(Block $block) : bool{ - return $this->position->getWorld()->isInWorld($block->position->x, $block->position->y, $block->position->z) and $block->canBeFlowedInto() and !($block instanceof Liquid and $block->isSource()); //TODO: I think this should only be liquids of the same type + return + $this->position->getWorld()->isInWorld($block->position->x, $block->position->y, $block->position->z) and + $block->canBeFlowedInto() and + !($block instanceof Liquid and $block->isSource()); //TODO: I think this should only be liquids of the same type } } From a9c4238c59f05262cdfb2bfcd418298449f08a5e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 Sep 2021 16:13:38 +0100 Subject: [PATCH 2858/3224] Liquid: Extract a big chunk of code to MinimumCostFlowCalculator --- src/block/Liquid.php | 124 +------------- src/block/utils/MinimumCostFlowCalculator.php | 160 ++++++++++++++++++ 2 files changed, 163 insertions(+), 121 deletions(-) create mode 100644 src/block/utils/MinimumCostFlowCalculator.php diff --git a/src/block/Liquid.php b/src/block/Liquid.php index 542b2dc48b..9329453dba 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -24,20 +24,16 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\MinimumCostFlowCalculator; use pocketmine\entity\Entity; use pocketmine\event\block\BlockFormEvent; use pocketmine\event\block\BlockSpreadEvent; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; -use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\world\sound\FizzSound; use pocketmine\world\sound\Sound; -use pocketmine\world\World; -use function array_fill; -use function intdiv; use function lcg_value; -use function min; abstract class Liquid extends Transparent{ @@ -47,13 +43,6 @@ abstract class Liquid extends Transparent{ protected ?Vector3 $flowVector = null; - /** @var int[] */ - private array $flowCostVisited = []; - - private const CAN_FLOW_DOWN = 1; - private const CAN_FLOW = 0; - private const BLOCKED = -1; - protected bool $falling = false; protected int $decay = 0; //PC "level" property protected bool $still = false; @@ -327,7 +316,8 @@ abstract class Liquid extends Transparent{ } if($adjacentDecay < 8){ - foreach($this->getOptimalFlowDirections() as $facing){ + $calculator = new MinimumCostFlowCalculator($this->position->getWorld(), $this->getFlowDecayPerBlock(), \Closure::fromCallable([$this, 'canFlowInto'])); + foreach($calculator->getOptimalFlowDirections($this->position->getFloorX(), $this->position->getFloorY(), $this->position->getFloorZ()) as $facing){ $this->flowIntoBlock($world->getBlock($this->position->getSide($facing)), $adjacentDecay, false); } } @@ -354,113 +344,6 @@ abstract class Liquid extends Transparent{ } } - private function calculateFlowCost(int $blockX, int $blockY, int $blockZ, int $accumulatedCost, int $maxCost, int $originOpposite, int $lastOpposite) : int{ - $cost = 1000; - - $world = $this->position->getWorld(); - foreach(Facing::HORIZONTAL as $j){ - if($j === $originOpposite or $j === $lastOpposite){ - continue; - } - - $x = $blockX; - $y = $blockY; - $z = $blockZ; - - if($j === Facing::WEST){ - --$x; - }elseif($j === Facing::EAST){ - ++$x; - }elseif($j === Facing::NORTH){ - --$z; - }elseif($j === Facing::SOUTH){ - ++$z; - } - - if(!isset($this->flowCostVisited[$hash = World::blockHash($x, $y, $z)])){ - $blockSide = $world->getBlockAt($x, $y, $z); - if(!$this->canFlowInto($blockSide)){ - $this->flowCostVisited[$hash] = self::BLOCKED; - }elseif($world->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ - $this->flowCostVisited[$hash] = self::CAN_FLOW_DOWN; - }else{ - $this->flowCostVisited[$hash] = self::CAN_FLOW; - } - } - - $status = $this->flowCostVisited[$hash]; - - if($status === self::BLOCKED){ - continue; - }elseif($status === self::CAN_FLOW_DOWN){ - return $accumulatedCost; - } - - if($accumulatedCost >= $maxCost){ - continue; - } - - $realCost = $this->calculateFlowCost($x, $y, $z, $accumulatedCost + 1, $maxCost, $originOpposite, Facing::opposite($j)); - - if($realCost < $cost){ - $cost = $realCost; - } - } - - return $cost; - } - - /** - * @return int[] - */ - private function getOptimalFlowDirections() : array{ - $world = $this->position->getWorld(); - $flowCost = array_fill(0, 4, 1000); - $maxCost = intdiv(4, $this->getFlowDecayPerBlock()); - foreach(Facing::HORIZONTAL as $j){ - $x = $this->position->x; - $y = $this->position->y; - $z = $this->position->z; - - if($j === Facing::WEST){ - --$x; - }elseif($j === Facing::EAST){ - ++$x; - }elseif($j === Facing::NORTH){ - --$z; - }elseif($j === Facing::SOUTH){ - ++$z; - } - $block = $world->getBlockAt($x, $y, $z); - - if(!$this->canFlowInto($block)){ - $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::BLOCKED; - }elseif($world->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ - $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::CAN_FLOW_DOWN; - $flowCost[$j] = $maxCost = 0; - }elseif($maxCost > 0){ - $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::CAN_FLOW; - $opposite = Facing::opposite($j); - $flowCost[$j] = $this->calculateFlowCost($x, $y, $z, 1, $maxCost, $opposite, $opposite); - $maxCost = min($maxCost, $flowCost[$j]); - } - } - - $this->flowCostVisited = []; - - $minCost = min($flowCost); - - $isOptimalFlowDirection = []; - - foreach($flowCost as $facing => $cost){ - if($cost === $minCost){ - $isOptimalFlowDirection[] = $facing; - } - } - - return $isOptimalFlowDirection; - } - /** @phpstan-impure */ private function getSmallestFlowDecay(Block $block, int $decay) : int{ if(!($block instanceof Liquid) or !$block->isSameType($this)){ @@ -494,7 +377,6 @@ abstract class Liquid extends Transparent{ protected function canFlowInto(Block $block) : bool{ return - $this->position->getWorld()->isInWorld($block->position->x, $block->position->y, $block->position->z) and $block->canBeFlowedInto() and !($block instanceof Liquid and $block->isSource()); //TODO: I think this should only be liquids of the same type } diff --git a/src/block/utils/MinimumCostFlowCalculator.php b/src/block/utils/MinimumCostFlowCalculator.php new file mode 100644 index 0000000000..46a078fd66 --- /dev/null +++ b/src/block/utils/MinimumCostFlowCalculator.php @@ -0,0 +1,160 @@ +flowCostVisited[$hash = World::blockHash($x, $y, $z)])){ + if(!$this->world->isInWorld($x, $y, $z) || !$this->canFlowInto($this->world->getBlockAt($x, $y, $z))){ + $this->flowCostVisited[$hash] = self::BLOCKED; + }elseif($this->world->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ + $this->flowCostVisited[$hash] = self::CAN_FLOW_DOWN; + }else{ + $this->flowCostVisited[$hash] = self::CAN_FLOW; + } + } + + $status = $this->flowCostVisited[$hash]; + + if($status === self::BLOCKED){ + continue; + }elseif($status === self::CAN_FLOW_DOWN){ + return $accumulatedCost; + } + + if($accumulatedCost >= $maxCost){ + continue; + } + + $realCost = $this->calculateFlowCost($x, $y, $z, $accumulatedCost + 1, $maxCost, $originOpposite, Facing::opposite($j)); + + if($realCost < $cost){ + $cost = $realCost; + } + } + + return $cost; + } + + /** + * @return int[] + */ + public function getOptimalFlowDirections(int $originX, int $originY, int $originZ) : array{ + $flowCost = array_fill(0, 4, 1000); + $maxCost = intdiv(4, $this->flowDecayPerBlock); + foreach(Facing::HORIZONTAL as $j){ + $x = $originX; + $y = $originY; + $z = $originZ; + + if($j === Facing::WEST){ + --$x; + }elseif($j === Facing::EAST){ + ++$x; + }elseif($j === Facing::NORTH){ + --$z; + }elseif($j === Facing::SOUTH){ + ++$z; + } + + if(!$this->world->isInWorld($x, $y, $z) || !$this->canFlowInto($this->world->getBlockAt($x, $y, $z))){ + $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::BLOCKED; + }elseif($this->world->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ + $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::CAN_FLOW_DOWN; + $flowCost[$j] = $maxCost = 0; + }elseif($maxCost > 0){ + $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::CAN_FLOW; + $opposite = Facing::opposite($j); + $flowCost[$j] = $this->calculateFlowCost($x, $y, $z, 1, $maxCost, $opposite, $opposite); + $maxCost = min($maxCost, $flowCost[$j]); + } + } + + $this->flowCostVisited = []; + + $minCost = min($flowCost); + + $isOptimalFlowDirection = []; + + foreach($flowCost as $facing => $cost){ + if($cost === $minCost){ + $isOptimalFlowDirection[] = $facing; + } + } + + return $isOptimalFlowDirection; + } + + private function canFlowInto(Block $block) : bool{ + return ($this->canFlowInto)($block); + } +} From 027f7e249b865d216db3eb1312241046f67f2205 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 Sep 2021 16:17:08 +0100 Subject: [PATCH 2859/3224] MinimumCostFlowCalculator: Use match statements where possible coincidentally, this also fixes the build. --- src/block/utils/MinimumCostFlowCalculator.php | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/block/utils/MinimumCostFlowCalculator.php b/src/block/utils/MinimumCostFlowCalculator.php index 46a078fd66..94704857f5 100644 --- a/src/block/utils/MinimumCostFlowCalculator.php +++ b/src/block/utils/MinimumCostFlowCalculator.php @@ -63,15 +63,12 @@ final class MinimumCostFlowCalculator{ $y = $blockY; $z = $blockZ; - if($j === Facing::WEST){ - --$x; - }elseif($j === Facing::EAST){ - ++$x; - }elseif($j === Facing::NORTH){ - --$z; - }elseif($j === Facing::SOUTH){ - ++$z; - } + match($j){ + Facing::WEST => --$x, + Facing::EAST => ++$x, + Facing::NORTH => --$z, + Facing::SOUTH => ++$z + }; if(!isset($this->flowCostVisited[$hash = World::blockHash($x, $y, $z)])){ if(!$this->world->isInWorld($x, $y, $z) || !$this->canFlowInto($this->world->getBlockAt($x, $y, $z))){ @@ -116,15 +113,12 @@ final class MinimumCostFlowCalculator{ $y = $originY; $z = $originZ; - if($j === Facing::WEST){ - --$x; - }elseif($j === Facing::EAST){ - ++$x; - }elseif($j === Facing::NORTH){ - --$z; - }elseif($j === Facing::SOUTH){ - ++$z; - } + match($j){ + Facing::WEST => --$x, + Facing::EAST => ++$x, + Facing::NORTH => --$z, + Facing::SOUTH => ++$z + }; if(!$this->world->isInWorld($x, $y, $z) || !$this->canFlowInto($this->world->getBlockAt($x, $y, $z))){ $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::BLOCKED; From 6b2ab15ea1f59eca437ba254d1dcaf799f1274aa Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 Sep 2021 16:20:01 +0100 Subject: [PATCH 2860/3224] MinimumCostFlowCalculator: fix bug caused by recent change --- src/block/utils/MinimumCostFlowCalculator.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/block/utils/MinimumCostFlowCalculator.php b/src/block/utils/MinimumCostFlowCalculator.php index 94704857f5..95e8457917 100644 --- a/src/block/utils/MinimumCostFlowCalculator.php +++ b/src/block/utils/MinimumCostFlowCalculator.php @@ -26,7 +26,7 @@ namespace pocketmine\block\utils; use pocketmine\block\Block; use pocketmine\math\Facing; use pocketmine\world\World; -use function array_fill; +use function array_fill_keys; use function intdiv; use function min; @@ -106,7 +106,7 @@ final class MinimumCostFlowCalculator{ * @return int[] */ public function getOptimalFlowDirections(int $originX, int $originY, int $originZ) : array{ - $flowCost = array_fill(0, 4, 1000); + $flowCost = array_fill_keys(Facing::HORIZONTAL, 1000); $maxCost = intdiv(4, $this->flowDecayPerBlock); foreach(Facing::HORIZONTAL as $j){ $x = $originX; From 576c33ee8f9db11bf2ff9dbaaf00161994378302 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 Sep 2021 23:04:28 +0100 Subject: [PATCH 2861/3224] Liquid: make flow vector calculation less cancerous to read --- src/block/Liquid.php | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/block/Liquid.php b/src/block/Liquid.php index 9329453dba..c7f0e3da83 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -30,6 +30,7 @@ use pocketmine\event\block\BlockFormEvent; use pocketmine\event\block\BlockSpreadEvent; use pocketmine\item\Item; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\world\sound\FizzSound; use pocketmine\world\sound\Sound; @@ -221,17 +222,15 @@ abstract class Liquid extends Transparent{ $vector = new Vector3($vX, $vY, $vZ); if($this->falling){ - if( - !$this->canFlowInto($world->getBlockAt($this->position->x, $this->position->y, $this->position->z - 1)) or - !$this->canFlowInto($world->getBlockAt($this->position->x, $this->position->y, $this->position->z + 1)) or - !$this->canFlowInto($world->getBlockAt($this->position->x - 1, $this->position->y, $this->position->z)) or - !$this->canFlowInto($world->getBlockAt($this->position->x + 1, $this->position->y, $this->position->z)) or - !$this->canFlowInto($world->getBlockAt($this->position->x, $this->position->y + 1, $this->position->z - 1)) or - !$this->canFlowInto($world->getBlockAt($this->position->x, $this->position->y + 1, $this->position->z + 1)) or - !$this->canFlowInto($world->getBlockAt($this->position->x - 1, $this->position->y + 1, $this->position->z)) or - !$this->canFlowInto($world->getBlockAt($this->position->x + 1, $this->position->y + 1, $this->position->z)) - ){ - $vector = $vector->normalize()->add(0, -6, 0); + foreach(Facing::HORIZONTAL as $facing){ + $pos = $this->position->getSide($facing); + if( + !$this->canFlowInto($world->getBlockAt($pos->x, $pos->y, $pos->z)) || + !$this->canFlowInto($world->getBlockAt($pos->x, $pos->y + 1, $pos->z)) + ){ + $vector = $vector->normalize()->add(0, -6, 0); + break; + } } } From 18de35ffc79ba89d857775e2d7b9565613231ce7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 19 Sep 2021 15:37:03 +0100 Subject: [PATCH 2862/3224] Liquid: use facing instead of hardcoded integers --- src/block/Liquid.php | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/block/Liquid.php b/src/block/Liquid.php index c7f0e3da83..d6bcc8f316 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -177,21 +177,17 @@ abstract class Liquid extends Transparent{ $world = $this->position->getWorld(); - for($j = 0; $j < 4; ++$j){ - + foreach(Facing::HORIZONTAL as $j){ $x = $this->position->x; $y = $this->position->y; $z = $this->position->z; - if($j === 0){ - --$x; - }elseif($j === 1){ - ++$x; - }elseif($j === 2){ - --$z; - }elseif($j === 3){ - ++$z; - } + match($j){ + Facing::WEST => --$x, + Facing::EAST => ++$x, + Facing::NORTH => --$z, + Facing::SOUTH => ++$z + }; $sideBlock = $world->getBlockAt($x, $y, $z); $blockDecay = $this->getEffectiveFlowDecay($sideBlock); From 971cbe39295010351931737aadf12c2a18fbfad5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 19 Sep 2021 15:42:17 +0100 Subject: [PATCH 2863/3224] Liquid: restore mistakenly removed check --- src/block/Liquid.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/block/Liquid.php b/src/block/Liquid.php index d6bcc8f316..677c3b0aef 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -372,6 +372,7 @@ abstract class Liquid extends Transparent{ protected function canFlowInto(Block $block) : bool{ return + $this->position->getWorld()->isInWorld($block->position->x, $block->position->y, $block->position->z) and $block->canBeFlowedInto() and !($block instanceof Liquid and $block->isSource()); //TODO: I think this should only be liquids of the same type } From 1ce388ca0b977dd700d05a1756adc04714e3dccf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 19 Sep 2021 15:59:16 +0100 Subject: [PATCH 2864/3224] Liquid: add getMinAdjacentSourcesToFormSource(), remove circular dependency between Liquid and Water this unpleasantly-named method allows controlling the source-forming behaviour of liquids by changing the required number of adjacent sources that must be present in order for a new source to form. This allows stuff like non-infinite water. --- src/block/Liquid.php | 13 +++++++++++-- src/block/Water.php | 4 ++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/block/Liquid.php b/src/block/Liquid.php index 677c3b0aef..6e3c8df359 100644 --- a/src/block/Liquid.php +++ b/src/block/Liquid.php @@ -249,6 +249,14 @@ abstract class Liquid extends Transparent{ return 1; } + /** + * Returns the number of source blocks of this liquid that must be horizontally adjacent to this block in order for + * this block to become a source block itself, or null if the liquid does not exhibit source-forming behaviour. + */ + public function getMinAdjacentSourcesToFormSource() : ?int{ + return null; + } + public function onNearbyBlockChange() : void{ if(!$this->checkForHarden()){ $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, $this->tickRate()); @@ -279,9 +287,10 @@ abstract class Liquid extends Transparent{ $falling = true; } - if($this->adjacentSources >= 2 and $this instanceof Water){ + $minAdjacentSources = $this->getMinAdjacentSourcesToFormSource(); + if($minAdjacentSources !== null && $this->adjacentSources >= $minAdjacentSources){ $bottomBlock = $world->getBlockAt($this->position->x, $this->position->y - 1, $this->position->z); - if($bottomBlock->isSolid() or ($bottomBlock instanceof Water and $bottomBlock->isSource())){ + if($bottomBlock->isSolid() or ($bottomBlock instanceof Liquid and $bottomBlock->isSameType($this) and $bottomBlock->isSource())){ $newDecay = 0; $falling = false; } diff --git a/src/block/Water.php b/src/block/Water.php index a516d40647..ff638a8f9f 100644 --- a/src/block/Water.php +++ b/src/block/Water.php @@ -46,6 +46,10 @@ class Water extends Liquid{ return 5; } + public function getMinAdjacentSourcesToFormSource() : ?int{ + return 2; + } + public function onEntityInside(Entity $entity) : bool{ $entity->resetFallDistance(); if($entity->isOnFire()){ From 52b6952771eb58abcbd8ea910df91753e9027169 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 19 Sep 2021 22:55:48 +0100 Subject: [PATCH 2865/3224] changelog: baseline for 4.0.0-BETA3 [ci skip] --- changelogs/4.0.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index 59f2151dbe..a817eb0ff5 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1304,3 +1304,21 @@ Released 10th September 2021. - `SubChunk::EDGE_LENGTH` - `SubChunk::COORD_BIT_SIZE` - `SubChunk::COORD_MASK` + +# 4.0.0-BETA3 + + +## General +- `tools/convert-world.php` now writes errors to stderr and sets the proper exit code. +- Explosions now use the standard mechanism for processing block updates. Previously, it used a special mechanism due to prohibitively poor efficiency of the standard algorithm. Since these inefficiencies have now been addressed, explosions can now be consistent with everything else, with minimal performance impact. +- Command usage strings are no longer automatically translated (use `Translatable` instead of bare string keys). +- Command description strings are no longer automatically translated (use `Translatable` instead of bare string keys). +## Fixes +- `ItemFactory->isRegistered()` no longer crashes when given negative item IDs. +- Furnaces now continue to operate after reloading the chunk they were contained in. + +## API changes +- The following API methods have been added: + - `Liquid->getMinAdjacentSourcesToFormSource()`: returns how many adjacent source blocks of the same liquid must be present in order for the current block to become a source itself + - `Player->getPlayerInfo()` +- `Liquid` minimum-cost flow calculation code has been extracted to `MinimumCostFlowCalculator`. From 133398c69ace5e916386ea8d5689c4f84086b077 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 19 Sep 2021 22:57:22 +0100 Subject: [PATCH 2866/3224] changelog: add newline [ci skip] --- changelogs/4.0.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index a817eb0ff5..091c4555e2 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1313,6 +1313,7 @@ Released 10th September 2021. - Explosions now use the standard mechanism for processing block updates. Previously, it used a special mechanism due to prohibitively poor efficiency of the standard algorithm. Since these inefficiencies have now been addressed, explosions can now be consistent with everything else, with minimal performance impact. - Command usage strings are no longer automatically translated (use `Translatable` instead of bare string keys). - Command description strings are no longer automatically translated (use `Translatable` instead of bare string keys). + ## Fixes - `ItemFactory->isRegistered()` no longer crashes when given negative item IDs. - Furnaces now continue to operate after reloading the chunk they were contained in. From 3813caf5ecd7836b95330834c88039678a814ee4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 22 Sep 2021 00:36:21 +0100 Subject: [PATCH 2867/3224] Updated BedrockProtocol and BedrockData for 1.17.30 --- composer.json | 2 +- composer.lock | 16 ++++++++-------- resources/vanilla | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/composer.json b/composer.json index ae2cf4a1d3..c8d46530ac 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "adhocore/json-comment": "^1.1", "fgrosse/phpasn1": "^2.3", "netresearch/jsonmapper": "^4.0", - "pocketmine/bedrock-protocol": "1.1.0+bedrock1.17.10", + "pocketmine/bedrock-protocol": "2.0.0+bedrock1.17.30", "pocketmine/binaryutils": "^0.2.1", "pocketmine/callback-validator": "^1.0.2", "pocketmine/classloader": "dev-master", diff --git a/composer.lock b/composer.lock index 7fa6959166..32cd742aca 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b0ec4c919d9322989980754f328c5e36", + "content-hash": "b21a1c4f07a3cccadb5f0fbe01ecf633", "packages": [ { "name": "adhocore/json-comment", @@ -245,16 +245,16 @@ }, { "name": "pocketmine/bedrock-protocol", - "version": "1.1.0+bedrock1.17.10", + "version": "2.0.0+bedrock1.17.30", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "9250ef96eba59c78c6aec91f154c63aebae118c5" + "reference": "faff7da904e68f69b1a9128956dac3122e87308a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/9250ef96eba59c78c6aec91f154c63aebae118c5", - "reference": "9250ef96eba59c78c6aec91f154c63aebae118c5", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/faff7da904e68f69b1a9128956dac3122e87308a", + "reference": "faff7da904e68f69b1a9128956dac3122e87308a", "shasum": "" }, "require": { @@ -268,7 +268,7 @@ "ramsey/uuid": "^4.1" }, "require-dev": { - "phpstan/phpstan": "0.12.96", + "phpstan/phpstan": "0.12.99", "phpstan/phpstan-phpunit": "^0.12.21", "phpstan/phpstan-strict-rules": "^0.12.10", "phpunit/phpunit": "^9.5" @@ -286,9 +286,9 @@ "description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP", "support": { "issues": "https://github.com/pmmp/BedrockProtocol/issues", - "source": "https://github.com/pmmp/BedrockProtocol/tree/1.1.0+bedrock1.17.10" + "source": "https://github.com/pmmp/BedrockProtocol/tree/bedrock-1.17.30" }, - "time": "2021-09-15T21:19:15+00:00" + "time": "2021-09-21T23:25:51+00:00" }, { "name": "pocketmine/binaryutils", diff --git a/resources/vanilla b/resources/vanilla index 21ec07f14e..19569dd729 160000 --- a/resources/vanilla +++ b/resources/vanilla @@ -1 +1 @@ -Subproject commit 21ec07f14e258d10475a714d77cbdcb7284745ec +Subproject commit 19569dd729970e161a24b574b41c06a5e064ab81 From 36b8217e68a3ce3eecb1ef5240f5b39786dbb7be Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 22 Sep 2021 23:05:24 +0100 Subject: [PATCH 2868/3224] Updated to RakLib 0.14.0 --- composer.json | 2 +- composer.lock | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/composer.json b/composer.json index c8d46530ac..12ff5f3930 100644 --- a/composer.json +++ b/composer.json @@ -44,7 +44,7 @@ "pocketmine/log-pthreads": "^0.2.0", "pocketmine/math": "^0.3.0", "pocketmine/nbt": "^0.3.0", - "pocketmine/raklib": "^0.13.1", + "pocketmine/raklib": "^0.14.0", "pocketmine/raklib-ipc": "^0.1.0", "pocketmine/snooze": "^0.3.0", "pocketmine/spl": "dev-master", diff --git a/composer.lock b/composer.lock index 32cd742aca..667f2f983f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b21a1c4f07a3cccadb5f0fbe01ecf633", + "content-hash": "bd5d7fc81a75739bfd2ef04b38220b84", "packages": [ { "name": "adhocore/json-comment", @@ -671,28 +671,28 @@ }, { "name": "pocketmine/raklib", - "version": "0.13.1", + "version": "0.14.0", "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "0b2b84f894adebe6a746237f9cc36d80cc4227ab" + "reference": "ed27bfd83f4de5ff32f71ec7611a66c4857a82ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/0b2b84f894adebe6a746237f9cc36d80cc4227ab", - "reference": "0b2b84f894adebe6a746237f9cc36d80cc4227ab", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/ed27bfd83f4de5ff32f71ec7611a66c4857a82ce", + "reference": "ed27bfd83f4de5ff32f71ec7611a66c4857a82ce", "shasum": "" }, "require": { "ext-sockets": "*", - "php": "^7.4 || ^8.0", + "php": "^8.0", "php-64bit": "*", "php-ipv6": "*", "pocketmine/binaryutils": "^0.2.0", - "pocketmine/log": "^0.3.0" + "pocketmine/log": "^0.3.0 || ^0.4.0" }, "require-dev": { - "phpstan/phpstan": "0.12.88", + "phpstan/phpstan": "0.12.99", "phpstan/phpstan-strict-rules": "^0.12.2" }, "type": "library", @@ -708,29 +708,29 @@ "description": "A RakNet server implementation written in PHP", "support": { "issues": "https://github.com/pmmp/RakLib/issues", - "source": "https://github.com/pmmp/RakLib/tree/0.13.1" + "source": "https://github.com/pmmp/RakLib/tree/0.14.0" }, - "time": "2021-05-18T21:14:20+00:00" + "time": "2021-09-20T21:53:31+00:00" }, { "name": "pocketmine/raklib-ipc", - "version": "0.1.0", + "version": "0.1.1", "source": { "type": "git", "url": "https://github.com/pmmp/RakLibIpc.git", - "reference": "85f1a4834e34abd6d77f622f14731e8ef06dc7cf" + "reference": "922a6444b0c6c7daaa5aa5a832107e1ec4738aed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLibIpc/zipball/85f1a4834e34abd6d77f622f14731e8ef06dc7cf", - "reference": "85f1a4834e34abd6d77f622f14731e8ef06dc7cf", + "url": "https://api.github.com/repos/pmmp/RakLibIpc/zipball/922a6444b0c6c7daaa5aa5a832107e1ec4738aed", + "reference": "922a6444b0c6c7daaa5aa5a832107e1ec4738aed", "shasum": "" }, "require": { "php": "^7.4 || ^8.0", "php-64bit": "*", "pocketmine/binaryutils": "^0.2.0", - "pocketmine/raklib": "^0.13.1" + "pocketmine/raklib": "^0.13.1 || ^0.14.0" }, "require-dev": { "phpstan/phpstan": "0.12.81", @@ -749,9 +749,9 @@ "description": "Channel-based protocols for inter-thread/inter-process communication with RakLib", "support": { "issues": "https://github.com/pmmp/RakLibIpc/issues", - "source": "https://github.com/pmmp/RakLibIpc/tree/0.1.0" + "source": "https://github.com/pmmp/RakLibIpc/tree/0.1.1" }, - "time": "2021-05-18T21:19:03+00:00" + "time": "2021-09-22T17:01:12+00:00" }, { "name": "pocketmine/snooze", From 5f1e66478b22ce1a2ba4414e4089375e29c8f2dd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 22 Sep 2021 23:12:56 +0100 Subject: [PATCH 2869/3224] changelog: mention UPnP API changes --- changelogs/4.0.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index 091c4555e2..6534ab8213 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -780,6 +780,12 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `mcpe\RakLibInterface` -> `mcpe\raklib\RakLibInterface` - The following classes have been removed: - `mcpe\PlayerNetworkSessionAdapter` +- The following methods have been renamed: + - `UPnP::PortForward()` -> `UPnP::portForward()` + - `UPnP::RemovePortForward()` -> `UPnP::removePortForward()` +- The following methods have changed signatures: + - `UPnP::portForward()` now accepts `string $serviceURL, string $internalIP, int $internalPort, int $externalPort`. + - `UPnP::removePortForward()` now accepts `string $serviceURL, int $externalPort`. - The following methods have been removed: - `NetworkInterface->putPacket()` - `NetworkInterface->close()` From 9bc07a9cc0ed1b653d961846a059049319c918d1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 23 Sep 2021 21:51:23 +0100 Subject: [PATCH 2870/3224] Release 4.0.0-BETA3 --- changelogs/4.0.md | 3 +++ src/VersionInfo.php | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index 6534ab8213..6445506572 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1315,6 +1315,8 @@ Released 10th September 2021. ## General +- Added support for Minecraft: Bedrock Edition 1.17.30. +- Dropped support for Minecraft: Bedrock Edition 1.17.1x. - `tools/convert-world.php` now writes errors to stderr and sets the proper exit code. - Explosions now use the standard mechanism for processing block updates. Previously, it used a special mechanism due to prohibitively poor efficiency of the standard algorithm. Since these inefficiencies have now been addressed, explosions can now be consistent with everything else, with minimal performance impact. - Command usage strings are no longer automatically translated (use `Translatable` instead of bare string keys). @@ -1323,6 +1325,7 @@ Released 10th September 2021. ## Fixes - `ItemFactory->isRegistered()` no longer crashes when given negative item IDs. - Furnaces now continue to operate after reloading the chunk they were contained in. +- Fixed being unable to reconnect for 10 seconds after disconnecting in some cases. ## API changes - The following API methods have been added: diff --git a/src/VersionInfo.php b/src/VersionInfo.php index f049a991ec..e8444c0204 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -30,9 +30,9 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; public const BASE_VERSION = "4.0.0-BETA3"; - public const IS_DEVELOPMENT_BUILD = true; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_NUMBER = 0; - public const BUILD_CHANNEL = ""; + public const BUILD_CHANNEL = "beta"; private function __construct(){ //NOOP From 1cb540387c4ca2aa31db688e3aef978d622c10bc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 23 Sep 2021 21:51:36 +0100 Subject: [PATCH 2871/3224] 4.0.0-BETA4 is next --- src/VersionInfo.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index e8444c0204..dedf0f3ae5 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -29,10 +29,10 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "4.0.0-BETA3"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "4.0.0-BETA4"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_NUMBER = 0; - public const BUILD_CHANNEL = "beta"; + public const BUILD_CHANNEL = ""; private function __construct(){ //NOOP From eb80515e992467ca6a3361a1d2c4cf0498915055 Mon Sep 17 00:00:00 2001 From: Leo Lee Date: Fri, 24 Sep 2021 22:47:11 +0800 Subject: [PATCH 2872/3224] Fixed incorrect parameter checking in BlockFactory::get() (#4476) --- src/block/BlockFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 94414da460..ee2345f82f 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -952,7 +952,7 @@ class BlockFactory{ * Deserializes a block from the provided legacy ID and legacy meta. */ public function get(int $id, int $meta) : Block{ - if($meta < 0 or $meta > (1 << Block::INTERNAL_METADATA_BITS)){ + if($meta < 0 or $meta >= (1 << Block::INTERNAL_METADATA_BITS)){ throw new \InvalidArgumentException("Block meta value $meta is out of bounds"); } From 8e2d06a88051293a412bd298f759b10ccd3acca8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 25 Sep 2021 01:16:59 +0100 Subject: [PATCH 2873/3224] ChunkSerializer: support writing 0 bpb palettes on the wire these are now supported as of 1.17.30. --- .../mcpe/serializer/ChunkSerializer.php | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index 9565598868..fe8253e4cb 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -32,10 +32,8 @@ use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\utils\Binary; use pocketmine\utils\BinaryStream; use pocketmine\world\format\Chunk; -use pocketmine\world\format\PalettedBlockArray; use pocketmine\world\format\SubChunk; use function count; -use function str_repeat; final class ChunkSerializer{ @@ -83,23 +81,18 @@ final class ChunkSerializer{ $stream->putByte(count($layers)); foreach($layers as $blocks){ - if($blocks->getBitsPerBlock() === 0){ - //TODO: we use these in memory, but the game doesn't support them yet - //polyfill them with 1-bpb instead - $bitsPerBlock = 1; - $words = str_repeat("\x00", PalettedBlockArray::getExpectedWordArraySize(1)); - }else{ - $bitsPerBlock = $blocks->getBitsPerBlock(); - $words = $blocks->getWordArray(); - } + $bitsPerBlock = $blocks->getBitsPerBlock(); + $words = $blocks->getWordArray(); $stream->putByte(($bitsPerBlock << 1) | ($persistentBlockStates ? 0 : 1)); $stream->put($words); $palette = $blocks->getPalette(); - //these LSHIFT by 1 uvarints are optimizations: the client expects zigzag varints here - //but since we know they are always unsigned, we can avoid the extra fcall overhead of - //zigzag and just shift directly. - $stream->putUnsignedVarInt(count($palette) << 1); //yes, this is intentionally zigzag + if($bitsPerBlock !== 0){ + //these LSHIFT by 1 uvarints are optimizations: the client expects zigzag varints here + //but since we know they are always unsigned, we can avoid the extra fcall overhead of + //zigzag and just shift directly. + $stream->putUnsignedVarInt(count($palette) << 1); //yes, this is intentionally zigzag + } if($persistentBlockStates){ $nbtSerializer = new NetworkNbtSerializer(); foreach($palette as $p){ From f138004913de1b2a3523f3d01365c34ea5d4a3d7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 26 Sep 2021 21:20:42 +0100 Subject: [PATCH 2874/3224] PlayerDeathEvent: fixed property type variance issue PHPStan complains about --- src/event/player/PlayerDeathEvent.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/event/player/PlayerDeathEvent.php b/src/event/player/PlayerDeathEvent.php index 8b018c1a1f..6c44d38197 100644 --- a/src/event/player/PlayerDeathEvent.php +++ b/src/event/player/PlayerDeathEvent.php @@ -36,7 +36,7 @@ use pocketmine\player\Player; class PlayerDeathEvent extends EntityDeathEvent{ /** @var Player */ - protected $entity; + protected $player; /** @var Translatable|string */ private $deathMessage; @@ -49,6 +49,7 @@ class PlayerDeathEvent extends EntityDeathEvent{ */ public function __construct(Player $entity, array $drops, int $xp, Translatable|string|null $deathMessage){ parent::__construct($entity, $drops, $xp); + $this->player = $entity; $this->deathMessage = $deathMessage ?? self::deriveMessage($entity->getDisplayName(), $entity->getLastDamageCause()); } @@ -56,11 +57,11 @@ class PlayerDeathEvent extends EntityDeathEvent{ * @return Player */ public function getEntity(){ - return $this->entity; + return $this->player; } public function getPlayer() : Player{ - return $this->entity; + return $this->player; } public function getDeathMessage() : Translatable|string{ From b3e8314b9f6385a7ed4f9e8b0dd3f4d16fe73d03 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 26 Sep 2021 21:41:24 +0100 Subject: [PATCH 2875/3224] PTHREADS_INHERIT_CONSTANTS is no longer needed for MainLogger to log exceptions cleaned paths are now referenced from Filesystem instead of namespace constants. --- src/network/mcpe/raklib/RakLibInterface.php | 3 +-- src/scheduler/AsyncPool.php | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 9a5b38ceb2..9653a0d4e8 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -51,7 +51,6 @@ use function mt_rand; use function random_bytes; use function rtrim; use function substr; -use const PTHREADS_INHERIT_CONSTANTS; class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ /** @@ -122,7 +121,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ while($this->eventReceiver->handle($this)); }); $this->server->getLogger()->debug("Waiting for RakLib to start..."); - $this->rakLib->startAndWait(PTHREADS_INHERIT_CONSTANTS); //HACK: MainLogger needs constants for exception logging + $this->rakLib->startAndWait(); $this->server->getLogger()->debug("RakLib booted successfully"); } diff --git a/src/scheduler/AsyncPool.php b/src/scheduler/AsyncPool.php index 707a6e3f33..047488ee31 100644 --- a/src/scheduler/AsyncPool.php +++ b/src/scheduler/AsyncPool.php @@ -33,7 +33,6 @@ use function count; use function spl_object_id; use function time; use const PHP_INT_MAX; -use const PTHREADS_INHERIT_CONSTANTS; use const PTHREADS_INHERIT_INI; /** @@ -41,7 +40,7 @@ use const PTHREADS_INHERIT_INI; * workers. */ class AsyncPool{ - private const WORKER_START_OPTIONS = PTHREADS_INHERIT_INI | PTHREADS_INHERIT_CONSTANTS; + private const WORKER_START_OPTIONS = PTHREADS_INHERIT_INI; /** @var \ClassLoader */ private $classLoader; From c931c526179761fedc9508a4e971c54b75fc0491 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 27 Sep 2021 13:53:30 +0100 Subject: [PATCH 2876/3224] AsyncTask: added newline --- src/scheduler/AsyncTask.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/scheduler/AsyncTask.php b/src/scheduler/AsyncTask.php index 8440eb3e91..2f1bedc6b5 100644 --- a/src/scheduler/AsyncTask.php +++ b/src/scheduler/AsyncTask.php @@ -129,6 +129,7 @@ abstract class AsyncTask extends \Threaded{ public function cancelRun() : void{ $this->cancelRun = true; } + public function hasCancelledRun() : bool{ return $this->cancelRun; } From 6a8280b1ba3c19816ca8138e65ee466468abc151 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 29 Sep 2021 00:20:57 +0100 Subject: [PATCH 2877/3224] Lever: add block property APIs --- src/block/Lever.php | 108 +++++++++++++++++++------------- src/block/utils/LeverFacing.php | 67 ++++++++++++++++++++ 2 files changed, 131 insertions(+), 44 deletions(-) create mode 100644 src/block/utils/LeverFacing.php diff --git a/src/block/Lever.php b/src/block/Lever.php index e32920f70e..905ee87561 100644 --- a/src/block/Lever.php +++ b/src/block/Lever.php @@ -23,50 +23,72 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\block\utils\BlockDataSerializer; +use pocketmine\block\utils\LeverFacing; use pocketmine\item\Item; use pocketmine\math\Axis; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; +use pocketmine\utils\AssumptionFailedError; use pocketmine\world\BlockTransaction; use pocketmine\world\sound\RedstonePowerOffSound; use pocketmine\world\sound\RedstonePowerOnSound; class Lever extends Flowable{ - protected const BOTTOM = 0; - protected const SIDE = 1; - protected const TOP = 2; + protected LeverFacing $facing; + protected bool $activated = false; - protected int $leverPos = self::BOTTOM; - protected int $facing = Facing::NORTH; - protected bool $powered = false; + public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){ + $this->facing = LeverFacing::UP_AXIS_X(); + parent::__construct($idInfo, $name, $breakInfo); + } protected function writeStateToMeta() : int{ - if($this->leverPos === self::BOTTOM){ - $rotationMeta = Facing::axis($this->facing) === Axis::Z ? 7 : 0; - }elseif($this->leverPos === self::TOP){ - $rotationMeta = Facing::axis($this->facing) === Axis::Z ? 5 : 6; - }else{ - $rotationMeta = 6 - BlockDataSerializer::writeHorizontalFacing($this->facing); - } - return $rotationMeta | ($this->powered ? BlockLegacyMetadata::LEVER_FLAG_POWERED : 0); + $rotationMeta = match($this->facing->id()){ + LeverFacing::DOWN_AXIS_X()->id() => 0, + LeverFacing::EAST()->id() => 1, + LeverFacing::WEST()->id() => 2, + LeverFacing::SOUTH()->id() => 3, + LeverFacing::NORTH()->id() => 4, + LeverFacing::UP_AXIS_Z()->id() => 5, + LeverFacing::UP_AXIS_X()->id() => 6, + LeverFacing::DOWN_AXIS_Z()->id() => 7, + default => throw new AssumptionFailedError(), + }; + return $rotationMeta | ($this->activated ? BlockLegacyMetadata::LEVER_FLAG_POWERED : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ $rotationMeta = $stateMeta & 0x07; - if($rotationMeta === 5 or $rotationMeta === 6){ - $this->leverPos = self::TOP; - $this->facing = $rotationMeta === 5 ? Facing::SOUTH : Facing::EAST; - }elseif($rotationMeta === 7 or $rotationMeta === 0){ - $this->leverPos = self::BOTTOM; - $this->facing = $rotationMeta === 7 ? Facing::SOUTH : Facing::EAST; - }else{ - $this->leverPos = self::SIDE; - $this->facing = BlockDataSerializer::readHorizontalFacing(6 - $rotationMeta); - } + $this->facing = match($rotationMeta){ + 0 => LeverFacing::DOWN_AXIS_X(), + 1 => LeverFacing::EAST(), + 2 => LeverFacing::WEST(), + 3 => LeverFacing::SOUTH(), + 4 => LeverFacing::NORTH(), + 5 => LeverFacing::UP_AXIS_Z(), + 6 => LeverFacing::UP_AXIS_X(), + 7 => LeverFacing::DOWN_AXIS_Z(), + default => throw new AssumptionFailedError("0x07 mask should make this impossible"), //phpstan doesn't understand :( + }; - $this->powered = ($stateMeta & BlockLegacyMetadata::LEVER_FLAG_POWERED) !== 0; + $this->activated = ($stateMeta & BlockLegacyMetadata::LEVER_FLAG_POWERED) !== 0; + } + + public function getFacing() : LeverFacing{ return $this->facing; } + + /** @return $this */ + public function setFacing(LeverFacing $facing) : self{ + $this->facing = $facing; + return $this; + } + + public function isActivated() : bool{ return $this->activated; } + + /** @return $this */ + public function setActivated(bool $activated) : self{ + $this->activated = $activated; + return $this; } public function getStateBitmask() : int{ @@ -78,39 +100,37 @@ class Lever extends Flowable{ return false; } - if(Facing::axis($face) === Axis::Y){ + $selectUpDownPos = function(LeverFacing $x, LeverFacing $z) use ($player) : LeverFacing{ if($player !== null){ - $this->facing = Facing::opposite($player->getHorizontalFacing()); + return Facing::axis($player->getHorizontalFacing()) === Axis::X ? $x : $z; } - $this->leverPos = $face === Facing::DOWN ? self::BOTTOM : self::TOP; - }else{ - $this->facing = $face; - $this->leverPos = self::SIDE; - } + return $x; + }; + $this->facing = match($face){ + Facing::DOWN => $selectUpDownPos(LeverFacing::DOWN_AXIS_X(), LeverFacing::DOWN_AXIS_Z()), + Facing::UP => $selectUpDownPos(LeverFacing::UP_AXIS_X(), LeverFacing::UP_AXIS_Z()), + Facing::NORTH => LeverFacing::NORTH(), + Facing::SOUTH => LeverFacing::SOUTH(), + Facing::WEST => LeverFacing::WEST(), + Facing::EAST => LeverFacing::EAST(), + default => throw new AssumptionFailedError("Bad facing value"), + }; return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onNearbyBlockChange() : void{ - if($this->leverPos === self::BOTTOM){ - $face = Facing::UP; - }elseif($this->leverPos === self::TOP){ - $face = Facing::DOWN; - }else{ - $face = Facing::opposite($this->facing); - } - - if(!$this->getSide($face)->isSolid()){ + if(!$this->getSide(Facing::opposite($this->facing->getFacing()))->isSolid()){ $this->position->getWorld()->useBreakOn($this->position); } } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - $this->powered = !$this->powered; + $this->activated = !$this->activated; $this->position->getWorld()->setBlock($this->position, $this); $this->position->getWorld()->addSound( $this->position->add(0.5, 0.5, 0.5), - $this->powered ? new RedstonePowerOnSound() : new RedstonePowerOffSound() + $this->activated ? new RedstonePowerOnSound() : new RedstonePowerOffSound() ); return true; } diff --git a/src/block/utils/LeverFacing.php b/src/block/utils/LeverFacing.php new file mode 100644 index 0000000000..fbc83c880c --- /dev/null +++ b/src/block/utils/LeverFacing.php @@ -0,0 +1,67 @@ +Enum___construct($enumName); + } + + public function getFacing() : int{ return $this->facing; } +} From afa3349c04822e07705ff6908e0a6a583f6b513e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Oct 2021 21:09:53 +0100 Subject: [PATCH 2878/3224] Acknowledge the presence of capabilities field in resource pack manifest closes #4485 --- src/resourcepacks/json/Manifest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/resourcepacks/json/Manifest.php b/src/resourcepacks/json/Manifest.php index 31c68973eb..dad99a8615 100644 --- a/src/resourcepacks/json/Manifest.php +++ b/src/resourcepacks/json/Manifest.php @@ -40,4 +40,7 @@ final class Manifest{ public array $modules; public ?ManifestMetadata $metadata = null; + + /** @var string[] */ + public ?array $capabilities = null; } From 349f37b15fccfa1efca17272328580fad0d632d8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Oct 2021 21:14:28 +0100 Subject: [PATCH 2879/3224] resource packs: manifest may also contain a list of dependencies ... which we should be verifying the presence of, as the server. --- src/resourcepacks/json/Manifest.php | 3 ++ .../json/ManifestDependencyEntry.php | 37 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 src/resourcepacks/json/ManifestDependencyEntry.php diff --git a/src/resourcepacks/json/Manifest.php b/src/resourcepacks/json/Manifest.php index dad99a8615..cd6f1c9139 100644 --- a/src/resourcepacks/json/Manifest.php +++ b/src/resourcepacks/json/Manifest.php @@ -43,4 +43,7 @@ final class Manifest{ /** @var string[] */ public ?array $capabilities = null; + + /** @var ManifestDependencyEntry[] */ + public ?array $dependencies = null; } diff --git a/src/resourcepacks/json/ManifestDependencyEntry.php b/src/resourcepacks/json/ManifestDependencyEntry.php new file mode 100644 index 0000000000..f7dd76abc6 --- /dev/null +++ b/src/resourcepacks/json/ManifestDependencyEntry.php @@ -0,0 +1,37 @@ + Date: Fri, 1 Oct 2021 21:39:26 +0100 Subject: [PATCH 2880/3224] RakLib 0.14.1 --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 667f2f983f..baa3a8c3e8 100644 --- a/composer.lock +++ b/composer.lock @@ -671,16 +671,16 @@ }, { "name": "pocketmine/raklib", - "version": "0.14.0", + "version": "0.14.1", "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "ed27bfd83f4de5ff32f71ec7611a66c4857a82ce" + "reference": "2d7bac3d593219880696ca2ca254f083f1e71850" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/ed27bfd83f4de5ff32f71ec7611a66c4857a82ce", - "reference": "ed27bfd83f4de5ff32f71ec7611a66c4857a82ce", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/2d7bac3d593219880696ca2ca254f083f1e71850", + "reference": "2d7bac3d593219880696ca2ca254f083f1e71850", "shasum": "" }, "require": { @@ -708,9 +708,9 @@ "description": "A RakNet server implementation written in PHP", "support": { "issues": "https://github.com/pmmp/RakLib/issues", - "source": "https://github.com/pmmp/RakLib/tree/0.14.0" + "source": "https://github.com/pmmp/RakLib/tree/0.14.1" }, - "time": "2021-09-20T21:53:31+00:00" + "time": "2021-10-01T20:35:44+00:00" }, { "name": "pocketmine/raklib-ipc", From aee4a00a5030cce602ec20702495284f7319050f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Oct 2021 21:40:31 +0100 Subject: [PATCH 2881/3224] Updated dependencies --- composer.lock | 301 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 235 insertions(+), 66 deletions(-) diff --git a/composer.lock b/composer.lock index baa3a8c3e8..d79f124286 100644 --- a/composer.lock +++ b/composer.lock @@ -63,16 +63,16 @@ }, { "name": "brick/math", - "version": "0.9.2", + "version": "0.9.3", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "dff976c2f3487d42c1db75a3b180e2b9f0e72ce0" + "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/dff976c2f3487d42c1db75a3b180e2b9f0e72ce0", - "reference": "dff976c2f3487d42c1db75a3b180e2b9f0e72ce0", + "url": "https://api.github.com/repos/brick/math/zipball/ca57d18f028f84f777b2168cd1911b0dee2343ae", + "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae", "shasum": "" }, "require": { @@ -82,7 +82,7 @@ "require-dev": { "php-coveralls/php-coveralls": "^2.2", "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0", - "vimeo/psalm": "4.3.2" + "vimeo/psalm": "4.9.2" }, "type": "library", "autoload": { @@ -107,15 +107,19 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.9.2" + "source": "https://github.com/brick/math/tree/0.9.3" }, "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/brick/math", "type": "tidelift" } ], - "time": "2021-01-20T22:51:39+00:00" + "time": "2021-08-15T20:50:18+00:00" }, { "name": "fgrosse/phpasn1", @@ -832,20 +836,21 @@ }, { "name": "ramsey/collection", - "version": "1.1.3", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/ramsey/collection.git", - "reference": "28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1" + "reference": "eaca1dc1054ddd10cbd83c1461907bee6fb528fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1", - "reference": "28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1", + "url": "https://api.github.com/repos/ramsey/collection/zipball/eaca1dc1054ddd10cbd83c1461907bee6fb528fa", + "reference": "eaca1dc1054ddd10cbd83c1461907bee6fb528fa", "shasum": "" }, "require": { - "php": "^7.2 || ^8" + "php": "^7.3 || ^8", + "symfony/polyfill-php81": "^1.23" }, "require-dev": { "captainhook/captainhook": "^5.3", @@ -855,6 +860,7 @@ "hamcrest/hamcrest-php": "^2", "jangregor/phpstan-prophecy": "^0.8", "mockery/mockery": "^1.3", + "phpspec/prophecy-phpunit": "^2.0", "phpstan/extension-installer": "^1", "phpstan/phpstan": "^0.12.32", "phpstan/phpstan-mockery": "^0.12.5", @@ -882,7 +888,7 @@ "homepage": "https://benramsey.com" } ], - "description": "A PHP 7.2+ library for representing and manipulating collections.", + "description": "A PHP library for representing and manipulating collections.", "keywords": [ "array", "collection", @@ -893,7 +899,7 @@ ], "support": { "issues": "https://github.com/ramsey/collection/issues", - "source": "https://github.com/ramsey/collection/tree/1.1.3" + "source": "https://github.com/ramsey/collection/tree/1.2.1" }, "funding": [ { @@ -905,28 +911,29 @@ "type": "tidelift" } ], - "time": "2021-01-21T17:40:04+00:00" + "time": "2021-08-06T03:41:06+00:00" }, { "name": "ramsey/uuid", - "version": "4.2.1", + "version": "4.2.3", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "fe665a03df4f056aa65af552a96e1976df8c8dae" + "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/fe665a03df4f056aa65af552a96e1976df8c8dae", - "reference": "fe665a03df4f056aa65af552a96e1976df8c8dae", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", + "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", "shasum": "" }, "require": { "brick/math": "^0.8 || ^0.9", "ext-json": "*", - "php": "^7.2 || ^8", + "php": "^7.2 || ^8.0", "ramsey/collection": "^1.0", - "symfony/polyfill-ctype": "^1.8" + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-php80": "^1.14" }, "replace": { "rhumsaa/uuid": "self.version" @@ -990,7 +997,7 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.2.1" + "source": "https://github.com/ramsey/uuid/tree/4.2.3" }, "funding": [ { @@ -1002,7 +1009,7 @@ "type": "tidelift" } ], - "time": "2021-08-11T01:06:55+00:00" + "time": "2021-09-25T23:10:38+00:00" }, { "name": "respect/stringifier", @@ -1209,16 +1216,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.23.0", + "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "2df51500adbaebdc4c38dea4c89a2e131c45c8a1" + "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/2df51500adbaebdc4c38dea4c89a2e131c45c8a1", - "reference": "2df51500adbaebdc4c38dea4c89a2e131c45c8a1", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6", + "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6", "shasum": "" }, "require": { @@ -1269,7 +1276,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.1" }, "funding": [ { @@ -1285,7 +1292,169 @@ "type": "tidelift" } ], - "time": "2021-05-27T09:27:20+00:00" + "time": "2021-05-27T12:26:48+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.23.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be", + "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.23.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-07-28T13:41:28+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.23.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "e66119f3de95efc359483f810c4c3e6436279436" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/e66119f3de95efc359483f810c4c3e6436279436", + "reference": "e66119f3de95efc359483f810c4c3e6436279436", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.23.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-05-21T13:25:03+00:00" }, { "name": "webmozart/assert", @@ -1526,16 +1695,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.12.0", + "version": "v4.13.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "6608f01670c3cc5079e18c1dab1104e002579143" + "reference": "50953a2691a922aa1769461637869a0a2faa3f53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6608f01670c3cc5079e18c1dab1104e002579143", - "reference": "6608f01670c3cc5079e18c1dab1104e002579143", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/50953a2691a922aa1769461637869a0a2faa3f53", + "reference": "50953a2691a922aa1769461637869a0a2faa3f53", "shasum": "" }, "require": { @@ -1576,9 +1745,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.12.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.0" }, - "time": "2021-07-21T10:44:31+00:00" + "time": "2021-09-20T12:20:58+00:00" }, { "name": "phar-io/manifest", @@ -1802,16 +1971,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.4.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" + "reference": "30f38bffc6f24293dadd1823936372dfa9e86e2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", - "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/30f38bffc6f24293dadd1823936372dfa9e86e2f", + "reference": "30f38bffc6f24293dadd1823936372dfa9e86e2f", "shasum": "" }, "require": { @@ -1819,7 +1988,8 @@ "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { - "ext-tokenizer": "*" + "ext-tokenizer": "*", + "psalm/phar": "^4.8" }, "type": "library", "extra": { @@ -1845,39 +2015,39 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.0" }, - "time": "2020-09-17T18:55:26+00:00" + "time": "2021-09-17T15:28:14+00:00" }, { "name": "phpspec/prophecy", - "version": "1.13.0", + "version": "1.14.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea" + "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be1996ed8adc35c3fd795488a653f4b518be70ea", - "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", + "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", "shasum": "" }, "require": { "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.1", + "php": "^7.2 || ~8.0, <8.2", "phpdocumentor/reflection-docblock": "^5.2", "sebastian/comparator": "^3.0 || ^4.0", "sebastian/recursion-context": "^3.0 || ^4.0" }, "require-dev": { - "phpspec/phpspec": "^6.0", + "phpspec/phpspec": "^6.0 || ^7.0", "phpunit/phpunit": "^8.0 || ^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.11.x-dev" + "dev-master": "1.x-dev" } }, "autoload": { @@ -1912,9 +2082,9 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/1.13.0" + "source": "https://github.com/phpspec/prophecy/tree/1.14.0" }, - "time": "2021-03-17T13:42:18+00:00" + "time": "2021-09-10T09:02:12+00:00" }, { "name": "phpstan/phpstan", @@ -2086,23 +2256,23 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.6", + "version": "9.2.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "f6293e1b30a2354e8428e004689671b83871edde" + "reference": "d4c798ed8d51506800b441f7a13ecb0f76f12218" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f6293e1b30a2354e8428e004689671b83871edde", - "reference": "f6293e1b30a2354e8428e004689671b83871edde", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d4c798ed8d51506800b441f7a13ecb0f76f12218", + "reference": "d4c798ed8d51506800b441f7a13ecb0f76f12218", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.10.2", + "nikic/php-parser": "^4.12.0", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -2151,7 +2321,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.6" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.7" }, "funding": [ { @@ -2159,7 +2329,7 @@ "type": "github" } ], - "time": "2021-03-28T07:26:59+00:00" + "time": "2021-09-17T05:39:03+00:00" }, { "name": "phpunit/php-file-iterator", @@ -2404,16 +2574,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.9", + "version": "9.5.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "ea8c2dfb1065eb35a79b3681eee6e6fb0a6f273b" + "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ea8c2dfb1065eb35a79b3681eee6e6fb0a6f273b", - "reference": "ea8c2dfb1065eb35a79b3681eee6e6fb0a6f273b", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c814a05837f2edb0d1471d6e3f4ab3501ca3899a", + "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a", "shasum": "" }, "require": { @@ -2429,7 +2599,7 @@ "phar-io/version": "^3.0.2", "php": ">=7.3", "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.3", + "phpunit/php-code-coverage": "^9.2.7", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.3", @@ -2491,7 +2661,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.9" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.10" }, "funding": [ { @@ -2503,7 +2673,7 @@ "type": "github" } ], - "time": "2021-08-31T06:47:40+00:00" + "time": "2021-09-25T07:38:51+00:00" }, { "name": "sebastian/cli-parser", @@ -3358,7 +3528,6 @@ "type": "github" } ], - "abandoned": true, "time": "2020-09-28T06:45:17+00:00" }, { From 42bf9578ce4d0d3858a2a580b5362df0d3401224 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Oct 2021 22:05:03 +0100 Subject: [PATCH 2882/3224] Remove unused constants --- src/block/Bell.php | 2 -- src/world/format/io/FastChunkSerializer.php | 1 - 2 files changed, 3 deletions(-) diff --git a/src/block/Bell.php b/src/block/Bell.php index 1cffd606bc..2b33610b64 100644 --- a/src/block/Bell.php +++ b/src/block/Bell.php @@ -37,8 +37,6 @@ use pocketmine\world\BlockTransaction; use pocketmine\world\sound\BellRingSound; final class Bell extends Transparent{ - private const BELL_RINGING_REPEAT_TICKS = 20; - use HorizontalFacingTrait; private BellAttachmentType $attachmentType; diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index ca6d4ea50f..8dfaf76b06 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -41,7 +41,6 @@ use function unpack; * The serialization format **is not intended for permanent storage** and may change without warning. */ final class FastChunkSerializer{ - private const FLAG_GENERATED = 1 << 0; private const FLAG_POPULATED = 1 << 1; private const FLAG_HAS_LIGHT = 1 << 2; From 5b818827dbce69faa82b6426e24261118c28c580 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Oct 2021 22:17:28 +0100 Subject: [PATCH 2883/3224] Chunk: stop exposing SplFixedArray to the API this fixes a large number of PHPStan errors, and also brings us a step closer to negative-build-height readiness. --- .../mcpe/serializer/ChunkSerializer.php | 2 +- src/world/format/Chunk.php | 8 +-- src/world/format/io/FastChunkSerializer.php | 2 +- src/world/light/SkyLightUpdate.php | 5 +- .../configs/spl-fixed-array-sucks.neon | 70 ++----------------- 5 files changed, 14 insertions(+), 73 deletions(-) diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index fe8253e4cb..6fe392b670 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -46,7 +46,7 @@ final class ChunkSerializer{ * Chunks are sent in a stack, so every chunk below the top non-empty one must be sent. */ public static function getSubChunkCount(Chunk $chunk) : int{ - for($count = $chunk->getSubChunks()->count(); $count > 0; --$count){ + for($count = count($chunk->getSubChunks()); $count > 0; --$count){ if($chunk->getSubChunk($count - 1)->isEmptyFast()){ continue; } diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 3691b4dbd4..c90c18482f 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -299,11 +299,11 @@ class Chunk{ } /** - * @return \SplFixedArray|SubChunk[] - * @phpstan-return \SplFixedArray + * @return SubChunk[] + * @phpstan-return array */ - public function getSubChunks() : \SplFixedArray{ - return $this->subChunks; + public function getSubChunks() : array{ + return $this->subChunks->toArray(); } /** diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index 8dfaf76b06..4e65c414f2 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -67,7 +67,7 @@ final class FastChunkSerializer{ //subchunks $subChunks = $chunk->getSubChunks(); - $count = $subChunks->count(); + $count = count($subChunks); $stream->putByte($count); foreach($subChunks as $y => $subChunk){ diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index e9507c153e..42d12be17d 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -30,6 +30,7 @@ use pocketmine\world\format\SubChunk; use pocketmine\world\utils\SubChunkExplorer; use pocketmine\world\utils\SubChunkExplorerStatus; use pocketmine\world\World; +use function count; use function max; class SkyLightUpdate extends LightUpdate{ @@ -114,7 +115,7 @@ class SkyLightUpdate extends LightUpdate{ //have to avoid filling full light for any subchunk that contains a heightmap Y coordinate $highestHeightMapPlusOne = max($chunk->getHeightMapArray()) + 1; $lowestClearSubChunk = ($highestHeightMapPlusOne >> SubChunk::COORD_BIT_SIZE) + (($highestHeightMapPlusOne & SubChunk::COORD_MASK) !== 0 ? 1 : 0); - $chunkHeight = $chunk->getSubChunks()->count(); + $chunkHeight = count($chunk->getSubChunks()); for($y = 0; $y < $lowestClearSubChunk && $y < $chunkHeight; $y++){ $chunk->getSubChunk($y)->setBlockSkyLightArray(LightArray::fill(0)); } @@ -173,7 +174,7 @@ class SkyLightUpdate extends LightUpdate{ * @phpstan-param \SplFixedArray $directSkyLightBlockers */ private static function recalculateHeightMap(Chunk $chunk, \SplFixedArray $directSkyLightBlockers) : HeightArray{ - $maxSubChunkY = $chunk->getSubChunks()->count() - 1; + $maxSubChunkY = count($chunk->getSubChunks()) - 1; for(; $maxSubChunkY >= 0; $maxSubChunkY--){ if(!$chunk->getSubChunk($maxSubChunkY)->isEmptyFast()){ break; diff --git a/tests/phpstan/configs/spl-fixed-array-sucks.neon b/tests/phpstan/configs/spl-fixed-array-sucks.neon index f984dc5554..d69e0a6e41 100644 --- a/tests/phpstan/configs/spl-fixed-array-sucks.neon +++ b/tests/phpstan/configs/spl-fixed-array-sucks.neon @@ -1,77 +1,17 @@ parameters: ignoreErrors: - - - message: "#^Cannot call method getFullBlock\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" - count: 1 - path: ../../../src/world/World.php - - - - message: "#^Cannot call method isEmptyFast\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" - count: 1 - path: ../../../src/world/World.php - - message: "#^Cannot call method collectGarbage\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" count: 1 path: ../../../src/world/format/Chunk.php + - + message: "#^Method pocketmine\\\\world\\\\format\\\\Chunk\\:\\:getSubChunks\\(\\) should return array\\ but returns array\\\\.$#" + count: 1 + path: ../../../src/world/format/Chunk.php + - message: "#^Method pocketmine\\\\world\\\\format\\\\HeightArray\\:\\:getValues\\(\\) should return array\\ but returns array\\\\.$#" count: 1 path: ../../../src/world/format/HeightArray.php - - - message: "#^Cannot call method getBlockLayers\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" - count: 1 - path: ../../../src/world/format/io/FastChunkSerializer.php - - - - message: "#^Cannot call method getBlockLightArray\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" - count: 1 - path: ../../../src/world/format/io/FastChunkSerializer.php - - - - message: "#^Cannot call method getBlockSkyLightArray\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" - count: 1 - path: ../../../src/world/format/io/FastChunkSerializer.php - - - - message: "#^Cannot call method getEmptyBlockId\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" - count: 1 - path: ../../../src/world/format/io/FastChunkSerializer.php - - - - message: "#^Cannot call method getBlockLayers\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" - count: 1 - path: ../../../src/world/format/io/leveldb/LevelDB.php - - - - message: "#^Cannot call method isEmptyAuthoritative\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" - count: 1 - path: ../../../src/world/format/io/leveldb/LevelDB.php - - - - message: "#^Cannot call method getBlockLayers\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" - count: 1 - path: ../../../src/world/light/BlockLightUpdate.php - - - - message: "#^Cannot call method setBlockLightArray\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" - count: 1 - path: ../../../src/world/light/BlockLightUpdate.php - - - - message: "#^Parameter \\#1 \\$subChunk of method pocketmine\\\\world\\\\light\\\\BlockLightUpdate\\:\\:scanForLightEmittingBlocks\\(\\) expects pocketmine\\\\world\\\\format\\\\SubChunk, pocketmine\\\\world\\\\format\\\\SubChunk\\|null given\\.$#" - count: 1 - path: ../../../src/world/light/BlockLightUpdate.php - - - - message: "#^Cannot call method getBlockLightArray\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" - count: 1 - path: ../../../src/world/light/LightPopulationTask.php - - - - message: "#^Cannot call method getBlockSkyLightArray\\(\\) on pocketmine\\\\world\\\\format\\\\SubChunk\\|null\\.$#" - count: 1 - path: ../../../src/world/light/LightPopulationTask.php - From 32f8b8163e8632ef5a65531b647c741c1c320b65 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Oct 2021 22:19:36 +0100 Subject: [PATCH 2884/3224] Clean out PHPStan l7 baseline --- tests/phpstan/configs/l7-baseline.neon | 83 ++------------------------ 1 file changed, 4 insertions(+), 79 deletions(-) diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index 4f82f4aff4..ae390b9deb 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -260,14 +260,9 @@ parameters: count: 1 path: ../../../src/block/Leaves.php - - - message: "#^Parameter \\#1 \\$blockX of method pocketmine\\\\block\\\\Liquid\\:\\:calculateFlowCost\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/block/Liquid.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" - count: 23 + count: 11 path: ../../../src/block/Liquid.php - @@ -275,19 +270,9 @@ parameters: count: 1 path: ../../../src/block/Liquid.php - - - message: "#^Parameter \\#1 \\$x of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" - count: 3 - path: ../../../src/block/Liquid.php - - - - message: "#^Parameter \\#2 \\$blockY of method pocketmine\\\\block\\\\Liquid\\:\\:calculateFlowCost\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/block/Liquid.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" - count: 23 + count: 11 path: ../../../src/block/Liquid.php - @@ -295,19 +280,9 @@ parameters: count: 1 path: ../../../src/block/Liquid.php - - - message: "#^Parameter \\#2 \\$y of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" - count: 3 - path: ../../../src/block/Liquid.php - - - - message: "#^Parameter \\#3 \\$blockZ of method pocketmine\\\\block\\\\Liquid\\:\\:calculateFlowCost\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/block/Liquid.php - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" - count: 23 + count: 11 path: ../../../src/block/Liquid.php - @@ -315,11 +290,6 @@ parameters: count: 1 path: ../../../src/block/Liquid.php - - - message: "#^Parameter \\#3 \\$z of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" - count: 3 - path: ../../../src/block/Liquid.php - - message: "#^Parameter \\#1 \\$min of function mt_rand expects int, float\\|int given\\.$#" count: 3 @@ -610,38 +580,18 @@ parameters: count: 1 path: ../../../src/utils/Timezone.php - - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/world/Explosion.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:getTileAt\\(\\) expects int, float\\|int given\\.$#" count: 1 path: ../../../src/world/Explosion.php - - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/world/Explosion.php - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:setBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 1 path: ../../../src/world/Explosion.php - - - message: "#^Parameter \\#1 \\$x of method pocketmine\\\\world\\\\World\\:\\:updateAllLight\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/world/Explosion.php - - message: "#^Parameter \\#1 \\$x of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" - count: 2 - path: ../../../src/world/Explosion.php - - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 1 path: ../../../src/world/Explosion.php @@ -650,28 +600,13 @@ parameters: count: 1 path: ../../../src/world/Explosion.php - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/world/Explosion.php - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:setBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 1 path: ../../../src/world/Explosion.php - - - message: "#^Parameter \\#2 \\$y of method pocketmine\\\\world\\\\World\\:\\:updateAllLight\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/world/Explosion.php - - message: "#^Parameter \\#2 \\$y of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" - count: 2 - path: ../../../src/world/Explosion.php - - - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:getBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 1 path: ../../../src/world/Explosion.php @@ -680,24 +615,14 @@ parameters: count: 1 path: ../../../src/world/Explosion.php - - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:isInWorld\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/world/Explosion.php - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:setBlockAt\\(\\) expects int, float\\|int given\\.$#" count: 1 path: ../../../src/world/Explosion.php - - - message: "#^Parameter \\#3 \\$z of method pocketmine\\\\world\\\\World\\:\\:updateAllLight\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/world/Explosion.php - - message: "#^Parameter \\#3 \\$z of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" - count: 2 + count: 1 path: ../../../src/world/Explosion.php - From e6f6a036ef523cba75013745cf804cd6ddb81858 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Oct 2021 22:34:11 +0100 Subject: [PATCH 2885/3224] LightPopulationTask: do not copy existing light arrays this task wipes out the light arrays and recalculates them from scratch, so it's pointless to copy any preexisting light arrays anyway. --- src/world/light/LightPopulationTask.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index d7cdce64a4..a2d607e0e0 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -51,7 +51,7 @@ class LightPopulationTask extends AsyncTask{ * @phpstan-param \Closure(array $blockLight, array $skyLight, array $heightMap) : void $onCompletion */ public function __construct(Chunk $chunk, \Closure $onCompletion){ - $this->chunk = FastChunkSerializer::serialize($chunk); + $this->chunk = FastChunkSerializer::serializeWithoutLight($chunk); $this->storeLocal(self::TLS_KEY_COMPLETION_CALLBACK, $onCompletion); } From 8de30e8162e8c46f94b8c6e166e9d191044aa3f2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Oct 2021 22:57:22 +0100 Subject: [PATCH 2886/3224] FastChunkSerializer no longer serializes light by default the core doesn't use this anywhere. serializeWithoutLight() has been renamed to serializeTerrain() to more accurately describe what it does. --- src/network/mcpe/ChunkRequestTask.php | 4 +-- src/world/format/io/FastChunkSerializer.php | 36 +++------------------ src/world/generator/PopulationTask.php | 16 ++++----- src/world/light/LightPopulationTask.php | 4 +-- 4 files changed, 16 insertions(+), 44 deletions(-) diff --git a/src/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php index ec7b0adf7b..676a480a96 100644 --- a/src/network/mcpe/ChunkRequestTask.php +++ b/src/network/mcpe/ChunkRequestTask.php @@ -58,7 +58,7 @@ class ChunkRequestTask extends AsyncTask{ public function __construct(int $chunkX, int $chunkZ, Chunk $chunk, CompressBatchPromise $promise, Compressor $compressor, ?\Closure $onError = null){ $this->compressor = $compressor; - $this->chunk = FastChunkSerializer::serializeWithoutLight($chunk); + $this->chunk = FastChunkSerializer::serializeTerrain($chunk); $this->chunkX = $chunkX; $this->chunkZ = $chunkZ; $this->tiles = ChunkSerializer::serializeTiles($chunk); @@ -68,7 +68,7 @@ class ChunkRequestTask extends AsyncTask{ } public function onRun() : void{ - $chunk = FastChunkSerializer::deserialize($this->chunk); + $chunk = FastChunkSerializer::deserializeTerrain($this->chunk); $subCount = ChunkSerializer::getSubChunkCount($chunk); $encoderContext = new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary()); $payload = ChunkSerializer::serializeFullChunk($chunk, RuntimeBlockMapping::getInstance(), $encoderContext, $this->tiles); diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index 4e65c414f2..cc85444115 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -26,8 +26,6 @@ namespace pocketmine\world\format\io; use pocketmine\utils\BinaryStream; use pocketmine\world\format\BiomeArray; use pocketmine\world\format\Chunk; -use pocketmine\world\format\HeightArray; -use pocketmine\world\format\LightArray; use pocketmine\world\format\PalettedBlockArray; use pocketmine\world\format\SubChunk; use function array_values; @@ -42,26 +40,18 @@ use function unpack; */ final class FastChunkSerializer{ private const FLAG_POPULATED = 1 << 1; - private const FLAG_HAS_LIGHT = 1 << 2; private function __construct(){ //NOOP } - public static function serializeWithoutLight(Chunk $chunk) : string{ - return self::serialize($chunk, false); - } - /** * Fast-serializes the chunk for passing between threads * TODO: tiles and entities */ - public static function serialize(Chunk $chunk, bool $includeLight = true) : string{ - $includeLight = $includeLight && $chunk->isLightPopulated() === true; - + public static function serializeTerrain(Chunk $chunk) : string{ $stream = new BinaryStream(); $stream->putByte( - ($includeLight ? self::FLAG_HAS_LIGHT : 0) | ($chunk->isPopulated() ? self::FLAG_POPULATED : 0) ); @@ -85,18 +75,10 @@ final class FastChunkSerializer{ $stream->putInt(strlen($serialPalette)); $stream->put($serialPalette); } - - if($includeLight){ - $stream->put($subChunk->getBlockSkyLightArray()->getData()); - $stream->put($subChunk->getBlockLightArray()->getData()); - } } //biomes $stream->put($chunk->getBiomeIdArray()); - if($includeLight){ - $stream->put(pack("S*", ...$chunk->getHeightMapArray())); - } return $stream->getBuffer(); } @@ -104,15 +86,13 @@ final class FastChunkSerializer{ /** * Deserializes a fast-serialized chunk */ - public static function deserialize(string $data) : Chunk{ + public static function deserializeTerrain(string $data) : Chunk{ $stream = new BinaryStream($data); $flags = $stream->getByte(); - $lightPopulated = (bool) ($flags & self::FLAG_HAS_LIGHT); $terrainPopulated = (bool) ($flags & self::FLAG_POPULATED); $subChunks = []; - $heightMap = null; $count = $stream->getByte(); for($subCount = 0; $subCount < $count; ++$subCount){ @@ -130,21 +110,13 @@ final class FastChunkSerializer{ $layers[] = PalettedBlockArray::fromData($bitsPerBlock, $words, $palette); } - $subChunks[$y] = new SubChunk( - $airBlockId, $layers, $lightPopulated ? new LightArray($stream->get(2048)) : null, $lightPopulated ? new LightArray($stream->get(2048)) : null - ); + $subChunks[$y] = new SubChunk($airBlockId, $layers); } $biomeIds = new BiomeArray($stream->get(256)); - if($lightPopulated){ - /** @var int[] $unpackedHeightMap */ - $unpackedHeightMap = unpack("S*", $stream->get(512)); //unpack() will never fail here - $heightMap = new HeightArray(array_values($unpackedHeightMap)); - } - $chunk = new Chunk($subChunks, $biomeIds, $heightMap); + $chunk = new Chunk($subChunks, $biomeIds); $chunk->setPopulated($terrainPopulated); - $chunk->setLightPopulated($lightPopulated); $chunk->clearTerrainDirtyFlags(); return $chunk; diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 87222664ec..2af1a452bc 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -68,10 +68,10 @@ class PopulationTask extends AsyncTask{ $this->worldId = $world->getId(); $this->chunkX = $chunkX; $this->chunkZ = $chunkZ; - $this->chunk = $chunk !== null ? FastChunkSerializer::serializeWithoutLight($chunk) : null; + $this->chunk = $chunk !== null ? FastChunkSerializer::serializeTerrain($chunk) : null; foreach($world->getAdjacentChunks($chunkX, $chunkZ) as $i => $c){ - $this->{"chunk$i"} = $c !== null ? FastChunkSerializer::serializeWithoutLight($c) : null; + $this->{"chunk$i"} = $c !== null ? FastChunkSerializer::serializeTerrain($c) : null; } $this->storeLocal(self::TLS_KEY_WORLD, $world); @@ -88,7 +88,7 @@ class PopulationTask extends AsyncTask{ /** @var Chunk[] $chunks */ $chunks = []; - $chunk = $this->chunk !== null ? FastChunkSerializer::deserialize($this->chunk) : null; + $chunk = $this->chunk !== null ? FastChunkSerializer::deserializeTerrain($this->chunk) : null; for($i = 0; $i < 9; ++$i){ if($i === 4){ @@ -98,7 +98,7 @@ class PopulationTask extends AsyncTask{ if($ck === null){ $chunks[$i] = null; }else{ - $chunks[$i] = FastChunkSerializer::deserialize($ck); + $chunks[$i] = FastChunkSerializer::deserializeTerrain($ck); } } @@ -135,10 +135,10 @@ class PopulationTask extends AsyncTask{ $chunk = $manager->getChunk($this->chunkX, $this->chunkZ); $chunk->setPopulated(); - $this->chunk = FastChunkSerializer::serializeWithoutLight($chunk); + $this->chunk = FastChunkSerializer::serializeTerrain($chunk); foreach($chunks as $i => $c){ - $this->{"chunk$i"} = $c->isTerrainDirty() ? FastChunkSerializer::serializeWithoutLight($c) : null; + $this->{"chunk$i"} = $c->isTerrainDirty() ? FastChunkSerializer::serializeTerrain($c) : null; } } @@ -146,7 +146,7 @@ class PopulationTask extends AsyncTask{ /** @var World $world */ $world = $this->fetchLocal(self::TLS_KEY_WORLD); if($world->isLoaded()){ - $chunk = $this->chunk !== null ? FastChunkSerializer::deserialize($this->chunk) : null; + $chunk = $this->chunk !== null ? FastChunkSerializer::deserializeTerrain($this->chunk) : null; for($i = 0; $i < 9; ++$i){ if($i === 4){ @@ -157,7 +157,7 @@ class PopulationTask extends AsyncTask{ $xx = -1 + $i % 3; $zz = -1 + intdiv($i, 3); - $c = FastChunkSerializer::deserialize($c); + $c = FastChunkSerializer::deserializeTerrain($c); $world->generateChunkCallback($this->chunkX + $xx, $this->chunkZ + $zz, $c); } } diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index a2d607e0e0..97d6344ede 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -51,12 +51,12 @@ class LightPopulationTask extends AsyncTask{ * @phpstan-param \Closure(array $blockLight, array $skyLight, array $heightMap) : void $onCompletion */ public function __construct(Chunk $chunk, \Closure $onCompletion){ - $this->chunk = FastChunkSerializer::serializeWithoutLight($chunk); + $this->chunk = FastChunkSerializer::serializeTerrain($chunk); $this->storeLocal(self::TLS_KEY_COMPLETION_CALLBACK, $onCompletion); } public function onRun() : void{ - $chunk = FastChunkSerializer::deserialize($this->chunk); + $chunk = FastChunkSerializer::deserializeTerrain($this->chunk); $manager = new SimpleChunkManager(World::Y_MIN, World::Y_MAX); $manager->setChunk(0, 0, $chunk); From 88f799da2ceb88e290a3fe7a992fc3cdf2d40058 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Oct 2021 23:05:48 +0100 Subject: [PATCH 2887/3224] more AssumptionFailedError hacks for PHPStan :( the code in this class is really horrible --- src/world/generator/PopulationTask.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 2af1a452bc..6c96b1c27f 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -133,6 +133,9 @@ class PopulationTask extends AsyncTask{ $generator->populateChunk($manager, $this->chunkX, $this->chunkZ); $chunk = $manager->getChunk($this->chunkX, $this->chunkZ); + if($chunk === null){ + throw new AssumptionFailedError("We just generated this chunk, so it must exist"); + } $chunk->setPopulated(); $this->chunk = FastChunkSerializer::serializeTerrain($chunk); From c7e913899498fccb9d62284ade3503f7260428f7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Oct 2021 23:18:56 +0100 Subject: [PATCH 2888/3224] PopulationTask: reduce code duplication --- src/world/generator/PopulationTask.php | 37 +++++++++++--------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 6c96b1c27f..5af9ed6502 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -102,32 +102,13 @@ class PopulationTask extends AsyncTask{ } } - $manager->setChunk($this->chunkX, $this->chunkZ, $chunk ?? new Chunk()); - if($chunk === null){ - $generator->generateChunk($manager, $this->chunkX, $this->chunkZ); - $chunk = $manager->getChunk($this->chunkX, $this->chunkZ); - if($chunk === null){ - throw new AssumptionFailedError("We just set this chunk, so it must exist"); - } - $chunk->setTerrainDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN, true); - $chunk->setTerrainDirtyFlag(Chunk::DIRTY_FLAG_BIOMES, true); - } + self::setOrGenerateChunk($manager, $generator, $this->chunkX, $this->chunkZ, $chunk); $resultChunks = []; //this is just to keep phpstan's type inference happy foreach($chunks as $i => $c){ $cX = (-1 + $i % 3) + $this->chunkX; $cZ = (-1 + intdiv($i, 3)) + $this->chunkZ; - $manager->setChunk($cX, $cZ, $c ?? new Chunk()); - if($c === null){ - $generator->generateChunk($manager, $cX, $cZ); - $c = $manager->getChunk($cX, $cZ); - if($c === null){ - throw new AssumptionFailedError("We just set this chunk, so it must exist"); - } - $c->setTerrainDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN, true); - $c->setTerrainDirtyFlag(Chunk::DIRTY_FLAG_BIOMES, true); - } - $resultChunks[$i] = $c; + $resultChunks[$i] = self::setOrGenerateChunk($manager, $generator, $cX, $cZ, $c); } $chunks = $resultChunks; @@ -145,6 +126,20 @@ class PopulationTask extends AsyncTask{ } } + private static function setOrGenerateChunk(SimpleChunkManager $manager, Generator $generator, int $chunkX, int $chunkZ, ?Chunk $chunk) : Chunk{ + $manager->setChunk($chunkX, $chunkZ, $chunk ?? new Chunk()); + if($chunk === null){ + $generator->generateChunk($manager, $chunkX, $chunkZ); + $chunk = $manager->getChunk($chunkX, $chunkZ); + if($chunk === null){ + throw new AssumptionFailedError("We just set this chunk, so it must exist"); + } + $chunk->setTerrainDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN, true); + $chunk->setTerrainDirtyFlag(Chunk::DIRTY_FLAG_BIOMES, true); + } + return $chunk; + } + public function onCompletion() : void{ /** @var World $world */ $world = $this->fetchLocal(self::TLS_KEY_WORLD); From 81d5598e96ecf776c6d312a403d9bcd6f0b3b502 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 1 Oct 2021 23:27:58 +0100 Subject: [PATCH 2889/3224] UPnP: Fixed server crash on failure to find UPnP device https://crash.pmmp.io/view/5241010 --- src/network/upnp/UPnPNetworkInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/upnp/UPnPNetworkInterface.php b/src/network/upnp/UPnPNetworkInterface.php index f261cc4015..06634d0186 100644 --- a/src/network/upnp/UPnPNetworkInterface.php +++ b/src/network/upnp/UPnPNetworkInterface.php @@ -50,9 +50,9 @@ final class UPnPNetworkInterface implements NetworkInterface{ public function start() : void{ $this->logger->info("Attempting to portforward..."); - $this->serviceURL = UPnP::getServiceUrl(); try{ + $this->serviceURL = UPnP::getServiceUrl(); UPnP::portForward($this->serviceURL, Internet::getInternalIP(), $this->port, $this->port); $this->logger->info("Forwarded $this->ip:$this->port to external port $this->port"); }catch(UPnPException $e){ From f26f06316411767a3b404fbe5bc45be68e09d9b1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Oct 2021 00:52:14 +0100 Subject: [PATCH 2890/3224] UPnP: catch InternetException when attempting portforward we might fail to get the internal IP for some reason, which shouldn't crash the server. --- src/network/upnp/UPnPNetworkInterface.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/upnp/UPnPNetworkInterface.php b/src/network/upnp/UPnPNetworkInterface.php index 06634d0186..45e8a11711 100644 --- a/src/network/upnp/UPnPNetworkInterface.php +++ b/src/network/upnp/UPnPNetworkInterface.php @@ -25,6 +25,7 @@ namespace pocketmine\network\upnp; use pocketmine\network\NetworkInterface; use pocketmine\utils\Internet; +use pocketmine\utils\InternetException; final class UPnPNetworkInterface implements NetworkInterface{ @@ -55,7 +56,7 @@ final class UPnPNetworkInterface implements NetworkInterface{ $this->serviceURL = UPnP::getServiceUrl(); UPnP::portForward($this->serviceURL, Internet::getInternalIP(), $this->port, $this->port); $this->logger->info("Forwarded $this->ip:$this->port to external port $this->port"); - }catch(UPnPException $e){ + }catch(UPnPException | InternetException $e){ $this->logger->error("UPnP portforward failed: " . $e->getMessage()); } } From c6b2c63a9b69e9b7a89881064ae9e54d030d7b2e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Oct 2021 00:52:47 +0100 Subject: [PATCH 2891/3224] Remove a couple more dead errors from PHPStan baseline --- tests/phpstan/configs/l8-baseline.neon | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index cb21fad4ea..2c4824f435 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -275,16 +275,6 @@ parameters: count: 1 path: ../../../src/world/format/HeightArray.php - - - message: "#^Cannot call method setPopulated\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/world/generator/PopulationTask.php - - - - message: "#^Parameter \\#1 \\$chunk of static method pocketmine\\\\world\\\\format\\\\io\\\\FastChunkSerializer\\:\\:serializeWithoutLight\\(\\) expects pocketmine\\\\world\\\\format\\\\Chunk, pocketmine\\\\world\\\\format\\\\Chunk\\|null given\\.$#" - count: 1 - path: ../../../src/world/generator/PopulationTask.php - - message: "#^Method pocketmine\\\\world\\\\generator\\\\biome\\\\BiomeSelector\\:\\:pickBiome\\(\\) should return pocketmine\\\\world\\\\biome\\\\Biome but returns pocketmine\\\\world\\\\biome\\\\Biome\\|null\\.$#" count: 1 From f5266ec81658809025e88aaffffc93faf46d0624 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Oct 2021 12:33:46 +0100 Subject: [PATCH 2892/3224] World: remove dead code leftover from 34f01a3ce3c02f41cfebfc81d34b755cfed62811 fixes #4486 --- src/world/World.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 05ff4dcd8c..0eea2c7bcb 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2289,10 +2289,6 @@ class World implements ChunkManager{ } } $pos = $entity->getPosition()->asVector3(); - $chunk = $this->getOrLoadChunkAtPosition($pos); - if($chunk === null){ - throw new \InvalidArgumentException("Cannot add an Entity in an ungenerated chunk"); - } $this->entitiesByChunk[World::chunkHash($pos->getFloorX() >> Chunk::COORD_BIT_SIZE, $pos->getFloorZ() >> Chunk::COORD_BIT_SIZE)][$entity->getId()] = $entity; $this->entityLastKnownPositions[$entity->getId()] = $pos; From 54174eefa026123a9eedebbd4917f88e1326377c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Oct 2021 15:27:11 +0100 Subject: [PATCH 2893/3224] Make sure COMPOSER_AUTOLOADER_PATH is always declared Sacrifice dynamic composer autoloader path to do this, because we don't need it anyway - it was a misconceived feature from the days when I used the same workspace for PM3 and PM4 both. --- src/CoreConstants.php | 1 + src/PocketMine.php | 13 +++---------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/CoreConstants.php b/src/CoreConstants.php index bf88306f16..63913e9417 100644 --- a/src/CoreConstants.php +++ b/src/CoreConstants.php @@ -35,3 +35,4 @@ define('pocketmine\_CORE_CONSTANTS_INCLUDED', true); define('pocketmine\PATH', dirname(__DIR__) . '/'); define('pocketmine\RESOURCE_PATH', dirname(__DIR__) . '/resources/'); +define('pocketmine\COMPOSER_AUTOLOADER_PATH', dirname(__DIR__) . '/vendor/autoload.php'); diff --git a/src/PocketMine.php b/src/PocketMine.php index afac6fd8d6..88029b5dfd 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -214,20 +214,13 @@ JIT_WARNING error_reporting(-1); set_ini_entries(); - $opts = getopt("", ["bootstrap:"]); - if(isset($opts["bootstrap"])){ - $bootstrap = ($real = realpath($opts["bootstrap"])) !== false ? $real : $opts["bootstrap"]; - }else{ - $bootstrap = dirname(__FILE__, 2) . '/vendor/autoload.php'; - } - - if($bootstrap === false or !is_file($bootstrap)){ + $bootstrap = dirname(__FILE__, 2) . '/vendor/autoload.php'; + if(!is_file($bootstrap)){ critical_error("Composer autoloader not found at " . $bootstrap); critical_error("Please install/update Composer dependencies or use provided builds."); exit(1); } - define('pocketmine\COMPOSER_AUTOLOADER_PATH', $bootstrap); - require_once(\pocketmine\COMPOSER_AUTOLOADER_PATH); + require_once($bootstrap); $composerGitHash = InstalledVersions::getReference('pocketmine/pocketmine-mp'); if($composerGitHash !== null){ From 2566123e49deacc915512594d09c6b4f71f822ac Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Oct 2021 16:34:38 +0100 Subject: [PATCH 2894/3224] Remove unnecessary constant from PHPStan bootstrap --- tests/phpstan/bootstrap.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/phpstan/bootstrap.php b/tests/phpstan/bootstrap.php index ba8ccd3fc4..6e25be8c3f 100644 --- a/tests/phpstan/bootstrap.php +++ b/tests/phpstan/bootstrap.php @@ -28,6 +28,3 @@ if(!defined('LEVELDB_ZLIB_RAW_COMPRESSION')){ if(!extension_loaded('libdeflate')){ function libdeflate_deflate_compress(string $data, int $level = 6) : string{} } - -//TODO: these need to be defined properly or removed -define('pocketmine\COMPOSER_AUTOLOADER_PATH', dirname(__DIR__, 2) . '/vendor/autoload.php'); From dd0c2fed8201ea7e76fc68c9d754f5a9187e9fed Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Oct 2021 16:56:24 +0100 Subject: [PATCH 2895/3224] Process: add subprocess parameter to kill() fix CommandReader subprocess lingering on a crash and fucking up the console --- src/PocketMine.php | 2 +- src/Server.php | 4 ++-- src/utils/Process.php | 7 +++++-- src/utils/ServerKiller.php | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index 88029b5dfd..44b7ebdd67 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -300,7 +300,7 @@ JIT_WARNING if(ThreadManager::getInstance()->stopAll() > 0){ $logger->debug("Some threads could not be stopped, performing a force-kill"); - Process::kill(Process::pid()); + Process::kill(Process::pid(), true); } }while(false); diff --git a/src/Server.php b/src/Server.php index f76235d57f..7b22fabf33 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1371,7 +1371,7 @@ class Server{ }catch(\Throwable $e){ $this->logger->logException($e); $this->logger->emergency("Crashed while crashing, killing process"); - @Process::kill(Process::pid()); + @Process::kill(Process::pid(), true); } } @@ -1501,7 +1501,7 @@ class Server{ echo "--- Waiting $spacing seconds to throttle automatic restart (you can kill the process safely now) ---" . PHP_EOL; sleep($spacing); } - @Process::kill(Process::pid()); + @Process::kill(Process::pid(), true); exit(1); } diff --git a/src/utils/Process.php b/src/utils/Process.php index f433300fed..a24550c5c2 100644 --- a/src/utils/Process.php +++ b/src/utils/Process.php @@ -125,18 +125,21 @@ final class Process{ return count(ThreadManager::getInstance()->getAll()) + 2; //MainLogger + Main Thread } - public static function kill(int $pid) : void{ + public static function kill(int $pid, bool $subprocesses) : void{ $logger = \GlobalLogger::get(); if($logger instanceof MainLogger){ $logger->syncFlushBuffer(); } switch(Utils::getOS()){ case Utils::OS_WINDOWS: - exec("taskkill.exe /F /PID $pid > NUL"); + exec("taskkill.exe /F " . ($subprocesses ? "/T " : "") . "/PID $pid"); break; case Utils::OS_MACOS: case Utils::OS_LINUX: default: + if($subprocesses){ + $pid = -$pid; + } if(function_exists("posix_kill")){ posix_kill($pid, 9); //SIGKILL }else{ diff --git a/src/utils/ServerKiller.php b/src/utils/ServerKiller.php index 78d83f6547..24f8eb37a3 100644 --- a/src/utils/ServerKiller.php +++ b/src/utils/ServerKiller.php @@ -50,7 +50,7 @@ class ServerKiller extends Thread{ }); if(time() - $start >= $this->time){ echo "\nTook too long to stop, server was killed forcefully!\n"; - @Process::kill(Process::pid()); + @Process::kill(Process::pid(), true); } } From 0108888450e094263934b6f5959ba0cbc8873bff Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Oct 2021 17:23:26 +0100 Subject: [PATCH 2896/3224] Process: silence taskkill complaining that it can't commit suicide since taskkill is a subprocess of the server process, it gets included in taskkill's own attempted killing spree, but taskkill (wisely) won't kill itself. --- src/utils/Process.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/Process.php b/src/utils/Process.php index a24550c5c2..8e93f9b1c4 100644 --- a/src/utils/Process.php +++ b/src/utils/Process.php @@ -132,7 +132,7 @@ final class Process{ } switch(Utils::getOS()){ case Utils::OS_WINDOWS: - exec("taskkill.exe /F " . ($subprocesses ? "/T " : "") . "/PID $pid"); + exec("taskkill.exe /F " . ($subprocesses ? "/T " : "") . "/PID $pid > NUL 2> NUL"); break; case Utils::OS_MACOS: case Utils::OS_LINUX: From d63b9d1648583e4be2ee379bbaca3e5b5c06cacd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Oct 2021 20:33:32 +0100 Subject: [PATCH 2897/3224] WorldManager: localize strings for world loading, generation and conversion --- resources/locale | 2 +- src/lang/KnownTranslationFactory.php | 45 ++++++++++++++++++++++++++++ src/lang/KnownTranslationKeys.php | 7 +++++ src/world/WorldManager.php | 22 ++++++++++---- 4 files changed, 69 insertions(+), 7 deletions(-) diff --git a/resources/locale b/resources/locale index 4a322da43e..6023e8b3bf 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 4a322da43eb9beef727bd36be3d6b641b8316591 +Subproject commit 6023e8b3bf089eb7c25a5ddc7b29e9ef81520e7e diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index 62577ee162..62bc5d2893 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -573,6 +573,12 @@ final class KnownTranslationFactory{ return new Translatable(KnownTranslationKeys::COMMANDS_WHITELIST_USAGE, []); } + public static function death_attack_anvil(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_ATTACK_ANVIL, [ + 0 => $param0, + ]); + } + public static function death_attack_arrow(Translatable|string $param0, Translatable|string $param1) : Translatable{ return new Translatable(KnownTranslationKeys::DEATH_ATTACK_ARROW, [ 0 => $param0, @@ -1490,6 +1496,25 @@ final class KnownTranslationFactory{ ]); } + public static function pocketmine_level_conversion_finish(Translatable|string $worldName, Translatable|string $backupPath) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_CONVERSION_FINISH, [ + "worldName" => $worldName, + "backupPath" => $backupPath, + ]); + } + + public static function pocketmine_level_conversion_start(Translatable|string $worldName) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_CONVERSION_START, [ + "worldName" => $worldName, + ]); + } + + public static function pocketmine_level_corrupted(Translatable|string $details) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_CORRUPTED, [ + "details" => $details, + ]); + } + public static function pocketmine_level_defaultError() : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_DEFAULTERROR, []); } @@ -1520,16 +1545,36 @@ final class KnownTranslationFactory{ ]); } + public static function pocketmine_level_spawnTerrainGenerationProgress(Translatable|string $done, Translatable|string $total, Translatable|string $percentageDone) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_SPAWNTERRAINGENERATIONPROGRESS, [ + "done" => $done, + "total" => $total, + "percentageDone" => $percentageDone, + ]); + } + public static function pocketmine_level_unknownFormat() : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_UNKNOWNFORMAT, []); } + public static function pocketmine_level_unknownGenerator(Translatable|string $generatorName) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_UNKNOWNGENERATOR, [ + "generatorName" => $generatorName, + ]); + } + public static function pocketmine_level_unloading(Translatable|string $param0) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_UNLOADING, [ 0 => $param0, ]); } + public static function pocketmine_level_unsupportedFormat(Translatable|string $details) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_UNSUPPORTEDFORMAT, [ + "details" => $details, + ]); + } + public static function pocketmine_player_invalidEntity(Translatable|string $param0) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_PLAYER_INVALIDENTITY, [ 0 => $param0, diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index 5c3d5bfa36..62ead25d92 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -128,6 +128,7 @@ final class KnownTranslationKeys{ public const COMMANDS_WHITELIST_REMOVE_SUCCESS = "commands.whitelist.remove.success"; public const COMMANDS_WHITELIST_REMOVE_USAGE = "commands.whitelist.remove.usage"; public const COMMANDS_WHITELIST_USAGE = "commands.whitelist.usage"; + public const DEATH_ATTACK_ANVIL = "death.attack.anvil"; public const DEATH_ATTACK_ARROW = "death.attack.arrow"; public const DEATH_ATTACK_ARROW_ITEM = "death.attack.arrow.item"; public const DEATH_ATTACK_CACTUS = "death.attack.cactus"; @@ -324,13 +325,19 @@ final class KnownTranslationKeys{ public const POCKETMINE_LEVEL_AMBIGUOUSFORMAT = "pocketmine.level.ambiguousFormat"; public const POCKETMINE_LEVEL_BACKGROUNDGENERATION = "pocketmine.level.backgroundGeneration"; public const POCKETMINE_LEVEL_BADDEFAULTFORMAT = "pocketmine.level.badDefaultFormat"; + public const POCKETMINE_LEVEL_CONVERSION_FINISH = "pocketmine.level.conversion.finish"; + public const POCKETMINE_LEVEL_CONVERSION_START = "pocketmine.level.conversion.start"; + public const POCKETMINE_LEVEL_CORRUPTED = "pocketmine.level.corrupted"; public const POCKETMINE_LEVEL_DEFAULTERROR = "pocketmine.level.defaultError"; public const POCKETMINE_LEVEL_GENERATIONERROR = "pocketmine.level.generationError"; public const POCKETMINE_LEVEL_LOADERROR = "pocketmine.level.loadError"; public const POCKETMINE_LEVEL_NOTFOUND = "pocketmine.level.notFound"; public const POCKETMINE_LEVEL_PREPARING = "pocketmine.level.preparing"; + public const POCKETMINE_LEVEL_SPAWNTERRAINGENERATIONPROGRESS = "pocketmine.level.spawnTerrainGenerationProgress"; public const POCKETMINE_LEVEL_UNKNOWNFORMAT = "pocketmine.level.unknownFormat"; + public const POCKETMINE_LEVEL_UNKNOWNGENERATOR = "pocketmine.level.unknownGenerator"; public const POCKETMINE_LEVEL_UNLOADING = "pocketmine.level.unloading"; + public const POCKETMINE_LEVEL_UNSUPPORTEDFORMAT = "pocketmine.level.unsupportedFormat"; public const POCKETMINE_PLAYER_INVALIDENTITY = "pocketmine.player.invalidEntity"; public const POCKETMINE_PLAYER_INVALIDMOVE = "pocketmine.player.invalidMove"; public const POCKETMINE_PLAYER_LOGIN = "pocketmine.player.logIn"; diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index 452e5a1251..d79eee0b64 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -50,6 +50,7 @@ use function iterator_to_array; use function microtime; use function round; use function sprintf; +use function strval; use function trim; class WorldManager{ @@ -207,28 +208,37 @@ class WorldManager{ try{ $provider = $providerClass->fromPath($path); }catch(CorruptedWorldException $e){ - $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_loadError($name, "Corruption detected: " . $e->getMessage()))); + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_loadError( + $name, + KnownTranslationFactory::pocketmine_level_corrupted($e->getMessage()) + ))); return false; }catch(UnsupportedWorldFormatException $e){ - $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_loadError($name, "Unsupported format: " . $e->getMessage()))); + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_loadError( + $name, + KnownTranslationFactory::pocketmine_level_unsupportedFormat($e->getMessage()) + ))); return false; } try{ GeneratorManager::getInstance()->getGenerator($provider->getWorldData()->getGenerator(), true); }catch(\InvalidArgumentException $e){ - $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_loadError($name, "Unknown generator \"" . $provider->getWorldData()->getGenerator() . "\""))); + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_loadError( + $name, + KnownTranslationFactory::pocketmine_level_unknownGenerator($provider->getWorldData()->getGenerator()) + ))); return false; } if(!($provider instanceof WritableWorldProvider)){ if(!$autoUpgrade){ throw new UnsupportedWorldFormatException("World \"$name\" is in an unsupported format and needs to be upgraded"); } - $this->server->getLogger()->notice("Upgrading world \"$name\" to new format. This may take a while."); + $this->server->getLogger()->notice($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_conversion_start($name))); $converter = new FormatConverter($provider, $this->providerManager->getDefault(), Path::join($this->server->getDataPath(), "backups", "worlds"), $this->server->getLogger()); $provider = $converter->execute(); - $this->server->getLogger()->notice("Upgraded world \"$name\" to new format successfully. Backed up pre-conversion world at " . $converter->getBackupPath()); + $this->server->getLogger()->notice($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_conversion_finish($name, $converter->getBackupPath()))); } $world = new World($this->server, $name, $provider, $this->server->getAsyncPool()); @@ -282,7 +292,7 @@ class WorldManager{ $oldProgress = (int) floor(($done / $total) * 100); $newProgress = (int) floor((++$done / $total) * 100); if(intdiv($oldProgress, 10) !== intdiv($newProgress, 10) || $done === $total || $done === 1){ - $world->getLogger()->info("Generating spawn terrain chunks: $done / $total ($newProgress%)"); + $world->getLogger()->info($world->getServer()->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_spawnTerrainGenerationProgress(strval($done), strval($total), strval($newProgress)))); } }, static function() : void{ From 05dc675d5be8a245bba4250a4de1ca529d56b4c0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Oct 2021 20:42:59 +0100 Subject: [PATCH 2898/3224] Replace commands.generic.notFound with a custom PM version this also fixes #4379. --- resources/locale | 2 +- src/Server.php | 8 +------ src/command/SimpleCommandMap.php | 32 +++++++++++++--------------- src/lang/KnownTranslationFactory.php | 7 ++++++ src/lang/KnownTranslationKeys.php | 1 + 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/resources/locale b/resources/locale index 6023e8b3bf..73fb74ffce 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 6023e8b3bf089eb7c25a5ddc7b29e9ef81520e7e +Subproject commit 73fb74ffce2b633b87fc82039d1fb3c2cf0d5ac7 diff --git a/src/Server.php b/src/Server.php index 7b22fabf33..def42ef92f 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1293,13 +1293,7 @@ class Server{ $commandLine = $ev->getCommand(); } - if($this->commandMap->dispatch($sender, $commandLine)){ - return true; - } - - $sender->sendMessage(KnownTranslationFactory::commands_generic_notFound()->prefix(TextFormat::RED)); - - return false; + return $this->commandMap->dispatch($sender, $commandLine); } /** diff --git a/src/command/SimpleCommandMap.php b/src/command/SimpleCommandMap.php index 638e107400..6b8f392e6b 100644 --- a/src/command/SimpleCommandMap.php +++ b/src/command/SimpleCommandMap.php @@ -67,6 +67,7 @@ use pocketmine\command\defaults\WhitelistCommand; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; use pocketmine\Server; +use pocketmine\utils\TextFormat; use function array_shift; use function count; use function explode; @@ -210,26 +211,23 @@ class SimpleCommandMap implements CommandMap{ } } } + $sentCommandLabel = array_shift($args); - if($sentCommandLabel === null){ - return false; - } - $target = $this->getCommand($sentCommandLabel); - if($target === null){ - return false; + if($sentCommandLabel !== null && ($target = $this->getCommand($sentCommandLabel)) !== null){ + $target->timings->startTiming(); + + try{ + $target->execute($sender, $sentCommandLabel, $args); + }catch(InvalidCommandSyntaxException $e){ + $sender->sendMessage($sender->getLanguage()->translate(KnownTranslationFactory::commands_generic_usage($target->getUsage()))); + }finally{ + $target->timings->stopTiming(); + } + return true; } - $target->timings->startTiming(); - - try{ - $target->execute($sender, $sentCommandLabel, $args); - }catch(InvalidCommandSyntaxException $e){ - $sender->sendMessage($sender->getLanguage()->translate(KnownTranslationFactory::commands_generic_usage($target->getUsage()))); - }finally{ - $target->timings->stopTiming(); - } - - return true; + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_notFound($sentCommandLabel ?? "", "/help")->prefix(TextFormat::RED)); + return false; } public function clearCommands() : void{ diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index 62bc5d2893..a36417c810 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -1185,6 +1185,13 @@ final class KnownTranslationFactory{ return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_ME_DESCRIPTION, []); } + public static function pocketmine_command_notFound(Translatable|string $commandName, Translatable|string $helpCommand) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_NOTFOUND, [ + "commandName" => $commandName, + "helpCommand" => $helpCommand, + ]); + } + public static function pocketmine_command_op_description() : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_OP_DESCRIPTION, []); } diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index 62ead25d92..65a3c9a76d 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -260,6 +260,7 @@ final class KnownTranslationKeys{ public const POCKETMINE_COMMAND_KILL_USAGE = "pocketmine.command.kill.usage"; public const POCKETMINE_COMMAND_LIST_DESCRIPTION = "pocketmine.command.list.description"; public const POCKETMINE_COMMAND_ME_DESCRIPTION = "pocketmine.command.me.description"; + public const POCKETMINE_COMMAND_NOTFOUND = "pocketmine.command.notFound"; public const POCKETMINE_COMMAND_OP_DESCRIPTION = "pocketmine.command.op.description"; public const POCKETMINE_COMMAND_PARTICLE_DESCRIPTION = "pocketmine.command.particle.description"; public const POCKETMINE_COMMAND_PARTICLE_USAGE = "pocketmine.command.particle.usage"; From 30e10c38b6933dd1e6b7c935e70fc7c5b1e7dae4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Oct 2021 20:59:36 +0100 Subject: [PATCH 2899/3224] Localize /help --- resources/locale | 2 +- src/command/defaults/HelpCommand.php | 13 ++++++++----- src/lang/KnownTranslationFactory.php | 18 ++++++++++++++++++ src/lang/KnownTranslationKeys.php | 3 +++ 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/resources/locale b/resources/locale index 73fb74ffce..73439bd449 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 73fb74ffce2b633b87fc82039d1fb3c2cf0d5ac7 +Subproject commit 73439bd4492a3fb3c3ed11eb6e654cf4a282b20c diff --git a/src/command/defaults/HelpCommand.php b/src/command/defaults/HelpCommand.php index 77bc98d0e7..f16049a693 100644 --- a/src/command/defaults/HelpCommand.php +++ b/src/command/defaults/HelpCommand.php @@ -105,17 +105,20 @@ class HelpCommand extends VanillaCommand{ $lang = $sender->getLanguage(); $description = $cmd->getDescription(); $descriptionString = $description instanceof Translatable ? $lang->translate($description) : $description; - $message = TextFormat::YELLOW . "--------- " . TextFormat::WHITE . " Help: /" . $cmd->getName() . TextFormat::YELLOW . " ---------\n"; - $message .= TextFormat::GOLD . "Description: " . TextFormat::WHITE . $descriptionString . "\n"; + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_help_specificCommand_header($commandName) + ->format(TextFormat::YELLOW . "--------- " . TextFormat::WHITE, TextFormat::YELLOW . " ---------")); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_help_specificCommand_description(TextFormat::WHITE . $descriptionString) + ->prefix(TextFormat::GOLD)); + $usage = $cmd->getUsage(); $usageString = $usage instanceof Translatable ? $lang->translate($usage) : $usage; - $message .= TextFormat::GOLD . "Usage: " . TextFormat::WHITE . implode("\n" . TextFormat::WHITE, explode("\n", $usageString)) . "\n"; - $sender->sendMessage($message); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_help_specificCommand_usage(TextFormat::WHITE . implode("\n" . TextFormat::WHITE, explode("\n", $usageString))) + ->prefix(TextFormat::GOLD)); return true; } } - $sender->sendMessage(TextFormat::RED . "No help for " . strtolower($commandName)); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_notFound($commandName, "/help")->prefix(TextFormat::RED)); return true; } diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index a36417c810..1150e1d51d 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -1165,6 +1165,24 @@ final class KnownTranslationFactory{ return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_HELP_DESCRIPTION, []); } + public static function pocketmine_command_help_specificCommand_description(Translatable|string $description) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_HELP_SPECIFICCOMMAND_DESCRIPTION, [ + "description" => $description, + ]); + } + + public static function pocketmine_command_help_specificCommand_header(Translatable|string $commandName) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_HELP_SPECIFICCOMMAND_HEADER, [ + "commandName" => $commandName, + ]); + } + + public static function pocketmine_command_help_specificCommand_usage(Translatable|string $usage) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_HELP_SPECIFICCOMMAND_USAGE, [ + "usage" => $usage, + ]); + } + public static function pocketmine_command_kick_description() : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_KICK_DESCRIPTION, []); } diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index 65a3c9a76d..88807b9975 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -255,6 +255,9 @@ final class KnownTranslationKeys{ public const POCKETMINE_COMMAND_GIVE_DESCRIPTION = "pocketmine.command.give.description"; public const POCKETMINE_COMMAND_GIVE_USAGE = "pocketmine.command.give.usage"; public const POCKETMINE_COMMAND_HELP_DESCRIPTION = "pocketmine.command.help.description"; + public const POCKETMINE_COMMAND_HELP_SPECIFICCOMMAND_DESCRIPTION = "pocketmine.command.help.specificCommand.description"; + public const POCKETMINE_COMMAND_HELP_SPECIFICCOMMAND_HEADER = "pocketmine.command.help.specificCommand.header"; + public const POCKETMINE_COMMAND_HELP_SPECIFICCOMMAND_USAGE = "pocketmine.command.help.specificCommand.usage"; public const POCKETMINE_COMMAND_KICK_DESCRIPTION = "pocketmine.command.kick.description"; public const POCKETMINE_COMMAND_KILL_DESCRIPTION = "pocketmine.command.kill.description"; public const POCKETMINE_COMMAND_KILL_USAGE = "pocketmine.command.kill.usage"; From fb570970a8384cf0cea1a2c2659c62b5a68fc805 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Oct 2021 21:22:54 +0100 Subject: [PATCH 2900/3224] Localize gamemode command errors --- resources/locale | 2 +- src/command/defaults/DefaultGamemodeCommand.php | 2 +- src/command/defaults/GamemodeCommand.php | 4 ++-- src/lang/KnownTranslationFactory.php | 12 ++++++++++++ src/lang/KnownTranslationKeys.php | 2 ++ 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/resources/locale b/resources/locale index 73439bd449..cb47518ae3 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 73439bd4492a3fb3c3ed11eb6e654cf4a282b20c +Subproject commit cb47518ae37ce834b612b2efe2df841852d07a31 diff --git a/src/command/defaults/DefaultGamemodeCommand.php b/src/command/defaults/DefaultGamemodeCommand.php index f7752319e2..d2ae848aef 100644 --- a/src/command/defaults/DefaultGamemodeCommand.php +++ b/src/command/defaults/DefaultGamemodeCommand.php @@ -53,7 +53,7 @@ class DefaultGamemodeCommand extends VanillaCommand{ $gameMode = GameMode::fromString($args[0]); if($gameMode === null){ - $sender->sendMessage("Unknown game mode"); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_gamemode_unknown($args[0])); return true; } diff --git a/src/command/defaults/GamemodeCommand.php b/src/command/defaults/GamemodeCommand.php index e011508756..86658de6da 100644 --- a/src/command/defaults/GamemodeCommand.php +++ b/src/command/defaults/GamemodeCommand.php @@ -55,7 +55,7 @@ class GamemodeCommand extends VanillaCommand{ $gameMode = GameMode::fromString($args[0]); if($gameMode === null){ - $sender->sendMessage("Unknown game mode"); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_gamemode_unknown($args[0])); return true; } @@ -74,7 +74,7 @@ class GamemodeCommand extends VanillaCommand{ $target->setGamemode($gameMode); if(!$gameMode->equals($target->getGamemode())){ - $sender->sendMessage("Game mode change for " . $target->getName() . " failed!"); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_gamemode_failure($target->getName())); }else{ if($target === $sender){ Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_gamemode_success_self($gameMode->getTranslatableName())); diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index 1150e1d51d..9fc1fc67bc 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -1121,6 +1121,18 @@ final class KnownTranslationFactory{ return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_GAMEMODE_DESCRIPTION, []); } + public static function pocketmine_command_gamemode_failure(Translatable|string $playerName) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_GAMEMODE_FAILURE, [ + "playerName" => $playerName, + ]); + } + + public static function pocketmine_command_gamemode_unknown(Translatable|string $gameModeName) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_GAMEMODE_UNKNOWN, [ + "gameModeName" => $gameModeName, + ]); + } + public static function pocketmine_command_gc_chunks(Translatable|string $chunksCollected) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_GC_CHUNKS, [ "chunksCollected" => $chunksCollected, diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index 88807b9975..0814c5dddb 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -246,6 +246,8 @@ final class KnownTranslationKeys{ public const POCKETMINE_COMMAND_ENCHANT_DESCRIPTION = "pocketmine.command.enchant.description"; public const POCKETMINE_COMMAND_EXCEPTION = "pocketmine.command.exception"; public const POCKETMINE_COMMAND_GAMEMODE_DESCRIPTION = "pocketmine.command.gamemode.description"; + public const POCKETMINE_COMMAND_GAMEMODE_FAILURE = "pocketmine.command.gamemode.failure"; + public const POCKETMINE_COMMAND_GAMEMODE_UNKNOWN = "pocketmine.command.gamemode.unknown"; public const POCKETMINE_COMMAND_GC_CHUNKS = "pocketmine.command.gc.chunks"; public const POCKETMINE_COMMAND_GC_CYCLES = "pocketmine.command.gc.cycles"; public const POCKETMINE_COMMAND_GC_DESCRIPTION = "pocketmine.command.gc.description"; From 6332af3e5925c15b7bc71a068aeb4c69fcdef347 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 4 Oct 2021 21:50:11 +0100 Subject: [PATCH 2901/3224] Require RakLib 0.14.2 minimum --- composer.json | 2 +- composer.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index 12ff5f3930..ee6bccdccd 100644 --- a/composer.json +++ b/composer.json @@ -44,7 +44,7 @@ "pocketmine/log-pthreads": "^0.2.0", "pocketmine/math": "^0.3.0", "pocketmine/nbt": "^0.3.0", - "pocketmine/raklib": "^0.14.0", + "pocketmine/raklib": "^0.14.2", "pocketmine/raklib-ipc": "^0.1.0", "pocketmine/snooze": "^0.3.0", "pocketmine/spl": "dev-master", diff --git a/composer.lock b/composer.lock index d79f124286..e2b12903f6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "bd5d7fc81a75739bfd2ef04b38220b84", + "content-hash": "77f899b35819bca38246a665fd0233f3", "packages": [ { "name": "adhocore/json-comment", @@ -675,16 +675,16 @@ }, { "name": "pocketmine/raklib", - "version": "0.14.1", + "version": "0.14.2", "source": { "type": "git", "url": "https://github.com/pmmp/RakLib.git", - "reference": "2d7bac3d593219880696ca2ca254f083f1e71850" + "reference": "e3a861187470e1facc6625040128f447ebbcbaec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/RakLib/zipball/2d7bac3d593219880696ca2ca254f083f1e71850", - "reference": "2d7bac3d593219880696ca2ca254f083f1e71850", + "url": "https://api.github.com/repos/pmmp/RakLib/zipball/e3a861187470e1facc6625040128f447ebbcbaec", + "reference": "e3a861187470e1facc6625040128f447ebbcbaec", "shasum": "" }, "require": { @@ -712,9 +712,9 @@ "description": "A RakNet server implementation written in PHP", "support": { "issues": "https://github.com/pmmp/RakLib/issues", - "source": "https://github.com/pmmp/RakLib/tree/0.14.1" + "source": "https://github.com/pmmp/RakLib/tree/0.14.2" }, - "time": "2021-10-01T20:35:44+00:00" + "time": "2021-10-04T20:39:11+00:00" }, { "name": "pocketmine/raklib-ipc", From 356a49d225ca9b735fd16cf1b5c9d3c7d1e9de0c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 4 Oct 2021 22:12:58 +0100 Subject: [PATCH 2902/3224] NetworkSession: account for possibility of syncGameMode() being called before the player is ready to receive it close #4323 --- src/network/mcpe/NetworkSession.php | 6 ++++-- tests/phpstan/configs/l8-baseline.neon | 7 +------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 45d6daaa66..3020484b2f 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -754,8 +754,10 @@ class NetworkSession{ public function syncGameMode(GameMode $mode, bool $isRollback = false) : void{ $this->sendDataPacket(SetPlayerGameTypePacket::create(TypeConverter::getInstance()->coreGameModeToProtocol($mode))); - $this->syncAdventureSettings($this->player); - if(!$isRollback){ + if($this->player !== null){ + $this->syncAdventureSettings($this->player); + } + if(!$isRollback && $this->invManager !== null){ $this->invManager->syncCreative(); } } diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index 2c4824f435..c97b637289 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -125,11 +125,6 @@ parameters: count: 1 path: ../../../src/network/mcpe/NetworkSession.php - - - message: "#^Cannot call method syncCreative\\(\\) on pocketmine\\\\network\\\\mcpe\\\\InventoryManager\\|null\\.$#" - count: 1 - path: ../../../src/network/mcpe/NetworkSession.php - - message: "#^Parameter \\#1 \\$clientPub of class pocketmine\\\\network\\\\mcpe\\\\encryption\\\\PrepareEncryptionTask constructor expects string, string\\|null given\\.$#" count: 1 @@ -147,7 +142,7 @@ parameters: - message: "#^Parameter \\#1 \\$for of method pocketmine\\\\network\\\\mcpe\\\\NetworkSession\\:\\:syncAdventureSettings\\(\\) expects pocketmine\\\\player\\\\Player, pocketmine\\\\player\\\\Player\\|null given\\.$#" - count: 3 + count: 2 path: ../../../src/network/mcpe/NetworkSession.php - From bb6ea8cbdc3f457c85f31f73a6efeab98d0d295a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 4 Oct 2021 22:36:50 +0100 Subject: [PATCH 2903/3224] Do not call PlayerLoginEvent during the Player constructor this closes a lot of loopholes in the login sequence that plugins were using to cause crashes. --- src/Server.php | 26 +++++++++++++++++++++++++- src/network/mcpe/NetworkSession.php | 4 ++++ src/player/Player.php | 23 ----------------------- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/Server.php b/src/Server.php index def42ef92f..c99ac010ee 100644 --- a/src/Server.php +++ b/src/Server.php @@ -40,6 +40,7 @@ use pocketmine\entity\Location; use pocketmine\event\HandlerListManager; use pocketmine\event\player\PlayerCreationEvent; use pocketmine\event\player\PlayerDataSaveEvent; +use pocketmine\event\player\PlayerLoginEvent; use pocketmine\event\server\CommandEvent; use pocketmine\event\server\DataPacketSendEvent; use pocketmine\event\server\QueryRegenerateEvent; @@ -1521,7 +1522,28 @@ class Server{ } } - public function addOnlinePlayer(Player $player) : void{ + public function addOnlinePlayer(Player $player) : bool{ + $ev = new PlayerLoginEvent($player, "Plugin reason"); + $ev->call(); + if($ev->isCancelled() or !$player->isConnected()){ + $player->disconnect($ev->getKickMessage()); + + return false; + } + + $session = $player->getNetworkSession(); + $position = $player->getPosition(); + $this->logger->info($this->language->translate(KnownTranslationFactory::pocketmine_player_logIn( + TextFormat::AQUA . $player->getName() . TextFormat::WHITE, + $session->getIp(), + (string) $session->getPort(), + (string) $player->getId(), + $position->getWorld()->getDisplayName(), + (string) round($position->x, 4), + (string) round($position->y, 4), + (string) round($position->z, 4) + ))); + foreach($this->playerList as $p){ $p->getNetworkSession()->onPlayerAdded($player); } @@ -1531,6 +1553,8 @@ class Server{ if($this->sendUsageTicker > 0){ $this->uniquePlayers[$rawUUID] = $rawUUID; } + + return true; } public function removeOnlinePlayer(Player $player) : void{ diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 3020484b2f..cff5b3ee92 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -234,6 +234,10 @@ class NetworkSession{ return; } $this->player = $player; + if(!$this->server->addOnlinePlayer($player)){ + return; + } + $this->invManager = new InventoryManager($this->player, $this); $effectManager = $this->player->getEffects(); diff --git a/src/player/Player.php b/src/player/Player.php index 14a6b205a9..bd7222af02 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -63,7 +63,6 @@ use pocketmine\event\player\PlayerItemUseEvent; use pocketmine\event\player\PlayerJoinEvent; use pocketmine\event\player\PlayerJumpEvent; use pocketmine\event\player\PlayerKickEvent; -use pocketmine\event\player\PlayerLoginEvent; use pocketmine\event\player\PlayerMoveEvent; use pocketmine\event\player\PlayerQuitEvent; use pocketmine\event\player\PlayerRespawnEvent; @@ -133,7 +132,6 @@ use function max; use function microtime; use function min; use function preg_match; -use function round; use function spl_object_id; use function sqrt; use function strlen; @@ -277,27 +275,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->usedChunks[World::chunkHash($spawnLocation->getFloorX() >> Chunk::COORD_BIT_SIZE, $spawnLocation->getFloorZ() >> Chunk::COORD_BIT_SIZE)] = UsedChunkStatus::NEEDED(); parent::__construct($spawnLocation, $this->playerInfo->getSkin(), $namedtag); - - $ev = new PlayerLoginEvent($this, "Plugin reason"); - $ev->call(); - if($ev->isCancelled() or !$this->isConnected()){ - $this->disconnect($ev->getKickMessage()); - - return; - } - - $this->server->getLogger()->info($this->getServer()->getLanguage()->translate(KnownTranslationFactory::pocketmine_player_logIn( - TextFormat::AQUA . $this->username . TextFormat::WHITE, - $session->getIp(), - (string) $session->getPort(), - (string) $this->id, - $this->getWorld()->getDisplayName(), - (string) round($this->location->x, 4), - (string) round($this->location->y, 4), - (string) round($this->location->z, 4) - ))); - - $this->server->addOnlinePlayer($this); } protected function initHumanData(CompoundTag $nbt) : void{ From f2d60596134c51fb061797c5c06b0e7d3b21e64b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 4 Oct 2021 22:51:31 +0100 Subject: [PATCH 2904/3224] NetworkSession: Sync world spawn on world change --- src/network/mcpe/NetworkSession.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index cff5b3ee92..abf2a7c77d 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -756,6 +756,11 @@ class NetworkSession{ $this->sendDataPacket(SetSpawnPositionPacket::playerSpawn($x, $y, $z, DimensionIds::OVERWORLD, $x, $y, $z)); } + public function syncWorldSpawnPoint(Position $newSpawn) : void{ + [$x, $y, $z] = [$newSpawn->getFloorX(), $newSpawn->getFloorY(), $newSpawn->getFloorZ()]; + $this->sendDataPacket(SetSpawnPositionPacket::worldSpawn($x, $y, $z, DimensionIds::OVERWORLD, $x, $y, $z)); + } + public function syncGameMode(GameMode $mode, bool $isRollback = false) : void{ $this->sendDataPacket(SetPlayerGameTypePacket::create(TypeConverter::getInstance()->coreGameModeToProtocol($mode))); if($this->player !== null){ @@ -939,8 +944,8 @@ class NetworkSession{ $world = $this->player->getWorld(); $this->syncWorldTime($world->getTime()); $this->syncWorldDifficulty($world->getDifficulty()); + $this->syncWorldSpawnPoint($world->getSpawnLocation()); //TODO: weather needs to be synced here (when implemented) - //TODO: world spawn needs to be synced here } } From 5b26abcb0ec730334e46b326a2d17e91a9e205c0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Oct 2021 01:02:15 +0100 Subject: [PATCH 2905/3224] NetworkSession: fixed code copy pasta these are not, in fact, equivalent. --- src/network/mcpe/NetworkSession.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index abf2a7c77d..be4ea440a2 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -757,8 +757,7 @@ class NetworkSession{ } public function syncWorldSpawnPoint(Position $newSpawn) : void{ - [$x, $y, $z] = [$newSpawn->getFloorX(), $newSpawn->getFloorY(), $newSpawn->getFloorZ()]; - $this->sendDataPacket(SetSpawnPositionPacket::worldSpawn($x, $y, $z, DimensionIds::OVERWORLD, $x, $y, $z)); + $this->sendDataPacket(SetSpawnPositionPacket::worldSpawn($newSpawn->getFloorX(), $newSpawn->getFloorY(), $newSpawn->getFloorZ(), DimensionIds::OVERWORLD)); } public function syncGameMode(GameMode $mode, bool $isRollback = false) : void{ From 7d06b76aafce64f6d0121b41eb6a4a6f6ef69824 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Oct 2021 18:36:00 +0100 Subject: [PATCH 2906/3224] PluginManager: account for possible invalid format of API version we're seeing a lot of crashes because of this. --- resources/locale | 2 +- src/lang/KnownTranslationFactory.php | 6 ++++++ src/lang/KnownTranslationKeys.php | 1 + src/plugin/PluginManager.php | 11 +++++++++++ src/utils/VersionString.php | 4 ++++ 5 files changed, 23 insertions(+), 1 deletion(-) diff --git a/resources/locale b/resources/locale index cb47518ae3..cf184a00f8 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit cb47518ae37ce834b612b2efe2df841852d07a31 +Subproject commit cf184a00f886a49dd91c2acb69384c630d3ac102 diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index 9fc1fc67bc..c66c5e35d6 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -1734,6 +1734,12 @@ final class KnownTranslationFactory{ ]); } + public static function pocketmine_plugin_invalidAPI(Translatable|string $apiVersion) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_INVALIDAPI, [ + "apiVersion" => $apiVersion, + ]); + } + public static function pocketmine_plugin_load(Translatable|string $param0) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_LOAD, [ 0 => $param0, diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index 0814c5dddb..3171445beb 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -362,6 +362,7 @@ final class KnownTranslationKeys{ public const POCKETMINE_PLUGIN_INCOMPATIBLEOS = "pocketmine.plugin.incompatibleOS"; public const POCKETMINE_PLUGIN_INCOMPATIBLEPHPVERSION = "pocketmine.plugin.incompatiblePhpVersion"; public const POCKETMINE_PLUGIN_INCOMPATIBLEPROTOCOL = "pocketmine.plugin.incompatibleProtocol"; + public const POCKETMINE_PLUGIN_INVALIDAPI = "pocketmine.plugin.invalidAPI"; public const POCKETMINE_PLUGIN_LOAD = "pocketmine.plugin.load"; public const POCKETMINE_PLUGIN_LOADERROR = "pocketmine.plugin.loadError"; public const POCKETMINE_PLUGIN_RESTRICTEDNAME = "pocketmine.plugin.restrictedName"; diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index c646a4dffb..2ab6875250 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -40,6 +40,7 @@ use pocketmine\Server; use pocketmine\timings\TimingsHandler; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Utils; +use pocketmine\utils\VersionString; use Webmozart\PathUtil\Path; use function array_intersect; use function array_merge; @@ -268,6 +269,16 @@ class PluginManager{ continue; } + foreach($description->getCompatibleApis() as $api){ + if(!VersionString::isValidBaseVersion($api)){ + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( + $name, + KnownTranslationFactory::pocketmine_plugin_invalidAPI($api) + ))); + continue 2; + } + } + if(!ApiVersion::isCompatible($this->server->getApiVersion(), $description->getCompatibleApis())){ $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( $name, diff --git a/src/utils/VersionString.php b/src/utils/VersionString.php index 1dd666c9f1..7dae029b54 100644 --- a/src/utils/VersionString.php +++ b/src/utils/VersionString.php @@ -63,6 +63,10 @@ class VersionString{ $this->suffix = $matches[4] ?? ""; } + public static function isValidBaseVersion(string $baseVersion) : bool{ + return preg_match('/^\d+\.\d+\.\d+(?:-(.*))?$/', $baseVersion, $matches) === 1; + } + public function getNumber() : int{ return (($this->major << 9) | ($this->minor << 5) | $this->patch); } From 2db79cf58d5a66cc2ff280e4d5430799f8d45a46 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Oct 2021 18:41:47 +0100 Subject: [PATCH 2907/3224] Fix build --- src/lang/KnownTranslationFactory.php | 6 ++++++ src/lang/KnownTranslationKeys.php | 1 + 2 files changed, 7 insertions(+) diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index c66c5e35d6..e4aea7df66 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -1109,6 +1109,12 @@ final class KnownTranslationFactory{ return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_ENCHANT_DESCRIPTION, []); } + public static function pocketmine_command_error_playerNotFound(Translatable|string $playerName) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_ERROR_PLAYERNOTFOUND, [ + "playerName" => $playerName, + ]); + } + public static function pocketmine_command_exception(Translatable|string $param0, Translatable|string $param1, Translatable|string $param2) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_EXCEPTION, [ 0 => $param0, diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index 3171445beb..4b8d87c640 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -244,6 +244,7 @@ final class KnownTranslationKeys{ public const POCKETMINE_COMMAND_DIFFICULTY_DESCRIPTION = "pocketmine.command.difficulty.description"; public const POCKETMINE_COMMAND_EFFECT_DESCRIPTION = "pocketmine.command.effect.description"; public const POCKETMINE_COMMAND_ENCHANT_DESCRIPTION = "pocketmine.command.enchant.description"; + public const POCKETMINE_COMMAND_ERROR_PLAYERNOTFOUND = "pocketmine.command.error.playerNotFound"; public const POCKETMINE_COMMAND_EXCEPTION = "pocketmine.command.exception"; public const POCKETMINE_COMMAND_GAMEMODE_DESCRIPTION = "pocketmine.command.gamemode.description"; public const POCKETMINE_COMMAND_GAMEMODE_FAILURE = "pocketmine.command.gamemode.failure"; From dbeaf27cb7485a422f1ab5a7748baf3a29639c8f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Oct 2021 19:09:22 +0100 Subject: [PATCH 2908/3224] Document that Item::setNamedTag() may cause NbtException to be thrown if the NBT is bogus for some reason in PM3, these kinds of bugs wouldn't show up until/unless the item NBT was actually used, but on PM4, we decode it ahead of time, so the errors always show up immediately. --- src/item/Item.php | 6 ++++++ src/item/ItemFactory.php | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/item/Item.php b/src/item/Item.php index b28bf90661..f37015ba90 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -37,6 +37,7 @@ use pocketmine\math\Vector3; use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\NBT; use pocketmine\nbt\NbtDataException; +use pocketmine\nbt\NbtException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ShortTag; @@ -240,6 +241,7 @@ class Item implements \JsonSerializable{ * Sets the Item's NBT from the supplied CompoundTag object. * * @return $this + * @throws NbtException */ public function setNamedTag(CompoundTag $tag) : Item{ if($tag->getCount() === 0){ @@ -255,6 +257,7 @@ class Item implements \JsonSerializable{ /** * Removes the Item's NBT. * @return $this + * @throws NbtException */ public function clearNamedTag() : Item{ $this->nbt = new CompoundTag(); @@ -262,6 +265,9 @@ class Item implements \JsonSerializable{ return $this; } + /** + * @throws NbtException + */ protected function deserializeCompoundTag(CompoundTag $tag) : void{ $this->customName = ""; $this->lore = []; diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 5fb7438a10..0e1a710ce5 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -41,6 +41,7 @@ use pocketmine\entity\Villager; use pocketmine\entity\Zombie; use pocketmine\inventory\ArmorInventory; use pocketmine\math\Vector3; +use pocketmine\nbt\NbtException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\utils\SingletonTrait; use pocketmine\world\World; @@ -444,6 +445,7 @@ class ItemFactory{ * Deserializes an item from the provided legacy ID, legacy meta, count and NBT. * * @throws \InvalidArgumentException + * @throws NbtException */ public function get(int $id, int $meta = 0, int $count = 1, ?CompoundTag $tags = null) : Item{ /** @var Item|null $item */ From fef8297907b22baec072708c162cf76aa0a1db89 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Oct 2021 19:09:46 +0100 Subject: [PATCH 2909/3224] GiveCommand: don't crash on bogus item NBT --- src/command/defaults/GiveCommand.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/command/defaults/GiveCommand.php b/src/command/defaults/GiveCommand.php index 34814f207c..8fd5c42983 100644 --- a/src/command/defaults/GiveCommand.php +++ b/src/command/defaults/GiveCommand.php @@ -32,6 +32,7 @@ use pocketmine\item\StringToItemParser; use pocketmine\lang\KnownTranslationFactory; use pocketmine\nbt\JsonNbtParser; use pocketmine\nbt\NbtDataException; +use pocketmine\nbt\NbtException; use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\TextFormat; use function array_slice; @@ -86,7 +87,12 @@ class GiveCommand extends VanillaCommand{ return true; } - $item->setNamedTag($tags); + try{ + $item->setNamedTag($tags); + }catch(NbtException $e){ + $sender->sendMessage(KnownTranslationFactory::commands_give_tagError($e->getMessage())); + return true; + } } //TODO: overflow From 817ab88c70b5bc574908e82f88284e81f5a91fe2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Oct 2021 19:10:55 +0100 Subject: [PATCH 2910/3224] Properly handle errors decoding network item NBT since the NBT is now decoded immediately now, any incorrect NBT will cause exceptions to be thrown that we weren't handling, causing server crashes. --- src/network/mcpe/convert/TypeConverter.php | 46 +++++++++++++------ .../mcpe/handler/InGamePacketHandler.php | 5 +- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index c523eac106..d878423f60 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -37,6 +37,7 @@ use pocketmine\item\Durable; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\ItemIds; +use pocketmine\nbt\NbtException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\network\mcpe\InventoryManager; @@ -183,6 +184,9 @@ class TypeConverter{ ); } + /** + * @throws TypeConversionException + */ public function netItemStackToCore(ItemStack $itemStack) : Item{ if($itemStack->getId() === 0){ return ItemFactory::getInstance()->get(ItemIds::AIR, 0, 0); @@ -214,12 +218,16 @@ class TypeConverter{ } } - return ItemFactory::getInstance()->get( - $id, - $meta, - $itemStack->getCount(), - $compound - ); + try{ + return ItemFactory::getInstance()->get( + $id, + $meta, + $itemStack->getCount(), + $compound + ); + }catch(NbtException $e){ + throw TypeConversionException::wrap($e, "Bad itemstack NBT data"); + } } /** @@ -239,15 +247,23 @@ class TypeConverter{ } /** - * @throws \UnexpectedValueException + * @throws TypeConversionException */ public function createInventoryAction(NetworkInventoryAction $action, Player $player, InventoryManager $inventoryManager) : ?InventoryAction{ if($action->oldItem->getItemStack()->equals($action->newItem->getItemStack())){ //filter out useless noise in 1.13 return null; } - $old = $this->netItemStackToCore($action->oldItem->getItemStack()); - $new = $this->netItemStackToCore($action->newItem->getItemStack()); + try{ + $old = $this->netItemStackToCore($action->oldItem->getItemStack()); + }catch(TypeConversionException $e){ + throw TypeConversionException::wrap($e, "Inventory action: oldItem"); + } + try{ + $new = $this->netItemStackToCore($action->newItem->getItemStack()); + }catch(TypeConversionException $e){ + throw TypeConversionException::wrap($e, "Inventory action: newItem"); + } switch($action->sourceType){ case NetworkInventoryAction::SOURCE_CONTAINER: if($action->windowId === ContainerIds::UI and $action->inventorySlot > 0){ @@ -273,7 +289,7 @@ class TypeConverter{ fn(Inventory $i) => $i instanceof LoomInventory); } if($mapped === null){ - throw new \UnexpectedValueException("Unmatched UI inventory slot offset $pSlot"); + throw new TypeConversionException("Unmatched UI inventory slot offset $pSlot"); } [$slot, $window] = $mapped; }else{ @@ -284,10 +300,10 @@ class TypeConverter{ return new SlotChangeAction($window, $slot, $old, $new); } - throw new \UnexpectedValueException("No open container with window ID $action->windowId"); + throw new TypeConversionException("No open container with window ID $action->windowId"); case NetworkInventoryAction::SOURCE_WORLD: if($action->inventorySlot !== NetworkInventoryAction::ACTION_MAGIC_SLOT_DROP_ITEM){ - throw new \UnexpectedValueException("Only expecting drop-item world actions from the client!"); + throw new TypeConversionException("Only expecting drop-item world actions from the client!"); } return new DropItemAction($new); @@ -298,7 +314,7 @@ class TypeConverter{ case NetworkInventoryAction::ACTION_MAGIC_SLOT_CREATIVE_CREATE_ITEM: return new CreateItemAction($old); default: - throw new \UnexpectedValueException("Unexpected creative action type $action->inventorySlot"); + throw new TypeConversionException("Unexpected creative action type $action->inventorySlot"); } case NetworkInventoryAction::SOURCE_TODO: @@ -310,9 +326,9 @@ class TypeConverter{ } //TODO: more stuff - throw new \UnexpectedValueException("No open container with window ID $action->windowId"); + throw new TypeConversionException("No open container with window ID $action->windowId"); default: - throw new \UnexpectedValueException("Unknown inventory source type $action->sourceType"); + throw new TypeConversionException("Unknown inventory source type $action->sourceType"); } } } diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index c36510d022..65d294ae8c 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -42,6 +42,7 @@ use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\convert\SkinAdapterSingleton; +use pocketmine\network\mcpe\convert\TypeConversionException; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\InventoryManager; use pocketmine\network\mcpe\NetworkSession; @@ -271,8 +272,8 @@ class InGamePacketHandler extends PacketHandler{ if($action !== null){ $actions[] = $action; } - }catch(\UnexpectedValueException $e){ - $this->session->getLogger()->debug("Unhandled inventory action: " . $e->getMessage()); + }catch(TypeConversionException $e){ + $this->session->getLogger()->debug("Error unpacking inventory action: " . $e->getMessage()); return false; } } From 13178a47a5eed4a72b7854c44134d5bbd12c6bf5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Oct 2021 19:11:10 +0100 Subject: [PATCH 2911/3224] fuck you git --- .../mcpe/convert/TypeConversionException.php | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/network/mcpe/convert/TypeConversionException.php diff --git a/src/network/mcpe/convert/TypeConversionException.php b/src/network/mcpe/convert/TypeConversionException.php new file mode 100644 index 0000000000..fb24fefd36 --- /dev/null +++ b/src/network/mcpe/convert/TypeConversionException.php @@ -0,0 +1,35 @@ +getMessage(), 0, $previous); + } +} From 7245d15abe045983588c7d812e79b2ba2020b458 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Oct 2021 19:57:26 +0100 Subject: [PATCH 2912/3224] PermissionParser: Throw more specific exceptions --- src/permission/PermissionParser.php | 7 +++-- src/permission/PermissionParserException.php | 31 ++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 src/permission/PermissionParserException.php diff --git a/src/permission/PermissionParser.php b/src/permission/PermissionParser.php index 7115a5536f..c7733a49cd 100644 --- a/src/permission/PermissionParser.php +++ b/src/permission/PermissionParser.php @@ -55,7 +55,7 @@ class PermissionParser{ /** * @param bool|string $value * - * @throws \InvalidArgumentException + * @throws PermissionParserException */ public static function defaultFromString($value) : string{ if(is_bool($value)){ @@ -70,7 +70,7 @@ class PermissionParser{ return self::DEFAULT_STRING_MAP[$lower]; } - throw new \InvalidArgumentException("Unknown permission default name \"$value\""); + throw new PermissionParserException("Unknown permission default name \"$value\""); } /** @@ -79,6 +79,7 @@ class PermissionParser{ * * @return Permission[][] * @phpstan-return array> + * @throws PermissionParserException */ public static function loadPermissions(array $data, string $default = self::DEFAULT_FALSE) : array{ $result = []; @@ -89,7 +90,7 @@ class PermissionParser{ } if(isset($entry["children"])){ - throw new \InvalidArgumentException("Nested permission declarations are no longer supported. Declare each permission separately."); + throw new PermissionParserException("Nested permission declarations are no longer supported. Declare each permission separately."); } if(isset($entry["description"])){ diff --git a/src/permission/PermissionParserException.php b/src/permission/PermissionParserException.php new file mode 100644 index 0000000000..a0231f8058 --- /dev/null +++ b/src/permission/PermissionParserException.php @@ -0,0 +1,31 @@ + Date: Tue, 5 Oct 2021 20:28:43 +0100 Subject: [PATCH 2913/3224] Gracefully handle errors loading plugin manifest this isn't perfect, but it covers the common cases. Now, the server won't spam crashdumps just because some plugin declared nested permissions. --- src/lang/KnownTranslationFactory.php | 6 ++++++ src/lang/KnownTranslationKeys.php | 1 + src/plugin/PluginDescription.php | 15 ++++++++++----- src/plugin/PluginLoader.php | 1 + src/plugin/PluginManager.php | 7 +++++++ 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index e4aea7df66..756d623de5 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -1746,6 +1746,12 @@ final class KnownTranslationFactory{ ]); } + public static function pocketmine_plugin_invalidManifest(Translatable|string $details) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_INVALIDMANIFEST, [ + "details" => $details, + ]); + } + public static function pocketmine_plugin_load(Translatable|string $param0) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_LOAD, [ 0 => $param0, diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index 4b8d87c640..7f1eb2658d 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -364,6 +364,7 @@ final class KnownTranslationKeys{ public const POCKETMINE_PLUGIN_INCOMPATIBLEPHPVERSION = "pocketmine.plugin.incompatiblePhpVersion"; public const POCKETMINE_PLUGIN_INCOMPATIBLEPROTOCOL = "pocketmine.plugin.incompatibleProtocol"; public const POCKETMINE_PLUGIN_INVALIDAPI = "pocketmine.plugin.invalidAPI"; + public const POCKETMINE_PLUGIN_INVALIDMANIFEST = "pocketmine.plugin.invalidManifest"; public const POCKETMINE_PLUGIN_LOAD = "pocketmine.plugin.load"; public const POCKETMINE_PLUGIN_LOADERROR = "pocketmine.plugin.loadError"; public const POCKETMINE_PLUGIN_RESTRICTEDNAME = "pocketmine.plugin.restrictedName"; diff --git a/src/plugin/PluginDescription.php b/src/plugin/PluginDescription.php index 9ae463093d..090be61b1b 100644 --- a/src/plugin/PluginDescription.php +++ b/src/plugin/PluginDescription.php @@ -25,6 +25,7 @@ namespace pocketmine\plugin; use pocketmine\permission\Permission; use pocketmine\permission\PermissionParser; +use pocketmine\permission\PermissionParserException; use function array_map; use function array_values; use function is_array; @@ -99,20 +100,20 @@ class PluginDescription{ /** * @param mixed[] $plugin - * @throws PluginException + * @throws PluginDescriptionParseException */ private function loadMap(array $plugin) : void{ $this->map = $plugin; $this->name = $plugin["name"]; if(preg_match('/^[A-Za-z0-9 _.-]+$/', $this->name) === 0){ - throw new PluginException("Invalid Plugin name"); + throw new PluginDescriptionParseException("Invalid Plugin name"); } $this->name = str_replace(" ", "_", $this->name); $this->version = (string) $plugin["version"]; $this->main = $plugin["main"]; if(stripos($this->main, "pocketmine\\") === 0){ - throw new PluginException("Invalid Plugin main, cannot start within the PocketMine namespace"); + throw new PluginDescriptionParseException("Invalid Plugin main, cannot start within the PocketMine namespace"); } $this->srcNamespacePrefix = $plugin["src-namespace-prefix"] ?? ""; @@ -153,7 +154,7 @@ class PluginDescription{ if(isset($plugin["load"])){ $order = PluginEnableOrder::fromString($plugin["load"]); if($order === null){ - throw new PluginException("Invalid Plugin \"load\""); + throw new PluginDescriptionParseException("Invalid Plugin \"load\""); } $this->order = $order; }else{ @@ -175,7 +176,11 @@ class PluginDescription{ } if(isset($plugin["permissions"])){ - $this->permissions = PermissionParser::loadPermissions($plugin["permissions"]); + try{ + $this->permissions = PermissionParser::loadPermissions($plugin["permissions"]); + }catch(PermissionParserException $e){ + throw new PluginDescriptionParseException("Invalid Plugin \"permissions\": " . $e->getMessage(), 0, $e); + } } } diff --git a/src/plugin/PluginLoader.php b/src/plugin/PluginLoader.php index 2bf603ddeb..7e4787fa6d 100644 --- a/src/plugin/PluginLoader.php +++ b/src/plugin/PluginLoader.php @@ -40,6 +40,7 @@ interface PluginLoader{ /** * Gets the PluginDescription from the file + * @throws PluginDescriptionParseException */ public function getPluginDescription(string $file) : ?PluginDescription; diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 2ab6875250..3a58e3bc46 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -246,6 +246,13 @@ class PluginManager{ } try{ $description = $loader->getPluginDescription($file); + }catch(PluginDescriptionParseException $e){ + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_fileError( + $file, + $directory, + KnownTranslationFactory::pocketmine_plugin_invalidManifest($e->getMessage()) + ))); + continue; }catch(\RuntimeException $e){ //TODO: more specific exception handling $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_fileError($file, $directory, $e->getMessage()))); $this->server->getLogger()->logException($e); From fec48003d92297e4b9f66e0b611ea789c687efa9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Oct 2021 20:29:24 +0100 Subject: [PATCH 2914/3224] ..... --- resources/locale | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/locale b/resources/locale index cf184a00f8..dcfe3ff188 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit cf184a00f886a49dd91c2acb69384c630d3ac102 +Subproject commit dcfe3ff1888b2d3adecc00c14870717ed55824cc From a101d1cdf90c4d855bf43f756efeeb56442b1b03 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 5 Oct 2021 23:31:00 +0100 Subject: [PATCH 2915/3224] Drop pocketmine.plugin.fileError in favour of pocketmine.plugin.loadError fileError was unnecessarily noisy, putting the directory path on the console twice. This conveys just as much information but with less wasted space. --- resources/locale | 2 +- src/lang/KnownTranslationFactory.php | 8 -------- src/lang/KnownTranslationKeys.php | 1 - src/plugin/PluginManager.php | 5 ++--- 4 files changed, 3 insertions(+), 13 deletions(-) diff --git a/resources/locale b/resources/locale index dcfe3ff188..c940b9f171 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit dcfe3ff1888b2d3adecc00c14870717ed55824cc +Subproject commit c940b9f17188548f78d0dc5fdd4e607c703b7952 diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index 756d623de5..43d3ce3b17 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -1702,14 +1702,6 @@ final class KnownTranslationFactory{ ]); } - public static function pocketmine_plugin_fileError(Translatable|string $param0, Translatable|string $param1, Translatable|string $param2) : Translatable{ - return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_FILEERROR, [ - 0 => $param0, - 1 => $param1, - 2 => $param2, - ]); - } - public static function pocketmine_plugin_genericLoadError(Translatable|string $param0) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_GENERICLOADERROR, [ 0 => $param0, diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index 7f1eb2658d..e4301fa247 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -357,7 +357,6 @@ final class KnownTranslationKeys{ public const POCKETMINE_PLUGIN_DISABLE = "pocketmine.plugin.disable"; public const POCKETMINE_PLUGIN_DUPLICATEERROR = "pocketmine.plugin.duplicateError"; public const POCKETMINE_PLUGIN_ENABLE = "pocketmine.plugin.enable"; - public const POCKETMINE_PLUGIN_FILEERROR = "pocketmine.plugin.fileError"; public const POCKETMINE_PLUGIN_GENERICLOADERROR = "pocketmine.plugin.genericLoadError"; public const POCKETMINE_PLUGIN_INCOMPATIBLEAPI = "pocketmine.plugin.incompatibleAPI"; public const POCKETMINE_PLUGIN_INCOMPATIBLEOS = "pocketmine.plugin.incompatibleOS"; diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 3a58e3bc46..1e849bc530 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -247,14 +247,13 @@ class PluginManager{ try{ $description = $loader->getPluginDescription($file); }catch(PluginDescriptionParseException $e){ - $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_fileError( + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( $file, - $directory, KnownTranslationFactory::pocketmine_plugin_invalidManifest($e->getMessage()) ))); continue; }catch(\RuntimeException $e){ //TODO: more specific exception handling - $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_fileError($file, $directory, $e->getMessage()))); + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError($file, $e->getMessage()))); $this->server->getLogger()->logException($e); continue; } From 5061bbbc25797c1b5efc04202f0d47fec7c7676f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 Oct 2021 01:01:20 +0100 Subject: [PATCH 2916/3224] fuck you git x2 --- .../PluginDescriptionParseException.php | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/plugin/PluginDescriptionParseException.php diff --git a/src/plugin/PluginDescriptionParseException.php b/src/plugin/PluginDescriptionParseException.php new file mode 100644 index 0000000000..ad98342f08 --- /dev/null +++ b/src/plugin/PluginDescriptionParseException.php @@ -0,0 +1,31 @@ + Date: Wed, 6 Oct 2021 01:12:02 +0100 Subject: [PATCH 2917/3224] PluginBase: remove special true/false handling for command permissions these aren't accepted as permission names anymore, and they never worked properly anyway. --- src/plugin/PluginBase.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/plugin/PluginBase.php b/src/plugin/PluginBase.php index ac7b0036f1..c4fd5bb6b1 100644 --- a/src/plugin/PluginBase.php +++ b/src/plugin/PluginBase.php @@ -195,9 +195,7 @@ abstract class PluginBase implements Plugin, CommandExecutor{ } if(isset($data["permission"])){ - if(is_bool($data["permission"])){ - $newCmd->setPermission($data["permission"] ? "true" : "false"); - }elseif(is_string($data["permission"])){ + if(is_string($data["permission"])){ $newCmd->setPermission($data["permission"]); }else{ $this->logger->error("Permission must be a string, " . gettype($data["permission"]) . " given for command $key"); From 31a176286d7a33306f8ce8457fa64fed5a2b4d75 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 Oct 2021 01:18:14 +0100 Subject: [PATCH 2918/3224] Do not register plugin commands without valid permissions this could lead to harmful results, e.g. if a developer typo'd while writing the plugin.yml, an admin-only command could become accessible to everyone, since commands are by default accessible by everyone. --- src/plugin/PluginBase.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugin/PluginBase.php b/src/plugin/PluginBase.php index c4fd5bb6b1..d5460cf37d 100644 --- a/src/plugin/PluginBase.php +++ b/src/plugin/PluginBase.php @@ -199,7 +199,11 @@ abstract class PluginBase implements Plugin, CommandExecutor{ $newCmd->setPermission($data["permission"]); }else{ $this->logger->error("Permission must be a string, " . gettype($data["permission"]) . " given for command $key"); + continue; } + }else{ + $this->logger->error("No permission set for command $key"); + continue; } if(isset($data["permission-message"])){ From d07517fe8bcdf4da75471fafffa9d747eafbf1d6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 Oct 2021 01:42:03 +0100 Subject: [PATCH 2919/3224] Use an object to represent command entries in plugin manifest --- src/plugin/PluginBase.php | 61 +++++++------------- src/plugin/PluginDescription.php | 28 +++++++-- src/plugin/PluginDescriptionCommandEntry.php | 53 +++++++++++++++++ 3 files changed, 98 insertions(+), 44 deletions(-) create mode 100644 src/plugin/PluginDescriptionCommandEntry.php diff --git a/src/plugin/PluginBase.php b/src/plugin/PluginBase.php index d5460cf37d..db29c40da2 100644 --- a/src/plugin/PluginBase.php +++ b/src/plugin/PluginBase.php @@ -38,10 +38,6 @@ use function dirname; use function fclose; use function file_exists; use function fopen; -use function gettype; -use function is_array; -use function is_bool; -use function is_string; use function mkdir; use function rtrim; use function stream_copy_to_stream; @@ -171,47 +167,34 @@ abstract class PluginBase implements Plugin, CommandExecutor{ $this->logger->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_commandError($key, $this->getDescription()->getFullName()))); continue; } - if(is_array($data)){ //TODO: error out if it isn't - $newCmd = new PluginCommand($key, $this, $this); - if(isset($data["description"])){ - $newCmd->setDescription($data["description"]); - } - if(isset($data["usage"])){ - $newCmd->setUsage($data["usage"]); - } + $newCmd = new PluginCommand($key, $this, $this); + if(($description = $data->getDescription()) !== null){ + $newCmd->setDescription($description); + } - if(isset($data["aliases"]) and is_array($data["aliases"])){ - $aliasList = []; - foreach($data["aliases"] as $alias){ - if(strpos($alias, ":") !== false){ - $this->logger->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_aliasError($alias, $this->getDescription()->getFullName()))); - continue; - } - $aliasList[] = $alias; - } + if(($usageMessage = $data->getUsageMessage()) !== null){ + $newCmd->setUsage($usageMessage); + } - $newCmd->setAliases($aliasList); - } - - if(isset($data["permission"])){ - if(is_string($data["permission"])){ - $newCmd->setPermission($data["permission"]); - }else{ - $this->logger->error("Permission must be a string, " . gettype($data["permission"]) . " given for command $key"); - continue; - } - }else{ - $this->logger->error("No permission set for command $key"); + $aliasList = []; + foreach($data->getAliases() as $alias){ + if(strpos($alias, ":") !== false){ + $this->logger->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_aliasError($alias, $this->getDescription()->getFullName()))); continue; } - - if(isset($data["permission-message"])){ - $newCmd->setPermissionMessage($data["permission-message"]); - } - - $pluginCmds[] = $newCmd; + $aliasList[] = $alias; } + + $newCmd->setAliases($aliasList); + + $newCmd->setPermission($data->getPermission()); + + if(($permissionDeniedMessage = $data->getPermissionDeniedMessage()) !== null){ + $newCmd->setPermissionMessage($permissionDeniedMessage); + } + + $pluginCmds[] = $newCmd; } if(count($pluginCmds) > 0){ diff --git a/src/plugin/PluginDescription.php b/src/plugin/PluginDescription.php index 090be61b1b..0e34da74af 100644 --- a/src/plugin/PluginDescription.php +++ b/src/plugin/PluginDescription.php @@ -29,6 +29,7 @@ use pocketmine\permission\PermissionParserException; use function array_map; use function array_values; use function is_array; +use function is_string; use function phpversion; use function preg_match; use function str_replace; @@ -70,8 +71,8 @@ class PluginDescription{ /** @var string */ private $version; /** - * @var mixed[][] - * @phpstan-var array> + * @var PluginDescriptionCommandEntry[] + * @phpstan-var array */ private $commands = []; /** @var string */ @@ -123,7 +124,24 @@ class PluginDescription{ $this->compatibleOperatingSystems = array_map("\strval", (array) ($plugin["os"] ?? [])); if(isset($plugin["commands"]) and is_array($plugin["commands"])){ - $this->commands = $plugin["commands"]; + foreach($plugin["commands"] as $commandName => $commandData){ + if(!is_string($commandName)){ + throw new PluginDescriptionParseException("Invalid Plugin commands, key must be the name of the command"); + } + if(!is_array($commandData)){ + throw new PluginDescriptionParseException("Command $commandName has invalid properties"); + } + if(!isset($commandData["permission"]) || !is_string($commandData["permission"])){ + throw new PluginDescriptionParseException("Command $commandName does not have a permission set"); + } + $this->commands[$commandName] = new PluginDescriptionCommandEntry( + $commandData["description"] ?? null, + $commandData["usage"] ?? null, + $commandData["aliases"] ?? [], + $commandData["permission"], + $commandData["permission-message"] ?? null + ); + } } if(isset($plugin["depend"])){ @@ -221,8 +239,8 @@ class PluginDescription{ } /** - * @return mixed[][] - * @phpstan-return array> + * @return PluginDescriptionCommandEntry[] + * @phpstan-return array */ public function getCommands() : array{ return $this->commands; diff --git a/src/plugin/PluginDescriptionCommandEntry.php b/src/plugin/PluginDescriptionCommandEntry.php new file mode 100644 index 0000000000..b9b618e8a8 --- /dev/null +++ b/src/plugin/PluginDescriptionCommandEntry.php @@ -0,0 +1,53 @@ + $aliases + */ + public function __construct( + private ?string $description, + private ?string $usageMessage, + private array $aliases, + private string $permission, + private ?string $permissionDeniedMessage, + ){} + + public function getDescription() : ?string{ return $this->description; } + + public function getUsageMessage() : ?string{ return $this->usageMessage; } + + /** + * @return string[] + * @phpstan-return list + */ + public function getAliases() : array{ return $this->aliases; } + + public function getPermission() : string{ return $this->permission; } + + public function getPermissionDeniedMessage() : ?string{ return $this->permissionDeniedMessage; } +} From 258c38f9cd55c2f84c33b8f9d98d86cc35288b23 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 Oct 2021 01:45:40 +0100 Subject: [PATCH 2920/3224] PluginDescription: loosen invalid permission message (it might be wrong type as well as not existing) --- src/plugin/PluginDescription.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugin/PluginDescription.php b/src/plugin/PluginDescription.php index 0e34da74af..889823d845 100644 --- a/src/plugin/PluginDescription.php +++ b/src/plugin/PluginDescription.php @@ -132,7 +132,7 @@ class PluginDescription{ throw new PluginDescriptionParseException("Command $commandName has invalid properties"); } if(!isset($commandData["permission"]) || !is_string($commandData["permission"])){ - throw new PluginDescriptionParseException("Command $commandName does not have a permission set"); + throw new PluginDescriptionParseException("Command $commandName does not have a valid permission set"); } $this->commands[$commandName] = new PluginDescriptionCommandEntry( $commandData["description"] ?? null, From 10b3596eef37d84eaaac312b792dac5bf3e9ae5d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 Oct 2021 02:00:55 +0100 Subject: [PATCH 2921/3224] PluginDescription: use typed properties --- src/plugin/PluginDescription.php | 43 +++++++++++++------------------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/src/plugin/PluginDescription.php b/src/plugin/PluginDescription.php index 889823d845..895097cb5d 100644 --- a/src/plugin/PluginDescription.php +++ b/src/plugin/PluginDescription.php @@ -44,53 +44,46 @@ class PluginDescription{ * @var mixed[] * @phpstan-var array */ - private $map; + private array $map; - /** @var string */ - private $name; - /** @var string */ - private $main; + private string $name; + private string $main; private string $srcNamespacePrefix = ""; /** @var string[] */ - private $api; + private array $api; /** @var int[] */ - private $compatibleMcpeProtocols = []; + private array $compatibleMcpeProtocols = []; /** @var string[] */ - private $compatibleOperatingSystems = []; + private array $compatibleOperatingSystems = []; /** * @var string[][] * @phpstan-var array> */ - private $extensions = []; + private array $extensions = []; /** @var string[] */ - private $depend = []; + private array $depend = []; /** @var string[] */ - private $softDepend = []; + private array $softDepend = []; /** @var string[] */ - private $loadBefore = []; - /** @var string */ - private $version; + private array $loadBefore = []; + private string $version; /** * @var PluginDescriptionCommandEntry[] * @phpstan-var array */ - private $commands = []; - /** @var string */ - private $description = ""; + private array $commands = []; + private string $description = ""; /** @var string[] */ - private $authors = []; - /** @var string */ - private $website = ""; - /** @var string */ - private $prefix = ""; - /** @var PluginEnableOrder */ - private $order; + private array $authors = []; + private string $website = ""; + private string $prefix = ""; + private PluginEnableOrder $order; /** * @var Permission[][] * @phpstan-var array> */ - private $permissions = []; + private array $permissions = []; /** * @param string|mixed[] $yamlString From 4b00465e2435ad8115c3bb44683937e1fcf43b31 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 Oct 2021 02:14:30 +0100 Subject: [PATCH 2922/3224] Clean PHPStan baselines --- .../configs/check-explicit-mixed-baseline.neon | 15 --------------- tests/phpstan/configs/l7-baseline.neon | 5 ----- tests/phpstan/configs/runtime-type-checks.neon | 5 ----- 3 files changed, 25 deletions(-) diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index 56654cf262..cffdf0a1c7 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -80,21 +80,6 @@ parameters: count: 1 path: ../../../src/permission/PermissionParser.php - - - message: "#^Parameter \\#1 \\$description of method pocketmine\\\\command\\\\Command\\:\\:setDescription\\(\\) expects pocketmine\\\\lang\\\\Translatable\\|string, mixed given\\.$#" - count: 1 - path: ../../../src/plugin/PluginBase.php - - - - message: "#^Parameter \\#1 \\$permissionMessage of method pocketmine\\\\command\\\\Command\\:\\:setPermissionMessage\\(\\) expects string, mixed given\\.$#" - count: 1 - path: ../../../src/plugin/PluginBase.php - - - - message: "#^Parameter \\#1 \\$usage of method pocketmine\\\\command\\\\Command\\:\\:setUsage\\(\\) expects pocketmine\\\\lang\\\\Translatable\\|string, mixed given\\.$#" - count: 1 - path: ../../../src/plugin/PluginBase.php - - message: "#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#" count: 1 diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index ae390b9deb..4cd255836a 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -35,11 +35,6 @@ parameters: count: 1 path: ../../../src/PocketMine.php - - - message: "#^Parameter \\#1 \\$path of function realpath expects string, array\\\\|string\\|false given\\.$#" - count: 1 - path: ../../../src/PocketMine.php - - message: "#^Parameter \\#1 \\$path of function realpath expects string, string\\|false given\\.$#" count: 2 diff --git a/tests/phpstan/configs/runtime-type-checks.neon b/tests/phpstan/configs/runtime-type-checks.neon index 12e59f585a..fb1e456b78 100644 --- a/tests/phpstan/configs/runtime-type-checks.neon +++ b/tests/phpstan/configs/runtime-type-checks.neon @@ -10,8 +10,3 @@ parameters: count: 1 path: ../../../src/network/mcpe/handler/InGamePacketHandler.php - - - message: "#^Call to function is_array\\(\\) with array\\ will always evaluate to true\\.$#" - count: 1 - path: ../../../src/plugin/PluginBase.php - From 90800a4124f99b11ad7d609d4b8b78cc311cd585 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 Oct 2021 21:07:57 +0100 Subject: [PATCH 2923/3224] Config: Try to coerce types, similar to YAML --- src/utils/Config.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/utils/Config.php b/src/utils/Config.php index 841b7f860a..2e10ad5e20 100644 --- a/src/utils/Config.php +++ b/src/utils/Config.php @@ -557,6 +557,13 @@ class Config{ case "no": $v = false; break; + default: + $v = match($v){ + (string) ((int) $v) => (int) $v, + (string) ((float) $v) => (float) $v, + default => $v, + }; + break; } if(isset($result[$k])){ \GlobalLogger::get()->debug("[Config] Repeated property " . $k . " on file " . $this->file); From 8e3772ceef672b406cb75676e6c74ccc01327dbd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 Oct 2021 23:16:03 +0100 Subject: [PATCH 2924/3224] Block: fixed incorrect behaviour of isSameState() for multi-ID blocks fixes #4492 --- src/block/Block.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/Block.php b/src/block/Block.php index 7006db1ca3..1ef2ccee06 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -179,7 +179,7 @@ class Block{ * Returns whether the given block has the same type and properties as this block. */ public function isSameState(Block $other) : bool{ - return $this->isSameType($other) and $this->writeStateToMeta() === $other->writeStateToMeta(); + return $this->getFullId() === $other->getFullId(); } /** From 9e6d7405709560c0025e072324602983213276dd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 Oct 2021 23:49:13 +0100 Subject: [PATCH 2925/3224] Release 4.0.0-BETA4 --- changelogs/4.0.md | 59 +++++++++++++++++++++++++++++++++++++++++++++ src/VersionInfo.php | 4 +-- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index 6445506572..0f38515436 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1332,3 +1332,62 @@ Released 10th September 2021. - `Liquid->getMinAdjacentSourcesToFormSource()`: returns how many adjacent source blocks of the same liquid must be present in order for the current block to become a source itself - `Player->getPlayerInfo()` - `Liquid` minimum-cost flow calculation code has been extracted to `MinimumCostFlowCalculator`. + +# 4.0.0-BETA4 +Released 6th October 2021. + +## General +- Improved performance of lighting calculation by avoiding copies of useless data from the main thread. +- Resource pack loading now accepts `dependencies` and `capabilities` fields in the `manifest.json` (although it doesn't currently check them). +- `/help` is now localized according to language set in `server.properties`. +- Various messages related to world loading, generation and conversion are now localized according to the language set in `server.properties`. +- Compasses now point to the correct (current) world's spawn point after teleporting players to a different world. Previously, they would continue to point to the spawn of the world that the player initially spawned in. +- The `--bootstrap` CLI option has been removed. +- RakLib 0.14.2 is now required. This fixes the following issues: + - Fixed incorrect handling of sessions on client disconnect (leading to timeout debug messages). + - Fixed transferring players often not working correctly. + - Fixed disconnect screens sometimes not displaying. + +## Fixes +- Fixed server crash when UPnP encounters an error. +- Fixed server crash when clients sent items with bad NBT in inventory transactions. +- Fixed server crash when loading a plugin with legacy nested permission structure (now the plugin will fail to load, but the server won't crash). +- Fixed server crash when using `/give` with bad NBT on any item. +- Fixed server crash when loading a plugin with improperly formatted API version (now the plugin will fail to load, but the server won't crash). +- Fixed server crash when changing player gamemode during `PlayerLoginEvent`. +- Incorrect structure of `commands` in plugin manifest is now detected earlier and handled more gracefully. +- Fixed console reader subprocess lingering on server crash on Windows and screwing up the terminal. +- Fixed `Player` object memory leak when kicking players during `PlayerLoginEvent` (this caused the `World` to report warnings about leaked entities on shutdown). +- Fixed `Projectile->move()` ignoring the `dx`/`dy`/`dz` parameters given and using its own `motion` instead. +- Fixed `BlockFactory->get()` erroneously accepting meta values of `16`. +- Fixed `Block->isSameState()` false negatives for some types of slabs. +- Fixed being unable to place slabs of the same type on top of each other to create double slabs. + +## API changes +- Plugin commands in `plugin.yml` must now declare `permission` for each command. Previously, the `permission` key was optional, causing anyone to be able to use the command. + - This behaviour was removed because of the potential for security issues - a typo in `plugin.yml` could lead to dangerous functionality being exposed to everyone. + - If you want to make a command that everyone can use, declare a permission with a `default` of `true` and assign it to the command. +- Plugin permissions in `plugin.yml` must now declare `default` for each permission. Previously, the `default` key was optional, causing the permission to silently be denied to everyone (PM4) or granted to ops implicitly (PM3). + +### Block +- Added the following classes: + - `pocketmine\block\utils\LeverFacing` +- Added the following API methods: + - `pocketmine\block\Lever->isActivated()` + - `pocketmine\block\Lever->setActivated()` + - `pocketmine\block\Lever->getFacing()` + - `pocketmine\block\Lever->setFacing()` + +### World +- The following API methods have signature changes: + - `Chunk->getSubChunks()` now returns `array` instead of `SplFixedArray`. +- The following API methods have been removed: + - `FastChunkSerializer::serialize()` + - `FastChunkSerializer::deserialize()` +- The following API methods have been added: + - `FastChunkSerializer::serializeTerrain()`: serializes blocks and biomes only + - `FastChunkSerializer::deserializeTerrain()`: deserializes the output of `serializeTerrain()` + +### Utils +- The following API methods have signature changes: + - `Process::kill()` now requires an additional `bool $subprocesses` parameter. diff --git a/src/VersionInfo.php b/src/VersionInfo.php index dedf0f3ae5..2bebe456a0 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -30,9 +30,9 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; public const BASE_VERSION = "4.0.0-BETA4"; - public const IS_DEVELOPMENT_BUILD = true; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_NUMBER = 0; - public const BUILD_CHANNEL = ""; + public const BUILD_CHANNEL = "beta"; private function __construct(){ //NOOP From 847e24fc41852510e7d2c5928a125d370a5b2873 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 6 Oct 2021 23:49:30 +0100 Subject: [PATCH 2926/3224] 4.0.0-BETA5 is next --- src/VersionInfo.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 2bebe456a0..8b9fb420b5 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -29,10 +29,10 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "4.0.0-BETA4"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "4.0.0-BETA5"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_NUMBER = 0; - public const BUILD_CHANNEL = "beta"; + public const BUILD_CHANNEL = ""; private function __construct(){ //NOOP From dc2e8e7e8f13e23882c4df27ac0d1b397f7746b1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 7 Oct 2021 20:02:21 +0100 Subject: [PATCH 2927/3224] ServerConfigGroup: do not assume that values are always bool|string --- src/ServerConfigGroup.php | 18 +++++++++++------- .../configs/check-explicit-mixed-baseline.neon | 5 ----- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/ServerConfigGroup.php b/src/ServerConfigGroup.php index 1965e0d7fb..37df7e9a79 100644 --- a/src/ServerConfigGroup.php +++ b/src/ServerConfigGroup.php @@ -110,16 +110,20 @@ final class ServerConfigGroup{ }else{ $value = $this->serverProperties->exists($variable) ? $this->serverProperties->get($variable) : $defaultValue; } - if(is_bool($value)){ return $value; } - switch(strtolower($value)){ - case "on": - case "true": - case "1": - case "yes": - return true; + if(is_int($value)){ + return $value !== 0; + } + if(is_string($value)){ + switch(strtolower($value)){ + case "on": + case "true": + case "1": + case "yes": + return true; + } } return false; diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index cffdf0a1c7..cb0893173a 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -40,11 +40,6 @@ parameters: count: 2 path: ../../../src/ServerConfigGroup.php - - - message: "#^Parameter \\#1 \\$string of function strtolower expects string, mixed given\\.$#" - count: 1 - path: ../../../src/ServerConfigGroup.php - - message: "#^Cannot access offset 'git' on mixed\\.$#" count: 2 From 32fd9879e5ab8b58d82f2ec30a5c55a6188aea0f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 7 Oct 2021 20:16:54 +0100 Subject: [PATCH 2928/3224] fix CS --- src/ServerConfigGroup.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ServerConfigGroup.php b/src/ServerConfigGroup.php index 37df7e9a79..f69990cf85 100644 --- a/src/ServerConfigGroup.php +++ b/src/ServerConfigGroup.php @@ -27,6 +27,8 @@ use pocketmine\utils\Config; use function array_key_exists; use function getopt; use function is_bool; +use function is_int; +use function is_string; use function strtolower; final class ServerConfigGroup{ From 1be9b2f037ba446c003b14c661bb959c1ddf9f1d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 7 Oct 2021 20:30:56 +0100 Subject: [PATCH 2929/3224] Config: drop packing of arrays we don't handle arrays on decode, so there's no reason to support them on encode either. --- src/utils/Config.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/utils/Config.php b/src/utils/Config.php index 2e10ad5e20..db0b8c464f 100644 --- a/src/utils/Config.php +++ b/src/utils/Config.php @@ -529,8 +529,6 @@ class Config{ foreach($this->config as $k => $v){ if(is_bool($v)){ $v = $v ? "on" : "off"; - }elseif(is_array($v)){ - $v = implode(";", $v); } $content .= $k . "=" . $v . "\r\n"; } From a555f21b181dcc889e1c8749e551d8587717df38 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 7 Oct 2021 20:32:02 +0100 Subject: [PATCH 2930/3224] MainLogger: write messages before calling logger attachments --- src/utils/MainLogger.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/utils/MainLogger.php b/src/utils/MainLogger.php index ebce6012ed..29c64e974e 100644 --- a/src/utils/MainLogger.php +++ b/src/utils/MainLogger.php @@ -244,12 +244,11 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ $this->synchronized(function() use ($message, $level, $time) : void{ Terminal::writeLine($message); + $this->logWriterThread->write($time->format("Y-m-d") . " " . TextFormat::clean($message) . PHP_EOL); foreach($this->attachments as $attachment){ $attachment->call($level, $message); } - - $this->logWriterThread->write($time->format("Y-m-d") . " " . TextFormat::clean($message) . PHP_EOL); }); } From dd0aaf59b5a269259cd2f922ca3f7d2bad8a3d06 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 7 Oct 2021 20:40:20 +0100 Subject: [PATCH 2931/3224] MainLogger: Log exceptions as a single block message --- src/utils/MainLogger.php | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/utils/MainLogger.php b/src/utils/MainLogger.php index 29c64e974e..b5b9dd7ef1 100644 --- a/src/utils/MainLogger.php +++ b/src/utils/MainLogger.php @@ -140,18 +140,20 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ $trace = $e->getTrace(); } - $this->buffer(function() use ($e, $trace) : void{ - $this->critical(self::printExceptionMessage($e)); - foreach(Utils::printableTrace($trace) as $line){ - $this->critical($line); + $lines = [self::printExceptionMessage($e)]; + $lines[] = "--- Stack trace ---"; + foreach(Utils::printableTrace($trace) as $line){ + $lines[] = " " . $line; + } + for($prev = $e->getPrevious(); $prev !== null; $prev = $prev->getPrevious()){ + $lines[] = "--- Previous ---"; + $lines[] = self::printExceptionMessage($prev); + foreach(Utils::printableTrace($prev->getTrace()) as $line){ + $lines[] = " " . $line; } - for($prev = $e->getPrevious(); $prev !== null; $prev = $prev->getPrevious()){ - $this->critical("Previous: " . self::printExceptionMessage($prev)); - foreach(Utils::printableTrace($prev->getTrace()) as $line){ - $this->critical(" " . $line); - } - } - }); + } + $lines[] = "--- End of exception information ---"; + $this->critical(implode("\n", $lines)); $this->syncFlushBuffer(); } From 5115387feb7f6c16735f8a82f8d46e5dea38107b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 7 Oct 2021 20:43:55 +0100 Subject: [PATCH 2932/3224] fix CS (again) --- src/utils/MainLogger.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils/MainLogger.php b/src/utils/MainLogger.php index b5b9dd7ef1..67ab82a62e 100644 --- a/src/utils/MainLogger.php +++ b/src/utils/MainLogger.php @@ -28,6 +28,7 @@ use pocketmine\errorhandler\ErrorTypeToStringMap; use pocketmine\thread\Thread; use pocketmine\thread\Worker; use function get_class; +use function implode; use function is_int; use function preg_replace; use function sprintf; From 2a3a57c5195ffe3094ef6c6862ce0b73e7cd1fc3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 7 Oct 2021 20:53:15 +0100 Subject: [PATCH 2933/3224] Enable parsing/emitting .properties without creating a Config object this is useful when the contents are just going to get passed straight into a model, making Config object redundant anyway. --- src/utils/Config.php | 22 ++++++++++--------- .../check-explicit-mixed-baseline.neon | 5 +++++ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/utils/Config.php b/src/utils/Config.php index db0b8c464f..9449f768dd 100644 --- a/src/utils/Config.php +++ b/src/utils/Config.php @@ -170,7 +170,7 @@ class Config{ $config = null; switch($this->type){ case Config::PROPERTIES: - $config = $this->parseProperties($content); + $config = self::parseProperties($content); break; case Config::JSON: $config = json_decode($content, true); @@ -211,7 +211,7 @@ class Config{ $content = null; switch($this->type){ case Config::PROPERTIES: - $content = $this->writeProperties(); + $content = self::writeProperties($this->config); break; case Config::JSON: $content = json_encode($this->config, $this->jsonOptions); @@ -524,9 +524,13 @@ class Config{ return $result; } - private function writeProperties() : string{ + /** + * @param string[]|int[]|float[]|bool[] $config + * @phpstan-param array $config + */ + public static function writeProperties(array $config) : string{ $content = "#Properties Config file\r\n#" . date("D M j H:i:s T Y") . "\r\n"; - foreach($this->config as $k => $v){ + foreach($config as $k => $v){ if(is_bool($v)){ $v = $v ? "on" : "off"; } @@ -537,9 +541,10 @@ class Config{ } /** - * @return mixed[] + * @return string[]|int[]|float[]|bool[] + * @phpstan-return array */ - private function parseProperties(string $content) : array{ + public static function parseProperties(string $content) : array{ $result = []; if(preg_match_all('/^\s*([a-zA-Z0-9\-_\.]+)[ \t]*=([^\r\n]*)/um', $content, $matches) > 0){ //false or 0 matches foreach($matches[1] as $i => $k){ @@ -563,10 +568,7 @@ class Config{ }; break; } - if(isset($result[$k])){ - \GlobalLogger::get()->debug("[Config] Repeated property " . $k . " on file " . $this->file); - } - $result[$k] = $v; + $result[(string) $k] = $v; } } diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index cb0893173a..a13bb3a1b6 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -165,6 +165,11 @@ parameters: count: 1 path: ../../../src/timings/TimingsHandler.php + - + message: "#^Parameter \\#1 \\$config of static method pocketmine\\\\utils\\\\Config\\:\\:writeProperties\\(\\) expects array\\, array\\ given\\.$#" + count: 1 + path: ../../../src/utils/Config.php + - message: "#^Parameter \\#2 \\$offset of function substr expects int, mixed given\\.$#" count: 1 From d5f02a0bf84d3918087df8392e0ab18ba77e8d5c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 7 Oct 2021 21:18:42 +0100 Subject: [PATCH 2934/3224] Config: expose APIs to parse/emit list configs --- src/utils/Config.php | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/utils/Config.php b/src/utils/Config.php index 9449f768dd..e611d1f03f 100644 --- a/src/utils/Config.php +++ b/src/utils/Config.php @@ -183,7 +183,7 @@ class Config{ $config = unserialize($content); break; case Config::ENUM: - $config = self::parseList($content); + $config = array_fill_keys(self::parseList($content), true); break; default: throw new \InvalidStateException("Config type is unknown"); @@ -223,7 +223,7 @@ class Config{ $content = serialize($this->config); break; case Config::ENUM: - $content = implode("\r\n", array_keys($this->config)); + $content = self::writeList(array_keys($this->config)); break; default: throw new \InvalidStateException("Config type is unknown, has not been set or not detected"); @@ -509,21 +509,29 @@ class Config{ } /** - * @return true[] - * @phpstan-return array + * @return string[] + * @phpstan-return list */ - private static function parseList(string $content) : array{ + public static function parseList(string $content) : array{ $result = []; foreach(explode("\n", trim(str_replace("\r\n", "\n", $content))) as $v){ $v = trim($v); - if($v == ""){ + if($v === ""){ continue; } - $result[$v] = true; + $result[] = $v; } return $result; } + /** + * @param string[] $entries + * @phpstan-param list $entries + */ + public static function writeList(array $entries) : string{ + return implode("\n", array_keys($entries)); + } + /** * @param string[]|int[]|float[]|bool[] $config * @phpstan-param array $config From e0d2e24698c531a0ff4cdad372709d67f568e13a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 7 Oct 2021 21:19:44 +0100 Subject: [PATCH 2935/3224] fix CS (again\!) --- src/utils/Config.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils/Config.php b/src/utils/Config.php index e611d1f03f..6923db5887 100644 --- a/src/utils/Config.php +++ b/src/utils/Config.php @@ -25,6 +25,7 @@ namespace pocketmine\utils; use Webmozart\PathUtil\Path; use function array_change_key_case; +use function array_fill_keys; use function array_keys; use function array_shift; use function count; From 4910250a81eae7a8955437b2c04d8a0f1ef4accb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 7 Oct 2021 21:47:09 +0100 Subject: [PATCH 2936/3224] Config: fixed writeList() --- src/utils/Config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/Config.php b/src/utils/Config.php index 6923db5887..696269a1ba 100644 --- a/src/utils/Config.php +++ b/src/utils/Config.php @@ -530,7 +530,7 @@ class Config{ * @phpstan-param list $entries */ public static function writeList(array $entries) : string{ - return implode("\n", array_keys($entries)); + return implode("\n", $entries); } /** From 308d7c126a6609c36ce2de886a408ff492369351 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 8 Oct 2021 23:39:25 +0100 Subject: [PATCH 2937/3224] Fixed world data ::generate() functions putting level.dat in the wrong place if the world path didn't end with a / --- src/world/format/io/data/BedrockWorldData.php | 3 ++- src/world/format/io/data/JavaWorldData.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/world/format/io/data/BedrockWorldData.php b/src/world/format/io/data/BedrockWorldData.php index e59c066d50..50a4184fec 100644 --- a/src/world/format/io/data/BedrockWorldData.php +++ b/src/world/format/io/data/BedrockWorldData.php @@ -39,6 +39,7 @@ use pocketmine\world\generator\Generator; use pocketmine\world\generator\GeneratorManager; use pocketmine\world\World; use pocketmine\world\WorldCreationOptions; +use Webmozart\PathUtil\Path; use function file_get_contents; use function file_put_contents; use function strlen; @@ -101,7 +102,7 @@ class BedrockWorldData extends BaseNbtWorldData{ $nbt = new LittleEndianNbtSerializer(); $buffer = $nbt->write(new TreeRoot($worldData)); - file_put_contents($path . "level.dat", Binary::writeLInt(self::CURRENT_STORAGE_VERSION) . Binary::writeLInt(strlen($buffer)) . $buffer); + file_put_contents(Path::join($path, "level.dat"), Binary::writeLInt(self::CURRENT_STORAGE_VERSION) . Binary::writeLInt(strlen($buffer)) . $buffer); } protected function load() : CompoundTag{ diff --git a/src/world/format/io/data/JavaWorldData.php b/src/world/format/io/data/JavaWorldData.php index 3565799797..c2f4888762 100644 --- a/src/world/format/io/data/JavaWorldData.php +++ b/src/world/format/io/data/JavaWorldData.php @@ -33,6 +33,7 @@ use pocketmine\world\format\io\exception\CorruptedWorldException; use pocketmine\world\generator\GeneratorManager; use pocketmine\world\World; use pocketmine\world\WorldCreationOptions; +use Webmozart\PathUtil\Path; use function ceil; use function file_get_contents; use function file_put_contents; @@ -68,7 +69,7 @@ class JavaWorldData extends BaseNbtWorldData{ $nbt = new BigEndianNbtSerializer(); $buffer = zlib_encode($nbt->write(new TreeRoot(CompoundTag::create()->setTag("Data", $worldData))), ZLIB_ENCODING_GZIP); - file_put_contents($path . "level.dat", $buffer); + file_put_contents(Path::join($path, "level.dat"), $buffer); } protected function load() : CompoundTag{ From ccc881ee5808a747bb197dfee19a2d2cd3a47341 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 9 Oct 2021 00:57:15 +0100 Subject: [PATCH 2938/3224] Switch to custom permission denied message closes #4494 --- resources/locale | 2 +- src/command/Command.php | 2 +- src/lang/KnownTranslationFactory.php | 6 ++++++ src/lang/KnownTranslationKeys.php | 1 + 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/resources/locale b/resources/locale index c940b9f171..299927cf85 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit c940b9f17188548f78d0dc5fdd4e607c703b7952 +Subproject commit 299927cf85ef6b19d9a159e0bde66ef50e1c143d diff --git a/src/command/Command.php b/src/command/Command.php index ff08620f1f..ea324a9338 100644 --- a/src/command/Command.php +++ b/src/command/Command.php @@ -117,7 +117,7 @@ abstract class Command{ } if($this->permissionMessage === null){ - $target->sendMessage(KnownTranslationFactory::commands_generic_permission()->prefix(TextFormat::RED)); + $target->sendMessage(KnownTranslationFactory::pocketmine_command_error_permission($this->name)->prefix(TextFormat::RED)); }elseif($this->permissionMessage !== ""){ $target->sendMessage(str_replace("", $permission ?? $this->permission, $this->permissionMessage)); } diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index 43d3ce3b17..78f0abe6e0 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -1109,6 +1109,12 @@ final class KnownTranslationFactory{ return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_ENCHANT_DESCRIPTION, []); } + public static function pocketmine_command_error_permission(Translatable|string $commandName) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_ERROR_PERMISSION, [ + "commandName" => $commandName, + ]); + } + public static function pocketmine_command_error_playerNotFound(Translatable|string $playerName) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_COMMAND_ERROR_PLAYERNOTFOUND, [ "playerName" => $playerName, diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index e4301fa247..039642a966 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -244,6 +244,7 @@ final class KnownTranslationKeys{ public const POCKETMINE_COMMAND_DIFFICULTY_DESCRIPTION = "pocketmine.command.difficulty.description"; public const POCKETMINE_COMMAND_EFFECT_DESCRIPTION = "pocketmine.command.effect.description"; public const POCKETMINE_COMMAND_ENCHANT_DESCRIPTION = "pocketmine.command.enchant.description"; + public const POCKETMINE_COMMAND_ERROR_PERMISSION = "pocketmine.command.error.permission"; public const POCKETMINE_COMMAND_ERROR_PLAYERNOTFOUND = "pocketmine.command.error.playerNotFound"; public const POCKETMINE_COMMAND_EXCEPTION = "pocketmine.command.exception"; public const POCKETMINE_COMMAND_GAMEMODE_DESCRIPTION = "pocketmine.command.gamemode.description"; From 09715906c8850088ceb34718530c876bf2985986 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 9 Oct 2021 23:51:46 +0200 Subject: [PATCH 2939/3224] StructureGrowEvent: added API to get the player who caused the growth (#4445) --- src/block/Bamboo.php | 10 +++++----- src/block/BambooSapling.php | 8 ++++---- src/block/Sapling.php | 8 ++++---- src/event/block/StructureGrowEvent.php | 13 ++++++++++++- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/block/Bamboo.php b/src/block/Bamboo.php index fc5182cfb9..171491406a 100644 --- a/src/block/Bamboo.php +++ b/src/block/Bamboo.php @@ -145,12 +145,12 @@ class Bamboo extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof Fertilizer){ $top = $this->seekToTop(); - if($top->grow(self::getMaxHeight($top->position->getFloorX(), $top->position->getFloorZ()), mt_rand(1, 2))){ + if($top->grow(self::getMaxHeight($top->position->getFloorX(), $top->position->getFloorZ()), mt_rand(1, 2), $player)){ $item->pop(); return true; } }elseif($item instanceof ItemBamboo){ - if($this->seekToTop()->grow(PHP_INT_MAX, 1)){ + if($this->seekToTop()->grow(PHP_INT_MAX, 1, $player)){ $item->pop(); return true; } @@ -165,7 +165,7 @@ class Bamboo extends Transparent{ } } - private function grow(int $maxHeight, int $growAmount) : bool{ + private function grow(int $maxHeight, int $growAmount, ?Player $player) : bool{ $world = $this->position->getWorld(); if(!$world->getBlock($this->position->up())->canBeReplaced()){ return false; @@ -212,7 +212,7 @@ class Bamboo extends Transparent{ $tx->addBlock($this->position->subtract(0, $idx - $growAmount, 0), $newBlock); } - $ev = new StructureGrowEvent($this, $tx); + $ev = new StructureGrowEvent($this, $tx, $player); $ev->call(); if($ev->isCancelled()){ return false; @@ -229,7 +229,7 @@ class Bamboo extends Transparent{ $world = $this->position->getWorld(); if($this->ready){ $this->ready = false; - if($world->getFullLight($this->position) < 9 || !$this->grow(self::getMaxHeight($this->position->getFloorX(), $this->position->getFloorZ()), 1)){ + if($world->getFullLight($this->position) < 9 || !$this->grow(self::getMaxHeight($this->position->getFloorX(), $this->position->getFloorZ()), 1, null)){ $world->setBlock($this->position, $this); } }elseif($world->getBlock($this->position->up())->canBeReplaced()){ diff --git a/src/block/BambooSapling.php b/src/block/BambooSapling.php index b617236ed2..3da1e593a8 100644 --- a/src/block/BambooSapling.php +++ b/src/block/BambooSapling.php @@ -73,7 +73,7 @@ final class BambooSapling extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof Fertilizer || $item instanceof ItemBamboo){ - if($this->grow()){ + if($this->grow($player)){ $item->pop(); return true; } @@ -87,7 +87,7 @@ final class BambooSapling extends Flowable{ } } - private function grow() : bool{ + private function grow(?Player $player) : bool{ $world = $this->position->getWorld(); if(!$world->getBlock($this->position->up())->canBeReplaced()){ return false; @@ -98,7 +98,7 @@ final class BambooSapling extends Flowable{ $tx->addBlock($this->position, $bamboo) ->addBlock($this->position->up(), (clone $bamboo)->setLeafSize(Bamboo::SMALL_LEAVES)); - $ev = new StructureGrowEvent($this, $tx); + $ev = new StructureGrowEvent($this, $tx, $player); $ev->call(); if($ev->isCancelled()){ return false; @@ -115,7 +115,7 @@ final class BambooSapling extends Flowable{ $world = $this->position->getWorld(); if($this->ready){ $this->ready = false; - if($world->getFullLight($this->position) < 9 || !$this->grow()){ + if($world->getFullLight($this->position) < 9 || !$this->grow(null)){ $world->setBlock($this->position, $this); } }elseif($world->getBlock($this->position->up())->canBeReplaced()){ diff --git a/src/block/Sapling.php b/src/block/Sapling.php index cb9d36b021..169cb9a327 100644 --- a/src/block/Sapling.php +++ b/src/block/Sapling.php @@ -77,7 +77,7 @@ class Sapling extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof Fertilizer){ - $this->grow(); + $this->grow($player); $item->pop(); @@ -100,7 +100,7 @@ class Sapling extends Flowable{ public function onRandomTick() : void{ if($this->position->getWorld()->getFullLightAt($this->position->getFloorX(), $this->position->getFloorY(), $this->position->getFloorZ()) >= 8 and mt_rand(1, 7) === 1){ if($this->ready){ - $this->grow(); + $this->grow(null); }else{ $this->ready = true; $this->position->getWorld()->setBlock($this->position, $this); @@ -108,7 +108,7 @@ class Sapling extends Flowable{ } } - private function grow() : void{ + private function grow(?Player $player) : void{ $random = new Random(mt_rand()); $tree = TreeFactory::get($random, $this->treeType); $transaction = $tree?->getBlockTransaction($this->position->getWorld(), $this->position->getFloorX(), $this->position->getFloorY(), $this->position->getFloorZ(), $random); @@ -116,7 +116,7 @@ class Sapling extends Flowable{ return; } - $ev = new StructureGrowEvent($this, $transaction); + $ev = new StructureGrowEvent($this, $transaction, $player); $ev->call(); if($ev->isCancelled()){ return; diff --git a/src/event/block/StructureGrowEvent.php b/src/event/block/StructureGrowEvent.php index 88fd54ae88..30d7c7ceb1 100644 --- a/src/event/block/StructureGrowEvent.php +++ b/src/event/block/StructureGrowEvent.php @@ -7,6 +7,7 @@ namespace pocketmine\event\block; use pocketmine\block\Block; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; +use pocketmine\player\Player; use pocketmine\world\BlockTransaction; /** @@ -17,13 +18,23 @@ class StructureGrowEvent extends BlockEvent implements Cancellable{ use CancellableTrait; private BlockTransaction $transaction; + private ?Player $player; - public function __construct(Block $block, BlockTransaction $transaction){ + public function __construct(Block $block, BlockTransaction $transaction, ?Player $player){ parent::__construct($block); $this->transaction = $transaction; + $this->player = $player; } public function getTransaction() : BlockTransaction{ return $this->transaction; } + + /** + * It returns the player which grows the structure. + * It returns null when the structure grows by itself. + */ + public function getPlayer() : ?Player{ + return $this->player; + } } \ No newline at end of file From c1f843a42ca073e2ff096d1a64f02903790b78dc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 9 Oct 2021 23:55:36 +0100 Subject: [PATCH 2940/3224] GarbageCollectorCommand: fixed duplicate MB suffix --- src/command/defaults/GarbageCollectorCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command/defaults/GarbageCollectorCommand.php b/src/command/defaults/GarbageCollectorCommand.php index 1081ac52e9..2e85ed0934 100644 --- a/src/command/defaults/GarbageCollectorCommand.php +++ b/src/command/defaults/GarbageCollectorCommand.php @@ -68,7 +68,7 @@ class GarbageCollectorCommand extends VanillaCommand{ $sender->sendMessage(KnownTranslationFactory::pocketmine_command_gc_entities(TextFormat::RED . number_format($entitiesCollected))->prefix(TextFormat::GOLD)); $sender->sendMessage(KnownTranslationFactory::pocketmine_command_gc_cycles(TextFormat::RED . number_format($cyclesCollected))->prefix(TextFormat::GOLD)); - $sender->sendMessage(KnownTranslationFactory::pocketmine_command_gc_memoryFreed(TextFormat::RED . number_format(round((($memory - memory_get_usage()) / 1024) / 1024, 2), 2) . " MB")->prefix(TextFormat::GOLD)); + $sender->sendMessage(KnownTranslationFactory::pocketmine_command_gc_memoryFreed(TextFormat::RED . number_format(round((($memory - memory_get_usage()) / 1024) / 1024, 2), 2))->prefix(TextFormat::GOLD)); return true; } } From aa53dc670982d05c5235ef26cc55586bc08d4b52 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 9 Oct 2021 23:56:49 +0100 Subject: [PATCH 2941/3224] Entity: fixed network properties not updating when fireTicks changes another bug that LBSG knew about, but didn't report. :/ --- src/entity/Entity.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index b1680fdb21..8bab76480b 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -681,10 +681,12 @@ abstract class Entity{ throw new \InvalidArgumentException("Fire ticks must be in range 0 ... " . 0x7fff . ", got $fireTicks"); } $this->fireTicks = $fireTicks; + $this->networkPropertiesDirty = true; } public function extinguish() : void{ $this->fireTicks = 0; + $this->networkPropertiesDirty = true; } public function isFireProof() : bool{ From fd2df637b60871fd6f0ae47d10ec47cf126c5eb3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 10 Oct 2021 22:35:38 +0100 Subject: [PATCH 2942/3224] Block: rename getPositionOffset() -> getModelPositionOffset() this gives a better idea of what the function does, and is also much less annoying for auto complete. --- src/block/Bamboo.php | 2 +- src/block/Block.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/block/Bamboo.php b/src/block/Bamboo.php index 171491406a..08817d12db 100644 --- a/src/block/Bamboo.php +++ b/src/block/Bamboo.php @@ -115,7 +115,7 @@ class Bamboo extends Transparent{ return 12 + (self::getOffsetSeed($x, 0, $z) % 5); } - public function getPositionOffset() : ?Vector3{ + public function getModelPositionOffset() : ?Vector3{ $seed = self::getOffsetSeed($this->position->getFloorX(), 0, $this->position->getFloorZ()); $retX = (($seed % 12) + 1) / 16; $retZ = ((($seed >> 8) % 12) + 1) / 16; diff --git a/src/block/Block.php b/src/block/Block.php index 1ef2ccee06..2de12ce585 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -577,7 +577,7 @@ class Block{ final public function getCollisionBoxes() : array{ if($this->collisionBoxes === null){ $this->collisionBoxes = $this->recalculateCollisionBoxes(); - $extraOffset = $this->getPositionOffset(); + $extraOffset = $this->getModelPositionOffset(); $offset = $extraOffset !== null ? $this->position->addVector($extraOffset) : $this->position; foreach($this->collisionBoxes as $bb){ $bb->offset($offset->x, $offset->y, $offset->z); @@ -588,10 +588,10 @@ class Block{ } /** - * Returns an additional fractional vector to shift the block's effective position by based on the current position. + * Returns an additional fractional vector to shift the block model's position by based on the current position. * Used to randomize position of things like bamboo canes and tall grass. */ - public function getPositionOffset() : ?Vector3{ + public function getModelPositionOffset() : ?Vector3{ return null; } From 912e612743485d48612eece46162038a071dc120 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 10 Oct 2021 23:27:09 +0100 Subject: [PATCH 2943/3224] Utils: allow validateCallableSignature() to accept a manually constructed CallbackType instead of a closure this allows more fine-grained control without PHPStan yelling at us. --- src/utils/Utils.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/utils/Utils.php b/src/utils/Utils.php index 72192e6eec..9e33fc8a72 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -488,17 +488,20 @@ final class Utils{ * Verifies that the given callable is compatible with the desired signature. Throws a TypeError if they are * incompatible. * - * @param callable $signature Dummy callable with the required parameters and return type - * @param callable $subject Callable to check the signature of - * @phpstan-param anyCallable $signature - * @phpstan-param anyCallable $subject + * @param callable|CallbackType $signature Dummy callable with the required parameters and return type + * @param callable $subject Callable to check the signature of + * @phpstan-param anyCallable|CallbackType $signature + * @phpstan-param anyCallable $subject * * @throws \DaveRandom\CallbackValidator\InvalidCallbackException * @throws \TypeError */ - public static function validateCallableSignature(callable $signature, callable $subject) : void{ - if(!($sigType = CallbackType::createFromCallable($signature))->isSatisfiedBy($subject)){ - throw new \TypeError("Declaration of callable `" . CallbackType::createFromCallable($subject) . "` must be compatible with `" . $sigType . "`"); + public static function validateCallableSignature(callable|CallbackType $signature, callable $subject) : void{ + if(!($signature instanceof CallbackType)){ + $signature = CallbackType::createFromCallable($signature); + } + if(!$signature->isSatisfiedBy($subject)){ + throw new \TypeError("Declaration of callable `" . CallbackType::createFromCallable($subject) . "` must be compatible with `" . $signature . "`"); } } From 2696698926bd7651ca344b36ae63357057c1596c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 10 Oct 2021 23:31:57 +0100 Subject: [PATCH 2944/3224] ClosureTask: relax closure checks to allow arrow functions without return typehints nobody uses return typehints on arrow functions anyway .. they just waste space. --- src/scheduler/ClosureTask.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/scheduler/ClosureTask.php b/src/scheduler/ClosureTask.php index 45e30212ed..74bf85a00b 100644 --- a/src/scheduler/ClosureTask.php +++ b/src/scheduler/ClosureTask.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace pocketmine\scheduler; +use DaveRandom\CallbackValidator\CallbackType; +use DaveRandom\CallbackValidator\ReturnType; use pocketmine\utils\Utils; /** @@ -49,7 +51,7 @@ class ClosureTask extends Task{ * @phpstan-param \Closure() : void $closure */ public function __construct(\Closure $closure){ - Utils::validateCallableSignature(function() : void{}, $closure); + Utils::validateCallableSignature(new CallbackType(new ReturnType()), $closure); $this->closure = $closure; } From 5bae458a91d13871d3624c636fbd7ae3078a4966 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 10 Oct 2021 23:32:40 +0100 Subject: [PATCH 2945/3224] changelog: mention that Entity->setPosition(AndRotation)() are now protected --- changelogs/4.0.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index 0f38515436..e5194d5b01 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -329,6 +329,8 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - The following methods have signature changes: - `Entity->entityBaseTick()` is now `protected`. - `Entity->move()` is now `protected`. + - `Entity->setPosition()` is now `protected` (use `Entity->teleport()` instead). + - `Entity->setPositionAndRotation()` is now `protected` (use `Entity->teleport()` instead). - `Living->knockBack()` now accepts `float, float, float` (the first two parameters have been removed). - `Living->getEffects()` now returns `EffectManager` instead of `Effect[]`. - The following classes have been added: From 965a16d19d053f9499838a4c66836d317f7ea0e7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Oct 2021 00:49:32 +0100 Subject: [PATCH 2946/3224] PluginManager: Extract deterministic plugin loadability checks into a separate method --- src/plugin/PluginManager.php | 101 ++++++++++++++++------------------- 1 file changed, 47 insertions(+), 54 deletions(-) diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 1e849bc530..064780653f 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -32,6 +32,7 @@ use pocketmine\event\plugin\PluginDisableEvent; use pocketmine\event\plugin\PluginEnableEvent; use pocketmine\event\RegisteredListener; use pocketmine\lang\KnownTranslationFactory; +use pocketmine\lang\Translatable; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\permission\DefaultPermissions; use pocketmine\permission\PermissionManager; @@ -128,6 +129,47 @@ class PluginManager{ return Path::join(dirname($pluginPath), $pluginName); } + private function checkPluginLoadability(PluginDescription $description) : Translatable|string|null{ + $name = $description->getName(); + if(stripos($name, "pocketmine") !== false or stripos($name, "minecraft") !== false or stripos($name, "mojang") !== false){ + return KnownTranslationFactory::pocketmine_plugin_restrictedName(); + } + + foreach($description->getCompatibleApis() as $api){ + if(!VersionString::isValidBaseVersion($api)){ + return KnownTranslationFactory::pocketmine_plugin_invalidAPI($api); + } + } + + if(!ApiVersion::isCompatible($this->server->getApiVersion(), $description->getCompatibleApis())){ + return KnownTranslationFactory::pocketmine_plugin_incompatibleAPI(implode(", ", $description->getCompatibleApis())); + } + + $ambiguousVersions = ApiVersion::checkAmbiguousVersions($description->getCompatibleApis()); + if(count($ambiguousVersions) > 0){ + return KnownTranslationFactory::pocketmine_plugin_ambiguousMinAPI(implode(", ", $ambiguousVersions)); + } + + if(count($description->getCompatibleOperatingSystems()) > 0 and !in_array(Utils::getOS(), $description->getCompatibleOperatingSystems(), true)) { + return KnownTranslationFactory::pocketmine_plugin_incompatibleOS(implode(", ", $description->getCompatibleOperatingSystems())); + } + + if(count($pluginMcpeProtocols = $description->getCompatibleMcpeProtocols()) > 0){ + $serverMcpeProtocols = [ProtocolInfo::CURRENT_PROTOCOL]; + if(count(array_intersect($pluginMcpeProtocols, $serverMcpeProtocols)) === 0){ + return KnownTranslationFactory::pocketmine_plugin_incompatibleProtocol(implode(", ", $pluginMcpeProtocols)); + } + } + + try{ + $description->checkRequiredExtensions(); + }catch(PluginException $ex){ + return $ex->getMessage(); + } + + return null; + } + /** * @param PluginLoader[] $loaders */ @@ -137,12 +179,6 @@ class PluginManager{ $description = $loader->getPluginDescription($path); if($description instanceof PluginDescription){ $this->server->getLogger()->info($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_load($description->getFullName()))); - try{ - $description->checkRequiredExtensions(); - }catch(PluginException $ex){ - $this->server->getLogger()->error($ex->getMessage()); - return null; - } $dataFolder = $this->getDataDirectory($path, $description->getName()); if(file_exists($dataFolder) and !is_dir($dataFolder)){ @@ -262,62 +298,19 @@ class PluginManager{ } $name = $description->getName(); - if(stripos($name, "pocketmine") !== false or stripos($name, "minecraft") !== false or stripos($name, "mojang") !== false){ - $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError($name, KnownTranslationFactory::pocketmine_plugin_restrictedName()))); + + if(($loadabilityError = $this->checkPluginLoadability($description)) !== null){ + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError($name, $loadabilityError))); continue; } - if(strpos($name, " ") !== false){ - $this->server->getLogger()->warning($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_spacesDiscouraged($name))); - } if(isset($plugins[$name]) or $this->getPlugin($name) instanceof Plugin){ $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_duplicateError($name))); continue; } - foreach($description->getCompatibleApis() as $api){ - if(!VersionString::isValidBaseVersion($api)){ - $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( - $name, - KnownTranslationFactory::pocketmine_plugin_invalidAPI($api) - ))); - continue 2; - } - } - - if(!ApiVersion::isCompatible($this->server->getApiVersion(), $description->getCompatibleApis())){ - $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( - $name, - KnownTranslationFactory::pocketmine_plugin_incompatibleAPI(implode(", ", $description->getCompatibleApis())) - ))); - continue; - } - $ambiguousVersions = ApiVersion::checkAmbiguousVersions($description->getCompatibleApis()); - if(count($ambiguousVersions) > 0){ - $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( - $name, - KnownTranslationFactory::pocketmine_plugin_ambiguousMinAPI(implode(", ", $ambiguousVersions)) - ))); - continue; - } - - if(count($description->getCompatibleOperatingSystems()) > 0 and !in_array(Utils::getOS(), $description->getCompatibleOperatingSystems(), true)) { - $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( - $name, - KnownTranslationFactory::pocketmine_plugin_incompatibleOS(implode(", ", $description->getCompatibleOperatingSystems())) - ))); - continue; - } - - if(count($pluginMcpeProtocols = $description->getCompatibleMcpeProtocols()) > 0){ - $serverMcpeProtocols = [ProtocolInfo::CURRENT_PROTOCOL]; - if(count(array_intersect($pluginMcpeProtocols, $serverMcpeProtocols)) === 0){ - $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( - $name, - KnownTranslationFactory::pocketmine_plugin_incompatibleProtocol(implode(", ", $pluginMcpeProtocols)) - ))); - continue; - } + if(strpos($name, " ") !== false){ + $this->server->getLogger()->warning($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_spacesDiscouraged($name))); } if($this->graylist !== null and !$this->graylist->isAllowed($name)){ From e1ee320c8d4b5eaf355e7696b12786257190b23d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Oct 2021 00:58:33 +0100 Subject: [PATCH 2947/3224] PluginManager: Localize plugin loading error messages --- resources/locale | 2 +- src/lang/KnownTranslationFactory.php | 52 ++++++++++++++++++++++++++++ src/lang/KnownTranslationKeys.php | 9 +++++ src/plugin/PluginManager.php | 20 +++++++---- 4 files changed, 76 insertions(+), 7 deletions(-) diff --git a/resources/locale b/resources/locale index 299927cf85..d9b2c17b20 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 299927cf85ef6b19d9a159e0bde66ef50e1c143d +Subproject commit d9b2c17b20e4eaf5538b179ab57c5568bb818359 diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index 78f0abe6e0..e02f95370b 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -1671,6 +1671,12 @@ final class KnownTranslationFactory{ ]); } + public static function pocketmine_plugin_badDataFolder(Translatable|string $dataFolder) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_BADDATAFOLDER, [ + "dataFolder" => $dataFolder, + ]); + } + public static function pocketmine_plugin_circularDependency() : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_CIRCULARDEPENDENCY, []); } @@ -1696,18 +1702,39 @@ final class KnownTranslationFactory{ ]); } + public static function pocketmine_plugin_disallowedByBlacklist() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_DISALLOWEDBYBLACKLIST, []); + } + + public static function pocketmine_plugin_disallowedByWhitelist() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_DISALLOWEDBYWHITELIST, []); + } + public static function pocketmine_plugin_duplicateError(Translatable|string $param0) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_DUPLICATEERROR, [ 0 => $param0, ]); } + public static function pocketmine_plugin_emptyExtensionVersionConstraint(Translatable|string $constraintIndex, Translatable|string $extensionName) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_EMPTYEXTENSIONVERSIONCONSTRAINT, [ + "constraintIndex" => $constraintIndex, + "extensionName" => $extensionName, + ]); + } + public static function pocketmine_plugin_enable(Translatable|string $param0) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_ENABLE, [ 0 => $param0, ]); } + public static function pocketmine_plugin_extensionNotLoaded(Translatable|string $extensionName) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_EXTENSIONNOTLOADED, [ + "extensionName" => $extensionName, + ]); + } + public static function pocketmine_plugin_genericLoadError(Translatable|string $param0) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_GENERICLOADERROR, [ 0 => $param0, @@ -1720,6 +1747,14 @@ final class KnownTranslationFactory{ ]); } + public static function pocketmine_plugin_incompatibleExtensionVersion(Translatable|string $extensionVersion, Translatable|string $extensionName, Translatable|string $pluginRequirement) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEEXTENSIONVERSION, [ + "extensionVersion" => $extensionVersion, + "extensionName" => $extensionName, + "pluginRequirement" => $pluginRequirement, + ]); + } + public static function pocketmine_plugin_incompatibleOS(Translatable|string $param0) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_INCOMPATIBLEOS, [ 0 => $param0, @@ -1744,6 +1779,13 @@ final class KnownTranslationFactory{ ]); } + public static function pocketmine_plugin_invalidExtensionVersionConstraint(Translatable|string $versionConstraint, Translatable|string $extensionName) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_INVALIDEXTENSIONVERSIONCONSTRAINT, [ + "versionConstraint" => $versionConstraint, + "extensionName" => $extensionName, + ]); + } + public static function pocketmine_plugin_invalidManifest(Translatable|string $details) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_INVALIDMANIFEST, [ "details" => $details, @@ -1763,6 +1805,16 @@ final class KnownTranslationFactory{ ]); } + public static function pocketmine_plugin_mainClassNotFound() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_MAINCLASSNOTFOUND, []); + } + + public static function pocketmine_plugin_mainClassWrongType(Translatable|string $pluginInterface) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_MAINCLASSWRONGTYPE, [ + "pluginInterface" => $pluginInterface, + ]); + } + public static function pocketmine_plugin_restrictedName() : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_RESTRICTEDNAME, []); } diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index 039642a966..238b4f8068 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -352,21 +352,30 @@ final class KnownTranslationKeys{ public const POCKETMINE_PLAYER_LOGOUT = "pocketmine.player.logOut"; public const POCKETMINE_PLUGIN_ALIASERROR = "pocketmine.plugin.aliasError"; public const POCKETMINE_PLUGIN_AMBIGUOUSMINAPI = "pocketmine.plugin.ambiguousMinAPI"; + public const POCKETMINE_PLUGIN_BADDATAFOLDER = "pocketmine.plugin.badDataFolder"; public const POCKETMINE_PLUGIN_CIRCULARDEPENDENCY = "pocketmine.plugin.circularDependency"; public const POCKETMINE_PLUGIN_COMMANDERROR = "pocketmine.plugin.commandError"; public const POCKETMINE_PLUGIN_DEPRECATEDEVENT = "pocketmine.plugin.deprecatedEvent"; public const POCKETMINE_PLUGIN_DISABLE = "pocketmine.plugin.disable"; + public const POCKETMINE_PLUGIN_DISALLOWEDBYBLACKLIST = "pocketmine.plugin.disallowedByBlacklist"; + public const POCKETMINE_PLUGIN_DISALLOWEDBYWHITELIST = "pocketmine.plugin.disallowedByWhitelist"; public const POCKETMINE_PLUGIN_DUPLICATEERROR = "pocketmine.plugin.duplicateError"; + public const POCKETMINE_PLUGIN_EMPTYEXTENSIONVERSIONCONSTRAINT = "pocketmine.plugin.emptyExtensionVersionConstraint"; public const POCKETMINE_PLUGIN_ENABLE = "pocketmine.plugin.enable"; + public const POCKETMINE_PLUGIN_EXTENSIONNOTLOADED = "pocketmine.plugin.extensionNotLoaded"; public const POCKETMINE_PLUGIN_GENERICLOADERROR = "pocketmine.plugin.genericLoadError"; public const POCKETMINE_PLUGIN_INCOMPATIBLEAPI = "pocketmine.plugin.incompatibleAPI"; + public const POCKETMINE_PLUGIN_INCOMPATIBLEEXTENSIONVERSION = "pocketmine.plugin.incompatibleExtensionVersion"; public const POCKETMINE_PLUGIN_INCOMPATIBLEOS = "pocketmine.plugin.incompatibleOS"; public const POCKETMINE_PLUGIN_INCOMPATIBLEPHPVERSION = "pocketmine.plugin.incompatiblePhpVersion"; public const POCKETMINE_PLUGIN_INCOMPATIBLEPROTOCOL = "pocketmine.plugin.incompatibleProtocol"; public const POCKETMINE_PLUGIN_INVALIDAPI = "pocketmine.plugin.invalidAPI"; + public const POCKETMINE_PLUGIN_INVALIDEXTENSIONVERSIONCONSTRAINT = "pocketmine.plugin.invalidExtensionVersionConstraint"; public const POCKETMINE_PLUGIN_INVALIDMANIFEST = "pocketmine.plugin.invalidManifest"; public const POCKETMINE_PLUGIN_LOAD = "pocketmine.plugin.load"; public const POCKETMINE_PLUGIN_LOADERROR = "pocketmine.plugin.loadError"; + public const POCKETMINE_PLUGIN_MAINCLASSNOTFOUND = "pocketmine.plugin.mainClassNotFound"; + public const POCKETMINE_PLUGIN_MAINCLASSWRONGTYPE = "pocketmine.plugin.mainClassWrongType"; public const POCKETMINE_PLUGIN_RESTRICTEDNAME = "pocketmine.plugin.restrictedName"; public const POCKETMINE_PLUGIN_SPACESDISCOURAGED = "pocketmine.plugin.spacesDiscouraged"; public const POCKETMINE_PLUGIN_UNKNOWNDEPENDENCY = "pocketmine.plugin.unknownDependency"; diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 064780653f..7b963af7e3 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -178,11 +178,15 @@ class PluginManager{ if($loader->canLoadPlugin($path)){ $description = $loader->getPluginDescription($path); if($description instanceof PluginDescription){ + $language = $this->server->getLanguage(); $this->server->getLogger()->info($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_load($description->getFullName()))); $dataFolder = $this->getDataDirectory($path, $description->getName()); if(file_exists($dataFolder) and !is_dir($dataFolder)){ - $this->server->getLogger()->error("Projected dataFolder '" . $dataFolder . "' for " . $description->getName() . " exists and is not a directory"); + $this->server->getLogger()->error($language->translate(KnownTranslationFactory::pocketmine_plugin_loadError( + $description->getName(), + KnownTranslationFactory::pocketmine_plugin_badDataFolder($dataFolder) + ))); return null; } if(!file_exists($dataFolder)){ @@ -194,11 +198,17 @@ class PluginManager{ $mainClass = $description->getMain(); if(!class_exists($mainClass, true)){ - $this->server->getLogger()->error("Main class for plugin " . $description->getName() . " not found"); + $this->server->getLogger()->error($language->translate(KnownTranslationFactory::pocketmine_plugin_loadError( + $description->getName(), + KnownTranslationFactory::pocketmine_plugin_mainClassNotFound() + ))); return null; } if(!is_a($mainClass, Plugin::class, true)){ - $this->server->getLogger()->error("Main class for plugin " . $description->getName() . " is not an instance of " . Plugin::class); + $this->server->getLogger()->error($language->translate(KnownTranslationFactory::pocketmine_plugin_loadError( + $description->getName(), + KnownTranslationFactory::pocketmine_plugin_mainClassWrongType(Plugin::class) + ))); return null; } @@ -316,7 +326,7 @@ class PluginManager{ if($this->graylist !== null and !$this->graylist->isAllowed($name)){ $this->server->getLogger()->notice($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( $name, - "Disallowed by graylist" + $this->graylist->isWhitelist() ? KnownTranslationFactory::pocketmine_plugin_disallowedByWhitelist() : KnownTranslationFactory::pocketmine_plugin_disallowedByBlacklist() ))); continue; } @@ -381,8 +391,6 @@ class PluginManager{ $loadedThisLoop++; if(($plugin = $this->loadPlugin($file, $loaders)) instanceof Plugin){ $loadedPlugins[$name] = $plugin; - }else{ - $this->server->getLogger()->critical($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_genericLoadError($name))); } } } From 6d728e8d98d7910856d21b6fdc7193ba08968bbb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Oct 2021 01:11:59 +0100 Subject: [PATCH 2948/3224] PluginManager: Improved startup performance when loading many plugins for some reason we were reading and parsing the plugin.yml at least twice for every plugin loaded. We were repeating work already done by the initial loadPlugins() triage (discovering correct loader, loading plugin.yml from disk, parsing plugin.yml, validating plugin.yml) every time loadPlugin() was called with that plugin. --- src/plugin/PluginLoadTriageEntry.php | 42 ++++++++ src/plugin/PluginManager.php | 152 ++++++++++++++------------- 2 files changed, 120 insertions(+), 74 deletions(-) create mode 100644 src/plugin/PluginLoadTriageEntry.php diff --git a/src/plugin/PluginLoadTriageEntry.php b/src/plugin/PluginLoadTriageEntry.php new file mode 100644 index 0000000000..5a1a875de3 --- /dev/null +++ b/src/plugin/PluginLoadTriageEntry.php @@ -0,0 +1,42 @@ +file; } + + public function getLoader() : PluginLoader{ return $this->loader; } + + public function getDescription() : PluginDescription{ return $this->description; } +} \ No newline at end of file diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 7b963af7e3..63a4442338 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -178,77 +178,7 @@ class PluginManager{ if($loader->canLoadPlugin($path)){ $description = $loader->getPluginDescription($path); if($description instanceof PluginDescription){ - $language = $this->server->getLanguage(); - $this->server->getLogger()->info($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_load($description->getFullName()))); - - $dataFolder = $this->getDataDirectory($path, $description->getName()); - if(file_exists($dataFolder) and !is_dir($dataFolder)){ - $this->server->getLogger()->error($language->translate(KnownTranslationFactory::pocketmine_plugin_loadError( - $description->getName(), - KnownTranslationFactory::pocketmine_plugin_badDataFolder($dataFolder) - ))); - return null; - } - if(!file_exists($dataFolder)){ - mkdir($dataFolder, 0777, true); - } - - $prefixed = $loader->getAccessProtocol() . $path; - $loader->loadPlugin($prefixed); - - $mainClass = $description->getMain(); - if(!class_exists($mainClass, true)){ - $this->server->getLogger()->error($language->translate(KnownTranslationFactory::pocketmine_plugin_loadError( - $description->getName(), - KnownTranslationFactory::pocketmine_plugin_mainClassNotFound() - ))); - return null; - } - if(!is_a($mainClass, Plugin::class, true)){ - $this->server->getLogger()->error($language->translate(KnownTranslationFactory::pocketmine_plugin_loadError( - $description->getName(), - KnownTranslationFactory::pocketmine_plugin_mainClassWrongType(Plugin::class) - ))); - return null; - } - - $permManager = PermissionManager::getInstance(); - $opRoot = $permManager->getPermission(DefaultPermissions::ROOT_OPERATOR); - $everyoneRoot = $permManager->getPermission(DefaultPermissions::ROOT_USER); - foreach($description->getPermissions() as $default => $perms){ - foreach($perms as $perm){ - $permManager->addPermission($perm); - switch($default){ - case PermissionParser::DEFAULT_TRUE: - $everyoneRoot->addChild($perm->getName(), true); - break; - case PermissionParser::DEFAULT_OP: - $opRoot->addChild($perm->getName(), true); - break; - case PermissionParser::DEFAULT_NOT_OP: - //TODO: I don't think anyone uses this, and it currently relies on some magic inside PermissibleBase - //to ensure that the operator override actually applies. - //Explore getting rid of this. - //The following grants this permission to anyone who has the "everyone" root permission. - //However, if the operator root node (which has higher priority) is present, the - //permission will be denied instead. - $everyoneRoot->addChild($perm->getName(), true); - $opRoot->addChild($perm->getName(), false); - break; - default: - break; - } - } - } - - /** - * @var Plugin $plugin - * @see Plugin::__construct() - */ - $plugin = new $mainClass($loader, $this->server, $description, $dataFolder, $prefixed, new DiskResourceProvider($prefixed . "/resources/")); - $this->plugins[$plugin->getDescription()->getName()] = $plugin; - - return $plugin; + $this->internalLoadPlugin($path, $loader, $description); } } } @@ -256,6 +186,80 @@ class PluginManager{ return null; } + private function internalLoadPlugin(string $path, PluginLoader $loader, PluginDescription $description) : ?Plugin{ + $language = $this->server->getLanguage(); + $this->server->getLogger()->info($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_load($description->getFullName()))); + + $dataFolder = $this->getDataDirectory($path, $description->getName()); + if(file_exists($dataFolder) and !is_dir($dataFolder)){ + $this->server->getLogger()->error($language->translate(KnownTranslationFactory::pocketmine_plugin_loadError( + $description->getName(), + KnownTranslationFactory::pocketmine_plugin_badDataFolder($dataFolder) + ))); + return null; + } + if(!file_exists($dataFolder)){ + mkdir($dataFolder, 0777, true); + } + + $prefixed = $loader->getAccessProtocol() . $path; + $loader->loadPlugin($prefixed); + + $mainClass = $description->getMain(); + if(!class_exists($mainClass, true)){ + $this->server->getLogger()->error($language->translate(KnownTranslationFactory::pocketmine_plugin_loadError( + $description->getName(), + KnownTranslationFactory::pocketmine_plugin_mainClassNotFound() + ))); + return null; + } + if(!is_a($mainClass, Plugin::class, true)){ + $this->server->getLogger()->error($language->translate(KnownTranslationFactory::pocketmine_plugin_loadError( + $description->getName(), + KnownTranslationFactory::pocketmine_plugin_mainClassWrongType(Plugin::class) + ))); + return null; + } + + $permManager = PermissionManager::getInstance(); + $opRoot = $permManager->getPermission(DefaultPermissions::ROOT_OPERATOR); + $everyoneRoot = $permManager->getPermission(DefaultPermissions::ROOT_USER); + foreach($description->getPermissions() as $default => $perms){ + foreach($perms as $perm){ + $permManager->addPermission($perm); + switch($default){ + case PermissionParser::DEFAULT_TRUE: + $everyoneRoot->addChild($perm->getName(), true); + break; + case PermissionParser::DEFAULT_OP: + $opRoot->addChild($perm->getName(), true); + break; + case PermissionParser::DEFAULT_NOT_OP: + //TODO: I don't think anyone uses this, and it currently relies on some magic inside PermissibleBase + //to ensure that the operator override actually applies. + //Explore getting rid of this. + //The following grants this permission to anyone who has the "everyone" root permission. + //However, if the operator root node (which has higher priority) is present, the + //permission will be denied instead. + $everyoneRoot->addChild($perm->getName(), true); + $opRoot->addChild($perm->getName(), false); + break; + default: + break; + } + } + } + + /** + * @var Plugin $plugin + * @see Plugin::__construct() + */ + $plugin = new $mainClass($loader, $this->server, $description, $dataFolder, $prefixed, new DiskResourceProvider($prefixed . "/resources/")); + $this->plugins[$plugin->getDescription()->getName()] = $plugin; + + return $plugin; + } + /** * @param string[]|null $newLoaders * @phpstan-param list> $newLoaders @@ -330,7 +334,7 @@ class PluginManager{ ))); continue; } - $plugins[$name] = $file; + $plugins[$name] = new PluginLoadTriageEntry($file, $loader, $description); $softDependencies[$name] = array_merge($softDependencies[$name] ?? [], $description->getSoftDepend()); $dependencies[$name] = $description->getDepend(); @@ -347,7 +351,7 @@ class PluginManager{ while(count($plugins) > 0){ $loadedThisLoop = 0; - foreach($plugins as $name => $file){ + foreach($plugins as $name => $entry){ if(isset($dependencies[$name])){ foreach($dependencies[$name] as $key => $dependency){ if(isset($loadedPlugins[$dependency]) or $this->getPlugin($dependency) instanceof Plugin){ @@ -389,7 +393,7 @@ class PluginManager{ if(!isset($dependencies[$name]) and !isset($softDependencies[$name])){ unset($plugins[$name]); $loadedThisLoop++; - if(($plugin = $this->loadPlugin($file, $loaders)) instanceof Plugin){ + if(($plugin = $this->internalLoadPlugin($entry->getFile(), $entry->getLoader(), $entry->getDescription())) instanceof Plugin){ $loadedPlugins[$name] = $plugin; } } From 19a66a8d037d0d02d046cc73e36bc1212bc00f73 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Oct 2021 01:14:00 +0100 Subject: [PATCH 2949/3224] committing the new strings would have helped ... --- resources/locale | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/locale b/resources/locale index d9b2c17b20..0fe963d087 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit d9b2c17b20e4eaf5538b179ab57c5568bb818359 +Subproject commit 0fe963d087c1408b1dffa82f33e67f34ad8deaf5 From 8ac16345a3bc099b62c1f5cfbf3b736e621c3f76 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Oct 2021 15:05:08 +0100 Subject: [PATCH 2950/3224] TypeConverter: account for items without properly mapped IDs fixes #4459 --- src/network/mcpe/convert/ItemTranslator.php | 17 +++++-- src/network/mcpe/convert/TypeConverter.php | 52 +++++++++++++++------ 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/src/network/mcpe/convert/ItemTranslator.php b/src/network/mcpe/convert/ItemTranslator.php index d1a7c3a580..1af9adba21 100644 --- a/src/network/mcpe/convert/ItemTranslator.php +++ b/src/network/mcpe/convert/ItemTranslator.php @@ -142,10 +142,10 @@ final class ItemTranslator{ } /** - * @return int[] - * @phpstan-return array{int, int} + * @return int[]|null + * @phpstan-return array{int, int}|null */ - public function toNetworkId(int $internalId, int $internalMeta) : array{ + public function toNetworkIdQuiet(int $internalId, int $internalMeta) : ?array{ if($internalMeta === -1){ $internalMeta = 0x7fff; } @@ -156,7 +156,16 @@ final class ItemTranslator{ return [$this->simpleCoreToNetMapping[$internalId], $internalMeta]; } - throw new \InvalidArgumentException("Unmapped ID/metadata combination $internalId:$internalMeta"); + return null; + } + + /** + * @return int[] + * @phpstan-return array{int, int} + */ + public function toNetworkId(int $internalId, int $internalMeta) : array{ + return $this->toNetworkIdQuiet($internalId, $internalMeta) ?? + throw new \InvalidArgumentException("Unmapped ID/metadata combination $internalId:$internalMeta"); } /** diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index d878423f60..21b3ab7492 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -58,6 +58,7 @@ class TypeConverter{ private const DAMAGE_TAG = "Damage"; //TAG_Int private const DAMAGE_TAG_CONFLICT_RESOLUTION = "___Damage_ProtocolCollisionResolution___"; + private const PM_ID_TAG = "___Id___"; private const PM_META_TAG = "___Meta___"; /** @var int */ @@ -143,26 +144,40 @@ class TypeConverter{ } $isBlockItem = $itemStack->getId() < 256; - if($itemStack instanceof Durable and $itemStack->getDamage() > 0){ - if($nbt !== null){ - if(($existing = $nbt->getTag(self::DAMAGE_TAG)) !== null){ - $nbt->removeTag(self::DAMAGE_TAG); - $nbt->setTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION, $existing); - } - }else{ - $nbt = new CompoundTag(); - } - $nbt->setInt(self::DAMAGE_TAG, $itemStack->getDamage()); - }elseif($isBlockItem && $itemStack->getMeta() !== 0){ - //TODO HACK: This foul-smelling code ensures that we can correctly deserialize an item when the - //client sends it back to us, because as of 1.16.220, blockitems quietly discard their metadata - //client-side. Aside from being very annoying, this also breaks various server-side behaviours. + + $idMeta = ItemTranslator::getInstance()->toNetworkIdQuiet($itemStack->getId(), $itemStack->getMeta()); + if($idMeta === null){ + //Display unmapped items as INFO_UPDATE, but stick something in their NBT to make sure they don't stack with + //other unmapped items. + [$id, $meta] = ItemTranslator::getInstance()->toNetworkId(ItemIds::INFO_UPDATE, 0); if($nbt === null){ $nbt = new CompoundTag(); } + $nbt->setInt(self::PM_ID_TAG, $itemStack->getId()); $nbt->setInt(self::PM_META_TAG, $itemStack->getMeta()); + }else{ + [$id, $meta] = $idMeta; + + if($itemStack instanceof Durable and $itemStack->getDamage() > 0){ + if($nbt !== null){ + if(($existing = $nbt->getTag(self::DAMAGE_TAG)) !== null){ + $nbt->removeTag(self::DAMAGE_TAG); + $nbt->setTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION, $existing); + } + }else{ + $nbt = new CompoundTag(); + } + $nbt->setInt(self::DAMAGE_TAG, $itemStack->getDamage()); + }elseif($isBlockItem && $itemStack->getMeta() !== 0){ + //TODO HACK: This foul-smelling code ensures that we can correctly deserialize an item when the + //client sends it back to us, because as of 1.16.220, blockitems quietly discard their metadata + //client-side. Aside from being very annoying, this also breaks various server-side behaviours. + if($nbt === null){ + $nbt = new CompoundTag(); + } + $nbt->setInt(self::PM_META_TAG, $itemStack->getMeta()); + } } - [$id, $meta] = ItemTranslator::getInstance()->toNetworkId($itemStack->getId(), $itemStack->getMeta()); $blockRuntimeId = 0; if($isBlockItem){ @@ -197,6 +212,13 @@ class TypeConverter{ if($compound !== null){ $compound = clone $compound; + if(($idTag = $compound->getTag(self::PM_ID_TAG)) instanceof IntTag){ + $id = $idTag->getValue(); + $compound->removeTag(self::PM_ID_TAG); + if($compound->count() === 0){ + $compound = null; + } + } if(($damageTag = $compound->getTag(self::DAMAGE_TAG)) instanceof IntTag){ $meta = $damageTag->getValue(); $compound->removeTag(self::DAMAGE_TAG); From 500c298aafeb2d551bcd3b2154de96db773c7c9a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Oct 2021 15:12:16 +0100 Subject: [PATCH 2951/3224] Disallow the use of @handleCancelled on non-cancellable events closes #3464 --- src/plugin/PluginManager.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 63a4442338..3fceaa7105 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\plugin; +use pocketmine\event\Cancellable; use pocketmine\event\Event; use pocketmine\event\EventPriority; use pocketmine\event\HandlerListManager; @@ -60,6 +61,7 @@ use function is_subclass_of; use function iterator_to_array; use function mkdir; use function shuffle; +use function sprintf; use function stripos; use function strpos; use function strtolower; @@ -528,6 +530,14 @@ class PluginManager{ $handleCancelled = false; if(isset($tags[ListenerMethodTags::HANDLE_CANCELLED])){ + if(!is_a($eventClass, Cancellable::class, true)){ + throw new PluginException(sprintf( + "Event handler %s() declares @%s for non-cancellable event of type %s", + Utils::getNiceClosureName($handlerClosure), + ListenerMethodTags::HANDLE_CANCELLED, + $eventClass + )); + } switch(strtolower($tags[ListenerMethodTags::HANDLE_CANCELLED])){ case "true": case "": From e62794e4cfc12e47f73dee94e4134392254fc928 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Oct 2021 15:17:32 +0100 Subject: [PATCH 2952/3224] TypeConverter: fixed PHPStan errors --- src/network/mcpe/convert/TypeConverter.php | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index 21b3ab7492..38bbe359ad 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -215,9 +215,6 @@ class TypeConverter{ if(($idTag = $compound->getTag(self::PM_ID_TAG)) instanceof IntTag){ $id = $idTag->getValue(); $compound->removeTag(self::PM_ID_TAG); - if($compound->count() === 0){ - $compound = null; - } } if(($damageTag = $compound->getTag(self::DAMAGE_TAG)) instanceof IntTag){ $meta = $damageTag->getValue(); @@ -225,8 +222,6 @@ class TypeConverter{ if(($conflicted = $compound->getTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION)) !== null){ $compound->removeTag(self::DAMAGE_TAG_CONFLICT_RESOLUTION); $compound->setTag(self::DAMAGE_TAG, $conflicted); - }elseif($compound->count() === 0){ - $compound = null; } }elseif(($metaTag = $compound->getTag(self::PM_META_TAG)) instanceof IntTag){ //TODO HACK: This foul-smelling code ensures that we can correctly deserialize an item when the @@ -234,9 +229,9 @@ class TypeConverter{ //client-side. Aside from being very annoying, this also breaks various server-side behaviours. $meta = $metaTag->getValue(); $compound->removeTag(self::PM_META_TAG); - if($compound->count() === 0){ - $compound = null; - } + } + if($compound->count() === 0){ + $compound = null; } } From 7b6632941de7756676b96227ea43a2a06b63eb3f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Oct 2021 16:04:36 +0100 Subject: [PATCH 2953/3224] GeneratorManager::getGenerator() now returns null for unknown generator aliases instead of returning Normal::class (indistinguishable from successful match) or throwing an exception (pain in the ass to handle). --- src/Server.php | 5 +++-- src/world/World.php | 3 ++- src/world/WorldManager.php | 5 ++--- src/world/format/io/FormatConverter.php | 5 ++++- src/world/generator/GeneratorManager.php | 17 ++++------------- 5 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/Server.php b/src/Server.php index c99ac010ee..172aaf6437 100644 --- a/src/Server.php +++ b/src/Server.php @@ -106,6 +106,7 @@ use pocketmine\world\format\io\WorldProviderManager; use pocketmine\world\format\io\WritableWorldProviderManagerEntry; use pocketmine\world\generator\Generator; use pocketmine\world\generator\GeneratorManager; +use pocketmine\world\generator\normal\Normal; use pocketmine\world\World; use pocketmine\world\WorldCreationOptions; use pocketmine\world\WorldManager; @@ -979,7 +980,7 @@ class Server{ if(isset($options["generator"])){ $generatorOptions = explode(":", $options["generator"]); - $creationOptions->setGeneratorClass(GeneratorManager::getInstance()->getGenerator(array_shift($generatorOptions))); + $creationOptions->setGeneratorClass(GeneratorManager::getInstance()->getGenerator(array_shift($generatorOptions)) ?? Normal::class); if(count($generatorOptions) > 0){ $creationOptions->setGeneratorOptions(implode(":", $generatorOptions)); } @@ -1010,7 +1011,7 @@ class Server{ } if(!$this->worldManager->loadWorld($default, true)){ $creationOptions = WorldCreationOptions::create() - ->setGeneratorClass(GeneratorManager::getInstance()->getGenerator($this->configGroup->getConfigString("level-type"))) + ->setGeneratorClass(GeneratorManager::getInstance()->getGenerator($this->configGroup->getConfigString("level-type")) ?? Normal::class) ->setGeneratorOptions($this->configGroup->getConfigString("generator-settings")); $convertedSeed = Generator::convertSeed($this->configGroup->getConfigString("level-seed")); if($convertedSeed !== null){ diff --git a/src/world/World.php b/src/world/World.php index 0eea2c7bcb..9b953b3d4e 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -411,7 +411,8 @@ class World implements ChunkManager{ $this->maxY = $this->provider->getWorldMaxY(); $this->server->getLogger()->info($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_preparing($this->displayName))); - $this->generator = GeneratorManager::getInstance()->getGenerator($this->provider->getWorldData()->getGenerator(), true); + $this->generator = GeneratorManager::getInstance()->getGenerator($this->provider->getWorldData()->getGenerator()) ?? + throw new AssumptionFailedError("WorldManager should already have checked that the generator exists"); //TODO: validate generator options $this->chunkPopulationRequestQueue = new \SplQueue(); $this->addOnUnloadCallback(function() : void{ diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index d79eee0b64..ff2c7ca125 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -220,9 +220,8 @@ class WorldManager{ ))); return false; } - try{ - GeneratorManager::getInstance()->getGenerator($provider->getWorldData()->getGenerator(), true); - }catch(\InvalidArgumentException $e){ + + if(GeneratorManager::getInstance()->getGenerator($provider->getWorldData()->getGenerator()) === null){ $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_loadError( $name, KnownTranslationFactory::pocketmine_level_unknownGenerator($provider->getWorldData()->getGenerator()) diff --git a/src/world/format/io/FormatConverter.php b/src/world/format/io/FormatConverter.php index 5ee6ea3a8f..6931d3b5f0 100644 --- a/src/world/format/io/FormatConverter.php +++ b/src/world/format/io/FormatConverter.php @@ -25,6 +25,7 @@ namespace pocketmine\world\format\io; use pocketmine\utils\Filesystem; use pocketmine\world\generator\GeneratorManager; +use pocketmine\world\generator\normal\Normal; use pocketmine\world\WorldCreationOptions; use Webmozart\PathUtil\Path; use function basename; @@ -112,7 +113,9 @@ class FormatConverter{ Filesystem::recursiveUnlink($convertedOutput); } $this->newProvider->generate($convertedOutput, $data->getName(), WorldCreationOptions::create() - ->setGeneratorClass(GeneratorManager::getInstance()->getGenerator($data->getGenerator())) + //TODO: defaulting to NORMAL here really isn't very good behaviour, but it's consistent with what we already + //did previously; besides, WorldManager checks for unknown generators before this is reached anyway. + ->setGeneratorClass(GeneratorManager::getInstance()->getGenerator($data->getGenerator()) ?? Normal::class) ->setGeneratorOptions($data->getGeneratorOptions()) ->setSeed($data->getSeed()) ->setSpawnPosition($data->getSpawn()) diff --git a/src/world/generator/GeneratorManager.php b/src/world/generator/GeneratorManager.php index 58811f05f1..1415906c96 100644 --- a/src/world/generator/GeneratorManager.php +++ b/src/world/generator/GeneratorManager.php @@ -79,20 +79,11 @@ final class GeneratorManager{ * * @param bool $throwOnMissing @deprecated this is for backwards compatibility only * - * @return string Name of class that extends Generator - * @phpstan-return class-string - * - * @throws \InvalidArgumentException if the generator type isn't registered + * @return string|null Name of class that extends Generator, or null if no generator is mapped to that name + * @phpstan-return class-string|null */ - public function getGenerator(string $name, bool $throwOnMissing = false){ - if(isset($this->list[$name = strtolower($name)])){ - return $this->list[$name]; - } - - if($throwOnMissing){ - throw new \InvalidArgumentException("Alias \"$name\" does not map to any known generator"); - } - return Normal::class; + public function getGenerator(string $name, bool $throwOnMissing = false) : ?string{ + return $this->list[strtolower($name)] ?? null; } /** From fa93a8d78f7aff607d72dcdd551ee60fd3773098 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Oct 2021 16:13:32 +0100 Subject: [PATCH 2954/3224] Server: Error on unknown generators when generating new worlds from config, instead of silently using DEFAULT this is consistent with the behaviour of loading worlds. --- src/Server.php | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/Server.php b/src/Server.php index 172aaf6437..52bde0c2ae 100644 --- a/src/Server.php +++ b/src/Server.php @@ -106,7 +106,6 @@ use pocketmine\world\format\io\WorldProviderManager; use pocketmine\world\format\io\WritableWorldProviderManagerEntry; use pocketmine\world\generator\Generator; use pocketmine\world\generator\GeneratorManager; -use pocketmine\world\generator\normal\Normal; use pocketmine\world\World; use pocketmine\world\WorldCreationOptions; use pocketmine\world\WorldManager; @@ -968,6 +967,17 @@ class Server{ $this->pluginManager->loadPlugins($this->pluginPath); $this->enablePlugins(PluginEnableOrder::STARTUP()); + $getGenerator = function(string $generatorName, string $worldName) : ?string{ + $generatorClass = GeneratorManager::getInstance()->getGenerator($generatorName); + if($generatorClass === null){ + $this->logger->error($this->language->translate(KnownTranslationFactory::pocketmine_level_generationError( + $worldName, + KnownTranslationFactory::pocketmine_level_unknownGenerator($generatorName) + ))); + } + return $generatorClass; + }; + foreach((array) $this->configGroup->getProperty("worlds", []) as $name => $options){ if($options === null){ $options = []; @@ -980,7 +990,11 @@ class Server{ if(isset($options["generator"])){ $generatorOptions = explode(":", $options["generator"]); - $creationOptions->setGeneratorClass(GeneratorManager::getInstance()->getGenerator(array_shift($generatorOptions)) ?? Normal::class); + $generatorClass = $getGenerator(array_shift($generatorOptions), $name); + if($generatorClass === null){ + continue; + } + $creationOptions->setGeneratorClass($generatorClass); if(count($generatorOptions) > 0){ $creationOptions->setGeneratorOptions(implode(":", $generatorOptions)); } @@ -1010,14 +1024,17 @@ class Server{ $this->configGroup->setConfigString("level-name", "world"); } if(!$this->worldManager->loadWorld($default, true)){ - $creationOptions = WorldCreationOptions::create() - ->setGeneratorClass(GeneratorManager::getInstance()->getGenerator($this->configGroup->getConfigString("level-type")) ?? Normal::class) - ->setGeneratorOptions($this->configGroup->getConfigString("generator-settings")); - $convertedSeed = Generator::convertSeed($this->configGroup->getConfigString("level-seed")); - if($convertedSeed !== null){ - $creationOptions->setSeed($convertedSeed); + $generatorClass = $getGenerator($this->configGroup->getConfigString("level-type"), $default); + if($generatorClass !== null){ + $creationOptions = WorldCreationOptions::create() + ->setGeneratorClass($generatorClass) + ->setGeneratorOptions($this->configGroup->getConfigString("generator-settings")); + $convertedSeed = Generator::convertSeed($this->configGroup->getConfigString("level-seed")); + if($convertedSeed !== null){ + $creationOptions->setSeed($convertedSeed); + } + $this->worldManager->generateWorld($default, $creationOptions); } - $this->worldManager->generateWorld($default, $creationOptions); } $world = $this->worldManager->getWorldByName($default); From 859cdfa5d2883d4ccebf5c0f6f6ff90802e88284 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Oct 2021 16:18:38 +0100 Subject: [PATCH 2955/3224] GeneratorManager: removed unused parameter from getGenerator() --- src/world/generator/GeneratorManager.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/world/generator/GeneratorManager.php b/src/world/generator/GeneratorManager.php index 1415906c96..0db15390ea 100644 --- a/src/world/generator/GeneratorManager.php +++ b/src/world/generator/GeneratorManager.php @@ -77,12 +77,10 @@ final class GeneratorManager{ /** * Returns a class name of a registered Generator matching the given name. * - * @param bool $throwOnMissing @deprecated this is for backwards compatibility only - * * @return string|null Name of class that extends Generator, or null if no generator is mapped to that name * @phpstan-return class-string|null */ - public function getGenerator(string $name, bool $throwOnMissing = false) : ?string{ + public function getGenerator(string $name) : ?string{ return $this->list[strtolower($name)] ?? null; } From 70deea0ef992a572ec4ec9ddae63b2541b2de516 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Oct 2021 16:52:10 +0100 Subject: [PATCH 2956/3224] Flat: Move preset handling to a FlatGeneratorOptions unit --- src/world/generator/Flat.php | 84 ++---------- src/world/generator/FlatGeneratorOptions.php | 127 +++++++++++++++++++ 2 files changed, 137 insertions(+), 74 deletions(-) create mode 100644 src/world/generator/FlatGeneratorOptions.php diff --git a/src/world/generator/Flat.php b/src/world/generator/Flat.php index 1aba3ae130..3afab55dbb 100644 --- a/src/world/generator/Flat.php +++ b/src/world/generator/Flat.php @@ -39,32 +39,22 @@ use function preg_match; use function preg_match_all; class Flat extends Generator{ + /** @var Chunk */ private $chunk; /** @var Populator[] */ private $populators = []; - /** - * @var int[] - * @phpstan-var array - */ - private $structure; - /** @var int */ - private $biome; - /** - * @var mixed[] - * @phpstan-var array - */ - private array $options = []; + private FlatGeneratorOptions $options; /** * @throws InvalidGeneratorOptionsException */ public function __construct(int $seed, string $preset){ parent::__construct($seed, $preset !== "" ? $preset : "2;bedrock,2xdirt,grass;1;"); - $this->parsePreset(); + $this->options = FlatGeneratorOptions::parsePreset($this->preset); - if(isset($this->options["decoration"])){ + if(isset($this->options->getExtraOptions()["decoration"])){ $ores = new Ore(); $stone = VanillaBlocks::STONE(); $ores->setOreTypes([ @@ -83,76 +73,22 @@ class Flat extends Generator{ $this->generateBaseChunk(); } - /** - * @return int[] - * @phpstan-return array - * - * @throws InvalidGeneratorOptionsException - */ - public static function parseLayers(string $layers) : array{ - $result = []; - $split = array_map('\trim', explode(',', $layers)); - $y = 0; - $itemParser = LegacyStringToItemParser::getInstance(); - foreach($split as $line){ - preg_match('#^(?:(\d+)[x|*])?(.+)$#', $line, $matches); - if(count($matches) !== 3){ - throw new InvalidGeneratorOptionsException("Invalid preset layer \"$line\""); - } - - $cnt = $matches[1] !== "" ? (int) $matches[1] : 1; - try{ - $b = $itemParser->parse($matches[2])->getBlock(); - }catch(LegacyStringToItemParserException $e){ - throw new InvalidGeneratorOptionsException("Invalid preset layer \"$line\": " . $e->getMessage(), 0, $e); - } - for($cY = $y, $y += $cnt; $cY < $y; ++$cY){ - $result[$cY] = $b->getFullId(); - } - } - - return $result; - } - - protected function parsePreset() : void{ - $preset = explode(";", $this->preset); - $blocks = $preset[1] ?? ""; - $this->biome = (int) ($preset[2] ?? 1); - $options = $preset[3] ?? ""; - $this->structure = self::parseLayers($blocks); - - //TODO: more error checking - preg_match_all('#(([0-9a-z_]{1,})\(?([0-9a-z_ =:]{0,})\)?),?#', $options, $matches); - foreach($matches[2] as $i => $option){ - $params = true; - if($matches[3][$i] !== ""){ - $params = []; - $p = explode(" ", $matches[3][$i]); - foreach($p as $k){ - $k = explode("=", $k); - if(isset($k[1])){ - $params[$k[0]] = $k[1]; - } - } - } - $this->options[$option] = $params; - } - } - protected function generateBaseChunk() : void{ $this->chunk = new Chunk(); + $biomeId = $this->options->getBiomeId(); for($Z = 0; $Z < Chunk::EDGE_LENGTH; ++$Z){ for($X = 0; $X < Chunk::EDGE_LENGTH; ++$X){ - $this->chunk->setBiomeId($X, $Z, $this->biome); + $this->chunk->setBiomeId($X, $Z, $biomeId); } } - $count = count($this->structure); + $structure = $this->options->getStructure(); + $count = count($structure); for($sy = 0; $sy < $count; $sy += SubChunk::EDGE_LENGTH){ $subchunk = $this->chunk->getSubChunk($sy >> SubChunk::COORD_BIT_SIZE); - for($y = 0; $y < SubChunk::EDGE_LENGTH and isset($this->structure[$y | $sy]); ++$y){ - $id = $this->structure[$y | $sy]; + for($y = 0; $y < SubChunk::EDGE_LENGTH and isset($structure[$y | $sy]); ++$y){ + $id = $structure[$y | $sy]; for($Z = 0; $Z < SubChunk::EDGE_LENGTH; ++$Z){ for($X = 0; $X < SubChunk::EDGE_LENGTH; ++$X){ diff --git a/src/world/generator/FlatGeneratorOptions.php b/src/world/generator/FlatGeneratorOptions.php new file mode 100644 index 0000000000..6c3f20a9cc --- /dev/null +++ b/src/world/generator/FlatGeneratorOptions.php @@ -0,0 +1,127 @@ + $structure + * @phpstan-param array|true> $extraOptions + */ + public function __construct( + private array $structure, + private int $biomeId, + private array $extraOptions = [] + ){} + + /** + * @return int[] + * @phpstan-return array + */ + public function getStructure() : array{ return $this->structure; } + + public function getBiomeId() : int{ return $this->biomeId; } + + /** + * @return mixed[] + * @phpstan-return array|true> + */ + public function getExtraOptions() : array{ return $this->extraOptions; } + + + /** + * @return int[] + * @phpstan-return array + * + * @throws InvalidGeneratorOptionsException + */ + public static function parseLayers(string $layers) : array{ + $result = []; + $split = array_map('\trim', explode(',', $layers)); + $y = 0; + $itemParser = LegacyStringToItemParser::getInstance(); + foreach($split as $line){ + preg_match('#^(?:(\d+)[x|*])?(.+)$#', $line, $matches); + if(count($matches) !== 3){ + throw new InvalidGeneratorOptionsException("Invalid preset layer \"$line\""); + } + + $cnt = $matches[1] !== "" ? (int) $matches[1] : 1; + try{ + $b = $itemParser->parse($matches[2])->getBlock(); + }catch(LegacyStringToItemParserException $e){ + throw new InvalidGeneratorOptionsException("Invalid preset layer \"$line\": " . $e->getMessage(), 0, $e); + } + for($cY = $y, $y += $cnt; $cY < $y; ++$cY){ + $result[$cY] = $b->getFullId(); + } + } + + return $result; + } + + /** + * @throws InvalidGeneratorOptionsException + */ + public static function parsePreset(string $presetString) : self{ + $preset = explode(";", $presetString); + $blocks = $preset[1] ?? ""; + $biomeId = (int) ($preset[2] ?? 1); + $optionsString = $preset[3] ?? ""; + $structure = self::parseLayers($blocks); + + $options = []; + //TODO: more error checking + preg_match_all('#(([0-9a-z_]{1,})\(?([0-9a-z_ =:]{0,})\)?),?#', $optionsString, $matches); + foreach($matches[2] as $i => $option){ + $params = true; + if($matches[3][$i] !== ""){ + $params = []; + $p = explode(" ", $matches[3][$i]); + foreach($p as $k){ + $k = explode("=", $k); + if(isset($k[1])){ + $params[$k[0]] = $k[1]; + } + } + } + $options[(string) $option] = $params; + } + return new self($structure, $biomeId, $options); + } + +} \ No newline at end of file From 89d7b7198feecc21cf3efc613b0751f4686e75dd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Oct 2021 17:20:49 +0100 Subject: [PATCH 2957/3224] Server: drop support for tagging generator options onto the 'generator' key in pocketmine.yml the 'preset' key should be used for this purpose instead. This couldn't be dropped until now due to the shitty handling of unknown generators. --- src/Server.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Server.php b/src/Server.php index 52bde0c2ae..3c8c2e4c60 100644 --- a/src/Server.php +++ b/src/Server.php @@ -989,15 +989,11 @@ class Server{ //TODO: error checking if(isset($options["generator"])){ - $generatorOptions = explode(":", $options["generator"]); - $generatorClass = $getGenerator(array_shift($generatorOptions), $name); + $generatorClass = $getGenerator($options["generator"], $name); if($generatorClass === null){ continue; } $creationOptions->setGeneratorClass($generatorClass); - if(count($generatorOptions) > 0){ - $creationOptions->setGeneratorOptions(implode(":", $generatorOptions)); - } } if(isset($options["difficulty"]) && is_string($options["difficulty"])){ $creationOptions->setDifficulty(World::getDifficultyFromString($options["difficulty"])); From 092aabeb97c06fb4228e83dd6075633cb3e83872 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Oct 2021 17:21:19 +0100 Subject: [PATCH 2958/3224] fix CS --- src/Server.php | 3 --- src/world/generator/Flat.php | 6 ------ src/world/generator/FlatGeneratorOptions.php | 1 - 3 files changed, 10 deletions(-) diff --git a/src/Server.php b/src/Server.php index 3c8c2e4c60..7168341f7f 100644 --- a/src/Server.php +++ b/src/Server.php @@ -111,19 +111,16 @@ use pocketmine\world\WorldCreationOptions; use pocketmine\world\WorldManager; use Ramsey\Uuid\UuidInterface; use Webmozart\PathUtil\Path; -use function array_shift; use function array_sum; use function base64_encode; use function cli_set_process_title; use function copy; use function count; -use function explode; use function file_exists; use function file_get_contents; use function file_put_contents; use function filemtime; use function get_class; -use function implode; use function ini_set; use function is_array; use function is_string; diff --git a/src/world/generator/Flat.php b/src/world/generator/Flat.php index 3afab55dbb..fff96db945 100644 --- a/src/world/generator/Flat.php +++ b/src/world/generator/Flat.php @@ -24,19 +24,13 @@ declare(strict_types=1); namespace pocketmine\world\generator; use pocketmine\block\VanillaBlocks; -use pocketmine\item\LegacyStringToItemParser; -use pocketmine\item\LegacyStringToItemParserException; use pocketmine\world\ChunkManager; use pocketmine\world\format\Chunk; use pocketmine\world\format\SubChunk; use pocketmine\world\generator\object\OreType; use pocketmine\world\generator\populator\Ore; use pocketmine\world\generator\populator\Populator; -use function array_map; use function count; -use function explode; -use function preg_match; -use function preg_match_all; class Flat extends Generator{ diff --git a/src/world/generator/FlatGeneratorOptions.php b/src/world/generator/FlatGeneratorOptions.php index 6c3f20a9cc..98d2f16a25 100644 --- a/src/world/generator/FlatGeneratorOptions.php +++ b/src/world/generator/FlatGeneratorOptions.php @@ -62,7 +62,6 @@ final class FlatGeneratorOptions{ */ public function getExtraOptions() : array{ return $this->extraOptions; } - /** * @return int[] * @phpstan-return array From 34f54750c82b614bcfe919adef46f9584358c61d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Oct 2021 17:37:47 +0100 Subject: [PATCH 2959/3224] Added support for creation-time validation of generator options, closes #2717 --- resources/locale | 2 +- src/Server.php | 44 +++++++++++------ src/lang/KnownTranslationFactory.php | 8 ++++ src/lang/KnownTranslationKeys.php | 1 + src/world/World.php | 5 +- src/world/format/io/FormatConverter.php | 2 +- src/world/generator/GeneratorManager.php | 47 +++++++++++------- src/world/generator/GeneratorManagerEntry.php | 48 +++++++++++++++++++ 8 files changed, 120 insertions(+), 37 deletions(-) create mode 100644 src/world/generator/GeneratorManagerEntry.php diff --git a/resources/locale b/resources/locale index 0fe963d087..17fc6a1050 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 0fe963d087c1408b1dffa82f33e67f34ad8deaf5 +Subproject commit 17fc6a10501c2cd48ec08f81ab41a640864f8d1d diff --git a/src/Server.php b/src/Server.php index 7168341f7f..77e441c61b 100644 --- a/src/Server.php +++ b/src/Server.php @@ -106,6 +106,7 @@ use pocketmine\world\format\io\WorldProviderManager; use pocketmine\world\format\io\WritableWorldProviderManagerEntry; use pocketmine\world\generator\Generator; use pocketmine\world\generator\GeneratorManager; +use pocketmine\world\generator\InvalidGeneratorOptionsException; use pocketmine\world\World; use pocketmine\world\WorldCreationOptions; use pocketmine\world\WorldManager; @@ -964,15 +965,25 @@ class Server{ $this->pluginManager->loadPlugins($this->pluginPath); $this->enablePlugins(PluginEnableOrder::STARTUP()); - $getGenerator = function(string $generatorName, string $worldName) : ?string{ - $generatorClass = GeneratorManager::getInstance()->getGenerator($generatorName); - if($generatorClass === null){ + $getGenerator = function(string $generatorName, string $generatorOptions, string $worldName) : ?string{ + $generatorEntry = GeneratorManager::getInstance()->getGenerator($generatorName); + if($generatorEntry === null){ $this->logger->error($this->language->translate(KnownTranslationFactory::pocketmine_level_generationError( $worldName, KnownTranslationFactory::pocketmine_level_unknownGenerator($generatorName) ))); + return null; } - return $generatorClass; + try{ + $generatorEntry->validateGeneratorOptions($generatorOptions); + }catch(InvalidGeneratorOptionsException $e){ + $this->logger->error($this->language->translate(KnownTranslationFactory::pocketmine_level_generationError( + $worldName, + KnownTranslationFactory::pocketmine_level_invalidGeneratorOptions($generatorOptions, $generatorName, $e->getMessage()) + ))); + return null; + } + return $generatorEntry->getGeneratorClass(); }; foreach((array) $this->configGroup->getProperty("worlds", []) as $name => $options){ @@ -985,19 +996,20 @@ class Server{ $creationOptions = WorldCreationOptions::create(); //TODO: error checking - if(isset($options["generator"])){ - $generatorClass = $getGenerator($options["generator"], $name); - if($generatorClass === null){ - continue; - } - $creationOptions->setGeneratorClass($generatorClass); + $generatorName = $options["generator"] ?? "default"; + $generatorOptions = isset($options["preset"]) && is_string($options["preset"]) ? $options["preset"] : ""; + + $generatorClass = $getGenerator($generatorName, $generatorOptions, $name); + if($generatorClass === null){ + continue; } + $creationOptions->setGeneratorClass($generatorClass); + $creationOptions->setGeneratorOptions($generatorOptions); + if(isset($options["difficulty"]) && is_string($options["difficulty"])){ $creationOptions->setDifficulty(World::getDifficultyFromString($options["difficulty"])); } - if(isset($options["preset"]) && is_string($options["preset"])){ - $creationOptions->setGeneratorOptions($options["preset"]); - } + if(isset($options["seed"])){ $convertedSeed = Generator::convertSeed((string) ($options["seed"] ?? "")); if($convertedSeed !== null){ @@ -1017,11 +1029,13 @@ class Server{ $this->configGroup->setConfigString("level-name", "world"); } if(!$this->worldManager->loadWorld($default, true)){ - $generatorClass = $getGenerator($this->configGroup->getConfigString("level-type"), $default); + $generatorName = $this->configGroup->getConfigString("level-type"); + $generatorOptions = $this->configGroup->getConfigString("generator-settings"); + $generatorClass = $getGenerator($generatorName, $generatorOptions, $default); if($generatorClass !== null){ $creationOptions = WorldCreationOptions::create() ->setGeneratorClass($generatorClass) - ->setGeneratorOptions($this->configGroup->getConfigString("generator-settings")); + ->setGeneratorOptions($generatorOptions); $convertedSeed = Generator::convertSeed($this->configGroup->getConfigString("level-seed")); if($convertedSeed !== null){ $creationOptions->setSeed($convertedSeed); diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index e02f95370b..ce4f33c2b8 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -1575,6 +1575,14 @@ final class KnownTranslationFactory{ ]); } + public static function pocketmine_level_invalidGeneratorOptions(Translatable|string $preset, Translatable|string $generatorName, Translatable|string $details) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_INVALIDGENERATOROPTIONS, [ + "preset" => $preset, + "generatorName" => $generatorName, + "details" => $details, + ]); + } + public static function pocketmine_level_loadError(Translatable|string $param0, Translatable|string $param1) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_LOADERROR, [ 0 => $param0, diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index 238b4f8068..16f4d26f40 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -338,6 +338,7 @@ final class KnownTranslationKeys{ public const POCKETMINE_LEVEL_CORRUPTED = "pocketmine.level.corrupted"; public const POCKETMINE_LEVEL_DEFAULTERROR = "pocketmine.level.defaultError"; public const POCKETMINE_LEVEL_GENERATIONERROR = "pocketmine.level.generationError"; + public const POCKETMINE_LEVEL_INVALIDGENERATOROPTIONS = "pocketmine.level.invalidGeneratorOptions"; public const POCKETMINE_LEVEL_LOADERROR = "pocketmine.level.loadError"; public const POCKETMINE_LEVEL_NOTFOUND = "pocketmine.level.notFound"; public const POCKETMINE_LEVEL_PREPARING = "pocketmine.level.preparing"; diff --git a/src/world/World.php b/src/world/World.php index 9b953b3d4e..f85320e34c 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -411,9 +411,10 @@ class World implements ChunkManager{ $this->maxY = $this->provider->getWorldMaxY(); $this->server->getLogger()->info($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_preparing($this->displayName))); - $this->generator = GeneratorManager::getInstance()->getGenerator($this->provider->getWorldData()->getGenerator()) ?? + $generator = GeneratorManager::getInstance()->getGenerator($this->provider->getWorldData()->getGenerator()) ?? throw new AssumptionFailedError("WorldManager should already have checked that the generator exists"); - //TODO: validate generator options + $generator->validateGeneratorOptions($this->provider->getWorldData()->getGeneratorOptions()); + $this->generator = $generator->getGeneratorClass(); $this->chunkPopulationRequestQueue = new \SplQueue(); $this->addOnUnloadCallback(function() : void{ $this->logger->debug("Cancelling unfulfilled generation requests"); diff --git a/src/world/format/io/FormatConverter.php b/src/world/format/io/FormatConverter.php index 6931d3b5f0..2599415c49 100644 --- a/src/world/format/io/FormatConverter.php +++ b/src/world/format/io/FormatConverter.php @@ -115,7 +115,7 @@ class FormatConverter{ $this->newProvider->generate($convertedOutput, $data->getName(), WorldCreationOptions::create() //TODO: defaulting to NORMAL here really isn't very good behaviour, but it's consistent with what we already //did previously; besides, WorldManager checks for unknown generators before this is reached anyway. - ->setGeneratorClass(GeneratorManager::getInstance()->getGenerator($data->getGenerator()) ?? Normal::class) + ->setGeneratorClass(GeneratorManager::getInstance()->getGenerator($data->getGenerator())?->getGeneratorClass() ?? Normal::class) ->setGeneratorOptions($data->getGeneratorOptions()) ->setSeed($data->getSeed()) ->setSpawnPosition($data->getSpawn()) diff --git a/src/world/generator/GeneratorManager.php b/src/world/generator/GeneratorManager.php index 0db15390ea..11fd02f3b3 100644 --- a/src/world/generator/GeneratorManager.php +++ b/src/world/generator/GeneratorManager.php @@ -34,35 +34,49 @@ final class GeneratorManager{ use SingletonTrait; /** - * @var string[] name => classname mapping - * @phpstan-var array> + * @var GeneratorManagerEntry[] name => classname mapping + * @phpstan-var array */ private $list = []; public function __construct(){ - $this->addGenerator(Flat::class, "flat"); - $this->addGenerator(Normal::class, "normal"); - $this->addGenerator(Normal::class, "default"); - $this->addGenerator(Nether::class, "hell"); - $this->addGenerator(Nether::class, "nether"); + $this->addGenerator(Flat::class, "flat", \Closure::fromCallable(function(string $preset) : ?InvalidGeneratorOptionsException{ + if($preset === ""){ + return null; + } + try{ + FlatGeneratorOptions::parsePreset($preset); + return null; + }catch(InvalidGeneratorOptionsException $e){ + return $e; + } + })); + $this->addGenerator(Normal::class, "normal", fn() => null); + $this->addGenerator(Normal::class, "default", fn() => null); + $this->addGenerator(Nether::class, "hell", fn() => null); + $this->addGenerator(Nether::class, "nether", fn() => null); } /** - * @param string $class Fully qualified name of class that extends \pocketmine\world\generator\Generator - * @param string $name Alias for this generator type that can be written in configs - * @param bool $overwrite Whether to force overwriting any existing registered generator with the same name + * @param string $class Fully qualified name of class that extends \pocketmine\world\generator\Generator + * @param string $name Alias for this generator type that can be written in configs + * @param \Closure $presetValidator Callback to validate generator options for new worlds + * @param bool $overwrite Whether to force overwriting any existing registered generator with the same name + * + * @phpstan-param \Closure(string) : ?InvalidGeneratorOptionsException $presetValidator + * * @phpstan-param class-string $class * * @throws \InvalidArgumentException */ - public function addGenerator(string $class, string $name, bool $overwrite = false) : void{ + public function addGenerator(string $class, string $name, \Closure $presetValidator, bool $overwrite = false) : void{ Utils::testValidInstance($class, Generator::class); if(!$overwrite and isset($this->list[$name = strtolower($name)])){ throw new \InvalidArgumentException("Alias \"$name\" is already assigned"); } - $this->list[$name] = $class; + $this->list[$name] = new GeneratorManagerEntry($class, $presetValidator); } /** @@ -75,12 +89,9 @@ final class GeneratorManager{ } /** - * Returns a class name of a registered Generator matching the given name. - * - * @return string|null Name of class that extends Generator, or null if no generator is mapped to that name - * @phpstan-return class-string|null + * Returns the generator entry of a registered Generator matching the given name, or null if not found. */ - public function getGenerator(string $name) : ?string{ + public function getGenerator(string $name) : ?GeneratorManagerEntry{ return $this->list[strtolower($name)] ?? null; } @@ -95,7 +106,7 @@ final class GeneratorManager{ public function getGeneratorName(string $class) : string{ Utils::testValidInstance($class, Generator::class); foreach($this->list as $name => $c){ - if($c === $class){ + if($c->getGeneratorClass() === $class){ return $name; } } diff --git a/src/world/generator/GeneratorManagerEntry.php b/src/world/generator/GeneratorManagerEntry.php new file mode 100644 index 0000000000..2f7bbc16c5 --- /dev/null +++ b/src/world/generator/GeneratorManagerEntry.php @@ -0,0 +1,48 @@ + $generatorClass + * @phpstan-param \Closure(string) : ?InvalidGeneratorOptionsException $presetValidator + */ + public function __construct( + private string $generatorClass, + private \Closure $presetValidator + ){} + + /** @phpstan-return class-string */ + public function getGeneratorClass() : string{ return $this->generatorClass; } + + /** + * @throws InvalidGeneratorOptionsException + */ + public function validateGeneratorOptions(string $generatorOptions) : void{ + if(($exception = ($this->presetValidator)($generatorOptions)) !== null){ + throw $exception; + } + } +} \ No newline at end of file From 8fd475f87b458b313b916f8ba73750dfc0de9d34 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Oct 2021 17:44:38 +0100 Subject: [PATCH 2960/3224] WorldManager: Check generator options of worlds before loading them, too --- src/world/WorldManager.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/world/WorldManager.php b/src/world/WorldManager.php index ff2c7ca125..aa906e4ab4 100644 --- a/src/world/WorldManager.php +++ b/src/world/WorldManager.php @@ -38,6 +38,7 @@ use pocketmine\world\format\io\FormatConverter; use pocketmine\world\format\io\WorldProviderManager; use pocketmine\world\format\io\WritableWorldProvider; use pocketmine\world\generator\GeneratorManager; +use pocketmine\world\generator\InvalidGeneratorOptionsException; use Webmozart\PathUtil\Path; use function array_keys; use function array_shift; @@ -221,13 +222,27 @@ class WorldManager{ return false; } - if(GeneratorManager::getInstance()->getGenerator($provider->getWorldData()->getGenerator()) === null){ + $generatorEntry = GeneratorManager::getInstance()->getGenerator($provider->getWorldData()->getGenerator()); + if($generatorEntry === null){ $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_loadError( $name, KnownTranslationFactory::pocketmine_level_unknownGenerator($provider->getWorldData()->getGenerator()) ))); return false; } + try{ + $generatorEntry->validateGeneratorOptions($provider->getWorldData()->getGeneratorOptions()); + }catch(InvalidGeneratorOptionsException $e){ + $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_loadError( + $name, + KnownTranslationFactory::pocketmine_level_invalidGeneratorOptions( + $provider->getWorldData()->getGeneratorOptions(), + $provider->getWorldData()->getGenerator(), + $e->getMessage() + ) + ))); + return false; + } if(!($provider instanceof WritableWorldProvider)){ if(!$autoUpgrade){ throw new UnsupportedWorldFormatException("World \"$name\" is in an unsupported format and needs to be upgraded"); From 01c06020430f8549fb2bfd2e7ad2c7a15abde4fe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Oct 2021 17:48:08 +0100 Subject: [PATCH 2961/3224] Server: do not attempt to generate a new world if it already exists --- src/Server.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Server.php b/src/Server.php index 77e441c61b..71374fc459 100644 --- a/src/Server.php +++ b/src/Server.php @@ -992,7 +992,7 @@ class Server{ }elseif(!is_array($options)){ continue; } - if(!$this->worldManager->loadWorld($name, true)){ + if(!$this->worldManager->loadWorld($name, true) && !$this->worldManager->isWorldGenerated($name)){ $creationOptions = WorldCreationOptions::create(); //TODO: error checking @@ -1028,7 +1028,7 @@ class Server{ $default = "world"; $this->configGroup->setConfigString("level-name", "world"); } - if(!$this->worldManager->loadWorld($default, true)){ + if(!$this->worldManager->loadWorld($default, true) && !$this->worldManager->isWorldGenerated($default)){ $generatorName = $this->configGroup->getConfigString("level-type"); $generatorOptions = $this->configGroup->getConfigString("generator-settings"); $generatorClass = $getGenerator($generatorName, $generatorOptions, $default); From 835e18ce6ea2f91564812b97261812f47fab4c73 Mon Sep 17 00:00:00 2001 From: ErikPDev <33035080+ErikPDev@users.noreply.github.com> Date: Mon, 11 Oct 2021 22:15:44 +0300 Subject: [PATCH 2962/3224] Changelog: Changed utils\Color to color\Color (#4502) [ci skip] --- changelogs/4.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index e5194d5b01..88914ea8a5 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1147,7 +1147,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` #### Particles - `DestroyBlockParticle` has been renamed to `BlockBreakParticle` for consistency. -- `DustParticle->__construct()` now accepts a `pocketmine\utils\Color` object instead of `r, g, b, a`. +- `DustParticle->__construct()` now accepts a `pocketmine\color\Color` object instead of `r, g, b, a`. - `pocketmine\world\particle\Particle` no longer extends `pocketmine\math\Vector3`, and has been converted to an interface. - Added the following `Particle` classes: - `DragonEggTeleportParticle` From d73ea8efe4f0510b4b74ad12d1401c32b1a63874 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Oct 2021 21:32:03 +0100 Subject: [PATCH 2963/3224] FlatGeneratorOptions: Do not hardcode biome ID --- src/world/generator/FlatGeneratorOptions.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/world/generator/FlatGeneratorOptions.php b/src/world/generator/FlatGeneratorOptions.php index 98d2f16a25..01ca4a9146 100644 --- a/src/world/generator/FlatGeneratorOptions.php +++ b/src/world/generator/FlatGeneratorOptions.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\generator; +use pocketmine\data\bedrock\BiomeIds; use pocketmine\item\LegacyStringToItemParser; use pocketmine\item\LegacyStringToItemParserException; use function array_map; @@ -99,7 +100,7 @@ final class FlatGeneratorOptions{ public static function parsePreset(string $presetString) : self{ $preset = explode(";", $presetString); $blocks = $preset[1] ?? ""; - $biomeId = (int) ($preset[2] ?? 1); + $biomeId = (int) ($preset[2] ?? BiomeIds::PLAINS); $optionsString = $preset[3] ?? ""; $structure = self::parseLayers($blocks); From a5833327f0608135fc0e04666a2d09884d272dc8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Oct 2021 21:46:27 +0100 Subject: [PATCH 2964/3224] Inventory: added getAddableItemQuantity() this mostly reuses the code from canAddItem(). --- src/inventory/BaseInventory.php | 8 ++++++-- src/inventory/Inventory.php | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/inventory/BaseInventory.php b/src/inventory/BaseInventory.php index 4d79d7d94c..c5b854a6df 100644 --- a/src/inventory/BaseInventory.php +++ b/src/inventory/BaseInventory.php @@ -169,6 +169,10 @@ abstract class BaseInventory implements Inventory{ } public function canAddItem(Item $item) : bool{ + return $this->getAddableItemQuantity($item) === $item->getCount(); + } + + public function getAddableItemQuantity(Item $item) : int{ $count = $item->getCount(); for($i = 0, $size = $this->getSize(); $i < $size; ++$i){ $slot = $this->getItem($i); @@ -181,11 +185,11 @@ abstract class BaseInventory implements Inventory{ } if($count <= 0){ - return true; + return $item->getCount(); } } - return false; + return $item->getCount() - $count; } public function addItem(Item ...$slots) : array{ diff --git a/src/inventory/Inventory.php b/src/inventory/Inventory.php index 0a5e3b7666..b1fad3904d 100644 --- a/src/inventory/Inventory.php +++ b/src/inventory/Inventory.php @@ -63,6 +63,11 @@ interface Inventory{ */ public function canAddItem(Item $item) : bool; + /** + * Returns how many items from the given itemstack can be added to this inventory. + */ + public function getAddableItemQuantity(Item $item) : int; + /** * Removes the given Item from the inventory. * It will return the Items that couldn't be removed. From 62f11360ee1f3dc5c9c0f211a20e86b0778d7257 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Oct 2021 21:52:27 +0100 Subject: [PATCH 2965/3224] Added unit tests for getAddableItemQuantity() --- tests/phpunit/inventory/BaseInventoryTest.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/phpunit/inventory/BaseInventoryTest.php b/tests/phpunit/inventory/BaseInventoryTest.php index a0ae029ea1..0354b26965 100644 --- a/tests/phpunit/inventory/BaseInventoryTest.php +++ b/tests/phpunit/inventory/BaseInventoryTest.php @@ -94,4 +94,18 @@ class BaseInventoryTest extends TestCase{ } self::assertSame(100, $count); } + + public function testGetAddableItemQuantityStacking() : void{ + $inventory = new SimpleInventory(1); + $inventory->addItem(VanillaItems::APPLE()->setCount(60)); + self::assertSame(2, $inventory->getAddableItemQuantity(VanillaItems::APPLE()->setCount(2))); + self::assertSame(4, $inventory->getAddableItemQuantity(VanillaItems::APPLE()->setCount(6))); + } + + public function testGetAddableItemQuantityEmptyStack() : void{ + $inventory = new SimpleInventory(1); + $item = VanillaItems::APPLE(); + $item->setCount($item->getMaxStackSize()); + self::assertSame($item->getMaxStackSize(), $inventory->getAddableItemQuantity($item)); + } } From 9b94a4661b1a0a773c5cff64b626adaaf068cbbb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 11 Oct 2021 22:17:40 +0100 Subject: [PATCH 2966/3224] ItemTranslator: Use LegacyItemIdToStringMap instead of reading files directly --- src/network/mcpe/convert/ItemTranslator.php | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/network/mcpe/convert/ItemTranslator.php b/src/network/mcpe/convert/ItemTranslator.php index 1af9adba21..0302a6898f 100644 --- a/src/network/mcpe/convert/ItemTranslator.php +++ b/src/network/mcpe/convert/ItemTranslator.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\convert; +use pocketmine\data\bedrock\LegacyItemIdToStringIdMap; use pocketmine\network\mcpe\protocol\serializer\ItemTypeDictionary; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\SingletonTrait; @@ -76,10 +77,7 @@ final class ItemTranslator{ if($legacyStringToIntMapRaw === false){ throw new AssumptionFailedError("Missing required resource file"); } - $legacyStringToIntMap = json_decode($legacyStringToIntMapRaw, true); - if(!is_array($legacyStringToIntMap)){ - throw new AssumptionFailedError("Invalid mapping table format"); - } + $legacyStringToIntMap = LegacyItemIdToStringIdMap::getInstance(); /** @phpstan-var array $simpleMappings */ $simpleMappings = []; @@ -87,13 +85,14 @@ final class ItemTranslator{ if(!is_string($oldId) || !is_string($newId)){ throw new AssumptionFailedError("Invalid item table format"); } - if(!isset($legacyStringToIntMap[$oldId])){ + $intId = $legacyStringToIntMap->stringToLegacy($oldId); + if($intId === null){ //new item without a fixed legacy ID - we can't handle this right now continue; } - $simpleMappings[$newId] = $legacyStringToIntMap[$oldId]; + $simpleMappings[$newId] = $intId; } - foreach($legacyStringToIntMap as $stringId => $intId){ + foreach($legacyStringToIntMap->getStringToLegacyMap() as $stringId => $intId){ if(isset($simpleMappings[$stringId])){ throw new \UnexpectedValueException("Old ID $stringId collides with new ID"); } @@ -110,7 +109,12 @@ final class ItemTranslator{ if(!is_numeric($meta) || !is_string($newId)){ throw new AssumptionFailedError("Invalid item table format"); } - $complexMappings[$newId] = [$legacyStringToIntMap[$oldId], (int) $meta]; + $intId = $legacyStringToIntMap->stringToLegacy($oldId); + if($intId === null){ + //new item without a fixed legacy ID - we can't handle this right now + continue; + } + $complexMappings[$newId] = [$intId, (int) $meta]; } } From 49c1e4c06e3a1561501ef579d8e08be1740aa4b4 Mon Sep 17 00:00:00 2001 From: IceCruelStuff <50642756+IceCruelStuff@users.noreply.github.com> Date: Tue, 12 Oct 2021 13:21:05 -0700 Subject: [PATCH 2967/3224] Implement fletching table (#4501) --- src/block/BlockFactory.php | 2 +- src/block/FletchingTable.php | 30 +++++++++++++++++++ src/block/VanillaBlocks.php | 2 ++ src/item/StringToItemParser.php | 1 + .../block_factory_consistency_check.json | 2 +- 5 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 src/block/FletchingTable.php diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index ee2345f82f..6390812a19 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -183,6 +183,7 @@ class BlockFactory{ $this->register(new EnderChest(new BID(Ids::ENDER_CHEST, 0, null, TileEnderChest::class), "Ender Chest", new BlockBreakInfo(22.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 3000.0))); $this->register(new Farmland(new BID(Ids::FARMLAND, 0), "Farmland", new BlockBreakInfo(0.6, BlockToolType::SHOVEL))); $this->register(new Fire(new BID(Ids::FIRE, 0), "Fire Block", BlockBreakInfo::instant())); + $this->register(new FletchingTable(new BID(Ids::FLETCHING_TABLE, 0), "Fletching Table", new BlockBreakInfo(2.5, BlockToolType::AXE, 0, 2.5))); $this->register(new Flower(new BID(Ids::DANDELION, 0), "Dandelion", BlockBreakInfo::instant())); $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ALLIUM), "Allium", BlockBreakInfo::instant())); $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_AZURE_BLUET), "Azure Bluet", BlockBreakInfo::instant())); @@ -567,7 +568,6 @@ class BlockFactory{ //TODO: minecraft:dropper //TODO: minecraft:end_gateway //TODO: minecraft:end_portal - //TODO: minecraft:fletching_table //TODO: minecraft:grindstone //TODO: minecraft:jigsaw //TODO: minecraft:kelp diff --git a/src/block/FletchingTable.php b/src/block/FletchingTable.php new file mode 100644 index 0000000000..64a71ad975 --- /dev/null +++ b/src/block/FletchingTable.php @@ -0,0 +1,30 @@ +get(60, 0)); self::register("fern", $factory->get(31, 2)); self::register("fire", $factory->get(51, 0)); + self::register("fletching_table", $factory->get(456, 0)); self::register("flower_pot", $factory->get(140, 0)); self::register("frosted_ice", $factory->get(207, 0)); self::register("furnace", $factory->get(61, 2)); diff --git a/src/item/StringToItemParser.php b/src/item/StringToItemParser.php index 700ada9bf8..75b6b81aa3 100644 --- a/src/item/StringToItemParser.php +++ b/src/item/StringToItemParser.php @@ -530,6 +530,7 @@ final class StringToItemParser{ $result->registerBlock("fence_gate_spruce", fn() => VanillaBlocks::SPRUCE_FENCE_GATE()); $result->registerBlock("fern", fn() => VanillaBlocks::FERN()); $result->registerBlock("fire", fn() => VanillaBlocks::FIRE()); + $result->registerBlock("fletching_table", fn() => VanillaBlocks::FLETCHING_TABLE()); $result->registerBlock("flower_pot", fn() => VanillaBlocks::FLOWER_POT()); $result->registerBlock("flower_pot_block", fn() => VanillaBlocks::FLOWER_POT()); $result->registerBlock("flowing_lava", fn() => VanillaBlocks::LAVA()); diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 28308e4a4a..6df3cf0980 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"knownStates":{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","497":"Tall Grass","498":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1614":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2640":"Slime Block","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3280":"Shulker Box","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3488":"Dyed Shulker Box","3489":"Dyed Shulker Box","3490":"Dyed Shulker Box","3491":"Dyed Shulker Box","3492":"Dyed Shulker Box","3493":"Dyed Shulker Box","3494":"Dyed Shulker Box","3495":"Dyed Shulker Box","3496":"Dyed Shulker Box","3497":"Dyed Shulker Box","3498":"Dyed Shulker Box","3499":"Dyed Shulker Box","3500":"Dyed Shulker Box","3501":"Dyed Shulker Box","3502":"Dyed Shulker Box","3503":"Dyed Shulker Box","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6274":"Wall Coral Fan","6276":"Wall Coral Fan","6278":"Wall Coral Fan","6280":"Wall Coral Fan","6282":"Wall Coral Fan","6284":"Wall Coral Fan","6286":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7218":"Blast Furnace","7219":"Blast Furnace","7220":"Blast Furnace","7221":"Blast Furnace","7250":"Smoker","7251":"Smoker","7252":"Smoker","7253":"Smoker","7266":"Smoker","7267":"Smoker","7268":"Smoker","7269":"Smoker","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7376":"Bell","7377":"Bell","7378":"Bell","7379":"Bell","7380":"Bell","7381":"Bell","7382":"Bell","7383":"Bell","7384":"Bell","7385":"Bell","7386":"Bell","7387":"Bell","7388":"Bell","7389":"Bell","7390":"Bell","7391":"Bell","7392":"Sweet Berry Bush","7393":"Sweet Berry Bush","7394":"Sweet Berry Bush","7395":"Sweet Berry Bush","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood","7480":"Stripped Oak Wood","7481":"Stripped Spruce Wood","7482":"Stripped Birch Wood","7483":"Stripped Jungle Wood","7484":"Stripped Acacia Wood","7485":"Stripped Dark Oak Wood","7506":"Blast Furnace","7507":"Blast Furnace","7508":"Blast Furnace","7509":"Blast Furnace"},"remaps":{"284":7472,"285":7473,"286":7474,"287":7475,"438":432,"439":432,"446":432,"447":432,"454":448,"455":448,"462":448,"463":448,"496":498,"499":498,"696":688,"697":689,"698":690,"699":691,"700":692,"701":693,"702":694,"703":695,"800":805,"806":805,"807":805,"864":866,"865":866,"870":866,"871":866,"976":978,"977":978,"982":978,"983":978,"992":978,"993":978,"998":978,"999":978,"1036":1027,"1037":1027,"1038":1027,"1039":1027,"1040":1042,"1041":1042,"1046":1042,"1047":1042,"1066":1056,"1067":1056,"1068":1056,"1069":1056,"1070":1056,"1071":1056,"1088":1090,"1089":1090,"1094":1090,"1095":1090,"1148":1139,"1149":1139,"1150":1139,"1151":1139,"1200":1221,"1206":1221,"1207":1221,"1216":1221,"1222":1221,"1223":1221,"1238":1232,"1239":1232,"1246":1232,"1247":1232,"1377":1376,"1378":1376,"1379":1376,"1440":1441,"1443":1441,"1479":1472,"1595":1598,"1596":1598,"1597":1598,"1610":1594,"1611":1614,"1612":1614,"1613":1614,"1615":1599,"2022":2016,"2023":2016,"2030":2016,"2031":2016,"2044":2032,"2045":2032,"2046":2032,"2047":2032,"2080":2082,"2081":2082,"2086":2082,"2087":2082,"2241":2240,"2242":2240,"2243":2240,"2244":2240,"2245":2240,"2246":2240,"2247":2240,"2248":2240,"2249":2240,"2250":2240,"2251":2240,"2252":2240,"2253":2240,"2254":2240,"2255":2240,"2294":2288,"2295":2288,"2302":2288,"2303":2288,"2304":2306,"2310":2306,"2311":2306,"2312":2306,"2313":2306,"2314":2306,"2315":2306,"2316":2306,"2317":2306,"2318":2306,"2319":2306,"2332":2322,"2333":2322,"2334":2322,"2335":2322,"2336":2338,"2337":2338,"2342":2338,"2343":2338,"2392":2386,"2393":2386,"2394":2386,"2395":2386,"2396":2386,"2397":2386,"2398":2386,"2399":2386,"2400":2386,"2401":2386,"2402":2386,"2403":2386,"2404":2386,"2405":2386,"2406":2386,"2407":2386,"2465":2464,"2470":2464,"2471":2464,"2473":2464,"2478":2464,"2479":2464,"2493":2481,"2494":2482,"2520":2512,"2521":2513,"2522":2514,"2523":2515,"2524":2516,"2525":2517,"2604":7476,"2605":7477,"2732":2720,"2832":2834,"2833":2834,"2838":2834,"2839":2834,"2904":2896,"2905":2897,"2906":2898,"2907":2899,"2908":2900,"2909":2901,"2910":2902,"2911":2903,"3100":3091,"3101":3091,"3102":3091,"3103":3091,"3116":3107,"3117":3107,"3118":3107,"3119":3107,"3132":3123,"3133":3123,"3134":3123,"3135":3123,"3148":3139,"3149":3139,"3150":3139,"3151":3139,"3164":3155,"3165":3155,"3166":3155,"3167":3155,"3230":3218,"3232":3237,"3238":3237,"3239":3237,"3240":3245,"3246":3245,"3247":3245,"3264":3269,"3270":3269,"3271":3269,"3272":3277,"3278":3277,"3279":3277,"3334":3328,"3335":3328,"3468":3456,"3504":3506,"3505":3506,"3510":3506,"3511":3506,"3520":3522,"3521":3522,"3526":3522,"3527":3522,"3536":3538,"3537":3538,"3542":3538,"3543":3538,"3552":3554,"3553":3554,"3558":3554,"3559":3554,"3568":3570,"3569":3570,"3574":3570,"3575":3570,"3584":3586,"3585":3586,"3590":3586,"3591":3586,"3600":3602,"3601":3602,"3606":3602,"3607":3602,"3616":3618,"3617":3618,"3622":3618,"3623":3618,"3632":3634,"3633":3634,"3638":3634,"3639":3634,"3648":3650,"3649":3650,"3654":3650,"3655":3650,"3664":3666,"3665":3666,"3670":3666,"3671":3666,"3696":3698,"3697":3698,"3702":3698,"3703":3698,"3712":3714,"3713":3714,"3718":3714,"3719":3714,"3728":3730,"3729":3730,"3734":3730,"3735":3730,"3744":3746,"3745":3746,"3750":3746,"3751":3746,"3760":3762,"3761":3762,"3766":3762,"3767":3762,"3824":3829,"3830":3829,"3831":3829,"3955":3952,"4163":4160,"4179":4176,"4195":4192,"4211":4208,"4227":4224,"4243":4240,"6181":6176,"6182":6176,"6183":6176,"6197":6192,"6198":6192,"6199":6192,"6205":6192,"6206":6192,"6207":6192,"6213":6208,"6214":6208,"6215":6208,"6221":6208,"6222":6208,"6223":6208,"6229":6208,"6230":6208,"6231":6208,"6237":6208,"6238":6208,"6239":6208,"6273":6248,"6275":6248,"6277":6248,"6279":6248,"6281":6248,"6283":6248,"6285":6248,"6287":6248,"6326":6320,"6327":6320,"6334":6320,"6335":6320,"6342":6336,"6343":6336,"6350":6336,"6351":6336,"6358":6352,"6359":6352,"6366":6352,"6367":6352,"6374":6368,"6375":6368,"6382":6368,"6383":6368,"6390":6384,"6391":6384,"6398":6384,"6399":6384,"6694":6688,"6695":6688,"6702":6688,"6703":6688,"6760":6752,"6761":6753,"6762":6754,"6763":6755,"6764":6756,"6765":6757,"6766":6758,"6767":6759,"6776":6768,"6777":6769,"6778":6770,"6779":6771,"6780":6772,"6992":6994,"6993":6994,"6998":6994,"6999":6994,"7072":7074,"7073":7074,"7078":7074,"7079":7074,"7104":7106,"7105":7106,"7110":7106,"7111":7106,"7136":7138,"7137":7138,"7142":7138,"7143":7138,"7168":7170,"7169":7170,"7174":7170,"7175":7170,"7216":7218,"7217":7218,"7222":7218,"7223":7218,"7248":7250,"7249":7250,"7254":7250,"7255":7250,"7264":7250,"7265":7250,"7270":7250,"7271":7250,"7334":7328,"7335":7328,"7342":7328,"7343":7328,"7396":7392,"7397":7392,"7398":7392,"7399":7392,"7504":7218,"7505":7218,"7510":7218,"7511":7218}} \ No newline at end of file +{"knownStates":{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","497":"Tall Grass","498":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1614":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2640":"Slime Block","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3280":"Shulker Box","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3488":"Dyed Shulker Box","3489":"Dyed Shulker Box","3490":"Dyed Shulker Box","3491":"Dyed Shulker Box","3492":"Dyed Shulker Box","3493":"Dyed Shulker Box","3494":"Dyed Shulker Box","3495":"Dyed Shulker Box","3496":"Dyed Shulker Box","3497":"Dyed Shulker Box","3498":"Dyed Shulker Box","3499":"Dyed Shulker Box","3500":"Dyed Shulker Box","3501":"Dyed Shulker Box","3502":"Dyed Shulker Box","3503":"Dyed Shulker Box","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6274":"Wall Coral Fan","6276":"Wall Coral Fan","6278":"Wall Coral Fan","6280":"Wall Coral Fan","6282":"Wall Coral Fan","6284":"Wall Coral Fan","6286":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7218":"Blast Furnace","7219":"Blast Furnace","7220":"Blast Furnace","7221":"Blast Furnace","7250":"Smoker","7251":"Smoker","7252":"Smoker","7253":"Smoker","7266":"Smoker","7267":"Smoker","7268":"Smoker","7269":"Smoker","7296":"Fletching Table","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7376":"Bell","7377":"Bell","7378":"Bell","7379":"Bell","7380":"Bell","7381":"Bell","7382":"Bell","7383":"Bell","7384":"Bell","7385":"Bell","7386":"Bell","7387":"Bell","7388":"Bell","7389":"Bell","7390":"Bell","7391":"Bell","7392":"Sweet Berry Bush","7393":"Sweet Berry Bush","7394":"Sweet Berry Bush","7395":"Sweet Berry Bush","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood","7480":"Stripped Oak Wood","7481":"Stripped Spruce Wood","7482":"Stripped Birch Wood","7483":"Stripped Jungle Wood","7484":"Stripped Acacia Wood","7485":"Stripped Dark Oak Wood","7506":"Blast Furnace","7507":"Blast Furnace","7508":"Blast Furnace","7509":"Blast Furnace"},"remaps":{"284":7472,"285":7473,"286":7474,"287":7475,"438":432,"439":432,"446":432,"447":432,"454":448,"455":448,"462":448,"463":448,"496":498,"499":498,"696":688,"697":689,"698":690,"699":691,"700":692,"701":693,"702":694,"703":695,"800":805,"806":805,"807":805,"864":866,"865":866,"870":866,"871":866,"976":978,"977":978,"982":978,"983":978,"992":978,"993":978,"998":978,"999":978,"1036":1027,"1037":1027,"1038":1027,"1039":1027,"1040":1042,"1041":1042,"1046":1042,"1047":1042,"1066":1056,"1067":1056,"1068":1056,"1069":1056,"1070":1056,"1071":1056,"1088":1090,"1089":1090,"1094":1090,"1095":1090,"1148":1139,"1149":1139,"1150":1139,"1151":1139,"1200":1221,"1206":1221,"1207":1221,"1216":1221,"1222":1221,"1223":1221,"1238":1232,"1239":1232,"1246":1232,"1247":1232,"1377":1376,"1378":1376,"1379":1376,"1440":1441,"1443":1441,"1479":1472,"1595":1598,"1596":1598,"1597":1598,"1610":1594,"1611":1614,"1612":1614,"1613":1614,"1615":1599,"2022":2016,"2023":2016,"2030":2016,"2031":2016,"2044":2032,"2045":2032,"2046":2032,"2047":2032,"2080":2082,"2081":2082,"2086":2082,"2087":2082,"2241":2240,"2242":2240,"2243":2240,"2244":2240,"2245":2240,"2246":2240,"2247":2240,"2248":2240,"2249":2240,"2250":2240,"2251":2240,"2252":2240,"2253":2240,"2254":2240,"2255":2240,"2294":2288,"2295":2288,"2302":2288,"2303":2288,"2304":2306,"2310":2306,"2311":2306,"2312":2306,"2313":2306,"2314":2306,"2315":2306,"2316":2306,"2317":2306,"2318":2306,"2319":2306,"2332":2322,"2333":2322,"2334":2322,"2335":2322,"2336":2338,"2337":2338,"2342":2338,"2343":2338,"2392":2386,"2393":2386,"2394":2386,"2395":2386,"2396":2386,"2397":2386,"2398":2386,"2399":2386,"2400":2386,"2401":2386,"2402":2386,"2403":2386,"2404":2386,"2405":2386,"2406":2386,"2407":2386,"2465":2464,"2470":2464,"2471":2464,"2473":2464,"2478":2464,"2479":2464,"2493":2481,"2494":2482,"2520":2512,"2521":2513,"2522":2514,"2523":2515,"2524":2516,"2525":2517,"2604":7476,"2605":7477,"2732":2720,"2832":2834,"2833":2834,"2838":2834,"2839":2834,"2904":2896,"2905":2897,"2906":2898,"2907":2899,"2908":2900,"2909":2901,"2910":2902,"2911":2903,"3100":3091,"3101":3091,"3102":3091,"3103":3091,"3116":3107,"3117":3107,"3118":3107,"3119":3107,"3132":3123,"3133":3123,"3134":3123,"3135":3123,"3148":3139,"3149":3139,"3150":3139,"3151":3139,"3164":3155,"3165":3155,"3166":3155,"3167":3155,"3230":3218,"3232":3237,"3238":3237,"3239":3237,"3240":3245,"3246":3245,"3247":3245,"3264":3269,"3270":3269,"3271":3269,"3272":3277,"3278":3277,"3279":3277,"3334":3328,"3335":3328,"3468":3456,"3504":3506,"3505":3506,"3510":3506,"3511":3506,"3520":3522,"3521":3522,"3526":3522,"3527":3522,"3536":3538,"3537":3538,"3542":3538,"3543":3538,"3552":3554,"3553":3554,"3558":3554,"3559":3554,"3568":3570,"3569":3570,"3574":3570,"3575":3570,"3584":3586,"3585":3586,"3590":3586,"3591":3586,"3600":3602,"3601":3602,"3606":3602,"3607":3602,"3616":3618,"3617":3618,"3622":3618,"3623":3618,"3632":3634,"3633":3634,"3638":3634,"3639":3634,"3648":3650,"3649":3650,"3654":3650,"3655":3650,"3664":3666,"3665":3666,"3670":3666,"3671":3666,"3696":3698,"3697":3698,"3702":3698,"3703":3698,"3712":3714,"3713":3714,"3718":3714,"3719":3714,"3728":3730,"3729":3730,"3734":3730,"3735":3730,"3744":3746,"3745":3746,"3750":3746,"3751":3746,"3760":3762,"3761":3762,"3766":3762,"3767":3762,"3824":3829,"3830":3829,"3831":3829,"3955":3952,"4163":4160,"4179":4176,"4195":4192,"4211":4208,"4227":4224,"4243":4240,"6181":6176,"6182":6176,"6183":6176,"6197":6192,"6198":6192,"6199":6192,"6205":6192,"6206":6192,"6207":6192,"6213":6208,"6214":6208,"6215":6208,"6221":6208,"6222":6208,"6223":6208,"6229":6208,"6230":6208,"6231":6208,"6237":6208,"6238":6208,"6239":6208,"6273":6248,"6275":6248,"6277":6248,"6279":6248,"6281":6248,"6283":6248,"6285":6248,"6287":6248,"6326":6320,"6327":6320,"6334":6320,"6335":6320,"6342":6336,"6343":6336,"6350":6336,"6351":6336,"6358":6352,"6359":6352,"6366":6352,"6367":6352,"6374":6368,"6375":6368,"6382":6368,"6383":6368,"6390":6384,"6391":6384,"6398":6384,"6399":6384,"6694":6688,"6695":6688,"6702":6688,"6703":6688,"6760":6752,"6761":6753,"6762":6754,"6763":6755,"6764":6756,"6765":6757,"6766":6758,"6767":6759,"6776":6768,"6777":6769,"6778":6770,"6779":6771,"6780":6772,"6992":6994,"6993":6994,"6998":6994,"6999":6994,"7072":7074,"7073":7074,"7078":7074,"7079":7074,"7104":7106,"7105":7106,"7110":7106,"7111":7106,"7136":7138,"7137":7138,"7142":7138,"7143":7138,"7168":7170,"7169":7170,"7174":7170,"7175":7170,"7216":7218,"7217":7218,"7222":7218,"7223":7218,"7248":7250,"7249":7250,"7254":7250,"7255":7250,"7264":7250,"7265":7250,"7270":7250,"7271":7250,"7334":7328,"7335":7328,"7342":7328,"7343":7328,"7396":7392,"7397":7392,"7398":7392,"7399":7392,"7504":7218,"7505":7218,"7510":7218,"7511":7218}} \ No newline at end of file From ec2699ffee7e29913dd9490fd5e6c5f5b752c030 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 12 Oct 2021 22:15:52 +0100 Subject: [PATCH 2968/3224] DefaultPermissions: fix description of timings command permission --- src/permission/DefaultPermissions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/permission/DefaultPermissions.php b/src/permission/DefaultPermissions.php index 371a970dbb..8e0bb5a01c 100644 --- a/src/permission/DefaultPermissions.php +++ b/src/permission/DefaultPermissions.php @@ -105,7 +105,7 @@ abstract class DefaultPermissions{ self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_STATUS, "Allows the user to view the server performance"), [$operatorRoot]); self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_GC, "Allows the user to fire garbage collection tasks"), [$operatorRoot]); self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_DUMPMEMORY, "Allows the user to dump memory contents"), [$consoleRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_TIMINGS, "Allows the user to records timings for all plugin events"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_TIMINGS, "Allows the user to record timings to analyse server performance"), [$operatorRoot]); self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_SPAWNPOINT, "Allows the user to change player's spawnpoint"), [$operatorRoot]); self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_SETWORLDSPAWN, "Allows the user to change the world spawn"), [$operatorRoot]); self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_TRANSFERSERVER, "Allows the user to transfer self to another server"), [$operatorRoot]); From aefa0afd7ca91d345ec903ba0abde8f1cd31f6f2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 12 Oct 2021 22:17:46 +0100 Subject: [PATCH 2969/3224] DefaultPermissions: Order registrations alphabetically --- src/permission/DefaultPermissions.php | 87 ++++++++++++--------------- 1 file changed, 39 insertions(+), 48 deletions(-) diff --git a/src/permission/DefaultPermissions.php b/src/permission/DefaultPermissions.php index 8e0bb5a01c..3145fda584 100644 --- a/src/permission/DefaultPermissions.php +++ b/src/permission/DefaultPermissions.php @@ -51,65 +51,56 @@ abstract class DefaultPermissions{ self::registerPermission(new Permission(DefaultPermissionNames::BROADCAST_ADMIN, "Allows the user to receive administrative broadcasts"), [$operatorRoot]); self::registerPermission(new Permission(DefaultPermissionNames::BROADCAST_USER, "Allows the user to receive user broadcasts"), [$everyoneRoot]); - - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_WHITELIST_ADD, "Allows the user to add a player to the server whitelist"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_WHITELIST_REMOVE, "Allows the user to remove a player from the server whitelist"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_WHITELIST_RELOAD, "Allows the user to reload the server whitelist"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_WHITELIST_ENABLE, "Allows the user to enable the server whitelist"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_WHITELIST_DISABLE, "Allows the user to disable the server whitelist"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_WHITELIST_LIST, "Allows the user to list all players on the server whitelist"), [$operatorRoot]); - - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_BAN_PLAYER, "Allows the user to ban players"), [$operatorRoot]); self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_BAN_IP, "Allows the user to ban IP addresses"), [$operatorRoot]); self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_BAN_LIST, "Allows the user to list banned players"), [$operatorRoot]); - - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_UNBAN_PLAYER, "Allows the user to unban players"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_UNBAN_IP, "Allows the user to unban IP addresses"), [$operatorRoot]); - + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_BAN_PLAYER, "Allows the user to ban players"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_CLEAR_OTHER, "Allows the user to clear inventory of other players"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_CLEAR_SELF, "Allows the user to clear their own inventory"), [$everyoneRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_DEFAULTGAMEMODE, "Allows the user to change the default gamemode"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_DIFFICULTY, "Allows the user to change the game difficulty"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_DUMPMEMORY, "Allows the user to dump memory contents"), [$consoleRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_EFFECT, "Allows the user to give/take potion effects"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_ENCHANT, "Allows the user to enchant items"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_GAMEMODE, "Allows the user to change the gamemode of players"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_GC, "Allows the user to fire garbage collection tasks"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_GIVE, "Allows the user to give items to players"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_HELP, "Allows the user to view the help menu"), [$everyoneRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_KICK, "Allows the user to kick players"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_KILL_OTHER, "Allows the user to kill other players"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_KILL_SELF, "Allows the user to commit suicide"), [$everyoneRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_LIST, "Allows the user to list all online players"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_ME, "Allows the user to perform a chat action"), [$everyoneRoot]); self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_OP_GIVE, "Allows the user to give a player operator status"), [$operatorRoot]); self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_OP_TAKE, "Allows the user to take a player's operator status"), [$operatorRoot]); - - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_SAVE_ENABLE, "Allows the user to enable automatic saving"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_PARTICLE, "Allows the user to create particle effects"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_PLUGINS, "Allows the user to view the list of plugins"), [$operatorRoot]); self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_SAVE_DISABLE, "Allows the user to disable automatic saving"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_SAVE_ENABLE, "Allows the user to enable automatic saving"), [$operatorRoot]); self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_SAVE_PERFORM, "Allows the user to perform a manual save"), [$operatorRoot]); - + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_SAY, "Allows the user to talk as the console"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_SEED, "Allows the user to view the seed of the world"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_SETWORLDSPAWN, "Allows the user to change the world spawn"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_SPAWNPOINT, "Allows the user to change player's spawnpoint"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_STATUS, "Allows the user to view the server performance"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_STOP, "Allows the user to stop the server"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_TELEPORT, "Allows the user to teleport players"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_TELL, "Allows the user to privately message another player"), [$everyoneRoot]); self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_TIME_ADD, "Allows the user to fast-forward time"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_TIME_QUERY, "Allows the user query the time"), [$operatorRoot]); self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_TIME_SET, "Allows the user to change the time"), [$operatorRoot]); self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_TIME_START, "Allows the user to restart the time"), [$operatorRoot]); self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_TIME_STOP, "Allows the user to stop the time"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_TIME_QUERY, "Allows the user query the time"), [$operatorRoot]); - - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_KILL_SELF, "Allows the user to commit suicide"), [$everyoneRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_KILL_OTHER, "Allows the user to kill other players"), [$operatorRoot]); - - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_CLEAR_SELF, "Allows the user to clear their own inventory"), [$everyoneRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_CLEAR_OTHER, "Allows the user to clear inventory of other players"), [$operatorRoot]); - - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_ME, "Allows the user to perform a chat action"), [$everyoneRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_TELL, "Allows the user to privately message another player"), [$everyoneRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_SAY, "Allows the user to talk as the console"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_GIVE, "Allows the user to give items to players"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_EFFECT, "Allows the user to give/take potion effects"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_ENCHANT, "Allows the user to enchant items"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_PARTICLE, "Allows the user to create particle effects"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_TELEPORT, "Allows the user to teleport players"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_KICK, "Allows the user to kick players"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_STOP, "Allows the user to stop the server"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_LIST, "Allows the user to list all online players"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_HELP, "Allows the user to view the help menu"), [$everyoneRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_PLUGINS, "Allows the user to view the list of plugins"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_VERSION, "Allows the user to view the version of the server"), [$everyoneRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_GAMEMODE, "Allows the user to change the gamemode of players"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_DEFAULTGAMEMODE, "Allows the user to change the default gamemode"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_SEED, "Allows the user to view the seed of the world"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_STATUS, "Allows the user to view the server performance"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_GC, "Allows the user to fire garbage collection tasks"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_DUMPMEMORY, "Allows the user to dump memory contents"), [$consoleRoot]); self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_TIMINGS, "Allows the user to record timings to analyse server performance"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_SPAWNPOINT, "Allows the user to change player's spawnpoint"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_SETWORLDSPAWN, "Allows the user to change the world spawn"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_TRANSFERSERVER, "Allows the user to transfer self to another server"), [$operatorRoot]); self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_TITLE, "Allows the user to send a title to the specified player"), [$operatorRoot]); - self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_DIFFICULTY, "Allows the user to change the game difficulty"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_TRANSFERSERVER, "Allows the user to transfer self to another server"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_UNBAN_IP, "Allows the user to unban IP addresses"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_UNBAN_PLAYER, "Allows the user to unban players"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_VERSION, "Allows the user to view the version of the server"), [$everyoneRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_WHITELIST_ADD, "Allows the user to add a player to the server whitelist"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_WHITELIST_DISABLE, "Allows the user to disable the server whitelist"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_WHITELIST_ENABLE, "Allows the user to enable the server whitelist"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_WHITELIST_LIST, "Allows the user to list all players on the server whitelist"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_WHITELIST_RELOAD, "Allows the user to reload the server whitelist"), [$operatorRoot]); + self::registerPermission(new Permission(DefaultPermissionNames::COMMAND_WHITELIST_REMOVE, "Allows the user to remove a player from the server whitelist"), [$operatorRoot]); } } From b65e89b605aeba5f7958d3cbb6db47e766cd6f9f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 Oct 2021 00:01:56 +0100 Subject: [PATCH 2970/3224] Release 4.0.0-BETA5 --- changelogs/4.0.md | 50 +++++++++++++++++++++++++++++++++++++++++++++ src/VersionInfo.php | 4 ++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index 88914ea8a5..70add2c997 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1393,3 +1393,53 @@ Released 6th October 2021. ### Utils - The following API methods have signature changes: - `Process::kill()` now requires an additional `bool $subprocesses` parameter. + +# 4.0.0-BETA5 +Released 12th October 2021. + +## General +- Exception log format has been changed. Now, exception info is logged in one big block message. This saves space on the console and improves readability, as well as reducing the ability for bad `ThreadedLoggerAttachment`s to break exception output. +- Log messages are now pushed to `server.log` before calling logger attachment, instead of after. This fixes messages not being written to disk when an error occurs in a logger attachment. +- Improved startup performance when loading many plugins. +- The `worlds` config in `pocketmine.yml` no longer supports attaching the generator settings to the `generator` key (use the `preset` key instead). +- Using an unknown generator in `server.properties` or `pocketmine.yml` will now cause a failure to generate the world. +- Using invalid/incorrect world generator options (presets) in `server.properties` or `pocketmine.yml` will now cause a failure to generate the world. +- Generator options of existing worlds are now validated before loading them. If they are invalid, the server will fail to load them. +- Several more log messages have been localized, including plugin loading errors. + +## Fixes +- Fixed server crash when using `/give` to give an item by ID which doesn't exist in Minecraft. +- Fixed server crash when boolean `server.properties` options were given an integer value (e.g. `0` or `1` instead of `false` or `true`). +- Fixed stats reporting checking for a nonexistent `pocketmine.yml` setting. +- Fixed use of commands without the proper permission sending a message `commands.generic.permission` instead of the proper message. +- Fixed entities set on fire appearing to stay on fire, although not taking any damage. +- Fixed a duplicate `MB` suffix on the `Memory freed` output of `/gc`. +- Fixed the server attempting to generate a world if it failed to load. + +## API +### Block +- The following API methods have been renamed: + - `Block->getPositionOffset()` -> `Block->getModelPositionOffset()`. + +### Event +- `@handleCancelled` PhpDoc annotation can no longer be used on event handlers for non-cancellable events. +- The following API methods have been added: + - `StructureGrowEvent->getPlayer()` + +### Inventory +- The following API methods have been added: + - `Inventory->getAddableItemQuantity()` + +### Scheduler +- `ClosureTask` now permits closures without an explicit return type (useful for arrow functions). + +### Utils +- The following API methods have been added: + - `Config::parseProperties()` + - `Config::writeProperties()` + - `Config::parseList()` + - `Config::writeList()` + +### World +- The following API methods have signature changes: + - `GeneratorManager->registerGenerator()` now requires a `\Closure $presetValidator` parameter. This is used to check generator options of worlds and configs before attempting to use them. diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 8b9fb420b5..3cf7af10b2 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -30,9 +30,9 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; public const BASE_VERSION = "4.0.0-BETA5"; - public const IS_DEVELOPMENT_BUILD = true; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_NUMBER = 0; - public const BUILD_CHANNEL = ""; + public const BUILD_CHANNEL = "beta"; private function __construct(){ //NOOP From ce8af4e3bca90b6778b6b0c47ec88b8a952e60d7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 Oct 2021 00:02:01 +0100 Subject: [PATCH 2971/3224] 4.0.0-BETA6 is next --- src/VersionInfo.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 3cf7af10b2..9bae4e775b 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -29,10 +29,10 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "4.0.0-BETA5"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "4.0.0-BETA6"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_NUMBER = 0; - public const BUILD_CHANNEL = "beta"; + public const BUILD_CHANNEL = ""; private function __construct(){ //NOOP From 6284cd14c7d662e5afe3a50c09010949e5b3fe2c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 Oct 2021 20:19:44 +0100 Subject: [PATCH 2972/3224] LegacyStringToItemParser: added getMappings() --- src/item/LegacyStringToItemParser.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/item/LegacyStringToItemParser.php b/src/item/LegacyStringToItemParser.php index 9edb37c19e..6eb3888c68 100644 --- a/src/item/LegacyStringToItemParser.php +++ b/src/item/LegacyStringToItemParser.php @@ -84,6 +84,14 @@ final class LegacyStringToItemParser{ $this->map[$alias] = $id; } + /** + * @return int[] + * @phpstan-return array + */ + public function getMappings() : array{ + return $this->map; + } + /** * Tries to parse the specified string into Item types. * From b57032428824de5909a8854dc9e0d7952caed5c6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 Oct 2021 20:29:18 +0100 Subject: [PATCH 2973/3224] LegacyStringToItemParser: rely exclusively on item_from_string_bc_map.json, do not interpret integers given as strings fixes #4507 --- resources/item_from_string_bc_map.json | 687 +++++++++++++++++++++++++ src/item/LegacyStringToItemParser.php | 8 +- 2 files changed, 690 insertions(+), 5 deletions(-) diff --git a/resources/item_from_string_bc_map.json b/resources/item_from_string_bc_map.json index 0edc1e7dfb..c12f00a242 100644 --- a/resources/item_from_string_bc_map.json +++ b/resources/item_from_string_bc_map.json @@ -1,4 +1,691 @@ { + "-10": -10, + "-100": -100, + "-101": -101, + "-102": -102, + "-103": -103, + "-104": -104, + "-105": -105, + "-106": -106, + "-107": -107, + "-108": -108, + "-109": -109, + "-11": -11, + "-110": -110, + "-111": -111, + "-112": -112, + "-113": -113, + "-114": -114, + "-115": -115, + "-116": -116, + "-117": -117, + "-118": -118, + "-119": -119, + "-12": -12, + "-120": -120, + "-121": -121, + "-122": -122, + "-123": -123, + "-124": -124, + "-125": -125, + "-126": -126, + "-127": -127, + "-128": -128, + "-129": -129, + "-13": -13, + "-130": -130, + "-131": -131, + "-132": -132, + "-133": -133, + "-134": -134, + "-135": -135, + "-136": -136, + "-137": -137, + "-138": -138, + "-139": -139, + "-14": -14, + "-140": -140, + "-141": -141, + "-142": -142, + "-143": -143, + "-144": -144, + "-145": -145, + "-146": -146, + "-147": -147, + "-148": -148, + "-149": -149, + "-15": -15, + "-150": -150, + "-151": -151, + "-152": -152, + "-153": -153, + "-154": -154, + "-155": -155, + "-156": -156, + "-157": -157, + "-159": -159, + "-16": -16, + "-160": -160, + "-161": -161, + "-162": -162, + "-163": -163, + "-164": -164, + "-165": -165, + "-166": -166, + "-167": -167, + "-168": -168, + "-169": -169, + "-17": -17, + "-170": -170, + "-171": -171, + "-172": -172, + "-173": -173, + "-174": -174, + "-175": -175, + "-176": -176, + "-177": -177, + "-178": -178, + "-179": -179, + "-18": -18, + "-180": -180, + "-181": -181, + "-182": -182, + "-183": -183, + "-184": -184, + "-185": -185, + "-186": -186, + "-187": -187, + "-188": -188, + "-189": -189, + "-19": -19, + "-190": -190, + "-191": -191, + "-192": -192, + "-193": -193, + "-194": -194, + "-195": -195, + "-196": -196, + "-197": -197, + "-198": -198, + "-199": -199, + "-2": -2, + "-20": -20, + "-200": -200, + "-201": -201, + "-202": -202, + "-203": -203, + "-204": -204, + "-206": -206, + "-207": -207, + "-208": -208, + "-209": -209, + "-21": -21, + "-210": -210, + "-211": -211, + "-213": -213, + "-214": -214, + "-22": -22, + "-23": -23, + "-24": -24, + "-25": -25, + "-26": -26, + "-27": -27, + "-28": -28, + "-29": -29, + "-3": -3, + "-30": -30, + "-31": -31, + "-32": -32, + "-33": -33, + "-34": -34, + "-35": -35, + "-36": -36, + "-37": -37, + "-38": -38, + "-39": -39, + "-4": -4, + "-40": -40, + "-41": -41, + "-42": -42, + "-43": -43, + "-44": -44, + "-45": -45, + "-46": -46, + "-47": -47, + "-48": -48, + "-49": -49, + "-5": -5, + "-50": -50, + "-51": -51, + "-52": -52, + "-53": -53, + "-54": -54, + "-55": -55, + "-56": -56, + "-57": -57, + "-58": -58, + "-59": -59, + "-6": -6, + "-60": -60, + "-61": -61, + "-62": -62, + "-63": -63, + "-64": -64, + "-65": -65, + "-66": -66, + "-67": -67, + "-68": -68, + "-69": -69, + "-7": -7, + "-70": -70, + "-71": -71, + "-72": -72, + "-73": -73, + "-74": -74, + "-75": -75, + "-76": -76, + "-77": -77, + "-78": -78, + "-79": -79, + "-8": -8, + "-80": -80, + "-81": -81, + "-82": -82, + "-83": -83, + "-84": -84, + "-85": -85, + "-86": -86, + "-87": -87, + "-88": -88, + "-89": -89, + "-9": -9, + "-90": -90, + "-91": -91, + "-92": -92, + "-93": -93, + "-94": -94, + "-95": -95, + "-96": -96, + "-97": -97, + "-98": -98, + "-99": -99, + "0": 0, + "1": 1, + "10": 10, + "100": 100, + "101": 101, + "102": 102, + "103": 103, + "104": 104, + "105": 105, + "106": 106, + "107": 107, + "108": 108, + "109": 109, + "11": 11, + "110": 110, + "111": 111, + "112": 112, + "113": 113, + "114": 114, + "115": 115, + "116": 116, + "117": 117, + "118": 118, + "119": 119, + "12": 12, + "120": 120, + "121": 121, + "122": 122, + "123": 123, + "124": 124, + "125": 125, + "126": 126, + "127": 127, + "128": 128, + "129": 129, + "13": 13, + "130": 130, + "131": 131, + "132": 132, + "133": 133, + "134": 134, + "135": 135, + "136": 136, + "137": 137, + "138": 138, + "139": 139, + "14": 14, + "140": 140, + "141": 141, + "142": 142, + "143": 143, + "144": 144, + "145": 145, + "146": 146, + "147": 147, + "148": 148, + "149": 149, + "15": 15, + "150": 150, + "151": 151, + "152": 152, + "153": 153, + "154": 154, + "155": 155, + "156": 156, + "157": 157, + "158": 158, + "159": 159, + "16": 16, + "160": 160, + "161": 161, + "162": 162, + "163": 163, + "164": 164, + "165": 165, + "166": 166, + "167": 167, + "168": 168, + "169": 169, + "17": 17, + "170": 170, + "171": 171, + "172": 172, + "173": 173, + "174": 174, + "175": 175, + "176": 176, + "177": 177, + "178": 178, + "179": 179, + "18": 18, + "180": 180, + "181": 181, + "182": 182, + "183": 183, + "184": 184, + "185": 185, + "186": 186, + "187": 187, + "188": 188, + "189": 189, + "19": 19, + "190": 190, + "191": 191, + "192": 192, + "193": 193, + "194": 194, + "195": 195, + "196": 196, + "197": 197, + "198": 198, + "199": 199, + "2": 2, + "20": 20, + "200": 200, + "201": 201, + "202": 202, + "203": 203, + "204": 204, + "205": 205, + "206": 206, + "207": 207, + "208": 208, + "209": 209, + "21": 21, + "213": 213, + "214": 214, + "215": 215, + "216": 216, + "218": 218, + "219": 219, + "22": 22, + "220": 220, + "221": 221, + "222": 222, + "223": 223, + "224": 224, + "225": 225, + "226": 226, + "227": 227, + "228": 228, + "229": 229, + "23": 23, + "231": 231, + "232": 232, + "233": 233, + "234": 234, + "235": 235, + "236": 236, + "237": 237, + "238": 238, + "239": 239, + "24": 24, + "240": 240, + "241": 241, + "243": 243, + "244": 244, + "245": 245, + "246": 246, + "247": 247, + "248": 248, + "249": 249, + "25": 25, + "250": 250, + "251": 251, + "252": 252, + "253": 253, + "254": 254, + "255": 255, + "256": 256, + "257": 257, + "258": 258, + "259": 259, + "26": 26, + "260": 260, + "261": 261, + "262": 262, + "263": 263, + "264": 264, + "265": 265, + "266": 266, + "267": 267, + "268": 268, + "269": 269, + "27": 27, + "270": 270, + "271": 271, + "272": 272, + "273": 273, + "274": 274, + "275": 275, + "276": 276, + "277": 277, + "278": 278, + "279": 279, + "28": 28, + "280": 280, + "281": 281, + "282": 282, + "283": 283, + "284": 284, + "285": 285, + "286": 286, + "287": 287, + "288": 288, + "289": 289, + "29": 29, + "290": 290, + "291": 291, + "292": 292, + "293": 293, + "294": 294, + "295": 295, + "296": 296, + "297": 297, + "298": 298, + "299": 299, + "3": 3, + "30": 30, + "300": 300, + "301": 301, + "302": 302, + "303": 303, + "304": 304, + "305": 305, + "306": 306, + "307": 307, + "308": 308, + "309": 309, + "31": 31, + "310": 310, + "311": 311, + "312": 312, + "313": 313, + "314": 314, + "315": 315, + "316": 316, + "317": 317, + "318": 318, + "319": 319, + "32": 32, + "320": 320, + "321": 321, + "322": 322, + "323": 323, + "324": 324, + "325": 325, + "328": 328, + "329": 329, + "33": 33, + "330": 330, + "331": 331, + "332": 332, + "333": 333, + "334": 334, + "335": 335, + "336": 336, + "337": 337, + "338": 338, + "339": 339, + "34": 34, + "340": 340, + "341": 341, + "342": 342, + "344": 344, + "345": 345, + "346": 346, + "347": 347, + "348": 348, + "349": 349, + "35": 35, + "350": 350, + "351": 351, + "352": 352, + "353": 353, + "354": 354, + "355": 355, + "356": 356, + "357": 357, + "358": 358, + "359": 359, + "36": 36, + "360": 360, + "361": 361, + "362": 362, + "363": 363, + "364": 364, + "365": 365, + "366": 366, + "367": 367, + "368": 368, + "369": 369, + "37": 37, + "370": 370, + "371": 371, + "372": 372, + "373": 373, + "374": 374, + "375": 375, + "376": 376, + "377": 377, + "378": 378, + "379": 379, + "38": 38, + "380": 380, + "381": 381, + "382": 382, + "383": 383, + "384": 384, + "385": 385, + "386": 386, + "387": 387, + "388": 388, + "389": 389, + "39": 39, + "390": 390, + "391": 391, + "392": 392, + "393": 393, + "394": 394, + "395": 395, + "396": 396, + "397": 397, + "398": 398, + "399": 399, + "4": 4, + "40": 40, + "400": 400, + "401": 401, + "402": 402, + "403": 403, + "404": 404, + "405": 405, + "406": 406, + "407": 407, + "408": 408, + "409": 409, + "41": 41, + "410": 410, + "411": 411, + "412": 412, + "413": 413, + "414": 414, + "415": 415, + "416": 416, + "417": 417, + "418": 418, + "419": 419, + "42": 42, + "420": 420, + "421": 421, + "422": 422, + "423": 423, + "424": 424, + "425": 425, + "426": 426, + "427": 427, + "428": 428, + "429": 429, + "43": 43, + "430": 430, + "431": 431, + "432": 432, + "433": 433, + "434": 434, + "437": 437, + "438": 438, + "44": 44, + "441": 441, + "442": 442, + "443": 443, + "444": 444, + "445": 445, + "446": 446, + "447": 447, + "448": 448, + "449": 449, + "45": 45, + "450": 450, + "451": 451, + "452": 452, + "453": 453, + "455": 455, + "457": 457, + "458": 458, + "459": 459, + "46": 46, + "460": 460, + "461": 461, + "462": 462, + "463": 463, + "464": 464, + "465": 465, + "466": 466, + "467": 467, + "468": 468, + "469": 469, + "47": 47, + "470": 470, + "471": 471, + "472": 472, + "473": 473, + "474": 474, + "475": 475, + "476": 476, + "477": 477, + "48": 48, + "49": 49, + "499": 499, + "5": 5, + "50": 50, + "500": 500, + "501": 501, + "502": 502, + "503": 503, + "504": 504, + "505": 505, + "506": 506, + "507": 507, + "508": 508, + "509": 509, + "51": 51, + "510": 510, + "511": 511, + "513": 513, + "52": 52, + "53": 53, + "54": 54, + "55": 55, + "56": 56, + "57": 57, + "58": 58, + "59": 59, + "6": 6, + "60": 60, + "61": 61, + "62": 62, + "63": 63, + "64": 64, + "65": 65, + "66": 66, + "67": 67, + "68": 68, + "69": 69, + "7": 7, + "70": 70, + "71": 71, + "72": 72, + "73": 73, + "74": 74, + "75": 75, + "76": 76, + "77": 77, + "78": 78, + "79": 79, + "8": 8, + "80": 80, + "81": 81, + "82": 82, + "83": 83, + "84": 84, + "85": 85, + "86": 86, + "87": 87, + "88": 88, + "89": 89, + "9": 9, + "90": 90, + "91": 91, + "92": 92, + "93": 93, + "94": 94, + "95": 95, + "96": 96, + "97": 97, + "98": 98, + "99": 99, "acacia_button": -140, "acacia_door": 430, "acacia_door_block": 196, diff --git a/src/item/LegacyStringToItemParser.php b/src/item/LegacyStringToItemParser.php index 6eb3888c68..afe22cd2dd 100644 --- a/src/item/LegacyStringToItemParser.php +++ b/src/item/LegacyStringToItemParser.php @@ -63,8 +63,8 @@ final class LegacyStringToItemParser{ if(!is_array($mappings)) throw new AssumptionFailedError("Invalid mappings format, expected array"); foreach($mappings as $name => $id){ - if(!is_string($name) or !is_int($id)) throw new AssumptionFailedError("Invalid mappings format, expected string keys and int values"); - $result->addMapping($name, $id); + if(!is_int($id)) throw new AssumptionFailedError("Invalid mappings format, expected int values"); + $result->addMapping((string) $name, $id); } return $result; @@ -114,9 +114,7 @@ final class LegacyStringToItemParser{ throw new LegacyStringToItemParserException("Unable to parse \"" . $b[1] . "\" from \"" . $input . "\" as a valid meta value"); } - if(is_numeric($b[0])){ - $item = $this->itemFactory->get((int) $b[0], $meta); - }elseif(isset($this->map[strtolower($b[0])])){ + if(isset($this->map[strtolower($b[0])])){ $item = $this->itemFactory->get($this->map[strtolower($b[0])], $meta); }else{ throw new LegacyStringToItemParserException("Unable to resolve \"" . $input . "\" to a valid item"); From 8523f0fb0bcd83e7ed20ec20525b3a916be7fe45 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 Oct 2021 20:31:24 +0100 Subject: [PATCH 2974/3224] CS fix --- src/item/LegacyStringToItemParser.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/item/LegacyStringToItemParser.php b/src/item/LegacyStringToItemParser.php index afe22cd2dd..ccc824b0df 100644 --- a/src/item/LegacyStringToItemParser.php +++ b/src/item/LegacyStringToItemParser.php @@ -31,7 +31,6 @@ use function file_get_contents; use function is_array; use function is_int; use function is_numeric; -use function is_string; use function json_decode; use function str_replace; use function strtolower; From 2db53775e0f89512167db166303e05e7e24ef0f6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 Oct 2021 21:01:59 +0100 Subject: [PATCH 2975/3224] Sort item_from_string_bc_map using SORT_NATURAL --- resources/item_from_string_bc_map.json | 1138 ++++++++++++------------ 1 file changed, 569 insertions(+), 569 deletions(-) diff --git a/resources/item_from_string_bc_map.json b/resources/item_from_string_bc_map.json index c12f00a242..c5c502e9a2 100644 --- a/resources/item_from_string_bc_map.json +++ b/resources/item_from_string_bc_map.json @@ -1,129 +1,24 @@ { - "-10": -10, - "-100": -100, - "-101": -101, - "-102": -102, - "-103": -103, - "-104": -104, - "-105": -105, - "-106": -106, - "-107": -107, - "-108": -108, - "-109": -109, - "-11": -11, - "-110": -110, - "-111": -111, - "-112": -112, - "-113": -113, - "-114": -114, - "-115": -115, - "-116": -116, - "-117": -117, - "-118": -118, - "-119": -119, - "-12": -12, - "-120": -120, - "-121": -121, - "-122": -122, - "-123": -123, - "-124": -124, - "-125": -125, - "-126": -126, - "-127": -127, - "-128": -128, - "-129": -129, - "-13": -13, - "-130": -130, - "-131": -131, - "-132": -132, - "-133": -133, - "-134": -134, - "-135": -135, - "-136": -136, - "-137": -137, - "-138": -138, - "-139": -139, - "-14": -14, - "-140": -140, - "-141": -141, - "-142": -142, - "-143": -143, - "-144": -144, - "-145": -145, - "-146": -146, - "-147": -147, - "-148": -148, - "-149": -149, - "-15": -15, - "-150": -150, - "-151": -151, - "-152": -152, - "-153": -153, - "-154": -154, - "-155": -155, - "-156": -156, - "-157": -157, - "-159": -159, - "-16": -16, - "-160": -160, - "-161": -161, - "-162": -162, - "-163": -163, - "-164": -164, - "-165": -165, - "-166": -166, - "-167": -167, - "-168": -168, - "-169": -169, - "-17": -17, - "-170": -170, - "-171": -171, - "-172": -172, - "-173": -173, - "-174": -174, - "-175": -175, - "-176": -176, - "-177": -177, - "-178": -178, - "-179": -179, - "-18": -18, - "-180": -180, - "-181": -181, - "-182": -182, - "-183": -183, - "-184": -184, - "-185": -185, - "-186": -186, - "-187": -187, - "-188": -188, - "-189": -189, - "-19": -19, - "-190": -190, - "-191": -191, - "-192": -192, - "-193": -193, - "-194": -194, - "-195": -195, - "-196": -196, - "-197": -197, - "-198": -198, - "-199": -199, "-2": -2, + "-3": -3, + "-4": -4, + "-5": -5, + "-6": -6, + "-7": -7, + "-8": -8, + "-9": -9, + "-10": -10, + "-11": -11, + "-12": -12, + "-13": -13, + "-14": -14, + "-15": -15, + "-16": -16, + "-17": -17, + "-18": -18, + "-19": -19, "-20": -20, - "-200": -200, - "-201": -201, - "-202": -202, - "-203": -203, - "-204": -204, - "-206": -206, - "-207": -207, - "-208": -208, - "-209": -209, "-21": -21, - "-210": -210, - "-211": -211, - "-213": -213, - "-214": -214, "-22": -22, "-23": -23, "-24": -24, @@ -132,7 +27,6 @@ "-27": -27, "-28": -28, "-29": -29, - "-3": -3, "-30": -30, "-31": -31, "-32": -32, @@ -143,7 +37,6 @@ "-37": -37, "-38": -38, "-39": -39, - "-4": -4, "-40": -40, "-41": -41, "-42": -42, @@ -154,7 +47,6 @@ "-47": -47, "-48": -48, "-49": -49, - "-5": -5, "-50": -50, "-51": -51, "-52": -52, @@ -165,7 +57,6 @@ "-57": -57, "-58": -58, "-59": -59, - "-6": -6, "-60": -60, "-61": -61, "-62": -62, @@ -176,7 +67,6 @@ "-67": -67, "-68": -68, "-69": -69, - "-7": -7, "-70": -70, "-71": -71, "-72": -72, @@ -187,7 +77,6 @@ "-77": -77, "-78": -78, "-79": -79, - "-8": -8, "-80": -80, "-81": -81, "-82": -82, @@ -198,7 +87,6 @@ "-87": -87, "-88": -88, "-89": -89, - "-9": -9, "-90": -90, "-91": -91, "-92": -92, @@ -209,431 +97,170 @@ "-97": -97, "-98": -98, "-99": -99, + "-100": -100, + "-101": -101, + "-102": -102, + "-103": -103, + "-104": -104, + "-105": -105, + "-106": -106, + "-107": -107, + "-108": -108, + "-109": -109, + "-110": -110, + "-111": -111, + "-112": -112, + "-113": -113, + "-114": -114, + "-115": -115, + "-116": -116, + "-117": -117, + "-118": -118, + "-119": -119, + "-120": -120, + "-121": -121, + "-122": -122, + "-123": -123, + "-124": -124, + "-125": -125, + "-126": -126, + "-127": -127, + "-128": -128, + "-129": -129, + "-130": -130, + "-131": -131, + "-132": -132, + "-133": -133, + "-134": -134, + "-135": -135, + "-136": -136, + "-137": -137, + "-138": -138, + "-139": -139, + "-140": -140, + "-141": -141, + "-142": -142, + "-143": -143, + "-144": -144, + "-145": -145, + "-146": -146, + "-147": -147, + "-148": -148, + "-149": -149, + "-150": -150, + "-151": -151, + "-152": -152, + "-153": -153, + "-154": -154, + "-155": -155, + "-156": -156, + "-157": -157, + "-159": -159, + "-160": -160, + "-161": -161, + "-162": -162, + "-163": -163, + "-164": -164, + "-165": -165, + "-166": -166, + "-167": -167, + "-168": -168, + "-169": -169, + "-170": -170, + "-171": -171, + "-172": -172, + "-173": -173, + "-174": -174, + "-175": -175, + "-176": -176, + "-177": -177, + "-178": -178, + "-179": -179, + "-180": -180, + "-181": -181, + "-182": -182, + "-183": -183, + "-184": -184, + "-185": -185, + "-186": -186, + "-187": -187, + "-188": -188, + "-189": -189, + "-190": -190, + "-191": -191, + "-192": -192, + "-193": -193, + "-194": -194, + "-195": -195, + "-196": -196, + "-197": -197, + "-198": -198, + "-199": -199, + "-200": -200, + "-201": -201, + "-202": -202, + "-203": -203, + "-204": -204, + "-206": -206, + "-207": -207, + "-208": -208, + "-209": -209, + "-210": -210, + "-211": -211, + "-213": -213, + "-214": -214, "0": 0, "1": 1, - "10": 10, - "100": 100, - "101": 101, - "102": 102, - "103": 103, - "104": 104, - "105": 105, - "106": 106, - "107": 107, - "108": 108, - "109": 109, - "11": 11, - "110": 110, - "111": 111, - "112": 112, - "113": 113, - "114": 114, - "115": 115, - "116": 116, - "117": 117, - "118": 118, - "119": 119, - "12": 12, - "120": 120, - "121": 121, - "122": 122, - "123": 123, - "124": 124, - "125": 125, - "126": 126, - "127": 127, - "128": 128, - "129": 129, - "13": 13, - "130": 130, - "131": 131, - "132": 132, - "133": 133, - "134": 134, - "135": 135, - "136": 136, - "137": 137, - "138": 138, - "139": 139, - "14": 14, - "140": 140, - "141": 141, - "142": 142, - "143": 143, - "144": 144, - "145": 145, - "146": 146, - "147": 147, - "148": 148, - "149": 149, - "15": 15, - "150": 150, - "151": 151, - "152": 152, - "153": 153, - "154": 154, - "155": 155, - "156": 156, - "157": 157, - "158": 158, - "159": 159, - "16": 16, - "160": 160, - "161": 161, - "162": 162, - "163": 163, - "164": 164, - "165": 165, - "166": 166, - "167": 167, - "168": 168, - "169": 169, - "17": 17, - "170": 170, - "171": 171, - "172": 172, - "173": 173, - "174": 174, - "175": 175, - "176": 176, - "177": 177, - "178": 178, - "179": 179, - "18": 18, - "180": 180, - "181": 181, - "182": 182, - "183": 183, - "184": 184, - "185": 185, - "186": 186, - "187": 187, - "188": 188, - "189": 189, - "19": 19, - "190": 190, - "191": 191, - "192": 192, - "193": 193, - "194": 194, - "195": 195, - "196": 196, - "197": 197, - "198": 198, - "199": 199, "2": 2, - "20": 20, - "200": 200, - "201": 201, - "202": 202, - "203": 203, - "204": 204, - "205": 205, - "206": 206, - "207": 207, - "208": 208, - "209": 209, - "21": 21, - "213": 213, - "214": 214, - "215": 215, - "216": 216, - "218": 218, - "219": 219, - "22": 22, - "220": 220, - "221": 221, - "222": 222, - "223": 223, - "224": 224, - "225": 225, - "226": 226, - "227": 227, - "228": 228, - "229": 229, - "23": 23, - "231": 231, - "232": 232, - "233": 233, - "234": 234, - "235": 235, - "236": 236, - "237": 237, - "238": 238, - "239": 239, - "24": 24, - "240": 240, - "241": 241, - "243": 243, - "244": 244, - "245": 245, - "246": 246, - "247": 247, - "248": 248, - "249": 249, - "25": 25, - "250": 250, - "251": 251, - "252": 252, - "253": 253, - "254": 254, - "255": 255, - "256": 256, - "257": 257, - "258": 258, - "259": 259, - "26": 26, - "260": 260, - "261": 261, - "262": 262, - "263": 263, - "264": 264, - "265": 265, - "266": 266, - "267": 267, - "268": 268, - "269": 269, - "27": 27, - "270": 270, - "271": 271, - "272": 272, - "273": 273, - "274": 274, - "275": 275, - "276": 276, - "277": 277, - "278": 278, - "279": 279, - "28": 28, - "280": 280, - "281": 281, - "282": 282, - "283": 283, - "284": 284, - "285": 285, - "286": 286, - "287": 287, - "288": 288, - "289": 289, - "29": 29, - "290": 290, - "291": 291, - "292": 292, - "293": 293, - "294": 294, - "295": 295, - "296": 296, - "297": 297, - "298": 298, - "299": 299, "3": 3, - "30": 30, - "300": 300, - "301": 301, - "302": 302, - "303": 303, - "304": 304, - "305": 305, - "306": 306, - "307": 307, - "308": 308, - "309": 309, - "31": 31, - "310": 310, - "311": 311, - "312": 312, - "313": 313, - "314": 314, - "315": 315, - "316": 316, - "317": 317, - "318": 318, - "319": 319, - "32": 32, - "320": 320, - "321": 321, - "322": 322, - "323": 323, - "324": 324, - "325": 325, - "328": 328, - "329": 329, - "33": 33, - "330": 330, - "331": 331, - "332": 332, - "333": 333, - "334": 334, - "335": 335, - "336": 336, - "337": 337, - "338": 338, - "339": 339, - "34": 34, - "340": 340, - "341": 341, - "342": 342, - "344": 344, - "345": 345, - "346": 346, - "347": 347, - "348": 348, - "349": 349, - "35": 35, - "350": 350, - "351": 351, - "352": 352, - "353": 353, - "354": 354, - "355": 355, - "356": 356, - "357": 357, - "358": 358, - "359": 359, - "36": 36, - "360": 360, - "361": 361, - "362": 362, - "363": 363, - "364": 364, - "365": 365, - "366": 366, - "367": 367, - "368": 368, - "369": 369, - "37": 37, - "370": 370, - "371": 371, - "372": 372, - "373": 373, - "374": 374, - "375": 375, - "376": 376, - "377": 377, - "378": 378, - "379": 379, - "38": 38, - "380": 380, - "381": 381, - "382": 382, - "383": 383, - "384": 384, - "385": 385, - "386": 386, - "387": 387, - "388": 388, - "389": 389, - "39": 39, - "390": 390, - "391": 391, - "392": 392, - "393": 393, - "394": 394, - "395": 395, - "396": 396, - "397": 397, - "398": 398, - "399": 399, "4": 4, + "5": 5, + "6": 6, + "7": 7, + "8": 8, + "9": 9, + "10": 10, + "11": 11, + "12": 12, + "13": 13, + "14": 14, + "15": 15, + "16": 16, + "17": 17, + "18": 18, + "19": 19, + "20": 20, + "21": 21, + "22": 22, + "23": 23, + "24": 24, + "25": 25, + "26": 26, + "27": 27, + "28": 28, + "29": 29, + "30": 30, + "31": 31, + "32": 32, + "33": 33, + "34": 34, + "35": 35, + "36": 36, + "37": 37, + "38": 38, + "39": 39, "40": 40, - "400": 400, - "401": 401, - "402": 402, - "403": 403, - "404": 404, - "405": 405, - "406": 406, - "407": 407, - "408": 408, - "409": 409, "41": 41, - "410": 410, - "411": 411, - "412": 412, - "413": 413, - "414": 414, - "415": 415, - "416": 416, - "417": 417, - "418": 418, - "419": 419, "42": 42, - "420": 420, - "421": 421, - "422": 422, - "423": 423, - "424": 424, - "425": 425, - "426": 426, - "427": 427, - "428": 428, - "429": 429, "43": 43, - "430": 430, - "431": 431, - "432": 432, - "433": 433, - "434": 434, - "437": 437, - "438": 438, "44": 44, - "441": 441, - "442": 442, - "443": 443, - "444": 444, - "445": 445, - "446": 446, - "447": 447, - "448": 448, - "449": 449, "45": 45, - "450": 450, - "451": 451, - "452": 452, - "453": 453, - "455": 455, - "457": 457, - "458": 458, - "459": 459, "46": 46, - "460": 460, - "461": 461, - "462": 462, - "463": 463, - "464": 464, - "465": 465, - "466": 466, - "467": 467, - "468": 468, - "469": 469, "47": 47, - "470": 470, - "471": 471, - "472": 472, - "473": 473, - "474": 474, - "475": 475, - "476": 476, - "477": 477, "48": 48, "49": 49, - "499": 499, - "5": 5, "50": 50, - "500": 500, - "501": 501, - "502": 502, - "503": 503, - "504": 504, - "505": 505, - "506": 506, - "507": 507, - "508": 508, - "509": 509, "51": 51, - "510": 510, - "511": 511, - "513": 513, "52": 52, "53": 53, "54": 54, @@ -642,7 +269,6 @@ "57": 57, "58": 58, "59": 59, - "6": 6, "60": 60, "61": 61, "62": 62, @@ -653,7 +279,6 @@ "67": 67, "68": 68, "69": 69, - "7": 7, "70": 70, "71": 71, "72": 72, @@ -664,7 +289,6 @@ "77": 77, "78": 78, "79": 79, - "8": 8, "80": 80, "81": 81, "82": 82, @@ -675,7 +299,6 @@ "87": 87, "88": 88, "89": 89, - "9": 9, "90": 90, "91": 91, "92": 92, @@ -686,6 +309,383 @@ "97": 97, "98": 98, "99": 99, + "100": 100, + "101": 101, + "102": 102, + "103": 103, + "104": 104, + "105": 105, + "106": 106, + "107": 107, + "108": 108, + "109": 109, + "110": 110, + "111": 111, + "112": 112, + "113": 113, + "114": 114, + "115": 115, + "116": 116, + "117": 117, + "118": 118, + "119": 119, + "120": 120, + "121": 121, + "122": 122, + "123": 123, + "124": 124, + "125": 125, + "126": 126, + "127": 127, + "128": 128, + "129": 129, + "130": 130, + "131": 131, + "132": 132, + "133": 133, + "134": 134, + "135": 135, + "136": 136, + "137": 137, + "138": 138, + "139": 139, + "140": 140, + "141": 141, + "142": 142, + "143": 143, + "144": 144, + "145": 145, + "146": 146, + "147": 147, + "148": 148, + "149": 149, + "150": 150, + "151": 151, + "152": 152, + "153": 153, + "154": 154, + "155": 155, + "156": 156, + "157": 157, + "158": 158, + "159": 159, + "160": 160, + "161": 161, + "162": 162, + "163": 163, + "164": 164, + "165": 165, + "166": 166, + "167": 167, + "168": 168, + "169": 169, + "170": 170, + "171": 171, + "172": 172, + "173": 173, + "174": 174, + "175": 175, + "176": 176, + "177": 177, + "178": 178, + "179": 179, + "180": 180, + "181": 181, + "182": 182, + "183": 183, + "184": 184, + "185": 185, + "186": 186, + "187": 187, + "188": 188, + "189": 189, + "190": 190, + "191": 191, + "192": 192, + "193": 193, + "194": 194, + "195": 195, + "196": 196, + "197": 197, + "198": 198, + "199": 199, + "200": 200, + "201": 201, + "202": 202, + "203": 203, + "204": 204, + "205": 205, + "206": 206, + "207": 207, + "208": 208, + "209": 209, + "213": 213, + "214": 214, + "215": 215, + "216": 216, + "218": 218, + "219": 219, + "220": 220, + "221": 221, + "222": 222, + "223": 223, + "224": 224, + "225": 225, + "226": 226, + "227": 227, + "228": 228, + "229": 229, + "231": 231, + "232": 232, + "233": 233, + "234": 234, + "235": 235, + "236": 236, + "237": 237, + "238": 238, + "239": 239, + "240": 240, + "241": 241, + "243": 243, + "244": 244, + "245": 245, + "246": 246, + "247": 247, + "248": 248, + "249": 249, + "250": 250, + "251": 251, + "252": 252, + "253": 253, + "254": 254, + "255": 255, + "256": 256, + "257": 257, + "258": 258, + "259": 259, + "260": 260, + "261": 261, + "262": 262, + "263": 263, + "264": 264, + "265": 265, + "266": 266, + "267": 267, + "268": 268, + "269": 269, + "270": 270, + "271": 271, + "272": 272, + "273": 273, + "274": 274, + "275": 275, + "276": 276, + "277": 277, + "278": 278, + "279": 279, + "280": 280, + "281": 281, + "282": 282, + "283": 283, + "284": 284, + "285": 285, + "286": 286, + "287": 287, + "288": 288, + "289": 289, + "290": 290, + "291": 291, + "292": 292, + "293": 293, + "294": 294, + "295": 295, + "296": 296, + "297": 297, + "298": 298, + "299": 299, + "300": 300, + "301": 301, + "302": 302, + "303": 303, + "304": 304, + "305": 305, + "306": 306, + "307": 307, + "308": 308, + "309": 309, + "310": 310, + "311": 311, + "312": 312, + "313": 313, + "314": 314, + "315": 315, + "316": 316, + "317": 317, + "318": 318, + "319": 319, + "320": 320, + "321": 321, + "322": 322, + "323": 323, + "324": 324, + "325": 325, + "328": 328, + "329": 329, + "330": 330, + "331": 331, + "332": 332, + "333": 333, + "334": 334, + "335": 335, + "336": 336, + "337": 337, + "338": 338, + "339": 339, + "340": 340, + "341": 341, + "342": 342, + "344": 344, + "345": 345, + "346": 346, + "347": 347, + "348": 348, + "349": 349, + "350": 350, + "351": 351, + "352": 352, + "353": 353, + "354": 354, + "355": 355, + "356": 356, + "357": 357, + "358": 358, + "359": 359, + "360": 360, + "361": 361, + "362": 362, + "363": 363, + "364": 364, + "365": 365, + "366": 366, + "367": 367, + "368": 368, + "369": 369, + "370": 370, + "371": 371, + "372": 372, + "373": 373, + "374": 374, + "375": 375, + "376": 376, + "377": 377, + "378": 378, + "379": 379, + "380": 380, + "381": 381, + "382": 382, + "383": 383, + "384": 384, + "385": 385, + "386": 386, + "387": 387, + "388": 388, + "389": 389, + "390": 390, + "391": 391, + "392": 392, + "393": 393, + "394": 394, + "395": 395, + "396": 396, + "397": 397, + "398": 398, + "399": 399, + "400": 400, + "401": 401, + "402": 402, + "403": 403, + "404": 404, + "405": 405, + "406": 406, + "407": 407, + "408": 408, + "409": 409, + "410": 410, + "411": 411, + "412": 412, + "413": 413, + "414": 414, + "415": 415, + "416": 416, + "417": 417, + "418": 418, + "419": 419, + "420": 420, + "421": 421, + "422": 422, + "423": 423, + "424": 424, + "425": 425, + "426": 426, + "427": 427, + "428": 428, + "429": 429, + "430": 430, + "431": 431, + "432": 432, + "433": 433, + "434": 434, + "437": 437, + "438": 438, + "441": 441, + "442": 442, + "443": 443, + "444": 444, + "445": 445, + "446": 446, + "447": 447, + "448": 448, + "449": 449, + "450": 450, + "451": 451, + "452": 452, + "453": 453, + "455": 455, + "457": 457, + "458": 458, + "459": 459, + "460": 460, + "461": 461, + "462": 462, + "463": 463, + "464": 464, + "465": 465, + "466": 466, + "467": 467, + "468": 468, + "469": 469, + "470": 470, + "471": 471, + "472": 472, + "473": 473, + "474": 474, + "475": 475, + "476": 476, + "477": 477, + "499": 499, + "500": 500, + "501": 501, + "502": 502, + "503": 503, + "504": 504, + "505": 505, + "506": 506, + "507": 507, + "508": 508, + "509": 509, + "510": 510, + "511": 511, + "513": 513, "acacia_button": -140, "acacia_door": 430, "acacia_door_block": 196, @@ -913,27 +913,16 @@ "egg": 344, "element_0": 36, "element_1": -12, + "element_2": -13, + "element_3": -14, + "element_4": -15, + "element_5": -16, + "element_6": -17, + "element_7": -18, + "element_8": -19, + "element_9": -20, "element_10": -21, - "element_100": -111, - "element_101": -112, - "element_102": -113, - "element_103": -114, - "element_104": -115, - "element_105": -116, - "element_106": -117, - "element_107": -118, - "element_108": -119, - "element_109": -120, "element_11": -22, - "element_110": -121, - "element_111": -122, - "element_112": -123, - "element_113": -124, - "element_114": -125, - "element_115": -126, - "element_116": -127, - "element_117": -128, - "element_118": -129, "element_12": -23, "element_13": -24, "element_14": -25, @@ -942,7 +931,6 @@ "element_17": -28, "element_18": -29, "element_19": -30, - "element_2": -13, "element_20": -31, "element_21": -32, "element_22": -33, @@ -953,7 +941,6 @@ "element_27": -38, "element_28": -39, "element_29": -40, - "element_3": -14, "element_30": -41, "element_31": -42, "element_32": -43, @@ -964,7 +951,6 @@ "element_37": -48, "element_38": -49, "element_39": -50, - "element_4": -15, "element_40": -51, "element_41": -52, "element_42": -53, @@ -975,7 +961,6 @@ "element_47": -58, "element_48": -59, "element_49": -60, - "element_5": -16, "element_50": -61, "element_51": -62, "element_52": -63, @@ -986,7 +971,6 @@ "element_57": -68, "element_58": -69, "element_59": -70, - "element_6": -17, "element_60": -71, "element_61": -72, "element_62": -73, @@ -997,7 +981,6 @@ "element_67": -78, "element_68": -79, "element_69": -80, - "element_7": -18, "element_70": -81, "element_71": -82, "element_72": -83, @@ -1008,7 +991,6 @@ "element_77": -88, "element_78": -89, "element_79": -90, - "element_8": -19, "element_80": -91, "element_81": -92, "element_82": -93, @@ -1019,7 +1001,6 @@ "element_87": -98, "element_88": -99, "element_89": -100, - "element_9": -20, "element_90": -101, "element_91": -102, "element_92": -103, @@ -1030,6 +1011,25 @@ "element_97": -108, "element_98": -109, "element_99": -110, + "element_100": -111, + "element_101": -112, + "element_102": -113, + "element_103": -114, + "element_104": -115, + "element_105": -116, + "element_106": -117, + "element_107": -118, + "element_108": -119, + "element_109": -120, + "element_110": -121, + "element_111": -122, + "element_112": -123, + "element_113": -124, + "element_114": -125, + "element_115": -126, + "element_116": -127, + "element_117": -128, + "element_118": -129, "elytra": 444, "emerald": 388, "emerald_block": 133, @@ -1219,8 +1219,8 @@ "leather_pants": 300, "leather_tunic": 299, "leave": 18, - "leaves": 18, "leave2": 161, + "leaves": 18, "leaves2": 161, "lectern": -194, "lever": 69, From 0ac9f4fe61227df626ca00e8898436235ada171f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 Oct 2021 22:26:51 +0100 Subject: [PATCH 2976/3224] BlockFactory: move SweetBerryBush to its proper place --- src/block/BlockFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 6390812a19..70077b71a0 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -403,6 +403,7 @@ class BlockFactory{ $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_STONE), "Stone", $stoneSlabBreakInfo)); $this->register(new Opaque(new BID(Ids::STONECUTTER, 0), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); $this->register(new Sugarcane(new BID(Ids::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane", BlockBreakInfo::instant())); + $this->register(new SweetBerryBush(new BID(Ids::SWEET_BERRY_BUSH, 0, ItemIds::SWEET_BERRIES), "Sweet Berry Bush", BlockBreakInfo::instant())); $this->register(new TNT(new BID(Ids::TNT, 0), "TNT", BlockBreakInfo::instant())); $fern = new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_FERN), "Fern", BlockBreakInfo::instant(BlockToolType::SHEARS, 1)); @@ -584,7 +585,6 @@ class BlockFactory{ //TODO: minecraft:sticky_piston //TODO: minecraft:stonecutter_block //TODO: minecraft:structure_block - $this->register(new SweetBerryBush(new BID(Ids::SWEET_BERRY_BUSH, 0, ItemIds::SWEET_BERRIES), "Sweet Berry Bush", BlockBreakInfo::instant())); //TODO: minecraft:turtle_egg //endregion From 321345fcc817d59475faead6ea2323b4f00e38de Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 Oct 2021 23:00:38 +0100 Subject: [PATCH 2977/3224] Sapling: simplify condition --- src/block/Sapling.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/block/Sapling.php b/src/block/Sapling.php index 169cb9a327..d2ae0b5a7a 100644 --- a/src/block/Sapling.php +++ b/src/block/Sapling.php @@ -118,11 +118,9 @@ class Sapling extends Flowable{ $ev = new StructureGrowEvent($this, $transaction, $player); $ev->call(); - if($ev->isCancelled()){ - return; + if(!$ev->isCancelled()){ + $transaction->apply(); } - - $transaction->apply(); } public function getFuelTime() : int{ From 34b13925983a92f9749c3fa1dda0237069574220 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 14 Oct 2021 15:03:11 +0100 Subject: [PATCH 2978/3224] Cross-platform signal handler --- src/Server.php | 13 +++++- src/utils/SignalHandler.php | 79 +++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 src/utils/SignalHandler.php diff --git a/src/Server.php b/src/Server.php index abc24f8daa..0a4aebf09f 100644 --- a/src/Server.php +++ b/src/Server.php @@ -98,6 +98,7 @@ use pocketmine\utils\NotCloneable; use pocketmine\utils\NotSerializable; use pocketmine\utils\Process; use pocketmine\utils\Promise; +use pocketmine\utils\SignalHandler; use pocketmine\utils\Terminal; use pocketmine\utils\TextFormat; use pocketmine\utils\Utils; @@ -250,6 +251,8 @@ class Server{ /** @var Player[] */ private array $playerList = []; + private SignalHandler $signalHandler; + /** * @var CommandSender[][] * @phpstan-var array> @@ -743,6 +746,11 @@ class Server{ $this->autoloader = $autoloader; $this->logger = $logger; + $this->signalHandler = new SignalHandler(function() : void{ + $this->logger->info("Received signal interrupt, stopping the server"); + $this->shutdown(); + }); + try{ foreach([ $dataPath, @@ -1326,7 +1334,10 @@ class Server{ * Shuts the server down correctly */ public function shutdown() : void{ - $this->isRunning = false; + if($this->isRunning){ + $this->isRunning = false; + $this->signalHandler->unregister(); + } } public function forceShutdown() : void{ diff --git a/src/utils/SignalHandler.php b/src/utils/SignalHandler.php new file mode 100644 index 0000000000..3f6d7b256e --- /dev/null +++ b/src/utils/SignalHandler.php @@ -0,0 +1,79 @@ +interruptCallback = $interruptCallback; + + if(function_exists('sapi_windows_set_ctrl_handler')){ + sapi_windows_set_ctrl_handler($this->interruptCallback = function(int $signo) use ($interruptCallback) : void{ + if($signo === PHP_WINDOWS_EVENT_CTRL_C || $signo === PHP_WINDOWS_EVENT_CTRL_BREAK){ + $interruptCallback(); + } + }); + }elseif(function_exists('pcntl_signal')){ + foreach([ + SIGTERM, + SIGINT, + SIGHUP + ] as $signal){ + pcntl_signal($signal, $this->interruptCallback = fn(int $signo) => $interruptCallback()); + } + pcntl_async_signals(true); + }else{ + //no supported signal handlers :( + } + } + + public function unregister() : void{ + if(function_exists('sapi_windows_set_ctrl_handler')){ + sapi_windows_set_ctrl_handler($this->interruptCallback, false); + }elseif(function_exists('pcntl_signal')){ + foreach([ + SIGTERM, + SIGINT, + SIGHUP + ] as $signal){ + pcntl_signal($signal, SIG_DFL); + } + } + } +} From 7a4af7a0bcb9b6904df5a7f1e53fd840eb0b7347 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 14 Oct 2021 15:14:27 +0100 Subject: [PATCH 2979/3224] SignalHandler: fix CS AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --- src/utils/SignalHandler.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils/SignalHandler.php b/src/utils/SignalHandler.php index 3f6d7b256e..de81a2b670 100644 --- a/src/utils/SignalHandler.php +++ b/src/utils/SignalHandler.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\utils; use function function_exists; +use function pcntl_async_signals; use function pcntl_signal; use function sapi_windows_set_ctrl_handler; use const PHP_WINDOWS_EVENT_CTRL_BREAK; From bdbfa705582b91ed800563bb53c86ebbe4484345 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 14 Oct 2021 15:44:18 +0100 Subject: [PATCH 2980/3224] Server: break some isolated stuff out of Server::__construct() --- src/Server.php | 227 ++++++++++++++++++++++++++----------------------- 1 file changed, 121 insertions(+), 106 deletions(-) diff --git a/src/Server.php b/src/Server.php index 0a4aebf09f..b1b3579073 100644 --- a/src/Server.php +++ b/src/Server.php @@ -973,115 +973,13 @@ class Server{ $this->pluginManager->loadPlugins($this->pluginPath); $this->enablePlugins(PluginEnableOrder::STARTUP()); - $getGenerator = function(string $generatorName, string $generatorOptions, string $worldName) : ?string{ - $generatorEntry = GeneratorManager::getInstance()->getGenerator($generatorName); - if($generatorEntry === null){ - $this->logger->error($this->language->translate(KnownTranslationFactory::pocketmine_level_generationError( - $worldName, - KnownTranslationFactory::pocketmine_level_unknownGenerator($generatorName) - ))); - return null; - } - try{ - $generatorEntry->validateGeneratorOptions($generatorOptions); - }catch(InvalidGeneratorOptionsException $e){ - $this->logger->error($this->language->translate(KnownTranslationFactory::pocketmine_level_generationError( - $worldName, - KnownTranslationFactory::pocketmine_level_invalidGeneratorOptions($generatorOptions, $generatorName, $e->getMessage()) - ))); - return null; - } - return $generatorEntry->getGeneratorClass(); - }; - - foreach((array) $this->configGroup->getProperty("worlds", []) as $name => $options){ - if($options === null){ - $options = []; - }elseif(!is_array($options)){ - continue; - } - if(!$this->worldManager->loadWorld($name, true) && !$this->worldManager->isWorldGenerated($name)){ - $creationOptions = WorldCreationOptions::create(); - //TODO: error checking - - $generatorName = $options["generator"] ?? "default"; - $generatorOptions = isset($options["preset"]) && is_string($options["preset"]) ? $options["preset"] : ""; - - $generatorClass = $getGenerator($generatorName, $generatorOptions, $name); - if($generatorClass === null){ - continue; - } - $creationOptions->setGeneratorClass($generatorClass); - $creationOptions->setGeneratorOptions($generatorOptions); - - if(isset($options["difficulty"]) && is_string($options["difficulty"])){ - $creationOptions->setDifficulty(World::getDifficultyFromString($options["difficulty"])); - } - - if(isset($options["seed"])){ - $convertedSeed = Generator::convertSeed((string) ($options["seed"] ?? "")); - if($convertedSeed !== null){ - $creationOptions->setSeed($convertedSeed); - } - } - - $this->worldManager->generateWorld($name, $creationOptions); - } + if(!$this->startupPrepareWorlds()){ + return; } - - if($this->worldManager->getDefaultWorld() === null){ - $default = $this->configGroup->getConfigString("level-name", "world"); - if(trim($default) == ""){ - $this->getLogger()->warning("level-name cannot be null, using default"); - $default = "world"; - $this->configGroup->setConfigString("level-name", "world"); - } - if(!$this->worldManager->loadWorld($default, true) && !$this->worldManager->isWorldGenerated($default)){ - $generatorName = $this->configGroup->getConfigString("level-type"); - $generatorOptions = $this->configGroup->getConfigString("generator-settings"); - $generatorClass = $getGenerator($generatorName, $generatorOptions, $default); - if($generatorClass !== null){ - $creationOptions = WorldCreationOptions::create() - ->setGeneratorClass($generatorClass) - ->setGeneratorOptions($generatorOptions); - $convertedSeed = Generator::convertSeed($this->configGroup->getConfigString("level-seed")); - if($convertedSeed !== null){ - $creationOptions->setSeed($convertedSeed); - } - $this->worldManager->generateWorld($default, $creationOptions); - } - } - - $world = $this->worldManager->getWorldByName($default); - if($world === null){ - $this->getLogger()->emergency($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_defaultError())); - $this->forceShutdown(); - - return; - } - $this->worldManager->setDefaultWorld($world); - } - $this->enablePlugins(PluginEnableOrder::POSTWORLD()); - $useQuery = $this->configGroup->getConfigBool("enable-query", true); - if(!$this->network->registerInterface(new RakLibInterface($this)) && $useQuery){ - //RakLib would normally handle the transport for Query packets - //if it's not registered we need to make sure Query still works - $this->network->registerInterface(new DedicatedQueryNetworkInterface($this->getIp(), $this->getPort(), new \PrefixedLogger($this->logger, "Dedicated Query Interface"))); - } - $this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_networkStart($this->getIp(), (string) $this->getPort()))); - - if($useQuery){ - $this->network->registerRawPacketHandler(new QueryHandler($this)); - } - - foreach($this->getIPBans()->getEntries() as $entry){ - $this->network->blockAddress($entry->getName(), -1); - } - - if($this->configGroup->getPropertyBool("network.upnp-forwarding", false)){ - $this->network->registerInterface(new UPnPNetworkInterface($this->logger, Internet::getInternalIP(), $this->getPort())); + if(!$this->startupPrepareNetworkInterfaces()){ + return; } if($this->configGroup->getPropertyBool("anonymous-statistics.enabled", true)){ @@ -1119,6 +1017,123 @@ class Server{ } } + private function startupPrepareWorlds() : bool{ + $getGenerator = function(string $generatorName, string $generatorOptions, string $worldName) : ?string{ + $generatorEntry = GeneratorManager::getInstance()->getGenerator($generatorName); + if($generatorEntry === null){ + $this->logger->error($this->language->translate(KnownTranslationFactory::pocketmine_level_generationError( + $worldName, + KnownTranslationFactory::pocketmine_level_unknownGenerator($generatorName) + ))); + return null; + } + try{ + $generatorEntry->validateGeneratorOptions($generatorOptions); + }catch(InvalidGeneratorOptionsException $e){ + $this->logger->error($this->language->translate(KnownTranslationFactory::pocketmine_level_generationError( + $worldName, + KnownTranslationFactory::pocketmine_level_invalidGeneratorOptions($generatorOptions, $generatorName, $e->getMessage()) + ))); + return null; + } + return $generatorEntry->getGeneratorClass(); + }; + + foreach((array) $this->configGroup->getProperty("worlds", []) as $name => $options){ + if($options === null){ + $options = []; + }elseif(!is_array($options)){ + continue; + } + if(!$this->worldManager->loadWorld($name, true) && !$this->worldManager->isWorldGenerated($name)){ + $creationOptions = WorldCreationOptions::create(); + //TODO: error checking + + $generatorName = $options["generator"] ?? "default"; + $generatorOptions = isset($options["preset"]) && is_string($options["preset"]) ? $options["preset"] : ""; + + $generatorClass = $getGenerator($generatorName, $generatorOptions, $name); + if($generatorClass === null){ + continue; + } + $creationOptions->setGeneratorClass($generatorClass); + $creationOptions->setGeneratorOptions($generatorOptions); + + if(isset($options["difficulty"]) && is_string($options["difficulty"])){ + $creationOptions->setDifficulty(World::getDifficultyFromString($options["difficulty"])); + } + + if(isset($options["seed"])){ + $convertedSeed = Generator::convertSeed((string) ($options["seed"] ?? "")); + if($convertedSeed !== null){ + $creationOptions->setSeed($convertedSeed); + } + } + + $this->worldManager->generateWorld($name, $creationOptions); + } + } + + if($this->worldManager->getDefaultWorld() === null){ + $default = $this->configGroup->getConfigString("level-name", "world"); + if(trim($default) == ""){ + $this->getLogger()->warning("level-name cannot be null, using default"); + $default = "world"; + $this->configGroup->setConfigString("level-name", "world"); + } + if(!$this->worldManager->loadWorld($default, true) && !$this->worldManager->isWorldGenerated($default)){ + $generatorName = $this->configGroup->getConfigString("level-type"); + $generatorOptions = $this->configGroup->getConfigString("generator-settings"); + $generatorClass = $getGenerator($generatorName, $generatorOptions, $default); + if($generatorClass !== null){ + $creationOptions = WorldCreationOptions::create() + ->setGeneratorClass($generatorClass) + ->setGeneratorOptions($generatorOptions); + $convertedSeed = Generator::convertSeed($this->configGroup->getConfigString("level-seed")); + if($convertedSeed !== null){ + $creationOptions->setSeed($convertedSeed); + } + $this->worldManager->generateWorld($default, $creationOptions); + } + } + + $world = $this->worldManager->getWorldByName($default); + if($world === null){ + $this->getLogger()->emergency($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_level_defaultError())); + $this->forceShutdown(); + + return false; + } + $this->worldManager->setDefaultWorld($world); + } + + return true; + } + + private function startupPrepareNetworkInterfaces() : bool{ + $useQuery = $this->configGroup->getConfigBool("enable-query", true); + if(!$this->network->registerInterface(new RakLibInterface($this)) && $useQuery){ + //RakLib would normally handle the transport for Query packets + //if it's not registered we need to make sure Query still works + $this->network->registerInterface(new DedicatedQueryNetworkInterface($this->getIp(), $this->getPort(), new \PrefixedLogger($this->logger, "Dedicated Query Interface"))); + } + $this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_networkStart($this->getIp(), (string) $this->getPort()))); + + if($useQuery){ + $this->network->registerRawPacketHandler(new QueryHandler($this)); + } + + foreach($this->getIPBans()->getEntries() as $entry){ + $this->network->blockAddress($entry->getName(), -1); + } + + if($this->configGroup->getPropertyBool("network.upnp-forwarding", false)){ + $this->network->registerInterface(new UPnPNetworkInterface($this->logger, Internet::getInternalIP(), $this->getPort())); + } + + return true; + } + /** * Subscribes to a particular message broadcast channel. * The channel ID can be any arbitrary string. From 06e7338ff915f3c95b2b2ef213a7ccb6836b58e0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 14 Oct 2021 15:54:20 +0100 Subject: [PATCH 2981/3224] Move exception printing utilities from MainLogger to Utils where they can be useful to other stuff apart from just the logger --- src/utils/MainLogger.php | 42 +---------------- src/utils/Utils.php | 46 +++++++++++++++++++ .../check-explicit-mixed-baseline.neon | 15 ++++-- 3 files changed, 57 insertions(+), 46 deletions(-) diff --git a/src/utils/MainLogger.php b/src/utils/MainLogger.php index 67ab82a62e..1e5c530440 100644 --- a/src/utils/MainLogger.php +++ b/src/utils/MainLogger.php @@ -24,15 +24,10 @@ declare(strict_types=1); namespace pocketmine\utils; use LogLevel; -use pocketmine\errorhandler\ErrorTypeToStringMap; use pocketmine\thread\Thread; use pocketmine\thread\Worker; -use function get_class; use function implode; -use function is_int; -use function preg_replace; use function sprintf; -use function trim; use const PHP_EOL; use const PTHREADS_INHERIT_NONE; @@ -137,46 +132,11 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ * @return void */ public function logException(\Throwable $e, $trace = null){ - if($trace === null){ - $trace = $e->getTrace(); - } - - $lines = [self::printExceptionMessage($e)]; - $lines[] = "--- Stack trace ---"; - foreach(Utils::printableTrace($trace) as $line){ - $lines[] = " " . $line; - } - for($prev = $e->getPrevious(); $prev !== null; $prev = $prev->getPrevious()){ - $lines[] = "--- Previous ---"; - $lines[] = self::printExceptionMessage($prev); - foreach(Utils::printableTrace($prev->getTrace()) as $line){ - $lines[] = " " . $line; - } - } - $lines[] = "--- End of exception information ---"; - $this->critical(implode("\n", $lines)); + $this->critical(implode("\n", Utils::printableExceptionInfo($e, $trace))); $this->syncFlushBuffer(); } - private static function printExceptionMessage(\Throwable $e) : string{ - $errstr = preg_replace('/\s+/', ' ', trim($e->getMessage())); - - $errno = $e->getCode(); - if(is_int($errno)){ - try{ - $errno = ErrorTypeToStringMap::get($errno); - }catch(\InvalidArgumentException $ex){ - //pass - } - } - - $errfile = Filesystem::cleanPath($e->getFile()); - $errline = $e->getLine(); - - return get_class($e) . ": \"$errstr\" ($errno) in \"$errfile\" at line $errline"; - } - public function log($level, $message){ switch($level){ case LogLevel::EMERGENCY: diff --git a/src/utils/Utils.php b/src/utils/Utils.php index 9e33fc8a72..e8add3c9c0 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -28,6 +28,7 @@ declare(strict_types=1); namespace pocketmine\utils; use DaveRandom\CallbackValidator\CallbackType; +use pocketmine\errorhandler\ErrorTypeToStringMap; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; use function array_combine; @@ -46,6 +47,7 @@ use function file; use function file_exists; use function file_get_contents; use function function_exists; +use function get_class; use function get_current_user; use function get_loaded_extensions; use function getenv; @@ -53,6 +55,7 @@ use function gettype; use function implode; use function is_array; use function is_bool; +use function is_int; use function is_object; use function is_string; use function mb_check_encoding; @@ -384,6 +387,49 @@ final class Utils{ return -1; } + private static function printableExceptionMessage(\Throwable $e) : string{ + $errstr = preg_replace('/\s+/', ' ', trim($e->getMessage())); + + $errno = $e->getCode(); + if(is_int($errno)){ + try{ + $errno = ErrorTypeToStringMap::get($errno); + }catch(\InvalidArgumentException $ex){ + //pass + } + } + + $errfile = Filesystem::cleanPath($e->getFile()); + $errline = $e->getLine(); + + return get_class($e) . ": \"$errstr\" ($errno) in \"$errfile\" at line $errline"; + } + + /** + * @param mixed[] $trace + * @return string[] + */ + public static function printableExceptionInfo(\Throwable $e, $trace = null) : array{ + if($trace === null){ + $trace = $e->getTrace(); + } + + $lines = [self::printableExceptionMessage($e)]; + $lines[] = "--- Stack trace ---"; + foreach(Utils::printableTrace($trace) as $line){ + $lines[] = " " . $line; + } + for($prev = $e->getPrevious(); $prev !== null; $prev = $prev->getPrevious()){ + $lines[] = "--- Previous ---"; + $lines[] = self::printableExceptionMessage($prev); + foreach(Utils::printableTrace($prev->getTrace()) as $line){ + $lines[] = " " . $line; + } + } + $lines[] = "--- End of exception information ---"; + return $lines; + } + /** * @param mixed[][] $trace * @phpstan-param list> $trace diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index a13bb3a1b6..2a0dd54044 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -180,21 +180,26 @@ parameters: count: 1 path: ../../../src/utils/Internet.php - - - message: "#^Part \\$errno \\(mixed\\) of encapsed string cannot be cast to string\\.$#" - count: 1 - path: ../../../src/utils/MainLogger.php - - message: "#^Parameter \\#1 \\$path of static method pocketmine\\\\utils\\\\Filesystem\\:\\:cleanPath\\(\\) expects string, mixed given\\.$#" count: 1 path: ../../../src/utils/Utils.php + - + message: "#^Parameter \\#1 \\$trace of static method pocketmine\\\\utils\\\\Utils\\:\\:printableTrace\\(\\) expects array\\\\>, array given\\.$#" + count: 1 + path: ../../../src/utils/Utils.php + - message: "#^Parameter \\#2 \\$array of function array_map expects array, mixed given\\.$#" count: 1 path: ../../../src/utils/Utils.php + - + message: "#^Part \\$errno \\(mixed\\) of encapsed string cannot be cast to string\\.$#" + count: 1 + path: ../../../src/utils/Utils.php + - message: "#^Parameter \\#1 \\$keys of function array_fill_keys expects array, mixed given\\.$#" count: 1 From 8c07748100d29f8c7f12680d02d0feefadc72a4a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 14 Oct 2021 15:55:08 +0100 Subject: [PATCH 2982/3224] RakLibInterface: print packet exception info as a block using Utils::printableExceptionInfo() --- src/network/mcpe/raklib/RakLibInterface.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 9653a0d4e8..55302b43a8 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -192,10 +192,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ $logger->error("Bad packet (error ID $errorId): " . $e->getMessage()); //intentionally doesn't use logException, we don't want spammy packet error traces to appear in release mode - $logger->debug("Origin: " . Filesystem::cleanPath($e->getFile()) . "(" . $e->getLine() . ")"); - foreach(Utils::printableTrace($e->getTrace()) as $frame){ - $logger->debug($frame); - } + $logger->debug(implode("\n", Utils::printableExceptionInfo($e))); $session->disconnect("Packet processing error (Error ID: $errorId)"); $this->interface->blockAddress($address, 5); } From 03482368608164acd202547854df9efabbc7f678 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 14 Oct 2021 15:56:50 +0100 Subject: [PATCH 2983/3224] fucking CS again --- src/network/mcpe/raklib/RakLibInterface.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 55302b43a8..927cdbd768 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -35,7 +35,6 @@ use pocketmine\network\Network; use pocketmine\network\PacketHandlingException; use pocketmine\Server; use pocketmine\snooze\SleeperNotifier; -use pocketmine\utils\Filesystem; use pocketmine\utils\Utils; use raklib\protocol\EncapsulatedPacket; use raklib\protocol\PacketReliability; From 48f809d3fa8b40e460352f11a9b527b4a123da3e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 15 Oct 2021 17:01:09 +0100 Subject: [PATCH 2984/3224] Removed another dead PHPStan error pattern this was actually a PHPStan bug fixed in 0.12.99. --- tests/phpstan/configs/check-explicit-mixed-baseline.neon | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index 2a0dd54044..5591d54c84 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -160,11 +160,6 @@ parameters: count: 1 path: ../../../src/thread/ThreadManager.php - - - message: "#^Method pocketmine\\\\timings\\\\TimingsHandler\\:\\:time\\(\\) should return TClosureReturn but returns TClosureReturn\\.$#" - count: 1 - path: ../../../src/timings/TimingsHandler.php - - message: "#^Parameter \\#1 \\$config of static method pocketmine\\\\utils\\\\Config\\:\\:writeProperties\\(\\) expects array\\, array\\ given\\.$#" count: 1 From 8db5732b44578a59c785e6e3c1d36c87c90ddeb4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 15 Oct 2021 17:15:46 +0100 Subject: [PATCH 2985/3224] Drop respect/validation it's not worth this turning into compatibility baggage just so that we can parse plugin_list.yml, especially when we have new ways to handle data parsing coming in the pipeline. For something as small as plugin_list.yml, it's easier (and in this case better too) to just validate it manually (respect/validation was anyway too strict considering it's YAML we're dealing with). --- composer.json | 1 - composer.lock | 206 +----------------- src/plugin/PluginGraylist.php | 42 ++-- .../check-explicit-mixed-baseline.neon | 5 - 4 files changed, 25 insertions(+), 229 deletions(-) diff --git a/composer.json b/composer.json index 05f575214c..167149a72f 100644 --- a/composer.json +++ b/composer.json @@ -49,7 +49,6 @@ "pocketmine/snooze": "^0.3.0", "pocketmine/spl": "dev-master", "ramsey/uuid": "^4.1", - "respect/validation": "^2.0", "webmozart/path-util": "^2.3" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 4286906a6b..fe195368cc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c7a00c5a35d43f307fdba7a588029131", + "content-hash": "39ec9b1c108888c32a660f3bc2c400c4", "packages": [ { "name": "adhocore/json-comment", @@ -1011,130 +1011,6 @@ ], "time": "2021-09-25T23:10:38+00:00" }, - { - "name": "respect/stringifier", - "version": "0.2.0", - "source": { - "type": "git", - "url": "https://github.com/Respect/Stringifier.git", - "reference": "e55af3c8aeaeaa2abb5fa47a58a8e9688cc23b59" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Respect/Stringifier/zipball/e55af3c8aeaeaa2abb5fa47a58a8e9688cc23b59", - "reference": "e55af3c8aeaeaa2abb5fa47a58a8e9688cc23b59", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^2.8", - "malukenho/docheader": "^0.1.7", - "phpunit/phpunit": "^6.4" - }, - "type": "library", - "autoload": { - "psr-4": { - "Respect\\Stringifier\\": "src/" - }, - "files": [ - "src/stringify.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Respect/Stringifier Contributors", - "homepage": "https://github.com/Respect/Stringifier/graphs/contributors" - } - ], - "description": "Converts any value to a string", - "homepage": "http://respect.github.io/Stringifier/", - "keywords": [ - "respect", - "stringifier", - "stringify" - ], - "support": { - "issues": "https://github.com/Respect/Stringifier/issues", - "source": "https://github.com/Respect/Stringifier/tree/0.2.0" - }, - "time": "2017-12-29T19:39:25+00:00" - }, - { - "name": "respect/validation", - "version": "2.2.3", - "source": { - "type": "git", - "url": "https://github.com/Respect/Validation.git", - "reference": "4c21a7ffc9a4915673cb2c2843963919e664e627" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Respect/Validation/zipball/4c21a7ffc9a4915673cb2c2843963919e664e627", - "reference": "4c21a7ffc9a4915673cb2c2843963919e664e627", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0", - "respect/stringifier": "^0.2.0", - "symfony/polyfill-mbstring": "^1.2" - }, - "require-dev": { - "egulias/email-validator": "^3.0", - "malukenho/docheader": "^0.1", - "mikey179/vfsstream": "^1.6", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-deprecation-rules": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^9.3", - "psr/http-message": "^1.0", - "respect/coding-standard": "^3.0", - "squizlabs/php_codesniffer": "^3.5", - "symfony/validator": "^3.0||^4.0", - "zendframework/zend-validator": "^2.1" - }, - "suggest": { - "egulias/email-validator": "Strict (RFC compliant) email validation", - "ext-bcmath": "Arbitrary Precision Mathematics", - "ext-fileinfo": "File Information", - "ext-mbstring": "Multibyte String Functions", - "symfony/validator": "Use Symfony validator through Respect\\Validation", - "zendframework/zend-validator": "Use Zend Framework validator through Respect\\Validation" - }, - "type": "library", - "autoload": { - "psr-4": { - "Respect\\Validation\\": "library/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Respect/Validation Contributors", - "homepage": "https://github.com/Respect/Validation/graphs/contributors" - } - ], - "description": "The most awesome validation engine ever created for PHP", - "homepage": "http://respect.github.io/Validation/", - "keywords": [ - "respect", - "validation", - "validator" - ], - "support": { - "issues": "https://github.com/Respect/Validation/issues", - "source": "https://github.com/Respect/Validation/tree/2.2.3" - }, - "time": "2021-03-19T14:12:45+00:00" - }, { "name": "symfony/polyfill-ctype", "version": "v1.23.0", @@ -1214,86 +1090,6 @@ ], "time": "2021-02-19T12:13:01+00:00" }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.23.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6", - "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.1" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-05-27T12:26:48+00:00" - }, { "name": "symfony/polyfill-php80", "version": "v1.23.1", diff --git a/src/plugin/PluginGraylist.php b/src/plugin/PluginGraylist.php index 34aad55f12..cd6287f829 100644 --- a/src/plugin/PluginGraylist.php +++ b/src/plugin/PluginGraylist.php @@ -23,15 +23,11 @@ declare(strict_types=1); namespace pocketmine\plugin; -use Respect\Validation\Exceptions\NestedValidationException; -use Respect\Validation\Rules\AllOf; -use Respect\Validation\Rules\ArrayType; -use Respect\Validation\Rules\Each; -use Respect\Validation\Rules\In; -use Respect\Validation\Rules\Key; -use Respect\Validation\Rules\StringType; -use Respect\Validation\Validator; use function array_flip; +use function is_array; +use function is_float; +use function is_int; +use function is_string; class PluginGraylist{ @@ -70,17 +66,27 @@ class PluginGraylist{ * @param mixed[] $array */ public static function fromArray(array $array) : PluginGraylist{ - $validator = new Validator( - new Key("mode", new In(['whitelist', 'blacklist'], true), true), - new Key("plugins", new AllOf(new ArrayType(), new Each(new StringType())), true) - ); - $validator->setName('plugin_list.yml'); - try{ - $validator->assert($array); - }catch(NestedValidationException $e){ - throw new \InvalidArgumentException($e->getFullMessage(), 0, $e); + if(!isset($array["mode"]) || ($array["mode"] !== "whitelist" && $array["mode"] !== "blacklist")){ + throw new \InvalidArgumentException("\"mode\" must be set"); } - return new PluginGraylist($array["plugins"], $array["mode"] === 'whitelist'); + $isWhitelist = match($array["mode"]){ + "whitelist" => true, + "blacklist" => false, + default => throw new \InvalidArgumentException("\"mode\" must be either \"whitelist\" or \"blacklist\"") + }; + $plugins = []; + if(isset($array["plugins"])){ + if(!is_array($array["plugins"])){ + throw new \InvalidArgumentException("\"plugins\" must be an array"); + } + foreach($array["plugins"] as $k => $v){ + if(!is_string($v) && !is_int($v) && !is_float($v)){ + throw new \InvalidArgumentException("\"plugins\" contains invalid element at position $k"); + } + $plugins[] = (string) $v; + } + } + return new PluginGraylist($plugins, $isWhitelist); } /** diff --git a/tests/phpstan/configs/check-explicit-mixed-baseline.neon b/tests/phpstan/configs/check-explicit-mixed-baseline.neon index 5591d54c84..d8bb79fb20 100644 --- a/tests/phpstan/configs/check-explicit-mixed-baseline.neon +++ b/tests/phpstan/configs/check-explicit-mixed-baseline.neon @@ -135,11 +135,6 @@ parameters: count: 1 path: ../../../src/plugin/PluginDescription.php - - - message: "#^Parameter \\#1 \\$plugins of class pocketmine\\\\plugin\\\\PluginGraylist constructor expects array\\, mixed given\\.$#" - count: 1 - path: ../../../src/plugin/PluginGraylist.php - - message: "#^Parameter \\#2 \\$code of class pocketmine\\\\resourcepacks\\\\ResourcePackException constructor expects int, mixed given\\.$#" count: 1 From a794d24c81af0111a47a039f24b8ce64c88b0ccc Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 17 Oct 2021 17:02:18 +0100 Subject: [PATCH 2986/3224] Added a tool to generate a Markdown document of all core permissions --- tools/generate-permission-doc.php | 100 ++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 tools/generate-permission-doc.php diff --git a/tools/generate-permission-doc.php b/tools/generate-permission-doc.php new file mode 100644 index 0000000000..57fd04626a --- /dev/null +++ b/tools/generate-permission-doc.php @@ -0,0 +1,100 @@ +getPermissions(); +ksort($permissions, SORT_STRING); + +fwrite($doc, "# PocketMine-MP Core Permissions\n"); +fwrite($doc, "Generated from PocketMine-MP " . VersionInfo::VERSION()->getFullVersion() . "\n"); +fwrite($doc, "\n"); +fwrite($doc, "| Name | Description | Implied permissions |\n"); +fwrite($doc, "|:-----|:------------|:-------------------:|\n"); +foreach($permissions as $permission){ + $link = count($permission->getChildren()) === 0 ? "N/A" : "[Jump](#" . markdownify("Permissions implied by `" . $permission->getName() . "`") . ")"; + fwrite($doc, "| `" . $permission->getName() . "` | " . $permission->getDescription() . " | $link |\n"); +} + +fwrite($doc, "\n\n"); +fwrite($doc, "## Implied permissions\n"); +fwrite($doc, "Some permissions automatically grant (or deny) other permissions by default when granted. These are referred to as **implied permissions**.
\n"); +fwrite($doc, "Permissions may imply permissions which in turn imply other permissions (e.g. `pocketmine.group.operator` implies `pocketmine.group.user`, which in turn implies `pocketmine.command.help`).
\n"); +fwrite($doc, "Implied permissions can be overridden by explicit permissions from elsewhere.
\n"); +fwrite($doc, "**Note:** When explicitly denied, implied permissions are inverted. This means that \"granted\" becomes \"denied\" and vice versa.\n"); +fwrite($doc, "\n\n"); +foreach($permissions as $permission){ + if(count($permission->getChildren()) === 0){ + continue; + } + fwrite($doc, "### Permissions implied by `" . $permission->getName() . "`\n"); + fwrite($doc, "Users granted this permission will also be granted/denied the following permissions implicitly:\n\n"); + + fwrite($doc, "| Name | Type |\n"); + fwrite($doc, "|:-----|:----:|\n"); + $children = $permission->getChildren(); + ksort($children, SORT_STRING); + foreach($children as $childName => $isGranted){ + fwrite($doc, "| `$childName` | " . ($isGranted ? "Granted" : "Denied") . " |\n"); + } + fwrite($doc, "\n"); +} + +fclose($doc); +echo "Done.\n"; From c70b80c2730233b0551c11e6bafb996b708302d0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 17 Oct 2021 22:37:49 +0100 Subject: [PATCH 2987/3224] ItemEntity: implement partial itemstack pickups in the dumbest way possible Given the various limitations and flexibilities posed by EntityItemPickupEvent, I settled on this as the simplest way to deal with the problem. - EntityItemPickupEvent may have its destination inventory changed, so we can't cache the result of getAddableItemQuantity() to use after the event. - The item itself may have changed, so even if we thought we could add some items before the change, we might not be able to afterwards. Considering the above facts, it's better to just give the whole itemstack to EntityItemPickupEvent, and let plugins use getAddableItemQuantity() on their own to decide if their chosen inventory can accommodate the item or not. If it can't, then we'll just drop it on the ground. This also fixes a potential issue where plugins changing the item to a custom one might end up with their items and the actual items both just vanishing if the target inventory was full. closes #4499 --- src/entity/object/ItemEntity.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index 7de765e65c..2b16b7a117 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -227,8 +227,8 @@ class ItemEntity extends Entity{ $item = $this->getItem(); $playerInventory = match(true){ - $player->getOffHandInventory()->getItem(0)->canStackWith($item) and $player->getOffHandInventory()->canAddItem($item) => $player->getOffHandInventory(), - $player->getInventory()->canAddItem($item) => $player->getInventory(), + $player->getOffHandInventory()->getItem(0)->canStackWith($item) and $player->getOffHandInventory()->getAddableItemQuantity($item) > 0 => $player->getOffHandInventory(), + $player->getInventory()->getAddableItemQuantity($item) > 0 => $player->getInventory(), default => null }; @@ -246,7 +246,12 @@ class ItemEntity extends Entity{ $viewer->getNetworkSession()->onPlayerPickUpItem($player, $this); } - $ev->getInventory()?->addItem($ev->getItem()); + $inventory = $ev->getInventory(); + if($inventory !== null){ + foreach($inventory->addItem($ev->getItem()) as $remains){ + $this->getWorld()->dropItem($this->location, $remains, new Vector3(0, 0, 0)); + } + } $this->flagForDespawn(); } } From fee6478cbeed78e9c5aa010c39d6d3e48744885d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 19 Oct 2021 19:00:29 +0100 Subject: [PATCH 2988/3224] Updated BedrockData and BedrockProtocol for 1.17.40 support --- composer.json | 2 +- composer.lock | 16 ++++++++-------- resources/vanilla | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/composer.json b/composer.json index 167149a72f..da7c87f62b 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "adhocore/json-comment": "^1.1", "fgrosse/phpasn1": "^2.3", "netresearch/jsonmapper": "^4.0", - "pocketmine/bedrock-protocol": "2.0.0+bedrock1.17.30", + "pocketmine/bedrock-protocol": "3.0.0+bedrock1.17.40", "pocketmine/binaryutils": "^0.2.1", "pocketmine/callback-validator": "^1.0.2", "pocketmine/classloader": "dev-master", diff --git a/composer.lock b/composer.lock index fe195368cc..3aa90d53bf 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "39ec9b1c108888c32a660f3bc2c400c4", + "content-hash": "ddffa959e1045fc084bb9142884f27a3", "packages": [ { "name": "adhocore/json-comment", @@ -249,22 +249,22 @@ }, { "name": "pocketmine/bedrock-protocol", - "version": "2.0.0+bedrock1.17.30", + "version": "3.0.0+bedrock1.17.40", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "faff7da904e68f69b1a9128956dac3122e87308a" + "reference": "ea9e22563b3d56f3b94b4a132c725912d029c101" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/faff7da904e68f69b1a9128956dac3122e87308a", - "reference": "faff7da904e68f69b1a9128956dac3122e87308a", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/ea9e22563b3d56f3b94b4a132c725912d029c101", + "reference": "ea9e22563b3d56f3b94b4a132c725912d029c101", "shasum": "" }, "require": { "ext-json": "*", "netresearch/jsonmapper": "^4.0", - "php": "^7.4 || ^8.0", + "php": "^8.0", "pocketmine/binaryutils": "^0.2.0", "pocketmine/color": "^0.2.0", "pocketmine/math": "^0.3.0", @@ -290,9 +290,9 @@ "description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP", "support": { "issues": "https://github.com/pmmp/BedrockProtocol/issues", - "source": "https://github.com/pmmp/BedrockProtocol/tree/bedrock-1.17.30" + "source": "https://github.com/pmmp/BedrockProtocol/tree/bedrock-1.17.40" }, - "time": "2021-09-21T23:25:51+00:00" + "time": "2021-10-19T17:28:41+00:00" }, { "name": "pocketmine/binaryutils", diff --git a/resources/vanilla b/resources/vanilla index 19569dd729..f29b7be8fa 160000 --- a/resources/vanilla +++ b/resources/vanilla @@ -1 +1 @@ -Subproject commit 19569dd729970e161a24b574b41c06a5e064ab81 +Subproject commit f29b7be8fa3046d2ee4c6421485b97b3f5b07774 From 46920818b5de1632991c29620b4822fd87f7946b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 19 Oct 2021 19:13:43 +0100 Subject: [PATCH 2989/3224] Release 4.0.0-BETA6 --- changelogs/4.0.md | 17 +++++++++++++++++ src/VersionInfo.php | 4 ++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index 70add2c997..708822771d 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1443,3 +1443,20 @@ Released 12th October 2021. ### World - The following API methods have signature changes: - `GeneratorManager->registerGenerator()` now requires a `\Closure $presetValidator` parameter. This is used to check generator options of worlds and configs before attempting to use them. + +# 4.0.0-BETA6 +Released 19th October 2021. + +## General +- Added support for Minecraft: Bedrock Edition 1.17.40. +- Removed support for earlier versions. +- CTRL+C signal handling has been restored, and is now supported on Windows. Pressing CTRL+C while the server is running will behave as if the `/stop` command was invoked. +- Added a script `tools/generate-permission-doc.php` to generate a Markdown file with a list of all permissions and their relationships. In the future, this will be used to maintain the official documentation, but plugin developers might find it useful for their own purposes too. +- [`respect/validation`](https://packagist.org/packages/respect/validation) is no longer a core dependency. + +## Fixes +- Fixed server crash when using `/give` to give an item with a too-large item ID, or `/clear` to clear an item that does not exist. + - Now, `LegacyStringToItemParser` is used exclusively, and numeric IDs are no longer parsed. + +## Gameplay +- Picking up some items from a dropped stack of items is now supported. This fixes various bugs with being unable to pick up items with an almost-full inventory. diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 9bae4e775b..c313f11938 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -30,9 +30,9 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; public const BASE_VERSION = "4.0.0-BETA6"; - public const IS_DEVELOPMENT_BUILD = true; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_NUMBER = 0; - public const BUILD_CHANNEL = ""; + public const BUILD_CHANNEL = "beta"; private function __construct(){ //NOOP From a3f8546ac442d6bbb44dfedc19eb6d3e639a50b6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 19 Oct 2021 19:13:43 +0100 Subject: [PATCH 2990/3224] 4.0.0-BETA7 is next --- src/VersionInfo.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index c313f11938..701598a17c 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -29,10 +29,10 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "4.0.0-BETA6"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "4.0.0-BETA7"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_NUMBER = 0; - public const BUILD_CHANNEL = "beta"; + public const BUILD_CHANNEL = ""; private function __construct(){ //NOOP From 80b402e529fe3d47735aeb75676d5313ae453a20 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Oct 2021 14:01:39 +0100 Subject: [PATCH 2991/3224] ItemTranslator: throw the proper exceptions when failing to map network IDs --- src/network/mcpe/convert/ItemTranslator.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/network/mcpe/convert/ItemTranslator.php b/src/network/mcpe/convert/ItemTranslator.php index 0302a6898f..c7cba0226a 100644 --- a/src/network/mcpe/convert/ItemTranslator.php +++ b/src/network/mcpe/convert/ItemTranslator.php @@ -175,11 +175,12 @@ final class ItemTranslator{ /** * @return int[] * @phpstan-return array{int, int} + * @throws TypeConversionException */ public function fromNetworkId(int $networkId, int $networkMeta, ?bool &$isComplexMapping = null) : array{ if(isset($this->complexNetToCoreMapping[$networkId])){ if($networkMeta !== 0){ - throw new \UnexpectedValueException("Unexpected non-zero network meta on complex item mapping"); + throw new TypeConversionException("Unexpected non-zero network meta on complex item mapping"); } $isComplexMapping = true; return $this->complexNetToCoreMapping[$networkId]; @@ -188,12 +189,13 @@ final class ItemTranslator{ if(isset($this->simpleNetToCoreMapping[$networkId])){ return [$this->simpleNetToCoreMapping[$networkId], $networkMeta]; } - throw new \UnexpectedValueException("Unmapped network ID/metadata combination $networkId:$networkMeta"); + throw new TypeConversionException("Unmapped network ID/metadata combination $networkId:$networkMeta"); } /** * @return int[] * @phpstan-return array{int, int} + * @throws TypeConversionException */ public function fromNetworkIdWithWildcardHandling(int $networkId, int $networkMeta) : array{ $isComplexMapping = false; From 09c840b66a6c6d35be4a2dcd1eec3c6d105132ae Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Oct 2021 16:19:20 +0100 Subject: [PATCH 2992/3224] Update transient composer dependencies --- composer.lock | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/composer.lock b/composer.lock index 3aa90d53bf..95ceaa103a 100644 --- a/composer.lock +++ b/composer.lock @@ -1711,16 +1711,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.2.2", + "version": "5.3.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", - "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", "shasum": "" }, "require": { @@ -1731,7 +1731,8 @@ "webmozart/assert": "^1.9.1" }, "require-dev": { - "mockery/mockery": "~1.3.2" + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" }, "type": "library", "extra": { @@ -1761,9 +1762,9 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" }, - "time": "2020-09-03T19:13:55+00:00" + "time": "2021-10-19T17:43:47+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -3324,6 +3325,7 @@ "type": "github" } ], + "abandoned": true, "time": "2020-09-28T06:45:17+00:00" }, { From ec3986827c87f244e55ff7497d0c86a5b4f92f49 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Oct 2021 16:20:10 +0100 Subject: [PATCH 2993/3224] Update BedrockProtocol to 3.0.1, widen constraint to allow newer patch versions --- composer.json | 2 +- composer.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index da7c87f62b..4a01020a7c 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "adhocore/json-comment": "^1.1", "fgrosse/phpasn1": "^2.3", "netresearch/jsonmapper": "^4.0", - "pocketmine/bedrock-protocol": "3.0.0+bedrock1.17.40", + "pocketmine/bedrock-protocol": "^3.0.1+bedrock1.17.40", "pocketmine/binaryutils": "^0.2.1", "pocketmine/callback-validator": "^1.0.2", "pocketmine/classloader": "dev-master", diff --git a/composer.lock b/composer.lock index 95ceaa103a..cb1287b83d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ddffa959e1045fc084bb9142884f27a3", + "content-hash": "bc2b425a6f436a01de4e423ea651dc84", "packages": [ { "name": "adhocore/json-comment", @@ -249,16 +249,16 @@ }, { "name": "pocketmine/bedrock-protocol", - "version": "3.0.0+bedrock1.17.40", + "version": "3.0.1+bedrock1.17.40", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "ea9e22563b3d56f3b94b4a132c725912d029c101" + "reference": "1add11e06366b983b97fa415fee55f31af3cb7a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/ea9e22563b3d56f3b94b4a132c725912d029c101", - "reference": "ea9e22563b3d56f3b94b4a132c725912d029c101", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/1add11e06366b983b97fa415fee55f31af3cb7a9", + "reference": "1add11e06366b983b97fa415fee55f31af3cb7a9", "shasum": "" }, "require": { @@ -290,9 +290,9 @@ "description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP", "support": { "issues": "https://github.com/pmmp/BedrockProtocol/issues", - "source": "https://github.com/pmmp/BedrockProtocol/tree/bedrock-1.17.40" + "source": "https://github.com/pmmp/BedrockProtocol/tree/3.0.1+bedrock1.17.40" }, - "time": "2021-10-19T17:28:41+00:00" + "time": "2021-10-20T14:00:00+00:00" }, { "name": "pocketmine/binaryutils", From a7889545517a85e38574651d5ca0cdbb74268c91 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Wed, 20 Oct 2021 20:22:00 +0100 Subject: [PATCH 2994/3224] Fixed dependency handling across plugin loaders (#3971) --- src/plugin/PluginLoadTriage.php | 42 ++++++++ src/plugin/PluginManager.php | 165 +++++++++++++++++++++----------- tests/plugins/DevTools | 2 +- 3 files changed, 150 insertions(+), 59 deletions(-) create mode 100644 src/plugin/PluginLoadTriage.php diff --git a/src/plugin/PluginLoadTriage.php b/src/plugin/PluginLoadTriage.php new file mode 100644 index 0000000000..c9c4fff773 --- /dev/null +++ b/src/plugin/PluginLoadTriage.php @@ -0,0 +1,42 @@ + + */ + public $plugins = []; + /** + * @var string[][] + * @phpstan-var array> + */ + public $dependencies = []; + /** + * @var string[][] + * @phpstan-var array> + */ + public $softDependencies = []; +} diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 3fceaa7105..ae73c009fa 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -44,7 +44,10 @@ use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Utils; use pocketmine\utils\VersionString; use Webmozart\PathUtil\Path; +use function array_diff_assoc; use function array_intersect; +use function array_key_exists; +use function array_keys; use function array_merge; use function class_exists; use function count; @@ -265,18 +268,12 @@ class PluginManager{ /** * @param string[]|null $newLoaders * @phpstan-param list> $newLoaders - * - * @return Plugin[] */ - public function loadPlugins(string $directory, ?array $newLoaders = null) : array{ + private function triagePlugins(string $directory, PluginLoadTriage $triage, ?array $newLoaders = null) : void{ if(!is_dir($directory)){ - return []; + return; } - $plugins = []; - $loadedPlugins = []; - $dependencies = []; - $softDependencies = []; if(is_array($newLoaders)){ $loaders = []; foreach($newLoaders as $key){ @@ -320,7 +317,7 @@ class PluginManager{ continue; } - if(isset($plugins[$name]) or $this->getPlugin($name) instanceof Plugin){ + if(isset($triage->plugins[$name]) or $this->getPlugin($name) instanceof Plugin){ $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_duplicateError($name))); continue; } @@ -336,77 +333,129 @@ class PluginManager{ ))); continue; } - $plugins[$name] = new PluginLoadTriageEntry($file, $loader, $description); - $softDependencies[$name] = array_merge($softDependencies[$name] ?? [], $description->getSoftDepend()); - $dependencies[$name] = $description->getDepend(); + $triage->plugins[$name] = new PluginLoadTriageEntry($file, $loader, $description); + + $triage->softDependencies[$name] = array_merge($triage->softDependencies[$name] ?? [], $description->getSoftDepend()); + $triage->dependencies[$name] = $description->getDepend(); foreach($description->getLoadBefore() as $before){ - if(isset($softDependencies[$before])){ - $softDependencies[$before][] = $name; + if(isset($triage->softDependencies[$before])){ + $triage->softDependencies[$before][] = $name; }else{ - $softDependencies[$before] = [$name]; + $triage->softDependencies[$before] = [$name]; } } } } + } - while(count($plugins) > 0){ + /** + * @param string[][] $dependencyLists + * @param Plugin[] $loadedPlugins + */ + private function checkDepsForTriage(string $pluginName, string $dependencyType, array &$dependencyLists, array $loadedPlugins, PluginLoadTriage $triage) : void{ + if(isset($dependencyLists[$pluginName])){ + foreach($dependencyLists[$pluginName] as $key => $dependency){ + if(isset($loadedPlugins[$dependency]) or $this->getPlugin($dependency) instanceof Plugin){ + $this->server->getLogger()->debug("Successfully resolved $dependencyType dependency \"$dependency\" for plugin \"$pluginName\""); + unset($dependencyLists[$pluginName][$key]); + }elseif(array_key_exists($dependency, $triage->plugins)){ + $this->server->getLogger()->debug("Deferring resolution of $dependencyType dependency \"$dependency\" for plugin \"$pluginName\" (found but not loaded yet)"); + } + } + + if(count($dependencyLists[$pluginName]) === 0){ + unset($dependencyLists[$pluginName]); + } + } + } + + /** + * @return Plugin[] + */ + public function loadPlugins(string $directory) : array{ + $triage = new PluginLoadTriage(); + $this->triagePlugins($directory, $triage); + + $loadedPlugins = []; + + while(count($triage->plugins) > 0){ $loadedThisLoop = 0; - foreach($plugins as $name => $entry){ - if(isset($dependencies[$name])){ - foreach($dependencies[$name] as $key => $dependency){ - if(isset($loadedPlugins[$dependency]) or $this->getPlugin($dependency) instanceof Plugin){ - unset($dependencies[$name][$key]); - }elseif(!isset($plugins[$dependency])){ - $this->server->getLogger()->critical($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( - $name, - KnownTranslationFactory::pocketmine_plugin_unknownDependency($dependency) - ))); - unset($plugins[$name]); - continue 2; - } - } + foreach($triage->plugins as $name => $entry){ + $this->checkDepsForTriage($name, "hard", $triage->dependencies, $loadedPlugins, $triage); + $this->checkDepsForTriage($name, "soft", $triage->softDependencies, $loadedPlugins, $triage); - if(count($dependencies[$name]) === 0){ - unset($dependencies[$name]); - } - } - - if(isset($softDependencies[$name])){ - foreach($softDependencies[$name] as $key => $dependency){ - if(isset($loadedPlugins[$dependency]) or $this->getPlugin($dependency) instanceof Plugin){ - $this->server->getLogger()->debug("Successfully resolved soft dependency \"$dependency\" for plugin \"$name\""); - unset($softDependencies[$name][$key]); - }elseif(!isset($plugins[$dependency])){ - //this dependency is never going to be resolved, so don't bother trying - $this->server->getLogger()->debug("Skipping resolution of missing soft dependency \"$dependency\" for plugin \"$name\""); - unset($softDependencies[$name][$key]); - }else{ - $this->server->getLogger()->debug("Deferring resolution of soft dependency \"$dependency\" for plugin \"$name\" (found but not loaded yet)"); - } - } - - if(count($softDependencies[$name]) === 0){ - unset($softDependencies[$name]); - } - } - - if(!isset($dependencies[$name]) and !isset($softDependencies[$name])){ - unset($plugins[$name]); + if(!isset($triage->dependencies[$name]) and !isset($triage->softDependencies[$name])){ + unset($triage->plugins[$name]); $loadedThisLoop++; + + $oldRegisteredLoaders = $this->fileAssociations; if(($plugin = $this->internalLoadPlugin($entry->getFile(), $entry->getLoader(), $entry->getDescription())) instanceof Plugin){ $loadedPlugins[$name] = $plugin; + $diffLoaders = []; + foreach($this->fileAssociations as $k => $loader){ + if(!array_key_exists($k, $oldRegisteredLoaders)){ + $diffLoaders[] = $k; + } + } + if(count($diffLoaders) !== 0){ + $this->server->getLogger()->debug("Plugin $name registered a new plugin loader during load, scanning for new plugins"); + $plugins = $triage->plugins; + $this->triagePlugins($directory, $triage, $diffLoaders); + $diffPlugins = array_diff_assoc($triage->plugins, $plugins); + $this->server->getLogger()->debug("Re-triage found plugins: " . implode(", ", array_keys($diffPlugins))); + } } } } if($loadedThisLoop === 0){ //No plugins loaded :( - foreach($plugins as $name => $file){ + + //check for skippable soft dependencies first, in case the dependents could resolve hard dependencies + foreach($triage->plugins as $name => $file){ + if(isset($triage->softDependencies[$name]) && !isset($triage->dependencies[$name])){ + foreach($triage->softDependencies[$name] as $k => $dependency){ + if($this->getPlugin($dependency) === null && !array_key_exists($dependency, $triage->plugins)){ + $this->server->getLogger()->debug("Skipping resolution of missing soft dependency \"$dependency\" for plugin \"$name\""); + unset($triage->softDependencies[$name][$k]); + } + } + if(count($triage->softDependencies[$name]) === 0){ + unset($triage->softDependencies[$name]); + continue 2; //go back to the top and try again + } + } + } + + foreach($triage->plugins as $name => $file){ + if(isset($triage->dependencies[$name])){ + $unknownDependencies = []; + + foreach($triage->dependencies[$name] as $k => $dependency){ + if($this->getPlugin($dependency) === null && !array_key_exists($dependency, $triage->plugins)){ + //assume that the plugin is never going to be loaded + //by this point all soft dependencies have been ignored if they were able to be, so + //there's no chance of this dependency ever being resolved + $unknownDependencies[$dependency] = $dependency; + } + } + + if(count($unknownDependencies) > 0){ + $this->server->getLogger()->critical($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError( + $name, + KnownTranslationFactory::pocketmine_plugin_unknownDependency(implode(", ", $unknownDependencies)) + ))); + unset($triage->plugins[$name]); + } + } + } + + foreach($triage->plugins as $name => $file){ $this->server->getLogger()->critical($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError($name, KnownTranslationFactory::pocketmine_plugin_circularDependency()))); } - $plugins = []; + break; } } diff --git a/tests/plugins/DevTools b/tests/plugins/DevTools index dfbea943e1..db184c2563 160000 --- a/tests/plugins/DevTools +++ b/tests/plugins/DevTools @@ -1 +1 @@ -Subproject commit dfbea943e1c64094358acac56013b89065884657 +Subproject commit db184c25636b1f984c6539fd4b1729b0b64b35d6 From 9646128d0176240c818dcefa57d39fb46af0de07 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Oct 2021 21:22:56 +0100 Subject: [PATCH 2995/3224] Updated resources/locale submodule to pmmp/Language@09c709f2426cb8d21d2a4851ad6df5a254a40fd4 --- resources/locale | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/locale b/resources/locale index 17fc6a1050..09c709f242 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 17fc6a10501c2cd48ec08f81ab41a640864f8d1d +Subproject commit 09c709f2426cb8d21d2a4851ad6df5a254a40fd4 From 03fcd844ebb8d563a54759ca6890ae694afd0e8a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Oct 2021 21:36:14 +0100 Subject: [PATCH 2996/3224] PluginManager::loadPlugins() now accepts files as well as directories loadPlugins() is now a superior option to loadPlugin(), since it enforces dependency checks and also supports automatic loading of plugins when new loaders are installed. --- src/plugin/PluginManager.php | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index ae73c009fa..d39ee83356 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -269,11 +269,7 @@ class PluginManager{ * @param string[]|null $newLoaders * @phpstan-param list> $newLoaders */ - private function triagePlugins(string $directory, PluginLoadTriage $triage, ?array $newLoaders = null) : void{ - if(!is_dir($directory)){ - return; - } - + private function triagePlugins(string $path, PluginLoadTriage $triage, ?array $newLoaders = null) : void{ if(is_array($newLoaders)){ $loaders = []; foreach($newLoaders as $key){ @@ -285,8 +281,16 @@ class PluginManager{ $loaders = $this->fileAssociations; } - $files = iterator_to_array(new \FilesystemIterator($directory, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS)); - shuffle($files); //this prevents plugins implicitly relying on the filesystem name order when they should be using dependency properties + if(is_dir($path)){ + $files = iterator_to_array(new \FilesystemIterator($path, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS)); + shuffle($files); //this prevents plugins implicitly relying on the filesystem name order when they should be using dependency properties + }elseif(is_file($path)){ + $realPath = realpath($path); + if($realPath === false) throw new AssumptionFailedError("realpath() should not return false on an accessible, existing file"); + $files = [$realPath]; + }else{ + return; + } foreach($loaders as $loader){ foreach($files as $file){ if(!is_string($file)) throw new AssumptionFailedError("FilesystemIterator current should be string when using CURRENT_AS_PATHNAME"); @@ -374,9 +378,9 @@ class PluginManager{ /** * @return Plugin[] */ - public function loadPlugins(string $directory) : array{ + public function loadPlugins(string $path) : array{ $triage = new PluginLoadTriage(); - $this->triagePlugins($directory, $triage); + $this->triagePlugins($path, $triage); $loadedPlugins = []; @@ -402,7 +406,7 @@ class PluginManager{ if(count($diffLoaders) !== 0){ $this->server->getLogger()->debug("Plugin $name registered a new plugin loader during load, scanning for new plugins"); $plugins = $triage->plugins; - $this->triagePlugins($directory, $triage, $diffLoaders); + $this->triagePlugins($path, $triage, $diffLoaders); $diffPlugins = array_diff_assoc($triage->plugins, $plugins); $this->server->getLogger()->debug("Re-triage found plugins: " . implode(", ", array_keys($diffPlugins))); } From 76b4b23d98d5b17f09f6a918097fbb8ca8020099 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Oct 2021 21:52:19 +0100 Subject: [PATCH 2997/3224] PluginManager: remove loadPlugin() loadPlugins() is now the preferred option, since it does all the proper checks. In addition, the server now acknowledges that loading a single plugin may cause multiple plugins to be loaded, so returning only a single Plugin is not representative of what's actually happening. --- src/plugin/PluginManager.php | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index d39ee83356..fc560bf959 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -175,22 +175,6 @@ class PluginManager{ return null; } - /** - * @param PluginLoader[] $loaders - */ - public function loadPlugin(string $path, ?array $loaders = null) : ?Plugin{ - foreach($loaders ?? $this->fileAssociations as $loader){ - if($loader->canLoadPlugin($path)){ - $description = $loader->getPluginDescription($path); - if($description instanceof PluginDescription){ - $this->internalLoadPlugin($path, $loader, $description); - } - } - } - - return null; - } - private function internalLoadPlugin(string $path, PluginLoader $loader, PluginDescription $description) : ?Plugin{ $language = $this->server->getLanguage(); $this->server->getLogger()->info($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_load($description->getFullName()))); From 6d78a0b435ff0fc807a9d1e2bcdff2a2e72ac330 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Oct 2021 21:52:42 +0100 Subject: [PATCH 2998/3224] CS --- src/plugin/PluginManager.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index fc560bf959..8dc2b10926 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -59,10 +59,12 @@ use function in_array; use function is_a; use function is_array; use function is_dir; +use function is_file; use function is_string; use function is_subclass_of; use function iterator_to_array; use function mkdir; +use function realpath; use function shuffle; use function sprintf; use function stripos; From aa408c9a97ae737c6f98601106c09133b5047f15 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Oct 2021 21:54:57 +0100 Subject: [PATCH 2999/3224] Fixed 9646128d0176240c818dcefa57d39fb46af0de07 --- src/lang/KnownTranslationFactory.php | 4 ++++ src/lang/KnownTranslationKeys.php | 1 + 2 files changed, 5 insertions(+) diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index ce4f33c2b8..a08e87f5cd 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -2075,6 +2075,10 @@ final class KnownTranslationFactory{ return new Translatable(KnownTranslationKeys::POTION_SATURATION, []); } + public static function potion_slowFalling() : Translatable{ + return new Translatable(KnownTranslationKeys::POTION_SLOWFALLING, []); + } + public static function potion_waterBreathing() : Translatable{ return new Translatable(KnownTranslationKeys::POTION_WATERBREATHING, []); } diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index 16f4d26f40..cf4aca5553 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -430,6 +430,7 @@ final class KnownTranslationKeys{ public const POTION_REGENERATION = "potion.regeneration"; public const POTION_RESISTANCE = "potion.resistance"; public const POTION_SATURATION = "potion.saturation"; + public const POTION_SLOWFALLING = "potion.slowFalling"; public const POTION_WATERBREATHING = "potion.waterBreathing"; public const POTION_WEAKNESS = "potion.weakness"; public const POTION_WITHER = "potion.wither"; From 44508a138f8ce7e0459571bc1a4249dde951bf1b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Oct 2021 22:13:30 +0100 Subject: [PATCH 3000/3224] Moved plugin extension requirement checks to PluginManager::checkPluginLoadability() these don't really belong in PluginDescription. --- src/plugin/PluginDescription.php | 38 -------------------------------- src/plugin/PluginManager.php | 35 ++++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 43 deletions(-) diff --git a/src/plugin/PluginDescription.php b/src/plugin/PluginDescription.php index 895097cb5d..c1ab144fe8 100644 --- a/src/plugin/PluginDescription.php +++ b/src/plugin/PluginDescription.php @@ -30,13 +30,9 @@ use function array_map; use function array_values; use function is_array; use function is_string; -use function phpversion; use function preg_match; use function str_replace; use function stripos; -use function strlen; -use function substr; -use function version_compare; use function yaml_parse; class PluginDescription{ @@ -247,40 +243,6 @@ class PluginDescription{ return $this->extensions; } - /** - * Checks if the current PHP runtime has the extensions required by the plugin. - * - * @throws PluginException if there are required extensions missing or have incompatible version, or if the version constraint cannot be parsed - */ - public function checkRequiredExtensions() : void{ - foreach($this->extensions as $name => $versionConstrs){ - $gotVersion = phpversion($name); - if($gotVersion === false){ - throw new PluginException("Required extension $name not loaded"); - } - - foreach($versionConstrs as $constr){ // versionConstrs_loop - if($constr === "*"){ - continue; - } - if($constr === ""){ - throw new PluginException("One of the extension version constraints of $name is empty. Consider quoting the version string in plugin.yml"); - } - foreach(["<=", "le", "<>", "!=", "ne", "<", "lt", "==", "=", "eq", ">=", "ge", ">", "gt"] as $comparator){ - // warning: the > character should be quoted in YAML - if(substr($constr, 0, strlen($comparator)) === $comparator){ - $version = substr($constr, strlen($comparator)); - if(!version_compare($gotVersion, $version, $comparator)){ - throw new PluginException("Required extension $name has an incompatible version ($gotVersion not $constr)"); - } - continue 2; // versionConstrs_loop - } - } - throw new PluginException("Error parsing version constraint: $constr"); - } - } - } - /** * @return string[] */ diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 8dc2b10926..88e2d08b7c 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -64,12 +64,16 @@ use function is_string; use function is_subclass_of; use function iterator_to_array; use function mkdir; +use function phpversion; use function realpath; use function shuffle; use function sprintf; use function stripos; +use function strlen; use function strpos; use function strtolower; +use function substr; +use function version_compare; /** * Manages all the plugins @@ -136,7 +140,7 @@ class PluginManager{ return Path::join(dirname($pluginPath), $pluginName); } - private function checkPluginLoadability(PluginDescription $description) : Translatable|string|null{ + private function checkPluginLoadability(PluginDescription $description) : Translatable|null{ $name = $description->getName(); if(stripos($name, "pocketmine") !== false or stripos($name, "minecraft") !== false or stripos($name, "mojang") !== false){ return KnownTranslationFactory::pocketmine_plugin_restrictedName(); @@ -168,10 +172,31 @@ class PluginManager{ } } - try{ - $description->checkRequiredExtensions(); - }catch(PluginException $ex){ - return $ex->getMessage(); + foreach($description->getRequiredExtensions() as $extensionName => $versionConstrs){ + $gotVersion = phpversion($extensionName); + if($gotVersion === false){ + return KnownTranslationFactory::pocketmine_plugin_extensionNotLoaded($extensionName); + } + + foreach($versionConstrs as $k => $constr){ // versionConstrs_loop + if($constr === "*"){ + continue; + } + if($constr === ""){ + return KnownTranslationFactory::pocketmine_plugin_emptyExtensionVersionConstraint(extensionName: $extensionName, constraintIndex: "$k"); + } + foreach(["<=", "le", "<>", "!=", "ne", "<", "lt", "==", "=", "eq", ">=", "ge", ">", "gt"] as $comparator){ + // warning: the > character should be quoted in YAML + if(substr($constr, 0, strlen($comparator)) === $comparator){ + $version = substr($constr, strlen($comparator)); + if(!version_compare($gotVersion, $version, $comparator)){ + return KnownTranslationFactory::pocketmine_plugin_incompatibleExtensionVersion(extensionName: $extensionName, extensionVersion: $gotVersion, pluginRequirement: $constr); + } + continue 2; // versionConstrs_loop + } + } + return KnownTranslationFactory::pocketmine_plugin_invalidExtensionVersionConstraint(extensionName: $extensionName, versionConstraint: $constr); + } } return null; From 620874d902e91dca93f0ac5fbda83067a96e1e83 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Oct 2021 22:31:56 +0100 Subject: [PATCH 3001/3224] PluginManager: Extract checkPluginLoadability() to a PluginLoadabilityChecker unit this can be more easily unit-tested. --- src/plugin/PluginLoadabilityChecker.php | 108 ++++++++++++++++++++++++ src/plugin/PluginManager.php | 76 +---------------- 2 files changed, 111 insertions(+), 73 deletions(-) create mode 100644 src/plugin/PluginLoadabilityChecker.php diff --git a/src/plugin/PluginLoadabilityChecker.php b/src/plugin/PluginLoadabilityChecker.php new file mode 100644 index 0000000000..9d3ca0387a --- /dev/null +++ b/src/plugin/PluginLoadabilityChecker.php @@ -0,0 +1,108 @@ +getName(); + if(stripos($name, "pocketmine") !== false or stripos($name, "minecraft") !== false or stripos($name, "mojang") !== false){ + return KnownTranslationFactory::pocketmine_plugin_restrictedName(); + } + + foreach($description->getCompatibleApis() as $api){ + if(!VersionString::isValidBaseVersion($api)){ + return KnownTranslationFactory::pocketmine_plugin_invalidAPI($api); + } + } + + if(!ApiVersion::isCompatible($this->apiVersion, $description->getCompatibleApis())){ + return KnownTranslationFactory::pocketmine_plugin_incompatibleAPI(implode(", ", $description->getCompatibleApis())); + } + + $ambiguousVersions = ApiVersion::checkAmbiguousVersions($description->getCompatibleApis()); + if(count($ambiguousVersions) > 0){ + return KnownTranslationFactory::pocketmine_plugin_ambiguousMinAPI(implode(", ", $ambiguousVersions)); + } + + if(count($description->getCompatibleOperatingSystems()) > 0 and !in_array(Utils::getOS(), $description->getCompatibleOperatingSystems(), true)) { + return KnownTranslationFactory::pocketmine_plugin_incompatibleOS(implode(", ", $description->getCompatibleOperatingSystems())); + } + + if(count($pluginMcpeProtocols = $description->getCompatibleMcpeProtocols()) > 0){ + $serverMcpeProtocols = [ProtocolInfo::CURRENT_PROTOCOL]; + if(count(array_intersect($pluginMcpeProtocols, $serverMcpeProtocols)) === 0){ + return KnownTranslationFactory::pocketmine_plugin_incompatibleProtocol(implode(", ", $pluginMcpeProtocols)); + } + } + + foreach($description->getRequiredExtensions() as $extensionName => $versionConstrs){ + $gotVersion = phpversion($extensionName); + if($gotVersion === false){ + return KnownTranslationFactory::pocketmine_plugin_extensionNotLoaded($extensionName); + } + + foreach($versionConstrs as $k => $constr){ // versionConstrs_loop + if($constr === "*"){ + continue; + } + if($constr === ""){ + return KnownTranslationFactory::pocketmine_plugin_emptyExtensionVersionConstraint(extensionName: $extensionName, constraintIndex: "$k"); + } + foreach(["<=", "le", "<>", "!=", "ne", "<", "lt", "==", "=", "eq", ">=", "ge", ">", "gt"] as $comparator){ + // warning: the > character should be quoted in YAML + if(substr($constr, 0, strlen($comparator)) === $comparator){ + $version = substr($constr, strlen($comparator)); + if(!version_compare($gotVersion, $version, $comparator)){ + return KnownTranslationFactory::pocketmine_plugin_incompatibleExtensionVersion(extensionName: $extensionName, extensionVersion: $gotVersion, pluginRequirement: $constr); + } + continue 2; // versionConstrs_loop + } + } + return KnownTranslationFactory::pocketmine_plugin_invalidExtensionVersionConstraint(extensionName: $extensionName, versionConstraint: $constr); + } + } + + return null; + } +} \ No newline at end of file diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 88e2d08b7c..f244888781 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -33,8 +33,6 @@ use pocketmine\event\plugin\PluginDisableEvent; use pocketmine\event\plugin\PluginEnableEvent; use pocketmine\event\RegisteredListener; use pocketmine\lang\KnownTranslationFactory; -use pocketmine\lang\Translatable; -use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\permission\DefaultPermissions; use pocketmine\permission\PermissionManager; use pocketmine\permission\PermissionParser; @@ -42,10 +40,8 @@ use pocketmine\Server; use pocketmine\timings\TimingsHandler; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Utils; -use pocketmine\utils\VersionString; use Webmozart\PathUtil\Path; use function array_diff_assoc; -use function array_intersect; use function array_key_exists; use function array_keys; use function array_merge; @@ -55,7 +51,6 @@ use function dirname; use function file_exists; use function get_class; use function implode; -use function in_array; use function is_a; use function is_array; use function is_dir; @@ -64,16 +59,11 @@ use function is_string; use function is_subclass_of; use function iterator_to_array; use function mkdir; -use function phpversion; use function realpath; use function shuffle; use function sprintf; -use function stripos; -use function strlen; use function strpos; use function strtolower; -use function substr; -use function version_compare; /** * Manages all the plugins @@ -140,68 +130,6 @@ class PluginManager{ return Path::join(dirname($pluginPath), $pluginName); } - private function checkPluginLoadability(PluginDescription $description) : Translatable|null{ - $name = $description->getName(); - if(stripos($name, "pocketmine") !== false or stripos($name, "minecraft") !== false or stripos($name, "mojang") !== false){ - return KnownTranslationFactory::pocketmine_plugin_restrictedName(); - } - - foreach($description->getCompatibleApis() as $api){ - if(!VersionString::isValidBaseVersion($api)){ - return KnownTranslationFactory::pocketmine_plugin_invalidAPI($api); - } - } - - if(!ApiVersion::isCompatible($this->server->getApiVersion(), $description->getCompatibleApis())){ - return KnownTranslationFactory::pocketmine_plugin_incompatibleAPI(implode(", ", $description->getCompatibleApis())); - } - - $ambiguousVersions = ApiVersion::checkAmbiguousVersions($description->getCompatibleApis()); - if(count($ambiguousVersions) > 0){ - return KnownTranslationFactory::pocketmine_plugin_ambiguousMinAPI(implode(", ", $ambiguousVersions)); - } - - if(count($description->getCompatibleOperatingSystems()) > 0 and !in_array(Utils::getOS(), $description->getCompatibleOperatingSystems(), true)) { - return KnownTranslationFactory::pocketmine_plugin_incompatibleOS(implode(", ", $description->getCompatibleOperatingSystems())); - } - - if(count($pluginMcpeProtocols = $description->getCompatibleMcpeProtocols()) > 0){ - $serverMcpeProtocols = [ProtocolInfo::CURRENT_PROTOCOL]; - if(count(array_intersect($pluginMcpeProtocols, $serverMcpeProtocols)) === 0){ - return KnownTranslationFactory::pocketmine_plugin_incompatibleProtocol(implode(", ", $pluginMcpeProtocols)); - } - } - - foreach($description->getRequiredExtensions() as $extensionName => $versionConstrs){ - $gotVersion = phpversion($extensionName); - if($gotVersion === false){ - return KnownTranslationFactory::pocketmine_plugin_extensionNotLoaded($extensionName); - } - - foreach($versionConstrs as $k => $constr){ // versionConstrs_loop - if($constr === "*"){ - continue; - } - if($constr === ""){ - return KnownTranslationFactory::pocketmine_plugin_emptyExtensionVersionConstraint(extensionName: $extensionName, constraintIndex: "$k"); - } - foreach(["<=", "le", "<>", "!=", "ne", "<", "lt", "==", "=", "eq", ">=", "ge", ">", "gt"] as $comparator){ - // warning: the > character should be quoted in YAML - if(substr($constr, 0, strlen($comparator)) === $comparator){ - $version = substr($constr, strlen($comparator)); - if(!version_compare($gotVersion, $version, $comparator)){ - return KnownTranslationFactory::pocketmine_plugin_incompatibleExtensionVersion(extensionName: $extensionName, extensionVersion: $gotVersion, pluginRequirement: $constr); - } - continue 2; // versionConstrs_loop - } - } - return KnownTranslationFactory::pocketmine_plugin_invalidExtensionVersionConstraint(extensionName: $extensionName, versionConstraint: $constr); - } - } - - return null; - } - private function internalLoadPlugin(string $path, PluginLoader $loader, PluginDescription $description) : ?Plugin{ $language = $this->server->getLanguage(); $this->server->getLogger()->info($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_load($description->getFullName()))); @@ -302,6 +230,8 @@ class PluginManager{ }else{ return; } + + $loadabilityChecker = new PluginLoadabilityChecker($this->server->getApiVersion()); foreach($loaders as $loader){ foreach($files as $file){ if(!is_string($file)) throw new AssumptionFailedError("FilesystemIterator current should be string when using CURRENT_AS_PATHNAME"); @@ -327,7 +257,7 @@ class PluginManager{ $name = $description->getName(); - if(($loadabilityError = $this->checkPluginLoadability($description)) !== null){ + if(($loadabilityError = $loadabilityChecker->check($description)) !== null){ $this->server->getLogger()->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError($name, $loadabilityError))); continue; } From e2275cc8ec02b1d3b9dac8735f7e1060a913fb26 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Oct 2021 23:10:18 +0100 Subject: [PATCH 3002/3224] PluginManager: Prevent infinite recursion in loadPlugins() if a plugin calls loadPlugins(server->getPluginPath()) during its onLoad(), and it itself is in that plugin path, an infinite recursion will occur. --- src/plugin/PluginManager.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index f244888781..c46ad4a65b 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -79,6 +79,8 @@ class PluginManager{ /** @var Plugin[] */ protected $enabledPlugins = []; + private bool $loadPluginsGuard = false; + /** * @var PluginLoader[] * @phpstan-var array, PluginLoader> @@ -320,6 +322,11 @@ class PluginManager{ * @return Plugin[] */ public function loadPlugins(string $path) : array{ + if($this->loadPluginsGuard){ + throw new \LogicException(__METHOD__ . "() cannot be called from within itself"); + } + $this->loadPluginsGuard = true; + $triage = new PluginLoadTriage(); $this->triagePlugins($path, $triage); @@ -404,6 +411,7 @@ class PluginManager{ } } + $this->loadPluginsGuard = false; return $loadedPlugins; } From 4f2bcb61d693d68243862f233f0c6c4272397640 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 20 Oct 2021 23:35:04 +0100 Subject: [PATCH 3003/3224] Fixed crashdump generation when crashing before PluginManager was created --- src/CrashDump.php | 9 ++++++--- src/Server.php | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/CrashDump.php b/src/CrashDump.php index 983ecd4a89..a42d757aed 100644 --- a/src/CrashDump.php +++ b/src/CrashDump.php @@ -101,9 +101,12 @@ class CrashDump{ /** @var string */ private $path; - public function __construct(Server $server){ + private ?PluginManager $pluginManager; + + public function __construct(Server $server, ?PluginManager $pluginManager){ $this->time = microtime(true); $this->server = $server; + $this->pluginManager = $pluginManager; $crashPath = Path::join($this->server->getDataPath(), "crashdumps"); if(!is_dir($crashPath)){ @@ -166,11 +169,11 @@ class CrashDump{ } private function pluginsData() : void{ - if($this->server->getPluginManager() instanceof PluginManager){ + if($this->pluginManager !== null){ + $plugins = $this->pluginManager->getPlugins(); $this->addLine(); $this->addLine("Loaded plugins:"); $this->data["plugins"] = []; - $plugins = $this->server->getPluginManager()->getPlugins(); ksort($plugins, SORT_STRING); foreach($plugins as $p){ $d = $p->getDescription(); diff --git a/src/Server.php b/src/Server.php index b1b3579073..dcec8fb053 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1476,7 +1476,7 @@ class Server{ ini_set("memory_limit", '-1'); //Fix error dump not dumped on memory problems try{ $this->logger->emergency($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_crash_create())); - $dump = new CrashDump($this); + $dump = new CrashDump($this, $this->pluginManager ?? null); $this->logger->emergency($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_crash_submit($dump->getPath()))); From 2971bf30a50dc91e0a88c0e95d8465bdaa8c3bca Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Oct 2021 00:30:19 +0100 Subject: [PATCH 3004/3224] actions: combine code verify into one step this way the diff takes one less click to get to. --- .github/workflows/main.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5a56fc25e9..9ba8745123 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -238,11 +238,10 @@ jobs: - name: Regenerate KnownTranslation APIs run: php build/generate-known-translation-apis.php - - name: Run git diff - run: git diff - - - name: Fail job if changes were made - run: git diff --quiet + - name: Verify code is unchanged + run: | + git diff + git diff --quiet codestyle: name: Code Style checks From a4b65d6a3f40d74dac02ca5e842a8fb664a40047 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 21 Oct 2021 14:49:46 +0100 Subject: [PATCH 3005/3224] PlayerCreationEvent: verify that the class actually exists and is instantiable this ensures that crashdumps blame the plugin instead of the core on bad classes, such as in this case: https://crash.pmmp.io/view/5331225 --- src/event/player/PlayerCreationEvent.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/event/player/PlayerCreationEvent.php b/src/event/player/PlayerCreationEvent.php index d4056ee12d..013fcdb2aa 100644 --- a/src/event/player/PlayerCreationEvent.php +++ b/src/event/player/PlayerCreationEvent.php @@ -26,6 +26,7 @@ namespace pocketmine\event\player; use pocketmine\event\Event; use pocketmine\network\mcpe\NetworkSession; use pocketmine\player\Player; +use pocketmine\utils\Utils; use function is_a; /** @@ -96,10 +97,7 @@ class PlayerCreationEvent extends Event{ * @phpstan-param class-string $class */ public function setPlayerClass($class) : void{ - if(!is_a($class, $this->baseClass, true)){ - throw new \RuntimeException("Class $class must extend " . $this->baseClass); - } - + Utils::testValidInstance($class, $this->baseClass); $this->playerClass = $class; } } From c262c2e726fc0b474566ae6a41d577416b4d16c3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Oct 2021 01:14:54 +0100 Subject: [PATCH 3006/3224] Updated composer dependencies --- composer.lock | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/composer.lock b/composer.lock index cb1287b83d..dbeae084d3 100644 --- a/composer.lock +++ b/composer.lock @@ -249,16 +249,16 @@ }, { "name": "pocketmine/bedrock-protocol", - "version": "3.0.1+bedrock1.17.40", + "version": "3.0.2+bedrock1.17.40", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "1add11e06366b983b97fa415fee55f31af3cb7a9" + "reference": "3edb21da787c1ab0f028d35243f87bd7c9038b9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/1add11e06366b983b97fa415fee55f31af3cb7a9", - "reference": "1add11e06366b983b97fa415fee55f31af3cb7a9", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/3edb21da787c1ab0f028d35243f87bd7c9038b9e", + "reference": "3edb21da787c1ab0f028d35243f87bd7c9038b9e", "shasum": "" }, "require": { @@ -290,22 +290,22 @@ "description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP", "support": { "issues": "https://github.com/pmmp/BedrockProtocol/issues", - "source": "https://github.com/pmmp/BedrockProtocol/tree/3.0.1+bedrock1.17.40" + "source": "https://github.com/pmmp/BedrockProtocol/tree/3.0.2+bedrock1.17.40" }, - "time": "2021-10-20T14:00:00+00:00" + "time": "2021-10-20T18:52:14+00:00" }, { "name": "pocketmine/binaryutils", - "version": "0.2.1", + "version": "0.2.2", "source": { "type": "git", "url": "https://github.com/pmmp/BinaryUtils.git", - "reference": "8cd078e2426f8100331f2d73bef10f481dad6cde" + "reference": "f883e1cf9099ed6a757a10a2f75b3333eeb2cdf9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/8cd078e2426f8100331f2d73bef10f481dad6cde", - "reference": "8cd078e2426f8100331f2d73bef10f481dad6cde", + "url": "https://api.github.com/repos/pmmp/BinaryUtils/zipball/f883e1cf9099ed6a757a10a2f75b3333eeb2cdf9", + "reference": "f883e1cf9099ed6a757a10a2f75b3333eeb2cdf9", "shasum": "" }, "require": { @@ -314,7 +314,7 @@ }, "require-dev": { "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "0.12.85", + "phpstan/phpstan": "0.12.99", "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", @@ -330,9 +330,9 @@ "description": "Classes and methods for conveniently handling binary data", "support": { "issues": "https://github.com/pmmp/BinaryUtils/issues", - "source": "https://github.com/pmmp/BinaryUtils/tree/0.2.1" + "source": "https://github.com/pmmp/BinaryUtils/tree/0.2.2" }, - "time": "2021-05-30T19:42:57+00:00" + "time": "2021-10-22T19:54:16+00:00" }, { "name": "pocketmine/callback-validator", @@ -3325,7 +3325,6 @@ "type": "github" } ], - "abandoned": true, "time": "2020-09-28T06:45:17+00:00" }, { From c773e43eda0da159b181ef1c79f29a6c8986e697 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Oct 2021 01:16:45 +0100 Subject: [PATCH 3007/3224] Updated BedrockProtocol to pmmp/BedrockProtocol@97fa88e9eff2c9bd5408fa964515504a4d9230bf --- composer.json | 2 +- composer.lock | 16 +++-- src/block/inventory/ChestInventory.php | 3 +- src/block/inventory/EnderChestInventory.php | 3 +- src/block/inventory/ShulkerBoxInventory.php | 3 +- src/block/tile/Bell.php | 3 +- src/entity/Entity.php | 2 +- src/entity/Human.php | 4 +- src/entity/object/ItemEntity.php | 2 +- src/entity/object/Painting.php | 2 +- src/network/mcpe/InventoryManager.php | 21 +++--- src/network/mcpe/NetworkSession.php | 18 ++--- src/network/mcpe/cache/CraftingDataCache.php | 6 +- .../mcpe/handler/InGamePacketHandler.php | 53 ++++++++------- .../mcpe/handler/PreSpawnPacketHandler.php | 67 +++++++++++-------- .../handler/ResourcePacksPacketHandler.php | 8 ++- src/player/Player.php | 3 +- src/world/World.php | 11 ++- src/world/particle/FloatingTextParticle.php | 2 +- src/world/sound/ArrowHitSound.php | 2 +- src/world/sound/BarrelCloseSound.php | 2 +- src/world/sound/BarrelOpenSound.php | 2 +- src/world/sound/BellRingSound.php | 2 +- src/world/sound/BlockBreakSound.php | 2 +- src/world/sound/BlockPlaceSound.php | 2 +- src/world/sound/BlockPunchSound.php | 3 +- src/world/sound/BowShootSound.php | 2 +- src/world/sound/BucketEmptyLavaSound.php | 2 +- src/world/sound/BucketEmptyWaterSound.php | 2 +- src/world/sound/BucketFillLavaSound.php | 2 +- src/world/sound/BucketFillWaterSound.php | 2 +- src/world/sound/ChestCloseSound.php | 2 +- src/world/sound/ChestOpenSound.php | 2 +- src/world/sound/EnderChestCloseSound.php | 2 +- src/world/sound/EnderChestOpenSound.php | 2 +- src/world/sound/EntityAttackNoDamageSound.php | 4 +- src/world/sound/EntityAttackSound.php | 4 +- src/world/sound/EntityLandSound.php | 5 +- src/world/sound/EntityLongFallSound.php | 5 +- src/world/sound/EntityShortFallSound.php | 5 +- src/world/sound/ExplodeSound.php | 2 +- src/world/sound/FireExtinguishSound.php | 2 +- src/world/sound/FlintSteelSound.php | 2 +- src/world/sound/ItemBreakSound.php | 2 +- src/world/sound/NoteSound.php | 2 +- src/world/sound/PotionSplashSound.php | 2 +- src/world/sound/RecordSound.php | 2 +- src/world/sound/RecordStopSound.php | 2 +- src/world/sound/RedstonePowerOffSound.php | 2 +- src/world/sound/RedstonePowerOnSound.php | 2 +- src/world/sound/ShulkerBoxCloseSound.php | 2 +- src/world/sound/ShulkerBoxOpenSound.php | 2 +- src/world/sound/ThrowSound.php | 2 +- src/world/sound/XpLevelUpSound.php | 2 +- 54 files changed, 178 insertions(+), 135 deletions(-) diff --git a/composer.json b/composer.json index 4a01020a7c..22b5cd7a02 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "adhocore/json-comment": "^1.1", "fgrosse/phpasn1": "^2.3", "netresearch/jsonmapper": "^4.0", - "pocketmine/bedrock-protocol": "^3.0.1+bedrock1.17.40", + "pocketmine/bedrock-protocol": "dev-master", "pocketmine/binaryutils": "^0.2.1", "pocketmine/callback-validator": "^1.0.2", "pocketmine/classloader": "dev-master", diff --git a/composer.lock b/composer.lock index dbeae084d3..89bd8e43b7 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "bc2b425a6f436a01de4e423ea651dc84", + "content-hash": "ddbcdbc7ea7247bea7fcb37e5c42340b", "packages": [ { "name": "adhocore/json-comment", @@ -249,16 +249,16 @@ }, { "name": "pocketmine/bedrock-protocol", - "version": "3.0.2+bedrock1.17.40", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "3edb21da787c1ab0f028d35243f87bd7c9038b9e" + "reference": "97fa88e9eff2c9bd5408fa964515504a4d9230bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/3edb21da787c1ab0f028d35243f87bd7c9038b9e", - "reference": "3edb21da787c1ab0f028d35243f87bd7c9038b9e", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/97fa88e9eff2c9bd5408fa964515504a4d9230bf", + "reference": "97fa88e9eff2c9bd5408fa964515504a4d9230bf", "shasum": "" }, "require": { @@ -277,6 +277,7 @@ "phpstan/phpstan-strict-rules": "^0.12.10", "phpunit/phpunit": "^9.5" }, + "default-branch": true, "type": "library", "autoload": { "psr-4": { @@ -290,9 +291,9 @@ "description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP", "support": { "issues": "https://github.com/pmmp/BedrockProtocol/issues", - "source": "https://github.com/pmmp/BedrockProtocol/tree/3.0.2+bedrock1.17.40" + "source": "https://github.com/pmmp/BedrockProtocol/tree/master" }, - "time": "2021-10-20T18:52:14+00:00" + "time": "2021-10-23T00:06:46+00:00" }, { "name": "pocketmine/binaryutils", @@ -3490,6 +3491,7 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { + "pocketmine/bedrock-protocol": 20, "pocketmine/classloader": 20, "pocketmine/spl": 20 }, diff --git a/src/block/inventory/ChestInventory.php b/src/block/inventory/ChestInventory.php index 1f8538e4bd..b7594b2320 100644 --- a/src/block/inventory/ChestInventory.php +++ b/src/block/inventory/ChestInventory.php @@ -25,6 +25,7 @@ namespace pocketmine\block\inventory; use pocketmine\inventory\SimpleInventory; use pocketmine\network\mcpe\protocol\BlockEventPacket; +use pocketmine\network\mcpe\protocol\types\BlockPosition; use pocketmine\world\Position; use pocketmine\world\sound\ChestCloseSound; use pocketmine\world\sound\ChestOpenSound; @@ -50,6 +51,6 @@ class ChestInventory extends SimpleInventory implements BlockInventory{ $holder = $this->getHolder(); //event ID is always 1 for a chest - $holder->getWorld()->broadcastPacketToViewers($holder, BlockEventPacket::create(1, $isOpen ? 1 : 0, $holder->asVector3())); + $holder->getWorld()->broadcastPacketToViewers($holder, BlockEventPacket::create(BlockPosition::fromVector3($holder), 1, $isOpen ? 1 : 0)); } } diff --git a/src/block/inventory/EnderChestInventory.php b/src/block/inventory/EnderChestInventory.php index 6887219c69..b9ff1832ef 100644 --- a/src/block/inventory/EnderChestInventory.php +++ b/src/block/inventory/EnderChestInventory.php @@ -28,6 +28,7 @@ use pocketmine\inventory\DelegateInventory; use pocketmine\inventory\Inventory; use pocketmine\inventory\PlayerEnderInventory; use pocketmine\network\mcpe\protocol\BlockEventPacket; +use pocketmine\network\mcpe\protocol\types\BlockPosition; use pocketmine\player\Player; use pocketmine\world\Position; use pocketmine\world\sound\EnderChestCloseSound; @@ -74,7 +75,7 @@ class EnderChestInventory extends DelegateInventory implements BlockInventory{ $holder = $this->getHolder(); //event ID is always 1 for a chest - $holder->getWorld()->broadcastPacketToViewers($holder, BlockEventPacket::create(1, $isOpen ? 1 : 0, $holder->asVector3())); + $holder->getWorld()->broadcastPacketToViewers($holder, BlockEventPacket::create(BlockPosition::fromVector3($holder), 1, $isOpen ? 1 : 0)); } public function onClose(Player $who) : void{ diff --git a/src/block/inventory/ShulkerBoxInventory.php b/src/block/inventory/ShulkerBoxInventory.php index 3e4edcdd7e..cace496522 100644 --- a/src/block/inventory/ShulkerBoxInventory.php +++ b/src/block/inventory/ShulkerBoxInventory.php @@ -27,6 +27,7 @@ use pocketmine\block\BlockLegacyIds; use pocketmine\inventory\SimpleInventory; use pocketmine\item\Item; use pocketmine\network\mcpe\protocol\BlockEventPacket; +use pocketmine\network\mcpe\protocol\types\BlockPosition; use pocketmine\world\Position; use pocketmine\world\sound\ShulkerBoxCloseSound; use pocketmine\world\sound\ShulkerBoxOpenSound; @@ -59,6 +60,6 @@ class ShulkerBoxInventory extends SimpleInventory implements BlockInventory{ $holder = $this->getHolder(); //event ID is always 1 for a chest - $holder->getWorld()->broadcastPacketToViewers($holder, BlockEventPacket::create(1, $isOpen ? 1 : 0, $holder->asVector3())); + $holder->getWorld()->broadcastPacketToViewers($holder, BlockEventPacket::create(BlockPosition::fromVector3($holder), 1, $isOpen ? 1 : 0)); } } diff --git a/src/block/tile/Bell.php b/src/block/tile/Bell.php index b7e5eadde2..bc2ab29fe7 100644 --- a/src/block/tile/Bell.php +++ b/src/block/tile/Bell.php @@ -27,6 +27,7 @@ use pocketmine\block\utils\BlockDataSerializer; use pocketmine\math\Facing; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\BlockActorDataPacket; +use pocketmine\network\mcpe\protocol\types\BlockPosition; use pocketmine\network\mcpe\protocol\types\CacheableNbt; final class Bell extends Spawnable{ @@ -81,6 +82,6 @@ final class Bell extends Spawnable{ $nbt->setByte(self::TAG_RINGING, 1); $nbt->setInt(self::TAG_DIRECTION, BlockDataSerializer::writeLegacyHorizontalFacing($bellHitFace)); $nbt->setInt(self::TAG_TICKS, 0); - return BlockActorDataPacket::create($this->position->getFloorX(), $this->position->getFloorY(), $this->position->getFloorZ(), new CacheableNbt($nbt)); + return BlockActorDataPacket::create(BlockPosition::fromVector3($this->position), new CacheableNbt($nbt)); } } diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 8bab76480b..ceb5a97b1e 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1419,7 +1419,7 @@ abstract class Entity{ */ protected function sendSpawnPacket(Player $player) : void{ $pk = new AddActorPacket(); - $pk->entityRuntimeId = $this->getId(); + $pk->actorRuntimeId = $this->getId(); $pk->type = static::getNetworkTypeId(); $pk->position = $this->location->asVector3(); $pk->motion = $this->getMotion(); diff --git a/src/entity/Human.php b/src/entity/Human.php index 4768422ae7..c953ffb471 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -145,7 +145,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ */ public function sendSkin(?array $targets = null) : void{ $this->server->broadcastPackets($targets ?? $this->hasSpawned, [ - PlayerSkinPacket::create($this->getUniqueId(), SkinAdapterSingleton::get()->toSkinData($this->skin)) + PlayerSkinPacket::create($this->getUniqueId(), "", "", SkinAdapterSingleton::get()->toSkinData($this->skin)) ]); } @@ -447,7 +447,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $pk = new AddPlayerPacket(); $pk->uuid = $this->getUniqueId(); $pk->username = $this->getName(); - $pk->entityRuntimeId = $this->getId(); + $pk->actorRuntimeId = $this->getId(); $pk->position = $this->location->asVector3(); $pk->motion = $this->getMotion(); $pk->yaw = $this->location->yaw; diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index 2b16b7a117..e9c71c6c2b 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -207,7 +207,7 @@ class ItemEntity extends Entity{ protected function sendSpawnPacket(Player $player) : void{ $pk = new AddItemActorPacket(); - $pk->entityRuntimeId = $this->getId(); + $pk->actorRuntimeId = $this->getId(); $pk->position = $this->location->asVector3(); $pk->motion = $this->getMotion(); $pk->item = ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($this->getItem())); diff --git a/src/entity/object/Painting.php b/src/entity/object/Painting.php index 4769df15d2..fa031cb982 100644 --- a/src/entity/object/Painting.php +++ b/src/entity/object/Painting.php @@ -150,7 +150,7 @@ class Painting extends Entity{ protected function sendSpawnPacket(Player $player) : void{ $pk = new AddPaintingPacket(); - $pk->entityRuntimeId = $this->getId(); + $pk->actorRuntimeId = $this->getId(); $pk->position = new Vector3( ($this->boundingBox->minX + $this->boundingBox->maxX) / 2, ($this->boundingBox->minY + $this->boundingBox->maxY) / 2, diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index 67931b7d0a..db5b3a2ae8 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -45,6 +45,7 @@ use pocketmine\network\mcpe\protocol\CreativeContentPacket; use pocketmine\network\mcpe\protocol\InventoryContentPacket; use pocketmine\network\mcpe\protocol\InventorySlotPacket; use pocketmine\network\mcpe\protocol\MobEquipmentPacket; +use pocketmine\network\mcpe\protocol\types\BlockPosition; use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; use pocketmine\network\mcpe\protocol\types\inventory\CreativeContentEntry; use pocketmine\network\mcpe\protocol\types\inventory\ItemStackWrapper; @@ -164,26 +165,27 @@ class InventoryManager{ //TODO: we should be using some kind of tagging system to identify the types. Instanceof is flaky especially //if the class isn't final, not to mention being inflexible. if($inv instanceof BlockInventory){ + $blockPosition = BlockPosition::fromVector3($inv->getHolder()); switch(true){ case $inv instanceof LoomInventory: - return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::LOOM, $inv->getHolder())]; + return [ContainerOpenPacket::blockInv($id, WindowTypes::LOOM, $blockPosition)]; case $inv instanceof FurnaceInventory: return match($inv->getFurnaceType()->id()){ - FurnaceType::FURNACE()->id() => [ContainerOpenPacket::blockInvVec3($id, WindowTypes::FURNACE, $inv->getHolder())], - FurnaceType::BLAST_FURNACE()->id() => [ContainerOpenPacket::blockInvVec3($id, WindowTypes::BLAST_FURNACE, $inv->getHolder())], - FurnaceType::SMOKER()->id() => [ContainerOpenPacket::blockInvVec3($id, WindowTypes::SMOKER, $inv->getHolder())], + FurnaceType::FURNACE()->id() => [ContainerOpenPacket::blockInv($id, WindowTypes::FURNACE, $blockPosition)], + FurnaceType::BLAST_FURNACE()->id() => [ContainerOpenPacket::blockInv($id, WindowTypes::BLAST_FURNACE, $blockPosition)], + FurnaceType::SMOKER()->id() => [ContainerOpenPacket::blockInv($id, WindowTypes::SMOKER, $blockPosition)], default => throw new AssumptionFailedError("Unreachable") }; case $inv instanceof EnchantInventory: - return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::ENCHANTMENT, $inv->getHolder())]; + return [ContainerOpenPacket::blockInv($id, WindowTypes::ENCHANTMENT, $blockPosition)]; case $inv instanceof BrewingStandInventory: - return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::BREWING_STAND, $inv->getHolder())]; + return [ContainerOpenPacket::blockInv($id, WindowTypes::BREWING_STAND, $blockPosition)]; case $inv instanceof AnvilInventory: - return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::ANVIL, $inv->getHolder())]; + return [ContainerOpenPacket::blockInv($id, WindowTypes::ANVIL, $blockPosition)]; case $inv instanceof HopperInventory: - return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::HOPPER, $inv->getHolder())]; + return [ContainerOpenPacket::blockInv($id, WindowTypes::HOPPER, $blockPosition)]; default: - return [ContainerOpenPacket::blockInvVec3($id, WindowTypes::CONTAINER, $inv->getHolder())]; + return [ContainerOpenPacket::blockInv($id, WindowTypes::CONTAINER, $blockPosition)]; } } return null; @@ -279,6 +281,7 @@ class InventoryManager{ $this->player->getId(), ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($this->player->getInventory()->getItemInHand())), $selected, + $selected, ContainerIds::INVENTORY )); $this->clientSelectedHotbarSlot = $selected; diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index be4ea440a2..720e993494 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -88,6 +88,7 @@ use pocketmine\network\mcpe\protocol\SetTitlePacket; use pocketmine\network\mcpe\protocol\TakeItemActorPacket; use pocketmine\network\mcpe\protocol\TextPacket; use pocketmine\network\mcpe\protocol\TransferPacket; +use pocketmine\network\mcpe\protocol\types\BlockPosition; use pocketmine\network\mcpe\protocol\types\command\CommandData; use pocketmine\network\mcpe\protocol\types\command\CommandEnum; use pocketmine\network\mcpe\protocol\types\command\CommandParameter; @@ -727,7 +728,7 @@ class NetworkSession{ $pitch = $pitch ?? $location->getPitch(); $pk = new MovePlayerPacket(); - $pk->entityRuntimeId = $this->player->getId(); + $pk->actorRuntimeId = $this->player->getId(); $pk->position = $this->player->getOffsetPosition($pos); $pk->pitch = $pitch; $pk->headYaw = $yaw; @@ -748,16 +749,17 @@ class NetworkSession{ } public function syncViewAreaCenterPoint(Vector3 $newPos, int $viewDistance) : void{ - $this->sendDataPacket(NetworkChunkPublisherUpdatePacket::create($newPos->getFloorX(), $newPos->getFloorY(), $newPos->getFloorZ(), $viewDistance * 16)); //blocks, not chunks >.> + $this->sendDataPacket(NetworkChunkPublisherUpdatePacket::create(BlockPosition::fromVector3($newPos), $viewDistance * 16)); //blocks, not chunks >.> } public function syncPlayerSpawnPoint(Position $newSpawn) : void{ - [$x, $y, $z] = [$newSpawn->getFloorX(), $newSpawn->getFloorY(), $newSpawn->getFloorZ()]; - $this->sendDataPacket(SetSpawnPositionPacket::playerSpawn($x, $y, $z, DimensionIds::OVERWORLD, $x, $y, $z)); + $newSpawnBlockPosition = BlockPosition::fromVector3($newSpawn); + //TODO: respawn causing block position (bed, respawn anchor) + $this->sendDataPacket(SetSpawnPositionPacket::playerSpawn($newSpawnBlockPosition, DimensionIds::OVERWORLD, $newSpawnBlockPosition)); } public function syncWorldSpawnPoint(Position $newSpawn) : void{ - $this->sendDataPacket(SetSpawnPositionPacket::worldSpawn($newSpawn->getFloorX(), $newSpawn->getFloorY(), $newSpawn->getFloorZ(), DimensionIds::OVERWORLD)); + $this->sendDataPacket(SetSpawnPositionPacket::worldSpawn(BlockPosition::fromVector3($newSpawn), DimensionIds::OVERWORLD)); } public function syncGameMode(GameMode $mode, bool $isRollback = false) : void{ @@ -788,7 +790,7 @@ class NetworkSession{ $isOp = $for->hasPermission(DefaultPermissions::ROOT_OPERATOR); $pk->commandPermission = ($isOp ? AdventureSettingsPacket::PERMISSION_OPERATOR : AdventureSettingsPacket::PERMISSION_NORMAL); $pk->playerPermission = ($isOp ? PlayerPermissions::OPERATOR : PlayerPermissions::MEMBER); - $pk->entityUniqueId = $for->getId(); + $pk->targetActorUniqueId = $for->getId(); $this->sendDataPacket($pk); } @@ -966,12 +968,12 @@ class NetworkSession{ public function onMobMainHandItemChange(Human $mob) : void{ //TODO: we could send zero for slot here because remote players don't need to know which slot was selected $inv = $mob->getInventory(); - $this->sendDataPacket(MobEquipmentPacket::create($mob->getId(), ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($inv->getItemInHand())), $inv->getHeldItemIndex(), ContainerIds::INVENTORY)); + $this->sendDataPacket(MobEquipmentPacket::create($mob->getId(), ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($inv->getItemInHand())), $inv->getHeldItemIndex(), $inv->getHeldItemIndex(), ContainerIds::INVENTORY)); } public function onMobOffHandItemChange(Human $mob) : void{ $inv = $mob->getOffHandInventory(); - $this->sendDataPacket(MobEquipmentPacket::create($mob->getId(), ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($inv->getItem(0))), 0, ContainerIds::OFFHAND)); + $this->sendDataPacket(MobEquipmentPacket::create($mob->getId(), ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($inv->getItem(0))), 0, 0, ContainerIds::OFFHAND)); } public function onMobArmorChange(Living $mob) : void{ diff --git a/src/network/mcpe/cache/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php index a87629a262..68414e835c 100644 --- a/src/network/mcpe/cache/CraftingDataCache.php +++ b/src/network/mcpe/cache/CraftingDataCache.php @@ -79,7 +79,7 @@ final class CraftingDataCache{ $converter = TypeConverter::getInstance(); foreach($manager->getShapelessRecipes() as $list){ foreach($list as $recipe){ - $pk->entries[] = new ProtocolShapelessRecipe( + $pk->recipesWithTypeIds[] = new ProtocolShapelessRecipe( CraftingDataPacket::ENTRY_SHAPELESS, Binary::writeInt(++$counter), array_map(function(Item $item) use ($converter) : RecipeIngredient{ @@ -104,7 +104,7 @@ final class CraftingDataCache{ $inputs[$row][$column] = $converter->coreItemStackToRecipeIngredient($recipe->getIngredient($column, $row)); } } - $pk->entries[] = $r = new ProtocolShapedRecipe( + $pk->recipesWithTypeIds[] = $r = new ProtocolShapedRecipe( CraftingDataPacket::ENTRY_SHAPED, Binary::writeInt(++$counter), $inputs, @@ -128,7 +128,7 @@ final class CraftingDataCache{ }; foreach($manager->getFurnaceRecipeManager($furnaceType)->getAll() as $recipe){ $input = $converter->coreItemStackToNet($recipe->getInput()); - $pk->entries[] = new ProtocolFurnaceRecipe( + $pk->recipesWithTypeIds[] = new ProtocolFurnaceRecipe( CraftingDataPacket::ENTRY_FURNACE_DATA, $input->getId(), $input->getMeta(), diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 65d294ae8c..a8e784ceda 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -199,13 +199,13 @@ class InGamePacketHandler extends PacketHandler{ } public function handleActorEvent(ActorEventPacket $packet) : bool{ - if($packet->entityRuntimeId !== $this->player->getId()){ + if($packet->actorRuntimeId !== $this->player->getId()){ //TODO HACK: EATING_ITEM is sent back to the server when the server sends it for other players (1.14 bug, maybe earlier) - return $packet->event === ActorEventPacket::EATING_ITEM; + return $packet->actorRuntimeId === ActorEventPacket::EATING_ITEM; } $this->player->doCloseInventory(); - switch($packet->event){ + switch($packet->eventId){ case ActorEventPacket::EATING_ITEM: //TODO: ignore this and handle it server-side $item = $this->player->getInventory()->getItemInHand(); if($item->isNull()){ @@ -356,12 +356,12 @@ class InGamePacketHandler extends PacketHandler{ switch($data->getActionType()){ case UseItemTransactionData::ACTION_CLICK_BLOCK: //TODO: start hack for client spam bug - $clickPos = $data->getClickPos(); + $clickPos = $data->getClickPosition(); $spamBug = ($this->lastRightClickData !== null and microtime(true) - $this->lastRightClickTime < 0.1 and //100ms - $this->lastRightClickData->getPlayerPos()->distanceSquared($data->getPlayerPos()) < 0.00001 and - $this->lastRightClickData->getBlockPos()->equals($data->getBlockPos()) and - $this->lastRightClickData->getClickPos()->distanceSquared($clickPos) < 0.00001 //signature spam bug has 0 distance, but allow some error + $this->lastRightClickData->getPlayerPosition()->distanceSquared($data->getPlayerPosition()) < 0.00001 and + $this->lastRightClickData->getBlockPosition()->equals($data->getBlockPosition()) and + $this->lastRightClickData->getClickPosition()->distanceSquared($clickPos) < 0.00001 //signature spam bug has 0 distance, but allow some error ); //get rid of continued spam if the player clicks and holds right-click $this->lastRightClickData = $data; @@ -371,9 +371,10 @@ class InGamePacketHandler extends PacketHandler{ } //TODO: end hack for client spam bug - $blockPos = $data->getBlockPos(); - if(!$this->player->interactBlock($blockPos, $data->getFace(), $clickPos)){ - $this->onFailedBlockAction($blockPos, $data->getFace()); + $blockPos = $data->getBlockPosition(); + $vBlockPos = new Vector3($blockPos->getX(), $blockPos->getY(), $blockPos->getZ()); + if(!$this->player->interactBlock($vBlockPos, $data->getFace(), $clickPos)){ + $this->onFailedBlockAction($vBlockPos, $data->getFace()); }elseif( !array_key_exists($windowId = InventoryManager::HARDCODED_CRAFTING_GRID_WINDOW_ID, $this->openHardcodedWindows) && $this->player->getCraftingGrid()->getGridWidth() === CraftingGrid::SIZE_BIG @@ -381,7 +382,7 @@ class InGamePacketHandler extends PacketHandler{ //TODO: HACK! crafting grid doesn't fit very well into the current PM container system, so this hack //allows it to carry on working approximately the same way as it did in 1.14 $this->openHardcodedWindows[$windowId] = true; - $this->session->sendDataPacket(ContainerOpenPacket::blockInvVec3( + $this->session->sendDataPacket(ContainerOpenPacket::blockInv( InventoryManager::HARDCODED_CRAFTING_GRID_WINDOW_ID, WindowTypes::WORKBENCH, $blockPos @@ -389,9 +390,10 @@ class InGamePacketHandler extends PacketHandler{ } return true; case UseItemTransactionData::ACTION_BREAK_BLOCK: - $blockPos = $data->getBlockPos(); - if(!$this->player->breakBlock($blockPos)){ - $this->onFailedBlockAction($blockPos, null); + $blockPos = $data->getBlockPosition(); + $vBlockPos = new Vector3($blockPos->getX(), $blockPos->getY(), $blockPos->getZ()); + if(!$this->player->breakBlock($vBlockPos)){ + $this->onFailedBlockAction($vBlockPos, null); } return true; case UseItemTransactionData::ACTION_CLICK_AIR: @@ -432,7 +434,7 @@ class InGamePacketHandler extends PacketHandler{ } private function handleUseItemOnEntityTransaction(UseItemOnEntityTransactionData $data) : bool{ - $target = $this->player->getWorld()->getEntity($data->getEntityRuntimeId()); + $target = $this->player->getWorld()->getEntity($data->getActorRuntimeId()); if($target === null){ return false; } @@ -442,7 +444,7 @@ class InGamePacketHandler extends PacketHandler{ //TODO: use transactiondata for rollbacks here switch($data->getActionType()){ case UseItemOnEntityTransactionData::ACTION_INTERACT: - if(!$this->player->interactEntity($target, $data->getClickPos())){ + if(!$this->player->interactEntity($target, $data->getClickPosition())){ $this->inventoryManager->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex()); } return true; @@ -498,7 +500,7 @@ class InGamePacketHandler extends PacketHandler{ //TODO: implement handling for this where it matters return true; } - $target = $this->player->getWorld()->getEntity($packet->target); + $target = $this->player->getWorld()->getEntity($packet->targetActorRuntimeId); if($target === null){ return false; } @@ -521,7 +523,7 @@ class InGamePacketHandler extends PacketHandler{ } public function handleBlockPickRequest(BlockPickRequestPacket $packet) : bool{ - return $this->player->pickBlock(new Vector3($packet->blockX, $packet->blockY, $packet->blockZ), $packet->addUserData); + return $this->player->pickBlock(new Vector3($packet->blockPosition->getX(), $packet->blockPosition->getY(), $packet->blockPosition->getZ()), $packet->addUserData); } public function handleActorPickRequest(ActorPickRequestPacket $packet) : bool{ @@ -529,7 +531,7 @@ class InGamePacketHandler extends PacketHandler{ } public function handlePlayerAction(PlayerActionPacket $packet) : bool{ - $pos = new Vector3($packet->x, $packet->y, $packet->z); + $pos = new Vector3($packet->blockPosition->getX(), $packet->blockPosition->getY(), $packet->blockPosition->getZ()); switch($packet->action){ case PlayerActionPacket::ACTION_START_BREAK: @@ -628,7 +630,7 @@ class InGamePacketHandler extends PacketHandler{ } public function handleAdventureSettings(AdventureSettingsPacket $packet) : bool{ - if($packet->entityUniqueId !== $this->player->getId()){ + if($packet->targetActorUniqueId !== $this->player->getId()){ return false; //TODO: operators can change other people's permissions using this } @@ -648,13 +650,13 @@ class InGamePacketHandler extends PacketHandler{ } public function handleBlockActorData(BlockActorDataPacket $packet) : bool{ - $pos = new Vector3($packet->x, $packet->y, $packet->z); + $pos = new Vector3($packet->blockPosition->getX(), $packet->blockPosition->getY(), $packet->blockPosition->getZ()); if($pos->distanceSquared($this->player->getLocation()) > 10000){ return false; } $block = $this->player->getLocation()->getWorld()->getBlock($pos); - $nbt = $packet->namedtag->getRoot(); + $nbt = $packet->nbt->getRoot(); if(!($nbt instanceof CompoundTag)) throw new AssumptionFailedError("PHPStan should ensure this is a CompoundTag"); //for phpstorm's benefit if($block instanceof BaseSign){ @@ -678,7 +680,7 @@ class InGamePacketHandler extends PacketHandler{ return true; } - $this->session->getLogger()->debug("Invalid sign update data: " . base64_encode($packet->namedtag->getEncodedNbt())); + $this->session->getLogger()->debug("Invalid sign update data: " . base64_encode($packet->nbt->getEncodedNbt())); } return false; @@ -712,9 +714,10 @@ class InGamePacketHandler extends PacketHandler{ } public function handleItemFrameDropItem(ItemFrameDropItemPacket $packet) : bool{ - $block = $this->player->getWorld()->getBlockAt($packet->x, $packet->y, $packet->z); + $blockPosition = $packet->blockPosition; + $block = $this->player->getWorld()->getBlockAt($blockPosition->getX(), $blockPosition->getY(), $blockPosition->getZ()); if($block instanceof ItemFrame and $block->getFramedItem() !== null){ - return $this->player->attackBlock(new Vector3($packet->x, $packet->y, $packet->z), $block->getFacing()); + return $this->player->attackBlock(new Vector3($blockPosition->getX(), $blockPosition->getY(), $blockPosition->getZ()), $block->getFacing()); } return false; } diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index 59d204d68f..6d2091065f 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -31,9 +31,11 @@ use pocketmine\network\mcpe\InventoryManager; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket; use pocketmine\network\mcpe\protocol\StartGamePacket; +use pocketmine\network\mcpe\protocol\types\BlockPosition; use pocketmine\network\mcpe\protocol\types\BoolGameRule; use pocketmine\network\mcpe\protocol\types\DimensionIds; use pocketmine\network\mcpe\protocol\types\Experiments; +use pocketmine\network\mcpe\protocol\types\LevelSettings; use pocketmine\network\mcpe\protocol\types\PlayerMovementSettings; use pocketmine\network\mcpe\protocol\types\PlayerMovementType; use pocketmine\network\mcpe\protocol\types\SpawnSettings; @@ -64,39 +66,46 @@ class PreSpawnPacketHandler extends PacketHandler{ } public function setUp() : void{ - $spawnPosition = $this->player->getSpawn(); $location = $this->player->getLocation(); - $pk = new StartGamePacket(); - $pk->entityUniqueId = $this->player->getId(); - $pk->entityRuntimeId = $this->player->getId(); - $pk->playerGamemode = TypeConverter::getInstance()->coreGameModeToProtocol($this->player->getGamemode()); - $pk->playerPosition = $this->player->getOffsetPosition($location); - $pk->pitch = $location->pitch; - $pk->yaw = $location->yaw; - $pk->seed = -1; - $pk->spawnSettings = new SpawnSettings(SpawnSettings::BIOME_TYPE_DEFAULT, "", DimensionIds::OVERWORLD); //TODO: implement this properly - $pk->worldGamemode = TypeConverter::getInstance()->coreGameModeToProtocol($this->server->getGamemode()); - $pk->difficulty = $location->getWorld()->getDifficulty(); - $pk->spawnX = $spawnPosition->getFloorX(); - $pk->spawnY = $spawnPosition->getFloorY(); - $pk->spawnZ = $spawnPosition->getFloorZ(); - $pk->hasAchievementsDisabled = true; - $pk->time = $location->getWorld()->getTime(); - $pk->eduEditionOffer = 0; - $pk->rainLevel = 0; //TODO: implement these properly - $pk->lightningLevel = 0; - $pk->commandsEnabled = true; - $pk->gameRules = [ + $levelSettings = new LevelSettings(); + $levelSettings->seed = -1; + $levelSettings->spawnSettings = new SpawnSettings(SpawnSettings::BIOME_TYPE_DEFAULT, "", DimensionIds::OVERWORLD); //TODO: implement this properly + $levelSettings->worldGamemode = TypeConverter::getInstance()->coreGameModeToProtocol($this->server->getGamemode()); + $levelSettings->difficulty = $location->getWorld()->getDifficulty(); + $levelSettings->spawnPosition = BlockPosition::fromVector3($location->getWorld()->getSpawnLocation()); + $levelSettings->hasAchievementsDisabled = true; + $levelSettings->time = $location->getWorld()->getTime(); + $levelSettings->eduEditionOffer = 0; + $levelSettings->rainLevel = 0; //TODO: implement these properly + $levelSettings->lightningLevel = 0; + $levelSettings->commandsEnabled = true; + $levelSettings->gameRules = [ "naturalregeneration" => new BoolGameRule(false, false) //Hack for client side regeneration ]; - $pk->experiments = new Experiments([], false); - $pk->levelId = ""; - $pk->worldName = $this->server->getMotd(); - $pk->itemTable = GlobalItemTypeDictionary::getInstance()->getDictionary()->getEntries(); //TODO: check if this is actually needed - $pk->playerMovementSettings = new PlayerMovementSettings(PlayerMovementType::LEGACY, 0, false); - $pk->serverSoftwareVersion = sprintf("%s %s", VersionInfo::NAME, VersionInfo::VERSION()->getFullVersion(true)); - $this->session->sendDataPacket($pk); + $levelSettings->experiments = new Experiments([], false); + + $this->session->sendDataPacket(StartGamePacket::create( + $this->player->getId(), + $this->player->getId(), + TypeConverter::getInstance()->coreGameModeToProtocol($this->player->getGamemode()), + $this->player->getOffsetPosition($location), + $location->pitch, + $location->yaw, + $levelSettings, + "", + $this->server->getMotd(), + "", + false, + new PlayerMovementSettings(PlayerMovementType::LEGACY, 0, false), + 0, + 0, + "", + false, + sprintf("%s %s", VersionInfo::NAME, VersionInfo::VERSION()->getFullVersion(true)), + [], + GlobalItemTypeDictionary::getInstance()->getDictionary()->getEntries() + )); $this->session->sendDataPacket(StaticPacketCache::getInstance()->getAvailableActorIdentifiers()); $this->session->sendDataPacket(StaticPacketCache::getInstance()->getBiomeDefs()); diff --git a/src/network/mcpe/handler/ResourcePacksPacketHandler.php b/src/network/mcpe/handler/ResourcePacksPacketHandler.php index 5b6d1d7a58..8f93e25477 100644 --- a/src/network/mcpe/handler/ResourcePacksPacketHandler.php +++ b/src/network/mcpe/handler/ResourcePacksPacketHandler.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe\handler; use pocketmine\lang\KnownTranslationKeys; use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\ResourcePackChunkDataPacket; use pocketmine\network\mcpe\protocol\ResourcePackChunkRequestPacket; use pocketmine\network\mcpe\protocol\ResourcePackClientResponsePacket; @@ -34,6 +35,7 @@ use pocketmine\network\mcpe\protocol\ResourcePackStackPacket; use pocketmine\network\mcpe\protocol\types\Experiments; use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackInfoEntry; use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackStackEntry; +use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackType; use pocketmine\resourcepacks\ResourcePack; use pocketmine\resourcepacks\ResourcePackManager; use function array_map; @@ -113,7 +115,9 @@ class ResourcePacksPacketHandler extends PacketHandler{ self::PACK_CHUNK_SIZE, (int) ceil($pack->getPackSize() / self::PACK_CHUNK_SIZE), $pack->getPackSize(), - $pack->getSha256() + $pack->getSha256(), + false, + ResourcePackType::ADDON //TODO: this might be an addon (not behaviour pack), needed to properly support client-side custom items )); } $this->session->getLogger()->debug("Player requested download of " . count($packet->packIds) . " resource packs"); @@ -130,7 +134,7 @@ class ResourcePacksPacketHandler extends PacketHandler{ //we don't force here, because it doesn't have user-facing effects //but it does have an annoying side-effect when true: it makes //the client remove its own non-server-supplied resource packs. - $this->session->sendDataPacket(ResourcePackStackPacket::create($stack, [], false, new Experiments([], false))); + $this->session->sendDataPacket(ResourcePackStackPacket::create($stack, [], false, ProtocolInfo::MINECRAFT_VERSION_NETWORK, new Experiments([], false))); $this->session->getLogger()->debug("Applying resource pack stack"); break; case ResourcePackClientResponsePacket::STATUS_COMPLETED: diff --git a/src/player/Player.php b/src/player/Player.php index bd7222af02..10265f466f 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -97,6 +97,7 @@ use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\AnimatePacket; use pocketmine\network\mcpe\protocol\MovePlayerPacket; use pocketmine\network\mcpe\protocol\SetActorMotionPacket; +use pocketmine\network\mcpe\protocol\types\BlockPosition; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; @@ -2183,7 +2184,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $properties->setGenericFlag(EntityMetadataFlags::ACTION, $this->startAction > -1); $properties->setPlayerFlag(PlayerMetadataFlags::SLEEP, $this->sleeping !== null); - $properties->setBlockPos(EntityMetadataProperties::PLAYER_BED_POSITION, $this->sleeping ?? new Vector3(0, 0, 0)); + $properties->setBlockPos(EntityMetadataProperties::PLAYER_BED_POSITION, $this->sleeping !== null ? BlockPosition::fromVector3($this->sleeping) : new BlockPosition(0, 0, 0)); } public function sendData(?array $targets, ?array $data = null) : void{ diff --git a/src/world/World.php b/src/world/World.php index f85320e34c..282767e768 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -63,6 +63,7 @@ use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\BlockActorDataPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; +use pocketmine\network\mcpe\protocol\types\BlockPosition; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; use pocketmine\player\Player; use pocketmine\scheduler\AsyncPool; @@ -952,11 +953,17 @@ class World implements ChunkManager{ } $fullBlock = $this->getBlockAt($b->x, $b->y, $b->z); - $packets[] = UpdateBlockPacket::create($b->x, $b->y, $b->z, RuntimeBlockMapping::getInstance()->toRuntimeId($fullBlock->getFullId())); + $blockPosition = BlockPosition::fromVector3($b); + $packets[] = UpdateBlockPacket::create( + $blockPosition, + RuntimeBlockMapping::getInstance()->toRuntimeId($fullBlock->getFullId()), + UpdateBlockPacket::FLAG_NETWORK, + UpdateBlockPacket::DATA_LAYER_NORMAL + ); $tile = $this->getTileAt($b->x, $b->y, $b->z); if($tile instanceof Spawnable){ - $packets[] = BlockActorDataPacket::create($b->x, $b->y, $b->z, $tile->getSerializedSpawnCompound()); + $packets[] = BlockActorDataPacket::create($blockPosition, $tile->getSerializedSpawnCompound()); } } diff --git a/src/world/particle/FloatingTextParticle.php b/src/world/particle/FloatingTextParticle.php index fd7e14f0ce..bac0759751 100644 --- a/src/world/particle/FloatingTextParticle.php +++ b/src/world/particle/FloatingTextParticle.php @@ -99,7 +99,7 @@ class FloatingTextParticle implements Particle{ $pk = new AddPlayerPacket(); $pk->uuid = $uuid; $pk->username = $name; - $pk->entityRuntimeId = $this->entityId; + $pk->actorRuntimeId = $this->entityId; $pk->position = $pos; //TODO: check offset $pk->item = ItemStackWrapper::legacy(ItemStack::null()); diff --git a/src/world/sound/ArrowHitSound.php b/src/world/sound/ArrowHitSound.php index 1927b0c2cf..cb89dbc51c 100644 --- a/src/world/sound/ArrowHitSound.php +++ b/src/world/sound/ArrowHitSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ArrowHitSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BOW_HIT, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BOW_HIT, $pos, false)]; } } diff --git a/src/world/sound/BarrelCloseSound.php b/src/world/sound/BarrelCloseSound.php index a493305117..6adb76093d 100644 --- a/src/world/sound/BarrelCloseSound.php +++ b/src/world/sound/BarrelCloseSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BarrelCloseSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BLOCK_BARREL_CLOSE, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BLOCK_BARREL_CLOSE, $pos, false)]; } } diff --git a/src/world/sound/BarrelOpenSound.php b/src/world/sound/BarrelOpenSound.php index 7e77ef2c3c..04edd73658 100644 --- a/src/world/sound/BarrelOpenSound.php +++ b/src/world/sound/BarrelOpenSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BarrelOpenSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BLOCK_BARREL_OPEN, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BLOCK_BARREL_OPEN, $pos, false)]; } } diff --git a/src/world/sound/BellRingSound.php b/src/world/sound/BellRingSound.php index c6ee1cffbd..af96e7f09e 100644 --- a/src/world/sound/BellRingSound.php +++ b/src/world/sound/BellRingSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; final class BellRingSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BLOCK_BELL_HIT, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BLOCK_BELL_HIT, $pos, false)]; } } diff --git a/src/world/sound/BlockBreakSound.php b/src/world/sound/BlockBreakSound.php index b5c9a11b91..041664cc84 100644 --- a/src/world/sound/BlockBreakSound.php +++ b/src/world/sound/BlockBreakSound.php @@ -38,6 +38,6 @@ class BlockBreakSound implements Sound{ } public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BREAK, $pos, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()))]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BREAK, $pos, false, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()))]; } } diff --git a/src/world/sound/BlockPlaceSound.php b/src/world/sound/BlockPlaceSound.php index 8635588b4b..0c89674690 100644 --- a/src/world/sound/BlockPlaceSound.php +++ b/src/world/sound/BlockPlaceSound.php @@ -38,6 +38,6 @@ class BlockPlaceSound implements Sound{ } public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_PLACE, $pos, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()))]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_PLACE, $pos, false, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()))]; } } diff --git a/src/world/sound/BlockPunchSound.php b/src/world/sound/BlockPunchSound.php index 0637c4133b..009e1a7543 100644 --- a/src/world/sound/BlockPunchSound.php +++ b/src/world/sound/BlockPunchSound.php @@ -41,9 +41,10 @@ class BlockPunchSound implements Sound{ } public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create( + return [LevelSoundEventPacket::nonActorSound( LevelSoundEventPacket::SOUND_HIT, $pos, + false, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()) )]; } diff --git a/src/world/sound/BowShootSound.php b/src/world/sound/BowShootSound.php index 09f644bfb1..22b65cac6e 100644 --- a/src/world/sound/BowShootSound.php +++ b/src/world/sound/BowShootSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BowShootSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BOW, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BOW, $pos, false)]; } } diff --git a/src/world/sound/BucketEmptyLavaSound.php b/src/world/sound/BucketEmptyLavaSound.php index 2764cc8239..d0f66e7c17 100644 --- a/src/world/sound/BucketEmptyLavaSound.php +++ b/src/world/sound/BucketEmptyLavaSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BucketEmptyLavaSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BUCKET_EMPTY_LAVA, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BUCKET_EMPTY_LAVA, $pos, false)]; } } diff --git a/src/world/sound/BucketEmptyWaterSound.php b/src/world/sound/BucketEmptyWaterSound.php index b3b847721c..af4dec6e29 100644 --- a/src/world/sound/BucketEmptyWaterSound.php +++ b/src/world/sound/BucketEmptyWaterSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BucketEmptyWaterSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BUCKET_EMPTY_WATER, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BUCKET_EMPTY_WATER, $pos, false)]; } } diff --git a/src/world/sound/BucketFillLavaSound.php b/src/world/sound/BucketFillLavaSound.php index c8dbba3008..01d4edb095 100644 --- a/src/world/sound/BucketFillLavaSound.php +++ b/src/world/sound/BucketFillLavaSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BucketFillLavaSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BUCKET_FILL_LAVA, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BUCKET_FILL_LAVA, $pos, false)]; } } diff --git a/src/world/sound/BucketFillWaterSound.php b/src/world/sound/BucketFillWaterSound.php index 0661a5da03..cdb126c7ce 100644 --- a/src/world/sound/BucketFillWaterSound.php +++ b/src/world/sound/BucketFillWaterSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BucketFillWaterSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BUCKET_FILL_WATER, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BUCKET_FILL_WATER, $pos, false)]; } } diff --git a/src/world/sound/ChestCloseSound.php b/src/world/sound/ChestCloseSound.php index 744305b1bd..1738ed81fb 100644 --- a/src/world/sound/ChestCloseSound.php +++ b/src/world/sound/ChestCloseSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ChestCloseSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_CHEST_CLOSED, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_CHEST_CLOSED, $pos, false)]; } } diff --git a/src/world/sound/ChestOpenSound.php b/src/world/sound/ChestOpenSound.php index 86a7ea8fc5..dd7bb6a14b 100644 --- a/src/world/sound/ChestOpenSound.php +++ b/src/world/sound/ChestOpenSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ChestOpenSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_CHEST_OPEN, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_CHEST_OPEN, $pos, false)]; } } diff --git a/src/world/sound/EnderChestCloseSound.php b/src/world/sound/EnderChestCloseSound.php index 07073b523b..d016a3ae54 100644 --- a/src/world/sound/EnderChestCloseSound.php +++ b/src/world/sound/EnderChestCloseSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class EnderChestCloseSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_ENDERCHEST_CLOSED, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_ENDERCHEST_CLOSED, $pos, false)]; } } diff --git a/src/world/sound/EnderChestOpenSound.php b/src/world/sound/EnderChestOpenSound.php index 17e6fef9bb..b2a664dd31 100644 --- a/src/world/sound/EnderChestOpenSound.php +++ b/src/world/sound/EnderChestOpenSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class EnderChestOpenSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_ENDERCHEST_OPEN, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_ENDERCHEST_OPEN, $pos, false)]; } } diff --git a/src/world/sound/EntityAttackNoDamageSound.php b/src/world/sound/EntityAttackNoDamageSound.php index edd39483cc..0b2fb0cffd 100644 --- a/src/world/sound/EntityAttackNoDamageSound.php +++ b/src/world/sound/EntityAttackNoDamageSound.php @@ -36,7 +36,9 @@ class EntityAttackNoDamageSound implements Sound{ LevelSoundEventPacket::SOUND_ATTACK_NODAMAGE, $pos, -1, - "minecraft:player" + "minecraft:player", + false, + false )]; } } diff --git a/src/world/sound/EntityAttackSound.php b/src/world/sound/EntityAttackSound.php index 04b461f491..d7fd63b7b3 100644 --- a/src/world/sound/EntityAttackSound.php +++ b/src/world/sound/EntityAttackSound.php @@ -36,7 +36,9 @@ class EntityAttackSound implements Sound{ LevelSoundEventPacket::SOUND_ATTACK_STRONG, //TODO: seems like ATTACK is dysfunctional $pos, -1, - "minecraft:player" + "minecraft:player", + false, + false )]; } } diff --git a/src/world/sound/EntityLandSound.php b/src/world/sound/EntityLandSound.php index 983c0d2e61..7871082bb0 100644 --- a/src/world/sound/EntityLandSound.php +++ b/src/world/sound/EntityLandSound.php @@ -49,8 +49,9 @@ class EntityLandSound implements Sound{ LevelSoundEventPacket::SOUND_LAND, $pos, RuntimeBlockMapping::getInstance()->toRuntimeId($this->blockLandedOn->getFullId()), - $this->entity::getNetworkTypeId() - //TODO: does isBaby have any relevance here? + $this->entity::getNetworkTypeId(), + false, //TODO: does isBaby have any relevance here? + false )]; } } diff --git a/src/world/sound/EntityLongFallSound.php b/src/world/sound/EntityLongFallSound.php index 2e95b9e8cf..88246f8469 100644 --- a/src/world/sound/EntityLongFallSound.php +++ b/src/world/sound/EntityLongFallSound.php @@ -45,8 +45,9 @@ class EntityLongFallSound implements Sound{ LevelSoundEventPacket::SOUND_FALL_BIG, $pos, -1, - $this->entity::getNetworkTypeId() - //TODO: is isBaby relevant here? + $this->entity::getNetworkTypeId(), + false, //TODO: is isBaby relevant here? + false )]; } } diff --git a/src/world/sound/EntityShortFallSound.php b/src/world/sound/EntityShortFallSound.php index de16c58b0c..fcacd797ee 100644 --- a/src/world/sound/EntityShortFallSound.php +++ b/src/world/sound/EntityShortFallSound.php @@ -44,8 +44,9 @@ class EntityShortFallSound implements Sound{ LevelSoundEventPacket::SOUND_FALL_SMALL, $pos, -1, - $this->entity::getNetworkTypeId() - //TODO: does isBaby have any relevance here? + $this->entity::getNetworkTypeId(), + false, //TODO: does isBaby have any relevance here? + false )]; } } diff --git a/src/world/sound/ExplodeSound.php b/src/world/sound/ExplodeSound.php index 86ed9b3420..9dfcd19f84 100644 --- a/src/world/sound/ExplodeSound.php +++ b/src/world/sound/ExplodeSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ExplodeSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_EXPLODE, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_EXPLODE, $pos, false)]; } } diff --git a/src/world/sound/FireExtinguishSound.php b/src/world/sound/FireExtinguishSound.php index 0c0707911b..e9f7e30976 100644 --- a/src/world/sound/FireExtinguishSound.php +++ b/src/world/sound/FireExtinguishSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; final class FireExtinguishSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_EXTINGUISH_FIRE, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_EXTINGUISH_FIRE, $pos, false)]; } } diff --git a/src/world/sound/FlintSteelSound.php b/src/world/sound/FlintSteelSound.php index 1852169593..15ff96a281 100644 --- a/src/world/sound/FlintSteelSound.php +++ b/src/world/sound/FlintSteelSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class FlintSteelSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_IGNITE, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_IGNITE, $pos, false)]; } } diff --git a/src/world/sound/ItemBreakSound.php b/src/world/sound/ItemBreakSound.php index fbe9aef778..0b7f07435d 100644 --- a/src/world/sound/ItemBreakSound.php +++ b/src/world/sound/ItemBreakSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ItemBreakSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_BREAK, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BREAK, $pos, false)]; } } diff --git a/src/world/sound/NoteSound.php b/src/world/sound/NoteSound.php index 70228021ea..e84c736b07 100644 --- a/src/world/sound/NoteSound.php +++ b/src/world/sound/NoteSound.php @@ -42,6 +42,6 @@ class NoteSound implements Sound{ } public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_NOTE, $pos, ($this->instrument->getMagicNumber() << 8) | $this->note)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_NOTE, $pos, false, ($this->instrument->getMagicNumber() << 8) | $this->note)]; } } diff --git a/src/world/sound/PotionSplashSound.php b/src/world/sound/PotionSplashSound.php index 96a2f6ead9..efde99b258 100644 --- a/src/world/sound/PotionSplashSound.php +++ b/src/world/sound/PotionSplashSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class PotionSplashSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_GLASS, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_GLASS, $pos, false)]; } } diff --git a/src/world/sound/RecordSound.php b/src/world/sound/RecordSound.php index 9f8bb15d14..99e781db98 100644 --- a/src/world/sound/RecordSound.php +++ b/src/world/sound/RecordSound.php @@ -37,6 +37,6 @@ class RecordSound implements Sound{ } public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create($this->recordType->getSoundId(), $pos)]; + return [LevelSoundEventPacket::nonActorSound($this->recordType->getSoundId(), $pos, false)]; } } diff --git a/src/world/sound/RecordStopSound.php b/src/world/sound/RecordStopSound.php index ccb139f828..2bdd0e6119 100644 --- a/src/world/sound/RecordStopSound.php +++ b/src/world/sound/RecordStopSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class RecordStopSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_STOP_RECORD, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_STOP_RECORD, $pos, false)]; } } diff --git a/src/world/sound/RedstonePowerOffSound.php b/src/world/sound/RedstonePowerOffSound.php index d1363ed544..5f0ec72809 100644 --- a/src/world/sound/RedstonePowerOffSound.php +++ b/src/world/sound/RedstonePowerOffSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class RedstonePowerOffSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_POWER_OFF, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_POWER_OFF, $pos, false)]; } } diff --git a/src/world/sound/RedstonePowerOnSound.php b/src/world/sound/RedstonePowerOnSound.php index eaea5f6173..e260d11669 100644 --- a/src/world/sound/RedstonePowerOnSound.php +++ b/src/world/sound/RedstonePowerOnSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class RedstonePowerOnSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_POWER_ON, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_POWER_ON, $pos, false)]; } } diff --git a/src/world/sound/ShulkerBoxCloseSound.php b/src/world/sound/ShulkerBoxCloseSound.php index cb170aab65..2e8e758a4d 100644 --- a/src/world/sound/ShulkerBoxCloseSound.php +++ b/src/world/sound/ShulkerBoxCloseSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ShulkerBoxCloseSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_SHULKERBOX_CLOSED, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_SHULKERBOX_CLOSED, $pos, false)]; } } diff --git a/src/world/sound/ShulkerBoxOpenSound.php b/src/world/sound/ShulkerBoxOpenSound.php index fd75b2f82f..a5dacea087 100644 --- a/src/world/sound/ShulkerBoxOpenSound.php +++ b/src/world/sound/ShulkerBoxOpenSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ShulkerBoxOpenSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_SHULKERBOX_OPEN, $pos)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_SHULKERBOX_OPEN, $pos, false)]; } } diff --git a/src/world/sound/ThrowSound.php b/src/world/sound/ThrowSound.php index 65c5079aff..1e3297a657 100644 --- a/src/world/sound/ThrowSound.php +++ b/src/world/sound/ThrowSound.php @@ -29,6 +29,6 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ThrowSound implements Sound{ public function encode(?Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_THROW, $pos, -1, "minecraft:player")]; + return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_THROW, $pos, -1, "minecraft:player", false, false)]; } } diff --git a/src/world/sound/XpLevelUpSound.php b/src/world/sound/XpLevelUpSound.php index abc41fef74..aa44a5ff69 100644 --- a/src/world/sound/XpLevelUpSound.php +++ b/src/world/sound/XpLevelUpSound.php @@ -44,6 +44,6 @@ class XpLevelUpSound implements Sound{ public function encode(?Vector3 $pos) : array{ //No idea why such odd numbers, but this works... //TODO: check arbitrary volume - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_LEVELUP, $pos, 0x10000000 * intdiv(min(30, $this->xpLevel), 5))]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_LEVELUP, $pos, false, 0x10000000 * intdiv(min(30, $this->xpLevel), 5))]; } } From c77829f4adee4d5fe61829823f4dbad545c100e9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Oct 2021 01:46:01 +0100 Subject: [PATCH 3008/3224] Migrate packet creation to use ::create() methods in all but one case MovePlayerPacket doesn't yet have a ::create() due to a complication with fields that aren't always present. --- src/entity/Entity.php | 29 ++++++++-------- src/entity/Human.php | 31 +++++++++++------ src/entity/object/ItemEntity.php | 17 +++++----- src/entity/object/Painting.php | 22 ++++++------ src/network/mcpe/NetworkSession.php | 23 +++++++------ src/network/mcpe/cache/CraftingDataCache.php | 11 +++--- src/world/particle/FloatingTextParticle.php | 35 +++++++++++++------- 7 files changed, 96 insertions(+), 72 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index ceb5a97b1e..6289a896bf 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1418,20 +1418,21 @@ abstract class Entity{ * Called by spawnTo() to send whatever packets needed to spawn the entity to the client. */ protected function sendSpawnPacket(Player $player) : void{ - $pk = new AddActorPacket(); - $pk->actorRuntimeId = $this->getId(); - $pk->type = static::getNetworkTypeId(); - $pk->position = $this->location->asVector3(); - $pk->motion = $this->getMotion(); - $pk->yaw = $this->location->yaw; - $pk->headYaw = $this->location->yaw; //TODO - $pk->pitch = $this->location->pitch; - $pk->attributes = array_map(function(Attribute $attr) : NetworkAttribute{ - return new NetworkAttribute($attr->getId(), $attr->getMinValue(), $attr->getMaxValue(), $attr->getValue(), $attr->getDefaultValue()); - }, $this->attributeMap->getAll()); - $pk->metadata = $this->getAllNetworkData(); - - $player->getNetworkSession()->sendDataPacket($pk); + $player->getNetworkSession()->sendDataPacket(AddActorPacket::create( + $this->getId(), //TODO: actor unique ID + $this->getId(), + static::getNetworkTypeId(), + $this->location->asVector3(), + $this->getMotion(), + $this->location->pitch, + $this->location->yaw, + $this->location->yaw, //TODO: head yaw + array_map(function(Attribute $attr) : NetworkAttribute{ + return new NetworkAttribute($attr->getId(), $attr->getMinValue(), $attr->getMaxValue(), $attr->getValue(), $attr->getDefaultValue()); + }, $this->attributeMap->getAll()), + $this->getAllNetworkData(), + [] //TODO: entity links + )); } public function spawnTo(Player $player) : void{ diff --git a/src/entity/Human.php b/src/entity/Human.php index c953ffb471..c77de50056 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -47,8 +47,10 @@ use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\convert\SkinAdapterSingleton; use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\protocol\AddPlayerPacket; +use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\PlayerSkinPacket; +use pocketmine\network\mcpe\protocol\types\DeviceOS; use pocketmine\network\mcpe\protocol\types\entity\EntityIds; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\entity\StringMetadataProperty; @@ -444,17 +446,24 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ $player->getNetworkSession()->sendDataPacket(PlayerListPacket::add([PlayerListEntry::createAdditionEntry($this->uuid, $this->id, $this->getName(), SkinAdapterSingleton::get()->toSkinData($this->skin))])); } - $pk = new AddPlayerPacket(); - $pk->uuid = $this->getUniqueId(); - $pk->username = $this->getName(); - $pk->actorRuntimeId = $this->getId(); - $pk->position = $this->location->asVector3(); - $pk->motion = $this->getMotion(); - $pk->yaw = $this->location->yaw; - $pk->pitch = $this->location->pitch; - $pk->item = ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($this->getInventory()->getItemInHand())); - $pk->metadata = $this->getAllNetworkData(); - $player->getNetworkSession()->sendDataPacket($pk); + $player->getNetworkSession()->sendDataPacket(AddPlayerPacket::create( + $this->getUniqueId(), + $this->getName(), + $this->getId(), //TODO: actor unique ID + $this->getId(), + "", + $this->location->asVector3(), + $this->getMotion(), + $this->location->pitch, + $this->location->yaw, + $this->location->yaw, //TODO: head yaw + ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($this->getInventory()->getItemInHand())), + $this->getAllNetworkData(), + AdventureSettingsPacket::create(0, 0, 0, 0, 0, $this->getId()), //TODO + [], //TODO: entity links + "", //device ID (we intentionally don't send this - secvuln) + DeviceOS::UNKNOWN //we intentionally don't send this (secvuln) + )); //TODO: Hack for MCPE 1.2.13: DATA_NAMETAG is useless in AddPlayerPacket, so it has to be sent separately $this->sendData([$player], [EntityMetadataProperties::NAMETAG => new StringMetadataProperty($this->getNameTag())]); diff --git a/src/entity/object/ItemEntity.php b/src/entity/object/ItemEntity.php index e9c71c6c2b..899cbc279c 100644 --- a/src/entity/object/ItemEntity.php +++ b/src/entity/object/ItemEntity.php @@ -206,14 +206,15 @@ class ItemEntity extends Entity{ } protected function sendSpawnPacket(Player $player) : void{ - $pk = new AddItemActorPacket(); - $pk->actorRuntimeId = $this->getId(); - $pk->position = $this->location->asVector3(); - $pk->motion = $this->getMotion(); - $pk->item = ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($this->getItem())); - $pk->metadata = $this->getAllNetworkData(); - - $player->getNetworkSession()->sendDataPacket($pk); + $player->getNetworkSession()->sendDataPacket(AddItemActorPacket::create( + $this->getId(), //TODO: entity unique ID + $this->getId(), + ItemStackWrapper::legacy(TypeConverter::getInstance()->coreItemStackToNet($this->getItem())), + $this->location->asVector3(), + $this->getMotion(), + $this->getAllNetworkData(), + false //TODO: I have no idea what this is needed for, but right now we don't support fishing anyway + )); } public function getOffsetPosition(Vector3 $vector3) : Vector3{ diff --git a/src/entity/object/Painting.php b/src/entity/object/Painting.php index fa031cb982..a95560e243 100644 --- a/src/entity/object/Painting.php +++ b/src/entity/object/Painting.php @@ -149,17 +149,17 @@ class Painting extends Entity{ } protected function sendSpawnPacket(Player $player) : void{ - $pk = new AddPaintingPacket(); - $pk->actorRuntimeId = $this->getId(); - $pk->position = new Vector3( - ($this->boundingBox->minX + $this->boundingBox->maxX) / 2, - ($this->boundingBox->minY + $this->boundingBox->maxY) / 2, - ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2 - ); - $pk->direction = self::FACING_TO_DATA[$this->facing]; - $pk->title = $this->motive->getName(); - - $player->getNetworkSession()->sendDataPacket($pk); + $player->getNetworkSession()->sendDataPacket(AddPaintingPacket::create( + $this->getId(), //TODO: entity unique ID + $this->getId(), + new Vector3( + ($this->boundingBox->minX + $this->boundingBox->maxX) / 2, + ($this->boundingBox->minY + $this->boundingBox->maxY) / 2, + ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2 + ), + self::FACING_TO_DATA[$this->facing], + $this->motive->getName() + )); } /** diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 720e993494..2ca46db0ee 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -776,7 +776,15 @@ class NetworkSession{ * TODO: make this less specialized */ public function syncAdventureSettings(Player $for) : void{ - $pk = new AdventureSettingsPacket(); + $isOp = $for->hasPermission(DefaultPermissions::ROOT_OPERATOR); + $pk = AdventureSettingsPacket::create( + 0, + $isOp ? AdventureSettingsPacket::PERMISSION_OPERATOR : AdventureSettingsPacket::PERMISSION_NORMAL, + 0, + $isOp ? PlayerPermissions::OPERATOR : PlayerPermissions::MEMBER, + 0, + $for->getId() + ); $pk->setFlag(AdventureSettingsPacket::WORLD_IMMUTABLE, $for->isSpectator()); $pk->setFlag(AdventureSettingsPacket::NO_PVP, $for->isSpectator()); @@ -787,11 +795,6 @@ class NetworkSession{ //TODO: permission flags - $isOp = $for->hasPermission(DefaultPermissions::ROOT_OPERATOR); - $pk->commandPermission = ($isOp ? AdventureSettingsPacket::PERMISSION_OPERATOR : AdventureSettingsPacket::PERMISSION_NORMAL); - $pk->playerPermission = ($isOp ? PlayerPermissions::OPERATOR : PlayerPermissions::MEMBER); - $pk->targetActorUniqueId = $for->getId(); - $this->sendDataPacket($pk); } @@ -828,9 +831,9 @@ class NetworkSession{ } public function syncAvailableCommands() : void{ - $pk = new AvailableCommandsPacket(); + $commandData = []; foreach($this->server->getCommandMap()->getCommands() as $name => $command){ - if(isset($pk->commandData[$command->getName()]) or $command->getName() === "help" or !$command->testPermissionSilent($this->player)){ + if(isset($commandData[$command->getName()]) or $command->getName() === "help" or !$command->testPermissionSilent($this->player)){ continue; } @@ -857,10 +860,10 @@ class NetworkSession{ ] ); - $pk->commandData[$command->getName()] = $data; + $commandData[$command->getName()] = $data; } - $this->sendDataPacket($pk); + $this->sendDataPacket(AvailableCommandsPacket::create($commandData, [], [], [])); } public function onRawChatMessage(string $message) : void{ diff --git a/src/network/mcpe/cache/CraftingDataCache.php b/src/network/mcpe/cache/CraftingDataCache.php index 68414e835c..369a450397 100644 --- a/src/network/mcpe/cache/CraftingDataCache.php +++ b/src/network/mcpe/cache/CraftingDataCache.php @@ -71,15 +71,14 @@ final class CraftingDataCache{ */ private function buildCraftingDataCache(CraftingManager $manager) : CraftingDataPacket{ Timings::$craftingDataCacheRebuild->startTiming(); - $pk = new CraftingDataPacket(); - $pk->cleanRecipes = true; $counter = 0; $nullUUID = Uuid::fromString(Uuid::NIL); $converter = TypeConverter::getInstance(); + $recipesWithTypeIds = []; foreach($manager->getShapelessRecipes() as $list){ foreach($list as $recipe){ - $pk->recipesWithTypeIds[] = new ProtocolShapelessRecipe( + $recipesWithTypeIds[] = new ProtocolShapelessRecipe( CraftingDataPacket::ENTRY_SHAPELESS, Binary::writeInt(++$counter), array_map(function(Item $item) use ($converter) : RecipeIngredient{ @@ -104,7 +103,7 @@ final class CraftingDataCache{ $inputs[$row][$column] = $converter->coreItemStackToRecipeIngredient($recipe->getIngredient($column, $row)); } } - $pk->recipesWithTypeIds[] = $r = new ProtocolShapedRecipe( + $recipesWithTypeIds[] = $r = new ProtocolShapedRecipe( CraftingDataPacket::ENTRY_SHAPED, Binary::writeInt(++$counter), $inputs, @@ -128,7 +127,7 @@ final class CraftingDataCache{ }; foreach($manager->getFurnaceRecipeManager($furnaceType)->getAll() as $recipe){ $input = $converter->coreItemStackToNet($recipe->getInput()); - $pk->recipesWithTypeIds[] = new ProtocolFurnaceRecipe( + $recipesWithTypeIds[] = new ProtocolFurnaceRecipe( CraftingDataPacket::ENTRY_FURNACE_DATA, $input->getId(), $input->getMeta(), @@ -139,6 +138,6 @@ final class CraftingDataCache{ } Timings::$craftingDataCacheRebuild->stopTiming(); - return $pk; + return CraftingDataPacket::create($recipesWithTypeIds, [], [], [], true); } } diff --git a/src/world/particle/FloatingTextParticle.php b/src/world/particle/FloatingTextParticle.php index bac0759751..1fe3ee008e 100644 --- a/src/world/particle/FloatingTextParticle.php +++ b/src/world/particle/FloatingTextParticle.php @@ -28,8 +28,10 @@ use pocketmine\entity\Skin; use pocketmine\math\Vector3; use pocketmine\network\mcpe\convert\SkinAdapterSingleton; use pocketmine\network\mcpe\protocol\AddPlayerPacket; +use pocketmine\network\mcpe\protocol\AdventureSettingsPacket; use pocketmine\network\mcpe\protocol\PlayerListPacket; use pocketmine\network\mcpe\protocol\RemoveActorPacket; +use pocketmine\network\mcpe\protocol\types\DeviceOS; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags; use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties; use pocketmine\network\mcpe\protocol\types\entity\FloatMetadataProperty; @@ -96,22 +98,31 @@ class FloatingTextParticle implements Particle{ $p[] = PlayerListPacket::add([PlayerListEntry::createAdditionEntry($uuid, $this->entityId, $name, SkinAdapterSingleton::get()->toSkinData(new Skin("Standard_Custom", str_repeat("\x00", 8192))))]); - $pk = new AddPlayerPacket(); - $pk->uuid = $uuid; - $pk->username = $name; - $pk->actorRuntimeId = $this->entityId; - $pk->position = $pos; //TODO: check offset - $pk->item = ItemStackWrapper::legacy(ItemStack::null()); - - $flags = ( + $actorFlags = ( 1 << EntityMetadataFlags::IMMOBILE ); - $pk->metadata = [ - EntityMetadataProperties::FLAGS => new LongMetadataProperty($flags), + $actorMetadata = [ + EntityMetadataProperties::FLAGS => new LongMetadataProperty($actorFlags), EntityMetadataProperties::SCALE => new FloatMetadataProperty(0.01) //zero causes problems on debug builds ]; - - $p[] = $pk; + $p[] = AddPlayerPacket::create( + $uuid, + $name, + $this->entityId, //TODO: actor unique ID + $this->entityId, + "", + $pos, //TODO: check offset + null, + 0, + 0, + 0, + ItemStackWrapper::legacy(ItemStack::null()), + $actorMetadata, + AdventureSettingsPacket::create(0, 0, 0, 0, 0, $this->entityId), + [], + "", + DeviceOS::UNKNOWN + ); $p[] = PlayerListPacket::remove([PlayerListEntry::createRemovalEntry($uuid)]); } From e50072dc2756b479ca478aa2c6b12ebe07fbf418 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Oct 2021 01:55:10 +0100 Subject: [PATCH 3009/3224] Clean PHPStan baselines --- tests/phpstan/configs/actual-problems.neon | 5 ---- tests/phpstan/configs/l7-baseline.neon | 30 ---------------------- 2 files changed, 35 deletions(-) diff --git a/tests/phpstan/configs/actual-problems.neon b/tests/phpstan/configs/actual-problems.neon index 312971fa64..ed9a6f9866 100644 --- a/tests/phpstan/configs/actual-problems.neon +++ b/tests/phpstan/configs/actual-problems.neon @@ -1,10 +1,5 @@ parameters: ignoreErrors: - - - message: "#^Instanceof between pocketmine\\\\plugin\\\\PluginManager and pocketmine\\\\plugin\\\\PluginManager will always evaluate to true\\.$#" - count: 1 - path: ../../../src/CrashDump.php - - message: "#^Property pocketmine\\\\event\\\\entity\\\\EntityShootBowEvent\\:\\:\\$projectile \\(pocketmine\\\\entity\\\\projectile\\\\Projectile\\) does not accept pocketmine\\\\entity\\\\Entity\\.$#" count: 1 diff --git a/tests/phpstan/configs/l7-baseline.neon b/tests/phpstan/configs/l7-baseline.neon index 4cd255836a..950cef3e60 100644 --- a/tests/phpstan/configs/l7-baseline.neon +++ b/tests/phpstan/configs/l7-baseline.neon @@ -650,16 +650,6 @@ parameters: count: 3 path: ../../../src/world/World.php - - - message: "#^Parameter \\#1 \\$x of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\BlockActorDataPacket\\:\\:create\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/world/World.php - - - - message: "#^Parameter \\#1 \\$x of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\UpdateBlockPacket\\:\\:create\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/world/World.php - - message: "#^Parameter \\#1 \\$x of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" count: 3 @@ -690,16 +680,6 @@ parameters: count: 3 path: ../../../src/world/World.php - - - message: "#^Parameter \\#2 \\$y of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\BlockActorDataPacket\\:\\:create\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/world/World.php - - - - message: "#^Parameter \\#2 \\$y of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\UpdateBlockPacket\\:\\:create\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/world/World.php - - message: "#^Parameter \\#2 \\$y of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" count: 3 @@ -730,16 +710,6 @@ parameters: count: 3 path: ../../../src/world/World.php - - - message: "#^Parameter \\#3 \\$z of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\BlockActorDataPacket\\:\\:create\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/world/World.php - - - - message: "#^Parameter \\#3 \\$z of static method pocketmine\\\\network\\\\mcpe\\\\protocol\\\\UpdateBlockPacket\\:\\:create\\(\\) expects int, float\\|int given\\.$#" - count: 1 - path: ../../../src/world/World.php - - message: "#^Parameter \\#3 \\$z of static method pocketmine\\\\world\\\\World\\:\\:blockHash\\(\\) expects int, float\\|int given\\.$#" count: 3 From 701a71a4ee7d54de8ad9fbed9796059d87b7256f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Oct 2021 02:01:26 +0100 Subject: [PATCH 3010/3224] Sound::encode() position is no longer nullable making this nullable was based on the invalid assumption that global sounds have no position, but it turns out they _do_ still use the position to make the sound come from the correct direction. --- src/world/sound/AnvilBreakSound.php | 2 +- src/world/sound/AnvilFallSound.php | 2 +- src/world/sound/AnvilUseSound.php | 2 +- src/world/sound/ArrowHitSound.php | 2 +- src/world/sound/BarrelCloseSound.php | 2 +- src/world/sound/BarrelOpenSound.php | 2 +- src/world/sound/BellRingSound.php | 2 +- src/world/sound/BlazeShootSound.php | 2 +- src/world/sound/BlockBreakSound.php | 2 +- src/world/sound/BlockPlaceSound.php | 2 +- src/world/sound/BlockPunchSound.php | 2 +- src/world/sound/BowShootSound.php | 2 +- src/world/sound/BucketEmptyLavaSound.php | 2 +- src/world/sound/BucketEmptyWaterSound.php | 2 +- src/world/sound/BucketFillLavaSound.php | 2 +- src/world/sound/BucketFillWaterSound.php | 2 +- src/world/sound/ChestCloseSound.php | 2 +- src/world/sound/ChestOpenSound.php | 2 +- src/world/sound/ClickSound.php | 2 +- src/world/sound/DoorBumpSound.php | 2 +- src/world/sound/DoorCrashSound.php | 2 +- src/world/sound/DoorSound.php | 2 +- src/world/sound/EnderChestCloseSound.php | 2 +- src/world/sound/EnderChestOpenSound.php | 2 +- src/world/sound/EndermanTeleportSound.php | 2 +- src/world/sound/EntityAttackNoDamageSound.php | 2 +- src/world/sound/EntityAttackSound.php | 2 +- src/world/sound/EntityLandSound.php | 2 +- src/world/sound/EntityLongFallSound.php | 2 +- src/world/sound/EntityShortFallSound.php | 2 +- src/world/sound/ExplodeSound.php | 2 +- src/world/sound/FireExtinguishSound.php | 2 +- src/world/sound/FizzSound.php | 2 +- src/world/sound/FlintSteelSound.php | 2 +- src/world/sound/GhastShootSound.php | 2 +- src/world/sound/GhastSound.php | 2 +- src/world/sound/IgniteSound.php | 2 +- src/world/sound/ItemBreakSound.php | 2 +- src/world/sound/LaunchSound.php | 2 +- src/world/sound/NoteSound.php | 2 +- src/world/sound/PaintingPlaceSound.php | 2 +- src/world/sound/PopSound.php | 2 +- src/world/sound/PotionSplashSound.php | 2 +- src/world/sound/RecordSound.php | 2 +- src/world/sound/RecordStopSound.php | 2 +- src/world/sound/RedstonePowerOffSound.php | 2 +- src/world/sound/RedstonePowerOnSound.php | 2 +- src/world/sound/ShulkerBoxCloseSound.php | 2 +- src/world/sound/ShulkerBoxOpenSound.php | 2 +- src/world/sound/Sound.php | 2 +- src/world/sound/ThrowSound.php | 2 +- src/world/sound/TotemUseSound.php | 2 +- src/world/sound/XpCollectSound.php | 2 +- src/world/sound/XpLevelUpSound.php | 2 +- 54 files changed, 54 insertions(+), 54 deletions(-) diff --git a/src/world/sound/AnvilBreakSound.php b/src/world/sound/AnvilBreakSound.php index 9da378b35d..cde91af4cf 100644 --- a/src/world/sound/AnvilBreakSound.php +++ b/src/world/sound/AnvilBreakSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class AnvilBreakSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ANVIL_BREAK, 0, $pos)]; } } diff --git a/src/world/sound/AnvilFallSound.php b/src/world/sound/AnvilFallSound.php index 7abf3f6ceb..3ef6cc61e1 100644 --- a/src/world/sound/AnvilFallSound.php +++ b/src/world/sound/AnvilFallSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class AnvilFallSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ANVIL_FALL, 0, $pos)]; } } diff --git a/src/world/sound/AnvilUseSound.php b/src/world/sound/AnvilUseSound.php index 93c0b64ee3..99beb8b0e7 100644 --- a/src/world/sound/AnvilUseSound.php +++ b/src/world/sound/AnvilUseSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class AnvilUseSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ANVIL_USE, 0, $pos)]; } } diff --git a/src/world/sound/ArrowHitSound.php b/src/world/sound/ArrowHitSound.php index cb89dbc51c..4b1d9da58e 100644 --- a/src/world/sound/ArrowHitSound.php +++ b/src/world/sound/ArrowHitSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ArrowHitSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BOW_HIT, $pos, false)]; } } diff --git a/src/world/sound/BarrelCloseSound.php b/src/world/sound/BarrelCloseSound.php index 6adb76093d..fa673a938b 100644 --- a/src/world/sound/BarrelCloseSound.php +++ b/src/world/sound/BarrelCloseSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BarrelCloseSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BLOCK_BARREL_CLOSE, $pos, false)]; } } diff --git a/src/world/sound/BarrelOpenSound.php b/src/world/sound/BarrelOpenSound.php index 04edd73658..ed8a1a4df1 100644 --- a/src/world/sound/BarrelOpenSound.php +++ b/src/world/sound/BarrelOpenSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BarrelOpenSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BLOCK_BARREL_OPEN, $pos, false)]; } } diff --git a/src/world/sound/BellRingSound.php b/src/world/sound/BellRingSound.php index af96e7f09e..c14b63d688 100644 --- a/src/world/sound/BellRingSound.php +++ b/src/world/sound/BellRingSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; final class BellRingSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BLOCK_BELL_HIT, $pos, false)]; } } diff --git a/src/world/sound/BlazeShootSound.php b/src/world/sound/BlazeShootSound.php index 3924784d0d..00f772bbeb 100644 --- a/src/world/sound/BlazeShootSound.php +++ b/src/world/sound/BlazeShootSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class BlazeShootSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_BLAZE_SHOOT, 0, $pos)]; } } diff --git a/src/world/sound/BlockBreakSound.php b/src/world/sound/BlockBreakSound.php index 041664cc84..99cac4c7bc 100644 --- a/src/world/sound/BlockBreakSound.php +++ b/src/world/sound/BlockBreakSound.php @@ -37,7 +37,7 @@ class BlockBreakSound implements Sound{ $this->block = $block; } - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BREAK, $pos, false, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()))]; } } diff --git a/src/world/sound/BlockPlaceSound.php b/src/world/sound/BlockPlaceSound.php index 0c89674690..7a95b22222 100644 --- a/src/world/sound/BlockPlaceSound.php +++ b/src/world/sound/BlockPlaceSound.php @@ -37,7 +37,7 @@ class BlockPlaceSound implements Sound{ $this->block = $block; } - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_PLACE, $pos, false, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()))]; } } diff --git a/src/world/sound/BlockPunchSound.php b/src/world/sound/BlockPunchSound.php index 009e1a7543..51093522ef 100644 --- a/src/world/sound/BlockPunchSound.php +++ b/src/world/sound/BlockPunchSound.php @@ -40,7 +40,7 @@ class BlockPunchSound implements Sound{ $this->block = $block; } - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound( LevelSoundEventPacket::SOUND_HIT, $pos, diff --git a/src/world/sound/BowShootSound.php b/src/world/sound/BowShootSound.php index 22b65cac6e..abdb8169c8 100644 --- a/src/world/sound/BowShootSound.php +++ b/src/world/sound/BowShootSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BowShootSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BOW, $pos, false)]; } } diff --git a/src/world/sound/BucketEmptyLavaSound.php b/src/world/sound/BucketEmptyLavaSound.php index d0f66e7c17..99241daf1f 100644 --- a/src/world/sound/BucketEmptyLavaSound.php +++ b/src/world/sound/BucketEmptyLavaSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BucketEmptyLavaSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BUCKET_EMPTY_LAVA, $pos, false)]; } } diff --git a/src/world/sound/BucketEmptyWaterSound.php b/src/world/sound/BucketEmptyWaterSound.php index af4dec6e29..087675aa9c 100644 --- a/src/world/sound/BucketEmptyWaterSound.php +++ b/src/world/sound/BucketEmptyWaterSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BucketEmptyWaterSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BUCKET_EMPTY_WATER, $pos, false)]; } } diff --git a/src/world/sound/BucketFillLavaSound.php b/src/world/sound/BucketFillLavaSound.php index 01d4edb095..d4df3ef676 100644 --- a/src/world/sound/BucketFillLavaSound.php +++ b/src/world/sound/BucketFillLavaSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BucketFillLavaSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BUCKET_FILL_LAVA, $pos, false)]; } } diff --git a/src/world/sound/BucketFillWaterSound.php b/src/world/sound/BucketFillWaterSound.php index cdb126c7ce..638922413d 100644 --- a/src/world/sound/BucketFillWaterSound.php +++ b/src/world/sound/BucketFillWaterSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class BucketFillWaterSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BUCKET_FILL_WATER, $pos, false)]; } } diff --git a/src/world/sound/ChestCloseSound.php b/src/world/sound/ChestCloseSound.php index 1738ed81fb..2ccaaa0357 100644 --- a/src/world/sound/ChestCloseSound.php +++ b/src/world/sound/ChestCloseSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ChestCloseSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_CHEST_CLOSED, $pos, false)]; } } diff --git a/src/world/sound/ChestOpenSound.php b/src/world/sound/ChestOpenSound.php index dd7bb6a14b..ee8c9313bd 100644 --- a/src/world/sound/ChestOpenSound.php +++ b/src/world/sound/ChestOpenSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ChestOpenSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_CHEST_OPEN, $pos, false)]; } } diff --git a/src/world/sound/ClickSound.php b/src/world/sound/ClickSound.php index dad9e325ac..db472b2926 100644 --- a/src/world/sound/ClickSound.php +++ b/src/world/sound/ClickSound.php @@ -39,7 +39,7 @@ class ClickSound implements Sound{ return $this->pitch; } - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_CLICK, (int) ($this->pitch * 1000), $pos)]; } } diff --git a/src/world/sound/DoorBumpSound.php b/src/world/sound/DoorBumpSound.php index 2d13b0ad89..239401637b 100644 --- a/src/world/sound/DoorBumpSound.php +++ b/src/world/sound/DoorBumpSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class DoorBumpSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_DOOR_BUMP, 0, $pos)]; } } diff --git a/src/world/sound/DoorCrashSound.php b/src/world/sound/DoorCrashSound.php index fa9524a74d..6f3a6cbe03 100644 --- a/src/world/sound/DoorCrashSound.php +++ b/src/world/sound/DoorCrashSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class DoorCrashSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_DOOR_CRASH, 0, $pos)]; } } diff --git a/src/world/sound/DoorSound.php b/src/world/sound/DoorSound.php index 9eca4181d4..b3e4addf95 100644 --- a/src/world/sound/DoorSound.php +++ b/src/world/sound/DoorSound.php @@ -39,7 +39,7 @@ class DoorSound implements Sound{ return $this->pitch; } - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_DOOR, (int) ($this->pitch * 1000), $pos)]; } } diff --git a/src/world/sound/EnderChestCloseSound.php b/src/world/sound/EnderChestCloseSound.php index d016a3ae54..4292dec358 100644 --- a/src/world/sound/EnderChestCloseSound.php +++ b/src/world/sound/EnderChestCloseSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class EnderChestCloseSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_ENDERCHEST_CLOSED, $pos, false)]; } } diff --git a/src/world/sound/EnderChestOpenSound.php b/src/world/sound/EnderChestOpenSound.php index b2a664dd31..ab1894450d 100644 --- a/src/world/sound/EnderChestOpenSound.php +++ b/src/world/sound/EnderChestOpenSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class EnderChestOpenSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_ENDERCHEST_OPEN, $pos, false)]; } } diff --git a/src/world/sound/EndermanTeleportSound.php b/src/world/sound/EndermanTeleportSound.php index 544ffcd216..e2f3f03e82 100644 --- a/src/world/sound/EndermanTeleportSound.php +++ b/src/world/sound/EndermanTeleportSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class EndermanTeleportSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ENDERMAN_TELEPORT, 0, $pos)]; } } diff --git a/src/world/sound/EntityAttackNoDamageSound.php b/src/world/sound/EntityAttackNoDamageSound.php index 0b2fb0cffd..2ab77a2418 100644 --- a/src/world/sound/EntityAttackNoDamageSound.php +++ b/src/world/sound/EntityAttackNoDamageSound.php @@ -31,7 +31,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; */ class EntityAttackNoDamageSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::create( LevelSoundEventPacket::SOUND_ATTACK_NODAMAGE, $pos, diff --git a/src/world/sound/EntityAttackSound.php b/src/world/sound/EntityAttackSound.php index d7fd63b7b3..ecf39a888f 100644 --- a/src/world/sound/EntityAttackSound.php +++ b/src/world/sound/EntityAttackSound.php @@ -31,7 +31,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; */ class EntityAttackSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::create( LevelSoundEventPacket::SOUND_ATTACK_STRONG, //TODO: seems like ATTACK is dysfunctional $pos, diff --git a/src/world/sound/EntityLandSound.php b/src/world/sound/EntityLandSound.php index 7871082bb0..38ba283fc5 100644 --- a/src/world/sound/EntityLandSound.php +++ b/src/world/sound/EntityLandSound.php @@ -44,7 +44,7 @@ class EntityLandSound implements Sound{ $this->blockLandedOn = $blockLandedOn; } - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::create( LevelSoundEventPacket::SOUND_LAND, $pos, diff --git a/src/world/sound/EntityLongFallSound.php b/src/world/sound/EntityLongFallSound.php index 88246f8469..1d0a07f405 100644 --- a/src/world/sound/EntityLongFallSound.php +++ b/src/world/sound/EntityLongFallSound.php @@ -40,7 +40,7 @@ class EntityLongFallSound implements Sound{ $this->entity = $entity; } - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::create( LevelSoundEventPacket::SOUND_FALL_BIG, $pos, diff --git a/src/world/sound/EntityShortFallSound.php b/src/world/sound/EntityShortFallSound.php index fcacd797ee..2f64cc269c 100644 --- a/src/world/sound/EntityShortFallSound.php +++ b/src/world/sound/EntityShortFallSound.php @@ -39,7 +39,7 @@ class EntityShortFallSound implements Sound{ $this->entity = $entity; } - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::create( LevelSoundEventPacket::SOUND_FALL_SMALL, $pos, diff --git a/src/world/sound/ExplodeSound.php b/src/world/sound/ExplodeSound.php index 9dfcd19f84..1f2db9c894 100644 --- a/src/world/sound/ExplodeSound.php +++ b/src/world/sound/ExplodeSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ExplodeSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_EXPLODE, $pos, false)]; } } diff --git a/src/world/sound/FireExtinguishSound.php b/src/world/sound/FireExtinguishSound.php index e9f7e30976..255e821f9a 100644 --- a/src/world/sound/FireExtinguishSound.php +++ b/src/world/sound/FireExtinguishSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; final class FireExtinguishSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_EXTINGUISH_FIRE, $pos, false)]; } } diff --git a/src/world/sound/FizzSound.php b/src/world/sound/FizzSound.php index 0e7b42ffb8..67be8db447 100644 --- a/src/world/sound/FizzSound.php +++ b/src/world/sound/FizzSound.php @@ -39,7 +39,7 @@ class FizzSound implements Sound{ return $this->pitch; } - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_FIZZ, (int) ($this->pitch * 1000), $pos)]; } } diff --git a/src/world/sound/FlintSteelSound.php b/src/world/sound/FlintSteelSound.php index 15ff96a281..4569ed5101 100644 --- a/src/world/sound/FlintSteelSound.php +++ b/src/world/sound/FlintSteelSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class FlintSteelSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_IGNITE, $pos, false)]; } } diff --git a/src/world/sound/GhastShootSound.php b/src/world/sound/GhastShootSound.php index 40f6a47cc6..e7cb550ffc 100644 --- a/src/world/sound/GhastShootSound.php +++ b/src/world/sound/GhastShootSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class GhastShootSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_GHAST_SHOOT, 0, $pos)]; } } diff --git a/src/world/sound/GhastSound.php b/src/world/sound/GhastSound.php index b49a9c374c..2e707d3db0 100644 --- a/src/world/sound/GhastSound.php +++ b/src/world/sound/GhastSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class GhastSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_GHAST, 0, $pos)]; } } diff --git a/src/world/sound/IgniteSound.php b/src/world/sound/IgniteSound.php index dd72342daa..1f1e887036 100644 --- a/src/world/sound/IgniteSound.php +++ b/src/world/sound/IgniteSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class IgniteSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_IGNITE, 0, $pos)]; } } diff --git a/src/world/sound/ItemBreakSound.php b/src/world/sound/ItemBreakSound.php index 0b7f07435d..c2329ce121 100644 --- a/src/world/sound/ItemBreakSound.php +++ b/src/world/sound/ItemBreakSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ItemBreakSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BREAK, $pos, false)]; } } diff --git a/src/world/sound/LaunchSound.php b/src/world/sound/LaunchSound.php index e6772f1c9f..af8b02041a 100644 --- a/src/world/sound/LaunchSound.php +++ b/src/world/sound/LaunchSound.php @@ -39,7 +39,7 @@ class LaunchSound implements Sound{ return $this->pitch; } - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_SHOOT, (int) ($this->pitch * 1000), $pos)]; } } diff --git a/src/world/sound/NoteSound.php b/src/world/sound/NoteSound.php index e84c736b07..7d2bdef428 100644 --- a/src/world/sound/NoteSound.php +++ b/src/world/sound/NoteSound.php @@ -41,7 +41,7 @@ class NoteSound implements Sound{ $this->note = $note; } - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_NOTE, $pos, false, ($this->instrument->getMagicNumber() << 8) | $this->note)]; } } diff --git a/src/world/sound/PaintingPlaceSound.php b/src/world/sound/PaintingPlaceSound.php index c836e0842c..6d9a7ebe39 100644 --- a/src/world/sound/PaintingPlaceSound.php +++ b/src/world/sound/PaintingPlaceSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class PaintingPlaceSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ //item frame and painting have the same sound return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ITEMFRAME_PLACE, 0, $pos)]; } diff --git a/src/world/sound/PopSound.php b/src/world/sound/PopSound.php index 5bce1145f1..421018333c 100644 --- a/src/world/sound/PopSound.php +++ b/src/world/sound/PopSound.php @@ -39,7 +39,7 @@ class PopSound implements Sound{ return $this->pitch; } - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_POP, (int) ($this->pitch * 1000), $pos)]; } } diff --git a/src/world/sound/PotionSplashSound.php b/src/world/sound/PotionSplashSound.php index efde99b258..2547f2aeeb 100644 --- a/src/world/sound/PotionSplashSound.php +++ b/src/world/sound/PotionSplashSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class PotionSplashSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_GLASS, $pos, false)]; } } diff --git a/src/world/sound/RecordSound.php b/src/world/sound/RecordSound.php index 99e781db98..57051d5b65 100644 --- a/src/world/sound/RecordSound.php +++ b/src/world/sound/RecordSound.php @@ -36,7 +36,7 @@ class RecordSound implements Sound{ $this->recordType = $recordType; } - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound($this->recordType->getSoundId(), $pos, false)]; } } diff --git a/src/world/sound/RecordStopSound.php b/src/world/sound/RecordStopSound.php index 2bdd0e6119..9e331a9ffe 100644 --- a/src/world/sound/RecordStopSound.php +++ b/src/world/sound/RecordStopSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class RecordStopSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_STOP_RECORD, $pos, false)]; } } diff --git a/src/world/sound/RedstonePowerOffSound.php b/src/world/sound/RedstonePowerOffSound.php index 5f0ec72809..b07c723b4c 100644 --- a/src/world/sound/RedstonePowerOffSound.php +++ b/src/world/sound/RedstonePowerOffSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class RedstonePowerOffSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_POWER_OFF, $pos, false)]; } } diff --git a/src/world/sound/RedstonePowerOnSound.php b/src/world/sound/RedstonePowerOnSound.php index e260d11669..d71f6b998e 100644 --- a/src/world/sound/RedstonePowerOnSound.php +++ b/src/world/sound/RedstonePowerOnSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class RedstonePowerOnSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_POWER_ON, $pos, false)]; } } diff --git a/src/world/sound/ShulkerBoxCloseSound.php b/src/world/sound/ShulkerBoxCloseSound.php index 2e8e758a4d..ea7a630c3e 100644 --- a/src/world/sound/ShulkerBoxCloseSound.php +++ b/src/world/sound/ShulkerBoxCloseSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ShulkerBoxCloseSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_SHULKERBOX_CLOSED, $pos, false)]; } } diff --git a/src/world/sound/ShulkerBoxOpenSound.php b/src/world/sound/ShulkerBoxOpenSound.php index a5dacea087..491b5dace1 100644 --- a/src/world/sound/ShulkerBoxOpenSound.php +++ b/src/world/sound/ShulkerBoxOpenSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ShulkerBoxOpenSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_SHULKERBOX_OPEN, $pos, false)]; } } diff --git a/src/world/sound/Sound.php b/src/world/sound/Sound.php index 84121db6a1..19074e2564 100644 --- a/src/world/sound/Sound.php +++ b/src/world/sound/Sound.php @@ -31,5 +31,5 @@ interface Sound{ /** * @return ClientboundPacket[] */ - public function encode(?Vector3 $pos) : array; + public function encode(Vector3 $pos) : array; } diff --git a/src/world/sound/ThrowSound.php b/src/world/sound/ThrowSound.php index 1e3297a657..b24474e5fb 100644 --- a/src/world/sound/ThrowSound.php +++ b/src/world/sound/ThrowSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; class ThrowSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_THROW, $pos, -1, "minecraft:player", false, false)]; } } diff --git a/src/world/sound/TotemUseSound.php b/src/world/sound/TotemUseSound.php index baa04275cf..561d9c41ab 100644 --- a/src/world/sound/TotemUseSound.php +++ b/src/world/sound/TotemUseSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class TotemUseSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_TOTEM, 0, $pos)]; } } diff --git a/src/world/sound/XpCollectSound.php b/src/world/sound/XpCollectSound.php index 71a304f30c..655835069e 100644 --- a/src/world/sound/XpCollectSound.php +++ b/src/world/sound/XpCollectSound.php @@ -28,7 +28,7 @@ use pocketmine\network\mcpe\protocol\LevelEventPacket; class XpCollectSound implements Sound{ - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ORB, 0, $pos)]; } } diff --git a/src/world/sound/XpLevelUpSound.php b/src/world/sound/XpLevelUpSound.php index aa44a5ff69..8334b7bead 100644 --- a/src/world/sound/XpLevelUpSound.php +++ b/src/world/sound/XpLevelUpSound.php @@ -41,7 +41,7 @@ class XpLevelUpSound implements Sound{ return $this->xpLevel; } - public function encode(?Vector3 $pos) : array{ + public function encode(Vector3 $pos) : array{ //No idea why such odd numbers, but this works... //TODO: check arbitrary volume return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_LEVELUP, $pos, false, 0x10000000 * intdiv(min(30, $this->xpLevel), 5))]; From 04aedc64946923d91caa9870b39556c4e1fa9069 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Oct 2021 23:54:49 +0100 Subject: [PATCH 3011/3224] Updated BedrockProtocol --- composer.lock | 8 ++-- src/block/utils/RecordType.php | 25 ++++++------ src/entity/animation/ArmSwingAnimation.php | 3 +- src/entity/animation/ArrowShakeAnimation.php | 3 +- .../animation/ConsumingItemAnimation.php | 3 +- src/entity/animation/DeathAnimation.php | 3 +- src/entity/animation/HurtAnimation.php | 3 +- src/entity/animation/RespawnAnimation.php | 3 +- .../animation/SquidInkCloudAnimation.php | 3 +- src/entity/animation/TotemUseAnimation.php | 3 +- .../mcpe/handler/DeathPacketHandler.php | 3 +- .../mcpe/handler/InGamePacketHandler.php | 40 ++++++++++--------- src/player/SurvivalBlockBreakHandler.php | 5 ++- src/world/particle/BlockBreakParticle.php | 3 +- src/world/particle/BlockPunchParticle.php | 3 +- .../particle/DragonEggTeleportParticle.php | 3 +- .../particle/EndermanTeleportParticle.php | 3 +- src/world/particle/MobSpawnParticle.php | 3 +- src/world/particle/PotionSplashParticle.php | 3 +- src/world/sound/AnvilBreakSound.php | 3 +- src/world/sound/AnvilFallSound.php | 3 +- src/world/sound/AnvilUseSound.php | 3 +- src/world/sound/ArrowHitSound.php | 3 +- src/world/sound/BarrelCloseSound.php | 3 +- src/world/sound/BarrelOpenSound.php | 3 +- src/world/sound/BellRingSound.php | 3 +- src/world/sound/BlazeShootSound.php | 3 +- src/world/sound/BlockBreakSound.php | 3 +- src/world/sound/BlockPlaceSound.php | 3 +- src/world/sound/BlockPunchSound.php | 3 +- src/world/sound/BowShootSound.php | 3 +- src/world/sound/BucketEmptyLavaSound.php | 3 +- src/world/sound/BucketEmptyWaterSound.php | 3 +- src/world/sound/BucketFillLavaSound.php | 3 +- src/world/sound/BucketFillWaterSound.php | 3 +- src/world/sound/ChestCloseSound.php | 3 +- src/world/sound/ChestOpenSound.php | 3 +- src/world/sound/ClickSound.php | 3 +- src/world/sound/DoorBumpSound.php | 3 +- src/world/sound/DoorCrashSound.php | 3 +- src/world/sound/DoorSound.php | 3 +- src/world/sound/EnderChestCloseSound.php | 3 +- src/world/sound/EnderChestOpenSound.php | 3 +- src/world/sound/EndermanTeleportSound.php | 3 +- src/world/sound/EntityAttackNoDamageSound.php | 3 +- src/world/sound/EntityAttackSound.php | 3 +- src/world/sound/EntityLandSound.php | 3 +- src/world/sound/EntityLongFallSound.php | 3 +- src/world/sound/EntityShortFallSound.php | 3 +- src/world/sound/ExplodeSound.php | 3 +- src/world/sound/FireExtinguishSound.php | 3 +- src/world/sound/FizzSound.php | 3 +- src/world/sound/FlintSteelSound.php | 3 +- src/world/sound/GhastShootSound.php | 3 +- src/world/sound/GhastSound.php | 3 +- src/world/sound/IgniteSound.php | 3 +- src/world/sound/ItemBreakSound.php | 3 +- src/world/sound/LaunchSound.php | 3 +- src/world/sound/NoteSound.php | 3 +- src/world/sound/PaintingPlaceSound.php | 3 +- src/world/sound/PopSound.php | 3 +- src/world/sound/PotionSplashSound.php | 3 +- src/world/sound/RecordStopSound.php | 3 +- src/world/sound/RedstonePowerOffSound.php | 3 +- src/world/sound/RedstonePowerOnSound.php | 3 +- src/world/sound/ShulkerBoxCloseSound.php | 3 +- src/world/sound/ShulkerBoxOpenSound.php | 3 +- src/world/sound/ThrowSound.php | 3 +- src/world/sound/TotemUseSound.php | 3 +- src/world/sound/XpCollectSound.php | 3 +- src/world/sound/XpLevelUpSound.php | 3 +- 71 files changed, 175 insertions(+), 104 deletions(-) diff --git a/composer.lock b/composer.lock index 89bd8e43b7..883984a57b 100644 --- a/composer.lock +++ b/composer.lock @@ -253,12 +253,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "97fa88e9eff2c9bd5408fa964515504a4d9230bf" + "reference": "5285dde125b529e070db7eeb0d3774208e1652ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/97fa88e9eff2c9bd5408fa964515504a4d9230bf", - "reference": "97fa88e9eff2c9bd5408fa964515504a4d9230bf", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/5285dde125b529e070db7eeb0d3774208e1652ef", + "reference": "5285dde125b529e070db7eeb0d3774208e1652ef", "shasum": "" }, "require": { @@ -293,7 +293,7 @@ "issues": "https://github.com/pmmp/BedrockProtocol/issues", "source": "https://github.com/pmmp/BedrockProtocol/tree/master" }, - "time": "2021-10-23T00:06:46+00:00" + "time": "2021-10-23T15:18:49+00:00" }, { "name": "pocketmine/binaryutils", diff --git a/src/block/utils/RecordType.php b/src/block/utils/RecordType.php index 093663d0ba..967cdc0349 100644 --- a/src/block/utils/RecordType.php +++ b/src/block/utils/RecordType.php @@ -26,6 +26,7 @@ namespace pocketmine\block\utils; use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\Translatable; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; use pocketmine\utils\EnumTrait; /** @@ -54,18 +55,18 @@ final class RecordType{ protected static function setup() : void{ self::registerAll( - new RecordType("disk_13", "C418 - 13", LevelSoundEventPacket::SOUND_RECORD_13, KnownTranslationFactory::item_record_13_desc()), - new RecordType("disk_cat", "C418 - cat", LevelSoundEventPacket::SOUND_RECORD_CAT, KnownTranslationFactory::item_record_cat_desc()), - new RecordType("disk_blocks", "C418 - blocks", LevelSoundEventPacket::SOUND_RECORD_BLOCKS, KnownTranslationFactory::item_record_blocks_desc()), - new RecordType("disk_chirp", "C418 - chirp", LevelSoundEventPacket::SOUND_RECORD_CHIRP, KnownTranslationFactory::item_record_chirp_desc()), - new RecordType("disk_far", "C418 - far", LevelSoundEventPacket::SOUND_RECORD_FAR, KnownTranslationFactory::item_record_far_desc()), - new RecordType("disk_mall", "C418 - mall", LevelSoundEventPacket::SOUND_RECORD_MALL, KnownTranslationFactory::item_record_mall_desc()), - new RecordType("disk_mellohi", "C418 - mellohi", LevelSoundEventPacket::SOUND_RECORD_MELLOHI, KnownTranslationFactory::item_record_mellohi_desc()), - new RecordType("disk_stal", "C418 - stal", LevelSoundEventPacket::SOUND_RECORD_STAL, KnownTranslationFactory::item_record_stal_desc()), - new RecordType("disk_strad", "C418 - strad", LevelSoundEventPacket::SOUND_RECORD_STRAD, KnownTranslationFactory::item_record_strad_desc()), - new RecordType("disk_ward", "C418 - ward", LevelSoundEventPacket::SOUND_RECORD_WARD, KnownTranslationFactory::item_record_ward_desc()), - new RecordType("disk_11", "C418 - 11", LevelSoundEventPacket::SOUND_RECORD_11, KnownTranslationFactory::item_record_11_desc()), - new RecordType("disk_wait", "C418 - wait", LevelSoundEventPacket::SOUND_RECORD_WAIT, KnownTranslationFactory::item_record_wait_desc()) + new RecordType("disk_13", "C418 - 13", LevelSoundEvent::RECORD_13, KnownTranslationFactory::item_record_13_desc()), + new RecordType("disk_cat", "C418 - cat", LevelSoundEvent::RECORD_CAT, KnownTranslationFactory::item_record_cat_desc()), + new RecordType("disk_blocks", "C418 - blocks", LevelSoundEvent::RECORD_BLOCKS, KnownTranslationFactory::item_record_blocks_desc()), + new RecordType("disk_chirp", "C418 - chirp", LevelSoundEvent::RECORD_CHIRP, KnownTranslationFactory::item_record_chirp_desc()), + new RecordType("disk_far", "C418 - far", LevelSoundEvent::RECORD_FAR, KnownTranslationFactory::item_record_far_desc()), + new RecordType("disk_mall", "C418 - mall", LevelSoundEvent::RECORD_MALL, KnownTranslationFactory::item_record_mall_desc()), + new RecordType("disk_mellohi", "C418 - mellohi", LevelSoundEvent::RECORD_MELLOHI, KnownTranslationFactory::item_record_mellohi_desc()), + new RecordType("disk_stal", "C418 - stal", LevelSoundEvent::RECORD_STAL, KnownTranslationFactory::item_record_stal_desc()), + new RecordType("disk_strad", "C418 - strad", LevelSoundEvent::RECORD_STRAD, KnownTranslationFactory::item_record_strad_desc()), + new RecordType("disk_ward", "C418 - ward", LevelSoundEvent::RECORD_WARD, KnownTranslationFactory::item_record_ward_desc()), + new RecordType("disk_11", "C418 - 11", LevelSoundEvent::RECORD_11, KnownTranslationFactory::item_record_11_desc()), + new RecordType("disk_wait", "C418 - wait", LevelSoundEvent::RECORD_WAIT, KnownTranslationFactory::item_record_wait_desc()) //TODO: Lena Raine - Pigstep ); } diff --git a/src/entity/animation/ArmSwingAnimation.php b/src/entity/animation/ArmSwingAnimation.php index c309472bf1..8871415a20 100644 --- a/src/entity/animation/ArmSwingAnimation.php +++ b/src/entity/animation/ArmSwingAnimation.php @@ -25,6 +25,7 @@ namespace pocketmine\entity\animation; use pocketmine\entity\Living; use pocketmine\network\mcpe\protocol\ActorEventPacket; +use pocketmine\network\mcpe\protocol\types\ActorEvent; final class ArmSwingAnimation implements Animation{ @@ -37,7 +38,7 @@ final class ArmSwingAnimation implements Animation{ public function encode() : array{ return [ - ActorEventPacket::create($this->entity->getId(), ActorEventPacket::ARM_SWING, 0) + ActorEventPacket::create($this->entity->getId(), ActorEvent::ARM_SWING, 0) ]; } } diff --git a/src/entity/animation/ArrowShakeAnimation.php b/src/entity/animation/ArrowShakeAnimation.php index 925b93d3a8..256c6142bf 100644 --- a/src/entity/animation/ArrowShakeAnimation.php +++ b/src/entity/animation/ArrowShakeAnimation.php @@ -25,6 +25,7 @@ namespace pocketmine\entity\animation; use pocketmine\entity\projectile\Arrow; use pocketmine\network\mcpe\protocol\ActorEventPacket; +use pocketmine\network\mcpe\protocol\types\ActorEvent; class ArrowShakeAnimation implements Animation{ @@ -40,7 +41,7 @@ class ArrowShakeAnimation implements Animation{ public function encode() : array{ return [ - ActorEventPacket::create($this->arrow->getId(), ActorEventPacket::ARROW_SHAKE, $this->durationInTicks) + ActorEventPacket::create($this->arrow->getId(), ActorEvent::ARROW_SHAKE, $this->durationInTicks) ]; } } diff --git a/src/entity/animation/ConsumingItemAnimation.php b/src/entity/animation/ConsumingItemAnimation.php index 4f3e34ba4c..b32f118bbd 100644 --- a/src/entity/animation/ConsumingItemAnimation.php +++ b/src/entity/animation/ConsumingItemAnimation.php @@ -27,6 +27,7 @@ use pocketmine\entity\Human; use pocketmine\item\Item; use pocketmine\network\mcpe\convert\ItemTranslator; use pocketmine\network\mcpe\protocol\ActorEventPacket; +use pocketmine\network\mcpe\protocol\types\ActorEvent; final class ConsumingItemAnimation implements Animation{ @@ -45,7 +46,7 @@ final class ConsumingItemAnimation implements Animation{ [$netId, $netData] = ItemTranslator::getInstance()->toNetworkId($this->item->getId(), $this->item->getMeta()); return [ //TODO: need to check the data values - ActorEventPacket::create($this->human->getId(), ActorEventPacket::EATING_ITEM, ($netId << 16) | $netData) + ActorEventPacket::create($this->human->getId(), ActorEvent::EATING_ITEM, ($netId << 16) | $netData) ]; } } diff --git a/src/entity/animation/DeathAnimation.php b/src/entity/animation/DeathAnimation.php index 35dab4597b..a3a9244134 100644 --- a/src/entity/animation/DeathAnimation.php +++ b/src/entity/animation/DeathAnimation.php @@ -25,6 +25,7 @@ namespace pocketmine\entity\animation; use pocketmine\entity\Living; use pocketmine\network\mcpe\protocol\ActorEventPacket; +use pocketmine\network\mcpe\protocol\types\ActorEvent; final class DeathAnimation implements Animation{ @@ -37,7 +38,7 @@ final class DeathAnimation implements Animation{ public function encode() : array{ return [ - ActorEventPacket::create($this->entity->getId(), ActorEventPacket::DEATH_ANIMATION, 0) + ActorEventPacket::create($this->entity->getId(), ActorEvent::DEATH_ANIMATION, 0) ]; } } diff --git a/src/entity/animation/HurtAnimation.php b/src/entity/animation/HurtAnimation.php index 3ba5ebb8c6..355b49d470 100644 --- a/src/entity/animation/HurtAnimation.php +++ b/src/entity/animation/HurtAnimation.php @@ -25,6 +25,7 @@ namespace pocketmine\entity\animation; use pocketmine\entity\Living; use pocketmine\network\mcpe\protocol\ActorEventPacket; +use pocketmine\network\mcpe\protocol\types\ActorEvent; final class HurtAnimation implements Animation{ @@ -37,7 +38,7 @@ final class HurtAnimation implements Animation{ public function encode() : array{ return [ - ActorEventPacket::create($this->entity->getId(), ActorEventPacket::HURT_ANIMATION, 0) + ActorEventPacket::create($this->entity->getId(), ActorEvent::HURT_ANIMATION, 0) ]; } } diff --git a/src/entity/animation/RespawnAnimation.php b/src/entity/animation/RespawnAnimation.php index defb26cf72..e8466e26e2 100644 --- a/src/entity/animation/RespawnAnimation.php +++ b/src/entity/animation/RespawnAnimation.php @@ -25,6 +25,7 @@ namespace pocketmine\entity\animation; use pocketmine\entity\Living; use pocketmine\network\mcpe\protocol\ActorEventPacket; +use pocketmine\network\mcpe\protocol\types\ActorEvent; final class RespawnAnimation implements Animation{ @@ -37,7 +38,7 @@ final class RespawnAnimation implements Animation{ public function encode() : array{ return [ - ActorEventPacket::create($this->entity->getId(), ActorEventPacket::RESPAWN, 0) + ActorEventPacket::create($this->entity->getId(), ActorEvent::RESPAWN, 0) ]; } } diff --git a/src/entity/animation/SquidInkCloudAnimation.php b/src/entity/animation/SquidInkCloudAnimation.php index fa3a9fd6b1..6ae728a797 100644 --- a/src/entity/animation/SquidInkCloudAnimation.php +++ b/src/entity/animation/SquidInkCloudAnimation.php @@ -25,6 +25,7 @@ namespace pocketmine\entity\animation; use pocketmine\entity\Squid; use pocketmine\network\mcpe\protocol\ActorEventPacket; +use pocketmine\network\mcpe\protocol\types\ActorEvent; final class SquidInkCloudAnimation implements Animation{ @@ -37,7 +38,7 @@ final class SquidInkCloudAnimation implements Animation{ public function encode() : array{ return [ - ActorEventPacket::create($this->squid->getId(), ActorEventPacket::SQUID_INK_CLOUD, 0) + ActorEventPacket::create($this->squid->getId(), ActorEvent::SQUID_INK_CLOUD, 0) ]; } } diff --git a/src/entity/animation/TotemUseAnimation.php b/src/entity/animation/TotemUseAnimation.php index 11eb68e464..ec0d3b12cc 100644 --- a/src/entity/animation/TotemUseAnimation.php +++ b/src/entity/animation/TotemUseAnimation.php @@ -25,6 +25,7 @@ namespace pocketmine\entity\animation; use pocketmine\entity\Human; use pocketmine\network\mcpe\protocol\ActorEventPacket; +use pocketmine\network\mcpe\protocol\types\ActorEvent; final class TotemUseAnimation implements Animation{ @@ -38,7 +39,7 @@ final class TotemUseAnimation implements Animation{ public function encode() : array{ return [ - ActorEventPacket::create($this->human->getId(), ActorEventPacket::CONSUME_TOTEM, 0) + ActorEventPacket::create($this->human->getId(), ActorEvent::CONSUME_TOTEM, 0) ]; } } diff --git a/src/network/mcpe/handler/DeathPacketHandler.php b/src/network/mcpe/handler/DeathPacketHandler.php index db4cbaa7d0..c3421f1a5f 100644 --- a/src/network/mcpe/handler/DeathPacketHandler.php +++ b/src/network/mcpe/handler/DeathPacketHandler.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\handler; use pocketmine\network\mcpe\NetworkSession; use pocketmine\network\mcpe\protocol\PlayerActionPacket; use pocketmine\network\mcpe\protocol\RespawnPacket; +use pocketmine\network\mcpe\protocol\types\PlayerAction; use pocketmine\player\Player; class DeathPacketHandler extends PacketHandler{ @@ -49,7 +50,7 @@ class DeathPacketHandler extends PacketHandler{ } public function handlePlayerAction(PlayerActionPacket $packet) : bool{ - if($packet->action === PlayerActionPacket::ACTION_RESPAWN){ + if($packet->action === PlayerAction::RESPAWN){ $this->player->respawn(); return true; } diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index a8e784ceda..ef49cb355b 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -83,6 +83,7 @@ use pocketmine\network\mcpe\protocol\ShowCreditsPacket; use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket; use pocketmine\network\mcpe\protocol\SubClientLoginPacket; use pocketmine\network\mcpe\protocol\TextPacket; +use pocketmine\network\mcpe\protocol\types\ActorEvent; use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds; use pocketmine\network\mcpe\protocol\types\inventory\MismatchTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\NetworkInventoryAction; @@ -92,6 +93,7 @@ use pocketmine\network\mcpe\protocol\types\inventory\UIInventorySlotOffset; use pocketmine\network\mcpe\protocol\types\inventory\UseItemOnEntityTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\UseItemTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes; +use pocketmine\network\mcpe\protocol\types\PlayerAction; use pocketmine\network\PacketHandlingException; use pocketmine\player\Player; use pocketmine\utils\AssumptionFailedError; @@ -201,12 +203,12 @@ class InGamePacketHandler extends PacketHandler{ public function handleActorEvent(ActorEventPacket $packet) : bool{ if($packet->actorRuntimeId !== $this->player->getId()){ //TODO HACK: EATING_ITEM is sent back to the server when the server sends it for other players (1.14 bug, maybe earlier) - return $packet->actorRuntimeId === ActorEventPacket::EATING_ITEM; + return $packet->actorRuntimeId === ActorEvent::EATING_ITEM; } $this->player->doCloseInventory(); switch($packet->eventId){ - case ActorEventPacket::EATING_ITEM: //TODO: ignore this and handle it server-side + case ActorEvent::EATING_ITEM: //TODO: ignore this and handle it server-side $item = $this->player->getInventory()->getItemInHand(); if($item->isNull()){ return false; @@ -534,60 +536,60 @@ class InGamePacketHandler extends PacketHandler{ $pos = new Vector3($packet->blockPosition->getX(), $packet->blockPosition->getY(), $packet->blockPosition->getZ()); switch($packet->action){ - case PlayerActionPacket::ACTION_START_BREAK: + case PlayerAction::START_BREAK: if(!$this->player->attackBlock($pos, $packet->face)){ $this->onFailedBlockAction($pos, $packet->face); } break; - case PlayerActionPacket::ACTION_ABORT_BREAK: - case PlayerActionPacket::ACTION_STOP_BREAK: + case PlayerAction::ABORT_BREAK: + case PlayerAction::STOP_BREAK: $this->player->stopBreakBlock($pos); break; - case PlayerActionPacket::ACTION_START_SLEEPING: + case PlayerAction::START_SLEEPING: //unused break; - case PlayerActionPacket::ACTION_STOP_SLEEPING: + case PlayerAction::STOP_SLEEPING: $this->player->stopSleep(); break; - case PlayerActionPacket::ACTION_JUMP: + case PlayerAction::JUMP: $this->player->jump(); return true; - case PlayerActionPacket::ACTION_START_SPRINT: + case PlayerAction::START_SPRINT: if(!$this->player->toggleSprint(true)){ $this->player->sendData([$this->player]); } return true; - case PlayerActionPacket::ACTION_STOP_SPRINT: + case PlayerAction::STOP_SPRINT: if(!$this->player->toggleSprint(false)){ $this->player->sendData([$this->player]); } return true; - case PlayerActionPacket::ACTION_START_SNEAK: + case PlayerAction::START_SNEAK: if(!$this->player->toggleSneak(true)){ $this->player->sendData([$this->player]); } return true; - case PlayerActionPacket::ACTION_STOP_SNEAK: + case PlayerAction::STOP_SNEAK: if(!$this->player->toggleSneak(false)){ $this->player->sendData([$this->player]); } return true; - case PlayerActionPacket::ACTION_START_GLIDE: - case PlayerActionPacket::ACTION_STOP_GLIDE: + case PlayerAction::START_GLIDE: + case PlayerAction::STOP_GLIDE: break; //TODO - case PlayerActionPacket::ACTION_CRACK_BREAK: + case PlayerAction::CRACK_BREAK: $this->player->continueBreakBlock($pos, $packet->face); break; - case PlayerActionPacket::ACTION_START_SWIMMING: + case PlayerAction::START_SWIMMING: break; //TODO - case PlayerActionPacket::ACTION_STOP_SWIMMING: + case PlayerAction::STOP_SWIMMING: //TODO: handle this when it doesn't spam every damn tick (yet another spam bug!!) break; - case PlayerActionPacket::ACTION_INTERACT_BLOCK: //TODO: ignored (for now) + case PlayerAction::INTERACT_BLOCK: //TODO: ignored (for now) break; - case PlayerActionPacket::ACTION_CREATIVE_PLAYER_DESTROY_BLOCK: + case PlayerAction::CREATIVE_PLAYER_DESTROY_BLOCK: //TODO: do we need to handle this? break; default: diff --git a/src/player/SurvivalBlockBreakHandler.php b/src/player/SurvivalBlockBreakHandler.php index 3992e8fa5e..ee9ff4df91 100644 --- a/src/player/SurvivalBlockBreakHandler.php +++ b/src/player/SurvivalBlockBreakHandler.php @@ -28,6 +28,7 @@ use pocketmine\entity\animation\ArmSwingAnimation; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; use pocketmine\world\particle\BlockPunchParticle; use pocketmine\world\sound\BlockPunchSound; use function abs; @@ -70,7 +71,7 @@ final class SurvivalBlockBreakHandler{ if($this->breakSpeed > 0){ $this->player->getWorld()->broadcastPacketToViewers( $this->blockPos, - LevelEventPacket::create(LevelEventPacket::EVENT_BLOCK_START_BREAK, (int) (65535 * $this->breakSpeed), $this->blockPos) + LevelEventPacket::create(LevelEvent::BLOCK_START_BREAK, (int) (65535 * $this->breakSpeed), $this->blockPos) ); } } @@ -147,7 +148,7 @@ final class SurvivalBlockBreakHandler{ if($this->player->getWorld()->isInLoadedTerrain($this->blockPos)){ $this->player->getWorld()->broadcastPacketToViewers( $this->blockPos, - LevelEventPacket::create(LevelEventPacket::EVENT_BLOCK_STOP_BREAK, 0, $this->blockPos) + LevelEventPacket::create(LevelEvent::BLOCK_STOP_BREAK, 0, $this->blockPos) ); } } diff --git a/src/world/particle/BlockBreakParticle.php b/src/world/particle/BlockBreakParticle.php index bf3c235118..40e8d8beab 100644 --- a/src/world/particle/BlockBreakParticle.php +++ b/src/world/particle/BlockBreakParticle.php @@ -27,6 +27,7 @@ use pocketmine\block\Block; use pocketmine\math\Vector3; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class BlockBreakParticle implements Particle{ @@ -38,6 +39,6 @@ class BlockBreakParticle implements Particle{ } public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_DESTROY, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()), $pos)]; + return [LevelEventPacket::create(LevelEvent::PARTICLE_DESTROY, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()), $pos)]; } } diff --git a/src/world/particle/BlockPunchParticle.php b/src/world/particle/BlockPunchParticle.php index e0a7eaaf8d..5ee0c33521 100644 --- a/src/world/particle/BlockPunchParticle.php +++ b/src/world/particle/BlockPunchParticle.php @@ -27,6 +27,7 @@ use pocketmine\block\Block; use pocketmine\math\Vector3; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; /** * This particle appears when a player is attacking a block face in survival mode attempting to break it. @@ -44,6 +45,6 @@ class BlockPunchParticle implements Particle{ } public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_PUNCH_BLOCK, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()) | ($this->face << 24), $pos)]; + return [LevelEventPacket::create(LevelEvent::PARTICLE_PUNCH_BLOCK, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()) | ($this->face << 24), $pos)]; } } diff --git a/src/world/particle/DragonEggTeleportParticle.php b/src/world/particle/DragonEggTeleportParticle.php index 5c17650da3..a2f2ae3ac2 100644 --- a/src/world/particle/DragonEggTeleportParticle.php +++ b/src/world/particle/DragonEggTeleportParticle.php @@ -25,6 +25,7 @@ namespace pocketmine\world\particle; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; use function abs; class DragonEggTeleportParticle implements Particle{ @@ -57,6 +58,6 @@ class DragonEggTeleportParticle implements Particle{ (abs($this->yDiff) << 8) | abs($this->zDiff); - return [LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_DRAGON_EGG_TELEPORT, $data, $pos)]; + return [LevelEventPacket::create(LevelEvent::PARTICLE_DRAGON_EGG_TELEPORT, $data, $pos)]; } } diff --git a/src/world/particle/EndermanTeleportParticle.php b/src/world/particle/EndermanTeleportParticle.php index 274d1540e6..f370e44870 100644 --- a/src/world/particle/EndermanTeleportParticle.php +++ b/src/world/particle/EndermanTeleportParticle.php @@ -25,10 +25,11 @@ namespace pocketmine\world\particle; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class EndermanTeleportParticle implements Particle{ public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_ENDERMAN_TELEPORT, 0, $pos)]; + return [LevelEventPacket::create(LevelEvent::PARTICLE_ENDERMAN_TELEPORT, 0, $pos)]; } } diff --git a/src/world/particle/MobSpawnParticle.php b/src/world/particle/MobSpawnParticle.php index bdc2f01449..07706888e8 100644 --- a/src/world/particle/MobSpawnParticle.php +++ b/src/world/particle/MobSpawnParticle.php @@ -25,6 +25,7 @@ namespace pocketmine\world\particle; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class MobSpawnParticle implements Particle{ /** @var int */ @@ -39,6 +40,6 @@ class MobSpawnParticle implements Particle{ } public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_SPAWN, ($this->width & 0xff) | (($this->height & 0xff) << 8), $pos)]; + return [LevelEventPacket::create(LevelEvent::PARTICLE_SPAWN, ($this->width & 0xff) | (($this->height & 0xff) << 8), $pos)]; } } diff --git a/src/world/particle/PotionSplashParticle.php b/src/world/particle/PotionSplashParticle.php index 83ad8c699a..1175e95189 100644 --- a/src/world/particle/PotionSplashParticle.php +++ b/src/world/particle/PotionSplashParticle.php @@ -26,6 +26,7 @@ namespace pocketmine\world\particle; use pocketmine\color\Color; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class PotionSplashParticle implements Particle{ @@ -50,6 +51,6 @@ class PotionSplashParticle implements Particle{ } public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_PARTICLE_SPLASH, $this->color->toARGB(), $pos)]; + return [LevelEventPacket::create(LevelEvent::PARTICLE_SPLASH, $this->color->toARGB(), $pos)]; } } diff --git a/src/world/sound/AnvilBreakSound.php b/src/world/sound/AnvilBreakSound.php index cde91af4cf..e57c0e02b6 100644 --- a/src/world/sound/AnvilBreakSound.php +++ b/src/world/sound/AnvilBreakSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class AnvilBreakSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ANVIL_BREAK, 0, $pos)]; + return [LevelEventPacket::create(LevelEvent::SOUND_ANVIL_BREAK, 0, $pos)]; } } diff --git a/src/world/sound/AnvilFallSound.php b/src/world/sound/AnvilFallSound.php index 3ef6cc61e1..fd6efc7fe2 100644 --- a/src/world/sound/AnvilFallSound.php +++ b/src/world/sound/AnvilFallSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class AnvilFallSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ANVIL_FALL, 0, $pos)]; + return [LevelEventPacket::create(LevelEvent::SOUND_ANVIL_FALL, 0, $pos)]; } } diff --git a/src/world/sound/AnvilUseSound.php b/src/world/sound/AnvilUseSound.php index 99beb8b0e7..b384c8624c 100644 --- a/src/world/sound/AnvilUseSound.php +++ b/src/world/sound/AnvilUseSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class AnvilUseSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ANVIL_USE, 0, $pos)]; + return [LevelEventPacket::create(LevelEvent::SOUND_ANVIL_USE, 0, $pos)]; } } diff --git a/src/world/sound/ArrowHitSound.php b/src/world/sound/ArrowHitSound.php index 4b1d9da58e..abfdfc4a4d 100644 --- a/src/world/sound/ArrowHitSound.php +++ b/src/world/sound/ArrowHitSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class ArrowHitSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BOW_HIT, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::BOW_HIT, $pos, false)]; } } diff --git a/src/world/sound/BarrelCloseSound.php b/src/world/sound/BarrelCloseSound.php index fa673a938b..be2bdaf79f 100644 --- a/src/world/sound/BarrelCloseSound.php +++ b/src/world/sound/BarrelCloseSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class BarrelCloseSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BLOCK_BARREL_CLOSE, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::BLOCK_BARREL_CLOSE, $pos, false)]; } } diff --git a/src/world/sound/BarrelOpenSound.php b/src/world/sound/BarrelOpenSound.php index ed8a1a4df1..ee695060c2 100644 --- a/src/world/sound/BarrelOpenSound.php +++ b/src/world/sound/BarrelOpenSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class BarrelOpenSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BLOCK_BARREL_OPEN, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::BLOCK_BARREL_OPEN, $pos, false)]; } } diff --git a/src/world/sound/BellRingSound.php b/src/world/sound/BellRingSound.php index c14b63d688..c2a45a561d 100644 --- a/src/world/sound/BellRingSound.php +++ b/src/world/sound/BellRingSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; final class BellRingSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BLOCK_BELL_HIT, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::BLOCK_BELL_HIT, $pos, false)]; } } diff --git a/src/world/sound/BlazeShootSound.php b/src/world/sound/BlazeShootSound.php index 00f772bbeb..a86c09344b 100644 --- a/src/world/sound/BlazeShootSound.php +++ b/src/world/sound/BlazeShootSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class BlazeShootSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_BLAZE_SHOOT, 0, $pos)]; + return [LevelEventPacket::create(LevelEvent::SOUND_BLAZE_SHOOT, 0, $pos)]; } } diff --git a/src/world/sound/BlockBreakSound.php b/src/world/sound/BlockBreakSound.php index 99cac4c7bc..39323259d2 100644 --- a/src/world/sound/BlockBreakSound.php +++ b/src/world/sound/BlockBreakSound.php @@ -27,6 +27,7 @@ use pocketmine\block\Block; use pocketmine\math\Vector3; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class BlockBreakSound implements Sound{ @@ -38,6 +39,6 @@ class BlockBreakSound implements Sound{ } public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BREAK, $pos, false, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()))]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::BREAK, $pos, false, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()))]; } } diff --git a/src/world/sound/BlockPlaceSound.php b/src/world/sound/BlockPlaceSound.php index 7a95b22222..831c879a18 100644 --- a/src/world/sound/BlockPlaceSound.php +++ b/src/world/sound/BlockPlaceSound.php @@ -27,6 +27,7 @@ use pocketmine\block\Block; use pocketmine\math\Vector3; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class BlockPlaceSound implements Sound{ @@ -38,6 +39,6 @@ class BlockPlaceSound implements Sound{ } public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_PLACE, $pos, false, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()))]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::PLACE, $pos, false, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()))]; } } diff --git a/src/world/sound/BlockPunchSound.php b/src/world/sound/BlockPunchSound.php index 51093522ef..03d3ded64c 100644 --- a/src/world/sound/BlockPunchSound.php +++ b/src/world/sound/BlockPunchSound.php @@ -27,6 +27,7 @@ use pocketmine\block\Block; use pocketmine\math\Vector3; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; /** * Played when a player attacks a block in survival, attempting to break it. @@ -42,7 +43,7 @@ class BlockPunchSound implements Sound{ public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::nonActorSound( - LevelSoundEventPacket::SOUND_HIT, + LevelSoundEvent::HIT, $pos, false, RuntimeBlockMapping::getInstance()->toRuntimeId($this->block->getFullId()) diff --git a/src/world/sound/BowShootSound.php b/src/world/sound/BowShootSound.php index abdb8169c8..2b595972fc 100644 --- a/src/world/sound/BowShootSound.php +++ b/src/world/sound/BowShootSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class BowShootSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BOW, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::BOW, $pos, false)]; } } diff --git a/src/world/sound/BucketEmptyLavaSound.php b/src/world/sound/BucketEmptyLavaSound.php index 99241daf1f..e3e991597f 100644 --- a/src/world/sound/BucketEmptyLavaSound.php +++ b/src/world/sound/BucketEmptyLavaSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class BucketEmptyLavaSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BUCKET_EMPTY_LAVA, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::BUCKET_EMPTY_LAVA, $pos, false)]; } } diff --git a/src/world/sound/BucketEmptyWaterSound.php b/src/world/sound/BucketEmptyWaterSound.php index 087675aa9c..b80b903116 100644 --- a/src/world/sound/BucketEmptyWaterSound.php +++ b/src/world/sound/BucketEmptyWaterSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class BucketEmptyWaterSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BUCKET_EMPTY_WATER, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::BUCKET_EMPTY_WATER, $pos, false)]; } } diff --git a/src/world/sound/BucketFillLavaSound.php b/src/world/sound/BucketFillLavaSound.php index d4df3ef676..0315c8a8e5 100644 --- a/src/world/sound/BucketFillLavaSound.php +++ b/src/world/sound/BucketFillLavaSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class BucketFillLavaSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BUCKET_FILL_LAVA, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::BUCKET_FILL_LAVA, $pos, false)]; } } diff --git a/src/world/sound/BucketFillWaterSound.php b/src/world/sound/BucketFillWaterSound.php index 638922413d..4314357888 100644 --- a/src/world/sound/BucketFillWaterSound.php +++ b/src/world/sound/BucketFillWaterSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class BucketFillWaterSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BUCKET_FILL_WATER, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::BUCKET_FILL_WATER, $pos, false)]; } } diff --git a/src/world/sound/ChestCloseSound.php b/src/world/sound/ChestCloseSound.php index 2ccaaa0357..e1c15e523e 100644 --- a/src/world/sound/ChestCloseSound.php +++ b/src/world/sound/ChestCloseSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class ChestCloseSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_CHEST_CLOSED, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::CHEST_CLOSED, $pos, false)]; } } diff --git a/src/world/sound/ChestOpenSound.php b/src/world/sound/ChestOpenSound.php index ee8c9313bd..0e835d5fab 100644 --- a/src/world/sound/ChestOpenSound.php +++ b/src/world/sound/ChestOpenSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class ChestOpenSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_CHEST_OPEN, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::CHEST_OPEN, $pos, false)]; } } diff --git a/src/world/sound/ClickSound.php b/src/world/sound/ClickSound.php index db472b2926..c02471f87e 100644 --- a/src/world/sound/ClickSound.php +++ b/src/world/sound/ClickSound.php @@ -25,6 +25,7 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class ClickSound implements Sound{ @@ -40,6 +41,6 @@ class ClickSound implements Sound{ } public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_CLICK, (int) ($this->pitch * 1000), $pos)]; + return [LevelEventPacket::create(LevelEvent::SOUND_CLICK, (int) ($this->pitch * 1000), $pos)]; } } diff --git a/src/world/sound/DoorBumpSound.php b/src/world/sound/DoorBumpSound.php index 239401637b..86ed0f3398 100644 --- a/src/world/sound/DoorBumpSound.php +++ b/src/world/sound/DoorBumpSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class DoorBumpSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_DOOR_BUMP, 0, $pos)]; + return [LevelEventPacket::create(LevelEvent::SOUND_DOOR_BUMP, 0, $pos)]; } } diff --git a/src/world/sound/DoorCrashSound.php b/src/world/sound/DoorCrashSound.php index 6f3a6cbe03..3259c4889b 100644 --- a/src/world/sound/DoorCrashSound.php +++ b/src/world/sound/DoorCrashSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class DoorCrashSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_DOOR_CRASH, 0, $pos)]; + return [LevelEventPacket::create(LevelEvent::SOUND_DOOR_CRASH, 0, $pos)]; } } diff --git a/src/world/sound/DoorSound.php b/src/world/sound/DoorSound.php index b3e4addf95..368136c915 100644 --- a/src/world/sound/DoorSound.php +++ b/src/world/sound/DoorSound.php @@ -25,6 +25,7 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class DoorSound implements Sound{ @@ -40,6 +41,6 @@ class DoorSound implements Sound{ } public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_DOOR, (int) ($this->pitch * 1000), $pos)]; + return [LevelEventPacket::create(LevelEvent::SOUND_DOOR, (int) ($this->pitch * 1000), $pos)]; } } diff --git a/src/world/sound/EnderChestCloseSound.php b/src/world/sound/EnderChestCloseSound.php index 4292dec358..3b72698219 100644 --- a/src/world/sound/EnderChestCloseSound.php +++ b/src/world/sound/EnderChestCloseSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class EnderChestCloseSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_ENDERCHEST_CLOSED, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::ENDERCHEST_CLOSED, $pos, false)]; } } diff --git a/src/world/sound/EnderChestOpenSound.php b/src/world/sound/EnderChestOpenSound.php index ab1894450d..6d88ac1f5a 100644 --- a/src/world/sound/EnderChestOpenSound.php +++ b/src/world/sound/EnderChestOpenSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class EnderChestOpenSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_ENDERCHEST_OPEN, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::ENDERCHEST_OPEN, $pos, false)]; } } diff --git a/src/world/sound/EndermanTeleportSound.php b/src/world/sound/EndermanTeleportSound.php index e2f3f03e82..a5857aab25 100644 --- a/src/world/sound/EndermanTeleportSound.php +++ b/src/world/sound/EndermanTeleportSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class EndermanTeleportSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ENDERMAN_TELEPORT, 0, $pos)]; + return [LevelEventPacket::create(LevelEvent::SOUND_ENDERMAN_TELEPORT, 0, $pos)]; } } diff --git a/src/world/sound/EntityAttackNoDamageSound.php b/src/world/sound/EntityAttackNoDamageSound.php index 2ab77a2418..d329147f60 100644 --- a/src/world/sound/EntityAttackNoDamageSound.php +++ b/src/world/sound/EntityAttackNoDamageSound.php @@ -25,6 +25,7 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; /** * Played when a player attacks a mob, but fails to deal damage (e.g. cancelled or attack cooldown). @@ -33,7 +34,7 @@ class EntityAttackNoDamageSound implements Sound{ public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::create( - LevelSoundEventPacket::SOUND_ATTACK_NODAMAGE, + LevelSoundEvent::ATTACK_NODAMAGE, $pos, -1, "minecraft:player", diff --git a/src/world/sound/EntityAttackSound.php b/src/world/sound/EntityAttackSound.php index ecf39a888f..289f2d597f 100644 --- a/src/world/sound/EntityAttackSound.php +++ b/src/world/sound/EntityAttackSound.php @@ -25,6 +25,7 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; /** * Played when a player attacks a mob, dealing damage. @@ -33,7 +34,7 @@ class EntityAttackSound implements Sound{ public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::create( - LevelSoundEventPacket::SOUND_ATTACK_STRONG, //TODO: seems like ATTACK is dysfunctional + LevelSoundEvent::ATTACK_STRONG, //TODO: seems like ATTACK is dysfunctional $pos, -1, "minecraft:player", diff --git a/src/world/sound/EntityLandSound.php b/src/world/sound/EntityLandSound.php index 38ba283fc5..a973e3ba5d 100644 --- a/src/world/sound/EntityLandSound.php +++ b/src/world/sound/EntityLandSound.php @@ -28,6 +28,7 @@ use pocketmine\entity\Entity; use pocketmine\math\Vector3; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; /** * Played when an entity hits the ground after falling a distance that doesn't cause damage, e.g. due to jumping. @@ -46,7 +47,7 @@ class EntityLandSound implements Sound{ public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::create( - LevelSoundEventPacket::SOUND_LAND, + LevelSoundEvent::LAND, $pos, RuntimeBlockMapping::getInstance()->toRuntimeId($this->blockLandedOn->getFullId()), $this->entity::getNetworkTypeId(), diff --git a/src/world/sound/EntityLongFallSound.php b/src/world/sound/EntityLongFallSound.php index 1d0a07f405..c6cd2a33af 100644 --- a/src/world/sound/EntityLongFallSound.php +++ b/src/world/sound/EntityLongFallSound.php @@ -26,6 +26,7 @@ namespace pocketmine\world\sound; use pocketmine\entity\Entity; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; /** * Played when an entity hits ground after falling a long distance (damage). @@ -42,7 +43,7 @@ class EntityLongFallSound implements Sound{ public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::create( - LevelSoundEventPacket::SOUND_FALL_BIG, + LevelSoundEvent::FALL_BIG, $pos, -1, $this->entity::getNetworkTypeId(), diff --git a/src/world/sound/EntityShortFallSound.php b/src/world/sound/EntityShortFallSound.php index 2f64cc269c..722a3c1a3c 100644 --- a/src/world/sound/EntityShortFallSound.php +++ b/src/world/sound/EntityShortFallSound.php @@ -26,6 +26,7 @@ namespace pocketmine\world\sound; use pocketmine\entity\Entity; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; /** * Played when an entity hits the ground after falling a short distance. @@ -41,7 +42,7 @@ class EntityShortFallSound implements Sound{ public function encode(Vector3 $pos) : array{ return [LevelSoundEventPacket::create( - LevelSoundEventPacket::SOUND_FALL_SMALL, + LevelSoundEvent::FALL_SMALL, $pos, -1, $this->entity::getNetworkTypeId(), diff --git a/src/world/sound/ExplodeSound.php b/src/world/sound/ExplodeSound.php index 1f2db9c894..b20f5a3592 100644 --- a/src/world/sound/ExplodeSound.php +++ b/src/world/sound/ExplodeSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class ExplodeSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_EXPLODE, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::EXPLODE, $pos, false)]; } } diff --git a/src/world/sound/FireExtinguishSound.php b/src/world/sound/FireExtinguishSound.php index 255e821f9a..a4f02fb035 100644 --- a/src/world/sound/FireExtinguishSound.php +++ b/src/world/sound/FireExtinguishSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; final class FireExtinguishSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_EXTINGUISH_FIRE, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::EXTINGUISH_FIRE, $pos, false)]; } } diff --git a/src/world/sound/FizzSound.php b/src/world/sound/FizzSound.php index 67be8db447..62b54ee16d 100644 --- a/src/world/sound/FizzSound.php +++ b/src/world/sound/FizzSound.php @@ -25,6 +25,7 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class FizzSound implements Sound{ @@ -40,6 +41,6 @@ class FizzSound implements Sound{ } public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_FIZZ, (int) ($this->pitch * 1000), $pos)]; + return [LevelEventPacket::create(LevelEvent::SOUND_FIZZ, (int) ($this->pitch * 1000), $pos)]; } } diff --git a/src/world/sound/FlintSteelSound.php b/src/world/sound/FlintSteelSound.php index 4569ed5101..7edd564cf3 100644 --- a/src/world/sound/FlintSteelSound.php +++ b/src/world/sound/FlintSteelSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class FlintSteelSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_IGNITE, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::IGNITE, $pos, false)]; } } diff --git a/src/world/sound/GhastShootSound.php b/src/world/sound/GhastShootSound.php index e7cb550ffc..3dae9758f0 100644 --- a/src/world/sound/GhastShootSound.php +++ b/src/world/sound/GhastShootSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class GhastShootSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_GHAST_SHOOT, 0, $pos)]; + return [LevelEventPacket::create(LevelEvent::SOUND_GHAST_SHOOT, 0, $pos)]; } } diff --git a/src/world/sound/GhastSound.php b/src/world/sound/GhastSound.php index 2e707d3db0..d62413dac1 100644 --- a/src/world/sound/GhastSound.php +++ b/src/world/sound/GhastSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class GhastSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_GHAST, 0, $pos)]; + return [LevelEventPacket::create(LevelEvent::SOUND_GHAST, 0, $pos)]; } } diff --git a/src/world/sound/IgniteSound.php b/src/world/sound/IgniteSound.php index 1f1e887036..05f443123c 100644 --- a/src/world/sound/IgniteSound.php +++ b/src/world/sound/IgniteSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class IgniteSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_IGNITE, 0, $pos)]; + return [LevelEventPacket::create(LevelEvent::SOUND_IGNITE, 0, $pos)]; } } diff --git a/src/world/sound/ItemBreakSound.php b/src/world/sound/ItemBreakSound.php index c2329ce121..98ee24c8bd 100644 --- a/src/world/sound/ItemBreakSound.php +++ b/src/world/sound/ItemBreakSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class ItemBreakSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_BREAK, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::BREAK, $pos, false)]; } } diff --git a/src/world/sound/LaunchSound.php b/src/world/sound/LaunchSound.php index af8b02041a..11ef5ad1d7 100644 --- a/src/world/sound/LaunchSound.php +++ b/src/world/sound/LaunchSound.php @@ -25,6 +25,7 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class LaunchSound implements Sound{ @@ -40,6 +41,6 @@ class LaunchSound implements Sound{ } public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_SHOOT, (int) ($this->pitch * 1000), $pos)]; + return [LevelEventPacket::create(LevelEvent::SOUND_SHOOT, (int) ($this->pitch * 1000), $pos)]; } } diff --git a/src/world/sound/NoteSound.php b/src/world/sound/NoteSound.php index 7d2bdef428..00101b8d77 100644 --- a/src/world/sound/NoteSound.php +++ b/src/world/sound/NoteSound.php @@ -25,6 +25,7 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class NoteSound implements Sound{ @@ -42,6 +43,6 @@ class NoteSound implements Sound{ } public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_NOTE, $pos, false, ($this->instrument->getMagicNumber() << 8) | $this->note)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::NOTE, $pos, false, ($this->instrument->getMagicNumber() << 8) | $this->note)]; } } diff --git a/src/world/sound/PaintingPlaceSound.php b/src/world/sound/PaintingPlaceSound.php index 6d9a7ebe39..2363299f39 100644 --- a/src/world/sound/PaintingPlaceSound.php +++ b/src/world/sound/PaintingPlaceSound.php @@ -25,11 +25,12 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class PaintingPlaceSound implements Sound{ public function encode(Vector3 $pos) : array{ //item frame and painting have the same sound - return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ITEMFRAME_PLACE, 0, $pos)]; + return [LevelEventPacket::create(LevelEvent::SOUND_ITEMFRAME_PLACE, 0, $pos)]; } } diff --git a/src/world/sound/PopSound.php b/src/world/sound/PopSound.php index 421018333c..a706e6d033 100644 --- a/src/world/sound/PopSound.php +++ b/src/world/sound/PopSound.php @@ -25,6 +25,7 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class PopSound implements Sound{ @@ -40,6 +41,6 @@ class PopSound implements Sound{ } public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_POP, (int) ($this->pitch * 1000), $pos)]; + return [LevelEventPacket::create(LevelEvent::SOUND_POP, (int) ($this->pitch * 1000), $pos)]; } } diff --git a/src/world/sound/PotionSplashSound.php b/src/world/sound/PotionSplashSound.php index 2547f2aeeb..083e8e0210 100644 --- a/src/world/sound/PotionSplashSound.php +++ b/src/world/sound/PotionSplashSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class PotionSplashSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_GLASS, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::GLASS, $pos, false)]; } } diff --git a/src/world/sound/RecordStopSound.php b/src/world/sound/RecordStopSound.php index 9e331a9ffe..0f2b7dcc9d 100644 --- a/src/world/sound/RecordStopSound.php +++ b/src/world/sound/RecordStopSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class RecordStopSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_STOP_RECORD, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::STOP_RECORD, $pos, false)]; } } diff --git a/src/world/sound/RedstonePowerOffSound.php b/src/world/sound/RedstonePowerOffSound.php index b07c723b4c..d32ef391eb 100644 --- a/src/world/sound/RedstonePowerOffSound.php +++ b/src/world/sound/RedstonePowerOffSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class RedstonePowerOffSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_POWER_OFF, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::POWER_OFF, $pos, false)]; } } diff --git a/src/world/sound/RedstonePowerOnSound.php b/src/world/sound/RedstonePowerOnSound.php index d71f6b998e..3c98832ee9 100644 --- a/src/world/sound/RedstonePowerOnSound.php +++ b/src/world/sound/RedstonePowerOnSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class RedstonePowerOnSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_POWER_ON, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::POWER_ON, $pos, false)]; } } diff --git a/src/world/sound/ShulkerBoxCloseSound.php b/src/world/sound/ShulkerBoxCloseSound.php index ea7a630c3e..6c8ace7834 100644 --- a/src/world/sound/ShulkerBoxCloseSound.php +++ b/src/world/sound/ShulkerBoxCloseSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class ShulkerBoxCloseSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_SHULKERBOX_CLOSED, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::SHULKERBOX_CLOSED, $pos, false)]; } } diff --git a/src/world/sound/ShulkerBoxOpenSound.php b/src/world/sound/ShulkerBoxOpenSound.php index 491b5dace1..9aafb95ce9 100644 --- a/src/world/sound/ShulkerBoxOpenSound.php +++ b/src/world/sound/ShulkerBoxOpenSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class ShulkerBoxOpenSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_SHULKERBOX_OPEN, $pos, false)]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::SHULKERBOX_OPEN, $pos, false)]; } } diff --git a/src/world/sound/ThrowSound.php b/src/world/sound/ThrowSound.php index b24474e5fb..5ac34cbe62 100644 --- a/src/world/sound/ThrowSound.php +++ b/src/world/sound/ThrowSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; class ThrowSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelSoundEventPacket::create(LevelSoundEventPacket::SOUND_THROW, $pos, -1, "minecraft:player", false, false)]; + return [LevelSoundEventPacket::create(LevelSoundEvent::THROW, $pos, -1, "minecraft:player", false, false)]; } } diff --git a/src/world/sound/TotemUseSound.php b/src/world/sound/TotemUseSound.php index 561d9c41ab..7d82c31106 100644 --- a/src/world/sound/TotemUseSound.php +++ b/src/world/sound/TotemUseSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class TotemUseSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_TOTEM, 0, $pos)]; + return [LevelEventPacket::create(LevelEvent::SOUND_TOTEM, 0, $pos)]; } } diff --git a/src/world/sound/XpCollectSound.php b/src/world/sound/XpCollectSound.php index 655835069e..bbf60041bc 100644 --- a/src/world/sound/XpCollectSound.php +++ b/src/world/sound/XpCollectSound.php @@ -25,10 +25,11 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelEvent; class XpCollectSound implements Sound{ public function encode(Vector3 $pos) : array{ - return [LevelEventPacket::create(LevelEventPacket::EVENT_SOUND_ORB, 0, $pos)]; + return [LevelEventPacket::create(LevelEvent::SOUND_ORB, 0, $pos)]; } } diff --git a/src/world/sound/XpLevelUpSound.php b/src/world/sound/XpLevelUpSound.php index 8334b7bead..b9e2737b2a 100644 --- a/src/world/sound/XpLevelUpSound.php +++ b/src/world/sound/XpLevelUpSound.php @@ -25,6 +25,7 @@ namespace pocketmine\world\sound; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; +use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; use function intdiv; use function min; @@ -44,6 +45,6 @@ class XpLevelUpSound implements Sound{ public function encode(Vector3 $pos) : array{ //No idea why such odd numbers, but this works... //TODO: check arbitrary volume - return [LevelSoundEventPacket::nonActorSound(LevelSoundEventPacket::SOUND_LEVELUP, $pos, false, 0x10000000 * intdiv(min(30, $this->xpLevel), 5))]; + return [LevelSoundEventPacket::nonActorSound(LevelSoundEvent::LEVELUP, $pos, false, 0x10000000 * intdiv(min(30, $this->xpLevel), 5))]; } } From 42ede30e77bb0f66f8f40023aa4329b9b89dc312 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Oct 2021 23:57:28 +0100 Subject: [PATCH 3012/3224] ... --- src/block/utils/RecordType.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/block/utils/RecordType.php b/src/block/utils/RecordType.php index 967cdc0349..e497d419ce 100644 --- a/src/block/utils/RecordType.php +++ b/src/block/utils/RecordType.php @@ -25,7 +25,6 @@ namespace pocketmine\block\utils; use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\Translatable; -use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\types\LevelSoundEvent; use pocketmine\utils\EnumTrait; From b8519d1af4a9ff2182c15da29e715a2d506150e8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 25 Oct 2021 19:49:35 +0100 Subject: [PATCH 3013/3224] World: fixed every chunk having terrain saved at least once, even if unmodified setPopulated() sets dirty flags on the chunk, causing the autosave sweep to think they've been changed when they haven't. We now pass terrainPopulated to the constructor to avoid this ambiguity recurring in the future. --- src/world/format/Chunk.php | 4 +++- src/world/format/io/FastChunkSerializer.php | 6 +----- src/world/format/io/leveldb/LevelDB.php | 21 +++++++++++-------- .../io/region/LegacyAnvilChunkTrait.php | 12 +++++------ src/world/format/io/region/McRegion.php | 9 +++++--- 5 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index c90c18482f..fe37161b81 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -69,7 +69,7 @@ class Chunk{ /** * @param SubChunk[] $subChunks */ - public function __construct(array $subChunks = [], ?BiomeArray $biomeIds = null, ?HeightArray $heightMap = null){ + public function __construct(array $subChunks = [], ?BiomeArray $biomeIds = null, ?HeightArray $heightMap = null, bool $terrainPopulated = false){ $this->subChunks = new \SplFixedArray(Chunk::MAX_SUBCHUNKS); foreach($this->subChunks as $y => $null){ @@ -79,6 +79,8 @@ class Chunk{ $val = ($this->subChunks->getSize() * SubChunk::EDGE_LENGTH); $this->heightMap = $heightMap ?? new HeightArray(array_fill(0, 256, $val)); $this->biomeIds = $biomeIds ?? BiomeArray::fill(BiomeIds::OCEAN); + + $this->terrainPopulated = $terrainPopulated; } /** diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index cc85444115..62a22352ed 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -115,10 +115,6 @@ final class FastChunkSerializer{ $biomeIds = new BiomeArray($stream->get(256)); - $chunk = new Chunk($subChunks, $biomeIds); - $chunk->setPopulated($terrainPopulated); - $chunk->clearTerrainDirtyFlags(); - - return $chunk; + return new Chunk($subChunks, $biomeIds, null, $terrainPopulated); } } diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 6713818ac7..2ab5ef0cb6 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -404,20 +404,23 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ } } - $chunk = new Chunk( - $subChunks, - $biomeArray - ); - - //TODO: tile ticks, biome states (?) - $finalisationChr = $this->db->get($index . self::TAG_STATE_FINALISATION); if($finalisationChr !== false){ $finalisation = ord($finalisationChr); - $chunk->setPopulated($finalisation === self::FINALISATION_DONE); + $terrainPopulated = $finalisation === self::FINALISATION_DONE; }else{ //older versions didn't have this tag - $chunk->setPopulated(); + $terrainPopulated = true; } + + //TODO: tile ticks, biome states (?) + + $chunk = new Chunk( + $subChunks, + $biomeArray, + null, + $terrainPopulated + ); + if($hasBeenUpgraded){ $chunk->setTerrainDirty(); //trigger rewriting chunk to disk if it was converted from an older format } diff --git a/src/world/format/io/region/LegacyAnvilChunkTrait.php b/src/world/format/io/region/LegacyAnvilChunkTrait.php index 831f02b18a..4f6ce4123f 100644 --- a/src/world/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/world/format/io/region/LegacyAnvilChunkTrait.php @@ -88,13 +88,13 @@ trait LegacyAnvilChunkTrait{ $biomeArray = $makeBiomeArray($biomesTag->getValue()); } - $result = new Chunk( - $subChunks, - $biomeArray - ); - $result->setPopulated($chunk->getByte("TerrainPopulated", 0) !== 0); return new ChunkData( - $result, + new Chunk( + $subChunks, + $biomeArray, + null, + $chunk->getByte("TerrainPopulated", 0) !== 0 + ), ($entitiesTag = $chunk->getTag("Entities")) instanceof ListTag ? self::getCompoundList("Entities", $entitiesTag) : [], ($tilesTag = $chunk->getTag("TileEntities")) instanceof ListTag ? self::getCompoundList("TileEntities", $tilesTag) : [], ); diff --git a/src/world/format/io/region/McRegion.php b/src/world/format/io/region/McRegion.php index aab62a3db3..0aac961590 100644 --- a/src/world/format/io/region/McRegion.php +++ b/src/world/format/io/region/McRegion.php @@ -82,10 +82,13 @@ class McRegion extends RegionWorldProvider{ $biomeIds = $makeBiomeArray($biomesTag->getValue()); } - $result = new Chunk($subChunks, $biomeIds); - $result->setPopulated($chunk->getByte("TerrainPopulated", 0) !== 0); return new ChunkData( - $result, + new Chunk( + $subChunks, + $biomeIds, + null, + $chunk->getByte("TerrainPopulated", 0) !== 0 + ), ($entitiesTag = $chunk->getTag("Entities")) instanceof ListTag ? self::getCompoundList("Entities", $entitiesTag) : [], ($tilesTag = $chunk->getTag("TileEntities")) instanceof ListTag ? self::getCompoundList("TileEntities", $tilesTag) : [], ); From 9835d75f65570b4bb5baf68c6127147ae7b324c7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 25 Oct 2021 20:13:50 +0100 Subject: [PATCH 3014/3224] Chunk: removed heighArray parameter from constructor we don't pass this anywhere, and really it should be dynamically initialized anyway, just like light. --- src/world/format/Chunk.php | 4 ++-- src/world/format/io/FastChunkSerializer.php | 2 +- src/world/format/io/leveldb/LevelDB.php | 1 - src/world/format/io/region/LegacyAnvilChunkTrait.php | 1 - src/world/format/io/region/McRegion.php | 1 - 5 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index fe37161b81..42daa1bcba 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -69,7 +69,7 @@ class Chunk{ /** * @param SubChunk[] $subChunks */ - public function __construct(array $subChunks = [], ?BiomeArray $biomeIds = null, ?HeightArray $heightMap = null, bool $terrainPopulated = false){ + public function __construct(array $subChunks = [], ?BiomeArray $biomeIds = null, bool $terrainPopulated = false){ $this->subChunks = new \SplFixedArray(Chunk::MAX_SUBCHUNKS); foreach($this->subChunks as $y => $null){ @@ -77,7 +77,7 @@ class Chunk{ } $val = ($this->subChunks->getSize() * SubChunk::EDGE_LENGTH); - $this->heightMap = $heightMap ?? new HeightArray(array_fill(0, 256, $val)); + $this->heightMap = new HeightArray(array_fill(0, 256, $val)); //TODO: what about lazily initializing this? $this->biomeIds = $biomeIds ?? BiomeArray::fill(BiomeIds::OCEAN); $this->terrainPopulated = $terrainPopulated; diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index 62a22352ed..bb8bec687a 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -115,6 +115,6 @@ final class FastChunkSerializer{ $biomeIds = new BiomeArray($stream->get(256)); - return new Chunk($subChunks, $biomeIds, null, $terrainPopulated); + return new Chunk($subChunks, $biomeIds, $terrainPopulated); } } diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 2ab5ef0cb6..17f42f7bdd 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -417,7 +417,6 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $chunk = new Chunk( $subChunks, $biomeArray, - null, $terrainPopulated ); diff --git a/src/world/format/io/region/LegacyAnvilChunkTrait.php b/src/world/format/io/region/LegacyAnvilChunkTrait.php index 4f6ce4123f..a7181718fd 100644 --- a/src/world/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/world/format/io/region/LegacyAnvilChunkTrait.php @@ -92,7 +92,6 @@ trait LegacyAnvilChunkTrait{ new Chunk( $subChunks, $biomeArray, - null, $chunk->getByte("TerrainPopulated", 0) !== 0 ), ($entitiesTag = $chunk->getTag("Entities")) instanceof ListTag ? self::getCompoundList("Entities", $entitiesTag) : [], diff --git a/src/world/format/io/region/McRegion.php b/src/world/format/io/region/McRegion.php index 0aac961590..d4864f934c 100644 --- a/src/world/format/io/region/McRegion.php +++ b/src/world/format/io/region/McRegion.php @@ -86,7 +86,6 @@ class McRegion extends RegionWorldProvider{ new Chunk( $subChunks, $biomeIds, - null, $chunk->getByte("TerrainPopulated", 0) !== 0 ), ($entitiesTag = $chunk->getTag("Entities")) instanceof ListTag ? self::getCompoundList("Entities", $entitiesTag) : [], From 401e8d117b4f6c26a4ea71c64994b90af15bc29c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 25 Oct 2021 20:15:33 +0100 Subject: [PATCH 3015/3224] Flat: use a less dumb way to build biome array --- src/world/generator/Flat.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/world/generator/Flat.php b/src/world/generator/Flat.php index fff96db945..39d782de3b 100644 --- a/src/world/generator/Flat.php +++ b/src/world/generator/Flat.php @@ -25,6 +25,7 @@ namespace pocketmine\world\generator; use pocketmine\block\VanillaBlocks; use pocketmine\world\ChunkManager; +use pocketmine\world\format\BiomeArray; use pocketmine\world\format\Chunk; use pocketmine\world\format\SubChunk; use pocketmine\world\generator\object\OreType; @@ -68,14 +69,7 @@ class Flat extends Generator{ } protected function generateBaseChunk() : void{ - $this->chunk = new Chunk(); - - $biomeId = $this->options->getBiomeId(); - for($Z = 0; $Z < Chunk::EDGE_LENGTH; ++$Z){ - for($X = 0; $X < Chunk::EDGE_LENGTH; ++$X){ - $this->chunk->setBiomeId($X, $Z, $biomeId); - } - } + $this->chunk = new Chunk([], BiomeArray::fill($this->options->getBiomeId())); $structure = $this->options->getStructure(); $count = count($structure); From d53347454bf9b6fb21f8fc7e74a5b68c0c2abbc3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 25 Oct 2021 20:17:17 +0100 Subject: [PATCH 3016/3224] Chunk: use HeightArray::fill() --- src/world/format/Chunk.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 42daa1bcba..c287823d49 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -30,7 +30,6 @@ use pocketmine\block\Block; use pocketmine\block\BlockLegacyIds; use pocketmine\block\tile\Tile; use pocketmine\data\bedrock\BiomeIds; -use function array_fill; use function array_map; class Chunk{ @@ -77,7 +76,7 @@ class Chunk{ } $val = ($this->subChunks->getSize() * SubChunk::EDGE_LENGTH); - $this->heightMap = new HeightArray(array_fill(0, 256, $val)); //TODO: what about lazily initializing this? + $this->heightMap = HeightArray::fill($val); //TODO: what about lazily initializing this? $this->biomeIds = $biomeIds ?? BiomeArray::fill(BiomeIds::OCEAN); $this->terrainPopulated = $terrainPopulated; From baba25953fe8a1cbce745a94e645cce62d4e0e59 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 25 Oct 2021 20:22:50 +0100 Subject: [PATCH 3017/3224] Chunk: make all parameters of __construct() mandatory and non-nullable having the constructor fill in defaults for these invariably causes bugs. --- src/world/format/Chunk.php | 4 ++-- src/world/format/io/leveldb/LevelDB.php | 3 ++- src/world/format/io/region/LegacyAnvilChunkTrait.php | 3 +++ src/world/format/io/region/McRegion.php | 3 +++ src/world/generator/Flat.php | 2 +- src/world/generator/PopulationTask.php | 4 +++- tests/phpunit/world/format/ChunkTest.php | 3 ++- 7 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index c287823d49..9f001fd37d 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -68,7 +68,7 @@ class Chunk{ /** * @param SubChunk[] $subChunks */ - public function __construct(array $subChunks = [], ?BiomeArray $biomeIds = null, bool $terrainPopulated = false){ + public function __construct(array $subChunks, BiomeArray $biomeIds, bool $terrainPopulated){ $this->subChunks = new \SplFixedArray(Chunk::MAX_SUBCHUNKS); foreach($this->subChunks as $y => $null){ @@ -77,7 +77,7 @@ class Chunk{ $val = ($this->subChunks->getSize() * SubChunk::EDGE_LENGTH); $this->heightMap = HeightArray::fill($val); //TODO: what about lazily initializing this? - $this->biomeIds = $biomeIds ?? BiomeArray::fill(BiomeIds::OCEAN); + $this->biomeIds = $biomeIds; $this->terrainPopulated = $terrainPopulated; } diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 17f42f7bdd..54433214e6 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -25,6 +25,7 @@ namespace pocketmine\world\format\io\leveldb; use pocketmine\block\Block; use pocketmine\block\BlockLegacyIds; +use pocketmine\data\bedrock\BiomeIds; use pocketmine\data\bedrock\LegacyBlockIdToStringIdMap; use pocketmine\nbt\LittleEndianNbtSerializer; use pocketmine\nbt\NbtDataException; @@ -416,7 +417,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $chunk = new Chunk( $subChunks, - $biomeArray, + $biomeArray ?? BiomeArray::fill(BiomeIds::OCEAN), //TODO: maybe missing biomes should be an error? $terrainPopulated ); diff --git a/src/world/format/io/region/LegacyAnvilChunkTrait.php b/src/world/format/io/region/LegacyAnvilChunkTrait.php index a7181718fd..8970a2fb3b 100644 --- a/src/world/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/world/format/io/region/LegacyAnvilChunkTrait.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\format\io\region; +use pocketmine\data\bedrock\BiomeIds; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\ByteArrayTag; @@ -86,6 +87,8 @@ trait LegacyAnvilChunkTrait{ $biomeArray = $makeBiomeArray(ChunkUtils::convertBiomeColors($biomeColorsTag->getValue())); //Convert back to original format }elseif(($biomesTag = $chunk->getTag("Biomes")) instanceof ByteArrayTag){ $biomeArray = $makeBiomeArray($biomesTag->getValue()); + }else{ + $biomeArray = BiomeArray::fill(BiomeIds::OCEAN); } return new ChunkData( diff --git a/src/world/format/io/region/McRegion.php b/src/world/format/io/region/McRegion.php index d4864f934c..3367a2f817 100644 --- a/src/world/format/io/region/McRegion.php +++ b/src/world/format/io/region/McRegion.php @@ -25,6 +25,7 @@ namespace pocketmine\world\format\io\region; use pocketmine\block\Block; use pocketmine\block\BlockLegacyIds; +use pocketmine\data\bedrock\BiomeIds; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\ByteArrayTag; @@ -80,6 +81,8 @@ class McRegion extends RegionWorldProvider{ $biomeIds = $makeBiomeArray(ChunkUtils::convertBiomeColors($biomeColorsTag->getValue())); //Convert back to original format }elseif(($biomesTag = $chunk->getTag("Biomes")) instanceof ByteArrayTag){ $biomeIds = $makeBiomeArray($biomesTag->getValue()); + }else{ + $biomeIds = BiomeArray::fill(BiomeIds::OCEAN); } return new ChunkData( diff --git a/src/world/generator/Flat.php b/src/world/generator/Flat.php index 39d782de3b..26a658b6d6 100644 --- a/src/world/generator/Flat.php +++ b/src/world/generator/Flat.php @@ -69,7 +69,7 @@ class Flat extends Generator{ } protected function generateBaseChunk() : void{ - $this->chunk = new Chunk([], BiomeArray::fill($this->options->getBiomeId())); + $this->chunk = new Chunk([], BiomeArray::fill($this->options->getBiomeId()), false); $structure = $this->options->getStructure(); $count = count($structure); diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 5af9ed6502..74594c879f 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\world\generator; +use pocketmine\data\bedrock\BiomeIds; use pocketmine\scheduler\AsyncTask; use pocketmine\utils\AssumptionFailedError; +use pocketmine\world\format\BiomeArray; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\FastChunkSerializer; use pocketmine\world\SimpleChunkManager; @@ -127,7 +129,7 @@ class PopulationTask extends AsyncTask{ } private static function setOrGenerateChunk(SimpleChunkManager $manager, Generator $generator, int $chunkX, int $chunkZ, ?Chunk $chunk) : Chunk{ - $manager->setChunk($chunkX, $chunkZ, $chunk ?? new Chunk()); + $manager->setChunk($chunkX, $chunkZ, $chunk ?? new Chunk([], BiomeArray::fill(BiomeIds::OCEAN), false)); if($chunk === null){ $generator->generateChunk($manager, $chunkX, $chunkZ); $chunk = $manager->getChunk($chunkX, $chunkZ); diff --git a/tests/phpunit/world/format/ChunkTest.php b/tests/phpunit/world/format/ChunkTest.php index c557c65c3e..5d12f7dd2e 100644 --- a/tests/phpunit/world/format/ChunkTest.php +++ b/tests/phpunit/world/format/ChunkTest.php @@ -24,11 +24,12 @@ declare(strict_types=1); namespace pocketmine\world\format; use PHPUnit\Framework\TestCase; +use pocketmine\data\bedrock\BiomeIds; class ChunkTest extends TestCase{ public function testClone() : void{ - $chunk = new Chunk(); + $chunk = new Chunk([], BiomeArray::fill(BiomeIds::OCEAN), false); $chunk->setFullBlock(0, 0, 0, 1); $chunk->setBiomeId(0, 0, 1); $chunk->setHeightMap(0, 0, 1); From a5418a019dc2a83210084632130db8ce06f529ea Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 25 Oct 2021 20:53:11 +0100 Subject: [PATCH 3018/3224] Chunk: added modification counter this is independent from the terrain dirty flags (which are specifically used to track state of chunks needing to be saved). --- src/world/format/Chunk.php | 16 +++++++++++++++- src/world/format/io/FastChunkSerializer.php | 5 ++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 9f001fd37d..2bef86b263 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -42,6 +42,8 @@ class Chunk{ public const COORD_BIT_SIZE = SubChunk::COORD_BIT_SIZE; public const COORD_MASK = SubChunk::COORD_MASK; + private int $modificationCount; + /** @var int */ private $terrainDirtyFlags = 0; @@ -68,7 +70,7 @@ class Chunk{ /** * @param SubChunk[] $subChunks */ - public function __construct(array $subChunks, BiomeArray $biomeIds, bool $terrainPopulated){ + public function __construct(array $subChunks, BiomeArray $biomeIds, bool $terrainPopulated, int $modificationCount = 0){ $this->subChunks = new \SplFixedArray(Chunk::MAX_SUBCHUNKS); foreach($this->subChunks as $y => $null){ @@ -80,6 +82,7 @@ class Chunk{ $this->biomeIds = $biomeIds; $this->terrainPopulated = $terrainPopulated; + $this->modificationCount = $modificationCount; } /** @@ -108,6 +111,7 @@ class Chunk{ public function setFullBlock(int $x, int $y, int $z, int $block) : void{ $this->getSubChunk($y >> SubChunk::COORD_BIT_SIZE)->setFullBlock($x, $y & SubChunk::COORD_MASK, $z, $block); $this->terrainDirtyFlags |= self::DIRTY_FLAG_TERRAIN; + $this->modificationCount++; } /** @@ -171,6 +175,7 @@ class Chunk{ public function setBiomeId(int $x, int $z, int $biomeId) : void{ $this->biomeIds->set($x, $z, $biomeId); $this->terrainDirtyFlags |= self::DIRTY_FLAG_BIOMES; + $this->modificationCount++; } public function isLightPopulated() : ?bool{ @@ -188,6 +193,7 @@ class Chunk{ public function setPopulated(bool $value = true) : void{ $this->terrainPopulated = $value; $this->terrainDirtyFlags |= self::DIRTY_FLAG_TERRAIN; + $this->modificationCount++; } public function addTile(Tile $tile) : void{ @@ -270,16 +276,24 @@ class Chunk{ }else{ $this->terrainDirtyFlags &= ~$flag; } + $this->modificationCount++; } public function setTerrainDirty() : void{ $this->terrainDirtyFlags = ~0; + $this->modificationCount++; } public function clearTerrainDirtyFlags() : void{ $this->terrainDirtyFlags = 0; } + /** + * Returns the modcount for this chunk. Any saveable change to the chunk will cause this number to be incremented, + * so you can use this to detect when the chunk has been modified. + */ + public function getModificationCount() : int{ return $this->modificationCount; } + public function getSubChunk(int $y) : SubChunk{ if($y < 0 || $y >= $this->subChunks->getSize()){ throw new \InvalidArgumentException("Invalid subchunk Y coordinate $y"); diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index bb8bec687a..0f3db73d18 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -51,6 +51,8 @@ final class FastChunkSerializer{ */ public static function serializeTerrain(Chunk $chunk) : string{ $stream = new BinaryStream(); + $stream->putLong($chunk->getModificationCount()); + $stream->putByte( ($chunk->isPopulated() ? self::FLAG_POPULATED : 0) ); @@ -88,6 +90,7 @@ final class FastChunkSerializer{ */ public static function deserializeTerrain(string $data) : Chunk{ $stream = new BinaryStream($data); + $modificationCounter = $stream->getLong(); $flags = $stream->getByte(); $terrainPopulated = (bool) ($flags & self::FLAG_POPULATED); @@ -115,6 +118,6 @@ final class FastChunkSerializer{ $biomeIds = new BiomeArray($stream->get(256)); - return new Chunk($subChunks, $biomeIds, $terrainPopulated); + return new Chunk($subChunks, $biomeIds, $terrainPopulated, $modificationCounter); } } From d4cbde6f100e82da6e40f98c9ff0d5fabe8413c5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 25 Oct 2021 20:53:50 +0100 Subject: [PATCH 3019/3224] PopulationTask: use modification counters to detect changed chunks instead of using terrain dirty flags, which aren't suitable for this purpose --- src/world/generator/PopulationTask.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 74594c879f..ad0602efca 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -89,6 +89,7 @@ class PopulationTask extends AsyncTask{ /** @var Chunk[] $chunks */ $chunks = []; + $oldModCounts = []; $chunk = $this->chunk !== null ? FastChunkSerializer::deserializeTerrain($this->chunk) : null; @@ -101,6 +102,7 @@ class PopulationTask extends AsyncTask{ $chunks[$i] = null; }else{ $chunks[$i] = FastChunkSerializer::deserializeTerrain($ck); + $oldModCounts[$i] = $chunks[$i]->getModificationCount(); } } @@ -124,7 +126,8 @@ class PopulationTask extends AsyncTask{ $this->chunk = FastChunkSerializer::serializeTerrain($chunk); foreach($chunks as $i => $c){ - $this->{"chunk$i"} = $c->isTerrainDirty() ? FastChunkSerializer::serializeTerrain($c) : null; + $oldModCount = $oldModCounts[$i] ?? 0; + $this->{"chunk$i"} = $oldModCount !== $c->getModificationCounter() ? FastChunkSerializer::serializeTerrain($c) : null; } } From 359d0835f3e3ce5e19b608916c471ae4b6c843bd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 25 Oct 2021 20:54:39 +0100 Subject: [PATCH 3020/3224] CS --- src/world/format/Chunk.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 2bef86b263..13a84742bf 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -29,7 +29,6 @@ namespace pocketmine\world\format; use pocketmine\block\Block; use pocketmine\block\BlockLegacyIds; use pocketmine\block\tile\Tile; -use pocketmine\data\bedrock\BiomeIds; use function array_map; class Chunk{ From 2e2515354c707d96b73accd454596f91cd602922 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 25 Oct 2021 20:57:43 +0100 Subject: [PATCH 3021/3224] PopulationTask: fixed undefined method call fuck you PhpStorm! fuck you PhpStorm! fuck you PhpStorm! --- src/world/generator/PopulationTask.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index ad0602efca..2f601a80de 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -127,7 +127,7 @@ class PopulationTask extends AsyncTask{ foreach($chunks as $i => $c){ $oldModCount = $oldModCounts[$i] ?? 0; - $this->{"chunk$i"} = $oldModCount !== $c->getModificationCounter() ? FastChunkSerializer::serializeTerrain($c) : null; + $this->{"chunk$i"} = $oldModCount !== $c->getModificationCount() ? FastChunkSerializer::serializeTerrain($c) : null; } } From 94f4ef5862de594daa21bf3cf51bdd7e48c25e01 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 25 Oct 2021 21:07:03 +0100 Subject: [PATCH 3022/3224] PopulationTask: Throw AssumptionFailedError if center chunk is null for some reason --- src/world/generator/PopulationTask.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 2f601a80de..2cd68ebdea 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -149,7 +149,9 @@ class PopulationTask extends AsyncTask{ /** @var World $world */ $world = $this->fetchLocal(self::TLS_KEY_WORLD); if($world->isLoaded()){ - $chunk = $this->chunk !== null ? FastChunkSerializer::deserializeTerrain($this->chunk) : null; + $chunk = $this->chunk !== null ? + FastChunkSerializer::deserializeTerrain($this->chunk) : + throw new AssumptionFailedError("Center chunk should never be null"); for($i = 0; $i < 9; ++$i){ if($i === 4){ From 4178c812094fac387f0b2ca063a968d93362aaad Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Oct 2021 00:31:30 +0100 Subject: [PATCH 3023/3224] Utils: fixed testValidInstance() not accepting the same valid class for both className and baseName this caused problems in PlayerCreationEvent because plugins set the base class and then set the player class to the same thing. --- src/utils/Utils.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/utils/Utils.php b/src/utils/Utils.php index e8add3c9c0..de1ade0bd0 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -519,12 +519,10 @@ final class Utils{ if(!class_exists($className)){ throw new \InvalidArgumentException("Class $className does not exist"); } - $base = new \ReflectionClass($baseName); - $class = new \ReflectionClass($className); - - if(!$class->isSubclassOf($baseName)){ - throw new \InvalidArgumentException("Class $className does not " . ($base->isInterface() ? "implement" : "extend") . " " . $baseName); + if(!is_a($className, $baseName, true)){ + throw new \InvalidArgumentException("Class $className does not extend or implement $baseName"); } + $class = new \ReflectionClass($className); if(!$class->isInstantiable()){ throw new \InvalidArgumentException("Class $className cannot be constructed"); } From 24d4daec90af7bbfabe11b932217baf1bbb97eda Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Oct 2021 00:32:32 +0100 Subject: [PATCH 3024/3224] Utils::testValidInstance() now accepts interfaces for the baseName --- src/utils/Utils.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/utils/Utils.php b/src/utils/Utils.php index de1ade0bd0..bd4d8ea69e 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -53,6 +53,7 @@ use function get_loaded_extensions; use function getenv; use function gettype; use function implode; +use function interface_exists; use function is_array; use function is_bool; use function is_int; @@ -513,14 +514,18 @@ final class Utils{ * @phpstan-param class-string $baseName */ public static function testValidInstance(string $className, string $baseName) : void{ + $baseInterface = false; if(!class_exists($baseName)){ - throw new \InvalidArgumentException("Base class $baseName does not exist"); + if(!interface_exists($baseName)){ + throw new \InvalidArgumentException("Base class $baseName does not exist"); + } + $baseInterface = true; } if(!class_exists($className)){ - throw new \InvalidArgumentException("Class $className does not exist"); + throw new \InvalidArgumentException("Class $className does not exist or is not a class"); } if(!is_a($className, $baseName, true)){ - throw new \InvalidArgumentException("Class $className does not extend or implement $baseName"); + throw new \InvalidArgumentException("Class $className does not " . ($baseInterface ? "implement" : "extend") . " $baseName"); } $class = new \ReflectionClass($className); if(!$class->isInstantiable()){ From bd8cba1a7fb36185301cbe95458b0bb340fcd6ff Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Oct 2021 00:49:41 +0100 Subject: [PATCH 3025/3224] Added unit tests for Utils::testValidInstance() --- tests/phpunit/utils/UtilsTest.php | 58 +++++++++++++++++++ .../utils/fixtures/TestAbstractClass.php | 7 +++ .../utils/fixtures/TestInstantiableClass.php | 7 +++ .../phpunit/utils/fixtures/TestInterface.php | 7 +++ .../TestSubclassOfInstantiableClass.php | 7 +++ tests/phpunit/utils/fixtures/TestTrait.php | 7 +++ 6 files changed, 93 insertions(+) create mode 100644 tests/phpunit/utils/fixtures/TestAbstractClass.php create mode 100644 tests/phpunit/utils/fixtures/TestInstantiableClass.php create mode 100644 tests/phpunit/utils/fixtures/TestInterface.php create mode 100644 tests/phpunit/utils/fixtures/TestSubclassOfInstantiableClass.php create mode 100644 tests/phpunit/utils/fixtures/TestTrait.php diff --git a/tests/phpunit/utils/UtilsTest.php b/tests/phpunit/utils/UtilsTest.php index 20bb88cdf8..80fe84a455 100644 --- a/tests/phpunit/utils/UtilsTest.php +++ b/tests/phpunit/utils/UtilsTest.php @@ -24,6 +24,11 @@ declare(strict_types=1); namespace pocketmine\utils; use PHPUnit\Framework\TestCase; +use pocketmine\utils\fixtures\TestAbstractClass; +use pocketmine\utils\fixtures\TestInstantiableClass; +use pocketmine\utils\fixtures\TestInterface; +use pocketmine\utils\fixtures\TestSubclassOfInstantiableClass; +use pocketmine\utils\fixtures\TestTrait; use function define; use function defined; @@ -89,4 +94,57 @@ class UtilsTest extends TestCase{ //be careful with this test. The closure has to be declared on the same line as the assertion. self::assertSame('closure@' . Filesystem::cleanPath(__FILE__) . '#L' . __LINE__, Utils::getNiceClosureName(function() : void{})); } + + /** + * @return string[][] + * @return list + */ + public function validInstanceProvider() : array{ + return [ + //direct instance / implement / extend + [TestInstantiableClass::class, TestInstantiableClass::class], + [TestInstantiableClass::class, TestAbstractClass::class], + [TestInstantiableClass::class, TestInterface::class], + + //inherited + [TestSubclassOfInstantiableClass::class, TestInstantiableClass::class], + [TestSubclassOfInstantiableClass::class, TestAbstractClass::class], + [TestSubclassOfInstantiableClass::class, TestInterface::class] + ]; + } + + /** + * @dataProvider validInstanceProvider + * @doesNotPerformAssertions + * @phpstan-param class-string $className + * @phpstan-param class-string $baseName + */ + public function testValidInstanceWithValidCombinations(string $className, string $baseName) : void{ + Utils::testValidInstance($className, $baseName); + } + + /** + * @return string[][] + * @return list + */ + public function validInstanceInvalidCombinationsProvider() : array{ + return [ + ["iDontExist abc", TestInstantiableClass::class], + [TestInstantiableClass::class, "iDon'tExist abc"], + ["iDontExist", "iAlsoDontExist"], + [TestInstantiableClass::class, TestTrait::class], + [TestTrait::class, TestTrait::class], + [TestAbstractClass::class, TestAbstractClass::class], + [TestInterface::class, TestInterface::class], + [TestInstantiableClass::class, TestSubclassOfInstantiableClass::class] + ]; + } + + /** + * @dataProvider validInstanceInvalidCombinationsProvider + */ + public function testValidInstanceInvalidParameters(string $className, string $baseName) : void{ + $this->expectException(\InvalidArgumentException::class); + Utils::testValidInstance($className, $baseName); //@phpstan-ignore-line + } } diff --git a/tests/phpunit/utils/fixtures/TestAbstractClass.php b/tests/phpunit/utils/fixtures/TestAbstractClass.php new file mode 100644 index 0000000000..2384d3eb1d --- /dev/null +++ b/tests/phpunit/utils/fixtures/TestAbstractClass.php @@ -0,0 +1,7 @@ + Date: Tue, 26 Oct 2021 00:50:43 +0100 Subject: [PATCH 3026/3224] CS again --- src/utils/Utils.php | 1 + tests/phpunit/utils/fixtures/TestAbstractClass.php | 2 ++ tests/phpunit/utils/fixtures/TestInstantiableClass.php | 2 ++ tests/phpunit/utils/fixtures/TestInterface.php | 2 ++ .../phpunit/utils/fixtures/TestSubclassOfInstantiableClass.php | 2 ++ tests/phpunit/utils/fixtures/TestTrait.php | 2 ++ 6 files changed, 11 insertions(+) diff --git a/src/utils/Utils.php b/src/utils/Utils.php index bd4d8ea69e..8e8445baa6 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -54,6 +54,7 @@ use function getenv; use function gettype; use function implode; use function interface_exists; +use function is_a; use function is_array; use function is_bool; use function is_int; diff --git a/tests/phpunit/utils/fixtures/TestAbstractClass.php b/tests/phpunit/utils/fixtures/TestAbstractClass.php index 2384d3eb1d..212806c4f4 100644 --- a/tests/phpunit/utils/fixtures/TestAbstractClass.php +++ b/tests/phpunit/utils/fixtures/TestAbstractClass.php @@ -1,5 +1,7 @@ Date: Tue, 26 Oct 2021 01:07:14 +0100 Subject: [PATCH 3027/3224] ConsoleReaderThread: trim the string before returning it it will have a newline at the end that was added by the subprocess when posting it to the main process. --- src/console/ConsoleReaderThread.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/console/ConsoleReaderThread.php b/src/console/ConsoleReaderThread.php index f1cca9bb33..fde505f3c2 100644 --- a/src/console/ConsoleReaderThread.php +++ b/src/console/ConsoleReaderThread.php @@ -39,6 +39,7 @@ use function stream_socket_accept; use function stream_socket_get_name; use function stream_socket_server; use function stream_socket_shutdown; +use function trim; use const PHP_BINARY; use const STREAM_SHUT_RDWR; @@ -113,7 +114,7 @@ final class ConsoleReaderThread extends Thread{ break; } - $buffer[] = preg_replace("#\\x1b\\x5b([^\\x1b]*\\x7e|[\\x40-\\x50])#", "", $command); + $buffer[] = preg_replace("#\\x1b\\x5b([^\\x1b]*\\x7e|[\\x40-\\x50])#", "", trim($command)); if($notifier !== null){ $notifier->wakeupSleeper(); } From 8f883931841e7b73ea7a11dc04c4e28fa5c0f4f3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Oct 2021 15:28:00 +0100 Subject: [PATCH 3028/3224] World: Specialize generateChunkCallback() for PopulationTask this allows us to also set the adjacent chunks before calling ChunkPopulateEvent, to give a more accurate picture of what changed. --- src/world/World.php | 23 +++++++++++------------ src/world/generator/PopulationTask.php | 6 +++--- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 282767e768..d5bca01958 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2145,12 +2145,13 @@ class World implements ChunkManager{ } } - public function generateChunkCallback(int $x, int $z, ?Chunk $chunk) : void{ + /** + * @param Chunk[] $adjacentChunks + * @phpstan-param array $adjacentChunks + */ + public function generateChunkCallback(int $x, int $z, Chunk $chunk, array $adjacentChunks) : void{ Timings::$generationCallback->startTiming(); if(isset($this->chunkPopulationRequestMap[$index = World::chunkHash($x, $z)]) && isset($this->activeChunkPopulationTasks[$index])){ - if($chunk === null){ - throw new AssumptionFailedError("Primary chunk should never be NULL"); - } for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ $this->unlockChunk($x + $xx, $z + $zz); @@ -2159,6 +2160,12 @@ class World implements ChunkManager{ $oldChunk = $this->loadChunk($x, $z); $this->setChunk($x, $z, $chunk, false); + + foreach($adjacentChunks as $adjacentChunkHash => $adjacentChunk){ + World::getXZ($adjacentChunkHash, $xAdjacentChunk, $zAdjacentChunk); + $this->setChunk($xAdjacentChunk, $zAdjacentChunk, $adjacentChunk); + } + if(($oldChunk === null or !$oldChunk->isPopulated()) and $chunk->isPopulated()){ (new ChunkPopulateEvent($this, $x, $z, $chunk))->call(); @@ -2172,14 +2179,6 @@ class World implements ChunkManager{ $promise->resolve($chunk); $this->drainPopulationRequestQueue(); - }elseif($this->isChunkLocked($x, $z)){ - $this->unlockChunk($x, $z); - if($chunk !== null){ - $this->setChunk($x, $z, $chunk, false); - } - $this->drainPopulationRequestQueue(); - }elseif($chunk !== null){ - $this->setChunk($x, $z, $chunk, false); } Timings::$generationCallback->stopTiming(); } diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 2cd68ebdea..0237a8cc02 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -153,6 +153,7 @@ class PopulationTask extends AsyncTask{ FastChunkSerializer::deserializeTerrain($this->chunk) : throw new AssumptionFailedError("Center chunk should never be null"); + $adjacentChunks = []; for($i = 0; $i < 9; ++$i){ if($i === 4){ continue; @@ -162,12 +163,11 @@ class PopulationTask extends AsyncTask{ $xx = -1 + $i % 3; $zz = -1 + intdiv($i, 3); - $c = FastChunkSerializer::deserializeTerrain($c); - $world->generateChunkCallback($this->chunkX + $xx, $this->chunkZ + $zz, $c); + $adjacentChunks[World::chunkHash($this->chunkX + $xx, $this->chunkZ + $zz)] = FastChunkSerializer::deserializeTerrain($c); } } - $world->generateChunkCallback($this->chunkX, $this->chunkZ, $chunk); + $world->generateChunkCallback($this->chunkX, $this->chunkZ, $chunk, $adjacentChunks); } } } From fca70efbb1f247b5fe7680bfb3cafcbf795d5c6a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Oct 2021 16:44:08 +0100 Subject: [PATCH 3029/3224] World: move chunk population related methods to be in the same overall place --- src/world/World.php | 118 ++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index d5bca01958..5474aba614 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2124,65 +2124,6 @@ class World implements ChunkManager{ return isset($this->chunkLock[World::chunkHash($chunkX, $chunkZ)]); } - private function drainPopulationRequestQueue() : void{ - $failed = []; - while(count($this->activeChunkPopulationTasks) < $this->maxConcurrentChunkPopulationTasks && !$this->chunkPopulationRequestQueue->isEmpty()){ - $nextChunkHash = $this->chunkPopulationRequestQueue->dequeue(); - World::getXZ($nextChunkHash, $nextChunkX, $nextChunkZ); - if(isset($this->chunkPopulationRequestMap[$nextChunkHash])){ - assert(!isset($this->activeChunkPopulationTasks[$nextChunkHash]), "Population for chunk $nextChunkX $nextChunkZ already running"); - $this->orderChunkPopulation($nextChunkX, $nextChunkZ, null); - if(!isset($this->activeChunkPopulationTasks[$nextChunkHash])){ - $failed[] = $nextChunkHash; - } - } - } - - //these requests failed even though they weren't rate limited; we can't directly re-add them to the back of the - //queue because it would result in an infinite loop - foreach($failed as $hash){ - $this->chunkPopulationRequestQueue->enqueue($hash); - } - } - - /** - * @param Chunk[] $adjacentChunks - * @phpstan-param array $adjacentChunks - */ - public function generateChunkCallback(int $x, int $z, Chunk $chunk, array $adjacentChunks) : void{ - Timings::$generationCallback->startTiming(); - if(isset($this->chunkPopulationRequestMap[$index = World::chunkHash($x, $z)]) && isset($this->activeChunkPopulationTasks[$index])){ - for($xx = -1; $xx <= 1; ++$xx){ - for($zz = -1; $zz <= 1; ++$zz){ - $this->unlockChunk($x + $xx, $z + $zz); - } - } - - $oldChunk = $this->loadChunk($x, $z); - $this->setChunk($x, $z, $chunk, false); - - foreach($adjacentChunks as $adjacentChunkHash => $adjacentChunk){ - World::getXZ($adjacentChunkHash, $xAdjacentChunk, $zAdjacentChunk); - $this->setChunk($xAdjacentChunk, $zAdjacentChunk, $adjacentChunk); - } - - if(($oldChunk === null or !$oldChunk->isPopulated()) and $chunk->isPopulated()){ - (new ChunkPopulateEvent($this, $x, $z, $chunk))->call(); - - foreach($this->getChunkListeners($x, $z) as $listener){ - $listener->onChunkPopulated($x, $z, $chunk); - } - } - unset($this->activeChunkPopulationTasks[$index]); - $promise = $this->chunkPopulationRequestMap[$index]; - unset($this->chunkPopulationRequestMap[$index]); - $promise->resolve($chunk); - - $this->drainPopulationRequestQueue(); - } - Timings::$generationCallback->stopTiming(); - } - /** * @param bool $deleteEntitiesAndTiles Whether to delete entities and tiles on the old chunk, or transfer them to the new one */ @@ -2775,6 +2716,27 @@ class World implements ChunkManager{ return $promise; } + private function drainPopulationRequestQueue() : void{ + $failed = []; + while(count($this->activeChunkPopulationTasks) < $this->maxConcurrentChunkPopulationTasks && !$this->chunkPopulationRequestQueue->isEmpty()){ + $nextChunkHash = $this->chunkPopulationRequestQueue->dequeue(); + World::getXZ($nextChunkHash, $nextChunkX, $nextChunkZ); + if(isset($this->chunkPopulationRequestMap[$nextChunkHash])){ + assert(!isset($this->activeChunkPopulationTasks[$nextChunkHash]), "Population for chunk $nextChunkX $nextChunkZ already running"); + $this->orderChunkPopulation($nextChunkX, $nextChunkZ, null); + if(!isset($this->activeChunkPopulationTasks[$nextChunkHash])){ + $failed[] = $nextChunkHash; + } + } + } + + //these requests failed even though they weren't rate limited; we can't directly re-add them to the back of the + //queue because it would result in an infinite loop + foreach($failed as $hash){ + $this->chunkPopulationRequestQueue->enqueue($hash); + } + } + /** * Attempts to initiate asynchronous generation/population of the target chunk, if it's currently reasonable to do * so (and if it isn't already generated/populated). @@ -2859,6 +2821,44 @@ class World implements ChunkManager{ return $result; } + /** + * @param Chunk[] $adjacentChunks + * @phpstan-param array $adjacentChunks + */ + public function generateChunkCallback(int $x, int $z, Chunk $chunk, array $adjacentChunks) : void{ + Timings::$generationCallback->startTiming(); + if(isset($this->chunkPopulationRequestMap[$index = World::chunkHash($x, $z)]) && isset($this->activeChunkPopulationTasks[$index])){ + for($xx = -1; $xx <= 1; ++$xx){ + for($zz = -1; $zz <= 1; ++$zz){ + $this->unlockChunk($x + $xx, $z + $zz); + } + } + + $oldChunk = $this->loadChunk($x, $z); + $this->setChunk($x, $z, $chunk, false); + + foreach($adjacentChunks as $adjacentChunkHash => $adjacentChunk){ + World::getXZ($adjacentChunkHash, $xAdjacentChunk, $zAdjacentChunk); + $this->setChunk($xAdjacentChunk, $zAdjacentChunk, $adjacentChunk); + } + + if(($oldChunk === null or !$oldChunk->isPopulated()) and $chunk->isPopulated()){ + (new ChunkPopulateEvent($this, $x, $z, $chunk))->call(); + + foreach($this->getChunkListeners($x, $z) as $listener){ + $listener->onChunkPopulated($x, $z, $chunk); + } + } + unset($this->activeChunkPopulationTasks[$index]); + $promise = $this->chunkPopulationRequestMap[$index]; + unset($this->chunkPopulationRequestMap[$index]); + $promise->resolve($chunk); + + $this->drainPopulationRequestQueue(); + } + Timings::$generationCallback->stopTiming(); + } + public function doChunkGarbageCollection() : void{ $this->timings->doChunkGC->startTiming(); From 18734578407486798529b1ef5253b61d36ad8ffd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Oct 2021 20:21:58 +0100 Subject: [PATCH 3030/3224] PopulationTask: stop using dynamic properties --- src/world/generator/PopulationTask.php | 72 ++++++++-------------- tests/phpstan/configs/actual-problems.neon | 5 -- 2 files changed, 27 insertions(+), 50 deletions(-) diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 0237a8cc02..7ed3abcc76 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -31,7 +31,12 @@ use pocketmine\world\format\Chunk; use pocketmine\world\format\io\FastChunkSerializer; use pocketmine\world\SimpleChunkManager; use pocketmine\world\World; +use function array_map; +use function igbinary_serialize; +use function igbinary_unserialize; use function intdiv; +use function is_array; +use function is_string; class PopulationTask extends AsyncTask{ private const TLS_KEY_WORLD = "world"; @@ -46,25 +51,7 @@ class PopulationTask extends AsyncTask{ /** @var string|null */ public $chunk; - /** @var string|null */ - public $chunk0; - /** @var string|null */ - public $chunk1; - /** @var string|null */ - public $chunk2; - /** @var string|null */ - public $chunk3; - - //center chunk - - /** @var string|null */ - public $chunk5; - /** @var string|null */ - public $chunk6; - /** @var string|null */ - public $chunk7; - /** @var string|null */ - public $chunk8; + private string $adjacentChunks; public function __construct(World $world, int $chunkX, int $chunkZ, ?Chunk $chunk){ $this->worldId = $world->getId(); @@ -72,9 +59,10 @@ class PopulationTask extends AsyncTask{ $this->chunkZ = $chunkZ; $this->chunk = $chunk !== null ? FastChunkSerializer::serializeTerrain($chunk) : null; - foreach($world->getAdjacentChunks($chunkX, $chunkZ) as $i => $c){ - $this->{"chunk$i"} = $c !== null ? FastChunkSerializer::serializeTerrain($c) : null; - } + $this->adjacentChunks = igbinary_serialize(array_map( + fn(?Chunk $c) => $c !== null ? FastChunkSerializer::serializeTerrain($c) : null, + $world->getAdjacentChunks($chunkX, $chunkZ) + )) ?? throw new AssumptionFailedError("igbinary_serialize() returned null"); $this->storeLocal(self::TLS_KEY_WORLD, $world); } @@ -87,27 +75,19 @@ class PopulationTask extends AsyncTask{ $generator = $context->getGenerator(); $manager = new SimpleChunkManager($context->getWorldMinY(), $context->getWorldMaxY()); - /** @var Chunk[] $chunks */ - $chunks = []; - $oldModCounts = []; - $chunk = $this->chunk !== null ? FastChunkSerializer::deserializeTerrain($this->chunk) : null; - for($i = 0; $i < 9; ++$i){ - if($i === 4){ - continue; - } - $ck = $this->{"chunk$i"}; - if($ck === null){ - $chunks[$i] = null; - }else{ - $chunks[$i] = FastChunkSerializer::deserializeTerrain($ck); - $oldModCounts[$i] = $chunks[$i]->getModificationCount(); - } - } + /** @var string[] $serialChunks */ + $serialChunks = igbinary_unserialize($this->adjacentChunks); + $chunks = array_map( + fn(?string $serialized) => $serialized !== null ? FastChunkSerializer::deserializeTerrain($serialized) : null, + $serialChunks + ); + $oldModCounts = array_map(fn(?Chunk $chunk) => $chunk !== null ? $chunk->getModificationCount() : null, $chunks); self::setOrGenerateChunk($manager, $generator, $this->chunkX, $this->chunkZ, $chunk); + /** @var Chunk[] $resultChunks */ $resultChunks = []; //this is just to keep phpstan's type inference happy foreach($chunks as $i => $c){ $cX = (-1 + $i % 3) + $this->chunkX; @@ -125,10 +105,11 @@ class PopulationTask extends AsyncTask{ $this->chunk = FastChunkSerializer::serializeTerrain($chunk); + $serialChunks = []; foreach($chunks as $i => $c){ - $oldModCount = $oldModCounts[$i] ?? 0; - $this->{"chunk$i"} = $oldModCount !== $c->getModificationCount() ? FastChunkSerializer::serializeTerrain($c) : null; + $serialChunks[$i] = $oldModCounts[$i] !== $c->getModificationCount() ? FastChunkSerializer::serializeTerrain($c) : null; } + $this->adjacentChunks = igbinary_serialize($serialChunks) ?? throw new AssumptionFailedError("igbinary_serialize() returned null"); } private static function setOrGenerateChunk(SimpleChunkManager $manager, Generator $generator, int $chunkX, int $chunkZ, ?Chunk $chunk) : Chunk{ @@ -153,12 +134,13 @@ class PopulationTask extends AsyncTask{ FastChunkSerializer::deserializeTerrain($this->chunk) : throw new AssumptionFailedError("Center chunk should never be null"); + /** + * @var string[]|null[] $serialAdjacentChunks + * @phpstan-var array $serialAdjacentChunks + */ + $serialAdjacentChunks = igbinary_unserialize($this->adjacentChunks); $adjacentChunks = []; - for($i = 0; $i < 9; ++$i){ - if($i === 4){ - continue; - } - $c = $this->{"chunk$i"}; + foreach($serialAdjacentChunks as $i => $c){ if($c !== null){ $xx = -1 + $i % 3; $zz = -1 + intdiv($i, 3); diff --git a/tests/phpstan/configs/actual-problems.neon b/tests/phpstan/configs/actual-problems.neon index ed9a6f9866..1ad3c569fc 100644 --- a/tests/phpstan/configs/actual-problems.neon +++ b/tests/phpstan/configs/actual-problems.neon @@ -5,8 +5,3 @@ parameters: count: 1 path: ../../../src/event/entity/EntityShootBowEvent.php - - - message: "#^Variable property access on \\$this\\(pocketmine\\\\world\\\\generator\\\\PopulationTask\\)\\.$#" - count: 4 - path: ../../../src/world/generator/PopulationTask.php - From 51fbff204bd7d01acb30636ec9900446b7d0d637 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Oct 2021 20:29:50 +0100 Subject: [PATCH 3031/3224] World: make PhpStorm understand return type of getAdjacentChunks() --- src/world/World.php | 2 +- src/world/generator/PopulationTask.php | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 5474aba614..0af46a4f9b 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2091,7 +2091,7 @@ class World implements ChunkManager{ /** * Returns the chunks adjacent to the specified chunk. * - * @return (Chunk|null)[] + * @return Chunk[]|null[] */ public function getAdjacentChunks(int $x, int $z) : array{ $result = []; diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 7ed3abcc76..fe5f6fc8af 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -35,8 +35,6 @@ use function array_map; use function igbinary_serialize; use function igbinary_unserialize; use function intdiv; -use function is_array; -use function is_string; class PopulationTask extends AsyncTask{ private const TLS_KEY_WORLD = "world"; From a7d8a598e15fd31e0b9203d986ae1c0ee13ee883 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Oct 2021 22:58:17 +0100 Subject: [PATCH 3032/3224] World: reduce code duplication for chunk coordinate calculation --- src/world/World.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 0af46a4f9b..522aa57b26 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1610,7 +1610,7 @@ class World implements ChunkManager{ $block->writeStateToWorld(); $pos = $block->getPosition(); - $chunkHash = World::chunkHash($x >> Chunk::COORD_BIT_SIZE, $z >> Chunk::COORD_BIT_SIZE); + $chunkHash = World::chunkHash($chunkX, $chunkZ); $relativeBlockHash = World::chunkBlockHash($x, $y, $z); unset($this->blockCache[$chunkHash][$relativeBlockHash]); @@ -1620,7 +1620,7 @@ class World implements ChunkManager{ } $this->changedBlocks[$chunkHash][$relativeBlockHash] = $pos; - foreach($this->getChunkListeners($x >> Chunk::COORD_BIT_SIZE, $z >> Chunk::COORD_BIT_SIZE) as $listener){ + foreach($this->getChunkListeners($chunkX, $chunkZ) as $listener){ $listener->onBlockChanged($pos); } From 6d89265510212a082f79e333a707b5aef5e5a832 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 26 Oct 2021 23:02:50 +0100 Subject: [PATCH 3033/3224] Player: reduce code duplication back when this was just hardcoded >> 4 everywhere, nobody thought anything of it, but now it uses constants, it's easy to cross-reference and see where the duplicates are. --- src/player/Player.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 10265f466f..8a8ba1ce29 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -271,9 +271,11 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $world = $spawnLocation->getWorld(); //load the spawn chunk so we can see the terrain - $world->registerChunkLoader($this->chunkLoader, $spawnLocation->getFloorX() >> Chunk::COORD_BIT_SIZE, $spawnLocation->getFloorZ() >> Chunk::COORD_BIT_SIZE, true); - $world->registerChunkListener($this, $spawnLocation->getFloorX() >> Chunk::COORD_BIT_SIZE, $spawnLocation->getFloorZ() >> Chunk::COORD_BIT_SIZE); - $this->usedChunks[World::chunkHash($spawnLocation->getFloorX() >> Chunk::COORD_BIT_SIZE, $spawnLocation->getFloorZ() >> Chunk::COORD_BIT_SIZE)] = UsedChunkStatus::NEEDED(); + $xSpawnChunk = $spawnLocation->getFloorX() >> Chunk::COORD_BIT_SIZE; + $zSpawnChunk = $spawnLocation->getFloorZ() >> Chunk::COORD_BIT_SIZE; + $world->registerChunkLoader($this->chunkLoader, $xSpawnChunk, $zSpawnChunk, true); + $world->registerChunkListener($this, $xSpawnChunk, $zSpawnChunk); + $this->usedChunks[World::chunkHash($xSpawnChunk, $zSpawnChunk)] = UsedChunkStatus::NEEDED(); parent::__construct($spawnLocation, $this->playerInfo->getSkin(), $namedtag); } From 0ef5c67b9b6b2b42b42e9e93001299b784dd96b9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 27 Oct 2021 21:10:16 +0100 Subject: [PATCH 3034/3224] Use static constructor for MovePlayerPacket this marks the last of the packets created using the old way. --- composer.lock | 8 ++++---- src/network/mcpe/NetworkSession.php | 21 +++++++++++---------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/composer.lock b/composer.lock index 883984a57b..4348bbce62 100644 --- a/composer.lock +++ b/composer.lock @@ -253,12 +253,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "5285dde125b529e070db7eeb0d3774208e1652ef" + "reference": "58c53a259e819a076bf8fe875d2a012da7d19d65" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/5285dde125b529e070db7eeb0d3774208e1652ef", - "reference": "5285dde125b529e070db7eeb0d3774208e1652ef", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/58c53a259e819a076bf8fe875d2a012da7d19d65", + "reference": "58c53a259e819a076bf8fe875d2a012da7d19d65", "shasum": "" }, "require": { @@ -293,7 +293,7 @@ "issues": "https://github.com/pmmp/BedrockProtocol/issues", "source": "https://github.com/pmmp/BedrockProtocol/tree/master" }, - "time": "2021-10-23T15:18:49+00:00" + "time": "2021-10-27T19:49:20+00:00" }, { "name": "pocketmine/binaryutils", diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 2ca46db0ee..5ff3998a2c 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -727,16 +727,17 @@ class NetworkSession{ $yaw = $yaw ?? $location->getYaw(); $pitch = $pitch ?? $location->getPitch(); - $pk = new MovePlayerPacket(); - $pk->actorRuntimeId = $this->player->getId(); - $pk->position = $this->player->getOffsetPosition($pos); - $pk->pitch = $pitch; - $pk->headYaw = $yaw; - $pk->yaw = $yaw; - $pk->mode = $mode; - $pk->onGround = $this->player->onGround; - - $this->sendDataPacket($pk); + $this->sendDataPacket(MovePlayerPacket::simple( + $this->player->getId(), + $this->player->getOffsetPosition($pos), + $pitch, + $yaw, + $yaw, //TODO: head yaw + $mode, + $this->player->onGround, + 0, //TODO: riding entity ID + 0 //TODO: tick + )); if($this->handler instanceof InGamePacketHandler){ $this->handler->forceMoveSync = true; From bb05af103d22148dbe3aa053a2119c2603282343 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Oct 2021 15:55:05 +0100 Subject: [PATCH 3035/3224] PluginManager: fixed crash when using a plugin-loader plugin (read: devtools) closes #4518 --- src/plugin/PluginManager.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index c46ad4a65b..1b02e082ab 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -41,7 +41,7 @@ use pocketmine\timings\TimingsHandler; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Utils; use Webmozart\PathUtil\Path; -use function array_diff_assoc; +use function array_diff_key; use function array_key_exists; use function array_keys; use function array_merge; @@ -355,7 +355,7 @@ class PluginManager{ $this->server->getLogger()->debug("Plugin $name registered a new plugin loader during load, scanning for new plugins"); $plugins = $triage->plugins; $this->triagePlugins($path, $triage, $diffLoaders); - $diffPlugins = array_diff_assoc($triage->plugins, $plugins); + $diffPlugins = array_diff_key($triage->plugins, $plugins); $this->server->getLogger()->debug("Re-triage found plugins: " . implode(", ", array_keys($diffPlugins))); } } From 48f77abe7e4b078c2f8b185f738b5d269dceb203 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Oct 2021 16:03:43 +0100 Subject: [PATCH 3036/3224] Leave channel ID in VersionInfo so that I don't have to type it out every time I make a new release. Most of the time it's going to be posted to the same channel as before anyway. --- src/VersionInfo.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 701598a17c..cc0170c8bd 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -32,7 +32,7 @@ final class VersionInfo{ public const BASE_VERSION = "4.0.0-BETA7"; public const IS_DEVELOPMENT_BUILD = true; public const BUILD_NUMBER = 0; - public const BUILD_CHANNEL = ""; + public const BUILD_CHANNEL = "beta"; private function __construct(){ //NOOP From dba148cfaa3b9cc53a3bdd7bb622bb35c39a5194 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Oct 2021 16:25:18 +0100 Subject: [PATCH 3037/3224] build/make-release: make arg parsing use getopt --- build/make-release.php | 57 ++++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/build/make-release.php b/build/make-release.php index d90623332d..65f46f385f 100644 --- a/build/make-release.php +++ b/build/make-release.php @@ -25,18 +25,26 @@ namespace pocketmine\build\make_release; use pocketmine\utils\VersionString; use pocketmine\VersionInfo; -use function count; +use function array_keys; +use function array_map; use function dirname; use function fgets; use function file_get_contents; use function file_put_contents; use function fwrite; +use function getopt; +use function is_string; +use function max; use function preg_replace; use function sleep; use function sprintf; +use function str_pad; +use function strlen; use function system; use const STDERR; use const STDIN; +use const STDOUT; +use const STR_PAD_LEFT; require_once dirname(__DIR__) . '/vendor/autoload.php'; @@ -60,22 +68,38 @@ function replaceVersion(string $versionInfoPath, string $newVersion, bool $isDev file_put_contents($versionInfoPath, $versionInfo); } -/** - * @param string[] $argv - * @phpstan-param list $argv - */ -function main(array $argv) : void{ - if(count($argv) < 2){ - fwrite(STDERR, "Arguments: [release version] [next version]\n"); - exit(1); +const ACCEPTED_OPTS = [ + "current" => "Version to insert and tag", + "next" => "Version to put in the file after tagging", + "channel" => "Release channel to post this build into" +]; + +function main() : void{ + $filteredOpts = []; + foreach(getopt("", ["current:", "next:", "channel:", "help"]) as $optName => $optValue){ + if($optName === "help"){ + fwrite(STDOUT, "Options:\n"); + + $maxLength = max(array_map(fn(string $str) => strlen($str), array_keys(ACCEPTED_OPTS))); + foreach(ACCEPTED_OPTS as $acceptedName => $description){ + fwrite(STDOUT, str_pad("--$acceptedName", $maxLength + 4, " ", STR_PAD_LEFT) . ": $description\n"); + } + exit(0); + } + if(!is_string($optValue)){ + fwrite(STDERR, "--$optName expects exactly 1 value\n"); + exit(1); + } + $filteredOpts[$optName] = $optValue; } - if(isset($argv[2])){ - $currentVer = new VersionString($argv[2]); + + if(isset($filteredOpts["current"])){ + $currentVer = new VersionString($filteredOpts["current"]); }else{ $currentVer = VersionInfo::VERSION(); } - if(isset($argv[3])){ - $nextVer = new VersionString($argv[3]); + if(isset($filteredOpts["next"])){ + $nextVer = new VersionString($filteredOpts["next"]); }else{ $nextVer = new VersionString(sprintf( "%u.%u.%u", @@ -84,6 +108,7 @@ function main(array $argv) : void{ $currentVer->getPatch() + 1 )); } + $channel = $filteredOpts["channel"] ?? VersionInfo::BUILD_CHANNEL; echo "About to tag version $currentVer. Next version will be $nextVer.\n"; echo "please add appropriate notes to the changelog and press enter..."; @@ -95,10 +120,10 @@ function main(array $argv) : void{ exit(1); } $versionInfoPath = dirname(__DIR__) . '/src/VersionInfo.php'; - replaceVersion($versionInfoPath, $currentVer->getBaseVersion(), false, $argv[1]); + replaceVersion($versionInfoPath, $currentVer->getBaseVersion(), false, $channel); system('git commit -m "Release ' . $currentVer->getBaseVersion() . '" --include "' . $versionInfoPath . '"'); system('git tag ' . $currentVer->getBaseVersion()); - replaceVersion($versionInfoPath, $nextVer->getBaseVersion(), true, ""); + replaceVersion($versionInfoPath, $nextVer->getBaseVersion(), true, $channel); system('git add "' . $versionInfoPath . '"'); system('git commit -m "' . $nextVer->getBaseVersion() . ' is next" --include "' . $versionInfoPath . '"'); echo "pushing changes in 5 seconds\n"; @@ -106,4 +131,4 @@ function main(array $argv) : void{ system('git push origin HEAD ' . $currentVer->getBaseVersion()); } -main($argv); +main(); From 2b0768f7208cfa4fa4cb0c0c23f492c9f0189498 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Oct 2021 16:26:56 +0100 Subject: [PATCH 3038/3224] make-release: fixed retention of +dev on release versions --- build/make-release.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/make-release.php b/build/make-release.php index 65f46f385f..ea334e04d5 100644 --- a/build/make-release.php +++ b/build/make-release.php @@ -96,7 +96,7 @@ function main() : void{ if(isset($filteredOpts["current"])){ $currentVer = new VersionString($filteredOpts["current"]); }else{ - $currentVer = VersionInfo::VERSION(); + $currentVer = new VersionString(VersionInfo::BASE_VERSION); } if(isset($filteredOpts["next"])){ $nextVer = new VersionString($filteredOpts["next"]); From d0474ccd9257c1992a6014f5e4a3c82caa2f4c45 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Oct 2021 16:29:20 +0100 Subject: [PATCH 3039/3224] make-release: note which channel the build will be released into --- build/make-release.php | 1 + 1 file changed, 1 insertion(+) diff --git a/build/make-release.php b/build/make-release.php index ea334e04d5..90961c3929 100644 --- a/build/make-release.php +++ b/build/make-release.php @@ -111,6 +111,7 @@ function main() : void{ $channel = $filteredOpts["channel"] ?? VersionInfo::BUILD_CHANNEL; echo "About to tag version $currentVer. Next version will be $nextVer.\n"; + echo "$currentVer will be published on release channel \"$channel\".\n"; echo "please add appropriate notes to the changelog and press enter..."; fgets(STDIN); system('git add "' . dirname(__DIR__) . '/changelogs"'); From 7effa03ba45083ad8364b38a1c6399a8d9d3c74e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Oct 2021 17:28:48 +0100 Subject: [PATCH 3040/3224] Release 4.0.0-BETA7 --- changelogs/4.0.md | 36 ++++++++++++++++++++++++++++++++++++ src/VersionInfo.php | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index 708822771d..d9a268bef7 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1460,3 +1460,39 @@ Released 19th October 2021. ## Gameplay - Picking up some items from a dropped stack of items is now supported. This fixes various bugs with being unable to pick up items with an almost-full inventory. + +# 4.0.0-BETA7 +Released 28 October 2021. + +## General +- Phar plugins are now able to depend on folder plugins loaded by DevTools. +- Now uses [`pocketmine/bedrock-protocol@58c53a259e819a076bf8fe875d2a012da7d19d65`](https://github.com/pmmp/BedrockProtocol/tree/58c53a259e819a076bf8fe875d2a012da7d19d65). This version features significant changes, including: + - Standardisation of various field names (e.g. `eid` -> `actorRuntimeId`, `evid` -> `eventId`) + - Rename of `entity` related fields to `actor` where appropriate (e.g. `entityRuntimeId` -> `actorRuntimeId`) + - Block position `x`/`y`/`z` fields replaced by `BlockPosition` + - Static `::create()` functions for all packets, which ensure that fields can't be forgotten + +## Fixes +- Fixed server crash when clients send itemstacks with unmappable dynamic item IDs. +- Fixed server crash on invalid ItemStackRequest action types. +- Fixed autosave bug that caused unmodified chunks to be saved at least once (during the first autosave after they were loaded). +- Fixed `ConsoleReaderThread` returning strings with newlines still on the end. +- Fixed changes made to adjacent chunks in `ChunkPopulateEvent` (e.g. setting blocks) sometimes getting overwritten. + +## API +### Event +- `PlayerCreationEvent` now verifies that the player class set is instantiable - this ensures that plugins get properly blamed for breaking things. + +### World +- `World->generateChunkCallback()` has been specialized for use by `PopulationTask`. This allows fixing various inconsistencies involving `ChunkPopulateEvent` (e.g. modifications to adjacent chunks in `ChunkPopulationEvent` might be wiped out, if the population of the target chunk modified the adjacent chunk). + - It now accepts `Chunk $centerChunk, array $adjacentChunks` (instead of `?Chunk $chunk`). + - It's no longer expected to be used by plugins - plugins should be using `World->setChunk()` anyway. +- `Chunk->getModificationCounter()` has been added. This is a number starting from `0` when the `Chunk` object is first created (unless overridden by the constructor). It's incremented every time blocks or biomes are changed in the chunk. It resets after the chunk is unloaded and reloaded. +- The following API methods have changed signatures: + - `Sound->encode()` no longer accepts `null` for the position. + - `Chunk->__construct()`: removed `HeightArray $heightMap` parameter, added `bool $terrainPopulated` and `int $modificationCounter` parameters. + +### Plugin +- `PluginManager->loadPlugins()` now accepts paths to files as well as directories, in which case it will load only the plugin found in the target file. +- The following API methods have been removed: + - `PluginManager->loadPlugin()`: use `PluginManager->loadPlugins()` instead diff --git a/src/VersionInfo.php b/src/VersionInfo.php index cc0170c8bd..f9b39cab47 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -30,7 +30,7 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; public const BASE_VERSION = "4.0.0-BETA7"; - public const IS_DEVELOPMENT_BUILD = true; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_NUMBER = 0; public const BUILD_CHANNEL = "beta"; From b3720b3f17024ac6d1dad50e6dc1bee7649461d4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Oct 2021 17:28:53 +0100 Subject: [PATCH 3041/3224] 4.0.0-BETA8 is next --- src/VersionInfo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index f9b39cab47..c56b36a607 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -29,8 +29,8 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "4.0.0-BETA7"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "4.0.0-BETA8"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_NUMBER = 0; public const BUILD_CHANNEL = "beta"; From eb40b741aee28502bab400f25a8649adef69a609 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Oct 2021 20:15:37 +0100 Subject: [PATCH 3042/3224] StandardPacketBroadcaster now splits broadcasts by session-specific PacketSerializerContext in the normal case, all sessions will share the same PacketSerializerContext and Compressor, so this code will be the same as before However, for the multi-protocol hackers out there, this should reduce the maintenance burden (@Driesboy) since now only the PacketSerializerContext needs to be maintained. I recommend a separate PacketSerializerContext for each protocol (perhaps put the protocol version in the serializer context too, if you need it for some reason). --- src/network/mcpe/NetworkSession.php | 2 + .../mcpe/StandardPacketBroadcaster.php | 50 ++++++++++--------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 5ff3998a2c..fc46f8ae55 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -447,6 +447,8 @@ class NetworkSession{ } } + public function getPacketSerializerContext() : PacketSerializerContext{ return $this->packetSerializerContext; } + public function getBroadcaster() : PacketBroadcaster{ return $this->broadcaster; } public function getCompressor() : Compressor{ diff --git a/src/network/mcpe/StandardPacketBroadcaster.php b/src/network/mcpe/StandardPacketBroadcaster.php index 1442a5bbf6..4da9b09511 100644 --- a/src/network/mcpe/StandardPacketBroadcaster.php +++ b/src/network/mcpe/StandardPacketBroadcaster.php @@ -23,10 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe; -use pocketmine\network\mcpe\compression\Compressor; -use pocketmine\network\mcpe\convert\GlobalItemTypeDictionary; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; -use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\Server; use function spl_object_id; @@ -40,35 +37,40 @@ final class StandardPacketBroadcaster implements PacketBroadcaster{ } public function broadcastPackets(array $recipients, array $packets) : void{ - //TODO: we should be using session-specific serializer contexts for this - $stream = PacketBatch::fromPackets(new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary()), ...$packets); - - /** @var Compressor[] $compressors */ + $buffers = []; $compressors = []; - /** @var NetworkSession[][] $compressorTargets */ - $compressorTargets = []; + $targetMap = []; foreach($recipients as $recipient){ - $compressor = $recipient->getCompressor(); - $compressorId = spl_object_id($compressor); + $serializerContext = $recipient->getPacketSerializerContext(); + $bufferId = spl_object_id($serializerContext); + if(!isset($buffers[$bufferId])){ + $buffers[$bufferId] = PacketBatch::fromPackets($serializerContext, ...$packets); + } + //TODO: different compressors might be compatible, it might not be necessary to split them up by object - $compressors[$compressorId] = $compressor; - $compressorTargets[$compressorId][] = $recipient; + $compressor = $recipient->getCompressor(); + $compressors[spl_object_id($compressor)] = $compressor; + + $targetMap[$bufferId][spl_object_id($compressor)][] = $recipient; } - foreach($compressors as $compressorId => $compressor){ - if(!$compressor->willCompress($stream->getBuffer())){ - foreach($compressorTargets[$compressorId] as $target){ - foreach($packets as $pk){ - $target->addToSendBuffer($pk); + foreach($targetMap as $bufferId => $compressorMap){ + $buffer = $buffers[$bufferId]; + foreach($compressorMap as $compressorId => $compressorTargets){ + $compressor = $compressors[$compressorId]; + if(!$compressor->willCompress($buffer->getBuffer())){ + foreach($compressorTargets as $target){ + foreach($packets as $pk){ + $target->addToSendBuffer($pk); + } + } + }else{ + $promise = $this->server->prepareBatch($buffer, $compressor); + foreach($compressorTargets as $target){ + $target->queueCompressed($promise); } - } - }else{ - $promise = $this->server->prepareBatch($stream, $compressor); - foreach($compressorTargets[$compressorId] as $target){ - $target->queueCompressed($promise); } } } - } } From 5db3915aad8b6218be25fc6b49646cefac36c696 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Oct 2021 20:28:00 +0100 Subject: [PATCH 3043/3224] Make MemoryManager aware of ChunkCache --- src/MemoryManager.php | 2 ++ src/network/mcpe/cache/ChunkCache.php | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/MemoryManager.php b/src/MemoryManager.php index dbcd800927..f456479694 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine; use pocketmine\event\server\LowMemoryEvent; +use pocketmine\network\mcpe\cache\ChunkCache; use pocketmine\scheduler\DumpWorkerMemoryTask; use pocketmine\scheduler\GarbageCollectionTask; use pocketmine\timings\Timings; @@ -187,6 +188,7 @@ class MemoryManager{ foreach($this->server->getWorldManager()->getWorlds() as $world){ $world->clearCache(true); } + ChunkCache::pruneCaches(); } if($this->lowMemChunkGC){ diff --git a/src/network/mcpe/cache/ChunkCache.php b/src/network/mcpe/cache/ChunkCache.php index 269451f497..bf0ee44191 100644 --- a/src/network/mcpe/cache/ChunkCache.php +++ b/src/network/mcpe/cache/ChunkCache.php @@ -36,9 +36,6 @@ use function strlen; /** * This class is used by the current MCPE protocol system to store cached chunk packets for fast resending. - * - * TODO: make MemoryManager aware of this so the cache can be destroyed when memory is low - * TODO: this needs a hook for world unloading */ class ChunkCache implements ChunkListener{ /** @var self[][] */ @@ -69,6 +66,19 @@ class ChunkCache implements ChunkListener{ return self::$instances[$worldId][$compressorId]; } + public static function pruneCaches() : void{ + foreach(self::$instances as $compressorMap){ + foreach($compressorMap as $chunkCache){ + foreach($chunkCache->caches as $chunkHash => $promise){ + if($promise->hasResult()){ + //Do not clear promises that are not yet fulfilled; they will have requesters waiting on them + unset($chunkCache->caches[$chunkHash]); + } + } + } + } + } + /** @var World */ private $world; /** @var Compressor */ From a62ce64fdd337003e065073d33778d9486bc8e22 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Oct 2021 20:59:51 +0100 Subject: [PATCH 3044/3224] Revert "Chunk: added modification counter" This reverts commit a5418a019dc2a83210084632130db8ce06f529ea. The more I assessed this, the more I realized that this implementation doesn't actually offer any value. Since modcounters don't persist after chunk unload + reload, they can't be reliably used to detect changes in chunks without additional event subscriptions. For the purpose I actually intended to use them for (population task cancellation) there's a) another solution, and b) modcounts are unreliable for that too, because of the aforementioned potential for chunks to get unloaded and reloaded. For the case of detecting dirty chunks within PopulationTask itself, they are also unnecessary, since the dirty flags are sufficient within there, since FastChunkSerializer doesn't copy dirty flags. In conclusion, this was a misbegotten addition with little real value, but does impact performance in hot paths. --- src/world/format/Chunk.php | 16 +--------------- src/world/format/io/FastChunkSerializer.php | 5 +---- src/world/generator/PopulationTask.php | 3 +-- 3 files changed, 3 insertions(+), 21 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 13a84742bf..23367ef7e0 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -41,8 +41,6 @@ class Chunk{ public const COORD_BIT_SIZE = SubChunk::COORD_BIT_SIZE; public const COORD_MASK = SubChunk::COORD_MASK; - private int $modificationCount; - /** @var int */ private $terrainDirtyFlags = 0; @@ -69,7 +67,7 @@ class Chunk{ /** * @param SubChunk[] $subChunks */ - public function __construct(array $subChunks, BiomeArray $biomeIds, bool $terrainPopulated, int $modificationCount = 0){ + public function __construct(array $subChunks, BiomeArray $biomeIds, bool $terrainPopulated){ $this->subChunks = new \SplFixedArray(Chunk::MAX_SUBCHUNKS); foreach($this->subChunks as $y => $null){ @@ -81,7 +79,6 @@ class Chunk{ $this->biomeIds = $biomeIds; $this->terrainPopulated = $terrainPopulated; - $this->modificationCount = $modificationCount; } /** @@ -110,7 +107,6 @@ class Chunk{ public function setFullBlock(int $x, int $y, int $z, int $block) : void{ $this->getSubChunk($y >> SubChunk::COORD_BIT_SIZE)->setFullBlock($x, $y & SubChunk::COORD_MASK, $z, $block); $this->terrainDirtyFlags |= self::DIRTY_FLAG_TERRAIN; - $this->modificationCount++; } /** @@ -174,7 +170,6 @@ class Chunk{ public function setBiomeId(int $x, int $z, int $biomeId) : void{ $this->biomeIds->set($x, $z, $biomeId); $this->terrainDirtyFlags |= self::DIRTY_FLAG_BIOMES; - $this->modificationCount++; } public function isLightPopulated() : ?bool{ @@ -192,7 +187,6 @@ class Chunk{ public function setPopulated(bool $value = true) : void{ $this->terrainPopulated = $value; $this->terrainDirtyFlags |= self::DIRTY_FLAG_TERRAIN; - $this->modificationCount++; } public function addTile(Tile $tile) : void{ @@ -275,24 +269,16 @@ class Chunk{ }else{ $this->terrainDirtyFlags &= ~$flag; } - $this->modificationCount++; } public function setTerrainDirty() : void{ $this->terrainDirtyFlags = ~0; - $this->modificationCount++; } public function clearTerrainDirtyFlags() : void{ $this->terrainDirtyFlags = 0; } - /** - * Returns the modcount for this chunk. Any saveable change to the chunk will cause this number to be incremented, - * so you can use this to detect when the chunk has been modified. - */ - public function getModificationCount() : int{ return $this->modificationCount; } - public function getSubChunk(int $y) : SubChunk{ if($y < 0 || $y >= $this->subChunks->getSize()){ throw new \InvalidArgumentException("Invalid subchunk Y coordinate $y"); diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index 0f3db73d18..bb8bec687a 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -51,8 +51,6 @@ final class FastChunkSerializer{ */ public static function serializeTerrain(Chunk $chunk) : string{ $stream = new BinaryStream(); - $stream->putLong($chunk->getModificationCount()); - $stream->putByte( ($chunk->isPopulated() ? self::FLAG_POPULATED : 0) ); @@ -90,7 +88,6 @@ final class FastChunkSerializer{ */ public static function deserializeTerrain(string $data) : Chunk{ $stream = new BinaryStream($data); - $modificationCounter = $stream->getLong(); $flags = $stream->getByte(); $terrainPopulated = (bool) ($flags & self::FLAG_POPULATED); @@ -118,6 +115,6 @@ final class FastChunkSerializer{ $biomeIds = new BiomeArray($stream->get(256)); - return new Chunk($subChunks, $biomeIds, $terrainPopulated, $modificationCounter); + return new Chunk($subChunks, $biomeIds, $terrainPopulated); } } diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index fe5f6fc8af..0e35961beb 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -81,7 +81,6 @@ class PopulationTask extends AsyncTask{ fn(?string $serialized) => $serialized !== null ? FastChunkSerializer::deserializeTerrain($serialized) : null, $serialChunks ); - $oldModCounts = array_map(fn(?Chunk $chunk) => $chunk !== null ? $chunk->getModificationCount() : null, $chunks); self::setOrGenerateChunk($manager, $generator, $this->chunkX, $this->chunkZ, $chunk); @@ -105,7 +104,7 @@ class PopulationTask extends AsyncTask{ $serialChunks = []; foreach($chunks as $i => $c){ - $serialChunks[$i] = $oldModCounts[$i] !== $c->getModificationCount() ? FastChunkSerializer::serializeTerrain($c) : null; + $serialChunks[$i] = $c->isTerrainDirty() ? FastChunkSerializer::serializeTerrain($c) : null; } $this->adjacentChunks = igbinary_serialize($serialChunks) ?? throw new AssumptionFailedError("igbinary_serialize() returned null"); } From d410db4302855b9df05d17b84a4300db4aa5ca84 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Oct 2021 22:11:07 +0100 Subject: [PATCH 3045/3224] Chunk: rename DIRTY_FLAG_TERRAIN to DIRTY_FLAG_BLOCKS we use the word 'terrain' elsewhere to refer to the combination of blocks and biomes, so using TERRAIN here is misleading. --- src/world/format/Chunk.php | 8 ++++---- src/world/format/io/leveldb/LevelDB.php | 2 +- src/world/generator/PopulationTask.php | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index 23367ef7e0..f1b1320ae2 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -32,7 +32,7 @@ use pocketmine\block\tile\Tile; use function array_map; class Chunk{ - public const DIRTY_FLAG_TERRAIN = 1 << 0; + public const DIRTY_FLAG_BLOCKS = 1 << 0; public const DIRTY_FLAG_BIOMES = 1 << 3; public const MAX_SUBCHUNKS = 16; @@ -106,7 +106,7 @@ class Chunk{ */ public function setFullBlock(int $x, int $y, int $z, int $block) : void{ $this->getSubChunk($y >> SubChunk::COORD_BIT_SIZE)->setFullBlock($x, $y & SubChunk::COORD_MASK, $z, $block); - $this->terrainDirtyFlags |= self::DIRTY_FLAG_TERRAIN; + $this->terrainDirtyFlags |= self::DIRTY_FLAG_BLOCKS; } /** @@ -186,7 +186,7 @@ class Chunk{ public function setPopulated(bool $value = true) : void{ $this->terrainPopulated = $value; - $this->terrainDirtyFlags |= self::DIRTY_FLAG_TERRAIN; + $this->terrainDirtyFlags |= self::DIRTY_FLAG_BLOCKS; } public function addTile(Tile $tile) : void{ @@ -295,7 +295,7 @@ class Chunk{ } $this->subChunks[$y] = $subChunk ?? new SubChunk(BlockLegacyIds::AIR << Block::INTERNAL_METADATA_BITS, []); - $this->setTerrainDirtyFlag(self::DIRTY_FLAG_TERRAIN, true); + $this->setTerrainDirtyFlag(self::DIRTY_FLAG_BLOCKS, true); } /** diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index 54433214e6..a96e329b31 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -436,7 +436,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ $write->put($index . self::TAG_VERSION, chr(self::CURRENT_LEVEL_CHUNK_VERSION)); $chunk = $chunkData->getChunk(); - if($chunk->getTerrainDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN)){ + if($chunk->getTerrainDirtyFlag(Chunk::DIRTY_FLAG_BLOCKS)){ $subChunks = $chunk->getSubChunks(); foreach($subChunks as $y => $subChunk){ $key = $index . self::TAG_SUBCHUNK_PREFIX . chr($y); diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 0e35961beb..e3bccbbfb5 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -117,7 +117,7 @@ class PopulationTask extends AsyncTask{ if($chunk === null){ throw new AssumptionFailedError("We just set this chunk, so it must exist"); } - $chunk->setTerrainDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN, true); + $chunk->setTerrainDirtyFlag(Chunk::DIRTY_FLAG_BLOCKS, true); $chunk->setTerrainDirtyFlag(Chunk::DIRTY_FLAG_BIOMES, true); } return $chunk; From d78801b9d5c2f53c3340448c657dc52ff3e8c7f9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Oct 2021 22:24:47 +0100 Subject: [PATCH 3046/3224] World: fixed tiles and entities getting deleted when adjacent chunks are modified during population --- src/world/World.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index 522aa57b26..148363254d 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2839,7 +2839,7 @@ class World implements ChunkManager{ foreach($adjacentChunks as $adjacentChunkHash => $adjacentChunk){ World::getXZ($adjacentChunkHash, $xAdjacentChunk, $zAdjacentChunk); - $this->setChunk($xAdjacentChunk, $zAdjacentChunk, $adjacentChunk); + $this->setChunk($xAdjacentChunk, $zAdjacentChunk, $adjacentChunk, false); } if(($oldChunk === null or !$oldChunk->isPopulated()) and $chunk->isPopulated()){ From c66790b6a69da5ed2aa3bcb653f7864d2e52c93f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Oct 2021 23:42:28 +0100 Subject: [PATCH 3047/3224] World: never delete entities in setChunk() entities exist completely independently from chunks now, so there is no need to interact with them whatsoever. As I wrote in #4520, there's no sense in deleting entities here, since a chunk replacement is essentially just a mass block update. On that theme, it might be a good idea to call Entity->onNearbyBlockChange() for all entities in the target and adjacent chunks when replacing a chunk, to ensure that they get the proper movement updates. --- src/world/World.php | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 148363254d..ae3837b061 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2125,18 +2125,13 @@ class World implements ChunkManager{ } /** - * @param bool $deleteEntitiesAndTiles Whether to delete entities and tiles on the old chunk, or transfer them to the new one + * @param bool $deleteTiles Whether to delete tiles on the old chunk, or transfer them to the new one */ - public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk, bool $deleteEntitiesAndTiles = true) : void{ + public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk, bool $deleteTiles = true) : void{ $chunkHash = World::chunkHash($chunkX, $chunkZ); $oldChunk = $this->loadChunk($chunkX, $chunkZ); if($oldChunk !== null and $oldChunk !== $chunk){ - if($deleteEntitiesAndTiles){ - foreach($this->getChunkEntities($chunkX, $chunkZ) as $entity){ - if(!($entity instanceof Player)){ - $entity->close(); - } - } + if($deleteTiles){ foreach($oldChunk->getTiles() as $tile){ $tile->close(); } From eb75df6f8e338b22927ad7ee6ae58c103ea0a9fb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Oct 2021 23:46:35 +0100 Subject: [PATCH 3048/3224] World: Intelligently perform automatic transfer or deletion of tiles in setChunk(), depending on the context tiles may be deleted in the following circumstances: 1) the target block in the new chunk doesn't expect a tile 2) the target block in the new chunk expects a different type of tile (responsibility of the plugin developer to create the new tile) 3) there's already a tile in the target chunk which conflicts with the old one In all other cases, the tile will be transferred. This resolves a large number of unintentional bugs caused by world editors replacing chunks without setting the deleteTilesAndEntities parameter to false (even the core itself does it). closes #4520 --- src/world/World.php | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index ae3837b061..df780e5a1f 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2124,23 +2124,36 @@ class World implements ChunkManager{ return isset($this->chunkLock[World::chunkHash($chunkX, $chunkZ)]); } - /** - * @param bool $deleteTiles Whether to delete tiles on the old chunk, or transfer them to the new one - */ - public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk, bool $deleteTiles = true) : void{ + public function setChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ $chunkHash = World::chunkHash($chunkX, $chunkZ); $oldChunk = $this->loadChunk($chunkX, $chunkZ); if($oldChunk !== null and $oldChunk !== $chunk){ - if($deleteTiles){ - foreach($oldChunk->getTiles() as $tile){ - $tile->close(); - } - }else{ - foreach($oldChunk->getTiles() as $tile){ - $chunk->addTile($tile); - $oldChunk->removeTile($tile); + $deletedTiles = 0; + $transferredTiles = 0; + foreach($oldChunk->getTiles() as $oldTile){ + $tilePosition = $oldTile->getPosition(); + $localX = $tilePosition->getFloorX() & Chunk::COORD_MASK; + $localY = $tilePosition->getFloorY(); + $localZ = $tilePosition->getFloorZ() & Chunk::COORD_MASK; + + $newBlock = BlockFactory::getInstance()->fromFullBlock($chunk->getFullBlock($localX, $localY, $localZ)); + $expectedTileClass = $newBlock->getIdInfo()->getTileClass(); + if( + $expectedTileClass === null || //new block doesn't expect a tile + !($oldTile instanceof $expectedTileClass) || //new block expects a different tile + (($newTile = $chunk->getTile($localX, $localY, $localZ)) !== null && $newTile !== $oldTile) //new chunk already has a different tile + ){ + $oldTile->close(); + $deletedTiles++; + }else{ + $transferredTiles++; + $chunk->addTile($oldTile); + $oldChunk->removeTile($oldTile); } } + if($deletedTiles > 0 || $transferredTiles > 0){ + $this->logger->debug("Replacement of chunk $chunkX $chunkZ caused deletion of $deletedTiles obsolete/conflicted tiles, and transfer of $transferredTiles"); + } } $this->chunks[$chunkHash] = $chunk; @@ -2830,11 +2843,11 @@ class World implements ChunkManager{ } $oldChunk = $this->loadChunk($x, $z); - $this->setChunk($x, $z, $chunk, false); + $this->setChunk($x, $z, $chunk); foreach($adjacentChunks as $adjacentChunkHash => $adjacentChunk){ World::getXZ($adjacentChunkHash, $xAdjacentChunk, $zAdjacentChunk); - $this->setChunk($xAdjacentChunk, $zAdjacentChunk, $adjacentChunk, false); + $this->setChunk($xAdjacentChunk, $zAdjacentChunk, $adjacentChunk); } if(($oldChunk === null or !$oldChunk->isPopulated()) and $chunk->isPopulated()){ From a4eda9a8f5a0d30e364470c2a5c9fc214b4f6e24 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 28 Oct 2021 23:59:32 +0100 Subject: [PATCH 3049/3224] World: call nearby entities' onNearbyBlockChange() in setChunk() fixes #2779 in all known cases. --- src/world/World.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index df780e5a1f..4aaba2d515 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2177,6 +2177,14 @@ class World implements ChunkManager{ $listener->onChunkChanged($chunkX, $chunkZ, $chunk); } } + + for($cX = -1; $cX <= 1; ++$cX){ + for($cZ = -1; $cZ <= 1; ++$cZ){ + foreach($this->getChunkEntities($chunkX + $cX, $chunkZ + $cZ) as $entity){ + $entity->onNearbyBlockChange(); + } + } + } } /** From fb5543a2adf8f25e79e894f346969a4efc290020 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 29 Oct 2021 00:16:11 +0100 Subject: [PATCH 3050/3224] Updated BedrockProtocol dependency --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 4348bbce62..706fbcc04b 100644 --- a/composer.lock +++ b/composer.lock @@ -253,12 +253,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "58c53a259e819a076bf8fe875d2a012da7d19d65" + "reference": "49e929d3a7c9aba21d6f0d9ac5ce73e23e6ca8b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/58c53a259e819a076bf8fe875d2a012da7d19d65", - "reference": "58c53a259e819a076bf8fe875d2a012da7d19d65", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/49e929d3a7c9aba21d6f0d9ac5ce73e23e6ca8b2", + "reference": "49e929d3a7c9aba21d6f0d9ac5ce73e23e6ca8b2", "shasum": "" }, "require": { @@ -293,7 +293,7 @@ "issues": "https://github.com/pmmp/BedrockProtocol/issues", "source": "https://github.com/pmmp/BedrockProtocol/tree/master" }, - "time": "2021-10-27T19:49:20+00:00" + "time": "2021-10-28T23:13:59+00:00" }, { "name": "pocketmine/binaryutils", From 88b7389080cad7a3a0a2020f42b55ec44fbd99a0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 29 Oct 2021 15:37:52 +0100 Subject: [PATCH 3051/3224] InventoryManager: reduce code duplication --- src/network/mcpe/InventoryManager.php | 34 +++++++++++---------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index db5b3a2ae8..b5271f5f9e 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -166,27 +166,21 @@ class InventoryManager{ //if the class isn't final, not to mention being inflexible. if($inv instanceof BlockInventory){ $blockPosition = BlockPosition::fromVector3($inv->getHolder()); - switch(true){ - case $inv instanceof LoomInventory: - return [ContainerOpenPacket::blockInv($id, WindowTypes::LOOM, $blockPosition)]; - case $inv instanceof FurnaceInventory: - return match($inv->getFurnaceType()->id()){ - FurnaceType::FURNACE()->id() => [ContainerOpenPacket::blockInv($id, WindowTypes::FURNACE, $blockPosition)], - FurnaceType::BLAST_FURNACE()->id() => [ContainerOpenPacket::blockInv($id, WindowTypes::BLAST_FURNACE, $blockPosition)], - FurnaceType::SMOKER()->id() => [ContainerOpenPacket::blockInv($id, WindowTypes::SMOKER, $blockPosition)], + $windowType = match(true){ + $inv instanceof LoomInventory => WindowTypes::LOOM, + $inv instanceof FurnaceInventory => match($inv->getFurnaceType()->id()){ + FurnaceType::FURNACE()->id() => WindowTypes::FURNACE, + FurnaceType::BLAST_FURNACE()->id() => WindowTypes::BLAST_FURNACE, + FurnaceType::SMOKER()->id() => WindowTypes::SMOKER, default => throw new AssumptionFailedError("Unreachable") - }; - case $inv instanceof EnchantInventory: - return [ContainerOpenPacket::blockInv($id, WindowTypes::ENCHANTMENT, $blockPosition)]; - case $inv instanceof BrewingStandInventory: - return [ContainerOpenPacket::blockInv($id, WindowTypes::BREWING_STAND, $blockPosition)]; - case $inv instanceof AnvilInventory: - return [ContainerOpenPacket::blockInv($id, WindowTypes::ANVIL, $blockPosition)]; - case $inv instanceof HopperInventory: - return [ContainerOpenPacket::blockInv($id, WindowTypes::HOPPER, $blockPosition)]; - default: - return [ContainerOpenPacket::blockInv($id, WindowTypes::CONTAINER, $blockPosition)]; - } + }, + $inv instanceof EnchantInventory => WindowTypes::ENCHANTMENT, + $inv instanceof BrewingStandInventory => WindowTypes::BREWING_STAND, + $inv instanceof AnvilInventory => WindowTypes::ANVIL, + $inv instanceof HopperInventory => WindowTypes::HOPPER, + default => WindowTypes::CONTAINER + }; + return [ContainerOpenPacket::blockInv($id, $windowType, $blockPosition)]; } return null; } From ee9f5e0044c7b355470b3c9d8b411805b3e3ea94 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 29 Oct 2021 15:40:58 +0100 Subject: [PATCH 3052/3224] Location: make __construct() parameters mandatory I did consider allowing yaw/pitch to remain optional, but considering the implicit immutability of Location, it really doesn't make any sense to create a Location with default yaw/pitch - just create a Position in that case instead. --- src/entity/Location.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entity/Location.php b/src/entity/Location.php index 156062a417..fe02f6eecc 100644 --- a/src/entity/Location.php +++ b/src/entity/Location.php @@ -34,7 +34,7 @@ class Location extends Position{ /** @var float */ public $pitch; - public function __construct(float $x, float $y, float $z, float $yaw = 0.0, float $pitch = 0.0, ?World $world = null){ + public function __construct(float $x, float $y, float $z, float $yaw, float $pitch, ?World $world){ $this->yaw = $yaw; $this->pitch = $pitch; parent::__construct($x, $y, $z, $world); From 32a34d249473d172e85eb7a8a1f8a66055f1727f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 29 Oct 2021 15:43:09 +0100 Subject: [PATCH 3053/3224] Location: change order of constructor parameters to be consistent with Position::__construct() and Location::fromObject() (although Location::fromObject() has no choice, thanks to the anti-feature known as late static binding ...) --- src/command/defaults/TeleportCommand.php | 2 +- src/entity/Entity.php | 4 ++-- src/entity/Location.php | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/command/defaults/TeleportCommand.php b/src/command/defaults/TeleportCommand.php index 1ece20f308..e3bbff7d09 100644 --- a/src/command/defaults/TeleportCommand.php +++ b/src/command/defaults/TeleportCommand.php @@ -113,7 +113,7 @@ class TeleportCommand extends VanillaCommand{ $x = $this->getRelativeDouble($base->x, $sender, $targetArgs[0]); $y = $this->getRelativeDouble($base->y, $sender, $targetArgs[1], 0, 256); $z = $this->getRelativeDouble($base->z, $sender, $targetArgs[2]); - $targetLocation = new Location($x, $y, $z, $yaw, $pitch, $base->getWorld()); + $targetLocation = new Location($x, $y, $z, $base->getWorld(), $yaw, $pitch); $subject->teleport($targetLocation); Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_tp_success_coordinates( diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 6289a896bf..c917f6001c 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1185,9 +1185,9 @@ abstract class Entity{ ($this->boundingBox->minX + $this->boundingBox->maxX) / 2, $this->boundingBox->minY - $this->ySize, ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2, + $this->location->world, $this->location->yaw, - $this->location->pitch, - $this->location->world + $this->location->pitch ); $this->getWorld()->onEntityMoved($this); diff --git a/src/entity/Location.php b/src/entity/Location.php index fe02f6eecc..c04ac9acbd 100644 --- a/src/entity/Location.php +++ b/src/entity/Location.php @@ -34,7 +34,7 @@ class Location extends Position{ /** @var float */ public $pitch; - public function __construct(float $x, float $y, float $z, float $yaw, float $pitch, ?World $world){ + public function __construct(float $x, float $y, float $z, ?World $world, float $yaw, float $pitch){ $this->yaw = $yaw; $this->pitch = $pitch; parent::__construct($x, $y, $z, $world); @@ -44,14 +44,14 @@ class Location extends Position{ * @return Location */ public static function fromObject(Vector3 $pos, ?World $world, float $yaw = 0.0, float $pitch = 0.0){ - return new Location($pos->x, $pos->y, $pos->z, $yaw, $pitch, $world ?? (($pos instanceof Position) ? $pos->world : null)); + return new Location($pos->x, $pos->y, $pos->z, $world ?? (($pos instanceof Position) ? $pos->world : null), $yaw, $pitch); } /** * Return a Location instance */ public function asLocation() : Location{ - return new Location($this->x, $this->y, $this->z, $this->yaw, $this->pitch, $this->world); + return new Location($this->x, $this->y, $this->z, $this->world, $this->yaw, $this->pitch); } public function getYaw() : float{ From 1c18c731efd780a2136c4cd11368c7e36fb07c16 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 29 Oct 2021 19:15:12 +0100 Subject: [PATCH 3054/3224] bootstrap: check for zlib raw support in leveldb --- src/PocketMine.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/PocketMine.php b/src/PocketMine.php index 44b7ebdd67..f944d445d9 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -126,6 +126,9 @@ namespace pocketmine { if(version_compare($leveldb_version, "0.2.1") < 0){ $messages[] = "php-leveldb >= 0.2.1 is required, while you have $leveldb_version."; } + if(!defined('LEVELDB_ZLIB_RAW_COMPRESSION')){ + $messages[] = "Given version of php-leveldb doesn't support ZLIB_RAW compression (use https://github.com/pmmp/php-leveldb)"; + } } $chunkutils2_version = phpversion("chunkutils2"); From 19f448d074f6f0eccb1a76570d629962a21dbf51 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 29 Oct 2021 21:56:56 +0100 Subject: [PATCH 3055/3224] pocketmine/math 0.4.0 --- composer.json | 2 +- composer.lock | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/composer.json b/composer.json index 22b5cd7a02..ee148e2139 100644 --- a/composer.json +++ b/composer.json @@ -42,7 +42,7 @@ "pocketmine/errorhandler": "^0.3.0", "pocketmine/log": "^0.3.0", "pocketmine/log-pthreads": "^0.2.0", - "pocketmine/math": "^0.3.0", + "pocketmine/math": "^0.4.0", "pocketmine/nbt": "^0.3.0", "pocketmine/raklib": "^0.14.2", "pocketmine/raklib-ipc": "^0.1.0", diff --git a/composer.lock b/composer.lock index 706fbcc04b..747ede1148 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ddbcdbc7ea7247bea7fcb37e5c42340b", + "content-hash": "3f467dca67940d465ceafbe5774d6977", "packages": [ { "name": "adhocore/json-comment", @@ -253,12 +253,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "49e929d3a7c9aba21d6f0d9ac5ce73e23e6ca8b2" + "reference": "c8d891b4dff9817d5fcd373dfec0608b20be3b0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/49e929d3a7c9aba21d6f0d9ac5ce73e23e6ca8b2", - "reference": "49e929d3a7c9aba21d6f0d9ac5ce73e23e6ca8b2", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/c8d891b4dff9817d5fcd373dfec0608b20be3b0a", + "reference": "c8d891b4dff9817d5fcd373dfec0608b20be3b0a", "shasum": "" }, "require": { @@ -267,7 +267,7 @@ "php": "^8.0", "pocketmine/binaryutils": "^0.2.0", "pocketmine/color": "^0.2.0", - "pocketmine/math": "^0.3.0", + "pocketmine/math": "^0.3.0 || ^0.4.0", "pocketmine/nbt": "^0.3.0", "ramsey/uuid": "^4.1" }, @@ -293,7 +293,7 @@ "issues": "https://github.com/pmmp/BedrockProtocol/issues", "source": "https://github.com/pmmp/BedrockProtocol/tree/master" }, - "time": "2021-10-28T23:13:59+00:00" + "time": "2021-10-29T20:54:42+00:00" }, { "name": "pocketmine/binaryutils", @@ -593,26 +593,26 @@ }, { "name": "pocketmine/math", - "version": "0.3.0", + "version": "0.4.0", "source": { "type": "git", "url": "https://github.com/pmmp/Math.git", - "reference": "83ec067b12c066fc61d9fb129daf7e61ef3b1d63" + "reference": "6d64e2555bd2e95ed024574f75d1cefc135c89fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Math/zipball/83ec067b12c066fc61d9fb129daf7e61ef3b1d63", - "reference": "83ec067b12c066fc61d9fb129daf7e61ef3b1d63", + "url": "https://api.github.com/repos/pmmp/Math/zipball/6d64e2555bd2e95ed024574f75d1cefc135c89fc", + "reference": "6d64e2555bd2e95ed024574f75d1cefc135c89fc", "shasum": "" }, "require": { - "php": "^7.4 || ^8.0", + "php": "^8.0", "php-64bit": "*" }, "require-dev": { "irstea/phpunit-shim": "^8.5 || ^9.5", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "0.12.90", + "phpstan/phpstan": "0.12.99", "phpstan/phpstan-strict-rules": "^0.12.4" }, "type": "library", @@ -628,9 +628,9 @@ "description": "PHP library containing math related code used in PocketMine-MP", "support": { "issues": "https://github.com/pmmp/Math/issues", - "source": "https://github.com/pmmp/Math/tree/0.3.0" + "source": "https://github.com/pmmp/Math/tree/0.4.0" }, - "time": "2021-07-14T18:39:31+00:00" + "time": "2021-10-29T20:33:10+00:00" }, { "name": "pocketmine/nbt", From 428bd5ae91b23d8d542a0217dda6b2bd1c3157d5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 29 Oct 2021 22:35:15 +0100 Subject: [PATCH 3056/3224] Release 4.0.0-BETA8 --- changelogs/4.0.md | 31 ++++++++++++++++++++++++++++++- src/VersionInfo.php | 2 +- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index d9a268bef7..dd27e019de 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1462,7 +1462,7 @@ Released 19th October 2021. - Picking up some items from a dropped stack of items is now supported. This fixes various bugs with being unable to pick up items with an almost-full inventory. # 4.0.0-BETA7 -Released 28 October 2021. +Released 28th October 2021. ## General - Phar plugins are now able to depend on folder plugins loaded by DevTools. @@ -1496,3 +1496,32 @@ Released 28 October 2021. - `PluginManager->loadPlugins()` now accepts paths to files as well as directories, in which case it will load only the plugin found in the target file. - The following API methods have been removed: - `PluginManager->loadPlugin()`: use `PluginManager->loadPlugins()` instead + +# 4.0.0-BETA8 +Released 29th October 2021. + +## General +- Chunk packet caches are now cleared by the memory manager on low memory. +- `Entity->spawnTo()` now has an additional sanity check for matching worlds (might expose a few new errors in plugins). +- [`pocketmine/math` 0.4.0](https://github.com/pmmp/Math/releases/tag/0.4.0) is now used. Please see its release notes for changes. + +## Fixes +- Zlib raw check for LevelDB is now done directly on startup, avoiding crashes when later trying to load worlds. +- Fixed tiles and entities getting deleted from adjacent chunks during chunk population. +- Fixed players being unable to open their inventories more than once. +- Fixed entities not getting updated when a nearby chunk is replaced (e.g. dropped items would float in midair if the ground was lower than before) + +## API +### World +- `World::setChunk()` has the following changes: + - `$deleteEntitiesAndTiles` parameter has been removed. + - Entities are no longer deleted on chunk replacement. + - Tiles are no longer deleted on chunk replacement, unless one of the following conditions is met: + - the target block in the new chunk doesn't expect a tile + - the target block in the new chunk expects a different type of tile (responsibility of the plugin developer to create the new tile) + - there's already a tile in the target chunk which conflicts with the old one +- `Location::__construct()` has the following changes: + - `world` parameter is now 4th instead of last. + - All parameters are now mandatory. +- Reverted addition of chunk modification counters in previous beta. +- `Chunk::DIRTY_FLAG_TERRAIN` has been renamed to `Chunk::DIRTY_FLAG_BLOCKS`. diff --git a/src/VersionInfo.php b/src/VersionInfo.php index c56b36a607..282461242d 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -30,7 +30,7 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; public const BASE_VERSION = "4.0.0-BETA8"; - public const IS_DEVELOPMENT_BUILD = true; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_NUMBER = 0; public const BUILD_CHANNEL = "beta"; From 63dfcc60c31dd60a7c358fd50ecca931f53010de Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 29 Oct 2021 22:35:23 +0100 Subject: [PATCH 3057/3224] 4.0.0-BETA9 is next --- src/VersionInfo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 282461242d..10d2f6e4bf 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -29,8 +29,8 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "4.0.0-BETA8"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "4.0.0-BETA9"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_NUMBER = 0; public const BUILD_CHANNEL = "beta"; From 465a5098589af4e08456495c21c920d069ea5310 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 30 Oct 2021 16:13:01 +0100 Subject: [PATCH 3058/3224] World: remove spammy debug message --- src/world/World.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index 4aaba2d515..3b5d12ffa3 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1412,7 +1412,6 @@ class World implements ChunkManager{ public function updateAllLight(int $x, int $y, int $z) : void{ if(($chunk = $this->getChunk($x >> Chunk::COORD_BIT_SIZE, $z >> Chunk::COORD_BIT_SIZE)) === null || $chunk->isLightPopulated() !== true){ - $this->logger->debug("Skipped runtime light update of x=$x,y=$y,z=$z because the target area has not received base light calculation"); return; } From 08f3c18de930d00240867f719c0fd1d2b59cdb45 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 30 Oct 2021 17:16:46 +0100 Subject: [PATCH 3059/3224] Arrow: do not add pickups to creative players' inventories closes #2932 --- src/entity/projectile/Arrow.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/entity/projectile/Arrow.php b/src/entity/projectile/Arrow.php index 5fbef6486d..ca194d2c56 100644 --- a/src/entity/projectile/Arrow.php +++ b/src/entity/projectile/Arrow.php @@ -175,6 +175,7 @@ class Arrow extends Projectile{ $item = VanillaItems::ARROW(); $playerInventory = match(true){ + !$player->hasFiniteResources() => null, //arrows are not picked up in creative $player->getOffHandInventory()->getItem(0)->canStackWith($item) and $player->getOffHandInventory()->canAddItem($item) => $player->getOffHandInventory(), $player->getInventory()->canAddItem($item) => $player->getInventory(), default => null From 5b8ce7e3e218e869092904206fcc80e3ad2b643a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 30 Oct 2021 21:02:24 +0100 Subject: [PATCH 3060/3224] Cake: fixed desync on cancellation of eating closes #3591 we don't support eating in creative right now, but the cake shouldn't appear to be eaten when it's not. --- src/block/Cake.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/block/Cake.php b/src/block/Cake.php index 75030c659d..e9f82943f4 100644 --- a/src/block/Cake.php +++ b/src/block/Cake.php @@ -94,8 +94,7 @@ class Cake extends Transparent implements FoodSource{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ - $player->consumeObject($this); - return true; + return $player->consumeObject($this); } return false; From 1d22761d272815730e94afd974cef39170cd42ed Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 30 Oct 2021 21:25:47 +0100 Subject: [PATCH 3061/3224] Remove useless newline --- src/player/SurvivalBlockBreakHandler.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/player/SurvivalBlockBreakHandler.php b/src/player/SurvivalBlockBreakHandler.php index ee9ff4df91..d407f02cd6 100644 --- a/src/player/SurvivalBlockBreakHandler.php +++ b/src/player/SurvivalBlockBreakHandler.php @@ -101,8 +101,7 @@ final class SurvivalBlockBreakHandler{ } public function update() : bool{ - if( - $this->player->getPosition()->distanceSquared($this->blockPos->add(0.5, 0.5, 0.5)) > $this->maxPlayerDistance ** 2){ + if($this->player->getPosition()->distanceSquared($this->blockPos->add(0.5, 0.5, 0.5)) > $this->maxPlayerDistance ** 2){ return false; } From 4f816d03a767d55f5312ef4668cb34545503ce62 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 30 Oct 2021 21:35:58 +0100 Subject: [PATCH 3062/3224] SurvivalBlockBreakHandler: remove useless code --- src/player/Player.php | 4 ++-- src/player/SurvivalBlockBreakHandler.php | 10 +--------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 33c61b302f..2f743fea3b 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1518,8 +1518,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return true; } - if(!$this->isCreative()){ - $this->blockBreakHandler = SurvivalBlockBreakHandler::createIfNecessary($this, $pos, $target, $face, 16); + if(!$this->isCreative() && !$block->getBreakInfo()->breaksInstantly()){ + $this->blockBreakHandler = new SurvivalBlockBreakHandler($this, $pos, $target, $face, 16); } return true; diff --git a/src/player/SurvivalBlockBreakHandler.php b/src/player/SurvivalBlockBreakHandler.php index d407f02cd6..5e27392cf4 100644 --- a/src/player/SurvivalBlockBreakHandler.php +++ b/src/player/SurvivalBlockBreakHandler.php @@ -59,7 +59,7 @@ final class SurvivalBlockBreakHandler{ /** @var float */ private $breakProgress = 0; - private function __construct(Player $player, Vector3 $blockPos, Block $block, int $targetedFace, int $maxPlayerDistance, int $fxTickInterval = self::DEFAULT_FX_INTERVAL_TICKS){ + public function __construct(Player $player, Vector3 $blockPos, Block $block, int $targetedFace, int $maxPlayerDistance, int $fxTickInterval = self::DEFAULT_FX_INTERVAL_TICKS){ $this->player = $player; $this->blockPos = $blockPos; $this->block = $block; @@ -76,14 +76,6 @@ final class SurvivalBlockBreakHandler{ } } - public static function createIfNecessary(Player $player, Vector3 $blockPos, Block $block, int $targetedFace, int $maxPlayerDistance, int $fxTickInterval = self::DEFAULT_FX_INTERVAL_TICKS) : ?self{ - $breakInfo = $block->getBreakInfo(); - if(!$breakInfo->breaksInstantly()){ - return new self($player, $blockPos, $block, $targetedFace, $maxPlayerDistance, $fxTickInterval); - } - return null; - } - /** * Returns the calculated break speed as percentage progress per game tick. */ From faad2365e2529d4bb6e86fcb26d6f46dc7ee93c9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 30 Oct 2021 22:17:06 +0100 Subject: [PATCH 3063/3224] World: Register a temporary chunk loader on chunks used by PopulationTask fixes #3839 --- src/world/World.php | 13 +++++++++++-- src/world/generator/PopulationTask.php | 9 +++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 3b5d12ffa3..a4bd8e81a0 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2813,13 +2813,15 @@ class World implements ChunkManager{ $this->chunkPopulationRequestMap[$index] = $promise; } + $temporaryChunkLoader = new class implements ChunkLoader{}; for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ $this->lockChunk($x + $xx, $z + $zz); + $this->registerChunkLoader($temporaryChunkLoader, $x + $xx, $z + $zz); } } - $task = new PopulationTask($this, $x, $z, $chunk); + $task = new PopulationTask($this, $x, $z, $chunk, $temporaryChunkLoader); $workerId = $this->workerPool->selectWorker(); if(!isset($this->generatorRegisteredWorkers[$workerId])){ $this->registerGeneratorToWorker($workerId); @@ -2840,8 +2842,15 @@ class World implements ChunkManager{ * @param Chunk[] $adjacentChunks * @phpstan-param array $adjacentChunks */ - public function generateChunkCallback(int $x, int $z, Chunk $chunk, array $adjacentChunks) : void{ + public function generateChunkCallback(int $x, int $z, Chunk $chunk, array $adjacentChunks, ChunkLoader $temporaryChunkLoader) : void{ Timings::$generationCallback->startTiming(); + + for($xx = -1; $xx <= 1; ++$xx){ + for($zz = -1; $zz <= 1; ++$zz){ + $this->unregisterChunkLoader($temporaryChunkLoader, $x + $xx, $z + $zz); + } + } + if(isset($this->chunkPopulationRequestMap[$index = World::chunkHash($x, $z)]) && isset($this->activeChunkPopulationTasks[$index])){ for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index e3bccbbfb5..19c0038fa3 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -26,6 +26,7 @@ namespace pocketmine\world\generator; use pocketmine\data\bedrock\BiomeIds; use pocketmine\scheduler\AsyncTask; use pocketmine\utils\AssumptionFailedError; +use pocketmine\world\ChunkLoader; use pocketmine\world\format\BiomeArray; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\FastChunkSerializer; @@ -38,6 +39,7 @@ use function intdiv; class PopulationTask extends AsyncTask{ private const TLS_KEY_WORLD = "world"; + private const TLS_KEY_CHUNK_LOADER = "chunkLoader"; /** @var int */ public $worldId; @@ -51,7 +53,7 @@ class PopulationTask extends AsyncTask{ private string $adjacentChunks; - public function __construct(World $world, int $chunkX, int $chunkZ, ?Chunk $chunk){ + public function __construct(World $world, int $chunkX, int $chunkZ, ?Chunk $chunk, ChunkLoader $temporaryChunkLoader){ $this->worldId = $world->getId(); $this->chunkX = $chunkX; $this->chunkZ = $chunkZ; @@ -63,6 +65,7 @@ class PopulationTask extends AsyncTask{ )) ?? throw new AssumptionFailedError("igbinary_serialize() returned null"); $this->storeLocal(self::TLS_KEY_WORLD, $world); + $this->storeLocal(self::TLS_KEY_CHUNK_LOADER, $temporaryChunkLoader); } public function onRun() : void{ @@ -126,6 +129,8 @@ class PopulationTask extends AsyncTask{ public function onCompletion() : void{ /** @var World $world */ $world = $this->fetchLocal(self::TLS_KEY_WORLD); + /** @var ChunkLoader $temporaryChunkLoader */ + $temporaryChunkLoader = $this->fetchLocal(self::TLS_KEY_CHUNK_LOADER); if($world->isLoaded()){ $chunk = $this->chunk !== null ? FastChunkSerializer::deserializeTerrain($this->chunk) : @@ -146,7 +151,7 @@ class PopulationTask extends AsyncTask{ } } - $world->generateChunkCallback($this->chunkX, $this->chunkZ, $chunk, $adjacentChunks); + $world->generateChunkCallback($this->chunkX, $this->chunkZ, $chunk, $adjacentChunks, $temporaryChunkLoader); } } } From 1cabe4baf33c4901af4f446330caf2edd838614f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Oct 2021 13:58:32 +0000 Subject: [PATCH 3064/3224] World: do not crash on duplicate tiles loaded from disk closes #4049 --- src/world/World.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index a4bd8e81a0..c9fb8f816b 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2485,6 +2485,8 @@ class World implements ChunkManager{ $this->getLogger()->warning("Chunk $chunkX $chunkZ: Deleted unknown tile entity type " . $nbt->getString("id", "")); }elseif(!$this->isChunkLoaded($tile->getPosition()->getFloorX() >> Chunk::COORD_BIT_SIZE, $tile->getPosition()->getFloorZ() >> Chunk::COORD_BIT_SIZE)){ $this->logger->error("Chunk $chunkX $chunkZ: Found tile saved on wrong chunk - unable to fix due to correct chunk not loaded"); + }elseif($this->getTile($tilePosition = $tile->getPosition()) !== null){ + $this->logger->error("Chunk $chunkX $chunkZ: Cannot add tile at x=$tilePosition->x,y=$tilePosition->y,z=$tilePosition->z: Another tile is already at that position"); }else{ $this->addTile($tile); } From 3dc75644d9546e7e57439d8e07677b1c7ce66ec0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Oct 2021 14:02:25 +0000 Subject: [PATCH 3065/3224] World: avoid duplicated logger code in initChunk() --- src/world/World.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index c9fb8f816b..ab7e18ce96 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2442,6 +2442,7 @@ class World implements ChunkManager{ } private function initChunk(int $chunkX, int $chunkZ, ChunkData $chunkData) : void{ + $logger = new \PrefixedLogger($this->logger, "Loading chunk $chunkX $chunkZ"); if(count($chunkData->getEntityNBT()) !== 0){ $this->timings->syncChunkLoadEntities->startTiming(); $entityFactory = EntityFactory::getInstance(); @@ -2449,8 +2450,8 @@ class World implements ChunkManager{ try{ $entity = $entityFactory->createFromData($this, $nbt); }catch(NbtDataException $e){ - $this->getLogger()->error("Chunk $chunkX $chunkZ: Bad entity data at list position $k: " . $e->getMessage()); - $this->getLogger()->logException($e); + $logger->error("Bad entity data at list position $k: " . $e->getMessage()); + $logger->logException($e); continue; } if($entity === null){ @@ -2461,7 +2462,7 @@ class World implements ChunkManager{ }elseif($saveIdTag instanceof IntTag){ //legacy MCPE format $saveId = "legacy(" . $saveIdTag->getValue() . ")"; } - $this->getLogger()->warning("Chunk $chunkX $chunkZ: Deleted unknown entity type $saveId"); + $logger->warning("Deleted unknown entity type $saveId"); } //TODO: we can't prevent entities getting added to unloaded chunks if they were saved in the wrong place //here, because entities currently add themselves to the world @@ -2477,16 +2478,16 @@ class World implements ChunkManager{ try{ $tile = $tileFactory->createFromData($this, $nbt); }catch(NbtDataException $e){ - $this->getLogger()->error("Chunk $chunkX $chunkZ: Bad tile entity data at list position $k: " . $e->getMessage()); - $this->getLogger()->logException($e); + $logger->error("Bad tile entity data at list position $k: " . $e->getMessage()); + $logger->logException($e); continue; } if($tile === null){ - $this->getLogger()->warning("Chunk $chunkX $chunkZ: Deleted unknown tile entity type " . $nbt->getString("id", "")); + $logger->warning("Deleted unknown tile entity type " . $nbt->getString("id", "")); }elseif(!$this->isChunkLoaded($tile->getPosition()->getFloorX() >> Chunk::COORD_BIT_SIZE, $tile->getPosition()->getFloorZ() >> Chunk::COORD_BIT_SIZE)){ - $this->logger->error("Chunk $chunkX $chunkZ: Found tile saved on wrong chunk - unable to fix due to correct chunk not loaded"); + $logger->error("Found tile saved on wrong chunk - unable to fix due to correct chunk not loaded"); }elseif($this->getTile($tilePosition = $tile->getPosition()) !== null){ - $this->logger->error("Chunk $chunkX $chunkZ: Cannot add tile at x=$tilePosition->x,y=$tilePosition->y,z=$tilePosition->z: Another tile is already at that position"); + $logger->error("Cannot add tile at x=$tilePosition->x,y=$tilePosition->y,z=$tilePosition->z: Another tile is already at that position"); }else{ $this->addTile($tile); } From fbb91d123d882315715fc2261a44cecce94f68a6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Oct 2021 14:03:40 +0000 Subject: [PATCH 3066/3224] World::unregisterChunkListenerFromAll(): go through unregisterChunkListener() this ensures that everything gets cleaned up properly (e.g. player chunk listeners). --- src/world/World.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index ab7e18ce96..484b06182e 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -731,14 +731,9 @@ class World implements ChunkManager{ * Unregisters a chunk listener from all chunks it is listening on in this World. */ public function unregisterChunkListenerFromAll(ChunkListener $listener) : void{ - $id = spl_object_id($listener); foreach($this->chunkListeners as $hash => $listeners){ - if(isset($listeners[$id])){ - unset($this->chunkListeners[$hash][$id]); - if(count($this->chunkListeners[$hash]) === 0){ - unset($this->chunkListeners[$hash]); - } - } + World::getXZ($hash, $chunkX, $chunkZ); + $this->unregisterChunkListener($listener, $chunkX, $chunkZ); } } From 018006541ec2d0b130846ef17b181de8dc9b6934 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Oct 2021 14:12:12 +0000 Subject: [PATCH 3067/3224] changelog: mention block-picking changes [ci skip] --- changelogs/4.0.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index dd27e019de..12f7fff642 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1274,6 +1274,8 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` ### Inventory - Implemented offhand inventory. +- Block-picking is now supported in survival mode. +- Block picking behaviour now matches vanilla (no longer overwrites held item, jumps to existing item where possible). # 4.0.0-BETA2 Released 10th September 2021. From 4fe3f697025831dcd9f7f316147bcc53e7b300c2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Oct 2021 14:33:27 +0000 Subject: [PATCH 3068/3224] World: eliminate final remaining 'no loaders attached' debug message on player creation --- src/world/World.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 484b06182e..a285af58e8 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2801,6 +2801,8 @@ class World implements ChunkManager{ } } + $temporaryChunkLoader = new class implements ChunkLoader{}; + $this->registerChunkLoader($temporaryChunkLoader, $x, $z); $chunk = $this->loadChunk($x, $z); if($chunk === null || !$chunk->isPopulated()){ Timings::$population->startTiming(); @@ -2811,11 +2813,12 @@ class World implements ChunkManager{ $this->chunkPopulationRequestMap[$index] = $promise; } - $temporaryChunkLoader = new class implements ChunkLoader{}; for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ $this->lockChunk($x + $xx, $z + $zz); - $this->registerChunkLoader($temporaryChunkLoader, $x + $xx, $z + $zz); + if($xx !== 0 || $zz !== 0){ //avoid registering it twice for the center chunk; we already did that above + $this->registerChunkLoader($temporaryChunkLoader, $x + $xx, $z + $zz); + } } } @@ -2830,6 +2833,8 @@ class World implements ChunkManager{ return $promise; } + $this->unregisterChunkLoader($temporaryChunkLoader, $x, $z); + //chunk is already populated; return a pre-resolved promise that will directly fire callbacks assigned $result = new Promise(); $result->resolve($chunk); From c580bb24341e645c9dc4586239b7206ddcce880a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Oct 2021 14:41:31 +0000 Subject: [PATCH 3069/3224] InGamePacketHandler: mark player as not using item in more cases fixes #4355 --- src/network/mcpe/handler/InGamePacketHandler.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index ef49cb355b..a884bf7c2c 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -297,6 +297,7 @@ class InGamePacketHandler extends PacketHandler{ //all of the parts before we can execute it return true; } + $this->player->setUsingItem(false); try{ $this->inventoryManager->onTransactionStart($this->craftingTransaction); $this->craftingTransaction->execute(); @@ -332,6 +333,7 @@ class InGamePacketHandler extends PacketHandler{ return true; } + $this->player->setUsingItem(false); $transaction = new InventoryTransaction($this->player, $actions); $this->inventoryManager->onTransactionStart($transaction); try{ From 866020dfdb06434b4f361a4a0f0faf7a89c30ed2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Oct 2021 16:43:32 +0000 Subject: [PATCH 3070/3224] Player: do not re-request the same ungenerated chunks multiple times this doesn't affect chunk resends, since they'll be kicked back to NEEDED, which is detected by orderChunks(). --- src/network/mcpe/NetworkSession.php | 2 +- src/player/Player.php | 14 +++++--------- src/player/UsedChunkStatus.php | 6 ++++-- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index fc46f8ae55..82f1516b6e 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -924,7 +924,7 @@ class NetworkSession{ $this->logger->debug("Tried to send no-longer-active chunk $chunkX $chunkZ in world " . $world->getFolderName()); return; } - if(!$status->equals(UsedChunkStatus::REQUESTED())){ + if(!$status->equals(UsedChunkStatus::REQUESTED_SENDING())){ //TODO: make this an error //this could be triggered due to the shitty way that chunk resends are handled //right now - not because of the spammy re-requesting, but because the chunk status reverts diff --git a/src/player/Player.php b/src/player/Player.php index 2f743fea3b..469c025f78 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -676,7 +676,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ ++$count; - $this->usedChunks[$index] = UsedChunkStatus::NEEDED(); + $this->usedChunks[$index] = UsedChunkStatus::REQUESTED_GENERATION(); + unset($this->loadQueue[$index]); $this->getWorld()->registerChunkLoader($this->chunkLoader, $X, $Z, true); $this->getWorld()->registerChunkListener($this, $X, $Z); @@ -685,15 +686,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ if(!$this->isConnected() || !isset($this->usedChunks[$index]) || $world !== $this->getWorld()){ return; } - if(!$this->usedChunks[$index]->equals(UsedChunkStatus::NEEDED())){ - //TODO: make this an error - //we may have added multiple completion handlers, since the Player keeps re-requesting chunks - //it doesn't have yet (a relic from the old system, but also currently relied on for chunk resends). - //in this event, make sure we don't try to send the chunk multiple times. - return; + if(!$this->usedChunks[$index]->equals(UsedChunkStatus::REQUESTED_GENERATION())){ + throw new AssumptionFailedError("Used chunk status should not have changed while in REQUESTED_GENERATION mode"); } - unset($this->loadQueue[$index]); - $this->usedChunks[$index] = UsedChunkStatus::REQUESTED(); + $this->usedChunks[$index] = UsedChunkStatus::REQUESTED_SENDING(); $this->getNetworkSession()->startUsingChunk($X, $Z, function() use ($X, $Z, $index) : void{ $this->usedChunks[$index] = UsedChunkStatus::SENT(); diff --git a/src/player/UsedChunkStatus.php b/src/player/UsedChunkStatus.php index bbdb9a0616..fa8227628a 100644 --- a/src/player/UsedChunkStatus.php +++ b/src/player/UsedChunkStatus.php @@ -32,7 +32,8 @@ use pocketmine\utils\EnumTrait; * @generate-registry-docblock * * @method static UsedChunkStatus NEEDED() - * @method static UsedChunkStatus REQUESTED() + * @method static UsedChunkStatus REQUESTED_GENERATION() + * @method static UsedChunkStatus REQUESTED_SENDING() * @method static UsedChunkStatus SENT() */ final class UsedChunkStatus{ @@ -41,7 +42,8 @@ final class UsedChunkStatus{ protected static function setup() : void{ self::registerAll( new self("NEEDED"), - new self("REQUESTED"), + new self("REQUESTED_GENERATION"), + new self("REQUESTED_SENDING"), new self("SENT") ); } From f1a791ef75fdbaf0d9923b84ebbfa619d963a1c2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Oct 2021 19:49:57 +0000 Subject: [PATCH 3071/3224] Improved Promise API - separate resolver and consumer APIs this makes creating a promise slightly more cumbersome, but I'm more concerned about people who might try to call 'new Promise' directly. --- src/Server.php | 15 ++++--- src/utils/Promise.php | 60 ++++---------------------- src/utils/PromiseResolver.php | 75 +++++++++++++++++++++++++++++++++ src/utils/PromiseSharedData.php | 51 ++++++++++++++++++++++ src/world/World.php | 39 ++++++++--------- 5 files changed, 163 insertions(+), 77 deletions(-) create mode 100644 src/utils/PromiseResolver.php create mode 100644 src/utils/PromiseSharedData.php diff --git a/src/Server.php b/src/Server.php index dcec8fb053..475a4385be 100644 --- a/src/Server.php +++ b/src/Server.php @@ -98,6 +98,7 @@ use pocketmine\utils\NotCloneable; use pocketmine\utils\NotSerializable; use pocketmine\utils\Process; use pocketmine\utils\Promise; +use pocketmine\utils\PromiseResolver; use pocketmine\utils\SignalHandler; use pocketmine\utils\Terminal; use pocketmine\utils\TextFormat; @@ -548,11 +549,11 @@ class Server{ $playerPos = null; $spawn = $world->getSpawnLocation(); } - $playerPromise = new Promise(); + $playerPromiseResolver = new PromiseResolver(); $world->requestChunkPopulation($spawn->getFloorX() >> Chunk::COORD_BIT_SIZE, $spawn->getFloorZ() >> Chunk::COORD_BIT_SIZE, null)->onCompletion( - function() use ($playerPromise, $class, $session, $playerInfo, $authenticated, $world, $playerPos, $spawn, $offlinePlayerData) : void{ + function() use ($playerPromiseResolver, $class, $session, $playerInfo, $authenticated, $world, $playerPos, $spawn, $offlinePlayerData) : void{ if(!$session->isConnected()){ - $playerPromise->reject(); + $playerPromiseResolver->reject(); return; } @@ -572,16 +573,16 @@ class Server{ if(!$player->hasPlayedBefore()){ $player->onGround = true; //TODO: this hack is needed for new players in-air ticks - they don't get detected as on-ground until they move } - $playerPromise->resolve($player); + $playerPromiseResolver->resolve($player); }, - static function() use ($playerPromise, $session) : void{ + static function() use ($playerPromiseResolver, $session) : void{ if($session->isConnected()){ $session->disconnect("Spawn terrain generation failed"); } - $playerPromise->reject(); + $playerPromiseResolver->reject(); } ); - return $playerPromise; + return $playerPromiseResolver->getPromise(); } /** diff --git a/src/utils/Promise.php b/src/utils/Promise.php index 4ccfc4bc56..c4cf7eb2fd 100644 --- a/src/utils/Promise.php +++ b/src/utils/Promise.php @@ -30,64 +30,22 @@ use function spl_object_id; */ final class Promise{ /** - * @var \Closure[] - * @phpstan-var array + * @internal Do NOT call this directly; create a new Resolver and call Resolver->promise() + * @see PromiseResolver + * @phpstan-param PromiseSharedData $shared */ - private array $onSuccess = []; - - /** - * @var \Closure[] - * @phpstan-var array - */ - private array $onFailure = []; - - private bool $resolved = false; - - /** - * @var mixed - * @phpstan-var TValue|null - */ - private $result = null; + public function __construct(private PromiseSharedData $shared){} /** * @phpstan-param \Closure(TValue) : void $onSuccess * @phpstan-param \Closure() : void $onFailure */ public function onCompletion(\Closure $onSuccess, \Closure $onFailure) : void{ - if($this->resolved){ - $this->result === null ? $onFailure() : $onSuccess($this->result); + if($this->shared->resolved){ + $this->shared->result === null ? $onFailure() : $onSuccess($this->shared->result); }else{ - $this->onSuccess[spl_object_id($onSuccess)] = $onSuccess; - $this->onFailure[spl_object_id($onFailure)] = $onFailure; + $this->shared->onSuccess[spl_object_id($onSuccess)] = $onSuccess; + $this->shared->onFailure[spl_object_id($onFailure)] = $onFailure; } } - - /** - * @param mixed $value - * @phpstan-param TValue $value - */ - public function resolve($value) : void{ - if($this->resolved){ - throw new \InvalidStateException("Promise has already been resolved/rejected"); - } - $this->resolved = true; - $this->result = $value; - foreach($this->onSuccess as $c){ - $c($value); - } - $this->onSuccess = []; - $this->onFailure = []; - } - - public function reject() : void{ - if($this->resolved){ - throw new \InvalidStateException("Promise has already been resolved/rejected"); - } - $this->resolved = true; - foreach($this->onFailure as $c){ - $c(); - } - $this->onSuccess = []; - $this->onFailure = []; - } -} +} \ No newline at end of file diff --git a/src/utils/PromiseResolver.php b/src/utils/PromiseResolver.php new file mode 100644 index 0000000000..860d683b0e --- /dev/null +++ b/src/utils/PromiseResolver.php @@ -0,0 +1,75 @@ + */ + private PromiseSharedData $shared; + /** @phpstan-var Promise */ + private Promise $promise; + + public function __construct(){ + $this->shared = new PromiseSharedData(); + $this->promise = new Promise($this->shared); + } + + /** + * @param mixed $value + * @phpstan-param TValue $value + */ + public function resolve($value) : void{ + if($this->shared->resolved){ + throw new \InvalidStateException("Promise has already been resolved/rejected"); + } + $this->shared->resolved = true; + $this->shared->result = $value; + foreach($this->shared->onSuccess as $c){ + $c($value); + } + $this->shared->onSuccess = []; + $this->shared->onFailure = []; + } + + public function reject() : void{ + if($this->shared->resolved){ + throw new \InvalidStateException("Promise has already been resolved/rejected"); + } + $this->shared->resolved = true; + foreach($this->shared->onFailure as $c){ + $c(); + } + $this->shared->onSuccess = []; + $this->shared->onFailure = []; + } + + /** + * @phpstan-return Promise + */ + public function getPromise() : Promise{ + return $this->promise; + } +} \ No newline at end of file diff --git a/src/utils/PromiseSharedData.php b/src/utils/PromiseSharedData.php new file mode 100644 index 0000000000..05c5ab0074 --- /dev/null +++ b/src/utils/PromiseSharedData.php @@ -0,0 +1,51 @@ + + */ + public array $onSuccess = []; + + /** + * @var \Closure[] + * @phpstan-var array + */ + public array $onFailure = []; + + public bool $resolved = false; + + /** + * @var mixed + * @phpstan-var TValue|null + */ + public $result = null; +} diff --git a/src/world/World.php b/src/world/World.php index a285af58e8..2d391a92a8 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -72,6 +72,7 @@ use pocketmine\timings\Timings; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Limits; use pocketmine\utils\Promise; +use pocketmine\utils\PromiseResolver; use pocketmine\utils\ReversePriorityQueue; use pocketmine\world\biome\Biome; use pocketmine\world\biome\BiomeRegistry; @@ -253,8 +254,8 @@ class World implements ChunkManager{ /** @var int */ private $maxConcurrentChunkPopulationTasks = 2; /** - * @var Promise[] chunkHash => promise - * @phpstan-var array> + * @var PromiseResolver[] chunkHash => promise + * @phpstan-var array> */ private array $chunkPopulationRequestMap = []; /** @@ -2717,16 +2718,16 @@ class World implements ChunkManager{ private function enqueuePopulationRequest(int $chunkX, int $chunkZ, ?ChunkLoader $associatedChunkLoader) : Promise{ $chunkHash = World::chunkHash($chunkX, $chunkZ); $this->chunkPopulationRequestQueue->enqueue($chunkHash); - $promise = $this->chunkPopulationRequestMap[$chunkHash] = new Promise(); + $resolver = $this->chunkPopulationRequestMap[$chunkHash] = new PromiseResolver(); if($associatedChunkLoader === null){ $temporaryLoader = new class implements ChunkLoader{}; $this->registerChunkLoader($temporaryLoader, $chunkX, $chunkZ); - $promise->onCompletion( + $resolver->getPromise()->onCompletion( fn() => $this->unregisterChunkLoader($temporaryLoader, $chunkX, $chunkZ), static function() : void{} ); } - return $promise; + return $resolver->getPromise(); } private function drainPopulationRequestQueue() : void{ @@ -2763,14 +2764,14 @@ class World implements ChunkManager{ */ public function requestChunkPopulation(int $chunkX, int $chunkZ, ?ChunkLoader $associatedChunkLoader) : Promise{ $chunkHash = World::chunkHash($chunkX, $chunkZ); - $promise = $this->chunkPopulationRequestMap[$chunkHash] ?? null; - if($promise !== null && isset($this->activeChunkPopulationTasks[$chunkHash])){ + $resolver = $this->chunkPopulationRequestMap[$chunkHash] ?? null; + if($resolver !== null && isset($this->activeChunkPopulationTasks[$chunkHash])){ //generation is already running - return $promise; + return $resolver->getPromise(); } if(count($this->activeChunkPopulationTasks) >= $this->maxConcurrentChunkPopulationTasks){ //too many chunks are already generating; delay resolution of the request until later - return $promise ?? $this->enqueuePopulationRequest($chunkX, $chunkZ, $associatedChunkLoader); + return $resolver?->getPromise() ?? $this->enqueuePopulationRequest($chunkX, $chunkZ, $associatedChunkLoader); } return $this->orderChunkPopulation($chunkX, $chunkZ, $associatedChunkLoader); } @@ -2787,16 +2788,16 @@ class World implements ChunkManager{ */ public function orderChunkPopulation(int $x, int $z, ?ChunkLoader $associatedChunkLoader) : Promise{ $index = World::chunkHash($x, $z); - $promise = $this->chunkPopulationRequestMap[$index] ?? null; - if($promise !== null && isset($this->activeChunkPopulationTasks[$index])){ + $resolver = $this->chunkPopulationRequestMap[$index] ?? null; + if($resolver !== null && isset($this->activeChunkPopulationTasks[$index])){ //generation is already running - return $promise; + return $resolver->getPromise(); } for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ if($this->isChunkLocked($x + $xx, $z + $zz)){ //chunk is already in use by another generation request; queue the request for later - return $promise ?? $this->enqueuePopulationRequest($x, $z, $associatedChunkLoader); + return $resolver?->getPromise() ?? $this->enqueuePopulationRequest($x, $z, $associatedChunkLoader); } } } @@ -2808,9 +2809,9 @@ class World implements ChunkManager{ Timings::$population->startTiming(); $this->activeChunkPopulationTasks[$index] = true; - if($promise === null){ - $promise = new Promise(); - $this->chunkPopulationRequestMap[$index] = $promise; + if($resolver === null){ + $resolver = new PromiseResolver(); + $this->chunkPopulationRequestMap[$index] = $resolver; } for($xx = -1; $xx <= 1; ++$xx){ @@ -2830,15 +2831,15 @@ class World implements ChunkManager{ $this->workerPool->submitTaskToWorker($task, $workerId); Timings::$population->stopTiming(); - return $promise; + return $resolver->getPromise(); } $this->unregisterChunkLoader($temporaryChunkLoader, $x, $z); //chunk is already populated; return a pre-resolved promise that will directly fire callbacks assigned - $result = new Promise(); + $result = new PromiseResolver(); $result->resolve($chunk); - return $result; + return $result->getPromise(); } /** From 0f78a2b5efac27fb7e16832c11c8d80f15b252a2 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Sun, 31 Oct 2021 21:11:20 +0000 Subject: [PATCH 3072/3224] Advisory chunk locking for chunk population (#4513) this allows chunks locked for population to be modified. If the PopulationTask detects that the chunk was modified during the onCompletion(), the result of the population will be discarded and rescheduled, so that it includes user modifications. --- src/world/ChunkLockId.php | 38 ++++++++ src/world/World.php | 117 ++++++++++++++++++------- src/world/generator/PopulationTask.php | 9 +- 3 files changed, 129 insertions(+), 35 deletions(-) create mode 100644 src/world/ChunkLockId.php diff --git a/src/world/ChunkLockId.php b/src/world/ChunkLockId.php new file mode 100644 index 0000000000..312b8c9109 --- /dev/null +++ b/src/world/ChunkLockId.php @@ -0,0 +1,38 @@ +> Chunk::COORD_BIT_SIZE; $chunkZ = $z >> Chunk::COORD_BIT_SIZE; - if($this->isChunkLocked($chunkX, $chunkZ)){ - throw new WorldException("Terrain is locked for generation/population"); - } if($this->loadChunk($chunkX, $chunkZ) === null){ //current expected behaviour is to try to load the terrain synchronously throw new WorldException("Cannot set a block in un-generated terrain"); } $this->timings->setBlock->startTiming(); + $this->unlockChunk($chunkX, $chunkZ, null); + $oldBlock = $this->getBlockAt($x, $y, $z, true, false); $block = clone $block; @@ -2046,10 +2045,7 @@ class World implements ChunkManager{ public function setBiomeId(int $x, int $z, int $biomeId) : void{ $chunkX = $x >> Chunk::COORD_BIT_SIZE; $chunkZ = $z >> Chunk::COORD_BIT_SIZE; - if($this->isChunkLocked($chunkX, $chunkZ)){ - //the changes would be overwritten when the generation finishes - throw new WorldException("Chunk is currently locked for async generation/population"); - } + $this->unlockChunk($chunkX, $chunkZ, null); if(($chunk = $this->loadChunk($chunkX, $chunkZ)) !== null){ $chunk->setBiomeId($x & Chunk::COORD_MASK, $z & Chunk::COORD_MASK, $biomeId); }else{ @@ -2103,18 +2099,50 @@ class World implements ChunkManager{ return $result; } - public function lockChunk(int $chunkX, int $chunkZ) : void{ + /** + * Flags a chunk as locked, usually for async modification. + * + * This is an **advisory lock**. This means that the lock does **not** prevent the chunk from being modified on the + * main thread, such as by setBlock() or setBiomeId(). However, you can use it to detect when such modifications + * have taken place - unlockChunk() with the same lockID will fail and return false if this happens. + * + * This is used internally by the generation system to ensure that two PopulationTasks don't try to modify the same + * chunk at the same time. Generation will respect these locks and won't try to do generation of chunks over which + * a lock is held. + * + * WARNING: Be sure to release all locks once you're done with them, or you WILL have problems with terrain not + * being generated. + */ + public function lockChunk(int $chunkX, int $chunkZ, ChunkLockId $lockId) : void{ $chunkHash = World::chunkHash($chunkX, $chunkZ); if(isset($this->chunkLock[$chunkHash])){ throw new \InvalidArgumentException("Chunk $chunkX $chunkZ is already locked"); } - $this->chunkLock[$chunkHash] = true; + $this->chunkLock[$chunkHash] = $lockId; } - public function unlockChunk(int $chunkX, int $chunkZ) : void{ - unset($this->chunkLock[World::chunkHash($chunkX, $chunkZ)]); + /** + * Unlocks a chunk previously locked by lockChunk(). + * + * You must provide the same lockID as provided to lockChunk(). + * If a null lockID is given, any existing lock will be removed from the chunk, regardless of who owns it. + * + * Returns true if unlocking was successful, false otherwise. + */ + public function unlockChunk(int $chunkX, int $chunkZ, ?ChunkLockId $lockId) : bool{ + $chunkHash = World::chunkHash($chunkX, $chunkZ); + if(isset($this->chunkLock[$chunkHash]) && ($lockId === null || $this->chunkLock[$chunkHash] === $lockId)){ + unset($this->chunkLock[$chunkHash]); + return true; + } + return false; } + /** + * Returns whether anyone currently has a lock on the chunk at the given coordinates. + * You should check this to make sure that population tasks aren't currently modifying chunks that you want to use + * in async tasks. + */ public function isChunkLocked(int $chunkX, int $chunkZ) : bool{ return isset($this->chunkLock[World::chunkHash($chunkX, $chunkZ)]); } @@ -2814,16 +2842,18 @@ class World implements ChunkManager{ $this->chunkPopulationRequestMap[$index] = $resolver; } + $chunkPopulationLockId = new ChunkLockId(); + for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ - $this->lockChunk($x + $xx, $z + $zz); + $this->lockChunk($x + $xx, $z + $zz, $chunkPopulationLockId); if($xx !== 0 || $zz !== 0){ //avoid registering it twice for the center chunk; we already did that above $this->registerChunkLoader($temporaryChunkLoader, $x + $xx, $z + $zz); } } } - $task = new PopulationTask($this, $x, $z, $chunk, $temporaryChunkLoader); + $task = new PopulationTask($this, $x, $z, $chunk, $temporaryChunkLoader, $chunkPopulationLockId); $workerId = $this->workerPool->selectWorker(); if(!isset($this->generatorRegisteredWorkers[$workerId])){ $this->registerGeneratorToWorker($workerId); @@ -2843,10 +2873,10 @@ class World implements ChunkManager{ } /** - * @param Chunk[] $adjacentChunks + * @param Chunk[] $adjacentChunks chunkHash => chunk * @phpstan-param array $adjacentChunks */ - public function generateChunkCallback(int $x, int $z, Chunk $chunk, array $adjacentChunks, ChunkLoader $temporaryChunkLoader) : void{ + public function generateChunkCallback(ChunkLockId $chunkLockId, int $x, int $z, Chunk $chunk, array $adjacentChunks, ChunkLoader $temporaryChunkLoader) : void{ Timings::$generationCallback->startTiming(); for($xx = -1; $xx <= 1; ++$xx){ @@ -2856,31 +2886,52 @@ class World implements ChunkManager{ } if(isset($this->chunkPopulationRequestMap[$index = World::chunkHash($x, $z)]) && isset($this->activeChunkPopulationTasks[$index])){ + $dirtyChunks = 0; for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ - $this->unlockChunk($x + $xx, $z + $zz); + if(!$this->unlockChunk($x + $xx, $z + $zz, $chunkLockId)){ + $dirtyChunks++; + } } } + if($dirtyChunks === 0){ + $oldChunk = $this->loadChunk($x, $z); + $this->setChunk($x, $z, $chunk); - $oldChunk = $this->loadChunk($x, $z); - $this->setChunk($x, $z, $chunk); - - foreach($adjacentChunks as $adjacentChunkHash => $adjacentChunk){ - World::getXZ($adjacentChunkHash, $xAdjacentChunk, $zAdjacentChunk); - $this->setChunk($xAdjacentChunk, $zAdjacentChunk, $adjacentChunk); - } - - if(($oldChunk === null or !$oldChunk->isPopulated()) and $chunk->isPopulated()){ - (new ChunkPopulateEvent($this, $x, $z, $chunk))->call(); - - foreach($this->getChunkListeners($x, $z) as $listener){ - $listener->onChunkPopulated($x, $z, $chunk); + foreach($adjacentChunks as $adjacentChunkHash => $adjacentChunk){ + World::getXZ($adjacentChunkHash, $xAdjacentChunk, $zAdjacentChunk); + $this->setChunk($xAdjacentChunk, $zAdjacentChunk, $adjacentChunk); } + + if(($oldChunk === null or !$oldChunk->isPopulated()) and $chunk->isPopulated()){ + (new ChunkPopulateEvent($this, $x, $z, $chunk))->call(); + + foreach($this->getChunkListeners($x, $z) as $listener){ + $listener->onChunkPopulated($x, $z, $chunk); + } + } + }else{ + $this->logger->debug("Discarding population result for chunk x=$x,z=$z - terrain was modified on the main thread before async population completed"); } + + //This needs to be in this specific spot because user code might call back to orderChunkPopulation(). + //If it does, and finds the promise, and doesn't find an active task associated with it, it will schedule + //another PopulationTask. We don't want that because we're here processing the results. + //We can't remove the promise from the array before setting the chunks in the world because that would lead + //to the same problem. Therefore, it's necessary that this code be split into two if/else, with this in the + //middle. unset($this->activeChunkPopulationTasks[$index]); - $promise = $this->chunkPopulationRequestMap[$index]; - unset($this->chunkPopulationRequestMap[$index]); - $promise->resolve($chunk); + + if($dirtyChunks === 0){ + $promise = $this->chunkPopulationRequestMap[$index]; + unset($this->chunkPopulationRequestMap[$index]); + $promise->resolve($chunk); + }else{ + //request failed, stick it back on the queue + //we didn't resolve the promise or touch it in any way, so any fake chunk loaders are still valid and + //don't need to be added a second time. + $this->chunkPopulationRequestQueue->enqueue($index); + } $this->drainPopulationRequestQueue(); } diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 19c0038fa3..5a628248d9 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -27,6 +27,7 @@ use pocketmine\data\bedrock\BiomeIds; use pocketmine\scheduler\AsyncTask; use pocketmine\utils\AssumptionFailedError; use pocketmine\world\ChunkLoader; +use pocketmine\world\ChunkLockId; use pocketmine\world\format\BiomeArray; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\FastChunkSerializer; @@ -40,6 +41,7 @@ use function intdiv; class PopulationTask extends AsyncTask{ private const TLS_KEY_WORLD = "world"; private const TLS_KEY_CHUNK_LOADER = "chunkLoader"; + private const TLS_KEY_LOCK_ID = "chunkLockId"; /** @var int */ public $worldId; @@ -53,7 +55,7 @@ class PopulationTask extends AsyncTask{ private string $adjacentChunks; - public function __construct(World $world, int $chunkX, int $chunkZ, ?Chunk $chunk, ChunkLoader $temporaryChunkLoader){ + public function __construct(World $world, int $chunkX, int $chunkZ, ?Chunk $chunk, ChunkLoader $temporaryChunkLoader, ChunkLockId $chunkLockId){ $this->worldId = $world->getId(); $this->chunkX = $chunkX; $this->chunkZ = $chunkZ; @@ -66,6 +68,7 @@ class PopulationTask extends AsyncTask{ $this->storeLocal(self::TLS_KEY_WORLD, $world); $this->storeLocal(self::TLS_KEY_CHUNK_LOADER, $temporaryChunkLoader); + $this->storeLocal(self::TLS_KEY_LOCK_ID, $chunkLockId); } public function onRun() : void{ @@ -131,6 +134,8 @@ class PopulationTask extends AsyncTask{ $world = $this->fetchLocal(self::TLS_KEY_WORLD); /** @var ChunkLoader $temporaryChunkLoader */ $temporaryChunkLoader = $this->fetchLocal(self::TLS_KEY_CHUNK_LOADER); + /** @var ChunkLockId $lockId */ + $lockId = $this->fetchLocal(self::TLS_KEY_LOCK_ID); if($world->isLoaded()){ $chunk = $this->chunk !== null ? FastChunkSerializer::deserializeTerrain($this->chunk) : @@ -151,7 +156,7 @@ class PopulationTask extends AsyncTask{ } } - $world->generateChunkCallback($this->chunkX, $this->chunkZ, $chunk, $adjacentChunks, $temporaryChunkLoader); + $world->generateChunkCallback($lockId, $this->chunkX, $this->chunkZ, $chunk, $adjacentChunks, $temporaryChunkLoader); } } } From 3265d3f6b4d6705276b56fab5f765e2f97b5d992 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Oct 2021 21:23:36 +0000 Subject: [PATCH 3073/3224] Revert "Player: do not re-request the same ungenerated chunks multiple times" This reverts commit 866020dfdb06434b4f361a4a0f0faf7a89c30ed2. For some fucking reason this broke resending chunks in some cases (and sending chunks at all in others). I don't have time to debug this right now, so it's going to have to remain broken, infuriatingly enough. --- src/network/mcpe/NetworkSession.php | 2 +- src/player/Player.php | 14 +++++++++----- src/player/UsedChunkStatus.php | 6 ++---- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 82f1516b6e..fc46f8ae55 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -924,7 +924,7 @@ class NetworkSession{ $this->logger->debug("Tried to send no-longer-active chunk $chunkX $chunkZ in world " . $world->getFolderName()); return; } - if(!$status->equals(UsedChunkStatus::REQUESTED_SENDING())){ + if(!$status->equals(UsedChunkStatus::REQUESTED())){ //TODO: make this an error //this could be triggered due to the shitty way that chunk resends are handled //right now - not because of the spammy re-requesting, but because the chunk status reverts diff --git a/src/player/Player.php b/src/player/Player.php index 469c025f78..2f743fea3b 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -676,8 +676,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ ++$count; - $this->usedChunks[$index] = UsedChunkStatus::REQUESTED_GENERATION(); - unset($this->loadQueue[$index]); + $this->usedChunks[$index] = UsedChunkStatus::NEEDED(); $this->getWorld()->registerChunkLoader($this->chunkLoader, $X, $Z, true); $this->getWorld()->registerChunkListener($this, $X, $Z); @@ -686,10 +685,15 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ if(!$this->isConnected() || !isset($this->usedChunks[$index]) || $world !== $this->getWorld()){ return; } - if(!$this->usedChunks[$index]->equals(UsedChunkStatus::REQUESTED_GENERATION())){ - throw new AssumptionFailedError("Used chunk status should not have changed while in REQUESTED_GENERATION mode"); + if(!$this->usedChunks[$index]->equals(UsedChunkStatus::NEEDED())){ + //TODO: make this an error + //we may have added multiple completion handlers, since the Player keeps re-requesting chunks + //it doesn't have yet (a relic from the old system, but also currently relied on for chunk resends). + //in this event, make sure we don't try to send the chunk multiple times. + return; } - $this->usedChunks[$index] = UsedChunkStatus::REQUESTED_SENDING(); + unset($this->loadQueue[$index]); + $this->usedChunks[$index] = UsedChunkStatus::REQUESTED(); $this->getNetworkSession()->startUsingChunk($X, $Z, function() use ($X, $Z, $index) : void{ $this->usedChunks[$index] = UsedChunkStatus::SENT(); diff --git a/src/player/UsedChunkStatus.php b/src/player/UsedChunkStatus.php index fa8227628a..bbdb9a0616 100644 --- a/src/player/UsedChunkStatus.php +++ b/src/player/UsedChunkStatus.php @@ -32,8 +32,7 @@ use pocketmine\utils\EnumTrait; * @generate-registry-docblock * * @method static UsedChunkStatus NEEDED() - * @method static UsedChunkStatus REQUESTED_GENERATION() - * @method static UsedChunkStatus REQUESTED_SENDING() + * @method static UsedChunkStatus REQUESTED() * @method static UsedChunkStatus SENT() */ final class UsedChunkStatus{ @@ -42,8 +41,7 @@ final class UsedChunkStatus{ protected static function setup() : void{ self::registerAll( new self("NEEDED"), - new self("REQUESTED_GENERATION"), - new self("REQUESTED_SENDING"), + new self("REQUESTED"), new self("SENT") ); } From 08636d079dd4c390a36b89f433fa7e823d945975 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Oct 2021 22:48:52 +0000 Subject: [PATCH 3074/3224] Promise: expose isResolved() --- src/utils/Promise.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/utils/Promise.php b/src/utils/Promise.php index c4cf7eb2fd..d9ae9c5637 100644 --- a/src/utils/Promise.php +++ b/src/utils/Promise.php @@ -48,4 +48,8 @@ final class Promise{ $this->shared->onFailure[spl_object_id($onFailure)] = $onFailure; } } + + public function isResolved() : bool{ + return $this->shared->resolved; + } } \ No newline at end of file From 2fa0a914ff6dce7a051e176374c3441098b5e255 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Oct 2021 22:51:37 +0000 Subject: [PATCH 3075/3224] World::orderChunkPopulation() may return a pre-resolved promise this does not indicate a failure; it indicates that the chunk has already been successfully populated. In this case, we shouldn't be putting the task back on the queue. This is skirting around the real bug, which is that requestChunkPopulation() doesn't check if the target chunk is already populated before it creates a new promise that it will be. --- src/world/World.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 2267d4c085..7c17cc88bb 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2765,8 +2765,10 @@ class World implements ChunkManager{ World::getXZ($nextChunkHash, $nextChunkX, $nextChunkZ); if(isset($this->chunkPopulationRequestMap[$nextChunkHash])){ assert(!isset($this->activeChunkPopulationTasks[$nextChunkHash]), "Population for chunk $nextChunkX $nextChunkZ already running"); - $this->orderChunkPopulation($nextChunkX, $nextChunkZ, null); - if(!isset($this->activeChunkPopulationTasks[$nextChunkHash])){ + if( + !$this->orderChunkPopulation($nextChunkX, $nextChunkZ, null)->isResolved() && + !isset($this->activeChunkPopulationTasks[$nextChunkHash]) + ){ $failed[] = $nextChunkHash; } } From 96cfdc79b85bbcf63d87811966c625d200d5014d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Oct 2021 22:54:37 +0000 Subject: [PATCH 3076/3224] World: fixed original promise not getting fulfilled if the chunk became populated=true after a promise was already made (but not fulfilled) to populate it this could happen if a plugin calls setPopulated(true) on a chunk after a request for its population landed in the queue, but before it actually got processed. In that case, the promise would never get fulfilled. --- src/world/World.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 7c17cc88bb..47b4fd7122 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2869,9 +2869,9 @@ class World implements ChunkManager{ $this->unregisterChunkLoader($temporaryChunkLoader, $x, $z); //chunk is already populated; return a pre-resolved promise that will directly fire callbacks assigned - $result = new PromiseResolver(); - $result->resolve($chunk); - return $result->getPromise(); + $resolver ??= new PromiseResolver(); + $resolver->resolve($chunk); + return $resolver->getPromise(); } /** From bd60e41268c52aba16513cfc86e5dd41cfc4bea9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Oct 2021 22:57:56 +0000 Subject: [PATCH 3077/3224] Revert "Revert "Player: do not re-request the same ungenerated chunks multiple times"" This reverts commit 3265d3f6b4d6705276b56fab5f765e2f97b5d992. --- src/network/mcpe/NetworkSession.php | 2 +- src/player/Player.php | 14 +++++--------- src/player/UsedChunkStatus.php | 6 ++++-- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index fc46f8ae55..82f1516b6e 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -924,7 +924,7 @@ class NetworkSession{ $this->logger->debug("Tried to send no-longer-active chunk $chunkX $chunkZ in world " . $world->getFolderName()); return; } - if(!$status->equals(UsedChunkStatus::REQUESTED())){ + if(!$status->equals(UsedChunkStatus::REQUESTED_SENDING())){ //TODO: make this an error //this could be triggered due to the shitty way that chunk resends are handled //right now - not because of the spammy re-requesting, but because the chunk status reverts diff --git a/src/player/Player.php b/src/player/Player.php index 2f743fea3b..469c025f78 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -676,7 +676,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ ++$count; - $this->usedChunks[$index] = UsedChunkStatus::NEEDED(); + $this->usedChunks[$index] = UsedChunkStatus::REQUESTED_GENERATION(); + unset($this->loadQueue[$index]); $this->getWorld()->registerChunkLoader($this->chunkLoader, $X, $Z, true); $this->getWorld()->registerChunkListener($this, $X, $Z); @@ -685,15 +686,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ if(!$this->isConnected() || !isset($this->usedChunks[$index]) || $world !== $this->getWorld()){ return; } - if(!$this->usedChunks[$index]->equals(UsedChunkStatus::NEEDED())){ - //TODO: make this an error - //we may have added multiple completion handlers, since the Player keeps re-requesting chunks - //it doesn't have yet (a relic from the old system, but also currently relied on for chunk resends). - //in this event, make sure we don't try to send the chunk multiple times. - return; + if(!$this->usedChunks[$index]->equals(UsedChunkStatus::REQUESTED_GENERATION())){ + throw new AssumptionFailedError("Used chunk status should not have changed while in REQUESTED_GENERATION mode"); } - unset($this->loadQueue[$index]); - $this->usedChunks[$index] = UsedChunkStatus::REQUESTED(); + $this->usedChunks[$index] = UsedChunkStatus::REQUESTED_SENDING(); $this->getNetworkSession()->startUsingChunk($X, $Z, function() use ($X, $Z, $index) : void{ $this->usedChunks[$index] = UsedChunkStatus::SENT(); diff --git a/src/player/UsedChunkStatus.php b/src/player/UsedChunkStatus.php index bbdb9a0616..fa8227628a 100644 --- a/src/player/UsedChunkStatus.php +++ b/src/player/UsedChunkStatus.php @@ -32,7 +32,8 @@ use pocketmine\utils\EnumTrait; * @generate-registry-docblock * * @method static UsedChunkStatus NEEDED() - * @method static UsedChunkStatus REQUESTED() + * @method static UsedChunkStatus REQUESTED_GENERATION() + * @method static UsedChunkStatus REQUESTED_SENDING() * @method static UsedChunkStatus SENT() */ final class UsedChunkStatus{ @@ -41,7 +42,8 @@ final class UsedChunkStatus{ protected static function setup() : void{ self::registerAll( new self("NEEDED"), - new self("REQUESTED"), + new self("REQUESTED_GENERATION"), + new self("REQUESTED_SENDING"), new self("SENT") ); } From 74031d2fbea2256262aa81a45ce5f6f5f45ff54d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Oct 2021 23:05:12 +0000 Subject: [PATCH 3078/3224] World: remove the fulfilled promise from the population request map fixes crash when unregistering chunk loaders --- src/world/World.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/world/World.php b/src/world/World.php index 47b4fd7122..2cd4fab2c7 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2870,6 +2870,7 @@ class World implements ChunkManager{ //chunk is already populated; return a pre-resolved promise that will directly fire callbacks assigned $resolver ??= new PromiseResolver(); + unset($this->chunkPopulationRequestMap[$index]); $resolver->resolve($chunk); return $resolver->getPromise(); } From 9dec82cdbc168a900fd860d9b5739bb9cf1df88c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Oct 2021 23:40:34 +0000 Subject: [PATCH 3079/3224] World: fixed requestChunkPopulation() queuing requests for chunks which are already populated this led to chunk sending getting bogged down if there were more than population-queue-size chunks waiting to be generated. --- src/world/World.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index 2cd4fab2c7..f58b3ca29d 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2799,6 +2799,19 @@ class World implements ChunkManager{ //generation is already running return $resolver->getPromise(); } + + $temporaryChunkLoader = new class implements ChunkLoader{}; + $this->registerChunkLoader($temporaryChunkLoader, $chunkX, $chunkZ); + $chunk = $this->loadChunk($chunkX, $chunkZ); + $this->unregisterChunkLoader($temporaryChunkLoader, $chunkX, $chunkZ); + if($chunk !== null && $chunk->isPopulated()){ + //chunk is already populated; return a pre-resolved promise that will directly fire callbacks assigned + $resolver ??= new PromiseResolver(); + unset($this->chunkPopulationRequestMap[$chunkHash]); + $resolver->resolve($chunk); + return $resolver->getPromise(); + } + if(count($this->activeChunkPopulationTasks) >= $this->maxConcurrentChunkPopulationTasks){ //too many chunks are already generating; delay resolution of the request until later return $resolver?->getPromise() ?? $this->enqueuePopulationRequest($chunkX, $chunkZ, $associatedChunkLoader); From f4a3c40b5c3ab39a1432e5c358e27c6aa8884e58 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Oct 2021 23:48:00 +0000 Subject: [PATCH 3080/3224] World: use better variable names in orderChunkPopulation() --- src/world/World.php | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index f58b3ca29d..3fa24f12e2 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2829,46 +2829,46 @@ class World implements ChunkManager{ * * @phpstan-return Promise */ - public function orderChunkPopulation(int $x, int $z, ?ChunkLoader $associatedChunkLoader) : Promise{ - $index = World::chunkHash($x, $z); - $resolver = $this->chunkPopulationRequestMap[$index] ?? null; - if($resolver !== null && isset($this->activeChunkPopulationTasks[$index])){ + public function orderChunkPopulation(int $chunkX, int $chunkZ, ?ChunkLoader $associatedChunkLoader) : Promise{ + $chunkHash = World::chunkHash($chunkX, $chunkZ); + $resolver = $this->chunkPopulationRequestMap[$chunkHash] ?? null; + if($resolver !== null && isset($this->activeChunkPopulationTasks[$chunkHash])){ //generation is already running return $resolver->getPromise(); } for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ - if($this->isChunkLocked($x + $xx, $z + $zz)){ + if($this->isChunkLocked($chunkX + $xx, $chunkZ + $zz)){ //chunk is already in use by another generation request; queue the request for later - return $resolver?->getPromise() ?? $this->enqueuePopulationRequest($x, $z, $associatedChunkLoader); + return $resolver?->getPromise() ?? $this->enqueuePopulationRequest($chunkX, $chunkZ, $associatedChunkLoader); } } } $temporaryChunkLoader = new class implements ChunkLoader{}; - $this->registerChunkLoader($temporaryChunkLoader, $x, $z); - $chunk = $this->loadChunk($x, $z); + $this->registerChunkLoader($temporaryChunkLoader, $chunkX, $chunkZ); + $chunk = $this->loadChunk($chunkX, $chunkZ); if($chunk === null || !$chunk->isPopulated()){ Timings::$population->startTiming(); - $this->activeChunkPopulationTasks[$index] = true; + $this->activeChunkPopulationTasks[$chunkHash] = true; if($resolver === null){ $resolver = new PromiseResolver(); - $this->chunkPopulationRequestMap[$index] = $resolver; + $this->chunkPopulationRequestMap[$chunkHash] = $resolver; } $chunkPopulationLockId = new ChunkLockId(); for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ - $this->lockChunk($x + $xx, $z + $zz, $chunkPopulationLockId); + $this->lockChunk($chunkX + $xx, $chunkZ + $zz, $chunkPopulationLockId); if($xx !== 0 || $zz !== 0){ //avoid registering it twice for the center chunk; we already did that above - $this->registerChunkLoader($temporaryChunkLoader, $x + $xx, $z + $zz); + $this->registerChunkLoader($temporaryChunkLoader, $chunkX + $xx, $chunkZ + $zz); } } } - $task = new PopulationTask($this, $x, $z, $chunk, $temporaryChunkLoader, $chunkPopulationLockId); + $task = new PopulationTask($this, $chunkX, $chunkZ, $chunk, $temporaryChunkLoader, $chunkPopulationLockId); $workerId = $this->workerPool->selectWorker(); if(!isset($this->generatorRegisteredWorkers[$workerId])){ $this->registerGeneratorToWorker($workerId); @@ -2879,11 +2879,11 @@ class World implements ChunkManager{ return $resolver->getPromise(); } - $this->unregisterChunkLoader($temporaryChunkLoader, $x, $z); + $this->unregisterChunkLoader($temporaryChunkLoader, $chunkX, $chunkZ); //chunk is already populated; return a pre-resolved promise that will directly fire callbacks assigned $resolver ??= new PromiseResolver(); - unset($this->chunkPopulationRequestMap[$index]); + unset($this->chunkPopulationRequestMap[$chunkHash]); $resolver->resolve($chunk); return $resolver->getPromise(); } From 8f803df5114182bac73621694a32ae38bb95c48e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 31 Oct 2021 23:54:27 +0000 Subject: [PATCH 3081/3224] World: check population locks _after_ checking if the chunk is already populated, not before this led to another case where a population request would be queued up for an already-populated chunk for no reason. --- src/world/World.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 3fa24f12e2..375869da17 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2836,14 +2836,6 @@ class World implements ChunkManager{ //generation is already running return $resolver->getPromise(); } - for($xx = -1; $xx <= 1; ++$xx){ - for($zz = -1; $zz <= 1; ++$zz){ - if($this->isChunkLocked($chunkX + $xx, $chunkZ + $zz)){ - //chunk is already in use by another generation request; queue the request for later - return $resolver?->getPromise() ?? $this->enqueuePopulationRequest($chunkX, $chunkZ, $associatedChunkLoader); - } - } - } $temporaryChunkLoader = new class implements ChunkLoader{}; $this->registerChunkLoader($temporaryChunkLoader, $chunkX, $chunkZ); @@ -2851,6 +2843,15 @@ class World implements ChunkManager{ if($chunk === null || !$chunk->isPopulated()){ Timings::$population->startTiming(); + for($xx = -1; $xx <= 1; ++$xx){ + for($zz = -1; $zz <= 1; ++$zz){ + if($this->isChunkLocked($chunkX + $xx, $chunkZ + $zz)){ + //chunk is already in use by another generation request; queue the request for later + return $resolver?->getPromise() ?? $this->enqueuePopulationRequest($chunkX, $chunkZ, $associatedChunkLoader); + } + } + } + $this->activeChunkPopulationTasks[$chunkHash] = true; if($resolver === null){ $resolver = new PromiseResolver(); From afb54f1ae4380c2a65ad423de599dd9ea73939c7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 1 Nov 2021 00:25:30 +0000 Subject: [PATCH 3082/3224] World: flip orderChunkPopulation() condition around this makes it more obvious that the code is similar to requestChunkPopulation() barring one distinct difference. --- src/world/World.php | 82 ++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 375869da17..b1726e1446 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2840,52 +2840,52 @@ class World implements ChunkManager{ $temporaryChunkLoader = new class implements ChunkLoader{}; $this->registerChunkLoader($temporaryChunkLoader, $chunkX, $chunkZ); $chunk = $this->loadChunk($chunkX, $chunkZ); - if($chunk === null || !$chunk->isPopulated()){ - Timings::$population->startTiming(); + if($chunk !== null && $chunk->isPopulated()){ + $this->unregisterChunkLoader($temporaryChunkLoader, $chunkX, $chunkZ); - for($xx = -1; $xx <= 1; ++$xx){ - for($zz = -1; $zz <= 1; ++$zz){ - if($this->isChunkLocked($chunkX + $xx, $chunkZ + $zz)){ - //chunk is already in use by another generation request; queue the request for later - return $resolver?->getPromise() ?? $this->enqueuePopulationRequest($chunkX, $chunkZ, $associatedChunkLoader); - } - } - } - - $this->activeChunkPopulationTasks[$chunkHash] = true; - if($resolver === null){ - $resolver = new PromiseResolver(); - $this->chunkPopulationRequestMap[$chunkHash] = $resolver; - } - - $chunkPopulationLockId = new ChunkLockId(); - - for($xx = -1; $xx <= 1; ++$xx){ - for($zz = -1; $zz <= 1; ++$zz){ - $this->lockChunk($chunkX + $xx, $chunkZ + $zz, $chunkPopulationLockId); - if($xx !== 0 || $zz !== 0){ //avoid registering it twice for the center chunk; we already did that above - $this->registerChunkLoader($temporaryChunkLoader, $chunkX + $xx, $chunkZ + $zz); - } - } - } - - $task = new PopulationTask($this, $chunkX, $chunkZ, $chunk, $temporaryChunkLoader, $chunkPopulationLockId); - $workerId = $this->workerPool->selectWorker(); - if(!isset($this->generatorRegisteredWorkers[$workerId])){ - $this->registerGeneratorToWorker($workerId); - } - $this->workerPool->submitTaskToWorker($task, $workerId); - - Timings::$population->stopTiming(); + //chunk is already populated; return a pre-resolved promise that will directly fire callbacks assigned + $resolver ??= new PromiseResolver(); + unset($this->chunkPopulationRequestMap[$chunkHash]); + $resolver->resolve($chunk); return $resolver->getPromise(); } - $this->unregisterChunkLoader($temporaryChunkLoader, $chunkX, $chunkZ); + Timings::$population->startTiming(); - //chunk is already populated; return a pre-resolved promise that will directly fire callbacks assigned - $resolver ??= new PromiseResolver(); - unset($this->chunkPopulationRequestMap[$chunkHash]); - $resolver->resolve($chunk); + for($xx = -1; $xx <= 1; ++$xx){ + for($zz = -1; $zz <= 1; ++$zz){ + if($this->isChunkLocked($chunkX + $xx, $chunkZ + $zz)){ + //chunk is already in use by another generation request; queue the request for later + return $resolver?->getPromise() ?? $this->enqueuePopulationRequest($chunkX, $chunkZ, $associatedChunkLoader); + } + } + } + + $this->activeChunkPopulationTasks[$chunkHash] = true; + if($resolver === null){ + $resolver = new PromiseResolver(); + $this->chunkPopulationRequestMap[$chunkHash] = $resolver; + } + + $chunkPopulationLockId = new ChunkLockId(); + + for($xx = -1; $xx <= 1; ++$xx){ + for($zz = -1; $zz <= 1; ++$zz){ + $this->lockChunk($chunkX + $xx, $chunkZ + $zz, $chunkPopulationLockId); + if($xx !== 0 || $zz !== 0){ //avoid registering it twice for the center chunk; we already did that above + $this->registerChunkLoader($temporaryChunkLoader, $chunkX + $xx, $chunkZ + $zz); + } + } + } + + $task = new PopulationTask($this, $chunkX, $chunkZ, $chunk, $temporaryChunkLoader, $chunkPopulationLockId); + $workerId = $this->workerPool->selectWorker(); + if(!isset($this->generatorRegisteredWorkers[$workerId])){ + $this->registerGeneratorToWorker($workerId); + } + $this->workerPool->submitTaskToWorker($task, $workerId); + + Timings::$population->stopTiming(); return $resolver->getPromise(); } From e4a54f5b6ab96866c478bb7aedbe23124b7abc99 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 1 Nov 2021 00:33:18 +0000 Subject: [PATCH 3083/3224] World: deduplicate code in request/orderChunkPopulation --- src/world/World.php | 67 ++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index b1726e1446..74cf528213 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2782,22 +2782,16 @@ class World implements ChunkManager{ } /** - * Attempts to initiate asynchronous generation/population of the target chunk, if it's currently reasonable to do - * so (and if it isn't already generated/populated). - * If the generator is busy, the request will be put into a queue and delayed until a better time. - * - * A ChunkLoader can be associated with the generation request to ensure that the generation request is cancelled if - * no loaders are attached to the target chunk. If no loader is provided, one will be assigned (and automatically - * removed when the generation request completes). - * - * @phpstan-return Promise + * Checks if a chunk needs to be populated, and whether it's ready to do so. + * @return bool[]|PromiseResolver[]|null[] + * @phpstan-return array{?PromiseResolver, bool} */ - public function requestChunkPopulation(int $chunkX, int $chunkZ, ?ChunkLoader $associatedChunkLoader) : Promise{ + private function checkChunkPopulationPreconditions(int $chunkX, int $chunkZ) : array{ $chunkHash = World::chunkHash($chunkX, $chunkZ); $resolver = $this->chunkPopulationRequestMap[$chunkHash] ?? null; if($resolver !== null && isset($this->activeChunkPopulationTasks[$chunkHash])){ //generation is already running - return $resolver->getPromise(); + return [$resolver, false]; } $temporaryChunkLoader = new class implements ChunkLoader{}; @@ -2809,7 +2803,26 @@ class World implements ChunkManager{ $resolver ??= new PromiseResolver(); unset($this->chunkPopulationRequestMap[$chunkHash]); $resolver->resolve($chunk); - return $resolver->getPromise(); + return [$resolver, false]; + } + return [$resolver, true]; + } + + /** + * Attempts to initiate asynchronous generation/population of the target chunk, if it's currently reasonable to do + * so (and if it isn't already generated/populated). + * If the generator is busy, the request will be put into a queue and delayed until a better time. + * + * A ChunkLoader can be associated with the generation request to ensure that the generation request is cancelled if + * no loaders are attached to the target chunk. If no loader is provided, one will be assigned (and automatically + * removed when the generation request completes). + * + * @phpstan-return Promise + */ + public function requestChunkPopulation(int $chunkX, int $chunkZ, ?ChunkLoader $associatedChunkLoader) : Promise{ + [$resolver, $proceedWithPopulation] = $this->checkChunkPopulationPreconditions($chunkX, $chunkZ); + if(!$proceedWithPopulation){ + return $resolver?->getPromise() ?? $this->enqueuePopulationRequest($chunkX, $chunkZ, $associatedChunkLoader); } if(count($this->activeChunkPopulationTasks) >= $this->maxConcurrentChunkPopulationTasks){ @@ -2830,25 +2843,12 @@ class World implements ChunkManager{ * @phpstan-return Promise */ public function orderChunkPopulation(int $chunkX, int $chunkZ, ?ChunkLoader $associatedChunkLoader) : Promise{ + [$resolver, $proceedWithPopulation] = $this->checkChunkPopulationPreconditions($chunkX, $chunkZ); + if(!$proceedWithPopulation){ + return $resolver?->getPromise() ?? $this->enqueuePopulationRequest($chunkX, $chunkZ, $associatedChunkLoader); + } + $chunkHash = World::chunkHash($chunkX, $chunkZ); - $resolver = $this->chunkPopulationRequestMap[$chunkHash] ?? null; - if($resolver !== null && isset($this->activeChunkPopulationTasks[$chunkHash])){ - //generation is already running - return $resolver->getPromise(); - } - - $temporaryChunkLoader = new class implements ChunkLoader{}; - $this->registerChunkLoader($temporaryChunkLoader, $chunkX, $chunkZ); - $chunk = $this->loadChunk($chunkX, $chunkZ); - if($chunk !== null && $chunk->isPopulated()){ - $this->unregisterChunkLoader($temporaryChunkLoader, $chunkX, $chunkZ); - - //chunk is already populated; return a pre-resolved promise that will directly fire callbacks assigned - $resolver ??= new PromiseResolver(); - unset($this->chunkPopulationRequestMap[$chunkHash]); - $resolver->resolve($chunk); - return $resolver->getPromise(); - } Timings::$population->startTiming(); @@ -2869,16 +2869,15 @@ class World implements ChunkManager{ $chunkPopulationLockId = new ChunkLockId(); + $temporaryChunkLoader = new class implements ChunkLoader{}; for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ $this->lockChunk($chunkX + $xx, $chunkZ + $zz, $chunkPopulationLockId); - if($xx !== 0 || $zz !== 0){ //avoid registering it twice for the center chunk; we already did that above - $this->registerChunkLoader($temporaryChunkLoader, $chunkX + $xx, $chunkZ + $zz); - } + $this->registerChunkLoader($temporaryChunkLoader, $chunkX + $xx, $chunkZ + $zz); } } - $task = new PopulationTask($this, $chunkX, $chunkZ, $chunk, $temporaryChunkLoader, $chunkPopulationLockId); + $task = new PopulationTask($this, $chunkX, $chunkZ, $this->loadChunk($chunkX, $chunkZ), $temporaryChunkLoader, $chunkPopulationLockId); $workerId = $this->workerPool->selectWorker(); if(!isset($this->generatorRegisteredWorkers[$workerId])){ $this->registerGeneratorToWorker($workerId); From c781efcf90c3bff76899462058255304978654a3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 1 Nov 2021 00:36:57 +0000 Subject: [PATCH 3084/3224] World: avoid calling the same logic twice in requestChunkPopulation() orderChunkPopulation() checks the preconditions too. Have them both call an internal function that doesn't. --- src/world/World.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index 74cf528213..17de8eefeb 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2829,7 +2829,7 @@ class World implements ChunkManager{ //too many chunks are already generating; delay resolution of the request until later return $resolver?->getPromise() ?? $this->enqueuePopulationRequest($chunkX, $chunkZ, $associatedChunkLoader); } - return $this->orderChunkPopulation($chunkX, $chunkZ, $associatedChunkLoader); + return $this->internalOrderChunkPopulation($chunkX, $chunkZ, $associatedChunkLoader, $resolver); } /** @@ -2848,6 +2848,14 @@ class World implements ChunkManager{ return $resolver?->getPromise() ?? $this->enqueuePopulationRequest($chunkX, $chunkZ, $associatedChunkLoader); } + return $this->internalOrderChunkPopulation($chunkX, $chunkZ, $associatedChunkLoader, $resolver); + } + + /** + * @phpstan-param PromiseResolver|null $resolver + * @phpstan-return Promise + */ + private function internalOrderChunkPopulation(int $chunkX, int $chunkZ, ?ChunkLoader $associatedChunkLoader, ?PromiseResolver $resolver) : Promise{ $chunkHash = World::chunkHash($chunkX, $chunkZ); Timings::$population->startTiming(); From 46b7d35cd38114d86536941c6216d34c95cb96b8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 1 Nov 2021 01:45:49 +0000 Subject: [PATCH 3085/3224] Player: return from callback if used chunk status is not REQUESTED_GENERATION() this can happen especially on large render distances when flying fast and changing direction - we decide we don't want the chunk, then, after changing direction and re-ordering chunks, we decide we do want it again, and end up registering a second callback. In this case, we need to ensure that only one of the callbacks gets executed (it doesn't matter which one). --- src/player/Player.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index 469c025f78..5c34c66806 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -687,7 +687,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return; } if(!$this->usedChunks[$index]->equals(UsedChunkStatus::REQUESTED_GENERATION())){ - throw new AssumptionFailedError("Used chunk status should not have changed while in REQUESTED_GENERATION mode"); + //We may have previously requested this, decided we didn't want it, and then decided we did want + //it again, all before the generation request got executed. In that case, the promise would have + //multiple callbacks for this player. In that case, only the first one matters. + return; } $this->usedChunks[$index] = UsedChunkStatus::REQUESTED_SENDING(); From 9d30bc8b95705b41177f677293b6ede46acc63e8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 1 Nov 2021 02:17:11 +0000 Subject: [PATCH 3086/3224] World: fixed assertion failure when requesting, cancelling, and then re-requesting chunks via requestChunkPopulation() if the request/cancel/re-request happens all in the time before the queue gets drained, chunk hashes may appear multiple times in the queue. We don't want to process them twice if this happens (although it's mostly harmless anyway). --- src/world/World.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index 17de8eefeb..ded2d9524b 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2760,8 +2760,17 @@ class World implements ChunkManager{ private function drainPopulationRequestQueue() : void{ $failed = []; + $seen = []; while(count($this->activeChunkPopulationTasks) < $this->maxConcurrentChunkPopulationTasks && !$this->chunkPopulationRequestQueue->isEmpty()){ $nextChunkHash = $this->chunkPopulationRequestQueue->dequeue(); + if(isset($seen[$nextChunkHash])){ + //We may have previously requested this, decided we didn't want it, and then decided we did want it + //again, all before the generation request got executed. In that case, the chunk hash may appear in the + //queue multiple times (it can't be quickly removed from the queue when the request is cancelled, so we + //leave it in the queue). + continue; + } + $seen[$nextChunkHash] = true; World::getXZ($nextChunkHash, $nextChunkX, $nextChunkZ); if(isset($this->chunkPopulationRequestMap[$nextChunkHash])){ assert(!isset($this->activeChunkPopulationTasks[$nextChunkHash]), "Population for chunk $nextChunkX $nextChunkZ already running"); From 616eb0050dc9e760b95db60fd944b77fe94c46f5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 1 Nov 2021 02:34:44 +0000 Subject: [PATCH 3087/3224] World: remove premature optimisation of setBlockAt() introduced by ece28e5d7b0d4c8d12a9477cdd1d3337277e892d closes #4531 it turns out that letting the light updates themselves handle this is faster than trying to get in the way. --- src/world/World.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index ded2d9524b..a6c71cd6fe 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1596,8 +1596,6 @@ class World implements ChunkManager{ $this->unlockChunk($chunkX, $chunkZ, null); - $oldBlock = $this->getBlockAt($x, $y, $z, true, false); - $block = clone $block; $block->position($this, $x, $y, $z); @@ -1619,9 +1617,7 @@ class World implements ChunkManager{ } if($update){ - if($oldBlock->getLightFilter() !== $block->getLightFilter() or $oldBlock->getLightLevel() !== $block->getLightLevel()){ - $this->updateAllLight($x, $y, $z); - } + $this->updateAllLight($x, $y, $z); $this->tryAddToNeighbourUpdateQueue($pos); foreach($pos->sides() as $side){ $this->tryAddToNeighbourUpdateQueue($side); From f6480017ce31039f90635e7cffcbfb6e7180145b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 1 Nov 2021 16:12:37 +0000 Subject: [PATCH 3088/3224] Update PHPUnit dependency junk --- composer.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.lock b/composer.lock index 747ede1148..34c1f14b09 100644 --- a/composer.lock +++ b/composer.lock @@ -2054,23 +2054,23 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.7", + "version": "9.2.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "d4c798ed8d51506800b441f7a13ecb0f76f12218" + "reference": "cf04e88a2e3c56fc1a65488afd493325b4c1bc3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d4c798ed8d51506800b441f7a13ecb0f76f12218", - "reference": "d4c798ed8d51506800b441f7a13ecb0f76f12218", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/cf04e88a2e3c56fc1a65488afd493325b4c1bc3e", + "reference": "cf04e88a2e3c56fc1a65488afd493325b4c1bc3e", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.12.0", + "nikic/php-parser": "^4.13.0", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -2119,7 +2119,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.7" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.8" }, "funding": [ { @@ -2127,7 +2127,7 @@ "type": "github" } ], - "time": "2021-09-17T05:39:03+00:00" + "time": "2021-10-30T08:01:38+00:00" }, { "name": "phpunit/php-file-iterator", From c3768b997a835cc3bcc39627e0ef4d4d0ddab8e5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 1 Nov 2021 16:13:33 +0000 Subject: [PATCH 3089/3224] Updated to pmmp/BedrockProtocol@146498c279b3dc645ab6b8cdf45f7b96d8a33f8b --- composer.lock | 8 ++++---- src/network/mcpe/NetworkSession.php | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 34c1f14b09..543a9524ca 100644 --- a/composer.lock +++ b/composer.lock @@ -253,12 +253,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "c8d891b4dff9817d5fcd373dfec0608b20be3b0a" + "reference": "146498c279b3dc645ab6b8cdf45f7b96d8a33f8b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/c8d891b4dff9817d5fcd373dfec0608b20be3b0a", - "reference": "c8d891b4dff9817d5fcd373dfec0608b20be3b0a", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/146498c279b3dc645ab6b8cdf45f7b96d8a33f8b", + "reference": "146498c279b3dc645ab6b8cdf45f7b96d8a33f8b", "shasum": "" }, "require": { @@ -293,7 +293,7 @@ "issues": "https://github.com/pmmp/BedrockProtocol/issues", "source": "https://github.com/pmmp/BedrockProtocol/tree/master" }, - "time": "2021-10-29T20:54:42+00:00" + "time": "2021-11-01T15:46:55+00:00" }, { "name": "pocketmine/binaryutils", diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 82f1516b6e..4a7cfe259c 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -348,6 +348,10 @@ class NetworkSession{ try{ foreach($stream->getPackets($this->packetPool, $this->packetSerializerContext, 500) as [$packet, $buffer]){ + if($packet === null){ + $this->logger->debug("Unknown packet: " . base64_encode($buffer)); + throw new PacketHandlingException("Unknown packet received"); + } try{ $this->handleDataPacket($packet, $buffer); }catch(PacketHandlingException $e){ From f6cb4f9597c703d32f8454138125a0c0b9d05ae5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 1 Nov 2021 21:32:02 +0000 Subject: [PATCH 3090/3224] Updated BedrockProtocol --- composer.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.lock b/composer.lock index ece09d4787..568e498eae 100644 --- a/composer.lock +++ b/composer.lock @@ -253,12 +253,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "146498c279b3dc645ab6b8cdf45f7b96d8a33f8b" + "reference": "c76e31fc948f58ad2b788679c84335684396d025" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/146498c279b3dc645ab6b8cdf45f7b96d8a33f8b", - "reference": "146498c279b3dc645ab6b8cdf45f7b96d8a33f8b", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/c76e31fc948f58ad2b788679c84335684396d025", + "reference": "c76e31fc948f58ad2b788679c84335684396d025", "shasum": "" }, "require": { @@ -272,9 +272,9 @@ "ramsey/uuid": "^4.1" }, "require-dev": { - "phpstan/phpstan": "0.12.99", - "phpstan/phpstan-phpunit": "^0.12.21", - "phpstan/phpstan-strict-rules": "^0.12.10", + "phpstan/phpstan": "1.0.0", + "phpstan/phpstan-phpunit": "^1.0.0", + "phpstan/phpstan-strict-rules": "^1.0.0", "phpunit/phpunit": "^9.5" }, "default-branch": true, @@ -293,7 +293,7 @@ "issues": "https://github.com/pmmp/BedrockProtocol/issues", "source": "https://github.com/pmmp/BedrockProtocol/tree/master" }, - "time": "2021-11-01T15:46:55+00:00" + "time": "2021-11-01T18:59:44+00:00" }, { "name": "pocketmine/binaryutils", From f2912fcdd827bceb559a4ee02901688917237231 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 1 Nov 2021 22:22:22 +0000 Subject: [PATCH 3091/3224] Updated pocketmine/log and pocketmine/log-pthreads (BC breaks included) AttachableLogger deals with Closures now instead of LoggerAttachment objects ThreadedLoggerAttachment no longer implements LoggerAttachment --- composer.json | 4 ++-- composer.lock | 30 +++++++++++++++--------------- src/plugin/PluginLogger.php | 20 ++++++++++++++++---- src/utils/MainLogger.php | 2 +- 4 files changed, 34 insertions(+), 22 deletions(-) diff --git a/composer.json b/composer.json index 14f5046be1..35adb7adcc 100644 --- a/composer.json +++ b/composer.json @@ -40,8 +40,8 @@ "pocketmine/classloader": "^0.2.0", "pocketmine/color": "^0.2.0", "pocketmine/errorhandler": "^0.3.0", - "pocketmine/log": "^0.3.0", - "pocketmine/log-pthreads": "^0.2.0", + "pocketmine/log": "^0.4.0", + "pocketmine/log-pthreads": "^0.4.0", "pocketmine/math": "^0.4.0", "pocketmine/nbt": "^0.3.0", "pocketmine/raklib": "^0.14.2", diff --git a/composer.lock b/composer.lock index 568e498eae..6f587ce0fe 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3aab4c7b78ea85bf5e68e8b953cd9e1f", + "content-hash": "9b3c01e7b850d45218b81a436f463011", "packages": [ { "name": "adhocore/json-comment", @@ -508,16 +508,16 @@ }, { "name": "pocketmine/log", - "version": "0.3.0", + "version": "0.4.0", "source": { "type": "git", "url": "https://github.com/pmmp/Log.git", - "reference": "03ab1316da0b1978a7a1c8dd73e1c2a973cb62ec" + "reference": "e6c912c0f9055c81d23108ec2d179b96f404c043" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Log/zipball/03ab1316da0b1978a7a1c8dd73e1c2a973cb62ec", - "reference": "03ab1316da0b1978a7a1c8dd73e1c2a973cb62ec", + "url": "https://api.github.com/repos/pmmp/Log/zipball/e6c912c0f9055c81d23108ec2d179b96f404c043", + "reference": "e6c912c0f9055c81d23108ec2d179b96f404c043", "shasum": "" }, "require": { @@ -527,7 +527,7 @@ "pocketmine/spl": "<0.4" }, "require-dev": { - "phpstan/phpstan": "0.12.80", + "phpstan/phpstan": "0.12.88", "phpstan/phpstan-strict-rules": "^0.12.2" }, "type": "library", @@ -543,28 +543,28 @@ "description": "Logging components used by PocketMine-MP and related projects", "support": { "issues": "https://github.com/pmmp/Log/issues", - "source": "https://github.com/pmmp/Log/tree/0.3.0" + "source": "https://github.com/pmmp/Log/tree/0.4.0" }, - "time": "2021-05-18T21:00:49+00:00" + "time": "2021-06-18T19:08:09+00:00" }, { "name": "pocketmine/log-pthreads", - "version": "0.2.1", + "version": "0.4.0", "source": { "type": "git", "url": "https://github.com/pmmp/LogPthreads.git", - "reference": "26f51ed44b1884f6dd72c06a883d9d07613af4f1" + "reference": "61f709e8cf36bcc24e4efe02acded680a1ce23cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/26f51ed44b1884f6dd72c06a883d9d07613af4f1", - "reference": "26f51ed44b1884f6dd72c06a883d9d07613af4f1", + "url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/61f709e8cf36bcc24e4efe02acded680a1ce23cd", + "reference": "61f709e8cf36bcc24e4efe02acded680a1ce23cd", "shasum": "" }, "require": { "ext-pthreads": "~3.2.0 || ^4.0", "php": "^7.4 || ^8.0", - "pocketmine/log": "^0.2.0 || ^0.3.0" + "pocketmine/log": "^0.4.0" }, "conflict": { "pocketmine/spl": "<0.4" @@ -587,9 +587,9 @@ "description": "Logging components specialized for pthreads used by PocketMine-MP and related projects", "support": { "issues": "https://github.com/pmmp/LogPthreads/issues", - "source": "https://github.com/pmmp/LogPthreads/tree/0.2.1" + "source": "https://github.com/pmmp/LogPthreads/tree/0.4.0" }, - "time": "2021-11-01T20:41:37+00:00" + "time": "2021-11-01T21:42:09+00:00" }, { "name": "pocketmine/math", diff --git a/src/plugin/PluginLogger.php b/src/plugin/PluginLogger.php index ba310563bf..1a1ab9cdb1 100644 --- a/src/plugin/PluginLogger.php +++ b/src/plugin/PluginLogger.php @@ -25,16 +25,28 @@ namespace pocketmine\plugin; use function spl_object_id; +/** + * @phpstan-import-type LoggerAttachment from \AttachableLogger + */ class PluginLogger extends \PrefixedLogger implements \AttachableLogger{ - /** @var \LoggerAttachment[] */ + /** + * @var \Closure[] + * @phpstan-var LoggerAttachment[] + */ private $attachments = []; - public function addAttachment(\LoggerAttachment $attachment){ + /** + * @phpstan-param LoggerAttachment $attachment + */ + public function addAttachment(\Closure $attachment){ $this->attachments[spl_object_id($attachment)] = $attachment; } - public function removeAttachment(\LoggerAttachment $attachment){ + /** + * @phpstan-param LoggerAttachment $attachment + */ + public function removeAttachment(\Closure $attachment){ unset($this->attachments[spl_object_id($attachment)]); } @@ -49,7 +61,7 @@ class PluginLogger extends \PrefixedLogger implements \AttachableLogger{ public function log($level, $message){ parent::log($level, $message); foreach($this->attachments as $attachment){ - $attachment->log($level, $message); + $attachment($level, $message); } } } diff --git a/src/utils/MainLogger.php b/src/utils/MainLogger.php index 1e5c530440..c7290f0d29 100644 --- a/src/utils/MainLogger.php +++ b/src/utils/MainLogger.php @@ -210,7 +210,7 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{ $this->logWriterThread->write($time->format("Y-m-d") . " " . TextFormat::clean($message) . PHP_EOL); foreach($this->attachments as $attachment){ - $attachment->call($level, $message); + $attachment->log($level, $message); } }); } From 0f6b7e48cb29f1abc2cb957c546077398f5b8a05 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 01:37:56 +0000 Subject: [PATCH 3092/3224] Updated BedrockProtocol: it's weirdly satisfying that LevelChunkPacket::create() with the extra parameter turns out to be exactly the same length as the old way. --- composer.lock | 8 ++++---- src/network/mcpe/ChunkRequestTask.php | 2 +- src/network/mcpe/NetworkSession.php | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 6f587ce0fe..b2878d494a 100644 --- a/composer.lock +++ b/composer.lock @@ -253,12 +253,12 @@ "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "c76e31fc948f58ad2b788679c84335684396d025" + "reference": "67c0c15b4044cab2190501933912c3d02c5f63ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/c76e31fc948f58ad2b788679c84335684396d025", - "reference": "c76e31fc948f58ad2b788679c84335684396d025", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/67c0c15b4044cab2190501933912c3d02c5f63ab", + "reference": "67c0c15b4044cab2190501933912c3d02c5f63ab", "shasum": "" }, "require": { @@ -293,7 +293,7 @@ "issues": "https://github.com/pmmp/BedrockProtocol/issues", "source": "https://github.com/pmmp/BedrockProtocol/tree/master" }, - "time": "2021-11-01T18:59:44+00:00" + "time": "2021-11-02T01:27:05+00:00" }, { "name": "pocketmine/binaryutils", diff --git a/src/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php index 676a480a96..8279fc00e6 100644 --- a/src/network/mcpe/ChunkRequestTask.php +++ b/src/network/mcpe/ChunkRequestTask.php @@ -72,7 +72,7 @@ class ChunkRequestTask extends AsyncTask{ $subCount = ChunkSerializer::getSubChunkCount($chunk); $encoderContext = new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary()); $payload = ChunkSerializer::serializeFullChunk($chunk, RuntimeBlockMapping::getInstance(), $encoderContext, $this->tiles); - $this->setResult($this->compressor->compress(PacketBatch::fromPackets($encoderContext, LevelChunkPacket::withoutCache($this->chunkX, $this->chunkZ, $subCount, $payload))->getBuffer())); + $this->setResult($this->compressor->compress(PacketBatch::fromPackets($encoderContext, LevelChunkPacket::create($this->chunkX, $this->chunkZ, $subCount, null, $payload))->getBuffer())); } public function onError() : void{ diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 4a7cfe259c..ed910c45ec 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -563,7 +563,7 @@ class NetworkSession{ */ private function doServerDisconnect(string $reason, bool $notify = true) : void{ if($notify){ - $this->sendDataPacket($reason === "" ? DisconnectPacket::silent() : DisconnectPacket::message($reason), true); + $this->sendDataPacket(DisconnectPacket::create($reason !== "" ? $reason : null), true); } $this->sender->close($notify ? $reason : ""); From c17587d436c36d5fc801999768e090d223899ee9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 03:00:00 +0000 Subject: [PATCH 3093/3224] World: use new Vector3() instead of Block->getPosition() When profiling this, I noticed that we spend a stupidly large amount of time creating useless Position objects in the case of update=true, because Vector3->sides() calls Position->getSide(), which calls Position::fromObject(parent::getSide()). This is stupid because the update logic doesn't require Positions anywhere (as evidenced by this change needing no other alterations. A rough profile shows that this improves setBlock() performance by about 25% in the update=true case, which is a pretty big margin. As an added bonus, it gets rid of some unrealized cyclic dependencies in World->changedBlocks. --- src/world/World.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index a6c71cd6fe..43768cfc3c 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1600,7 +1600,7 @@ class World implements ChunkManager{ $block->position($this, $x, $y, $z); $block->writeStateToWorld(); - $pos = $block->getPosition(); + $pos = new Vector3($x, $y, $z); $chunkHash = World::chunkHash($chunkX, $chunkZ); $relativeBlockHash = World::chunkBlockHash($x, $y, $z); From 7e4be29fc44c2a7298b5b803c3f805be940c3439 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 13:51:01 +0000 Subject: [PATCH 3094/3224] Gracefully force-shutdown on failure to start RakLib this now won't generate a crashdump. --- resources/locale | 2 +- src/Server.php | 15 ++++- src/lang/KnownTranslationFactory.php | 8 +++ src/lang/KnownTranslationKeys.php | 1 + src/network/Network.php | 3 + src/network/NetworkInterface.php | 1 + .../NetworkInterfaceStartException.php | 32 ++++++++++ src/network/mcpe/raklib/RakLibInterface.php | 11 +++- src/network/mcpe/raklib/RakLibServer.php | 30 ++++++--- .../mcpe/raklib/RakLibThreadCrashInfo.php | 61 +++++++++++++++++++ 10 files changed, 150 insertions(+), 14 deletions(-) create mode 100644 src/network/NetworkInterfaceStartException.php create mode 100644 src/network/mcpe/raklib/RakLibThreadCrashInfo.php diff --git a/resources/locale b/resources/locale index 09c709f242..f9076e4a6e 160000 --- a/resources/locale +++ b/resources/locale @@ -1 +1 @@ -Subproject commit 09c709f2426cb8d21d2a4851ad6df5a254a40fd4 +Subproject commit f9076e4a6e3049aeaf7abd30d39a482a1392eafe diff --git a/src/Server.php b/src/Server.php index 475a4385be..277a56ad6e 100644 --- a/src/Server.php +++ b/src/Server.php @@ -64,6 +64,7 @@ use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\network\mcpe\protocol\serializer\PacketBatch; use pocketmine\network\mcpe\raklib\RakLibInterface; use pocketmine\network\Network; +use pocketmine\network\NetworkInterfaceStartException; use pocketmine\network\query\DedicatedQueryNetworkInterface; use pocketmine\network\query\QueryHandler; use pocketmine\network\query\QueryInfo; @@ -980,6 +981,7 @@ class Server{ $this->enablePlugins(PluginEnableOrder::POSTWORLD()); if(!$this->startupPrepareNetworkInterfaces()){ + $this->forceShutdown(); return; } @@ -1113,7 +1115,18 @@ class Server{ private function startupPrepareNetworkInterfaces() : bool{ $useQuery = $this->configGroup->getConfigBool("enable-query", true); - if(!$this->network->registerInterface(new RakLibInterface($this)) && $useQuery){ + + try{ + $rakLibRegistered = $this->network->registerInterface(new RakLibInterface($this)); + }catch(NetworkInterfaceStartException $e){ + $this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_server_networkStartFailed( + $this->getIp(), + (string) $this->getPort(), + $e->getMessage() + ))); + return false; + } + if(!$rakLibRegistered && $useQuery){ //RakLib would normally handle the transport for Query packets //if it's not registered we need to make sure Query still works $this->network->registerInterface(new DedicatedQueryNetworkInterface($this->getIp(), $this->getPort(), new \PrefixedLogger($this->logger, "Dedicated Query Interface"))); diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index a08e87f5cd..04b644f831 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -1950,6 +1950,14 @@ final class KnownTranslationFactory{ ]); } + public static function pocketmine_server_networkStartFailed(Translatable|string $ipAddress, Translatable|string $port, Translatable|string $errorMessage) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_NETWORKSTARTFAILED, [ + "ipAddress" => $ipAddress, + "port" => $port, + "errorMessage" => $errorMessage, + ]); + } + public static function pocketmine_server_query_running(Translatable|string $param0, Translatable|string $param1) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_SERVER_QUERY_RUNNING, [ 0 => $param0, diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index cf4aca5553..2a609c8d86 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -401,6 +401,7 @@ final class KnownTranslationKeys{ public const POCKETMINE_SERVER_INFO_EXTENDED = "pocketmine.server.info.extended"; public const POCKETMINE_SERVER_LICENSE = "pocketmine.server.license"; public const POCKETMINE_SERVER_NETWORKSTART = "pocketmine.server.networkStart"; + public const POCKETMINE_SERVER_NETWORKSTARTFAILED = "pocketmine.server.networkStartFailed"; public const POCKETMINE_SERVER_QUERY_RUNNING = "pocketmine.server.query.running"; public const POCKETMINE_SERVER_START = "pocketmine.server.start"; public const POCKETMINE_SERVER_STARTFINISHED = "pocketmine.server.startFinished"; diff --git a/src/network/Network.php b/src/network/Network.php index 22c1b2f399..fc65e3acac 100644 --- a/src/network/Network.php +++ b/src/network/Network.php @@ -91,6 +91,9 @@ class Network{ $this->sessionManager->tick(); } + /** + * @throws NetworkInterfaceStartException + */ public function registerInterface(NetworkInterface $interface) : bool{ $ev = new NetworkInterfaceRegisterEvent($interface); $ev->call(); diff --git a/src/network/NetworkInterface.php b/src/network/NetworkInterface.php index 146a7351c5..a6beddbaeb 100644 --- a/src/network/NetworkInterface.php +++ b/src/network/NetworkInterface.php @@ -33,6 +33,7 @@ interface NetworkInterface{ /** * Performs actions needed to start the interface after it is registered. + * @throws NetworkInterfaceStartException */ public function start() : void; diff --git a/src/network/NetworkInterfaceStartException.php b/src/network/NetworkInterfaceStartException.php new file mode 100644 index 0000000000..3dfd2b0a7f --- /dev/null +++ b/src/network/NetworkInterfaceStartException.php @@ -0,0 +1,32 @@ +eventReceiver->handle($this)); }); $this->server->getLogger()->debug("Waiting for RakLib to start..."); - $this->rakLib->startAndWait(); + try{ + $this->rakLib->startAndWait(); + }catch(SocketException $e){ + throw new NetworkInterfaceStartException($e->getMessage(), 0, $e); + } $this->server->getLogger()->debug("RakLib booted successfully"); } @@ -132,7 +139,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ if(!$this->rakLib->isRunning()){ $e = $this->rakLib->getCrashInfo(); if($e !== null){ - throw new \RuntimeException("RakLib crashed: $e"); + throw new \RuntimeException("RakLib crashed: " . $e->makePrettyMessage()); } throw new \Exception("RakLib Thread crashed without crash information"); } diff --git a/src/network/mcpe/raklib/RakLibServer.php b/src/network/mcpe/raklib/RakLibServer.php index 7591475ee9..94ea2c9736 100644 --- a/src/network/mcpe/raklib/RakLibServer.php +++ b/src/network/mcpe/raklib/RakLibServer.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe\raklib; use pocketmine\snooze\SleeperNotifier; use pocketmine\thread\Thread; use raklib\generic\Socket; +use raklib\generic\SocketException; use raklib\server\ipc\RakLibToUserThreadMessageSender; use raklib\server\ipc\UserToRakLibThreadMessageReceiver; use raklib\server\Server; @@ -68,7 +69,7 @@ class RakLibServer extends Thread{ /** @var SleeperNotifier */ protected $mainThreadNotifier; - /** @var string|null */ + /** @var RakLibThreadCrashInfo|null */ public $crashInfo = null; public function __construct( @@ -102,24 +103,24 @@ class RakLibServer extends Thread{ * @return void */ public function shutdownHandler(){ - if($this->cleanShutdown !== true){ + if($this->cleanShutdown !== true && $this->crashInfo === null){ $error = error_get_last(); if($error !== null){ $this->logger->emergency("Fatal error: " . $error["message"] . " in " . $error["file"] . " on line " . $error["line"]); - $this->setCrashInfo($error['message']); + $this->setCrashInfo(RakLibThreadCrashInfo::fromLastErrorInfo($error)); }else{ $this->logger->emergency("RakLib shutdown unexpectedly"); } } } - public function getCrashInfo() : ?string{ + public function getCrashInfo() : ?RakLibThreadCrashInfo{ return $this->crashInfo; } - private function setCrashInfo(string $info) : void{ - $this->synchronized(function(string $info) : void{ + private function setCrashInfo(RakLibThreadCrashInfo $info) : void{ + $this->synchronized(function(RakLibThreadCrashInfo $info) : void{ $this->crashInfo = $info; $this->notify(); }, $info); @@ -131,8 +132,12 @@ class RakLibServer extends Thread{ while(!$this->ready and $this->crashInfo === null){ $this->wait(); } - if($this->crashInfo !== null){ - throw new \RuntimeException("RakLib failed to start: $this->crashInfo"); + $crashInfo = $this->crashInfo; + if($crashInfo !== null){ + if($crashInfo->getClass() === SocketException::class){ + throw new SocketException($crashInfo->getMessage()); + } + throw new \RuntimeException("RakLib failed to start: " . $crashInfo->makePrettyMessage()); } }); } @@ -145,7 +150,12 @@ class RakLibServer extends Thread{ register_shutdown_function([$this, "shutdownHandler"]); - $socket = new Socket($this->address); + try{ + $socket = new Socket($this->address); + }catch(SocketException $e){ + $this->setCrashInfo(RakLibThreadCrashInfo::fromThrowable($e)); + return; + } $manager = new Server( $this->serverId, $this->logger, @@ -166,7 +176,7 @@ class RakLibServer extends Thread{ $manager->waitShutdown(); $this->cleanShutdown = true; }catch(\Throwable $e){ - $this->setCrashInfo($e->getMessage()); + $this->setCrashInfo(RakLibThreadCrashInfo::fromThrowable($e)); $this->logger->logException($e); } } diff --git a/src/network/mcpe/raklib/RakLibThreadCrashInfo.php b/src/network/mcpe/raklib/RakLibThreadCrashInfo.php new file mode 100644 index 0000000000..826cdc42dc --- /dev/null +++ b/src/network/mcpe/raklib/RakLibThreadCrashInfo.php @@ -0,0 +1,61 @@ +getMessage(), $e->getFile(), $e->getLine()); + } + + /** + * @phpstan-param array{message: string, file: string, line: int} $info + */ + public static function fromLastErrorInfo(array $info) : self{ + return new self(null, $info["message"], $info["file"], $info["line"]); + } + + /** @return string|null */ + public function getClass() : ?string{ return $this->class; } + + public function getMessage() : string{ return $this->message; } + + public function getFile() : string{ return $this->file; } + + public function getLine() : int{ return $this->line; } + + public function makePrettyMessage() : string{ + return sprintf("%s: \"%s\" in %s on line %d", $this->class ?? "Fatal error", $this->message, Filesystem::cleanPath($this->file), $this->line); + } +} \ No newline at end of file From 32a857b8b4a45ec6945e6b91b1679ffc16c450e4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 14:09:16 +0000 Subject: [PATCH 3095/3224] fix CS --- src/network/mcpe/raklib/RakLibInterface.php | 1 - src/network/mcpe/raklib/RakLibThreadCrashInfo.php | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 0972360133..4bfee22584 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -36,7 +36,6 @@ use pocketmine\network\NetworkInterfaceStartException; use pocketmine\network\PacketHandlingException; use pocketmine\Server; use pocketmine\snooze\SleeperNotifier; -use pocketmine\utils\Filesystem; use pocketmine\utils\Utils; use raklib\generic\SocketException; use raklib\protocol\EncapsulatedPacket; diff --git a/src/network/mcpe/raklib/RakLibThreadCrashInfo.php b/src/network/mcpe/raklib/RakLibThreadCrashInfo.php index 826cdc42dc..806aebc85f 100644 --- a/src/network/mcpe/raklib/RakLibThreadCrashInfo.php +++ b/src/network/mcpe/raklib/RakLibThreadCrashInfo.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe\raklib; use pocketmine\utils\Filesystem; use function get_class; +use function sprintf; final class RakLibThreadCrashInfo{ From 1775699f05ee44094353fc13f815b1026d56ad47 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 14:20:42 +0000 Subject: [PATCH 3096/3224] World: make sure that chunks locked by PopulationTask always get unlocked, no matter what fixes #4527 --- src/world/World.php | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 43768cfc3c..3725da08ec 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2908,21 +2908,17 @@ class World implements ChunkManager{ public function generateChunkCallback(ChunkLockId $chunkLockId, int $x, int $z, Chunk $chunk, array $adjacentChunks, ChunkLoader $temporaryChunkLoader) : void{ Timings::$generationCallback->startTiming(); + $dirtyChunks = 0; for($xx = -1; $xx <= 1; ++$xx){ for($zz = -1; $zz <= 1; ++$zz){ $this->unregisterChunkLoader($temporaryChunkLoader, $x + $xx, $z + $zz); + if(!$this->unlockChunk($x + $xx, $z + $zz, $chunkLockId)){ + $dirtyChunks++; + } } } if(isset($this->chunkPopulationRequestMap[$index = World::chunkHash($x, $z)]) && isset($this->activeChunkPopulationTasks[$index])){ - $dirtyChunks = 0; - for($xx = -1; $xx <= 1; ++$xx){ - for($zz = -1; $zz <= 1; ++$zz){ - if(!$this->unlockChunk($x + $xx, $z + $zz, $chunkLockId)){ - $dirtyChunks++; - } - } - } if($dirtyChunks === 0){ $oldChunk = $this->loadChunk($x, $z); $this->setChunk($x, $z, $chunk); From 34ea199fb0da75890930f019d28dc78dc2b0e26a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 14:30:23 +0000 Subject: [PATCH 3097/3224] World: fixed additional edge case - population promise rejected before task completion if this happened, the index would stay set in activeChunkPopulationTasks, eventually causing the generation queue to jam up completely and non-forced generation to come to a standstill. --- src/world/World.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/world/World.php b/src/world/World.php index 3725da08ec..cb4039b898 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2918,7 +2918,11 @@ class World implements ChunkManager{ } } - if(isset($this->chunkPopulationRequestMap[$index = World::chunkHash($x, $z)]) && isset($this->activeChunkPopulationTasks[$index])){ + $index = World::chunkHash($x, $z); + if(!isset($this->chunkPopulationRequestMap[$index])){ + $this->logger->debug("Discarding population result for chunk x=$x,z=$z - promise was already broken"); + unset($this->activeChunkPopulationTasks[$index]); + }elseif(isset($this->activeChunkPopulationTasks[$index])){ if($dirtyChunks === 0){ $oldChunk = $this->loadChunk($x, $z); $this->setChunk($x, $z, $chunk); From ede4157814829e1afa1f97ca187baaa0e326fab8 Mon Sep 17 00:00:00 2001 From: Rush2929 <76860328+Rush2929@users.noreply.github.com> Date: Tue, 2 Nov 2021 23:36:16 +0900 Subject: [PATCH 3098/3224] Check to see if the player can start using the Releasable item. (#4532) --- src/item/Bow.php | 4 ++++ src/item/Food.php | 5 +++++ src/item/MilkBucket.php | 5 +++++ src/item/Potion.php | 5 +++++ src/item/Releasable.php | 4 ++++ src/player/Player.php | 2 +- 6 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/item/Bow.php b/src/item/Bow.php index fd6364e846..41777e0a6c 100644 --- a/src/item/Bow.php +++ b/src/item/Bow.php @@ -123,4 +123,8 @@ class Bow extends Tool implements Releasable{ return ItemUseResult::SUCCESS(); } + + public function canStartUsingItem(Player $player) : bool{ + return !$player->hasFiniteResources() || $player->getOffHandInventory()->contains($arrow = VanillaItems::ARROW()) || $player->getInventory()->contains($arrow); + } } diff --git a/src/item/Food.php b/src/item/Food.php index ff737e3299..ddaa77da6e 100644 --- a/src/item/Food.php +++ b/src/item/Food.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\entity\Living; +use pocketmine\player\Player; abstract class Food extends Item implements FoodSourceItem{ public function requiresHunger() : bool{ @@ -41,4 +42,8 @@ abstract class Food extends Item implements FoodSourceItem{ public function onConsume(Living $consumer) : void{ } + + public function canStartUsingItem(Player $player) : bool{ + return !$this->requiresHunger() || $player->getHungerManager()->isHungry(); + } } diff --git a/src/item/MilkBucket.php b/src/item/MilkBucket.php index 4419a510ff..f8c8b3ddf1 100644 --- a/src/item/MilkBucket.php +++ b/src/item/MilkBucket.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\entity\Living; +use pocketmine\player\Player; class MilkBucket extends Item implements ConsumableItem{ @@ -42,4 +43,8 @@ class MilkBucket extends Item implements ConsumableItem{ public function onConsume(Living $consumer) : void{ $consumer->getEffects()->clear(); } + + public function canStartUsingItem(Player $player) : bool{ + return true; + } } diff --git a/src/item/Potion.php b/src/item/Potion.php index 5b2bbc17ef..5be216e96d 100644 --- a/src/item/Potion.php +++ b/src/item/Potion.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\entity\Living; +use pocketmine\player\Player; class Potion extends Item implements ConsumableItem{ @@ -52,4 +53,8 @@ class Potion extends Item implements ConsumableItem{ public function getResidue() : Item{ return VanillaItems::GLASS_BOTTLE(); } + + public function canStartUsingItem(Player $player) : bool{ + return true; + } } diff --git a/src/item/Releasable.php b/src/item/Releasable.php index 07e77cf28c..acb9d65c8a 100644 --- a/src/item/Releasable.php +++ b/src/item/Releasable.php @@ -23,9 +23,13 @@ declare(strict_types=1); namespace pocketmine\item; +use pocketmine\player\Player; + /** * Interface implemented by objects that can be used. */ interface Releasable{ + public function canStartUsingItem(Player $player) : bool; + } diff --git a/src/player/Player.php b/src/player/Player.php index 3b74b27c77..a568ba644e 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1374,7 +1374,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->inventory->setItemInHand($item); } - $this->setUsingItem($item instanceof Releasable); + $this->setUsingItem($item instanceof Releasable && $item->canStartUsingItem($this)); return true; } From 4dc13ab3dafd1e008325e6232085dfe0efc2f59f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 15:11:10 +0000 Subject: [PATCH 3099/3224] ConsoleReaderThread: strip control characters this fixes a bug I encountered when accidentally pressing ctrl+a+d (which inserts a chr(1) character), because it made the server unable to find the command - but still reported an error containing what looked like a valid command (character isn't printable). --- src/console/ConsoleReaderThread.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/console/ConsoleReaderThread.php b/src/console/ConsoleReaderThread.php index fde505f3c2..dbf3770d3e 100644 --- a/src/console/ConsoleReaderThread.php +++ b/src/console/ConsoleReaderThread.php @@ -114,7 +114,9 @@ final class ConsoleReaderThread extends Thread{ break; } - $buffer[] = preg_replace("#\\x1b\\x5b([^\\x1b]*\\x7e|[\\x40-\\x50])#", "", trim($command)); + $command = preg_replace("#\\x1b\\x5b([^\\x1b]*\\x7e|[\\x40-\\x50])#", "", trim($command)) ?? throw new AssumptionFailedError("This regex is assumed to be valid"); + $command = preg_replace('/[[:cntrl:]]/', '', $command) ?? throw new AssumptionFailedError("This regex is assumed to be valid"); + $buffer[] = $command; if($notifier !== null){ $notifier->wakeupSleeper(); } From 65ef9f786adfbcbcd14bd103b491b6458e9249a2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 15:25:03 +0000 Subject: [PATCH 3100/3224] Use standard chunkHash() to index population chunks --- src/world/World.php | 15 +++++++-------- src/world/generator/PopulationTask.php | 19 +++++++------------ 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index cb4039b898..27444ad6ab 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2082,13 +2082,12 @@ class World implements ChunkManager{ */ public function getAdjacentChunks(int $x, int $z) : array{ $result = []; - for($xx = 0; $xx <= 2; ++$xx){ - for($zz = 0; $zz <= 2; ++$zz){ - $i = $zz * 3 + $xx; - if($i === 4){ + for($xx = -1; $xx <= 1; ++$xx){ + for($zz = -1; $zz <= 1; ++$zz){ + if($xx === 0 && $zz === 0){ continue; //center chunk } - $result[$i] = $this->loadChunk($x + $xx - 1, $z + $zz - 1); + $result[World::chunkHash($xx, $zz)] = $this->loadChunk($x + $xx, $z + $zz); } } @@ -2927,9 +2926,9 @@ class World implements ChunkManager{ $oldChunk = $this->loadChunk($x, $z); $this->setChunk($x, $z, $chunk); - foreach($adjacentChunks as $adjacentChunkHash => $adjacentChunk){ - World::getXZ($adjacentChunkHash, $xAdjacentChunk, $zAdjacentChunk); - $this->setChunk($xAdjacentChunk, $zAdjacentChunk, $adjacentChunk); + foreach($adjacentChunks as $relativeChunkHash => $adjacentChunk){ + World::getXZ($relativeChunkHash, $relativeX, $relativeZ); + $this->setChunk($x + $relativeX, $z + $relativeZ, $adjacentChunk); } if(($oldChunk === null or !$oldChunk->isPopulated()) and $chunk->isPopulated()){ diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 5a628248d9..55b612a8a1 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -36,7 +36,6 @@ use pocketmine\world\World; use function array_map; use function igbinary_serialize; use function igbinary_unserialize; -use function intdiv; class PopulationTask extends AsyncTask{ private const TLS_KEY_WORLD = "world"; @@ -92,10 +91,9 @@ class PopulationTask extends AsyncTask{ /** @var Chunk[] $resultChunks */ $resultChunks = []; //this is just to keep phpstan's type inference happy - foreach($chunks as $i => $c){ - $cX = (-1 + $i % 3) + $this->chunkX; - $cZ = (-1 + intdiv($i, 3)) + $this->chunkZ; - $resultChunks[$i] = self::setOrGenerateChunk($manager, $generator, $cX, $cZ, $c); + foreach($chunks as $relativeChunkHash => $c){ + World::getXZ($relativeChunkHash, $relativeX, $relativeZ); + $resultChunks[$relativeChunkHash] = self::setOrGenerateChunk($manager, $generator, $this->chunkX + $relativeX, $this->chunkZ + $relativeZ, $c); } $chunks = $resultChunks; @@ -109,8 +107,8 @@ class PopulationTask extends AsyncTask{ $this->chunk = FastChunkSerializer::serializeTerrain($chunk); $serialChunks = []; - foreach($chunks as $i => $c){ - $serialChunks[$i] = $c->isTerrainDirty() ? FastChunkSerializer::serializeTerrain($c) : null; + foreach($chunks as $relativeChunkHash => $c){ + $serialChunks[$relativeChunkHash] = $c->isTerrainDirty() ? FastChunkSerializer::serializeTerrain($c) : null; } $this->adjacentChunks = igbinary_serialize($serialChunks) ?? throw new AssumptionFailedError("igbinary_serialize() returned null"); } @@ -147,12 +145,9 @@ class PopulationTask extends AsyncTask{ */ $serialAdjacentChunks = igbinary_unserialize($this->adjacentChunks); $adjacentChunks = []; - foreach($serialAdjacentChunks as $i => $c){ + foreach($serialAdjacentChunks as $relativeChunkHash => $c){ if($c !== null){ - $xx = -1 + $i % 3; - $zz = -1 + intdiv($i, 3); - - $adjacentChunks[World::chunkHash($this->chunkX + $xx, $this->chunkZ + $zz)] = FastChunkSerializer::deserializeTerrain($c); + $adjacentChunks[$relativeChunkHash] = FastChunkSerializer::deserializeTerrain($c); } } From facfd7c04a25ef8c79bad8547e493b97cae2e7ad Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 15:26:54 +0000 Subject: [PATCH 3101/3224] sanity check --- src/world/World.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index 27444ad6ab..a540650356 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2928,6 +2928,9 @@ class World implements ChunkManager{ foreach($adjacentChunks as $relativeChunkHash => $adjacentChunk){ World::getXZ($relativeChunkHash, $relativeX, $relativeZ); + if($relativeX < -1 || $relativeX > 1 || $relativeZ < -1 || $relativeZ > 1){ + throw new AssumptionFailedError("Adjacent chunks should be in range -1 ... +1 coordinates"); + } $this->setChunk($x + $relativeX, $z + $relativeZ, $adjacentChunk); } From 8b3565b75db9877dfbf0dcd789e39fa5b57905e5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 15:40:51 +0000 Subject: [PATCH 3102/3224] PopulationTask no longer depends on a World object this means it's now possible to test generation offline without too much hassle. World::generateChunkCallback() has been removed from public API. --- src/world/World.php | 19 +++++++- src/world/generator/PopulationTask.php | 66 +++++++++++++------------- 2 files changed, 50 insertions(+), 35 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index a540650356..246799a856 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2889,7 +2889,22 @@ class World implements ChunkManager{ } } - $task = new PopulationTask($this, $chunkX, $chunkZ, $this->loadChunk($chunkX, $chunkZ), $temporaryChunkLoader, $chunkPopulationLockId); + $centerChunk = $this->loadChunk($chunkX, $chunkZ); + $adjacentChunks = $this->getAdjacentChunks($chunkX, $chunkZ); + $task = new PopulationTask( + $this->worldId, + $chunkX, + $chunkZ, + $centerChunk, + $adjacentChunks, + function(Chunk $centerChunk, array $adjacentChunks) use ($chunkPopulationLockId, $chunkX, $chunkZ, $temporaryChunkLoader) : void{ + if(!$this->isLoaded()){ + return; + } + + $this->generateChunkCallback($chunkPopulationLockId, $chunkX, $chunkZ, $centerChunk, $adjacentChunks, $temporaryChunkLoader); + } + ); $workerId = $this->workerPool->selectWorker(); if(!isset($this->generatorRegisteredWorkers[$workerId])){ $this->registerGeneratorToWorker($workerId); @@ -2904,7 +2919,7 @@ class World implements ChunkManager{ * @param Chunk[] $adjacentChunks chunkHash => chunk * @phpstan-param array $adjacentChunks */ - public function generateChunkCallback(ChunkLockId $chunkLockId, int $x, int $z, Chunk $chunk, array $adjacentChunks, ChunkLoader $temporaryChunkLoader) : void{ + private function generateChunkCallback(ChunkLockId $chunkLockId, int $x, int $z, Chunk $chunk, array $adjacentChunks, ChunkLoader $temporaryChunkLoader) : void{ Timings::$generationCallback->startTiming(); $dirtyChunks = 0; diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 55b612a8a1..f1f2d38580 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -26,8 +26,6 @@ namespace pocketmine\world\generator; use pocketmine\data\bedrock\BiomeIds; use pocketmine\scheduler\AsyncTask; use pocketmine\utils\AssumptionFailedError; -use pocketmine\world\ChunkLoader; -use pocketmine\world\ChunkLockId; use pocketmine\world\format\BiomeArray; use pocketmine\world\format\Chunk; use pocketmine\world\format\io\FastChunkSerializer; @@ -37,10 +35,11 @@ use function array_map; use function igbinary_serialize; use function igbinary_unserialize; +/** + * @phpstan-type OnCompletion \Closure(Chunk $centerChunk, array $adjacentChunks) : void + */ class PopulationTask extends AsyncTask{ - private const TLS_KEY_WORLD = "world"; - private const TLS_KEY_CHUNK_LOADER = "chunkLoader"; - private const TLS_KEY_LOCK_ID = "chunkLockId"; + private const TLS_KEY_ON_COMPLETION = "onCompletion"; /** @var int */ public $worldId; @@ -54,20 +53,23 @@ class PopulationTask extends AsyncTask{ private string $adjacentChunks; - public function __construct(World $world, int $chunkX, int $chunkZ, ?Chunk $chunk, ChunkLoader $temporaryChunkLoader, ChunkLockId $chunkLockId){ - $this->worldId = $world->getId(); + /** + * @param Chunk[]|null[] $adjacentChunks + * @phpstan-param array $adjacentChunks + * @phpstan-param OnCompletion $onCompletion + */ + public function __construct(int $worldId, int $chunkX, int $chunkZ, ?Chunk $chunk, array $adjacentChunks, \Closure $onCompletion){ + $this->worldId = $worldId; $this->chunkX = $chunkX; $this->chunkZ = $chunkZ; $this->chunk = $chunk !== null ? FastChunkSerializer::serializeTerrain($chunk) : null; $this->adjacentChunks = igbinary_serialize(array_map( fn(?Chunk $c) => $c !== null ? FastChunkSerializer::serializeTerrain($c) : null, - $world->getAdjacentChunks($chunkX, $chunkZ) + $adjacentChunks )) ?? throw new AssumptionFailedError("igbinary_serialize() returned null"); - $this->storeLocal(self::TLS_KEY_WORLD, $world); - $this->storeLocal(self::TLS_KEY_CHUNK_LOADER, $temporaryChunkLoader); - $this->storeLocal(self::TLS_KEY_LOCK_ID, $chunkLockId); + $this->storeLocal(self::TLS_KEY_ON_COMPLETION, $onCompletion); } public function onRun() : void{ @@ -128,30 +130,28 @@ class PopulationTask extends AsyncTask{ } public function onCompletion() : void{ - /** @var World $world */ - $world = $this->fetchLocal(self::TLS_KEY_WORLD); - /** @var ChunkLoader $temporaryChunkLoader */ - $temporaryChunkLoader = $this->fetchLocal(self::TLS_KEY_CHUNK_LOADER); - /** @var ChunkLockId $lockId */ - $lockId = $this->fetchLocal(self::TLS_KEY_LOCK_ID); - if($world->isLoaded()){ - $chunk = $this->chunk !== null ? - FastChunkSerializer::deserializeTerrain($this->chunk) : - throw new AssumptionFailedError("Center chunk should never be null"); + /** + * @var \Closure $onCompletion + * @phpstan-var OnCompletion $onCompletion + */ + $onCompletion = $this->fetchLocal(self::TLS_KEY_ON_COMPLETION); - /** - * @var string[]|null[] $serialAdjacentChunks - * @phpstan-var array $serialAdjacentChunks - */ - $serialAdjacentChunks = igbinary_unserialize($this->adjacentChunks); - $adjacentChunks = []; - foreach($serialAdjacentChunks as $relativeChunkHash => $c){ - if($c !== null){ - $adjacentChunks[$relativeChunkHash] = FastChunkSerializer::deserializeTerrain($c); - } + $chunk = $this->chunk !== null ? + FastChunkSerializer::deserializeTerrain($this->chunk) : + throw new AssumptionFailedError("Center chunk should never be null"); + + /** + * @var string[]|null[] $serialAdjacentChunks + * @phpstan-var array $serialAdjacentChunks + */ + $serialAdjacentChunks = igbinary_unserialize($this->adjacentChunks); + $adjacentChunks = []; + foreach($serialAdjacentChunks as $relativeChunkHash => $c){ + if($c !== null){ + $adjacentChunks[$relativeChunkHash] = FastChunkSerializer::deserializeTerrain($c); } - - $world->generateChunkCallback($lockId, $this->chunkX, $this->chunkZ, $chunk, $adjacentChunks, $temporaryChunkLoader); } + + $onCompletion($chunk, $adjacentChunks); } } From 4eef458d29feceea0a6814f7ad641939b022171b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 16:03:43 +0000 Subject: [PATCH 3103/3224] Config: throw AssumptionFailedError if config type is invalid or DETECT during save() this should never happen ... it was already checked in load() --- src/utils/Config.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/utils/Config.php b/src/utils/Config.php index 696269a1ba..f65f77190c 100644 --- a/src/utils/Config.php +++ b/src/utils/Config.php @@ -205,8 +205,6 @@ class Config{ /** * Flushes the config to disk in the appropriate format. - * - * @throws \InvalidStateException if config type is not valid */ public function save() : void{ $content = null; @@ -227,7 +225,7 @@ class Config{ $content = self::writeList(array_keys($this->config)); break; default: - throw new \InvalidStateException("Config type is unknown, has not been set or not detected"); + throw new AssumptionFailedError("Config type is unknown, has not been set or not detected"); } file_put_contents($this->file, $content); From e34364412b783710720738a9b53eac4034cc7126 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 16:05:54 +0000 Subject: [PATCH 3104/3224] Replace InvalidStateException usages with InvalidArgument or LogicException --- src/Server.php | 2 +- src/block/Block.php | 2 +- src/crafting/CraftingGrid.php | 2 +- src/entity/Entity.php | 2 +- src/event/HandlerList.php | 2 +- src/event/entity/EntityEffectRemoveEvent.php | 2 +- src/network/mcpe/compression/CompressBatchPromise.php | 6 +++--- src/permission/PermissibleInternal.php | 2 +- src/player/Player.php | 4 ++-- src/scheduler/AsyncWorker.php | 6 +++--- src/scheduler/TaskScheduler.php | 5 +---- src/utils/Config.php | 5 ++--- src/utils/PromiseResolver.php | 4 ++-- src/utils/Terminal.php | 2 +- src/world/World.php | 8 +++----- 15 files changed, 24 insertions(+), 30 deletions(-) diff --git a/src/Server.php b/src/Server.php index 277a56ad6e..afe2404466 100644 --- a/src/Server.php +++ b/src/Server.php @@ -739,7 +739,7 @@ class Server{ public function __construct(\DynamicClassLoader $autoloader, \AttachableThreadedLogger $logger, string $dataPath, string $pluginPath){ if(self::$instance !== null){ - throw new \InvalidStateException("Only one server instance can exist at once"); + throw new \LogicException("Only one server instance can exist at once"); } self::$instance = $this; $this->startTime = microtime(true); diff --git a/src/block/Block.php b/src/block/Block.php index 2de12ce585..414d9b6494 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -493,7 +493,7 @@ class Block{ return $this->position->getWorld()->getBlock($this->position->getSide($side, $step)); } - throw new \InvalidStateException("Block does not have a valid world"); + throw new \LogicException("Block does not have a valid world"); } /** diff --git a/src/crafting/CraftingGrid.php b/src/crafting/CraftingGrid.php index 5c84c9b474..a8d4f6ebe8 100644 --- a/src/crafting/CraftingGrid.php +++ b/src/crafting/CraftingGrid.php @@ -111,7 +111,7 @@ class CraftingGrid extends SimpleInventory{ return $this->getItem(($y + $this->startY) * $this->gridWidth + ($x + $this->startX)); } - throw new \InvalidStateException("No ingredients found in grid"); + throw new \LogicException("No ingredients found in grid"); } /** diff --git a/src/entity/Entity.php b/src/entity/Entity.php index b4cc59c17f..e483b43489 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -980,7 +980,7 @@ abstract class Entity{ final public function scheduleUpdate() : void{ if($this->closed){ - throw new \InvalidStateException("Cannot schedule update on garbage entity " . get_class($this)); + throw new \LogicException("Cannot schedule update on garbage entity " . get_class($this)); } $this->getWorld()->updateEntities[$this->id] = $this; } diff --git a/src/event/HandlerList.php b/src/event/HandlerList.php index b452a382c8..b135a53cdb 100644 --- a/src/event/HandlerList.php +++ b/src/event/HandlerList.php @@ -47,7 +47,7 @@ class HandlerList{ */ public function register(RegisteredListener $listener) : void{ if(isset($this->handlerSlots[$listener->getPriority()][spl_object_id($listener)])){ - throw new \InvalidStateException("This listener is already registered to priority {$listener->getPriority()} of event {$this->class}"); + throw new \InvalidArgumentException("This listener is already registered to priority {$listener->getPriority()} of event {$this->class}"); } $this->handlerSlots[$listener->getPriority()][spl_object_id($listener)] = $listener; } diff --git a/src/event/entity/EntityEffectRemoveEvent.php b/src/event/entity/EntityEffectRemoveEvent.php index afd2ef631b..35e59023c4 100644 --- a/src/event/entity/EntityEffectRemoveEvent.php +++ b/src/event/entity/EntityEffectRemoveEvent.php @@ -29,7 +29,7 @@ namespace pocketmine\event\entity; class EntityEffectRemoveEvent extends EntityEffectEvent{ public function cancel() : void{ if($this->getEffect()->getDuration() <= 0){ - throw new \InvalidStateException("Removal of expired effects cannot be cancelled"); + throw new \LogicException("Removal of expired effects cannot be cancelled"); } parent::cancel(); } diff --git a/src/network/mcpe/compression/CompressBatchPromise.php b/src/network/mcpe/compression/CompressBatchPromise.php index 8fa8b12ae7..c62388f6aa 100644 --- a/src/network/mcpe/compression/CompressBatchPromise.php +++ b/src/network/mcpe/compression/CompressBatchPromise.php @@ -59,7 +59,7 @@ class CompressBatchPromise{ public function resolve(string $result) : void{ if(!$this->cancelled){ if($this->result !== null){ - throw new \InvalidStateException("Cannot resolve promise more than once"); + throw new \LogicException("Cannot resolve promise more than once"); } $this->result = $result; foreach($this->callbacks as $callback){ @@ -80,7 +80,7 @@ class CompressBatchPromise{ public function getResult() : string{ $this->checkCancelled(); if($this->result === null){ - throw new \InvalidStateException("Promise has not yet been resolved"); + throw new \LogicException("Promise has not yet been resolved"); } return $this->result; } @@ -95,7 +95,7 @@ class CompressBatchPromise{ public function cancel() : void{ if($this->hasResult()){ - throw new \InvalidStateException("Cannot cancel a resolved promise"); + throw new \LogicException("Cannot cancel a resolved promise"); } $this->cancelled = true; } diff --git a/src/permission/PermissibleInternal.php b/src/permission/PermissibleInternal.php index c9484085ee..0d14d79436 100644 --- a/src/permission/PermissibleInternal.php +++ b/src/permission/PermissibleInternal.php @@ -146,7 +146,7 @@ class PermissibleInternal implements Permissible{ foreach($this->rootPermissions as $name => $isGranted){ $perm = $permManager->getPermission($name); if($perm === null){ - throw new \InvalidStateException("Unregistered root permission $name"); + throw new \LogicException("Unregistered root permission $name"); } $this->permissions[$name] = new PermissionAttachmentInfo($name, null, $isGranted, null); $permManager->subscribeToPermission($name, $this); diff --git a/src/player/Player.php b/src/player/Player.php index a568ba644e..1ca3faee84 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -475,7 +475,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ public function getNetworkSession() : NetworkSession{ if($this->networkSession === null){ - throw new \InvalidStateException("Player is not connected"); + throw new \LogicException("Player is not connected"); } return $this->networkSession; } @@ -1941,7 +1941,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ */ public function onPostDisconnect(string $reason, Translatable|string|null $quitMessage) : void{ if($this->isConnected()){ - throw new \InvalidStateException("Player is still connected"); + throw new \LogicException("Player is still connected"); } //prevent the player receiving their own disconnect message diff --git a/src/scheduler/AsyncWorker.php b/src/scheduler/AsyncWorker.php index eedb7ea5c3..3dc8c2e688 100644 --- a/src/scheduler/AsyncWorker.php +++ b/src/scheduler/AsyncWorker.php @@ -92,7 +92,7 @@ class AsyncWorker extends Worker{ */ public function saveToThreadStore(string $identifier, $value) : void{ if(\Thread::getCurrentThread() !== $this){ - throw new \InvalidStateException("Thread-local data can only be stored in the thread context"); + throw new \LogicException("Thread-local data can only be stored in the thread context"); } self::$store[$identifier] = $value; } @@ -109,7 +109,7 @@ class AsyncWorker extends Worker{ */ public function getFromThreadStore(string $identifier){ if(\Thread::getCurrentThread() !== $this){ - throw new \InvalidStateException("Thread-local data can only be fetched in the thread context"); + throw new \LogicException("Thread-local data can only be fetched in the thread context"); } return self::$store[$identifier] ?? null; } @@ -119,7 +119,7 @@ class AsyncWorker extends Worker{ */ public function removeFromThreadStore(string $identifier) : void{ if(\Thread::getCurrentThread() !== $this){ - throw new \InvalidStateException("Thread-local data can only be removed in the thread context"); + throw new \LogicException("Thread-local data can only be removed in the thread context"); } unset(self::$store[$identifier]); } diff --git a/src/scheduler/TaskScheduler.php b/src/scheduler/TaskScheduler.php index 22317573d4..a1ed6a261b 100644 --- a/src/scheduler/TaskScheduler.php +++ b/src/scheduler/TaskScheduler.php @@ -88,12 +88,9 @@ class TaskScheduler{ return $this->tasks->contains($task); } - /** - * @throws \InvalidStateException - */ private function addTask(Task $task, int $delay, int $period) : TaskHandler{ if(!$this->enabled){ - throw new \InvalidStateException("Tried to schedule task to disabled scheduler"); + throw new \LogicException("Tried to schedule task to disabled scheduler"); } if($delay <= 0){ diff --git a/src/utils/Config.php b/src/utils/Config.php index f65f77190c..562d614f86 100644 --- a/src/utils/Config.php +++ b/src/utils/Config.php @@ -144,8 +144,7 @@ class Config{ * @param mixed[] $default * @phpstan-param array $default * - * @throws \InvalidArgumentException if config type could not be auto-detected - * @throws \InvalidStateException if config type is invalid + * @throws \InvalidArgumentException if config type is invalid or could not be auto-detected */ private function load(string $file, int $type = Config::DETECT, array $default = []) : void{ $this->file = $file; @@ -187,7 +186,7 @@ class Config{ $config = array_fill_keys(self::parseList($content), true); break; default: - throw new \InvalidStateException("Config type is unknown"); + throw new \InvalidArgumentException("Invalid config type specified"); } $this->config = is_array($config) ? $config : $default; if($this->fillDefaults($default, $this->config) > 0){ diff --git a/src/utils/PromiseResolver.php b/src/utils/PromiseResolver.php index 860d683b0e..81ed05201d 100644 --- a/src/utils/PromiseResolver.php +++ b/src/utils/PromiseResolver.php @@ -43,7 +43,7 @@ final class PromiseResolver{ */ public function resolve($value) : void{ if($this->shared->resolved){ - throw new \InvalidStateException("Promise has already been resolved/rejected"); + throw new \LogicException("Promise has already been resolved/rejected"); } $this->shared->resolved = true; $this->shared->result = $value; @@ -56,7 +56,7 @@ final class PromiseResolver{ public function reject() : void{ if($this->shared->resolved){ - throw new \InvalidStateException("Promise has already been resolved/rejected"); + throw new \LogicException("Promise has already been resolved/rejected"); } $this->shared->resolved = true; foreach($this->shared->onFailure as $c){ diff --git a/src/utils/Terminal.php b/src/utils/Terminal.php index 4280f94d88..73e350a2c2 100644 --- a/src/utils/Terminal.php +++ b/src/utils/Terminal.php @@ -64,7 +64,7 @@ abstract class Terminal{ public static function hasFormattingCodes() : bool{ if(self::$formattingCodes === null){ - throw new \InvalidStateException("Formatting codes have not been initialized"); + throw new \LogicException("Formatting codes have not been initialized"); } return self::$formattingCodes; } diff --git a/src/world/World.php b/src/world/World.php index 246799a856..bdb8d9fbbf 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -516,7 +516,7 @@ class World implements ChunkManager{ */ public function onUnload() : void{ if($this->unloaded){ - throw new \InvalidStateException("Tried to close a world which is already closed"); + throw new \LogicException("Tried to close a world which is already closed"); } foreach($this->unloadCallbacks as $callback){ @@ -770,7 +770,7 @@ class World implements ChunkManager{ */ public function doTick(int $currentTick) : void{ if($this->unloaded){ - throw new \InvalidStateException("Attempted to tick a world which has been closed"); + throw new \LogicException("Attempted to tick a world which has been closed"); } $this->timings->doTick->startTiming(); @@ -2374,7 +2374,7 @@ class World implements ChunkManager{ if(isset($this->chunks[$hash = World::chunkHash($chunkX, $chunkZ)])){ $this->chunks[$hash]->addTile($tile); }else{ - throw new \InvalidStateException("Attempted to create tile " . get_class($tile) . " in unloaded chunk $chunkX $chunkZ"); + throw new \InvalidArgumentException("Attempted to create tile " . get_class($tile) . " in unloaded chunk $chunkX $chunkZ"); } //delegate tile ticking to the corresponding block @@ -2411,8 +2411,6 @@ class World implements ChunkManager{ * returned directly. * * @return Chunk|null the requested chunk, or null on failure. - * - * @throws \InvalidStateException */ public function loadChunk(int $x, int $z) : ?Chunk{ if(isset($this->chunks[$chunkHash = World::chunkHash($x, $z)])){ From e131c2cefa39af4c68c681c564923ff72fcd2373 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 16:08:29 +0000 Subject: [PATCH 3105/3224] Drop pocketmine/spl --- composer.json | 1 - composer.lock | 42 ++------------------------- src/network/mcpe/InventoryManager.php | 2 +- src/network/mcpe/NetworkSession.php | 2 -- 4 files changed, 3 insertions(+), 44 deletions(-) diff --git a/composer.json b/composer.json index 35adb7adcc..8669357229 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,6 @@ "pocketmine/raklib": "^0.14.2", "pocketmine/raklib-ipc": "^0.1.0", "pocketmine/snooze": "^0.3.0", - "pocketmine/spl": "dev-master", "ramsey/uuid": "^4.1", "webmozart/path-util": "^2.3" }, diff --git a/composer.lock b/composer.lock index b2878d494a..ffed79405d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9b3c01e7b850d45218b81a436f463011", + "content-hash": "94aedb2c8c81dd851b775b7b4e1467cb", "packages": [ { "name": "adhocore/json-comment", @@ -798,43 +798,6 @@ }, "time": "2021-11-01T20:50:08+00:00" }, - { - "name": "pocketmine/spl", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/pmmp/SPL.git", - "reference": "b7a8904f912c1f6d38ad867ff1120614ccb80171" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pmmp/SPL/zipball/b7a8904f912c1f6d38ad867ff1120614ccb80171", - "reference": "b7a8904f912c1f6d38ad867ff1120614ccb80171", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^0.12.8" - }, - "type": "library", - "autoload": { - "classmap": [ - "./src" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0" - ], - "description": "Standard library files required by PocketMine-MP and related projects", - "support": { - "issues": "https://github.com/pmmp/SPL/issues", - "source": "https://github.com/pmmp/SPL/tree/master" - }, - "time": "2021-01-15T15:19:34+00:00" - }, { "name": "ramsey/collection", "version": "1.2.2", @@ -3493,8 +3456,7 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "pocketmine/bedrock-protocol": 20, - "pocketmine/spl": 20 + "pocketmine/bedrock-protocol": 20 }, "prefer-stable": false, "prefer-lowest": false, diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index b5271f5f9e..07092d2ede 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -151,7 +151,7 @@ class InventoryManager{ return; } } - throw new \UnsupportedOperationException("Unsupported inventory type"); + throw new \LogicException("Unsupported inventory type"); } /** @phpstan-return ObjectSet */ diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index ed910c45ec..cf189d8755 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -536,8 +536,6 @@ class NetworkSession{ /** * Instructs the remote client to connect to a different server. - * - * @throws \UnsupportedOperationException */ public function transfer(string $ip, int $port, string $reason = "transfer") : void{ $this->tryDisconnect(function() use ($ip, $port, $reason) : void{ From 6b07f7a5ecb2ac089719abd686beead98a8018d2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 16:22:56 +0000 Subject: [PATCH 3106/3224] pmmp/BedrockProtocol@5.0.0+bedrock-1.17.40 --- composer.json | 2 +- composer.lock | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index 8669357229..a1158e02a6 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "adhocore/json-comment": "^1.1", "fgrosse/phpasn1": "^2.3", "netresearch/jsonmapper": "^4.0", - "pocketmine/bedrock-protocol": "dev-master", + "pocketmine/bedrock-protocol": "^5.0.0+bedrock-1.17.40", "pocketmine/binaryutils": "^0.2.1", "pocketmine/callback-validator": "^1.0.2", "pocketmine/classloader": "^0.2.0", diff --git a/composer.lock b/composer.lock index ffed79405d..8aa4a764a5 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "94aedb2c8c81dd851b775b7b4e1467cb", + "content-hash": "ea2d9321ba41afb67761c8f0cf3afe22", "packages": [ { "name": "adhocore/json-comment", @@ -249,7 +249,7 @@ }, { "name": "pocketmine/bedrock-protocol", - "version": "dev-master", + "version": "5.0.0+bedrock-1.17.40", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", @@ -277,7 +277,6 @@ "phpstan/phpstan-strict-rules": "^1.0.0", "phpunit/phpunit": "^9.5" }, - "default-branch": true, "type": "library", "autoload": { "psr-4": { @@ -291,7 +290,7 @@ "description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP", "support": { "issues": "https://github.com/pmmp/BedrockProtocol/issues", - "source": "https://github.com/pmmp/BedrockProtocol/tree/master" + "source": "https://github.com/pmmp/BedrockProtocol/tree/5.0.0+bedrock-1.17.40" }, "time": "2021-11-02T01:27:05+00:00" }, @@ -3455,9 +3454,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "pocketmine/bedrock-protocol": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { From 275f145418afa22b762efcfd77dfa82ffac3c449 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 16:45:45 +0000 Subject: [PATCH 3107/3224] BedrockData is now a Composer dependency this should put a stop to people nagging me about incorrect blocks (we have a check to make sure composer dependencies are up to date). --- .gitmodules | 3 -- composer.json | 1 + composer.lock | 28 ++++++++++++++++++- resources/vanilla | 1 - src/CoreConstants.php | 1 + src/Server.php | 2 +- .../bedrock/LegacyBlockIdToStringIdMap.php | 2 +- .../bedrock/LegacyEntityIdToStringIdMap.php | 2 +- .../bedrock/LegacyItemIdToStringIdMap.php | 2 +- src/inventory/CreativeInventory.php | 2 +- src/network/mcpe/cache/StaticPacketCache.php | 4 +-- .../mcpe/convert/GlobalItemTypeDictionary.php | 2 +- src/network/mcpe/convert/ItemTranslator.php | 4 +-- .../mcpe/convert/RuntimeBlockMapping.php | 4 +-- 14 files changed, 41 insertions(+), 17 deletions(-) delete mode 160000 resources/vanilla diff --git a/.gitmodules b/.gitmodules index ec6560fd14..71a80c00a4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,6 +7,3 @@ [submodule "build/php"] path = build/php url = https://github.com/pmmp/php-build-scripts.git -[submodule "resources/vanilla"] - path = resources/vanilla - url = https://github.com/pmmp/BedrockData.git diff --git a/composer.json b/composer.json index a1158e02a6..c31ed61446 100644 --- a/composer.json +++ b/composer.json @@ -34,6 +34,7 @@ "adhocore/json-comment": "^1.1", "fgrosse/phpasn1": "^2.3", "netresearch/jsonmapper": "^4.0", + "pocketmine/bedrock-data": "^1.4.0+bedrock-1.17.40", "pocketmine/bedrock-protocol": "^5.0.0+bedrock-1.17.40", "pocketmine/binaryutils": "^0.2.1", "pocketmine/callback-validator": "^1.0.2", diff --git a/composer.lock b/composer.lock index 8aa4a764a5..b5214753a6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ea2d9321ba41afb67761c8f0cf3afe22", + "content-hash": "3fa50836a0e8560fe59ba9e73cc50c44", "packages": [ { "name": "adhocore/json-comment", @@ -247,6 +247,32 @@ }, "time": "2020-12-01T19:48:11+00:00" }, + { + "name": "pocketmine/bedrock-data", + "version": "1.4.0+bedrock-1.17.40", + "source": { + "type": "git", + "url": "https://github.com/pmmp/BedrockData.git", + "reference": "f29b7be8fa3046d2ee4c6421485b97b3f5b07774" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pmmp/BedrockData/zipball/f29b7be8fa3046d2ee4c6421485b97b3f5b07774", + "reference": "f29b7be8fa3046d2ee4c6421485b97b3f5b07774", + "shasum": "" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0" + ], + "description": "Blobs of data generated from Minecraft: Bedrock Edition, used by PocketMine-MP", + "support": { + "issues": "https://github.com/pmmp/BedrockData/issues", + "source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.17.40" + }, + "time": "2021-10-19T16:55:41+00:00" + }, { "name": "pocketmine/bedrock-protocol", "version": "5.0.0+bedrock-1.17.40", diff --git a/resources/vanilla b/resources/vanilla deleted file mode 160000 index f29b7be8fa..0000000000 --- a/resources/vanilla +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f29b7be8fa3046d2ee4c6421485b97b3f5b07774 diff --git a/src/CoreConstants.php b/src/CoreConstants.php index 63913e9417..91b9b95b95 100644 --- a/src/CoreConstants.php +++ b/src/CoreConstants.php @@ -35,4 +35,5 @@ define('pocketmine\_CORE_CONSTANTS_INCLUDED', true); define('pocketmine\PATH', dirname(__DIR__) . '/'); define('pocketmine\RESOURCE_PATH', dirname(__DIR__) . '/resources/'); +define('pocketmine\BEDROCK_DATA_PATH', dirname(__DIR__) . '/vendor/pocketmine/bedrock-data/'); define('pocketmine\COMPOSER_AUTOLOADER_PATH', dirname(__DIR__) . '/vendor/autoload.php'); diff --git a/src/Server.php b/src/Server.php index afe2404466..69cdc9f18e 100644 --- a/src/Server.php +++ b/src/Server.php @@ -932,7 +932,7 @@ class Server{ $this->commandMap = new SimpleCommandMap($this); - $this->craftingManager = CraftingManagerFromDataHelper::make(Path::join(\pocketmine\RESOURCE_PATH, "vanilla", "recipes.json")); + $this->craftingManager = CraftingManagerFromDataHelper::make(Path::join(\pocketmine\BEDROCK_DATA_PATH, "recipes.json")); $this->resourceManager = new ResourcePackManager(Path::join($this->getDataPath(), "resource_packs"), $this->logger); diff --git a/src/data/bedrock/LegacyBlockIdToStringIdMap.php b/src/data/bedrock/LegacyBlockIdToStringIdMap.php index c9e0212b08..5c52fa9728 100644 --- a/src/data/bedrock/LegacyBlockIdToStringIdMap.php +++ b/src/data/bedrock/LegacyBlockIdToStringIdMap.php @@ -30,6 +30,6 @@ final class LegacyBlockIdToStringIdMap extends LegacyToStringBidirectionalIdMap{ use SingletonTrait; public function __construct(){ - parent::__construct(Path::join(\pocketmine\RESOURCE_PATH, 'vanilla', 'block_id_map.json')); + parent::__construct(Path::join(\pocketmine\BEDROCK_DATA_PATH, 'block_id_map.json')); } } diff --git a/src/data/bedrock/LegacyEntityIdToStringIdMap.php b/src/data/bedrock/LegacyEntityIdToStringIdMap.php index fa37bfbd91..23852b9256 100644 --- a/src/data/bedrock/LegacyEntityIdToStringIdMap.php +++ b/src/data/bedrock/LegacyEntityIdToStringIdMap.php @@ -30,6 +30,6 @@ final class LegacyEntityIdToStringIdMap extends LegacyToStringBidirectionalIdMap use SingletonTrait; public function __construct(){ - parent::__construct(Path::join(\pocketmine\RESOURCE_PATH, 'vanilla', 'entity_id_map.json')); + parent::__construct(Path::join(\pocketmine\BEDROCK_DATA_PATH, 'entity_id_map.json')); } } diff --git a/src/data/bedrock/LegacyItemIdToStringIdMap.php b/src/data/bedrock/LegacyItemIdToStringIdMap.php index 083f2024b4..86cd83bf8a 100644 --- a/src/data/bedrock/LegacyItemIdToStringIdMap.php +++ b/src/data/bedrock/LegacyItemIdToStringIdMap.php @@ -30,6 +30,6 @@ final class LegacyItemIdToStringIdMap extends LegacyToStringBidirectionalIdMap{ use SingletonTrait; public function __construct(){ - parent::__construct(Path::join(\pocketmine\RESOURCE_PATH, 'vanilla', 'item_id_map.json')); + parent::__construct(Path::join(\pocketmine\BEDROCK_DATA_PATH, 'item_id_map.json')); } } diff --git a/src/inventory/CreativeInventory.php b/src/inventory/CreativeInventory.php index 99ad5f60ed..e71966f446 100644 --- a/src/inventory/CreativeInventory.php +++ b/src/inventory/CreativeInventory.php @@ -37,7 +37,7 @@ final class CreativeInventory{ private $creative = []; private function __construct(){ - $creativeItems = json_decode(file_get_contents(Path::join(\pocketmine\RESOURCE_PATH, "vanilla", "creativeitems.json")), true); + $creativeItems = json_decode(file_get_contents(Path::join(\pocketmine\BEDROCK_DATA_PATH, "creativeitems.json")), true); foreach($creativeItems as $data){ $item = Item::jsonDeserialize($data); diff --git a/src/network/mcpe/cache/StaticPacketCache.php b/src/network/mcpe/cache/StaticPacketCache.php index 901fe875cc..39b8ea7743 100644 --- a/src/network/mcpe/cache/StaticPacketCache.php +++ b/src/network/mcpe/cache/StaticPacketCache.php @@ -50,8 +50,8 @@ class StaticPacketCache{ private static function make() : self{ return new self( - BiomeDefinitionListPacket::create(self::loadCompoundFromFile(Path::join(\pocketmine\RESOURCE_PATH, 'vanilla', 'biome_definitions.nbt'))), - AvailableActorIdentifiersPacket::create(self::loadCompoundFromFile(Path::join(\pocketmine\RESOURCE_PATH, 'vanilla', 'entity_identifiers.nbt'))) + BiomeDefinitionListPacket::create(self::loadCompoundFromFile(Path::join(\pocketmine\BEDROCK_DATA_PATH, 'biome_definitions.nbt'))), + AvailableActorIdentifiersPacket::create(self::loadCompoundFromFile(Path::join(\pocketmine\BEDROCK_DATA_PATH, 'entity_identifiers.nbt'))) ); } diff --git a/src/network/mcpe/convert/GlobalItemTypeDictionary.php b/src/network/mcpe/convert/GlobalItemTypeDictionary.php index c1537fa7cd..d3ab00f533 100644 --- a/src/network/mcpe/convert/GlobalItemTypeDictionary.php +++ b/src/network/mcpe/convert/GlobalItemTypeDictionary.php @@ -39,7 +39,7 @@ final class GlobalItemTypeDictionary{ use SingletonTrait; private static function make() : self{ - $data = file_get_contents(Path::join(\pocketmine\RESOURCE_PATH, 'vanilla', 'required_item_list.json')); + $data = file_get_contents(Path::join(\pocketmine\BEDROCK_DATA_PATH, 'required_item_list.json')); if($data === false) throw new AssumptionFailedError("Missing required resource file"); $table = json_decode($data, true); if(!is_array($table)){ diff --git a/src/network/mcpe/convert/ItemTranslator.php b/src/network/mcpe/convert/ItemTranslator.php index c7cba0226a..bffa6cb180 100644 --- a/src/network/mcpe/convert/ItemTranslator.php +++ b/src/network/mcpe/convert/ItemTranslator.php @@ -66,14 +66,14 @@ final class ItemTranslator{ private $complexNetToCoreMapping = []; private static function make() : self{ - $data = file_get_contents(Path::join(\pocketmine\RESOURCE_PATH, 'vanilla', 'r16_to_current_item_map.json')); + $data = file_get_contents(Path::join(\pocketmine\BEDROCK_DATA_PATH, 'r16_to_current_item_map.json')); if($data === false) throw new AssumptionFailedError("Missing required resource file"); $json = json_decode($data, true); if(!is_array($json) or !isset($json["simple"], $json["complex"]) || !is_array($json["simple"]) || !is_array($json["complex"])){ throw new AssumptionFailedError("Invalid item table format"); } - $legacyStringToIntMapRaw = file_get_contents(Path::join(\pocketmine\RESOURCE_PATH, 'vanilla', 'item_id_map.json')); + $legacyStringToIntMapRaw = file_get_contents(Path::join(\pocketmine\BEDROCK_DATA_PATH, 'item_id_map.json')); if($legacyStringToIntMapRaw === false){ throw new AssumptionFailedError("Missing required resource file"); } diff --git a/src/network/mcpe/convert/RuntimeBlockMapping.php b/src/network/mcpe/convert/RuntimeBlockMapping.php index 45affea444..dfa69168e6 100644 --- a/src/network/mcpe/convert/RuntimeBlockMapping.php +++ b/src/network/mcpe/convert/RuntimeBlockMapping.php @@ -49,7 +49,7 @@ final class RuntimeBlockMapping{ private $bedrockKnownStates; private function __construct(){ - $canonicalBlockStatesFile = file_get_contents(Path::join(\pocketmine\RESOURCE_PATH, "vanilla", "canonical_block_states.nbt")); + $canonicalBlockStatesFile = file_get_contents(Path::join(\pocketmine\BEDROCK_DATA_PATH, "canonical_block_states.nbt")); if($canonicalBlockStatesFile === false){ throw new AssumptionFailedError("Missing required resource file"); } @@ -67,7 +67,7 @@ final class RuntimeBlockMapping{ $legacyIdMap = LegacyBlockIdToStringIdMap::getInstance(); /** @var R12ToCurrentBlockMapEntry[] $legacyStateMap */ $legacyStateMap = []; - $legacyStateMapReader = PacketSerializer::decoder(file_get_contents(Path::join(\pocketmine\RESOURCE_PATH, "vanilla", "r12_to_current_block_map.bin")), 0, new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary())); + $legacyStateMapReader = PacketSerializer::decoder(file_get_contents(Path::join(\pocketmine\BEDROCK_DATA_PATH, "r12_to_current_block_map.bin")), 0, new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary())); $nbtReader = new NetworkNbtSerializer(); while(!$legacyStateMapReader->feof()){ $id = $legacyStateMapReader->getString(); From 38f97bed5257f9bdbf04b8ddc12231209c6e96c6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 16:58:14 +0000 Subject: [PATCH 3108/3224] World: fixed PopulationTask failed assumption that generator is always registered if the worker selected previously had a generator registered, but has since been shutdown, the workerStartHook that cleans up generatorRegisteredWorkers won't yet have been called. This results in the worker being started by the submission of PopulationTask, and the generator doesn't get preemptively registered. --- src/world/World.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/world/World.php b/src/world/World.php index bdb8d9fbbf..6d3af41903 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2904,6 +2904,10 @@ class World implements ChunkManager{ } ); $workerId = $this->workerPool->selectWorker(); + if(!isset($this->workerPool->getRunningWorkers()[$workerId]) && isset($this->generatorRegisteredWorkers[$workerId])){ + $this->logger->debug("Selected worker $workerId previously had generator registered, but is now offline"); + unset($this->generatorRegisteredWorkers[$workerId]); + } if(!isset($this->generatorRegisteredWorkers[$workerId])){ $this->registerGeneratorToWorker($workerId); } From ead8ccf08d3d3792224795728d225e949f33ab9f Mon Sep 17 00:00:00 2001 From: Colin Date: Tue, 2 Nov 2021 18:05:07 +0100 Subject: [PATCH 3109/3224] CocoaBlock: call BlockGrowEvent when growing for any reason (#4536) --- src/block/CocoaBlock.php | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/block/CocoaBlock.php b/src/block/CocoaBlock.php index 82b5141729..efcc4590fb 100644 --- a/src/block/CocoaBlock.php +++ b/src/block/CocoaBlock.php @@ -26,6 +26,7 @@ namespace pocketmine\block; use pocketmine\block\utils\BlockDataSerializer; use pocketmine\block\utils\HorizontalFacingTrait; use pocketmine\block\utils\TreeType; +use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Fertilizer; use pocketmine\item\Item; use pocketmine\item\VanillaItems; @@ -94,10 +95,7 @@ class CocoaBlock extends Transparent{ } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($this->age < 2 and $item instanceof Fertilizer){ - $this->age++; - $this->position->getWorld()->setBlock($this->position, $this); - + if($item instanceof Fertilizer && $this->grow()){ $item->pop(); return true; @@ -117,12 +115,25 @@ class CocoaBlock extends Transparent{ } public function onRandomTick() : void{ - if($this->age < 2 and mt_rand(1, 5) === 1){ - $this->age++; - $this->position->getWorld()->setBlock($this->position, $this); + if(mt_rand(1, 5) === 1){ + $this->grow(); } } + private function grow() : bool{ + if($this->age < 2){ + $block = clone $this; + $block->age++; + $ev = new BlockGrowEvent($this, $block); + $ev->call(); + if(!$ev->isCancelled()){ + $this->position->getWorld()->setBlock($this->position, $ev->getNewState()); + return true; + } + } + return false; + } + public function getDropsForCompatibleTool(Item $item) : array{ return [ VanillaItems::COCOA_BEANS()->setCount($this->age === 2 ? mt_rand(2, 3) : 1) From d184838ba0196305a0f1ab6a9f46734292516551 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 17:10:07 +0000 Subject: [PATCH 3110/3224] Move Promise classes to their own namespace --- src/Server.php | 4 ++-- src/{utils => promise}/Promise.php | 2 +- src/{utils => promise}/PromiseResolver.php | 2 +- src/{utils => promise}/PromiseSharedData.php | 2 +- src/world/World.php | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) rename src/{utils => promise}/Promise.php (98%) rename src/{utils => promise}/PromiseResolver.php (98%) rename src/{utils => promise}/PromiseSharedData.php (97%) diff --git a/src/Server.php b/src/Server.php index 69cdc9f18e..753556ff87 100644 --- a/src/Server.php +++ b/src/Server.php @@ -82,6 +82,8 @@ use pocketmine\plugin\PluginGraylist; use pocketmine\plugin\PluginManager; use pocketmine\plugin\PluginOwned; use pocketmine\plugin\ScriptPluginLoader; +use pocketmine\promise\Promise; +use pocketmine\promise\PromiseResolver; use pocketmine\resourcepacks\ResourcePackManager; use pocketmine\scheduler\AsyncPool; use pocketmine\snooze\SleeperHandler; @@ -98,8 +100,6 @@ use pocketmine\utils\MainLogger; use pocketmine\utils\NotCloneable; use pocketmine\utils\NotSerializable; use pocketmine\utils\Process; -use pocketmine\utils\Promise; -use pocketmine\utils\PromiseResolver; use pocketmine\utils\SignalHandler; use pocketmine\utils\Terminal; use pocketmine\utils\TextFormat; diff --git a/src/utils/Promise.php b/src/promise/Promise.php similarity index 98% rename from src/utils/Promise.php rename to src/promise/Promise.php index d9ae9c5637..28666917e9 100644 --- a/src/utils/Promise.php +++ b/src/promise/Promise.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\utils; +namespace pocketmine\promise; use function spl_object_id; diff --git a/src/utils/PromiseResolver.php b/src/promise/PromiseResolver.php similarity index 98% rename from src/utils/PromiseResolver.php rename to src/promise/PromiseResolver.php index 81ed05201d..0f447693fc 100644 --- a/src/utils/PromiseResolver.php +++ b/src/promise/PromiseResolver.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\utils; +namespace pocketmine\promise; /** * @phpstan-template TValue diff --git a/src/utils/PromiseSharedData.php b/src/promise/PromiseSharedData.php similarity index 97% rename from src/utils/PromiseSharedData.php rename to src/promise/PromiseSharedData.php index 05c5ab0074..bccf56cc29 100644 --- a/src/utils/PromiseSharedData.php +++ b/src/promise/PromiseSharedData.php @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace pocketmine\utils; +namespace pocketmine\promise; /** * @internal diff --git a/src/world/World.php b/src/world/World.php index 6d3af41903..978bd8a42d 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -66,13 +66,13 @@ use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\types\BlockPosition; use pocketmine\network\mcpe\protocol\UpdateBlockPacket; use pocketmine\player\Player; +use pocketmine\promise\Promise; +use pocketmine\promise\PromiseResolver; use pocketmine\scheduler\AsyncPool; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Limits; -use pocketmine\utils\Promise; -use pocketmine\utils\PromiseResolver; use pocketmine\utils\ReversePriorityQueue; use pocketmine\world\biome\Biome; use pocketmine\world\biome\BiomeRegistry; From 4ca7c29cde281a28fdfa3adfccae5e04e2561860 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 19:14:12 +0000 Subject: [PATCH 3111/3224] Release 4.0.0-BETA9 --- changelogs/4.0.md | 74 +++++++++++++++++++++++++++++++++++++++++++++ src/VersionInfo.php | 2 +- 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index 12f7fff642..41392cac26 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1527,3 +1527,77 @@ Released 29th October 2021. - All parameters are now mandatory. - Reverted addition of chunk modification counters in previous beta. - `Chunk::DIRTY_FLAG_TERRAIN` has been renamed to `Chunk::DIRTY_FLAG_BLOCKS`. + +# 4.0.0-BETA9 +Released 2nd November 2021. + +## General +- Now analysed using level 9 on PHPStan 1.0.0. +- `ext-pthreads` v4.0.0 or newer is now required. +- `resources/vanilla` submodule has been removed. BedrockData is now included via Composer dependency [`pocketmine/bedrock-data`](https://packagist.org/packages/pocketmine/bedrock-data). +- `pocketmine/spl` Composer dependency has been dropped. +- The following Composer dependency versions are now required: + - [`pocketmine/bedrock-protocol` v5.0.0](https://github.com/pmmp/BedrockProtocol/tree/5.0.0+bedrock-1.17.40) features substantial changes to its API compared to 3.0.1, which was used in 4.0.0-BETA8. Please see its [release notes](https://github.com/pmmp/BedrockData/releases/tag/5.0.0+bedrock-1.17.40). + - [`pocketmine/log` v0.4.0](https://github.com/pmmp/Log/tree/0.4.0) removes the `LoggerAttachment` interface and replaces logger attachment objects with closures. + - [`pocketmine/log-pthreads` v0.4.0](https://github.com/pmmp/LogPthreads/tree/0.4.0) + - [`pocketmine/classloader` v0.2.0](https://github.com/pmmp/ClassLoader/tree/0.2.0) +- A noisy debug message in `World->updateAllLight()` has been removed. + +## API +### Entity +- `Human->setLifetimeTotalXp()` now limits the maximum value to 2^31. + +### Event +- `BlockGrowEvent` is now called when cocoa pods grow. + +### Item +- Added `Releasable->canStartUsingItem()`. + +### Network +- Added `NetworkInterfaceStartException`, which may be thrown by `Network->registerInterface()` and `NetworkInterface->start()`. + +### Player +- `SurvivalBlockBreakHandler::createIfNecessary()` has been removed. +- `SurvivalBlockBreakHandler->__construct()` is now public. +- `UsedChunkStatus::REQUESTED()` has been renamed to `REQUESTED_SENDING`. +- `UsedChunkStatus::REQUESTED_GENERATION()` has been added. + +### Utils +- `Promise` API has changed: + - Promise-related classes have been moved to `pocketmine\promise` namespace. + - It's now split into `Promise` and `PromiseResolver`. + - `PromiseResolver` provides only `resolve()` and `reject()`. It should be used by callbacks to resolve a promise. + - `Promise` now provides only `onCompletion()` and `isResolved()` APIs. This should be given to consumers to allow them to handle the result of the async operation. + - `PromiseResolver` must not be created directly. Use `new PromiseResolver` and `PromiseResolver->getPromise()`. + +### World +- Improved performance of `setBlock()` by around 35% when the `$update` parameter is set to `true`. +- Improved performance of `setBlock()` by around 30% when the `$update` parameter is set to `false`. +- `World->generateChunkCallback()` is no longer exposed to public API. +- `World->getAdjacentChunks()` now returns an array indexed using `World::chunkHash()`, where the `x` and `z` components are the relative offsets from the target chunk (range -1 to +1). +- `World->lockChunk()` now requires `ChunkLockId $lockId` parameter. +- `World->unlockChunk()` now requires a `?ChunkLockId $lockId` parameter. If a non-null lockID is given, the lock on the chunk will only be removed if it matches the given lockID. +- `World->unlockChunk()` now returns `bool` instead of `void` (to signal whether unlocking succeded or not). +- Added `ChunkLockId` class. + +## Fixes +### World +- Fixed server crash when tiles with colliding positions are loaded from saved data. Now, an error is logged, but the server won't crash. +- Fixed server crash when liquids and other items flow into terrain locked for population. Now, an advisory locking mechanism is used, and population results will be discarded and recalculated if modifications are detected. +- Fixed various crashes that could occur if a chunk was flagged with `setPopulated(true)` after a promise had already been created for its population. +- Fixed `AssumptionFailedError` in `PopulationTask` when workers previously used for generation are shutdown, and then restarted on the fly by a generation request. +- Fixed assertion failure in `World->drainPopulationRequestQueue()` when requesting, cancelling and then re-requesting generation of a chunk while the generator was busy. +- Fixed generation potentially getting stuck if a population request was cancelled while the population task was running (failure to remove locks from used chunks). +- Fixed `World->requestChunkPopulation()` not taking into account that the target chunk may already be populated. This caused a variety of strange bugs and performance issues. +- Fixed potential memory leak caused by `World->unregisterChunkListenerFromAll()` not taking players into account. +- Fixed debug spam of `chunk has no loaders registered` messages during chunk generation. + +### Other fixes +- Fixed server crash when unable to bind to the desired port. Now, the server will show an error and gracefully stop without a crashdump instead. +- Fixed server crash in `Player->showPlayer()` when the target is not in the same world. +- Fixed players, who died in hardcore mode and were unbanned, getting re-banned on next server join. +- Fixed cake block desync when attempting to eat in creative (eating in creative is not yet supported, but the block rollback was missing). +- Fixed players being able to eat items more quickly by dropping them while eating. +- Fixed arrows getting added to creative players' inventories when picked up. +- Fixed players re-requesting the same ungenerated chunks multiple times before they were sent. +- Fixed commands not working in some cases after using some control sequences on the console. diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 10d2f6e4bf..5431c30e6f 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -30,7 +30,7 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; public const BASE_VERSION = "4.0.0-BETA9"; - public const IS_DEVELOPMENT_BUILD = true; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_NUMBER = 0; public const BUILD_CHANNEL = "beta"; From f50f26d52e4d7283c53a89c8415d9b308715bc1a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 19:14:15 +0000 Subject: [PATCH 3112/3224] 4.0.0-BETA10 is next --- src/VersionInfo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 5431c30e6f..69254d79d4 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -29,8 +29,8 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "4.0.0-BETA9"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "4.0.0-BETA10"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_NUMBER = 0; public const BUILD_CHANNEL = "beta"; From 102277c6366ae4843a69cef41448cfe21be13d27 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 19:16:36 +0000 Subject: [PATCH 3113/3224] draft-release: fixed BedrockData JSON minification --- .github/workflows/draft-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml index 6c3d25996e..6c3caf748f 100644 --- a/.github/workflows/draft-release.yml +++ b/.github/workflows/draft-release.yml @@ -42,7 +42,7 @@ jobs: sed -i "s/const BUILD_NUMBER = 0/const BUILD_NUMBER = ${BUILD_NUMBER}/" src/VersionInfo.php - name: Minify BedrockData JSON files - run: php resources/vanilla/.minify_json.php + run: php vendor/pocketmine/bedrock-data/.minify_json.php - name: Build PocketMine-MP.phar run: php -dphar.readonly=0 build/server-phar.php --git ${{ github.sha }} From fa6a432d5816bb8c5d5546549ac3988fede14728 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 19:18:19 +0000 Subject: [PATCH 3114/3224] Release 4.0.0-BETA10 --- changelogs/4.0.md | 6 ++++++ src/VersionInfo.php | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index 41392cac26..2ef72ea0be 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1601,3 +1601,9 @@ Released 2nd November 2021. - Fixed arrows getting added to creative players' inventories when picked up. - Fixed players re-requesting the same ungenerated chunks multiple times before they were sent. - Fixed commands not working in some cases after using some control sequences on the console. + +# 4.0.0-BETA10 +Released 2nd November 2021. + +## Fixes +- Fixed an issue with BedrockData JSON minification which broke the release build of 4.0.0-BETA9. diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 69254d79d4..d220afe32c 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -30,7 +30,7 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; public const BASE_VERSION = "4.0.0-BETA10"; - public const IS_DEVELOPMENT_BUILD = true; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_NUMBER = 0; public const BUILD_CHANNEL = "beta"; From a0e9eec652623b6eb6d9244708994961c009c067 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 19:18:20 +0000 Subject: [PATCH 3115/3224] 4.0.0-BETA11 is next --- src/VersionInfo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index d220afe32c..f394d85d99 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -29,8 +29,8 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "4.0.0-BETA10"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "4.0.0-BETA11"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_NUMBER = 0; public const BUILD_CHANNEL = "beta"; From f0661999717abc3ed5cefceb4c47b732915761f3 Mon Sep 17 00:00:00 2001 From: Hashim <13991048+Prim69@users.noreply.github.com> Date: Tue, 2 Nov 2021 19:04:55 -0400 Subject: [PATCH 3116/3224] Implement emote support (#4523) --- src/event/player/PlayerEmoteEvent.php | 51 +++++++++++++++++++ src/network/mcpe/NetworkSession.php | 5 ++ .../mcpe/handler/InGamePacketHandler.php | 6 +++ src/player/Player.php | 14 +++++ 4 files changed, 76 insertions(+) create mode 100644 src/event/player/PlayerEmoteEvent.php diff --git a/src/event/player/PlayerEmoteEvent.php b/src/event/player/PlayerEmoteEvent.php new file mode 100644 index 0000000000..b10a3171e1 --- /dev/null +++ b/src/event/player/PlayerEmoteEvent.php @@ -0,0 +1,51 @@ +player = $player; + } + + public function getEmoteId() : string{ + return $this->emoteId; + } + + public function setEmoteId(string $emoteId) : void{ + $this->emoteId = $emoteId; + } + +} diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index cf189d8755..ee7c349971 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -62,6 +62,7 @@ use pocketmine\network\mcpe\protocol\AvailableCommandsPacket; use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket; use pocketmine\network\mcpe\protocol\ClientboundPacket; use pocketmine\network\mcpe\protocol\DisconnectPacket; +use pocketmine\network\mcpe\protocol\EmotePacket; use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket; use pocketmine\network\mcpe\protocol\MobEffectPacket; use pocketmine\network\mcpe\protocol\MobEquipmentPacket; @@ -1043,6 +1044,10 @@ class NetworkSession{ $this->sendDataPacket(SetTitlePacket::setAnimationTimes($fadeIn, $stay, $fadeOut)); } + public function onEmote(Player $from, string $emoteId) : void{ + $this->sendDataPacket(EmotePacket::create($from->getId(), $emoteId, EmotePacket::FLAG_SERVER)); + } + public function tick() : void{ if($this->info === null){ if(time() >= $this->connectTime + 10){ diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index a884bf7c2c..ad8b001c08 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -59,6 +59,7 @@ use pocketmine\network\mcpe\protocol\CommandRequestPacket; use pocketmine\network\mcpe\protocol\ContainerClosePacket; use pocketmine\network\mcpe\protocol\ContainerOpenPacket; use pocketmine\network\mcpe\protocol\CraftingEventPacket; +use pocketmine\network\mcpe\protocol\EmotePacket; use pocketmine\network\mcpe\protocol\InteractPacket; use pocketmine\network\mcpe\protocol\InventoryTransactionPacket; use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket; @@ -890,4 +891,9 @@ class InGamePacketHandler extends PacketHandler{ */ return true; } + + public function handleEmote(EmotePacket $packet) : bool{ + $this->player->emote($packet->getEmoteId()); + return true; + } } diff --git a/src/player/Player.php b/src/player/Player.php index 1ca3faee84..ef48c5b2bf 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -53,6 +53,7 @@ use pocketmine\event\player\PlayerChatEvent; use pocketmine\event\player\PlayerCommandPreprocessEvent; use pocketmine\event\player\PlayerDeathEvent; use pocketmine\event\player\PlayerDisplayNameChangeEvent; +use pocketmine\event\player\PlayerEmoteEvent; use pocketmine\event\player\PlayerEntityInteractEvent; use pocketmine\event\player\PlayerExhaustEvent; use pocketmine\event\player\PlayerGameModeChangeEvent; @@ -234,6 +235,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ /** @var int[] ID => ticks map */ protected array $usedItemsCooldown = []; + private int $lastEmoteTick = 0; + protected int $formIdCounter = 0; /** @var Form[] */ protected array $forms = []; @@ -1727,6 +1730,17 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return true; } + public function emote(string $emoteId) : void{ + $event = new PlayerEmoteEvent($this, $emoteId); + $event->call(); + if(!$event->isCancelled() && $this->getServer()->getTick() - $this->lastEmoteTick > 5){ + $this->lastEmoteTick = $this->getServer()->getTick(); + foreach($this->getViewers() as $player){ + $player->getNetworkSession()->onEmote($this, $emoteId); + } + } + } + /** * Drops an item on the ground in front of the player. */ From 87031627bfd1ba0d1df0ba5697eead31592d5f80 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 23:09:43 +0000 Subject: [PATCH 3117/3224] Do not call PlayerEmoteEvent if rate limit was reached --- src/player/Player.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index ef48c5b2bf..a9df0d04fe 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1731,12 +1731,15 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } public function emote(string $emoteId) : void{ - $event = new PlayerEmoteEvent($this, $emoteId); - $event->call(); - if(!$event->isCancelled() && $this->getServer()->getTick() - $this->lastEmoteTick > 5){ - $this->lastEmoteTick = $this->getServer()->getTick(); - foreach($this->getViewers() as $player){ - $player->getNetworkSession()->onEmote($this, $emoteId); + $currentTick = $this->server->getTick(); + if($currentTick - $this->lastEmoteTick > 5){ + $this->lastEmoteTick = $currentTick; + $event = new PlayerEmoteEvent($this, $emoteId); + $event->call(); + if(!$event->isCancelled()){ + foreach($this->getViewers() as $player){ + $player->getNetworkSession()->onEmote($this, $emoteId); + } } } } From ef82a2cd7997e8b4a665a7e9ee8ba768a45b9c23 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 2 Nov 2021 23:10:26 +0000 Subject: [PATCH 3118/3224] Fixed PlayerEmoteEvent::setEmoteId() being useless --- src/player/Player.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/player/Player.php b/src/player/Player.php index a9df0d04fe..2f27430ac7 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1737,6 +1737,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $event = new PlayerEmoteEvent($this, $emoteId); $event->call(); if(!$event->isCancelled()){ + $emoteId = $event->getEmoteId(); foreach($this->getViewers() as $player){ $player->getNetworkSession()->onEmote($this, $emoteId); } From 1ebb2067627c298834a60b992ee42a98091a38fd Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 3 Nov 2021 14:58:58 +0000 Subject: [PATCH 3119/3224] World: fixed yet another edge case in drainPopulationRequestQueue() leading to assertion failure really had to go fucking nuclear on it :( --- src/world/World.php | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/world/World.php b/src/world/World.php index 978bd8a42d..a06f2ad5ec 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -263,6 +263,12 @@ class World implements ChunkManager{ * @phpstan-var \SplQueue */ private \SplQueue $chunkPopulationRequestQueue; + /** + * @var true[] chunkHash => dummy + * @phpstan-var array + */ + private array $chunkPopulationRequestQueueIndex = []; + /** @var bool[] */ private $generatorRegisteredWorkers = []; @@ -2733,12 +2739,19 @@ class World implements ChunkManager{ } } + private function addChunkHashToPopulationRequestQueue(int $chunkHash) : void{ + if(!isset($this->chunkPopulationRequestQueueIndex[$chunkHash])){ + $this->chunkPopulationRequestQueue->enqueue($chunkHash); + $this->chunkPopulationRequestQueueIndex[$chunkHash] = true; + } + } + /** * @phpstan-return Promise */ private function enqueuePopulationRequest(int $chunkX, int $chunkZ, ?ChunkLoader $associatedChunkLoader) : Promise{ $chunkHash = World::chunkHash($chunkX, $chunkZ); - $this->chunkPopulationRequestQueue->enqueue($chunkHash); + $this->addChunkHashToPopulationRequestQueue($chunkHash); $resolver = $this->chunkPopulationRequestMap[$chunkHash] = new PromiseResolver(); if($associatedChunkLoader === null){ $temporaryLoader = new class implements ChunkLoader{}; @@ -2753,17 +2766,9 @@ class World implements ChunkManager{ private function drainPopulationRequestQueue() : void{ $failed = []; - $seen = []; while(count($this->activeChunkPopulationTasks) < $this->maxConcurrentChunkPopulationTasks && !$this->chunkPopulationRequestQueue->isEmpty()){ $nextChunkHash = $this->chunkPopulationRequestQueue->dequeue(); - if(isset($seen[$nextChunkHash])){ - //We may have previously requested this, decided we didn't want it, and then decided we did want it - //again, all before the generation request got executed. In that case, the chunk hash may appear in the - //queue multiple times (it can't be quickly removed from the queue when the request is cancelled, so we - //leave it in the queue). - continue; - } - $seen[$nextChunkHash] = true; + unset($this->chunkPopulationRequestQueueIndex[$nextChunkHash]); World::getXZ($nextChunkHash, $nextChunkX, $nextChunkZ); if(isset($this->chunkPopulationRequestMap[$nextChunkHash])){ assert(!isset($this->activeChunkPopulationTasks[$nextChunkHash]), "Population for chunk $nextChunkX $nextChunkZ already running"); @@ -2779,7 +2784,7 @@ class World implements ChunkManager{ //these requests failed even though they weren't rate limited; we can't directly re-add them to the back of the //queue because it would result in an infinite loop foreach($failed as $hash){ - $this->chunkPopulationRequestQueue->enqueue($hash); + $this->addChunkHashToPopulationRequestQueue($hash); } } @@ -2978,7 +2983,7 @@ class World implements ChunkManager{ //request failed, stick it back on the queue //we didn't resolve the promise or touch it in any way, so any fake chunk loaders are still valid and //don't need to be added a second time. - $this->chunkPopulationRequestQueue->enqueue($index); + $this->addChunkHashToPopulationRequestQueue($index); } $this->drainPopulationRequestQueue(); From 5c81b0481306f428934bffbdae34eed9bd19c575 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 3 Nov 2021 15:22:49 +0000 Subject: [PATCH 3120/3224] PopulationTask: use typed properties --- src/world/generator/PopulationTask.php | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index f1f2d38580..4ba21312f3 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -41,15 +41,11 @@ use function igbinary_unserialize; class PopulationTask extends AsyncTask{ private const TLS_KEY_ON_COMPLETION = "onCompletion"; - /** @var int */ - public $worldId; - /** @var int */ - private $chunkX; - /** @var int */ - private $chunkZ; + public int $worldId; + private int $chunkX; + private int $chunkZ; - /** @var string|null */ - public $chunk; + public ?string $chunk; private string $adjacentChunks; From 0356716e8e7f1b9d8ca87645b577d0dcf505cfd0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 3 Nov 2021 15:23:43 +0000 Subject: [PATCH 3121/3224] PopulationTask: do not expose internal fields as public this code dates back to pthreads v2, when visibility on Threaded object fields meant different things (wtf, krakjoe??) --- src/world/generator/PopulationTask.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 4ba21312f3..a50f884fca 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -41,11 +41,11 @@ use function igbinary_unserialize; class PopulationTask extends AsyncTask{ private const TLS_KEY_ON_COMPLETION = "onCompletion"; - public int $worldId; + private int $worldId; private int $chunkX; private int $chunkZ; - public ?string $chunk; + private ?string $chunk; private string $adjacentChunks; From 2405e45b357caf7e0284ffd7d91c302260d10722 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 3 Nov 2021 21:26:20 +0000 Subject: [PATCH 3122/3224] Player: mark as not using item when held item slot is changed closes #4538 --- src/player/Player.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/player/Player.php b/src/player/Player.php index 2f27430ac7..fdbb60391c 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -73,6 +73,7 @@ use pocketmine\event\player\PlayerToggleSprintEvent; use pocketmine\event\player\PlayerTransferEvent; use pocketmine\form\Form; use pocketmine\form\FormValidationException; +use pocketmine\inventory\CallbackInventoryListener; use pocketmine\inventory\Inventory; use pocketmine\inventory\PlayerCursorInventory; use pocketmine\inventory\transaction\action\DropItemAction; @@ -291,6 +292,17 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ parent::initEntity($nbt); $this->addDefaultWindows(); + $this->inventory->getListeners()->add(new CallbackInventoryListener( + function(Inventory $unused, int $slot) : void{ + if($slot === $this->inventory->getHeldItemIndex()){ + $this->setUsingItem(false); + } + }, + function() : void{ + $this->setUsingItem(false); + } + )); + $this->firstPlayed = $nbt->getLong("firstPlayed", $now = (int) (microtime(true) * 1000)); $this->lastPlayed = $nbt->getLong("lastPlayed", $now); From 4f8501ff34fc0cb4f8f64c09a7a149421598c414 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Nov 2021 14:14:55 +0000 Subject: [PATCH 3123/3224] Added a tool to visualise behaviour of ChunkSelector I actually intended to write a tool for debugging generation, but it turns out this, as an intermediary step, is also useful and a whole bunch of fun to play with. --- tools/simulate-chunk-selector.php | 171 ++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 tools/simulate-chunk-selector.php diff --git a/tools/simulate-chunk-selector.php b/tools/simulate-chunk-selector.php new file mode 100644 index 0000000000..9ae7a11619 --- /dev/null +++ b/tools/simulate-chunk-selector.php @@ -0,0 +1,171 @@ +selectChunks($radius, $baseX, $baseZ); + + $middleOffsetX = $scale * ($radius + $offsetX); + $middleOffsetZ = $scale * ($radius + $offsetZ); + + $frame = 0; + $seen = []; + while($iterator->valid()){ + $frame++; + + $black = imagecolorallocate($image, 0, 0, 0); + $yellow = imagecolorallocate($image, 255, 255, 51); + $red = imagecolorallocate($image, 255, 0, 0); + if($black === false || $yellow === false || $red === false) throw new AssumptionFailedError(); + + for($i = 0; $i < $chunksPerStep; ++$i){ + $chunkHash = $iterator->current(); + if(!isset($seen[$chunkHash])){ + $color = $chunkColor; + $seen[$chunkHash] = true; + }else{ + $color = $yellow; + } + World::getXZ($chunkHash, $chunkX, $chunkZ); + $imageX = $middleOffsetX + (($chunkX - $baseX) * $scale); + $imageZ = $middleOffsetZ + (($chunkZ - $baseZ) * $scale); + + imagefilledrectangle($image, $imageX, $imageZ, $imageX + $scale, $imageZ + $scale, $color); + imagerectangle($image, $imageX, $imageZ, $imageX + $scale, $imageZ + $scale, $black); + + $iterator->next(); + if(!$iterator->valid()){ + break; + } + } + imagearc($image, $middleOffsetX, $middleOffsetZ, $radius * $scale * 2, $radius * $scale * 2, 0, 360, $red); + + imagepng($image, Path::join($outputFolder, "frame" . str_pad(strval($frame), 5, "0", STR_PAD_LEFT) . ".png")); + echo "\rRendered step $frame"; + } + echo "\n"; +} + +$radius = null; +$baseX = 10000 >> Chunk::COORD_BIT_SIZE; +$baseZ = 10000 >> Chunk::COORD_BIT_SIZE; + +$nChunksPerStep = 32; +$scale = 10; + +if(count(getopt("", ["help"])) !== 0){ + echo "Required parameters:\n"; + echo "--output=path/to/dir: Output folder to put the generated images into (will attempt to create if it doesn't exist)\n"; + echo "--radius=N: Radius of chunks to render (default $radius)\n"; + echo "\n"; + echo "Optional parameters:\n"; + echo "--baseX=N: Base X coordinate to use for simulation (default $baseX\n"; + echo "--baseZ=N: Base Z coordinate to use for simulation (default $baseZ)\n"; + echo "--scale=N: Height/width of square of pixels to use for each chunk (default $scale)\n"; + echo "--chunksPerStep=N: Number of chunks to process in each frame (default $nChunksPerStep)\n"; + exit(0); +} + +foreach(getopt("", ["radius:", "baseX:", "baseZ:", "scale:", "chunksPerStep:"]) as $name => $value){ + if(!is_string($value) || (string) ((int) $value) !== $value){ + fwrite(STDERR, "Value for --$name must be an integer\n"); + exit(1); + } + $value = (int) $value; + match($name){ + "radius" => ($radius = $value), + "baseX" => ($baseX = $value), + "baseZ" => ($baseZ = $value), + "scale" => ($scale = $value), + "chunksPerStep" => ($nChunksPerStep = $value), + default => throw new AssumptionFailedError("getopt() returned unknown option") + }; +} +if($radius === null){ + fwrite(STDERR, "Please specify a radius using --radius\n"); + exit(1); +} + +$outputDirectory = null; +foreach(getopt("", ["output:"]) as $name => $value){ + assert($name === "output"); + if(!is_string($value)){ + fwrite(STDERR, "Value for --$name must be a string\n"); + exit(1); + } + if(!@mkdir($value) && !is_dir($value)){ + fwrite(STDERR, "Output directory $value could not be created\n"); + exit(1); + } + $files = scandir($value, SCANDIR_SORT_NONE); + if($files !== false && count($files) > 2){ //always returns . and .. + fwrite(STDERR, "Output directory $value is not empty\n"); + exit(1); + } + $realPath = realpath($value); + if($realPath === false){ + throw new AssumptionFailedError(); + } + $outputDirectory = $realPath; +} +if($outputDirectory === null){ + fwrite(STDERR, "Please specify an output directory using --output\n"); + exit(1); +} +$image = newImage($scale, $radius); + +$black = imagecolorallocate($image, 0, 0, 0); +$green = imagecolorallocate($image, 0, 220, 0); +if($black === false || $green === false){ + throw new AssumptionFailedError(); +} +render($radius, $baseX, $baseZ, $nChunksPerStep, $scale, $image, $green, 0, 0, $outputDirectory); From 8ac999cbd4fb7d0049a31b83f54a1147aab41fad Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Nov 2021 16:55:04 +0000 Subject: [PATCH 3124/3224] Use object models for crashdump generation --- src/CrashDump.php | 120 ++++++++++++------------- src/Server.php | 6 +- src/crash/CrashDumpData.php | 84 +++++++++++++++++ src/crash/CrashDumpDataGeneral.php | 46 ++++++++++ src/crash/CrashDumpDataPluginEntry.php | 45 ++++++++++ 5 files changed, 233 insertions(+), 68 deletions(-) create mode 100644 src/crash/CrashDumpData.php create mode 100644 src/crash/CrashDumpDataGeneral.php create mode 100644 src/crash/CrashDumpDataPluginEntry.php diff --git a/src/CrashDump.php b/src/CrashDump.php index d6cf5caf09..b18d09021e 100644 --- a/src/CrashDump.php +++ b/src/CrashDump.php @@ -24,6 +24,9 @@ declare(strict_types=1); namespace pocketmine; use Composer\InstalledVersions; +use pocketmine\crash\CrashDumpData; +use pocketmine\crash\CrashDumpDataGeneral; +use pocketmine\crash\CrashDumpDataPluginEntry; use pocketmine\errorhandler\ErrorTypeToStringMap; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\plugin\PluginBase; @@ -69,6 +72,7 @@ use const FILE_IGNORE_NEW_LINES; use const JSON_UNESCAPED_SLASHES; use const PHP_EOL; use const PHP_OS; +use const PHP_VERSION; use const SORT_STRING; class CrashDump{ @@ -91,13 +95,9 @@ class CrashDump{ private $fp; /** @var float */ private $time; - /** - * @var mixed[] - * @phpstan-var array - */ - private $data = []; + private CrashDumpData $data; /** @var string */ - private $encodedData = ""; + private $encodedData; /** @var string */ private $path; @@ -118,9 +118,10 @@ class CrashDump{ throw new \RuntimeException("Could not create Crash Dump"); } $this->fp = $fp; - $this->data["format_version"] = self::FORMAT_VERSION; - $this->data["time"] = $this->time; - $this->data["uptime"] = $this->time - $this->server->getStartTime(); + $this->data = new CrashDumpData(); + $this->data->format_version = self::FORMAT_VERSION; + $this->data->time = $this->time; + $this->data->uptime = $this->time - $this->server->getStartTime(); $this->addLine($this->server->getName() . " Crash Dump " . date("D M j H:i:s T Y", (int) $this->time)); $this->addLine(); $this->baseCrash(); @@ -142,11 +143,7 @@ class CrashDump{ return $this->encodedData; } - /** - * @return mixed[] - * @phpstan-return array - */ - public function getData() : array{ + public function getData() : CrashDumpData{ return $this->data; } @@ -173,22 +170,21 @@ class CrashDump{ $plugins = $this->pluginManager->getPlugins(); $this->addLine(); $this->addLine("Loaded plugins:"); - $this->data["plugins"] = []; ksort($plugins, SORT_STRING); foreach($plugins as $p){ $d = $p->getDescription(); - $this->data["plugins"][$d->getName()] = [ - "name" => $d->getName(), - "version" => $d->getVersion(), - "authors" => $d->getAuthors(), - "api" => $d->getCompatibleApis(), - "enabled" => $p->isEnabled(), - "depends" => $d->getDepend(), - "softDepends" => $d->getSoftDepend(), - "main" => $d->getMain(), - "load" => mb_strtoupper($d->getOrder()->name()), - "website" => $d->getWebsite() - ]; + $this->data->plugins[$d->getName()] = new CrashDumpDataPluginEntry( + name: $d->getName(), + version: $d->getVersion(), + authors: $d->getAuthors(), + api: $d->getCompatibleApis(), + enabled: $p->isEnabled(), + depends: $d->getDepend(), + softDepends: $d->getSoftDepend(), + main: $d->getMain(), + load: mb_strtoupper($d->getOrder()->name()), + website: $d->getWebsite() + ); $this->addLine($d->getName() . " " . $d->getVersion() . " by " . implode(", ", $d->getAuthors()) . " for API(s) " . implode(", ", $d->getCompatibleApis())); } } @@ -198,32 +194,26 @@ class CrashDump{ global $argv; if($this->server->getConfigGroup()->getPropertyBool("auto-report.send-settings", true)){ - $this->data["parameters"] = (array) $argv; + $this->data->parameters = (array) $argv; if(($serverDotProperties = @file_get_contents(Path::join($this->server->getDataPath(), "server.properties"))) !== false){ - $this->data["server.properties"] = preg_replace("#^rcon\\.password=(.*)$#m", "rcon.password=******", $serverDotProperties); - }else{ - $this->data["server.properties"] = $serverDotProperties; + $this->data->serverDotProperties = preg_replace("#^rcon\\.password=(.*)$#m", "rcon.password=******", $serverDotProperties) ?? throw new AssumptionFailedError("Pattern is valid"); } if(($pocketmineDotYml = @file_get_contents(Path::join($this->server->getDataPath(), "pocketmine.yml"))) !== false){ - $this->data["pocketmine.yml"] = $pocketmineDotYml; - }else{ - $this->data["pocketmine.yml"] = ""; + $this->data->pocketmineDotYml = $pocketmineDotYml; } - }else{ - $this->data["pocketmine.yml"] = ""; - $this->data["server.properties"] = ""; - $this->data["parameters"] = []; } $extensions = []; foreach(get_loaded_extensions() as $ext){ - $extensions[$ext] = phpversion($ext); + $version = phpversion($ext); + if($version === false) throw new AssumptionFailedError(); + $extensions[$ext] = $version; } - $this->data["extensions"] = $extensions; + $this->data->extensions = $extensions; if($this->server->getConfigGroup()->getPropertyBool("auto-report.send-phpinfo", true)){ ob_start(); phpinfo(); - $this->data["phpinfo"] = ob_get_contents(); + $this->data->phpinfo = ob_get_contents(); // @phpstan-ignore-line ob_end_clean(); } } @@ -255,18 +245,18 @@ class CrashDump{ if(isset($lastError["trace"])){ $lastError["trace"] = Utils::printableTrace($lastError["trace"]); } - $this->data["lastError"] = $lastError; + $this->data->lastError = $lastError; } - $this->data["error"] = $error; - unset($this->data["error"]["fullFile"]); - unset($this->data["error"]["trace"]); + $this->data->error = $error; + unset($this->data->error["fullFile"]); + unset($this->data->error["trace"]); $this->addLine("Error: " . $error["message"]); $this->addLine("File: " . $error["file"]); $this->addLine("Line: " . $error["line"]); $this->addLine("Type: " . $error["type"]); - $this->data["plugin_involvement"] = self::PLUGIN_INVOLVEMENT_NONE; + $this->data->plugin_involvement = self::PLUGIN_INVOLVEMENT_NONE; if(!$this->determinePluginFromFile($error["fullFile"], true)){ //fatal errors won't leave any stack trace foreach($error["trace"] as $frame){ if(!isset($frame["file"])){ @@ -280,21 +270,20 @@ class CrashDump{ $this->addLine(); $this->addLine("Code:"); - $this->data["code"] = []; if($this->server->getConfigGroup()->getPropertyBool("auto-report.send-code", true) and file_exists($error["fullFile"])){ $file = @file($error["fullFile"], FILE_IGNORE_NEW_LINES); if($file !== false){ for($l = max(0, $error["line"] - 10); $l < $error["line"] + 10 and isset($file[$l]); ++$l){ $this->addLine("[" . ($l + 1) . "] " . $file[$l]); - $this->data["code"][$l + 1] = $file[$l]; + $this->data->code[$l + 1] = $file[$l]; } } } $this->addLine(); $this->addLine("Backtrace:"); - foreach(($this->data["trace"] = Utils::printableTrace($error["trace"])) as $line){ + foreach(($this->data->trace = Utils::printableTrace($error["trace"])) as $line){ $this->addLine($line); } $this->addLine(); @@ -306,10 +295,10 @@ class CrashDump{ $this->addLine(); if($crashFrame){ $this->addLine("THIS CRASH WAS CAUSED BY A PLUGIN"); - $this->data["plugin_involvement"] = self::PLUGIN_INVOLVEMENT_DIRECT; + $this->data->plugin_involvement = self::PLUGIN_INVOLVEMENT_DIRECT; }else{ $this->addLine("A PLUGIN WAS INVOLVED IN THIS CRASH"); - $this->data["plugin_involvement"] = self::PLUGIN_INVOLVEMENT_INDIRECT; + $this->data->plugin_involvement = self::PLUGIN_INVOLVEMENT_INDIRECT; } if(file_exists($filePath)){ @@ -319,7 +308,7 @@ class CrashDump{ foreach($this->server->getPluginManager()->getPlugins() as $plugin){ $filePath = Filesystem::cleanPath($file->getValue($plugin)); if(strpos($frameCleanPath, $filePath) === 0){ - $this->data["plugin"] = $plugin->getName(); + $this->data->plugin = $plugin->getName(); $this->addLine("BAD PLUGIN: " . $plugin->getDescription()->getFullName()); break; } @@ -341,19 +330,20 @@ class CrashDump{ ); } - $this->data["general"] = []; - $this->data["general"]["name"] = $this->server->getName(); - $this->data["general"]["base_version"] = VersionInfo::BASE_VERSION; - $this->data["general"]["build"] = VersionInfo::BUILD_NUMBER; - $this->data["general"]["is_dev"] = VersionInfo::IS_DEVELOPMENT_BUILD; - $this->data["general"]["protocol"] = ProtocolInfo::CURRENT_PROTOCOL; - $this->data["general"]["git"] = VersionInfo::GIT_HASH(); - $this->data["general"]["uname"] = php_uname("a"); - $this->data["general"]["php"] = phpversion(); - $this->data["general"]["zend"] = zend_version(); - $this->data["general"]["php_os"] = PHP_OS; - $this->data["general"]["os"] = Utils::getOS(); - $this->data["general"]["composer_libraries"] = $composerLibraries; + $this->data->general = new CrashDumpDataGeneral( + name: $this->server->getName(), + base_version: VersionInfo::BASE_VERSION, + build: VersionInfo::BUILD_NUMBER, + is_dev: VersionInfo::IS_DEVELOPMENT_BUILD, + protocol: ProtocolInfo::CURRENT_PROTOCOL, + git: VersionInfo::GIT_HASH(), + uname: php_uname("a"), + php: PHP_VERSION, + zend: zend_version(), + php_os: PHP_OS, + os: Utils::getOS(), + composer_libraries: $composerLibraries, + ); $this->addLine($this->server->getName() . " version: " . $version->getFullVersion(true) . " [Protocol " . ProtocolInfo::CURRENT_PROTOCOL . "]"); $this->addLine("Git commit: " . VersionInfo::GIT_HASH()); $this->addLine("uname -a: " . php_uname("a")); diff --git a/src/Server.php b/src/Server.php index 753556ff87..30fba8f258 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1504,8 +1504,8 @@ class Server{ } @touch($stamp); //update file timestamp - $plugin = $dump->getData()["plugin"]; - if(is_string($plugin)){ + $plugin = $dump->getData()->plugin; + if($plugin !== ""){ $p = $this->pluginManager->getPlugin($plugin); if($p instanceof Plugin and !($p->getPluginLoader() instanceof PharPluginLoader)){ $this->logger->debug("Not sending crashdump due to caused by non-phar plugin"); @@ -1513,7 +1513,7 @@ class Server{ } } - if($dump->getData()["error"]["type"] === \ParseError::class){ + if($dump->getData()->error["type"] === \ParseError::class){ $report = false; } diff --git a/src/crash/CrashDumpData.php b/src/crash/CrashDumpData.php new file mode 100644 index 0000000000..a3f13f2cac --- /dev/null +++ b/src/crash/CrashDumpData.php @@ -0,0 +1,84 @@ + + */ + public array $plugins = []; + + /** @var string[] */ + public array $parameters = []; + + public string $serverDotProperties = ""; + + public string $pocketmineDotYml = ""; + + /** + * @var string[] + * @phpstan-var array + */ + public array $extensions = []; + + public string $phpinfo = ""; + + public CrashDumpDataGeneral $general; + + /** + * @return mixed[] + */ + public function jsonSerialize() : array{ + $result = (array) $this; + unset($result["serverDotProperties"]); + unset($result["pocketmineDotYml"]); + $result["pocketmine.yml"] = $this->pocketmineDotYml; + $result["server.properties"] = $this->serverDotProperties; + return $result; + } +} \ No newline at end of file diff --git a/src/crash/CrashDumpDataGeneral.php b/src/crash/CrashDumpDataGeneral.php new file mode 100644 index 0000000000..33e41ce014 --- /dev/null +++ b/src/crash/CrashDumpDataGeneral.php @@ -0,0 +1,46 @@ + $composer_libraries + */ + public function __construct( + public string $name, + public string $base_version, + public int $build, + public bool $is_dev, + public int $protocol, + public string $git, + public string $uname, + public string $php, + public string $zend, + public string $php_os, + public string $os, + public array $composer_libraries, + ){} +} \ No newline at end of file diff --git a/src/crash/CrashDumpDataPluginEntry.php b/src/crash/CrashDumpDataPluginEntry.php new file mode 100644 index 0000000000..21139f4316 --- /dev/null +++ b/src/crash/CrashDumpDataPluginEntry.php @@ -0,0 +1,45 @@ + Date: Thu, 4 Nov 2021 19:18:29 +0000 Subject: [PATCH 3125/3224] Regenerate PHPStan bugs baseline --- tests/phpstan/configs/phpstan-bugs.neon | 52 +------------------------ 1 file changed, 1 insertion(+), 51 deletions(-) diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 5fc2c433a4..b6b9288700 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -1,57 +1,7 @@ parameters: ignoreErrors: - - message: "#^Cannot access offset 'base_version' on mixed\\.$#" - count: 1 - path: ../../../src/CrashDump.php - - - - message: "#^Cannot access offset 'build' on mixed\\.$#" - count: 1 - path: ../../../src/CrashDump.php - - - - message: "#^Cannot access offset 'composer_libraries' on mixed\\.$#" - count: 1 - path: ../../../src/CrashDump.php - - - - message: "#^Cannot access offset 'git' on mixed\\.$#" - count: 1 - path: ../../../src/CrashDump.php - - - - message: "#^Cannot access offset 'is_dev' on mixed\\.$#" - count: 1 - path: ../../../src/CrashDump.php - - - - message: "#^Cannot access offset 'os' on mixed\\.$#" - count: 1 - path: ../../../src/CrashDump.php - - - - message: "#^Cannot access offset 'php' on mixed\\.$#" - count: 1 - path: ../../../src/CrashDump.php - - - - message: "#^Cannot access offset 'php_os' on mixed\\.$#" - count: 1 - path: ../../../src/CrashDump.php - - - - message: "#^Cannot access offset 'protocol' on mixed\\.$#" - count: 1 - path: ../../../src/CrashDump.php - - - - message: "#^Cannot access offset 'uname' on mixed\\.$#" - count: 1 - path: ../../../src/CrashDump.php - - - - message: "#^Cannot access offset 'zend' on mixed\\.$#" + message: "#^Property pocketmine\\\\crash\\\\CrashDumpData\\:\\:\\$extensions \\(array\\\\) does not accept array\\\\.$#" count: 1 path: ../../../src/CrashDump.php From 15fca84f3b76699e2915a509048b0023e38930c1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Nov 2021 19:22:49 +0000 Subject: [PATCH 3126/3224] remove some PHPStan error patterns --- tests/phpstan/configs/actual-problems.neon | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/tests/phpstan/configs/actual-problems.neon b/tests/phpstan/configs/actual-problems.neon index fe984f0209..5c1237f805 100644 --- a/tests/phpstan/configs/actual-problems.neon +++ b/tests/phpstan/configs/actual-problems.neon @@ -20,16 +20,6 @@ parameters: count: 1 path: ../../../build/server-phar.php - - - message: "#^Cannot access offset \\(float\\|int\\) on mixed\\.$#" - count: 1 - path: ../../../src/CrashDump.php - - - - message: "#^Cannot access offset string on mixed\\.$#" - count: 1 - path: ../../../src/CrashDump.php - - message: "#^Parameter \\#1 \\$path of static method pocketmine\\\\utils\\\\Filesystem\\:\\:cleanPath\\(\\) expects string, mixed given\\.$#" count: 1 @@ -70,11 +60,6 @@ parameters: count: 3 path: ../../../src/PocketMine.php - - - message: "#^Cannot access offset 'type' on mixed\\.$#" - count: 1 - path: ../../../src/Server.php - - message: "#^Cannot cast mixed to string\\.$#" count: 1 From 84f8b3eb2dbe9c4e8b7659d7b1001e829579b21c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Nov 2021 19:23:45 +0000 Subject: [PATCH 3127/3224] Move CrashDump to pocketmine\crash namespace --- src/Server.php | 1 + src/{ => crash}/CrashDump.php | 7 +++---- tests/phpstan/configs/actual-problems.neon | 10 +++++----- tests/phpstan/configs/phpstan-bugs.neon | 10 +++++----- 4 files changed, 14 insertions(+), 14 deletions(-) rename src/{ => crash}/CrashDump.php (98%) diff --git a/src/Server.php b/src/Server.php index 30fba8f258..731860d4a4 100644 --- a/src/Server.php +++ b/src/Server.php @@ -34,6 +34,7 @@ use pocketmine\console\ConsoleCommandSender; use pocketmine\console\ConsoleReaderThread; use pocketmine\crafting\CraftingManager; use pocketmine\crafting\CraftingManagerFromDataHelper; +use pocketmine\crash\CrashDump; use pocketmine\data\java\GameModeIdMap; use pocketmine\entity\EntityDataHelper; use pocketmine\entity\Location; diff --git a/src/CrashDump.php b/src/crash/CrashDump.php similarity index 98% rename from src/CrashDump.php rename to src/crash/CrashDump.php index b18d09021e..1d595402e4 100644 --- a/src/CrashDump.php +++ b/src/crash/CrashDump.php @@ -21,19 +21,18 @@ declare(strict_types=1); -namespace pocketmine; +namespace pocketmine\crash; use Composer\InstalledVersions; -use pocketmine\crash\CrashDumpData; -use pocketmine\crash\CrashDumpDataGeneral; -use pocketmine\crash\CrashDumpDataPluginEntry; use pocketmine\errorhandler\ErrorTypeToStringMap; use pocketmine\network\mcpe\protocol\ProtocolInfo; use pocketmine\plugin\PluginBase; use pocketmine\plugin\PluginManager; +use pocketmine\Server; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Filesystem; use pocketmine\utils\Utils; +use pocketmine\VersionInfo; use Webmozart\PathUtil\Path; use function base64_encode; use function date; diff --git a/tests/phpstan/configs/actual-problems.neon b/tests/phpstan/configs/actual-problems.neon index 5c1237f805..badcc3e0ef 100644 --- a/tests/phpstan/configs/actual-problems.neon +++ b/tests/phpstan/configs/actual-problems.neon @@ -20,11 +20,6 @@ parameters: count: 1 path: ../../../build/server-phar.php - - - message: "#^Parameter \\#1 \\$path of static method pocketmine\\\\utils\\\\Filesystem\\:\\:cleanPath\\(\\) expects string, mixed given\\.$#" - count: 1 - path: ../../../src/CrashDump.php - - message: "#^Parameter \\#1 \\$stream of function fclose expects resource, resource\\|false given\\.$#" count: 1 @@ -530,6 +525,11 @@ parameters: count: 1 path: ../../../src/crafting/CraftingManagerFromDataHelper.php + - + message: "#^Parameter \\#1 \\$path of static method pocketmine\\\\utils\\\\Filesystem\\:\\:cleanPath\\(\\) expects string, mixed given\\.$#" + count: 1 + path: ../../../src/crash/CrashDump.php + - message: "#^Parameter \\#1 \\$json of function json_decode expects string, string\\|false given\\.$#" count: 1 diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index b6b9288700..0a580dcf09 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -1,10 +1,5 @@ parameters: ignoreErrors: - - - message: "#^Property pocketmine\\\\crash\\\\CrashDumpData\\:\\:\\$extensions \\(array\\\\) does not accept array\\\\.$#" - count: 1 - path: ../../../src/CrashDump.php - - message: "#^Instanceof between pocketmine\\\\block\\\\utils\\\\BannerPatternLayer and pocketmine\\\\block\\\\utils\\\\BannerPatternLayer will always evaluate to true\\.$#" count: 1 @@ -25,6 +20,11 @@ parameters: count: 1 path: ../../../src/crafting/CraftingManager.php + - + message: "#^Property pocketmine\\\\crash\\\\CrashDumpData\\:\\:\\$extensions \\(array\\\\) does not accept array\\\\.$#" + count: 1 + path: ../../../src/crash/CrashDump.php + - message: "#^Call to function assert\\(\\) with false and 'unknown hit type' will always evaluate to false\\.$#" count: 1 From 4c3a5fdd731b8df37620ae19172654b4855a9636 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Nov 2021 19:28:52 +0000 Subject: [PATCH 3128/3224] Clean PHPStan baselines from 1.0.2 --- tests/phpstan/configs/phpstan-bugs.neon | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 0a580dcf09..8baae94f11 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -30,16 +30,6 @@ parameters: count: 1 path: ../../../src/entity/projectile/Projectile.php - - - message: "#^Parameter \\#1 \\$array of function array_values expects array, array given\\.$#" - count: 1 - path: ../../../src/plugin/PluginDescription.php - - - - message: "#^Parameter \\#2 \\$array of function array_map expects array, array given\\.$#" - count: 3 - path: ../../../src/plugin/PluginDescription.php - - message: "#^Dead catch \\- RuntimeException is never thrown in the try block\\.$#" count: 1 From 8abc952c74da426257ef4fff25be1b72ffeb1eb4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Nov 2021 19:38:40 +0000 Subject: [PATCH 3129/3224] simulate-chunk-selector: do not reallocate colours on every frame --- tools/simulate-chunk-selector.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/simulate-chunk-selector.php b/tools/simulate-chunk-selector.php index 9ae7a11619..b4af186e26 100644 --- a/tools/simulate-chunk-selector.php +++ b/tools/simulate-chunk-selector.php @@ -57,16 +57,16 @@ function render(int $radius, int $baseX, int $baseZ, int $chunksPerStep, int $sc $middleOffsetX = $scale * ($radius + $offsetX); $middleOffsetZ = $scale * ($radius + $offsetZ); + $black = imagecolorallocate($image, 0, 0, 0); + $yellow = imagecolorallocate($image, 255, 255, 51); + $red = imagecolorallocate($image, 255, 0, 0); + if($black === false || $yellow === false || $red === false) throw new AssumptionFailedError(); + $frame = 0; $seen = []; while($iterator->valid()){ $frame++; - $black = imagecolorallocate($image, 0, 0, 0); - $yellow = imagecolorallocate($image, 255, 255, 51); - $red = imagecolorallocate($image, 255, 0, 0); - if($black === false || $yellow === false || $red === false) throw new AssumptionFailedError(); - for($i = 0; $i < $chunksPerStep; ++$i){ $chunkHash = $iterator->current(); if(!isset($seen[$chunkHash])){ From 579ef63663e71dbdd9a819bb6e82ea1e17a3f710 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Nov 2021 20:46:34 +0000 Subject: [PATCH 3130/3224] EntityDataHelper: accept FloatTag for vector3 as well as Double MCPE uses Float for entity positions. --- src/entity/EntityDataHelper.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/entity/EntityDataHelper.php b/src/entity/EntityDataHelper.php index f58fef743d..2038f47d47 100644 --- a/src/entity/EntityDataHelper.php +++ b/src/entity/EntityDataHelper.php @@ -59,10 +59,10 @@ final class EntityDataHelper{ if($pos === null and $optional){ return new Vector3(0, 0, 0); } - if(!($pos instanceof ListTag) or $pos->getTagType() !== NBT::TAG_Double){ - throw new \UnexpectedValueException("'$tagName' should be a List"); + if(!($pos instanceof ListTag) or ($pos->getTagType() !== NBT::TAG_Double && $pos->getTagType() !== NBT::TAG_Float)){ + throw new \UnexpectedValueException("'$tagName' should be a List or List"); } - /** @var DoubleTag[] $values */ + /** @var DoubleTag[]|FloatTag[] $values */ $values = $pos->getValue(); if(count($values) !== 3){ throw new \UnexpectedValueException("Expected exactly 3 entries in '$tagName' tag"); From 5107d0df4e71d9cd5dd11516c6c0faf2186dcb52 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 5 Nov 2021 15:09:42 +0000 Subject: [PATCH 3131/3224] Player: cap maximum number of active generation requests this fixes the horrible spotty chunk loading seen in https://twitter.com/dktapps/status/1456397007946461190?s=20. In practice, this made chunks invisible on teleport for several tens of seconds after teleporting. Having a larger chunks-per-tick with large render distance compounded to worsen the problem. It wasn't really noticeable on small render distances, but very obvious on large ones with fast chunk sending and slow generation. This also fixes #4187 (at least to the extent that it works on PM3, anyway). --- src/player/Player.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index fdbb60391c..866cbb967f 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -195,6 +195,11 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ * @phpstan-var array */ protected array $usedChunks = []; + /** + * @var true[] + * @phpstan-var array + */ + private array $activeChunkGenerationRequests = []; /** * @var true[] chunkHash => dummy * @phpstan-var array @@ -643,6 +648,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } $this->getNetworkSession()->stopUsingChunk($x, $z); unset($this->usedChunks[$index]); + unset($this->activeChunkGenerationRequests[$index]); } $world->unregisterChunkLoader($this->chunkLoader, $x, $z); $world->unregisterChunkListener($this, $x, $z); @@ -680,7 +686,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $count = 0; $world = $this->getWorld(); foreach($this->loadQueue as $index => $distance){ - if($count >= $this->chunksPerTick){ + if($count >= $this->chunksPerTick || count($this->activeChunkGenerationRequests) >= $this->chunksPerTick){ break; } @@ -692,6 +698,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ ++$count; $this->usedChunks[$index] = UsedChunkStatus::REQUESTED_GENERATION(); + $this->activeChunkGenerationRequests[$index] = true; unset($this->loadQueue[$index]); $this->getWorld()->registerChunkLoader($this->chunkLoader, $X, $Z, true); $this->getWorld()->registerChunkListener($this, $X, $Z); @@ -707,6 +714,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ //multiple callbacks for this player. In that case, only the first one matters. return; } + unset($this->activeChunkGenerationRequests[$index]); $this->usedChunks[$index] = UsedChunkStatus::REQUESTED_SENDING(); $this->getNetworkSession()->startUsingChunk($X, $Z, function() use ($X, $Z, $index) : void{ From 0989c77037f87654382f209c709b4e17f82549a0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 5 Nov 2021 15:46:55 +0000 Subject: [PATCH 3132/3224] Player: check that horizontal distance travelled is > 0 before adding exhaustion, or triggering a new chunk order closes #4548 --- src/player/Player.php | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/player/Player.php b/src/player/Player.php index 866cbb967f..0a00b40104 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1186,16 +1186,18 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->lastLocation = $to; $this->broadcastMovement(); - $distance = sqrt((($from->x - $to->x) ** 2) + (($from->z - $to->z) ** 2)); - //TODO: check swimming (adds 0.015 exhaustion in MCPE) - if($this->isSprinting()){ - $this->hungerManager->exhaust(0.1 * $distance, PlayerExhaustEvent::CAUSE_SPRINTING); - }else{ - $this->hungerManager->exhaust(0.01 * $distance, PlayerExhaustEvent::CAUSE_WALKING); - } + $horizontalDistanceTravelled = sqrt((($from->x - $to->x) ** 2) + (($from->z - $to->z) ** 2)); + if($horizontalDistanceTravelled > 0){ + //TODO: check swimming (adds 0.015 exhaustion in MCPE) + if($this->isSprinting()){ + $this->hungerManager->exhaust(0.1 * $horizontalDistanceTravelled, PlayerExhaustEvent::CAUSE_SPRINTING); + }else{ + $this->hungerManager->exhaust(0.01 * $horizontalDistanceTravelled, PlayerExhaustEvent::CAUSE_WALKING); + } - if($this->nextChunkOrderRun > 20){ - $this->nextChunkOrderRun = 20; + if($this->nextChunkOrderRun > 20){ + $this->nextChunkOrderRun = 20; + } } } From 07b1cff30609e3e11360cdb4403d4757918559c7 Mon Sep 17 00:00:00 2001 From: Colin Date: Fri, 5 Nov 2021 17:15:55 +0100 Subject: [PATCH 3133/3224] Bonemeal is no longer consumed when cancelling plant growth events (#4551) --- src/block/Crops.php | 3 +-- src/block/Sapling.php | 11 +++++------ src/block/Sugarcane.php | 11 ++++++----- src/block/SweetBerryBush.php | 2 +- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/block/Crops.php b/src/block/Crops.php index 47cb338977..c7f201b41f 100644 --- a/src/block/Crops.php +++ b/src/block/Crops.php @@ -80,10 +80,9 @@ abstract class Crops extends Flowable{ $ev->call(); if(!$ev->isCancelled()){ $this->position->getWorld()->setBlock($this->position, $ev->getNewState()); + $item->pop(); } - $item->pop(); - return true; } diff --git a/src/block/Sapling.php b/src/block/Sapling.php index d2ae0b5a7a..85e0924510 100644 --- a/src/block/Sapling.php +++ b/src/block/Sapling.php @@ -76,9 +76,7 @@ class Sapling extends Flowable{ } public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($item instanceof Fertilizer){ - $this->grow($player); - + if($item instanceof Fertilizer && $this->grow($player)){ $item->pop(); return true; @@ -108,19 +106,20 @@ class Sapling extends Flowable{ } } - private function grow(?Player $player) : void{ + private function grow(?Player $player) : bool{ $random = new Random(mt_rand()); $tree = TreeFactory::get($random, $this->treeType); $transaction = $tree?->getBlockTransaction($this->position->getWorld(), $this->position->getFloorX(), $this->position->getFloorY(), $this->position->getFloorZ(), $random); if($transaction === null){ - return; + return false; } $ev = new StructureGrowEvent($this, $transaction, $player); $ev->call(); if(!$ev->isCancelled()){ - $transaction->apply(); + return $transaction->apply(); } + return false; } public function getFuelTime() : int{ diff --git a/src/block/Sugarcane.php b/src/block/Sugarcane.php index eadf9c1ff0..90eef3d4be 100644 --- a/src/block/Sugarcane.php +++ b/src/block/Sugarcane.php @@ -48,7 +48,8 @@ class Sugarcane extends Flowable{ return 0b1111; } - private function grow() : void{ + private function grow() : bool{ + $grew = false; for($y = 1; $y < 3; ++$y){ if(!$this->position->getWorld()->isInWorld($this->position->x, $this->position->y + $y, $this->position->z)){ break; @@ -61,12 +62,14 @@ class Sugarcane extends Flowable{ break; } $this->position->getWorld()->setBlock($b->position, $ev->getNewState()); + $grew = true; }else{ break; } } $this->age = 0; $this->position->getWorld()->setBlock($this->position, $this); + return $grew; } public function getAge() : int{ return $this->age; } @@ -82,12 +85,10 @@ class Sugarcane extends Flowable{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof Fertilizer){ - if(!$this->getSide(Facing::DOWN)->isSameType($this)){ - $this->grow(); + if(!$this->getSide(Facing::DOWN)->isSameType($this) && $this->grow()){ + $item->pop(); } - $item->pop(); - return true; } diff --git a/src/block/SweetBerryBush.php b/src/block/SweetBerryBush.php index efb35845e1..4412d0cff8 100644 --- a/src/block/SweetBerryBush.php +++ b/src/block/SweetBerryBush.php @@ -99,9 +99,9 @@ class SweetBerryBush extends Flowable{ if(!$ev->isCancelled()){ $this->position->getWorld()->setBlock($this->position, $ev->getNewState()); + $item->pop(); } - $item->pop(); }elseif(($dropAmount = $this->getBerryDropAmount()) > 0){ $this->position->getWorld()->setBlock($this->position, $this->setAge(self::STAGE_BUSH_NO_BERRIES)); $this->position->getWorld()->dropItem($this->position, $this->asItem()->setCount($dropAmount)); From dbf9a331600b1e0daa90d2ee05d54415b2939e22 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Nov 2021 00:06:08 +0000 Subject: [PATCH 3134/3224] ChunkSelector: Improve algorithm to send chunks in proper circles, instead of squares this ensures that the edge of loaded terain is always the same distance away in any direction. This also means that when flying parallel to X or Z axes, you now have about 12% more chunks directly in front of you, instead of to your left and right, which gives the impression that chunks are loading faster (they aren't, they are just being ordered in a more sensible way). --- src/player/ChunkSelector.php | 59 +++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/src/player/ChunkSelector.php b/src/player/ChunkSelector.php index 31bbf08e45..3ba3142159 100644 --- a/src/player/ChunkSelector.php +++ b/src/player/ChunkSelector.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\player; use pocketmine\world\World; +use const M_SQRT2; //TODO: turn this into an interface? final class ChunkSelector{ @@ -33,34 +34,44 @@ final class ChunkSelector{ * @phpstan-return \Generator */ public function selectChunks(int $radius, int $centerX, int $centerZ) : \Generator{ - $radiusSquared = $radius ** 2; + for($subRadius = 0; $subRadius < $radius; $subRadius++){ + $subRadiusSquared = $subRadius ** 2; + $nextSubRadiusSquared = ($subRadius + 1) ** 2; + $minX = (int) ($subRadius / M_SQRT2); - for($x = 0; $x < $radius; ++$x){ - for($z = 0; $z <= $x; ++$z){ - if(($x ** 2 + $z ** 2) > $radiusSquared){ - break; //skip to next band - } + $lastZ = 0; - //If the chunk is in the radius, others at the same offsets in different quadrants are also guaranteed to be. + for($x = $subRadius; $x >= $minX; --$x){ + for($z = $lastZ; $z <= $x; ++$z){ + $distanceSquared = ($x ** 2 + $z ** 2); + if($distanceSquared < $subRadiusSquared){ + continue; + }elseif($distanceSquared >= $nextSubRadiusSquared){ + break; //skip to next X + } - /* Top right quadrant */ - yield World::chunkHash($centerX + $x, $centerZ + $z); - /* Top left quadrant */ - yield World::chunkHash($centerX - $x - 1, $centerZ + $z); - /* Bottom right quadrant */ - yield World::chunkHash($centerX + $x, $centerZ - $z - 1); - /* Bottom left quadrant */ - yield World::chunkHash($centerX - $x - 1, $centerZ - $z - 1); + $lastZ = $z; + //If the chunk is in the radius, others at the same offsets in different quadrants are also guaranteed to be. - if($x !== $z){ - /* Top right quadrant mirror */ - yield World::chunkHash($centerX + $z, $centerZ + $x); - /* Top left quadrant mirror */ - yield World::chunkHash($centerX - $z - 1, $centerZ + $x); - /* Bottom right quadrant mirror */ - yield World::chunkHash($centerX + $z, $centerZ - $x - 1); - /* Bottom left quadrant mirror */ - yield World::chunkHash($centerX - $z - 1, $centerZ - $x - 1); + /* Top right quadrant */ + yield World::chunkHash($centerX + $x, $centerZ + $z); + /* Top left quadrant */ + yield World::chunkHash($centerX - $x - 1, $centerZ + $z); + /* Bottom right quadrant */ + yield World::chunkHash($centerX + $x, $centerZ - $z - 1); + /* Bottom left quadrant */ + yield World::chunkHash($centerX - $x - 1, $centerZ - $z - 1); + + if($x !== $z){ + /* Top right quadrant mirror */ + yield World::chunkHash($centerX + $z, $centerZ + $x); + /* Top left quadrant mirror */ + yield World::chunkHash($centerX - $z - 1, $centerZ + $x); + /* Bottom right quadrant mirror */ + yield World::chunkHash($centerX + $z, $centerZ - $x - 1); + /* Bottom left quadrant mirror */ + yield World::chunkHash($centerX - $z - 1, $centerZ - $x - 1); + } } } } From 3c754b079c440764a7ae59046c47764f4c6b914f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Nov 2021 00:32:58 +0000 Subject: [PATCH 3135/3224] Move resources/locale to Composer dependency all remaining submodules are now non-essential to running a server. They are also versioned and updates can be done automatically using 'composer update'. Finally, we can also put an end to the issue of translations being rendered incorrectly or being missing due to outdated submodules. --- .gitmodules | 3 --- build/generate-known-translation-apis.php | 2 +- composer.json | 1 + composer.lock | 25 ++++++++++++++++++++++- resources/locale | 1 - src/CoreConstants.php | 1 + src/lang/Language.php | 4 ++-- 7 files changed, 29 insertions(+), 8 deletions(-) delete mode 160000 resources/locale diff --git a/.gitmodules b/.gitmodules index 71a80c00a4..0b2349472d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "resources/locale"] - path = resources/locale - url = https://github.com/pmmp/Language.git [submodule "tests/plugins/DevTools"] path = tests/plugins/DevTools url = https://github.com/pmmp/DevTools.git diff --git a/build/generate-known-translation-apis.php b/build/generate-known-translation-apis.php index 04dbe37a6e..b2703b5136 100644 --- a/build/generate-known-translation-apis.php +++ b/build/generate-known-translation-apis.php @@ -172,7 +172,7 @@ HEADER; echo "Done generating KnownTranslationFactory.\n"; } -$lang = parse_ini_file(Path::join(\pocketmine\RESOURCE_PATH, "locale", "eng.ini"), false, INI_SCANNER_RAW); +$lang = parse_ini_file(Path::join(\pocketmine\LOCALE_DATA_PATH, "eng.ini"), false, INI_SCANNER_RAW); if($lang === false){ fwrite(STDERR, "Missing language files!\n"); exit(1); diff --git a/composer.json b/composer.json index 9c9898693e..978a881c4e 100644 --- a/composer.json +++ b/composer.json @@ -41,6 +41,7 @@ "pocketmine/classloader": "^0.2.0", "pocketmine/color": "^0.2.0", "pocketmine/errorhandler": "^0.3.0", + "pocketmine/locale-data": "^1.0.3", "pocketmine/log": "^0.4.0", "pocketmine/log-pthreads": "^0.4.0", "pocketmine/math": "^0.4.0", diff --git a/composer.lock b/composer.lock index c6676bc5bd..0c3b4eb906 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c0368348f30e5309e979840d1cfad409", + "content-hash": "e36db7fb94bd79034dcc599c3029a621", "packages": [ { "name": "adhocore/json-comment", @@ -531,6 +531,29 @@ }, "time": "2021-02-12T18:56:22+00:00" }, + { + "name": "pocketmine/locale-data", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/pmmp/Language.git", + "reference": "7342b4eb593036c739e7f0c0ed95299ada69ff19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pmmp/Language/zipball/7342b4eb593036c739e7f0c0ed95299ada69ff19", + "reference": "7342b4eb593036c739e7f0c0ed95299ada69ff19", + "shasum": "" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "description": "Language resources used by PocketMine-MP", + "support": { + "issues": "https://github.com/pmmp/Language/issues", + "source": "https://github.com/pmmp/Language/tree/1.0.3" + }, + "time": "2021-11-06T00:27:03+00:00" + }, { "name": "pocketmine/log", "version": "0.4.0", diff --git a/resources/locale b/resources/locale deleted file mode 160000 index f9076e4a6e..0000000000 --- a/resources/locale +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f9076e4a6e3049aeaf7abd30d39a482a1392eafe diff --git a/src/CoreConstants.php b/src/CoreConstants.php index 91b9b95b95..46e00a2a32 100644 --- a/src/CoreConstants.php +++ b/src/CoreConstants.php @@ -36,4 +36,5 @@ define('pocketmine\_CORE_CONSTANTS_INCLUDED', true); define('pocketmine\PATH', dirname(__DIR__) . '/'); define('pocketmine\RESOURCE_PATH', dirname(__DIR__) . '/resources/'); define('pocketmine\BEDROCK_DATA_PATH', dirname(__DIR__) . '/vendor/pocketmine/bedrock-data/'); +define('pocketmine\LOCALE_DATA_PATH', dirname(__DIR__) . '/vendor/pocketmine/locale-data/'); define('pocketmine\COMPOSER_AUTOLOADER_PATH', dirname(__DIR__) . '/vendor/autoload.php'); diff --git a/src/lang/Language.php b/src/lang/Language.php index f3e9667049..33ad938889 100644 --- a/src/lang/Language.php +++ b/src/lang/Language.php @@ -52,7 +52,7 @@ class Language{ */ public static function getLanguageList(string $path = "") : array{ if($path === ""){ - $path = Path::join(\pocketmine\RESOURCE_PATH, "locale"); + $path = \pocketmine\LOCALE_DATA_PATH; } if(is_dir($path)){ @@ -101,7 +101,7 @@ class Language{ $this->langName = strtolower($lang); if($path === null){ - $path = Path::join(\pocketmine\RESOURCE_PATH, "locale"); + $path = \pocketmine\LOCALE_DATA_PATH; } $this->lang = self::loadLang($path, $this->langName); From 566c57bcd388d3c94b9ccbbbf165709318b78b90 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Nov 2021 00:35:39 +0000 Subject: [PATCH 3136/3224] we no longer need submodules for these jobs --- .github/workflows/main.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index aa42903b78..e3f2d182e4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -91,8 +91,6 @@ jobs: steps: - uses: actions/checkout@v2 - with: - submodules: true - name: Restore PHP build cache id: php-build-cache @@ -195,8 +193,6 @@ jobs: steps: - uses: actions/checkout@v2 - with: - submodules: true - name: Restore PHP build cache id: php-build-cache From 6cd272c9e17680439ca8886b594046154f043877 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Nov 2021 00:55:13 +0000 Subject: [PATCH 3137/3224] Update transient composer dependencies --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 0c3b4eb906..7b021777bc 100644 --- a/composer.lock +++ b/composer.lock @@ -1503,16 +1503,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.13.0", + "version": "v4.13.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "50953a2691a922aa1769461637869a0a2faa3f53" + "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/50953a2691a922aa1769461637869a0a2faa3f53", - "reference": "50953a2691a922aa1769461637869a0a2faa3f53", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/63a79e8daa781cac14e5195e63ed8ae231dd10fd", + "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd", "shasum": "" }, "require": { @@ -1553,9 +1553,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.1" }, - "time": "2021-09-20T12:20:58+00:00" + "time": "2021-11-03T20:52:16+00:00" }, { "name": "phar-io/manifest", From 640e88009b6b66d9822c0da1eb6718375720b0c0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Nov 2021 00:57:37 +0000 Subject: [PATCH 3138/3224] Player: fixed a mistake in generation rate limit we don't want to allow sending further chunks when we haven't generated near ones, because we won't be able to see them anyway, and we might end up not needing them. This now fully matches the results of PM3. --- src/player/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index 0a00b40104..4d46cfac60 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -686,7 +686,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $count = 0; $world = $this->getWorld(); foreach($this->loadQueue as $index => $distance){ - if($count >= $this->chunksPerTick || count($this->activeChunkGenerationRequests) >= $this->chunksPerTick){ + if($count >= $this->chunksPerTick - count($this->activeChunkGenerationRequests)){ break; } From b8523f7a18ed83888e8f66c659bc77eea6985b63 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Nov 2021 01:00:35 +0000 Subject: [PATCH 3139/3224] Player: fix the fix which just degraded performance if a chunk was requested for generation, count++ and count(activeRequests)++, which means that we would only get to submit half as many generation requests as we're allowed to. Calculate the limit at the start and remember it instead. --- src/player/Player.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/player/Player.php b/src/player/Player.php index 4d46cfac60..1839adc099 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -685,8 +685,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $count = 0; $world = $this->getWorld(); + + $limit = $this->chunksPerTick - count($this->activeChunkGenerationRequests); foreach($this->loadQueue as $index => $distance){ - if($count >= $this->chunksPerTick - count($this->activeChunkGenerationRequests)){ + if($count >= $limit){ break; } From 002feacf8e2ea9084bf3e13b42f5b2eaf2730116 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Nov 2021 01:16:58 +0000 Subject: [PATCH 3140/3224] Release 4.0.0-BETA11 --- changelogs/4.0.md | 27 +++++++++++++++++++++++++++ src/VersionInfo.php | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index 2ef72ea0be..9e9faad628 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1607,3 +1607,30 @@ Released 2nd November 2021. ## Fixes - Fixed an issue with BedrockData JSON minification which broke the release build of 4.0.0-BETA9. + +# 4.0.0-BETA11 +Released 6th November 2021. + +## General +- `resources/locale` submodule has been removed. Language files are now included via Composer dependency [`pocketmine/locale-data`](https://packagist.org/packages/pocketmine/locale-data). + - This means it's now possible to run a server from git sources without cloning submodules :) + - All remaining submodules (DevTools, build/php) are non-essential for building and running a server. +- Added a tool `tools/simulate-chunk-sending.php` to visualise the behaviour of `ChunkSelector`. + +## Fixes +- Fixed server crash on saving when player XP has reached int32 max (XP is now capped, similar to Java Edition). +- Fixed another edge case in chunk generation that led to assertion failures. +- Fixed server crash when finding a list of `TAG_Float` for entity positions instead of `TAG_Double`. +- Fixed fast eating when picking up items. +- Fixed terrain being invisible for a long time when teleporting into ungenerated terrain. +- Fixed weird chunk loading when teleporting into ungenerated terrain (sometimes farther chunks would render before closer ones, leaving holes in the map temporarily). +- Fixed players re-requesting chunks when turning their heads or jumping. +- Fixed bonemeal sometimes being consumed even when cancelling `BlockGrowEvent` and `StructureGrowEvent`. + +## API +### Event +- Added `PlayerEmoteEvent`. + +### Gameplay +- Chunks are now sent in proper circles. This improves the experience when flying quickly parallel to X or Z axis, since now more chunks in front of the player will load sooner. +- Added support for emotes. diff --git a/src/VersionInfo.php b/src/VersionInfo.php index f394d85d99..37435fb15a 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -30,7 +30,7 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; public const BASE_VERSION = "4.0.0-BETA11"; - public const IS_DEVELOPMENT_BUILD = true; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_NUMBER = 0; public const BUILD_CHANNEL = "beta"; From f81c55ce6c76972f7828f17a16ea68d7c8eb37c5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Nov 2021 01:17:03 +0000 Subject: [PATCH 3141/3224] 4.0.0-BETA12 is next --- src/VersionInfo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 37435fb15a..5216a66505 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -29,8 +29,8 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "4.0.0-BETA11"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "4.0.0-BETA12"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_NUMBER = 0; public const BUILD_CHANNEL = "beta"; From 4cb6c7dc1e8c34761929913d6c301e748a2c23b0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Nov 2021 16:32:19 +0000 Subject: [PATCH 3142/3224] PluginManager: fixed plugins being able to alter groups of other plugins' permissions this could happen if a plugin declared a permission already declared by another plugin, and then declared a different default for it (e.g. true instead of op). --- src/plugin/PluginManager.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 1b02e082ab..eb4ab55558 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -172,7 +172,9 @@ class PluginManager{ $everyoneRoot = $permManager->getPermission(DefaultPermissions::ROOT_USER); foreach($description->getPermissions() as $default => $perms){ foreach($perms as $perm){ - $permManager->addPermission($perm); + if(!$permManager->addPermission($perm)){ + continue; //TODO: this should be reported as an error and prevent the plugin from loading + } switch($default){ case PermissionParser::DEFAULT_TRUE: $everyoneRoot->addChild($perm->getName(), true); From d9d37f7fa6f4b7a0a7d7a7972f892beed061fa48 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Nov 2021 16:45:14 +0000 Subject: [PATCH 3143/3224] ResourcePacksPacketHandler: fixed a mistake from c773e43eda0da159b181ef1c79f29a6c8986e697 fixes #4557 Note: you may need to clear your local pack cache in order to get it working again. --- src/network/mcpe/handler/ResourcePacksPacketHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/mcpe/handler/ResourcePacksPacketHandler.php b/src/network/mcpe/handler/ResourcePacksPacketHandler.php index 8f93e25477..f82ed1232e 100644 --- a/src/network/mcpe/handler/ResourcePacksPacketHandler.php +++ b/src/network/mcpe/handler/ResourcePacksPacketHandler.php @@ -117,7 +117,7 @@ class ResourcePacksPacketHandler extends PacketHandler{ $pack->getPackSize(), $pack->getSha256(), false, - ResourcePackType::ADDON //TODO: this might be an addon (not behaviour pack), needed to properly support client-side custom items + ResourcePackType::RESOURCES //TODO: this might be an addon (not behaviour pack), needed to properly support client-side custom items )); } $this->session->getLogger()->debug("Player requested download of " . count($packet->packIds) . " resource packs"); From 6b316dc29abd418540ade8ee67f9329cf89004b2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 6 Nov 2021 17:05:37 +0000 Subject: [PATCH 3144/3224] PluginManager: Make declaration of duplicate permissions a load error --- composer.json | 2 +- composer.lock | 14 +++++++------- src/lang/KnownTranslationFactory.php | 6 ++++++ src/lang/KnownTranslationKeys.php | 1 + src/plugin/PluginManager.php | 15 ++++++++++++--- 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/composer.json b/composer.json index 978a881c4e..73e43f6bfe 100644 --- a/composer.json +++ b/composer.json @@ -41,7 +41,7 @@ "pocketmine/classloader": "^0.2.0", "pocketmine/color": "^0.2.0", "pocketmine/errorhandler": "^0.3.0", - "pocketmine/locale-data": "^1.0.3", + "pocketmine/locale-data": "^1.1.4", "pocketmine/log": "^0.4.0", "pocketmine/log-pthreads": "^0.4.0", "pocketmine/math": "^0.4.0", diff --git a/composer.lock b/composer.lock index 7b021777bc..0a6a2aa616 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e36db7fb94bd79034dcc599c3029a621", + "content-hash": "6de5c66b7a0f693fd30c701b0d0db3d1", "packages": [ { "name": "adhocore/json-comment", @@ -533,16 +533,16 @@ }, { "name": "pocketmine/locale-data", - "version": "1.0.3", + "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/pmmp/Language.git", - "reference": "7342b4eb593036c739e7f0c0ed95299ada69ff19" + "reference": "549f27f593b200d8b11ca05ffcd5a73e02a0d9fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Language/zipball/7342b4eb593036c739e7f0c0ed95299ada69ff19", - "reference": "7342b4eb593036c739e7f0c0ed95299ada69ff19", + "url": "https://api.github.com/repos/pmmp/Language/zipball/549f27f593b200d8b11ca05ffcd5a73e02a0d9fb", + "reference": "549f27f593b200d8b11ca05ffcd5a73e02a0d9fb", "shasum": "" }, "type": "library", @@ -550,9 +550,9 @@ "description": "Language resources used by PocketMine-MP", "support": { "issues": "https://github.com/pmmp/Language/issues", - "source": "https://github.com/pmmp/Language/tree/1.0.3" + "source": "https://github.com/pmmp/Language/tree/1.1.4" }, - "time": "2021-11-06T00:27:03+00:00" + "time": "2021-11-06T17:02:22+00:00" }, { "name": "pocketmine/log", diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index 04b644f831..7d36320c2a 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -1724,6 +1724,12 @@ final class KnownTranslationFactory{ ]); } + public static function pocketmine_plugin_duplicatePermissionError(Translatable|string $permissionName) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_DUPLICATEPERMISSIONERROR, [ + "permissionName" => $permissionName, + ]); + } + public static function pocketmine_plugin_emptyExtensionVersionConstraint(Translatable|string $constraintIndex, Translatable|string $extensionName) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_EMPTYEXTENSIONVERSIONCONSTRAINT, [ "constraintIndex" => $constraintIndex, diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index 2a609c8d86..7b77513dc2 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -361,6 +361,7 @@ final class KnownTranslationKeys{ public const POCKETMINE_PLUGIN_DISALLOWEDBYBLACKLIST = "pocketmine.plugin.disallowedByBlacklist"; public const POCKETMINE_PLUGIN_DISALLOWEDBYWHITELIST = "pocketmine.plugin.disallowedByWhitelist"; public const POCKETMINE_PLUGIN_DUPLICATEERROR = "pocketmine.plugin.duplicateError"; + public const POCKETMINE_PLUGIN_DUPLICATEPERMISSIONERROR = "pocketmine.plugin.duplicatePermissionError"; public const POCKETMINE_PLUGIN_EMPTYEXTENSIONVERSIONCONSTRAINT = "pocketmine.plugin.emptyExtensionVersionConstraint"; public const POCKETMINE_PLUGIN_ENABLE = "pocketmine.plugin.enable"; public const POCKETMINE_PLUGIN_EXTENSIONNOTLOADED = "pocketmine.plugin.extensionNotLoaded"; diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index eb4ab55558..46986946c6 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -168,13 +168,22 @@ class PluginManager{ } $permManager = PermissionManager::getInstance(); + foreach($description->getPermissions() as $permsGroup){ + foreach($permsGroup as $perm){ + if($permManager->getPermission($perm->getName()) !== null){ + $this->server->getLogger()->error($language->translate(KnownTranslationFactory::pocketmine_plugin_loadError( + $description->getName(), + KnownTranslationFactory::pocketmine_plugin_duplicatePermissionError($perm->getName()) + ))); + return null; + } + } + } $opRoot = $permManager->getPermission(DefaultPermissions::ROOT_OPERATOR); $everyoneRoot = $permManager->getPermission(DefaultPermissions::ROOT_USER); foreach($description->getPermissions() as $default => $perms){ foreach($perms as $perm){ - if(!$permManager->addPermission($perm)){ - continue; //TODO: this should be reported as an error and prevent the plugin from loading - } + $permManager->addPermission($perm); switch($default){ case PermissionParser::DEFAULT_TRUE: $everyoneRoot->addChild($perm->getName(), true); From 45edb946072e82bdd9d3821c4c3a2b106fa33e8a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 7 Nov 2021 16:20:07 +0000 Subject: [PATCH 3145/3224] Crafting tables now work the same way as anvils and enchanting tables Removing almost all special-case logic for crafting tables. --- src/block/CraftingTable.php | 4 +- .../inventory/CraftingTableInventory.php | 46 +++++++++++++++++++ src/crafting/CraftingGrid.php | 15 +----- src/inventory/PlayerCraftingInventory.php | 36 +++++++++++++++ src/network/mcpe/InventoryManager.php | 3 +- src/network/mcpe/convert/TypeConverter.php | 12 ++--- .../mcpe/handler/InGamePacketHandler.php | 21 --------- src/player/Player.php | 13 ++---- 8 files changed, 96 insertions(+), 54 deletions(-) create mode 100644 src/block/inventory/CraftingTableInventory.php create mode 100644 src/inventory/PlayerCraftingInventory.php diff --git a/src/block/CraftingTable.php b/src/block/CraftingTable.php index a3d1dc47fe..a35e13e5bd 100644 --- a/src/block/CraftingTable.php +++ b/src/block/CraftingTable.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\crafting\CraftingGrid; +use pocketmine\block\inventory\CraftingTableInventory; use pocketmine\item\Item; use pocketmine\math\Vector3; use pocketmine\player\Player; @@ -32,7 +32,7 @@ class CraftingTable extends Opaque{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player instanceof Player){ - $player->setCraftingGrid(new CraftingGrid($player, CraftingGrid::SIZE_BIG)); + $player->setCurrentWindow(new CraftingTableInventory($this->position)); } return true; diff --git a/src/block/inventory/CraftingTableInventory.php b/src/block/inventory/CraftingTableInventory.php new file mode 100644 index 0000000000..493e5dec03 --- /dev/null +++ b/src/block/inventory/CraftingTableInventory.php @@ -0,0 +1,46 @@ +holder = $holder; + parent::__construct(CraftingGrid::SIZE_BIG); + } + + public function onClose(Player $who) : void{ + parent::onClose($who); + + foreach($this->getContents() as $item){ + $who->dropItem($item); + } + $this->clearAll(); + } +} \ No newline at end of file diff --git a/src/crafting/CraftingGrid.php b/src/crafting/CraftingGrid.php index a8d4f6ebe8..eb3ea5f25e 100644 --- a/src/crafting/CraftingGrid.php +++ b/src/crafting/CraftingGrid.php @@ -25,17 +25,14 @@ namespace pocketmine\crafting; use pocketmine\inventory\SimpleInventory; use pocketmine\item\Item; -use pocketmine\player\Player; use function max; use function min; use const PHP_INT_MAX; -class CraftingGrid extends SimpleInventory{ +abstract class CraftingGrid extends SimpleInventory{ public const SIZE_SMALL = 2; public const SIZE_BIG = 3; - /** @var Player */ - protected $holder; /** @var int */ private $gridWidth; @@ -48,8 +45,7 @@ class CraftingGrid extends SimpleInventory{ /** @var int|null */ private $yLen; - public function __construct(Player $holder, int $gridWidth){ - $this->holder = $holder; + public function __construct(int $gridWidth){ $this->gridWidth = $gridWidth; parent::__construct($this->getGridWidth() ** 2); } @@ -63,13 +59,6 @@ class CraftingGrid extends SimpleInventory{ $this->seekRecipeBounds(); } - /** - * @return Player - */ - public function getHolder(){ - return $this->holder; - } - private function seekRecipeBounds() : void{ $minX = PHP_INT_MAX; $maxX = 0; diff --git a/src/inventory/PlayerCraftingInventory.php b/src/inventory/PlayerCraftingInventory.php new file mode 100644 index 0000000000..300346476d --- /dev/null +++ b/src/inventory/PlayerCraftingInventory.php @@ -0,0 +1,36 @@ +holder; } +} \ No newline at end of file diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index 07092d2ede..15127d3d47 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe; use pocketmine\block\inventory\AnvilInventory; use pocketmine\block\inventory\BlockInventory; use pocketmine\block\inventory\BrewingStandInventory; +use pocketmine\block\inventory\CraftingTableInventory; use pocketmine\block\inventory\EnchantInventory; use pocketmine\block\inventory\FurnaceInventory; use pocketmine\block\inventory\HopperInventory; @@ -67,7 +68,6 @@ class InventoryManager{ //effect on the behaviour of inventory transactions I don't currently plan to integrate these into the main system. private const RESERVED_WINDOW_ID_RANGE_START = ContainerIds::LAST - 10; private const RESERVED_WINDOW_ID_RANGE_END = ContainerIds::LAST; - public const HARDCODED_CRAFTING_GRID_WINDOW_ID = self::RESERVED_WINDOW_ID_RANGE_START + 1; public const HARDCODED_INVENTORY_WINDOW_ID = self::RESERVED_WINDOW_ID_RANGE_START + 2; /** @var Player */ @@ -178,6 +178,7 @@ class InventoryManager{ $inv instanceof BrewingStandInventory => WindowTypes::BREWING_STAND, $inv instanceof AnvilInventory => WindowTypes::ANVIL, $inv instanceof HopperInventory => WindowTypes::HOPPER, + $inv instanceof CraftingTableInventory => WindowTypes::WORKBENCH, default => WindowTypes::CONTAINER }; return [ContainerOpenPacket::blockInv($id, $windowType, $blockPosition)]; diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index 38bbe359ad..a2f9d98cea 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -24,9 +24,9 @@ namespace pocketmine\network\mcpe\convert; use pocketmine\block\BlockLegacyIds; use pocketmine\block\inventory\AnvilInventory; +use pocketmine\block\inventory\CraftingTableInventory; use pocketmine\block\inventory\EnchantInventory; use pocketmine\block\inventory\LoomInventory; -use pocketmine\crafting\CraftingGrid; use pocketmine\inventory\Inventory; use pocketmine\inventory\transaction\action\CreateItemAction; use pocketmine\inventory\transaction\action\DestroyItemAction; @@ -290,11 +290,7 @@ class TypeConverter{ $pSlot = $action->inventorySlot; $craftingGrid = $player->getCraftingGrid(); - $mapped = - $this->mapUIInventory($pSlot, UIInventorySlotOffset::CRAFTING2X2_INPUT, $craftingGrid, - function(Inventory $i) : bool{ return $i instanceof CraftingGrid && $i->getGridWidth() === CraftingGrid::SIZE_SMALL; }) ?? - $this->mapUIInventory($pSlot, UIInventorySlotOffset::CRAFTING3X3_INPUT, $craftingGrid, - function(Inventory $i) : bool{ return $i instanceof CraftingGrid && $i->getGridWidth() === CraftingGrid::SIZE_BIG; }); + $mapped = $this->mapUIInventory($pSlot, UIInventorySlotOffset::CRAFTING2X2_INPUT, $craftingGrid, fn() => true); if($mapped === null){ $current = $player->getCurrentWindow(); $mapped = @@ -303,7 +299,9 @@ class TypeConverter{ $this->mapUIInventory($pSlot, UIInventorySlotOffset::ENCHANTING_TABLE, $current, function(Inventory $i) : bool{ return $i instanceof EnchantInventory; }) ?? $this->mapUIInventory($pSlot, UIInventorySlotOffset::LOOM, $current, - fn(Inventory $i) => $i instanceof LoomInventory); + fn(Inventory $i) => $i instanceof LoomInventory) ?? + $this->mapUIInventory($pSlot, UIInventorySlotOffset::CRAFTING3X3_INPUT, $current, + fn(Inventory $i) => $i instanceof CraftingTableInventory); } if($mapped === null){ throw new TypeConversionException("Unmatched UI inventory slot offset $pSlot"); diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index ad8b001c08..d2ae3108e1 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -26,7 +26,6 @@ namespace pocketmine\network\mcpe\handler; use pocketmine\block\BaseSign; use pocketmine\block\ItemFrame; use pocketmine\block\utils\SignText; -use pocketmine\crafting\CraftingGrid; use pocketmine\entity\animation\ConsumingItemAnimation; use pocketmine\entity\InvalidSkinException; use pocketmine\event\player\PlayerEditBookEvent; @@ -309,14 +308,6 @@ class InGamePacketHandler extends PacketHandler{ foreach($this->craftingTransaction->getInventories() as $inventory){ $this->inventoryManager->syncContents($inventory); } - /* - * TODO: HACK! - * we can't resend the contents of the crafting window, so we force the client to close it instead. - * So people don't whine about messy desync issues when someone cancels CraftItemEvent, or when a crafting - * transaction goes wrong. - */ - $this->session->sendDataPacket(ContainerClosePacket::create(InventoryManager::HARDCODED_CRAFTING_GRID_WINDOW_ID, true)); - return false; }finally{ $this->craftingTransaction = null; @@ -380,18 +371,6 @@ class InGamePacketHandler extends PacketHandler{ $vBlockPos = new Vector3($blockPos->getX(), $blockPos->getY(), $blockPos->getZ()); if(!$this->player->interactBlock($vBlockPos, $data->getFace(), $clickPos)){ $this->onFailedBlockAction($vBlockPos, $data->getFace()); - }elseif( - !array_key_exists($windowId = InventoryManager::HARDCODED_CRAFTING_GRID_WINDOW_ID, $this->openHardcodedWindows) && - $this->player->getCraftingGrid()->getGridWidth() === CraftingGrid::SIZE_BIG - ){ - //TODO: HACK! crafting grid doesn't fit very well into the current PM container system, so this hack - //allows it to carry on working approximately the same way as it did in 1.14 - $this->openHardcodedWindows[$windowId] = true; - $this->session->sendDataPacket(ContainerOpenPacket::blockInv( - InventoryManager::HARDCODED_CRAFTING_GRID_WINDOW_ID, - WindowTypes::WORKBENCH, - $blockPos - )); } return true; case UseItemTransactionData::ACTION_BREAK_BLOCK: diff --git a/src/player/Player.php b/src/player/Player.php index 1839adc099..7f43296b14 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -75,6 +75,7 @@ use pocketmine\form\Form; use pocketmine\form\FormValidationException; use pocketmine\inventory\CallbackInventoryListener; use pocketmine\inventory\Inventory; +use pocketmine\inventory\PlayerCraftingInventory; use pocketmine\inventory\PlayerCursorInventory; use pocketmine\inventory\transaction\action\DropItemAction; use pocketmine\inventory\transaction\InventoryTransaction; @@ -182,7 +183,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ /** @var Inventory[] */ protected array $permanentWindows = []; protected PlayerCursorInventory $cursorInventory; - protected CraftingGrid $craftingGrid; + protected PlayerCraftingInventory $craftingGrid; protected int $messageCounter = 2; @@ -2301,7 +2302,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ protected function addDefaultWindows() : void{ $this->cursorInventory = new PlayerCursorInventory($this); - $this->craftingGrid = new CraftingGrid($this, CraftingGrid::SIZE_SMALL); + $this->craftingGrid = new PlayerCraftingInventory($this); $this->addPermanentInventories($this->inventory, $this->armorInventory, $this->cursorInventory, $this->offHandInventory); @@ -2316,10 +2317,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return $this->craftingGrid; } - public function setCraftingGrid(CraftingGrid $grid) : void{ - $this->craftingGrid = $grid; - } - /** * @internal Called to clean up crafting grid and cursor inventory when it is detected that the player closed their * inventory. @@ -2363,10 +2360,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ throw new AssumptionFailedError("This server-generated transaction should never be invalid", 0, $e); } } - - if($this->craftingGrid->getGridWidth() > CraftingGrid::SIZE_SMALL){ - $this->craftingGrid = new CraftingGrid($this, CraftingGrid::SIZE_SMALL); - } } /** From b84f7c18ecf79b4d72e507ca5264de06f14d5107 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 7 Nov 2021 19:18:09 +0000 Subject: [PATCH 3146/3224] Install ext/crypto from PECL --- tests/gh-actions/build.sh | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/tests/gh-actions/build.sh b/tests/gh-actions/build.sh index d70be79807..3a2b733d6a 100755 --- a/tests/gh-actions/build.sh +++ b/tests/gh-actions/build.sh @@ -56,17 +56,7 @@ leveldb=@60763a09bf5c7a10376d16e25b078b99a35c5c37 \ chunkutils2=@0.3.1 \ morton=@0.1.2 \ igbinary=3.2.1 \ +crypto=0.3.2 \ " PHP_BUILD_ZTS_ENABLE=on PHP_BUILD_CONFIGURE_OPTS='--with-gmp' ./bin/php-build "$VERSION" "$INSTALL_DIR" || exit 1 -rm -rf crypto -git clone --recursive https://github.com/bukka/php-crypto.git crypto -cd crypto -git checkout -qf c8867aa944fa5227eaea9d11a6ce282e64c15af9 -git submodule update --init --recursive -"$INSTALL_DIR/bin/phpize" -./configure --with-php-config="$INSTALL_DIR/bin/php-config" -make -j8 install -echo "extension=crypto.so" >> "$INSTALL_DIR/etc/conf.d/crypto.ini" -cd .. - rm "$INSTALL_DIR/etc/conf.d/xdebug.ini" || true From 4131bcef08000eccd7d3ad95c6ce8677c2e9cb2a Mon Sep 17 00:00:00 2001 From: DataLion <34657342+TheDataLion@users.noreply.github.com> Date: Sun, 7 Nov 2021 22:11:55 +0100 Subject: [PATCH 3147/3224] Changed "Level" string to "World" in Position::__toString() method. (#4559) --- src/world/Position.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/Position.php b/src/world/Position.php index 82df931e0d..f3fe84caaf 100644 --- a/src/world/Position.php +++ b/src/world/Position.php @@ -98,7 +98,7 @@ class Position extends Vector3{ } public function __toString(){ - return "Position(level=" . ($this->isValid() ? $this->getWorld()->getDisplayName() : "null") . ",x=" . $this->x . ",y=" . $this->y . ",z=" . $this->z . ")"; + return "Position(world=" . ($this->isValid() ? $this->getWorld()->getDisplayName() : "null") . ",x=" . $this->x . ",y=" . $this->y . ",z=" . $this->z . ")"; } public function equals(Vector3 $v) : bool{ From 2b0b9bd8ed73cdd809cb9a8230ad93785cf59f12 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Nov 2021 17:16:57 +0000 Subject: [PATCH 3148/3224] Update composer dependencies --- composer.lock | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/composer.lock b/composer.lock index 0a6a2aa616..22868f8044 100644 --- a/composer.lock +++ b/composer.lock @@ -275,16 +275,16 @@ }, { "name": "pocketmine/bedrock-protocol", - "version": "5.0.0+bedrock-1.17.40", + "version": "5.1.0+bedrock-1.17.40", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "67c0c15b4044cab2190501933912c3d02c5f63ab" + "reference": "5abbe5bc21d8a9152d46c26578bf5257526612f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/67c0c15b4044cab2190501933912c3d02c5f63ab", - "reference": "67c0c15b4044cab2190501933912c3d02c5f63ab", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/5abbe5bc21d8a9152d46c26578bf5257526612f9", + "reference": "5abbe5bc21d8a9152d46c26578bf5257526612f9", "shasum": "" }, "require": { @@ -298,7 +298,7 @@ "ramsey/uuid": "^4.1" }, "require-dev": { - "phpstan/phpstan": "1.0.0", + "phpstan/phpstan": "1.1.1", "phpstan/phpstan-phpunit": "^1.0.0", "phpstan/phpstan-strict-rules": "^1.0.0", "phpunit/phpunit": "^9.5" @@ -316,9 +316,9 @@ "description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP", "support": { "issues": "https://github.com/pmmp/BedrockProtocol/issues", - "source": "https://github.com/pmmp/BedrockProtocol/tree/5.0.0+bedrock-1.17.40" + "source": "https://github.com/pmmp/BedrockProtocol/tree/5.1.0+bedrock-1.17.40" }, - "time": "2021-11-02T01:27:05+00:00" + "time": "2021-11-08T16:26:25+00:00" }, { "name": "pocketmine/binaryutils", @@ -533,16 +533,16 @@ }, { "name": "pocketmine/locale-data", - "version": "1.1.4", + "version": "1.1.6", "source": { "type": "git", "url": "https://github.com/pmmp/Language.git", - "reference": "549f27f593b200d8b11ca05ffcd5a73e02a0d9fb" + "reference": "216b49b87e20332f0b39d1717e1e2012a40074cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Language/zipball/549f27f593b200d8b11ca05ffcd5a73e02a0d9fb", - "reference": "549f27f593b200d8b11ca05ffcd5a73e02a0d9fb", + "url": "https://api.github.com/repos/pmmp/Language/zipball/216b49b87e20332f0b39d1717e1e2012a40074cc", + "reference": "216b49b87e20332f0b39d1717e1e2012a40074cc", "shasum": "" }, "type": "library", @@ -550,9 +550,9 @@ "description": "Language resources used by PocketMine-MP", "support": { "issues": "https://github.com/pmmp/Language/issues", - "source": "https://github.com/pmmp/Language/tree/1.1.4" + "source": "https://github.com/pmmp/Language/tree/1.1.6" }, - "time": "2021-11-06T17:02:22+00:00" + "time": "2021-11-07T14:30:46+00:00" }, { "name": "pocketmine/log", @@ -1370,6 +1370,7 @@ "issues": "https://github.com/webmozart/path-util/issues", "source": "https://github.com/webmozart/path-util/tree/2.3.0" }, + "abandoned": "symfony/filesystem", "time": "2015-12-17T08:42:14+00:00" } ], From df39a1ca0777cbb089e69dab62e3dd96eb7e5923 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Nov 2021 17:22:01 +0000 Subject: [PATCH 3149/3224] TeleportCommand: do not hardcode world bounds --- src/command/defaults/TeleportCommand.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/command/defaults/TeleportCommand.php b/src/command/defaults/TeleportCommand.php index e3bbff7d09..4748dc2d3d 100644 --- a/src/command/defaults/TeleportCommand.php +++ b/src/command/defaults/TeleportCommand.php @@ -32,6 +32,7 @@ use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\TextFormat; +use pocketmine\world\World; use function array_shift; use function count; use function round; @@ -111,7 +112,7 @@ class TeleportCommand extends VanillaCommand{ } $x = $this->getRelativeDouble($base->x, $sender, $targetArgs[0]); - $y = $this->getRelativeDouble($base->y, $sender, $targetArgs[1], 0, 256); + $y = $this->getRelativeDouble($base->y, $sender, $targetArgs[1], World::Y_MIN, World::Y_MAX); $z = $this->getRelativeDouble($base->z, $sender, $targetArgs[2]); $targetLocation = new Location($x, $y, $z, $base->getWorld(), $yaw, $pitch); From c6c992a1f0fdc1734c6777d7acbd8035422f76df Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Nov 2021 17:28:22 +0000 Subject: [PATCH 3150/3224] Preparations for negative Y support --- src/entity/Entity.php | 2 +- .../mcpe/serializer/ChunkSerializer.php | 6 ++--- src/world/World.php | 2 +- src/world/format/Chunk.php | 24 ++++++++++++------- src/world/format/io/FastChunkSerializer.php | 3 ++- src/world/format/io/leveldb/LevelDB.php | 2 +- src/world/light/SkyLightUpdate.php | 15 ++++++------ src/world/utils/SubChunkExplorer.php | 2 +- 8 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/entity/Entity.php b/src/entity/Entity.php index e483b43489..1631667c51 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -635,7 +635,7 @@ abstract class Entity{ $this->checkBlockIntersections(); - if($this->location->y <= -16 and $this->isAlive()){ + if($this->location->y <= World::Y_MIN - 16 and $this->isAlive()){ $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_VOID, 10); $this->attack($ev); $hasUpdate = true; diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index 6fe392b670..af53364657 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -46,8 +46,8 @@ final class ChunkSerializer{ * Chunks are sent in a stack, so every chunk below the top non-empty one must be sent. */ public static function getSubChunkCount(Chunk $chunk) : int{ - for($count = count($chunk->getSubChunks()); $count > 0; --$count){ - if($chunk->getSubChunk($count - 1)->isEmptyFast()){ + for($y = Chunk::MAX_SUBCHUNK_INDEX, $count = count($chunk->getSubChunks()); $y >= Chunk::MIN_SUBCHUNK_INDEX; --$y, --$count){ + if($chunk->getSubChunk($y)->isEmptyFast()){ continue; } return $count; @@ -59,7 +59,7 @@ final class ChunkSerializer{ public static function serializeFullChunk(Chunk $chunk, RuntimeBlockMapping $blockMapper, PacketSerializerContext $encoderContext, ?string $tiles = null) : string{ $stream = PacketSerializer::encoder($encoderContext); $subChunkCount = self::getSubChunkCount($chunk); - for($y = 0; $y < $subChunkCount; ++$y){ + for($y = Chunk::MIN_SUBCHUNK_INDEX, $writtenCount = 0; $writtenCount < $subChunkCount; ++$y, ++$writtenCount){ self::serializeSubChunk($chunk->getSubChunk($y), $blockMapper, $stream, false); } $stream->put($chunk->getBiomeIdArray()); diff --git a/src/world/World.php b/src/world/World.php index a06f2ad5ec..dcd27805cb 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -331,7 +331,7 @@ class World implements ChunkManager{ private const BLOCKHASH_Y_OFFSET = self::BLOCKHASH_Y_PADDING - self::Y_MIN; private const BLOCKHASH_Y_MASK = (1 << self::BLOCKHASH_Y_BITS) - 1; private const BLOCKHASH_XZ_MASK = (1 << self::MORTON3D_BIT_SIZE) - 1; - private const BLOCKHASH_XZ_EXTRA_BITS = 6; + private const BLOCKHASH_XZ_EXTRA_BITS = (self::MORTON3D_BIT_SIZE - self::BLOCKHASH_Y_BITS) >> 1; private const BLOCKHASH_XZ_EXTRA_MASK = (1 << self::BLOCKHASH_XZ_EXTRA_BITS) - 1; private const BLOCKHASH_XZ_SIGN_SHIFT = 64 - self::MORTON3D_BIT_SIZE - self::BLOCKHASH_XZ_EXTRA_BITS; private const BLOCKHASH_X_SHIFT = self::BLOCKHASH_Y_BITS; diff --git a/src/world/format/Chunk.php b/src/world/format/Chunk.php index f1b1320ae2..8bb5eed9f2 100644 --- a/src/world/format/Chunk.php +++ b/src/world/format/Chunk.php @@ -35,7 +35,9 @@ class Chunk{ public const DIRTY_FLAG_BLOCKS = 1 << 0; public const DIRTY_FLAG_BIOMES = 1 << 3; - public const MAX_SUBCHUNKS = 16; + public const MIN_SUBCHUNK_INDEX = 0; + public const MAX_SUBCHUNK_INDEX = 15; + public const MAX_SUBCHUNKS = self::MAX_SUBCHUNK_INDEX - self::MIN_SUBCHUNK_INDEX + 1; public const EDGE_LENGTH = SubChunk::EDGE_LENGTH; public const COORD_BIT_SIZE = SubChunk::COORD_BIT_SIZE; @@ -71,10 +73,10 @@ class Chunk{ $this->subChunks = new \SplFixedArray(Chunk::MAX_SUBCHUNKS); foreach($this->subChunks as $y => $null){ - $this->subChunks[$y] = $subChunks[$y] ?? new SubChunk(BlockLegacyIds::AIR << Block::INTERNAL_METADATA_BITS, []); + $this->subChunks[$y] = $subChunks[$y + self::MIN_SUBCHUNK_INDEX] ?? new SubChunk(BlockLegacyIds::AIR << Block::INTERNAL_METADATA_BITS, []); } - $val = ($this->subChunks->getSize() * SubChunk::EDGE_LENGTH); + $val = (self::MAX_SUBCHUNK_INDEX + 1) * SubChunk::EDGE_LENGTH; $this->heightMap = HeightArray::fill($val); //TODO: what about lazily initializing this? $this->biomeIds = $biomeIds; @@ -118,7 +120,7 @@ class Chunk{ * @return int|null 0-255, or null if there are no blocks in the column */ public function getHighestBlockAt(int $x, int $z) : ?int{ - for($y = $this->subChunks->count() - 1; $y >= 0; --$y){ + for($y = self::MAX_SUBCHUNK_INDEX; $y >= self::MIN_SUBCHUNK_INDEX; --$y){ $height = $this->getSubChunk($y)->getHighestBlockAt($x, $z); if($height !== null){ return $height | ($y << SubChunk::COORD_BIT_SIZE); @@ -280,21 +282,21 @@ class Chunk{ } public function getSubChunk(int $y) : SubChunk{ - if($y < 0 || $y >= $this->subChunks->getSize()){ + if($y < self::MIN_SUBCHUNK_INDEX || $y > self::MAX_SUBCHUNK_INDEX){ throw new \InvalidArgumentException("Invalid subchunk Y coordinate $y"); } - return $this->subChunks[$y]; + return $this->subChunks[$y - self::MIN_SUBCHUNK_INDEX]; } /** * Sets a subchunk in the chunk index */ public function setSubChunk(int $y, ?SubChunk $subChunk) : void{ - if($y < 0 or $y >= $this->subChunks->getSize()){ + if($y < self::MIN_SUBCHUNK_INDEX or $y > self::MAX_SUBCHUNK_INDEX){ throw new \InvalidArgumentException("Invalid subchunk Y coordinate $y"); } - $this->subChunks[$y] = $subChunk ?? new SubChunk(BlockLegacyIds::AIR << Block::INTERNAL_METADATA_BITS, []); + $this->subChunks[$y - self::MIN_SUBCHUNK_INDEX] = $subChunk ?? new SubChunk(BlockLegacyIds::AIR << Block::INTERNAL_METADATA_BITS, []); $this->setTerrainDirtyFlag(self::DIRTY_FLAG_BLOCKS, true); } @@ -303,7 +305,11 @@ class Chunk{ * @phpstan-return array */ public function getSubChunks() : array{ - return $this->subChunks->toArray(); + $result = []; + foreach($this->subChunks as $yOffset => $subChunk){ + $result[$yOffset + self::MIN_SUBCHUNK_INDEX] = $subChunk; + } + return $result; } /** diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index bb8bec687a..c8ab53a733 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\format\io; +use pocketmine\utils\Binary; use pocketmine\utils\BinaryStream; use pocketmine\world\format\BiomeArray; use pocketmine\world\format\Chunk; @@ -96,7 +97,7 @@ final class FastChunkSerializer{ $count = $stream->getByte(); for($subCount = 0; $subCount < $count; ++$subCount){ - $y = $stream->getByte(); + $y = Binary::signByte($stream->getByte()); $airBlockId = $stream->getInt(); /** @var PalettedBlockArray[] $layers */ diff --git a/src/world/format/io/leveldb/LevelDB.php b/src/world/format/io/leveldb/LevelDB.php index a96e329b31..3fe2e359c2 100644 --- a/src/world/format/io/leveldb/LevelDB.php +++ b/src/world/format/io/leveldb/LevelDB.php @@ -266,7 +266,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{ case 3: //MCPE 1.0 $convertedLegacyExtraData = $this->deserializeLegacyExtraData($index, $chunkVersion); - for($y = 0; $y < Chunk::MAX_SUBCHUNKS; ++$y){ + for($y = Chunk::MIN_SUBCHUNK_INDEX; $y <= Chunk::MAX_SUBCHUNK_INDEX; ++$y){ if(($data = $this->db->get($index . self::TAG_SUBCHUNK_PREFIX . chr($y))) === false){ continue; } diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index 42d12be17d..2c4214568a 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -115,11 +115,10 @@ class SkyLightUpdate extends LightUpdate{ //have to avoid filling full light for any subchunk that contains a heightmap Y coordinate $highestHeightMapPlusOne = max($chunk->getHeightMapArray()) + 1; $lowestClearSubChunk = ($highestHeightMapPlusOne >> SubChunk::COORD_BIT_SIZE) + (($highestHeightMapPlusOne & SubChunk::COORD_MASK) !== 0 ? 1 : 0); - $chunkHeight = count($chunk->getSubChunks()); - for($y = 0; $y < $lowestClearSubChunk && $y < $chunkHeight; $y++){ + for($y = Chunk::MIN_SUBCHUNK_INDEX; $y < $lowestClearSubChunk && $y <= Chunk::MAX_SUBCHUNK_INDEX; $y++){ $chunk->getSubChunk($y)->setBlockSkyLightArray(LightArray::fill(0)); } - for($y = $lowestClearSubChunk, $yMax = $chunkHeight; $y < $yMax; $y++){ + for($y = $lowestClearSubChunk; $y <= Chunk::MAX_SUBCHUNK_INDEX; $y++){ $chunk->getSubChunk($y)->setBlockSkyLightArray(LightArray::fill(15)); } @@ -130,7 +129,7 @@ class SkyLightUpdate extends LightUpdate{ for($x = 0; $x < Chunk::EDGE_LENGTH; ++$x){ for($z = 0; $z < Chunk::EDGE_LENGTH; ++$z){ $currentHeight = $chunk->getHeightMap($x, $z); - $maxAdjacentHeight = 0; + $maxAdjacentHeight = World::Y_MIN; if($x !== 0){ $maxAdjacentHeight = max($maxAdjacentHeight, $chunk->getHeightMap($x - 1, $z)); } @@ -174,21 +173,21 @@ class SkyLightUpdate extends LightUpdate{ * @phpstan-param \SplFixedArray $directSkyLightBlockers */ private static function recalculateHeightMap(Chunk $chunk, \SplFixedArray $directSkyLightBlockers) : HeightArray{ - $maxSubChunkY = count($chunk->getSubChunks()) - 1; - for(; $maxSubChunkY >= 0; $maxSubChunkY--){ + $maxSubChunkY = Chunk::MAX_SUBCHUNK_INDEX; + for(; $maxSubChunkY >= Chunk::MIN_SUBCHUNK_INDEX; $maxSubChunkY--){ if(!$chunk->getSubChunk($maxSubChunkY)->isEmptyFast()){ break; } } $result = HeightArray::fill(World::Y_MIN); - if($maxSubChunkY === -1){ //whole column is definitely empty + if($maxSubChunkY < Chunk::MIN_SUBCHUNK_INDEX){ //whole column is definitely empty return $result; } for($z = 0; $z < Chunk::EDGE_LENGTH; ++$z){ for($x = 0; $x < Chunk::EDGE_LENGTH; ++$x){ $y = null; - for($subChunkY = $maxSubChunkY; $subChunkY >= 0; $subChunkY--){ + for($subChunkY = $maxSubChunkY; $subChunkY >= Chunk::MIN_SUBCHUNK_INDEX; $subChunkY--){ $subHighestBlockY = $chunk->getSubChunk($subChunkY)->getHighestBlockAt($x, $z); if($subHighestBlockY !== null){ $y = ($subChunkY * SubChunk::EDGE_LENGTH) + $subHighestBlockY; diff --git a/src/world/utils/SubChunkExplorer.php b/src/world/utils/SubChunkExplorer.php index 9d7faeb969..69bdb44e10 100644 --- a/src/world/utils/SubChunkExplorer.php +++ b/src/world/utils/SubChunkExplorer.php @@ -68,7 +68,7 @@ class SubChunkExplorer{ if($this->currentSubChunk === null or $this->currentY !== $newChunkY){ $this->currentY = $newChunkY; - if($this->currentY < 0 or $this->currentY >= $this->currentChunk->getHeight()){ + if($this->currentY < Chunk::MIN_SUBCHUNK_INDEX or $this->currentY > Chunk::MAX_SUBCHUNK_INDEX){ $this->currentSubChunk = null; return SubChunkExplorerStatus::INVALID; } From a6f6b60bed7f570f96ee48de79a3fa3dc2953006 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Nov 2021 18:02:24 +0000 Subject: [PATCH 3151/3224] fix CS again --- src/world/light/SkyLightUpdate.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/world/light/SkyLightUpdate.php b/src/world/light/SkyLightUpdate.php index 2c4214568a..a505fde025 100644 --- a/src/world/light/SkyLightUpdate.php +++ b/src/world/light/SkyLightUpdate.php @@ -30,7 +30,6 @@ use pocketmine\world\format\SubChunk; use pocketmine\world\utils\SubChunkExplorer; use pocketmine\world\utils\SubChunkExplorerStatus; use pocketmine\world\World; -use function count; use function max; class SkyLightUpdate extends LightUpdate{ From 18f5fb66bba9f468daf9a019455be3ff1ab371f0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Nov 2021 18:37:05 +0000 Subject: [PATCH 3152/3224] Abstract the base functionality of StringToItemParser --- src/item/StringToItemParser.php | 44 ++---------------- src/utils/StringToTParser.php | 82 +++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 39 deletions(-) create mode 100644 src/utils/StringToTParser.php diff --git a/src/item/StringToItemParser.php b/src/item/StringToItemParser.php index 75b6b81aa3..6d313905de 100644 --- a/src/item/StringToItemParser.php +++ b/src/item/StringToItemParser.php @@ -29,6 +29,7 @@ use pocketmine\block\utils\DyeColor; use pocketmine\block\utils\SlabType; use pocketmine\block\VanillaBlocks; use pocketmine\utils\SingletonTrait; +use pocketmine\utils\StringToTParser; use function array_keys; use function str_replace; use function strtolower; @@ -36,18 +37,12 @@ use function trim; /** * Handles parsing items from strings. This is used to interpret names from the /give command (and others). - * Custom aliases may be registered. - * Note that the aliases should be user-friendly, i.e. easily readable and writable. + * + * @phpstan-extends StringToTParser */ -final class StringToItemParser{ +final class StringToItemParser extends StringToTParser{ use SingletonTrait; - /** - * @var \Closure[] - * @phpstan-var array - */ - private array $callbackMap = []; - private static function make() : self{ $result = new self; @@ -1325,41 +1320,12 @@ final class StringToItemParser{ return $result; } - /** @phpstan-param \Closure(string $input) : Item $callback */ - public function register(string $alias, \Closure $callback) : void{ - $key = $this->reprocess($alias); - if(isset($this->callbackMap[$key])){ - throw new \InvalidArgumentException("Alias \"$key\" is already registered"); - } - $this->callbackMap[$key] = $callback; - } - /** @phpstan-param \Closure(string $input) : Block $callback */ public function registerBlock(string $alias, \Closure $callback) : void{ $this->register($alias, fn(string $input) => $callback($input)->asItem()); } - /** @phpstan-param \Closure(string $input) : Item $callback */ - public function override(string $alias, \Closure $callback) : void{ - $this->callbackMap[$this->reprocess($alias)] = $callback; - } - - /** Tries to parse the specified string into an item. */ public function parse(string $input) : ?Item{ - $key = $this->reprocess($input); - if(isset($this->callbackMap[$key])){ - return ($this->callbackMap[$key])($input); - } - - return null; - } - - protected function reprocess(string $input) : string{ - return strtolower(str_replace([" ", "minecraft:"], ["_", ""], trim($input))); - } - - /** @return string[] */ - public function getKnownAliases() : array{ - return array_keys($this->callbackMap); + return parent::parse($input); } } diff --git a/src/utils/StringToTParser.php b/src/utils/StringToTParser.php new file mode 100644 index 0000000000..598b3768db --- /dev/null +++ b/src/utils/StringToTParser.php @@ -0,0 +1,82 @@ + + */ + private array $callbackMap = []; + + /** @phpstan-param \Closure(string $input) : T $callback */ + public function register(string $alias, \Closure $callback) : void{ + $key = $this->reprocess($alias); + if(isset($this->callbackMap[$key])){ + throw new \InvalidArgumentException("Alias \"$key\" is already registered"); + } + $this->callbackMap[$key] = $callback; + } + + /** @phpstan-param \Closure(string $input) : T $callback */ + public function override(string $alias, \Closure $callback) : void{ + $this->callbackMap[$this->reprocess($alias)] = $callback; + } + + /** + * Tries to parse the specified string into an enchantment. + * @phpstan-return T|null + */ + public function parse(string $input){ + $key = $this->reprocess($input); + if(isset($this->callbackMap[$key])){ + return ($this->callbackMap[$key])($input); + } + + return null; + } + + protected function reprocess(string $input) : string{ + return strtolower(str_replace([" ", "minecraft:"], ["_", ""], trim($input))); + } + + /** @return string[] */ + public function getKnownAliases() : array{ + return array_keys($this->callbackMap); + } +} \ No newline at end of file From 08420c25564017b8aaea277b60e9e6472c290203 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Nov 2021 18:44:15 +0000 Subject: [PATCH 3153/3224] Added new dynamic StringToEnchantmentParser this should be used instead of VanillaEnchantments::fromString(), because it allows registering custom aliases. --- src/command/defaults/EnchantCommand.php | 7 +- .../enchantment/StringToEnchantmentParser.php | 66 +++++++++++++++++++ 2 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 src/item/enchantment/StringToEnchantmentParser.php diff --git a/src/command/defaults/EnchantCommand.php b/src/command/defaults/EnchantCommand.php index 08e959a4fb..3e53a55fb2 100644 --- a/src/command/defaults/EnchantCommand.php +++ b/src/command/defaults/EnchantCommand.php @@ -26,7 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\item\enchantment\EnchantmentInstance; -use pocketmine\item\enchantment\VanillaEnchantments; +use pocketmine\item\enchantment\StringToEnchantmentParser; use pocketmine\lang\KnownTranslationFactory; use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\TextFormat; @@ -66,9 +66,8 @@ class EnchantCommand extends VanillaCommand{ return true; } - try{ - $enchantment = VanillaEnchantments::fromString($args[1]); - }catch(\InvalidArgumentException $e){ + $enchantment = StringToEnchantmentParser::getInstance()->parse($args[1]); + if($enchantment === null){ $sender->sendMessage(KnownTranslationFactory::commands_enchant_notFound($args[1])); return true; } diff --git a/src/item/enchantment/StringToEnchantmentParser.php b/src/item/enchantment/StringToEnchantmentParser.php new file mode 100644 index 0000000000..2205f12ff8 --- /dev/null +++ b/src/item/enchantment/StringToEnchantmentParser.php @@ -0,0 +1,66 @@ + + */ +final class StringToEnchantmentParser extends StringToTParser{ + use SingletonTrait; + + private static function make() : self{ + $result = new self; + + $result->register("blast_protection", fn() => VanillaEnchantments::BLAST_PROTECTION()); + $result->register("efficiency", fn() => VanillaEnchantments::EFFICIENCY()); + $result->register("feather_falling", fn() => VanillaEnchantments::FEATHER_FALLING()); + $result->register("fire_aspect", fn() => VanillaEnchantments::FIRE_ASPECT()); + $result->register("fire_protection", fn() => VanillaEnchantments::FIRE_PROTECTION()); + $result->register("flame", fn() => VanillaEnchantments::FLAME()); + $result->register("infinity", fn() => VanillaEnchantments::INFINITY()); + $result->register("knockback", fn() => VanillaEnchantments::KNOCKBACK()); + $result->register("mending", fn() => VanillaEnchantments::MENDING()); + $result->register("power", fn() => VanillaEnchantments::POWER()); + $result->register("projectile_protection", fn() => VanillaEnchantments::PROJECTILE_PROTECTION()); + $result->register("protection", fn() => VanillaEnchantments::PROTECTION()); + $result->register("punch", fn() => VanillaEnchantments::PUNCH()); + $result->register("respiration", fn() => VanillaEnchantments::RESPIRATION()); + $result->register("sharpness", fn() => VanillaEnchantments::SHARPNESS()); + $result->register("silk_touch", fn() => VanillaEnchantments::SILK_TOUCH()); + $result->register("thorns", fn() => VanillaEnchantments::THORNS()); + $result->register("unbreaking", fn() => VanillaEnchantments::UNBREAKING()); + $result->register("vanishing", fn() => VanillaEnchantments::VANISHING()); + + return $result; + } + + public function parse(string $input) : ?Enchantment{ + return parent::parse($input); + } +} \ No newline at end of file From 1fb60b5b3a3931c51e26e9f181cbdb07e8d52a37 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Nov 2021 18:45:05 +0000 Subject: [PATCH 3154/3224] CS fix again --- src/item/StringToItemParser.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/item/StringToItemParser.php b/src/item/StringToItemParser.php index 6d313905de..0d92ec4289 100644 --- a/src/item/StringToItemParser.php +++ b/src/item/StringToItemParser.php @@ -30,10 +30,6 @@ use pocketmine\block\utils\SlabType; use pocketmine\block\VanillaBlocks; use pocketmine\utils\SingletonTrait; use pocketmine\utils\StringToTParser; -use function array_keys; -use function str_replace; -use function strtolower; -use function trim; /** * Handles parsing items from strings. This is used to interpret names from the /give command (and others). From f93b5be789d834af28c42449c5513ce354169774 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Nov 2021 18:49:28 +0000 Subject: [PATCH 3155/3224] Added new dynamic StringToEffectParser --- src/command/defaults/EffectCommand.php | 7 +-- src/entity/effect/StringToEffectParser.php | 73 ++++++++++++++++++++++ 2 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 src/entity/effect/StringToEffectParser.php diff --git a/src/command/defaults/EffectCommand.php b/src/command/defaults/EffectCommand.php index 84fa8585e5..7b2541ea71 100644 --- a/src/command/defaults/EffectCommand.php +++ b/src/command/defaults/EffectCommand.php @@ -26,7 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\entity\effect\EffectInstance; -use pocketmine\entity\effect\VanillaEffects; +use pocketmine\entity\effect\StringToEffectParser; use pocketmine\lang\KnownTranslationFactory; use pocketmine\permission\DefaultPermissionNames; use pocketmine\utils\Limits; @@ -69,9 +69,8 @@ class EffectCommand extends VanillaCommand{ return true; } - try{ - $effect = VanillaEffects::fromString($args[1]); - }catch(\InvalidArgumentException $e){ + $effect = StringToEffectParser::getInstance()->parse($args[1]); + if($effect === null){ $sender->sendMessage(KnownTranslationFactory::commands_effect_notFound($args[1])->prefix(TextFormat::RED)); return true; } diff --git a/src/entity/effect/StringToEffectParser.php b/src/entity/effect/StringToEffectParser.php new file mode 100644 index 0000000000..b35ff68fcb --- /dev/null +++ b/src/entity/effect/StringToEffectParser.php @@ -0,0 +1,73 @@ + + */ +final class StringToEffectParser extends StringToTParser{ + use SingletonTrait; + + private static function make() : self{ + $result = new self; + + $result->register("absorption", fn() => VanillaEffects::ABSORPTION()); + $result->register("blindness", fn() => VanillaEffects::BLINDNESS()); + $result->register("conduit_power", fn() => VanillaEffects::CONDUIT_POWER()); + $result->register("fatal_poison", fn() => VanillaEffects::FATAL_POISON()); + $result->register("fire_resistance", fn() => VanillaEffects::FIRE_RESISTANCE()); + $result->register("haste", fn() => VanillaEffects::HASTE()); + $result->register("health_boost", fn() => VanillaEffects::HEALTH_BOOST()); + $result->register("hunger", fn() => VanillaEffects::HUNGER()); + $result->register("instant_damage", fn() => VanillaEffects::INSTANT_DAMAGE()); + $result->register("instant_health", fn() => VanillaEffects::INSTANT_HEALTH()); + $result->register("invisibility", fn() => VanillaEffects::INVISIBILITY()); + $result->register("jump_boost", fn() => VanillaEffects::JUMP_BOOST()); + $result->register("levitation", fn() => VanillaEffects::LEVITATION()); + $result->register("mining_fatigue", fn() => VanillaEffects::MINING_FATIGUE()); + $result->register("nausea", fn() => VanillaEffects::NAUSEA()); + $result->register("night_vision", fn() => VanillaEffects::NIGHT_VISION()); + $result->register("poison", fn() => VanillaEffects::POISON()); + $result->register("regeneration", fn() => VanillaEffects::REGENERATION()); + $result->register("resistance", fn() => VanillaEffects::RESISTANCE()); + $result->register("saturation", fn() => VanillaEffects::SATURATION()); + $result->register("slowness", fn() => VanillaEffects::SLOWNESS()); + $result->register("speed", fn() => VanillaEffects::SPEED()); + $result->register("strength", fn() => VanillaEffects::STRENGTH()); + $result->register("water_breathing", fn() => VanillaEffects::WATER_BREATHING()); + $result->register("weakness", fn() => VanillaEffects::WEAKNESS()); + $result->register("wither", fn() => VanillaEffects::WITHER()); + + return $result; + } + + public function parse(string $input) : ?Effect{ + return parent::parse($input); + } +} \ No newline at end of file From a1ecdc27e5b1a4b095482f4e14f149bce1a94d41 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Nov 2021 18:52:14 +0000 Subject: [PATCH 3156/3224] Removed Vanilla*::fromString() these were misbegotten and should never have existed. If someone really needs these for some reason, they can use getAll()[name]. --- src/block/VanillaBlocks.php | 6 ------ src/entity/effect/VanillaEffects.php | 6 ------ src/item/VanillaItems.php | 6 ------ src/item/enchantment/VanillaEnchantments.php | 6 ------ 4 files changed, 24 deletions(-) diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index 65099ab289..f40f52d57d 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -581,12 +581,6 @@ final class VanillaBlocks{ self::_registryRegister($name, $block); } - public static function fromString(string $name) : Block{ - $result = self::_registryFromString($name); - assert($result instanceof Block); - return $result; - } - /** * @return Block[] */ diff --git a/src/entity/effect/VanillaEffects.php b/src/entity/effect/VanillaEffects.php index a447613d40..ba2fc27cfe 100644 --- a/src/entity/effect/VanillaEffects.php +++ b/src/entity/effect/VanillaEffects.php @@ -109,10 +109,4 @@ final class VanillaEffects{ $result = self::_registryGetAll(); return $result; } - - public static function fromString(string $name) : Effect{ - $result = self::_registryFromString($name); - assert($result instanceof Effect); - return $result; - } } diff --git a/src/item/VanillaItems.php b/src/item/VanillaItems.php index f9ab3ade77..eba778cba4 100644 --- a/src/item/VanillaItems.php +++ b/src/item/VanillaItems.php @@ -381,12 +381,6 @@ final class VanillaItems{ self::_registryRegister($name, $item); } - public static function fromString(string $name) : Item{ - $result = self::_registryFromString($name); - assert($result instanceof Item); - return $result; - } - /** * @return Item[] */ diff --git a/src/item/enchantment/VanillaEnchantments.php b/src/item/enchantment/VanillaEnchantments.php index 37425bca13..f42039160d 100644 --- a/src/item/enchantment/VanillaEnchantments.php +++ b/src/item/enchantment/VanillaEnchantments.php @@ -113,10 +113,4 @@ final class VanillaEnchantments{ $result = self::_registryGetAll(); return $result; } - - public static function fromString(string $name) : Enchantment{ - /** @var Enchantment $result */ - $result = self::_registryFromString($name); - return $result; - } } From 19a3efe8936ad8f3e484c01b213bf2b84c0a40ae Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Nov 2021 18:57:14 +0000 Subject: [PATCH 3157/3224] ....... --- src/block/VanillaBlocks.php | 1 - src/entity/effect/VanillaEffects.php | 1 - src/item/VanillaItems.php | 1 - 3 files changed, 3 deletions(-) diff --git a/src/block/VanillaBlocks.php b/src/block/VanillaBlocks.php index f40f52d57d..7d2d947c5d 100644 --- a/src/block/VanillaBlocks.php +++ b/src/block/VanillaBlocks.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\utils\CloningRegistryTrait; -use function assert; /** * This doc-block is generated automatically, do not modify it manually. diff --git a/src/entity/effect/VanillaEffects.php b/src/entity/effect/VanillaEffects.php index ba2fc27cfe..50bddc9416 100644 --- a/src/entity/effect/VanillaEffects.php +++ b/src/entity/effect/VanillaEffects.php @@ -26,7 +26,6 @@ namespace pocketmine\entity\effect; use pocketmine\color\Color; use pocketmine\lang\KnownTranslationFactory; use pocketmine\utils\RegistryTrait; -use function assert; /** * This doc-block is generated automatically, do not modify it manually. diff --git a/src/item/VanillaItems.php b/src/item/VanillaItems.php index eba778cba4..c817ae6862 100644 --- a/src/item/VanillaItems.php +++ b/src/item/VanillaItems.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\utils\CloningRegistryTrait; -use function assert; /** * This doc-block is generated automatically, do not modify it manually. From cc4bb91fcb3c671f10a2223dc1fde61f77cd60fb Mon Sep 17 00:00:00 2001 From: Dylan T Date: Mon, 8 Nov 2021 20:03:28 +0000 Subject: [PATCH 3158/3224] Implemented IPv6 support (#4554) --- src/PocketMine.php | 5 ++ src/Server.php | 50 +++++++++++++++---- src/command/defaults/BanIpCommand.php | 4 +- src/command/defaults/PardonIpCommand.php | 4 +- src/network/mcpe/raklib/RakLibInterface.php | 4 +- .../query/DedicatedQueryNetworkInterface.php | 10 +++- src/network/query/QueryHandler.php | 4 -- 7 files changed, 58 insertions(+), 23 deletions(-) diff --git a/src/PocketMine.php b/src/PocketMine.php index 551585bbb0..e251fd614a 100644 --- a/src/PocketMine.php +++ b/src/PocketMine.php @@ -34,6 +34,7 @@ namespace pocketmine { use pocketmine\utils\Timezone; use pocketmine\wizard\SetupWizard; use Webmozart\PathUtil\Path; + use function defined; use function extension_loaded; use function phpversion; use function preg_match; @@ -145,6 +146,10 @@ namespace pocketmine { $messages[] = "The native PocketMine extension is no longer supported."; } + if(!defined('AF_INET6')){ + $messages[] = "IPv6 support is required, but your PHP binary was built without IPv6 support."; + } + return $messages; } diff --git a/src/Server.php b/src/Server.php index 731860d4a4..b384c29572 100644 --- a/src/Server.php +++ b/src/Server.php @@ -321,6 +321,10 @@ class Server{ return $this->configGroup->getConfigInt("server-port", 19132); } + public function getPortV6() : int{ + return $this->configGroup->getConfigInt("server-portv6", 19133); + } + public function getViewDistance() : int{ return max(2, $this->configGroup->getConfigInt("view-distance", 8)); } @@ -337,6 +341,11 @@ class Server{ return $str !== "" ? $str : "0.0.0.0"; } + public function getIpV6() : string{ + $str = $this->configGroup->getConfigString("server-ipv6"); + return $str !== "" ? $str : "::"; + } + public function getServerUniqueId() : UuidInterface{ return $this->serverID; } @@ -784,6 +793,8 @@ class Server{ new Config(Path::join($this->dataPath, "server.properties"), Config::PROPERTIES, [ "motd" => VersionInfo::NAME . " Server", "server-port" => 19132, + "server-portv6" => 19133, + "enable-ipv6" => true, "white-list" => false, "max-players" => 20, "gamemode" => 0, @@ -1114,25 +1125,42 @@ class Server{ return true; } - private function startupPrepareNetworkInterfaces() : bool{ - $useQuery = $this->configGroup->getConfigBool("enable-query", true); - + private function startupPrepareConnectableNetworkInterfaces(string $ip, int $port, bool $ipV6, bool $useQuery) : bool{ + $prettyIp = $ipV6 ? "[$ip]" : $ip; try{ - $rakLibRegistered = $this->network->registerInterface(new RakLibInterface($this)); + $rakLibRegistered = $this->network->registerInterface(new RakLibInterface($this, $ip, $port, $ipV6)); }catch(NetworkInterfaceStartException $e){ $this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_server_networkStartFailed( - $this->getIp(), - (string) $this->getPort(), + $ip, + (string) $port, $e->getMessage() ))); return false; } - if(!$rakLibRegistered && $useQuery){ - //RakLib would normally handle the transport for Query packets - //if it's not registered we need to make sure Query still works - $this->network->registerInterface(new DedicatedQueryNetworkInterface($this->getIp(), $this->getPort(), new \PrefixedLogger($this->logger, "Dedicated Query Interface"))); + $this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_networkStart($prettyIp, (string) $port))); + if($useQuery){ + if(!$rakLibRegistered){ + //RakLib would normally handle the transport for Query packets + //if it's not registered we need to make sure Query still works + $this->network->registerInterface(new DedicatedQueryNetworkInterface($ip, $port, $ipV6, new \PrefixedLogger($this->logger, "Dedicated Query Interface"))); + } + $this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_query_running($prettyIp, (string) $port))); + } + return true; + } + + private function startupPrepareNetworkInterfaces() : bool{ + $useQuery = $this->configGroup->getConfigBool("enable-query", true); + + if( + !$this->startupPrepareConnectableNetworkInterfaces($this->getIp(), $this->getPort(), false, $useQuery) || + ( + $this->configGroup->getConfigBool("enable-ipv6", true) && + !$this->startupPrepareConnectableNetworkInterfaces($this->getIpV6(), $this->getPortV6(), true, $useQuery) + ) + ){ + return false; } - $this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_networkStart($this->getIp(), (string) $this->getPort()))); if($useQuery){ $this->network->registerRawPacketHandler(new QueryHandler($this)); diff --git a/src/command/defaults/BanIpCommand.php b/src/command/defaults/BanIpCommand.php index fca99eff64..d6e1584b94 100644 --- a/src/command/defaults/BanIpCommand.php +++ b/src/command/defaults/BanIpCommand.php @@ -32,7 +32,7 @@ use pocketmine\player\Player; use function array_shift; use function count; use function implode; -use function preg_match; +use function inet_pton; class BanIpCommand extends VanillaCommand{ @@ -57,7 +57,7 @@ class BanIpCommand extends VanillaCommand{ $value = array_shift($args); $reason = implode(" ", $args); - if(preg_match("/^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$/", $value)){ + if(inet_pton($value) !== false){ $this->processIPBan($value, $sender, $reason); Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_banip_success($value)); diff --git a/src/command/defaults/PardonIpCommand.php b/src/command/defaults/PardonIpCommand.php index 395ba1d931..f0b2c9aa51 100644 --- a/src/command/defaults/PardonIpCommand.php +++ b/src/command/defaults/PardonIpCommand.php @@ -29,7 +29,7 @@ use pocketmine\command\utils\InvalidCommandSyntaxException; use pocketmine\lang\KnownTranslationFactory; use pocketmine\permission\DefaultPermissionNames; use function count; -use function preg_match; +use function inet_pton; class PardonIpCommand extends VanillaCommand{ @@ -52,7 +52,7 @@ class PardonIpCommand extends VanillaCommand{ throw new InvalidCommandSyntaxException(); } - if(preg_match("/^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$/", $args[0])){ + if(inet_pton($args[0]) !== false){ $sender->getServer()->getIPBans()->remove($args[0]); $sender->getServer()->getNetwork()->unblockAddress($args[0]); Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_unbanip_success($args[0])); diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 4bfee22584..15a8177fb4 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -88,7 +88,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ /** @var PacketBroadcaster */ private $broadcaster; - public function __construct(Server $server){ + public function __construct(Server $server, string $ip, int $port, bool $ipV6){ $this->server = $server; $this->rakServerId = mt_rand(0, PHP_INT_MAX); @@ -101,7 +101,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ $this->server->getLogger(), $mainToThreadBuffer, $threadToMainBuffer, - new InternetAddress($this->server->getIp(), $this->server->getPort(), 4), + new InternetAddress($ip, $port, $ipV6 ? 6 : 4), $this->rakServerId, $this->server->getConfigGroup()->getPropertyInt("network.max-mtu-size", 1492), self::MCPE_RAKNET_PROTOCOL_VERSION, diff --git a/src/network/query/DedicatedQueryNetworkInterface.php b/src/network/query/DedicatedQueryNetworkInterface.php index d742c9e53d..70a021a5a9 100644 --- a/src/network/query/DedicatedQueryNetworkInterface.php +++ b/src/network/query/DedicatedQueryNetworkInterface.php @@ -34,11 +34,14 @@ use function socket_recvfrom; use function socket_select; use function socket_sendto; use function socket_set_nonblock; +use function socket_set_option; use function socket_strerror; use function strlen; use function time; use function trim; use const AF_INET; +use const IPPROTO_IPV6; +use const IPV6_V6ONLY; use const PHP_INT_MAX; use const SOCK_DGRAM; use const SOCKET_EADDRINUSE; @@ -74,15 +77,18 @@ final class DedicatedQueryNetworkInterface implements AdvancedNetworkInterface{ /** @var string[] */ private $rawPacketPatterns = []; - public function __construct(string $ip, int $port, \Logger $logger){ + public function __construct(string $ip, int $port, bool $ipV6, \Logger $logger){ $this->ip = $ip; $this->port = $port; $this->logger = $logger; - $socket = @socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); + $socket = @socket_create($ipV6 ? AF_INET6 : AF_INET, SOCK_DGRAM, SOL_UDP); if($socket === false){ throw new \RuntimeException("Failed to create socket"); } + if($ipV6){ + socket_set_option($socket, IPPROTO_IPV6, IPV6_V6ONLY, 1); //disable linux's cool but annoying ipv4-over-ipv6 network stack + } $this->socket = $socket; } diff --git a/src/network/query/QueryHandler.php b/src/network/query/QueryHandler.php index 1ec8a22773..1fe2079694 100644 --- a/src/network/query/QueryHandler.php +++ b/src/network/query/QueryHandler.php @@ -27,7 +27,6 @@ declare(strict_types=1); */ namespace pocketmine\network\query; -use pocketmine\lang\KnownTranslationFactory; use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\RawPacketHandler; use pocketmine\Server; @@ -57,8 +56,6 @@ class QueryHandler implements RawPacketHandler{ public function __construct(Server $server){ $this->server = $server; $this->logger = new \PrefixedLogger($this->server->getLogger(), "Query Handler"); - $addr = $this->server->getIp(); - $port = $this->server->getPort(); /* The Query protocol is built on top of the existing Minecraft PE UDP network stack. @@ -71,7 +68,6 @@ class QueryHandler implements RawPacketHandler{ $this->regenerateToken(); $this->lastToken = $this->token; - $this->logger->info($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_query_running($addr, (string) $port))); } public function getPattern() : string{ From c33f97ae41e87b449d178c366f73ecc39e9c8cc0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Nov 2021 20:18:07 +0000 Subject: [PATCH 3159/3224] TypeConverter: clean up absurdly overcomplicated bullshit in createInventoryAction() --- src/network/mcpe/convert/TypeConverter.php | 42 ++++++++++------------ 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index a2f9d98cea..67c618ade0 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -27,7 +27,6 @@ use pocketmine\block\inventory\AnvilInventory; use pocketmine\block\inventory\CraftingTableInventory; use pocketmine\block\inventory\EnchantInventory; use pocketmine\block\inventory\LoomInventory; -use pocketmine\inventory\Inventory; use pocketmine\inventory\transaction\action\CreateItemAction; use pocketmine\inventory\transaction\action\DestroyItemAction; use pocketmine\inventory\transaction\action\DropItemAction; @@ -248,17 +247,12 @@ class TypeConverter{ } /** - * @param int[] $test + * @param int[] $test * @phpstan-param array $test - * @phpstan-param \Closure(Inventory) : bool $c - * @phpstan-return array{int, Inventory} */ - protected function mapUIInventory(int $slot, array $test, ?Inventory $inventory, \Closure $c) : ?array{ - if($inventory === null){ - return null; - } - if(array_key_exists($slot, $test) && $c($inventory)){ - return [$test[$slot], $inventory]; + protected function mapUIInventory(int $slot, array $test, bool $valid) : ?int{ + if(array_key_exists($slot, $test) && $valid){ + return $test[$slot]; } return null; } @@ -283,6 +277,7 @@ class TypeConverter{ } switch($action->sourceType){ case NetworkInventoryAction::SOURCE_CONTAINER: + $window = null; if($action->windowId === ContainerIds::UI and $action->inventorySlot > 0){ if($action->inventorySlot === UIInventorySlotOffset::CREATED_ITEM_OUTPUT){ return null; //useless noise @@ -290,23 +285,22 @@ class TypeConverter{ $pSlot = $action->inventorySlot; $craftingGrid = $player->getCraftingGrid(); - $mapped = $this->mapUIInventory($pSlot, UIInventorySlotOffset::CRAFTING2X2_INPUT, $craftingGrid, fn() => true); - if($mapped === null){ - $current = $player->getCurrentWindow(); - $mapped = - $this->mapUIInventory($pSlot, UIInventorySlotOffset::ANVIL, $current, - function(Inventory $i) : bool{ return $i instanceof AnvilInventory; }) ?? - $this->mapUIInventory($pSlot, UIInventorySlotOffset::ENCHANTING_TABLE, $current, - function(Inventory $i) : bool{ return $i instanceof EnchantInventory; }) ?? - $this->mapUIInventory($pSlot, UIInventorySlotOffset::LOOM, $current, - fn(Inventory $i) => $i instanceof LoomInventory) ?? - $this->mapUIInventory($pSlot, UIInventorySlotOffset::CRAFTING3X3_INPUT, $current, - fn(Inventory $i) => $i instanceof CraftingTableInventory); + $slot = $this->mapUIInventory($pSlot, UIInventorySlotOffset::CRAFTING2X2_INPUT, true); + if($slot !== null){ + $window = $craftingGrid; + }elseif(($current = $player->getCurrentWindow()) !== null){ + $slot = + $this->mapUIInventory($pSlot, UIInventorySlotOffset::ANVIL, $current instanceof AnvilInventory) ?? + $this->mapUIInventory($pSlot, UIInventorySlotOffset::ENCHANTING_TABLE, $current instanceof EnchantInventory) ?? + $this->mapUIInventory($pSlot, UIInventorySlotOffset::LOOM, $current instanceof LoomInventory) ?? + $this->mapUIInventory($pSlot, UIInventorySlotOffset::CRAFTING3X3_INPUT, $current instanceof CraftingTableInventory); + if($slot !== null){ + $window = $current; + } } - if($mapped === null){ + if($slot === null){ throw new TypeConversionException("Unmatched UI inventory slot offset $pSlot"); } - [$slot, $window] = $mapped; }else{ $window = $inventoryManager->getWindow($action->windowId); $slot = $action->inventorySlot; From 93a1e84ad9f7d7ad90d007d7002112286fb7ca83 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Nov 2021 20:27:53 +0000 Subject: [PATCH 3160/3224] TypeConverter: further simplification --- src/network/mcpe/convert/TypeConverter.php | 32 ++++++++-------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/src/network/mcpe/convert/TypeConverter.php b/src/network/mcpe/convert/TypeConverter.php index 67c618ade0..efa4e79c08 100644 --- a/src/network/mcpe/convert/TypeConverter.php +++ b/src/network/mcpe/convert/TypeConverter.php @@ -50,7 +50,6 @@ use pocketmine\player\GameMode; use pocketmine\player\Player; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\SingletonTrait; -use function array_key_exists; class TypeConverter{ use SingletonTrait; @@ -246,17 +245,6 @@ class TypeConverter{ } } - /** - * @param int[] $test - * @phpstan-param array $test - */ - protected function mapUIInventory(int $slot, array $test, bool $valid) : ?int{ - if(array_key_exists($slot, $test) && $valid){ - return $test[$slot]; - } - return null; - } - /** * @throws TypeConversionException */ @@ -284,18 +272,20 @@ class TypeConverter{ } $pSlot = $action->inventorySlot; - $craftingGrid = $player->getCraftingGrid(); - $slot = $this->mapUIInventory($pSlot, UIInventorySlotOffset::CRAFTING2X2_INPUT, true); + $slot = UIInventorySlotOffset::CRAFTING2X2_INPUT[$pSlot] ?? null; if($slot !== null){ - $window = $craftingGrid; + $window = $player->getCraftingGrid(); }elseif(($current = $player->getCurrentWindow()) !== null){ - $slot = - $this->mapUIInventory($pSlot, UIInventorySlotOffset::ANVIL, $current instanceof AnvilInventory) ?? - $this->mapUIInventory($pSlot, UIInventorySlotOffset::ENCHANTING_TABLE, $current instanceof EnchantInventory) ?? - $this->mapUIInventory($pSlot, UIInventorySlotOffset::LOOM, $current instanceof LoomInventory) ?? - $this->mapUIInventory($pSlot, UIInventorySlotOffset::CRAFTING3X3_INPUT, $current instanceof CraftingTableInventory); - if($slot !== null){ + $slotMap = match(true){ + $current instanceof AnvilInventory => UIInventorySlotOffset::ANVIL, + $current instanceof EnchantInventory => UIInventorySlotOffset::ENCHANTING_TABLE, + $current instanceof LoomInventory => UIInventorySlotOffset::LOOM, + $current instanceof CraftingTableInventory => UIInventorySlotOffset::CRAFTING3X3_INPUT, + default => null + }; + if($slotMap !== null){ $window = $current; + $slot = $slotMap[$pSlot] ?? null; } } if($slot === null){ From 6fdcfb01c886ca7c7464c801f9f841fe13ee8444 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Nov 2021 22:58:06 +0000 Subject: [PATCH 3161/3224] Seal up main inventory open/close logic inside InventoryManager where it belongs --- src/network/mcpe/InventoryManager.php | 39 +++++++++++++++---- .../mcpe/handler/InGamePacketHandler.php | 35 ++--------------- 2 files changed, 35 insertions(+), 39 deletions(-) diff --git a/src/network/mcpe/InventoryManager.php b/src/network/mcpe/InventoryManager.php index 15127d3d47..2c3fff30c8 100644 --- a/src/network/mcpe/InventoryManager.php +++ b/src/network/mcpe/InventoryManager.php @@ -67,8 +67,7 @@ class InventoryManager{ //these IDs are used for 1.16 to restore 1.14ish crafting & inventory behaviour; since they don't seem to have any //effect on the behaviour of inventory transactions I don't currently plan to integrate these into the main system. private const RESERVED_WINDOW_ID_RANGE_START = ContainerIds::LAST - 10; - private const RESERVED_WINDOW_ID_RANGE_END = ContainerIds::LAST; - public const HARDCODED_INVENTORY_WINDOW_ID = self::RESERVED_WINDOW_ID_RANGE_START + 2; + private const HARDCODED_INVENTORY_WINDOW_ID = self::RESERVED_WINDOW_ID_RANGE_START + 2; /** @var Player */ private $player; @@ -80,6 +79,15 @@ class InventoryManager{ /** @var int */ private $lastInventoryNetworkId = ContainerIds::FIRST; + /** + * TODO: HACK! This tracks GUIs for inventories that the server considers "always open" so that the client can't + * open them twice. (1.16 hack) + * @var true[] + * @phpstan-var array + * @internal + */ + protected $openHardcodedWindows = []; + /** * @var Item[][] * @phpstan-var array> @@ -186,6 +194,21 @@ class InventoryManager{ return null; } + public function onClientOpenMainInventory() : void{ + $id = self::HARDCODED_INVENTORY_WINDOW_ID; + if(!isset($this->openHardcodedWindows[$id])){ + //TODO: HACK! this restores 1.14ish behaviour, but this should be able to be listened to and + //controlled by plugins. However, the player is always a subscriber to their own inventory so it + //doesn't integrate well with the regular container system right now. + $this->openHardcodedWindows[$id] = true; + $this->session->sendDataPacket(ContainerOpenPacket::entityInv( + InventoryManager::HARDCODED_INVENTORY_WINDOW_ID, + WindowTypes::INVENTORY, + $this->player->getId() + )); + } + } + public function onCurrentWindowRemove() : void{ if(isset($this->windowMap[$this->lastInventoryNetworkId])){ $this->remove($this->lastInventoryNetworkId); @@ -194,16 +217,18 @@ class InventoryManager{ } public function onClientRemoveWindow(int $id) : void{ - if($id >= self::RESERVED_WINDOW_ID_RANGE_START && $id <= self::RESERVED_WINDOW_ID_RANGE_END){ - //TODO: HACK! crafting grid & main inventory currently use these fake IDs - return; - } - if($id === $this->lastInventoryNetworkId){ + if(isset($this->openHardcodedWindows[$id])){ + unset($this->openHardcodedWindows[$id]); + }elseif($id === $this->lastInventoryNetworkId){ $this->remove($id); $this->player->removeCurrentWindow(); }else{ $this->session->getLogger()->debug("Attempted to close inventory with network ID $id, but current is $this->lastInventoryNetworkId"); } + + //Always send this, even if no window matches. If we told the client to close a window, it will behave as if it + //initiated the close and expect an ack. + $this->session->sendDataPacket(ContainerClosePacket::create($id, false)); } public function syncSlot(Inventory $inventory, int $slot) : void{ diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index d2ae3108e1..5b63aa09d8 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -56,7 +56,6 @@ use pocketmine\network\mcpe\protocol\BossEventPacket; use pocketmine\network\mcpe\protocol\CommandBlockUpdatePacket; use pocketmine\network\mcpe\protocol\CommandRequestPacket; use pocketmine\network\mcpe\protocol\ContainerClosePacket; -use pocketmine\network\mcpe\protocol\ContainerOpenPacket; use pocketmine\network\mcpe\protocol\CraftingEventPacket; use pocketmine\network\mcpe\protocol\EmotePacket; use pocketmine\network\mcpe\protocol\InteractPacket; @@ -92,12 +91,10 @@ use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\UIInventorySlotOffset; use pocketmine\network\mcpe\protocol\types\inventory\UseItemOnEntityTransactionData; use pocketmine\network\mcpe\protocol\types\inventory\UseItemTransactionData; -use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes; use pocketmine\network\mcpe\protocol\types\PlayerAction; use pocketmine\network\PacketHandlingException; use pocketmine\player\Player; use pocketmine\utils\AssumptionFailedError; -use function array_key_exists; use function array_push; use function base64_encode; use function count; @@ -137,15 +134,6 @@ class InGamePacketHandler extends PacketHandler{ /** @var bool */ public $forceMoveSync = false; - /** - * TODO: HACK! This tracks GUIs for inventories that the server considers "always open" so that the client can't - * open them twice. (1.16 hack) - * @var true[] - * @phpstan-var array - * @internal - */ - protected $openHardcodedWindows = []; - private InventoryManager $inventoryManager; public function __construct(Player $player, NetworkSession $session, InventoryManager $inventoryManager){ @@ -488,19 +476,8 @@ class InGamePacketHandler extends PacketHandler{ if($target === null){ return false; } - if( - $packet->action === InteractPacket::ACTION_OPEN_INVENTORY && $target === $this->player && - !array_key_exists($windowId = InventoryManager::HARDCODED_INVENTORY_WINDOW_ID, $this->openHardcodedWindows) - ){ - //TODO: HACK! this restores 1.14ish behaviour, but this should be able to be listened to and - //controlled by plugins. However, the player is always a subscriber to their own inventory so it - //doesn't integrate well with the regular container system right now. - $this->openHardcodedWindows[$windowId] = true; - $this->session->sendDataPacket(ContainerOpenPacket::entityInv( - InventoryManager::HARDCODED_INVENTORY_WINDOW_ID, - WindowTypes::INVENTORY, - $this->player->getId() - )); + if($packet->action === InteractPacket::ACTION_OPEN_INVENTORY && $target === $this->player){ + $this->inventoryManager->onClientOpenMainInventory(); return true; } return false; //TODO @@ -595,13 +572,7 @@ class InGamePacketHandler extends PacketHandler{ public function handleContainerClose(ContainerClosePacket $packet) : bool{ $this->player->doCloseInventory(); - if(array_key_exists($packet->windowId, $this->openHardcodedWindows)){ - unset($this->openHardcodedWindows[$packet->windowId]); - }else{ - $this->inventoryManager->onClientRemoveWindow($packet->windowId); - } - - $this->session->sendDataPacket(ContainerClosePacket::create($packet->windowId, false)); + $this->inventoryManager->onClientRemoveWindow($packet->windowId); return true; } From 6efb1db1076d9b2219653572933e8b834cfc41f5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Nov 2021 23:03:41 +0000 Subject: [PATCH 3162/3224] Fixed inventories not working after dying with inventory open closes #4185 closes #4177 --- src/network/mcpe/NetworkSession.php | 3 ++- src/network/mcpe/handler/DeathPacketHandler.php | 11 ++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index ee7c349971..2fe44e3acb 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -111,6 +111,7 @@ use pocketmine\player\UsedChunkStatus; use pocketmine\player\XboxLivePlayerInfo; use pocketmine\Server; use pocketmine\timings\Timings; +use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\ObjectSet; use pocketmine\utils\TextFormat; use pocketmine\utils\Utils; @@ -714,7 +715,7 @@ class NetworkSession{ public function onServerDeath() : void{ if($this->handler instanceof InGamePacketHandler){ //TODO: this is a bad fix for pre-spawn death, this shouldn't be reachable at all at this stage :( - $this->setHandler(new DeathPacketHandler($this->player, $this)); + $this->setHandler(new DeathPacketHandler($this->player, $this, $this->invManager ?? throw new AssumptionFailedError())); } } diff --git a/src/network/mcpe/handler/DeathPacketHandler.php b/src/network/mcpe/handler/DeathPacketHandler.php index c3421f1a5f..bc56729c9b 100644 --- a/src/network/mcpe/handler/DeathPacketHandler.php +++ b/src/network/mcpe/handler/DeathPacketHandler.php @@ -23,7 +23,9 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\handler; +use pocketmine\network\mcpe\InventoryManager; use pocketmine\network\mcpe\NetworkSession; +use pocketmine\network\mcpe\protocol\ContainerClosePacket; use pocketmine\network\mcpe\protocol\PlayerActionPacket; use pocketmine\network\mcpe\protocol\RespawnPacket; use pocketmine\network\mcpe\protocol\types\PlayerAction; @@ -35,10 +37,12 @@ class DeathPacketHandler extends PacketHandler{ private $player; /** @var NetworkSession */ private $session; + private InventoryManager $inventoryManager; - public function __construct(Player $player, NetworkSession $session){ + public function __construct(Player $player, NetworkSession $session, InventoryManager $inventoryManager){ $this->player = $player; $this->session = $session; + $this->inventoryManager = $inventoryManager; } public function setUp() : void{ @@ -58,6 +62,11 @@ class DeathPacketHandler extends PacketHandler{ return false; } + public function handleContainerClose(ContainerClosePacket $packet) : bool{ + $this->inventoryManager->onClientRemoveWindow($packet->windowId); + return true; + } + public function handleRespawn(RespawnPacket $packet) : bool{ if($packet->respawnState === RespawnPacket::CLIENT_READY_TO_SPAWN){ $this->session->sendDataPacket(RespawnPacket::create( From ab002ca06d459077cf92cf6fcdc551bade341096 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Nov 2021 23:36:58 +0000 Subject: [PATCH 3163/3224] Improved handling of temporary inventory windows evacuation behaviour is now consistent regardless of who is doing it --- src/block/inventory/AnvilInventory.php | 13 ++----------- src/block/inventory/CraftingTableInventory.php | 13 ++----------- src/block/inventory/EnchantInventory.php | 13 ++----------- src/block/inventory/LoomInventory.php | 12 ++---------- src/inventory/PlayerCraftingInventory.php | 2 +- src/inventory/PlayerCursorInventory.php | 2 +- src/player/Player.php | 5 ++++- 7 files changed, 14 insertions(+), 46 deletions(-) diff --git a/src/block/inventory/AnvilInventory.php b/src/block/inventory/AnvilInventory.php index 2e875d3ffd..1def8f913b 100644 --- a/src/block/inventory/AnvilInventory.php +++ b/src/block/inventory/AnvilInventory.php @@ -24,10 +24,10 @@ declare(strict_types=1); namespace pocketmine\block\inventory; use pocketmine\inventory\SimpleInventory; -use pocketmine\player\Player; +use pocketmine\inventory\TemporaryInventory; use pocketmine\world\Position; -class AnvilInventory extends SimpleInventory implements BlockInventory{ +class AnvilInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{ use BlockInventoryTrait; public const SLOT_INPUT = 0; @@ -37,13 +37,4 @@ class AnvilInventory extends SimpleInventory implements BlockInventory{ $this->holder = $holder; parent::__construct(2); } - - public function onClose(Player $who) : void{ - parent::onClose($who); - - foreach($this->getContents() as $item){ - $who->dropItem($item); - } - $this->clearAll(); - } } diff --git a/src/block/inventory/CraftingTableInventory.php b/src/block/inventory/CraftingTableInventory.php index 493e5dec03..a885df4bef 100644 --- a/src/block/inventory/CraftingTableInventory.php +++ b/src/block/inventory/CraftingTableInventory.php @@ -24,23 +24,14 @@ declare(strict_types=1); namespace pocketmine\block\inventory; use pocketmine\crafting\CraftingGrid; -use pocketmine\player\Player; +use pocketmine\inventory\TemporaryInventory; use pocketmine\world\Position; -final class CraftingTableInventory extends CraftingGrid implements BlockInventory{ +final class CraftingTableInventory extends CraftingGrid implements BlockInventory, TemporaryInventory{ use BlockInventoryTrait; public function __construct(Position $holder){ $this->holder = $holder; parent::__construct(CraftingGrid::SIZE_BIG); } - - public function onClose(Player $who) : void{ - parent::onClose($who); - - foreach($this->getContents() as $item){ - $who->dropItem($item); - } - $this->clearAll(); - } } \ No newline at end of file diff --git a/src/block/inventory/EnchantInventory.php b/src/block/inventory/EnchantInventory.php index aafc90caf0..91bfcab5e4 100644 --- a/src/block/inventory/EnchantInventory.php +++ b/src/block/inventory/EnchantInventory.php @@ -24,10 +24,10 @@ declare(strict_types=1); namespace pocketmine\block\inventory; use pocketmine\inventory\SimpleInventory; -use pocketmine\player\Player; +use pocketmine\inventory\TemporaryInventory; use pocketmine\world\Position; -class EnchantInventory extends SimpleInventory implements BlockInventory{ +class EnchantInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{ use BlockInventoryTrait; public const SLOT_INPUT = 0; @@ -37,13 +37,4 @@ class EnchantInventory extends SimpleInventory implements BlockInventory{ $this->holder = $holder; parent::__construct(2); } - - public function onClose(Player $who) : void{ - parent::onClose($who); - - foreach($this->getContents() as $item){ - $who->dropItem($item); - } - $this->clearAll(); - } } diff --git a/src/block/inventory/LoomInventory.php b/src/block/inventory/LoomInventory.php index 24830329a9..8e1a763f10 100644 --- a/src/block/inventory/LoomInventory.php +++ b/src/block/inventory/LoomInventory.php @@ -24,10 +24,11 @@ declare(strict_types=1); namespace pocketmine\block\inventory; use pocketmine\inventory\SimpleInventory; +use pocketmine\inventory\TemporaryInventory; use pocketmine\player\Player; use pocketmine\world\Position; -final class LoomInventory extends SimpleInventory implements BlockInventory{ +final class LoomInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{ use BlockInventoryTrait; public const SLOT_BANNER = 0; @@ -38,13 +39,4 @@ final class LoomInventory extends SimpleInventory implements BlockInventory{ $this->holder = $holder; parent::__construct($size); } - - public function onClose(Player $who) : void{ - parent::onClose($who); - - foreach($this->getContents() as $item){ - $who->dropItem($item); - } - $this->clearAll(); - } } diff --git a/src/inventory/PlayerCraftingInventory.php b/src/inventory/PlayerCraftingInventory.php index 300346476d..d3a8174342 100644 --- a/src/inventory/PlayerCraftingInventory.php +++ b/src/inventory/PlayerCraftingInventory.php @@ -26,7 +26,7 @@ namespace pocketmine\inventory; use pocketmine\crafting\CraftingGrid; use pocketmine\player\Player; -final class PlayerCraftingInventory extends CraftingGrid{ +final class PlayerCraftingInventory extends CraftingGrid implements TemporaryInventory{ public function __construct(private Player $holder){ parent::__construct(CraftingGrid::SIZE_SMALL); diff --git a/src/inventory/PlayerCursorInventory.php b/src/inventory/PlayerCursorInventory.php index 9cd948c589..7c219fd007 100644 --- a/src/inventory/PlayerCursorInventory.php +++ b/src/inventory/PlayerCursorInventory.php @@ -25,7 +25,7 @@ namespace pocketmine\inventory; use pocketmine\player\Player; -class PlayerCursorInventory extends SimpleInventory{ +class PlayerCursorInventory extends SimpleInventory implements TemporaryInventory{ /** @var Player */ protected $holder; diff --git a/src/player/Player.php b/src/player/Player.php index 7f43296b14..b1a4034ba9 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -77,6 +77,7 @@ use pocketmine\inventory\CallbackInventoryListener; use pocketmine\inventory\Inventory; use pocketmine\inventory\PlayerCraftingInventory; use pocketmine\inventory\PlayerCursorInventory; +use pocketmine\inventory\TemporaryInventory; use pocketmine\inventory\transaction\action\DropItemAction; use pocketmine\inventory\transaction\InventoryTransaction; use pocketmine\inventory\transaction\TransactionBuilderInventory; @@ -2322,8 +2323,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ * inventory. */ public function doCloseInventory() : void{ - /** @var Inventory[] $inventories */ $inventories = [$this->craftingGrid, $this->cursorInventory]; + if($this->currentWindow instanceof TemporaryInventory){ + $inventories[] = $this->currentWindow; + } $transaction = new InventoryTransaction($this); $mainInventoryTransactionBuilder = new TransactionBuilderInventory($this->inventory); From 5be429a8c473f32a0595e95adb1cddaa2e8c53eb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Nov 2021 23:48:05 +0000 Subject: [PATCH 3164/3224] Ensure inventories get evacuated on server-side window close --- src/player/Player.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/player/Player.php b/src/player/Player.php index b1a4034ba9..308371af7a 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2399,6 +2399,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } public function removeCurrentWindow() : void{ + $this->doCloseInventory(); if($this->currentWindow !== null){ (new InventoryCloseEvent($this->currentWindow, $this))->call(); From c7beb0a70258fdf5dbba6bf4f93b17cca2a88838 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 8 Nov 2021 23:51:25 +0000 Subject: [PATCH 3165/3224] Clean up inventory auto close mess from PM3 on PM3 there was no concept of 'current window', we had no idea which window the player was actually looking at. --- src/network/mcpe/handler/InGamePacketHandler.php | 4 +--- src/player/Player.php | 10 +++++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 5b63aa09d8..e4553c49be 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -193,7 +193,7 @@ class InGamePacketHandler extends PacketHandler{ //TODO HACK: EATING_ITEM is sent back to the server when the server sends it for other players (1.14 bug, maybe earlier) return $packet->actorRuntimeId === ActorEvent::EATING_ITEM; } - $this->player->doCloseInventory(); + $this->player->removeCurrentWindow(); switch($packet->eventId){ case ActorEvent::EATING_ITEM: //TODO: ignore this and handle it server-side @@ -570,8 +570,6 @@ class InGamePacketHandler extends PacketHandler{ } public function handleContainerClose(ContainerClosePacket $packet) : bool{ - $this->player->doCloseInventory(); - $this->inventoryManager->onClientRemoveWindow($packet->windowId); return true; } diff --git a/src/player/Player.php b/src/player/Player.php index 308371af7a..aab421014e 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1316,7 +1316,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ * as a command. */ public function chat(string $message) : bool{ - $this->doCloseInventory(); + $this->removeCurrentWindow(); $message = TextFormat::clean($message, false); foreach(explode("\n", $message) as $messagePart){ @@ -1572,7 +1572,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ * @return bool if the block was successfully broken, false if a rollback needs to take place. */ public function breakBlock(Vector3 $pos) : bool{ - $this->doCloseInventory(); + $this->removeCurrentWindow(); if($this->canInteract($pos->add(0.5, 0.5, 0.5), $this->isCreative() ? 13 : 7)){ $this->broadcastAnimation(new ArmSwingAnimation($this), $this->getViewers()); @@ -1991,7 +1991,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ //prevent the player receiving their own disconnect message $this->server->unsubscribeFromAllBroadcastChannels($this); - $this->doCloseInventory(); + $this->removeCurrentWindow(); $ev = new PlayerQuitEvent($this, $quitMessage ?? $this->getLeaveMessage(), $reason); $ev->call(); @@ -2104,7 +2104,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ protected function onDeath() : void{ //Crafting grid must always be evacuated even if keep-inventory is true. This dumps the contents into the //main inventory and drops the rest on the ground. - $this->doCloseInventory(); + $this->removeCurrentWindow(); $ev = new PlayerDeathEvent($this, $this->getDrops(), $this->getXpDropAmount(), null); $ev->call(); @@ -2322,7 +2322,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ * @internal Called to clean up crafting grid and cursor inventory when it is detected that the player closed their * inventory. */ - public function doCloseInventory() : void{ + private function doCloseInventory() : void{ $inventories = [$this->craftingGrid, $this->cursorInventory]; if($this->currentWindow instanceof TemporaryInventory){ $inventories[] = $this->currentWindow; From fed59d3ebeac7968eeaab9c7deb62d1f5baf5fe6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 9 Nov 2021 00:11:39 +0000 Subject: [PATCH 3166/3224] added missing file --- src/inventory/TemporaryInventory.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/inventory/TemporaryInventory.php diff --git a/src/inventory/TemporaryInventory.php b/src/inventory/TemporaryInventory.php new file mode 100644 index 0000000000..9e239dcdf9 --- /dev/null +++ b/src/inventory/TemporaryInventory.php @@ -0,0 +1,28 @@ + Date: Tue, 9 Nov 2021 00:20:06 +0000 Subject: [PATCH 3167/3224] CS AGAIN --- src/block/inventory/LoomInventory.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/block/inventory/LoomInventory.php b/src/block/inventory/LoomInventory.php index 8e1a763f10..27a8f2dbc3 100644 --- a/src/block/inventory/LoomInventory.php +++ b/src/block/inventory/LoomInventory.php @@ -25,7 +25,6 @@ namespace pocketmine\block\inventory; use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\TemporaryInventory; -use pocketmine\player\Player; use pocketmine\world\Position; final class LoomInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{ From c3ec9c09480bbc48d417f1731b263b24827abc81 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 9 Nov 2021 01:46:50 +0000 Subject: [PATCH 3168/3224] Effect default duration is once again NOT hardcoded, like PM3 I have no fucking idea why I hardcoded this to begin with. Not one of my better ideas ... --- src/entity/effect/Effect.php | 4 +++- src/entity/effect/InstantEffect.php | 7 +++++-- src/entity/effect/PoisonEffect.php | 4 ++-- src/entity/effect/VanillaEffects.php | 4 ++-- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/entity/effect/Effect.php b/src/entity/effect/Effect.php index b5c385c6f8..3d1bd4c7cf 100644 --- a/src/entity/effect/Effect.php +++ b/src/entity/effect/Effect.php @@ -38,12 +38,14 @@ class Effect{ * @param Translatable|string $name Translation key used for effect name * @param Color $color Color of bubbles given by this effect * @param bool $bad Whether the effect is harmful + * @param int $defaultDuration * @param bool $hasBubbles Whether the effect has potion bubbles. Some do not (e.g. Instant Damage has its own particles instead of bubbles) */ public function __construct( protected Translatable|string $name, protected Color $color, protected bool $bad = false, + private int $defaultDuration = 600, protected bool $hasBubbles = true ){} @@ -73,7 +75,7 @@ class Effect{ * Returns the default duration (in ticks) this effect will apply for if a duration is not specified. */ public function getDefaultDuration() : int{ - return 600; + return $this->defaultDuration; } /** diff --git a/src/entity/effect/InstantEffect.php b/src/entity/effect/InstantEffect.php index 6539259188..ac5852e2f4 100644 --- a/src/entity/effect/InstantEffect.php +++ b/src/entity/effect/InstantEffect.php @@ -23,10 +23,13 @@ declare(strict_types=1); namespace pocketmine\entity\effect; +use pocketmine\color\Color; +use pocketmine\lang\Translatable; + abstract class InstantEffect extends Effect{ - public function getDefaultDuration() : int{ - return 1; + public function __construct(Translatable|string $name, Color $color, bool $bad = false, bool $hasBubbles = true){ + parent::__construct($name, $color, $bad, 1, $hasBubbles); } public function canTick(EffectInstance $instance) : bool{ diff --git a/src/entity/effect/PoisonEffect.php b/src/entity/effect/PoisonEffect.php index 99dffb3afd..e3b1618b5f 100644 --- a/src/entity/effect/PoisonEffect.php +++ b/src/entity/effect/PoisonEffect.php @@ -34,8 +34,8 @@ class PoisonEffect extends Effect{ /** @var bool */ private $fatal; - public function __construct(Translatable|string $name, Color $color, bool $isBad = false, bool $hasBubbles = true, bool $fatal = false){ - parent::__construct($name, $color, $isBad, $hasBubbles); + public function __construct(Translatable|string $name, Color $color, bool $isBad = false, int $defaultDuration = 600, bool $hasBubbles = true, bool $fatal = false){ + parent::__construct($name, $color, $isBad, $defaultDuration, $hasBubbles); $this->fatal = $fatal; } diff --git a/src/entity/effect/VanillaEffects.php b/src/entity/effect/VanillaEffects.php index 50bddc9416..d382a9f60b 100644 --- a/src/entity/effect/VanillaEffects.php +++ b/src/entity/effect/VanillaEffects.php @@ -68,7 +68,7 @@ final class VanillaEffects{ //TODO: bad_omen self::register("blindness", new Effect(KnownTranslationFactory::potion_blindness(), new Color(0x1f, 0x1f, 0x23), true)); self::register("conduit_power", new Effect(KnownTranslationFactory::potion_conduitPower(), new Color(0x1d, 0xc2, 0xd1))); - self::register("fatal_poison", new PoisonEffect(KnownTranslationFactory::potion_poison(), new Color(0x4e, 0x93, 0x31), true, true, true)); + self::register("fatal_poison", new PoisonEffect(KnownTranslationFactory::potion_poison(), new Color(0x4e, 0x93, 0x31), true, 600, true, true)); self::register("fire_resistance", new Effect(KnownTranslationFactory::potion_fireResistance(), new Color(0xe4, 0x9a, 0x3a))); self::register("haste", new Effect(KnownTranslationFactory::potion_digSpeed(), new Color(0xd9, 0xc0, 0x43))); self::register("health_boost", new HealthBoostEffect(KnownTranslationFactory::potion_healthBoost(), new Color(0xf8, 0x7d, 0x23))); @@ -84,7 +84,7 @@ final class VanillaEffects{ self::register("poison", new PoisonEffect(KnownTranslationFactory::potion_poison(), new Color(0x4e, 0x93, 0x31), true)); self::register("regeneration", new RegenerationEffect(KnownTranslationFactory::potion_regeneration(), new Color(0xcd, 0x5c, 0xab))); self::register("resistance", new Effect(KnownTranslationFactory::potion_resistance(), new Color(0x99, 0x45, 0x3a))); - self::register("saturation", new SaturationEffect(KnownTranslationFactory::potion_saturation(), new Color(0xf8, 0x24, 0x23), false)); + self::register("saturation", new SaturationEffect(KnownTranslationFactory::potion_saturation(), new Color(0xf8, 0x24, 0x23))); //TODO: slow_falling self::register("slowness", new SlownessEffect(KnownTranslationFactory::potion_moveSlowdown(), new Color(0x5a, 0x6c, 0x81), true)); self::register("speed", new SpeedEffect(KnownTranslationFactory::potion_moveSpeed(), new Color(0x7c, 0xaf, 0xc6))); From 635a9143de62e69c6811ef4bc9cb65933b166cd7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 9 Nov 2021 16:50:42 +0000 Subject: [PATCH 3169/3224] Release 4.0.0-BETA12 --- changelogs/4.0.md | 69 +++++++++++++++++++++++++++++++++++++++++++++ src/VersionInfo.php | 2 +- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index 9e9faad628..a3f4e67204 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1634,3 +1634,72 @@ Released 6th November 2021. ### Gameplay - Chunks are now sent in proper circles. This improves the experience when flying quickly parallel to X or Z axis, since now more chunks in front of the player will load sooner. - Added support for emotes. + +# 4.0.0-BETA12 +Released 9th November 2021. + +## General +- Introduced support for connecting via IPv6. + - PHP binary used must now always be built with IPv6 support, even if IPv6 is disabled. This is because RakNet may still send link-local IPv6 loopback addresses in connection packets even when only using IPv4. + - The default port for IPv6 is `19133` (similar to Bedrock Dedicated Server). + - Port `19133` is used by default so that Minecraft Bedrock can detect IPv6 servers on LAN. + - GS4 Query is supported on both IPv4 and IPv6 according to `server.properties` settings. + - The following `server.properties` settings are influential: + - `enable-ipv6`: `on` by default. Disabling this completely disables IPv6 support. + - `server-ipv6`: `::` by default (equivalent to "any IP", like `0.0.0.0` for IPv4). Most users shouldn't need to change this setting, and it doesn't appear in `server.properties` by default. + - `server-portv6`: `19133` by default. You may run both IPv4 and IPv6 on the same port. +- Various internal changes have been made to prepare for negative Y axis support (upcoming 1.18). + +## Fixes +- Fixed resource packs not applying. +- Fixed inventory windows being unopenable after dying with inventory windows open. +- Fixed plugins being able to alter other plugins' permission defaults by redeclaring them in the `plugin.yml`. + +## API +### Block +- `VanillaBlocks::fromString()` has been removed. +- Added `CraftingTableInventory`. This exclusively represents a crafting table's 3x3 crafting grid. + +### Crafting +- `CraftingGrid` is now abstract. +- Removed `CraftingGrid->getHolder()`. +- The constructor of `CraftingGrid` no longer accepts a `Player` parameter. + +### Entity +#### Effect +- `Effect->__construct()` once again accepts an `int $defaultDuration` parameter. +- Removed `VanillaEffects::fromString()`. +- Added `StringToEffectParser` + - Supports custom aliases! + - This is used by `/effect` to provide name support. + +### Event +- `InventoryOpenEvent` is now fired when a player opens a crafting table's UI. +- `InventoryCloseEvent` is now fired when a player closes a crafting table's UI. +- `PlayerDropItemEvent` will now prevent the drops from force-closing of the following inventories: + - anvil + - enchanting table + - loom + +### Inventory +- Added `TemporaryInventory`. This should be implemented by any inventory whose contents should be evacuated when closing. +- Added `PlayerCraftingInventory`. This exclusively represents the player's own 2x2 crafting grid. + +### Item +- Removed `VanillaItems::fromString()` + - Obsoleted by the far superior, much more dynamic, and plugin-customizable `StringToItemParser`. + - `StringToItemParser` allows mapping strings to closure callbacks, allowing you to create aliases for `/give` for any item, including custom ones. + +#### Enchantment +- Removed `VanillaEnchantments::fromString()`. +- Added `StringToEnchantmentParser` + - Supports custom aliases! + - This is used by `/enchant` to provide name support. + +### Player +- Removed `Player->setCraftingGrid()`. To open a 3x3 crafting grid to a player, use `setCurrentWindow(new CraftingTableInventory)`. + +### Server +- Added the following API methods: + - `Server->getIpV6()` + - `Server->getPortV6()` \ No newline at end of file diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 5216a66505..1e7d35d7f6 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -30,7 +30,7 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; public const BASE_VERSION = "4.0.0-BETA12"; - public const IS_DEVELOPMENT_BUILD = true; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_NUMBER = 0; public const BUILD_CHANNEL = "beta"; From 73592349cd29d91b03c2703107db859115a92e2d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 9 Nov 2021 16:50:46 +0000 Subject: [PATCH 3170/3224] 4.0.0-BETA13 is next --- src/VersionInfo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 1e7d35d7f6..ee43667629 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -29,8 +29,8 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "4.0.0-BETA12"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "4.0.0-BETA13"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_NUMBER = 0; public const BUILD_CHANNEL = "beta"; From 49a8eff11ea85494b6e830ad03d9c197facb05ed Mon Sep 17 00:00:00 2001 From: Dylan T Date: Thu, 11 Nov 2021 14:29:56 +0000 Subject: [PATCH 3171/3224] BUILDING: submodules are no longer required submodules are useful (e.g. devtools, build/php) but they are not required to build a server phar. --- BUILDING.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/BUILDING.md b/BUILDING.md index 155896a935..d6e97e05c7 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -14,13 +14,12 @@ Because PocketMine-MP requires several non-standard PHP extensions and configura If you use a custom binary, you'll need to replace `composer` usages in this guide with `path/to/your/php path/to/your/composer.phar`. ## Setting up environment -1. `git clone --recursive https://github.com/pmmp/PocketMine-MP.git` +1. `git clone https://github.com/pmmp/PocketMine-MP.git` 2. `composer install` ## Checking out a different branch to build 1. `git checkout ` -2. `git submodule update --init` -3. Re-run `composer install` to synchronize dependencies. +2. Re-run `composer install` to synchronize dependencies. ## Optimizing for release builds 1. Add the flags `--no-dev --classmap-authoritative` to your `composer install` command. This will reduce build size and improve autoloading speed. From 3276047497b5be206b7288c3668b5f8f53813fae Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 12 Nov 2021 00:13:22 +0000 Subject: [PATCH 3172/3224] Updated composer dependencies --- composer.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/composer.lock b/composer.lock index b8a2d17d2a..1316f2f843 100644 --- a/composer.lock +++ b/composer.lock @@ -275,16 +275,16 @@ }, { "name": "pocketmine/bedrock-protocol", - "version": "5.1.0+bedrock-1.17.40", + "version": "5.1.2+bedrock-1.17.40", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "5abbe5bc21d8a9152d46c26578bf5257526612f9" + "reference": "5f600ce446f357391968c8ce92e3be989aa1dc9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/5abbe5bc21d8a9152d46c26578bf5257526612f9", - "reference": "5abbe5bc21d8a9152d46c26578bf5257526612f9", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/5f600ce446f357391968c8ce92e3be989aa1dc9e", + "reference": "5f600ce446f357391968c8ce92e3be989aa1dc9e", "shasum": "" }, "require": { @@ -316,9 +316,9 @@ "description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP", "support": { "issues": "https://github.com/pmmp/BedrockProtocol/issues", - "source": "https://github.com/pmmp/BedrockProtocol/tree/5.1.0+bedrock-1.17.40" + "source": "https://github.com/pmmp/BedrockProtocol/tree/5.1.2+bedrock-1.17.40" }, - "time": "2021-11-08T16:26:25+00:00" + "time": "2021-11-10T13:53:03+00:00" }, { "name": "pocketmine/binaryutils", @@ -2916,16 +2916,16 @@ }, { "name": "sebastian/exporter", - "version": "4.0.3", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65" + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d89cc98761b8cb5a1a235a6b703ae50d34080e65", - "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", "shasum": "" }, "require": { @@ -2974,14 +2974,14 @@ } ], "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", + "homepage": "https://www.github.com/sebastianbergmann/exporter", "keywords": [ "export", "exporter" ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.3" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" }, "funding": [ { @@ -2989,7 +2989,7 @@ "type": "github" } ], - "time": "2020-09-28T05:24:23+00:00" + "time": "2021-11-11T14:18:36+00:00" }, { "name": "sebastian/global-state", From e4754ab029c6acc9c82fe18fef0b08f9a161ae71 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 12 Nov 2021 00:16:53 +0000 Subject: [PATCH 3173/3224] PluginBase: Improved error messages for commands containing illegal characters --- composer.json | 2 +- composer.lock | 14 +++++++------- src/lang/KnownTranslationFactory.php | 6 ++++-- src/plugin/PluginBase.php | 4 ++-- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/composer.json b/composer.json index 9e9f75a66f..e9eaa10090 100644 --- a/composer.json +++ b/composer.json @@ -41,7 +41,7 @@ "pocketmine/classloader": "^0.2.0", "pocketmine/color": "^0.2.0", "pocketmine/errorhandler": "^0.3.0", - "pocketmine/locale-data": "^1.1.4", + "pocketmine/locale-data": "^2.0.16", "pocketmine/log": "^0.4.0", "pocketmine/log-pthreads": "^0.4.0", "pocketmine/math": "^0.4.0", diff --git a/composer.lock b/composer.lock index 1316f2f843..d112e624c9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4f8e023ae390414fb40b77857c16ebee", + "content-hash": "7787453a7902c21ea0d15aee34b12019", "packages": [ { "name": "adhocore/json-comment", @@ -533,16 +533,16 @@ }, { "name": "pocketmine/locale-data", - "version": "1.1.6", + "version": "2.0.16", "source": { "type": "git", "url": "https://github.com/pmmp/Language.git", - "reference": "216b49b87e20332f0b39d1717e1e2012a40074cc" + "reference": "8bd74825ac685446f67ea20999ce756a2acd5a30" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Language/zipball/216b49b87e20332f0b39d1717e1e2012a40074cc", - "reference": "216b49b87e20332f0b39d1717e1e2012a40074cc", + "url": "https://api.github.com/repos/pmmp/Language/zipball/8bd74825ac685446f67ea20999ce756a2acd5a30", + "reference": "8bd74825ac685446f67ea20999ce756a2acd5a30", "shasum": "" }, "type": "library", @@ -550,9 +550,9 @@ "description": "Language resources used by PocketMine-MP", "support": { "issues": "https://github.com/pmmp/Language/issues", - "source": "https://github.com/pmmp/Language/tree/1.1.6" + "source": "https://github.com/pmmp/Language/tree/2.0.16" }, - "time": "2021-11-07T14:30:46+00:00" + "time": "2021-11-12T00:10:09+00:00" }, { "name": "pocketmine/log", diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index 7d36320c2a..35418d18cd 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -1666,10 +1666,11 @@ final class KnownTranslationFactory{ ]); } - public static function pocketmine_plugin_aliasError(Translatable|string $param0, Translatable|string $param1) : Translatable{ + public static function pocketmine_plugin_aliasError(Translatable|string $param0, Translatable|string $param1, Translatable|string $param2) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_ALIASERROR, [ 0 => $param0, 1 => $param1, + 2 => $param2, ]); } @@ -1689,10 +1690,11 @@ final class KnownTranslationFactory{ return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_CIRCULARDEPENDENCY, []); } - public static function pocketmine_plugin_commandError(Translatable|string $param0, Translatable|string $param1) : Translatable{ + public static function pocketmine_plugin_commandError(Translatable|string $param0, Translatable|string $param1, Translatable|string $param2) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_PLUGIN_COMMANDERROR, [ 0 => $param0, 1 => $param1, + 2 => $param2, ]); } diff --git a/src/plugin/PluginBase.php b/src/plugin/PluginBase.php index db29c40da2..7af6c3492c 100644 --- a/src/plugin/PluginBase.php +++ b/src/plugin/PluginBase.php @@ -164,7 +164,7 @@ abstract class PluginBase implements Plugin, CommandExecutor{ foreach($this->getDescription()->getCommands() as $key => $data){ if(strpos($key, ":") !== false){ - $this->logger->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_commandError($key, $this->getDescription()->getFullName()))); + $this->logger->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_commandError($key, $this->getDescription()->getFullName(), ":"))); continue; } @@ -180,7 +180,7 @@ abstract class PluginBase implements Plugin, CommandExecutor{ $aliasList = []; foreach($data->getAliases() as $alias){ if(strpos($alias, ":") !== false){ - $this->logger->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_aliasError($alias, $this->getDescription()->getFullName()))); + $this->logger->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_aliasError($alias, $this->getDescription()->getFullName(), ":"))); continue; } $aliasList[] = $alias; From 399824c31c0986459bac3cbb828c04a7a75a5519 Mon Sep 17 00:00:00 2001 From: Covered123 <58715544+JavierLeon9966@users.noreply.github.com> Date: Sun, 14 Nov 2021 11:15:36 -0300 Subject: [PATCH 3174/3224] Add correct drop for Podzol (#4573) --- src/block/Podzol.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/block/Podzol.php b/src/block/Podzol.php index 8da535c545..0eeba12c80 100644 --- a/src/block/Podzol.php +++ b/src/block/Podzol.php @@ -23,6 +23,13 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\item\Item; + class Podzol extends Opaque{ + public function getDropsForCompatibleTool(Item $item) : array{ + return [ + VanillaBlocks::DIRT()->asItem() + ]; + } } From d4a382d56837a6cc5cd6f8de9dc9fa632ea6648f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=AD=E3=82=89=E3=81=B2=E3=81=8B=E3=81=A0?= Date: Mon, 15 Nov 2021 00:40:20 +0900 Subject: [PATCH 3175/3224] Fix position of setworldspawn command (#4574) * The world spawn position is no longer rounded * Remove round() since the position is always int --- src/command/defaults/SetWorldSpawnCommand.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/command/defaults/SetWorldSpawnCommand.php b/src/command/defaults/SetWorldSpawnCommand.php index 9bd37db988..1257e388fd 100644 --- a/src/command/defaults/SetWorldSpawnCommand.php +++ b/src/command/defaults/SetWorldSpawnCommand.php @@ -32,7 +32,6 @@ use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; use function count; -use function round; class SetWorldSpawnCommand extends VanillaCommand{ @@ -54,7 +53,7 @@ class SetWorldSpawnCommand extends VanillaCommand{ if($sender instanceof Player){ $location = $sender->getPosition(); $world = $location->getWorld(); - $pos = $location->asVector3()->round(); + $pos = $location->asVector3()->floor(); }else{ $sender->sendMessage(TextFormat::RED . "You can only perform this command as a player"); @@ -69,7 +68,7 @@ class SetWorldSpawnCommand extends VanillaCommand{ $world->setSpawnLocation($pos); - Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_setworldspawn_success((string) round($pos->x, 2), (string) round($pos->y, 2), (string) round($pos->z, 2))); + Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_setworldspawn_success((string) $pos->x, (string) $pos->y, (string) $pos->z)); return true; } From 639867a64027b3cf7a8c30183c9f203b484de4e5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 14 Nov 2021 15:51:41 +0000 Subject: [PATCH 3176/3224] Added missing aliases for wooden items --- src/item/StringToItemParser.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/item/StringToItemParser.php b/src/item/StringToItemParser.php index 0d92ec4289..f79f059396 100644 --- a/src/item/StringToItemParser.php +++ b/src/item/StringToItemParser.php @@ -214,6 +214,7 @@ final class StringToItemParser extends StringToTParser{ $result->registerBlock("dark_oak_sign", fn() => VanillaBlocks::DARK_OAK_SIGN()); $result->registerBlock("dark_oak_slab", fn() => VanillaBlocks::DARK_OAK_SLAB()); $result->registerBlock("dark_oak_stairs", fn() => VanillaBlocks::DARK_OAK_STAIRS()); + $result->registerBlock("dark_oak_standing_sign", fn() => VanillaBlocks::DARK_OAK_SIGN()); $result->registerBlock("dark_oak_trapdoor", fn() => VanillaBlocks::DARK_OAK_TRAPDOOR()); $result->registerBlock("dark_oak_wall_sign", fn() => VanillaBlocks::DARK_OAK_WALL_SIGN()); $result->registerBlock("dark_oak_wood", fn() => VanillaBlocks::DARK_OAK_WOOD()); @@ -609,6 +610,8 @@ final class StringToItemParser extends StringToTParser{ $result->registerBlock("jungle_trapdoor", fn() => VanillaBlocks::JUNGLE_TRAPDOOR()); $result->registerBlock("jungle_wall_sign", fn() => VanillaBlocks::JUNGLE_WALL_SIGN()); $result->registerBlock("jungle_wood", fn() => VanillaBlocks::JUNGLE_WOOD()); + $result->registerBlock("jungle_wood_stairs", fn() => VanillaBlocks::JUNGLE_STAIRS()); + $result->registerBlock("jungle_wooden_stairs", fn() => VanillaBlocks::JUNGLE_STAIRS()); $result->registerBlock("lab_table", fn() => VanillaBlocks::LAB_TABLE()); $result->registerBlock("ladder", fn() => VanillaBlocks::LADDER()); $result->registerBlock("lantern", fn() => VanillaBlocks::LANTERN()); @@ -695,6 +698,7 @@ final class StringToItemParser extends StringToTParser{ $result->registerBlock("oak_sign", fn() => VanillaBlocks::OAK_SIGN()); $result->registerBlock("oak_slab", fn() => VanillaBlocks::OAK_SLAB()); $result->registerBlock("oak_stairs", fn() => VanillaBlocks::OAK_STAIRS()); + $result->registerBlock("oak_standing_sign", fn() => VanillaBlocks::OAK_SIGN()); $result->registerBlock("oak_trapdoor", fn() => VanillaBlocks::OAK_TRAPDOOR()); $result->registerBlock("oak_wall_sign", fn() => VanillaBlocks::OAK_WALL_SIGN()); $result->registerBlock("oak_wood", fn() => VanillaBlocks::OAK_WOOD()); From 3dd03075cbed0a22ac862b3ee21f5eac6419f352 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 14 Nov 2021 15:52:50 +0000 Subject: [PATCH 3177/3224] StringToItemParser: added some quality-of-life aliases --- src/item/StringToItemParser.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/item/StringToItemParser.php b/src/item/StringToItemParser.php index f79f059396..df0b8944f9 100644 --- a/src/item/StringToItemParser.php +++ b/src/item/StringToItemParser.php @@ -158,6 +158,7 @@ final class StringToItemParser extends StringToTParser{ $result->registerBlock("chemical_heat", fn() => VanillaBlocks::CHEMICAL_HEAT()); $result->registerBlock("chemistry_table", fn() => VanillaBlocks::COMPOUND_CREATOR()); $result->registerBlock("chest", fn() => VanillaBlocks::CHEST()); + $result->registerBlock("chipped_anvil", fn() => VanillaBlocks::ANVIL()->setDamage(1)); $result->registerBlock("chiseled_quartz", fn() => VanillaBlocks::CHISELED_QUARTZ()); $result->registerBlock("chiseled_red_sandstone", fn() => VanillaBlocks::CHISELED_RED_SANDSTONE()); $result->registerBlock("chiseled_sandstone", fn() => VanillaBlocks::CHISELED_SANDSTONE()); @@ -165,6 +166,7 @@ final class StringToItemParser extends StringToTParser{ $result->registerBlock("clay_block", fn() => VanillaBlocks::CLAY()); $result->registerBlock("coal_block", fn() => VanillaBlocks::COAL()); $result->registerBlock("coal_ore", fn() => VanillaBlocks::COAL_ORE()); + $result->registerBlock("coarse_dirt", fn() => VanillaBlocks::DIRT()->setCoarse(true)); $result->registerBlock("cobble", fn() => VanillaBlocks::COBBLESTONE()); $result->registerBlock("cobble_stairs", fn() => VanillaBlocks::COBBLESTONE_STAIRS()); $result->registerBlock("cobble_wall", fn() => VanillaBlocks::COBBLESTONE_WALL()); @@ -200,6 +202,7 @@ final class StringToItemParser extends StringToTParser{ $result->registerBlock("cut_sandstone", fn() => VanillaBlocks::CUT_SANDSTONE()); $result->registerBlock("cut_sandstone_slab", fn() => VanillaBlocks::CUT_SANDSTONE_SLAB()); $result->registerBlock("cyan_glazed_terracotta", fn() => VanillaBlocks::CYAN_GLAZED_TERRACOTTA()); + $result->registerBlock("damaged_anvil", fn() => VanillaBlocks::ANVIL()->setDamage(2)); $result->registerBlock("dandelion", fn() => VanillaBlocks::DANDELION()); $result->registerBlock("dark_oak_button", fn() => VanillaBlocks::DARK_OAK_BUTTON()); $result->registerBlock("dark_oak_door", fn() => VanillaBlocks::DARK_OAK_DOOR()); From 2f408708f011319366ac5606740c2bf4f69eb90f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 14 Nov 2021 16:27:47 +0000 Subject: [PATCH 3178/3224] Explosion: fixed blocks with tiles not using said tiles for drop info closes #4571 --- src/world/Explosion.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/world/Explosion.php b/src/world/Explosion.php index 86d9eeb800..4fc1a1fb07 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -134,8 +134,7 @@ class Explosion{ $blastForce -= ($blastResistance / 5 + 0.3) * $this->stepLen; if($blastForce > 0){ if(!isset($this->affectedBlocks[World::blockHash($vBlockX, $vBlockY, $vBlockZ)])){ - $_block = $blockFactory->fromFullBlock($state); - $_block->position($this->world, $vBlockX, $vBlockY, $vBlockZ); + $_block = $this->world->getBlockAt($vBlockX, $vBlockY, $vBlockZ, true, false); foreach($_block->getAffectedBlocks() as $_affectedBlock){ $_affectedBlockPos = $_affectedBlock->getPosition(); $this->affectedBlocks[World::blockHash($_affectedBlockPos->x, $_affectedBlockPos->y, $_affectedBlockPos->z)] = $_affectedBlock; From 65247b7248bdee0f26a620cdcb06400ce839d980 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 14 Nov 2021 16:41:57 +0000 Subject: [PATCH 3179/3224] changelog: add notes about ender inventory closes #4569 --- changelogs/4.0.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index a3f4e67204..5dccaed82d 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -313,6 +313,10 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` ### Entity #### General - `Entity` no longer extends from `Location`. `Entity->getLocation()` and `Entity->getPosition()` should be used instead. +- Ender inventory has been refactored. It's now split into two parts: + - `EnderChestInventory` is a temporary gateway "inventory" that acts as a proxy to the player's ender inventory. It has a `Position` for holder. This is discarded when the player closes the inventory window. + - `PlayerEnderInventory` is the storage part. This is stored in `Human` and does not contain any block info. + - To open the player's ender inventory, use `Player->setCurrentWindow(new EnderChestInventory($blockPos, $player->getEnderInventory()))`. - The following public fields have been removed: - `Entity->chunk`: Entities no longer know which chunk they are in (the `World` now manages this instead). - `Entity->height`: moved to `EntitySizeInfo`; use `Entity->size` instead @@ -351,6 +355,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Human->getMaxFood()` -> `HungerManager->getMaxFood()` - `Human->addFood()` -> `HungerManager->addFood()` - `Human->isHungry()` -> `HungerManager->isHungry()` + - `Human->getEnderChestInventory()` -> `Human->getEnderInventory()` - `Human->getSaturation()` -> `HungerManager->getSaturation()` - `Human->setSaturation()` -> `HungerManager->setSaturation()` - `Human->addSaturation()` -> `HungerManager->addSaturation()` @@ -564,6 +569,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `CallbackInventoryChangeListener` - `CreativeInventory`: contains the creative functionality previously embedded in `pocketmine\item\Item`, see Item changes for details - `InventoryChangeListener`: allows listening (but not interfering with) events in an inventory. + - `PlayerEnderInventory`: represents the pure storage part of the player's ender inventory, without any block information - `transaction\CreateItemAction` - `transaction\DestroyItemAction` - The following classes have been renamed / moved: @@ -588,6 +594,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - The following API methods have been removed: - `BaseInventory->getDefaultSize()` - `BaseInventory->setSize()` + - `EnderChestInventory->setHolderPosition()` - `Inventory->close()` - `Inventory->dropContents()` - `Inventory->getName()` From f2d5455c5e512939478baf83c7ca7807f56509bf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 14 Nov 2021 16:42:35 +0000 Subject: [PATCH 3180/3224] changelog: mention that armor right-click equipping is now supported [ci skip] closes #4570 --- changelogs/4.0.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index 5dccaed82d..12fa5c9a6d 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1283,6 +1283,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - Implemented offhand inventory. - Block-picking is now supported in survival mode. - Block picking behaviour now matches vanilla (no longer overwrites held item, jumps to existing item where possible). +- Armor can now be equipped by right-clicking while holding it. # 4.0.0-BETA2 Released 10th September 2021. From 4cad552909e50b565af731d0a49201a2a41cef2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=AD=E3=82=89=E3=81=B2=E3=81=8B=E3=81=A0?= Date: Mon, 15 Nov 2021 05:07:37 +0900 Subject: [PATCH 3181/3224] Allow input of relative coordinates to setworldspawn command (#4575) --- src/command/defaults/SetWorldSpawnCommand.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/command/defaults/SetWorldSpawnCommand.php b/src/command/defaults/SetWorldSpawnCommand.php index 1257e388fd..96582a3490 100644 --- a/src/command/defaults/SetWorldSpawnCommand.php +++ b/src/command/defaults/SetWorldSpawnCommand.php @@ -31,6 +31,7 @@ use pocketmine\math\Vector3; use pocketmine\permission\DefaultPermissionNames; use pocketmine\player\Player; use pocketmine\utils\TextFormat; +use pocketmine\world\World; use function count; class SetWorldSpawnCommand extends VanillaCommand{ @@ -60,8 +61,18 @@ class SetWorldSpawnCommand extends VanillaCommand{ return true; } }elseif(count($args) === 3){ - $world = $sender->getServer()->getWorldManager()->getDefaultWorld(); - $pos = new Vector3($this->getInteger($sender, $args[0]), $this->getInteger($sender, $args[1]), $this->getInteger($sender, $args[2])); + if($sender instanceof Player){ + $base = $sender->getPosition(); + $world = $base->getWorld(); + }else{ + $base = new Vector3(0.0, 0.0, 0.0); + $world = $sender->getServer()->getWorldManager()->getDefaultWorld(); + } + $pos = (new Vector3( + $this->getRelativeDouble($base->x, $sender, $args[0]), + $this->getRelativeDouble($base->y, $sender, $args[1], World::Y_MIN, World::Y_MAX), + $this->getRelativeDouble($base->z, $sender, $args[2]), + ))->floor(); }else{ throw new InvalidCommandSyntaxException(); } From 269231c2283375b7a1794a0d03c1e1b05b9dcf4a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 15 Nov 2021 22:52:05 +0000 Subject: [PATCH 3182/3224] Ban foreach(arrayWithStringKeys as k => v) this is not as good as phpstan/phpstan-src#769 (e.g. array_key_first()/array_key_last() aren't covered by this, nor is array_rand()) but it does eliminate the most infuriating cases where this usually crops up. --- build/generate-known-translation-apis.php | 5 +- build/make-release.php | 3 +- phpstan.neon.dist | 1 + src/MemoryManager.php | 2 +- src/Server.php | 2 +- src/crash/CrashDump.php | 2 +- src/network/mcpe/convert/ItemTranslator.php | 3 +- src/network/query/QueryInfo.php | 2 +- src/permission/PermissibleInternal.php | 8 +- src/permission/PermissionParser.php | 3 +- src/plugin/PluginBase.php | 3 +- src/plugin/PluginLoadabilityChecker.php | 2 +- src/plugin/PluginManager.php | 10 +-- src/stats/SendUsageTask.php | 4 +- src/utils/Config.php | 6 +- src/utils/Filesystem.php | 3 +- src/utils/StringToTParser.php | 2 +- src/utils/Utils.php | 16 ++++ src/wizard/SetupWizard.php | 3 +- src/world/format/io/WorldProviderManager.php | 3 +- src/world/generator/GeneratorManager.php | 2 +- .../rules/UnsafeForeachArrayOfStringRule.php | 90 +++++++++++++++++++ tools/generate-permission-doc.php | 3 +- tools/simulate-chunk-selector.php | 5 +- 24 files changed, 150 insertions(+), 33 deletions(-) create mode 100644 tests/phpstan/rules/UnsafeForeachArrayOfStringRule.php diff --git a/build/generate-known-translation-apis.php b/build/generate-known-translation-apis.php index b2703b5136..feee9b1830 100644 --- a/build/generate-known-translation-apis.php +++ b/build/generate-known-translation-apis.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\build\generate_known_translation_apis; use pocketmine\lang\Translatable; +use pocketmine\utils\Utils; use Webmozart\PathUtil\Path; use function array_map; use function count; @@ -100,7 +101,7 @@ final class KnownTranslationKeys{ HEADER; ksort($languageDefinitions, SORT_STRING); - foreach($languageDefinitions as $k => $_){ + foreach(Utils::stringifyKeys($languageDefinitions) as $k => $_){ echo "\tpublic const "; echo constantify($k); echo " = \"" . $k . "\";\n"; @@ -135,7 +136,7 @@ HEADER; $parameterRegex = '/{%(.+?)}/'; $translationContainerClass = (new \ReflectionClass(Translatable::class))->getShortName(); - foreach($languageDefinitions as $key => $value){ + foreach(Utils::stringifyKeys($languageDefinitions) as $key => $value){ $parameters = []; if(preg_match_all($parameterRegex, $value, $matches) > 0){ foreach($matches[1] as $parameterName){ diff --git a/build/make-release.php b/build/make-release.php index 90961c3929..e3a3dad816 100644 --- a/build/make-release.php +++ b/build/make-release.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\build\make_release; +use pocketmine\utils\Utils; use pocketmine\utils\VersionString; use pocketmine\VersionInfo; use function array_keys; @@ -76,7 +77,7 @@ const ACCEPTED_OPTS = [ function main() : void{ $filteredOpts = []; - foreach(getopt("", ["current:", "next:", "channel:", "help"]) as $optName => $optValue){ + foreach(Utils::stringifyKeys(getopt("", ["current:", "next:", "channel:", "help"])) as $optName => $optValue){ if($optName === "help"){ fwrite(STDOUT, "Options:\n"); diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 9da6fe3520..6fec9cfa9b 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -13,6 +13,7 @@ includes: rules: - pocketmine\phpstan\rules\DisallowEnumComparisonRule + - pocketmine\phpstan\rules\UnsafeForeachArrayOfStringRule # - pocketmine\phpstan\rules\ThreadedSupportedTypesRule parameters: diff --git a/src/MemoryManager.php b/src/MemoryManager.php index f456479694..9c2642b262 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -368,7 +368,7 @@ class MemoryManager{ '_SESSION' => true ]; - foreach($GLOBALS as $varName => $value){ + foreach(Utils::stringifyKeys($GLOBALS) as $varName => $value){ if(isset($ignoredGlobals[$varName])){ continue; } diff --git a/src/Server.php b/src/Server.php index b384c29572..628c9a3113 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1201,7 +1201,7 @@ class Server{ * Unsubscribes from all broadcast channels. */ public function unsubscribeFromAllBroadcastChannels(CommandSender $subscriber) : void{ - foreach($this->broadcastSubscribers as $channelId => $recipients){ + foreach(Utils::stringifyKeys($this->broadcastSubscribers) as $channelId => $recipients){ $this->unsubscribeFromBroadcastChannel($channelId, $subscriber); } } diff --git a/src/crash/CrashDump.php b/src/crash/CrashDump.php index 1d595402e4..2719e317c0 100644 --- a/src/crash/CrashDump.php +++ b/src/crash/CrashDump.php @@ -350,7 +350,7 @@ class CrashDump{ $this->addLine("Zend version: " . zend_version()); $this->addLine("OS: " . PHP_OS . ", " . Utils::getOS()); $this->addLine("Composer libraries: "); - foreach($composerLibraries as $library => $libraryVersion){ + foreach(Utils::stringifyKeys($composerLibraries) as $library => $libraryVersion){ $this->addLine("- $library $libraryVersion"); } } diff --git a/src/network/mcpe/convert/ItemTranslator.php b/src/network/mcpe/convert/ItemTranslator.php index bffa6cb180..dd1dc9cd2b 100644 --- a/src/network/mcpe/convert/ItemTranslator.php +++ b/src/network/mcpe/convert/ItemTranslator.php @@ -27,6 +27,7 @@ use pocketmine\data\bedrock\LegacyItemIdToStringIdMap; use pocketmine\network\mcpe\protocol\serializer\ItemTypeDictionary; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\SingletonTrait; +use pocketmine\utils\Utils; use Webmozart\PathUtil\Path; use function array_key_exists; use function file_get_contents; @@ -92,7 +93,7 @@ final class ItemTranslator{ } $simpleMappings[$newId] = $intId; } - foreach($legacyStringToIntMap->getStringToLegacyMap() as $stringId => $intId){ + foreach(Utils::stringifyKeys($legacyStringToIntMap->getStringToLegacyMap()) as $stringId => $intId){ if(isset($simpleMappings[$stringId])){ throw new \UnexpectedValueException("Old ID $stringId collides with new ID"); } diff --git a/src/network/query/QueryInfo.php b/src/network/query/QueryInfo.php index b6cb199cae..559f9a6531 100644 --- a/src/network/query/QueryInfo.php +++ b/src/network/query/QueryInfo.php @@ -233,7 +233,7 @@ final class QueryInfo{ $query .= $key . "\x00" . $value . "\x00"; } - foreach($this->extraData as $key => $value){ + foreach(Utils::stringifyKeys($this->extraData) as $key => $value){ $query .= $key . "\x00" . $value . "\x00"; } diff --git a/src/permission/PermissibleInternal.php b/src/permission/PermissibleInternal.php index 0d14d79436..14cb0ba1ad 100644 --- a/src/permission/PermissibleInternal.php +++ b/src/permission/PermissibleInternal.php @@ -27,6 +27,7 @@ use pocketmine\plugin\Plugin; use pocketmine\plugin\PluginException; use pocketmine\timings\Timings; use pocketmine\utils\ObjectSet; +use pocketmine\utils\Utils; use function count; use function spl_object_id; @@ -143,7 +144,7 @@ class PermissibleInternal implements Permissible{ $oldPermissions = $this->permissions; $this->permissions = []; - foreach($this->rootPermissions as $name => $isGranted){ + foreach(Utils::stringifyKeys($this->rootPermissions) as $name => $isGranted){ $perm = $permManager->getPermission($name); if($perm === null){ throw new \LogicException("Unregistered root permission $name"); @@ -187,11 +188,12 @@ class PermissibleInternal implements Permissible{ } /** - * @param bool[] $children + * @param bool[] $children + * @phpstan-param array $children */ private function calculateChildPermissions(array $children, bool $invert, ?PermissionAttachment $attachment, ?PermissionAttachmentInfo $parent) : void{ $permManager = PermissionManager::getInstance(); - foreach($children as $name => $v){ + foreach(Utils::stringifyKeys($children) as $name => $v){ $perm = $permManager->getPermission($name); $value = ($v xor $invert); $this->permissions[$name] = new PermissionAttachmentInfo($name, $attachment, $value, $parent); diff --git a/src/permission/PermissionParser.php b/src/permission/PermissionParser.php index c7733a49cd..8aab762cf6 100644 --- a/src/permission/PermissionParser.php +++ b/src/permission/PermissionParser.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\permission; +use pocketmine\utils\Utils; use function is_bool; use function strtolower; @@ -83,7 +84,7 @@ class PermissionParser{ */ public static function loadPermissions(array $data, string $default = self::DEFAULT_FALSE) : array{ $result = []; - foreach($data as $name => $entry){ + foreach(Utils::stringifyKeys($data) as $name => $entry){ $desc = null; if(isset($entry["default"])){ $default = PermissionParser::defaultFromString($entry["default"]); diff --git a/src/plugin/PluginBase.php b/src/plugin/PluginBase.php index 7af6c3492c..32b30794e3 100644 --- a/src/plugin/PluginBase.php +++ b/src/plugin/PluginBase.php @@ -32,6 +32,7 @@ use pocketmine\scheduler\TaskScheduler; use pocketmine\Server; use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\Config; +use pocketmine\utils\Utils; use Webmozart\PathUtil\Path; use function count; use function dirname; @@ -162,7 +163,7 @@ abstract class PluginBase implements Plugin, CommandExecutor{ private function registerYamlCommands() : void{ $pluginCmds = []; - foreach($this->getDescription()->getCommands() as $key => $data){ + foreach(Utils::stringifyKeys($this->getDescription()->getCommands()) as $key => $data){ if(strpos($key, ":") !== false){ $this->logger->error($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_commandError($key, $this->getDescription()->getFullName(), ":"))); continue; diff --git a/src/plugin/PluginLoadabilityChecker.php b/src/plugin/PluginLoadabilityChecker.php index 9d3ca0387a..a293f33c00 100644 --- a/src/plugin/PluginLoadabilityChecker.php +++ b/src/plugin/PluginLoadabilityChecker.php @@ -76,7 +76,7 @@ final class PluginLoadabilityChecker{ } } - foreach($description->getRequiredExtensions() as $extensionName => $versionConstrs){ + foreach(Utils::stringifyKeys($description->getRequiredExtensions()) as $extensionName => $versionConstrs){ $gotVersion = phpversion($extensionName); if($gotVersion === false){ return KnownTranslationFactory::pocketmine_plugin_extensionNotLoaded($extensionName); diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 46986946c6..de84130973 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -181,7 +181,7 @@ class PluginManager{ } $opRoot = $permManager->getPermission(DefaultPermissions::ROOT_OPERATOR); $everyoneRoot = $permManager->getPermission(DefaultPermissions::ROOT_USER); - foreach($description->getPermissions() as $default => $perms){ + foreach(Utils::stringifyKeys($description->getPermissions()) as $default => $perms){ foreach($perms as $perm){ $permManager->addPermission($perm); switch($default){ @@ -345,7 +345,7 @@ class PluginManager{ while(count($triage->plugins) > 0){ $loadedThisLoop = 0; - foreach($triage->plugins as $name => $entry){ + foreach(Utils::stringifyKeys($triage->plugins) as $name => $entry){ $this->checkDepsForTriage($name, "hard", $triage->dependencies, $loadedPlugins, $triage); $this->checkDepsForTriage($name, "soft", $triage->softDependencies, $loadedPlugins, $triage); @@ -377,7 +377,7 @@ class PluginManager{ //No plugins loaded :( //check for skippable soft dependencies first, in case the dependents could resolve hard dependencies - foreach($triage->plugins as $name => $file){ + foreach(Utils::stringifyKeys($triage->plugins) as $name => $file){ if(isset($triage->softDependencies[$name]) && !isset($triage->dependencies[$name])){ foreach($triage->softDependencies[$name] as $k => $dependency){ if($this->getPlugin($dependency) === null && !array_key_exists($dependency, $triage->plugins)){ @@ -392,7 +392,7 @@ class PluginManager{ } } - foreach($triage->plugins as $name => $file){ + foreach(Utils::stringifyKeys($triage->plugins) as $name => $file){ if(isset($triage->dependencies[$name])){ $unknownDependencies = []; @@ -415,7 +415,7 @@ class PluginManager{ } } - foreach($triage->plugins as $name => $file){ + foreach(Utils::stringifyKeys($triage->plugins) as $name => $file){ $this->server->getLogger()->critical($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_loadError($name, KnownTranslationFactory::pocketmine_plugin_circularDependency()))); } break; diff --git a/src/stats/SendUsageTask.php b/src/stats/SendUsageTask.php index d108ca94a7..9440ae7797 100644 --- a/src/stats/SendUsageTask.php +++ b/src/stats/SendUsageTask.php @@ -123,9 +123,7 @@ class SendUsageTask extends AsyncTask{ ]; //This anonymizes the user ids so they cannot be reversed to the original - foreach($playerList as $k => $v){ - $playerList[$k] = md5($v); - } + $playerList = array_map('md5', $playerList); $players = array_map(function(Player $p) : string{ return md5($p->getUniqueId()->getBytes()); }, $server->getOnlinePlayers()); diff --git a/src/utils/Config.php b/src/utils/Config.php index 562d614f86..1a51254962 100644 --- a/src/utils/Config.php +++ b/src/utils/Config.php @@ -425,7 +425,7 @@ class Config{ public function set($k, $v = true) : void{ $this->config[$k] = $v; $this->changed = true; - foreach($this->nestedCache as $nestedKey => $nvalue){ + foreach(Utils::stringifyKeys($this->nestedCache) as $nestedKey => $nvalue){ if(substr($nestedKey, 0, strlen($k) + 1) === ($k . ".")){ unset($this->nestedCache[$nestedKey]); } @@ -487,7 +487,7 @@ class Config{ */ private function fillDefaults(array $default, &$data) : int{ $changed = 0; - foreach($default as $k => $v){ + foreach(Utils::stringifyKeys($default) as $k => $v){ if(is_array($v)){ if(!isset($data[$k]) or !is_array($data[$k])){ $data[$k] = []; @@ -536,7 +536,7 @@ class Config{ */ public static function writeProperties(array $config) : string{ $content = "#Properties Config file\r\n#" . date("D M j H:i:s T Y") . "\r\n"; - foreach($config as $k => $v){ + foreach(Utils::stringifyKeys($config) as $k => $v){ if(is_bool($v)){ $v = $v ? "on" : "off"; } diff --git a/src/utils/Filesystem.php b/src/utils/Filesystem.php index 9a89976e6c..2d107af6e0 100644 --- a/src/utils/Filesystem.php +++ b/src/utils/Filesystem.php @@ -163,7 +163,8 @@ final class Filesystem{ $result = str_replace([DIRECTORY_SEPARATOR, ".php", "phar://"], ["/", "", ""], $path); //remove relative paths - foreach(self::$cleanedPaths as $cleanPath => $replacement){ + //this should probably never have integer keys, but it's safer than making PHPStan ignore it + foreach(Utils::stringifyKeys(self::$cleanedPaths) as $cleanPath => $replacement){ $cleanPath = rtrim(str_replace([DIRECTORY_SEPARATOR, "phar://"], ["/", ""], $cleanPath), "/"); if(strpos($result, $cleanPath) === 0){ $result = ltrim(str_replace($cleanPath, $replacement, $result), "/"); diff --git a/src/utils/StringToTParser.php b/src/utils/StringToTParser.php index 598b3768db..a15204ba47 100644 --- a/src/utils/StringToTParser.php +++ b/src/utils/StringToTParser.php @@ -75,7 +75,7 @@ abstract class StringToTParser{ return strtolower(str_replace([" ", "minecraft:"], ["_", ""], trim($input))); } - /** @return string[] */ + /** @return string[]|int[] */ public function getKnownAliases() : array{ return array_keys($this->callbackMap); } diff --git a/src/utils/Utils.php b/src/utils/Utils.php index b0e81ca288..6f95001254 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -571,6 +571,22 @@ final class Utils{ } } + /** + * Generator which forces array keys to string during iteration. + * This is necessary because PHP has an anti-feature where it casts numeric string keys to integers, leading to + * various crashes. + * + * @phpstan-template TKeyType of string + * @phpstan-template TValueType + * @phpstan-param array $array + * @phpstan-return \Generator + */ + public static function stringifyKeys(array $array) : \Generator{ + foreach($array as $key => $value){ // @phpstan-ignore-line - this is where we fix the stupid bullshit with array keys :) + yield (string) $key => $value; + } + } + public static function checkUTF8(string $string) : void{ if(!mb_check_encoding($string, 'UTF-8')){ throw new \InvalidArgumentException("Text must be valid UTF-8"); diff --git a/src/wizard/SetupWizard.php b/src/wizard/SetupWizard.php index bb1b8de264..6dfb3b6909 100644 --- a/src/wizard/SetupWizard.php +++ b/src/wizard/SetupWizard.php @@ -35,6 +35,7 @@ use pocketmine\player\GameMode; use pocketmine\utils\Config; use pocketmine\utils\Internet; use pocketmine\utils\InternetException; +use pocketmine\utils\Utils; use pocketmine\VersionInfo; use Webmozart\PathUtil\Path; use function fgets; @@ -69,7 +70,7 @@ class SetupWizard{ } $this->message("Please select a language"); - foreach($langs as $short => $native){ + foreach(Utils::stringifyKeys($langs) as $short => $native){ $this->writeLine(" $native => $short"); } diff --git a/src/world/format/io/WorldProviderManager.php b/src/world/format/io/WorldProviderManager.php index 001f92913b..64dad08168 100644 --- a/src/world/format/io/WorldProviderManager.php +++ b/src/world/format/io/WorldProviderManager.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\world\format\io; +use pocketmine\utils\Utils; use pocketmine\world\format\io\leveldb\LevelDB; use pocketmine\world\format\io\region\Anvil; use pocketmine\world\format\io\region\McRegion; @@ -77,7 +78,7 @@ final class WorldProviderManager{ */ public function getMatchingProviders(string $path) : array{ $result = []; - foreach($this->providers as $alias => $providerEntry){ + foreach(Utils::stringifyKeys($this->providers) as $alias => $providerEntry){ if($providerEntry->isValid($path)){ $result[$alias] = $providerEntry; } diff --git a/src/world/generator/GeneratorManager.php b/src/world/generator/GeneratorManager.php index 11fd02f3b3..0e29cc68b1 100644 --- a/src/world/generator/GeneratorManager.php +++ b/src/world/generator/GeneratorManager.php @@ -105,7 +105,7 @@ final class GeneratorManager{ */ public function getGeneratorName(string $class) : string{ Utils::testValidInstance($class, Generator::class); - foreach($this->list as $name => $c){ + foreach(Utils::stringifyKeys($this->list) as $name => $c){ if($c->getGeneratorClass() === $class){ return $name; } diff --git a/tests/phpstan/rules/UnsafeForeachArrayOfStringRule.php b/tests/phpstan/rules/UnsafeForeachArrayOfStringRule.php new file mode 100644 index 0000000000..639a5b469d --- /dev/null +++ b/tests/phpstan/rules/UnsafeForeachArrayOfStringRule.php @@ -0,0 +1,90 @@ + + */ +final class UnsafeForeachArrayOfStringRule implements Rule{ + + public function getNodeType() : string{ + return Foreach_::class; + } + + public function processNode(Node $node, Scope $scope) : array{ + /** @var Foreach_ $node */ + if($node->keyVar === null){ + return []; + } + $iterableType = $scope->getType($node->expr); + + if($iterableType->isArray()->no()){ + return []; + } + if($iterableType->isIterableAtLeastOnce()->no()){ + return []; + } + + $hasCastableKeyTypes = false; + $expectsIntKeyTypes = false; + TypeTraverser::map($iterableType->getIterableKeyType(), function(Type $type, callable $traverse) use (&$hasCastableKeyTypes, &$expectsIntKeyTypes) : Type{ + if($type instanceof IntegerType){ + $expectsIntKeyTypes = true; + return $type; + } + if(!$type instanceof StringType){ + return $traverse($type); + } + if($type->isNumericString()->no() || $type instanceof ClassStringType){ + //class-string cannot be numeric, even if PHPStan thinks they can be + return $type; + } + $hasCastableKeyTypes = true; + return $type; + }); + if($hasCastableKeyTypes && !$expectsIntKeyTypes){ + return [ + RuleErrorBuilder::message(sprintf( + "Unsafe foreach on array with key type %s (they might be casted to int).", + $iterableType->getIterableKeyType()->describe(VerbosityLevel::value()) + ))->tip("Use Utils::foreachWithStringKeys() for a safe Generator-based iterator.")->build() + ]; + } + return []; + } + +} \ No newline at end of file diff --git a/tools/generate-permission-doc.php b/tools/generate-permission-doc.php index 57fd04626a..944d2aae30 100644 --- a/tools/generate-permission-doc.php +++ b/tools/generate-permission-doc.php @@ -26,6 +26,7 @@ namespace pocketmine\generate_permission_doc; use pocketmine\permission\DefaultPermissions; use pocketmine\permission\PermissionManager; use pocketmine\utils\AssumptionFailedError; +use pocketmine\utils\Utils; use pocketmine\VersionInfo; use Webmozart\PathUtil\Path; use function count; @@ -90,7 +91,7 @@ foreach($permissions as $permission){ fwrite($doc, "|:-----|:----:|\n"); $children = $permission->getChildren(); ksort($children, SORT_STRING); - foreach($children as $childName => $isGranted){ + foreach(Utils::stringifyKeys($children) as $childName => $isGranted){ fwrite($doc, "| `$childName` | " . ($isGranted ? "Granted" : "Denied") . " |\n"); } fwrite($doc, "\n"); diff --git a/tools/simulate-chunk-selector.php b/tools/simulate-chunk-selector.php index b4af186e26..b30355f7c1 100644 --- a/tools/simulate-chunk-selector.php +++ b/tools/simulate-chunk-selector.php @@ -6,6 +6,7 @@ namespace pocketmine\tools\simulate_chunk_selector; use pocketmine\player\ChunkSelector; use pocketmine\utils\AssumptionFailedError; +use pocketmine\utils\Utils; use pocketmine\world\format\Chunk; use pocketmine\world\World; use Webmozart\PathUtil\Path; @@ -115,7 +116,7 @@ if(count(getopt("", ["help"])) !== 0){ exit(0); } -foreach(getopt("", ["radius:", "baseX:", "baseZ:", "scale:", "chunksPerStep:"]) as $name => $value){ +foreach(Utils::stringifyKeys(getopt("", ["radius:", "baseX:", "baseZ:", "scale:", "chunksPerStep:"])) as $name => $value){ if(!is_string($value) || (string) ((int) $value) !== $value){ fwrite(STDERR, "Value for --$name must be an integer\n"); exit(1); @@ -136,7 +137,7 @@ if($radius === null){ } $outputDirectory = null; -foreach(getopt("", ["output:"]) as $name => $value){ +foreach(Utils::stringifyKeys(getopt("", ["output:"])) as $name => $value){ assert($name === "output"); if(!is_string($value)){ fwrite(STDERR, "Value for --$name must be a string\n"); From 4599913034787143da4d32b3d76fa05ea066fe36 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 18 Nov 2021 00:58:20 +0000 Subject: [PATCH 3183/3224] Separate crashdump rendering from crashdump data collection this allows this code to be reused for reproducing crashdumps based on the original data. --- src/crash/CrashDump.php | 91 +++++++--------------------- src/crash/CrashDumpRenderer.php | 103 ++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 70 deletions(-) create mode 100644 src/crash/CrashDumpRenderer.php diff --git a/src/crash/CrashDump.php b/src/crash/CrashDump.php index 2719e317c0..f1072e3545 100644 --- a/src/crash/CrashDump.php +++ b/src/crash/CrashDump.php @@ -42,9 +42,7 @@ use function file; use function file_exists; use function file_get_contents; use function fopen; -use function fwrite; use function get_loaded_extensions; -use function implode; use function is_dir; use function is_resource; use function json_encode; @@ -69,7 +67,6 @@ use function zend_version; use function zlib_encode; use const FILE_IGNORE_NEW_LINES; use const JSON_UNESCAPED_SLASHES; -use const PHP_EOL; use const PHP_OS; use const PHP_VERSION; use const SORT_STRING; @@ -84,14 +81,12 @@ class CrashDump{ */ private const FORMAT_VERSION = 4; - private const PLUGIN_INVOLVEMENT_NONE = "none"; - private const PLUGIN_INVOLVEMENT_DIRECT = "direct"; - private const PLUGIN_INVOLVEMENT_INDIRECT = "indirect"; + public const PLUGIN_INVOLVEMENT_NONE = "none"; + public const PLUGIN_INVOLVEMENT_DIRECT = "direct"; + public const PLUGIN_INVOLVEMENT_INDIRECT = "indirect"; /** @var Server */ private $server; - /** @var resource */ - private $fp; /** @var float */ private $time; private CrashDumpData $data; @@ -112,26 +107,27 @@ class CrashDump{ mkdir($crashPath); } $this->path = Path::join($crashPath, date("D_M_j-H.i.s-T_Y", (int) $this->time) . ".log"); - $fp = @fopen($this->path, "wb"); - if(!is_resource($fp)){ - throw new \RuntimeException("Could not create Crash Dump"); - } - $this->fp = $fp; + $this->data = new CrashDumpData(); $this->data->format_version = self::FORMAT_VERSION; $this->data->time = $this->time; $this->data->uptime = $this->time - $this->server->getStartTime(); - $this->addLine($this->server->getName() . " Crash Dump " . date("D M j H:i:s T Y", (int) $this->time)); - $this->addLine(); + $this->baseCrash(); $this->generalData(); $this->pluginsData(); $this->extraData(); - $this->encodeData(); + $fp = @fopen($this->path, "wb"); + if(!is_resource($fp)){ + throw new \RuntimeException("Could not create Crash Dump"); + } + $writer = new CrashDumpRenderer($fp, $this->data); + $writer->renderHumanReadable(); + $this->encodeData($writer); - fclose($this->fp); + fclose($fp); } public function getPath() : string{ @@ -146,11 +142,11 @@ class CrashDump{ return $this->data; } - private function encodeData() : void{ - $this->addLine(); - $this->addLine("----------------------REPORT THE DATA BELOW THIS LINE-----------------------"); - $this->addLine(); - $this->addLine("===BEGIN CRASH DUMP==="); + private function encodeData(CrashDumpRenderer $renderer) : void{ + $renderer->addLine(); + $renderer->addLine("----------------------REPORT THE DATA BELOW THIS LINE-----------------------"); + $renderer->addLine(); + $renderer->addLine("===BEGIN CRASH DUMP==="); $json = json_encode($this->data, JSON_UNESCAPED_SLASHES); if($json === false){ throw new \RuntimeException("Failed to encode crashdump JSON: " . json_last_error_msg()); @@ -159,16 +155,14 @@ class CrashDump{ if($zlibEncoded === false) throw new AssumptionFailedError("ZLIB compression failed"); $this->encodedData = $zlibEncoded; foreach(str_split(base64_encode($this->encodedData), 76) as $line){ - $this->addLine($line); + $renderer->addLine($line); } - $this->addLine("===END CRASH DUMP==="); + $renderer->addLine("===END CRASH DUMP==="); } private function pluginsData() : void{ if($this->pluginManager !== null){ $plugins = $this->pluginManager->getPlugins(); - $this->addLine(); - $this->addLine("Loaded plugins:"); ksort($plugins, SORT_STRING); foreach($plugins as $p){ $d = $p->getDescription(); @@ -184,7 +178,6 @@ class CrashDump{ load: mb_strtoupper($d->getOrder()->name()), website: $d->getWebsite() ); - $this->addLine($d->getName() . " " . $d->getVersion() . " by " . implode(", ", $d->getAuthors()) . " for API(s) " . implode(", ", $d->getCompatibleApis())); } } } @@ -250,10 +243,6 @@ class CrashDump{ $this->data->error = $error; unset($this->data->error["fullFile"]); unset($this->data->error["trace"]); - $this->addLine("Error: " . $error["message"]); - $this->addLine("File: " . $error["file"]); - $this->addLine("Line: " . $error["line"]); - $this->addLine("Type: " . $error["type"]); $this->data->plugin_involvement = self::PLUGIN_INVOLVEMENT_NONE; if(!$this->determinePluginFromFile($error["fullFile"], true)){ //fatal errors won't leave any stack trace @@ -267,36 +256,24 @@ class CrashDump{ } } - $this->addLine(); - $this->addLine("Code:"); - if($this->server->getConfigGroup()->getPropertyBool("auto-report.send-code", true) and file_exists($error["fullFile"])){ $file = @file($error["fullFile"], FILE_IGNORE_NEW_LINES); if($file !== false){ for($l = max(0, $error["line"] - 10); $l < $error["line"] + 10 and isset($file[$l]); ++$l){ - $this->addLine("[" . ($l + 1) . "] " . $file[$l]); $this->data->code[$l + 1] = $file[$l]; } } } - $this->addLine(); - $this->addLine("Backtrace:"); - foreach(($this->data->trace = Utils::printableTrace($error["trace"])) as $line){ - $this->addLine($line); - } - $this->addLine(); + $this->data->trace = Utils::printableTrace($error["trace"]); } private function determinePluginFromFile(string $filePath, bool $crashFrame) : bool{ $frameCleanPath = Filesystem::cleanPath($filePath); if(strpos($frameCleanPath, Filesystem::CLEAN_PATH_SRC_PREFIX) !== 0){ - $this->addLine(); if($crashFrame){ - $this->addLine("THIS CRASH WAS CAUSED BY A PLUGIN"); $this->data->plugin_involvement = self::PLUGIN_INVOLVEMENT_DIRECT; }else{ - $this->addLine("A PLUGIN WAS INVOLVED IN THIS CRASH"); $this->data->plugin_involvement = self::PLUGIN_INVOLVEMENT_INDIRECT; } @@ -308,7 +285,6 @@ class CrashDump{ $filePath = Filesystem::cleanPath($file->getValue($plugin)); if(strpos($frameCleanPath, $filePath) === 0){ $this->data->plugin = $plugin->getName(); - $this->addLine("BAD PLUGIN: " . $plugin->getDescription()->getFullName()); break; } } @@ -319,7 +295,6 @@ class CrashDump{ } private function generalData() : void{ - $version = VersionInfo::VERSION(); $composerLibraries = []; foreach(InstalledVersions::getInstalledPackages() as $package){ $composerLibraries[$package] = sprintf( @@ -343,29 +318,5 @@ class CrashDump{ os: Utils::getOS(), composer_libraries: $composerLibraries, ); - $this->addLine($this->server->getName() . " version: " . $version->getFullVersion(true) . " [Protocol " . ProtocolInfo::CURRENT_PROTOCOL . "]"); - $this->addLine("Git commit: " . VersionInfo::GIT_HASH()); - $this->addLine("uname -a: " . php_uname("a")); - $this->addLine("PHP Version: " . phpversion()); - $this->addLine("Zend version: " . zend_version()); - $this->addLine("OS: " . PHP_OS . ", " . Utils::getOS()); - $this->addLine("Composer libraries: "); - foreach(Utils::stringifyKeys($composerLibraries) as $library => $libraryVersion){ - $this->addLine("- $library $libraryVersion"); - } - } - - /** - * @param string $line - */ - public function addLine($line = "") : void{ - fwrite($this->fp, $line . PHP_EOL); - } - - /** - * @param string $str - */ - public function add($str) : void{ - fwrite($this->fp, $str); } } diff --git a/src/crash/CrashDumpRenderer.php b/src/crash/CrashDumpRenderer.php new file mode 100644 index 0000000000..68945229d1 --- /dev/null +++ b/src/crash/CrashDumpRenderer.php @@ -0,0 +1,103 @@ +addLine($this->data->general->name . " Crash Dump " . date("D M j H:i:s T Y", (int) $this->data->time)); + $this->addLine(); + + $this->addLine("Error: " . $this->data->error["message"]); + $this->addLine("File: " . $this->data->error["file"]); + $this->addLine("Line: " . $this->data->error["line"]); + $this->addLine("Type: " . $this->data->error["type"]); + + if($this->data->plugin_involvement !== CrashDump::PLUGIN_INVOLVEMENT_NONE){ + $this->addLine(); + $this->addLine(match($this->data->plugin_involvement){ + CrashDump::PLUGIN_INVOLVEMENT_DIRECT => "THIS CRASH WAS CAUSED BY A PLUGIN", + CrashDump::PLUGIN_INVOLVEMENT_INDIRECT => "A PLUGIN WAS INVOLVED IN THIS CRASH", + default => "Unknown plugin involvement!" + }); + } + if($this->data->plugin !== ""){ + $this->addLine("BAD PLUGIN: " . $this->data->plugin); + } + + $this->addLine(); + $this->addLine("Code:"); + + foreach($this->data->code as $lineNumber => $line){ + $this->addLine("[$lineNumber] $line"); + } + + $this->addLine(); + $this->addLine("Backtrace:"); + foreach($this->data->trace as $line){ + $this->addLine($line); + } + $this->addLine(); + + $version = new VersionString($this->data->general->base_version, $this->data->general->is_dev, $this->data->general->build); + + $this->addLine($this->data->general->name . " version: " . $version->getFullVersion(true) . " [Protocol " . $this->data->general->protocol . "]"); + $this->addLine("Git commit: " . $this->data->general->git); + $this->addLine("uname -a: " . $this->data->general->uname); + $this->addLine("PHP Version: " . $this->data->general->php); + $this->addLine("Zend version: " . $this->data->general->zend); + $this->addLine("OS: " . $this->data->general->php_os . ", " . $this->data->general->os); + $this->addLine("Composer libraries: "); + foreach(Utils::stringifyKeys($this->data->general->composer_libraries) as $library => $libraryVersion){ + $this->addLine("- $library $libraryVersion"); + } + + if(count($this->data->plugins) > 0){ + $this->addLine(); + $this->addLine("Loaded plugins:"); + foreach($this->data->plugins as $p){ + $this->addLine($p->name . " " . $p->version . " by " . implode(", ", $p->authors) . " for API(s) " . implode(", ", $p->api)); + } + } + } + + public function addLine(string $line = "") : void{ + fwrite($this->fp, $line . PHP_EOL); + } +} \ No newline at end of file From b4b954cc5fb92c7270ce207b5bc127ae2de837e9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 Nov 2021 21:38:43 +0000 Subject: [PATCH 3184/3224] build/generate-registry-annotations: accommodate code with CRLF --- build/generate-registry-annotations.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/generate-registry-annotations.php b/build/generate-registry-annotations.php index f7dce3c508..11e15a3c60 100644 --- a/build/generate-registry-annotations.php +++ b/build/generate-registry-annotations.php @@ -91,7 +91,7 @@ foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($argv[1], throw new \RuntimeException("Failed to get contents of $file"); } - if(preg_match("/^namespace (.+);$/m", $contents, $matches) !== 1 || preg_match('/^((final|abstract)\s+)?class /m', $contents) !== 1){ + if(preg_match("/(*ANYCRLF)^namespace (.+);$/m", $contents, $matches) !== 1 || preg_match('/(*ANYCRLF)^((final|abstract)\s+)?class /m', $contents) !== 1){ continue; } $shortClassName = basename($file, ".php"); @@ -101,7 +101,7 @@ foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($argv[1], } $reflect = new \ReflectionClass($className); $docComment = $reflect->getDocComment(); - if($docComment === false || preg_match("/^\s*\*\s*@generate-registry-docblock$/m", $docComment) !== 1){ + if($docComment === false || preg_match("/(*ANYCRLF)^\s*\*\s*@generate-registry-docblock$/m", $docComment) !== 1){ continue; } echo "Found registry in $file\n"; From b34e6f53ebe3ed265f88cadfa2f5900f9fd69d2d Mon Sep 17 00:00:00 2001 From: Rush2929 <76860328+Rush2929@users.noreply.github.com> Date: Sat, 20 Nov 2021 08:21:10 +0900 Subject: [PATCH 3185/3224] Changed visibility of Projectile->move to Protected. (#4585) --- src/entity/projectile/Projectile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entity/projectile/Projectile.php b/src/entity/projectile/Projectile.php index a549b0d7a1..cf700b052a 100644 --- a/src/entity/projectile/Projectile.php +++ b/src/entity/projectile/Projectile.php @@ -166,7 +166,7 @@ abstract class Projectile extends Entity{ return $this->blockHit === null and parent::hasMovementUpdate(); } - public function move(float $dx, float $dy, float $dz) : void{ + protected function move(float $dx, float $dy, float $dz) : void{ $this->blocksAround = null; Timings::$entityMove->startTiming(); From ed8b4950a35c5d0d57eb3415bc7f78f0fc98f54f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 21 Nov 2021 21:10:58 +0000 Subject: [PATCH 3186/3224] Updated BedrockProtocol --- composer.json | 2 +- composer.lock | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index 0406c56437..4c71c4e130 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,7 @@ "fgrosse/phpasn1": "^2.3", "netresearch/jsonmapper": "^4.0", "pocketmine/bedrock-data": "^1.4.0+bedrock-1.17.40", - "pocketmine/bedrock-protocol": "^5.0.0+bedrock-1.17.40", + "pocketmine/bedrock-protocol": "^6.0.0+bedrock-1.17.40", "pocketmine/binaryutils": "^0.2.1", "pocketmine/callback-validator": "^1.0.2", "pocketmine/classloader": "^0.2.0", diff --git a/composer.lock b/composer.lock index e688bbe203..b078ca3176 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "eb459041db634d88bee7d4202e096178", + "content-hash": "fb545e4c8e17b0b07e8e20986b64e5a6", "packages": [ { "name": "adhocore/json-comment", @@ -275,16 +275,16 @@ }, { "name": "pocketmine/bedrock-protocol", - "version": "5.1.2+bedrock-1.17.40", + "version": "6.0.0+bedrock-1.17.40", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "5f600ce446f357391968c8ce92e3be989aa1dc9e" + "reference": "906bafec4fc41f548749ce01d120902b25c1bbfe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/5f600ce446f357391968c8ce92e3be989aa1dc9e", - "reference": "5f600ce446f357391968c8ce92e3be989aa1dc9e", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/906bafec4fc41f548749ce01d120902b25c1bbfe", + "reference": "906bafec4fc41f548749ce01d120902b25c1bbfe", "shasum": "" }, "require": { @@ -298,7 +298,7 @@ "ramsey/uuid": "^4.1" }, "require-dev": { - "phpstan/phpstan": "1.1.1", + "phpstan/phpstan": "1.2.0", "phpstan/phpstan-phpunit": "^1.0.0", "phpstan/phpstan-strict-rules": "^1.0.0", "phpunit/phpunit": "^9.5" @@ -316,9 +316,9 @@ "description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP", "support": { "issues": "https://github.com/pmmp/BedrockProtocol/issues", - "source": "https://github.com/pmmp/BedrockProtocol/tree/5.1.2+bedrock-1.17.40" + "source": "https://github.com/pmmp/BedrockProtocol/tree/6.0.0+bedrock-1.17.40" }, - "time": "2021-11-10T13:53:03+00:00" + "time": "2021-11-21T20:56:18+00:00" }, { "name": "pocketmine/binaryutils", From 37622e02b865e447298645adc943030518df98da Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 21 Nov 2021 21:11:39 +0000 Subject: [PATCH 3187/3224] Updated translations --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index b078ca3176..969ab365b7 100644 --- a/composer.lock +++ b/composer.lock @@ -533,16 +533,16 @@ }, { "name": "pocketmine/locale-data", - "version": "2.0.16", + "version": "2.0.17", "source": { "type": "git", "url": "https://github.com/pmmp/Language.git", - "reference": "8bd74825ac685446f67ea20999ce756a2acd5a30" + "reference": "30e4a64d5674bac556c4e2b9842b19a981471ac4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Language/zipball/8bd74825ac685446f67ea20999ce756a2acd5a30", - "reference": "8bd74825ac685446f67ea20999ce756a2acd5a30", + "url": "https://api.github.com/repos/pmmp/Language/zipball/30e4a64d5674bac556c4e2b9842b19a981471ac4", + "reference": "30e4a64d5674bac556c4e2b9842b19a981471ac4", "shasum": "" }, "type": "library", @@ -550,9 +550,9 @@ "description": "Language resources used by PocketMine-MP", "support": { "issues": "https://github.com/pmmp/Language/issues", - "source": "https://github.com/pmmp/Language/tree/2.0.16" + "source": "https://github.com/pmmp/Language/tree/2.0.17" }, - "time": "2021-11-12T00:10:09+00:00" + "time": "2021-11-12T00:59:39+00:00" }, { "name": "pocketmine/log", From cbe0f44c4f7bc3715acbf148f981bd93111c4c8f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 22 Nov 2021 14:58:45 +0000 Subject: [PATCH 3188/3224] ConsoleReaderChildProcess: Commit suicide in more cases this makes it slightly less annoying to get rid of as an orphan process, though it still won't immediately die. --- src/console/ConsoleReader.php | 27 ++++++---------------- src/console/ConsoleReaderChildProcess.php | 16 ++++++++++--- src/console/ConsoleReaderException.php | 28 +++++++++++++++++++++++ 3 files changed, 48 insertions(+), 23 deletions(-) create mode 100644 src/console/ConsoleReaderException.php diff --git a/src/console/ConsoleReader.php b/src/console/ConsoleReader.php index 9da61cb6dd..c34be83c39 100644 --- a/src/console/ConsoleReader.php +++ b/src/console/ConsoleReader.php @@ -23,50 +23,37 @@ declare(strict_types=1); namespace pocketmine\console; +use pocketmine\utils\AssumptionFailedError; use function fclose; -use function fgets; use function fopen; -use function is_resource; use function stream_select; use function trim; -use function usleep; final class ConsoleReader{ /** @var resource */ private $stdin; public function __construct(){ - $this->initStdin(); - } - - private function initStdin() : void{ - if(is_resource($this->stdin)){ - fclose($this->stdin); - } - - $this->stdin = fopen("php://stdin", "r"); + $stdin = fopen("php://stdin", "r"); + if($stdin === false) throw new AssumptionFailedError("Opening stdin should never fail"); + $this->stdin = $stdin; } /** * Reads a line from the console and adds it to the buffer. This method may block the thread. + * @throws ConsoleReaderException */ public function readLine() : ?string{ - if(!is_resource($this->stdin)){ - $this->initStdin(); - } - $r = [$this->stdin]; $w = $e = null; if(($count = stream_select($r, $w, $e, 0, 200000)) === 0){ //nothing changed in 200000 microseconds return null; }elseif($count === false){ //stream error - $this->initStdin(); + throw new ConsoleReaderException("Unexpected EOF on select()"); } if(($raw = fgets($this->stdin)) === false){ //broken pipe or EOF - $this->initStdin(); - usleep(200000); //prevent CPU waste if it's end of pipe - return null; //loop back round + throw new ConsoleReaderException("Unexpected EOF on fgets()"); } $line = trim($raw); diff --git a/src/console/ConsoleReaderChildProcess.php b/src/console/ConsoleReaderChildProcess.php index 3879ecdff8..6f4a742584 100644 --- a/src/console/ConsoleReaderChildProcess.php +++ b/src/console/ConsoleReaderChildProcess.php @@ -45,8 +45,18 @@ if($socket === false){ } $consoleReader = new ConsoleReader(); while(!feof($socket)){ - $line = $consoleReader->readLine(); - if($line !== null){ - fwrite($socket, $line . "\n"); + try{ + $line = $consoleReader->readLine(); + }catch(ConsoleReaderException $e){ + //Encountered unexpected EOF. This might be because the user did something stupid, or because the parent process + //has died. In either case, commit suicide. If the parent process is still alive, it will start a new console + //reader. + break; + } + if(@fwrite($socket, ($line ?? "") . "\n") === false){ + //Always send even if there's no line, to check if the parent is alive + //If the parent process was terminated forcibly, it won't close the connection properly, so feof() will return + //false even though the connection is actually broken. However, fwrite() will fail. + break; } } diff --git a/src/console/ConsoleReaderException.php b/src/console/ConsoleReaderException.php new file mode 100644 index 0000000000..bf9e8fc672 --- /dev/null +++ b/src/console/ConsoleReaderException.php @@ -0,0 +1,28 @@ + Date: Mon, 22 Nov 2021 15:37:33 +0000 Subject: [PATCH 3189/3224] fixed spam --- src/console/ConsoleReaderThread.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/console/ConsoleReaderThread.php b/src/console/ConsoleReaderThread.php index dbf3770d3e..fb9dc85bbe 100644 --- a/src/console/ConsoleReaderThread.php +++ b/src/console/ConsoleReaderThread.php @@ -116,6 +116,9 @@ final class ConsoleReaderThread extends Thread{ $command = preg_replace("#\\x1b\\x5b([^\\x1b]*\\x7e|[\\x40-\\x50])#", "", trim($command)) ?? throw new AssumptionFailedError("This regex is assumed to be valid"); $command = preg_replace('/[[:cntrl:]]/', '', $command) ?? throw new AssumptionFailedError("This regex is assumed to be valid"); + if($command === ""){ + continue; + } $buffer[] = $command; if($notifier !== null){ $notifier->wakeupSleeper(); From 2bb97d8904497f84c0e5ae40f347a67d7f8471b0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 22 Nov 2021 15:40:47 +0000 Subject: [PATCH 3190/3224] Be quiet CS --- src/console/ConsoleReader.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/console/ConsoleReader.php b/src/console/ConsoleReader.php index c34be83c39..bd1fef4f5f 100644 --- a/src/console/ConsoleReader.php +++ b/src/console/ConsoleReader.php @@ -25,6 +25,7 @@ namespace pocketmine\console; use pocketmine\utils\AssumptionFailedError; use function fclose; +use function fgets; use function fopen; use function stream_select; use function trim; From c37c261c0f5b0df545f99db7219f8c270d4024a6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 22 Nov 2021 22:19:40 +0000 Subject: [PATCH 3191/3224] Separate crashdump file generation from crashdump data collection this allows CrashDump to be used just to generate data, which will come in useful for non-crash error reporting in the future (e.g. packet decoding errors). --- src/Server.php | 29 ++++++++++++++++++++++++++++- src/crash/CrashDump.php | 38 ++++---------------------------------- 2 files changed, 32 insertions(+), 35 deletions(-) diff --git a/src/Server.php b/src/Server.php index 628c9a3113..4ab8b8dcb3 100644 --- a/src/Server.php +++ b/src/Server.php @@ -35,6 +35,7 @@ use pocketmine\console\ConsoleReaderThread; use pocketmine\crafting\CraftingManager; use pocketmine\crafting\CraftingManagerFromDataHelper; use pocketmine\crash\CrashDump; +use pocketmine\crash\CrashDumpRenderer; use pocketmine\data\java\GameModeIdMap; use pocketmine\entity\EntityDataHelper; use pocketmine\entity\Location; @@ -121,13 +122,18 @@ use function base64_encode; use function cli_set_process_title; use function copy; use function count; +use function date; +use function fclose; use function file_exists; use function file_get_contents; use function file_put_contents; use function filemtime; +use function fopen; use function get_class; use function ini_set; use function is_array; +use function is_dir; +use function is_resource; use function is_string; use function json_decode; use function max; @@ -1505,6 +1511,25 @@ class Server{ $this->crashDump(); } + private function writeCrashDumpFile(CrashDump $dump) : string{ + $crashFolder = Path::join($this->getDataPath(), "crashdumps"); + if(!is_dir($crashFolder)){ + mkdir($crashFolder); + } + $crashDumpPath = Path::join($crashFolder, date("D_M_j-H.i.s-T_Y", (int) $dump->getData()->time) . ".log"); + + $fp = @fopen($crashDumpPath, "wb"); + if(!is_resource($fp)){ + throw new \RuntimeException("Unable to open new file to generate crashdump"); + } + $writer = new CrashDumpRenderer($fp, $dump->getData()); + $writer->renderHumanReadable(); + $dump->encodeData($writer); + + fclose($fp); + return $crashDumpPath; + } + public function crashDump() : void{ while(@ob_end_flush()){} if(!$this->isRunning){ @@ -1521,7 +1546,9 @@ class Server{ $this->logger->emergency($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_crash_create())); $dump = new CrashDump($this, $this->pluginManager ?? null); - $this->logger->emergency($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_crash_submit($dump->getPath()))); + $crashDumpPath = $this->writeCrashDumpFile($dump); + + $this->logger->emergency($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_crash_submit($crashDumpPath))); if($this->configGroup->getPropertyBool("auto-report.enabled", true)){ $report = true; diff --git a/src/crash/CrashDump.php b/src/crash/CrashDump.php index f1072e3545..76cb0fef36 100644 --- a/src/crash/CrashDump.php +++ b/src/crash/CrashDump.php @@ -35,23 +35,17 @@ use pocketmine\utils\Utils; use pocketmine\VersionInfo; use Webmozart\PathUtil\Path; use function base64_encode; -use function date; use function error_get_last; -use function fclose; use function file; use function file_exists; use function file_get_contents; -use function fopen; use function get_loaded_extensions; -use function is_dir; -use function is_resource; use function json_encode; use function json_last_error_msg; use function ksort; use function max; use function mb_strtoupper; use function microtime; -use function mkdir; use function ob_end_clean; use function ob_get_contents; use function ob_start; @@ -87,51 +81,27 @@ class CrashDump{ /** @var Server */ private $server; - /** @var float */ - private $time; private CrashDumpData $data; /** @var string */ private $encodedData; - /** @var string */ - private $path; private ?PluginManager $pluginManager; public function __construct(Server $server, ?PluginManager $pluginManager){ - $this->time = microtime(true); + $now = microtime(true); $this->server = $server; $this->pluginManager = $pluginManager; - $crashPath = Path::join($this->server->getDataPath(), "crashdumps"); - if(!is_dir($crashPath)){ - mkdir($crashPath); - } - $this->path = Path::join($crashPath, date("D_M_j-H.i.s-T_Y", (int) $this->time) . ".log"); - $this->data = new CrashDumpData(); $this->data->format_version = self::FORMAT_VERSION; - $this->data->time = $this->time; - $this->data->uptime = $this->time - $this->server->getStartTime(); + $this->data->time = $now; + $this->data->uptime = $now - $this->server->getStartTime(); $this->baseCrash(); $this->generalData(); $this->pluginsData(); $this->extraData(); - - $fp = @fopen($this->path, "wb"); - if(!is_resource($fp)){ - throw new \RuntimeException("Could not create Crash Dump"); - } - $writer = new CrashDumpRenderer($fp, $this->data); - $writer->renderHumanReadable(); - $this->encodeData($writer); - - fclose($fp); - } - - public function getPath() : string{ - return $this->path; } public function getEncodedData() : string{ @@ -142,7 +112,7 @@ class CrashDump{ return $this->data; } - private function encodeData(CrashDumpRenderer $renderer) : void{ + public function encodeData(CrashDumpRenderer $renderer) : void{ $renderer->addLine(); $renderer->addLine("----------------------REPORT THE DATA BELOW THIS LINE-----------------------"); $renderer->addLine(); From 020cd7b966ceb89c47f210ef2f240e8e28746de2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 22 Nov 2021 22:31:07 +0000 Subject: [PATCH 3192/3224] CrashDump: fixed encodedData being uninitialized before getEncodedData() is called --- src/crash/CrashDump.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/crash/CrashDump.php b/src/crash/CrashDump.php index 76cb0fef36..8407e70ce2 100644 --- a/src/crash/CrashDump.php +++ b/src/crash/CrashDump.php @@ -64,6 +64,7 @@ use const JSON_UNESCAPED_SLASHES; use const PHP_OS; use const PHP_VERSION; use const SORT_STRING; +use const ZLIB_ENCODING_DEFLATE; class CrashDump{ @@ -102,6 +103,14 @@ class CrashDump{ $this->pluginsData(); $this->extraData(); + + $json = json_encode($this->data, JSON_UNESCAPED_SLASHES); + if($json === false){ + throw new \RuntimeException("Failed to encode crashdump JSON: " . json_last_error_msg()); + } + $zlibEncoded = zlib_encode($json, ZLIB_ENCODING_DEFLATE, 9); + if($zlibEncoded === false) throw new AssumptionFailedError("ZLIB compression failed"); + $this->encodedData = $zlibEncoded; } public function getEncodedData() : string{ @@ -117,13 +126,6 @@ class CrashDump{ $renderer->addLine("----------------------REPORT THE DATA BELOW THIS LINE-----------------------"); $renderer->addLine(); $renderer->addLine("===BEGIN CRASH DUMP==="); - $json = json_encode($this->data, JSON_UNESCAPED_SLASHES); - if($json === false){ - throw new \RuntimeException("Failed to encode crashdump JSON: " . json_last_error_msg()); - } - $zlibEncoded = zlib_encode($json, ZLIB_ENCODING_DEFLATE, 9); - if($zlibEncoded === false) throw new AssumptionFailedError("ZLIB compression failed"); - $this->encodedData = $zlibEncoded; foreach(str_split(base64_encode($this->encodedData), 76) as $line){ $renderer->addLine($line); } From fb0eebc0dcbf61e2254645460d58b7c13b0d938c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 23 Nov 2021 01:39:35 +0000 Subject: [PATCH 3193/3224] RegionWorldProvider: Show a more specific message on missing required ByteArrayTags --- src/world/format/io/region/RegionWorldProvider.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index 3ac9132f67..df28c3ffe9 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -173,6 +173,9 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ protected static function readFixedSizeByteArray(CompoundTag $chunk, string $tagName, int $length) : string{ $tag = $chunk->getTag($tagName); if(!($tag instanceof ByteArrayTag)){ + if($tag === null){ + throw new CorruptedChunkException("'$tagName' key is missing from chunk NBT"); + } throw new CorruptedChunkException("Expected TAG_ByteArray for '$tagName'"); } $data = $tag->getValue(); From d8f0fd0a7ef710930401ba056b7ae8be463d5cfb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 23 Nov 2021 01:49:48 +0000 Subject: [PATCH 3194/3224] McRegion: skip chunks with TerrainGenerated=false legacy PM used to save even ungenerated chunks, and omitted some tags when doing so which we expect to always be present. --- src/world/format/io/region/LegacyAnvilChunkTrait.php | 2 +- src/world/format/io/region/McRegion.php | 11 ++++++++++- src/world/format/io/region/RegionWorldProvider.php | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/world/format/io/region/LegacyAnvilChunkTrait.php b/src/world/format/io/region/LegacyAnvilChunkTrait.php index 8970a2fb3b..7debb29bad 100644 --- a/src/world/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/world/format/io/region/LegacyAnvilChunkTrait.php @@ -51,7 +51,7 @@ trait LegacyAnvilChunkTrait{ /** * @throws CorruptedChunkException */ - protected function deserializeChunk(string $data) : ChunkData{ + protected function deserializeChunk(string $data) : ?ChunkData{ $decompressed = @zlib_decode($data); if($decompressed === false){ throw new CorruptedChunkException("Failed to decompress chunk NBT"); diff --git a/src/world/format/io/region/McRegion.php b/src/world/format/io/region/McRegion.php index 3367a2f817..bf15973643 100644 --- a/src/world/format/io/region/McRegion.php +++ b/src/world/format/io/region/McRegion.php @@ -29,6 +29,7 @@ use pocketmine\data\bedrock\BiomeIds; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\ByteArrayTag; +use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntArrayTag; use pocketmine\nbt\tag\ListTag; @@ -45,7 +46,7 @@ class McRegion extends RegionWorldProvider{ /** * @throws CorruptedChunkException */ - protected function deserializeChunk(string $data) : ChunkData{ + protected function deserializeChunk(string $data) : ?ChunkData{ $decompressed = @zlib_decode($data); if($decompressed === false){ throw new CorruptedChunkException("Failed to decompress chunk NBT"); @@ -61,6 +62,14 @@ class McRegion extends RegionWorldProvider{ throw new CorruptedChunkException("'Level' key is missing from chunk NBT"); } + $legacyGeneratedTag = $chunk->getTag("TerrainGenerated"); + if($legacyGeneratedTag instanceof ByteTag && $legacyGeneratedTag->getValue() === 0){ + //In legacy PM before 3.0, PM used to save MCRegion chunks even when they weren't generated. In these cases + //(we'll see them in old worlds), some of the tags which we expect to always be present, will be missing. + //If TerrainGenerated (PM-specific tag from the olden days) is false, toss the chunk data and don't bother + //trying to read it. + return null; + } $subChunks = []; $fullIds = self::readFixedSizeByteArray($chunk, "Blocks", 32768); $fullData = self::readFixedSizeByteArray($chunk, "Data", 16384); diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index df28c3ffe9..1fe62912c7 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -146,7 +146,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ /** * @throws CorruptedChunkException */ - abstract protected function deserializeChunk(string $data) : ChunkData; + abstract protected function deserializeChunk(string $data) : ?ChunkData; /** * @return CompoundTag[] From eb0cf52d81dfa799f0598cbdbc821114d6c56b5c Mon Sep 17 00:00:00 2001 From: Covered123 <58715544+JavierLeon9966@users.noreply.github.com> Date: Tue, 23 Nov 2021 14:09:33 -0300 Subject: [PATCH 3195/3224] Remove useless code (#4590) --- src/network/mcpe/convert/ItemTranslator.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/network/mcpe/convert/ItemTranslator.php b/src/network/mcpe/convert/ItemTranslator.php index dd1dc9cd2b..4aa82f32b7 100644 --- a/src/network/mcpe/convert/ItemTranslator.php +++ b/src/network/mcpe/convert/ItemTranslator.php @@ -74,10 +74,6 @@ final class ItemTranslator{ throw new AssumptionFailedError("Invalid item table format"); } - $legacyStringToIntMapRaw = file_get_contents(Path::join(\pocketmine\BEDROCK_DATA_PATH, 'item_id_map.json')); - if($legacyStringToIntMapRaw === false){ - throw new AssumptionFailedError("Missing required resource file"); - } $legacyStringToIntMap = LegacyItemIdToStringIdMap::getInstance(); /** @phpstan-var array $simpleMappings */ From 5c7125f190ad00c3eddbb65b3bc4dd29d6d56ab2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 23 Nov 2021 17:39:20 +0000 Subject: [PATCH 3196/3224] Improved error handling for loading broken entity / tile data --- src/block/tile/TileFactory.php | 31 +++++++++-------- src/data/SavedDataLoadingException.php | 28 ++++++++++++++++ src/entity/EntityDataHelper.php | 15 ++++++--- src/entity/EntityFactory.php | 46 ++++++++++++++------------ src/entity/Human.php | 5 +-- src/item/Item.php | 5 ++- src/world/World.php | 6 ++-- 7 files changed, 92 insertions(+), 44 deletions(-) create mode 100644 src/data/SavedDataLoadingException.php diff --git a/src/block/tile/TileFactory.php b/src/block/tile/TileFactory.php index 9c51050fe6..f8a6db7468 100644 --- a/src/block/tile/TileFactory.php +++ b/src/block/tile/TileFactory.php @@ -23,8 +23,9 @@ declare(strict_types=1); namespace pocketmine\block\tile; +use pocketmine\data\SavedDataLoadingException; use pocketmine\math\Vector3; -use pocketmine\nbt\NbtDataException; +use pocketmine\nbt\NbtException; use pocketmine\nbt\tag\CompoundTag; use pocketmine\utils\SingletonTrait; use pocketmine\utils\Utils; @@ -112,21 +113,25 @@ final class TileFactory{ /** * @internal - * @throws NbtDataException + * @throws SavedDataLoadingException */ public function createFromData(World $world, CompoundTag $nbt) : ?Tile{ - $type = $nbt->getString(Tile::TAG_ID, ""); - if(!isset($this->knownTiles[$type])){ - return null; + try{ + $type = $nbt->getString(Tile::TAG_ID, ""); + if(!isset($this->knownTiles[$type])){ + return null; + } + $class = $this->knownTiles[$type]; + assert(is_a($class, Tile::class, true)); + /** + * @var Tile $tile + * @see Tile::__construct() + */ + $tile = new $class($world, new Vector3($nbt->getInt(Tile::TAG_X), $nbt->getInt(Tile::TAG_Y), $nbt->getInt(Tile::TAG_Z))); + $tile->readSaveData($nbt); + }catch(NbtException $e){ + throw new SavedDataLoadingException($e->getMessage(), 0, $e); } - $class = $this->knownTiles[$type]; - assert(is_a($class, Tile::class, true)); - /** - * @var Tile $tile - * @see Tile::__construct() - */ - $tile = new $class($world, new Vector3($nbt->getInt(Tile::TAG_X), $nbt->getInt(Tile::TAG_Y), $nbt->getInt(Tile::TAG_Z))); - $tile->readSaveData($nbt); return $tile; } diff --git a/src/data/SavedDataLoadingException.php b/src/data/SavedDataLoadingException.php new file mode 100644 index 0000000000..fcc72c7abc --- /dev/null +++ b/src/data/SavedDataLoadingException.php @@ -0,0 +1,28 @@ +getTag("Rotation"); if(!($yawPitch instanceof ListTag) or $yawPitch->getTagType() !== NBT::TAG_Float){ - throw new \UnexpectedValueException("'Rotation' should be a List"); + throw new SavedDataLoadingException("'Rotation' should be a List"); } /** @var FloatTag[] $values */ $values = $yawPitch->getValue(); if(count($values) !== 2){ - throw new \UnexpectedValueException("Expected exactly 2 entries for 'Rotation'"); + throw new SavedDataLoadingException("Expected exactly 2 entries for 'Rotation'"); } return Location::fromObject($pos, $world, $values[0]->getValue(), $values[1]->getValue()); } + /** + * @throws SavedDataLoadingException + */ public static function parseVec3(CompoundTag $nbt, string $tagName, bool $optional) : Vector3{ $pos = $nbt->getTag($tagName); if($pos === null and $optional){ return new Vector3(0, 0, 0); } if(!($pos instanceof ListTag) or ($pos->getTagType() !== NBT::TAG_Double && $pos->getTagType() !== NBT::TAG_Float)){ - throw new \UnexpectedValueException("'$tagName' should be a List or List"); + throw new SavedDataLoadingException("'$tagName' should be a List or List"); } /** @var DoubleTag[]|FloatTag[] $values */ $values = $pos->getValue(); if(count($values) !== 3){ - throw new \UnexpectedValueException("Expected exactly 3 entries in '$tagName' tag"); + throw new SavedDataLoadingException("Expected exactly 3 entries in '$tagName' tag"); } return new Vector3($values[0]->getValue(), $values[1]->getValue(), $values[2]->getValue()); } diff --git a/src/entity/EntityFactory.php b/src/entity/EntityFactory.php index 809d323414..0010f0ace9 100644 --- a/src/entity/EntityFactory.php +++ b/src/entity/EntityFactory.php @@ -30,6 +30,7 @@ use pocketmine\block\BlockFactory; use pocketmine\data\bedrock\EntityLegacyIds; use pocketmine\data\bedrock\PotionTypeIdMap; use pocketmine\data\bedrock\PotionTypeIds; +use pocketmine\data\SavedDataLoadingException; use pocketmine\entity\object\ExperienceOrb; use pocketmine\entity\object\FallingBlock; use pocketmine\entity\object\ItemEntity; @@ -45,7 +46,7 @@ use pocketmine\entity\projectile\SplashPotion; use pocketmine\item\Item; use pocketmine\math\Facing; use pocketmine\math\Vector3; -use pocketmine\nbt\NbtDataException; +use pocketmine\nbt\NbtException; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; @@ -113,12 +114,12 @@ final class EntityFactory{ $this->register(ItemEntity::class, function(World $world, CompoundTag $nbt) : ItemEntity{ $itemTag = $nbt->getCompoundTag("Item"); if($itemTag === null){ - throw new \UnexpectedValueException("Expected \"Item\" NBT tag not found"); + throw new SavedDataLoadingException("Expected \"Item\" NBT tag not found"); } $item = Item::nbtDeserialize($itemTag); if($item->isNull()){ - throw new \UnexpectedValueException("Item is invalid"); + throw new SavedDataLoadingException("Item is invalid"); } return new ItemEntity(EntityDataHelper::parseLocation($nbt, $world), $item, $nbt); }, ['Item', 'minecraft:item'], EntityLegacyIds::ITEM); @@ -126,7 +127,7 @@ final class EntityFactory{ $this->register(Painting::class, function(World $world, CompoundTag $nbt) : Painting{ $motive = PaintingMotive::getMotiveByName($nbt->getString("Motive")); if($motive === null){ - throw new \UnexpectedValueException("Unknown painting motive"); + throw new SavedDataLoadingException("Unknown painting motive"); } $blockIn = new Vector3($nbt->getInt("TileX"), $nbt->getInt("TileY"), $nbt->getInt("TileZ")); if(($directionTag = $nbt->getTag("Direction")) instanceof ByteTag){ @@ -134,7 +135,7 @@ final class EntityFactory{ }elseif(($facingTag = $nbt->getTag("Facing")) instanceof ByteTag){ $facing = Painting::DATA_TO_FACING[$facingTag->getValue()] ?? Facing::NORTH; }else{ - throw new \UnexpectedValueException("Missing facing info"); + throw new SavedDataLoadingException("Missing facing info"); } return new Painting(EntityDataHelper::parseLocation($nbt, $world), $blockIn, $facing, $motive, $nbt); @@ -151,7 +152,7 @@ final class EntityFactory{ $this->register(SplashPotion::class, function(World $world, CompoundTag $nbt) : SplashPotion{ $potionType = PotionTypeIdMap::getInstance()->fromId($nbt->getShort("PotionId", PotionTypeIds::WATER)); if($potionType === null){ - throw new \UnexpectedValueException("No such potion type"); + throw new SavedDataLoadingException("No such potion type"); } return new SplashPotion(EntityDataHelper::parseLocation($nbt, $world), null, $potionType, $nbt); }, ['ThrownPotion', 'minecraft:potion', 'thrownpotion'], EntityLegacyIds::SPLASH_POTION); @@ -222,25 +223,28 @@ final class EntityFactory{ /** * Creates an entity from data stored on a chunk. * - * @throws \RuntimeException - * @throws NbtDataException + * @throws SavedDataLoadingException * @internal */ public function createFromData(World $world, CompoundTag $nbt) : ?Entity{ - $saveId = $nbt->getTag("id") ?? $nbt->getTag("identifier"); - $func = null; - if($saveId instanceof StringTag){ - $func = $this->creationFuncs[$saveId->getValue()] ?? null; - }elseif($saveId instanceof IntTag){ //legacy MCPE format - $func = $this->creationFuncs[$saveId->getValue() & 0xff] ?? null; - } - if($func === null){ - return null; - } - /** @var Entity $entity */ - $entity = $func($world, $nbt); + try{ + $saveId = $nbt->getTag("id") ?? $nbt->getTag("identifier"); + $func = null; + if($saveId instanceof StringTag){ + $func = $this->creationFuncs[$saveId->getValue()] ?? null; + }elseif($saveId instanceof IntTag){ //legacy MCPE format + $func = $this->creationFuncs[$saveId->getValue() & 0xff] ?? null; + } + if($func === null){ + return null; + } + /** @var Entity $entity */ + $entity = $func($world, $nbt); - return $entity; + return $entity; + }catch(NbtException $e){ + throw new SavedDataLoadingException($e->getMessage(), 0, $e); + } } public function injectSaveId(string $class, CompoundTag $saveData) : void{ diff --git a/src/entity/Human.php b/src/entity/Human.php index c77de50056..c82cee7f82 100644 --- a/src/entity/Human.php +++ b/src/entity/Human.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\entity; +use pocketmine\data\SavedDataLoadingException; use pocketmine\entity\animation\TotemUseAnimation; use pocketmine\entity\effect\EffectInstance; use pocketmine\entity\effect\VanillaEffects; @@ -104,12 +105,12 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ /** * @throws InvalidSkinException - * @throws \UnexpectedValueException + * @throws SavedDataLoadingException */ public static function parseSkinNBT(CompoundTag $nbt) : Skin{ $skinTag = $nbt->getCompoundTag("Skin"); if($skinTag === null){ - throw new \UnexpectedValueException("Missing skin data"); + throw new SavedDataLoadingException("Missing skin data"); } return new Skin( //this throws if the skin is invalid $skinTag->getString("Name"), diff --git a/src/item/Item.php b/src/item/Item.php index f37015ba90..bceb921425 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -31,6 +31,7 @@ use pocketmine\block\BlockBreakInfo; use pocketmine\block\BlockToolType; use pocketmine\block\VanillaBlocks; use pocketmine\data\bedrock\EnchantmentIdMap; +use pocketmine\data\SavedDataLoadingException; use pocketmine\entity\Entity; use pocketmine\item\enchantment\EnchantmentInstance; use pocketmine\math\Vector3; @@ -671,6 +672,8 @@ class Item implements \JsonSerializable{ /** * Deserializes an Item from an NBT CompoundTag + * @throws NbtException + * @throws SavedDataLoadingException */ public static function nbtDeserialize(CompoundTag $tag) : Item{ if($tag->getTag("id") === null or $tag->getTag("Count") === null){ @@ -692,7 +695,7 @@ class Item implements \JsonSerializable{ } $item->setCount($count); }else{ - throw new \InvalidArgumentException("Item CompoundTag ID must be an instance of StringTag or ShortTag, " . get_class($idTag) . " given"); + throw new SavedDataLoadingException("Item CompoundTag ID must be an instance of StringTag or ShortTag, " . get_class($idTag) . " given"); } $itemNBT = $tag->getCompoundTag("tag"); diff --git a/src/world/World.php b/src/world/World.php index dcd27805cb..9549980eb0 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -36,6 +36,7 @@ use pocketmine\block\tile\TileFactory; use pocketmine\block\UnknownBlock; use pocketmine\block\VanillaBlocks; use pocketmine\data\bedrock\BiomeIds; +use pocketmine\data\SavedDataLoadingException; use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; use pocketmine\entity\Location; @@ -57,7 +58,6 @@ use pocketmine\item\LegacyStringToItemParser; use pocketmine\lang\KnownTranslationFactory; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; -use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; @@ -2472,7 +2472,7 @@ class World implements ChunkManager{ foreach($chunkData->getEntityNBT() as $k => $nbt){ try{ $entity = $entityFactory->createFromData($this, $nbt); - }catch(NbtDataException $e){ + }catch(SavedDataLoadingException $e){ $logger->error("Bad entity data at list position $k: " . $e->getMessage()); $logger->logException($e); continue; @@ -2500,7 +2500,7 @@ class World implements ChunkManager{ foreach($chunkData->getTileNBT() as $k => $nbt){ try{ $tile = $tileFactory->createFromData($this, $nbt); - }catch(NbtDataException $e){ + }catch(SavedDataLoadingException $e){ $logger->error("Bad tile entity data at list position $k: " . $e->getMessage()); $logger->logException($e); continue; From b784a04e08392bef51cd87d2d4eff736c2d25f22 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 24 Nov 2021 16:38:37 +0000 Subject: [PATCH 3197/3224] Utils: fixed parseDocComment() ignoring tags containing hyphens --- src/utils/Utils.php | 2 +- tests/phpunit/utils/UtilsTest.php | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/utils/Utils.php b/src/utils/Utils.php index 6f95001254..d761f772f0 100644 --- a/src/utils/Utils.php +++ b/src/utils/Utils.php @@ -506,7 +506,7 @@ final class Utils{ if($rawDocComment === false){ //usually empty doc comment, but this is safer and statically analysable return []; } - preg_match_all('/(*ANYCRLF)^[\t ]*(?:\* )?@([a-zA-Z]+)(?:[\t ]+(.+?))?[\t ]*$/m', $rawDocComment, $matches); + preg_match_all('/(*ANYCRLF)^[\t ]*(?:\* )?@([a-zA-Z\-]+)(?:[\t ]+(.+?))?[\t ]*$/m', $rawDocComment, $matches); return array_combine($matches[1], $matches[2]); } diff --git a/tests/phpunit/utils/UtilsTest.php b/tests/phpunit/utils/UtilsTest.php index 80fe84a455..7a84488159 100644 --- a/tests/phpunit/utils/UtilsTest.php +++ b/tests/phpunit/utils/UtilsTest.php @@ -90,6 +90,12 @@ class UtilsTest extends TestCase{ self::assertCount(0, $tags); } + public function testParseDocCommentWithTagsContainingHyphens() : void{ + $tags = Utils::parseDocComment("/** @phpstan-return list */"); + self::assertArrayHasKey("phpstan-return", $tags); + self::assertEquals("list", $tags["phpstan-return"]); + } + public function testNamespacedNiceClosureName() : void{ //be careful with this test. The closure has to be declared on the same line as the assertion. self::assertSame('closure@' . Filesystem::cleanPath(__FILE__) . '#L' . __LINE__, Utils::getNiceClosureName(function() : void{})); From ad56392d959e9d4eefb1cdae4bc659eac7ae2e1f Mon Sep 17 00:00:00 2001 From: Colin Date: Wed, 24 Nov 2021 22:42:51 +0100 Subject: [PATCH 3198/3224] Skull: fixed calculation of collision boxes (#4591) --- src/block/Skull.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/block/Skull.php b/src/block/Skull.php index 6ee2e77f43..47476abcea 100644 --- a/src/block/Skull.php +++ b/src/block/Skull.php @@ -124,8 +124,14 @@ class Skull extends Flowable{ * @return AxisAlignedBB[] */ protected function recalculateCollisionBoxes() : array{ - //TODO: different bounds depending on attached face - return [AxisAlignedBB::one()->contract(0.25, 0, 0.25)->trim(Facing::UP, 0.5)]; + $collisionBox = AxisAlignedBB::one()->contract(0.25, 0, 0.25)->trim(Facing::UP, 0.5); + return match($this->facing){ + Facing::NORTH => [$collisionBox->offset(0, 0.25, 0.25)], + Facing::SOUTH => [$collisionBox->offset(0, 0.25, -0.25)], + Facing::WEST => [$collisionBox->offset(0.25, 0.25, 0)], + Facing::EAST => [$collisionBox->offset(-0.25, 0.25, 0)], + default => [$collisionBox] + }; } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ From fad96b77ceeae86a5b92ab7ba9cf37b5e80d8202 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 24 Nov 2021 23:49:56 +0000 Subject: [PATCH 3199/3224] stfu --- tests/phpstan/configs/phpstan-bugs.neon | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 8baae94f11..5b91ae7488 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -40,6 +40,11 @@ parameters: count: 1 path: ../../../src/plugin/PluginManager.php + - + message: "#^Parameter \\#1 \\$yamlString of class pocketmine\\\\plugin\\\\PluginDescription constructor expects array\\|string, array\\ given\\.$#" + count: 1 + path: ../../../src/plugin/ScriptPluginLoader.php + - message: "#^Strict comparison using \\=\\=\\= between string and false will always evaluate to false\\.$#" count: 1 From bb7683158f8ac1cbe6930a27e5c9d3d9c8ef33d5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 24 Nov 2021 23:52:51 +0000 Subject: [PATCH 3200/3224] Remove dead ignoreErrors patterns --- tests/phpstan/configs/actual-problems.neon | 20 -------------------- tests/phpstan/configs/phpstan-bugs.neon | 10 ---------- 2 files changed, 30 deletions(-) diff --git a/tests/phpstan/configs/actual-problems.neon b/tests/phpstan/configs/actual-problems.neon index badcc3e0ef..a9c45db8bf 100644 --- a/tests/phpstan/configs/actual-problems.neon +++ b/tests/phpstan/configs/actual-problems.neon @@ -465,16 +465,6 @@ parameters: count: 1 path: ../../../src/command/SimpleCommandMap.php - - - message: "#^Only booleans are allowed in an if condition, int\\|false given\\.$#" - count: 1 - path: ../../../src/command/defaults/BanIpCommand.php - - - - message: "#^Only booleans are allowed in an if condition, int\\|false given\\.$#" - count: 1 - path: ../../../src/command/defaults/PardonIpCommand.php - - message: "#^Cannot call method addParticle\\(\\) on pocketmine\\\\world\\\\World\\|null\\.$#" count: 1 @@ -515,11 +505,6 @@ parameters: count: 1 path: ../../../src/command/defaults/TimingsCommand.php - - - message: "#^Property pocketmine\\\\console\\\\ConsoleReader\\:\\:\\$stdin \\(resource\\) does not accept resource\\|false\\.$#" - count: 1 - path: ../../../src/console/ConsoleReader.php - - message: "#^Parameter \\#1 \\$json of function json_decode expects string, string\\|false given\\.$#" count: 1 @@ -1450,11 +1435,6 @@ parameters: count: 2 path: ../../../src/world/light/SkyLightUpdate.php - - - message: "#^Cannot call method getSubChunks\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" - count: 1 - path: ../../../src/world/light/SkyLightUpdate.php - - message: "#^Cannot call method setHeightMap\\(\\) on pocketmine\\\\world\\\\format\\\\Chunk\\|null\\.$#" count: 2 diff --git a/tests/phpstan/configs/phpstan-bugs.neon b/tests/phpstan/configs/phpstan-bugs.neon index 5b91ae7488..0d98c36771 100644 --- a/tests/phpstan/configs/phpstan-bugs.neon +++ b/tests/phpstan/configs/phpstan-bugs.neon @@ -5,11 +5,6 @@ parameters: count: 1 path: ../../../src/block/BaseBanner.php - - - message: "#^Call to function is_resource\\(\\) with resource will always evaluate to true\\.$#" - count: 2 - path: ../../../src/console/ConsoleReader.php - - message: "#^Method pocketmine\\\\crafting\\\\CraftingManager\\:\\:getDestructorCallbacks\\(\\) should return pocketmine\\\\utils\\\\ObjectSet\\ but returns pocketmine\\\\utils\\\\ObjectSet\\\\|pocketmine\\\\utils\\\\ObjectSet\\\\.$#" count: 1 @@ -20,11 +15,6 @@ parameters: count: 1 path: ../../../src/crafting/CraftingManager.php - - - message: "#^Property pocketmine\\\\crash\\\\CrashDumpData\\:\\:\\$extensions \\(array\\\\) does not accept array\\\\.$#" - count: 1 - path: ../../../src/crash/CrashDump.php - - message: "#^Call to function assert\\(\\) with false and 'unknown hit type' will always evaluate to false\\.$#" count: 1 From 9338d427429393f701f2b506178434cf46ed5023 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 25 Nov 2021 00:40:40 +0000 Subject: [PATCH 3201/3224] Release 4.0.0-BETA13 --- changelogs/4.0.md | 39 ++++++++++++++++++++++++++++++++++++++- src/VersionInfo.php | 2 +- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index 12fa5c9a6d..c7038c96c4 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1710,4 +1710,41 @@ Released 9th November 2021. ### Server - Added the following API methods: - `Server->getIpV6()` - - `Server->getPortV6()` \ No newline at end of file + - `Server->getPortV6()` + +# 4.0.0-BETA13 +Released 25th November 2021. + +## General +- Improved error messages when a plugin command name or alias contains an illegal character. +- Fixed script plugins reading tags from non-docblocks before the actual docblock. +- Added a sanity check to `Human->setCurrentTotalXp()` to try and catch an elusive bug that's been appearing in the wild - please get in touch if you know how to reproduce it! +- Updated `BUILDING.md` to reflect the fact that submodules are no longer required to build or run the server. + +## Internals +- Crashdump rendering has been separated from crashdump data generation. This allows rendering crashdumps from existing JSON data. +- Direct iteration of arrays with string keys is now disallowed by a custom PHPStan rule. This is because numeric strings are casted to integers when used as array keys, which produces a variety of unexpected behaviour particularly for iteration. + - To iterate on arrays with string keys, `Utils::stringifyKeys()` must now be used. + +## Fixes +- Fixed various crashes involving bad entity data saved on disk (e.g. an item entity with invalid item would crash the server). +- Fixed various crashes involving arrays with numeric string keys. +- Fixed crash when players try to pickup XP while already having max XP. +- Fixed ungenerated chunks saved on disk by old versions of PocketMine-MP (before 3.0.0) being treated as corrupted during world conversion (they are now ignored instead). +- Fixed misleading corruption error message when saved chunks have missing NBT tags. + +## Gameplay +- Fixed `/setworldspawn` setting incorrect positions based on player position when in negative coordinates. +- `/setworldspawn` now accepts relative coordinates when used as a player. +- Added some extra aliases for `/give` and `/clear`: `chipped_anvil`, `coarse_dirt`, `damaged_anvil`, `dark_oak_standing_sign`, `jungle_wood_stairs`, `jungle_wooden_stairs` and `oak_standing_sign`. + - Some of these were added for quality-of-life, others were added just to be consistent. +- Fixed explosions dropping incorrect items when destroying blocks with tile data (e.g. banners, beds). +- Fixed the bounding box of skulls when mounted on a wall. +- Fixed podzol dropping itself when mined (instead of dirt). + +## API +### Entity +- `Projectile->move()` is now protected, like its parent. + +### Utils +- `Utils::parseDocComment()` now allows `-` in tag names. diff --git a/src/VersionInfo.php b/src/VersionInfo.php index ee43667629..f4c221c3f7 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -30,7 +30,7 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; public const BASE_VERSION = "4.0.0-BETA13"; - public const IS_DEVELOPMENT_BUILD = true; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_NUMBER = 0; public const BUILD_CHANNEL = "beta"; From 7dd5d0b59333417ba90967b1e0f8cb44e97386a2 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 25 Nov 2021 00:40:43 +0000 Subject: [PATCH 3202/3224] 4.0.0-BETA14 is next --- src/VersionInfo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index f4c221c3f7..b44c7856ed 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -29,8 +29,8 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "4.0.0-BETA13"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "4.0.0-BETA14"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_NUMBER = 0; public const BUILD_CHANNEL = "beta"; From 5556861000563db6bd1108b6d782292ca3ef746f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Nov 2021 00:46:21 +0000 Subject: [PATCH 3203/3224] ItemFactory: move SweetBerries registration to the correct place --- src/item/ItemFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 0e1a710ce5..95622b4e91 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -252,6 +252,7 @@ class ItemFactory{ $this->register(new Steak(new ItemIdentifier(ItemIds::STEAK, 0), "Steak")); $this->register(new Stick(new ItemIdentifier(ItemIds::STICK, 0), "Stick")); $this->register(new StringItem(new ItemIdentifier(ItemIds::STRING, 0), "String")); + $this->register(new SweetBerries(new ItemIdentifier(ItemIds::SWEET_BERRIES, 0), "Sweet Berries")); $this->register(new Totem(new ItemIdentifier(ItemIds::TOTEM, 0), "Totem of Undying")); $this->register(new WheatSeeds(new ItemIdentifier(ItemIds::WHEAT_SEEDS, 0), "Wheat Seeds")); $this->register(new WritableBook(new ItemIdentifier(ItemIds::WRITABLE_BOOK, 0), "Book & Quill")); @@ -327,7 +328,6 @@ class ItemFactory{ //TODO: minecraft:shield //TODO: minecraft:sparkler //TODO: minecraft:spawn_egg - $this->register(new SweetBerries(new ItemIdentifier(ItemIds::SWEET_BERRIES, 0), "Sweet Berries")); //TODO: minecraft:tnt_minecart //TODO: minecraft:trident //TODO: minecraft:turtle_helmet From 1bc7869f6e17d68785e33503a97128953b5fade0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 26 Nov 2021 01:58:52 +0000 Subject: [PATCH 3204/3224] Added remapping for almost 4000 invalid blockstates when a block has sole ownership of an ID, the state bitmask can be ignored and we can just claim the whole metadata range for that single block. This fixes a large number of issues with unknown blocks on older worlds where world editors did not remove the metadata, although update blocks will currently still appear on initial chunk send due to lack of AOT conversion (TODO). --- src/block/BlockFactory.php | 664 +++++++++--------- .../block_factory_consistency_check.json | 2 +- 2 files changed, 338 insertions(+), 328 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 70077b71a0..fd252f7892 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -105,86 +105,86 @@ class BlockFactory{ $this->blastResistance = \SplFixedArray::fromArray(array_fill(0, 1024 << Block::INTERNAL_METADATA_BITS, 0.0)); $railBreakInfo = new BlockBreakInfo(0.7); - $this->register(new ActivatorRail(new BID(Ids::ACTIVATOR_RAIL, 0), "Activator Rail", $railBreakInfo)); - $this->register(new Air(new BID(Ids::AIR, 0), "Air", BlockBreakInfo::indestructible(-1.0))); - $this->register(new Anvil(new BID(Ids::ANVIL, 0), "Anvil", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 6000.0))); - $this->register(new Bamboo(new BID(Ids::BAMBOO, 0), "Bamboo", new BlockBreakInfo(2.0 /* 1.0 in PC */, BlockToolType::AXE))); - $this->register(new BambooSapling(new BID(Ids::BAMBOO_SAPLING, 0), "Bamboo Sapling", BlockBreakInfo::instant())); + $this->registerAllMeta(new ActivatorRail(new BID(Ids::ACTIVATOR_RAIL, 0), "Activator Rail", $railBreakInfo)); + $this->registerAllMeta(new Air(new BID(Ids::AIR, 0), "Air", BlockBreakInfo::indestructible(-1.0))); + $this->registerAllMeta(new Anvil(new BID(Ids::ANVIL, 0), "Anvil", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 6000.0))); + $this->registerAllMeta(new Bamboo(new BID(Ids::BAMBOO, 0), "Bamboo", new BlockBreakInfo(2.0 /* 1.0 in PC */, BlockToolType::AXE))); + $this->registerAllMeta(new BambooSapling(new BID(Ids::BAMBOO_SAPLING, 0), "Bamboo Sapling", BlockBreakInfo::instant())); $bannerBreakInfo = new BlockBreakInfo(1.0, BlockToolType::AXE); - $this->register(new FloorBanner(new BID(Ids::STANDING_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Banner", $bannerBreakInfo)); - $this->register(new WallBanner(new BID(Ids::WALL_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Wall Banner", $bannerBreakInfo)); - $this->register(new Barrel(new BID(Ids::BARREL, 0, null, TileBarrel::class), "Barrel", new BlockBreakInfo(2.5, BlockToolType::AXE))); - $this->register(new Transparent(new BID(Ids::BARRIER, 0), "Barrier", BlockBreakInfo::indestructible())); - $this->register(new Beacon(new BID(Ids::BEACON, 0, null, TileBeacon::class), "Beacon", new BlockBreakInfo(3.0))); - $this->register(new Bed(new BID(Ids::BED_BLOCK, 0, ItemIds::BED, TileBed::class), "Bed Block", new BlockBreakInfo(0.2))); - $this->register(new Bedrock(new BID(Ids::BEDROCK, 0), "Bedrock", BlockBreakInfo::indestructible())); + $this->registerAllMeta(new FloorBanner(new BID(Ids::STANDING_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Banner", $bannerBreakInfo)); + $this->registerAllMeta(new WallBanner(new BID(Ids::WALL_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Wall Banner", $bannerBreakInfo)); + $this->registerAllMeta(new Barrel(new BID(Ids::BARREL, 0, null, TileBarrel::class), "Barrel", new BlockBreakInfo(2.5, BlockToolType::AXE))); + $this->registerAllMeta(new Transparent(new BID(Ids::BARRIER, 0), "Barrier", BlockBreakInfo::indestructible())); + $this->registerAllMeta(new Beacon(new BID(Ids::BEACON, 0, null, TileBeacon::class), "Beacon", new BlockBreakInfo(3.0))); + $this->registerAllMeta(new Bed(new BID(Ids::BED_BLOCK, 0, ItemIds::BED, TileBed::class), "Bed Block", new BlockBreakInfo(0.2))); + $this->registerAllMeta(new Bedrock(new BID(Ids::BEDROCK, 0), "Bedrock", BlockBreakInfo::indestructible())); - $this->register(new Beetroot(new BID(Ids::BEETROOT_BLOCK, 0), "Beetroot Block", BlockBreakInfo::instant())); - $this->register(new Bell(new BID(Ids::BELL, 0, null, TileBell::class), "Bell", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - $this->register(new BlueIce(new BID(Ids::BLUE_ICE, 0), "Blue Ice", new BlockBreakInfo(2.8, BlockToolType::PICKAXE))); - $this->register(new BoneBlock(new BID(Ids::BONE_BLOCK, 0), "Bone Block", new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - $this->register(new Bookshelf(new BID(Ids::BOOKSHELF, 0), "Bookshelf", new BlockBreakInfo(1.5, BlockToolType::AXE))); - $this->register(new BrewingStand(new BID(Ids::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND, TileBrewingStand::class), "Brewing Stand", new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->registerAllMeta(new Beetroot(new BID(Ids::BEETROOT_BLOCK, 0), "Beetroot Block", BlockBreakInfo::instant())); + $this->registerAllMeta(new Bell(new BID(Ids::BELL, 0, null, TileBell::class), "Bell", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->registerAllMeta(new BlueIce(new BID(Ids::BLUE_ICE, 0), "Blue Ice", new BlockBreakInfo(2.8, BlockToolType::PICKAXE))); + $this->registerAllMeta(new BoneBlock(new BID(Ids::BONE_BLOCK, 0), "Bone Block", new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->registerAllMeta(new Bookshelf(new BID(Ids::BOOKSHELF, 0), "Bookshelf", new BlockBreakInfo(1.5, BlockToolType::AXE))); + $this->registerAllMeta(new BrewingStand(new BID(Ids::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND, TileBrewingStand::class), "Brewing Stand", new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); $bricksBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - $this->register(new Stair(new BID(Ids::BRICK_STAIRS, 0), "Brick Stairs", $bricksBreakInfo)); - $this->register(new Opaque(new BID(Ids::BRICK_BLOCK, 0), "Bricks", $bricksBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::BRICK_STAIRS, 0), "Brick Stairs", $bricksBreakInfo)); + $this->registerAllMeta(new Opaque(new BID(Ids::BRICK_BLOCK, 0), "Bricks", $bricksBreakInfo)); - $this->register(new BrownMushroom(new BID(Ids::BROWN_MUSHROOM, 0), "Brown Mushroom", BlockBreakInfo::instant())); - $this->register(new Cactus(new BID(Ids::CACTUS, 0), "Cactus", new BlockBreakInfo(0.4))); - $this->register(new Cake(new BID(Ids::CAKE_BLOCK, 0, ItemIds::CAKE), "Cake", new BlockBreakInfo(0.5))); - $this->register(new Carrot(new BID(Ids::CARROTS, 0), "Carrot Block", BlockBreakInfo::instant())); + $this->registerAllMeta(new BrownMushroom(new BID(Ids::BROWN_MUSHROOM, 0), "Brown Mushroom", BlockBreakInfo::instant())); + $this->registerAllMeta(new Cactus(new BID(Ids::CACTUS, 0), "Cactus", new BlockBreakInfo(0.4))); + $this->registerAllMeta(new Cake(new BID(Ids::CAKE_BLOCK, 0, ItemIds::CAKE), "Cake", new BlockBreakInfo(0.5))); + $this->registerAllMeta(new Carrot(new BID(Ids::CARROTS, 0), "Carrot Block", BlockBreakInfo::instant())); $chestBreakInfo = new BlockBreakInfo(2.5, BlockToolType::AXE); - $this->register(new Chest(new BID(Ids::CHEST, 0, null, TileChest::class), "Chest", $chestBreakInfo)); - $this->register(new Clay(new BID(Ids::CLAY_BLOCK, 0), "Clay Block", new BlockBreakInfo(0.6, BlockToolType::SHOVEL))); - $this->register(new Coal(new BID(Ids::COAL_BLOCK, 0), "Coal Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0))); - $this->register(new CoalOre(new BID(Ids::COAL_ORE, 0), "Coal Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->registerAllMeta(new Chest(new BID(Ids::CHEST, 0, null, TileChest::class), "Chest", $chestBreakInfo)); + $this->registerAllMeta(new Clay(new BID(Ids::CLAY_BLOCK, 0), "Clay Block", new BlockBreakInfo(0.6, BlockToolType::SHOVEL))); + $this->registerAllMeta(new Coal(new BID(Ids::COAL_BLOCK, 0), "Coal Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0))); + $this->registerAllMeta(new CoalOre(new BID(Ids::COAL_ORE, 0), "Coal Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); $cobblestoneBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - $this->register($cobblestone = new Opaque(new BID(Ids::COBBLESTONE, 0), "Cobblestone", $cobblestoneBreakInfo)); + $this->registerAllMeta($cobblestone = new Opaque(new BID(Ids::COBBLESTONE, 0), "Cobblestone", $cobblestoneBreakInfo)); $infestedStoneBreakInfo = new BlockBreakInfo(0.75); $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_COBBLESTONE), "Infested Cobblestone", $infestedStoneBreakInfo, $cobblestone)); - $this->register(new Opaque(new BID(Ids::MOSSY_COBBLESTONE, 0), "Mossy Cobblestone", $cobblestoneBreakInfo)); - $this->register(new Stair(new BID(Ids::COBBLESTONE_STAIRS, 0), "Cobblestone Stairs", $cobblestoneBreakInfo)); - $this->register(new Stair(new BID(Ids::MOSSY_COBBLESTONE_STAIRS, 0), "Mossy Cobblestone Stairs", $cobblestoneBreakInfo)); + $this->registerAllMeta(new Opaque(new BID(Ids::MOSSY_COBBLESTONE, 0), "Mossy Cobblestone", $cobblestoneBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::COBBLESTONE_STAIRS, 0), "Cobblestone Stairs", $cobblestoneBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::MOSSY_COBBLESTONE_STAIRS, 0), "Mossy Cobblestone Stairs", $cobblestoneBreakInfo)); - $this->register(new Cobweb(new BID(Ids::COBWEB, 0), "Cobweb", new BlockBreakInfo(4.0, BlockToolType::SWORD | BlockToolType::SHEARS, 1))); - $this->register(new CocoaBlock(new BID(Ids::COCOA, 0), "Cocoa Block", new BlockBreakInfo(0.2, BlockToolType::AXE, 0, 15.0))); - $this->register(new CoralBlock(new BID(Ids::CORAL_BLOCK, 0), "Coral Block", new BlockBreakInfo(7.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - $this->register(new CraftingTable(new BID(Ids::CRAFTING_TABLE, 0), "Crafting Table", new BlockBreakInfo(2.5, BlockToolType::AXE))); - $this->register(new DaylightSensor(new BIDFlattened(Ids::DAYLIGHT_DETECTOR, [Ids::DAYLIGHT_DETECTOR_INVERTED], 0, null, TileDaylightSensor::class), "Daylight Sensor", new BlockBreakInfo(0.2, BlockToolType::AXE))); - $this->register(new DeadBush(new BID(Ids::DEADBUSH, 0), "Dead Bush", BlockBreakInfo::instant(BlockToolType::SHEARS, 1))); - $this->register(new DetectorRail(new BID(Ids::DETECTOR_RAIL, 0), "Detector Rail", $railBreakInfo)); + $this->registerAllMeta(new Cobweb(new BID(Ids::COBWEB, 0), "Cobweb", new BlockBreakInfo(4.0, BlockToolType::SWORD | BlockToolType::SHEARS, 1))); + $this->registerAllMeta(new CocoaBlock(new BID(Ids::COCOA, 0), "Cocoa Block", new BlockBreakInfo(0.2, BlockToolType::AXE, 0, 15.0))); + $this->registerAllMeta(new CoralBlock(new BID(Ids::CORAL_BLOCK, 0), "Coral Block", new BlockBreakInfo(7.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->registerAllMeta(new CraftingTable(new BID(Ids::CRAFTING_TABLE, 0), "Crafting Table", new BlockBreakInfo(2.5, BlockToolType::AXE))); + $this->registerAllMeta(new DaylightSensor(new BIDFlattened(Ids::DAYLIGHT_DETECTOR, [Ids::DAYLIGHT_DETECTOR_INVERTED], 0, null, TileDaylightSensor::class), "Daylight Sensor", new BlockBreakInfo(0.2, BlockToolType::AXE))); + $this->registerAllMeta(new DeadBush(new BID(Ids::DEADBUSH, 0), "Dead Bush", BlockBreakInfo::instant(BlockToolType::SHEARS, 1))); + $this->registerAllMeta(new DetectorRail(new BID(Ids::DETECTOR_RAIL, 0), "Detector Rail", $railBreakInfo)); - $this->register(new Opaque(new BID(Ids::DIAMOND_BLOCK, 0), "Diamond Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); - $this->register(new DiamondOre(new BID(Ids::DIAMOND_ORE, 0), "Diamond Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); - $this->register(new Dirt(new BID(Ids::DIRT, 0), "Dirt", new BlockBreakInfo(0.5, BlockToolType::SHOVEL))); + $this->registerAllMeta(new Opaque(new BID(Ids::DIAMOND_BLOCK, 0), "Diamond Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); + $this->registerAllMeta(new DiamondOre(new BID(Ids::DIAMOND_ORE, 0), "Diamond Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); + $this->registerAllMeta(new Dirt(new BID(Ids::DIRT, 0), "Dirt", new BlockBreakInfo(0.5, BlockToolType::SHOVEL))); $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_SUNFLOWER), "Sunflower", BlockBreakInfo::instant())); $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LILAC), "Lilac", BlockBreakInfo::instant())); $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_ROSE_BUSH), "Rose Bush", BlockBreakInfo::instant())); $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_PEONY), "Peony", BlockBreakInfo::instant())); $this->register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_TALLGRASS), "Double Tallgrass", BlockBreakInfo::instant(BlockToolType::SHEARS, 1))); $this->register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LARGE_FERN), "Large Fern", BlockBreakInfo::instant(BlockToolType::SHEARS, 1))); - $this->register(new DragonEgg(new BID(Ids::DRAGON_EGG, 0), "Dragon Egg", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - $this->register(new DriedKelp(new BID(Ids::DRIED_KELP_BLOCK, 0), "Dried Kelp Block", new BlockBreakInfo(0.5, BlockToolType::NONE, 0, 12.5))); - $this->register(new Opaque(new BID(Ids::EMERALD_BLOCK, 0), "Emerald Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); - $this->register(new EmeraldOre(new BID(Ids::EMERALD_ORE, 0), "Emerald Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); - $this->register(new EnchantingTable(new BID(Ids::ENCHANTING_TABLE, 0, null, TileEnchantingTable::class), "Enchanting Table", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 6000.0))); - $this->register(new EndPortalFrame(new BID(Ids::END_PORTAL_FRAME, 0), "End Portal Frame", BlockBreakInfo::indestructible())); - $this->register(new EndRod(new BID(Ids::END_ROD, 0), "End Rod", BlockBreakInfo::instant())); - $this->register(new Opaque(new BID(Ids::END_STONE, 0), "End Stone", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 45.0))); + $this->registerAllMeta(new DragonEgg(new BID(Ids::DRAGON_EGG, 0), "Dragon Egg", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->registerAllMeta(new DriedKelp(new BID(Ids::DRIED_KELP_BLOCK, 0), "Dried Kelp Block", new BlockBreakInfo(0.5, BlockToolType::NONE, 0, 12.5))); + $this->registerAllMeta(new Opaque(new BID(Ids::EMERALD_BLOCK, 0), "Emerald Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); + $this->registerAllMeta(new EmeraldOre(new BID(Ids::EMERALD_ORE, 0), "Emerald Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); + $this->registerAllMeta(new EnchantingTable(new BID(Ids::ENCHANTING_TABLE, 0, null, TileEnchantingTable::class), "Enchanting Table", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 6000.0))); + $this->registerAllMeta(new EndPortalFrame(new BID(Ids::END_PORTAL_FRAME, 0), "End Portal Frame", BlockBreakInfo::indestructible())); + $this->registerAllMeta(new EndRod(new BID(Ids::END_ROD, 0), "End Rod", BlockBreakInfo::instant())); + $this->registerAllMeta(new Opaque(new BID(Ids::END_STONE, 0), "End Stone", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 45.0))); $endBrickBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 4.0); - $this->register(new Opaque(new BID(Ids::END_BRICKS, 0), "End Stone Bricks", $endBrickBreakInfo)); - $this->register(new Stair(new BID(Ids::END_BRICK_STAIRS, 0), "End Stone Brick Stairs", $endBrickBreakInfo)); + $this->registerAllMeta(new Opaque(new BID(Ids::END_BRICKS, 0), "End Stone Bricks", $endBrickBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::END_BRICK_STAIRS, 0), "End Stone Brick Stairs", $endBrickBreakInfo)); - $this->register(new EnderChest(new BID(Ids::ENDER_CHEST, 0, null, TileEnderChest::class), "Ender Chest", new BlockBreakInfo(22.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 3000.0))); - $this->register(new Farmland(new BID(Ids::FARMLAND, 0), "Farmland", new BlockBreakInfo(0.6, BlockToolType::SHOVEL))); - $this->register(new Fire(new BID(Ids::FIRE, 0), "Fire Block", BlockBreakInfo::instant())); - $this->register(new FletchingTable(new BID(Ids::FLETCHING_TABLE, 0), "Fletching Table", new BlockBreakInfo(2.5, BlockToolType::AXE, 0, 2.5))); - $this->register(new Flower(new BID(Ids::DANDELION, 0), "Dandelion", BlockBreakInfo::instant())); + $this->registerAllMeta(new EnderChest(new BID(Ids::ENDER_CHEST, 0, null, TileEnderChest::class), "Ender Chest", new BlockBreakInfo(22.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 3000.0))); + $this->registerAllMeta(new Farmland(new BID(Ids::FARMLAND, 0), "Farmland", new BlockBreakInfo(0.6, BlockToolType::SHOVEL))); + $this->registerAllMeta(new Fire(new BID(Ids::FIRE, 0), "Fire Block", BlockBreakInfo::instant())); + $this->registerAllMeta(new FletchingTable(new BID(Ids::FLETCHING_TABLE, 0), "Fletching Table", new BlockBreakInfo(2.5, BlockToolType::AXE, 0, 2.5))); + $this->registerAllMeta(new Flower(new BID(Ids::DANDELION, 0), "Dandelion", BlockBreakInfo::instant())); $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ALLIUM), "Allium", BlockBreakInfo::instant())); $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_AZURE_BLUET), "Azure Bluet", BlockBreakInfo::instant())); $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_BLUE_ORCHID), "Blue Orchid", BlockBreakInfo::instant())); @@ -196,141 +196,133 @@ class BlockFactory{ $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_POPPY), "Poppy", BlockBreakInfo::instant())); $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_RED_TULIP), "Red Tulip", BlockBreakInfo::instant())); $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_WHITE_TULIP), "White Tulip", BlockBreakInfo::instant())); - - $flowerPot = new FlowerPot(new BID(Ids::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, TileFlowerPot::class), "Flower Pot", BlockBreakInfo::instant()); - $this->register($flowerPot); - for($meta = 1; $meta < 16; ++$meta){ - $this->remap(Ids::FLOWER_POT_BLOCK, $meta, $flowerPot); - } - $this->register(new FrostedIce(new BID(Ids::FROSTED_ICE, 0), "Frosted Ice", new BlockBreakInfo(2.5, BlockToolType::PICKAXE))); - $this->register(new Furnace(new BIDFlattened(Ids::FURNACE, [Ids::LIT_FURNACE], 0, null, TileNormalFurnace::class), "Furnace", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - $this->register(new Furnace(new BIDFlattened(Ids::BLAST_FURNACE, [Ids::LIT_BLAST_FURNACE], 0, null, TileBlastFurnace::class), "Blast Furnace", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - $this->register(new Furnace(new BIDFlattened(Ids::SMOKER, [Ids::LIT_SMOKER], 0, null, TileSmoker::class), "Smoker", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->registerAllMeta(new FlowerPot(new BID(Ids::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, TileFlowerPot::class), "Flower Pot", BlockBreakInfo::instant())); + $this->registerAllMeta(new FrostedIce(new BID(Ids::FROSTED_ICE, 0), "Frosted Ice", new BlockBreakInfo(2.5, BlockToolType::PICKAXE))); + $this->registerAllMeta(new Furnace(new BIDFlattened(Ids::FURNACE, [Ids::LIT_FURNACE], 0, null, TileNormalFurnace::class), "Furnace", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->registerAllMeta(new Furnace(new BIDFlattened(Ids::BLAST_FURNACE, [Ids::LIT_BLAST_FURNACE], 0, null, TileBlastFurnace::class), "Blast Furnace", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->registerAllMeta(new Furnace(new BIDFlattened(Ids::SMOKER, [Ids::LIT_SMOKER], 0, null, TileSmoker::class), "Smoker", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); $glassBreakInfo = new BlockBreakInfo(0.3); - $this->register(new Glass(new BID(Ids::GLASS, 0), "Glass", $glassBreakInfo)); - $this->register(new GlassPane(new BID(Ids::GLASS_PANE, 0), "Glass Pane", $glassBreakInfo)); - $this->register(new GlowingObsidian(new BID(Ids::GLOWINGOBSIDIAN, 0), "Glowing Obsidian", new BlockBreakInfo(10.0, BlockToolType::PICKAXE, ToolTier::DIAMOND()->getHarvestLevel(), 50.0))); - $this->register(new Glowstone(new BID(Ids::GLOWSTONE, 0), "Glowstone", new BlockBreakInfo(0.3, BlockToolType::PICKAXE))); - $this->register(new Opaque(new BID(Ids::GOLD_BLOCK, 0), "Gold Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); - $this->register(new Opaque(new BID(Ids::GOLD_ORE, 0), "Gold Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); + $this->registerAllMeta(new Glass(new BID(Ids::GLASS, 0), "Glass", $glassBreakInfo)); + $this->registerAllMeta(new GlassPane(new BID(Ids::GLASS_PANE, 0), "Glass Pane", $glassBreakInfo)); + $this->registerAllMeta(new GlowingObsidian(new BID(Ids::GLOWINGOBSIDIAN, 0), "Glowing Obsidian", new BlockBreakInfo(10.0, BlockToolType::PICKAXE, ToolTier::DIAMOND()->getHarvestLevel(), 50.0))); + $this->registerAllMeta(new Glowstone(new BID(Ids::GLOWSTONE, 0), "Glowstone", new BlockBreakInfo(0.3, BlockToolType::PICKAXE))); + $this->registerAllMeta(new Opaque(new BID(Ids::GOLD_BLOCK, 0), "Gold Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); + $this->registerAllMeta(new Opaque(new BID(Ids::GOLD_ORE, 0), "Gold Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); $grassBreakInfo = new BlockBreakInfo(0.6, BlockToolType::SHOVEL); - $this->register(new Grass(new BID(Ids::GRASS, 0), "Grass", $grassBreakInfo)); - $this->register(new GrassPath(new BID(Ids::GRASS_PATH, 0), "Grass Path", $grassBreakInfo)); - $this->register(new Gravel(new BID(Ids::GRAVEL, 0), "Gravel", new BlockBreakInfo(0.6, BlockToolType::SHOVEL))); + $this->registerAllMeta(new Grass(new BID(Ids::GRASS, 0), "Grass", $grassBreakInfo)); + $this->registerAllMeta(new GrassPath(new BID(Ids::GRASS_PATH, 0), "Grass Path", $grassBreakInfo)); + $this->registerAllMeta(new Gravel(new BID(Ids::GRAVEL, 0), "Gravel", new BlockBreakInfo(0.6, BlockToolType::SHOVEL))); $hardenedClayBreakInfo = new BlockBreakInfo(1.25, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 21.0); - $this->register(new HardenedClay(new BID(Ids::HARDENED_CLAY, 0), "Hardened Clay", $hardenedClayBreakInfo)); + $this->registerAllMeta(new HardenedClay(new BID(Ids::HARDENED_CLAY, 0), "Hardened Clay", $hardenedClayBreakInfo)); $hardenedGlassBreakInfo = new BlockBreakInfo(10.0); - $this->register(new HardenedGlass(new BID(Ids::HARD_GLASS, 0), "Hardened Glass", $hardenedGlassBreakInfo)); - $this->register(new HardenedGlassPane(new BID(Ids::HARD_GLASS_PANE, 0), "Hardened Glass Pane", $hardenedGlassBreakInfo)); - $this->register(new HayBale(new BID(Ids::HAY_BALE, 0), "Hay Bale", new BlockBreakInfo(0.5))); - $this->register(new Hopper(new BID(Ids::HOPPER_BLOCK, 0, ItemIds::HOPPER, TileHopper::class), "Hopper", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 15.0))); - $this->register(new Ice(new BID(Ids::ICE, 0), "Ice", new BlockBreakInfo(0.5, BlockToolType::PICKAXE))); + $this->registerAllMeta(new HardenedGlass(new BID(Ids::HARD_GLASS, 0), "Hardened Glass", $hardenedGlassBreakInfo)); + $this->registerAllMeta(new HardenedGlassPane(new BID(Ids::HARD_GLASS_PANE, 0), "Hardened Glass Pane", $hardenedGlassBreakInfo)); + $this->registerAllMeta(new HayBale(new BID(Ids::HAY_BALE, 0), "Hay Bale", new BlockBreakInfo(0.5))); + $this->registerAllMeta(new Hopper(new BID(Ids::HOPPER_BLOCK, 0, ItemIds::HOPPER, TileHopper::class), "Hopper", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 15.0))); + $this->registerAllMeta(new Ice(new BID(Ids::ICE, 0), "Ice", new BlockBreakInfo(0.5, BlockToolType::PICKAXE))); $updateBlockBreakInfo = new BlockBreakInfo(1.0); - $this->register(new Opaque(new BID(Ids::INFO_UPDATE, 0), "update!", $updateBlockBreakInfo)); - $this->register(new Opaque(new BID(Ids::INFO_UPDATE2, 0), "ate!upd", $updateBlockBreakInfo)); - $this->register(new Transparent(new BID(Ids::INVISIBLEBEDROCK, 0), "Invisible Bedrock", BlockBreakInfo::indestructible())); + $this->registerAllMeta(new Opaque(new BID(Ids::INFO_UPDATE, 0), "update!", $updateBlockBreakInfo)); + $this->registerAllMeta(new Opaque(new BID(Ids::INFO_UPDATE2, 0), "ate!upd", $updateBlockBreakInfo)); + $this->registerAllMeta(new Transparent(new BID(Ids::INVISIBLEBEDROCK, 0), "Invisible Bedrock", BlockBreakInfo::indestructible())); $ironBreakInfo = new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel(), 30.0); - $this->register(new Opaque(new BID(Ids::IRON_BLOCK, 0), "Iron Block", $ironBreakInfo)); - $this->register(new Thin(new BID(Ids::IRON_BARS, 0), "Iron Bars", $ironBreakInfo)); + $this->registerAllMeta(new Opaque(new BID(Ids::IRON_BLOCK, 0), "Iron Block", $ironBreakInfo)); + $this->registerAllMeta(new Thin(new BID(Ids::IRON_BARS, 0), "Iron Bars", $ironBreakInfo)); $ironDoorBreakInfo = new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0); - $this->register(new Door(new BID(Ids::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door", $ironDoorBreakInfo)); - $this->register(new Trapdoor(new BID(Ids::IRON_TRAPDOOR, 0), "Iron Trapdoor", $ironDoorBreakInfo)); - $this->register(new Opaque(new BID(Ids::IRON_ORE, 0), "Iron Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); - $this->register(new ItemFrame(new BID(Ids::FRAME_BLOCK, 0, ItemIds::FRAME, TileItemFrame::class), "Item Frame", new BlockBreakInfo(0.25))); - $this->register(new Jukebox(new BID(Ids::JUKEBOX, 0, ItemIds::JUKEBOX, TileJukebox::class), "Jukebox", new BlockBreakInfo(0.8, BlockToolType::AXE))); //TODO: in PC the hardness is 2.0, not 0.8, unsure if this is a MCPE bug or not - $this->register(new Ladder(new BID(Ids::LADDER, 0), "Ladder", new BlockBreakInfo(0.4, BlockToolType::AXE))); - $this->register(new Lantern(new BID(Ids::LANTERN, 0), "Lantern", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - $this->register(new Opaque(new BID(Ids::LAPIS_BLOCK, 0), "Lapis Lazuli Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); - $this->register(new LapisOre(new BID(Ids::LAPIS_ORE, 0), "Lapis Lazuli Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); - $this->register(new Lava(new BIDFlattened(Ids::FLOWING_LAVA, [Ids::STILL_LAVA], 0), "Lava", BlockBreakInfo::indestructible(500.0))); - $this->register(new Lever(new BID(Ids::LEVER, 0), "Lever", new BlockBreakInfo(0.5))); - $this->register(new Loom(new BID(Ids::LOOM, 0), "Loom", new BlockBreakInfo(2.5, BlockToolType::AXE))); - $this->register(new Magma(new BID(Ids::MAGMA, 0), "Magma Block", new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - $this->register(new Melon(new BID(Ids::MELON_BLOCK, 0), "Melon Block", new BlockBreakInfo(1.0, BlockToolType::AXE))); - $this->register(new MelonStem(new BID(Ids::MELON_STEM, 0, ItemIds::MELON_SEEDS), "Melon Stem", BlockBreakInfo::instant())); - $this->register(new MonsterSpawner(new BID(Ids::MOB_SPAWNER, 0, null, TileMonsterSpawner::class), "Monster Spawner", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - $this->register(new Mycelium(new BID(Ids::MYCELIUM, 0), "Mycelium", new BlockBreakInfo(0.6, BlockToolType::SHOVEL))); + $this->registerAllMeta(new Door(new BID(Ids::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door", $ironDoorBreakInfo)); + $this->registerAllMeta(new Trapdoor(new BID(Ids::IRON_TRAPDOOR, 0), "Iron Trapdoor", $ironDoorBreakInfo)); + $this->registerAllMeta(new Opaque(new BID(Ids::IRON_ORE, 0), "Iron Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); + $this->registerAllMeta(new ItemFrame(new BID(Ids::FRAME_BLOCK, 0, ItemIds::FRAME, TileItemFrame::class), "Item Frame", new BlockBreakInfo(0.25))); + $this->registerAllMeta(new Jukebox(new BID(Ids::JUKEBOX, 0, ItemIds::JUKEBOX, TileJukebox::class), "Jukebox", new BlockBreakInfo(0.8, BlockToolType::AXE))); //TODO: in PC the hardness is 2.0, not 0.8, unsure if this is a MCPE bug or not + $this->registerAllMeta(new Ladder(new BID(Ids::LADDER, 0), "Ladder", new BlockBreakInfo(0.4, BlockToolType::AXE))); + $this->registerAllMeta(new Lantern(new BID(Ids::LANTERN, 0), "Lantern", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->registerAllMeta(new Opaque(new BID(Ids::LAPIS_BLOCK, 0), "Lapis Lazuli Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); + $this->registerAllMeta(new LapisOre(new BID(Ids::LAPIS_ORE, 0), "Lapis Lazuli Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel()))); + $this->registerAllMeta(new Lava(new BIDFlattened(Ids::FLOWING_LAVA, [Ids::STILL_LAVA], 0), "Lava", BlockBreakInfo::indestructible(500.0))); + $this->registerAllMeta(new Lever(new BID(Ids::LEVER, 0), "Lever", new BlockBreakInfo(0.5))); + $this->registerAllMeta(new Loom(new BID(Ids::LOOM, 0), "Loom", new BlockBreakInfo(2.5, BlockToolType::AXE))); + $this->registerAllMeta(new Magma(new BID(Ids::MAGMA, 0), "Magma Block", new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->registerAllMeta(new Melon(new BID(Ids::MELON_BLOCK, 0), "Melon Block", new BlockBreakInfo(1.0, BlockToolType::AXE))); + $this->registerAllMeta(new MelonStem(new BID(Ids::MELON_STEM, 0, ItemIds::MELON_SEEDS), "Melon Stem", BlockBreakInfo::instant())); + $this->registerAllMeta(new MonsterSpawner(new BID(Ids::MOB_SPAWNER, 0, null, TileMonsterSpawner::class), "Monster Spawner", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->registerAllMeta(new Mycelium(new BID(Ids::MYCELIUM, 0), "Mycelium", new BlockBreakInfo(0.6, BlockToolType::SHOVEL))); $netherBrickBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - $this->register(new Opaque(new BID(Ids::NETHER_BRICK_BLOCK, 0), "Nether Bricks", $netherBrickBreakInfo)); - $this->register(new Opaque(new BID(Ids::RED_NETHER_BRICK, 0), "Red Nether Bricks", $netherBrickBreakInfo)); - $this->register(new Fence(new BID(Ids::NETHER_BRICK_FENCE, 0), "Nether Brick Fence", $netherBrickBreakInfo)); - $this->register(new Stair(new BID(Ids::NETHER_BRICK_STAIRS, 0), "Nether Brick Stairs", $netherBrickBreakInfo)); - $this->register(new Stair(new BID(Ids::RED_NETHER_BRICK_STAIRS, 0), "Red Nether Brick Stairs", $netherBrickBreakInfo)); - $this->register(new NetherPortal(new BID(Ids::PORTAL, 0), "Nether Portal", BlockBreakInfo::indestructible(0.0))); - $this->register(new NetherQuartzOre(new BID(Ids::NETHER_QUARTZ_ORE, 0), "Nether Quartz Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - $this->register(new NetherReactor(new BID(Ids::NETHERREACTOR, 0), "Nether Reactor Core", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - $this->register(new Opaque(new BID(Ids::NETHER_WART_BLOCK, 0), "Nether Wart Block", new BlockBreakInfo(1.0))); - $this->register(new NetherWartPlant(new BID(Ids::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART), "Nether Wart", BlockBreakInfo::instant())); - $this->register(new Netherrack(new BID(Ids::NETHERRACK, 0), "Netherrack", new BlockBreakInfo(0.4, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - $this->register(new Note(new BID(Ids::NOTEBLOCK, 0, null, TileNote::class), "Note Block", new BlockBreakInfo(0.8, BlockToolType::AXE))); - $this->register(new Opaque(new BID(Ids::OBSIDIAN, 0), "Obsidian", new BlockBreakInfo(35.0 /* 50 in PC */, BlockToolType::PICKAXE, ToolTier::DIAMOND()->getHarvestLevel(), 6000.0))); - $this->register(new PackedIce(new BID(Ids::PACKED_ICE, 0), "Packed Ice", new BlockBreakInfo(0.5, BlockToolType::PICKAXE))); - $this->register(new Podzol(new BID(Ids::PODZOL, 0), "Podzol", new BlockBreakInfo(0.5, BlockToolType::SHOVEL))); - $this->register(new Potato(new BID(Ids::POTATOES, 0), "Potato Block", BlockBreakInfo::instant())); - $this->register(new PoweredRail(new BID(Ids::GOLDEN_RAIL, Meta::RAIL_STRAIGHT_NORTH_SOUTH), "Powered Rail", $railBreakInfo)); + $this->registerAllMeta(new Opaque(new BID(Ids::NETHER_BRICK_BLOCK, 0), "Nether Bricks", $netherBrickBreakInfo)); + $this->registerAllMeta(new Opaque(new BID(Ids::RED_NETHER_BRICK, 0), "Red Nether Bricks", $netherBrickBreakInfo)); + $this->registerAllMeta(new Fence(new BID(Ids::NETHER_BRICK_FENCE, 0), "Nether Brick Fence", $netherBrickBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::NETHER_BRICK_STAIRS, 0), "Nether Brick Stairs", $netherBrickBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::RED_NETHER_BRICK_STAIRS, 0), "Red Nether Brick Stairs", $netherBrickBreakInfo)); + $this->registerAllMeta(new NetherPortal(new BID(Ids::PORTAL, 0), "Nether Portal", BlockBreakInfo::indestructible(0.0))); + $this->registerAllMeta(new NetherQuartzOre(new BID(Ids::NETHER_QUARTZ_ORE, 0), "Nether Quartz Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->registerAllMeta(new NetherReactor(new BID(Ids::NETHERREACTOR, 0), "Nether Reactor Core", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->registerAllMeta(new Opaque(new BID(Ids::NETHER_WART_BLOCK, 0), "Nether Wart Block", new BlockBreakInfo(1.0))); + $this->registerAllMeta(new NetherWartPlant(new BID(Ids::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART), "Nether Wart", BlockBreakInfo::instant())); + $this->registerAllMeta(new Netherrack(new BID(Ids::NETHERRACK, 0), "Netherrack", new BlockBreakInfo(0.4, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->registerAllMeta(new Note(new BID(Ids::NOTEBLOCK, 0, null, TileNote::class), "Note Block", new BlockBreakInfo(0.8, BlockToolType::AXE))); + $this->registerAllMeta(new Opaque(new BID(Ids::OBSIDIAN, 0), "Obsidian", new BlockBreakInfo(35.0 /* 50 in PC */, BlockToolType::PICKAXE, ToolTier::DIAMOND()->getHarvestLevel(), 6000.0))); + $this->registerAllMeta(new PackedIce(new BID(Ids::PACKED_ICE, 0), "Packed Ice", new BlockBreakInfo(0.5, BlockToolType::PICKAXE))); + $this->registerAllMeta(new Podzol(new BID(Ids::PODZOL, 0), "Podzol", new BlockBreakInfo(0.5, BlockToolType::SHOVEL))); + $this->registerAllMeta(new Potato(new BID(Ids::POTATOES, 0), "Potato Block", BlockBreakInfo::instant())); + $this->registerAllMeta(new PoweredRail(new BID(Ids::GOLDEN_RAIL, 0), "Powered Rail", $railBreakInfo)); $prismarineBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); $this->register(new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_BRICKS), "Prismarine Bricks", $prismarineBreakInfo)); - $this->register(new Stair(new BID(Ids::PRISMARINE_BRICKS_STAIRS, 0), "Prismarine Bricks Stairs", $prismarineBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::PRISMARINE_BRICKS_STAIRS, 0), "Prismarine Bricks Stairs", $prismarineBreakInfo)); $this->register(new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_DARK), "Dark Prismarine", $prismarineBreakInfo)); - $this->register(new Stair(new BID(Ids::DARK_PRISMARINE_STAIRS, 0), "Dark Prismarine Stairs", $prismarineBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::DARK_PRISMARINE_STAIRS, 0), "Dark Prismarine Stairs", $prismarineBreakInfo)); $this->register(new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_NORMAL), "Prismarine", $prismarineBreakInfo)); - $this->register(new Stair(new BID(Ids::PRISMARINE_STAIRS, 0), "Prismarine Stairs", $prismarineBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::PRISMARINE_STAIRS, 0), "Prismarine Stairs", $prismarineBreakInfo)); $pumpkinBreakInfo = new BlockBreakInfo(1.0, BlockToolType::AXE); - $this->register($pumpkin = new Opaque(new BID(Ids::PUMPKIN, 0), "Pumpkin", $pumpkinBreakInfo)); - for($i = 1; $i <= 3; ++$i){ - $this->remap(Ids::PUMPKIN, $i, $pumpkin); - } - $this->register(new CarvedPumpkin(new BID(Ids::CARVED_PUMPKIN, 0), "Carved Pumpkin", $pumpkinBreakInfo)); - $this->register(new LitPumpkin(new BID(Ids::JACK_O_LANTERN, 0), "Jack o'Lantern", $pumpkinBreakInfo)); + $this->registerAllMeta($pumpkin = new Opaque(new BID(Ids::PUMPKIN, 0), "Pumpkin", $pumpkinBreakInfo)); + $this->registerAllMeta(new CarvedPumpkin(new BID(Ids::CARVED_PUMPKIN, 0), "Carved Pumpkin", $pumpkinBreakInfo)); + $this->registerAllMeta(new LitPumpkin(new BID(Ids::JACK_O_LANTERN, 0), "Jack o'Lantern", $pumpkinBreakInfo)); - $this->register(new PumpkinStem(new BID(Ids::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem", BlockBreakInfo::instant())); + $this->registerAllMeta(new PumpkinStem(new BID(Ids::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem", BlockBreakInfo::instant())); $purpurBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); $this->register(new Opaque(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_NORMAL), "Purpur Block", $purpurBreakInfo)); $this->register(new SimplePillar(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_PILLAR), "Purpur Pillar", $purpurBreakInfo)); - $this->register(new Stair(new BID(Ids::PURPUR_STAIRS, 0), "Purpur Stairs", $purpurBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::PURPUR_STAIRS, 0), "Purpur Stairs", $purpurBreakInfo)); $quartzBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()); $this->register(new Opaque(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_NORMAL), "Quartz Block", $quartzBreakInfo)); - $this->register(new Stair(new BID(Ids::QUARTZ_STAIRS, 0), "Quartz Stairs", $quartzBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::QUARTZ_STAIRS, 0), "Quartz Stairs", $quartzBreakInfo)); $this->register(new SimplePillar(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_CHISELED), "Chiseled Quartz Block", $quartzBreakInfo)); $this->register(new SimplePillar(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_PILLAR), "Quartz Pillar", $quartzBreakInfo)); $this->register(new Opaque(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_SMOOTH), "Smooth Quartz Block", $quartzBreakInfo)); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) - $this->register(new Stair(new BID(Ids::SMOOTH_QUARTZ_STAIRS, 0), "Smooth Quartz Stairs", $quartzBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::SMOOTH_QUARTZ_STAIRS, 0), "Smooth Quartz Stairs", $quartzBreakInfo)); - $this->register(new Rail(new BID(Ids::RAIL, 0), "Rail", $railBreakInfo)); - $this->register(new RedMushroom(new BID(Ids::RED_MUSHROOM, 0), "Red Mushroom", BlockBreakInfo::instant())); - $this->register(new Redstone(new BID(Ids::REDSTONE_BLOCK, 0), "Redstone Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0))); - $this->register(new RedstoneComparator(new BIDFlattened(Ids::UNPOWERED_COMPARATOR, [Ids::POWERED_COMPARATOR], 0, ItemIds::COMPARATOR, TileComparator::class), "Redstone Comparator", BlockBreakInfo::instant())); - $this->register(new RedstoneLamp(new BIDFlattened(Ids::REDSTONE_LAMP, [Ids::LIT_REDSTONE_LAMP], 0), "Redstone Lamp", new BlockBreakInfo(0.3))); - $this->register(new RedstoneOre(new BIDFlattened(Ids::REDSTONE_ORE, [Ids::LIT_REDSTONE_ORE], 0), "Redstone Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); - $this->register(new RedstoneRepeater(new BIDFlattened(Ids::UNPOWERED_REPEATER, [Ids::POWERED_REPEATER], 0, ItemIds::REPEATER), "Redstone Repeater", BlockBreakInfo::instant())); - $this->register(new RedstoneTorch(new BIDFlattened(Ids::REDSTONE_TORCH, [Ids::UNLIT_REDSTONE_TORCH], 0), "Redstone Torch", BlockBreakInfo::instant())); - $this->register(new RedstoneWire(new BID(Ids::REDSTONE_WIRE, 0, ItemIds::REDSTONE), "Redstone", BlockBreakInfo::instant())); - $this->register(new Reserved6(new BID(Ids::RESERVED6, 0), "reserved6", BlockBreakInfo::instant())); + $this->registerAllMeta(new Rail(new BID(Ids::RAIL, 0), "Rail", $railBreakInfo)); + $this->registerAllMeta(new RedMushroom(new BID(Ids::RED_MUSHROOM, 0), "Red Mushroom", BlockBreakInfo::instant())); + $this->registerAllMeta(new Redstone(new BID(Ids::REDSTONE_BLOCK, 0), "Redstone Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0))); + $this->registerAllMeta(new RedstoneComparator(new BIDFlattened(Ids::UNPOWERED_COMPARATOR, [Ids::POWERED_COMPARATOR], 0, ItemIds::COMPARATOR, TileComparator::class), "Redstone Comparator", BlockBreakInfo::instant())); + $this->registerAllMeta(new RedstoneLamp(new BIDFlattened(Ids::REDSTONE_LAMP, [Ids::LIT_REDSTONE_LAMP], 0), "Redstone Lamp", new BlockBreakInfo(0.3))); + $this->registerAllMeta(new RedstoneOre(new BIDFlattened(Ids::REDSTONE_ORE, [Ids::LIT_REDSTONE_ORE], 0), "Redstone Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); + $this->registerAllMeta(new RedstoneRepeater(new BIDFlattened(Ids::UNPOWERED_REPEATER, [Ids::POWERED_REPEATER], 0, ItemIds::REPEATER), "Redstone Repeater", BlockBreakInfo::instant())); + $this->registerAllMeta(new RedstoneTorch(new BIDFlattened(Ids::REDSTONE_TORCH, [Ids::UNLIT_REDSTONE_TORCH], 0), "Redstone Torch", BlockBreakInfo::instant())); + $this->registerAllMeta(new RedstoneWire(new BID(Ids::REDSTONE_WIRE, 0, ItemIds::REDSTONE), "Redstone", BlockBreakInfo::instant())); + $this->registerAllMeta(new Reserved6(new BID(Ids::RESERVED6, 0), "reserved6", BlockBreakInfo::instant())); $sandBreakInfo = new BlockBreakInfo(0.5, BlockToolType::SHOVEL); $this->register(new Sand(new BID(Ids::SAND, 0), "Sand", $sandBreakInfo)); $this->register(new Sand(new BID(Ids::SAND, 1), "Red Sand", $sandBreakInfo)); - $this->register(new SeaLantern(new BID(Ids::SEALANTERN, 0), "Sea Lantern", new BlockBreakInfo(0.3))); - $this->register(new SeaPickle(new BID(Ids::SEA_PICKLE, 0), "Sea Pickle", BlockBreakInfo::instant())); - $this->register(new Skull(new BID(Ids::MOB_HEAD_BLOCK, 0, ItemIds::SKULL, TileSkull::class), "Mob Head", new BlockBreakInfo(1.0))); - $this->register(new Slime(new BID(Ids::SLIME, 0), "Slime Block", BlockBreakInfo::instant())); - $this->register(new Snow(new BID(Ids::SNOW, 0), "Snow Block", new BlockBreakInfo(0.2, BlockToolType::SHOVEL, ToolTier::WOOD()->getHarvestLevel()))); - $this->register(new SnowLayer(new BID(Ids::SNOW_LAYER, 0), "Snow Layer", new BlockBreakInfo(0.1, BlockToolType::SHOVEL, ToolTier::WOOD()->getHarvestLevel()))); - $this->register(new SoulSand(new BID(Ids::SOUL_SAND, 0), "Soul Sand", new BlockBreakInfo(0.5, BlockToolType::SHOVEL))); - $this->register(new Sponge(new BID(Ids::SPONGE, 0), "Sponge", new BlockBreakInfo(0.6, BlockToolType::HOE))); + $this->registerAllMeta(new SeaLantern(new BID(Ids::SEALANTERN, 0), "Sea Lantern", new BlockBreakInfo(0.3))); + $this->registerAllMeta(new SeaPickle(new BID(Ids::SEA_PICKLE, 0), "Sea Pickle", BlockBreakInfo::instant())); + $this->registerAllMeta(new Skull(new BID(Ids::MOB_HEAD_BLOCK, 0, ItemIds::SKULL, TileSkull::class), "Mob Head", new BlockBreakInfo(1.0))); + $this->registerAllMeta(new Slime(new BID(Ids::SLIME, 0), "Slime Block", BlockBreakInfo::instant())); + $this->registerAllMeta(new Snow(new BID(Ids::SNOW, 0), "Snow Block", new BlockBreakInfo(0.2, BlockToolType::SHOVEL, ToolTier::WOOD()->getHarvestLevel()))); + $this->registerAllMeta(new SnowLayer(new BID(Ids::SNOW_LAYER, 0), "Snow Layer", new BlockBreakInfo(0.1, BlockToolType::SHOVEL, ToolTier::WOOD()->getHarvestLevel()))); + $this->registerAllMeta(new SoulSand(new BID(Ids::SOUL_SAND, 0), "Soul Sand", new BlockBreakInfo(0.5, BlockToolType::SHOVEL))); + $this->registerAllMeta(new Sponge(new BID(Ids::SPONGE, 0), "Sponge", new BlockBreakInfo(0.6, BlockToolType::HOE))); $shulkerBoxBreakInfo = new BlockBreakInfo(2, BlockToolType::PICKAXE); - $this->register(new ShulkerBox(new BID(Ids::UNDYED_SHULKER_BOX, 0, null, TileShulkerBox::class), "Shulker Box", $shulkerBoxBreakInfo)); + $this->registerAllMeta(new ShulkerBox(new BID(Ids::UNDYED_SHULKER_BOX, 0, null, TileShulkerBox::class), "Shulker Box", $shulkerBoxBreakInfo)); $stoneBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); $this->register($stone = new class(new BID(Ids::STONE, Meta::STONE_NORMAL), "Stone", $stoneBreakInfo) extends Opaque{ @@ -343,32 +335,32 @@ class BlockFactory{ } }); $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE), "Infested Stone", $infestedStoneBreakInfo, $stone)); - $this->register(new Stair(new BID(Ids::NORMAL_STONE_STAIRS, 0), "Stone Stairs", $stoneBreakInfo)); - $this->register(new Opaque(new BID(Ids::SMOOTH_STONE, 0), "Smooth Stone", $stoneBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::NORMAL_STONE_STAIRS, 0), "Stone Stairs", $stoneBreakInfo)); + $this->registerAllMeta(new Opaque(new BID(Ids::SMOOTH_STONE, 0), "Smooth Stone", $stoneBreakInfo)); $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_ANDESITE), "Andesite", $stoneBreakInfo)); - $this->register(new Stair(new BID(Ids::ANDESITE_STAIRS, 0), "Andesite Stairs", $stoneBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::ANDESITE_STAIRS, 0), "Andesite Stairs", $stoneBreakInfo)); $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_DIORITE), "Diorite", $stoneBreakInfo)); - $this->register(new Stair(new BID(Ids::DIORITE_STAIRS, 0), "Diorite Stairs", $stoneBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::DIORITE_STAIRS, 0), "Diorite Stairs", $stoneBreakInfo)); $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_GRANITE), "Granite", $stoneBreakInfo)); - $this->register(new Stair(new BID(Ids::GRANITE_STAIRS, 0), "Granite Stairs", $stoneBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::GRANITE_STAIRS, 0), "Granite Stairs", $stoneBreakInfo)); $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_ANDESITE), "Polished Andesite", $stoneBreakInfo)); - $this->register(new Stair(new BID(Ids::POLISHED_ANDESITE_STAIRS, 0), "Polished Andesite Stairs", $stoneBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::POLISHED_ANDESITE_STAIRS, 0), "Polished Andesite Stairs", $stoneBreakInfo)); $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_DIORITE), "Polished Diorite", $stoneBreakInfo)); - $this->register(new Stair(new BID(Ids::POLISHED_DIORITE_STAIRS, 0), "Polished Diorite Stairs", $stoneBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::POLISHED_DIORITE_STAIRS, 0), "Polished Diorite Stairs", $stoneBreakInfo)); $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_GRANITE), "Polished Granite", $stoneBreakInfo)); - $this->register(new Stair(new BID(Ids::POLISHED_GRANITE_STAIRS, 0), "Polished Granite Stairs", $stoneBreakInfo)); - $this->register(new Stair(new BID(Ids::STONE_BRICK_STAIRS, 0), "Stone Brick Stairs", $stoneBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::POLISHED_GRANITE_STAIRS, 0), "Polished Granite Stairs", $stoneBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::STONE_BRICK_STAIRS, 0), "Stone Brick Stairs", $stoneBreakInfo)); $this->register($chiseledStoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CHISELED), "Chiseled Stone Bricks", $stoneBreakInfo)); $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CHISELED), "Infested Chiseled Stone Brick", $infestedStoneBreakInfo, $chiseledStoneBrick)); $this->register($crackedStoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CRACKED), "Cracked Stone Bricks", $stoneBreakInfo)); $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CRACKED), "Infested Cracked Stone Brick", $infestedStoneBreakInfo, $crackedStoneBrick)); $this->register($mossyStoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_MOSSY), "Mossy Stone Bricks", $stoneBreakInfo)); $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_MOSSY), "Infested Mossy Stone Brick", $infestedStoneBreakInfo, $mossyStoneBrick)); - $this->register(new Stair(new BID(Ids::MOSSY_STONE_BRICK_STAIRS, 0), "Mossy Stone Brick Stairs", $stoneBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::MOSSY_STONE_BRICK_STAIRS, 0), "Mossy Stone Brick Stairs", $stoneBreakInfo)); $this->register($stoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_NORMAL), "Stone Bricks", $stoneBreakInfo)); $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK), "Infested Stone Brick", $infestedStoneBreakInfo, $stoneBrick)); - $this->register(new StoneButton(new BID(Ids::STONE_BUTTON, 0), "Stone Button", new BlockBreakInfo(0.5, BlockToolType::PICKAXE))); - $this->register(new StonePressurePlate(new BID(Ids::STONE_PRESSURE_PLATE, 0), "Stone Pressure Plate", new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->registerAllMeta(new StoneButton(new BID(Ids::STONE_BUTTON, 0), "Stone Button", new BlockBreakInfo(0.5, BlockToolType::PICKAXE))); + $this->registerAllMeta(new StonePressurePlate(new BID(Ids::STONE_PRESSURE_PLATE, 0), "Stone Pressure Plate", new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); //TODO: in the future this won't be the same for all the types $stoneSlabBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); @@ -401,10 +393,10 @@ class BlockFactory{ $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_MOSSY_STONE_BRICK), "Mossy Stone Brick", $stoneSlabBreakInfo)); $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_SMOOTH_QUARTZ), "Smooth Quartz", $stoneSlabBreakInfo)); $this->registerSlabWithDoubleHighBitsRemapping(new Slab(BlockLegacyIdHelper::getStoneSlabIdentifier(4, Meta::STONE_SLAB4_STONE), "Stone", $stoneSlabBreakInfo)); - $this->register(new Opaque(new BID(Ids::STONECUTTER, 0), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - $this->register(new Sugarcane(new BID(Ids::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane", BlockBreakInfo::instant())); - $this->register(new SweetBerryBush(new BID(Ids::SWEET_BERRY_BUSH, 0, ItemIds::SWEET_BERRIES), "Sweet Berry Bush", BlockBreakInfo::instant())); - $this->register(new TNT(new BID(Ids::TNT, 0), "TNT", BlockBreakInfo::instant())); + $this->registerAllMeta(new Opaque(new BID(Ids::STONECUTTER, 0), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->registerAllMeta(new Sugarcane(new BID(Ids::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane", BlockBreakInfo::instant())); + $this->registerAllMeta(new SweetBerryBush(new BID(Ids::SWEET_BERRY_BUSH, 0, ItemIds::SWEET_BERRIES), "Sweet Berry Bush", BlockBreakInfo::instant())); + $this->registerAllMeta(new TNT(new BID(Ids::TNT, 0), "TNT", BlockBreakInfo::instant())); $fern = new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_FERN), "Fern", BlockBreakInfo::instant(BlockToolType::SHEARS, 1)); $this->register($fern); @@ -415,19 +407,19 @@ class BlockFactory{ $this->register(new Torch(new BID(Ids::COLORED_TORCH_BP, 8), "Purple Torch", BlockBreakInfo::instant())); $this->register(new Torch(new BID(Ids::COLORED_TORCH_RG, 0), "Red Torch", BlockBreakInfo::instant())); $this->register(new Torch(new BID(Ids::COLORED_TORCH_RG, 8), "Green Torch", BlockBreakInfo::instant())); - $this->register(new Torch(new BID(Ids::TORCH, 0), "Torch", BlockBreakInfo::instant())); - $this->register(new TrappedChest(new BID(Ids::TRAPPED_CHEST, 0, null, TileChest::class), "Trapped Chest", $chestBreakInfo)); - $this->register(new Tripwire(new BID(Ids::TRIPWIRE, 0, ItemIds::STRING), "Tripwire", BlockBreakInfo::instant())); - $this->register(new TripwireHook(new BID(Ids::TRIPWIRE_HOOK, 0), "Tripwire Hook", BlockBreakInfo::instant())); - $this->register(new UnderwaterTorch(new BID(Ids::UNDERWATER_TORCH, 0), "Underwater Torch", BlockBreakInfo::instant())); - $this->register(new Vine(new BID(Ids::VINE, 0), "Vines", new BlockBreakInfo(0.2, BlockToolType::AXE))); - $this->register(new Water(new BIDFlattened(Ids::FLOWING_WATER, [Ids::STILL_WATER], 0), "Water", BlockBreakInfo::indestructible(500.0))); - $this->register(new WaterLily(new BID(Ids::LILY_PAD, 0), "Lily Pad", new BlockBreakInfo(0.6))); + $this->registerAllMeta(new Torch(new BID(Ids::TORCH, 0), "Torch", BlockBreakInfo::instant())); + $this->registerAllMeta(new TrappedChest(new BID(Ids::TRAPPED_CHEST, 0, null, TileChest::class), "Trapped Chest", $chestBreakInfo)); + $this->registerAllMeta(new Tripwire(new BID(Ids::TRIPWIRE, 0, ItemIds::STRING), "Tripwire", BlockBreakInfo::instant())); + $this->registerAllMeta(new TripwireHook(new BID(Ids::TRIPWIRE_HOOK, 0), "Tripwire Hook", BlockBreakInfo::instant())); + $this->registerAllMeta(new UnderwaterTorch(new BID(Ids::UNDERWATER_TORCH, 0), "Underwater Torch", BlockBreakInfo::instant())); + $this->registerAllMeta(new Vine(new BID(Ids::VINE, 0), "Vines", new BlockBreakInfo(0.2, BlockToolType::AXE))); + $this->registerAllMeta(new Water(new BIDFlattened(Ids::FLOWING_WATER, [Ids::STILL_WATER], 0), "Water", BlockBreakInfo::indestructible(500.0))); + $this->registerAllMeta(new WaterLily(new BID(Ids::LILY_PAD, 0), "Lily Pad", new BlockBreakInfo(0.6))); $weightedPressurePlateBreakInfo = new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()); - $this->register(new WeightedPressurePlateHeavy(new BID(Ids::HEAVY_WEIGHTED_PRESSURE_PLATE, 0), "Weighted Pressure Plate Heavy", $weightedPressurePlateBreakInfo)); - $this->register(new WeightedPressurePlateLight(new BID(Ids::LIGHT_WEIGHTED_PRESSURE_PLATE, 0), "Weighted Pressure Plate Light", $weightedPressurePlateBreakInfo)); - $this->register(new Wheat(new BID(Ids::WHEAT_BLOCK, 0), "Wheat Block", BlockBreakInfo::instant())); + $this->registerAllMeta(new WeightedPressurePlateHeavy(new BID(Ids::HEAVY_WEIGHTED_PRESSURE_PLATE, 0), "Weighted Pressure Plate Heavy", $weightedPressurePlateBreakInfo)); + $this->registerAllMeta(new WeightedPressurePlateLight(new BID(Ids::LIGHT_WEIGHTED_PRESSURE_PLATE, 0), "Weighted Pressure Plate Light", $weightedPressurePlateBreakInfo)); + $this->registerAllMeta(new Wheat(new BID(Ids::WHEAT_BLOCK, 0), "Wheat Block", BlockBreakInfo::instant())); $planksBreakInfo = new BlockBreakInfo(2.0, BlockToolType::AXE, 0, 15.0); $leavesBreakInfo = new BlockBreakInfo(0.2, BlockToolType::SHEARS); @@ -453,17 +445,17 @@ class BlockFactory{ $this->remap($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, ($magicNumber & 0x03) | 0b1100, $wood); $this->register(new Wood(new BID(Ids::WOOD, $magicNumber | BlockLegacyMetadata::WOOD_FLAG_STRIPPED), "Stripped $name Wood", $logBreakInfo, $treeType, true)); - $this->register(new Log(BlockLegacyIdHelper::getStrippedLogIdentifier($treeType), "Stripped " . $name . " Log", $logBreakInfo, $treeType, true)); - $this->register(new FenceGate(BlockLegacyIdHelper::getWoodenFenceIdentifier($treeType), $name . " Fence Gate", $planksBreakInfo)); - $this->register(new WoodenStairs(BlockLegacyIdHelper::getWoodenStairsIdentifier($treeType), $name . " Stairs", $planksBreakInfo)); - $this->register(new WoodenDoor(BlockLegacyIdHelper::getWoodenDoorIdentifier($treeType), $name . " Door", $woodenDoorBreakInfo)); + $this->registerAllMeta(new Log(BlockLegacyIdHelper::getStrippedLogIdentifier($treeType), "Stripped " . $name . " Log", $logBreakInfo, $treeType, true)); + $this->registerAllMeta(new FenceGate(BlockLegacyIdHelper::getWoodenFenceIdentifier($treeType), $name . " Fence Gate", $planksBreakInfo)); + $this->registerAllMeta(new WoodenStairs(BlockLegacyIdHelper::getWoodenStairsIdentifier($treeType), $name . " Stairs", $planksBreakInfo)); + $this->registerAllMeta(new WoodenDoor(BlockLegacyIdHelper::getWoodenDoorIdentifier($treeType), $name . " Door", $woodenDoorBreakInfo)); - $this->register(new WoodenButton(BlockLegacyIdHelper::getWoodenButtonIdentifier($treeType), $name . " Button", $woodenButtonBreakInfo)); - $this->register(new WoodenPressurePlate(BlockLegacyIdHelper::getWoodenPressurePlateIdentifier($treeType), $name . " Pressure Plate", $woodenPressurePlateBreakInfo)); - $this->register(new WoodenTrapdoor(BlockLegacyIdHelper::getWoodenTrapdoorIdentifier($treeType), $name . " Trapdoor", $woodenDoorBreakInfo)); + $this->registerAllMeta(new WoodenButton(BlockLegacyIdHelper::getWoodenButtonIdentifier($treeType), $name . " Button", $woodenButtonBreakInfo)); + $this->registerAllMeta(new WoodenPressurePlate(BlockLegacyIdHelper::getWoodenPressurePlateIdentifier($treeType), $name . " Pressure Plate", $woodenPressurePlateBreakInfo)); + $this->registerAllMeta(new WoodenTrapdoor(BlockLegacyIdHelper::getWoodenTrapdoorIdentifier($treeType), $name . " Trapdoor", $woodenDoorBreakInfo)); - $this->register(new FloorSign(BlockLegacyIdHelper::getWoodenFloorSignIdentifier($treeType), $name . " Sign", $signBreakInfo)); - $this->register(new WallSign(BlockLegacyIdHelper::getWoodenWallSignIdentifier($treeType), $name . " Wall Sign", $signBreakInfo)); + $this->registerAllMeta(new FloorSign(BlockLegacyIdHelper::getWoodenFloorSignIdentifier($treeType), $name . " Sign", $signBreakInfo)); + $this->registerAllMeta(new WallSign(BlockLegacyIdHelper::getWoodenWallSignIdentifier($treeType), $name . " Wall Sign", $signBreakInfo)); } static $sandstoneTypes = [ @@ -473,10 +465,10 @@ class BlockFactory{ Meta::SANDSTONE_SMOOTH => "Smooth " ]; $sandstoneBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()); - $this->register(new Stair(new BID(Ids::RED_SANDSTONE_STAIRS, 0), "Red Sandstone Stairs", $sandstoneBreakInfo)); - $this->register(new Stair(new BID(Ids::SMOOTH_RED_SANDSTONE_STAIRS, 0), "Smooth Red Sandstone Stairs", $sandstoneBreakInfo)); - $this->register(new Stair(new BID(Ids::SANDSTONE_STAIRS, 0), "Sandstone Stairs", $sandstoneBreakInfo)); - $this->register(new Stair(new BID(Ids::SMOOTH_SANDSTONE_STAIRS, 0), "Smooth Sandstone Stairs", $sandstoneBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::RED_SANDSTONE_STAIRS, 0), "Red Sandstone Stairs", $sandstoneBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::SMOOTH_RED_SANDSTONE_STAIRS, 0), "Smooth Red Sandstone Stairs", $sandstoneBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::SANDSTONE_STAIRS, 0), "Sandstone Stairs", $sandstoneBreakInfo)); + $this->registerAllMeta(new Stair(new BID(Ids::SMOOTH_SANDSTONE_STAIRS, 0), "Smooth Sandstone Stairs", $sandstoneBreakInfo)); foreach($sandstoneTypes as $variant => $prefix){ $this->register(new Opaque(new BID(Ids::SANDSTONE, $variant), $prefix . "Sandstone", $sandstoneBreakInfo)); $this->register(new Opaque(new BID(Ids::RED_SANDSTONE, $variant), $prefix . "Red Sandstone", $sandstoneBreakInfo)); @@ -487,18 +479,18 @@ class BlockFactory{ $coloredName = function(string $name) use($color) : string{ return $color->getDisplayName() . " " . $name; }; - $this->register(new GlazedTerracotta(BlockLegacyIdHelper::getGlazedTerracottaIdentifier($color), $coloredName("Glazed Terracotta"), $glazedTerracottaBreakInfo)); + $this->registerAllMeta(new GlazedTerracotta(BlockLegacyIdHelper::getGlazedTerracottaIdentifier($color), $coloredName("Glazed Terracotta"), $glazedTerracottaBreakInfo)); } - $this->register(new DyedShulkerBox(new BID(Ids::SHULKER_BOX, 0, null, TileShulkerBox::class), "Dyed Shulker Box", $shulkerBoxBreakInfo)); - $this->register(new StainedGlass(new BID(Ids::STAINED_GLASS, 0), "Stained Glass", $glassBreakInfo)); - $this->register(new StainedGlassPane(new BID(Ids::STAINED_GLASS_PANE, 0), "Stained Glass Pane", $glassBreakInfo)); - $this->register(new StainedHardenedClay(new BID(Ids::STAINED_CLAY, 0), "Stained Clay", $hardenedClayBreakInfo)); - $this->register(new StainedHardenedGlass(new BID(Ids::HARD_STAINED_GLASS, 0), "Stained Hardened Glass", $hardenedGlassBreakInfo)); - $this->register(new StainedHardenedGlassPane(new BID(Ids::HARD_STAINED_GLASS_PANE, 0), "Stained Hardened Glass Pane", $hardenedGlassBreakInfo)); - $this->register(new Carpet(new BID(Ids::CARPET, 0), "Carpet", new BlockBreakInfo(0.1))); - $this->register(new Concrete(new BID(Ids::CONCRETE, 0), "Concrete", new BlockBreakInfo(1.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); - $this->register(new ConcretePowder(new BID(Ids::CONCRETE_POWDER, 0), "Concrete Powder", new BlockBreakInfo(0.5, BlockToolType::SHOVEL))); - $this->register(new Wool(new BID(Ids::WOOL, 0), "Wool", new class(0.8, BlockToolType::SHEARS) extends BlockBreakInfo{ + $this->registerAllMeta(new DyedShulkerBox(new BID(Ids::SHULKER_BOX, 0, null, TileShulkerBox::class), "Dyed Shulker Box", $shulkerBoxBreakInfo)); + $this->registerAllMeta(new StainedGlass(new BID(Ids::STAINED_GLASS, 0), "Stained Glass", $glassBreakInfo)); + $this->registerAllMeta(new StainedGlassPane(new BID(Ids::STAINED_GLASS_PANE, 0), "Stained Glass Pane", $glassBreakInfo)); + $this->registerAllMeta(new StainedHardenedClay(new BID(Ids::STAINED_CLAY, 0), "Stained Clay", $hardenedClayBreakInfo)); + $this->registerAllMeta(new StainedHardenedGlass(new BID(Ids::HARD_STAINED_GLASS, 0), "Stained Hardened Glass", $hardenedGlassBreakInfo)); + $this->registerAllMeta(new StainedHardenedGlassPane(new BID(Ids::HARD_STAINED_GLASS_PANE, 0), "Stained Hardened Glass Pane", $hardenedGlassBreakInfo)); + $this->registerAllMeta(new Carpet(new BID(Ids::CARPET, 0), "Carpet", new BlockBreakInfo(0.1))); + $this->registerAllMeta(new Concrete(new BID(Ids::CONCRETE, 0), "Concrete", new BlockBreakInfo(1.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); + $this->registerAllMeta(new ConcretePowder(new BID(Ids::CONCRETE_POWDER, 0), "Concrete Powder", new BlockBreakInfo(0.5, BlockToolType::SHOVEL))); + $this->registerAllMeta(new Wool(new BID(Ids::WOOL, 0), "Wool", new class(0.8, BlockToolType::SHEARS) extends BlockBreakInfo{ public function getBreakTime(Item $item) : float{ $time = parent::getBreakTime($item); if($item->getBlockToolType() === BlockToolType::SHEARS){ @@ -534,21 +526,21 @@ class BlockFactory{ $this->register(new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_LAB_TABLE), "Lab Table", $chemistryTableBreakInfo)); $this->register(new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_MATERIAL_REDUCER), "Material Reducer", $chemistryTableBreakInfo)); - $this->register(new ChemicalHeat(new BID(Ids::CHEMICAL_HEAT, 0), "Heat Block", $chemistryTableBreakInfo)); + $this->registerAllMeta(new ChemicalHeat(new BID(Ids::CHEMICAL_HEAT, 0), "Heat Block", $chemistryTableBreakInfo)); $this->registerMushroomBlocks(); - $this->register(new Coral( + $this->registerAllMeta(new Coral( new BID(Ids::CORAL, 0), "Coral", BlockBreakInfo::instant(), )); - $this->register(new FloorCoralFan( + $this->registerAllMeta(new FloorCoralFan( new BlockIdentifierFlattened(Ids::CORAL_FAN, [Ids::CORAL_FAN_DEAD], 0, ItemIds::CORAL_FAN), "Coral Fan", BlockBreakInfo::instant(), )); - $this->register(new WallCoralFan( + $this->registerAllMeta(new WallCoralFan( new BlockIdentifierFlattened(Ids::CORAL_FAN_HANG, [Ids::CORAL_FAN_HANG2, Ids::CORAL_FAN_HANG3], 0, ItemIds::CORAL_FAN), "Wall Coral Fan", BlockBreakInfo::instant(), @@ -740,126 +732,144 @@ class BlockFactory{ private function registerElements() : void{ $instaBreak = BlockBreakInfo::instant(); - $this->register(new Opaque(new BID(Ids::ELEMENT_0, 0), "???", $instaBreak)); + $this->registerAllMeta(new Opaque(new BID(Ids::ELEMENT_0, 0), "???", $instaBreak)); - $this->register(new Element(new BID(Ids::ELEMENT_1, 0), "Hydrogen", $instaBreak, "h", 1, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_2, 0), "Helium", $instaBreak, "he", 2, 7)); - $this->register(new Element(new BID(Ids::ELEMENT_3, 0), "Lithium", $instaBreak, "li", 3, 0)); - $this->register(new Element(new BID(Ids::ELEMENT_4, 0), "Beryllium", $instaBreak, "be", 4, 1)); - $this->register(new Element(new BID(Ids::ELEMENT_5, 0), "Boron", $instaBreak, "b", 5, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_6, 0), "Carbon", $instaBreak, "c", 6, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_7, 0), "Nitrogen", $instaBreak, "n", 7, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_8, 0), "Oxygen", $instaBreak, "o", 8, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_9, 0), "Fluorine", $instaBreak, "f", 9, 6)); - $this->register(new Element(new BID(Ids::ELEMENT_10, 0), "Neon", $instaBreak, "ne", 10, 7)); - $this->register(new Element(new BID(Ids::ELEMENT_11, 0), "Sodium", $instaBreak, "na", 11, 0)); - $this->register(new Element(new BID(Ids::ELEMENT_12, 0), "Magnesium", $instaBreak, "mg", 12, 1)); - $this->register(new Element(new BID(Ids::ELEMENT_13, 0), "Aluminum", $instaBreak, "al", 13, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_14, 0), "Silicon", $instaBreak, "si", 14, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_15, 0), "Phosphorus", $instaBreak, "p", 15, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_16, 0), "Sulfur", $instaBreak, "s", 16, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_17, 0), "Chlorine", $instaBreak, "cl", 17, 6)); - $this->register(new Element(new BID(Ids::ELEMENT_18, 0), "Argon", $instaBreak, "ar", 18, 7)); - $this->register(new Element(new BID(Ids::ELEMENT_19, 0), "Potassium", $instaBreak, "k", 19, 0)); - $this->register(new Element(new BID(Ids::ELEMENT_20, 0), "Calcium", $instaBreak, "ca", 20, 1)); - $this->register(new Element(new BID(Ids::ELEMENT_21, 0), "Scandium", $instaBreak, "sc", 21, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_22, 0), "Titanium", $instaBreak, "ti", 22, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_23, 0), "Vanadium", $instaBreak, "v", 23, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_24, 0), "Chromium", $instaBreak, "cr", 24, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_25, 0), "Manganese", $instaBreak, "mn", 25, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_26, 0), "Iron", $instaBreak, "fe", 26, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_27, 0), "Cobalt", $instaBreak, "co", 27, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_28, 0), "Nickel", $instaBreak, "ni", 28, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_29, 0), "Copper", $instaBreak, "cu", 29, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_30, 0), "Zinc", $instaBreak, "zn", 30, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_31, 0), "Gallium", $instaBreak, "ga", 31, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_32, 0), "Germanium", $instaBreak, "ge", 32, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_33, 0), "Arsenic", $instaBreak, "as", 33, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_34, 0), "Selenium", $instaBreak, "se", 34, 5)); - $this->register(new Element(new BID(Ids::ELEMENT_35, 0), "Bromine", $instaBreak, "br", 35, 6)); - $this->register(new Element(new BID(Ids::ELEMENT_36, 0), "Krypton", $instaBreak, "kr", 36, 7)); - $this->register(new Element(new BID(Ids::ELEMENT_37, 0), "Rubidium", $instaBreak, "rb", 37, 0)); - $this->register(new Element(new BID(Ids::ELEMENT_38, 0), "Strontium", $instaBreak, "sr", 38, 1)); - $this->register(new Element(new BID(Ids::ELEMENT_39, 0), "Yttrium", $instaBreak, "y", 39, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_40, 0), "Zirconium", $instaBreak, "zr", 40, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_41, 0), "Niobium", $instaBreak, "nb", 41, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_42, 0), "Molybdenum", $instaBreak, "mo", 42, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_43, 0), "Technetium", $instaBreak, "tc", 43, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_44, 0), "Ruthenium", $instaBreak, "ru", 44, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_45, 0), "Rhodium", $instaBreak, "rh", 45, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_46, 0), "Palladium", $instaBreak, "pd", 46, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_47, 0), "Silver", $instaBreak, "ag", 47, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_48, 0), "Cadmium", $instaBreak, "cd", 48, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_49, 0), "Indium", $instaBreak, "in", 49, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_50, 0), "Tin", $instaBreak, "sn", 50, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_51, 0), "Antimony", $instaBreak, "sb", 51, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_52, 0), "Tellurium", $instaBreak, "te", 52, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_53, 0), "Iodine", $instaBreak, "i", 53, 6)); - $this->register(new Element(new BID(Ids::ELEMENT_54, 0), "Xenon", $instaBreak, "xe", 54, 7)); - $this->register(new Element(new BID(Ids::ELEMENT_55, 0), "Cesium", $instaBreak, "cs", 55, 0)); - $this->register(new Element(new BID(Ids::ELEMENT_56, 0), "Barium", $instaBreak, "ba", 56, 1)); - $this->register(new Element(new BID(Ids::ELEMENT_57, 0), "Lanthanum", $instaBreak, "la", 57, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_58, 0), "Cerium", $instaBreak, "ce", 58, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_59, 0), "Praseodymium", $instaBreak, "pr", 59, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_60, 0), "Neodymium", $instaBreak, "nd", 60, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_61, 0), "Promethium", $instaBreak, "pm", 61, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_62, 0), "Samarium", $instaBreak, "sm", 62, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_63, 0), "Europium", $instaBreak, "eu", 63, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_64, 0), "Gadolinium", $instaBreak, "gd", 64, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_65, 0), "Terbium", $instaBreak, "tb", 65, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_66, 0), "Dysprosium", $instaBreak, "dy", 66, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_67, 0), "Holmium", $instaBreak, "ho", 67, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_68, 0), "Erbium", $instaBreak, "er", 68, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_69, 0), "Thulium", $instaBreak, "tm", 69, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_70, 0), "Ytterbium", $instaBreak, "yb", 70, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_71, 0), "Lutetium", $instaBreak, "lu", 71, 8)); - $this->register(new Element(new BID(Ids::ELEMENT_72, 0), "Hafnium", $instaBreak, "hf", 72, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_73, 0), "Tantalum", $instaBreak, "ta", 73, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_74, 0), "Tungsten", $instaBreak, "w", 74, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_75, 0), "Rhenium", $instaBreak, "re", 75, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_76, 0), "Osmium", $instaBreak, "os", 76, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_77, 0), "Iridium", $instaBreak, "ir", 77, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_78, 0), "Platinum", $instaBreak, "pt", 78, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_79, 0), "Gold", $instaBreak, "au", 79, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_80, 0), "Mercury", $instaBreak, "hg", 80, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_81, 0), "Thallium", $instaBreak, "tl", 81, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_82, 0), "Lead", $instaBreak, "pb", 82, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_83, 0), "Bismuth", $instaBreak, "bi", 83, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_84, 0), "Polonium", $instaBreak, "po", 84, 4)); - $this->register(new Element(new BID(Ids::ELEMENT_85, 0), "Astatine", $instaBreak, "at", 85, 6)); - $this->register(new Element(new BID(Ids::ELEMENT_86, 0), "Radon", $instaBreak, "rn", 86, 7)); - $this->register(new Element(new BID(Ids::ELEMENT_87, 0), "Francium", $instaBreak, "fr", 87, 0)); - $this->register(new Element(new BID(Ids::ELEMENT_88, 0), "Radium", $instaBreak, "ra", 88, 1)); - $this->register(new Element(new BID(Ids::ELEMENT_89, 0), "Actinium", $instaBreak, "ac", 89, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_90, 0), "Thorium", $instaBreak, "th", 90, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_91, 0), "Protactinium", $instaBreak, "pa", 91, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_92, 0), "Uranium", $instaBreak, "u", 92, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_93, 0), "Neptunium", $instaBreak, "np", 93, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_94, 0), "Plutonium", $instaBreak, "pu", 94, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_95, 0), "Americium", $instaBreak, "am", 95, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_96, 0), "Curium", $instaBreak, "cm", 96, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_97, 0), "Berkelium", $instaBreak, "bk", 97, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_98, 0), "Californium", $instaBreak, "cf", 98, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_99, 0), "Einsteinium", $instaBreak, "es", 99, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_100, 0), "Fermium", $instaBreak, "fm", 100, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_101, 0), "Mendelevium", $instaBreak, "md", 101, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_102, 0), "Nobelium", $instaBreak, "no", 102, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_103, 0), "Lawrencium", $instaBreak, "lr", 103, 9)); - $this->register(new Element(new BID(Ids::ELEMENT_104, 0), "Rutherfordium", $instaBreak, "rf", 104, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_105, 0), "Dubnium", $instaBreak, "db", 105, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_106, 0), "Seaborgium", $instaBreak, "sg", 106, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_107, 0), "Bohrium", $instaBreak, "bh", 107, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_108, 0), "Hassium", $instaBreak, "hs", 108, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_109, 0), "Meitnerium", $instaBreak, "mt", 109, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_110, 0), "Darmstadtium", $instaBreak, "ds", 110, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_111, 0), "Roentgenium", $instaBreak, "rg", 111, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_112, 0), "Copernicium", $instaBreak, "cn", 112, 2)); - $this->register(new Element(new BID(Ids::ELEMENT_113, 0), "Nihonium", $instaBreak, "nh", 113, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_114, 0), "Flerovium", $instaBreak, "fl", 114, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_115, 0), "Moscovium", $instaBreak, "mc", 115, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_116, 0), "Livermorium", $instaBreak, "lv", 116, 3)); - $this->register(new Element(new BID(Ids::ELEMENT_117, 0), "Tennessine", $instaBreak, "ts", 117, 6)); - $this->register(new Element(new BID(Ids::ELEMENT_118, 0), "Oganesson", $instaBreak, "og", 118, 7)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_1, 0), "Hydrogen", $instaBreak, "h", 1, 5)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_2, 0), "Helium", $instaBreak, "he", 2, 7)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_3, 0), "Lithium", $instaBreak, "li", 3, 0)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_4, 0), "Beryllium", $instaBreak, "be", 4, 1)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_5, 0), "Boron", $instaBreak, "b", 5, 4)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_6, 0), "Carbon", $instaBreak, "c", 6, 5)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_7, 0), "Nitrogen", $instaBreak, "n", 7, 5)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_8, 0), "Oxygen", $instaBreak, "o", 8, 5)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_9, 0), "Fluorine", $instaBreak, "f", 9, 6)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_10, 0), "Neon", $instaBreak, "ne", 10, 7)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_11, 0), "Sodium", $instaBreak, "na", 11, 0)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_12, 0), "Magnesium", $instaBreak, "mg", 12, 1)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_13, 0), "Aluminum", $instaBreak, "al", 13, 3)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_14, 0), "Silicon", $instaBreak, "si", 14, 4)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_15, 0), "Phosphorus", $instaBreak, "p", 15, 5)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_16, 0), "Sulfur", $instaBreak, "s", 16, 5)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_17, 0), "Chlorine", $instaBreak, "cl", 17, 6)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_18, 0), "Argon", $instaBreak, "ar", 18, 7)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_19, 0), "Potassium", $instaBreak, "k", 19, 0)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_20, 0), "Calcium", $instaBreak, "ca", 20, 1)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_21, 0), "Scandium", $instaBreak, "sc", 21, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_22, 0), "Titanium", $instaBreak, "ti", 22, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_23, 0), "Vanadium", $instaBreak, "v", 23, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_24, 0), "Chromium", $instaBreak, "cr", 24, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_25, 0), "Manganese", $instaBreak, "mn", 25, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_26, 0), "Iron", $instaBreak, "fe", 26, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_27, 0), "Cobalt", $instaBreak, "co", 27, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_28, 0), "Nickel", $instaBreak, "ni", 28, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_29, 0), "Copper", $instaBreak, "cu", 29, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_30, 0), "Zinc", $instaBreak, "zn", 30, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_31, 0), "Gallium", $instaBreak, "ga", 31, 3)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_32, 0), "Germanium", $instaBreak, "ge", 32, 4)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_33, 0), "Arsenic", $instaBreak, "as", 33, 4)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_34, 0), "Selenium", $instaBreak, "se", 34, 5)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_35, 0), "Bromine", $instaBreak, "br", 35, 6)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_36, 0), "Krypton", $instaBreak, "kr", 36, 7)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_37, 0), "Rubidium", $instaBreak, "rb", 37, 0)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_38, 0), "Strontium", $instaBreak, "sr", 38, 1)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_39, 0), "Yttrium", $instaBreak, "y", 39, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_40, 0), "Zirconium", $instaBreak, "zr", 40, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_41, 0), "Niobium", $instaBreak, "nb", 41, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_42, 0), "Molybdenum", $instaBreak, "mo", 42, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_43, 0), "Technetium", $instaBreak, "tc", 43, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_44, 0), "Ruthenium", $instaBreak, "ru", 44, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_45, 0), "Rhodium", $instaBreak, "rh", 45, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_46, 0), "Palladium", $instaBreak, "pd", 46, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_47, 0), "Silver", $instaBreak, "ag", 47, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_48, 0), "Cadmium", $instaBreak, "cd", 48, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_49, 0), "Indium", $instaBreak, "in", 49, 3)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_50, 0), "Tin", $instaBreak, "sn", 50, 3)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_51, 0), "Antimony", $instaBreak, "sb", 51, 4)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_52, 0), "Tellurium", $instaBreak, "te", 52, 4)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_53, 0), "Iodine", $instaBreak, "i", 53, 6)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_54, 0), "Xenon", $instaBreak, "xe", 54, 7)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_55, 0), "Cesium", $instaBreak, "cs", 55, 0)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_56, 0), "Barium", $instaBreak, "ba", 56, 1)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_57, 0), "Lanthanum", $instaBreak, "la", 57, 8)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_58, 0), "Cerium", $instaBreak, "ce", 58, 8)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_59, 0), "Praseodymium", $instaBreak, "pr", 59, 8)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_60, 0), "Neodymium", $instaBreak, "nd", 60, 8)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_61, 0), "Promethium", $instaBreak, "pm", 61, 8)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_62, 0), "Samarium", $instaBreak, "sm", 62, 8)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_63, 0), "Europium", $instaBreak, "eu", 63, 8)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_64, 0), "Gadolinium", $instaBreak, "gd", 64, 8)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_65, 0), "Terbium", $instaBreak, "tb", 65, 8)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_66, 0), "Dysprosium", $instaBreak, "dy", 66, 8)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_67, 0), "Holmium", $instaBreak, "ho", 67, 8)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_68, 0), "Erbium", $instaBreak, "er", 68, 8)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_69, 0), "Thulium", $instaBreak, "tm", 69, 8)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_70, 0), "Ytterbium", $instaBreak, "yb", 70, 8)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_71, 0), "Lutetium", $instaBreak, "lu", 71, 8)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_72, 0), "Hafnium", $instaBreak, "hf", 72, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_73, 0), "Tantalum", $instaBreak, "ta", 73, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_74, 0), "Tungsten", $instaBreak, "w", 74, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_75, 0), "Rhenium", $instaBreak, "re", 75, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_76, 0), "Osmium", $instaBreak, "os", 76, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_77, 0), "Iridium", $instaBreak, "ir", 77, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_78, 0), "Platinum", $instaBreak, "pt", 78, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_79, 0), "Gold", $instaBreak, "au", 79, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_80, 0), "Mercury", $instaBreak, "hg", 80, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_81, 0), "Thallium", $instaBreak, "tl", 81, 3)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_82, 0), "Lead", $instaBreak, "pb", 82, 3)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_83, 0), "Bismuth", $instaBreak, "bi", 83, 3)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_84, 0), "Polonium", $instaBreak, "po", 84, 4)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_85, 0), "Astatine", $instaBreak, "at", 85, 6)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_86, 0), "Radon", $instaBreak, "rn", 86, 7)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_87, 0), "Francium", $instaBreak, "fr", 87, 0)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_88, 0), "Radium", $instaBreak, "ra", 88, 1)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_89, 0), "Actinium", $instaBreak, "ac", 89, 9)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_90, 0), "Thorium", $instaBreak, "th", 90, 9)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_91, 0), "Protactinium", $instaBreak, "pa", 91, 9)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_92, 0), "Uranium", $instaBreak, "u", 92, 9)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_93, 0), "Neptunium", $instaBreak, "np", 93, 9)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_94, 0), "Plutonium", $instaBreak, "pu", 94, 9)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_95, 0), "Americium", $instaBreak, "am", 95, 9)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_96, 0), "Curium", $instaBreak, "cm", 96, 9)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_97, 0), "Berkelium", $instaBreak, "bk", 97, 9)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_98, 0), "Californium", $instaBreak, "cf", 98, 9)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_99, 0), "Einsteinium", $instaBreak, "es", 99, 9)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_100, 0), "Fermium", $instaBreak, "fm", 100, 9)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_101, 0), "Mendelevium", $instaBreak, "md", 101, 9)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_102, 0), "Nobelium", $instaBreak, "no", 102, 9)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_103, 0), "Lawrencium", $instaBreak, "lr", 103, 9)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_104, 0), "Rutherfordium", $instaBreak, "rf", 104, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_105, 0), "Dubnium", $instaBreak, "db", 105, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_106, 0), "Seaborgium", $instaBreak, "sg", 106, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_107, 0), "Bohrium", $instaBreak, "bh", 107, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_108, 0), "Hassium", $instaBreak, "hs", 108, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_109, 0), "Meitnerium", $instaBreak, "mt", 109, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_110, 0), "Darmstadtium", $instaBreak, "ds", 110, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_111, 0), "Roentgenium", $instaBreak, "rg", 111, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_112, 0), "Copernicium", $instaBreak, "cn", 112, 2)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_113, 0), "Nihonium", $instaBreak, "nh", 113, 3)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_114, 0), "Flerovium", $instaBreak, "fl", 114, 3)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_115, 0), "Moscovium", $instaBreak, "mc", 115, 3)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_116, 0), "Livermorium", $instaBreak, "lv", 116, 3)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_117, 0), "Tennessine", $instaBreak, "ts", 117, 6)); + $this->registerAllMeta(new Element(new BID(Ids::ELEMENT_118, 0), "Oganesson", $instaBreak, "og", 118, 7)); + } + + /** + * Claims the whole metadata range (0-15) for all IDs associated with this block. Any unregistered states will be + * mapped to the default (provided) state. + * + * This should only be used when this block type has sole ownership of an ID. For IDs which contain multiple block + * types (variants), the regular register() method should be used instead. + */ + private function registerAllMeta(Block $block) : void{ + $this->register($block); + foreach($block->getIdInfo()->getAllBlockIds() as $id){ + for($meta = 0; $meta < 1 << Block::INTERNAL_METADATA_BITS; ++$meta){ + if(!$this->isRegistered($id, $meta)){ + $this->remap($id, $meta, $block); + } + } + } } private function registerSlabWithDoubleHighBitsRemapping(Slab $block) : void{ diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index 6df3cf0980..c370eeaaeb 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"knownStates":{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","497":"Tall Grass","498":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1614":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2640":"Slime Block","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3280":"Shulker Box","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3488":"Dyed Shulker Box","3489":"Dyed Shulker Box","3490":"Dyed Shulker Box","3491":"Dyed Shulker Box","3492":"Dyed Shulker Box","3493":"Dyed Shulker Box","3494":"Dyed Shulker Box","3495":"Dyed Shulker Box","3496":"Dyed Shulker Box","3497":"Dyed Shulker Box","3498":"Dyed Shulker Box","3499":"Dyed Shulker Box","3500":"Dyed Shulker Box","3501":"Dyed Shulker Box","3502":"Dyed Shulker Box","3503":"Dyed Shulker Box","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6274":"Wall Coral Fan","6276":"Wall Coral Fan","6278":"Wall Coral Fan","6280":"Wall Coral Fan","6282":"Wall Coral Fan","6284":"Wall Coral Fan","6286":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7218":"Blast Furnace","7219":"Blast Furnace","7220":"Blast Furnace","7221":"Blast Furnace","7250":"Smoker","7251":"Smoker","7252":"Smoker","7253":"Smoker","7266":"Smoker","7267":"Smoker","7268":"Smoker","7269":"Smoker","7296":"Fletching Table","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7376":"Bell","7377":"Bell","7378":"Bell","7379":"Bell","7380":"Bell","7381":"Bell","7382":"Bell","7383":"Bell","7384":"Bell","7385":"Bell","7386":"Bell","7387":"Bell","7388":"Bell","7389":"Bell","7390":"Bell","7391":"Bell","7392":"Sweet Berry Bush","7393":"Sweet Berry Bush","7394":"Sweet Berry Bush","7395":"Sweet Berry Bush","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood","7480":"Stripped Oak Wood","7481":"Stripped Spruce Wood","7482":"Stripped Birch Wood","7483":"Stripped Jungle Wood","7484":"Stripped Acacia Wood","7485":"Stripped Dark Oak Wood","7506":"Blast Furnace","7507":"Blast Furnace","7508":"Blast Furnace","7509":"Blast Furnace"},"remaps":{"284":7472,"285":7473,"286":7474,"287":7475,"438":432,"439":432,"446":432,"447":432,"454":448,"455":448,"462":448,"463":448,"496":498,"499":498,"696":688,"697":689,"698":690,"699":691,"700":692,"701":693,"702":694,"703":695,"800":805,"806":805,"807":805,"864":866,"865":866,"870":866,"871":866,"976":978,"977":978,"982":978,"983":978,"992":978,"993":978,"998":978,"999":978,"1036":1027,"1037":1027,"1038":1027,"1039":1027,"1040":1042,"1041":1042,"1046":1042,"1047":1042,"1066":1056,"1067":1056,"1068":1056,"1069":1056,"1070":1056,"1071":1056,"1088":1090,"1089":1090,"1094":1090,"1095":1090,"1148":1139,"1149":1139,"1150":1139,"1151":1139,"1200":1221,"1206":1221,"1207":1221,"1216":1221,"1222":1221,"1223":1221,"1238":1232,"1239":1232,"1246":1232,"1247":1232,"1377":1376,"1378":1376,"1379":1376,"1440":1441,"1443":1441,"1479":1472,"1595":1598,"1596":1598,"1597":1598,"1610":1594,"1611":1614,"1612":1614,"1613":1614,"1615":1599,"2022":2016,"2023":2016,"2030":2016,"2031":2016,"2044":2032,"2045":2032,"2046":2032,"2047":2032,"2080":2082,"2081":2082,"2086":2082,"2087":2082,"2241":2240,"2242":2240,"2243":2240,"2244":2240,"2245":2240,"2246":2240,"2247":2240,"2248":2240,"2249":2240,"2250":2240,"2251":2240,"2252":2240,"2253":2240,"2254":2240,"2255":2240,"2294":2288,"2295":2288,"2302":2288,"2303":2288,"2304":2306,"2310":2306,"2311":2306,"2312":2306,"2313":2306,"2314":2306,"2315":2306,"2316":2306,"2317":2306,"2318":2306,"2319":2306,"2332":2322,"2333":2322,"2334":2322,"2335":2322,"2336":2338,"2337":2338,"2342":2338,"2343":2338,"2392":2386,"2393":2386,"2394":2386,"2395":2386,"2396":2386,"2397":2386,"2398":2386,"2399":2386,"2400":2386,"2401":2386,"2402":2386,"2403":2386,"2404":2386,"2405":2386,"2406":2386,"2407":2386,"2465":2464,"2470":2464,"2471":2464,"2473":2464,"2478":2464,"2479":2464,"2493":2481,"2494":2482,"2520":2512,"2521":2513,"2522":2514,"2523":2515,"2524":2516,"2525":2517,"2604":7476,"2605":7477,"2732":2720,"2832":2834,"2833":2834,"2838":2834,"2839":2834,"2904":2896,"2905":2897,"2906":2898,"2907":2899,"2908":2900,"2909":2901,"2910":2902,"2911":2903,"3100":3091,"3101":3091,"3102":3091,"3103":3091,"3116":3107,"3117":3107,"3118":3107,"3119":3107,"3132":3123,"3133":3123,"3134":3123,"3135":3123,"3148":3139,"3149":3139,"3150":3139,"3151":3139,"3164":3155,"3165":3155,"3166":3155,"3167":3155,"3230":3218,"3232":3237,"3238":3237,"3239":3237,"3240":3245,"3246":3245,"3247":3245,"3264":3269,"3270":3269,"3271":3269,"3272":3277,"3278":3277,"3279":3277,"3334":3328,"3335":3328,"3468":3456,"3504":3506,"3505":3506,"3510":3506,"3511":3506,"3520":3522,"3521":3522,"3526":3522,"3527":3522,"3536":3538,"3537":3538,"3542":3538,"3543":3538,"3552":3554,"3553":3554,"3558":3554,"3559":3554,"3568":3570,"3569":3570,"3574":3570,"3575":3570,"3584":3586,"3585":3586,"3590":3586,"3591":3586,"3600":3602,"3601":3602,"3606":3602,"3607":3602,"3616":3618,"3617":3618,"3622":3618,"3623":3618,"3632":3634,"3633":3634,"3638":3634,"3639":3634,"3648":3650,"3649":3650,"3654":3650,"3655":3650,"3664":3666,"3665":3666,"3670":3666,"3671":3666,"3696":3698,"3697":3698,"3702":3698,"3703":3698,"3712":3714,"3713":3714,"3718":3714,"3719":3714,"3728":3730,"3729":3730,"3734":3730,"3735":3730,"3744":3746,"3745":3746,"3750":3746,"3751":3746,"3760":3762,"3761":3762,"3766":3762,"3767":3762,"3824":3829,"3830":3829,"3831":3829,"3955":3952,"4163":4160,"4179":4176,"4195":4192,"4211":4208,"4227":4224,"4243":4240,"6181":6176,"6182":6176,"6183":6176,"6197":6192,"6198":6192,"6199":6192,"6205":6192,"6206":6192,"6207":6192,"6213":6208,"6214":6208,"6215":6208,"6221":6208,"6222":6208,"6223":6208,"6229":6208,"6230":6208,"6231":6208,"6237":6208,"6238":6208,"6239":6208,"6273":6248,"6275":6248,"6277":6248,"6279":6248,"6281":6248,"6283":6248,"6285":6248,"6287":6248,"6326":6320,"6327":6320,"6334":6320,"6335":6320,"6342":6336,"6343":6336,"6350":6336,"6351":6336,"6358":6352,"6359":6352,"6366":6352,"6367":6352,"6374":6368,"6375":6368,"6382":6368,"6383":6368,"6390":6384,"6391":6384,"6398":6384,"6399":6384,"6694":6688,"6695":6688,"6702":6688,"6703":6688,"6760":6752,"6761":6753,"6762":6754,"6763":6755,"6764":6756,"6765":6757,"6766":6758,"6767":6759,"6776":6768,"6777":6769,"6778":6770,"6779":6771,"6780":6772,"6992":6994,"6993":6994,"6998":6994,"6999":6994,"7072":7074,"7073":7074,"7078":7074,"7079":7074,"7104":7106,"7105":7106,"7110":7106,"7111":7106,"7136":7138,"7137":7138,"7142":7138,"7143":7138,"7168":7170,"7169":7170,"7174":7170,"7175":7170,"7216":7218,"7217":7218,"7222":7218,"7223":7218,"7248":7250,"7249":7250,"7254":7250,"7255":7250,"7264":7250,"7265":7250,"7270":7250,"7271":7250,"7334":7328,"7335":7328,"7342":7328,"7343":7328,"7396":7392,"7397":7392,"7398":7392,"7399":7392,"7504":7218,"7505":7218,"7510":7218,"7511":7218}} \ No newline at end of file +{"knownStates":{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","497":"Tall Grass","498":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1614":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2640":"Slime Block","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3280":"Shulker Box","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3488":"Dyed Shulker Box","3489":"Dyed Shulker Box","3490":"Dyed Shulker Box","3491":"Dyed Shulker Box","3492":"Dyed Shulker Box","3493":"Dyed Shulker Box","3494":"Dyed Shulker Box","3495":"Dyed Shulker Box","3496":"Dyed Shulker Box","3497":"Dyed Shulker Box","3498":"Dyed Shulker Box","3499":"Dyed Shulker Box","3500":"Dyed Shulker Box","3501":"Dyed Shulker Box","3502":"Dyed Shulker Box","3503":"Dyed Shulker Box","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6274":"Wall Coral Fan","6276":"Wall Coral Fan","6278":"Wall Coral Fan","6280":"Wall Coral Fan","6282":"Wall Coral Fan","6284":"Wall Coral Fan","6286":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7218":"Blast Furnace","7219":"Blast Furnace","7220":"Blast Furnace","7221":"Blast Furnace","7250":"Smoker","7251":"Smoker","7252":"Smoker","7253":"Smoker","7266":"Smoker","7267":"Smoker","7268":"Smoker","7269":"Smoker","7296":"Fletching Table","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7376":"Bell","7377":"Bell","7378":"Bell","7379":"Bell","7380":"Bell","7381":"Bell","7382":"Bell","7383":"Bell","7384":"Bell","7385":"Bell","7386":"Bell","7387":"Bell","7388":"Bell","7389":"Bell","7390":"Bell","7391":"Bell","7392":"Sweet Berry Bush","7393":"Sweet Berry Bush","7394":"Sweet Berry Bush","7395":"Sweet Berry Bush","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood","7480":"Stripped Oak Wood","7481":"Stripped Spruce Wood","7482":"Stripped Birch Wood","7483":"Stripped Jungle Wood","7484":"Stripped Acacia Wood","7485":"Stripped Dark Oak Wood","7506":"Blast Furnace","7507":"Blast Furnace","7508":"Blast Furnace","7509":"Blast Furnace"},"remaps":{"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"33":32,"34":32,"35":32,"36":32,"37":32,"38":32,"39":32,"40":32,"41":32,"42":32,"43":32,"44":32,"45":32,"46":32,"47":32,"50":48,"51":48,"52":48,"53":48,"54":48,"55":48,"56":48,"57":48,"58":48,"59":48,"60":48,"61":48,"62":48,"63":48,"65":64,"66":64,"67":64,"68":64,"69":64,"70":64,"71":64,"72":64,"73":64,"74":64,"75":64,"76":64,"77":64,"78":64,"79":64,"114":112,"115":112,"116":112,"117":112,"118":112,"119":112,"120":112,"121":112,"122":112,"123":112,"124":112,"125":112,"126":112,"127":112,"209":208,"210":208,"211":208,"212":208,"213":208,"214":208,"215":208,"216":208,"217":208,"218":208,"219":208,"220":208,"221":208,"222":208,"223":208,"225":224,"226":224,"227":224,"228":224,"229":224,"230":224,"231":224,"232":224,"233":224,"234":224,"235":224,"236":224,"237":224,"238":224,"239":224,"241":240,"242":240,"243":240,"244":240,"245":240,"246":240,"247":240,"248":240,"249":240,"250":240,"251":240,"252":240,"253":240,"254":240,"255":240,"257":256,"258":256,"259":256,"260":256,"261":256,"262":256,"263":256,"264":256,"265":256,"266":256,"267":256,"268":256,"269":256,"270":256,"271":256,"284":7472,"285":7473,"286":7474,"287":7475,"306":304,"307":304,"308":304,"309":304,"310":304,"311":304,"312":304,"313":304,"314":304,"315":304,"316":304,"317":304,"318":304,"319":304,"321":320,"322":320,"323":320,"324":320,"325":320,"326":320,"327":320,"328":320,"329":320,"330":320,"331":320,"332":320,"333":320,"334":320,"335":320,"337":336,"338":336,"339":336,"340":336,"341":336,"342":336,"343":336,"344":336,"345":336,"346":336,"347":336,"348":336,"349":336,"350":336,"351":336,"353":352,"354":352,"355":352,"356":352,"357":352,"358":352,"359":352,"360":352,"361":352,"362":352,"363":352,"364":352,"365":352,"366":352,"367":352,"401":400,"402":400,"403":400,"404":400,"405":400,"406":400,"407":400,"408":400,"409":400,"410":400,"411":400,"412":400,"413":400,"414":400,"415":400,"438":432,"439":432,"446":432,"447":432,"454":448,"455":448,"462":448,"463":448,"481":480,"482":480,"483":480,"484":480,"485":480,"486":480,"487":480,"488":480,"489":480,"490":480,"491":480,"492":480,"493":480,"494":480,"495":480,"496":498,"499":498,"513":512,"514":512,"515":512,"516":512,"517":512,"518":512,"519":512,"520":512,"521":512,"522":512,"523":512,"524":512,"525":512,"526":512,"527":512,"577":576,"578":576,"579":576,"580":576,"581":576,"582":576,"583":576,"584":576,"585":576,"586":576,"587":576,"588":576,"589":576,"590":576,"591":576,"593":592,"594":592,"595":592,"596":592,"597":592,"598":592,"599":592,"600":592,"601":592,"602":592,"603":592,"604":592,"605":592,"606":592,"607":592,"625":624,"626":624,"627":624,"628":624,"629":624,"630":624,"631":624,"632":624,"633":624,"634":624,"635":624,"636":624,"637":624,"638":624,"639":624,"641":640,"642":640,"643":640,"644":640,"645":640,"646":640,"647":640,"648":640,"649":640,"650":640,"651":640,"652":640,"653":640,"654":640,"655":640,"657":656,"658":656,"659":656,"660":656,"661":656,"662":656,"663":656,"664":656,"665":656,"666":656,"667":656,"668":656,"669":656,"670":656,"671":656,"673":672,"674":672,"675":672,"676":672,"677":672,"678":672,"679":672,"680":672,"681":672,"682":672,"683":672,"684":672,"685":672,"686":672,"687":672,"696":688,"697":689,"698":690,"699":691,"700":692,"701":693,"702":694,"703":695,"721":720,"722":720,"723":720,"724":720,"725":720,"726":720,"727":720,"728":720,"729":720,"730":720,"731":720,"732":720,"733":720,"734":720,"735":720,"740":736,"741":736,"742":736,"743":736,"744":736,"745":736,"746":736,"747":736,"748":736,"749":736,"750":736,"751":736,"753":752,"754":752,"755":752,"756":752,"757":752,"758":752,"759":752,"760":752,"761":752,"762":752,"763":752,"764":752,"765":752,"766":752,"767":752,"769":768,"770":768,"771":768,"772":768,"773":768,"774":768,"775":768,"776":768,"777":768,"778":768,"779":768,"780":768,"781":768,"782":768,"783":768,"785":784,"786":784,"787":784,"788":784,"789":784,"790":784,"791":784,"792":784,"793":784,"794":784,"795":784,"796":784,"797":784,"798":784,"799":784,"800":805,"806":805,"807":805,"808":805,"809":805,"810":805,"811":805,"812":805,"813":805,"814":805,"815":805,"833":832,"834":832,"835":832,"836":832,"837":832,"838":832,"839":832,"840":832,"841":832,"842":832,"843":832,"844":832,"845":832,"846":832,"847":832,"856":851,"857":851,"858":851,"859":851,"860":851,"861":851,"862":851,"863":851,"864":866,"865":866,"870":866,"871":866,"872":866,"873":866,"874":866,"875":866,"876":866,"877":866,"878":866,"879":866,"897":896,"898":896,"899":896,"900":896,"901":896,"902":896,"903":896,"904":896,"905":896,"906":896,"907":896,"908":896,"909":896,"910":896,"911":896,"913":912,"914":912,"915":912,"916":912,"917":912,"918":912,"919":912,"920":912,"921":912,"922":912,"923":912,"924":912,"925":912,"926":912,"927":912,"929":928,"930":928,"931":928,"932":928,"933":928,"934":928,"935":928,"936":928,"937":928,"938":928,"939":928,"940":928,"941":928,"942":928,"943":928,"952":944,"953":944,"954":944,"955":944,"956":944,"957":944,"958":944,"959":944,"968":960,"969":960,"970":960,"971":960,"972":960,"973":960,"974":960,"975":960,"976":978,"977":978,"982":978,"983":978,"984":978,"985":978,"986":978,"987":978,"988":978,"989":978,"990":978,"991":978,"992":978,"993":978,"998":978,"999":978,"1000":978,"1001":978,"1002":978,"1003":978,"1004":978,"1005":978,"1006":978,"1007":978,"1036":1027,"1037":1027,"1038":1027,"1039":1027,"1040":1042,"1041":1042,"1046":1042,"1047":1042,"1048":1042,"1049":1042,"1050":1042,"1051":1042,"1052":1042,"1053":1042,"1054":1042,"1055":1042,"1066":1056,"1067":1056,"1068":1056,"1069":1056,"1070":1056,"1071":1056,"1080":1075,"1081":1075,"1082":1075,"1083":1075,"1084":1075,"1085":1075,"1086":1075,"1087":1075,"1088":1090,"1089":1090,"1094":1090,"1095":1090,"1096":1090,"1097":1090,"1098":1090,"1099":1090,"1100":1090,"1101":1090,"1102":1090,"1103":1090,"1122":1120,"1123":1120,"1124":1120,"1125":1120,"1126":1120,"1127":1120,"1128":1120,"1129":1120,"1130":1120,"1131":1120,"1132":1120,"1133":1120,"1134":1120,"1135":1120,"1148":1139,"1149":1139,"1150":1139,"1151":1139,"1154":1152,"1155":1152,"1156":1152,"1157":1152,"1158":1152,"1159":1152,"1160":1152,"1161":1152,"1162":1152,"1163":1152,"1164":1152,"1165":1152,"1166":1152,"1167":1152,"1169":1168,"1170":1168,"1171":1168,"1172":1168,"1173":1168,"1174":1168,"1175":1168,"1176":1168,"1177":1168,"1178":1168,"1179":1168,"1180":1168,"1181":1168,"1182":1168,"1183":1168,"1185":1168,"1186":1168,"1187":1168,"1188":1168,"1189":1168,"1190":1168,"1191":1168,"1192":1168,"1193":1168,"1194":1168,"1195":1168,"1196":1168,"1197":1168,"1198":1168,"1199":1168,"1200":1221,"1206":1221,"1207":1221,"1208":1221,"1209":1221,"1210":1221,"1211":1221,"1212":1221,"1213":1221,"1214":1221,"1215":1221,"1216":1221,"1222":1221,"1223":1221,"1224":1221,"1225":1221,"1226":1221,"1227":1221,"1228":1221,"1229":1221,"1230":1221,"1231":1221,"1238":1232,"1239":1232,"1246":1232,"1247":1232,"1256":1248,"1257":1248,"1258":1248,"1259":1248,"1260":1248,"1261":1248,"1262":1248,"1263":1248,"1265":1264,"1266":1264,"1267":1264,"1268":1264,"1269":1264,"1270":1264,"1271":1264,"1272":1264,"1273":1264,"1274":1264,"1275":1264,"1276":1264,"1277":1264,"1278":1264,"1279":1264,"1281":1280,"1282":1280,"1283":1280,"1284":1280,"1285":1280,"1286":1280,"1287":1280,"1288":1280,"1289":1280,"1290":1280,"1291":1280,"1292":1280,"1293":1280,"1294":1280,"1295":1280,"1313":1312,"1314":1312,"1315":1312,"1316":1312,"1317":1312,"1318":1312,"1319":1312,"1320":1312,"1321":1312,"1322":1312,"1323":1312,"1324":1312,"1325":1312,"1326":1312,"1327":1312,"1345":1344,"1346":1344,"1347":1344,"1348":1344,"1349":1344,"1350":1344,"1351":1344,"1352":1344,"1353":1344,"1354":1344,"1355":1344,"1356":1344,"1357":1344,"1358":1344,"1359":1344,"1377":1376,"1378":1376,"1379":1376,"1380":1376,"1381":1376,"1382":1376,"1383":1376,"1384":1376,"1385":1376,"1386":1376,"1387":1376,"1388":1376,"1389":1376,"1390":1376,"1391":1376,"1393":1392,"1394":1392,"1395":1392,"1396":1392,"1397":1392,"1398":1392,"1399":1392,"1400":1392,"1401":1392,"1402":1392,"1403":1392,"1404":1392,"1405":1392,"1406":1392,"1407":1392,"1409":1408,"1410":1408,"1411":1408,"1412":1408,"1413":1408,"1414":1408,"1415":1408,"1416":1408,"1417":1408,"1418":1408,"1419":1408,"1420":1408,"1421":1408,"1422":1408,"1423":1408,"1425":1424,"1426":1424,"1427":1424,"1428":1424,"1429":1424,"1430":1424,"1431":1424,"1432":1424,"1433":1424,"1434":1424,"1435":1424,"1436":1424,"1437":1424,"1438":1424,"1439":1424,"1440":1441,"1443":1441,"1444":1441,"1445":1441,"1446":1441,"1447":1441,"1448":1441,"1449":1441,"1450":1441,"1451":1441,"1452":1441,"1453":1441,"1454":1441,"1455":1441,"1460":1458,"1461":1458,"1462":1458,"1463":1458,"1464":1458,"1465":1458,"1466":1458,"1467":1458,"1468":1458,"1469":1458,"1470":1458,"1471":1458,"1479":1472,"1480":1472,"1481":1472,"1482":1472,"1483":1472,"1484":1472,"1485":1472,"1486":1472,"1487":1472,"1521":1520,"1522":1520,"1523":1520,"1524":1520,"1525":1520,"1526":1520,"1527":1520,"1528":1520,"1529":1520,"1530":1520,"1531":1520,"1532":1520,"1533":1520,"1534":1520,"1535":1520,"1595":1598,"1596":1598,"1597":1598,"1610":1594,"1611":1614,"1612":1614,"1613":1614,"1615":1599,"1617":1616,"1618":1616,"1619":1616,"1620":1616,"1621":1616,"1622":1616,"1623":1616,"1624":1616,"1625":1616,"1626":1616,"1627":1616,"1628":1616,"1629":1616,"1630":1616,"1631":1616,"1633":1632,"1634":1632,"1635":1632,"1636":1632,"1637":1632,"1638":1632,"1639":1632,"1640":1632,"1641":1632,"1642":1632,"1643":1632,"1644":1632,"1645":1632,"1646":1632,"1647":1632,"1649":1648,"1650":1648,"1651":1648,"1652":1648,"1653":1648,"1654":1648,"1655":1648,"1656":1648,"1657":1648,"1658":1648,"1659":1648,"1660":1648,"1661":1648,"1662":1648,"1663":1648,"1672":1664,"1673":1664,"1674":1664,"1675":1664,"1676":1664,"1677":1664,"1678":1664,"1679":1664,"1688":1680,"1689":1680,"1690":1680,"1691":1680,"1692":1680,"1693":1680,"1694":1680,"1695":1680,"1736":1731,"1737":1731,"1738":1731,"1739":1731,"1740":1731,"1741":1731,"1742":1731,"1743":1731,"1752":1747,"1753":1747,"1754":1747,"1755":1747,"1756":1747,"1757":1747,"1758":1747,"1759":1747,"1761":1760,"1762":1760,"1763":1760,"1764":1760,"1765":1760,"1766":1760,"1767":1760,"1768":1760,"1769":1760,"1770":1760,"1771":1760,"1772":1760,"1773":1760,"1774":1760,"1775":1760,"1777":1776,"1778":1776,"1779":1776,"1780":1776,"1781":1776,"1782":1776,"1783":1776,"1784":1776,"1785":1776,"1786":1776,"1787":1776,"1788":1776,"1789":1776,"1790":1776,"1791":1776,"1793":1792,"1794":1792,"1795":1792,"1796":1792,"1797":1792,"1798":1792,"1799":1792,"1800":1792,"1801":1792,"1802":1792,"1803":1792,"1804":1792,"1805":1792,"1806":1792,"1807":1792,"1809":1808,"1810":1808,"1811":1808,"1812":1808,"1813":1808,"1814":1808,"1815":1808,"1816":1808,"1817":1808,"1818":1808,"1819":1808,"1820":1808,"1821":1808,"1822":1808,"1823":1808,"1832":1827,"1833":1827,"1834":1827,"1835":1827,"1836":1827,"1837":1827,"1838":1827,"1839":1827,"1844":1840,"1845":1840,"1846":1840,"1847":1840,"1848":1840,"1849":1840,"1850":1840,"1851":1840,"1852":1840,"1853":1840,"1854":1840,"1855":1840,"1857":1856,"1858":1856,"1859":1856,"1860":1856,"1861":1856,"1862":1856,"1863":1856,"1864":1856,"1865":1856,"1866":1856,"1867":1856,"1868":1856,"1869":1856,"1870":1856,"1871":1856,"1880":1872,"1881":1872,"1882":1872,"1883":1872,"1884":1872,"1885":1872,"1886":1872,"1887":1872,"1928":1922,"1929":1922,"1930":1922,"1931":1922,"1932":1922,"1933":1922,"1934":1922,"1935":1922,"1937":1936,"1938":1936,"1939":1936,"1940":1936,"1941":1936,"1942":1936,"1943":1936,"1944":1936,"1945":1936,"1946":1936,"1947":1936,"1948":1936,"1949":1936,"1950":1936,"1951":1936,"1953":1952,"1954":1952,"1955":1952,"1956":1952,"1957":1952,"1958":1952,"1959":1952,"1960":1952,"1961":1952,"1962":1952,"1963":1952,"1964":1952,"1965":1952,"1966":1952,"1967":1952,"1969":1968,"1970":1968,"1971":1968,"1972":1968,"1973":1968,"1974":1968,"1975":1968,"1976":1968,"1977":1968,"1978":1968,"1979":1968,"1980":1968,"1981":1968,"1982":1968,"1983":1968,"1985":1968,"1986":1968,"1987":1968,"1988":1968,"1989":1968,"1990":1968,"1991":1968,"1992":1968,"1993":1968,"1994":1968,"1995":1968,"1996":1968,"1997":1968,"1998":1968,"1999":1968,"2022":2016,"2023":2016,"2030":2016,"2031":2016,"2044":2032,"2045":2032,"2046":2032,"2047":2032,"2056":2051,"2057":2051,"2058":2051,"2059":2051,"2060":2051,"2061":2051,"2062":2051,"2063":2051,"2065":2064,"2066":2064,"2067":2064,"2068":2064,"2069":2064,"2070":2064,"2071":2064,"2072":2064,"2073":2064,"2074":2064,"2075":2064,"2076":2064,"2077":2064,"2078":2064,"2079":2064,"2080":2082,"2081":2082,"2086":2082,"2087":2082,"2088":2082,"2089":2082,"2090":2082,"2091":2082,"2092":2082,"2093":2082,"2094":2082,"2095":2082,"2129":2128,"2130":2128,"2131":2128,"2132":2128,"2133":2128,"2134":2128,"2135":2128,"2136":2128,"2137":2128,"2138":2128,"2139":2128,"2140":2128,"2141":2128,"2142":2128,"2143":2128,"2152":2147,"2153":2147,"2154":2147,"2155":2147,"2156":2147,"2157":2147,"2158":2147,"2159":2147,"2168":2163,"2169":2163,"2170":2163,"2171":2163,"2172":2163,"2173":2163,"2174":2163,"2175":2163,"2184":2179,"2185":2179,"2186":2179,"2187":2179,"2188":2179,"2189":2179,"2190":2179,"2191":2179,"2209":2208,"2210":2208,"2211":2208,"2212":2208,"2213":2208,"2214":2208,"2215":2208,"2216":2208,"2217":2208,"2218":2208,"2219":2208,"2220":2208,"2221":2208,"2222":2208,"2223":2208,"2241":2240,"2242":2240,"2243":2240,"2244":2240,"2245":2240,"2246":2240,"2247":2240,"2248":2240,"2249":2240,"2250":2240,"2251":2240,"2252":2240,"2253":2240,"2254":2240,"2255":2240,"2264":2256,"2265":2256,"2266":2256,"2267":2256,"2268":2256,"2269":2256,"2270":2256,"2271":2256,"2280":2272,"2281":2272,"2282":2272,"2283":2272,"2284":2272,"2285":2272,"2286":2272,"2287":2272,"2294":2288,"2295":2288,"2302":2288,"2303":2288,"2304":2306,"2310":2306,"2311":2306,"2312":2306,"2313":2306,"2314":2306,"2315":2306,"2316":2306,"2317":2306,"2318":2306,"2319":2306,"2332":2322,"2333":2322,"2334":2322,"2335":2322,"2336":2338,"2337":2338,"2342":2338,"2343":2338,"2344":2338,"2345":2338,"2346":2338,"2347":2338,"2348":2338,"2349":2338,"2350":2338,"2351":2338,"2392":2386,"2393":2386,"2394":2386,"2395":2386,"2396":2386,"2397":2386,"2398":2386,"2399":2386,"2400":2386,"2401":2386,"2402":2386,"2403":2386,"2404":2386,"2405":2386,"2406":2386,"2407":2386,"2433":2432,"2434":2432,"2435":2432,"2436":2432,"2437":2432,"2438":2432,"2439":2432,"2440":2432,"2441":2432,"2442":2432,"2443":2432,"2444":2432,"2445":2432,"2446":2432,"2447":2432,"2449":2448,"2450":2448,"2451":2448,"2452":2448,"2453":2448,"2454":2448,"2455":2448,"2456":2448,"2457":2448,"2458":2448,"2459":2448,"2460":2448,"2461":2448,"2462":2448,"2463":2448,"2465":2464,"2470":2464,"2471":2464,"2473":2464,"2478":2464,"2479":2464,"2493":2481,"2494":2482,"2504":2499,"2505":2499,"2506":2499,"2507":2499,"2508":2499,"2509":2499,"2510":2499,"2511":2499,"2520":2512,"2521":2513,"2522":2514,"2523":2515,"2524":2516,"2525":2517,"2604":7476,"2605":7477,"2616":2611,"2617":2611,"2618":2611,"2619":2611,"2620":2611,"2621":2611,"2622":2611,"2623":2611,"2632":2627,"2633":2627,"2634":2627,"2635":2627,"2636":2627,"2637":2627,"2638":2627,"2639":2627,"2641":2640,"2642":2640,"2643":2640,"2644":2640,"2645":2640,"2646":2640,"2647":2640,"2648":2640,"2649":2640,"2650":2640,"2651":2640,"2652":2640,"2653":2640,"2654":2640,"2655":2640,"2705":2704,"2706":2704,"2707":2704,"2708":2704,"2709":2704,"2710":2704,"2711":2704,"2712":2704,"2713":2704,"2714":2704,"2715":2704,"2716":2704,"2717":2704,"2718":2704,"2719":2704,"2721":2720,"2722":2720,"2723":2720,"2725":2720,"2726":2720,"2727":2720,"2729":2720,"2730":2720,"2731":2720,"2732":2720,"2733":2720,"2734":2720,"2735":2720,"2753":2752,"2754":2752,"2755":2752,"2756":2752,"2757":2752,"2758":2752,"2759":2752,"2760":2752,"2761":2752,"2762":2752,"2763":2752,"2764":2752,"2765":2752,"2766":2752,"2767":2752,"2769":2768,"2770":2768,"2771":2768,"2772":2768,"2773":2768,"2774":2768,"2775":2768,"2776":2768,"2777":2768,"2778":2768,"2779":2768,"2780":2768,"2781":2768,"2782":2768,"2783":2768,"2785":2784,"2786":2784,"2787":2784,"2788":2784,"2789":2784,"2790":2784,"2791":2784,"2792":2784,"2793":2784,"2794":2784,"2795":2784,"2796":2784,"2797":2784,"2798":2784,"2799":2784,"2832":2834,"2833":2834,"2838":2834,"2839":2834,"2840":2834,"2841":2834,"2842":2834,"2843":2834,"2844":2834,"2845":2834,"2846":2834,"2847":2834,"2888":2883,"2889":2883,"2890":2883,"2891":2883,"2892":2883,"2893":2883,"2894":2883,"2895":2883,"2904":2896,"2905":2897,"2906":2898,"2907":2899,"2908":2900,"2909":2901,"2910":2902,"2911":2903,"3041":3040,"3042":3040,"3043":3040,"3044":3040,"3045":3040,"3046":3040,"3047":3040,"3048":3040,"3049":3040,"3050":3040,"3051":3040,"3052":3040,"3053":3040,"3054":3040,"3055":3040,"3073":3072,"3074":3072,"3075":3072,"3076":3072,"3077":3072,"3078":3072,"3079":3072,"3080":3072,"3081":3072,"3082":3072,"3083":3072,"3084":3072,"3085":3072,"3086":3072,"3087":3072,"3100":3091,"3101":3091,"3102":3091,"3103":3091,"3116":3107,"3117":3107,"3118":3107,"3119":3107,"3132":3123,"3133":3123,"3134":3123,"3135":3123,"3148":3139,"3149":3139,"3150":3139,"3151":3139,"3164":3155,"3165":3155,"3166":3155,"3167":3155,"3169":3168,"3170":3168,"3171":3168,"3172":3168,"3173":3168,"3174":3168,"3175":3168,"3176":3168,"3177":3168,"3178":3168,"3179":3168,"3180":3168,"3181":3168,"3182":3168,"3183":3168,"3192":3187,"3193":3187,"3194":3187,"3195":3187,"3196":3187,"3197":3187,"3198":3187,"3199":3187,"3230":3218,"3232":3237,"3238":3237,"3239":3237,"3240":3245,"3246":3245,"3247":3245,"3256":3251,"3257":3251,"3258":3251,"3259":3251,"3260":3251,"3261":3251,"3262":3251,"3263":3251,"3264":3269,"3270":3269,"3271":3269,"3272":3277,"3278":3277,"3279":3277,"3281":3280,"3282":3280,"3283":3280,"3284":3280,"3285":3280,"3286":3280,"3287":3280,"3288":3280,"3289":3280,"3290":3280,"3291":3280,"3292":3280,"3293":3280,"3294":3280,"3295":3280,"3297":3296,"3298":3296,"3299":3296,"3300":3296,"3301":3296,"3302":3296,"3303":3296,"3304":3296,"3305":3296,"3306":3296,"3307":3296,"3308":3296,"3309":3296,"3310":3296,"3311":3296,"3316":3312,"3317":3312,"3318":3312,"3319":3312,"3320":3312,"3321":3312,"3322":3312,"3323":3312,"3324":3312,"3325":3312,"3326":3312,"3327":3312,"3334":3328,"3335":3328,"3336":3328,"3337":3328,"3338":3328,"3339":3328,"3340":3328,"3341":3328,"3342":3328,"3343":3328,"3409":3408,"3410":3408,"3411":3408,"3412":3408,"3413":3408,"3414":3408,"3415":3408,"3416":3408,"3417":3408,"3418":3408,"3419":3408,"3420":3408,"3421":3408,"3422":3408,"3423":3408,"3425":3424,"3426":3424,"3427":3424,"3428":3424,"3429":3424,"3430":3424,"3431":3424,"3432":3424,"3433":3424,"3434":3424,"3435":3424,"3436":3424,"3437":3424,"3438":3424,"3439":3424,"3441":3440,"3442":3440,"3443":3440,"3444":3440,"3445":3440,"3446":3440,"3447":3440,"3448":3440,"3449":3440,"3450":3440,"3451":3440,"3452":3440,"3453":3440,"3454":3440,"3455":3440,"3457":3456,"3458":3456,"3459":3456,"3461":3456,"3462":3456,"3463":3456,"3465":3456,"3466":3456,"3467":3456,"3468":3456,"3469":3456,"3470":3456,"3471":3456,"3504":3506,"3505":3506,"3510":3506,"3511":3506,"3512":3506,"3513":3506,"3514":3506,"3515":3506,"3516":3506,"3517":3506,"3518":3506,"3519":3506,"3520":3522,"3521":3522,"3526":3522,"3527":3522,"3528":3522,"3529":3522,"3530":3522,"3531":3522,"3532":3522,"3533":3522,"3534":3522,"3535":3522,"3536":3538,"3537":3538,"3542":3538,"3543":3538,"3544":3538,"3545":3538,"3546":3538,"3547":3538,"3548":3538,"3549":3538,"3550":3538,"3551":3538,"3552":3554,"3553":3554,"3558":3554,"3559":3554,"3560":3554,"3561":3554,"3562":3554,"3563":3554,"3564":3554,"3565":3554,"3566":3554,"3567":3554,"3568":3570,"3569":3570,"3574":3570,"3575":3570,"3576":3570,"3577":3570,"3578":3570,"3579":3570,"3580":3570,"3581":3570,"3582":3570,"3583":3570,"3584":3586,"3585":3586,"3590":3586,"3591":3586,"3592":3586,"3593":3586,"3594":3586,"3595":3586,"3596":3586,"3597":3586,"3598":3586,"3599":3586,"3600":3602,"3601":3602,"3606":3602,"3607":3602,"3608":3602,"3609":3602,"3610":3602,"3611":3602,"3612":3602,"3613":3602,"3614":3602,"3615":3602,"3616":3618,"3617":3618,"3622":3618,"3623":3618,"3624":3618,"3625":3618,"3626":3618,"3627":3618,"3628":3618,"3629":3618,"3630":3618,"3631":3618,"3632":3634,"3633":3634,"3638":3634,"3639":3634,"3640":3634,"3641":3634,"3642":3634,"3643":3634,"3644":3634,"3645":3634,"3646":3634,"3647":3634,"3648":3650,"3649":3650,"3654":3650,"3655":3650,"3656":3650,"3657":3650,"3658":3650,"3659":3650,"3660":3650,"3661":3650,"3662":3650,"3663":3650,"3664":3666,"3665":3666,"3670":3666,"3671":3666,"3672":3666,"3673":3666,"3674":3666,"3675":3666,"3676":3666,"3677":3666,"3678":3666,"3679":3666,"3696":3698,"3697":3698,"3702":3698,"3703":3698,"3704":3698,"3705":3698,"3706":3698,"3707":3698,"3708":3698,"3709":3698,"3710":3698,"3711":3698,"3712":3714,"3713":3714,"3718":3714,"3719":3714,"3720":3714,"3721":3714,"3722":3714,"3723":3714,"3724":3714,"3725":3714,"3726":3714,"3727":3714,"3728":3730,"3729":3730,"3734":3730,"3735":3730,"3736":3730,"3737":3730,"3738":3730,"3739":3730,"3740":3730,"3741":3730,"3742":3730,"3743":3730,"3744":3746,"3745":3746,"3750":3746,"3751":3746,"3752":3746,"3753":3746,"3754":3746,"3755":3746,"3756":3746,"3757":3746,"3758":3746,"3759":3746,"3760":3762,"3761":3762,"3766":3762,"3767":3762,"3768":3762,"3769":3762,"3770":3762,"3771":3762,"3772":3762,"3773":3762,"3774":3762,"3775":3762,"3824":3829,"3830":3829,"3831":3829,"3832":3829,"3833":3829,"3834":3829,"3835":3829,"3836":3829,"3837":3829,"3838":3829,"3839":3829,"3889":3888,"3890":3888,"3891":3888,"3892":3888,"3893":3888,"3894":3888,"3895":3888,"3896":3888,"3897":3888,"3898":3888,"3899":3888,"3900":3888,"3901":3888,"3902":3888,"3903":3888,"3912":3904,"3913":3904,"3914":3904,"3915":3904,"3916":3904,"3917":3904,"3918":3904,"3919":3904,"3921":3920,"3922":3920,"3923":3920,"3924":3920,"3925":3920,"3926":3920,"3927":3920,"3928":3920,"3929":3920,"3930":3920,"3931":3920,"3932":3920,"3933":3920,"3934":3920,"3935":3920,"3937":3936,"3938":3936,"3939":3936,"3940":3936,"3941":3936,"3942":3936,"3943":3936,"3944":3936,"3945":3936,"3946":3936,"3947":3936,"3948":3936,"3949":3936,"3950":3936,"3951":3936,"3955":3952,"3956":3952,"3957":3952,"3958":3952,"3959":3952,"3960":3952,"3961":3952,"3962":3952,"3963":3952,"3964":3952,"3965":3952,"3966":3952,"3967":3952,"3969":3968,"3970":3968,"3971":3968,"3972":3968,"3973":3968,"3974":3968,"3975":3968,"3976":3968,"3977":3968,"3978":3968,"3979":3968,"3980":3968,"3981":3968,"3982":3968,"3983":3968,"3985":3984,"3986":3984,"3987":3984,"3988":3984,"3989":3984,"3990":3984,"3991":3984,"3992":3984,"3993":3984,"3994":3984,"3995":3984,"3996":3984,"3997":3984,"3998":3984,"3999":3984,"4049":4048,"4050":4048,"4051":4048,"4052":4048,"4053":4048,"4054":4048,"4055":4048,"4056":4048,"4057":4048,"4058":4048,"4059":4048,"4060":4048,"4061":4048,"4062":4048,"4063":4048,"4081":4080,"4082":4080,"4083":4080,"4084":4080,"4085":4080,"4086":4080,"4087":4080,"4088":4080,"4089":4080,"4090":4080,"4091":4080,"4092":4080,"4093":4080,"4094":4080,"4095":4080,"4120":4115,"4121":4115,"4122":4115,"4123":4115,"4124":4115,"4125":4115,"4126":4115,"4127":4115,"4136":4131,"4137":4131,"4138":4131,"4139":4131,"4140":4131,"4141":4131,"4142":4131,"4143":4131,"4152":4147,"4153":4147,"4154":4147,"4155":4147,"4156":4147,"4157":4147,"4158":4147,"4159":4147,"4163":4160,"4164":4160,"4165":4160,"4166":4160,"4167":4160,"4168":4160,"4169":4160,"4170":4160,"4171":4160,"4172":4160,"4173":4160,"4174":4160,"4175":4160,"4179":4176,"4180":4176,"4181":4176,"4182":4176,"4183":4176,"4184":4176,"4185":4176,"4186":4176,"4187":4176,"4188":4176,"4189":4176,"4190":4176,"4191":4176,"4195":4192,"4196":4192,"4197":4192,"4198":4192,"4199":4192,"4200":4192,"4201":4192,"4202":4192,"4203":4192,"4204":4192,"4205":4192,"4206":4192,"4207":4192,"4211":4208,"4212":4208,"4213":4208,"4214":4208,"4215":4208,"4216":4208,"4217":4208,"4218":4208,"4219":4208,"4220":4208,"4221":4208,"4222":4208,"4223":4208,"4227":4224,"4228":4224,"4229":4224,"4230":4224,"4231":4224,"4232":4224,"4233":4224,"4234":4224,"4235":4224,"4236":4224,"4237":4224,"4238":4224,"4239":4224,"4243":4240,"4244":4240,"4245":4240,"4246":4240,"4247":4240,"4248":4240,"4249":4240,"4250":4240,"4251":4240,"4252":4240,"4253":4240,"4254":4240,"4255":4240,"4257":4256,"4258":4256,"4259":4256,"4260":4256,"4261":4256,"4262":4256,"4263":4256,"4264":4256,"4265":4256,"4266":4256,"4267":4256,"4268":4256,"4269":4256,"4270":4256,"4271":4256,"4273":4272,"4274":4272,"4275":4272,"4276":4272,"4277":4272,"4278":4272,"4279":4272,"4280":4272,"4281":4272,"4282":4272,"4283":4272,"4284":4272,"4285":4272,"4286":4272,"4287":4272,"4289":4288,"4290":4288,"4291":4288,"4292":4288,"4293":4288,"4294":4288,"4295":4288,"4296":4288,"4297":4288,"4298":4288,"4299":4288,"4300":4288,"4301":4288,"4302":4288,"4303":4288,"4305":4304,"4306":4304,"4307":4304,"4308":4304,"4309":4304,"4310":4304,"4311":4304,"4312":4304,"4313":4304,"4314":4304,"4315":4304,"4316":4304,"4317":4304,"4318":4304,"4319":4304,"4321":4320,"4322":4320,"4323":4320,"4324":4320,"4325":4320,"4326":4320,"4327":4320,"4328":4320,"4329":4320,"4330":4320,"4331":4320,"4332":4320,"4333":4320,"4334":4320,"4335":4320,"4337":4336,"4338":4336,"4339":4336,"4340":4336,"4341":4336,"4342":4336,"4343":4336,"4344":4336,"4345":4336,"4346":4336,"4347":4336,"4348":4336,"4349":4336,"4350":4336,"4351":4336,"4353":4352,"4354":4352,"4355":4352,"4356":4352,"4357":4352,"4358":4352,"4359":4352,"4360":4352,"4361":4352,"4362":4352,"4363":4352,"4364":4352,"4365":4352,"4366":4352,"4367":4352,"4369":4368,"4370":4368,"4371":4368,"4372":4368,"4373":4368,"4374":4368,"4375":4368,"4376":4368,"4377":4368,"4378":4368,"4379":4368,"4380":4368,"4381":4368,"4382":4368,"4383":4368,"4385":4384,"4386":4384,"4387":4384,"4388":4384,"4389":4384,"4390":4384,"4391":4384,"4392":4384,"4393":4384,"4394":4384,"4395":4384,"4396":4384,"4397":4384,"4398":4384,"4399":4384,"4401":4400,"4402":4400,"4403":4400,"4404":4400,"4405":4400,"4406":4400,"4407":4400,"4408":4400,"4409":4400,"4410":4400,"4411":4400,"4412":4400,"4413":4400,"4414":4400,"4415":4400,"4417":4416,"4418":4416,"4419":4416,"4420":4416,"4421":4416,"4422":4416,"4423":4416,"4424":4416,"4425":4416,"4426":4416,"4427":4416,"4428":4416,"4429":4416,"4430":4416,"4431":4416,"4433":4432,"4434":4432,"4435":4432,"4436":4432,"4437":4432,"4438":4432,"4439":4432,"4440":4432,"4441":4432,"4442":4432,"4443":4432,"4444":4432,"4445":4432,"4446":4432,"4447":4432,"4449":4448,"4450":4448,"4451":4448,"4452":4448,"4453":4448,"4454":4448,"4455":4448,"4456":4448,"4457":4448,"4458":4448,"4459":4448,"4460":4448,"4461":4448,"4462":4448,"4463":4448,"4465":4464,"4466":4464,"4467":4464,"4468":4464,"4469":4464,"4470":4464,"4471":4464,"4472":4464,"4473":4464,"4474":4464,"4475":4464,"4476":4464,"4477":4464,"4478":4464,"4479":4464,"4481":4480,"4482":4480,"4483":4480,"4484":4480,"4485":4480,"4486":4480,"4487":4480,"4488":4480,"4489":4480,"4490":4480,"4491":4480,"4492":4480,"4493":4480,"4494":4480,"4495":4480,"4497":4496,"4498":4496,"4499":4496,"4500":4496,"4501":4496,"4502":4496,"4503":4496,"4504":4496,"4505":4496,"4506":4496,"4507":4496,"4508":4496,"4509":4496,"4510":4496,"4511":4496,"4513":4512,"4514":4512,"4515":4512,"4516":4512,"4517":4512,"4518":4512,"4519":4512,"4520":4512,"4521":4512,"4522":4512,"4523":4512,"4524":4512,"4525":4512,"4526":4512,"4527":4512,"4529":4528,"4530":4528,"4531":4528,"4532":4528,"4533":4528,"4534":4528,"4535":4528,"4536":4528,"4537":4528,"4538":4528,"4539":4528,"4540":4528,"4541":4528,"4542":4528,"4543":4528,"4545":4544,"4546":4544,"4547":4544,"4548":4544,"4549":4544,"4550":4544,"4551":4544,"4552":4544,"4553":4544,"4554":4544,"4555":4544,"4556":4544,"4557":4544,"4558":4544,"4559":4544,"4561":4560,"4562":4560,"4563":4560,"4564":4560,"4565":4560,"4566":4560,"4567":4560,"4568":4560,"4569":4560,"4570":4560,"4571":4560,"4572":4560,"4573":4560,"4574":4560,"4575":4560,"4577":4576,"4578":4576,"4579":4576,"4580":4576,"4581":4576,"4582":4576,"4583":4576,"4584":4576,"4585":4576,"4586":4576,"4587":4576,"4588":4576,"4589":4576,"4590":4576,"4591":4576,"4593":4592,"4594":4592,"4595":4592,"4596":4592,"4597":4592,"4598":4592,"4599":4592,"4600":4592,"4601":4592,"4602":4592,"4603":4592,"4604":4592,"4605":4592,"4606":4592,"4607":4592,"4609":4608,"4610":4608,"4611":4608,"4612":4608,"4613":4608,"4614":4608,"4615":4608,"4616":4608,"4617":4608,"4618":4608,"4619":4608,"4620":4608,"4621":4608,"4622":4608,"4623":4608,"4625":4624,"4626":4624,"4627":4624,"4628":4624,"4629":4624,"4630":4624,"4631":4624,"4632":4624,"4633":4624,"4634":4624,"4635":4624,"4636":4624,"4637":4624,"4638":4624,"4639":4624,"4641":4640,"4642":4640,"4643":4640,"4644":4640,"4645":4640,"4646":4640,"4647":4640,"4648":4640,"4649":4640,"4650":4640,"4651":4640,"4652":4640,"4653":4640,"4654":4640,"4655":4640,"4657":4656,"4658":4656,"4659":4656,"4660":4656,"4661":4656,"4662":4656,"4663":4656,"4664":4656,"4665":4656,"4666":4656,"4667":4656,"4668":4656,"4669":4656,"4670":4656,"4671":4656,"4673":4672,"4674":4672,"4675":4672,"4676":4672,"4677":4672,"4678":4672,"4679":4672,"4680":4672,"4681":4672,"4682":4672,"4683":4672,"4684":4672,"4685":4672,"4686":4672,"4687":4672,"4689":4688,"4690":4688,"4691":4688,"4692":4688,"4693":4688,"4694":4688,"4695":4688,"4696":4688,"4697":4688,"4698":4688,"4699":4688,"4700":4688,"4701":4688,"4702":4688,"4703":4688,"4705":4704,"4706":4704,"4707":4704,"4708":4704,"4709":4704,"4710":4704,"4711":4704,"4712":4704,"4713":4704,"4714":4704,"4715":4704,"4716":4704,"4717":4704,"4718":4704,"4719":4704,"4721":4720,"4722":4720,"4723":4720,"4724":4720,"4725":4720,"4726":4720,"4727":4720,"4728":4720,"4729":4720,"4730":4720,"4731":4720,"4732":4720,"4733":4720,"4734":4720,"4735":4720,"4737":4736,"4738":4736,"4739":4736,"4740":4736,"4741":4736,"4742":4736,"4743":4736,"4744":4736,"4745":4736,"4746":4736,"4747":4736,"4748":4736,"4749":4736,"4750":4736,"4751":4736,"4753":4752,"4754":4752,"4755":4752,"4756":4752,"4757":4752,"4758":4752,"4759":4752,"4760":4752,"4761":4752,"4762":4752,"4763":4752,"4764":4752,"4765":4752,"4766":4752,"4767":4752,"4769":4768,"4770":4768,"4771":4768,"4772":4768,"4773":4768,"4774":4768,"4775":4768,"4776":4768,"4777":4768,"4778":4768,"4779":4768,"4780":4768,"4781":4768,"4782":4768,"4783":4768,"4785":4784,"4786":4784,"4787":4784,"4788":4784,"4789":4784,"4790":4784,"4791":4784,"4792":4784,"4793":4784,"4794":4784,"4795":4784,"4796":4784,"4797":4784,"4798":4784,"4799":4784,"4801":4800,"4802":4800,"4803":4800,"4804":4800,"4805":4800,"4806":4800,"4807":4800,"4808":4800,"4809":4800,"4810":4800,"4811":4800,"4812":4800,"4813":4800,"4814":4800,"4815":4800,"4817":4816,"4818":4816,"4819":4816,"4820":4816,"4821":4816,"4822":4816,"4823":4816,"4824":4816,"4825":4816,"4826":4816,"4827":4816,"4828":4816,"4829":4816,"4830":4816,"4831":4816,"4833":4832,"4834":4832,"4835":4832,"4836":4832,"4837":4832,"4838":4832,"4839":4832,"4840":4832,"4841":4832,"4842":4832,"4843":4832,"4844":4832,"4845":4832,"4846":4832,"4847":4832,"4849":4848,"4850":4848,"4851":4848,"4852":4848,"4853":4848,"4854":4848,"4855":4848,"4856":4848,"4857":4848,"4858":4848,"4859":4848,"4860":4848,"4861":4848,"4862":4848,"4863":4848,"4865":4864,"4866":4864,"4867":4864,"4868":4864,"4869":4864,"4870":4864,"4871":4864,"4872":4864,"4873":4864,"4874":4864,"4875":4864,"4876":4864,"4877":4864,"4878":4864,"4879":4864,"4881":4880,"4882":4880,"4883":4880,"4884":4880,"4885":4880,"4886":4880,"4887":4880,"4888":4880,"4889":4880,"4890":4880,"4891":4880,"4892":4880,"4893":4880,"4894":4880,"4895":4880,"4897":4896,"4898":4896,"4899":4896,"4900":4896,"4901":4896,"4902":4896,"4903":4896,"4904":4896,"4905":4896,"4906":4896,"4907":4896,"4908":4896,"4909":4896,"4910":4896,"4911":4896,"4913":4912,"4914":4912,"4915":4912,"4916":4912,"4917":4912,"4918":4912,"4919":4912,"4920":4912,"4921":4912,"4922":4912,"4923":4912,"4924":4912,"4925":4912,"4926":4912,"4927":4912,"4929":4928,"4930":4928,"4931":4928,"4932":4928,"4933":4928,"4934":4928,"4935":4928,"4936":4928,"4937":4928,"4938":4928,"4939":4928,"4940":4928,"4941":4928,"4942":4928,"4943":4928,"4945":4944,"4946":4944,"4947":4944,"4948":4944,"4949":4944,"4950":4944,"4951":4944,"4952":4944,"4953":4944,"4954":4944,"4955":4944,"4956":4944,"4957":4944,"4958":4944,"4959":4944,"4961":4960,"4962":4960,"4963":4960,"4964":4960,"4965":4960,"4966":4960,"4967":4960,"4968":4960,"4969":4960,"4970":4960,"4971":4960,"4972":4960,"4973":4960,"4974":4960,"4975":4960,"4977":4976,"4978":4976,"4979":4976,"4980":4976,"4981":4976,"4982":4976,"4983":4976,"4984":4976,"4985":4976,"4986":4976,"4987":4976,"4988":4976,"4989":4976,"4990":4976,"4991":4976,"4993":4992,"4994":4992,"4995":4992,"4996":4992,"4997":4992,"4998":4992,"4999":4992,"5000":4992,"5001":4992,"5002":4992,"5003":4992,"5004":4992,"5005":4992,"5006":4992,"5007":4992,"5009":5008,"5010":5008,"5011":5008,"5012":5008,"5013":5008,"5014":5008,"5015":5008,"5016":5008,"5017":5008,"5018":5008,"5019":5008,"5020":5008,"5021":5008,"5022":5008,"5023":5008,"5025":5024,"5026":5024,"5027":5024,"5028":5024,"5029":5024,"5030":5024,"5031":5024,"5032":5024,"5033":5024,"5034":5024,"5035":5024,"5036":5024,"5037":5024,"5038":5024,"5039":5024,"5041":5040,"5042":5040,"5043":5040,"5044":5040,"5045":5040,"5046":5040,"5047":5040,"5048":5040,"5049":5040,"5050":5040,"5051":5040,"5052":5040,"5053":5040,"5054":5040,"5055":5040,"5057":5056,"5058":5056,"5059":5056,"5060":5056,"5061":5056,"5062":5056,"5063":5056,"5064":5056,"5065":5056,"5066":5056,"5067":5056,"5068":5056,"5069":5056,"5070":5056,"5071":5056,"5073":5072,"5074":5072,"5075":5072,"5076":5072,"5077":5072,"5078":5072,"5079":5072,"5080":5072,"5081":5072,"5082":5072,"5083":5072,"5084":5072,"5085":5072,"5086":5072,"5087":5072,"5089":5088,"5090":5088,"5091":5088,"5092":5088,"5093":5088,"5094":5088,"5095":5088,"5096":5088,"5097":5088,"5098":5088,"5099":5088,"5100":5088,"5101":5088,"5102":5088,"5103":5088,"5105":5104,"5106":5104,"5107":5104,"5108":5104,"5109":5104,"5110":5104,"5111":5104,"5112":5104,"5113":5104,"5114":5104,"5115":5104,"5116":5104,"5117":5104,"5118":5104,"5119":5104,"5121":5120,"5122":5120,"5123":5120,"5124":5120,"5125":5120,"5126":5120,"5127":5120,"5128":5120,"5129":5120,"5130":5120,"5131":5120,"5132":5120,"5133":5120,"5134":5120,"5135":5120,"5137":5136,"5138":5136,"5139":5136,"5140":5136,"5141":5136,"5142":5136,"5143":5136,"5144":5136,"5145":5136,"5146":5136,"5147":5136,"5148":5136,"5149":5136,"5150":5136,"5151":5136,"5153":5152,"5154":5152,"5155":5152,"5156":5152,"5157":5152,"5158":5152,"5159":5152,"5160":5152,"5161":5152,"5162":5152,"5163":5152,"5164":5152,"5165":5152,"5166":5152,"5167":5152,"5169":5168,"5170":5168,"5171":5168,"5172":5168,"5173":5168,"5174":5168,"5175":5168,"5176":5168,"5177":5168,"5178":5168,"5179":5168,"5180":5168,"5181":5168,"5182":5168,"5183":5168,"5185":5184,"5186":5184,"5187":5184,"5188":5184,"5189":5184,"5190":5184,"5191":5184,"5192":5184,"5193":5184,"5194":5184,"5195":5184,"5196":5184,"5197":5184,"5198":5184,"5199":5184,"5201":5200,"5202":5200,"5203":5200,"5204":5200,"5205":5200,"5206":5200,"5207":5200,"5208":5200,"5209":5200,"5210":5200,"5211":5200,"5212":5200,"5213":5200,"5214":5200,"5215":5200,"5217":5216,"5218":5216,"5219":5216,"5220":5216,"5221":5216,"5222":5216,"5223":5216,"5224":5216,"5225":5216,"5226":5216,"5227":5216,"5228":5216,"5229":5216,"5230":5216,"5231":5216,"5233":5232,"5234":5232,"5235":5232,"5236":5232,"5237":5232,"5238":5232,"5239":5232,"5240":5232,"5241":5232,"5242":5232,"5243":5232,"5244":5232,"5245":5232,"5246":5232,"5247":5232,"5249":5248,"5250":5248,"5251":5248,"5252":5248,"5253":5248,"5254":5248,"5255":5248,"5256":5248,"5257":5248,"5258":5248,"5259":5248,"5260":5248,"5261":5248,"5262":5248,"5263":5248,"5265":5264,"5266":5264,"5267":5264,"5268":5264,"5269":5264,"5270":5264,"5271":5264,"5272":5264,"5273":5264,"5274":5264,"5275":5264,"5276":5264,"5277":5264,"5278":5264,"5279":5264,"5281":5280,"5282":5280,"5283":5280,"5284":5280,"5285":5280,"5286":5280,"5287":5280,"5288":5280,"5289":5280,"5290":5280,"5291":5280,"5292":5280,"5293":5280,"5294":5280,"5295":5280,"5297":5296,"5298":5296,"5299":5296,"5300":5296,"5301":5296,"5302":5296,"5303":5296,"5304":5296,"5305":5296,"5306":5296,"5307":5296,"5308":5296,"5309":5296,"5310":5296,"5311":5296,"5313":5312,"5314":5312,"5315":5312,"5316":5312,"5317":5312,"5318":5312,"5319":5312,"5320":5312,"5321":5312,"5322":5312,"5323":5312,"5324":5312,"5325":5312,"5326":5312,"5327":5312,"5329":5328,"5330":5328,"5331":5328,"5332":5328,"5333":5328,"5334":5328,"5335":5328,"5336":5328,"5337":5328,"5338":5328,"5339":5328,"5340":5328,"5341":5328,"5342":5328,"5343":5328,"5345":5344,"5346":5344,"5347":5344,"5348":5344,"5349":5344,"5350":5344,"5351":5344,"5352":5344,"5353":5344,"5354":5344,"5355":5344,"5356":5344,"5357":5344,"5358":5344,"5359":5344,"5361":5360,"5362":5360,"5363":5360,"5364":5360,"5365":5360,"5366":5360,"5367":5360,"5368":5360,"5369":5360,"5370":5360,"5371":5360,"5372":5360,"5373":5360,"5374":5360,"5375":5360,"5377":5376,"5378":5376,"5379":5376,"5380":5376,"5381":5376,"5382":5376,"5383":5376,"5384":5376,"5385":5376,"5386":5376,"5387":5376,"5388":5376,"5389":5376,"5390":5376,"5391":5376,"5393":5392,"5394":5392,"5395":5392,"5396":5392,"5397":5392,"5398":5392,"5399":5392,"5400":5392,"5401":5392,"5402":5392,"5403":5392,"5404":5392,"5405":5392,"5406":5392,"5407":5392,"5409":5408,"5410":5408,"5411":5408,"5412":5408,"5413":5408,"5414":5408,"5415":5408,"5416":5408,"5417":5408,"5418":5408,"5419":5408,"5420":5408,"5421":5408,"5422":5408,"5423":5408,"5425":5424,"5426":5424,"5427":5424,"5428":5424,"5429":5424,"5430":5424,"5431":5424,"5432":5424,"5433":5424,"5434":5424,"5435":5424,"5436":5424,"5437":5424,"5438":5424,"5439":5424,"5441":5440,"5442":5440,"5443":5440,"5444":5440,"5445":5440,"5446":5440,"5447":5440,"5448":5440,"5449":5440,"5450":5440,"5451":5440,"5452":5440,"5453":5440,"5454":5440,"5455":5440,"5457":5456,"5458":5456,"5459":5456,"5460":5456,"5461":5456,"5462":5456,"5463":5456,"5464":5456,"5465":5456,"5466":5456,"5467":5456,"5468":5456,"5469":5456,"5470":5456,"5471":5456,"5473":5472,"5474":5472,"5475":5472,"5476":5472,"5477":5472,"5478":5472,"5479":5472,"5480":5472,"5481":5472,"5482":5472,"5483":5472,"5484":5472,"5485":5472,"5486":5472,"5487":5472,"5489":5488,"5490":5488,"5491":5488,"5492":5488,"5493":5488,"5494":5488,"5495":5488,"5496":5488,"5497":5488,"5498":5488,"5499":5488,"5500":5488,"5501":5488,"5502":5488,"5503":5488,"5505":5504,"5506":5504,"5507":5504,"5508":5504,"5509":5504,"5510":5504,"5511":5504,"5512":5504,"5513":5504,"5514":5504,"5515":5504,"5516":5504,"5517":5504,"5518":5504,"5519":5504,"5521":5520,"5522":5520,"5523":5520,"5524":5520,"5525":5520,"5526":5520,"5527":5520,"5528":5520,"5529":5520,"5530":5520,"5531":5520,"5532":5520,"5533":5520,"5534":5520,"5535":5520,"5537":5536,"5538":5536,"5539":5536,"5540":5536,"5541":5536,"5542":5536,"5543":5536,"5544":5536,"5545":5536,"5546":5536,"5547":5536,"5548":5536,"5549":5536,"5550":5536,"5551":5536,"5553":5552,"5554":5552,"5555":5552,"5556":5552,"5557":5552,"5558":5552,"5559":5552,"5560":5552,"5561":5552,"5562":5552,"5563":5552,"5564":5552,"5565":5552,"5566":5552,"5567":5552,"5569":5568,"5570":5568,"5571":5568,"5572":5568,"5573":5568,"5574":5568,"5575":5568,"5576":5568,"5577":5568,"5578":5568,"5579":5568,"5580":5568,"5581":5568,"5582":5568,"5583":5568,"5585":5584,"5586":5584,"5587":5584,"5588":5584,"5589":5584,"5590":5584,"5591":5584,"5592":5584,"5593":5584,"5594":5584,"5595":5584,"5596":5584,"5597":5584,"5598":5584,"5599":5584,"5601":5600,"5602":5600,"5603":5600,"5604":5600,"5605":5600,"5606":5600,"5607":5600,"5608":5600,"5609":5600,"5610":5600,"5611":5600,"5612":5600,"5613":5600,"5614":5600,"5615":5600,"5617":5616,"5618":5616,"5619":5616,"5620":5616,"5621":5616,"5622":5616,"5623":5616,"5624":5616,"5625":5616,"5626":5616,"5627":5616,"5628":5616,"5629":5616,"5630":5616,"5631":5616,"5633":5632,"5634":5632,"5635":5632,"5636":5632,"5637":5632,"5638":5632,"5639":5632,"5640":5632,"5641":5632,"5642":5632,"5643":5632,"5644":5632,"5645":5632,"5646":5632,"5647":5632,"5649":5648,"5650":5648,"5651":5648,"5652":5648,"5653":5648,"5654":5648,"5655":5648,"5656":5648,"5657":5648,"5658":5648,"5659":5648,"5660":5648,"5661":5648,"5662":5648,"5663":5648,"5665":5664,"5666":5664,"5667":5664,"5668":5664,"5669":5664,"5670":5664,"5671":5664,"5672":5664,"5673":5664,"5674":5664,"5675":5664,"5676":5664,"5677":5664,"5678":5664,"5679":5664,"5681":5680,"5682":5680,"5683":5680,"5684":5680,"5685":5680,"5686":5680,"5687":5680,"5688":5680,"5689":5680,"5690":5680,"5691":5680,"5692":5680,"5693":5680,"5694":5680,"5695":5680,"5697":5696,"5698":5696,"5699":5696,"5700":5696,"5701":5696,"5702":5696,"5703":5696,"5704":5696,"5705":5696,"5706":5696,"5707":5696,"5708":5696,"5709":5696,"5710":5696,"5711":5696,"5713":5712,"5714":5712,"5715":5712,"5716":5712,"5717":5712,"5718":5712,"5719":5712,"5720":5712,"5721":5712,"5722":5712,"5723":5712,"5724":5712,"5725":5712,"5726":5712,"5727":5712,"5729":5728,"5730":5728,"5731":5728,"5732":5728,"5733":5728,"5734":5728,"5735":5728,"5736":5728,"5737":5728,"5738":5728,"5739":5728,"5740":5728,"5741":5728,"5742":5728,"5743":5728,"5745":5744,"5746":5744,"5747":5744,"5748":5744,"5749":5744,"5750":5744,"5751":5744,"5752":5744,"5753":5744,"5754":5744,"5755":5744,"5756":5744,"5757":5744,"5758":5744,"5759":5744,"5761":5760,"5762":5760,"5763":5760,"5764":5760,"5765":5760,"5766":5760,"5767":5760,"5768":5760,"5769":5760,"5770":5760,"5771":5760,"5772":5760,"5773":5760,"5774":5760,"5775":5760,"5777":5776,"5778":5776,"5779":5776,"5780":5776,"5781":5776,"5782":5776,"5783":5776,"5784":5776,"5785":5776,"5786":5776,"5787":5776,"5788":5776,"5789":5776,"5790":5776,"5791":5776,"5793":5792,"5794":5792,"5795":5792,"5796":5792,"5797":5792,"5798":5792,"5799":5792,"5800":5792,"5801":5792,"5802":5792,"5803":5792,"5804":5792,"5805":5792,"5806":5792,"5807":5792,"5809":5808,"5810":5808,"5811":5808,"5812":5808,"5813":5808,"5814":5808,"5815":5808,"5816":5808,"5817":5808,"5818":5808,"5819":5808,"5820":5808,"5821":5808,"5822":5808,"5823":5808,"5825":5824,"5826":5824,"5827":5824,"5828":5824,"5829":5824,"5830":5824,"5831":5824,"5832":5824,"5833":5824,"5834":5824,"5835":5824,"5836":5824,"5837":5824,"5838":5824,"5839":5824,"5841":5840,"5842":5840,"5843":5840,"5844":5840,"5845":5840,"5846":5840,"5847":5840,"5848":5840,"5849":5840,"5850":5840,"5851":5840,"5852":5840,"5853":5840,"5854":5840,"5855":5840,"5857":5856,"5858":5856,"5859":5856,"5860":5856,"5861":5856,"5862":5856,"5863":5856,"5864":5856,"5865":5856,"5866":5856,"5867":5856,"5868":5856,"5869":5856,"5870":5856,"5871":5856,"5873":5872,"5874":5872,"5875":5872,"5876":5872,"5877":5872,"5878":5872,"5879":5872,"5880":5872,"5881":5872,"5882":5872,"5883":5872,"5884":5872,"5885":5872,"5886":5872,"5887":5872,"5889":5888,"5890":5888,"5891":5888,"5892":5888,"5893":5888,"5894":5888,"5895":5888,"5896":5888,"5897":5888,"5898":5888,"5899":5888,"5900":5888,"5901":5888,"5902":5888,"5903":5888,"5905":5904,"5906":5904,"5907":5904,"5908":5904,"5909":5904,"5910":5904,"5911":5904,"5912":5904,"5913":5904,"5914":5904,"5915":5904,"5916":5904,"5917":5904,"5918":5904,"5919":5904,"5921":5920,"5922":5920,"5923":5920,"5924":5920,"5925":5920,"5926":5920,"5927":5920,"5928":5920,"5929":5920,"5930":5920,"5931":5920,"5932":5920,"5933":5920,"5934":5920,"5935":5920,"5937":5936,"5938":5936,"5939":5936,"5940":5936,"5941":5936,"5942":5936,"5943":5936,"5944":5936,"5945":5936,"5946":5936,"5947":5936,"5948":5936,"5949":5936,"5950":5936,"5951":5936,"5953":5952,"5954":5952,"5955":5952,"5956":5952,"5957":5952,"5958":5952,"5959":5952,"5960":5952,"5961":5952,"5962":5952,"5963":5952,"5964":5952,"5965":5952,"5966":5952,"5967":5952,"5969":5968,"5970":5968,"5971":5968,"5972":5968,"5973":5968,"5974":5968,"5975":5968,"5976":5968,"5977":5968,"5978":5968,"5979":5968,"5980":5968,"5981":5968,"5982":5968,"5983":5968,"5985":5984,"5986":5984,"5987":5984,"5988":5984,"5989":5984,"5990":5984,"5991":5984,"5992":5984,"5993":5984,"5994":5984,"5995":5984,"5996":5984,"5997":5984,"5998":5984,"5999":5984,"6001":6000,"6002":6000,"6003":6000,"6004":6000,"6005":6000,"6006":6000,"6007":6000,"6008":6000,"6009":6000,"6010":6000,"6011":6000,"6012":6000,"6013":6000,"6014":6000,"6015":6000,"6017":6016,"6018":6016,"6019":6016,"6020":6016,"6021":6016,"6022":6016,"6023":6016,"6024":6016,"6025":6016,"6026":6016,"6027":6016,"6028":6016,"6029":6016,"6030":6016,"6031":6016,"6033":6032,"6034":6032,"6035":6032,"6036":6032,"6037":6032,"6038":6032,"6039":6032,"6040":6032,"6041":6032,"6042":6032,"6043":6032,"6044":6032,"6045":6032,"6046":6032,"6047":6032,"6049":6048,"6050":6048,"6051":6048,"6052":6048,"6053":6048,"6054":6048,"6055":6048,"6056":6048,"6057":6048,"6058":6048,"6059":6048,"6060":6048,"6061":6048,"6062":6048,"6063":6048,"6065":6064,"6066":6064,"6067":6064,"6068":6064,"6069":6064,"6070":6064,"6071":6064,"6072":6064,"6073":6064,"6074":6064,"6075":6064,"6076":6064,"6077":6064,"6078":6064,"6079":6064,"6081":6080,"6082":6080,"6083":6080,"6084":6080,"6085":6080,"6086":6080,"6087":6080,"6088":6080,"6089":6080,"6090":6080,"6091":6080,"6092":6080,"6093":6080,"6094":6080,"6095":6080,"6097":6096,"6098":6096,"6099":6096,"6100":6096,"6101":6096,"6102":6096,"6103":6096,"6104":6096,"6105":6096,"6106":6096,"6107":6096,"6108":6096,"6109":6096,"6110":6096,"6111":6096,"6113":6112,"6114":6112,"6115":6112,"6116":6112,"6117":6112,"6118":6112,"6119":6112,"6120":6112,"6121":6112,"6122":6112,"6123":6112,"6124":6112,"6125":6112,"6126":6112,"6127":6112,"6129":6128,"6130":6128,"6131":6128,"6132":6128,"6133":6128,"6134":6128,"6135":6128,"6136":6128,"6137":6128,"6138":6128,"6139":6128,"6140":6128,"6141":6128,"6142":6128,"6143":6128,"6145":6144,"6146":6144,"6147":6144,"6148":6144,"6149":6144,"6150":6144,"6151":6144,"6152":6144,"6153":6144,"6154":6144,"6155":6144,"6156":6144,"6157":6144,"6158":6144,"6159":6144,"6181":6176,"6182":6176,"6183":6176,"6184":6176,"6185":6176,"6186":6176,"6187":6176,"6188":6176,"6189":6176,"6190":6176,"6191":6176,"6197":6192,"6198":6192,"6199":6192,"6205":6192,"6206":6192,"6207":6192,"6213":6208,"6214":6208,"6215":6208,"6221":6208,"6222":6208,"6223":6208,"6229":6208,"6230":6208,"6231":6208,"6237":6208,"6238":6208,"6239":6208,"6273":6248,"6275":6248,"6277":6248,"6279":6248,"6281":6248,"6283":6248,"6285":6248,"6287":6248,"6305":6304,"6306":6304,"6307":6304,"6308":6304,"6309":6304,"6310":6304,"6311":6304,"6312":6304,"6313":6304,"6314":6304,"6315":6304,"6316":6304,"6317":6304,"6318":6304,"6319":6304,"6326":6320,"6327":6320,"6334":6320,"6335":6320,"6342":6336,"6343":6336,"6350":6336,"6351":6336,"6358":6352,"6359":6352,"6366":6352,"6367":6352,"6374":6368,"6375":6368,"6382":6368,"6383":6368,"6390":6384,"6391":6384,"6398":6384,"6399":6384,"6482":6480,"6483":6480,"6484":6480,"6485":6480,"6486":6480,"6487":6480,"6488":6480,"6489":6480,"6490":6480,"6491":6480,"6492":6480,"6493":6480,"6494":6480,"6495":6480,"6498":6496,"6499":6496,"6500":6496,"6501":6496,"6502":6496,"6503":6496,"6504":6496,"6505":6496,"6506":6496,"6507":6496,"6508":6496,"6509":6496,"6510":6496,"6511":6496,"6514":6512,"6515":6512,"6516":6512,"6517":6512,"6518":6512,"6519":6512,"6520":6512,"6521":6512,"6522":6512,"6523":6512,"6524":6512,"6525":6512,"6526":6512,"6527":6512,"6530":6528,"6531":6528,"6532":6528,"6533":6528,"6534":6528,"6535":6528,"6536":6528,"6537":6528,"6538":6528,"6539":6528,"6540":6528,"6541":6528,"6542":6528,"6543":6528,"6546":6544,"6547":6544,"6548":6544,"6549":6544,"6550":6544,"6551":6544,"6552":6544,"6553":6544,"6554":6544,"6555":6544,"6556":6544,"6557":6544,"6558":6544,"6559":6544,"6564":6562,"6565":6562,"6566":6562,"6567":6562,"6568":6562,"6569":6562,"6570":6562,"6571":6562,"6572":6562,"6573":6562,"6574":6562,"6575":6562,"6584":6580,"6585":6580,"6586":6580,"6587":6580,"6588":6580,"6589":6580,"6590":6580,"6591":6580,"6657":6656,"6658":6656,"6659":6656,"6660":6656,"6661":6656,"6662":6656,"6663":6656,"6664":6656,"6665":6656,"6666":6656,"6667":6656,"6668":6656,"6669":6656,"6670":6656,"6671":6656,"6694":6688,"6695":6688,"6702":6688,"6703":6688,"6705":6704,"6706":6704,"6707":6704,"6708":6704,"6709":6704,"6710":6704,"6711":6704,"6713":6704,"6714":6704,"6715":6704,"6716":6704,"6717":6704,"6718":6704,"6719":6704,"6760":6752,"6761":6753,"6762":6754,"6763":6755,"6764":6756,"6765":6757,"6766":6758,"6767":6759,"6776":6768,"6777":6769,"6778":6770,"6779":6771,"6780":6772,"6792":6787,"6793":6787,"6794":6787,"6795":6787,"6796":6787,"6797":6787,"6798":6787,"6799":6787,"6808":6803,"6809":6803,"6810":6803,"6811":6803,"6812":6803,"6813":6803,"6814":6803,"6815":6803,"6824":6819,"6825":6819,"6826":6819,"6827":6819,"6828":6819,"6829":6819,"6830":6819,"6831":6819,"6840":6835,"6841":6835,"6842":6835,"6843":6835,"6844":6835,"6845":6835,"6846":6835,"6847":6835,"6856":6851,"6857":6851,"6858":6851,"6859":6851,"6860":6851,"6861":6851,"6862":6851,"6863":6851,"6872":6867,"6873":6867,"6874":6867,"6875":6867,"6876":6867,"6877":6867,"6878":6867,"6879":6867,"6888":6883,"6889":6883,"6890":6883,"6891":6883,"6892":6883,"6893":6883,"6894":6883,"6895":6883,"6904":6899,"6905":6899,"6906":6899,"6907":6899,"6908":6899,"6909":6899,"6910":6899,"6911":6899,"6920":6915,"6921":6915,"6922":6915,"6923":6915,"6924":6915,"6925":6915,"6926":6915,"6927":6915,"6936":6931,"6937":6931,"6938":6931,"6939":6931,"6940":6931,"6941":6931,"6942":6931,"6943":6931,"6952":6947,"6953":6947,"6954":6947,"6955":6947,"6956":6947,"6957":6947,"6958":6947,"6959":6947,"6968":6963,"6969":6963,"6970":6963,"6971":6963,"6972":6963,"6973":6963,"6974":6963,"6975":6963,"6992":6994,"6993":6994,"6998":6994,"6999":6994,"7000":6994,"7001":6994,"7002":6994,"7003":6994,"7004":6994,"7005":6994,"7006":6994,"7007":6994,"7009":7008,"7010":7008,"7011":7008,"7012":7008,"7013":7008,"7014":7008,"7015":7008,"7016":7008,"7017":7008,"7018":7008,"7019":7008,"7020":7008,"7021":7008,"7022":7008,"7023":7008,"7032":7027,"7033":7027,"7034":7027,"7035":7027,"7036":7027,"7037":7027,"7038":7027,"7039":7027,"7048":7043,"7049":7043,"7050":7043,"7051":7043,"7052":7043,"7053":7043,"7054":7043,"7055":7043,"7072":7074,"7073":7074,"7078":7074,"7079":7074,"7080":7074,"7081":7074,"7082":7074,"7083":7074,"7084":7074,"7085":7074,"7086":7074,"7087":7074,"7104":7106,"7105":7106,"7110":7106,"7111":7106,"7112":7106,"7113":7106,"7114":7106,"7115":7106,"7116":7106,"7117":7106,"7118":7106,"7119":7106,"7136":7138,"7137":7138,"7142":7138,"7143":7138,"7144":7138,"7145":7138,"7146":7138,"7147":7138,"7148":7138,"7149":7138,"7150":7138,"7151":7138,"7168":7170,"7169":7170,"7174":7170,"7175":7170,"7176":7170,"7177":7170,"7178":7170,"7179":7170,"7180":7170,"7181":7170,"7182":7170,"7183":7170,"7216":7218,"7217":7218,"7222":7218,"7223":7218,"7224":7218,"7225":7218,"7226":7218,"7227":7218,"7228":7218,"7229":7218,"7230":7218,"7231":7218,"7248":7250,"7249":7250,"7254":7250,"7255":7250,"7256":7250,"7257":7250,"7258":7250,"7259":7250,"7260":7250,"7261":7250,"7262":7250,"7263":7250,"7264":7250,"7265":7250,"7270":7250,"7271":7250,"7272":7250,"7273":7250,"7274":7250,"7275":7250,"7276":7250,"7277":7250,"7278":7250,"7279":7250,"7297":7296,"7298":7296,"7299":7296,"7300":7296,"7301":7296,"7302":7296,"7303":7296,"7304":7296,"7305":7296,"7306":7296,"7307":7296,"7308":7296,"7309":7296,"7310":7296,"7311":7296,"7334":7328,"7335":7328,"7342":7328,"7343":7328,"7348":7346,"7349":7346,"7350":7346,"7351":7346,"7352":7346,"7353":7346,"7354":7346,"7355":7346,"7356":7346,"7357":7346,"7358":7346,"7359":7346,"7396":7392,"7397":7392,"7398":7392,"7399":7392,"7400":7392,"7401":7392,"7402":7392,"7403":7392,"7404":7392,"7405":7392,"7406":7392,"7407":7392,"7410":7408,"7411":7408,"7412":7408,"7413":7408,"7414":7408,"7415":7408,"7416":7408,"7417":7408,"7418":7408,"7419":7408,"7420":7408,"7421":7408,"7422":7408,"7423":7408,"7504":7218,"7505":7218,"7510":7218,"7511":7218,"7512":7218,"7513":7218,"7514":7218,"7515":7218,"7516":7218,"7517":7218,"7518":7218,"7519":7218}} \ No newline at end of file From e5149756a8de7175594cea4dca072397c11b9751 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Nov 2021 00:06:09 +0000 Subject: [PATCH 3205/3224] WorldTimings: fixed merge error introduced by 3bf87378ef24eec8845bb048a6916f188d9b1220 --- src/world/WorldTimings.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/world/WorldTimings.php b/src/world/WorldTimings.php index 2ace793179..ac060e9a3d 100644 --- a/src/world/WorldTimings.php +++ b/src/world/WorldTimings.php @@ -64,14 +64,14 @@ class WorldTimings{ $this->entityTick = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Tick Entities"); Timings::init(); //make sure the timers we want are available - $this->syncChunkSend = new TimingsHandler("** " . $name . "Player Send Chunks", Timings::$playerChunkSend); - $this->syncChunkSendPrepare = new TimingsHandler("** " . $name . "Player Send Chunk Prepare", Timings::$playerChunkSend); + $this->syncChunkSend = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Player Send Chunks", Timings::$playerChunkSend); + $this->syncChunkSendPrepare = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Player Send Chunk Prepare", Timings::$playerChunkSend); - $this->syncChunkLoad = new TimingsHandler("** " . $name . "Chunk Load", Timings::$worldLoad); - $this->syncChunkLoadData = new TimingsHandler("** " . $name . "Chunk Load - Data"); - $this->syncChunkLoadEntities = new TimingsHandler("** " . $name . "Chunk Load - Entities"); - $this->syncChunkLoadTileEntities = new TimingsHandler("** " . $name . "Chunk Load - TileEntities"); - $this->syncChunkSave = new TimingsHandler("** " . $name . "Chunk Save", Timings::$worldSave); + $this->syncChunkLoad = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Chunk Load", Timings::$worldLoad); + $this->syncChunkLoadData = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Chunk Load - Data"); + $this->syncChunkLoadEntities = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Chunk Load - Entities"); + $this->syncChunkLoadTileEntities = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Chunk Load - TileEntities"); + $this->syncChunkSave = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Chunk Save", Timings::$worldSave); $this->doTick = new TimingsHandler($name . "World Tick"); } From 1f9400f9011546ab914090853069aaa76192a722 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Nov 2021 01:12:30 +0000 Subject: [PATCH 3206/3224] World: automatically remap invalid blockstates on chunk load this fixes a wide range of blocks with invalid blockstates becoming update! blocks on the client. The most common occurrence of this was air with nonzero metadata left behind by world editors which set blockIDs but not block metadata. This caused large ghost structures of update! blocks to appear from nowhere. The performance impact of this is very minimal (20 microseconds per chunk load in timings, compared to average 660 microseconds to load tiles). --- src/block/BlockFactory.php | 16 ++++++++++++++++ src/world/World.php | 21 +++++++++++++++++++++ src/world/WorldTimings.php | 2 ++ 3 files changed, 39 insertions(+) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index fd252f7892..38e26f6b7c 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -75,6 +75,12 @@ class BlockFactory{ */ private $fullList; + /** + * @var \SplFixedArray|int[] + * @phpstan-var \SplFixedArray + */ + private \SplFixedArray $mappedStateIds; + /** * @var \SplFixedArray|int[] * @phpstan-var \SplFixedArray @@ -98,6 +104,7 @@ class BlockFactory{ public function __construct(){ $this->fullList = new \SplFixedArray(1024 << Block::INTERNAL_METADATA_BITS); + $this->mappedStateIds = new \SplFixedArray(1024 << Block::INTERNAL_METADATA_BITS); $this->light = \SplFixedArray::fromArray(array_fill(0, 1024 << Block::INTERNAL_METADATA_BITS, 0)); $this->lightFilter = \SplFixedArray::fromArray(array_fill(0, 1024 << Block::INTERNAL_METADATA_BITS, 1)); @@ -948,6 +955,7 @@ class BlockFactory{ private function fillStaticArrays(int $index, Block $block) : void{ $this->fullList[$index] = $block; + $this->mappedStateIds[$index] = $block->getFullId(); $this->light[$index] = $block->getLightLevel(); $this->lightFilter[$index] = min(15, $block->getLightFilter() + 1); //opacity plus 1 standard light filter $this->blocksDirectSkyLight[$index] = $block->blocksDirectSkyLight(); @@ -997,4 +1005,12 @@ class BlockFactory{ public function getAllKnownStates() : array{ return array_filter($this->fullList->toArray(), function(?Block $v) : bool{ return $v !== null; }); } + + /** + * Returns the ID of the state mapped to the given state ID. + * Used to correct invalid blockstates found in loaded chunks. + */ + public function getMappedStateId(int $fullState) : int{ + return $this->mappedStateIds[$fullState] ?? $fullState; + } } diff --git a/src/world/World.php b/src/world/World.php index 9549980eb0..37236de221 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -2466,6 +2466,27 @@ class World implements ChunkManager{ private function initChunk(int $chunkX, int $chunkZ, ChunkData $chunkData) : void{ $logger = new \PrefixedLogger($this->logger, "Loading chunk $chunkX $chunkZ"); + + $this->timings->syncChunkLoadFixInvalidBlocks->startTiming(); + $blockFactory = BlockFactory::getInstance(); + $invalidBlocks = 0; + foreach($chunkData->getChunk()->getSubChunks() as $subChunk){ + foreach($subChunk->getBlockLayers() as $blockLayer){ + foreach($blockLayer->getPalette() as $blockStateId){ + $mappedStateId = $blockFactory->getMappedStateId($blockStateId); + if($mappedStateId !== $blockStateId){ + $blockLayer->replaceAll($blockStateId, $mappedStateId); + $invalidBlocks++; + } + } + } + } + if($invalidBlocks > 0){ + $logger->debug("Fixed $invalidBlocks invalid blockstates"); + $chunkData->getChunk()->setTerrainDirtyFlag(Chunk::DIRTY_FLAG_BLOCKS, true); + } + $this->timings->syncChunkLoadFixInvalidBlocks->stopTiming(); + if(count($chunkData->getEntityNBT()) !== 0){ $this->timings->syncChunkLoadEntities->startTiming(); $entityFactory = EntityFactory::getInstance(); diff --git a/src/world/WorldTimings.php b/src/world/WorldTimings.php index ac060e9a3d..874a5f5fdd 100644 --- a/src/world/WorldTimings.php +++ b/src/world/WorldTimings.php @@ -45,6 +45,7 @@ class WorldTimings{ public TimingsHandler $syncChunkLoad; public TimingsHandler $syncChunkLoadData; + public TimingsHandler $syncChunkLoadFixInvalidBlocks; public TimingsHandler $syncChunkLoadEntities; public TimingsHandler $syncChunkLoadTileEntities; public TimingsHandler $syncChunkSave; @@ -69,6 +70,7 @@ class WorldTimings{ $this->syncChunkLoad = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Chunk Load", Timings::$worldLoad); $this->syncChunkLoadData = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Chunk Load - Data"); + $this->syncChunkLoadFixInvalidBlocks = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Chunk Load - Fix Invalid Blocks"); $this->syncChunkLoadEntities = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Chunk Load - Entities"); $this->syncChunkLoadTileEntities = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Chunk Load - TileEntities"); $this->syncChunkSave = new TimingsHandler(Timings::INCLUDED_BY_OTHER_TIMINGS_PREFIX . $name . "Chunk Save", Timings::$worldSave); From cc23e0b7a151cf6b3fda2836b717321f19003cb6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Nov 2021 03:52:32 +0000 Subject: [PATCH 3207/3224] Updated DevTools submodule to pmmp/DevTools@6af57741e67a928e2782cebe8dd422044d16dc04 --- tests/plugins/DevTools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/plugins/DevTools b/tests/plugins/DevTools index db184c2563..6af57741e6 160000 --- a/tests/plugins/DevTools +++ b/tests/plugins/DevTools @@ -1 +1 @@ -Subproject commit db184c25636b1f984c6539fd4b1729b0b64b35d6 +Subproject commit 6af57741e67a928e2782cebe8dd422044d16dc04 From 95401937664e4dea59f1bdee63811258f2a794e9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Nov 2021 03:54:30 +0000 Subject: [PATCH 3208/3224] Fixed everything lighting on fire --- composer.json | 2 +- tests/travis.sh | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 4c71c4e130..b42e95a74e 100644 --- a/composer.json +++ b/composer.json @@ -79,7 +79,7 @@ "sort-packages": true }, "scripts": { - "make-devtools": "@php -dphar.readonly=0 tests/plugins/DevTools/src/DevTools/ConsoleScript.php --make tests/plugins/DevTools --out plugins/DevTools.phar", + "make-devtools": "@php -dphar.readonly=0 tests/plugins/DevTools/src/ConsoleScript.php --make tests/plugins/DevTools --out plugins/DevTools.phar", "make-server": [ "@composer install --no-dev --classmap-authoritative --ignore-platform-reqs", "@php -dphar.readonly=0 build/server-phar.php" diff --git a/tests/travis.sh b/tests/travis.sh index e16a283333..714e024257 100755 --- a/tests/travis.sh +++ b/tests/travis.sh @@ -19,9 +19,7 @@ rm PocketMine-MP.phar 2> /dev/null mkdir "$DATA_DIR" mkdir "$PLUGINS_DIR" -cd tests/plugins/DevTools -php -dphar.readonly=0 ./src/DevTools/ConsoleScript.php --make ./ --relative ./ --out "$PLUGINS_DIR/DevTools.phar" -cd ../../.. +composer make-devtools composer make-server if [ -f PocketMine-MP.phar ]; then From 932a88764c18967c2ba544562527707d3d7a1ab8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Nov 2021 04:07:25 +0000 Subject: [PATCH 3209/3224] composer commands suck --- tests/travis.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/travis.sh b/tests/travis.sh index 714e024257..094f659053 100755 --- a/tests/travis.sh +++ b/tests/travis.sh @@ -19,7 +19,9 @@ rm PocketMine-MP.phar 2> /dev/null mkdir "$DATA_DIR" mkdir "$PLUGINS_DIR" -composer make-devtools +cd tests/plugins/DevTools +php -dphar.readonly=0 ./src/ConsoleScript.php --make ./ --relative ./ --out "$PLUGINS_DIR/DevTools.phar" +cd ../../.. composer make-server if [ -f PocketMine-MP.phar ]; then From e2815eed60861564b678de5f6e43c16eb98f3da9 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Nov 2021 20:07:58 +0000 Subject: [PATCH 3210/3224] BlockFactory: remap a bunch more invalid states --- src/block/BlockFactory.php | 239 +++++++++++------- .../block_factory_consistency_check.json | 2 +- 2 files changed, 146 insertions(+), 95 deletions(-) diff --git a/src/block/BlockFactory.php b/src/block/BlockFactory.php index 38e26f6b7c..fd98293c5f 100644 --- a/src/block/BlockFactory.php +++ b/src/block/BlockFactory.php @@ -151,8 +151,6 @@ class BlockFactory{ $cobblestoneBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); $this->registerAllMeta($cobblestone = new Opaque(new BID(Ids::COBBLESTONE, 0), "Cobblestone", $cobblestoneBreakInfo)); - $infestedStoneBreakInfo = new BlockBreakInfo(0.75); - $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_COBBLESTONE), "Infested Cobblestone", $infestedStoneBreakInfo, $cobblestone)); $this->registerAllMeta(new Opaque(new BID(Ids::MOSSY_COBBLESTONE, 0), "Mossy Cobblestone", $cobblestoneBreakInfo)); $this->registerAllMeta(new Stair(new BID(Ids::COBBLESTONE_STAIRS, 0), "Cobblestone Stairs", $cobblestoneBreakInfo)); $this->registerAllMeta(new Stair(new BID(Ids::MOSSY_COBBLESTONE_STAIRS, 0), "Mossy Cobblestone Stairs", $cobblestoneBreakInfo)); @@ -168,12 +166,14 @@ class BlockFactory{ $this->registerAllMeta(new Opaque(new BID(Ids::DIAMOND_BLOCK, 0), "Diamond Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); $this->registerAllMeta(new DiamondOre(new BID(Ids::DIAMOND_ORE, 0), "Diamond Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel()))); $this->registerAllMeta(new Dirt(new BID(Ids::DIRT, 0), "Dirt", new BlockBreakInfo(0.5, BlockToolType::SHOVEL))); - $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_SUNFLOWER), "Sunflower", BlockBreakInfo::instant())); - $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LILAC), "Lilac", BlockBreakInfo::instant())); - $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_ROSE_BUSH), "Rose Bush", BlockBreakInfo::instant())); - $this->register(new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_PEONY), "Peony", BlockBreakInfo::instant())); - $this->register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_TALLGRASS), "Double Tallgrass", BlockBreakInfo::instant(BlockToolType::SHEARS, 1))); - $this->register(new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LARGE_FERN), "Large Fern", BlockBreakInfo::instant(BlockToolType::SHEARS, 1))); + $this->registerAllMeta( + new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_SUNFLOWER), "Sunflower", BlockBreakInfo::instant()), + new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LILAC), "Lilac", BlockBreakInfo::instant()), + new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_ROSE_BUSH), "Rose Bush", BlockBreakInfo::instant()), + new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_PEONY), "Peony", BlockBreakInfo::instant()), + new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_TALLGRASS), "Double Tallgrass", BlockBreakInfo::instant(BlockToolType::SHEARS, 1)), + new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LARGE_FERN), "Large Fern", BlockBreakInfo::instant(BlockToolType::SHEARS, 1)), + ); $this->registerAllMeta(new DragonEgg(new BID(Ids::DRAGON_EGG, 0), "Dragon Egg", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); $this->registerAllMeta(new DriedKelp(new BID(Ids::DRIED_KELP_BLOCK, 0), "Dried Kelp Block", new BlockBreakInfo(0.5, BlockToolType::NONE, 0, 12.5))); $this->registerAllMeta(new Opaque(new BID(Ids::EMERALD_BLOCK, 0), "Emerald Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0))); @@ -192,17 +192,19 @@ class BlockFactory{ $this->registerAllMeta(new Fire(new BID(Ids::FIRE, 0), "Fire Block", BlockBreakInfo::instant())); $this->registerAllMeta(new FletchingTable(new BID(Ids::FLETCHING_TABLE, 0), "Fletching Table", new BlockBreakInfo(2.5, BlockToolType::AXE, 0, 2.5))); $this->registerAllMeta(new Flower(new BID(Ids::DANDELION, 0), "Dandelion", BlockBreakInfo::instant())); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ALLIUM), "Allium", BlockBreakInfo::instant())); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_AZURE_BLUET), "Azure Bluet", BlockBreakInfo::instant())); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_BLUE_ORCHID), "Blue Orchid", BlockBreakInfo::instant())); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_CORNFLOWER), "Cornflower", BlockBreakInfo::instant())); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_LILY_OF_THE_VALLEY), "Lily of the Valley", BlockBreakInfo::instant())); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ORANGE_TULIP), "Orange Tulip", BlockBreakInfo::instant())); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_OXEYE_DAISY), "Oxeye Daisy", BlockBreakInfo::instant())); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_PINK_TULIP), "Pink Tulip", BlockBreakInfo::instant())); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_POPPY), "Poppy", BlockBreakInfo::instant())); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_RED_TULIP), "Red Tulip", BlockBreakInfo::instant())); - $this->register(new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_WHITE_TULIP), "White Tulip", BlockBreakInfo::instant())); + $this->registerAllMeta( + new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_POPPY), "Poppy", BlockBreakInfo::instant()), + new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ALLIUM), "Allium", BlockBreakInfo::instant()), + new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_AZURE_BLUET), "Azure Bluet", BlockBreakInfo::instant()), + new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_BLUE_ORCHID), "Blue Orchid", BlockBreakInfo::instant()), + new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_CORNFLOWER), "Cornflower", BlockBreakInfo::instant()), + new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_LILY_OF_THE_VALLEY), "Lily of the Valley", BlockBreakInfo::instant()), + new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ORANGE_TULIP), "Orange Tulip", BlockBreakInfo::instant()), + new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_OXEYE_DAISY), "Oxeye Daisy", BlockBreakInfo::instant()), + new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_PINK_TULIP), "Pink Tulip", BlockBreakInfo::instant()), + new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_RED_TULIP), "Red Tulip", BlockBreakInfo::instant()), + new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_WHITE_TULIP), "White Tulip", BlockBreakInfo::instant()), + ); $this->registerAllMeta(new FlowerPot(new BID(Ids::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, TileFlowerPot::class), "Flower Pot", BlockBreakInfo::instant())); $this->registerAllMeta(new FrostedIce(new BID(Ids::FROSTED_ICE, 0), "Frosted Ice", new BlockBreakInfo(2.5, BlockToolType::PICKAXE))); $this->registerAllMeta(new Furnace(new BIDFlattened(Ids::FURNACE, [Ids::LIT_FURNACE], 0, null, TileNormalFurnace::class), "Furnace", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); @@ -279,11 +281,13 @@ class BlockFactory{ $this->registerAllMeta(new PoweredRail(new BID(Ids::GOLDEN_RAIL, 0), "Powered Rail", $railBreakInfo)); $prismarineBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - $this->register(new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_BRICKS), "Prismarine Bricks", $prismarineBreakInfo)); + $this->registerAllMeta( + new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_NORMAL), "Prismarine", $prismarineBreakInfo), + new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_DARK), "Dark Prismarine", $prismarineBreakInfo), + new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_BRICKS), "Prismarine Bricks", $prismarineBreakInfo) + ); $this->registerAllMeta(new Stair(new BID(Ids::PRISMARINE_BRICKS_STAIRS, 0), "Prismarine Bricks Stairs", $prismarineBreakInfo)); - $this->register(new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_DARK), "Dark Prismarine", $prismarineBreakInfo)); $this->registerAllMeta(new Stair(new BID(Ids::DARK_PRISMARINE_STAIRS, 0), "Dark Prismarine Stairs", $prismarineBreakInfo)); - $this->register(new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_NORMAL), "Prismarine", $prismarineBreakInfo)); $this->registerAllMeta(new Stair(new BID(Ids::PRISMARINE_STAIRS, 0), "Prismarine Stairs", $prismarineBreakInfo)); $pumpkinBreakInfo = new BlockBreakInfo(1.0, BlockToolType::AXE); @@ -294,16 +298,20 @@ class BlockFactory{ $this->registerAllMeta(new PumpkinStem(new BID(Ids::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem", BlockBreakInfo::instant())); $purpurBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - $this->register(new Opaque(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_NORMAL), "Purpur Block", $purpurBreakInfo)); - $this->register(new SimplePillar(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_PILLAR), "Purpur Pillar", $purpurBreakInfo)); + $this->registerAllMeta( + new Opaque(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_NORMAL), "Purpur Block", $purpurBreakInfo), + new SimplePillar(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_PILLAR), "Purpur Pillar", $purpurBreakInfo) + ); $this->registerAllMeta(new Stair(new BID(Ids::PURPUR_STAIRS, 0), "Purpur Stairs", $purpurBreakInfo)); $quartzBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()); - $this->register(new Opaque(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_NORMAL), "Quartz Block", $quartzBreakInfo)); + $this->registerAllMeta( + new Opaque(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_NORMAL), "Quartz Block", $quartzBreakInfo), + new SimplePillar(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_CHISELED), "Chiseled Quartz Block", $quartzBreakInfo), + new SimplePillar(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_PILLAR), "Quartz Pillar", $quartzBreakInfo), + new Opaque(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_SMOOTH), "Smooth Quartz Block", $quartzBreakInfo) //TODO: we may need to account for the fact this previously incorrectly had axis + ); $this->registerAllMeta(new Stair(new BID(Ids::QUARTZ_STAIRS, 0), "Quartz Stairs", $quartzBreakInfo)); - $this->register(new SimplePillar(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_CHISELED), "Chiseled Quartz Block", $quartzBreakInfo)); - $this->register(new SimplePillar(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_PILLAR), "Quartz Pillar", $quartzBreakInfo)); - $this->register(new Opaque(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_SMOOTH), "Smooth Quartz Block", $quartzBreakInfo)); //TODO: this has axis rotation in 1.9, unsure if a bug (https://bugs.mojang.com/browse/MCPE-39074) $this->registerAllMeta(new Stair(new BID(Ids::SMOOTH_QUARTZ_STAIRS, 0), "Smooth Quartz Stairs", $quartzBreakInfo)); $this->registerAllMeta(new Rail(new BID(Ids::RAIL, 0), "Rail", $railBreakInfo)); @@ -318,8 +326,10 @@ class BlockFactory{ $this->registerAllMeta(new Reserved6(new BID(Ids::RESERVED6, 0), "reserved6", BlockBreakInfo::instant())); $sandBreakInfo = new BlockBreakInfo(0.5, BlockToolType::SHOVEL); - $this->register(new Sand(new BID(Ids::SAND, 0), "Sand", $sandBreakInfo)); - $this->register(new Sand(new BID(Ids::SAND, 1), "Red Sand", $sandBreakInfo)); + $this->registerAllMeta( + new Sand(new BID(Ids::SAND, 0), "Sand", $sandBreakInfo), + new Sand(new BID(Ids::SAND, 1), "Red Sand", $sandBreakInfo) + ); $this->registerAllMeta(new SeaLantern(new BID(Ids::SEALANTERN, 0), "Sea Lantern", new BlockBreakInfo(0.3))); $this->registerAllMeta(new SeaPickle(new BID(Ids::SEA_PICKLE, 0), "Sea Pickle", BlockBreakInfo::instant())); $this->registerAllMeta(new Skull(new BID(Ids::MOB_HEAD_BLOCK, 0, ItemIds::SKULL, TileSkull::class), "Mob Head", new BlockBreakInfo(1.0))); @@ -332,40 +342,48 @@ class BlockFactory{ $this->registerAllMeta(new ShulkerBox(new BID(Ids::UNDYED_SHULKER_BOX, 0, null, TileShulkerBox::class), "Shulker Box", $shulkerBoxBreakInfo)); $stoneBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - $this->register($stone = new class(new BID(Ids::STONE, Meta::STONE_NORMAL), "Stone", $stoneBreakInfo) extends Opaque{ - public function getDropsForCompatibleTool(Item $item) : array{ - return [VanillaBlocks::COBBLESTONE()->asItem()]; - } + $this->registerAllMeta( + $stone = new class(new BID(Ids::STONE, Meta::STONE_NORMAL), "Stone", $stoneBreakInfo) extends Opaque{ + public function getDropsForCompatibleTool(Item $item) : array{ + return [VanillaBlocks::COBBLESTONE()->asItem()]; + } - public function isAffectedBySilkTouch() : bool{ - return true; - } - }); - $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE), "Infested Stone", $infestedStoneBreakInfo, $stone)); + public function isAffectedBySilkTouch() : bool{ + return true; + } + }, + new Opaque(new BID(Ids::STONE, Meta::STONE_ANDESITE), "Andesite", $stoneBreakInfo), + new Opaque(new BID(Ids::STONE, Meta::STONE_DIORITE), "Diorite", $stoneBreakInfo), + new Opaque(new BID(Ids::STONE, Meta::STONE_GRANITE), "Granite", $stoneBreakInfo), + new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_ANDESITE), "Polished Andesite", $stoneBreakInfo), + new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_DIORITE), "Polished Diorite", $stoneBreakInfo), + new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_GRANITE), "Polished Granite", $stoneBreakInfo) + ); + $this->registerAllMeta( + $stoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_NORMAL), "Stone Bricks", $stoneBreakInfo), + $mossyStoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_MOSSY), "Mossy Stone Bricks", $stoneBreakInfo), + $crackedStoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CRACKED), "Cracked Stone Bricks", $stoneBreakInfo), + $chiseledStoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CHISELED), "Chiseled Stone Bricks", $stoneBreakInfo) + ); + $infestedStoneBreakInfo = new BlockBreakInfo(0.75); + $this->registerAllMeta( + new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE), "Infested Stone", $infestedStoneBreakInfo, $stone), + new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK), "Infested Stone Brick", $infestedStoneBreakInfo, $stoneBrick), + new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_COBBLESTONE), "Infested Cobblestone", $infestedStoneBreakInfo, $cobblestone), + new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_MOSSY), "Infested Mossy Stone Brick", $infestedStoneBreakInfo, $mossyStoneBrick), + new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CRACKED), "Infested Cracked Stone Brick", $infestedStoneBreakInfo, $crackedStoneBrick), + new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CHISELED), "Infested Chiseled Stone Brick", $infestedStoneBreakInfo, $chiseledStoneBrick) + ); $this->registerAllMeta(new Stair(new BID(Ids::NORMAL_STONE_STAIRS, 0), "Stone Stairs", $stoneBreakInfo)); $this->registerAllMeta(new Opaque(new BID(Ids::SMOOTH_STONE, 0), "Smooth Stone", $stoneBreakInfo)); - $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_ANDESITE), "Andesite", $stoneBreakInfo)); $this->registerAllMeta(new Stair(new BID(Ids::ANDESITE_STAIRS, 0), "Andesite Stairs", $stoneBreakInfo)); - $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_DIORITE), "Diorite", $stoneBreakInfo)); $this->registerAllMeta(new Stair(new BID(Ids::DIORITE_STAIRS, 0), "Diorite Stairs", $stoneBreakInfo)); - $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_GRANITE), "Granite", $stoneBreakInfo)); $this->registerAllMeta(new Stair(new BID(Ids::GRANITE_STAIRS, 0), "Granite Stairs", $stoneBreakInfo)); - $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_ANDESITE), "Polished Andesite", $stoneBreakInfo)); $this->registerAllMeta(new Stair(new BID(Ids::POLISHED_ANDESITE_STAIRS, 0), "Polished Andesite Stairs", $stoneBreakInfo)); - $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_DIORITE), "Polished Diorite", $stoneBreakInfo)); $this->registerAllMeta(new Stair(new BID(Ids::POLISHED_DIORITE_STAIRS, 0), "Polished Diorite Stairs", $stoneBreakInfo)); - $this->register(new Opaque(new BID(Ids::STONE, Meta::STONE_POLISHED_GRANITE), "Polished Granite", $stoneBreakInfo)); $this->registerAllMeta(new Stair(new BID(Ids::POLISHED_GRANITE_STAIRS, 0), "Polished Granite Stairs", $stoneBreakInfo)); $this->registerAllMeta(new Stair(new BID(Ids::STONE_BRICK_STAIRS, 0), "Stone Brick Stairs", $stoneBreakInfo)); - $this->register($chiseledStoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CHISELED), "Chiseled Stone Bricks", $stoneBreakInfo)); - $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CHISELED), "Infested Chiseled Stone Brick", $infestedStoneBreakInfo, $chiseledStoneBrick)); - $this->register($crackedStoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CRACKED), "Cracked Stone Bricks", $stoneBreakInfo)); - $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_CRACKED), "Infested Cracked Stone Brick", $infestedStoneBreakInfo, $crackedStoneBrick)); - $this->register($mossyStoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_MOSSY), "Mossy Stone Bricks", $stoneBreakInfo)); - $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK_MOSSY), "Infested Mossy Stone Brick", $infestedStoneBreakInfo, $mossyStoneBrick)); $this->registerAllMeta(new Stair(new BID(Ids::MOSSY_STONE_BRICK_STAIRS, 0), "Mossy Stone Brick Stairs", $stoneBreakInfo)); - $this->register($stoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_NORMAL), "Stone Bricks", $stoneBreakInfo)); - $this->register(new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK), "Infested Stone Brick", $infestedStoneBreakInfo, $stoneBrick)); $this->registerAllMeta(new StoneButton(new BID(Ids::STONE_BUTTON, 0), "Stone Button", new BlockBreakInfo(0.5, BlockToolType::PICKAXE))); $this->registerAllMeta(new StonePressurePlate(new BID(Ids::STONE_PRESSURE_PLATE, 0), "Stone Pressure Plate", new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()))); @@ -404,16 +422,18 @@ class BlockFactory{ $this->registerAllMeta(new Sugarcane(new BID(Ids::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane", BlockBreakInfo::instant())); $this->registerAllMeta(new SweetBerryBush(new BID(Ids::SWEET_BERRY_BUSH, 0, ItemIds::SWEET_BERRIES), "Sweet Berry Bush", BlockBreakInfo::instant())); $this->registerAllMeta(new TNT(new BID(Ids::TNT, 0), "TNT", BlockBreakInfo::instant())); - - $fern = new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_FERN), "Fern", BlockBreakInfo::instant(BlockToolType::SHEARS, 1)); - $this->register($fern); - $this->remap(Ids::TALLGRASS, 0, $fern); - $this->remap(Ids::TALLGRASS, 3, $fern); - $this->register(new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_NORMAL), "Tall Grass", BlockBreakInfo::instant(BlockToolType::SHEARS, 1))); - $this->register(new Torch(new BID(Ids::COLORED_TORCH_BP, 0), "Blue Torch", BlockBreakInfo::instant())); - $this->register(new Torch(new BID(Ids::COLORED_TORCH_BP, 8), "Purple Torch", BlockBreakInfo::instant())); - $this->register(new Torch(new BID(Ids::COLORED_TORCH_RG, 0), "Red Torch", BlockBreakInfo::instant())); - $this->register(new Torch(new BID(Ids::COLORED_TORCH_RG, 8), "Green Torch", BlockBreakInfo::instant())); + $this->registerAllMeta( + new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_FERN), "Fern", BlockBreakInfo::instant(BlockToolType::SHEARS, 1)), + new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_NORMAL), "Tall Grass", BlockBreakInfo::instant(BlockToolType::SHEARS, 1)) + ); + $this->registerAllMeta( + new Torch(new BID(Ids::COLORED_TORCH_BP, 0), "Blue Torch", BlockBreakInfo::instant()), + new Torch(new BID(Ids::COLORED_TORCH_BP, 8), "Purple Torch", BlockBreakInfo::instant()) + ); + $this->registerAllMeta( + new Torch(new BID(Ids::COLORED_TORCH_RG, 0), "Red Torch", BlockBreakInfo::instant()), + new Torch(new BID(Ids::COLORED_TORCH_RG, 8), "Green Torch", BlockBreakInfo::instant()) + ); $this->registerAllMeta(new Torch(new BID(Ids::TORCH, 0), "Torch", BlockBreakInfo::instant())); $this->registerAllMeta(new TrappedChest(new BID(Ids::TRAPPED_CHEST, 0, null, TileChest::class), "Trapped Chest", $chestBreakInfo)); $this->registerAllMeta(new Tripwire(new BID(Ids::TRIPWIRE, 0, ItemIds::STRING), "Tripwire", BlockBreakInfo::instant())); @@ -435,22 +455,29 @@ class BlockFactory{ $woodenDoorBreakInfo = new BlockBreakInfo(3.0, BlockToolType::AXE, 0, 15.0); $woodenButtonBreakInfo = new BlockBreakInfo(0.5, BlockToolType::AXE); $woodenPressurePlateBreakInfo = new BlockBreakInfo(0.5, BlockToolType::AXE); + + $planks = []; + $saplings = []; + $fences = []; + $leaves = []; + $allSidedLogs = []; foreach(TreeType::getAll() as $treeType){ $magicNumber = $treeType->getMagicNumber(); $name = $treeType->getDisplayName(); - $this->register(new Planks(new BID(Ids::PLANKS, $magicNumber), $name . " Planks", $planksBreakInfo)); - $this->register(new Sapling(new BID(Ids::SAPLING, $magicNumber), $name . " Sapling", BlockBreakInfo::instant(), $treeType)); - $this->register(new WoodenFence(new BID(Ids::FENCE, $magicNumber), $name . " Fence", $planksBreakInfo)); + $planks[] = new Planks(new BID(Ids::PLANKS, $magicNumber), $name . " Planks", $planksBreakInfo); + $saplings[] = new Sapling(new BID(Ids::SAPLING, $magicNumber), $name . " Sapling", BlockBreakInfo::instant(), $treeType); + $fences[] = new WoodenFence(new BID(Ids::FENCE, $magicNumber), $name . " Fence", $planksBreakInfo); $this->registerSlabWithDoubleHighBitsRemapping(new WoodenSlab(new BIDFlattened(Ids::WOODEN_SLAB, [Ids::DOUBLE_WOODEN_SLAB], $magicNumber), $name, $planksBreakInfo)); //TODO: find a better way to deal with this split - $this->register(new Leaves(new BID($magicNumber >= 4 ? Ids::LEAVES2 : Ids::LEAVES, $magicNumber & 0x03), $name . " Leaves", $leavesBreakInfo, $treeType)); - $this->register(new Log(new BID($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, $magicNumber & 0x03), $name . " Log", $logBreakInfo, $treeType, false)); + $leaves[] = new Leaves(new BID($magicNumber >= 4 ? Ids::LEAVES2 : Ids::LEAVES, $magicNumber & 0x03), $name . " Leaves", $leavesBreakInfo, $treeType); + $this->register(new Log(new BID($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, $magicNumber & 0x03), $name . " Log", $logBreakInfo, $treeType, false)); $wood = new Wood(new BID(Ids::WOOD, $magicNumber), $name . " Wood", $logBreakInfo, $treeType, false); - $this->register($wood); $this->remap($magicNumber >= 4 ? Ids::LOG2 : Ids::LOG, ($magicNumber & 0x03) | 0b1100, $wood); - $this->register(new Wood(new BID(Ids::WOOD, $magicNumber | BlockLegacyMetadata::WOOD_FLAG_STRIPPED), "Stripped $name Wood", $logBreakInfo, $treeType, true)); + + $allSidedLogs[] = $wood; + $allSidedLogs[] = new Wood(new BID(Ids::WOOD, $magicNumber | BlockLegacyMetadata::WOOD_FLAG_STRIPPED), "Stripped $name Wood", $logBreakInfo, $treeType, true); $this->registerAllMeta(new Log(BlockLegacyIdHelper::getStrippedLogIdentifier($treeType), "Stripped " . $name . " Log", $logBreakInfo, $treeType, true)); $this->registerAllMeta(new FenceGate(BlockLegacyIdHelper::getWoodenFenceIdentifier($treeType), $name . " Fence Gate", $planksBreakInfo)); @@ -464,6 +491,11 @@ class BlockFactory{ $this->registerAllMeta(new FloorSign(BlockLegacyIdHelper::getWoodenFloorSignIdentifier($treeType), $name . " Sign", $signBreakInfo)); $this->registerAllMeta(new WallSign(BlockLegacyIdHelper::getWoodenWallSignIdentifier($treeType), $name . " Wall Sign", $signBreakInfo)); } + $this->registerAllMeta(...$planks); + $this->registerAllMeta(...$saplings); + $this->registerAllMeta(...$fences); + $this->registerAllMeta(...$leaves); + $this->registerAllMeta(...$allSidedLogs); static $sandstoneTypes = [ Meta::SANDSTONE_NORMAL => "", @@ -476,10 +508,14 @@ class BlockFactory{ $this->registerAllMeta(new Stair(new BID(Ids::SMOOTH_RED_SANDSTONE_STAIRS, 0), "Smooth Red Sandstone Stairs", $sandstoneBreakInfo)); $this->registerAllMeta(new Stair(new BID(Ids::SANDSTONE_STAIRS, 0), "Sandstone Stairs", $sandstoneBreakInfo)); $this->registerAllMeta(new Stair(new BID(Ids::SMOOTH_SANDSTONE_STAIRS, 0), "Smooth Sandstone Stairs", $sandstoneBreakInfo)); + $sandstones = []; + $redSandstones = []; foreach($sandstoneTypes as $variant => $prefix){ - $this->register(new Opaque(new BID(Ids::SANDSTONE, $variant), $prefix . "Sandstone", $sandstoneBreakInfo)); - $this->register(new Opaque(new BID(Ids::RED_SANDSTONE, $variant), $prefix . "Red Sandstone", $sandstoneBreakInfo)); + $sandstones[] = new Opaque(new BID(Ids::SANDSTONE, $variant), $prefix . "Sandstone", $sandstoneBreakInfo); + $redSandstones[] = new Opaque(new BID(Ids::RED_SANDSTONE, $variant), $prefix . "Red Sandstone", $sandstoneBreakInfo); } + $this->registerAllMeta(...$sandstones); + $this->registerAllMeta(...$redSandstones); $glazedTerracottaBreakInfo = new BlockBreakInfo(1.4, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()); foreach(DyeColor::getAll() as $color){ @@ -510,28 +546,32 @@ class BlockFactory{ //TODO: in the future these won't all have the same hardness; they only do now because of the old metadata crap $wallBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_ANDESITE), "Andesite Wall", $wallBreakInfo)); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_BRICK), "Brick Wall", $wallBreakInfo)); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_DIORITE), "Diorite Wall", $wallBreakInfo)); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_END_STONE_BRICK), "End Stone Brick Wall", $wallBreakInfo)); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_GRANITE), "Granite Wall", $wallBreakInfo)); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_MOSSY_STONE_BRICK), "Mossy Stone Brick Wall", $wallBreakInfo)); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_MOSSY_COBBLESTONE), "Mossy Cobblestone Wall", $wallBreakInfo)); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_NETHER_BRICK), "Nether Brick Wall", $wallBreakInfo)); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_COBBLESTONE), "Cobblestone Wall", $wallBreakInfo)); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_PRISMARINE), "Prismarine Wall", $wallBreakInfo)); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_RED_NETHER_BRICK), "Red Nether Brick Wall", $wallBreakInfo)); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_RED_SANDSTONE), "Red Sandstone Wall", $wallBreakInfo)); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_SANDSTONE), "Sandstone Wall", $wallBreakInfo)); - $this->register(new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_STONE_BRICK), "Stone Brick Wall", $wallBreakInfo)); + $this->registerAllMeta( + new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_COBBLESTONE), "Cobblestone Wall", $wallBreakInfo), + new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_ANDESITE), "Andesite Wall", $wallBreakInfo), + new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_BRICK), "Brick Wall", $wallBreakInfo), + new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_DIORITE), "Diorite Wall", $wallBreakInfo), + new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_END_STONE_BRICK), "End Stone Brick Wall", $wallBreakInfo), + new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_GRANITE), "Granite Wall", $wallBreakInfo), + new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_MOSSY_STONE_BRICK), "Mossy Stone Brick Wall", $wallBreakInfo), + new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_MOSSY_COBBLESTONE), "Mossy Cobblestone Wall", $wallBreakInfo), + new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_NETHER_BRICK), "Nether Brick Wall", $wallBreakInfo), + new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_PRISMARINE), "Prismarine Wall", $wallBreakInfo), + new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_RED_NETHER_BRICK), "Red Nether Brick Wall", $wallBreakInfo), + new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_RED_SANDSTONE), "Red Sandstone Wall", $wallBreakInfo), + new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_SANDSTONE), "Sandstone Wall", $wallBreakInfo), + new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_STONE_BRICK), "Stone Brick Wall", $wallBreakInfo), + ); $this->registerElements(); $chemistryTableBreakInfo = new BlockBreakInfo(2.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel()); - $this->register(new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_COMPOUND_CREATOR), "Compound Creator", $chemistryTableBreakInfo)); - $this->register(new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_ELEMENT_CONSTRUCTOR), "Element Constructor", $chemistryTableBreakInfo)); - $this->register(new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_LAB_TABLE), "Lab Table", $chemistryTableBreakInfo)); - $this->register(new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_MATERIAL_REDUCER), "Material Reducer", $chemistryTableBreakInfo)); + $this->registerAllMeta( + new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_COMPOUND_CREATOR), "Compound Creator", $chemistryTableBreakInfo), + new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_ELEMENT_CONSTRUCTOR), "Element Constructor", $chemistryTableBreakInfo), + new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_LAB_TABLE), "Lab Table", $chemistryTableBreakInfo), + new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_MATERIAL_REDUCER), "Material Reducer", $chemistryTableBreakInfo) + ); $this->registerAllMeta(new ChemicalHeat(new BID(Ids::CHEMICAL_HEAT, 0), "Heat Block", $chemistryTableBreakInfo)); @@ -868,12 +908,23 @@ class BlockFactory{ * This should only be used when this block type has sole ownership of an ID. For IDs which contain multiple block * types (variants), the regular register() method should be used instead. */ - private function registerAllMeta(Block $block) : void{ - $this->register($block); - foreach($block->getIdInfo()->getAllBlockIds() as $id){ + private function registerAllMeta(Block $default, Block ...$additional) : void{ + $ids = []; + $this->register($default); + foreach($default->getIdInfo()->getAllBlockIds() as $id){ + $ids[$id] = $id; + } + foreach($additional as $block){ + $this->register($block); + foreach($block->getIdInfo()->getAllBlockIds() as $id){ + $ids[$id] = $id; + } + } + + foreach($ids as $id){ for($meta = 0; $meta < 1 << Block::INTERNAL_METADATA_BITS; ++$meta){ if(!$this->isRegistered($id, $meta)){ - $this->remap($id, $meta, $block); + $this->remap($id, $meta, $default); } } } diff --git a/tests/phpunit/block/block_factory_consistency_check.json b/tests/phpunit/block/block_factory_consistency_check.json index c370eeaaeb..932d526a4c 100644 --- a/tests/phpunit/block/block_factory_consistency_check.json +++ b/tests/phpunit/block/block_factory_consistency_check.json @@ -1 +1 @@ -{"knownStates":{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","497":"Tall Grass","498":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1614":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2640":"Slime Block","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3280":"Shulker Box","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3488":"Dyed Shulker Box","3489":"Dyed Shulker Box","3490":"Dyed Shulker Box","3491":"Dyed Shulker Box","3492":"Dyed Shulker Box","3493":"Dyed Shulker Box","3494":"Dyed Shulker Box","3495":"Dyed Shulker Box","3496":"Dyed Shulker Box","3497":"Dyed Shulker Box","3498":"Dyed Shulker Box","3499":"Dyed Shulker Box","3500":"Dyed Shulker Box","3501":"Dyed Shulker Box","3502":"Dyed Shulker Box","3503":"Dyed Shulker Box","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6274":"Wall Coral Fan","6276":"Wall Coral Fan","6278":"Wall Coral Fan","6280":"Wall Coral Fan","6282":"Wall Coral Fan","6284":"Wall Coral Fan","6286":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7218":"Blast Furnace","7219":"Blast Furnace","7220":"Blast Furnace","7221":"Blast Furnace","7250":"Smoker","7251":"Smoker","7252":"Smoker","7253":"Smoker","7266":"Smoker","7267":"Smoker","7268":"Smoker","7269":"Smoker","7296":"Fletching Table","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7376":"Bell","7377":"Bell","7378":"Bell","7379":"Bell","7380":"Bell","7381":"Bell","7382":"Bell","7383":"Bell","7384":"Bell","7385":"Bell","7386":"Bell","7387":"Bell","7388":"Bell","7389":"Bell","7390":"Bell","7391":"Bell","7392":"Sweet Berry Bush","7393":"Sweet Berry Bush","7394":"Sweet Berry Bush","7395":"Sweet Berry Bush","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood","7480":"Stripped Oak Wood","7481":"Stripped Spruce Wood","7482":"Stripped Birch Wood","7483":"Stripped Jungle Wood","7484":"Stripped Acacia Wood","7485":"Stripped Dark Oak Wood","7506":"Blast Furnace","7507":"Blast Furnace","7508":"Blast Furnace","7509":"Blast Furnace"},"remaps":{"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"33":32,"34":32,"35":32,"36":32,"37":32,"38":32,"39":32,"40":32,"41":32,"42":32,"43":32,"44":32,"45":32,"46":32,"47":32,"50":48,"51":48,"52":48,"53":48,"54":48,"55":48,"56":48,"57":48,"58":48,"59":48,"60":48,"61":48,"62":48,"63":48,"65":64,"66":64,"67":64,"68":64,"69":64,"70":64,"71":64,"72":64,"73":64,"74":64,"75":64,"76":64,"77":64,"78":64,"79":64,"114":112,"115":112,"116":112,"117":112,"118":112,"119":112,"120":112,"121":112,"122":112,"123":112,"124":112,"125":112,"126":112,"127":112,"209":208,"210":208,"211":208,"212":208,"213":208,"214":208,"215":208,"216":208,"217":208,"218":208,"219":208,"220":208,"221":208,"222":208,"223":208,"225":224,"226":224,"227":224,"228":224,"229":224,"230":224,"231":224,"232":224,"233":224,"234":224,"235":224,"236":224,"237":224,"238":224,"239":224,"241":240,"242":240,"243":240,"244":240,"245":240,"246":240,"247":240,"248":240,"249":240,"250":240,"251":240,"252":240,"253":240,"254":240,"255":240,"257":256,"258":256,"259":256,"260":256,"261":256,"262":256,"263":256,"264":256,"265":256,"266":256,"267":256,"268":256,"269":256,"270":256,"271":256,"284":7472,"285":7473,"286":7474,"287":7475,"306":304,"307":304,"308":304,"309":304,"310":304,"311":304,"312":304,"313":304,"314":304,"315":304,"316":304,"317":304,"318":304,"319":304,"321":320,"322":320,"323":320,"324":320,"325":320,"326":320,"327":320,"328":320,"329":320,"330":320,"331":320,"332":320,"333":320,"334":320,"335":320,"337":336,"338":336,"339":336,"340":336,"341":336,"342":336,"343":336,"344":336,"345":336,"346":336,"347":336,"348":336,"349":336,"350":336,"351":336,"353":352,"354":352,"355":352,"356":352,"357":352,"358":352,"359":352,"360":352,"361":352,"362":352,"363":352,"364":352,"365":352,"366":352,"367":352,"401":400,"402":400,"403":400,"404":400,"405":400,"406":400,"407":400,"408":400,"409":400,"410":400,"411":400,"412":400,"413":400,"414":400,"415":400,"438":432,"439":432,"446":432,"447":432,"454":448,"455":448,"462":448,"463":448,"481":480,"482":480,"483":480,"484":480,"485":480,"486":480,"487":480,"488":480,"489":480,"490":480,"491":480,"492":480,"493":480,"494":480,"495":480,"496":498,"499":498,"513":512,"514":512,"515":512,"516":512,"517":512,"518":512,"519":512,"520":512,"521":512,"522":512,"523":512,"524":512,"525":512,"526":512,"527":512,"577":576,"578":576,"579":576,"580":576,"581":576,"582":576,"583":576,"584":576,"585":576,"586":576,"587":576,"588":576,"589":576,"590":576,"591":576,"593":592,"594":592,"595":592,"596":592,"597":592,"598":592,"599":592,"600":592,"601":592,"602":592,"603":592,"604":592,"605":592,"606":592,"607":592,"625":624,"626":624,"627":624,"628":624,"629":624,"630":624,"631":624,"632":624,"633":624,"634":624,"635":624,"636":624,"637":624,"638":624,"639":624,"641":640,"642":640,"643":640,"644":640,"645":640,"646":640,"647":640,"648":640,"649":640,"650":640,"651":640,"652":640,"653":640,"654":640,"655":640,"657":656,"658":656,"659":656,"660":656,"661":656,"662":656,"663":656,"664":656,"665":656,"666":656,"667":656,"668":656,"669":656,"670":656,"671":656,"673":672,"674":672,"675":672,"676":672,"677":672,"678":672,"679":672,"680":672,"681":672,"682":672,"683":672,"684":672,"685":672,"686":672,"687":672,"696":688,"697":689,"698":690,"699":691,"700":692,"701":693,"702":694,"703":695,"721":720,"722":720,"723":720,"724":720,"725":720,"726":720,"727":720,"728":720,"729":720,"730":720,"731":720,"732":720,"733":720,"734":720,"735":720,"740":736,"741":736,"742":736,"743":736,"744":736,"745":736,"746":736,"747":736,"748":736,"749":736,"750":736,"751":736,"753":752,"754":752,"755":752,"756":752,"757":752,"758":752,"759":752,"760":752,"761":752,"762":752,"763":752,"764":752,"765":752,"766":752,"767":752,"769":768,"770":768,"771":768,"772":768,"773":768,"774":768,"775":768,"776":768,"777":768,"778":768,"779":768,"780":768,"781":768,"782":768,"783":768,"785":784,"786":784,"787":784,"788":784,"789":784,"790":784,"791":784,"792":784,"793":784,"794":784,"795":784,"796":784,"797":784,"798":784,"799":784,"800":805,"806":805,"807":805,"808":805,"809":805,"810":805,"811":805,"812":805,"813":805,"814":805,"815":805,"833":832,"834":832,"835":832,"836":832,"837":832,"838":832,"839":832,"840":832,"841":832,"842":832,"843":832,"844":832,"845":832,"846":832,"847":832,"856":851,"857":851,"858":851,"859":851,"860":851,"861":851,"862":851,"863":851,"864":866,"865":866,"870":866,"871":866,"872":866,"873":866,"874":866,"875":866,"876":866,"877":866,"878":866,"879":866,"897":896,"898":896,"899":896,"900":896,"901":896,"902":896,"903":896,"904":896,"905":896,"906":896,"907":896,"908":896,"909":896,"910":896,"911":896,"913":912,"914":912,"915":912,"916":912,"917":912,"918":912,"919":912,"920":912,"921":912,"922":912,"923":912,"924":912,"925":912,"926":912,"927":912,"929":928,"930":928,"931":928,"932":928,"933":928,"934":928,"935":928,"936":928,"937":928,"938":928,"939":928,"940":928,"941":928,"942":928,"943":928,"952":944,"953":944,"954":944,"955":944,"956":944,"957":944,"958":944,"959":944,"968":960,"969":960,"970":960,"971":960,"972":960,"973":960,"974":960,"975":960,"976":978,"977":978,"982":978,"983":978,"984":978,"985":978,"986":978,"987":978,"988":978,"989":978,"990":978,"991":978,"992":978,"993":978,"998":978,"999":978,"1000":978,"1001":978,"1002":978,"1003":978,"1004":978,"1005":978,"1006":978,"1007":978,"1036":1027,"1037":1027,"1038":1027,"1039":1027,"1040":1042,"1041":1042,"1046":1042,"1047":1042,"1048":1042,"1049":1042,"1050":1042,"1051":1042,"1052":1042,"1053":1042,"1054":1042,"1055":1042,"1066":1056,"1067":1056,"1068":1056,"1069":1056,"1070":1056,"1071":1056,"1080":1075,"1081":1075,"1082":1075,"1083":1075,"1084":1075,"1085":1075,"1086":1075,"1087":1075,"1088":1090,"1089":1090,"1094":1090,"1095":1090,"1096":1090,"1097":1090,"1098":1090,"1099":1090,"1100":1090,"1101":1090,"1102":1090,"1103":1090,"1122":1120,"1123":1120,"1124":1120,"1125":1120,"1126":1120,"1127":1120,"1128":1120,"1129":1120,"1130":1120,"1131":1120,"1132":1120,"1133":1120,"1134":1120,"1135":1120,"1148":1139,"1149":1139,"1150":1139,"1151":1139,"1154":1152,"1155":1152,"1156":1152,"1157":1152,"1158":1152,"1159":1152,"1160":1152,"1161":1152,"1162":1152,"1163":1152,"1164":1152,"1165":1152,"1166":1152,"1167":1152,"1169":1168,"1170":1168,"1171":1168,"1172":1168,"1173":1168,"1174":1168,"1175":1168,"1176":1168,"1177":1168,"1178":1168,"1179":1168,"1180":1168,"1181":1168,"1182":1168,"1183":1168,"1185":1168,"1186":1168,"1187":1168,"1188":1168,"1189":1168,"1190":1168,"1191":1168,"1192":1168,"1193":1168,"1194":1168,"1195":1168,"1196":1168,"1197":1168,"1198":1168,"1199":1168,"1200":1221,"1206":1221,"1207":1221,"1208":1221,"1209":1221,"1210":1221,"1211":1221,"1212":1221,"1213":1221,"1214":1221,"1215":1221,"1216":1221,"1222":1221,"1223":1221,"1224":1221,"1225":1221,"1226":1221,"1227":1221,"1228":1221,"1229":1221,"1230":1221,"1231":1221,"1238":1232,"1239":1232,"1246":1232,"1247":1232,"1256":1248,"1257":1248,"1258":1248,"1259":1248,"1260":1248,"1261":1248,"1262":1248,"1263":1248,"1265":1264,"1266":1264,"1267":1264,"1268":1264,"1269":1264,"1270":1264,"1271":1264,"1272":1264,"1273":1264,"1274":1264,"1275":1264,"1276":1264,"1277":1264,"1278":1264,"1279":1264,"1281":1280,"1282":1280,"1283":1280,"1284":1280,"1285":1280,"1286":1280,"1287":1280,"1288":1280,"1289":1280,"1290":1280,"1291":1280,"1292":1280,"1293":1280,"1294":1280,"1295":1280,"1313":1312,"1314":1312,"1315":1312,"1316":1312,"1317":1312,"1318":1312,"1319":1312,"1320":1312,"1321":1312,"1322":1312,"1323":1312,"1324":1312,"1325":1312,"1326":1312,"1327":1312,"1345":1344,"1346":1344,"1347":1344,"1348":1344,"1349":1344,"1350":1344,"1351":1344,"1352":1344,"1353":1344,"1354":1344,"1355":1344,"1356":1344,"1357":1344,"1358":1344,"1359":1344,"1377":1376,"1378":1376,"1379":1376,"1380":1376,"1381":1376,"1382":1376,"1383":1376,"1384":1376,"1385":1376,"1386":1376,"1387":1376,"1388":1376,"1389":1376,"1390":1376,"1391":1376,"1393":1392,"1394":1392,"1395":1392,"1396":1392,"1397":1392,"1398":1392,"1399":1392,"1400":1392,"1401":1392,"1402":1392,"1403":1392,"1404":1392,"1405":1392,"1406":1392,"1407":1392,"1409":1408,"1410":1408,"1411":1408,"1412":1408,"1413":1408,"1414":1408,"1415":1408,"1416":1408,"1417":1408,"1418":1408,"1419":1408,"1420":1408,"1421":1408,"1422":1408,"1423":1408,"1425":1424,"1426":1424,"1427":1424,"1428":1424,"1429":1424,"1430":1424,"1431":1424,"1432":1424,"1433":1424,"1434":1424,"1435":1424,"1436":1424,"1437":1424,"1438":1424,"1439":1424,"1440":1441,"1443":1441,"1444":1441,"1445":1441,"1446":1441,"1447":1441,"1448":1441,"1449":1441,"1450":1441,"1451":1441,"1452":1441,"1453":1441,"1454":1441,"1455":1441,"1460":1458,"1461":1458,"1462":1458,"1463":1458,"1464":1458,"1465":1458,"1466":1458,"1467":1458,"1468":1458,"1469":1458,"1470":1458,"1471":1458,"1479":1472,"1480":1472,"1481":1472,"1482":1472,"1483":1472,"1484":1472,"1485":1472,"1486":1472,"1487":1472,"1521":1520,"1522":1520,"1523":1520,"1524":1520,"1525":1520,"1526":1520,"1527":1520,"1528":1520,"1529":1520,"1530":1520,"1531":1520,"1532":1520,"1533":1520,"1534":1520,"1535":1520,"1595":1598,"1596":1598,"1597":1598,"1610":1594,"1611":1614,"1612":1614,"1613":1614,"1615":1599,"1617":1616,"1618":1616,"1619":1616,"1620":1616,"1621":1616,"1622":1616,"1623":1616,"1624":1616,"1625":1616,"1626":1616,"1627":1616,"1628":1616,"1629":1616,"1630":1616,"1631":1616,"1633":1632,"1634":1632,"1635":1632,"1636":1632,"1637":1632,"1638":1632,"1639":1632,"1640":1632,"1641":1632,"1642":1632,"1643":1632,"1644":1632,"1645":1632,"1646":1632,"1647":1632,"1649":1648,"1650":1648,"1651":1648,"1652":1648,"1653":1648,"1654":1648,"1655":1648,"1656":1648,"1657":1648,"1658":1648,"1659":1648,"1660":1648,"1661":1648,"1662":1648,"1663":1648,"1672":1664,"1673":1664,"1674":1664,"1675":1664,"1676":1664,"1677":1664,"1678":1664,"1679":1664,"1688":1680,"1689":1680,"1690":1680,"1691":1680,"1692":1680,"1693":1680,"1694":1680,"1695":1680,"1736":1731,"1737":1731,"1738":1731,"1739":1731,"1740":1731,"1741":1731,"1742":1731,"1743":1731,"1752":1747,"1753":1747,"1754":1747,"1755":1747,"1756":1747,"1757":1747,"1758":1747,"1759":1747,"1761":1760,"1762":1760,"1763":1760,"1764":1760,"1765":1760,"1766":1760,"1767":1760,"1768":1760,"1769":1760,"1770":1760,"1771":1760,"1772":1760,"1773":1760,"1774":1760,"1775":1760,"1777":1776,"1778":1776,"1779":1776,"1780":1776,"1781":1776,"1782":1776,"1783":1776,"1784":1776,"1785":1776,"1786":1776,"1787":1776,"1788":1776,"1789":1776,"1790":1776,"1791":1776,"1793":1792,"1794":1792,"1795":1792,"1796":1792,"1797":1792,"1798":1792,"1799":1792,"1800":1792,"1801":1792,"1802":1792,"1803":1792,"1804":1792,"1805":1792,"1806":1792,"1807":1792,"1809":1808,"1810":1808,"1811":1808,"1812":1808,"1813":1808,"1814":1808,"1815":1808,"1816":1808,"1817":1808,"1818":1808,"1819":1808,"1820":1808,"1821":1808,"1822":1808,"1823":1808,"1832":1827,"1833":1827,"1834":1827,"1835":1827,"1836":1827,"1837":1827,"1838":1827,"1839":1827,"1844":1840,"1845":1840,"1846":1840,"1847":1840,"1848":1840,"1849":1840,"1850":1840,"1851":1840,"1852":1840,"1853":1840,"1854":1840,"1855":1840,"1857":1856,"1858":1856,"1859":1856,"1860":1856,"1861":1856,"1862":1856,"1863":1856,"1864":1856,"1865":1856,"1866":1856,"1867":1856,"1868":1856,"1869":1856,"1870":1856,"1871":1856,"1880":1872,"1881":1872,"1882":1872,"1883":1872,"1884":1872,"1885":1872,"1886":1872,"1887":1872,"1928":1922,"1929":1922,"1930":1922,"1931":1922,"1932":1922,"1933":1922,"1934":1922,"1935":1922,"1937":1936,"1938":1936,"1939":1936,"1940":1936,"1941":1936,"1942":1936,"1943":1936,"1944":1936,"1945":1936,"1946":1936,"1947":1936,"1948":1936,"1949":1936,"1950":1936,"1951":1936,"1953":1952,"1954":1952,"1955":1952,"1956":1952,"1957":1952,"1958":1952,"1959":1952,"1960":1952,"1961":1952,"1962":1952,"1963":1952,"1964":1952,"1965":1952,"1966":1952,"1967":1952,"1969":1968,"1970":1968,"1971":1968,"1972":1968,"1973":1968,"1974":1968,"1975":1968,"1976":1968,"1977":1968,"1978":1968,"1979":1968,"1980":1968,"1981":1968,"1982":1968,"1983":1968,"1985":1968,"1986":1968,"1987":1968,"1988":1968,"1989":1968,"1990":1968,"1991":1968,"1992":1968,"1993":1968,"1994":1968,"1995":1968,"1996":1968,"1997":1968,"1998":1968,"1999":1968,"2022":2016,"2023":2016,"2030":2016,"2031":2016,"2044":2032,"2045":2032,"2046":2032,"2047":2032,"2056":2051,"2057":2051,"2058":2051,"2059":2051,"2060":2051,"2061":2051,"2062":2051,"2063":2051,"2065":2064,"2066":2064,"2067":2064,"2068":2064,"2069":2064,"2070":2064,"2071":2064,"2072":2064,"2073":2064,"2074":2064,"2075":2064,"2076":2064,"2077":2064,"2078":2064,"2079":2064,"2080":2082,"2081":2082,"2086":2082,"2087":2082,"2088":2082,"2089":2082,"2090":2082,"2091":2082,"2092":2082,"2093":2082,"2094":2082,"2095":2082,"2129":2128,"2130":2128,"2131":2128,"2132":2128,"2133":2128,"2134":2128,"2135":2128,"2136":2128,"2137":2128,"2138":2128,"2139":2128,"2140":2128,"2141":2128,"2142":2128,"2143":2128,"2152":2147,"2153":2147,"2154":2147,"2155":2147,"2156":2147,"2157":2147,"2158":2147,"2159":2147,"2168":2163,"2169":2163,"2170":2163,"2171":2163,"2172":2163,"2173":2163,"2174":2163,"2175":2163,"2184":2179,"2185":2179,"2186":2179,"2187":2179,"2188":2179,"2189":2179,"2190":2179,"2191":2179,"2209":2208,"2210":2208,"2211":2208,"2212":2208,"2213":2208,"2214":2208,"2215":2208,"2216":2208,"2217":2208,"2218":2208,"2219":2208,"2220":2208,"2221":2208,"2222":2208,"2223":2208,"2241":2240,"2242":2240,"2243":2240,"2244":2240,"2245":2240,"2246":2240,"2247":2240,"2248":2240,"2249":2240,"2250":2240,"2251":2240,"2252":2240,"2253":2240,"2254":2240,"2255":2240,"2264":2256,"2265":2256,"2266":2256,"2267":2256,"2268":2256,"2269":2256,"2270":2256,"2271":2256,"2280":2272,"2281":2272,"2282":2272,"2283":2272,"2284":2272,"2285":2272,"2286":2272,"2287":2272,"2294":2288,"2295":2288,"2302":2288,"2303":2288,"2304":2306,"2310":2306,"2311":2306,"2312":2306,"2313":2306,"2314":2306,"2315":2306,"2316":2306,"2317":2306,"2318":2306,"2319":2306,"2332":2322,"2333":2322,"2334":2322,"2335":2322,"2336":2338,"2337":2338,"2342":2338,"2343":2338,"2344":2338,"2345":2338,"2346":2338,"2347":2338,"2348":2338,"2349":2338,"2350":2338,"2351":2338,"2392":2386,"2393":2386,"2394":2386,"2395":2386,"2396":2386,"2397":2386,"2398":2386,"2399":2386,"2400":2386,"2401":2386,"2402":2386,"2403":2386,"2404":2386,"2405":2386,"2406":2386,"2407":2386,"2433":2432,"2434":2432,"2435":2432,"2436":2432,"2437":2432,"2438":2432,"2439":2432,"2440":2432,"2441":2432,"2442":2432,"2443":2432,"2444":2432,"2445":2432,"2446":2432,"2447":2432,"2449":2448,"2450":2448,"2451":2448,"2452":2448,"2453":2448,"2454":2448,"2455":2448,"2456":2448,"2457":2448,"2458":2448,"2459":2448,"2460":2448,"2461":2448,"2462":2448,"2463":2448,"2465":2464,"2470":2464,"2471":2464,"2473":2464,"2478":2464,"2479":2464,"2493":2481,"2494":2482,"2504":2499,"2505":2499,"2506":2499,"2507":2499,"2508":2499,"2509":2499,"2510":2499,"2511":2499,"2520":2512,"2521":2513,"2522":2514,"2523":2515,"2524":2516,"2525":2517,"2604":7476,"2605":7477,"2616":2611,"2617":2611,"2618":2611,"2619":2611,"2620":2611,"2621":2611,"2622":2611,"2623":2611,"2632":2627,"2633":2627,"2634":2627,"2635":2627,"2636":2627,"2637":2627,"2638":2627,"2639":2627,"2641":2640,"2642":2640,"2643":2640,"2644":2640,"2645":2640,"2646":2640,"2647":2640,"2648":2640,"2649":2640,"2650":2640,"2651":2640,"2652":2640,"2653":2640,"2654":2640,"2655":2640,"2705":2704,"2706":2704,"2707":2704,"2708":2704,"2709":2704,"2710":2704,"2711":2704,"2712":2704,"2713":2704,"2714":2704,"2715":2704,"2716":2704,"2717":2704,"2718":2704,"2719":2704,"2721":2720,"2722":2720,"2723":2720,"2725":2720,"2726":2720,"2727":2720,"2729":2720,"2730":2720,"2731":2720,"2732":2720,"2733":2720,"2734":2720,"2735":2720,"2753":2752,"2754":2752,"2755":2752,"2756":2752,"2757":2752,"2758":2752,"2759":2752,"2760":2752,"2761":2752,"2762":2752,"2763":2752,"2764":2752,"2765":2752,"2766":2752,"2767":2752,"2769":2768,"2770":2768,"2771":2768,"2772":2768,"2773":2768,"2774":2768,"2775":2768,"2776":2768,"2777":2768,"2778":2768,"2779":2768,"2780":2768,"2781":2768,"2782":2768,"2783":2768,"2785":2784,"2786":2784,"2787":2784,"2788":2784,"2789":2784,"2790":2784,"2791":2784,"2792":2784,"2793":2784,"2794":2784,"2795":2784,"2796":2784,"2797":2784,"2798":2784,"2799":2784,"2832":2834,"2833":2834,"2838":2834,"2839":2834,"2840":2834,"2841":2834,"2842":2834,"2843":2834,"2844":2834,"2845":2834,"2846":2834,"2847":2834,"2888":2883,"2889":2883,"2890":2883,"2891":2883,"2892":2883,"2893":2883,"2894":2883,"2895":2883,"2904":2896,"2905":2897,"2906":2898,"2907":2899,"2908":2900,"2909":2901,"2910":2902,"2911":2903,"3041":3040,"3042":3040,"3043":3040,"3044":3040,"3045":3040,"3046":3040,"3047":3040,"3048":3040,"3049":3040,"3050":3040,"3051":3040,"3052":3040,"3053":3040,"3054":3040,"3055":3040,"3073":3072,"3074":3072,"3075":3072,"3076":3072,"3077":3072,"3078":3072,"3079":3072,"3080":3072,"3081":3072,"3082":3072,"3083":3072,"3084":3072,"3085":3072,"3086":3072,"3087":3072,"3100":3091,"3101":3091,"3102":3091,"3103":3091,"3116":3107,"3117":3107,"3118":3107,"3119":3107,"3132":3123,"3133":3123,"3134":3123,"3135":3123,"3148":3139,"3149":3139,"3150":3139,"3151":3139,"3164":3155,"3165":3155,"3166":3155,"3167":3155,"3169":3168,"3170":3168,"3171":3168,"3172":3168,"3173":3168,"3174":3168,"3175":3168,"3176":3168,"3177":3168,"3178":3168,"3179":3168,"3180":3168,"3181":3168,"3182":3168,"3183":3168,"3192":3187,"3193":3187,"3194":3187,"3195":3187,"3196":3187,"3197":3187,"3198":3187,"3199":3187,"3230":3218,"3232":3237,"3238":3237,"3239":3237,"3240":3245,"3246":3245,"3247":3245,"3256":3251,"3257":3251,"3258":3251,"3259":3251,"3260":3251,"3261":3251,"3262":3251,"3263":3251,"3264":3269,"3270":3269,"3271":3269,"3272":3277,"3278":3277,"3279":3277,"3281":3280,"3282":3280,"3283":3280,"3284":3280,"3285":3280,"3286":3280,"3287":3280,"3288":3280,"3289":3280,"3290":3280,"3291":3280,"3292":3280,"3293":3280,"3294":3280,"3295":3280,"3297":3296,"3298":3296,"3299":3296,"3300":3296,"3301":3296,"3302":3296,"3303":3296,"3304":3296,"3305":3296,"3306":3296,"3307":3296,"3308":3296,"3309":3296,"3310":3296,"3311":3296,"3316":3312,"3317":3312,"3318":3312,"3319":3312,"3320":3312,"3321":3312,"3322":3312,"3323":3312,"3324":3312,"3325":3312,"3326":3312,"3327":3312,"3334":3328,"3335":3328,"3336":3328,"3337":3328,"3338":3328,"3339":3328,"3340":3328,"3341":3328,"3342":3328,"3343":3328,"3409":3408,"3410":3408,"3411":3408,"3412":3408,"3413":3408,"3414":3408,"3415":3408,"3416":3408,"3417":3408,"3418":3408,"3419":3408,"3420":3408,"3421":3408,"3422":3408,"3423":3408,"3425":3424,"3426":3424,"3427":3424,"3428":3424,"3429":3424,"3430":3424,"3431":3424,"3432":3424,"3433":3424,"3434":3424,"3435":3424,"3436":3424,"3437":3424,"3438":3424,"3439":3424,"3441":3440,"3442":3440,"3443":3440,"3444":3440,"3445":3440,"3446":3440,"3447":3440,"3448":3440,"3449":3440,"3450":3440,"3451":3440,"3452":3440,"3453":3440,"3454":3440,"3455":3440,"3457":3456,"3458":3456,"3459":3456,"3461":3456,"3462":3456,"3463":3456,"3465":3456,"3466":3456,"3467":3456,"3468":3456,"3469":3456,"3470":3456,"3471":3456,"3504":3506,"3505":3506,"3510":3506,"3511":3506,"3512":3506,"3513":3506,"3514":3506,"3515":3506,"3516":3506,"3517":3506,"3518":3506,"3519":3506,"3520":3522,"3521":3522,"3526":3522,"3527":3522,"3528":3522,"3529":3522,"3530":3522,"3531":3522,"3532":3522,"3533":3522,"3534":3522,"3535":3522,"3536":3538,"3537":3538,"3542":3538,"3543":3538,"3544":3538,"3545":3538,"3546":3538,"3547":3538,"3548":3538,"3549":3538,"3550":3538,"3551":3538,"3552":3554,"3553":3554,"3558":3554,"3559":3554,"3560":3554,"3561":3554,"3562":3554,"3563":3554,"3564":3554,"3565":3554,"3566":3554,"3567":3554,"3568":3570,"3569":3570,"3574":3570,"3575":3570,"3576":3570,"3577":3570,"3578":3570,"3579":3570,"3580":3570,"3581":3570,"3582":3570,"3583":3570,"3584":3586,"3585":3586,"3590":3586,"3591":3586,"3592":3586,"3593":3586,"3594":3586,"3595":3586,"3596":3586,"3597":3586,"3598":3586,"3599":3586,"3600":3602,"3601":3602,"3606":3602,"3607":3602,"3608":3602,"3609":3602,"3610":3602,"3611":3602,"3612":3602,"3613":3602,"3614":3602,"3615":3602,"3616":3618,"3617":3618,"3622":3618,"3623":3618,"3624":3618,"3625":3618,"3626":3618,"3627":3618,"3628":3618,"3629":3618,"3630":3618,"3631":3618,"3632":3634,"3633":3634,"3638":3634,"3639":3634,"3640":3634,"3641":3634,"3642":3634,"3643":3634,"3644":3634,"3645":3634,"3646":3634,"3647":3634,"3648":3650,"3649":3650,"3654":3650,"3655":3650,"3656":3650,"3657":3650,"3658":3650,"3659":3650,"3660":3650,"3661":3650,"3662":3650,"3663":3650,"3664":3666,"3665":3666,"3670":3666,"3671":3666,"3672":3666,"3673":3666,"3674":3666,"3675":3666,"3676":3666,"3677":3666,"3678":3666,"3679":3666,"3696":3698,"3697":3698,"3702":3698,"3703":3698,"3704":3698,"3705":3698,"3706":3698,"3707":3698,"3708":3698,"3709":3698,"3710":3698,"3711":3698,"3712":3714,"3713":3714,"3718":3714,"3719":3714,"3720":3714,"3721":3714,"3722":3714,"3723":3714,"3724":3714,"3725":3714,"3726":3714,"3727":3714,"3728":3730,"3729":3730,"3734":3730,"3735":3730,"3736":3730,"3737":3730,"3738":3730,"3739":3730,"3740":3730,"3741":3730,"3742":3730,"3743":3730,"3744":3746,"3745":3746,"3750":3746,"3751":3746,"3752":3746,"3753":3746,"3754":3746,"3755":3746,"3756":3746,"3757":3746,"3758":3746,"3759":3746,"3760":3762,"3761":3762,"3766":3762,"3767":3762,"3768":3762,"3769":3762,"3770":3762,"3771":3762,"3772":3762,"3773":3762,"3774":3762,"3775":3762,"3824":3829,"3830":3829,"3831":3829,"3832":3829,"3833":3829,"3834":3829,"3835":3829,"3836":3829,"3837":3829,"3838":3829,"3839":3829,"3889":3888,"3890":3888,"3891":3888,"3892":3888,"3893":3888,"3894":3888,"3895":3888,"3896":3888,"3897":3888,"3898":3888,"3899":3888,"3900":3888,"3901":3888,"3902":3888,"3903":3888,"3912":3904,"3913":3904,"3914":3904,"3915":3904,"3916":3904,"3917":3904,"3918":3904,"3919":3904,"3921":3920,"3922":3920,"3923":3920,"3924":3920,"3925":3920,"3926":3920,"3927":3920,"3928":3920,"3929":3920,"3930":3920,"3931":3920,"3932":3920,"3933":3920,"3934":3920,"3935":3920,"3937":3936,"3938":3936,"3939":3936,"3940":3936,"3941":3936,"3942":3936,"3943":3936,"3944":3936,"3945":3936,"3946":3936,"3947":3936,"3948":3936,"3949":3936,"3950":3936,"3951":3936,"3955":3952,"3956":3952,"3957":3952,"3958":3952,"3959":3952,"3960":3952,"3961":3952,"3962":3952,"3963":3952,"3964":3952,"3965":3952,"3966":3952,"3967":3952,"3969":3968,"3970":3968,"3971":3968,"3972":3968,"3973":3968,"3974":3968,"3975":3968,"3976":3968,"3977":3968,"3978":3968,"3979":3968,"3980":3968,"3981":3968,"3982":3968,"3983":3968,"3985":3984,"3986":3984,"3987":3984,"3988":3984,"3989":3984,"3990":3984,"3991":3984,"3992":3984,"3993":3984,"3994":3984,"3995":3984,"3996":3984,"3997":3984,"3998":3984,"3999":3984,"4049":4048,"4050":4048,"4051":4048,"4052":4048,"4053":4048,"4054":4048,"4055":4048,"4056":4048,"4057":4048,"4058":4048,"4059":4048,"4060":4048,"4061":4048,"4062":4048,"4063":4048,"4081":4080,"4082":4080,"4083":4080,"4084":4080,"4085":4080,"4086":4080,"4087":4080,"4088":4080,"4089":4080,"4090":4080,"4091":4080,"4092":4080,"4093":4080,"4094":4080,"4095":4080,"4120":4115,"4121":4115,"4122":4115,"4123":4115,"4124":4115,"4125":4115,"4126":4115,"4127":4115,"4136":4131,"4137":4131,"4138":4131,"4139":4131,"4140":4131,"4141":4131,"4142":4131,"4143":4131,"4152":4147,"4153":4147,"4154":4147,"4155":4147,"4156":4147,"4157":4147,"4158":4147,"4159":4147,"4163":4160,"4164":4160,"4165":4160,"4166":4160,"4167":4160,"4168":4160,"4169":4160,"4170":4160,"4171":4160,"4172":4160,"4173":4160,"4174":4160,"4175":4160,"4179":4176,"4180":4176,"4181":4176,"4182":4176,"4183":4176,"4184":4176,"4185":4176,"4186":4176,"4187":4176,"4188":4176,"4189":4176,"4190":4176,"4191":4176,"4195":4192,"4196":4192,"4197":4192,"4198":4192,"4199":4192,"4200":4192,"4201":4192,"4202":4192,"4203":4192,"4204":4192,"4205":4192,"4206":4192,"4207":4192,"4211":4208,"4212":4208,"4213":4208,"4214":4208,"4215":4208,"4216":4208,"4217":4208,"4218":4208,"4219":4208,"4220":4208,"4221":4208,"4222":4208,"4223":4208,"4227":4224,"4228":4224,"4229":4224,"4230":4224,"4231":4224,"4232":4224,"4233":4224,"4234":4224,"4235":4224,"4236":4224,"4237":4224,"4238":4224,"4239":4224,"4243":4240,"4244":4240,"4245":4240,"4246":4240,"4247":4240,"4248":4240,"4249":4240,"4250":4240,"4251":4240,"4252":4240,"4253":4240,"4254":4240,"4255":4240,"4257":4256,"4258":4256,"4259":4256,"4260":4256,"4261":4256,"4262":4256,"4263":4256,"4264":4256,"4265":4256,"4266":4256,"4267":4256,"4268":4256,"4269":4256,"4270":4256,"4271":4256,"4273":4272,"4274":4272,"4275":4272,"4276":4272,"4277":4272,"4278":4272,"4279":4272,"4280":4272,"4281":4272,"4282":4272,"4283":4272,"4284":4272,"4285":4272,"4286":4272,"4287":4272,"4289":4288,"4290":4288,"4291":4288,"4292":4288,"4293":4288,"4294":4288,"4295":4288,"4296":4288,"4297":4288,"4298":4288,"4299":4288,"4300":4288,"4301":4288,"4302":4288,"4303":4288,"4305":4304,"4306":4304,"4307":4304,"4308":4304,"4309":4304,"4310":4304,"4311":4304,"4312":4304,"4313":4304,"4314":4304,"4315":4304,"4316":4304,"4317":4304,"4318":4304,"4319":4304,"4321":4320,"4322":4320,"4323":4320,"4324":4320,"4325":4320,"4326":4320,"4327":4320,"4328":4320,"4329":4320,"4330":4320,"4331":4320,"4332":4320,"4333":4320,"4334":4320,"4335":4320,"4337":4336,"4338":4336,"4339":4336,"4340":4336,"4341":4336,"4342":4336,"4343":4336,"4344":4336,"4345":4336,"4346":4336,"4347":4336,"4348":4336,"4349":4336,"4350":4336,"4351":4336,"4353":4352,"4354":4352,"4355":4352,"4356":4352,"4357":4352,"4358":4352,"4359":4352,"4360":4352,"4361":4352,"4362":4352,"4363":4352,"4364":4352,"4365":4352,"4366":4352,"4367":4352,"4369":4368,"4370":4368,"4371":4368,"4372":4368,"4373":4368,"4374":4368,"4375":4368,"4376":4368,"4377":4368,"4378":4368,"4379":4368,"4380":4368,"4381":4368,"4382":4368,"4383":4368,"4385":4384,"4386":4384,"4387":4384,"4388":4384,"4389":4384,"4390":4384,"4391":4384,"4392":4384,"4393":4384,"4394":4384,"4395":4384,"4396":4384,"4397":4384,"4398":4384,"4399":4384,"4401":4400,"4402":4400,"4403":4400,"4404":4400,"4405":4400,"4406":4400,"4407":4400,"4408":4400,"4409":4400,"4410":4400,"4411":4400,"4412":4400,"4413":4400,"4414":4400,"4415":4400,"4417":4416,"4418":4416,"4419":4416,"4420":4416,"4421":4416,"4422":4416,"4423":4416,"4424":4416,"4425":4416,"4426":4416,"4427":4416,"4428":4416,"4429":4416,"4430":4416,"4431":4416,"4433":4432,"4434":4432,"4435":4432,"4436":4432,"4437":4432,"4438":4432,"4439":4432,"4440":4432,"4441":4432,"4442":4432,"4443":4432,"4444":4432,"4445":4432,"4446":4432,"4447":4432,"4449":4448,"4450":4448,"4451":4448,"4452":4448,"4453":4448,"4454":4448,"4455":4448,"4456":4448,"4457":4448,"4458":4448,"4459":4448,"4460":4448,"4461":4448,"4462":4448,"4463":4448,"4465":4464,"4466":4464,"4467":4464,"4468":4464,"4469":4464,"4470":4464,"4471":4464,"4472":4464,"4473":4464,"4474":4464,"4475":4464,"4476":4464,"4477":4464,"4478":4464,"4479":4464,"4481":4480,"4482":4480,"4483":4480,"4484":4480,"4485":4480,"4486":4480,"4487":4480,"4488":4480,"4489":4480,"4490":4480,"4491":4480,"4492":4480,"4493":4480,"4494":4480,"4495":4480,"4497":4496,"4498":4496,"4499":4496,"4500":4496,"4501":4496,"4502":4496,"4503":4496,"4504":4496,"4505":4496,"4506":4496,"4507":4496,"4508":4496,"4509":4496,"4510":4496,"4511":4496,"4513":4512,"4514":4512,"4515":4512,"4516":4512,"4517":4512,"4518":4512,"4519":4512,"4520":4512,"4521":4512,"4522":4512,"4523":4512,"4524":4512,"4525":4512,"4526":4512,"4527":4512,"4529":4528,"4530":4528,"4531":4528,"4532":4528,"4533":4528,"4534":4528,"4535":4528,"4536":4528,"4537":4528,"4538":4528,"4539":4528,"4540":4528,"4541":4528,"4542":4528,"4543":4528,"4545":4544,"4546":4544,"4547":4544,"4548":4544,"4549":4544,"4550":4544,"4551":4544,"4552":4544,"4553":4544,"4554":4544,"4555":4544,"4556":4544,"4557":4544,"4558":4544,"4559":4544,"4561":4560,"4562":4560,"4563":4560,"4564":4560,"4565":4560,"4566":4560,"4567":4560,"4568":4560,"4569":4560,"4570":4560,"4571":4560,"4572":4560,"4573":4560,"4574":4560,"4575":4560,"4577":4576,"4578":4576,"4579":4576,"4580":4576,"4581":4576,"4582":4576,"4583":4576,"4584":4576,"4585":4576,"4586":4576,"4587":4576,"4588":4576,"4589":4576,"4590":4576,"4591":4576,"4593":4592,"4594":4592,"4595":4592,"4596":4592,"4597":4592,"4598":4592,"4599":4592,"4600":4592,"4601":4592,"4602":4592,"4603":4592,"4604":4592,"4605":4592,"4606":4592,"4607":4592,"4609":4608,"4610":4608,"4611":4608,"4612":4608,"4613":4608,"4614":4608,"4615":4608,"4616":4608,"4617":4608,"4618":4608,"4619":4608,"4620":4608,"4621":4608,"4622":4608,"4623":4608,"4625":4624,"4626":4624,"4627":4624,"4628":4624,"4629":4624,"4630":4624,"4631":4624,"4632":4624,"4633":4624,"4634":4624,"4635":4624,"4636":4624,"4637":4624,"4638":4624,"4639":4624,"4641":4640,"4642":4640,"4643":4640,"4644":4640,"4645":4640,"4646":4640,"4647":4640,"4648":4640,"4649":4640,"4650":4640,"4651":4640,"4652":4640,"4653":4640,"4654":4640,"4655":4640,"4657":4656,"4658":4656,"4659":4656,"4660":4656,"4661":4656,"4662":4656,"4663":4656,"4664":4656,"4665":4656,"4666":4656,"4667":4656,"4668":4656,"4669":4656,"4670":4656,"4671":4656,"4673":4672,"4674":4672,"4675":4672,"4676":4672,"4677":4672,"4678":4672,"4679":4672,"4680":4672,"4681":4672,"4682":4672,"4683":4672,"4684":4672,"4685":4672,"4686":4672,"4687":4672,"4689":4688,"4690":4688,"4691":4688,"4692":4688,"4693":4688,"4694":4688,"4695":4688,"4696":4688,"4697":4688,"4698":4688,"4699":4688,"4700":4688,"4701":4688,"4702":4688,"4703":4688,"4705":4704,"4706":4704,"4707":4704,"4708":4704,"4709":4704,"4710":4704,"4711":4704,"4712":4704,"4713":4704,"4714":4704,"4715":4704,"4716":4704,"4717":4704,"4718":4704,"4719":4704,"4721":4720,"4722":4720,"4723":4720,"4724":4720,"4725":4720,"4726":4720,"4727":4720,"4728":4720,"4729":4720,"4730":4720,"4731":4720,"4732":4720,"4733":4720,"4734":4720,"4735":4720,"4737":4736,"4738":4736,"4739":4736,"4740":4736,"4741":4736,"4742":4736,"4743":4736,"4744":4736,"4745":4736,"4746":4736,"4747":4736,"4748":4736,"4749":4736,"4750":4736,"4751":4736,"4753":4752,"4754":4752,"4755":4752,"4756":4752,"4757":4752,"4758":4752,"4759":4752,"4760":4752,"4761":4752,"4762":4752,"4763":4752,"4764":4752,"4765":4752,"4766":4752,"4767":4752,"4769":4768,"4770":4768,"4771":4768,"4772":4768,"4773":4768,"4774":4768,"4775":4768,"4776":4768,"4777":4768,"4778":4768,"4779":4768,"4780":4768,"4781":4768,"4782":4768,"4783":4768,"4785":4784,"4786":4784,"4787":4784,"4788":4784,"4789":4784,"4790":4784,"4791":4784,"4792":4784,"4793":4784,"4794":4784,"4795":4784,"4796":4784,"4797":4784,"4798":4784,"4799":4784,"4801":4800,"4802":4800,"4803":4800,"4804":4800,"4805":4800,"4806":4800,"4807":4800,"4808":4800,"4809":4800,"4810":4800,"4811":4800,"4812":4800,"4813":4800,"4814":4800,"4815":4800,"4817":4816,"4818":4816,"4819":4816,"4820":4816,"4821":4816,"4822":4816,"4823":4816,"4824":4816,"4825":4816,"4826":4816,"4827":4816,"4828":4816,"4829":4816,"4830":4816,"4831":4816,"4833":4832,"4834":4832,"4835":4832,"4836":4832,"4837":4832,"4838":4832,"4839":4832,"4840":4832,"4841":4832,"4842":4832,"4843":4832,"4844":4832,"4845":4832,"4846":4832,"4847":4832,"4849":4848,"4850":4848,"4851":4848,"4852":4848,"4853":4848,"4854":4848,"4855":4848,"4856":4848,"4857":4848,"4858":4848,"4859":4848,"4860":4848,"4861":4848,"4862":4848,"4863":4848,"4865":4864,"4866":4864,"4867":4864,"4868":4864,"4869":4864,"4870":4864,"4871":4864,"4872":4864,"4873":4864,"4874":4864,"4875":4864,"4876":4864,"4877":4864,"4878":4864,"4879":4864,"4881":4880,"4882":4880,"4883":4880,"4884":4880,"4885":4880,"4886":4880,"4887":4880,"4888":4880,"4889":4880,"4890":4880,"4891":4880,"4892":4880,"4893":4880,"4894":4880,"4895":4880,"4897":4896,"4898":4896,"4899":4896,"4900":4896,"4901":4896,"4902":4896,"4903":4896,"4904":4896,"4905":4896,"4906":4896,"4907":4896,"4908":4896,"4909":4896,"4910":4896,"4911":4896,"4913":4912,"4914":4912,"4915":4912,"4916":4912,"4917":4912,"4918":4912,"4919":4912,"4920":4912,"4921":4912,"4922":4912,"4923":4912,"4924":4912,"4925":4912,"4926":4912,"4927":4912,"4929":4928,"4930":4928,"4931":4928,"4932":4928,"4933":4928,"4934":4928,"4935":4928,"4936":4928,"4937":4928,"4938":4928,"4939":4928,"4940":4928,"4941":4928,"4942":4928,"4943":4928,"4945":4944,"4946":4944,"4947":4944,"4948":4944,"4949":4944,"4950":4944,"4951":4944,"4952":4944,"4953":4944,"4954":4944,"4955":4944,"4956":4944,"4957":4944,"4958":4944,"4959":4944,"4961":4960,"4962":4960,"4963":4960,"4964":4960,"4965":4960,"4966":4960,"4967":4960,"4968":4960,"4969":4960,"4970":4960,"4971":4960,"4972":4960,"4973":4960,"4974":4960,"4975":4960,"4977":4976,"4978":4976,"4979":4976,"4980":4976,"4981":4976,"4982":4976,"4983":4976,"4984":4976,"4985":4976,"4986":4976,"4987":4976,"4988":4976,"4989":4976,"4990":4976,"4991":4976,"4993":4992,"4994":4992,"4995":4992,"4996":4992,"4997":4992,"4998":4992,"4999":4992,"5000":4992,"5001":4992,"5002":4992,"5003":4992,"5004":4992,"5005":4992,"5006":4992,"5007":4992,"5009":5008,"5010":5008,"5011":5008,"5012":5008,"5013":5008,"5014":5008,"5015":5008,"5016":5008,"5017":5008,"5018":5008,"5019":5008,"5020":5008,"5021":5008,"5022":5008,"5023":5008,"5025":5024,"5026":5024,"5027":5024,"5028":5024,"5029":5024,"5030":5024,"5031":5024,"5032":5024,"5033":5024,"5034":5024,"5035":5024,"5036":5024,"5037":5024,"5038":5024,"5039":5024,"5041":5040,"5042":5040,"5043":5040,"5044":5040,"5045":5040,"5046":5040,"5047":5040,"5048":5040,"5049":5040,"5050":5040,"5051":5040,"5052":5040,"5053":5040,"5054":5040,"5055":5040,"5057":5056,"5058":5056,"5059":5056,"5060":5056,"5061":5056,"5062":5056,"5063":5056,"5064":5056,"5065":5056,"5066":5056,"5067":5056,"5068":5056,"5069":5056,"5070":5056,"5071":5056,"5073":5072,"5074":5072,"5075":5072,"5076":5072,"5077":5072,"5078":5072,"5079":5072,"5080":5072,"5081":5072,"5082":5072,"5083":5072,"5084":5072,"5085":5072,"5086":5072,"5087":5072,"5089":5088,"5090":5088,"5091":5088,"5092":5088,"5093":5088,"5094":5088,"5095":5088,"5096":5088,"5097":5088,"5098":5088,"5099":5088,"5100":5088,"5101":5088,"5102":5088,"5103":5088,"5105":5104,"5106":5104,"5107":5104,"5108":5104,"5109":5104,"5110":5104,"5111":5104,"5112":5104,"5113":5104,"5114":5104,"5115":5104,"5116":5104,"5117":5104,"5118":5104,"5119":5104,"5121":5120,"5122":5120,"5123":5120,"5124":5120,"5125":5120,"5126":5120,"5127":5120,"5128":5120,"5129":5120,"5130":5120,"5131":5120,"5132":5120,"5133":5120,"5134":5120,"5135":5120,"5137":5136,"5138":5136,"5139":5136,"5140":5136,"5141":5136,"5142":5136,"5143":5136,"5144":5136,"5145":5136,"5146":5136,"5147":5136,"5148":5136,"5149":5136,"5150":5136,"5151":5136,"5153":5152,"5154":5152,"5155":5152,"5156":5152,"5157":5152,"5158":5152,"5159":5152,"5160":5152,"5161":5152,"5162":5152,"5163":5152,"5164":5152,"5165":5152,"5166":5152,"5167":5152,"5169":5168,"5170":5168,"5171":5168,"5172":5168,"5173":5168,"5174":5168,"5175":5168,"5176":5168,"5177":5168,"5178":5168,"5179":5168,"5180":5168,"5181":5168,"5182":5168,"5183":5168,"5185":5184,"5186":5184,"5187":5184,"5188":5184,"5189":5184,"5190":5184,"5191":5184,"5192":5184,"5193":5184,"5194":5184,"5195":5184,"5196":5184,"5197":5184,"5198":5184,"5199":5184,"5201":5200,"5202":5200,"5203":5200,"5204":5200,"5205":5200,"5206":5200,"5207":5200,"5208":5200,"5209":5200,"5210":5200,"5211":5200,"5212":5200,"5213":5200,"5214":5200,"5215":5200,"5217":5216,"5218":5216,"5219":5216,"5220":5216,"5221":5216,"5222":5216,"5223":5216,"5224":5216,"5225":5216,"5226":5216,"5227":5216,"5228":5216,"5229":5216,"5230":5216,"5231":5216,"5233":5232,"5234":5232,"5235":5232,"5236":5232,"5237":5232,"5238":5232,"5239":5232,"5240":5232,"5241":5232,"5242":5232,"5243":5232,"5244":5232,"5245":5232,"5246":5232,"5247":5232,"5249":5248,"5250":5248,"5251":5248,"5252":5248,"5253":5248,"5254":5248,"5255":5248,"5256":5248,"5257":5248,"5258":5248,"5259":5248,"5260":5248,"5261":5248,"5262":5248,"5263":5248,"5265":5264,"5266":5264,"5267":5264,"5268":5264,"5269":5264,"5270":5264,"5271":5264,"5272":5264,"5273":5264,"5274":5264,"5275":5264,"5276":5264,"5277":5264,"5278":5264,"5279":5264,"5281":5280,"5282":5280,"5283":5280,"5284":5280,"5285":5280,"5286":5280,"5287":5280,"5288":5280,"5289":5280,"5290":5280,"5291":5280,"5292":5280,"5293":5280,"5294":5280,"5295":5280,"5297":5296,"5298":5296,"5299":5296,"5300":5296,"5301":5296,"5302":5296,"5303":5296,"5304":5296,"5305":5296,"5306":5296,"5307":5296,"5308":5296,"5309":5296,"5310":5296,"5311":5296,"5313":5312,"5314":5312,"5315":5312,"5316":5312,"5317":5312,"5318":5312,"5319":5312,"5320":5312,"5321":5312,"5322":5312,"5323":5312,"5324":5312,"5325":5312,"5326":5312,"5327":5312,"5329":5328,"5330":5328,"5331":5328,"5332":5328,"5333":5328,"5334":5328,"5335":5328,"5336":5328,"5337":5328,"5338":5328,"5339":5328,"5340":5328,"5341":5328,"5342":5328,"5343":5328,"5345":5344,"5346":5344,"5347":5344,"5348":5344,"5349":5344,"5350":5344,"5351":5344,"5352":5344,"5353":5344,"5354":5344,"5355":5344,"5356":5344,"5357":5344,"5358":5344,"5359":5344,"5361":5360,"5362":5360,"5363":5360,"5364":5360,"5365":5360,"5366":5360,"5367":5360,"5368":5360,"5369":5360,"5370":5360,"5371":5360,"5372":5360,"5373":5360,"5374":5360,"5375":5360,"5377":5376,"5378":5376,"5379":5376,"5380":5376,"5381":5376,"5382":5376,"5383":5376,"5384":5376,"5385":5376,"5386":5376,"5387":5376,"5388":5376,"5389":5376,"5390":5376,"5391":5376,"5393":5392,"5394":5392,"5395":5392,"5396":5392,"5397":5392,"5398":5392,"5399":5392,"5400":5392,"5401":5392,"5402":5392,"5403":5392,"5404":5392,"5405":5392,"5406":5392,"5407":5392,"5409":5408,"5410":5408,"5411":5408,"5412":5408,"5413":5408,"5414":5408,"5415":5408,"5416":5408,"5417":5408,"5418":5408,"5419":5408,"5420":5408,"5421":5408,"5422":5408,"5423":5408,"5425":5424,"5426":5424,"5427":5424,"5428":5424,"5429":5424,"5430":5424,"5431":5424,"5432":5424,"5433":5424,"5434":5424,"5435":5424,"5436":5424,"5437":5424,"5438":5424,"5439":5424,"5441":5440,"5442":5440,"5443":5440,"5444":5440,"5445":5440,"5446":5440,"5447":5440,"5448":5440,"5449":5440,"5450":5440,"5451":5440,"5452":5440,"5453":5440,"5454":5440,"5455":5440,"5457":5456,"5458":5456,"5459":5456,"5460":5456,"5461":5456,"5462":5456,"5463":5456,"5464":5456,"5465":5456,"5466":5456,"5467":5456,"5468":5456,"5469":5456,"5470":5456,"5471":5456,"5473":5472,"5474":5472,"5475":5472,"5476":5472,"5477":5472,"5478":5472,"5479":5472,"5480":5472,"5481":5472,"5482":5472,"5483":5472,"5484":5472,"5485":5472,"5486":5472,"5487":5472,"5489":5488,"5490":5488,"5491":5488,"5492":5488,"5493":5488,"5494":5488,"5495":5488,"5496":5488,"5497":5488,"5498":5488,"5499":5488,"5500":5488,"5501":5488,"5502":5488,"5503":5488,"5505":5504,"5506":5504,"5507":5504,"5508":5504,"5509":5504,"5510":5504,"5511":5504,"5512":5504,"5513":5504,"5514":5504,"5515":5504,"5516":5504,"5517":5504,"5518":5504,"5519":5504,"5521":5520,"5522":5520,"5523":5520,"5524":5520,"5525":5520,"5526":5520,"5527":5520,"5528":5520,"5529":5520,"5530":5520,"5531":5520,"5532":5520,"5533":5520,"5534":5520,"5535":5520,"5537":5536,"5538":5536,"5539":5536,"5540":5536,"5541":5536,"5542":5536,"5543":5536,"5544":5536,"5545":5536,"5546":5536,"5547":5536,"5548":5536,"5549":5536,"5550":5536,"5551":5536,"5553":5552,"5554":5552,"5555":5552,"5556":5552,"5557":5552,"5558":5552,"5559":5552,"5560":5552,"5561":5552,"5562":5552,"5563":5552,"5564":5552,"5565":5552,"5566":5552,"5567":5552,"5569":5568,"5570":5568,"5571":5568,"5572":5568,"5573":5568,"5574":5568,"5575":5568,"5576":5568,"5577":5568,"5578":5568,"5579":5568,"5580":5568,"5581":5568,"5582":5568,"5583":5568,"5585":5584,"5586":5584,"5587":5584,"5588":5584,"5589":5584,"5590":5584,"5591":5584,"5592":5584,"5593":5584,"5594":5584,"5595":5584,"5596":5584,"5597":5584,"5598":5584,"5599":5584,"5601":5600,"5602":5600,"5603":5600,"5604":5600,"5605":5600,"5606":5600,"5607":5600,"5608":5600,"5609":5600,"5610":5600,"5611":5600,"5612":5600,"5613":5600,"5614":5600,"5615":5600,"5617":5616,"5618":5616,"5619":5616,"5620":5616,"5621":5616,"5622":5616,"5623":5616,"5624":5616,"5625":5616,"5626":5616,"5627":5616,"5628":5616,"5629":5616,"5630":5616,"5631":5616,"5633":5632,"5634":5632,"5635":5632,"5636":5632,"5637":5632,"5638":5632,"5639":5632,"5640":5632,"5641":5632,"5642":5632,"5643":5632,"5644":5632,"5645":5632,"5646":5632,"5647":5632,"5649":5648,"5650":5648,"5651":5648,"5652":5648,"5653":5648,"5654":5648,"5655":5648,"5656":5648,"5657":5648,"5658":5648,"5659":5648,"5660":5648,"5661":5648,"5662":5648,"5663":5648,"5665":5664,"5666":5664,"5667":5664,"5668":5664,"5669":5664,"5670":5664,"5671":5664,"5672":5664,"5673":5664,"5674":5664,"5675":5664,"5676":5664,"5677":5664,"5678":5664,"5679":5664,"5681":5680,"5682":5680,"5683":5680,"5684":5680,"5685":5680,"5686":5680,"5687":5680,"5688":5680,"5689":5680,"5690":5680,"5691":5680,"5692":5680,"5693":5680,"5694":5680,"5695":5680,"5697":5696,"5698":5696,"5699":5696,"5700":5696,"5701":5696,"5702":5696,"5703":5696,"5704":5696,"5705":5696,"5706":5696,"5707":5696,"5708":5696,"5709":5696,"5710":5696,"5711":5696,"5713":5712,"5714":5712,"5715":5712,"5716":5712,"5717":5712,"5718":5712,"5719":5712,"5720":5712,"5721":5712,"5722":5712,"5723":5712,"5724":5712,"5725":5712,"5726":5712,"5727":5712,"5729":5728,"5730":5728,"5731":5728,"5732":5728,"5733":5728,"5734":5728,"5735":5728,"5736":5728,"5737":5728,"5738":5728,"5739":5728,"5740":5728,"5741":5728,"5742":5728,"5743":5728,"5745":5744,"5746":5744,"5747":5744,"5748":5744,"5749":5744,"5750":5744,"5751":5744,"5752":5744,"5753":5744,"5754":5744,"5755":5744,"5756":5744,"5757":5744,"5758":5744,"5759":5744,"5761":5760,"5762":5760,"5763":5760,"5764":5760,"5765":5760,"5766":5760,"5767":5760,"5768":5760,"5769":5760,"5770":5760,"5771":5760,"5772":5760,"5773":5760,"5774":5760,"5775":5760,"5777":5776,"5778":5776,"5779":5776,"5780":5776,"5781":5776,"5782":5776,"5783":5776,"5784":5776,"5785":5776,"5786":5776,"5787":5776,"5788":5776,"5789":5776,"5790":5776,"5791":5776,"5793":5792,"5794":5792,"5795":5792,"5796":5792,"5797":5792,"5798":5792,"5799":5792,"5800":5792,"5801":5792,"5802":5792,"5803":5792,"5804":5792,"5805":5792,"5806":5792,"5807":5792,"5809":5808,"5810":5808,"5811":5808,"5812":5808,"5813":5808,"5814":5808,"5815":5808,"5816":5808,"5817":5808,"5818":5808,"5819":5808,"5820":5808,"5821":5808,"5822":5808,"5823":5808,"5825":5824,"5826":5824,"5827":5824,"5828":5824,"5829":5824,"5830":5824,"5831":5824,"5832":5824,"5833":5824,"5834":5824,"5835":5824,"5836":5824,"5837":5824,"5838":5824,"5839":5824,"5841":5840,"5842":5840,"5843":5840,"5844":5840,"5845":5840,"5846":5840,"5847":5840,"5848":5840,"5849":5840,"5850":5840,"5851":5840,"5852":5840,"5853":5840,"5854":5840,"5855":5840,"5857":5856,"5858":5856,"5859":5856,"5860":5856,"5861":5856,"5862":5856,"5863":5856,"5864":5856,"5865":5856,"5866":5856,"5867":5856,"5868":5856,"5869":5856,"5870":5856,"5871":5856,"5873":5872,"5874":5872,"5875":5872,"5876":5872,"5877":5872,"5878":5872,"5879":5872,"5880":5872,"5881":5872,"5882":5872,"5883":5872,"5884":5872,"5885":5872,"5886":5872,"5887":5872,"5889":5888,"5890":5888,"5891":5888,"5892":5888,"5893":5888,"5894":5888,"5895":5888,"5896":5888,"5897":5888,"5898":5888,"5899":5888,"5900":5888,"5901":5888,"5902":5888,"5903":5888,"5905":5904,"5906":5904,"5907":5904,"5908":5904,"5909":5904,"5910":5904,"5911":5904,"5912":5904,"5913":5904,"5914":5904,"5915":5904,"5916":5904,"5917":5904,"5918":5904,"5919":5904,"5921":5920,"5922":5920,"5923":5920,"5924":5920,"5925":5920,"5926":5920,"5927":5920,"5928":5920,"5929":5920,"5930":5920,"5931":5920,"5932":5920,"5933":5920,"5934":5920,"5935":5920,"5937":5936,"5938":5936,"5939":5936,"5940":5936,"5941":5936,"5942":5936,"5943":5936,"5944":5936,"5945":5936,"5946":5936,"5947":5936,"5948":5936,"5949":5936,"5950":5936,"5951":5936,"5953":5952,"5954":5952,"5955":5952,"5956":5952,"5957":5952,"5958":5952,"5959":5952,"5960":5952,"5961":5952,"5962":5952,"5963":5952,"5964":5952,"5965":5952,"5966":5952,"5967":5952,"5969":5968,"5970":5968,"5971":5968,"5972":5968,"5973":5968,"5974":5968,"5975":5968,"5976":5968,"5977":5968,"5978":5968,"5979":5968,"5980":5968,"5981":5968,"5982":5968,"5983":5968,"5985":5984,"5986":5984,"5987":5984,"5988":5984,"5989":5984,"5990":5984,"5991":5984,"5992":5984,"5993":5984,"5994":5984,"5995":5984,"5996":5984,"5997":5984,"5998":5984,"5999":5984,"6001":6000,"6002":6000,"6003":6000,"6004":6000,"6005":6000,"6006":6000,"6007":6000,"6008":6000,"6009":6000,"6010":6000,"6011":6000,"6012":6000,"6013":6000,"6014":6000,"6015":6000,"6017":6016,"6018":6016,"6019":6016,"6020":6016,"6021":6016,"6022":6016,"6023":6016,"6024":6016,"6025":6016,"6026":6016,"6027":6016,"6028":6016,"6029":6016,"6030":6016,"6031":6016,"6033":6032,"6034":6032,"6035":6032,"6036":6032,"6037":6032,"6038":6032,"6039":6032,"6040":6032,"6041":6032,"6042":6032,"6043":6032,"6044":6032,"6045":6032,"6046":6032,"6047":6032,"6049":6048,"6050":6048,"6051":6048,"6052":6048,"6053":6048,"6054":6048,"6055":6048,"6056":6048,"6057":6048,"6058":6048,"6059":6048,"6060":6048,"6061":6048,"6062":6048,"6063":6048,"6065":6064,"6066":6064,"6067":6064,"6068":6064,"6069":6064,"6070":6064,"6071":6064,"6072":6064,"6073":6064,"6074":6064,"6075":6064,"6076":6064,"6077":6064,"6078":6064,"6079":6064,"6081":6080,"6082":6080,"6083":6080,"6084":6080,"6085":6080,"6086":6080,"6087":6080,"6088":6080,"6089":6080,"6090":6080,"6091":6080,"6092":6080,"6093":6080,"6094":6080,"6095":6080,"6097":6096,"6098":6096,"6099":6096,"6100":6096,"6101":6096,"6102":6096,"6103":6096,"6104":6096,"6105":6096,"6106":6096,"6107":6096,"6108":6096,"6109":6096,"6110":6096,"6111":6096,"6113":6112,"6114":6112,"6115":6112,"6116":6112,"6117":6112,"6118":6112,"6119":6112,"6120":6112,"6121":6112,"6122":6112,"6123":6112,"6124":6112,"6125":6112,"6126":6112,"6127":6112,"6129":6128,"6130":6128,"6131":6128,"6132":6128,"6133":6128,"6134":6128,"6135":6128,"6136":6128,"6137":6128,"6138":6128,"6139":6128,"6140":6128,"6141":6128,"6142":6128,"6143":6128,"6145":6144,"6146":6144,"6147":6144,"6148":6144,"6149":6144,"6150":6144,"6151":6144,"6152":6144,"6153":6144,"6154":6144,"6155":6144,"6156":6144,"6157":6144,"6158":6144,"6159":6144,"6181":6176,"6182":6176,"6183":6176,"6184":6176,"6185":6176,"6186":6176,"6187":6176,"6188":6176,"6189":6176,"6190":6176,"6191":6176,"6197":6192,"6198":6192,"6199":6192,"6205":6192,"6206":6192,"6207":6192,"6213":6208,"6214":6208,"6215":6208,"6221":6208,"6222":6208,"6223":6208,"6229":6208,"6230":6208,"6231":6208,"6237":6208,"6238":6208,"6239":6208,"6273":6248,"6275":6248,"6277":6248,"6279":6248,"6281":6248,"6283":6248,"6285":6248,"6287":6248,"6305":6304,"6306":6304,"6307":6304,"6308":6304,"6309":6304,"6310":6304,"6311":6304,"6312":6304,"6313":6304,"6314":6304,"6315":6304,"6316":6304,"6317":6304,"6318":6304,"6319":6304,"6326":6320,"6327":6320,"6334":6320,"6335":6320,"6342":6336,"6343":6336,"6350":6336,"6351":6336,"6358":6352,"6359":6352,"6366":6352,"6367":6352,"6374":6368,"6375":6368,"6382":6368,"6383":6368,"6390":6384,"6391":6384,"6398":6384,"6399":6384,"6482":6480,"6483":6480,"6484":6480,"6485":6480,"6486":6480,"6487":6480,"6488":6480,"6489":6480,"6490":6480,"6491":6480,"6492":6480,"6493":6480,"6494":6480,"6495":6480,"6498":6496,"6499":6496,"6500":6496,"6501":6496,"6502":6496,"6503":6496,"6504":6496,"6505":6496,"6506":6496,"6507":6496,"6508":6496,"6509":6496,"6510":6496,"6511":6496,"6514":6512,"6515":6512,"6516":6512,"6517":6512,"6518":6512,"6519":6512,"6520":6512,"6521":6512,"6522":6512,"6523":6512,"6524":6512,"6525":6512,"6526":6512,"6527":6512,"6530":6528,"6531":6528,"6532":6528,"6533":6528,"6534":6528,"6535":6528,"6536":6528,"6537":6528,"6538":6528,"6539":6528,"6540":6528,"6541":6528,"6542":6528,"6543":6528,"6546":6544,"6547":6544,"6548":6544,"6549":6544,"6550":6544,"6551":6544,"6552":6544,"6553":6544,"6554":6544,"6555":6544,"6556":6544,"6557":6544,"6558":6544,"6559":6544,"6564":6562,"6565":6562,"6566":6562,"6567":6562,"6568":6562,"6569":6562,"6570":6562,"6571":6562,"6572":6562,"6573":6562,"6574":6562,"6575":6562,"6584":6580,"6585":6580,"6586":6580,"6587":6580,"6588":6580,"6589":6580,"6590":6580,"6591":6580,"6657":6656,"6658":6656,"6659":6656,"6660":6656,"6661":6656,"6662":6656,"6663":6656,"6664":6656,"6665":6656,"6666":6656,"6667":6656,"6668":6656,"6669":6656,"6670":6656,"6671":6656,"6694":6688,"6695":6688,"6702":6688,"6703":6688,"6705":6704,"6706":6704,"6707":6704,"6708":6704,"6709":6704,"6710":6704,"6711":6704,"6713":6704,"6714":6704,"6715":6704,"6716":6704,"6717":6704,"6718":6704,"6719":6704,"6760":6752,"6761":6753,"6762":6754,"6763":6755,"6764":6756,"6765":6757,"6766":6758,"6767":6759,"6776":6768,"6777":6769,"6778":6770,"6779":6771,"6780":6772,"6792":6787,"6793":6787,"6794":6787,"6795":6787,"6796":6787,"6797":6787,"6798":6787,"6799":6787,"6808":6803,"6809":6803,"6810":6803,"6811":6803,"6812":6803,"6813":6803,"6814":6803,"6815":6803,"6824":6819,"6825":6819,"6826":6819,"6827":6819,"6828":6819,"6829":6819,"6830":6819,"6831":6819,"6840":6835,"6841":6835,"6842":6835,"6843":6835,"6844":6835,"6845":6835,"6846":6835,"6847":6835,"6856":6851,"6857":6851,"6858":6851,"6859":6851,"6860":6851,"6861":6851,"6862":6851,"6863":6851,"6872":6867,"6873":6867,"6874":6867,"6875":6867,"6876":6867,"6877":6867,"6878":6867,"6879":6867,"6888":6883,"6889":6883,"6890":6883,"6891":6883,"6892":6883,"6893":6883,"6894":6883,"6895":6883,"6904":6899,"6905":6899,"6906":6899,"6907":6899,"6908":6899,"6909":6899,"6910":6899,"6911":6899,"6920":6915,"6921":6915,"6922":6915,"6923":6915,"6924":6915,"6925":6915,"6926":6915,"6927":6915,"6936":6931,"6937":6931,"6938":6931,"6939":6931,"6940":6931,"6941":6931,"6942":6931,"6943":6931,"6952":6947,"6953":6947,"6954":6947,"6955":6947,"6956":6947,"6957":6947,"6958":6947,"6959":6947,"6968":6963,"6969":6963,"6970":6963,"6971":6963,"6972":6963,"6973":6963,"6974":6963,"6975":6963,"6992":6994,"6993":6994,"6998":6994,"6999":6994,"7000":6994,"7001":6994,"7002":6994,"7003":6994,"7004":6994,"7005":6994,"7006":6994,"7007":6994,"7009":7008,"7010":7008,"7011":7008,"7012":7008,"7013":7008,"7014":7008,"7015":7008,"7016":7008,"7017":7008,"7018":7008,"7019":7008,"7020":7008,"7021":7008,"7022":7008,"7023":7008,"7032":7027,"7033":7027,"7034":7027,"7035":7027,"7036":7027,"7037":7027,"7038":7027,"7039":7027,"7048":7043,"7049":7043,"7050":7043,"7051":7043,"7052":7043,"7053":7043,"7054":7043,"7055":7043,"7072":7074,"7073":7074,"7078":7074,"7079":7074,"7080":7074,"7081":7074,"7082":7074,"7083":7074,"7084":7074,"7085":7074,"7086":7074,"7087":7074,"7104":7106,"7105":7106,"7110":7106,"7111":7106,"7112":7106,"7113":7106,"7114":7106,"7115":7106,"7116":7106,"7117":7106,"7118":7106,"7119":7106,"7136":7138,"7137":7138,"7142":7138,"7143":7138,"7144":7138,"7145":7138,"7146":7138,"7147":7138,"7148":7138,"7149":7138,"7150":7138,"7151":7138,"7168":7170,"7169":7170,"7174":7170,"7175":7170,"7176":7170,"7177":7170,"7178":7170,"7179":7170,"7180":7170,"7181":7170,"7182":7170,"7183":7170,"7216":7218,"7217":7218,"7222":7218,"7223":7218,"7224":7218,"7225":7218,"7226":7218,"7227":7218,"7228":7218,"7229":7218,"7230":7218,"7231":7218,"7248":7250,"7249":7250,"7254":7250,"7255":7250,"7256":7250,"7257":7250,"7258":7250,"7259":7250,"7260":7250,"7261":7250,"7262":7250,"7263":7250,"7264":7250,"7265":7250,"7270":7250,"7271":7250,"7272":7250,"7273":7250,"7274":7250,"7275":7250,"7276":7250,"7277":7250,"7278":7250,"7279":7250,"7297":7296,"7298":7296,"7299":7296,"7300":7296,"7301":7296,"7302":7296,"7303":7296,"7304":7296,"7305":7296,"7306":7296,"7307":7296,"7308":7296,"7309":7296,"7310":7296,"7311":7296,"7334":7328,"7335":7328,"7342":7328,"7343":7328,"7348":7346,"7349":7346,"7350":7346,"7351":7346,"7352":7346,"7353":7346,"7354":7346,"7355":7346,"7356":7346,"7357":7346,"7358":7346,"7359":7346,"7396":7392,"7397":7392,"7398":7392,"7399":7392,"7400":7392,"7401":7392,"7402":7392,"7403":7392,"7404":7392,"7405":7392,"7406":7392,"7407":7392,"7410":7408,"7411":7408,"7412":7408,"7413":7408,"7414":7408,"7415":7408,"7416":7408,"7417":7408,"7418":7408,"7419":7408,"7420":7408,"7421":7408,"7422":7408,"7423":7408,"7504":7218,"7505":7218,"7510":7218,"7511":7218,"7512":7218,"7513":7218,"7514":7218,"7515":7218,"7516":7218,"7517":7218,"7518":7218,"7519":7218}} \ No newline at end of file +{"knownStates":{"0":"Air","16":"Stone","17":"Granite","18":"Polished Granite","19":"Diorite","20":"Polished Diorite","21":"Andesite","22":"Polished Andesite","32":"Grass","48":"Dirt","49":"Dirt","64":"Cobblestone","80":"Oak Planks","81":"Spruce Planks","82":"Birch Planks","83":"Jungle Planks","84":"Acacia Planks","85":"Dark Oak Planks","96":"Oak Sapling","97":"Spruce Sapling","98":"Birch Sapling","99":"Jungle Sapling","100":"Acacia Sapling","101":"Dark Oak Sapling","104":"Oak Sapling","105":"Spruce Sapling","106":"Birch Sapling","107":"Jungle Sapling","108":"Acacia Sapling","109":"Dark Oak Sapling","112":"Bedrock","113":"Bedrock","128":"Water","129":"Water","130":"Water","131":"Water","132":"Water","133":"Water","134":"Water","135":"Water","136":"Water","137":"Water","138":"Water","139":"Water","140":"Water","141":"Water","142":"Water","143":"Water","144":"Water","145":"Water","146":"Water","147":"Water","148":"Water","149":"Water","150":"Water","151":"Water","152":"Water","153":"Water","154":"Water","155":"Water","156":"Water","157":"Water","158":"Water","159":"Water","160":"Lava","161":"Lava","162":"Lava","163":"Lava","164":"Lava","165":"Lava","166":"Lava","167":"Lava","168":"Lava","169":"Lava","170":"Lava","171":"Lava","172":"Lava","173":"Lava","174":"Lava","175":"Lava","176":"Lava","177":"Lava","178":"Lava","179":"Lava","180":"Lava","181":"Lava","182":"Lava","183":"Lava","184":"Lava","185":"Lava","186":"Lava","187":"Lava","188":"Lava","189":"Lava","190":"Lava","191":"Lava","192":"Sand","193":"Red Sand","208":"Gravel","224":"Gold Ore","240":"Iron Ore","256":"Coal Ore","272":"Oak Log","273":"Spruce Log","274":"Birch Log","275":"Jungle Log","276":"Oak Log","277":"Spruce Log","278":"Birch Log","279":"Jungle Log","280":"Oak Log","281":"Spruce Log","282":"Birch Log","283":"Jungle Log","288":"Oak Leaves","289":"Spruce Leaves","290":"Birch Leaves","291":"Jungle Leaves","292":"Oak Leaves","293":"Spruce Leaves","294":"Birch Leaves","295":"Jungle Leaves","296":"Oak Leaves","297":"Spruce Leaves","298":"Birch Leaves","299":"Jungle Leaves","300":"Oak Leaves","301":"Spruce Leaves","302":"Birch Leaves","303":"Jungle Leaves","304":"Sponge","305":"Sponge","320":"Glass","336":"Lapis Lazuli Ore","352":"Lapis Lazuli Block","384":"Sandstone","385":"Chiseled Sandstone","386":"Cut Sandstone","387":"Smooth Sandstone","400":"Note Block","416":"Bed Block","417":"Bed Block","418":"Bed Block","419":"Bed Block","420":"Bed Block","421":"Bed Block","422":"Bed Block","423":"Bed Block","424":"Bed Block","425":"Bed Block","426":"Bed Block","427":"Bed Block","428":"Bed Block","429":"Bed Block","430":"Bed Block","431":"Bed Block","432":"Powered Rail","433":"Powered Rail","434":"Powered Rail","435":"Powered Rail","436":"Powered Rail","437":"Powered Rail","440":"Powered Rail","441":"Powered Rail","442":"Powered Rail","443":"Powered Rail","444":"Powered Rail","445":"Powered Rail","448":"Detector Rail","449":"Detector Rail","450":"Detector Rail","451":"Detector Rail","452":"Detector Rail","453":"Detector Rail","456":"Detector Rail","457":"Detector Rail","458":"Detector Rail","459":"Detector Rail","460":"Detector Rail","461":"Detector Rail","480":"Cobweb","497":"Tall Grass","498":"Fern","512":"Dead Bush","560":"Wool","561":"Wool","562":"Wool","563":"Wool","564":"Wool","565":"Wool","566":"Wool","567":"Wool","568":"Wool","569":"Wool","570":"Wool","571":"Wool","572":"Wool","573":"Wool","574":"Wool","575":"Wool","576":"???","592":"Dandelion","608":"Poppy","609":"Blue Orchid","610":"Allium","611":"Azure Bluet","612":"Red Tulip","613":"Orange Tulip","614":"White Tulip","615":"Pink Tulip","616":"Oxeye Daisy","617":"Cornflower","618":"Lily of the Valley","624":"Brown Mushroom","640":"Red Mushroom","656":"Gold Block","672":"Iron Block","688":"Smooth Stone Slab","689":"Sandstone Slab","690":"Fake Wooden Slab","691":"Cobblestone Slab","692":"Brick Slab","693":"Stone Brick Slab","694":"Quartz Slab","695":"Nether Brick Slab","704":"Smooth Stone Slab","705":"Sandstone Slab","706":"Fake Wooden Slab","707":"Cobblestone Slab","708":"Brick Slab","709":"Stone Brick Slab","710":"Quartz Slab","711":"Nether Brick Slab","712":"Smooth Stone Slab","713":"Sandstone Slab","714":"Fake Wooden Slab","715":"Cobblestone Slab","716":"Brick Slab","717":"Stone Brick Slab","718":"Quartz Slab","719":"Nether Brick Slab","720":"Bricks","736":"TNT","737":"TNT","738":"TNT","739":"TNT","752":"Bookshelf","768":"Mossy Cobblestone","784":"Obsidian","801":"Torch","802":"Torch","803":"Torch","804":"Torch","805":"Torch","816":"Fire Block","817":"Fire Block","818":"Fire Block","819":"Fire Block","820":"Fire Block","821":"Fire Block","822":"Fire Block","823":"Fire Block","824":"Fire Block","825":"Fire Block","826":"Fire Block","827":"Fire Block","828":"Fire Block","829":"Fire Block","830":"Fire Block","831":"Fire Block","832":"Monster Spawner","848":"Oak Stairs","849":"Oak Stairs","850":"Oak Stairs","851":"Oak Stairs","852":"Oak Stairs","853":"Oak Stairs","854":"Oak Stairs","855":"Oak Stairs","866":"Chest","867":"Chest","868":"Chest","869":"Chest","880":"Redstone","881":"Redstone","882":"Redstone","883":"Redstone","884":"Redstone","885":"Redstone","886":"Redstone","887":"Redstone","888":"Redstone","889":"Redstone","890":"Redstone","891":"Redstone","892":"Redstone","893":"Redstone","894":"Redstone","895":"Redstone","896":"Diamond Ore","912":"Diamond Block","928":"Crafting Table","944":"Wheat Block","945":"Wheat Block","946":"Wheat Block","947":"Wheat Block","948":"Wheat Block","949":"Wheat Block","950":"Wheat Block","951":"Wheat Block","960":"Farmland","961":"Farmland","962":"Farmland","963":"Farmland","964":"Farmland","965":"Farmland","966":"Farmland","967":"Farmland","978":"Furnace","979":"Furnace","980":"Furnace","981":"Furnace","994":"Furnace","995":"Furnace","996":"Furnace","997":"Furnace","1008":"Oak Sign","1009":"Oak Sign","1010":"Oak Sign","1011":"Oak Sign","1012":"Oak Sign","1013":"Oak Sign","1014":"Oak Sign","1015":"Oak Sign","1016":"Oak Sign","1017":"Oak Sign","1018":"Oak Sign","1019":"Oak Sign","1020":"Oak Sign","1021":"Oak Sign","1022":"Oak Sign","1023":"Oak Sign","1024":"Oak Door","1025":"Oak Door","1026":"Oak Door","1027":"Oak Door","1028":"Oak Door","1029":"Oak Door","1030":"Oak Door","1031":"Oak Door","1032":"Oak Door","1033":"Oak Door","1034":"Oak Door","1035":"Oak Door","1042":"Ladder","1043":"Ladder","1044":"Ladder","1045":"Ladder","1056":"Rail","1057":"Rail","1058":"Rail","1059":"Rail","1060":"Rail","1061":"Rail","1062":"Rail","1063":"Rail","1064":"Rail","1065":"Rail","1072":"Cobblestone Stairs","1073":"Cobblestone Stairs","1074":"Cobblestone Stairs","1075":"Cobblestone Stairs","1076":"Cobblestone Stairs","1077":"Cobblestone Stairs","1078":"Cobblestone Stairs","1079":"Cobblestone Stairs","1090":"Oak Wall Sign","1091":"Oak Wall Sign","1092":"Oak Wall Sign","1093":"Oak Wall Sign","1104":"Lever","1105":"Lever","1106":"Lever","1107":"Lever","1108":"Lever","1109":"Lever","1110":"Lever","1111":"Lever","1112":"Lever","1113":"Lever","1114":"Lever","1115":"Lever","1116":"Lever","1117":"Lever","1118":"Lever","1119":"Lever","1120":"Stone Pressure Plate","1121":"Stone Pressure Plate","1136":"Iron Door","1137":"Iron Door","1138":"Iron Door","1139":"Iron Door","1140":"Iron Door","1141":"Iron Door","1142":"Iron Door","1143":"Iron Door","1144":"Iron Door","1145":"Iron Door","1146":"Iron Door","1147":"Iron Door","1152":"Oak Pressure Plate","1153":"Oak Pressure Plate","1168":"Redstone Ore","1184":"Redstone Ore","1201":"Redstone Torch","1202":"Redstone Torch","1203":"Redstone Torch","1204":"Redstone Torch","1205":"Redstone Torch","1217":"Redstone Torch","1218":"Redstone Torch","1219":"Redstone Torch","1220":"Redstone Torch","1221":"Redstone Torch","1232":"Stone Button","1233":"Stone Button","1234":"Stone Button","1235":"Stone Button","1236":"Stone Button","1237":"Stone Button","1240":"Stone Button","1241":"Stone Button","1242":"Stone Button","1243":"Stone Button","1244":"Stone Button","1245":"Stone Button","1248":"Snow Layer","1249":"Snow Layer","1250":"Snow Layer","1251":"Snow Layer","1252":"Snow Layer","1253":"Snow Layer","1254":"Snow Layer","1255":"Snow Layer","1264":"Ice","1280":"Snow Block","1296":"Cactus","1297":"Cactus","1298":"Cactus","1299":"Cactus","1300":"Cactus","1301":"Cactus","1302":"Cactus","1303":"Cactus","1304":"Cactus","1305":"Cactus","1306":"Cactus","1307":"Cactus","1308":"Cactus","1309":"Cactus","1310":"Cactus","1311":"Cactus","1312":"Clay Block","1328":"Sugarcane","1329":"Sugarcane","1330":"Sugarcane","1331":"Sugarcane","1332":"Sugarcane","1333":"Sugarcane","1334":"Sugarcane","1335":"Sugarcane","1336":"Sugarcane","1337":"Sugarcane","1338":"Sugarcane","1339":"Sugarcane","1340":"Sugarcane","1341":"Sugarcane","1342":"Sugarcane","1343":"Sugarcane","1344":"Jukebox","1360":"Oak Fence","1361":"Spruce Fence","1362":"Birch Fence","1363":"Jungle Fence","1364":"Acacia Fence","1365":"Dark Oak Fence","1376":"Pumpkin","1392":"Netherrack","1408":"Soul Sand","1424":"Glowstone","1441":"Nether Portal","1442":"Nether Portal","1456":"Jack o'Lantern","1457":"Jack o'Lantern","1458":"Jack o'Lantern","1459":"Jack o'Lantern","1472":"Cake","1473":"Cake","1474":"Cake","1475":"Cake","1476":"Cake","1477":"Cake","1478":"Cake","1488":"Redstone Repeater","1489":"Redstone Repeater","1490":"Redstone Repeater","1491":"Redstone Repeater","1492":"Redstone Repeater","1493":"Redstone Repeater","1494":"Redstone Repeater","1495":"Redstone Repeater","1496":"Redstone Repeater","1497":"Redstone Repeater","1498":"Redstone Repeater","1499":"Redstone Repeater","1500":"Redstone Repeater","1501":"Redstone Repeater","1502":"Redstone Repeater","1503":"Redstone Repeater","1504":"Redstone Repeater","1505":"Redstone Repeater","1506":"Redstone Repeater","1507":"Redstone Repeater","1508":"Redstone Repeater","1509":"Redstone Repeater","1510":"Redstone Repeater","1511":"Redstone Repeater","1512":"Redstone Repeater","1513":"Redstone Repeater","1514":"Redstone Repeater","1515":"Redstone Repeater","1516":"Redstone Repeater","1517":"Redstone Repeater","1518":"Redstone Repeater","1519":"Redstone Repeater","1520":"Invisible Bedrock","1536":"Oak Trapdoor","1537":"Oak Trapdoor","1538":"Oak Trapdoor","1539":"Oak Trapdoor","1540":"Oak Trapdoor","1541":"Oak Trapdoor","1542":"Oak Trapdoor","1543":"Oak Trapdoor","1544":"Oak Trapdoor","1545":"Oak Trapdoor","1546":"Oak Trapdoor","1547":"Oak Trapdoor","1548":"Oak Trapdoor","1549":"Oak Trapdoor","1550":"Oak Trapdoor","1551":"Oak Trapdoor","1552":"Infested Stone","1553":"Infested Cobblestone","1554":"Infested Stone Brick","1555":"Infested Mossy Stone Brick","1556":"Infested Cracked Stone Brick","1557":"Infested Chiseled Stone Brick","1568":"Stone Bricks","1569":"Mossy Stone Bricks","1570":"Cracked Stone Bricks","1571":"Chiseled Stone Bricks","1584":"Brown Mushroom Block","1585":"Brown Mushroom Block","1586":"Brown Mushroom Block","1587":"Brown Mushroom Block","1588":"Brown Mushroom Block","1589":"Brown Mushroom Block","1590":"Brown Mushroom Block","1591":"Brown Mushroom Block","1592":"Brown Mushroom Block","1593":"Brown Mushroom Block","1594":"Mushroom Stem","1598":"Brown Mushroom Block","1599":"All Sided Mushroom Stem","1600":"Red Mushroom Block","1601":"Red Mushroom Block","1602":"Red Mushroom Block","1603":"Red Mushroom Block","1604":"Red Mushroom Block","1605":"Red Mushroom Block","1606":"Red Mushroom Block","1607":"Red Mushroom Block","1608":"Red Mushroom Block","1609":"Red Mushroom Block","1614":"Red Mushroom Block","1616":"Iron Bars","1632":"Glass Pane","1648":"Melon Block","1664":"Pumpkin Stem","1665":"Pumpkin Stem","1666":"Pumpkin Stem","1667":"Pumpkin Stem","1668":"Pumpkin Stem","1669":"Pumpkin Stem","1670":"Pumpkin Stem","1671":"Pumpkin Stem","1680":"Melon Stem","1681":"Melon Stem","1682":"Melon Stem","1683":"Melon Stem","1684":"Melon Stem","1685":"Melon Stem","1686":"Melon Stem","1687":"Melon Stem","1696":"Vines","1697":"Vines","1698":"Vines","1699":"Vines","1700":"Vines","1701":"Vines","1702":"Vines","1703":"Vines","1704":"Vines","1705":"Vines","1706":"Vines","1707":"Vines","1708":"Vines","1709":"Vines","1710":"Vines","1711":"Vines","1712":"Oak Fence Gate","1713":"Oak Fence Gate","1714":"Oak Fence Gate","1715":"Oak Fence Gate","1716":"Oak Fence Gate","1717":"Oak Fence Gate","1718":"Oak Fence Gate","1719":"Oak Fence Gate","1720":"Oak Fence Gate","1721":"Oak Fence Gate","1722":"Oak Fence Gate","1723":"Oak Fence Gate","1724":"Oak Fence Gate","1725":"Oak Fence Gate","1726":"Oak Fence Gate","1727":"Oak Fence Gate","1728":"Brick Stairs","1729":"Brick Stairs","1730":"Brick Stairs","1731":"Brick Stairs","1732":"Brick Stairs","1733":"Brick Stairs","1734":"Brick Stairs","1735":"Brick Stairs","1744":"Stone Brick Stairs","1745":"Stone Brick Stairs","1746":"Stone Brick Stairs","1747":"Stone Brick Stairs","1748":"Stone Brick Stairs","1749":"Stone Brick Stairs","1750":"Stone Brick Stairs","1751":"Stone Brick Stairs","1760":"Mycelium","1776":"Lily Pad","1792":"Nether Bricks","1808":"Nether Brick Fence","1824":"Nether Brick Stairs","1825":"Nether Brick Stairs","1826":"Nether Brick Stairs","1827":"Nether Brick Stairs","1828":"Nether Brick Stairs","1829":"Nether Brick Stairs","1830":"Nether Brick Stairs","1831":"Nether Brick Stairs","1840":"Nether Wart","1841":"Nether Wart","1842":"Nether Wart","1843":"Nether Wart","1856":"Enchanting Table","1872":"Brewing Stand","1873":"Brewing Stand","1874":"Brewing Stand","1875":"Brewing Stand","1876":"Brewing Stand","1877":"Brewing Stand","1878":"Brewing Stand","1879":"Brewing Stand","1920":"End Portal Frame","1921":"End Portal Frame","1922":"End Portal Frame","1923":"End Portal Frame","1924":"End Portal Frame","1925":"End Portal Frame","1926":"End Portal Frame","1927":"End Portal Frame","1936":"End Stone","1952":"Dragon Egg","1968":"Redstone Lamp","1984":"Redstone Lamp","2016":"Activator Rail","2017":"Activator Rail","2018":"Activator Rail","2019":"Activator Rail","2020":"Activator Rail","2021":"Activator Rail","2024":"Activator Rail","2025":"Activator Rail","2026":"Activator Rail","2027":"Activator Rail","2028":"Activator Rail","2029":"Activator Rail","2032":"Cocoa Block","2033":"Cocoa Block","2034":"Cocoa Block","2035":"Cocoa Block","2036":"Cocoa Block","2037":"Cocoa Block","2038":"Cocoa Block","2039":"Cocoa Block","2040":"Cocoa Block","2041":"Cocoa Block","2042":"Cocoa Block","2043":"Cocoa Block","2048":"Sandstone Stairs","2049":"Sandstone Stairs","2050":"Sandstone Stairs","2051":"Sandstone Stairs","2052":"Sandstone Stairs","2053":"Sandstone Stairs","2054":"Sandstone Stairs","2055":"Sandstone Stairs","2064":"Emerald Ore","2082":"Ender Chest","2083":"Ender Chest","2084":"Ender Chest","2085":"Ender Chest","2096":"Tripwire Hook","2097":"Tripwire Hook","2098":"Tripwire Hook","2099":"Tripwire Hook","2100":"Tripwire Hook","2101":"Tripwire Hook","2102":"Tripwire Hook","2103":"Tripwire Hook","2104":"Tripwire Hook","2105":"Tripwire Hook","2106":"Tripwire Hook","2107":"Tripwire Hook","2108":"Tripwire Hook","2109":"Tripwire Hook","2110":"Tripwire Hook","2111":"Tripwire Hook","2112":"Tripwire","2113":"Tripwire","2114":"Tripwire","2115":"Tripwire","2116":"Tripwire","2117":"Tripwire","2118":"Tripwire","2119":"Tripwire","2120":"Tripwire","2121":"Tripwire","2122":"Tripwire","2123":"Tripwire","2124":"Tripwire","2125":"Tripwire","2126":"Tripwire","2127":"Tripwire","2128":"Emerald Block","2144":"Spruce Stairs","2145":"Spruce Stairs","2146":"Spruce Stairs","2147":"Spruce Stairs","2148":"Spruce Stairs","2149":"Spruce Stairs","2150":"Spruce Stairs","2151":"Spruce Stairs","2160":"Birch Stairs","2161":"Birch Stairs","2162":"Birch Stairs","2163":"Birch Stairs","2164":"Birch Stairs","2165":"Birch Stairs","2166":"Birch Stairs","2167":"Birch Stairs","2176":"Jungle Stairs","2177":"Jungle Stairs","2178":"Jungle Stairs","2179":"Jungle Stairs","2180":"Jungle Stairs","2181":"Jungle Stairs","2182":"Jungle Stairs","2183":"Jungle Stairs","2208":"Beacon","2224":"Cobblestone Wall","2225":"Mossy Cobblestone Wall","2226":"Granite Wall","2227":"Diorite Wall","2228":"Andesite Wall","2229":"Sandstone Wall","2230":"Brick Wall","2231":"Stone Brick Wall","2232":"Mossy Stone Brick Wall","2233":"Nether Brick Wall","2234":"End Stone Brick Wall","2235":"Prismarine Wall","2236":"Red Sandstone Wall","2237":"Red Nether Brick Wall","2240":"Flower Pot","2256":"Carrot Block","2257":"Carrot Block","2258":"Carrot Block","2259":"Carrot Block","2260":"Carrot Block","2261":"Carrot Block","2262":"Carrot Block","2263":"Carrot Block","2272":"Potato Block","2273":"Potato Block","2274":"Potato Block","2275":"Potato Block","2276":"Potato Block","2277":"Potato Block","2278":"Potato Block","2279":"Potato Block","2288":"Oak Button","2289":"Oak Button","2290":"Oak Button","2291":"Oak Button","2292":"Oak Button","2293":"Oak Button","2296":"Oak Button","2297":"Oak Button","2298":"Oak Button","2299":"Oak Button","2300":"Oak Button","2301":"Oak Button","2305":"Mob Head","2306":"Mob Head","2307":"Mob Head","2308":"Mob Head","2309":"Mob Head","2320":"Anvil","2321":"Anvil","2322":"Anvil","2323":"Anvil","2324":"Anvil","2325":"Anvil","2326":"Anvil","2327":"Anvil","2328":"Anvil","2329":"Anvil","2330":"Anvil","2331":"Anvil","2338":"Trapped Chest","2339":"Trapped Chest","2340":"Trapped Chest","2341":"Trapped Chest","2352":"Weighted Pressure Plate Light","2353":"Weighted Pressure Plate Light","2354":"Weighted Pressure Plate Light","2355":"Weighted Pressure Plate Light","2356":"Weighted Pressure Plate Light","2357":"Weighted Pressure Plate Light","2358":"Weighted Pressure Plate Light","2359":"Weighted Pressure Plate Light","2360":"Weighted Pressure Plate Light","2361":"Weighted Pressure Plate Light","2362":"Weighted Pressure Plate Light","2363":"Weighted Pressure Plate Light","2364":"Weighted Pressure Plate Light","2365":"Weighted Pressure Plate Light","2366":"Weighted Pressure Plate Light","2367":"Weighted Pressure Plate Light","2368":"Weighted Pressure Plate Heavy","2369":"Weighted Pressure Plate Heavy","2370":"Weighted Pressure Plate Heavy","2371":"Weighted Pressure Plate Heavy","2372":"Weighted Pressure Plate Heavy","2373":"Weighted Pressure Plate Heavy","2374":"Weighted Pressure Plate Heavy","2375":"Weighted Pressure Plate Heavy","2376":"Weighted Pressure Plate Heavy","2377":"Weighted Pressure Plate Heavy","2378":"Weighted Pressure Plate Heavy","2379":"Weighted Pressure Plate Heavy","2380":"Weighted Pressure Plate Heavy","2381":"Weighted Pressure Plate Heavy","2382":"Weighted Pressure Plate Heavy","2383":"Weighted Pressure Plate Heavy","2384":"Redstone Comparator","2385":"Redstone Comparator","2386":"Redstone Comparator","2387":"Redstone Comparator","2388":"Redstone Comparator","2389":"Redstone Comparator","2390":"Redstone Comparator","2391":"Redstone Comparator","2408":"Redstone Comparator","2409":"Redstone Comparator","2410":"Redstone Comparator","2411":"Redstone Comparator","2412":"Redstone Comparator","2413":"Redstone Comparator","2414":"Redstone Comparator","2415":"Redstone Comparator","2416":"Daylight Sensor","2417":"Daylight Sensor","2418":"Daylight Sensor","2419":"Daylight Sensor","2420":"Daylight Sensor","2421":"Daylight Sensor","2422":"Daylight Sensor","2423":"Daylight Sensor","2424":"Daylight Sensor","2425":"Daylight Sensor","2426":"Daylight Sensor","2427":"Daylight Sensor","2428":"Daylight Sensor","2429":"Daylight Sensor","2430":"Daylight Sensor","2431":"Daylight Sensor","2432":"Redstone Block","2448":"Nether Quartz Ore","2464":"Hopper","2466":"Hopper","2467":"Hopper","2468":"Hopper","2469":"Hopper","2472":"Hopper","2474":"Hopper","2475":"Hopper","2476":"Hopper","2477":"Hopper","2480":"Quartz Block","2481":"Chiseled Quartz Block","2482":"Quartz Pillar","2483":"Smooth Quartz Block","2485":"Chiseled Quartz Block","2486":"Quartz Pillar","2489":"Chiseled Quartz Block","2490":"Quartz Pillar","2496":"Quartz Stairs","2497":"Quartz Stairs","2498":"Quartz Stairs","2499":"Quartz Stairs","2500":"Quartz Stairs","2501":"Quartz Stairs","2502":"Quartz Stairs","2503":"Quartz Stairs","2512":"Oak Slab","2513":"Spruce Slab","2514":"Birch Slab","2515":"Jungle Slab","2516":"Acacia Slab","2517":"Dark Oak Slab","2528":"Oak Slab","2529":"Spruce Slab","2530":"Birch Slab","2531":"Jungle Slab","2532":"Acacia Slab","2533":"Dark Oak Slab","2536":"Oak Slab","2537":"Spruce Slab","2538":"Birch Slab","2539":"Jungle Slab","2540":"Acacia Slab","2541":"Dark Oak Slab","2544":"Stained Clay","2545":"Stained Clay","2546":"Stained Clay","2547":"Stained Clay","2548":"Stained Clay","2549":"Stained Clay","2550":"Stained Clay","2551":"Stained Clay","2552":"Stained Clay","2553":"Stained Clay","2554":"Stained Clay","2555":"Stained Clay","2556":"Stained Clay","2557":"Stained Clay","2558":"Stained Clay","2559":"Stained Clay","2560":"Stained Glass Pane","2561":"Stained Glass Pane","2562":"Stained Glass Pane","2563":"Stained Glass Pane","2564":"Stained Glass Pane","2565":"Stained Glass Pane","2566":"Stained Glass Pane","2567":"Stained Glass Pane","2568":"Stained Glass Pane","2569":"Stained Glass Pane","2570":"Stained Glass Pane","2571":"Stained Glass Pane","2572":"Stained Glass Pane","2573":"Stained Glass Pane","2574":"Stained Glass Pane","2575":"Stained Glass Pane","2576":"Acacia Leaves","2577":"Dark Oak Leaves","2580":"Acacia Leaves","2581":"Dark Oak Leaves","2584":"Acacia Leaves","2585":"Dark Oak Leaves","2588":"Acacia Leaves","2589":"Dark Oak Leaves","2592":"Acacia Log","2593":"Dark Oak Log","2596":"Acacia Log","2597":"Dark Oak Log","2600":"Acacia Log","2601":"Dark Oak Log","2608":"Acacia Stairs","2609":"Acacia Stairs","2610":"Acacia Stairs","2611":"Acacia Stairs","2612":"Acacia Stairs","2613":"Acacia Stairs","2614":"Acacia Stairs","2615":"Acacia Stairs","2624":"Dark Oak Stairs","2625":"Dark Oak Stairs","2626":"Dark Oak Stairs","2627":"Dark Oak Stairs","2628":"Dark Oak Stairs","2629":"Dark Oak Stairs","2630":"Dark Oak Stairs","2631":"Dark Oak Stairs","2640":"Slime Block","2672":"Iron Trapdoor","2673":"Iron Trapdoor","2674":"Iron Trapdoor","2675":"Iron Trapdoor","2676":"Iron Trapdoor","2677":"Iron Trapdoor","2678":"Iron Trapdoor","2679":"Iron Trapdoor","2680":"Iron Trapdoor","2681":"Iron Trapdoor","2682":"Iron Trapdoor","2683":"Iron Trapdoor","2684":"Iron Trapdoor","2685":"Iron Trapdoor","2686":"Iron Trapdoor","2687":"Iron Trapdoor","2688":"Prismarine","2689":"Dark Prismarine","2690":"Prismarine Bricks","2704":"Sea Lantern","2720":"Hay Bale","2724":"Hay Bale","2728":"Hay Bale","2736":"Carpet","2737":"Carpet","2738":"Carpet","2739":"Carpet","2740":"Carpet","2741":"Carpet","2742":"Carpet","2743":"Carpet","2744":"Carpet","2745":"Carpet","2746":"Carpet","2747":"Carpet","2748":"Carpet","2749":"Carpet","2750":"Carpet","2751":"Carpet","2752":"Hardened Clay","2768":"Coal Block","2784":"Packed Ice","2800":"Sunflower","2801":"Lilac","2802":"Double Tallgrass","2803":"Large Fern","2804":"Rose Bush","2805":"Peony","2808":"Sunflower","2809":"Lilac","2810":"Double Tallgrass","2811":"Large Fern","2812":"Rose Bush","2813":"Peony","2816":"Banner","2817":"Banner","2818":"Banner","2819":"Banner","2820":"Banner","2821":"Banner","2822":"Banner","2823":"Banner","2824":"Banner","2825":"Banner","2826":"Banner","2827":"Banner","2828":"Banner","2829":"Banner","2830":"Banner","2831":"Banner","2834":"Wall Banner","2835":"Wall Banner","2836":"Wall Banner","2837":"Wall Banner","2848":"Daylight Sensor","2849":"Daylight Sensor","2850":"Daylight Sensor","2851":"Daylight Sensor","2852":"Daylight Sensor","2853":"Daylight Sensor","2854":"Daylight Sensor","2855":"Daylight Sensor","2856":"Daylight Sensor","2857":"Daylight Sensor","2858":"Daylight Sensor","2859":"Daylight Sensor","2860":"Daylight Sensor","2861":"Daylight Sensor","2862":"Daylight Sensor","2863":"Daylight Sensor","2864":"Red Sandstone","2865":"Chiseled Red Sandstone","2866":"Cut Red Sandstone","2867":"Smooth Red Sandstone","2880":"Red Sandstone Stairs","2881":"Red Sandstone Stairs","2882":"Red Sandstone Stairs","2883":"Red Sandstone Stairs","2884":"Red Sandstone Stairs","2885":"Red Sandstone Stairs","2886":"Red Sandstone Stairs","2887":"Red Sandstone Stairs","2896":"Red Sandstone Slab","2897":"Purpur Slab","2898":"Prismarine Slab","2899":"Dark Prismarine Slab","2900":"Prismarine Bricks Slab","2901":"Mossy Cobblestone Slab","2902":"Smooth Sandstone Slab","2903":"Red Nether Brick Slab","2912":"Red Sandstone Slab","2913":"Purpur Slab","2914":"Prismarine Slab","2915":"Dark Prismarine Slab","2916":"Prismarine Bricks Slab","2917":"Mossy Cobblestone Slab","2918":"Smooth Sandstone Slab","2919":"Red Nether Brick Slab","2920":"Red Sandstone Slab","2921":"Purpur Slab","2922":"Prismarine Slab","2923":"Dark Prismarine Slab","2924":"Prismarine Bricks Slab","2925":"Mossy Cobblestone Slab","2926":"Smooth Sandstone Slab","2927":"Red Nether Brick Slab","2928":"Spruce Fence Gate","2929":"Spruce Fence Gate","2930":"Spruce Fence Gate","2931":"Spruce Fence Gate","2932":"Spruce Fence Gate","2933":"Spruce Fence Gate","2934":"Spruce Fence Gate","2935":"Spruce Fence Gate","2936":"Spruce Fence Gate","2937":"Spruce Fence Gate","2938":"Spruce Fence Gate","2939":"Spruce Fence Gate","2940":"Spruce Fence Gate","2941":"Spruce Fence Gate","2942":"Spruce Fence Gate","2943":"Spruce Fence Gate","2944":"Birch Fence Gate","2945":"Birch Fence Gate","2946":"Birch Fence Gate","2947":"Birch Fence Gate","2948":"Birch Fence Gate","2949":"Birch Fence Gate","2950":"Birch Fence Gate","2951":"Birch Fence Gate","2952":"Birch Fence Gate","2953":"Birch Fence Gate","2954":"Birch Fence Gate","2955":"Birch Fence Gate","2956":"Birch Fence Gate","2957":"Birch Fence Gate","2958":"Birch Fence Gate","2959":"Birch Fence Gate","2960":"Jungle Fence Gate","2961":"Jungle Fence Gate","2962":"Jungle Fence Gate","2963":"Jungle Fence Gate","2964":"Jungle Fence Gate","2965":"Jungle Fence Gate","2966":"Jungle Fence Gate","2967":"Jungle Fence Gate","2968":"Jungle Fence Gate","2969":"Jungle Fence Gate","2970":"Jungle Fence Gate","2971":"Jungle Fence Gate","2972":"Jungle Fence Gate","2973":"Jungle Fence Gate","2974":"Jungle Fence Gate","2975":"Jungle Fence Gate","2976":"Dark Oak Fence Gate","2977":"Dark Oak Fence Gate","2978":"Dark Oak Fence Gate","2979":"Dark Oak Fence Gate","2980":"Dark Oak Fence Gate","2981":"Dark Oak Fence Gate","2982":"Dark Oak Fence Gate","2983":"Dark Oak Fence Gate","2984":"Dark Oak Fence Gate","2985":"Dark Oak Fence Gate","2986":"Dark Oak Fence Gate","2987":"Dark Oak Fence Gate","2988":"Dark Oak Fence Gate","2989":"Dark Oak Fence Gate","2990":"Dark Oak Fence Gate","2991":"Dark Oak Fence Gate","2992":"Acacia Fence Gate","2993":"Acacia Fence Gate","2994":"Acacia Fence Gate","2995":"Acacia Fence Gate","2996":"Acacia Fence Gate","2997":"Acacia Fence Gate","2998":"Acacia Fence Gate","2999":"Acacia Fence Gate","3000":"Acacia Fence Gate","3001":"Acacia Fence Gate","3002":"Acacia Fence Gate","3003":"Acacia Fence Gate","3004":"Acacia Fence Gate","3005":"Acacia Fence Gate","3006":"Acacia Fence Gate","3007":"Acacia Fence Gate","3040":"Hardened Glass Pane","3056":"Stained Hardened Glass Pane","3057":"Stained Hardened Glass Pane","3058":"Stained Hardened Glass Pane","3059":"Stained Hardened Glass Pane","3060":"Stained Hardened Glass Pane","3061":"Stained Hardened Glass Pane","3062":"Stained Hardened Glass Pane","3063":"Stained Hardened Glass Pane","3064":"Stained Hardened Glass Pane","3065":"Stained Hardened Glass Pane","3066":"Stained Hardened Glass Pane","3067":"Stained Hardened Glass Pane","3068":"Stained Hardened Glass Pane","3069":"Stained Hardened Glass Pane","3070":"Stained Hardened Glass Pane","3071":"Stained Hardened Glass Pane","3072":"Heat Block","3088":"Spruce Door","3089":"Spruce Door","3090":"Spruce Door","3091":"Spruce Door","3092":"Spruce Door","3093":"Spruce Door","3094":"Spruce Door","3095":"Spruce Door","3096":"Spruce Door","3097":"Spruce Door","3098":"Spruce Door","3099":"Spruce Door","3104":"Birch Door","3105":"Birch Door","3106":"Birch Door","3107":"Birch Door","3108":"Birch Door","3109":"Birch Door","3110":"Birch Door","3111":"Birch Door","3112":"Birch Door","3113":"Birch Door","3114":"Birch Door","3115":"Birch Door","3120":"Jungle Door","3121":"Jungle Door","3122":"Jungle Door","3123":"Jungle Door","3124":"Jungle Door","3125":"Jungle Door","3126":"Jungle Door","3127":"Jungle Door","3128":"Jungle Door","3129":"Jungle Door","3130":"Jungle Door","3131":"Jungle Door","3136":"Acacia Door","3137":"Acacia Door","3138":"Acacia Door","3139":"Acacia Door","3140":"Acacia Door","3141":"Acacia Door","3142":"Acacia Door","3143":"Acacia Door","3144":"Acacia Door","3145":"Acacia Door","3146":"Acacia Door","3147":"Acacia Door","3152":"Dark Oak Door","3153":"Dark Oak Door","3154":"Dark Oak Door","3155":"Dark Oak Door","3156":"Dark Oak Door","3157":"Dark Oak Door","3158":"Dark Oak Door","3159":"Dark Oak Door","3160":"Dark Oak Door","3161":"Dark Oak Door","3162":"Dark Oak Door","3163":"Dark Oak Door","3168":"Grass Path","3184":"Item Frame","3185":"Item Frame","3186":"Item Frame","3187":"Item Frame","3188":"Item Frame","3189":"Item Frame","3190":"Item Frame","3191":"Item Frame","3216":"Purpur Block","3218":"Purpur Pillar","3222":"Purpur Pillar","3226":"Purpur Pillar","3233":"Red Torch","3234":"Red Torch","3235":"Red Torch","3236":"Red Torch","3237":"Red Torch","3241":"Green Torch","3242":"Green Torch","3243":"Green Torch","3244":"Green Torch","3245":"Green Torch","3248":"Purpur Stairs","3249":"Purpur Stairs","3250":"Purpur Stairs","3251":"Purpur Stairs","3252":"Purpur Stairs","3253":"Purpur Stairs","3254":"Purpur Stairs","3255":"Purpur Stairs","3265":"Blue Torch","3266":"Blue Torch","3267":"Blue Torch","3268":"Blue Torch","3269":"Blue Torch","3273":"Purple Torch","3274":"Purple Torch","3275":"Purple Torch","3276":"Purple Torch","3277":"Purple Torch","3280":"Shulker Box","3296":"End Stone Bricks","3312":"Frosted Ice","3313":"Frosted Ice","3314":"Frosted Ice","3315":"Frosted Ice","3328":"End Rod","3329":"End Rod","3330":"End Rod","3331":"End Rod","3332":"End Rod","3333":"End Rod","3408":"Magma Block","3424":"Nether Wart Block","3440":"Red Nether Bricks","3456":"Bone Block","3460":"Bone Block","3464":"Bone Block","3488":"Dyed Shulker Box","3489":"Dyed Shulker Box","3490":"Dyed Shulker Box","3491":"Dyed Shulker Box","3492":"Dyed Shulker Box","3493":"Dyed Shulker Box","3494":"Dyed Shulker Box","3495":"Dyed Shulker Box","3496":"Dyed Shulker Box","3497":"Dyed Shulker Box","3498":"Dyed Shulker Box","3499":"Dyed Shulker Box","3500":"Dyed Shulker Box","3501":"Dyed Shulker Box","3502":"Dyed Shulker Box","3503":"Dyed Shulker Box","3506":"Purple Glazed Terracotta","3507":"Purple Glazed Terracotta","3508":"Purple Glazed Terracotta","3509":"Purple Glazed Terracotta","3522":"White Glazed Terracotta","3523":"White Glazed Terracotta","3524":"White Glazed Terracotta","3525":"White Glazed Terracotta","3538":"Orange Glazed Terracotta","3539":"Orange Glazed Terracotta","3540":"Orange Glazed Terracotta","3541":"Orange Glazed Terracotta","3554":"Magenta Glazed Terracotta","3555":"Magenta Glazed Terracotta","3556":"Magenta Glazed Terracotta","3557":"Magenta Glazed Terracotta","3570":"Light Blue Glazed Terracotta","3571":"Light Blue Glazed Terracotta","3572":"Light Blue Glazed Terracotta","3573":"Light Blue Glazed Terracotta","3586":"Yellow Glazed Terracotta","3587":"Yellow Glazed Terracotta","3588":"Yellow Glazed Terracotta","3589":"Yellow Glazed Terracotta","3602":"Lime Glazed Terracotta","3603":"Lime Glazed Terracotta","3604":"Lime Glazed Terracotta","3605":"Lime Glazed Terracotta","3618":"Pink Glazed Terracotta","3619":"Pink Glazed Terracotta","3620":"Pink Glazed Terracotta","3621":"Pink Glazed Terracotta","3634":"Gray Glazed Terracotta","3635":"Gray Glazed Terracotta","3636":"Gray Glazed Terracotta","3637":"Gray Glazed Terracotta","3650":"Light Gray Glazed Terracotta","3651":"Light Gray Glazed Terracotta","3652":"Light Gray Glazed Terracotta","3653":"Light Gray Glazed Terracotta","3666":"Cyan Glazed Terracotta","3667":"Cyan Glazed Terracotta","3668":"Cyan Glazed Terracotta","3669":"Cyan Glazed Terracotta","3698":"Blue Glazed Terracotta","3699":"Blue Glazed Terracotta","3700":"Blue Glazed Terracotta","3701":"Blue Glazed Terracotta","3714":"Brown Glazed Terracotta","3715":"Brown Glazed Terracotta","3716":"Brown Glazed Terracotta","3717":"Brown Glazed Terracotta","3730":"Green Glazed Terracotta","3731":"Green Glazed Terracotta","3732":"Green Glazed Terracotta","3733":"Green Glazed Terracotta","3746":"Red Glazed Terracotta","3747":"Red Glazed Terracotta","3748":"Red Glazed Terracotta","3749":"Red Glazed Terracotta","3762":"Black Glazed Terracotta","3763":"Black Glazed Terracotta","3764":"Black Glazed Terracotta","3765":"Black Glazed Terracotta","3776":"Concrete","3777":"Concrete","3778":"Concrete","3779":"Concrete","3780":"Concrete","3781":"Concrete","3782":"Concrete","3783":"Concrete","3784":"Concrete","3785":"Concrete","3786":"Concrete","3787":"Concrete","3788":"Concrete","3789":"Concrete","3790":"Concrete","3791":"Concrete","3792":"Concrete Powder","3793":"Concrete Powder","3794":"Concrete Powder","3795":"Concrete Powder","3796":"Concrete Powder","3797":"Concrete Powder","3798":"Concrete Powder","3799":"Concrete Powder","3800":"Concrete Powder","3801":"Concrete Powder","3802":"Concrete Powder","3803":"Concrete Powder","3804":"Concrete Powder","3805":"Concrete Powder","3806":"Concrete Powder","3807":"Concrete Powder","3808":"Compound Creator","3809":"Compound Creator","3810":"Compound Creator","3811":"Compound Creator","3812":"Material Reducer","3813":"Material Reducer","3814":"Material Reducer","3815":"Material Reducer","3816":"Element Constructor","3817":"Element Constructor","3818":"Element Constructor","3819":"Element Constructor","3820":"Lab Table","3821":"Lab Table","3822":"Lab Table","3823":"Lab Table","3825":"Underwater Torch","3826":"Underwater Torch","3827":"Underwater Torch","3828":"Underwater Torch","3829":"Underwater Torch","3856":"Stained Glass","3857":"Stained Glass","3858":"Stained Glass","3859":"Stained Glass","3860":"Stained Glass","3861":"Stained Glass","3862":"Stained Glass","3863":"Stained Glass","3864":"Stained Glass","3865":"Stained Glass","3866":"Stained Glass","3867":"Stained Glass","3868":"Stained Glass","3869":"Stained Glass","3870":"Stained Glass","3871":"Stained Glass","3888":"Podzol","3904":"Beetroot Block","3905":"Beetroot Block","3906":"Beetroot Block","3907":"Beetroot Block","3908":"Beetroot Block","3909":"Beetroot Block","3910":"Beetroot Block","3911":"Beetroot Block","3920":"Stonecutter","3936":"Glowing Obsidian","3952":"Nether Reactor Core","3953":"Nether Reactor Core","3954":"Nether Reactor Core","3968":"update!","3984":"ate!upd","4048":"Hardened Glass","4064":"Stained Hardened Glass","4065":"Stained Hardened Glass","4066":"Stained Hardened Glass","4067":"Stained Hardened Glass","4068":"Stained Hardened Glass","4069":"Stained Hardened Glass","4070":"Stained Hardened Glass","4071":"Stained Hardened Glass","4072":"Stained Hardened Glass","4073":"Stained Hardened Glass","4074":"Stained Hardened Glass","4075":"Stained Hardened Glass","4076":"Stained Hardened Glass","4077":"Stained Hardened Glass","4078":"Stained Hardened Glass","4079":"Stained Hardened Glass","4080":"reserved6","4112":"Prismarine Stairs","4113":"Prismarine Stairs","4114":"Prismarine Stairs","4115":"Prismarine Stairs","4116":"Prismarine Stairs","4117":"Prismarine Stairs","4118":"Prismarine Stairs","4119":"Prismarine Stairs","4128":"Dark Prismarine Stairs","4129":"Dark Prismarine Stairs","4130":"Dark Prismarine Stairs","4131":"Dark Prismarine Stairs","4132":"Dark Prismarine Stairs","4133":"Dark Prismarine Stairs","4134":"Dark Prismarine Stairs","4135":"Dark Prismarine Stairs","4144":"Prismarine Bricks Stairs","4145":"Prismarine Bricks Stairs","4146":"Prismarine Bricks Stairs","4147":"Prismarine Bricks Stairs","4148":"Prismarine Bricks Stairs","4149":"Prismarine Bricks Stairs","4150":"Prismarine Bricks Stairs","4151":"Prismarine Bricks Stairs","4160":"Stripped Spruce Log","4161":"Stripped Spruce Log","4162":"Stripped Spruce Log","4176":"Stripped Birch Log","4177":"Stripped Birch Log","4178":"Stripped Birch Log","4192":"Stripped Jungle Log","4193":"Stripped Jungle Log","4194":"Stripped Jungle Log","4208":"Stripped Acacia Log","4209":"Stripped Acacia Log","4210":"Stripped Acacia Log","4224":"Stripped Dark Oak Log","4225":"Stripped Dark Oak Log","4226":"Stripped Dark Oak Log","4240":"Stripped Oak Log","4241":"Stripped Oak Log","4242":"Stripped Oak Log","4256":"Blue Ice","4272":"Hydrogen","4288":"Helium","4304":"Lithium","4320":"Beryllium","4336":"Boron","4352":"Carbon","4368":"Nitrogen","4384":"Oxygen","4400":"Fluorine","4416":"Neon","4432":"Sodium","4448":"Magnesium","4464":"Aluminum","4480":"Silicon","4496":"Phosphorus","4512":"Sulfur","4528":"Chlorine","4544":"Argon","4560":"Potassium","4576":"Calcium","4592":"Scandium","4608":"Titanium","4624":"Vanadium","4640":"Chromium","4656":"Manganese","4672":"Iron","4688":"Cobalt","4704":"Nickel","4720":"Copper","4736":"Zinc","4752":"Gallium","4768":"Germanium","4784":"Arsenic","4800":"Selenium","4816":"Bromine","4832":"Krypton","4848":"Rubidium","4864":"Strontium","4880":"Yttrium","4896":"Zirconium","4912":"Niobium","4928":"Molybdenum","4944":"Technetium","4960":"Ruthenium","4976":"Rhodium","4992":"Palladium","5008":"Silver","5024":"Cadmium","5040":"Indium","5056":"Tin","5072":"Antimony","5088":"Tellurium","5104":"Iodine","5120":"Xenon","5136":"Cesium","5152":"Barium","5168":"Lanthanum","5184":"Cerium","5200":"Praseodymium","5216":"Neodymium","5232":"Promethium","5248":"Samarium","5264":"Europium","5280":"Gadolinium","5296":"Terbium","5312":"Dysprosium","5328":"Holmium","5344":"Erbium","5360":"Thulium","5376":"Ytterbium","5392":"Lutetium","5408":"Hafnium","5424":"Tantalum","5440":"Tungsten","5456":"Rhenium","5472":"Osmium","5488":"Iridium","5504":"Platinum","5520":"Gold","5536":"Mercury","5552":"Thallium","5568":"Lead","5584":"Bismuth","5600":"Polonium","5616":"Astatine","5632":"Radon","5648":"Francium","5664":"Radium","5680":"Actinium","5696":"Thorium","5712":"Protactinium","5728":"Uranium","5744":"Neptunium","5760":"Plutonium","5776":"Americium","5792":"Curium","5808":"Berkelium","5824":"Californium","5840":"Einsteinium","5856":"Fermium","5872":"Mendelevium","5888":"Nobelium","5904":"Lawrencium","5920":"Rutherfordium","5936":"Dubnium","5952":"Seaborgium","5968":"Bohrium","5984":"Hassium","6000":"Meitnerium","6016":"Darmstadtium","6032":"Roentgenium","6048":"Copernicium","6064":"Nihonium","6080":"Flerovium","6096":"Moscovium","6112":"Livermorium","6128":"Tennessine","6144":"Oganesson","6176":"Coral","6177":"Coral","6178":"Coral","6179":"Coral","6180":"Coral","6192":"Coral Block","6193":"Coral Block","6194":"Coral Block","6195":"Coral Block","6196":"Coral Block","6200":"Coral Block","6201":"Coral Block","6202":"Coral Block","6203":"Coral Block","6204":"Coral Block","6208":"Coral Fan","6209":"Coral Fan","6210":"Coral Fan","6211":"Coral Fan","6212":"Coral Fan","6216":"Coral Fan","6217":"Coral Fan","6218":"Coral Fan","6219":"Coral Fan","6220":"Coral Fan","6224":"Coral Fan","6225":"Coral Fan","6226":"Coral Fan","6227":"Coral Fan","6228":"Coral Fan","6232":"Coral Fan","6233":"Coral Fan","6234":"Coral Fan","6235":"Coral Fan","6236":"Coral Fan","6240":"Wall Coral Fan","6241":"Wall Coral Fan","6242":"Wall Coral Fan","6243":"Wall Coral Fan","6244":"Wall Coral Fan","6245":"Wall Coral Fan","6246":"Wall Coral Fan","6247":"Wall Coral Fan","6248":"Wall Coral Fan","6249":"Wall Coral Fan","6250":"Wall Coral Fan","6251":"Wall Coral Fan","6252":"Wall Coral Fan","6253":"Wall Coral Fan","6254":"Wall Coral Fan","6255":"Wall Coral Fan","6256":"Wall Coral Fan","6257":"Wall Coral Fan","6258":"Wall Coral Fan","6259":"Wall Coral Fan","6260":"Wall Coral Fan","6261":"Wall Coral Fan","6262":"Wall Coral Fan","6263":"Wall Coral Fan","6264":"Wall Coral Fan","6265":"Wall Coral Fan","6266":"Wall Coral Fan","6267":"Wall Coral Fan","6268":"Wall Coral Fan","6269":"Wall Coral Fan","6270":"Wall Coral Fan","6271":"Wall Coral Fan","6272":"Wall Coral Fan","6274":"Wall Coral Fan","6276":"Wall Coral Fan","6278":"Wall Coral Fan","6280":"Wall Coral Fan","6282":"Wall Coral Fan","6284":"Wall Coral Fan","6286":"Wall Coral Fan","6304":"Dried Kelp Block","6320":"Acacia Button","6321":"Acacia Button","6322":"Acacia Button","6323":"Acacia Button","6324":"Acacia Button","6325":"Acacia Button","6328":"Acacia Button","6329":"Acacia Button","6330":"Acacia Button","6331":"Acacia Button","6332":"Acacia Button","6333":"Acacia Button","6336":"Birch Button","6337":"Birch Button","6338":"Birch Button","6339":"Birch Button","6340":"Birch Button","6341":"Birch Button","6344":"Birch Button","6345":"Birch Button","6346":"Birch Button","6347":"Birch Button","6348":"Birch Button","6349":"Birch Button","6352":"Dark Oak Button","6353":"Dark Oak Button","6354":"Dark Oak Button","6355":"Dark Oak Button","6356":"Dark Oak Button","6357":"Dark Oak Button","6360":"Dark Oak Button","6361":"Dark Oak Button","6362":"Dark Oak Button","6363":"Dark Oak Button","6364":"Dark Oak Button","6365":"Dark Oak Button","6368":"Jungle Button","6369":"Jungle Button","6370":"Jungle Button","6371":"Jungle Button","6372":"Jungle Button","6373":"Jungle Button","6376":"Jungle Button","6377":"Jungle Button","6378":"Jungle Button","6379":"Jungle Button","6380":"Jungle Button","6381":"Jungle Button","6384":"Spruce Button","6385":"Spruce Button","6386":"Spruce Button","6387":"Spruce Button","6388":"Spruce Button","6389":"Spruce Button","6392":"Spruce Button","6393":"Spruce Button","6394":"Spruce Button","6395":"Spruce Button","6396":"Spruce Button","6397":"Spruce Button","6400":"Acacia Trapdoor","6401":"Acacia Trapdoor","6402":"Acacia Trapdoor","6403":"Acacia Trapdoor","6404":"Acacia Trapdoor","6405":"Acacia Trapdoor","6406":"Acacia Trapdoor","6407":"Acacia Trapdoor","6408":"Acacia Trapdoor","6409":"Acacia Trapdoor","6410":"Acacia Trapdoor","6411":"Acacia Trapdoor","6412":"Acacia Trapdoor","6413":"Acacia Trapdoor","6414":"Acacia Trapdoor","6415":"Acacia Trapdoor","6416":"Birch Trapdoor","6417":"Birch Trapdoor","6418":"Birch Trapdoor","6419":"Birch Trapdoor","6420":"Birch Trapdoor","6421":"Birch Trapdoor","6422":"Birch Trapdoor","6423":"Birch Trapdoor","6424":"Birch Trapdoor","6425":"Birch Trapdoor","6426":"Birch Trapdoor","6427":"Birch Trapdoor","6428":"Birch Trapdoor","6429":"Birch Trapdoor","6430":"Birch Trapdoor","6431":"Birch Trapdoor","6432":"Dark Oak Trapdoor","6433":"Dark Oak Trapdoor","6434":"Dark Oak Trapdoor","6435":"Dark Oak Trapdoor","6436":"Dark Oak Trapdoor","6437":"Dark Oak Trapdoor","6438":"Dark Oak Trapdoor","6439":"Dark Oak Trapdoor","6440":"Dark Oak Trapdoor","6441":"Dark Oak Trapdoor","6442":"Dark Oak Trapdoor","6443":"Dark Oak Trapdoor","6444":"Dark Oak Trapdoor","6445":"Dark Oak Trapdoor","6446":"Dark Oak Trapdoor","6447":"Dark Oak Trapdoor","6448":"Jungle Trapdoor","6449":"Jungle Trapdoor","6450":"Jungle Trapdoor","6451":"Jungle Trapdoor","6452":"Jungle Trapdoor","6453":"Jungle Trapdoor","6454":"Jungle Trapdoor","6455":"Jungle Trapdoor","6456":"Jungle Trapdoor","6457":"Jungle Trapdoor","6458":"Jungle Trapdoor","6459":"Jungle Trapdoor","6460":"Jungle Trapdoor","6461":"Jungle Trapdoor","6462":"Jungle Trapdoor","6463":"Jungle Trapdoor","6464":"Spruce Trapdoor","6465":"Spruce Trapdoor","6466":"Spruce Trapdoor","6467":"Spruce Trapdoor","6468":"Spruce Trapdoor","6469":"Spruce Trapdoor","6470":"Spruce Trapdoor","6471":"Spruce Trapdoor","6472":"Spruce Trapdoor","6473":"Spruce Trapdoor","6474":"Spruce Trapdoor","6475":"Spruce Trapdoor","6476":"Spruce Trapdoor","6477":"Spruce Trapdoor","6478":"Spruce Trapdoor","6479":"Spruce Trapdoor","6480":"Acacia Pressure Plate","6481":"Acacia Pressure Plate","6496":"Birch Pressure Plate","6497":"Birch Pressure Plate","6512":"Dark Oak Pressure Plate","6513":"Dark Oak Pressure Plate","6528":"Jungle Pressure Plate","6529":"Jungle Pressure Plate","6544":"Spruce Pressure Plate","6545":"Spruce Pressure Plate","6560":"Carved Pumpkin","6561":"Carved Pumpkin","6562":"Carved Pumpkin","6563":"Carved Pumpkin","6576":"Sea Pickle","6577":"Sea Pickle","6578":"Sea Pickle","6579":"Sea Pickle","6580":"Sea Pickle","6581":"Sea Pickle","6582":"Sea Pickle","6583":"Sea Pickle","6656":"Barrier","6672":"End Stone Brick Slab","6673":"Smooth Red Sandstone Slab","6674":"Polished Andesite Slab","6675":"Andesite Slab","6676":"Diorite Slab","6677":"Polished Diorite Slab","6678":"Granite Slab","6679":"Polished Granite Slab","6680":"End Stone Brick Slab","6681":"Smooth Red Sandstone Slab","6682":"Polished Andesite Slab","6683":"Andesite Slab","6684":"Diorite Slab","6685":"Polished Diorite Slab","6686":"Granite Slab","6687":"Polished Granite Slab","6688":"Bamboo","6689":"Bamboo","6690":"Bamboo","6691":"Bamboo","6692":"Bamboo","6693":"Bamboo","6696":"Bamboo","6697":"Bamboo","6698":"Bamboo","6699":"Bamboo","6700":"Bamboo","6701":"Bamboo","6704":"Bamboo Sapling","6712":"Bamboo Sapling","6736":"Mossy Stone Brick Slab","6737":"Smooth Quartz Slab","6738":"Stone Slab","6739":"Cut Sandstone Slab","6740":"Cut Red Sandstone Slab","6744":"Mossy Stone Brick Slab","6745":"Smooth Quartz Slab","6746":"Stone Slab","6747":"Cut Sandstone Slab","6748":"Cut Red Sandstone Slab","6752":"End Stone Brick Slab","6753":"Smooth Red Sandstone Slab","6754":"Polished Andesite Slab","6755":"Andesite Slab","6756":"Diorite Slab","6757":"Polished Diorite Slab","6758":"Granite Slab","6759":"Polished Granite Slab","6768":"Mossy Stone Brick Slab","6769":"Smooth Quartz Slab","6770":"Stone Slab","6771":"Cut Sandstone Slab","6772":"Cut Red Sandstone Slab","6784":"Granite Stairs","6785":"Granite Stairs","6786":"Granite Stairs","6787":"Granite Stairs","6788":"Granite Stairs","6789":"Granite Stairs","6790":"Granite Stairs","6791":"Granite Stairs","6800":"Diorite Stairs","6801":"Diorite Stairs","6802":"Diorite Stairs","6803":"Diorite Stairs","6804":"Diorite Stairs","6805":"Diorite Stairs","6806":"Diorite Stairs","6807":"Diorite Stairs","6816":"Andesite Stairs","6817":"Andesite Stairs","6818":"Andesite Stairs","6819":"Andesite Stairs","6820":"Andesite Stairs","6821":"Andesite Stairs","6822":"Andesite Stairs","6823":"Andesite Stairs","6832":"Polished Granite Stairs","6833":"Polished Granite Stairs","6834":"Polished Granite Stairs","6835":"Polished Granite Stairs","6836":"Polished Granite Stairs","6837":"Polished Granite Stairs","6838":"Polished Granite Stairs","6839":"Polished Granite Stairs","6848":"Polished Diorite Stairs","6849":"Polished Diorite Stairs","6850":"Polished Diorite Stairs","6851":"Polished Diorite Stairs","6852":"Polished Diorite Stairs","6853":"Polished Diorite Stairs","6854":"Polished Diorite Stairs","6855":"Polished Diorite Stairs","6864":"Polished Andesite Stairs","6865":"Polished Andesite Stairs","6866":"Polished Andesite Stairs","6867":"Polished Andesite Stairs","6868":"Polished Andesite Stairs","6869":"Polished Andesite Stairs","6870":"Polished Andesite Stairs","6871":"Polished Andesite Stairs","6880":"Mossy Stone Brick Stairs","6881":"Mossy Stone Brick Stairs","6882":"Mossy Stone Brick Stairs","6883":"Mossy Stone Brick Stairs","6884":"Mossy Stone Brick Stairs","6885":"Mossy Stone Brick Stairs","6886":"Mossy Stone Brick Stairs","6887":"Mossy Stone Brick Stairs","6896":"Smooth Red Sandstone Stairs","6897":"Smooth Red Sandstone Stairs","6898":"Smooth Red Sandstone Stairs","6899":"Smooth Red Sandstone Stairs","6900":"Smooth Red Sandstone Stairs","6901":"Smooth Red Sandstone Stairs","6902":"Smooth Red Sandstone Stairs","6903":"Smooth Red Sandstone Stairs","6912":"Smooth Sandstone Stairs","6913":"Smooth Sandstone Stairs","6914":"Smooth Sandstone Stairs","6915":"Smooth Sandstone Stairs","6916":"Smooth Sandstone Stairs","6917":"Smooth Sandstone Stairs","6918":"Smooth Sandstone Stairs","6919":"Smooth Sandstone Stairs","6928":"End Stone Brick Stairs","6929":"End Stone Brick Stairs","6930":"End Stone Brick Stairs","6931":"End Stone Brick Stairs","6932":"End Stone Brick Stairs","6933":"End Stone Brick Stairs","6934":"End Stone Brick Stairs","6935":"End Stone Brick Stairs","6944":"Mossy Cobblestone Stairs","6945":"Mossy Cobblestone Stairs","6946":"Mossy Cobblestone Stairs","6947":"Mossy Cobblestone Stairs","6948":"Mossy Cobblestone Stairs","6949":"Mossy Cobblestone Stairs","6950":"Mossy Cobblestone Stairs","6951":"Mossy Cobblestone Stairs","6960":"Stone Stairs","6961":"Stone Stairs","6962":"Stone Stairs","6963":"Stone Stairs","6964":"Stone Stairs","6965":"Stone Stairs","6966":"Stone Stairs","6967":"Stone Stairs","6976":"Spruce Sign","6977":"Spruce Sign","6978":"Spruce Sign","6979":"Spruce Sign","6980":"Spruce Sign","6981":"Spruce Sign","6982":"Spruce Sign","6983":"Spruce Sign","6984":"Spruce Sign","6985":"Spruce Sign","6986":"Spruce Sign","6987":"Spruce Sign","6988":"Spruce Sign","6989":"Spruce Sign","6990":"Spruce Sign","6991":"Spruce Sign","6994":"Spruce Wall Sign","6995":"Spruce Wall Sign","6996":"Spruce Wall Sign","6997":"Spruce Wall Sign","7008":"Smooth Stone","7024":"Red Nether Brick Stairs","7025":"Red Nether Brick Stairs","7026":"Red Nether Brick Stairs","7027":"Red Nether Brick Stairs","7028":"Red Nether Brick Stairs","7029":"Red Nether Brick Stairs","7030":"Red Nether Brick Stairs","7031":"Red Nether Brick Stairs","7040":"Smooth Quartz Stairs","7041":"Smooth Quartz Stairs","7042":"Smooth Quartz Stairs","7043":"Smooth Quartz Stairs","7044":"Smooth Quartz Stairs","7045":"Smooth Quartz Stairs","7046":"Smooth Quartz Stairs","7047":"Smooth Quartz Stairs","7056":"Birch Sign","7057":"Birch Sign","7058":"Birch Sign","7059":"Birch Sign","7060":"Birch Sign","7061":"Birch Sign","7062":"Birch Sign","7063":"Birch Sign","7064":"Birch Sign","7065":"Birch Sign","7066":"Birch Sign","7067":"Birch Sign","7068":"Birch Sign","7069":"Birch Sign","7070":"Birch Sign","7071":"Birch Sign","7074":"Birch Wall Sign","7075":"Birch Wall Sign","7076":"Birch Wall Sign","7077":"Birch Wall Sign","7088":"Jungle Sign","7089":"Jungle Sign","7090":"Jungle Sign","7091":"Jungle Sign","7092":"Jungle Sign","7093":"Jungle Sign","7094":"Jungle Sign","7095":"Jungle Sign","7096":"Jungle Sign","7097":"Jungle Sign","7098":"Jungle Sign","7099":"Jungle Sign","7100":"Jungle Sign","7101":"Jungle Sign","7102":"Jungle Sign","7103":"Jungle Sign","7106":"Jungle Wall Sign","7107":"Jungle Wall Sign","7108":"Jungle Wall Sign","7109":"Jungle Wall Sign","7120":"Acacia Sign","7121":"Acacia Sign","7122":"Acacia Sign","7123":"Acacia Sign","7124":"Acacia Sign","7125":"Acacia Sign","7126":"Acacia Sign","7127":"Acacia Sign","7128":"Acacia Sign","7129":"Acacia Sign","7130":"Acacia Sign","7131":"Acacia Sign","7132":"Acacia Sign","7133":"Acacia Sign","7134":"Acacia Sign","7135":"Acacia Sign","7138":"Acacia Wall Sign","7139":"Acacia Wall Sign","7140":"Acacia Wall Sign","7141":"Acacia Wall Sign","7152":"Dark Oak Sign","7153":"Dark Oak Sign","7154":"Dark Oak Sign","7155":"Dark Oak Sign","7156":"Dark Oak Sign","7157":"Dark Oak Sign","7158":"Dark Oak Sign","7159":"Dark Oak Sign","7160":"Dark Oak Sign","7161":"Dark Oak Sign","7162":"Dark Oak Sign","7163":"Dark Oak Sign","7164":"Dark Oak Sign","7165":"Dark Oak Sign","7166":"Dark Oak Sign","7167":"Dark Oak Sign","7170":"Dark Oak Wall Sign","7171":"Dark Oak Wall Sign","7172":"Dark Oak Wall Sign","7173":"Dark Oak Wall Sign","7218":"Blast Furnace","7219":"Blast Furnace","7220":"Blast Furnace","7221":"Blast Furnace","7250":"Smoker","7251":"Smoker","7252":"Smoker","7253":"Smoker","7266":"Smoker","7267":"Smoker","7268":"Smoker","7269":"Smoker","7296":"Fletching Table","7328":"Barrel","7329":"Barrel","7330":"Barrel","7331":"Barrel","7332":"Barrel","7333":"Barrel","7336":"Barrel","7337":"Barrel","7338":"Barrel","7339":"Barrel","7340":"Barrel","7341":"Barrel","7344":"Loom","7345":"Loom","7346":"Loom","7347":"Loom","7376":"Bell","7377":"Bell","7378":"Bell","7379":"Bell","7380":"Bell","7381":"Bell","7382":"Bell","7383":"Bell","7384":"Bell","7385":"Bell","7386":"Bell","7387":"Bell","7388":"Bell","7389":"Bell","7390":"Bell","7391":"Bell","7392":"Sweet Berry Bush","7393":"Sweet Berry Bush","7394":"Sweet Berry Bush","7395":"Sweet Berry Bush","7408":"Lantern","7409":"Lantern","7472":"Oak Wood","7473":"Spruce Wood","7474":"Birch Wood","7475":"Jungle Wood","7476":"Acacia Wood","7477":"Dark Oak Wood","7480":"Stripped Oak Wood","7481":"Stripped Spruce Wood","7482":"Stripped Birch Wood","7483":"Stripped Jungle Wood","7484":"Stripped Acacia Wood","7485":"Stripped Dark Oak Wood","7506":"Blast Furnace","7507":"Blast Furnace","7508":"Blast Furnace","7509":"Blast Furnace"},"remaps":{"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"23":16,"24":16,"25":16,"26":16,"27":16,"28":16,"29":16,"30":16,"31":16,"33":32,"34":32,"35":32,"36":32,"37":32,"38":32,"39":32,"40":32,"41":32,"42":32,"43":32,"44":32,"45":32,"46":32,"47":32,"50":48,"51":48,"52":48,"53":48,"54":48,"55":48,"56":48,"57":48,"58":48,"59":48,"60":48,"61":48,"62":48,"63":48,"65":64,"66":64,"67":64,"68":64,"69":64,"70":64,"71":64,"72":64,"73":64,"74":64,"75":64,"76":64,"77":64,"78":64,"79":64,"86":80,"87":80,"88":80,"89":80,"90":80,"91":80,"92":80,"93":80,"94":80,"95":80,"102":96,"103":96,"110":96,"111":96,"114":112,"115":112,"116":112,"117":112,"118":112,"119":112,"120":112,"121":112,"122":112,"123":112,"124":112,"125":112,"126":112,"127":112,"194":192,"195":192,"196":192,"197":192,"198":192,"199":192,"200":192,"201":192,"202":192,"203":192,"204":192,"205":192,"206":192,"207":192,"209":208,"210":208,"211":208,"212":208,"213":208,"214":208,"215":208,"216":208,"217":208,"218":208,"219":208,"220":208,"221":208,"222":208,"223":208,"225":224,"226":224,"227":224,"228":224,"229":224,"230":224,"231":224,"232":224,"233":224,"234":224,"235":224,"236":224,"237":224,"238":224,"239":224,"241":240,"242":240,"243":240,"244":240,"245":240,"246":240,"247":240,"248":240,"249":240,"250":240,"251":240,"252":240,"253":240,"254":240,"255":240,"257":256,"258":256,"259":256,"260":256,"261":256,"262":256,"263":256,"264":256,"265":256,"266":256,"267":256,"268":256,"269":256,"270":256,"271":256,"284":7472,"285":7473,"286":7474,"287":7475,"306":304,"307":304,"308":304,"309":304,"310":304,"311":304,"312":304,"313":304,"314":304,"315":304,"316":304,"317":304,"318":304,"319":304,"321":320,"322":320,"323":320,"324":320,"325":320,"326":320,"327":320,"328":320,"329":320,"330":320,"331":320,"332":320,"333":320,"334":320,"335":320,"337":336,"338":336,"339":336,"340":336,"341":336,"342":336,"343":336,"344":336,"345":336,"346":336,"347":336,"348":336,"349":336,"350":336,"351":336,"353":352,"354":352,"355":352,"356":352,"357":352,"358":352,"359":352,"360":352,"361":352,"362":352,"363":352,"364":352,"365":352,"366":352,"367":352,"388":384,"389":384,"390":384,"391":384,"392":384,"393":384,"394":384,"395":384,"396":384,"397":384,"398":384,"399":384,"401":400,"402":400,"403":400,"404":400,"405":400,"406":400,"407":400,"408":400,"409":400,"410":400,"411":400,"412":400,"413":400,"414":400,"415":400,"438":432,"439":432,"446":432,"447":432,"454":448,"455":448,"462":448,"463":448,"481":480,"482":480,"483":480,"484":480,"485":480,"486":480,"487":480,"488":480,"489":480,"490":480,"491":480,"492":480,"493":480,"494":480,"495":480,"496":498,"499":498,"500":498,"501":498,"502":498,"503":498,"504":498,"505":498,"506":498,"507":498,"508":498,"509":498,"510":498,"511":498,"513":512,"514":512,"515":512,"516":512,"517":512,"518":512,"519":512,"520":512,"521":512,"522":512,"523":512,"524":512,"525":512,"526":512,"527":512,"577":576,"578":576,"579":576,"580":576,"581":576,"582":576,"583":576,"584":576,"585":576,"586":576,"587":576,"588":576,"589":576,"590":576,"591":576,"593":592,"594":592,"595":592,"596":592,"597":592,"598":592,"599":592,"600":592,"601":592,"602":592,"603":592,"604":592,"605":592,"606":592,"607":592,"619":608,"620":608,"621":608,"622":608,"623":608,"625":624,"626":624,"627":624,"628":624,"629":624,"630":624,"631":624,"632":624,"633":624,"634":624,"635":624,"636":624,"637":624,"638":624,"639":624,"641":640,"642":640,"643":640,"644":640,"645":640,"646":640,"647":640,"648":640,"649":640,"650":640,"651":640,"652":640,"653":640,"654":640,"655":640,"657":656,"658":656,"659":656,"660":656,"661":656,"662":656,"663":656,"664":656,"665":656,"666":656,"667":656,"668":656,"669":656,"670":656,"671":656,"673":672,"674":672,"675":672,"676":672,"677":672,"678":672,"679":672,"680":672,"681":672,"682":672,"683":672,"684":672,"685":672,"686":672,"687":672,"696":688,"697":689,"698":690,"699":691,"700":692,"701":693,"702":694,"703":695,"721":720,"722":720,"723":720,"724":720,"725":720,"726":720,"727":720,"728":720,"729":720,"730":720,"731":720,"732":720,"733":720,"734":720,"735":720,"740":736,"741":736,"742":736,"743":736,"744":736,"745":736,"746":736,"747":736,"748":736,"749":736,"750":736,"751":736,"753":752,"754":752,"755":752,"756":752,"757":752,"758":752,"759":752,"760":752,"761":752,"762":752,"763":752,"764":752,"765":752,"766":752,"767":752,"769":768,"770":768,"771":768,"772":768,"773":768,"774":768,"775":768,"776":768,"777":768,"778":768,"779":768,"780":768,"781":768,"782":768,"783":768,"785":784,"786":784,"787":784,"788":784,"789":784,"790":784,"791":784,"792":784,"793":784,"794":784,"795":784,"796":784,"797":784,"798":784,"799":784,"800":805,"806":805,"807":805,"808":805,"809":805,"810":805,"811":805,"812":805,"813":805,"814":805,"815":805,"833":832,"834":832,"835":832,"836":832,"837":832,"838":832,"839":832,"840":832,"841":832,"842":832,"843":832,"844":832,"845":832,"846":832,"847":832,"856":851,"857":851,"858":851,"859":851,"860":851,"861":851,"862":851,"863":851,"864":866,"865":866,"870":866,"871":866,"872":866,"873":866,"874":866,"875":866,"876":866,"877":866,"878":866,"879":866,"897":896,"898":896,"899":896,"900":896,"901":896,"902":896,"903":896,"904":896,"905":896,"906":896,"907":896,"908":896,"909":896,"910":896,"911":896,"913":912,"914":912,"915":912,"916":912,"917":912,"918":912,"919":912,"920":912,"921":912,"922":912,"923":912,"924":912,"925":912,"926":912,"927":912,"929":928,"930":928,"931":928,"932":928,"933":928,"934":928,"935":928,"936":928,"937":928,"938":928,"939":928,"940":928,"941":928,"942":928,"943":928,"952":944,"953":944,"954":944,"955":944,"956":944,"957":944,"958":944,"959":944,"968":960,"969":960,"970":960,"971":960,"972":960,"973":960,"974":960,"975":960,"976":978,"977":978,"982":978,"983":978,"984":978,"985":978,"986":978,"987":978,"988":978,"989":978,"990":978,"991":978,"992":978,"993":978,"998":978,"999":978,"1000":978,"1001":978,"1002":978,"1003":978,"1004":978,"1005":978,"1006":978,"1007":978,"1036":1027,"1037":1027,"1038":1027,"1039":1027,"1040":1042,"1041":1042,"1046":1042,"1047":1042,"1048":1042,"1049":1042,"1050":1042,"1051":1042,"1052":1042,"1053":1042,"1054":1042,"1055":1042,"1066":1056,"1067":1056,"1068":1056,"1069":1056,"1070":1056,"1071":1056,"1080":1075,"1081":1075,"1082":1075,"1083":1075,"1084":1075,"1085":1075,"1086":1075,"1087":1075,"1088":1090,"1089":1090,"1094":1090,"1095":1090,"1096":1090,"1097":1090,"1098":1090,"1099":1090,"1100":1090,"1101":1090,"1102":1090,"1103":1090,"1122":1120,"1123":1120,"1124":1120,"1125":1120,"1126":1120,"1127":1120,"1128":1120,"1129":1120,"1130":1120,"1131":1120,"1132":1120,"1133":1120,"1134":1120,"1135":1120,"1148":1139,"1149":1139,"1150":1139,"1151":1139,"1154":1152,"1155":1152,"1156":1152,"1157":1152,"1158":1152,"1159":1152,"1160":1152,"1161":1152,"1162":1152,"1163":1152,"1164":1152,"1165":1152,"1166":1152,"1167":1152,"1169":1168,"1170":1168,"1171":1168,"1172":1168,"1173":1168,"1174":1168,"1175":1168,"1176":1168,"1177":1168,"1178":1168,"1179":1168,"1180":1168,"1181":1168,"1182":1168,"1183":1168,"1185":1168,"1186":1168,"1187":1168,"1188":1168,"1189":1168,"1190":1168,"1191":1168,"1192":1168,"1193":1168,"1194":1168,"1195":1168,"1196":1168,"1197":1168,"1198":1168,"1199":1168,"1200":1221,"1206":1221,"1207":1221,"1208":1221,"1209":1221,"1210":1221,"1211":1221,"1212":1221,"1213":1221,"1214":1221,"1215":1221,"1216":1221,"1222":1221,"1223":1221,"1224":1221,"1225":1221,"1226":1221,"1227":1221,"1228":1221,"1229":1221,"1230":1221,"1231":1221,"1238":1232,"1239":1232,"1246":1232,"1247":1232,"1256":1248,"1257":1248,"1258":1248,"1259":1248,"1260":1248,"1261":1248,"1262":1248,"1263":1248,"1265":1264,"1266":1264,"1267":1264,"1268":1264,"1269":1264,"1270":1264,"1271":1264,"1272":1264,"1273":1264,"1274":1264,"1275":1264,"1276":1264,"1277":1264,"1278":1264,"1279":1264,"1281":1280,"1282":1280,"1283":1280,"1284":1280,"1285":1280,"1286":1280,"1287":1280,"1288":1280,"1289":1280,"1290":1280,"1291":1280,"1292":1280,"1293":1280,"1294":1280,"1295":1280,"1313":1312,"1314":1312,"1315":1312,"1316":1312,"1317":1312,"1318":1312,"1319":1312,"1320":1312,"1321":1312,"1322":1312,"1323":1312,"1324":1312,"1325":1312,"1326":1312,"1327":1312,"1345":1344,"1346":1344,"1347":1344,"1348":1344,"1349":1344,"1350":1344,"1351":1344,"1352":1344,"1353":1344,"1354":1344,"1355":1344,"1356":1344,"1357":1344,"1358":1344,"1359":1344,"1366":1360,"1367":1360,"1368":1360,"1369":1360,"1370":1360,"1371":1360,"1372":1360,"1373":1360,"1374":1360,"1375":1360,"1377":1376,"1378":1376,"1379":1376,"1380":1376,"1381":1376,"1382":1376,"1383":1376,"1384":1376,"1385":1376,"1386":1376,"1387":1376,"1388":1376,"1389":1376,"1390":1376,"1391":1376,"1393":1392,"1394":1392,"1395":1392,"1396":1392,"1397":1392,"1398":1392,"1399":1392,"1400":1392,"1401":1392,"1402":1392,"1403":1392,"1404":1392,"1405":1392,"1406":1392,"1407":1392,"1409":1408,"1410":1408,"1411":1408,"1412":1408,"1413":1408,"1414":1408,"1415":1408,"1416":1408,"1417":1408,"1418":1408,"1419":1408,"1420":1408,"1421":1408,"1422":1408,"1423":1408,"1425":1424,"1426":1424,"1427":1424,"1428":1424,"1429":1424,"1430":1424,"1431":1424,"1432":1424,"1433":1424,"1434":1424,"1435":1424,"1436":1424,"1437":1424,"1438":1424,"1439":1424,"1440":1441,"1443":1441,"1444":1441,"1445":1441,"1446":1441,"1447":1441,"1448":1441,"1449":1441,"1450":1441,"1451":1441,"1452":1441,"1453":1441,"1454":1441,"1455":1441,"1460":1458,"1461":1458,"1462":1458,"1463":1458,"1464":1458,"1465":1458,"1466":1458,"1467":1458,"1468":1458,"1469":1458,"1470":1458,"1471":1458,"1479":1472,"1480":1472,"1481":1472,"1482":1472,"1483":1472,"1484":1472,"1485":1472,"1486":1472,"1487":1472,"1521":1520,"1522":1520,"1523":1520,"1524":1520,"1525":1520,"1526":1520,"1527":1520,"1528":1520,"1529":1520,"1530":1520,"1531":1520,"1532":1520,"1533":1520,"1534":1520,"1535":1520,"1558":1552,"1559":1552,"1560":1552,"1561":1552,"1562":1552,"1563":1552,"1564":1552,"1565":1552,"1566":1552,"1567":1552,"1572":1568,"1573":1568,"1574":1568,"1575":1568,"1576":1568,"1577":1568,"1578":1568,"1579":1568,"1580":1568,"1581":1568,"1582":1568,"1583":1568,"1595":1598,"1596":1598,"1597":1598,"1610":1594,"1611":1614,"1612":1614,"1613":1614,"1615":1599,"1617":1616,"1618":1616,"1619":1616,"1620":1616,"1621":1616,"1622":1616,"1623":1616,"1624":1616,"1625":1616,"1626":1616,"1627":1616,"1628":1616,"1629":1616,"1630":1616,"1631":1616,"1633":1632,"1634":1632,"1635":1632,"1636":1632,"1637":1632,"1638":1632,"1639":1632,"1640":1632,"1641":1632,"1642":1632,"1643":1632,"1644":1632,"1645":1632,"1646":1632,"1647":1632,"1649":1648,"1650":1648,"1651":1648,"1652":1648,"1653":1648,"1654":1648,"1655":1648,"1656":1648,"1657":1648,"1658":1648,"1659":1648,"1660":1648,"1661":1648,"1662":1648,"1663":1648,"1672":1664,"1673":1664,"1674":1664,"1675":1664,"1676":1664,"1677":1664,"1678":1664,"1679":1664,"1688":1680,"1689":1680,"1690":1680,"1691":1680,"1692":1680,"1693":1680,"1694":1680,"1695":1680,"1736":1731,"1737":1731,"1738":1731,"1739":1731,"1740":1731,"1741":1731,"1742":1731,"1743":1731,"1752":1747,"1753":1747,"1754":1747,"1755":1747,"1756":1747,"1757":1747,"1758":1747,"1759":1747,"1761":1760,"1762":1760,"1763":1760,"1764":1760,"1765":1760,"1766":1760,"1767":1760,"1768":1760,"1769":1760,"1770":1760,"1771":1760,"1772":1760,"1773":1760,"1774":1760,"1775":1760,"1777":1776,"1778":1776,"1779":1776,"1780":1776,"1781":1776,"1782":1776,"1783":1776,"1784":1776,"1785":1776,"1786":1776,"1787":1776,"1788":1776,"1789":1776,"1790":1776,"1791":1776,"1793":1792,"1794":1792,"1795":1792,"1796":1792,"1797":1792,"1798":1792,"1799":1792,"1800":1792,"1801":1792,"1802":1792,"1803":1792,"1804":1792,"1805":1792,"1806":1792,"1807":1792,"1809":1808,"1810":1808,"1811":1808,"1812":1808,"1813":1808,"1814":1808,"1815":1808,"1816":1808,"1817":1808,"1818":1808,"1819":1808,"1820":1808,"1821":1808,"1822":1808,"1823":1808,"1832":1827,"1833":1827,"1834":1827,"1835":1827,"1836":1827,"1837":1827,"1838":1827,"1839":1827,"1844":1840,"1845":1840,"1846":1840,"1847":1840,"1848":1840,"1849":1840,"1850":1840,"1851":1840,"1852":1840,"1853":1840,"1854":1840,"1855":1840,"1857":1856,"1858":1856,"1859":1856,"1860":1856,"1861":1856,"1862":1856,"1863":1856,"1864":1856,"1865":1856,"1866":1856,"1867":1856,"1868":1856,"1869":1856,"1870":1856,"1871":1856,"1880":1872,"1881":1872,"1882":1872,"1883":1872,"1884":1872,"1885":1872,"1886":1872,"1887":1872,"1928":1922,"1929":1922,"1930":1922,"1931":1922,"1932":1922,"1933":1922,"1934":1922,"1935":1922,"1937":1936,"1938":1936,"1939":1936,"1940":1936,"1941":1936,"1942":1936,"1943":1936,"1944":1936,"1945":1936,"1946":1936,"1947":1936,"1948":1936,"1949":1936,"1950":1936,"1951":1936,"1953":1952,"1954":1952,"1955":1952,"1956":1952,"1957":1952,"1958":1952,"1959":1952,"1960":1952,"1961":1952,"1962":1952,"1963":1952,"1964":1952,"1965":1952,"1966":1952,"1967":1952,"1969":1968,"1970":1968,"1971":1968,"1972":1968,"1973":1968,"1974":1968,"1975":1968,"1976":1968,"1977":1968,"1978":1968,"1979":1968,"1980":1968,"1981":1968,"1982":1968,"1983":1968,"1985":1968,"1986":1968,"1987":1968,"1988":1968,"1989":1968,"1990":1968,"1991":1968,"1992":1968,"1993":1968,"1994":1968,"1995":1968,"1996":1968,"1997":1968,"1998":1968,"1999":1968,"2022":2016,"2023":2016,"2030":2016,"2031":2016,"2044":2032,"2045":2032,"2046":2032,"2047":2032,"2056":2051,"2057":2051,"2058":2051,"2059":2051,"2060":2051,"2061":2051,"2062":2051,"2063":2051,"2065":2064,"2066":2064,"2067":2064,"2068":2064,"2069":2064,"2070":2064,"2071":2064,"2072":2064,"2073":2064,"2074":2064,"2075":2064,"2076":2064,"2077":2064,"2078":2064,"2079":2064,"2080":2082,"2081":2082,"2086":2082,"2087":2082,"2088":2082,"2089":2082,"2090":2082,"2091":2082,"2092":2082,"2093":2082,"2094":2082,"2095":2082,"2129":2128,"2130":2128,"2131":2128,"2132":2128,"2133":2128,"2134":2128,"2135":2128,"2136":2128,"2137":2128,"2138":2128,"2139":2128,"2140":2128,"2141":2128,"2142":2128,"2143":2128,"2152":2147,"2153":2147,"2154":2147,"2155":2147,"2156":2147,"2157":2147,"2158":2147,"2159":2147,"2168":2163,"2169":2163,"2170":2163,"2171":2163,"2172":2163,"2173":2163,"2174":2163,"2175":2163,"2184":2179,"2185":2179,"2186":2179,"2187":2179,"2188":2179,"2189":2179,"2190":2179,"2191":2179,"2209":2208,"2210":2208,"2211":2208,"2212":2208,"2213":2208,"2214":2208,"2215":2208,"2216":2208,"2217":2208,"2218":2208,"2219":2208,"2220":2208,"2221":2208,"2222":2208,"2223":2208,"2238":2224,"2239":2224,"2241":2240,"2242":2240,"2243":2240,"2244":2240,"2245":2240,"2246":2240,"2247":2240,"2248":2240,"2249":2240,"2250":2240,"2251":2240,"2252":2240,"2253":2240,"2254":2240,"2255":2240,"2264":2256,"2265":2256,"2266":2256,"2267":2256,"2268":2256,"2269":2256,"2270":2256,"2271":2256,"2280":2272,"2281":2272,"2282":2272,"2283":2272,"2284":2272,"2285":2272,"2286":2272,"2287":2272,"2294":2288,"2295":2288,"2302":2288,"2303":2288,"2304":2306,"2310":2306,"2311":2306,"2312":2306,"2313":2306,"2314":2306,"2315":2306,"2316":2306,"2317":2306,"2318":2306,"2319":2306,"2332":2322,"2333":2322,"2334":2322,"2335":2322,"2336":2338,"2337":2338,"2342":2338,"2343":2338,"2344":2338,"2345":2338,"2346":2338,"2347":2338,"2348":2338,"2349":2338,"2350":2338,"2351":2338,"2392":2386,"2393":2386,"2394":2386,"2395":2386,"2396":2386,"2397":2386,"2398":2386,"2399":2386,"2400":2386,"2401":2386,"2402":2386,"2403":2386,"2404":2386,"2405":2386,"2406":2386,"2407":2386,"2433":2432,"2434":2432,"2435":2432,"2436":2432,"2437":2432,"2438":2432,"2439":2432,"2440":2432,"2441":2432,"2442":2432,"2443":2432,"2444":2432,"2445":2432,"2446":2432,"2447":2432,"2449":2448,"2450":2448,"2451":2448,"2452":2448,"2453":2448,"2454":2448,"2455":2448,"2456":2448,"2457":2448,"2458":2448,"2459":2448,"2460":2448,"2461":2448,"2462":2448,"2463":2448,"2465":2464,"2470":2464,"2471":2464,"2473":2464,"2478":2464,"2479":2464,"2484":2480,"2487":2480,"2488":2480,"2491":2480,"2492":2480,"2493":2481,"2494":2482,"2495":2480,"2504":2499,"2505":2499,"2506":2499,"2507":2499,"2508":2499,"2509":2499,"2510":2499,"2511":2499,"2520":2512,"2521":2513,"2522":2514,"2523":2515,"2524":2516,"2525":2517,"2578":288,"2579":288,"2582":288,"2583":288,"2586":288,"2587":288,"2590":288,"2591":288,"2604":7476,"2605":7477,"2616":2611,"2617":2611,"2618":2611,"2619":2611,"2620":2611,"2621":2611,"2622":2611,"2623":2611,"2632":2627,"2633":2627,"2634":2627,"2635":2627,"2636":2627,"2637":2627,"2638":2627,"2639":2627,"2641":2640,"2642":2640,"2643":2640,"2644":2640,"2645":2640,"2646":2640,"2647":2640,"2648":2640,"2649":2640,"2650":2640,"2651":2640,"2652":2640,"2653":2640,"2654":2640,"2655":2640,"2691":2688,"2692":2688,"2693":2688,"2694":2688,"2695":2688,"2696":2688,"2697":2688,"2698":2688,"2699":2688,"2700":2688,"2701":2688,"2702":2688,"2703":2688,"2705":2704,"2706":2704,"2707":2704,"2708":2704,"2709":2704,"2710":2704,"2711":2704,"2712":2704,"2713":2704,"2714":2704,"2715":2704,"2716":2704,"2717":2704,"2718":2704,"2719":2704,"2721":2720,"2722":2720,"2723":2720,"2725":2720,"2726":2720,"2727":2720,"2729":2720,"2730":2720,"2731":2720,"2732":2720,"2733":2720,"2734":2720,"2735":2720,"2753":2752,"2754":2752,"2755":2752,"2756":2752,"2757":2752,"2758":2752,"2759":2752,"2760":2752,"2761":2752,"2762":2752,"2763":2752,"2764":2752,"2765":2752,"2766":2752,"2767":2752,"2769":2768,"2770":2768,"2771":2768,"2772":2768,"2773":2768,"2774":2768,"2775":2768,"2776":2768,"2777":2768,"2778":2768,"2779":2768,"2780":2768,"2781":2768,"2782":2768,"2783":2768,"2785":2784,"2786":2784,"2787":2784,"2788":2784,"2789":2784,"2790":2784,"2791":2784,"2792":2784,"2793":2784,"2794":2784,"2795":2784,"2796":2784,"2797":2784,"2798":2784,"2799":2784,"2806":2800,"2807":2800,"2814":2800,"2815":2800,"2832":2834,"2833":2834,"2838":2834,"2839":2834,"2840":2834,"2841":2834,"2842":2834,"2843":2834,"2844":2834,"2845":2834,"2846":2834,"2847":2834,"2868":2864,"2869":2864,"2870":2864,"2871":2864,"2872":2864,"2873":2864,"2874":2864,"2875":2864,"2876":2864,"2877":2864,"2878":2864,"2879":2864,"2888":2883,"2889":2883,"2890":2883,"2891":2883,"2892":2883,"2893":2883,"2894":2883,"2895":2883,"2904":2896,"2905":2897,"2906":2898,"2907":2899,"2908":2900,"2909":2901,"2910":2902,"2911":2903,"3041":3040,"3042":3040,"3043":3040,"3044":3040,"3045":3040,"3046":3040,"3047":3040,"3048":3040,"3049":3040,"3050":3040,"3051":3040,"3052":3040,"3053":3040,"3054":3040,"3055":3040,"3073":3072,"3074":3072,"3075":3072,"3076":3072,"3077":3072,"3078":3072,"3079":3072,"3080":3072,"3081":3072,"3082":3072,"3083":3072,"3084":3072,"3085":3072,"3086":3072,"3087":3072,"3100":3091,"3101":3091,"3102":3091,"3103":3091,"3116":3107,"3117":3107,"3118":3107,"3119":3107,"3132":3123,"3133":3123,"3134":3123,"3135":3123,"3148":3139,"3149":3139,"3150":3139,"3151":3139,"3164":3155,"3165":3155,"3166":3155,"3167":3155,"3169":3168,"3170":3168,"3171":3168,"3172":3168,"3173":3168,"3174":3168,"3175":3168,"3176":3168,"3177":3168,"3178":3168,"3179":3168,"3180":3168,"3181":3168,"3182":3168,"3183":3168,"3192":3187,"3193":3187,"3194":3187,"3195":3187,"3196":3187,"3197":3187,"3198":3187,"3199":3187,"3217":3216,"3219":3216,"3220":3216,"3221":3216,"3223":3216,"3224":3216,"3225":3216,"3227":3216,"3228":3216,"3229":3216,"3230":3218,"3231":3216,"3232":3237,"3238":3237,"3239":3237,"3240":3245,"3246":3245,"3247":3245,"3256":3251,"3257":3251,"3258":3251,"3259":3251,"3260":3251,"3261":3251,"3262":3251,"3263":3251,"3264":3269,"3270":3269,"3271":3269,"3272":3277,"3278":3277,"3279":3277,"3281":3280,"3282":3280,"3283":3280,"3284":3280,"3285":3280,"3286":3280,"3287":3280,"3288":3280,"3289":3280,"3290":3280,"3291":3280,"3292":3280,"3293":3280,"3294":3280,"3295":3280,"3297":3296,"3298":3296,"3299":3296,"3300":3296,"3301":3296,"3302":3296,"3303":3296,"3304":3296,"3305":3296,"3306":3296,"3307":3296,"3308":3296,"3309":3296,"3310":3296,"3311":3296,"3316":3312,"3317":3312,"3318":3312,"3319":3312,"3320":3312,"3321":3312,"3322":3312,"3323":3312,"3324":3312,"3325":3312,"3326":3312,"3327":3312,"3334":3328,"3335":3328,"3336":3328,"3337":3328,"3338":3328,"3339":3328,"3340":3328,"3341":3328,"3342":3328,"3343":3328,"3409":3408,"3410":3408,"3411":3408,"3412":3408,"3413":3408,"3414":3408,"3415":3408,"3416":3408,"3417":3408,"3418":3408,"3419":3408,"3420":3408,"3421":3408,"3422":3408,"3423":3408,"3425":3424,"3426":3424,"3427":3424,"3428":3424,"3429":3424,"3430":3424,"3431":3424,"3432":3424,"3433":3424,"3434":3424,"3435":3424,"3436":3424,"3437":3424,"3438":3424,"3439":3424,"3441":3440,"3442":3440,"3443":3440,"3444":3440,"3445":3440,"3446":3440,"3447":3440,"3448":3440,"3449":3440,"3450":3440,"3451":3440,"3452":3440,"3453":3440,"3454":3440,"3455":3440,"3457":3456,"3458":3456,"3459":3456,"3461":3456,"3462":3456,"3463":3456,"3465":3456,"3466":3456,"3467":3456,"3468":3456,"3469":3456,"3470":3456,"3471":3456,"3504":3506,"3505":3506,"3510":3506,"3511":3506,"3512":3506,"3513":3506,"3514":3506,"3515":3506,"3516":3506,"3517":3506,"3518":3506,"3519":3506,"3520":3522,"3521":3522,"3526":3522,"3527":3522,"3528":3522,"3529":3522,"3530":3522,"3531":3522,"3532":3522,"3533":3522,"3534":3522,"3535":3522,"3536":3538,"3537":3538,"3542":3538,"3543":3538,"3544":3538,"3545":3538,"3546":3538,"3547":3538,"3548":3538,"3549":3538,"3550":3538,"3551":3538,"3552":3554,"3553":3554,"3558":3554,"3559":3554,"3560":3554,"3561":3554,"3562":3554,"3563":3554,"3564":3554,"3565":3554,"3566":3554,"3567":3554,"3568":3570,"3569":3570,"3574":3570,"3575":3570,"3576":3570,"3577":3570,"3578":3570,"3579":3570,"3580":3570,"3581":3570,"3582":3570,"3583":3570,"3584":3586,"3585":3586,"3590":3586,"3591":3586,"3592":3586,"3593":3586,"3594":3586,"3595":3586,"3596":3586,"3597":3586,"3598":3586,"3599":3586,"3600":3602,"3601":3602,"3606":3602,"3607":3602,"3608":3602,"3609":3602,"3610":3602,"3611":3602,"3612":3602,"3613":3602,"3614":3602,"3615":3602,"3616":3618,"3617":3618,"3622":3618,"3623":3618,"3624":3618,"3625":3618,"3626":3618,"3627":3618,"3628":3618,"3629":3618,"3630":3618,"3631":3618,"3632":3634,"3633":3634,"3638":3634,"3639":3634,"3640":3634,"3641":3634,"3642":3634,"3643":3634,"3644":3634,"3645":3634,"3646":3634,"3647":3634,"3648":3650,"3649":3650,"3654":3650,"3655":3650,"3656":3650,"3657":3650,"3658":3650,"3659":3650,"3660":3650,"3661":3650,"3662":3650,"3663":3650,"3664":3666,"3665":3666,"3670":3666,"3671":3666,"3672":3666,"3673":3666,"3674":3666,"3675":3666,"3676":3666,"3677":3666,"3678":3666,"3679":3666,"3696":3698,"3697":3698,"3702":3698,"3703":3698,"3704":3698,"3705":3698,"3706":3698,"3707":3698,"3708":3698,"3709":3698,"3710":3698,"3711":3698,"3712":3714,"3713":3714,"3718":3714,"3719":3714,"3720":3714,"3721":3714,"3722":3714,"3723":3714,"3724":3714,"3725":3714,"3726":3714,"3727":3714,"3728":3730,"3729":3730,"3734":3730,"3735":3730,"3736":3730,"3737":3730,"3738":3730,"3739":3730,"3740":3730,"3741":3730,"3742":3730,"3743":3730,"3744":3746,"3745":3746,"3750":3746,"3751":3746,"3752":3746,"3753":3746,"3754":3746,"3755":3746,"3756":3746,"3757":3746,"3758":3746,"3759":3746,"3760":3762,"3761":3762,"3766":3762,"3767":3762,"3768":3762,"3769":3762,"3770":3762,"3771":3762,"3772":3762,"3773":3762,"3774":3762,"3775":3762,"3824":3829,"3830":3829,"3831":3829,"3832":3829,"3833":3829,"3834":3829,"3835":3829,"3836":3829,"3837":3829,"3838":3829,"3839":3829,"3889":3888,"3890":3888,"3891":3888,"3892":3888,"3893":3888,"3894":3888,"3895":3888,"3896":3888,"3897":3888,"3898":3888,"3899":3888,"3900":3888,"3901":3888,"3902":3888,"3903":3888,"3912":3904,"3913":3904,"3914":3904,"3915":3904,"3916":3904,"3917":3904,"3918":3904,"3919":3904,"3921":3920,"3922":3920,"3923":3920,"3924":3920,"3925":3920,"3926":3920,"3927":3920,"3928":3920,"3929":3920,"3930":3920,"3931":3920,"3932":3920,"3933":3920,"3934":3920,"3935":3920,"3937":3936,"3938":3936,"3939":3936,"3940":3936,"3941":3936,"3942":3936,"3943":3936,"3944":3936,"3945":3936,"3946":3936,"3947":3936,"3948":3936,"3949":3936,"3950":3936,"3951":3936,"3955":3952,"3956":3952,"3957":3952,"3958":3952,"3959":3952,"3960":3952,"3961":3952,"3962":3952,"3963":3952,"3964":3952,"3965":3952,"3966":3952,"3967":3952,"3969":3968,"3970":3968,"3971":3968,"3972":3968,"3973":3968,"3974":3968,"3975":3968,"3976":3968,"3977":3968,"3978":3968,"3979":3968,"3980":3968,"3981":3968,"3982":3968,"3983":3968,"3985":3984,"3986":3984,"3987":3984,"3988":3984,"3989":3984,"3990":3984,"3991":3984,"3992":3984,"3993":3984,"3994":3984,"3995":3984,"3996":3984,"3997":3984,"3998":3984,"3999":3984,"4049":4048,"4050":4048,"4051":4048,"4052":4048,"4053":4048,"4054":4048,"4055":4048,"4056":4048,"4057":4048,"4058":4048,"4059":4048,"4060":4048,"4061":4048,"4062":4048,"4063":4048,"4081":4080,"4082":4080,"4083":4080,"4084":4080,"4085":4080,"4086":4080,"4087":4080,"4088":4080,"4089":4080,"4090":4080,"4091":4080,"4092":4080,"4093":4080,"4094":4080,"4095":4080,"4120":4115,"4121":4115,"4122":4115,"4123":4115,"4124":4115,"4125":4115,"4126":4115,"4127":4115,"4136":4131,"4137":4131,"4138":4131,"4139":4131,"4140":4131,"4141":4131,"4142":4131,"4143":4131,"4152":4147,"4153":4147,"4154":4147,"4155":4147,"4156":4147,"4157":4147,"4158":4147,"4159":4147,"4163":4160,"4164":4160,"4165":4160,"4166":4160,"4167":4160,"4168":4160,"4169":4160,"4170":4160,"4171":4160,"4172":4160,"4173":4160,"4174":4160,"4175":4160,"4179":4176,"4180":4176,"4181":4176,"4182":4176,"4183":4176,"4184":4176,"4185":4176,"4186":4176,"4187":4176,"4188":4176,"4189":4176,"4190":4176,"4191":4176,"4195":4192,"4196":4192,"4197":4192,"4198":4192,"4199":4192,"4200":4192,"4201":4192,"4202":4192,"4203":4192,"4204":4192,"4205":4192,"4206":4192,"4207":4192,"4211":4208,"4212":4208,"4213":4208,"4214":4208,"4215":4208,"4216":4208,"4217":4208,"4218":4208,"4219":4208,"4220":4208,"4221":4208,"4222":4208,"4223":4208,"4227":4224,"4228":4224,"4229":4224,"4230":4224,"4231":4224,"4232":4224,"4233":4224,"4234":4224,"4235":4224,"4236":4224,"4237":4224,"4238":4224,"4239":4224,"4243":4240,"4244":4240,"4245":4240,"4246":4240,"4247":4240,"4248":4240,"4249":4240,"4250":4240,"4251":4240,"4252":4240,"4253":4240,"4254":4240,"4255":4240,"4257":4256,"4258":4256,"4259":4256,"4260":4256,"4261":4256,"4262":4256,"4263":4256,"4264":4256,"4265":4256,"4266":4256,"4267":4256,"4268":4256,"4269":4256,"4270":4256,"4271":4256,"4273":4272,"4274":4272,"4275":4272,"4276":4272,"4277":4272,"4278":4272,"4279":4272,"4280":4272,"4281":4272,"4282":4272,"4283":4272,"4284":4272,"4285":4272,"4286":4272,"4287":4272,"4289":4288,"4290":4288,"4291":4288,"4292":4288,"4293":4288,"4294":4288,"4295":4288,"4296":4288,"4297":4288,"4298":4288,"4299":4288,"4300":4288,"4301":4288,"4302":4288,"4303":4288,"4305":4304,"4306":4304,"4307":4304,"4308":4304,"4309":4304,"4310":4304,"4311":4304,"4312":4304,"4313":4304,"4314":4304,"4315":4304,"4316":4304,"4317":4304,"4318":4304,"4319":4304,"4321":4320,"4322":4320,"4323":4320,"4324":4320,"4325":4320,"4326":4320,"4327":4320,"4328":4320,"4329":4320,"4330":4320,"4331":4320,"4332":4320,"4333":4320,"4334":4320,"4335":4320,"4337":4336,"4338":4336,"4339":4336,"4340":4336,"4341":4336,"4342":4336,"4343":4336,"4344":4336,"4345":4336,"4346":4336,"4347":4336,"4348":4336,"4349":4336,"4350":4336,"4351":4336,"4353":4352,"4354":4352,"4355":4352,"4356":4352,"4357":4352,"4358":4352,"4359":4352,"4360":4352,"4361":4352,"4362":4352,"4363":4352,"4364":4352,"4365":4352,"4366":4352,"4367":4352,"4369":4368,"4370":4368,"4371":4368,"4372":4368,"4373":4368,"4374":4368,"4375":4368,"4376":4368,"4377":4368,"4378":4368,"4379":4368,"4380":4368,"4381":4368,"4382":4368,"4383":4368,"4385":4384,"4386":4384,"4387":4384,"4388":4384,"4389":4384,"4390":4384,"4391":4384,"4392":4384,"4393":4384,"4394":4384,"4395":4384,"4396":4384,"4397":4384,"4398":4384,"4399":4384,"4401":4400,"4402":4400,"4403":4400,"4404":4400,"4405":4400,"4406":4400,"4407":4400,"4408":4400,"4409":4400,"4410":4400,"4411":4400,"4412":4400,"4413":4400,"4414":4400,"4415":4400,"4417":4416,"4418":4416,"4419":4416,"4420":4416,"4421":4416,"4422":4416,"4423":4416,"4424":4416,"4425":4416,"4426":4416,"4427":4416,"4428":4416,"4429":4416,"4430":4416,"4431":4416,"4433":4432,"4434":4432,"4435":4432,"4436":4432,"4437":4432,"4438":4432,"4439":4432,"4440":4432,"4441":4432,"4442":4432,"4443":4432,"4444":4432,"4445":4432,"4446":4432,"4447":4432,"4449":4448,"4450":4448,"4451":4448,"4452":4448,"4453":4448,"4454":4448,"4455":4448,"4456":4448,"4457":4448,"4458":4448,"4459":4448,"4460":4448,"4461":4448,"4462":4448,"4463":4448,"4465":4464,"4466":4464,"4467":4464,"4468":4464,"4469":4464,"4470":4464,"4471":4464,"4472":4464,"4473":4464,"4474":4464,"4475":4464,"4476":4464,"4477":4464,"4478":4464,"4479":4464,"4481":4480,"4482":4480,"4483":4480,"4484":4480,"4485":4480,"4486":4480,"4487":4480,"4488":4480,"4489":4480,"4490":4480,"4491":4480,"4492":4480,"4493":4480,"4494":4480,"4495":4480,"4497":4496,"4498":4496,"4499":4496,"4500":4496,"4501":4496,"4502":4496,"4503":4496,"4504":4496,"4505":4496,"4506":4496,"4507":4496,"4508":4496,"4509":4496,"4510":4496,"4511":4496,"4513":4512,"4514":4512,"4515":4512,"4516":4512,"4517":4512,"4518":4512,"4519":4512,"4520":4512,"4521":4512,"4522":4512,"4523":4512,"4524":4512,"4525":4512,"4526":4512,"4527":4512,"4529":4528,"4530":4528,"4531":4528,"4532":4528,"4533":4528,"4534":4528,"4535":4528,"4536":4528,"4537":4528,"4538":4528,"4539":4528,"4540":4528,"4541":4528,"4542":4528,"4543":4528,"4545":4544,"4546":4544,"4547":4544,"4548":4544,"4549":4544,"4550":4544,"4551":4544,"4552":4544,"4553":4544,"4554":4544,"4555":4544,"4556":4544,"4557":4544,"4558":4544,"4559":4544,"4561":4560,"4562":4560,"4563":4560,"4564":4560,"4565":4560,"4566":4560,"4567":4560,"4568":4560,"4569":4560,"4570":4560,"4571":4560,"4572":4560,"4573":4560,"4574":4560,"4575":4560,"4577":4576,"4578":4576,"4579":4576,"4580":4576,"4581":4576,"4582":4576,"4583":4576,"4584":4576,"4585":4576,"4586":4576,"4587":4576,"4588":4576,"4589":4576,"4590":4576,"4591":4576,"4593":4592,"4594":4592,"4595":4592,"4596":4592,"4597":4592,"4598":4592,"4599":4592,"4600":4592,"4601":4592,"4602":4592,"4603":4592,"4604":4592,"4605":4592,"4606":4592,"4607":4592,"4609":4608,"4610":4608,"4611":4608,"4612":4608,"4613":4608,"4614":4608,"4615":4608,"4616":4608,"4617":4608,"4618":4608,"4619":4608,"4620":4608,"4621":4608,"4622":4608,"4623":4608,"4625":4624,"4626":4624,"4627":4624,"4628":4624,"4629":4624,"4630":4624,"4631":4624,"4632":4624,"4633":4624,"4634":4624,"4635":4624,"4636":4624,"4637":4624,"4638":4624,"4639":4624,"4641":4640,"4642":4640,"4643":4640,"4644":4640,"4645":4640,"4646":4640,"4647":4640,"4648":4640,"4649":4640,"4650":4640,"4651":4640,"4652":4640,"4653":4640,"4654":4640,"4655":4640,"4657":4656,"4658":4656,"4659":4656,"4660":4656,"4661":4656,"4662":4656,"4663":4656,"4664":4656,"4665":4656,"4666":4656,"4667":4656,"4668":4656,"4669":4656,"4670":4656,"4671":4656,"4673":4672,"4674":4672,"4675":4672,"4676":4672,"4677":4672,"4678":4672,"4679":4672,"4680":4672,"4681":4672,"4682":4672,"4683":4672,"4684":4672,"4685":4672,"4686":4672,"4687":4672,"4689":4688,"4690":4688,"4691":4688,"4692":4688,"4693":4688,"4694":4688,"4695":4688,"4696":4688,"4697":4688,"4698":4688,"4699":4688,"4700":4688,"4701":4688,"4702":4688,"4703":4688,"4705":4704,"4706":4704,"4707":4704,"4708":4704,"4709":4704,"4710":4704,"4711":4704,"4712":4704,"4713":4704,"4714":4704,"4715":4704,"4716":4704,"4717":4704,"4718":4704,"4719":4704,"4721":4720,"4722":4720,"4723":4720,"4724":4720,"4725":4720,"4726":4720,"4727":4720,"4728":4720,"4729":4720,"4730":4720,"4731":4720,"4732":4720,"4733":4720,"4734":4720,"4735":4720,"4737":4736,"4738":4736,"4739":4736,"4740":4736,"4741":4736,"4742":4736,"4743":4736,"4744":4736,"4745":4736,"4746":4736,"4747":4736,"4748":4736,"4749":4736,"4750":4736,"4751":4736,"4753":4752,"4754":4752,"4755":4752,"4756":4752,"4757":4752,"4758":4752,"4759":4752,"4760":4752,"4761":4752,"4762":4752,"4763":4752,"4764":4752,"4765":4752,"4766":4752,"4767":4752,"4769":4768,"4770":4768,"4771":4768,"4772":4768,"4773":4768,"4774":4768,"4775":4768,"4776":4768,"4777":4768,"4778":4768,"4779":4768,"4780":4768,"4781":4768,"4782":4768,"4783":4768,"4785":4784,"4786":4784,"4787":4784,"4788":4784,"4789":4784,"4790":4784,"4791":4784,"4792":4784,"4793":4784,"4794":4784,"4795":4784,"4796":4784,"4797":4784,"4798":4784,"4799":4784,"4801":4800,"4802":4800,"4803":4800,"4804":4800,"4805":4800,"4806":4800,"4807":4800,"4808":4800,"4809":4800,"4810":4800,"4811":4800,"4812":4800,"4813":4800,"4814":4800,"4815":4800,"4817":4816,"4818":4816,"4819":4816,"4820":4816,"4821":4816,"4822":4816,"4823":4816,"4824":4816,"4825":4816,"4826":4816,"4827":4816,"4828":4816,"4829":4816,"4830":4816,"4831":4816,"4833":4832,"4834":4832,"4835":4832,"4836":4832,"4837":4832,"4838":4832,"4839":4832,"4840":4832,"4841":4832,"4842":4832,"4843":4832,"4844":4832,"4845":4832,"4846":4832,"4847":4832,"4849":4848,"4850":4848,"4851":4848,"4852":4848,"4853":4848,"4854":4848,"4855":4848,"4856":4848,"4857":4848,"4858":4848,"4859":4848,"4860":4848,"4861":4848,"4862":4848,"4863":4848,"4865":4864,"4866":4864,"4867":4864,"4868":4864,"4869":4864,"4870":4864,"4871":4864,"4872":4864,"4873":4864,"4874":4864,"4875":4864,"4876":4864,"4877":4864,"4878":4864,"4879":4864,"4881":4880,"4882":4880,"4883":4880,"4884":4880,"4885":4880,"4886":4880,"4887":4880,"4888":4880,"4889":4880,"4890":4880,"4891":4880,"4892":4880,"4893":4880,"4894":4880,"4895":4880,"4897":4896,"4898":4896,"4899":4896,"4900":4896,"4901":4896,"4902":4896,"4903":4896,"4904":4896,"4905":4896,"4906":4896,"4907":4896,"4908":4896,"4909":4896,"4910":4896,"4911":4896,"4913":4912,"4914":4912,"4915":4912,"4916":4912,"4917":4912,"4918":4912,"4919":4912,"4920":4912,"4921":4912,"4922":4912,"4923":4912,"4924":4912,"4925":4912,"4926":4912,"4927":4912,"4929":4928,"4930":4928,"4931":4928,"4932":4928,"4933":4928,"4934":4928,"4935":4928,"4936":4928,"4937":4928,"4938":4928,"4939":4928,"4940":4928,"4941":4928,"4942":4928,"4943":4928,"4945":4944,"4946":4944,"4947":4944,"4948":4944,"4949":4944,"4950":4944,"4951":4944,"4952":4944,"4953":4944,"4954":4944,"4955":4944,"4956":4944,"4957":4944,"4958":4944,"4959":4944,"4961":4960,"4962":4960,"4963":4960,"4964":4960,"4965":4960,"4966":4960,"4967":4960,"4968":4960,"4969":4960,"4970":4960,"4971":4960,"4972":4960,"4973":4960,"4974":4960,"4975":4960,"4977":4976,"4978":4976,"4979":4976,"4980":4976,"4981":4976,"4982":4976,"4983":4976,"4984":4976,"4985":4976,"4986":4976,"4987":4976,"4988":4976,"4989":4976,"4990":4976,"4991":4976,"4993":4992,"4994":4992,"4995":4992,"4996":4992,"4997":4992,"4998":4992,"4999":4992,"5000":4992,"5001":4992,"5002":4992,"5003":4992,"5004":4992,"5005":4992,"5006":4992,"5007":4992,"5009":5008,"5010":5008,"5011":5008,"5012":5008,"5013":5008,"5014":5008,"5015":5008,"5016":5008,"5017":5008,"5018":5008,"5019":5008,"5020":5008,"5021":5008,"5022":5008,"5023":5008,"5025":5024,"5026":5024,"5027":5024,"5028":5024,"5029":5024,"5030":5024,"5031":5024,"5032":5024,"5033":5024,"5034":5024,"5035":5024,"5036":5024,"5037":5024,"5038":5024,"5039":5024,"5041":5040,"5042":5040,"5043":5040,"5044":5040,"5045":5040,"5046":5040,"5047":5040,"5048":5040,"5049":5040,"5050":5040,"5051":5040,"5052":5040,"5053":5040,"5054":5040,"5055":5040,"5057":5056,"5058":5056,"5059":5056,"5060":5056,"5061":5056,"5062":5056,"5063":5056,"5064":5056,"5065":5056,"5066":5056,"5067":5056,"5068":5056,"5069":5056,"5070":5056,"5071":5056,"5073":5072,"5074":5072,"5075":5072,"5076":5072,"5077":5072,"5078":5072,"5079":5072,"5080":5072,"5081":5072,"5082":5072,"5083":5072,"5084":5072,"5085":5072,"5086":5072,"5087":5072,"5089":5088,"5090":5088,"5091":5088,"5092":5088,"5093":5088,"5094":5088,"5095":5088,"5096":5088,"5097":5088,"5098":5088,"5099":5088,"5100":5088,"5101":5088,"5102":5088,"5103":5088,"5105":5104,"5106":5104,"5107":5104,"5108":5104,"5109":5104,"5110":5104,"5111":5104,"5112":5104,"5113":5104,"5114":5104,"5115":5104,"5116":5104,"5117":5104,"5118":5104,"5119":5104,"5121":5120,"5122":5120,"5123":5120,"5124":5120,"5125":5120,"5126":5120,"5127":5120,"5128":5120,"5129":5120,"5130":5120,"5131":5120,"5132":5120,"5133":5120,"5134":5120,"5135":5120,"5137":5136,"5138":5136,"5139":5136,"5140":5136,"5141":5136,"5142":5136,"5143":5136,"5144":5136,"5145":5136,"5146":5136,"5147":5136,"5148":5136,"5149":5136,"5150":5136,"5151":5136,"5153":5152,"5154":5152,"5155":5152,"5156":5152,"5157":5152,"5158":5152,"5159":5152,"5160":5152,"5161":5152,"5162":5152,"5163":5152,"5164":5152,"5165":5152,"5166":5152,"5167":5152,"5169":5168,"5170":5168,"5171":5168,"5172":5168,"5173":5168,"5174":5168,"5175":5168,"5176":5168,"5177":5168,"5178":5168,"5179":5168,"5180":5168,"5181":5168,"5182":5168,"5183":5168,"5185":5184,"5186":5184,"5187":5184,"5188":5184,"5189":5184,"5190":5184,"5191":5184,"5192":5184,"5193":5184,"5194":5184,"5195":5184,"5196":5184,"5197":5184,"5198":5184,"5199":5184,"5201":5200,"5202":5200,"5203":5200,"5204":5200,"5205":5200,"5206":5200,"5207":5200,"5208":5200,"5209":5200,"5210":5200,"5211":5200,"5212":5200,"5213":5200,"5214":5200,"5215":5200,"5217":5216,"5218":5216,"5219":5216,"5220":5216,"5221":5216,"5222":5216,"5223":5216,"5224":5216,"5225":5216,"5226":5216,"5227":5216,"5228":5216,"5229":5216,"5230":5216,"5231":5216,"5233":5232,"5234":5232,"5235":5232,"5236":5232,"5237":5232,"5238":5232,"5239":5232,"5240":5232,"5241":5232,"5242":5232,"5243":5232,"5244":5232,"5245":5232,"5246":5232,"5247":5232,"5249":5248,"5250":5248,"5251":5248,"5252":5248,"5253":5248,"5254":5248,"5255":5248,"5256":5248,"5257":5248,"5258":5248,"5259":5248,"5260":5248,"5261":5248,"5262":5248,"5263":5248,"5265":5264,"5266":5264,"5267":5264,"5268":5264,"5269":5264,"5270":5264,"5271":5264,"5272":5264,"5273":5264,"5274":5264,"5275":5264,"5276":5264,"5277":5264,"5278":5264,"5279":5264,"5281":5280,"5282":5280,"5283":5280,"5284":5280,"5285":5280,"5286":5280,"5287":5280,"5288":5280,"5289":5280,"5290":5280,"5291":5280,"5292":5280,"5293":5280,"5294":5280,"5295":5280,"5297":5296,"5298":5296,"5299":5296,"5300":5296,"5301":5296,"5302":5296,"5303":5296,"5304":5296,"5305":5296,"5306":5296,"5307":5296,"5308":5296,"5309":5296,"5310":5296,"5311":5296,"5313":5312,"5314":5312,"5315":5312,"5316":5312,"5317":5312,"5318":5312,"5319":5312,"5320":5312,"5321":5312,"5322":5312,"5323":5312,"5324":5312,"5325":5312,"5326":5312,"5327":5312,"5329":5328,"5330":5328,"5331":5328,"5332":5328,"5333":5328,"5334":5328,"5335":5328,"5336":5328,"5337":5328,"5338":5328,"5339":5328,"5340":5328,"5341":5328,"5342":5328,"5343":5328,"5345":5344,"5346":5344,"5347":5344,"5348":5344,"5349":5344,"5350":5344,"5351":5344,"5352":5344,"5353":5344,"5354":5344,"5355":5344,"5356":5344,"5357":5344,"5358":5344,"5359":5344,"5361":5360,"5362":5360,"5363":5360,"5364":5360,"5365":5360,"5366":5360,"5367":5360,"5368":5360,"5369":5360,"5370":5360,"5371":5360,"5372":5360,"5373":5360,"5374":5360,"5375":5360,"5377":5376,"5378":5376,"5379":5376,"5380":5376,"5381":5376,"5382":5376,"5383":5376,"5384":5376,"5385":5376,"5386":5376,"5387":5376,"5388":5376,"5389":5376,"5390":5376,"5391":5376,"5393":5392,"5394":5392,"5395":5392,"5396":5392,"5397":5392,"5398":5392,"5399":5392,"5400":5392,"5401":5392,"5402":5392,"5403":5392,"5404":5392,"5405":5392,"5406":5392,"5407":5392,"5409":5408,"5410":5408,"5411":5408,"5412":5408,"5413":5408,"5414":5408,"5415":5408,"5416":5408,"5417":5408,"5418":5408,"5419":5408,"5420":5408,"5421":5408,"5422":5408,"5423":5408,"5425":5424,"5426":5424,"5427":5424,"5428":5424,"5429":5424,"5430":5424,"5431":5424,"5432":5424,"5433":5424,"5434":5424,"5435":5424,"5436":5424,"5437":5424,"5438":5424,"5439":5424,"5441":5440,"5442":5440,"5443":5440,"5444":5440,"5445":5440,"5446":5440,"5447":5440,"5448":5440,"5449":5440,"5450":5440,"5451":5440,"5452":5440,"5453":5440,"5454":5440,"5455":5440,"5457":5456,"5458":5456,"5459":5456,"5460":5456,"5461":5456,"5462":5456,"5463":5456,"5464":5456,"5465":5456,"5466":5456,"5467":5456,"5468":5456,"5469":5456,"5470":5456,"5471":5456,"5473":5472,"5474":5472,"5475":5472,"5476":5472,"5477":5472,"5478":5472,"5479":5472,"5480":5472,"5481":5472,"5482":5472,"5483":5472,"5484":5472,"5485":5472,"5486":5472,"5487":5472,"5489":5488,"5490":5488,"5491":5488,"5492":5488,"5493":5488,"5494":5488,"5495":5488,"5496":5488,"5497":5488,"5498":5488,"5499":5488,"5500":5488,"5501":5488,"5502":5488,"5503":5488,"5505":5504,"5506":5504,"5507":5504,"5508":5504,"5509":5504,"5510":5504,"5511":5504,"5512":5504,"5513":5504,"5514":5504,"5515":5504,"5516":5504,"5517":5504,"5518":5504,"5519":5504,"5521":5520,"5522":5520,"5523":5520,"5524":5520,"5525":5520,"5526":5520,"5527":5520,"5528":5520,"5529":5520,"5530":5520,"5531":5520,"5532":5520,"5533":5520,"5534":5520,"5535":5520,"5537":5536,"5538":5536,"5539":5536,"5540":5536,"5541":5536,"5542":5536,"5543":5536,"5544":5536,"5545":5536,"5546":5536,"5547":5536,"5548":5536,"5549":5536,"5550":5536,"5551":5536,"5553":5552,"5554":5552,"5555":5552,"5556":5552,"5557":5552,"5558":5552,"5559":5552,"5560":5552,"5561":5552,"5562":5552,"5563":5552,"5564":5552,"5565":5552,"5566":5552,"5567":5552,"5569":5568,"5570":5568,"5571":5568,"5572":5568,"5573":5568,"5574":5568,"5575":5568,"5576":5568,"5577":5568,"5578":5568,"5579":5568,"5580":5568,"5581":5568,"5582":5568,"5583":5568,"5585":5584,"5586":5584,"5587":5584,"5588":5584,"5589":5584,"5590":5584,"5591":5584,"5592":5584,"5593":5584,"5594":5584,"5595":5584,"5596":5584,"5597":5584,"5598":5584,"5599":5584,"5601":5600,"5602":5600,"5603":5600,"5604":5600,"5605":5600,"5606":5600,"5607":5600,"5608":5600,"5609":5600,"5610":5600,"5611":5600,"5612":5600,"5613":5600,"5614":5600,"5615":5600,"5617":5616,"5618":5616,"5619":5616,"5620":5616,"5621":5616,"5622":5616,"5623":5616,"5624":5616,"5625":5616,"5626":5616,"5627":5616,"5628":5616,"5629":5616,"5630":5616,"5631":5616,"5633":5632,"5634":5632,"5635":5632,"5636":5632,"5637":5632,"5638":5632,"5639":5632,"5640":5632,"5641":5632,"5642":5632,"5643":5632,"5644":5632,"5645":5632,"5646":5632,"5647":5632,"5649":5648,"5650":5648,"5651":5648,"5652":5648,"5653":5648,"5654":5648,"5655":5648,"5656":5648,"5657":5648,"5658":5648,"5659":5648,"5660":5648,"5661":5648,"5662":5648,"5663":5648,"5665":5664,"5666":5664,"5667":5664,"5668":5664,"5669":5664,"5670":5664,"5671":5664,"5672":5664,"5673":5664,"5674":5664,"5675":5664,"5676":5664,"5677":5664,"5678":5664,"5679":5664,"5681":5680,"5682":5680,"5683":5680,"5684":5680,"5685":5680,"5686":5680,"5687":5680,"5688":5680,"5689":5680,"5690":5680,"5691":5680,"5692":5680,"5693":5680,"5694":5680,"5695":5680,"5697":5696,"5698":5696,"5699":5696,"5700":5696,"5701":5696,"5702":5696,"5703":5696,"5704":5696,"5705":5696,"5706":5696,"5707":5696,"5708":5696,"5709":5696,"5710":5696,"5711":5696,"5713":5712,"5714":5712,"5715":5712,"5716":5712,"5717":5712,"5718":5712,"5719":5712,"5720":5712,"5721":5712,"5722":5712,"5723":5712,"5724":5712,"5725":5712,"5726":5712,"5727":5712,"5729":5728,"5730":5728,"5731":5728,"5732":5728,"5733":5728,"5734":5728,"5735":5728,"5736":5728,"5737":5728,"5738":5728,"5739":5728,"5740":5728,"5741":5728,"5742":5728,"5743":5728,"5745":5744,"5746":5744,"5747":5744,"5748":5744,"5749":5744,"5750":5744,"5751":5744,"5752":5744,"5753":5744,"5754":5744,"5755":5744,"5756":5744,"5757":5744,"5758":5744,"5759":5744,"5761":5760,"5762":5760,"5763":5760,"5764":5760,"5765":5760,"5766":5760,"5767":5760,"5768":5760,"5769":5760,"5770":5760,"5771":5760,"5772":5760,"5773":5760,"5774":5760,"5775":5760,"5777":5776,"5778":5776,"5779":5776,"5780":5776,"5781":5776,"5782":5776,"5783":5776,"5784":5776,"5785":5776,"5786":5776,"5787":5776,"5788":5776,"5789":5776,"5790":5776,"5791":5776,"5793":5792,"5794":5792,"5795":5792,"5796":5792,"5797":5792,"5798":5792,"5799":5792,"5800":5792,"5801":5792,"5802":5792,"5803":5792,"5804":5792,"5805":5792,"5806":5792,"5807":5792,"5809":5808,"5810":5808,"5811":5808,"5812":5808,"5813":5808,"5814":5808,"5815":5808,"5816":5808,"5817":5808,"5818":5808,"5819":5808,"5820":5808,"5821":5808,"5822":5808,"5823":5808,"5825":5824,"5826":5824,"5827":5824,"5828":5824,"5829":5824,"5830":5824,"5831":5824,"5832":5824,"5833":5824,"5834":5824,"5835":5824,"5836":5824,"5837":5824,"5838":5824,"5839":5824,"5841":5840,"5842":5840,"5843":5840,"5844":5840,"5845":5840,"5846":5840,"5847":5840,"5848":5840,"5849":5840,"5850":5840,"5851":5840,"5852":5840,"5853":5840,"5854":5840,"5855":5840,"5857":5856,"5858":5856,"5859":5856,"5860":5856,"5861":5856,"5862":5856,"5863":5856,"5864":5856,"5865":5856,"5866":5856,"5867":5856,"5868":5856,"5869":5856,"5870":5856,"5871":5856,"5873":5872,"5874":5872,"5875":5872,"5876":5872,"5877":5872,"5878":5872,"5879":5872,"5880":5872,"5881":5872,"5882":5872,"5883":5872,"5884":5872,"5885":5872,"5886":5872,"5887":5872,"5889":5888,"5890":5888,"5891":5888,"5892":5888,"5893":5888,"5894":5888,"5895":5888,"5896":5888,"5897":5888,"5898":5888,"5899":5888,"5900":5888,"5901":5888,"5902":5888,"5903":5888,"5905":5904,"5906":5904,"5907":5904,"5908":5904,"5909":5904,"5910":5904,"5911":5904,"5912":5904,"5913":5904,"5914":5904,"5915":5904,"5916":5904,"5917":5904,"5918":5904,"5919":5904,"5921":5920,"5922":5920,"5923":5920,"5924":5920,"5925":5920,"5926":5920,"5927":5920,"5928":5920,"5929":5920,"5930":5920,"5931":5920,"5932":5920,"5933":5920,"5934":5920,"5935":5920,"5937":5936,"5938":5936,"5939":5936,"5940":5936,"5941":5936,"5942":5936,"5943":5936,"5944":5936,"5945":5936,"5946":5936,"5947":5936,"5948":5936,"5949":5936,"5950":5936,"5951":5936,"5953":5952,"5954":5952,"5955":5952,"5956":5952,"5957":5952,"5958":5952,"5959":5952,"5960":5952,"5961":5952,"5962":5952,"5963":5952,"5964":5952,"5965":5952,"5966":5952,"5967":5952,"5969":5968,"5970":5968,"5971":5968,"5972":5968,"5973":5968,"5974":5968,"5975":5968,"5976":5968,"5977":5968,"5978":5968,"5979":5968,"5980":5968,"5981":5968,"5982":5968,"5983":5968,"5985":5984,"5986":5984,"5987":5984,"5988":5984,"5989":5984,"5990":5984,"5991":5984,"5992":5984,"5993":5984,"5994":5984,"5995":5984,"5996":5984,"5997":5984,"5998":5984,"5999":5984,"6001":6000,"6002":6000,"6003":6000,"6004":6000,"6005":6000,"6006":6000,"6007":6000,"6008":6000,"6009":6000,"6010":6000,"6011":6000,"6012":6000,"6013":6000,"6014":6000,"6015":6000,"6017":6016,"6018":6016,"6019":6016,"6020":6016,"6021":6016,"6022":6016,"6023":6016,"6024":6016,"6025":6016,"6026":6016,"6027":6016,"6028":6016,"6029":6016,"6030":6016,"6031":6016,"6033":6032,"6034":6032,"6035":6032,"6036":6032,"6037":6032,"6038":6032,"6039":6032,"6040":6032,"6041":6032,"6042":6032,"6043":6032,"6044":6032,"6045":6032,"6046":6032,"6047":6032,"6049":6048,"6050":6048,"6051":6048,"6052":6048,"6053":6048,"6054":6048,"6055":6048,"6056":6048,"6057":6048,"6058":6048,"6059":6048,"6060":6048,"6061":6048,"6062":6048,"6063":6048,"6065":6064,"6066":6064,"6067":6064,"6068":6064,"6069":6064,"6070":6064,"6071":6064,"6072":6064,"6073":6064,"6074":6064,"6075":6064,"6076":6064,"6077":6064,"6078":6064,"6079":6064,"6081":6080,"6082":6080,"6083":6080,"6084":6080,"6085":6080,"6086":6080,"6087":6080,"6088":6080,"6089":6080,"6090":6080,"6091":6080,"6092":6080,"6093":6080,"6094":6080,"6095":6080,"6097":6096,"6098":6096,"6099":6096,"6100":6096,"6101":6096,"6102":6096,"6103":6096,"6104":6096,"6105":6096,"6106":6096,"6107":6096,"6108":6096,"6109":6096,"6110":6096,"6111":6096,"6113":6112,"6114":6112,"6115":6112,"6116":6112,"6117":6112,"6118":6112,"6119":6112,"6120":6112,"6121":6112,"6122":6112,"6123":6112,"6124":6112,"6125":6112,"6126":6112,"6127":6112,"6129":6128,"6130":6128,"6131":6128,"6132":6128,"6133":6128,"6134":6128,"6135":6128,"6136":6128,"6137":6128,"6138":6128,"6139":6128,"6140":6128,"6141":6128,"6142":6128,"6143":6128,"6145":6144,"6146":6144,"6147":6144,"6148":6144,"6149":6144,"6150":6144,"6151":6144,"6152":6144,"6153":6144,"6154":6144,"6155":6144,"6156":6144,"6157":6144,"6158":6144,"6159":6144,"6181":6176,"6182":6176,"6183":6176,"6184":6176,"6185":6176,"6186":6176,"6187":6176,"6188":6176,"6189":6176,"6190":6176,"6191":6176,"6197":6192,"6198":6192,"6199":6192,"6205":6192,"6206":6192,"6207":6192,"6213":6208,"6214":6208,"6215":6208,"6221":6208,"6222":6208,"6223":6208,"6229":6208,"6230":6208,"6231":6208,"6237":6208,"6238":6208,"6239":6208,"6273":6248,"6275":6248,"6277":6248,"6279":6248,"6281":6248,"6283":6248,"6285":6248,"6287":6248,"6305":6304,"6306":6304,"6307":6304,"6308":6304,"6309":6304,"6310":6304,"6311":6304,"6312":6304,"6313":6304,"6314":6304,"6315":6304,"6316":6304,"6317":6304,"6318":6304,"6319":6304,"6326":6320,"6327":6320,"6334":6320,"6335":6320,"6342":6336,"6343":6336,"6350":6336,"6351":6336,"6358":6352,"6359":6352,"6366":6352,"6367":6352,"6374":6368,"6375":6368,"6382":6368,"6383":6368,"6390":6384,"6391":6384,"6398":6384,"6399":6384,"6482":6480,"6483":6480,"6484":6480,"6485":6480,"6486":6480,"6487":6480,"6488":6480,"6489":6480,"6490":6480,"6491":6480,"6492":6480,"6493":6480,"6494":6480,"6495":6480,"6498":6496,"6499":6496,"6500":6496,"6501":6496,"6502":6496,"6503":6496,"6504":6496,"6505":6496,"6506":6496,"6507":6496,"6508":6496,"6509":6496,"6510":6496,"6511":6496,"6514":6512,"6515":6512,"6516":6512,"6517":6512,"6518":6512,"6519":6512,"6520":6512,"6521":6512,"6522":6512,"6523":6512,"6524":6512,"6525":6512,"6526":6512,"6527":6512,"6530":6528,"6531":6528,"6532":6528,"6533":6528,"6534":6528,"6535":6528,"6536":6528,"6537":6528,"6538":6528,"6539":6528,"6540":6528,"6541":6528,"6542":6528,"6543":6528,"6546":6544,"6547":6544,"6548":6544,"6549":6544,"6550":6544,"6551":6544,"6552":6544,"6553":6544,"6554":6544,"6555":6544,"6556":6544,"6557":6544,"6558":6544,"6559":6544,"6564":6562,"6565":6562,"6566":6562,"6567":6562,"6568":6562,"6569":6562,"6570":6562,"6571":6562,"6572":6562,"6573":6562,"6574":6562,"6575":6562,"6584":6580,"6585":6580,"6586":6580,"6587":6580,"6588":6580,"6589":6580,"6590":6580,"6591":6580,"6657":6656,"6658":6656,"6659":6656,"6660":6656,"6661":6656,"6662":6656,"6663":6656,"6664":6656,"6665":6656,"6666":6656,"6667":6656,"6668":6656,"6669":6656,"6670":6656,"6671":6656,"6694":6688,"6695":6688,"6702":6688,"6703":6688,"6705":6704,"6706":6704,"6707":6704,"6708":6704,"6709":6704,"6710":6704,"6711":6704,"6713":6704,"6714":6704,"6715":6704,"6716":6704,"6717":6704,"6718":6704,"6719":6704,"6760":6752,"6761":6753,"6762":6754,"6763":6755,"6764":6756,"6765":6757,"6766":6758,"6767":6759,"6776":6768,"6777":6769,"6778":6770,"6779":6771,"6780":6772,"6792":6787,"6793":6787,"6794":6787,"6795":6787,"6796":6787,"6797":6787,"6798":6787,"6799":6787,"6808":6803,"6809":6803,"6810":6803,"6811":6803,"6812":6803,"6813":6803,"6814":6803,"6815":6803,"6824":6819,"6825":6819,"6826":6819,"6827":6819,"6828":6819,"6829":6819,"6830":6819,"6831":6819,"6840":6835,"6841":6835,"6842":6835,"6843":6835,"6844":6835,"6845":6835,"6846":6835,"6847":6835,"6856":6851,"6857":6851,"6858":6851,"6859":6851,"6860":6851,"6861":6851,"6862":6851,"6863":6851,"6872":6867,"6873":6867,"6874":6867,"6875":6867,"6876":6867,"6877":6867,"6878":6867,"6879":6867,"6888":6883,"6889":6883,"6890":6883,"6891":6883,"6892":6883,"6893":6883,"6894":6883,"6895":6883,"6904":6899,"6905":6899,"6906":6899,"6907":6899,"6908":6899,"6909":6899,"6910":6899,"6911":6899,"6920":6915,"6921":6915,"6922":6915,"6923":6915,"6924":6915,"6925":6915,"6926":6915,"6927":6915,"6936":6931,"6937":6931,"6938":6931,"6939":6931,"6940":6931,"6941":6931,"6942":6931,"6943":6931,"6952":6947,"6953":6947,"6954":6947,"6955":6947,"6956":6947,"6957":6947,"6958":6947,"6959":6947,"6968":6963,"6969":6963,"6970":6963,"6971":6963,"6972":6963,"6973":6963,"6974":6963,"6975":6963,"6992":6994,"6993":6994,"6998":6994,"6999":6994,"7000":6994,"7001":6994,"7002":6994,"7003":6994,"7004":6994,"7005":6994,"7006":6994,"7007":6994,"7009":7008,"7010":7008,"7011":7008,"7012":7008,"7013":7008,"7014":7008,"7015":7008,"7016":7008,"7017":7008,"7018":7008,"7019":7008,"7020":7008,"7021":7008,"7022":7008,"7023":7008,"7032":7027,"7033":7027,"7034":7027,"7035":7027,"7036":7027,"7037":7027,"7038":7027,"7039":7027,"7048":7043,"7049":7043,"7050":7043,"7051":7043,"7052":7043,"7053":7043,"7054":7043,"7055":7043,"7072":7074,"7073":7074,"7078":7074,"7079":7074,"7080":7074,"7081":7074,"7082":7074,"7083":7074,"7084":7074,"7085":7074,"7086":7074,"7087":7074,"7104":7106,"7105":7106,"7110":7106,"7111":7106,"7112":7106,"7113":7106,"7114":7106,"7115":7106,"7116":7106,"7117":7106,"7118":7106,"7119":7106,"7136":7138,"7137":7138,"7142":7138,"7143":7138,"7144":7138,"7145":7138,"7146":7138,"7147":7138,"7148":7138,"7149":7138,"7150":7138,"7151":7138,"7168":7170,"7169":7170,"7174":7170,"7175":7170,"7176":7170,"7177":7170,"7178":7170,"7179":7170,"7180":7170,"7181":7170,"7182":7170,"7183":7170,"7216":7218,"7217":7218,"7222":7218,"7223":7218,"7224":7218,"7225":7218,"7226":7218,"7227":7218,"7228":7218,"7229":7218,"7230":7218,"7231":7218,"7248":7250,"7249":7250,"7254":7250,"7255":7250,"7256":7250,"7257":7250,"7258":7250,"7259":7250,"7260":7250,"7261":7250,"7262":7250,"7263":7250,"7264":7250,"7265":7250,"7270":7250,"7271":7250,"7272":7250,"7273":7250,"7274":7250,"7275":7250,"7276":7250,"7277":7250,"7278":7250,"7279":7250,"7297":7296,"7298":7296,"7299":7296,"7300":7296,"7301":7296,"7302":7296,"7303":7296,"7304":7296,"7305":7296,"7306":7296,"7307":7296,"7308":7296,"7309":7296,"7310":7296,"7311":7296,"7334":7328,"7335":7328,"7342":7328,"7343":7328,"7348":7346,"7349":7346,"7350":7346,"7351":7346,"7352":7346,"7353":7346,"7354":7346,"7355":7346,"7356":7346,"7357":7346,"7358":7346,"7359":7346,"7396":7392,"7397":7392,"7398":7392,"7399":7392,"7400":7392,"7401":7392,"7402":7392,"7403":7392,"7404":7392,"7405":7392,"7406":7392,"7407":7392,"7410":7408,"7411":7408,"7412":7408,"7413":7408,"7414":7408,"7415":7408,"7416":7408,"7417":7408,"7418":7408,"7419":7408,"7420":7408,"7421":7408,"7422":7408,"7423":7408,"7478":7472,"7479":7472,"7486":7472,"7487":7472,"7504":7218,"7505":7218,"7510":7218,"7511":7218,"7512":7218,"7513":7218,"7514":7218,"7515":7218,"7516":7218,"7517":7218,"7518":7218,"7519":7218}} \ No newline at end of file From 52f0c4f3ed7f82e9bb04ad471432e61ab4725bee Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 27 Nov 2021 22:51:14 +0000 Subject: [PATCH 3211/3224] Removed dodgy test using invalid block metadata --- tests/phpunit/block/BlockTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/phpunit/block/BlockTest.php b/tests/phpunit/block/BlockTest.php index 1e7e470aef..8e101bc0f5 100644 --- a/tests/phpunit/block/BlockTest.php +++ b/tests/phpunit/block/BlockTest.php @@ -107,7 +107,6 @@ class BlockTest extends TestCase{ public function blockGetProvider() : array{ return [ [BlockLegacyIds::STONE, 5], - [BlockLegacyIds::STONE, 15], [BlockLegacyIds::GOLD_BLOCK, 0], [BlockLegacyIds::WOODEN_PLANKS, 5], [BlockLegacyIds::SAND, 0], From 4a8ca603a1de9277c1ba91f3159a27791ea667ea Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 28 Nov 2021 18:53:34 +0000 Subject: [PATCH 3212/3224] Log a message when forceShutdown() is called for anything other than a graceful shutdown --- src/Server.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Server.php b/src/Server.php index 4ab8b8dcb3..f10a6b6891 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1413,6 +1413,9 @@ class Server{ echo "\x1b]0;\x07"; } + if($this->isRunning){ + $this->logger->emergency("Forcing server shutdown"); + } try{ if(!$this->isRunning()){ $this->sendUsage(SendUsageTask::TYPE_CLOSE); From 882df94bcbfc0b6111ebe2d9d5e717726ed590e0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 29 Nov 2021 23:45:10 +0000 Subject: [PATCH 3213/3224] ConsoleReaderThread: fixed zombie process leak --- src/console/ConsoleReaderThread.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/console/ConsoleReaderThread.php b/src/console/ConsoleReaderThread.php index fb9dc85bbe..bdfccd80fd 100644 --- a/src/console/ConsoleReaderThread.php +++ b/src/console/ConsoleReaderThread.php @@ -31,6 +31,7 @@ use function base64_encode; use function fgets; use function fopen; use function preg_replace; +use function proc_close; use function proc_open; use function proc_terminate; use function sprintf; @@ -130,6 +131,7 @@ final class ConsoleReaderThread extends Thread{ //gets stuck in a blocking fgets() read because stream_select() is a hunk of junk (hence the separate process in //the first place). proc_terminate($sub); + proc_close($sub); stream_socket_shutdown($client, STREAM_SHUT_RDWR); } From 6f8f460a6c84f057013c74db8c47782ae4923b42 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 30 Nov 2021 00:27:52 +0000 Subject: [PATCH 3214/3224] Partially revert "ConsoleReaderChildProcess: Commit suicide in more cases" This reverts commit cbe0f44c4f7bc3715acbf148f981bd93111c4c8f. This achieves the same result as the reverted commit wrt. process in the same manner (writing a keepalive into the socket and checking if it failed to send). However, it does _not_ allow the process to die on reaching pipe EOF, since this can cause many spams of subprocesses when stdin is actually not a tty (e.g. in a Docker container). --- src/console/ConsoleReader.php | 25 ++++++++++++++------ src/console/ConsoleReaderChildProcess.php | 9 +------- src/console/ConsoleReaderException.php | 28 ----------------------- 3 files changed, 19 insertions(+), 43 deletions(-) delete mode 100644 src/console/ConsoleReaderException.php diff --git a/src/console/ConsoleReader.php b/src/console/ConsoleReader.php index bd1fef4f5f..6d7545fde5 100644 --- a/src/console/ConsoleReader.php +++ b/src/console/ConsoleReader.php @@ -23,38 +23,49 @@ declare(strict_types=1); namespace pocketmine\console; -use pocketmine\utils\AssumptionFailedError; use function fclose; use function fgets; use function fopen; +use function is_resource; use function stream_select; use function trim; +use function usleep; final class ConsoleReader{ /** @var resource */ private $stdin; public function __construct(){ - $stdin = fopen("php://stdin", "r"); - if($stdin === false) throw new AssumptionFailedError("Opening stdin should never fail"); - $this->stdin = $stdin; + $this->initStdin(); + } + + private function initStdin() : void{ + if(is_resource($this->stdin)){ + fclose($this->stdin); + } + + $this->stdin = fopen("php://stdin", "r"); } /** * Reads a line from the console and adds it to the buffer. This method may block the thread. - * @throws ConsoleReaderException */ public function readLine() : ?string{ + if(!is_resource($this->stdin)){ + $this->initStdin(); + } + $r = [$this->stdin]; $w = $e = null; if(($count = stream_select($r, $w, $e, 0, 200000)) === 0){ //nothing changed in 200000 microseconds return null; }elseif($count === false){ //stream error - throw new ConsoleReaderException("Unexpected EOF on select()"); + return null; } if(($raw = fgets($this->stdin)) === false){ //broken pipe or EOF - throw new ConsoleReaderException("Unexpected EOF on fgets()"); + usleep(200000); //prevent CPU waste if it's end of pipe + return null; //loop back round } $line = trim($raw); diff --git a/src/console/ConsoleReaderChildProcess.php b/src/console/ConsoleReaderChildProcess.php index 6f4a742584..509d0daca3 100644 --- a/src/console/ConsoleReaderChildProcess.php +++ b/src/console/ConsoleReaderChildProcess.php @@ -45,14 +45,7 @@ if($socket === false){ } $consoleReader = new ConsoleReader(); while(!feof($socket)){ - try{ - $line = $consoleReader->readLine(); - }catch(ConsoleReaderException $e){ - //Encountered unexpected EOF. This might be because the user did something stupid, or because the parent process - //has died. In either case, commit suicide. If the parent process is still alive, it will start a new console - //reader. - break; - } + $line = $consoleReader->readLine(); if(@fwrite($socket, ($line ?? "") . "\n") === false){ //Always send even if there's no line, to check if the parent is alive //If the parent process was terminated forcibly, it won't close the connection properly, so feof() will return diff --git a/src/console/ConsoleReaderException.php b/src/console/ConsoleReaderException.php deleted file mode 100644 index bf9e8fc672..0000000000 --- a/src/console/ConsoleReaderException.php +++ /dev/null @@ -1,28 +0,0 @@ - Date: Tue, 30 Nov 2021 00:36:38 +0000 Subject: [PATCH 3215/3224] Fixed PHPStan complaints --- src/console/ConsoleReader.php | 5 ++++- tests/phpstan/configs/actual-problems.neon | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/console/ConsoleReader.php b/src/console/ConsoleReader.php index 6d7545fde5..77a3f4b6f5 100644 --- a/src/console/ConsoleReader.php +++ b/src/console/ConsoleReader.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\console; +use pocketmine\utils\AssumptionFailedError; use function fclose; use function fgets; use function fopen; @@ -44,7 +45,9 @@ final class ConsoleReader{ fclose($this->stdin); } - $this->stdin = fopen("php://stdin", "r"); + $stdin = fopen("php://stdin", "r"); + if($stdin === false) throw new AssumptionFailedError("Opening stdin should never fail"); + $this->stdin = $stdin; } /** diff --git a/tests/phpstan/configs/actual-problems.neon b/tests/phpstan/configs/actual-problems.neon index a9c45db8bf..52b727319a 100644 --- a/tests/phpstan/configs/actual-problems.neon +++ b/tests/phpstan/configs/actual-problems.neon @@ -505,6 +505,11 @@ parameters: count: 1 path: ../../../src/command/defaults/TimingsCommand.php + - + message: "#^Call to function is_resource\\(\\) with resource will always evaluate to true\\.$#" + count: 2 + path: ../../../src/console/ConsoleReader.php + - message: "#^Parameter \\#1 \\$json of function json_decode expects string, string\\|false given\\.$#" count: 1 From 38325c8573ae46d7861eb5fe45459668d41dd00f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 30 Nov 2021 01:14:21 +0000 Subject: [PATCH 3216/3224] Updated translations --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 969ab365b7..3bb3c0e48f 100644 --- a/composer.lock +++ b/composer.lock @@ -533,16 +533,16 @@ }, { "name": "pocketmine/locale-data", - "version": "2.0.17", + "version": "2.0.20", "source": { "type": "git", "url": "https://github.com/pmmp/Language.git", - "reference": "30e4a64d5674bac556c4e2b9842b19a981471ac4" + "reference": "a6e4eb22587e0014f6d658732cf633262723f8d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Language/zipball/30e4a64d5674bac556c4e2b9842b19a981471ac4", - "reference": "30e4a64d5674bac556c4e2b9842b19a981471ac4", + "url": "https://api.github.com/repos/pmmp/Language/zipball/a6e4eb22587e0014f6d658732cf633262723f8d3", + "reference": "a6e4eb22587e0014f6d658732cf633262723f8d3", "shasum": "" }, "type": "library", @@ -550,9 +550,9 @@ "description": "Language resources used by PocketMine-MP", "support": { "issues": "https://github.com/pmmp/Language/issues", - "source": "https://github.com/pmmp/Language/tree/2.0.17" + "source": "https://github.com/pmmp/Language/tree/2.0.20" }, - "time": "2021-11-12T00:59:39+00:00" + "time": "2021-11-25T20:56:12+00:00" }, { "name": "pocketmine/log", From 6d62b06ce68c605a35c1af35da7a48431d929767 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 30 Nov 2021 01:26:07 +0000 Subject: [PATCH 3217/3224] Release 4.0.0-BETA14 --- changelogs/4.0.md | 10 ++++++++++ src/VersionInfo.php | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index c7038c96c4..27d27ac61f 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1748,3 +1748,13 @@ Released 25th November 2021. ### Utils - `Utils::parseDocComment()` now allows `-` in tag names. + +# 4.0.0-BETA14 +Released 30th November 2021. + +## General +- The server will now log an EMERGENCY-level message when `forceShutdown()` is used for any other reason than a graceful shutdown. +- The server will now attempt to translate invalid blocks to valid equivalents when loading chunks. This fixes many issues with `update!` blocks appearing in worlds, particularly ghost structures (these would appear when world editors previously erased some blocks by setting their IDs but not metadata). + +## Fixes +- Fixed `ConsoleReaderThread` spawning many zombie processes when running a server inside a Docker container. diff --git a/src/VersionInfo.php b/src/VersionInfo.php index fc0171e8a1..ce5edfdd45 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -32,7 +32,7 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; public const BASE_VERSION = "4.0.0-BETA14"; - public const IS_DEVELOPMENT_BUILD = true; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_CHANNEL = "beta"; private function __construct(){ From d21a3d87506fe4a7758893b86703bbd241d37ae4 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 30 Nov 2021 01:26:07 +0000 Subject: [PATCH 3218/3224] 4.0.0-BETA15 is next --- src/VersionInfo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index ce5edfdd45..4699d4eb0a 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -31,8 +31,8 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "4.0.0-BETA14"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "4.0.0-BETA15"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_CHANNEL = "beta"; private function __construct(){ From 8620e67d88d5ce6090e03307964bdbf39e712fd0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 30 Nov 2021 19:16:38 +0000 Subject: [PATCH 3219/3224] Protocol changes for 1.18.0 --- composer.json | 4 +- composer.lock | 26 ++++----- src/data/bedrock/LegacyBiomeIdToStringMap.php | 35 ++++++++++++ src/network/mcpe/ChunkRequestTask.php | 2 +- .../mcpe/handler/PreSpawnPacketHandler.php | 1 + .../mcpe/serializer/ChunkSerializer.php | 54 ++++++++++++++++++- 6 files changed, 105 insertions(+), 17 deletions(-) create mode 100644 src/data/bedrock/LegacyBiomeIdToStringMap.php diff --git a/composer.json b/composer.json index b42e95a74e..5d6c1e4c6b 100644 --- a/composer.json +++ b/composer.json @@ -34,8 +34,8 @@ "adhocore/json-comment": "^1.1", "fgrosse/phpasn1": "^2.3", "netresearch/jsonmapper": "^4.0", - "pocketmine/bedrock-data": "^1.4.0+bedrock-1.17.40", - "pocketmine/bedrock-protocol": "^6.0.0+bedrock-1.17.40", + "pocketmine/bedrock-data": "^1.5.0+bedrock-1.18.0", + "pocketmine/bedrock-protocol": "^7.0.0+bedrock-1.18.0", "pocketmine/binaryutils": "^0.2.1", "pocketmine/callback-validator": "^1.0.2", "pocketmine/classloader": "^0.2.0", diff --git a/composer.lock b/composer.lock index 3bb3c0e48f..66f1c97df6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "fb545e4c8e17b0b07e8e20986b64e5a6", + "content-hash": "4acde3df19f222385a36bf6c7b15f965", "packages": [ { "name": "adhocore/json-comment", @@ -249,16 +249,16 @@ }, { "name": "pocketmine/bedrock-data", - "version": "1.4.0+bedrock-1.17.40", + "version": "1.5.0+bedrock-1.18.0", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockData.git", - "reference": "f29b7be8fa3046d2ee4c6421485b97b3f5b07774" + "reference": "482c679aa5ed0b81c088c2b1ff0b8110a94c8a6c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockData/zipball/f29b7be8fa3046d2ee4c6421485b97b3f5b07774", - "reference": "f29b7be8fa3046d2ee4c6421485b97b3f5b07774", + "url": "https://api.github.com/repos/pmmp/BedrockData/zipball/482c679aa5ed0b81c088c2b1ff0b8110a94c8a6c", + "reference": "482c679aa5ed0b81c088c2b1ff0b8110a94c8a6c", "shasum": "" }, "type": "library", @@ -269,22 +269,22 @@ "description": "Blobs of data generated from Minecraft: Bedrock Edition, used by PocketMine-MP", "support": { "issues": "https://github.com/pmmp/BedrockData/issues", - "source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.17.40" + "source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.18.0" }, - "time": "2021-10-19T16:55:41+00:00" + "time": "2021-11-30T18:30:46+00:00" }, { "name": "pocketmine/bedrock-protocol", - "version": "6.0.0+bedrock-1.17.40", + "version": "7.0.0+bedrock-1.18.0", "source": { "type": "git", "url": "https://github.com/pmmp/BedrockProtocol.git", - "reference": "906bafec4fc41f548749ce01d120902b25c1bbfe" + "reference": "040a883a4abb8c9b93114d5278cb5fecc635da82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/906bafec4fc41f548749ce01d120902b25c1bbfe", - "reference": "906bafec4fc41f548749ce01d120902b25c1bbfe", + "url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/040a883a4abb8c9b93114d5278cb5fecc635da82", + "reference": "040a883a4abb8c9b93114d5278cb5fecc635da82", "shasum": "" }, "require": { @@ -316,9 +316,9 @@ "description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP", "support": { "issues": "https://github.com/pmmp/BedrockProtocol/issues", - "source": "https://github.com/pmmp/BedrockProtocol/tree/6.0.0+bedrock-1.17.40" + "source": "https://github.com/pmmp/BedrockProtocol/tree/7.0.0+bedrock-1.18.0" }, - "time": "2021-11-21T20:56:18+00:00" + "time": "2021-11-30T19:02:41+00:00" }, { "name": "pocketmine/binaryutils", diff --git a/src/data/bedrock/LegacyBiomeIdToStringMap.php b/src/data/bedrock/LegacyBiomeIdToStringMap.php new file mode 100644 index 0000000000..2ccdc6abd7 --- /dev/null +++ b/src/data/bedrock/LegacyBiomeIdToStringMap.php @@ -0,0 +1,35 @@ +chunk); - $subCount = ChunkSerializer::getSubChunkCount($chunk); + $subCount = ChunkSerializer::getSubChunkCount($chunk) + ChunkSerializer::LOWER_PADDING_SIZE; $encoderContext = new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary()); $payload = ChunkSerializer::serializeFullChunk($chunk, RuntimeBlockMapping::getInstance(), $encoderContext, $this->tiles); $this->setResult($this->compressor->compress(PacketBatch::fromPackets($encoderContext, LevelChunkPacket::create($this->chunkX, $this->chunkZ, $subCount, null, $payload))->getBuffer())); diff --git a/src/network/mcpe/handler/PreSpawnPacketHandler.php b/src/network/mcpe/handler/PreSpawnPacketHandler.php index 6d2091065f..dbad9ab6ca 100644 --- a/src/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/network/mcpe/handler/PreSpawnPacketHandler.php @@ -104,6 +104,7 @@ class PreSpawnPacketHandler extends PacketHandler{ false, sprintf("%s %s", VersionInfo::NAME, VersionInfo::VERSION()->getFullVersion(true)), [], + 0, GlobalItemTypeDictionary::getInstance()->getDictionary()->getEntries() )); diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index af53364657..2d76f1291a 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -24,6 +24,8 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\serializer; use pocketmine\block\tile\Spawnable; +use pocketmine\data\bedrock\BiomeIds; +use pocketmine\data\bedrock\LegacyBiomeIdToStringMap; use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; @@ -32,10 +34,14 @@ use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext; use pocketmine\utils\Binary; use pocketmine\utils\BinaryStream; use pocketmine\world\format\Chunk; +use pocketmine\world\format\PalettedBlockArray; use pocketmine\world\format\SubChunk; +use function chr; use function count; +use function str_repeat; final class ChunkSerializer{ + public const LOWER_PADDING_SIZE = 4; private function __construct(){ //NOOP @@ -58,11 +64,22 @@ final class ChunkSerializer{ public static function serializeFullChunk(Chunk $chunk, RuntimeBlockMapping $blockMapper, PacketSerializerContext $encoderContext, ?string $tiles = null) : string{ $stream = PacketSerializer::encoder($encoderContext); + + //TODO: HACK! fill in fake subchunks to make up for the new negative space client-side + for($y = 0; $y < self::LOWER_PADDING_SIZE; $y++){ + $stream->putByte(8); //subchunk version 8 + $stream->putByte(0); //0 layers - client will treat this as all-air + } + $subChunkCount = self::getSubChunkCount($chunk); for($y = Chunk::MIN_SUBCHUNK_INDEX, $writtenCount = 0; $writtenCount < $subChunkCount; ++$y, ++$writtenCount){ self::serializeSubChunk($chunk->getSubChunk($y), $blockMapper, $stream, false); } - $stream->put($chunk->getBiomeIdArray()); + + //TODO: right now we don't support 3D natively, so we just 3Dify our 2D biomes so they fill the column + $encodedBiomePalette = self::serializeBiomesAsPalette($chunk); + $stream->put(str_repeat($encodedBiomePalette, 25)); + $stream->putByte(0); //border block array count //Border block entry format: 1 byte (4 bits X, 4 bits Z). These are however useless since they crash the regular client. @@ -116,4 +133,39 @@ final class ChunkSerializer{ return $stream->getBuffer(); } + + private static function serializeBiomesAsPalette(Chunk $chunk) : string{ + $biomeIdMap = LegacyBiomeIdToStringMap::getInstance(); + $biomePalette = new PalettedBlockArray($chunk->getBiomeId(0, 0)); + for($x = 0; $x < 16; ++$x){ + for($z = 0; $z < 16; ++$z){ + $biomeId = $chunk->getBiomeId($x, $z); + if($biomeIdMap->legacyToString($biomeId) === null){ + //make sure we aren't sending bogus biomes - the 1.18.0 client crashes if we do this + $biomeId = BiomeIds::OCEAN; + } + for($y = 0; $y < 16; ++$y){ + $biomePalette->set($x, $y, $z, $biomeId); + } + } + } + + $biomePaletteBitsPerBlock = $biomePalette->getBitsPerBlock(); + $encodedBiomePalette = + chr(($biomePaletteBitsPerBlock << 1) | 1) . //the last bit is non-persistence (like for blocks), though it has no effect on biomes since they always use integer IDs + $biomePalette->getWordArray(); + + //these LSHIFT by 1 uvarints are optimizations: the client expects zigzag varints here + //but since we know they are always unsigned, we can avoid the extra fcall overhead of + //zigzag and just shift directly. + $biomePaletteArray = $biomePalette->getPalette(); + if($biomePaletteBitsPerBlock !== 0){ + $encodedBiomePalette .= Binary::writeUnsignedVarInt(count($biomePaletteArray) << 1); + } + foreach($biomePaletteArray as $p){ + $encodedBiomePalette .= Binary::writeUnsignedVarInt($p << 1); + } + + return $encodedBiomePalette; + } } From aea124af74004a2a52f0caf2befe14a48487531b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 30 Nov 2021 19:17:26 +0000 Subject: [PATCH 3220/3224] Fix inconsistent class name --- ...yBiomeIdToStringMap.php => LegacyBiomeIdToStringIdMap.php} | 2 +- src/network/mcpe/serializer/ChunkSerializer.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/data/bedrock/{LegacyBiomeIdToStringMap.php => LegacyBiomeIdToStringIdMap.php} (92%) diff --git a/src/data/bedrock/LegacyBiomeIdToStringMap.php b/src/data/bedrock/LegacyBiomeIdToStringIdMap.php similarity index 92% rename from src/data/bedrock/LegacyBiomeIdToStringMap.php rename to src/data/bedrock/LegacyBiomeIdToStringIdMap.php index 2ccdc6abd7..e377e371d7 100644 --- a/src/data/bedrock/LegacyBiomeIdToStringMap.php +++ b/src/data/bedrock/LegacyBiomeIdToStringIdMap.php @@ -26,7 +26,7 @@ namespace pocketmine\data\bedrock; use pocketmine\utils\SingletonTrait; use Webmozart\PathUtil\Path; -final class LegacyBiomeIdToStringMap extends LegacyToStringBidirectionalIdMap{ +final class LegacyBiomeIdToStringIdMap extends LegacyToStringBidirectionalIdMap{ use SingletonTrait; public function __construct(){ diff --git a/src/network/mcpe/serializer/ChunkSerializer.php b/src/network/mcpe/serializer/ChunkSerializer.php index 2d76f1291a..0fe5d891ae 100644 --- a/src/network/mcpe/serializer/ChunkSerializer.php +++ b/src/network/mcpe/serializer/ChunkSerializer.php @@ -25,7 +25,7 @@ namespace pocketmine\network\mcpe\serializer; use pocketmine\block\tile\Spawnable; use pocketmine\data\bedrock\BiomeIds; -use pocketmine\data\bedrock\LegacyBiomeIdToStringMap; +use pocketmine\data\bedrock\LegacyBiomeIdToStringIdMap; use pocketmine\nbt\TreeRoot; use pocketmine\network\mcpe\convert\RuntimeBlockMapping; use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer; @@ -135,7 +135,7 @@ final class ChunkSerializer{ } private static function serializeBiomesAsPalette(Chunk $chunk) : string{ - $biomeIdMap = LegacyBiomeIdToStringMap::getInstance(); + $biomeIdMap = LegacyBiomeIdToStringIdMap::getInstance(); $biomePalette = new PalettedBlockArray($chunk->getBiomeId(0, 0)); for($x = 0; $x < 16; ++$x){ for($z = 0; $z < 16; ++$z){ From d560cf17fc2496161c375324ec3fb52f17057c25 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 30 Nov 2021 19:27:04 +0000 Subject: [PATCH 3221/3224] Release 4.0.0-BETA15 --- changelogs/4.0.md | 7 +++++++ src/VersionInfo.php | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index 27d27ac61f..a08f22428d 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1758,3 +1758,10 @@ Released 30th November 2021. ## Fixes - Fixed `ConsoleReaderThread` spawning many zombie processes when running a server inside a Docker container. + +# 4.0.0-BETA15 +Released 30th November 2021. + +## General +- Added support for Minecraft: Bedrock 1.18.0 +- Removed support for earlier versions. diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 4699d4eb0a..08f0f5d366 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -32,7 +32,7 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; public const BASE_VERSION = "4.0.0-BETA15"; - public const IS_DEVELOPMENT_BUILD = true; + public const IS_DEVELOPMENT_BUILD = false; public const BUILD_CHANNEL = "beta"; private function __construct(){ From 2850ea1e892c8af43bbcc42fa272303bc2d58515 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 30 Nov 2021 19:27:05 +0000 Subject: [PATCH 3222/3224] 4.0.0-BETA16 is next --- src/VersionInfo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 08f0f5d366..5a5b6139bb 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -31,8 +31,8 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "4.0.0-BETA15"; - public const IS_DEVELOPMENT_BUILD = false; + public const BASE_VERSION = "4.0.0-BETA16"; + public const IS_DEVELOPMENT_BUILD = true; public const BUILD_CHANNEL = "beta"; private function __construct(){ From 06e70308179875e3c05326758750694029bc25cb Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 1 Dec 2021 22:09:34 +0000 Subject: [PATCH 3223/3224] Prepare changelog for 4.0.0 --- changelogs/4.0-beta.md | 1767 ++++++++++++++++++++++++++++++++++++++++ changelogs/4.0.md | 1082 ++++++++++-------------- 2 files changed, 2185 insertions(+), 664 deletions(-) create mode 100644 changelogs/4.0-beta.md diff --git a/changelogs/4.0-beta.md b/changelogs/4.0-beta.md new file mode 100644 index 0000000000..a08f22428d --- /dev/null +++ b/changelogs/4.0-beta.md @@ -0,0 +1,1767 @@ +# 4.0.0-BETA1 +Released 7th September 2021. + +This major version features substantial changes throughout the core, including significant API changes, new world format support, performance improvements and a network revamp. + +Please note that this is a BETA release and is not finalized. While no significant changes are expected between now and release, the API might still be changed. + +Please also note that this changelog is provided on a best-effort basis, and it's possible some changes might not have been mentioned here. +If you find any omissions, please submit pull requests to add them. + +## WARNING +This is NOT a stable release. PMMP accepts no responsibility or liability for any damages incurred by using this build. +It should be used for TESTING purposes only. + +## Contents + * [Core](#core) + + [General](#general) + + [Configuration](#configuration) + + [World handling](#world-handling) + - [Interface](#interface) + - [Functional](#functional) + - [Performance](#performance) + + [Logger revamp](#logger-revamp) + + [Network](#network) + - [Minecraft Bedrock packet encryption](#minecraft-bedrock-packet-encryption) + - [Packet receive error handling has been overhauled](#packet-receive-error-handling-has-been-overhauled) + - [New packet handler system](#new-packet-handler-system) + * [API](#api) + + [General](#general-1) + + [Changes to `plugin.yml`](#changes-to-pluginyml) + - [Permission nesting](#permission-nesting) + - [`src-namespace-prefix`](#src-namespace-prefix) + + [Block](#block) + + [Command](#command) + + [Entity](#entity) + - [General](#general-2) + - [Effect](#effect) + - [Removal of runtime entity NBT](#removal-of-runtime-entity-nbt) + - [Entity creation](#entity-creation) + - [WIP removal of entity network metadata](#wip-removal-of-entity-network-metadata) + + [Event](#event) + - [Internal event system no longer depends on `Listener`s](#internal-event-system-no-longer-depends-on-listeners) + - [Default cancelled handling behaviour has changed](#default-cancelled-handling-behaviour-has-changed) + - [`PlayerPreLoginEvent` changes](#playerpreloginevent-changes) + - [Other changes](#other-changes) + + [Inventory](#inventory) + + [Item](#item) + - [General](#general-3) + - [NBT handling](#nbt-handling) + - [Enchantment](#enchantment) + + [Lang](#lang) + + [Network](#network-1) + + [Permission](#permission) + + [Player](#player) + + [Plugin](#plugin) + + [Scheduler](#scheduler) + - [Thread-local storage for AsyncTasks](#thread-local-storage-for-asynctasks) + - [Other changes](#other-changes-1) + + [Server](#server) + + [Level / World](#level--world) + - [General](#general-4) + - [Particles](#particles) + - [Sounds](#sounds) + + [Utils](#utils) + * [Gameplay](#gameplay) + + [Blocks](#blocks) + + [Items](#items) + +Table of contents generated with markdown-toc + +## Core +### General +- A new "plugin greylist" feature has been introduced, which allows whitelisting or blacklisting plugins from loading. +- Remote console (RCON) has been removed. The [RconServer](https://github.com/pmmp/RconServer) plugin is provided as a substitute. +- Spawn protection has been removed. The [BasicSpawnProtection](https://github.com/pmmp/BasicSpawnProtection) plugin is provided as a substitute. +- CTRL+C signal handling has been removed. The [PcntlSignalHandler](https://github.com/pmmp/PcntlSignalHandler) plugin is provided as a substitute. +- Player movement anti-cheat has been removed. +- GS4 Query no longer breaks when disabling RakLib. +- The `pocketmine_chunkutils` PHP extension has been dropped. +- New PHP extensions are required by this version: + - [chunkutils2](https://github.com/pmmp/ext-chunkutils2) + - [morton](https://github.com/pmmp/ext-morton) +- Many bugs in player respawning have been fixed, including: + - Spawning underneath bedrock when spawn position referred to ungenerated terrain + - Spawning underneath bedrock on first server join on very slow machines (or when the machine was under very high load) + - Spawning inside blocks (or above the ground) when respawning with a custom spawn position set + - Player spawn positions sticking to the old location when world spawn position changed - this was because the world spawn at time of player creation was used as the player's custom spawn, so the bug will persist for older player data, but will work as expected for new players. +- PreProcessor is removed from builds due to high maintenance cost and low benefit. Its usage is now discouraged. + +### Commands +- The `/reload` command has been removed. +- The `/effect` command no longer supports numeric IDs - it's now required to use names. +- The `/enchant` command no longer supports numeric IDs - it's now required to use names. +- Added `/clear` command with functionality equivalent to that of vanilla Minecraft. +- The following commands' outputs are now localized according to the chosen language settings: + - `/gc` + - `/status` + - `/op` + - `/deop` + +### Configuration +- World presets can now be provided as a `preset` key in `pocketmine.yml`, instead of putting them in the `generator` key. +- The following new options have been added to `pocketmine.yml`: + - `chunk-ticking.blocks-per-subchunk-per-tick` (default `3`): Increasing this value will increase the rate at which random block updates happen (e.g. grass growth). + - `network.enable-encryption` (default `true`): Controls whether Minecraft network packets are encrypted or not. +- The following options have been removed from `pocketmine.yml`: + - `chunk-ticking.light-updates`: Since lighting is needed for basic vanilla functionality to work, allowing this to be disabled without disabling chunk ticking made no sense. If you don't want light calculation to occur, you can disable chunk ticking altogether. + - `player.anti-cheat.allow-movement-cheats` + +### World handling +#### Interface +- Progress of spawn terrain chunk generation is now logged during initial world creation. + +#### Functional +- Minecraft Bedrock worlds up to 1.12.x are now supported. (1.13+ are still **not supported** due to yet another format change, which is large and requires a lot of work). +- Automatic conversion of deprecated world formats is now implemented. +- All formats except `leveldb` have been deprecated. The following world formats will be **automatically converted on load to a new format**: + - `mcregion` + - `anvil` + - `pmanvil` +- 256 build-height is now supported in all worlds (facilitated by automatic conversion). +- Extended blocks are now supported (facilitated by automatic conversion). +- Lighting is no longer stored or loaded from disk - instead, it's calculated on the fly as-needed. This fixes many long-standing bugs. + +#### Performance +- `leveldb` is now the primary supported world format. It is inherently faster than region-based formats thanks to better design. +- Partial chunk saves (only saving modified subcomponents of chunks) has been implemented. This drastically reduces the amount of data that is usually necessary to write on chunk save, which in turn **drastically reduces the time to complete world saves**. This is possible thanks to the modular design of the `leveldb` world format - this enhancement is not possible with region-based formats. +- Lighting is no longer guaranteed to be available on every chunk. It's now calculated on the fly as-needed. +- `/op`, `/deop`, `/whitelist add` and `/whitelist remove` no longer cause player data to be loaded from disk for no reason. +- Timings now use high-resolution timers provided by `hrtime()` to collect more accurate performance metrics. +- Z-order curves (morton codes) are now used for block and chunk coordinate hashes. This substantially improves performance in many areas by resolving a hashtable key hash collision performance issue. Affected areas include explosions, light calculation, and more. +- [`libdeflate`](https://github.com/ebiggers/libdeflate) is now (optionally) used for outbound Minecraft packet compression. It's more than twice as fast as zlib in most cases, providing significant performance boosts to packet broadcasts and overall network performance. +- Closures are now used for internal event handler calls. This provides a performance improvement of 10-20% over the 3.x system, which had to dynamically resolve callables for every event call. + +### Logger revamp +- Many components now have a dedicated logger which automatically adds [prefixes] to their messages. +- Main logger now includes milliseconds in timestamps. + +### Network +This version features substantial changes to the network system, improving coherency, reliability and modularity. + +#### Minecraft Bedrock packet encryption +- This fixes replay attacks where hackers steal and replay player logins. +- A new setting has been added to `pocketmine.yml`: `network.enable-encryption` which is `true` by default. + +#### Packet receive error handling has been overhauled +- Only `BadPacketException` is now caught during packet decode and handling. This requires that all decoding MUST perform proper data error checking. + - Throwing a `BadPacketException` from decoding will now cause players to be kicked with the message `Packet processing error`. + - The disconnect message includes a random hex ID to help server owners identify the problems reported by their players. +- Throwing any other exception will now cause a server crash. `Internal server error` has been removed. +- It is now illegal to send a clientbound packet to the server. Doing so will result in the client being kicked with the message `Unexpected non-serverbound packet`. + +#### New packet handler system +- Packet handlers have been separated from NetworkSession into a dedicated packet handler structure. +- A network session may have exactly 1 handler at a time, which is mutable and may be replaced at any time. This allows packet handling logic to be broken up into multiple stages: + - preventing undefined behaviour when sending wrong packets at the wrong time (they'll now be silently dropped) + - allowing the existence of ephemeral state-specific logic (for example stricter resource packs download checks) +- Packet handlers are now almost entirely absent from `Player` and instead appear in their own dedicated units. +- Almost all game logic that was previously locked up inside packet handlers in `Player` has been extracted into new API methods. See Player API changes for details. + +## API +### General +- Most places which previously allowed `callable` now only allow `\Closure`. This is because closures have more consistent behaviour and are more performant. +- `void` and `?nullable` parameter and return types have been applied in many places. +- Everything in the `pocketmine\metadata` namespace and related implementations have been removed. + +### Changes to `plugin.yml` +#### Permission nesting +Permission nesting is no longer supported in `plugin.yml`. Grouping permissions (with defaults) in `plugin.yml` had very confusing and inconsistent behaviour. +Instead of nesting permission declarations, they should each be declared separately. + +_Before_: +``` +permissions: + pmmp: + default: op + children: + pmmp.something: + default: op + pmmp.somethingElse + default: op +``` + +_After_: +``` +permissions: + pmmp.something: + default: op + pmmp.somethingElse + default: op +``` + +#### `src-namespace-prefix` +A new directive `src-namespace-prefix` has been introduced. This allows you to get rid of those useless subdirectories in a plugin's structure. +For example, a plugin whose main was `pmmp\TesterPlugin\Main` used to have to be structured like this: +``` +|-- plugin.yml +|-- src/ + |-- pmmp/ + |-- TesterPlugin/ + |-- Main.php + |-- SomeOtherClass.php + |-- SomeNamespace/ + |-- SomeNamespacedClass.php +``` +However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml`, now we can get rid of the useless directories and structure it like this instead: +``` +|-- plugin.yml +|-- src/ + |-- Main.php + |-- SomeOtherClass.php + |-- SomeNamespace/ + |-- SomeNamespacedClass.php +``` + +**Note**: The old structure will also still work just fine. This is not a required change. + +### Block +- A new `VanillaBlocks` class has been added, which contains static methods for creating any currently-known block type. This should be preferred instead of use of `BlockFactory::get()` where constants were used. +- Blocks now contain their positions instead of extending `Position`. `Block->getPosition()` has been added. +- Blocks with IDs >= 256 are now supported. +- Block state and variant metadata have been separated. + - Variant is considered an extension of ID and is immutable. + - `Block->setDamage()` has been removed. + - All blocks now have getters and setters for their appropriate block properties, such as facing, lit/unlit, colour (in some cases), and many more. These should be used instead of metadata. +- Tile entities are now created and deleted automatically when `World->setBlock()` is used with a block that requires a tile entity. +- Some tile entities' API has been exposed on their corresponding `Block` classes, with the tile entity classes being deprecated. +- The `pocketmine\tile` namespace has been relocated to `pocketmine\block\tile`. +- `Block->recalculateBoundingBox()` and `Block->recalculateCollisionBoxes()` are now expected to return AABBs relative to `0,0,0` instead of their own position. +- Block break-info has been extracted into a new dynamic `BlockBreakInfo` unit. The following methods have been moved: + - `Block->getBlastResistance()` -> `BlockBreakInfo->getBlastResistance()` + - `Block->getBreakTime()` -> `BlockBreakInfo->getBreakTime()` + - `Block->getHardness()` -> `BlockBreakInfo->getHardness()` + - `Block->getToolHarvestLevel()` -> `BlockBreakInfo->getToolHarvestLevel()` + - `Block->getToolType()` -> `BlockBreakInfo->getToolType()` + - `Block->isBreakable()` -> `BlockBreakInfo->isBreakable()` + - `Block->isCompatibleWithTool()` -> `BlockBreakInfo->isToolCompatible()` +- The following API methods have been added: + - `Block->asItem()`: returns an itemstack corresponding to the block + - `Block->isSameState()`: returns whether the block is the same as the parameter, including state information + - `Block->isSameType()`: returns whether the block is the same as the parameter, without state information + - `Block->isFullCube()` +- The following hooks have been added: + - `Block->onAttack()`: called when a player in survival left-clicks the block to try to start breaking it + - `Block->onEntityLand()`: called when an entity lands on this block after falling (from any distance) + - `Block->onPostPlace()`: called directly after placement in the world, handles things like rail connections and chest pairing +- The following API methods have been renamed: + - `Block->getDamage()` -> `Block->getMeta()` + - `Block->onActivate()` -> `Block->onInteract()` + - `Block->onEntityCollide()` -> `Block->onEntityInside()` +- The following API methods have changed signatures: + - `Block->onInteract()` now has the signature `onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool` + - `Block->getCollisionBoxes()` is now final. Classes should override `recalculateCollisionBoxes()`. +- The following API methods have been removed: + - `Block->canPassThrough()` + - `Block->setDamage()` + - `Block::get()`: this was superseded by `BlockFactory::get()` a long time ago + - `Block->getBoundingBox()` +- The following classes have been renamed: + - `BlockIds` -> `BlockLegacyIds` + - `CobblestoneWall` -> `Wall` + - `NoteBlock` -> `Note` + - `SignPost` -> `Sign` + - `StandingBanner` -> `Banner` +- The following classes have been removed: + - `Bricks` + - `BurningFurnace` + - `CobblestoneStairs` + - `Dandelion` + - `DoubleSlab` + - `DoubleStoneSlab` + - `EndStone` + - `GlowingRedstoneOre` + - `GoldOre` + - `Gold` + - `IronDoor` + - `IronOre` + - `IronTrapdoor` + - `Iron` + - `Lapis` + - `NetherBrickFence` + - `NetherBrickStairs` + - `Obsidian` + - `PurpurStairs` + - `Purpur` + - `QuartzStairs` + - `Quartz` + - `RedSandstoneStairs` + - `RedSandstone` + - `SandstoneStairs` + - `Sandstone` + - `StainedClay` + - `StainedGlassPane` + - `StainedGlass` + - `StoneBrickStairs` + - `StoneBricks` + - `StoneSlab2` + - `StoneSlab` + - `Stone` + - `WallBanner` + - `WallSign` + - `Wood2` +- `BlockToolType` constants have been renamed to remove the `TYPE_` prefix. + +### Command +- The following classes have been removed: + - `RemoteConsoleCommandSender` +- The following API methods have signature changes: + - `Command->setPermission()` argument is now mandatory (but still nullable). + - `CommandSender->setScreenLineHeight()` argument is now mandatory (but still nullable). +- Commands with spaces in the name are no longer supported. + +### Entity +#### General +- `Entity` no longer extends from `Location`. `Entity->getLocation()` and `Entity->getPosition()` should be used instead. +- Ender inventory has been refactored. It's now split into two parts: + - `EnderChestInventory` is a temporary gateway "inventory" that acts as a proxy to the player's ender inventory. It has a `Position` for holder. This is discarded when the player closes the inventory window. + - `PlayerEnderInventory` is the storage part. This is stored in `Human` and does not contain any block info. + - To open the player's ender inventory, use `Player->setCurrentWindow(new EnderChestInventory($blockPos, $player->getEnderInventory()))`. +- The following public fields have been removed: + - `Entity->chunk`: Entities no longer know which chunk they are in (the `World` now manages this instead). + - `Entity->height`: moved to `EntitySizeInfo`; use `Entity->size` instead + - `Entity->width`: moved to `EntitySizeInfo`; use `Entity->size` instead + - `Entity->eyeHeight`: moved to `EntitySizeInfo`; use `Entity->size` instead +- The following API methods have been added: + - `Entity->getFallDistance()` + - `Entity->setFallDistance()` + - `ItemEntity->getDespawnDelay()` + - `ItemEntity->setDespawnDelay()` + - `Living->calculateFallDamage()`: this is `protected`, and may be overridden by subclasses to provide custom damage logic + - `Human->getHungerManager()` + - `Human->getXpManager()` +- The following methods have signature changes: + - `Entity->entityBaseTick()` is now `protected`. + - `Entity->move()` is now `protected`. + - `Entity->setPosition()` is now `protected` (use `Entity->teleport()` instead). + - `Entity->setPositionAndRotation()` is now `protected` (use `Entity->teleport()` instead). + - `Living->knockBack()` now accepts `float, float, float` (the first two parameters have been removed). + - `Living->getEffects()` now returns `EffectManager` instead of `Effect[]`. +- The following classes have been added: + - `effect\EffectManager`: contains effect-management functionality extracted from `Living` + - `HungerManager`: contains hunger-management functionality extracted from `Human` + - `ExperienceManager`: contains XP-management functionality extracted from `Human` +- The following API methods have been moved / renamed: + - `Entity->fall()` -> `Entity->onHitGround()` (and visibility changed to `protected` from `public`) + - `Living->removeAllEffects()` -> `EffectManager->clear()` + - `Living->removeEffect()` -> `EffectManager->remove()` + - `Living->addEffect()` -> `EffectManager->add()` + - `Living->getEffect()` -> `EffectManager->get()` + - `Living->hasEffect()` -> `EffectManager->has()` + - `Living->hasEffects()` -> `EffectManager->hasEffects()` + - `Living->getEffects()` -> `EffectManager->all()` + - `Human->getFood()` -> `HungerManager->getFood()` + - `Human->setFood()` -> `HungerManager->setFood()` + - `Human->getMaxFood()` -> `HungerManager->getMaxFood()` + - `Human->addFood()` -> `HungerManager->addFood()` + - `Human->isHungry()` -> `HungerManager->isHungry()` + - `Human->getEnderChestInventory()` -> `Human->getEnderInventory()` + - `Human->getSaturation()` -> `HungerManager->getSaturation()` + - `Human->setSaturation()` -> `HungerManager->setSaturation()` + - `Human->addSaturation()` -> `HungerManager->addSaturation()` + - `Human->getExhaustion()` -> `HungerManager->getExhaustion()` + - `Human->setExhaustion()` -> `HungerManager->setExhaustion()` + - `Human->exhaust()` -> `HungerManager->exhaust()` + - `Human->getXpLevel()` -> `ExperienceManager->getXpLevel()` + - `Human->setXpLevel()` -> `ExperienceManager->setXpLevel()` + - `Human->addXpLevels()` -> `ExperienceManager->addXpLevels()` + - `Human->subtractXpLevels()` -> `ExperienceManager->subtractXpLevels()` + - `Human->getXpProgress()` -> `ExperienceManager->getXpProgress()` + - `Human->setXpProgress()` -> `ExperienceManager->setXpProgress()` + - `Human->getRemainderXp()` -> `ExperienceManager->getRemainderXp()` + - `Human->getCurrentTotalXp()` -> `ExperienceManager->getCurrentTotalXp()` + - `Human->setCurrentTotalXp()` -> `ExperienceManager->setCurrentTotalXp()` + - `Human->addXp()` -> `ExperienceManager->addXp()` + - `Human->subtractXp()` -> `ExperienceManager->subtractXp()` + - `Human->getLifetimeTotalXp()` -> `ExperienceManager->getLifetimeTotalXp()` + - `Human->setLifetimeTotalXp()` -> `ExperienceManager->setLifetimeTotalXp()` + - `Human->canPickupXp()` -> `ExperienceManager->canPickupXp()` + - `Human->onPickupXp()` -> `ExperienceManager->onPickupXp()` + - `Human->resetXpCooldown()` -> `ExperienceManager->resetXpCooldown()` +- The following API methods have been removed: + - `Human->getRawUniqueId()`: use `Human->getUniqueId()->toBinary()` instead +- The following classes have been removed: + - `Creature` + - `Damageable` + - `Monster` + - `NPC` + - `Rideable` + - `Vehicle` +- `Skin` now throws exceptions on creation if given invalid data. + +#### Effect +- All `Effect` related classes have been moved to the `pocketmine\entity\effect` namespace. +- Effect functionality embedded in the `Effect` class has been separated out into several classes. The following classes have been added: + - `AbsorptionEffect` + - `HealthBoostEffect` + - `HungerEffect` + - `InstantDamageEffect` + - `InstantEffect` + - `InstantHealthEffect` + - `InvisibilityEffect` + - `LevitationEffect` + - `PoisonEffect` + - `RegenerationEffect` + - `SaturationEffect` + - `SlownessEffect` + - `SpeedEffect` + - `WitherEffect` +- `VanillaEffects` class has been added. This exposes all vanilla effect types as static methods, replacing the old `Effect::getEffect()` nastiness. + - Example: `Effect::getEffect(Effect::NIGHT_VISION)` can be replaced by `VanillaEffects::NIGHT_VISION()`. +- Negative effect amplifiers are now explicitly disallowed due to undefined behaviour they created. +- The boundaries between MCPE effect IDs and PocketMine-MP internals are now more clear. + - ID handling is moved to `pocketmine\data\bedrock\EffectIdMap`. + - All effect ID constants have been removed from `Effect`. `pocketmine\data\bedrock\EffectIds` if you still need legacy effect IDs for some reason. +- The following API methods have been moved: + - `Effect->getId()` -> `EffectIdMap->toId()` + - `Effect::registerEffect()` -> `EffectIdMap->register()` + - `Effect::getEffect()` -> `EffectIdMap->fromId()` + - `Effect::getEffectByName()` -> `VanillaEffects::fromString()` +- The following API methods have been added: + - `Effect->getRuntimeId()`: this is a **dynamic ID** which can be used for effect type comparisons. **This cannot be stored, so don't use it in configs or NBT!** + +#### Removal of runtime entity NBT +- Entities no longer keep their NBT alive at runtime. + - `Entity->namedtag` has been removed. + - `Entity->saveNBT()` now returns a newly created `CompoundTag` instead of modifying the previous one in-place. + - `Entity->initEntity()` now accepts a `CompoundTag` parameter. + +#### Entity creation +- `Entity::createEntity()` has been removed. It's no longer needed for creating new entities at runtime - just use `new YourEntity` instead. +- `Entity` subclass constructors can now have any signature, just like a normal class. +- Loading entities from NBT is now handled by `EntityFactory`. It works quite a bit differently than `Entity::createEntity()` did. Instead of registering `YourEntity::class` to a set of Minecraft save IDs, you now need to provide a callback which will construct an entity when given some NBT and a `World`. + - The creation callback is registered using `EntityFactory::register()`. + - The creation callback must have the signature `function(World, CompoundTag) : Entity`. + - This enables `Entity` subclasses to have any constructor parameters they like. + - It also allows requiring that certain data is always provided (for example, it doesn't make much sense to create a `FallingBlock` without specifying what type of block). + - Examples: + - `ItemEntity` now requires an `Item` in its constructor, so its creation callback decodes the `Item` from the NBT to be passed to the constructor. + - `Painting` now requires a `PaintingMotive` in its constructor, so its creation callback decides which `PaintingMotive` to provide based on the NBT it receives. + - See `EntityFactory` for more examples. +- `EntityFactory::register()` (previously `Entity::registerEntity()`) will now throw exceptions on error cases instead of returning `false`. +- The following API methods have been moved: + - `Entity::registerEntity()` -> `EntityFactory::register()` +- The following classes have changed constructors: + - All projectile subclasses now require a `?Entity $thrower` parameter. + - `Arrow->__construct()` now requires a `bool $critical` parameter (in addition to the `$thrower` parameter). + - `ExperienceOrb->__construct()` now requires a `int $xpValue` parameter. + - `FallingBlock->__construct()` now requires a `Block $block` parameter. + - `ItemEntity->__construct()` now requires an `Item $item` parameter. + - `Painting->__construct()` now requires a `PaintingMotive $motive` parameter. + - `SplashPotion->__construct()` now requires a `int $potionId` parameter. +- The following API methods have been removed: + - `Entity::createBaseNBT()`: `new YourEntity` and appropriate API methods should be used instead + - `Entity->getSaveId()` + - `Entity::getKnownEntityTypes()` + - `Entity::createEntity()`: use `new YourEntity` instead (to be reviewed) + +#### WIP removal of entity network metadata +- All network metadata related constants have been removed from the `Entity` class and moved to the protocol layer. It is intended to remove network metadata from the API entirely, but this has not yet been completed. + - `Entity::DATA_FLAG_*` constants have been moved to `pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags`. + - `Entity::DATA_TYPE_*` constants have been moved to `pocketmine\network\mcpe\protocol\types\entity\EntityMetadataTypes`. + - `Entity::DATA_*` constants have been moved to `pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties`. +- `DataPropertyManager` has been moved to the `pocketmine\network\mcpe\protocol\types\entity` namespace, and as such isn't considered part of the API anymore. +- Introduced internal `Entity` hook `syncNetworkData()`. This function is expected to synchronize entity properties with the entity's network data set. +- Internal usage of network metadata sets to store internal entity properties has been removed. Entities are now expected to use regular class properties and synchronize with the network data set as-asked. +- `Entity->propertyManager` has been renamed to `Entity->networkProperties`. +- `Entity->getDataPropertyManager()` has been renamed to `Entity->getNetworkProperties()`. + +### Event +#### Internal event system no longer depends on `Listener`s +- The internal event processing system no longer depends on `Listener` objects. Arbitrary closures can now be used, provided that they satisfy the standard requirements to be a handler. + - This change improves performance of event handler calling by approximately 15%. This does not include anything plugins are doing. + - The following classes have been removed: + - `pocketmine\plugin\EventExecutor` + - `pocketmine\plugin\MethodEventExecutor` + - `RegisteredListener->__construct()` now requires `Closure` instead of `Listener, EventExecutor` as the leading parameters. + - `RegisteredListener->getListener()` has been removed. + +#### Default cancelled handling behaviour has changed +- Handler functions will now **not receive cancelled events by default**. This is a **silent BC break**, i.e. it won't raise errors, but it might cause bugs. +- `@ignoreCancelled` is now no longer respected. +- `@handleCancelled` has been added. This allows opting _into_ receiving cancelled events (it's the opposite of `@ignoreCancelled`). + +#### `PlayerPreLoginEvent` changes +- The `Player` object no longer exists at this phase of the login. Instead, a `PlayerInfo` object is provided, along with connection information. +- Ban, server-full and whitelist checks are now centralized to `PlayerPreLoginEvent`. It's no longer necessary (or possible) to intercept `PlayerKickEvent` to handle these types of disconnects. + - Multiple kick reasons may be set to ensure that the player is still removed if there are other reasons for them to be disconnected and one of them is cleared. For example, if a player is banned and the server is full, clearing the ban flag will still cause the player to be disconnected because the server is full. + - Plugins may set custom kick reasons. Any custom reason has absolute priority. + - If multiple flags are set, the kick message corresponding to the highest priority reason will be shown. The priority (as of this snapshot) is as follows: + - Custom (highest priority) + - Server full + - Whitelisted + - Banned + - The `PlayerPreLoginEvent::KICK_REASON_PRIORITY` constant contains a list of kick reason priorities, highest first. +- The following constants have been added: + - `PlayerPreLoginEvent::KICK_REASON_PLUGIN` + - `PlayerPreLoginEvent::KICK_REASON_SERVER_FULL` + - `PlayerPreLoginEvent::KICK_REASON_SERVER_WHITELISTED` + - `PlayerPreLoginEvent::KICK_REASON_BANNED` + - `PlayerPreLoginEvent::KICK_REASON_PRIORITY`: ordered list of kick reason priorities, highest first +- The following API methods have been added: + - `PlayerPreLoginEvent->clearAllKickReasons()` + - `PlayerPreLoginEvent->clearKickReason()` + - `PlayerPreLoginEvent->getFinalKickMessage()`: the message to be shown to the player with the current reason list in place + - `PlayerPreLoginEvent->getIp()` + - `PlayerPreLoginEvent->getKickReasons()`: returns an array of flags indicating kick reasons, must be empty to allow joining + - `PlayerPreLoginEvent->getPlayerInfo()` + - `PlayerPreLoginEvent->getPort()` + - `PlayerPreLoginEvent->isAllowed()` + - `PlayerPreLoginEvent->isAuthRequired()`: whether XBL authentication will be enforced + - `PlayerPreLoginEvent->isKickReasonSet()` + - `PlayerPreLoginEvent->setAuthRequired()` + - `PlayerPreLoginEvent->setKickReason()` +- The following API methods have been changed: + - `PlayerPreLoginEvent->getKickMessage()` now has the signature `getKickMessage(int $flag) : ?string` +- The following API methods have been removed: + - `PlayerPreLoginEvent->setKickMessage()` + - `PlayerPreLoginEvent->getPlayer()` +- The following API methods have been moved / renamed: + - `InventoryPickupItemEvent->getItem()` -> `InventoryPickupItemEvent->getItemEntity()` + +#### Other changes +- Disconnecting players during events no longer crashes the server (although it might cause other side effects). +- `PlayerKickEvent` is no longer fired for disconnects that occur before the player completes the initial login sequence (i.e. completing downloading resource packs). +- Cancellable events must now implement `CancellableTrait` to get the cancellable components needed to satisfy interface requirements. `Event` no longer stubs these methods. +- `PlayerInteractEvent` is no longer fired when a player activates an item. This fixes the age-old complaint of `PlayerInteractEvent` firing multiple times when interacting once. The following constants have been removed: + - `PlayerInteractEvent::LEFT_CLICK_AIR` + - `PlayerInteractEvent::RIGHT_CLICK_AIR` + - `PlayerInteractEvent::PHYSICAL` +- The following events have been added: + - `PlayerEntityInteractEvent`: player right-clicking (or long-clicking on mobile) on an entity. + - `PlayerItemUseEvent`: player activating their held item, for example to throw it. + - `BlockTeleportEvent`: block teleporting, for example dragon egg when attacked. + - `PlayerDisplayNameChangeEvent` + - `EntityItemPickupEvent`: player (or other entity) picks up a dropped item (or arrow). Replaces `InventoryPickupItemEvent` and `InventoryPickupArrowEvent`. + - Unlike its predecessors, this event supports changing the destination inventory. + - If the destination inventory is `null`, the item will be destroyed. This is usually seen for creative players with full inventories. + - `EntityTrampleFarmlandEvent`: mob (or player) jumping on farmland causing it to turn to dirt + - `StructureGrowEvent`: called when trees or bamboo grow (or any other multi-block plant structure). +- The following events have been removed: + - `EntityArmorChangeEvent` + - `EntityInventoryChangeEvent` + - `EntityLevelChangeEvent` - `EntityTeleportEvent` with world checks should be used instead. + - `InventoryPickupItemEvent` - use `EntityItemPickupEvent` instead + - `InventoryPickupArrowEvent` - use `EntityItemPickupEvent` instead + - `NetworkInterfaceCrashEvent` + - `PlayerCheatEvent` + - `PlayerIllegalMoveEvent` +- The following API methods have been added: + - `EntityDeathEvent->getXpDropAmount()` + - `EntityDeathEvent->setXpDropAmount()` + - `PlayerDeathEvent->getXpDropAmount()` + - `PlayerDeathEvent->setXpDropAmount()` +- The following API methods have been removed: + - `PlayerPreLoginEvent->getPlayer()` + - `Cancellable->setCancelled()`: this allows implementors of `Cancellable` to implement their own cancellation mechanisms, such as the complex one in `PlayerPreLoginEvent` +- The following API methods have been moved: + - `Event->isCancelled()` -> `CancellableTrait->isCancelled()`: this was a stub which threw `BadMethodCallException` if the class didn't implement `Cancellable`; now this is simply not available on non-cancellable events + - `Event->setCancelled()` has been split into `cancel()` and `uncancel()`, and moved to `CancellableTrait` + - `HandlerList::unregisterAll()` -> `HandlerListManager->unregisterAll()` + - `HandlerList::getHandlerListFor()` -> `HandlerListManager->getListFor()` + - `HandlerList::getHandlerLists()` -> `HandlerListManager->getAll()` +- The following classes have been moved: + - `pocketmine\plugin\RegisteredListener` -> `pocketmine\event\RegisteredListener` + +### Inventory +- All crafting and recipe related classes have been moved to the `pocketmine\crafting` namespace. +- The following classes have been added: + - `CallbackInventoryChangeListener` + - `CreativeInventory`: contains the creative functionality previously embedded in `pocketmine\item\Item`, see Item changes for details + - `InventoryChangeListener`: allows listening (but not interfering with) events in an inventory. + - `PlayerEnderInventory`: represents the pure storage part of the player's ender inventory, without any block information + - `transaction\CreateItemAction` + - `transaction\DestroyItemAction` +- The following classes have been renamed / moved: + - `ContainerInventory` -> `pocketmine\block\inventory\BlockInventory` +- The following classes have been moved to the `pocketmine\block\inventory` namespace: + - `AnvilInventory` + - `ChestInventory` + - `DoubleChestInventory` + - `EnchantInventory` + - `EnderChestInventory` + - `FurnaceInventory` +- The following classes have been removed: + - `CustomInventory` + - `InventoryEventProcessor` + - `Recipe` + - `transaction\CreativeInventoryAction` +- The following API methods have been added: + - `Inventory->addChangeListeners()` + - `Inventory->getChangeListeners()` + - `Inventory->removeChangeListeners()` + - `Inventory->swap()`: swaps the contents of two slots +- The following API methods have been removed: + - `BaseInventory->getDefaultSize()` + - `BaseInventory->setSize()` + - `EnderChestInventory->setHolderPosition()` + - `Inventory->close()` + - `Inventory->dropContents()` + - `Inventory->getName()` + - `Inventory->getTitle()` + - `Inventory->onSlotChange()` + - `Inventory->open()` + - `Inventory->sendContents()` + - `Inventory->sendSlot()` + - `InventoryAction->onExecuteFail()` + - `InventoryAction->onExecuteSuccess()` + - `PlayerInventory->sendCreativeContents()` +- The following API methods have signature changes: + - `Inventory->clear()` now returns `void` instead of `bool`. + - `Inventory->setItem()` now returns `void` instead of `bool`. + - `InventoryAction->execute()` now returns `void` instead of `bool`. + - `BaseInventory->construct()` no longer accepts a list of items to initialize with. +- `PlayerInventory->setItemInHand()` now sends the update to viewers of the player. + +### Item +#### General +- A new `VanillaItems` class has been added, which contains static methods for creating any currently-known item type. This should be preferred instead of use of `ItemFactory::get()` where constants were used. +- `StringToItemParser` has been added, which allows mapping any string to any item, irrespective of IDs. These mappings are used by `/give` and `/clear`, and are made with custom plugin aliases in mind. + - Yes, this means you can finally add your own custom aliases to `/give` without ugly hacks! +- `LegacyStringToItemParser` has been added, which is a slightly more dynamic (but still inadvisable) replacement for `ItemFactory::fromString()`. +- `Item->count` is no longer public. +- The hierarchy of writable books has been changed: `WritableBook` and `WrittenBook` now extend `WritableBookBase`. +- The following API methods have signature changes: + - `WritableBookBase->setPages()` now accepts `WritableBookPage[]` instead of `CompoundTag[]`. + - `ItemFactory::get()` no longer accepts `string` for the `tags` parameter. + - `ItemFactory::fromString()` no longer accepts a `$multiple` parameter and now only returns `Item`, not `Item|Item[]`. +- The following methods are now fluent: + - `WritableBookBase->setPages()` + - `Item->addEnchantment()` + - `Item->removeEnchantment()` + - `Item->removeEnchantments()` + - `Armor->setCustomColor()` + - `WrittenBook->setTitle()` + - `WrittenBook->setAuthor()` + - `WrittenBook->setGeneration()` +- The following API methods have been removed: + - `Item->getNamedTagEntry()` + - `Item->removeNamedTagEntry()` + - `Item->setDamage()`: "Damage" is now immutable for all items except `Durable` descendents. + - `Item->setNamedTagEntry()` + - `Item::get()`: this was superseded by `ItemFactory::get()` a long time ago + - `Item::fromString()`: this was superseded by `ItemFactory::fromString()` a long time ago + - `Item->setCompoundTag()` + - `Item->getCompoundTag()` + - `Item->hasCompoundTag()` + - `Potion::getPotionEffectsById()` + - `ProjectileItem->getProjectileEntityType()` +- The following constants have been removed: + - `Potion::ALL` - use `PotionType::getAll()` instead + - `Potion::WATER` + - `Potion::MUNDANE` + - `Potion::LONG_MUNDANE` + - `Potion::THICK` + - `Potion::AWKWARD` + - `Potion::NIGHT_VISION` + - `Potion::LONG_NIGHT_VISION` + - `Potion::INVISIBILITY` + - `Potion::LONG_INVISIBILITY` + - `Potion::LEAPING` + - `Potion::LONG_LEAPING` + - `Potion::STRONG_LEAPING` + - `Potion::FIRE_RESISTANCE` + - `Potion::LONG_FIRE_RESISTANCE` + - `Potion::SWIFTNESS` + - `Potion::LONG_SWIFTNESS` + - `Potion::STRONG_SWIFTNESS` + - `Potion::SLOWNESS` + - `Potion::LONG_SLOWNESS` + - `Potion::WATER_BREATHING` + - `Potion::LONG_WATER_BREATHING` + - `Potion::HEALING` + - `Potion::STRONG_HEALING` + - `Potion::HARMING` + - `Potion::STRONG_HARMING` + - `Potion::POISON` + - `Potion::LONG_POISON` + - `Potion::STRONG_POISON` + - `Potion::REGENERATION` + - `Potion::LONG_REGENERATION` + - `Potion::STRONG_REGENERATION` + - `Potion::STRENGTH` + - `Potion::LONG_STRENGTH` + - `Potion::STRONG_STRENGTH` + - `Potion::WEAKNESS` + - `Potion::LONG_WEAKNESS` + - `Potion::WITHER` +- The following methods have been renamed: + - `Item->getDamage()` -> `Item->getMeta()` +- The following methods have been moved to `pocketmine\inventory\CreativeInventory`: + - `Item::addCreativeItem()` -> `CreativeInventory::add()` + - `Item::clearCreativeItems()` -> `CreativeInventory::clear()` + - `Item::getCreativeItemIndex()` -> `CreativeInventory::getItemIndex()` + - `Item::getCreativeItems()` -> `CreativeInventory::getAll()` + - `Item::initCreativeItems()` -> `CreativeInventory::init()` + - `Item::isCreativeItem()` -> `CreativeInventory::contains()` + - `Item::removeCreativeItem()` -> `CreativeInventory::remove()` +- The following classes have been added: + - `ArmorTypeInfo` + - `Fertilizer` + - `LiquidBucket` + - `MilkBucket` + - `PotionType`: enum class containing information about vanilla potion types + - `WritableBookBase` + - `WritableBookPage` +- The following API methods have been added: + - `Armor->getArmorSlot()` + - `Item->canStackWith()`: returns whether the two items could be contained in the same inventory slot, ignoring count and stack size limits + - `Potion->getType()`: returns a `PotionType` enum object containing information such as the applied effects + - `ProjectileItem->createEntity()`: returns a new instance of the projectile entity that will be thrown +- The following classes have been removed: + - `ChainBoots` + - `ChainChestplate` + - `ChainHelmet` + - `ChainLeggings` + - `DiamondBoots` + - `DiamondChestplate` + - `DiamondHelmet` + - `DiamondLeggings` + - `GoldBoots` + - `GoldChestplate` + - `GoldHelmet` + - `GoldLeggings` + - `IronBoots` + - `IronChesplate` + - `IronHelmet` + - `IronLeggings` + - `LeatherBoots` + - `LeatherCap` + - `LeatherPants` + - `LeatherTunic` + +#### NBT handling +- Serialized NBT byte array caches are no longer stored on itemstacks. These caches were a premature optimization used for network layer serialization and as such were dependent on the network NBT format. +- Internal NBT usage has been marginalized. It's no longer necessary to immediately write changes to NBT. The following hooks have been added: + - `Item->serializeCompoundTag()` + - `Item->deserializeCompoundTag()` +- It's planned to remove runtime NBT from items completely, but this currently presents unresolved backwards-compatibility problems. + +#### Enchantment +- `VanillaEnchantments` class has been added. This exposes all vanilla enchantment types as static methods, replacing the old `Enchantment::get()` nastiness. + - Example: `Enchantment::get(Enchantment::PROTECTION)` is replaced by `VanillaEnchantments::PROTECTION()` + - These methods also provide proper type information to static analysers instead of just generic `Enchantment`, making them easier to code with. +- The boundaries between MCPE enchantment IDs and PocketMine-MP internals are now more clear. + - ID handling is moved to `pocketmine\data\bedrock\EnchantmentIdMap`. + - All enchantment ID constants have been removed from `Enchantment`. `pocketmine\data\bedrock\EnchantmentIds` if you still need legacy effect IDs for some reason. +- `Enchantment::RARITY_*` constants were moved to `Rarity` class, and the `RARITY_` prefixes removed. +- `Enchantment::SLOT_*` constants were moved to `ItemFlags` class, and the `SLOT_` prefixes removed. +- The following API methods have been moved: + - `Enchantment::registerEnchantment()` -> `EnchantmentIdMap->register()` + - `Enchantment::getEnchantment()` -> `EnchantmentIdMap->fromId()` + - `Enchantment->getId()` -> `EnchantmentIdMap->toId()` + - `Enchantment::getEnchantmentByName()` -> `VanillaEnchantments::fromString()` +- The following API methods have been added: + - `Enchantment->getRuntimeId()`: this is a **dynamic ID** which can be used for enchantment type comparisons. **This cannot be stored, so don't use it in configs or NBT!** + +### Lang +- The following classes have been renamed: + - `BaseLang` -> `Language` + - `TranslationContainer` -> `Translatable` +- The following classes have been removed: + - `TextContainer` +- The following API methods have been added: + - `Translatable->format()`: allows adding formatting (such as color codes) to a translation + - `Translatable->prefix()`: allows prefixing formatting + - `Translatable->postfix()`: allows postfixing formatting +- The following API methods have changed signatures: + - `Translatable->__construct()` now accepts `array` for parameters, instead of just `list`. + - `Translatable->getParameter()` now accepts `int|string` for the index instead of just `int`. + - `Translatable->getParameter()` now returns `Translatable|string` instead of just `string`. + - `Translatable->getParameters()` now returns `array`. +- `LanguageNotFoundException` has been added. This is thrown when trying to construct a `Language` which doesn't exist in the server files. +- `Translatable` no longer discards keys for translation parameters. Previously, only the insertion order was considered. +- `Translatable` now supports string keys for translation parameters. +- `Translatable` now supports providing other `Translatable`s as translation parameters. +- `Language->translateString()` now supports providing `Translatable`s as translation parameters. +- `Language->translateString()` no longer automatically attempts to translate string parameters. If you want them to be translated, translate them explicitly. This fixes bugs where player chat messages containing translation keys would be unexpectedly translated. +- `Language->translate()` no longer attempts to translate string parameters of `Translatable` (same rationale as previous point). + +### Network +- The following fields have been removed: + - `Network::$BATCH_THRESHOLD` +- The following classes have been renamed: + - `SourceInterface` -> `NetworkInterface` + - `AdvancedSourceInterface` -> `AdvancedNetworkInterface` +- The following classes have been moved: + - `CompressBatchedTask` -> `mcpe\CompressBatchTask` + - `level\format\io\ChunkRequestTask` -> `mcpe\ChunkRequestTask` + - `mcpe\RakLibInterface` -> `mcpe\raklib\RakLibInterface` +- The following classes have been removed: + - `mcpe\PlayerNetworkSessionAdapter` +- The following methods have been renamed: + - `UPnP::PortForward()` -> `UPnP::portForward()` + - `UPnP::RemovePortForward()` -> `UPnP::removePortForward()` +- The following methods have changed signatures: + - `UPnP::portForward()` now accepts `string $serviceURL, string $internalIP, int $internalPort, int $externalPort`. + - `UPnP::removePortForward()` now accepts `string $serviceURL, int $externalPort`. +- The following methods have been removed: + - `NetworkInterface->putPacket()` + - `NetworkInterface->close()` + - `NetworkInterface->emergencyShutdown()` +- `NetworkInterface` now represents a more generic interface to be implemented by any network component, as opposed to specifically a player network interface. +- Everything under the `rcon` subnamespace has been removed. +- `upnp\UPnP` has significant changes. It's now a network component instead of a pair of static methods. + +### Permission +- The following new permission nodes have been introduced: + - `pocketmine.group.everyone`: granted to everyone by default + - `pocketmine.group.operator`: granted to operator players and the console + These permission nodes can be assigned and overridden by permission attachments just like any other, which means it's now possible to grant **temporary operator** status which goes away when the player disconnects (or the attachment is removed). +- Permissions are now always false if they haven't been set explictly, or granted implicitly by another permission. +- Undefined permissions are now always `false` instead of following the value of `Permission::$DEFAULT_PERMISSION`. +- Permissions internally no longer have default values. Instead, they are now assigned as a child of one of the `pocketmine.group` permissions: + - `true`: add as child to `pocketmine.group.everyone` with value `true` + - `false`: do not add to any permission + - `op`: add as child to `pocketmine.group.operator` with value `true` + - `notop`: add as child to `pocketmine.group.everyone` with value `true`, and to `pocketmine.group.operator` with value `false` + However, the `default` key in `plugin.yml` permission definitions continues to be supported. +- Added `PermissibleDelegateTrait` to reduce boilerplate for users of `PermissibleBase`. This trait is used by `ConsoleCommandSender` and `Player`. +- The following API methods have been moved: + - `Permission::getByName()` -> `PermissionParser::defaultFromString()` + - `Permission::loadPermissions()` -> `PermissionParser::loadPermissions()` + - `Permission::loadPermission()` -> `PermissionParser::loadPermission()` +- The following constants have been moved: + - `Permission::DEFAULT_FALSE` -> `PermissionParser::DEFAULT_FALSE` + - `Permission::DEFAULT_TRUE` -> `PermissionParser::DEFAULT_TRUE` + - `Permission::DEFAULT_OP` -> `PermissionParser::DEFAULT_OP` + - `Permission::DEFAULT_NOT_OP` -> `PermissionParser::DEFAULT_NOT_OP` +- The following API methods have been added: + - `Permission->addChild()` + - `Permission->removeChild()` + - `Permissible->getPermissionRecalculationCallbacks()` - allows reacting to changes of permissions, such as new permissions being granted or denied + - `Permissible->setBasePermission()` - used for assigning root permissions like `pocketmine.group.operator`; plugins usually shouldn't use this + - `Permissible->unsetBasePermission()` + - `PermissionAttachmentInfo->getGroupPermissionInfo()` - returns the `PermissionAttachmentInfo` of the permission that caused the current permission value to be set, or null if the permission is explicit +- The following API methods have been removed: + - `Permissible->isOp()`: use `Permissible->hasPermission(DefaultPermissions::ROOT_OPERATOR)` instead, **but you really shouldn't directly depend on a player's op status, add your own permissions instead!** + - `Permissible->setOp()`: use `addAttachment($plugin, DefaultPermissions::ROOT_OPERATOR, true)` instead to add, and `removeAttachment()` to remove it (or addAttachment() with false to explicitly deny it, just like any other permission) + - `Permission->addParent()` + - `Permission->getDefault()` + - `Permission->setDefault()` + - `PermissionManager->getDefaultPermissions()` + - `PermissionManager->recalculatePermissionDefaults()` + - `PermissionManager->subscribeToDefaultPerms()` + - `PermissionManager->unsubscribeFromDefaultPerms()` + - `PermissionManager->getDefaultPermSubscriptions()` + - `PermissionAttachment->getPermissible()` + - `PermissionAttachmentInfo->getPermissible()` +- The following fields have been removed: + - `Permission::$DEFAULT_PERMISSION` +- The following API methods have changes: + - `PermissionParser::defaultFromString()` now throws `InvalidArgumentException` on unknown values. + - `Permission->__construct()` no longer accepts a `$defaultValue` parameter (see notes above about defaults refactor).you should add your permission as a child of `pocketmine.group.everyone` or `pocketmine.group.operator` instead). +- The following classes have been removed: + - `ServerOperator` + +### Player +- The following classes have moved to the new `pocketmine\player` namespace: + - `Achievement` + - `GameMode` + - `IPlayer` + - `OfflinePlayer` + - `PlayerInfo` + - `Player` +- The following constants have been removed: + - `Player::SURVIVAL` - use `GameMode::SURVIVAL()` + - `Player::CREATIVE` - use `GameMode::CREATIVE()` + - `Player::ADVENTURE` - use `GameMode::ADVENTURE()` + - `Player::SPECTATOR` - use `GameMode::SPECTATOR()` + - `Player::VIEW` - use `GameMode::SPECTATOR()` +- (almost) all packet handlers have been removed from `Player`. They are now encapsulated within the network layer. +- `Player->getSpawn()` no longer returns the world's safe spawn if the player's spawn position isn't set. Returning the safe spawn at the time of call made no sense, because it might not have been safe when actually used. You should pass the result of this function to `World->getSafeSpawn()` to get a safe spawn position instead. +- The following API methods have been added: + - `Player->attackBlock()`: attack (left click) the target block, e.g. to start destroying it (survival) + - `Player->attackEntity()`: melee-attack (left click) the target entity (if within range) + - `Player->breakBlock()`: destroy the target block in the current world (immediately) + - `Player->consumeHeldItem()`: consume the previously activated item, e.g. eating food + - `Player->continueBreakBlock()`: punch the target block during destruction in survival, advancing break animation and creating particles + - `Player->getItemCooldownExpiry()`: returns the tick on which the player's cooldown for a given item expires + - `Player->hasFiniteResources()` + - `Player->interactBlock()`: interact (right click) the target block in the current world + - `Player->interactEntity()`: interact (right click) the target entity, e.g. to apply a nametag (not implemented yet) + - `Player->pickBlock()`: picks (mousewheel click) the target block in the current world + - `Player->releaseHeldItem()`: release the previously activated item, e.g. shooting a bow + - `Player->selectHotbarSlot()`: select the specified hotbar slot + - `Player->stopBreakBlock()`: cease attacking a previously attacked block + - `Player->toggleFlight()`: tries to start / stop flying (fires events, may be cancelled) + - `Player->updateNextPosition()`: sets the player's next attempted move location (fires events, may be cancelled) + - `Player->useHeldItem()`: activate the held item, e.g. throwing a snowball + - `Player->getSaveData()`: returns save data generated on the fly +- The following API methods have been removed: + - `Player->addActionBarMessage()`: replaced by `sendActionBarMessage()` + - `Player->addSubTitle()`: replaced by `sendSubTitle()` + - `Player->addTitle()`: replaced by `sendTitle()` + - `Player->getAddress()`: replaced by `NetworkSession->getIp()` + - `Player->getPing()`: moved to `NetworkSession` + - `Player->getPort()`: moved to `NetworkSession` + - `Player->updatePing()`: moved to `NetworkSession` + - `Player->dataPacket()`: replaced by `NetworkSession->sendDataPacket()` + - `Player->sendDataPacket()`: replaced by `NetworkSession->sendDataPacket()` + - `Player->updateNextPosition()`: use `Player->handleMovement()` instead + - `IPlayer->isWhitelisted()`: use `Server->isWhitelisted()` instead + - `IPlayer->setWhitelisted()`: use `Server->setWhitelisted()` instead + - `IPlayer->isBanned()`: this was unreliable because it only checked name bans and didn't account for plugin custom ban systems. Use `Server->getNameBans()->isBanned()` and `Server->getIPBans()->isBanned()` instead. + - `IPlayer->setBanned()`: use `Server` APIs instead + - `IPlayer->isOp()`: use `Server` APIs instead + - `IPlayer->setOp()`: use `Server` APIs instead + +### Plugin +- API version checks are now more strict. It is no longer legal to declare multiple minimum versions on the same major version. Doing so will now cause the plugin to fail to load with the message `Multiple minimum API versions found for some major versions`. +- `plugin.yml` YAML commands loading is now internalized inside `PluginBase`. +- `PluginManager->registerEvent()` now has a simpler signature: `registerEvent(string $event, \Closure $handler, int $priority, Plugin $plugin, bool $handleCancelled = false)`. The provided closure must accept the specified event class as its only parameter. See [Event API changes](#event) for more details. +- The following classes have been removed: + - `PluginLogger` +- The following constants have been removed: + - `PluginLoadOrder::STARTUP` - use `PluginEnableOrder::STARTUP()` + - `PluginLoadOrder::POSTWORLD` - use `PluginEnableOrder::POSTWORLD()` +- The following interface requirements have been removed: + - `Plugin->onEnable()`: this is now internalized inside `PluginBase` + - `Plugin->onDisable()`: same as above + - `Plugin->onLoad()`: same as above + - `Plugin->getServer()` is no longer required to be implemented. It's implemented in `PluginBase` for convenience. + - `Plugin->isDisabled()` was removed (use `Plugin->isEnabled()` instead). + - `Plugin` no longer extends `CommandExecutor`. This means that `Plugin` implementations don't need to implement `onCommand()` anymore. +- The following hook methods have changed visibility: + - `PluginBase->onEnable()` changed from `public` to `protected` + - `PluginBase->onDisable()` changed from `public` to `protected` + - `PluginBase->onLoad()` changed from `public` to `protected` +- The following hook methods have been renamed: + - `Plugin->setEnabled()` -> `Plugin->onEnableStateChange()`. This change was made to force plugin developers misusing this hook to stop, and to give it a name that better describes what it does. +- The following (deprecated) API methods have been removed: + - `PluginManager->callEvent()`: use `Event->call()` instead + - `PluginManager->addPermission()`: use `PermissionManager` instead + - `PluginManager->getDefaultPermSubscriptions()`: use `PermissionManager` instead + - `PluginManager->getDefaultPermissions()`: use `PermissionManager` instead + - `PluginManager->getPermission()`: use `PermissionManager` instead + - `PluginManager->getPermissionSubscriptions()`: use `PermissionManager` instead + - `PluginManager->getPermissions()`: use `PermissionManager` instead + - `PluginManager->recalculatePermissionDefaults()`: use `PermissionManager` instead + - `PluginManager->removePermission()`: use `PermissionManager` instead + - `PluginManager->subscribeToDefaultPerms()`: use `PermissionManager` instead + - `PluginManager->subscribeToPermission()`: use `PermissionManager` instead + - `PluginManager->unsubscribeFromDefaultPerms()`: use `PermissionManager` instead + - `PluginManager->unsubscribeFromPermission()`: use `PermissionManager` instead +- It is no longer permitted to throw exceptions from `PluginBase->onEnable()` or `PluginBase->onLoad()`. Doing so will now cause the server to crash. + +### Scheduler +#### Thread-local storage for AsyncTasks +- TLS has been completely rewritten in this release to be self contained, more robust and easier to use. +- Now behaves more like simple properties. `storeLocal()` writes, `fetchLocal()` reads. +- Self-contained and doesn't depend on the async pool to clean up after it. +- Values are automatically removed from storage when the `AsyncTask` is garbage-collected, just like a regular property. +- Supports storing multiple values, differentiated by string names. +- `fetchLocal()` can now be used multiple times. It no longer deletes the stored value. +- The following classes have been removed: + - `FileWriteTask` +- The following methods have been removed: + - `AsyncTask->peekLocal()`: use `fetchLocal()` instead +- The following methods have signature changes: + - `AsyncTask->storeLocal()` now has the signature `storeLocal(string $key, mixed $complexData) : void` + - `AsyncTask->fetchLocal()` now has the signature `fetchLocal(string $key) : mixed` + +#### Other changes +- `AsyncPool` uses a new, significantly more performant algorithm for task collection. +- `BulkCurlTask` has had the `$complexData` constructor parameter removed. +- `BulkCurlTask->__construct()` now accepts `BulkCurlTaskOperation[]` instead of `mixed[]`. +- Added `CancelTaskException`, which can be thrown from `Task::onRun()` to cancel a task (especially useful for `ClosureTask`). +- `pocketmine\Collectable` has been removed, and is no longer extended by `AsyncTask`. +- The following hooks have been added: + - `AsyncTask->onError()`: called on the main thread when an uncontrolled error was detected in the async task, such as a memory failure +- The following hooks have signature changes: + - `AsyncTask->onCompletion()` no longer accepts a `Server` parameter, and has a `void` return type. + - `AsyncTask->onProgressUpdate()` no longer accepts a `Server` parameter, and has a `void` return type. +- The following API methods have been removed: + - `AsyncTask->getFromThreadStore()`: use `AsyncTask->worker->getFromThreadStore()` + - `AsyncTask->removeFromThreadStore()`: use `AsyncTask->worker->removeFromThreadStore()` + - `AsyncTask->saveToThreadStore()`: use `AsyncTask->worker->saveToThreadStore()` + +### Server +- New chat broadcasting APIs have been implemented, which don't depend on the permission system. + - The following API methods have been added: + - `subscribeToBroadcastChannel()` - allows subscribing a `CommandSender` to receive chat messages (and other message types) on any channel + - `unsubscribeFromBroadcastChannel()` + - `unsubscribeFromAllBroadcastChannels()` + - `getBroadcastChannelSubscribers()` + - Giving `Player` any `pocketmine.broadcast.*` permissions will cause them to automatically subscribe to the corresponding broadcast channel (and removing them will unsubscribe it). + - It's now possible to create and subscribe to custom broadcast channels without using permissions. + - However, `Player`s may automatically unsubscribe themselves from the builtin broadcast channels if they don't have the proper permissions. + - Automatic subscribe/unsubscribe from custom broadcast channels can be implemented using the new `Permissible` permission recalculation callbacks API. +- The following API methods have been removed: + - `reloadWhitelist()` + - `getLevelMetadata()` + - `getPlayerMetadata()` + - `getEntityMetadata()` + - `getDefaultGamemode()` + - `getLoggedInPlayers()` + - `onPlayerLogout()` + - `addPlayer()` + - `removePlayer()` + - `reload()` + - `getSpawnRadius()` + - `enablePlugin()` + - `disablePlugin()` + - `getGamemodeString()` - replaced by `pocketmine\player\GameMode->getTranslationKey()` + - `getGamemodeName()` - replaced by `pocketmine\player\GameMode->name()` + - `getGamemodeFromString()` - replaced by `GameMode::fromString()` + - `broadcast()` - use `broadcastMessage()` instead +- The following API methods have changed: + - `getOfflinePlayerData()` no longer creates data when it doesn't exist. +- The following API methods have been renamed: + - `getPlayer()` -> `getPlayerByPrefix()` (consider using `getPlayerExact()` instead where possible) + +### Level / World +#### General +- All references to `Level` in the context of "world" have been changed to `World`. + - The `pocketmine\level` namespace has been renamed to `pocketmine\world` + - All classes containing the world `Level` in the name in the "world" context have been changed to `World`. + - `Position->getLevel()` has been renamed to `Position->getWorld()`, and `Position->level` has been renamed to `Position->world`. +- Extracted a `WorldManager` unit from `Server` + - `Server->findEntity()` -> `WorldManager->findEntity()` + - `Server->generateLevel()` -> `WorldManager->generateWorld()` + - `Server->getAutoSave()` -> `WorldManager->getAutoSave()` + - `Server->getDefaultLevel()` -> `WorldManager->getDefaultWorld()` + - `Server->getLevel()` -> `WorldManager->getWorld()` + - `Server->getLevelByName()` -> `WorldManager->getWorldByName()` + - `Server->getLevels()` -> `WorldManager->getWorlds()` + - `Server->isLevelGenerated()` -> `WorldManager->isWorldGenerated()` + - `Server->isLevelLoaded()` -> `WorldManager->isWorldLoaded()` + - `Server->loadLevel()` -> `WorldManager->loadWorld()` + - `WorldManager->loadWorld()` may convert worlds if requested (the `$autoUpgrade` parameter must be provided). + - `Server->setAutoSave()` -> `WorldManager->setAutoSave()` + - `Server->setDefaultLevel()` -> `WorldManager->setDefaultWorld()` + - `Server->unloadLevel()` -> `WorldManager->unloadWorld()` +- Added `WorldManager->getAutoSaveTicks()` and `WorldManager->setAutoSaveTicks()` to allow controlling the autosave interval. +- The following classes have been added: + - `BlockTransaction`: allows creating batch commits of block changes with validation conditions - if any block can't be applied, the whole transaction fails to apply. + - `ChunkListenerNoOpTrait`: contains default no-op stubs for chunk listener implementations + - `ChunkListener`: interface allowing subscribing to events happening on a given chunk + - `TickingChunkLoader`: a `ChunkLoader` specialization that allows ticking chunks +- `ChunkLoader` no longer requires implementing `getX()` and `getZ()`. +- `ChunkLoader` no longer causes chunks to get random updates. If this behaviour is needed, implement `TickingChunkLoader`. +- The following classes have been renamed: + - `pocketmine\world\utils\SubChunkIteratorManager` -> `pocketmine\world\utils\SubChunkExplorer` +- The following API methods have been added: + - `World->registerChunkListener()` + - `World->unregisterChunkListener()` + - `World->getBlockAt()` (accepts int x/y/z instead of Vector3, faster for some use cases) + - `World->setBlockAt()` (accepts int x/y/z instead of Vector3, faster for some use cases) + - `Chunk->isDirty()` (replacement for `Chunk->hasChanged()`) + - `Chunk->getDirtyFlag()` (more granular component-based chunk dirty-flagging, used to avoid saving unmodified parts of the chunk) + - `Chunk->setDirty()` + - `Chunk->setDirtyFlag()` +- The following API methods have been removed: + - `ChunkLoader->getLoaderId()` (now object ID is used) + - `ChunkLoader->isLoaderActive()` + - `ChunkLoader->getPosition()` + - `ChunkLoader->getLevel()` + - `Chunk->fastSerialize()` (use `FastChunkSerializer::serialize()` instead) + - `Chunk->getBlockData()` + - `Chunk->getBlockDataColumn()` + - `Chunk->getBlockId()` + - `Chunk->getBlockIdColumn()` + - `Chunk->getBlockLight()` + - `Chunk->getBlockLightColumn()` + - `Chunk->getBlockSkyLight()` + - `Chunk->getBlockSkyLightColumn()` + - `Chunk->getMaxY()` + - `Chunk->getSubChunkSendCount()` (this was specialized for protocol usage) + - `Chunk->getX()` + - `Chunk->getZ()` + - `Chunk->hasChanged()` (use `Chunk->isDirty()` or `Chunk->getDirtyFlag()` instead) + - `Chunk->isGenerated()` + - `Chunk->networkSerialize()` (see `ChunkSerializer` in the `network\mcpe\serializer` package) + - `Chunk->populateSkyLight()` (use `SkyLightUpdate->recalculateChunk()` instead) + - `Chunk->recalculateHeightMap()` (moved to `SkyLightUpdate`) + - `Chunk->recalculateHeightMapColumn()` (moved to `SkyLightUpdate`) + - `Chunk->setAllBlockLight()` + - `Chunk->setAllBlockSkyLight()` + - `Chunk->setBlock()` + - `Chunk->setBlockData()` + - `Chunk->setBlockId()` + - `Chunk->setBlockLight()` + - `Chunk->setBlockSkyLight()` + - `Chunk->setChanged()` (use `Chunk->setDirty()` or `Chunk->setDirtyFlag()` instead) + - `Chunk->setGenerated()` + - `Chunk->setX()` + - `Chunk->setZ()` + - `Chunk::fastDeserialize()` (use `FastChunkSerializer::deserialize()` instead) + - `World->isFullBlock()` + - `World->getFullBlock()` + - `World->getBlockIdAt()` + - `World->setBlockIdAt()` + - `World->getBlockDataAt()` + - `World->setBlockDataAt()` + - `World->setBlockLightAt()` + - `World->setBlockSkyLightAt()` + - `World->getBlockSkyLightAt()` (use `World->getRealBlockSkyLightAt()` or `World->getPotentialBlockSkyLightAt()`, depending on use-case) + - `World->getHeightMap()` (misleading name, only actually useful for sky light calculation - you probably want `getHighestBlockAt()` instead) + - `World->setHeightMap()` (misleading name, only actually useful for sky light calculation) + - `World->getChunkEntities()` + - `World->getChunkTiles()` + - `World->getTileById()` + - `World->checkSpawnProtection()` + - `World->updateBlockLight()` + - `World->updateSkyLight()` + - `World->isFullBlock()` (use `Block->isFullCube()` instead) + - `World->sendBlocks()` + - `World->sendTime()` + - `World->addGlobalPacket()` + - `World->broadcastGlobalPacket()` + - `World->addChunkPacket()` + - `World->broadcastLevelSoundEvent()` + - `World->broadcastLevelEvent()` + - `World->getTickRate()` + - `World->setTickRate()` + - `World::generateChunkLoaderId()` +- The following API methods have changed signatures: + - `World->addParticle()` now has the signature `addParticle(Vector3 $pos, Particle $particle, ?Player[] $players = null) : void` + - `World->addSound()` now has the signature `addSound(?Vector3 $pos, Sound $sound, ?Player[] $players = null) : void` + - `World->getRandomTickedBlocks()` now returns `bool[]` instead of `SplFixedArray`. + - `World->addRandomTickedBlock()` now accepts `Block` instead of `int, int`. + - `World->removeRandomTickedBlock()` now accepts `Block` instead of `int, int`. + - `World->setBlock()` has had the `$direct` parameter removed. + - `World->loadChunk()` now returns `?Chunk`, and the `$create` parameter has been removed. + - `World->getChunk()` no longer accepts a `$create` parameter. + - `World->updateAllLight()` now accepts `int, int, int` instead of `Vector3`. + - `ChunkManager->setChunk()` (and its notable implementations in `World` and `SimpleChunkManager`) no longer accepts NULL for the `$chunk` parameter. + - `Chunk->__construct()` now has the signature `array $subChunks, ?list $entities, ?list $tiles, ?BiomeArray $biomeArray, ?HeightArray $heightArray`. + - `Chunk->getSubChunk()` now returns `SubChunk` instead of `SubChunkInterface|null` (and throws `InvalidArgumentException` on out-of-bounds coordinates). + - `Chunk->setSubChunk()` no longer accepts `SubChunkInterface`, and the `$allowEmpty` parameter has been removed. + - `WorldManager->generateWorld()` (previously `Server->generateWorld()`) now accepts `WorldCreationOptions` instead of `int $seed, class-string $generator, mixed[] $options`. +- The following API methods have been renamed / moved: + - `Level->getChunks()` -> `World->getLoadedChunks()` + - `Level->getCollisionCubes()` -> `World->getCollisionBoxes()` + - `World->getName()` -> `World->getDisplayName()` + - `World->populateChunk()` has been split into `World->requestChunkPopulation()` and `World->orderChunkPopulation()`. +- The following API methods have changed behaviour: + - `World->getChunk()` no longer tries to load chunks from disk. If the chunk is not already in memory, null is returned. (This behaviour now properly matches other `ChunkManager` implementations.) + - `World->getHighestBlockAt()` now returns `null` instead of `-1` if the target X/Z column contains no blocks. + - The following methods now throw `WorldException` when targeting ungenerated terrain: + - `World->getSafeSpawn()` (previously it just silently returned the input position) + - `World->getHighestBlockAt()` (previously it returned -1) + - `World->loadChunk()` no longer creates an empty chunk when the target chunk doesn't exist on disk. + - `World->setChunk()` now fires `ChunkLoadEvent` and `ChunkListener->onChunkLoaded()` when replacing a chunk that didn't previously exist. + - `World->useBreakOn()` now returns `false` when the target position is in an ungenerated or unloaded chunk (or chunk locked for generation). + - `World->useItemOn()` now returns `false` when the target position is in an ungenerated or unloaded chunk (or chunk locked for generation). +- A `ChunkListener` interface has been extracted from `ChunkLoader`. The following methods have been moved: + - `ChunkLoader->onBlockChanged()` -> `ChunkListener->onBlockChanged()` + - `ChunkLoader->onChunkChanged()` -> `ChunkListener->onChunkChanged()` + - `ChunkLoader->onChunkLoaded()` -> `ChunkListener->onChunkLoaded()` + - `ChunkLoader->onChunkPopulated()` -> `ChunkListener->onChunkPopulated()` + - `ChunkLoader->onChunkUnloaded()` -> `ChunkListener->onChunkUnloaded()` +- `Location` has been moved to `pocketmine\entity\Location`. + +#### Particles +- `DestroyBlockParticle` has been renamed to `BlockBreakParticle` for consistency. +- `DustParticle->__construct()` now accepts a `pocketmine\color\Color` object instead of `r, g, b, a`. +- `pocketmine\world\particle\Particle` no longer extends `pocketmine\math\Vector3`, and has been converted to an interface. +- Added the following `Particle` classes: + - `DragonEggTeleportParticle` + - `PunchBlockParticle` + +#### Sounds +- `pocketmine\world\sound\Sound` no longer extends `pocketmine\math\Vector3`, and has been converted to an interface. +- `Sound->encode()` now accepts `?\pocketmine\math\Vector3`. `NULL` may be passed for sounds which are global. +- Added the following classes: + - `ArrowHitSound` + - `BlockBreakSound` + - `BlockPlaceSound` + - `BowShootSound` + - `BucketEmptyLavaSound` + - `BucketEmptyWaterSound` + - `BucketFillLavaSound` + - `BucketFillWaterSound` + - `ChestCloseSound` + - `ChestOpenSound` + - `EnderChestCloseSound` + - `EnderChestOpenSound` + - `ExplodeSound` + - `FlintSteelSound` + - `ItemBreakSound` + - `NoteInstrument` + - `NoteSound` + - `PaintingPlaceSound` + - `PotionSplashSound` + - `RedstonePowerOffSound` + - `RedstonePowerOnSound` + - `ThrowSound` + - `XpCollectSound` + - `XpLevelUpSound` + +### Utils +- The `Color` class was removed. It's now found as `pocketmine\color\Color` in the [`pocketmine/color`](https://github.com/pmmp/Color) package. +- The `UUID` class was removed. [`ramsey/uuid`](https://github.com/ramsey/uuid) version 4.1 is now used instead. + - `UUID::fromData()` can be replaced by `Ramsey\Uuid\Uuid::uuid3()` + - `UUID::fromRandom()` can be replaced by `Ramsey\Uuid\Uuid::uuid4()` + - `UUID::fromBinary()` can be replaced by `Ramsey\Uuid\Uuid::fromBytes()` (use `Ramsey\Uuid\Uuid::isValid()` to check validity) + - `UUID::toBinary()` is replaced by `Ramsey\Uuid\UuidInterface::getBytes()` + - See the documentation at https://uuid.ramsey.dev/en/latest/introduction.html for more information. +- `Terminal::hasFormattingCodes()` no longer auto-detects the availability of formatting codes. Instead it's necessary to use `Terminal::init()` with no parameters to initialize, or `true` or `false` to override. +- `Config->save()` no longer catches exceptions thrown during emitting to disk. +- The following new classes have been added: + - `InternetException` + - `Internet` + - `Process` +- The following API methods have been added: + - `Config->getPath()`: returns the path to the config on disk + - `Terminal::write()`: emits a Minecraft-formatted text line without newline + - `Terminal::writeLine()`: emits a Minecraft-formatted text line with newline + - `Utils::recursiveUnlink()`: recursively deletes a directory and its contents +- The following API class constants have been added: + - `TextFormat::COLORS`: lists all known color codes + - `TextFormat::FORMATS`: lists all known formatting codes (e.g. italic, bold). (`RESET` is not included because it _removes_ formats, rather than adding them.) +- The following deprecated API redirects have been removed: + - `Utils::execute()`: moved to `Process` + - `Utils::getIP()`: moved to `Internet` + - `Utils::getMemoryUsage()`: moved to `Process` + - `Utils::getRealMemoryUsage()`: moved to `Process` + - `Utils::getThreadCount()`: moved to `Process` + - `Utils::getURL()`: moved to `Internet` + - `Utils::kill()`: moved to `Process` + - `Utils::postURL()`: moved to `Internet` + - `Utils::simpleCurl()`: moved to `Internet` +- The following API fields have been removed / hidden: + - `Utils::$ip` + - `Utils::$online` + - `Utils::$os` +- The following API methods have signature changes: + - `Internet::simpleCurl()` now requires a `Closure` for its `onSuccess` parameter instead of `callable`. +- The following API methods have been removed: + - `TextFormat::toJSON()` + - `Utils::getCallableIdentifier()` + +## Gameplay +### Blocks +- Implemented the following blocks: + - bamboo + - bamboo sapling + - barrel + - barrier + - blast furnace + - blue ice + - carved pumpkin + - coral block + - daylight sensor + - dried kelp + - elements (from Minecraft: Education Edition) + - hard (stained and unstained) glass (from Minecraft: Education Edition) + - hard (stained and unstained) glass pane (from Minecraft: Education Edition) + - jukebox + - note block + - red, green, blue and purple torches (from Minecraft: Education Edition) + - sea pickle + - slime + - smoker + - underwater torches (from Minecraft: Education Edition) + - additional wood variants of the following: + - buttons + - pressure plates + - signs + - trapdoors + - stairs of the following materials: + - andesite (smooth and natural) + - diorite (smooth and natural) + - end stone + - end stone brick + - granite (smooth and natural) + - mossy cobblestone + - prismarine (natural, dark and bricks) + - red nether brick + - red sandstone (and variants) + - stone-like slabs of many variants +- Non-player entities now bounce when falling on beds. +- Players and mobs now receive reduced fall damage when falling on beds. + +### Items +- Implemented the following items: + - records + - compounds (from Minecraft: Education Edition) + - black, brown, blue and white dyes + +### Inventory +- Implemented offhand inventory. +- Block-picking is now supported in survival mode. +- Block picking behaviour now matches vanilla (no longer overwrites held item, jumps to existing item where possible). +- Armor can now be equipped by right-clicking while holding it. + +# 4.0.0-BETA2 +Released 10th September 2021. + +## General +- ext-chunkutils 0.3.x is now required. +- Reduced memory usage of light storage after garbage collection. +- Reduced memory usage of uniform subchunks which only contain 1 type of block. +- The title bar no longer displays heap memory usage numbers (nobody seemed to know that was what it was, anyway). +- `/status` no longer displays heap memory usage numbers. +- `start.sh` no longer specifically mentions PHP 7 when erroring because of a missing PHP binary. +- Debug messages are now logged when reach distance checks prevent players from doing something. + +## Fixes +- Fixed players getting disconnected when using `/tp` to ungenerated chunks (or when teleported by players). +- Fixed a potential memory leak in block updating when chunks are unloaded. +- Fixed `Living->lookAt()` not taking eye height into account. +- Fixed grass replacing itself when placing grass (and consuming inventory items). +- Fixed players taking fall damage when falling next to a wall. + +## API changes +- The following API methods have been added: + - `World->getChunkEntities()` + - `World->notifyNeighbourBlockUpdate()` +- The following API methods have been removed: + - `Chunk->getEntities()` + - `Chunk->getSavableEntities()` + - `Chunk->addEntity()` + - `Chunk->removeEntity()` +- The following classes have been added: + - `pocketmine\inventory\transaction\TransactionBuilderInventory`: facilitates building `InventoryTransaction`s using standard `Inventory` API methods +- The following class constants have been added: + - `Chunk::EDGE_LENGTH` + - `Chunk::COORD_BIT_SIZE` + - `Chunk::COORD_MASK` + - `SubChunk::EDGE_LENGTH` + - `SubChunk::COORD_BIT_SIZE` + - `SubChunk::COORD_MASK` + +# 4.0.0-BETA3 + + +## General +- Added support for Minecraft: Bedrock Edition 1.17.30. +- Dropped support for Minecraft: Bedrock Edition 1.17.1x. +- `tools/convert-world.php` now writes errors to stderr and sets the proper exit code. +- Explosions now use the standard mechanism for processing block updates. Previously, it used a special mechanism due to prohibitively poor efficiency of the standard algorithm. Since these inefficiencies have now been addressed, explosions can now be consistent with everything else, with minimal performance impact. +- Command usage strings are no longer automatically translated (use `Translatable` instead of bare string keys). +- Command description strings are no longer automatically translated (use `Translatable` instead of bare string keys). + +## Fixes +- `ItemFactory->isRegistered()` no longer crashes when given negative item IDs. +- Furnaces now continue to operate after reloading the chunk they were contained in. +- Fixed being unable to reconnect for 10 seconds after disconnecting in some cases. + +## API changes +- The following API methods have been added: + - `Liquid->getMinAdjacentSourcesToFormSource()`: returns how many adjacent source blocks of the same liquid must be present in order for the current block to become a source itself + - `Player->getPlayerInfo()` +- `Liquid` minimum-cost flow calculation code has been extracted to `MinimumCostFlowCalculator`. + +# 4.0.0-BETA4 +Released 6th October 2021. + +## General +- Improved performance of lighting calculation by avoiding copies of useless data from the main thread. +- Resource pack loading now accepts `dependencies` and `capabilities` fields in the `manifest.json` (although it doesn't currently check them). +- `/help` is now localized according to language set in `server.properties`. +- Various messages related to world loading, generation and conversion are now localized according to the language set in `server.properties`. +- Compasses now point to the correct (current) world's spawn point after teleporting players to a different world. Previously, they would continue to point to the spawn of the world that the player initially spawned in. +- The `--bootstrap` CLI option has been removed. +- RakLib 0.14.2 is now required. This fixes the following issues: + - Fixed incorrect handling of sessions on client disconnect (leading to timeout debug messages). + - Fixed transferring players often not working correctly. + - Fixed disconnect screens sometimes not displaying. + +## Fixes +- Fixed server crash when UPnP encounters an error. +- Fixed server crash when clients sent items with bad NBT in inventory transactions. +- Fixed server crash when loading a plugin with legacy nested permission structure (now the plugin will fail to load, but the server won't crash). +- Fixed server crash when using `/give` with bad NBT on any item. +- Fixed server crash when loading a plugin with improperly formatted API version (now the plugin will fail to load, but the server won't crash). +- Fixed server crash when changing player gamemode during `PlayerLoginEvent`. +- Incorrect structure of `commands` in plugin manifest is now detected earlier and handled more gracefully. +- Fixed console reader subprocess lingering on server crash on Windows and screwing up the terminal. +- Fixed `Player` object memory leak when kicking players during `PlayerLoginEvent` (this caused the `World` to report warnings about leaked entities on shutdown). +- Fixed `Projectile->move()` ignoring the `dx`/`dy`/`dz` parameters given and using its own `motion` instead. +- Fixed `BlockFactory->get()` erroneously accepting meta values of `16`. +- Fixed `Block->isSameState()` false negatives for some types of slabs. +- Fixed being unable to place slabs of the same type on top of each other to create double slabs. + +## API changes +- Plugin commands in `plugin.yml` must now declare `permission` for each command. Previously, the `permission` key was optional, causing anyone to be able to use the command. + - This behaviour was removed because of the potential for security issues - a typo in `plugin.yml` could lead to dangerous functionality being exposed to everyone. + - If you want to make a command that everyone can use, declare a permission with a `default` of `true` and assign it to the command. +- Plugin permissions in `plugin.yml` must now declare `default` for each permission. Previously, the `default` key was optional, causing the permission to silently be denied to everyone (PM4) or granted to ops implicitly (PM3). + +### Block +- Added the following classes: + - `pocketmine\block\utils\LeverFacing` +- Added the following API methods: + - `pocketmine\block\Lever->isActivated()` + - `pocketmine\block\Lever->setActivated()` + - `pocketmine\block\Lever->getFacing()` + - `pocketmine\block\Lever->setFacing()` + +### World +- The following API methods have signature changes: + - `Chunk->getSubChunks()` now returns `array` instead of `SplFixedArray`. +- The following API methods have been removed: + - `FastChunkSerializer::serialize()` + - `FastChunkSerializer::deserialize()` +- The following API methods have been added: + - `FastChunkSerializer::serializeTerrain()`: serializes blocks and biomes only + - `FastChunkSerializer::deserializeTerrain()`: deserializes the output of `serializeTerrain()` + +### Utils +- The following API methods have signature changes: + - `Process::kill()` now requires an additional `bool $subprocesses` parameter. + +# 4.0.0-BETA5 +Released 12th October 2021. + +## General +- Exception log format has been changed. Now, exception info is logged in one big block message. This saves space on the console and improves readability, as well as reducing the ability for bad `ThreadedLoggerAttachment`s to break exception output. +- Log messages are now pushed to `server.log` before calling logger attachment, instead of after. This fixes messages not being written to disk when an error occurs in a logger attachment. +- Improved startup performance when loading many plugins. +- The `worlds` config in `pocketmine.yml` no longer supports attaching the generator settings to the `generator` key (use the `preset` key instead). +- Using an unknown generator in `server.properties` or `pocketmine.yml` will now cause a failure to generate the world. +- Using invalid/incorrect world generator options (presets) in `server.properties` or `pocketmine.yml` will now cause a failure to generate the world. +- Generator options of existing worlds are now validated before loading them. If they are invalid, the server will fail to load them. +- Several more log messages have been localized, including plugin loading errors. + +## Fixes +- Fixed server crash when using `/give` to give an item by ID which doesn't exist in Minecraft. +- Fixed server crash when boolean `server.properties` options were given an integer value (e.g. `0` or `1` instead of `false` or `true`). +- Fixed stats reporting checking for a nonexistent `pocketmine.yml` setting. +- Fixed use of commands without the proper permission sending a message `commands.generic.permission` instead of the proper message. +- Fixed entities set on fire appearing to stay on fire, although not taking any damage. +- Fixed a duplicate `MB` suffix on the `Memory freed` output of `/gc`. +- Fixed the server attempting to generate a world if it failed to load. + +## API +### Block +- The following API methods have been renamed: + - `Block->getPositionOffset()` -> `Block->getModelPositionOffset()`. + +### Event +- `@handleCancelled` PhpDoc annotation can no longer be used on event handlers for non-cancellable events. +- The following API methods have been added: + - `StructureGrowEvent->getPlayer()` + +### Inventory +- The following API methods have been added: + - `Inventory->getAddableItemQuantity()` + +### Scheduler +- `ClosureTask` now permits closures without an explicit return type (useful for arrow functions). + +### Utils +- The following API methods have been added: + - `Config::parseProperties()` + - `Config::writeProperties()` + - `Config::parseList()` + - `Config::writeList()` + +### World +- The following API methods have signature changes: + - `GeneratorManager->registerGenerator()` now requires a `\Closure $presetValidator` parameter. This is used to check generator options of worlds and configs before attempting to use them. + +# 4.0.0-BETA6 +Released 19th October 2021. + +## General +- Added support for Minecraft: Bedrock Edition 1.17.40. +- Removed support for earlier versions. +- CTRL+C signal handling has been restored, and is now supported on Windows. Pressing CTRL+C while the server is running will behave as if the `/stop` command was invoked. +- Added a script `tools/generate-permission-doc.php` to generate a Markdown file with a list of all permissions and their relationships. In the future, this will be used to maintain the official documentation, but plugin developers might find it useful for their own purposes too. +- [`respect/validation`](https://packagist.org/packages/respect/validation) is no longer a core dependency. + +## Fixes +- Fixed server crash when using `/give` to give an item with a too-large item ID, or `/clear` to clear an item that does not exist. + - Now, `LegacyStringToItemParser` is used exclusively, and numeric IDs are no longer parsed. + +## Gameplay +- Picking up some items from a dropped stack of items is now supported. This fixes various bugs with being unable to pick up items with an almost-full inventory. + +# 4.0.0-BETA7 +Released 28th October 2021. + +## General +- Phar plugins are now able to depend on folder plugins loaded by DevTools. +- Now uses [`pocketmine/bedrock-protocol@58c53a259e819a076bf8fe875d2a012da7d19d65`](https://github.com/pmmp/BedrockProtocol/tree/58c53a259e819a076bf8fe875d2a012da7d19d65). This version features significant changes, including: + - Standardisation of various field names (e.g. `eid` -> `actorRuntimeId`, `evid` -> `eventId`) + - Rename of `entity` related fields to `actor` where appropriate (e.g. `entityRuntimeId` -> `actorRuntimeId`) + - Block position `x`/`y`/`z` fields replaced by `BlockPosition` + - Static `::create()` functions for all packets, which ensure that fields can't be forgotten + +## Fixes +- Fixed server crash when clients send itemstacks with unmappable dynamic item IDs. +- Fixed server crash on invalid ItemStackRequest action types. +- Fixed autosave bug that caused unmodified chunks to be saved at least once (during the first autosave after they were loaded). +- Fixed `ConsoleReaderThread` returning strings with newlines still on the end. +- Fixed changes made to adjacent chunks in `ChunkPopulateEvent` (e.g. setting blocks) sometimes getting overwritten. + +## API +### Event +- `PlayerCreationEvent` now verifies that the player class set is instantiable - this ensures that plugins get properly blamed for breaking things. + +### World +- `World->generateChunkCallback()` has been specialized for use by `PopulationTask`. This allows fixing various inconsistencies involving `ChunkPopulateEvent` (e.g. modifications to adjacent chunks in `ChunkPopulationEvent` might be wiped out, if the population of the target chunk modified the adjacent chunk). + - It now accepts `Chunk $centerChunk, array $adjacentChunks` (instead of `?Chunk $chunk`). + - It's no longer expected to be used by plugins - plugins should be using `World->setChunk()` anyway. +- `Chunk->getModificationCounter()` has been added. This is a number starting from `0` when the `Chunk` object is first created (unless overridden by the constructor). It's incremented every time blocks or biomes are changed in the chunk. It resets after the chunk is unloaded and reloaded. +- The following API methods have changed signatures: + - `Sound->encode()` no longer accepts `null` for the position. + - `Chunk->__construct()`: removed `HeightArray $heightMap` parameter, added `bool $terrainPopulated` and `int $modificationCounter` parameters. + +### Plugin +- `PluginManager->loadPlugins()` now accepts paths to files as well as directories, in which case it will load only the plugin found in the target file. +- The following API methods have been removed: + - `PluginManager->loadPlugin()`: use `PluginManager->loadPlugins()` instead + +# 4.0.0-BETA8 +Released 29th October 2021. + +## General +- Chunk packet caches are now cleared by the memory manager on low memory. +- `Entity->spawnTo()` now has an additional sanity check for matching worlds (might expose a few new errors in plugins). +- [`pocketmine/math` 0.4.0](https://github.com/pmmp/Math/releases/tag/0.4.0) is now used. Please see its release notes for changes. + +## Fixes +- Zlib raw check for LevelDB is now done directly on startup, avoiding crashes when later trying to load worlds. +- Fixed tiles and entities getting deleted from adjacent chunks during chunk population. +- Fixed players being unable to open their inventories more than once. +- Fixed entities not getting updated when a nearby chunk is replaced (e.g. dropped items would float in midair if the ground was lower than before) + +## API +### World +- `World::setChunk()` has the following changes: + - `$deleteEntitiesAndTiles` parameter has been removed. + - Entities are no longer deleted on chunk replacement. + - Tiles are no longer deleted on chunk replacement, unless one of the following conditions is met: + - the target block in the new chunk doesn't expect a tile + - the target block in the new chunk expects a different type of tile (responsibility of the plugin developer to create the new tile) + - there's already a tile in the target chunk which conflicts with the old one +- `Location::__construct()` has the following changes: + - `world` parameter is now 4th instead of last. + - All parameters are now mandatory. +- Reverted addition of chunk modification counters in previous beta. +- `Chunk::DIRTY_FLAG_TERRAIN` has been renamed to `Chunk::DIRTY_FLAG_BLOCKS`. + +# 4.0.0-BETA9 +Released 2nd November 2021. + +## General +- Now analysed using level 9 on PHPStan 1.0.0. +- `ext-pthreads` v4.0.0 or newer is now required. +- `resources/vanilla` submodule has been removed. BedrockData is now included via Composer dependency [`pocketmine/bedrock-data`](https://packagist.org/packages/pocketmine/bedrock-data). +- `pocketmine/spl` Composer dependency has been dropped. +- The following Composer dependency versions are now required: + - [`pocketmine/bedrock-protocol` v5.0.0](https://github.com/pmmp/BedrockProtocol/tree/5.0.0+bedrock-1.17.40) features substantial changes to its API compared to 3.0.1, which was used in 4.0.0-BETA8. Please see its [release notes](https://github.com/pmmp/BedrockData/releases/tag/5.0.0+bedrock-1.17.40). + - [`pocketmine/log` v0.4.0](https://github.com/pmmp/Log/tree/0.4.0) removes the `LoggerAttachment` interface and replaces logger attachment objects with closures. + - [`pocketmine/log-pthreads` v0.4.0](https://github.com/pmmp/LogPthreads/tree/0.4.0) + - [`pocketmine/classloader` v0.2.0](https://github.com/pmmp/ClassLoader/tree/0.2.0) +- A noisy debug message in `World->updateAllLight()` has been removed. + +## API +### Entity +- `Human->setLifetimeTotalXp()` now limits the maximum value to 2^31. + +### Event +- `BlockGrowEvent` is now called when cocoa pods grow. + +### Item +- Added `Releasable->canStartUsingItem()`. + +### Network +- Added `NetworkInterfaceStartException`, which may be thrown by `Network->registerInterface()` and `NetworkInterface->start()`. + +### Player +- `SurvivalBlockBreakHandler::createIfNecessary()` has been removed. +- `SurvivalBlockBreakHandler->__construct()` is now public. +- `UsedChunkStatus::REQUESTED()` has been renamed to `REQUESTED_SENDING`. +- `UsedChunkStatus::REQUESTED_GENERATION()` has been added. + +### Utils +- `Promise` API has changed: + - Promise-related classes have been moved to `pocketmine\promise` namespace. + - It's now split into `Promise` and `PromiseResolver`. + - `PromiseResolver` provides only `resolve()` and `reject()`. It should be used by callbacks to resolve a promise. + - `Promise` now provides only `onCompletion()` and `isResolved()` APIs. This should be given to consumers to allow them to handle the result of the async operation. + - `PromiseResolver` must not be created directly. Use `new PromiseResolver` and `PromiseResolver->getPromise()`. + +### World +- Improved performance of `setBlock()` by around 35% when the `$update` parameter is set to `true`. +- Improved performance of `setBlock()` by around 30% when the `$update` parameter is set to `false`. +- `World->generateChunkCallback()` is no longer exposed to public API. +- `World->getAdjacentChunks()` now returns an array indexed using `World::chunkHash()`, where the `x` and `z` components are the relative offsets from the target chunk (range -1 to +1). +- `World->lockChunk()` now requires `ChunkLockId $lockId` parameter. +- `World->unlockChunk()` now requires a `?ChunkLockId $lockId` parameter. If a non-null lockID is given, the lock on the chunk will only be removed if it matches the given lockID. +- `World->unlockChunk()` now returns `bool` instead of `void` (to signal whether unlocking succeded or not). +- Added `ChunkLockId` class. + +## Fixes +### World +- Fixed server crash when tiles with colliding positions are loaded from saved data. Now, an error is logged, but the server won't crash. +- Fixed server crash when liquids and other items flow into terrain locked for population. Now, an advisory locking mechanism is used, and population results will be discarded and recalculated if modifications are detected. +- Fixed various crashes that could occur if a chunk was flagged with `setPopulated(true)` after a promise had already been created for its population. +- Fixed `AssumptionFailedError` in `PopulationTask` when workers previously used for generation are shutdown, and then restarted on the fly by a generation request. +- Fixed assertion failure in `World->drainPopulationRequestQueue()` when requesting, cancelling and then re-requesting generation of a chunk while the generator was busy. +- Fixed generation potentially getting stuck if a population request was cancelled while the population task was running (failure to remove locks from used chunks). +- Fixed `World->requestChunkPopulation()` not taking into account that the target chunk may already be populated. This caused a variety of strange bugs and performance issues. +- Fixed potential memory leak caused by `World->unregisterChunkListenerFromAll()` not taking players into account. +- Fixed debug spam of `chunk has no loaders registered` messages during chunk generation. + +### Other fixes +- Fixed server crash when unable to bind to the desired port. Now, the server will show an error and gracefully stop without a crashdump instead. +- Fixed server crash in `Player->showPlayer()` when the target is not in the same world. +- Fixed players, who died in hardcore mode and were unbanned, getting re-banned on next server join. +- Fixed cake block desync when attempting to eat in creative (eating in creative is not yet supported, but the block rollback was missing). +- Fixed players being able to eat items more quickly by dropping them while eating. +- Fixed arrows getting added to creative players' inventories when picked up. +- Fixed players re-requesting the same ungenerated chunks multiple times before they were sent. +- Fixed commands not working in some cases after using some control sequences on the console. + +# 4.0.0-BETA10 +Released 2nd November 2021. + +## Fixes +- Fixed an issue with BedrockData JSON minification which broke the release build of 4.0.0-BETA9. + +# 4.0.0-BETA11 +Released 6th November 2021. + +## General +- `resources/locale` submodule has been removed. Language files are now included via Composer dependency [`pocketmine/locale-data`](https://packagist.org/packages/pocketmine/locale-data). + - This means it's now possible to run a server from git sources without cloning submodules :) + - All remaining submodules (DevTools, build/php) are non-essential for building and running a server. +- Added a tool `tools/simulate-chunk-sending.php` to visualise the behaviour of `ChunkSelector`. + +## Fixes +- Fixed server crash on saving when player XP has reached int32 max (XP is now capped, similar to Java Edition). +- Fixed another edge case in chunk generation that led to assertion failures. +- Fixed server crash when finding a list of `TAG_Float` for entity positions instead of `TAG_Double`. +- Fixed fast eating when picking up items. +- Fixed terrain being invisible for a long time when teleporting into ungenerated terrain. +- Fixed weird chunk loading when teleporting into ungenerated terrain (sometimes farther chunks would render before closer ones, leaving holes in the map temporarily). +- Fixed players re-requesting chunks when turning their heads or jumping. +- Fixed bonemeal sometimes being consumed even when cancelling `BlockGrowEvent` and `StructureGrowEvent`. + +## API +### Event +- Added `PlayerEmoteEvent`. + +### Gameplay +- Chunks are now sent in proper circles. This improves the experience when flying quickly parallel to X or Z axis, since now more chunks in front of the player will load sooner. +- Added support for emotes. + +# 4.0.0-BETA12 +Released 9th November 2021. + +## General +- Introduced support for connecting via IPv6. + - PHP binary used must now always be built with IPv6 support, even if IPv6 is disabled. This is because RakNet may still send link-local IPv6 loopback addresses in connection packets even when only using IPv4. + - The default port for IPv6 is `19133` (similar to Bedrock Dedicated Server). + - Port `19133` is used by default so that Minecraft Bedrock can detect IPv6 servers on LAN. + - GS4 Query is supported on both IPv4 and IPv6 according to `server.properties` settings. + - The following `server.properties` settings are influential: + - `enable-ipv6`: `on` by default. Disabling this completely disables IPv6 support. + - `server-ipv6`: `::` by default (equivalent to "any IP", like `0.0.0.0` for IPv4). Most users shouldn't need to change this setting, and it doesn't appear in `server.properties` by default. + - `server-portv6`: `19133` by default. You may run both IPv4 and IPv6 on the same port. +- Various internal changes have been made to prepare for negative Y axis support (upcoming 1.18). + +## Fixes +- Fixed resource packs not applying. +- Fixed inventory windows being unopenable after dying with inventory windows open. +- Fixed plugins being able to alter other plugins' permission defaults by redeclaring them in the `plugin.yml`. + +## API +### Block +- `VanillaBlocks::fromString()` has been removed. +- Added `CraftingTableInventory`. This exclusively represents a crafting table's 3x3 crafting grid. + +### Crafting +- `CraftingGrid` is now abstract. +- Removed `CraftingGrid->getHolder()`. +- The constructor of `CraftingGrid` no longer accepts a `Player` parameter. + +### Entity +#### Effect +- `Effect->__construct()` once again accepts an `int $defaultDuration` parameter. +- Removed `VanillaEffects::fromString()`. +- Added `StringToEffectParser` + - Supports custom aliases! + - This is used by `/effect` to provide name support. + +### Event +- `InventoryOpenEvent` is now fired when a player opens a crafting table's UI. +- `InventoryCloseEvent` is now fired when a player closes a crafting table's UI. +- `PlayerDropItemEvent` will now prevent the drops from force-closing of the following inventories: + - anvil + - enchanting table + - loom + +### Inventory +- Added `TemporaryInventory`. This should be implemented by any inventory whose contents should be evacuated when closing. +- Added `PlayerCraftingInventory`. This exclusively represents the player's own 2x2 crafting grid. + +### Item +- Removed `VanillaItems::fromString()` + - Obsoleted by the far superior, much more dynamic, and plugin-customizable `StringToItemParser`. + - `StringToItemParser` allows mapping strings to closure callbacks, allowing you to create aliases for `/give` for any item, including custom ones. + +#### Enchantment +- Removed `VanillaEnchantments::fromString()`. +- Added `StringToEnchantmentParser` + - Supports custom aliases! + - This is used by `/enchant` to provide name support. + +### Player +- Removed `Player->setCraftingGrid()`. To open a 3x3 crafting grid to a player, use `setCurrentWindow(new CraftingTableInventory)`. + +### Server +- Added the following API methods: + - `Server->getIpV6()` + - `Server->getPortV6()` + +# 4.0.0-BETA13 +Released 25th November 2021. + +## General +- Improved error messages when a plugin command name or alias contains an illegal character. +- Fixed script plugins reading tags from non-docblocks before the actual docblock. +- Added a sanity check to `Human->setCurrentTotalXp()` to try and catch an elusive bug that's been appearing in the wild - please get in touch if you know how to reproduce it! +- Updated `BUILDING.md` to reflect the fact that submodules are no longer required to build or run the server. + +## Internals +- Crashdump rendering has been separated from crashdump data generation. This allows rendering crashdumps from existing JSON data. +- Direct iteration of arrays with string keys is now disallowed by a custom PHPStan rule. This is because numeric strings are casted to integers when used as array keys, which produces a variety of unexpected behaviour particularly for iteration. + - To iterate on arrays with string keys, `Utils::stringifyKeys()` must now be used. + +## Fixes +- Fixed various crashes involving bad entity data saved on disk (e.g. an item entity with invalid item would crash the server). +- Fixed various crashes involving arrays with numeric string keys. +- Fixed crash when players try to pickup XP while already having max XP. +- Fixed ungenerated chunks saved on disk by old versions of PocketMine-MP (before 3.0.0) being treated as corrupted during world conversion (they are now ignored instead). +- Fixed misleading corruption error message when saved chunks have missing NBT tags. + +## Gameplay +- Fixed `/setworldspawn` setting incorrect positions based on player position when in negative coordinates. +- `/setworldspawn` now accepts relative coordinates when used as a player. +- Added some extra aliases for `/give` and `/clear`: `chipped_anvil`, `coarse_dirt`, `damaged_anvil`, `dark_oak_standing_sign`, `jungle_wood_stairs`, `jungle_wooden_stairs` and `oak_standing_sign`. + - Some of these were added for quality-of-life, others were added just to be consistent. +- Fixed explosions dropping incorrect items when destroying blocks with tile data (e.g. banners, beds). +- Fixed the bounding box of skulls when mounted on a wall. +- Fixed podzol dropping itself when mined (instead of dirt). + +## API +### Entity +- `Projectile->move()` is now protected, like its parent. + +### Utils +- `Utils::parseDocComment()` now allows `-` in tag names. + +# 4.0.0-BETA14 +Released 30th November 2021. + +## General +- The server will now log an EMERGENCY-level message when `forceShutdown()` is used for any other reason than a graceful shutdown. +- The server will now attempt to translate invalid blocks to valid equivalents when loading chunks. This fixes many issues with `update!` blocks appearing in worlds, particularly ghost structures (these would appear when world editors previously erased some blocks by setting their IDs but not metadata). + +## Fixes +- Fixed `ConsoleReaderThread` spawning many zombie processes when running a server inside a Docker container. + +# 4.0.0-BETA15 +Released 30th November 2021. + +## General +- Added support for Minecraft: Bedrock 1.18.0 +- Removed support for earlier versions. diff --git a/changelogs/4.0.md b/changelogs/4.0.md index a08f22428d..213ab4f7de 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -1,111 +1,174 @@ -# 4.0.0-BETA1 -Released 7th September 2021. +# 4.0.0 +Released 1st December 2021. This major version features substantial changes throughout the core, including significant API changes, new world format support, performance improvements and a network revamp. -Please note that this is a BETA release and is not finalized. While no significant changes are expected between now and release, the API might still be changed. - Please also note that this changelog is provided on a best-effort basis, and it's possible some changes might not have been mentioned here. If you find any omissions, please submit pull requests to add them. -## WARNING -This is NOT a stable release. PMMP accepts no responsibility or liability for any damages incurred by using this build. -It should be used for TESTING purposes only. - -## Contents - * [Core](#core) - + [General](#general) - + [Configuration](#configuration) - + [World handling](#world-handling) - - [Interface](#interface) - - [Functional](#functional) - - [Performance](#performance) - + [Logger revamp](#logger-revamp) - + [Network](#network) - - [Minecraft Bedrock packet encryption](#minecraft-bedrock-packet-encryption) - - [Packet receive error handling has been overhauled](#packet-receive-error-handling-has-been-overhauled) - - [New packet handler system](#new-packet-handler-system) - * [API](#api) - + [General](#general-1) - + [Changes to `plugin.yml`](#changes-to-pluginyml) - - [Permission nesting](#permission-nesting) - - [`src-namespace-prefix`](#src-namespace-prefix) - + [Block](#block) - + [Command](#command) - + [Entity](#entity) - - [General](#general-2) - - [Effect](#effect) - - [Removal of runtime entity NBT](#removal-of-runtime-entity-nbt) - - [Entity creation](#entity-creation) - - [WIP removal of entity network metadata](#wip-removal-of-entity-network-metadata) - + [Event](#event) - - [Internal event system no longer depends on `Listener`s](#internal-event-system-no-longer-depends-on-listeners) - - [Default cancelled handling behaviour has changed](#default-cancelled-handling-behaviour-has-changed) - - [`PlayerPreLoginEvent` changes](#playerpreloginevent-changes) - - [Other changes](#other-changes) - + [Inventory](#inventory) - + [Item](#item) - - [General](#general-3) - - [NBT handling](#nbt-handling) - - [Enchantment](#enchantment) - + [Lang](#lang) - + [Network](#network-1) - + [Permission](#permission) - + [Player](#player) - + [Plugin](#plugin) - + [Scheduler](#scheduler) - - [Thread-local storage for AsyncTasks](#thread-local-storage-for-asynctasks) - - [Other changes](#other-changes-1) - + [Server](#server) - + [Level / World](#level--world) - - [General](#general-4) - - [Particles](#particles) - - [Sounds](#sounds) - + [Utils](#utils) - * [Gameplay](#gameplay) - + [Blocks](#blocks) - + [Items](#items) +* [Core](#core) + + [General](#general) + + [Dependency changes](#dependency-changes) + + [Performance](#performance) + + [Tools](#tools) + + [Commands](#commands) + + [Configuration](#configuration) + + [World handling](#world-handling) + - [Interface](#interface) + - [Functional](#functional) + - [Performance](#performance-1) + + [Logging](#logging) + + [Network](#network) + - [Performance](#performance-2) + - [Minecraft Bedrock packet encryption](#minecraft-bedrock-packet-encryption) + - [Error handling](#error-handling) + - [New packet handler system](#new-packet-handler-system) + + [Plugin loading](#plugin-loading) + + [Internals](#internals) +* [API](#api) + + [General](#general-1) + + [Changes to `plugin.yml`](#changes-to-pluginyml) + - [Permission nesting](#permission-nesting) + - [`src-namespace-prefix`](#src-namespace-prefix) + + [Other changes](#other-changes) + + [Block](#block) + + [Command](#command) + + [Entity](#entity) + - [General](#general-2) + - [Effect](#effect) + - [Removal of runtime entity NBT](#removal-of-runtime-entity-nbt) + - [Entity creation](#entity-creation) + - [WIP removal of entity network metadata](#wip-removal-of-entity-network-metadata) + + [Event](#event) + - [Internal event system no longer depends on `Listener`s](#internal-event-system-no-longer-depends-on-listeners) + - [Default cancelled handling behaviour has changed](#default-cancelled-handling-behaviour-has-changed) + - [`PlayerPreLoginEvent` changes](#playerpreloginevent-changes) + - [Other changes](#other-changes-1) + + [Inventory](#inventory) + + [Item](#item) + - [General](#general-3) + - [NBT handling](#nbt-handling) + - [Enchantment](#enchantment) + + [Lang](#lang) + + [Network](#network-1) + + [Permission](#permission) + + [Player](#player) + + [Plugin](#plugin) + + [Promise](#promise) + + [Scheduler](#scheduler) + - [Thread-local storage for AsyncTasks](#thread-local-storage-for-asynctasks) + - [Other AsyncTask changes](#other-asynctask-changes) + - [Non-AsyncTask changes](#non-asynctask-changes) + + [Server](#server) + + [Level / World](#level--world) + - [General](#general-4) + - [Particles](#particles) + - [Sounds](#sounds) + + [Utils](#utils) +* [Gameplay](#gameplay) + + [World loading](#world-loading) + + [Blocks](#blocks) + + [Items](#items) + + [Inventory](#inventory-1) + + [Misc](#misc) Table of contents generated with markdown-toc ## Core ### General -- A new "plugin greylist" feature has been introduced, which allows whitelisting or blacklisting plugins from loading. - Remote console (RCON) has been removed. The [RconServer](https://github.com/pmmp/RconServer) plugin is provided as a substitute. - Spawn protection has been removed. The [BasicSpawnProtection](https://github.com/pmmp/BasicSpawnProtection) plugin is provided as a substitute. -- CTRL+C signal handling has been removed. The [PcntlSignalHandler](https://github.com/pmmp/PcntlSignalHandler) plugin is provided as a substitute. - Player movement anti-cheat has been removed. - GS4 Query no longer breaks when disabling RakLib. -- The `pocketmine_chunkutils` PHP extension has been dropped. -- New PHP extensions are required by this version: - - [chunkutils2](https://github.com/pmmp/ext-chunkutils2) - - [morton](https://github.com/pmmp/ext-morton) -- Many bugs in player respawning have been fixed, including: - - Spawning underneath bedrock when spawn position referred to ungenerated terrain - - Spawning underneath bedrock on first server join on very slow machines (or when the machine was under very high load) - - Spawning inside blocks (or above the ground) when respawning with a custom spawn position set - - Player spawn positions sticking to the old location when world spawn position changed - this was because the world spawn at time of player creation was used as the player's custom spawn, so the bug will persist for older player data, but will work as expected for new players. - PreProcessor is removed from builds due to high maintenance cost and low benefit. Its usage is now discouraged. +- The title bar no longer displays heap memory usage numbers (nobody seemed to know that was what it was, anyway). +- `start.sh` no longer specifically mentions PHP 7 when erroring because of a missing PHP binary. +- The `--bootstrap` CLI option has been removed. +- Introduced support for connecting via IPv6: + - PHP binary used must now always be built with IPv6 support, even if IPv6 is disabled. This is because RakNet may still send link-local IPv6 loopback addresses in connection packets even when only using IPv4. + - Port `19133` is used for IPv6 by default so that Minecraft Bedrock can detect IPv6 servers on LAN. + - GS4 Query is supported on both IPv4 and IPv6 according to `server.properties` settings. + - New `server.properties` options `enable-ipv6`, `server-ipv6`, `server-portv6` have been added (see below). + +### Dependency changes +- The `pocketmine_chunkutils` PHP extension has been dropped. +- IPv6 support in PHP is now mandatory. +- New PHP extensions are required by this version: + - [crypto](https://github.com/bukka/php-crypto) + - [chunkutils2](https://github.com/pmmp/ext-chunkutils2) + - [gmp](https://www.php.net/manual/en/book.gmp.php) + - [igbinary](https://github.com/igbinary/igbinary) + - [leveldb](https://github.com/pmmp/php-leveldb) (must be built with [pmmp/leveldb](https://github.com/pmmp/leveldb/tree/mojang-compatible)) + - [morton](https://github.com/pmmp/ext-morton) +- The following Composer dependency versions have changed (**PLEASE READ, dependency API changes are not mentioned in this changelog!**): + - `pocketmine/bedrock-protocol` has been added at [7.0.0](https://github.com/pmmp/BedrockProtocol/releases/tag/7.0.0+bedrock-1.18.0). + - `pocketmine/classloader` has been updated from 0.1.0 to [0.2.0](https://github.com/pmmp/ClassLoader/releases/tag/0.2.0) (**significant API changes, new features**). + - `pocketmine/color` has been added at [0.2.0](https://github.com/pmmp/Color/releases/tag/0.2.0). + - `pocketmine/errorhandler` has been added at [0.3.0](https://github.com/pmmp/ErrorHandler/releases/tag/0.3.0). + - `pocketmine/locale-data` has been added at [2.0.16](https://github.com/pmmp/Language/releases/tag/2.0.16). + - `pocketmine/log` has been updated from 0.2.0 to [0.4.0](https://github.com/pmmp/Log/releases/tag/0.4.0) (**minor API changes**, see also [0.3.0](https://github.com/pmmp/Log/releases/tag/0.3.0)). + - `pocketmine/nbt` has been updated from 0.2.18 to [0.3.0](https://github.com/pmmp/NBT/releases/tag/0.3.0) (**significant API changes**). + - `pocketmine/raklib` has been updated from 0.12.7 to [0.14.2](https://github.com/pmmp/RakLib/releases/tag/0.14.2) (**significant API changes**, see also [0.13.0](https://github.com/pmmp/RakLib/releases/tag/0.13.0)). + - `pocketmine/raklib-ipc` has been added at [0.1.0](https://github.com/pmmp/RakLibIpc/releases/tag/0.1.0) (components extracted from RakLib). + - `pocketmine/snooze` has been updated from 0.1.0 to [0.3.0](https://github.com/pmmp/Snooze/releases/tag/0.3.0) (**minor API changes**, see also [0.2.0](https://github.com/pmmp/Snooze/releases/tag/0.2.0)). + - `pocketmine/spl` has been dropped. +- Minecraft Bedrock protocol is now developed in a separate repository, [pmmp/BedrockProtocol](https://github.com/pmmp/BedrockProtocol). + - It has significant changes compared to PM3. Please read its changelogs. +- The following submodules have been removed: + - `resources/vanilla`: BedrockData is now included via Composer dependency [`pocketmine/bedrock-data`](https://packagist.org/packages/pocketmine/bedrock-data). + - `resources/locale`: Language files are now included via Composer dependency [`pocketmine/locale-data`](https://packagist.org/packages/pocketmine/locale-data). + - This means it's now possible to run a server from git sources without cloning submodules :) + - All remaining submodules (DevTools, build/php) are non-essential for building and running a server. + +### Performance +- `/op`, `/deop`, `/whitelist add` and `/whitelist remove` no longer cause player data to be loaded from disk for no reason. +- Timings now use high-resolution timers provided by `hrtime()` to collect more accurate performance metrics. +- Closures are now used for internal event handler calls. This provides a performance improvement of 10-20% over the 3.x system, which had to dynamically resolve callables for every event call. +- Improved startup performance when loading many plugins. +- See more in the [Worlds / Performance](#performance-2) and [Network / Performance](#performance-3) sections. + +### Tools +Some new scripts have been added in the `tools/` directory of the repository. These scripts may use the PocketMine-MP core library, but are intended to be run standalone. + + - `convert-world.php`: allows converting a world to a new format without a running server + - `compact-regions.php`: repacks files in legacy Region worlds to clean up wasted disk space + - `generate-permission-doc.php`: generates a Markdown document of all core permissions (see [example](https://gist.github.com/dktapps/eed6d6a4571f01b676236bf9ff2779b2)) + - `simulate-chunk-selector.php`: generates a series of images to visualize the behaviour of the chunk sending algorithm; these images can then be stitched into video using a tool such as [ffmpeg](https://ffmpeg.org/) ### Commands -- The `/reload` command has been removed. - The `/effect` command no longer supports numeric IDs - it's now required to use names. - The `/enchant` command no longer supports numeric IDs - it's now required to use names. +- The `/give` command no longer permits giving items with invalid NBT (e.g. incorrect types). Previously, this was the cause of random server crashes when using items on PM3. +- The `/give` command now supports many new aliases like in Java, e.g. it's now possible to do `/give someone bonemeal` or `/give someone lapis_lazuli` instead of using legacy id:metadata. +- The `/help` command is now localized according to language set in `server.properties`. +- The `/reload` command has been removed. +- The `/setworldspawn` command now accepts relative coordinates when used as a player. +- The `/status` command no longer displays heap memory usage numbers. - Added `/clear` command with functionality equivalent to that of vanilla Minecraft. - The following commands' outputs are now localized according to the chosen language settings: - `/gc` - `/status` - `/op` - `/deop` +- Fixed use of commands without the proper permission sending a message `commands.generic.permission` instead of the proper message. +- Fixed commands not working in some cases after using some control sequences on the console. +- Fixed `/setworldspawn` setting incorrect positions based on player position when in negative coordinates. ### Configuration - World presets can now be provided as a `preset` key in `pocketmine.yml`, instead of putting them in the `generator` key. +- The `worlds` config no longer supports attaching the generator settings to the `generator` key (use the `preset` key instead). +- Using an unknown generator in `server.properties` or `pocketmine.yml` will now cause a failure to generate the world. +- Using invalid/incorrect world generator options (presets) in `server.properties` or `pocketmine.yml` will now cause a failure to generate the world. - The following new options have been added to `pocketmine.yml`: - `chunk-ticking.blocks-per-subchunk-per-tick` (default `3`): Increasing this value will increase the rate at which random block updates happen (e.g. grass growth). - `network.enable-encryption` (default `true`): Controls whether Minecraft network packets are encrypted or not. - The following options have been removed from `pocketmine.yml`: - - `chunk-ticking.light-updates`: Since lighting is needed for basic vanilla functionality to work, allowing this to be disabled without disabling chunk ticking made no sense. If you don't want light calculation to occur, you can disable chunk ticking altogether. + - `chunk-ticking.light-updates`: Since lighting is needed for basic vanilla functionality to work, allowing this to be disabled without disabling chunk ticking made no sense. If you don't want light calculation to occur, you can disable chunk ticking altogether by setting `chunk-ticking.per-tick` to `0` in `pocketmine.yml`. - `player.anti-cheat.allow-movement-cheats` +- The following new options have been added to `server.properties`: + - `enable-ipv6`: `on` by default. Disabling this completely disables IPv6 support. + - `server-ipv6`: `::` by default (equivalent to "any IP", like `0.0.0.0` for IPv4). Most users shouldn't need to change this setting, and it doesn't appear in `server.properties` by default. + - `server-portv6`: `19133` by default. You may run both IPv4 and IPv6 on the same port, but since Bedrock scans on 19133 by default, PM also uses the same. ### World handling #### Interface @@ -118,37 +181,52 @@ It should be used for TESTING purposes only. - `mcregion` - `anvil` - `pmanvil` +- Generator options of existing worlds are now validated before loading them. If they are invalid, the server will fail to load them. +- Fixed the server attempting to generate a world if it failed to load. - 256 build-height is now supported in all worlds (facilitated by automatic conversion). - Extended blocks are now supported (facilitated by automatic conversion). +- The server will now attempt to translate invalid blocks to valid equivalents when loading chunks. This fixes many issues with `update!` blocks appearing in worlds, particularly ghost structures (these would appear when world editors previously erased some blocks by setting their IDs but not metadata). - Lighting is no longer stored or loaded from disk - instead, it's calculated on the fly as-needed. This fixes many long-standing bugs. +- Explosions now use the standard mechanism for processing block updates. Previously, it used a special mechanism due to prohibitively poor efficiency of the standard algorithm. Since these inefficiencies have now been addressed, explosions can now be consistent with everything else, with minimal performance impact. +- Fixed debug spam of `chunk has no loaders registered` messages during chunk generation. +- Various cases of corrupted data in chunks will now cause an error to be logged instead of a server crash. This includes tiles with colliding positions and tiles in incorrect, non-loaded chunks. +- Fixed players re-requesting the same ungenerated chunks multiple times before they were sent. +- Fixed players re-requesting chunks when turning their heads or jumping. #### Performance - `leveldb` is now the primary supported world format. It is inherently faster than region-based formats thanks to better design. - Partial chunk saves (only saving modified subcomponents of chunks) has been implemented. This drastically reduces the amount of data that is usually necessary to write on chunk save, which in turn **drastically reduces the time to complete world saves**. This is possible thanks to the modular design of the `leveldb` world format - this enhancement is not possible with region-based formats. - Lighting is no longer guaranteed to be available on every chunk. It's now calculated on the fly as-needed. -- `/op`, `/deop`, `/whitelist add` and `/whitelist remove` no longer cause player data to be loaded from disk for no reason. -- Timings now use high-resolution timers provided by `hrtime()` to collect more accurate performance metrics. - Z-order curves (morton codes) are now used for block and chunk coordinate hashes. This substantially improves performance in many areas by resolving a hashtable key hash collision performance issue. Affected areas include explosions, light calculation, and more. -- [`libdeflate`](https://github.com/ebiggers/libdeflate) is now (optionally) used for outbound Minecraft packet compression. It's more than twice as fast as zlib in most cases, providing significant performance boosts to packet broadcasts and overall network performance. -- Closures are now used for internal event handler calls. This provides a performance improvement of 10-20% over the 3.x system, which had to dynamically resolve callables for every event call. +- Improved performance of `World->setBlock()` by around 35% when the `$update` parameter is set to `true`. +- Improved performance of `World->setBlock()` by around 30% when the `$update` parameter is set to `false`. -### Logger revamp +### Logging - Many components now have a dedicated logger which automatically adds [prefixes] to their messages. - Main logger now includes milliseconds in timestamps. +- Debug messages are now logged when reach distance checks prevent players from doing something. +- Various messages related to world loading/generation/conversion and plugin loading errors are now localized according to the language set in `server.properties`. +- Exception log format has been changed. Now, exception info is logged in one big block message. This saves space on the console and improves readability, as well as reducing the ability for bad `ThreadedLoggerAttachment`s to break exception output. +- Improved error messages when a plugin command name or alias contains an illegal character. +- The server will now log an EMERGENCY-level message when `Server->forceShutdown()` is used for any other reason than a graceful shutdown. ### Network This version features substantial changes to the network system, improving coherency, reliability and modularity. +#### Performance +- [`libdeflate`](https://github.com/ebiggers/libdeflate) is now (optionally) used for outbound Minecraft packet compression. It's more than twice as fast as zlib in most cases, providing significant performance boosts to packet broadcasts and overall network performance. + #### Minecraft Bedrock packet encryption - This fixes replay attacks where hackers steal and replay player logins. - A new setting has been added to `pocketmine.yml`: `network.enable-encryption` which is `true` by default. -#### Packet receive error handling has been overhauled +#### Error handling - Only `BadPacketException` is now caught during packet decode and handling. This requires that all decoding MUST perform proper data error checking. - Throwing a `BadPacketException` from decoding will now cause players to be kicked with the message `Packet processing error`. - The disconnect message includes a random hex ID to help server owners identify the problems reported by their players. - Throwing any other exception will now cause a server crash. `Internal server error` has been removed. - It is now illegal to send a clientbound packet to the server. Doing so will result in the client being kicked with the message `Unexpected non-serverbound packet`. +- Fixed server crash when unable to bind to the desired port. Now, the server will show an error and gracefully stop without a crashdump instead. #### New packet handler system - Packet handlers have been separated from NetworkSession into a dedicated packet handler structure. @@ -158,6 +236,16 @@ This version features substantial changes to the network system, improving coher - Packet handlers are now almost entirely absent from `Player` and instead appear in their own dedicated units. - Almost all game logic that was previously locked up inside packet handlers in `Player` has been extracted into new API methods. See Player API changes for details. +### Plugin loading +- Phar plugins are now able to depend on folder plugins loaded by DevTools. +- A new "plugin greylist" feature has been introduced, which allows whitelisting or blacklisting plugins from loading. See `plugin_list.yml`. + +### Internals +- Crashdump rendering has been separated from crashdump data generation. This allows rendering crashdumps from existing JSON data. +- Direct iteration of arrays with string keys is now disallowed by a custom PHPStan rule. This is because numeric strings are casted to integers when used as array keys, which produces a variety of unexpected behaviour particularly for iteration. + - To iterate on arrays with string keys, `Utils::stringifyKeys()` must now be used. +- Fixed various crashes involving arrays with numeric string keys. + ## API ### General - Most places which previously allowed `callable` now only allow `\Closure`. This is because closures have more consistent behaviour and are more performant. @@ -215,14 +303,26 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` **Note**: The old structure will also still work just fine. This is not a required change. +### Other changes +- Incorrect structure of `commands` is now detected earlier and handled more gracefully. +- Commands must now declare `permission` for each command. Previously, the `permission` key was optional, causing anyone to be able to use the command. + - This behaviour was removed because of the potential for security issues - a typo in `plugin.yml` could lead to dangerous functionality being exposed to everyone. + - If you want to make a command that everyone can use, declare a permission with a `default` of `true` and assign it to the command. +- Permissions must now declare `default` for each permission. Previously, the `default` key was optional, causing the permission to silently be denied to everyone (PM4) or granted to ops implicitly (PM3). + ### Block - A new `VanillaBlocks` class has been added, which contains static methods for creating any currently-known block type. This should be preferred instead of use of `BlockFactory::get()` where constants were used. +- `BlockFactory` is now a singleton, and its methods are no longer static. `BlockFactory::whatever()` should be replaced with `BlockFactory::getInstance()->whatever()`. +- `BlockFactory->get()` is now **deprecated**. + - For most cases, `VanillaBlocks::WHATEVER_BLOCK()` should fill your needs. + - `BlockFactory` should now only be used for loading old save data from, for example, a database, config or a world save. + - To refer to blocks by name, consider using `StringToItemParser` to accept names instead of IDs. - Blocks now contain their positions instead of extending `Position`. `Block->getPosition()` has been added. - Blocks with IDs >= 256 are now supported. - Block state and variant metadata have been separated. - Variant is considered an extension of ID and is immutable. - `Block->setDamage()` has been removed. - - All blocks now have getters and setters for their appropriate block properties, such as facing, lit/unlit, colour (in some cases), and many more. These should be used instead of metadata. +- All blocks now have getters and setters for their appropriate block properties, such as facing, lit/unlit, colour (in some cases), and many more. These should be used instead of metadata. - Tile entities are now created and deleted automatically when `World->setBlock()` is used with a block that requires a tile entity. - Some tile entities' API has been exposed on their corresponding `Block` classes, with the tile entity classes being deprecated. - The `pocketmine\tile` namespace has been relocated to `pocketmine\block\tile`. @@ -237,9 +337,11 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Block->isCompatibleWithTool()` -> `BlockBreakInfo->isToolCompatible()` - The following API methods have been added: - `Block->asItem()`: returns an itemstack corresponding to the block + - `Block->getModelPositionOffset()`: used to offset the bounding box of blocks like bamboo based on coordinates - `Block->isSameState()`: returns whether the block is the same as the parameter, including state information - `Block->isSameType()`: returns whether the block is the same as the parameter, without state information - `Block->isFullCube()` + - `Liquid->getMinAdjacentSourcesToFormSource()`: returns how many adjacent source blocks of the same liquid must be present in order for the current block to become a source itself - The following hooks have been added: - `Block->onAttack()`: called when a player in survival left-clicks the block to try to start breaking it - `Block->onEntityLand()`: called when an entity lands on this block after falling (from any distance) @@ -256,12 +358,16 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Block->setDamage()` - `Block::get()`: this was superseded by `BlockFactory::get()` a long time ago - `Block->getBoundingBox()` +- The following classes have been added: + - `inventory\CraftingTableInventory`: represents a crafting table's 3x3 crafting grid + - `utils\LeverFacing` + - `utils\MinimumFlowCostCalculator`: encapsulates flow calculation logic previously locked inside `Liquid`. - The following classes have been renamed: - `BlockIds` -> `BlockLegacyIds` - `CobblestoneWall` -> `Wall` - `NoteBlock` -> `Note` - - `SignPost` -> `Sign` - - `StandingBanner` -> `Banner` + - `SignPost` -> `FloorSign` + - `StandingBanner` -> `FloorBanner` - The following classes have been removed: - `Bricks` - `BurningFurnace` @@ -308,7 +414,14 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - The following API methods have signature changes: - `Command->setPermission()` argument is now mandatory (but still nullable). - `CommandSender->setScreenLineHeight()` argument is now mandatory (but still nullable). + - `Command->getDescription()` now returns `Translatable|string`. + - `Command->getUsage()` now returns `Translatable|string`. + - `Command->setDescription()` now accepts `Translatable|string`. + - `Command->setUsage()` now accepts `Translatable|string`. +- `Command->setPermission()` now throws an exception if given a string containing non-existing permissions. Previously, it would silently default to allowing ops to use the command, which may not have been desired. + - This is usually caused by a typo or forgotten permission declaration. - Commands with spaces in the name are no longer supported. +- Command usage strings and description strings are no longer automatically translated (use `Translatable` instead of bare string keys). ### Entity #### General @@ -337,6 +450,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Entity->setPositionAndRotation()` is now `protected` (use `Entity->teleport()` instead). - `Living->knockBack()` now accepts `float, float, float` (the first two parameters have been removed). - `Living->getEffects()` now returns `EffectManager` instead of `Effect[]`. + - `Location->__construct()` now accepts `?World $world` in the 4th parameter, and all parameters are now mandatory. - The following classes have been added: - `effect\EffectManager`: contains effect-management functionality extracted from `Living` - `HungerManager`: contains hunger-management functionality extracted from `Human` @@ -388,6 +502,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Rideable` - `Vehicle` - `Skin` now throws exceptions on creation if given invalid data. +- Fixed `Living->lookAt()` not taking eye height into account. #### Effect - All `Effect` related classes have been moved to the `pocketmine\entity\effect` namespace. @@ -416,9 +531,10 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Effect->getId()` -> `EffectIdMap->toId()` - `Effect::registerEffect()` -> `EffectIdMap->register()` - `Effect::getEffect()` -> `EffectIdMap->fromId()` - - `Effect::getEffectByName()` -> `VanillaEffects::fromString()` -- The following API methods have been added: - - `Effect->getRuntimeId()`: this is a **dynamic ID** which can be used for effect type comparisons. **This cannot be stored, so don't use it in configs or NBT!** + - `Effect::getEffectByName()` -> `StringToEffectParser->parse()` +- Added `StringToEffectParser` singleton: + - Supports custom aliases! + - This is used by `/effect` to provide name support. #### Removal of runtime entity NBT - Entities no longer keep their NBT alive at runtime. @@ -430,17 +546,18 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Entity::createEntity()` has been removed. It's no longer needed for creating new entities at runtime - just use `new YourEntity` instead. - `Entity` subclass constructors can now have any signature, just like a normal class. - Loading entities from NBT is now handled by `EntityFactory`. It works quite a bit differently than `Entity::createEntity()` did. Instead of registering `YourEntity::class` to a set of Minecraft save IDs, you now need to provide a callback which will construct an entity when given some NBT and a `World`. - - The creation callback is registered using `EntityFactory::register()`. - - The creation callback must have the signature `function(World, CompoundTag) : Entity`. + - `EntityFactory` is a singleton. You can get its instance by using `EntityFactory::getInstance()`. + - Creation callbacks are registered using `EntityFactory->register()`. + - Creation callbacks must have the signature `function(World, CompoundTag) : Entity`. - This enables `Entity` subclasses to have any constructor parameters they like. - It also allows requiring that certain data is always provided (for example, it doesn't make much sense to create a `FallingBlock` without specifying what type of block). - Examples: - `ItemEntity` now requires an `Item` in its constructor, so its creation callback decodes the `Item` from the NBT to be passed to the constructor. - `Painting` now requires a `PaintingMotive` in its constructor, so its creation callback decides which `PaintingMotive` to provide based on the NBT it receives. - See `EntityFactory` for more examples. -- `EntityFactory::register()` (previously `Entity::registerEntity()`) will now throw exceptions on error cases instead of returning `false`. +- `EntityFactory->register()` (previously `Entity::registerEntity()`) will now throw exceptions on error cases instead of returning `false`. - The following API methods have been moved: - - `Entity::registerEntity()` -> `EntityFactory::register()` + - `Entity::registerEntity()` -> `EntityFactory->register()` - The following classes have changed constructors: - All projectile subclasses now require a `?Entity $thrower` parameter. - `Arrow->__construct()` now requires a `bool $critical` parameter (in addition to the `$thrower` parameter). @@ -480,6 +597,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - Handler functions will now **not receive cancelled events by default**. This is a **silent BC break**, i.e. it won't raise errors, but it might cause bugs. - `@ignoreCancelled` is now no longer respected. - `@handleCancelled` has been added. This allows opting _into_ receiving cancelled events (it's the opposite of `@ignoreCancelled`). + - `@handleCancelled` may not be used on non-cancellable events (an exception will be thrown during registration). #### `PlayerPreLoginEvent` changes - The `Player` object no longer exists at this phase of the login. Instead, a `PlayerInfo` object is provided, along with connection information. @@ -521,28 +639,39 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` #### Other changes - Disconnecting players during events no longer crashes the server (although it might cause other side effects). -- `PlayerKickEvent` is no longer fired for disconnects that occur before the player completes the initial login sequence (i.e. completing downloading resource packs). - Cancellable events must now implement `CancellableTrait` to get the cancellable components needed to satisfy interface requirements. `Event` no longer stubs these methods. - `PlayerInteractEvent` is no longer fired when a player activates an item. This fixes the age-old complaint of `PlayerInteractEvent` firing multiple times when interacting once. The following constants have been removed: - `PlayerInteractEvent::LEFT_CLICK_AIR` - `PlayerInteractEvent::RIGHT_CLICK_AIR` - `PlayerInteractEvent::PHYSICAL` - The following events have been added: - - `PlayerEntityInteractEvent`: player right-clicking (or long-clicking on mobile) on an entity. - - `PlayerItemUseEvent`: player activating their held item, for example to throw it. - `BlockTeleportEvent`: block teleporting, for example dragon egg when attacked. - - `PlayerDisplayNameChangeEvent` - `EntityItemPickupEvent`: player (or other entity) picks up a dropped item (or arrow). Replaces `InventoryPickupItemEvent` and `InventoryPickupArrowEvent`. - Unlike its predecessors, this event supports changing the destination inventory. - If the destination inventory is `null`, the item will be destroyed. This is usually seen for creative players with full inventories. - `EntityTrampleFarmlandEvent`: mob (or player) jumping on farmland causing it to turn to dirt + - `PlayerDisplayNameChangeEvent` + - `PlayerEmoteEvent` + - `PlayerEntityInteractEvent`: player right-clicking (or long-clicking on mobile) on an entity. + - `PlayerItemUseEvent`: player activating their held item, for example to throw it. - `StructureGrowEvent`: called when trees or bamboo grow (or any other multi-block plant structure). +- The following events have changed behaviour: + - Bone meal is now consistently never consumed when `BlockGrowEvent` or `StructureGrowEvent` is cancelled. + - `BlockGrowEvent` is now called when cocoa pods grow. + - `ChunkPopulateEvent` is now called after all adjacent chunks modified during population have been updated. This fixes issues with modifications made in the event sometimes disappearing. + - `InventoryOpenEvent` is now fired when a player opens a crafting table's UI. + - `InventoryCloseEvent` is now fired when a player closes a crafting table's UI. + - `PlayerDropItemEvent` will now prevent the drops from force-closing of the following inventories: + - anvil + - enchanting table + - loom + - `PlayerKickEvent` is no longer fired for disconnects that occur before the player completes the initial login sequence (i.e. completing downloading resource packs). - The following events have been removed: - `EntityArmorChangeEvent` - `EntityInventoryChangeEvent` - `EntityLevelChangeEvent` - `EntityTeleportEvent` with world checks should be used instead. - - `InventoryPickupItemEvent` - use `EntityItemPickupEvent` instead - `InventoryPickupArrowEvent` - use `EntityItemPickupEvent` instead + - `InventoryPickupItemEvent` - use `EntityItemPickupEvent` instead - `NetworkInterfaceCrashEvent` - `PlayerCheatEvent` - `PlayerIllegalMoveEvent` @@ -560,6 +689,8 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `HandlerList::unregisterAll()` -> `HandlerListManager->unregisterAll()` - `HandlerList::getHandlerListFor()` -> `HandlerListManager->getListFor()` - `HandlerList::getHandlerLists()` -> `HandlerListManager->getAll()` +- The following API methods have changed behaviour: + - `PlayerCreationEvent->setPlayerClass()` now verifies that the player class set is instantiable. - The following classes have been moved: - `pocketmine\plugin\RegisteredListener` -> `pocketmine\event\RegisteredListener` @@ -569,9 +700,12 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `CallbackInventoryChangeListener` - `CreativeInventory`: contains the creative functionality previously embedded in `pocketmine\item\Item`, see Item changes for details - `InventoryChangeListener`: allows listening (but not interfering with) events in an inventory. + - `PlayerCraftingInventory`: represents the player's own 2x2 crafting grid. - `PlayerEnderInventory`: represents the pure storage part of the player's ender inventory, without any block information + - `TemporaryInventory`: interface which should be implemented by any inventory whose contents should be evacuated when closing. - `transaction\CreateItemAction` - `transaction\DestroyItemAction` + - `transaction\TransactionBuilderInventory`: facilitates building `InventoryTransaction`s using standard `Inventory` API methods - The following classes have been renamed / moved: - `ContainerInventory` -> `pocketmine\block\inventory\BlockInventory` - The following classes have been moved to the `pocketmine\block\inventory` namespace: @@ -591,9 +725,11 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Inventory->getChangeListeners()` - `Inventory->removeChangeListeners()` - `Inventory->swap()`: swaps the contents of two slots + - `Inventory->getAddableItemQuantity()`: returns how many items from the given stack can be added to the inventory, used for partial pickups of itemstacks with a full inventory - The following API methods have been removed: - `BaseInventory->getDefaultSize()` - `BaseInventory->setSize()` + - `CraftingGrid->getHolder()` - `EnderChestInventory->setHolderPosition()` - `Inventory->close()` - `Inventory->dropContents()` @@ -607,24 +743,28 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `InventoryAction->onExecuteSuccess()` - `PlayerInventory->sendCreativeContents()` - The following API methods have signature changes: + - `BaseInventory->__construct()` no longer accepts a list of items to initialize with. + - `CraftingGrid->__construct()` no longer accepts a `Player` parameter. - `Inventory->clear()` now returns `void` instead of `bool`. - `Inventory->setItem()` now returns `void` instead of `bool`. - `InventoryAction->execute()` now returns `void` instead of `bool`. - - `BaseInventory->construct()` no longer accepts a list of items to initialize with. - `PlayerInventory->setItemInHand()` now sends the update to viewers of the player. +- `CraftingGrid` is now abstract. ### Item #### General - A new `VanillaItems` class has been added, which contains static methods for creating any currently-known item type. This should be preferred instead of use of `ItemFactory::get()` where constants were used. -- `StringToItemParser` has been added, which allows mapping any string to any item, irrespective of IDs. These mappings are used by `/give` and `/clear`, and are made with custom plugin aliases in mind. +- `StringToItemParser` singleton has been added: + - This allows mapping any string to any item, irrespective of IDs + - These mappings are used by `/give` and `/clear`, and are made with custom plugin aliases in mind. - Yes, this means you can finally add your own custom aliases to `/give` without ugly hacks! -- `LegacyStringToItemParser` has been added, which is a slightly more dynamic (but still inadvisable) replacement for `ItemFactory::fromString()`. +- `LegacyStringToItemParser` singleton has been added. This supports id:meta parsing in the same way that `ItemFactory::fromString()` used to, but its use is discouraged. +- `ItemFactory` is now a singleton instead of static class, and its remaining methods are no longer static. You can get its instance by `ItemFactory::getInstance()`. - `Item->count` is no longer public. - The hierarchy of writable books has been changed: `WritableBook` and `WrittenBook` now extend `WritableBookBase`. - The following API methods have signature changes: - `WritableBookBase->setPages()` now accepts `WritableBookPage[]` instead of `CompoundTag[]`. - - `ItemFactory::get()` no longer accepts `string` for the `tags` parameter. - - `ItemFactory::fromString()` no longer accepts a `$multiple` parameter and now only returns `Item`, not `Item|Item[]`. + - `ItemFactory->get()` no longer accepts `string` for the `tags` parameter. - The following methods are now fluent: - `WritableBookBase->setPages()` - `Item->addEnchantment()` @@ -639,8 +779,9 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Item->removeNamedTagEntry()` - `Item->setDamage()`: "Damage" is now immutable for all items except `Durable` descendents. - `Item->setNamedTagEntry()` - - `Item::get()`: this was superseded by `ItemFactory::get()` a long time ago - - `Item::fromString()`: this was superseded by `ItemFactory::fromString()` a long time ago + - `Item::get()`: prefer `VanillaItems` or `StringToItemParser` if possible; use `ItemFactory->get()` if you have no other choice + - `Item::fromString()`: use `StringToItemParser->parse()` or `LegacyStringToItemParser->parse()` instead + - `ItemFactory::fromString()` - `Item->setCompoundTag()` - `Item->getCompoundTag()` - `Item->hasCompoundTag()` @@ -701,6 +842,8 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `LiquidBucket` - `MilkBucket` - `PotionType`: enum class containing information about vanilla potion types + - `Releasable`: this interface is implemented by items like bows which have a "release" action + - `StringToItemParser`: allows converting string IDs into any item, used by `/give` and `/clear` - `WritableBookBase` - `WritableBookPage` - The following API methods have been added: @@ -742,7 +885,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - Example: `Enchantment::get(Enchantment::PROTECTION)` is replaced by `VanillaEnchantments::PROTECTION()` - These methods also provide proper type information to static analysers instead of just generic `Enchantment`, making them easier to code with. - The boundaries between MCPE enchantment IDs and PocketMine-MP internals are now more clear. - - ID handling is moved to `pocketmine\data\bedrock\EnchantmentIdMap`. + - ID handling is moved to `pocketmine\data\bedrock\EnchantmentIdMap` singleton. - All enchantment ID constants have been removed from `Enchantment`. `pocketmine\data\bedrock\EnchantmentIds` if you still need legacy effect IDs for some reason. - `Enchantment::RARITY_*` constants were moved to `Rarity` class, and the `RARITY_` prefixes removed. - `Enchantment::SLOT_*` constants were moved to `ItemFlags` class, and the `SLOT_` prefixes removed. @@ -750,9 +893,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Enchantment::registerEnchantment()` -> `EnchantmentIdMap->register()` - `Enchantment::getEnchantment()` -> `EnchantmentIdMap->fromId()` - `Enchantment->getId()` -> `EnchantmentIdMap->toId()` - - `Enchantment::getEnchantmentByName()` -> `VanillaEnchantments::fromString()` -- The following API methods have been added: - - `Enchantment->getRuntimeId()`: this is a **dynamic ID** which can be used for enchantment type comparisons. **This cannot be stored, so don't use it in configs or NBT!** + - `Enchantment::getEnchantmentByName()` -> `StringToEnchantmentParser->parse()` ### Lang - The following classes have been renamed: @@ -780,6 +921,8 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` ### Network - The following fields have been removed: - `Network::$BATCH_THRESHOLD` +- The following classes have been added: + - `NetworkInterfaceStartException`: this may be thrown by `Network->registerInterface()` and `NetworkInterface->start()` to cause a graceful failure without crashing - this should be used when, for example, you are unable to bind a port - The following classes have been renamed: - `SourceInterface` -> `NetworkInterface` - `AdvancedSourceInterface` -> `AdvancedNetworkInterface` @@ -855,13 +998,15 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `ServerOperator` ### Player -- The following classes have moved to the new `pocketmine\player` namespace: +- The following classes have been added/moved to the new `pocketmine\player` namespace: - `Achievement` - `GameMode` - `IPlayer` - `OfflinePlayer` - `PlayerInfo` - `Player` + - `SurvivalBlockBreakHandler`: handles cracking animation, sounds and particles when mining a block in creative + - `UsedChunkStatus`: enum used internally by the chunk sending system - The following constants have been removed: - `Player::SURVIVAL` - use `GameMode::SURVIVAL()` - `Player::CREATIVE` - use `GameMode::CREATIVE()` @@ -876,35 +1021,45 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Player->breakBlock()`: destroy the target block in the current world (immediately) - `Player->consumeHeldItem()`: consume the previously activated item, e.g. eating food - `Player->continueBreakBlock()`: punch the target block during destruction in survival, advancing break animation and creating particles + - `Player->getCurrentWindow()`: returns the inventory window the player is currently viewing, or null if they aren't viewing an inventory - `Player->getItemCooldownExpiry()`: returns the tick on which the player's cooldown for a given item expires + - `Player->getPlayerInfo()`: returns a `PlayerInfo` object containing various metadata about the player + - `Player->getSaveData()`: returns save data generated on the fly - `Player->hasFiniteResources()` - `Player->interactBlock()`: interact (right click) the target block in the current world - `Player->interactEntity()`: interact (right click) the target entity, e.g. to apply a nametag (not implemented yet) - `Player->pickBlock()`: picks (mousewheel click) the target block in the current world - `Player->releaseHeldItem()`: release the previously activated item, e.g. shooting a bow + - `Player->removeCurrentWindow()`: removes the inventory window the player is currently viewing, if any - `Player->selectHotbarSlot()`: select the specified hotbar slot + - `Player->setCurrentWindow()`: sets the inventory the player is currently viewing - `Player->stopBreakBlock()`: cease attacking a previously attacked block - `Player->toggleFlight()`: tries to start / stop flying (fires events, may be cancelled) - `Player->updateNextPosition()`: sets the player's next attempted move location (fires events, may be cancelled) - `Player->useHeldItem()`: activate the held item, e.g. throwing a snowball - - `Player->getSaveData()`: returns save data generated on the fly - The following API methods have been removed: + - `IPlayer->isBanned()`: this was unreliable because it only checked name bans and didn't account for plugin custom ban systems. Use `Server->getNameBans()->isBanned()` and `Server->getIPBans()->isBanned()` instead. + - `IPlayer->isOp()`: use `Server` APIs instead + - `IPlayer->isWhitelisted()`: use `Server->isWhitelisted()` instead + - `IPlayer->setBanned()`: use `Server` APIs instead + - `IPlayer->setOp()`: use `Server` APIs instead + - `IPlayer->setWhitelisted()`: use `Server->setWhitelisted()` instead - `Player->addActionBarMessage()`: replaced by `sendActionBarMessage()` - `Player->addSubTitle()`: replaced by `sendSubTitle()` - `Player->addTitle()`: replaced by `sendTitle()` + - `Player->addWindow()`: use `Player->setCurrentWindow()` instead + - `Player->dataPacket()`: replaced by `NetworkSession->sendDataPacket()` - `Player->getAddress()`: replaced by `NetworkSession->getIp()` - `Player->getPing()`: moved to `NetworkSession` - `Player->getPort()`: moved to `NetworkSession` - - `Player->updatePing()`: moved to `NetworkSession` - - `Player->dataPacket()`: replaced by `NetworkSession->sendDataPacket()` + - `Player->getWindow()`: use `Player->getCurrentWindow()` instead + - `Player->getWindowId()` + - `Player->removeAllWindows()` + - `Player->removeWindow()`: use `Player->removeCurrentWindow()` instead - `Player->sendDataPacket()`: replaced by `NetworkSession->sendDataPacket()` + - `Player->setCraftingGrid()`: crafting tables now work the same way as other containers; use `Player->setCurrentWindow()` - `Player->updateNextPosition()`: use `Player->handleMovement()` instead - - `IPlayer->isWhitelisted()`: use `Server->isWhitelisted()` instead - - `IPlayer->setWhitelisted()`: use `Server->setWhitelisted()` instead - - `IPlayer->isBanned()`: this was unreliable because it only checked name bans and didn't account for plugin custom ban systems. Use `Server->getNameBans()->isBanned()` and `Server->getIPBans()->isBanned()` instead. - - `IPlayer->setBanned()`: use `Server` APIs instead - - `IPlayer->isOp()`: use `Server` APIs instead - - `IPlayer->setOp()`: use `Server` APIs instead + - `Player->updatePing()`: moved to `NetworkSession` ### Plugin - API version checks are now more strict. It is no longer legal to declare multiple minimum versions on the same major version. Doing so will now cause the plugin to fail to load with the message `Multiple minimum API versions found for some major versions`. @@ -928,22 +1083,33 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `PluginBase->onLoad()` changed from `public` to `protected` - The following hook methods have been renamed: - `Plugin->setEnabled()` -> `Plugin->onEnableStateChange()`. This change was made to force plugin developers misusing this hook to stop, and to give it a name that better describes what it does. -- The following (deprecated) API methods have been removed: - - `PluginManager->callEvent()`: use `Event->call()` instead +- The following API methods have been removed: - `PluginManager->addPermission()`: use `PermissionManager` instead + - `PluginManager->callEvent()`: use `Event->call()` instead - `PluginManager->getDefaultPermSubscriptions()`: use `PermissionManager` instead - `PluginManager->getDefaultPermissions()`: use `PermissionManager` instead - `PluginManager->getPermission()`: use `PermissionManager` instead - `PluginManager->getPermissionSubscriptions()`: use `PermissionManager` instead - `PluginManager->getPermissions()`: use `PermissionManager` instead + - `PluginManager->loadPlugin()`: use `PluginManager->loadPlugins()` instead - `PluginManager->recalculatePermissionDefaults()`: use `PermissionManager` instead - `PluginManager->removePermission()`: use `PermissionManager` instead - `PluginManager->subscribeToDefaultPerms()`: use `PermissionManager` instead - `PluginManager->subscribeToPermission()`: use `PermissionManager` instead - `PluginManager->unsubscribeFromDefaultPerms()`: use `PermissionManager` instead - `PluginManager->unsubscribeFromPermission()`: use `PermissionManager` instead +- The following API methods have changed behaviour: + - `PluginManager->loadPlugins()` now accepts paths to files as well as directories, in which case it will load only the plugin found in the target file. - It is no longer permitted to throw exceptions from `PluginBase->onEnable()` or `PluginBase->onLoad()`. Doing so will now cause the server to crash. +### Promise +A very basic in-house implementation of Promises has been added. This is currently used for handling world generation requests. + +- `PromiseResolver` is created by the creator of the task. The task should call `PromiseResolver->resolve()` when the result is ready. +- `Promise` can be obtained by using `PromiseResolver->getPromise()` and should be returned to API consumers. + +Please note that this was not written with plugins in mind and its API may change in a future version. + ### Scheduler #### Thread-local storage for AsyncTasks - TLS has been completely rewritten in this release to be self contained, more robust and easier to use. @@ -960,11 +1126,10 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `AsyncTask->storeLocal()` now has the signature `storeLocal(string $key, mixed $complexData) : void` - `AsyncTask->fetchLocal()` now has the signature `fetchLocal(string $key) : mixed` -#### Other changes +#### Other AsyncTask changes - `AsyncPool` uses a new, significantly more performant algorithm for task collection. - `BulkCurlTask` has had the `$complexData` constructor parameter removed. - `BulkCurlTask->__construct()` now accepts `BulkCurlTaskOperation[]` instead of `mixed[]`. -- Added `CancelTaskException`, which can be thrown from `Task::onRun()` to cancel a task (especially useful for `ClosureTask`). - `pocketmine\Collectable` has been removed, and is no longer extended by `AsyncTask`. - The following hooks have been added: - `AsyncTask->onError()`: called on the main thread when an uncontrolled error was detected in the async task, such as a memory failure @@ -976,39 +1141,47 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `AsyncTask->removeFromThreadStore()`: use `AsyncTask->worker->removeFromThreadStore()` - `AsyncTask->saveToThreadStore()`: use `AsyncTask->worker->saveToThreadStore()` +#### Non-AsyncTask changes +- Added `CancelTaskException`, which can be thrown from `Task->onRun()` to cancel a task (especially useful for `ClosureTask`). +- The `$currentTick` parameter of `Task->onRun()` has been removed (use `Server->getTick()` instead if needed). +- Callables given to `ClosureTask` are no longer required to declare a `void` typehint (useful for arrow functions). + ### Server - New chat broadcasting APIs have been implemented, which don't depend on the permission system. - The following API methods have been added: - - `subscribeToBroadcastChannel()` - allows subscribing a `CommandSender` to receive chat messages (and other message types) on any channel - - `unsubscribeFromBroadcastChannel()` - - `unsubscribeFromAllBroadcastChannels()` - - `getBroadcastChannelSubscribers()` + - `Server->subscribeToBroadcastChannel()` - allows subscribing a `CommandSender` to receive chat messages (and other message types) on any channel + - `Server->unsubscribeFromBroadcastChannel()` + - `Server->unsubscribeFromAllBroadcastChannels()` + - `Server->getBroadcastChannelSubscribers()` - Giving `Player` any `pocketmine.broadcast.*` permissions will cause them to automatically subscribe to the corresponding broadcast channel (and removing them will unsubscribe it). - It's now possible to create and subscribe to custom broadcast channels without using permissions. - However, `Player`s may automatically unsubscribe themselves from the builtin broadcast channels if they don't have the proper permissions. - Automatic subscribe/unsubscribe from custom broadcast channels can be implemented using the new `Permissible` permission recalculation callbacks API. +- The following API methods have been added: + - `Server->getIpV6()` + - `Server->getPortV6()` - The following API methods have been removed: - - `reloadWhitelist()` - - `getLevelMetadata()` - - `getPlayerMetadata()` - - `getEntityMetadata()` - - `getDefaultGamemode()` - - `getLoggedInPlayers()` - - `onPlayerLogout()` - - `addPlayer()` - - `removePlayer()` - - `reload()` - - `getSpawnRadius()` - - `enablePlugin()` - - `disablePlugin()` - - `getGamemodeString()` - replaced by `pocketmine\player\GameMode->getTranslationKey()` - - `getGamemodeName()` - replaced by `pocketmine\player\GameMode->name()` - - `getGamemodeFromString()` - replaced by `GameMode::fromString()` - - `broadcast()` - use `broadcastMessage()` instead + - `Server->reloadWhitelist()` + - `Server->getLevelMetadata()` + - `Server->getPlayerMetadata()` + - `Server->getEntityMetadata()` + - `Server->getDefaultGamemode()` + - `Server->getLoggedInPlayers()` + - `Server->onPlayerLogout()` + - `Server->addPlayer()` + - `Server->removePlayer()` + - `Server->reload()` + - `Server->getSpawnRadius()` + - `Server->enablePlugin()` + - `Server->disablePlugin()` + - `Server->getGamemodeString()` - replaced by `pocketmine\player\GameMode->getTranslationKey()` + - `Server->getGamemodeName()` - replaced by `pocketmine\player\GameMode->name()` + - `Server->getGamemodeFromString()` - replaced by `GameMode::fromString()` + - `Server->broadcast()` - use `Server->broadcastMessage()` instead - The following API methods have changed: - - `getOfflinePlayerData()` no longer creates data when it doesn't exist. + - `Server->getOfflinePlayerData()` no longer creates data when it doesn't exist. - The following API methods have been renamed: - - `getPlayer()` -> `getPlayerByPrefix()` (consider using `getPlayerExact()` instead where possible) + - `Server->getPlayer()` -> `Server->getPlayerByPrefix()` (consider using `Server->getPlayerExact()` instead where possible) ### Level / World #### General @@ -1031,17 +1204,35 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Server->setAutoSave()` -> `WorldManager->setAutoSave()` - `Server->setDefaultLevel()` -> `WorldManager->setDefaultWorld()` - `Server->unloadLevel()` -> `WorldManager->unloadWorld()` -- Added `WorldManager->getAutoSaveTicks()` and `WorldManager->setAutoSaveTicks()` to allow controlling the autosave interval. +- The following static classes have been un-static-ified and converted to singletons (use `Whatever::getInstance()->method()` instead of `Whatever::method()`): + - `GeneratorManager` + - `WorldProviderManager` - The following classes have been added: - `BlockTransaction`: allows creating batch commits of block changes with validation conditions - if any block can't be applied, the whole transaction fails to apply. - `ChunkListenerNoOpTrait`: contains default no-op stubs for chunk listener implementations - `ChunkListener`: interface allowing subscribing to events happening on a given chunk + - `ChunkLockId`: used by `World->lockChunk()` and `World->unlockChunk()` - `TickingChunkLoader`: a `ChunkLoader` specialization that allows ticking chunks + - `format\io\FastChunkSerializer`: provides methods to encode a chunk for transmitting to another thread + - `WorldCreationOptions`: used for passing world generator options to `WorldManager->generateWorld()` - `ChunkLoader` no longer requires implementing `getX()` and `getZ()`. - `ChunkLoader` no longer causes chunks to get random updates. If this behaviour is needed, implement `TickingChunkLoader`. - The following classes have been renamed: - `pocketmine\world\utils\SubChunkIteratorManager` -> `pocketmine\world\utils\SubChunkExplorer` +- The following class constants have been added: + - `Chunk::COORD_BIT_SIZE` + - `Chunk::COORD_MASK` + - `Chunk::DIRTY_FLAG_BLOCKS` + - `Chunk::DIRTY_FLAG_TERRAIN` + - `Chunk::EDGE_LENGTH` + - `SubChunk::COORD_BIT_SIZE` + - `SubChunk::COORD_MASK` + - `SubChunk::EDGE_LENGTH` + - `World::Y_MIN` - The following API methods have been added: + - `WorldManager->getAutoSaveTicks()` + - `WorldManager->setAutoSaveTicks()` + - `World->notifyNeighbourBlockUpdate()` - `World->registerChunkListener()` - `World->unregisterChunkListener()` - `World->getBlockAt()` (accepts int x/y/z instead of Vector3, faster for some use cases) @@ -1050,12 +1241,9 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Chunk->getDirtyFlag()` (more granular component-based chunk dirty-flagging, used to avoid saving unmodified parts of the chunk) - `Chunk->setDirty()` - `Chunk->setDirtyFlag()` -- The following API methods have been removed: - - `ChunkLoader->getLoaderId()` (now object ID is used) - - `ChunkLoader->isLoaderActive()` - - `ChunkLoader->getPosition()` - - `ChunkLoader->getLevel()` - - `Chunk->fastSerialize()` (use `FastChunkSerializer::serialize()` instead) +- The following API methods have been removed from the public API: + - `Chunk->addEntity()` + - `Chunk->fastSerialize()` (use `FastChunkSerializer::serializeTerrain()` instead) - `Chunk->getBlockData()` - `Chunk->getBlockDataColumn()` - `Chunk->getBlockId()` @@ -1064,7 +1252,9 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Chunk->getBlockLightColumn()` - `Chunk->getBlockSkyLight()` - `Chunk->getBlockSkyLightColumn()` + - `Chunk->getEntities()` - `Chunk->getMaxY()` + - `Chunk->getSavableEntities()` - `Chunk->getSubChunkSendCount()` (this was specialized for protocol usage) - `Chunk->getX()` - `Chunk->getZ()` @@ -1074,6 +1264,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Chunk->populateSkyLight()` (use `SkyLightUpdate->recalculateChunk()` instead) - `Chunk->recalculateHeightMap()` (moved to `SkyLightUpdate`) - `Chunk->recalculateHeightMapColumn()` (moved to `SkyLightUpdate`) + - `Chunk->removeEntity()` - `Chunk->setAllBlockLight()` - `Chunk->setAllBlockSkyLight()` - `Chunk->setBlock()` @@ -1085,63 +1276,82 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Chunk->setGenerated()` - `Chunk->setX()` - `Chunk->setZ()` - - `Chunk::fastDeserialize()` (use `FastChunkSerializer::deserialize()` instead) - - `World->isFullBlock()` - - `World->getFullBlock()` - - `World->getBlockIdAt()` - - `World->setBlockIdAt()` - - `World->getBlockDataAt()` - - `World->setBlockDataAt()` - - `World->setBlockLightAt()` - - `World->setBlockSkyLightAt()` - - `World->getBlockSkyLightAt()` (use `World->getRealBlockSkyLightAt()` or `World->getPotentialBlockSkyLightAt()`, depending on use-case) - - `World->getHeightMap()` (misleading name, only actually useful for sky light calculation - you probably want `getHighestBlockAt()` instead) - - `World->setHeightMap()` (misleading name, only actually useful for sky light calculation) - - `World->getChunkEntities()` - - `World->getChunkTiles()` - - `World->getTileById()` + - `Chunk::fastDeserialize()` (use `FastChunkSerializer::deserializeTerrain()` instead) + - `ChunkLoader->getLevel()` + - `ChunkLoader->getLoaderId()` (now object ID is used) + - `ChunkLoader->getPosition()` + - `ChunkLoader->isLoaderActive()` + - `World->addChunkPacket()` + - `World->addGlobalPacket()` + - `World->broadcastGlobalPacket()` + - `World->broadcastLevelEvent()` + - `World->broadcastLevelSoundEvent()` - `World->checkSpawnProtection()` - - `World->updateBlockLight()` - - `World->updateSkyLight()` + - `World->generateChunkCallback()` + - `World->getBlockDataAt()` + - `World->getBlockIdAt()` + - `World->getBlockSkyLightAt()` (use `World->getRealBlockSkyLightAt()` or `World->getPotentialBlockSkyLightAt()`, depending on use-case) + - `World->getChunkTiles()` + - `World->getFullBlock()` + - `World->getHeightMap()` (misleading name, only actually useful for sky light calculation - you probably want `getHighestBlockAt()` instead) + - `World->getTickRate()` + - `World->getTileById()` + - `World->isFullBlock()` - `World->isFullBlock()` (use `Block->isFullCube()` instead) - `World->sendBlocks()` - `World->sendTime()` - - `World->addGlobalPacket()` - - `World->broadcastGlobalPacket()` - - `World->addChunkPacket()` - - `World->broadcastLevelSoundEvent()` - - `World->broadcastLevelEvent()` - - `World->getTickRate()` + - `World->setBlockDataAt()` + - `World->setBlockIdAt()` + - `World->setBlockLightAt()` + - `World->setBlockSkyLightAt()` + - `World->setHeightMap()` (misleading name, only actually useful for sky light calculation) - `World->setTickRate()` + - `World->updateBlockLight()` + - `World->updateSkyLight()` - `World::generateChunkLoaderId()` - The following API methods have changed signatures: + - `Chunk->__construct()` now has the signature `array $subChunks, BiomeArray $biomeIds, bool $terrainPopulated`. + - `Chunk->getSubChunk()` now returns `SubChunk` instead of `SubChunkInterface|null` (and throws `InvalidArgumentException` on out-of-bounds coordinates). + - `Chunk->getSubChunks()` now returns `array` instead of `SplFixedArray`. + - `Chunk->setSubChunk()` no longer accepts `SubChunkInterface`, and the `$allowEmpty` parameter has been removed. + - `ChunkManager->setChunk()` (and its notable implementations in `World` and `SimpleChunkManager`) no longer accepts NULL for the `$chunk` parameter. + - `GeneratorManager->registerGenerator()` now requires a `\Closure $presetValidator` parameter. This is used to check generator options of worlds and configs before attempting to use them. + - `Position->__construct()` now requires the `$world` parameter (it's no longer optional). - `World->addParticle()` now has the signature `addParticle(Vector3 $pos, Particle $particle, ?Player[] $players = null) : void` - - `World->addSound()` now has the signature `addSound(?Vector3 $pos, Sound $sound, ?Player[] $players = null) : void` - - `World->getRandomTickedBlocks()` now returns `bool[]` instead of `SplFixedArray`. - `World->addRandomTickedBlock()` now accepts `Block` instead of `int, int`. + - `World->addSound()` now has the signature `addSound(?Vector3 $pos, Sound $sound, ?Player[] $players = null) : void` + - `World->getChunk()` no longer accepts a `$create` parameter. + - `World->getRandomTickedBlocks()` now returns `bool[]` instead of `SplFixedArray`. + - `World->loadChunk()` now returns `?Chunk`, and the `$create` parameter has been removed. - `World->removeRandomTickedBlock()` now accepts `Block` instead of `int, int`. - `World->setBlock()` has had the `$direct` parameter removed. - - `World->loadChunk()` now returns `?Chunk`, and the `$create` parameter has been removed. - - `World->getChunk()` no longer accepts a `$create` parameter. + - `World->setChunks()` no longer accepts a `$deleteEntitiesAndTiles` parameter. - `World->updateAllLight()` now accepts `int, int, int` instead of `Vector3`. - - `ChunkManager->setChunk()` (and its notable implementations in `World` and `SimpleChunkManager`) no longer accepts NULL for the `$chunk` parameter. - - `Chunk->__construct()` now has the signature `array $subChunks, ?list $entities, ?list $tiles, ?BiomeArray $biomeArray, ?HeightArray $heightArray`. - - `Chunk->getSubChunk()` now returns `SubChunk` instead of `SubChunkInterface|null` (and throws `InvalidArgumentException` on out-of-bounds coordinates). - - `Chunk->setSubChunk()` no longer accepts `SubChunkInterface`, and the `$allowEmpty` parameter has been removed. - - `WorldManager->generateWorld()` (previously `Server->generateWorld()`) now accepts `WorldCreationOptions` instead of `int $seed, class-string $generator, mixed[] $options`. + - `WorldManager->generateWorld()` (previously `Server->generateWorld()`) now accepts `WorldCreationOptions` instead of `int $seed, class-string $generator, mixed[] $options` + - `World->lockChunk()` now requires `ChunkLockId $lockId` parameter. + - `World->unlockChunk()` now requires a `?ChunkLockId $lockId` parameter. If a non-null lockID is given, the lock on the chunk will only be removed if it matches the given lockID. + - `World->unlockChunk()` now returns `bool` instead of `void` (to signal whether unlocking succeded or not). - The following API methods have been renamed / moved: - - `Level->getChunks()` -> `World->getLoadedChunks()` - - `Level->getCollisionCubes()` -> `World->getCollisionBoxes()` + - `World->getChunks()` -> `World->getLoadedChunks()` + - `World->getCollisionCubes()` -> `World->getCollisionBoxes()` - `World->getName()` -> `World->getDisplayName()` - `World->populateChunk()` has been split into `World->requestChunkPopulation()` and `World->orderChunkPopulation()`. - The following API methods have changed behaviour: + - `World->getAdjacentChunks()` now returns an array indexed using `World::chunkHash()`, where the `x` and `z` components are the relative offsets from the target chunk (range -1 to +1). - `World->getChunk()` no longer tries to load chunks from disk. If the chunk is not already in memory, null is returned. (This behaviour now properly matches other `ChunkManager` implementations.) - `World->getHighestBlockAt()` now returns `null` instead of `-1` if the target X/Z column contains no blocks. - The following methods now throw `WorldException` when targeting ungenerated terrain: - `World->getSafeSpawn()` (previously it just silently returned the input position) - `World->getHighestBlockAt()` (previously it returned -1) - `World->loadChunk()` no longer creates an empty chunk when the target chunk doesn't exist on disk. - - `World->setChunk()` now fires `ChunkLoadEvent` and `ChunkListener->onChunkLoaded()` when replacing a chunk that didn't previously exist. + - `World->setChunk()` has the following behavioural changes: + - Now fires `ChunkLoadEvent` and `ChunkListener->onChunkLoaded()` when replacing a chunk that didn't previously exist. + - Now updates entities in the replaced chunk and its neighbours. This fixes bugs such as paintings not dropping and dropped items floating in midair if the ground was lower than before. + - Entities are no longer deleted on chunk replacement. + - Tiles are no longer deleted on chunk replacement, unless one of the following conditions is met: + - the target block in the new chunk doesn't expect a tile + - the target block in the new chunk expects a different type of tile (responsibility of the plugin developer to create the new tile) + - there's already a tile in the target chunk which conflicts with the old one - `World->useBreakOn()` now returns `false` when the target position is in an ungenerated or unloaded chunk (or chunk locked for generation). - `World->useItemOn()` now returns `false` when the target position is in an ungenerated or unloaded chunk (or chunk locked for generation). - A `ChunkListener` interface has been extracted from `ChunkLoader`. The following methods have been moved: @@ -1162,7 +1372,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` #### Sounds - `pocketmine\world\sound\Sound` no longer extends `pocketmine\math\Vector3`, and has been converted to an interface. -- `Sound->encode()` now accepts `?\pocketmine\math\Vector3`. `NULL` may be passed for sounds which are global. +- `Sound->encode()` now accepts `pocketmine\math\Vector3`. - Added the following classes: - `ArrowHitSound` - `BlockBreakSound` @@ -1196,7 +1406,7 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `UUID::fromRandom()` can be replaced by `Ramsey\Uuid\Uuid::uuid4()` - `UUID::fromBinary()` can be replaced by `Ramsey\Uuid\Uuid::fromBytes()` (use `Ramsey\Uuid\Uuid::isValid()` to check validity) - `UUID::toBinary()` is replaced by `Ramsey\Uuid\UuidInterface::getBytes()` - - See the documentation at https://uuid.ramsey.dev/en/latest/introduction.html for more information. + - See the [documentation for `ramsey/uuid`](https://uuid.ramsey.dev/en/latest/introduction.html) for more information. - `Terminal::hasFormattingCodes()` no longer auto-detects the availability of formatting codes. Instead it's necessary to use `Terminal::init()` with no parameters to initialize, or `true` or `false` to override. - `Config->save()` no longer catches exceptions thrown during emitting to disk. - The following new classes have been added: @@ -1205,6 +1415,10 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Process` - The following API methods have been added: - `Config->getPath()`: returns the path to the config on disk + - `Config::parseList()`: parses a list of entries like `ops.txt` into an array + - `Config::parseProperties()`: parses a properties file like `server.properties` into an array + - `Config::writeList()` + - `Config::writeProperties()` - `Terminal::write()`: emits a Minecraft-formatted text line without newline - `Terminal::writeLine()`: emits a Minecraft-formatted text line with newline - `Utils::recursiveUnlink()`: recursively deletes a directory and its contents @@ -1227,11 +1441,23 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - `Utils::$os` - The following API methods have signature changes: - `Internet::simpleCurl()` now requires a `Closure` for its `onSuccess` parameter instead of `callable`. + - `Process::kill()` now requires an additional `bool $subprocesses` parameter. +- The following API methods have behavioural changes: + - `Utils::parseDocComment()` now allows `-` in tag names. - The following API methods have been removed: - `TextFormat::toJSON()` - `Utils::getCallableIdentifier()` +- `MainLogger` now pushes log messages to `server.log` before calling logger attachments. This fixes messages not being written to disk when an uncaught error is thrown from a logger attachment. ## Gameplay +### World loading +- Chunks are now sent in proper circles. This improves the experience when flying quickly parallel to X or Z axis, since now more chunks in front of the player will load sooner. +- Many bugs in player respawning have been fixed, including: + - Spawning underneath bedrock when spawn position referred to ungenerated terrain + - Spawning underneath bedrock on first server join on very slow machines (or when the machine was under very high load) + - Spawning inside blocks (or above the ground) when respawning with a custom spawn position set + - Player spawn positions sticking to the old location when world spawn position changed - this was because the world spawn at time of player creation was used as the player's custom spawn, so the bug will persist for older player data, but will work as expected for new players. + ### Blocks - Implemented the following blocks: - bamboo @@ -1272,496 +1498,24 @@ However, if we add `src-namespace-prefix: pmmp\TesterPlugin` to the `plugin.yml` - stone-like slabs of many variants - Non-player entities now bounce when falling on beds. - Players and mobs now receive reduced fall damage when falling on beds. +- Fixed cake block desync when attempting to eat in creative (eating in creative is not yet supported, but the block rollback was missing). +- Fixed the bounding box of skulls when mounted on a wall. +- Fixed podzol dropping itself when mined (instead of dirt). ### Items - Implemented the following items: - records - compounds (from Minecraft: Education Edition) - black, brown, blue and white dyes +- Compasses now point to the correct (current) world's spawn point after teleporting players to a different world. Previously, they would continue to point to the spawn of the world that the player initially spawned in. ### Inventory - Implemented offhand inventory. - Block-picking is now supported in survival mode. - Block picking behaviour now matches vanilla (no longer overwrites held item, jumps to existing item where possible). - Armor can now be equipped by right-clicking while holding it. - -# 4.0.0-BETA2 -Released 10th September 2021. - -## General -- ext-chunkutils 0.3.x is now required. -- Reduced memory usage of light storage after garbage collection. -- Reduced memory usage of uniform subchunks which only contain 1 type of block. -- The title bar no longer displays heap memory usage numbers (nobody seemed to know that was what it was, anyway). -- `/status` no longer displays heap memory usage numbers. -- `start.sh` no longer specifically mentions PHP 7 when erroring because of a missing PHP binary. -- Debug messages are now logged when reach distance checks prevent players from doing something. - -## Fixes -- Fixed players getting disconnected when using `/tp` to ungenerated chunks (or when teleported by players). -- Fixed a potential memory leak in block updating when chunks are unloaded. -- Fixed `Living->lookAt()` not taking eye height into account. -- Fixed grass replacing itself when placing grass (and consuming inventory items). -- Fixed players taking fall damage when falling next to a wall. - -## API changes -- The following API methods have been added: - - `World->getChunkEntities()` - - `World->notifyNeighbourBlockUpdate()` -- The following API methods have been removed: - - `Chunk->getEntities()` - - `Chunk->getSavableEntities()` - - `Chunk->addEntity()` - - `Chunk->removeEntity()` -- The following classes have been added: - - `pocketmine\inventory\transaction\TransactionBuilderInventory`: facilitates building `InventoryTransaction`s using standard `Inventory` API methods -- The following class constants have been added: - - `Chunk::EDGE_LENGTH` - - `Chunk::COORD_BIT_SIZE` - - `Chunk::COORD_MASK` - - `SubChunk::EDGE_LENGTH` - - `SubChunk::COORD_BIT_SIZE` - - `SubChunk::COORD_MASK` - -# 4.0.0-BETA3 - - -## General -- Added support for Minecraft: Bedrock Edition 1.17.30. -- Dropped support for Minecraft: Bedrock Edition 1.17.1x. -- `tools/convert-world.php` now writes errors to stderr and sets the proper exit code. -- Explosions now use the standard mechanism for processing block updates. Previously, it used a special mechanism due to prohibitively poor efficiency of the standard algorithm. Since these inefficiencies have now been addressed, explosions can now be consistent with everything else, with minimal performance impact. -- Command usage strings are no longer automatically translated (use `Translatable` instead of bare string keys). -- Command description strings are no longer automatically translated (use `Translatable` instead of bare string keys). - -## Fixes -- `ItemFactory->isRegistered()` no longer crashes when given negative item IDs. -- Furnaces now continue to operate after reloading the chunk they were contained in. -- Fixed being unable to reconnect for 10 seconds after disconnecting in some cases. - -## API changes -- The following API methods have been added: - - `Liquid->getMinAdjacentSourcesToFormSource()`: returns how many adjacent source blocks of the same liquid must be present in order for the current block to become a source itself - - `Player->getPlayerInfo()` -- `Liquid` minimum-cost flow calculation code has been extracted to `MinimumCostFlowCalculator`. - -# 4.0.0-BETA4 -Released 6th October 2021. - -## General -- Improved performance of lighting calculation by avoiding copies of useless data from the main thread. -- Resource pack loading now accepts `dependencies` and `capabilities` fields in the `manifest.json` (although it doesn't currently check them). -- `/help` is now localized according to language set in `server.properties`. -- Various messages related to world loading, generation and conversion are now localized according to the language set in `server.properties`. -- Compasses now point to the correct (current) world's spawn point after teleporting players to a different world. Previously, they would continue to point to the spawn of the world that the player initially spawned in. -- The `--bootstrap` CLI option has been removed. -- RakLib 0.14.2 is now required. This fixes the following issues: - - Fixed incorrect handling of sessions on client disconnect (leading to timeout debug messages). - - Fixed transferring players often not working correctly. - - Fixed disconnect screens sometimes not displaying. - -## Fixes -- Fixed server crash when UPnP encounters an error. -- Fixed server crash when clients sent items with bad NBT in inventory transactions. -- Fixed server crash when loading a plugin with legacy nested permission structure (now the plugin will fail to load, but the server won't crash). -- Fixed server crash when using `/give` with bad NBT on any item. -- Fixed server crash when loading a plugin with improperly formatted API version (now the plugin will fail to load, but the server won't crash). -- Fixed server crash when changing player gamemode during `PlayerLoginEvent`. -- Incorrect structure of `commands` in plugin manifest is now detected earlier and handled more gracefully. -- Fixed console reader subprocess lingering on server crash on Windows and screwing up the terminal. -- Fixed `Player` object memory leak when kicking players during `PlayerLoginEvent` (this caused the `World` to report warnings about leaked entities on shutdown). -- Fixed `Projectile->move()` ignoring the `dx`/`dy`/`dz` parameters given and using its own `motion` instead. -- Fixed `BlockFactory->get()` erroneously accepting meta values of `16`. -- Fixed `Block->isSameState()` false negatives for some types of slabs. -- Fixed being unable to place slabs of the same type on top of each other to create double slabs. - -## API changes -- Plugin commands in `plugin.yml` must now declare `permission` for each command. Previously, the `permission` key was optional, causing anyone to be able to use the command. - - This behaviour was removed because of the potential for security issues - a typo in `plugin.yml` could lead to dangerous functionality being exposed to everyone. - - If you want to make a command that everyone can use, declare a permission with a `default` of `true` and assign it to the command. -- Plugin permissions in `plugin.yml` must now declare `default` for each permission. Previously, the `default` key was optional, causing the permission to silently be denied to everyone (PM4) or granted to ops implicitly (PM3). - -### Block -- Added the following classes: - - `pocketmine\block\utils\LeverFacing` -- Added the following API methods: - - `pocketmine\block\Lever->isActivated()` - - `pocketmine\block\Lever->setActivated()` - - `pocketmine\block\Lever->getFacing()` - - `pocketmine\block\Lever->setFacing()` - -### World -- The following API methods have signature changes: - - `Chunk->getSubChunks()` now returns `array` instead of `SplFixedArray`. -- The following API methods have been removed: - - `FastChunkSerializer::serialize()` - - `FastChunkSerializer::deserialize()` -- The following API methods have been added: - - `FastChunkSerializer::serializeTerrain()`: serializes blocks and biomes only - - `FastChunkSerializer::deserializeTerrain()`: deserializes the output of `serializeTerrain()` - -### Utils -- The following API methods have signature changes: - - `Process::kill()` now requires an additional `bool $subprocesses` parameter. - -# 4.0.0-BETA5 -Released 12th October 2021. - -## General -- Exception log format has been changed. Now, exception info is logged in one big block message. This saves space on the console and improves readability, as well as reducing the ability for bad `ThreadedLoggerAttachment`s to break exception output. -- Log messages are now pushed to `server.log` before calling logger attachment, instead of after. This fixes messages not being written to disk when an error occurs in a logger attachment. -- Improved startup performance when loading many plugins. -- The `worlds` config in `pocketmine.yml` no longer supports attaching the generator settings to the `generator` key (use the `preset` key instead). -- Using an unknown generator in `server.properties` or `pocketmine.yml` will now cause a failure to generate the world. -- Using invalid/incorrect world generator options (presets) in `server.properties` or `pocketmine.yml` will now cause a failure to generate the world. -- Generator options of existing worlds are now validated before loading them. If they are invalid, the server will fail to load them. -- Several more log messages have been localized, including plugin loading errors. - -## Fixes -- Fixed server crash when using `/give` to give an item by ID which doesn't exist in Minecraft. -- Fixed server crash when boolean `server.properties` options were given an integer value (e.g. `0` or `1` instead of `false` or `true`). -- Fixed stats reporting checking for a nonexistent `pocketmine.yml` setting. -- Fixed use of commands without the proper permission sending a message `commands.generic.permission` instead of the proper message. -- Fixed entities set on fire appearing to stay on fire, although not taking any damage. -- Fixed a duplicate `MB` suffix on the `Memory freed` output of `/gc`. -- Fixed the server attempting to generate a world if it failed to load. - -## API -### Block -- The following API methods have been renamed: - - `Block->getPositionOffset()` -> `Block->getModelPositionOffset()`. - -### Event -- `@handleCancelled` PhpDoc annotation can no longer be used on event handlers for non-cancellable events. -- The following API methods have been added: - - `StructureGrowEvent->getPlayer()` - -### Inventory -- The following API methods have been added: - - `Inventory->getAddableItemQuantity()` - -### Scheduler -- `ClosureTask` now permits closures without an explicit return type (useful for arrow functions). - -### Utils -- The following API methods have been added: - - `Config::parseProperties()` - - `Config::writeProperties()` - - `Config::parseList()` - - `Config::writeList()` - -### World -- The following API methods have signature changes: - - `GeneratorManager->registerGenerator()` now requires a `\Closure $presetValidator` parameter. This is used to check generator options of worlds and configs before attempting to use them. - -# 4.0.0-BETA6 -Released 19th October 2021. - -## General -- Added support for Minecraft: Bedrock Edition 1.17.40. -- Removed support for earlier versions. -- CTRL+C signal handling has been restored, and is now supported on Windows. Pressing CTRL+C while the server is running will behave as if the `/stop` command was invoked. -- Added a script `tools/generate-permission-doc.php` to generate a Markdown file with a list of all permissions and their relationships. In the future, this will be used to maintain the official documentation, but plugin developers might find it useful for their own purposes too. -- [`respect/validation`](https://packagist.org/packages/respect/validation) is no longer a core dependency. - -## Fixes -- Fixed server crash when using `/give` to give an item with a too-large item ID, or `/clear` to clear an item that does not exist. - - Now, `LegacyStringToItemParser` is used exclusively, and numeric IDs are no longer parsed. - -## Gameplay - Picking up some items from a dropped stack of items is now supported. This fixes various bugs with being unable to pick up items with an almost-full inventory. - -# 4.0.0-BETA7 -Released 28th October 2021. - -## General -- Phar plugins are now able to depend on folder plugins loaded by DevTools. -- Now uses [`pocketmine/bedrock-protocol@58c53a259e819a076bf8fe875d2a012da7d19d65`](https://github.com/pmmp/BedrockProtocol/tree/58c53a259e819a076bf8fe875d2a012da7d19d65). This version features significant changes, including: - - Standardisation of various field names (e.g. `eid` -> `actorRuntimeId`, `evid` -> `eventId`) - - Rename of `entity` related fields to `actor` where appropriate (e.g. `entityRuntimeId` -> `actorRuntimeId`) - - Block position `x`/`y`/`z` fields replaced by `BlockPosition` - - Static `::create()` functions for all packets, which ensure that fields can't be forgotten - -## Fixes -- Fixed server crash when clients send itemstacks with unmappable dynamic item IDs. -- Fixed server crash on invalid ItemStackRequest action types. -- Fixed autosave bug that caused unmodified chunks to be saved at least once (during the first autosave after they were loaded). -- Fixed `ConsoleReaderThread` returning strings with newlines still on the end. -- Fixed changes made to adjacent chunks in `ChunkPopulateEvent` (e.g. setting blocks) sometimes getting overwritten. - -## API -### Event -- `PlayerCreationEvent` now verifies that the player class set is instantiable - this ensures that plugins get properly blamed for breaking things. - -### World -- `World->generateChunkCallback()` has been specialized for use by `PopulationTask`. This allows fixing various inconsistencies involving `ChunkPopulateEvent` (e.g. modifications to adjacent chunks in `ChunkPopulationEvent` might be wiped out, if the population of the target chunk modified the adjacent chunk). - - It now accepts `Chunk $centerChunk, array $adjacentChunks` (instead of `?Chunk $chunk`). - - It's no longer expected to be used by plugins - plugins should be using `World->setChunk()` anyway. -- `Chunk->getModificationCounter()` has been added. This is a number starting from `0` when the `Chunk` object is first created (unless overridden by the constructor). It's incremented every time blocks or biomes are changed in the chunk. It resets after the chunk is unloaded and reloaded. -- The following API methods have changed signatures: - - `Sound->encode()` no longer accepts `null` for the position. - - `Chunk->__construct()`: removed `HeightArray $heightMap` parameter, added `bool $terrainPopulated` and `int $modificationCounter` parameters. - -### Plugin -- `PluginManager->loadPlugins()` now accepts paths to files as well as directories, in which case it will load only the plugin found in the target file. -- The following API methods have been removed: - - `PluginManager->loadPlugin()`: use `PluginManager->loadPlugins()` instead - -# 4.0.0-BETA8 -Released 29th October 2021. - -## General -- Chunk packet caches are now cleared by the memory manager on low memory. -- `Entity->spawnTo()` now has an additional sanity check for matching worlds (might expose a few new errors in plugins). -- [`pocketmine/math` 0.4.0](https://github.com/pmmp/Math/releases/tag/0.4.0) is now used. Please see its release notes for changes. - -## Fixes -- Zlib raw check for LevelDB is now done directly on startup, avoiding crashes when later trying to load worlds. -- Fixed tiles and entities getting deleted from adjacent chunks during chunk population. -- Fixed players being unable to open their inventories more than once. -- Fixed entities not getting updated when a nearby chunk is replaced (e.g. dropped items would float in midair if the ground was lower than before) - -## API -### World -- `World::setChunk()` has the following changes: - - `$deleteEntitiesAndTiles` parameter has been removed. - - Entities are no longer deleted on chunk replacement. - - Tiles are no longer deleted on chunk replacement, unless one of the following conditions is met: - - the target block in the new chunk doesn't expect a tile - - the target block in the new chunk expects a different type of tile (responsibility of the plugin developer to create the new tile) - - there's already a tile in the target chunk which conflicts with the old one -- `Location::__construct()` has the following changes: - - `world` parameter is now 4th instead of last. - - All parameters are now mandatory. -- Reverted addition of chunk modification counters in previous beta. -- `Chunk::DIRTY_FLAG_TERRAIN` has been renamed to `Chunk::DIRTY_FLAG_BLOCKS`. - -# 4.0.0-BETA9 -Released 2nd November 2021. - -## General -- Now analysed using level 9 on PHPStan 1.0.0. -- `ext-pthreads` v4.0.0 or newer is now required. -- `resources/vanilla` submodule has been removed. BedrockData is now included via Composer dependency [`pocketmine/bedrock-data`](https://packagist.org/packages/pocketmine/bedrock-data). -- `pocketmine/spl` Composer dependency has been dropped. -- The following Composer dependency versions are now required: - - [`pocketmine/bedrock-protocol` v5.0.0](https://github.com/pmmp/BedrockProtocol/tree/5.0.0+bedrock-1.17.40) features substantial changes to its API compared to 3.0.1, which was used in 4.0.0-BETA8. Please see its [release notes](https://github.com/pmmp/BedrockData/releases/tag/5.0.0+bedrock-1.17.40). - - [`pocketmine/log` v0.4.0](https://github.com/pmmp/Log/tree/0.4.0) removes the `LoggerAttachment` interface and replaces logger attachment objects with closures. - - [`pocketmine/log-pthreads` v0.4.0](https://github.com/pmmp/LogPthreads/tree/0.4.0) - - [`pocketmine/classloader` v0.2.0](https://github.com/pmmp/ClassLoader/tree/0.2.0) -- A noisy debug message in `World->updateAllLight()` has been removed. - -## API -### Entity -- `Human->setLifetimeTotalXp()` now limits the maximum value to 2^31. - -### Event -- `BlockGrowEvent` is now called when cocoa pods grow. - -### Item -- Added `Releasable->canStartUsingItem()`. - -### Network -- Added `NetworkInterfaceStartException`, which may be thrown by `Network->registerInterface()` and `NetworkInterface->start()`. - -### Player -- `SurvivalBlockBreakHandler::createIfNecessary()` has been removed. -- `SurvivalBlockBreakHandler->__construct()` is now public. -- `UsedChunkStatus::REQUESTED()` has been renamed to `REQUESTED_SENDING`. -- `UsedChunkStatus::REQUESTED_GENERATION()` has been added. - -### Utils -- `Promise` API has changed: - - Promise-related classes have been moved to `pocketmine\promise` namespace. - - It's now split into `Promise` and `PromiseResolver`. - - `PromiseResolver` provides only `resolve()` and `reject()`. It should be used by callbacks to resolve a promise. - - `Promise` now provides only `onCompletion()` and `isResolved()` APIs. This should be given to consumers to allow them to handle the result of the async operation. - - `PromiseResolver` must not be created directly. Use `new PromiseResolver` and `PromiseResolver->getPromise()`. - -### World -- Improved performance of `setBlock()` by around 35% when the `$update` parameter is set to `true`. -- Improved performance of `setBlock()` by around 30% when the `$update` parameter is set to `false`. -- `World->generateChunkCallback()` is no longer exposed to public API. -- `World->getAdjacentChunks()` now returns an array indexed using `World::chunkHash()`, where the `x` and `z` components are the relative offsets from the target chunk (range -1 to +1). -- `World->lockChunk()` now requires `ChunkLockId $lockId` parameter. -- `World->unlockChunk()` now requires a `?ChunkLockId $lockId` parameter. If a non-null lockID is given, the lock on the chunk will only be removed if it matches the given lockID. -- `World->unlockChunk()` now returns `bool` instead of `void` (to signal whether unlocking succeded or not). -- Added `ChunkLockId` class. - -## Fixes -### World -- Fixed server crash when tiles with colliding positions are loaded from saved data. Now, an error is logged, but the server won't crash. -- Fixed server crash when liquids and other items flow into terrain locked for population. Now, an advisory locking mechanism is used, and population results will be discarded and recalculated if modifications are detected. -- Fixed various crashes that could occur if a chunk was flagged with `setPopulated(true)` after a promise had already been created for its population. -- Fixed `AssumptionFailedError` in `PopulationTask` when workers previously used for generation are shutdown, and then restarted on the fly by a generation request. -- Fixed assertion failure in `World->drainPopulationRequestQueue()` when requesting, cancelling and then re-requesting generation of a chunk while the generator was busy. -- Fixed generation potentially getting stuck if a population request was cancelled while the population task was running (failure to remove locks from used chunks). -- Fixed `World->requestChunkPopulation()` not taking into account that the target chunk may already be populated. This caused a variety of strange bugs and performance issues. -- Fixed potential memory leak caused by `World->unregisterChunkListenerFromAll()` not taking players into account. -- Fixed debug spam of `chunk has no loaders registered` messages during chunk generation. - -### Other fixes -- Fixed server crash when unable to bind to the desired port. Now, the server will show an error and gracefully stop without a crashdump instead. -- Fixed server crash in `Player->showPlayer()` when the target is not in the same world. -- Fixed players, who died in hardcore mode and were unbanned, getting re-banned on next server join. -- Fixed cake block desync when attempting to eat in creative (eating in creative is not yet supported, but the block rollback was missing). -- Fixed players being able to eat items more quickly by dropping them while eating. - Fixed arrows getting added to creative players' inventories when picked up. -- Fixed players re-requesting the same ungenerated chunks multiple times before they were sent. -- Fixed commands not working in some cases after using some control sequences on the console. -# 4.0.0-BETA10 -Released 2nd November 2021. - -## Fixes -- Fixed an issue with BedrockData JSON minification which broke the release build of 4.0.0-BETA9. - -# 4.0.0-BETA11 -Released 6th November 2021. - -## General -- `resources/locale` submodule has been removed. Language files are now included via Composer dependency [`pocketmine/locale-data`](https://packagist.org/packages/pocketmine/locale-data). - - This means it's now possible to run a server from git sources without cloning submodules :) - - All remaining submodules (DevTools, build/php) are non-essential for building and running a server. -- Added a tool `tools/simulate-chunk-sending.php` to visualise the behaviour of `ChunkSelector`. - -## Fixes -- Fixed server crash on saving when player XP has reached int32 max (XP is now capped, similar to Java Edition). -- Fixed another edge case in chunk generation that led to assertion failures. -- Fixed server crash when finding a list of `TAG_Float` for entity positions instead of `TAG_Double`. -- Fixed fast eating when picking up items. -- Fixed terrain being invisible for a long time when teleporting into ungenerated terrain. -- Fixed weird chunk loading when teleporting into ungenerated terrain (sometimes farther chunks would render before closer ones, leaving holes in the map temporarily). -- Fixed players re-requesting chunks when turning their heads or jumping. -- Fixed bonemeal sometimes being consumed even when cancelling `BlockGrowEvent` and `StructureGrowEvent`. - -## API -### Event -- Added `PlayerEmoteEvent`. - -### Gameplay -- Chunks are now sent in proper circles. This improves the experience when flying quickly parallel to X or Z axis, since now more chunks in front of the player will load sooner. +### Misc - Added support for emotes. - -# 4.0.0-BETA12 -Released 9th November 2021. - -## General -- Introduced support for connecting via IPv6. - - PHP binary used must now always be built with IPv6 support, even if IPv6 is disabled. This is because RakNet may still send link-local IPv6 loopback addresses in connection packets even when only using IPv4. - - The default port for IPv6 is `19133` (similar to Bedrock Dedicated Server). - - Port `19133` is used by default so that Minecraft Bedrock can detect IPv6 servers on LAN. - - GS4 Query is supported on both IPv4 and IPv6 according to `server.properties` settings. - - The following `server.properties` settings are influential: - - `enable-ipv6`: `on` by default. Disabling this completely disables IPv6 support. - - `server-ipv6`: `::` by default (equivalent to "any IP", like `0.0.0.0` for IPv4). Most users shouldn't need to change this setting, and it doesn't appear in `server.properties` by default. - - `server-portv6`: `19133` by default. You may run both IPv4 and IPv6 on the same port. -- Various internal changes have been made to prepare for negative Y axis support (upcoming 1.18). - -## Fixes -- Fixed resource packs not applying. -- Fixed inventory windows being unopenable after dying with inventory windows open. -- Fixed plugins being able to alter other plugins' permission defaults by redeclaring them in the `plugin.yml`. - -## API -### Block -- `VanillaBlocks::fromString()` has been removed. -- Added `CraftingTableInventory`. This exclusively represents a crafting table's 3x3 crafting grid. - -### Crafting -- `CraftingGrid` is now abstract. -- Removed `CraftingGrid->getHolder()`. -- The constructor of `CraftingGrid` no longer accepts a `Player` parameter. - -### Entity -#### Effect -- `Effect->__construct()` once again accepts an `int $defaultDuration` parameter. -- Removed `VanillaEffects::fromString()`. -- Added `StringToEffectParser` - - Supports custom aliases! - - This is used by `/effect` to provide name support. - -### Event -- `InventoryOpenEvent` is now fired when a player opens a crafting table's UI. -- `InventoryCloseEvent` is now fired when a player closes a crafting table's UI. -- `PlayerDropItemEvent` will now prevent the drops from force-closing of the following inventories: - - anvil - - enchanting table - - loom - -### Inventory -- Added `TemporaryInventory`. This should be implemented by any inventory whose contents should be evacuated when closing. -- Added `PlayerCraftingInventory`. This exclusively represents the player's own 2x2 crafting grid. - -### Item -- Removed `VanillaItems::fromString()` - - Obsoleted by the far superior, much more dynamic, and plugin-customizable `StringToItemParser`. - - `StringToItemParser` allows mapping strings to closure callbacks, allowing you to create aliases for `/give` for any item, including custom ones. - -#### Enchantment -- Removed `VanillaEnchantments::fromString()`. -- Added `StringToEnchantmentParser` - - Supports custom aliases! - - This is used by `/enchant` to provide name support. - -### Player -- Removed `Player->setCraftingGrid()`. To open a 3x3 crafting grid to a player, use `setCurrentWindow(new CraftingTableInventory)`. - -### Server -- Added the following API methods: - - `Server->getIpV6()` - - `Server->getPortV6()` - -# 4.0.0-BETA13 -Released 25th November 2021. - -## General -- Improved error messages when a plugin command name or alias contains an illegal character. -- Fixed script plugins reading tags from non-docblocks before the actual docblock. -- Added a sanity check to `Human->setCurrentTotalXp()` to try and catch an elusive bug that's been appearing in the wild - please get in touch if you know how to reproduce it! -- Updated `BUILDING.md` to reflect the fact that submodules are no longer required to build or run the server. - -## Internals -- Crashdump rendering has been separated from crashdump data generation. This allows rendering crashdumps from existing JSON data. -- Direct iteration of arrays with string keys is now disallowed by a custom PHPStan rule. This is because numeric strings are casted to integers when used as array keys, which produces a variety of unexpected behaviour particularly for iteration. - - To iterate on arrays with string keys, `Utils::stringifyKeys()` must now be used. - -## Fixes -- Fixed various crashes involving bad entity data saved on disk (e.g. an item entity with invalid item would crash the server). -- Fixed various crashes involving arrays with numeric string keys. -- Fixed crash when players try to pickup XP while already having max XP. -- Fixed ungenerated chunks saved on disk by old versions of PocketMine-MP (before 3.0.0) being treated as corrupted during world conversion (they are now ignored instead). -- Fixed misleading corruption error message when saved chunks have missing NBT tags. - -## Gameplay -- Fixed `/setworldspawn` setting incorrect positions based on player position when in negative coordinates. -- `/setworldspawn` now accepts relative coordinates when used as a player. -- Added some extra aliases for `/give` and `/clear`: `chipped_anvil`, `coarse_dirt`, `damaged_anvil`, `dark_oak_standing_sign`, `jungle_wood_stairs`, `jungle_wooden_stairs` and `oak_standing_sign`. - - Some of these were added for quality-of-life, others were added just to be consistent. -- Fixed explosions dropping incorrect items when destroying blocks with tile data (e.g. banners, beds). -- Fixed the bounding box of skulls when mounted on a wall. -- Fixed podzol dropping itself when mined (instead of dirt). - -## API -### Entity -- `Projectile->move()` is now protected, like its parent. - -### Utils -- `Utils::parseDocComment()` now allows `-` in tag names. - -# 4.0.0-BETA14 -Released 30th November 2021. - -## General -- The server will now log an EMERGENCY-level message when `forceShutdown()` is used for any other reason than a graceful shutdown. -- The server will now attempt to translate invalid blocks to valid equivalents when loading chunks. This fixes many issues with `update!` blocks appearing in worlds, particularly ghost structures (these would appear when world editors previously erased some blocks by setting their IDs but not metadata). - -## Fixes -- Fixed `ConsoleReaderThread` spawning many zombie processes when running a server inside a Docker container. - -# 4.0.0-BETA15 -Released 30th November 2021. - -## General -- Added support for Minecraft: Bedrock 1.18.0 -- Removed support for earlier versions. From bd8308cc6f784f00bce12c88417c3e212c97ed26 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 1 Dec 2021 22:15:38 +0000 Subject: [PATCH 3224/3224] changelog: mention pocketmine subdirectory removal --- changelogs/4.0.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelogs/4.0.md b/changelogs/4.0.md index 213ab4f7de..2f0673699b 100644 --- a/changelogs/4.0.md +++ b/changelogs/4.0.md @@ -241,6 +241,7 @@ This version features substantial changes to the network system, improving coher - A new "plugin greylist" feature has been introduced, which allows whitelisting or blacklisting plugins from loading. See `plugin_list.yml`. ### Internals +- The `pocketmine` subdirectory has been removed from `src`. [PSR-4 autoloading is now used thanks to Composer](https://github.com/pmmp/PocketMine-MP/blob/4.0.0/composer.json#L63). - Crashdump rendering has been separated from crashdump data generation. This allows rendering crashdumps from existing JSON data. - Direct iteration of arrays with string keys is now disallowed by a custom PHPStan rule. This is because numeric strings are casted to integers when used as array keys, which produces a variety of unexpected behaviour particularly for iteration. - To iterate on arrays with string keys, `Utils::stringifyKeys()` must now be used.